httpd-2.4.64/0000775000175100017510000000000015032766627012640 5ustar covenercovenerhttpd-2.4.64/docs/0000775000175100017510000000000015032766613013563 5ustar covenercovenerhttpd-2.4.64/docs/manual/0000775000175100017510000000000015032766627015045 5ustar covenercovenerhttpd-2.4.64/docs/manual/mod/0000775000175100017510000000000015032766627015624 5ustar covenercovenerhttpd-2.4.64/docs/manual/mod/mod_asis.html.ko.euc-kr0000664000175100017510000002074314743132254022102 0ustar covenercovener mod_asis - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_asis

ֽ ƴմϴ. ֱٿ ϼ.
:HTTP
:Base
:asis_module
ҽ:mod_asis.c

ġ Ϲ HTTP κ ߰ʰ send-as-is ڵ鷯 Ѵ.

׷ cgi ũƮ nph ũƮ ʰ ̷ǰ ٸ Ư HTTP  ڷᵵ ִ.

ſ mime type httpd/send-as-is ϵ óߴ.

Support Apache!

þ

⿡ þ ϴ.

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_groupfile.html.ja.utf80000664000175100017510000002362514743132254024035 0ustar covenercovener mod_authz_groupfile - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_authz_groupfile

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:プレーンテキストファイルを用いたグループ承認
ステータス:Base
モジュール識別子:authz_groupfile_module
ソースファイル:mod_authz_groupfile.c
互換性:Apache 2.1 以降

概要

このモジュールは認証されたユーザがグループのメンバーか 否かによってウェブサイトの一部へのアクセスを許可するか拒否するかの 承認機能を提供します。同様の機能は mod_authz_dbm によっても提供されています。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

AuthGroupFile ディレクティブ

説明:証認に使用するユーザグループの一覧が格納されている、 テキストファイルの名前を設定する
構文:AuthGroupFile file-path
コンテキスト:ディレクトリ, .htaccess
上書き:AuthConfig
ステータス:Base
モジュール:mod_authz_groupfile

AuthGroupFile ディレクティブは、 証認に使用するユーザグループの一覧が格納されている、 テキストファイルの名前を設定します。 file-path はグループファイルへのパスです。 絶対パスでなければ、 ServerRoot からの相対パスとして扱われます。

グループファイル各行は、グループ名、コロン、そして スペース区切りでそのメンバーのユーザ名を記述します。

例:

mygroup: bob joe anne

大きなファイルを探索するのは、非常に効率が悪いという点に 注意してください。そのような場合は、 AuthDBMGroupFile の方がずっと良い性能を発揮します。

セキュリティ

AuthGroupFile は、 ウェブサーバのドキュメントツリーの外側に 保管するようにしてください。 保護しようとしているディレクトリ以下には、置かないで下さい。 そうしないとクライアントが AuthGroupFile を ダウンロードできてしまう可能性があります。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_file.html.ja.utf80000664000175100017510000003070314743132254022737 0ustar covenercovener mod_authn_file - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_authn_file

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:テキストファイルを用いたユーザ認証
ステータス:Base
モジュール識別子:authn_file_module
ソースファイル:mod_authn_file.c
互換性:Apache 2.1 以降

概要

本モジュールは mod_auth_digestmod_auth_basic といった認証フロントエンドに対して、 プレインテキストのパスワードファイル内からユーザを検索することで、 ユーザ認証機能を提供します。似たような機能は mod_authn_dbm でも提供されています。

mod_auth_basicmod_auth_digest を使用する際には、 AuthBasicProviderAuthDigestPrividerfile と指定することでこのモジュールは起動されます。

Support Apache!

ディレクティブ

Bugfix checklist

参照

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 は ダウンロードできてしまいます。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.ja.utf80000664000175100017510000016354715032765673022151 0ustar covenercovener ディレクティブ一覧 - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

ディレクティブ一覧

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

標準 Apache 配布にあるすべての Apache のディレクティブの一覧です。 これらは一貫した形式で書かれていて、使われている用語の 用語集 も用意されています。

各ディレクティブの概要を説明した ディレクティブクイックリファレンスも あります。

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_uwsgi.html.fr.utf80000664000175100017510000002131314740503670023233 0ustar covenercovener mod_proxy_uwsgi - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_uwsgi

Langues Disponibles:  en  |  fr 

Description:Module de passerelle UWSGI pour mod_proxy
Statut:Extension
Identificateur de Module:proxy_uwsgi_module
Fichier Source:mod_proxy_uwsgi.c
Compatibilité:Disponible à partir de la version 2.4.30 du serveur HTTP Apache.

Sommaire

Pour pouvoir fonctionner, ce module requiert le chargement préalable de mod_proxy. Il fournit le support du protocole UWSGI.

Pour être en mesure de gérer le protocole UWSGI, le serveur doit donc pouvoir disposer des modules mod_proxy et mod_proxy_uwsgi.

Avertissement

N'activez le mandatement que si vous avez sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux pour votre réseau, mais aussi pour Internet en général.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Exemples

Il est rappelé que vous devez charger les modules mod_proxy et mod_proxy_uwsgi pour que les exemples suivants fonctionnent.

Passerelle simple

ProxyPass "/uwsgi-bin/" "uwsgi://localhost:4000/"

La passerelle à répartition de charge nécessite mod_proxy_balancer et au moins un module implémentant un algorithme de répartition de charge comme mod_lbmethod_byrequests, en plus des modules de mandatement listés ci-dessus. Par défaut, c'est mod_lbmethod_byrequests qui sera utilisé, et c'est donc ce dernier qui sera utilisé dans l'exemple suivant :

Passerelle à répartition de charge

ProxyPass "/uwsgi-bin/" "balancer://somecluster/"
<Proxy balancer://somecluster>
    BalancerMember uwsgi://localhost:4000
    BalancerMember uwsgi://localhost:4001
</Proxy>

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_user.html.ja.utf80000664000175100017510000001661414743132254023017 0ustar covenercovener mod_authz_user - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_authz_user

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:ユーザ承認
ステータス:Base
モジュール識別子:authz_user_module
ソースファイル:mod_authz_user.c
互換性:Apache 2.1 以降で使用可能

概要

このモジュールは、認証されたユーザにウェブサイトの一部への アクセスを許可したり拒否したりするための承認機能を提供します。 mod_authz_user は認証されたユーザが Require user ディレクティブに書かれていれば アクセスを認めます。認証に成功したユーザすべてにアクセスを 許可するには、代わりに Require valid-user を 使うことができます。

Support Apache!

ディレクティブ

このモジュールにディレクティブはありません。

Bugfix checklist

参照

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_http2.html.en0000664000175100017510000022267615032765673021032 0ustar covenercovener mod_http2 - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_http2

Available Languages:  en  |  fr 

Description:Support for the HTTP/2 transport layer
Status:Extension
Module Identifier:http2_module
Source File:mod_http2.c
Compatibility:Available in version 2.4.17 and later

Summary

This module provides HTTP/2 (RFC 7540) support for the Apache HTTP Server.

This module relies on libnghttp2 to provide the core http/2 engine.

You must enable HTTP/2 via Protocols in order to use the functionality described in this document. The HTTP/2 protocol does not require the use of encryption so two schemes are available: h2 (HTTP/2 over TLS) and h2c (HTTP/2 over TCP).

Two useful configuration schemes are:

HTTP/2 in a VirtualHost context (TLS only)

Protocols h2 http/1.1

Allows HTTP/2 negotiation (h2) via TLS ALPN in a secure <VirtualHost>. HTTP/2 preamble checking (Direct mode, see H2Direct) is disabled by default for h2.

HTTP/2 in a Server context (TLS and cleartext)

Protocols h2 h2c http/1.1

Allows HTTP/2 negotiation (h2) via TLS ALPN for secure <VirtualHost>. Allows HTTP/2 cleartext negotiation (h2c) upgrading from an initial HTTP/1.1 connection or via HTTP/2 preamble checking (Direct mode, see H2Direct).

Refer to the official HTTP/2 FAQ for any doubt about the protocol.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

How it works

HTTP/2 Dimensioning

Enabling HTTP/2 on your Apache Server has impact on the resource consumption and if you have a busy site, you may need to consider carefully the implications.

The first noticeable thing after enabling HTTP/2 is that your server processes will start additional threads. The reason for this is that HTTP/2 gives all requests that it receives to its own Worker threads for processing, collects the results and streams them out to the client.

In the current implementation, these workers use a separate thread pool from the MPM workers that you might be familiar with. This is just how things are right now and not intended to be like this forever. (It might be forever for the 2.4.x release line, though.) So, HTTP/2 workers, or shorter H2Workers, will not show up in mod_status. They are also not counted against directives such as ThreadsPerChild. However they take ThreadsPerChild as default if you have not configured something else via H2MinWorkers and H2MaxWorkers.

Another thing to watch out for is is memory consumption. Since HTTP/2 keeps more state on the server to manage all the open request, priorities for and dependencies between them, it will always need more memory than HTTP/1.1 processing. There are three directives which steer the memory footprint of a HTTP/2 connection: H2MaxSessionStreams, H2WindowSize and H2StreamMaxMemSize.

H2MaxSessionStreams limits the number of parallel requests that a client can make on a HTTP/2 connection. It depends on your site how many you should allow. The default is 100 which is plenty and unless you run into memory problems, I would keep it this way. Most requests that browsers send are GETs without a body, so they use up only a little bit of memory until the actual processing starts.

H2WindowSize controls how much the client is allowed to send as body of a request, before it waits for the server to encourage more. Or, the other way around, it is the amount of request body data the server needs to be able to buffer. This is per request.

And last, but not least, H2StreamMaxMemSize controls how much response data shall be buffered. The request sits in a H2Worker thread and is producing data, the HTTP/2 connection tries to send this to the client. If the client does not read fast enough, the connection will buffer this amount of data and then suspend the H2Worker.

Multiple Hosts and Misdirected Requests

Many sites use the same TLS certificate for multiple virtual hosts. The certificate either has a wildcard name, such as '*.example.org' or carries several alternate names. Browsers using HTTP/2 will recognize that and reuse an already opened connection for such hosts.

While this is great for performance, it comes at a price: such vhosts need more care in their configuration. The problem is that you will have multiple requests for multiple hosts on the same TLS connection. And that makes renegotiation impossible, in face the HTTP/2 standard forbids it.

So, if you have several virtual hosts using the same certificate and want to use HTTP/2 for them, you need to make sure that all vhosts have exactly the same SSL configuration. You need the same protocol, ciphers and settings for client verification.

If you mix things, Apache httpd will detect it and return a special response code, 421 Misdirected Request, to the client.

Environment Variables

This module can be configured to provide HTTP/2 related information as additional environment variables to the SSI and CGI namespace, as well as in custom log configurations (see %{VAR_NAME}e).

Variable Name: Value Type: Description:
HTTP2flagHTTP/2 is being used.
H2PUSHflagHTTP/2 Server Push is enabled for this connection and also supported by the client.
H2_PUSHflagalternate name for H2PUSH
H2_PUSHEDstringempty or PUSHED for a request being pushed by the server.
H2_PUSHED_ONnumberHTTP/2 stream number that triggered the push of this request.
H2_STREAM_IDnumberHTTP/2 stream number of this request.
H2_STREAM_TAGstringHTTP/2 process unique stream identifier, consisting of connection id and stream id separated by -.
top

H2CopyFiles Directive

Description:Determine file handling in responses
Syntax:H2CopyFiles on|off
Default:H2CopyFiles off
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.24 and later.

This directive influences how file content is handled in responses. When off, which is the default, file handles are passed from the requestion processing down to the main connection, using the usual Apache setaside handling for managing the lifetime of the file.

When set to on, file content is copied while the request is still being processed and the buffered data is passed on to the main connection. This is better if a third party module is injecting files with different lifetimes into the response.

An example for such a module is mod_wsgi that may place Python file handles into the response. Those files get close down when Python thinks processing has finished. That may be well before mod_http2 is done with them.

top

H2Direct Directive

Description:H2 Direct Protocol Switch
Syntax:H2Direct on|off
Default:H2Direct on for h2c, off for h2 protocol
Context:server config, virtual host
Status:Extension
Module:mod_http2

This directive toggles the usage of the HTTP/2 Direct Mode. This should be used inside a <VirtualHost> section to enable direct HTTP/2 communication for that virtual host.

Direct communication means that if the first bytes received by the server on a connection match the HTTP/2 preamble, the HTTP/2 protocol is switched to immediately without further negotiation. This mode is defined in RFC 7540 for the cleartext (h2c) case. Its use on TLS connections not mandated by the standard.

When a server/vhost does not have h2 or h2c enabled via Protocols, the connection is never inspected for a HTTP/2 preamble. H2Direct does not matter then. This is important for connections that use protocols where an initial read might hang indefinitely, such as NNTP.

For clients that have out-of-band knowledge about a server supporting h2c, direct HTTP/2 saves the client from having to perform an HTTP/1.1 upgrade, resulting in better performance and avoiding the Upgrade restrictions on request bodies.

This makes direct h2c attractive for server to server communication as well, when the connection can be trusted or is secured by other means.

Example

H2Direct on
top

H2EarlyHint Directive

Description:Add a response header to be picked up in 103 Early Hints
Syntax:H2EarlyHint name value
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.58 and later.

H2EarlyHint allows adding a response header before the real request processing is started. Such headers are picked up for "103 Early Hints" intermediate responses. The main purpose is to send "preload" information to client browsers.

name and value must be valid HTTP header fields or will lead to failed responses. H2EarlyHints must still be enabled to allow 103 intermediate responses to be sent. This directive can be repeated several times and header fields of the same names add.

Example

H2EarlyHint Link "</my.css>;rel=preload;as=style"
top

H2EarlyHints Directive

Description:Determine sending of 103 status codes
Syntax:H2EarlyHints on|off
Default:H2EarlyHints off
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.24 and later.

This setting controls if HTTP status 103 interim responses are forwarded to the client or not. By default, this is currently not the case since a range of clients still have trouble with unexpected interim responses.

When set to on, PUSH resources announced with H2PushResource will trigger an interim 103 response before the final response. The 103 response will carry Link headers that advise the preload of such resources.

top

H2MaxDataFrameLen Directive

Description:Maximum bytes inside a single HTTP/2 DATA frame
Syntax:H2MaxDataFrameLen n
Default:H2MaxDataFrameLen 0
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.58 and later.

H2MaxDataFrameLen limits the maximum amount of response body bytes placed into a single HTTP/2 DATA frame. Setting this to 0 places no limit (but the max size allowed by the protocol is observed).

The module, by default, tries to use the maximum size possible, which is somewhat around 16KB. This sets the maximum. When less response data is availble, smaller frames will be sent.

top

H2MaxHeaderBlockLen Directive

Description:Maximum size of response headers
Syntax:H2MaxHeaderBlockLen n
Default:H2MaxHeaderBlockLen 0
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.64 and later.

H2MaxHeaderBlockLen sets the limit on the overall size of response headers. A setting of 0 will leave this at the default of 64 KB in nghttp2.

Responses with headers larger than this (adding all headers) will not be processed and result in a reset of the stream.

top

H2MaxSessionStreams Directive

Description:Maximum number of active streams per HTTP/2 session.
Syntax:H2MaxSessionStreams n
Default:H2MaxSessionStreams 100
Context:server config, virtual host
Status:Extension
Module:mod_http2

This directive sets the maximum number of active streams per HTTP/2 session (e.g. connection) that the server allows. A stream is active if it is not idle or closed according to RFC 7540.

Example

H2MaxSessionStreams 20
top

H2MaxWorkerIdleSeconds Directive

Description:Maximum number of seconds h2 workers remain idle until shut down.
Syntax:H2MaxWorkerIdleSeconds n
Default:H2MaxWorkerIdleSeconds 600
Context:server config
Status:Extension
Module:mod_http2

This directive sets the maximum number of seconds a h2 worker may idle until it shuts itself down. This only happens while the number of h2 workers exceeds H2MinWorkers.

Example

H2MaxWorkerIdleSeconds 20
top

H2MaxWorkers Directive

Description:Maximum number of worker threads to use per child process.
Syntax:H2MaxWorkers n
Context:server config
Status:Extension
Module:mod_http2

This directive sets the maximum number of worker threads to spawn per child process for HTTP/2 processing. If this directive is not used, mod_http2 will chose a value suitable for the mpm module loaded.

Example

H2MaxWorkers 20
top

H2MinWorkers Directive

Description:Minimal number of worker threads to use per child process.
Syntax:H2MinWorkers n
Context:server config
Status:Extension
Module:mod_http2

This directive sets the minimum number of worker threads to spawn per child process for HTTP/2 processing. If this directive is not used, mod_http2 will chose a value suitable for the mpm module loaded.

Example

H2MinWorkers 10
top

H2ModernTLSOnly Directive

Description:Require HTTP/2 connections to be "modern TLS" only
Syntax:H2ModernTLSOnly on|off
Default:H2ModernTLSOnly on
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.18 and later.

This directive toggles the security checks on HTTP/2 connections in TLS mode (https:). This can be used server wide or for specific <VirtualHost>s.

The security checks require that the TSL protocol is at least TLSv1.2 and that none of the ciphers listed in RFC 7540, Appendix A is used. These checks will be extended once new security requirements come into place.

The name stems from the Security/Server Side TLS definitions at mozilla where "modern compatibility" is defined. Mozilla Firefox and other browsers require modern compatibility for HTTP/2 connections. As everything in OpSec, this is a moving target and can be expected to evolve in the future.

One purpose of having these checks in mod_http2 is to enforce this security level for all connections, not only those from browsers. The other purpose is to prevent the negotiation of HTTP/2 as a protocol should the requirements not be met.

Ultimately, the security of the TLS connection is determined by the server configuration directives for mod_ssl.

Example

H2ModernTLSOnly off
top

H2OutputBuffering Directive

Description:Determine buffering behaviour of output
Syntax:H2OutputBuffering on|off
Default:H2OutputBuffering on
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.48 and later.

The directive H2OutputBuffering controls the buffering of stream output. The default is on, which is the behaviour of previous versions. When off, all bytes are made available immediately to the main connection for sending them out to the client. This fixes interop issues with certain flavours of gRPC.

top

H2Padding Directive

Description:Determine the range of padding bytes added to payload frames
Syntax:H2Padding numbits
Default:H2Padding 0
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.39 and later.

With the default 0, no padding bytes are added to any payload frames, e.g. HEADERS, DATA and PUSH_PROMISE. This is the behaviour of previous versions. It means that under certain conditions, an observer of network traffic can see the length of those frames in the TLS stream.

When configuring numbits of 1-8, a random number in range [0, 2^numbits[ are added to each frame. The random value is chosen independently for each frame that the module sends back to the client.

While more padding bytes give better message length obfuscation, they are also additional traffic. The optimal number therefore depends on the kind of web traffic the server carries.

The default of 0, e.g. no padding, was chosen for maximum backward compatibility. There might be deployments where padding bytes are unwanted or do harm. The most likely cause would be a client that has a faults implementation.

top

H2ProxyRequests Directive

Description:En-/Disable forward proxy requests via HTTP/2
Syntax:H2ProxyRequests on|off
Default:H2ProxyRequests off
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.58 and later.

Use H2ProxyRequests to enable or disable handling of HTTP/2 requests in a forward proxy configuration.

Similar to ProxyRequests, this triggers the needed treatment of requests when HTTP/2 is enabled in a forward proxy configuration. Both directive should be enabled.

top

H2Push Directive

Description:H2 Server Push Switch
Syntax:H2Push on|off
Default:H2Push on
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.18 and later.

This directive toggles the usage of the HTTP/2 server push protocol feature.

The HTTP/2 protocol allows the server to push other resources to a client when it asked for a particular one. This is helpful if those resources are connected in some way and the client can be expected to ask for it anyway. The pushing then saves the time it takes the client to ask for the resources itself. On the other hand, pushing resources the client never needs or already has is a waste of bandwidth.

Server pushes are detected by inspecting the Link headers of responses (see https://tools.ietf.org/html/rfc5988 for the specification). When a link thus specified has the rel=preload attribute, it is treated as a resource to be pushed.

Link headers in responses are either set by the application or can be configured via H2PushResource or using mod_headers as:

mod_headers example

<Location /index.html>
    Header add Link "</css/site.css>;rel=preload"
    Header add Link "</images/logo.jpg>;rel=preload"
</Location>

As the example shows, there can be several link headers added to a response, resulting in several pushes being triggered. There are no checks in the module to avoid pushing the same resource twice or more to one client. Use with care.

HTTP/2 server pushes are enabled by default. On a server or virtual host, you may enable/disable this feature for any connection to the host. In addition, you may disable PUSH for a set of resources in a Directory/Location. This controls which resources may cause a PUSH, not which resources may be sent via PUSH.

Example

H2Push off

Last but not least, pushes happen only when the client signals its willingness to accept those. Most browsers do, some, like Safari 9, do not. Also, pushes also only happen for resources from the same authority as the original response is for.

top

H2PushDiarySize Directive

Description:H2 Server Push Diary Size
Syntax:H2PushDiarySize n
Default:H2PushDiarySize 256
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.19 and later.

This directive toggles the maximum number of HTTP/2 server pushes that are remembered per HTTP/2 connection. This can be used inside the <VirtualHost> section to influence the number for all connections to that virtual host.

The push diary records a digest of pushed resources (their URL) to avoid duplicate pushes on the same connection. These value are not persisted, so clients opening a new connection will experience known pushes again.

If the maximum size is reached, newer entries replace the oldest ones. A diary entry uses 8 bytes, letting a default diary with 256 entries consume around 2 KB of memory.

A size of 0 will effectively disable the push diary.

top

H2PushPriority Directive

Description:H2 Server Push Priority
Syntax:H2PushPriority mime-type [after|before|interleaved] [weight]
Default:H2PushPriority * After 16
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.18 and later. For having an effect, a nghttp2 library version 1.5.0 or newer is necessary.

This directive defines the priority handling of pushed responses based on the content-type of the response. This is usually defined per server config, but may also appear in a virtual host.

HTTP/2 server pushes are always related to a client request. Each such request/response pairs, or streams have a dependency and a weight, together defining the priority of a stream.

When a stream depends on another, say X depends on Y, then Y gets all bandwidth before X gets any. Note that this does not mean that Y will block X. If Y has no data to send, all bandwidth allocated to Y can be used by X.

When a stream has more than one dependent, say X1 and X2 both depend on Y, the weight determines the bandwidth allocation. If X1 and X2 have the same weight, they both get half of the available bandwidth. If the weight of X1 is twice as large as that for X2, X1 gets twice the bandwidth of X2.

Ultimately, every stream depends on the root stream which gets all the bandwidth available, but never sends anything. So all its bandwidth is distributed by weight among its children. Which either have data to send or distribute the bandwidth to their own children. And so on. If none of the children have data to send, that bandwidth get distributed somewhere else according to the same rules.

The purpose of this priority system is to always make use of available bandwidth while allowing precedence and weight to be given to specific streams. Since, normally, all streams are initiated by the client, it is also the one that sets these priorities.

Only when such a stream results in a PUSH, gets the server to decide what the initial priority of such a pushed stream is. In the examples below, X is the client stream. It depends on Y and the server decides to PUSH streams P1 and P2 onto X.

The default priority rule is:

Default Priority Rule

H2PushPriority * After 16

which reads as 'Send a pushed stream of any content-type depending on the client stream with weight 16'. And so P1 and P2 will be send after X and, as they have equal weight, share bandwidth equally among themselves.

Interleaved Priority Rule

H2PushPriority text/css Interleaved 256

which reads as 'Send any CSS resource on the same dependency and weight as the client stream'. If P1 has content-type 'text/css', it will depend on Y (as does X) and its effective weight will be calculated as P1ew = Xw * (P1w / 256). With P1w being 256, this will make the effective weight the same as the weight of X. If both X and P1 have data to send, bandwidth will be allocated to both equally.

With Pw specified as 512, a pushed, interleaved stream would get double the weight of X. With 128 only half as much. Note that effective weights are always capped at 256.

Before Priority Rule

H2PushPriority application/json Before

This says that any pushed stream of content type 'application/json' should be send out before X. This makes P1 dependent on Y and X dependent on P1. So, X will be stalled as long as P1 has data to send. The effective weight is inherited from the client stream. Specifying a weight is not allowed.

Be aware that the effect of priority specifications is limited by the available server resources. If a server does not have workers available for pushed streams, the data for the stream may only ever arrive when other streams have been finished.

Last, but not least, there are some specifics of the syntax to be used in this directive:

  1. '*' is the only special content-type that matches all others. 'image/*' will not work.
  2. The default dependency is 'After'.
  3. There are also default weights: for 'After' it is 16, 'interleaved' is 256.

Shorter Priority Rules

H2PushPriority application/json 32         # an After rule
H2PushPriority image/jpeg before           # weight inherited
H2PushPriority text/css   interleaved      # weight 256 default
top

H2PushResource Directive

Description:Declares resources for early pushing to the client
Syntax:H2PushResource [add] path [critical]
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.24 and later.

When added to a directory/location HTTP/2 PUSHes will be attempted for all paths added via this directive. This directive can be used several times for the same location.

This directive pushes resources much earlier than adding Link headers via mod_headers. mod_http2 announces these resources in a 103 Early Hints interim response to the client. That means that clients not supporting PUSH will still get early preload hints.

In contrast to setting Link response headers via mod_headers, this directive will only take effect on HTTP/2 connections.

By adding critical to such a resource, the server will give processing it more preference and send its data, once available, before the data from the main request.

top

H2SerializeHeaders Directive

Description:Serialize Request/Response Processing Switch
Syntax:H2SerializeHeaders on|off
Default:H2SerializeHeaders off
Context:server config, virtual host
Status:Extension
Module:mod_http2

This directive toggles if HTTP/2 requests shall be serialized in HTTP/1.1 format for processing by httpd core or if received binary data shall be passed into the request_recs directly.

Serialization will lower performance, but gives more backward compatibility in case custom filters/hooks need it.

Example

H2SerializeHeaders on
top

H2StreamMaxMemSize Directive

Description:Maximum amount of output data buffered per stream.
Syntax:H2StreamMaxMemSize bytes
Default:H2StreamMaxMemSize 65536
Context:server config, virtual host
Status:Extension
Module:mod_http2

This directive sets the maximum number of outgoing data bytes buffered in memory for an active streams. This memory is not allocated per stream as such. Allocations are counted against this limit when they are about to be done. Stream processing freezes when the limit has been reached and will only continue when buffered data has been sent out to the client.

Example

H2StreamMaxMemSize 128000
top

H2StreamTimeout Directive

Description:Maximum time waiting when sending/receiving data to stream processing
Syntax:H2StreamTimeout time-interval[s]
Default:Value of Timeout
Context:server config, virtual host, directory
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.55 and later.

H2StreamTimeout specifies the maximum time that a stream being processed will wait for its data to be sent/received.

top

H2TLSCoolDownSecs Directive

Description:Configure the number of seconds of idle time on TLS before shrinking writes
Syntax:H2TLSCoolDownSecs seconds
Default:H2TLSCoolDownSecs 1
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.18 and later.

This directive sets the number of seconds of idle time on a TLS connection before the TLS write size falls back to small (~1300 bytes) length. This can be used server wide or for specific <VirtualHost>s.

See H2TLSWarmUpSize for a description of TLS warmup. H2TLSCoolDownSecs reflects the fact that connections may deteriorate over time (and TCP flow adjusts) for idle connections as well. It is beneficial to overall performance to fall back to the pre-warmup phase after a number of seconds that no data has been sent.

In deployments where connections can be considered reliable, this timer can be disabled by setting it to 0.

The following example sets the seconds to zero, effectively disabling any cool down. Warmed up TLS connections stay on maximum record size.

Example

H2TLSCoolDownSecs 0
top

H2TLSWarmUpSize Directive

Description:Configure the number of bytes on TLS connection before doing max writes
Syntax:H2TLSWarmUpSize amount
Default:H2TLSWarmUpSize 1048576
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.18 and later.

This directive sets the number of bytes to be sent in small TLS records (~1300 bytes) until doing maximum sized writes (16k) on https: HTTP/2 connections. This can be used server wide or for specific <VirtualHost>s.

Measurements by google performance labs show that best performance on TLS connections is reached, if initial record sizes stay below the MTU level, to allow a complete record to fit into an IP packet.

While TCP adjust its flow-control and window sizes, longer TLS records can get stuck in queues or get lost and need retransmission. This is of course true for all packets. TLS however needs the whole record in order to decrypt it. Any missing bytes at the end will stall usage of the received ones.

After a sufficient number of bytes have been send successfully, the TCP state of the connection is stable and maximum TLS record sizes (16 KB) can be used for optimal performance.

In deployments where servers are reached locally or over reliable connections only, the value might be decreased with 0 disabling any warmup phase altogether.

The following example sets the size to zero, effectively disabling any warmup phase.

Example

H2TLSWarmUpSize 0
top

H2Upgrade Directive

Description:H2 Upgrade Protocol Switch
Syntax:H2Upgrade on|off
Default:H2Upgrade on for h2c, off for h2 protocol
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_http2

This directive toggles the usage of the HTTP/1.1 Upgrade method for switching to HTTP/2. This should be used inside a <VirtualHost> section to enable Upgrades to HTTP/2 for that virtual host.

This method of switching protocols is defined in HTTP/1.1 and uses the "Upgrade" header (thus the name) to announce willingness to use another protocol. This may happen on any request of a HTTP/1.1 connection.

This method of protocol switching is enabled by default on cleartext (potential h2c) connections and disabled on TLS (potential h2), as mandated by RFC 7540.

Please be aware that Upgrades are only accepted for requests that carry no body. POSTs and PUTs with content will never trigger an upgrade to HTTP/2. See H2Direct for an alternative to Upgrade.

This mode only has an effect when h2 or h2c is enabled via the Protocols.

Example

H2Upgrade on
top

H2WebSockets Directive

Description:En-/Disable WebSockets via HTTP/2
Syntax:H2WebSockets on|off
Default:H2WebSockets off
Context:server config, virtual host
Status:Extension
Module:mod_http2
Compatibility:Available in version 2.4.58 and later.

Use H2WebSockets to enable or disable bootstrapping of WebSockets via the HTTP/2 protocol. This protocol extension is defined in RFC 8441.

Such requests come as a CONNECT with an extra ':protocol' header. Such requests are transformed inside the module to their HTTP/1.1 equivalents before passing it to internal processing.

This means that HTTP/2 WebSockets can be used for a ProxyPass with 'upgrade=websocket' parameter without further changes.

For (3rd party) modules that handle WebSockets directly in the server, the protocol bootstrapping itself will also work. However the transfer of data does require extra support in case of HTTP/2. The negotiated WebSocket will not be able to use the client connection socket for polling IO related events.

Because enabling this feature might break backward compatibility for such 3rd party modules, it is not enabled by default.

top

H2WindowSize Directive

Description:Size of Stream Window for upstream data.
Syntax:H2WindowSize bytes
Default:H2WindowSize 65535
Context:server config, virtual host
Status:Extension
Module:mod_http2

This directive sets the size of the window that is used for flow control from client to server and limits the amount of data the server has to buffer. The client will stop sending on a stream once the limit has been reached until the server announces more available space (as it has processed some of the data).

This limit affects only request bodies, not its meta data such as headers. Also, it has no effect on response bodies as the window size for those are managed by the clients.

Example

H2WindowSize 128000

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_config.html.ja.utf80000664000175100017510000010350014743132254022723 0ustar covenercovener mod_log_config - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_log_config

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:サーバへのリクエストのロギング
ステータス:Base
モジュール識別子:log_config_module
ソースファイル:mod_log_config.c

概要

このモジュールはクライアントのリクエストを柔軟にログ収集する機能を 提供します。ログはカスタマイズ可能な書式で書かれ、ファイルに直接 書いたり、外部プログラムに渡したりすることができます。個々のリクエストを 特徴に応じてログに書いたり書かなかったりできるように、条件による ログ収集も提供されています。

このモジュールは三つのディレクティブ提供します: ログファイルを作成するための TransferLog, 新しい書式を 定義する LogFormat, ログファイルと 書式を一度に定義する CustomLog です。 各リクエストが複数回ログ収集されるようにするために TransferLog ディレクティブと CustomLog ディレクティブは複数回使用することができます。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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 リクエストを扱っているサーバの正式なポート
%{format}p サーバがリクエストを処理しているポートの公式 (訳注: canonical) のポート番号か、 サーバの実際のポート番号か、クライアント側の実際のポート番号かです。 format に使える文字列は canonical, local, remote になります。
%P リクエストを扱った子プロセスのプロセス ID
%{format}P リクエストを扱ったワーカーのプロセス ID かスレッド ID。 format として有効な値は pid, tid, hextid です。hextid を使うには APR 1.2.0 以降が必要です。
%q 問い合せ文字列 (存在する場合は前に ? が追加される。 そうでない場合は空文字列)
%r リクエストの最初の行
%s ステータス。内部でリダイレクトされたリクエストは、元々の リクエストのステータス --- 最後のステータスは %>s
%t リクエストを受付けた時刻。 CLF の時刻の書式 (標準の英語の書式)
%{format}t format で与えられた書式による時刻。format は strftime (3) の 書式である必要がある。(地域化されている可能性がある)
%T リクエストを扱うのにかかった時間、秒単位
%u リモートユーザ (認証によるもの。ステータス (%s) が 401 のときは意味がないものである可能性がある)
%U リクエストされた URL パス。クエリ文字列は含まない
%v リクエストを扱っているサーバの正式な ServerName
%V UseCanonicalName の設定によるサーバ名
%X 応答が完了したときの接続ステータス:
X = 応答が完了する前に接続が異常終了
+ = 応答が送られた後に接続を持続することが可能
- = 応答が送られた後に接続が切られる

(このディレクティブは Apache 1.3 の後期のバージョンでは %c に割り当てられて いましたが、これは歴史的に ssl が使用している %{var}c 構文と衝突していました。)

%I リクエストとヘッダを含む、受け取ったバイト数。 0 にはならない。 これを使用するためには mod_logio が必要
%O ヘッダを含む、送信したバイト数。0 にはならない。 これを使用するためには mod_logio が必要

修飾子

特定の要素は "%" の直後に HTTP ステータスコードをカンマ区切りで 指定することで、表示を制限することができます。例えば "%400,501{User-agent}i" では、 400 と 500 番エラーでのみ User-agent をログします。 他のステータスコードでは "-" という文字列が ログされます。ステータスコードのリストは "!" で否定を指定することができます : "%!200,304,302{Referer}i" は、指定された 3 つのコードのどれにも該当しないリクエスト全てで Referer をログします。

修飾子 "<" と ">" は内部リダイレクトされたリクエストのログに 元のリクエストか最終的なリクエストのどちらを使用するかを 指定するために使います。デフォルトでは、% ディレクティブの %s, %U, %T, %D, %r は元のリクエストを、他は最終的なリクエストを 使用します。例えば、リクエストの最終ステータスを記録するには %>s を、内部的に認証されていないリソースへリダイレクトされた リクエストで元のリクエストで認証されたユーザを記録するためには %<u を使うことができます。

その他注意点

セキュリティ上の理由により 2.0.46 より、 %r, %i, %o に入っている、 印字不可能な文字と他の特別な文字は、\xhh という形式の文字列でエスケープされるようになりました。hh は そのままのバイトの値の 16 進での値です。この規則の例外には、 バックスラッシュを使ってエスケープされる "\ と、 C 形式の表記法が使われる空白文字 (\n, \t など) があります。2.0.46 以前のバージョンではエスケープ処理は行われませんので、 生ログファイルを扱う際に注意が必要です。

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"
top

セキュリティに関して

ログファイルが保存されているディレクトリがサーバを起動した以外のユーザで 書き込み可能なときにセキュリティの問題が発生する理由の詳細はセキュリティのこつ を参照してください。

top

BufferedLogs ディレクティブ

説明:ディスクに書き出す前にメモリにログエントリをバッファする
構文:BufferedLogs On|Off
デフォルト:BufferedLogs Off
コンテキスト:サーバ設定ファイル
ステータス:Base
モジュール:mod_log_config
互換性:2.0.41 以降

BufferedLogs ディレクティブを使うと mod_log_config の挙動が変化して、 複数のログを書き出す際に、それぞれのリクエスト処理後毎に 書き出すのではなく、いったんメモリに蓄えてから、 まとめてディスクに書き出すようになります。 この結果ディスクアクセスがより効率的になり、 高いパフォーマンスの得られるシステムもあるでしょう。 このディレクティブはサーバ全体で一度だけ設定できます; バーチャルホストごとに設定することはできません。

このディレクティブは実験的なものですので、 使用する際は注意してください。
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

GlobalLog ディレクティブ

説明:Sets filename and format of log file
構文:GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]
コンテキスト:サーバ設定ファイル
ステータス:Base
モジュール:mod_log_config
互換性:Available in Apache HTTP Server 2.4.19 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

LogFormat ディレクティブ

説明:ログファイルで使用する書式を設定する
構文:LogFormat format|nickname [nickname]
デフォルト:LogFormat "%h %l %u %t \"%r\" %>s %b"
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Base
モジュール:mod_log_config

このディレクティブはアクセスログファイルの書式を指定します。

LogFormat ディレクティブは二つの形式のどちらかを とることができます。最初の形式では一つの引数のみが指定され、 続く TransferLog で指定されたログで使われるログの書式を設定します。この単独の引数では 上のカスタムログ書式で説明されているように format を明示的に指定することができます。 もしくは、下で説明されているように前に LogFormat ディレクティブで定義されたログの書式を nicknameを使って 参照することもできます。

LogFormat ディレクティブの二つめの形式は formatnickname を与えます。 フォーマット文字列全体を再び書くかわりに、 この 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

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_example_hooks.html.fr.utf80000664000175100017510000002762514740503670023506 0ustar covenercovener mod_example_hooks - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_example_hooks

Langues Disponibles:  en  |  fr  |  ko 

Description:Illustration de l'API des modules Apache
Statut:Expérimental
Identificateur de Module:example_hooks_module
Fichier Source:mod_example_hooks.c

Sommaire

Certains fichiers situés dans le répertoire modules/examples de l'arborescence de la distribution d'Apache sont fournis à titre d'exemples pour ceux qui souhaitent écrire des modules qui utilisent l'API d'Apache.

Le fichier principal est mod_example_hooks.c, qui constitue une illustration exhaustive des différents mécanismes et syntaxes d'appels. En aucun cas un module additionnel n'aura à inclure des routines pour tous les appels - il n'en nécessitera au contraire qu'un petit nombre !

Le module example_hooks fonctionne réellement. Si vous le chargez dans votre serveur, activez le gestionnaire "example-hooks-handler" dans une section location, et essayez d'accéder à la zone du site web correspondante, vous verrez s'afficher certaines sorties que le module example_hooks produit au cours des différents appels.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Compilation du module example_hooks

Pour inclure le module example_hooks dans votre serveur, effectuez les étapes suivantes :

  1. Exécutez configure avec l'option --enable-example-hooks.
  2. Compilez le serveur (exécutez la commande "make").

Pour ajouter votre propre module :

  1. cp modules/examples/mod_example_hooks.c modules/nouveau_module/mod_monexemple.c
  2. Modifiez le fichier.
  3. Créez modules/nouveau_module/config.m4.
    1. Ajoutez APACHE_MODPATH_INIT(nouveau_module).
    2. Copiez la ligne APACHE_MODULE contenant "example_hooks" depuis modules/examples/config.m4.
    3. Remplacez le premier argument "example-hooks" par monexemple.
    4. Remplacez le second argument par une brève description de votre module. Cette description sera utilisée par la commande configure --help.
    5. Si la compilation de votre module nécessite des drapeaux de compilation C, des drapeaux d'édition de liens, ou de bibliothèques supplémentaires, ajoutez les respectivement à CFLAGS, LDFLAGS et LIBS. Reportez-vous aux fichiers config.m4 des répertoires des autres modules pour plus d'exemples.
    6. Ajoutez APACHE_MODPATH_FINISH.
  4. Créez le fichier module/nouveau_module/Makefile.in. Si la compilation de votre module ne nécessite pas d'instructions particulières, ce fichier ne doit contenir que la ligne include $(top_srcdir)/build/special.mk.
  5. Exécutez ./buildconf à la racine du répertoire.
  6. Compilez le serveur après avoir exécuté la commande configure avec l'option --enable-monexemple.
top

Utilisation du module mod_example_hooks

Pour activer le module example_hooks, ajoutez à votre fichier httpd.conf un bloc du style :

<Location "/example-hooks-info">
   SetHandler example-hooks-handler
</Location>

Vous pouvez aussi ajouter ce qui suit dans un fichier .htaccess, puis accéder au fichier "test.example" à partir du répertoire correspondant :

AddHandler example-hooks-handler ".example"

Après avoir rechargé la configuration ou redémarré votre serveur, vous devriez pouvoir accéder à ce fichier et voir s'afficher ce qui a été décrit plus haut.

top

Directive Example

Description:Directive de démonstration pour illustrer l'API des modules Apache
Syntaxe:Example
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Expérimental
Module:mod_example_hooks

La directive Example n'a pour fonction que de définir un drapeau de démonstration que le gestionnaire de contenu du module example_hooks va afficher. Elle ne possède aucun argument. Si vous naviguez vers une URL à laquelle le gestionnaire de contenu example_hooks s'applique, vous verrez s'afficher les routines du module, ainsi que l'ordre dans lequel elles ont été appelées pour servir le document demandé. On peut observer l'effet de cette directive dans la phrase "Example directive declared here: YES/NO".

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_logio.html.ja.utf80000664000175100017510000002437514743132254021742 0ustar covenercovener mod_logio - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_logio

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:リクエスト毎に入力バイト数と出力バイト数とをロギング
ステータス:Extension
モジュール識別子:logio_module
ソースファイル:mod_logio.c

概要

このモジュールはリクエストごとに受け取ったバイト数と 送信したバイト数のロギングを行なう機能を提供します。 記録される数字はリクエストのヘッダとレスポンスの本体を 反映した、実際にネットワークで受け取ったバイト値です。 入力では SSL/TLS の前に、出力では SSL/TLS の後に数えるので、 数字は暗号による変化も正しく反映したものになります。

このモジュールの使用には mod_log_config モジュールが 必要です。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

カスタムログ書式

このモジュールは新しいロギング用ディレクティブを加えます。 リクエスト自身の特徴はフォーマット文字列に、以下の様に置換される "%" ディレクティブを 入れることでログ収集されます:

フォーマット文字列 説明
%...I リクエストとヘッダを含む、受け取ったバイト数。 0 にはならない。
%...O ヘッダを含む、送信したバイト数。0 にはならない。

通常、この機能は以下の様に使用されます:

結合 I/O ログ書式:
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %I %O"
top

LogIOTrackTTFB ディレクティブ

説明:Enable tracking of time to first byte (TTFB)
構文:LogIOTrackTTFB ON|OFF
デフォルト:LogIOTrackTTFB OFF
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Extension
モジュール:mod_logio
互換性:Apache HTTP Server 2.4.13 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/worker.html.fr.utf80000664000175100017510000004041714740503670021314 0ustar covenercovener worker - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Apache MPM worker

Langues Disponibles:  de  |  en  |  fr  |  ja  |  tr 

Description:Module multi-processus implémentant un serveur web hybride multi-processus multi-thread
Statut:MPM
Identificateur de Module:mpm_worker_module
Fichier Source:worker.c

Sommaire

Ce module multi-processus (MPM) implémente un serveur hybride multi-processus multi-thread. En utilisant les threads pour servir les requêtes, il peut en traiter un grand nombre tout en consommant moins de ressources qu'un serveur à base de processus. Cependant, il conserve une grande partie de la stabilité d'un serveur à base de processus en maintenant plusieurs processus disponibles, chacun de ces derniers possédant de nombreux threads.

Les directives les plus importantes qui permettent de contrôler ce MPM sont ThreadsPerChild, qui définit le nombre de threads lancés par chaque processus enfant et MaxRequestWorkers, qui définit le nombre global maximum de threads qui peuvent être lancés.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Comment ça marche

Un processus de contrôle unique (le parent) a pour tâche de lancer les processus enfants. Chaque processus enfant crée un nombre fixe de threads serveurs selon la valeur de la directive ThreadsPerChild, ainsi qu'un thread chargé d'attendre les connexions et de les passer à un thread serveur pour traitement au fur et à mesure de leur arrivée.

Le serveur HTTP Apache essaie toujours de maintenir un jeu de threads serveurs inactifs ou en réserve, qui se tiennent prêts à traiter les requêtes entrantes. De cette façon, les clients n'ont pas besoin d'attendre la création d'un nouveau thread ou d'un nouveau processus pour que leurs requêtes puissent être traitées. Le nombre de processus lancés initialement est défini par la directive StartServers. En cours de fonctionnement, le serveur évalue le nombre total de threads inactifs dans tous les processus, et en crée ou en arrête de façon à maintenir ce nombre à l'intérieur des limites définies par les directives MinSpareThreads et MaxSpareThreads. Comme ce module s'auto-contrôle de manière efficace, on peut en général conserver les valeurs par défaut. Le nombre maximum de clients pouvant être servis simultanément (c'est à dire le nombre global maximum de threads pour tous les processus) est défini par la directive MaxRequestWorkers. Le nombre maximum de processus enfants actifs est défini par la valeur de la directive MaxRequestWorkers divisée par la valeur de la directive ThreadsPerChild.

Deux directives permettent de fixer des limites absolues pour le nombre de processus enfants actifs et le nombre de threads serveurs par processus enfant, et ne peuvent être modifiées qu'en arrêtant complètement le serveur et en le démarrant à nouveau. La valeur de la directive ServerLimit constitue une limite absolue pour le nombre de processus enfants actifs, et doit être supérieure ou égale à la valeur de la directive MaxRequestWorkers divisée par la valeur de la directive ThreadsPerChild. La valeur de la directive ThreadLimit constitue une limite absolue pour le nombre de threads par processus enfant, et doit être supérieure ou égale à la valeur de la directive ThreadsPerChild.

En plus du jeu de processus enfants actifs, il peut exister quelques processus enfants en cours d'arrêt, mais dont au moins un thread serveur est encore en train de traiter une connexion client existante. Il peut subsister en théorie jusqu'à MaxRequestWorkers processus en cours d'arrêt, bien qu'en réalité, ce nombre sera en général beaucoup plus petit. Ce comportement peut être évité en désactivant l'arrêt de processus enfants individuels de la manière suivante :

Voici un exemple typique de configuration du contrôle processus-thread pour le MPM worker :

ServerLimit         16
StartServers         2
MaxRequestWorkers  150
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25

Alors que le processus parent est en général démarré en tant que root sous Unix afin de se mettre en écoute du port 80, les processus enfants et les threads sont lancés par le serveur sous un utilisateur avec privilèges restreints. On peut utiliser les directives User et Group pour définir les privilèges des processus enfants. Les processus enfants doivent pouvoir être en mesure de lire tous les contenus destinés à être servis, mais doivent avoir des privilèges aussi bas que possible. De plus, ces directives définissent également les privilèges dont vont hériter les scripts CGI (sauf si on utilise suexec).

La directive MaxConnectionsPerChild permet de définir la fréquence à laquelle le serveur recycle ses processus en arrêtant les plus anciens et en en lançant de nouveaux.

Ce module MPM utilise le mutex mpm-accept pour sérialiser l'accès aux connexions entrantes lorsqu'un problème d'afflux de requêtes peut survenir (en général, lorsqu'il y a plusieurs sockets en écoute). Les différents aspects de l'implémentation de ce mutex peuvent être configurés via la directive Mutex. Vous trouverez des informations plus détaillées à propos de ce mutex dans la documentation sur les conseils en matière de performances.

Langues Disponibles:  de  |  en  |  fr  |  ja  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/core.html.es0000664000175100017510000101736414743132254020053 0ustar covenercovener core - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4 > Módulos

Funcionalidad Básica de Apache

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  tr 

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.
Descripción:Funcionalides básicas del Servidor HTTP Apache que siempre están presentes.
Estado:Core
Support Apache!

Directivas

Lista de comprobación de errores corregidos

Consulte también

top

Directiva AcceptFilter

Descripción:Configura mejoras para un Protocolo de Escucha de Sockets
Sintaxis:AcceptFilter protocol accept_filter
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Disponible en Apache httpd 2.1.5 y posteriores. En Windows desde Apache httpd 2.3.3 y posteriores.

Esta directiva hace posible mejoras específicas a nivel de sistema operativo y a través del tipo de Protocolo para un socket que escucha. La premisa básica es que el kernel no envíe un socket al servidor hasta que o bien los datos se hayan recibido o bien se haya almacenado en el buffer una Respuesta HTTP completa. Actualmente sólo están soportados Accept Filters sobre FreeBSD, TCP_DEFER_ACCEPT sobre Linux, y AcceptEx() sobre Windows.

El uso de none para un argumento desactiva cualquier filtro aceptado para ese protocolo. Esto es útil para protocolos que requieren que un servidor envíe datos primeros, tales como ftp: o nntp:

AcceptFilter nntp none

Los nombres de protocolo por defecto son https para el puerto 443 y http para todos los demás puertos. Para especificar que se está utilizando otro protocolo con un puerto escuchando, añade el argumento protocol a la directiva Listen.

Sobre FreeBDS los valores por defecto:

AcceptFilter http httpready
AcceptFilter https dataready

El filtro httpready almacena en el buffer peticiones HTTP completas a nivel de kernel. Una vez que la petición es recibida, el kernel la envía al servidor. Consulta la página man de accf_http(9) para más detalles. Puesto que las peticiones HTTPS están encriptadas, sólo se utiliza el filtro accf_data(9).

Sobre Linux los valores por defecto son:

AcceptFilter http data
AcceptFilter https data

En Linux, TCP_DEFER_ACCEPT no soporta el buffering en peticiones http. Cualquier valor además de none habilitará TCP_DEFER_ACCEPT en ese socket. Para más detalles ver la página man de Linux tcp(7).

Sobre Windows los valores por defecto son:

AcceptFilter http data
AcceptFilter https data

Sobre Windows mpm_winnt interpreta el argumento AcceptFilter para conmutar la API AcceptEx(), y no soporta el buffering sobre el protocolo http. Hay dos valores que utilizan la API Windows AcceptEx() y que recuperan sockets de red entre conexciones. data espera hasta que los datos han sido transmitidos como se comentaba anteriormente, y el buffer inicial de datos y las direcciones de red son recuperadas a partir de una única llamada AcceptEx(). connect utiliza la API AcceptEx() API, y recupera también las direcciones de red, pero a diferencia de none la opción connect no espera a la transmisión inicial de los datos.

Sobre Windows, none prefiere accept() antes que AcceptEx() y no recuperará sockets entre las conexiones. Lo que es útil para los adaptadores de red con un soporte precario de drivers, así como para algunos proveedores de red tales como drivers vpn, o filtros de spam, de virus o de spyware.

Consulte también

top

Directiva AcceptPathInfo

Descripción:Los recursos aceptan información sobre su ruta
Sintaxis:AcceptPathInfo On|Off|Default
Valor por defecto:AcceptPathInfo Default
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:Disponible en Apache httpd 2.0.30 y posteriores

Esta directiva controla si las peticiones que contienen información sobre la ruta que sigue un fichero que existe (o un fichero que no existe pero en un directorio que sí existe) serán aceptadas o denegadas. La información de ruta puede estar disponible para los scripts en la variable de entorno PATH_INFO.

Por ejemplo, asumamos que la ubicación /test/ apunta a un directorio que contiene únicamente el fichero here.html. Entonces, las peticiones tanto para /test/here.html/more como para /test/nothere.html/more recogen /more como PATH_INFO.

Los tres posibles argumentos para la directiva AcceptPathInfo son los siguientes:

Off
Una petición sólo será aceptada si se corresponde con una ruta literal que existe. Por lo tanto, una petición con una información de ruta después del nombre de fichero tal como /test/here.html/more en el ejemplo anterior devolverá un error 404 NOT FOUND.
On
Una petición será aceptada si una ruta principal de acceso se corresponde con un fichero que existe. El ejemplo anterior /test/here.html/more será aceptado si /test/here.html corresponde a un fichero válido.
Default
La gestión de las peticiones con información de ruta está determinada por el controlador responsable de la petición. El controlador principal para para ficheros normales rechaza por defecto peticiones PATH_INFO. Los controladores que sirven scripts, tales como cgi-script e isapi-handler, normalmente aceptan PATH_INFO por defecto.

El objetivo principal de la directiva AcceptPathInfo es permitirte sobreescribir la opción del controlador de aceptar or rechazar PATH_INFO. Este tipo de sobreescritura se necesita, por ejemplo, cuando utilizas un filtro, tal como INCLUDES, para generar contenido basado en PATH_INFO. El controlador principal normalmente rechazaría la petición, de modo que puedes utilizar la siguiente configuración para habilitarla como script:

<Files "mypaths.shtml">
Options +Includes
SetOutputFilter INCLUDES
AcceptPathInfo On
</Files>

top

Directiva AccessFileName

Descripción:Nombre del fichero distribuido de configuración
Sintaxis:AccessFileName filename [filename] ...
Valor por defecto:AccessFileName .htaccess
Contexto:server config, virtual host
Estado:Core
Módulo:core

Mientras que procesa una petición el servidor busca el primer fichero de configuración existente dentro de un listado de nombres en cada directorio de la ruta del documento, si los ficheros distribuidos de configuración están habilitados para ese directorio. Por ejemplo:

AccessFileName .acl

antes de servir el documento /usr/local/web/index.html, el servidor leerá /.acl, /usr/.acl, /usr/local/.acl and /usr/local/web/.acl para las directivas, salvo que estén deshabilitadas with

<Directory />
AllowOverride None
</Directory>

Consulte también

top

Directiva AddDefaultCharset

Descripción:Default charset parameter to be added when a response content-type is text/plain or text/html
Sintaxis:AddDefaultCharset On|Off|charset
Valor por defecto:AddDefaultCharset Off
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo: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 Internet media types (MIME 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.

Consulte también

top

Directiva AllowEncodedSlashes

Descripción:Determines whether encoded path separators in URLs are allowed to be passed through
Sintaxis:AllowEncodedSlashes On|Off
Valor por defecto:AllowEncodedSlashes Off
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Available in Apache httpd 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.

Consulte también

top

Directiva AllowOverride

Descripción:Types of directives that are allowed in .htaccess files
Sintaxis:AllowOverride All|None|directive-type [directive-type] ...
Valor por defecto:AllowOverride None (2.3.9 and later), AllowOverride All (2.3.8 and earlier)
Contexto:directory
Estado:Core
Módulo: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 (ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, and mod_mime Add* and Remove* directives), document meta data (Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName), mod_rewrite directives RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule) and Action from mod_actions.
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.

For security and performance reasons, do not set AllowOverride to anything other than None in your <Directory /> block. Instead, find (or create) the <Directory> block that refers to the directory where you're actually planning to place a .htaccess file.

Consulte también

top

Directiva AllowOverrideList

Descripción:Individual directives that are allowed in .htaccess files
Sintaxis:AllowOverrideList None|directive [directive-type] ...
Valor por defecto:AllowOverrideList None
Contexto:directory
Estado:Core
Módulo:core

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva CGIMapExtension

Descripción:Technique for locating the interpreter for CGI scripts
Sintaxis:CGIMapExtension cgi-path .extension
Contexto:directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:NetWare only

This directive is used to control how Apache httpd 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

Directiva CGIPassAuth

Descripción:Enables passing HTTP authorization headers to scripts as CGI variables
Sintaxis:CGIPassAuth On|Off
Valor por defecto:CGIPassAuth Off
Contexto:directory, .htaccess
Anula:AuthConfig
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 2.4.13 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva CGIVar

Descripción:Controls how some CGI variables are set
Sintaxis:CGIVar variable rule
Contexto:directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 2.4.21 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva ContentDigest

Descripción:Enables the generation of Content-MD5 HTTP Response headers
Sintaxis:ContentDigest On|Off
Valor por defecto:ContentDigest Off
Contexto:server config, virtual host, directory, .htaccess
Anula:Options
Estado:Core
Módulo:core

This directive enables the generation of Content-MD5 headers as defined in RFC1864 respectively RFC2616.

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

Directiva DefaultRuntimeDir

Descripción:Base directory for the server run-time files
Sintaxis:DefaultRuntimeDir directory-path
Valor por defecto:DefaultRuntimeDir DEFAULT_REL_RUNTIMEDIR (logs/)
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Available in Apache 2.4.2 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva DefaultType

Descripción:This directive has no effect other than to emit warnings if the value is not none. In prior versions, DefaultType would specify a default media type to assign to response content for which no other media type configuration could be found.
Sintaxis:DefaultType media-type|none
Valor por defecto:DefaultType none
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:The argument none is available in Apache httpd 2.2.7 and later. All other choices are DISABLED for 2.3.x and later.

This directive has been disabled. For backwards compatibility of configuration files, it may be specified with the value none, meaning no default media type. For example:

DefaultType None

DefaultType None is only available in httpd-2.2.7 and later.

Use the mime.types configuration file and the AddType to configure media type assignments via file extensions, or the ForceType directive to configure the media type for specific resources. Otherwise, the server will send the response without a Content-Type header field and the recipient may attempt to guess the media type.

top

Directiva Define

Descripción:Define the existence of a variable
Sintaxis:Define parameter-name
Contexto:server config
Estado:Core
Módulo:core

Equivalent to passing the -D argument to httpd.

This directive can be used to toggle the use of <IfDefine> sections without needing to alter -D arguments in any startup scripts.

top

Directiva <Directory>

Descripción:Enclose a group of directives that apply only to the named file-system directory, sub-directories, and their contents.
Sintaxis:<Directory directory-path> ... </Directory>
Contexto:server config, virtual host
Estado:Core
Módulo:core

<Directory> and </Directory> are used to enclose a group of directives that will apply only to the named directory, sub-directories of that directory, and the files within the respective directories. 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 httpd 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.

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:

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 access for <Directory /> is Allow from All. This means that Apache httpd 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.

Consulte también

top

Directiva <DirectoryMatch>

Descripción:Enclose directives that apply to the contents of file-system directories matching a regular expression.
Sintaxis:<DirectoryMatch regex> ... </DirectoryMatch>
Contexto:server config, virtual host
Estado:Core
Módulo:core

<DirectoryMatch> and </DirectoryMatch> are used to enclose a group of directives which will apply only to the named directory (and the files within), 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.

Compatability

Prior to 2.3.9, this directive implicitly applied to sub-directories (like <Directory>) and could not match the end of line symbol ($). In 2.3.9 and later, only directories that match the expression are affected by the enclosed directives.

Trailing Slash

This directive applies to requests for directories that may or may not end in a trailing slash, so expressions that are anchored to the end of line ($) must be written with care.

Consulte también

top

Directiva DocumentRoot

Descripción:Directory that forms the main document tree visible from the web
Sintaxis:DocumentRoot directory-path
Valor por defecto:DocumentRoot /usr/local/apache/htdocs
Contexto:server config, virtual host
Estado:Core
Módulo: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.

Consulte también

top

Directiva <Else>

Descripción:Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
Sintaxis:<Else> ... </Else>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core
Compatibilidad:Nested conditions are evaluated in 2.4.26 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva <ElseIf>

Descripción:Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
Sintaxis:<ElseIf expression> ... </ElseIf>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core
Compatibilidad:Nested conditions are evaluated in 2.4.26 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva EnableMMAP

Descripción:Use memory-mapping to read files during delivery
Sintaxis:EnableMMAP On|Off
Valor por defecto:EnableMMAP On
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo: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 httpd 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:

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

Directiva EnableSendfile

Descripción:Use the kernel sendfile support to deliver files to the client
Sintaxis:EnableSendfile On|Off
Valor por defecto:EnableSendfile Off
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:Available in version 2.0.44 and later. Default changed to Off in version 2.3.9.

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 httpd 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:

For server configurations that are not vulnerable to these problems, you may enable this feature by specifying:

EnableSendfile On

For network mounted files, this feature may be disabled explicitly for the offending files by specifying:

<Directory "/path-to-nfs-files"> EnableSendfile Off </Directory>

Please note that the per-directory and .htaccess configuration of EnableSendfile is not supported by mod_cache_disk. Only global definition of EnableSendfile is taken into account by the module.

top

Directiva Error

Descripción:Abort configuration parsing with a custom error message
Sintaxis:Error message
Contexto:server config, virtual host, directory, .htaccess
Estado:Core
Módulo:core
Compatibilidad:2.3.9 and later

If an error can be detected within the configuration, this directive can be used to generate a custom error message, and halt configuration parsing. The typical use is for reporting required modules which are missing from the configuration.

Example

# ensure that mod_include is loaded
<IfModule !include_module>
Error mod_include is required by mod_foo. Load it with LoadModule.
</IfModule>

# ensure that exactly one of SSL,NOSSL is defined
<IfDefine SSL>
<IfDefine NOSSL>
Error Both SSL and NOSSL are defined. Define only one of them.
</IfDefine>
</IfDefine>
<IfDefine !SSL>
<IfDefine !NOSSL>
Error Either SSL or NOSSL must be defined.
</IfDefine>
</IfDefine>

top

Directiva ErrorDocument

Descripción:What the server will return to the client in case of an error
Sintaxis:ErrorDocument error-code document
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core

In the event of a problem or error, Apache httpd can be configured to do one of four things,

  1. output a simple hardcoded error message
  2. output a customized message
  3. redirect to a local URL-path to handle the problem/error
  4. redirect to an external URL to handle the problem/error

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 httpd 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 httpd's simple hardcoded message. While not required under normal circumstances, default will restore Apache httpd'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 HTTP Server 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.

If you are using mod_proxy, you may wish to enable ProxyErrorOverride so that you can provide custom error messages on behalf of your Origin servers. If you don't enable ProxyErrorOverride, Apache httpd will not generate custom error documents for proxied content.

Consulte también

top

Directiva ErrorLog

Descripción:Location where the server will log errors
Sintaxis: ErrorLog file-path|syslog[:facility]
Valor por defecto:ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and OS/2)
Contexto:server config, virtual host
Estado:Core
Módulo: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 character "|" then it is assumed to be a command to spawn to handle the error log.

Example

ErrorLog "|/usr/local/bin/httpd_errors"

See the notes on piped logs for more information.

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). The facility is effectively global, and if it is changed in individual virtual hosts, the final facility specified affects the entire server.

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.

Consulte también

top

Directiva ErrorLogFormat

Descripción:Format specification for error log entries
Sintaxis: ErrorLog [connection|request] format
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Available in Apache httpd 2.3.9 and later

ErrorLogFormat allows to specify what supplementary information is logged in the error log in addition to the actual log message.

Simple example

ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [client %a] %M"

Specifying connection or request as first paramter allows to specify additional formats, causing additional information to be logged when the first message is logged for a specific connection or request, respectivly. This additional information is only logged once per connection/request. If a connection or request is processed without causing any log message, the additional information is not logged either.

It can happen that some format string items do not produce output. For example, the Referer header is only present if the log message is associated to a request and the log message happens at a time when the Referer header has already been read from the client. If no output is produced, the default behaviour is to delete everything from the preceeding space character to the next space character. This means the log line is implicitly divided into fields on non-whitespace to whitespace transitions. If a format string item does not produce output, the whole field is ommitted. For example, if the remote address %a in the log format [%t] [%l] [%a] %M  is not available, the surrounding brackets are not logged either. Space characters can be escaped with a backslash to prevent them from delimiting a field. The combination '% ' (percent space) is a zero-witdh field delimiter that does not produce any output.

The above behaviour can be changed by adding modifiers to the format string item. A - (minus) modifier causes a minus to be logged if the respective item does not produce any output. In once-per-connection/request formats, it is also possible to use the + (plus) modifier. If an item with the plus modifier does not produce any output, the whole line is ommitted.

A number as modifier can be used to assign a log severity level to a format item. The item will only be logged if the severity of the log message is not higher than the specified log severity level. The number can range from 1 (alert) over 4 (warn) and 7 (debug) to 15 (trace8).

Some format string items accept additional parameters in braces.

Format String Description
%% The percent sign
%...a Remote IP-address and port
%...A Local IP-address and port
%...{name}e Request environment variable name
%...E APR/OS error status code and string
%...F Source file name and line number of the log call
%...{name}i Request header name
%...k Number of keep-alive requests on this connection
%...l Loglevel of the message
%...L Log ID of the request
%...{c}L Log ID of the connection
%...{C}L Log ID of the connection if used in connection scope, empty otherwise
%...m Name of the module logging the message
%M The actual log message
%...{name}n Request note name
%...P Process ID of current process
%...T Thread ID of current thread
%...t The current time
%...{u}t The current time including micro-seconds
%...{cu}t The current time in compact ISO 8601 format, including micro-seconds
%...v The canonical ServerName of the current server.
%...V The server name of the server serving the request according to the UseCanonicalName setting.
(backslash space) Non-field delimiting space
(percent space) Field delimiter (no output)

The log ID format %L produces a unique id for a connection or request. This can be used to correlate which log lines belong to the same connection or request, which request happens on which connection. A %L format string is also available in mod_log_config, to allow to correlate access log entries with error log lines. If mod_unique_id is loaded, its unique id will be used as log ID for requests.

Example (somewhat similar to default format)

ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"

Example (similar to the 2.2.x format)

ErrorLogFormat "[%t] [%l] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"

Advanced example with request/connection log IDs

ErrorLogFormat "[%{uc}t] [%-m:%-l] [R:%L] [C:%{C}L] %7F: %E: %M"
ErrorLogFormat request "[%{uc}t] [R:%L] Request %k on C:%{c}L pid:%P tid:%T"
ErrorLogFormat request "[%{uc}t] [R:%L] UA:'%+{User-Agent}i'"
ErrorLogFormat request "[%{uc}t] [R:%L] Referer:'%+{Referer}i'"
ErrorLogFormat connection "[%{uc}t] [C:%{c}L] local\ %a remote\ %A"

Consulte también

top

Directiva ExtendedStatus

Descripción:Keep track of extended status information for each request
Sintaxis:ExtendedStatus On|Off
Valor por defecto:ExtendedStatus Off[*]
Contexto:server config
Estado:Core
Módulo:core

This option tracks additional data per worker about the currently executing request, and a utilization summary; you can see these variables during runtime by configuring mod_status. Note that other modules may rely on this scoreboard.

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. Also note that this setting cannot be changed during a graceful restart.

Note that loading mod_status will change the default behavior to ExtendedStatus On, while other third party modules may do the same. Such modules rely on collecting detailed information about the state of all workers. The default is changed by mod_status beginning with version 2.3.6; the previous default was always Off.

top

Directiva FileETag

Descripción:File attributes used to create the ETag HTTP response header for static files
Sintaxis:FileETag component ...
Valor por defecto:FileETag INode MTime Size
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo: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 static file. (The ETag value is used in cache management to save network bandwidth.) 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.

Warning

Do not change the default for directories or locations that have WebDAV enabled and use mod_dav_fs as a storage provider. mod_dav_fs uses INode MTime Size as a fixed format for ETag comparisons on conditional requests. These conditional requests will break if the ETag format is changed via FileETag.

Server Side Includes

An ETag is not generated for responses parsed by mod_include, since the response entity can change without a change of the INode, MTime, or Size of the static file with embedded SSI directives.
top

Directiva <Files>

Descripción:Contains directives that apply to matched filenames
Sintaxis:<Files filename> ... </Files>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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. 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.

Consulte también

top

Directiva <FilesMatch>

Descripción:Contains directives that apply to regular-expression matched filenames
Sintaxis:<FilesMatch regex> ... </FilesMatch>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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.

Consulte también

top

Directiva FlushMaxPipelined

Descripción:Maximum number of pipelined responses above which they are flushed to the network
Sintaxis:FlushMaxPipelined number
Valor por defecto:FlushMaxPipelined 5
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:2.4.47 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva FlushMaxThreshold

Descripción:Threshold above which pending data are flushed to the network
Sintaxis:FlushMaxThreshold number-of-bytes
Valor por defecto:FlushMaxThreshold 65535
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:2.4.47 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva ForceType

Descripción:Forces all matching files to be served with the specified media type in the HTTP Content-Type header field
Sintaxis:ForceType media-type|None
Contexto:directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:Moved to the core in Apache httpd 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 media-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 this directive overrides other indirect media type associations defined in mime.types or via the AddType.

You can also override more general ForceType settings 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>

This directive primarily overrides the content types generated for static files served out of the filesystem. For resources other than static files, where the generator of the response typically specifies a Content-Type, this directive has no effect.

top

Directiva GprofDir

Descripción:Directory to write gmon.out profiling data to.
Sintaxis:GprofDir /tmp/gprof/|/tmp/gprof/%
Contexto:server config, virtual host
Estado:Core
Módulo:core

When the server has been compiled with gprof profiling support, GprofDir causes gmon.out files to be written to the specified directory when the process exits. If the argument ends with a percent symbol ('%'), subdirectories are created for each process id.

This directive currently only works with the prefork MPM.

top

Directiva HostnameLookups

Descripción:Enables DNS lookups on client IP addresses
Sintaxis:HostnameLookups On|Off|Double
Valor por defecto:HostnameLookups Off
Contexto:server config, virtual host, directory
Estado:Core
Módulo: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

Directiva HttpProtocolOptions

Descripción:Modify restrictions on HTTP Request Messages
Sintaxis:HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0]
Valor por defecto:HttpProtocolOptions Strict LenientMethods Allow0.9
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:2.2.32 or 2.4.24 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva <If>

Descripción:Contains directives that apply only if a condition is satisfied by a request at runtime
Sintaxis:<If expression> ... </If>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core

The <If> directive evaluates an expression at runtime, and applies the enclosed directives if and only if the expression evaluates to true. For example:

<If "$req{Host} = ''">

would match HTTP/1.0 requests without a Host: header.

You may compare the value of any variable in the request headers ($req), response headers ($resp) or environment ($env) in your expression.

Apart from =, If can use the IN operator to compare if the expression is in a given range:

<If %{REQUEST_METHOD} IN GET,HEAD,OPTIONS>

Consulte también

top

Directiva <IfDefine>

Descripción:Encloses directives that will be processed only if a test is true at startup
Sintaxis:<IfDefine [!]parameter-name> ... </IfDefine>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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:

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 or by the Define directive.

<IfDefine> sections are nest-able, which can be used to implement simple multiple-parameter tests. Example:

httpd -DReverseProxy -DUseCache -DMemCache ...

# httpd.conf
<IfDefine ReverseProxy>
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<IfDefine UseCache>
LoadModule cache_module modules/mod_cache.so
<IfDefine MemCache>
LoadModule mem_cache_module modules/mod_mem_cache.so
</IfDefine>
<IfDefine !MemCache>
LoadModule cache_disk_module modules/mod_cache_disk.so
</IfDefine>
</IfDefine>
</IfDefine>

top

Directiva <IfDirective>

Descripción:Encloses directives that are processed conditional on the presence or absence of a specific directive
Sintaxis:<IfDirective [!]directive-name> ... </IfDirective>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core
Compatibilidad:Available in 2.4.34 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva <IfFile>

Descripción:Encloses directives that will be processed only if file exists at startup
Sintaxis:<IfFile [!]filename> ... </IfFile>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core
Compatibilidad:Available in 2.4.34 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva <IfModule>

Descripción:Encloses directives that are processed conditional on the presence or absence of a specific module
Sintaxis:<IfModule [!]module-file|module-identifier> ... </IfModule>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core
Compatibilidad: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:

In the former case, the directives between the start and end markers are only processed if the module named module is included in Apache httpd -- 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

Directiva <IfSection>

Descripción:Encloses directives that are processed conditional on the presence or absence of a specific section directive
Sintaxis:<IfSection [!]section-name> ... </IfSection>
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core
Compatibilidad:Available in 2.4.34 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva Include

Descripción:Includes other configuration files from within the server configuration files
Sintaxis:Include [optional|strict] file-path|directory-path|wildcard
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core
Compatibilidad:Wildcard matching available in 2.0.41 and later, directory wildcard matching available in 2.3.6 and later

This directive allows inclusion of other configuration files from within the server configuration files.

Shell-style (fnmatch()) wildcard characters can be used in the filename or directory parts of the path to include several files at once, in alphabetical order. In addition, if Include points to a directory, rather than a file, Apache httpd will read all files in that directory and any subdirectory. However, including entire directories is not recommended, because it is easy to accidentally leave temporary files in a directory that can cause httpd to fail. Instead, we encourage you to use the wildcard syntax shown below, to include files that match a particular pattern, such as *.conf, for example.

When a wildcard is specified for a file component of the path, and no file matches the wildcard, the Include directive will be silently ignored. When a wildcard is specified for a directory component of the path, and no directory matches the wildcard, the Include directive will fail with an error saying the directory cannot be found.

For further control over the behaviour of the server when no files or directories match, prefix the path with the modifiers optional or strict. If optional is specified, any wildcard file or directory that does not match will be silently ignored. If strict is specified, any wildcard file or directory that does not match at least one file will cause server startup to fail.

When a directory or file component of the path is specified exactly, and that directory or file does not exist, Include directive will fail with an error saying the file or directory cannot be found.

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

Wildcards may be included in the directory or file portion of the path. In the following example, the server will fail to load if no directories match conf/vhosts/*, but will load successfully if no files match *.conf.

Include conf/vhosts/*/vhost.conf
Include conf/vhosts/*/*.conf

In this example, the server will fail to load if either conf/vhosts/* matches no directories, or if *.conf matches no files:

Include strict conf/vhosts/*/*.conf

In this example, the server load successfully if either conf/vhosts/* matches no directories, or if *.conf matches no files:

Include optional conf/vhosts/*/*.conf

Consulte también

top

Directiva IncludeOptional

Descripción:Includes other configuration files from within the server configuration files
Sintaxis:IncludeOptional file-path|directory-path|wildcard
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core
Compatibilidad:Available in 2.3.6 and later. Not existent file paths without wildcards do not cause SyntaxError after 2.4.30

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva KeepAlive

Descripción:Enables HTTP persistent connections
Sintaxis:KeepAlive On|Off
Valor por defecto:KeepAlive On
Contexto:server config, virtual host
Estado:Core
Módulo: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.

When a client uses a Keep-Alive connection it will be counted as a single "request" for the MaxConnectionsPerChild directive, regardless of how many requests are sent using the connection.

Consulte también

top

Directiva KeepAliveTimeout

Descripción:Amount of time the server will wait for subsequent requests on a persistent connection
Sintaxis:KeepAliveTimeout num[ms]
Valor por defecto:KeepAliveTimeout 5
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Specifying a value in milliseconds is available in Apache httpd 2.3.2 and later

The number of seconds Apache httpd will wait for a subsequent request before closing the connection. By adding a postfix of ms the timeout can be also set in milliseconds. 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.

In a name-based virtual host context, the value of the first defined virtual host (the default host) in a set of NameVirtualHost will be used. The other values will be ignored.

top

Directiva <Limit>

Descripción:Restrict enclosed access controls to only certain HTTP methods
Sintaxis:<Limit method [method] ... > ... </Limit>
Contexto:directory, .htaccess
Anula:AuthConfig, Limit
Estado:Core
Módulo: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 (see TraceEnable).

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.

The <Limit> and <LimitExcept> directives may be nested. In this case, each successive level of <Limit> or <LimitExcept> directives must further restrict the set of methods to which access controls apply.

When using <Limit> or <LimitExcept> directives with the Require directive, note that the first Require to succeed authorizes the request, regardless of the presence of other Require directives.

For example, given the following configuration, all users will be authorized for POST requests, and the Require group editors directive will be ignored in all cases:

<LimitExcept GET> Require valid-user </LimitExcept>
<Limit POST> Require group editors </Limit>

top

Directiva <LimitExcept>

Descripción:Restrict access controls to all HTTP methods except the named ones
Sintaxis:<LimitExcept method [method] ... > ... </LimitExcept>
Contexto:directory, .htaccess
Anula:AuthConfig, Limit
Estado:Core
Módulo: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

Directiva LimitInternalRecursion

Descripción:Determine maximum number of internal redirects and nested subrequests
Sintaxis:LimitInternalRecursion number [number]
Valor por defecto:LimitInternalRecursion 10
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Available in Apache httpd 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 httpd'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

Directiva LimitRequestBody

Descripción:Restricts the total size of the HTTP request body sent from the client
Sintaxis:LimitRequestBody bytes
Valor por defecto:LimitRequestBody 0
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo:core

This directive specifies the number of bytes from 0 (meaning unlimited) to 2147483647 (2GB) that are allowed in a request body. See the note below for the limited applicability to proxy requests.

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

For a full description of how this directive is interpreted by proxy requests, see the mod_proxy documentation.

top

Directiva LimitRequestFields

Descripción:Limits the number of HTTP request header fields that will be accepted from the client
Sintaxis:LimitRequestFields number
Valor por defecto:LimitRequestFields 100
Contexto:server config, virtual host
Estado:Core
Módulo: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

Warning

When name-based virtual hosting is used, the value for this directive is taken from the default (first-listed) virtual host for the NameVirtualHost the connection was mapped to.

top

Directiva LimitRequestFieldSize

Descripción:Limits the size of the HTTP request header allowed from the client
Sintaxis:LimitRequestFieldSize bytes
Valor por defecto:LimitRequestFieldSize 8190
Contexto:server config, virtual host
Estado:Core
Módulo: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.

Warning

When name-based virtual hosting is used, the value for this directive is taken from the default (first-listed) virtual host for the NameVirtualHost the connection was mapped to.

top

Directiva LimitRequestLine

Descripción:Limit the size of the HTTP request line that will be accepted from the client
Sintaxis:LimitRequestLine bytes
Valor por defecto:LimitRequestLine 8190
Contexto:server config, virtual host
Estado:Core
Módulo: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.

Warning

When name-based virtual hosting is used, the value for this directive is taken from the default (first-listed) virtual host for the NameVirtualHost the connection was mapped to.

top

Directiva LimitXMLRequestBody

Descripción:Limits the size of an XML-based request body
Sintaxis:LimitXMLRequestBody bytes
Valor por defecto:LimitXMLRequestBody 1000000
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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

Directiva <Location>

Descripción:Applies the enclosed directives only to matching URLs
Sintaxis:<Location URL-path|URL> ... </Location>
Contexto:server config, virtual host
Estado:Core
Módulo: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.

The enclosed directives will be applied to the request if the path component of the URL meets any of the following criteria:

In the example below, where no trailing slash is used, requests to /private1, /private1/ and /private1/file.txt will have the enclosed directives applied, but /private1other would not.

<Location /private1> ...

In the example below, where a trailing slash is used, requests to /private2/ and /private2/file.txt will have the enclosed directives applied, but /private2 and /private2other would not.

<Location /private2/> ...

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. Neither wildcard character matches a / in the URL-path.

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>, and is preferred, for the simple reason that ~ is hard to distinguish from - in many fonts.

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 example.com, you might use:

<Location /status>
SetHandler server-status
Require host example.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.

Consulte también

top

Directiva <LocationMatch>

Descripción:Applies the enclosed directives only to regular-expression matching URLs
Sintaxis:<LocationMatch regex> ... </LocationMatch>
Contexto:server config, virtual host
Estado:Core
Módulo: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.

Consulte también

top

Directiva LogLevel

Descripción:Controls the verbosity of the ErrorLog
Sintaxis:LogLevel [module:]level [module:level] ...
Valor por defecto:LogLevel warn
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core
Compatibilidad:Per-module and per-directory configuration is available in Apache HTTP Server 2.3.6 and later

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 ..."
trace1 Trace messages "proxy: FTP: control connection complete"
trace2 Trace messages "proxy: CONNECT: sending the CONNECT request to the remote proxy"
trace3 Trace messages "openssl: Handshake: start"
trace4 Trace messages "read from buffered SSL brigade, mode 0, 17 bytes"
trace5 Trace messages "map lookup FAILED: map=rewritemap key=keyname"
trace6 Trace messages "cache lookup FAILED, forcing new map lookup"
trace7 Trace messages, dumping large amounts of data "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"
trace8 Trace messages, dumping large amounts of data "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"

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.

Specifying a level without a module name will reset the level for all modules to that level. Specifying a level with a module name will set the level for that module only. It is possible to use the module source file name, the module identifier, or the module identifier with the trailing _module omitted as module specification. This means the following three specifications are equivalent:

LogLevel info ssl:warn
LogLevel info mod_ssl.c:warn
LogLevel info ssl_module:warn

It is also possible to change the level per directory:

LogLevel info
<Directory /usr/local/apache/htdocs/app>
  LogLevel debug
</Files>

Per directory loglevel configuration only affects messages that are logged after the request has been parsed and that are associated with the request. Log messages which are associated with the connection or the server are not affected.
top

Directiva MaxKeepAliveRequests

Descripción:Number of requests allowed on a persistent connection
Sintaxis:MaxKeepAliveRequests number
Valor por defecto:MaxKeepAliveRequests 100
Contexto:server config, virtual host
Estado:Core
Módulo: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

Directiva MaxRangeOverlaps

Descripción:Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
Sintaxis:MaxRangeOverlaps default | unlimited | none | number-of-ranges
Valor por defecto:MaxRangeOverlaps 20
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 2.3.15 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva MaxRangeReversals

Descripción:Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
Sintaxis:MaxRangeReversals default | unlimited | none | number-of-ranges
Valor por defecto:MaxRangeReversals 20
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 2.3.15 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva MaxRanges

Descripción:Number of ranges allowed before returning the complete resource
Sintaxis:MaxRanges default | unlimited | none | number-of-ranges
Valor por defecto:MaxRanges 200
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 2.3.15 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva MergeSlashes

Descripción:Controls whether the server merges consecutive slashes in URLs.
Sintaxis:MergeSlashes ON|OFF
Valor por defecto:MergeSlashes ON
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Added in 2.4.39

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva MergeTrailers

Descripción:Determines whether trailers are merged into headers
Sintaxis:MergeTrailers [on|off]
Valor por defecto:MergeTrailers off
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:2.4.11 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva Mutex

Descripción:Configures mutex mechanism and lock file directory for all or specified mutexes
Sintaxis:Mutex mechanism [default|mutex-name] ... [OmitPID]
Valor por defecto:Mutex default
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 2.3.4 and later

The Mutex directive sets the mechanism, and optionally the lock file location, that httpd and modules use to serialize access to resources. Specify default as the first argument to change the settings for all mutexes; specify a mutex name (see table below) as the first argument to override defaults only for that mutex.

The Mutex directive is typically used in the following exceptional situations:

Supported modules

This directive only configures mutexes which have been registered with the core server using the ap_mutex_register() API. All modules bundled with httpd support the Mutex directive, but third-party modules may not. Consult the documentation of the third-party module, which must indicate the mutex name(s) which can be configured if this directive is supported.

The following mutex mechanisms are available:

Most mechanisms are only available on selected platforms, where the underlying platform and APR support it. Mechanisms which aren't available on all platforms are posixsem, sysvsem, sem, pthread, fcntl, flock, and file.

With the file-based mechanisms fcntl and flock, the path, if provided, is a directory where the lock file will be created. The default directory is httpd's run-time file directory relative to ServerRoot. Always use a local disk filesystem for /path/to/mutex and never a directory residing on a NFS- or AFS-filesystem. The basename of the file will be the mutex type, an optional instance string provided by the module, and unless the OmitPID keyword is specified, the process id of the httpd parent process will be appended to to make the file name unique, avoiding conflicts when multiple httpd instances share a lock file directory. For example, if the mutex name is mpm-accept and the lock file directory is /var/httpd/locks, the lock file name for the httpd instance with parent process id 12345 would be /var/httpd/locks/mpm-accept.12345.

Security

It is best to avoid putting mutex files 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.

The following table documents the names of mutexes used by httpd and bundled modules.

Mutex name Module(s) Protected resource
mpm-accept prefork and worker MPMs incoming connections, to avoid the thundering herd problem; for more information, refer to the performance tuning documentation
authdigest-client mod_auth_digest client list in shared memory
authdigest-opaque mod_auth_digest counter in shared memory
ldap-cache mod_ldap LDAP result cache
rewrite-map mod_rewrite communication with external mapping programs, to avoid intermixed I/O from multiple requests
ssl-cache mod_ssl SSL session cache
ssl-stapling mod_ssl OCSP stapling response cache
watchdog-callback mod_watchdog callback function of a particular client module

The OmitPID keyword suppresses the addition of the httpd parent process id from the lock file name.

In the following example, the mutex mechanism for the MPM accept mutex will be changed from the compiled-in default to fcntl, with the associated lock file created in directory /var/httpd/locks. The mutex mechanism for all other mutexes will be changed from the compiled-in default to sysvsem.

Mutex default sysvsem
Mutex mpm-accept fcntl:/var/httpd/locks

top

Directiva NameVirtualHost

Descripción:Designates an IP address for name-virtual hosting
Sintaxis:NameVirtualHost addr[:port]
Contexto:server config
Estado:Core
Módulo:core

A single NameVirtualHost directive identifies a set of identical virtual hosts on which the server will further select from on the basis of the hostname requested by the client. The NameVirtualHost directive is a required directive if you want to configure name-based virtual hosts.

This directive, and the corresponding VirtualHost, must be qualified with a port number if the server supports both HTTP and HTTPS connections.

Although addr can be a hostname, it is recommended that you always use an IP address or a wildcard. A wildcard NameVirtualHost matches only virtualhosts that also have a literal wildcard as their argument.

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.

In the example below, requests received on interface 192.0.2.1 and port 80 will only select among the first two virtual hosts. Requests received on port 80 on any other interface will only select among the third and fourth virtual hosts. In the common case where the interface isn't important to the mapping, only the "*:80" NameVirtualHost and VirtualHost directives are necessary.

NameVirtualHost 192.0.2.1:80
NameVirtualHost *:80

<VirtualHost 192.0.2.1:80>
  ServerName namebased-a.example.com
</VirtualHost>

<VirtualHost 192.0.2.1:80>
  Servername namebased-b.example.com
</VirtualHost>

<VirtualHost *:80>
  ServerName namebased-c.example.com
</VirtualHost>

<VirtualHost *:80>
  ServerName namebased-d.example.com
</VirtualHost>

If no matching virtual host is found, then the first listed virtual host that matches the IP address and port will be used.

IPv6 addresses must be enclosed in square brackets, as shown in the following example:

NameVirtualHost [2001:db8::a00:20ff:fea7:ccea]:8080

Argument to <VirtualHost> directive

Note that the argument to the <VirtualHost> directive must exactly match the argument to the NameVirtualHost directive.

NameVirtualHost 192.0.2.2:80
<VirtualHost 192.0.2.2:80>
# ...
</VirtualHost>

Consulte también

top

Directiva Options

Descripción:Configures what features are available in a particular directory
Sintaxis:Options [+|-]option [[+|-]option] ...
Valor por defecto:Options All
Contexto:server config, virtual host, directory, .htaccess
Anula:Options
Estado:Core
Módulo: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.

Omitting this option should not be considered a security restriction, since symlink testing is subject to race conditions that make it circumventable.

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.

Note

This option gets ignored if set anywhere other than <Directory>, as mod_negotiation needs real resources to compare against and evaluate from.

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.

This option should not be considered a security restriction, since symlink testing is subject to race conditions that make it circumventable.

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.

Warning

Mixing Options with a + or - with those without is not valid syntax, and is likely to cause unexpected results.

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

Directiva Protocol

Descripción:Protocol for a listening socket
Sintaxis:Protocol protocol
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Available in Apache 2.1.5 and later. On Windows from Apache 2.3.3 and later.

This directive specifies the protocol used for a specific listening socket. The protocol is used to determine which module should handle a request, and to apply protocol specific optimizations with the AcceptFilter directive.

You only need to set the protocol if you are running on non-standard ports, otherwise http is assumed for port 80 and https for port 443.

For example, if you are running https on a non-standard port, specify the protocol explicitly:

Protocol https

You can also specify the protocol using the Listen directive.

Consulte también

top

Directiva Protocols

Descripción:Protocols available for a server/virtual host
Sintaxis:Protocols protocol ...
Valor por defecto:Protocols http/1.1
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Only available from Apache 2.4.17 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva ProtocolsHonorOrder

Descripción:Determines if order of Protocols determines precedence during negotiation
Sintaxis:ProtocolsHonorOrder On|Off
Valor por defecto:ProtocolsHonorOrder On
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Only available from Apache 2.4.17 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva QualifyRedirectURL

Descripción:Controls whether the REDIRECT_URL environment variable is fully qualified
Sintaxis:QualifyRedirectURL On|Off
Valor por defecto:QualifyRedirectURL Off
Contexto:server config, virtual host, directory
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:Directive supported in 2.4.18 and later. 2.4.17 acted as if 'QualifyRedirectURL On' was configured.

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva ReadBufferSize

Descripción:Size of the buffers used to read data
Sintaxis:ReadBufferSize bytes
Valor por defecto:ReadBufferSize 8192
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core
Compatibilidad:2.4.27 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva RegexDefaultOptions

Descripción:Allow to configure global/default options for regexes
Sintaxis:RegexDefaultOptions [none] [+|-]option [[+|-]option] ...
Valor por defecto:RegexDefaultOptions DOTALL DOLLAR_ENDONLY
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Only available from Apache 2.4.30 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva RegisterHttpMethod

Descripción:Register non-standard HTTP methods
Sintaxis:RegisterHttpMethod method [method [...]]
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 2.4.24 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

Consulte también

top

Directiva RLimitCPU

Descripción:Limits the CPU consumption of processes launched by Apache httpd children
Sintaxis:RLimitCPU seconds|max [seconds|max]
Valor por defecto:Unset; uses operating system defaults
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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 httpd children servicing requests, not the Apache httpd children themselves. This includes CGI scripts and SSI exec commands, but not any processes forked off from the Apache httpd parent such as piped logs.

CPU resource limits are expressed in seconds per process.

Consulte también

top

Directiva RLimitMEM

Descripción:Limits the memory consumption of processes launched by Apache httpd children
Sintaxis:RLimitMEM bytes|max [bytes|max]
Valor por defecto:Unset; uses operating system defaults
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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 httpd children servicing requests, not the Apache httpd children themselves. This includes CGI scripts and SSI exec commands, but not any processes forked off from the Apache httpd parent such as piped logs.

Memory resource limits are expressed in bytes per process.

Consulte también

top

Directiva RLimitNPROC

Descripción:Limits the number of processes that can be launched by processes launched by Apache httpd children
Sintaxis:RLimitNPROC number|max [number|max]
Valor por defecto:Unset; uses operating system defaults
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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 httpd children servicing requests, not the Apache httpd children themselves. This includes CGI scripts and SSI exec commands, but not any processes forked off from the Apache httpd 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.

Consulte también

top

Directiva ScriptInterpreterSource

Descripción:Technique for locating the interpreter for CGI scripts
Sintaxis:ScriptInterpreterSource Registry|Registry-Strict|Script
Valor por defecto:ScriptInterpreterSource Script
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:Win32 only; option Registry-Strict is available in Apache HTTP Server 2.0 and later

This directive is used to control how Apache httpd finds the interpreter used to run CGI scripts. The default setting is Script. This causes Apache httpd 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 httpd falls back to the behavior of the Script option.

Security

Be careful when using ScriptInterpreterSource Registry with ScriptAlias'ed directories, because Apache httpd 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 HTTP Server 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

Directiva SeeRequestTail

Descripción:Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
Sintaxis:SeeRequestTail On|Off
Valor por defecto:SeeRequestTail Off
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Available in Apache httpd 2.2.7 and later.

mod_status with ExtendedStatus On displays the actual request being handled. For historical purposes, only 63 characters of the request are actually stored for display purposes. This directive controls whether the 1st 63 characters are stored (the previous behavior and the default) or if the last 63 characters are. This is only applicable, of course, if the length of the request is 64 characters or greater.

If Apache httpd is handling GET /disk1/storage/apache/htdocs/images/imagestore1/food/apples.jpg HTTP/1.1 mod_status displays as follows:

Off (default) GET /disk1/storage/apache/htdocs/images/imagestore1/food/apples
On orage/apache/htdocs/images/imagestore1/food/apples.jpg HTTP/1.1
top

Directiva ServerAdmin

Descripción:Email address that the server includes in error messages sent to the client
Sintaxis:ServerAdmin email-address|URL
Contexto:server config, virtual host
Estado:Core
Módulo: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

Directiva ServerAlias

Descripción:Alternate names for a host used when matching requests to name-virtual hosts
Sintaxis:ServerAlias hostname [hostname] ...
Contexto:virtual host
Estado:Core
Módulo:core

The ServerAlias directive sets the alternate names for a host, for use with name-based virtual hosts. The ServerAlias may include wildcards, if appropriate.

<VirtualHost *:80>
ServerName server.domain.com
ServerAlias server server2.domain.com server2
ServerAlias *.example.com
UseCanonicalName Off
# ...
</VirtualHost>

Consulte también

top

Directiva ServerName

Descripción:Hostname and port that the server uses to identify itself
Sintaxis:ServerName [scheme://]fully-qualified-domain-name[:port]
Contexto:server config, virtual host
Estado:Core
Módulo:core

The ServerName directive sets the request scheme, hostname and port that the server uses to identify itself. This is used when creating redirection URLs.

Additionally, ServerName is used (possibly in conjunction with ServerAlias) to uniquely identify a virtual host, when using name-based virtual hosts.

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

The ServerName directive may appear anywhere within the definition of a server. However, each appearance overrides the previous appearance (within that server).

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.

Sometimes, the server runs behind a device that processes SSL, such as a reverse proxy, load balancer or SSL offload appliance. When this is the case, specify the https:// scheme and the port number to which the clients connect in the ServerName directive to make sure that the server generates the correct self-referential URLs.

See the description of the UseCanonicalName and UseCanonicalPhysicalPort directives for settings which determine whether self-referential URLs (e.g., by the mod_dir module) will refer to the specified port, or to the port number given in the client's request.

Failure to set ServerName to a name that your server can resolve to an IP address will result in a startup warning. httpd will then use whatever hostname it can determine, using the system's hostname command. This will almost never be the hostname you actually want.

httpd: Could not reliably determine the server's fully qualified domain name, using rocinante.local for ServerName

Consulte también

top

Directiva ServerPath

Descripción:Legacy URL pathname for a name-based virtual host that is accessed by an incompatible browser
Sintaxis:ServerPath URL-path
Contexto:virtual host
Estado:Core
Módulo:core

The ServerPath directive sets the legacy URL pathname for a host, for use with name-based virtual hosts.

Consulte también

top

Directiva ServerRoot

Descripción:Base directory for the server installation
Sintaxis:ServerRoot directory-path
Valor por defecto:ServerRoot /usr/local/apache
Contexto:server config
Estado:Core
Módulo: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

Consulte también

top

Directiva ServerSignature

Descripción:Configures the footer on server-generated documents
Sintaxis:ServerSignature On|Off|EMail
Valor por defecto:ServerSignature Off
Contexto:server config, virtual host, directory, .htaccess
Anula:All
Estado:Core
Módulo: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.

Consulte también

top

Directiva ServerTokens

Descripción:Configures the Server HTTP response header
Sintaxis:ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
Valor por defecto:ServerTokens Full
Contexto:server config
Estado:Core
Módulo: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 Full (or not specified)
Server sends (e.g.): Server: Apache/2.4.1 (Unix) PHP/4.2.2 MyMod/1.2
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.4
ServerTokens Min[imal]
Server sends (e.g.): Server: Apache/2.4.1
ServerTokens OS
Server sends (e.g.): Server: Apache/2.4.1 (Unix)

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.

Setting ServerTokens to less than minimal is not recommended because it makes it more difficult to debug interoperational problems. Also note that disabling the Server: header does nothing at all to make your server more secure; the idea of "security through obscurity" is a myth and leads to a false sense of safety.

Consulte también

top

Directiva SetHandler

Descripción:Forces all matching files to be processed by a handler
Sintaxis:SetHandler handler-name|None
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo:core
Compatibilidad:Moved into the core in Apache httpd 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.

Note: because SetHandler overrides default handlers, normal behaviour such as handling of URLs ending in a slash (/) as directories or index files is suppressed.

Consulte también

top

Directiva SetInputFilter

Descripción:Sets the filters that will process client requests and POST input
Sintaxis:SetInputFilter filter[;filter...]
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo: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.

Consulte también

top

Directiva SetOutputFilter

Descripción:Sets the filters that will process responses from the server
Sintaxis:SetOutputFilter filter[;filter...]
Contexto:server config, virtual host, directory, .htaccess
Anula:FileInfo
Estado:Core
Módulo: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.

Consulte también

top

Directiva StrictHostCheck

Descripción:Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Sintaxis:StrictHostCheck ON|OFF
Valor por defecto:StrictHostCheck OFF
Contexto:server config, virtual host
Estado:Core
Módulo:core
Compatibilidad:Added in 2.4.49

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva TimeOut

Descripción:Amount of time the server will wait for certain events before failing a request
Sintaxis:TimeOut seconds
Valor por defecto:TimeOut 60
Contexto:server config, virtual host
Estado:Core
Módulo:core

The TimeOut directive defines the length of time Apache httpd will wait for I/O in various circumstances:

  1. When reading data from the client, the length of time to wait for a TCP packet to arrive if the read buffer is empty.
  2. When writing data to the client, the length of time to wait for an acknowledgement of a packet if the send buffer is full.
  3. In mod_cgi, the length of time to wait for output from a CGI script.
  4. In mod_ext_filter, the length of time to wait for output from a filtering process.
  5. In mod_proxy, the default timeout value if ProxyTimeout is not configured.
top

Directiva TraceEnable

Descripción:Determines the behaviour on TRACE requests
Sintaxis:TraceEnable [on|off|extended]
Valor por defecto:TraceEnable on
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Available in Apache HTTP Server 1.3.34, 2.0.55 and later

This directive overrides the behavior of TRACE for both the core server and mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616, which disallows any request body to accompany the request. TraceEnable off causes the core server and mod_proxy to return a 405 (Method not allowed) error to the client.

Finally, for testing and diagnostic purposes only, request bodies may be allowed using the non-compliant TraceEnable extended directive. The core (as an origin server) will restrict the request body to 64k (plus 8k for chunk headers if Transfer-Encoding: chunked is used). The core will reflect the full headers and all chunk headers with the response body. As a proxy server, the request body is not restricted to 64k.

top

Directiva UNCList

Descripción:Controls what UNC host names can be accessed by the server
Sintaxis:UNCList hostname [hostname...]
Valor por defecto:unset
Contexto:server config
Estado:Core
Módulo:core
Compatibilidad:Added in 2.4.60, Windows only.

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

Directiva UnDefine

Descripción:Undefine the existence of a variable
Sintaxis:UnDefine parameter-name
Contexto:server config
Estado:Core
Módulo:core

Undoes the effect of a Define or of passing a -D argument to httpd.

This directive can be used to toggle the use of <IfDefine> sections without needing to alter -D arguments in any startup scripts.

top

Directiva UseCanonicalName

Descripción:Configures how the server determines its own name and port
Sintaxis:UseCanonicalName On|Off|DNS
Valor por defecto:UseCanonicalName Off
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core

In many situations Apache httpd must construct a self-referential URL -- that is, a URL that refers back to the same server. With UseCanonicalName On Apache httpd 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 httpd 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 httpd 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 httpd 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 httpd 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.

Consulte también

top

Directiva UseCanonicalPhysicalPort

Descripción:Configures how the server determines its own name and port
Sintaxis:UseCanonicalPhysicalPort On|Off
Valor por defecto:UseCanonicalPhysicalPort Off
Contexto:server config, virtual host, directory
Estado:Core
Módulo:core

In many situations Apache httpd must construct a self-referential URL -- that is, a URL that refers back to the same server. With UseCanonicalPhysicalPort On Apache httpd will, when constructing the canonical port for the server to honor the UseCanonicalName directive, provide the actual physical port number being used by this request as a potential port. With UseCanonicalPhysicalPort Off Apache httpd will not ever use the actual physical port number, instead relying on all configured information to construct a valid port number.

Note

The ordering of when the physical port is used is as follows:

UseCanonicalName On

  • Port provided in Servername
  • Physical port
  • Default port
UseCanonicalName Off | DNS
  • Parsed port from Host: header
  • Physical port
  • Port provided in Servername
  • Default port

With UseCanonicalPhysicalPort Off, the physical ports are removed from the ordering.

Consulte también

top

Directiva <VirtualHost>

Descripción:Contains directives that apply only to a specific hostname or IP address
Sintaxis:<VirtualHost addr[:port] [addr[:port]] ...> ... </VirtualHost>
Contexto:server config
Estado:Core
Módulo: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:

Example

<VirtualHost 10.1.2.3>
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>

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 [2001:db8::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 httpd listens on. You may need to ensure that Apache httpd 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.

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

A ServerName should be specified inside each <VirtualHost> block. If it is absent, the ServerName from the "main" server configuration will be inherited.

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.

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.

Consulte también

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  tr 

top

Comentarios

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_debug.html.fr.utf80000664000175100017510000002541214740503670022567 0ustar covenercovener mod_log_debug - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_log_debug

Langues Disponibles:  en  |  fr 

Description:Journalisation supplémentaire à des fins de débogage
Statut:Expérimental
Identificateur de Module:log_debug_module
Fichier Source:mod_log_debug.c
Compatibilité:Disponible depuis la version 2.3.14 d'Apache
Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples

  1. Enregistre un message après le traitement d'une requête pour /foo/* :
    <Location "/foo/">
      LogMessage "/foo/ has been requested"
    </Location>
  2. Enregistre un message si une requête pour /foo/* est traitée dans une sous-requête :
    <Location "/foo/">
      LogMessage "subrequest to /foo/" hook=type_checker "expr=-T %{IS_SUBREQ}"
    </Location>
    Le branchement (hook) par défaut log_transaction n'est pas exécuté pour les sous-requêtes ; nous devons donc en utiliser un autre.
  3. Enregistre un message si un client IPv6 est à l'origine d'un dépassement de délai pour une requête :
    LogMessage "IPv6 timeout from %{REMOTE_ADDR}" "expr=-T %{IPV6} && %{REQUEST_STATUS} = 408"
    Notez l'emplacement des guillemets pour l'argument expr=.
  4. Enregistre la valeur de la variable d'environnement de requête "X-Foo" à chaque étape du traitement :
    <Location "/">
      LogMessage "%{reqenv:X-Foo}" hook=all
    </Location>
    En association avec les repères de temps en microsecondes du journal des erreurs, hook=all permet aussi de déterminer la durée d'exécution des différentes phases du traitement de la requête.
top

Directive LogMessage

Description:Enregistre des messages personnalisés dans le journal des erreurs
Syntaxe:LogMessage message [hook=hook] [expr=expression]
Défaut:Non défini
Contexte:répertoire
Statut:Expérimental
Module:mod_log_debug

Cette directive permet d'enregistrer un message personnalisé dans le journal des erreurs. Ce message peut utiliser des variables et des fonctions dans la syntaxe ap_expr. D'éventuelles références à des en-têtes HTTP dans l'expression rationnelle n'entraîneront pas l'ajout des noms d'en-tête correspondants à l'en-tête Vary. Les messages sont enregistrés au loglevel info.

Le branchement (hook) précise la phase du traitement de la requête avant laquelle le message sera enregistré. Les branchements suivants sont supportés :

Nom
pre_translate_name
translate_name
type_checker
quick_handler
map_to_storage
check_access
check_access_ex
insert_filter
check_authn
check_authz
fixups
handler
log_transaction

Le branchement par défaut est log_transaction. La valeur spéciale all est également supportée ; dans ce cas, le message sera enregistré à chaque phase. Tous les branchements ne sont pas exécutés pour chaque requête.

L'expression optionnelle permet de restreindre l'enregistrement du message en fonction d'une certaine condition. La syntaxe de l'expression est décrite dans la documentation ap_expr. D'éventuelles références à des en-têtes HTTP dans l'expression rationnelle n'entraîneront pas l'ajout des noms d'en-tête correspondants à l'en-tête Vary.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_imagemap.html.fr.utf80000664000175100017510000005663514740503670022433 0ustar covenercovener mod_imagemap - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_imagemap

Langues Disponibles:  en  |  fr  |  ko 

Description:Traitement des cartes des zones interactives d'une image (imagemaps) au niveau du serveur
Statut:Base
Identificateur de Module:imagemap_module
Fichier Source:mod_imagemap.c

Sommaire

Ce module traite les fichiers .map, et remplace ainsi la fonctionnalité du programme CGI imagemap. Tout répertoire ou type de document configuré pour utiliser le gestionnaire imap-file (à l'aide des directives AddHandler ou SetHandler), sera traité par ce module.

La directive suivante confère aux fichiers possèdant l'extension .map le statut de fichiers imagemap :

AddHandler imap-file map

Notez que la syntaxe suivante reste encore supportée :

AddType application/x-httpd-imap map

Cependant, nous essayons d'abandonner progressivement les "types MIME magiques", et cette syntaxe est sur le point de devenir obsolète.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Nouvelles fonctionnalités

Le module imagemap propose quelques nouvelles fonctionnalités qui n'étaient pas disponibles avec les programmes imagemap précédemment distribués.

top

Fichier imagemap

Les lignes d'un fichier imagemap peuvent se présenter sous plusieurs formats :

directive valeur [x,y ...]
directive valeur "Texte de menu" [x,y ...]
directive valeur x,y ... "Texte de menu"

Les directives sont base, default, poly, circle, rect, ou point. valeur est une URL absolue ou relative, ou une des valeurs spéciales énumérées ci-dessous. Les coordonnées sont des paires x,y séparées par des espaces. Le texte entre guillemets est le texte du lien si un menu imagemap est généré. Les lignes commençant par '#' sont des commentaires.

Directives d'un fichier imagemap

Les directives autorisées dans un fichier imagemap sont au nombre de six. Elles peuvent se trouver à n'importe quelle position dans le fichier, mais sont traitées dans l'ordre selon lequel elles sont enregistrées dans le fichier imagemap.

Directive base

Elle a le même effet que <base href="valeur">. Les URLs non absolues du fichier imagemap sont considérées comme relatives à cette valeur. La directive base l'emporte sur une directive ImapBase définie dans un fichier .htaccess ou dans le fichier de configuration du serveur. En l'absence de directive de configuration ImapBase, la valeur par défaut de base est http://nom_serveur/.

base_uri est un synonyme de base. Notez que la présence ou l'absence d'un slash de fin dans l'URL est importante.

Directive default
La décision à prendre si les coordonnées fournies ne correspondent à aucune des directives poly, circle, ou rect, et si aucune directive point n'est présente. En l'absence de définition d'une directive de configuration ImapDefault, la valeur par défaut est nocontent et provoque l'envoi d'un code de statut 204 No Content. Le client verra toujours la même page s'afficher.
Directive poly
Accepte comme arguments trois à cent points, et est actionnée si les coordonnées sélectionnées par l'utilisateur tombent dans le polygone défini par ces points.
Directive circle
Accepte comme arguments les coordonnées du centre d'un cercle et celles d'un point de ce cercle. Elle est actionnée si les coordonnées sélectionnées par l'utilisateur tombent dans ce cercle.
Directive rect
Accepte comme arguments les coordonnées des sommets de deux angles opposés d'un rectangle. Elle est actionnée si les coordonnées sélectionnées par l'utilisateur tombent dans ce rectangle.
Directive point
Elle n'accepte qu'un seul point comme argument. Si aucune autre directive ne correspond, c'est la directive dont le point spécifié est le plus près du point sélectionné par l'utilisateur qui est actionnée. Notez que la directive default ne sera pas suivie si une directive point est présente et si des coordonnées valides sont fournies.

Valeurs

Les valeurs passées aux directives peuvent contenir :

une URL

L'URL peut être absolue ou relative. Les URLs relatives peuvent contenir '..' et seront considérées comme relatives à la valeur de base.

base en lui-même, ne sera pas résolu en fonction de la valeur courante. Cependant, une directive base mailto: fonctionnera correctement.

map
Équivalent à l'URL du fichier imagemap lui-même. Aucune coordonnée n'est spécifiée, et un menu sera donc généré, à moins qu'une directive ImapMenu n'ait été définie à none.
menu
Équivalent à map.
referer
Équivalent à l'URL du document référant. La valeur par défaut est http://nom_serveur/ si aucun en-tête Referer: n'est présent.
nocontent
Envoie un code de statut 204 No Content, indiquant au client qu'il doit continuer à afficher la même page. Valide pour toutes les directives, sauf base.
error
Envoie un code de statut d'échec 500 Server Error. Valide pour toutes les directives, sauf base, mais n'a de sens qu'avec la directive default.

Coordonnées

0,0 200,200
Une coordonnée se compose de deux valeurs, x et y, séparées par une virgule. Les coordonnées sont séparées entre elles par des espaces. Pour s'adapter à la manière dont Lynx traite les images interactives, la sélection par un utilisateur de la coordonnée 0,0 a le même effet que si aucune coordonnée n'a été sélectionnée.

Texte entre guillemets

"Texte du menu"

Après la valeur ou les coordonnées, la ligne peut éventuellement contenir un texte entre guillemets. Cette chaîne constitue le texte du lien si un menu est généré :

<a href="http://example.com/">Texte de menu</a>

Si aucun texte entre guillemets n'est présent, le texte sera constitué du nom du lien :

<a href="http://example.com/">http://example.com</a>

Si vous voulez insérer des guillemets dans le texte, vous devez les inscrire sous la forme &quot;.

top

Exemple de fichier imagemap

#Les commentaires sont affichés dans un menu 'formaté' ou #'semi-formaté'.
#Et peuvent contenir des balises html. <hr>
base referer
poly map "Puis-je avoir un menu, s'il vous plait ?" 0,0 0,10 10,10 10,0
rect .. 0,0 77,27 "le répertoire du référant"
circle http://www.inetnebr.example.com/lincoln/feedback/ 195,0 305,27
rect autre_fichier "dans le même répertoire que le référant" 306,0 419,27
point http://www.zyzzyva.example.com/ 100,100
point http://www.tripod.example.com/ 200,200
rect mailto:nate@tripod.example.com 100,150 200,0 "Bogues?"

top

Référencement de votre fichier imagemap

Exemple HTML

<a href="/maps/imagemap1.map">
<img ismap src="/images/imagemap1.gif">
</a>

Exemple XHTML

<a href="/maps/imagemap1.map">
<img ismap="ismap" src="/images/imagemap1.gif" />
</a>

top

Directive ImapBase

Description:Valeur par défaut de la directive base des fichiers imagemap
Syntaxe:ImapBase map|referer|URL
Défaut:ImapBase http://nom_serveur/
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_imagemap

La directive ImapBase permet de définir la valeur par défaut de la directive base des fichiers imagemap. Sa valeur est écrasée par la présence éventuelle d'une directive base dans le fichier imagemap. Si cette directive est absente, la valeur par défaut de la directive base est http://nom_serveur/.

Voir aussi

top

Directive ImapDefault

Description:Action à entreprendre par défaut lorsqu'un fichier imagemap est invoqué avec des coordonnées qui ne correspondent à aucune cible
Syntaxe:ImapDefault error|nocontent|map|referer|URL
Défaut:ImapDefault nocontent
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_imagemap

La directive ImapDefault permet de définir la valeur par défaut de la directive default utilisée dans les fichiers imagemap. Sa valeur est écrasée par la présence éventuelle d'une directive default dans le fichier imagemap. Si cette directive est absente, l'action associée à default est nocontent, ce qui implique l'envoi d'un code de statut 204 No Content au client. Dans ce cas, le client doit continuer à afficher la même page.

top

Directive ImapMenu

Description:Action à entreprendre si aucune coordonnée n'est fournie lorsqu'on invoque un fichier imagemap
Syntaxe:ImapMenu none|formatted|semiformatted|unformatted
Défaut:ImapMenu formatted
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_imagemap

La directive ImapMenu permet de spécifier l'action à entreprendre lorsqu'un fichier imagemap est invoqué sans coordonnées valides.

none
Si l'argument d'ImapMenu est none, aucun menu n'est généré, et l'action default est effectuée.
formatted
Le menu formatted est le menu le plus simple. Les commentaires du fichier imagemap sont ignorés. Un en-tête de niveau un est affiché, puis un séparateur horizontal, puis chacun des liens sur une ligne séparée. L'aspect du menu est similaire à celui d'un listing de répertoire.
semiformatted
Dans le menu semiformatted, les commentaires sont affichés au moment où ils apparaissent dans le fichier imagemap. Les lignes vides sont interprètées comme des lignes de séparation HTML. Aucun en-tête ni séparateur horizontal n'est affiché. À part ces différences, le menu semiformatted est identique au menu formatted.
unformatted
Les commentaires sont affichés et les lignes vides sont ignorées. N'est affiché que ce qui apparait dans le fichier imagemap. Toutes les lignes de séparation HTML et les en-têtes doivent être inclus en tant que commentaires dans le fichier imagemap. Cela vous procure une grande souplesse pour définir l'apparence de vos menus, mais vous oblige à rédiger vos fichiers imagemap en HTML, et non en texte plat.

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_basic.html.ko.euc-kr0000664000175100017510000003353014743132254023243 0ustar covenercovener mod_auth_basic - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_auth_basic

ֽ ƴմϴ. ֱٿ ϼ.
:Basic authentication
:Base
:auth_basic_module
ҽ:mod_auth_basic.c
:ġ 2.1 ĺ

ش (provider) Ͽ ں ϴ HTTP Basic Authentication Ѵ. HTTP Digest Authentication mod_auth_digest Ѵ.

Support Apache!

þ

Bugfix checklist

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

AuthBasicFake þ

:Fake basic authentication using the given expressions for username and password
:AuthBasicFake off|username [password]
⺻:none
:directory, .htaccess
Override ɼ:AuthConfig
:Base
:mod_auth_basic
:Apache HTTP Server 2.4.5 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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̸ ⺻· ư.

top

AuthBasicUseDigestAlgorithm þ

:Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
:AuthBasicUseDigestAlgorithm MD5|Off
⺻:AuthBasicUseDigestAlgorithm Off
:directory, .htaccess
Override ɼ:AuthConfig
:Base
:mod_auth_basic
:Apache HTTP Server 2.4.7 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/index.html.zh-cn.utf80000664000175100017510000005520314743132254021520 0ustar covenercovener 模块索引 - Apache HTTP 服务器 版本 2.4
<-
Apache > HTTP 服务器 > 文档 > 版本 2.4

模块索引

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

下面是 Apache HTTP 服务器发行版中的所有模块列表。参见按照字母顺序罗列的所有 Apache HTTP 服务器指令

参见

top

核心特性与多处理模块(MPM)

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)
event
A variant of the worker MPM with the goal of consuming threads only for connections with active processing
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
prefork
Implements a non-threaded, pre-forking web server
mpm_winnt
Multi-Processing Module optimized for Windows NT.
worker
Multi-Processing Module implementing a hybrid multi-threaded multi-process web server
top

其它模块

 A  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
Group authorizations based on host (name or IP address)
mod_actions
Execute 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_allowmethods
Easily restrict what HTTP methods can be used on the server
mod_asis
Sends files that contain their own HTTP headers
mod_auth_basic
Basic HTTP authentication
mod_auth_digest
User authentication using MD5 Digest Authentication
mod_auth_form
Form authentication
mod_authn_anon
Allows "anonymous" user access to authenticated areas
mod_authn_core
Core Authentication
mod_authn_dbd
User authentication using an SQL database
mod_authn_dbm
User authentication using DBM files
mod_authn_file
User authentication using text files
mod_authn_socache
Manages a cache of authentication credentials to relieve the load on backends
mod_authnz_fcgi
Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
mod_authnz_ldap
Allows an LDAP directory to be used to store the database for HTTP Basic authentication.
mod_authz_core
Core Authorization
mod_authz_dbd
Group Authorization and Login using SQL
mod_authz_dbm
Group authorization using DBM files
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_brotli
Compress content via Brotli before it is delivered to the client
mod_buffer
Support for request buffering
mod_cache
RFC 2616 compliant HTTP caching filter.
mod_cache_disk
Disk based storage module for the HTTP caching filter.
mod_cache_socache
Shared object cache (socache) based storage module for the HTTP caching filter.
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_data
Convert response body into an RFC2397 data URL
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_dialup
Send static content at a bandwidth rate limit, defined by the various old modem standards
mod_dir
Provides for "trailing slash" redirects and serving directory index files
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_hooks
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_heartbeat
Sends messages with server status to frontend proxy
mod_heartmonitor
Centralized monitor for mod_heartbeat origin servers
mod_http2
Support for the HTTP/2 transport layer
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_lbmethod_bybusyness
Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_byrequests
Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_bytraffic
Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_heartbeat
Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
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_debug
Additional configurable debug logging
mod_log_forensic
Forensic Logging of the requests made to the server
mod_logio
Logging of input and output bytes per request
mod_lua
Provides Lua hooks into various portions of the httpd request processing
mod_macro
Provides macros within apache httpd runtime configuration files
mod_md
Managing domains across virtual hosts, certificate provisioning via the ACME protocol
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_privileges
Support for Solaris privileges and for running virtual hosts under different user IDs.
mod_proxy
Multi-protocol 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_express
Dynamic mass reverse proxy extension for mod_proxy
mod_proxy_fcgi
FastCGI support module for mod_proxy
mod_proxy_fdpass
fdpass external process support module for mod_proxy
mod_proxy_ftp
FTP support module for mod_proxy
mod_proxy_hcheck
Dynamic health check of Balancer members (workers) for mod_proxy
mod_proxy_html
Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
mod_proxy_http
HTTP support module for mod_proxy
mod_proxy_http2
HTTP/2 support module for mod_proxy
mod_proxy_scgi
SCGI gateway module for mod_proxy
mod_proxy_uwsgi
UWSGI gateway module for mod_proxy
mod_proxy_wstunnel
Websockets support module for mod_proxy
mod_ratelimit
Bandwidth Rate Limiting for Clients
mod_reflector
Reflect a request body as a response via the output filter stack.
mod_remoteip
Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
mod_reqtimeout
Set timeout and minimum data rate for receiving requests
mod_request
Filters to handle and make available HTTP request bodies
mod_rewrite
Provides a rule-based rewriting engine to rewrite requested URLs on the fly
mod_sed
Filter Input (request) and Output (response) content using sed syntax
mod_session
Session support
mod_session_cookie
Cookie based session support
mod_session_crypto
Session encryption support
mod_session_dbd
DBD/SQL based session support
mod_setenvif
Allows the setting of environment variables based on characteristics of the request
mod_slotmem_plain
Slot-based shared memory provider.
mod_slotmem_shm
Slot-based shared memory provider.
mod_so
Loading of executable code and modules into the server at start-up or restart time
mod_socache_dbm
DBM based shared object cache provider.
mod_socache_dc
Distcache based shared object cache provider.
mod_socache_memcache
Memcache based shared object cache provider.
mod_socache_redis
Redis based shared object cache provider.
mod_socache_shmcb
shmcb based shared object cache provider.
mod_speling
Attempts to correct mistaken URLs by ignoring capitalization, or attempting to correct various minor misspellings.
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_substitute
Perform search and replace operations on response bodies
mod_suexec
Allows CGI scripts to run as a specified user and Group
mod_systemd
Provides better support for systemd integration
mod_unique_id
Provides an environment variable with a unique identifier for each request
mod_unixd
Basic (required) security for Unix-family platforms.
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
mod_watchdog
provides infrastructure for other modules to periodically run tasks
mod_xml2enc
Enhanced charset/internationalisation support for libxml2-based filter modules

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/mod_userdir.html.ja.utf80000664000175100017510000003212114743132254022272 0ustar covenercovener mod_userdir - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_userdir

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:ユーザ専用のディレクトリを提供
ステータス:Base
モジュール識別子:userdir_module
ソースファイル:mod_userdir.c

概要

このモジュールは、 http://example.com/~user/ 構文を使ってユーザ専用ディレクトリにアクセスできるようにします。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

UserDir ディレクティブ

説明:ユーザ専用ディレクトリの位置
構文:UserDir directory-filename [directory-filename] ...
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Base
モジュール:mod_userdir

UserDir ディレクティブは、 ユーザのドキュメントへのリクエストを受けた時に使う ユーザのホームディレクトリ中の、実際のディレクトリを 設定します。 directory-filename には次のどれかを指定します:

もし enableddisabled キーワードも UserDir に現われていなければ、 引数はファイル名パターンとして扱われ、 名前からディレクトリへの変換の指定を行なう時に使われます。 http://www.example.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.example.com/usershttp://www.example.com/users/bob/one/two.html
UserDir http://www.example.com/*/usrhttp://www.example.com/bob/usr/one/two.html
UserDir http://www.example.com/~*/http://www.example.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.example.com/

http://www.example.com/~bob/one/two.html へのリクエストはまず ~bob/public_html/one/two.html のページを調べ、その次に /usr/web/bob/one/two.html を調べ、最後に http://www.example.com/bob/one/two.html へのリダイレクトを送ります。

リダイレクトを加える場合は、リストの最後の選択肢でなければなりません。 Apache はリダイレクトが成功するかどうかを決めることはできませんので、 リストの前の方にリダイレクトを書くと、それが必ず使用される選択肢に なってしまいます。

2.1.4 以降では、ユーザディレクトリ置換機能はデフォルトでは起動しません。 それ以前のバージョンでは、UserDir ディレクティブが存在しなければ、UserDir public_html であると仮定されていました。

参照

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.en0000664000175100017510000016323715032765673021270 0ustar covenercovener Directive Index - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Directive Index

Available Languages:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

Available Languages:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directive-dict.html.tr.utf80000664000175100017510000004616214743132254022722 0ustar covenercovener Yönergeleri Tanımlamakta Kullanılan Terimler - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4

Yönergeleri Tanımlamakta Kullanılan Terimler

Mevcut Diller:  en  |  es  |  fr  |  ja  |  ko  |  tr 

Bu belgede Apache yapılandırma yönergelerini tanımlamakta kullanılan terimler açıklanmıştır.

Support Apache!

Ayrıca bakınız:

top

Açıklama

Yönergenin kullanım amacının kısa bir açıklaması.

top

Sözdizimi

Yönergenin bir yapılandırma dosyasında hangi söz dizimiyle görünebileceği belirtilir. Bu sözdizimi yönergeye özeldir ve ayrıntıları yönerge tanımında açıklanır. Genelde yönerge ismini aralarında boşluklar bırakılmış bir dizi argüman izler. Eğer argümanlardan biri kendi içinde boşluk içeriyorsa çift tırnak içine alınır. İsteğe bağlı argümanlar sözdiziminde köşeli ayraçların arasında gösterilmiştir. Birden fazla olası değeri olan argümanlarda değerler aralarına | karakteri konarak ayrılmıştır. Değerin yerine ismi belirtilen argümanlarda bu isimler eğik yazılırken, kendisi değer olan dizgeler öntanımlı yazıtipi ile gösterilmiştir. Değişik sayıda argüman alan yönergelerde bu durum son argümanı takibeden “...” ile belirtilmiştir.

Yönergelerde kullanılan argüman türleri çok çeşitlidir. Çok kullanılanlardan bazıları aşağıda tanımlanmıştır.

URL
http://host.example.com/yol/yordam/dosya.html örneğindeki gibi protokol şeması ve konak ismini isteğe bağlı bir dosya yolunun izlediği, açılımı “Uniform Resource Locator” olan ve Türkçe’ye “Tektip Özkaynak Konumlayıcı” şeklinde çevrilebilecek adresleri betimler.
URL-yolu
/yol/yordam/dosya.html örneğindeki gibi bir url’nin parçası olarak protokol şeması ve konak ismini izleyen bir yol dizgesini betimler. url-yolu, bir dosya sisteminin kök dizinine göre değil, DocumentRoot ile belirtilen dizine göre bir dosya yolu betimler.
dosya-yolu
/usr/local/apache/htdocs/yol/yordam/dosya.html örneğindeki gibi yerel dosya sisteminin kök dizini ile başlayan bir dosya yolunu betimler. Aksi belirtilmedikçe, bir / ile başlamayan bir dosya-yolu ServerRoot ile belirtilen dizine göre ele alınır.
dizin-yolu
/usr/local/apache/htdocs/yol/yordam/ örneğindeki gibi kök dizin ile başlayan, yerel dosya sistemindeki bir dizin yolunu betimler.
dosya-ismi
dosya.html örneğindeki gibi dizin yolu içermeyen bir dosya ismini betimler.
düzifd
Bir Perl uyumlu düzenli ifade betimler. Yönerge tanımında düzifd ile eşleşenler argüman olarak ele alınır.
uzantı
Bu genelde, dosya-ismi’nin bir parçası olarak son noktadan sonraki kısmı betimler. Bununla birlikte, Apache çok sayıda nokta içeren dosya isimlerinde ilk noktadan sonrasını uzantı kabul eden çoklu dosya ismi uzantılarını da tanır. Örneğin, dosya- ismi olarak dosya.html.tr değeri iki uzantı içerir: .html ve .tr. Apache yönergelerinde uzantı’ları başında noktası olmaksızın da belirtebilirsiniz. Ayrıca, uzantı’lar harf büyüklüğüne de duyarlı değildir.
MIME-türü
Dosya biçiminin, text/html örneğindeki gibi aralarına bir / konulmuş asıl ve alt biçimler şeklinde açıklandığı yönteme göre belirtileceğini betimler.
ortam-değişkeni
Apache yapılandırma sürecinde tanımlanmış bir ortam değişkeninin ismini betimler. Daha ayrıntılı bilgi için ortam değişkenleri belgesine bakınız.
top

Öntanımlı

Eğer yönerge öntanımlı bir değere sahipse o burada belirtilir (öntanımlı değer, yönergede kullanıcı tarafından belirtilmediği halde Apache tarafından belirtildiği varsayılarak işlem yapılan değerdir). Eğer öntanımlı bir değer yoksa bu bölümde bu durum “Yok” şeklinde belirtilir. Burada belirtilen öntanımlı değerin sunucu ile dağıtılan öntanımlı httpd.conf içindeki yönergede kullanılan değerle aynı olmasının gerekmediğine dikkat ediniz.

top

Bağlam

Yönergenin sunucunun yapılandırma dosyalarının nerelerinde meşru kabul edildiği aşağıdaki değerlerin virgül ayraçlı bir listesi halinde burada belirtilir.

sunucu geneli
Yönergenin sunucunun (httpd.conf gibi) yapılandırma dosyalarında <VirtualHost> ve <Directory> bölümleri dışında her yerde kullanılabileceğini belirtir. Ayrıca, .htaccess dosyalarında bulunmasına da izin verilmez.
sanal konak
Yönergenin sunucunun yapılandırma dosyalarının sadece <VirtualHost> bölümlerinde kullanıldığında geçerli kabul edileceğini belirtir.
dizin
Yönergenin sunucunun yapılandırma dosyalarında sadece <Directory>, <Location>, <Files>, <If> ve <Proxy> bölümlerinde kullanıldığında geçerli kabul edileceğini belirtir. Bu bağlama konu sınırlamaların çerçevesi Yapılandırma Bölümleri içinde çizilmiştir.
.htaccess
Bu bağlamda geçerli olacağı kabul edilen bir yönerge sadece dizin içi .htaccess dosyalarında görüldüğü zaman işleme sokulur. Üzerinde bir geçersizleştirme etkin kılınmışsa yönerge her şeye rağmen işleme sokulmayabilir.

Yönergeye sadece tasarlandığı bağlam içinde izin verilir; başka bir yerde kullanmayı denerseniz ya sunucunun bu bağlamı doğru şekilde işlemesine engel olan ya da sunucunun tamamen işlevsiz kalmasına sebep olan -- sunucu hiç başlatılamayabilir -- bir yapılandırma hatası alırsınız.

Yönergenin geçerli olacağı konumlar, aslında, listelenen bağlamların tamamına mantıksal VEYA uygulanarak bulunur. Başka bir deyişle, bir yönergenin geçerli olacağı yerler "sunucu geneli, .htaccess" şeklinde belirtilmişse yönerge httpd.conf dosyasında ve .htaccess dosyalarında, <Directory> veya <VirtualHost> bölümleri haricinde her yerde kullanılabilir.

top

Geçersizleştirme

Bir .htaccess dosyasında göründüğü takdirde yönerge işlenirken hangi yapılandırma geçersizleşirmesinin etkin olacağı burada belirtilir. Eğer yönerge bağlamının .htaccess dosyalarında görünmesine izin verilmiyorsa hiçbir bağlam listelenmez.

Geçersizleştirmeler AllowOverride yönergesi tarafından etkinleştirilir ve belli bir bağlama ve alt seviyelerde başka AllowOverride yönergeleri ile değiştirilmedikçe tüm çocuklarına uygulanır. Yönergenin belgesinde ayrıca kullanılabilecek tüm olası geçersizleştirme isimleri belirtilir.

top

Durum

Yönergenin Apache HTTP sunucusuna ne kadar sıkı bağlı olduğunu belirtir. Başka bir deyişle, yönergeye ve işlevselliğine erişim kazanmak için sunucuyu belli bir modül kümesiyle yeniden derlemek gerekip gerekmediği ile ilgili durumu belirtir. Bu özniteliğin olası değerleri şunlardır:

Çekirdek
Eğer bir yönerge “Çekirdek” durumuna sahip olarak listelenmişse bu, yönergenin Apache HTTP sunucusunun en iç kısımlarının bir parçası olduğu ve daima kullanılabilir olacağı anlamına gelir.
MPM
“MPM” durumuna sahip bir yönerge Çok Süreklilik Modülü tarafından sağlanır. Bu yönerge türü sadece ve sadece yönerge tanımının Modül satırında listelenmiş MPM’lerden birini kullanıyorsanız mevcut olacaktır.
Temel
“Temel” durumuna sahip bir yönerge, sunucuda öntanımlı derlenmiş standart Apache modüllerinden biri tarafından destekleniyor demektir. Bu nedenle sunucuyu derlemek için yapılandırırken yönergeyi içeren modülü yapılandırmadan özellikle kaldırmazsanız yönerge normal olarak kullanılabilir olacaktır.
Eklenti
“Eklenti” durumuna sahip bir yönerge, Apache sunucu kitinde bulunan ancak normalde sunucuyla birlikte derlenmeyen modüllerden biri tarafından sağlanır. Yönergeyi ve işlevselliğini etkin kılmak için sunucunun derleme öncesi paket yapılandırması sırasında modülün derleneceğini açıkça belirttikten sonra gerekirse sunucuyu yeniden derlemeniz gerekir.
Deneysel
“Deneysel” durumuna sahip bir yönerge, Apache sunucu kitinde bulunan modüllerden biri tarafından sağlanır ve modülün denenmesi tamamen sizin insiyatifinize bırakılır. Böyle bir yönerge her şeyiyle belgelenmiştir fakat gerektiği gibi desteklenmemiştir. Yönergeyi içeren modül öntanımlı olarak sunucuyla birlikte derlenebileceği gibi derlenmeyebilir de; bunun için yönergenin açıklandığı sayfanın başına ve kullanılabilirliği hakkında bilgi edinmek için yönergeyi içeren modüle bakın.
top

Modül

Burada sadece yönergeyi tanımlayan kaynak modülün ismi yazılır.

top

Uyumluluk

Eğer yönerge Apache’nin 2. sürüm dağıtımının özgün parçası değilse söz konusu sürüm burada belirtilir. Ayrıca, yönergenin kullanımı belli platformlarla sınırlıysa bunun ayrıntıları da burada belirtilir.

Mevcut Diller:  en  |  es  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.es0000664000175100017510000016371015032765673021271 0ustar covenercovener Índice de Directivas - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4 > Módulos

Índice de Directivas

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Comentarios

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.fr.utf80000664000175100017510000016341715021032132022131 0ustar covenercovener Index des directives - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Index des directives

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Toutes les directives Apache disponibles dans la distribution standard d'Apache sont référencées ici. Elles sont décrites en utilisant un format normalisé, et un dictionnaire des termes utilisés dans leurs descriptions est disponible.

Un Document de référence rapide des directives est également disponible. Il donne des détails à propos de chaque directive sous une forme abrégée.

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_md.html.fr.utf80000664000175100017510000034410315021032132021220 0ustar covenercovener mod_md - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_md

Langues Disponibles:  en  |  fr 

Description:Gestion des domaines au sein des serveurs virtuels et obtention de certificats via le protocole ACME
Statut:Expérimental
Identificateur de Module:md_module
Fichier Source:mod_md.c
Compatibilité:Disponible à partir de la version 2.4.30 du serveur HTTP Apache

Sommaire

Ce module permet de gérer les propriétés courantes des domaines pour un ou plusieurs serveurs virtuels. Il fournit deux fonctionnalités principales : la première permet la supervision et le renouvellement des certificats TLS via le protocole ACME (RFC 8555). Le module effectue le renouvellement des certificats avant leur expiration afin d'éviter une interruption des services internet. Il est possible de monitorer l'état de tous les certificats gérés par mod_md et de configurer le serveur de façon à ce qu'il envoie des notifications de renouvellement, d'expiration ou d'erreur personnalisées.

La seconde fonctionnalité principale fournit une implémentation alternative de l'agrafage OCSP, et ceci aussi bien pour les certificats gérés par mod_md que pour les certificats que vous gérez vous-même. Composant nécessaire pour tout site https, l'agrafage OCSP influence la vitesse de chargement des pages et suivant la configuration, la disponibilité de ces dernières. Vous trouverez plus de détails dans la section agrafage ci-dessous.

L'autorité ACME par défaut pour la gestion des certificats est Let's Encrypt, mais il est possible de configurer une autre CA si cette dernière supporte le protocole.

Exemple de configuration simple :

TLS dans un contexte de serveur virtuel

MDomain example.org

<VirtualHost *:443>
    ServerName example.org
    DocumentRoot htdocs/a

    SSLEngine on
    # aucun certificat spécifié
</VirtualHost>

Au démarrage, un serveur ainsi configuré contactera Let's Encrypt pour demander un certificat pour le domaine considéré. Si Let's Encrypt peut vérifier le propriétaire du domaine, le module obtiendra le certificat et sa chaîne de certification, le stockera dans son système de fichiers (voir la directive MDStoreDir) et le proposera au prochain redémarrage à mod_ssl.

Ce processus se déroule pendant l'exécution du serveur. Tous les autres serveurs virtuels continueront à fonctionner normalement, mais tant que le certificat ne sera pas disponible, toute requête pour le domaine considéré génèrera une réponse du type '503 Service Unavailable'.

Prérequis

Pour pouvoir être utilisé, ce module nécessite le chargement préalable du module mod_watchdog.

Pour que Let's Encrypt puisse signer et renouveler votre certificat, votre serveur doit être accessible depuis l'internet public sur le port 80 (http:) et/ou 443 (https:), à moins que votre serveur soit configuré pour utiliser les vérifications DNS - pour plus de détails, voir "certificats génériques".

Le module choisit une des méthodes proposées par Let's Encrypt. En général, LE propose des méthodes de vérification sur les ports ou le DNS et Apache choisit une des méthodes disponibles.

Pour déterminer quelles méthodes sont disponibles, le module consulte les ports sur lesquels écoute Apache httpd. Si le port 80 en fait partie, le module supposera que la vérification http: nommée http-01 est disponible. Si le port 443 en fait aussi partie, la vérification https: nommée tls-alpn-01 sera ajoutée à la liste des méthodes disponibles. Enfin, si la directive MDChallengeDns01 est définie, la méthode de vérification dns-01 sera aussi ajoutée.

Si votre configuration est plus complexe, deux méthodes permettent d'orienter ce choix. En premier lieu, voyez du côté de la directive MDPortMap si le serveur se trouve derrière un redirecteur de port comme un pare-feu. En second lieu, vous pouvez court-circuiter entièrement le processus de choix du module en définissant directement la directive MDCAChallenges.

Vérifications https:

Pour la vérification de domaine via le protocole TLS, le nom de la méthode correspondante est "tls-alpn-01". Le serveur Apache doit alors être en écoute sur le port 443 (voir la directive MDPortMap si vous redirigez ce port vers un autre).

Let's Encrypt ouvrira alors une connexion TLS avec Apache en utilisant l'indicateur spécial "acme-tls/1" (cette portion indication de TLS se nomme ALPN, d'où le nom de la méthode de vérification. ALPN est aussi utilisé par les navigateurs pour ouvrir une connexion HTTP/2.

Si vous ne souhaitez cependant qu'aucun de vos sites ne soit accessible sur le port 80, vous pouvez laiser ce dernier ouvert et rediriger toutes les requêtes vers vos sites en https:. Pour ce faire, utilisez la directive MDRequireHttps décrite plus loin. Votre serveur pourra alors continuer à répondre au requêtes en http: en provenance de Let's Encrypt. Comme dans le cas du protocole HTTP/2, vous pouvez configurer ceci de la manière suivante :

Protocols h2 http/1.1 acme-tls/1

La méthode de vérification "tls-alpn-01" sera alors disponible.

Certificats génériques

Les certificats génériques sont supportés à partir de la version 2.x de mod_md, mais leur obtention n'est pas triviale. Let's Encrypt impose pour ces derniers la vérification "dns-01". Aucune autre n'est considérée comme suffisamment efficace.

Apache ne peut cependant pas implémenter cette vérification de lui-même . Comme son nom l'indique, "dns-01" vous demande de présenter certains enregistrement DNS spécifiques à votre domaine qui doivent contenir certaines données de vérification. Vous devez donc être en mesure d'éditer et modifier les enregistrements DNS de votre domaine.

Si c'est le cas, vous pouvez procéder via mod_md. Supposons que vous disposiez pour cela du script /usr/bin/acme-setup-dns ; vous configurez alors Apache comme suit :

MDChallengeDns01 /usr/bin/acme-setup-dns

Apache fera alors appel à ce script lorsqu'il aura besoin de définir ou détruire un enregistrement DNS de vérification pour le domaine considéré.

Supposons ainsi que vous souhaitiez obtenir un certificat pour *.mydomain.com ; mod_md va appeler :

/usr/bin/acme-setup-dns setup mydomain.com challenge-data
# ceci nécessite de supprimer tout enregistrement DNS TXT pour
# _acme-challenge.mydomain.com et d'en créer un nouveau dont le contenu sera
# "challenge-data"

il appellera ensuite :

/usr/bin/acme-setup-dns teardown mydomain.com
# ceci nécessite de supprimer tout enregistrement DNS TXT pour
# _acme-challenge.mydomain.com

Monitoring

Apache possède un module de monitoring standard : mod_status. mod_md y ajoute une section et facilite le monitoring de votre domaine.

Vous pouvez alors visualiser tous vos domaines gérés par ordre alphabétique, les noms de domaine qu'ils contiennent, un état global, les date d'expiration ainsi que des paramètres spécifiques. Ces derniers comprennent la périodicité de renouvellement que vous avez sélectionnée (ou la valeur par défaut), la CA (autorité de certification) utilisée, etc...

La colonne "Renewal" montre des rapports d'activité ou d'erreur à propos des renouvellements de certificats, ce qui devrait faciliter la vie des utilisateurs qui souhaitent savoir si tout fonctionne correctement ou si des problèmes se produisent.

Si un des domaines gérés provoque une erreur, elle apparaîtra aussi ici, ce qui vous permettra de visualiser les éventuels problèmes sans devoir vous plonger dans les journaux du serveur.

Il existe aussi un nouveau gestionnaire, "md-status", qui peut vous fournir les informations à propos des domaines gérés à partir de "server-status" et au format JSON. Vous pouvez le configurer comme suit sur votre serveur :

<Location "/md-status">
  SetHandler md-status
</Location>

Comme pour "server-status", vous devez ajouter les autorisations nécessaires.

Si vous ne souhaitez recevoir l'état JSON que pour un domaine spécifique, ajoutez le simplement à votre URL d'état :

> curl https://<yourhost>/md-status/another-domain.org
{
  "name": "another-domain.org",
  "domains": [
    "another-domain.org",
    "www.another-domain.org"
  ],
  ...

Cet état JSON montre aussi un journal des renouvellements de certificats :

{
"when": "Wed, 19 Jun 2019 14:45:58 GMT",
"type": "progress", "detail": "The certificate for the managed domain has been renewed successfully and can be used. A graceful server restart now is recommended."
},{
"when": "Wed, 19 Jun 2019 14:45:58 GMT",
"type": "progress", "detail": "Retrieving certificate chain for test-901-003-1560955549.org"
},{
"when": "Wed, 19 Jun 2019 14:45:58 GMT",
"type": "progress", "detail": "Waiting for finalized order to become valid"
},{
"when": "Wed, 19 Jun 2019 14:45:50 GMT",
"type": "progress", "detail": "Submitting CSR to CA for test-901-003-1560955549.org"
},
...

Vous trouverez aussi ces informations dans le fichier "job.json" dans votre répertoire de test et, s'il est activé, dans le répertoire des domaines. Vous pourrez ainsi les consulter à tout moment.

Enfin, la directive MDCertificateStatus donne accès au informations à propos du certificat spécifié au format JSON.

Agrafage

Si vous voulez commencer par tester l'agrafage pour un seul domaine géré, utilisez cette configuration :

<MDomain mydomain.net>
  MDStapling on
</MDomain>

et utilisez 'server-status' et/ou MDMessageCmd pour voir comment tout cela fonctionne. Vous pourrez alors vérifier si l'information d'agrafage est présente, sa durée de validité, son origine et à quel moment elle sera rafraîchie.

Si tout fonctionne comme vous le souhaitez, vous pouvez définir cette configuration pour tous les certificats ou seulement vos certificats gérés.

De nombreux sites utilisent l'implémentation d'agrafage existante de mod_ssl depuis des années. Les implémentations par mod-ssl et mod_md présentent deux différences principales :

  1. Lecture des informations à la demande ou de manière planifiée : mod_ssl extrait les informations d'agrafage lorsque le besoin s'en fait sentir, par exemple lors d'une nouvelle connexion. mod_md quant à lui, extrait ces informations au démarrage du serveur et lorsqu'elles ont atteint les deux tiers de leur durée de vie.
  2. Conservation des informations en mémoire ou de manière persistante : mod_ssl peut conserver ces informations de manière persistante, mais la plupart des configurations exemples utilisent un cache en mémoire. mod_md quant à lui, stocke systématiquement les informations dans le système de fichiers.

Si par malchance vous redémarrez votre serveur alors que le service OCSP de votre CA est en panne, les utilisateurs ne pourront plus atteindre vos sites. Sans persistance des informations, votre serveur n'est plus en mesure de fournir au client les données nécessaires, et le navigateur client ne peut pas les obtenir lui-même car le service OCSP ne répond pas.

Avec l'implémentation de mod_md, l'information d'agrafage est stockée de manière persistante, et elle peut donc être réchargée au démarrage du serveur et être ainsi disponible pour les connexions entrantes. Un jour ou deux avant expiration des informations, mod_md va les renouveler, ce qui permet de faire face à un temps d'indisponibilité du service OCSP assez long.

Pour conserver une compatibilité ascendante, l'implémentation de mod_ssl n'a pas pu être modifiée en profondeur. Par exemple, mod_ssl est incapable d'ajouter une dépendance à mod_watchdog sans rendre inutilisables de nombreuses configurations existantes qui ne chargent pas ce module.

tailscale

Depuis la version 2.4.14 du module, vous pouvez l'utiliser pour obtenir des certificats pour vos domaines tailscale.

<MDomain mydomain.some-thing.ts.net>
  MDCertificateProtocol tailscale
  MDCertificateAuthority file://localhost/var/run/tailscale/tailscaled.sock",
</MDomain>

Tailscale permet des communications sécurisées entre vos machines, où qu'elles se trouvent, et peut leur fournir des noms de domaine dans l'espace *.ts.net. Pour ceux-ci, il fournira aussi ensuite des certificats Let's Encrypt de façon à ce que vous puissiez ouvrir ces domaines dans votre navigateur en toute sécurité.

Apache va contacter le démon tailscale local à l'aide des directives listées ci-dessous pour obtenir et renouveler les certificats. Ceci ne fonctionnera cependant que pour les noms de domaine que tailscale aura assigné à votre machine.

Dans le cas contraire, ces certificats fonctionneront exactement de la même façon que ceux qui auront été obtenus à l'aide du protocole ACME de Lets Encrypt. Vous les verrez dans le rapport d'état et les directives MDMessageCmd seront aussi exécutées pour eux.

Vous trouverez plus de détails dans la documentation github de mod_md.

Notez que cette fonctionnalité n'est disponible que sur les machines où le démon tailscale fournit un socket de domaine unix. Jusqu'à présent, ceci ne semble être le cas que sur les systèmes de style Unix.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive MDActivationDelay

Description:Définit le délai d'activation des nouveaux certificats
Syntaxe:MDActivationDelay duration
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

top

Directive MDBaseServer

Description:Définit si le serveur global peut être géré ou seulement les serveurs virtuels.
Syntaxe:MDBaseServer on|off
Défaut:MDBaseServer off
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir si le serveur global, autrement dit la partie du serveur située en dehors de tout serveur virtuel, doit être géré par mod_md ou non. Par défaut il ne le sera pas car cela provoquerait des effets de bord générateurs de confusion. Il est donc recommandé de définir des serveurs virtuels pour tous les domaines gérés, et d'exclure des domaines gérés le serveur global (serveur par défaut).

top

Directive MDCAChallenges

Description:Type de négociation ACME utilisée pour prouver l'appartenance du domaine.
Syntaxe:MDCAChallenges name [ name ... ]
Défaut:MDCAChallenges tls-alpn-01 http-01 dns-01
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir les types de négociation utilisés (par ordre de préférences) pour prouver l'appartenance du domaine. Les types de négociation supportés par le module sont 'tls-alpn-01', 'dns-01' et 'http-01'. Le module parcourt toute la configuration du serveur pour déterminer quelles méthodes peuvent être utilisées.

Si par exemple le serveur est en écoute sur le port 80, c'est la méthode 'http-01' qui sera disponible. Pour 'dns-01', une commande MDChallengeDns01 définie sera requise. La méthode 'tls-alpn-01' est décrite ci-dessus dans 'https: Challenges'.

Cette sélection automatique fonctionne pour la plupart des configurations. Mais comme Apache est un serveur très puissant avec de nombreuses options de configuration, certains cas pourront poser des problèmes. Par exemple, il peut être en écoute sur plusieurs adresses IP, certaines étant accessibles en https: et d'autres non.

Si vous définissez MDCAChallenges directement, la sélection automatique est désactivée. A la place, le module va utiliser la liste de méthodes de négociation spécifiée pour dialoguer avec le serveur ACME (un type de négociation doit aussi être proposé par le serveur). Ces méthodes de négociation sont examinées dans l'ordre selon lequel elles sont spécifiées.

top

Directive MDCertificateAgreement

Description:Acceptation des conditions d'utilisation de l'autorité de certification.
Syntaxe:MDCertificateAgreement accepted
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Lorsque vous utilisez mod_md pour obtenir un certificat, vous devenez un client de l'autorité de certification (par exemple Let's Encrypt). Cela signifie que vous devez lire et approuver leurs conditions d'utilisation, et donc que vous avez compris ce qu'ils ont à offrir, ce qu'ils ne fournissent pas, et ce que vous devez vous-même fournir. mod_md ne peut pas de lui-même procéder à cet agrément à votre place.

top

Directive MDCertificateAuthority

Description:Les URLs du service ACME de l'autorité de certification.
Syntaxe:MDCertificateAuthority url
Défaut:MDCertificateAuthority letsencrypt
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Les URLs auxquelles l'autorité de certication offre son service. Plutôt que l'URL proprement dite, vous pouvez spécifier 'letsencrypt' ou 'buypass'.

Si vous spécifiez plusieurs URLs, chacune d'entre elles est testée en mode tourniquet ("round-robin") après un certain nombre d'échecs. Vous pouvez définir la rapidité de ce processus à l'aide des directives MDRetryDelay et MDRetryFailover. Par défaut, une demie journée d'essais infructueux est considérée comme un échec.

Tous les autres réglages s'appliquent à chacune de ces URLs. Il est ainsi par exemple impossible d'en avoir deux avec des directives MDExternalAccountBinding différentes.

A des fins de test, les CAs fournissent en général une seconde URL de service. Le service 'test' ne fournit pas de certificat valable pour un navigateur, mais il est moins regardant vis à vis des limites de vitesse. Il permet de tester votre configuration avant de passer à l'URL de service de production.

Configuration pour le mode test de Let's Encrypt

MDCertificateAuthority https://acme-staging-v02.api.letsencrypt.org/directory
top

Directive MDCertificateCheck

Description:Définit le motif de nom et d’URL pour un nom de site de vérification de certificat.
Syntaxe:MDCertificateCheck name url
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

top

Directive MDCertificateFile

Description:Définit un fichier de certificat statique pour le domaine géré.
Syntaxe:MDCertificateFile path-to-pem-file
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive s'utilise dans une section MDomainSet et permet de spécifier le nom du fichier qui contiendra le certificat pour le domaine géré. La clé correspondante est spécifiée via la directive MDCertificateKeyFile.

Exemple

<MDomain mydomain.com>
  MDCertificateFile /etc/ssl/my.cert
  MDCertificateKeyFile /etc/ssl/my.key
</MDomain>

Cette directive est équivalente à la directive SSLCertificateFile de mod_ssl. Elle s'utilise dans de nombreuses applications.

Une première application est la migration de la gestion des certificats d'un domaine existant depuis le mode statique via des fichiers vers le mode automatique via Let's Encrypt. A cet effet, vous définissez tout d'abord la section MDomainSet dans laquelle vous spécifiez les fichiers, puis supprimez la directive SSLCertificateFile de la configuration de vos serveurs virtuels.

Avec cette configuration, votre serveur fonctionnera comme avant, avec probablement moins de lignes répétitives. Vous pouvez alors ajouter la directive MDRenewMode avec pour valeur "always", et le module obtiendra un nouveau cerificat avant que celui du fichier considéré n'arrive à expiration. Une fois le certificat renouvelé, vous pouvez supprimer la directive MDCertificateFile et recharger la configuration.

Une autre application est le renouvellement de vos certificats Let's Encrypt avec d'autres clients ACME comme l'excellent certbot. A cet effet, faites pointer vos domaines gérés vers les fichiers de certbot et ils travaillerons alors ensemble.

top

Directive MDCertificateKeyFile

Description:Définit une clé privée statique pour le certificat statique.
Syntaxe:MDCertificateKeyFile path-to-file
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive s'utilise dans une section MDomainSet et permet de spécifier le nom du fichier contenant la clé privée pour le domaine géré. Le certificat correspondant est spécifié via la directive MDCertificateFile.

Cette directive est équivalente à la directive SSLCertificateKeyFile de mod_ssl.

top

Directive MDCertificateMonitor

Description:L'URL d'un moniteur d'enregistrement de certificat.
Syntaxe:MDCertificateMonitor name url
Défaut:MDCertificateMonitor crt.sh https://crt.sh?q=
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive impacte l'interface utilisateur HTML 'server-status' et n'a rien à voir avec le fonctionnement de mod_md proprement dit. Elle permet de définir le lien qui s'affiche sur cette interface pour accéder facilement à un moniteur de certificat. L'empreinte SHA256 du certificat doit être ajoutée à l'URL spécifié.

Les moniteurs de certificat donnent accès aux enregistrements de la Certificate Transparency (CT) afin de tracer l'utilisation des certificats pour les domaines. Vous pourrez au moins vérifier si Let's Encrypt (ou tout autre CA que vous aurez défini) a bien inscrit votre certificat dans les enregistrements de CT.

Avertissement : La mise à jour des enregistrements des certificats et leur prise en compte par les moniteurs peut prendre un certain temps. Ce dernier varie en fonction des enregistreurs et des moniteurs. Un nouveau certificat ne sera donc pas connu immédiatement.

top

Directive MDCertificateProtocol

Description:Le protocole à utiliser avec l'autorité de certification.
Syntaxe:MDCertificateProtocol protocol
Défaut:MDCertificateProtocol ACME
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de spécifier le protocole à utiliser. Pour l'heure, seul le protocole ACME est supporté.

top

Directive MDCertificateStatus

Description:Extrait les informations publiques du certificat au format JSON.
Syntaxe:MDCertificateStatus on|off
Défaut:MDCertificateStatus on
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Lorsque cette directive est à "on", vous disposez d'une ressource pour les domaines gérés à https://domain/.httpd/certificate-status qui renvoie un document au format JSON contenant une liste de propriétés concernant les clés, le certificat courant et, s'il est disponible, le certificat renouvelé.

Exemple

{
  "valid-until": "Thu, 29 Aug 2019 16:06:35 GMT",
  "valid-from": "Fri, 31 May 2019 16:06:35 GMT",
  "serial": "03039C464D454EDE79FCD2CAE859F668F269",
  "sha256-fingerprint": "1ff3bfd2c7c199489ed04df6e29a9b4ea6c015fe8a1b0ce3deb88afc751e352d"
  "renewal" : { ...renewed cert information... }
}
top

Directive MDChallengeDns01

Description:Définit la commande d'activation/désactivation des vérifications dns-01
Syntaxe:MDChallengeDns01 path-to-command
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir le programme à appeler lorsque la vérification "dns-01" doit être activée/désactivée. Le programme prend respectivement comme arguments "setup" ou "teardown" suivi du nom de domaine. Pour "setup", le programme prend comme argument supplémentaire les données de vérification "dns-01". Lorsque MDChallengeDns01Version est définie à 2, `teardown` prend aussi comme argument le contenu de la vérification.

Tant que la méthode de vérification "http:" ou "https:" est valable, vous n'avez pas besoin de définir cette directive. Cependant, Let's Encrypt n'accepte que "dns-01" comme méthode de vérification valide pour les certificats génériques. Si vous avez besoin d'un tel certificat, vous devez alors définir cette directive.

Il est maintenant possible d'utiliser cette directive dans une section MDomain pour spécifier une commande spécifique au domaine considéré. Cela permet de configurer un script spécifique au fournisseur de DNS concerné.

Reportez vous à la section sur les certificats génériques pour plus de détails.

top

Directive MDChallengeDns01Version

Description:Définit le type des arguments avec lesquels appeler MDChallengeDns01
Syntaxe:MDChallengeDns01Version 1|2
Défaut:MDChallengeDns01Version 1
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache

Cette directive permet de définir de quelle manière est invoquée la commande MDChallengeDns01, à savoir le nombre et le type de ses arguments. Voir MDChallengeDns01 pour les différences. Cette définition est globale et ne peut pas s'appliquer différemment pour chaque domaine.

top

Directive MDCheckInterval

Description:Détermine la périodicité de la vérification des certificats
Syntaxe:MDCheckInterval duration
Défaut:MDCheckInterval 12h
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.60 du serveur HTTP Apache

Cette option permet de définir l’intervalle entre deux vérifications de certificat. Par défaut, la validité et le besoin de renouvellement sont vérifiés deux fois par jour. Cet intervalle n’est cependant pas appliqué avec précision. En effet, le module lui applique une plage de variation aléatoire de +/- 50%. Avec l’intervalle par défaut de 12 heures, cela signifie que l’intervalle réel entre deux vérifications varie entre 6 et 18 heures, la variation s’appliquant à nouveau à chaque vérification. Cela permet d’atténuer les pics de trafic sur les serveurs ACME.

La valeur minimale pouvant être définie pour l’intervalle est de 1 seconde. Il est cependant déconseillé de définir un intervalle aussi court sur un serveur en production.

top

Directive MDContactEmail

Description:Adresse Email pour l'enregistrement du compte
Syntaxe:MDContactEmail address
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

Lors de votre inscription, vous devez fournir une url de contact pour le protocole ACME. Actuellement, Let's Encrypt exige une adresse Email qu'il utilisera pour vous informer des renouvellements de certificats ou de toute modification des conditions d'utilisation. Pour obtenir cette adresse, mod_md utilise l'email spécifiée par la directive MDContactEmail dans votre configuration de httpd ; veillez par conséquent à bien spécifier une adresse correcte à ce niveau. Si la directive MDContactEmail n'est pas définie, mod_md utilisera l'email spécifiée via la directive ServerAdmin.

top

Directive MDDriveMode

Description:Ancien nom de MDRenewMode.
Syntaxe:MDDriveMode always|auto|manual
Défaut:MDDriveMode auto
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive est l'ancien nom de la directive MDRenewMode, et n'est encore supportée qu'à titre de compatibilité ascendante.

top

Directive MDExternalAccountBinding

Description:Définit les valeurs keyid et hmac de liaison avec les comptes externes à utiliser dans les CA
Syntaxe:MDExternalAccountBinding key-id hmac-64 | none | file
Défaut:MDExternalAccountBinding none
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.52 du serveur HTTP Apache

Cette directive permet de définir des valeurs pour associer des comptes externes avec ACME ("External Account Binding") ; c'est une fonctionnalité de la norme ACME qui permet à des clients d'associer des inscriptions à un compte client existant sur les serveurs ACME.

Certains CAs ACME ont besoin de ces valeurs, mais ce n'est pas le cas pour Let's Encrypt. Vérifiez avec votre CA ACME si vous avez besoin de ces valeurs et la manière de les obtenir. Ces dernières se composent de deux chaînes : un identifiant de clé et une valeur 'hmac' codée en base64.

Vous pouvez définir ces valeurs de manière globale ou pour un MDomain spécifique. Comme ces valeurs permettent à n'importe qui de s'inscrire sous le même compte, il est conseillé de restreindre les permissions d'accès au fichier de configuration (à root seulement, par exemple).

Les valeurs peuvent aussi être extraites d'un fichier JSON pour conserver l'ouverture des permissions au niveau de la configuration du serveur et restreindre celles de ce fichier. Le fichier JSON sera du style :

Exemple de fichier EAB JSON

{"kid": "kid-1", "hmac": "zWND..."}

Si vous modifiez les valeurs EAB, ce sont les nouvelles valeurs qui seront utilisées lors du prochain renouvellement de certificat.

top

Directive MDHttpProxy

Description:Spécifie un serveur mandataire pour les connexions sortantes.
Syntaxe:MDHttpProxy url
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de spécifier un serveur http mandataire pour se connecter à l'autorité de certification spécifiée via MDCertificateAuthority. Vous devez la définir si votre serveur web ne peut atteindre internet que via un serveur mandataire.

top

Directive MDMatchNames

Description:Définit comment les noms DNS sont comparés aux vhosts
Syntaxe:MDMatchNames all|servernames
Défaut:MDMatchNames all
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache

Le mode `all` correspond au comportement de toutes les versions précédentes. ServerName et ServerAlias sont inspectés pour trouver le MDomain qui correspond à un serveur virtuel. Les recouvrements sont automatiquement détectés, même si vous n'avez ajouté qu'un des noms à un MDomain.

Cet automatisme présente cependant des inconvénients avec les configurations plus complexes. Si vous définissez cette directive à `servernames`, seul le ServerName d'un serveur virtuel est inspecté pour la correspondance et les ServerAliases sont donc ignorés. Les Aliases seront tout de même ajoutés au certificat obtenu, à moins que vous ne spécifiiez aussi `MDMembers manual`.

`servernames` possède un autre avantage : il vous confère plus de souplesse avec les sous-domaines et les caractères génériques. Vous pouvez ainsi définir un MDomain avec un caractère générique et avoir d'autres MDomains pour des noms de sous-domaines spécifiques.

top

Directive MDMember

Description:Nom d'hôte additionnel pour le domaine géré.
Syntaxe:MDMember hostname
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Plutôt que de lister tous les noms DNS sur la même ligne, vous pouvez utiliser la directive MDMember pour ajouter des noms d'hôte à un domaine géré.

Exemple

<MDomain example.org>
    MDMember www.example.org
    MDMember mail.example.org
</MDomain>

Si vous utilisez cette directive au niveau de la configuration globale, en dehors de tout serveur virtuel correspondant à un domaine géré, vous ne pouvez spécifier qu'une valeur, 'auto' ou 'manual' comme mode par défaut pour tous les autres domaines gérés. Voir la directive MDomain pour une description de ces valeurs.

top

Directive MDMembers

Description:Définit si les alias de noms de domaines sont automatiquement ajoutés.
Syntaxe:MDMembers auto|manual
Défaut:MDMembers auto
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir si les valeurs de ServerName et ServerAlias sont automatiquement ajoutées en tant que membres d'un domaine géré.

top

Directive MDMessageCmd

Description:Gère les évènements pour les domaines gérés
Syntaxe:MDMessageCmd path-to-cmd optional-args
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir la commande à appeler lorsqu'un des évènements "renewed", "installed", "expiring" ou "errored" se produit pour un domaine géré. La commande sera probablement invoquée pour d'autres évènements dans le futur et ignorera les évènements pour lesquels elle n'aura pas été préparée.

Il s'agit d'une version plus souple de la directive MDNotifyCmd.

Exemple

MDMessageCmd /etc/apache/md-message

# sera invoquée sous la forme "/etc/apache/md-message renewed mydomain.com" # lorsqu'un nouveau certificat sera disponible pour le domaine mydomain.com

Le programme ne doit pas être bloquant car le module attend qu'il se termine. Un code de retour autre que 0 doit indiquer une erreur d'exécution.

"errored" n'est pas l'évènement à surveiller en priorité car le renouvellement du certificat est censé se produire suffisammant tôt pour éviter toute interruption de service. Cet évènement est signalé au plus une fois par heure.

L'évènement "expiring", quant à lui, doit être pris au sérieux. Il se produit lorsque la valeur de MDWarnWindow est atteinte. Par défaut, cette valeur correspond à 10% de la durée de vie du certificat, donc actuellement pour Let's Encrypt, 9 jours avant expiration du certificat. Le message d'avertissement est répété au plus une fois par jour.

'renewed' indique qu'un nouveau certificat a été obtenu et se trouve dans la zone intermédiaire du magasin MD. Il sera activé au prochain restart/reload du serveur.

'installed' indique qu'un nouveau certificat a été transféré depuis la zone intermédiaire vers la zone des domaines du magasin MD. Cet évènement se produit lors d'un restart/reload du serveur. A la différence des autres commandes, MDMessageCmd s'exécute avec les permissions de root (sur les systèmes *nix) et a donc accès aux fichiers de certificats (et aux clés). Les certificats nécessaires à d'autres applications ou possédant des formats différents peuvent être traités suite à cet évènement.

Un évènement de type 'renewing' est déclenché avant le démarrage du processus de renouvellement pour le domaine géré. Si dans ce cas la commande renvoie une valeur non nulle, le renouvellement sera interrompu et tenté à nouveau au cycle suivant. Certaines configurations de clusters l'utilisent pour n'effectuer le renouvellement que sur un seul noeud.

Un évènement de type 'challenge-setup:type:domain' est déclenché lorsque les données de vérification pour un domaine ont été créées. Il est invoqué avant qu'il soit demandé au serveur ACME de les vérifier. type contient une des méthodes de vérification ACME. Il est invoqué pour chaque nom DNS d'un MDomain. Les configurations de clusters peuvent utiliser cet évènement pour distribuer les fichiers de vérification à tous les noeuds.

Un évènement de type ocsp-errored est déclenché lorsque le MDStapling est activé pour un domaine, et indique qu'une erreur s'est produite en essayant d'obtenir la réponse OCSP de l'autorité de certification. mod_md essaiera à nouveau d'obtenir cette réponse.

top

Directive MDMustStaple

Description:Définit si les nouveaux certificats doivent avoir le drapeau OCSP Must Staple activé.
Syntaxe:MDMustStaple on|off
Défaut:MDMustStaple off
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir si les nouveaux certificats doivent avoir le drapeau OCSP Must Staple activé ou non. Si un certificat possède ce drapeau, le serveur devra envoyer une réponse avec agrafage OCSP à chaque client. Ceci ne fonctionne que si vous configurez mod_ssl pour générer cette agrafe (voir la directive SSLUseStapling et ses directives dérivées).

top

Directive MDNotifyCmd

Description:Lance un programme lorsqu'un domaine géré est opérationnel.
Syntaxe:MDNotifyCmd path [ args ]
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir un programme à lancer lorsqu'un domaine géré a obtenu ou renouvelé son certificat. Ce programme reçoit le nom de domaine géré concerné comme argument additionnel (après les paramètres spécifiés ici). Il doit renvoyer un code d'état de 0 s'il s'est exécuté avec succès.

top

Directive MDomain

Description:Définit une liste de noms de domaines qui appartiennent à un groupe.
Syntaxe:MDomain dns-name [ other-dns-name... ] [auto|manual]
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Tous les domaines de la liste seront gérés par mod_md comme un seul domaine géré (Managed Domain - MD). mod_md ne demandera qu'un seul certificat qui sera valide pour tous ces noms de domaine. Cette directive s'utilise au niveau de la configuration globale (voir plus loin les autres directives MD). Si un domaine nécessite une configuration particulière, utilisez la directive <MDomainSet>.

Deux définitions supplémentaires sont nécessaires pour un domaine géré : une adresse Email de contact (via MDContactEmail ou ServerAdmin) et MDCertificateAgreement. L'adresse électronique du ServerAdmin permet de s'enregistrer auprès de l'autorité de certification (par défaut Let's Encrypt). L'autorité de certification l'utilisera pour vous informer à propos du statut de vos certificats ou d'éventuelles modifications de ses services.

La seconde définition, MDCertificateAgreement doit avoir pour valeur "accepted". Vous confirmez ainsi que vous acceptez les conditions d'utilisation du CA.

Exemple

MDContactEmail admin@example.org
MDCertificateAgreement accepted
MDomain example.org www.example.org

<VirtualHost *:443>
    ServerName example.org
    DocumentRoot htdocs/root

    SSLEngine on
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.org
    DocumentRoot htdocs/www

    SSLEngine on
</VirtualHost>

En plus de la liste des domaines gérés, cette directive accepte un paramètre supplémentaire qui peut prendre pour valeur 'manual' ou 'auto'. Ce paramètre permet de définir si un domaine sera géré sous le nom spécifié dans la liste seul ('manual'), ou si tous les noms du serveur virtuel correspondant seront gérés ('auto'). C'est d'ailleurs cette dernière valeur qui est la valeur par défaut.

Exemple

MDomain example.org

<VirtualHost *:443>
    ServerName example.org
    ServerAlias www.example.org
    DocumentRoot htdocs/root

    SSLEngine on
</VirtualHost>

MDomain example2.org auto

<VirtualHost *:443>
    ServerName example2.org
    ServerAlias www.example2.org
    ...
</VirtualHost>

Dans cet exemple, le domaine 'www.example.org' est automatiquement ajouté à la liste MD 'example.org'. De manière similaire, le domaine 'www.example2.org' sera automatiquement ajouté à la liste MD 'example2.org' pour laquelle 'auto' est explicitement spécifié. Chaque fois que vous ajouterez des noms à ces serveurs virtuels via ServerAlias, ils seront ajoutés à la liste MD correspondante.

Si vous préférez déclarer explicitement tous les noms de domaines, utilisez le mode 'manual'. Une erreur sera enregistrée dans le journal si les noms ne correspondent pas à ceux attendus.

top

Directive <MDomainSet>

Description:Conteneur de directives à appliquer à un ou plusieurs domaines gérés.
Syntaxe:<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive est équivalente à la directive MDomain avec la possibilité supplémentaire d'ajouter des paramètres seulement pour le domaine géré considéré. En fait, vous pouvez aussi utiliser "<MDomain ..>" à titre de raccourci.

Cette directive permet de configurer un domaine géré en spécifiant un autre CA, ou d'autres paramètres de renouvellement des certificats, etc...

Exemple

<MDomain sandbox.example.org>
    MDCertificateAuthority   https://someotherca.com/ACME
</MDomain>

Cette configuration est souvent utilisée pour définir des paramètres https: spécifiques à votre domaine.

Exemple

<MDomain example.org>
    MDRequireHttps temporary
</MDomain>
top

Directive MDPortMap

Description:Mappage des ports externes avec les ports internes pour vérifier à qui appartient le domaine.
Syntaxe:MDPortMap map1 [ map2 ]
Défaut:MDPortMap http:80 https:443
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Le protocole ACME propose deux méthodes pour vérifier à qui appartient le domaine via HTTP : la première utilise les URLs en "http:" (port 80) et la deuxième les URLs en "https:" (port 443). Si votre serveur n'est accessible sur aucun de ces ports, ACME ne pourra fonctionner que si vous configurez votre serveur DNS de manière adéquate (voir la directive MDChallengeDns01).

Sur la plupart des serveurs publics, "http:" arrive sur le port 80 et "https:" sur le port 443. Ce module vérifie les ports sur lesquels votre serveur Apache est en écoute et suppose qu'ils sont disponibles. Autrement dit, si votre serveur n'est pas en écoute sur le port 80, le module suppose que les requêtes en "http:" en provenance d'internet ne seront pas traitées.

Ce raisonnement est légitime, mais il peut s'avérer faux. Par exemple, même si votre serveur est effectivement en écoute sur le port 80, votre pare-feu peut bloquer ce dernier. "http:" ne sera alors disponible que sur votre intranet. Dans ce cas, le module va supposer de manière erronée que Let's Encrypt peut effectuer des vérifications en "http:" avec votre serveur. Ces dernières échouerons car elles auront été rejetées par votre pare-feu.

Exemple

MDPortMap http:- https:8433

L'exemple précédent montre comment spécifier que les requêtes en "http:" en provenance d'internet n'arriveront jamais. En outre, il indique que les requêtes en "https:" arriveront sur le port 8433.

Cette définition peut s'avérer nécessaire si vous faites de la redirection de port ; votre serveur peut ainsi être accessible depuis l' Internet sur le port 443, alors que le port local utilisé par httpd sera différent. Par exemple, votre serveur peut n'être en écoute que sur les ports 8443 et 8000, mais accessible depuis internet sur les ports 443 et 80.

top

Directive MDPrivateKeys

Description:Définit le type et la taille des clés privées générées.
Syntaxe:MDPrivateKeys type [ params... ]
Défaut:MDPrivateKeys RSA 2048
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir les paramètres de construction des clés privées pour les domaines gérés. Vous pouvez configurer plusieurs types de clés privées et le module obtiendra un certificat pour chaque clé.

La recommandation actuelle (en 2017) est de 2048 bits au minimum, et une valeur inférieure ne sera pas acceptée. Des valeurs supérieures offriront une plus grande sécurité mais seront plus gourmandes en ressources, et augmenteront donc la charge de votre serveur, ce qui pourra (ou non) être gênant pour vous.

D'autres types de clés seront supportés dans le futur. Vous pouvez par exemple configurer une clé RSA et une clé Elliptic Curve (EC) de façon à ce que deux certificats soient créés pour le domaine concerné. Lors d'une connexion avec un client, c'est la première clé supportée par ce dernier qui sera utilisée.

Comme les clés et certificats EC sont plus petits, vous pouvez les proposer en premier pour tous les clients modernes compatibles, ce qui peut accélérer la phase de négociation. Ajoutez tout de même une clé RSA pour supporter les clients plus anciens.

Exemple

MDPrivateKeys secp256r1 rsa3072

Les types EC supportés dépendent du CA que vous utilisez. Par exemple, Let's encrypt supporte les courbes elliptiques 'secp256r1' et 'secp384r1'.

Chaque type de clé et certificat est stocké dans son fichier propre au sein de l'espace de stockage MD. Le type de clé constitue une partie du nom de fichier avec une convention de nommage présentant une compatibilité ascendante avec les certificats RSA. Vous pouvez ainsi continuer à partager ces fichiers avec les autres applications.

Notez que cette directive n'aura d'effet que sur les nouvelles clés. Toute clé préexistante ne sera pas affectée. En outre, seules les clés privées générées pour les certificats sont concernées, les clés de comptes ACME n'étant pas affectées.

top

Directive MDProfile

Description:Utiliser un profile ACME spécifique depuis le CA
Syntaxe:MDProfile name
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.64 du serveur HTTP Apache

Il s’agit d’une extension non standard d’ACME par Let's Encrypt.

Lets Encrypt a annoncé qu’ils allaient ajouter la prise en charge des profiles de certificat à leurs CA courant 2025, en commençant par leurs serveurs de test. Cette fonctionnalité, entre autres détails, vous permettra de définir la durée de validité des certificats que vous recevez. À ce titre, le profile « default » conservera la valeur de 90 jours, alors que le profile « tlsserver » délivrera des certificats dont la durée de validité sera de 6 jours seulement.

Si vous ne modifiez pas la configuration de votre module mod_md, vous continuerez à recevoir des certificats d’une durée de validité de 90 jours. Si vous pensez qu’une durée de validité plus courte convient mieux à votre situation (et acceptez le risque que le temps de renouvellement soit beaucoup plus court), vous pouvez définir le profile à utiliser à l’aide de « MDProfile tlsserver ».

Les noms de profile sont définis par le CA. Si vous tentez de définie un profile non valable, aucun profile ne sera utilisé, et le certificat sera délivré avec les valeurs par défaut du CA.

Voir la directive MDProfileMandatory pour la manière de désactiver les valeurs par défaut pour les profiles.

top

Directive MDProfileMandatory

Description:Contrôler si un MDProfile est obligatoire.
Syntaxe:MDProfileMandatory on|off
Défaut:MDProfileMandatory off
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de contrôler si un MDProfile que vous définissez est obligatoire ou non. S’il est obligatoire et si le CA ne propose pas de profile configuré, le renouvellement du certificat échouera.

S’il n’est pas obligatoire et si le CA ne propose pas de profile, les renouvellements seront effectués sans profile particulier et le CA délivrera les certificats avec les valeurs par défaut.

top

Directive MDRenewMode

Description:Contrôle le renouvellement des certificats.
Syntaxe:MDRenewMode always|auto|manual
Défaut:MDRenewMode auto
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

En mode "auto" (mode par défaut), le module va agir de la manière la plus opportune pour chaque domaine géré. Si un domaine ne possède pas de certificat, le module en demandera un à l'autorité de certification.

Si par contre vous avez défini un domaine géré qui n'est utilisé par aucun serveur virtuel, le module n'effectuera aucune demande de renouvellement. De même, pour les domaines gérés avec des fichiers de certificats statiques (voir MDCertificateFile), le module supposera que vous avez votre propre source et n'effectuera aucune demande de renouvellement.

Avec le mode "always", le module renouvellera les certificats des modules gérés, même s'il ne sont pas utilisés ou possèdent un fichier de certificats statique.

A l'opposé, avec le mode "manual", mod_md n'effectuera aucune demande automatique de renouvellement pour aucun domaine géré.

top

Directive MDRenewWindow

Description:Définit le moment auquel un certificat doit être renouvelé.
Syntaxe:MDRenewWindow duration
Défaut:MDRenewWindow 33%
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Lorsqu'un certificat arrive à expiration, mod_md va tenter d'en obtenir un nouveau signé.

Normalement, les certificats ont une validité de 90 jours, et mod_md les renouvelle lorsqu'il leur reste 33% de durée de vie (soit 30 jours pour une durée de vie de 90 jours). Si cela ne correspond pas à ce que vous souhaitez, vous pouvez spécifier une autre valeur comme dans les exemples suivants :

Exemple

# 21 jours avant expiration
MDRenewWindow 21d 
# 30 secondes (peut-être un peu juste !)
MDRenewWindow 30s
# lorsqu'il reste 10% de durée de vie au certificat
MDRenewWindow 10%

En mode pilotage automatique, le module va vérifier le statut des domaines gérés au moins toutes les 12 heures pour voir s'il y a quelque chose à faire. En cas d'erreur, par exemple lorsque le CA est inaccessible, il va dans un premier temps réessayer après quelques secondes. Si l'erreur persiste, il va réduire son intervalle de vérification de 12 à 1 heure.

top

Directive MDRequireHttps

Description:Redirige le trafic http: vers https: pour les domaines gérés.
Syntaxe:MDRequireHttps off|temporary|permanent
Défaut:MDRequireHttps off
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive facilite la migration de vos domaines gérés de http: vers https:. Dans l'exemple suivant,

Exemple

MDRequireHttps temporary

vous indiquez que vous désirez que pour l'instant, tout le trafic via des URLs en http: doit être redirigé vers des URLs en https:. Cette directive est sans risque et vous pouvez la désactiver à tout moment.

Ce qui suit par contre, a des conséquences : si vous souhaitez que les clients n'utilisent plus d'URLs en http:, spécifiez :

Permanent (pour au moins 6 mois !)

MDRequireHttps permanent

Cette directive a deux effets :

  1. Toutes les requêtes pour une ressource en http: sont redirigées vers la même requête en remplaçant le protocole http: par https: et en renvoyant le code d'état 301. Ce dernier indique aux clients que cette modification est permanente et qu'ils doivent mettre à jour leurs liens en conséquence.
  2. Toutes les réponses aux requêtes en https: comporteront l'en-tête Strict-Transport-Security avec une durée de vie de six mois. Cela indique au navigateur qu'il ne devra jamais utiliser http: (pendant six mois) lorsqu'il formulera une requête pour le domaine concerné. Avec cette information, les navigateurs refuseront de contacter votre site en mode non chiffré. Ceci interdit à des middlewares malicieux de dégrader les connexions et d'écouter/manipuler le trafic. C'est une bonne chose, mais cette configuration ne peut pas être désactivée aussi simplement que la configuration temporaire ci-dessus.

Vous pouvez obtenir le même résultat de manière simple avec mod_alias et une configuration basée sur la directive Redirect. Si vous le faites vous-même, assurez-vous d'exclure les chemins /.well-known/* de votre redirection, sinon mod_md aura des difficultés pour signer les nouveaux certificats.

Si vous effectuez cette configuration au niveau global, elle s'appliquera à tous les domaines gérés. Si vous souhaitez qu'elle ne s'applique qu'à un domaine spécifique, utilisez :

Exemple

<MDomain xxx.yyy>
  MDRequireHttps temporary
</MDomain>
top

Directive MDRetryDelay

Description:Temps d'attente avant de réessayer, doublé à chaque erreur consécutive
Syntaxe:MDRetryDelay duration
Défaut:MDRetryDelay 5s
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.54 du serveur HTTP Apache

Le temps d'attente après une erreur avant de tenter à nouveau le renouvellement d'un certificat. Ce temps est doublé après chaque erreur consécutive avec un maximum de 24 heures.

Ce temps d'attente est spécifique à chaque renouvellement de certificat. Autrement dit, une erreur sur un MDomain ne retarde pas les renouvellements des autres domaines.

top

Directive MDRetryFailover

Description:Le nombre d'erreurs avant de se tourner vers un autre CA
Syntaxe:MDRetryFailover number
Défaut:MDRetryFailover 13
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.54 du serveur HTTP Apache

Le nombre d'erreurs consécutives lors du renouvellement d'un certificat avant la sélection d'une autre CA. Ne s'applique qu'aux configurations pour lesquelles plusieurs MDCertificateAuthority ont été spécifiées.

top

Directive MDServerStatus

Description:Définit si les informations à propos des domaines gérés sont ajoutés ou non à server-status.
Syntaxe:MDServerStatus on|off
Défaut:MDServerStatus on
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Le gestionnaire d'Apache "server-status" vous permet de configurer une ressource pour monitorer le fonctionnement du serveur. Cette ressource inclut maintenant une section indiquant tous les domaines gérés avec leur nom DNS, l'état de renouvellement du certificat, la durée de vie de ce dernier, ainsi que d'autres propriétés fondamentales.

Cette directive permet d'activer/désactiver cette ressource.

top

Directive MDStapleOthers

Description:Active l'agrafage pour les certificats non gérés par mod_md.
Syntaxe:MDStapleOthers on|off
Défaut:MDStapleOthers on
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

Cette directive n'a d'effet que si MDStapling est activée. Elle permet de contrôler si mod_md doit aussi fournir les informations d'agrafage pour les certificats qu'il ne gère pas directement (autrement dit pour les certificats non renouvelés via le protocole ACME).

top

Directive MDStapling

Description:Active l'agrafage pour un ou plusieurs domaines.
Syntaxe:MDStapling on|off
Défaut:MDStapling off
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

mod_md permet l'obtention des informations d'agrafage OCSP. Cette fonctionnalité est une alternative à celle fournie par mod_ssl. Elle est désactivée par défaut à des fins de compatibilité ascendante.

La fonctionnalité peut être activée pour tous les certificats du serveur ou pour un MDomain seulement, ce qui aura pour effet de remplacer toute configuration d'agrafage au niveau de mod_ssl pour ce(s) domaine(s). Lorsqu'elle est désactivée, l'agrafage de mod_ssl se chargera du travail (s'il a été lui-même activé, bien entendu). Ceci permet de basculer de manière graduée d'une implémentation à l'autre.

L'agrafage fonctionne aussi pour les domaines non gérés par mod_md (voir à ce sujet la directive MDStapleOthers). En fait, l'agrafage OCSP peut très bien être utilisé en l'absence de tout certificat géré via le protocole ACME.

top

Directive MDStaplingKeepResponse

Description:Contrôle la durée au bout de laquelle les anciennes réponses doivent être supprimées.
Syntaxe:MDStaplingKeepResponse duration
Défaut:MDStaplingKeepResponse 7d
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

Cette directive permet de spécifier la durée au bout de laquelle les données OCSP utilisées pour l'agrafage doivent être supprimées du magasin. Par défaut, ces informations sont supprimées lors d'un restart/reload du serveur si elles ont plus de sept jours. Ceci permet de limiter la taille du magasin lorsque les certificats sont renouvelés et/ou reconfigurés fréquemment.

top

Directive MDStaplingRenewWindow

Description:Contrôle l'ancienneté des réponses OCSP au dela de laquelle ces dernières seront renouvelées.
Syntaxe:MDStaplingRenewWindow duration
Défaut:MDStaplingRenewWindow 33%
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

Si la durée de validité d'un réponse OCSP passe en dessous de duration, mod_md va tenter de la renouveler.

La CA à l'origine du certificat fournit aussi en général le service de réponse OCSP et détermine la durée de validité de sa réponse signée à propos de la validité du certificat. Plus longtemps une réponse sera valide, plus longtemps elle pourra être mise en cache, ce qui arrange tout le monde en matière de performances. Plus courte sera la validité d'une réponse, plus vite seront envoyées des révocations de certificats aux clients. Il est donc important de prendre en compte la qualité de service.

En ajustant la durée de validité des réponses vous-même, vous pouvez contrôler une partie du processus. Si vous spécifiez une durée de vie importante (autrement dit si vous spécifiez un petit pourcentage de validité avant que l'information n'expire), vous assurer un temps de mise en cache maximal, mais une interruption du service OCSP (par exemple un arrêt pour maintenance) aura plus de chance de vous affecter. Si vous spécifiez un pourcentage de temps avant expiration plus important, les mises à jour seront plus fréquentes, ce qui va augmenter la charge de l'infrastructure de serveurs du CA et nécessiter d'avantage de coordination entre les processus enfants de votre propre serveur.

La valeur par défaut choisie est de 33%, ce qui signifie que la demande de renouvellement interviendra lorsque la durée de vie de la réponse OCSP passera en dessous de 33%. Pour une CA qui fournit des réponses OCSP avec une durée de vie de 3 jours, cela implique 2 jours de mise en cache et 1 jour pour les tentatives de renouvellement. Pour affecter votre domaine, une interruption de service devra donc avoir une durée supérieure à 1 jour.

Vous pouvez aussi définir de manière absolue la durée de vie restante, par exemple `2d` pour 2 jours.

top

Directive MDStoreDir

Description:Chemin dans le système de fichiers local du répertoire où seront stockées les données à propos des domaines gérés.
Syntaxe:MDStoreDir path
Défaut:MDStoreDir md
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Cette directive permet de définir le répertoire dans le système de fichiers local où seront stockées les données à propos des domaines gérés. Il s'agit d'un chemin absolu ou relatif à la racine du serveur. Par défaut, le répertoire "md" sera créé à la racine de votre serveur.

Si vous souhaitez changer de répertoire et si ce dernier contient déjà des données, copiez tout d'abord les données vers le nouveau répertoire, puis modifier la configuration et redémarrez le serveur. Si vous commencez par modifier la configuration et redémarrer le serveur sans copier les données, ce dernier croira que les certificats sont absents et il tentera d'en obtenir de nouveaux.

top

Directive MDStoreLocks

Description:Configure le verrouillage du magasin pour les mises à jour
Syntaxe:MDStoreLocks on|off|duration
Défaut:MDStoreLocks off
Contexte:configuration globale
Statut:Expérimental
Module:mod_md
Compatibilité:Disponible à partir de la version 2.4.55 du serveur HTTP Apache

Définissez cette directive pour utiliser un fichier verrou au démarrage du serveur lorsque MDStoreDir est synchronisé avec la configuration du serveur et si les certificats renouvelés sont activés.

Le verrouillage a été implémenté pour les configurations de cluster où MDStoreDir appartient à un système de fichiers partagé. L'activation des certificats renouvelés sera alors protégée lorsque plusieurs noeuds du cluster sont redémarrés ou reconfigurés simultanément ; ceci à condition bien entendu que le système de fichiers partagé prenne en charge le verrouillage de fichier.

Le temps d'attente par défaut pour obtenir le verrou est de 5 secondes. Si le verrou ne peut pas être obtenu, une erreur est enregistrée dans le journal et le démarrage du serveur se poursuit ; de ce fait, un des noeuds du cluster pourra encore utiliser les anciens certificats par la suite.

Un délai d'attente plus long réduira cette probabilité, mais pourra aussi retarder les redémarrages et reconfigurations du serveur dans le cas où les verrous ne sont pas correctement gérés dans le système de fichiers sous-jacent. Un verrou ne doit être maintenu par une instance de httpd que pendant une courte durée.

top

Directive MDWarnWindow

Description:Définit la fenêtre de temps pendant laquelle vous serez informé de l'expiration prochaine d'un certificat.
Syntaxe:MDWarnWindow duration
Défaut:MDWarnWindow 10%
Contexte:configuration globale
Statut:Expérimental
Module:mod_md

Voir la directive MDRenewWindow pour une description de la méthode à employer pour spécifier cette durée.

Le module inspecte la durée de vie restante des certificats et invoque MDMessageCmd lorsqu'une de ces durées devient inférieure à la fenêtre de temps spécifiée. Si l'on conserve la valeur par défaut, cette durée correspond à 9 jours pour les certificats de Let's Encrypt.

Cette directive s'applique aussi aux domaines gérés via des fichiers de certificats statiques (voir la directive MDCertificateFile).

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_winnt.html.de0000664000175100017510000001776514744525602021124 0ustar covenercovener mpm_winnt - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Apache-MPM winnt

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

Diese Übersetzung ist möglicherweise nicht mehr aktuell. Bitte prüfen Sie die englische Version auf die neuesten Änderungen.
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.

Support Apache!

Direktiven

Bugfix checklist

Siehe auch

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

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ssl.html.fr.utf80000664000175100017510000063757715012110671021452 0ustar covenercovener mod_ssl - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_ssl

Langues Disponibles:  en  |  fr 

Description:Chiffrement de haut niveau basé sur les protocoles Secure Sockets Layer (SSL) et Transport Layer Security (TLS)
Statut:Extension
Identificateur de Module:ssl_module
Fichier Source:mod_ssl.c

Sommaire

Ce module fournit le support SSL v3 et TLS v1 au serveur HTTP Apache. SSL v2 n'est plus supporté.

Ce module s'appuie sur OpenSSL pour fournir le moteur de chiffrement.

D'autres détails, discussions et exemples sont fournis dans la documentation SSL.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Variables d'environnement

Ce module peut être configuré pour fournir aux espaces de nommage SSI et CGI de nombreux éléments d'informations concernant SSL par le biais de variables d'environnement supplémentaires. Par défaut, sauf pour HTTPS et SSL_TLS_SNI qui sont toujours définies, ces informations ne sont pas fournies pour des raisons de performances (Voir la directive SSLOptions StdEnvVars ci-dessous). Les variables générées se trouvent dans la table ci-dessous. Ces informations peuvent également être disponible sous des noms différents à des fins de compatibilité ascendante. Reportez-vous au chapitre Compatibilité pour plus de détails à propos des variables de compatibilité.

Nom de la variable Type de valeur Description
HTTPS drapeau HTTPS est utilisé.
SSL_PROTOCOL chaîne La version du protocole SSL (SSLv3, TLSv1, TLSv1.1, TLSv1.2)
SSL_SESSION_ID chaîne L'identifiant de session SSL codé en hexadécimal
SSL_SESSION_RESUMED chaîne Session SSL initiale ou reprise. Note : plusieurs requêtes peuvent être servies dans le cadre de la même session SSL (initiale ou reprise) si les connexions persistantes (HTTP KeepAlive) sont utilisées
SSL_SECURE_RENEG chaîne true si la renégociation sécurisée est supportée, false dans le cas contraire
SSL_CIPHER chaîne Le nom de l'algorithme de chiffrement
SSL_CIPHER_EXPORT chaîne true si l'algorithme de chiffrement est un algorithme exporté
SSL_CIPHER_USEKEYSIZE nombre Nombre de bits de chiffrement (réellement utilisés)
SSL_CIPHER_ALGKEYSIZE nombre Nombre de bits de chiffrement (possible)
SSL_COMPRESS_METHOD chaîne Méthode de compression SSL négociée
SSL_VERSION_INTERFACE chaîne La version du programme mod_ssl
SSL_VERSION_LIBRARY chaîne La version du programme OpenSSL
SSL_CLIENT_M_VERSION chaîne La version du certificat client
SSL_CLIENT_M_SERIAL chaîne Le numéro de série du certificat client
SSL_CLIENT_S_DN chaîne Le DN sujet du certificat client
SSL_CLIENT_S_DN_x509 chaîne Elément du DN sujet du client
SSL_CLIENT_SAN_Email_n chaîne Les entrées d'extension subjectAltName du certificat client de type rfc822Name
SSL_CLIENT_SAN_DNS_n chaîne Les entrées d'extension subjectAltName du certificat client de type dNSName
SSL_CLIENT_SAN_OTHER_msUPN_n chaîne Extensions subjectAltName de type otherName du certificat client, forme Microsoft du nom principal de l'utilisateur (OID 1.3.6.1.4.1.311.20.2.3)
SSL_CLIENT_I_DN chaîne DN de l'émetteur du certificat du client
SSL_CLIENT_I_DN_x509 chaîne Elément du DN de l'émetteur du certificat du client
SSL_CLIENT_V_START chaîne Validité du certificat du client (date de début)
SSL_CLIENT_V_END chaîne Validité du certificat du client (date de fin)
SSL_CLIENT_V_REMAIN chaîne Nombre de jours avant expiration du certificat du client
SSL_CLIENT_A_SIG chaîne Algorithme utilisé pour la signature du certificat du client
SSL_CLIENT_A_KEY chaîne Algorithme utilisé pour la clé publique du certificat du client
SSL_CLIENT_CERT chaîne Certificat du client au format PEM
SSL_CLIENT_CERT_CHAIN_n chaîne Certificats de la chaîne de certification du client au format PEM
SSL_CLIENT_CERT_RFC4523_CEA chaîne Numéro de série et fournisseur du certificat. le format correspond à celui de la CertificateExactAssertion dans la RFC4523
SSL_CLIENT_VERIFY chaîne NONE, SUCCESS, GENEROUS ou FAILED:raison
SSL_SERVER_M_VERSION chaîne La version du certificat du serveur
SSL_SERVER_M_SERIAL chaîne The serial of the server certificate
SSL_SERVER_S_DN chaîne DN sujet du certificat du serveur
SSL_SERVER_S_DN_x509 chaîne Elément du DN sujet du certificat du serveur
SSL_SERVER_SAN_Email_n chaîne Les entrées d'extension subjectAltName du certificat de serveur de type rfc822Name
SSL_SERVER_SAN_DNS_n chaîne Les entrées d'extension subjectAltName du certificat de serveur de type dNSName
SSL_SERVER_SAN_OTHER_dnsSRV_n chaîne Extensions subjectAltName de type otherName du certificat serveur, sous la forme SRVName (OID 1.3.6.1.5.5.7.8.7, RFC 4985)
SSL_SERVER_I_DN chaîne DN de l'émetteur du certificat du serveur
SSL_SERVER_I_DN_x509 chaîne Elément du DN de l'émetteur du certificat du serveur
SSL_SERVER_V_START chaîne Validité du certificat du serveur (date de dédut)
SSL_SERVER_V_END chaîne Validité du certificat du serveur (date de fin)
SSL_SERVER_A_SIG chaîne Algorithme utilisé pour la signature du certificat du serveur
SSL_SERVER_A_KEY chaîne Algorithme utilisé pour la clé publique du certificat du serveur
SSL_SERVER_CERT chaîne Certificat du serveur au format PEM
SSL_SRP_USER chaîne nom d'utilisateur SRP
SSL_SRP_USERINFO chaîne informations sur l'utilisateur SRP
SSL_TLS_SNI string Contenu de l'extension SNI TLS (si supporté par ClientHello)

x509 spécifie un élément de DN X.509 parmi C,ST,L,O,OU,CN,T,I,G,S,D,UID,Email. A partir de la version 2.2.0 d'Apache, x509 peut aussi comporter un suffixe numérique _n. Si le DN en question comporte plusieurs attributs de noms identiques, ce suffixe constitue un index débutant à zéro et permettant de sélectionner un attribut particulier. Par exemple, si le DN sujet du certificat du serveur comporte deux champs OU, on peut utiliser SSL_SERVER_S_DN_OU_0 et SSL_SERVER_S_DN_OU_1 pour référencer chacun d'entre eux. Un nom de variable sans suffixe _n est équivalent au même nom avec le suffixe _0, ce qui correspond au premier attribut (ou au seul) caractérisant le DN. Lorsque la table d'environnement est remplie en utilisant l'option StdEnvVars de la directive SSLOptions, le premier attribut (ou le seul) caractérisant le DN est enregistré avec un nom sans suffixe ; autrement dit, aucune entrée possédant comme suffixe _0 n'est enregistrée.

A partir de la version 2.4.32 de httpd, on peut ajouter le suffixe _RAW à x509 dans un composant DN afin d'empêcher la conversion de la valeur de l'attribut en UTF-8. Il doit être placé après le suffixe index (s'il existe). On utilisera par exemple SSL_SERVER_S_DN_OU_RAW ou SSL_SERVER_S_DN_OU_0_RAW.

Le format des variables *_DN a changé depuis la version 2.3.11 d'Apache HTTPD. Voir l'option LegacyDNStringFormat de la directive SSLOptions pour plus de détails.

SSL_CLIENT_V_REMAIN n'est disponible qu'à partir de la version 2.1.

Plusieurs variables d'environnement additionnelles peuvent être utilisées dans les expressions SSLRequire, ou dans les formats de journalisation personnalisés :

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
THE_REQUEST            SERVER_NAME           TIME_MIN
REQUEST_FILENAME       SERVER_PORT           TIME_SEC
REQUEST_METHOD         SERVER_PROTOCOL       TIME_WDAY
REQUEST_SCHEME         REMOTE_ADDR           TIME
REQUEST_URI            REMOTE_USER

Dans ces contextes, deux formats spéciaux peuvent aussi être utilisés :

ENV:nom_variable
Correspond à la variable d'environnement standard nom_variable.
HTTP:nom_en-tête
Correspond à la valeur de l'en-tête de requête dont le nom est nom_en-tête.
top

Formats de journaux personnalisés

Lorsque mod_ssl est compilé dans le serveur Apache ou même chargé (en mode DSO), des fonctions supplémentaires sont disponibles pour le Format de journal personnalisé du module mod_log_config. A ce titre, la fonction de format d'eXtension ``%{nom-var}x'' peut être utilisée pour présenter en extension toute variable fournie par tout module, et en particulier celles fournies par mod_ssl et que vous trouverez dans la table ci-dessus.

A des fins de compatibilité ascendante, il existe une fonction de format cryptographique supplémentaire ``%{nom}c''. Vous trouverez toutes les informations à propos de cette fonction dans le chapitre Compatibilité.

Exemple

CustomLog "logs/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

Ces formats sont disponibles même si l'option StdEnvVars de la directive SSLOptions n'a pas été définie.

top

Information à propos de la requête

mod_ssl enregistre des informations à propos de la requête que l'on peut restituer dans les journaux avec la chaîne de format %{nom}n via le module mod_log_config.

Les informations enregistrées sont les suivantes :

ssl-access-forbidden
Cette information contient la valeur 1 si l'accès a été refusé suite à une directive SSLRequire ou SSLRequireSSL.
ssl-secure-reneg
Si mod_ssl a été compilé avec une version d'OpenSSL qui supporte la renégociation sécurisée, si SSL est utilisé pour la connexion courante et si le client supporte lui aussi la renégociation sécurisée, cette information contiendra la valeur 1. Si le client ne supporte pas la renégociation sécurisée, l'information contiendra la valeur 0. Si mod_ssl n'a pas été compilé avec une version d'OpenSSL qui supporte la renégociation sécurisée, ou si SSL n'est pas utilisé pour la connexion courante, le contenu de l'information ne sera pas défini.
top

Extension pour l'interprétation des expressions

Lorsque mod_ssl est compilé statiquement avec Apache, ou même chargé dynamiquement (en tant que module DSO), toute variable en provenance de mod_ssl peut être utilisée pour l'interprétation des expression ap_expr. Les variables peuvent être référencées en utilisant la syntaxe ``%{varname}''. A partir de la version 2.4.18, on peut aussi utiliser la syntaxe de style mod_rewrite ``%{SSL:varname}'', ou la syntaxe de style fonction ``ssl(varname)''.

Exemple (en utilisant mod_headers)

Header set X-SSL-PROTOCOL "expr=%{SSL_PROTOCOL}"
Header set X-SSL-CIPHER "expr=%{SSL:SSL_CIPHER}"

Cette fonctionnalité est disponible même si l'option StdEnvVars de la directive SSLOptions n'a pas été définie.

top

Fournisseurs d'autorisation disponibles avec Require

mod_ssl propose quelques fournisseurs d'autorisation à utiliser avec la directive Require du module mod_authz_core.

Require ssl

Le fournisseur ssl refuse l'accès si une connexion n'est pas chiffrée avec SSL. L'effet est similaire à celui de la directive SSLRequireSSL.

Require ssl

Require ssl-verify-client

Le fournisseur ssl autorise l'accès si l'utilisateur est authentifié via un certificat client valide. Ceci n'a un effet que si SSLVerifyClient optional est actif.

Dans l'exemple suivant, l'accès est autorisé si le client est authentifié via un certificat client ou par nom d'utilisateur/mot de passe :

Require ssl-verify-client
Require valid-user
top

Directive SSLCACertificateFile

Description:Fichier contenant une concaténation des certificats de CA codés en PEM pour l'authentification des clients
Syntaxe:SSLCACertificateFile file-path
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive permet de définir le fichier tout-en-un où vous pouvez rassembler les certificats des Autorités de Certification (CAs) pour les clients auxquels vous avez à faire. On les utilise pour l'authentification des clients. Un tel fichier contient la simple concaténation des différents fichiers de certificats codés en PEM, par ordre de préférence. Cette directive peut être utilisée à la place et/ou en complément de la directive SSLCACertificatePath.

Exemple

SSLCACertificateFile "/usr/local/apache2/conf/ssl.crt/ca-bundle-client.crt"
top

Directive SSLCACertificatePath

Description:Répertoire des certificats de CA codés en PEM pour l'authentification des clients
Syntaxe:SSLCACertificatePath chemin-répertoire
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive permet de définir le répertoire où sont stockés les certificats des Autorités de Certification (CAs) pour les clients auxquels vous avez à faire. On les utilise pour vérifier le certificat du client au cours de l'authentification de ce dernier.

Les fichiers de ce répertoire doivent être codés en PEM et ils sont accédés via des noms de fichier sous forme de condensés ou hash. Il ne suffit donc pas de placer les fichiers de certificats dans ce répertoire : vous devez aussi créer des liens symboliques nommés valeur-de-hashage.N, et vous devez toujours vous assurer que ce répertoire contient les liens symboliques appropriés.

Exemple

SSLCACertificatePath "/usr/local/apache2/conf/ssl.crt/"
top

Directive SSLCADNRequestFile

Description:Fichier contenant la concaténation des certificats de CA codés en PEM pour la définition de noms de CA acceptables
Syntaxe:SSLCADNRequestFile file-path
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Lorsque mod_ssl demande un certificat client, une liste de noms d'Autorités de Certification acceptables est envoyée au client au cours de la phase d'initialisation de la connexion SSL. Le client peut alors utiliser cette liste de noms de CA pour sélectionner un certificat client approprié parmi ceux dont il dispose.

Si aucune des directives SSLCADNRequestPath ou SSLCADNRequestFile n'est définie, la liste de noms de CsA acceptables envoyée au client est la liste des noms de tous les certificats de CA spécifiés par les directives SSLCACertificateFile et SSLCACertificatePath ; en d'autres termes, c'est la liste des noms de CAs qui sera effectivement utilisée pour vérifier le certificat du client.

Dans certaines situations, il est utile de pouvoir envoyer une liste de noms de CA acceptables qui diffère de la liste des CAs effectivement utilisés pour vérifier le certificat du client ; considérons par exemple le cas où le certificat du client est signé par des CAs intermédiaires. On peut ici utiliser les directives SSLCADNRequestPath et/ou SSLCADNRequestFile, et les noms de CA acceptables seront alors extraits de l'ensemble des certificats contenus dans le répertoire et/ou le fichier définis par cette paire de directives.

SSLCADNRequestFile doit spécifier un fichier tout-en-un contenant une concaténation des certificats de CA codés en PEM.

Exemple

SSLCADNRequestFile "/usr/local/apache2/conf/ca-names.crt"
top

Directive SSLCADNRequestPath

Description:Répertoire contenant des fichiers de certificats de CA codés en PEM pour la définition de noms de CA acceptables
Syntaxe:SSLCADNRequestPath chemin-répertoire
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive optionnelle permet de définir la liste de noms de CAs acceptables qui sera envoyée au client lorsqu'un certificat de client est demandé. Voir la directive SSLCADNRequestFile pour plus de détails.

Les fichiers de ce répertoire doivent être codés en PEM et ils sont accédés via des noms de fichier sous forme de condensés ou hash. Il ne suffit donc pas de placer les fichiers de certificats dans ce répertoire : vous devez aussi créer des liens symboliques nommés valeur-de-hashage.N, et vous devez toujours vous assurer que ce répertoire contient les liens symboliques appropriés.

Exemple

SSLCADNRequestPath "/usr/local/apache2/conf/ca-names.crt/"
top

Directive SSLCARevocationCheck

Description:Active la vérification des révocations basée sur les CRL
Syntaxe:SSLCARevocationCheck chain|leaf|none [flags ...]
Défaut:SSLCARevocationCheck none
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Le drapeau optionnel flags est disponible à partir de la version 2.4.21 du serveur HTTP Apache

Active la vérification des révocations basée sur les Listes de Révocations de Certificats (CRL). Au moins une des directives SSLCARevocationFile ou SSLCARevocationPath doit être définie. Lorsque cette directive est définie à chain (valeur recommandée), les vérifications CRL sont effectuées sur tous les certificats de la chaîne, alors que la valeur leaf limite la vérification au certificat hors chaîne (la feuille).

flags peut prendre comme valeurs

Exemple

SSLCARevocationCheck chain

Compatibilité avec la branche 2.2

SSLCARevocationCheck chain no_crl_for_cert_ok
top

Directive SSLCARevocationFile

Description:Fichier contenant la concaténation des CRLs des CA codés en PEM pour l'authentification des clients
Syntaxe:SSLCARevocationFile file-path
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive permet de définir le fichier tout-en-un où sont rassemblées les Listes de Révocation de Certificats (CRLs) des Autorités de certification (CAs) pour les clients auxquels vous avez à faire. On les utilise pour l'authentification des clients. Un tel fichier contient la simple concaténation des différents fichiers de CRLs codés en PEM, dans l'ordre de préférence. Cette directive peut être utilisée à la place et/ou en complément de la directive SSLCARevocationPath.

Exemple

SSLCARevocationFile
"/usr/local/apache2/conf/ssl.crl/ca-bundle-client.crl"
top

Directive SSLCARevocationPath

Description:Répertoire des CRLs de CA codés en PEM pour l'authentification des clients
Syntaxe:SSLCARevocationPath chemin-répertoire
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive permet de définir le répertoire où sont stockées les Listes de Révocation de Certificats (CRL) des Autorités de Certification (CAs) pour les clients auxquels vous avez à faire. On les utilise pour révoquer les certificats des clients au cours de l'authentification de ces derniers.

Les fichiers de ce répertoire doivent être codés en PEM et ils sont accédés via des noms de fichier sous forme de condensés ou hash. Il ne suffit donc pas de placer les fichiers de CRL dans ce répertoire : vous devez aussi créer des liens symboliques nommés valeur-de-hashage.N, et vous devez toujours vous assurer que ce répertoire contient les liens symboliques appropriés.

Exemple

SSLCARevocationPath "/usr/local/apache2/conf/ssl.crl/"
top

Directive SSLCertificateChainFile

Description:Fichier contenant les certificats de CA du serveur codés en PEM
Syntaxe:SSLCertificateChainFile file-path
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

SSLCertificateChainFile est obsolète

SSLCertificateChainFile est devenue obsolète avec la version 2.4.8, lorsque la directive SSLCertificateFile a été étendue pour supporter aussi les certificats de CA intermédiaires dans le fichier de certificats du serveur.

Cette directive permet de définir le fichier optionnel tout-en-un où vous pouvez rassembler les certificats des Autorités de Certification (CA) qui forment la chaîne de certification du certificat du serveur. Cette chaîne débute par le certificat de la CA qui a délivré le certificat du serveur et peut remonter jusqu'au certificat de la CA racine. Un tel fichier contient la simple concaténation des différents certificats de CA codés en PEM, en général dans l'ordre de la chaîne de certification.

Elle doit être utilisée à la place et/ou en complément de la directive SSLCACertificatePath pour construire explicitement la chaîne de certification du serveur qui est envoyée au navigateur en plus du certificat du serveur. Elle s'avère particulièrement utile pour éviter les conflits avec les certificats de CA lorsqu'on utilise l'authentification du client. Comme le fait de placer un certificat de CA de la chaîne de certification du serveur dans la directive SSLCACertificatePath produit le même effet pour la construction de la chaîne de certification, cette directive a pour effet colatéral de faire accepter les certificats clients fournis par cette même CA, au cours de l'authentification du client.

Soyez cependant prudent : fournir la chaîne de certification ne fonctionne que si vous utilisez un simple certificat de serveur RSA ou DSA. Si vous utilisez une paire de certificats couplés RSA+DSA , cela ne fonctionnera que si les deux certificats utilisent vraiment la même chaîne de certification. Dans le cas contraire, la confusion risque de s'installer au niveau des navigateurs.

Exemple

SSLCertificateChainFile "/usr/local/apache2/conf/ssl.crt/ca.crt"
top

Directive SSLCertificateFile

Description:Fichier de données contenant les informations de certificat X.509 du serveur codées au format PEM ou identificateur de jeton
Syntaxe:SSLCertificateFile file-path|certid
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:L'option certid est disponible à partir de la version 2.4.42 du serveur HTTP Apache.

Cette directive permet de définir le fichier de données contenant les informations de certificat X.509 du serveur codées au format PEM ou l'identificateur de certificat via un jeton cryptographique. Si on utilise un fichier au format PEM, ce dernier doit contenir au minimum un certificat d'entité finale (feuille). La directive peut être utilisée plusieurs fois (elle référence des fichiers différents) pour accepter plusieurs algorithmes d'authentification au niveau du serveur - souvent RSA, DSA et ECC. Le nombre d'algorithmes supportés dépend de la version d'OpenSSL utilisée avec mod_ssl : à partir de la version 1.0.0, la commande openssl list-public-key-algorithms affiche la liste des algorithmes supportés. Voir aussi la note ci-dessous à propos des limitations des versions d'OpenSSL antérieures à 1.0.2 et la manière de les contourner.

Les fichiers peuvent aussi contenir des certificats de CA intermédiaires triés depuis la feuille vers la racine. Cette fonctionnalité est disponible depuis la version 2.4.8 du serveur HTTP Apache, et rend obsolète la directive SSLCertificateChainFile. A partir de la version 1.0.2 d'OpenSSL, il est alors possible de configurer la chaîne de certification en fonction du certificat.

Depuis la version 2.4.7 du serveur HTTP Apache, on peut aussi ajouter des paramètres DH personnalisés et un nom EC curve pour les clés éphémères à la fin du premier fichier défini par la directive SSLCertificateFile. Ces paramètres peuvent être générés avec les commandes openssl dhparam et openssl ecparam, et ils peuvent être ajoutés tel quel à la fin du premier fichier de certificat. En effet, seul le premier fichier de certificat défini peut être utilisé pour enregistrer des paramètres personnalisés, car ces derniers s'appliquent indépendamment de l'algorithme d'authentification utilisé.

Enfin, il est aussi possible d'ajouter la clé privée du certificat de l'entité finale au fichier de certificat, ce qui permet de se passer d'une directive SSLCertificateKeyFile séparée. Cette pratique est cependant fortement déconseillée. Dans ce cas, les fichiers de certificat qui contiennent de telles clés embarquées doivent être définis après les certificats qui utilisent un fichier de clé séparé. En outre, si la clé est chiffrée, une boîte de dialogue pour entrer le mot de passe de la clé s'ouvre au démarrage du serveur.

Plutôt que de stocker les certificats et les clés privées dans des fichiers, on peut utiliser un identificateur de certificat pour identifier un certificat stocké dans un jeton. Actuellement, seuls les URIs PKCS#11 sont reconnus comme identificateurs de certificats et peuvent être utilisés en conjonction avec le moteur ou le fournisseur OpenSSL pkcs11. Si la directive SSLCertificateKeyFile est absente, le certificat et la clé privée peuvent être chargés avec l'identificateur spécifié via la directive SSLCertificateFile.

Interopérabilité des paramètres DH avec les nombres premiers de plus de 1024 bits

Depuis la version 2.4.7, mod_ssl utilise des paramètres DH standardisés avec des nombres premiers de 2048, 3072 et 4096 bits, et avec des nombres premiers de 6144 et 8192 bits depuis la version 2.4.10 (voir RFC 3526), et les fournit aux clients en fonction de la longueur de la clé du certificat RSA/DSA. En particulier avec les clients basés sur Java (versions 7 et antérieures), ceci peut provoquer des erreurs au cours de la négociation - voir cette réponse de la FAQ SSL pour contourner les problèmes de ce genre.

Paramètres DH par défaut lorsqu'on utilise plusieurs certificats et une version d'OpenSSL antérieure à 1.0.2.

Lorsqu'on utilise plusieurs certificats pour supporter différents algorithmes d'authentification (comme RSA, DSA, mais principalement ECC) et une version d'OpenSSL antérieure à 1.0.2, il est recommandé soit d'utiliser des paramètres DH spécifiques (solution à privilégier) en les ajoutant au premier fichier certificat (comme décrit ci-dessus), soit d'ordonner les directives SSLCertificateFile de façon à ce que les certificats RSA/DSA soit placés après les certificats ECC.

Cette limitation est présente dans les anciennes versions d'OpenSSL qui présentent toujours le dernier certificat configuré, au lieu de laisser le serveur HTTP Apache déterminer le certificat sélectionné lors de la phase de négociation de la connexion (lorsque les paramètres DH doivent être envoyés à l'hôte distant). De ce fait, le serveur peut sélectionner des paramètres DH par défaut basés sur la longueur de la clé du mauvais certificat (les clés ECC sont beaucoup plus petites que les clés RSA/DSA et leur longueur n'est pas pertinente pour la sélection des nombres premiers DH).

Ce problème peut être résolu en créant et configurant des paramètres DH spécifiques (comme décrit ci-dessus), car ils l'emportent toujours sur les paramètres DH par défaut, et vous pourrez ainsi utiliser une longueur spécifique et appropriée.

Exemple

# Exemple utilisant un fichier codé en PEM.
SSLCertificateFile "/usr/local/apache2/conf/ssl.crt/server.crt"
# Exemple d'utilisation d'un certificat et d'une clé privés issus d'un jeton
# PKCS#11 :
SSLCertificateFile "pkcs11:token=My%20Token%20Name;id=45"
top

Directive SSLCertificateKeyFile

Description:Fichier contenant la clé privée du serveur codée en PEM
Syntaxe:SSLCertificateKeyFile file-path|keyid
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:keyid est disponible à partir de la version 2.4.42 du serveur HTTP Apache.

Cette directive permet de définir le fichier contenant la clé privée du serveur codée en PEM ou l'identifiant de la clé via un jeton cryptographique défini. Si la clé privée est chiffrée, une boîte de dialogue demandant le mot de passe de cette dernière s'ouvre au démarrage du serveur.

Cette directive peut être utilisée plusieurs fois pour référencer différents noms de fichiers, afin de supporter plusieurs algorithmes pour l'authentification du serveur. A chaque directive SSLCertificateKeyFile doit être associée une directive SSLCertificateFile correspondante.

La clé privée peut aussi être ajoutée au fichier défini par la directive SSLCertificateFile, mais cette pratique est fortement déconseillée. Dans ce cas, les fichiers de certificats qui comportent une telle clé doivent être définis après les certificats qui utilisent un fichier de clé séparé.

Plutôt que de stocker des clés privées dans des fichiers, il est possible d'identifier une clé privée via un identifiant stocké dans un jeton. Actuellement, seuls les PKCS#11 URIs sont reconnus comme identifiants de clés privées et peuvent être utilisés en conjonction avec le moteur ou le fournisseur OpenSSL pkcs11.

Exemple

# Pour utiliser une clé privée stockée dans fichier encodé PEM :
SSLCertificateKeyFile "/usr/local/apache2/conf/ssl.key/server.key"
# Pour utiliser une clé privée à partir d'un jeton PKCS#11 :
SSLCertificateKeyFile "pkcs11:token=My%20Token%20Name;id=45"
top

Directive SSLCipherSuite

Description:Algorithmes de chiffrement disponibles pour la négociation au cours de l'initialisation de la connexion SSL
Syntaxe:SSLCipherSuite [protocol] cipher-spec
Défaut:SSLCipherSuite DEFAULT (dépend de la version d'OpenSSL installée)
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ssl

Cette directive complexe utilise la chaîne cipher-spec contenant la liste des algorithmes de chiffrement OpenSSL que le client peut utiliser au cours de la phase d'initialisation de la connexion SSL. La spécification optionnelle du protocole permet de configurer la suite d'algorithmes de chiffrement pour une version spécifique de SSL. Une des valeurs possibles est "SSL" pour toutes les versions du protocole SSL jusqu'à TLSv1.2 compris.

Notez que cette directive peut être utilisée aussi bien dans un contexte de serveur que dans un contexte de répertoire. Dans un contexte de serveur, elle s'applique à l'initialisation SSL standard lorsqu'une connexion est établie. Dans un contexte de répertoire, elle force une renégociation SSL avec la liste d'algorithmes de chiffrement spécifiée après la lecture d'une requête HTTP, mais avant l'envoi de la réponse HTTP.

Si la bibliothèque SSL supporte TLSv1.3 (versions d'OpenSSL 1.1.1 et supérieures), il est possible de spécifier le paramètre "TLSv1.3" pour configurer la suite d'algorithmes de chiffrement pour ce protocole. Comme TLSv1.3 n'autorise pas la renégociation, spécifier pour lui des algorithmes de chiffrement dans un contexte de répertoire n'est pas autorisé

Pour obtenir la liste des noms d'algorithmes de chiffrement pour TLSv1.3, se référer à la documentation OpenSSL.

La liste d'algorithmes de chiffrement SSL spécifiée par l'argument cipher-spec comporte quatre attributs principaux auxquels s'ajoutent quelques attributs secondaires :

L'algorithme de chiffrement peut aussi provenir de l'extérieur. Les algorithmes SSLv2 ne sont plus supportés. Pour définir les algorithmes à utiliser, on peut soit spécifier tous les algorithmes à la fois, soit utiliser des alias pour spécifier une liste d'algorithmes dans leur ordre de préférence (voir Table 1). Les algorithmes et alias effectivement disponibles dépendent de la version d'openssl utilisée. Les versions ultérieures d'openssl sont susceptibles d'inclure des algorithmes supplémentaires.

Symbole Description
Algorithme d'échange de clés :
kRSA Echange de clés RSA
kDHr Echange de clés Diffie-Hellman avec clé RSA
kDHd Echange de clés Diffie-Hellman avec clé DSA
kEDH Echange de clés Diffie-Hellman temporaires (pas de certificat)
kSRP échange de clés avec mot de passe distant sécurisé (SRP)
Algorithmes d'authentification :
aNULL Pas d'authentification
aRSA Authentification RSA
aDSS Authentification DSS
aDH Authentification Diffie-Hellman
Algorithmes de chiffrement :
eNULL Pas de chiffrement
NULL alias pour eNULL
AES Chiffrement AES
DES Chiffrement DES
3DES Chiffrement Triple-DES
RC4 Chiffrement RC4
RC2 Chiffrement RC2
IDEA Chiffrement IDEA
Algorithmes de condensés MAC :
MD5 Fonction de hashage MD5
SHA1 Fonction de hashage SHA1
SHA alias pour SHA1
SHA256 Fonction de hashage SHA256
SHA384 Fonction de hashage SHA384
Alias :
SSLv3 tous les algorithmes de chiffrement SSL version 3.0
TLSv1 tous les algorithmes de chiffrement TLS version 1.0
EXP tous les algorithmes de chiffrement externes
EXPORT40 tous les algorithmes de chiffrement externes limités à 40 bits
EXPORT56 tous les algorithmes de chiffrement externes limités à 56 bits
LOW tous les algorithmes de chiffrement faibles (non externes, DES simple)
MEDIUM tous les algorithmes avec chiffrement 128 bits
HIGH tous les algorithmes utilisant Triple-DES
RSA tous les algorithmes utilisant l'échange de clés RSA
DH tous les algorithmes utilisant l'échange de clés Diffie-Hellman
EDH tous les algorithmes utilisant l'échange de clés Diffie-Hellman temporaires
ECDH Echange de clés Elliptic Curve Diffie-Hellman
ADH tous les algorithmes utilisant l'échange de clés Diffie-Hellman anonymes
AECDH tous les algorithmes utilisant l'échange de clés Elliptic Curve Diffie-Hellman
SRP tous les algorithmes utilisant l'échange de clés avec mot de passe distant sécurisé (SRP)
DSS tous les algorithmes utilisant l'authentification DSS
ECDSA tous les algorithmes utilisant l'authentification ECDSA
aNULL tous les algorithmes n'utilisant aucune authentification

Cela devient intéressant lorsque tous ces symboles sont combinés ensemble pour spécifier les algorithmes disponibles et l'ordre dans lequel vous voulez les utiliser. Pour simplifier tout cela, vous disposez aussi d'alias (SSLv3, TLSv1, EXP, LOW, MEDIUM, HIGH) pour certains groupes d'algorithmes. Ces symboles peuvent être reliés par des préfixes pour former la chaîne algorithmes. Les préfixes disponibles sont :

Les algorithmes aNULL, eNULL et EXP sont toujours désactivés

Depuis la version 2.4.7, les algorithmes de type null ou destinés à l'exportation sont toujours désactivés car mod_ssl ajoute obligatoirement !aNULL:!eNULL:!EXP à toute chaîne d'algorithme de chiffrement à l'initialisation.

Pour vous simplifier la vie, vous pouvez utiliser la commande ``openssl ciphers -v'' qui vous fournit un moyen simple de créer la chaîne algorithmes avec succès. La chaîne algorithmes par défaut dépend de la version des bibliothèques SSL installées. Supposons qu'elle contienne ``RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5'', ce qui stipule de mettre RC4-SHA et AES128-SHA en premiers, car ces algorithmes présentent un bon compromis entre vitesse et sécurité. Viennent ensuite les algorithmes de sécurité élevée et moyenne. En fin de compte, les algorithmes qui n'offrent aucune authentification sont exclus, comme les algorithmes anonymes Diffie-Hellman pour SSL, ainsi que tous les algorithmes qui utilisent MD5 pour le hashage, car celui-ci est reconnu comme insuffisant.

$ openssl ciphers -v 'RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5'
RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
...                     ...               ...     ...           ...
SEED-SHA                SSLv3 Kx=RSA      Au=RSA  Enc=SEED(128) Mac=SHA1
PSK-RC4-SHA             SSLv3 Kx=PSK      Au=PSK  Enc=RC4(128)  Mac=SHA1
KRB5-RC4-SHA            SSLv3 Kx=KRB5     Au=KRB5 Enc=RC4(128)  Mac=SHA1

Vous trouverez la liste complète des algorithmes RSA & DH spécifiques à SSL dans la Table 2.

Exemple

SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW
Symbole algorithme Protocole Echange de clés Authentification Chiffrement Condensé MAC Type
Algorithmes RSA :
DES-CBC3-SHA SSLv3 RSA RSA 3DES(168) SHA1
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
DES-CBC-SHA SSLv3 RSA RSA DES(56) SHA1
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
NULL-SHA SSLv3 RSA RSA None SHA1
NULL-MD5 SSLv3 RSA RSA None MD5
Algorithmes Diffie-Hellman :
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

Directive SSLCompression

Description:Permet d'activer la compression au niveau SSL
Syntaxe:SSLCompression on|off
Défaut:SSLCompression off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible à partir de la version 2.4.3 du serveur HTTP Apache, si on utilise une version d'OpenSSL 0.9.8 ou supérieure ; l'utilisation dans un contexte de serveur virtuel n'est disponible que si on utilise une version d'OpenSSL 1.0.0 ou supérieure. La valeur par défaut était on dans la version 2.4.3.

Cette directive permet d'activer la compression au niveau SSL.

L'activation de la compression est à l'origine de problèmes de sécurité dans la plupart des configurations (l'attaque nommée CRIME).

top

Directive SSLCryptoDevice

Description:Active l'utilisation d'un accélérateur matériel de chiffrement
Syntaxe:SSLCryptoDevice moteur
Défaut:SSLCryptoDevice builtin
Contexte:configuration globale
Statut:Extension
Module:mod_ssl

Cette directive permet d'activer l'utilisation d'une carte accélératrice de chiffrement qui prendra en compte certaines parties du traitement relatif à SSL. Cette directive n'est utilisable que si la boîte à outils SSL à été compilée avec le support "engine" ; les versions 0.9.7 et supérieures d'OpenSSL possèdent par défaut le support "engine", alors qu'avec la version 0.9.6, il faut utiliser les distributions séparées "-engine".

Pour déterminer les moteurs supportés, exécutez la commande "openssl engine".

Exemple

# Pour un accélérateur Broadcom :
SSLCryptoDevice ubsec

À partir de la version 3.0 d'OpenSSL, si aucun moteur n'est spécifié alors que la clé ou le certificat sont spécifiés à l'aide d'URIs PKCS#11, le chargement de la clé et du certificat est tenté à partir d'un fournisseur OpenSSL. Le fournisseur OpenSSL à utiliser doit être défini et configuré dans le fichier de configuration d'OpenSSL et il doit prendre en charge la méthode STORE pour les URIs PKCS#11.

top

Directive SSLEngine

Description:Interrupteur marche/arrêt du moteur SSL
Syntaxe:SSLEngine on|off|optional
Défaut:SSLEngine off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive permet d'activer/désactiver le moteur du protocole SSL/TLS. Elle doit être utilisée dans une section <VirtualHost> pour activer SSL/TLS pour ce serveur virtuel particulier. Par défaut, le moteur du protocole SSL/TLS est désactivé pour le serveur principal et tous les serveurs virtuels configurés.

Exemple

<VirtualHost _default_:443>
SSLEngine on
#...
</VirtualHost>

Depuis la version 2.1 d'Apache, la directive SSLEngine peut être définie à optional, ce qui active le support de RFC 2817, Upgrading to TLS Within HTTP/1.1. Pour le moment, aucun navigateur web ne supporte RFC 2817.

top

Directive SSLFIPS

Description:Coimmutateur du mode SSL FIPS
Syntaxe:SSLFIPS on|off
Défaut:SSLFIPS off
Contexte:configuration globale
Statut:Extension
Module:mod_ssl

Cette directive permet d'activer/désactiver l'utilisation du drapeau FIPS_mode de la bibliothèque SSL. Elle doit être définie dans le contexte du serveur principal, et n'accepte pas les configurations sources de conflits (SSLFIPS on suivi de SSLFIPS off par exemple). Le mode s'applique à toutes les opérations de la bibliothèque SSL.

Si httpd a été compilé avec une bibliothèque SSL qui ne supporte pas le drapeau FIPS_mode, la directive SSLFIPS on échouera. Reportez-vous au document sur la politique de sécurité FIPS 140-2 de la bibliothèque du fournisseur SSL, pour les prérequis spécifiques nécessaires à l'utilisation de mod_ssl selon un mode d'opération approuvé par FIPS 140-2 ; notez que mod_ssl en lui-même n'est pas validé, mais peut être décrit comme utilisant un module de chiffrement validé par FIPS 140-2, lorsque tous les composants sont assemblés et mis en oeuvre selon les recommandations de la politique de sécurité applicable.

top

Directive SSLHonorCipherOrder

Description:Option permettant de classer les algorithmes de chiffrement du serveur par ordre de préférence
Syntaxe:SSLHonorCipherOrder on|off
Défaut:SSLHonorCipherOrder off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Normalement, ce sont les préférences du client qui sont prises en compte lors du choix d'un algorithme de chiffrement au cours d'une négociation SSLv3 ou TLSv1. Si cette directive est activée, ce sont les préférences du serveur qui seront prises en compte à la place.

Exemple

SSLHonorCipherOrder on
top

Directive SSLInsecureRenegotiation

Description:Option permettant d'activer le support de la renégociation non sécurisée
Syntaxe:SSLInsecureRenegotiation on|off
Défaut:SSLInsecureRenegotiation off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible depuis httpd 2.2.15, si une version 0.9.8m ou supérieure d'OpenSSL est utilisée

Comme il a été spécifié, toutes les versions des protocoles SSL et TLS (jusqu'à la version 1.2 de TLS incluse) étaient vulnérables à une attaque de type Man-in-the-Middle (CVE-2009-3555) au cours d'une renégociation. Cette vulnérabilité permettait à un attaquant de préfixer la requête HTTP (telle qu'elle était vue du serveur) avec un texte choisi. Une extension du protocole a été développée pour corriger cette vulnérabilité, sous réserve qu'elle soit supportée par le client et le serveur.

Si mod_ssl est lié à une version 0.9.8m ou supérieure d'OpenSSL, par défaut, la renégociation n'est accordée qu'aux clients qui supportent la nouvelle extension du protocole. Si cette directive est activée, la renégociation sera accordée aux anciens clients (non patchés), quoique de manière non sécurisée

Avertissement à propos de la sécurité

Si cette directive est activée, les connexions SSL seront vulnérables aux attaques de type préfixe Man-in-the-Middle comme décrit dans CVE-2009-3555.

Exemple

SSLInsecureRenegotiation on

La variable d'environnement SSL_SECURE_RENEG peut être utilisée dans un script SSI ou CGI pour déterminer si la renégociation sécurisée est supportée pour une connexion SSL donnée.

top

Directive SSLOCSPDefaultResponder

Description:Définit l'URI du répondeur par défaut pour la validation OCSP
Syntaxe:SSLOCSPDefaultResponder uri
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive permet de définir le répondeur OCSP par défaut. Si la directive SSLOCSPOverrideResponder n'est pas activée, l'URI spécifié ne sera utilisé que si aucun URI de répondeur n'est spécifié dans le certificat en cours de vérification.

top

Directive SSLOCSPEnable

Description:Active la validation OCSP de la chaîne de certificats du client
Syntaxe:SSLOCSPEnable on|leaf|off
Défaut:SSLOCSPEnable off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Le mode leaf est disponible à partir de la version 2.4.34 du serveur HTTP Apache

Cette directive permet d'activer la validation OCSP de la chaîne de certificats du client. Si elle est activée, les certificats de la chaîne de certificats du client seront validés auprès d'un répondeur OCSP, une fois la vérification normale effectuée (vérification des CRLs incluse). En mode 'leaf', seul le certificat du client sera validé.

Le répondeur OCSP utilisé est soit extrait du certificat lui-même, soit spécifié dans la configuration ; voir les directives SSLOCSPDefaultResponder et SSLOCSPOverrideResponder.

Exemple

SSLVerifyClient on
SSLOCSPEnable on
SSLOCSPDefaultResponder "http://responder.example.com:8888/responder"
SSLOCSPOverrideResponder on
top

Directive SSLOCSPNoverify

Description:Evite la vérification des certificats des répondeurs OCSP
Syntaxe:SSLOCSPNoverify on|off
Défaut:SSLOCSPNoverify off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible à partir de la version 2.4.26 du serveur HTTP Apache, sous réserve d'utiliser une version 0.9.7 ou supérieure d'OpenSSL

Cette directive permet d'éviter la vérification des certificats des répondeurs OCSP, ce qui peut s'avérer utile lorsqu'on teste un serveur OCSP.

top

Directive SSLOCSPOverrideResponder

Description:Force l'utilisation de l'URI du répondeur par défaut pour la validation OCSP
Syntaxe:SSLOCSPOverrideResponder on|off
Défaut:SSLOCSPOverrideResponder off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Force l'utilisation, au cours d'une validation OCSP de certificat, du répondeur OCSP par défaut spécifié dans la configuration, que le certificat en cours de vérification fasse mention d'un répondeur OCSP ou non.

top

Directive SSLOCSPProxyURL

Description:Adresse de mandataire à utiliser pour les requêtes OCSP
Syntaxe:SSLOCSPProxyURL url
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible à partir de la version 2.4.19 du serveur HTTP Apache

Cette directive permet de définir l'URL d'un mandataire HTTP qui devra être utilisé pour toutes les requêtes vers un répondeur OCSP.

top

Directive SSLOCSPResponderCertificateFile

Description:Fournit un jeu de certificats de confiance du répondeur OCSP avec encodage PEM
Syntaxe:SSLOCSPResponderCertificateFile file
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible à partir de la version 2.4.26 du serveur HTTP Apache, sous réserve d'utiliser une version 0.9.7 ou supérieure d'OpenSSL

Cette directive permet de définir un fichier contenant une liste de certificats de confiance du répondeur OCSP à utiliser au cours de la validation du certificat du répondeur OCSP. Les certificats fournis peuvent être considérés comme de confiance sans avoir à effectuer de vérifications supplémentaires. Ce processus de validation du certificat du répondeur OCSP intervient en général lorsque ce dernier est autosigné ou tout simplement absent de la réponse OCSP.

top

Directive SSLOCSPResponderTimeout

Description:Délai d'attente pour les requêtes OCSP
Syntaxe:SSLOCSPResponderTimeout secondes
Défaut:SSLOCSPResponderTimeout 10
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette option permet de définir le délai d'attente pour les requêtes à destination des répondeurs OCSP, lorsque la directive SSLOCSPEnable est à on.

top

Directive SSLOCSPResponseMaxAge

Description:Age maximum autorisé pour les réponses OCSP
Syntaxe:SSLOCSPResponseMaxAge secondes
Défaut:SSLOCSPResponseMaxAge -1
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette option permet de définir l'âge maximum autorisé (la "fraicheur") des réponses OCSP. La valeur par défault (-1) signifie qu'aucun âge maximum n'est défini ; autrement dit, les réponses OCSP sont considérées comme valides tant que la valeur de leur champ nextUpdate se situe dans le futur.

top

Directive SSLOCSPResponseTimeSkew

Description:Dérive temporelle maximale autorisée pour la validation des réponses OCSP
Syntaxe:SSLOCSPResponseTimeSkew secondes
Défaut:SSLOCSPResponseTimeSkew 300
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette option permet de définir la dérive temporelle maximale autorisée pour les réponses OCSP (lors de la vérification des champs thisUpdate et nextUpdate).

top

Directive SSLOCSPUseRequestNonce

Description:Use a nonce within OCSP queries
Syntaxe:SSLOCSPUseRequestNonce on|off
Défaut:SSLOCSPUseRequestNonce on
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Available in httpd 2.4.10 and later

La documentation de cette directive n'a pas encore t traduite. Veuillez vous reporter la version en langue anglaise.

top

Directive SSLOpenSSLConfCmd

Description:Configuration des paramètres d'OpenSSL via son API SSL_CONF
Syntaxe:SSLOpenSSLConfCmd commande valeur
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible depuis la version 2.4.8 du serveur HTTP Apache avec OpenSSL 1.0.2 ou supérieur

Cette directive permet à mod_ssl d'accéder à l'API SSL_CONF d'OpenSSL. Il n'est ainsi plus nécessaire d'implémenter des directives supplémentaires pour mod_ssl lorsque de nouvelles fonctionnalités sont ajoutées à OpenSSL, ce qui rend la configuration de ce dernier beaucoup plus souple.

Le jeu de commandes disponibles pour la directive SSLOpenSSLConfCmd dépend de la version d'OpenSSL utilisée pour mod_ssl (la version minimale 1.0.2 est un prérequis). Pour obtenir la liste des commandes supportées, voir la section Supported configuration file commands de la page de manuel d'OpenSSL SSL_CONF_cmd(3).

Certaines commandes peuvent remplacer des directives existantes (comme SSLCipherSuite ou SSLProtocol) ; notez cependant que la syntaxe et/ou les valeurs possibles peuvent différer.

Examples

SSLOpenSSLConfCmd Options -SessionTicket,ServerPreference
SSLOpenSSLConfCmd ECDHParameters brainpoolP256r1
SSLOpenSSLConfCmd ServerInfoFile
"/usr/local/apache2/conf/server-info.pem"
SSLOpenSSLConfCmd Protocol "-ALL, TLSv1.2"
SSLOpenSSLConfCmd SignatureAlgorithms RSA+SHA384:ECDSA+SHA256
top

Directive SSLOptions

Description:Configure différentes options d'exécution du moteur SSL
Syntaxe:SSLOptions [+|-]option ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Extension
Module:mod_ssl

Cette directive permet de contrôler différentes options d'exécution du moteur SSL dans un contexte de répertoire. Normalement, si plusieurs SSLOptions peuvent s'appliquer à un répertoire, c'est la plus spécifique qui est véritablement prise en compte ; les options ne se combinent pas entre elles. Elles se combinent cependant entre elles si elles sont toutes précédées par un symbole plus (+) ou moins (-). Toute option précédée d'un + est ajoutée aux options actuellement en vigueur, et toute option précédée d'un - est supprimée de ces mêmes options.

Les options disponibles sont :

Exemple

SSLOptions +FakeBasicAuth -StrictRequire
<Files ~ "\.(cgi|shtml)$">
    SSLOptions +StdEnvVars -ExportCertData
</Files>
top

Directive SSLPassPhraseDialog

Description:Méthode utilisée pour entrer le mot de passe pour les clés privées chiffrées
Syntaxe:SSLPassPhraseDialog type
Défaut:SSLPassPhraseDialog builtin
Contexte:configuration globale
Statut:Extension
Module:mod_ssl

Lors de son démarrage, Apache doit lire les différents fichiers de certificats (voir la directive SSLCertificateFile) et de clés privées (voir la directive SSLCertificateKeyFile) des serveurs virtuels où SSL est activé. Comme, pour des raisons de sécurité, les fichiers de clés privées sont en général chiffrés, mod_ssl doit demander à l'administrateur un mot de passe pour déchiffrer ces fichiers. L'argument type permet de choisir la manière dont cette demande peut être formulée parmi les trois suivantes :

Exemple

SSLPassPhraseDialog "exec:/usr/local/apache/sbin/pp-filter"
top

Directive SSLProtocol

Description:Indique les versions du protocole SSL/TLS disponibles
Syntaxe:SSLProtocol [+|-]protocole ...
Défaut:SSLProtocol all -SSLv3 (jusqu'à la version 2.4.16 : all)
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl

Cette directive permet de définir quelles versions du protocole SSL/TLS seront acceptées lors de l'initialisation d'une nouvelle connexion.

Les protocoles disponibles sont les suivants (sensibles à la casse) :

Exemple

SSLProtocol TLSv1

La directive SSLProtocol et les serveurs virtuels basés sur le nom

Avant OpenSSL 1.1.1, et même si l'indication du nom de serveur (Server Name Indication ou SNI) permettait de déterminer le serveur virtuel cible assez tôt au cours de la négociation TLS, il était impossible de changer de version de protocole TLS à ce point, si bien que le SSLProtocol négocié se basait toujours sur celui du serveur virtuel de base (le premier serveur virtuel déclaré avec le couple IP:port de la connexion).

A partir de la version 2.4.42, si le serveur HTTP Apache est compilé avec une version 1.1.1. ou supérieure d'OpenSSL, et si le client fournit la SNI dans la négociation TLS, le SSLProtocol de chaque serveur virtuel (basé sur le nom) pourra être pris en compte et le sera.

A des fins de compatibilité avec les versions précédentes, si un serveur virtuel basé sur le nom n'a aucune directive SSLProtocol définie, c'est le protocole du serveur virtuel de base qui s'appliquera, à moins qu'une directive SSLProtocol ne soit configurée au niveau global, auquel cas c'est le protocole défini par cette directive qui s'appliquera (ce dernier cas relève cependant plus d'un comportement logique que d'un souci de compatibilité).

top

Directive SSLProxyCACertificateFile

Description:Fichier contenant la concaténation des certificats de CA codés en PEM pour l'authentification des serveurs distants
Syntaxe:SSLProxyCACertificateFile file-path
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir le fichier tout-en-un où sont stockés les certificats des Autorités de Certification (CA) pour les serveurs distants auxquels vous avez à faire. On les utilise lors de l'authentification du serveur distant. Un tel fichier contient la simple concaténation des différents fichiers de certificats codés en PEM, classés par ordre de préférence. On peut utiliser cette directive à la place et/ou en complément de la directive SSLProxyCACertificatePath.

Exemple

SSLProxyCACertificateFile
"/usr/local/apache2/conf/ssl.crt/ca-bundle-serveur.distant.crt"
top

Directive SSLProxyCACertificatePath

Description:Répertoire des certificats de CA codés en PEM pour l'authentification des serveurs distants
Syntaxe:SSLProxyCACertificatePath chemin-répertoire
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de spécifier le répertoire où sont stockés les certificats des Autorités de Certification (CAs) pour les serveurs distants auxquels vous avez à faire. On les utilise pour vérifier le certificat du serveur distant lors de l'authentification de ce dernier.

Les fichiers de ce répertoire doivent être codés en PEM et ils sont accédés via des noms de fichier sous forme de condensés ou hash. Il ne suffit donc pas de placer les fichiers de certificats dans ce répertoire : vous devez aussi créer des liens symboliques nommés valeur-de-hashage.N, et vous devez toujours vous assurer que ce répertoire contient les liens symboliques appropriés.

Exemple

SSLProxyCACertificatePath "/usr/local/apache2/conf/ssl.crt/"
top

Directive SSLProxyCARevocationCheck

Description:Active la vérification des révocations basée sur les CRLs pour l'authentification du serveur distant
Syntaxe:SSLProxyCARevocationCheck chain|leaf|none
Défaut:SSLProxyCARevocationCheck none
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Active la vérification des révocations basée sur les Listes de révocations de Certificats (CRL) pour les serveurs distants auxquels vous vous connectez. A moins une des directives SSLProxyCARevocationFile ou SSLProxyCARevocationPath doit être définie. Lorsque cette directive est définie à chain (valeur recommandée), les vérifications CRL sont effectuées sur tous les certificats de la chaîne, alors que la valeur leaf limite la vérification au certificat hors chaîne (la feuille).

Lorsque la directive est définie à chain ou leaf, les CRLs doivent être disponibles pour que la validation réussisse

Avant la version 2.3.15, les vérifications CRL dans mod_ssl réussissaient même si aucune CRL n'était trouvée dans les chemins définis par les directives SSLProxyCARevocationFile ou SSLProxyCARevocationPath. Le comportement a changé avec l'introduction de cette directive : lorsque la vérification est activée, les CRLs doivent être présentes pour que la validation réussisse ; dans le cas contraire, elle échouera avec une erreur "CRL introuvable".

Exemple

SSLProxyCARevocationCheck chain
top

Directive SSLProxyCARevocationFile

Description:Fichier contenant la concaténation des CRLs de CA codés en PEM pour l'authentification des serveurs distants
Syntaxe:SSLProxyCARevocationFile file-path
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir le fichier tout-en-un où sont rassemblées les Listes de Révocation de Certificats (CRLs) des Autorités de certification (CAs) pour les serveurs distants auxquels vous avez à faire. On les utilise pour l'authentification des serveurs distants. Un tel fichier contient la simple concaténation des différents fichiers de CRLs codés en PEM, classés par ordre de préférence. Cette directive peut être utilisée à la place et/ou en complément de la directive SSLProxyCARevocationPath.

Exemple

SSLProxyCARevocationFile
"/usr/local/apache2/conf/ssl.crl/ca-bundle-serveur.distant.crl"
top

Directive SSLProxyCARevocationPath

Description:Répertoire des CRLs de CA codés en PEM pour l'authentification des serveurs distants
Syntaxe:SSLProxyCARevocationPath chemin-répertoire
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir le répertoire où sont stockées les Listes de Révocation de Certificats (CRL) des Autorités de Certification (CAs) pour les serveurs distants auxquels vous avez à faire. On les utilise pour révoquer les certificats des serveurs distants au cours de l'authentification de ces derniers.

Les fichiers de ce répertoire doivent être codés en PEM et ils sont accédés via des noms de fichier sous forme de condensés ou hash. Il ne suffit donc pas de placer les fichiers de CRL dans ce répertoire : vous devez aussi créer des liens symboliques nommés valeur-de-hashage.rN, et vous devez toujours vous assurer que ce répertoire contient les liens symboliques appropriés.

Exemple

SSLProxyCARevocationPath "/usr/local/apache2/conf/ssl.crl/"
top

Directive SSLProxyCheckPeerCN

Description:Configuration de la vérification du champ CN du certificat du serveur distant
Syntaxe:SSLProxyCheckPeerCN on|off
Défaut:SSLProxyCheckPeerCN on
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir si le champ CN du certificat du serveur distant doit être comparé au nom de serveur de l'URL de la requête. S'ils ne correspondent pas, un code d'état 502 (Bad Gateway) est envoyé. A partir de la version 2.4.5, SSLProxyCheckPeerCN a été remplacé par SSLProxyCheckPeerName.

De la version 2.4.5 à la version 2.4.20, spécifier SSLProxyCheckPeerName off était suffisant pour obtenir ce comportement (car la valeur par défaut de SSLProxyCheckPeerCN était on). Avec ces versions, les deux directives doivent être définies à off pour éviter toute validation du nom de certificat du serveur distant, et de nombreux utilisateurs ont signalé ce comportement comme très perturbant.

A partir de la version 2.4.21, toutes les configurations qui activent au moins une des deux directives SSLProxyCheckPeerName ou SSLProxyCheckPeerCN adopteront le nouveau comportement de la directive SSLProxyCheckPeerName, et toutes les configurations qui désactivent une des deux directives SSLProxyCheckPeerName ou SSLProxyCheckPeerCN éviteront toute validation du nom de certificat du serveur distant. Seule la configuration suivante permettra de retrouver la comparaison de CN traditionnelle pour les versions 2.4.21 et supérieures :

Exemple

SSLProxyCheckPeerCN on
SSLProxyCheckPeerName off
top

Directive SSLProxyCheckPeerExpire

Description:Configuration de la vérification de l'expiration du certificat du serveur distant
Syntaxe:SSLProxyCheckPeerExpire on|off
Défaut:SSLProxyCheckPeerExpire on
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir si l'expiration du certificat du serveur distant doit être vérifiée ou non. Si la vérification échoue, un code d'état 502 (Bad Gateway) est envoyé.

Exemple

SSLProxyCheckPeerExpire on
top

Directive SSLProxyCheckPeerName

Description:Configure la vérification du nom d'hôte dans les certificats serveur distants
Syntaxe:SSLProxyCheckPeerName on|off
Défaut:SSLProxyCheckPeerName on
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache
Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de configurer la vérification du nom d'hôte pour les certificats serveur lorsque mod_ssl agit en tant que client SSL. La vérification réussit si le nom d'hôte de l'URI de la requête correspond à un des attributs CN du sujet du certificat, ou à l'extension subjectAltName. Si la vérification échoue, la requête SSL avorte, et un code d'erreur 502 (Bad Gateway) est renvoyé.

Les caractères génériques sont supportés dans certains cas bien spécifiques : une entrée subjectAltName de type dNSName ou les attributs CN commençant par *. correspondront à tout nom d'hôte comportant le même nombre de champs et le même suffixe ; par exemple, *.example.org correspondra à foo.example.org, mais pas à foo.bar.example.org car le nombre d'éléments dans les nom est différent.

Cette fonctionnalité a été introduite avec la version 2.4.5 et l'emporte sur la directive SSLProxyCheckPeerCN qui ne comparait que la valeur exacte du premier attribut CN avec le nom d'hôte. Cependant, de nombreux utilisateurs étaient déconcertés par le comportement induit par l'utilisation de ces deux directives individuellement, si bien que ce comportement a été amélioré avec la version 2.4.21. Voir la description de la directive SSLProxyCheckPeerCN pour le comportement original et des détails à propos de ces améliorations.

top

Directive SSLProxyCipherSuite

Description:Algorithmes de chiffrement disponibles pour la négociation lors de l'initialisation d'une connexion SSL de mandataire
Syntaxe:SSLProxyCipherSuite [protocol] cipher-spec
Défaut:SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive est équivalente à la directive SSLCipherSuite, mais s'applique à une connexion de mandataire. Veuillez vous reporter à la directive SSLCipherSuite pour plus d'informations.

top

Directive SSLProxyEngine

Description:Interrupteur marche/arrêt du moteur de mandataire SSL
Syntaxe:SSLProxyEngine on|off
Défaut:SSLProxyEngine off
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet d'activer/désactiver l'utilisation du moteur de protocole SSL/TLS pour le mandataire. On l'utilise en général à l'intérieur d'une section <VirtualHost> pour activer le protocole SSL/TLS dans le cadre d'un mandataire pour un serveur virtuel particulier. Par défaut, le moteur de protocole SSL/TLS est désactivé pour la fonction de mandataire du serveur principal et de tous les serveurs virtuels configurés.

Notez que la directive SSLProxyEngine ne doit généralement pas être utilisée dans le cadre d'un serveur virtuel qui agit en tant que mandataire direct (via les directives <Proxy> ou ProxyRequests). SSLProxyEngine n'est pas nécessaire pour activer un serveur mandataire direct pour les requêtes SSL/TLS.

Exemple

<VirtualHost _default_:443>
    SSLProxyEngine on
    #...
</VirtualHost>
top

Directive SSLProxyMachineCertificateChainFile

Description:Fichier de certificats de CA encodés PEM concaténés permettant au mandataire de choisir un certificat
Syntaxe:SSLProxyMachineCertificateChainFile nom-fichier
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir le fichier global où est enregistrée la chaîne de certification pour tous les certificats clients utilisés. Elle est nécessaire si le serveur distant présente une liste de certificats de CA qui ne sont pas les signataires directs d'un des certificats clients configurés.

Ce fichier contient tout simplement la concaténation des différents fichiers de certificats encodés PEM. Au démarrage, chaque certificat client configuré est examiné et une chaîne de certification est construite.

Avertissement en matière de sécurité

Si cette directive est définie, tous les certificats contenus dans le fichier spécifié seront considérés comme étant de confiance, comme s'ils étaient aussi désignés dans la directive SSLProxyCACertificateFile.

Exemple

SSLProxyMachineCertificateChainFile
"/usr/local/apache2/conf/ssl.crt/proxyCA.pem"
top

Directive SSLProxyMachineCertificateFile

Description:Fichier contenant la concaténation des clés et certificats clients codés en PEM que le mandataire doit utiliser
Syntaxe:SSLProxyMachineCertificateFile chemin-fichier
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est pris en charge à partir de la version 2.4.30 du serveur HTTP Apache
L'inclusion de certificats non-feuilles (CA) est prise en charge à partir de la version 2.4.59.

Cette directive permet de définir le fichier tout-en-un où sont stockés les clés et certificats permettant au serveur mandataire de s'authentifier auprès des serveurs distants.

Le fichier spécifié est la simple concaténation des différents fichiers de certificats codés en PEM. Cette directive s'utilise à la place ou en complément de la directive SSLProxyMachineCertificatePath. Le fichier spécifié peut contenir un nombre quelconque de paires certificat client/clé privée associée, et chaque paire peut être spécifiée selon l'ordre (certificat, clé) ou (clé, certificat). Des certificats non-feuilles (CA) peuvent aussi être inclus dans le fichier et sont traités comme s'ils avaient été définis à l'aide de la directive SSLProxyMachineCertificateChainFile.

Lorsqu'un serveur distant sollicite le serveur pour obtenir un certificat client, ce dernier doit fournir une liste de noms d'autorités de certification acceptables au cours de la négociation. Si cette liste n'est pas fournie, mod_ssl utilisera la première paire certificat/clé client définie. Si par contre cette liste est fournie, mod_ssl va la parcourir afin de trouver un certificat client défini qui a été fourni soit directement par l'autorité de certification considérée, soit indirectement via un nombre quelconque de certificats d'autorités de certification intermédiaires. La chaîne de certificats d'autorités de certification intermédiaires peut être construite à partir de ceux qui sont inclus dans le fichier ou configurés à l'aide de la directive SSLProxyMachineCertificateChainFile. Le premier certificat défini correspondant sera alors fourni comme réponse au cours de la négociation

Si la liste de noms de CA est fournie au serveur distant, et si aucun certificat client correspondant n'est trouvé, aucun certificat client ne sera fourni par mod_ssl, ce qui fera probablement échouer la négociation SSL/TLS (en fonction de la configuration du serveur distant).

Actuellement, les clés privées chiffrées ne sont pas supportées.

Seules les clés au format PKCS1 RSA, DSA ou EC sont supportées. Les clés au format PKCS8, autrement dit celles commençant par "-----BEGIN PRIVATE KEY-----", doivent être converties via une commande du style "openssl rsa -in private-pkcs8.pem -outform pem".

Exemple

SSLProxyMachineCertificateFile
"/usr/local/apache2/conf/ssl.crt/proxy.pem"
top

Directive SSLProxyMachineCertificatePath

Description:Répertoire des clés et certificats clients codés en PEM que le mandataire doit utiliser
Syntaxe:SSLProxyMachineCertificatePath chemin-répertoire
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir le répertoire où sont stockés les clés et certificats clients permettant au serveur mandataire de s'authentifier auprès des serveurs distants.

mod_ssl va essayer de charger tous les fichiers contenus dans le répertoire spécifié, comme si ces derniers étaient définis individuellement via la directive SSLProxyMachineCertificateFile.

Actuellement, les clés privées chiffrées ne sont pas supportées.

Seules les clés au format PKCS1 RSA, DSA ou EC sont supportées. Les clés au format PKCS8, autrement dit celles commençant par "-----BEGIN PRIVATE KEY-----", doivent être converties via une commande du style "openssl rsa -in private-pkcs8.pem -outform pem".

Exemple

SSLProxyMachineCertificatePath "/usr/local/apache2/conf/proxy.crt/"
top

Directive SSLProxyProtocol

Description:Définit les protocoles SSL disponibles pour la fonction de mandataire
Syntaxe:SSLProxyProtocol [+|-]protocole ...
Défaut:SSLProxyProtocol all -SSLv3 (jusqu'à la version 2.4.16: all)
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir les protocoles SSL que mod_ssl peut utiliser lors de l'élaboration de son environnement de serveur pour la fonction de mandataire. Il ne se connectera qu'aux serveurs utilisant un des protocoles spécifiés.

Veuillez vous reporter à la directive SSLProtocol pour plus d'informations.

top

Directive SSLProxyVerify

Description:Niveau de vérification du certificat du serveur distant
Syntaxe:SSLProxyVerify niveau
Défaut:SSLProxyVerify none
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Lorsqu'un mandataire est configuré pour faire suivre les requêtes vers un serveur SSL distant, cette directive permet de configurer la vérification du certificat de ce serveur distant.

Les valeurs de niveaux disponibles sont les suivantes :

En pratique, seuls les niveaux none et require sont vraiment intéressants, car le niveau optional ne fonctionne pas avec tous les serveurs, et le niveau optional_no_ca va tout à fait à l'encontre de l'idée que l'on peut se faire de l'authentification (mais peut tout de même être utilisé pour établir des pages de test SSL, etc...).

Exemple

SSLProxyVerify require
top

Directive SSLProxyVerifyDepth

Description:Niveau de profondeur maximum dans les certificats de CA lors de la vérification du certificat du serveur distant
Syntaxe:SSLProxyVerifyDepth niveau
Défaut:SSLProxyVerifyDepth 1
Contexte:configuration globale, serveur virtuel, section proxy
Statut:Extension
Module:mod_ssl
Compatibilité:Le contexte d'une section proxy est supporté à partir de la version 2.4.30 du serveur HTTP Apache

Cette directive permet de définir le niveau de profondeur maximum jusqu'auquel mod_ssl doit aller au cours de sa vérification avant de décider que le serveur distant ne possède pas de certificat valide.

La profondeur correspond en fait au nombre maximum de fournisseurs de certificats intermédiaires, c'est à dire le nombre maximum de certificats de CA que l'on peut consulter lors de la vérification du certificat du serveur distant. Une profondeur de 0 signifie que seuls les certificats de serveurs distants auto-signés sont acceptés, et la profondeur par défaut de 1 que le certificat du serveur distant peut être soit auto-signé, soit signé par une CA connue directement du serveur (en d'autres termes, le certificat de CA est référencé par la directive SSLProxyCACertificatePath), etc...

Exemple

SSLProxyVerifyDepth 10
top

Directive SSLRandomSeed

Description:Source de déclenchement du Générateur de Nombres Pseudo-Aléatoires (PRNG)
Syntaxe:SSLRandomSeed contexte source [nombre]
Contexte:configuration globale
Statut:Extension
Module:mod_ssl

Cette directive permet de définir une ou plusieurs sources de déclenchement du Générateur de Nombres Pseudo-Aléatoires (PRNG) dans OpenSSL au démarrage du serveur (si contexte a pour valeur startup) et/ou juste avant l'établissement d'une nouvelle connexion SSL (si contexte a pour valeur connect). Cette directive ne peut être utilisée qu'au niveau du serveur global car le PRNG est un service global.

Les différentes valeurs de source disponibles sont :

Exemple

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

Directive SSLRenegBufferSize

Description:Définit la taille du tampon de renégociation SSL
Syntaxe:SSLRenegBufferSize taille
Défaut:SSLRenegBufferSize 131072
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ssl

Si une renégociation SSL est requise dans un contexte de répertoire, par exemple avec l'utilisation de SSLVerifyClient dans un bloc Directory ou Location, mod_ssl doit mettre en tampon en mémoire tout corps de requête HTTP en attendant qu'une nouvelle initialisation de connexion SSL puisse être effectuée. Cette directive permet de définir la quantité de mémoire à allouer pour ce tampon.

Notez que dans de nombreuses configurations, le client qui envoie un corps de requête n'est pas forcément digne de confiance, et l'on doit par conséquent prendre en considération la possibilité d'une attaque de type déni de service lorsqu'on modifie la valeur de cette directive.

Exemple

SSLRenegBufferSize 262144
top

Directive SSLRequire

Description:N'autorise l'accès que lorsqu'une expression booléenne complexe et arbitraire est vraie
Syntaxe:SSLRequire expression
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ssl

SSLRequire est obsolète

SSLRequire est obsolète et doit en général être remplacée par l'expression Require. La syntaxe ap_expr de l'expression Require est une extension de la syntaxe de SSLRequire, avec les différences suivantes :

Avec SSLRequire, les opérateurs de comparaison <, <=, ... sont strictement équivalents aux opérateurs lt, le, ... , et fonctionnent selon une méthode qui compare tout d'abord la longueur des deux chaînes, puis l'ordre alphabétique. Les expressions ap_expr, quant à elles, possèdent deux jeux d'opérateurs de comparaison : les opérateurs <, <=, ... effectuent une comparaison alphabétique de chaînes, alors que les opérateurs -lt, -le, ... effectuent une comparaison d'entiers. Ces derniers possèdent aussi des alias sans tiret initial : lt, le, ...

Cette directive permet de spécifier une condition générale d'accès qui doit être entièrement satisfaite pour que l'accès soit autorisé. C'est une directive très puissante, car la condition d'accès spécifiée est une expression booléenne complexe et arbitraire contenant un nombre quelconque de vérifications quant aux autorisations d'accès.

L'expression doit respecter la syntaxe suivante (fournie ici sous la forme d'une notation dans le style de la grammaire BNF) :

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 "in" "PeerExtList(" word ")"
           | word "=~" regex
           | word "!~" regex

wordlist ::= word
           | wordlist "," word

word     ::= digit
           | cstring
           | variable
           | function

digit    ::= [0-9]+
cstring  ::= "..."
variable ::= "%{" varname "}"
function ::= funcname "(" funcargs ")"

Pour varname, toute variable décrite dans Variables d'environnement pourra être utilisée. Pour funcname, vous trouverez la liste des fonctions disponibles dans la documentation ap_expr.

expression est interprétée et traduite sous une forme machine interne lors du chargement de la configuration, puis évaluée lors du traitement de la requête. Dans le contexte des fichiers .htaccess, expression est interprétée et exécutée chaque fois que le fichier .htaccess intervient lors du traitement de la requête.

Exemple

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} -ge 1 and %{TIME_WDAY} -le 5          \
            and %{TIME_HOUR} -ge 8 and %{TIME_HOUR} -le 20       ) \
           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/

La fonction PeerExtList(identifiant objet) recherche une instance d'extension de certificat X.509 identifiée par identifiant objet (OID) dans le certificat client. L'expression est évaluée à true si la partie gauche de la chaîne correspond exactement à la valeur d'une extension identifiée par cet OID (Si plusieurs extensions possèdent le même OID, l'une d'entre elles au moins doit correspondre).

Exemple

SSLRequire "foobar" in PeerExtList("1.2.3.4.5.6")

Notes à propos de la fonction PeerExtList

  • L'identifiant objet peut être spécifié soit comme un nom descriptif reconnu par la bibliothèque SSL, tel que "nsComment", soit comme un OID numérique tel que "1.2.3.4.5.6".

  • Les expressions contenant des types connus de la bibliothèque SSL sont transformées en chaînes avant comparaison. Pour les extensions contenant un type non connu de la bibliothèque SSL, mod_ssl va essayer d'interpréter la valeur s'il s'agit d'un des types ASN.1 primaires UTF8String, IA5String, VisibleString, ou BMPString. Si l'extension correspond à un de ces types, la chaîne sera convertie en UTF-8 si nécessaire, puis comparée avec la partie gauche de l'expression.

Voir aussi

top

Directive SSLRequireSSL

Description:Interdit l'accès lorsque la requête HTTP n'utilise pas SSL
Syntaxe:SSLRequireSSL
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ssl

Cette directive interdit l'accès si HTTP sur SSL (c'est à dire HTTPS) n'est pas activé pour la connexion courante. Ceci est très pratique dans un serveur virtuel où SSL est activé ou dans un répertoire pour se protéger des erreurs de configuration qui pourraient donner accès à des ressources protégées. Lorsque cette directive est présente, toutes les requêtes qui n'utilisent pas SSL sont rejetées.

Exemple

SSLRequireSSL
top

Directive SSLSessionCache

Description:Type du cache de session SSL global et inter-processus
Syntaxe:SSLSessionCache type
Défaut:SSLSessionCache none
Contexte:configuration globale
Statut:Extension
Module:mod_ssl

Cette directive permet de configurer le type de stockage du cache de session SSL global et inter-processus. Ce cache est une fonctionnalité optionnelle qui accélère le traitement parallèle des requêtes. Pour ce qui est des requêtes vers un même processus du serveur (via HTTP keep-alive), OpenSSL met en cache les informations de session SSL en interne. Mais comme les clients modernes demandent des images en ligne et d'autres données via des requêtes parallèles (un nombre de quatre requêtes parallèles est courant), ces requêtes vont être servies par plusieurs processus du serveur pré-déclenchés. Ici, un cache inter-processus permet d'éviter des négociations de session inutiles.

Les quatre types de stockage suivants sont actuellement supportés :

Exemples

SSLSessionCache "dbm:/usr/local/apache/logs/ssl_gcache_data"
SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_gcache_data(512000)"

Le mutex ssl-cache permet de sérialiser l'accès au cache de session afin d'éviter toute corruption. Ce mutex peut être configuré via la directive Mutex.

top

Directive SSLSessionCacheTimeout

Description:Nombre de secondes avant l'expiration d'une session SSL dans le cache de sessions
Syntaxe:SSLSessionCacheTimeout secondes
Défaut:SSLSessionCacheTimeout 300
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:S'applique aussi à la reprise de session TLS (RFC 5077) à partir de la version 2.4.10 du serveur HTTP Apache

Cette directive permet de définir la durée de vie en secondes des informations stockées dans le cache de sessions SSL global et inter-processus, dans le cache OpenSSL interne en mémoire et pour les sessions réinitialisées par la reprise de session TLS (RFC 5077). elle peut être définie à une valeur d'environ 15 à des fins de test, mais à une valeur très supérieure comme 300 en production.

Exemple

SSLSessionCacheTimeout 600
top

Directive SSLSessionTicketKeyFile

Description:Clé de chiffrement/déchiffrement permanente pour les tickets de session TLS
Syntaxe:SSLSessionTicketKeyFile file-path
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible depuis la version 2.4.0 du serveur HTTP Apache, sous réserve que l'on utilise une version 0.9.8h ou supérieure d'OpenSSL

Cette directive permet de définir une clé secrète pour le chiffrement et le déchiffrement des tickets de session TLS selon les préconisations de la RFC 5077. Elle a été conçue à l'origine pour les environnements de clusters où les données des sessions TLS doivent être partagées entre plusieurs noeuds. Pour les configurations ne comportant qu'une seule instance de httpd, il est préférable d'utiliser les clés (aléatoires) générées par mod_ssl au démarrage du serveur.

Le fichier doit contenir 48 octets de données aléatoires créées de préférence par une source à haute entropie. Sur un système de type UNIX, il est possible de créer le fichier contenant la clé de la manière suivante :

dd if=/dev/random of=/chemin/vers/fichier.tkey bs=1 count=48

Ces clés doivent être renouvelées fréquemment, car il s'agit du seul moyen d'invalider un ticket de session existant - OpenSSL ne permet pas actuellement de spécifier une limite à la durée de vie des tickets. Une nouvelle clé ne peut être utilisée qu'après avoir redémarré le serveur. Tous les tickets de session existants deviennent invalides après le redémarrage du serveur.

Ce fichier contient des données sensibles et doit donc être protégé par des permissions similaires à celles du fichier spécifié par la directive SSLCertificateKeyFile.

top

Directive SSLSessionTickets

Description:Active ou désactive les tickets de session TLS
Syntaxe:SSLSessionTickets on|off
Défaut:SSLSessionTickets on
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible à partir de la version 2.4.11 du serveur HTTP Apache, sous réserve d'utiliser OpenSSL version 0.9.8f ou supérieure.

Cette directive permet d'activer ou de désactiver l'utilisation des tickets de session TLS (RFC 5077).

Les tickets de session TLS sont activés par défaut. Les utiliser sans redémarrer le serveur selon une périodicité appropriée (par exemple quotidiennement) compromet cependant le niveau de confidentialité.

top

Directive SSLSRPUnknownUserSeed

Description:Source d'aléa pour utilisateur SRP inconnu
Syntaxe:SSLSRPUnknownUserSeed secret-string
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible depuis la version 2.4.4 du serveur HTTP Apache, si la version 1.0.1 ou supérieure d'OpenSSL est utilisée.

Cette directive permet de définir la source d'aléa à utiliser pour les utilisateurs SRP inconnus, ceci afin de combler les manques en cas d'existence d'un tel utilisateur. Elle définit une chaîne secrète. Si cette directive n'est pas définie, Apache renverra une alerte UNKNOWN_PSK_IDENTITY aux clients qui fournissent un nom d'utilisateur inconnu.

Exemple

SSLSRPUnknownUserSeed "secret"

top

Directive SSLSRPVerifierFile

Description:Chemin du fichier de vérification SRP
Syntaxe:SSLSRPVerifierFile file-path
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible depuis la version 2.4.4 du serveur HTTP Apache, si la version 1.0.1 ou supérieure d'OpenSSL est utilisée.

Cette directive permet d'activer TLS-SRP et de définir le chemin du fichier de vérification OpenSSL SRP (Mot de passe distant sécurisé) contenant les noms d'utilisateurs TLS-SRP, les vérificateurs, les "grains de sel" (salts), ainsi que les paramètres de groupe.

Exemple

SSLSRPVerifierFile "/path/to/file.srpv"

Le fichier de vérification peut être créé via l'utilitaire en ligne de commande openssl :

Création du fichier de vérification SRP

openssl srp -srpvfile passwd.srpv -userinfo "some info" -add username

La valeur affectée au paramètre optionnel -userinfo est enregistrée dans la variable d'environnement SSL_SRP_USERINFO.

top

Directive SSLStaplingCache

Description:Configuration du cache pour l'agrafage OCSP
Syntaxe:SSLStaplingCache type
Contexte:configuration globale
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Si SSLUseStapling est à "on", cette directive permet de configurer le cache destiné à stocker les réponses OCSP incluses dans la négociation TLS. La configuration d'un cache est obligatoire pour pouvoir utiliser l'agrafage OCSP. A l'exception de none et nonenotnull, cette directive supporte les mêmes types de stockage que la directive SSLSessionCache.

top

Directive SSLStaplingErrorCacheTimeout

Description:Durée de vie des réponses invalides dans le cache pour agrafage OCSP
Syntaxe:SSLStaplingErrorCacheTimeout secondes
Défaut:SSLStaplingErrorCacheTimeout 600
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Cette directive permet de définir la durée de vie des réponses invalides dans le cache pour agrafage OCSP configuré via la directive SSLStaplingCache. Pour définir la durée de vie des réponses valides, voir la directive SSLStaplingStandardCacheTimeout.

top

Directive SSLStaplingFakeTryLater

Description:Génère une réponse "tryLater" pour les requêtes OCSP échouées
Syntaxe:SSLStaplingFakeTryLater on|off
Défaut:SSLStaplingFakeTryLater on
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Lorsque cette directive est activée, et si une requête vers un serveur OCSP à des fins d'inclusion dans une négociation TLS échoue, mod_ssl va générer une réponse "tryLater" pour le client (SSLStaplingReturnResponderErrors doit être activée).

top

Directive SSLStaplingForceURL

Description:Remplace l'URI du serveur OCSP spécifié dans l'extension AIA du certificat
Syntaxe:SSLStaplingForceURL uri
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Cette directive permet de remplacer l'URI du serveur OCSP extraite de l'extension authorityInfoAccess (AIA) du certificat. Elle peut s'avérer utile lorsqu'on passe par un mandataire

top

Directive SSLStaplingResponderTimeout

Description:Temps d'attente maximum pour les requêtes vers les serveurs OCSP
Syntaxe:SSLStaplingResponderTimeout secondes
Défaut:SSLStaplingResponderTimeout 10
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Cette directive permet de définir le temps d'attente maximum lorsque mod_ssl envoie une requête vers un serveur OCSP afin d'obtenir une réponse destinée à être incluse dans les négociations TLS avec les clients (SSLUseStapling doit avoir été activée au préalable).

top

Directive SSLStaplingResponseMaxAge

Description:Age maximum autorisé des réponses OCSP incluses dans la négociation TLS
Syntaxe:SSLStaplingResponseMaxAge secondes
Défaut:SSLStaplingResponseMaxAge -1
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Cette directive permet de définir l'âge maximum autorisé ("fraîcheur") des réponses OCSP incluses dans la négociation TLS (SSLUseStapling doit avoir été activée au préalable). La valeur par défaut (-1) ne définit aucun âge maximum, ce qui signifie que les réponses OCSP sont considérées comme valides à partir du moment où le contenu de leur champ nextUpdate se trouve dans le futur.

top

Directive SSLStaplingResponseTimeSkew

Description:Durée de vie maximale autorisée des réponses OCSP incluses dans la négociation TLS
Syntaxe:SSLStaplingResponseTimeSkew secondes
Défaut:SSLStaplingResponseTimeSkew 300
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Cette directive permet de spécifier l'intervalle de temps maximum que mod_ssl va calculer en faisant la différence entre les contenus des champs nextUpdate et thisUpdate des réponses OCSP incluses dans la négociation TLS. Pour pouvoir utiliser cette directive, SSLUseStapling doit être à "on".

top

Directive SSLStaplingReturnResponderErrors

Description:Transmet au client les erreurs survenues lors des requêtes OCSP
Syntaxe:SSLStaplingReturnResponderErrors on|off
Défaut:SSLStaplingReturnResponderErrors on
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Lorsque cette directive est activée, mod_ssl va transmettre au client les réponses concernant les requêtes OCSP échouées (comme les réponses avec un statut général autre que "successful", les réponses avec un statut de certificat autre que "good", les réponses arrivées à expiration, etc...). Lorsqu'elle est à off, seules les réponses avec un statut de certificat égal à "good" seront incluses dans la négociation TLS.

top

Directive SSLStaplingStandardCacheTimeout

Description:Durée de vie des réponses OCSP dans le cache
Syntaxe:SSLStaplingStandardCacheTimeout secondes
Défaut:SSLStaplingStandardCacheTimeout 3600
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Cette directive permet de définir la durée de vie des réponses OCSP dans le cache configuré via la directive SSLStaplingCache. Elle ne s'applique qu'aux réponse valides, alors que la directive SSLStaplingErrorCacheTimeout s'applique aux réponses invalides ou non disponibles.

top

Directive SSLStrictSNIVHostCheck

Description:Contrôle de l'accès des clients non-SNI à un serveur virtuel à base de nom.
Syntaxe:SSLStrictSNIVHostCheck on|off
Défaut:SSLStrictSNIVHostCheck off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible depuis la version 2.2.12 d'Apache

Cette directive permet de contrôler l'accès des clients non-SNI à un serveur virtuel à base de nom. Si elle est définie à on dans le serveur virtuel à base de nom par défaut, les clients non-SNI ne seront autorisés à accéder à aucun serveur virtuel appartenant à cette combinaison IP/port. Par contre, si elle est définie à on dans un serveur virtuel quelconque, les clients non-SNI ne se verront interdire l'accès qu'à ce serveur.

Cette option n'est disponible que si httpd a été compilé avec une version d'OpenSSL supportant SNI.

Exemple

SSLStrictSNIVHostCheck on
top

Directive SSLUserName

Description:Nom de la variable servant à déterminer le nom de l'utilisateur
Syntaxe:SSLUserName nom-var
Contexte:configuration globale, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ssl

Cette variable permet de définir le champ "user" de l'objet de la requête Apache. Ce champ est utilisé par des modules de plus bas niveau pour identifier l'utilisateur avec une chaîne de caractères. En particulier, l'utilisation de cette directive peut provoquer la définition de la variable d'environnement REMOTE_USER. La valeur de l'argument nom-var peut correspondre à toute variable d'environnement SSL.

Notez que cette directive est sans effet si l'option FakeBasicAuth est utilisée (voir SSLOptions).

Exemple

SSLUserName SSL_CLIENT_S_DN_CN
top

Directive SSLUseStapling

Description:Active l'ajout des réponses OCSP à la négociation TLS
Syntaxe:SSLUseStapling on|off
Défaut:SSLUseStapling off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ssl
Compatibilité:Disponible si on utilise OpenSSL version 0.9.8h ou supérieure

Cette directive permet d'activer l'"Agrafage OCSP" (OCSP stapling) selon la définition de l'extension TLS "Certificate Status Request" fournie dans la RFC 6066. Si elle est activée et si le client le demande, mod_ssl va inclure une réponse OCSP à propos de son propre certificat dans la négociation TLS. Pour pouvoir activer l'Agrafage OCSP, il est nécessaire de configurer un SSLStaplingCache.

L'agrafage OCSP dispense le client de requérir le serveur OCSP directement ; il faut cependant noter que selon les spécifications de la RFC 6066, la réponse CertificateStatus du serveur ne peut inclure une réponse OCSP que pour un seul certificat. Pour les certificats de serveur comportant des certificats de CA intermédiaires dans leur chaîne (c'est un cas typique de nos jours), l'implémentation actuelle de l'agrafage OCSP n'atteint que partiellement l'objectif d' "économie en questions/réponse et en ressources". Pour plus de détails, voir la RFC 6961 (TLS Multiple Certificate Status Extension).

Lorsque l'agrafage OCSP est activé, le mutex ssl-stapling contrôle l'accès au cache de l'agrafage OCSP afin de prévenir toute corruption, et le mutex sss-stapling-refresh contrôle le raffraîchissement des réponses OCSP. Ces mutex peuvent être configurés via la directive Mutex.

top

Directive SSLVerifyClient

Description:Niveau de vérification du certificat client
Syntaxe:SSLVerifyClient niveau
Défaut:SSLVerifyClient none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ssl

Cette directive permet de définir le niveau de vérification du certificat pour l'authentification du client. Notez que cette directive peut être utilisée à la fois dans les contextes du serveur principal et du répertoire. Dans le contexte du serveur principal, elle s'applique au processus d'authentification du client utilisé au cours de la négociation SSL standard lors de l'établissement d'une connexion. Dans un contexte de répertoire, elle force une renégociation SSL avec le niveau de vérification du client spécifié, après la lecture d'une requête HTTP, mais avant l'envoi de la réponse HTTP.

Les valeurs de niveau disponibles sont les suivantes :

Exemple

SSLVerifyClient require
top

Directive SSLVerifyDepth

Description:Profondeur maximale des certificats de CA pour la vérification des certificats clients
Syntaxe:SSLVerifyDepth nombre
Défaut:SSLVerifyDepth 1
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ssl

Cette directive permet de spécifier la profondeur maximale à laquelle mod_ssl va effectuer sa vérification avant de décider que le client ne possède pas de certificat valide. Notez que cette directive peut être utilisée à la fois dans les contextes du serveur principal et de répertoire. Dans le contexte du serveur principal, elle s'applique au processus d'authentification du client utilisé au cours de la négociation SSL standard lors de l'établissement d'une connexion. Dans un contexte de répertoire, elle force une renégociation SSL avec le client selon la nouvelle profondeur spécifiée, après la lecture d'une requête HTTP, mais avant l'envoi de la réponse HTTP.

La profondeur correspond au nombre maximum de fournisseurs de certificats intermédiaires, c'est à dire le nombre maximum de certificats de CA que l'on est autorisé à suivre lors de la vérification du certificat du client. Une profondeur de 0 signifie que seuls les certificats clients auto-signés sont acceptés ; la profondeur par défaut de 1 signifie que le certificat client peut être soit auto-signé, soit signé par une CA connue directement du serveur (c'est à dire que le certificat de la CA doit être référencé par la directive SSLCACertificatePath), etc...

Exemple

SSLVerifyDepth 10

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/core.html.de0000664000175100017510000073730714743132254020041 0ustar covenercovener core - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Apache-Kernfunktionen

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  tr 

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
Support Apache!

Direktiven

Bugfix checklist

Siehe auch

top

AcceptFilter-Direktive

Beschreibung:Konfiguriert Optimierungen für lauschende Sockets bestimmter Protokolle
Syntax:AcceptFilter Protokoll Filter
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Verfügbar ab Apache 2.1.5

Diese Direktive aktiviert betriebssystemspezifische Optimierungen für lauschende Sockets anhand des Protokolltyps. Der grundlegende Ansatz ist, dass der Kernel das Socket nicht an den Serverprozess übergibt, bis entweder Daten verfügbar sind oder eine komplette HTTP-Anfrage zwischengespeichert wurde. Derzeit werden ausschließlich die Accept-Filter von FreeBSD und das primitivere TCP_DEFER_ACCEPT von Linux unterstützt.

Die Standardeinstellungen für FreeBSD sind:

AcceptFilter http httpready
AcceptFilter https dataready

Der httpready-Accept-Filter puffert komplette HTTP-Anfragen auf Kernelebene. Sobald eine Anfrage vollständig vorliegt, schickt der Kernel sie an den Server weiter. Bitte schlagen Sie in der accf_http(9)-Manpage für weitere Details nach. HTTPS-Anfragen sind verschlüsselt. Daher wird dafür nur der accf_data(9)-Filter verwendet.

Die Standardeinstellungen für Linux sind:

AcceptFilter http data
AcceptFilter https data

TCP_DEFER_ACCEPT unter Linux unterstützt keine Zwischenspeicherung von HTTP-Anfragen. Jeder andere Wert als none aktiviert TCP_DEFER_ACCEPT auf dem Lauschsocket. Mehr Details finden Sie in der tcp(7)-Manpage von Linux.

Wenn Sie none als Argument verwenden, werden alle Accept-Filter für das Protokoll abgeschaltet. Das ist sinnvoll für Protokolle, bei denen der Server zuerst Daten senden muss, wie zum Beispiel nntp:

AcceptFilter nttp none

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-handler, 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

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 None (2.3.9 und später), AllowOverride All (2.3.8 und früher)
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.), Metadaten (Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName), mod_rewrite-Direktiven RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule) und Action aus mod_actions.
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

AllowOverrideList-Direktive

Beschreibung:Individual directives that are allowed in .htaccess files
Syntax:AllowOverrideList None|directive [directive-type] ...
Voreinstellung:AllowOverrideList None
Kontext:Verzeichnis
Status:Core
Modul:core

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

CGIPassAuth-Direktive

Beschreibung:Enables passing HTTP authorization headers to scripts as CGI variables
Syntax:CGIPassAuth On|Off
Voreinstellung:CGIPassAuth Off
Kontext:Verzeichnis, .htaccess
AllowOverride:AuthConfig
Status:Core
Modul:core
Kompatibilität:Available in Apache HTTP Server 2.4.13 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

CGIVar-Direktive

Beschreibung:Controls how some CGI variables are set
Syntax:CGIVar variable rule
Kontext:Verzeichnis, .htaccess
AllowOverride:FileInfo
Status:Core
Modul:core
Kompatibilität:Available in Apache HTTP Server 2.4.21 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

DefaultRuntimeDir-Direktive

Beschreibung:Base directory for the server run-time files
Syntax:DefaultRuntimeDir directory-path
Voreinstellung:DefaultRuntimeDir DEFAULT_REL_RUNTIMEDIR (logs/)
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Available in Apache 2.4.2 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

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

Define-Direktive

Beschreibung:Define the existence of a variable
Syntax:Define Parametername
Kontext:Serverkonfiguration
Status:Core
Modul:core

Equivalent zum übergeben von Parametername mittels des -D Arguments an httpd.

Diese Directive kann verwendet werden, um die Nutzung von <IfDefine> Sectionen umzuschalten, ohne die -D Argumentente in etwaigen Start-Skripten ändern zu müssen.

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:

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

<Else>-Direktive

Beschreibung:Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
Syntax:<Else> ... </Else>
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
AllowOverride:All
Status:Core
Modul:core
Kompatibilität:Nested conditions are evaluated in 2.4.26 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

top

<ElseIf>-Direktive

Beschreibung:Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
Syntax:<ElseIf expression> ... </ElseIf>
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
AllowOverride:All
Status:Core
Modul:core
Kompatibilität:Nested conditions are evaluated in 2.4.26 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

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>

Beachten Sie bitte, dass die verzeichnisbasierte und .htaccess-Konfiguration von EnableSendfile nicht vom mod_cache_disk-Modul unterstützt wird. Nur die globale Konfiguration von EnableSendfile wird vom Modul beachtet.

top

Error-Direktive

Beschreibung:Abort configuration parsing with a custom error message
Syntax:Error message
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
Status:Core
Modul:core
Kompatibilität:2.3.9 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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. Ausgabe einer angepassten Meldung
  3. Umleitung zu einem lokalen URL-Pfad der das Problem bzw. den Fehler behandelt
  4. Umleitung zu einer externen URL, die das Problem bzw. den Fehler behandelt

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 Webpfaden mit einem Schrägstrich (/) beginnen (relativ zum DocumentRoot-Verzeichnis) oder eine vollständige 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 verfügbar.

Obwohl die meisten Fehlermeldungen überschrieben werden können, werden unter bestimmten Umständen die internen Meldungen ungeachtet der Einstellung der ErrorDocument-Direktive verwendet. Insbesondere bei einer fehlerhaften Anfrage werden der normale Bearbeitungsprozess sofort beendet und die interne Meldung zurückgegeben. Das ist notwendig, um Sicherheitsprobleme zu vermeiden, die auf Grund fehlerhafter Anfragen entstehen.

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

ErrorLogFormat-Direktive

Beschreibung:Format specification for error log entries
Syntax: ErrorLogFormat [connection|request] format
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

top

ExtendedStatus-Direktive

Beschreibung:Keep track of extended status information for each request
Syntax:ExtendedStatus On|Off
Voreinstellung:ExtendedStatus Off[*]
Kontext:Serverkonfiguration
Status:Core
Modul:core

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

FlushMaxPipelined-Direktive

Beschreibung:Maximum number of pipelined responses above which they are flushed to the network
Syntax:FlushMaxPipelined number
Voreinstellung:FlushMaxPipelined 5
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:2.4.47 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

FlushMaxThreshold-Direktive

Beschreibung:Threshold above which pending data are flushed to the network
Syntax:FlushMaxThreshold number-of-bytes
Voreinstellung:FlushMaxThreshold 65535
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:2.4.47 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

GprofDir-Direktive

Beschreibung:Directory to write gmon.out profiling data to.
Syntax:GprofDir /tmp/gprof/|/tmp/gprof/%
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

HttpProtocolOptions-Direktive

Beschreibung:Modify restrictions on HTTP Request Messages
Syntax:HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0]
Voreinstellung:HttpProtocolOptions Strict LenientMethods Allow0.9
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:2.2.32 or 2.4.24 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

<If>-Direktive

Beschreibung:Contains directives that apply only if a condition is satisfied by a request at runtime
Syntax:<If expression> ... </If>
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
AllowOverride:All
Status:Core
Modul:core
Kompatibilität:Nested conditions are evaluated in 2.4.26 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

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:

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

<IfDirective>-Direktive

Beschreibung:Encloses directives that are processed conditional on the presence or absence of a specific directive
Syntax:<IfDirective [!]directive-name> ... </IfDirective>
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
AllowOverride:All
Status:Core
Modul:core
Kompatibilität:Available in 2.4.34 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

top

<IfFile>-Direktive

Beschreibung:Encloses directives that will be processed only if file exists at startup
Syntax:<IfFile [!]filename> ... </IfFile>
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
AllowOverride:All
Status:Core
Modul:core
Kompatibilität:Available in 2.4.34 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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:

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

<IfSection>-Direktive

Beschreibung:Encloses directives that are processed conditional on the presence or absence of a specific section directive
Syntax:<IfSection [!]section-name> ... </IfSection>
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
AllowOverride:All
Status:Core
Modul:core
Kompatibilität:Available in 2.4.34 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

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

IncludeOptional-Direktive

Beschreibung:Includes other configuration files from within the server configuration files
Syntax:IncludeOptional file-path|directory-path|wildcard
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
Status:Core
Modul:core
Kompatibilität:Available in 2.3.6 and later. Not existent file paths without wildcards do not cause SyntaxError after 2.4.30

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

MaxRangeOverlaps-Direktive

Beschreibung:Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
Syntax:MaxRangeOverlaps default | unlimited | none | number-of-ranges
Voreinstellung:MaxRangeOverlaps 20
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
Status:Core
Modul:core
Kompatibilität:Available in Apache HTTP Server 2.3.15 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

MaxRangeReversals-Direktive

Beschreibung:Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
Syntax:MaxRangeReversals default | unlimited | none | number-of-ranges
Voreinstellung:MaxRangeReversals 20
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
Status:Core
Modul:core
Kompatibilität:Available in Apache HTTP Server 2.3.15 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

MaxRanges-Direktive

Beschreibung:Number of ranges allowed before returning the complete resource
Syntax:MaxRanges default | unlimited | none | number-of-ranges
Voreinstellung:MaxRanges 200
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
Status:Core
Modul:core
Kompatibilität:Available in Apache HTTP Server 2.3.15 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

MergeSlashes-Direktive

Beschreibung:Controls whether the server merges consecutive slashes in URLs.
Syntax:MergeSlashes ON|OFF
Voreinstellung:MergeSlashes ON
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:Added in 2.4.39

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

MergeTrailers-Direktive

Beschreibung:Determines whether trailers are merged into headers
Syntax:MergeTrailers [on|off]
Voreinstellung:MergeTrailers off
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:2.4.11 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

Mutex-Direktive

Beschreibung:Configures mutex mechanism and lock file directory for all or specified mutexes
Syntax:Mutex mechanism [default|mutex-name] ... [OmitPID]
Voreinstellung:Mutex default
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Available in Apache HTTP Server 2.3.4 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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 [2001:db8::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.

Warnung

Die Vermischung von Optionen mit + oder - mit Optionen ohne diese (Zeichen) ist keine gültige Syntax und führt mit hoher Wahrscheinlichkeit zu unerwarteten Effekten.

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

Protocol-Direktive

Beschreibung:Protocol for a listening socket
Syntax:Protocol protocol
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:Available in Apache 2.1.5 and later. On Windows, from Apache 2.3.3 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

top

Protocols-Direktive

Beschreibung:Protocols available for a server/virtual host
Syntax:Protocols protocol ...
Voreinstellung:Protocols http/1.1
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:Only available from Apache 2.4.17 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

top

ProtocolsHonorOrder-Direktive

Beschreibung:Determines if order of Protocols determines precedence during negotiation
Syntax:ProtocolsHonorOrder On|Off
Voreinstellung:ProtocolsHonorOrder On
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:Only available from Apache 2.4.17 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

top

QualifyRedirectURL-Direktive

Beschreibung:Controls whether the REDIRECT_URL environment variable is fully qualified
Syntax:QualifyRedirectURL On|Off
Voreinstellung:QualifyRedirectURL Off
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
AllowOverride:FileInfo
Status:Core
Modul:core
Kompatibilität:Directive supported in 2.4.18 and later. 2.4.17 acted as if 'QualifyRedirectURL On' was configured.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

ReadBufferSize-Direktive

Beschreibung:Size of the buffers used to read data
Syntax:ReadBufferSize bytes
Voreinstellung:ReadBufferSize 8192
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
Status:Core
Modul:core
Kompatibilität:2.4.27 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

RegexDefaultOptions-Direktive

Beschreibung:Allow to configure global/default options for regexes
Syntax:RegexDefaultOptions [none] [+|-]option [[+|-]option] ...
Voreinstellung:RegexDefaultOptions DOTALL DOLLAR_ENDONLY
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Only available from Apache 2.4.30 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

RegisterHttpMethod-Direktive

Beschreibung:Register non-standard HTTP methods
Syntax:RegisterHttpMethod method [method [...]]
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Available in Apache HTTP Server 2.4.24 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

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

SeeRequestTail-Direktive

Beschreibung:Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
Syntax:SeeRequestTail On|Off
Voreinstellung:SeeRequestTail Off
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Available in Apache httpd 2.2.7 and later.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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 Direktiven UseCanonicalName und UseCanonicalPhysicalPort 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.

Hinweis: SetHandler setzt die Standard-Handler außer Kraft und unterdrückt gewohnte Verhaltensweisen, wie beispielsweise die Behandlung von URLs, die auf einen Schrägstrich (/) enden als Verzeichnisse oder (die Auslieferung von) Index-Dateien.

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

StrictHostCheck-Direktive

Beschreibung:Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Syntax:StrictHostCheck ON|OFF
Voreinstellung:StrictHostCheck OFF
Kontext:Serverkonfiguration, Virtual Host
Status:Core
Modul:core
Kompatibilität:Added in 2.4.49

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

TimeOut-Direktive

Beschreibung:Zeitspanne, die der Server auf verschiedene Ereignisse wartet, bevor er die Anfrage abbricht
Syntax:TimeOut Sekunden
Voreinstellung:TimeOut 60
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. Die Zeitspanne zwischen dem Empfang von TCP-Paketen einer POST- oder PUT-Anfrage.
  3. Die Zeitspanne zwischen ACKs bei der Übermittlung der TCP-Pakete der Antwort.

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. Seit Apache 2.4 ist die Voreinstellung 60.

top

TraceEnable-Direktive

Beschreibung:Legt das Verhalten von TRACE-Anfragen fest
Syntax:TraceEnable [on|off|extended]
Voreinstellung:TraceEnable on
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Verfügbar ab Apache 1.3.34 und 2.0.55

Diese Direktive beeinflusst das Verhalten von TRACE sowohl für den Server selbst als auch mod_proxy. Die Voreinstellung TraceEnable on erlaubt TRACE-Anfragen gemäß RFC 2616. Dort werden nur Anfragen ohne Datenteil zugelassen. TraceEnable off sorgt dafür, dass der Serverkern und mod_proxy den Fehler 405 (Zugriffsmethode nicht erlaubt) an den Client senden.

Zu Test- und Diagnosezwecken können Sie auch nicht-standardkonforme Anfragen mit Datenteil erlauben, indem Sie die Direktive TraceEnable extended verwenden. Der Server (als Ursprungsserver) beschränkt den Anfrageinhalt auf 64k. (Wenn Transfer-Encoding: chunked benutzt wird, können weitere 8k für die Chunk-Kopfzeilen verwendet werden.) Der Server selbst reflektiert dann die vollständigen HTTP- und Chunk-Kopfzeilen in seiner Antwort. Die Einschränkung auf 64k gilt nicht, wenn der Server als Proxy arbeitet.

top

UNCList-Direktive

Beschreibung:Controls what UNC host names can be accessed by the server
Syntax:UNCList hostname [hostname...]
Voreinstellung:unset
Kontext:Serverkonfiguration
Status:Core
Modul:core
Kompatibilität:Added in 2.4.60, Windows only.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

UnDefine-Direktive

Beschreibung:Undefine the existence of a variable
Syntax:UnDefine parameter-name
Kontext:Serverkonfiguration
Status:Core
Modul:core

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

Siehe auch

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

UseCanonicalPhysicalPort-Direktive

Beschreibung:Bestimmt, wie der Server seinen eigenen Namen und Port ermittelt
Syntax:UseCanonicalPhysicalPort On|Off
Voreinstellung:UseCanonicalPhysicalPort Off
Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
Status:Core
Modul:core

In vielen Situationen muss der Apache eine selbstreferenzierende URL zusammenbauen, d.h. eine URL, die auf den selben Server zurück verweist. Wenn der Apache für die UseCanonicalName-Direktive den Port bestimmt, wird mit UseCanonicalPhysicalPort On die tatsächlich für die Anfrage verwendete physische Portnummer in Betracht gezogen. Mit UseCanonicalPhysicalPort Off verläßt sich der Apache nur auf die Konfiguration, um eine gültige Portnummer zu bestimmen und läßt die physische Portnummer außer acht.

Hinweis

Wenn der physische Port verwendet wird, ist die Reihenfolge wie folgt:

UseCanonicalName On

  • Der in Servername angegebene Port
  • Der physische Port
  • Der Standardport
UseCanonicalName Off | DNS
  • Der Port, der aus dem Host:-Header gewonnen wurde
  • Der physische Port
  • Der in Servername angegebene Port
  • Der Standardport

Bei UseCanonicalPhysicalPort Off werden die physischen Ports aus der Suchreihe entfernt.

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:

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 [2001:db8::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  |  es  |  fr  |  ja  |  tr 

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ssl.html.en0000664000175100017510000057162415010377461020560 0ustar covenercovener mod_ssl - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_ssl

Available Languages:  en  |  fr 

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 v3 and TLS v1.x support for the Apache HTTP Server. SSL v2 is no longer supported.

This module relies on OpenSSL to provide the cryptography engine.

Further details, discussion, and examples are provided in the SSL documentation.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Environment Variables

This module can be configured to provide several items of SSL information as additional environment variables to the SSI and CGI namespace. Except for HTTPS and SSL_TLS_SNI which are always defined, this information is not provided by default for performance reasons. (See SSLOptions StdEnvVars, below) 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 (SSLv3, TLSv1, TLSv1.1, TLSv1.2)
SSL_SESSION_ID string The hex-encoded SSL session id
SSL_SESSION_RESUMED string Initial or Resumed SSL Session. Note: multiple requests may be served over the same (Initial or Resumed) SSL session if HTTP KeepAlive is in use
SSL_SECURE_RENEG string true if secure renegotiation is supported, else false
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_COMPRESS_METHOD string SSL compression method negotiated
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_SAN_Email_n string Client certificate's subjectAltName extension entries of type rfc822Name
SSL_CLIENT_SAN_DNS_n string Client certificate's subjectAltName extension entries of type dNSName
SSL_CLIENT_SAN_OTHER_msUPN_n string Client certificate's subjectAltName extension entries of type otherName, Microsoft User Principal Name form (OID 1.3.6.1.4.1.311.20.2.3)
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_CERT_RFC4523_CEA string Serial number and issuer of the certificate. The format matches that of the CertificateExactAssertion in RFC4523
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_SAN_Email_n string Server certificate's subjectAltName extension entries of type rfc822Name
SSL_SERVER_SAN_DNS_n string Server certificate's subjectAltName extension entries of type dNSName
SSL_SERVER_SAN_OTHER_dnsSRV_n string Server certificate's subjectAltName extension entries of type otherName, SRVName form (OID 1.3.6.1.5.5.7.8.7, RFC 4985)
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
SSL_SRP_USER string SRP username
SSL_SRP_USERINFO string SRP user info
SSL_TLS_SNI string Contents of the SNI TLS extension (if supplied with ClientHello)

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 httpd 2.2.0 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 a zero-based index to select a particular attribute. For example, where the server certificate subject DN included two OU attributes, SSL_SERVER_S_DN_OU_0 and SSL_SERVER_S_DN_OU_1 could be used to reference each. A variable name without a _n suffix is equivalent to that name with a _0 suffix; the first (or only) attribute. When the environment table is populated using the StdEnvVars option of the SSLOptions directive, the first (or only) attribute of any DN is added only under a non-suffixed name; i.e. no _0 suffixed entries are added.

In httpd 2.4.32 and later, an optional _RAW suffix may be added to x509 in a DN component, to suppress conversion of the attribute value to UTF-8. This must be placed after the index suffix (if any). For example, SSL_SERVER_S_DN_OU_RAW or SSL_SERVER_S_DN_OU_0_RAW could be used.

The format of the *_DN variables has changed in Apache HTTPD 2.3.11. See the LegacyDNStringFormat option for SSLOptions for details.

SSL_CLIENT_V_REMAIN is only available in version 2.1 and later.

A number of additional environment variables can also be used in SSLRequire expressions, or in custom log formats:

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
THE_REQUEST            SERVER_NAME           TIME_MIN
REQUEST_FILENAME       SERVER_PORT           TIME_SEC
REQUEST_METHOD         SERVER_PROTOCOL       TIME_WDAY
REQUEST_SCHEME         REMOTE_ADDR           TIME
REQUEST_URI            REMOTE_USER

In these contexts, two special formats can also be used:

ENV:variablename
This will expand to the standard environment variable variablename.
HTTP:headername
This will expand to the value of the request header with name headername.
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"

These formats even work without setting the StdEnvVars option of the SSLOptions directive.

top

Request Notes

mod_ssl sets "notes" for the request which can be used in logging with the %{name}n format string in mod_log_config.

The notes supported are as follows:

ssl-access-forbidden
This note is set to the value 1 if access was denied due to an SSLRequire or SSLRequireSSL directive.
ssl-secure-reneg
If mod_ssl is built against a version of OpenSSL which supports the secure renegotiation extension, this note is set to the value 1 if SSL is in used for the current connection, and the client also supports the secure renegotiation extension. If the client does not support the secure renegotiation extension, the note is set to the value 0. If mod_ssl is not built against a version of OpenSSL which supports secure renegotiation, or if SSL is not in use for the current connection, the note is not set.
top

Expression Parser Extension

When mod_ssl is built into Apache or at least loaded (under DSO situation) any variables provided by mod_ssl can be used in expressions for the ap_expr Expression Parser. The variables can be referenced using the syntax ``%{varname}''. Starting with version 2.4.18 one can also use the mod_rewrite style syntax ``%{SSL:varname}'' or the function style syntax ``ssl(varname)''.

Example (using mod_headers)

Header set X-SSL-PROTOCOL "expr=%{SSL_PROTOCOL}"
Header set X-SSL-CIPHER "expr=%{SSL:SSL_CIPHER}"

This feature even works without setting the StdEnvVars option of the SSLOptions directive.

top

Authorization providers for use with Require

mod_ssl provides a few authentication providers for use with mod_authz_core's Require directive.

Require ssl

The ssl provider denies access if a connection is not encrypted with SSL. This is similar to the SSLRequireSSL directive.

Require ssl

Require ssl-verify-client

The ssl provider allows access if the user is authenticated with a valid client certificate. This is only useful if SSLVerifyClient optional is in effect.

The following example grants access if the user is authenticated either with a client certificate or by username and password.

Require ssl-verify-client
Require valid-user
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.

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.

Example

SSLCADNRequestPath "/usr/local/apache2/conf/ca-names.crt/"
top

SSLCARevocationCheck Directive

Description:Enable CRL-based revocation checking
Syntax:SSLCARevocationCheck chain|leaf|none [flags ...]
Default:SSLCARevocationCheck none
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Optional flags available in httpd 2.4.21 or later

Enables certificate revocation list (CRL) checking. At least one of SSLCARevocationFile or SSLCARevocationPath must be configured. When set to chain (recommended setting), CRL checks are applied to all certificates in the chain, while setting it to leaf limits the checks to the end-entity cert.

The available flags are:

Example

SSLCARevocationCheck chain

Compatibility with versions 2.2

SSLCARevocationCheck chain no_crl_for_cert_ok
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.

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

SSLCertificateChainFile is deprecated

SSLCertificateChainFile became obsolete with version 2.4.8, when SSLCertificateFile was extended to also load intermediate CA certificates from the server certificate file.

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

But be careful: Providing the certificate chain works only if you are using a single 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 data file or token identifier
Syntax:SSLCertificateFile file-path|certid
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:certid available in 2.4.42 and later.

This directive points to a file with certificate data in PEM format, or the certificate identifier through a configured cryptographic token. If using a PEM file, at minimum, the file must include an end-entity (leaf) certificate. The directive can be used multiple times (referencing different filenames) to support multiple algorithms for server authentication - typically RSA, DSA, and ECC. The number of supported algorithms depends on the OpenSSL version being used for mod_ssl: with version 1.0.0 or later, openssl list-public-key-algorithms will output a list of supported algorithms, see also the note below about limitations of OpenSSL versions prior to 1.0.2 and the ways to work around them.

The files may also include intermediate CA certificates, sorted from leaf to root. This is supported with version 2.4.8 and later, and obsoletes SSLCertificateChainFile. When running with OpenSSL 1.0.2 or later, this allows to configure the intermediate CA chain on a per-certificate basis.

Custom DH parameters and an EC curve name for ephemeral keys, can also be added to end of the first file configured using SSLCertificateFile. This is supported in version 2.4.7 or later. Such parameters can be generated using the commands openssl dhparam and openssl ecparam. The parameters can be added as-is to the end of the first certificate file. Only the first file can be used for custom parameters, as they are applied independently of the authentication algorithm type.

Finally the end-entity certificate's private key can also be added to the certificate file instead of using a separate SSLCertificateKeyFile directive. This practice is highly discouraged. If it is used, the certificate files using such an embedded key must be configured after the certificates using a separate key file. If the private key is encrypted, the pass phrase dialog is forced at startup time.

As an alternative to storing certificates and private keys in files, a certificate identifier can be used to identify a certificate stored in a token. Currently, only PKCS#11 URIs are recognized as certificate identifiers, and can be used in conjunction with the OpenSSL pkcs11 engine or provider. If SSLCertificateKeyFile is omitted, the certificate and private key can be loaded through the single identifier specified with SSLCertificateFile.

DH parameter interoperability with primes > 1024 bit

Beginning with version 2.4.7, mod_ssl makes use of standardized DH parameters with prime lengths of 2048, 3072 and 4096 bits and with additional prime lengths of 6144 and 8192 bits beginning with version 2.4.10 (from RFC 3526), and hands them out to clients based on the length of the certificate's RSA/DSA key. With Java-based clients in particular (Java 7 or earlier), this may lead to handshake failures - see this FAQ answer for working around such issues.

Default DH parameters when using multiple certificates and OpenSSL versions prior to 1.0.2

When using multiple certificates to support different authentication algorithms (like RSA, DSA, but mainly ECC) and OpenSSL prior to 1.0.2, it is recommended to either use custom DH parameters (preferably) by adding them to the first certificate file (as described above), or to order the SSLCertificateFile directives such that RSA/DSA certificates are placed after the ECC one.

This is due to a limitation in older versions of OpenSSL which don't let the Apache HTTP Server determine the currently selected certificate at handshake time (when the DH parameters must be sent to the peer) but instead always provide the last configured certificate. Consequently, the server may select default DH parameters based on the length of the wrong certificate's key (ECC keys are much smaller than RSA/DSA ones and their length is not relevant for selecting DH primes).

Since custom DH parameters always take precedence over the default ones, this issue can be avoided by creating and configuring them (as described above), thus using a custom/suitable length.

Example

# Example using a PEM-encoded file.
SSLCertificateFile "/usr/local/apache2/conf/ssl.crt/server.crt"
# Example use of a certificate and private key from a PKCS#11 token:
SSLCertificateFile "pkcs11:token=My%20Token%20Name;id=45"
top

SSLCertificateKeyFile Directive

Description:Server PEM-encoded private key file
Syntax:SSLCertificateKeyFile file-path|keyid
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:keyid available in 2.4.42 and later.

This directive points to the PEM-encoded private key file for the server, or the key ID through a configured cryptographic token. If the contained private key is encrypted, the pass phrase dialog is forced at startup time.

The directive can be used multiple times (referencing different filenames) to support multiple algorithms for server authentication. For each SSLCertificateKeyFile directive, there must be a matching SSLCertificateFile directive.

The private key may also be combined with the certificate in the file given by SSLCertificateFile, but this practice is highly discouraged. If it is used, the certificate files using such an embedded key must be configured after the certificates using a separate key file.

As an alternative to storing private keys in files, a key identifier can be used to identify a private key stored in a token. Currently, only PKCS#11 URIs are recognized as private key identifiers, and can be used in conjunction with the OpenSSL pkcs11 engine or provider.

Example

# To use a private key from a PEM-encoded file:
SSLCertificateKeyFile "/usr/local/apache2/conf/ssl.key/server.key"
# To use a private key from a PKCS#11 token:
SSLCertificateKeyFile "pkcs11:token=My%20Token%20Name;id=45"
top

SSLCipherSuite Directive

Description:Cipher Suite available for negotiation in SSL handshake
Syntax:SSLCipherSuite [protocol] cipher-spec
Default:SSLCipherSuite DEFAULT (depends on OpenSSL version)
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. The optional protocol specifier can configure the Cipher Suite for a specific SSL version. Possible values include "SSL" for all SSL Protocols up to and including TLSv1.2.

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 renegotiation with the reconfigured Cipher Suite after the HTTP request was read but before the HTTP response is sent.

If the SSL library supports TLSv1.3 (OpenSSL 1.1.1 and later), the protocol specifier "TLSv1.3" can be used to configure the cipher suites for that protocol. Since TLSv1.3 does not offer renegotiations, specifying ciphers for it in a directory context is not allowed.

For a list of TLSv1.3 cipher names, see the OpenSSL documentation.

An SSL cipher specification in cipher-spec is composed of 4 major attributes plus a few extra minor ones:

An SSL cipher can also be an export cipher. SSLv2 ciphers are no longer supported. 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). The actually available ciphers and aliases depends on the used openssl version. Newer openssl versions may include additional ciphers.

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)
kSRP Secure Remote Password (SRP) key exchange
Authentication Algorithm:
aNULL No authentication
aRSA RSA authentication
aDSS DSS authentication
aDH Diffie-Hellman authentication
Cipher Encoding Algorithm:
eNULL No encryption
NULL alias for eNULL
AES AES encryption
DES DES encryption
3DES Triple-DES encryption
RC4 RC4 encryption
RC2 RC2 encryption
IDEA IDEA encryption
MAC Digest Algorithm:
MD5 MD5 hash function
SHA1 SHA1 hash function
SHA alias for SHA1
SHA256 SHA256 hash function
SHA384 SHA384 hash function
Aliases:
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
ECDH Elliptic Curve Diffie-Hellman key exchange
ADH all ciphers using Anonymous Diffie-Hellman key exchange
AECDH all ciphers using Anonymous Elliptic Curve Diffie-Hellman key exchange
SRP all ciphers using Secure Remote Password (SRP) key exchange
DSS all ciphers using DSS authentication
ECDSA all ciphers using ECDSA authentication
aNULL all ciphers using no authentication

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 (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:

aNULL, eNULL and EXP ciphers are always disabled

Beginning with version 2.4.7, null and export-grade ciphers are always disabled, as mod_ssl unconditionally adds !aNULL:!eNULL:!EXP to any cipher string at initialization.

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 depends on the version of the OpenSSL libraries used. Let's suppose it is ``RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5'' which means the following: Put RC4-SHA and AES128-SHA at the beginning. We do this, because these ciphers offer a good compromise between speed and security. Next, include high and medium security ciphers. Finally, remove all ciphers which do not authenticate, i.e. for SSL the Anonymous Diffie-Hellman ciphers, as well as all ciphers which use MD5 as hash algorithm, because it has been proven insufficient.

$ openssl ciphers -v 'RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5'
RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
...                     ...               ...     ...           ...
SEED-SHA                SSLv3 Kx=RSA      Au=RSA  Enc=SEED(128) Mac=SHA1
PSK-RC4-SHA             SSLv3 Kx=PSK      Au=PSK  Enc=RC4(128)  Mac=SHA1
KRB5-RC4-SHA            SSLv3 Kx=KRB5     Au=KRB5 Enc=RC4(128)  Mac=SHA1

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
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
DES-CBC-SHA SSLv3 RSA RSA DES(56) SHA1
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
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

SSLCompression Directive

Description:Enable compression on the SSL level
Syntax:SSLCompression on|off
Default:SSLCompression off
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.3 and later, if using OpenSSL 0.9.8 or later; virtual host scope available if using OpenSSL 1.0.0 or later. The default used to be on in version 2.4.3.

This directive allows to enable compression on the SSL level.

Enabling compression causes security issues in most setups (the so called CRIME attack).

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

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

With OpenSSL 3.0 or later, if no engine is specified but the key or certificate is specified using a PKCS#11 URIs then it is tried to load the key and certificate from an OpenSSL provider. The OpenSSL provider to use must be defined and configured in the OpenSSL config file, and it must support the STORE method for PKCS#11 URIs.

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 should be used inside a <VirtualHost> section to enable SSL/TLS for a that 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>

In Apache 2.1 and later, 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

SSLFIPS Directive

Description:SSL FIPS mode Switch
Syntax:SSLFIPS on|off
Default:SSLFIPS off
Context:server config
Status:Extension
Module:mod_ssl

This directive toggles the usage of the SSL library FIPS_mode flag. It must be set in the global server context and cannot be configured with conflicting settings (SSLFIPS on followed by SSLFIPS off or similar). The mode applies to all SSL library operations.

If httpd was compiled against an SSL library which did not support the FIPS_mode flag, SSLFIPS on will fail. Refer to the FIPS 140-2 Security Policy document of the SSL provider library for specific requirements to use mod_ssl in a FIPS 140-2 approved mode of operation; note that mod_ssl itself is not validated, but may be described as using FIPS 140-2 validated cryptographic module, when all components are assembled and operated under the guidelines imposed by the applicable Security Policy.

top

SSLHonorCipherOrder Directive

Description:Option to prefer the server's cipher preference order
Syntax:SSLHonorCipherOrder on|off
Default:SSLHonorCipherOrder off
Context:server config, virtual host
Status:Extension
Module:mod_ssl

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

SSLInsecureRenegotiation Directive

Description:Option to enable support for insecure renegotiation
Syntax:SSLInsecureRenegotiation on|off
Default:SSLInsecureRenegotiation off
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.2.15 and later, if using OpenSSL 0.9.8m or later

As originally specified, all versions of the SSL and TLS protocols (up to and including TLS/1.2) were vulnerable to a Man-in-the-Middle attack (CVE-2009-3555) during a renegotiation. This vulnerability allowed an attacker to "prefix" a chosen plaintext to the HTTP request as seen by the web server. A protocol extension was developed which fixed this vulnerability if supported by both client and server.

If mod_ssl is linked against OpenSSL version 0.9.8m or later, by default renegotiation is only supported with clients supporting the new protocol extension. If this directive is enabled, renegotiation will be allowed with old (unpatched) clients, albeit insecurely.

Security warning

If this directive is enabled, SSL connections will be vulnerable to the Man-in-the-Middle prefix attack as described in CVE-2009-3555.

Example

SSLInsecureRenegotiation on

The SSL_SECURE_RENEG environment variable can be used from an SSI or CGI script to determine whether secure renegotiation is supported for a given SSL connection.

top

SSLOCSPDefaultResponder Directive

Description:Set the default responder URI for OCSP validation
Syntax:SSLOCSPDefaultResponder uri
Context:server config, virtual host
Status:Extension
Module:mod_ssl

This option sets the default OCSP responder to use. If SSLOCSPOverrideResponder is not enabled, the URI given will be used only if no responder URI is specified in the certificate being verified.

top

SSLOCSPEnable Directive

Description:Enable OCSP validation of the client certificate chain
Syntax:SSLOCSPEnable on|leaf|off
Default:SSLOCSPEnable off
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Mode leaf available in httpd 2.4.34 and later

This option enables OCSP validation of the client certificate chain. If this option is enabled, certificates in the client's certificate chain will be validated against an OCSP responder after normal verification (including CRL checks) have taken place. In mode 'leaf', only the client certificate itself will be validated.

The OCSP responder used is either extracted from the certificate itself, or derived by configuration; see the SSLOCSPDefaultResponder and SSLOCSPOverrideResponder directives.

Example

SSLVerifyClient on
SSLOCSPEnable on
SSLOCSPDefaultResponder "http://responder.example.com:8888/responder"
SSLOCSPOverrideResponder on
top

SSLOCSPNoverify Directive

Description:skip the OCSP responder certificates verification
Syntax:SSLOCSPNoverify on|off
Default:SSLOCSPNoverify off
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.26 and later, if using OpenSSL 0.9.7 or later

Skip the OCSP responder certificates verification, mostly useful when testing an OCSP server.

top

SSLOCSPOverrideResponder Directive

Description:Force use of the default responder URI for OCSP validation
Syntax:SSLOCSPOverrideResponder on|off
Default:SSLOCSPOverrideResponder off
Context:server config, virtual host
Status:Extension
Module:mod_ssl

This option forces the configured default OCSP responder to be used during OCSP certificate validation, regardless of whether the certificate being validated references an OCSP responder.

top

SSLOCSPProxyURL Directive

Description:Proxy URL to use for OCSP requests
Syntax:SSLOCSPProxyURL url
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.19 and later

This option allows to set the URL of a HTTP proxy that should be used for all queries to OCSP responders.

top

SSLOCSPResponderCertificateFile Directive

Description:Set of trusted PEM encoded OCSP responder certificates
Syntax:SSLOCSPResponderCertificateFile file
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.26 and later, if using OpenSSL 0.9.7 or later

This supplies a list of trusted OCSP responder certificates to be used during OCSP responder certificate validation. The supplied certificates are implicitly trusted without any further validation. This is typically used where the OCSP responder certificate is self signed or omitted from the OCSP response.

top

SSLOCSPResponderTimeout Directive

Description:Timeout for OCSP queries
Syntax:SSLOCSPResponderTimeout seconds
Default:SSLOCSPResponderTimeout 10
Context:server config, virtual host
Status:Extension
Module:mod_ssl

This option sets the timeout for queries to OCSP responders, when SSLOCSPEnable is turned on.

top

SSLOCSPResponseMaxAge Directive

Description:Maximum allowable age for OCSP responses
Syntax:SSLOCSPResponseMaxAge seconds
Default:SSLOCSPResponseMaxAge -1
Context:server config, virtual host
Status:Extension
Module:mod_ssl

This option sets the maximum allowable age ("freshness") for OCSP responses. The default value (-1) does not enforce a maximum age, which means that OCSP responses are considered valid as long as their nextUpdate field is in the future.

top

SSLOCSPResponseTimeSkew Directive

Description:Maximum allowable time skew for OCSP response validation
Syntax:SSLOCSPResponseTimeSkew seconds
Default:SSLOCSPResponseTimeSkew 300
Context:server config, virtual host
Status:Extension
Module:mod_ssl

This option sets the maximum allowable time skew for OCSP responses (when checking their thisUpdate and nextUpdate fields).

top

SSLOCSPUseRequestNonce Directive

Description:Use a nonce within OCSP queries
Syntax:SSLOCSPUseRequestNonce on|off
Default:SSLOCSPUseRequestNonce on
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.10 and later

This option determines whether queries to OCSP responders should contain a nonce or not. By default, a query nonce is always used and checked against the response's one. When the responder does not use nonces (e.g. Microsoft OCSP Responder), this option should be turned off.

top

SSLOpenSSLConfCmd Directive

Description:Configure OpenSSL parameters through its SSL_CONF API
Syntax:SSLOpenSSLConfCmd command-name command-value
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.8 and later, if using OpenSSL 1.0.2 or later

This directive exposes OpenSSL's SSL_CONF API to mod_ssl, allowing a flexible configuration of OpenSSL parameters without the need of implementing additional mod_ssl directives when new features are added to OpenSSL.

The set of available SSLOpenSSLConfCmd commands depends on the OpenSSL version being used for mod_ssl (at least version 1.0.2 is required). For a list of supported command names, see the section Supported configuration file commands in the SSL_CONF_cmd(3) manual page for OpenSSL.

Some of the SSLOpenSSLConfCmd commands can be used as an alternative to existing directives (such as SSLCipherSuite or SSLProtocol), though it should be noted that the syntax / allowable values for the parameters may sometimes differ.

Examples

SSLOpenSSLConfCmd Options -SessionTicket,ServerPreference
SSLOpenSSLConfCmd ECDHParameters brainpoolP256r1
SSLOpenSSLConfCmd ServerInfoFile "/usr/local/apache2/conf/server-info.pem"
SSLOpenSSLConfCmd Protocol "-ALL, TLSv1.2"
SSLOpenSSLConfCmd SignatureAlgorithms RSA+SHA384:ECDSA+SHA256
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:

Example

SSLOptions +FakeBasicAuth -StrictRequire
<Files ~ "\.(cgi|shtml)$">
    SSLOptions +StdEnvVars -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:

Example

SSLPassPhraseDialog "exec:/usr/local/apache/sbin/pp-filter"
top

SSLProtocol Directive

Description:Configure usable SSL/TLS protocol versions
Syntax:SSLProtocol [+|-]protocol ...
Default:SSLProtocol all -SSLv3 (up to 2.4.16: all)
Context:server config, virtual host
Status:Extension
Module:mod_ssl

This directive can be used to control which versions of the SSL/TLS protocol will be accepted in new connections.

The available (case-insensitive) protocols are:

Example

SSLProtocol TLSv1

SSLProtocol for name-based virtual hosts

Before OpenSSL 1.1.1, even though the Server Name Indication (SNI) allowed to determine the targeted virtual host early in the TLS handshake, it was not possible to switch the TLS protocol version of the connection at this point, and thus the SSLProtocol negotiated was always based off the one of the base virtual host (first virtual host declared on the listening IP:port of the connection).

Beginning with Apache HTTP server version 2.4.42, when built/linked against OpenSSL 1.1.1 or later, and when the SNI is provided by the client in the TLS handshake, the SSLProtocol of each (name-based) virtual host can and will be honored.

For compatibility with previous versions, if no SSLProtocol is configured in a name-based virtual host, the one from the base virtual host still applies, unless SSLProtocol is configured globally in which case the global value applies (this latter exception is more sensible than compatible, though).

top

SSLProxyCACertificateFile Directive

Description:File of concatenated PEM-encoded CA Certificates for Remote Server Auth
Syntax:SSLProxyCACertificateFile file-path
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

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, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

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.

Example

SSLProxyCACertificatePath "/usr/local/apache2/conf/ssl.crt/"
top

SSLProxyCARevocationCheck Directive

Description:Enable CRL-based revocation checking for Remote Server Auth
Syntax:SSLProxyCARevocationCheck chain|leaf|none
Default:SSLProxyCARevocationCheck none
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

Enables certificate revocation list (CRL) checking for the remote servers you deal with. At least one of SSLProxyCARevocationFile or SSLProxyCARevocationPath must be configured. When set to chain (recommended setting), CRL checks are applied to all certificates in the chain, while setting it to leaf limits the checks to the end-entity cert.

When set to chain or leaf, CRLs must be available for successful validation

Prior to version 2.3.15, CRL checking in mod_ssl also succeeded when no CRL(s) were found in any of the locations configured with SSLProxyCARevocationFile or SSLProxyCARevocationPath. With the introduction of this directive, the behavior has been changed: when checking is enabled, CRLs must be present for the validation to succeed - otherwise it will fail with an "unable to get certificate CRL" error.

Example

SSLProxyCARevocationCheck chain
top

SSLProxyCARevocationFile Directive

Description:File of concatenated PEM-encoded CA CRLs for Remote Server Auth
Syntax:SSLProxyCARevocationFile file-path
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

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, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

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.

Example

SSLProxyCARevocationPath "/usr/local/apache2/conf/ssl.crl/"
top

SSLProxyCheckPeerCN Directive

Description:Whether to check the remote server certificate's CN field
Syntax:SSLProxyCheckPeerCN on|off
Default:SSLProxyCheckPeerCN on
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

This directive sets whether the remote server certificate's CN field is compared against the hostname of the request URL. If both are not equal a 502 status code (Bad Gateway) is sent. SSLProxyCheckPeerCN is superseded by SSLProxyCheckPeerName in release 2.4.5 and later.

In all releases 2.4.5 through 2.4.20, setting SSLProxyCheckPeerName off was sufficient to enable this behavior (as the SSLProxyCheckPeerCN default was on.) In these releases, both directives must be set to off to completely avoid remote server certificate name validation. Many users reported this to be very confusing.

As of release 2.4.21, all configurations which enable either one of the SSLProxyCheckPeerName or SSLProxyCheckPeerCN options will use the new SSLProxyCheckPeerName behavior, and all configurations which disable either one of the SSLProxyCheckPeerName or SSLProxyCheckPeerCN options will suppress all remote server certificate name validation. Only the following configuration will trigger the legacy certificate CN comparison in 2.4.21 and later releases;

Example

SSLProxyCheckPeerCN on
SSLProxyCheckPeerName off
top

SSLProxyCheckPeerExpire Directive

Description:Whether to check if remote server certificate is expired
Syntax:SSLProxyCheckPeerExpire on|off
Default:SSLProxyCheckPeerExpire on
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

This directive sets whether it is checked if the remote server certificate is expired or not. If the check fails a 502 status code (Bad Gateway) is sent.

Example

SSLProxyCheckPeerExpire on
top

SSLProxyCheckPeerName Directive

Description:Configure host name checking for remote server certificates
Syntax:SSLProxyCheckPeerName on|off
Default:SSLProxyCheckPeerName on
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:Apache HTTP Server 2.4.5 and later
The proxy section context is allowed in httpd 2.4.30 and later

This directive configures host name checking for server certificates when mod_ssl is acting as an SSL client. The check will succeed if the host name from the request URI matches one of the CN attribute(s) of the certificate's subject, or matches the subjectAltName extension. If the check fails, the SSL request is aborted and a 502 status code (Bad Gateway) is returned.

Wildcard matching is supported for specific cases: an subjectAltName entry of type dNSName, or CN attributes starting with *. will match with any host name of the same number of name elements and the same suffix. E.g. *.example.org will match foo.example.org, but will not match foo.bar.example.org, because the number of elements in the respective host names differs.

This feature was introduced in 2.4.5 and superseded the behavior of the SSLProxyCheckPeerCN directive, which only tested the exact value in the first CN attribute against the host name. However, many users were confused by the behavior of using these directives individually, so the mutual behavior of SSLProxyCheckPeerName and SSLProxyCheckPeerCN directives were improved in release 2.4.21. See the SSLProxyCheckPeerCN directive description for the original behavior and details of these improvements.

top

SSLProxyCipherSuite Directive

Description:Cipher Suite available for negotiation in SSL proxy handshake
Syntax:SSLProxyCipherSuite [protocol] cipher-spec
Default:SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

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, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

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 both for the main server and all configured virtual hosts.

Note that the SSLProxyEngine directive should not, in general, be included in a virtual host that will be acting as a forward proxy (using <Proxy> or ProxyRequests directives). SSLProxyEngine is not required to enable a forward proxy server to proxy SSL/TLS requests.

Example

<VirtualHost _default_:443>
    SSLProxyEngine on
    #...
</VirtualHost>
top

SSLProxyMachineCertificateChainFile Directive

Description:File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
Syntax:SSLProxyMachineCertificateChainFile filename
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

This directive sets the all-in-one file where you keep the certificate chain for all of the client certs in use. This directive will be needed if the remote server presents a list of CA certificates that are not direct signers of one of the configured client certificates.

This referenced file is simply the concatenation of the various PEM-encoded certificate files. Upon startup, each client certificate configured will be examined and a chain of trust will be constructed.

Security warning

If this directive is enabled, all of the certificates in the file will be trusted as if they were also in SSLProxyCACertificateFile.

Example

SSLProxyMachineCertificateChainFile "/usr/local/apache2/conf/ssl.crt/proxyCA.pem"
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, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later
Inclusion of non-leaf (CA) certificates is permitted only in httpd 2.4.59 and later.

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. Use this directive alternatively or additionally to SSLProxyMachineCertificatePath. The referenced file can contain any number of pairs of client certificate and associated private key. Each pair can be specified in either (certificate, key) or (key, certificate) order. Non-leaf (CA) certificates can also be included in the file, and are treated as if configured with SSLProxyMachineCertificateChainFile.

When challenged to provide a client certificate by a remote server, the server should provide a list of acceptable certificate authority names in the challenge. If such a list is not provided, mod_ssl will use the first configured client cert/key. If a list of CA names is provided, mod_ssl will iterate through that list, and attempt to find a configured client cert which was issued either directly by that CA, or indirectly via any number of intermediary CA certificates. The chain of intermediate CA certificates can be built from those included in the file, or configured with SSLProxyMachineCertificateChainFile. The first configured matching certificate will then be supplied in response to the challenge.

If the list of CA names is provided by the remote server, and no matching client certificate can be found, no client certificate will be provided by mod_ssl, which will likely fail the SSL/TLS handshake (depending on the remote server configuration).

Currently there is no support for encrypted private keys

Only keys encoded in PKCS1 RSA, DSA or EC format are supported. Keys encoded in PKCS8 format, ie. starting with "-----BEGIN PRIVATE KEY-----", must be converted, eg. using "openssl rsa -in private-pkcs8.pem -outform pem".

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, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

This directive sets the directory where you keep the client certificates and keys used for authentication of the proxy server to remote servers.

mod_ssl will attempt to load every file inside the specified directory as if it was configured individually with SSLProxyMachineCertificateFile.

Currently there is no support for encrypted private keys

Only keys encoded in PKCS1 RSA, DSA or EC format are supported. Keys encoded in PKCS8 format, ie. starting with "-----BEGIN PRIVATE KEY-----", must be converted, eg. using "openssl rsa -in private-pkcs8.pem -outform pem".

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 -SSLv3 (up to 2.4.16: all)
Context:server config, virtual host, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

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, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

When a proxy is configured to forward requests to a remote SSL server, this directive can be used to configure certificate verification of the remote server.

The following levels are available for level:

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, proxy section
Status:Extension
Module:mod_ssl
Compatibility:The proxy section context is allowed in httpd 2.4.30 and later

This directive sets how deeply mod_ssl should verify before deciding that the remote server does not have a valid certificate.

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:

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

SSLRenegBufferSize Directive

Description:Set the size for the SSL renegotiation buffer
Syntax:SSLRenegBufferSize bytes
Default:SSLRenegBufferSize 131072
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_ssl

If an SSL renegotiation is required in per-location context, for example, any use of SSLVerifyClient in a Directory or Location block, then mod_ssl must buffer any HTTP request body into memory until the new SSL handshake can be performed. This directive can be used to set the amount of memory that will be used for this buffer.

Note that in many configurations, the client sending the request body will be untrusted so a denial of service attack by consumption of memory must be considered when changing this configuration setting.

Example

SSLRenegBufferSize 262144
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

SSLRequire is deprecated

SSLRequire is deprecated and should in general be replaced by Require expr. The so called ap_expr syntax of Require expr is a superset of the syntax of SSLRequire, with the following exception:

In SSLRequire, the comparison operators <, <=, ... are completely equivalent to the operators lt, le, ... and work in a somewhat peculiar way that first compares the length of two strings and then the lexical order. On the other hand, ap_expr has two sets of comparison operators: The operators <, <=, ... do lexical string comparison, while the operators -lt, -le, ... do integer comparison. For the latter, there are also aliases without the leading dashes: lt, le, ...

This directive specifies a general access requirement which has to be fulfilled in order to allow access. It is a very powerful directive because the requirement specification is an arbitrarily complex boolean expression containing any number of access checks.

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 "in" "PeerExtList(" word ")"
           | word "=~" regex
           | word "!~" regex

wordlist ::= word
           | wordlist "," word

word     ::= digit
           | cstring
           | variable
           | function

digit    ::= [0-9]+
cstring  ::= "..."
variable ::= "%{" varname "}"
function ::= funcname "(" funcargs ")"

For varname any of the variables described in Environment Variables can be used. For funcname the available functions are listed in the ap_expr documentation.

The expression is parsed into an internal machine representation when the configuration is loaded, and then evaluated during request processing. In .htaccess context, the expression is both parsed and executed each time the .htaccess file is encountered during request processing.

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} -ge 1 and %{TIME_WDAY} -le 5          \
            and %{TIME_HOUR} -ge 8 and %{TIME_HOUR} -le 20       ) \
           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/

The PeerExtList(object-ID) function expects to find zero or more instances of the X.509 certificate extension identified by the given object ID (OID) in the client certificate. The expression evaluates to true if the left-hand side string matches exactly against the value of an extension identified with this OID. (If multiple extensions with the same OID are present, at least one extension must match).

Example

SSLRequire "foobar" in PeerExtList("1.2.3.4.5.6")

Notes on the PeerExtList function

  • The object ID can be specified either as a descriptive name recognized by the SSL library, such as "nsComment", or as a numeric OID, such as "1.2.3.4.5.6".

  • Expressions with types known to the SSL library are rendered to a string before comparison. For an extension with a type not recognized by the SSL library, mod_ssl will parse the value if it is one of the primitive ASN.1 types UTF8String, IA5String, VisibleString, or BMPString. For an extension of one of these types, the string value will be converted to UTF-8 if necessary, then compared against the left-hand-side expression.

See also

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 unnecessary session handshakes.

The following five storage types are currently supported:

Examples

SSLSessionCache "dbm:/usr/local/apache/logs/ssl_gcache_data"
SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_gcache_data(512000)"

The ssl-cache mutex is used to serialize access to the session cache to prevent corruption. This mutex can be configured using the Mutex directive.

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
Compatibility:Applies also to RFC 5077 TLS session resumption in Apache 2.4.10 and later

This directive sets the timeout in seconds for the information stored in the global/inter-process SSL Session Cache, the OpenSSL internal memory cache and for sessions resumed by TLS session resumption (RFC 5077). 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

SSLSessionTicketKeyFile Directive

Description:Persistent encryption/decryption key for TLS session tickets
Syntax:SSLSessionTicketKeyFile file-path
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.0 and later, if using OpenSSL 0.9.8h or later

Optionally configures a secret key for encrypting and decrypting TLS session tickets, as defined in RFC 5077. Primarily suitable for clustered environments where TLS sessions information should be shared between multiple nodes. For single-instance httpd setups, it is recommended to not configure a ticket key file, but to rely on (random) keys generated by mod_ssl at startup, instead.

The ticket key file must contain 48 bytes of random data, preferably created from a high-entropy source. On a Unix-based system, a ticket key file can be created as follows:

dd if=/dev/random of=/path/to/file.tkey bs=1 count=48

Ticket keys should be rotated (replaced) on a frequent basis, as this is the only way to invalidate an existing session ticket - OpenSSL currently doesn't allow to specify a limit for ticket lifetimes. A new ticket key only gets used after restarting the web server. All existing session tickets become invalid after a restart.

The ticket key file contains sensitive keying material and should be protected with file permissions similar to those used for SSLCertificateKeyFile.

top

SSLSessionTickets Directive

Description:Enable or disable use of TLS session tickets
Syntax:SSLSessionTickets on|off
Default:SSLSessionTickets on
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.11 and later, if using OpenSSL 0.9.8f or later.

This directive allows to enable or disable the use of TLS session tickets (RFC 5077).

TLS session tickets are enabled by default. Using them without restarting the web server with an appropriate frequency (e.g. daily) compromises perfect forward secrecy.

top

SSLSRPUnknownUserSeed Directive

Description:SRP unknown user seed
Syntax:SSLSRPUnknownUserSeed secret-string
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.4 and later, if using OpenSSL 1.0.1 or later

This directive sets the seed used to fake SRP user parameters for unknown users, to avoid leaking whether a given user exists. Specify a secret string. If this directive is not used, then Apache will return the UNKNOWN_PSK_IDENTITY alert to clients who specify an unknown username.

Example

SSLSRPUnknownUserSeed "secret"

top

SSLSRPVerifierFile Directive

Description:Path to SRP verifier file
Syntax:SSLSRPVerifierFile file-path
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in httpd 2.4.4 and later, if using OpenSSL 1.0.1 or later

This directive enables TLS-SRP and sets the path to the OpenSSL SRP (Secure Remote Password) verifier file containing TLS-SRP usernames, verifiers, salts, and group parameters.

Example

SSLSRPVerifierFile "/path/to/file.srpv"

The verifier file can be created with the openssl command line utility:

Creating the SRP verifier file

openssl srp -srpvfile passwd.srpv -userinfo "some info" -add username

The value given with the optional -userinfo parameter is available in the SSL_SRP_USERINFO request environment variable.

top

SSLStaplingCache Directive

Description:Configures the OCSP stapling cache
Syntax:SSLStaplingCache type
Context:server config
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

Configures the cache used to store OCSP responses which get included in the TLS handshake if SSLUseStapling is enabled. Configuration of a cache is mandatory for OCSP stapling. With the exception of none and nonenotnull, the same storage types are supported as with SSLSessionCache.

top

SSLStaplingErrorCacheTimeout Directive

Description:Number of seconds before expiring invalid responses in the OCSP stapling cache
Syntax:SSLStaplingErrorCacheTimeout seconds
Default:SSLStaplingErrorCacheTimeout 600
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

Sets the timeout in seconds before invalid responses in the OCSP stapling cache (configured through SSLStaplingCache) will expire. To set the cache timeout for valid responses, see SSLStaplingStandardCacheTimeout.

top

SSLStaplingFakeTryLater Directive

Description:Synthesize "tryLater" responses for failed OCSP stapling queries
Syntax:SSLStaplingFakeTryLater on|off
Default:SSLStaplingFakeTryLater on
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

When enabled and a query to an OCSP responder for stapling purposes fails, mod_ssl will synthesize a "tryLater" response for the client. Only effective if SSLStaplingReturnResponderErrors is also enabled.

top

SSLStaplingForceURL Directive

Description:Override the OCSP responder URI specified in the certificate's AIA extension
Syntax:SSLStaplingForceURL uri
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

This directive overrides the URI of an OCSP responder as obtained from the authorityInfoAccess (AIA) extension of the certificate. One potential use is when a proxy is used for retrieving OCSP queries.

top

SSLStaplingResponderTimeout Directive

Description:Timeout for OCSP stapling queries
Syntax:SSLStaplingResponderTimeout seconds
Default:SSLStaplingResponderTimeout 10
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

This option sets the timeout for queries to OCSP responders when SSLUseStapling is enabled and mod_ssl is querying a responder for OCSP stapling purposes.

top

SSLStaplingResponseMaxAge Directive

Description:Maximum allowable age for OCSP stapling responses
Syntax:SSLStaplingResponseMaxAge seconds
Default:SSLStaplingResponseMaxAge -1
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

This option sets the maximum allowable age ("freshness") when considering OCSP responses for stapling purposes, i.e. when SSLUseStapling is turned on. The default value (-1) does not enforce a maximum age, which means that OCSP responses are considered valid as long as their nextUpdate field is in the future.

top

SSLStaplingResponseTimeSkew Directive

Description:Maximum allowable time skew for OCSP stapling response validation
Syntax:SSLStaplingResponseTimeSkew seconds
Default:SSLStaplingResponseTimeSkew 300
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

This option sets the maximum allowable time skew when mod_ssl checks the thisUpdate and nextUpdate fields of OCSP responses which get included in the TLS handshake (OCSP stapling). Only applicable if SSLUseStapling is turned on.

top

SSLStaplingReturnResponderErrors Directive

Description:Pass stapling related OCSP errors on to client
Syntax:SSLStaplingReturnResponderErrors on|off
Default:SSLStaplingReturnResponderErrors on
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

When enabled, mod_ssl will pass responses from unsuccessful stapling related OCSP queries (such as responses with an overall status other than "successful", responses with a certificate status other than "good", expired responses etc.) on to the client. If set to off, only responses indicating a certificate status of "good" will be included in the TLS handshake.

top

SSLStaplingStandardCacheTimeout Directive

Description:Number of seconds before expiring responses in the OCSP stapling cache
Syntax:SSLStaplingStandardCacheTimeout seconds
Default:SSLStaplingStandardCacheTimeout 3600
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

Sets the timeout in seconds before responses in the OCSP stapling cache (configured through SSLStaplingCache) will expire. This directive applies to valid responses, while SSLStaplingErrorCacheTimeout is used for controlling the timeout for invalid/unavailable responses.

top

SSLStrictSNIVHostCheck Directive

Description:Whether to allow non-SNI clients to access a name-based virtual host.
Syntax:SSLStrictSNIVHostCheck on|off
Default:SSLStrictSNIVHostCheck off
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available in Apache 2.2.12 and later

This directive sets whether a non-SNI client is allowed to access a name-based virtual host. If set to on in the default name-based virtual host, clients that are SNI unaware will not be allowed to access any virtual host, belonging to this particular IP / port combination. If set to on in any other virtual host, SNI unaware clients are not allowed to access this particular virtual host.

This option is only available if httpd was compiled against an SNI capable version of OpenSSL.

Example

SSLStrictSNIVHostCheck on
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

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 FakeBasicAuth option is used (see SSLOptions).

Example

SSLUserName SSL_CLIENT_S_DN_CN
top

SSLUseStapling Directive

Description:Enable stapling of OCSP responses in the TLS handshake
Syntax:SSLUseStapling on|off
Default:SSLUseStapling off
Context:server config, virtual host
Status:Extension
Module:mod_ssl
Compatibility:Available if using OpenSSL 0.9.8h or later

This option enables OCSP stapling, as defined by the "Certificate Status Request" TLS extension specified in RFC 6066. If enabled (and requested by the client), mod_ssl will include an OCSP response for its own certificate in the TLS handshake. Configuring an SSLStaplingCache is a prerequisite for enabling OCSP stapling.

OCSP stapling relieves the client of querying the OCSP responder on its own, but it should be noted that with the RFC 6066 specification, the server's CertificateStatus reply may only include an OCSP response for a single cert. For server certificates with intermediate CA certificates in their chain (the typical case nowadays), stapling in its current implementation therefore only partially achieves the stated goal of "saving roundtrips and resources" - see also RFC 6961 (TLS Multiple Certificate Status Extension).

When OCSP stapling is enabled, the ssl-stapling mutex is used to control access to the OCSP stapling cache in order to prevent corruption, and the sss-stapling-refresh mutex is used to control refreshes of OCSP responses. These mutexes can be configured using the Mutex directive.

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 renegotiation 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:

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 renegotiation 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  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_common.html.de0000664000175100017510000017574014744525602021253 0ustar covenercovener mpm_common - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Allgemeine Direktiven der Apache-MPMs

Verfügbare Sprachen:  de  |  en  |  fr  |  ja  |  tr 

Diese Übersetzung ist möglicherweise nicht mehr aktuell. Bitte prüfen Sie die englische Version auf die neuesten Änderungen.
Beschreibung:Eine Sammlung von Direktiven, die in mehr als einem Multi-Processing-Modul (MPM) implementiert sind.
Status:MPM
Support Apache!

Direktiven

Bugfix checklist

Siehe auch

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

GracefulShutdownTimeout-Direktive

Beschreibung:Specify a timeout after which a gracefully shutdown server will exit.
Syntax:GracefulShutdownTimeout seconds
Voreinstellung:GracefulShutdownTimeout 0
Kontext:Serverkonfiguration
Status:MPM
Modul:event, worker, prefork
Kompatibilität:Available in version 2.2 and later

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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 [2001:db8::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

ListenCoresBucketsRatio-Direktive

Beschreibung:Ratio between the number of CPU cores (online) and the number of listeners' buckets
Syntax:ListenCoresBucketsRatio ratio
Voreinstellung:ListenCoresBucketsRatio 0 (disabled)
Kontext:Serverkonfiguration
Status:MPM
Modul:event, worker, prefork
Kompatibilität:Available in Apache HTTP Server 2.4.17, with a kernel supporting the socket option SO_REUSEPORT and distributing new connections evenly across listening processes' (or threads') sockets using it (eg. Linux 3.9 and later, but not the current implementations of SO_REUSEPORT in *BSDs.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

top

MaxConnectionsPerChild-Direktive

Beschreibung:Limit on the number of connections that an individual child server will handle during its life
Syntax:MaxConnectionsPerChild number
Voreinstellung:MaxConnectionsPerChild 0
Kontext:Serverkonfiguration
Status:MPM
Modul:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
Kompatibilität:Available Apache HTTP Server 2.3.9 and later. The old name MaxRequestsPerChild is still supported.

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

MaxRequestWorkers-Direktive

Beschreibung:Maximum number of connections that will be processed simultaneously
Syntax:MaxRequestWorkers number
Voreinstellung:See usage for details
Kontext:Serverkonfiguration
Status:MPM
Modul:event, worker, prefork

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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

ReceiveBufferSize-Direktive

Beschreibung:TCP receive buffer size
Syntax:ReceiveBufferSize bytes
Voreinstellung:ReceiveBufferSize 0
Kontext:Serverkonfiguration
Status:MPM
Modul:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

Die Dokumentation zu dieser Direktive wurde noch nicht übersetzt. Bitte schauen Sie in die englische Version.

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:

Verfügbare Sprachen:  de  |  en  |  fr  |  ja  |  tr 

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/worker.html.de0000664000175100017510000003744514744525602020422 0ustar covenercovener worker - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Apache-MPM worker

Verfügbare Sprachen:  de  |  en  |  fr  |  ja  |  tr 

Diese Übersetzung ist möglicherweise nicht mehr aktuell. Bitte prüfen Sie die englische Version auf die neuesten Änderungen.
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.

Support Apache!

Themen

Direktiven

Bugfix checklist

Siehe auch

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  |  fr  |  ja  |  tr 

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_config.html.fr.utf80000664000175100017510000011371714740503670022754 0ustar covenercovener mod_log_config - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_log_config

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Journalisation des requêtes envoyées au serveur
Statut:Base
Identificateur de Module:log_config_module
Fichier Source:mod_log_config.c

Sommaire

Ce module apporte une grande souplesse dans la journalisation des requêtes des clients. Les journaux sont écrits sous un format personnalisable, et peuvent être enregistrés directement dans un fichier, ou redirigés vers un programme externe. La journalisation conditionnelle est supportée, si bien que des requêtes individuelles peuvent être incluses ou exclues des journaux en fonction de leur caractéristiques.

Ce module fournit trois directives : TransferLog crée un fichier journal, LogFormat définit un format personnalisé, et CustomLog définit un fichier journal et un format en une seule étape. Pour journaliser les requêtes dans plusieurs fichiers, vous pouvez utiliser plusieurs fois les directives TransferLog et CustomLog dans chaque serveur.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Formats de journaux personnalisés

L'argument format des directives LogFormat et CustomLog est une chaîne de caractères. Cette chaîne définit le format de la journalisation des requêtes dans le fichier journal. Elle peut contenir des caractères littéraux qui seront reproduits dans le fichier journal, et les caractères de contrôle de style C "\n" et "\t" représentant respectivement une nouvelle ligne et une tabulation. Les guillemets et les anti-slashes littéraux doivent être échappés à l'aide d'anti-slashes.

Les caractéristiques de la requête en elle-même sont journalisées en insérant des directives "%" dans la chaîne de format, celles-ci étant remplacées dans le fichier journal par certaines valeurs comme suit :

Chaîne de format Description
%% Le signe "pourcentage"
%a L'adresse IP distante (voir le module mod_remoteip).
%{c}a Adresse IP distante de la connexion(voir le module mod_remoteip)
%A L'adresse IP locale
%B La taille de la réponse en octets, en excluant les en-têtes HTTP.
%b La taille de la réponse en octets, en excluant les en-têtes HTTP. Au format CLF , c'est à dire un '-' à la place d'un 0 lorsqu'aucun octet n'est renvoyé.
%{NOMVAR}C Le contenu du cookie NOMVAR dans la requête envoyée au serveur. Seuls les cookies version 0 sont pleinement supportés.
%D Le temps mis à servir la requête, en microsecondes.
%{NOMVAR}e Le contenu de la variable d'environnement NOMVAR
%f Nom de fichier
%h Serveur distant. Contiendra l'adresse IP si la directive HostnameLookups est définie à Off, ce qui est sa valeur par défaut. Si cette adresse IP n'est enregistrée que pour certains serveurs, vous avez probablement défini des directives de contrôle d'accès qui mentionnent ces derniers par leurs noms. Voir la documentation de Require host.
%{c}h Semblable à %h, mais exploite toujours le nom d'hôte de la connection TCP sous-jacente, en ignorant toute modification réalisée sur le nom d'hôte distant par des modules tels que mod_remoteip.
%H Le protocole de la requête
%{NOMVAR}i Le contenu des lignes d'en-tête NOMVAR: dans la requête envoyée au serveur. Ces en-têtes sont ajoutés par d'autres modules (par exemple mod_headers). Si vous êtes intéressé par ce qu'était l'en-tête de la requête avant d'être modifié par la plupart des modules, utilisez mod_setenvif pour copier l'en-tête dans une variable d'environnement interne et journaliser sa valeur via le champ %{VARNAME}e décrit plus haut.
%k Nombre de requêtes persistantes en cours pour cette connexion. Interessant si la directive KeepAlive est utilisée ; par exemple, '1' signifie la première requête après la requête initiale, '2' la seconde, etc... ; autrement, il s'agit toujours de 0 (indiquant la requête initiale).
%l Le nom de connexion distant (en provenance d'identd, si disponible). Affiche un tiret, sauf si mod_ident est présent et si IdentityCheck est à On.
%L L'identifiant du message de journalisation de la requête dans le journal des erreurs (ou '-' si aucun message n'a été enregistré dans le journal des erreurs pour cette requête)
%m La méthode de la requête
%{NOMVAR}n Le contenu de la note NOMVAR en provenance d'un autre module.
%{NOMVAR}o Le contenu de la ligne d'en-tête NOMVAR: de la réponse.
%p Le port canonique du serveur servant la requête
%{format}p Le port canonique du serveur servant la requête ou le véritable port du serveur ou le véritable port du client. les formats valides sont canonical, local, ou remote.
%P Le numéro de processus du processus enfant qui a servi la requête.
%{format}P Le numéro de processus ou le numéro de thread du processus enfant qui a servi la requête. Les formats valides sont pid, tid, et hextid.
%q La chaîne d'arguments (préfixée par un ? si une chaîne d'arguments existe, sinon une chaîne vide)
%r La première ligne de la requête
%R Le gestionnaire qui génère la réponse (s'il y en a un).
%s Statut. Pour les requêtes redirigées en interne, il s'agit du statut de la requête *originale* --- %>s pour la dernière.
%t Date à laquelle la requête a été reçue (au format anglais standard)
%{format}t La date, sous la forme spécifiée par format, qui devrait être au format étendu strftime(3) (éventuellement localisé). Si le format commence par begin: (valeur par défaut), la date est extraite au début du traitement de la requête ; s'il commence par end:, la date correspond au moment où l'entrée du journal est inscrite, par conséquent vers la fin du traitement de la requête. Hormis les formats supportés par strftime(3), les formats suivants sont aussi disponibles :
secnombre de secondes depuis Epoch
msecnombre de millisecondes depuis Epoch
usecnombre de microsecondes depuis Epoch
msec_fracfraction de milliseconde
usec_fracfraction de microseconde
Ces symboles ne peuvent pas être combinés entre eux ou avec un formatage strftime(3) dans la même chaîne de format. Par contre, vous pouvez utiliser plusieurs symboles %{format}t.
%T Le temps mis pour servir la requête, en secondes.
%{UNIT}T Le temps mis pour traiter la requête dans une unité définie par UNIT. Les valeurs d'unité valides sont ms pour millisecondes, us pour microsecondes et s pour secondes. Si UNIT est omis, la valeur de l'unité par défaut est la seconde ; spécifier la valeur d'unité us revient à utiliser le format %D. La possibilité de spécifier une valeur d'unité avec le format %T est disponible depuis la version 2.4.13 du serveur HTTP Apache.
%u L'utilisateur distant (en provenance d'auth ; peut être faux si le statut de retour (%s) est 401).
%U Le chemin de la requête, à l'exclusion de toute chaîne d'arguments.
%v Le nom canonique du serveur qui a servi la requête, défini par la directive ServerName.
%V La nom du serveur en tenant compte de la définition de la directive UseCanonicalName.
%X Statut de la connexion lorsque la réponse a été renvoyée :
X = connexion abandonnée avant l'envoi de la réponse.
+ = la connexion peut rester ouverte après l'envoi de la réponse.
- = la connexion sera fermée après l'envoi de la réponse.
%I Le nombre d'octets reçus, en comptant la requête et les en-têtes, ne peut être nul. Nécessite l'activation de mod_logio.
%O Nombre d'octets envoyés, y compris les en-têtes. Peut être nul dans les rares cas où une requête est avortée avant que la réponse ne soit envoyée. Nécessite l'activation de mod_logio.
%S Nombre d'octets transmis (en émission et réception), y compris corps et en-têtes de requête. Ce nombre ne peut pas être nul, et il correspond à la combinaison des formats %I et %O. mod_logio doit être chargé pour pouvoir utiliser ce format.
%{VARNAME}^ti Le contenu de VARNAME: dans les paramètres de la requête envoyée au serveur.
%{VARNAME}^to Le contenu de VARNAME: dans les paramètres de la réponse envoyée par le serveur.

Modificateurs

Il est possible de restreindre l'enregistrement de certains éléments en fonction du code de statut de la réponse, en insérant une liste de codes de statut séparés par des virgules immédiatement après le caractère "%". Par exemple, "%400,501{User-agent}i" n'enregistrera l'en-tête User-agent que dans le cas d'une erreur 400 ou 501. Avec les autres codes de statut, c'est la chaîne littérale "-" qui sera enregistrée. La liste de codes peut être précédée d'un "!" pour inverser la condition : "%!200,304,302{Referer}i" enregistre l'en-tête Referer pour toutes les requêtes qui ne renvoient pas un des trois codes spécifiés.

Les modificateurs "<" et ">" peuvent être utilisés pour les requêtes qui ont été redirigées en interne afin de choisir si c'est respectivement la requête originale ou finale qui doit être consultée. Par défaut, les directives %s, %U, %T, %D, et %r consultent la requête originale, alors que toutes les autres consultent la requête finale. Ainsi, par exemple, on peut utiliser %>s pour enregistrer le statut final de la requête, et %<u pour enregistrer l'utilisateur authentifié à l'origine pour une requête redirigée en interne vers une ressource sans authentification.

Quelques Notes

Pour des raisons de sécurité, à partir de la version 2.0.46, les caractères non imprimables et autres caractères spéciaux dans les directives %r, %i et %o doivent être échappés à l'aide des séquences \xhh, où hh est le code hexadécimal du caractère spécial. Comme exceptions à cette règle, les caractères " et \ doivent être échappés par un anti-slash, et tous les "blancs" doivent être écrits selon leur notation de style C (\n, \t, etc...). Avant la version 2.0.46, aucun échappement n'était effectué sur ces chaînes, et il fallait être très prudent lors de l'exploitation des journaux bruts.

A la différence de la version 1.3, depuis httpd 2.0, les chaînes de format %b et %B ne représentent pas le nombre d'octets envoyés au client, mais simplement la taille en octets de la réponse HTTP (les deux étant différents, par exemple, si la connexion est abandonnée, ou si SSL est utilisé). Le format %O fourni par mod_logio, enregistrera le nombre réel d'octets envoyés sur le réseau.

Note : mod_cache est implémenté en tant que gestionnaire basique et non en tant que gestionnaire standard. C'est pourquoi la chaîne de format %R ne renverra pas d'information à propos du gestionnaire lorsqu'une mise en cache de contenu entre en jeu.

Exemples

Quelques chaînes de format couramment utilisées :

Format de journal courant (CLF)
"%h %l %u %t \"%r\" %>s %b"
Format de journal courant avec un serveur virtuel
"%v %h %l %u %t \"%r\" %>s %b"
Format de journal NCSA étandu/combiné
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
Format de journal de la page qui contient le lien vers la page concernée (Referer)
"%{Referer}i -> %U"
Format de journal de l'agent (Navigateur)
"%{User-agent}i"

Vous pouvez utiliser plusieurs fois la directive %{format}t pour construire un format de temps utilisant les symboles de format étendus tels que msec_frac :

Format de temps prenant en compte les milisecondes
"%{%d/%b/%Y %T}t.%{msec_frac}t %{%z}t"
top

Considérations concernant la sécurité

Voir le document conseils à matière de sécurité pour plus de détails sur les raisons pour lesquelles votre sécurité pourrait être compromise, si le répertoire où sont stockés les fichiers journaux sont inscriptibles par tout autre utilisateur que celui qui démarre le serveur.

top

Directive BufferedLogs

Description:Enregistre les entrées du journal dans un tampon en mémoire avant de les écrire sur disque
Syntaxe:BufferedLogs On|Off
Défaut:BufferedLogs Off
Contexte:configuration globale
Statut:Base
Module:mod_log_config

Lorsque la directive BufferedLogs est à "on", mod_log_config stocke de nombreuses entrées du journal en mémoire, et les écrit d'un seul bloc sur disque, plutôt que de les écrire après chaque requête. Sur certains systèmes, ceci peut améliorer l'efficacité des accès disque, et par conséquent les performances. La directive ne peut être définie qu'une seule fois pour l'ensemble du serveur ; elle ne peut pas être définie au niveau d'un serveur virtuel.

Cette directive doit être utilisée avec précautions car un crash peut provoquer la perte de données de journalisation.
top

Directive CustomLog

Description:Définit le nom et le format du fichier journal
Syntaxe:CustomLog fichier|pipe format|alias [env=[!]variable-environnement| expr=expression]
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_log_config

La directive CustomLog permet de contrôler la journalisation des requêtes destinées au serveur. Un format de journal est spécifié, et la journalisation peut s'effectuer de manière conditionnelle en fonction des caractéristiques de la requête en utilisant des variables d'environnement.

Le premier argument, qui spécifie l'emplacement où les journaux seront écrits, accepte deux types de valeurs :

fichier
Un nom de fichier, relatif au répertoire défini par la directive ServerRoot.
pipe
Le caractère pipe "|", suivi du chemin vers un programme qui recevra les informations de la journalisation sur son entrée standard. Voir les notes à propos de la journalisation redirigée pour plus d'informations.

Sécurité :

Si les journaux sont redirigés vers un programme, ce dernier s'exécutera sous l'utilisateur qui a démarré httpd. Ce sera l'utilisateur root si le serveur a été démarré par root ; vérifiez que le programme est sécurisé.

Note

Lors de la spécification d'un chemin de fichier sur les plate-formes non-Unix, il faut prendre soin de ne pas oublier que seuls les slashes directs doivent être utilisés, même si la plate-forme autorise l'emploi d'anti-slashes. D'une manière générale, c'est une bonne idée que de n'utiliser que des slashes directs dans les fichiers de configuration.

Le second argument permet de définir ce qui va être écrit dans le fichier journal. Il peut contenir soit un alias prédéfini par une directive LogFormat, soit une chaîne de format explicite comme décrit dans la section formats de journaux.

Par exemple, les deux blocs de directives suivants produisent le même effet :

# Journal personnalisé avec alias de format
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog "logs/access_log" common

# Journal personnalisé avec chaîne de format explicite
CustomLog "logs/access_log" "%h %l %u %t \"%r\" %>s %b"

Le troisième argument est optionnel et permet de contrôler si une requête doit être ou non journalisée. Dans le cas d'une clause 'env=!nom', la condition peut être la présence ou l'absence d'une variable particulière dans l'environnement du serveur. Dans le cas d'une clause 'expr=expression', la condition consiste en une expression booléenne quelconque. Si la condition n'est pas vérifiée, la requête ne sera pas journalisée. D'éventuelles références à des en-têtes HTTP dans l'expression rationnelle n'entraîneront pas l'ajout des noms d'en-tête correspondants à l'en-tête Vary.

Les variables d'environnement peuvent être définies au niveau de chaque requête en utilisant les modules mod_setenvif et/ou mod_rewrite. Par exemple, si vous voulez enregistrer les requêtes pour toutes les images GIF sur votre serveur dans un fichier journal séparé, et pas dans votre journal principal, vous pouvez utiliser :

SetEnvIf Request_URI \.gif$ gif-image
CustomLog "gif-requests.log" common env=gif-image
CustomLog "nongif-requests.log" common env=!gif-image

Ou, pour reproduire le comportement de l'ancienne directive RefererIgnore, vous pouvez utiliser :

SetEnvIf Referer example\.com localreferer
CustomLog "referer.log" referer env=!localreferer
top

Directive GlobalLog

Description:Définit le nom et le format du fichier journal
Syntaxe:GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]
Contexte:configuration globale
Statut:Base
Module:mod_log_config
Compatibilité:Disponible à partir de la version 2.4.19 du serveur HTTP Apache

La directive GlobalLog permet de spécifier un journal partagé entre le serveur principal et tous les serveurs virtuels définis.

Elle est identique à la directive CustomLog à ces différences près :

top

Directive LogFormat

Description:Décrit un format utilisable dans un fichier journal
Syntaxe:LogFormat format|alias [alias]
Défaut:LogFormat "%h %l %u %t \"%r\" %>s %b"
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_log_config

Cette directive permet de spécifier le format du fichier journal des accès.

La directive LogFormat se présente sous deux formes. Sous la première forme, qui ne possède qu'un seul argument, la directive définit le format qui sera utilisé dans les journaux spécifiés par les directives TransferLog ultérieures. L'argument unique peut contenir un format explicite comme décrit dans la section formats de journaux personnalisés ci-dessus. Il peut aussi contenir un alias faisant référence à un format de journal prédéfini par une directive LogFormat comme décrit plus loin.

Sous sa seconde forme, la directive LogFormat associe un format explicite à un alias. Cet alias peut ensuite s'utiliser dans les directives LogFormat ou CustomLog ultérieures, ce qui évite d'avoir à répéter l'ensemble de la chaîne de format. Une directive LogFormat qui définit un alias ne fait rien d'autre -- c'est à dire qu'elle ne fait que définir l'alias, elle n'applique pas le format et n'en fait pas le format par défaut. Par conséquent, elle n'affecte pas les directives TransferLog ultérieures. En outre, la directive LogFormat ne peut pas utiliser un alias pour en définir un autre. Notez que l'alias ne doit pas contenir de caractère pourcent (%).

Exemple

LogFormat "%v %h %l %u %t \"%r\" %>s %b" serveur_virtuel_commun
top

Directive TransferLog

Description:Spécifie l'emplacement d'un fichier journal
Syntaxe:TransferLog fichier|pipe
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_log_config

Cette directive possède exactement les mêmes arguments et produit les mêmes effets que la directive CustomLog, à l'exception qu'elle ne permet pas de spécifier un format de journal explicite ou la journalisation conditionnelle des requêtes. En l'occurrence, le format de journal est déterminé par la dernière définition d'une directive LogFormat qui ne définit pas d'alias. Si aucun format particulier n'a été spécifié, c'est le Common Log Format qui sera utilisé.

Exemple

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
TransferLog logs/access_log

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgid.html.en0000664000175100017510000002710114737542416020660 0ustar covenercovener mod_cgid - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_cgid

Available Languages:  en  |  fr  |  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.

Support Apache!

Directives

Bugfix checklist

See also

top

CGIDScriptTimeout Directive

Description:The length of time to wait for more output from the CGI program
Syntax:CGIDScriptTimeout time[s|ms]
Default:value of Timeout directive when unset or set to 0
Context:server config, virtual host, directory, .htaccess
Status:Base
Module:mod_cgid
Compatibility:Available in httpd 2.4.10 and later; in prior releases no timeout was applied

This directive limits the length of time to wait for more output from the CGI program. If the time is exceeded, the request and CGI are terminated.

Example

CGIDScriptTimeout 20
top

ScriptSock Directive

Description:The filename prefix of the socket to use for communication with the cgi daemon
Syntax:ScriptSock file-path
Default:ScriptSock cgisock
Context:server config
Status:Base
Module:mod_cgid

This directive sets the filename prefix of the socket to use for communication with the CGI daemon, an extension corresponding to the process ID of the server will be appended. 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.

If file-path is not an absolute path, the location specified will be relative to the value of DefaultRuntimeDir.

Example

ScriptSock /var/run/cgid.sock

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_dbd.html.fr.utf80000664000175100017510000004047514740503670022576 0ustar covenercovener mod_authn_dbd - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authn_dbd

Langues Disponibles:  en  |  fr 

Description:Authentification utilisateur à l'aide d'une base de données SQL
Statut:Extension
Identificateur de Module:authn_dbd_module
Fichier Source:mod_authn_dbd.c
Compatibilité:Disponible depuis la version 2.1 d'Apache

Sommaire

Ce module permet aux frontaux d'authentification comme mod_auth_digest et mod_auth_basic d'authentifier les utilisateurs en les recherchant dans une base de données SQL. mod_authn_file, par exemple, fournit une fonctionnalité similaire.

Ce module s'appuie sur mod_dbd pour spécifier le pilote de la base de données sous-jacente et les paramètres de connexion, mais aussi pour gérer les connexions à la base de données.

Si l'on utilise mod_auth_basic ou mod_auth_digest, on peut invoquer ce module en affectant la valeur dbd à la directive AuthBasicProvider ou AuthDigestProvider.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Performances et mise en cache

Certains utilisateurs de l'authentification DBD sous HTTPD 2.2/2.4 ont signalé une charge problématique au niveau de la base de données. Cela se produit en général lorsqu'une page HTML contient des centaines d'objets (comme des images, des scripts, etc...), chacun d'entre eux nécessitant une authentification. Les utilisateurs qui rencontrent ce genre de problème peuvent utiliser le module mod_authn_socache qui permet de mettre les données d'authentification en cache, et soulager ainsi la base de données de la plus grande partie de la charge.

top

Exemple de configuration

Voici un exemple simple d'utilisation de ce module dans un contexte d'authentification et de bases de données.

# configuration de mod_dbd
# MISE À JOUR pour inclure la mise en cache de l'authentification
DBDriver pgsql
DBDParams "dbname=apacheauth user=apache password=xxxxxx"

DBDMin  4
DBDKeep 8
DBDMax  20
DBDExptime 300

<Directory "/usr/www/mon-serveur/private">
  # configuration de mod_authn_core et mod_auth_basic
  # pour mod_authn_dbd
  AuthType Basic
  AuthName "Mon serveur"

  # Pour mettre en cache les données d'authentification, placez socache
  # avant dbd
  AuthBasicProvider socache dbd

  # Aussi nécessaire à la mise en cache : dire au cache de mettre en
  # cache les recherches dbd !
  AuthnCacheProvideFor dbd
  AuthnCacheContext mon-serveur

  # configuration de mod_authz_core
  Require valid-user

  # la requête SQL de mod_authn_dbd pour authentifier un utilisateur
  AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"
</Directory>
top

Mise à disposition des informations de connexion

Pour chaque requête envoyée au serveur de base de données, toutes les valeurs de colonnes du premier enregistrement renvoyé par la requête sont affectées à des variables d'environnement avec le préfixe "AUTHENTICATE_".

Par exemple, si une requête renvoie un nom d'utilisateur, un nom complet et un numéro de téléphone, un programme CGI pourra accéder à ces informations sans avoir besoin d'effectuer une deuxième requête vers la base de données.

Ceci va entraîner une simplification considérable du code et de la configuration nécessaire de certaines applications web.

top

Directive AuthDBDUserPWQuery

Description:Requête SQL servant à vérifier le mot de passe d'un utilisateur
Syntaxe:AuthDBDUserPWQuery requête
Contexte:répertoire
Statut:Extension
Module:mod_authn_dbd

La directive AuthDBDUserPWQuery permet de spécifier une requête servant à vérifier le mot de passe d'un utilisateur donné. L'identifiant utilisateur sera transmis comme paramètre sous forme d'une seule chaîne de caractères lorsque la requête sera exécutée. Cet identifiant est référencé dans la requête en utilisant le spécificateur de format %s.

AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"

La première colonne du premier enregistrement renvoyé par la requête se présentera sous la forme d'une chaîne de caractères contenant le mot de passe chiffré. Les enregistrements suivants sont ignorés. Si aucun enregistrement n'est renvoyé, l'utilisateur ne sera pas authentifié par mod_authn_dbd.

Toute valeur de colonne supplémentaire du premier enregistrement renvoyé par la requête sera stockée dans une variable d'environnement dont le nom aura la forme AUTHENTICATE_valeur-colonne.

Le format du mot de passe chiffré dépend du frontal d'authentification utilisé (par exemple mod_auth_basic ou mod_auth_digest). Voir la documentation sur les Formats de mots de passe pour plus de détails.

top

Directive AuthDBDUserRealmQuery

Description:Requête SQL servant à vérifier une empreinte de mot de passe pour un utilisateur et un identifiant d'authentification.
Syntaxe:AuthDBDUserRealmQuery requête
Contexte:répertoire
Statut:Extension
Module:mod_authn_dbd

La directive AuthDBDUserRealmQuery permet de spécifier une requête SQL servant à vérifier une empreinte de mot de passe pour un utilisateur et un identifiant d'authentification donnés au cours d'un processus d'authentification digest. Les identifiants de l'utilisateur et de l'authentification sont passés dans cet ordre comme paramètres à l'exécution de la requête. Ils sont référencés dans la chaîne de la requête en utilisant des spécificateurs de format %s.

AuthDBDUserRealmQuery "SELECT password FROM authn WHERE user = %s AND realm = %s"

La première colonne du premier enregistrement renvoyé par la requête se présentera sous la forme d'une chaîne de caractères contenant le mot de passe chiffré. Les enregistrements suivants seront ignorés. Si aucun enregistrement n'est renvoyé, l'utilisateur ne sera pas authentifié par mod_authn_dbd.

Toute valeur de colonne supplémentaire du premier enregistrement renvoyé par la requête sera stockée dans une variable d'environnement avec un nom de la forme AUTHENTICATE_COLONNE.

Le format du mot de passe chiffré dépend du frontal d'authentification utilisé (par exemple mod_auth_basic ou mod_auth_digest). Voir la documentation sur les Formats de mots de passe pour plus de détails.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_version.html.ja.utf80000664000175100017510000002560214743132254022310 0ustar covenercovener mod_version - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_version

翻訳済み言語:  en  |  fr  |  ja  |  ko 

説明:バージョン依存の設定
ステータス:Extension
モジュール識別子:version_module
ソースファイル:mod_version.c

概要

様々なバージョンの httpd の異なる設定を扱うことになる、 テストスイートや大規模ネットワークでの使用のために設計されています。 このモジュールは新しいコンテナ ― <IfVersion> を 提供します。これを使うと、数字の比較や正規表現による柔軟な バージョンチェックができるようになります。

<IfVersion 2.4.2>
    # current httpd version is exactly 2.4.2
</IfVersion>

<IfVersion >= 2.5>
    # use really new features :-)
</IfVersion>

詳細は以下を読んでください。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

<IfVersion> ディレクティブ

説明:バージョン依存の設定を入れる
構文:<IfVersion [[!]operator] version> ... </IfVersion>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Extension
モジュール:mod_version

<IfVersion>httpd のバージョン が基準を満たしたときにのみ実行させたいディレクティブを囲みます。 通常の (数値) 比較のときは version 引数は major[.minor[.patch]] という 形式、例えば、2.1.02.2 となります。 minorpatch は省略可能です。省略された場合は、 0 を指定したものとみなされます。比較には次の数値 operator を 指定できます:

operator説明
=== 同じ httpd バージョン
> より大きい httpd バージョン
>= 指定以上の httpd バージョン
< 指定未満の httpd バージョン
<= 指定以下の httpd バージョン

<IfVersion >= 2.3>
    # this happens only in versions greater or
    # equal 2.3.0.
</IfVersion>

数値比較に加えて、http のバージョン番号に対して 正規表現による マッチングができます。二種類の書き方があります:

operator説明
= or == version/regex/ 形式
~ versionregex 形式

<IfVersion = /^2.4.[01234]$/>
    # e.g. workaround for buggy versions
</IfVersion>

マッチングの否定を表現するために、すべてのオペレータは前に 感嘆符 (!)を付けることができます:

<IfVersion !~ ^2.4.[01234]$>
    # not for those versions
</IfVersion>

operator が省略されたときは = と みなされます。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/core.html.en0000664000175100017510000111777315032765673020064 0ustar covenercovener core - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Core Features

Available Languages:  de  |  en  |  es  |  fr  |  ja  |  tr 

Description:Core Apache HTTP Server features that are always available
Status:Core
Support Apache!

Directives

Bugfix checklist

See also

top

AcceptFilter Directive

Description:Configures optimizations for a Protocol's Listener Sockets
Syntax:AcceptFilter protocol accept_filter
Context:server config
Status:Core
Module:core

This directive enables operating system specific optimizations for a listening socket by the Protocol type. The basic premise is for the kernel to not send a socket to the server process until either data is received or an entire HTTP Request is buffered. Only FreeBSD's Accept Filters, Linux's more primitive TCP_DEFER_ACCEPT, and Windows' optimized AcceptEx() are currently supported.

Using none for an argument will disable any accept filters for that protocol. This is useful for protocols that require a server send data first, such as ftp: or nntp:

AcceptFilter nntp none

The default protocol names are https for port 443 and http for all other ports. To specify that another protocol is being used with a listening port, add the protocol argument to the Listen directive.

The default values on FreeBSD are:

AcceptFilter http httpready
AcceptFilter https dataready

The httpready accept filter buffers entire HTTP requests at the kernel level. Once an entire request is received, the kernel then sends it to the server. See the accf_http(9) man page for more details. Since HTTPS requests are encrypted, only the accf_data(9) filter is used.

The default values on Linux are:

AcceptFilter http data
AcceptFilter https data

Linux's TCP_DEFER_ACCEPT does not support buffering http requests. Any value besides none will enable TCP_DEFER_ACCEPT on that listener. For more details see the Linux tcp(7) man page.

The default values on Windows are:

AcceptFilter http connect
AcceptFilter https connect

Window's mpm_winnt interprets the AcceptFilter to toggle the AcceptEx() API, and does not support http protocol buffering. connect will use the AcceptEx() API, also retrieve the network endpoint addresses, but like none the connect option does not wait for the initial data transmission.

On Windows, none uses accept() rather than AcceptEx() and will not recycle sockets between connections. This is useful for network adapters with broken driver support, as well as some virtual network providers such as vpn drivers, or spam, virus or spyware filters.

The data AcceptFilter (Windows)

For versions 2.4.23 and prior, the Windows data accept filter waited until data had been transmitted and the initial data buffer and network endpoint addresses had been retrieved from the single AcceptEx() invocation. This implementation was subject to a denial of service attack and has been disabled.

Current releases of httpd default to the connect filter on Windows, and will fall back to connect if data is specified. Users of prior releases are encouraged to add an explicit setting of connect for their AcceptFilter, as shown above.

See also

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

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-handler, 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 Internet media types (MIME 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

AllowEncodedSlashes Directive

Description:Determines whether encoded path separators in URLs are allowed to be passed through
Syntax:AllowEncodedSlashes On|Off|NoDecode
Default:AllowEncodedSlashes Off
Context:server config, virtual host
Status:Core
Module:core
Compatibility: NoDecode option available in 2.3.12 and later.

The AllowEncodedSlashes directive allows URLs which contain encoded path separators (%2F for / and additionally %5C for \ on accordant systems) to be used in the path info.

With the default value, Off, such URLs are refused with a 404 (Not found) error.

With the value On, such URLs are accepted, and encoded slashes are decoded like all other encoded characters.

With the value NoDecode, such URLs are accepted, but encoded slashes are not decoded but left in their encoded state.

Turning AllowEncodedSlashes On is mostly useful when used in conjunction with PATH_INFO.

Note

If encoded slashes are needed in path info, use of NoDecode is strongly recommended as a security measure. Allowing slashes to be decoded could potentially allow unsafe paths.

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 None (2.3.9 and later), AllowOverride All (2.3.8 and earlier)
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 and AllowOverrideList is set to None, .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. (See the override class index for an up-to-date listing of which directives are enabled by each directive-type.)

AuthConfig
Allow use of the authorization directives (AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, etc.).
FileInfo
Allow use of the directives controlling document types (ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, and mod_mime Add* and Remove* directives), document meta data (Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName), mod_rewrite directives (RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule), mod_alias directives (Redirect, RedirectTemp, RedirectPermanent, RedirectMatch), and Action from mod_actions.
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).
Nonfatal=[Override|Unknown|All]
Allow use of AllowOverride option to treat syntax errors in .htaccess as nonfatal. Instead of causing an Internal Server Error, disallowed or unrecognised directives will be ignored and a warning logged:
  • Nonfatal=Override treats directives forbidden by AllowOverride as nonfatal.
  • Nonfatal=Unknown treats unknown directives as nonfatal. This covers typos and directives implemented by a module that's not present.
  • Nonfatal=All treats both the above as nonfatal.

Note that a syntax error in a valid directive will still cause an internal server error.

Security

Nonfatal errors may have security implications for .htaccess users. For example, if AllowOverride disallows AuthConfig, users' configuration designed to restrict access to a site will be disabled.
Options[=Option,...]
Allow use of the directives controlling specific directory features (Options and XBitHack). An equal sign may be given followed by a comma-separated list, without spaces, of options that may be set using the Options command.

Implicit disabling of Options

Even though the list of options that may be used in .htaccess files can be limited with this directive, as long as any Options directive is allowed any other inherited option can be disabled by using the non-relative syntax. In other words, this mechanism cannot force a specific option to remain set while allowing any others to be set.

AllowOverride Options=Indexes,MultiViews

Example:

AllowOverride AuthConfig Indexes

In the example above, all directives that are neither in the group AuthConfig nor Indexes cause an internal server error.

For security and performance reasons, do not set AllowOverride to anything other than None in your <Directory "/"> block. Instead, find (or create) the <Directory> block that refers to the directory where you're actually planning to place a .htaccess file.

See also

top

AllowOverrideList Directive

Description:Individual directives that are allowed in .htaccess files
Syntax:AllowOverrideList None|directive [directive-type] ...
Default:AllowOverrideList None
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

AllowOverrideList is valid only in <Directory> sections specified without regular expressions, not in <Location>, <DirectoryMatch> or <Files> sections.

When this directive is set to None and AllowOverride 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.

Example:

AllowOverride None
AllowOverrideList Redirect RedirectMatch

In the example above, only the Redirect and RedirectMatch directives are allowed. All others will cause an internal server error.

Example:

AllowOverride AuthConfig
AllowOverrideList CookieTracking CookieName

In the example above, AllowOverride grants permission to the AuthConfig directive grouping and AllowOverrideList grants permission to only two directives from the FileInfo directive grouping. All others will cause an internal server error.

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

CGIPassAuth Directive

Description:Enables passing HTTP authorization headers to scripts as CGI variables
Syntax:CGIPassAuth On|Off
Default:CGIPassAuth Off
Context:directory, .htaccess
Override:AuthConfig
Status:Core
Module:core
Compatibility:Available in Apache HTTP Server 2.4.13 and later

CGIPassAuth allows scripts access to HTTP authorization headers such as Authorization, which is required for scripts that implement HTTP Basic authentication. Normally these HTTP headers are hidden from scripts. This is to disallow scripts from seeing user ids and passwords used to access the server when HTTP Basic authentication is enabled in the web server. This directive should be used when scripts are allowed to implement HTTP Basic authentication.

This directive can be used instead of the compile-time setting SECURITY_HOLE_PASS_AUTHORIZATION which has been available in previous versions of Apache HTTP Server.

The setting is respected by any modules which use ap_add_common_vars(), such as mod_cgi, mod_cgid, mod_proxy_fcgi, mod_proxy_scgi, and so on. Notably, it affects modules which don't handle the request in the usual sense but still use this API; examples of this are mod_include and mod_ext_filter. Third-party modules that don't use ap_add_common_vars() may choose to respect the setting as well.

top

CGIVar Directive

Description:Controls how some CGI variables are set
Syntax:CGIVar variable rule
Context:directory, .htaccess
Override:FileInfo
Status:Core
Module:core
Compatibility:Available in Apache HTTP Server 2.4.21 and later

This directive controls how some CGI variables are set.

REQUEST_URI rules:

original-uri (default)
The value is taken from the original request line, and will not reflect internal redirects or subrequests which change the requested resource.
current-uri
The value reflects the resource currently being processed, which may be different than the original request from the client due to internal redirects or subrequests.
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 RFC2616.

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

DefaultRuntimeDir Directive

Description:Base directory for the server run-time files
Syntax:DefaultRuntimeDir directory-path
Default:DefaultRuntimeDir DEFAULT_REL_RUNTIMEDIR (logs/)
Context:server config
Status:Core
Module:core
Compatibility:Available in Apache 2.4.2 and later

The DefaultRuntimeDir directive sets the directory in which the server will create various run-time files (shared memory, locks, etc.). If set as a relative path, the full path will be relative to ServerRoot.

Example

DefaultRuntimeDir scratch/

The default location of DefaultRuntimeDir may be modified by changing the DEFAULT_REL_RUNTIMEDIR #define at build time.

Note: ServerRoot should be specified before this directive is used. Otherwise, the default value of ServerRoot would be used to set the base directory.

See also

top

DefaultType Directive

Description:This directive has no effect other than to emit warnings if the value is not none. In prior versions, DefaultType would specify a default media type to assign to response content for which no other media type configuration could be found.
Syntax:DefaultType media-type|none
Default:DefaultType none
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Core
Module:core
Compatibility:The argument none is available in Apache httpd 2.2.7 and later. All other choices are DISABLED for 2.3.x and later.

This directive has been disabled. For backwards compatibility of configuration files, it may be specified with the value none, meaning no default media type. For example:

DefaultType None

DefaultType None is only available in httpd-2.2.7 and later.

Use the mime.types configuration file and the AddType to configure media type assignments via file extensions, or the ForceType directive to configure the media type for specific resources. Otherwise, the server will send the response without a Content-Type header field and the recipient may attempt to guess the media type.

top

Define Directive

Description:Define a variable
Syntax:Define parameter-name [parameter-value]
Context:server config, virtual host, directory
Status:Core
Module:core

In its one parameter form, Define is equivalent to passing the -D argument to httpd. It can be used to toggle the use of <IfDefine> sections without needing to alter -D arguments in any startup scripts.

In addition to that, if the second parameter is given, a config variable is set to this value. The variable can be used in the configuration using the ${VAR} syntax. The variable is always globally defined and not limited to the scope of the surrounding config section.

<IfDefine TEST>
  Define servername test.example.com
</IfDefine>
<IfDefine !TEST>
  Define servername www.example.com
  Define SSL
</IfDefine>

DocumentRoot "/var/www/${servername}/htdocs"

Variable names may not contain colon ":" characters, to avoid clashes with RewriteMap's syntax.

Virtual Host scope and pitfalls

While this directive is supported in virtual host context, the changes it makes are visible to any later configuration directives, beyond any enclosing virtual host.

See also

top

<Directory> Directive

Description:Enclose a group of directives that apply only to the named file-system directory, sub-directories, and their contents.
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, sub-directories of that directory, and the files within the respective directories. 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>

Directory paths may be quoted, if you like, however, it must be quoted if the path contains spaces. This is because a space would otherwise indicate the end of an argument.

Be careful with the directory-path arguments: They have to literally match the filesystem path which Apache httpd 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.

Regular expressions can also be used, with the addition of the ~ character. For example:

<Directory ~ "^/www/[0-9]{3}">

</Directory>

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:

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 access for <Directory "/"> is to permit all access. This means that Apache httpd will serve any file mapped from an URL. It is recommended that you change this with a block such as

<Directory "/">
  Require all denied
</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 the contents of file-system directories matching a regular expression.
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 the files within), the same as <Directory>. However, it takes as an argument a regular expression. For example:

<DirectoryMatch "^/www/(.+/)?[0-9]{3}/">
    # ...
</DirectoryMatch>

matches directories in /www/ (or any subdirectory thereof) that consist of three numbers.

Compatibility

Prior to 2.3.9, this directive implicitly applied to sub-directories (like <Directory>) and could not match the end of line symbol ($). In 2.3.9 and later, only directories that match the expression are affected by the enclosed directives.

Trailing Slash

This directive applies to requests for directories that may or may not end in a trailing slash, so expressions that are anchored to the end of line ($) must be written with care.

From 2.4.8 onwards, named groups and backreferences are captured and written to the environment with the corresponding name prefixed with "MATCH_" and in upper case. This allows elements of paths to be referenced from within expressions and modules like mod_rewrite. In order to prevent confusion, numbered (unnamed) backreferences are ignored. Use named groups instead.

<DirectoryMatch "^/var/www/combined/(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</DirectoryMatch>

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://my.example.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

<Else> Directive

Description:Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
Syntax:<Else> ... </Else>
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Core
Module:core
Compatibility:Nested conditions are evaluated in 2.4.26 and later

The <Else> applies the enclosed directives if and only if the most recent <If> or <ElseIf> section in the same scope has not been applied. For example: In

<If "-z req('Host')">
  # ...
</If>
<Else>
  # ...
</Else>

The <If> would match HTTP/1.0 requests without a Host: header and the <Else> would match requests with a Host: header.

See also

top

<ElseIf> Directive

Description:Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
Syntax:<ElseIf expression> ... </ElseIf>
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Core
Module:core
Compatibility:Nested conditions are evaluated in 2.4.26 and later

The <ElseIf> applies the enclosed directives if and only if both the given condition evaluates to true and the most recent <If> or <ElseIf> section in the same scope has not been applied. For example: In

<If "-R '10.1.0.0/16'">
  #...
</If>
<ElseIf "-R '10.0.0.0/8'">
  #...
</ElseIf>
<Else>
  #...
</Else>

The <ElseIf> would match if the remote address of a request belongs to the subnet 10.0.0.0/8 but not to the subnet 10.1.0.0/16.

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 httpd 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:

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 Off
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Core
Module:core
Compatibility:Default changed to Off in version 2.3.9.

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 httpd 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:

For server configurations that are not vulnerable to these problems, you may enable this feature by specifying:

EnableSendfile On

For network mounted files, this feature may be disabled explicitly for the offending files by specifying:

<Directory "/path-to-nfs-files">
  EnableSendfile Off
</Directory>

Please note that the per-directory and .htaccess configuration of EnableSendfile is not supported by mod_cache_disk. Only global definition of EnableSendfile is taken into account by the module.

top

Error Directive

Description:Abort configuration parsing with a custom error message
Syntax:Error message
Context:server config, virtual host, directory, .htaccess
Status:Core
Module:core
Compatibility:2.3.9 and later

If an error can be detected within the configuration, this directive can be used to generate a custom error message, and halt configuration parsing. The typical use is for reporting required modules which are missing from the configuration.

# Example
# ensure that mod_include is loaded
<IfModule !include_module>
  Error "mod_include is required by mod_foo.  Load it with LoadModule."
</IfModule>

# ensure that exactly one of SSL,NOSSL is defined
<IfDefine SSL>
<IfDefine NOSSL>
  Error "Both SSL and NOSSL are defined.  Define only one of them."
</IfDefine>
</IfDefine>
<IfDefine !SSL>
<IfDefine !NOSSL>
  Error "Either SSL or NOSSL must be defined."
</IfDefine>
</IfDefine>

Note

This directive is evaluated and configuration processing time, not at runtime. As a result, this directive cannot be conditonally evaluated by enclosing it in an <If> section.

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

In the event of a problem or error, Apache httpd can be configured to do one of four things,

  1. output a simple hardcoded error message
  2. output a customized message
  3. internally redirect to a local URL-path to handle the problem/error
  4. redirect to an external URL to handle the problem/error

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 httpd will sometimes offer additional information regarding the problem/error.

From 2.4.13, expression syntax can be used inside the directive to produce dynamic strings and URLs.

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. Note that deciding whether the parameter is an URL, a path or a message is performed before any expression is parsed. Examples:

ErrorDocument 500 http://example.com/cgi-bin/server-error.cgi
ErrorDocument 404 /errors/bad_urls.php
ErrorDocument 401 /subscription_info.html
ErrorDocument 403 "Sorry, can't allow you access today"
ErrorDocument 403 Forbidden!
ErrorDocument 403 /errors/forbidden.py?referrer=%{escape:%{HTTP_REFERER}}

Additionally, the special value default can be used to specify Apache httpd's simple hardcoded message. While not required under normal circumstances, default will restore Apache httpd'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 HTTP Server 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 overridden, 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.

If you are using mod_proxy, you may wish to enable ProxyErrorOverride so that you can provide custom error messages on behalf of your Origin servers. If you don't enable ProxyErrorOverride, Apache httpd will not generate custom error documents for proxied content.

See also

top

ErrorLog Directive

Description:Location where the server will log errors
Syntax: ErrorLog file-path|syslog[:[facility][:tag]]
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.

ErrorLog "/var/log/httpd/error_log"

If the file-path begins with a pipe character "|" then it is assumed to be a command to spawn to handle the error log.

ErrorLog "|/usr/local/bin/httpd_errors"

See the notes on piped logs for more information.

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). The facility is effectively global, and if it is changed in individual virtual hosts, the final facility specified affects the entire server. Same rules apply for the syslog tag, which by default uses the Apache binary name, httpd in most cases. You can also override this by using the syslog::tag syntax.

ErrorLog syslog:user
ErrorLog syslog:user:httpd.srv1
ErrorLog syslog::httpd.srv2

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

ErrorLogFormat Directive

Description:Format specification for error log entries
Syntax: ErrorLogFormat [connection|request] format
Context:server config, virtual host
Status:Core
Module:core

ErrorLogFormat allows to specify what supplementary information is logged in the error log in addition to the actual log message.

#Simple example
ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [client %a] %M"

Specifying connection or request as first parameter allows to specify additional formats, causing additional information to be logged when the first message is logged for a specific connection or request, respectively. This additional information is only logged once per connection/request. If a connection or request is processed without causing any log message, the additional information is not logged either.

It can happen that some format string items do not produce output. For example, the Referer header is only present if the log message is associated to a request and the log message happens at a time when the Referer header has already been read from the client. If no output is produced, the default behavior is to delete everything from the preceding space character to the next space character. This means the log line is implicitly divided into fields on non-whitespace to whitespace transitions. If a format string item does not produce output, the whole field is omitted. For example, if the remote address %a in the log format [%t] [%l] [%a] %M  is not available, the surrounding brackets are not logged either. Space characters can be escaped with a backslash to prevent them from delimiting a field. The combination '% ' (percent space) is a zero-width field delimiter that does not produce any output.

The above behavior can be changed by adding modifiers to the format string item. A - (minus) modifier causes a minus to be logged if the respective item does not produce any output. In once-per-connection/request formats, it is also possible to use the + (plus) modifier. If an item with the plus modifier does not produce any output, the whole line is omitted.

A number as modifier can be used to assign a log severity level to a format item. The item will only be logged if the severity of the log message is not higher than the specified log severity level. The number can range from 1 (alert) over 4 (warn) and 7 (debug) to 15 (trace8).

For example, here's what would happen if you added modifiers to the %{Referer}i token, which logs the Referer request header.

Modified TokenMeaning
%-{Referer}i Logs a - if Referer is not set.
%+{Referer}i Omits the entire line if Referer is not set.
%4{Referer}i Logs the Referer only if the log message severity is higher than 4.

Some format string items accept additional parameters in braces.

Format String Description
%% The percent sign
%a Client IP address and port of the request
%{c}a Underlying peer IP address and port of the connection (see the mod_remoteip module)
%A Local IP-address and port
%{name}e Request environment variable name
%E APR/OS error status code and string
%F Source file name and line number of the log call
%{name}i Request header name
%k Number of keep-alive requests on this connection
%l Loglevel of the message
%L Log ID of the request
%{c}L Log ID of the connection
%{C}L Log ID of the connection if used in connection scope, empty otherwise
%m Name of the module logging the message
%M The actual log message
%{name}n Request note name
%P Process ID of current process
%T Thread ID of current thread
%{g}T System unique thread ID of current thread (the same ID as displayed by e.g. top; currently Linux only)
%t The current time
%{u}t The current time including micro-seconds
%{cu}t The current time in ISO 8601 extended format (compact), including micro-seconds
%{cuz}t The current time in ISO 8601 extended format (compact), including micro-seconds and time zone in the ISO 8601:2000 standard format. Available since 2.4.58 only
%{%-format}t The current time formatted per the strftime(3) function. Available since 2.4.58 only
%v The canonical ServerName of the current server.
%V The server name of the server serving the request according to the UseCanonicalName setting.
(backslash space) Non-field delimiting space
(percent space) Field delimiter (no output)

The log ID format %L produces a unique id for a connection or request. This can be used to correlate which log lines belong to the same connection or request, which request happens on which connection. A %L format string is also available in mod_log_config to allow to correlate access log entries with error log lines. If mod_unique_id is loaded, its unique id will be used as log ID for requests.

#Example (default format for threaded MPMs)
ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"

This would result in error messages such as:

[Thu May 12 08:28:57.652118 2011] [core:error] [pid 8777:tid 4326490112] [client ::1:58619] File does not exist: /usr/local/apache2/htdocs/favicon.ico

Notice that, as discussed above, some fields are omitted entirely because they are not defined.

#Example (similar to the 2.2.x format)
ErrorLogFormat "[%t] [%l] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"
#Advanced example with request/connection log IDs
ErrorLogFormat "[%{uc}t] [%-m:%-l] [R:%L] [C:%{C}L] %7F: %E: %M"
ErrorLogFormat request "[%{uc}t] [R:%L] Request %k on C:%{c}L pid:%P tid:%T"
ErrorLogFormat request "[%{uc}t] [R:%L] UA:'%+{User-Agent}i'"
ErrorLogFormat request "[%{uc}t] [R:%L] Referer:'%+{Referer}i'"
ErrorLogFormat connection "[%{uc}t] [C:%{c}L] remote\ %a local\ %A"

See also

top

ExtendedStatus Directive

Description:Keep track of extended status information for each request
Syntax:ExtendedStatus On|Off
Default:ExtendedStatus Off[*]
Context:server config
Status:Core
Module:core

This option tracks additional data per worker about the currently executing request and creates a utilization summary. You can see these variables during runtime by configuring mod_status. Note that other modules may rely on this scoreboard.

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. Also note that this setting cannot be changed during a graceful restart.

Note that loading mod_status will change the default behavior to ExtendedStatus On, while other third party modules may do the same. Such modules rely on collecting detailed information about the state of all workers. The default is changed by mod_status beginning with version 2.3.6. The previous default was always Off.

top

FileETag Directive

Description:File attributes used to create the ETag HTTP response header for static files
Syntax:FileETag component ...
Default:FileETag MTime Size
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Core
Module:core
Compatibility:The default used to be "INode MTime Size" in 2.3.14 and earlier.

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 static file. (The ETag value is used in cache management to save network bandwidth.) 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
Digest
If a document is file-based, the ETag field will be calculated by taking the digest over the file.
None
If a document is file-based, no ETag field will be included in the response

The INode, MTime, Size and Digest 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.

Server Side Includes

An ETag is not generated for responses parsed by mod_include since the response entity can change without a change of the INode, MTime, Size or Digest of the static file with embedded SSI directives.
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.

<Files "cat.html">
    # Insert stuff that applies to cat.html here
</Files>

<Files "?at.*">
    # This would apply to cat.html, bat.html, hat.php and so on.
</Files>

Regular expressions can also be used, with the addition of the ~ character. For example:

<Files ~ "\.(gif|jpe?g|png)$">
    #...
</Files>

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)$">
    # ...
</FilesMatch>

would match most common Internet graphics formats.

The .+ at the start of the regex ensures that files named .png, or .gif, for example, are not matched.

From 2.4.8 onwards, named groups and backreferences are captured and written to the environment with the corresponding name prefixed with "MATCH_" and in upper case. This allows elements of files to be referenced from within expressions and modules like mod_rewrite. In order to prevent confusion, numbered (unnamed) backreferences are ignored. Use named groups instead.

<FilesMatch "^(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</FilesMatch>

See also

top

FlushMaxPipelined Directive

Description:Maximum number of pipelined responses above which they are flushed to the network
Syntax:FlushMaxPipelined number
Default:FlushMaxPipelined 5
Context:server config, virtual host
Status:Core
Module:core
Compatibility:2.4.47 and later

This directive allows to configure the maximum number of pipelined responses, which remain pending so long as pipelined request are received. When the limit is reached, responses are forcibly flushed to the network in blocking mode, until passing under the limit again.

FlushMaxPipelined helps constraining memory usage. When set to 0 pipelining is disabled, when set to -1 there is no limit (FlushMaxThreshold still applies).

top

FlushMaxThreshold Directive

Description:Threshold above which pending data are flushed to the network
Syntax:FlushMaxThreshold number-of-bytes
Default:FlushMaxThreshold 65535
Context:server config, virtual host
Status:Core
Module:core
Compatibility:2.4.47 and later

This directive allows to configure the threshold for pending output data (in bytes). When the limit is reached, data are forcibly flushed to the network in blocking mode, until passing under the limit again.

FlushMaxThreshold helps constraining memory usage. When set to 0 or a too small value there are actually no pending data, but for threaded MPMs there can be more threads busy waiting for the network thus less ones available to handle the other simultaneous connections.

top

ForceType Directive

Description:Forces all matching files to be served with the specified media type in the HTTP Content-Type header field
Syntax:ForceType media-type|None
Context:directory, .htaccess
Override:FileInfo
Status:Core
Module:core

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 media-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 this directive overrides other indirect media type associations defined in mime.types or via the AddType.

You can also override more general ForceType settings 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>

This directive primarily overrides the content types generated for static files served out of the filesystem. For resources other than static files, where the generator of the response typically specifies a Content-Type, this directive has no effect.

Note

When explicit directives such as SetHandler or AddHandler do not apply to the current request, the internal handler name normally set by those directives is set to match the content type specified by this directive. This is a historical behavior that some third-party modules (such as mod_php) may use "magic" content types used only to signal the module to take responsibility for the matching request. Configurations that rely on such "magic" types should be avoided by the use of SetHandler or AddHandler.

top

GprofDir Directive

Description:Directory to write gmon.out profiling data to.
Syntax:GprofDir /tmp/gprof/|/tmp/gprof/%
Context:server config, virtual host
Status:Core
Module:core

When the server has been compiled with gprof profiling support, GprofDir causes gmon.out files to be written to the specified directory when the process exits. If the argument ends with a percent symbol ('%'), subdirectories are created for each process id.

This directive currently only works with the prefork MPM.

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.

Finally, if you have hostname-based Require directives, a hostname lookup will be performed regardless of the setting of HostnameLookups.

top

HttpProtocolOptions Directive

Description:Modify restrictions on HTTP Request Messages
Syntax:HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0]
Default:HttpProtocolOptions Strict LenientMethods Allow0.9
Context:server config, virtual host
Status:Core
Module:core
Compatibility:2.2.32 or 2.4.24 and later

This directive changes the rules applied to the HTTP Request Line (RFC 7230 §3.1.1) and the HTTP Request Header Fields (RFC 7230 §3.2), which are now applied by default or using the Strict option. Due to legacy modules, applications or custom user-agents which must be deprecated the Unsafe option has been added to revert to the legacy behaviors.

These rules are applied prior to request processing, so must be configured at the global or default (first) matching virtual host section, by IP/port interface (and not by name) to be honored.

The directive accepts three parameters from the following list of choices, applying the default to the ones not specified:

Strict|Unsafe

Prior to the introduction of this directive, the Apache HTTP Server request message parsers were tolerant of a number of forms of input which did not conform to the protocol. RFC 7230 §9.4 Request Splitting and §9.5 Response Smuggling call out only two of the potential risks of accepting non-conformant request messages, while RFC 7230 §3.5 "Message Parsing Robustness" identify the risks of accepting obscure whitespace and request message formatting. As of the introduction of this directive, all grammar rules of the specification are enforced in the default Strict operating mode, and the strict whitespace suggested by section 3.5 is enforced and cannot be relaxed.

Security risks of Unsafe

Users are strongly cautioned against toggling the Unsafe mode of operation, particularly on outward-facing, publicly accessible server deployments. If an interface is required for faulty monitoring or other custom service consumers running on an intranet, users should toggle the Unsafe option only on a specific virtual host configured to service their internal private network.

Example of a request leading to HTTP 400 with Strict mode

# Missing CRLF
GET / HTTP/1.0\n\n

Command line tools and CRLF

Some tools need to be forced to use CRLF, otherwise httpd will return a HTTP 400 response like described in the above use case. For example, the OpenSSL s_client needs the -crlf parameter to work properly.

The DumpIOInput directive can help while reviewing the HTTP request to identify issues like the absence of CRLF.

RegisteredMethods|LenientMethods

RFC 7231 §4.1 "Request Methods" "Overview" requires that origin servers shall respond with a HTTP 501 status code when an unsupported method is encountered in the request line. This already happens when the LenientMethods option is used, but administrators may wish to toggle the RegisteredMethods option and register any non-standard methods using the RegisterHttpMethod directive, particularly if the Unsafe option has been toggled.

Forward Proxy compatibility

The RegisteredMethods option should not be toggled for forward proxy hosts, as the methods supported by the origin servers are unknown to the proxy server.

Example of a request leading to HTTP 501 with LenientMethods mode

# Unknown HTTP method
WOW / HTTP/1.0\r\n\r\n

# Lowercase HTTP method
get / HTTP/1.0\r\n\r\n

Allow0.9|Require1.0

RFC 2616 §19.6 "Compatibility With Previous Versions" had encouraged HTTP servers to support legacy HTTP/0.9 requests. RFC 7230 supersedes this with "The expectation to support HTTP/0.9 requests has been removed" and offers additional comments in RFC 7230 Appendix A. The Require1.0 option allows the user to remove support of the default Allow0.9 option's behavior.

Example of a request leading to HTTP 400 with Require1.0 mode

# Unsupported HTTP version
GET /\r\n\r\n

Reviewing the messages logged to the ErrorLog, configured with LogLevel debug level, can help identify such faulty requests along with their origin. Users should pay particular attention to the 400 responses in the access log for invalid requests which were unexpectedly rejected.

top

<If> Directive

Description:Contains directives that apply only if a condition is satisfied by a request at runtime
Syntax:<If expression> ... </If>
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Core
Module:core
Compatibility:Nested conditions are evaluated in 2.4.26 and later

The <If> directive evaluates an expression at runtime, and applies the enclosed directives if and only if the expression evaluates to true. For example:

<If "-z req('Host')">

would match HTTP/1.0 requests without a Host: header. Expressions may contain various shell-like operators for string comparison (==, !=, <, ...), integer comparison (-eq, -ne, ...), and others (-n, -z, -f, ...). It is also possible to use regular expressions,

<If "%{QUERY_STRING} =~ /(delete|commit)=.*?elem/">

shell-like pattern matches and many other operations. These operations can be done on request headers (req), environment variables (env), and a large number of other properties. The full documentation is available in Expressions in Apache HTTP Server.

Only directives that support the directory context can be used within this configuration section.

Certain variables, such as CONTENT_TYPE and other response headers, are set after <If> conditions have already been evaluated, and so will not be available to use in this directive.
Directives that take affect during configuration parsing, such as Define, Include, and Error cannot be made conditional by enclosing them in an if <If> configuration section. These sections are always part of the configuration, regardless of how they evaluate at runtime.

See also

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:

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 or by the Define directive.

<IfDefine> sections are nest-able, which can be used to implement simple multiple-parameter tests. Example:

httpd -DReverseProxy -DUseCache -DMemCache ...

<IfDefine ReverseProxy>
  LoadModule proxy_module   modules/mod_proxy.so
  LoadModule proxy_http_module   modules/mod_proxy_http.so
  <IfDefine UseCache>
    LoadModule cache_module   modules/mod_cache.so
    <IfDefine MemCache>
      LoadModule mem_cache_module   modules/mod_mem_cache.so
    </IfDefine>
    <IfDefine !MemCache>
      LoadModule cache_disk_module   modules/mod_cache_disk.so
    </IfDefine>
  </IfDefine>
</IfDefine>
top

<IfDirective> Directive

Description:Encloses directives that are processed conditional on the presence or absence of a specific directive
Syntax:<IfDirective [!]directive-name> ... </IfDirective>
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Core
Module:core
Compatibility:Available in 2.4.34 and later.

The <IfDirective test>...</IfDirective> section is used to mark directives that are conditional on the presence of a specific directive. The directives within an <IfDirective> 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 <IfDirective> section can be one of two forms:

In the former case, the directives between the start and end markers are only processed if a directive of the given name is available at the time of processing. The second format reverses the test, and only processes the directives if directive-name is not available.

This section should only be used if you need to have one configuration file that works across multiple versions of httpd, regardless of whether a particular directive is available. In normal operation, directives need not be placed in <IfDirective> sections.

See also

top

<IfFile> Directive

Description:Encloses directives that will be processed only if file exists at startup
Syntax:<IfFile [!]filename> ... </IfFile>
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Core
Module:core
Compatibility:Available in 2.4.34 and later.

The <IfFile filename>...</IfFile> section is used to mark directives that are conditional on the existence of a file on disk. The directives within an <IfFile> section are only processed if filename exists. If filename doesn't exist, everything between the start and end markers is ignored. filename can be an absolute path or a path relative to the server root.

The filename in the <IfFile> section directive can take the same forms as the test variable in the <IfDefine> section, i.e. the test can be negated if the ! character is placed directly before filename.

If a relative filename is supplied, the check is ServerRoot relative. In the case where this directive occurs before the ServerRoot, the path will be checked relative to the compiled-in server root or the server root passed in on the command line via the -d parameter.

Warning

In 2.4.34, it is not possible to specify a filename with surrounding quotes. This would generate a parsing error at start-up. The main impact is that filenames with spaces can't be used. This behavior is fixed in 2.4.35.
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:

In the former case, the directives between the start and end markers are only processed if the module named module is included in Apache httpd -- 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

<IfSection> Directive

Description:Encloses directives that are processed conditional on the presence or absence of a specific section directive
Syntax:<IfSection [!]section-name> ... </IfSection>
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Core
Module:core
Compatibility:Available in 2.4.34 and later.

The <IfSection test>...</IfSection> section is used to mark directives that are conditional on the presence of a specific section directive. A section directive is any directive such as <VirtualHost> which encloses other directives, and has a directive name with a leading "<".

The directives within an <IfSection> section are only processed if the test is true. If test is false, everything between the start and end markers is ignored.

The section-name must be specified without either the leading "<" or closing ">". The test in the <IfSection> section can be one of two forms:

In the former case, the directives between the start and end markers are only processed if a section directive of the given name is available at the time of processing. The second format reverses the test, and only processes the directives if section-name is not an available section directive.

For example:

<IfSection VirtualHost>
   ...
</IfSection>
This section should only be used if you need to have one configuration file that works across multiple versions of httpd, regardless of whether a particular section directive is available. In normal operation, directives need not be placed in <IfSection> sections.

See also

top

Include Directive

Description:Includes other configuration files from within the server configuration files
Syntax:Include file-path|directory-path|wildcard
Context:server config, virtual host, directory
Status:Core
Module:core
Compatibility:Directory wildcard matching available in 2.3.6 and later

This directive allows inclusion of other configuration files from within the server configuration files.

Shell-style (fnmatch()) wildcard characters can be used in the filename or directory parts of the path to include several files at once, in alphabetical order. In addition, if Include points to a directory, rather than a file, Apache httpd will read all files in that directory and any subdirectory. However, including entire directories is not recommended, because it is easy to accidentally leave temporary files in a directory that can cause httpd to fail. Instead, we encourage you to use the wildcard syntax shown below, to include files that match a particular pattern, such as *.conf, for example.

The Include directive will fail with an error if a wildcard expression does not match any file. The IncludeOptional directive can be used if non-matching wildcards should be ignored.

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

Wildcards may be included in the directory or file portion of the path. This example will fail if there is no subdirectory in conf/vhosts that contains at least one *.conf file:

Include conf/vhosts/*/*.conf

Alternatively, the following command will just be ignored in case of missing files or directories:

IncludeOptional conf/vhosts/*/*.conf

See also

top

IncludeOptional Directive

Description:Includes other configuration files from within the server configuration files
Syntax:IncludeOptional file-path|directory-path|wildcard
Context:server config, virtual host, directory
Status:Core
Module:core
Compatibility:Available in 2.3.6 and later. Not existent file paths without wildcards do not cause SyntaxError after 2.4.30

This directive allows inclusion of other configuration files from within the server configuration files. It works identically to the Include directive, but it will be silently ignored (instead of causing an error) if wildcards are used and they do not match any file or directory or if a file path does not exist on the file system.

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.

When a client uses a Keep-Alive connection, it will be counted as a single "request" for the MaxConnectionsPerChild directive, regardless of how many requests are sent using the connection.

See also

top

KeepAliveTimeout Directive

Description:Amount of time the server will wait for subsequent requests on a persistent connection
Syntax:KeepAliveTimeout num[ms]
Default:KeepAliveTimeout 5
Context:server config, virtual host
Status:Core
Module:core

The number of seconds Apache httpd will wait for a subsequent request before closing the connection. By adding a postfix of ms the timeout can be also set in milliseconds. 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.

If KeepAliveTimeout is not set for a name-based virtual host, the value of the first defined virtual host best matching the local IP and port will be used.

top

<Limit> Directive

Description:Restrict enclosed access controls to only certain HTTP methods
Syntax:<Limit method [method] ... > ... </Limit>
Context:directory, .htaccess
Override:AuthConfig, Limit
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 (see TraceEnable).

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.

The <Limit> and <LimitExcept> directives may be nested. In this case, each successive level of <Limit> or <LimitExcept> directives must further restrict the set of methods to which access controls apply.

When using <Limit> or <LimitExcept> directives with the Require directive, note that the first Require to succeed authorizes the request, regardless of the presence of other Require directives.

For example, given the following configuration, all users will be authorized for POST requests, and the Require group editors directive will be ignored in all cases:

<LimitExcept GET>
  Require valid-user
</LimitExcept>
<Limit POST>
  Require group editors
</Limit>
top

<LimitExcept> Directive

Description:Restrict access controls to all HTTP methods except the named ones
Syntax:<LimitExcept method [method] ... > ... </LimitExcept>
Context:directory, .htaccess
Override:AuthConfig, Limit
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

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 httpd'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 deeply subrequests may be nested. If you specify only one number, it will be assigned to both limits.

LimitInternalRecursion 5
top

LimitRequestBody Directive

Description:Restricts the total size of the HTTP request body sent from the client
Syntax:LimitRequestBody bytes
Default:LimitRequestBody 1073741824
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Core
Module:core
Compatibility:In Apache HTTP Server 2.4.53 and earlier, the default value was 0 (unlimited)

This directive specifies the number of bytes that are allowed in a request body. A value of 0 means unlimited.

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, virtual host
Status:Core
Module:core

Setting number at 0 means unlimited. 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

Warning

When name-based virtual hosting is used, the value for this directive is taken from the default (first-listed) virtual host for the local IP and port combination.

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, virtual host
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 set 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.

Warning

When name-based virtual hosting is used, the value for this directive is taken from the default (first-listed) virtual host best matching the current IP address and port combination.

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, virtual host
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 set 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.

Warning

When name-based virtual hosting is used, the value for this directive is taken from the default (first-listed) virtual host best matching the current IP address and port combination.

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 the maximum size of an XML-based request body. A value of 0 will apply a hard limit (depending on 32bit vs 64bit system) allowing for XML escaping within the bounds of the system addressable memory, but it exists for compatibility only and is not recommended since it does not account for memory consumed elsewhere or concurrent requests, which might result in an overall system out-of-memory.

Example:

# Limit of 1 MiB
LimitXMLRequestBody 1048576
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.

The enclosed directives will be applied to the request if the path component of the URL meets any of the following criteria:

In the example below, where no trailing slash is used, requests to /private1, /private1/ and /private1/file.txt will have the enclosed directives applied, but /private1other would not.

<Location "/private1">
    #  ...
</Location>

In the example below, where a trailing slash is used, requests to /private2/ and /private2/file.txt will have the enclosed directives applied, but /private2 and /private2other would not.

<Location "/private2/">
    # ...
</Location>

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. Neither wildcard character matches a / in the URL-path.

Regular expressions can also be used, with the addition of the ~ character. For example:

<Location ~ "/(extra|special)/data">
    #...
</Location>

would match URLs that contained the substring /extra/data or /special/data. The directive <LocationMatch> behaves identical to the regex version of <Location>, and is preferred, for the simple reason that ~ is hard to distinguish from - in many fonts.

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 example.com, you might use:

<Location "/status">
  SetHandler server-status
  Require host example.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 if directive MergeSlashes has been set to "OFF". The <LocationMatch> directive and the regex version of <Location> require you to explicitly specify multiple slashes if the slashes are not being merged.

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">
    # ...
</LocationMatch>

would match URLs that contained the substring /extra/data or /special/data.

If the intent is that a URL starts with /extra/data, rather than merely contains /extra/data, prefix the regular expression with a ^ to require this.

<LocationMatch "^/(extra|special)/data">

From 2.4.8 onwards, named groups and backreferences are captured and written to the environment with the corresponding name prefixed with "MATCH_" and in upper case. This allows elements of URLs to be referenced from within expressions and modules like mod_rewrite. In order to prevent confusion, numbered (unnamed) backreferences are ignored. Use named groups instead.

<LocationMatch "^/combined/(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</LocationMatch>

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 if directive MergeSlashes has been set to "OFF". The <LocationMatch> directive and the regex version of <Location> require you to explicitly specify multiple slashes if the slashes are not being merged.

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

LogLevel Directive

Description:Controls the verbosity of the ErrorLog
Syntax:LogLevel [module:]level [module:level] ...
Default:LogLevel warn
Context:server config, virtual host, directory
Status:Core
Module:core
Compatibility:Per-module and per-directory configuration is available in Apache HTTP Server 2.3.6 and later

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 ..."
trace1 Trace messages "proxy: FTP: control connection complete"
trace2 Trace messages "proxy: CONNECT: sending the CONNECT request to the remote proxy"
trace3 Trace messages "openssl: Handshake: start"
trace4 Trace messages "read from buffered SSL brigade, mode 0, 17 bytes"
trace5 Trace messages "map lookup FAILED: map=rewritemap key=keyname"
trace6 Trace messages "cache lookup FAILED, forcing new map lookup"
trace7 Trace messages, dumping large amounts of data "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"
trace8 Trace messages, dumping large amounts of data "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"

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.

Specifying a level without a module name will reset the level for all modules to that level. Specifying a level with a module name will set the level for that module only. It is possible to use the module source file name, the module identifier, or the module identifier with the trailing _module omitted as module specification. This means the following three specifications are equivalent:

LogLevel info ssl:warn
LogLevel info mod_ssl.c:warn
LogLevel info ssl_module:warn

It is also possible to change the level per directory:

LogLevel info
<Directory "/usr/local/apache/htdocs/app">
  LogLevel debug
</Directory>
Per directory loglevel configuration only affects messages that are logged after the request has been parsed and that are associated with the request. Log messages which are associated with the connection or the server are not affected.

See also

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

MaxRangeOverlaps Directive

Description:Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
Syntax:MaxRangeOverlaps default | unlimited | none | number-of-ranges
Default:MaxRangeOverlaps 20
Context:server config, virtual host, directory
Status:Core
Module:core
Compatibility:Available in Apache HTTP Server 2.3.15 and later

The MaxRangeOverlaps directive limits the number of overlapping HTTP ranges the server is willing to return to the client. If more overlapping ranges than permitted are requested, the complete resource is returned instead.

default
Limits the number of overlapping ranges to a compile-time default of 20.
none
No overlapping Range headers are allowed.
unlimited
The server does not limit the number of overlapping ranges it is willing to satisfy.
number-of-ranges
A positive number representing the maximum number of overlapping ranges the server is willing to satisfy.
top

MaxRangeReversals Directive

Description:Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
Syntax:MaxRangeReversals default | unlimited | none | number-of-ranges
Default:MaxRangeReversals 20
Context:server config, virtual host, directory
Status:Core
Module:core
Compatibility:Available in Apache HTTP Server 2.3.15 and later

The MaxRangeReversals directive limits the number of HTTP Range reversals the server is willing to return to the client. If more ranges reversals than permitted are requested, the complete resource is returned instead.

default
Limits the number of range reversals to a compile-time default of 20.
none
No Range reversals headers are allowed.
unlimited
The server does not limit the number of range reversals it is willing to satisfy.
number-of-ranges
A positive number representing the maximum number of range reversals the server is willing to satisfy.
top

MaxRanges Directive

Description:Number of ranges allowed before returning the complete resource
Syntax:MaxRanges default | unlimited | none | number-of-ranges
Default:MaxRanges 200
Context:server config, virtual host, directory
Status:Core
Module:core
Compatibility:Available in Apache HTTP Server 2.3.15 and later

The MaxRanges directive limits the number of HTTP ranges the server is willing to return to the client. If more ranges than permitted are requested, the complete resource is returned instead.

default
Limits the number of ranges to a compile-time default of 200.
none
Range headers are ignored.
unlimited
The server does not limit the number of ranges it is willing to satisfy.
number-of-ranges
A positive number representing the maximum number of ranges the server is willing to satisfy.
top

MergeSlashes Directive

Description:Controls whether the server merges consecutive slashes in URLs.
Syntax:MergeSlashes ON|OFF
Default:MergeSlashes ON
Context:server config, virtual host
Status:Core
Module:core
Compatibility:Added in 2.4.39

By default, the server merges (or collapses) multiple consecutive slash ('/') characters in the path component of the request URL.

When mapping URL's to the filesystem, these multiple slashes are not significant. However, URL's handled other ways, such as by CGI or proxy, might prefer to retain the significance of multiple consecutive slashes. In these cases MergeSlashes can be set to OFF to retain the multiple consecutive slashes, which is the legacy behavior.

When set to "OFF", regular expressions used in the configuration file that match the path component of the URL (LocationMatch, RewriteRule, ...) need to take into account multiple consecutive slashes. Non regular expression based Location always operate against a URL with merged slashes and cannot differentiate between multiple slashes.

top

MergeTrailers Directive

Description:Determines whether trailers are merged into headers
Syntax:MergeTrailers [on|off]
Default:MergeTrailers off
Context:server config, virtual host
Status:Core
Module:core
Compatibility:2.4.11 and later

This directive controls whether HTTP trailers are copied into the internal representation of HTTP headers. This merging occurs when the request body has been completely consumed, long after most header processing would have a chance to examine or modify request headers.

This option is provided for compatibility with releases prior to 2.4.11, where trailers were always merged.

top

Mutex Directive

Description:Configures mutex mechanism and lock file directory for all or specified mutexes
Syntax:Mutex mechanism [default|mutex-name] ... [OmitPID]
Default:Mutex default
Context:server config
Status:Core
Module:core
Compatibility:Available in Apache HTTP Server 2.3.4 and later

The Mutex directive sets the mechanism, and optionally the lock file location, that httpd and modules use to serialize access to resources. Specify default as the second argument to change the settings for all mutexes; specify a mutex name (see table below) as the second argument to override defaults only for that mutex.

The Mutex directive is typically used in the following exceptional situations:

Supported modules

This directive only configures mutexes which have been registered with the core server using the ap_mutex_register() API. All modules bundled with httpd support the Mutex directive, but third-party modules may not. Consult the documentation of the third-party module, which must indicate the mutex name(s) which can be configured if this directive is supported.

The following mutex mechanisms are available:

Most mechanisms are only available on selected platforms, where the underlying platform and APR support it. Mechanisms which aren't available on all platforms are posixsem, sysvsem, sem, pthread, fcntl, flock, and file.

With the file-based mechanisms fcntl and flock, the path, if provided, is a directory where the lock file will be created. The default directory is httpd's run-time file directory relative to ServerRoot. Always use a local disk filesystem for /path/to/mutex and never a directory residing on a NFS- or AFS-filesystem. The basename of the file will be the mutex type, an optional instance string provided by the module, and unless the OmitPID keyword is specified, the process id of the httpd parent process will be appended to make the file name unique, avoiding conflicts when multiple httpd instances share a lock file directory. For example, if the mutex name is mpm-accept and the lock file directory is /var/httpd/locks, the lock file name for the httpd instance with parent process id 12345 would be /var/httpd/locks/mpm-accept.12345.

Security

It is best to avoid putting mutex files 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.

The following table documents the names of mutexes used by httpd and bundled modules.

Mutex name Module(s) Protected resource
mpm-accept prefork and worker MPMs incoming connections, to avoid the thundering herd problem; for more information, refer to the performance tuning documentation
authdigest-client mod_auth_digest client list in shared memory
authdigest-opaque mod_auth_digest counter in shared memory
ldap-cache mod_ldap LDAP result cache
rewrite-map mod_rewrite communication with external mapping programs, to avoid intermixed I/O from multiple requests
ssl-cache mod_ssl SSL session cache
ssl-stapling mod_ssl OCSP stapling response cache
watchdog-callback mod_watchdog callback function of a particular client module

The OmitPID keyword suppresses the addition of the httpd parent process id from the lock file name.

In the following example, the mutex mechanism for the MPM accept mutex will be changed from the compiled-in default to fcntl, with the associated lock file created in directory /var/httpd/locks. The mutex mechanism for all other mutexes will be changed from the compiled-in default to sysvsem.

Mutex sysvsem default
Mutex fcntl:/var/httpd/locks mpm-accept
top

NameVirtualHost Directive

Description:DEPRECATED: Designates an IP address for name-virtual hosting
Syntax:NameVirtualHost addr[:port]
Context:server config
Status:Core
Module:core

Prior to 2.3.11, NameVirtualHost was required to instruct the server that a particular IP address and port combination was usable as a name-based virtual host. In 2.3.11 and later, any time an IP address and port combination is used in multiple virtual hosts, name-based virtual hosting is automatically enabled for that address.

This directive currently has no effect.

See also

top

Options Directive

Description:Configures what features are available in a particular directory
Syntax:Options [+|-]option [[+|-]option] ...
Default:Options FollowSymlinks
Context:server config, virtual host, directory, .htaccess
Override:Options
Status:Core
Module:core
Compatibility:The default was changed from All to FollowSymlinks in 2.3.11

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.
ExecCGI
Execution of CGI scripts using mod_cgi is permitted.
FollowSymLinks
The server will follow symbolic links in this directory. This is the default setting.

Even though the server follows the symlink it does not change the pathname used to match against <Directory> sections.

The FollowSymLinks and SymLinksIfOwnerMatch Options work only in <Directory> sections or .htaccess files.

Omitting this option should not be considered a security restriction, since symlink testing is subject to race conditions that make it circumventable.

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.

Note

This option gets ignored if set anywhere other than <Directory>, as mod_negotiation needs real resources to compare against and evaluate from.

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

The FollowSymLinks and SymLinksIfOwnerMatch Options work only in <Directory> sections or .htaccess files.

This option should not be considered a security restriction, since symlink testing is subject to race conditions that make it circumventable.

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.

Note

Mixing Options with a + or - with those without is not valid syntax and will be rejected during server startup by the syntax check with an abort.

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

top

Protocol Directive

Description:Protocol for a listening socket
Syntax:Protocol protocol
Context:server config, virtual host
Status:Core
Module:core
Compatibility:Available in Apache 2.1.5 and later. On Windows, from Apache 2.3.3 and later.

This directive specifies the protocol used for a specific listening socket. The protocol is used to determine which module should handle a request and to apply protocol specific optimizations with the AcceptFilter directive.

This directive not required for most configurations. If not specified, https is the default for port 443 and http the default for all other ports. The protocol is used to determine which module should handle a request, and to apply protocol specific optimizations with the AcceptFilter directive.

For example, if you are running https on a non-standard port, specify the protocol explicitly:

Protocol https

You can also specify the protocol using the Listen directive.

See also

top

Protocols Directive

Description:Protocols available for a server/virtual host
Syntax:Protocols protocol ...
Default:Protocols http/1.1
Context:server config, virtual host
Status:Core
Module:core
Compatibility:Only available from Apache 2.4.17 and later.

This directive specifies the list of protocols supported for a server/virtual host. The list determines the allowed protocols a client may negotiate for this server/host.

You need to set protocols if you want to extend the available protocols for a server/host. By default, only the http/1.1 protocol (which includes the compatibility with 1.0 and 0.9 clients) is allowed.

For example, if you want to support HTTP/2 for a server with TLS, specify:

Protocols h2 http/1.1

Valid protocols are http/1.1 for http and https connections, h2 on https connections and h2c for http connections. Modules may enable more protocols.

It is safe to specify protocols that are unavailable/disabled. Such protocol names will simply be ignored.

Protocols specified in base servers are inherited for virtual hosts only if the virtual host has no own Protocols directive. Or, the other way around, Protocols directives in virtual hosts replace any such directive in the base server.

See also

top

ProtocolsHonorOrder Directive

Description:Determines if order of Protocols determines precedence during negotiation
Syntax:ProtocolsHonorOrder On|Off
Default:ProtocolsHonorOrder On
Context:server config, virtual host
Status:Core
Module:core
Compatibility:Only available from Apache 2.4.17 and later.

This directive specifies if the server should honor the order in which the Protocols directive lists protocols.

If configured Off, the client supplied list order of protocols has precedence over the order in the server configuration.

With ProtocolsHonorOrder set to on (default), the client ordering does not matter and only the ordering in the server settings influences the outcome of the protocol negotiation.

See also

top

QualifyRedirectURL Directive

Description:Controls whether the REDIRECT_URL environment variable is fully qualified
Syntax:QualifyRedirectURL On|Off
Default:QualifyRedirectURL Off
Context:server config, virtual host, directory
Override:FileInfo
Status:Core
Module:core
Compatibility:Directive supported in 2.4.18 and later. 2.4.17 acted as if 'QualifyRedirectURL On' was configured.

This directive controls whether the server will ensure that the REDIRECT_URL environment variable is fully qualified. By default, the variable contains the verbatim URL requested by the client, such as "/index.html". With QualifyRedirectURL On, the same request would result in a value such as "http://www.example.com/index.html".

Even without this directive set, when a request is issued against a fully qualified URL, REDIRECT_URL will remain fully qualified.

top

ReadBufferSize Directive

Description:Size of the buffers used to read data
Syntax:ReadBufferSize bytes
Default:ReadBufferSize 8192
Context:server config, virtual host, directory
Status:Core
Module:core
Compatibility:2.4.27 and later

This directive allows to configure the size (in bytes) of the memory buffer used to read data from the network or files.

A larger buffer can increase peformances with larger data, but consumes more memory per connection. The minimum configurable size is 1024.

top

RegexDefaultOptions Directive

Description:Allow to configure global/default options for regexes
Syntax:RegexDefaultOptions [none] [+|-]option [[+|-]option] ...
Default:RegexDefaultOptions DOTALL DOLLAR_ENDONLY
Context:server config
Status:Core
Module:core
Compatibility:Only available from Apache 2.4.30 and later.

This directive adds some default behavior to ANY regular expression used afterwards.

Any option preceded by a '+' is added to the already set options.
Any option preceded by a '-' is removed from the already set options.
Any option without a '+' or a '-' will be set, removing any other already set option.
The none keyword resets any already set options.

option can be:

ICASE
Use a case-insensitive match.
EXTENDED
Perl's /x flag, ignore (unescaped-)spaces and comments in the pattern.
DOTALL
Perl's /s flag, '.' matches newline characters.
DOLLAR_ENDONLY
'$' matches at end of subject string only.
# Add the ICASE option for all regexes by default
RegexDefaultOptions +ICASE
...
# Remove the default DOLLAR_ENDONLY option, but keep any other one
RegexDefaultOptions -DOLLAR_ENDONLY
...
# Set the DOTALL option only, resetting any other one
RegexDefaultOptions DOTALL
...
# Reset all defined options
RegexDefaultOptions none
...
top

RegisterHttpMethod Directive

Description:Register non-standard HTTP methods
Syntax:RegisterHttpMethod method [method [...]]
Context:server config
Status:Core
Module:core
Compatibility:Available in Apache HTTP Server 2.4.24 and later

This directive may be used to register additional HTTP methods. This is necessary if non-standard methods need to be used with directives that accept method names as parameters, or to allow particular non-standard methods to be used via proxy or CGI script when the server has been configured to only pass recognized methods to modules.

See also

top

RLimitCPU Directive

Description:Limits the CPU consumption of processes launched by Apache httpd 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 from Apache httpd children servicing requests, not the Apache httpd children themselves. This includes CGI scripts and SSI exec commands, but not any processes forked from the Apache httpd 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 httpd 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 from Apache httpd children servicing requests, not the Apache httpd children themselves. This includes CGI scripts and SSI exec commands, but not any processes forked from the Apache httpd 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 httpd 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 from Apache httpd children servicing requests, not the Apache httpd children themselves. This includes CGI scripts and SSI exec commands, but not any processes forked from the Apache httpd 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

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.

This directive is used to control how Apache httpd finds the interpreter used to run CGI scripts. The default setting is Script. This causes Apache httpd 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 httpd falls back to the behavior of the Script option.

Security

Be careful when using ScriptInterpreterSource Registry with ScriptAlias'ed directories, because Apache httpd 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 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

SeeRequestTail Directive

Description:Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
Syntax:SeeRequestTail On|Off
Default:SeeRequestTail Off
Context:server config
Status:Core
Module:core
Compatibility:Available in Apache httpd 2.2.7 and later.

mod_status with ExtendedStatus On displays the actual request being handled. For historical purposes, only 63 characters of the request are actually stored for display purposes. This directive controls whether the first 63 characters are stored (the previous behavior and the default) or if the last 63 characters are. This is only applicable, of course, if the length of the request is 64 characters or greater.

If Apache httpd is handling GET /disk1/storage/apache/htdocs/images/imagestore1/food/apples.jpg HTTP/1.1 mod_status displays as follows:

Off (default) GET /disk1/storage/apache/htdocs/images/imagestore1/food/apples
On orage/apache/htdocs/images/imagestore1/food/apples.jpg HTTP/1.1
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. The ServerAlias may include wildcards, if appropriate.

<VirtualHost *:80>
  ServerName server.example.com
  ServerAlias server server2.example.com server2
  ServerAlias *.example.com
  UseCanonicalName Off
  # ...
</VirtualHost>

Name-based virtual hosts for the best-matching set of <virtualhost>s are processed in the order they appear in the configuration. The first matching ServerName or ServerAlias is used, with no different precedence for wildcards (nor for ServerName vs. ServerAlias).

The complete list of names in the <VirtualHost> directive are treated just like a (non wildcard) ServerAlias.

See also

top

ServerName Directive

Description:Hostname and port that the server uses to identify itself
Syntax:ServerName [scheme://]domain-name|ip-address[:port]
Context:server config, virtual host
Status:Core
Module:core

The ServerName directive sets the request scheme, hostname and port that the server uses to identify itself.

ServerName is used (possibly in conjunction with ServerAlias) to uniquely identify a virtual host, when using name-based virtual hosts.

Additionally, this is used when creating self-referential redirection URLs when UseCanonicalName is set to a non-default value.

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

The ServerName directive may appear anywhere within the definition of a server. However, each appearance overrides the previous appearance (within that server).

If no ServerName is specified, the server attempts to deduce the client visible hostname by first asking the operating system for the system hostname, and if that fails, performing a reverse lookup on an IP address present on the system.

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.

Sometimes, the server runs behind a device that processes SSL, such as a reverse proxy, load balancer or SSL offload appliance. When this is the case, specify the https:// scheme and the port number to which the clients connect in the ServerName directive to make sure that the server generates the correct self-referential URLs.

See the description of the UseCanonicalName and UseCanonicalPhysicalPort directives for settings which determine whether self-referential URLs (e.g., by the mod_dir module) will refer to the specified port, or to the port number given in the client's request.

Failure to set ServerName to a name that your server can resolve to an IP address will result in a startup warning. httpd will then use whatever hostname it can determine, using the system's hostname command. This will almost never be the hostname you actually want.

httpd: Could not reliably determine the server's fully qualified domain name, using rocinante.local for ServerName

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.

ServerRoot "/home/httpd"

The default location of ServerRoot may be modified by using the --prefix argument to configure, and most third-party distributions of the server have a different default location from the one listed above.

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

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 Full (or not specified)
Server sends (e.g.): Server: Apache/2.4.2 (Unix) PHP/4.2.2 MyMod/1.2
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.4
ServerTokens Min[imal]
Server sends (e.g.): Server: Apache/2.4.2
ServerTokens OS
Server sends (e.g.): Server: Apache/2.4.2 (Unix)

This setting applies to the entire server, and cannot be enabled or disabled on a virtualhost-by-virtualhost basis.

This directive also controls the information presented by the ServerSignature directive.

Setting ServerTokens to less than minimal is not recommended because it makes it more difficult to debug interoperational problems. Also note that disabling the Server: header does nothing at all to make your server more secure. The idea of "security through obscurity" is a myth and leads to a false sense of safety.

See also

top

SetHandler Directive

Description:Forces all matching files to be processed by a handler
Syntax:SetHandler handler-name|none|expression
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Core
Module:core
Compatibility:expression argument 2.4.19 and later

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 could also use this directive to configure a particular handler for files with a particular file extension. For example:

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

String-valued expressions can be used to reference per-request variables, including backreferences to named regular expressions:

<LocationMatch ^/app/(?<sub>[^/]+)/>
     SetHandler "proxy:unix:/var/run/app_%{env:MATCH_sub}.sock|fcgi://localhost:8080"
</LocationMatch>

You can override an earlier defined SetHandler directive by using the value None.

Note

Because SetHandler overrides default handlers, normal behavior such as handling of URLs ending in a slash (/) as directories or index files is suppressed.

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

StrictHostCheck Directive

Description:Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Syntax:StrictHostCheck ON|OFF
Default:StrictHostCheck OFF
Context:server config, virtual host
Status:Core
Module:core
Compatibility:Added in 2.4.49

By default, the server will respond to requests for any hostname, including requests addressed to unexpected or unconfigured hostnames. While this is convenient, it is sometimes desirable to limit what hostnames a backend application handles since it will often generate self-referential responses.

By setting StrictHostCheck to ON, the server will return an HTTP 400 error if the requested hostname hasn't been explicitly listed by either ServerName or ServerAlias in the virtual host that best matches the details of the incoming connection.

This directive also allows matching of the requested hostname to hostnames specified within the opening VirtualHost tag, which is a relatively obscure configuration mechanism that acts like additional ServerAlias entries.

This directive has no affect in non-default virtual hosts. The value inherited from the global server configuration, or the default virtualhost for the ip:port the underlying connection, determine the effective value.

top

TimeOut Directive

Description:Amount of time the server will wait for certain events before failing a request
Syntax:TimeOut seconds
Default:TimeOut 60
Context:server config, virtual host
Status:Core
Module:core

The TimeOut directive defines the length of time Apache httpd will wait for I/O in various circumstances:

top

TraceEnable Directive

Description:Determines the behavior on TRACE requests
Syntax:TraceEnable [on|off|extended]
Default:TraceEnable on
Context:server config, virtual host
Status:Core
Module:core

This directive overrides the behavior of TRACE for both the core server and mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616, which disallows any request body to accompany the request. TraceEnable off causes the core server and mod_proxy to return a 405 (Method not allowed) error to the client.

Finally, for testing and diagnostic purposes only, request bodies may be allowed using the non-compliant TraceEnable extended directive. The core (as an origin server) will restrict the request body to 64Kb (plus 8Kb for chunk headers if Transfer-Encoding: chunked is used). The core will reflect the full headers and all chunk headers with the response body. As a proxy server, the request body is not restricted to 64Kb.

Note

Despite claims to the contrary, enabling the TRACE method does not expose any security vulnerability in Apache httpd. The TRACE method is defined by the HTTP/1.1 specification and implementations are expected to support it.

top

UNCList Directive

Description:Controls what UNC host names can be accessed by the server
Syntax:UNCList hostname [hostname...]
Default:unset
Context:server config
Status:Core
Module:core
Compatibility:Added in 2.4.60, Windows only.

During request processing, requests to access a filesystem path that resolves to a UNC path will fail unless the hostname in the UNC path has been specified by this directive. The intent is to limit access to paths derived from untrusted inputs.

UNCList example.com other.example.com

Security

The values specified by this directive are only checked by some components of the server, prior to accessing filesystem paths that may be inadvertently derived from untrusted inputs.

Windows systems should be isolated at the network layer from making outbound SMB/NTLM calls to unexpected destinations as a more comprehensive and pre-emptive measure.

Directive Ordering

This directive should be placed before UNC paths used in httpd.conf. Multiple occurrences of the directive reset the list.

top

UnDefine Directive

Description:Undefine the existence of a variable
Syntax:UnDefine parameter-name
Context:server config
Status:Core
Module:core

Undoes the effect of a Define or of passing a -D argument to httpd.

This directive can be used to toggle the use of <IfDefine> sections without needing to alter -D arguments in any startup scripts.

Variable names may not contain colon ":" characters, to avoid clashes with RewriteMap's syntax.

Virtual Host scope and pitfalls

While this directive is supported in virtual host context, the changes it makes are visible to any later configuration directives, beyond any enclosing virtual host.

See also

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 httpd must construct a self-referential URL -- that is, a URL that refers back to the same server. With UseCanonicalName On Apache httpd 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 httpd 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 httpd will redirect them to http://www.example.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.example.com -- see the FAQ on this subject for more information). But if UseCanonicalName is set Off, then Apache httpd 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 httpd 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

UseCanonicalPhysicalPort Directive

Description:Configures how the server determines its own port
Syntax:UseCanonicalPhysicalPort On|Off
Default:UseCanonicalPhysicalPort Off
Context:server config, virtual host, directory
Status:Core
Module:core

In many situations Apache httpd must construct a self-referential URL -- that is, a URL that refers back to the same server. With UseCanonicalPhysicalPort On, Apache httpd will, when constructing the canonical port for the server to honor the UseCanonicalName directive, provide the actual physical port number being used by this request as a potential port. With UseCanonicalPhysicalPort Off, Apache httpd will not ever use the actual physical port number, instead relying on all configured information to construct a valid port number.

Note

The ordering of the lookup when the physical port is used is as follows:

UseCanonicalName On
  1. Port provided in Servername
  2. Physical port
  3. Default port for the scheme/protocol (such as 80 or 443)
UseCanonicalName Off | DNS
  1. Parsed port from Host: header
  2. Physical port
  3. Port provided in Servername
  4. Default port for the scheme/protocol (such as 80 or 443)

With UseCanonicalPhysicalPort Off, the physical ports are removed from the ordering.

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 any of the following, optionally followed by a colon and a port number (or *):

<VirtualHost 10.1.2.3:80>
  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>

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 [2001:db8::a00:20ff:fea7:ccea]:80>
  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 httpd listens on. You may need to ensure that Apache httpd is listening on the correct addresses using Listen.

A ServerName should be specified inside each <VirtualHost> block. If it is absent, the ServerName from the "main" server configuration will be inherited.

When a request is received, the server first maps it to the best matching <VirtualHost> based on the local IP address and port combination only. Non-wildcards have a higher precedence. If no match based on IP and port occurs at all, the "main" server configuration is used.

If multiple virtual hosts contain the best matching IP address and port, the server selects from these virtual hosts the best match based on the requested hostname. If no matching name-based virtual host is found, then the first listed virtual host that matched the IP address will be used. As a consequence, the first listed virtual host for a given IP address and port combination is the default virtual host for that IP and port combination.

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  |  es  |  fr  |  ja  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/core.html.tr.utf80000664000175100017510000116621714743132254020760 0ustar covenercovener core - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Temel Özellikleri

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  tr 

Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.
Açıklama:Apache HTTP Sunucusunda daima mevcut olan çekirdek özellikler
Durum:Çekirdek
Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

AcceptFilter Yönergesi

Açıklama:Bir protokolün dinleyici soketleri için en iyilemeleri ayarlar
Sözdizimi:AcceptFilter protocol kabul_süzgeci
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core

Bu yönerge Protocol yönergesinde belirtilen protokol türüne göre bir dinleme soketinin işletim sistemine özgü en iyilemelerini etkin kılar. İşletim sistemi çekirdeği için temel önerme veri alınıncaya kadar veya HTTP isteğinin tamamı tamponlanana kadar sunucu sürecine bir soket tahsis etmemektir. Şimdilik sadece FreeBSD’nin Kabul Süzgeçleri ve Linux’un soket seçeneklerinden TCP_DEFER_ACCEPT ve Windows'un en iyilenmiş AcceptEx() işlevi desteklenmektedir.

Değiştirge olarak none kullanımı, protokolün kabul süzgeçlerini iptal edecektir. ftp: veya nntp gibi sunucunun baştan bir veri göndermesinin gerekli olduğu protokoller için kullanışlıdır. Örnek:

AcceptFilter nntp none

Öntanımlı protokol isimleri port 443 için https ve tüm diğer portlar için http'dir. Dinlenmesi için başka bir port ile ilgili bir protokol belirtmek isterseniz Listen yönergesine protokol argümanını ekleyin.

FreeBSD için öntanımlı değerler:

AcceptFilter http httpready
AcceptFilter https dataready

httpready kabul süzgeci HTTP isteklerinin tamamını işletim sistemi çekirdeği seviyesinde tamponlar. Çekirdek isteğin tamamını alır almaz sunucuya gönderir. Ayrıntılar için accf_http(9) kılavuz sayfasına bakınız. HTTPS istekleri şifrelenmiş olduğundan sadece accf_data(9) süzgeci kullanılır.

Linux’taki öntanımlı değerler:

AcceptFilter http data
AcceptFilter https data

Linux’un TCP_DEFER_ACCEPT soket seçeneği HTTP isteklerinin tamponlanmasını desteklemez. none dahil her değer dinleyici üzerinde TCP_DEFER_ACCEPT seçeneğini etkin kılar. Daha ayrıntılı bilgi edinmek için Linux tcp(7) kılavuz sayfasına bakınız.

Windows’taki öntanımlı değerler::

AcceptFilter http connect
AcceptFilter https connect

Windows'un mpm_winnt modülü AcceptEx() arayüzünü açıp kapamak için AcceptFilter'i yorumlar ve http protokol tamponlamasını desteklemez. connect, AcceptEx() arayüzünü kullanacak, ayrıca uç ağ adresleri de alınacak, fakat none gibi connect seçeneği de ilk veri aktarımını beklemeyecektir.

Windows'ta none AcceptEx()'ten ziyade accept() kullanır ve ağ soketlerini bağlantılar arasında yer değiştirmez. Sürücü desteği bozuk ağ bağdaştırıcılarından başka vpn sürücüleri gibi bazı sanal ağ sağlayıcılar veya spam, virus veya casus yazılım süzgeçleri için kullanışlıdır.

data AcceptFilter (Windows)

2.4.23 ve öncesi sürümlerde, Windows data accept süzgeci veri aktarılana kadar bekletildikten sonra ilk veri tamponlanır ve uç ağ adresi için tek bir AcceptEx() çağrısı yapılır. Bu gerçeklenim hizmet reddi saldırısına konu olduğundan iptal edilmiştir.

httpd'nin şu anki dağıtımları için Windows'da connect süzgeci öntanımlıdır ve data belirtilmiş olsa dahi connect belirtilmiş gibi davranılır. Önceki sürümleri kullananların AcceptFilter satırını yukarıdaki gibi connect süzgecine ayarlamaları gerekmektedir.

Ayrıca bakınız:

top

AcceptPathInfo Yönergesi

Açıklama:Dosya isminden sonra belirtilen yol verisini kabul veya reddeder.
Sözdizimi:AcceptPathInfo On|Off|Default
Öntanımlı:AcceptPathInfo Default
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core

Bu yönerge, istekte dosya isminden sonra (dizinde belirtilen dosya bulunmayabilir) belirtilen yol verisinin kabul edilip edilmeyeceğini denetler. Dosya isminden sonra belirtilen yol verisi PATH_INFO ortam değişkeninde betiklerin kullanımına sunulabilir.

Örneğin, içinde sadece here.html dosyası bulunan bir /test/ dizinimiz olsun. /test/here.html/more ve /test/nothere.html/more isteklerinin her ikisi de PATH_INFO değişkenine /more verisinin atanmasını sağlar.

AcceptPathInfo yönergesine atanabilecek argüman sayısı üçtür:

Off
Sadece dosya isminden sonra yol verisi bulunmayan istekler kabul edilir. Yukarıdaki örnekteki gibi /test/here.html/more şeklindeki istekler bir 404 (Nesne bulunamadı) hatasıyla sonuçlanır.
On
Mevcut bir dosyaya ait bir dosya isminden sonra bir yol verisinin de belirtildiği istekler kabul edilir. Yukarıdaki örnekteki gibi /test/here.html/more şeklindeki istekler, /test/here.html geçerli bir dosya olduğu takdirde kabul edilir.
Default
Dosya isminden sonra yol verisi belirtilen isteklerin nasıl ele alınacağı istekten sorumlu eylemci tarafından saptanır. Normal dosyalar için çekirdek eylemci öntanımlı olarak PATH_INFO isteklerini reddeder. cgi-script ve isapi-handler gibi betiklere hizmet eden eylemciler ise genellikle PATH_INFO isteklerini öntanımlı olarak kabul ederler.

AcceptPathInfo yönergesinin birincil amacı eylemcinin PATH_INFO istekleri hakkında verdiği kabul veya red kararını geçersiz kılabilmenizi sağlamaktır. Örneğin, PATH_INFO’ya dayalı olarak içerik üretmek için INCLUDES gibi bir süzgeç kullandığınız takdirde bu geçersizleştirme zorunlu olur. Normal dosyalar için çekirdek eylemci normal olarak isteği reddederdi, böyle bir durumda bir betiği etkin kılmak için aşağıdaki gibi bir yapılandırma kullanabilirsiniz:

<Files "mypaths.shtml">
  Options +Includes
  SetOutputFilter INCLUDES
  AcceptPathInfo On
</Files>
top

AccessFileName Yönergesi

Açıklama:Dağıtık yapılandırma dosyasının ismi belirtilir.
Sözdizimi:AccessFileName filename [filename] ...
Öntanımlı:AccessFileName .htaccess
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Belge yolu üzerindeki dizinlerde dağıtık yapılandırma dosyalarının bulunmasına izin verilmişse sunucu bir isteği işlerken önce bu dizinlerde bu yönergede belirtilmiş yapılandırma dosyasını arar. Örnek:

AccessFileName .acl

Sunucu, /usr/local/web/index.html belgesini döndürmeden önce,

<Directory "/">
    AllowOverride None
</Directory>

şeklinde bir yapılandırma ile iptal edilmiş olmadıkça yönergeler için /.acl, /usr/.acl, /usr/local/.acl ve /usr/local/web/.acl dosyalarını okur.

Ayrıca bakınız:

top

AddDefaultCharset Yönergesi

Açıklama:Bir yanıtın içerik türü text/plain veya text/html olduğunda eklenecek öntanımlı karakter kümesi parametresini belirler.
Sözdizimi:AddDefaultCharset On|Off|karküm
Öntanımlı:AddDefaultCharset Off
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core

Bu yönerge, yanıtın içerik türü text/plain veya text/html olmak şartıyla yanıta eklenecek karakter kümesini (karakter kodlamasınının ismini) belirler. Bu, asıl davranış çoğunlukla kullanıcının istemci yapılandırmasına bağlı olmakla birlikte, yanıtın gövdesinde META elemanı vasıtasıyla belirtilmiş karakter kümesini geçersiz kılar. AddDefaultCharset Off şeklinde bir atama bu işlevselliği iptal eder. AddDefaultCharset On ile bu işlevsellik etkin kılınmaktan başka iso-8859-1 karakter kümesini öntanımlı olarak yanıta eklenir. Yönergede karküm olarak belirtilecek değerler, Genel Ağ ortam türlerinde (MIME türlerinde) kullanmak üzere IANA’da kayıtlı karakter kümesi değerlerinden biri olmalıdır. Örnek:

AddDefaultCharset utf-8

AddDefaultCharset yönergesi sadece, metin kaynaklarının hepsinin aynı karakter kümesine sahip olduğu bilindiği takdirde ve her birinde ayrı ayrı karakter kümesi belirtmek çok külfetli olacaksa kullanılmalıdır. Buna bir örnek, CGI betikleri tarafından üretilmiş içeriğe sahip kaynaklara karakter kümesinin eklenmesidir; böyle kaynaklar çıktıda kullanıcı tarafından sağlanmış veri içermeleri nedeniyle karşı siteden kaynaklanan betikli saldırılardan zarar görebilir. Bununla birlikte, bir öntanımlı karakter kümesi belirtmek, tarayıcılarında “karakter kodlamasını kendiliğinden sapta” özelliğini etkin kılmış kullanıcıları korumayacağından daha iyi bir çözüm bu betikleri bu tür saldırılara karşı düzeltmek veya en iyisi silmektir.

Ayrıca bakınız:

top

AllowEncodedSlashes Yönergesi

Açıklama:Kodlanmış dosya yolu ayracı içeren URL’lere izin verilip verilmeyeceğini belirler.
Sözdizimi:AllowEncodedSlashes On|Off|NoDecode
Öntanımlı:AllowEncodedSlashes Off
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:NoDecode seçeneği Apache httpd 2.3.12 ve sonrasında mevcuttur.

AllowEncodedSlashes yönergesi kodlanmış dosya yolu ayracı içeren URL’lere izin verir (/ yerine %2F ve ek olarak \ için ilgili sistemlerde %5C kullanılmış URL’ler).

Off öntanımlı değeriyle, böyle URL’ler bir 404 (Nesne bulunamadı) hatasıyla reddedilirler.

On değeriyle, böyle URL’ler kabul edilir ve kodlanmış dosya yolu ayraçları kodlanmış diğer karakterler gibi çözümlenir.

NoDecode değeriyle, böyle URL’ler kabul edilir fakat kodlanmış dosya yolu ayraçları çözümlenmeden kodlanmış halde bırakılır.

AllowEncodedSlashes On, çoğunlukla PATH_INFO ile bir arada kullanıldığı zaman kullanışlıdır.

Ek Bilgi

Kodlanmış bölü çizgileri yol bilgisi için gerekliyse bir güvenlik ölçütü olarak NoDecode kullanımı şiddetle önerilir. Kodlanmış bölü çizgilerinin çözümlenmesine izin vermek güvensiz olması olası yollara izin vermek olurdu.

Ayrıca bakınız:

top

AllowOverride Yönergesi

Açıklama:.htaccess dosyalarında bulunmasına izin verilen yönerge türleri belirtilir.
Sözdizimi:AllowOverride All|None|yönerge-türü [yönerge-türü] ...
Öntanımlı:AllowOverride None (2.3.9 ve sonrası), AllowOverride All (2.3.8 ve öncesi)
Bağlam:dizin
Durum:Çekirdek
Modül:core

Sunucu AccessFileName yönergesi ile belirtildiği şekilde bir .htaccess dosyasına rastlarsa önceki yapılandırma yönergelerinin hangilerinin geçersiz kılınmak üzere bildirildiğini bilmek ister.

Sadece <Directory> bölümlerinde geçerli

AllowOverride yönergesi, <Location>, <DirectoryMatch> veya <Files> bölümlerinde değil, sadece düzenli ifade içermeyen <Directory> bölümlerinde geçerlidir.

Bu yönergeye ve AllowOverrideList yönergesine değer olarak None belirtilirse .htaccess dosyaları tamamen yok sayılır. Bu durumda, sunucu dosya sisteminde rastladığı .htaccess dosyalarını okumaya dahi çalışmayacaktır.

Bu yönergeye All değeri atanırsa, .htaccess bağlamında kullanılabilecek her yönergeye .htaccess dosyalarında izin verilir. (Hangi yönerge-türü türü için hangi yönergelerin etkin olduğunu görmek için .htaccess için Geçersizleştirme Sınıfları sayfasına bakınız)

yönerge-türü olarak aşağıdaki yönerge grup isimlerinden biri belirtilebilir:

AuthConfig
AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require ve benzeri yetkilendirme yönergelerinin kullanımını izin verilir.
FileInfo
Belge türünü denetleyen mod_mime Add* ve Remove* yönergeleri, ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter yönergeleri ve benzerleri ile Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName belge meta veri yönergelerinin, mod_rewrite modülündeki RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule yönergelerinin, mod_alias modülündeki Redirect, RedirectTemp, RedirectPermanent, RedirectMatch) yönergelerinin ve mod_actions modülündeki Action yönergesinin kullanımına izin verilir.
Indexes
Dizin içeriğinin listelenmesini denetleyen AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName yönergelerinin ve benzerlerinin kullanımına izin verilir.
Limit
Konak erişimini denetleyen Allow, Deny ve Order yönergelerinin kullanımına izin verilir.
Nonfatal=[Override|Unknown|All]
.htaccess dosyalarındaki sözdizimi hatalarının ölümcül olarak ele alınmaması için AllowOverride yönergesinin kullanımına izin verir; bunun yerine bir dahili sunucu hatasına sebep olur, izin verilmeyen veya tanınmayan yönergeler yoksayılır ve günlüğe bir uyarı çıktılanır:
  • Nonfatal=Override ile AllowOverride tarafından yasaklanmış yönergeler ölümcül olarak ele alınmaz.
  • Nonfatal=Unknown ile bilinmeyen yönergeler ölümcül olarak ele alınmaz. Yazım hatalarını ve mevcut olmayan bir modül tarafından gerçeklenmiş yönergeleri kapsar.
  • Nonfatal=All ile yukarıdakilerin ikisi de ölümcül olarak ele alınmaz.

Geçerli bir yönergedeki yazım hatalarının hala dahili bir sunucu hatasına sebep olacağına dikkat ediniz.

Güvenlik

Ölümcül olmayan hatalar .htaccess kullanıcıları için güvenlikle ilgili sorunlara yol açabilir. Örneğin AllowOverride AuthConfig'e izin vermezse kullanıcıların siteye erişimini kısıtlayan yapılandırma iptal edilmiş olur.
Options[=seçenek,...]
Dizinlere özgü özellikleri denetleyen Options ve XBitHack yönergelerinin kullanımına izin verilir. Options komutunda belirtilecek seçenekler bir eşit işaretinden sonra aralarına sadece virgül konarak, fakat virgülden sonra boşluk bırakmadan belirtilebilir.

Options'ın örtük iptali

.htaccess dosyalarında kullanılabilen seçenek listesi bu yönergeyle sınırlanabilirse de herhangi bir Options yönergesine izin verildiği sürece miras alınmış diğer seçenekler göreli olmayan sözdizimi kullanılarak iptal edilebilir. Başka bir deyişle, bu mekanizma diğerlerinin değerlerini korumasına izin verirken belli bir seçeneği değerini korumaya zorlayamaz.

AllowOverride Options=Indexes,MultiViews

Örnek:

AllowOverride AuthConfig Indexes

Bu örnekte AuthConfig ve Indexes grubundaki yönergeler bir dahili sunucu hatasına yol açmayacaktır.

Güvenlik ve başarımı arttırmak için <Directory "/"> bloğu içinde AllowOverride yönergesine None dışında bir değer atamayın. Böyle yapmak yerine bir .htaccess dosyası yerleştirmeyi düşündüğünüz dizine ait bir <Directory> bloğu olması daha iyidir.

Ayrıca bakınız:

top

AllowOverrideList Yönergesi

Açıklama:.htaccess dosyalarında izin verilecek yönergeler tek tek belirtilir
Sözdizimi:AllowOverrideList None|yönerge [yönerge-türü] ...
Öntanımlı:AllowOverrideList None
Bağlam:dizin
Durum:Çekirdek
Modül:core

Sunucu bir .htaccess dosyası (AccessFileName tarafından belirtildiği gibi) bulduğunda önceki yapılandırma yönergelerini geçersiz kılabilen bu dosyada hangi yönergelerin bildirildiğini bilmek ister.

Sadece <Directory> bölümlerinde kullanılabilir

AllowOverrideList sadece <Directory> bölümlerinde düzenli ifadeler olmaksızın belirtilmişse kullanılabilir; <Location>, <DirectoryMatch> veya <Files> bölümlerinde değil.

Bu yönergeye ve AllowOverride yönergesine None atanmışsa .htaccess dosyaları tamamen yoksayılır. Bu durumda sunucu dosya sistemindeki .htaccess dosyalarını okumaya bile çalışmayacaktır.

Örnek:

AllowOverride None
AllowOverrideList Redirect RedirectMatch

Yukarıdaki örnekte sadece Redirect ve RedirectMatch yönergelerine izin verilmektedir. Tüm diğerleri dahili bir sunucu hatasına sebep olacaktır.

Örnek:

AllowOverride AuthConfig
AllowOverrideList CookieTracking CookieName

Yukarıdaki örnekte AllowOverride yönergesi AuthConfig yönerge grubuna izin verirken AllowOverrideList yönergesi FileInfo yönerge grubundan yalnız iki yönergeye izin vermektedir. Tüm diğerleri dahili bir sunucu hatasına sebep olacaktır.

Ayrıca bakınız:

top

CGIMapExtension Yönergesi

Açıklama:CGI betik yorumlayıcısını saptama tekniğini belirler.
Sözdizimi:CGIMapExtension cgi-yolu .uzantı
Bağlam:dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:Sadece NetWare’de geçerlidir.

Bu yönerge Apache httpd’nin CGI bekitlerini çalıştırmak için kullanacağı yorumlayıcıyı nasıl bulacağını denetlemek için kullanılır. Örneğin, CGIMapExtension sys:\foo.nlm .foo satırı .foo uzantılı CGI betik dosyalarının FOO yorumlayıcıya aktarılmasını sağlar.

top

CGIPassAuth Yönergesi

Açıklama:HTTP yetkilendirme başlıklarının betiklere CGI değişkenleri olarak aktarılmasını etkin kılar
Sözdizimi:CGIPassAuth On|Off
Öntanımlı:CGIPassAuth Off
Bağlam:dizin, .htaccess
Geçersizleştirme:AuthConfig
Durum:Çekirdek
Modül:core
Uyumluluk: Apache HTTP Sunucusunun 2.4.13 ve sonraki sürümlerinde kullanılabilmektedir

CGIPassAuth yönergesi, HTTP Temel kimlik doğrulamasını gerçekleştiren betikler için gereken Authorization gibi HTTP yetkilendirme başlıklarına betiklerin erişebilmesini sağlar. Normalde bu HTTP başlıkları betiklerden gizli olup sunucuda HTTP Temel kimlik kanıtlaması etkin kılındığında sunucuya erişmekte kullanılan kullanıcı kimliklerinin ve parolalarının betikler tarafından görülmemesini mümkün kılar. Bu yönerge, HTTP Temel kimlik kanıtlamasını betiklerin gerçekleştirmesini sağlamak için kullanılmalıdır.

Apache HTTP Sunucusunun önceki sürümlerinde derleme sırasında kullanılabilen SECURITY_HOLE_PASS_AUTHORIZATION sabitinin yerine bu yönerge kullanılabilir.

Bu ayarlama mod_cgi, mod_cgid, mod_proxy_fcgi, mod_proxy_scgi ve benzerleri gibi ap_add_common_vars() kullanan modüller tarafından kabul görür. Özellikle, isteği alışılmış tarzda işleme sokmayıp bu arayüzü kullanan modülleri etkiler. Ayrıca, ap_add_common_vars() kullanmayan üçüncü parti modüller de bu ayarlamayı kullanmayı tercih edebilir.

top

CGIVar Yönergesi

Açıklama:Bazı CGI değişkenlerinin nasıl atanacağını belirler
Sözdizimi:CGIVar değişken kural
Bağlam:dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:Apache HTTP Server 2.4.21 ve sonrasında kullanılabilir

Bu yönerge bazı CGI değişkenlerinin nasıl atanacağını belirler.

REQUEST_URI kuralları:

original-uri (default)
Değer özgün istek satırından alınır ve dahili yöneldirmeler veya istenen özkaynakları değiştiren alt istekler dikkate alınmaz.
current-uri
Değer özgün istek satırından farklı olabilecek dahili yönlendirmeleri veya istenen özkaynakları değiştiren alt istekleri de yansıtır.
top

ContentDigest Yönergesi

Açıklama:Content-MD5 HTTP yanıt başlıklarının üretimini etkin kılar.
Sözdizimi:ContentDigest On|Off
Öntanımlı:ContentDigest Off
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Options
Durum:Çekirdek
Modül:core

Bu yönerge RFC2616 ve RFC1864’te tanımlandığı gibi Content-MD5 üretimini etkin kılar.

MD5, verideki herhangi bir değişikliğin ileti özetinin değişmesi olarak yansıması nedeniyle yüksek derecede itimat sağlayan keyfi uzunlukta bir "ileti özeti" (bazen "parmakizi" dendiği de olur) hesaplama algoritmasıdır.

Content-MD5 başlığı öğe gövdesinin iki uç arasında ileti bütünlük sınamasının yapılabilmesini sağlar. Bir istemci veya vekil aktarılan öğe gövdesinde rastlantısal bir değişiklik olup olmadığını saptamak için bu başlığın doğruluğunu sınayabilir. Başlık örneği:

Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA==

Her istekte ileti özeti hesaplanacağından (değerler saklanmaz), bu yönergenin sunucunuzda başarım sorunlarına yol açacağına dikkat ediniz.

Content-MD5, herhangi bir modül değil, sadece core modülü tarafından sunulan belgeler için gönderilir. Örneğin, SSI belgeleri CGI betikleri tarafından çıktılanırlar ve bayt seviyesinden çıktılar bu başlığa sahip olmazlar.

top

DefaultRuntimeDir Yönergesi

Açıklama:Sunucunun çalışma anı dosyaları için temel dizin
Sözdizimi:DefaultRuntimeDir dizin-yolu
Öntanımlı:DefaultRuntimeDir DEFAULT_REL_RUNTIMEDIR (logs/)
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core
Uyumluluk:Apache 2.4.2 ve sonrasında kullanılabilmektedir.

DefaultRuntimeDir yönergesi sunucunun çalışma anında oluşturacağı dosyaların (paylaşımlı bellek, kilitler, vb.) saklanacağı dizini belirtmekte kullanılır. Göreli bir yol belirtilirse tam yol ServerRoot yönergesinde belirtilene göreli olacaktır.

Örnek

DefaultRuntimeDir scratch/

DefaultRuntimeDir için öntanımlı yer derleme sırasında DEFAULT_REL_RUNTIMEDIR #define satırı ile değiştirilebilir.

Bilgi: ServerRoot bu yönergeden önce belirtilmiş olmalıdır, aksi takdirde temel dizin için öntanımlı ServerRoot kullanılır.

Ayrıca bakınız:

top

DefaultType Yönergesi

Açıklama:Değeri none olduğu takdirde, bu yönergenin bir uyarı vermekten başka bir etkisi yoktur. Önceki sürümlerde, bu yönerge, sunucunun ortam türünü saptayamadığı durumda göndereceği öntanımlı ortam türünü belirlerdi.
Sözdizimi:DefaultType ortam-türü|none
Öntanımlı:DefaultType none
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:none değeri Apache httpd 2.2.7 ve sonrasında mevcuttur. Diğer tüm seçenekler Apache httpd'nin 2.3.x ve sonraki sürümleri için iptal edilmiştir.

Bu yönerge iptal edilmiştir. Yapılandırma dosyalarının geriye uyumluluğunu sağlamak için, öntanımlı bir ortam türünün olmadığını belirten none değeriyle belirtilebilir. Örnek:

DefaultType None

DefaultType None sadece httpd-2.2.7 ve sonrasında mevcuttur.

Ortam türlerini dosya uzantıları üzerinden yapılandırmak için AddType yönergesini ve mime.types yapılandırma dosyasını veya belli özkaynak türleri için ortam türlerini yapılandırmak için ForceType yönergesini kullanın.

top

Define Yönergesi

Açıklama:Bir değişken tanımlar
Sözdizimi:Define değişken-ismi [değişken-değeri]
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core

Tek değiştirgeli biçemi httpd’yi -D seçeneğiyle çalıştırmaya eşdeğerdir. Bu yönerge, başlatma betiğinde -D seçeneğinin argümanlarını değiştirme gereği duymaksızın <IfDefine> bölümlerini kullanıma sokmak için kullanılabilir.

Buna ek olarak, ikinci değiştirge belirtilirse yapılandırma değişkenine bu değer atanır. Değişken yapılandırmada ${VAR} sözdizimi ile kullanılabilir. Değişken daima küresel olarak tanımlı olup yapılandırma bölümünü sarmalayan etki alanı ile sınırlanmaz.

<IfDefine TEST>
  Define servername test.example.com
</IfDefine>
<IfDefine !TEST>
  Define servername www.example.com
  Define SSL
</IfDefine>
DocumentRoot "/var/www/${servername}/htdocs"

RewriteMap sözdizimi ile karışmalardan kaçınmak için değişken isimleri ikinokta ":" karakterleri içeremez.

Sanal konak bağlamı ve tuzaklar

Bu yönerge sanal konakta ve dizin içeriğinde desteklendiğinden yapılan değişiklikler (eşleşsin eşleşmesin) yönergeyi sarmalayan yapılandırma bölümünden başka, sonraki yapılandırma yönergelerine de görünür olur.

Ayrıca bakınız:

top

<Directory> Yönergesi

Açıklama:Sadece ismi belirtilen dosya sistemi dizininde ve bunun altdizinlerinde ve bunların içeriğinde uygulanacak bir yönerge grubunu sarmalar.
Sözdizimi:<Directory dizin-yolu> ... </Directory>
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

<Directory> ve </Directory> sadece ismi belirtilen dosya sistemi dizininde, bunun altdizinlerinde ve bu dizinlerin içindeki dosyalara uygulanacak bir yönerge grubunu sarmalamakta kullanılır. Bir dizin bağlamında kullanılabilecek her yönergeye izin verilir. dizin-yolu bir dizinin tam yolu olabileceği gibi Unix kabuk tarzı bir dosya ismi eşleştirme kalıbı da olabilir. Kalıp dizgesinde, ? herhangi bir tek karakterle, * herhangi bir karakter dizisiyle eşleşir. Ayrıca [] karakter aralıkları da kullanılabilir. ‘/’ karakteri ile hiçbir kalıp karakteri eşleşmez, bu bakımdan <Directory "/*/public_html"> ile /home/user/public_html değil, ama <Directory "/home/*/public_html"> eşleşecektir. Örnek:

<Directory "/usr/local/httpd/htdocs">
  Options Indexes FollowSymLinks
</Directory>

Dizin yollarında isterseniz önceleme kullanabilirsiniz, ancak eğer yol bazı boşluklar içeriyorsa mutlaka kullanmanız gerekir. Bir boşluk aksi belirtilmedikçe bir ifadenin sonunu belirlediğinden bu gereklidir.

dizin-yolu argümanlarını belirtirken dikkatli olmalısınız: Apache httpd’nin dosyalara erişmekte kullandığı dosya sistemi yolu ile bire bir eşleşmelidir. Belli bir <Directory> dizinine uygulanan yönergeler, aynı dizine farklı bir yoldan, örneğin başka bir sembolik bağ üzerinden erişilen dosyalara uygulanmayacaktır.

~ karakterine ek olarak düzenli ifadeler de kullanılabilir. Örnek:

<Directory ~ "^/www/[0-9]{3}">

</Directory>

yönergesi /www/ içindeki üç rakamdan oluşan dizinlerle eşleşecektir.

Eğer çok sayıda (düzenli ifade olmayan) <Directory> bölümü, bir dosyayı içeren bir dizinle veya üst dizinlerinden biri ile eşleşiyorsa, uygulama en kısa eşleşmedeki yönergelerden başlayarak .htaccess dosyalarındaki yönergelere kadar genişletilir. Örneğin,

<Directory "/">
  AllowOverride None
</Directory>

<Directory "/home">
  AllowOverride FileInfo
</Directory>

bölümleri ile /home/web/dir/doc.html belgesine erişirken şu aşamalardan geçilir:

Normal bölümlerin tamamı uygulanıncaya kadar düzenli ifadeler değerlendirilmez. Düzenli ifadelerin tamamı yapılandırma dosyasında görüldükleri sıraya göre sınanırlar. Örneğin,

<Directory ~ "abc$">
  # ... yönergeler burada ...
</Directory>

düzenli ifadeli bölümü, tüm normal <Directory> bölümleri ve .htaccess dosyaları uygulanıncaya kadar değerlendirilmeyecektir. Düzenli ifadeleri değerlendirmeye sıra gelince düzenli ifade /home/abc/public_html/abc ile eşleştirilecek ve buna ilişkin <Directory> uygulanacaktır.

<Directory "/"> için öntanımlı erişimin tüm erişime izin vermek oluşuna dikkat ediniz. Bunu şöyle bir blokla değiştirmeniz,

<Directory "/">
  Require all denied
</Directory>

ve erişilebilir olmasını istediğiniz dizinleri ayrıca belirtmeniz önerilir. Daha ayrıntılı bilgi edinmek için Güvenlik İpuçları belgesine bakınız.

Dizin bölümleri httpd.conf dosyasında yer alır. <Directory> yönergeleri iç içe olamazlar ve bir <Limit> veya <LimitExcept> bölümü içinde bulunamazlar.

Ayrıca bakınız:

top

<DirectoryMatch> Yönergesi

Açıklama:Bir düzenli ifade ile eşleşen dosya sistemi dizinlerinin içeriklerine uygulanacak bir yönerge grubunu sarmalar.
Sözdizimi:<DirectoryMatch düzifd> ... </DirectoryMatch>
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

<DirectoryMatch> and </DirectoryMatch> yönergeleri <Directory> gibi sadece ismi belirtilen dosya sistemi dizininde ve içindeki dosyalarda uygulanacak bir yönerge grubunu sarmalamakta kullanılır. Tek farkla argüman olarak bir düzenli ifade alır. Örnek:

<DirectoryMatch "^/www/(.+/)?[0-9]{3}/">
    # ...
</DirectoryMatch>

yönergesi /www/ içindeki (veya alt dizinlerindeki) üç rakamdan oluşan dizinlerle eşleşecektir.

Uyumluluk

2.3.9 öncesinde, bu yönerge örtük olarak (<Directory> gibi) alt dizinlere de uygulanırdı ve satır sonu simgesi ($) ile eşleşemezdi. 2.3.9 ve sonrasında, sadece ifade ile eşleşen dizinler sarmalanan yönerge grubundan etkilenmektedir.

Sondaki bölü çizgileri

Bu yönerge bir bölü çizgisi ile sonlanan veya sonlanmayan dizinler için yapılan isteklere uygulanır, dolayısıyla satır sonuna ($) çıpalanmış ifadeler dikkatli yazılmalıdır.

2.4.8 itibariyle, isimli gruplar ve geriye başvurular elde edilmekte olup ilgili isim büyük harfe çevrildikren sonra "MATCH_" ile öncelendikten sonra ortama yazılmaktadır. Böylece yol elemanlarına mod_rewrite gibi modüllerden veya düzenli ifadelerden başvurmak mümkün kılınmıştır. Karışıklığı önlemek için, numaralı (isimsiz) geriye başvurular yoksayılmaktadır. Bunların yerine isimli geriye başvurular kullanılmalıdır.

<DirectoryMatch "^/var/www/combined/(?<sitename>[^/]+)">
    require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</DirectoryMatch>

Ayrıca bakınız:

top

DocumentRoot Yönergesi

Açıklama:İstemciye görünür olan ana belge ağacının kök dizinini belirler.
Sözdizimi:DocumentRoot dizin-yolu
Öntanımlı:DocumentRoot "/usr/local/apache/htdocs"
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Bu yönerge httpd tarafından dosyalarının sunulacağı dizini belirler. Alias benzeri bir yönerge ile eşleşmedikçe, sunucu istenen URL’deki yolu, belge yolu haline getirmek için belge kök dizinine ekler. Örnek:

DocumentRoot "/usr/web"

yapılandırması ile http://my.example.com/index.html isteği /usr/web/index.html ile eşleştirilir. dizin-yolu ile göreli dosya yolu belirtildiği takdirde belge kök dizininin ServerRoot ile belirtilen sunucu kök dizinine göre belirtildiği varsayılır.

DocumentRoot ile belirtilen dizin bir bölü çizgisi ile bitirilmemelidir.

Ayrıca bakınız:

top

<Else> Yönergesi

Açıklama:Önceki bir <If> veya <ElseIf> bölümünün koşulu, çalışma anında bir istek tarafından yerine getirilmediği takdirde uygulanacak yönergeleri içerir
Sözdizimi:<Else> ... </Else>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:İç içe geçmiş koşullar 2.4.26 ve sonrasında değerlendirilmeye alınır

<Else> sadece ve sadece aynı etki alanındaki en son <If> veya <ElseIf> bölümü uygulanmamışsa kapsadığı yönergeleri uygular. Örneğin:

<If "-z req('Host')">
  # ...
</If>
<Else>
  # ...
</Else>

Burada, <If> yönergesi Host: başlıksız HTTP/1.0 istekleriyle eşleşirken <Else> Host: başlıklılarla eşleşir.

Ayrıca bakınız:

top

<ElseIf> Yönergesi

Açıklama:İçerdiği koşulun bir istek tarafınan sağlandığı ancak daha önceki bir <If> veya <ElseIf> bölümlerininkilerin sağlanmadığı durumda kapsadığı yönergelerin uygulanmasını sağlar
Sözdizimi:<ElseIf ifade> ... </ElseIf>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:İç içe geçmiş koşullar 2.4.26 ve sonrasında değerlendirilmeye alınır

<ElseIf> kapsadığı yönergeleri sadece ve sadece belirtilen koşulun doğrulandığı ancak aynı etki alanında hemen önceki <If> veya <ElseIf> yönergesinin uygulanmadığı takdirde uygular. Örnek:

<If "-R '10.1.0.0/16'">
  #...
</If>
<ElseIf "-R '10.0.0.0/8'">
  #...
</ElseIf>
<Else>
  #...
</Else>

<ElseIf> bir isteğin uzak adresi 10.0.0.0/8 ağına aitse ama 10.1.0.0/16 ağına ait değilse içerdiği yönergelerin uygulanmasını sağlar.

Ayrıca bakınız:

top

EnableMMAP Yönergesi

Açıklama:Teslimat sırasında okunacak dosyalar için bellek eşlemeyi etkin kılar.
Sözdizimi:EnableMMAP On|Off
Öntanımlı:EnableMMAP On
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:none değeri Apache 2.2.7 ve sonrasında mevcuttur.

Bu yönerge, sunucunun teslimat sırasında gerektiği takdirde bir dosya içeriğinin okunması için bellek eşleme kullanıp kullanmayacağını belirler. Öntanımlı olarak, bir isteğin yerine getirilmesi, mod_include kullanarak sunucu tarafından çözümlenen bir dosyanın teslimatı sırasında olduğu gibi, bir dosya içindeki veriye erişilmesini gerektirdiğinde Apache httpd, işletim sistemi tarafından desteklendiği takdirde dosyayı belleğe eşler.

Böyle bellek eşleme kimi zaman başarım artışını beraberinde getirirse de bazen sorunlardan kaçınmak için bellek eşlemeyi kapatmak daha iyi sonuç verir:

Bu tür sorunlardan dolayı zarar görülebilecek sunucu yapılandırmalarında dosya teslimatında bellek eşlemlerinin kullanımını şu şekilde iptal etmeniz gerekir:

EnableMMAP Off

Bu özellik, sadece NFS dosya sistemi üzerinde sunulan dosyaları kapsamak üzere şu şekilde kolayca kapatılabilir:

<Directory "/nfs-dosyaları-yolu">
  EnableMMAP Off
</Directory>
top

EnableSendfile Yönergesi

Açıklama:Dosyaların istemciye tesliminde çekirdeğin dosya gönderme desteğinin kullanımını etkin kılar.
Sözdizimi:EnableSendfile On|Off
Öntanımlı:EnableSendfile Off
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:Öntanımlı değer 2.3.9 sürümünde Off olarak değişti.

Bu yönerge, dosya içeriğinin istemciye teslimi için httpd’nin çekirdeğin dosya gönderme desteğini kullanıp kullanmayacağını belirler. Öntanımlı olarak, bir isteğin yerine getirilmesi, bir durağan dosyanın teslimatı sırasında olduğu gibi, bir dosya içindeki veriye erişilmesini gerektirmediği takdirde Apache httpd, işletim sistemi tarafından destekleniyorsa dosyayı istemciye teslim etmek için çekirdeğin dosya gönderme özelliğini kullanır.

Çekirdeğin dosya gönderme mekanizması, okuma, gönderme ve tampon ayırma işlemlerini ayrı ayrı yapmaktan kaçınır. Fakat bazı platformlarda veya bazı dosya sistemlerinde aşağıda belirtilen işlemsel sorunlardan kaçınmak için bu özelliği iptal etmek daha iyidir:

Bu sorunlardan muzdarip sunucu yapılandırmaları için bu özelliği şöyle etkin kılabilirsiniz:

EnableSendfile On

Bu özellik, sadece bir ağ dosya sistemi üzerinde sunulan dosyaları kapsamak üzere şu şekilde kolayca kapatılabilir:

<Directory "/nfs-dosyaları-yolu">
  EnableSendfile Off
</Directory>

EnableSendfile yönergesinin .htaccess ve diziniçi yapılandırmalarının mod_cache_disk tarafından desteklenmediğini lütfen aklınızdan çıkarmayın. EnableSendfile yönergesinin sadece küresel tanımları hesaba katılır.

top

Error Yönergesi

Açıklama:Özel bir hata iletisiyle yapılandırma çözümlemesini durdurur
Sözdizimi:Error ileti
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Durum:Çekirdek
Modül:core
Uyumluluk:2.3.9 ve sonrası

Yapılandırmada bir hatanın saptanması istenirse, bu yönerge yapılandırma çözümlemesinin durdurulması ve özel bir hata iletisi üretilmesi için kullanılabilir. Genelde kullanıldığı durum, gerekli modüllerin yapılandırmada bulunmadığının raporlanmasıdır.

# Örnek
# mod_include yüklü değilse bilelim
<IfModule !include_module>
  Error "Hata: mod_include mod_foo için gerekiyor. LoadModule ile yükleyin."
</IfModule>

# SSL veya NOSSL tanımlı mı bilelim
<IfDefine SSL>
<IfDefine NOSSL>
  Error "Ne SSL ne de NOSSL tanımlı. Sadece biri tanımlı olsa yeter."
</IfDefine>
</IfDefine>
<IfDefine !SSL>
<IfDefine !NOSSL>
  Error "Ya SSL ya da NOSSL tanımlı olmalı."
</IfDefine>
</IfDefine>

Ek Bilgi

Bu yönerge, çalışma zamanında değil, yapılandırma işlemi sırasında değerlendirilir. Sonuç olarak, bu yönerge bir <If> bölümü içine alınarak koşullu olarak değerlendirilemez.

top

ErrorDocument Yönergesi

Açıklama:Bir hata durumunda sunucunun istemciye ne döndüreceğini belirler.
Sözdizimi:ErrorDocument hata-kodu belge
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core

Bir sorun çıktığında veya hata oluştuğunda Apache httpd şu dört işlemden birini yapacak şekilde yapılandırılabilir:

  1. Yerleşik bir hata iletisi çıktılanır.
  2. Özel bir ileti çıktılanır.
  3. Sorunu/hatayı işleyecek yerel bir URL-yoluna dahili bir yönlendirme yapılır.
  4. Sorunu/hatayı işleyecek harici bir URL-yoluna yönlendirme yapılır.

İlk seçenek öntanımlıdır. Diğer üç seçenek ErrorDocument yönergesinin argümanları (hata kodundan sonra bir URL veya hata iletisi) ile belirtilir. Apache httpd bazı durumlarda sorun/hata ile ilgili ek bilgi verecektir.

2.4.13 itibariyle, özdevinimli dizgeler ve URLler üretmek için yönerge içinde ifade sözdizimi kullanılabilir.

URL’ler yerel yollarda (DocumentRoot’a göre) bir bölü çizgisi (/) ile başlatılabileceği gibi istemci tarafından çözümlenecek tam bir URL şeklinde de belirtilebilir. Bunlar yerine, tarayıcıda gösterilmek üzere bir ileti de belirtilebilir. Örnekler:

ErrorDocument 500 http://example.com/cgi-bin/server-error.cgi
ErrorDocument 404 /errors/bad_urls.php
ErrorDocument 401 /subscription_info.html
ErrorDocument 403 "Kusura bakmayın, bugün hizmet veremiyoruz."
ErrorDocument 403 /errors/forbidden.pl?referrer=%{escape:%{HTTP_REFERER}}

Bunlardan başka, Apache httpd’nin kendi hata iletilerinin kullanılacağı özel default değeri ile belirtilebilir. Normal şartlar altında gerekmese de, bir şey belirtilmediği takdirde mevcut bir ErrorDocument yönergesini miras alan yapılandırmalarda Apache httpd’nin kendi hata iletilerinin kullanımı default değeri açıkça belirtilerek örnekteki gibi zorlanabilir:

ErrorDocument 404 /cgi-bin/bad_urls.pl

<Directory "/web/docs">
  ErrorDocument 404 default
</Directory>

ErrorDocument yönergesinde bir uzak URL (önünde http bulunan bir yol) belirtildiğinde, belge aynı sunucuda olsa bile, Apache HTTP Sunucusunun istemciye belgeyi bulacağı yer için bir yönlendirme göndereceğine dikkat ediniz. Bunun bazı istenmeyen etkileri vardır; en önemlilerinden biri istemcinin hata kodu yerine bir yönlendirme durum kodu alacak olmasıdır. Bu, bir URL’nin geçerliliğini durum koduna göre saptayan istemciler veya robotlar için yanıltıcı olacaktır. Buna ek olarak, ErrorDocument 401 için bir uzak URL belirttiğiniz durumda istemci 401 durum kodunu almayacağı için kullanıcıdan parola isteğinde bulunamayacaktır. Bu bakımdan, ihtiyaç duyduğunuz takdirde, ErrorDocument 401 yönergesine yerel bir belge belirtmelisiniz.

Sunucunun ürettiği hata iletileri "çok kısa" olduğu takdirde, Microsoft Internet Explorer (MSIE) öntanımlı olarak bu hata iletilerini yoksayar ve bunun yerine kendi "kullanıcı dostu" hata iletilerini kullanır. "Çok kısa" eşiği duruma göre değişmekle birlikte, genellikle, hata iletileriniz 512 bayttan büyük olduğu takdirde MSIE kendi hata iletileri yerine sunucunun ürettiği hata iletilerini gösterecektir. Bu konuda daha fazla bilgiyi Q294807 kodlu Microsoft Knowledge Base makalesinde bulabilirsiniz.

Çoğu yerleşik hata iletisi özel iletilerle değiştirilebilse de bazı durumlarda ErrorDocument ile ne belirtildiğine bakılmaksızın yerleşik hata iletileri kullanılır. Özellikle, bozuk bir istek saptandığında normal istek işleme hemen devre dışı bırakılır ve yerleşik hata iletisi döndürülür. Bu, hatalı istekler yaparak güvenlik sorunlarına yol açılmak istenmesi durumlarında gereklidir.

mod_proxy kullanıyorsanız, ProxyErrorOverride yönergesini etkin kılmak isteyebilirsiniz, böylece asıl sunucular adına özel hata iletileri üretebilirsiniz. ProxyErrorOverride etkin kılınmak istenmezse, Apache httpd vekalet edilen içerik için özel hata belgeleri üretmeyecektir.

Ayrıca bakınız:

top

ErrorLog Yönergesi

Açıklama:Sunucunun hata günlüğünü tutacağı yeri belirler.
Sözdizimi: ErrorLog dosya-yolu|syslog[:[oluşum][:etiket]]
Öntanımlı:ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows ve OS/2)
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

ErrorLog yönergesi sunucunun saptadığı hataları kaydedeceği dosyanın ismini belirtmek için kullanılır. dosya-yolu ile göreli dosya yolu belirtildiği takdirde dizininin ServerRoot ile belirtilen sunucu kök dizinine göre belirtildiği varsayılır.

ErrorLog "/var/log/httpd/error_log"

dosya-yolu bir boru imi "|" ile başlatıldığı takdirde hata iletilerinin hata günlüğünü işleme sokacak komuta borulanacağı varsayılır.

ErrorLog "|/usr/local/bin/httpd_errors"

Daha fazla bilgi için borulu günlüklere bakınız.

Dosya adı yerine syslog kullanılırsa, sistem desteklediği takdirde günlük kaydı syslogd(8) üzerinden yürütülür. Öntanımlı olarak local7 syslog oluşumu kullanılır. Bunu syslog:oluşum sözdizimini kullanarak değiştirebilirsiniz. Buradaki oluşum syslog.conf(5) kılavuz sayfasında belirtilen oluşum isimlerinden biri olabilir. Oluşum aslında küreseldir ve sanal konaklardan bazılarında değiştirilmişse, belirtilen en son oluşum tüm sunucuyu etkileyecektir. etiket için de aynı kurallar uygulanır. Genellikle, öntanımlı etiket olarak Apache çalıştırılabilirinin ismi olan httpd kullanılır. Öntanımlı etiketi syslog::etiket sözdizimini kullanarak değiştirebilirsiniz

ErrorLog syslog:user
ErrorLog syslog:user:httpd.srv1
ErrorLog syslog::httpd.srv2

GÜVENLİK: Günlük dosyalarının saklandığı dizin, sunucuyu başlatan kullanıcı dışındakiler tarafından yazılabilir olduğu takdirde güvenliğinizin nasıl tehlikeye gireceği güvenlik ipuçları belgesinde ayrıntılı olarak açıklanmıştır.

Ek Bilgi

Unix-dışı platformlarda dosya yolunu girerken, platform ters bölü çizgilerini desteklese bile normal bölü çizgileri kullanmaya özen göstermelisiniz. Genel olarak, dosya yollarını belirtirken yapılandırma dosyası boyunca normal bölü çizgisi kullanmak her zaman daha iyidir.

Ayrıca bakınız:

top

ErrorLogFormat Yönergesi

Açıklama:Hata günlüğü girdileri için biçem belirtimi
Sözdizimi: ErrorLogFormat [connection|request] biçem
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

ErrorLogFormat yönergesi, hata günlüğünde asıl hata iletisine ek olarak günlüklenecek ek bilgiyi belirtmek için kullanılabilir.

#Basit örnek
ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [client %a] %M"

İlk değiştirge olarak connection veya request belirtilmesi ek biçemlerin belirtilebilmesini sağlar. Böylece, belli bir bağlantı ya da istek için ilk ileti günlüklendiğinde ek bilgininde günlüklenmesi sağlanır. Bu ek bilgi sadece bağlantı/istek başına bir kere günlüklenir. herhangi bir günlük iletisine sebep olmadan işlenmişse ek bilgi de günlüklenmez.

Bu, bazı biçem dizgesi öğeleri çıktı üretmediğinde olur. Örneğin, Referer başlığı sadece günlük iletisi bir istekle ilişkilendirilmişse mevcuttur ve hata iletisi Referer başlığı istemcide okunduğu anda oluşur. Eğer bir çıktı üretilmezse, öntanımlı davranış önceki boşluk karakterinden sonraki boşluk karakterine kadar herşeyi silmektir. Yani, günlük satırı örtük olarak boşluklarla ayrılmış alanlara bölünür. Bir biçem dizgesi öğesi çıktı üretmezse alanın tamamı çıktılanmaz. Örneğin, [%t] [%l] [%a] %M  günlük biçeminde uzak adres %a kullanılamazsa sarmalayıcı köşeli ayraçlar da günlüklenmeyecektir. Boşluk karakterleri ters bölülerle öncelenerek bir alanı sınırlaması önlenebilir. '% ' (yüzde boşluk) çifti sıfır genişlikte bir alan ayracı olup herhangi bir çıktı üretmez.

Yukarıdaki davranış, biçem dizgesi öğesine değiştirciler eklenerek değiştirilebilir. - (tire) değiştircisi ilgili öğe bir çıktı üretmediğinde tire iminin günlüklenmesine sebep olur. Bağlantı/istek başına bir kere biçemlerinde + (artı) değiştircisini de kullanmak mümkündür.Artı değiştiricili bir öğe herhangi bir çıktı üretmezse satırın tamamı günlüklenmez.

Bir biçem öğesine günlük önem derecesi atamak için değiştirici olarak bir sayı kullanılabilir. Bu öğenin günlüklenebilmesi için günlük iletisinin önem derecesinin belirtilen günlük önem derecesinden daha yüksek olmaması gerekir. Sayı 1'den (alarm) 4'e (uyarı) ve 7'den (hata ayıklama) 15'e (trace8) kadar olabilir.

Örneğin, Referer istek başlığını günlükleyen %{Referer}i dizgeciğine değiştirciler eklendiğinde neler olduğunu burada görebilirsiniz:

Değiştirlen DizgecikAnlamı
%-{Referer}i Referer atanmamışsa bir - günüklenir.
%+{Referer}i Referer atanmamışsa satırın tamamı çıktılanmaz.
%4{Referer}i Sadece hata iletisinin önemi 4'ten yüksek olduğu durumda Referer günlüklenir.

Bazı biçem dizfesi öğeleri ayraç içine alınmış ek değiştirgeler kabul eder.

Biçem Dizgesi Açıklama
%% Yüzde imi
%a İstekteki istemci IP adresi ve portu
%{c}a Bağlantının emsal IP adresi and portu (mod_remoteip modülüne bakın)
%A Yerel IP adresi ve portu
%{isim}e İstek ortam değişkeni isim
%E APR/OS hata durum kodu ve iletisi
%F Günlük çağrısının kaynak dosya ismi ve satır numarası
%{isim}i İstek başlığı isim
%k Bağlantıdaki keep-alive isteklerinin sayısı
%l İletinin günlük seviyesi
%L İsteğin günlük kimliği
%{c}L Bağlantının günlük kimliği
%{C}L Bağlantı etki alanında kullanılmışsa bağlantının günlük kimliği, aksi takdirde boş
%m İletiyi günlükleyen modülün ismi
%M Asıl günlük iletisi
%{isim}n istek notu isim
%P Geçerli sürecin süreç kimliği (PID'i)
%T Geçerli evrenin evre kimliği
%{g}T Geçerli evrenin eşsiz sistem evre kimliği (örn, top tarafınan gösterilenle aynı kimlik: şimdilik sadece Linux'a özgü)
%t geçerli zaman
%{u}t Mikro saniyeler dahil geçerli zaman
%{cu}t ISO 8601 biçemiyle uyumlu mikro saniyeleri de içeren geçerli zaman
%v Geçerli sunucunun kurallı ServerName
%V UseCanonicalName ayarına uygun olarak isteği sunan sunucunun sunucu ismi
(tersbölü boşluk) Alan ayracı olmayan boşluk
(yüzde boşluk) Alan ayracı (çıktısız)

The log ID format %L günlük kimliği biçemi bağlantı veya istek için eşsiz bir kimlik üretir. Bu, bağlantı üzerinden gelen istek durumunda günlük satırlarının ait olduğu bağlantı veya isteği bağdaştırmak için kullanılabilir. %L biçem dizgesi ayrıca mod_log_config modülünde erişim günlüğü iletilerini hata günlüğü iletileriyle ilişklendirmek için de kullanılabilmektedir. mod_unique_id modülü yüklüyse onun eşsiz kimliği istekler için günlük kimliği olarak kullanılacaktır.

#Örnek (Evreli MPM'ler için öntanımlı biçim)
ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"

Bunun hata iletilerindeki sonuçları şöyle olabilir:

[Thu May 12 08:28:57.652118 2011] [core:error] [pid 8777:tid 4326490112] [client ::1:58619] File does not exist: /usr/local/apache2/htdocs/favicon.ico

Dikkat edin, yukarıda açıklandığı gibi, bazı alanlar tanımlanmadıklarından tamamen yoksayılır.

#Örnek (2.2.x biçimine benzer)
ErrorLogFormat "[%t] [%l] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"
#İstek/bağlantı günlük kimlikli gelişkin bir örnek
ErrorLogFormat "[%{uc}t] [%-m:%-l] [R:%L] [C:%{C}L] %7F: %E: %M"
ErrorLogFormat request "[%{uc}t] [R:%L] Request %k on C:%{c}L pid:%P tid:%T"
ErrorLogFormat request "[%{uc}t] [R:%L] UA:'%+{User-Agent}i'"
ErrorLogFormat request "[%{uc}t] [R:%L] Referer:'%+{Referer}i'"
ErrorLogFormat connection "[%{uc}t] [C:%{c}L] remote\ %a local\ %A"

Ayrıca bakınız:

top

ExtendedStatus Yönergesi

Açıklama:Her istekte ek durum bilgisinin izini sürer
Sözdizimi:ExtendedStatus On|Off
Öntanımlı:ExtendedStatus Off[*]
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core

Bu yönerge, o an işlenmekte olan istek hakkında evre başına ek veriyi ve kullanım özetini izler; mod_status modülünü yapılandırarak bu değişkenleri çalışma anında görebilirsiniz. Diğer modüllerin bu sonuçlara bel bağlayabileceğini unutmayın.

Bu ayarlar sunucunun tamamına uygulanır ve bir sanal konakta etkin başka bir sanal konakta etkisiz kılınamaz. Ek durum bilgisinin toplanması sunucuyu yavaşlatabilir. Ayrıca, bu ayarın nazikçe yeniden başlatma sırasında değiştirilemeyeceğine dikkat ediniz.

Diğer üçüncü parti modüller aynısını yaparken mod_status modülünün yüklenmesi ExtendedStatus On için öntanımlı davranışı değiştirecektir. Böyle modüller, tüm evrelerin durumu hakkında ayrıntılı bilgi toplanmasına bel bağlar. Öntanımlı değer sürüm 2.3.6 itibariyle mod_status tarafından değiştirilmiştir. Önceki sürümlerde öntanımlı değer daima Off idi.

top

FileETag Yönergesi

Açıklama:Duruk dosyalar için ETag HTTP yanıt başlığını oluşturmakta kullanılacak dosya özniteliklerini belirler.
Sözdizimi:FileETag bileşen ...
Öntanımlı:FileETag MTime Size
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:2.3.14 ve öncesinde öntanımlı değer "INode MTime Size" idi.

FileETag yönergesi, belge bir duruk dosyaya dayandığı takdirde ETag (Entity Tag - öğe etiketi kısaltması) yanıt başlığı alanını oluşturmakta kullanılacak dosya özniteliklerini yapılandırır. (ETag değeri, ağ band genişliğinden kazanmak için arabellek yönetiminde kullanılır.) FileETagyönergesi ne kullanılması gerektiğini belirleyebilmenizi sağlar. Değer olarak belirtilebilecek anahtar sözcükler şunlardır:

INode
Dosyanın düğüm numarası hesaba katılır.
MTime
Dosyanın son değişiklik tarih ve saati dahil edilir.
Size
Dosyanın bayt cinsinden uzunluğu dahil edilir.
All
Olası tüm alanlar kullanılır. Bu şuna eşdeğerdir:
FileETag INode MTime Size
Digest
Bir belge dosya tabanlı ise ETag alanı dosyanın özeti alınarak hesaplanır.
None
Bir belge dosyasıyla sunulsa bile yanıta hiçbir ETag alanı dahil edilmez.

Öntanımlı ayarları miras alıp bunların kapsamını genişletmek/daraltmak için INode, MTime, Size ve Digest anahtar sözcüklerinin önüne + veya - imi konabilir. Bu imlerin bulunmadığı bir anahtar sözcüğün varlığı halinde hiçbir değer miras alınmaz.

Eğer bir dizinin yapılandırması FileETag INode MTime Size ve alt dizini FileETag -INode içeriyorsa bu alt dizinin (ve bir geçersizleştirme olmadığı takdirde onun alt dizinlerinin) ayarları FileETag MTime Size yapılandırmasına eşdeğer olacaktır.

Sunucu Taraflı İçerik

Gömülü SSI yönergeleri ile bir duruk dosyanın FileETag, MTime, Size ve Digest değerleri değişmeksizin yanıt öğesi değişebileceğinden mod_include tarafından çözümlenen yanıtlar için bir ETag üretilmez.
top

<Files> Yönergesi

Açıklama:Dosya isimleriyle eşleşme halinde uygulanacak yönergeleri içerir.
Sözdizimi:<Files dosya-adı> ... </Files>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

<Files> yönergesi, içerdiği yönergelerin etki alanını dosya isimlerine göre sınırlandırır. <Directory> ve <Location> bölümleri ile karşılaştırılabilir. Bir </Files> yönergesi ile sonlandırılması gerekir. Bu bölüm içinde belirtilen yönergeler, <Files> yönergesinde belirtilen dosya-adı’nın son bileşeniyle (dizinler atıldıktan sonda kalan dosya ismi) eşleşen nesnelere uygulanır. <Files> bölümleri yapılandırma dosyasında, <Directory> bölümleri ve .htaccess dosyaları okunduktan sonra fakat <Location> yönergelerinden önce göründükleri sıraya göre işleme sokulurlar. <Files> bölümlerinin <Directory> bölümlerinin içinde uygulama alanını sınırlamak amacıyla kullanılabileceğine dikkat ediniz.

dosya-adı argümanının bir dosya ismi veya bir dosya ismi kalıbı içermesi gerekir. Bir dosya ismi kalıbındaki her ? imi bir karakterle eşleştirilirken * imi karakter dizileri ile eşleştirilir.

<Files "zat.html">
    # zat.html dosyasına uygulanacakları buraya koy
</Files>

<Files "?at.*">
    # Buradakiler hat.html, kat.html, tat.html ve benzerlerine uygulanır.
</Files>

~ imine ek olarak düzenli ifadeler de kullanılabilir. Örneğin

<Files ~ "\.(gif|jpe?g|png)$">
    #...
</Files>

satırı en bilinen resim dosyası biçimleriyle eşleşecektir. Bunun yerine <FilesMatch> yönergesi de tercih edilebilirdi.

<Directory> ve <Location> bölümlerinin aksine, <Files> bölümleri .htaccess dosyaları içinde kullanılabilir. Bu sayede kullanıcıların kendi dosyalarına erişimi dosya seviyesinde denetlemelerine imkan sağlanmış olur.

Ayrıca bakınız:

top

<FilesMatch> Yönergesi

Açıklama:Düzenli ifadelerin dosya isimleriyle eşleşmesi halinde uygulanacak yönergeleri içerir.
Sözdizimi:<FilesMatch düzifd> ... </FilesMatch>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

<FilesMatch> yönergesi, içerdiği yönergelerin etki alanını <Files> yönergesinin yaptığı gibi dosya isimlerine göre sınırlandırır. Ancak, argüman olarak bir düzenli ifade kabul eder. Örneğin

<FilesMatch "\.(gif|jpe?g|png)$">
    # ...
</FilesMatch>

satırı en bilinen resim dosyası biçimleriyle eşleşecektir.

Düzenli ifadenin başlangıcındaki bir .+ .pngveya .gif dosyalarının, örnek olarak, eşleşmemesini garanti eder.

2.4.8 itibariyle, isimli gruplar ve geriye başvurular elde edilmekte olup ilgili isim büyük harfe çevrildikren sonra "MATCH_" ile öncelendikten sonra ortama yazılmaktadır. Böylece yol elemanlarına mod_rewrite gibi modüllerden veya düzenli ifadelerden başvurmak mümkün kılınmıştır. Karışıklığı önlemek için, numaralı (isimsiz) geriye başvurular yoksayılmaktadır. Bunların yerine isimli geriye başvurular kullanılmalıdır.

<FilesMatch "^(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</FilesMatch>

Ayrıca bakınız:

top

FlushMaxPipelined Yönergesi

Açıklama:Ağa akıtılacak azami ardışık yanıt sayısı
Sözdizimi:FlushMaxPipelined sayı
Öntanımlı:FlushMaxPipelined 5
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.47 ve sonrası

Bu yönerge, ardışık düzenli istek alındığı sürece beklemede kalan azami ardışık yanıt sayısını yapılandırmaya izin verir. Sınıra ulaşıldığında, yanıtlar tekrar sınırın altına inene kadar engelleme kipinde ağa zorla boşaltılır.

FlushMaxPipelined, bellek kullanımını kısıtlamaya yardımcı olur. 0 olarak ayarlandığında ardışık düzen devre dışı bırakılır, -1 olarak ayarlandığında sınır yoktur (FlushMaxThreshold hala geçerlidir).

top

FlushMaxThreshold Yönergesi

Açıklama:Bekleyen verilerin ağa boşaltılacağı eşik değer
Sözdizimi:FlushMaxThreshold bayt-sayısı
Öntanımlı:FlushMaxThreshold 65536
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.47 ve sonrası

Bu yönerge, bekleyen çıktı verileri için eşiği (bayt cinsinden) yapılandırmaya izin verir. Sınıra ulaşıldığında, veriler tekrar sınırın altına inene kadar engelleme kipinde ağa zorla boşaltılır.

FlushMaxThreshold, bellek kullanımını kısıtlamaya yardımcı olur. 0'a veya çok küçük bir değere ayarlandığında, gerçekte hiç bekleyen veri yoktur, ancak iş parçacıklı MPM'ler için ağı bekleyen daha fazla iş parçacığı olabilir, dolayısıyla diğer eşzamanlı bağlantıları işlemek için daha az sayıda kullanılabilir.

top

ForceType Yönergesi

Açıklama:Bütün dosyaların belirtilen ortam türüyle sunulmasına sebep olur.
Sözdizimi:ForceType ortam-türü|None
Bağlam:dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:Apache httpd 2.0’da core modülüne taşındı.

Bu yönerge, bir .htaccess dosyası veya bir <Directory>, <Location> veya <Files> bölümüne yerleştirildiği zaman, eşleşen tüm dosyaların ortam-türü ile belirtilen içerik türüyle sunulmasına sebep olur. Örneğin, altında sadece GIF dosyaları bulunan bir dizininiz varsa ve bunlara tek tek .gif uzantısı belirtmek istemiyorsanız şu yapılandırmayı kullanabilirsiniz:

ForceType image/gif

Bu yönerge, AddType yönergesi üzerinden ve mime.types dosyasında örtük olarak tanımlanmış ortam türü/dosya uzantısı ilişkilerini geçersiz kılar.

Ayrıca, daha genel ForceType ayarlarını da None değeriyle geçersiz kılabilirsiniz:

# tüm dosyaların image/gif olarak sunulması için:
<Location "/images">
  ForceType image/gif
</Location>

# normal MIME-türüne geri dönmek için:
<Location "/images/mixed">
  ForceType None
</Location>

Bu yönerge, öncelikle dosya sisteminden sunulan duruk dosyalar için üretilen içerik türlerini geçersiz kılar. Duruk dosyaların haricindeki özkaynaklar için yanıt üretecinin genelde bir Content-Type belirttiği durumda bu yönerge etkisizdir.

Ek Bilgi

SetHandler veya AddHandler gibi örtük yönergeler geçerli isteğe uygulanmadığı takdirde, normalde bu yönergeler tarafından belirlenen dahili eylemcinin ismi ForceType yönergesi tarafından belirtilen içerik türü ile eşleşecek şekilde belirlenir. Bu, bazı üçüncü parti modüller (mod_php gibi) tarafından kullanılan tarihi bir uygulama olup, bu modüller istekle eşleşecek modüllerin sorumluluğu almasını sağlamak için "sihirli" içerik türleri kullanabilir. Bu tür "sihirli" içerik türlerini kullanan yapılandırmalarda SetHandler veya AddHandler kullanımından kaçınılmalıdır.

top

GprofDir Yönergesi

Açıklama:gmon.out ayrıntılı inceleme verisinin yazılacağı dizin
Sözdizimi:GprofDir /tmp/gprof/|/tmp/gprof/%
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Sunucu gprof ayrıntılı inceleme desteği ile derlenmişse, GprofDir yönergesi gmon.out dosyalarının süreç çıktığında belirtilen dizine yazılmasını sağlar. Eğer değiştirge bir yüzde simgesi ('%') ile bitiyorsa her süreç kimliği için alt dizinler oluşturulur.

Bu yönerge şimdilik sadece prefork MPM'i ile çalışmaktadır.

top

HostnameLookups Yönergesi

Açıklama:İstemci IP adresleri üzerinde DNS sorgularını etkin kılar.
Sözdizimi:HostnameLookups On|Off|Double
Öntanımlı:HostnameLookups Off
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core

Bu yönerge oturum açabilecek konak isimlerini tespit edebilmek için DNS sorgularını etkin kılar (ve sonuç REMOTE_HOST’ta belirtilerek CGI/SSI’lere aktarılır). Double değeri sorgunun çift yönlü yapılacağını belirtir. Yani, bir tersine sorgunun ardından bir normal sorgu yapılır. Normal sorguda elde edilen IP adreslerinden birinin istek yapan IP adresi ile eşleşmesi gerekir. ("tcpwrappers" terminolojisinde buna PARANOID adı verilir.)

Konak ismine göre erişimi denetlemek için mod_authz_host kullanıldığında, nasıl bir ayar yapıldığına bakılmaksızın, çift yönlü sorgulama yapılır. Bu güvenlik için gereklidir. Bunun dışında açıkça HostnameLookups Double belirtilmedikçe genellikle çift yönlü sorgulama yapılmaz. Örneğin, sadece HostnameLookups On belirtilmiş ve konak ismi kısıtlamalarıyla korunmuş bir nesne için bir istek yapılmışsa çift yönlü sorgunun başarısına bakılmaksızın CGI’lere REMOTE_HOST olarak tek yönlü sorgu sonucu aktarılır.

Gerçekte ters yönlü sorguya gerek duyulmayan sitelerde ağ trafiğini yormamak için Off, öntanımlı değerdir. Ayrıca, son kullanıcıların DNS sorguları nedeniyle gereksiz yere bir beklemeye maruz kalmaması için de bu daha iyidir. Yükü zaten ağır olan sitelerde, DNS sorgularının görece uzun zaman alması nedeniyle bu yönergenin değeri Off olarak bırakılmalıdır. Öntanımlı olarak kurulum dizininizin bin alt dizinine kurulan logresolve uygulaması kullanılarak oturum açan IP adresleri için isim sorguları çevrim dışıyken yapılabilir.

Son olarak, konak ismine dayalı Require yönergelerine sahipseniz konak ismi araması HostnameLookups ayarına bakılmaksızın gerçekleştirilecektir.

top

HttpProtocolOptions Yönergesi

Açıklama:HTTP İstek İletilerindeki sınırlamalarda değişiklik yapar
Sözdizimi:HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0]
Öntanımlı:HttpProtocolOptions Strict LenientMethods Allow0.9
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:2.2.32 veya 2.4.24 ve sonrası

Bu yönerge HTTP istek satırına (RFC 7230 §3.1.1) ve the HTTP istek başlığı alanlarına (RFC 7230 §3.2) uygulanmış kuralları öntanımlı olarak veya Strict seçeneği kullanılarak değiştirir. Eski modüller, uygulamalar veya kullanımı önerilmeyen özel istemciler için eski davranışlara dönmeyi sağlamak üzere Unsafe seçeneği eklenmiştir.

Bu kurallar istek işlenmeden önce uygulanır. Dolayısıyla yönerge, IP/port arabirimine göre ana bölümde veya öntanımlı (ilk) eşleşen sanal konak bölümünde yapılandırılmalıdır.

Bu yönergeye aşağıdaki parametrelerden seçilen üç tanesi uygulanabilir. Belirtilmeyenlerin yerine öntanımlılar uygulanır.

Strict|Unsafe

Bu yönerge devreye girmeden önce, Apache HTTP Sunucusunun istek iletisi ayrıştırıcıları protokolle uyumlu olmayan bir dizi girdi şekline toleranslıydı. RFC 7230 §9.4 İstek bölme ve §9.5 Yanıt kaçırma çağrıları uyumsuz istek iletilerinin kabulündeki olası risklerden yalnızca iki tanesidir. RFC 7230 §3.5 "İleti Ayrıştırma Sağlamlığı" belirsiz boşlukların kabul ve istek iletisi biçimleme risklerini tanımlar. Bu yönergenin devreye girmesini takiben belirtimin tüm imla kurallarına öntanımlı Strict işlem kipi ve 3.5 bölümünde tavsiye edilen hoşgörüsüz boşluk uygulanır ve esnekliğe müsamaha edilmez.

Unsafe için güvenlik riskleri

Kullanıcılar, özellikle dışa bakan, herkes tarafından erişilebilen sunucu konuşlandırmalarında Unsafe işlem kipine geçiş yapmaya karşı kesinlikle uyarılır. Eğer bir arayüz hataları izlemek veya bir intranette çalışan özel hizmet tüketicileri için gerekliyse, kullanıcılar, sadece, dahili özel ağlarına hizmet etmek üzere yapılandırılmış özel bir sanal konak üzerinde Unsafe işlem kipine geçiş yapmalıdır.

Strict kipte HTTP 400 ile sonuçlanan bir istek örneği

# Eksik CRLF
GET / HTTP/1.0\n\n

Komut satırı araçları ve CRLF

Bazı araçların CRLF kullanmaya zorlanması gerekir, aksi takdirde httpd yukarıdaki örnekte belirtildiği gibi bir HTTP 400 yanıtı ile döner. Örneğin, OpenSSL s_client düzgün çalışmak için -crlf değiştirgesine ihtiyaç duyar.

CRLF yokluğu gibi durumları saptamak için HTTP isteğini görünümlemek isterseniz DumpIOInput yönergesi yardımcı olabilir.

RegisteredMethods|LenientMethods

RFC 7231 §4.1 "İstek Yöntemleri" "Genel Bakış" bölümlerinde bir istek satırında desteklenmeyen bir yöntem saptadığında özgün sunucuların bir hatayla yanıt vermesini gerekli görmüştür. LenientMethods seçeneği kullanıldığında olan zaten budur. RegisteredMethods seçeneğine geçiş yapmak isteyen yöneticiler RegisterHttpMethod yönergesini kullanarak standart olmayan yöntemleri belirlemelidir. Özellikle Unsafe seçeneğine geçiş yapılacaksa bu yol izlenmelidir.

İleri Vekil Uyumluluğu

Özgün sunucunun kullandığı yöntemleri vekil sunucu bilemeyeceği için ileri vekil konaklarda RegisteredMethods seçeneğine geçiş yapılmamalıdır.

Example of a request leading to HTTP 501 with LenientMethods mode

# Unknown HTTP method
WOW / HTTP/1.0\r\n\r\n

# Lowercase HTTP method
get / HTTP/1.0\r\n\r\n

Allow0.9|Require1.0

RFC 2616 §19.6 "Önceki Sürümlerle Uyumluluk" bölümünde HTTP sunucularının eski HTTP/0.9 isteklerini desteklemesi tavsiye edilmektedir. RFC 7230 "HTTP/0.9 isteklerini destekleme beklentisi kaldırılmıştır." cümlesiyle bunu geçersiz kılmış ve RFC 7230 Ek A bölümünde bununla ilgili yorumlar yer almıştır. Require1.0 seçeneği kullanıcıya öntanımlı Allow0.9 seçeneğinin davranışına verilen desteği kaldırma imkanını vermektedir.

Require1.0 kipinde HTTP 400 ile sonuçlanan bir istek örneği

# Desteklenmeyen HTTP sürümü
GET /\r\n\r\n

LogLevel debug seviyesiyle yapılandırılmış ErrorLog ile kaydedilmiş günlüklerin gözden geçirilmesi, böyle hatalı isteklerin kaynaklandıkları yerle birlikte belirlenmesine yardımcı olabilir. Kullanıcılar, beklenmedik bir şekilde reddedilmiş geçersiz istekleri bulmak için erişim günlüklerindeki 400 yanıtlarına özellikle dikkat etmelidir.

top

<If> Yönergesi

Açıklama:Çalışma anında bir koşul bir istek tarafından yerine getirildiği takdirde uygulanacak yönergeleri barındırır.
Sözdizimi:<If ifade> ... </If>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:İç içe geçmiş koşullar 2.4.26 ve sonrasında değerlendirilmeye alınır

<If> yönergesi bir ifadeyi çalışma anında değerlendirir ve ifadenin sonucu doğru olduğu takdirde içerdiği yönergeleri uygular. Örnek:

<If "-z req('Host')">

Bir Host: başlığı içermeyen HTTP/1.0 istekleriyle eşleşir. İfadeler, dizge karşılaştırması (==, !=, <, ...), tamsayı karşılaştırması (-eq, -ne, ...) ve diğerleri (-n, -z, -f, ...) için kabuktakilere benzer çeşitli işleçler içerebilir. Ayrıca, düzenli ifadeleri,

<If "%{QUERY_STRING} =~ /(delete|commit)=.*?elem/">

kabuk tarzı kalıp eşleştirme ve birçok başka işlemi kullanmak da mümkündür. Bu işlemler istek başlıklarında (req), ortam değişkenlerinde (env) ve çok sayıda başka niteliklerin üstünde yapılabilir. Apache HTTP Sunucusundaki İfadeler belgesinde daha ayrıntılı bilgi bulabilirsiniz.

Bu yapılandırma bölümünün içinde sadece dizin bağlamını destekleyen yönergeler kullanılabilir.

<If> sonrasında atanan CONTENT_TYPE gibi belli değişkenler ve diğer yanıt başlıkları zaten yorumlanmış olacaklarından bu yönerge için kullanılabilir olmayacaktır.
Define, Include ve Error gibi yapılandırma ayrıştırılırken etkili olan yönergeler, bir <If> yapılandırma bölümü içine alınarak koşullu hale getirilemez. Bu bölümler, çalışma anında nasıl değerlendirildiklerine bakılmaksızın, her zaman yapılandırmanın bir parçasıdır.

Ayrıca bakınız:

top

<IfDefine> Yönergesi

Açıklama:Başlatma sırasında bir doğruluk sınamasından sonra işleme sokulacak yönergeleri sarmalar.
Sözdizimi:<IfDefine [!]parametre-adı> ... </IfDefine>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

<IfDefine sınama>...</IfDefine> bölümü koşullu olarak işleme sokulacak yönergeleri içerir. Bir <IfDefine> bölümü içindeki yönergeler sadece sınama doğru sonuç verirse işleme sokulur. Aksi takdirde, bölüm içinde kalan her şey yok sayılır.

<IfDefine> bölüm yönergesinde sınama için belirtilebilecek iki biçim vardır:

Birinci durumda bölüm içinde kalan yönergeler sadece parametre-adı ile belirtilen parametre tanımlı ise işleme sokulur. İkinci durumda ise tersi yapılır, yani sadece parametre-adı ile belirtilen parametre tanımlı değil ise yönergeler işleme sokulur.

parametre-adı argümanı sunucu başlatılırken httpd komut satırında -Dparametre ile veya Define yönergesi ile belirtilerek tanımlı hale getirilebilir.

<IfDefine> bölümleri iç içe olabilir, dolayısıyla çok parametreli basit sınamalar gerçeklenebilir. Örnek:

httpd -DReverseProxy -DUseCache -DMemCache ...

<IfDefine ReverseProxy>
  LoadModule proxy_module   modules/mod_proxy.so
  LoadModule proxy_http_module   modules/mod_proxy_http.so
  <IfDefine UseCache>
    LoadModule cache_module   modules/mod_cache.so
    <IfDefine MemCache>
      LoadModule mem_cache_module   modules/mod_mem_cache.so
    </IfDefine>
    <IfDefine !MemCache>
      LoadModule cache_disk_module   modules/mod_cache_disk.so
    </IfDefine>
  </IfDefine>
</IfDefine>
top

<IfDirective> Yönergesi

Açıklama:Belirtilen yönerge adının varlığı veya yokluğuna bağlı olarak çalıştırılacak yönergeleri sarmalar.
Sözdizimi:<IfDirective [!]yönerge-adı> ... </IfDirective>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.34 ve sonrasında kullanılabilir.

<IfDirective yönerge-adı> ...</IfDirective> bölümü içindeki yönergeler yönerge-adı ile belirtilen yönerge mevcutsa çalıştırılır yoksa yok sayılır.

<IfDirective> yönergenide sınama iki türlü yapılır:

İlk durumda bölüm içinde kalan yönergeler, yönerge başlangıç satırına belirtilen yönerge işlem sırasında mevcutsa çalıştırılır, değilse çalıştırılmaz. İkinci durumda ise, bölüm içinde kalan yönergeler, yönerge başlangıç satırına belirtilen yönerge işlem sırasında mevcut değilse çalıştırılır, mevcutsa çalıştırılmaz.

Bu yönergeyi kullanma ihtiyacı sadece çok sayıda httpd tek bir yapılandırma dosyası ile çalıştırılmak zorundaysa ortaya çıkar. Böyle bir ihtiyacın olmadığı normal durumlarda yönergelerin <IfDirective> bölümlerine yerleştirlmesine gerek yoktur.

Ayrıca bakınız:

top

<IfFile> Yönergesi

Açıklama:Başlatma sırasında bir dosyanın varlığı durumunda işleme sokulacak yönergeleri sarmalar.
Sözdizimi:<IfFile [!]dosyaadı> ... </IfFile>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.34 ve sonrsında kullanılabilir.

<IfFile dosyaadı>...</IfFile> bölümü bir dosyanın diskteki mevcudiyetine bağlı olarak çalıştırılacak yönergeleri belirtmekte kullanılır. <IfFile> bölümü içindeki yönergeler sadece diskte dosyaadı mevcutsa çalıştırılır. dosyaadı mevcut değilse bölüm içindeki yönergeler yok sayılır. dosyaadı sunucu kök dizinine göreli veya mutlak bir yol olarak belirtilebilir.

<IfFile> bölüm yönergesindeki dosyaadı, <IfDefine> yönergesindeki sınama değişkenindeki gibi ele alınır, yani dosyaadı bir ! ile öncelenirse bölüm içindeki yonergeler dosyanın yokluğu durumunda çalıştırılır.

Göreli bir dosyaadı belirtilmişse sınama ServerRoot yönergesinde belirtilen dizinde göre yapılır. <IfFile> yönergesinin ServerRoot yönergesinde önce yer alması durumunda dosya yolu derleme sırasında kullanılan sunucu köküne veya komut satırında -d seçeneği ile belirtilen dizine göre sınanır.

Uyarı

2.4.34 sürümünde, dosyaadı'nı tırnak içinde belirtmek mümkün değildi. Bu, başlatma sırasında çözümleme hatasına sebep oluyordu. Bunun başlıca etkisi, boşluklu dosya adlarının kullanılamamasıdır. Bu sorun, 2.4.35 sürümünde düzeltildi.
top

<IfModule> Yönergesi

Açıklama:Belli bir modülün varlığına veya yokluğuna göre işleme sokulacak yönergeleri sarmalar.
Sözdizimi:<IfModule [!]modül-dosyası|modül-betimleyici> ... </IfModule>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:Modül betimleyiciler 2.1 sürümünde ve sonrası için geçerlidir.

<IfModule sınama>...</IfModule> bölümü belli bir modülün varlığına veya yokluğuna göre işleme sokulacak yönergeleri içerir. Bir <IfModule> bölümü içindeki yönergeler sadece sınama doğru sonuç verirse işleme sokulur. Aksi takdirde, bölüm içinde kalan her şey yok sayılır.

<IfModule> bölüm yönergesinde sınama için belirtilebilecek iki biçim vardır:

Birinci durumda bölüm içinde kalan yönergeler sadece modül ile belirtilen modül Apache httpd içine dahil edilmişse veya LoadModule yönergesi ile devingen olarak yüklenmişse işleme sokulur. İkinci durumda ise tersi yapılır, yani sadece modül içerilmiş değil ise yönergeler işleme sokulur.

modül argümanında bir modül betimleyici veya modülün derleme sırasındaki dosya adı belirtilebilir. Örneğin, rewrite_module bir betimleyici, mod_rewrite.c ise bir dosya ismidir. Eğer modül çok sayıda kaynak dosyasından oluşuyorsa STANDARD20_MODULE_STUFF dizgesini içeren dosyanın ismi kullanılır.

<IfModule> bölümleri iç içe olabilir, dolayısıyla çok parametreli basit sınamalar gerçeklenebilir.

Bu bölümü sadece yapılandırma dosyanızın belli modüllerin varlığına veya yokluğuna bağlı olarak çalışması gerektiği durumlarda kullanmalısınız. Normal işlemlerde yönergelerin <IfModule> bölümlerine yerleştirilmeleri gerekmez.
top

<IfSection> Yönergesi

Açıklama:Belirtilen bölüm adının varlığı veya yokluğuna bağlı olarak çalıştırılacak yönergeleri sarmalar.
Sözdizimi:<IfSection [!]bölüm-adı> ... </IfSection>
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.34 ve sonrasında kullanılabilir.

<IfSection bölüm-adı> ...</IfSection> bölümü içindeki yönergeler bölüm-adı ile belirtilen bölüm mevcutsa çalıştırılır yoksa yok sayılır. Bir bölüm yönergesi "<" ile öncelenmiş bir yönerge adına sahip olmalı ve <VirtualHost> gibi başka yönergeleri sarmalayan bir yönerge olmalıdır.

<IfSection> bölümü içindeki yönergeler sadece sınama doğru ise çalıştırılır, sınama yanlışsa çalıştırılmaz.

bölüm-adı başında "<" veya sonunda ">" olmaksızın belirtilmelidir. <IfSection> yönergesindeki bölüm-adı iki türlü ele alınır:

İlk durumda bölüm içinde kalan yönergeler, yönerge başlangıç satırına belirtilen bölüm işlem sırasında mevcutsa çalıştırılır, değilse çalıştırılmaz. İkinci durumda ise, bölüm içinde kalan yönergeler, yönerge başlangıç satırına belirtilen bölüm işlem sırasında mevcut değilse çalıştırılır, mevcutsa çalıştırılmaz.

Örnek:

<IfSection VirtualHost>
   ...
</IfSection>
Bu yönergeyi kullanma ihtiyacı sadece çok sayıda httpd tek bir yapılandırma dosyası ile (belli bir bölüm yönergesinin var olup olmamasına bakmaksızın) çalıştırılmak zorundaysa ortaya çıkar. Böyle bir ihtiyacın olmadığı normal durumlarda yönergelerin <IfSection> bölümlerine yerleştirlmesine gerek yoktur.

Ayrıca bakınız:

top

Include Yönergesi

Açıklama:Sunucu yapılandırma dosyalarının başka dosyaları içermesini sağlar.
Sözdizimi:Include dosya-yolu|dizin-yolu|joker
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core
Uyumluluk:Dizin kalıbıyla eşleşme ise 2.3.6 ve sonrasında mevcuttur.

Bu yönerge sunucu yapılandırma dosyalarının başka dosyaları içermesini mümkün kılar.

Çok sayıda dosyayı bir kerede alfabetik sırada içermek için yolun dosya ismi ve dizin parçalarında kabuk tarzı (fnmatch()) dosya ismi kalıp karakterleri kullanılabilir. Ayrıca, eğer Include yönergesi bir dosya değil de bir dizin gösteriyorsa Apache httpd bu dizindeki ve alt dizinlerindeki bütün dosyaları okuyacaktır. Bunula birlikte, dizinin bir bütün olarak okutulması önerilmez, çünkü dizinde httpd programının çökmesine sebep olabilecek geçici dosyalar unutulabilir. Bunun yerine, belli bir şablona uyan dosyaları seçebilmek için, örneğin *.conf gibi dosya kalıplarının kullanılmasını öneriyoruz.

Include yönergesi, bir dosya kalıbı ifadesi hiçbir dosyayla eşleşmezse bir hatayla başarısız olacaktır. Eşleşmeyen dosya kalıbı ifadelerinin yoksayılması gerekiyorsa IncludeOptional yönergesi kullanılabilir.

Dosya yolu mutlak bir dosya yolu olarak belirtilebileceği gibi ServerRoot dizinine göreli olarak da belirtilebilir.

Örnekler:

Include /usr/local/apache2/conf/ssl.conf
Include /usr/local/apache2/conf/vhosts/*.conf

Veya dizinler ServerRoot dizinine göre belirtilebilir:

Include conf/ssl.conf
Include conf/vhosts/*.conf

Dosya kalıbı karakterleri yolun dizin ve dosya parçalarına yerleştirilebilir. conf/vhosts altında en azından bir *.conf içeren hiçbir alt dizin yoksa bu örnek başarısız olacaktır:

Include conf/vhosts/*/*.conf

Bunun yerine, dizin ve dosyaların eksikliği durumunda aşağıdaki komut sadece yoksayılır:

IncludeOptional conf/vhosts/*/*.conf

Ayrıca bakınız:

top

IncludeOptional Yönergesi

Açıklama:Diğer yapılandırma dosyalarının sunucu yapılandırma dosyasına dahil edilmesini sağlar
Sözdizimi:IncludeOptional dosya-yolu|dizin-yolu|joker
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core
Uyumluluk:2.3.6 ve sonrasına kullanılabilmektedir. Dosya kalıp karakterleri içermeyen dosya yollarından mevcut olmayanlar 2.4.30 sürümünden itibaren sözdizimi hatalarına sebep olmamaktadır.

Bu yönerge, diğer yapılandırma dosyalarının sunucu yapılandırma dosyasında içerilmesini sağlar. Çalışması Include yönergesi ile bir istisna dışında aynıdır. Dosya kalıp karakterlerinin hiçbir dosya veya dizinle eşleşmemesi veya dosya yolunun dosya sisteminde mevcut olmaması durumunda bir hata oluşmayacak ve bu durum sadece yoksayılacaktır.

Ayrıca bakınız:

top

KeepAlive Yönergesi

Açıklama:HTTP kalıcı bağlantılarını etkin kılar
Sözdizimi:KeepAlive On|Off
Öntanımlı:KeepAlive On
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Keep-Alive yönergesi HTTP/1.0 protokolüne bir eklenti olup HTTP/1.1 protokolünün kalıcı bağlantı özelliği aynı TCP bağlantısı üzerinden çok sayıda isteğin gönderilmesini mümkün kılan uzun süreli HTTP oturumları açılmasını sağlar. Bunun, çok sayıda resim içeren HTML belgelerin yanıt zamanlarında bazı durumlarda %50’lik bir hızlanmayla sonuçlandığı gösterilmiştir. Kalıcı bağlantıları etkin kılmak için yönerge KeepAlive On şeklinde kullanılır.

HTTP/1.0 istemcileri için kalıcı bağlantılar sadece bir istemci tarafından özellikle istendiği takdirde kullanılabilir. Ek olarak, HTTP/1.0 istemci kalıcı bağlantıları sadece içerik uzunluğu baştan bilindiği zaman kullanılabilir. Bu, CGI çıktısı, SSI sayfaları ve sunucunun ürettiği dizin listeleri gibi genellikle HTTP/1.0 istemcilere kalıcı bağlantılar kullanmayan devingen içeriklere uygulanır. HTTP/1.1 istemciler için kalıcı bağlantılar aksi belirtilmedikçe öntanımlıdır. İstemci istediği takdirde, uzunluğu bilinmeyen içerik kalıcı bağlantılar üzerinden gönderilirken parçalı kodlama kullanılacaktır.

Bir istemci kalıcı bağlantı kullandığı takdirde, bağlantı üzerinden kaç istek gönderilirse gönderilsin, MaxConnectionsPerChild yönergesi bakımından tek bir istek olarak değerlendirilir.

Ayrıca bakınız:

top

KeepAliveTimeout Yönergesi

Açıklama:Bir kalıcı bağlantıda sunucunun bir sonraki isteği bekleme süresi
Sözdizimi:KeepAliveTimeout sayı[ms]
Öntanımlı:KeepAliveTimeout 5
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Sunucunun kalıcı bir bağlantıyı kapatmadan önce bir sonraki isteği kaç saniye bekleyeceğini belirler. Ayrıca, ms soneki kullanılarak süreyi milisaniye olarak belirtmek de mümkündür. İstek alındıktan sonra Timeout yönergesiyle belirtilen zaman aşımı değeri uygulanır.

KeepAliveTimeout için yüksek bir değer belirtmek ağır yüklü sunucularda başarım sorunlarına yol açar. Daha yüksek bir zaman aşımı, boştaki istemcilerin bulunduğu bağlantıları bekleyen daha fazla sunucu sürecini meşgul edecektir.

İsme dayalı sanal konak için KeepAliveTimeout atanmamışsa, yerel IP adresi ve portu ile en iyi eşleşen ilk sanal konağın değeri kullanılır.

top

<Limit> Yönergesi

Açıklama:Erişimi sınırlanacak HTTP yöntemleri için erişim sınırlayıcıları sarmalar.
Sözdizimi:<Limit yöntem [yöntem] ... > ... </Limit>
Bağlam:dizin, .htaccess
Geçersizleştirme:AuthConfig, Limit
Durum:Çekirdek
Modül:core

Erişim denetleyicileri normalde tüm erişim yöntemleri için etkindir ve olağan olanı da budur. Genel durum olarak, erişim denetim yönergeleri bir <Limit> bölümüne yerleştirilmemelidir.

<Limit> bölümünün amacı, erişim denetleyicilerinin etkilerini belli HTTP yöntemleri için sınırlamaktır. <Limit> bölümü içinde listelenen erişim sınırlamaları, kalan tüm diğer yöntemler için etkisiz olacaktır. Aşağıdaki örnekte, erişim sınırlaması POST, PUT ve DELETE yöntemleri için uygulanmakta, diğer tüm yöntemler korumasız bırakılmaktadır:

<Limit POST PUT DELETE>
  Require valid-user
</Limit>

Birden fazla bölümde kullanılabilecek yöntem isimleri: GET, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK ve UNLOCK. Yöntem isimleri harf büyüklüğüne duyarlıdır. GET yöntemi sınırlanırsa HEAD istekleri de sınırlanmış olur. TRACE yöntemi sınırlanamaz (bkz, TraceEnable).

Erişimi sınarlarken bir <Limit> bölümü yerine daima bir <LimitExcept> bölümünü tercih etmelisiniz, çünkü <LimitExcept> bölümü belirtilen yöntemler dışında kalanlara erişim koruması sağlar.

<Limit> ve <LimitExcept> yönergeleri iç içe olabilirler. Bu durumda, başarılı her <Limit> veya <LimitExcept> seviyesi, erişim denetimlerinin uygulanacağı yöntemlerle sınırlı kalmalıdır.

<Limit> veya <LimitExcept> yönergelerini Require yönergesi ile birlikte kullanılırken, ilk Require yönergesinin bir başka Require yönergesinin varlığından bağımsız olarak isteği başarıyla yetkilendirdiğine dikkat ediniz.

Örneğin, aşağıdaki yapılandırmayı ele alalım; tüm kullanıcılar POST istekleri için yetkilendirilecek ve tüm durumlarda Require group editors yönergesi yoksayılacaktır:

<LimitExcept GET>
  Require valid-user
</LimitExcept>
<Limit POST>
  Require group editors
</Limit>
top

<LimitExcept> Yönergesi

Açıklama:İsimleri belirtilenler dışında kalan HTTP yöntemleri için kullanılacak erişim sınırlayıcıları sarmalar.
Sözdizimi:<LimitExcept yöntem [yöntem] ... > ... </LimitExcept>
Bağlam:dizin, .htaccess
Geçersizleştirme:AuthConfig, Limit
Durum:Çekirdek
Modül:core

<LimitExcept> ve </LimitExcept> argüman olarak belirtilenler dışında kalan HTTP yöntemleri için kullanılacak erişim sınırlayıcıları gruplamakta kullanılır. Yani, <Limit> bölümünün tersine, standart olsun olmasın bütün yöntemler için erişimi kısıtlamakta kullanılabilir. Daha ayrıntılı bilgi edinmek için <Limit> yönergesinin açıklamasına bakınız.

Örnek:

<LimitExcept POST GET>
  Require valid-user
</LimitExcept>
top

LimitInternalRecursion Yönergesi

Açıklama:Dahili yönlendirmelerin ve istek içi isteklerin azami sayısını belirler.
Sözdizimi:LimitInternalRecursion sayı [sayı]
Öntanımlı:LimitInternalRecursion 10
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Örneğin, özgün istekleri dahili olarak bir CGI betiğine yönlendiren Action yönergesi kullanıldığında bir dahili yönlendirme oluşur. İstek içi istekler ise bazı URI’ler için istek yapıldığında ne olacağını bulmak için Apache httpd’nin kullandığı bir mekanizmadır. Örneğin, mod_dir, DirectoryIndex yönergesinde listelenen dosyalara bakmak için istek içi istekler kullanır.

LimitInternalRecursion yönergesi sunucunun dahili yönlendirmeler ve istek içi isteklerin oluşturduğu döngülerden dolayı çökmemesini sağlar. Böyle döngüler genellikle yanlış yapılandırma sonucu ortaya çıkarlar.

Yönerge her istek için değerlendirmeye alınacak iki farklı sınırlama için kullanılabilir. İlk sayı ardarda gelebilen dahili yönlendirmelerin azami sayısını, ikinci sayı ise istek içi isteklerin ne kadar iç içe olabileceğini belirler. Tek bir sayı belirtilirse iki sınırlama için de aynı değer kullanılır.

LimitInternalRecursion 5
top

LimitRequestBody Yönergesi

Açıklama:İstemci tarafından gönderilen HTTP istek gövdesinin toplam uzunluğunu sınırlar.
Sözdizimi:LimitRequestBody bayt-sayısı
Öntanımlı:LimitRequestBody 1073741824
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core
Uyumluluk:Apache HTTP Sunucusu 2.4.53 ve öncesinde, öntanımlı değer 0 idi (sınırsız)

Bu yönerge, bir istek gövdesinde izin verilen bayt sayısını sınırlamak için kullanılır. 0 sınırsız anlamına gelir.

LimitRequestBody yönergesi kullanıcıya yönergenin kullanıldığı bağlam (sunucu, belli bir dizin, belli bir dosya, belli bir yer) dahilinde bir HTTP istek iletisi gövdesinin izin verilen uzunluğu için bir sınır belirleme imkanı verir. Eğer istemcinin isteği bu sınırı aşarsa sunucu isteği sunmak yerine bir hata iletisi döndürecektir. Normal bir istek ileti gövdesinin uzunluğu büyük oranda özkaynağın doğasına ve bu özkaynak üzerinde izin verilen yöntemlere bağlıdır. CGI betikleri genellikle ileti gövdesini form bilgisini almak için kullanır. PUT yöntemi gerçeklenimleri, en azından, sunucunun o özkaynak için kabul etmek isteyeceği herhangi bir gösterim kadar büyük bir değer gerektirecektir.

Bu yönerge, bazı hizmet reddi (DoS) saldırılarından kaçınmak için sunucu yöneticilerine, anormal istemci istekleri üzerinde daha iyi denetim imkanı sağlar.

Eğer, örneğin, belli bir yere dosya yükleme izni verir ve buraya yüklenebilecek dosya boyutunu 100 kB ile sınırlamak isterseniz yönergeyi şöyle kullanabilirsiniz:

LimitRequestBody 102400
top

LimitRequestFields Yönergesi

Açıklama:İstemciden kabul edilecek HTTP isteği başlık alanlarının sayısını sınırlar.
Sözdizimi:LimitRequestFields sayı
Öntanımlı:LimitRequestFields 100
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

sayıya 0 atanması sınırsız anlamına gelir. Öntanımlı değer bir derleme zamanı sabiti olan DEFAULT_LIMIT_REQUEST_FIELDS ile belirlenir (dağıtımla gelen değeri 100’dür).

LimitRequestFields yönergesi sunucu yöneticilerine bir HTTP isteğinde izin verilen istek başlık alanlarının sayısı üzerindeki sınırı değiştirebilme imkanı verir. Sunucu bu değerin, normal bir istemci isteğinin içerebileceği alan sayısından daha büyük olmasına ihtiyaç duyar. Bir istemci tarafından kullanılan istek başlık alanlarının sayısı nadiren 20’yi geçer, fakat bu farklı istemci gerçeklenimleri için değişiklik gösterir ve çoğunlukla kullanıcının tarayıcısını ayrıntılı içerik müzakeresini desteklemek için nasıl yapılandırdığıyla ilgilidir. İsteğe bağlı HTTP eklentileri çoğunlukla istek başlık alanları kullanılarak ifade edilir.

Bu yönerge, bazı hizmet reddi (DoS) saldırılarından kaçınmak için sunucu yöneticilerine, anormal istemci istekleri üzerinde daha iyi denetim imkanı sağlar. Eğer normal istemciler sunucudan istekte bulunurken çok fazla başlık alanı gönderildiğine dair bir hata iletisi alırlarsa bu değerin arttırılması gerekir.

Örnek:

LimitRequestFields 50

Uyarı

İsme dayalı sanal konaklar kullanıldığında, bu yönergenin değeri, yerel IP adresi ve port çifti için öntanımlı olan (listedeki ilk) sanal konaktan alınır.

.
top

LimitRequestFieldSize Yönergesi

Açıklama:İstemciden kabul edilecek HTTP isteği başlık uzunluğunu sınırlar.
Sözdizimi:LimitRequestFieldSize bayt-sayısı
Öntanımlı:LimitRequestFieldSize 8190
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Bu yönerge, HTTP istek başlığında izin verilecek bayt sayısını belirler.

LimitRequestFieldSize yönergesi, sunucu yöneticilerine HTTP istek başlık alanının azami uzunluğunu ayarlama imkanı verir. Sunucu bu değerin, normal bir istemci isteğinin içerebileceği herhangi bir başlık alanını tutabilecek kadar büyük olmasını gerektirir. Normal bir istek başlık alanı uzunluğu kullanıcının tarayıcısını ayrıntılı içerik müzakeresini desteklemek için nasıl yapılandırdığıyla ilgilidir. SPNEGO kimlik doğrulama başlıkları 12392 baytlık olabilir.

Bu yönerge, bazı hizmet reddi (DoS) saldırılarından kaçınmak için sunucu yöneticilerine, anormal istemci istekleri üzerinde daha iyi denetim imkanı sağlar.

Örnek:

LimitRequestFieldSize 4094
Normal şartlar altında öntanımlı değer değiştirilmemelidir. Ayrıca, kaynak kodu değiştirip yeniden derlemeden bu değeri 8190'dan büyük yapamazsınız.

Uyarı

İsme dayalı sanal konaklar kullanıldığında, bu yönergenin değeri, yerel IP adresi ve port çifti için öntanımlı olan (listedeki ilk) sanal konaktan alınır.

top

LimitRequestLine Yönergesi

Açıklama:İstemciden kabul edilecek HTTP istek satırının uzunluğunu sınırlar.
Sözdizimi:LimitRequestLine bayt-sayısı
Öntanımlı:LimitRequestLine 8190
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Bu yönerge, HTTP istek satırında izin verilecek bayt sayısını belirler.

LimitRequestLine yönergesi, sunucu yöneticilerine bir istemcinin HTTP istek satırının azami uzunluğunu ayarlama imkanı verir. İstek satırının içeriği HTTP yöntemi, URI ve protokol sürümünden oluştuğundan LimitRequestLine yönergesi, sunucudan bir istek için kullanılan istek adresinin uzunluğunu sınırlamış olur. Sunucu bu değerin, bir GET isteğinin sorgu kısmında aktarılabilen her bilgi dahil, özkaynak isimlerinden her birini tutabilecek kadar büyük olmasını gerektirir.

Bu yönerge, bazı hizmet reddi (DoS) saldırılarından kaçınmak için sunucu yöneticilerine, anormal istemci istekleri üzerinde daha iyi denetim imkanı sağlar.

Örnek:

LimitRequestLine 4094
Normal şartlar altında öntanımlı değer değiştirilmemelidir.

Uyarı

İsme dayalı sanal konaklar kullanıldığında, bu yönergenin değeri, yerel IP adresi ve port çifti için öntanımlı olan (listedeki ilk) sanal konaktan alınır.

top

LimitXMLRequestBody Yönergesi

Açıklama:Bir XML temelli istek gövdesinin uzunluğunu sınırlar.
Sözdizimi:LimitXMLRequestBody bayt-sayısı
Öntanımlı:LimitXMLRequestBody 1000000
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

Bir XML temelli istek gövdesinin azami bayt sayısını belirler. 0 değeri, XML'in sistem adreslenebilir belleğinin sınırları içinde sarmalanmasına izin veren (32bit ve 64bit sisteme bağlı olarak) katı bir sınırlama uygular, ancak yalnızca uyumluluk için vardır ve önerilmez, çünkü genel sistemde belleğin yetersiz kalmasına neden olabilecek eşzamanlı istekleri veya başka bir yerde tüketilen belleği hesaba katmaz.

Örnek:

# 1 MiB'lık sınırlama
LimitXMLRequestBody 1073741824
top

<Location> Yönergesi

Açıklama:İçerdiği yönergeler sadece eşleşen URL’lere uygulanır.
Sözdizimi:<Location URL-yolu|URL> ... </Location>
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

<Location> bölüm yönergesi kapsadığı yönergelerin etki alanını belirtilen URL’lerle sınırlar. Bu yönerge, <Directory> yönergesine benzer ve </Location> yönergesi ile biten bir alt bölüm başlatır. <Location> bölümleri yapılandırma dosyasında göründükleri sıraya göre, <Directory> bölümleri ve .htaccess dosyaları okunup <Files> bölümleri de işlendikten sonra işleme sokulurlar.

<Location> bölümleri dosya sisteminin tamamen dışında işlem görürler. Bunun çeşitli sonuçları olur. En önemlisi, <Location> yönergelerinin dosya sistemi konumlarına erişimi denetim altına almak için kullanılmaması gerekliliğidir. Aynı dosya sistemi konumuna farklı URL’lerle erişmek mümkün olduğundan bu tür erişim denetimleri hile ile atlatılabilir olacaktır.

URL'nin yol bileşeni aşağıdaki koşullardan herhangi birini sağlıyorsa sarmalanan yönergeler isteğe uygulanır:

Aşağıdaki örnekte yer belirtimi bir bölü çizgisi ile bitirilmemiştir. /private1, /private1/ ve /private1/file.txt istekleri için sarmalanan yönergeler uygulanacaktır, fakat /private1other isteğine uygulanmayacaktır.

<Location "/private1">
    #  ...
</Location>

Aşağıdaki örnekte yer belirtimi bir bölü çizgisi ile bitirilmiştir. /private2/ ve /private2/file.txt istekleri için sarmalanan yönergeler uygulanacaktır, fakat /private2 ve /private2other isteklerine uygulanmayacaktır.

<Location "/private2/">
    # ...
</Location>

<Location> ne zaman kullanılmalı

<Location> yönergesini dosya sistemi dışındaki içeriğe çeşitli yönergeler uygulamak için kullanın. Dosya sisteminde bulunan içerik için <Directory> ve <Files> bölümlerini kullanın. Bunun istisnası, sunucunun tamamına bir yapılandırma uygulamak için kolay bir yol olan <Location "/"> kullanımıdır.

Kaynağa yapılan (vekil olmayan) tüm istekler için eşleşecek URL, /yol/ şeklinde bir URL yolu olmalı; ne şema, ne konak ismi ne port ne de sorgu dizgesi içermelidir. Vekil istekleri için eşleşecek URL ise şema://sunucuadı/dosya-yolu şeklinde olmalı ve önek içermelidir.

URL içinde dosya kalıp karakterleri kullanılabilir. Dosya kalıp karakterleri bulunan bir dizgede bulunan ? karakteri herhangi bir tek karakterle eşleşirken * karakteri herhangi bir karakter dizisi ile eşleşecektir. URL yolu içindeki / karakterleri ile hiçbir dosya kalıp karakteri eşleşmez.

Ayrıca, ~ karakteri eşliğinde düzenli ifadeler de kullanılabilir. Örneğin,

<Location ~ "/(ek|hususi)/veri">
    #...
</Location>

yönergesi /ek/veri ve /hususi/veri alt dizgeleriyle eşleşecektir. <LocationMatch> yönergesi <Location> yönergesinin düzenli ifade sürümüne eşdeğer davranır ve bir çok yazı tipinde ~ karakterini - karakterinden ayırmak zor olduğu için tercih edilir.

<Location> işlevselliği özellikle SetHandler yönergesi ile birlikte kullanışlı olur. Örneğin, durum isteklerini etkin kılmak ama sadece example.com’dan gelen isteklere izin vermek için şöyle bir uygulama yapabilirsiniz:

<Location "/status">
  SetHandler server-status
  Require host example.com
</Location>

/ (bölü çizgisi) hakkında

Bölü çizgisinin URL içinde bulunduğu yere bağlı olarak özel anlamları vardır. Dosya sistemindeki çok sayıda yanyana kullanımının tek bir bölü çizgisi olarak ele alındığı duruma alışkın olanlar olabilir (yani, /home///foo ile /home/foo aynıdır). MergeSlashes yönergesine OFF atanmışsa URL uzayında bunun böyle olması gerekli değildir. Eğer çok sayıda bölü çizgisinin birleştirilmeden yanyana belirtilmesi gerekiyorsa <LocationMatch> yönergesinde ve <Location> yönergesinin düzenli ifadeli kullanımında bunun açıkça belirtilmesi gerekir.

Örneğin, <LocationMatch "^/abc"> yönergesi /abc ile eşleşecek ama //abc ile eşleşmeyecektir. <Location> yönergesinin düzenli ifade içermeyen kullanımındaki davranış vekil isteklerinde kullanılana benzer ve doğrudan kaynağa yapılan (vekil olmayan) isteklerde çok sayıda bölü çizgisi dolaylı olarak tek bir bölü çizgisiyle eşleşecektir. Örneğin, <Location "/abc/def"> belirtirseniz ve istek /abc//def şeklinde olursa bu ikisi eşleşir.

Ayrıca bakınız:

top

<LocationMatch> Yönergesi

Açıklama:İçerdiği yönergeler sadece düzenli ifadelerle eşleşen URL’lere uygulanır.
Sözdizimi:<LocationMatch düzifade> ... </LocationMatch>
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

<LocationMatch> yönergesi içerdiği yönergelerin etki alanını <Location> yönergesinin yaptığı gibi belirtilen URL’lerle sınırlar. Ancak argüman olarak basit bir dizge değil bir düzenli ifade alır. Örneğin,

<LocationMatch "/(ek|hususi)/veri">
    # ...
</LocationMatch>

yönergesi /ek/veri ve /hususi/veri alt dizgeleriyle eşleşecektir.

Eğer hedef, /ek/veri içeren değil de /ek/veri ile başlayan bir URL ise düzenli ifadenin önüne ^ getirmek gerekir.

<LocationMatch "^/(ek|hususi)/veri">

2.4.8 itibariyle, isimli gruplar ve geriye başvurular elde edilmekte olup ilgili isim büyük harfe çevrildikren sonra "MATCH_" ile öncelendikten sonra ortama yazılmaktadır. Böylece yol elemanlarına mod_rewrite gibi modüllerden veya düzenli ifadelerden başvurmak mümkün kılınmıştır. Karışıklığı önlemek için, numaralı (isimsiz) geriye başvurular yoksayılmaktadır. Bunların yerine isimli geriye başvurular kullanılmalıdır.

<LocationMatch "^/combined/(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</LocationMatch>

/ (bölü çizgisi) hakkında

Bölü çizgisi karakteri URL üzerinde göründüğü yere bağlı olarak farklı anlamlar içerir. İnsanlar, birden çok bitişik bölü çizgisinin sık sık tek bir bölü çizgisine daraltıldığı dosya sistemindeki davranışına alışkın olabilir (örn, /home///foo ile /home/foo aynıdır). MergeSlashes yönergesine OFF atanmışsa URL uzayında bunun böyle olması gerekli değildir. Eğer çok sayıda bölü çizgisinin birleştirilmeden yanyana belirtilmesi gerekiyorsa <LocationMatch> yönergesinde ve <Location> yönergesinin düzenli ifadeli kullanımında bunun açıkça belirtilmesi gerekir.

Örneğin, <LocationMatch "^/abc"> ile /abc isteği eşleşirken //abc isteği eşleşmez. <Location> yönergesinin regex olmayan kullanımı vekil isteklerindeki gibi davranır. Fakat vekil harici işlemlerde <Location> yönergesinin regex olmayan kullanımında çok sayıda bölü çizgisi örtük olarak tek bölü çizgisiyle eşleşir. Örneğin, <Location "/abc/def"> belirtirseniz /abc//def isteği bu ifade ile eşleşecektir.

Ayrıca bakınız:

top

LogLevel Yönergesi

Açıklama:Hata günlüklerinin ayrıntı seviyesini belirler.
Sözdizimi:LogLevel [modül:]seviye [modül:seviye] ...
Öntanımlı:LogLevel warn
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core
Uyumluluk:Modül ve dizin bağlamındaki yapılandırmalar Apache HTTP Sunucusunun 2.3.6 ve sonraki sürümlerinde kullanılabilmektedir.

LogLevel yönergesi hata günlüklerine kaydedilen hata iletilerinde hangi ayrıntılara yer verileceğini belirler (ErrorLog yönergesine bakınız). En yüksek önem derecesinden başlayarak olası seviye değerleri aşağıda sıralanmıştır:

Seviye Açıklama Örnek
emerg Acil durumlar - sistem kullanışsız. "Child cannot open lock file. Exiting"
(Alt süreç kilit dosyasını açamıyor. Çıkılıyor)
alert Ne yapılacaksa beklemeden yapılmalı. "getpwuid: couldn't determine user name from uid"
(getpwuid: Kullanıcı ismi numarasından saptanamadı)
crit Kriz durumları. "socket: Failed to get a socket, exiting child"
(socket: bir soket alınamadı, alt süreç çıkıyor)
error Hata durumları. "Premature end of script headers"
(Betik başlıkları beklenmedik şekilde bitti)
warn Uyarı durumları. "child process 1234 did not exit, sending another SIGHUP"
(1234 alt süreci çıkmadı, başka bir SIGHUP gönderiliyor)
notice Normal fakat önemli durum. "httpd: caught SIGBUS, attempting to dump core in ..."
(httpd: SIGBUS alındı, core dökümlenmeye çalışılıyor: ...)
info Bilgilendirme. "Server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers)..."
(Sunucu meşgul görünüyor, (StartServers veya Min/MaxSpareServers değerlerini arttırmanız gerekebilir)...)
debug Hata ayıklama seviyesi iletileri "Opening config file ..."
(... yapılandırma dosyası açılıyor)
trace1 İz sürme iletileri "proxy: FTP: control connection complete"
(vekil: FTP: denetim bağlantısı sağlandı)
trace2 İz sürme iletileri "proxy: CONNECT: sending the CONNECT request to the remote proxy"
(vekil: CONNECT: uzak vekile CONNECT isteği gönderiliyor)
trace3 İz sürme iletileri "openssl: Handshake: start"
trace4 İz sürme iletileri "read from buffered SSL brigade, mode 0, 17 bytes"
(tamponlu SSL gruplamasından okuma, kip 0, 17 baytİz sürme iletileri
trace5 İz sürme iletileri "map lookup FAILED: map=rewritemap key=keyname"
(eşleşme araması BAŞARISIZ: map=rewritemap key=keyname)
trace6 İz sürme iletileri "cache lookup FAILED, forcing new map lookup"
(arabellek araması BAŞARISIZ, yeni bir eşleşme araması başlatılıyor)
trace7 İz sürme iletileri, büyük miktarda veri dökümü "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"
trace8 İz sürme iletileri, büyük miktarda veri dökümü "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"

Belli bir seviye belirtildiğinde daha yüksek seviyeden iletiler de raporlanır. Örneğin, LogLevel info belirtildiğinde notice ve warn günlük seviyelerinin iletileri ayrıca raporlanacaktır.

En az crit seviyesinin kullanılması önerilir.

Örnek:

LogLevel notice

Ek Bilgi

Günlük iletileri normal bir dosyaya yazılırken notice seviyesinden iletiler engellenemez ve dolayısıyla daima raporlanırlar. Ancak, günlük kaydı syslog kullanılarak yapılıyorsa bu uygulanmaz.

Bir modül ismi olmaksızın bir seviye belirtmek seviyeyi bu seviyedeki tüm modüller için sıfırlayacaktır. Bir seviyyi bir modül ismiyle birlikte belirtmek seviyeyi sadece bu modül için sıfırlayacaktır. Modül ismi olarak, modülün kaynak dosyası ismini, modül kimliği veya _module sonekli modül ismi belirtmek mümkündür. Yani, aşağıdaki üç belirtim eşdeğerdedir:

LogLevel info ssl:warn
LogLevel info mod_ssl.c:warn
LogLevel info ssl_module:warn

Ayrıca seviyeyi dizin bağlamında değiştirmek de mümkündür:

LogLevel info
<Directory "/usr/local/apache/htdocs/app">
  LogLevel debug
</Directory>
Dizin bağlamında günük seviyesi yapılandırması sadece istek çözümlendikten ve istek dizinle ilişkilendirildikten sonra günlüklenen iletileri etkiler. Bağlantı veya sunucu ile ilişkilendirilmemiş günlük iletileri etkilenmez.

Ayrıca bakınız:

top

MaxKeepAliveRequests Yönergesi

Açıklama:Bir kalıcı bağlantıda izin verilen istek sayısı
Sözdizimi:MaxKeepAliveRequests sayı
Öntanımlı:MaxKeepAliveRequests 100
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

MaxKeepAliveRequests yönergesi KeepAlive etkinken bağlantı başına izin verilecek istek sayısını sınırlar. Değer olarak 0 belirtilirse istek sayısı sınırsız olur. Sunucu başarımını yüksek tutmak için yüksekçe bir değer belirtmenizi öneririz.

Örnek:

MaxKeepAliveRequests 500
top

MaxRangeOverlaps Yönergesi

Açıklama:Özkaynağın tamamını döndürmeden önce izin verilen üst üste binen aralık sayısı (100-200,150-300 gibi)
Sözdizimi:MaxRangeOverlaps default | unlimited | none | aralık-sayısı
Öntanımlı:MaxRangeOverlaps 20
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core
Uyumluluk:Apache HTTP Sunucusunun 2.3.15 ve sonraki sürümlerinde kullanılabilmektedir.

MaxRangeOverlaps yönergesi, sunucunun istemciye göndermeye gönüllü olacağı üst üste binen HTTP Range'lerinin sayısını sınırlar. İzin verilenden daha fazlası istenmişse özkaynağın tamamı döndürülür.

default
Üst üste binen HTTP Range'lerinin sayısını derleme sırasında belirlenen öntanımlı 20 değeriyle sınırlar.
none
Üst üste binen Range başlıkları yoksayılır.
unlimited
Sunucunun sağlamaya gönüllü olacağı üst üste binen HTTP Range'lerinin sayısı sınırlanmaz.
aralık sayısı
Sunucunun sağlamaya gönüllü olacağı üst üste binen HTTP Range'lerinin azami sayısını ifade eden pozitif bir tamsayı.
top

MaxRangeReversals Yönergesi

Açıklama:Özkaynağın tamamını döndürmeden önce izin verilen ters sıralı aralık sayısı (100-200,50-70 gibi)
Sözdizimi:MaxRangeReversals default | unlimited | none | aralık-sayısı
Öntanımlı:MaxRangeReversals 20
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core
Uyumluluk:Apache HTTP Sunucusunun 2.3.15 ve sonraki sürümlerinde kullanılabilmektedir.

The MaxRangeReversals yönergesi, sunucunun istemciye göndermeye gönüllü olacağı ter sıralı HTTP Range'lerinin sayısını sınırlar. İzin verilenden daha fazlası istenmişse özkaynağın tamamı döndürülür.

default
Ters sıralı HTTP Range'lerinin sayısını derleme sırasında belirlenen öntanımlı 20 değeriyle sınırlar.
none
Ters sıralı Range başlıkları yoksayılır.
unlimited
Sunucunun sağlamaya gönüllü olacağı ters sıralı HTTP Range'lerinin sayısı sınırlanmaz.
aralık-sayısı
Sunucunun sağlamaya gönüllü olacağı ters sıralı HTTP Range'lerinin azami sayısını ifade eden pozitif bir tamsayı.
top

MaxRanges Yönergesi

Açıklama:Özkaynağın tamamını döndürmeden önce izin verilen aralık sayısı
Sözdizimi:MaxRanges default | unlimited | none | aralık-sayısı
Öntanımlı:MaxRanges 200
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core
Uyumluluk:Apache HTTP Sunucusunun 2.3.15 ve sonraki sürümlerinde kullanılabilmektedir.

MaxRanges yönergesi, sunucunun istemciye göndermeye gönüllü olacağı HTTP Range'lerinin sayısını sınırlar. İzin verilenden daha fazlası istenmişse özkaynağın tamamı döndürülür.

default
HTTP Range'lerinin sayısını derleme sırasında belirlenen öntanımlı 200 değeriyle sınırlar.
none
Range başlıkları yoksayılır.
unlimited
Sunucunun sağlamaya gönüllü olacağı HTTP Range'lerinin sayısı sınırlanmaz.
aralık-sayısı
Sunucunun sağlamaya gönüllü olacağı HTTP Range'lerinin azami sayısını ifade eden pozitif bir tamsayı.
top

MergeSlashes Yönergesi

Açıklama:Sunucunun URL’lerde ardışık bölü çizgilerini birleştirip birleştirmeyeceğini denetler.
Sözdizimi:MergeSlashes ON|OFF
Öntanımlı:MergeSlashes ON
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.39 sürümünde eklendi

Öntanımlı olarak, sunucu istek adresinin yol bileşenindeki ardışık bölü çizgilerini ('/') birleştirip tek bölü çizgisi olarak ele alır.

Bu adresleri dosya sistemi ile eşleştirirken, bu ardışık bölü çizgilerinin önemi yoktur. Ancak, bu adresler CGI veya vekil gibi başka yollardan değerlendiriliyorsa bu ardışık bölü çizgilerinin olduğu gibi kalması tercih edilebilir. Bu durumlarda ardışık bölü çizgilerinin birleştirilmesini önlemek için, eskiden, MergeSlashes yönergesine OFF atanabiliyordu.

OFF atanması durumunda, yapılandırma dosyasında, adresin yol bileşeni ile eşleşen düzenli ifadelerde (LocationMatch, RewriteRule, ...) ardışık bölü çizgilerinin hesaba katılması gerekir. Düzenli ifade içermeyen Location yönergeleri daima birleştirilmiş bölü çizgileri içeren bir URL'ye karşı çalışır ve çok sayıdaki bölü çizgileri arasında bir ayrım yapamaz.

top

MergeTrailers Yönergesi

Açıklama:Trailer alanlarının başlığa dahil edilip edilmeyeceğini belirler
Sözdizimi:MergeTrailers [on|off]
Öntanımlı:MergeTrailers off
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.11 ve sonrası

Bu yönerge HTTP Trailer alanlarının dahili HTTP başlıklarına kopyalanıp kopyalanmayacağını belirler. Kopyalama işlemi istek gövdesi tamamen alındığında gerçekleşir, çoğu başlık işleminin çok sonra istek başlıklarını inceleme veya değiştirme şansı olur.

Bu seçenek, Trailer alanlarını daima kopyalayan 2.4.11 öncesi dağıtımlarla uyumluluk için vardır.

top

Mutex Yönergesi

Açıklama:Muteks mekanizmasını ve kilit dosyası dizinini tüm muteksler veya belirtilenler için yapılandırır
Sözdizimi:Mutex mekanizma [default|muteks-ismi] ... [OmitPID]
Öntanımlı:Mutex default
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core
Uyumluluk:Apache HTTP Sunucusunun 2.3.4 ve sonraki sürümlerinde kullanılabilmektedir.

Mutex yönergesi httpd ve diğer modüllerin özkaynaklara erişimi dizgeleştirmekte kullandıkları mekanizmanın yanında isteğe bağlı olarak kilit dosyasının yerini belirler. İlk değiştirge olarak default belirtilirse tüm mutekslerin ayarları değişir; ikinci değiştirge olarak bir muteks ismi belirtilirse (aşağıdaki tabloya bakın) yalnızca bu muteksin öntanımlıları değişir.

Mutex yönergesi genelde aşağıdaki istisnai durumlarda kullanılır:

Destekleyen modüller

Bu yönerge sadece ap_mutex_register() API'si kullanılarak çekirdek sunucuda imlenmiş muteksleri yapılandırır. httpd ile birlikte dağıtılan tüm modüller Mutex yönergesini destekler, fakat üçüncü parti modüllerin hepsi desteklemeyebilir. Bu yönergenin desteklenip desteklenmediğini öğrenmek için üçüncü parti modülün belgelerini inceleyin; destekliyorsa muteks ad(lar)ı belirtilmiştir.

Kullanılabilen muteks mekanizmaları:

Çoğu mekanizma, yalnız kendilerini destekleyen platformlarda APR tarafından da destekleniyorsa kullanılabilir. Tüm platformlarda kullanılamayan mekanizmalar posixsem, sysvsem, sem, pthread, fcntl, flock ve file mekanizmalarıdır.

fcntl ve flock dosya tabanlı mekanizmaları ile bir yol sağlandığı takdirde bu, kilit dosyasının oluşturulacağı dizindir. Öntanımlı dizin, httpd'nin çalışma anı dizini ServerRoot'a görelidir. /path/to/mutex için daima bir yerel diskteki dosya sistemi kullanılır, asla NFS- veya AFS gibi bir ağ dosya sistemi kullanılmaz. Dosya ismi daima muteks ismi ile başlar, buna modül tarafından sağlanan isteğe bağlı bir aşama dizgesi eklenebilir, OmitPID değeri belirtilmemişse httpd ebeveyn sürecinin süreç kimliği buna eklenerek dosya ismi eşsiz kılınır. Böylece, çok sayıda httpd süreci aynı kilit dosyası dizinini paylaştığı durumda çakışmalar önlenmiş olur. Örneğin, muteks ismi mpm-accept ise ve kilit dosyası dizini /var/httpd/locks ise ve ebeveyn süreç kimliği 12345 ise bu httpd sürecine ait kilit dosyası ismi /var/httpd/locks/mpm-accept.12345 olurdu.

Güvenlik

Muteks dosyalarını herkesin yazabildiği /var/tmp gibi dizinlere koymaktan kaçınmak en iyisidir. Örneğin, birinin aynı dizinde oluşturmaya çalıştığı bir dosya ile aynı isimde bir kilit dosyasını sunucunun da oluşturmaya çalıştığı durumda sunucu engellenerek bir hizmet reddi saldırısı gerçekleştirilmiş gibi olur.

httpd ve birlikte dağıtılan modüller tarafından kullanılan mutekslerin isimleri:

Muteks ismi Modül(ler) Korunan özkaynak
mpm-accept prefork ve worker MPM'leri Gürleyen sürü sorunundan kaçınmak için gelen bağlantılar; daha fazla bilgi için başarımın arttırılması belgesine bakın.
authdigest-client mod_auth_digest Paylaşımlı bellekteki istemci listesi
authdigest-opaque mod_auth_digest Paylaşımlı bellekteki sayaç
ldap-cache mod_ldap LDAP sonuç arabelleği
rewrite-map mod_rewrite Çoklu isteklerdeki birbirine karışmış G/Ç'tan kaçınmak için harici eşleştirme progamlarıyla iletişim
ssl-cache mod_ssl SSL oturum arabelleği
ssl-stapling mod_ssl OCSP zımbalama yanıtı arabelleği
watchdog-callback mod_watchdog Bir istemci modülünün geri çağırım işlevi

OmitPID seçeneği, httpd ebeveyn süreç kimliğinin kilit dosyası ismine eklenmesini engeller.

Aşağıdaki örnekte, mpm-accept muteksinin mekanizmasının derleme sırasındaki öntanımlısı, kilit dosyasının oluşturulacağı dizinin /var/httpd/locks olarak belirtildiği fcntl mekanizmasıyla değiştirilmektedir.Tüm diğer mutekslerin derleme anı öntanımlı mekanizması ise sysvsem ile değiştirilmektedir.

Mutex sysvsem default
Mutex fcntl:/var/httpd/locks mpm-accept
top

NameVirtualHost Yönergesi

Açıklama:ÖNERİLMİYOR: İsme dayalı sanal konaklar için IP adresi belirtir
Sözdizimi:NameVirtualHost adres[:port]
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core

2.3.11 öncesinde, NameVirtualHost yönergesi, isme dayalı sanal konaklar için belli bir IP adresi ve port çiftini sunucuya tanıtmak için gerekliydi. 2.3.11 ve sonrasında, bir IP adresi ve port çifti her zaman çok sayıda sanal konakta kullanılabilmekte, isme dayalı sanal barındırma bu adres için özdevinimli olarak etkin kılınmaktadır.

Bu yönerge şu an etkisizdir.

Ayrıca bakınız:

top

Options Yönergesi

Açıklama:Belli bir dizinde geçerli olacak özellikleri yapılandırır.
Sözdizimi:Options [+|-]seçenek [[+|-]seçenek] ...
Öntanımlı:Options FollowSymlinks
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Options
Durum:Çekirdek
Modül:core
Uyumluluk:2.3.11 sürümünde öntanımlı değer All değiştirilip FollowSymlinks yapıldı.

Options yönergesi belli bir dizinde hangi sunucu özelliklerinin etkin olacağını (veya olmayacağını) belirler.

seçenek olarak hiçbir ek özellik etkin olmayacaksa None, aksi takdirde aşağıdakilerden biri veya bir kaçı belirtilir:

All
MultiViews hariç tüm seçenekler.
ExecCGI
mod_cgi kullanan CGI betiklerinin çalışmasına izin verilir.
FollowSymLinks
Sunucu bu dizindeki sembolik bağları izler. Bu öntanımlıdır.

Sembolik bağlar izlense bile <Directory> bölümleriyle eşleşen dosya yolları değiştirilmez.

FollowSymLinks ve SymLinksIfOwnerMatch Options sadece <Directory> bölümlerinde veya .htaccess dosyaları içinde çalışır.

Sembolik bağ sınamaları, atlatılabilir yarış koşullarına konu olduğundan bu seçeneğin yokluğu bir güvenlik sınırlaması olarak değerlendirilmemelidir.

Includes
mod_include tarafından sağlanan sunucu taraflı içeriklere izin verilir.
IncludesNOEXEC
Sunucu taraflı içeriklere izin verilir fakat #exec cmd ve #exec cgi iptal edilir. Ancak, ScriptAlias’lı dizinlerdeki CGI betikleri için #include virtual hala mümkün olacaktır.
Indexes
İstenen URL bir dizin ile eşleşiyorsa ve bu dizin için bir DirectoryIndex (index.html gibi) belirtilmemişse mod_autoindex bu dizinin biçimlenmiş bir listesini döndürecektir.
MultiViews
mod_negotiation kullanılarak içerik uzlaştırmalı çok görünümlü içeriğe izin verilir.

Bilgi

mod_negotiation karşılaştırmak değerlendirmek için gerçek özkaynaklara ihtiyaç duyduğundan <Directory> yönergesinde belirtilendan farklı bir yer ayarlanırsa bu seçenek yoksayılır.

SymLinksIfOwnerMatch
Sunucu sembolik bağları sadece sembolik bağın hedefi ile bulunduğu dizinin sahibinin aynı kullanıcı olması halinde izleyecektir.

FollowSymLinks ve SymLinksIfOwnerMatch Options sadece <Directory> bölümlerinde veya .htaccess dosyaları içinde çalışır.

Sembolik bağ sınamaları, atlatılabilir yarış koşullarına konu olduğundan bu seçenek bir güvenlik sınırlaması olarak değerlendirilmemelidir.

Normalde, bir dizine çok sayıda Options uygulanabilirse de, dizine en uygun olanı uygulanıp diğerleri yok sayılır; seçenekler katıştırılmaz (bkz, Bölümler Nasıl Katıştırılır?). Bununla birlikte, önüne bir + veya - simgesi konmuş seçenekler varsa, o seçenekler katıştırılır. Önüne + konmuş seçenekler mevcutlara eklenirken - konmuş seçenekler silinir.

Bilgi

+ veya - imli seçenekler içeren Options ile imsiz seçenekler içerenlerin karışık olarak kullanılması aslında geçersiz bir sözdizimi olup sunucunun başlatılması sırasında sözdizimi denetiminin çıkmasıyla reddedilir.

Örneğin, + ve - imleri olmaksızın,

<Directory "/web/docs">
  Options Indexes FollowSymLinks
</Directory>

<Directory "/web/docs/spec">
  Options Includes
</Directory>

yapılandırmasıyla /web/docs/spec dizininde sadece Includes seçeneği etkin olacaktır. Bununla birlikte, ikinci Options yönergesinde + ve - imleri kullanılırsa,

<Directory "/web/docs">
  Options Indexes FollowSymLinks
</Directory>

<Directory "/web/docs/spec">
  Options +Includes -Indexes
</Directory>

yapılandırmasıyla /web/docs/spec dizininde FollowSymLinks ve Includes seçenekleri etkin olacaktır.

Ek Bilgi

-IncludesNOEXEC veya -Includes kullanımı, önceki ayarların ne olduğuna bakılmaksızın sunucu taraflı içeriğin tamamen iptaline sebep olur.

Herhangi bir başka değer belirtilmedikçe FollowSymlinks öntanımlıdır.

top

Protocol Yönergesi

Açıklama:Dinlenen bir soket için protokol
Sözdizimi:Protocol protokol
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:Apache httpd 2.1.5 ve sonrasında kullanılabilmektedir. Windows'ta ise Apache httpd 2.3.3 ve sonrasında kullanılabilmektedir.

Bu yönerge dinlenen belli bir soket için kullanılacak protokolü belirler. Belirtilen protokol bir isteği hangi modülün ele alacağını ve AcceptFilter yönergesiyle yapılan özel eniyilemelere uygulanacak protokolü belirler.

Bu yönerge çoğu yapılandırma için gerekli değildir. Belirtilmezse, port 443 için https öntanımlıdır ve diğer tüm portlar için http ntanımlıdır. Protokol, hangi modülün bir isteği işleyeceğini belirlemek ve AcceptFilter yönergesi ile protokole özgü eniyilemeleri uygulamak için kullanılır.

Örneğin, https'i standartdışı bir portta çalıştırmak isterseniz protokolü şöyle belirtebilirsiniz:

Protocol https

Protokolü Listen yönergesini kullanarak da belirtebilirsiniz.

Ayrıca bakınız:

top

Protocols Yönergesi

Açıklama:Sunucu/sanal konak için kullanılabilecek protokoller
Sözdizimi:Protocols protokol ...
Öntanımlı:Protocols http/1.1
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:Sadece Apache 2.4.17 ve sonrasında kullanılabilir.

Bu yönerge bir sunucu/sanal konak için kullanılabilecek protokolleri belirtmekte kullanılır. Bu liste, bir istemcinin bir sanal konak veya sunucu ile uzlaşabilmesini sağlayan prokolleri belirler.

Bir sanal konak veya sunucuda kullanılabilecek protolleri çeşitlendirmek isterseniz bu protokolleri belirtmeniz gerekir. 1.0 ve 0.9 istemcilerle uyumlu olan http/1.1 protokolü öntanımlıdır.

Örneğin, bir sunucunun TLS'li HTTP/2 protokolünü desteklemesini şöyle sağlayabilirsiniz:

Protocols h2 http/1.1

Geçerli protokoller, http ve https bağlantıları için http/1.1 htps bağlantıları için h2 ve http bağlantıları için h2c protokolleridir. Modüller başka protokollerin de etkinleştirilmesini gerektirebilir.

Kullanımından vazgeçilmiş protokollerin silinmesi gerekmez. Böyle protokol isimleri basitçe yoksayılır.

Ana sunucu için belirtilen protokoller, kendi protokol yönergesi olmayan sanal konaklar için de geçerlidir. Diğer yandan sanal konaklarda protokol belirtilmesi ana sunucuda belirtien protollerin bu sanal konaklarda geçersiz olmasına sebep olur.

Ayrıca bakınız:

top

ProtocolsHonorOrder Yönergesi

Açıklama:Uzlaşma sırasında protokollerin öncelik sırasını belirler
Sözdizimi:ProtocolsHonorOrder On|Off
Öntanımlı:ProtocolsHonorOrder On
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:Sadece Apache 2.4.17 ve sonrasında kullanılabilir.

Sunucuda Protocols yönergesinde listelemiş protokollerin mi yoksa istemcinin protokol listesinin mi öncelikli olacağı bu yönerge ile belirtilir.

Off belirtilirse, istemcinin protokol listesi sunucu yapılandırmasındaki sıralamanın önüne geçer.

ProtocolsHonorOrder yönergesine on belirtilirse (öntanımlıdır), istemicinin protokol sıralaması dikkate alınmaz ve protokol uzlaşımının sonucunu sunucu ayarlarındaki sıralama belirler.

Ayrıca bakınız:

top

QualifyRedirectURL Yönergesi

Açıklama:REDIRECT_URL ortam değişkeninin tamamen nitelenmiş olup olmayacağını denetler
Sözdizimi:QualifyRedirectURL On|Off
Öntanımlı:QualifyRedirectURL Off
Bağlam:sunucu geneli, sanal konak, dizin
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:Yönerge 2.4.18 ve sonrasında desteklenmektedir. 2.4.17 sürümünde 'QualifyRedirectURL On' yapılandırması mevcutmuş gibi davranılır.

Bu yönerge sunucuya REDIRECT_URL ortam değişkenin tamamen nitelenmiş olacağını temin eder. Değişken öntanımlı olarak istemci tarafından talep edilen URL'yi harfi harfine içerir, "/index.html" gibi. QualifyRedirectURL On belirtilseydi aynı istek "http://www.example.com/index.html" gibi bir değerle sonuçlanırdı.

Böyle belirtilmemiş olsa bile, istek tam nitelenmiş bir URL içerseydi REDIRECT_URL de tam nitelenmiş URL'yi içerirdi.

top

ReadBufferSize Yönergesi

Açıklama:Veriyi okumakta kullanılacak tampon sayısı
Sözdizimi:ReadBufferSize bayt-sayısı
Öntanımlı:ReadBufferSize 8192
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.27 ve sonrası

Bu yönerge, ağdan veya dosyalardan veri okumak için kullanılan bellek tamponunun boyutunu (bayt cinsinden) yapılandırmaya izin verir.

Daha büyük bir arabellek, daha büyük verilerle başarımı artırabilir, ancak bağlantı başına tüketilen bellek artar. Yapılandırılabilir en küçük boyut 1024'tür.

top

RegexDefaultOptions Yönergesi

Açıklama:Regex düzenli ifadeleri için öntanımlı/küresel seçenekleri yapılandırır
Sözdizimi:RegexDefaultOptions [none] [+|-]seçenek [[+|-]seçenek] ...
Öntanımlı:RegexDefaultOptions DOTALL DOLLAR_ENDONLY
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core
Uyumluluk:Sadece Apache 2.4.30 ve sonrasında kullanılabilmektedir.

Bu yönerge kendisinden sonra kullanılan bütün düzenli ifsdelerin davranışını etkiler.

'+' ile öncelenmiş bütün seçenekler önceden atanmış seçeneklere eklenir.
'-' ile öncelenmiş bütün seçenekler önceden atanmış seçeneklerden çıkarılır.
'+' veya '-' ile öncelenmemiş her seçenek önceden atanmış seçenekleri silerek onların yerini alır.
none ile önceden atanmış tüm seçenekler sıfırlanır.

seçenek şunlardan biri olabilir:

ICASE
Harf büyüklüğüne duyarlı eşleşmeler kullanılır.
EXTENDED
Perl'ün /x seçeneği; kalıp içindeki açıklamaları ve (öncelenmemiş) boşlukları yoksayar.
DOTALL
Perl'ün /s seçeneği; '.' karakteri, satırsonu karakteri ile eşleşir.
DOLLAR_ENDONLY
'$' dizgenin sonu ile eşleşir.
# Tüm düzenli ifadeler için öntanımlı olarak ICASE seçeneğini ekler:
RegexDefaultOptions +ICASE
...
# Öntanımlı DOLLAR_ENDONLY seçeneği silinir, diğer seçenekler tutulur:
RegexDefaultOptions -DOLLAR_ENDONLY
...
# Atanmış seçenekler silinir, DOTALL öntanımlı seçenek yapılır:
RegexDefaultOptions DOTALL
...
# Tüm seçenekler silinir, öntanımlı seçenek kalmaz.
RegexDefaultOptions none
...
top

RegisterHttpMethod Yönergesi

Açıklama:Standart olmayan HTTP yöntemlerini devreye alır
Sözdizimi:RegisterHttpMethod yöntem [yöntem [...]]
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core
Uyumluluk:Apache HTTP Sunucusunun 2.4.24 ve sonraki sürümlerinde kullanılabilmektedir.

Bu yönerge sunucunun standatta bulunmayan ek HTTP yöntemlerini kullanabilmesini sağlar. Yönergelerde standartta olmayan yöntem isimleri kullanmak gerektiğinde veya sunucunun modüllere sadece standart yöntemleri aktaracak şekilde yapılandırıldığı durumlarda bazı standart-dışı yöntemleri vekil veya CGI betikleriyle aktarmayı mümkün kılmak için bu gereklidir.

Ayrıca bakınız:

top

RLimitCPU Yönergesi

Açıklama:Apache httpd alt süreçleri tarafından çalıştırılan süreçlerin işlemci tüketimine sınırlama getirir.
Sözdizimi:RLimitCPU saniye|max [saniye|max]
Öntanımlı:Bir değer belirtilmemiştir; işletim sistemi öntanımlıları kullanılır
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

1 veya 2 değer alır. İlk değer bütün süreçler için sanal özkaynak sınırını, ikinci değer ise kesin özkaynak sınırını belirler. İki değer de birer sayı olabileceği gibi bu sınırın işletim sistemi yapılandırmasında izin verilen üst sınıra ayarlanacağını belirtmek üzere max olabilir. Kesin özkaynak sınırını yükseltmek için sunucunun root olarak veya sistem açılışı sırasında çalıştırılması gerekir.

Bu sınırlar Apache httpd’nin kendi alt süreçlerine değil, isteklere yanıt verirken Apache httpd alt süreçlerinin çatalladıkları süreçlere uygulanır. Bunlar CGI betikleri ve SSI çalıştırma komutları olabilir fakat borulu günlük kaydı gibi ana Apache httpd süreci tarafından çatallanmış süreçler olmazlar.

İşlemci özkaynak sınırları saniye cinsinden ifade edilir.

Ayrıca bakınız:

top

RLimitMEM Yönergesi

Açıklama:Apache httpd alt süreçleri tarafından çalıştırılan süreçlerin bellek tüketimine sınırlama getirir.
Sözdizimi:RLimitMEM bayt-sayısı|max [bayt-sayısı|max]
Öntanımlı:Bir değer belirtilmemiştir; işletim sistemi öntanımlıları kullanılır
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

1 veya 2 değer alır. İlk değer bütün süreçler için sanal özkaynak sınırını, ikinci değer ise kesin özkaynak sınırını belirler. İki değer de birer sayı olabileceği gibi bu sınırın işletim sistemi yapılandırmasında izin verilen üst sınıra ayarlanacağını belirtmek üzere max olabilir. Kesin özkaynak sınırını yükseltmek için sunucunun root olarak veya sistem açılışı sırasında çalıştırılması gerekir.

Bu sınırlar Apache httpd’nin kendi alt süreçlerine değil, isteklere yanıt verirken Apache httpd alt süreçlerinin çatalladıkları süreçlere uygulanır. Bunlar CGI betikleri ve SSI çalıştırma komutları olabilir fakat borulu günlük kaydı gibi ana Apache httpd süreci tarafından çatallanmış süreçler olmazlar.

Bellek özkaynak sınırları süreç başına bayt sayısı olarak ifade edilir.

Ayrıca bakınız:

top

RLimitNPROC Yönergesi

Açıklama:Apache httpd alt süreçleri tarafından çalıştırılabilecek süreç sayısına sınırlama getirir.
Sözdizimi:RLimitNPROC sayı|max [sayı|max]
Öntanımlı:Bir değer belirtilmemiştir; işletim sistemi öntanımlıları kullanılır
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

1 veya 2 değer alır. İlk değer bütün süreçler için sanal özkaynak sınırını, ikinci değer ise kesin özkaynak sınırını belirler. İki değer de birer sayı olabileceği gibi bu sınırın işletim sistemi yapılandırmasında izin verilen üst sınıra ayarlanacağını belirtmek üzere max olabilir. Kesin özkaynak sınırını yükseltmek için sunucunun root olarak veya sistem açılışı sırasında çalıştırılması gerekir.

Bu sınırlar Apache httpd’nin kendi alt süreçlerine değil, isteklere yanıt verirken Apache httpd alt süreçlerinin çatalladıkları süreçlere uygulanır. Bunlar CGI betikleri ve SSI çalıştırma komutları olabilir fakat borulu günlük kaydı gibi ana Apache httpd süreci tarafından çatallanmış süreçler olmazlar.

Süreç sayısı sınırı kullanıcı başına süreç sayısına sınırlama getirir.

Ek Bilgi

CGI süreçleri sunucu kullanıcı kimliğinden farklı bir kullanıcı kimliği altında çalışmıyorsa bu yönerge sunucunun kendi oluşturduğu süreç sayısını sınırlayacaktır. Bunun kanıtı error_log’da iletilerin çatallanamamasıdır.

Ayrıca bakınız:

top

ScriptInterpreterSource Yönergesi

Açıklama:CGI betikleri için yorumlayıcı belirleme tekniği
Sözdizimi:ScriptInterpreterSource Registry|Registry-Strict|Script
Öntanımlı:ScriptInterpreterSource Script
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:Sadece Win32 için.

Bu yönerge Apache httpd’nin CGI betiklerini çalıştıracak yorumlayıcıyı nasıl tespit edeceğini belirler. Script öntanımlı olup Apache httpd’nin yorumlayıcı olarak betiğin diyezli ünlem satırında (#! ile başlayan ilk satır) belirtilen yorumlayıcıyı kullanacağını belirtir. Win32 sistemlerinde bu satır genellikle şöyledir:

#!C:/Perl/bin/perl.exe

perl yorumlayıcının yeri PATH değişkeninde kayıtlı ise şöyle de olabilir:

#!perl

ScriptInterpreterSource Registry değeri ise betik dosyası uzantısının (.pl gibi) Windows Sicili içindeki HKEY_CLASSES_ROOT ağacında arama yapmak için bir arama anahtarı olarak kullanılmasını sağlar. Betik dosyasını çalıştırmak için tanımlanmış komutu bulmak için Shell\ExecCGI\Command yoluna, orada yoksa Shell\Open\Command yoluna bakılır. İkisi de yoksa son çare olarak Script seçeneğinin davranışına dönülür.

Güvenlik

ScriptAlias’lı dizinlerde Apache httpd bulduğu her dosyayı çalıştırmayı deneyeceğinden ScriptInterpreterSource Registry yapılandırmasını kullanırken dikkatli olun. Registry seçeneği genellikle çalıştırılmayacak dosyalar için istenmeyen program çağrılarına sebep olabilir. Örneğin, çoğu Windows sisteminde .htm dosyaları için ön tanımlı "open" komutu Microsoft Internet Explorer’ın çalıştırılmasına sebep olur; bu bakımdan, betik dizininde bulunan bir .htm dosyası için yapılan bir HTTP isteği tarayıcının sunucu artalanında çalıştırılmasına sebep olacaktır. Bu, sistemi bir kaç dakika içinde çökertmek için iyi bir yoldur.

Registry-Strict seçeneği Registry seçeneğinin yaptığını Shell\ExecCGI\Command yolu için yapar. ExecCGI sistem tarafından bilinen bir anahtar olmadığından Windows Siciline elle kaydedilmesi gerekir ve dolayısıyla sisteminiz üzerinde istenmeyen program çağrılarına sebep olmaz.

top

SeeRequestTail Yönergesi

Açıklama:İsteğin 63 karakterden büyük olduğu varsayımıyla, mod_status'un ilk 63 karakteri mi yoksa son 63 karakteri mi göstereceğini belirler.
Sözdizimi:SeeRequestTail On|Off
Öntanımlı:SeeRequestTail Off
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core
Uyumluluk:Apache httpd 2.2.7 ve sonrasında kullanılabilmektedir.

mod_status modülü ExtendedStatus On ile işleme alınan asıl isteği gösterir. Tarihsel amaçlarla, isteğin sadece 63 karakteri gösterme amacıyla saklanır. Bu yönerge ilk 63 karakterin mi (önceki davranış ve öntanımlı durum) yoksa son 63 karakterin mi saklanacağını belirler. Bu, şüphesiz, isteğin uzunluğu 64 karakter veya daha fazlaysa uygulanabilirdir.

Apache httpd'ye gelen istek GET /disk1/storage/apache/htdocs/images/imagestore1/food/apples.jpg HTTP/1.1 ise mod_status şunu gösterir:

Off (öntanımlı) GET /disk1/storage/apache/htdocs/images/imagestore1/food/apples
On orage/apache/htdocs/images/imagestore1/food/apples.jpg HTTP/1.1
top

ServerAdmin Yönergesi

Açıklama:Sunucunun hata iletilerinde istemciye göstereceği eposta adresi
Sözdizimi:ServerAdmin eposta-adresi|URL
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

ServerAdmin yönergesi, sunucunun bir hata durumunda istemciye döndüreceği hata iletilerinde içereceği iletişim adresini belirtmek için kullanılır. Eğer httpd sağlanan değerin bir URL olmadığını saptarsa değerin bir eposta adresi olduğuna hükmeder ve önüne mailto: getirerek onu bir hiper bağ hedefi olarak kullanır. Çoğu CGI betiği bir eposta adresi belirtildiği kabulünü yaptığından değer olarak bir URL değil bir eposta adresi belirtmeniz önerilir. Eğer bir URL belirtecekseniz hedef sizin denetiminizde olan başka bir sunucuda bulunmalıdır, yoksa kullanıcılar hata durumunda bu adrese erişemeyebilirler.

Kullanıcıların sunucu hakkında konuşurken isminizden bahsetmemeleri için burada belirtilecek adresin sırf bu işe adanmış bir adres olması daha iyidir. Örnek:

ServerAdmin www-admin@foo.example.com
top

ServerAlias Yönergesi

Açıklama:İstekleri isme dayalı sanal konaklarla eşleştirilirken kullanılacak konak adları için başka isimler belirtebilmeyi sağlar.
Sözdizimi:ServerAlias konakadı [konakadı] ...
Bağlam:sanal konak
Durum:Çekirdek
Modül:core

ServerAlias yönergesi, istekleri isme dayalı sanal konaklarla eşleştirilirken kullanılacak konak adları için başka isimler belirtebilmeyi sağlar. ServerAlias dosya adı kalıp karakterleri içerebilir.

<VirtualHost *:80>
  ServerName server.example.com
  ServerAlias server server2.example.com server2
  ServerAlias *.example.com
  UseCanonicalName Off
  # ...
</VirtualHost>

İsme dayalı sanal konaklardan en iyi eşleşme kümesinde olanlar yapılandırmada göründükleri sıraya göre işleme sokulur. Joker kullanımları arasında fark gözetilmeksizin ServerName veya ServerAlias yönergesi eşleşen ilk sanal konak kullanılır.

<VirtualHost> bölümü içindeki isimlerin sırası (jokersiz) ServerAlias yönergesindeki gibi ele alınır.

Ayrıca bakınız:

top

ServerName Yönergesi

Açıklama:Sunucunun özdeşleşeceği konak ismi ve port.
Sözdizimi:ServerName [şema://]alan-adı|ip-adresi[:port]
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

ServerName yönergesi, sunucunun kendini betimlemekte kullanacağı şema, konak adı ve port değerlerini belirler.

isme dayalı sanal konaklar kullanılırken bir sanal konağı eşsiz bir şekilde betimlemek için ServerName kullanılır (muhtemelen ServerAlias ile birlikte).

Ek olarak, UseCanonicalName yönergesine öntanımlı olmayan bir değer atanarak özüne yönlendiren URL'ler oluştururken de bu yönerge kullanılır.

Örneğin, HTTP sunucusunun barındırıldığı makinenin ismi mail.example.com olduğu halde makinenin bir de www.example.com diye bir de DNS rumuzu varsa ve HTTP sunucunuzun bu rumuzla kendini özdeşleştirmesini isterseniz bunu şöyle belirtebilirsiniz:

ServerName www.example.com

ServerName yönergesi sunucu tanımının içinde herhangi bir yerde görünebilirse de her göründüğü yerde bir öncekini iptal eder.

Bir ServerName ataması yapılmamışsa sunucu istemciye görünen sunucu ismini anlamak için önce işletim sistemine sistemin konak adını sorar. Bu başarılı olmazsa sistem üzerinde IP adresine bir ters DNS sorgusu yapar.

ServerName yönergesinde bir port belirtilmediği takdirde sunucu, isteğin geldiği portu kullanacaktır. Öngörülebilirlik ve güvenilirlik açısından en iyisi ServerName yönergesini kullanarak açıkça bir konak ismi ve port belirtmektir.

İsme dayalı sanal konaklar kullanıyorsanız, <VirtualHost> bölümü içindeki ServerName yönergesi, isteğin Host: başlığında bu sanal konakla eşleşecek konak ismini belirler.

Bazen sunucu, bir ters vekil, yük dengeleyici veya SSL yük aktarım uygulaması gibi bir aygıtın arkasında çalışır. Böyle durumlarda sunucunun kendine yönelik URL’leri doğru üretebildiğinden emin olmak için ServerName yönergesinde istemcinin bağlanacağı https:// şeması ve port numarası belirtilir.

Sunucunun kendine yönelik URL’lerin belirtilen portu içerip içermediğini veya istemcinin yaptığı istekte belirtilen port numarasının verilip verilmediğinin saptamasını sağlayan (örneğin, mod_dir modülü tarafından) ayarlar için UseCanonicalName ve UseCanonicalPhysicalPort yönergelerinin açıklamalarına bakınız.

ServerName yönergesine isim atamadaki bir başarısızlık, sunucu başlatılırken isim bir IP adresine çözümlenebileceğinden bir uyarı çıktılanmasına sebep olur. httpd böyle bir durumda sistemin hostname komutunu kullanarak saptadığı konak ismini kullanacaktır. Bu konak ismi hemen hemen daima sizin istediğiniz isim olmayacaktır.

httpd: Could not reliably determine the server's fully qualified domain name, using belgeler.yerel for ServerName

Çevirisi: Sunucunun tamamen nitelenmiş alan adı gerektiği gibi saptanamadı, ServerName için belgeler.yerel kullanılıyor

Ayrıca bakınız:

top

ServerPath Yönergesi

Açıklama:Uyumsuz bir tarayıcı tarafından erişilmesi için bir isme dayalı sanal konak için meşru URL yolu
Sözdizimi:ServerPath URL-yolu
Bağlam:sanal konak
Durum:Çekirdek
Modül:core

ServerPath yönergesi isme dayalı sanal konaklarda kullanmak için konağa meşru bir URL yolu belirler.

Ayrıca bakınız:

top

ServerRoot Yönergesi

Açıklama:Sunucu yapılandırması için kök dizin
Sözdizimi:ServerRoot dizin-yolu
Öntanımlı:ServerRoot /usr/local/apache
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core

ServerRoot yönergesi sunucu yapılandırmasını içeren dizinin yerini belirtir. Genellikle conf/ ve logs/ gibi alt dizinler içerir. Include, LoadModule gibi diğer yapılandırma yönergelerindeki göreli yollar bu dizine göre ele alınır.

ServerRoot "/home/httpd"

ServerRoot için öntanımlı yer configure betiğinin --prefix seçeneği ile değiştirilebilir ve sunucunun çoğu üçüncü parti dağıtıcısı öntanımlı yeri yukardakilerden farklı bir yere ayarlar.

Ayrıca bakınız:

top

ServerSignature Yönergesi

Açıklama:Sunucu tarafından üretilen belgelerin dipnotunu ayarlar.
Sözdizimi:ServerSignature On|Off|EMail
Öntanımlı:ServerSignature Off
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Çekirdek
Modül:core

ServerSignature yönergesi, sunucu tarafından üretilen belgelerin (hata iletileri, mod_proxy ftp dizin listeleri, mod_info çıktısı, vs.) altındaki dipnot satırını yapılandırabilmenizi sağlar. Böyle bir dipnot satırın istenmesinin sebebi vekil zincirlerinde istemciye dönen hata iletisinin aslında hangi sunucu tarafından üretildiğini kullanıcıya bildirmektir.

Off değeri öntanımlı değer olup dipnot satırının gösterilmemesini sağlar. On değeri, sunucu sürüm numarası ve hizmeti sunan sanal konağın isminden (ServerName) oluşan bir dipnot satırı oluşturulmasını sağlar; EMail değeri bu ikisine ek olarak satıra ServerAdmin ile belirtilen adres için bir "mailto:" bağı ekler.

Sunucu sürüm numarasının ayrıntıları ServerTokens yönergesi ile belirlenmektedir.

Ayrıca bakınız:

top

ServerTokens Yönergesi

Açıklama:Server HTTP yanıt başlığını yapılandırır.
Sözdizimi:ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
Öntanımlı:ServerTokens Full
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core

Bu yönerge Server HTTP yanıt başlığı alanında istemcilere sunucunun işletim sistemi, sunucuyla derlenmiş modüller, vs. hakkında bilgi verilip verilmeyeceğini belirler.

ServerTokens Full (veya belirtilmezse)
Sunucu şunu gönderir (örnek): Server: Apache/2.4.2 (Unix) PHP/4.2.2 MyMod/1.2
ServerTokens Prod[uctOnly]
Sunucu şunu gönderir (örnek): Server: Apache
ServerTokens Major
Sunucu şunu gönderir (örnek): Server: Apache/2
ServerTokens Minor
Sunucu şunu gönderir (örnek): Server: Apache/2.4
ServerTokens Min[imal]
Sunucu şunu gönderir (örnek): Server: Apache/2.4.2
ServerTokens OS
Sunucu şunu gönderir (örnek): Server: Apache/2.4.2 (Unix)

Bu ayarlama sunucunun tamamını etkiler ve her sanal konak için farklılaştırılamaz.

Bu yönerge ServerSignature yönergesi tarafından sunulan bilgiyi de etkilemektedir.

ServerTokens yönergesinde minimal'den azının belirtilmesi önerilmez. Bunun sebebi ara işlemlerle ilgili hata ayıklamasını zorlaştırmasıdır. Ayrıca, Server: başlığının iptal edilmesinin sunucunuzu daha güvenli yapmayacağına dikkat ediniz; "çapraşıklıkla sağlanan güvenlik" düşüncesi gerçekle bağdaşmaz ve güvenliği olumsuz etkiler.

Ayrıca bakınız:

top

SetHandler Yönergesi

Açıklama:Eşleşen tüm dosyaların belli bir eylemci tarafından işlenmesine sebep olur.
Sözdizimi:SetHandler eylemci-ismi|none|ifade
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core
Uyumluluk:ifade seçeneği 2.4.19 sürümünde eklendi

Bir .htaccess dosyasına veya bir <Directory> ya da <Location> bölümüne yerleştirildiğinde, eşleşen tüm dosyaların, ismi eylemci-ismi ile belirtilen eylemci tarafından çözümlenmesine sebep olur. Örneğin, bir dizin içindeki bütün dosyaların, uzantılarına bakılmaksızın birer imagemap kural dosyası olarak çözümlenmesini istersiniz, bu dizin içindeki bir .htaccess dosyasına şöyle bir satır koyabilirsiniz:

SetHandler imap-file

Başka bir örnek: http://localhost/status gibi bir istek yapıldığında sunucunun bir durum bilgisi göstermesi için httpd.conf dosyasına şöyle bir satır koyabilirsiniz:

<Location "/status">
  SetHandler server-status
</Location>

Bu yönergeyi ayrıca, belli bir dosya uzantısına sahip dosyalara uygun bir eylemci atamak için de kullanabilirsiniz. örnek:

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

Dizge değerli ifadeler istek öncesi değişkenleri içerecek şekilde düzenlenebilir. Buna ismli düzenli ifadelere yapılan geriye başvurular dahildir:

<LocationMatch ^/app/(?<sub>[^/]+)/>
     SetHandler "proxy:unix:/var/run/app_%{env:MATCH_sub}.sock|fcgi://localhost:8080"
</LocationMatch>

Evvelce tanımlanmış bir SetHandler yönergesini None değeriyle geçersiz hale getirebilirsiniz.

Bilgi

SetHandler yönergesi, öntanımlı eylemcileri geçersiz kıldığından, index dosyaları ve dizinleri belirtmek için URL’nin sonuna bölü çizgisi (/) getirmek şeklindeki normal davranış baskılanır.

Ayrıca bakınız:

top

SetInputFilter Yönergesi

Açıklama:POST girdilerini ve istemci isteklerini işleyecek süzgeçleri belirler.
Sözdizimi:SetInputFilter süzgeç[;süzgeç...]
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core

SetInputFilter yönergesi, istemci isteklerini ve sunucu tarafından alındığı takdirde POST girdisini işleyecek süzgeç veya süzgeçleri belirler. Bu, diğer AddInputFilter yönergeleri dahil evvelce tanımlanmış süzgeçlere eklenir.

Birden fazla süzgeç belirtilmek istenirse birbirlerinden noktalı virgüllerle ayrılmalı ve çıktıyı işleyecekleri sıraya uygun olarak sıralanmalıdırlar.

Ayrıca bakınız:

top

SetOutputFilter Yönergesi

Açıklama:Sunucunun yanıtlarını işleyecek süzgeçleri belirler.
Sözdizimi:SetOutputFilter süzgeç[;süzgeç...]
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Çekirdek
Modül:core

SetOutputFilter yönergesi, istemciye gönderilmeden önce sunucunun yanıtlarını işleyecek süzgeçleri belirler. Bu, diğer AddOutputFilter yönergeleri dahil evvelce tanımlanmış süzgeçlere eklenir.

Örneğin, aşağıdaki yapılandırma ile /www/data/ dizinindeki bütün dosyalar sunucu taraflı içerik kapsamında ele alınacaktır.

<Directory "/www/data/">
  SetOutputFilter INCLUDES
</Directory>

Birden fazla süzgeç belirtilmek istenirse birbirlerinden noktalı virgüllerle ayrılmalı ve çıktıyı işleyecekleri sıraya uygun olarak sıralanmalıdırlar.

Ayrıca bakınız:

top

StrictHostCheck Yönergesi

Açıklama:Sunucunun, istenen konak adının, isteği işleyen sanal konakta listelenmesini gerektirip gerektirmediğini denetler
Sözdizimi:StrictHostCheck ON|OFF
Öntanımlı:StrictHostCheck OFF
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core
Uyumluluk:2.4.49'da eklendi.

Öntanımlı olarak sunucu, beklenmeyen veya yapılandırılmamış konak adlarına yönelik istekler de dahil olmak üzere her konak adı isteğine yanıt verir. Bu uygun olsa da, genellikle kendine dönen yanıtlar üretileceğinden, arkada çalışan bir uygulamanın işlenen konak adlarını bazı durumlarda sınırlaması istenebilir.

StrictHostCheck yönergesine ON, atanarak, gelen bağlantıyla en iyi eşleşen sanal konaktaki ServerName veya ServerAlias yönergesinde istenen konak adı açıkça listelenmemişse, sunucunun HTTP 400 hatası döndürmesi sağlanabilir.

Bu yönerge ayrıca, istenen konak adının, ek ServerAlias girdileri gibi davranan ve nispeten belirsiz bir yapılandırma mekanizması olan, VirtualHost açılış etiketinde belirtilen konak adlarıyla eşleşmesini de sağlar.

Bu yönergenin öntanımlı olmayan sanal konaklarda hiçbir etkisi yoktur. Etkin değeri, genel sunucu yapılandırmasından devralınan değer veya ilgili bağlantının ip:port'u için öntanımlı olan sanal konak belirler.

top

TimeOut Yönergesi

Açıklama:Bir istek için başarısız olmadan önce belirli olayların gerçekleşmesi için sunucunun geçmesini bekleyeceği süre.
Sözdizimi:TimeOut saniye
Öntanımlı:TimeOut 60
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

TimeOut yönergesi Apache httpd’nin aşağıdaki durumlarda G/Ç için bekleyeceği süreyi belirler:

top

TraceEnable Yönergesi

Açıklama:TRACE isteklerinde davranış şeklini belirler
Sözdizimi:TraceEnable [on|off|extended]
Öntanımlı:TraceEnable on
Bağlam:sunucu geneli, sanal konak
Durum:Çekirdek
Modül:core

Bu yönerge çekirdek ve vekil (mod_proxy) sunucuların her ikisi için öntanımlı TRACE davranışını değiştirir. Öntanımlı olan TraceEnable on ile RFC 2616’dan kaynaklanan ve isteğe herhangi bir istek gövdesinin eşlik etmesine izin vermeyen TRACE isteklerine izin verilir. TraceEnable off ile çekirdek ve vekil (mod_proxy) sunucuların her ikisi de TRACE isteklerine yanıt olarak bir 405 (Yönteme izin verilmiyor) hatası döndürür.

TraceEnable extended ile sadece sınama ve tanı koyma amaçlarına yönelik olarak istek gövdelerine izin verilir. Asıl sunucu istek gövdesini 64kB ile sınırlar (Transfer-Encoding: chunked kullanılmışsa bölüm başlıkları için 8kB daha). Asıl sunucu yanıt gövdesinde tüm başlıkları ve bölüm başlıklarının tamamını yansıtacaktır. Vekil sunucuda ise istek gövdesi için 64kB’lık sınır yoktur.

Bilgi

Aksine iddialara rağmen, TRACE yöntemini etkinleştirmek Apache httpd'de bir güvenlik açığı değildir. TRACE yöntemi HTTP/1.1 belirtiminde tanımlanmış olup desteklenmesi umulmuştur.

top

UNCList Yönergesi

Açıklama:Controls what UNC host names can be accessed by the server
Sözdizimi:UNCList hostname [hostname...]
Öntanımlı:unset
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core
Uyumluluk:Added in 2.4.60, Windows only.

Bu yönergenin belgesi henüz Türkçeye çevrilmedi. Lütfen İngilizce sürümüne bakınız.

top

UnDefine Yönergesi

Açıklama:Bir değişkeni tanımsız yapar
Sözdizimi:UnDefine değişken-ismi
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core

Define yönergesinde veya httpd'nin -D seçeneğiyle belirtileni geri alır.

RewriteMap yönergesinin sözdizimi ile çatışmalardan kaçınmak için değişken isimleri iki nokta üst üste ":" karakterlerini içerebilir.

Virtual Host scope and pitfalls

Bu yönerge başlatma betiklerinde -D seçeneğinin argümanını değiştirmek gerekmeksizin <IfDefine> bölümlerinin kullanımını değiştirmek için kullanılabilir.

Ayrıca bakınız:

top

UseCanonicalName Yönergesi

Açıklama:Sunucunun kendi adını ve portunu nasıl belirleyeceğini ayarlar
Sözdizimi:UseCanonicalName On|Off|DNS
Öntanımlı:UseCanonicalName Off
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core

Apache httpd‘nin çoğu durumda özüne yönelik URL‘ler (isteğin tekrar aynı sunucuya yapıldığı bir URL türü) oluşturması gerekir. UseCanonicalName On ile Apache httpd, sunucu için meşru ismi ve portu oluşturmak için ServerName yönergesinde belirtilen ismi ve portu kullanır. Bu isim CGI'lerde SERVER_NAME ve SERVER_PORT değerlerinde ve tüm özüne yönelik URL’lerde kullanılır.

UseCanonicalName Off ile Apache httpd, özüne yönelik URL’leri varsa istemci tarafından sağlanan konak ismini ve portu kullanarak oluşturur; bunlar istemci tarafından sağlanmamışsa yukarıda tanımlanan işleme başvurulur. Bu değerler, isme dayalı sanal konakları gerçekleştirirken kullanılan değerlerle aynı olup aynı istemcilerle kullanılabilir. SERVER_NAME ve SERVER_PORT CGI değişkenleri de istemci tarafından sağlanan isim ve portla oluşturulur.

Bir örnek olarak, iç ağdaki istemcilerin sunucuya www gibi bir kısa isim kullanarak bağlandığı durumu ele alırsak daha yararlı olur. Kullanıcılar bir kısa isim ve bir dizin isminden oluşan ve bir / ile sonlandırılmamış http://www/splat şeklinde bir istek yaparlarsa, Apache httpd onları http://www.example.com/splat/ adresine yönlendirecektir. Eğer kimlik doğrulama da etkinse bu kullanıcının iki defa kimlik doğrulamasına sokulmasına sebep olacaktır (bir kere www için bir kere de www.example.com için; daha fazla bilgi için SSS’ye bakınız). Fakat UseCanonicalName Off olsaydı Apache httpd isteği http://www/splat/ adresine yönlendirecekti.

UseCanonicalName DNS diye üçüncü bir seçenek daha vardır ve istek yaparken Host: başlığını kullanmayan eski istemcileri desteklemek amacıyla IP’ye dayalı sanal konaklarla kullanmak için tasarlanmıştır. Bu seçenek etkin olduğunda Apache httpd, istemciyi özüne yönelik URL’lerle doğru yere bağlamak için sunucu IP adresi üzerinde bir ters DNS sorgusu yapar.

Uyarı

Eğer CGI’ler SERVER_NAME değerleri için önkabuller yapıyorlarsa bu seçenek işlerinin bozulmasına yol açabilir. Aslında istemciler konak ismi olarak istedikleri değeri vermekte özgürdürler. Fakat eğer CGI, özüne yönelik URL’leri oluştururken sadece SERVER_NAME değerini kullanıyorsa bu istendiği gibi çalışacaktır.

Ayrıca bakınız:

top

UseCanonicalPhysicalPort Yönergesi

Açıklama:Sunucunun kendi adını ve portunu nasıl belirleyeceğini ayarlar
Sözdizimi:UseCanonicalPhysicalPort On|Off
Öntanımlı:UseCanonicalPhysicalPort Off
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Çekirdek
Modül:core

Apache httpd‘nin çoğu durumda özüne yönelik URL‘ler (isteğin tekrar aynı sunucuya yapıldığı bir URL türü) oluşturması gerekir. Apache httpd UseCanonicalName yönergesine bağlı olarak sunucu için meşru portu oluştururken UseCanonicalPhysicalPort On ile olası port olarak istek tarafından kullanılmakta olan fiziksel portu kullanacaktır. UseCanonicalPhysicalPort Off olduğunda ise geçerli bir port numarası oluşturmak için asıl fiziksel port yerine yapılandırma bilgisi kullanılır.

Ek Bilgi

Fiziksel port kullanımı etkin olduğunda işlemler şu sırayla yürütülür:

UseCanonicalName On
  1. Servername ile sağlanan port
  2. Fiziksel port
  3. Öntanımlı port
UseCanonicalName Off | DNS
  1. Host: başlığından çözümlenen port
  2. Fiziksel port
  3. Servername yönergesinde belirtilen port
  4. Öntanımlı port

UseCanonicalPhysicalPort Off olduğunda işlem sırasında fiziksel port adımları atlanır.

Ayrıca bakınız:

top

<VirtualHost> Yönergesi

Açıklama:Sadece belli bir konak ismine ve porta uygulanacak yönergeleri barındırır.
Sözdizimi:<VirtualHost adres[:port] [adres[:port]] ...> ... </VirtualHost>
Bağlam:sunucu geneli
Durum:Çekirdek
Modül:core

<VirtualHost> ve </VirtualHost> birlikte sadece belli bir sanal konağa uygulanacak yönergeleri sarmalamakta kullanılırlar. Bir sanal konak kapsamında belirtilebilecek her yönerge kullanılabilir. Sunucu belli bir sanal konak üzerindeki bir belge için bir istek aldığında <VirtualHost> bölümünde bulunan yapılandırma yönergelerini kullanır. adres şunlardan biri olabilir, istemlik olarak ikinokta imi ve bir port numarası (veya *) eklenebilir:

<VirtualHost 10.1.2.3:80>
  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>

İsteğe bağlı port numarasını belirtmeyi mümkün kılmak için IPv6 adresleri köşeli ayraç içine alınır. IPv6 adresi kullanılan bir örnek:

<VirtualHost [2001:db8::a00:20ff:fea7:ccea]:80>
  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>

Her sanal konağın ya farklı bir IP adresi ve port ile ya da farklı bir konak ismiyle eşleşmesi gerekir. Birinci durumda sunucu makinesinin çok sayıda adresten IP paketleri kabul edecek şekilde yapılandırılması gerekir. (Eğer makinede çok sayıda ağ arabirimi yoksa bu, işletim sistemi desteklediği takdirde ifconfig alias komutuyla sağlanabilir.)

Ek Bilgi

<VirtualHost> kullanımı Apache httpd’nin dinleyeceği adresler üzerinde belirleyici değildir. Apache httpd’nin doğru adresi dinlediğinden emin olmak için Listen kullanmanız gerekebilir.

Her <VirtualHost> bloku içinde bir ServerName yönergesi mutlaka olmalıdır. Yokluğu halinde "ana" sunucu yapılandırmasındaki ServerName miras alınacaktır.

Bir istek alındığında, sunucu isteği, sadece yerel IP adresi ve port çiftine dayalı en iyi eşleşen ilk <VirtualHost> bölümüne eşler. Joker kullanmayanlar daha yüksek önceliğe sahiptir. IP ve port çiftine dayalı bir eşleşme bulunamazsa istek için ana sunucu yapılandırması kullanılır.

En iyi eşleşen IP adresi ve port çiftini birden fazla sanal konak kullanıyorsa sunucu bu sanal konaklar (liste) arasından istenen konak ismiyle en iyi eşleşeni seçer. Eşleşen hiçbir isme dayalı sanal konak yoksa listedeki IP adresi ile eşleşen ilk sanal konak kullanılır. Bunun sonucu olarak, belirtilen IP adresi ve port çifti için listedeki ilk sanal konak, bu IP adresi ve port çifti için öntanımlı sanal konaktır.

Güvenlik

Günlük dosyalarının sunucuyu çalıştıran kullanıcıdan başka herkes tarafından yazılabilen bir yerde saklanmasından dolayı ortaya çıkabilecek güvenlik sorunları hakkında daha ayrıntılı bilgi için güvenlik ipuçları belgesine bakınız.

Ayrıca bakınız:

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/core.html.fr.utf80000664000175100017510000121646315032765673020752 0ustar covenercovener core - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Fonctionalités de Base Apache

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  tr 

Cette traduction peut être périmée. Vérifiez la version anglaise pour les changements récents.
Description:Fonctionnalités de base du serveur HTTP Apache toujours disponibles
Statut:Noyau httpd
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive AcceptFilter

Description:Permet d'optimiser la configuration d'une socket pour l'écoute d'un protocole
Syntaxe:AcceptFilter protocole filtre d'acceptation
Contexte:configuration globale
Statut:Noyau httpd
Module:core

Cette directive permet d'effectuer une optimisation de la socket d'écoute d'un type de protocole en fonction du système d'exploitation. Le but premier est de faire en sorte que le noyau n'envoie pas de socket au processus du serveur jusqu'à ce que des données soient reçues, ou qu'une requête HTTP complète soit mise en tampon. Seuls les Filtres d'acceptation de FreeBSD, le filtre plus primitif TCP_DEFER_ACCEPT sous Linux, et la version optimisée d'AcceptEx() de Windows sont actuellement supportés.

L'utilisation de l'argument none va désactiver tout filtre d'acceptation pour ce protocole. Ceci s'avère utile pour les protocoles qui nécessitent l'envoi de données par le serveur en premier, comme ftp: ou nntp:

AcceptFilter nntp none

Les noms de protocoles par défaut sont https pour le port 443 et http pour tous les autres ports. Pour spécifier un autre protocole à utiliser avec un port en écoute, ajoutez l'argument protocol à la directive Listen.

Sous FreeBSD, les valeurs par défaut sont :

AcceptFilter http httpready
AcceptFilter https dataready

Le filtre d'acceptation httpready met en tampon des requêtes HTTP entières au niveau du noyau. Quand une requête entière a été reçue, le noyau l'envoie au serveur. Voir la page de manuel de accf_http(9) pour plus de détails. Comme les requêtes HTTPS sont chiffrées, celles-ci n'autorisent que le filtre accf_data(9).

Sous Linux, les valeurs par défaut sont :

AcceptFilter http data
AcceptFilter https data

Le filtre TCP_DEFER_ACCEPT de Linux ne supporte pas la mise en tampon des requêtes http. Toute valeur autre que none active le filtre TCP_DEFER_ACCEPT pour ce protocole. Pour plus de détails, voir la page de manuel Linux de tcp(7).

Sous Windows, les valeurs par défaut sont :

AcceptFilter http connect
AcceptFilter https connect

Le module MPM pour Windows mpm_winnt utilise la directive AcceptFilter comme commutateur de l'API AcceptEx(), et ne supporte pas la mise en tampon du protocole http. connect utilise l'API AcceptEx(), extrait aussi les adresses réseau finales, mais à l'instar de none, la valeur connect n'attend pas la transmission des données initiales.

Sous Windows, none utilise accept() au lieu d'AcceptEx(), et ne recycle pas les sockets entre les connexions. Ceci s'avère utile pour les interfaces réseau dont le pilote est défectueux, ainsi que pour certains fournisseurs de réseau comme les pilotes vpn, ou les filtres anti-spam, anti-virus ou anti-spyware.

L'AcceptFilter data (Windows)

Jusqu'à la version 2.4.23, le filtre d'acceptation data attendait que des données aient été transmises et que le tampon de données initial et l'adresse réseau finale aient été déterminés par l'invocation AcceptEx(). Cette implémentation étant vulnérable à une attaque de type denial of service, elle a été désactivée.

La version actuelle de httpd prend par défaut le filtre connect sous Windows, et reprendra la valeur data si data est spécifié. Il est fortement conseillé aux utilisateurs des versions plus anciennes de définir explicitement le filtre connect pour leurs AcceptFilter comme indiqué plus haut.

Voir aussi

top

Directive AcceptPathInfo

Description:Les ressources acceptent des informations sous forme d'un nom de chemin en fin de requête.
Syntaxe:AcceptPathInfo On|Off|Default
Défaut:AcceptPathInfo Default
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core

Cette directive permet de définir si les requêtes contenant des informations sous forme d'un nom de chemin suivant le nom d'un fichier réel (ou un fichier qui n'existe pas dans un répertoire qui existe) doivent être acceptées ou rejetées. Les scripts peuvent accéder à cette information via la variable d'environnement PATH_INFO.

Supposons par exemple que /test/ pointe vers un répertoire qui ne contient que le fichier here.html. Les requêtes pour /test/here.html/more et /test/nothere.html/more vont affecter la valeur /more à la variable d'environnement PATH_INFO.

L'argument de la directive AcceptPathInfo possède trois valeurs possibles :

Off
Une requête ne sera acceptée que si elle correspond à un chemin qui existe. Par conséquent, une requête contenant une information de chemin après le nom de fichier réel comme /test/here.html/more dans l'exemple ci-dessus renverra une erreur "404 NOT FOUND".
On
Une requête sera acceptée si la partie principale du chemin correspond à un fichier existant. Dans l'exemple ci-dessus /test/here.html/more, la requête sera acceptée si /test/here.html correspond à un nom de fichier valide.
Default
Le traitement des requêtes est déterminé par le gestionnaire responsable de la requête. Le gestionnaire de base pour les fichiers normaux rejette par défaut les requêtes avec PATH_INFO. Les gestionnaires qui servent des scripts, commecgi-script et isapi-handler, acceptent en général par défaut les requêtes avec PATH_INFO.

Le but premier de la directive AcceptPathInfo est de vous permettre de remplacer le choix du gestionnaire d'accepter ou de rejeter PATH_INFO. Ce remplacement est nécessaire par exemple, lorsque vous utilisez un filtre, comme INCLUDES, pour générer un contenu basé sur PATH_INFO. Le gestionnaire de base va en général rejeter la requête, et vous pouvez utiliser la configuration suivante pour utiliser un tel script :

<Files "mypaths.shtml">
  Options +Includes
  SetOutputFilter INCLUDES
  AcceptPathInfo On
</Files>
top

Directive AccessFileName

Description:Nom du fichier de configuration distribué
Syntaxe:AccessFileName nom-du-fichier [nom-du-fichier] ...
Défaut:AccessFileName .htaccess
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Au cours du traitement d'une requête, le serveur recherche le premier fichier de configuration existant à partir de la liste de noms dans chaque répertoire composant le chemin du document, à partir du moment où les fichiers de configuration distribués sont activés pour ce répertoire. Par exemple :

AccessFileName .acl

avant de renvoyer le document /usr/local/web/index.html, le serveur va rechercher les fichiers /.acl, /usr/.acl, /usr/local/.acl et /usr/local/web/.acl pour y lire d'éventuelles directives, à moins quelles n'aient été désactivées avec

<Directory "/">
    AllowOverride None
</Directory>

Voir aussi

top

Directive AddDefaultCharset

Description:Paramètre jeu de caractères par défaut à ajouter quand le type de contenu d'une réponse est text/plain ou text/html
Syntaxe:AddDefaultCharset On|Off|jeu de caractères
Défaut:AddDefaultCharset Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core

Cette directive spécifie une valeur par défaut pour le paramètre jeu de caractères du type de média (le nom d'un codage de caractères) à ajouter à une réponse, si et seulement si le type de contenu de la réponse est soit text/plain, soit text/html. Ceci va remplacer tout jeu de caractères spécifié dans le corps de la réponse via un élément META, bien que cet effet dépende en fait souvent de la configuration du client de l'utilisateur. La définition de AddDefaultCharset Off désactive cette fonctionnalité. AddDefaultCharset On ajoute un jeu de caractères par défaut de iso-8859-1. Toute autre valeur peut être définie via le paramètre jeu de caractères, qui doit appartenir à la liste des valeurs de jeux de caractères enregistrés par l'IANA à utiliser dans les types de média Internet (types MIME). Par exemple :

AddDefaultCharset utf-8

La directive AddDefaultCharset ne doit être utilisée que lorsque toutes les ressources textes auxquelles elle s'applique possèdent le jeu de caractère spécifié, et qu'il est trop contraignant de définir leur jeu de caractères individuellement. Un exemple de ce type est l'ajout du paramètre jeu de caractères aux ressources comportant un contenu généré, comme les scripts CGI hérités qui peuvent être vulnérables à des attaques de type cross-site scripting à cause des données utilisateurs incluses dans leur sortie. Notez cependant qu'une meilleur solution consiste à corriger (ou supprimer) ces scripts, car la définition d'un jeu de caractères par défaut ne protège pas les utilisateurs qui ont activé la fonctionnalité "Détection automatique de l'encodage des caractères" dans leur navigateur.

Voir aussi

top

Directive AllowEncodedSlashes

Description:Détermine si les séparateurs de chemin encodés sont autorisés à transiter dans les URLs tels quels
Syntaxe:AllowEncodedSlashes On|Off|NoDecode
Défaut:AllowEncodedSlashes Off
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:L'option NoDecode est disponible depuis la version 2.3.12.

La directive AllowEncodedSlashes permet l'utilisation des URLs contenant des séparateurs de chemin encodés dans la partie chemin (%2F pour / et même %5C pour \ sur les systèmes concernés).

Avec la valeur par défaut, Off, de telles URLs sont refusées et provoquent le renvoi d'une erreur 404 (Not found).

Avec la valeur On, ces URLs sont acceptées, et les slashes encodés sont décodés comme tout autre caractère codé.

Avec la valeur NoDecode, ces URLs sont acceptées, mais les slashes codés ne sont pas décodés et laissés dans leur état codé.

Définir AllowEncodedSlashes à On est surtout utile en association avec PATH_INFO.

Note

Si le codage des slashes dans la partie chemin est nécessaire, l'utilisation de l'option NoDecode est fortement recommandée par mesure de sécurité. Permettre le décodage des slashes pourrait éventuellement induire l'autorisation de chemins non sûrs.

Voir aussi

top

Directive AllowOverride

Description:Types de directives autorisées dans les fichiers .htaccess
Syntaxe:AllowOverride All|None|type directive [type directive] ...
Défaut:AllowOverride None à partir de la version 2.3.9, AllowOverride All pour les versions antérieures
Contexte:répertoire
Statut:Noyau httpd
Module:core

Lorsque le serveur trouve un fichier .htaccess (dont le nom est défini par la directive AccessFileName), il doit savoir lesquelles des directives placées dans ce fichier sont autorisées à modifier la configuration préexistante.

Valable seulement dans les sections <Directory>

La directive AllowOverride ne peut être utilisée que dans les sections <Directory> définies sans expressions rationnelles, et non dans les sections <Location>, <DirectoryMatch> ou <Files>.

Lorsque cette directive et la directive AllowOverrideList sont définies à None, les fichiers .htaccess sont totalement ignorés. Dans ce cas, le serveur n'essaiera même pas de lire les fichiers .htaccess du système de fichiers.

Lorsque cette directive est définie à All, toute directive valable dans le Contexte .htaccess sera autorisée dans les fichiers .htaccess.

L'argument type directive peut contenir les groupements de directives suivants (voir ce document pour obtenir la liste à jour des directives activées pour chaque type de directive) :

AuthConfig
Permet l'utilisation des directives d'autorisation (AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, etc...).
FileInfo
Permet l'utilisation des directives qui contrôlent les types de documents (directives ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, et directives du module mod_mime Add* et Remove*), des metadonnées des documents (Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName), des directives du module mod_rewrite directives (RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule), des directives du module mod_alias directives (Redirect, RedirectTemp, RedirectPermanent, RedirectMatch), et de la directive Action du module mod_actions.
Indexes
Permet l'utilisation des directives qui contrôlent l'indexation des répertoires (AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, etc...).
Limit
Permet l'utilisation des directives contrôlant l'accès au serveur (Allow, Deny et Order).
Nonfatal=[Override|Unknown|All]
Permet d'utiliser l'option AllowOverride pour rendre les erreurs de syntaxe non fatales dans les fichiers .htaccess : au lieu de causer une Internal Server Error, les directives non autorisées ou non reconnues seront ignorées et un avertissement enregistré dans le journal :
  • Nonfatal=Override rend les directives interdite par AllowOverride non fatales.
  • Nonfatal=Unknown rend les directives inconnues non fatales. Sont concernées les erreurs de frappe et les directives implémentées par un module non chargé.
  • Nonfatal=All rend toutes les directives précédentes non fatales.

Notez qu'une erreur de syntaxe dans une directive valide causera toujours une internal server error.

Sécurité

Les erreurs non fatales peuvent être à l'origine de problèmes de sécurité pour les utilisateurs de fichiers .htaccess. Par exemple, si AllowOverride interdit AuthConfig, toute configuration utilisateur destinée à restreindre l'accès à un site ne sera pas prise en compte.
Options[=Option,...]
Permet l'utilisation des directives contrôlant les fonctionnalités spécifiques d'un répertoire (Options et XBitHack). "Options" doit être suivi d'un signe "égal", puis d'une liste d'options séparées par des virgules (pas d'espaces) ; ces options doivent être définies à l'aide de la commande Options.

Désactivation implicite des options

Bien que la liste des options disponibles dans les fichiers .htaccess puisse être limitée par cette directive, tant qu'un directive Options est autorisée, toute autre option héritée peut être désactivée en utilisant la syntaxe non-relative. En d'autres termes, ce mécanisme ne peut pas forcer une option spécifique à rester activée tout en permettant à toute autre option d'être activée.

AllowOverride Options=Indexes,MultiViews

Exemple :

AllowOverride AuthConfig Indexes

Dans l'exemple ci-dessus, toutes les directives qui ne font partie ni du groupe AuthConfig, ni du groupe Indexes, provoquent une erreur "internal server error".

Pour des raisons de sécurité et de performance, ne définissez pas AllowOverride à autre chose que None dans votre bloc <Directory "/">. Recherchez plutôt (ou créez) le bloc <Directory> qui se réfère au répertoire où vous allez précisément placer un fichier .htaccess.

Voir aussi

top

Directive AllowOverrideList

Description:Directives autorisées dans les fichiers .htaccess
Syntaxe:AllowOverrideList None|directive [directive-type] ...
Défaut:AllowOverrideList None
Contexte:répertoire
Statut:Noyau httpd
Module:core

Lorsque le serveur trouve un fichier .htaccess (comme spécifié par la directive AccessFileName), il doit savoir lesquelles des directives déclarées dans ce fichier peuvent remplacer des directives des fichiers de configuration du serveur.

Seulement disponible dans les sections <Directory>

La directive AllowOverrideList n'est disponible que dans les sections <Directory> spécifiées sans expressions rationnelles.

Lorsque cette directive et la directive AllowOverride sont définies à None, les fichiers .htaccess sont totalement ignorés. Dans ce cas, le serveur ne cherchera même pas à lire des fichiers .htaccess dans le système de fichiers.

Example:

AllowOverride None
AllowOverrideList Redirect RedirectMatch

Dans l'exemple ci-dessus, seules les directives Redirect et RedirectMatch sont autorisées. Toutes les autres provoqueront une erreur interne du serveur.

Example:

AllowOverride AuthConfig
AllowOverrideList CookieTracking CookieName

Dans l'exemple ci-dessus, la directive AllowOverride autorise les directives du groupement AuthConfig, et AllowOverrideList n'autorise que deux directives du groupement FileInfo. Toutes les autres provoqueront une erreur interne du serveur.

Voir aussi

top

Directive CGIMapExtension

Description:Technique permettant de localiser l'interpréteur des scripts CGI
Syntaxe:CGIMapExtension chemin CGI .extension
Contexte:répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:NetWare uniquement

Cette directive permet de contrôler la manière dont Apache httpd trouve l'interpréteur servant à exécuter les scripts CGI. Par exemple, avec la définition CGIMapExtension sys:\foo.nlm .foo, tous les fichiers scripts CGI possédant une extension .foo seront passés à l'interpréteur FOO.

top

Directive CGIPassAuth

Description:Active la transmission d'en-têtes d'autorisation HTTP aux scripts en tant que variables CGI
Syntaxe:CGIPassAuth On|Off
Défaut:CGIPassAuth Off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.13 du serveur HTTP Apache

La directive CGIPassAuth permet aux scripts d'accéder aux en-têtes d'autorisation HTTP tels que Authorization, en-tête nécessaire aux scripts qui implémente une authentification HTTP de base. Normalement, ces en-têtes HTTP sont invisibles pour les scripts car ils leurs permettraient de voir les identifiants et mots de passe utilisés pour accéder au serveur lorsque l'authentification HTTP de base est activée au niveau du serveur web. Cette directive doit être définie à "On" lorsque des scripts sont autorisés à implémenter une authentification HTTP de base.

Cette directive constitue une alternative à l'option de compilation SECURITY_HOLE_PASS_AUTHORIZATION qui était déjà disponible dans les versions précédentes du serveur HTTP Apache.

Cette option est prise en compte par tout module qui utilise ap_add_common_vars(), comme mod_cgi, mod_cgid, mod_proxy_fcgi, mod_proxy_scgi, etc... En particulier, elle affecte les modules qui ne traitent pas à proprement parler les requêtes, mais utilisent quand-même cette API, comme mod_include ou mod_ext_filter. Les modules tiers qui n'utilisent pas ap_add_common_vars() peuvent aussi choisir de prendre en compte cette option.

top

Directive CGIVar

Description:Contrôle la manière dont certaines variables CGI sont définies
Syntaxe:CGIVar variable rule
Contexte:répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.21 du serveur HTTP Apache

Cette directive permet de contrôler la manière dont certaines variables CGI sont définies.

règles REQUEST_URI :

original-uri (valeur par défaut)
La valeur est extraite de la requête originale, et ne tient pas compte des redirections internes ou des sous-requêtes qui pourraient modifier la ressource demandée.
current-uri
La valeur reflète la ressource en cours de traitement ; elle peut être différente de la ressource demandée dans la requête initiale du client suite à d'éventuelles redirections internes ou sous-requêtes.
top

Directive ContentDigest

Description:Active la génération d'un en-tête Content-MD5 dans la réponse HTTP
Syntaxe:ContentDigest On|Off
Défaut:ContentDigest Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Noyau httpd
Module:core

Cette directive active la génération d'un en-tête Content-MD5 selon les définitions des RFC 1864 et 2616.

MD5 est un algorithme permettant de générer un condensé (parfois appelé "empreinte") à partir de données d'une taille aléatoire ; le degré de précision est tel que la moindre altération des données d'origine entraîne une altération de l'empreinte.

L'en-tête Content-MD5 permet de vérifier l'intégrité de la réponse HTTP dans son ensemble. Un serveur mandataire ou un client peut utiliser cet en-tête pour rechercher une éventuelle modification accidentelle de la réponse au cours de sa transmission. Exemple d'en-tête :

Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA==

Notez que des problèmes de performances peuvent affecter votre serveur, car l'empreinte est générée pour chaque requête (il n'y a pas de mise en cache).

L'en-tête Content-MD5 n'est envoyé qu'avec les documents servis par le module core, à l'exclusion de tout autre module. Ainsi, les documents SSI, les sorties de scripts CGI, et les réponses à des requêtes partielles (byte range) ne comportent pas cet en-tête.

top

Directive DefaultRuntimeDir

Description:Répertoire de base des fichiers créés au cours de l'exécution du serveur
Syntaxe:DefaultRuntimeDir chemin-répertoire
Défaut:DefaultRuntimeDir DEFAULT_REL_RUNTIMEDIR (logs/)
Contexte:configuration globale
Statut:Noyau httpd
Module:core
Compatibilité:Disponible depuis la version 2.4.2 du serveur HTTP Apache

La directive DefaultRuntimeDir permet de définir le répertoire dans lequel le serveur va créer les différents fichiers relatifs à son exécution (mémoire partagée, verrous, etc...). Si le chemin spécifié est relatif, le chemin absolu sera généré relativement à la valeur de la directive ServerRoot

Example

DefaultRuntimeDir scratch/

La valeur par défaut de la directive DefaultRuntimeDir peut être modifiée en changeant la valeur de la macro DEFAULT_REL_RUNTIMEDIR définie à la compilation.

Note: si la valeur de ServerRoot n'a pas été spécifiée avant d'utiliser cette directive, c'est la valeur par défaut de ServerRoot qui sera utilisée pour définir la base du répertoire.

Voir aussi

top

Directive DefaultType

Description:Les seuls effets de cette directive sont des émissions d'avertissements si sa valeur est différente de none. Dans les versions précédentes, DefaultType permettait de spécifier un type de média à assigner par défaut au contenu d'une réponse pour lequel aucun autre type de média n'avait été trouvé.
Syntaxe:DefaultType type média|none
Défaut:DefaultType none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:L'argument none est disponible dans les versions d'Apache httpd 2.2.7 et supérieures. Tous les autres choix sont DESACTIVÉS à partir des version 2.3.x.

Cette directive a été désactivée. Pour la compatibilité ascendante avec les anciens fichiers de configuration, elle peut être spécifiée avec la valeur none, c'est à dire sans type de médium par défaut. Par exemple :

DefaultType None

DefaultType None n'est disponible que dans les versions d'Apache 2.2.7 et supérieures.

Utilisez le fichier de configuration mime.types et la directive AddType pour configurer l'assignement d'un type de médium via les extensions de fichiers, ou la directive ForceType pour attribuer un type de médium à des ressources spécifiques. Dans le cas contraire, le serveur enverra sa réponse sans champ d'en-tête Content-Type, et le destinataire devra déterminer lui-même le type de médium.

top

Directive Define

Description:Permet de définir une variable
Syntaxe:Define nom-paramètre [valeur-paramètre]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core

Avec un seul paramètre, l'effet de la directive Define est identique à celui de l'argument -D du programme httpd. Il permet de modifier le comportement des sections <IfDefine> sans avoir à ajouter d'argument -D au sein des scripts de démarrage.

De plus, le second paramètre permet d'affecter une valeur à la variable définie par le premier. Cette variable peut être référencée dans le fichier de configuration via la syntaxe ${VAR}. La portée de la variable est toujours globale, et n'est jamais limitée à la section de configuration courante.

<IfDefine TEST>
  Define servername test.example.com
</IfDefine>
<IfDefine !TEST>
  Define servername www.example.com
  Define SSL
</IfDefine>

DocumentRoot "/var/www/${servername}/htdocs"

Le caractère ":" est interdit dans les noms de variables afin d'éviter les conflits avec la syntaxe de la directive RewriteMap.

Portée de la directive et pièges à éviter

Si cette directive est définie au sein d'un bloc VirtualHost, les changements qu'elle induit sont visibles de toute directive ultérieure, au delà de tout bloc VirtualHost.

Voir aussi

top

Directive <Directory>

Description:Regroupe un ensemble de directives qui ne s'appliquent qu'au répertoire concerné du système de fichiers, à ses sous-répertoires, et à leur contenu.
Syntaxe:<Directory chemin répertoire> ... </Directory>
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Les balises <Directory> et </Directory> permettent de regrouper un ensemble de directives qui ne s'appliquent qu'au répertoire précisé, à ses sous-répertoires, et aux fichiers situés dans ces sous-répertoires. Toute directive autorisée dans un contexte de répertoire peut être utilisée. chemin répertoire est soit le chemin absolu d'un répertoire, soit une chaîne de caractères avec caractères génériques utilisant la comparaison Unix de style shell. Dans une chaîne de caractères avec caractères génériques, ? correspond à un caractère quelconque, et * à toute chaîne de caractères. Les intervalles de caractères [] sont aussi autorisés. Aucun caractère générique ne peut remplacer le caractère `/', si bien que l'expression <Directory "/*/public_html"> ne conviendra pas pour le chemin * /home/user/public_html, alors que <Directory "/home/*/public_html"> conviendra. Exemple :

<Directory "/usr/local/httpd/htdocs">
  Options Indexes FollowSymLinks
</Directory>

Les chemins de répertoires contenant des espaces doivent être entourés de guillemets afin d'empêcher l'interprétation de ces espaces comme fins d'arguments.

Soyez prudent avec l'argument chemin répertoire : il doit correspondre exactement au chemin du système de fichier qu'Apache httpd utilise pour accéder aux fichiers. Les directives comprises dans une section <Directory> ne s'appliqueront pas aux fichiers du même répertoire auxquels on aura accédé via un chemin différent, per exemple via un lien symbolique.

Les Expressions rationnelles peuvent aussi être utilisées en ajoutant le caractère ~. Par exemple :

<Directory ~ "^/www/[0-9]{3}">

</Directory>

pourra correspondre à tout répertoire situé dans /www/ et dont le nom se compose de trois chiffres.

Si plusieurs sections <Directory> (sans expression rationnelle) correspondent au répertoire (ou à un de ses parents) qui contient le document, les directives de la section <Directory> dont le chemin est le plus court sont appliquées en premier, en s'intercalant avec les directives des fichiers .htaccess. Par exemple, avec

<Directory "/">
  AllowOverride None
</Directory>

<Directory "/home">
  AllowOverride FileInfo
</Directory>

l'accès au document /home/web/dir/doc.html emprunte le chemin suivant :

Les directives associées aux répertoires sous forme d'expressions rationnelles ne sont prises en compte qu'une fois toutes les directives des sections sans expressions rationnelles appliquées. Alors, tous les répertoires avec expressions rationnelles sont testés selon l'ordre dans lequel ils apparaissent dans le fichier de configuration. Par exemple, avec

<Directory ~ "abc$">
  # ... directives ici ...
</Directory>

la section avec expression rationnelle ne sera prise en compte qu'après les sections <Directory> sans expression rationnelle et les fichiers .htaccess. Alors, l'expression rationnelle conviendra pour /home/abc/public_html/abc et la section <Directory> correspondante s'appliquera.

Notez que la politique d'accès par défaut dans les sections <Directory "/"> consiste à autoriser tout accès sans restriction. Ceci signifie qu'Apache httpd va servir tout fichier correspondant à une URL. Il est recommandé de modifier cette situation à l'aide d'un bloc du style

<Directory "/">
  Require all denied
</Directory>

puis d'affiner la configuration pour les répertoires que vous voulez rendre accessibles. Voir la page Conseils à propos de sécurité pour plus de détails.

Les sections <Directory> se situent dans le fichier httpd.conf. Les directives <Directory> ne peuvent pas être imbriquées et ne sont pas autorisées dans les sections <Limit> ou <LimitExcept>.

Voir aussi

top

Directive <DirectoryMatch>

Description:Regroupe des directives qui s'appliquent au contenu de répertoires du système de fichiers correspondant à une expression rationnelle
Syntaxe:<DirectoryMatch regex> ... </DirectoryMatch>
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Les balises <DirectoryMatch> et </DirectoryMatch> permettent de regrouper un ensemble de directives qui ne s'appliqueront qu'au répertoire précisé (et aux fichiers qu'il contient), comme pour la section <Directory>. Cependant, le répertoire est précisé sous la forme d'une expression rationnelle. Par exemple :

<DirectoryMatch "^/www/(.+/)?[0-9]{3}/">
    # ...
</DirectoryMatch>

convient pour les sous-répertoires de /www/ dont le nom se compose de trois chiffres.

Compatibilité

Avant la version 2.3.9, cette directive s'appliquait aussi aux sous-répertoires (comme la directive <Directory>), et ne tenait pas compte du symbole de fin de ligne ($). Depuis la version 2.3.9, seuls les répertoires qui correspondent à l'expression sont affectés par les directives contenues dans la section.

slash de fin

Cette directive s'applique aux requêtes pour des répertoires avec ou sans slash de fin ; les expressions contenant un symbole de fin de ligne ($) doivent donc faire l'objet d'une attention particulière.

A partir de la version 2.4.8, les groupes nommés et les références arrières sont extraits et enregistrés dans l'environnement avec leur nom en majuscules et préfixé par "MATCH_". Ceci permet de référencer des URLs dans des expressions ou au sein de modules comme mod_rewrite. Pour éviter toute confusion, les références arrières numérotées (non nommées) sont ignorées. Vous devez utiliser à la place des groupes nommés.

<DirectoryMatch "^/var/www/combined/(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</DirectoryMatch>

Voir aussi

top

Directive DocumentRoot

Description:Racine principale de l'arborescence des documents visible depuis Internet
Syntaxe:DocumentRoot chemin répertoire
Défaut:DocumentRoot "/usr/local/apache/htdocs"
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Cette directive permet de définir le répertoire à partir duquel httpd va servir les fichiers. S'il ne correspond pas à un Alias, le chemin de l'URL sera ajouté par le serveur à la racine des documents afin de construire le chemin du document recherché. Exemple :

DocumentRoot "/usr/web"

un accès à http://my.example.com/index.html se réfère alors à /usr/web/index.html. Si chemin répertoire n'est pas un chemin absolu, il est considéré comme relatif au chemin défini par la directive ServerRoot.

Le répertoire défini par la directive DocumentRoot ne doit pas comporter de slash final.

Voir aussi

top

Directive <Else>

Description:Contient des directives qui ne s'appliquent que si la condition correspondant à la section <If> ou <ElseIf> précédente n'est pas satisfaite par la requête à l'exécution
Syntaxe:<Else> ... </Else>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Les conditions imbriquées sont supportées à partir de la version 2.4.26 du serveur HTTP Apache

La section <Else> applique les directives qu'elle contient si et seulement si les conditions correspondant à la section <If> ou <ElseIf> immédiatement supérieure et dans la même portée n'ont pas été satisfaites. Par exemple, dans :

<If "-z req('Host')">
  # ...
</If>
<Else>
  # ...
</Else>

La condition de la section <If> serait satisfaite pour les requêtes HTTP/1.0 sans en-tête Host:, alors que celle de la section <Else> le serait pour les requêtes comportant un en-tête Host:.

Voir aussi

top

Directive <ElseIf>

Description:Contient des directives qui ne s'appliquent que si la condition correspondante est satisfaite par une requête à l'exécution, alors que la condition correspondant à la section <If> ou <ElseIf> précédente ne l'était pas.
Syntaxe:<ElseIf expression> ... </ElseIf>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Les conditions imbriquées sont supportées à partir de la version 2.4.26 du serveur HTTP Apache

La section <ElseIf> applique les directives qu'elle contient si et seulement si d'une part la condition correspondante est satisfaite, et d'autre part la condition correspondant à la section <If> ou <ElseIf> de la même portée ne l'est pas. Par exemple, dans :

<If "-R '10.1.0.0/16'">
  #...
</If>
<ElseIf "-R '10.0.0.0/8'">
  #...
</ElseIf>
<Else>
  #...
</Else>

La condition correspondant à la section <ElseIf> est satisfaite si l'adresse distante de la requête appartient au sous-réseau 10.0.0.0/8, mais pas si elle appartient au sous-réseau 10.1.0.0/16.

Voir aussi

top

Directive EnableMMAP

Description:Utilise la projection en mémoire (Memory-Mapping) pour lire les fichiers pendant qu'ils sont servis
Syntaxe:EnableMMAP On|Off
Défaut:EnableMMAP On
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core

Cette directive définit si httpd peut utiliser la projection en mémoire (Memory-Mapping) quand il doit lire le contenu d'un fichier pendant qu'il est servi. Par défaut, lorsque le traitement d'une requête requiert l'accès aux données contenues dans un fichier -- par exemple, pour servir un fichier interprété par le serveur à l'aide de mod_include -- Apache httpd projette le fichier en mémoire si le système d'exploitation le permet.

Cette projection en mémoire induit parfois une amélioration des performances. Sur certains systèmes cependant, il est préférable de désactiver la projection en mémoire afin d'éviter certains problèmes opérationnels :

Pour les configurations de serveur sujettes à ce genre de problème, il est préférable de désactiver la projection en mémoire des fichiers servis en spécifiant :

EnableMMAP Off

Pour les montages NFS, cette fonctionnalité peut être explicitement désactivée pour les fichiers concernés en spécifiant :

<Directory "/path-to-nfs-files">
  EnableMMAP Off
</Directory>
top

Directive EnableSendfile

Description:Utilise le support sendfile du noyau pour servir les fichiers aux clients
Syntaxe:EnableSendfile On|Off
Défaut:EnableSendfile Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:Par défaut à Off depuis la version 2.3.9.

Cette directive définit si le programme httpd peut utiliser le support sendfile du noyau pour transmettre le contenu des fichiers aux clients. Par défaut, lorsque le traitement d'une requête ne requiert pas l'accès aux données contenues dans un fichier -- par exemple, pour la transmission d'un fichier statique -- Apache httpd utilise sendfile pour transmettre le contenu du fichier sans même lire ce dernier, si le système d'exploitation le permet.

Ce mécanisme sendfile évite la séparation des opérations de lecture et d'envoi, ainsi que les réservations de tampons. sur certains systèmes cependant, ou sous certains systèmes de fichiers, il est préférable de désactiver cette fonctionnalité afin d'éviter certains problèmes opérationnels :

Pour les configurations de serveur non sujettes à ce genre de problème, vous pouvez activer cette fonctionnalité en spécifiant :

EnableSendfile On

Pour les montages réseau, cette fonctionnalité peut être explicitement désactivée pour les fichiers concernés en spécifiant :

<Directory "/path-to-nfs-files">
  EnableSendfile Off
</Directory>

Veuillez noter que la configuration de la directive EnableSendfile dans un contexte de répertoire ou de fichier .htaccess n'est pas supportée par mod_cache_disk. Le module ne prend en compte la définition de EnableSendfile que dans un contexte global.

top

Directive Error

Description:Interrompt la lecture de la configuration avec un message d'erreur personnalisé
Syntaxe:Error message
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Noyau httpd
Module:core
Compatibilité:à partir de la version 2.3.9

Si une erreur peut être détectée dans la configuration, souvent un module manquant, cette directive peut être utilisée pour générer un message d'erreur personnalisé, et interrompre la lecture de la configuration.

# Exemple
# vérification du chargement de mod_include
<IfModule !include_module>
  Error "mod_include is required by mod_foo.  Load it with LoadModule."
</IfModule>

# vérification de la définition de SSL ou (exclusif) NOSSL
<IfDefine SSL>
<IfDefine NOSSL>
  Error "Both SSL and NOSSL are defined.  Define only one of them."
</IfDefine>
</IfDefine>
<IfDefine !SSL>
<IfDefine !NOSSL>
  Error "Either SSL or NOSSL must be defined."
</IfDefine>
</IfDefine>

Note

Cette directive est évaluée lors du traitement de la configuration, et non à l'exécution. Par conséquent, elle ne peut pas être évaluée de manière conditionnelle en l'incluant dans une section <If>.

top

Directive ErrorDocument

Description:Document que le serveur renvoie au client en cas d'erreur
Syntaxe:ErrorDocument code erreur document
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core

Apache httpd peut traiter les problèmes et les erreurs de quatre manières,

  1. afficher un simple message d'erreur au contenu fixe
  2. afficher un message personnalisé
  3. rediriger en interne vers un chemin d'URL local pour traiter le problème ou l'erreur
  4. rediriger vers une URL externe pour traiter le problème ou l'erreur

La première option constitue le comportement par défaut; pour choisir une des trois autres options, il faut configurer Apache à l'aide de la directive ErrorDocument, suivie du code de la réponse HTTP et d'une URL ou d'un message. Apache httpd fournit parfois des informations supplémentaires à propos du problème ou de l'erreur.

A partir de la version 2.4.13, il est possible d'utiliser la syntaxe des expressions dans cette directive afin de générer des chaînes et URLs dynamiques.

Les URLs peuvent commencer par un slash (/) pour les chemins web locaux (relatifs au répertoire défini par la directive DocumentRoot), ou se présenter sous la forme d'une URL complète que le client pourra résoudre. Alternativement, un message à afficher par le navigateur pourra être fourni. Notez que la décision de considérer le paramètre comme URL, chemin ou message intervient avant toute interprètation d'expression. Exemples :

ErrorDocument 500 http://example.com/cgi-bin/server-error.cgi
ErrorDocument 404 /errors/bad_urls.php
ErrorDocument 401 /subscription_info.html
ErrorDocument 403 "Sorry can't allow you access today"
ErrorDocument 403 Forbidden!
ErrorDocument 403 /errors/forbidden.py?referrer=%{escape:%{HTTP_REFERER}}

De plus, on peut spécifier la valeur spéciale default pour indiquer l'utilisation d'un simple message d'Apache httpd codé en dur. Bien que non nécessaire dans des circonstances normales, la spécification de la valeur default va permettre de rétablir l'utilisation du simple message d'Apache httpd codé en dur pour les configurations qui sans cela, hériteraient d'une directive ErrorDocument existante.

ErrorDocument 404 /cgi-bin/bad_urls.pl

<Directory "/web/docs">
  ErrorDocument 404 default
</Directory>

Notez que lorsque vous spécifiez une directive ErrorDocument pointant vers une URL distante (c'est à dire tout ce qui commence par le préfixe http), le serveur HTTP Apache va envoyer une redirection au client afin de lui indiquer où trouver le document, même dans le cas où ce document se trouve sur le serveur local. Ceci a de nombreuses conséquences dont la plus importante réside dans le fait que le client ne recevra pas le code d'erreur original, mais au contraire un code de statut de redirection. Ceci peut en retour semer la confusion chez les robots web et divers clients qui tentent de déterminer la validité d'une URL en examinant le code de statut. De plus, si vous utilisez une URL distante avec ErrorDocument 401, le client ne saura pas qu'il doit demander un mot de passe à l'utilisateur car il ne recevra pas le code de statut 401. C'est pourquoi, si vous utilisez une directive ErrorDocument 401, elle devra faire référence à un document par le biais d'un chemin local.

Microsoft Internet Explorer (MSIE) ignore par défaut les messages d'erreur générés par le serveur lorsqu'ils sont trop courts et remplacent ses propres messages d'erreur "amicaux". Le seuil de taille varie en fonction du type d'erreur, mais en général, si la taille de votre message d'erreur est supérieure à 512 octets, il y a peu de chances pour que MSIE l'occulte, et il sera affiché par ce dernier. Vous trouverez d'avantage d'informations dans l'article de la base de connaissances Microsoft Q294807.

Bien que la plupart des messages d'erreur internes originaux puissent être remplacés, ceux-ci sont cependant conservés dans certaines circonstances sans tenir compte de la définition de la directive ErrorDocument. En particulier, en cas de détection d'une requête mal formée, le processus de traitement normal des requêtes est immédiatement interrompu, et un message d'erreur interne est renvoyé, ceci afin de se prémunir contre les problèmes de sécurité liés aux requêtes mal formées.

Si vous utilisez mod_proxy, il est en général préférable d'activer ProxyErrorOverride afin d'être en mesure de produire des messages d'erreur personnalisés pour le compte de votre serveur d'origine. Si vous n'activez pas ProxyErrorOverride, Apache httpd ne générera pas de messages d'erreur personnalisés pour le contenu mandaté.

Voir aussi

top

Directive ErrorLog

Description:Définition du chemin du journal des erreurs
Syntaxe: ErrorLog file-path|syslog[:[facility][:tag]]
Défaut:ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and OS/2)
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive ErrorLog permet de définir le nom du fichier dans lequel le serveur va journaliser toutes les erreurs qu'il rencontre. Si le file-path n'est pas absolu, il est considéré comme relatif au chemin défini par la directive ServerRoot.

ErrorLog "/var/log/httpd/error_log"

Si le file-path commence par une barre verticale "(|)", il est considéré comme une commande à lancer pour traiter la journalisation de l'erreur.

ErrorLog "|/usr/local/bin/httpd_errors"

Voir les notes à propos des journaux redirigés pour plus d'informations.

L'utilisation de syslog à la place d'un nom de fichier active la journalisation via syslogd(8) si le système le supporte. Le dispositif syslog par défaut est local7, mais vous pouvez le modifier à l'aide de la syntaxe syslog:facility, où facility peut être remplacé par un des noms habituellement documentés dans la page de man syslog(1). Le dispositif syslog local7 est global, et si il est modifié dans un serveur virtuel, le dispositif final spécifié affecte l'ensemble du serveur. La même règle s'applique au tag syslog qui utilise par défaut le nom du binaire du serveur HTTP Apache httpd dans la plupart des cas. Vous pouvez aussi modifier cette valeur en utilisant la syntaxe syslog::tag.

ErrorLog syslog:user
ErrorLog syslog:user:httpd.srv1
ErrorLog syslog::httpd.srv2

SECURITE : Voir le document conseils à propos de sécurité pour des détails sur les raisons pour lesquelles votre sécurité peut être compromise si le répertoire contenant les fichiers journaux présente des droits en écriture pour tout autre utilisateur que celui sous lequel le serveur est démarré.

Note

Lors de la spécification d'un chemin de fichier sur les plates-formes non-Unix, on doit veiller à n'utiliser que des slashes (/), même si la plate-forme autorise l'utilisation des anti-slashes (\). Et d'une manière générale, il est recommandé de n'utiliser que des slashes (/) dans les fichiers de configuration.

Voir aussi

top

Directive ErrorLogFormat

Description:Spécification du format des entrées du journal des erreurs
Syntaxe: ErrorLogFormat [connection|request] format
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive ErrorLogFormat permet de spécifier quelles informations supplémentaires vont être enregistrées dans le journal des erreurs en plus du message habituel.

# Exemple simple
ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [client %a] %M"

La spécification de connection ou request comme premier paramètre permet de définir des formats supplémentaires, ce qui a pour effet de journaliser des informations additionnelles lorsque le premier message est enregistré respectivement pour une connexion ou une requête spécifique. Ces informations additionnelles ne sont enregistrées qu'une seule fois par connexion/requête. Si le traitement d'une connexion ou d'une requête ne génère aucun message dans le journal, alors aucune information additionnelle n'est enregistrée.

Il peut arriver que certains items de la chaîne de format ne produisent aucune sortie. Par exemple, l'en-tête Referer n'est présent que si le message du journal est associé à une requête et s'il est généré à un moment où l'en-tête Referer a déjà été lu par le client. Si aucune sortie n'est générée, le comportement par défaut consiste à supprimer tout ce qui se trouve entre l'espace précédent et le suivant. Ceci implique que la ligne de journalisation est divisée en champs ne contenant pas d'espace séparés par des espaces. Si un item de la chaîne de format ne génère aucune sortie, l'ensemble du champ est omis. Par exemple, si l'adresse distante %a du format [%t] [%l] [%a] %M  n'est pas disponible, les crochets qui l'entourent ne seront eux-mêmes pas enregistrés. Il est possible d'échapper les espaces par un anti-slash afin qu'ils ne soient pas considérés comme séparateurs de champs. La combinaison '% ' (pourcentage espace) est un délimiteur de champ de taille nulle qui ne génère aucune sortie.

Ce comportement peut être changé en ajoutant des modificateurs à l'item de la chaîne de format. Le modificateur - (moins) provoque l'enregistrement d'un signe moins si l'item considéré ne génère aucune sortie. Pour les formats à enregistrement unique par connexion/requête, il est aussi possible d'utiliser le modificateur + (plus). Si un item ne générant aucune sortie possède le modificateur plus, la ligne dans son ensemble est omise.

Un modificateur de type entier permet d'assigner un niveau de sévérité à un item de format. L'item considéré ne sera journalisé que si la sévérité du message n'est pas plus haute que le niveau de sévérité spécifié. Les valeurs possibles vont de 1 (alert) à 15 (trace8), en passant par 4 (warn) ou 7 (debug).

Par exemple, voici ce qui arriverait si vous ajoutiez des modificateurs à l'item %{Referer}i qui enregistre le contenu de l'en-tête Referer.

Item modifiéSignification
%-{Referer}i Enregistre le caractère - si l'en-tête Referer n'est pas défini.
%+{Referer}i N'enregistre rien si l'en-tête Referer n'est pas défini.
%4{Referer}i N'enregistre le contenu de l'en-tête Referer que si la sévérité du message de journalisation est supérieure à 4.

Certains items de format acceptent des paramètres supplémentaires entre accolades.

Chaîne de format Description
%% Le signe pourcentage
%a Adresse IP et port clients
%{c}a Port et adresse IP sous-jacents du correspondant pour la connexion (voir le module mod_remoteip)
%A Adresse IP et port locaux
%{name}e Variable d'environnement de requête name
%E Etat d'erreur APR/OS et chaîne
%F Nom du fichier source et numéro de ligne de l'appel du journal
%{name}i En-tête de requête name
%k Nombre de requêtes persistantes pour cette connexion
%l Sévérité du message
%L Identifiant journal de la requête
%{c}L Identifiant journal de la connexion
%{C}L Identifiant journal de la connexion si utilisé dans la portée de la connexion, vide sinon
%m Nom du module qui effectue la journalisation du message
%M Le message effectif
%{name}n Note de requête name
%P Identifiant du processus courant
%T Identifiant du thread courant
%{g}T Identifiant unique de thread système du thread courant (l'identifiant affiché par la commande top par exemple ; seulement sous Linux pour l'instant)
%t L'heure courante
%{u}t L'heure courante avec les microsecondes
%{cu}t L'heure courante au format ISO 8601 étendu (compact), avec les microsecondes
%{cuz}t L'heure actuelle au format ISO 8601 étendu (compact), avec les microsecondes et la zone horaire au format standard ISO 8601:2000. Disponible depuis la version 2.4.58 seulement
%{%-format}t L'heure actuelle formatée selon la fonction strftime(3). Disponible depuis la version 2.4.58 seulement
%v Le nom de serveur canonique ServerName du serveur courant.
%V Le nom de serveur du serveur qui sert la requête en accord avec la définition de la directive UseCanonicalName.
(anti-slash espace) Espace non délimiteur
(pourcentage espace) Délimiteur de champ (aucune sortie)

L'item de format identifiant journal %L génère un identifiant unique pour une connexion ou une requête. Il peut servir à déterminer quelles lignes correspondent à la même connexion ou requête ou quelle requête est associée à tel connexion. Un item de format %L est aussi disponible dans le module mod_log_config, mais il permet dans ce contexte de corréler les entrées du journal des accès avec celles du journal des erreurs. Si le module mod_unique_id est chargé, c'est son identifiant unique qui sera utilisé comme identifiant de journal pour les requêtes.

# Exemple (format par défaut pour les MPMs threadés)
ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"

Cet exemple renverrait un message d'erreur du style :

[Thu May 12 08:28:57.652118 2011] [core:error] [pid 8777:tid 4326490112] [client ::1:58619] File does not exist: /usr/local/apache2/htdocs/favicon.ico

Notez que, comme indiqué plus haut, certains champs sont totalement supprimés s'ils n'ont pas été définis.

# Exemple (similaire au format 2.2.x)
ErrorLogFormat "[%t] [%l] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"
# Exemple avancé avec identifiants journal de requête/connexion
ErrorLogFormat "[%{uc}t] [%-m:%-l] [R:%L] [C:%{C}L] %7F: %E: %M"
ErrorLogFormat request "[%{uc}t] [R:%L] Request %k on C:%{c}L pid:%P tid:%T"
ErrorLogFormat request "[%{uc}t] [R:%L] UA:'%+{User-Agent}i'"
ErrorLogFormat request "[%{uc}t] [R:%L] Referer:'%+{Referer}i'"
ErrorLogFormat connection "[%{uc}t] [C:%{c}L] remote\ %a local\ %A"

Voir aussi

top

Directive ExtendedStatus

Description:Extrait des informations d'état étendues pour chaque requête
Syntaxe:ExtendedStatus On|Off
Défaut:ExtendedStatus Off
Contexte:configuration globale
Statut:Noyau httpd
Module:core

Cette option permet d'extraire des données supplémentaires concernant la requête en cours de traitement pour un processus donné, et crée un résumé d'utilisation ; vous pouvez accéder à ces variables pendant l'exécution en configurant mod_status. Notez que d'autres modules sont susceptibles de s'appuyer sur ce tableau de bord.

Cette directive s'applique au serveur dans son ensemble, et ne peut pas être activée/désactivée pour un serveur virtuel particulier. Notez que l'extraction des informations d'état étendues peut ralentir le serveur. Notez aussi que cette définition ne peut pas être modifiée au cours d'un redémarrage graceful.

Notez que le chargement de mod_status définit automatiquement ExtendedStatus à On, et que d'autres modules tiers sont susceptibles d'en faire de même. De tels modules ont besoin d'informations détaillées à propos de l'état de tous les processus. Depuis la version 2.3.6, mod_status a définit la valeur par défaut à On, alors qu'elle était à Off dans les versions antérieures.

top

Directive FileETag

Description:Caractéristiques de fichier utilisées lors de la génération de l'en-tête de réponse HTTP ETag pour les fichiers statiques
Syntaxe:FileETag composant ...
Défaut:FileETag MTime Size
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:La valeur par défaut était "INode MTime Size" dans les versions 2.3.14 et antérieures.

La directive FileETag définit les caractéristiques de fichier utilisées lors de la génération de l'en-tête de réponse HTTP ETag (entity tag) quand le document est contenu dans un fichier statique (la valeur de ETag est utilisée dans le cadre de la gestion du cache pour préserver la bande passante réseau). La directive FileETag vous permet maintenant de choisir quelles caractéristiques du fichier vont être utilisées, le cas échéant. Les mots-clés reconnus sont :

INode
Le numéro d'i-node du fichier sera inclus dans le processus de génération
MTime
La date et l'heure auxquelles le fichier a été modifié la dernière fois seront incluses
Size
La taille du fichier en octets sera incluse
All
Tous les champs disponibles seront utilisés. Cette définition est équivalente à :
FileETag INode MTime Size
Digest
Si un document est à base de fichier, le champ ETag sera généré à partir du condensé du fichier.
None
Si le document se compose d'un fichier, aucun champ ETag ne sera inclus dans la réponse

Les mots-clés INode, MTime, Size et Digest peuvent être préfixés par + ou -, ce qui permet de modifier les valeurs par défaut héritées d'un niveau de configuration plus général. Tout mot-clé apparaissant sans aucun préfixe annule entièrement et immédiatement les configurations héritées.

Si la configuration d'un répertoire contient FileETag INode MTime Size, et si un de ses sous-répertoires contient FileETag -INode, la configuration de ce sous-répertoire (qui sera propagée vers tout sous-répertoire qui ne la supplante pas), sera équivalente à FileETag MTime Size.

Inclusions côté serveur

Aucun champ ETag n'est généré pour les réponses interprétées par mod_include, car l'entité de la réponse peut changer sans modification de l'INode, MTime, Size ou Digest du fichier statique contenant les directives SSI.
top

Directive <Files>

Description:Contient des directives qui s'appliquent aux fichiers précisés
Syntaxe:<Files nom fichier> ... </Files>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

La directive <Files> limite la portée des directives qu'elle contient aux fichiers précisés. Elle est comparable aux directives <Directory> et <Location>. Elle doit se terminer par une balise </Files>. Les directives contenues dans cette section s'appliqueront à tout objet dont le nom de base (la dernière partie du nom de fichier) correspond au fichier spécifié. Les sections <Files> sont traitées selon l'ordre dans lequel elles apparaissent dans le fichier de configuration, après les sections <Directory> et la lecture des fichiers .htaccess, mais avant les sections <Location>. Notez que les sections <Files> peuvent être imbriquées dans les sections <Directory> afin de restreindre la portion du système de fichiers à laquelle ces dernières vont s'appliquer.

L'argument filename peut contenir un nom de fichier ou une chaîne de caractères avec caractères génériques, où ? remplace un caractère, et * toute chaîne de caractères.

<Files "cat.html">
    # Insérer ici des directives qui s'appliquent au fichier cat.html
</Files>

<Files "?at.*">
    # Les directives insérées ici s'appliqueront aux fichiers
    # cat.html, bat.html, hat.php, et ainsi de suite.
</Files>

On peut aussi utiliser les Expressions rationnelles en ajoutant la caractère ~. Par exemple :

<Files ~ "\.(gif|jpe?g|png)$">
    #...
</Files>

correspondrait à la plupart des formats graphiques de l'Internet. Il est cependant préférable d'utiliser la directive <FilesMatch>.

Notez qu'à la différence des sections <Directory> et <Location>, les sections <Files> peuvent être utilisées dans les fichiers .htaccess. Ceci permet aux utilisateurs de contrôler l'accès à leurs propres ressources, fichier par fichier.

Voir aussi

top

Directive <FilesMatch>

Description:Contient des directives qui s'appliquent à des fichiers spécifiés sous la forme d'expressions rationnelles
Syntaxe:<FilesMatch expression rationnelle> ... </FilesMatch>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

La section <FilesMatch> limite la portée des directives qu'elle contient aux fichiers spécifiés, tout comme le ferait une section <Files>. Mais elle accepte aussi les expressions rationnelles. Par exemple :

<FilesMatch ".+\.(gif|jpe?g|png)$">
    # ...
</FilesMatch>

correspondrait à la plupart des formats graphiques de l'Internet.

Les caractères .+ au début de l'expression rationnelle permettent de s'assurer que les fichiers de nom .png, ou .gif, par exemple, ne seront pas pris en compte.

A partir de la version 2.4.8, les groupes nommés et les références arrières sont extraits et enregistrés dans l'environnement avec leur nom en majuscules et préfixé par "MATCH_". Ceci permet de référencer des URLs dans des expressions ou au sein de modules comme mod_rewrite. Pour éviter toute confusion, les références arrières numérotées (non nommées) sont ignorées. Vous devez utiliser à la place des groupes nommés.

<FilesMatch "^(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</FilesMatch>

Voir aussi

top

Directive FlushMaxPipelined

Description:Nombre maximal de réponses en attente (pipelined) au-delà duquel elles sont envoyées sur le réseau
Syntaxe:FlushMaxPipelined number
Défaut:FlushMaxPipelined 5
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.47 du serveur HTTP Apache

Cette directive permet de définir le nombre maximal de réponses "pipelinées" qui restent en attente tant que des requêtes "pipelinées" sont reçues. Lorsque cette limite est dépassée, l'envoi des réponses sur le réseau est forcé en mode bloqué jusqu'à ce que leur nombre repasse en dessous de la limite.

La directive FlushMaxPipelined permet de limiter la consommation de mémoire. Lorsqu'elle est définie à 0, le pipelining est désactivé, et lorsqu'elle est définie à -1, il n'y a plus de limite (mais la directive FlushMaxThreshold s'applique quand-même).

top

Directive FlushMaxThreshold

Description:Seuil au-delà duquel les données en attente sont envoyées sur le réseau
Syntaxe:FlushMaxThreshold number-of-bytes
Défaut:FlushMaxThreshold 65535
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.47 du serveur HTTP Apache

Cette directive permet de définir le seuil maximal de données en attente d'envoi (en octets). Lorsque cette limite est dépassée, l'envoi des données sur le réseau est forcé en mode bloqué jusqu'à ce que leur quantité repasse en dessous du seuil spécifié.

La directive FlushMaxThreshold permet de limiter la consommation de mémoire. Lorsqu'elle est définie à 0 ou à une valeur trop petite, aucune donnée n'est mise en attente, mais dans le cas des MPMs threadés, il peut alors y avoir plus de threads occupés en attente du réseau, ce qui diminue d'autant le nombre de threads disponibles pour traiter les autres connexions simultanées.

top

Directive ForceType

Description:Force le type de médium spécifié dans le champ d'en-tête HTTP Content-Type pour les fichiers correspondants
Syntaxe:ForceType type médium|None
Contexte:répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core

Lorsqu'elle est placée dans un fichier .htaccess ou une section <Directory>, <Location>, ou <Files>, cette directive force l'identification du type MIME des fichiers spécifiés à la valeur de l'argument type médium. Par exemple, si vous possédez un répertoire ne contenant que des fichiers GIF, et si vous ne voulez pas leur ajouter l'extension .gif, vous pouvez utiliser :

ForceType image/gif

Notez que cette directive l'emporte sur d'autres associations de type de médium indirectes définies dans mime.types ou via la directive AddType.

Vous pouvez aussi annuler toute définition plus générale de ForceType en affectant la valeur None à l'argument type médium :

# force le type MIME de tous les fichiers à image/gif:
<Location "/images">
  ForceType image/gif
</Location>

# mais utilise les méthodes classiques d'attribution du type MIME
# dans le sous-répertoire suivant :
<Location "/images/mixed">
  ForceType None
</Location>

A la base, cette directive écrase le type de contenu généré pour les fichiers statiques servis à partir du sytème de fichiers. Pour les ressources autres que les fichiers statiques pour lesquels le générateur de réponse spécifie en général un type de contenu, cette directive est ignorée.

Note

Lorsque des directives explicites comme SetHandler ou module="mod_mime">AddHandler ne s'appliquent pas à la requête courante, le nom du gestionnaire interne normalement défini par ces directives correspondra alors au type de contenu spécifié par cette directive. Il s'agit d'un comportement historique que certains modules tiers, comme mod_php, peuvent interpréter comme un type de contenu artificiel ne servant qu'à indiquer le module qui doit prendre en compte la requête considérée. Dans la mesure du possible, il est conseillé d'éviter les configurations qui comportent de tels types artificiels en utilisant les directives SetHandler ou AddHandler.

top

Directive GprofDir

Description:Répertoire dans lequel écrire les données de profiling gmon.out.
Syntaxe:GprofDir /tmp/gprof/|/tmp/gprof/%
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Lorsque le serveur a été compilé avec le support du profiling gprof, la directive GprofDir permet de spécifier dans quel répertoire les fichiers gmon.out doivent être écrits lorsque le processus s'arrête. Si l'argument se termine par un caractère pourcentage ('%'), des sous-répertoires sont créés pour chaque identifiant de processus.

Cette directive ne fonctionne actuellement qu'avec le MPM prefork.

top

Directive HostnameLookups

Description:Active la recherche DNS sur les adresses IP des clients
Syntaxe:HostnameLookups On|Off|Double
Défaut:HostnameLookups Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core

Cette directive active la recherche DNS afin de pouvoir journaliser les nom d'hôtes (et les passer aux programmes CGI et aux inclusions SSI via la variable REMOTE_HOST). La valeur Double déclenche une double recherche DNS inverse. En d'autres termes, une fois la recherche inverse effectuée, on lance une recherche directe sur le résultat de cette dernière. Au moins une des adresses IP fournies par la recherche directe doit correspondre à l'adresse originale (ce que l'on nomme PARANOID dans la terminologie "tcpwrappers").

Quelle que soit la configuration, lorsqu'on utilise mod_authz_host pour contrôler l'accès en fonction du nom d'hôte, une double recherche DNS inverse est effectuée, sécurité oblige. Notez cependant que le résultat de cette double recherche n'est en général pas accessible, à moins que vous n'ayez spécifié HostnameLookups Double. Par exemple, si vous n'avez spécifié que HostnameLookups On, et si une requête concerne un objet protégé par des restrictions en fonction du nom d'hôte, quel que soit le résultat de la double recherche inverse, les programmes CGI ne recevront que le résultat de la recherche inverse simple dans la variable REMOTE_HOST.

La valeur par défaut est Off afin de préserver le traffic réseau des sites pour lesquels la recherche inverse n'est pas vraiment nécessaire. Cette valeur par défaut est aussi bénéfique pour les utilisateurs finaux car il n'ont ainsi pas à subir de temps d'attente supplémentaires dus aux recherches DNS. Les sites fortement chargés devraient laisser cette directive à Off, car les recherches DNS peuvent prendre des temps très longs. Vous pouvez éventuellement utiliser hors ligne l'utilitaire logresolve, compilé par défaut dans le sous-répertoire bin de votre répertoire d'installation, afin de déterminer les noms d'hôtes associés aux adresses IP journalisées.

Enfin, si vous avez des directives Require à base de nom, une recherche de nom d'hôte sera effectuée quelle que soit la définition de la directive HostnameLookups.

top

Directive HttpProtocolOptions

Description:Modifie les contraintes sur les messages des requêtes HTTP
Syntaxe:HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0]
Défaut:HttpProtocolOptions Strict LenientMethods Allow0.9
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir des versions 2.2.32 et 2.4.24 du serveur HTTP Apache

Cette directive permet de modifier les règles qui s'appliquent à la ligne de requête HTTP (RFC 7230 §3.1.1) et aux champs des en-têtes des requêtes HTTP (RFC 7230 §3.2), qui s'appliquent maintenant par défaut ou en utilisant l'option Strict. L'option Unsafe a été ajoutée pour pouvoir restaurer les anciens comportements nécessaires aux anciens modules et applications et aux agents utilisateurs personnalisés considérés comme obsolètes.

Ces règles s'appliquant avant le traitement de la requête, elles doivent, pour être prises en compte, être définies au niveau global ou dans la première section par défaut du serveur virtuel qui correspond à la requête considérée, par interface IP/port et non par nom.

Cette directive accepte trois paramètres issus de la liste suivante, ceux qui ne sont pas spécifiés prenant leur valeur par défaut :

Strict|Unsafe

Avant l'introduction de cette directive, les interpréteurs de requêtes du serveur HTTP Apache toléraient un grand nombre de formats en entrée qui n'étaient pas forcément conformes au protocole. RFC 7230 §9.4 Request Splitting et §9.5 Response Smuggling ne rappellent que deux des risques potentiels induits par des requêtes non conformes, alors que RFC 7230 §3.5 signale les risques encourus par l'acceptation de blancs non conformes dans les lignes de requête. Avec l'introduction de cette directive, toutes les règles de grammaire de la spécification doivent être respectées dans le mode d'opérations par défaut Strict.

Risques de sécurité liés au mode Unsafe

Il est fortement déconseillé aux utilisateurs d'utiliser le mode d'opération Unsafe, ou UnsafeWhitespace, en particulier pour les déploiements de serveurs ouverts sur l'extérieur et/ou accessibles au public. Si un moniteur défectueux ou autre logiciel spécialisé ne s'exécutant que sur un intranet nécessite une interface, les utilisateurs ne doivent utiliser les options de type UnSafe qu'en cas de nécessité et uniquement au sein d'un serveur virtuel bien spécifique et sur un réseau privé.

Exemple de requête provoquant l'envoi d'un message HTTP 400 en mode Strict

# Missing CRLF
GET / HTTP/1.0\n\n

Utilitaires en ligne de commande et CRLF

Il peut s'avérer nécessaire de forcer certains utilitaires à utiliser CRLF ; si ce n'est pas le cas, httpd reverra une réponse HTTP 400 comme dans le cas précédent. Par exemple, le client OpenSSL s_client doit utiliser le paramètre -crlf pour fonctionner correctement.

Pour détecter des problèmes tels que l'absence de CRLF, vous pouvez utiliser la directive DumpIOInput qui permet de décortiquer les requêtes HTTP.

RegisteredMethods|LenientMethods

La section de la RFC 7231 §4.1 "Request Methods" "Overview" indique que les serveurs doivent renvoyer un message d'erreur lorsque la ligne de requête comporte une méthode non supportée. C'est déjà le cas lorsque l'option LenientMethods est utilisée, mais les administrateurs ont la possibilité de limiter les méthodes utilisées via l'option RegisteredMethods en enregistrant toute méthode non standard via la directive RegisterHttpMethod, en particulier si l'option Unsafe est utilisée.

Compatibilité avec le mandat direct

L'option RegisteredMethods ne doit pas être utilisée pour les serveurs mandataires car ces derniers ne connaissent pas les méthodes supportées par les serveurs originaux.

Exemple de requête provoquant l'envoi d'un message HTTP 501 en mode LenientMethods

# Méthode HTTP inconnue
WOW / HTTP/1.0\r\n\r\n

# Méthode HTTP spécifiée en minuscules
get / HTTP/1.0\r\n\r\n

Allow0.9|Require1.0

La section de la RFC 2616 §19.6 "Compatibility With Previous Versions" encouragait les serveurs HTTP à supporter les anciennes requêtes HTTP/0.9. La RFC 7230 va cependant à son encontre via sa préconisation "Le souhait de supporter les requêtes HTTP/0.9 a été supprimé" et y adjoint des commentaires dans RFC 7230 Appendix A. A ce titre, l'option Require1.0 permet à l'utilisateur d'inhiber le comportement induit par l'option par défaut Allow0.9.

Exemple de requête provoquant l'envoi d'un message HTTP 400 en mode Require1.0

# Version HTTP non supportée
GET /\r\n\r\n

La consultation des messages enregistrés dans le journal ErrorLog, configuré via la directive LogLevel avec un niveau info, pourra vous aider à identifier de telles requêtes non conformes ainsi que leur provenance. Les utilisateurs devront accorder une attention particulière aux messages d'erreur de type 400 dans le journal access pour détecter les requêtes apparemment valides mais rejetées.

top

Directive <If>

Description:Contient des directives qui ne s'appliquent que si une condition est satisfaite au cours du traitement d'une requête
Syntaxe:<If expression> ... </If>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Les conditions imbriquées sont supportées à partir de la version 2.4.26 du serveur HTTP Apache

La directive <If> évalue une expression à la volée, et applique les directives qu'elle contient si et seulement si l'expression renvoie la valeur "vrai". Par exemple :

<If "-z req('Host')">

serait satisfaite pour les requêtes HTTP/1.0 sans en-tête Host:. Les expressions peuvent contenir différents opérateurs de type shell pour la comparaison de chaînes (==, !=, <, ...), la comparaison d'entiers (-eq, -ne, ...), ou à usages divers (-n, -z, -f, ...). Les expressions rationnelles sont aussi supportées,

<If "%{QUERY_STRING} =~ /(delete|commit)=.*?elem/">

ainsi que les comparaison de modèles de type shell et de nombreuses autres opérations. Ces opérations peuvent être effectuées sur les en-têtes de requêtes (req), les variables d'environnement (env), et un grand nombre d'autres propriétés. La documentation complète est disponible dans Les expressions dans le serveur HTTP Apache.

Cette section de configuration ne peut contenir que des directives qui supportent le contexte de répertoire.

Certain variables, such as CONTENT_TYPE and other response headers, are set after <If> conditions have already been evaluated, and so will not be available to use in this directive.
Les directives qui sont évaluées lors du traitement de la configuration comme Define, Include et Error ne peuvent pas être traitées de manière conditionnelle en les incluant dans une section de configuration <If>. Ces sections font en effet toujours partie de la configuration, quelle soit la manière dont elles sont évaluées à l'exécution.

Voir aussi

top

Directive <IfDefine>

Description:Contient des directives qui ne s'appliqueront que si un test retourne "vrai" au démarrage du serveur
Syntaxe:<IfDefine [!]paramètre> ... </IfDefine>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

La section <IfDefine test>...</IfDefine> permet de conférer un caractère conditionnel à un ensemble de directives. Les directives situées à l'intérieur d'une section <IfDefine> ne s'appliquent que si test est vrai. Si test est faux, tout ce qui se trouve entre les balises de début et de fin est ignoré.

test peut se présenter sous deux formes :

Dans le premier cas, les directives situées entre les balises de début et de fin ne s'appliqueront que si le paramètre nommé nom paramètre est défini. Le second format inverse le test, et dans ce cas, les directives ne s'appliqueront que si nom paramètre n'est pas défini.

L'argument nom paramètre est une définition qui peut être effectuée par la ligne de commande httpd via le paramètre -Dparamètre au démarrage du serveur, ou via la directive Define.

Les sections <IfDefine> peuvent être imbriquées, ce qui permet d'implémenter un test multi-paramètres simple. Exemple :

httpd -DReverseProxy -DUseCache -DMemCache ...

<IfDefine ReverseProxy>
  LoadModule proxy_module   modules/mod_proxy.so
  LoadModule proxy_http_module   modules/mod_proxy_http.so
  <IfDefine UseCache>
    LoadModule cache_module   modules/mod_cache.so
    <IfDefine MemCache>
      LoadModule mem_cache_module   modules/mod_mem_cache.so
    </IfDefine>
    <IfDefine !MemCache>
      LoadModule cache_disk_module   modules/mod_cache_disk.so
    </IfDefine>
  </IfDefine>
</IfDefine>
top

Directive <IfDirective>

Description:Regroupe des directives dont le traitement est conditionné par la présence ou l'absence d'une directive particulière
Syntaxe:<IfDirective [!]directive-name> ... </IfDirective>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.34 du serveur HTTP Apache

La section <IfDirective test>...</IfDirective> permet de regrouper des directives dont le traitement n'est effectué que si une directive particulière est présente, autrement dit si l'expression test est évaluée à true. Si l'expression test est évaluée à false, toutes les lignes qui se trouvent entre les balises de début et de fin de la section sont ignorées.

L'expression test de la section <IfDirective> peut prendre les deux formes suivantes :

Dans le premier cas, les directives qui se situent entre les balises de début et de fin de la section ne sont traitées que si une directive de nom directive-name est disponible à cet instant. Dans le second cas, la condition est inversée, et les directives ne sont traitées que si directive-name n'est pas disponible.

Cette section ne doit être utilisée que si vous devez partager le même fichier de configuration entre plusieurs versions de httpd, sans tenir compte de la disponibilité de telle ou telle directive. Dans une configuration standard, il est inutile de placer les directives dans des sections <IfDirective>.

Voir aussi

top

Directive <IfFile>

Description:Regroupe des directives qui ne seront traitées que si un fichier existe au démarrage
Syntaxe:<IfFile [!]filename> ... </IfFile>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.34 du serveur HTTP Apache

La section <IfFile filename>...</IfFile> permet de conditionner le traitement de directives à l'existence d'un fichier sur disque. Ainsi, les directives définies au sein d'une section <IfFile> ne seront traitées que si le fichier filename existe. Si le fichier filename n'existe pas, tout ce qui se trouve entre les marqueurs start et end sera ignoré. filename peut être un chemin absolu ou relatif au chemin défini par la directive ServerRoot.

Le paramètre filename de l'en-tête d'une section <IfFile> peut prendre la même forme que la variable test de la section <IfDefine> ; à ce titre, le résultat du test peut être inversé en plaçant le caractère ! juste avant filename.

Si filename est un chemin relatif, il sera généré par rapport au chemin défini par la directive ServerRoot. Lorsque la directive <IfFile> intervient avant la définition de la directive ServerRoot, filename sera relatif au répertoire racine par défaut du serveur ou au répertoire racine passé dans la ligne de commande via l'option -d.

Avertissement

Avec la version 2.4.34, il est interdit de spécifier un filename entouré de guillemets. Ceci provoquerait une erreur de syntaxe au démarrage. Il est donc impossible de spécifier des noms de fichiers contenant des espaces, mais ce défaut a été corrigé à partir de la version 2.4.35.
top

Directive <IfModule>

Description:Contient des directives qui ne s'appliquent qu'en fonction de la présence ou de l'absence d'un module spécifique
Syntaxe:<IfModule [!]fichier module|identificateur module> ... </IfModule>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Les identificateurs de modules sont disponibles dans les versions 2.1 et supérieures.

La section <IfModule test>...</IfModule> permet de conférer à des directives un caractère conditionnel basé sur la présence d'un module spécifique. Les directives situées dans une section <IfModule> ne s'appliquent que si test est vrai. Si test est faux, tout ce qui se trouve entre les balises de début et de fin est ignoré.

test peut se présenter sous deux formes :

Dans le premier cas, les directives situées entre les balises de début et de fin ne s'appliquent que si le module module est présent -- soit compilé avec le binaire Apache httpd, soit chargé dynamiquement via la directive LoadModule. Le second format inverse le test, et dans ce cas, les directives ne s'appliquent que si module n'est pas présent.

L'argument module peut contenir soit l'identificateur du module, soit le nom du fichier source du module. Par exemple, rewrite_module est un identificateur et mod_rewrite.c le nom du fichier source correspondant. Si un module comporte plusieurs fichiers sources, utilisez le nom du fichier qui contient la chaîne de caractères STANDARD20_MODULE_STUFF.

Les sections <IfModule> peuvent être imbriquées, ce qui permet d'implémenter des tests multi-modules simples.

Cette section ne doit être utilisée que si votre fichier de configuration ne fonctionne qu'en fonction de la présence ou de l'absence d'un module spécifique. D'une manière générale, il n'est pas nécessaire de placer les directives à l'intérieur de sections <IfModule>.
top

Directive <IfSection>

Description:Regroupe des directives dont le traitement est conditionné par la présence ou l'absence d'une section particulière
Syntaxe:<IfSection [!]section-name> ... </IfSection>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.34 du serveur HTTP Apache

La section <IfSection test>...</IfSection> permet de regrouper des directives dont le traitement n'est effectué que si une section de configuration particulière est présente. Une section, par exemple <VirtualHost>, permet de regrouper des directives et possède un nom précédé du caractère "<".

Les directives situées à l'intérieur d'une section <IfSection> ne sont traitées que si l'expression test est évaluée à true. Si l'expression test est évaluée à false, toutes les lignes situées entre les balises de début et de fin de la section sont ignorées.

section-name doit être spécifié sans les caractères de début "<" ou fin ">". L'expression test de la section <IfSection> peut prendre deux formes :

Dans le premier cas, les directives qui se situent entre les balises de début et de fin de la section ne sont traitées que si une section de nom section-name est disponible à cet instant. Dans le second cas, la condition est inversée, et les directives ne sont traitées que si section-name n'est pas disponible.

Par exemple :

<IfSection VirtualHost>
   ...
</IfSection>
Cette section ne doit être utilisée que si vous devez partager le même fichier de configuration entre plusieurs versions de httpd, sans tenir compte de la disponibilité de telle ou telle section. Dans une configuration standard, il est inutile de placer les directives dans des sections <IfSection>.

Voir aussi

top

Directive Include

Description:Inclut d'autres fichiers de configuration dans un des fichiers de configuration du serveur
Syntaxe:Include chemin-fichier|chemin-répertoire|wildcard
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core
Compatibilité:Utilisation des caractères génériques dans la partie chemin depuis la version 2.3.6

Cette directive permet l'inclusion d'autres fichiers de configuration dans un des fichiers de configuration du serveur.

On peut utiliser des caractères génériques de style Shell (fnmatch()) aussi bien dans la partie nom de fichier du chemin que dans la partie répertoires pour inclure plusieurs fichiers en une seule fois, selon leur ordre alphabétique. De plus, si la directive Include pointe vers un répertoire, Apache httpd inclura tous les fichiers de ce répertoire et de tous ces sous-répertoires. L'inclusion de répertoires entiers est cependant déconseillée, car il est fréquent d'oublier des fichiers temporaires dans un répertoire, ce qui causerait une erreur httpd en cas d'inclusion. Pour inclure des fichiers qui correspondent à un certain modèle, comme *.conf par exemple, nous vous recommandons d'utiliser plutôt la syntaxe avec caractères génériques comme ci-dessous.

La directive Include échouera avec un code d'erreur si une expression contenant des caractères génériques ne correspond à aucun fichier. Pour ignorer les expressions contenant des caractères génériques ne correspondant à aucun fichier, utilisez la directive IncludeOptional.

Le chemin fichier spécifié peut être soit un chemin absolu, soit un chemin relatif au répertoire défini par la directive ServerRoot.

Exemples :

Include /usr/local/apache2/conf/ssl.conf
Include /usr/local/apache2/conf/vhosts/*.conf

ou encore, avec des chemins relatifs au répertoire défini par la directive ServerRoot :

Include conf/ssl.conf
Include conf/vhosts/*.conf

On peut aussi insérer des caractères génériques dans la partie répertoires du chemin. Dans l'exemple suivant, la directive échouera si aucun sous-répertoire de conf/vhosts ne contient au moins un fichier *.conf :

Include conf/vhosts/*/*.conf

Par contre, dans l'exemple suivant, la directive sera simplement ignorée si aucun sous-répertoire de conf/vhosts ne contient au moins un fichier *.conf :

IncludeOptional conf/vhosts/*/*.conf

Voir aussi

top

Directive IncludeOptional

Description:Inclusion de fichiers dans le fichier de configuration
Syntaxe:IncludeOptional file-path|directory-path|wildcard
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.3.6 du serveur HTTP Apache. Après la version 2.4.30, les chemins de fichiers non existants et ne comportant pas de caractères génériques ne génèrent plus d'erreurs de syntaxe

Cette directive permet d'inclure des fichiers dans les fichiers de configuration du serveur. Elle fonctionne de manière identique à la directive Include, mais au lieu de générer une erreur, elle sera ignorée silensieusement si malgré l'utilisation de caractères génériques, le chemin de fichier ou de répertoire spécifié n'existe pas dans le système de fichiers.

Voir aussi

top

Directive KeepAlive

Description:Active les connexions HTTP persistantes
Syntaxe:KeepAlive On|Off
Défaut:KeepAlive On
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

L'extension Keep-Alive de HTTP/1.0 et l'implémentation des connexions persistantes dans HTTP/1.1 ont rendu possibles des sessions HTTP de longue durée, ce qui permet de transmettre plusieurs requêtes via la même connexion TCP. Dans certains cas, le gain en rapidité pour des documents comportant de nombreuses images peut atteindre 50%. Pour activer les connexions persistantes, définissez KeepAlive On.

Pour les clients HTTP/1.0, les connexions persistantes ne seront mises en oeuvre que si elles ont été spécialement demandées par un client. De plus, une connexion persistante avec un client HTTP/1.0 ne peut être utilisée que si la taille du contenu est connue d'avance. Ceci implique que les contenus dynamiques comme les sorties CGI, les pages SSI, et les listings de répertoires générés par le serveur n'utiliseront en général pas les connexions persistantes avec les clients HTTP/1.0. Avec les clients HTTP/1.1, les connexions persistantes sont utilisées par défaut, sauf instructions contraires. Si le client le demande, le transfert par tronçons de taille fixe (chunked encoding) sera utilisé afin de transmettre un contenu de longueur inconnue via une connexion persistante.

Lorsqu'un client utilise une connexion persistante, elle comptera pour une seule requête pour la directive MaxConnectionsPerChild, quel que soit le nombre de requêtes transmises via cette connexion.

Voir aussi

top

Directive KeepAliveTimeout

Description:Durée pendant laquelle le serveur va attendre une requête avant de fermer une connexion persistante
Syntaxe:KeepAliveTimeout nombre[ms]
Défaut:KeepAliveTimeout 5
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Le nombre de secondes pendant lesquelles Apache httpd va attendre une requête avant de fermer la connexion. Le délai peut être défini en millisecondes en suffixant sa valeur par ms. La valeur du délai spécifiée par la directive Timeout s'applique dès qu'une requête a été reçue.

Donner une valeur trop élévée à KeepAliveTimeout peut induire des problèmes de performances sur les serveurs fortement chargés. Plus le délai est élévé, plus nombreux seront les processus serveur en attente de requêtes de la part de clients inactifs.

Si la directive KeepAliveTimeout n'est pas définie pour un serveur virtuel à base de nom, c'est la valeur de la paire adresse IP/port du serveur virtuel qui correspond le mieux qui sera utilisée.

top

Directive <Limit>

Description:Limite les contrôles d'accès que la section contient à certaines méthodes HTTP
Syntaxe:<Limit méthode [méthode] ... > ... </Limit>
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig, Limit
Statut:Noyau httpd
Module:core

Les contrôles d'accès s'appliquent normalement à toutes les méthodes d'accès, et c'est en général le comportement souhaité. Dans le cas général, les directives de contrôle d'accès n'ont pas à être placées dans une section <Limit>.

La directive <Limit> a pour but de limiter les effets des contrôles d'accès aux méthodes HTTP spécifiées. Pour toutes les autres méthodes, les restrictions d'accès contenues dans la section <Limit> n'auront aucun effet. L'exemple suivant n'applique les contrôles d'accès qu'aux méthodes POST, PUT, et DELETE, en laissant les autres méthodes sans protection :

<Limit POST PUT DELETE>
  Require valid-user
</Limit>

La liste des noms de méthodes peut contenir une ou plusieurs valeurs parmi les suivantes : GET, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, et UNLOCK. Le nom de méthode est sensible à la casse. Si la valeur GET est présente, les requêtes HEAD seront aussi concernées. La méthode TRACE ne peut pas être limitée (voir la directive TraceEnable).

Une section <LimitExcept> doit toujours être préférée à une section <Limit> pour la restriction d'accès, car une section <LimitExcept> fournit une protection contre les méthodes arbitraires.

Les directives <Limit> et <LimitExcept> peuvent être imbriquées. Dans ce cas, pour chaque niveau des directives <Limit> ou <LimitExcept>, ces dernières doivent restreindre l'accès pour les méthodes auxquelles les contrôles d'accès s'appliquent.

Lorsqu'on utilise les directives <Limit> ou <LimitExcept> avec la directive Require, la première directive Require dont la condition est satisfaite autorise la requête, sans tenir compte de la présence d'autres directives Require.

Par exemple, avec la configuration suivante, tous les utilisateurs seront autorisés à effectuer des requêtes POST, et la directive Require group editors sera ignorée dans tous les cas :

<LimitExcept GET>
  Require valid-user
</LimitExcept>
<Limit POST>
  Require group editors
</Limit>
top

Directive <LimitExcept>

Description:Applique les contrôles d'accès à toutes les méthodes HTTP, sauf celles qui sont spécifiées
Syntaxe:<LimitExcept méthode [méthode] ... > ... </LimitExcept>
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig, Limit
Statut:Noyau httpd
Module:core

<LimitExcept> et </LimitExcept> permettent de regrouper des directives de contrôle d'accès qui s'appliqueront à toutes les méthodes d'accès HTTP qui ne font pas partie de la liste des arguments ; en d'autres termes, elles ont un comportement opposé à celui de la section <Limit>, et on peut les utiliser pour contrôler aussi bien les méthodes standards que les méthodes non standards ou non reconnues. Voir la documentation de la section <Limit> pour plus de détails.

Par exemple :

<LimitExcept POST GET>
  Require valid-user
</LimitExcept>
top

Directive LimitInternalRecursion

Description:Détermine le nombre maximal de redirections internes et de sous-requêtes imbriquées
Syntaxe:LimitInternalRecursion nombre [nombre]
Défaut:LimitInternalRecursion 10
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Une redirection interne survient, par exemple, quand on utilise la directive Action qui redirige en interne la requête d'origine vers un script CGI. Une sous-requête est le mécanisme qu'utilise Apache httpd pour déterminer ce qui se passerait pour un URI s'il faisait l'objet d'une requête. Par exemple, mod_dir utilise les sous-requêtes pour rechercher les fichiers listés dans la directive DirectoryIndex.

La directive LimitInternalRecursion permet d'éviter un crash du serveur dû à un bouclage infini de redirections internes ou de sous-requêtes. De tels bouclages sont dus en général à des erreurs de configuration.

La directive accepte, comme arguments, deux limites qui sont évaluées à chaque requête. Le premier nombre est le nombre maximum de redirections internes qui peuvent se succéder. Le second nombre détermine la profondeur d'imbrication maximum des sous-requêtes. Si vous ne spécifiez qu'un seul nombre, il sera affecté aux deux limites.

LimitInternalRecursion 5
top

Directive LimitRequestBody

Description:limite la taille maximale du corps de la requête HTTP envoyée par le client
Syntaxe:LimitRequestBody octets
Défaut:LimitRequestBody 1073741824
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core
Compatibilité:Dans les versions 2.4.53 et antérieures du serveur HTTP Apache, la valeur par défaut était 0 (aucune limite)

Cette directive permet de spécifier la taille maximale d'un corps de requête, en octets. Une valeur de 0 signifie « sans limites ».

La directive LimitRequestBody permet de définir une limite pour la taille maximale autorisée du corps d'une requête HTTP en tenant compte du contexte dans lequel la directive a été placée (c'est à dire au niveau du serveur, d'un répertoire, d'un fichier ou d'une localisation). Si la requête du client dépasse cette limite, le serveur répondra par un message d'erreur et ne traitera pas la requête. La taille du corps d'une requête normale va varier de manière importante en fonction de la nature de la ressource et des méthodes autorisées pour cette dernière. Les scripts CGI utilisent souvent le corps du message pour extraire les informations d'un formulaire. Les implémentations de la méthode PUT nécessitent une valeur au moins aussi élevée que la taille maximale des représentations que le serveur désire accepter pour cette ressource.

L'administrateur du serveur peut utiliser cette directive pour contrôler plus efficacement les comportements anormaux des requêtes des clients, ce qui lui permettra de prévenir certaines formes d'attaques par déni de service.

Si par exemple, vous autorisez le chargement de fichiers vers une localisation particulière, et souhaitez limiter la taille des fichiers chargés à 100Ko, vous pouvez utiliser la directive suivante :

LimitRequestBody 102400
top

Directive LimitRequestFields

Description:Limite le nombre de champs d'en-tête autorisés dans une requête HTTP
Syntaxe:LimitRequestFields nombre
Défaut:LimitRequestFields 100
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

nombre est un entier de 0 à 32767. La valeur 0 signifie un nombre de champs illimité. La valeur par défaut est définie à la compilation par la constante DEFAULT_LIMIT_REQUEST_FIELDS (100 selon la distribution).

La directive LimitRequestFields permet à l'administrateur du serveur de modifier le nombre maximum de champs d'en-tête autorisés dans une requête HTTP. Pour un serveur, cette valeur doit être supérieure au nombre de champs qu'une requête client normale peut contenir. Le nombre de champs d'en-tête d'une requête qu'un client utilise dépasse rarement 20, mais ce nombre peut varier selon les implémentations des clients, et souvent en fonction des extensions que les utilisateurs configurent dans leurs navigateurs pour supporter la négociation de contenu détaillée. Les extensions HTTP optionnelles utilisent souvent les champs d'en-tête des requêtes.

L'administrateur du serveur peut utiliser cette directive pour contrôler plus efficacement les comportements anormaux des requêtes des clients, ce qui lui permettra de prévenir certaines formes d'attaques par déni de service. La valeur spécifiée doit être augmentée si les clients standards reçoivent une erreur du serveur indiquant que la requête comportait un nombre d'en-têtes trop important.

Par exemple :

LimitRequestFields 50

Avertissement

Dans le cas des serveurs virtuels à base de noms, la valeur de cette directive est extraite du serveur virtuel par défaut (le premier de la liste) pour la paire adresse IP/port.

top

Directive LimitRequestFieldSize

Description:Dédinit la taille maximale autorisée d'un en-tête de requête HTTP
Syntaxe:LimitRequestFieldSize octets
Défaut:LimitRequestFieldSize 8190
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Cette directive permet de définir le nombre maximum d'octets autorisés dans un en-tête de requête HTTP.

La directive LimitRequestFieldSize permet à l'administrateur du serveur de définir la taille maximale autorisée d'un en-tête de requête HTTP. Pour un serveur, cette valeur doit être suffisamment grande pour contenir tout en-tête d'une requête client normale. La taille d'un champ d'en-tête de requête normal va varier selon les implémentations des clients, et en fonction des extensions que les utilisateurs configurent dans leurs navigateurs pour supporter la négociation de contenu détaillée. Les en-têtes d'authentification SPNEGO peuvent atteindre une taille de 12392 octets.

L'administrateur du serveur peut utiliser cette directive pour contrôler plus efficacement les comportements anormaux des requêtes des clients, ce qui lui permettra de prévenir certaines formes d'attaques par déni de service.

Par exemple :

LimitRequestFieldSize 4094
Dans des conditions normales, la valeur par défaut de cette directive ne doit pas être modifiée.

Avertissement

Dans le cas des serveurs virtuels à base de noms, la valeur de cette directive est extraite du serveur virtuel par défaut (le premier de la liste) pour lequel la paire adresse IP/port correspond le mieux.

top

Directive LimitRequestLine

Description:Définit la taille maximale d'une ligne de requête HTTP
Syntaxe:LimitRequestLine octets
Défaut:LimitRequestLine 8190
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Cette directive permet de définir la taille maximale autorisée pour une ligne de requête HTTP en octets.

La directive LimitRequestLine permet à l'administrateur du serveur de définir la taille maximale autorisée d'une ligne de requête HTTP client. Comme une requête comporte une méthode HTTP, un URI, et une version de protocole, la directive LimitRequestLine impose une restriction sur la longueur maximale autorisée pour un URI dans une requête au niveau du serveur. Pour un serveur, cette valeur doit être suffisamment grande pour référencer les noms de toutes ses ressources, y compris toutes informations pouvant être ajoutées dans la partie requête d'une méthode GET.

L'administrateur du serveur peut utiliser cette directive pour contrôler plus efficacement les comportements anormaux des requêtes des clients, ce qui lui permettra de prévenir certaines formes d'attaques par déni de service.

Par exemple :

LimitRequestLine 4094
Dans des conditions normales, cette directive doit conserver sa valeur par défaut.

Avertissement

Dans le cas des serveurs virtuels à base de noms, la valeur de cette directive est extraite du serveur virtuel par défaut (le premier de la liste) pour lequel la paire adresse IP/port correspond le mieux.

top

Directive LimitXMLRequestBody

Description:Définit la taille maximale du corps d'une requête au format XML
Syntaxe:LimitXMLRequestBody octets
Défaut:LimitXMLRequestBody 1000000
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

Taille maximale (en octets) du corps d'une requête au format XML. Une valeur de 0 appliquera une limite physique (différente selon que le système est sur 32 ou 64 bits) permettant à XML de s'étaler jusqu'aux limites de la mémoire adressable du système, mais elle n'existe qu'à des fins de compatibilité et il est déconseillé de l'utiliser car elle ne tient pas compte de la mémoire consommée ailleurs et des requêtes simultanées, ce qui pourrait provoquer un dépassement de mémoire global du système.

Exemple :

# Limitation à 1 Mo
LimitXMLRequestBody 1048576
top

Directive <Location>

Description:N'applique les directives contenues qu'aux URLs spécifiées
Syntaxe:<Location chemin URL|URL> ... </Location>
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive <Location> limite la portée des directives contenues aux URLs définies par l'argument URL. Elle est similaire à la directive <Directory>, et marque le début d'une section qui se termine par une directive </Location>. Les sections <Location> sont traitées selon l'ordre dans lequel elles apparaissent dans le fichier de configuration, mais après les sections <Directory> et la lecture des fichiers .htaccess, et après les sections <Files>.

Les sections <Location> agissent complètement en dehors du système de fichiers. Ceci a de nombreuses conséquences. Parmi les plus importantes, on ne doit pas utiliser les sections <Location> pour contrôler l'accès aux répertoires du système de fichiers. Comme plusieurs URLs peuvent correspondre au même répertoire du système de fichiers, un tel contrôle d'accès pourrait être contourné.

Les directives que contient cette section seront appliquées aux requêtes si la partie chemin de l'URL satisfait à l'un au moins de ces critères :

Dans l'exemple ci-dessous, où aucun slash de fin n'est utilisé, les directives contenues dans la section s'appliqueront à /private1, /private1/ et /private1/file.txt, mais pas à /private1other.

<Location "/private1">
    #  ...
</Location>

De même, dans l'exemple ci-dessous, où l'on utilise un slash de fin, les directives contenues dans la section s'appliqueront à /private2/ et à /private2/file.txt, mais pas à /private2other.

<Location "/private2/">
    # ...
</Location>

Quand utiliser la section <Location>

Vous pouvez utiliser une section <Location> pour appliquer des directives à des contenus situés en dehors du système de fichiers. Pour les contenus situés à l'intérieur du système de fichiers, utilisez plutôt les sections <Directory> et <Files>. <Location "/"> constitue une exception et permet d'appliquer aisément une configuration à l'ensemble du serveur.

Pour toutes les requêtes originales (non mandatées), l'argument URL est un chemin d'URL de la forme /chemin/. Aucun protocole, nom d'hôte, port, ou chaîne de requête ne doivent apparaître. Pour les requêtes mandatées, l'URL spécifiée doit être de la forme protocole://nom_serveur/chemin, et vous devez inclure le préfixe.

L'URL peut contenir des caractères génériques. Dans une chaîne avec caractères génériques, ? correspond à un caractère quelconque, et * à toute chaîne de caractères. Les caractères génériques ne peuvent pas remplacer un / dans le chemin URL.

On peut aussi utiliser les Expressions rationnelles, moyennant l'addition d'un caractère ~. Par exemple :

<Location ~ "/(extra|special)/data">
    #...
</Location>

concernerait les URLs contenant les sous-chaîne /extra/data ou /special/data. La directive <LocationMatch> présente un comportement identique à la version avec expressions rationnelles de la directive <Location>, et son utilisation est préférable à l'utilisation de cette dernière pour la simple raison qu'il est difficile de distinguer ~ de - dans la plupart des fontes.

La fonctionnalité <Location> est particulièrement utile avec la directive SetHandler. Par exemple, pour activer les requêtes d'état, mais ne les autoriser que depuis des navigateurs appartenant au domaine example.com, vous pouvez utiliser :

<Location "/status">
  SetHandler server-status
  Require host example.com
</Location>

Note à propos du slash (/)

La signification du caractère slash dépend de l'endroit où il se trouve dans l'URL. Les utilisateurs peuvent être habitués à son comportement dans le système de fichiers où plusieurs slashes successifs sont souvent réduits à un slash unique (en d'autres termes, /home///foo est identique à /home/foo). Dans l'espace de nommage des URLs, ce n'est cependant pas toujours vrai si la directive MergeSlashes a été définie à "OFF". Pour la directive <LocationMatch> et la version avec expressions rationnelles de la directive <Location>, vous devez spécifier explicitement les slashes multiples si les slashes ne sont pas fusionnés.

Par exemple, <LocationMatch "^/abc"> va correspondre à l'URL /abc mais pas à l'URL //abc. La directive <Location> sans expression rationnelle se comporte de la même manière lorsqu'elle est utilisée pour des requêtes mandatées. Par contre, lorsque la directive <Location> sans expression rationnelle est utilisée pour des requêtes non mandatées, elle fera correspondre implicitement les slashes multiples à des slashes uniques. Par exemple, si vous spécifiez <Location "/abc/def">, une requête de la forme /abc//def correspondra.

Voir aussi

top

Directive <LocationMatch>

Description:N'applique les directives contenues qu'aux URLs correspondant à une expression rationnelle
Syntaxe:<LocationMatch regex> ... </LocationMatch>
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive <LocationMatch> limite la portée des directives contenues à l'URL spécifiée, de manière identique à la directive <Location>. Mais son argument permettant de spécifier les URLs concernées est une expression rationnelle au lieu d'une simple chaîne de caractères. Par exemple :

<LocationMatch "/(extra|special)/data">
    # ...
</LocationMatch>

correspondrait à toute URL contenant les sous-chaînes /extra/data ou /special/data.

Si vous recherchez une URL commençant par plutôt que seulement contenant /extra/data, préfixez l'expression rationnelle avec un ^.

<LocationMatch "^/(extra|special)/data">

A partir de la version 2.4.8, les groupes nommés et les références arrières sont extraits et enregistrés dans l'environnement avec leur nom en majuscules et préfixé par "MATCH_". Ceci permet de référencer des URLs dans des expressions ou au sein de modules comme mod_rewrite. Pour éviter toute confusion, les références arrières numérotées (non nommées) sont ignorées. Vous devez utiliser à la place des groupes nommés.

<LocationMatch "^/combined/(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</LocationMatch>

Note à propos du slash '/'

La signification du caractère slash '/' dépend de l'endroit où il apparaît dans une URL. Les utilisateurs sont habitués à voir de multiples slashes adjacents réduits à un seul au sein du système de fichiers (par exemple, /home///foo est équivalent à /home/foo). Ce n'est n'est cependant pas toujours vrai au sein des URLs si la directive MergeSlashes a été définie à "OFF". En effet, si vous souhaitez spécifier plusieurs slashes, vous devez le faire explicitement au sein de la directive <LocationMatch> et de la version regex de la directive <Location>, si les slashes ne sont pas fusionnés.

Par exemple, <LocationMatch "^/abc"> correspondra à l'URL /abc, mais pas à l'URL //abc. La directive (non-regex) <Location> se comporte de la même manière lorsqu'elle est utilisée dans les requêtes de mandataire. Par contre, pour les autres types de requêtes, la directive <Location> considérera plusieurs slashes adjacents comme équivalents à un seul slash. Par exemple, si vous spécifiez <Location "/abc/def">, une requête pour /abc//def correspondra.

Voir aussi

top

Directive LogLevel

Description:Contrôle la verbosité du journal des erreurs
Syntaxe:LogLevel [module:]niveau [module:niveau] ...
Défaut:LogLevel warn
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core
Compatibilité:La configuration du niveau de journalisation par module et par répertoire est disponible depuis la version 2.3.6 du serveur HTTP Apache

La directive LogLevel permet d'ajuster la verbosité des messages enregistrés dans les journaux d'erreur (voir la directive ErrorLog directive). Les niveaux disponibles sont présentés ci-après, par ordre de criticité décroissante :

Niveau Description Exemple
emerg Urgences - le système est inutilisable. "Child cannot open lock file. Exiting"
alert Des mesures doivent être prises immédiatement. "getpwuid: couldn't determine user name from uid"
crit Conditions critiques. "socket: Failed to get a socket, exiting child"
error Erreurs. "Premature end of script headers"
warn Avertissements. "child process 1234 did not exit, sending another SIGHUP"
notice Evènement important mais normal. "httpd: caught SIGBUS, attempting to dump core in ..."
info Informations. "Server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers)..."
debug Messages de débogage. "Opening config file ..."
trace1 Messages de traces "proxy: FTP: control connection complete"
trace2 Messages de traces "proxy: CONNECT: sending the CONNECT request to the remote proxy"
trace3 Messages de traces "openssl: Handshake: start"
trace4 Messages de traces "read from buffered SSL brigade, mode 0, 17 bytes"
trace5 Messages de traces "map lookup FAILED: map=rewritemap key=keyname"
trace6 Messages de traces "cache lookup FAILED, forcing new map lookup"
trace7 Messages de traces, enregistrement d'une grande quantité de données "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"
trace8 Messages de traces, enregistrement d'une grande quantité de données "| 0000: 02 23 44 30 13 40 ac 34 df 3d bf 9a 19 49 39 15 |"

Lorsqu'un niveau particulier est spécifié, les messages de tous les autres niveaux de criticité supérieure seront aussi enregistrés. Par exemple, si LogLevel info est spécifié, les messages de niveaux notice et warn seront aussi émis.

Il est recommandé d'utiliser un niveau crit ou inférieur.

Par exemple :

LogLevel notice

Note

Si la journalisation s'effectue directement dans un fichier, les messages de niveau notice ne peuvent pas être supprimés et sont donc toujours journalisés. Cependant, ceci ne s'applique pas lorsque la journalisation s'effectue vers syslog.

Spécifier un niveau sans nom de module va attribuer ce niveau à tous les modules. Spécifier un niveau avec nom de module va attribuer ce niveau à ce module seulement. Il est possible de spécifier un module par le nom de son fichier source ou par son identificateur, avec ou sans le suffixe _module. Les trois spécifications suivantes sont donc équivalentes :

LogLevel info ssl:warn
LogLevel info mod_ssl.c:warn
LogLevel info ssl_module:warn

Il est aussi possible d'attribuer un niveau de journalisation par répertoire :

LogLevel info
<Directory "/usr/local/apache/htdocs/app">
  LogLevel debug
</Directory>
La configuration du niveau de journalisation par répertoire n'affecte que les messages journalisés après l'interprétation de la requête et qui sont associés à cette dernière. Les messages de journalisation associés à la connexion ou au serveur ne sont pas affectés.

Voir aussi

top

Directive MaxKeepAliveRequests

Description:Nombre de requêtes permises pour une connexion persistante
Syntaxe:MaxKeepAliveRequests nombre
Défaut:MaxKeepAliveRequests 100
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive MaxKeepAliveRequests permet de limiter le nombre de requêtes autorisées par connexion lorsque KeepAlive est à "on". Si sa valeur est 0, le nombre de requêtes autorisées est illimité. Il est recommandé de définir une valeur assez haute pour des performances du serveur maximales.

Par exemple :

MaxKeepAliveRequests 500
top

Directive MaxRangeOverlaps

Description:Nombre de chevauchements de segments de données autorisé (par exemple 100-200,150-300) avant le renvoi de la ressource complète
Syntaxe:MaxRangeOverlaps default | unlimited | none | nombre de chevauchements
Défaut:MaxRangeOverlaps 20
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core
Compatibilité:Disponible depuis la version 2.3.15 du serveur HTTP Apache

La directive MaxRangeOverlaps permet de limiter le nombre de chevauchements de segments de données HTTP autorisé par le serveur. Si le nombre de chevauchements de segments demandé est supérieur au nombre maximal autorisé, la ressource sera renvoyée dans son intégralité.

default
Limite le nombre de chevauchements de segments à la valeur par défaut 20 définie à la compilation.
none
Aucun chevauchement de segment n'est autorisé.
unlimited
Le nombre de chevauchements de segments est illimité.
number-of-ranges
Un nombre positif représente le nombre maximal de chevauchements de segments autorisé par le serveur.
top

Directive MaxRangeReversals

Description:Nombre d'inversions d'ordre autorisé dans la spécification des segments de données (par exemple 100-200,50-70) avant le renvoi de la ressource complète
Syntaxe:MaxRangeReversals default | unlimited | none | nombre d'inversions
Défaut:MaxRangeReversals 20
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core
Compatibilité:Disponible depuis la version 2.3.15 du serveur HTTP Apache

La directive MaxRangeReversals permet de limiter le nombre d'inversions d'ordre dans la spécification des segments de données HTTP autorisé par le serveur. Si le nombre d'inversions demandé est supérieur au nombre maximal autorisé, la ressource sera renvoyée dans son intégralité.

default
Limite le nombre d'inversions à la valeur par défaut 20 définie à la compilation.
none
Aucune inversion n'est autorisée.
unlimited
Le nombre d'inversions est illimité.
number-of-ranges
Un nombre positif représente le nombre maximal d'inversions autorisé par le serveur.
top

Directive MaxRanges

Description:Nombre de segments de données autorisé avant le renvoi de l'intégralité de la ressource
Syntaxe:MaxRanges default | unlimited | none | nombre de segments
Défaut:MaxRanges 200
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core
Compatibilité:Disponible depuis la version 2.3.15 du serveur HTTP Apache

La directive MaxRanges permet de limiter le nombre de segments de données que le serveur va renvoyer au client. Si un nombre de segments plus important est demandé, la ressource sera renvoyée dans son intégralité.

default
Limite le nombre de segments de données à 200 (valeur par défaut définie à la compilation).
none
Les en-têtes Range sont ignorés.
unlimited
Le nombre de segments de données est illimité.
nombre de segments
Un nombre positif représentera la nombre de segments de données maximal que le serveur renverra au client.
top

Directive MergeSlashes

Description:Fusion des slashes consécutifs dans les URLs par le serveur.
Syntaxe:MergeSlashes ON|OFF
Défaut:MergeSlashes ON
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.39 du serveur HTTP Apache

Par défaut, le serveur fusionne les caractères slash ('/') multiples et consécutifs dans la partie chemin de l'URL d'une requête.

Lorsque cette partie chemin de l'URL est appliquée au système de fichiers, ces slashes multiples sont inutiles. Il peut être cependant préférable de conserver ces slashes multiples et consécutifs car ils peuvent avoir une signification dans le cas des URLs gérées différemment, par exemple par CGI ou par un serveur mandataire. Il convient alors de définir MergeSlashes à OFF pour conserver les slashes multiples consécutifs, ce qui correspond au comportement traditionnel.

Lorsque cette directive est définie à "OFF", les expressions rationnelles utilisées dans le fichier de configuration pour effectuer une comparaison de la partie chemin de l'URL ((LocationMatch, RewriteRule, ...) doivent en effet tenir compte de la présence éventuelle de slashes multiples et consécutifs. Les sections Location à base d'expressions non rationnelles correspondent toujours à des URLs avec slashes fusionnés et ne peuvent pas tenir compte des slashes multiples.

top

Directive MergeTrailers

Description:Détermine si les données supplémentaires (trailers) sont fusionnées avec les en-têtes
Syntaxe:MergeTrailers [on|off]
Défaut:MergeTrailers off
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.11 du serveur HTTP Apache

Cette directive permet de contrôler la fusion des données HTTP supplémentaires (trailers) avec la représentation interne des en-têtes. Cette fusion intervient lorsque le corps de la requête a été entièrement reçu, bien longtemps après que la majeure partie du traitement des en-têtes ait une chance de pouvoir examiner ou modifier les en-têtes de la requête.

Cette option a été introduite dans un souci de compatibilité avec les versions antérieures à 2.4.11, où les données supplémentaires étaient systématiquement fusionnées avec les en-têtes de la requête.

top

Directive Mutex

Description:Définit les mécanismes de mutex et le repertoire du fichier verrou pour tous les mutex ou seulement les mutex spécifiés
Syntaxe:Mutex mécanisme [default|nom-mutex] ... [OmitPID]
Défaut:Mutex default
Contexte:configuration globale
Statut:Noyau httpd
Module:core
Compatibilité:Disponible depuis la version 2.3.4 du serveur HTTP Apache

La directive Mutex permet de définir le mécanisme de mutex, et éventuellement le répertoire du fichier verrou que les modules et httpd utilisent pour sérialiser l'accès aux ressources. Spécifiez default comme second argument pour modifier la configuration de tous les mutex ; spécifiez un nom de mutex (voir la table ci-dessous) comme second argument pour ne modifier que la configuration de ce mutex.

La directive Mutex est typiquement utilisée dans les situations exceptionnelles suivantes :

Modules supportés

Cette directive ne configure que les mutex qui ont été enregistrés avec le serveur de base via l'API ap_mutex_register(). Tous les modules fournis avec httpd supportent la directive Mutex, mais il n'en sera pas forcément de même pour les modules tiers. Reportez-vous à la documentation du module tiers considéré afin de déterminer le(s) nom(s) de mutex qui pourront être définis si la directive est supportée.

Les mécanismes de mutex disponibles sont les suivants :

La plupart des mécanismes ne sont disponibles que sur les plate-formes où ces dernières et APR les supportent. Les mécanismes qui ne sont pas disponibles sur toutes les plate-formes sont posixsem, sysvsem, sem, pthread, fcntl, flock, et file.

Avec les mécanismes à base de fichier fcntl et flock, le chemin, s'il est fourni, est un répertoire dans lequel le fichier verrou sera créé. Le répertoire par défaut est le répertoire d'exécution de httpd relatif à la directive ServerRoot. Utilisez toujours un système de fichiers local sur disque pour /chemin/vers/mutex et jamais un répertoire se trouvant dans un système de fichiers NFS ou AFS. Le nom de base du fichier se composera du type de mutex, d'une chaîne optionnelle correspondant à l'instance et fournie par le module ; et, sauf si le mot-clé OmitPID a été spécifié, l'identificateur du processus parent httpd sera ajouté afin de rendre le nom du fichier unique, évitant ainsi tout conflit lorsque plusieurs instances d'httpd partagent le même répertoire de verrouillage. Par exemple, si le nom de mutex est mpm-accept, et si le répertoire de verrouillage est /var/httpd/locks, le nom du fichier verrou pour l'instance httpd dont le processus parent a pour identifiant 12345 sera /var/httpd/locks/mpm-accept.12345.

Sécurité

Il est conseillé d'éviter de placer les fichiers mutex dans un répertoire où tout le monde peut écrire comme /var/tmp, car quelqu'un pourrait initier une attaque par déni de service et empêcher le serveur de démarrer en créant un fichier verrou possédant un nom identique à celui que le serveur va tenter de créer.

La table suivante décrit les noms de mutex utilisés par httpd et ses modules associés.

Nom mutex Module(s) Ressource protégée
mpm-accept modules MPM prefork et worker connexions entrantes, afin d'éviter le problème de l'afflux de requêtes ; pour plus d'informations, voir la documentation Amélioration des performances
authdigest-client mod_auth_digest liste de clients en mémoire partagée
authdigest-opaque mod_auth_digest compteur en mémoire partagée
ldap-cache mod_ldap cache de résultat de recherche LDAP
rewrite-map mod_rewrite communication avec des programmes externes d'associations de valeurs, afin d'éviter les interférences d'entrées/sorties entre plusieurs requêtes
ssl-cache mod_ssl cache de session SSL
ssl-stapling mod_ssl cache de l'étiquetage OCSP ("OCSP stapling")
watchdog-callback mod_watchdog fonction de rappel d'un module client particulier

Le mot-clé OmitPID permet d'empêcher l'addition de l'identifiant du processus httpd parent au nom du fichier verrou.

Dans l'exemple suivant, le mécanisme de mutex pour le mutex mpm-accept est modifié pour passer du mécanisme par défaut au mécanisme fcntl, avec le fichier verrou associé créé dans le répertoire /var/httpd/locks. Le mécanisme de mutex par défaut pour tous les autres mutex deviendra sysvsem.

Mutex sysvsem default
Mutex fcntl:/var/httpd/locks mpm-accept
top

Directive NameVirtualHost

Description:OBSOLETE : Définit une adresse IP pour les serveurs virtuels à base de nom
Syntaxe:NameVirtualHost adresse[:port]
Contexte:configuration globale
Statut:Noyau httpd
Module:core

Avant la version 2.3.11, il était nécessaire de définir une directive NameVirtualHost pour indiquer au serveur qu'une paire adresse IP/port particulière pouvait être utilisée comme serveur virtuel à base de nom. Depuis la version 2.3.11, chaque fois qu'une paire adresse IP/port est utilisée dans plusieurs serveurs virtuels, l'hébergement virtuel à base de nom est automatiquement activé pour cette adresse.

Cette directive n'a actuellement plus aucun effet.

Voir aussi

top

Directive Options

Description:Définit les fonctionnalités disponibles pour un répertoire particulier
Syntaxe:Options [+|-]option [[+|-]option] ...
Défaut:Options FollowSymlinks
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Noyau httpd
Module:core
Compatibilité:Avec la version 2.3.11, la valeur par défaut passe de All à FollowSymlinks

La directive Options permet de définir les fonctionnalités de serveur disponibles pour un répertoire particulier.

option peut être défini à None, auquel cas aucune fonctionnalité spécifique n'est activée, ou comprendre une ou plusieurs des options suivantes :

All
Toutes les options excepté MultiViews.
ExecCGI
L'exécution de scripts CGI à l'aide du module mod_cgi est permise.
FollowSymLinks
Le serveur va suivre les liens symboliques dans le répertoire concerné. Il s'agit de la valeur par défaut.

Bien que le serveur suive les liens symboliques, il ne modifie pas le nom de chemin concerné défini par la section <Directory>.

Les options FollowSymLinks et SymLinksIfOwnerMatch ne fonctionnent que dans les sections <Directory> ou les fichiers .htaccess.

Le fait d'omettre cette option ne doit pas être considéré comme une mesure de sécurité efficace, car il existe toujours une situation de compétition (race condition) entre l'instant où l'on vérifie qu'un chemin n'est pas un lien symbolique, et l'instant où l'on utilise effectivement ce chemin.

Includes
Les inclusions côté serveur (SSI) à l'aide du module mod_include sont autorisées.
IncludesNOEXEC
Les inclusions côté serveur (SSI) sont permises, mais #exec cmd et #exec cgi sont désactivés. L'utilisation de #include virtual pour les scripts CGI est cependant toujours possible depuis des répertoires définis par ScriptAlias.
Indexes
Si une URL requise correspond au répertoire concerné, et si aucun DirectoryIndex (par exemple index.html) n'est défini pour ce répertoire, le module mod_autoindex va renvoyer un listing formaté du répertoire.
MultiViews
Les vues multiples ("multiviews") à contenu négocié à l'aide du module mod_negotiation sont autorisées.

Note

Cette option est ignorée si elle est définie en tout autre endroit qu'une section <Directory>, car mod_negotiation a besoin de ressources réelles pour effectuer ses comparaisons et ses évaluations.

SymLinksIfOwnerMatch
Le serveur ne suivra que les liens symboliques qui renvoient vers un fichier ou un répertoire dont le propriétaire est le même que celui du lien.

Note

Les options FollowSymLinks et SymLinksIfOwnerMatch ne fonctionnent que dans les sections <Directory> ou les fichiers .htaccess.

Le fait d'omettre cette option ne doit pas être considéré comme une mesure de sécurité efficace, car il existe toujours une situation de compétition (race condition) entre l'instant où l'on vérifie qu'un chemin n'est pas un lien symbolique, et l'instant où l'on utilise effectivement ce chemin.

Normalement, si plusieurs directives Options peuvent s'appliquer à un répertoire, c'est la plus spécifique qui est utilisée et les autres sont ignorées ; les options ne sont pas fusionnées (voir comment les sections sont fusionnées). Elles le sont cependant si toutes les options de la directive Options sont précédées d'un symbole + ou -. Toute option précédée d'un + est ajoutée à la liste des options courantes de manière forcée et toute option précédée d'un - est supprimée de la liste des options courantes de la même manière.

Note

Mélanger des Options avec + ou - avec des Options sans + ou - constitue une erreur de syntaxe, et la vérification de la syntaxe au cours du démarrage du serveur fera échouer ce dernier.

Par exemple, sans aucun symbole + et - :

<Directory "/web/docs">
  Options Indexes FollowSymLinks
</Directory>

<Directory "/web/docs/spec">
  Options Includes
</Directory>

ici, seule l'option Includes sera prise en compte pour le répertoire /web/docs/spec. Par contre, si la seconde directive Options utilise les symboles + et - :

<Directory "/web/docs">
  Options Indexes FollowSymLinks
</Directory>

<Directory "/web/docs/spec">
  Options +Includes -Indexes
</Directory>

alors, les options FollowSymLinks et Includes seront prises en compte pour le répertoire /web/docs/spec.

Note

L'utilisation de -IncludesNOEXEC ou -Includes désactive complètement les inclusions côté serveur sans tenir compte des définitions précédentes.

En l'absence de toute définition d'options, la valeur par défaut est FollowSymlinks.

top

Directive Protocol

Description:Protocole pour une socket d'écoute
Syntaxe:Protocol protocole
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible depuis la version 2.1.5 d'Apache, mais seulement depuis la version 2.3.3 sous Windows.

Cette directive permet de spécifier le protocole utilisé pour une socket d'écoute particulière. Le protocole sert à déterminer quel module doit traiter une requête, et d'appliquer les optimisations spécifiques au protocole via la directive AcceptFilter.

Dans la plupart des configurations, cette directive n'est pas nécessaire. Si elle n'est pas définie, le protocole par défaut pour le port 443 est https et http pour tous les autres ports. La connaissance du protocole permet de déterminer quel module doit traiter la requête, et d'appliquer les optimisations spécifiques au protocole via la directive AcceptFilter.

Par exemple, si vous travaillez avec le protocole https sur un port non standard, spécifiez le protocole de manière explicite :

Protocol https

Vous pouvez aussi spécifier le protocole via la directive Listen.

Voir aussi

top

Directive Protocols

Description:Protocoles disponibles pour un serveur virtuel ou non
Syntaxe:Protocols protocole ...
Défaut:Protocols http/1.1
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.17 du serveur HTTP Apache.

Cette directive permet de spécifier la liste des protocoles supportés par un serveur virtuel ou non. Cette liste énumère les protocoles qu'un client sera autorisé à négocier avec ce serveur.

Par défaut, seul le protocole http/1.1 est disponible (compatible avec les clients http/1.0 et http/0.9). Par conséquent, vous devez fournir cette liste si vous voulez étendre les protocoles disponibles pour le serveur.

Par exemple, si vous voulez autoriser le protocole HTTP/2 pour un serveur avec TLS, utilisez cette directive comme suit :

Protocols h2 http/1.1

Les protocoles valides sont http/1.1 pour les connexions http et https, h2 pour les connections https et h2c pour les connexions http. D'autres modules peuvent fournir d'autres protocoles.

Spécifier des protocoles non disponibles ou désactivés n'aura aucun effet, et ceux-ci seront simplement ignorés.

Si un serveur virtuel ne possède pas de directive Protocols propre, il hérite des protocoles spécifiés pour le serveur principal. Autrement dit, les directives Protocols définies au niveau d'un serveur virtuel remplacent celles définies au niveau du serveur principal.

Voir aussi

top

Directive ProtocolsHonorOrder

Description:Détermine qui du client ou du serveur détermine l'ordre des protocoles au cours de la négociation de la connexion
Syntaxe:ProtocolsHonorOrder On|Off
Défaut:ProtocolsHonorOrder On
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.17 du serveur HTTP Apache.

Cette directive permet de définir si le serveur doit tenir compte de l'ordre des protocoles définis par la directive Protocols.

Si cette directive est définie à Off, l'ordre de la liste des protocoles fournie par le client l'emporte sur l'ordre défini dans la configuration du serveur.

Si la directive ProtocolsHonorOrder est définie à on (valeur par défaut), il n'est pas tenu compte de l'ordre de la liste des protocoles fournie par le client, et seul l'ordre de la liste des protocles définie au niveau du serveur influera la négociation du protocole.

Voir aussi

top

Directive QualifyRedirectURL

Description:Vérifie si la variable d'environnement REDIRECT_URL est pleinement qualifiée
Syntaxe:QualifyRedirectURL On|Off
Défaut:QualifyRedirectURL Off
Contexte:configuration globale, serveur virtuel, répertoire
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:Directive supportée à partir de la version 2.4.18 du serveur HTTP Apache. Jusqu'à la version 2.4.17, le serveur se comportait comme si la directive QualifyRedirectURL était définie à On.

Cette directive permet de s'assurer que le serveur vérifiera que la variable d'environnement REDIRECT_URL est bien pleinement qualifiée. Par défaut, cette variable contient l'URL textuellement demandée par le client, par exemple "/index.html". Avec QualifyRedirectURL ON, la même requête affectera à la variable REDIRECT_URL une valeur du style "http://www.example.com/index.html".

Même si cette directive n'est pas définie, lorsqu'une requête est soumise avec une URL pleinement qualifiée, la variable REDIRECT_URL contiendra quand-même une URL pleinement qualifiée.

top

Directive ReadBufferSize

Description:Taille des tampons utilisés pour lire les données
Syntaxe:ReadBufferSize bytes
Défaut:ReadBufferSize 8192
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.5 du serveur HTTP Apache.

Cette directive permet de définir la taille (en octets) du tampon mémoire utilisé pour lire des données depuis le réseau ou un fichier.

Un tampon de grande taille peut améliorer les performances pour les grandes quantités de données, mais consomme d'avantage de mémoire par connexion. La taille minimale du tampon est de 1024 octets.

top

Directive RegexDefaultOptions

Description:Configuration des options globales par défaut pour les expressions rationnelles
Syntaxe:RegexDefaultOptions [none] [+|-]option [[+|-]option] ...
Défaut:RegexDefaultOptions DOTALL DOLLAR_ENDONLY
Contexte:configuration globale
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.30 du serveur HTTP Apache.

Cette directive permet d'ajouter certains comportements par défaut à TOUTES les expressions rationnelles utilisées ultérieurement.

Toute option précédée d'un '+' est ajoutée aux options déjà définies.
Toute option précédée d'un '-' est enlevée des options déjà définies.
Toute option non suffixée par '+' ou '-' sera définie et remplacera l'option correspondante éventuellement déjà définie.
Le mot-clé none annule toutes les options déjà définies.

option peut être :

ICASE
Utilise une recherche de correspondance insensible à la casse.
EXTENDED
Le drapeau Perl /x ; ignore les espaces non échappés et les commentaires dans le modèle.
DOTALL
Le drapeau Perl /s ; '.' correspond aux caractères nouvelle ligne.
DOLLAR_ENDONLY
'$' n'est actif qu'à la fin de la chaîne de référence.
# Ajoute l'option ICASE par défaut pour toutes les expressions rationnelles
RegexDefaultOptions +ICASE
...
# Supprime l'option DOLLAR_ENDONLY par défaut et conserve toutes les autres
# options
RegexDefaultOptions -DOLLAR_ENDONLY
...
# Définit l'option DOTALL seule et annule toutes les autres options
RegexDefaultOptions DOTALL
...
# Annule toutes les options définies
RegexDefaultOptions none
...
top

Directive RegisterHttpMethod

Description:Enregistrement de méthodes HTTP non standards
Syntaxe:RegisterHttpMethod méthode [méthode [...]]
Contexte:configuration globale
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.24 du serveur HTTP Apache

Cette directive permet d'enregistrer des méthodes HTTP supplémentaires. Ceci s'avérera nécessaire si l'on doit utiliser des méthodes non standards avec des directives qui acceptent des noms de méthodes en paramètres, ou pour permettre l'utilisation de méthodes particulières non standards en passant par un serveur mandataire ou au sein de scripts CGI, et ceci alors que le serveur a été configuré pour ne transmettre que des méthodes reconnues aux modules.

Voir aussi

top

Directive RLimitCPU

Description:Limite le temps CPU alloué aux processus initiés par les processus enfants d'Apache httpd
Syntaxe:RLimitCPU secondes|max [secondes|max]
Défaut:Non défini ; utilise les valeurs par défaut du système d'exploitation
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

Prend 1 ou 2 paramètres. Le premier definit la limite de consommation de ressources pour tous les processus, et le second la consommation de ressources maximale. Les deux paramètres peuvent contenir soit un nombre, soit max pour indiquer au serveur que la limite de consommation correspond à la valeur maximale autorisée par la configuration du système d'exploitation. Pour augmenter la consommation maximale de ressources, le serveur doit s'exécuter en tant que root, ou se trouver dans sa phase de démarrage.

Cette directive s'applique aux processus initiés par les processus enfants d'Apache httpd qui traitent les requêtes, et non aux processus enfants eux-mêmes. Sont concernés les scripts CGI et les commandes exec des SSI, mais en aucun cas les processus initiés par le processus parent d'Apache httpd comme les journalisations redirigées vers un programme.

Les limites de ressources CPU sont exprimées en secondes par processus.

Voir aussi

top

Directive RLimitMEM

Description:Limite la mémoire allouée aux processus initiés par les processus enfants d'Apache httpd
Syntaxe:RLimitMEM octets|max [octets|max]
Défaut:Non défini ; utilise les valeurs par défaut du système d'exploitation
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

Prend 1 ou 2 paramètres. Le premier definit la limite de consommation de ressources pour tous les processus, et le second la consommation de ressources maximale. Les deux paramètres peuvent contenir soit un nombre, soit max pour indiquer au serveur que la limite de consommation correspond à la valeur maximale autorisée par la configuration du système d'exploitation. Pour augmenter la consommation maximale de ressources, le serveur doit s'exécuter en tant que root, ou se trouver dans sa phase de démarrage.

Cette directive s'applique aux processus initiés par les processus enfants d'Apache httpd qui traitent les requêtes, et non aux processus enfants eux-mêmes. Sont concernés les scripts CGI et les commandes exec des SSI, mais en aucun cas les processus initiés par le processus parent d'Apache httpd comme les journalisations redirigées vers un programme.

Les limites de ressources mémoire sont exprimées en octets par processus.

Voir aussi

top

Directive RLimitNPROC

Description:Limite le nombre de processus qui peuvent être initiés par les processus initiés par les processus enfants d'Apache httpd
Syntaxe:RLimitNPROC nombre|max [nombre|max]
Défaut:Unset; uses operating system defaults
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

Prend 1 ou 2 paramètres. Le premier definit la limite de consommation de ressources pour tous les processus, et le second la consommation de ressources maximale. Les deux paramètres peuvent contenir soit un nombre, soit max pour indiquer au serveur que la limite de consommation correspond à la valeur maximale autorisée par la configuration du système d'exploitation. Pour augmenter la consommation maximale de ressources, le serveur doit s'exécuter en tant que root, ou se trouver dans sa phase de démarrage.

Cette directive s'applique aux processus initiés par les processus enfants d'Apache httpd qui traitent les requêtes, et non aux processus enfants eux-mêmes. Sont concernés les scripts CGI et les commandes exec des SSI, mais en aucun cas les processus initiés par le processus parent d'Apache httpd comme les journalisations redirigées vers un programme.

Les limites des processus contrôlent le nombre de processus par utilisateur.

Note

Si les processus CGI s'exécutent sous le même utilisateur que celui du serveur web, cette directive va limiter le nombre de processus que le serveur pourra lui-même créer. La présence de messages cannot fork dans le journal des erreurs indiquera que la limite est atteinte.

Voir aussi

top

Directive ScriptInterpreterSource

Description:Permet de localiser l'interpréteur des scripts CGI
Syntaxe:ScriptInterpreterSource Registry|Registry-Strict|Script
Défaut:ScriptInterpreterSource Script
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:Win32 seulement.

Cette directive permet de contrôler la méthode qu'utilise Apache httpd pour trouver l'interpréteur destiné à exécuter les scripts CGI. La définition par défaut est Script : ceci indique à Apache httpd qu'il doit utiliser l'interpréteur précisé dans la ligne shebang du script (la première ligne, commençant par #!). Sur les systèmes Win32, cette ligne ressemble souvent à ceci :

#!C:/Perl/bin/perl.exe

ou simplement, dans le cas où perl est dans le PATH :

#!perl

Avec ScriptInterpreterSource Registry, Windows va effectuer une recherche dans l'arborescence HKEY_CLASSES_ROOT de la base de registre avec comme mot-clé l'extension du fichier contenant le script (par exemple .pl). C'est la commande définie par la sous-clé de registre Shell\ExecCGI\Command ou, si elle n'existe pas, la sous-clé Shell\Open\Command qui est utilisée pour ouvrir le fichier du script. Si ces clés de registre ne sont pas trouvées, Apache httpd utilise la méthode de l'option Script.

Sécurité

Soyez prudent si vous utilisez ScriptInterpreterSource Registry avec des répertoires faisant l'objet d'un ScriptAlias, car Apache httpd va essayer d'exécuter tous les fichiers contenus dans celui-ci. L'option Registry peut causer des appels de programmes non voulus sur des fichiers non destinés à être exécutés. Par exemple, la commande par défaut open sur les fichiers .htm sur la plupart des systèmes Windows va lancer Microsoft Internet Explorer ; ainsi, toute requête HTTP pour un fichier .htm situé dans le répertoire des scripts va lancer le navigateur en arrière-plan sur le serveur, ce qui a toutes les chances de crasher votre système dans les minutes qui suivent.

L'option Registry-Strict agit de manière identique à Registry, mais n'utilise que la sous-clé Shell\ExecCGI\Command. La présence de la clé ExecCGI n'étant pas systématique, Elle doit être définie manuellement dans le registre Windows et évite ainsi tout appel de programme accidentel sur votre système.

top

Directive SeeRequestTail

Description:Détermine si mod_status affiche les 63 premiers caractères d'une requête ou les 63 derniers, en supposant que la requête elle-même possède plus de 63 caractères.
Syntaxe:SeeRequestTail On|Off
Défaut:SeeRequestTail Off
Contexte:configuration globale
Statut:Noyau httpd
Module:core
Compatibilité:Disponible depuis la version 2.2.7 d'Apache httpd.

Avec ExtendedStatus On, mod_status affiche la véritable requête en cours de traitement. Pour des raisons historiques, seuls 63 caractères de la requête sont réellement stockés à des fins d'affichage. Cette directive permet de déterminer si ce sont les 63 premiers caractères qui seront stockés (c'est le comportement par défaut), ou si ce sont les 63 derniers. Ceci ne s'applique bien entendu que si la taille de la requête est de 64 caractères ou plus.

Si Apache httpd traite la requête GET /disque1/stockage/apache/htdocs/images/rep-images1/nourriture/pommes.jpg HTTP/1.1 , l'affichage de la requête par mod_status se présentera comme suit :

Off (défaut) GET /disque1/stockage/apache/htdocs/images/rep-images1/nourritu
On apache/htdocs/images/rep-images1/nourriture/pommes.jpg HTTP/1.1
top

Directive ServerAdmin

Description:L'adresse électronique que le serveur inclut dans les messages d'erreur envoyés au client
Syntaxe:ServerAdmin adresse électronique|URL
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive ServerAdmin permet de définir l'adresse de contact que le serveur va inclure dans tout message d'erreur qu'il envoie au client. Si le programme httpd ne reconnait pas l'argument fourni comme une URL, il suppose que c'est une adresse électronique, et lui ajoute le préfixe mailto: dans les cibles des hyperliens. Il est cependant recommandé d'utiliser exclusivement une adresse électronique, car de nombreux scripts CGI considèrent ceci comme implicite. Si vous utilisez une URL, elle doit pointer vers un autre serveur que vous contrôlez. Dans le cas contraire, les utilisateurs seraient dans l'impossibilité de vous contacter en cas de problème.

Il peut s'avérer utile de définir une adresse dédiée à l'administration du serveur, par exemple :

ServerAdmin www-admin@foo.example.com

car les utilisateurs ne mentionnent pas systématiquement le serveur dont ils parlent !

top

Directive ServerAlias

Description:Autres noms d'un serveur utilisables pour atteindre des serveurs virtuels à base de nom
Syntaxe:ServerAlias nom serveur [nom serveur] ...
Contexte:serveur virtuel
Statut:Noyau httpd
Module:core

La directive ServerAlias permet de définir les noms alternatifs d'un serveur utilisables pour atteindre des serveurs virtuels à base de nom. La directive ServerAlias peut contenir des caractères génériques, si nécessaire.

<VirtualHost *:80>
  ServerName server.example.com
  ServerAlias server server2.example.com server2
  ServerAlias *.example.com
  UseCanonicalName Off
  # ...
</VirtualHost>

La recherche du serveur virtuel à base de nom correspondant au plus près à la requête s'effectue selon l'ordre d'apparition des directives <virtualhost> dans le fichier de configuration. Le premier serveur virtuel dont le ServerName ou le ServerAlias correspond est choisi, sans priorité particulière si le nom contient des caractères génériques (que ce soit pour ServerName ou ServerAlias).

Tous les noms spécifiés au sein d'une section <VirtualHost> sont traités comme un ServerAlias (sans caractères génériques).

Voir aussi

top

Directive ServerName

Description:Nom d'hôte et port que le serveur utilise pour s'authentifier lui-même
Syntaxe:ServerName [protocole://]nom-de-domaine|adresse-ip[:port]
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive ServerName permet de définir les protocole, nom d'hôte et port d'une requête que le serveur utilise pour s'authentifier lui-même.

La directive ServerName permet (éventuellement en conjonction avec la directive ServerAlias) d'identifier de manière unique un serveur virtuel, lorsqu'elle est utilisée dans un contexte de serveurs virtuels à base de noms.

Cette directive est aussi utilisée lors de la création d'URLs de redirection relatives quand la directive UseCanonicalName est définie à une valeur autre que la valeur par défaut.

Par exemple, si le nom de la machine hébergeant le serveur web est simple.example.com, la machine possède l'alias DNS www.example.com, et si vous voulez que le serveur web s'identifie avec cet alias, vous devez utilisez la définition suivante :

ServerName www.example.com

La directive ServerName peut apparaître à toutes les étapes de la définition du serveur. Toute occurrence annule cependant la précédente (pour ce serveur).

Si la directive ServerName n'est pas définie, le serveur tente de déterminer le nom d'hôte visible du point de vue du client en demandant tout d'abord au système d'exploitation le nom d'hôte système, et en cas d'échec, en effectuant une recherche DNS inverse sur une adresse IP présente sur le système.

Si la directive ServerName ne précise pas de port, le serveur utilisera celui de la requête entrante. Il est recommandé de spécifier un nom d'hôte et un port spécifiques à l'aide de la directive ServerName pour une fiabilité optimale et à titre préventif.

Si vous définissez des serveurs virtuels à base de nom, une directive ServerName située à l'intérieur d'une section <VirtualHost> spécifiera quel nom d'hôte doit apparaître dans l'en-tête de requête Host: pour pouvoir atteindre ce serveur virtuel.

Parfois, le serveur s'exécute en amont d'un dispositif qui implémente SSL, comme un mandataire inverse, un répartiteur de charge ou un boîtier dédié SSL. Dans ce cas, spécifiez le protocole https:// et le port auquel les clients se connectent dans la directive ServerName, afin de s'assurer que le serveur génère correctement ses URLs d'auto-identification.

Voir la description des directives UseCanonicalName et UseCanonicalPhysicalPort pour les définitions qui permettent de déterminer si les URLs auto-identifiantes (par exemple via le module mod_dir) vont faire référence au port spécifié, ou au port indiqué dans la requête du client.

Si la valeur de la directive ServerName ne peut pas être résolue en adresse IP, le démarrage du serveur provoquera un avertissement. httpd va alors utiliser le résultat de la commande système hostname pour déterminer le nom du serveur, ce qui ne correspondra pratiquement jamais au nom de serveur que vous souhaitez réellement.

httpd: Could not reliably determine the server's fully qualified domain name, using rocinante.local for ServerName

Voir aussi

top

Directive ServerPath

Description:Nom de chemin d'URL hérité pour un serveur virtuel à base de nom accédé par un navigateur incompatible
Syntaxe:ServerPath chemin d'URL
Contexte:serveur virtuel
Statut:Noyau httpd
Module:core

La directive ServerPath permet de définir le nom de chemin d'URL hérité d'un hôte, à utiliser avec les serveurs virtuels à base de nom.

Voir aussi

top

Directive ServerRoot

Description:Racine du répertoire d'installation du serveur
Syntaxe:ServerRoot chemin de répertoire
Défaut:ServerRoot /usr/local/apache
Contexte:configuration globale
Statut:Noyau httpd
Module:core

La directive ServerRoot permet de définir le répertoire dans lequel le serveur est installé. En particulier, il contiendra les sous-répertoires conf/ et logs/. Les chemins relatifs indiqués dans les autres directives (comme Include ou LoadModule) seront définis par rapport à ce répertoire.

ServerRoot "/home/httpd"

La valeur par défaut de ServerRoot peut être modifiée via l'argument --prefix de la commande configure, et de nombreuses distributions tierces du serveur proposent une valeur différente de celles listées ci-dessus.

Voir aussi

top

Directive ServerSignature

Description:Définit un pied de page pour les documents générés par le serveur
Syntaxe:ServerSignature On|Off|EMail
Défaut:ServerSignature Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Noyau httpd
Module:core

La directive ServerSignature permet de définir une ligne de pied de page fixe pour les documents générés par le serveur (messages d'erreur, listings de répertoires ftp de mod_proxy, sorties de mod_info, etc...). Dans le cas d'une chaîne de mandataires, l'utilisateur n'a souvent aucun moyen de déterminer lequel des mandataires chaînés a généré un message d'erreur, et c'est une des raisons pour lesquelles on peut être amené à ajouter un tel pied de page.

La valeur par défaut Off supprime la ligne de pied de page. la valeur On ajoute simplement une ligne contenant le numéro de version du serveur ainsi que le nom du serveur virtuel issu de la directive ServerName, alors que la valeur EMail ajoute en plus une référence "mailto:" à l'administrateur du document référencé issu la directive ServerAdmin.

Les détails à propos du numéro de version du serveur sont contrôlés à l'aide de la directive ServerTokens.

Voir aussi

top

Directive ServerTokens

Description:Configure l'en-tête Server de la réponse HTTP
Syntaxe:ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
Défaut:ServerTokens Full
Contexte:configuration globale
Statut:Noyau httpd
Module:core

Cette directive permet de contrôler le contenu de l'en-tête Server inclus dans la réponse envoyée au client : cet en-tête peut contenir le type de système d'exploitation du serveur, ainsi que des informations à propos des modules compilés avec le serveur.

ServerTokens Full (ou non spécifié)
Le serveur envoie par exemple : Server: Apache/2.4.2 (Unix) PHP/4.2.2 MyMod/1.2
ServerTokens Prod[uctOnly]
Le serveur renvoie (par exemple): Server: Apache
ServerTokens Major
Le serveur renvoie (par exemple): Server: Apache/2
ServerTokens Minor
Le serveur renvoie (par exemple): Server: Apache/2.4
ServerTokens Min[imal]
Le serveur renvoie (par exemple): Server: Apache/2.4.2
ServerTokens OS
Le serveur renvoie (par exemple): Server: Apache/2.4.2 (Unix)

Cette définition s'applique à l'ensemble du serveur et ne peut être activée ou désactivée pour tel ou tel serveur virtuel.

Cette directive contrôle aussi les informations fournies par la directive ServerSignature.

Définir ServerTokens à une valeur inférieure à minimal n'est pas recommandé car le débogage des problèmes interopérationnels n'en sera alors que plus difficile. Notez aussi que la désactivation de l'en-tête Server: n'améliore en rien la sécurité de votre serveur ; le concept de "sécurité par l'obscurité" est un mythe et conduit à une mauvaise perception de ce qu'est la sécurité.

Voir aussi

top

Directive SetHandler

Description:Force le traitement des fichiers spécifiés par un gestionnaire particulier
Syntaxe:SetHandler handler-name|none|expression
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core
Compatibilité:L'argument expression est disponible à partir de la version 2.4.19 su serveur HTTP Apache

Lorsqu'elle se situe à l'intérieur d'un fichier .htaccess, ou d'une section <Directory> ou <Location>, cette directive force le traitement de tous les fichiers spécifiés par le gestionnaire défini par l'argument nom gestionnaire. Par exemple, dans le cas d'un répertoire dont vous voulez interpréter le contenu comme des fichiers de règles d'images cliquables, sans tenir compte des extensions, vous pouvez ajouter la ligne suivante dans un fichier .htaccess de ce répertoire :

SetHandler imap-file

Autre exemple : si vous voulez que le serveur affiche un compte-rendu d'état chaque fois qu'une URL du type http://nom serveur/status est appelée, vous pouvez ajouter ceci dans httpd.conf :

<Location "/status">
  SetHandler server-status
</Location>

Vous pouvez aussi utiliser cette directive pour associer un gestionnaire à des fichiers possèdant une extension de nom de fichier particulière. Par exemple :

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

Pour référencer des variables spécifiques à une requête, y compris les références arrières vers des expressions rationnelles nommées, vous pouvez utiliser des expressions ayant pour valeur une chaîne :

<LocationMatch ^/app/(?<sub>[^/]+)/>
     SetHandler "proxy:unix:/var/run/app_%{env:MATCH_sub}.sock|fcgi://localhost:8080"
</LocationMatch>

Vous pouvez écraser la définition antérieure d'une directive SetHandler en utilisant la valeur None.

Note

Comme SetHandler l'emporte sur la définition des gestionnaires par défaut, le comportement habituel consistant à traiter les URLs se terminant par un slash (/) comme des répertoires ou des fichiers index est désactivé.

Voir aussi

top

Directive SetInputFilter

Description:Définit les filtres par lesquels vont passer les requêtes client et les données POST
Syntaxe:SetInputFilter filtre[;filtre...]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core

La directive SetInputFilter permet de définir le ou les filtres par lesquels vont passer les requêtes client et les données POST au moment où le serveur les reçoit. Cette définition vient en ajout à tout autre filtre défini en quelqu'endroit que ce soit, y compris via la directive AddInputFilter.

Si la directive comporte plusieurs filtres, ils doivent être séparés par des points-virgules, et spécifiés selon l'ordre dans lequel vous souhaitez les voir agir sur les contenus.

Voir aussi

top

Directive SetOutputFilter

Description:Définit les filtres par lesquels vont passer les réponses du serveur
Syntaxe:SetOutputFilter filtre[;filtre...]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Noyau httpd
Module:core

La directive SetOutputFilter permet de définir les filtres par lesquels vont passer les réponses du serveur avant d'être envoyées au client. Cette définition vient en ajout à tout autre filtre défini en quelqu'endroit que ce soit, y compris via la directive AddOutputFilter.

Par exemple, la configuration suivante va traiter tous les fichiers du répertoire /www/data/ comme des inclusions côté serveur (SSI) :

<Directory "/www/data/">
  SetOutputFilter INCLUDES
</Directory>

Si la directive comporte plusieurs filtres, ils doivent être séparés par des points-virgules, et spécifiés selon l'ordre dans lequel vous souhaitez les voir agir sur les contenus.

Voir aussi

top

Directive StrictHostCheck

Description:Détermine si le nom d'hôte contenu dans une requête doit être explicitement spécifié au niveau du serveur virtuel qui a pris en compte cette dernière.
Syntaxe:StrictHostCheck ON|OFF
Défaut:StrictHostCheck OFF
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core
Compatibilité:Disponible à partir de la version 2.4.49 du serveur HTTP Apache.

Par défaut, le serveur répond aux requêtes quel que soit le nom d'hôte qu'elles contiennent, y compris un nom d'hôte non prévu dans la configuration. Bien que cela soit pratique, il peut s'avérer souhaitable de restreindre les noms d'hôte qu'une application sous-jacente devra prendre en compte car elle va souvent générer des réponses en se référençant elle-même.

Si la directive StrictHostCheck est définie à ON, le serveur générera une erreur HTTP 400 si le nom d'hôte que contient la requête n'a pas été explicitement spécifié par une directive ServerName ou ServerAlias au niveau du serveur virtuel qui correspond le mieux aux caractéristiques de la connexion entrante.

Cette directive permet aussi de rechercher une correspondance entre le nom d'hôte de la requête et les noms d'hôte spécifiés au sein de la balise ouvrante VirtualHost. Il s'agit cependant d'un mécanisme de configuration relativement obscur qui agit comme une directive ServerAlias supplémentaire.

Cette directive n'a aucun effet dans les serveurs virtuels qui ne sont pas des serveurs par défaut. La valeur héritée de la configuration globale du serveur ou le serveur virtuel par défaut pour l'adresse IP/port de la connexion sous-jacente déterminent la valeur effective.

top

Directive TimeOut

Description:Temps pendant lequel le serveur va attendre certains évènements avant de considérer qu'une requête a échoué
Syntaxe:TimeOut secondes
Défaut:TimeOut 60
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

La directive TimeOut permet de définir le temps maximum pendant lequel Apache httpd va attendre des entrées/sorties selon les circonstances :

top

Directive TraceEnable

Description:Détermine le comportement des requêtes TRACE
Syntaxe:TraceEnable [on|off|extended]
Défaut:TraceEnable on
Contexte:configuration globale, serveur virtuel
Statut:Noyau httpd
Module:core

Cette directive l'emporte sur le comportement de TRACE pour le noyau du serveur et mod_proxy. La définition par défaut TraceEnable on permet des requêtes TRACE selon la RFC 2616, qui interdit d'ajouter tout corps à la requête. La définition TraceEnable off indique au noyau du serveur et à mod_proxy de retourner un code d'erreur 405 (Méthode non autorisée) au client.

En fait, et à des fins de test et de diagnostic seulement, on peut autoriser l'ajout d'un corps de requête à l'aide de la définition non standard TraceEnable extended. Le noyau du serveur (dans le cas d'un serveur d'origine) va limiter la taille du corps de requête à 64Kb (plus 8Kb pour les en-têtes de fractionnement si Transfer-Encoding: chunked est utilisé). Le noyau du serveur va reproduire l'ensemble des en-têtes, y compris les en-têtes de fractionnement avec le corps de la réponse. Dans le cas d'un serveur mandataire, la taille du corps de requête n'est pas limitée à 64Kb.

Note

Bien que certains prétendent le contraire, activer la méthode TRACE ne constitue pas un problème de sécurité dans Apache httpd. La méthode TRACE est définie par la spécification HTTP/1.1 et les différentes implémentations sont censées la supporter.

top

Directive UNCList

Description:Définit quels sont les noms d’hôte UNC auxquels le serveur peut accéder
Syntaxe:UNCList hostname [hostname...]
Défaut:unset
Contexte:configuration globale
Statut:Noyau httpd
Module:core
Compatibilité:Windows seulement. Disponible à partir de la version 2.4.60 du serveur HTTP Apache.

Au cours de leur traitement, les requêtes pour accéder à un chemin du système de fichiers qui aboutissent à un chemin UNC échoueront si le nom d’hôte dans le chemin UNC n’a pas été spécifié par cette directive. Le but est de limiter l’accès aux chemins dérivés d’entrées non fiables.

UNCList example.com other.example.com

Sécurité

Les chemins UNC accédés en dehors du traitement d’une requête, par exemple au cours du démarrage, ne font pas nécessairement l’objet d’une vérification par rapport aux noms d’hôte configurés avec cette directive.

Ordre des directives

Cette directive doit être placée avant les chemins UNC utilisés dans le fichier httpd.conf. Plusieurs occurences de la directive redéfinissent la liste.

top

Directive UnDefine

Description:Invalide la définition d'une variable
Syntaxe:UnDefine nom-variable
Contexte:configuration globale
Statut:Noyau httpd
Module:core

Annule l'effet d'une directive Define ou d'un argument -D de httpd en invalidant l'existence de la variable correspondante.

On peut utiliser cette directive pour inverser l'effet d'une section <IfDefine> sans avoir à modifier les arguments -D dans les scripts de démarrage.

Afin d'éviter tout risque de collision avec la syntaxe de la directive RewriteMap, les noms de variables ne doivent pas contenir de caractère ":".

Piège de la portée de cette directive

Si cette directive est définie au sein d'un bloc VirtualHost, les changements qu'elle induit sont visibles de toute directive ultérieure, au delà de tout bloc VirtualHost.

Voir aussi

top

Directive UseCanonicalName

Description:Définit la manière dont le serveur détermine son propre nom et son port
Syntaxe:UseCanonicalName On|Off|DNS
Défaut:UseCanonicalName Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core

Dans de nombreuses situations, Apache httpd doit construire une URL auto-identifiante -- c'est à dire une URL qui fait référence au serveur lui-même. Avec UseCanonicalName On, Apache httpd va utiliser le nom d'hôte et le port spécifiés par la directive ServerName pour construire le nom canonique du serveur. Ce nom est utilisé dans toutes les URLs auto-identifiantes, et affecté aux variables SERVER_NAME et SERVER_PORT dans les programmes CGI.

Avec UseCanonicalName Off, Apache httpd va construire ses URLs auto-identifiantes à l'aide du nom d'hôte et du port fournis par le client, si ce dernier en a fourni un (dans la négative, Apache utilisera le nom canonique, de la même manière que ci-dessus). Ces valeurs sont les mêmes que celles qui sont utilisées pour implémenter les serveurs virtuels à base de nom, et sont disponibles avec les mêmes clients. De même, les variables CGI SERVER_NAME et SERVER_PORT seront affectées des valeurs fournies par le client.

Cette directive peut s'avérer utile, par exemple, sur un serveur intranet auquel les utilisateurs se connectent en utilisant des noms courts tels que www. Si les utilisateurs tapent un nom court suivi d'une URL qui fait référence à un répertoire, comme http://www/splat, sans le slash terminal, vous remarquerez qu'Apache httpd va les rediriger vers http://www.example.com/splat/. Si vous avez activé l'authentification, ceci va obliger l'utilisateur à s'authentifier deux fois (une première fois pour www et une seconde fois pour www.example.com -- voir la foire aux questions sur ce sujet pour plus d'informations). Par contre, si UseCanonicalName est définie à Off, Apache httpd redirigera l'utilisateur vers http://www/splat/.

Pour l'hébergement virtuel en masse à base d'adresse IP, on utilise une troisième option, UseCanonicalName DNS, pour supporter les clients anciens qui ne fournissent pas d'en-tête Host:. Apache httpd effectue alors une recherche DNS inverse sur l'adresse IP du serveur auquel le client s'est connecté afin de construire ses URLs auto-identifiantes.

Avertissement

Les programmes CGI risquent d'être perturbés par cette option s'ils tiennent compte de la variable SERVER_NAME. Le client est pratiquement libre de fournir la valeur qu'il veut comme nom d'hôte. Mais si le programme CGI n'utilise SERVER_NAME que pour construire des URLs auto-identifiantes, il ne devrait pas y avoir de problème.

Voir aussi

top

Directive UseCanonicalPhysicalPort

Description:Définit la manière dont le serveur détermine son propre port
Syntaxe:UseCanonicalPhysicalPort On|Off
Défaut:UseCanonicalPhysicalPort Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Noyau httpd
Module:core

Dans de nombreuses situations, Apache httpd doit construire une URL auto-identifiante -- c'est à dire une URL qui fait référence au serveur lui-même. Avec UseCanonicalPhysicalPort On, Apache httpd va fournir le numéro de port physique réel utilisé par la requête en tant que port potentiel, pour construire le port canonique afin que le serveur puisse alimenter la directive UseCanonicalName. Avec UseCanonicalPhysicalPort Off, Apache httpd n'utilisera pas le numéro de port physique réel, mais au contraire se référera aux informations de configuration pour construire un numéro de port valide.

Note

L'ordre dans lequel s'effectue la recherche quand on utilise le port physique est le suivant :

UseCanonicalName On
  1. Port indiqué dans Servername
  2. Port physique
  3. Port par défaut pour le contexte/protocole (comme 80 ou 443)
UseCanonicalName Off | DNS
  1. Port spécifié dans l'en-tête Host:
  2. Port physique
  3. Port spécifié par Servername
  4. Port par défaut pour le contexte/protocole (comme 80 ou 443)

Avec UseCanonicalPhysicalPort Off, on reprend l'ordre ci-dessus en supprimant "Port physique".

Voir aussi

top

Directive <VirtualHost>

Description:Contient des directives qui ne s'appliquent qu'à un nom d'hôte spécifique ou à une adresse IP
Syntaxe:<VirtualHost adresse IP[:port] [adresse IP[:port]] ...> ... </VirtualHost>
Contexte:configuration globale
Statut:Noyau httpd
Module:core

Les balises <VirtualHost> et </VirtualHost> permettent de rassembler un groupe de directives qui ne s'appliquent qu'à un serveur virtuel particulier. Toute directive autorisée dans un contexte de serveur virtuel peut être utilisée. Lorsque le serveur reçoit un requête pour un document hébergé par un serveur virtuel particulier, il applique les directives de configuration rassemblées dans la section <VirtualHost>. adresse IP peut être une des entités suivantes, éventuellement suivies d'un caractère ':' et d'un numéro de port (ou *) :

<VirtualHost 10.1.2.3:80>
  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>

Les adresses IPv6 doivent être entourées de crochets car dans le cas contraire, un éventuel port optionnel ne pourrait pas être déterminé. Voici un exemple de serveur virtuel avec adresse IPv6 :

<VirtualHost [2001:db8::a00:20ff:fea7:ccea]:80>
  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>

Chaque serveur virtuel doit correspondre à une adresse IP, un port ou un nom d'hôte spécifique ; dans le premier cas, le serveur doit être configuré pour recevoir les paquets IP de plusieurs adresses (si le serveur n'a qu'une interface réseau, on peut utiliser à cet effet la commande ifconfig alias -- si votre système d'exploitation le permet).

Note

L'utilisation de la directive <VirtualHost> n'affecte en rien les adresses IP sur lesquelles Apache httpd est en écoute. Vous devez vous assurer que les adresses des serveurs virtuels sont bien incluses dans la liste des adresses précisées par la directive Listen.

Tout bloc <VirtualHost> doit comporter une directive ServerName. Dans le cas contraire, le serveur virtuel héritera de la valeur de la directive ServerName issue de la configuration du serveur principal.

A l'arrivée d'une requête, le serveur tente de la faire prendre en compte par la section <VirtualHost> qui correspond le mieux en ne se basant que sur la paire adresse IP/port. Les chaînes sans caractères génériques l'emportent sur celles qui en contiennent. Si aucune correspondance du point de vue de l'adresse IP/port n'est trouvée, c'est la configuration du serveur "principal" qui sera utilisée.

Si plusieurs serveurs virtuels correspondent du point de vue de l'adresse IP/port, le serveur sélectionne celui qui correspond le mieux du point de vue du nom d'hôte de la requête. Si aucune correspondance du point de vue du nom d'hôte n'est trouvée, c'est le premier serveur virtuel dont l'adresse IP/port correspond qui sera utilisé. Par voie de conséquence, le premier serveur virtuel comportant une certaine paire adresse IP/port est le serveur virtuel par défaut pour cette paire adresse IP/port.

Sécurité

Voir le document sur les conseils à propos de sécurité pour une description détaillée des raisons pour lesquelles la sécurité de votre serveur pourrait être compromise, si le répertoire contenant les fichiers journaux est inscriptible par tout autre utilisateur que celui qui démarre le serveur.

Voir aussi

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/core.html.ja.utf80000664000175100017510000077703514743132254020732 0ustar covenercovener core - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache コア機能

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:常に使用可能な Apache HTTP サーバのコア機能
ステータス:Core
Support Apache!

ディレクティブ

Bugfix checklist

参照

top

AcceptFilter ディレクティブ

説明:プロトコルを Listen しているソケットの最適化を設定する
構文:AcceptFilter protocol accept_filter
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:2.1.5 以降

Listen しているソケットに対して、OS が固有に持っているプロトコルについての最適化を 有効にするディレクティブです。大前提となる条件は、データが受信されるか HTTP リクエスト全体がバッファされるかするまで、カーネルがサーバプロセスに ソケットを送らないようになっている、ということです。現在サポートされているのは、 FreeBSD の Accept Filter と Linux のプリミティブな TCP_DEFER_ACCEPT のみです。

FreeBSD のデフォルト値は :

AcceptFilter http httpready
AcceptFilter https dataready

httpready Accept Filter は HTTP リクエスト全体を、 カーネルレベルでバッファリングします。リクエスト全体を受信し終わると、 その後サーバプロセスにそれを送ります。詳細については accf_http(9) を参照してください。HTTPS のリクエストは暗号化されているので accf_data(9) フィルタのみが使用されます。

Linux でのデフォルト値は :

AcceptFilter http data
AcceptFilter https data

Linux の TCP_DEFER_ACCEPT は HTTP リクエストのバッファリングを サポートしていません。none 以外の値で TCP_DEFER_ACCEPT が有効になります。詳細については Linux man ページ tcp(7) を参照してください。

引数に none を指定すると、プロトコルに対する全ての Accept Filter が無効になります。nntp といった、先にサーバにデータを 送る必要のあるプロトコルに有効です :

AcceptFilter nntp none

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 へのリクエストは両方とも /morePATH_INFO とします。

AcceptPathInfo ディレクティブに指定可能な 三つの引数は:

Off
リクエストは存在するパスにそのまま マップされる場合にのみ受け付けられます。ですから、上の例の /test/here.html/more のように、本当のファイル名の 後にパス名情報が続くリクエストには 404 NOT FOUND エラーが返ります。
On
前の方のパスが存在するファイルにマップする場合は リクエストが受け付けられます。上の例の /test/here.html/more/test/here.html が有効なファイルにマップすれば 受け付けられます。
Default
続きのパス名情報の扱いはリクエストの ハンドラで決まります。 普通のファイルのためのコアハンドラのデフォルトは PATH_INFO を拒否します。 cgi-scriptisapi-handler のようにスクリプトを扱うハンドラは 一般的にデフォルトで 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

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 と合わせて 使うときに一番役に立ちます。

符号化されたスラッシュを許可することは、復号をすることを 意味しません%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* ディレクティブなど), ドキュメントのメタデータ (Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName), mod_rewrite のディレクティブ RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule) と mod_actionsAction ディレクティブ。
Indexes
ディレクトリインデックスを制御するためのディレクティブの使用を許可する (AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName など)。
Limit
ホストへのアクセス制御を行うためのディレクティブの使用を許可する (Allow, Deny, Order).
Options[=Option,...]
特定のディレクトリにおける機能を指定するためのディレクティブの使用を許可する (OptionsXBitHack)。 Options で設定するオプション を、(空白を含めない) コンマ区切りのリストにして等号の後に続けることで 設定できます。

例:

AllowOverride AuthConfig Indexes

上の例では AuthConfigIndexes のどちらにも 属さないディレクティブはすべて内部サーバエラーを引き起こします。

参照

top

AllowOverrideList ディレクティブ

説明:Individual directives that are allowed in .htaccess files
構文:AllowOverrideList None|directive [directive-type] ...
デフォルト:AllowOverrideList None
コンテキスト:ディレクトリ
ステータス:Core
モジュール:core

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

CGIMapExtension ディレクティブ

説明:CGI スクリプトのインタープリタの位置を調べるための手法
構文:CGIMapExtension cgi-path .extension
コンテキスト:ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Core
モジュール:core
互換性:NetWare のみ

このディレクティブは Apache が CGI スクリプトを実行するための インタープリタを探す方法を制御します。 例えば、CGIMapExtension sys:\foo.nlm .foo と設定すると .foo という拡張子のすべての CGI スクリプトは FOO インタープリタに 渡されます。

top

CGIPassAuth ディレクティブ

説明:Enables passing HTTP authorization headers to scripts as CGI variables
構文:CGIPassAuth On|Off
デフォルト:CGIPassAuth Off
コンテキスト:ディレクトリ, .htaccess
上書き:AuthConfig
ステータス:Core
モジュール:core
互換性:Available in Apache HTTP Server 2.4.13 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CGIVar ディレクティブ

説明:Controls how some CGI variables are set
構文:CGIVar variable rule
コンテキスト:ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Core
モジュール:core
互換性:Available in Apache HTTP Server 2.4.21 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

ContentDigest ディレクティブ

説明:Content-MD5 HTTP 応答ヘッダの生成を有効にする
構文:ContentDigest On|Off
デフォルト:ContentDigest Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Options
ステータス:Core
モジュール:core

このディレクティブは、RFC1864 及び RFC2616 において定義されている Content-MD5 ヘッダーの生成を有効にします。

MD5 は、任意長のデータの「メッセージダイジェスト」(「指紋」 と表現されることもある) を計算するアルゴリズムで、 データの変更があった場合には非常に高い信頼度でメッセージダイジェストに変更が 反映されます。

Content-MD5 ヘッダは、エンドツーエンドで エンティティボディーに含まれるメッセージの完全性チェック (Message Integrity Check - MIC)を提供します。 このヘッダを調べることで、プロキシやクライアントは、 途中経路におけるエンティティボディの予期せぬ変更などを 検出することができます。ヘッダの例:

Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA==

リクエスト毎にメッセージダイジェストを計算する (値はキャッシュされません) ことから、 サーバパフォーマンスが低下することについて注意してください。

Content-MD5は、core 機能により処理された ドキュメントを送るときのみ有効であり、 SSI ドキュメントや CGI スクリプトの出力、バイトレンジを指定した 応答の場合にはこのヘッダは付与されません。

top

DefaultRuntimeDir ディレクティブ

説明:Base directory for the server run-time files
構文:DefaultRuntimeDir directory-path
デフォルト:DefaultRuntimeDir DEFAULT_REL_RUNTIMEDIR (logs/)
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:Available in Apache 2.4.2 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

DefaultType ディレクティブ

説明:サーバがコンテントタイプを決定できないときに 送られる MIME コンテントタイプ
構文:DefaultType MIME-type|none
デフォルト:DefaultType text/plain
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Core
モジュール:core
互換性:引数 none は Apache 2.2.7 以降で利用可能

サーバは、MIME タイプ のマップからは決定できないドキュメントの送信を要求されることがあります。

サーバは、ドキュメントのコンテントタイプをクライアントに通知するべきです。 サーバで通常の方法ではこれが判定できない場合は、 DefaultType で指定されたタイプを利用します。 例:

DefaultType image/gif

これは .gif という拡張子がファイル名に含まれていない 多くの GIF 画像が含まれているディレクトリに適しているでしょう。

サーバでも管理者でも判定することができない (例えばプロクシの) 場合、 誤った情報を与えるよりは MIME タイプの指定がない状態が望ましいことも あります。この場合は次のようにします :

DefaultType None

DefaultType None は httpd-2.2.7 以降でのみ利用できます。

ForceType ディレクティブと 違って、このディレクティブはデフォルトの MIME タイプを提供するだけで あることに注意してください。ファイル名の拡張子を含め、 メディアタイプを決定できる他の MIME タイプの定義があれば このデフォルトは上書きされます。

top

Define ディレクティブ

説明:変数の存在を宣言する
構文:Define parameter-name
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core

httpd-D 引数と同じものです。

このディレクティブを使うと、スタートアップスクリプトに 記載されている -D 引数を書き換える必要なく、 <IfDefine> セクションを切り替えることができます。

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 への アクセスがあった場合には以下のように動作します:

正規表現は、通常のセクションがすべて適用されるまで 考慮されません。 その後、全ての正規表現が設定ファイルに現れた順で試されます。 例えば、以下のような場合に

<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

<Else> ディレクティブ

説明:Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
構文:<Else> ... </Else>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core
互換性:Nested conditions are evaluated in 2.4.26 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

<ElseIf> ディレクティブ

説明:Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
構文:<ElseIf expression> ... </ElseIf>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core
互換性:Nested conditions are evaluated in 2.4.26 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

EnableMMAP ディレクティブ

説明:配送中にファイルを読み込むためにメモリマッピングを 使うかどうか
構文:EnableMMAP On|Off
デフォルト:EnableMMAP On
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Core
モジュール:core

このディレクティブは配送中にファイルの内容を読み込む必要があるときに httpd がメモリマッピングを使うかどうかを制御します。 デフォルトでは、 例えば、mod_include を使って SSI ファイルを配送 するときのように、ファイルの途中のデータをアクセスする必要があるときには Apache は OS がサポートしていればファイルをメモリにマップします。

このメモリマップは性能の向上をもたらすことがあります。 しかし、環境によっては運用上の問題を防ぐためにメモリマッピングを 使用しないようにした方が良い場合もあります:

これらの問題に当てはまるサーバの設定の場合は、以下のようにして ファイルの配送時のメモリマッピングを使用不可にしてください:

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 を別々に行なうことと、バッファの割り当てを 回避します。しかし、プラットフォームやファイルシステムの中には 運用上の問題を避けるためにこの機能を使用不可にした方が良い場合があります:

これらの問題に当てはまるサーバの設定の場合は、以下のようにして この機能を使用不可にしてください:

EnableSendfile Off

NFS や SMB マウントされたファイルには、問題のあるファイルにのみ明示的に この機能を使用不可にします:

<Directory "/path-to-nfs-files"> EnableSendfile Off </Directory>

top

Error ディレクティブ

説明:Abort configuration parsing with a custom error message
構文:Error message
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Core
モジュール:core
互換性:2.3.9 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

ErrorDocument ディレクティブ

説明:エラーが発生したときにサーバがクライアントに送るもの
構文:ErrorDocument error-code document
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Core
モジュール:core

問題やエラーが発生したときの動作として、 Apache には以下の四つのうち一つの動作を設定することができます。

  1. Apache 標準の簡単なエラーメッセージを表示
  2. 自分で指定したメッセージを表示
  3. 問題やエラーの処理をする為に、自サーバ内の URL-path へリダイレクト
  4. 問題やエラーの処理をする為に、外部の URL へリダイレクト

最初のものがデフォルトの動作で、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

ErrorLogFormat ディレクティブ

説明:Format specification for error log entries
構文: ErrorLogFormat [connection|request] format
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

ExtendedStatus ディレクティブ

説明:Keep track of extended status information for each request
構文:ExtendedStatus On|Off
デフォルト:ExtendedStatus Off[*]
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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 と同じになります。

警告

WebDAV を使っていて、mod_dav_fs をストレージプロバイダとして 使っているような Directory や Location では、デフォルト値を変更しないでください。 mod_dav_fs では、条件付リクエストでの比較演算に INode MTime Size の固定フォーマットを使っています。 FileETagETag フォーマットを 変更してしまうと、条件付リクエストでうまく動作しなくなります。
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

FlushMaxPipelined ディレクティブ

説明:Maximum number of pipelined responses above which they are flushed to the network
構文:FlushMaxPipelined number
デフォルト:FlushMaxPipelined 5
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:2.4.47 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

FlushMaxThreshold ディレクティブ

説明:Threshold above which pending data are flushed to the network
構文:FlushMaxThreshold number-of-bytes
デフォルト:FlushMaxThreshold 65535
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:2.4.47 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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

GprofDir ディレクティブ

説明:Directory to write gmon.out profiling data to.
構文:GprofDir /tmp/gprof/|/tmp/gprof/%
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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

HttpProtocolOptions ディレクティブ

説明:Modify restrictions on HTTP Request Messages
構文:HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0]
デフォルト:HttpProtocolOptions Strict LenientMethods Allow0.9
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:2.2.32 or 2.4.24 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

<If> ディレクティブ

説明:実行時、リクエストが条件を満たした場合にのみ適用される ディレクティブを包含する
構文:<If expression> ... </If>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core

<If> ディレクティブは 実行時に式を評価し、条件式が真になるときにのみ 内包するディレクティブを適用します。 例えば

<If "$req{Host} = ''">

上記例は Host: ヘッダの存在しない HTTP/1.0 のリクエストに マッチします。

参照

top

<IfDefine> ディレクティブ

説明:起動時にテストが真であるときのみに処理されるディレクティブを 囲む
構文:<IfDefine [!]parameter-name> ... </IfDefine>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core

<IfDefine test>...</IfDefine> セクションは、 ディレクティブを条件付きで指定するために利用します。 <IfDefine> セクションに 含まれるディレクティブは、testが 定義されているときのみ処理されます。 もし test が定義されていなければ、 開始と終了の指定の間のディレクティブは無視されます。

<IfDefine> セクションディレクティブに 指定する test は、 次の二つの形式のうちの一つをとります:

前者の場合には、parameter-name と名付けられたパラメータが 定義されていれば開始と終了の間のディレクティブが処理されます。 後者の場合は逆で、parameter-name が指定されていない 場合に処理されます。

parameter-name 引数は、サーバを起動する際に httpd のコマンドラインに -Dparameter という形で指定するか あるいは Define ディレクティブで指定されると定義されます。

<IfDefine> セクションは 入れ子にすることができ、複数のパラメータによるテストをするために使用できます。 例:

httpd -DReverseProxy -DUseCache -DMemCache ...

# httpd.conf
<IfDefine ReverseProxy>
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<IfDefine UseCache>
LoadModule cache_module modules/mod_cache.so
<IfDefine MemCache>
LoadModule mem_cache_module modules/mod_mem_cache.so
</IfDefine>
<IfDefine !MemCache>
LoadModule cache_disk_module modules/mod_cache_disk.so
</IfDefine>
</IfDefine>
</IfDefine>

top

<IfDirective> ディレクティブ

説明:Encloses directives that are processed conditional on the presence or absence of a specific directive
構文:<IfDirective [!]directive-name> ... </IfDirective>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core
互換性:Available in 2.4.34 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

<IfFile> ディレクティブ

説明:Encloses directives that will be processed only if file exists at startup
構文:<IfFile [!]filename> ... </IfFile>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core
互換性:Available in 2.4.34 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

<IfModule> ディレクティブ

説明:モジュールの存在するかしないかに応じて処理される ディレクティブを囲む
構文:<IfModule [!]module-file|module-identifier> ... </IfModule>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core
互換性:モジュール識別子はバージョン 2.1 以降で使用可能。

<IfModule test>...</IfModule> セクションは、モジュールが存在するときに処理されるディレクティブを 指定するために利用します。 <IfModule> セクションに 含まれるディレクティブは、test で指定するモジュールが組み込まれているときのみ処理されます。 もし test が組み込まれていなければ、開始と終了の間のディレクティブ は無視されます。

<IfModule> セクションディレクティブに 指定する test は、 次の二つの形式のうちの一つをとります。

前者の場合は、module と名付けられたモジュールが Apache に組み込まれていれば (コンパイル済みのものと、LoadModule を利用して 動的に読み込んだものの両方)、 開始と終了の間のディレクティブが処理されます。 後者の場合は逆で、module が組み込まれていない 場合に処理されます。

module 引数は、モジュール識別子か コンパイルをした時のモジュールのファイル名です。 例えば、rewrite_module は識別子で mod_rewrite.c はファイル名です。 モジュールが複数のソースファイルから構成されている場合は、文字列 STANDARD20_MODULE_STUFF があるファイルの名前を 使ってください。

<IfModule> セクションは 入れ子にすることが可能であり、 複数のモジュールのテストを行なうために使用できます。

特定のモジュールの存在に関わらず動作する 設定ファイルの原本が必要なときにのみこのセクションを使用してください。 通常の動作では、ディレクティブを <IfModule> セクションの中に 入れる必要はありません。
top

<IfSection> ディレクティブ

説明:Encloses directives that are processed conditional on the presence or absence of a specific section directive
構文:<IfSection [!]section-name> ... </IfSection>
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:All
ステータス:Core
モジュール:core
互換性:Available in 2.4.34 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

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

参照

top

IncludeOptional ディレクティブ

説明:Includes other configuration files from within the server configuration files
構文:IncludeOptional file-path|directory-path|wildcard
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Core
モジュール:core
互換性:Available in 2.3.6 and later. Not existent file paths without wildcards do not cause SyntaxError after 2.4.30

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

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 に対応したクライアントの際には、 特に指定されない限りはデフォルトとして持続的な接続が行なわれます。 クライアントが要求すれば、コンテンツの容量を判別できないものを 持続的な接続を通して送るために、チャンクエンコーディングが用いられます。

クライアントが Keep-Alive コネクションを使用している場合、 そのコネクションを通してどれだけたくさんのリクエストが処理されても、 それは「リクエスト」1 つとして、MaxRequestsPerChild ディレクティブでは 数えられます。

参照

top

KeepAliveTimeout ディレクティブ

説明:持続的な接続で次のリクエストが来るまでサーバが待つ時間
構文:KeepAliveTimeout seconds
デフォルト:KeepAliveTimeout 5
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core

接続を閉じる前に、Apache が次のリクエストを何秒待つかを指定します。 リクエストを受け付けた後は、Timeout ディレクティブによって 指定されたタイムアウト値が使われます。

KeepAliveTimeout を大きな値に設定すると、 負荷の高いサーバにおいてはパフォーマンスの問題を引き起こす場合があります。 タイムアウトが長ければ長いほど、より多くのサーバプロセスが 活性でないクライアントからの接続の終了を待ち続けることになります。

名前ベースのバーチャルホストコンテキストでは、 NameVirtualHost のセットの中で最初に定義されたバーチャルホストの値 (デフォルトホスト) が使われます。 その他の値は無視されます。

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 メソッドに制限をかけることはできません (<TraceEnable> 参照)。

アクセス制御が目的の場合は <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_dirDirectoryIndex ディレクティブ がリストするファイルを調べるためにサブリクエストを使います。

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 にはワイルドカードを利用することができます。 ? は任意の一文字、* は任意の文字列にマッチします。 どちらのワイルドカードも URL パス中の / にはマッチしません。

~ という文字を追加することで、正規表現を 利用することもできます。 例えば:

<Location ~ "/(extra|special)/data">

は URL に /extra/data/special/data という文字列が 含まれている場合にマッチします。 <LocationMatch> ディレクティブは <Location> の正規表現 版とまったく同じ動作をします。

<Location> 機能は、SetHandler ディレクティブと 組合わせて利用すると特に便利です。 例えば、example.com のブラウザからのみステータスの参照を有効にしたければ、 次のようにすれば良いでしょう。

<Location /status>
SetHandler server-status
Order Deny,Allow
Deny from all
Allow from .example.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 に指定すると、 noticewarn も報告されます。

なお crit 以上のレベルを指定することが推奨されます。

例:

LogLevel notice

ファイルにログを出力する場合、notice レベルのメッセージは抑制されず、すべてログに出力されます。 しかし syslog を使用している場合は、 これは当てはまりません。

top

MaxKeepAliveRequests ディレクティブ

説明:持続的な接続上で許可されるリクエストの数
構文:MaxKeepAliveRequests number
デフォルト:MaxKeepAliveRequests 100
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core

MaxKeepAliveRequests ディレクティブは、 KeepAlive が有効な場合に、 一回の接続で受け付け可能なリクエストの数を制限します。 0 に設定していれば、受け付けるリクエストは無制限になります。 この設定は、サーバ性能を向上させるために、大きな数値を指定することを勧めます。

例:

MaxKeepAliveRequests 500

top

MaxRangeOverlaps ディレクティブ

説明:Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
構文:MaxRangeOverlaps default | unlimited | none | number-of-ranges
デフォルト:MaxRangeOverlaps 20
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Core
モジュール:core
互換性:Available in Apache HTTP Server 2.3.15 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

MaxRangeReversals ディレクティブ

説明:Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
構文:MaxRangeReversals default | unlimited | none | number-of-ranges
デフォルト:MaxRangeReversals 20
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Core
モジュール:core
互換性:Available in Apache HTTP Server 2.3.15 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

MaxRanges ディレクティブ

説明:Number of ranges allowed before returning the complete resource
構文:MaxRanges default | unlimited | none | number-of-ranges
デフォルト:MaxRanges 200
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Core
モジュール:core
互換性:Available in Apache HTTP Server 2.3.15 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

MergeSlashes ディレクティブ

説明:Controls whether the server merges consecutive slashes in URLs.
構文:MergeSlashes ON|OFF
デフォルト:MergeSlashes ON
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:Added in 2.4.39

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

MergeTrailers ディレクティブ

説明:Determines whether trailers are merged into headers
構文:MergeTrailers [on|off]
デフォルト:MergeTrailers off
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:2.4.11 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

Mutex ディレクティブ

説明:Configures mutex mechanism and lock file directory for all or specified mutexes
構文:Mutex mechanism [default|mutex-name] ... [OmitPID]
デフォルト:Mutex default
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:Available in Apache HTTP Server 2.3.4 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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 [2001:db8::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 ディレクティブは、特定のディレクトリに対して どの機能が使用可能かを制御します。

optionNoneに指定すると、 特別な機能は全て無効になります。 また、以下の示す 1 個以上のものを指定できます。

All
MultiViews を除いた全ての機能が有効となります。 これがデフォルトです。
ExecCGI
mod_cgi による CGI スクリプトの実行を許可します。
FollowSymLinks
サーバが、このディレクトリ内でシンボリックリンクをたどれるようにします。

サーバがシンボリックリンクをたどる場合でも、 <Directory> セクションに マッチさせるための パス名は変更されません

<Location> 内に このオプションを指定しても無視されることに 注意してください。

このオプションを省略したからといってセキュリティの強化にはなりません。 なぜなら symlink の検査はレースコンディションを引き起こす可能性があり、 そのため回避可能になるからです。

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> 内にこのオプションを 指定しても無視されます。

このオプションはセキュリティの強化にはなりません。 なぜなら symlink の検査はレースコンディションを引き起こす可能性があり、 そのため回避可能になるからです。

通常、ディレクトリに対して複数の Options が 適用可能な場合、 最も近いもの一つのみが適用され、他のものは無視されます。 複数の指定がマージされるわけではありません。(セクションのマージ方法を参照してください。) しかし、すべての 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 というディレクトリには、 FollowSymLinksIncludes が適用されます。

-IncludesNOEXEC もしくは -Includes を指定すると、 前の設定がどのようになっていようとも SSI は無効となります。

どのような設定もされていなければ、デフォルトでは All に なります。

top

Protocol ディレクティブ

説明:Protocol for a listening socket
構文:Protocol protocol
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:Available in Apache 2.1.5 and later. On Windows, from Apache 2.3.3 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

Protocols ディレクティブ

説明:Protocols available for a server/virtual host
構文:Protocols protocol ...
デフォルト:Protocols http/1.1
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:Only available from Apache 2.4.17 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

ProtocolsHonorOrder ディレクティブ

説明:Determines if order of Protocols determines precedence during negotiation
構文:ProtocolsHonorOrder On|Off
デフォルト:ProtocolsHonorOrder On
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:Only available from Apache 2.4.17 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

QualifyRedirectURL ディレクティブ

説明:Controls whether the REDIRECT_URL environment variable is fully qualified
構文:QualifyRedirectURL On|Off
デフォルト:QualifyRedirectURL Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
上書き:FileInfo
ステータス:Core
モジュール:core
互換性:Directive supported in 2.4.18 and later. 2.4.17 acted as if 'QualifyRedirectURL On' was configured.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

ReadBufferSize ディレクティブ

説明:Size of the buffers used to read data
構文:ReadBufferSize bytes
デフォルト:ReadBufferSize 8192
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Core
モジュール:core
互換性:2.4.27 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

RegexDefaultOptions ディレクティブ

説明:Allow to configure global/default options for regexes
構文:RegexDefaultOptions [none] [+|-]option [[+|-]option] ...
デフォルト:RegexDefaultOptions DOTALL DOLLAR_ENDONLY
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:Only available from Apache 2.4.30 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

RegisterHttpMethod ディレクティブ

説明:Register non-standard HTTP methods
構文:RegisterHttpMethod method [method [...]]
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:Available in Apache HTTP Server 2.4.24 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

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

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

もしくは、perlPATH にある場合は単に:

#!perl

ScriptInterpreterSource Registry を指定すると、 スクリプトファイルの拡張子 (例えば、.pl) を キーとして、Windows のレジストリツリー HKEY_CLASSES_ROOT を検索するようになります。レジストリのサブキー Shell\ExecCGI\Command か、それが存在しない場合は Shell\Open\Command がスクリプトファイルを開くために 使われます。レジストリキーが見つからないときは、Apache は Script オプションが指定されたときの動作に戻ります。

セキュリティ

ScriptInterpreterSource RegistryScriptAlias されたディレクトリで使うときは 注意してください。Apache はそのディレクトリ中のすべてのファイルを 実行しようとします。Registry という設定は通常は実行されない ファイルに対して望ましくないプログラムの実行が発生する可能性があります。 例えば、ほとんどの Windows システムで、 .htm ファイルのデフォルトの「開く」コマンドは Microsoft Internet Explorer を実行しますので、スクリプトに指定された ディレクトリにある .htm ファイルへのリクエストはサーバの バックグラウンドでブラウザを実行することになります。これは、一分内くらいで システムをクラッシュさるための良い方法です。

Apache 2.0 から導入されたオプション Registry-StrictRegistry と同じことを行ないますが、サブキー Shell\ExecCGI\Command のみを使います。 ExecCGI キーは普通に使われるキーではありません。Windows レジストリに手動で設定する必要がありますので、システムでの偶発的なプログラムの 実行を防ぐことができます。

top

SeeRequestTail ディレクティブ

説明:Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
構文:SeeRequestTail On|Off
デフォルト:SeeRequestTail Off
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:Available in Apache httpd 2.2.7 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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 ディレクティブは、ネームベースのバーチャルホストにおいて 使用するホストの別名を指定します。 適切であれば、ServerAlias ディレクティブでは ワイルドカードを使うこともできます。

<VirtualHost *>
ServerName server.domain.com
ServerAlias server server2.domain.com server2
# ...
</VirtualHost>

参照

top

ServerName ディレクティブ

説明:サーバが自分自身を示すときに使うホスト名とポート
構文:ServerName [scheme://]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: ヘッダに現れる必要があるのかを指定します。

SSL を処理するデバイス、例えばリバースプロクシやロードバランサや SSL 処理軽減アプライアンスの裏側でサーバが稼動する場合もあるでしょう。 そういった場合では、クライアントが接続するときに使う https:// スキームとポート番号を ServerName ディレクティブで指定して、自己参照 URL が正しく生成できるようにします。

自己参照 URL (例えば mod_dir モジュールによるものなど) が指定されたポートを使うか、クライアントのリクエストのポート番号を使うかを 決定する設定は UseCanonicalName ディレクティブと UseCanonicalPhysicalPort ディレクティブを参照してください。

参照

top

ServerPath ディレクティブ

説明:非互換のブラウザが名前ベースのバーチャルホストにアクセスしたときの ための互換用 URL パス名
構文:ServerPath URL-path
コンテキスト:バーチャルホスト
ステータス:Core
モジュール:core

ServerPath ディレクティブは、ネームベースのバーチャルホストにおいて利用する 互換用 URL パス名を設定します。

参照

top

ServerRoot ディレクティブ

説明:インストールされたサーバのベースディレクトリ
構文:ServerRoot directory-path
デフォルト:ServerRoot /usr/local/apache
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core

ServerRoot ディレクティブは、 サーバが存在するディレクトリを設定します。 通常、conf/logs/ といったサブディレクトリが 存在します。 また、他の設定ディレクティブ (例えば IncludeLoadModule など) における相対パスは、 このディレクトリからの相対位置となります。

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 以降では、表示されるサーバーのバージョン番号の詳細はServerTokens ディレクティブにより制御されます。

参照

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 で定義された設定を無効にすることが できます。

注意:SetHandler はデフォルトのハンドラをオーバーライド しますので、通常の挙動、たとえば、スラッシュ (/) で終わる URL が リクエストされたときにディレクトリやインデックスファイルを返すよう取り扱う挙動は、 行われなくなります。

参照

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

StrictHostCheck ディレクティブ

説明:Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
構文:StrictHostCheck ON|OFF
デフォルト:StrictHostCheck OFF
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core
互換性:Added in 2.4.49

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

TimeOut ディレクティブ

説明:各イベントについて、リクエストを失敗させるまでにサーバが 待つ時間を設定
構文:TimeOut seconds
デフォルト:TimeOut 60
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Core
モジュール:core

TimeOut ディレクティブは、 様々な条件下での I/O 待ち時間を定義します:

  1. クライアントからのデータを読み込む時。 受信バッファが空になっていて、TCP パケットが届くまで 待つ時間の長さ
  2. クライアントに対してデータを送り出す時。 送信バッファがいっぱいで、パケットの受信完了 (訳注: ACK) が届くまで待つ時間の長さ
  3. mod_cgi 内で、CGI スクリプトが出力を 返すまでの待ち時間の長さ
  4. mod_ext_filter 内で、フィルタ処理で出力を 待つ時間の長さ
  5. mod_proxy 内で、 ProxyTimeout が設定されていない場合のデフォルトの待ち時間
top

TraceEnable ディレクティブ

説明:TRACE メソッドのリクエストに対する応答方法を決める
構文:TraceEnable [on|off|extended]
デフォルト:TraceEnable on
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:Apache 1.3.34, 2.0.55 以降

Apache のコア機能(訳注: core)mod_proxy 両方の TRACE の挙動をオーバーライドします。デフォルトの TraceEnable on は、リクエストボディを受け入れないような、RFC2616 に準拠した TRACE リクエストを受け付けます。 TraceEnable off と設定すると、コアサーバと mod_proxy405 (メソッド不許可) エラーをクライアントに返します。

最後に、テストや調査目的などの限定用途として、仕様に準拠しない TraceEnable extended を使って、リクエストボディを 受け付けるように挙動を変更できます。(オリジンサーバとしての) Apache のコアでは、リクエストボディのサイズは 64k ( Transfer-Encoding: chunked が使われている場合は chunk ヘッダ用に +8k) に制限されます。 Apache のコアは、ヘッダと全ての chunk ヘッダをレスポンスの ボディとして返却します。 proxy サーバとしては、リクエストボディのサイズは 64k に制限されません。

top

UNCList ディレクティブ

説明:Controls what UNC host names can be accessed by the server
構文:UNCList hostname [hostname...]
デフォルト:unset
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core
互換性:Added in 2.4.60, Windows only.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

UnDefine ディレクティブ

説明:Undefine the existence of a variable
構文:UnDefine parameter-name
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

参照

top

UseCanonicalName ディレクティブ

説明:サーバが自分自身の名前とポートを決定する方法を設定する
構文:UseCanonicalName On|Off|Dns
デフォルト:UseCanonicalName Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Core
モジュール:core

多くの状況で Apache は自己参照 URL、すなわち 同じサーバを指す URL、を作成する必要があります。 UseCanonicalName On の場合は、ServerName ディレクティブで指定されている ホスト名とポート番号を使って、その正規名 (自己参照の名前) を生成します。 この名前は、すべての自己参照 URL で使われますし、CGI の SERVER_NAMESERVER_PORT でも使われます。

UseCanonicalName Off の場合、 クライアントがホスト名とポートを指定したときには、 それらを元に自己参照 URL を作成します (指定がなかったときは 上の定義と同様にして正規名を解決します)。 これらの値は名前ベースの バーチャルホストを実装で使われているのと同じ値で、 同じクライアントで取得できる値になっています。 CGI 変数 SERVER_NAMESERVER_PORT もクライアントから与えられた値から作成されます。

このような挙動が便利な例は、イントラネットのサーバで www のような短い名前でユーザがマシンに接続するときです。 ユーザの入力で短いホスト名が使われていて、URL が最後のスラッシュ無しの ディレクトリになっている http://www/splat のようなとき、 Apache はリクエストを http://www.domain.com/splat/ へリダイレクトします。 認証をするように設定していると、この場合 ユーザは 2 回認証をしなければならなくなります (www に 対して 1 回、www.domain.com に対してもう 1 回 -- 詳細は この話題の FAQ を参照してください)。 しかし UseCanonicalNameOff になっていると、 Apache は http://www/splat/ にリダイレクトします。

三つ目のオプション UseCanonicalName DNS は、 大規模な IP ベースのバーチャルホスティングで、 Host: ヘッダを提供しない古いクライアントを サポートする場合を想定しています。 このオプションでは Apache は、クライアントが接続した IP アドレスに対して DNS の逆引きを行なって、自己参照 URL を作成します。

警告

CGI が SERVER_NAME に関して何らかの前提条件を 仮定しているときには、このオプションの設定によっては動作しなく なるかもしれません。クライアントは実質的にはホスト名として 何でも望みの値を指定することができます。CGI が SERVER_NAME を使って自己参照 URL を作成することしかしない 場合は、どの設定を行なっても大丈夫なはずです。

参照

top

UseCanonicalPhysicalPort ディレクティブ

説明:自分自身の名前とポート番号を解決する方法を設定する
構文:UseCanonicalPhysicalPort On|Off
デフォルト:UseCanonicalPhysicalPort Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Core
モジュール:core

さまざまな局面で 自己参照 URL -- それ自体のサーバを参照する URL を作ることになります。UseCanonicalPhysicalPort On と設定すると、 UseCanonicalName に従って別名を 生成する場合に、実際の物理ポート番号を使って構成するようになります。 UseCanonicalPhysicalPort Off の場合は、実際の物理ポート番号は 使用せず、設定された情報を元にポート番号を決めます。

注意

物理ポートが使われる場合の順番は次のようになっています:

UseCanonicalName On

  • ServerName で指定されているポート番号
  • 物理ポート番号
  • デフォルトのポート番号
UseCanonicalName Off | DNS
  • Host: ヘッダをパースして取得されるポート番号
  • 物理ポート番号
  • ServerName で指定されているポート番号
  • デフォルトのポート番号

UseCanonicalPhysicalPort Off で、 物理ポート番号が上記の順序付けから除外されます。

参照

top

<VirtualHost> ディレクティブ

説明:特定のホスト名や IP アドレスのみに適用されるディレクティブを 囲む
構文:<VirtualHost addr[:port] [addr[:port]] ...> ... </VirtualHost>
コンテキスト:サーバ設定ファイル
ステータス:Core
モジュール:core

<VirtualHost> 及び </VirtualHost> は、 特定のバーチャルホストに対してのみ適用されるディレクティブ群を括る ために使われます。 バーチャルホストコンテキストで許可される全てのディレクティブを指定可能です。 サーバが、指定されたバーチャルホストにあるドキュメントへの リクエストを受け付けた場合、 <VirtualHost> セクションの中にある ディレクティブが適用されます。 Addrは、次のものが利用できます:

<VirtualHost 10.1.2.3>
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>

IPv6 アドレスはオプションのポート番号の指定と区別するために、 角括弧で括って指定する必要があります。次は IPv6 の例です:

<VirtualHost [2001:db8::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 コマンドにより 達成できます)。

注意点

<VirtualHost> は Apache が Listen する IP アドレスには影響を与えませんListen を 使って Apache が正しいアドレスを listen するように設定する必要があります。

IP ベースのバーチャルホストを使っている場合は、特別な名前 _default_ を指定することができます。その場合は そのバーチャルホストは他のバーチャルホストで明示的に挙げられていない すべての IP アドレスにマッチします。_default_ バーチャルホストが無い 場合に IP がバーチャルホストで指定されたものにマッチしないときは、 VirtualHost セクションの外のすべての定義からなる「主」サーバ設定が 使われます。(ただし、NameVirtualHost ディレクティブにマッチする すべての IP アドレスは「主」サーバ設定も _default_ バーチャルホストも 使わないことに注意してください。詳しくは ネームベースのバーチャルホスト を 参照してください。)

:port といった形式で記述することにより、 マッチさせるポートを変更可能です。 この指定をしない場合には、主サーバ設定における 一番最後に Port で指定されたポートが デフォルトとなります。 :* を指定することにより、 アドレス上の全てのポートにマッチします。(_default_ のときは これを使うことが推奨されています。)

<VirtualHost> ブロックごとに ServerName を指定すべきです。 もしなければ、メインサーバ設定の ServerName が継承されます

セキュリティ

サーバーを起動した以外のユーザがログファイルが保管されるディレクトリに 書き込み可能なときになぜセキュリティが破られる可能性があるかの詳細は セキュリティに関するコツ を 参照してください。

参照

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directive-dict.html.ja.utf80000664000175100017510000005010014743132254022652 0ustar covenercovener ディレクティブの解説に使われる用語 - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4

ディレクティブの解説に使われる用語

翻訳済み言語:  en  |  es  |  fr  |  ja  |  ko  |  tr 

この文書は各 Apache 設定ディレクティブ を説明するために使われている用語を説明します。

Support 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-pathServerRoot からの相対パスとして 扱われます。
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>, <If>, <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 の配布に組み込まれていなかった場合、 ディレクティブが導入されたバージョンがここに書かれています。 また、ディレクティブが特定のプラットフォームにのみ存在するときも ここに書かれています。

翻訳済み言語:  en  |  es  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/index.html.de0000664000175100017510000005603314743132254020206 0ustar covenercovener Modul-Index - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4

Modul-Index

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Nachfolgend ist eine Liste aller Module angegeben, die als Bestandteil der Distribution des Apache HTTP Servers mitgeliefert werden. Bitte beachten Sie auch die vollständige alphabetische Liste aller Apache-HTTP-Server-Direktiven.

Siehe auch

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.
event
A variant of the worker MPM with the goal of consuming threads only for connections with active processing
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
prefork
Implementiert einen im Voraus forkenden Webserver ohne Thread-Unterstützung
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  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
Group authorizations based on host (name or IP address)
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_allowmethods
Easily restrict what HTTP methods can be used on the server
mod_asis
Sends files that contain their own HTTP headers
mod_auth_basic
Basic HTTP authentication
mod_auth_digest
User authentication using MD5 Digest Authentication
mod_auth_form
Form authentication
mod_authn_anon
Allows "anonymous" user access to authenticated areas
mod_authn_core
Core Authentication
mod_authn_dbd
User authentication using an SQL database
mod_authn_dbm
User authentication using DBM files
mod_authn_file
User authentication using text files
mod_authn_socache
Manages a cache of authentication credentials to relieve the load on backends
mod_authnz_fcgi
Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
mod_authnz_ldap
Allows an LDAP directory to be used to store the database for HTTP Basic authentication.
mod_authz_core
Core Authorization
mod_authz_dbd
Group Authorization and Login using SQL
mod_authz_dbm
Group authorization using DBM files
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_brotli
Compress content via Brotli before it is delivered to the client
mod_buffer
Support for request buffering
mod_cache
RFC 2616 compliant HTTP caching filter.
mod_cache_disk
Disk based storage module for the HTTP caching filter.
mod_cache_socache
Shared object cache (socache) based storage module for the HTTP caching filter.
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_data
Convert response body into an RFC2397 data URL
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_dialup
Send static content at a bandwidth rate limit, defined by the various old modem standards
mod_dir
Provides for "trailing slash" redirects and serving directory index files
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_hooks
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_heartbeat
Sends messages with server status to frontend proxy
mod_heartmonitor
Centralized monitor for mod_heartbeat origin servers
mod_http2
Support for the HTTP/2 transport layer
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_lbmethod_bybusyness
Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_byrequests
Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_bytraffic
Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_heartbeat
Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
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_debug
Additional configurable debug logging
mod_log_forensic
Forensic Logging of the requests made to the server
mod_logio
Logging of input and output bytes per request
mod_lua
Provides Lua hooks into various portions of the httpd request processing
mod_macro
Provides macros within apache httpd runtime configuration files
mod_md
Managing domains across virtual hosts, certificate provisioning via the ACME protocol
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_privileges
Support for Solaris privileges and for running virtual hosts under different user IDs.
mod_proxy
Multi-protocol 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_express
Dynamic mass reverse proxy extension for mod_proxy
mod_proxy_fcgi
FastCGI support module for mod_proxy
mod_proxy_fdpass
fdpass external process support module for mod_proxy
mod_proxy_ftp
FTP support module for mod_proxy
mod_proxy_hcheck
Dynamic health check of Balancer members (workers) for mod_proxy
mod_proxy_html
Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
mod_proxy_http
HTTP support module for mod_proxy
mod_proxy_http2
HTTP/2 support module for mod_proxy
mod_proxy_scgi
SCGI gateway module for mod_proxy
mod_proxy_uwsgi
UWSGI gateway module for mod_proxy
mod_proxy_wstunnel
Websockets support module for mod_proxy
mod_ratelimit
Bandwidth Rate Limiting for Clients
mod_reflector
Reflect a request body as a response via the output filter stack.
mod_remoteip
Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
mod_reqtimeout
Set timeout and minimum data rate for receiving requests
mod_request
Filters to handle and make available HTTP request bodies
mod_rewrite
Provides a rule-based rewriting engine to rewrite requested URLs on the fly
mod_sed
Filter Input (request) and Output (response) content using sed syntax
mod_session
Session support
mod_session_cookie
Cookie based session support
mod_session_crypto
Session encryption support
mod_session_dbd
DBD/SQL based session support
mod_setenvif
Allows the setting of environment variables based on characteristics of the request
mod_slotmem_plain
Slot-based shared memory provider.
mod_slotmem_shm
Slot-based shared memory provider.
mod_so
Loading of executable code and modules into the server at start-up or restart time
mod_socache_dbm
DBM based shared object cache provider.
mod_socache_dc
Distcache based shared object cache provider.
mod_socache_memcache
Memcache based shared object cache provider.
mod_socache_redis
Redis based shared object cache provider.
mod_socache_shmcb
shmcb based shared object cache provider.
mod_speling
Attempts to correct mistaken URLs by ignoring capitalization, or attempting to correct various minor misspellings.
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_substitute
Perform search and replace operations on response bodies
mod_suexec
Allows CGI scripts to run as a specified user and Group
mod_systemd
Provides better support for systemd integration
mod_unique_id
Provides an environment variable with a unique identifier for each request
mod_unixd
Basic (required) security for Unix-family platforms.
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
mod_watchdog
provides infrastructure for other modules to periodically run tasks
mod_xml2enc
Enhanced charset/internationalisation support for libxml2-based filter modules

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/index.html.ko.euc-kr0000664000175100017510000005430414743132254021413 0ustar covenercovener - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

ֽ ƴմϴ. ֱٿ ϼ.

ġ Ե ̴. ġ þ ϵ ϶.

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)
event
A variant of the worker MPM with the goal of consuming threads only for connections with active processing
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
prefork
Implements a non-threaded, pre-forking web server
mpm_winnt
Multi-Processing Module optimized for Windows NT.
worker
Multi-Processing Module implementing a hybrid multi-threaded multi-process web server
top

ٸ

 A  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
Group authorizations based on host (name or IP address)
mod_actions
̵ û޼忡 CGI ũƮ Ѵ.
mod_alias
Ͻý ٸ κе ϰ, URL ̷ Ѵ
mod_allowmethods
Easily restrict what HTTP methods can be used on the server
mod_asis
HTTP
mod_auth_basic
Basic authentication
mod_auth_digest
MD5 Digest Authentication .
mod_auth_form
Form authentication
mod_authn_anon
"͸(anonymous)" Ѵ
mod_authn_core
Core Authentication
mod_authn_dbd
User authentication using an SQL database
mod_authn_dbm
DBM
mod_authn_file
̿
mod_authn_socache
Manages a cache of authentication credentials to relieve the load on backends
mod_authnz_fcgi
Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
mod_authnz_ldap
Allows an LDAP directory to be used to store the database for HTTP Basic authentication.
mod_authz_core
Core Authorization
mod_authz_dbd
Group Authorization and Login using SQL
mod_authz_dbm
DBM ׷
mod_authz_groupfile
Ϲ ̿ ׷ Ѻο
mod_authz_host
Group authorizations based on host (name or IP address)
mod_authz_owner
ڸ ̿ Ѻο
mod_authz_user
Ѻο
mod_autoindex
ڵ н ls ɾ Win32 dir ɾ 丮
mod_brotli
Compress content via Brotli before it is delivered to the client
mod_buffer
Support for request buffering
mod_cache
URI Ű Ͽ ijѴ.
mod_cache_disk
Content cache storage manager keyed to URIs
mod_cache_socache
Shared object cache (socache) based storage module for the HTTP caching filter.
mod_cern_meta
CERN Ÿ
mod_cgi
CGI ũƮ
mod_cgid
ܺ CGI Ͽ CGI ũƮ
mod_charset_lite
ȯ
mod_data
Convert response body into an RFC2397 data URL
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_dialup
Send static content at a bandwidth rate limit, defined by the various old modem standards
mod_dir
" " ̷ ϰ 丮 index Ѵ
mod_dumpio
Dumps all I/O to error log as desired.
mod_echo
ϱ echo
mod_env
CGI ũƮ SSI ȯ溯 Ѵ
mod_example_hooks
ġ 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_heartbeat
Sends messages with server status to frontend proxy
mod_heartmonitor
Centralized monitor for mod_heartbeat origin servers
mod_http2
Support for the HTTP/2 transport layer
mod_ident
RFC 1413 ident ˻
mod_imagemap
̹(imagemap) ó
mod_include
Server-parsed html documents (Server Side Includes)
mod_info
ش
mod_isapi
Windows ġ ISAPI Extension
mod_lbmethod_bybusyness
Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_byrequests
Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_bytraffic
Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_heartbeat
Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_ldap
LDAP connection pooling and result caching services for use by other LDAP modules
mod_log_config
û α׿ Ѵ
mod_log_debug
Additional configurable debug logging
mod_log_forensic
Forensic Logging of the requests made to the server
mod_logio
û Ʈ
mod_lua
Provides Lua hooks into various portions of the httpd request processing
mod_macro
Provides macros within apache httpd runtime configuration files
mod_md
Managing domains across virtual hosts, certificate provisioning via the ACME protocol
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_privileges
Support for Solaris privileges and for running virtual hosts under different user IDs.
mod_proxy
Multi-protocol 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_express
Dynamic mass reverse proxy extension for mod_proxy
mod_proxy_fcgi
FastCGI support module for mod_proxy
mod_proxy_fdpass
fdpass external process support module for mod_proxy
mod_proxy_ftp
FTP support module for mod_proxy
mod_proxy_hcheck
Dynamic health check of Balancer members (workers) for mod_proxy
mod_proxy_html
Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
mod_proxy_http
HTTP support module for mod_proxy
mod_proxy_http2
HTTP/2 support module for mod_proxy
mod_proxy_scgi
SCGI gateway module for mod_proxy
mod_proxy_uwsgi
UWSGI gateway module for mod_proxy
mod_proxy_wstunnel
Websockets support module for mod_proxy
mod_ratelimit
Bandwidth Rate Limiting for Clients
mod_reflector
Reflect a request body as a response via the output filter stack.
mod_remoteip
Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
mod_reqtimeout
Set timeout and minimum data rate for receiving requests
mod_request
Filters to handle and make available HTTP request bodies
mod_rewrite
Provides a rule-based rewriting engine to rewrite requested URLs on the fly
mod_sed
Filter Input (request) and Output (response) content using sed syntax
mod_session
Session support
mod_session_cookie
Cookie based session support
mod_session_crypto
Session encryption support
mod_session_dbd
DBD/SQL based session support
mod_setenvif
û ݿ ȯ溯 Ѵ
mod_slotmem_plain
Slot-based shared memory provider.
mod_slotmem_shm
Slot-based shared memory provider.
mod_so
Ҷ Ȥ Ҷ డ ڵ оδ
mod_socache_dbm
DBM based shared object cache provider.
mod_socache_dc
Distcache based shared object cache provider.
mod_socache_memcache
Memcache based shared object cache provider.
mod_socache_redis
Redis based shared object cache provider.
mod_socache_shmcb
shmcb based shared object cache provider.
mod_speling
ڰ ҹڸ ߸ ϰų Ʋ ѹ Ͽ ߸ URL ġ õѴ
mod_ssl
Strong cryptography using the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols
mod_status
Ȱ ɿ Ѵ
mod_substitute
Perform search and replace operations on response bodies
mod_suexec
CGI ũƮ Ư ڿ ׷ Ѵ
mod_systemd
Provides better support for systemd integration
mod_unique_id
û ĺڸ ȯ溯 Ѵ
mod_unixd
Basic (required) security for Unix-family platforms.
mod_userdir
ں 丮
mod_usertrack
Clickstream logging of user activity on a site
mod_version
mod_vhost_alias
Provides for dynamically configured mass virtual hosting
mod_watchdog
provides infrastructure for other modules to periodically run tasks
mod_xml2enc
Enhanced charset/internationalisation support for libxml2-based filter modules

:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/mod_actions.html.ko.euc-kr0000664000175100017510000003057014743132254022602 0ustar covenercovener mod_actions - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_actions

ֽ ƴմϴ. ֱٿ ϼ.
: ̵ û޼忡 CGI ũƮ Ѵ.
:Base
:actions_module
ҽ:mod_actions.c

⿡ ΰ þ ִ. Action þ ûϴ MIME content type CGI ũƮ Ѵ. Script þ û Ư ޼带 CGI ũƮ Ѵ. ׷ óϴ ũƮ ſ ִ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_deflate.html.ko.euc-kr0000664000175100017510000006671714743132254022562 0ustar covenercovener mod_deflate - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_deflate

ֽ ƴմϴ. ֱٿ ϼ.
: Ŭ̾Ʈ Ѵ
:Extension
:deflate_module
ҽ:mod_deflate.c

mod_deflate Ʈ Ŭ̾Ʈ ϴ DEFLATE ͸ Ѵ.

Support Apache!

þ

Bugfix checklist

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 Ͻð ڽ ij Accept-Encoding û Ŭ̾ƮԸ Vary: Accept-Encoding HTTP ߰Ѵ. ׷ Ŭ̾Ʈ ʵ Ѵ.

, User-Agent  Ư Ѵٸ, Ͻÿ ̷ ˷ֱ Vary ߰ؾ Ѵ. , User-Agent DEFLATE ͸ ߰Ѵٸ Ѵ:

Header append Vary User-Agent

û ٸ ( , HTTP ) ΰ ȴٸ, Vary * ؾ Ѵ. ׷ ǥ Ͻô ij ʰ ȴ.

Header set Vary *

top

DeflateAlterETag þ

:How the outgoing ETag header should be modified during compression
:DeflateAlterETag AddSuffix|NoChange|Remove
⺻:DeflateAlterETag AddSuffix
:ּ, ȣƮ
:Extension
:mod_deflate
:Available in Apache 2.4.58 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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

DeflateInflateLimitRequestBody þ

:Maximum size of inflated request bodies
:DeflateInflateLimitRequestBody value
⺻:None, but LimitRequestBody applies after deflation
:ּ, ȣƮ, directory, .htaccess
:Extension
:mod_deflate
:2.4.10 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

DeflateInflateRatioBurst þ

:Maximum number of times the inflation ratio for request bodies can be crossed
:DeflateInflateRatioBurst value
⺻:DeflateInflateRatioBurst 3
:ּ, ȣƮ, directory, .htaccess
:Extension
:mod_deflate
:2.4.10 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

DeflateInflateRatioLimit þ

:Maximum inflation ratio for request bodies
:DeflateInflateRatioLimit value
⺻:DeflateInflateRatioLimit 200
:ּ, ȣƮ, directory, .htaccess
:Extension
:mod_deflate
:2.4.10 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache_disk.html.ko.euc-kr0000664000175100017510000003734114743132254023222 0ustar covenercovener mod_cache_disk - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_cache_disk

ֽ ƴմϴ. ֱٿ ϼ.
:Content cache storage manager keyed to URIs
:Experimental
:cache_disk_module
ҽ:mod_cache_disk.c

̴. ۾̴...

mod_cache_disk ũ ڸ Ѵ. ⺻ mod_proxy Ѵ.

URI Ű ij ϰ ´. ٺȣ ijʴ´.

Support Apache!

þ

Bugfix checklist

top

CacheDirLength þ

:丮 ڰ
:CacheDirLength length
⺻:CacheDirLength 2
:ּ, ȣƮ
:Experimental
:mod_cache_disk

CacheDirLength þ ij 丮 ڼ Ѵ.

CacheDirLevels CacheDirLength Ͽ 20 ũ ȵȴ.

CacheDirLength 4

top

CacheDirLevels þ

:ij 丮 .
:CacheDirLevels levels
⺻:CacheDirLevels 3
:ּ, ȣƮ
:Experimental
:mod_cache_disk

CacheDirLevels þ ij 丮 ̸ Ѵ. ij ڷḦ CacheRoot 丮 Ʒ ̱ Ѵ.

CacheDirLevels CacheDirLength Ͽ 20 ũ ȵȴ.

CacheDirLevels 5

top

CacheMaxFileSize þ

:ij ִũ (Ʈ )
:CacheMaxFileSize bytes
⺻:CacheMaxFileSize 1000000
:ּ, ȣƮ
:Experimental
:mod_cache_disk

CacheMaxFileSize þ ij ִũ⸦ Ʈ Ѵ.

CacheMaxFileSize 64000

top

CacheMinFileSize þ

:ij ּũ (Ʈ )
:CacheMinFileSize bytes
⺻:CacheMinFileSize 1
:ּ, ȣƮ
:Experimental
:mod_cache_disk

CacheMinFileSize þ ij ּũ⸦ Ʈ Ѵ.

CacheMinFileSize 64

top

CacheReadSize þ

:The minimum size (in bytes) of the document to read and be cached before sending the data downstream
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache_disk

Documentation not yet translated. Please see English version of document.

top

CacheReadTime þ

:The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache_disk

Documentation not yet translated. Please see English version of document.

top

CacheRoot þ

:ij 丮 root
:CacheRoot directory
:ּ, ȣƮ
:Experimental
:mod_cache_disk

CacheRoot þ ũ ij 丮 Ѵ. mod_cache_disk ġ Ͽų о ݵ þ ؾ Ѵ. CacheRoot ó ʴ´. CacheDirLevels CacheDirLength þ þ root 丮 丮 Ѵ.

CacheRoot c:/cacheroot

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directive-dict.html.ko.euc-kr0000664000175100017510000003723414743132254023206 0ustar covenercovener þ ϴµ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

þ ϴµ

ֽ ƴմϴ. ֱٿ ϼ.

ġ þ ϴµ Ѵ.

Support Apache!

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  |  es  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/index.html.es0000664000175100017510000005647714743132254020241 0ustar covenercovener Índice de Módulos - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4

Índice de Módulos

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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.

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.

Consulte también

top

Funcionalidad Básica y Módulos de MultiProcesamiento (MPM)

core
Funcionalides básicas del Servidor HTTP Apache que siempre están presentes.
mpm_common
A collection of directives that are implemented by more than one multi-processing module (MPM)
event
A variant of the worker MPM with the goal of consuming threads only for connections with active processing
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
prefork
Implements a non-threaded, pre-forking web server
mpm_winnt
Multi-Processing Module optimized for Windows NT.
worker
Multi-Processing Module implementing a hybrid multi-threaded multi-process web server
top

Otros Módulos

 A  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
Group authorizations based on host (name or IP address)
mod_actions
Execute 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_allowmethods
Easily restrict what HTTP methods can be used on the server
mod_asis
Sends files that contain their own HTTP headers
mod_auth_basic
Basic HTTP authentication
mod_auth_digest
User authentication using MD5 Digest Authentication
mod_auth_form
Form authentication
mod_authn_anon
Allows "anonymous" user access to authenticated areas
mod_authn_core
Core Authentication
mod_authn_dbd
User authentication using an SQL database
mod_authn_dbm
User authentication using DBM files
mod_authn_file
User authentication using text files
mod_authn_socache
Manages a cache of authentication credentials to relieve the load on backends
mod_authnz_fcgi
Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
mod_authnz_ldap
Allows an LDAP directory to be used to store the database for HTTP Basic authentication.
mod_authz_core
Core Authorization
mod_authz_dbd
Group Authorization and Login using SQL
mod_authz_dbm
Group authorization using DBM files
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_brotli
Compress content via Brotli before it is delivered to the client
mod_buffer
Support for request buffering
mod_cache
RFC 2616 compliant HTTP caching filter.
mod_cache_disk
Disk based storage module for the HTTP caching filter.
mod_cache_socache
Shared object cache (socache) based storage module for the HTTP caching filter.
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_data
Convert response body into an RFC2397 data URL
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_dialup
Send static content at a bandwidth rate limit, defined by the various old modem standards
mod_dir
Provides for "trailing slash" redirects and serving directory index files
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_hooks
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_heartbeat
Sends messages with server status to frontend proxy
mod_heartmonitor
Centralized monitor for mod_heartbeat origin servers
mod_http2
Support for the HTTP/2 transport layer
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_lbmethod_bybusyness
Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_byrequests
Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_bytraffic
Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_heartbeat
Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
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_debug
Additional configurable debug logging
mod_log_forensic
Forensic Logging of the requests made to the server
mod_logio
Logging of input and output bytes per request
mod_lua
Provides Lua hooks into various portions of the httpd request processing
mod_macro
Provides macros within apache httpd runtime configuration files
mod_md
Managing domains across virtual hosts, certificate provisioning via the ACME protocol
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_privileges
Support for Solaris privileges and for running virtual hosts under different user IDs.
mod_proxy
Multi-protocol 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_express
Dynamic mass reverse proxy extension for mod_proxy
mod_proxy_fcgi
FastCGI support module for mod_proxy
mod_proxy_fdpass
fdpass external process support module for mod_proxy
mod_proxy_ftp
FTP support module for mod_proxy
mod_proxy_hcheck
Dynamic health check of Balancer members (workers) for mod_proxy
mod_proxy_html
Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
mod_proxy_http
HTTP support module for mod_proxy
mod_proxy_http2
HTTP/2 support module for mod_proxy
mod_proxy_scgi
SCGI gateway module for mod_proxy
mod_proxy_uwsgi
UWSGI gateway module for mod_proxy
mod_proxy_wstunnel
Websockets support module for mod_proxy
mod_ratelimit
Bandwidth Rate Limiting for Clients
mod_reflector
Reflect a request body as a response via the output filter stack.
mod_remoteip
Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
mod_reqtimeout
Set timeout and minimum data rate for receiving requests
mod_request
Filters to handle and make available HTTP request bodies
mod_rewrite
Provides a rule-based rewriting engine to rewrite requested URLs on the fly
mod_sed
Filter Input (request) and Output (response) content using sed syntax
mod_session
Session support
mod_session_cookie
Cookie based session support
mod_session_crypto
Session encryption support
mod_session_dbd
DBD/SQL based session support
mod_setenvif
Allows the setting of environment variables based on characteristics of the request
mod_slotmem_plain
Slot-based shared memory provider.
mod_slotmem_shm
Slot-based shared memory provider.
mod_so
Loading of executable code and modules into the server at start-up or restart time
mod_socache_dbm
DBM based shared object cache provider.
mod_socache_dc
Distcache based shared object cache provider.
mod_socache_memcache
Memcache based shared object cache provider.
mod_socache_redis
Redis based shared object cache provider.
mod_socache_shmcb
shmcb based shared object cache provider.
mod_speling
Attempts to correct mistaken URLs by ignoring capitalization, or attempting to correct various minor misspellings.
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_substitute
Perform search and replace operations on response bodies
mod_suexec
Allows CGI scripts to run as a specified user and Group
mod_systemd
Provides better support for systemd integration
mod_unique_id
Provides an environment variable with a unique identifier for each request
mod_unixd
Basic (required) security for Unix-family platforms.
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
mod_watchdog
provides infrastructure for other modules to periodically run tasks
mod_xml2enc
Enhanced charset/internationalisation support for libxml2-based filter modules

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/mod_authn_socache.html.fr.utf80000664000175100017510000005125614740503670023451 0ustar covenercovener mod_authn_socache - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authn_socache

Langues Disponibles:  en  |  fr 

Description:Gère un cache des données d'authentification pour diminuer la charge des serveurs d'arrière-plan
Statut:Base
Identificateur de Module:authn_socache_module
Fichier Source:mod_authn_socache.c
Compatibilité:Versions 2.3 et ultérieures

Sommaire

Maintient un cache des données d'authentification pour limiter les sollicitations du serveur d'arrière-plan.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Mise en cache des données d'authentification

Certains utilisateurs qui mettent en oeuvre une authentification lourde s'appuyant par exemple sur des requêtes SQL (mod_authn_dbd) ont signalé une charge induite inacceptable sur leur fournisseur d'authentification. Cela se produit typiquement dans le cas où une page HTML contient des centaines d'objets (images, scripts, pages de styles, media, etc...), et où une requête pour cette page génère des centaines de sous-requêtes à effet immédiat pour des contenus supplémentaires authentifiés.

Pour résoudre ce problème, mod_authn_socache fournit une solution qui permet de maintenir un cache des données d'authentification.

top

Utilisation

Le cache d'authentification doit être utilisé lorsque les requêtes d'authentification induisent une charge significative sur le serveur, le serveur d'arrière-plan ou le réseau. Cette mise en cache n'apportera probablement aucune amélioration dans le cas d'une authentification à base de fichier (mod_authn_file) ou de base de données dbm (mod_authn_dbm) car ces méthodes sont de par leur conception rapides et légères (la mise en cache peut cependant s'avérer utile dans le cas où le fichier est situé sur un montage réseau). Les fournisseurs d'authentification basés sur SQL ou LDAP ont plus de chances de tirer parti de cette mise en cache, en particulier lorsqu'un problème de performances est détecté. mod_authnz_ldap gérant son propre cache, seul mod_authn_dbd est concerné par notre sujet.

Les principales règles à appliquer pour la mise en cache sont :

  1. Inclure le fournisseur pour lequel vous voulez effectuer une mise en cache dans une directive AuthnCacheProvideFor.
  2. Mettre socache avant le fournisseur pour lequel vous voulez effectuer une mise en cache dans votre directive AuthBasicProvider ou AuthDigestProvider.

Voici un exemple simple permettant d'accélérer mod_authn_dbd et utilisant dbm comme moteur de la mise en cache :

    #AuthnCacheSOCache est optionnel. S'il est défini, il l'est pour
    #l'ensemble du serveur
AuthnCacheSOCache dbm
<Directory "/usr/www/myhost/private">
    AuthType Basic
    AuthName "Cached Authentication Example"
    AuthBasicProvider socache dbd
    AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"
    AuthnCacheProvideFor dbd
    Require valid-user
    #Optionnel
    AuthnCacheContext dbd-authn-example
</Directory>
top

La mise en cache avec les modules tiers

Les développeurs de modules doivent savoir que la mise en cache avec mod_authn_socache doit être activée dans leurs modules. La fonction de l'API ap_authn_cache_store permet de mettre en cache les données d'authentification qu'un fournisseur vient de rechercher ou de générer. Vous trouverez des exemples d'utilisation à r957072, où trois fournisseurs authn sont activés pour la mise en cache.

top

Directive AuthnCacheContext

Description:Spécifie une chaîne de contexte à utiliser dans la clé du cache
Syntaxe:AuthnCacheContext directory|server|custom-string
Défaut:AuthnCacheContext directory
Contexte:répertoire
Statut:Base
Module:mod_authn_socache

Cette directive permet de spécifier une chaîne à utiliser avec le nom d'utilisateur fourni (et le domaine d'authentification - realm - dans le cas d'une authentification à base de condensés) lors de la construction d'une clé de cache. Ceci permet de lever l'ambiguïté entre plusieurs noms d'utilisateurs identiques servant différentes zones d'authentification sur le serveur.

Il y a deux valeurs spéciales pour le paramètre : directory, qui utilise le contexte de répertoire de la requête comme chaîne, et server, qui utilise le nom du serveur virtuel.

La valeur par défaut est directory, qui est aussi la définition la plus courante. Ceci est cependant loin d'être optimal, car par exemple, $app-base, $app-base/images, $app-base/scripts et $app-base/media possèderont chacun leur propre clé de cache. Il est préférable d'utiliser le fournisseur de mot de passe : par exemple un fichier htpasswd ou une table de base de données.

Les contextes peuvent être partagés entre différentes zones du serveur, où les données d'authentification sont partagées. Ceci est cependant susceptible de créer des trous de sécurité de type cross-site ou cross-application, et cette directive n'est donc pas disponible dans les contextes .htaccess.

top

Directive AuthnCacheEnable

Description:Active la mise en cache de l'authentification en tout endroit
Syntaxe:AuthnCacheEnable
Contexte:configuration globale
Statut:Base
Module:mod_authn_socache

Normalement, cette directive n'est pas nécessaire : l'activation est implicite si la mise en cache de l'authentification a été activée en tout autre endroit du fichier httpd.conf. Par contre, si cette mise en cache n'a pas été activée, par défaut, elle ne sera pas initialisée, et ne sera donc pas disponible dans un contexte de fichier .htaccess. Cette directive permet d'être sûr que la mise en cache a bien été activée et pourra donc être utilisée dans les fichiers .htaccess.

top

Directive AuthnCacheProvideFor

Description:Spécifie le fournisseur pour lequel on veut effectuer une mise en cache
Syntaxe:AuthnCacheProvideFor fournisseur-authn [...]
Défaut:None
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authn_socache

Cette directive permet de spécifier un ou plusieurs fournisseurs pour le(s)quel(s) on veut effectuer une mise en cache. Les données d'authentification trouvées par un fournisseur non spécifié dans une directive AuthnCacheProvideFor ne seront pas mises en cache.

Par exemple, pour mettre en cache les données d'authentification trouvées par mod_authn_dbd ou par un fournisseur personnalisé mon-fournisseur, et ne pas mettre en cache celles trouvées par les fournisseurs légers comme file ou dbm :

AuthnCacheProvideFor dbd mon-fournisseur
top

Directive AuthnCacheSOCache

Description:Sélectionne le fournisseur socache d'arrière-plan à utiliser
Syntaxe:AuthnCacheSOCache nom-fournisseur[:arguments-fournisseur]
Contexte:configuration globale
Statut:Base
Module:mod_authn_socache
Compatibilité:Les arguments optionnels du fournisseur sont disponibles à partir de la version 2.4.7 du serveur HTTP Apache

Cette définition s'applique à l'ensemble du serveur et permet de sélectionner un fournisseur pour le cache d'objets partagés, ainsi que des arguments éventuels pour ce fournisseur. Les fournisseurs disponibles sont, entre autres, "dbm", "dc", "memcache", ou "shmcb", chacun d'entre eux nécessitant le chargement du module approprié. Si elle est absente, c'est la valeur par défaut pour votre plate-forme qui sera utilisée.

top

Directive AuthnCacheTimeout

Description:Définit une durée de vie pour les entrées du cache
Syntaxe:AuthnCacheTimeout durée-de-vie (secondes)
Défaut:AuthnCacheTimeout 300 (5 minutes)
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authn_socache

La mise en cache des données d'authentification peut constituer un trou de sécurité, bien qu'un mise en cache de courte durée ne posera probablement pas de problème. En général, il est conseillé de conserver les entrées du cache de façon à ce que la charge du serveur d'arrière-plan reste normale, mais pas plus longtemps ; une durée de vie plus longue peut être paramétrée si les changements d'utilisateurs et de mots de passe sont peu fréquents. La durée de vie par défaut de 300 secondes (5 minutes) est à la fois raisonnable et suffisamment importante pour réduire la charge d'un serveur d'arrière-plan comme dbd (requêtes SQL).

Cette durée de vie ne doit pas être confondue avec la durée de vie de session qui est un tout autre sujet. Cependant, vous devez utiliser votre logiciel de gestion de session pour vérifier si les données d'authentification mises en cache peuvent allonger accidentellement une session, et en tenir compte lorsque vous définissez la durée de vie.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_anon.html.ja.utf80000664000175100017510000004474314743132254022764 0ustar covenercovener mod_authn_anon - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_authn_anon

翻訳済み言語:  en  |  fr  |  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 を使用している場合は、このモジュールは AuthBasicProvideranon という値を設定することで起動されます。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

以下の例は「普通」の htpasswd ファイルに基づいた認証と組み合わされて おり、以下の要件を見たすユーザを「ゲスト」として許可します:

<Directory /var/www/html/private>
    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
    
    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 参照)。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.tr.utf80000664000175100017510000016327515032765673022202 0ustar covenercovener Yönerge Dizini - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Yönerge Dizini

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Standart Apache dağıtımında bulunan yönergelerin tamamı burada listelenmiştir. Hepsi aralarında şekilsel bir uyum sağlanarak açıklanmışlardır. Açıklamalarında kullanılan terimler için Yönerge Sözlüğüne bakabilirsiniz.

Ayrıca, yönerge ayrıntılarının bir özet olarak listelendiği bir Hızlı Yönerge Kılavuzu da mevcuttur.

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/index.html.tr.utf80000664000175100017510000005602214743132254021126 0ustar covenercovener Modül Dizini - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4

Modül Dizini

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Apache HTTP Sunucusu dağıtımının parçası olarak gelen modüllerin tamamı aşağıda listelenmiştir. Ayrıca, tüm Apache HTTP Sunucusu yönergelerinin alfabetik olarak listelendiği bir Yönerge Dizini de mevcuttur.

Ayrıca bakınız:

top

Temel Özellikler ve Çoklu İşlem Modülleri

core
Apache HTTP Sunucusunda daima mevcut olan çekirdek özellikler
mpm_common
Birden fazla Çok Süreçlilik Modülü (MPM) tarafından gerçeklenmiş yönergeler bütünü.
event
A variant of the worker MPM with the goal of consuming threads only for connections with active processing
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
prefork
Evresiz ön çatallamalı HTTP sunucusu oluşturur
mpm_winnt
Multi-Processing Module optimized for Windows NT.
worker
Çok evreli ve çok süreçli melez bir HTTP sunucusu oluşturan çok süreçlilik modülü.
top

Diğer Modüller

 A  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
Group authorizations based on host (name or IP address)
mod_actions
Execute CGI scripts based on media type or request method.
mod_alias
Belge ağacının parçalarının dosya sisteminin parçalarıyla eşlenmesini sağlar ve URL yönlendirmesi yapar.
mod_allowmethods
Easily restrict what HTTP methods can be used on the server
mod_asis
Sends files that contain their own HTTP headers
mod_auth_basic
Basic HTTP authentication
mod_auth_digest
User authentication using MD5 Digest Authentication
mod_auth_form
Form authentication
mod_authn_anon
Allows "anonymous" user access to authenticated areas
mod_authn_core
Core Authentication
mod_authn_dbd
User authentication using an SQL database
mod_authn_dbm
User authentication using DBM files
mod_authn_file
User authentication using text files
mod_authn_socache
Manages a cache of authentication credentials to relieve the load on backends
mod_authnz_fcgi
Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
mod_authnz_ldap
Allows an LDAP directory to be used to store the database for HTTP Basic authentication.
mod_authz_core
Core Authorization
mod_authz_dbd
Group Authorization and Login using SQL
mod_authz_dbm
Group authorization using DBM files
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
Unix ls veya Win32 dir kabuk komutunun yaptığı gibi dizin içeriğini listeler.
mod_brotli
Compress content via Brotli before it is delivered to the client
mod_buffer
Support for request buffering
mod_cache
RFC 2616 compliant HTTP caching filter.
mod_cache_disk
Disk based storage module for the HTTP caching filter.
mod_cache_socache
Shared object cache (socache) based storage module for the HTTP caching filter.
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_data
Convert response body into an RFC2397 data URL
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_dialup
Send static content at a bandwidth rate limit, defined by the various old modem standards
mod_dir
Bölü çizgisiyle biten yönlendirmeleri yapar ve dizin içeriği dosyalarını sunar.
mod_dumpio
Dumps all I/O to error log as desired.
mod_echo
A simple echo server to illustrate protocol modules
mod_env
CGI betiklerine ve SSI sayfalarına aktarılan değişkenlere müdahale etmek için kullanılır.
mod_example_hooks
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_heartbeat
Sends messages with server status to frontend proxy
mod_heartmonitor
Centralized monitor for mod_heartbeat origin servers
mod_http2
Support for the HTTP/2 transport layer
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_lbmethod_bybusyness
Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_byrequests
Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_bytraffic
Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_heartbeat
Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_ldap
LDAP connection pooling and result caching services for use by other LDAP modules
mod_log_config
Sunucuya yapılan isteklerin günlük kayıtlarının tutulması
mod_log_debug
Additional configurable debug logging
mod_log_forensic
Sunucuya yapılan isteklerin adli günlük kayıtlarının tutulması
mod_logio
Her isteğin girdi ve çıktı uzunluklarının günlüklenmesi.
mod_lua
Provides Lua hooks into various portions of the httpd request processing
mod_macro
Provides macros within apache httpd runtime configuration files
mod_md
Managing domains across virtual hosts, certificate provisioning via the ACME protocol
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_privileges
Support for Solaris privileges and for running virtual hosts under different user IDs.
mod_proxy
Multi-protocol 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_express
Dynamic mass reverse proxy extension for mod_proxy
mod_proxy_fcgi
FastCGI support module for mod_proxy
mod_proxy_fdpass
fdpass external process support module for mod_proxy
mod_proxy_ftp
FTP support module for mod_proxy
mod_proxy_hcheck
Dynamic health check of Balancer members (workers) for mod_proxy
mod_proxy_html
Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
mod_proxy_http
HTTP support module for mod_proxy
mod_proxy_http2
HTTP/2 support module for mod_proxy
mod_proxy_scgi
SCGI gateway module for mod_proxy
mod_proxy_uwsgi
UWSGI gateway module for mod_proxy
mod_proxy_wstunnel
Websockets support module for mod_proxy
mod_ratelimit
Bandwidth Rate Limiting for Clients
mod_reflector
Reflect a request body as a response via the output filter stack.
mod_remoteip
Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
mod_reqtimeout
Set timeout and minimum data rate for receiving requests
mod_request
HTTP istek gövdelerini işleme sokup kullanılabilir kılan süzgeçler
mod_rewrite
Provides a rule-based rewriting engine to rewrite requested URLs on the fly
mod_sed
Filter Input (request) and Output (response) content using sed syntax
mod_session
Session support
mod_session_cookie
Cookie based session support
mod_session_crypto
Session encryption support
mod_session_dbd
DBD/SQL based session support
mod_setenvif
Ortam değişkenlerinin isteğin özelliklerine uygun olarak atanmasını sağlar
mod_slotmem_plain
Slot-based shared memory provider.
mod_slotmem_shm
Slot-based shared memory provider.
mod_so
Modüllerin ve çalıştırılabilir kodun sunucunun başlatılması veya yeniden başlatılması sırasında yüklenmesini sağlar.
mod_socache_dbm
DBM based shared object cache provider.
mod_socache_dc
Distcache based shared object cache provider.
mod_socache_memcache
Memcache based shared object cache provider.
mod_socache_redis
Redis based shared object cache provider.
mod_socache_shmcb
shmcb based shared object cache provider.
mod_speling
Attempts to correct mistaken URLs by ignoring capitalization, or attempting to correct various minor misspellings.
mod_ssl
Strong cryptography using the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols
mod_status
Sunucu etkinliği ve başarımı hakkında bilgi sağlar.
mod_substitute
Perform search and replace operations on response bodies
mod_suexec
CGI betiklerinin belli bir kullanıcı ve grubun aidiyetinde çalışmasını mümkün kılar.
mod_systemd
Provides better support for systemd integration
mod_unique_id
Provides an environment variable with a unique identifier for each request
mod_unixd
Unix ailesi platformlar için temel (gerekli) güvenlik.
mod_userdir
Kullanıcılara özel dizinler
mod_usertrack
Clickstream logging of user activity on a site
mod_version
Version dependent configuration
mod_vhost_alias
Kitlesel sanal konakların devingen olarak yapılandırılmasını sağlar
mod_watchdog
provides infrastructure for other modules to periodically run tasks
mod_xml2enc
Enhanced charset/internationalisation support for libxml2-based filter modules

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/mod_access_compat.html.ja.utf80000664000175100017510000007501114743132254023426 0ustar covenercovener mod_access_compat - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_access_compat

翻訳済み言語:  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:ホスト (名前もしくは IP アドレス) に基づいたグループ承認
ステータス:Extension
モジュール識別子:access_compat_module
ソースファイル:mod_access_compat.c
互換性:Apache 2.3 (Apache 2.x の以前のバージョンとの互換性のためのモジュールとして)。 このモジュールで提供するディレクティブは、承認の仕組みの一新に伴い、非推奨になったものです。 mod_authz_host も見てください。

概要

mod_access_compat により提供されるディレクティブは サーバの特定の部分への アクセスを制御するために <Directory>, <Files>, <Location>.htaccess ファイルで使用されます。クライアントのホスト名、IP アドレスや、環境変数などのリクエストの特徴に基づいて アクセス制御を行なうことができます。AllowDeny ディレクティブを使って、 どのようなクライアントにアクセスを 許可する、しないを指定します。また Order ディレクティブを使って、 デフォルトのアクセス状態と、 Allow ディレクティブと Deny ディレクティブとのお互いへの影響の仕方を設定します。

ホストによるアクセス制限とパスワードによる認証を、 同時に組み合わせて使うこともできます。 この場合、その二つの制限の関係を指定するために Satisfy ディレクティブを使用します。

Note

mod_access_compatが提供するディレクティブは、 承認の仕組みの一新に伴い、非推奨になったものです。 mod_authz_host も見てください。 デフォルトの承認の取り扱い機能を使用するために mod_authz_default モジュールもロードされなければなりません。

一般的には、アクセス制限ディレクティブはすべてのアクセスメソッド (GET, PUT, POST など) に適用されます。そして、ほとんどの場合これが望ましい動作です。 しかし、<Limit> セクションの中にディレクティブを書くことで、 一部のメソッドにのみ制限をかけることもできます。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

Allow ディレクティブ

説明:サーバのある領域にアクセスできるホストを制御する
構文: Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...
コンテキスト:ディレクトリ, .htaccess
上書き:Limit
ステータス:Extension
モジュール:mod_access_compat

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 2001:db8::a00:20ff:fea7:ccea
Allow from 2001:db8::a00:20ff:fea7:ccea/10

Allow ディレクティブの引数の三つ目の形式は、 環境変数 の存在によりアクセスの制御を行なえるようにするものです。 Allow from env=env-variable が指定されていると、環境変数 env-variable が存在した場合にリクエストはアクセスを許可されます。 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
ステータス:Extension
モジュール:mod_access_compat

このディレクティブはホスト名、IP アドレス、環境変数に基づいてサーバへのアクセスを制限します。 Deny ディレクティブの引数は Allow ディレクティブとまったく同じです。

top

Order ディレクティブ

説明:デフォルトのアクセス可能な状態と、AllowDeny が評価される順番を制御する
構文: Order ordering
デフォルト:Order Deny,Allow
コンテキスト:ディレクトリ, .htaccess
上書き:Limit
ステータス:Extension
モジュール:mod_access_compat

Order ディレクティブは Allow ディレクティブとDeny と共に"3段階アクセス制御システム" を制御します。第1段階目では Order ディレクティブで1番目に 指定したディレクティブ(Allow または Deny)を全て処理します。 第2段階目で、残りのディレクティブ(Deny または Allow) を全て処理します。第3段階目で、第1段階目と第2段階目で マッチしなかったリクエストを処理します。

全ての AllowDeny が処理され、結局のところ最後にマッチ した条件が有効となることに注意してください。これは最初にマッチした条件だけが有効 となる、典型的なファイアウォールの動作とは異なっています。 また、設定ファイルに書く順番には意味はありません。Allow 行は全部一つのグループとして扱われ、 Deny 行はもう一つのグループとみなされます。 またデフォルト状態は単独で一つのグループとみなされます。

Order 設定は以下のどれかです。

Allow,Deny
まず Allow ディレクティブが適用されます。どれにもマッチしなかった場合、この時点で リクエストは拒否されます。次に、全ての Deny ディレクティブが適用されます。どれか一つでもマッチした場合は、 リクエストは拒否されます。 最後に、 Allow にも Deny にもマッチしなかったリクエストは デフォルト設定が適用されるので拒否されます。
Deny,Allow
まず Deny ディレクティブが適用されます。どれか一つでもマッチした場合は、 Allow のどれにも マッチしなければ、アクセスは拒否されます。 どの Allow にも Deny にもマッチしないリクエストは 許可されます。
Mutual-failure
これは Order Allow,Deny と全く同じ効果を持ち、 そのため非推奨となっています。

キーワードの間に置けるのはコンマだけです。 間に空白があってはいけません

マッチ Allow,Deny 時の結果 Deny,Allow 時の結果
Allow だけにマッチ 許可 許可
Deny だけにマッチ 拒否 拒否
どちらにもマッチしない 2番目のディレクティブがデフォルト: 拒否 2番目のディレクティブがデフォルト: 許可
Allow と Deny 両方にマッチ 最後にマッチしたほう: 拒否 最後にマッチしたほう: 許可

以下の例では、apache.org ドメインのすべてのホストはアクセスを許可されます。 他のすべてのホストはアクセスを拒否されます。

Order Deny,Allow
Deny from all
Allow from apache.org

次の例では、foo.apache.org サブドメインにあるホスト以外の、 apache.org ドメインのすべてのホストがアクセスを許可されます。 apache.org ドメインでないホストは、デフォルトの状態が Deny のため、 サーバへのアクセスを拒否されます。

Order Allow,Deny
Allow from apache.org
Deny from foo.apache.org

一方、上の例の OrderDeny,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 セクションの動作方法 を参照してください。

top

Satisfy ディレクティブ

説明:ホストレベルのアクセス制御とユーザ認証との相互作用を指定
構文:Satisfy Any|All
デフォルト:Satisfy All
コンテキスト:ディレクトリ, .htaccess
上書き:AuthConfig
ステータス:Extension
モジュール:mod_access_compat
互換性:バージョン 2.0.51 以降では <Limit> ディレクティブと <LimitExcept> ディレクティブの影響を受ける

AllowRequire の両方が使われているときの アクセスポリシーを設定します。パラメータは AllAny です。このディレクティブはある場所へのアクセスがユーザ名/パスワード クライアントのホストのアドレスで制限されているときにのみ 役立ちます。デフォルトの動作 (All) はクライアントがアドレスによる アクセス制限を満たし、かつ正しいユーザ名とパスワードを入力することを 要求します。Any では、クライアントはホストの制限を満たすか、 正しいユーザ名とパスワードの入力をするかをすればアクセスを許可されます。 これは、ある場所をパスワードで保護するけれど、特定のアドレスからの クライアントにはパスワードの入力を要求せずにアクセスを許可する、 というようなときに使用できます。

例えば、同じネットワーク上にいる人にはウェブサイトのある部分について 無制限のアクセスを許したいけれど、外のネットワークの人には パスワードを提供させるようにするためには、次のような設定をすることが できます:

Require valid-user
Allow from 192.168.1
Satisfy Any

バージョン 2.0.51 からは <Limit> セクションと <LimitExcept> セクションを使用することで Satisfy ディレクティブが 適用されるメソッドを制限することが できるようになりました。

参照

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_actions.html.ja.utf80000664000175100017510000003467114743132254022271 0ustar covenercovener mod_actions - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_actions

翻訳済み言語:  de  |  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:メディアタイプやリクエストメソッドに応じて CGI スクリプトを実行する機能を提供
ステータス:Base
モジュール識別子:actions_module
ソースファイル:mod_actions.c

概要

このモジュールには二つのディレクティブがあります。Action ディレクティブは特定の MIME タイプのファイルをリクエストされた場合に CGI スクリプトが実行されるようにします。Script ディレクティブはリクエストで特定のメソッドが使用されたときに CGI スクリプトが実行されるようにします。 これはファイルを処理するスクリプトの実行をずっと簡単にします。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

Action ディレクティブ

説明:特定のハンドラやコンテントタイプに対して CGI を実行するように 設定
構文:Action action-type cgi-script [virtual]
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Base
モジュール:mod_actions
互換性:virtual 修飾子とハンドラ渡しは Apache 2.1 で導入されました

このディレクティブは action-type がリクエストされたときに cgi-script が実行されるという動作を追加します。cgi-scriptScriptAliasAddHandler によって CGI スクリプトに設定されたリソースへの URL-path です。 Action-type には handlerMIME コンテントタイプを指定できます。リクエストされたドキュメントの URL とファイルのパスは標準 CGI 環境変数 PATH_INFOPATH_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-scriptScriptAliasAddHandler によって CGI スクリプトに設定されたリソースへの URL-path です。 リクエストされたドキュメントの URL とファイルのパスは標準 CGI 環境変数 PATH_INFOPATH_TRANSLATED を使って伝えられます。

任意のメソッド名を使用することができます。 メソッド名は大文字小文字を区別します。ですから、 Script PUTScript 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

翻訳済み言語:  de  |  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_alias.html.ja.utf80000664000175100017510000007633714743132254021727 0ustar covenercovener mod_alias - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_alias

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:ホストファイルシステム上のいろいろな違う場所を ドキュメントツリーにマップする機能と、 URL のリダイレクトを行なう機能を提供する
ステータス:Base
モジュール識別子:alias_module
ソースファイル:mod_alias.c

概要

このモジュールのディレクティブはサーバにリクエストが到着したときに URL の操作や制御をすることを可能にします。Alias ディレクティブと ScriptAlias ディレクティブは URL とファイルシステムのパスをマップするために使用されます。これは DocumentRoot の下にないドキュメントをウェブのドキュメントツリーの一部として 送られるようにします。ScriptAlias ディレクティブにはマップ先のディレクトリが CGI スクリプトのみであることを示すという追加の効果があります。

Redirect ディレクティブは クライアントに違った URL に新しいリクエストを送るように指示します。これは、 リソースが新しい場所に移動したときによく使用されます。

mod_alias は簡単な URL 操作向けに設計されています。 より複雑な操作、クエリーストリングの操作には、mod_rewrite で提供されるツールを使用してください。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

処理の順番

様々なコンテキスト中での Alias や Redirect は他のディレクティブと 同じように標準の マージ規則 に 従って処理されます。ただし、(例えば <VirtualHost> セクションの中のように) 複数の Alias や Redirect が 同じコンテキスト中に現れた場合は決まった順番で処理されます。

まず、Alias の前にすべての Redirect が処理されます。ですから、RedirectRedirectMatch にマッチするリクエストには 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> セクションはエイリアスが処理される前に実行されますので、 こちらは適用されます。)

特に、AliasDocumentRoot ディレクトリの外側に配置した場合は、行き先のディレクトリに対する アクセス権限を明示的に制限しなければならないでしょう。

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

AliasPreservePath ディレクティブ

説明:Map the full path after the alias in a location.
構文:AliasPreservePath OFF|ON
デフォルト:AliasPreservePath OFF
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Base
モジュール:mod_alias
互換性:2.4.58 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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

RedirectRelative ディレクティブ

説明:Allows relative redirect targets.
構文:RedirectRelative On|Off
デフォルト:RedirectRelative Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Base
モジュール:mod_alias
互換性:2.4.58 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_alias.html.ko.euc-kr0000664000175100017510000006262514743132254022241 0ustar covenercovener mod_alias - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_alias

ֽ ƴմϴ. ֱٿ ϼ.
:Ͻý ٸ κе ϰ, URL ̷ Ѵ
:Base
:alias_module
ҽ:mod_alias.c

ϴ þ Ͽ û URL ϰų ִ. Alias ScriptAlias þ URL Ͻý η Ѵ. ׷ DocumentRoot Ʒ ִ. , ScriptAlias þ 丮 CGI ũƮۿ ٰ ˸.

Redirect þ Ŭ̾Ʈ ٸ URL ο û ϵ Ѵ. ڿ ο ҷ ű Ѵ.

mod_alias URL Ǿ. ǹڿ ۰ ۾ mod_rewrite ϴ ̿϶.

Support Apache!

þ

Bugfix checklist

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

AliasPreservePath þ

:Map the full path after the alias in a location.
:AliasPreservePath OFF|ON
⺻:AliasPreservePath OFF
:ּ, ȣƮ, directory
:Base
:mod_alias
:2.4.58 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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

RedirectRelative þ

:Allows relative redirect targets.
:RedirectRelative On|Off
⺻:RedirectRelative Off
:ּ, ȣƮ, directory
:Base
:mod_alias
:2.4.58 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_dbm.html.ko.euc-kr0000664000175100017510000002613314743132254023103 0ustar covenercovener mod_authn_dbm - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_authn_dbm

ֽ ƴմϴ. ֱٿ ϼ.
: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 ϸ Ѵ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.ko.euc-kr0000664000175100017510000016300115032765673022451 0ustar covenercovener þ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

þ

:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

ǥ ġ 밡 þ ̴. ̵ Ͽ, ִ.

þ Ͽ þ ִ.

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/prefork.html.tr.utf80000664000175100017510000004154414743132254021472 0ustar covenercovener prefork - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache MPM prefork

Mevcut Diller:  de  |  en  |  fr  |  ja  |  tr 

Açıklama:Evresiz ön çatallamalı HTTP sunucusu oluşturur
Durum:MPM
Modül Betimleyici:mpm_prefork_module
Kaynak Dosyası:prefork.c

Özet

Bu çok süreçlilik modülü (MPM) evresiz ve çocuk süreçlerin önceden çatallandığı bir HTTP sunucusu oluşturur. Her çocuk süreç gelen bir isteğe yanıt verirken ebeveyn süreç çocuk süreç havuzunu yönetir. Evresiz kütüphanelerle uyumluluk için evrelemeden kaçınma ihtiyacında olan siteler için uygundur. Ayrıca istekleri birbirlerinden yalıtmak için en iyi MPM’dir, dolayısıyla herhangi bir istekle ilgili bir sorun diğerlerini etkilemez.

Bu MPM kendi kendine her duruma çok iyi uyum sağladığından yapılandırma yönergeleri ile yapılandırılmaya nadiren ihtiyaç gösterir. Yönergelerin en önemlisi MaxRequestWorkers olup, değeri aynı anda almayı umduğunuz istek sayısını işleyebilecek kadar büyük, fiziksel belleğin tüm süreçlerin ihtiyaçlarını karşılamasına yetecek kadar da küçük olması gerekir.

Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Nasıl çalışır?

Bağlantıları dinleyip gerektiğinde onlara hizmet sunan çocuk süreçleri devreye almak tek bir denetim sürecinin sorumluluğundadır. Apache httpd daima, gelen isteklere hizmet vermeye hazır bekleyen en fazla sayıda sunucu sürecini yedekte tutmaya veya boşta bekletmeye çalışır. Bu suretle, istemcilere isteklerinin sunulması için yeni çocuk süreçlerin çatallanmasını beklemek gerekmez.

Ana sürecin istekleri sunacak çocuk süreçleri oluşturma işlemini nasıl gerçekleştireceği StartServers, MinSpareServers, MaxSpareServers ve MaxRequestWorkers yönergeleri ile düzenlenir. Apache httpd kendiliğinden her duruma çok iyi uyum sağladığından, genelde, çoğu sitenin bu yönergelerin öntanımlı değerlerini değiştirmesi gerekmez. Aynı anda 256’dan fazla isteğe hizmet sunacak sitelerin MaxRequestWorkers değerini arttırmaları gerekebilir. Ancak, fiziksel belleği yeterli olmayan sitelerin de sunucunun belleği diske takaslamasını önlemek için bu değeri azaltmaları gerekebilir. Süreç oluşturmanın ayarlanması ile ilgili daha fazla bilgi edinmek için başarım arttırma ipuçları belgesine bakınız.

Unix altında 80. portu dinleyebilmek için ana sürecin root tarafından çalıştırılmış olması gerekirse de çocuk süreçler Apache httpd tarafından daha az yetkili bir kullanıcının aidiyetinde çalıştırılırlar. Apache httpd’nin çocuk süreçlerinin kullanıcı ve gruplarını ayarlamak için User ve Group yönergeleri kullanılır. Çocuk süreçlerin sunacakları içeriği okumaya yetkili olmaları gerekir, fakat bu yetkinin mümkün olduğunca kısıtlı tutulmasına çalışılmalıdır.

MaxConnectionsPerChild yönergesi ana sunucunun eski süreçleri öldürüp yenilerini oluşturmayı ne kadar sıklıkla yapacağını denetler.

Bu MPM, gürleyen sürü sorunu ortaya çıktığında (genelde çok sayıda dinlenen soket varlığında) gelen bağlantılara erişimi dizgileştirmek için mpm-accept muteksini kullanır. Bu muteksin gerçeklenimle ilgili hususları Mutex yönergesi ile yapılandırılabilir. Bu muteks hakkında ek bilgi için başarımın arttırılması belgesine bakınız.

top

MaxSpareServers Yönergesi

Açıklama:Boştaki çocuk süreçlerin azami sayısı
Sözdizimi:MaxSpareServers sayı
Öntanımlı:MaxSpareServers 10
Bağlam:sunucu geneli
Durum:MPM
Modül:prefork

MaxSpareServers yönergesi boştaki çocuk sunucu süreçlerinin azami sayısını belirler. Boştaki süreç, o an bir isteğe hizmet sunmayan süreçtir. Eğer MaxSpareServers sayıda süreçten daha fazla boşta süreç varsa ana süreç bu fazlalıkları öldürecektir.

Bu parametrenin ayarlanması sadece çok meşgul siteler için gerekli olabilir. Bu parametreye çok büyük bir değerin atanması oldukça kötü bir fikirdir. Eğer bu değeri MinSpareServers değerine eşit veya daha küçük bir değere ayarlarsanız, Apache HTTP Sunucusu bu değeri kendiliğinden MinSpareServers + 1 olarak değiştirecektir.

Ayrıca bakınız:

top

MinSpareServers Yönergesi

Açıklama:Boştaki çocuk süreçlerin asgari sayısı
Sözdizimi:MinSpareServers sayı
Öntanımlı:MinSpareServers 5
Bağlam:sunucu geneli
Durum:MPM
Modül:prefork

MinSpareServers yönergesi boştaki çocuk sunucu süreçlerinin asgari sayısını belirler. Boştaki süreç, o an bir isteğe hizmet sunmayan süreçtir. Eğer MinSpareServers sayıda süreçten daha az boşta süreç varsa ana süreç sayıyı tamamlamak için yeni çocuk süreçler oluşturacaktır: Bir tane oluşturur, 1 saniye bekler, sonra 2 tane oluşturur, 1 saniye bekler, sonra 4 tane oluşturur ve saniyede 32 çocuk süreç oluşturuluncaya kadar böyle üstel olarak artar. Artış MinSpareServers ile belirlenen sayıda duracaktır.

Bu parametrenin ayarlanması sadece çok meşgul siteler için gerekli olabilir. Bu parametreye çok büyük bir değerin atanması oldukça kötü bir fikirdir.

Ayrıca bakınız:

Mevcut Diller:  de  |  en  |  fr  |  ja  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_asis.html.ja.utf80000664000175100017510000002336714743132254021570 0ustar covenercovener mod_asis - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_asis

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:自分用の HTTP ヘッダの書かれているファイルを送信する
ステータス:Base
モジュール識別子:asis_module
ソースファイル:mod_asis.c

概要

このモジュールはハンドラ send-as-is を提供します。このハンドラは通常の HTTP ヘッダをほとんど追加することなくドキュメントを送信します。

これはサーバからどんな種類のデータを送るときにも使用できます。 Cgi スクリプトや nph スクリプトが無くてもリダイレクトや他の特別な HTTP 応答を送ることができます。

歴史的な理由により、このモジュールは mime タイプ httpd/send-as-is のファイルも処理します。

Support Apache!

トピック

ディレクティブ

このモジュールにディレクティブはありません。

Bugfix checklist

参照

top

使用法

サーバ設定ファイルで、ファイルと send-as-is ハンドラを例えば以下のように関連付けてください。

AddHandler send-as-is asis

拡張子が .asis のすべてのファイルの内容は Apache からクライアントへほとんど変更無く送られます。 HTTP ヘッダは特別で、ファイルから mod_cgi のルールに従って取り出されます。ですから asis ファイルには 正しいヘッダが記載されていなければなりませし、 また CGI での表記法であるところの Status: ヘッダを使って 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 ヘッダを追加しません。 おそらくはそうすべきでしょうけれど。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache_disk.html.ja.utf80000664000175100017510000004456514743132254022711 0ustar covenercovener mod_cache_disk - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_cache_disk

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:URI をキーにしたコンテンツキャッシュストレージ管理
ステータス:Extension
モジュール識別子:cache_disk_module
ソースファイル:mod_cache_disk.c

概要

mod_cache_disk はディスクを使用したストレージ 管理機構を実装しています。主に mod_cache と組み合わせて使われます。

コンテンツのキャッシュへの保存と取得は URI に基づいたキーが使われます。 アクセス保護のかけられているコンテンツはキャッシュされません。

キャッシュの大きさを最大レベルで維持するために htcacheclean を使うことができます。

注:

mod_cache_diskmod_cache を必要とします

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

CacheDirLength ディレクティブ

説明:サブディレクトリ名の文字数
構文:CacheDirLength length
デフォルト:CacheDirLength 2
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache_disk

CacheDirLength ディレクティブはキャッシュ 階層の各サブディレクトリの文字数を設定します。 CacheDirLevels と組み合わせて設定することで、 キャッシュ階層のおおよその構造を決めることができます。

CacheDirLength が大きくて CacheDirLevels が小さい場合、 比較的浅い階層になりますが、 各階層のサブディレクトリの数は多くなります。

CacheDirLevels* CacheDirLength の 結果は 20 以内でなければなりません。

top

CacheDirLevels ディレクティブ

説明:キャッシュのサブディレクトリの深さの数
構文:CacheDirLevels levels
デフォルト:CacheDirLevels 2
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache_disk

CacheDirLevels ディレクティブはキャッシュの サブディレクトリの深さを設定します。キャッシュデータは CacheRoot ディレクトリから このディレクトリの深さ分下のディレクトリに保存されます。

CacheDirLevels が大きくて CacheDirLength が小さい場合、 比較的深い階層になりますが、 各階層のサブディレクトリの数は少なくなります。

CacheDirLevels* CacheDirLength の 結果は 20 以内でなければなりません。

top

CacheMaxFileSize ディレクティブ

説明:キャッシュに保管されるドキュメントの最大の (バイトでの) サイズ
構文:CacheMaxFileSize bytes
デフォルト:CacheMaxFileSize 1000000
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache_disk

CacheMaxFileSize ディレクティブは、ドキュメントを キャッシュするかどうかを判定する、最大のサイズをバイト数で設定します。

CacheMaxFileSize 64000

top

CacheMinFileSize ディレクティブ

説明:キャッシュに保管されるドキュメントの最小限の (バイトでの) 大きさ
構文:CacheMinFileSize bytes
デフォルト:CacheMinFileSize 1
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache_disk

CacheMinFileSize ディレクティブは、ドキュメントを キャッシュするかどうかを判定する、最小のサイズをバイト数で設定します。

CacheMinFileSize 64

top

CacheReadSize ディレクティブ

説明:The minimum size (in bytes) of the document to read and be cached before sending the data downstream
構文:
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_cache_disk

Documentation not yet translated. Please see English version of document.

top

CacheReadTime ディレクティブ

説明:The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
構文:
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_cache_disk

Documentation not yet translated. Please see English version of document.

top

CacheRoot ディレクティブ

説明:キャッシュファイルが保管されるルートディレクトリ
構文:CacheRoot directory
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache_disk

CacheRoot ディレクティブはキャッシュファイルを 保管するためのディスク上のディレクトリを指定します。mod_cache_disk モジュールが Apache サーバにロードされて いるか、組み込まれていれば、このディレクティブは必ず 定義しなければなりません。 CacheRoot の値を指定しなければ、 設定ファイルの処理でエラーになります。CacheDirLevels ディレクティブと CacheDirLength ディレクティブが 指定されたルートディレクトリ下のディレクトリ構成を定義します。

CacheRoot c:/cacheroot

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_digest.html.ko.euc-kr0000664000175100017510000005064114743132254023443 0ustar covenercovener mod_auth_digest - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_auth_digest

ֽ ƴմϴ. ֱٿ ϼ.
:MD5 Digest Authentication .
:Experimental
:auth_digest_module
ҽ:mod_auth_digest.c

HTTP Digest Authentication Ѵ. ׷ ׽Ʈ ġ ̴.

Support Apache!

þ

Bugfix checklist

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

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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_dbm.html.ja.utf80000664000175100017510000003210314743132254022556 0ustar covenercovener mod_authn_dbm - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_authn_dbm

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:DBM ファイルを用いたユーザ認証
ステータス:Extension
モジュール識別子:authn_dbm_module
ソースファイル:mod_authn_dbm.c
互換性:Apache 2.1 以降

概要

本モジュールは mod_auth_digestmod_auth_basic といった認証フロントエンドに対して、 dbm パスワードファイル内からのユーザ検索による ユーザ認証機能を提供します。似たような機能は mod_authn_file でも提供されています。

mod_auth_basicmod_auth_digest を使用する際には、このモジュールは AuthBasicProviderAuthDigestPrividerdbm と指定することで起動されます。

Support Apache!

ディレクティブ

Bugfix checklist

参照

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 フォーマットのパスワードファイルを作成したり 更新したりすることができます。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_anon.html.ko.euc-kr0000664000175100017510000004006314743132254023272 0ustar covenercovener mod_authn_anon - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_authn_anon

ֽ ƴմϴ. ֱٿ ϼ.
: "͸(anonymous)" Ѵ
:Extension
:authn_anon_module
ҽ:mod_authn_anon.c
:ġ 2.1 ĺ

mod_auth_basic մܸ ( 'Ư' ̵ 'anonymous' ڿ ּҸ ȣ ϴ) ͸-ftp Ʈ Ѵ. ڿ ּҸ α׿ ִ.

ٸ (ͺ̽) İ Բ Ͽ '' ڿ Ʈ θ鼭 ȿ ǰ ϴ. Ű URL λ/̻ ޸ ̰ ڰ URL ִٴ ִ.

mod_auth_basic Ҷ AuthBasicProvider anon ϸ Ѵ.

Support Apache!

þ

Bugfix checklist

top

"Ϲ" htpasswd-ϱ ߰ ڰ Ѵٸ 'մ(guest)' ֵ Ѵ:

<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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.de0000664000175100017510000016344515032765673021257 0ustar covenercovener Verzeichnis der Direktiven - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Verzeichnis der Direktiven

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_autoindex.html.tr.utf80000664000175100017510000020422214743132254022653 0ustar covenercovener mod_autoindex - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_autoindex

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:Unix ls veya Win32 dir kabuk komutunun yaptığı gibi dizin içeriğini listeler.
Durum:Temel
Modül Betimleyici:autoindex_module
Kaynak Dosyası:mod_autoindex.c

Özet

Bir dizin içerik dosyası iki kaynaktan gelebilir:

İki işlev birbirinden ayrı tutulmuştur, böylece kendiliğinden içerik listesi üretimi tamamen iptal edilebilir (veya değiştirilebilir).

Kendiliğinden içerik listesi üretimi Options +Indexes ile etkin kılınabilir. Daha fazla bilgi için Options yönergesinin açıklamasına bakınız.

IndexOptions yönergesi FancyIndexing seçeneği ile kullanılmışsa sütun başlıkları listenin sıralamasını sütundaki sıralamaya göre değiştirecek hiper bağlar haline getirilir (süslü liste). Aynı başlığa peşpeşe tıklamak suretiyle sıralamayı büyükten küçüğe veya tersine değiştirebilirsiniz. Bu sütun başlığı bağlarının oluşturulması IndexOptions yönergesi SuppressColumnSorting seçeneği ile kullanılarak engellenebilir.

Boyuta göre sıralamada daima dosyanın asıl boyutuna bakılır. Dolayısıyla ikisi de "1K" olarak gösterilen iki dosyadan 1010 baytlık olanı küçükten büyüğe sıralamada 1011 baytlıktan önce gösterilecektir.

Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Sütun Sıralamada Sorgu Seçenekleri

İstemciye, dizin içeriğini listelerken neleri hangi sırada listeleyeceğini belirleyebilmesi için içerik üzerinde biraz denetim sağlayabileceği çeşitli sorgu dizgesi bileşenleri sağlanmıştır. Çıktı üzerinde kullanıcı denetimini tamamen ortadan kaldırmak için IndexOptions yönergesinin IgnoreClient seçeneği kullanılabilir.

Sütun sıralama başlıklarının her biri hedefi kendisi olan birer hiper bağ olup aşağıda sıralanan sorgu seçeneklerini kullanırlar. Bu seçeneklerin her biri her dizin içerik listesi isteğine eklenebilir.

P=kalıp sorgu seçeneğinin normalde IndexIgnore yönergesi işleme sokulduktan sonra değerlendirildiğine ve dosya isimlerinin diğer kendiliğinden içerik listeleme koşullarının konusu olmaya devam ettiğine dikkat ediniz. mod_autoindex modülündeki Sorgu Seçenekleri çözümleyicisi tanımadığı bir seçeneğe rastlar rastlamaz işlemi durdurur. Sorgu Seçenekleri yukarıda belirtilene uygun olarak iyi biçimli olmak zorundadır.

Aşağıdaki basit örnekte sorgu seçeneklerinin kullanımı gösterilmiştir. Son satırda bulunan "submit" düğmesindeki tanınmayan "X" girdisine dikkat ediniz. "X=Göster" girdisi tüm seçenekler işlendikten sonra mod_autoindex tarafından son argüman olarak ele alınacak ve çözümleme işlemi o noktada duracaktır.

Örnek

<form action="" method="get">
   <input type="text" name="P" value="*" /> ile eşleşen
   <select name="C">
       <option value="N" selected="selected">isme</option>
       <option value="M"> değişiklik tarihine</option>
       <option value="S"> boyuta</option>
       <option value="D"> açıklamaya</option>
   </select> göre
   <select name="O">
       <option value="A" selected="selected"> artan</option>
       <option value="D"> azalan</option>
   </select>
   <select name="V">
       <option value="0" selected="selected">normal</option>
       <option value="1"> sürümlü</option>
   </select> sıralamayla bir
   <select name="F">
       <option value="0"> basit liste</option>
       <option value="1" selected="selected"> süslü liste</option>
       <option value="2"> tablolu liste</option>
   </select>
   <input type="submit" name="X" value="Göster" />
</form>
top

AddAlt Yönergesi

Açıklama:Dosyaya göre seçilen simgenin yerinde gösterilecek metni belirler.
Sözdizimi:AddAlt metin dosya [dosya] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

AddAlt yönergesi, FancyIndexing seçeneğiyle üretilen dizin listesinde bir dosya simgesinin yerinde gösterilecek metni belirler. dosya olarak dosya türünü betimleyecek bir dosya uzantısı, dosya isminin bir kısmı, bir dosya ismi kalıbı veya tam yoluyla bir dosya ismi belirtilebilir. Eğer metin boşluk karakterleri içeriyorsa tırnak içine (" veya ') alınmalıdır. Simge metni, simge bulunamadığı veya istemci resim gösteremediği takdirde ya da kullanıcı resim yüklememeyi tercih etmişse gösterilir.

AddAlt "PDF file" *.pdf
AddAlt Compressed *.gz *.zip *.Z
top

AddAltByEncoding Yönergesi

Açıklama:Dosyanın MIME kodlamasına göre seçilen simgenin yerinde gösterilecek metni belirler.
Sözdizimi:AddAltByEncoding metin MIME-kodlaması [MIME-kodlaması] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

AddAltByEncoding yönergesi, FancyIndexing seçeneğiyle üretilen dizin listesinde bir dosya simgesinin yerinde gösterilecek metni belirler. MIME-kodlaması olarak x-compress gibi geçerli bir içerik kodlaması belirtilmelidir. Eğer metin boşluk karakterleri içeriyorsa tırnak içine (" veya ') alınmalıdır. Simge metni simge bulunamadığı veya istemci resim gösteremediği takdirde ya da kullanıcı resim yüklememeyi tercih etmişse gösterilir.

AddAltByEncoding gzip x-gzip
top

AddAltByType Yönergesi

Açıklama:Dosyanın MIME türüne göre seçilen simgenin yerinde gösterilecek metni belirler.
Sözdizimi:AddAltByType metin MIME-türü [MIME-türü] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

AddAltByType yönergesi, FancyIndexing seçeneğiyle üretilen dizin listesinde bir dosya simgesinin yerinde gösterilecek metni belirler. MIME-türü olarak text/html gibi geçerli bir içerik türü belirtilmelidir. Eğer metin boşluk karakterleri içeriyorsa tırnak içine (" veya ') alınmalıdır. Simge metni simge bulunamadığı veya istemci resim gösteremediği takdirde ya da kullanıcı resim yüklememeyi tercih etmişse gösterilir.

AddAltByType 'salt metin' text/plain
top

AddDescription Yönergesi

Açıklama:Bir dosya için gösterilecek açıklama belirtilir.
Sözdizimi:AddDescription metin dosya [dosya] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

Yönerge, FancyIndexing seçeneğiyle üretilen dizin listesinde bir dosya için gösterilecek açıklamayı belirler. dosya olarak dosya türünü betimleyecek bir dosya uzantısı, dosya isminin bir kısmı, bir dosya ismi kalıbı veya tam yoluyla bir dosya ismi belirtilebilir. Eğer dosya açıklamasını içeren metin boşluk karakterleri içeriyorsa çift tırnak (") içine alınmalıdır.

AddDescription "Mars Gezegeni" mars.gif 
AddDescription "Dostum Marshall" dostlar/mars.gif

Normalde öntanımlı açıklama alanının genişliği 23 bayttır. IndexOptions SuppressIcon seçeneği buna 6 bayt daha ekler; IndexOptions SuppressSize seçeneği 7 bayt, IndexOptions SuppressLastModified seçeneği ise 19 bayt ekler. Böylece en fazla 55 karakterlik öntanımlı sütun genişliğine ulaşılabilir.

dosya kısmî dosya ismi içerebileceğinden çok kısa dosya ismi belirtilmesi yüzünden istemeden de olsa başka dosyalarla eşleşebileceğini unutmayın. Örneğin, le.html doğrudan le.html ile eşleşebileceği gibi example.html ile de eşleşecektir. Şüpheli durumların ortaya çıkabileceği durumlarda mümkün olduğunca dosya isminin tamamını kullanın ve saptanan ilk eşleşmenin kullanılacağını aklınızdan çıkarmayın ayrıca, AddDescription listesini de uygun şekilde sıralayın.

Açıklama sütununun öntanımlı genişliği geçersiz kılınabilir hatta sınırsız açıklama uzunluğu atanabilir. Bu konu için IndexOptions yönergesinin DescriptionWidth seçeneğinin açıklamasına bakınız.

Önemli

AddDescription ile tanımlanan açıklama metni HTML etiketleri ve karakter öğeleri içerebilir. Eğer açıklama sütununun genişlik sınırlamasından dolayı bir HTML etiketinin içeriği kırpılırsa bu durum dizin listesinin kalanını etkileyebilir (örneğin, kalın gösterim listenin kalanına yayılabilir).

Yol bilgisi içeren değiştirgeler

Mutlak yollar henüz desteklenmemetedir ve çalışma anında hiçbir şeyle eşleşmeyeceklerdir. Normalde sadece htaccess bağlamında kullanılan, göreli yol bilgisi içeren değiştirgeler, kısmi dizin isimleriyle eşleşmemeleri için örtük olarak '*/' öneki alırlar.

top

AddIcon Yönergesi

Açıklama:Bir dosya için gösterilecek simgeyi dosya adına göre belirler.
Sözdizimi:AddIcon simge isim [isim] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

Yönerge, FancyIndexing seçeneğiyle üretilen dizin listesinde adı isim ile biten bir dosya için gösterilecek simgeyi belirler. simge ya simgenin göreli URL’si (% öncelemeli), tam nitelenmiş bir uzak URL ya da (alt-metin,url) biçeminde olmalıdır; buradaki alt-metin simge gösterilemediği durumda tarayıcı tarafından simgenin yerinde gösterilecek metindir.

isim olarak ya (listeyi düzgün biçemlemek amacıyla) dizinler için ^^DIRECTORY^^, boş satırlar için ^^BLANKICON^^ ya da dosya türünü betimleyecek bir dosya uzantısı, dosya isminin bir kısmı, bir dosya ismi kalıbı veya tam yoluyla bir dosya ismi belirtilebilir.

^^BLANKICON^^ sadece biçemleme için kullanılır, dolayısıyla IndexOptions HTMLTable kullanıyorsanız gereksizdir.

#Examples
AddIcon (IMG,/icons/image.png) .gif .jpg .png
AddIcon /icons/dir.png ^^DIRECTORY^^
AddIcon /icons/backup.png *~

Mümkünse AddIcon yerine AddIconByType yönergesi tercih edilmelidir.

top

AddIconByEncoding Yönergesi

Açıklama:Bir dosya için gösterilecek simgeyi dosyanın MIME kodlamasına göre belirler.
Sözdizimi:AddIconByEncoding simge MIME-kodlaması [MIME-kodlaması] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

Yönerge, FancyIndexing seçeneğiyle üretilen dizin listesinde bir dosya için gösterilecek simgeyi belirler. simge ya simgenin göreli URL’si (% öncelemeli), tam nitelenmiş uzak bir URL ya da (alt-metin,url) biçeminde olmalıdır; buradaki alt-metin simge gösterilemediği durumda tarayıcı tarafından simgenin yerinde gösterilecek metindir.

MIME-kodlaması olarak x-compress gibi geçerli bir içerik kodlaması belirtilmelidir.

AddIconByEncoding /icons/compress.png x-compress
top

AddIconByType Yönergesi

Açıklama:Bir dosya için gösterilecek simgeyi dosyanın MIME türüne göre belirler.
Sözdizimi:AddIconByType simge MIME-türü [MIME-türü] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

Yönerge, FancyIndexing seçeneğiyle üretilen dizin listesinde MIME türü MIME-türü olarak belirtilen bir dosya için gösterilecek simgeyi belirler. simge ya simgenin göreli URL’si (% öncelemeli), tam nitelenmiş uzak bir URL ya da (alt-metin,url) biçeminde olmalıdır; buradaki alt-metin simge gösterilemediği durumda tarayıcı tarafından simgenin yerinde gösterilecek metindir.

MIME-türü MIME türleri ile eşleşen bir dosya kalıbı ifadesi olabilir.

AddIconByType (IMG,/icons/image.png) image/*
top

DefaultIcon Yönergesi

Açıklama:Özel bir simge atanmamış dosyalar için gösterilecek simgeyi belirler.
Sözdizimi:DefaultIcon URL-yolu
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

The DefaultIcon yönergesi FancyIndexing seçeneğiyle üretilen dizin listesinde özel bir simge atanmamış dosyalar için gösterilecek simgeyi belirler. URL-yolu simgeye bir göreli URL (% öncelemeli) veya tam nitelenmiş uzak bir URL belirtir.

DefaultIcon /icon/unknown.png
top

HeaderName Yönergesi

Açıklama:Dizin listesinin tepesine yerleştirilecek dosyanın ismini belirler.
Sözdizimi:HeaderName dosya-ismi
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

HeaderName yönergesi, dizin listesinin tepesine yerleştirilecek dosyanın ismini belirler. Dosyanın ismi dosya-ismi ile belirtilir.

HeaderName HEADER.html

HeaderName and ReadmeName yönergelerinde dosya-ismi artık içeriği listelenecek dizine erişmek için kullanılan bir göreli URL yolu olarak ele alınmaktadır. Eğer dosya-ismi bir bölü çizgisi ("/") ile başlıyorsa DocumentRoot yönergesinde belirtilen dizine göre belirtildiği varsayılır.

HeaderName /include/HEADER.html

dosya-ismi, içerik türü text/* (text/html, text/plain gibi) olan bir belge olarak çözümlenmelidir. Yani, aşağıdaki örnekteki gibi betiğin asıl dosya türü text/html olarak imlenmişse dosya-ismi bir CGI betiğinin ismi bile olabilir:

AddType text/html .cgi

Options ile MultiViews etkin kılınmışsa dosyaya içerik dili uzlaşımı da uygulanabilir. dosya-ismi ile belirtilen dosya text/html türünde durağan bir belge (bir CGI betiği değil) ise ve options ile Includes ve IncludesNOEXEC seçeneklerinden biri belirtilmişse dosya bir SSI sayfası olarak ele alınır (mod_include belgesine bakınız).

Eğer yönergede belirtilen dosya bir HTML belge gibi başlıyorsa (<html>, <head>, vs.) ve bu etiketlerin yinelenmemesini istiyorsanız IndexOptions +SuppressHTMLPreamble ataması yapmanız gerekecektir.

Ayrıca bakınız:

top

IndexHeadInsert Yönergesi

Açıklama:Bir dizin sayfasının HEAD bölümüne metin yerleştirir.
Sözdizimi:IndexHeadInsert "imlenim ..."
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

IndexHeadInsert yönergesi, dizin listesi için üretilen HTML’nin <head> bölümüne yerleştirilecek bir dizge tanımlar.

IndexHeadInsert "<link rel=\"sitemap\" href=\"/sitemap.html\">"
top

IndexIgnore Yönergesi

Açıklama:Dizin içerik listesinden gizlenecek dosyaların listesi belirtilir.
Sözdizimi:IndexIgnore dosya [dosya] ...
Öntanımlı:IndexIgnore "."
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

IndexIgnore yönergesi, dizin içerik listesinden gizlenecek dosyaların listesini belirtmek için kullanılır. dosya olarak kabuk tarzı bir dosya ismi kalıbı veya tam yoluyla bir dosya ismi belirtilebilir. Evvelce yapılmış bir atamada değişiklik yapmak yerine birden fazla IndexIgnore ataması yapabilirsiniz. Liste öntanımlı olarak içinde bulunulan dizini (./) içerir.

IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t

Düzenli İfadeler

Bu yönerge, <DirectoryMatch> gibidüzenli ifadeler içeren yapılandırma bölümlerinde henüz çalışmamaktadır.

top

IndexIgnoreReset Yönergesi

Açıklama:Bir dizini listelerken gizlenecek dosyalar listesini boşaltır
Sözdizimi:IndexIgnoreReset ON|OFF
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex
Uyumluluk:Apache HTTP Sunucusunun 2.3.10 ve sonraki sürümlerinde kullanılabilmektedir.

Bu yönerge, diğer yapılandırma bölümlerince bir şekilde miras alınmayan ve IndexIgnore tarafından yoksayılan dosyaları kaldırır.

<Directory "/var/www">
    IndexIgnore *.bak .??* *~ *# HEADER* README* RCS CVS *,v *,t
</Directory>
<Directory "/var/www/backups">
    IndexIgnoreReset ON
    IndexIgnore .??* *# HEADER* README* RCS CVS *,v *,t
</Directory>

Bu yönergeyi kullandıktan sonra, açıkça yoksaymak istediğiniz kalıpların bir listesi için öntanımlı yapılandırmayı gözden geçirin.

top

IndexOptions Yönergesi

Açıklama:Dizin içerik listesini yapılandıracak seçenekler belirtilir.
Sözdizimi:IndexOptions [+|-]seçenek [[+|-]seçenek] ...
Öntanımlı:Öntanımlı olarak hiçbir seçenek etkin değildir.
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

IndexOptions yönergesi dizin içerik listesinin davranışını belirler. seçenek olarak şunlar belirtilebilir:

AddAltClass
IndexOptions HTMLTable etkin ve bir IndexStyleSheet tanımlı olduğunda dizin listesi tablosunun her satırına fazladan bir CSS sınıfı bildirimi ekler. Tablonun her satırına uygulanmaması için standart even ve odd sınıfları yerine even-ALT ve odd-ALT bildirimleri kullanılabilir. Burada ALT ya bir dosya biçimiyle ilişkili standat bir alt dizgesidir ya da AddAlt* yönergeleriyle tanımlanan bir alt dizgesidir.
Charset=karakter-kümesi
Charset seçeneği üretilen sayfa için bir karakter kümesi belirtebilmenizi sağlar. Dizinin bulunduğu dosya sisteminin karakter kodlamasına bağlı olarak öntanımlı değeri Windows ve Mac OS X'te UTF-8, diğerlerinde ISO-8859-1’dir (İlgili dosya sisteminin Unicode dosya isimleri kullanıp kullanmamasına bağlıdır).
IndexOptions Charset=UTF-8
DescriptionWidth=[n | *]

DescriptionWidth seçeneği üretilen sayfada açıklama sütununun genişliğini sizin belirleyebilmenizi sağlar. Bu seçenek kullanılmadığında veya -DescriptionWidth olarak belirtildiğinde uygun genişliği mod_autoindex hesaplar.

DescriptionWidth=n ile açıklama sütununun genişliği n baytla sınırlanır.

DescriptionWidth=* ile açıklama sütununun genişliği en uzun açıklama metni sığacak şekilde arttırılır.

Sütun genişliğinin sabitliği nedeniyle metnin kırpılmasından kaynaklanan sorunlar için AddDescription yönergesinin açıklamasına bakınız.

FancyIndexing
Dizin içerik listesi süslü olur.
FoldersFirst
Bu seçenek etkin kılındığında dizin içerik listesinde alt dizinler dosyalardan önce listelenir. Listelemede genel olarak iki bileşen vardır: Alt dizinler ve dosyalar. Her biri kendi arasında sıraya dizilir ve alt dizinlerin tamamı dosyalardan önce gösterilir. Örneğin sıralama isme göre azalan sırada yapılıyorsa ve FoldersFirst etkinse Zed dizini listede Beta dizininden ve Gamma ve Alpha dosyalarından önce yer alacaktır. Bu seçenek sadece FancyIndexing seçeneği etkinse etkili olacaktır.
HTMLTable
FancyIndexing seçeneği ile birlikte süslü listeleme için basit bir tablo oluşturur. UTF-8'in etkin olduğu platformlarda gereklidir. Bununla birlikte, Linux, WinNT gibi sağdan sola veya soldan sağa yazım yönünün değiştiği platformlarda dosya isimleri ve açıklamalar için bu özellikle gerekli olabilir.
IconsAreLinks
Bu seçenek FancyIndexing seçeneği ile birlikte süslü listelemede dosya simgesini dosyaya bir hiper bağ haline getirir.
IconHeight[=benek-sayısı]
Bu seçeneğin varlığı IconWidth seçeneği ile kullanıldığında dosya simgesinin img etiketinin height ve width özniteliklerini içermesine sebep olur. Böylece tarayıcının tüm simgelerin yüklenmesini beklemeden sayfa yerleşimi için bir ön hesaplama yapabilmesi mümkün olur. Seçenek bir değer belirtilmeksizin kullanıldığında Apache http tarafından atanmış standart simge yüksekliği öntanımlıdır. Bu seçenek sadece FancyIndexing seçeneği etkinse etkili olacaktır.
IconWidth[=benek-sayısı]
Bu seçeneğin varlığı IconHeight seçeneği ile kullanıldığında dosya simgesinin img etiketinin height ve width özniteliklerini içermesine sebep olur. Böylece tarayıcının tüm simgelerin yüklenmesini beklemeden sayfa yerleşimi için bir ön hesaplama yapabilmesi mümkün olur. Seçenek bir değer belirtilmeksizin kullanıldığında Apache httpd tarafından atanmış standart simge genişliği öntanımlıdır.
IgnoreCase
Bu seçenek etkin kılındığında isimler harf büyüklüğüne duyarsız sıralanır. Örneğin, isme göre artan sıralamada IgnoreCase etkinse Zeta dosyası alfa dosyasından sonra listelenir (Dikkat: GAMMA daima gamma’dan önce listelenir.)
IgnoreClient
Bu seçenek mod_autoindex’in listenin sıralanmasına etki edenler dahil tüm sorgu değişkenlerini yoksaymasına sebep olur (örtük olarak SuppressColumnSorting uygulanır).
NameWidth=[n | *]

NameWidth seçeneği dosya ismi sütunu için bir genişlik belirtebilmenizi mümkün kılar.

Hiç belirtilmediğinde veya -NameWidth biçeminde belirtildiğinde mod_autoindex uygun genişliği kendisi hesaplayacaktır, fakat en fazla 20 karakter olabilir.

NameWidth=n ile sütun genişliği n bayt genişlikte sabitlenir.

NameWidth=* olduğunda ise sütun genişliği en geniş satırın sığacağı kadar arttırılır.

ScanHTMLTitles
Bu seçenek süslü listeleme için HTML belgelerden sayfa başlığının okunmasını sağlar. Dosya için AddDescription ile bir açıklama tanımlanmımışsa Apache httpd belgenin title etiketinin içeriğini okuyacaktır. Bu seçenek işlemciyi ve diski fazla meşgul eder.
ShowForbidden
Alt istek HTTP_UNAUTHORIZED veya HTTP_FORBIDDEN döndürdüğünden dolayı normalde gizli olan dosyalar bu seçenek belirtilmişse listede gösterilir.
SuppressColumnSorting
Bu seçenek belirtilmişse Apache, süslü dizin listesinde sütun başlıklarını sıralama için hiper bağ haline getirmeyecektir. Sütun başlıkları için öntanımlı davranış hiper bağ olmak olup bunlar seçilerek dizin listesinin o sütundaki değerlere göre sıralanması sağlanır. Bu davranış IndexOptions IgnoreClient ile sağlanmaktadır.
SuppressDescription
Süslü listelemede dosya açıklamalarının gösterilmesini engeller. Öntanımlı olarak hiçbir dosya açıklaması tanımlı değildir, dolayısıyla bu seçenek kullanılarak ekran genişliğinden 23 karakterlik yer kazanılabilir. Dosya açıklamalarının nasıl belirlendiğini öğrenmek için AddDescription yönergesinin açıklamasına bakınız. Ayrıca, açıklama sütununun genişliğini ayarlayan DescriptionWidth dizin listeleme seçeneğine de bakınız. Bu seçenek sadece FancyIndexing seçeneği etkinse etkili olacaktır.
SuppressHTMLPreamble
Eğer dizin aslında HeaderName yönergesi ile belirtilmiş bir dosya içeriyorsa modül normal olarak bu dosyanın içeriğinin öncesine HTML başlangıç etiketlerini (<html>, <head>, vs.) yerleştirir. Bu seçenek bu davranışı iptal ederek modülün dosya içeriğinin başlangıcına bir şey eklememesini sağlar. Bu durumda başlık dosyasının uygun HTML etiketlerini içermesi gerekir. Böyle bir başlık dosyası yoksa normal olarak HTML başlangıç etiketleri üretilir. Eğer bir ReadmeName yönergesi de belirtilirse ve bu dosya mevcutsa, kapayan </body></html> etiketleri de çıktı bulunmaz. Buna dayanarak bu etiketleri de sizin koymanız gerekebilir.
SuppressIcon
Süslü dizin listesinde dosya simgelerinin gösterilmesini engeller. Son belirtim, süslü dizin listelemede kullanılan pre etiketinin içeriğinde img ve hr etiketlerinin bulunmasına izin vermediğinden SuppressIcon ve SuppressRules seçenekleri birlikte kullanılarak HTML 3.2 belirtimine uyum sağlanır.
SuppressLastModified
Süslü dizin listelemede son değişiklik tarihinin gösterilmesi engellenir. Bu seçenek sadece FancyIndexing seçeneği etkinse etkili olacaktır.
SuppressRules
Dizin listelemede hr etiketinin kullanımını engeller. Son belirtim, süslü dizin listelemede kullanılan pre etiketinin içeriğinde img ve hr etiketlerinin bulunmasına izin vermediğinden SuppressIcon ve SuppressRules seçenekleri birlikte kullanılarak HTML 3.2 belirtimine uyum sağlanır. Bu seçenek sadece FancyIndexing seçeneği etkinse etkili olacaktır.
SuppressSize
Süslü dizin listelemede dosya boyutunun gösterilmesi engellenir. Bu seçenek sadece FancyIndexing seçeneği etkinse etkili olacaktır.
TrackModified
Bu seçenek listelenen dizin için HTTP başlığında Last-Modified ve ETag alanlarının dönmesini sağlar. Sadece işletim sistemi veya dosya sistemi uygun stat() sonuçlarını döndürüyorsa bu geçerlidir. Bazı Unix sistemleri ve OS/2'nin JFS'si ile Win32’nin NTFS’i böyledir. Ancak OS/2 ve Win32 FAT dosya sistemleri böyle değildir. Bu özellik etkin kılındığında istemci veya vekil HEAD istekleriyle dosya listesindeki değişiklikleri izleyebilirler. Yalnız, bazı işletim sistemlerinin yeni ve silinmiş dosyaların izini iyi sürdüğü halde dizin içindeki dosyaların boyut ve tarih değişikliklerini izlemediklerine dikkat ediniz. Mevcut bir dosyanın boyut ve zaman damgasındaki değişiklikler Last-Modified başlığının güncellenmesini tüm Unix sistemlerinde sağlamaz. Bu gibi durumlarda bu seçeneğin kapalı kalması daha iyidir.
Type=MIME-türü
Type anahtar sözcüğü üretilen sayfanın MIME içerik türünün belirtilebilmesini sağlar. text/html öntanımlıdır.
IndexOptions Type=text/plain
UseOldDateFormat (Apache HTTP Sunucusu 2.4.26 ve sonrasında)
Last Modified alanı tarafından kullanılan tarih biçemi "%Y-%m-%d %H:%M" dikkatsizlik sonucu 2.4.0 sürümünde "%d-%b-%Y %H:%M" olarak değişmiştir. Bu seçenekle tarih biçemini 2.2 ve öncesindeki biçemiyle kullanabilirsiniz.
VersionSort
VersionSort seçeneği isimlerinde sürüm numarası bulunan dosyaların sayısal sıralamaya uygun olarak sıralanmalarını sağlar. Normalde sıralama karakter sıralamasına göre yapılır, ardından sürüm numaralı dosyalar veya açıklamalar kendi aralarında sayısal sıralamaya tabi tutulur.

Örnek:

foo-1.7
foo-1.7.2
foo-1.7.12
foo-1.8.2
foo-1.8.2a
foo-1.12

Sıfır ile başlalan numaralara ondalık sayı muamelesi yapılır:

foo-1.001
foo-1.002
foo-1.030
foo-1.04

XHTML
XHTML seçeneği mod_autoindex’in kodu HTML 3.2’ye değil XHTML 1.0’a uygun üretmesini sağlar. Bu seçenek sadece FancyIndexing seçeneği etkinse etkili olacaktır.
+ veya - Önekli Seçenekler

Çok sayıda IndexOptions yönergesinin işlenebileceğine dikkat edin.

  • Tek bir dizin için çok sayıda IndexOptions yönergesi belirtilmişse bunlar ayrı ayrı değil birlikte ele alınır. Yani,
    <Directory "/foo">
        IndexOptions HTMLTable
        IndexOptions SuppressColumnsorting
    </Directory>

    yapılandırmasındaki IndexOptions yönergeleri

    IndexOptions HTMLTable SuppressColumnsorting

    yönergesine eşdeğerdir.

  • Seçeneklerde + veya - önekleri kullanılabilmektedir.

+ veya - önekli seçeneklere rastlandığında bunlar mevcut (üst dizinden miras alınanlar ve/veya önceki atamalar) IndexOptions yönergelerine uygulanır. Ancak, önek kullanılmamış bir seçeneğe raslandığında, o noktada önceki ve miras alınmış bu tür seçenekler iptal edilir. Şu örneği ele alalım:

IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
IndexOptions +SuppressSize

Bunun net etkisi IndexOptions FancyIndexing +SuppressSize atamasına eşdeğerdir, çünkü öneksiz FancyIndexing seçeneği kendinden önceki önekli seçenekleri iptal etmiş fakat hemen ardından eklenmelerine izin vermiştir.

Belli bir dizine önceki seçenekleri temizleyerek koşulsuz olarak tamamen yeni seçenekler atamak istiyorsanız IndexOptions yönergesinde seçenekleri + veya - öneklerini kullanmadan belirtiniz.

top

IndexOrderDefault Yönergesi

Açıklama:Dizin içerik listesinin öntanımlı sıralamasını belirler.
Sözdizimi:IndexOrderDefault Ascending|Descending Name|Date|Size|Description
Öntanımlı:IndexOrderDefault Ascending Name
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

IndexOrderDefault yönergesi FancyIndexing seçeneğinin etkin olduğu durumda işe yarar. Öntanımlı olarak süslü listelemede dizin içeriği dosya ismine göre artan sıralamayla listelenir. IndexOrderDefault yönergesi bu öntanımlı sıralamanın değiştirilmesini mümkün kılar.

IndexOrderDefault yönergesi iki değer alır. İlki sıralama yönünü belirtmek üzere Ascending (küçükten büyüğe) veya Descending (büyükten küçüğe) olmak zorundadır. İkinci değer ise birincil sıralama anahtarını belirtmek üzere Name, Date, Size ve Description sözcüklerinden biri olmalıdır (anlamları sırayla: İsim, Tarih, Boyut, Açıklama). İkincil sıralama anahtarı daima artan sıralamayla dosya ismidir.

Sütunun tepesindeki sıralama bağını kaldırmak için SuppressColumnSorting seçeneğinin yanında, sıralama tercihlerinizi geçersiz kılmak için sorgu dizgesine elle sıralama seçenekleri eklenmesini engellemek için IgnoreClient seçeneğini de kullanarak istemcinin listeyi yeniden sıralamasını engelleyebilirsiniz.

top

IndexStyleSheet Yönergesi

Açıklama:Dizin listesine bir biçembent ekler.
Sözdizimi:IndexStyleSheet url-yolu
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

IndexStyleSheet yönergesi dizin listelemesi için kullanılacak biçembent dosyasının ismini belirtmek için kullanılır.

IndexStyleSheet "/css/style.css"

Bu yönergenin IndexOptions HTMLTable ile birlikte kullanılması sonuçlanan HTML dosyasına bir miktar CSS sınıfı ekler. Tablonun tamamı indexlist için bir CSS kimliği verir ve aşağıdaki sınıflar listenin çeşitli parçalarıyla ilişkilendirilir:

SınıfTanım
tr.indexhead Liste satırının başlığı
th.indexcolicon and td.indexcolicon Simge sütunu
th.indexcolname and td.indexcolname Dosya ismi sütunu
th.indexcollastmod and td.indexcollastmod Son değişiklik sütunu
th.indexcolsize and td.indexcolsize Dosya boyutu sütunu
th.indexcoldesc and td.indexcoldesc Açıklama sütunu
tr.breakrow Tablonun altınaki yatay çizgi
tr.odd and tr.even Tek ve çift satırlar
top

ReadmeName Yönergesi

Açıklama:Dizin listesinin sonuna yerleştirilecek dosyanın ismini belirler.
Sözdizimi:ReadmeName dosya-ismi
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_autoindex

ReadmeName yönergesi dizin listesinin sonuna eklenecek dosyanın ismini belirler. dosya-ismi ile listeye dahil edilecek dosyanın ismi listelenen dizine göreli olarak belirtilir. Eğer dosya ismi 2. örnekteki gibi bir bölü çizgisi ile başlıyorsa DocumentRoot’a göreli belirtildiği varsayılır.

# 1. Örnek
ReadmeName FOOTER.html
# 2. Örnek
ReadmeName /include/FOOTER.html

Ayrıca bu davranışın daha ayrıntılı ele alındığı HeaderName yönergesine de bakınız.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache.html.ja.utf80000664000175100017510000015054414743132254021672 0ustar covenercovener mod_cache - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_cache

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:URI をキーにしたコンテンツのキャッシュ
ステータス:Extension
モジュール識別子:cache_module
ソースファイル:mod_cache.c

概要

このモジュールは AllowDeny ディレクティブを無視しますので、 注意して使って下さい。クライアントのホスト名、アドレスや環境変数を使って アクセスを制限したいコンテンツに対してはキャッシュ機能を有効にするべきではありません。

mod_cache はローカルのコンテンツやプロキシされた コンテンツをキャッシュするために使われる RFC 2616 準拠の HTTP コンテンツキャッシュを実装しています。mod_cache の動作にはストレージを管理するモジュールが必要です。標準 Apache 配布には二つストレージ管理モジュールが含まれています:

mod_cache_disk
ディスクを使用したストレージ管理機構を実装しています。
mod_mem_cache
メモリを使用したストレージ管理機構を実装しています。 mod_mem_cache は次の二つのモードのどちらかで動作する ように設定できます: オープンされているファイル記述子をキャッシュするモードか、 ヒープ上でのオブジェクトの自体をキャッシュをするモードです。 mod_mem_cache はローカルで生成されるコンテンツや、 mod_proxyProxyPass を使って設定されている ときの (つまりリバースプロキシ での) バックエンドサーバの コンテンツをキャッシュするのに使えます。

コンテンツのキャッシュへの保存と取得は URI に基づいたキーが使われます。 アクセス保護のかけられているコンテンツはキャッシュされません。

より詳細な解説や例についてはキャッシュ機能 を参照してください。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

関連モジュールとディレクティブ

top

サンプル設定

Sample httpd.conf

#
# Sample Cache Configuration
#
LoadModule cache_module modules/mod_cache.so

<IfModule mod_cache.c>
#LoadModule cache_disk_module modules/mod_cache_disk.so
# If you want to use mod_cache_disk instead of mod_mem_cache,
# uncomment the line above and comment out the LoadModule line below.
<IfModule mod_cache_disk.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>

# When acting as a proxy, don't cache the list of security updates
CacheDisable http://security.update.server/update-list/
</IfModule>

top

CacheDefaultExpire ディレクティブ

説明:期日が指定されていないときにドキュメントをキャッシュするデフォルトの期間
構文:CacheDefaultExpire seconds
デフォルト:CacheDefaultExpire 3600 (1時間)
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

CacheDefaultExpire ディレクティブは、ドキュメントに 有効期限 (expiry) や最終修正時刻 (last-modified) が指定されていない場合の デフォルトの時間を指定します。CacheMaxExpire ディレクティブで指定された値はこの設定を上書きしません

CacheDefaultExpire 86400

top

CacheDetailHeader ディレクティブ

説明:Add an X-Cache-Detail header to the response.
構文:CacheDetailHeader on|off
デフォルト:CacheDetailHeader off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_cache
互換性:Available in Apache 2.3.9 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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_cache_disk で実装されているディスクを使ったストレージ 管理を使うように mod_cache に指示します。 cache_type fdmod_cachemod_mem_cache により実装されているファイル記述子の キャッシュを使うように指示します。

(下の例のように) CacheEnable ディレクティブの URL 空間が重複しているときは、該当するストレージ方式を順に試して、 実際にリクエストの処理ができると、その方式で処理します。 ストレージ管理方式が実行される順番は設定ファイル中の CacheEnable の順番により決定されます。

CacheEnable mem /manual
CacheEnable fd /images
CacheEnable disk /

フォワードプロクシサーバとして動作する場合、 url-string を使って、キャッシュを有効にするリモートサイトや プロクシプロトコルを指定することもできます。

# Cache proxied url's
CacheEnable disk /

# Cache FTP-proxied url's
CacheEnable disk ftp://

# Cache content from www.apache.org
CacheEnable disk http://www.apache.org/

top

CacheHeader ディレクティブ

説明:Add an X-Cache header to the response.
構文:CacheHeader on|off
デフォルト:CacheHeader off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_cache
互換性:Available in Apache 2.3.9 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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 の設定に関係なくキャッシュには保管されません:

CacheIgnoreHeaders で キャッシュに保管しない追加の HTTP ヘッダを指定します。 例えば、クッキーをキャッシュに保管しないようにした方がよい場合も あるでしょう。

CacheIgnoreHeaders の引数は、 キャッシュに保管しない HTTP ヘッダを空白区切りにしたリスト形式です。 キャッシュに保管しないヘッダが hop-by-hop ヘッダだけの場合 (RFC 2616 準拠の動作のとき) は、 CacheIgnoreHeadersNone に設定できます。

例 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

CacheIgnoreQueryString ディレクティブ

説明:キャッシュ時にクエリーストリングを無視する
構文:CacheIgnoreQueryString On|Off
デフォルト:CacheIgnoreQueryString Off
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

クエリーストリング付のリクエストについては通常、クエリーストリングごとに 個別にキャッシュされます。 キャッシュされるのは有効期限が指定されている場合のみで、これは RFC 2616/13.9 に従ったものです。 CacheIgnoreQueryString ディレクティブを使うと 有効期限が指定されていなくてもキャッシュしますし、 クエリーストリングが異なっていてもキャッシュを返します。 このディレクティブが有効になっている場合、キャッシュ機能の側面からみると、 あたかもリクエストにクエリーストリングがついていなかったかのように扱います。

CacheIgnoreQueryString On

top

CacheIgnoreURLSessionIdentifiers ディレクティブ

説明:Ignore defined session identifiers encoded in the URL when caching
構文:CacheIgnoreURLSessionIdentifiers identifier [identifier] ...
デフォルト:CacheIgnoreURLSessionIdentifiers None
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CacheKeyBaseURL ディレクティブ

説明:Override the base URL of reverse proxied cache keys.
構文:CacheKeyBaseURL URL
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache
互換性:Available in Apache 2.3.9 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CacheLastModifiedFactor ディレクティブ

説明:LastModified の日付に基づいて有効期限 (expiry) を計算するための重みを指定する
構文:CacheLastModifiedFactor float
デフォルト:CacheLastModifiedFactor 0.1
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

ドキュメントに Last-Modified の日付が無いけれども有効期限 (expiry) の日付があるというときに、有効期限を最終修正時刻からの経過時間として 計算するようにできます。有効期限を次の計算式に従って生成するのですが、 そのときに使われる factorCacheLastModifiedFactor ディレクティブで指定します。

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

CacheLock ディレクティブ

説明:Enable the thundering herd lock.
構文:CacheLock on|off
デフォルト:CacheLock off
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache
互換性:Available in Apache 2.2.15 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CacheLockMaxAge ディレクティブ

説明:Set the maximum possible age of a cache lock.
構文:CacheLockMaxAge integer
デフォルト:CacheLockMaxAge 5
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CacheLockPath ディレクティブ

説明:Set the lock path directory.
構文:CacheLockPath directory
デフォルト:CacheLockPath /tmp/mod_cache-lock
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CacheMaxExpire ディレクティブ

説明:ドキュメントをキャッシュする最大時間を秒数で表したもの
構文:CacheMaxExpire seconds
デフォルト:CacheMaxExpire 86400 (一日)
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

CacheMaxExpire ディレクティブは、 キャッシュする HTTP ドキュメントを、元のサーバに問い合わせないまま最大何秒 保持してもよいかを指定します。つまり、ドキュメントは最大でこの秒数間ぶん古く なることになります。この最大値は、(訳注: レスポンス中で)ドキュメントと共に ドキュメントの期日が提供されている場合でも適用されます。

CacheMaxExpire 604800

top

CacheMinExpire ディレクティブ

説明:ドキュメントをキャッシュする最小秒数
構文:CacheMinExpire seconds
デフォルト:CacheMinExpire 0
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache

キャッシュ可能な HTTP ドキュメントがあったときに、オリジンサーバに問い合わせることなく 保持する秒数の最小値は CacheMinExpire ディレクティブを使って設定します。 この値は、ドキュメントに妥当な有効期限が指定されていなかった場合にのみ使われます。

CacheMinExpire 3600

top

CacheQuickHandler ディレクティブ

説明:Run the cache from the quick handler.
構文:CacheQuickHandler on|off
デフォルト:CacheQuickHandler on
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_cache
互換性:Apache HTTP Server 2.3.3 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CacheStaleOnError ディレクティブ

説明:Serve stale content in place of 5xx responses.
構文:CacheStaleOnError on|off
デフォルト:CacheStaleOnError on
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_cache
互換性:Available in Apache 2.3.9 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CacheStoreExpired ディレクティブ

説明:Attempt to cache responses that the server reports as expired
構文:CacheStoreExpired On|Off
デフォルト:CacheStoreExpired Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_cache

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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' なキャッシュについてのみでしょう。

参照

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_unique_id.html.ja.utf80000664000175100017510000004471614743132254022614 0ustar covenercovener mod_unique_id - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_unique_id

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:それぞれのリクエストに対する一意な識別子の入った環境変数を 提供する
ステータス:Extension
モジュール識別子:unique_id_module
ソースファイル:mod_unique_id.c

概要

このモジュールは非常に制限された条件下で、 それぞれのリクエストに「すべて」のリクエストに対して 一意に決まることが保証されている魔法のトークンを提供します。 この一意な識別子は、適切に設定されたクラスタでは複数の マシンの間でさえも一意になります。それぞれのリクエストに対して環境変数 UNIQUE_ID に識別子が設定されます。 一意な識別子が便利な理由はいろいろありますが、 このドキュメントの目的からは外れるため、ここでは説明しません。

Support Apache!

トピック

ディレクティブ

このモジュールにディレクティブはありません。

Bugfix checklist

参照

top

理論

まずはじめに、Apache サーバが Unix マシンでどのように動作をするかを簡単に説明します。 この機能は現時点では Windows NT ではサポートされていません。 Unix マシンでは Apache はいくつかの子プロセスを作成し、 その子プロセスが一つずつリクエストを処理します。それぞれの子プロセスは、 生存期間中に複数のリクエストを扱うことができます。 この議論では子プロセス間では一切データを共有しないことにします。 以後、この子プロセスのことを httpd プロセス と呼びます。

あなたのウェブサイトにはあなたが管理するいくつかのマシンがあるとします。 それらをまとめてクラスタと呼ぶことにします。それぞれのマシンは複数の Apache を実行することもできます。 これらすべてをまとめたものが「宇宙」であると考えられます。 いくつかの仮定の下で、クラスタのマシン間がたくさん通信をすることなく、 この宇宙の中でそれぞれのリクエストに一意な識別子を生成できることを示します。

クラスタにあるマシンは以下の要求を見たさなければなりません。 (マシンが一つだけだとしても、NTP で時計を合わせる方が良いです。)

オペレーティングシステムにおいては、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 アドレスはどのサイトにおいても過剰な情報ですが、 それの代わりになる移植性のあるものはありません)。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_file.html.ko.euc-kr0000664000175100017510000002504514743132254023261 0ustar covenercovener mod_authn_file - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_authn_file

ֽ ƴմϴ. ֱٿ ϼ.
: ̿
: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 ϸ Ѵ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_groupfile.html.ko.euc-kr0000664000175100017510000002146314743132254024352 0ustar covenercovener mod_authz_groupfile - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_authz_groupfile

ֽ ƴմϴ. ֱٿ ϼ.
:Ϲ ̿ ׷ Ѻο
:Base
:authz_groupfile_module
ҽ:mod_authz_groupfile.c
:ġ 2.1 ĺ

׷ Ʈ Ϻθ ִ Ͽ Ѻο Ѵ. mod_authz_dbm ϴ.

Support Apache!

þ

Bugfix checklist

top

AuthGroupFile þ

: ׷ ϴ ϸ Ѵ
:AuthGroupFile file-path
:directory, .htaccess
Override ɼ:AuthConfig
:Base
:mod_authz_groupfile

AuthGroupFile þ ׷ ϴ ϸ Ѵ. File-path ׷ ̴. θ ServerRoot η ޾Ƶδ.

׷ ٿ ׷, ݷ, ڸ ´.

:

mygroup: bob joe anne

׷ ū ˻ϴ ſ ȿ ϶. AuthDBMGroupFile .

AuthGroupFile ۿ ġ Ȯ϶. ȣ 丮 ȿ . ׷ , Ŭ̾Ʈ AuthGroupFile ٿε ִ.

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_autoindex.html.ko.euc-kr0000664000175100017510000014430014743132254023137 0ustar covenercovener mod_autoindex - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_autoindex

ֽ ƴմϴ. ֱٿ ϼ.
:ڵ н ls ɾ Win32 dir ɾ 丮
:Base
:autoindex_module
ҽ:mod_autoindex.c

丮 ΰ:

, Ѵٸ ڵ (Ȥ ü) ִ.

ڵ Options +Indexes ϴ. ڼ Options þ ϶.

IndexOptions þ FancyIndexing ɼ ָ, ̸ ٲٴ ũ . ̸ ũ ϸ ٽ . ̸ ݺؼ ϸ ̸ . IndexOptions þ SuppressColumnSorting ɼ ̷ ̸ ũ ʴ´.

"Size(ũ)" µǴ ƴ϶ ũ ϶. , 1010 Ʈ ϰ 1011 Ʈ Ѵ "1K" ̴ ׻ 1010 Ʈ տ ´.

Support Apache!

þ

Bugfix checklist

top

Autoindex û ƱԸƮ

ġ 2.0.23 û ƱԸƮ ϰ, ο ɼǵ ߰ߴ. Ŭ̾Ʈ IndexOptions IgnoreClient ɼ ߰Ǿ.

̸ Ʒ û ɼ ڱ ũ. Ʒ ɼ 丮 ڿ  û ִ.

'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

IndexHeadInsert þ

:Inserts text in the HEAD section of an index page.
:
:ּ, ȣƮ, directory, .htaccess
:Base
:mod_autoindex

Documentation not yet translated. Please see English version of document.

top

IndexIgnore þ

:丮 Ͽ ϸ ߰Ѵ
:IndexIgnore file [file] ...
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Indexes
:Base
:mod_autoindex

IndexIgnore þ 丮 Ͽ ϸ ߰Ѵ. File ( ϴ) ȭϵī ǥ̳ ü ϸ ִ. IndexIgnore þ ϸ ϸ üʰ Ͽ ϵ ߰Ѵ. ⺻ . ( 丮) Ѵ.

IndexIgnore README .htaccess *.bak *~

top

IndexIgnoreReset þ

:Empties the list of files to hide when listing a directory
:IndexIgnoreReset ON|OFF
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Indexes
:Base
:mod_autoindex
:2.3.10 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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 Ѵٸ 丮 ZedBeta տ , 丮 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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_owner.html.ko.euc-kr0000664000175100017510000002614314743132254023510 0ustar covenercovener mod_authz_owner - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_authz_owner

ֽ ƴմϴ. ֱٿ ϼ.
: ڸ ̿ Ѻο
: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" ڿ Ѻο ʴ´.

Support Apache!

þ

⿡ þ ϴ.

Bugfix checklist

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>

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directives.html.zh-cn.utf80000664000175100017510000016302615032765673022566 0ustar covenercovener 指令索引 - Apache HTTP 服务器 版本 2.4
<-
Apache > HTTP 服务器 > 文档 > 版本 2.4 > 模块

指令索引

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

每个在 Apache 标准发行版中可用的指令都列在这里。它们使用一致的格式描述,而且有术语字典

指令快速参考用来以摘要的形式提供有关每个指令的详细信息。

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

评论

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_autoindex.html.ja.utf80000664000175100017510000020165214743132254022624 0ustar covenercovener mod_autoindex - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_autoindex

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:Unix の ls コマンドや Win32 の dir シェルコマンドに似た ディレクトリインデックスを生成する
ステータス:Base
モジュール識別子:autoindex_module
ソースファイル:mod_autoindex.c

概要

ディレクトリのインデックスは二つの情報源のうちの 一つから生成できます:

望むならば、自動インデックス生成を完全に除去 (あるいは置換) できるように、この二つの機能は分離されています。

自動インデックス生成は Options +Indexes を使うことで有効になります。詳細については、 Options ディレクティブをご覧下さい。

もし FancyIndexingオプションが IndexOptions ディレクティブに与えられているならば、 列の先頭は表示の順番を制御するリンクになります。 先頭のリンクを選択すると、一覧は再生成されて その列の値でソートされます。 同じ先頭を続けて選択すると、交互に昇順と降順とになります。 これらの列の先頭のリンクは、 IndexOptions ディレクティブの SuppressColumnSorting オプションで消すことができます。

"Size" でソートした場合は、用いられるのは 実際のファイルのサイズであって、 表示の値ではないことに注意してください - たとえ両方ともが "1K" と表示されていたとしても、 1010 バイトのファイルは必ず 1011 バイトのファイルよりも前 (昇順の場合) に表示されます。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

Autoindex リクエストクエリー引数

Apache 2.0.23 で、 コラムソートのためにクエリー引数を再編成して、 新しいクエリーオプションのグループを導入しました。 出力に対するクライアントのすべての制御を効率的に抹消 できるように、 IndexOptions IgnoreClient が導入されました。

コラムソートのヘッダそれ自体が、 下記のソートクエリーオプションを付加する 自分自身を参照するリンクです。 下記のオプションのどれでも、 ディレクトリリソースへのリクエストに加えることができます。

"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 は、有効なコンテントエンコーディング、 例えば x-compressです。

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 IncludesIncludesNOEXEC が有効になっている場合は、 ファイルはサーバーサイドインクルードで処理されます (mod_include ドキュメントを参照して下さい)。

もし HeaderName で指定されたファイルが HTML ドキュメントの開始部分 (<html>, <head>, 等) を含んでいたら、 IndexOptions +SuppressHTMLPreamble を設定して、これらのタグが繰り返されないようにしたいと思うでしょう。

top

IndexHeadInsert ディレクティブ

説明:インデックスページの HEAD セクションにテキストを挿入する
構文:IndexHeadInsert "markup ..."
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Indexes
ステータス:Base
モジュール:mod_autoindex

IndexHeadInsert ディレクティブを使って インデックスとして生成されたHTMLの <head> セクションに 挿入する文字列を指定します。

Example

IndexHeadInsert "<link rel=\"sitemap\" href=\"/sitemap.html\">"

top

IndexIgnore ディレクティブ

説明:ディレクトリ一覧を行なう際に無視すべき ファイルリストに追加
構文:IndexIgnore file [file] ...
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Indexes
ステータス:Base
モジュール:mod_autoindex

IndexIgnore ディレクティブは、 ディレクトリの一覧を行う際に無視すべきファイルリストに追加します。 file は、 シェル形式のワイルドカード表現か完全なファイル名です。 IndexIgnore が複数ある場合は、無視するリストに追加が行われ、 置換は行われません。デフォルトではリストには . (カレントディレクトリ) が含まれています。

IndexIgnore README .htaccess *.bak *~

top

IndexIgnoreReset ディレクティブ

説明:Empties the list of files to hide when listing a directory
構文:IndexIgnoreReset ON|OFF
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Indexes
ステータス:Base
モジュール:mod_autoindex
互換性:2.3.10 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

IndexOptions ディレクティブ

説明:ディレクトリインデックスの様々な設定項目
構文:IndexOptions [+|-]option [[+|-]option] ...
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Indexes
ステータス:Base
モジュール:mod_autoindex

IndexOptions は、ディレクトリインデックスの挙動を指定します。 option は次のどれかです:

Charset=character-set (Apache 2.0.61 以降)
Charset キーワードで、 生成されるページの文字セットを指定できます。 下位のファイルシステムが Unicode ベースかどうかに依存しますが、 デフォルト値は ISO-8859-1UTF-8 になります。

Example:

IndexOptions Charset=UTF-8

Type=MIME content-type (Apache 2.0.61 以降)
Type キーワードで、 生成されるページの MIME コンテントタイプを指定できます。 デフォルト値は text/html になります。

Example:

IndexOptions Type=text/plain

DescriptionWidth=[n | *] (2.0.23 以降)
DescriptionWidth キーワードは説明コラムの幅を文字数で指定することができます。
-DescriptionWidth (または非設定) で、 mod_autoindex が最適な幅を計算するようにできます。
DescriptionWidth=n で、コラム幅を n バイトに固定します。
DescriptionWidth=* は、最長の説明に合わせて必要な長さまでコラムを延ばします。
説明を丸め込んだ場合特有の危険については AddDescription セクションをお読み下さい。
FancyIndexing
飾り付きインデックスをオンにします。
FoldersFirst (2.0.23 以降)
このオプションが有効になった場合、サブディレクトリの一覧は 必ず最初に現われて、通常のファイルはその後に続きます。 一覧は基本的には、ファイルとディレクトリの二つの部分に分けられて、 それぞれは別々にソートされ、その後サブディレクトリを先にして 表示が行なわれます。例えばソート順が名前の降順になっていて、 FoldersFirst が有効になっている場合は、 サブディレクトリ Zed はサブディレクトリ Beta よりも前にリストされ、通常のファイル GammaAlpha よりも前にリストされます。このオプションは FancyIndexing も有効になっているときにのみ有効です。
HTMLTable (実験的、 Apache 2.0.23 以降)
この実験的なオプションは FancyIndexing とともに指定することで、 飾りの付いたディレクトリ一覧のためにテーブルを使った単純な表を作ります。 これは古いブラウザを混乱させるかもしれないことに注意してください。 WinNT やその他 utf-8 が有効なプラットホームのように、ファイル名や説明テキストが 右読みになったり左読みになりえる場合は特に必要です。
IconsAreLinks
これは、FancyIndexing において、 アイコンもファイル名へのリンクの一部にします。
IconHeight[=pixels]
このオプションが、IconWidth とともに 使われている場合は、サーバはファイルアイコンのための img タグに heightwidth 属性を取り込むようになります。 これによって、イメージ全てをロードし終わるまで待たなくても、 ブラウザはページレイアウトをあらかじめ計算することができます。 このオプションに何も値が与えられなければ、Apache ソフトウェアで提供されているアイコンの標準の高さが デフォルトなります。
IconWidth[=pixels]
このオプションが、IconHeight とともに使われている場合は、 サーバはファイルアイコンのための img タグに heightwidth 属性を取り込むようになります。 これによって、イメージ全てをロードし終わるまで待たなくても、 ブラウザはページレイアウトをあらかじめ計算することができます。 このオプションに何も値が与えられなければ、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
通常 Apache はサブリクエストの結果がHTTP_UNAUTHORIZEDHTTP_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 の一覧からアイコンを消去します。 SuppressIconSuppressRules と組合わせることによって正しい HTML 3.2 の出力が得られます。 HTML 3.2 の最終規格は、 imghrpre ブロックに入る (FancyIndexing 一覧で書式に使われています) ことを禁止しています。
SuppressLastModified
FancyIndexing 一覧において最終更新日時の表示を消去します。
SuppressRules (Apache 2.0.23 以降)
ディレクトリ一覧において水平区切り線 (hr タグ) を消去します。 SuppressIconSuppressRules と組合わせることによって正しい HTML 3.2 の出力が得られます。 HTML 3.2 の最終規格は、 imghrpre ブロックに入る (FancyIndexing 一覧で書式に使われています) ことを禁止しています。
SuppressSize
FancyIndexing 一覧においてファイルサイズの表示を消去します。
TrackModified (Apache 2.0.23 以降)
これは HTTP ヘッダ中に、 ディレクトリの Last-ModifiedETag を含めます。 これは、オペレーティングシステムやファイルシステムが 適切な stat() の返り値を返す場合にのみ有効です。 いくつかの UNIX システム、OS2 の JFS や Win32 の NTFS ボリュームはそうなっています。 例えば、OS2 と Win32 FAT ボリュームはそうではありません。 この機能が有効になると、クライアントやプロキシは HEAD リクエストを行うことによって、 ファイル一覧の変化を追跡することができるようになります。 オペレーティングシステムによっては、新規ファイルや 移動ファイルは正しく追跡するけれども、 ディレクトリ中のファイルのサイズや日付は追跡しないということに 注意してください。 既に存在するファイルのサイズや日付のスタンプが変化しても、 全ての Unix プラットホームでは、 Last-Modified ヘッダーを更新しません。 もしこれが重要であれば、 このオプションを無効のままにしてください。
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 は二つの引数をとります。一つ目はソートの方向を指示する AscendingDescending のいずれかです。 二つ目の引数は Name, Date, SizeDescription のいずれか一つのキーワードであって、1つ目のソートキーを指定します。 2つ目のソートキーは常にファイル名の昇順になります。

このディレクティブと 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 もご覧下さい。

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache.html.ko.euc-kr0000664000175100017510000011501314743132254022201 0ustar covenercovener mod_cache - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_cache

ֽ ƴմϴ. ֱٿ ϼ.
:URI Ű Ͽ ijѴ.
:Experimental
:cache_module
ҽ:mod_cache.c

̴. ۾̴...

mod_cache ǻͿ ִ ̳ Ͻõ ij ִ RFC 2616 ȣȯ HTTP ij Ѵ. mod_cache Ϸ (storage management module) ʿϴ. ⺻ ġ ΰ ִ:

mod_cache_disk
ũ ڸ Ѵ.
mod_mem_cache
޸𸮱 ڸ Ѵ. mod_mem_cache ϱڸ ijϰų (heap) ü ijϴ ΰ Ѱ ϵ ִ. mod_mem_cache ڽ ijϰų, (Ͻ(reverse proxy) ˷) ProxyPass Ͽ mod_proxy ޴ ij ִ.

URI Ű ij ϰ ´. ٺȣ ijʴ´.

Support Apache!

þ

Bugfix checklist

top

õ þ

top

Sample httpd.conf

#
# ij
#
LoadModule cache_module modules/mod_cache.so

<IfModule mod_cache.c>
#LoadModule cache_disk_module modules/mod_cache_disk.so
<IfModule mod_cache_disk.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

CacheDetailHeader þ

:Add an X-Cache-Detail header to the response.
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

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_cache_disk ϴ ũ ڸ Ѵ. cache_type fd mod_mem_cache ϴ ϱ ij Ѵ.

(Ʒ ) URL ٸ CacheEnable þ ġ ڰ û óҶ ڸ Ѵ. Ͽ CacheEnable þ ڰ ȴ.

CacheEnable mem /manual
CacheEnable fd /images
CacheEnable disk /

top

CacheHeader þ

:Add an X-Cache header to the response.
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

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

CacheIgnoreHeaders ij ϸ ȵǴ HTTP ߰ Ѵ. , Ű(cookie) ij ϸ ȵǴ 찡 ִ.

CacheIgnoreHeaders ij HTTP ޴´. (RFC 2616 ) ij ȩ , CacheIgnoreHeaders None Ѵ.

1

CacheIgnoreHeaders Set-Cookie

2

CacheIgnoreHeaders None

:

CacheIgnoreHeaders Ͽ Expires ij ʿ , mod_cache Ѵ.
top

CacheIgnoreNoLastMod þ

:信 Last Modified ٴ Ѵ.
:CacheIgnoreNoLastMod On|Off
⺻:CacheIgnoreNoLastMod Off
:ּ, ȣƮ
:Experimental
:mod_cache

ֱټ ij ʴ´.  ֱټ ( mod_include ó߿) ų ó ִ. CacheIgnoreNoLastMod þ ֱټ ݵ ijϵ . ֱټϰ ð CacheDefaultExpire þ ð Ѵ.

CacheIgnoreNoLastMod On

top

CacheIgnoreQueryString þ

:Ignore query string when caching
:
:ּ, ȣƮ
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheIgnoreURLSessionIdentifiers þ

:Ignore defined session identifiers encoded in the URL when caching
:
:ּ, ȣƮ
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheKeyBaseURL þ

:Override the base URL of reverse proxied cache keys.
:
:ּ, ȣƮ
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

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

CacheLock þ

:Enable the thundering herd lock.
:
:ּ, ȣƮ
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheLockMaxAge þ

:Set the maximum possible age of a cache lock.
:
:ּ, ȣƮ
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheLockPath þ

:Set the lock path directory.
:
:ּ, ȣƮ
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheMaxExpire þ

: ijϴ ʴ ִð
:CacheMaxExpire seconds
⺻:CacheMaxExpire 86400 (Ϸ)
:ּ, ȣƮ
:Experimental
:mod_cache

CacheMaxExpire þ ˻ʰ ij HTTP ִ ʴ ִð Ѵ. , ִ ŭ Ǿ. ð Ͽ ִ밪 Ų.

CacheMaxExpire 604800

top

CacheMinExpire þ

:The minimum time in seconds to cache a document
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheQuickHandler þ

:Run the cache from the quick handler.
:
:ּ, ȣƮ
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheStaleOnError þ

:Serve stale content in place of 5xx responses.
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheStoreExpired þ

:Attempt to cache responses that the server reports as expired
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheStoreNoStore þ

:Attempt to cache requests or responses that have been marked as no-store.
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

top

CacheStorePrivate þ

:Attempt to cache responses that the server has marked as private
:
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_cache

Documentation not yet translated. Please see English version of document.

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cern_meta.html.ko.euc-kr0000664000175100017510000002505214743132254023076 0ustar covenercovener mod_cern_meta - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_cern_meta

ֽ ƴմϴ. ֱٿ ϼ.
:CERN Ÿ
:Extension
:cern_meta_module
ҽ:mod_cern_meta.c

CERN Ÿ 䳻. Ÿ ϴ Ͽ Ϲ ܿ ߰ HTTP ִ. ġ .asis ϰ ϰ, Expires: ϰų ٸ ű ϵ ִ. Ÿ ٷ پ, ̹ ϴ CERN ڵ ߴ.

ڼ CERN metafile semantics ϶.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_md.html.en0000664000175100017510000032337415032765673020366 0ustar covenercovener mod_md - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_md

Available Languages:  en  |  fr 

Description:Managing domains across virtual hosts, certificate provisioning via the ACME protocol
Status:Experimental
Module Identifier:md_module
Source File:mod_md.c
Compatibility:Available in version 2.4.30 and later

Summary

This module manages common properties of domains for one or more virtual hosts. Its serves two main purposes: for one, supervise/renew TLS certificates via the ACME protocol (RFC 8555). Certificates will be renewed by the module ahead of their expiration to account for disruption in internet services. There are ways to monitor the status of all certificates managed this way and configurations that will run your own notification commands on renewal, expiration and errors.

Second, mod_md offers an alternate OCSP Stapling implementation. This works with managed certificates as well as with certificates you configure yourself. OCSP Stapling is a necessary component for any https: site, influencing page load times and, depending on other setups, page availability. More in the stapling section below.

The default ACME Authority for managing certificates is Let's Encrypt, but it is possible to configure another CA that supports the protocol.

Simple configuration example:

TLS in a VirtualHost context

MDomain example.org

<VirtualHost *:443>
    ServerName example.org
    DocumentRoot htdocs/a

    SSLEngine on
    # no certificates specification
</VirtualHost>

This setup will, on server start, contact Let's Encrypt to request a certificate for the domain. If Let's Encrypt can verify the ownership of the domain, the module will retrieve the certificate and its chain, store it in the local file system (see MDStoreDir) and provide it, on next restart, to mod_ssl.

This happens while the server is already running. All other hosts will continue to work as before. While a certificate is not available, requests for the managed domain will be answered with a '503 Service Unavailable'.

Prerequisites

This module requires mod_watchdog to be loaded as well.

Certificate sign-up and renewal with Let's Encrypt requires your server to be reachable on port 80 (http:) and/or port 443 (https:) from the public internet. (Unless your server is configured to use DNS for challenges - more on that under 'wildcard certificates')

The module will select from the methods offered by Let's Encrypt. Usually LE offers challenges on both ports and DNS and Apache chooses a method available.

To determine which one is available, the module looks at the ports Apache httpd listens on. If those include port 80, it assumes that the http: challenge (named http-01) is available. If the server listens on port 443, the https: challenge (named tls-alpn-01) is also added to the list. (And if MDChallengeDns01 is configured, the challenge dns-01 is added as well.)

If your setup is not so straight forward, there are two methods available to influence this. First, look at MDPortMap if the server is behind a portmapper, such as a firewall. Second, you may override the module's guesswork completely by configuring MDCAChallenges directly.

https: Challenges

For domain verification via the TLS protocol `tls-alpn-01` is the name of the challenge type. It requires the Apache server to listen on port 443 (see MDPortMap if you map that port to something else).

Let's Encrypt will open a TLS connection to Apache using the special indicator `acme-tls/1` (this indication part of TLS is called ALPN, therefore the name of the challenge. ALPN is also used by browsers to request a HTTP/2 connection).

As with the HTTP/2 protocol, to allow this, you configure:

Protocols h2 http/1.1 acme-tls/1

And the `tls-alpn-01` challenge type is available.

Wildcard Certificates

Wildcard certificates are possible, but not straight-forward to use out of the box. Let's Encrypt requires the `dns-01` challenge verification for those. No other is considered good enough.

The difficulty here is that Apache cannot do that on its own. As the name implies, `dns-01` requires you to show some specific DNS records for your domain that contain some challenge data. So you need to _write_ your domain's DNS records.

If you know how to do that, you can integrated this with mod_md. Let's say you have a script for that in `/usr/bin/acme-setup-dns` you configure Apache with:

MDChallengeDns01 /usr/bin/acme-setup-dns

and Apache will call this script when it needs to setup/teardown a DNS challenge record for a domain.

Assuming you want a certificate for `*.mydomain.com`, mod_md will call:

/usr/bin/acme-setup-dns setup mydomain.com challenge-data
# this needs to remove all existing DNS TXT records for 
# _acme-challenge.mydomain.com and create a new one with 
# content "challenge-data"

and afterwards it will call

/usr/bin/acme-setup-dns teardown mydomain.com
# this needs to remove all existing DNS TXT records for 
# _acme-challenge.mydomain.com

Monitoring

Apache has a standard module for monitoring: mod_status. mod_md contributes a section and makes monitoring your domains easy.

You see all your MDs listed alphabetically, the domain names they contain, an overall status, expiration times and specific settings. The settings show your selection of renewal times (or the default), the CA that is used, etc.

The 'Renewal' column will show activity and error descriptions for certificate renewals. This should make life easier for people to find out if everything is all right or what went wrong.

If there is an error with an MD it will be shown here as well. This let's you assess problems without digging through your server logs.

There is also a new 'md-status' handler available to give you the MD information from 'server-status' in JSON format. You configure it as

<Location "/md-status">
  SetHandler md-status
</Location>

on your server. As with 'server-status' you will want to add authorization for this.

If you just want to check the JSON status of a specific domain, simply append that to your status url:

> curl https://<yourhost>/md-status/another-domain.org
{
  "name": "another-domain.org",
  "domains": [
    "another-domain.org",
    "www.another-domain.org"
  ],
  ...

This JSON status also shows a log of activities when domains are renewed:

{
"when": "Wed, 19 Jun 2019 14:45:58 GMT",
"type": "progress", "detail": "The certificate for the managed domain has been renewed successfully and can be used. A graceful server restart now is recommended."
},{
"when": "Wed, 19 Jun 2019 14:45:58 GMT",
"type": "progress", "detail": "Retrieving certificate chain for test-901-003-1560955549.org"
},{
"when": "Wed, 19 Jun 2019 14:45:58 GMT",
"type": "progress", "detail": "Waiting for finalized order to become valid"
},{
"when": "Wed, 19 Jun 2019 14:45:50 GMT",
"type": "progress", "detail": "Submitting CSR to CA for test-901-003-1560955549.org"
},
...

You will also find this information in the file `job.json` in your staging and, when activated, domains directory. This allows you to inspect these at any later point in time as well.

In addition, there is MDCertificateStatus which gives access to relevant certificate information in JSON format.

Stapling

If you want to try the stapling in one Managed Domain alone at first, configure:

<MDomain mydomain.net>
  MDStapling on
</MDomain>

and use the 'server-status' and/or MDMessageCmd to see how it operates. You will see if Stapling information is there, how long it is valid, from where it came and when it will be refreshed.

If this all works to your satisfaction, you can switch it on for all your certificates or just your managed ones.

The existing stapling implementation by mod_ssl is used by many sites for years. There are two main differences between the mod_ssl and mod_md one:

  1. On demand vs. scheduled: mod_ssl retrieves the stapling information when it is requested, e.g. on a new connection. mod_md retrieves it right at server start and after 2/3rds of its lifetime.
  2. In memory vs. persisted: mod_ssl can persist this information, but most example configurations use a memory cache. mod_md always stores in the file system.

If you are unlucky and restart your server during an outage of your CA's OCSP service, your users may no longer reach your sites. Without persistence your server cannot provide the client with the data and the client browser cannot get it as well, since the OCSP service is not responding.

The implementation in mod_md will have persisted it, load it again after restart and have it available for incoming connections. A day or two before this information expires, it will renew it, making it able to cope with a long OCSP service downtime.

Due to backward compatibility, the existing implementation in mod_ssl could not be changed drastically. For example, mod_ssl is unable to add a dependency to mod_watchdog without braking many existing installations (that do not load it).

tailscale

Since version 2.4.14 of the module, you can use it to get certificates for your tailscale domains.

<MDomain mydomain.some-thing.ts.net>
  MDCertificateProtocol tailscale
  MDCertificateAuthority file://localhost/var/run/tailscale/tailscaled.sock",
</MDomain>

Tailscale provides secure networking between your machines, where ever they are, and can provide domain names in the *.ts.net space for them. For those, it will then provide Let's Encrypt certificates as well, so you can open these domains in your browser securely.

The directives listed above tell Apache to contact the local tailscale demon for obtaining and renewing certificates. This will only work for the domain name that tailscale assigns to your machine.

Otherwise, these certificates work exactly like the ones retrieved via the ACME protocol from Lets Encrypt. You see them in status reporting and MDMessageCmd directives are executed for them as well.

More details are available at the mod_md github documentation.

Note that this feature only works on machines where the tailscale demon provides a unix domain socket. This, so far, seems only the case on *nix systems.

Support Apache!

Directives

Bugfix checklist

See also

top

MDActivationDelay Directive

Description:How long to delay activation of new certificates
Syntax:MDActivationDelay duration
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.42 and later

top

MDBaseServer Directive

Description:Control if base server may be managed or only virtual hosts.
Syntax:MDBaseServer on|off
Default:MDBaseServer off
Context:server config
Status:Experimental
Module:mod_md

Controls if the base server, the one outside all VirtualHosts should be managed by mod_md or not. By default, it will not. For the very reason that it may have confusing side-effects. It is recommended that you have virtual hosts for all managed domains and do not rely on the global, fallback server configuration.

top

MDCAChallenges Directive

Description:Type of ACME challenge used to prove domain ownership.
Syntax:MDCAChallenges name [ name ... ]
Default:MDCAChallenges tls-alpn-01 http-01 dns-01
Context:server config
Status:Experimental
Module:mod_md

Sets challenge types (in order of preference) when proving domain ownership. Supported by the module are the challenge methods 'tls-alpn-01', 'dns-01' and 'http-01'. The module will look at the overall configuration of the server to find out which methods can be used.

If the server listens on port 80, for example, the 'http-01' method is available. The prerequisite for 'dns-01' is a configured MDChallengeDns01 command. 'tls-alpn-01' is described above in 'https: Challenges'.

This auto selection works for most setups. But since Apache is a very powerful server with many configuration options, the situation is not clear for all possible cases. For example: it may listen on multiple IP addresses where some are reachable on `https:` and some not.

If you configure MDCAChallenges directly, this auto selection is disabled. Instead, the module will use the configured challenge list when talking to the ACME server (a challenge type must be offered by the server as well). This challenges are examined in the order specified.

top

MDCertificateAgreement Directive

Description:You confirm that you accepted the Terms of Service of the Certificate Authority.
Syntax:MDCertificateAgreement accepted
Context:server config
Status:Experimental
Module:mod_md

When you use mod_md to obtain a certificate, you become a customer of the CA (e.g. Let's Encrypt). That means you need to read and agree to their Terms of Service, so that you understand what they offer and what they might exclude or require from you. mod_md cannot, by itself, agree to such a thing.

top

MDCertificateAuthority Directive

Description:The URL(s) of the ACME Certificate Authority to use.
Syntax:MDCertificateAuthority url
Default:MDCertificateAuthority letsencrypt
Context:server config
Status:Experimental
Module:mod_md

The URL(s) where the CA offers its service. Instead of the actual URL, you may use 'letsencrypt' or 'buypass'.

If you configure more than one URL, each one is tried in a round-robin fashion after a number of failures. You can configure how quickly or delayed that happens via the MDRetryDelay and MDRetryFailover directives. The default setting makes a failover after about half a day of trying.

All other settings apply to each of these URLs. It is therefore not possible to have two with different MDExternalAccountBindings, for example.

For testing, CAs commonly offer a second service URL. The 'test' service does not give certificates valid in a browser, but are more relaxed in regard to rate limits. This allows for verification of your own setup before switching to the production service URL.

LE Test Setup

MDCertificateAuthority https://acme-staging-v02.api.letsencrypt.org/directory
top

MDCertificateCheck Directive

Description:Set name and URL pattern for a certificate monitoring site.
Syntax:MDCertificateCheck name url
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.42 and later

top

MDCertificateFile Directive

Description:Specify a static certificate file for the MD.
Syntax:MDCertificateFile path-to-pem-file
Context:server config
Status:Experimental
Module:mod_md

This is used inside a MDomainSet and specifies the file holding the certificate chain for the Managed Domain. The matching key is specified via MDCertificateKeyFile.

Example

<MDomain mydomain.com>
  MDCertificateFile /etc/ssl/my.cert
  MDCertificateKeyFile /etc/ssl/my.key
</MDomain>

This is that equivalent of the mod_ssl SSLCertificateFile directive. It has several uses.

If you want to migrate an existing domain, using static files, to automated Let's Encrypt certificates, for one. You define the MDomainSet, add the files here and remove the SSLCertificateFile from your VirtualHosts.

This will give you the same as before, with maybe less repeating lines in your configuration. Then you can add MDRenewMode 'always' to it and the module will get a new certificate before the one from the file expires. When it has done so, you remove the MDCertificateFile and reload the server.

Another use case is that you renew your Let's Encrypt certificates with another ACME clients, for example the excellent certbot. Then let your MDs point to the files from certbot and have both working together.

top

MDCertificateKeyFile Directive

Description:Specify a static private key for for the static cerrtificate.
Syntax:MDCertificateKeyFile path-to-file
Context:server config
Status:Experimental
Module:mod_md

This is used inside a MDomainSet and specifies the file holding the private key for the Managed Domain. The matching certificate is specified via MDCertificateFile.

This is that equivalent of the mod_ssl SSLCertificateKeyFile directive.

top

MDCertificateMonitor Directive

Description:The URL of a certificate log monitor.
Syntax:MDCertificateMonitor name url
Default:MDCertificateMonitor crt.sh https://crt.sh?q=
Context:server config
Status:Experimental
Module:mod_md

This is part of the 'server-status' HTML user interface and has nothing to do with the core functioning itself. It defines the link offered on that page for easy checking of a certificate monitor. The SHA256 fingerprint of the certificate is appended to the configured url.

Certificate Monitors offer supervision of Certificate Transparency (CT) Logs to track the use of certificates for domains. The least you may see is that Let's Encrypt (or whichever CA you have configured) has entered your certificates into the CTLogs.

Caveat: certificate logs update and monitor's intakes of those updates suffer some delay. This varies between logs and monitors. A brand new certificate will not be known immediately.

top

MDCertificateProtocol Directive

Description:The protocol to use with the Certificate Authority.
Syntax:MDCertificateProtocol protocol
Default:MDCertificateProtocol ACME
Context:server config
Status:Experimental
Module:mod_md

Specifies the protocol to use. Currently, only ACME is supported.

top

MDCertificateStatus Directive

Description:Exposes public certificate information in JSON.
Syntax:MDCertificateStatus on|off
Default:MDCertificateStatus on
Context:server config
Status:Experimental
Module:mod_md

When enabled, a resources is available in Managed Domains at 'https://domain/.httpd/certificate-status' that returns a JSON document list key properties of the current and of a renewed certificate - when available.

Example

{
  "valid-until": "Thu, 29 Aug 2019 16:06:35 GMT",
  "valid-from": "Fri, 31 May 2019 16:06:35 GMT",
  "serial": "03039C464D454EDE79FCD2CAE859F668F269",
  "sha256-fingerprint": "1ff3bfd2c7c199489ed04df6e29a9b4ea6c015fe8a1b0ce3deb88afc751e352d"
  "renewal" : { ...renewed cert information... }
}
top

MDChallengeDns01 Directive

Description:Set the command for setup/teardown of dns-01 challenges
Syntax:MDChallengeDns01 path-to-command
Context:server config
Status:Experimental
Module:mod_md

Define a program to be called when the `dns-01` challenge needs to be setup/torn down. The program is given the argument `setup` or `teardown` followed by the domain name. For `setup` the challenge content is additionally given. When MDChallengeDns01Version is set to 2, the `teardown` also gets the challenge content as argument.

You do not need to specify this, as long as a 'http:' or 'https:' challenge method is possible. However, Let's Encrypt makes 'dns-01' the only challenge available for wildcard certificates. If you require one of those, you need to configure this.

It is now possible to use this directive inside a MDomain section to specify a specific command for that domain. This allows to configure a script specific for the particular DNS provider involved.

See the section about wildcard certificates above for more details.

top

MDChallengeDns01Version Directive

Description:Set the type of arguments to call MDChallengeDns01 with
Syntax:MDChallengeDns01Version 1|2
Default:MDChallengeDns01Version 1
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.58 and later

Set the way MDChallengeDns01 command is invoked, e.g the number and types of arguments. See MDChallengeDns01 for the differences. This setting is global and cannot be varied per domain.

top

MDCheckInterval Directive

Description:Determines how often certificates are checked
Syntax:MDCheckInterval duration
Default:MDCheckInterval 12h
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.60 and later

The time between certificate checks. By default, the validity and need for renewals is checked twice a day. This interval is not followed precisely. Instead the module randomly applies a +/-50% jitter to it. With the default of 12 hours, this means the actual time between runs varies between 6 and 18 hours, jittered anew every run. This helps to mitigate traffic peaks at ACME servers.

The minimum duration you may configure is 1 second. It is not recommended to use such short times in production.

top

MDContactEmail Directive

Description:Email address used for account registration
Syntax:MDContactEmail address
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.42 and later

The ACME protocol requires you to give a contact url when you sign up. Currently, Let's Encrypt wants an email address (and it will use it to inform you about renewals or changed terms of service). mod_md uses the MDContactEmail directive email in your Apache configuration, so please specify the correct address there. If MDContactEmail is not present, mod_md will use the ServerAdmin directive.

top

MDDriveMode Directive

Description:former name of MDRenewMode.
Syntax:MDDriveMode always|auto|manual
Default:MDDriveMode auto
Context:server config
Status:Experimental
Module:mod_md

This directive exists for backward compatibility as the old name for MDRenewMode.

top

MDExternalAccountBinding Directive

Description:Set the external account binding keyid and hmac values to use at CA
Syntax:MDExternalAccountBinding key-id hmac-64 | none | file
Default:MDExternalAccountBinding none
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.52 and later

Configure values for ACME "External Account Binding", a feature of the ACME standard that allows clients to bind registrations to an existing customer account on ACME servers.

Let's Encrypt does not require those, but other ACME CAs do. Check with your ACME CA if you need those and how to obtain the values. They are two strings, a key identifier and a base64 encoded 'hmac' value.

You can configure those globally or for a specific MDomain. Since these values allow anyone to register under the same account, it is advisable to give the configuration file restricted permissions, e.g. root only.

The value can also be taken from a JSON file, to keep more open permissions on the server configuration and restrict the ones on that file. The JSON itself is:

EAB JSON Example file

{"kid": "kid-1", "hmac": "zWND..."}

If you change EAB values, the new ones will be used when the next certificate renewal is due.

top

MDHttpProxy Directive

Description:Define a proxy for outgoing connections.
Syntax:MDHttpProxy url
Context:server config
Status:Experimental
Module:mod_md

Use a http proxy to connect to the MDCertificateAuthority. Define this if your webserver can only reach the internet with a forward proxy.

top

MDMatchNames Directive

Description:Determines how DNS names are matched to vhosts
Syntax:MDMatchNames all|servernames
Default:MDMatchNames all
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.58 and later

The mode `all` is the behaviour as in all previous versions. Both ServerName and ServerAlias are inspected to find the MDomain matching a VirtualHost. This automatically detects coverage, even when you only have added one of the names to an MDomain.

However, this auto-magic has drawbacks in more complex setups. If you set this directive to `servernames`, only the ServerName of a virtual host is used for matching. ServerAliases are disregarded then, for matching. Aliases will still be added to the certificate obtained, unless you also run `MDMembers manual`.

Another advantage of `servernames` is that it gives you more flexibility with sub-domains and wildcards. You can define one MDomain with a wildcard and have other MDomains for specific sub-domain names.

top

MDMember Directive

Description:Additional hostname for the managed domain.
Syntax:MDMember hostname
Context:server config
Status:Experimental
Module:mod_md

Instead of listing all dns names on the same line, you may use MDMember to add such names to a managed domain.

Example

<MDomain example.org>
    MDMember www.example.org
    MDMember mail.example.org
</MDomain>

If you use it in the global context, outside a specific MD, you can only specify one value, 'auto' or 'manual' as the default for all other MDs. See MDomain for a description of these special values.

top

MDMembers Directive

Description:Control if the alias domain names are automatically added.
Syntax:MDMembers auto|manual
Default:MDMembers auto
Context:server config
Status:Experimental
Module:mod_md

Defines if the ServerName and ServerAlias values of a VirtualHost are automatically added to the members of a Managed Domain or not.

top

MDMessageCmd Directive

Description:Handle events for Manage Domains
Syntax:MDMessageCmd path-to-cmd optional-args
Context:server config
Status:Experimental
Module:mod_md

This command gets called when one of the following events happen for a Managed Domain: "renewed", "installed", "expiring", "errored". The command may be invoked for more than these in the future and ignore events it is not prepared to handle.

This is the more flexible companion to MDNotifyCmd.

Example

MDMessageCmd /etc/apache/md-message

# will be invoked when a new certificate for mydomain.org is available as: /etc/apache/md-message renewed mydomain.com

The program should not block, as the module will wait for it to finish. A return code other than 0 is regarded as an error.

'errored' is no immediate cause for concern since renewal is attempted early enough to allow the internet to come back. This is reported at most once per hour.

'expiring' should be taken serious. It is issued when the MDWarnWindow is reached. By default this is 10% of the certificate lifetime, so for Let's Encrypt this currently means 9 days before it expires. The warning is repeated at most once a day.

'renewed' means that a new certificate has been obtained and is stored in the 'staging' area in the MD store. It will be activated on the next server restart/reload.

'installed' is triggered when a new certificate has been transferred from staging into the domains location in MD store. This happens at server startup/reload. Different to all other invocations, MDMessageCmd is run with root permissions (on *nix systems) and has access to the certificate files (and keys). Certificates needed for other applications or in different formats can be processed on this event.

'renewing' event is triggered before starting renew process for the managed domain. Should the command return != 0 for this reason, renew will be aborted and repeated on next cycle. Some cluster setups use this to allow renewals to run only on a single node.

'challenge-setup:type:domain' event is triggered when the challenge data for a domain has been created. This is invoked before the ACME server is told to check for it. The type is one of the ACME challenge types. This is invoked for every DNS name in a MDomain. Cluster setups may use this event to distribute challenge files to all nodes in a cluster.

ocsp-errored happens when MDStapling is enabled for a domain, this indicates that an error was encountered retrieving the OCSP response from the Certificate Authority. mod_md will continue trying.

top

MDMustStaple Directive

Description:Control if new certificates carry the OCSP Must Staple flag.
Syntax:MDMustStaple on|off
Default:MDMustStaple off
Context:server config
Status:Experimental
Module:mod_md

Defines if newly requested certificate should have the OCSP Must Staple flag set or not. If a certificate has this flag, the server is required to send a OCSP stapling response to every client. This only works if you configure mod_ssl to generate this (see SSLUseStapling and friends).

top

MDNotifyCmd Directive

Description:Run a program when a Managed Domain is ready.
Syntax:MDNotifyCmd path [ args ]
Context:server config
Status:Experimental
Module:mod_md

The configured executable is run when a Managed Domain has signed up or renewed its certificate. It is given the name of the processed MD as additional arguments (after the parameters specified here). It should return status code 0 to indicate that it has run successfully.

top

MDomain Directive

Description:Define list of domain names that belong to one group.
Syntax:MDomain dns-name [ other-dns-name... ] [auto|manual]
Context:server config
Status:Experimental
Module:mod_md

All the names in the list are managed as one Managed Domain (MD). mod_md will request one single certificate that is valid for all these names. This directive uses the global settings (see other MD directives below). If you need specific settings for one MD, use the <MDomainSet>.

There are 2 additional settings that are necessary for a Managed Domain: a contact Email address (via MDContactEmail or ServerAdmin) and MDCertificateAgreement. The mail address of ServerAdmin is used to register at the CA (Let's Encrypt by default). The CA may use it to notify you about changes in its service or status of your certificates.

The second setting, MDCertificateAgreement, should have the value "accepted". By specifying this, you confirm that your accept the Terms of Service of the CA.

Example

MDContactEmail admin@example.org
MDCertificateAgreement accepted
MDomain example.org www.example.org

<VirtualHost *:443>
    ServerName example.org
    DocumentRoot htdocs/root

    SSLEngine on
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.org
    DocumentRoot htdocs/www

    SSLEngine on
</VirtualHost>

There are two special names that you may use in this directive: 'manual' and 'auto'. This determines if a Managed Domain shall have exactly the name list as is configured ('manual') or offer more convenience. With 'auto' all names of a virtual host are added to a MD. Conveniently, 'auto' is also the default.

Example

MDomain example.org

<VirtualHost *:443>
    ServerName example.org
    ServerAlias www.example.org
    DocumentRoot htdocs/root

    SSLEngine on
</VirtualHost>

MDomain example2.org auto

<VirtualHost *:443>
    ServerName example2.org
    ServerAlias www.example2.org
    ...
</VirtualHost>

In this example, the domain 'www.example.org' is automatically added to the MD 'example.org'. Similarly for 'example2.org' where 'auto' is configured explicitly. Whenever you add more ServerAlias names to this virtual host, they will be added as well to the Managed Domain.

If you prefer to explicitly declare all the domain names, use 'manual' mode. An error will be logged if the names do not match with the expected ones.

top

<MDomainSet> Directive

Description:Container for directives applied to the same managed domains.
Syntax:<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>
Context:server config
Status:Experimental
Module:mod_md

This is the directive MDomain with the added possibility to add setting just for this MD. In fact, you may also use "<MDomain ..>" as a shortcut.

This allows you to configure an MD that uses another Certificate Authority, have other renewal requirements, etc.

Example

<MDomain sandbox.example.org>
    MDCertificateAuthority   https://someotherca.com/ACME
</MDomain>

A common use case is to configure https: requirements separately for your domains.

Example

<MDomain example.org>
    MDRequireHttps temporary
</MDomain>
top

MDPortMap Directive

Description:Map external to internal ports for domain ownership verification.
Syntax:MDPortMap map1 [ map2 ]
Default:MDPortMap http:80 https:443
Context:server config
Status:Experimental
Module:mod_md

The ACME protocol provides two methods to verify domain ownership via HTTP: one that uses 'http:' urls (port 80) and one for 'https:' urls (port 443). If your server is not reachable by at least one of the two, ACME may only work by configuring your DNS server, see MDChallengeDns01.

On most public facing servers, 'http:' arrives on port 80 and 'https:' on port 443. The module checks the ports your Apache server is listening on and assumes those are available. This means that when your server does not listen on port 80, it assumes that 'http:' requests from the internet will not work.

This is a good guess, but it may be wrong. For example, your Apache might listen to port 80, but your firewall might block it. 'http:' is only available in your intranet. So, the module will falsely assume that Let's Encrypt can use 'http:' challenges with your server. This will then fail, because your firewall will drop those.

Example

MDPortMap http:- https:8433

The above example shows how you can specify that 'http:' requests from the internet will never arrive. In addition it says that 'https:' requests will arrive on local port 8433.

This is necessary if you have port forwarding in place, your server may be reachable from the Internet on port 443, but the local port that httpd uses is another one. Your server might only listen on ports 8443 and 8000, but be reached on ports 443 and 80 (from the internet).

top

MDPrivateKeys Directive

Description:Set type and size of the private keys generated.
Syntax:MDPrivateKeys type [ params... ]
Default:MDPrivateKeys RSA 2048
Context:server config
Status:Experimental
Module:mod_md

Defines what kind of private keys are generated for a managed domain and with what parameters. You can have more than one private key type configured and the module will obtain a certificate for each key.

For example, you may configure an RSA and an Elliptic Curve (EC) key, so that 2 certificates are created for a domain. On a client connection, the first one supported by the client will then be used.

Since EC keys and certificates are smaller, you might want to offer them first for all compatible (modern) clients. This can enable faster handshakes. Add an RSA key type to support older clients.

Example

MDPrivateKeys secp256r1 rsa3072

The EC types supported depend on the CA you use. For Let's encrypt the supported curves include 'secp256r1' and 'secp384r1'.

Each key and certificate type is stored in its own file in the MD store. The key type is part of the file name with some backward compatible naming for RSA certificates. So you may continue sharing these files with other applications.

Please note that this setting only has an effect on new keys. Any existing private key you have remains unaffected. Also, this only affects private keys generated for certificates. ACME account keys are unaffected by this.

top

MDProfile Directive

Description:Use a specific ACME profile from the CA
Syntax:MDProfile name
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.64 and later

This about a non-standard ACME extension by Let's Encrypt.

Lets Encrypt announced they will add Certificate Profiles support in their CA during 2025, beginning with their staging servers. This, among some other details, let's you select the lifetime of the certificates you get. The "default" profile will keep the 90 days and a "tlsserver" profile will issue certificates with only 6 days of validity.

If you do not change your mod_md configuration, you will continue to get the 90 days certificates. Should you believe that a shorter lifetime is beneficial for you (and take the risk that the renewal time is way shorter), you can configure the profile to use via 'MDProfile tlsserver'.

The profile names are defined by the CA. If a profile you configure is not available, no profile will be used and the certificate will be issue according to what the CA considers default.

See MDProfileMandatory on how to disable defaults for profiles.

top

MDProfileMandatory Directive

Description:Control if an MDProfile is mandatory.
Syntax:MDProfileMandatory on|off
Default:MDProfileMandatory off
Context:server config
Status:Experimental
Module:mod_md

Controls if a MDProfile you configure is mandatory or not. When mandatory and the CA does not offer a configured profile, the certificate renewal will fail.

When not mandatory and a profile is not offered by the CA, renewals will be performed without specifying a profile and the CA will issue a certificates according to its defaults.

top

MDRenewMode Directive

Description:Controls if certificates shall be renewed.
Syntax:MDRenewMode always|auto|manual
Default:MDRenewMode auto
Context:server config
Status:Experimental
Module:mod_md

In the default 'auto' mode, the module will do what makes most sense of each Managed Domain. For a domain without any certificates, it will obtain them from the Certificate Authority.

However, if you have defined an MD that is not used by any of Apache's VirtualHosts, it will not bother. And for MDs with static certificate files (see MDCertificateFile), it assumes that you have your own source, and will not renew them either.

You can override this default in either way. If you specify 'always', the module will renew certificates for an MD, regardless if the domains are in use or if there are static files.

For the opposite effect, configure 'manual' and no renewal will be attempted.

top

MDRenewWindow Directive

Description:Control when a certificate will be renewed.
Syntax:MDRenewWindow duration
Default:MDRenewWindow 33%
Context:server config
Status:Experimental
Module:mod_md

If the validity of the certificate falls below duration, mod_md will get a new signed certificate.

Normally, certificates are valid for around 90 days and mod_md will renew them the earliest 33% of their complete lifetime before they expire (so for 90 days validity, 30 days before it expires). If you think this is not what you need, you can specify either the exact time, as in:

Example

# 21 days before expiry
MDRenewWindow 21d 
# 30 seconds (might be close)
MDRenewWindow 30s
# 10% of the cert lifetime
MDRenewWindow 10%

When in auto drive mode, the module will check every 12 hours at least what the status of the managed domains is and if it needs to do something. On errors, for example when the CA is unreachable, it will initially retry after some seconds. Should that continue to fail, it will back off to a maximum interval of hourly checks.

top

MDRequireHttps Directive

Description:Redirects http: traffic to https: for Managed Domains.
Syntax:MDRequireHttps off|temporary|permanent
Default:MDRequireHttps off
Context:server config
Status:Experimental
Module:mod_md

This is a convenience directive to ease http: to https: migration of your Managed Domains. With:

Example

MDRequireHttps temporary

you announce that you want all traffic via http: URLs to be redirected to the https: ones, for now. This is safe and you can remove this again at any time.

The following has consequences: if you want client to no longer use the http: URLs, configure:

Permanent (for at least half a year!)

MDRequireHttps permanent

This does two things:

  1. All request to the http: resources are redirected to the same url with the https: scheme using the 301 status code. This tells clients that this is intended to be forever and the should update any links they have accordingly.
  2. All answers to https: requests will carry the header Strict-Transport-Security with a life time of half a year. This tells the browser that it never (for half a year) shall use http: when talking to this domain name. Browsers will, after having seen this, refuse to contact your unencrypted site. This prevents malicious middleware to downgrade connections and listen/manipulate the traffic. Which is good. But you cannot simply take it back again.

You can achieve the same with mod_alias and some Redirect configuration, basically. If you do it yourself, please make sure to exclude the paths /.well-known/* from your redirection, otherwise mod_md might have trouble signing on new certificates.

If you set this globally, it applies to all managed domains. If you want it for a specific domain only, use:

Example

<MDomain xxx.yyy>
  MDRequireHttps temporary
</MDomain>
top

MDRetryDelay Directive

Description:Time length for first retry, doubled on every consecutive error.
Syntax:MDRetryDelay duration
Default:MDRetryDelay 5s
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.54 and later

The amount of time to wait after an error before trying to renew a certificate again. This duration is doubled after each consecutive error with a maximum of 24 hours.

It is kept separate for each certificate renewal. Meaning an error on one MDomain does not delay the renewals of other domains.

top

MDRetryFailover Directive

Description:The number of errors before a failover to another CA is triggered
Syntax:MDRetryFailover number
Default:MDRetryFailover 13
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.54 and later

The number of consecutive errors on renewing a certificate before another CA is selected. This only applies to configurations that have more than one MDCertificateAuthority specified.

top

MDServerStatus Directive

Description:Control if Managed Domain information is added to server-status.
Syntax:MDServerStatus on|off
Default:MDServerStatus on
Context:server config
Status:Experimental
Module:mod_md

Apaches 'server-status' handler allows you configure a resource to monitor what is going on. This includes now a section listing all Managed Domains with the DNS names, renewal status, lifetimes and main properties.

You can switch that off using this directive.

top

MDStapleOthers Directive

Description:Enable stapling for certificates not managed by mod_md.
Syntax:MDStapleOthers on|off
Default:MDStapleOthers on
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.42 and later

This setting only takes effect when MDStapling is enabled. It controls if mod_md should also provide stapling information for certificates that are not directly controlled by it, e.g. renewed via an ACME CA.

top

MDStapling Directive

Description:Enable stapling for all or a particular MDomain.
Syntax:MDStapling on|off
Default:MDStapling off
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.42 and later

mod_md offers an implementation for providing OCSP stapling information. This is an alternative to the one provided by mod_ssl. For backward compatibility, this is disabled by default.

The stapling can be switched on for all certificates on the server or for an individual MDomain. This will replace any stapling configuration in mod_ssl for these hosts. When disabled, the mod_ssl stapling will do the work (if it is itself enabled, of course). This allows for a gradual shift over from one implementation to the other.

The stapling of mod_md will also work for domains where the certificates are not managed by this module (see MDStapleOthers for how to control this). This allows use of the new stapling without using any ACME certificate management.

top

MDStaplingKeepResponse Directive

Description:Controls when old responses should be removed.
Syntax:MDStaplingKeepResponse duration
Default:MDStaplingKeepResponse 7d
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.42 and later

This time window specifies when OCSP response data used in stapling shall be removed from the store again. Response information older than 7 days (default) is deleted on server restart/reload. This keeps the store from growing when certificates are renewed/reconfigured frequently.

top

MDStaplingRenewWindow Directive

Description:Control when the stapling responses will be renewed.
Syntax:MDStaplingRenewWindow duration
Default:MDStaplingRenewWindow 33%
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.42 and later

If the validity of the OCSP response used in stapling falls below duration, mod_md will obtain a new OCSP response.

The CA issuing a certificate commonly also operates the OCSP responder service and determines how long its signed response about the validity of a certificate are itself valid. The longer a response is valid, the longer it can be cached which mean better overall performance for everyone. The shorter the life time, the more rapidly certificate revocations spread to clients. Also, service reliability is a consideration.

By adjusting the stapling renew window you can control parts of this yourself. If you make the renew time short (e.g. a short time before the current information expires), you gain maximum cache time. But a service outage (down for maintenance, for example) will affect you. If you renew a long time before expiry, updates will be made more frequent, cause more load on the CA server infrastructure and also more coordination between the child processes of your server.

The default is chosen as 33%, which means renewal is started when only a third of the response lifetime is left. For a CA that issues OCSP responses with lifetime of 3 days, this means 2 days of caching and 1 day for renewal attempts. A service outage would have to last full 24 hours to affect your domains.

Setting an absolute renew window, like `2d` (2 days), is also possible.

top

MDStoreDir Directive

Description:Path on the local file system to store the Managed Domains data.
Syntax:MDStoreDir path
Default:MDStoreDir md
Context:server config
Status:Experimental
Module:mod_md

Defines where on the local file system the Managed Domain data is stored. This is an absolute path or interpreted relative to the server root. The default will create a directory 'md' in your server root.

If you move this and have already data, be sure to move/copy the data first to the new location, reconfigure and then restart the server. If you reconfigure and restart first, the server will try to get new certificates that it thinks are missing.

top

MDStoreLocks Directive

Description:Configure locking of store for updates
Syntax:MDStoreLocks on|off|duration
Default:MDStoreLocks off
Context:server config
Status:Experimental
Module:mod_md
Compatibility:Available in version 2.4.55 and later

Enable this to use a lock file on server startup when MDStoreDir is synchronized with the server configuration and renewed certificates are activated.

Locking is intended for setups in a cluster that have a shared file system for MDStoreDir. It will protect the activation of renewed certificates when cluster nodes are restarted/reloaded at the same time. Under the condition that the shared file system does support file locking.

The default duration to obtain the lock is 5 seconds. If the log cannot be obtained, an error is logged and the server startup will continue. This may result in a cluster node to still use the previous certificate afterwards.

A higher timeout will reduce that likelihood, but may delay server startups/reloads in case the locks are not properly handled in the underlying file system. A lock should only be held by a httpd instance for a short duration.

top

MDWarnWindow Directive

Description:Define the time window when you want to be warned about an expiring certificate.
Syntax:MDWarnWindow duration
Default:MDWarnWindow 10%
Context:server config
Status:Experimental
Module:mod_md

See MDRenewWindow for a description on how you can specify the time.

The modules checks the remaining lifetime of certificates and invokes MDMessageCmd when there is less than the warn window left. With the default, this mean 9 days for certificates from Let's Encrypt.

It also applies to Managed Domains with static certificate files ( see MDCertificateFile).

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgid.html.ja.utf80000664000175100017510000003031314743132254021524 0ustar covenercovener mod_cgid - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_cgid

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:外部 CGI デーモンを使った CGI スクリプトの実行
ステータス:Base
モジュール識別子:cgid_module
ソースファイル:mod_cgid.c
互換性:Unix のスレッド MPM のみ

概要

最適化が施されていることと、以下で説明されている追加の ScriptSock ディレクティブを除いては、 mod_cgidmod_cgi と同様の 動作をします。Apache と CGI に関する詳細は mod_cgi の概要を読んでください。

Unix オペレーティングシステムの中には、マルチスレッドのサーバから プロセスを fork するのが非常にコストの高い動作になっているものがあります。 理由は、新しいプロセスが親プロセスのスレッドすべてを複製するからです。 各 CGI 起動時にこのコストがかかるのを防ぐために、mod_cgid は子プロセスを fork して CGI スクリプトを実行するための 外部デーモンを実行します。 主サーバは unix ドメインソケットを使ってこのデーモンと通信します。

コンパイル時にマルチスレッド MPM が選ばれたときは mod_cgi の代わりに必ずこのモジュールが使用されます。 ユーザのレベルではこのモジュールの設定と動作は mod_cgi とまったく同じです。唯一の例外は ScriptSock ディレクティブの 追加で、このディレクティブは CGI デーモンとの通信用のソケットの名前を 指定します。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

CGIDScriptTimeout ディレクティブ

説明:The length of time to wait for more output from the CGI program
構文:CGIDScriptTimeout time[s|ms]
デフォルト:value of Timeout directive when unset or set to 0
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Base
モジュール:mod_cgid
互換性:Available in httpd 2.4.10 and later; in prior releases no timeout was applied

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

ScriptSock ディレクティブ

説明:CGI デーモンとの通信に使われるソケットのファイル名の接頭辞
構文:ScriptSock file-path
デフォルト:ScriptSock logs/cgisock
コンテキスト:サーバ設定ファイル
ステータス:Base
モジュール:mod_cgid

このディレクティブは CGI デーモンとの通信に使われるソケットの ファイル名の接頭辞を設定します。また、ファイル名にはサーバのプロセスIDが 追加されます。ソケットは Apache が起動されたユーザ (通常 root) の パーミッションを用いてオープンされます。CGI スクリプトとの通信の セキュリティを保つために、ソケットの存在するディレクトリに 他のユーザが書き込み権限を持っていないようにすることが重要です。

ScriptSock /var/run/cgid.sock

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgi.html.ko.euc-kr0000664000175100017510000004327314743132254021710 0ustar covenercovener mod_cgi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_cgi

ֽ ƴմϴ. ֱٿ ϼ.
:CGI ũƮ
:Base
:cgi_module
ҽ:mod_cgi.c

mime type application/x-httpd-cgḭų (ġ 1.1 ) ڵ鷯 cgi-script CGI ũƮ νϿ, ϰ, Ŭ̾Ʈ . AddType þ Ȯڸ ų, ScriptAlias 丮 ȿ CGI óȴ.

CGI ũƮ θ DOCUMENT_ROOT ȯ溯 ߰Ѵ. DocumentRoot .

ġ CGI ũƮ ϴ Ұ CGI 丮 ϶.

н ߾ MPM Ѵٸ mod_cgid ؾ Ѵ. 忡 ⺻ ϴ.

Support Apache!

þ

Bugfix checklist

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

CGIScriptTimeout þ

:The length of time to wait for more output from the CGI program
:CGIScriptTimeout time[s|ms]
⺻:value of Timeout directive when unset
:ּ, ȣƮ, directory, .htaccess
:Base
:mod_cgi
:Available in version 2.4.59 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

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 ߻Ҷ ( û , ũƮ ) α׿ ϵDZ⶧ ſ Ŀ ִ. Ŀ þ Ͽ CGI α ִ ũ⸦ Ѵ. ũⰡ ̻ ʴ´.

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_charset_lite.html.ko.euc-kr0000664000175100017510000003443214743132254023611 0ustar covenercovener mod_charset_lite - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_charset_lite

ֽ ƴմϴ. ֱٿ ϼ.
: ȯ
: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 ϴ Ϻθ Ѵ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav.html.ja.utf80000664000175100017510000005364214743132254021402 0ustar covenercovener mod_dav - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_dav

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:分散オーサリングとバージョン管理 (WebDAV) 機能
ステータス:Extension
モジュール識別子:dav_module
ソースファイル:mod_dav.c

概要

このモジュールはクラス 1 とクラス 2 の WebDAV ('ウェブベースの分散オーサリングとバージョン管理') 機能を Apache に提供します。 この HTTP プロトコルの拡張により、リモートのウェブサーバ上にある リソースやコレクションを 作成、移動、複製、削除できるようになります。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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 が実行されている UserGroup に書き込み権限がある必要があります。

<Limit> 節を <Location> ディレクティブ内部に追加して、DAV が有効な場所への アクセスを制限することもできます。DAV クライアントが 一度のリクエストで送信できる最大バイト数を指定したいときは、 LimitXMLRequestBody ディレクティブを使用する必要があります。「通常の」 LimitRequestBody ディレクティブは DAV リクエストに対しては効力を持ちません。

完全な例

DavLockDB /usr/local/apache2/var/DavLock

<Directory /usr/local/apache2/htdocs/foo>
    Require all granted
    Dav On

    AuthType Basic
    AuthName DAV
    AuthUserFile user.passwd

    <LimitExcept GET POST OPTIONS>
        Require user admin
    </LimitExcept>
</Directory>
top

セキュリティの問題

DAV のアクセスメソッドは遠隔クライアントがサーバのファイルを 操作することを可能にしますので、 mod_dav を使用する 前に、サーバが安全であることを特に注意して確認しなければなりません。

サーバ上の DAV が使用可能になっている場所はすべて認証で保護してください。 HTTP 基本認証の使用は推奨できません。少なくとも mod_auth_digest モジュールで提供される HTTP ダイジェスト認証を用いるべきです。WebDAV クライアントのほとんどは この認証方法に対応しています。代わりに、SSL が 有効なコネクションを通した基本認証を使うこともできます。

mod_dav がファイルを操作できるようにするためには、 管理下のディレクトリとファイルとに Apache が実行されている UserGroup で書き込み可能である必要があります。 新しく作成されるファイルもこの UserGroup に所有される ことになります。この理由から、そのアカウントへのアクセスを制御することは 重要です。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

DavBasePath ディレクティブ

説明:Configure repository root path
構文:DavBasePath root-path
デフォルト:None
コンテキスト:ディレクトリ
ステータス:Extension
モジュール:mod_dav
互換性:Available in version 2.4.58 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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>

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.de0000664000175100017510000060213615032765673022104 0ustar covenercovener Kurzreferenz der Direktiven - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Kurzreferenz der Direktiven

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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, wird sie abgeschnitten und mit einem nachfolgenden "+" versehen.

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  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
sServerkonfiguration
vVirtual Host
dVerzeichnis
h.htaccess
CCore
MMPM
BBasis
EErweiterung
Xexperimentell
Textern
AcceptFilter Protokoll FiltersC
Konfiguriert Optimierungen für lauschende Sockets bestimmter Protokolle
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 encoding 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 language-tag 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...] media-type [media-type] ...svdhB
assigns an output filter to a particular media-type
AddType media-type extension [extension] ...svdhB
Maps the given filename extensions onto the specified content type
Alias [URL-path] file-path|directory-pathsvdB
Maps URLs to filesystem locations
AliasMatch regex file-path|directory-pathsvB
Maps URLs to filesystem locations using regular expressions
AliasPreservePath OFF|ON OFF svdB
Map the full path after the alias in a location.
Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
Controls which hosts can access an area of the server
AllowCONNECT port[-port] [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
AllowMethods reset|HTTP-method [HTTP-method]... reset dX
Restrict access to the listed HTTP methods
AllowOverride All|None|Direktiven-Typ [Direktiven-Typ] ... None (2.3.9 und spä +dC
Direktiven-Typen, die in .htaccess-Dateien erlaubt sind.
AllowOverrideList None|directive [directive-type] ... None dC
Individual 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
AsyncRequestWorkerFactor factorsM
Limit concurrent connections per process
AuthBasicAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthBasicFake off|username [password]dhB
Fake basic authentication using the given expressions for username and password
AuthBasicProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthBasicUseDigestAlgorithm MD5|Off Off dhB
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBDUserPWQuery querydE
SQL query to look up a password for a user
AuthDBDUserRealmQuery querydE
SQL query to look up a password hash for a user and realm.
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
AuthDigestAlgorithm MD5|MD5-sess MD5 dhE
Selects the algorithm used to calculate the challenge and response hashes in digest authentication
AuthDigestDomain URI [URI] ...dhE
URIs that are in the same protection space for digest authentication
AuthDigestNonceLifetime seconds 300 dhE
How long the server nonce is valid
AuthDigestProvider provider-name [provider-name] ... file dhE
Sets the authentication provider(s) for this location
AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhE
Determines the quality-of-protection to use in digest authentication
AuthDigestShmemSize size 1000 sE
The amount of shared memory to allocate for keeping track of clients
AuthFormAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthFormBody fieldname httpd_body dB
The name of a form field carrying the body of the request to attempt on successful login
AuthFormDisableNoStore On|Off Off dB
Disable the CacheControl no-store header on the login page
AuthFormFakeBasicAuth On|Off Off dB
Fake a Basic Authentication header
AuthFormLocation fieldname httpd_location dB
The name of a form field carrying a URL to redirect to on successful login
AuthFormLoginRequiredLocation urldB
The URL of the page to be redirected to should login be required
AuthFormLoginSuccessLocation urldB
The URL of the page to be redirected to should login be successful
AuthFormLogoutLocation uridB
The URL to redirect to after a user has logged out
AuthFormMethod fieldname httpd_method dB
The name of a form field carrying the method of the request to attempt on successful login
AuthFormMimetype fieldname httpd_mimetype dB
The name of a form field carrying the mimetype of the body of the request to attempt on successful login
AuthFormPassword fieldname httpd_password dB
The name of a form field carrying the login password
AuthFormProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthFormSitePassphrase secretdB
Bypass authentication checks for high traffic sites
AuthFormSize size 8192 dB
The largest size of the form in bytes that will be parsed for the login details
AuthFormUsername fieldname httpd_username dB
The name of a form field carrying the login username
AuthGroupFile file-pathdhB
Sets the name of a text file containing the list of user groups for authorization
AuthLDAPAuthorizePrefix prefix AUTHORIZE_ dhE
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritative off|on on dhE
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDN distinguished-namedhE
Optional DN to use in binding to the LDAP server
AuthLDAPBindPassword passworddhE
Password used in conjunction with the bind DN
AuthLDAPCharsetConfig file-pathsE
Language to charset conversion configuration file
AuthLDAPCompareAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization comparisons
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 attribute member uniqueMember +dhE
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDN on|off on dhE
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUser off|on off dhE
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPattern regex substitution (.*) $1 (remote use +dhE
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepth Number 10 dhE
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttribute uiddhE
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDN on|off off dhE
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttribute attribute member uniqueMember +dhE
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClass LdapObjectClass groupOfNames groupO +dhE
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhB
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthName auth-domaindhB
Authorization realm for use in HTTP authentication
AuthnCacheContext directory|server|custom-string directory dB
Specify a context string for use in the cache key
AuthnCacheEnablesB
Enable Authn caching configured anywhere
AuthnCacheProvideFor authn-provider [...]dhB
Specify which authn provider(s) to cache for
AuthnCacheSOCache provider-name[:provider-args]sB
Select socache backend provider to use
AuthnCacheTimeout timeout (seconds) 300 (5 minutes) dhB
Set a timeout for cache entries
<AuthnProviderAlias baseProvider Alias> ... </AuthnProviderAlias>sB
Enclose a group of directives that represent an extension of a base authentication provider and referenced by the specified alias
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Enables a FastCGI application to handle the check_authn authentication hook.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Defines a FastCGI application as a provider for authentication and/or authorization
AuthType None|Basic|Digest|FormdhB
Type of user authentication
AuthUserFile file-pathdhB
Sets the name of a text file containing the list of users and passwords for authentication
AuthzDBDLoginToReferer On|Off Off dE
Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
AuthzDBDQuery querydE
Specify the SQL Query for the required operation
AuthzDBDRedirectQuery querydE
Specify a query to look up a login page for the user
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
Sets the type of database file that is used to store list of user groups
<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> sB
Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
AuthzSendForbiddenOnFailure On|Off Off dhB
Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
BalancerGrowth # 5 svE
Number of additional Balancers that can be added Post-configuration
BalancerInherit On|Off On svE
Inherit ProxyPassed Balancers/Workers from the main server
BalancerMember [balancerurl] url [key=value [key=value ...]]dE
Add a member to a load balancing group
BalancerPersist On|Off Off svE
Attempt to persist changes made by the Balancer Manager across restarts.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
BrotliCompressionMaxInputBlock valuesvE
Maximum input block size
BrotliCompressionQuality value 5 svE
Compression quality
BrotliCompressionWindow value 18 svE
Brotli sliding compression window size
BrotliFilterNote [type] notenamesvE
Places the compression ratio in a note for logging
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
BufferSize integer 131072 svdhE
Maximum size in bytes to buffer by the buffer filter
CacheDefaultExpire seconds 3600 (one hour) svdhE
The default duration to cache a document when no expiry date is specified.
CacheDetailHeader on|off off svdhE
Add an X-Cache-Detail header to the response.
CacheDirLength length 2 svE
The number of characters in subdirectory names
CacheDirLevels levels 2 svE
The number of levels of subdirectories in the cache.
CacheDisable url-string | onsvdhE
Disable caching of specified URLs
CacheEnable cache_type [url-string]svdE
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
CacheHeader on|off off svdhE
Add an X-Cache header to the response.
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 svdhE
Ignore the fact that a response has no Last Modified header.
CacheIgnoreQueryString On|Off Off svE
Ignore query string when caching
CacheIgnoreURLSessionIdentifiers identifier [identifier] ... None svE
Ignore defined session identifiers encoded in the URL when caching
CacheKeyBaseURL URLsvE
Override the base URL of reverse proxied cache keys.
CacheLastModifiedFactor float 0.1 svdhE
The factor used to compute an expiry date based on the LastModified date.
CacheLock on|off off svE
Enable the thundering herd lock.
CacheLockMaxAge integer 5 svE
Set the maximum possible age of a cache lock.
CacheLockPath directory /tmp/mod_cache-lock +svE
Set the lock path directory.
CacheMaxExpire seconds 86400 (one day) svdhE
The maximum time in seconds to cache a document
CacheMaxFileSize bytes 1000000 svdhE
The maximum size (in bytes) of a document to be placed in the cache
CacheMinExpire seconds 0 svdhE
The minimum time in seconds to cache a document
CacheMinFileSize bytes 1 svdhE
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
CacheQuickHandler on|off on svE
Run the cache from the quick handler.
CacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheRoot directorysvE
The directory root under which cache files are stored
CacheSocache type[:args]svE
The shared object cache implementation to use
CacheSocacheMaxSize bytes 102400 svdhE
The maximum size (in bytes) of an entry to be placed in the cache
CacheSocacheMaxTime seconds 86400 svdhE
The maximum time (in seconds) for a document to be placed in the cache
CacheSocacheMinTime seconds 600 svdhE
The minimum time (in seconds) for a document to be placed in the cache
CacheSocacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheSocacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheStaleOnError on|off on svdhE
Serve stale content in place of 5xx responses.
CacheStoreExpired On|Off Off svdhE
Attempt to cache responses that the server reports as expired
CacheStoreNoStore On|Off Off svdhE
Attempt to cache requests or responses that have been marked as no-store.
CacheStorePrivate On|Off Off svdhE
Attempt to cache responses that the server has marked as private
CGIDScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIMapExtension CGI-Pfad .EndungdhC
Technik zur Bestimmung des Interpreters für CGI-Skripte
CGIPassAuth On|Off Off dhC
Enables passing HTTP authorization headers to scripts as CGI variables
CGIScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIVar variable ruledhC
Controls how some CGI variables are set
CharsetDefault charsetsvdhE
Charset to translate into
CharsetOptions option [option] ... ImplicitAdd svdhE
Configures charset translation behavior
CharsetSourceEnc charsetsvdhE
Source charset of files
CheckBasenameMatch on|off On svdhE
Also match files with differing file name extensions.
CheckCaseOnly on|off Off svdhE
Limits the action of the speling module to case corrections
CheckSpelling on|off Off svdhE
Enables the spelling module
ChrootDir /path/to/directorysB
Directory for apache to run chroot(8) after startup.
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
CookieHTTPOnly on|off off svdhE
Adds the 'HTTPOnly' attribute to the cookie
CookieName token Apache svdhE
Name of the tracking cookie
CookieSameSite None|Lax|StrictsvdhE
Adds the 'SameSite' attribute to the cookie
CookieSecure on|off off svdhE
Adds the 'Secure' attribute to the 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| expr=expression]svB
Sets filename and format of log file
Dav On|Off|provider-name Off dE
Enable WebDAV HTTP methods
DavBasePath root-pathdE
Configure repository root path
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
DavLockDiscovery on|off on svdhE
Enable lock discovery
DavMinTimeout seconds 0 svdE
Minimum amount of time the server holds a lock on a DAV resource
DBDExptime time-in-seconds 300 svE
Keepalive time for idle connections
DBDInitSQL "SQL statement"svE
Execute an SQL statement after connecting to a database
DBDKeep number 2 svE
Maximum sustained number of connections
DBDMax number 10 svE
Maximum number of connections
DBDMin number 1 svE
Minimum number of connections
DBDParams param1=value1[,param2=value2]svE
Parameters for database connection
DBDPersist On|OffsvE
Whether to use persistent connections
DBDPrepareSQL "SQL statement" labelsvE
Define an SQL prepared statement
DBDriver namesvE
Specify an SQL driver
DefaultIcon url-pathsvdhB
Icon to display for files when no specific icon is configured
DefaultLanguage language-tagsvdhB
Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
DefaultRuntimeDir directory-path DEFAULT_REL_RUNTIME +sC
Base directory for the server run-time files
DefaultType MIME-Type text/plain svdhC
MIME-Content-Type, der gesendet wird, wenn der Server den Typ nicht auf andere Weise ermitteln kann.
Define ParameternamesC
Define the existence of a variable
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
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
DeflateInflateLimitRequestBody valuesvdhE
Maximum size of inflated request bodies
DeflateInflateRatioBurst value 3 svdhE
Maximum number of times the inflation ratio for request bodies can be crossed
DeflateInflateRatioLimit value 200 svdhE
Maximum inflation ratio for request bodies
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] ...dhE
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
DirectoryCheckHandler On|Off Off svdhB
Toggle how this module responds when another handler is configured
DirectoryIndex disabled | local-url [local-url] ... index.html svdhB
List of resources to look for when the client requests a directory
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code off svdhB
Configures an external redirect for directory indexes.
<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.
DTracePrivileges On|Off Off sX
Determines whether the privileges required by dtrace are enabled.
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
<Else> ... </Else>svdhC
Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
<ElseIf expression> ... </ElseIf>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
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
Error messagesvdhC
Abort configuration parsing with a custom error message
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
ErrorLogFormat [connection|request] formatsvC
Format specification for error log entries
ExamplesvdhX
Demonstration directive to illustrate the Apache module API
ExpiresActive On|Off Off svdhE
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[*] sC
Keep track of extended status information for each request
ExtFilterDefine filtername parameterssE
Define an external filter
ExtFilterOptions option [option] ... NoLogStderr dE
Configure mod_ext_filter options
FallbackResource disabled | local-urlsvdhB
Define a default URL for requests that don't map to a file
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 ...svdhB
Configure the filter chain
FilterDeclare filter-name [type]svdhB
Declare a smart filter
FilterProtocol filter-name [provider-name] proto-flagssvdhB
Deal with correct HTTP protocol handling
FilterProvider filter-name provider-name expressionsvdhB
Register a content filter
FilterTrace filter-name levelsvdB
Get debug/diagnostic information from mod_filter
FlushMaxPipelined number 5 svC
Maximum number of pipelined responses above which they are flushed to the network
FlushMaxThreshold number-of-bytes 65535 svC
Threshold above which pending data are flushed to the network
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
GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]sB
Sets filename and format of log file
GprofDir /tmp/gprof/|/tmp/gprof/%svC
Directory to write gmon.out profiling data to.
GracefulShutdownTimeout seconds 0 sM
Specify a timeout after which a gracefully shutdown server will exit.
Group unix-group #-1 sB
Group under which the server will answer requests
H2CopyFiles on|off off svdhE
Determine file handling in responses
H2Direct on|off on for h2c, off for +svE
H2 Direct Protocol Switch
H2EarlyHint name valuesvdhE
Add a response header to be picked up in 103 Early Hints
H2EarlyHints on|off off svE
Determine sending of 103 status codes
H2MaxDataFrameLen n 0 svE
Maximum bytes inside a single HTTP/2 DATA frame
H2MaxHeaderBlockLen n 0 svE
Maximum size of response headers
H2MaxSessionStreams n 100 svE
Maximum number of active streams per HTTP/2 session.
H2MaxWorkerIdleSeconds n 600 sE
Maximum number of seconds h2 workers remain idle until shut down.
H2MaxWorkers nsE
Maximum number of worker threads to use per child process.
H2MinWorkers nsE
Minimal number of worker threads to use per child process.
H2ModernTLSOnly on|off on svE
Require HTTP/2 connections to be "modern TLS" only
H2OutputBuffering on|off on svE
Determine buffering behaviour of output
H2Padding numbits 0 svE
Determine the range of padding bytes added to payload frames
H2ProxyRequests on|off off svE
En-/Disable forward proxy requests via HTTP/2
H2Push on|off on svdhE
H2 Server Push Switch
H2PushDiarySize n 256 svE
H2 Server Push Diary Size
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 svE
H2 Server Push Priority
H2PushResource [add] path [critical]svdhE
Declares resources for early pushing to the client
H2SerializeHeaders on|off off svE
Serialize Request/Response Processing Switch
H2StreamMaxMemSize bytes 65536 svE
Maximum amount of output data buffered per stream.
H2StreamTimeout time-interval[s]svdE
Maximum time waiting when sending/receiving data to stream processing
H2TLSCoolDownSecs seconds 1 svE
Configure the number of seconds of idle time on TLS before shrinking writes
H2TLSWarmUpSize amount 1048576 svE
Configure the number of bytes on TLS connection before doing max writes
H2Upgrade on|off on for h2c, off for +svdhE
H2 Upgrade Protocol Switch
H2WebSockets on|off off svE
En-/Disable WebSockets via HTTP/2
H2WindowSize bytes 65535 svE
Size of Stream Window for upstream data.
Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP response headers
HeaderName filenamesvdhB
Name of the file that will be inserted at the top of the index listing
HeartbeatAddress addr:portsX
Multicast address for heartbeat packets
HeartbeatListen addr:portsX
multicast address to listen for incoming heartbeat requests
HeartbeatMaxServers number-of-servers 10 sX
Specifies the maximum number of servers that will be sending heartbeat requests to this server
HeartbeatStorage file-path logs/hb.dat sX
Path to store heartbeat data when using flat-file storage
HeartbeatStorage file-path logs/hb.dat sX
Path to read heartbeat data
HostnameLookups On|Off|Double Off svdC
Aktiviert DNS-Lookups auf Client-IP-Adressen
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +svC
Modify restrictions on HTTP Request Messages
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
<If expression> ... </If>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime
<IfDefine [!]Parametername> ... </IfDefine>svdhC
Schließt Direktiven ein, die nur ausgeführt werden, wenn eine Testbedingung beim Start wahr ist
<IfDirective [!]directive-name> ... </IfDirective>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific directive
<IfFile [!]filename> ... </IfFile>svdhC
Encloses directives that will be processed only if file exists at startup
<IfModule [!]Modulname|Modulbezeichner> ... </IfModule>svdhC
Schließt Direktiven ein, die abhängig vom Vorhandensein oder Fehlen eines speziellen Moduls ausgeführt werden
<IfSection [!]section-name> ... </IfSection>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific section directive
<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|unformatted formatted svdhB
Action if no coordinates are given when calling an imagemap
Include Dateiname|VerzeichnissvdC
Fügt andere Konfigurationsdateien innerhalb der Server-Konfigurationsdatei ein
IncludeOptional file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IndexHeadInsert "markup ..."svdhB
Inserts text in the HEAD section of an index page.
IndexIgnore file [file] ... "." svdhB
Adds to the list of files to hide when listing a directory
IndexIgnoreReset ON|OFFsvdhB
Empties 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
InputSed sed-commanddhX
Sed command to filter request data (typically POST data)
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
KeptBodySize maximum size in bytes 0 dB
Keep the request body instead of discarding it up to the specified maximum size, for potential use by filters such as mod_include.
LanguagePriority MIME-lang [MIME-lang] ...svdhB
The precedence 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
LDAPConnectionPoolTTL n -1 svE
Discard backend connections that have been sitting in the connection pool too long
LDAPConnectionTimeout secondssE
Specifies the socket connection timeout in seconds
LDAPLibraryDebug 7sE
Enable debugging in the LDAP SDK
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
LDAPReferralHopLimit numberdhE
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferrals On|Off|default On dhE
Enable referral chasing during queries to the LDAP server.
LDAPRetries number-of-retries 3 sE
Configures the number of LDAP server retries.
LDAPRetryDelay seconds 0 sE
Configures the delay between LDAP server retries.
LDAPSharedCacheFile directory-path/filenamesE
Sets the shared memory cache file
LDAPSharedCacheSize bytes 500000 sE
Size in bytes of the shared-memory cache
LDAPTimeout seconds 60 sE
Specifies the timeout for LDAP search and bind operations, in seconds
LDAPTrustedClientCert type directory-path/filename/nickname [password]dhE
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 typesvE
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
ListenCoresBucketsRatio ratio 0 (disabled) sM
Ratio between the number of CPU cores (online) and the number of listeners' buckets
LoadFile filename [filename] ...svE
Link in the named object file or library
LoadModule module filenamesvE
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
LogFormat format|nickname [nickname] "%h %l %u %t \"%r\" +svB
Describes a format for use in a log file
LogIOTrackTTFB ON|OFF OFF svdhE
Enable tracking of time to first byte (TTFB)
LogLevel Level warn svC
Steuert die Ausführlichkeit des Fehlerprotokolls
LogMessage message [hook=hook] [expr=expression] dX
Log user-defined message to error log
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Plug an authorization provider function into mod_authz_core
LuaCodeCache stat|forever|never stat svdhE
Configure the compiled code cache.
LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the access_checker phase of request processing
LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the check_user_id phase of request processing
LuaHookFixups /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the fixups phase of a request processing
LuaHookInsertFilter /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the insert_filter phase of request processing
LuaHookLog /path/to/lua/script.lua log_function_namesvdhE
Provide a hook for the access log phase of a request processing
LuaHookMapToStorage /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslate /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]svE
Provide a hook for the translate name phase of request processing
LuaHookTypeChecker /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the type_checker phase of request processing
LuaInherit none|parent-first|parent-last parent-first svdhE
Controls how parent configuration sections are merged into children
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content input filtering
LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]svdhE
Map a path to a lua handler
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content output filtering
LuaPackageCPath /path/to/include/?.soasvdhE
Add a directory to lua's package.cpath
LuaPackagePath /path/to/include/?.luasvdhE
Add a directory to lua's package.path
LuaQuickHandler /path/to/script.lua hook_function_namesvE
Provide a hook for the quick handler of request processing
LuaRoot /path/to/a/directorysvdhE
Specify the base path for resolving relative paths for mod_lua directives
LuaScope once|request|conn|thread|server [min] [max] once svdhE
One of once, request, conn, thread -- default is once
<Macro name [par1 .. parN]> ... </Macro>svdB
Define a configuration file macro
MaxConnectionsPerChild number 0 sM
Limit on the number of connections that an individual child server will handle during its life
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
MaxRangeOverlaps default | unlimited | none | number-of-ranges 20 svdC
Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
MaxRangeReversals default | unlimited | none | number-of-ranges 20 svdC
Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
MaxRanges default | unlimited | none | number-of-ranges 200 svdC
Number of ranges allowed before returning the complete resource
MaxRequestWorkers numbersM
Maximum number of connections that will be processed simultaneously
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
MDActivationDelay durationsX
How long to delay activation of new certificates
MDBaseServer on|off off sX
Control if base server may be managed or only virtual hosts.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sX
Type of ACME challenge used to prove domain ownership.
MDCertificateAgreement acceptedsX
You confirm that you accepted the Terms of Service of the Certificate Authority.
MDCertificateAuthority url letsencrypt sX
The URL(s) of the ACME Certificate Authority to use.
MDCertificateCheck name urlsX
Set name and URL pattern for a certificate monitoring site.
MDCertificateFile path-to-pem-filesX
Specify a static certificate file for the MD.
MDCertificateKeyFile path-to-filesX
Specify a static private key for for the static cerrtificate.
MDCertificateMonitor name url crt.sh https://crt. +sX
The URL of a certificate log monitor.
MDCertificateProtocol protocol ACME sX
The protocol to use with the Certificate Authority.
MDCertificateStatus on|off on sX
Exposes public certificate information in JSON.
MDChallengeDns01 path-to-commandsX
Set the command for setup/teardown of dns-01 challenges
MDChallengeDns01Version 1|2 1 sX
Set the type of arguments to call MDChallengeDns01 with
MDCheckInterval duration 12h sX
Determines how often certificates are checked
MDContactEmail addresssX
Email address used for account registration
MDDriveMode always|auto|manual auto sX
former name of MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sX
Set the external account binding keyid and hmac values to use at CA
MDHttpProxy urlsX
Define a proxy for outgoing connections.
MDMatchNames all|servernames all sX
Determines how DNS names are matched to vhosts
MDMember hostnamesX
Additional hostname for the managed domain.
MDMembers auto|manual auto sX
Control if the alias domain names are automatically added.
MDMessageCmd path-to-cmd optional-argssX
Handle events for Manage Domains
MDMustStaple on|off off sX
Control if new certificates carry the OCSP Must Staple flag.
MDNotifyCmd path [ args ]sX
Run a program when a Managed Domain is ready.
MDomain dns-name [ other-dns-name... ] [auto|manual]sX
Define list of domain names that belong to one group.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sX
Container for directives applied to the same managed domains.
MDPortMap map1 [ map2 ] http:80 https:443 sX
Map external to internal ports for domain ownership verification.
MDPrivateKeys type [ params... ] RSA 2048 sX
Set type and size of the private keys generated.
MDProfile namesX
Use a specific ACME profile from the CA
MDProfileMandatory on|off off sX
Control if an MDProfile is mandatory.
MDRenewMode always|auto|manual auto sX
Controls if certificates shall be renewed.
MDRenewWindow duration 33% sX
Control when a certificate will be renewed.
MDRequireHttps off|temporary|permanent off sX
Redirects http: traffic to https: for Managed Domains.
MDRetryDelay duration 5s sX
Time length for first retry, doubled on every consecutive error.
MDRetryFailover number 13 sX
The number of errors before a failover to another CA is triggered
MDServerStatus on|off on sX
Control if Managed Domain information is added to server-status.
MDStapleOthers on|off on sX
Enable stapling for certificates not managed by mod_md.
MDStapling on|off off sX
Enable stapling for all or a particular MDomain.
MDStaplingKeepResponse duration 7d sX
Controls when old responses should be removed.
MDStaplingRenewWindow duration 33% sX
Control when the stapling responses will be renewed.
MDStoreDir path md sX
Path on the local file system to store the Managed Domains data.
MDStoreLocks on|off|duration off sX
Configure locking of store for updates
MDWarnWindow duration 10% sX
Define the time window when you want to be warned about an expiring certificate.
MemcacheConnTTL num[units] 15s svE
Keepalive time for idle connections
MergeSlashes ON|OFF ON svC
Controls whether the server merges consecutive slashes in URLs.
MergeTrailers [on|off] off svC
Determines whether trailers are merged into headers
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 containing 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
ModemStandard V.21|V.26bis|V.32|V.34|V.92dX
Modem standard to simulate
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
Mutex mechanism [default|mutex-name] ... [OmitPID] default sC
Configures mutex mechanism and lock file directory for all or specified mutexes
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
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 dhE
Controls the default access state and the order in which Allow and Deny are evaluated.
OutputSed sed-commanddhX
Sed command for filtering response content
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
PrivilegesMode FAST|SECURE|SELECTIVE FAST svdX
Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Protocol protocolsvC
Protocol for a listening socket
ProtocolEcho On|Off Off svX
Turn the echo server on or off
Protocols protocol ... http/1.1 svC
Protocols available for a server/virtual host
ProtocolsHonorOrder On|Off On svC
Determines if order of Protocols determines precedence during negotiation
<Proxy wildcard-url> ...</Proxy>svE
Container for directives applied to proxied resources
Proxy100Continue Off|On On svdE
Forward 100-continue expectation to the origin server
ProxyAddHeaders Off|On On svdE
Add proxy information in X-Forwarded-* headers
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 Off|On [code ...] Off svdE
Override error pages for proxied content
ProxyExpressDBMFile pathnamesvE
Pathname to DBM file.
ProxyExpressDBMType type default svE
DBM type of file.
ProxyExpressEnable on|off off svE
Enable the module functionality.
ProxyFCGIBackendType FPM|GENERIC FPM svdhE
Specify the type of backend FastCGI application
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]svdhE
Allow variables sent to FastCGI servers to be fixed up
ProxyFtpDirCharset character_set ISO-8859-1 svdE
Define the character set for proxied FTP listings
ProxyFtpEscapeWildcards on|off on svdE
Whether wildcards in requested filenames are escaped when sent to the FTP server
ProxyFtpListOnWildcard on|off on svdE
Whether wildcards in requested filenames trigger a file listing
ProxyHCExpr name {ap_expr expression}svE
Creates a named condition expression to use to determine health of the backend based on its response
ProxyHCTemplate name parameter=setting [...]svE
Creates a named template for setting various health check parameters
ProxyHCTPsize size 16 sE
Sets the total server-wide size of the threadpool used for the health check workers
ProxyHTMLBufSize bytes 8192 svdB
Sets the buffer size increment for buffering inline scripts and stylesheets.
ProxyHTMLCharsetOut Charset | *svdB
Specify a charset for mod_proxy_html output.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
svdB
Sets an HTML or XHTML document type declaration.
ProxyHTMLEnable On|Off Off svdB
Turns the proxy_html filter on or off.
ProxyHTMLEvents attribute [attribute ...]svdB
Specify attributes to treat as scripting events.
ProxyHTMLExtended On|Off Off svdB
Determines whether to fix links in inline scripts, stylesheets, and scripting events.
ProxyHTMLFixups [lowercase] [dospath] [reset]svdB
Fixes for simple HTML errors.
ProxyHTMLInterp On|Off Off svdB
Enables per-request interpolation of ProxyHTMLURLMap rules.
ProxyHTMLLinks element attribute [attribute2 ...]svdB
Specify HTML elements that have URL attributes to be rewritten.
ProxyHTMLMeta On|Off Off svdB
Turns on or off extra pre-parsing of metadata in HTML <head> sections.
ProxyHTMLStripComments On|Off Off svdB
Determines whether to strip HTML comments.
ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]svdB
Defines a rule to rewrite HTML links
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 -1 svE
Maximum number of proxies that a request can be forwarded through
ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] [noquery]svdE
Maps remote servers into the local server URL-space
ProxyPassInherit On|Off On svE
Inherit ProxyPass directives defined from the main server
ProxyPassInterpolateEnv On|Off Off svdE
Enable Environment Variable interpolation in Reverse Proxy configurations
ProxyPassMatch [regex] !|url [key=value [key=value ...]]svdE
Maps remote servers into the local server URL-space using regular expressions
ProxyPassReverse [path] url [interpolate]svdE
Adjusts the URL in HTTP response headers sent from a reverse proxied server
ProxyPassReverseCookieDomain internal-domain public-domain [interpolate]svdE
Adjusts the Domain string in Set-Cookie headers from a reverse- proxied server
ProxyPassReverseCookiePath internal-path public-path [interpolate]svdE
Adjusts the Path string in Set-Cookie headers from a reverse- proxied server
ProxyPreserveHost On|Off Off svdE
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-server [username:password]svE
Remote proxy used to handle certain requests
ProxyRemoteMatch regex remote-server [username:password]svE
Remote proxy used to handle requests matched by regular expressions
ProxyRequests On|Off Off svE
Enables forward (standard) proxy requests
ProxySCGIInternalRedirect On|Off|Headername On svdE
Enable or disable internal redirect responses from the backend
ProxySCGISendfile On|Off|Headername Off svdE
Enable evaluation of X-Sendfile pseudo response header
ProxySet url key=value [key=value ...]svdE
Set various Proxy balancer or member parameters
ProxySourceAddress addresssvE
Set local IP address for outgoing proxy connections
ProxyStatus Off|On|Full Off svE
Show Proxy LoadBalancer status in mod_status
ProxyTimeout secondssvE
Network timeout for proxied requests
ProxyVia On|Off|Full|Block Off svE
Information provided in the Via HTTP response header for proxied requests
ProxyWebsocketFallbackToProxyHttp On|Off On svE
Instructs this module to let mod_proxy_http handle the request
QualifyRedirectURL On|Off Off svdC
Controls whether the REDIRECT_URL environment variable is fully qualified
ReadBufferSize bytes 8192 svdC
Size of the buffers used to read data
ReadmeName filenamesvdhB
Name of the file that will be inserted at the end of the index listing
ReceiveBufferSize bytes 0 sM
TCP receive buffer size
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
RedirectRelative On|Off Off svdB
Allows relative redirect targets.
RedirectTemp URL-path URLsvdhB
Sends an external temporary redirect asking the client to fetch a different URL
RedisConnPoolTTL num[units] 15s svE
TTL used for the connection pool with the Redis server(s)
RedisTimeout num[units] 5s svE
R/W timeout used for the connection with the Redis server(s)
ReflectorHeader inputheader [outputheader]svdhB
Reflect an input header to the output headers
RegexDefaultOptions [none] [+|-]option [[+|-]option] ... DOTALL DOLLAR_ENDON +sC
Allow to configure global/default options for regexes
RegisterHttpMethod method [method [...]]sC
Register non-standard HTTP methods
RemoteIPHeader header-fieldsvB
Declare the header field which should be parsed for useragent IP addresses
RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPInternalProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPProxiesHeader HeaderFieldNamesvB
Declare the header field which will record all intermediate IP addresses
RemoteIPProxyProtocol On|OffsvB
Enable or disable PROXY protocol handling
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]svB
Disable processing of PROXY header for certain hosts or networks
RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPTrustedProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
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 add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP request headers
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate] handshake=0 header= +svE
Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Require [not] entity-name [entity-name] ...dhB
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll> ... </RequireAll>dhB
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny> ... </RequireAny>dhB
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone> ... </RequireNone>dhB
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
RewriteBase URL-pathdhE
Sets the base URL for per-directory rewrites
RewriteCond TestString CondPattern [flags]svdhE
Defines a condition under which rewriting will take place
RewriteEngine on|off off svdhE
Enables or disables runtime rewriting engine
RewriteMap MapName MapType:MapSource [MapTypeOptions] svE
Defines a mapping function for key-lookup
RewriteOptions OptionssvdhE
Sets some special options for the rewrite engine
RewriteRule Pattern Substitution [flags]svdhE
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 dhE
Interaction between host-level access control and user authentication
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-pathsvdB
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 cgisock sB
The filename prefix 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
SeeRequestTail On|Off Off sC
Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
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
Session On|Off Off svdhE
Enables a session for the current directory or location
SessionCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session
SessionCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session
SessionCookieRemove On|Off Off svdhE
Control for whether session cookies should be removed from incoming HTTP headers
SessionCryptoCipher name aes256 svdhX
The crypto cipher to be used to encrypt the session
SessionCryptoDriver name [param[=value]]sX
The crypto driver to be used to encrypt the session
SessionCryptoPassphrase secret [ secret ... ] svdhX
The key used to encrypt the session
SessionCryptoPassphraseFile filenamesvdX
File containing keys used to encrypt the session
SessionDBDCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session ID
SessionDBDCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session ID
SessionDBDCookieRemove On|Off On svdhE
Control for whether session ID cookies should be removed from incoming HTTP headers
SessionDBDDeleteLabel label deletesession svdhE
The SQL query to use to remove sessions from the database
SessionDBDInsertLabel label insertsession svdhE
The SQL query to use to insert sessions into the database
SessionDBDPerUser On|Off Off svdhE
Enable a per user session
SessionDBDSelectLabel label selectsession svdhE
The SQL query to use to select sessions from the database
SessionDBDUpdateLabel label updatesession svdhE
The SQL query to use to update existing sessions in the database
SessionEnv On|Off Off svdhE
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionExclude pathsvdhE
Define URL prefixes for which a session is ignored
SessionExpiryUpdateInterval interval 0 (always update) svdhE
Define the number of seconds a session's expiry may change without the session being updated
SessionHeader headersvdhE
Import session updates from a given HTTP response header
SessionInclude pathsvdhE
Define URL prefixes for which a session is valid
SessionMaxAge maxage 0 svdhE
Define a maximum age in seconds for a session
SetEnv env-variable [value]svdhB
Sets environment variables
SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on attributes of the request
SetEnvIfExpr expr [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on an ap_expr expression
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
SSIETag on|off off dhB
Controls whether ETags are generated by the server.
SSILastModified on|off off dhB
Controls whether Last-Modified headers are generated by the server.
SSILegacyExprParser on|off off dhB
Enable compatibility mode for conditional expressions.
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
SSLCARevocationCheck chain|leaf|none [flags ...] none svE
Enable CRL-based revocation checking
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-path|certidsvE
Server PEM-encoded X.509 certificate data file or token identifier
SSLCertificateKeyFile file-path|keyidsvE
Server PEM-encoded private key file
SSLCipherSuite [protocol] cipher-spec DEFAULT (depends on +svdhE
Cipher Suite available for negotiation in SSL handshake
SSLCompression on|off off svE
Enable compression on the SSL level
SSLCryptoDevice engine builtin sE
Enable use of a cryptographic hardware accelerator
SSLEngine on|off|optional off svE
SSL Engine Operation Switch
SSLFIPS on|off off sE
SSL FIPS mode Switch
SSLHonorCipherOrder on|off off svE
Option to prefer the server's cipher preference order
SSLInsecureRenegotiation on|off off svE
Option to enable support for insecure renegotiation
SSLOCSPDefaultResponder urisvE
Set the default responder URI for OCSP validation
SSLOCSPEnable on|leaf|off off svE
Enable OCSP validation of the client certificate chain
SSLOCSPNoverify on|off off svE
skip the OCSP responder certificates verification
SSLOCSPOverrideResponder on|off off svE
Force use of the default responder URI for OCSP validation
SSLOCSPProxyURL urlsvE
Proxy URL to use for OCSP requests
SSLOCSPResponderCertificateFile filesvE
Set of trusted PEM encoded OCSP responder certificates
SSLOCSPResponderTimeout seconds 10 svE
Timeout for OCSP queries
SSLOCSPResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP responses
SSLOCSPResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP response validation
SSLOCSPUseRequestNonce on|off on svE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd command-name command-valuesvE
Configure OpenSSL parameters through its SSL_CONF API
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 -SSLv3 (up to 2 +svE
Configure usable SSL/TLS protocol versions
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
SSLProxyCARevocationCheck chain|leaf|none none svE
Enable CRL-based revocation checking 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
SSLProxyCheckPeerCN on|off on svE
Whether to check the remote server certificate's CN field
SSLProxyCheckPeerExpire on|off on svE
Whether to check if remote server certificate is expired
SSLProxyCheckPeerName on|off on svE
Configure host name checking for remote server certificates
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +svE
Cipher Suite available for negotiation in SSL proxy handshake
SSLProxyEngine on|off off svE
SSL Proxy Engine Operation Switch
SSLProxyMachineCertificateChainFile filenamesvE
File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
SSLProxyMachineCertificateFile filenamesvE
File of concatenated PEM-encoded client certificates and keys to be used by the proxy
SSLProxyMachineCertificatePath directorysvE
Directory of PEM-encoded client certificates and keys to be used by the proxy
SSLProxyProtocol [+|-]protocol ... all -SSLv3 (up to 2 +svE
Configure usable SSL protocol flavors for proxy usage
SSLProxyVerify level none svE
Type of remote server Certificate verification
SSLProxyVerifyDepth number 1 svE
Maximum depth of CA Certificates in Remote Server Certificate verification
SSLRandomSeed context source [bytes]sE
Pseudo Random Number Generator (PRNG) seeding source
SSLRenegBufferSize bytes 131072 dhE
Set the size for the SSL renegotiation buffer
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
SSLSessionTicketKeyFile file-pathsvE
Persistent encryption/decryption key for TLS session tickets
SSLSessionTickets on|off on svE
Enable or disable use of TLS session tickets
SSLSRPUnknownUserSeed secret-stringsvE
SRP unknown user seed
SSLSRPVerifierFile file-pathsvE
Path to SRP verifier file
SSLStaplingCache typesE
Configures the OCSP stapling cache
SSLStaplingErrorCacheTimeout seconds 600 svE
Number of seconds before expiring invalid responses in the OCSP stapling cache
SSLStaplingFakeTryLater on|off on svE
Synthesize "tryLater" responses for failed OCSP stapling queries
SSLStaplingForceURL urisvE
Override the OCSP responder URI specified in the certificate's AIA extension
SSLStaplingResponderTimeout seconds 10 svE
Timeout for OCSP stapling queries
SSLStaplingResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP stapling responses
SSLStaplingResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP stapling response validation
SSLStaplingReturnResponderErrors on|off on svE
Pass stapling related OCSP errors on to client
SSLStaplingStandardCacheTimeout seconds 3600 svE
Number of seconds before expiring responses in the OCSP stapling cache
SSLStrictSNIVHostCheck on|off off svE
Whether to allow non-SNI clients to access a name-based virtual host.
SSLUserName varnamesdhE
Variable name to determine user name
SSLUseStapling on|off off svE
Enable stapling of OCSP responses in the TLS handshake
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
StrictHostCheck ON|OFF OFF svC
Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Substitute s/pattern/substitution/[infq]dhE
Pattern to filter the response content
SubstituteInheritBefore on|off off dhE
Change the merge order of inherited patterns
SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G) 1m dhE
Set the maximum line size
Suexec On|OffsB
Enable or disable the suEXEC feature
SuexecUserGroup User GroupsvE
User and group for CGI programs to run as
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 60 sC
Zeitspanne, die der Server auf verschiedene Ereignisse wartet, bevor er die Anfrage abbricht
TraceEnable [on|off|extended] on sC
Legt das Verhalten von TRACE-Anfragen fest
TransferLog file|pipesvB
Specify location of a log file
TypesConfig file-path conf/mime.types sB
The location of the mime.types file
UNCList hostname [hostname...]sC
Controls what UNC host names can be accessed by the server
UnDefine parameter-namesC
Undefine the existence of a variable
UndefMacro namesvdB
Undefine a macro
UnsetEnv env-variable [env-variable] ...svdhB
Removes variables from the environment
Use name [value1 ... valueN] svdB
Use a macro
UseCanonicalName On|Off|DNS Off svdC
Bestimmt, wie der Server seinen eigenen Namen und Port ermittelt
UseCanonicalPhysicalPort On|Off Off svdC
Bestimmt, wie der Server seinen eigenen Namen und Port ermittelt
User unix-userid #-1 sB
The userid under which the server will answer requests
UserDir directory-filename [directory-filename] ... svB
Location of the user-specific directories
VHostCGIMode On|Off|Secure On vX
Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to subprocesses created by a virtual host.
VHostGroup unix-groupidvX
Sets the Group ID under which a virtual host runs.
VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to a virtual host.
VHostSecure On|Off On vX
Determines whether the server runs with enhanced security for the virtualhost.
VHostUser unix-useridvX
Sets the User ID under which a virtual host runs.
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
WatchdogInterval time-interval[s] 1 sB
Watchdog interval in seconds
XBitHack on|off|full off svdhB
Parse SSI directives in files with the execute bit set
xml2EncAlias charset alias [alias ...]sB
Recognise Aliases for encoding values
xml2EncDefault namesvdhB
Sets a default encoding to assume when absolutely no information can be automatically detected
xml2StartParse element [element ...]svdhB
Advise the parser to skip leading junk.

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav_fs.html.ja.utf80000664000175100017510000002514714743132254022071 0ustar covenercovener mod_dav_fs - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_dav_fs

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:mod_dav のためのファイルシステムプロバイダ
ステータス:Extension
モジュール識別子:dav_fs_module
ソースファイル:mod_dav_fs.c

概要

このモジュールは mod_dav のサービスを必要としますmod_dav のサポートモジュールとして動作し、サーバファイルシステム上に 位置するリソースへのアクセスを提供します。このプロバイダの正式な名前は filesystem です。mod_dav バックエンドプロバイダは Dav ディレクティブを使用して起動されます。

Dav filesystem

filesystemmod_dav のデフォルトプロバイダになっていますから、代わりに単に On と指定することもできます。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

DavLockDB ディレクティブ

説明:DAV ロックデータベースの位置
構文:DavLockDB file-path
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_dav_fs

ロックデータベースへのフルパスを、拡張子を除いた形で 指定するには、DavLockDB を使います。パスが絶対パスでなければ、ServerRoot からの相対パスと解釈されます。 mod_dav_fs 実装では、ユーザロックを 追跡するために SDBM データベースを使います。

DavLockDB logs/DavLock

top

DavLockDiscovery ディレクティブ

説明:Enable lock discovery
構文:DavLockDiscovery on|off
デフォルト:DavLockDiscovery on
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_dav_fs
互換性:Available from Apache 2.4.55 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav_fs.html.ko.euc-kr0000664000175100017510000002425214743132254022404 0ustar covenercovener mod_dav_fs - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_dav_fs

ֽ ƴմϴ. ֱٿ ϼ.
: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 ִ.

Support Apache!

þ

Bugfix checklist

top

DavLockDB þ

:DAV ͺ̽ ġ
:DavLockDB file-path
:ּ, ȣƮ
:Extension
:mod_dav_fs

DavLockDB þ ͺ̽ ü θ Ȯڸ ϰ Ѵ. ΰ ƴϸ ServerRoot η óѴ. mod_dav_fs SDBM ͺ̽ Ѵ.

DavLockDB var/DavLock

ġ ϴ User Group ͺ̽ ִ 丮 Ѵ. Ȼ 丮 ٲٱ⺸ٴ ͺ̽ 丮 Ѵ. ġ ServerRoot Ʒ var/ 丮 Ȯ DavLock .

top

DavLockDiscovery þ

:Enable lock discovery
:DavLockDiscovery on|off
⺻:DavLockDiscovery on
:ּ, ȣƮ, directory, .htaccess
:Extension
:mod_dav_fs
:Available from Apache 2.4.55 and later.

The documentation for this directive has not been translated yet. Please have a look at the English version.

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_deflate.html.ja.utf80000664000175100017510000010070714743132254022227 0ustar covenercovener mod_deflate - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_deflate

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:クライアントへ送られる前にコンテンツを圧縮する
ステータス:Extension
モジュール識別子:deflate_module
ソースファイル:mod_deflate.c

概要

mod_deflate モジュールは DEFLATE 出力フィルタを提供します。これはサーバからの出力を、ネットワークを 通してクライアントに送る前に圧縮することを可能にします。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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

# 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-gzipgzip-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 するフィルタも提供しています。 この機能を有効にするには、SetOutputFilterAddOutputFilter を使って、 INFLATE フィルタを出力フィルタチェインに挿入します。 例えば次のようにします。

<Location /dav-area>
ProxyPass http://example.com/
SetOutputFilter INFLATE
</Location>

この例では、example.com からの gzip 圧縮された出力を伸長し、 その他のフィルタがさらにその出力を処理できるようにします。

入力の伸張

mod_deflate モジュールは、gzip で圧縮されたリクエスト本体を伸張するフィルタも提供しています。 この機能を有効にするには、SetInputFilterAddInputFilter を使用して、 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

DeflateAlterETag ディレクティブ

説明:How the outgoing ETag header should be modified during compression
構文:DeflateAlterETag AddSuffix|NoChange|Remove
デフォルト:DeflateAlterETag AddSuffix
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_deflate
互換性:Available in Apache 2.4.58 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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

DeflateInflateLimitRequestBody ディレクティブ

説明:Maximum size of inflated request bodies
構文:DeflateInflateLimitRequestBody value
デフォルト:None, but LimitRequestBody applies after deflation
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_deflate
互換性:2.4.10 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

DeflateInflateRatioBurst ディレクティブ

説明:Maximum number of times the inflation ratio for request bodies can be crossed
構文:DeflateInflateRatioBurst value
デフォルト:DeflateInflateRatioBurst 3
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_deflate
互換性:2.4.10 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

DeflateInflateRatioLimit ディレクティブ

説明:Maximum inflation ratio for request bodies
構文:DeflateInflateRatioLimit value
デフォルト:DeflateInflateRatioLimit 200
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_deflate
互換性:2.4.10 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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 にするのが良いでしょう。)

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dir.html.ko.euc-kr0000664000175100017510000004103314743132254021714 0ustar covenercovener mod_dir - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_dir

ֽ ƴմϴ. ֱٿ ϼ.
:" " ̷ ϰ 丮 index Ѵ
:Base
:dir_module
ҽ:mod_dir.c

丮 index Ѱ ȴ:

Ѵٸ ڵ index (Ȥ ü) ִ.

dirname 丮 URL http://servername/foo/dirname û " " ̷ . 丮 ʿϴ. ׷ mod_dir http://servername/foo/dirname/ ̷ .

Support Apache!

þ

Bugfix checklist

top

DirectoryCheckHandler þ

:Toggle how this module responds when another handler is configured
:DirectoryCheckHandler On|Off
⺻:DirectoryCheckHandler Off
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Indexes
:Base
:mod_dir
:Available in 2.4.8 and later. Releases prior to 2.4 implicitly act as if "DirectoryCheckHandler ON" was specified.

The documentation for this directive has not been translated yet. Please have a look at the English version.

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

DirectoryIndexRedirect þ

:Configures an external redirect for directory indexes.
:DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code
⺻:DirectoryIndexRedirect off
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Indexes
:Base
:mod_dir
:Available in version 2.3.14 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

DirectorySlash þ

: ̷ Ű
:DirectorySlash On|Off
⺻:DirectorySlash On
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Indexes
:Base
:mod_dir
:ġ 2.0.51 ĺ

DirectorySlash þ mod_dir 丮 Ű URL θ Ѵ.

ڰ 丮 شϴ ڿ ûϸ, mod_dir ڸ ڿ ̷Ѵ.

׷ ʰ ſ ˸ ʴٸ ̷ ִ.

# Ʒ !
<Location /some/path>
DirectorySlash Off
SetHandler some-handler
</Location>

̷ ִ. (Options +Indexes) mod_autoindex ϰ DirectoryIndex (index.html ) ȿ ڿ Ͽ ش URL ٸ Ư ڵ鷯 Ȳ غ. ִ û index.html ش. ׷ û 丮 ش.

top

FallbackResource þ

:Define a default URL for requests that don't map to a file
:
:ּ, ȣƮ, directory, .htaccess
:Base
:mod_dir

Documentation not yet translated. Please see English version of document.

:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_echo.html.ja.utf80000664000175100017510000001761014743132254021541 0ustar covenercovener mod_echo - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_echo

翻訳済み言語:  en  |  fr  |  ja  |  ko 

説明:プロトコルモジュールの概要を示すための単純なエコーサーバ
ステータス:Experimental
モジュール識別子:echo_module
ソースファイル:mod_echo.c

概要

本モジュールはコンセプトを伝えるためのプロトコルモジュールの 実装例となっています。単純なエコーサーバを提供します。 Telnet で接続し、文字列を送信すると、エコーを返します。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

ProtocolEcho ディレクティブ

説明:エコーサーバの有効無効を設定します。
構文:ProtocolEcho On|Off
デフォルト:ProtocolEcho Off
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Experimental
モジュール:mod_echo

ProtocolEcho ディレクティブで エコーサーバの有効無効を設定します。

ProtocolEcho On

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dir.html.tr.utf80000664000175100017510000005724514743132254021444 0ustar covenercovener mod_dir - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_dir

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:Bölü çizgisiyle biten yönlendirmeleri yapar ve dizin içeriği dosyalarını sunar.
Durum:Temel
Modül Betimleyici:dir_module
Kaynak Dosyası:mod_dir.c

Özet

Bir dizin içerik dosyası şu iki kaynaktan birinden gelebilir:

Bu iki işlev tamamen birbirinden ayrıdır, dolayısıyla eğer isterseniz kendiliğinden dizin içerik listesi üretimini tamamen iptal edebilirsiniz.

Sunucu http://example.com/filanca/birdizin şeklinde bir istek aldığında birdizin bir dizinin ismiyse ‘bölü çizgisiyle biten’ bir yönlendirme söz konusudur. Dizinler URL sonuna bir bölü çizgisi eklenmesini gerektirir, bu bakımdan mod_dir modülü isteği http://example.com/filanca/birdizin/ şeklinde yönlendirir.

Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

DirectoryCheckHandler Yönergesi

Açıklama:Başka bir eylemci yapılandırılmışsa bu modülün nasıl yanıt vereceğini belirler
Sözdizimi:DirectoryCheckHandler On|Off
Öntanımlı:DirectoryCheckHandler Off
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_dir
Uyumluluk:2.4.8 ve sonrasında kullanılabilmektedir. 2.4 öncesi sürümler örtük olarak "DirectoryCheckHandler ON" belirtilmiş gibi davranır.

DirectoryCheckHandler yönergesi, geçerli URL için başka bir eylemcinin yapılandırılmış olması durumunda, mod_dir modülünün index dosyaları için dizine mi bakacağını yoksa URL'nin sonuna bölü çizgisi mi ekleyeceğini belirler. Eylemciler SetHandler gibi yönergelerle atanabileceği gibi dizin işlemleri sırasında mod_rewrite gibi modüller tarafından da atanabilir.

2.4 öncesi sürümlerde, bir URL için başka bir eylemcinin yapılandılmış olması durumunda bu modül herhangi bir eylemde bulunmaz ve sonuç olarak, tüm dizin için bir SetHandler belirtildiği durumda index dosyalarının sunulmasının yanında mod_rewrite gibi modüller de ayrıca bazı çelişkili sonuçlar oluşturabilir.

top

DirectoryIndex Yönergesi

Açıklama:İstemci bir dizin istediğinde dizin içeriğini listeler.
Sözdizimi:DirectoryIndex disabled | yerel-url [yerel-url] ...
Öntanımlı:DirectoryIndex index.html
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_dir

DirectoryIndex yönergesi, istemci, dizinin sonuna bir bölü çizgisi ekleyerek dizin içeriğinin listelenmesini istediğinde bakılmak üzere özkaynakları listeler. yerel-url, sunucu üstünde istenen dizine göreli bir belgenin URL’sidir; normal olarak dizin içindeki bir dosyanın ismidir. Çeşitli URL’ler verilebilirse de sunucu daima ilk bulduğuyla dönecektir. Eğer özkaynakların hiçbiri yoksa ve Indexes seçeneği atanmışsa sunucu dizin içeriğinden bir liste üretecektir.

DirectoryIndex index.html

Bu yapılandırmadan sonra yapılan bir http://sunucum/belgeler/ isteğine karşılık, sunucu, mevcutsa http://sunucum/belgeler/index.html dosyasını döndürecek, değilse ürettiği dizin içerik listesini gönderecektir.

Belgelerin dizine göreli olmasının gerekmediğine dikkat ediniz.

DirectoryIndex index.html index.txt  /cgi-bin/index.pl

Bu örnekte ise dizin içinde ne index.html ne de index.txt mevcut olduğunda /cgi-bin/index.pl CGI betiği çalıştırılacaktır.

disabled değeri tek başına mod_dir’in bir dizin listesi aramasını engeller. disabled değiştirgesi öncesinde ve sonrasında başka bir değiştirge hatta bir disabled daha olsa bile sadece bir disabled verilmiş gibi yorumlanır.

Bilginize: Aynı bağlamdaki çok sayıda DirectoryIndex yönergesi bir öncekini değiştirmek yerine onun bulunduğu listeye eklenir:

# 1. örnek: İçerik dosyası olarak index.html atayıp sonraki satırda buna
# index.php'yi ekleyebilirsiniz.
<Directory "/foo">
    DirectoryIndex index.html
    DirectoryIndex index.php
</Directory>

# 2. Örnek: Atamaların tet bir satırda yapıldığı bu örnek 1. örneğe denktir.
<Directory "/foo">
    DirectoryIndex index.html index.php
</Directory>

# 3. Örnek: Listeyi tamamen değiştirmek için, listeyi önce sıfırlamalısınız:
# Bu örnekte içerik dosyası olarak listede sadece index.php kalır.
<Directory "/foo">
    DirectoryIndex index.html
    DirectoryIndex disabled
    DirectoryIndex index.php
</Directory>
top

DirectoryIndexRedirect Yönergesi

Açıklama:Dizin içerik listeleri için harici bir yönlendirme yapılandırır.
Sözdizimi:DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-kodu
Öntanımlı:DirectoryIndexRedirect off
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_dir
Uyumluluk:Apache HTTP Sunucusunun 2.3.14 ve sonraki sürümlerinde kullanılabilmektedir.

Öntanımlı olarak, DirectoryIndex listeyi istemciye şeffaf olarak seçip gönderir. DirectoryIndexRedirect ise harici bir yönlendirmeye sebep olur.

Bunlardan biri kullanılabilir:

Örnek

DirectoryIndexRedirect on

http://example.com/docs/ için yapılan bir istek, http://example.com/docs/index.html (mevcutsa) adresine geçici bir yönlendirme döndürür.

top

DirectorySlash Yönergesi

Açıklama:Bölü çizgisi ile biten yönlendirmeleri açar/kapar.
Sözdizimi:DirectorySlash On|Off
Öntanımlı:DirectorySlash On
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_dir

DirectorySlash yönergesi, bir dizin isteğinde bulunan URL’lerin sonuna mod_dir modülü tarafından bir bölü çizgisi eklenip eklenmeyeceğini belirler.

Normalde, bir kullanıcı sona bir bölü çizgisi eklemeden bir dizin için istekte bulunursa mod_dir zaten onu aynı özkaynağa yönlendirir, fakat isteğin sonuna bir bölü çizgisi eklenmesinin bazı iyi sebepleri vardır:

Siz yine de bu etkiyi istemezseniz ve yukarıdaki sebepler de size uygun değilse yönlendirmeyi aşağıdaki gibi kapatabilirsiniz. Ancak bunu yaparken dikkatli olun, bununla ilgili bazı güvenlik sorunları olasılığı vardır.

# Aşağıdaki güvenlik uyarısına bakınız!
<Location "/bir/yol">
DirectorySlash Off
SetHandler bir-eylemci
</Location>

Güvenlik Uyarı

Bölü çizgisi ile biten yönlendirmelerin kapatılması bir bilginin istemeyek açığa çıkmasına sebep olabilir. mod_autoindex modülünün etkin olduğunu (Options +Indexes) ve DirectoryIndex ile geçerli bir özkaynağın (index.html olsun) atandığını ama bu URL için başka hiçbir özel eylemci tanımlanmadığını varsayalım. Bu durumda bölü çizgisi ile biten bir istek olduğunda index.html dosyası sunulurdu. Fakat bölü çizgisi ile bitmeyen bir istek dizin içeriğinin listelenmesi ile sonuçlanırdı.

Bir yönlendirme sözkonusu olduğunda bazı tarayıcıların yanlışlıkla POST isteklerini GET istekleri haline getirme (böylece POST verisi iptal olur) olasılığı olduğuna da dikkat edin.

top

FallbackResource Yönergesi

Açıklama:Bir dosya ile eşleşmeyen istekler için öntanımlı URL tanımlar
Sözdizimi:FallbackResource disabled | yerel-url
Öntanımlı:disabled - httpd 404 döndürecektir (Yok)
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:Indexes
Durum:Temel
Modül:mod_dir
Uyumluluk:disabled değiştirgesi 2.4.4 sürümü ve sonrasında kullanılabilmektedir.

Dosya sisteminde bulunmayan bir dosya için istek yapıldığında HTTP'nin 404 (Yok) hatasını döndürmemesi için sunulacak dosyanın yolunu tanımlar. Örnek:

FallbackResource /not-404.php

Bu satırla, (mevcut dosyaları etkilemeden) mevcut olmayan dosyaların yerine not-404.php dosyası sunulacaktır.

Belli bir dizindeki mevcut bir dosya veya betik için yapılanlar dışındaki tüm isteklerin tek bir dosya veya özkaynakla yerine getirilmesi sıkça istenen bir durum olup bu mekanizmaya 'ön denetleyici' adı verilir.

httpd'nin önceki sürümlerinde bir dosya veya dizinin varlığının sınanması için genellikle mod_rewrite modülü ve -f ve -d kullanımı gerekirdi. Bunun için şimdi tek satırlık bir yapılandırma yeterli olmaktadır.

FallbackResource /index.php

Resim, CSS dosyaları gibi mevcut dosyalar normal olarak sunulur.

Üst dizinden hiçbir şeyin miras alınmaması isteniyorsa bu özelliği kapatmak için disabled değiştirgesini kullanın.

http://example.com/blog/ gibi bir alt URI yerel-url olarak sağlanır:

<Directory "/web/example.com/htdocs/blog">
  FallbackResource /blog/index.php
</Directory>
<Directory "/web/example.com/htdocs/blog/images">
  FallbackResource disabled
</Directory>

Bir acil durum işleyicisi (yukarıdaki durumda, /blog/index.php) özgün istek URL'sine sunucu değişkeni REQUEST_URI üzerinden erişebilir. Örneğin PHP'de bu değişkene erişmek için $_SERVER['REQUEST_URI'] kullanılır.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_echo.html.ko.euc-kr0000664000175100017510000001706314743132254022062 0ustar covenercovener mod_echo - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_echo

ֽ ƴմϴ. ֱٿ ϼ.
: ϱ echo
:Experimental
:echo_module
ҽ:mod_echo.c
:Apache 2.0 ĺ

ϱ ̴. echo Ѵ. telnetϿ 𰡸 Էϸ, Է ״ ȯѴ.

Support Apache!

þ

Bugfix checklist

top

ProtocolEcho þ

:echo Ű
:ProtocolEcho On|Off
:ּ, ȣƮ
:Experimental
:mod_echo
:ProtocolEcho 2.0 Ŀ ִ.

ProtocolEcho þ echo Ű .

ProtocolEcho On

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.en0000664000175100017510000060023415032765673022113 0ustar covenercovener Directive Quick Reference - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Directive Quick Reference

Available Languages:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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 column shows the default value of the directive, if a default exists. If the default is too large to display, it will be truncated and 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  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
sserver config
vvirtual host
ddirectory
h.htaccess
pproxy section
CCore
MMPM
BBase
EExtension
XExperimental
TExternal
AcceptFilter protocol accept_filtersC
Configures optimizations for a Protocol's Listener 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 encoding 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 language-tag 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...] media-type [media-type] ...svdhB
assigns an output filter to a particular media-type
AddType media-type extension [extension] ...svdhB
Maps the given filename extensions onto the specified content type
Alias [URL-path] file-path|directory-pathsvdB
Maps URLs to filesystem locations
AliasMatch regex file-path|directory-pathsvB
Maps URLs to filesystem locations using regular expressions
AliasPreservePath OFF|ON OFF svdB
Map the full path after the alias in a location.
Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
Controls which hosts can access an area of the server
AllowCONNECT port[-port] [port[-port]] ... 443 563 svE
Ports that are allowed to CONNECT through the proxy
AllowEncodedSlashes On|Off|NoDecode Off svC
Determines whether encoded path separators in URLs are allowed to be passed through
AllowMethods reset|HTTP-method [HTTP-method]... reset dX
Restrict access to the listed HTTP methods
AllowOverride All|None|directive-type [directive-type] ... None (2.3.9 and lat +dC
Types of directives that are allowed in .htaccess files
AllowOverrideList None|directive [directive-type] ... None dC
Individual 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
AsyncRequestWorkerFactor factorsM
Limit concurrent connections per process
AuthBasicAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthBasicFake off|username [password]dhB
Fake basic authentication using the given expressions for username and password
AuthBasicProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthBasicUseDigestAlgorithm MD5|Off Off dhB
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBDUserPWQuery querydE
SQL query to look up a password for a user
AuthDBDUserRealmQuery querydE
SQL query to look up a password hash for a user and realm.
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
AuthDigestAlgorithm MD5|MD5-sess MD5 dhE
Selects the algorithm used to calculate the challenge and response hashes in digest authentication
AuthDigestDomain URI [URI] ...dhE
URIs that are in the same protection space for digest authentication
AuthDigestNonceLifetime seconds 300 dhE
How long the server nonce is valid
AuthDigestProvider provider-name [provider-name] ... file dhE
Sets the authentication provider(s) for this location
AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhE
Determines the quality-of-protection to use in digest authentication
AuthDigestShmemSize size 1000 sE
The amount of shared memory to allocate for keeping track of clients
AuthFormAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthFormBody fieldname httpd_body dB
The name of a form field carrying the body of the request to attempt on successful login
AuthFormDisableNoStore On|Off Off dB
Disable the CacheControl no-store header on the login page
AuthFormFakeBasicAuth On|Off Off dB
Fake a Basic Authentication header
AuthFormLocation fieldname httpd_location dB
The name of a form field carrying a URL to redirect to on successful login
AuthFormLoginRequiredLocation urldB
The URL of the page to be redirected to should login be required
AuthFormLoginSuccessLocation urldB
The URL of the page to be redirected to should login be successful
AuthFormLogoutLocation uridB
The URL to redirect to after a user has logged out
AuthFormMethod fieldname httpd_method dB
The name of a form field carrying the method of the request to attempt on successful login
AuthFormMimetype fieldname httpd_mimetype dB
The name of a form field carrying the mimetype of the body of the request to attempt on successful login
AuthFormPassword fieldname httpd_password dB
The name of a form field carrying the login password
AuthFormProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthFormSitePassphrase secretdB
Bypass authentication checks for high traffic sites
AuthFormSize size 8192 dB
The largest size of the form in bytes that will be parsed for the login details
AuthFormUsername fieldname httpd_username dB
The name of a form field carrying the login username
AuthGroupFile file-pathdhB
Sets the name of a text file containing the list of user groups for authorization
AuthLDAPAuthorizePrefix prefix AUTHORIZE_ dhE
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritative off|on on dhE
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDN distinguished-namedhE
Optional DN to use in binding to the LDAP server
AuthLDAPBindPassword passworddhE
Password used in conjunction with the bind DN
AuthLDAPCharsetConfig file-pathsE
Language to charset conversion configuration file
AuthLDAPCompareAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization comparisons
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 attribute member uniqueMember +dhE
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDN on|off on dhE
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUser off|on off dhE
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPattern regex substitution (.*) $1 (remote use +dhE
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepth Number 10 dhE
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttribute uiddhE
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDN on|off off dhE
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttribute attribute member uniqueMember +dhE
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClass LdapObjectClass groupOfNames groupO +dhE
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhB
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthName auth-domaindhB
Authorization realm for use in HTTP authentication
AuthnCacheContext directory|server|custom-string directory dB
Specify a context string for use in the cache key
AuthnCacheEnablesB
Enable Authn caching configured anywhere
AuthnCacheProvideFor authn-provider [...]dhB
Specify which authn provider(s) to cache for
AuthnCacheSOCache provider-name[:provider-args]sB
Select socache backend provider to use
AuthnCacheTimeout timeout (seconds) 300 (5 minutes) dhB
Set a timeout for cache entries
<AuthnProviderAlias baseProvider Alias> ... </AuthnProviderAlias>sB
Enclose a group of directives that represent an extension of a base authentication provider and referenced by the specified alias
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Enables a FastCGI application to handle the check_authn authentication hook.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Defines a FastCGI application as a provider for authentication and/or authorization
AuthType None|Basic|Digest|FormdhB
Type of user authentication
AuthUserFile file-pathdhB
Sets the name of a text file containing the list of users and passwords for authentication
AuthzDBDLoginToReferer On|Off Off dE
Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
AuthzDBDQuery querydE
Specify the SQL Query for the required operation
AuthzDBDRedirectQuery querydE
Specify a query to look up a login page for the user
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
Sets the type of database file that is used to store list of user groups
<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> sB
Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
AuthzSendForbiddenOnFailure On|Off Off dhB
Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
BalancerGrowth # 5 svE
Number of additional Balancers that can be added Post-configuration
BalancerInherit On|Off On svE
Inherit ProxyPassed Balancers/Workers from the main server
BalancerMember [balancerurl] url [key=value [key=value ...]]dE
Add a member to a load balancing group
BalancerPersist On|Off Off svE
Attempt to persist changes made by the Balancer Manager across restarts.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
BrotliCompressionMaxInputBlock valuesvE
Maximum input block size
BrotliCompressionQuality value 5 svE
Compression quality
BrotliCompressionWindow value 18 svE
Brotli sliding compression window size
BrotliFilterNote [type] notenamesvE
Places the compression ratio in a note for logging
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
BufferSize integer 131072 svdhE
Maximum size in bytes to buffer by the buffer filter
CacheDefaultExpire seconds 3600 (one hour) svdhE
The default duration to cache a document when no expiry date is specified.
CacheDetailHeader on|off off svdhE
Add an X-Cache-Detail header to the response.
CacheDirLength length 2 svE
The number of characters in subdirectory names
CacheDirLevels levels 2 svE
The number of levels of subdirectories in the cache.
CacheDisable url-string | onsvdhE
Disable caching of specified URLs
CacheEnable cache_type [url-string]svdE
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
CacheHeader on|off off svdhE
Add an X-Cache header to the response.
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 svdhE
Ignore the fact that a response has no Last Modified header.
CacheIgnoreQueryString On|Off Off svE
Ignore query string when caching
CacheIgnoreURLSessionIdentifiers identifier [identifier] ... None svE
Ignore defined session identifiers encoded in the URL when caching
CacheKeyBaseURL URLsvE
Override the base URL of reverse proxied cache keys.
CacheLastModifiedFactor float 0.1 svdhE
The factor used to compute an expiry date based on the LastModified date.
CacheLock on|off off svE
Enable the thundering herd lock.
CacheLockMaxAge integer 5 svE
Set the maximum possible age of a cache lock.
CacheLockPath directory /tmp/mod_cache-lock +svE
Set the lock path directory.
CacheMaxExpire seconds 86400 (one day) svdhE
The maximum time in seconds to cache a document
CacheMaxFileSize bytes 1000000 svdhE
The maximum size (in bytes) of a document to be placed in the cache
CacheMinExpire seconds 0 svdhE
The minimum time in seconds to cache a document
CacheMinFileSize bytes 1 svdhE
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
CacheQuickHandler on|off on svE
Run the cache from the quick handler.
CacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheRoot directorysvE
The directory root under which cache files are stored
CacheSocache type[:args]svE
The shared object cache implementation to use
CacheSocacheMaxSize bytes 102400 svdhE
The maximum size (in bytes) of an entry to be placed in the cache
CacheSocacheMaxTime seconds 86400 svdhE
The maximum time (in seconds) for a document to be placed in the cache
CacheSocacheMinTime seconds 600 svdhE
The minimum time (in seconds) for a document to be placed in the cache
CacheSocacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheSocacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheStaleOnError on|off on svdhE
Serve stale content in place of 5xx responses.
CacheStoreExpired On|Off Off svdhE
Attempt to cache responses that the server reports as expired
CacheStoreNoStore On|Off Off svdhE
Attempt to cache requests or responses that have been marked as no-store.
CacheStorePrivate On|Off Off svdhE
Attempt to cache responses that the server has marked as private
CGIDScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIMapExtension cgi-path .extensiondhC
Technique for locating the interpreter for CGI scripts
CGIPassAuth On|Off Off dhC
Enables passing HTTP authorization headers to scripts as CGI variables
CGIScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIVar variable ruledhC
Controls how some CGI variables are set
CharsetDefault charsetsvdhE
Charset to translate into
CharsetOptions option [option] ... ImplicitAdd svdhE
Configures charset translation behavior
CharsetSourceEnc charsetsvdhE
Source charset of files
CheckBasenameMatch on|off On svdhE
Also match files with differing file name extensions.
CheckCaseOnly on|off Off svdhE
Limits the action of the speling module to case corrections
CheckSpelling on|off Off svdhE
Enables the spelling module
ChrootDir /path/to/directorysB
Directory for apache to run chroot(8) after startup.
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
CookieHTTPOnly on|off off svdhE
Adds the 'HTTPOnly' attribute to the cookie
CookieName token Apache svdhE
Name of the tracking cookie
CookieSameSite None|Lax|StrictsvdhE
Adds the 'SameSite' attribute to the cookie
CookieSecure on|off off svdhE
Adds the 'Secure' attribute to the 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 HTTP Server attempts to switch before dumping core
CustomLog file|pipe format|nickname [env=[!]environment-variable| expr=expression]svB
Sets filename and format of log file
Dav On|Off|provider-name Off dE
Enable WebDAV HTTP methods
DavBasePath root-pathdE
Configure repository root path
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
DavLockDiscovery on|off on svdhE
Enable lock discovery
DavMinTimeout seconds 0 svdE
Minimum amount of time the server holds a lock on a DAV resource
DBDExptime time-in-seconds 300 svE
Keepalive time for idle connections
DBDInitSQL "SQL statement"svE
Execute an SQL statement after connecting to a database
DBDKeep number 2 svE
Maximum sustained number of connections
DBDMax number 10 svE
Maximum number of connections
DBDMin number 1 svE
Minimum number of connections
DBDParams param1=value1[,param2=value2]svE
Parameters for database connection
DBDPersist On|OffsvE
Whether to use persistent connections
DBDPrepareSQL "SQL statement" labelsvE
Define an SQL prepared statement
DBDriver namesvE
Specify an SQL driver
DefaultIcon url-pathsvdhB
Icon to display for files when no specific icon is configured
DefaultLanguage language-tagsvdhB
Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
DefaultRuntimeDir directory-path DEFAULT_REL_RUNTIME +sC
Base directory for the server run-time files
DefaultType media-type|none none svdhC
This directive has no effect other than to emit warnings if the value is not none. In prior versions, DefaultType would specify a default media type to assign to response content for which no other media type configuration could be found.
Define parameter-name [parameter-value]svdC
Define a variable
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
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
DeflateInflateLimitRequestBody valuesvdhE
Maximum size of inflated request bodies
DeflateInflateRatioBurst value 3 svdhE
Maximum number of times the inflation ratio for request bodies can be crossed
DeflateInflateRatioLimit value 200 svdhE
Maximum inflation ratio for request bodies
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] ...dhE
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, sub-directories, and their contents.
DirectoryCheckHandler On|Off Off svdhB
Toggle how this module responds when another handler is configured
DirectoryIndex disabled | local-url [local-url] ... index.html svdhB
List of resources to look for when the client requests a directory
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code off svdhB
Configures an external redirect for directory indexes.
<DirectoryMatch regex> ... </DirectoryMatch>svC
Enclose directives that apply to the contents of file-system directories matching a regular expression.
DirectorySlash On|Off On svdhB
Toggle trailing slash redirects on or off
DocumentRoot directory-path "/usr/local/apache/ +svC
Directory that forms the main document tree visible from the web
DTracePrivileges On|Off Off sX
Determines whether the privileges required by dtrace are enabled.
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
<Else> ... </Else>svdhC
Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
<ElseIf expression> ... </ElseIf>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
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 Off svdhC
Use the kernel sendfile support to deliver files to the client
Error messagesvdhC
Abort configuration parsing with a custom error message
ErrorDocument error-code documentsvdhC
What the server will return to the client in case of an error
ErrorLog file-path|syslog[:[facility][:tag]] logs/error_log (Uni +svC
Location where the server will log errors
ErrorLogFormat [connection|request] formatsvC
Format specification for error log entries
ExamplesvdhX
Demonstration directive to illustrate the Apache module API
ExpiresActive On|Off Off svdhE
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[*] sC
Keep track of extended status information for each request
ExtFilterDefine filtername parameterssE
Define an external filter
ExtFilterOptions option [option] ... NoLogStderr dE
Configure mod_ext_filter options
FallbackResource disabled | local-urlsvdhB
Define a default URL for requests that don't map to a file
FileETag component ... MTime Size svdhC
File attributes used to create the ETag HTTP response header for static files
<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 ...svdhB
Configure the filter chain
FilterDeclare filter-name [type]svdhB
Declare a smart filter
FilterProtocol filter-name [provider-name] proto-flagssvdhB
Deal with correct HTTP protocol handling
FilterProvider filter-name provider-name expressionsvdhB
Register a content filter
FilterTrace filter-name levelsvdB
Get debug/diagnostic information from mod_filter
FlushMaxPipelined number 5 svC
Maximum number of pipelined responses above which they are flushed to the network
FlushMaxThreshold number-of-bytes 65535 svC
Threshold above which pending data are flushed to the network
ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
Action to take if a single acceptable document is not found
ForceType media-type|NonedhC
Forces all matching files to be served with the specified media type in the HTTP Content-Type header field
ForensicLog filename|pipesvE
Sets filename of the forensic log
GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]sB
Sets filename and format of log file
GprofDir /tmp/gprof/|/tmp/gprof/%svC
Directory to write gmon.out profiling data to.
GracefulShutdownTimeout seconds 0 sM
Specify a timeout after which a gracefully shutdown server will exit.
Group unix-group #-1 sB
Group under which the server will answer requests
H2CopyFiles on|off off svdhE
Determine file handling in responses
H2Direct on|off on for h2c, off for +svE
H2 Direct Protocol Switch
H2EarlyHint name valuesvdhE
Add a response header to be picked up in 103 Early Hints
H2EarlyHints on|off off svE
Determine sending of 103 status codes
H2MaxDataFrameLen n 0 svE
Maximum bytes inside a single HTTP/2 DATA frame
H2MaxHeaderBlockLen n 0 svE
Maximum size of response headers
H2MaxSessionStreams n 100 svE
Maximum number of active streams per HTTP/2 session.
H2MaxWorkerIdleSeconds n 600 sE
Maximum number of seconds h2 workers remain idle until shut down.
H2MaxWorkers nsE
Maximum number of worker threads to use per child process.
H2MinWorkers nsE
Minimal number of worker threads to use per child process.
H2ModernTLSOnly on|off on svE
Require HTTP/2 connections to be "modern TLS" only
H2OutputBuffering on|off on svE
Determine buffering behaviour of output
H2Padding numbits 0 svE
Determine the range of padding bytes added to payload frames
H2ProxyRequests on|off off svE
En-/Disable forward proxy requests via HTTP/2
H2Push on|off on svdhE
H2 Server Push Switch
H2PushDiarySize n 256 svE
H2 Server Push Diary Size
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 svE
H2 Server Push Priority
H2PushResource [add] path [critical]svdhE
Declares resources for early pushing to the client
H2SerializeHeaders on|off off svE
Serialize Request/Response Processing Switch
H2StreamMaxMemSize bytes 65536 svE
Maximum amount of output data buffered per stream.
H2StreamTimeout time-interval[s]svdE
Maximum time waiting when sending/receiving data to stream processing
H2TLSCoolDownSecs seconds 1 svE
Configure the number of seconds of idle time on TLS before shrinking writes
H2TLSWarmUpSize amount 1048576 svE
Configure the number of bytes on TLS connection before doing max writes
H2Upgrade on|off on for h2c, off for +svdhE
H2 Upgrade Protocol Switch
H2WebSockets on|off off svE
En-/Disable WebSockets via HTTP/2
H2WindowSize bytes 65535 svE
Size of Stream Window for upstream data.
Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP response headers
HeaderName filenamesvdhB
Name of the file that will be inserted at the top of the index listing
HeartbeatAddress addr:portsX
Multicast address for heartbeat packets
HeartbeatListen addr:portsX
multicast address to listen for incoming heartbeat requests
HeartbeatMaxServers number-of-servers 10 sX
Specifies the maximum number of servers that will be sending heartbeat requests to this server
HeartbeatStorage file-path logs/hb.dat sX
Path to store heartbeat data when using flat-file storage
HeartbeatStorage file-path logs/hb.dat sX
Path to read heartbeat data
HostnameLookups On|Off|Double Off svdC
Enables DNS lookups on client IP addresses
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +svC
Modify restrictions on HTTP Request Messages
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
<If expression> ... </If>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime
<IfDefine [!]parameter-name> ... </IfDefine>svdhC
Encloses directives that will be processed only if a test is true at startup
<IfDirective [!]directive-name> ... </IfDirective>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific directive
<IfFile [!]filename> ... </IfFile>svdhC
Encloses directives that will be processed only if file exists at startup
<IfModule [!]module-file|module-identifier> ... </IfModule>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific module
<IfSection [!]section-name> ... </IfSection>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific section directive
<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|unformatted formatted svdhB
Action if no coordinates are given when calling an imagemap
Include file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IncludeOptional file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IndexHeadInsert "markup ..."svdhB
Inserts text in the HEAD section of an index page.
IndexIgnore file [file] ... "." svdhB
Adds to the list of files to hide when listing a directory
IndexIgnoreReset ON|OFFsvdhB
Empties 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
InputSed sed-commanddhX
Sed command to filter request data (typically POST data)
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 num[ms] 5 svC
Amount of time the server will wait for subsequent requests on a persistent connection
KeptBodySize maximum size in bytes 0 dB
Keep the request body instead of discarding it up to the specified maximum size, for potential use by filters such as mod_include.
LanguagePriority MIME-lang [MIME-lang] ...svdhB
The precedence 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
LDAPConnectionPoolTTL n -1 svE
Discard backend connections that have been sitting in the connection pool too long
LDAPConnectionTimeout secondssE
Specifies the socket connection timeout in seconds
LDAPLibraryDebug 7sE
Enable debugging in the LDAP SDK
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
LDAPReferralHopLimit numberdhE
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferrals On|Off|default On dhE
Enable referral chasing during queries to the LDAP server.
LDAPRetries number-of-retries 3 sE
Configures the number of LDAP server retries.
LDAPRetryDelay seconds 0 sE
Configures the delay between LDAP server retries.
LDAPSharedCacheFile directory-path/filenamesE
Sets the shared memory cache file
LDAPSharedCacheSize bytes 500000 sE
Size in bytes of the shared-memory cache
LDAPTimeout seconds 60 sE
Specifies the timeout for LDAP search and bind operations, in seconds
LDAPTrustedClientCert type directory-path/filename/nickname [password]dhE
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 typesvE
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>dhC
Restrict enclosed access controls to only certain HTTP methods
<LimitExcept method [method] ... > ... </LimitExcept>dhC
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 1073741824 svdhC
Restricts the total size of the HTTP request body sent from the client
LimitRequestFields number 100 svC
Limits the number of HTTP request header fields that will be accepted from the client
LimitRequestFieldSize bytes 8190 svC
Limits the size of the HTTP request header allowed from the client
LimitRequestLine bytes 8190 svC
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:]portnumber [protocol]sM
IP addresses and ports that the server listens to
ListenBackLog backlog 511 sM
Maximum length of the queue of pending connections
ListenCoresBucketsRatio ratio 0 (disabled) sM
Ratio between the number of CPU cores (online) and the number of listeners' buckets
LoadFile filename [filename] ...svE
Link in the named object file or library
LoadModule module filenamesvE
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
LogFormat format|nickname [nickname] "%h %l %u %t \"%r\" +svB
Describes a format for use in a log file
LogIOTrackTTFB ON|OFF OFF svdhE
Enable tracking of time to first byte (TTFB)
LogLevel [module:]level [module:level] ... warn svdC
Controls the verbosity of the ErrorLog
LogMessage message [hook=hook] [expr=expression] dX
Log user-defined message to error log
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Plug an authorization provider function into mod_authz_core
LuaCodeCache stat|forever|never stat svdhE
Configure the compiled code cache.
LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the access_checker phase of request processing
LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the check_user_id phase of request processing
LuaHookFixups /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the fixups phase of a request processing
LuaHookInsertFilter /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the insert_filter phase of request processing
LuaHookLog /path/to/lua/script.lua log_function_namesvdhE
Provide a hook for the access log phase of a request processing
LuaHookMapToStorage /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslate /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]svE
Provide a hook for the translate name phase of request processing
LuaHookTypeChecker /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the type_checker phase of request processing
LuaInherit none|parent-first|parent-last parent-first svdhE
Controls how parent configuration sections are merged into children
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content input filtering
LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]svdhE
Map a path to a lua handler
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content output filtering
LuaPackageCPath /path/to/include/?.soasvdhE
Add a directory to lua's package.cpath
LuaPackagePath /path/to/include/?.luasvdhE
Add a directory to lua's package.path
LuaQuickHandler /path/to/script.lua hook_function_namesvE
Provide a hook for the quick handler of request processing
LuaRoot /path/to/a/directorysvdhE
Specify the base path for resolving relative paths for mod_lua directives
LuaScope once|request|conn|thread|server [min] [max] once svdhE
One of once, request, conn, thread -- default is once
<Macro name [par1 .. parN]> ... </Macro>svdB
Define a configuration file macro
MaxConnectionsPerChild number 0 sM
Limit on the number of connections that an individual child server will handle during its life
MaxKeepAliveRequests number 100 svC
Number of requests allowed on a persistent connection
MaxMemFree KBytes 2048 sM
Maximum amount of memory that the main allocator is allowed to hold without calling free()
MaxRangeOverlaps default | unlimited | none | number-of-ranges 20 svdC
Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
MaxRangeReversals default | unlimited | none | number-of-ranges 20 svdC
Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
MaxRanges default | unlimited | none | number-of-ranges 200 svdC
Number of ranges allowed before returning the complete resource
MaxRequestWorkers numbersM
Maximum number of connections that will be processed simultaneously
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
MDActivationDelay durationsX
How long to delay activation of new certificates
MDBaseServer on|off off sX
Control if base server may be managed or only virtual hosts.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sX
Type of ACME challenge used to prove domain ownership.
MDCertificateAgreement acceptedsX
You confirm that you accepted the Terms of Service of the Certificate Authority.
MDCertificateAuthority url letsencrypt sX
The URL(s) of the ACME Certificate Authority to use.
MDCertificateCheck name urlsX
Set name and URL pattern for a certificate monitoring site.
MDCertificateFile path-to-pem-filesX
Specify a static certificate file for the MD.
MDCertificateKeyFile path-to-filesX
Specify a static private key for for the static cerrtificate.
MDCertificateMonitor name url crt.sh https://crt. +sX
The URL of a certificate log monitor.
MDCertificateProtocol protocol ACME sX
The protocol to use with the Certificate Authority.
MDCertificateStatus on|off on sX
Exposes public certificate information in JSON.
MDChallengeDns01 path-to-commandsX
Set the command for setup/teardown of dns-01 challenges
MDChallengeDns01Version 1|2 1 sX
Set the type of arguments to call MDChallengeDns01 with
MDCheckInterval duration 12h sX
Determines how often certificates are checked
MDContactEmail addresssX
Email address used for account registration
MDDriveMode always|auto|manual auto sX
former name of MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sX
Set the external account binding keyid and hmac values to use at CA
MDHttpProxy urlsX
Define a proxy for outgoing connections.
MDMatchNames all|servernames all sX
Determines how DNS names are matched to vhosts
MDMember hostnamesX
Additional hostname for the managed domain.
MDMembers auto|manual auto sX
Control if the alias domain names are automatically added.
MDMessageCmd path-to-cmd optional-argssX
Handle events for Manage Domains
MDMustStaple on|off off sX
Control if new certificates carry the OCSP Must Staple flag.
MDNotifyCmd path [ args ]sX
Run a program when a Managed Domain is ready.
MDomain dns-name [ other-dns-name... ] [auto|manual]sX
Define list of domain names that belong to one group.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sX
Container for directives applied to the same managed domains.
MDPortMap map1 [ map2 ] http:80 https:443 sX
Map external to internal ports for domain ownership verification.
MDPrivateKeys type [ params... ] RSA 2048 sX
Set type and size of the private keys generated.
MDProfile namesX
Use a specific ACME profile from the CA
MDProfileMandatory on|off off sX
Control if an MDProfile is mandatory.
MDRenewMode always|auto|manual auto sX
Controls if certificates shall be renewed.
MDRenewWindow duration 33% sX
Control when a certificate will be renewed.
MDRequireHttps off|temporary|permanent off sX
Redirects http: traffic to https: for Managed Domains.
MDRetryDelay duration 5s sX
Time length for first retry, doubled on every consecutive error.
MDRetryFailover number 13 sX
The number of errors before a failover to another CA is triggered
MDServerStatus on|off on sX
Control if Managed Domain information is added to server-status.
MDStapleOthers on|off on sX
Enable stapling for certificates not managed by mod_md.
MDStapling on|off off sX
Enable stapling for all or a particular MDomain.
MDStaplingKeepResponse duration 7d sX
Controls when old responses should be removed.
MDStaplingRenewWindow duration 33% sX
Control when the stapling responses will be renewed.
MDStoreDir path md sX
Path on the local file system to store the Managed Domains data.
MDStoreLocks on|off|duration off sX
Configure locking of store for updates
MDWarnWindow duration 10% sX
Define the time window when you want to be warned about an expiring certificate.
MemcacheConnTTL num[units] 15s svE
Keepalive time for idle connections
MergeSlashes ON|OFF ON svC
Controls whether the server merges consecutive slashes in URLs.
MergeTrailers [on|off] off svC
Determines whether trailers are merged into headers
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 containing 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
ModemStandard V.21|V.26bis|V.32|V.34|V.92dX
Modem standard to simulate
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
Mutex mechanism [default|mutex-name] ... [OmitPID] default sC
Configures mutex mechanism and lock file directory for all or specified mutexes
NameVirtualHost addr[:port]sC
DEPRECATED: Designates an IP address for name-virtual hosting
NoProxy host [host] ...svE
Hosts, domains, or networks that will be connected to directly
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] ... FollowSymlinks svdhC
Configures what features are available in a particular directory
Order ordering Deny,Allow dhE
Controls the default access state and the order in which Allow and Deny are evaluated.
OutputSed sed-commanddhX
Sed command for filtering response content
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
PrivilegesMode FAST|SECURE|SELECTIVE FAST svdX
Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Protocol protocolsvC
Protocol for a listening socket
ProtocolEcho On|Off Off svX
Turn the echo server on or off
Protocols protocol ... http/1.1 svC
Protocols available for a server/virtual host
ProtocolsHonorOrder On|Off On svC
Determines if order of Protocols determines precedence during negotiation
<Proxy wildcard-url> ...</Proxy>svE
Container for directives applied to proxied resources
Proxy100Continue Off|On On svdE
Forward 100-continue expectation to the origin server
ProxyAddHeaders Off|On On svdE
Add proxy information in X-Forwarded-* headers
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 Off|On [code ...] Off svdE
Override error pages for proxied content
ProxyExpressDBMFile pathnamesvE
Pathname to DBM file.
ProxyExpressDBMType type default svE
DBM type of file.
ProxyExpressEnable on|off off svE
Enable the module functionality.
ProxyFCGIBackendType FPM|GENERIC FPM svdhE
Specify the type of backend FastCGI application
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]svdhE
Allow variables sent to FastCGI servers to be fixed up
ProxyFtpDirCharset character_set ISO-8859-1 svdE
Define the character set for proxied FTP listings
ProxyFtpEscapeWildcards on|off on svdE
Whether wildcards in requested filenames are escaped when sent to the FTP server
ProxyFtpListOnWildcard on|off on svdE
Whether wildcards in requested filenames trigger a file listing
ProxyHCExpr name {ap_expr expression}svE
Creates a named condition expression to use to determine health of the backend based on its response
ProxyHCTemplate name parameter=setting [...]svE
Creates a named template for setting various health check parameters
ProxyHCTPsize size 16 sE
Sets the total server-wide size of the threadpool used for the health check workers
ProxyHTMLBufSize bytes 8192 svdB
Sets the buffer size increment for buffering inline scripts and stylesheets.
ProxyHTMLCharsetOut Charset | *svdB
Specify a charset for mod_proxy_html output.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
svdB
Sets an HTML or XHTML document type declaration.
ProxyHTMLEnable On|Off Off svdB
Turns the proxy_html filter on or off.
ProxyHTMLEvents attribute [attribute ...]svdB
Specify attributes to treat as scripting events.
ProxyHTMLExtended On|Off Off svdB
Determines whether to fix links in inline scripts, stylesheets, and scripting events.
ProxyHTMLFixups [lowercase] [dospath] [reset]svdB
Fixes for simple HTML errors.
ProxyHTMLInterp On|Off Off svdB
Enables per-request interpolation of ProxyHTMLURLMap rules.
ProxyHTMLLinks element attribute [attribute2 ...]svdB
Specify HTML elements that have URL attributes to be rewritten.
ProxyHTMLMeta On|Off Off svdB
Turns on or off extra pre-parsing of metadata in HTML <head> sections.
ProxyHTMLStripComments On|Off Off svdB
Determines whether to strip HTML comments.
ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]svdB
Defines a rule to rewrite HTML links
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 -1 svE
Maximum number of proxies that a request can be forwarded through
ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] [noquery]svdE
Maps remote servers into the local server URL-space
ProxyPassInherit On|Off On svE
Inherit ProxyPass directives defined from the main server
ProxyPassInterpolateEnv On|Off Off svdE
Enable Environment Variable interpolation in Reverse Proxy configurations
ProxyPassMatch [regex] !|url [key=value [key=value ...]]svdE
Maps remote servers into the local server URL-space using regular expressions
ProxyPassReverse [path] url [interpolate]svdE
Adjusts the URL in HTTP response headers sent from a reverse proxied server
ProxyPassReverseCookieDomain internal-domain public-domain [interpolate]svdE
Adjusts the Domain string in Set-Cookie headers from a reverse- proxied server
ProxyPassReverseCookiePath internal-path public-path [interpolate]svdE
Adjusts the Path string in Set-Cookie headers from a reverse- proxied server
ProxyPreserveHost On|Off Off svdE
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-server [username:password]svE
Remote proxy used to handle certain requests
ProxyRemoteMatch regex remote-server [username:password]svE
Remote proxy used to handle requests matched by regular expressions
ProxyRequests On|Off Off svE
Enables forward (standard) proxy requests
ProxySCGIInternalRedirect On|Off|Headername On svdE
Enable or disable internal redirect responses from the backend
ProxySCGISendfile On|Off|Headername Off svdE
Enable evaluation of X-Sendfile pseudo response header
ProxySet url key=value [key=value ...]svdE
Set various Proxy balancer or member parameters
ProxySourceAddress addresssvE
Set local IP address for outgoing proxy connections
ProxyStatus Off|On|Full Off svE
Show Proxy LoadBalancer status in mod_status
ProxyTimeout secondssvE
Network timeout for proxied requests
ProxyVia On|Off|Full|Block Off svE
Information provided in the Via HTTP response header for proxied requests
ProxyWebsocketFallbackToProxyHttp On|Off On svE
Instructs this module to let mod_proxy_http handle the request
QualifyRedirectURL On|Off Off svdC
Controls whether the REDIRECT_URL environment variable is fully qualified
ReadBufferSize bytes 8192 svdC
Size of the buffers used to read data
ReadmeName filenamesvdhB
Name of the file that will be inserted at the end of the index listing
ReceiveBufferSize bytes 0 sM
TCP receive buffer size
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
RedirectRelative On|Off Off svdB
Allows relative redirect targets.
RedirectTemp URL-path URLsvdhB
Sends an external temporary redirect asking the client to fetch a different URL
RedisConnPoolTTL num[units] 15s svE
TTL used for the connection pool with the Redis server(s)
RedisTimeout num[units] 5s svE
R/W timeout used for the connection with the Redis server(s)
ReflectorHeader inputheader [outputheader]svdhB
Reflect an input header to the output headers
RegexDefaultOptions [none] [+|-]option [[+|-]option] ... DOTALL DOLLAR_ENDON +sC
Allow to configure global/default options for regexes
RegisterHttpMethod method [method [...]]sC
Register non-standard HTTP methods
RemoteIPHeader header-fieldsvB
Declare the header field which should be parsed for useragent IP addresses
RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPInternalProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPProxiesHeader HeaderFieldNamesvB
Declare the header field which will record all intermediate IP addresses
RemoteIPProxyProtocol On|OffsvB
Enable or disable PROXY protocol handling
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]svB
Disable processing of PROXY header for certain hosts or networks
RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPTrustedProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
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 add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP request headers
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate] handshake=0 header= +svE
Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Require [not] entity-name [entity-name] ...dhB
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll> ... </RequireAll>dhB
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny> ... </RequireAny>dhB
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone> ... </RequireNone>dhB
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
RewriteBase URL-pathdhE
Sets the base URL for per-directory rewrites
RewriteCond TestString CondPattern [flags]svdhE
Defines a condition under which rewriting will take place
RewriteEngine on|off off svdhE
Enables or disables runtime rewriting engine
RewriteMap MapName MapType:MapSource [MapTypeOptions] svE
Defines a mapping function for key-lookup
RewriteOptions OptionssvdhE
Sets some special options for the rewrite engine
RewriteRule Pattern Substitution [flags]svdhE
Defines rules for the rewriting engine
RLimitCPU seconds|max [seconds|max]svdhC
Limits the CPU consumption of processes launched by Apache httpd children
RLimitMEM bytes|max [bytes|max]svdhC
Limits the memory consumption of processes launched by Apache httpd children
RLimitNPROC number|max [number|max]svdhC
Limits the number of processes that can be launched by processes launched by Apache httpd children
Satisfy Any|All All dhE
Interaction between host-level access control and user authentication
ScoreBoardFile file-path logs/apache_runtime +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-pathsvdB
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 cgisock sB
The filename prefix 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
SeeRequestTail On|Off Off sC
Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
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 [scheme://]domain-name|ip-address[: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
Session On|Off Off svdhE
Enables a session for the current directory or location
SessionCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session
SessionCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session
SessionCookieRemove On|Off Off svdhE
Control for whether session cookies should be removed from incoming HTTP headers
SessionCryptoCipher name aes256 svdhX
The crypto cipher to be used to encrypt the session
SessionCryptoDriver name [param[=value]]sX
The crypto driver to be used to encrypt the session
SessionCryptoPassphrase secret [ secret ... ] svdhX
The key used to encrypt the session
SessionCryptoPassphraseFile filenamesvdX
File containing keys used to encrypt the session
SessionDBDCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session ID
SessionDBDCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session ID
SessionDBDCookieRemove On|Off On svdhE
Control for whether session ID cookies should be removed from incoming HTTP headers
SessionDBDDeleteLabel label deletesession svdhE
The SQL query to use to remove sessions from the database
SessionDBDInsertLabel label insertsession svdhE
The SQL query to use to insert sessions into the database
SessionDBDPerUser On|Off Off svdhE
Enable a per user session
SessionDBDSelectLabel label selectsession svdhE
The SQL query to use to select sessions from the database
SessionDBDUpdateLabel label updatesession svdhE
The SQL query to use to update existing sessions in the database
SessionEnv On|Off Off svdhE
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionExclude pathsvdhE
Define URL prefixes for which a session is ignored
SessionExpiryUpdateInterval interval 0 (always update) svdhE
Define the number of seconds a session's expiry may change without the session being updated
SessionHeader headersvdhE
Import session updates from a given HTTP response header
SessionInclude pathsvdhE
Define URL prefixes for which a session is valid
SessionMaxAge maxage 0 svdhE
Define a maximum age in seconds for a session
SetEnv env-variable [value]svdhB
Sets environment variables
SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on attributes of the request
SetEnvIfExpr expr [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on an ap_expr expression
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|none|expressionsvdhC
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
SSIETag on|off off dhB
Controls whether ETags are generated by the server.
SSILastModified on|off off dhB
Controls whether Last-Modified headers are generated by the server.
SSILegacyExprParser on|off off dhB
Enable compatibility mode for conditional expressions.
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
SSLCARevocationCheck chain|leaf|none [flags ...] none svE
Enable CRL-based revocation checking
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-path|certidsvE
Server PEM-encoded X.509 certificate data file or token identifier
SSLCertificateKeyFile file-path|keyidsvE
Server PEM-encoded private key file
SSLCipherSuite [protocol] cipher-spec DEFAULT (depends on +svdhE
Cipher Suite available for negotiation in SSL handshake
SSLCompression on|off off svE
Enable compression on the SSL level
SSLCryptoDevice engine builtin sE
Enable use of a cryptographic hardware accelerator
SSLEngine on|off|optional off svE
SSL Engine Operation Switch
SSLFIPS on|off off sE
SSL FIPS mode Switch
SSLHonorCipherOrder on|off off svE
Option to prefer the server's cipher preference order
SSLInsecureRenegotiation on|off off svE
Option to enable support for insecure renegotiation
SSLOCSPDefaultResponder urisvE
Set the default responder URI for OCSP validation
SSLOCSPEnable on|leaf|off off svE
Enable OCSP validation of the client certificate chain
SSLOCSPNoverify on|off off svE
skip the OCSP responder certificates verification
SSLOCSPOverrideResponder on|off off svE
Force use of the default responder URI for OCSP validation
SSLOCSPProxyURL urlsvE
Proxy URL to use for OCSP requests
SSLOCSPResponderCertificateFile filesvE
Set of trusted PEM encoded OCSP responder certificates
SSLOCSPResponderTimeout seconds 10 svE
Timeout for OCSP queries
SSLOCSPResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP responses
SSLOCSPResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP response validation
SSLOCSPUseRequestNonce on|off on svE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd command-name command-valuesvE
Configure OpenSSL parameters through its SSL_CONF API
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 -SSLv3 (up to 2 +svE
Configure usable SSL/TLS protocol versions
SSLProxyCACertificateFile file-pathsvpE
File of concatenated PEM-encoded CA Certificates for Remote Server Auth
SSLProxyCACertificatePath directory-pathsvpE
Directory of PEM-encoded CA Certificates for Remote Server Auth
SSLProxyCARevocationCheck chain|leaf|none none svpE
Enable CRL-based revocation checking for Remote Server Auth
SSLProxyCARevocationFile file-pathsvpE
File of concatenated PEM-encoded CA CRLs for Remote Server Auth
SSLProxyCARevocationPath directory-pathsvpE
Directory of PEM-encoded CA CRLs for Remote Server Auth
SSLProxyCheckPeerCN on|off on svpE
Whether to check the remote server certificate's CN field
SSLProxyCheckPeerExpire on|off on svpE
Whether to check if remote server certificate is expired
SSLProxyCheckPeerName on|off on svpE
Configure host name checking for remote server certificates
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +svpE
Cipher Suite available for negotiation in SSL proxy handshake
SSLProxyEngine on|off off svpE
SSL Proxy Engine Operation Switch
SSLProxyMachineCertificateChainFile filenamesvpE
File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
SSLProxyMachineCertificateFile filenamesvpE
File of concatenated PEM-encoded client certificates and keys to be used by the proxy
SSLProxyMachineCertificatePath directorysvpE
Directory of PEM-encoded client certificates and keys to be used by the proxy
SSLProxyProtocol [+|-]protocol ... all -SSLv3 (up to 2 +svpE
Configure usable SSL protocol flavors for proxy usage
SSLProxyVerify level none svpE
Type of remote server Certificate verification
SSLProxyVerifyDepth number 1 svpE
Maximum depth of CA Certificates in Remote Server Certificate verification
SSLRandomSeed context source [bytes]sE
Pseudo Random Number Generator (PRNG) seeding source
SSLRenegBufferSize bytes 131072 dhE
Set the size for the SSL renegotiation buffer
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
SSLSessionTicketKeyFile file-pathsvE
Persistent encryption/decryption key for TLS session tickets
SSLSessionTickets on|off on svE
Enable or disable use of TLS session tickets
SSLSRPUnknownUserSeed secret-stringsvE
SRP unknown user seed
SSLSRPVerifierFile file-pathsvE
Path to SRP verifier file
SSLStaplingCache typesE
Configures the OCSP stapling cache
SSLStaplingErrorCacheTimeout seconds 600 svE
Number of seconds before expiring invalid responses in the OCSP stapling cache
SSLStaplingFakeTryLater on|off on svE
Synthesize "tryLater" responses for failed OCSP stapling queries
SSLStaplingForceURL urisvE
Override the OCSP responder URI specified in the certificate's AIA extension
SSLStaplingResponderTimeout seconds 10 svE
Timeout for OCSP stapling queries
SSLStaplingResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP stapling responses
SSLStaplingResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP stapling response validation
SSLStaplingReturnResponderErrors on|off on svE
Pass stapling related OCSP errors on to client
SSLStaplingStandardCacheTimeout seconds 3600 svE
Number of seconds before expiring responses in the OCSP stapling cache
SSLStrictSNIVHostCheck on|off off svE
Whether to allow non-SNI clients to access a name-based virtual host.
SSLUserName varnamesdhE
Variable name to determine user name
SSLUseStapling on|off off svE
Enable stapling of OCSP responses in the TLS handshake
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
StrictHostCheck ON|OFF OFF svC
Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Substitute s/pattern/substitution/[infq]dhE
Pattern to filter the response content
SubstituteInheritBefore on|off off dhE
Change the merge order of inherited patterns
SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G) 1m dhE
Set the maximum line size
Suexec On|OffsB
Enable or disable the suEXEC feature
SuexecUserGroup User GroupsvE
User and group for CGI programs to run as
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 60 svC
Amount of time the server will wait for certain events before failing a request
TraceEnable [on|off|extended] on svC
Determines the behavior on TRACE requests
TransferLog file|pipesvB
Specify location of a log file
TypesConfig file-path conf/mime.types sB
The location of the mime.types file
UNCList hostname [hostname...]sC
Controls what UNC host names can be accessed by the server
UnDefine parameter-namesC
Undefine the existence of a variable
UndefMacro namesvdB
Undefine a macro
UnsetEnv env-variable [env-variable] ...svdhB
Removes variables from the environment
Use name [value1 ... valueN] svdB
Use a macro
UseCanonicalName On|Off|DNS Off svdC
Configures how the server determines its own name and port
UseCanonicalPhysicalPort On|Off Off svdC
Configures how the server determines its own port
User unix-userid #-1 sB
The userid under which the server will answer requests
UserDir directory-filename [directory-filename] ... svB
Location of the user-specific directories
VHostCGIMode On|Off|Secure On vX
Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to subprocesses created by a virtual host.
VHostGroup unix-groupidvX
Sets the Group ID under which a virtual host runs.
VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to a virtual host.
VHostSecure On|Off On vX
Determines whether the server runs with enhanced security for the virtualhost.
VHostUser unix-useridvX
Sets the User ID under which a virtual host runs.
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
WatchdogInterval time-interval[s] 1 sB
Watchdog interval in seconds
XBitHack on|off|full off svdhB
Parse SSI directives in files with the execute bit set
xml2EncAlias charset alias [alias ...]sB
Recognise Aliases for encoding values
xml2EncDefault namesvdhB
Sets a default encoding to assume when absolutely no information can be automatically detected
xml2StartParse element [element ...]svdhB
Advise the parser to skip leading junk.

Available Languages:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_env.html.ko.euc-kr0000664000175100017510000002363514743132254021736 0ustar covenercovener mod_env - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_env

ֽ ƴմϴ. ֱٿ ϼ.
:CGI ũƮ SSI ȯ溯 Ѵ
:Base
:env_module
ҽ:mod_env.c

CGI ũƮ SSI ȯ溯 Ѵ. ȯ溯 ִ. ƴϸ ߿ ȯ溯 ϰ ִ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_env.html.tr.utf80000664000175100017510000002734614743132254021455 0ustar covenercovener mod_env - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_env

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:CGI betiklerine ve SSI sayfalarına aktarılan değişkenlere müdahale etmek için kullanılır.
Durum:Temel
Modül Betimleyici:env_module
Kaynak Dosyası:mod_env.c

Özet

Bu modül Apache HTTP Sunucusunun çeşitli modülleri tarafınan kullanılan dahili ortam değişkenlerime müdahale etmeyi mümkün kılar. bu değişkenler ayrıca, CGI betiklerine yerel ortam değişkenleri olarak sunulur ve SSI sayfalarında da kullanılabilir. Ortam değişkenleri httpd süreci başlatılırken kabuktan aktarılabilir. Bundan başka, yapılandırma sürecinde tanımlı veya tanımsız yapılabilirler.

Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

PassEnv Yönergesi

Açıklama:Ortam değişkenlerini kabuktan aktarır.
Sözdizimi:PassEnv ortam-değişkeni [ortam-değişkeni] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_env

Dahili ortam değişkenleri olarak kullanılmak üzere sistem ortam değişkenlerini içeri aktarmak için kullanılır. Bunlar daha sonra Apache HTTP Sunucusunun modüllerinden kullanılabilir, CGI betiklerine ve SSI sayfalarında aktarılabilir. Değerler httpd süreci başlatılırken kabuğun işletim sistemi ortamından gelir.

Örnek

PassEnv LD_LIBRARY_PATH

top

SetEnv Yönergesi

Açıklama:Ortam değişkenlerini tanımlar.
Sözdizimi:SetEnv ortam-değişkeni [değer]
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_env

CGI betiklerine ve SSI sayfalarına aktarılmak ve Apache HTTP Sunucusu modüllerinde kullanılmak üzere bir dahili ortam değişkeni tanımlanmasını sağlar.

SetEnv SPECIAL_PATH /foo/bin

Bir değer belirtilmezse değişkene boş dizgi atanır.

Bu yönerge tarafından atanan dahili ortam değişkenleri, en başta işleme sokulan, ereşem denetimi, URI-dosya ismi eşleştirmesi gibi istek işleme yönergelerinden sonra işleme sokulur. Eğer atadığınız ortam değişkeni, bir RewriteRule yönergesindeki gibi erken işlem aşamalarına girdi sağlıyorsa, bu durumda ortam değişkenini SetEnvIf ile atamalısınız.

Ayrıca bakınız:

top

UnsetEnv Yönergesi

Açıklama:Ortamdaki değişkenleri tanımsız hale getirir.
Sözdizimi:UnsetEnv ortam-değişkeni [ortam-değişkeni] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_env

CGI betiklerine ve SSI sayfalarına bir daha aktarılmamak üzere bir dahili ortam değişkenini siler.

UnsetEnv LD_LIBRARY_PATH

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_expires.html.ja.utf80000664000175100017510000004445314743132254022307 0ustar covenercovener mod_expires - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_expires

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:ユーザの指定した基準に基づいた ExpiresCache-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 ディレクティブを 使うことができます。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

代替期間指定構文

ExpiresDefault ディレクティブと ExpiresByType ディレクティブは 以下のより読み易い構文を使って定義することができます:

ExpiresDefault "<base> [plus] {<num> <type>}*"
ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"

<base> は以下のどれかです:

plus キーワードは省略可能です。<num> は (atoi() が受け付ける) 整数値、 <type> は以下のどれかです:

例えば、以下のディレクティブはどれもデフォルトで文書がアクセスの 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

このディレクティブは対応するドキュメントの領域で ExpiresCache-Controlヘッダを 有効にするか無効にするかを決めます。 (例えば、.htaccess ファイルではそのディレクトリの 文書のみに適用されるということです。) Off に 設定された場合は対応領域でそれらのヘッダは 生成されません (.htaccess がサーバ設定ファイルの設定を 上書きする、というような下位レベルでの上書きがされていなければ)。 On に設定されていれば、ヘッダは ExpiresByType ディレクティブと ExpiresDefault ディレクティブ の基準に従って文書にヘッダを追加します (各ディレクティブ参照)。

このディレクティブは ExpiresCache-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 ディレクティブによって タイプ毎に上書きすることができます。引数の構文はそのディレクティブの 説明を参照してください。また、代替構文も 参照してください。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_expires.html.ko.euc-kr0000664000175100017510000003612314743132254022621 0ustar covenercovener mod_expires - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_expires

ֽ ƴմϴ. ֱٿ ϼ.
:ڰ ؿ 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 ) ִ.

Support Apache!

þ

Bugfix checklist

top

ٸ

ExpiresDefault ExpiresByType þ б ִ:

ExpiresDefault "<base> [plus] {<num> <type>}*"
ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"

<base> ϳ̴:

plus Ű  ȴ. <num> [atoi() ִ] ̴. <type> ϳ̴:

, δ ⺻ ӵ 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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.es0000664000175100017510000060077715032765673022134 0ustar covenercovener Guía Rápida de Referencia de Directivas - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4 > Módulos

Guía Rápida de Referencia de Directivas

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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 carácter 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  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
sserver config
vvirtual host
ddirectory
h.htaccess
psección de proxy
CCore
MMPM
BBase
EExtensión
XExperimental
TExterno
AcceptFilter protocol accept_filtersC
Configura mejoras para un Protocolo de Escucha de Sockets
AcceptPathInfo On|Off|Default Default svdhC
Los recursos aceptan información sobre su ruta
AccessFileName filename [filename] ... .htaccess svC
Nombre del fichero distribuido de configuración
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 encoding 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 language-tag 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...] media-type [media-type] ...svdhB
assigns an output filter to a particular media-type
AddType media-type extension [extension] ...svdhB
Maps the given filename extensions onto the specified content type
Alias [URL-path] file-path|directory-pathsvdB
Maps URLs to filesystem locations
AliasMatch regex file-path|directory-pathsvB
Maps URLs to filesystem locations using regular expressions
AliasPreservePath OFF|ON OFF svdB
Map the full path after the alias in a location.
Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
Controls which hosts can access an area of the server
AllowCONNECT port[-port] [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
AllowMethods reset|HTTP-method [HTTP-method]... reset dX
Restrict access to the listed HTTP methods
AllowOverride All|None|directive-type [directive-type] ... None (2.3.9 and lat +dC
Types of directives that are allowed in .htaccess files
AllowOverrideList None|directive [directive-type] ... None dC
Individual 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
AsyncRequestWorkerFactor factorsM
Limit concurrent connections per process
AuthBasicAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthBasicFake off|username [password]dhB
Fake basic authentication using the given expressions for username and password
AuthBasicProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthBasicUseDigestAlgorithm MD5|Off Off dhB
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBDUserPWQuery querydE
SQL query to look up a password for a user
AuthDBDUserRealmQuery querydE
SQL query to look up a password hash for a user and realm.
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
AuthDigestAlgorithm MD5|MD5-sess MD5 dhE
Selects the algorithm used to calculate the challenge and response hashes in digest authentication
AuthDigestDomain URI [URI] ...dhE
URIs that are in the same protection space for digest authentication
AuthDigestNonceLifetime seconds 300 dhE
How long the server nonce is valid
AuthDigestProvider provider-name [provider-name] ... file dhE
Sets the authentication provider(s) for this location
AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhE
Determines the quality-of-protection to use in digest authentication
AuthDigestShmemSize size 1000 sE
The amount of shared memory to allocate for keeping track of clients
AuthFormAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthFormBody fieldname httpd_body dB
The name of a form field carrying the body of the request to attempt on successful login
AuthFormDisableNoStore On|Off Off dB
Disable the CacheControl no-store header on the login page
AuthFormFakeBasicAuth On|Off Off dB
Fake a Basic Authentication header
AuthFormLocation fieldname httpd_location dB
The name of a form field carrying a URL to redirect to on successful login
AuthFormLoginRequiredLocation urldB
The URL of the page to be redirected to should login be required
AuthFormLoginSuccessLocation urldB
The URL of the page to be redirected to should login be successful
AuthFormLogoutLocation uridB
The URL to redirect to after a user has logged out
AuthFormMethod fieldname httpd_method dB
The name of a form field carrying the method of the request to attempt on successful login
AuthFormMimetype fieldname httpd_mimetype dB
The name of a form field carrying the mimetype of the body of the request to attempt on successful login
AuthFormPassword fieldname httpd_password dB
The name of a form field carrying the login password
AuthFormProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthFormSitePassphrase secretdB
Bypass authentication checks for high traffic sites
AuthFormSize size 8192 dB
The largest size of the form in bytes that will be parsed for the login details
AuthFormUsername fieldname httpd_username dB
The name of a form field carrying the login username
AuthGroupFile file-pathdhB
Sets the name of a text file containing the list of user groups for authorization
AuthLDAPAuthorizePrefix prefix AUTHORIZE_ dhE
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritative off|on on dhE
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDN distinguished-namedhE
Optional DN to use in binding to the LDAP server
AuthLDAPBindPassword passworddhE
Password used in conjunction with the bind DN
AuthLDAPCharsetConfig file-pathsE
Language to charset conversion configuration file
AuthLDAPCompareAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization comparisons
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 attribute member uniqueMember +dhE
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDN on|off on dhE
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUser off|on off dhE
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPattern regex substitution (.*) $1 (remote use +dhE
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepth Number 10 dhE
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttribute uiddhE
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDN on|off off dhE
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttribute attribute member uniqueMember +dhE
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClass LdapObjectClass groupOfNames groupO +dhE
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhB
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthName auth-domaindhB
Authorization realm for use in HTTP authentication
AuthnCacheContext directory|server|custom-string directory dB
Specify a context string for use in the cache key
AuthnCacheEnablesB
Enable Authn caching configured anywhere
AuthnCacheProvideFor authn-provider [...]dhB
Specify which authn provider(s) to cache for
AuthnCacheSOCache provider-name[:provider-args]sB
Select socache backend provider to use
AuthnCacheTimeout timeout (seconds) 300 (5 minutes) dhB
Set a timeout for cache entries
<AuthnProviderAlias baseProvider Alias> ... </AuthnProviderAlias>sB
Enclose a group of directives that represent an extension of a base authentication provider and referenced by the specified alias
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Enables a FastCGI application to handle the check_authn authentication hook.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Defines a FastCGI application as a provider for authentication and/or authorization
AuthType None|Basic|Digest|FormdhB
Type of user authentication
AuthUserFile file-pathdhB
Sets the name of a text file containing the list of users and passwords for authentication
AuthzDBDLoginToReferer On|Off Off dE
Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
AuthzDBDQuery querydE
Specify the SQL Query for the required operation
AuthzDBDRedirectQuery querydE
Specify a query to look up a login page for the user
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
Sets the type of database file that is used to store list of user groups
<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> sB
Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
AuthzSendForbiddenOnFailure On|Off Off dhB
Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
BalancerGrowth # 5 svE
Number of additional Balancers that can be added Post-configuration
BalancerInherit On|Off On svE
Inherit ProxyPassed Balancers/Workers from the main server
BalancerMember [balancerurl] url [key=value [key=value ...]]dE
Add a member to a load balancing group
BalancerPersist On|Off Off svE
Attempt to persist changes made by the Balancer Manager across restarts.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
BrotliCompressionMaxInputBlock valuesvE
Maximum input block size
BrotliCompressionQuality value 5 svE
Compression quality
BrotliCompressionWindow value 18 svE
Brotli sliding compression window size
BrotliFilterNote [type] notenamesvE
Places the compression ratio in a note for logging
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
BufferSize integer 131072 svdhE
Maximum size in bytes to buffer by the buffer filter
CacheDefaultExpire seconds 3600 (one hour) svdhE
The default duration to cache a document when no expiry date is specified.
CacheDetailHeader on|off off svdhE
Add an X-Cache-Detail header to the response.
CacheDirLength length 2 svE
The number of characters in subdirectory names
CacheDirLevels levels 2 svE
The number of levels of subdirectories in the cache.
CacheDisable url-string | onsvdhE
Disable caching of specified URLs
CacheEnable cache_type [url-string]svdE
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
CacheHeader on|off off svdhE
Add an X-Cache header to the response.
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 svdhE
Ignore the fact that a response has no Last Modified header.
CacheIgnoreQueryString On|Off Off svE
Ignore query string when caching
CacheIgnoreURLSessionIdentifiers identifier [identifier] ... None svE
Ignore defined session identifiers encoded in the URL when caching
CacheKeyBaseURL URLsvE
Override the base URL of reverse proxied cache keys.
CacheLastModifiedFactor float 0.1 svdhE
The factor used to compute an expiry date based on the LastModified date.
CacheLock on|off off svE
Enable the thundering herd lock.
CacheLockMaxAge integer 5 svE
Set the maximum possible age of a cache lock.
CacheLockPath directory /tmp/mod_cache-lock +svE
Set the lock path directory.
CacheMaxExpire seconds 86400 (one day) svdhE
The maximum time in seconds to cache a document
CacheMaxFileSize bytes 1000000 svdhE
The maximum size (in bytes) of a document to be placed in the cache
CacheMinExpire seconds 0 svdhE
The minimum time in seconds to cache a document
CacheMinFileSize bytes 1 svdhE
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
CacheQuickHandler on|off on svE
Run the cache from the quick handler.
CacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheRoot directorysvE
The directory root under which cache files are stored
CacheSocache type[:args]svE
The shared object cache implementation to use
CacheSocacheMaxSize bytes 102400 svdhE
The maximum size (in bytes) of an entry to be placed in the cache
CacheSocacheMaxTime seconds 86400 svdhE
The maximum time (in seconds) for a document to be placed in the cache
CacheSocacheMinTime seconds 600 svdhE
The minimum time (in seconds) for a document to be placed in the cache
CacheSocacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheSocacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheStaleOnError on|off on svdhE
Serve stale content in place of 5xx responses.
CacheStoreExpired On|Off Off svdhE
Attempt to cache responses that the server reports as expired
CacheStoreNoStore On|Off Off svdhE
Attempt to cache requests or responses that have been marked as no-store.
CacheStorePrivate On|Off Off svdhE
Attempt to cache responses that the server has marked as private
CGIDScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIMapExtension cgi-path .extensiondhC
Technique for locating the interpreter for CGI scripts
CGIPassAuth On|Off Off dhC
Enables passing HTTP authorization headers to scripts as CGI variables
CGIScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIVar variable ruledhC
Controls how some CGI variables are set
CharsetDefault charsetsvdhE
Charset to translate into
CharsetOptions option [option] ... ImplicitAdd svdhE
Configures charset translation behavior
CharsetSourceEnc charsetsvdhE
Source charset of files
CheckBasenameMatch on|off On svdhE
Also match files with differing file name extensions.
CheckCaseOnly on|off Off svdhE
Limits the action of the speling module to case corrections
CheckSpelling on|off Off svdhE
Enables the spelling module
ChrootDir /path/to/directorysB
Directory for apache to run chroot(8) after startup.
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
CookieHTTPOnly on|off off svdhE
Adds the 'HTTPOnly' attribute to the cookie
CookieName token Apache svdhE
Name of the tracking cookie
CookieSameSite None|Lax|StrictsvdhE
Adds the 'SameSite' attribute to the cookie
CookieSecure on|off off svdhE
Adds the 'Secure' attribute to the 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 HTTP Server attempts to switch before dumping core
CustomLog file|pipe format|nickname [env=[!]environment-variable| expr=expression]svB
Sets filename and format of log file
Dav On|Off|provider-name Off dE
Enable WebDAV HTTP methods
DavBasePath root-pathdE
Configure repository root path
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
DavLockDiscovery on|off on svdhE
Enable lock discovery
DavMinTimeout seconds 0 svdE
Minimum amount of time the server holds a lock on a DAV resource
DBDExptime time-in-seconds 300 svE
Keepalive time for idle connections
DBDInitSQL "SQL statement"svE
Execute an SQL statement after connecting to a database
DBDKeep number 2 svE
Maximum sustained number of connections
DBDMax number 10 svE
Maximum number of connections
DBDMin number 1 svE
Minimum number of connections
DBDParams param1=value1[,param2=value2]svE
Parameters for database connection
DBDPersist On|OffsvE
Whether to use persistent connections
DBDPrepareSQL "SQL statement" labelsvE
Define an SQL prepared statement
DBDriver namesvE
Specify an SQL driver
DefaultIcon url-pathsvdhB
Icon to display for files when no specific icon is configured
DefaultLanguage language-tagsvdhB
Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
DefaultRuntimeDir directory-path DEFAULT_REL_RUNTIME +sC
Base directory for the server run-time files
DefaultType media-type|none none svdhC
This directive has no effect other than to emit warnings if the value is not none. In prior versions, DefaultType would specify a default media type to assign to response content for which no other media type configuration could be found.
Define parameter-namesC
Define the existence of a variable
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
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
DeflateInflateLimitRequestBody valuesvdhE
Maximum size of inflated request bodies
DeflateInflateRatioBurst value 3 svdhE
Maximum number of times the inflation ratio for request bodies can be crossed
DeflateInflateRatioLimit value 200 svdhE
Maximum inflation ratio for request bodies
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] ...dhE
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, sub-directories, and their contents.
DirectoryCheckHandler On|Off Off svdhB
Toggle how this module responds when another handler is configured
DirectoryIndex disabled | local-url [local-url] ... index.html svdhB
List of resources to look for when the client requests a directory
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code off svdhB
Configures an external redirect for directory indexes.
<DirectoryMatch regex> ... </DirectoryMatch>svC
Enclose directives that apply to the contents of file-system directories matching a regular expression.
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
DTracePrivileges On|Off Off sX
Determines whether the privileges required by dtrace are enabled.
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
<Else> ... </Else>svdhC
Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
<ElseIf expression> ... </ElseIf>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
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 Off svdhC
Use the kernel sendfile support to deliver files to the client
Error messagesvdhC
Abort configuration parsing with a custom error message
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
ErrorLog [connection|request] formatsvC
Format specification for error log entries
ExamplesvdhX
Demonstration directive to illustrate the Apache module API
ExpiresActive On|Off Off svdhE
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[*] sC
Keep track of extended status information for each request
ExtFilterDefine filtername parameterssE
Define an external filter
ExtFilterOptions option [option] ... NoLogStderr dE
Configure mod_ext_filter options
FallbackResource disabled | local-urlsvdhB
Define a default URL for requests that don't map to a file
FileETag component ... INode MTime Size svdhC
File attributes used to create the ETag HTTP response header for static files
<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 ...svdhB
Configure the filter chain
FilterDeclare filter-name [type]svdhB
Declare a smart filter
FilterProtocol filter-name [provider-name] proto-flagssvdhB
Deal with correct HTTP protocol handling
FilterProvider filter-name provider-name expressionsvdhB
Register a content filter
FilterTrace filter-name levelsvdB
Get debug/diagnostic information from mod_filter
FlushMaxPipelined number 5 svC
Maximum number of pipelined responses above which they are flushed to the network
FlushMaxThreshold number-of-bytes 65535 svC
Threshold above which pending data are flushed to the network
ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
Action to take if a single acceptable document is not found
ForceType media-type|NonedhC
Forces all matching files to be served with the specified media type in the HTTP Content-Type header field
ForensicLog filename|pipesvE
Sets filename of the forensic log
GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]sB
Sets filename and format of log file
GprofDir /tmp/gprof/|/tmp/gprof/%svC
Directory to write gmon.out profiling data to.
GracefulShutdownTimeout seconds 0 sM
Specify a timeout after which a gracefully shutdown server will exit.
Group unix-group #-1 sB
Group under which the server will answer requests
H2CopyFiles on|off off svdhE
Determine file handling in responses
H2Direct on|off on for h2c, off for +svE
H2 Direct Protocol Switch
H2EarlyHint name valuesvdhE
Add a response header to be picked up in 103 Early Hints
H2EarlyHints on|off off svE
Determine sending of 103 status codes
H2MaxDataFrameLen n 0 svE
Maximum bytes inside a single HTTP/2 DATA frame
H2MaxHeaderBlockLen n 0 svE
Maximum size of response headers
H2MaxSessionStreams n 100 svE
Maximum number of active streams per HTTP/2 session.
H2MaxWorkerIdleSeconds n 600 sE
Maximum number of seconds h2 workers remain idle until shut down.
H2MaxWorkers nsE
Maximum number of worker threads to use per child process.
H2MinWorkers nsE
Minimal number of worker threads to use per child process.
H2ModernTLSOnly on|off on svE
Require HTTP/2 connections to be "modern TLS" only
H2OutputBuffering on|off on svE
Determine buffering behaviour of output
H2Padding numbits 0 svE
Determine the range of padding bytes added to payload frames
H2ProxyRequests on|off off svE
En-/Disable forward proxy requests via HTTP/2
H2Push on|off on svdhE
H2 Server Push Switch
H2PushDiarySize n 256 svE
H2 Server Push Diary Size
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 svE
H2 Server Push Priority
H2PushResource [add] path [critical]svdhE
Declares resources for early pushing to the client
H2SerializeHeaders on|off off svE
Serialize Request/Response Processing Switch
H2StreamMaxMemSize bytes 65536 svE
Maximum amount of output data buffered per stream.
H2StreamTimeout time-interval[s]svdE
Maximum time waiting when sending/receiving data to stream processing
H2TLSCoolDownSecs seconds 1 svE
Configure the number of seconds of idle time on TLS before shrinking writes
H2TLSWarmUpSize amount 1048576 svE
Configure the number of bytes on TLS connection before doing max writes
H2Upgrade on|off on for h2c, off for +svdhE
H2 Upgrade Protocol Switch
H2WebSockets on|off off svE
En-/Disable WebSockets via HTTP/2
H2WindowSize bytes 65535 svE
Size of Stream Window for upstream data.
Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP response headers
HeaderName filenamesvdhB
Name of the file that will be inserted at the top of the index listing
HeartbeatAddress addr:portsX
Multicast address for heartbeat packets
HeartbeatListen addr:portsX
multicast address to listen for incoming heartbeat requests
HeartbeatMaxServers number-of-servers 10 sX
Specifies the maximum number of servers that will be sending heartbeat requests to this server
HeartbeatStorage file-path logs/hb.dat sX
Path to store heartbeat data when using flat-file storage
HeartbeatStorage file-path logs/hb.dat sX
Path to read heartbeat data
HostnameLookups On|Off|Double Off svdC
Enables DNS lookups on client IP addresses
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +svC
Modify restrictions on HTTP Request Messages
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
<If expression> ... </If>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime
<IfDefine [!]parameter-name> ... </IfDefine>svdhC
Encloses directives that will be processed only if a test is true at startup
<IfDirective [!]directive-name> ... </IfDirective>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific directive
<IfFile [!]filename> ... </IfFile>svdhC
Encloses directives that will be processed only if file exists at startup
<IfModule [!]module-file|module-identifier> ... </IfModule>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific module
<IfSection [!]section-name> ... </IfSection>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific section directive
<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|unformatted formatted svdhB
Action if no coordinates are given when calling an imagemap
Include [optional|strict] file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IncludeOptional file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IndexHeadInsert "markup ..."svdhB
Inserts text in the HEAD section of an index page.
IndexIgnore file [file] ... "." svdhB
Adds to the list of files to hide when listing a directory
IndexIgnoreReset ON|OFFsvdhB
Empties 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
InputSed sed-commanddhX
Sed command to filter request data (typically POST data)
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 num[ms] 5 svC
Amount of time the server will wait for subsequent requests on a persistent connection
KeptBodySize maximum size in bytes 0 dB
Keep the request body instead of discarding it up to the specified maximum size, for potential use by filters such as mod_include.
LanguagePriority MIME-lang [MIME-lang] ...svdhB
The precedence 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
LDAPConnectionPoolTTL n -1 svE
Discard backend connections that have been sitting in the connection pool too long
LDAPConnectionTimeout secondssE
Specifies the socket connection timeout in seconds
LDAPLibraryDebug 7sE
Enable debugging in the LDAP SDK
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
LDAPReferralHopLimit numberdhE
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferrals On|Off|default On dhE
Enable referral chasing during queries to the LDAP server.
LDAPRetries number-of-retries 3 sE
Configures the number of LDAP server retries.
LDAPRetryDelay seconds 0 sE
Configures the delay between LDAP server retries.
LDAPSharedCacheFile directory-path/filenamesE
Sets the shared memory cache file
LDAPSharedCacheSize bytes 500000 sE
Size in bytes of the shared-memory cache
LDAPTimeout seconds 60 sE
Specifies the timeout for LDAP search and bind operations, in seconds
LDAPTrustedClientCert type directory-path/filename/nickname [password]dhE
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 typesvE
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>dhC
Restrict enclosed access controls to only certain HTTP methods
<LimitExcept method [method] ... > ... </LimitExcept>dhC
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 svC
Limits the number of HTTP request header fields that will be accepted from the client
LimitRequestFieldSize bytes 8190 svC
Limits the size of the HTTP request header allowed from the client
LimitRequestLine bytes 8190 svC
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:]portnumber [protocol]sM
IP addresses and ports that the server listens to
ListenBackLog backlog 511 sM
Maximum length of the queue of pending connections
ListenCoresBucketsRatio ratio 0 (disabled) sM
Ratio between the number of CPU cores (online) and the number of listeners' buckets
LoadFile filename [filename] ...svE
Link in the named object file or library
LoadModule module filenamesvE
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
LogFormat format|nickname [nickname] "%h %l %u %t \"%r\" +svB
Describes a format for use in a log file
LogIOTrackTTFB ON|OFF OFF svdhE
Enable tracking of time to first byte (TTFB)
LogLevel [module:]level [module:level] ... warn svdC
Controls the verbosity of the ErrorLog
LogMessage message [hook=hook] [expr=expression] dX
Log user-defined message to error log
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Plug an authorization provider function into mod_authz_core
LuaCodeCache stat|forever|never stat svdhE
Configure the compiled code cache.
LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the access_checker phase of request processing
LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the check_user_id phase of request processing
LuaHookFixups /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the fixups phase of a request processing
LuaHookInsertFilter /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the insert_filter phase of request processing
LuaHookLog /path/to/lua/script.lua log_function_namesvdhE
Provide a hook for the access log phase of a request processing
LuaHookMapToStorage /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslate /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]svE
Provide a hook for the translate name phase of request processing
LuaHookTypeChecker /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the type_checker phase of request processing
LuaInherit none|parent-first|parent-last parent-first svdhE
Controls how parent configuration sections are merged into children
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content input filtering
LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]svdhE
Map a path to a lua handler
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content output filtering
LuaPackageCPath /path/to/include/?.soasvdhE
Add a directory to lua's package.cpath
LuaPackagePath /path/to/include/?.luasvdhE
Add a directory to lua's package.path
LuaQuickHandler /path/to/script.lua hook_function_namesvE
Provide a hook for the quick handler of request processing
LuaRoot /path/to/a/directorysvdhE
Specify the base path for resolving relative paths for mod_lua directives
LuaScope once|request|conn|thread|server [min] [max] once svdhE
One of once, request, conn, thread -- default is once
<Macro name [par1 .. parN]> ... </Macro>svdB
Define a configuration file macro
MaxConnectionsPerChild number 0 sM
Limit on the number of connections that an individual child server will handle during its life
MaxKeepAliveRequests number 100 svC
Number of requests allowed on a persistent connection
MaxMemFree KBytes 2048 sM
Maximum amount of memory that the main allocator is allowed to hold without calling free()
MaxRangeOverlaps default | unlimited | none | number-of-ranges 20 svdC
Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
MaxRangeReversals default | unlimited | none | number-of-ranges 20 svdC
Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
MaxRanges default | unlimited | none | number-of-ranges 200 svdC
Number of ranges allowed before returning the complete resource
MaxRequestWorkers numbersM
Maximum number of connections that will be processed simultaneously
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
MDActivationDelay durationsX
How long to delay activation of new certificates
MDBaseServer on|off off sX
Control if base server may be managed or only virtual hosts.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sX
Type of ACME challenge used to prove domain ownership.
MDCertificateAgreement acceptedsX
You confirm that you accepted the Terms of Service of the Certificate Authority.
MDCertificateAuthority url letsencrypt sX
The URL(s) of the ACME Certificate Authority to use.
MDCertificateCheck name urlsX
Set name and URL pattern for a certificate monitoring site.
MDCertificateFile path-to-pem-filesX
Specify a static certificate file for the MD.
MDCertificateKeyFile path-to-filesX
Specify a static private key for for the static cerrtificate.
MDCertificateMonitor name url crt.sh https://crt. +sX
The URL of a certificate log monitor.
MDCertificateProtocol protocol ACME sX
The protocol to use with the Certificate Authority.
MDCertificateStatus on|off on sX
Exposes public certificate information in JSON.
MDChallengeDns01 path-to-commandsX
Set the command for setup/teardown of dns-01 challenges
MDChallengeDns01Version 1|2 1 sX
Set the type of arguments to call MDChallengeDns01 with
MDCheckInterval duration 12h sX
Determines how often certificates are checked
MDContactEmail addresssX
Email address used for account registration
MDDriveMode always|auto|manual auto sX
former name of MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sX
Set the external account binding keyid and hmac values to use at CA
MDHttpProxy urlsX
Define a proxy for outgoing connections.
MDMatchNames all|servernames all sX
Determines how DNS names are matched to vhosts
MDMember hostnamesX
Additional hostname for the managed domain.
MDMembers auto|manual auto sX
Control if the alias domain names are automatically added.
MDMessageCmd path-to-cmd optional-argssX
Handle events for Manage Domains
MDMustStaple on|off off sX
Control if new certificates carry the OCSP Must Staple flag.
MDNotifyCmd path [ args ]sX
Run a program when a Managed Domain is ready.
MDomain dns-name [ other-dns-name... ] [auto|manual]sX
Define list of domain names that belong to one group.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sX
Container for directives applied to the same managed domains.
MDPortMap map1 [ map2 ] http:80 https:443 sX
Map external to internal ports for domain ownership verification.
MDPrivateKeys type [ params... ] RSA 2048 sX
Set type and size of the private keys generated.
MDProfile namesX
Use a specific ACME profile from the CA
MDProfileMandatory on|off off sX
Control if an MDProfile is mandatory.
MDRenewMode always|auto|manual auto sX
Controls if certificates shall be renewed.
MDRenewWindow duration 33% sX
Control when a certificate will be renewed.
MDRequireHttps off|temporary|permanent off sX
Redirects http: traffic to https: for Managed Domains.
MDRetryDelay duration 5s sX
Time length for first retry, doubled on every consecutive error.
MDRetryFailover number 13 sX
The number of errors before a failover to another CA is triggered
MDServerStatus on|off on sX
Control if Managed Domain information is added to server-status.
MDStapleOthers on|off on sX
Enable stapling for certificates not managed by mod_md.
MDStapling on|off off sX
Enable stapling for all or a particular MDomain.
MDStaplingKeepResponse duration 7d sX
Controls when old responses should be removed.
MDStaplingRenewWindow duration 33% sX
Control when the stapling responses will be renewed.
MDStoreDir path md sX
Path on the local file system to store the Managed Domains data.
MDStoreLocks on|off|duration off sX
Configure locking of store for updates
MDWarnWindow duration 10% sX
Define the time window when you want to be warned about an expiring certificate.
MemcacheConnTTL num[units] 15s svE
Keepalive time for idle connections
MergeSlashes ON|OFF ON svC
Controls whether the server merges consecutive slashes in URLs.
MergeTrailers [on|off] off svC
Determines whether trailers are merged into headers
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 containing 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
ModemStandard V.21|V.26bis|V.32|V.34|V.92dX
Modem standard to simulate
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
Mutex mechanism [default|mutex-name] ... [OmitPID] default sC
Configures mutex mechanism and lock file directory for all or specified mutexes
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
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 dhE
Controls the default access state and the order in which Allow and Deny are evaluated.
OutputSed sed-commanddhX
Sed command for filtering response content
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
PrivilegesMode FAST|SECURE|SELECTIVE FAST svdX
Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Protocol protocolsvC
Protocol for a listening socket
ProtocolEcho On|Off Off svX
Turn the echo server on or off
Protocols protocol ... http/1.1 svC
Protocols available for a server/virtual host
ProtocolsHonorOrder On|Off On svC
Determines if order of Protocols determines precedence during negotiation
<Proxy wildcard-url> ...</Proxy>svE
Container for directives applied to proxied resources
Proxy100Continue Off|On On svdE
Forward 100-continue expectation to the origin server
ProxyAddHeaders Off|On On svdE
Add proxy information in X-Forwarded-* headers
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 Off|On [code ...] Off svdE
Override error pages for proxied content
ProxyExpressDBMFile pathnamesvE
Pathname to DBM file.
ProxyExpressDBMType type default svE
DBM type of file.
ProxyExpressEnable on|off off svE
Enable the module functionality.
ProxyFCGIBackendType FPM|GENERIC FPM svdhE
Specify the type of backend FastCGI application
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]svdhE
Allow variables sent to FastCGI servers to be fixed up
ProxyFtpDirCharset character_set ISO-8859-1 svdE
Define the character set for proxied FTP listings
ProxyFtpEscapeWildcards on|off on svdE
Whether wildcards in requested filenames are escaped when sent to the FTP server
ProxyFtpListOnWildcard on|off on svdE
Whether wildcards in requested filenames trigger a file listing
ProxyHCExpr name {ap_expr expression}svE
Creates a named condition expression to use to determine health of the backend based on its response
ProxyHCTemplate name parameter=setting [...]svE
Creates a named template for setting various health check parameters
ProxyHCTPsize size 16 sE
Sets the total server-wide size of the threadpool used for the health check workers
ProxyHTMLBufSize bytes 8192 svdB
Sets the buffer size increment for buffering inline scripts and stylesheets.
ProxyHTMLCharsetOut Charset | *svdB
Specify a charset for mod_proxy_html output.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
svdB
Sets an HTML or XHTML document type declaration.
ProxyHTMLEnable On|Off Off svdB
Turns the proxy_html filter on or off.
ProxyHTMLEvents attribute [attribute ...]svdB
Specify attributes to treat as scripting events.
ProxyHTMLExtended On|Off Off svdB
Determines whether to fix links in inline scripts, stylesheets, and scripting events.
ProxyHTMLFixups [lowercase] [dospath] [reset]svdB
Fixes for simple HTML errors.
ProxyHTMLInterp On|Off Off svdB
Enables per-request interpolation of ProxyHTMLURLMap rules.
ProxyHTMLLinks element attribute [attribute2 ...]svdB
Specify HTML elements that have URL attributes to be rewritten.
ProxyHTMLMeta On|Off Off svdB
Turns on or off extra pre-parsing of metadata in HTML <head> sections.
ProxyHTMLStripComments On|Off Off svdB
Determines whether to strip HTML comments.
ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]svdB
Defines a rule to rewrite HTML links
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 -1 svE
Maximum number of proxies that a request can be forwarded through
ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] [noquery]svdE
Maps remote servers into the local server URL-space
ProxyPassInherit On|Off On svE
Inherit ProxyPass directives defined from the main server
ProxyPassInterpolateEnv On|Off Off svdE
Enable Environment Variable interpolation in Reverse Proxy configurations
ProxyPassMatch [regex] !|url [key=value [key=value ...]]svdE
Maps remote servers into the local server URL-space using regular expressions
ProxyPassReverse [path] url [interpolate]svdE
Adjusts the URL in HTTP response headers sent from a reverse proxied server
ProxyPassReverseCookieDomain internal-domain public-domain [interpolate]svdE
Adjusts the Domain string in Set-Cookie headers from a reverse- proxied server
ProxyPassReverseCookiePath internal-path public-path [interpolate]svdE
Adjusts the Path string in Set-Cookie headers from a reverse- proxied server
ProxyPreserveHost On|Off Off svdE
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-server [username:password]svE
Remote proxy used to handle certain requests
ProxyRemoteMatch regex remote-server [username:password]svE
Remote proxy used to handle requests matched by regular expressions
ProxyRequests On|Off Off svE
Enables forward (standard) proxy requests
ProxySCGIInternalRedirect On|Off|Headername On svdE
Enable or disable internal redirect responses from the backend
ProxySCGISendfile On|Off|Headername Off svdE
Enable evaluation of X-Sendfile pseudo response header
ProxySet url key=value [key=value ...]svdE
Set various Proxy balancer or member parameters
ProxySourceAddress addresssvE
Set local IP address for outgoing proxy connections
ProxyStatus Off|On|Full Off svE
Show Proxy LoadBalancer status in mod_status
ProxyTimeout secondssvE
Network timeout for proxied requests
ProxyVia On|Off|Full|Block Off svE
Information provided in the Via HTTP response header for proxied requests
ProxyWebsocketFallbackToProxyHttp On|Off On svE
Instructs this module to let mod_proxy_http handle the request
QualifyRedirectURL On|Off Off svdC
Controls whether the REDIRECT_URL environment variable is fully qualified
ReadBufferSize bytes 8192 svdC
Size of the buffers used to read data
ReadmeName filenamesvdhB
Name of the file that will be inserted at the end of the index listing
ReceiveBufferSize bytes 0 sM
TCP receive buffer size
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
RedirectRelative On|Off Off svdB
Allows relative redirect targets.
RedirectTemp URL-path URLsvdhB
Sends an external temporary redirect asking the client to fetch a different URL
RedisConnPoolTTL num[units] 15s svE
TTL used for the connection pool with the Redis server(s)
RedisTimeout num[units] 5s svE
R/W timeout used for the connection with the Redis server(s)
ReflectorHeader inputheader [outputheader]svdhB
Reflect an input header to the output headers
RegexDefaultOptions [none] [+|-]option [[+|-]option] ... DOTALL DOLLAR_ENDON +sC
Allow to configure global/default options for regexes
RegisterHttpMethod method [method [...]]sC
Register non-standard HTTP methods
RemoteIPHeader header-fieldsvB
Declare the header field which should be parsed for useragent IP addresses
RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPInternalProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPProxiesHeader HeaderFieldNamesvB
Declare the header field which will record all intermediate IP addresses
RemoteIPProxyProtocol On|OffsvB
Enable or disable PROXY protocol handling
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]svB
Disable processing of PROXY header for certain hosts or networks
RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPTrustedProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
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 add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP request headers
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate] handshake=0 header= +svE
Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Require [not] entity-name [entity-name] ...dhB
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll> ... </RequireAll>dhB
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny> ... </RequireAny>dhB
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone> ... </RequireNone>dhB
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
RewriteBase URL-pathdhE
Sets the base URL for per-directory rewrites
RewriteCond TestString CondPattern [flags]svdhE
Defines a condition under which rewriting will take place
RewriteEngine on|off off svdhE
Enables or disables runtime rewriting engine
RewriteMap MapName MapType:MapSource [MapTypeOptions] svE
Defines a mapping function for key-lookup
RewriteOptions OptionssvdhE
Sets some special options for the rewrite engine
RewriteRule Pattern Substitution [flags]svdhE
Defines rules for the rewriting engine
RLimitCPU seconds|max [seconds|max]svdhC
Limits the CPU consumption of processes launched by Apache httpd children
RLimitMEM bytes|max [bytes|max]svdhC
Limits the memory consumption of processes launched by Apache httpd children
RLimitNPROC number|max [number|max]svdhC
Limits the number of processes that can be launched by processes launched by Apache httpd children
Satisfy Any|All All dhE
Interaction between host-level access control and user authentication
ScoreBoardFile file-path logs/apache_runtime +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-pathsvdB
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 cgisock sB
The filename prefix 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
SeeRequestTail On|Off Off sC
Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
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 [scheme://]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
Session On|Off Off svdhE
Enables a session for the current directory or location
SessionCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session
SessionCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session
SessionCookieRemove On|Off Off svdhE
Control for whether session cookies should be removed from incoming HTTP headers
SessionCryptoCipher name aes256 svdhX
The crypto cipher to be used to encrypt the session
SessionCryptoDriver name [param[=value]]sX
The crypto driver to be used to encrypt the session
SessionCryptoPassphrase secret [ secret ... ] svdhX
The key used to encrypt the session
SessionCryptoPassphraseFile filenamesvdX
File containing keys used to encrypt the session
SessionDBDCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session ID
SessionDBDCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session ID
SessionDBDCookieRemove On|Off On svdhE
Control for whether session ID cookies should be removed from incoming HTTP headers
SessionDBDDeleteLabel label deletesession svdhE
The SQL query to use to remove sessions from the database
SessionDBDInsertLabel label insertsession svdhE
The SQL query to use to insert sessions into the database
SessionDBDPerUser On|Off Off svdhE
Enable a per user session
SessionDBDSelectLabel label selectsession svdhE
The SQL query to use to select sessions from the database
SessionDBDUpdateLabel label updatesession svdhE
The SQL query to use to update existing sessions in the database
SessionEnv On|Off Off svdhE
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionExclude pathsvdhE
Define URL prefixes for which a session is ignored
SessionExpiryUpdateInterval interval 0 (always update) svdhE
Define the number of seconds a session's expiry may change without the session being updated
SessionHeader headersvdhE
Import session updates from a given HTTP response header
SessionInclude pathsvdhE
Define URL prefixes for which a session is valid
SessionMaxAge maxage 0 svdhE
Define a maximum age in seconds for a session
SetEnv env-variable [value]svdhB
Sets environment variables
SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on attributes of the request
SetEnvIfExpr expr [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on an ap_expr expression
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
SSIETag on|off off dhB
Controls whether ETags are generated by the server.
SSILastModified on|off off dhB
Controls whether Last-Modified headers are generated by the server.
SSILegacyExprParser on|off off dhB
Enable compatibility mode for conditional expressions.
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
SSLCARevocationCheck chain|leaf|none [flags ...] none svE
Enable CRL-based revocation checking
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-path|certidsvE
Server PEM-encoded X.509 certificate data file or token identifier
SSLCertificateKeyFile file-path|keyidsvE
Server PEM-encoded private key file
SSLCipherSuite [protocol] cipher-spec DEFAULT (depends on +svdhE
Cipher Suite available for negotiation in SSL handshake
SSLCompression on|off off svE
Enable compression on the SSL level
SSLCryptoDevice engine builtin sE
Enable use of a cryptographic hardware accelerator
SSLEngine on|off|optional off svE
SSL Engine Operation Switch
SSLFIPS on|off off sE
SSL FIPS mode Switch
SSLHonorCipherOrder on|off off svE
Option to prefer the server's cipher preference order
SSLInsecureRenegotiation on|off off svE
Option to enable support for insecure renegotiation
SSLOCSPDefaultResponder urisvE
Set the default responder URI for OCSP validation
SSLOCSPEnable on|leaf|off off svE
Enable OCSP validation of the client certificate chain
SSLOCSPNoverify on|off off svE
skip the OCSP responder certificates verification
SSLOCSPOverrideResponder on|off off svE
Force use of the default responder URI for OCSP validation
SSLOCSPProxyURL urlsvE
Proxy URL to use for OCSP requests
SSLOCSPResponderCertificateFile filesvE
Set of trusted PEM encoded OCSP responder certificates
SSLOCSPResponderTimeout seconds 10 svE
Timeout for OCSP queries
SSLOCSPResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP responses
SSLOCSPResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP response validation
SSLOCSPUseRequestNonce on|off on svE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd command-name command-valuesvE
Configure OpenSSL parameters through its SSL_CONF API
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 -SSLv3 (up to 2 +svE
Configure usable SSL/TLS protocol versions
SSLProxyCACertificateFile file-pathsvpE
File of concatenated PEM-encoded CA Certificates for Remote Server Auth
SSLProxyCACertificatePath directory-pathsvpE
Directory of PEM-encoded CA Certificates for Remote Server Auth
SSLProxyCARevocationCheck chain|leaf|none none svpE
Enable CRL-based revocation checking for Remote Server Auth
SSLProxyCARevocationFile file-pathsvpE
File of concatenated PEM-encoded CA CRLs for Remote Server Auth
SSLProxyCARevocationPath directory-pathsvpE
Directory of PEM-encoded CA CRLs for Remote Server Auth
SSLProxyCheckPeerCN on|off on svpE
Whether to check the remote server certificate's CN field
SSLProxyCheckPeerExpire on|off on svpE
Whether to check if remote server certificate is expired
SSLProxyCheckPeerName on|off on svpE
Configure host name checking for remote server certificates
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +svpE
Cipher Suite available for negotiation in SSL proxy handshake
SSLProxyEngine on|off off svpE
SSL Proxy Engine Operation Switch
SSLProxyMachineCertificateChainFile filenamesvpE
File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
SSLProxyMachineCertificateFile filenamesvpE
File of concatenated PEM-encoded client certificates and keys to be used by the proxy
SSLProxyMachineCertificatePath directorysvpE
Directory of PEM-encoded client certificates and keys to be used by the proxy
SSLProxyProtocol [+|-]protocol ... all -SSLv3 (up to 2 +svpE
Configure usable SSL protocol flavors for proxy usage
SSLProxyVerify level none svpE
Type of remote server Certificate verification
SSLProxyVerifyDepth number 1 svpE
Maximum depth of CA Certificates in Remote Server Certificate verification
SSLRandomSeed context source [bytes]sE
Pseudo Random Number Generator (PRNG) seeding source
SSLRenegBufferSize bytes 131072 dhE
Set the size for the SSL renegotiation buffer
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
SSLSessionTicketKeyFile file-pathsvE
Persistent encryption/decryption key for TLS session tickets
SSLSessionTickets on|off on svE
Enable or disable use of TLS session tickets
SSLSRPUnknownUserSeed secret-stringsvE
SRP unknown user seed
SSLSRPVerifierFile file-pathsvE
Path to SRP verifier file
SSLStaplingCache typesE
Configures the OCSP stapling cache
SSLStaplingErrorCacheTimeout seconds 600 svE
Number of seconds before expiring invalid responses in the OCSP stapling cache
SSLStaplingFakeTryLater on|off on svE
Synthesize "tryLater" responses for failed OCSP stapling queries
SSLStaplingForceURL urisvE
Override the OCSP responder URI specified in the certificate's AIA extension
SSLStaplingResponderTimeout seconds 10 svE
Timeout for OCSP stapling queries
SSLStaplingResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP stapling responses
SSLStaplingResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP stapling response validation
SSLStaplingReturnResponderErrors on|off on svE
Pass stapling related OCSP errors on to client
SSLStaplingStandardCacheTimeout seconds 3600 svE
Number of seconds before expiring responses in the OCSP stapling cache
SSLStrictSNIVHostCheck on|off off svE
Whether to allow non-SNI clients to access a name-based virtual host.
SSLUserName varnamesdhE
Variable name to determine user name
SSLUseStapling on|off off svE
Enable stapling of OCSP responses in the TLS handshake
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
StrictHostCheck ON|OFF OFF svC
Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Substitute s/pattern/substitution/[infq]dhE
Pattern to filter the response content
SubstituteInheritBefore on|off off dhE
Change the merge order of inherited patterns
SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G) 1m dhE
Set the maximum line size
Suexec On|OffsB
Enable or disable the suEXEC feature
SuexecUserGroup User GroupsvE
User and group for CGI programs to run as
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 60 svC
Amount of time the server will wait for certain events before failing a request
TraceEnable [on|off|extended] on sC
Determines the behaviour on TRACE requests
TransferLog file|pipesvB
Specify location of a log file
TypesConfig file-path conf/mime.types sB
The location of the mime.types file
UNCList hostname [hostname...]sC
Controls what UNC host names can be accessed by the server
UnDefine parameter-namesC
Undefine the existence of a variable
UndefMacro namesvdB
Undefine a macro
UnsetEnv env-variable [env-variable] ...svdhB
Removes variables from the environment
Use name [value1 ... valueN] svdB
Use a macro
UseCanonicalName On|Off|DNS Off svdC
Configures how the server determines its own name and port
UseCanonicalPhysicalPort On|Off Off svdC
Configures how the server determines its own name and port
User unix-userid #-1 sB
The userid under which the server will answer requests
UserDir directory-filename [directory-filename] ... svB
Location of the user-specific directories
VHostCGIMode On|Off|Secure On vX
Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to subprocesses created by a virtual host.
VHostGroup unix-groupidvX
Sets the Group ID under which a virtual host runs.
VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to a virtual host.
VHostSecure On|Off On vX
Determines whether the server runs with enhanced security for the virtualhost.
VHostUser unix-useridvX
Sets the User ID under which a virtual host runs.
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
WatchdogInterval time-interval[s] 1 sB
Watchdog interval in seconds
XBitHack on|off|full off svdhB
Parse SSI directives in files with the execute bit set
xml2EncAlias charset alias [alias ...]sB
Recognise Aliases for encoding values
xml2EncDefault namesvdhB
Sets a default encoding to assume when absolutely no information can be automatically detected
xml2StartParse element [element ...]svdhB
Advise the parser to skip leading junk.

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Comentarios

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.ja.utf80000664000175100017510000060662715032765673023004 0ustar covenercovener ディレクティブ クイックリファレンス - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

ディレクティブ クイックリファレンス

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

ディレクティブ クイックリファレンスでは、各 Apache 設定ディレクティブの 使用方法、デフォルト値、ステータスとコンテキストを示しています。 各ディレクティブの、より詳しい情報に関しては ディレクティブ辞書を ご覧下さい。

第 1 列目はディレクティブの名前と使用方法です。 第 2 列目は (もしあれば) デフォルト値となっています。 デフォルト値が長すぎて表示しきれない場合は、途中まで表示した上で、、 「 + 」で続きがあることを示しています。

第 3, 4 列は、下の表の注釈に従って、 ディレクティブの使用できるコンテキストと、 ディレクティブのステータスが示されています。

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
sサーバ設定ファイル
vバーチャルホスト
dディレクトリ
h.htaccess
CCore
MMPM
BBase
EExtension
XExperimental
TExternal
AcceptFilter protocol accept_filtersC
プロトコルを Listen しているソケットの最適化を設定する
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...] media-type [media-type] ...svdhB
assigns an output filter to a particular media-type
AddType MIME-type extension [extension] ...svdh
ファイル名の拡張子を指定されたコンテントタイプにマップ
Alias URL-path file-path|directory-pathsvB
URL をファイルシステムの位置にマップする
AliasMatch regex file-path|directory-pathsvB
正規表現を使って URL をファイルシステムの位置にマップする
AliasPreservePath OFF|ON OFF svdB
Map the full path after the alias in a location.
Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
サーバのある領域にアクセスできるホストを制御する
AllowCONNECT port[-port] [port[-port]] ... 443 563 svE
Ports that are allowed to CONNECT through the proxy
AllowEncodedSlashes On|Off Off svC
URL 中の符号化されたパス分離文字が先に伝えられるのを許可するかどうかを 決定する
AllowMethods reset|HTTP-method [HTTP-method]... reset dX
Restrict access to the listed HTTP methods
AllowOverride All|None|directive-type [directive-type] ... All dC
.htaccess で許可されるディレクティブの種類
AllowOverrideList None|directive [directive-type] ... None dC
Individual directives that are allowed in .htaccess files
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
パスワード欄が正しい形式の電子メールアドレスであることを 調べるかどうかを設定する
AsyncRequestWorkerFactor factorsM
Limit concurrent connections per process
AuthBasicAuthoritative On|Off On dhB
認証と承認を、より低いレベルのモジュールに移行させるかを 設定します。
AuthBasicFake off|username [password]dhB
Fake basic authentication using the given expressions for username and password
AuthBasicProvider provider-name [provider-name] ... file dhB
この位置に対する認証プロバイダを設定します。
AuthBasicUseDigestAlgorithm MD5|Off Off dhB
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBDUserPWQuery querydE
SQL query to look up a password for a user
AuthDBDUserRealmQuery querydE
SQL query to look up a password hash for a user and realm.
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
認証用のユーザとパスワードのリストを保持している データベースファイル名を設定する
AuthDigestAlgorithm MD5|MD5-sess MD5 dhE
Selects the algorithm used to calculate the challenge and response hashes in digest authentication
AuthDigestDomain URI [URI] ...dhE
URIs that are in the same protection space for digest authentication
AuthDigestNonceLifetime seconds 300 dhE
How long the server nonce is valid
AuthDigestProvider provider-name [provider-name] ... file dhE
Sets the authentication provider(s) for this location
AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhE
Determines the quality-of-protection to use in digest authentication
AuthDigestShmemSize size 1000 sE
The amount of shared memory to allocate for keeping track of clients
AuthFormAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthFormBody fieldname httpd_body dB
The name of a form field carrying the body of the request to attempt on successful login
AuthFormDisableNoStore On|Off Off dB
Disable the CacheControl no-store header on the login page
AuthFormFakeBasicAuth On|Off Off dB
Fake a Basic Authentication header
AuthFormLocation fieldname httpd_location dB
The name of a form field carrying a URL to redirect to on successful login
AuthFormLoginRequiredLocation urldB
The URL of the page to be redirected to should login be required
AuthFormLoginSuccessLocation urldB
The URL of the page to be redirected to should login be successful
AuthFormLogoutLocation uridB
The URL to redirect to after a user has logged out
AuthFormMethod fieldname httpd_method dB
The name of a form field carrying the method of the request to attempt on successful login
AuthFormMimetype fieldname httpd_mimetype dB
The name of a form field carrying the mimetype of the body of the request to attempt on successful login
AuthFormPassword fieldname httpd_password dB
The name of a form field carrying the login password
AuthFormProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthFormSitePassphrase secretdB
Bypass authentication checks for high traffic sites
AuthFormSize size 8192 dB
The largest size of the form in bytes that will be parsed for the login details
AuthFormUsername fieldname httpd_username dB
The name of a form field carrying the login username
AuthGroupFile file-pathdhB
証認に使用するユーザグループの一覧が格納されている、 テキストファイルの名前を設定する
AuthLDAPAuthorizePrefix prefix AUTHORIZE_ dhE
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritative off|on on dhE
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDN distinguished-namedhE
Optional DN to use in binding to the LDAP server
AuthLDAPBindPassword passworddhE
Password used in conjunction with the bind DN
AuthLDAPCharsetConfig file-pathsE
Language to charset conversion configuration file
AuthLDAPCompareAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization comparisons
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 attribute member uniqueMember +dhE
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDN on|off on dhE
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUser off|on off dhE
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPattern regex substitution (.*) $1 (remote use +dhE
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepth Number 10 dhE
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttribute uiddhE
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDN on|off off dhE
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttribute attribute member uniqueMember +dhE
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClass LdapObjectClass groupOfNames groupO +dhE
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhB
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthName auth-domaindhB
Authorization realm for use in HTTP authentication
AuthnCacheContext directory|server|custom-string directory dB
Specify a context string for use in the cache key
AuthnCacheEnablesB
Enable Authn caching configured anywhere
AuthnCacheProvideFor authn-provider [...]dhB
Specify which authn provider(s) to cache for
AuthnCacheSOCache provider-name[:provider-args]sB
Select socache backend provider to use
AuthnCacheTimeout timeout (seconds) 300 (5 minutes) dhB
Set a timeout for cache entries
<AuthnProviderAlias baseProvider Alias> ... </AuthnProviderAlias>sB
Enclose a group of directives that represent an extension of a base authentication provider and referenced by the specified alias
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Enables a FastCGI application to handle the check_authn authentication hook.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Defines a FastCGI application as a provider for authentication and/or authorization
AuthType None|Basic|Digest|FormdhB
Type of user authentication
AuthUserFile file-pathdhB
認証に使用するユーザとパスワードの一覧が格納されている、 テキストファイルの名前を設定する
AuthzDBDLoginToReferer On|Off Off dE
Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
AuthzDBDQuery querydE
Specify the SQL Query for the required operation
AuthzDBDRedirectQuery querydE
Specify a query to look up a login page for the user
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
Sets the type of database file that is used to store list of user groups
<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> sB
Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
AuthzSendForbiddenOnFailure On|Off Off dhB
Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
BalancerGrowth # 5 svE
Number of additional Balancers that can be added Post-configuration
BalancerInherit On|Off On svE
Inherit ProxyPassed Balancers/Workers from the main server
dE
Add a member to a load balancing group
BalancerPersist On|Off Off svE
Attempt to persist changes made by the Balancer Manager across restarts.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
BrotliCompressionMaxInputBlock valuesvE
Maximum input block size
BrotliCompressionQuality value 5 svE
Compression quality
BrotliCompressionWindow value 18 svE
Brotli sliding compression window size
BrotliFilterNote [type] notenamesvE
Places the compression ratio in a note for logging
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
ディスクに書き出す前にメモリにログエントリをバッファする
BufferSize integer 131072 svdhE
Maximum size in bytes to buffer by the buffer filter
CacheDefaultExpire seconds 3600 (1時間) svE
期日が指定されていないときにドキュメントをキャッシュするデフォルトの期間
CacheDetailHeader on|off off svdhE
Add an X-Cache-Detail header to the response.
CacheDirLength length 2 svE
サブディレクトリ名の文字数
CacheDirLevels levels 2 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
CacheHeader on|off off svdhE
Add an X-Cache header to the response.
CacheIgnoreCacheControl On|Off Off svE
キャッシュされているコンテンツを返さないようにクライアントから リクエストされても無視する
CacheIgnoreHeaders header-string [header-string] ... None svE
指定された HTTP ヘッダをキャッシュに保存しない。
CacheIgnoreNoLastMod On|Off Off svE
応答に Last Modified が無くても気にしないようにする
CacheIgnoreQueryString On|Off Off svE
キャッシュ時にクエリーストリングを無視する
CacheIgnoreURLSessionIdentifiers identifier [identifier] ... None svE
Ignore defined session identifiers encoded in the URL when caching
CacheKeyBaseURL URLsvE
Override the base URL of reverse proxied cache keys.
CacheLastModifiedFactor float 0.1 svE
LastModified の日付に基づいて有効期限 (expiry) を計算するための重みを指定する
CacheLock on|off off svE
Enable the thundering herd lock.
CacheLockMaxAge integer 5 svE
Set the maximum possible age of a cache lock.
CacheLockPath directory /tmp/mod_cache-lock +svE
Set the lock path directory.
CacheMaxExpire seconds 86400 (一日) svE
ドキュメントをキャッシュする最大時間を秒数で表したもの
CacheMaxFileSize bytes 1000000 svE
キャッシュに保管されるドキュメントの最大の (バイトでの) サイズ
CacheMinExpire seconds 0 svE
ドキュメントをキャッシュする最小秒数
CacheMinFileSize bytes 1 svE
キャッシュに保管されるドキュメントの最小限の (バイトでの) 大きさ
CacheNegotiatedDocs On|Off Off svB
コンテントネゴシエーションされたドキュメントをプロキシサーバが キャッシュできるようにする
CacheQuickHandler on|off on svE
Run the cache from the quick handler.
svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheRoot directorysvE
キャッシュファイルが保管されるルートディレクトリ
CacheSocache type[:args]svE
The shared object cache implementation to use
CacheSocacheMaxSize bytes 102400 svdhE
The maximum size (in bytes) of an entry to be placed in the cache
CacheSocacheMaxTime seconds 86400 svdhE
The maximum time (in seconds) for a document to be placed in the cache
CacheSocacheMinTime seconds 600 svdhE
The minimum time (in seconds) for a document to be placed in the cache
CacheSocacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheSocacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheStaleOnError on|off on svdhE
Serve stale content in place of 5xx responses.
CacheStoreExpired On|Off Off svdhE
Attempt to cache responses that the server reports as expired
CacheStoreNoStore On|Off Off svE
no-store と指定されているレスポンスのキャッシュを試みる。
CacheStorePrivate On|Off Off svE
private と指定されているレスポンスのキャッシュを試みる。
CGIDScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIMapExtension cgi-path .extensiondhC
CGI スクリプトのインタープリタの位置を調べるための手法
CGIPassAuth On|Off Off dhC
Enables passing HTTP authorization headers to scripts as CGI variables
CGIScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIVar variable ruledhC
Controls how some CGI variables are set
CharsetDefault charsetsvdhE
Charset to translate into
CharsetOptions option [option] ... ImplicitAdd svdhE
Configures charset translation behavior
CharsetSourceEnc charsetsvdhE
Source charset of files
CheckBasenameMatch on|off On svdhE
Also match files with differing file name extensions.
CheckCaseOnly on|off Off svdhE
大文字小文字の修正だけ行うようにする
CheckSpelling on|off Off svdhE
spelling モジュールを使用するようにする
ChrootDir /path/to/directorysB
Directory for apache to run chroot(8) after startup.
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
CookieHTTPOnly on|off off svdhE
Adds the 'HTTPOnly' attribute to the cookie
CookieName token Apache svdhE
Name of the tracking cookie
CookieSameSite None|Lax|StrictsvdhE
Adds the 'SameSite' attribute to the cookie
CookieSecure on|off off svdhE
Adds the 'Secure' attribute to the 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 メソッドを有効にします
DavBasePath root-pathdE
Configure repository root path
DavDepthInfinity on|off off svdE
PROPFIND, Depth: Infinity リクエストを許可します
DavGenericLockDB file-pathsvdE
DAV ロックデータベースの場所
DavLockDB file-pathsvE
DAV ロックデータベースの位置
DavLockDiscovery on|off on svdhE
Enable lock discovery
DavMinTimeout seconds 0 svdE
サーバが DAV リソースのロックを維持する最小時間です。
DBDExptime time-in-seconds 300 svE
Keepalive time for idle connections
DBDInitSQL "SQL statement"svE
Execute an SQL statement after connecting to a database
DBDKeep number 2 svE
Maximum sustained number of connections
DBDMax number 10 svE
Maximum number of connections
DBDMin number 1 svE
Minimum number of connections
DBDParams param1=value1[,param2=value2]svE
Parameters for database connection
DBDPersist On|OffsvE
Whether to use persistent connections
DBDPrepareSQL "SQL statement" labelsvE
Define an SQL prepared statement
DBDriver namesvE
Specify an SQL driver
DefaultIcon url-pathsvdhB
特定のアイコンが何も設定されていない時に ファイルに表示するアイコン
DefaultLanguage MIME-langsvdh
あるスコープのすべてのファイルを指定された言語に 設定する
DefaultRuntimeDir directory-path DEFAULT_REL_RUNTIME +sC
Base directory for the server run-time files
DefaultType MIME-type|none text/plain svdhC
サーバがコンテントタイプを決定できないときに 送られる MIME コンテントタイプ
Define parameter-namesC
変数の存在を宣言する
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
DeflateBufferSize value 8096 svE
zlib が一度に圧縮する塊の大きさ
DeflateCompressionLevel valuesvE
出力に対して行なう圧縮の程度
DeflateFilterNote [type] notenamesvE
ロギング用に圧縮比をメモに追加
DeflateInflateLimitRequestBody valuesvdhE
Maximum size of inflated request bodies
DeflateInflateRatioBurst value 3 svdhE
Maximum number of times the inflation ratio for request bodies can be crossed
DeflateInflateRatioLimit value 200 svdhE
Maximum inflation ratio for request bodies
DeflateMemLevel value 9 svE
zlib が圧縮に使うメモリのレベルを指定
DeflateWindowSize value 15 svE
Zlib の圧縮用ウィンドウの大きさ
Deny from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
サーバがアクセスを拒否するホストを制御する
<Directory directory-path> ... </Directory>svC
指定のファイルシステムのディレクトリとサブディレクトリとのみに 適用されるディレクティブを囲む
DirectoryCheckHandler On|Off Off svdhB
Toggle how this module responds when another handler is configured
DirectoryIndex local-url [local-url] ... index.html svdhB
クライアントがディレクトリをリクエストしたときに調べる リソースのリスト
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code off svdhB
Configures an external redirect for directory indexes.
<DirectoryMatch regex> ... </DirectoryMatch>svC
正規表現にマッチするファイルシステムのディレクトリと サブディレクトリとのみに適用されるディレクティブを囲む
DirectorySlash On|Off On svdhB
パス末尾のスラッシュでリダイレクトするかどうかのオンオフをトグルさせる
DocumentRoot directory-path /usr/local/apache/h +svC
ウェブから見えるメインのドキュメントツリーになる ディレクトリ
DTracePrivileges On|Off Off sX
Determines whether the privileges required by dtrace are enabled.
DumpIOInput On|Off Off sE
エラーログにすべての入力データをダンプ
DumpIOOutput On|Off Off sE
エラーログにすべての出力データをダンプ
<Else> ... </Else>svdhC
Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
<ElseIf expression> ... </ElseIf>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
EnableExceptionHook On|Off Off sM
クラッシュの後に例外ハンドラを実行するフックを有効にする
EnableMMAP On|Off On svdhC
配送中にファイルを読み込むためにメモリマッピングを 使うかどうか
EnableSendfile On|Off On svdhC
ファイルのクライアントへの配送時にカーネルの sendfile サポートを 使うかどうか
Error messagesvdhC
Abort configuration parsing with a custom error message
ErrorDocument error-code documentsvdhC
エラーが発生したときにサーバがクライアントに送るもの
ErrorLog file-path|syslog[:facility] logs/error_log (Uni +svC
サーバがエラーをログ収集する場所
ErrorLogFormat [connection|request] formatsvC
Format specification for error log entries
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[*] sC
Keep track of extended status information for each request
ExtFilterDefine filtername parameterssE
外部フィルタを定義
ExtFilterOptions option [option] ... DebugLevel=0 NoLogS +dE
mod_ext_filter のオプションを設定
svdhB
Define a default URL for requests that don't map to a file
FileETag component ... INode MTime Size svdhC
ETag HTTP 応答ヘッダを作成するために使用される ファイルの属性
<Files filename> ... </Files>svdhC
マッチするファイル名に適用されるディレクティブを囲む
<FilesMatch regex> ... </FilesMatch>svdhC
正規表現にマッチするファイル名に適用される ディレクティブを囲む
FilterChain [+=-@!]filter-name ...svdhB
Configure the filter chain
FilterDeclare filter-name [type]svdhB
Declare a smart filter
FilterProtocol filter-name [provider-name] proto-flagssvdhB
Deal with correct HTTP protocol handling
FilterProvider filter-name provider-name expressionsvdhB
Register a content filter
FilterTrace filter-name levelsvdB
Get debug/diagnostic information from mod_filter
FlushMaxPipelined number 5 svC
Maximum number of pipelined responses above which they are flushed to the network
FlushMaxThreshold number-of-bytes 65535 svC
Threshold above which pending data are flushed to the network
ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
要求に合う単独のドキュメントが見つからなかったときに行なうことを指定
ForceType MIME-type|NonedhC
すべてのマッチするファイルが指定の MIME コンテントタイプで 送られるようにする
ForensicLog filename|pipesvE
Forensic ログのファイル名を設定する
GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]sB
Sets filename and format of log file
GprofDir /tmp/gprof/|/tmp/gprof/%svC
Directory to write gmon.out profiling data to.
GracefulShutDownTimeout secondssM
穏やかな停止をかけた後、終了するまで待つ時間
Group unix-group #-1 sB
Group under which the server will answer requests
H2CopyFiles on|off off svdhE
Determine file handling in responses
H2Direct on|off on for h2c, off for +svE
H2 Direct Protocol Switch
H2EarlyHint name valuesvdhE
Add a response header to be picked up in 103 Early Hints
H2EarlyHints on|off off svE
Determine sending of 103 status codes
H2MaxDataFrameLen n 0 svE
Maximum bytes inside a single HTTP/2 DATA frame
H2MaxHeaderBlockLen n 0 svE
Maximum size of response headers
H2MaxSessionStreams n 100 svE
Maximum number of active streams per HTTP/2 session.
H2MaxWorkerIdleSeconds n 600 sE
Maximum number of seconds h2 workers remain idle until shut down.
H2MaxWorkers nsE
Maximum number of worker threads to use per child process.
H2MinWorkers nsE
Minimal number of worker threads to use per child process.
H2ModernTLSOnly on|off on svE
Require HTTP/2 connections to be "modern TLS" only
H2OutputBuffering on|off on svE
Determine buffering behaviour of output
H2Padding numbits 0 svE
Determine the range of padding bytes added to payload frames
H2ProxyRequests on|off off svE
En-/Disable forward proxy requests via HTTP/2
H2Push on|off on svdhE
H2 Server Push Switch
H2PushDiarySize n 256 svE
H2 Server Push Diary Size
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 svE
H2 Server Push Priority
H2PushResource [add] path [critical]svdhE
Declares resources for early pushing to the client
H2SerializeHeaders on|off off svE
Serialize Request/Response Processing Switch
H2StreamMaxMemSize bytes 65536 svE
Maximum amount of output data buffered per stream.
H2StreamTimeout time-interval[s]svdE
Maximum time waiting when sending/receiving data to stream processing
H2TLSCoolDownSecs seconds 1 svE
Configure the number of seconds of idle time on TLS before shrinking writes
H2TLSWarmUpSize amount 1048576 svE
Configure the number of bytes on TLS connection before doing max writes
H2Upgrade on|off on for h2c, off for +svdhE
H2 Upgrade Protocol Switch
H2WebSockets on|off off svE
En-/Disable WebSockets via HTTP/2
H2WindowSize bytes 65535 svE
Size of Stream Window for upstream data.
Header [condition] set|append|add|unset|echo header [value] [early|env=[!]variable]svdhE
HTTP 応答ヘッダの設定
HeaderName filenamesvdhB
インデックス一覧の先頭に挿入されるファイルの名前
HeartbeatAddress addr:portsX
Multicast address for heartbeat packets
HeartbeatListen addr:portsX
multicast address to listen for incoming heartbeat requests
HeartbeatMaxServers number-of-servers 10 sX
Specifies the maximum number of servers that will be sending heartbeat requests to this server
HeartbeatStorage file-path logs/hb.dat sX
Path to store heartbeat data when using flat-file storage
HeartbeatStorage file-path logs/hb.dat sX
Path to read heartbeat data
HostnameLookups On|Off|Double Off svdC
クライアントの IP アドレスの DNS ルックアップを 有効にする
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +svC
Modify restrictions on HTTP Request Messages
IdentityCheck On|Off Off svdE
リモートユーザの RFC 1413 によるアイデンティティのロギングを 有効にする
IdentityCheckTimeout seconds 30 svdE
Ident リクエストがタイムアウトするまでの期間を決める
<If expression> ... </If>svdhC
実行時、リクエストが条件を満たした場合にのみ適用される ディレクティブを包含する
<IfDefine [!]parameter-name> ... </IfDefine>svdhC
起動時にテストが真であるときのみに処理されるディレクティブを 囲む
<IfDirective [!]directive-name> ... </IfDirective>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific directive
<IfFile [!]filename> ... </IfFile>svdhC
Encloses directives that will be processed only if file exists at startup
<IfModule [!]module-file|module-identifier> ... </IfModule>svdhC
モジュールの存在するかしないかに応じて処理される ディレクティブを囲む
<IfSection [!]section-name> ... </IfSection>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific section directive
<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|unformatted formatted svdhB
Action if no coordinates are given when calling an imagemap
Include file-path|directory-pathsvdC
サーバ設定ファイル中から他の設定ファイルを取り込む
IncludeOptional file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IndexHeadInsert "markup ..."svdhB
インデックスページの HEAD セクションにテキストを挿入する
IndexIgnore file [file] ...svdhB
ディレクトリ一覧を行なう際に無視すべき ファイルリストに追加
IndexIgnoreReset ON|OFFsvdhB
Empties the list of files to hide when listing a directory
IndexOptions [+|-]option [[+|-]option] ...svdhB
ディレクトリインデックスの様々な設定項目
IndexOrderDefault Ascending|Descending Name|Date|Size|Description Ascending Name svdhB
ディレクトリインデックスの標準の順番付けを設定
IndexStyleSheet url-pathsvdhB
ディレクトリインデックスに CSS スタイルシートを追加する
InputSed sed-commanddhX
Sed command to filter request data (typically POST data)
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
持続的な接続で次のリクエストが来るまでサーバが待つ時間
KeptBodySize maximum size in bytes 0 dB
Keep the request body instead of discarding it up to the specified maximum size, for potential use by filters such as mod_include.
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
LDAPConnectionPoolTTL n -1 svE
Discard backend connections that have been sitting in the connection pool too long
LDAPConnectionTimeout secondssE
Specifies the socket connection timeout in seconds
LDAPLibraryDebug 7sE
Enable debugging in the LDAP SDK
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
LDAPReferralHopLimit numberdhE
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferrals On|Off|default On dhE
Enable referral chasing during queries to the LDAP server.
LDAPRetries number-of-retries 3 sE
Configures the number of LDAP server retries.
LDAPRetryDelay seconds 0 sE
Configures the delay between LDAP server retries.
LDAPSharedCacheFile directory-path/filenamesE
Sets the shared memory cache file
LDAPSharedCacheSize bytes 500000 sE
Size in bytes of the shared-memory cache
LDAPTimeout seconds 60 sE
Specifies the timeout for LDAP search and bind operations, in seconds
LDAPTrustedClientCert type directory-path/filename/nickname [password]dhE
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 typesvE
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 bytes 8190 sC
クライアントからの HTTP リクエストのヘッダの サイズを制限する
LimitRequestLine bytes 8190 sC
クライアントからの HTTP リクエスト行のサイズを制限する
LimitXMLRequestBody bytes 1000000 svdhC
XML 形式のリクエストのボディのサイズを制限する
Listen [IP-address:]portnumber [protocol]sM
サーバが listen するIP アドレスとポート番号
ListenBacklog backlogsM
保留状態のコネクションのキューの最大長
ListenCoresBucketsRatio ratio 0 (disabled) sM
Ratio between the number of CPU cores (online) and the number of listeners' buckets
LoadFile filename [filename] ...svE
指定されたオブジェクトファイルやライブラリをリンクする
LoadModule module filenamesvE
オブジェクトファイルやライブラリをリンクし、使用モジュールの リストに追加する
<Location URL-path|URL> ... </Location>svC
囲んだディレクティブをマッチする URL のみに適用
<LocationMatch regex> ... </LocationMatch>svC
囲んだディレクティブを正規表現にマッチする URL のみに 適用
LogFormat format|nickname [nickname] "%h %l %u %t \"%r\" +svB
ログファイルで使用する書式を設定する
LogIOTrackTTFB ON|OFF OFF svdhE
Enable tracking of time to first byte (TTFB)
LogLevel level warn svC
ErrorLog の冗長性を制御する
LogMessage message [hook=hook] [expr=expression] dX
Log user-defined message to error log
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Plug an authorization provider function into mod_authz_core
LuaCodeCache stat|forever|never stat svdhE
Configure the compiled code cache.
LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the access_checker phase of request processing
LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the check_user_id phase of request processing
LuaHookFixups /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the fixups phase of a request processing
LuaHookInsertFilter /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the insert_filter phase of request processing
LuaHookLog /path/to/lua/script.lua log_function_namesvdhE
Provide a hook for the access log phase of a request processing
LuaHookMapToStorage /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslate /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]svE
Provide a hook for the translate name phase of request processing
LuaHookTypeChecker /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the type_checker phase of request processing
LuaInherit none|parent-first|parent-last parent-first svdhE
Controls how parent configuration sections are merged into children
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content input filtering
LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]svdhE
Map a path to a lua handler
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content output filtering
LuaPackageCPath /path/to/include/?.soasvdhE
Add a directory to lua's package.cpath
LuaPackagePath /path/to/include/?.luasvdhE
Add a directory to lua's package.path
LuaQuickHandler /path/to/script.lua hook_function_namesvE
Provide a hook for the quick handler of request processing
LuaRoot /path/to/a/directorysvdhE
Specify the base path for resolving relative paths for mod_lua directives
LuaScope once|request|conn|thread|server [min] [max] once svdhE
One of once, request, conn, thread -- default is once
<Macro name [par1 .. parN]> ... </Macro>svdB
Define a configuration file macro
MaxConnectionsPerChild number 0 sM
Limit on the number of connections that an individual child server will handle during its life
MaxKeepAliveRequests number 100 svC
持続的な接続上で許可されるリクエストの数
MaxMemFree KBytes 0 sM
free() が呼ばれない限り、 主メモリアロケータが保持し続けられるメモリの最大量
MaxRangeOverlaps default | unlimited | none | number-of-ranges 20 svdC
Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
MaxRangeReversals default | unlimited | none | number-of-ranges 20 svdC
Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
MaxRanges default | unlimited | none | number-of-ranges 200 svdC
Number of ranges allowed before returning the complete resource
MaxRequestWorkers numbersM
Maximum number of connections that will be processed simultaneously
MaxSpareServers number 10 sM
アイドルな子サーバプロセスの最大個数
MaxSpareThreads numbersM
アイドルスレッドの最大数
MaxThreads number 2048 sM
Set the maximum number of worker threads
MDActivationDelay durationsX
How long to delay activation of new certificates
MDBaseServer on|off off sX
Control if base server may be managed or only virtual hosts.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sX
Type of ACME challenge used to prove domain ownership.
MDCertificateAgreement acceptedsX
You confirm that you accepted the Terms of Service of the Certificate Authority.
MDCertificateAuthority url letsencrypt sX
The URL(s) of the ACME Certificate Authority to use.
MDCertificateCheck name urlsX
Set name and URL pattern for a certificate monitoring site.
MDCertificateFile path-to-pem-filesX
Specify a static certificate file for the MD.
MDCertificateKeyFile path-to-filesX
Specify a static private key for for the static cerrtificate.
MDCertificateMonitor name url crt.sh https://crt. +sX
The URL of a certificate log monitor.
MDCertificateProtocol protocol ACME sX
The protocol to use with the Certificate Authority.
MDCertificateStatus on|off on sX
Exposes public certificate information in JSON.
MDChallengeDns01 path-to-commandsX
Set the command for setup/teardown of dns-01 challenges
MDChallengeDns01Version 1|2 1 sX
Set the type of arguments to call MDChallengeDns01 with
MDCheckInterval duration 12h sX
Determines how often certificates are checked
MDContactEmail addresssX
Email address used for account registration
MDDriveMode always|auto|manual auto sX
former name of MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sX
Set the external account binding keyid and hmac values to use at CA
MDHttpProxy urlsX
Define a proxy for outgoing connections.
MDMatchNames all|servernames all sX
Determines how DNS names are matched to vhosts
MDMember hostnamesX
Additional hostname for the managed domain.
MDMembers auto|manual auto sX
Control if the alias domain names are automatically added.
MDMessageCmd path-to-cmd optional-argssX
Handle events for Manage Domains
MDMustStaple on|off off sX
Control if new certificates carry the OCSP Must Staple flag.
MDNotifyCmd path [ args ]sX
Run a program when a Managed Domain is ready.
MDomain dns-name [ other-dns-name... ] [auto|manual]sX
Define list of domain names that belong to one group.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sX
Container for directives applied to the same managed domains.
MDPortMap map1 [ map2 ] http:80 https:443 sX
Map external to internal ports for domain ownership verification.
MDPrivateKeys type [ params... ] RSA 2048 sX
Set type and size of the private keys generated.
MDProfile namesX
Use a specific ACME profile from the CA
MDProfileMandatory on|off off sX
Control if an MDProfile is mandatory.
MDRenewMode always|auto|manual auto sX
Controls if certificates shall be renewed.
MDRenewWindow duration 33% sX
Control when a certificate will be renewed.
MDRequireHttps off|temporary|permanent off sX
Redirects http: traffic to https: for Managed Domains.
MDRetryDelay duration 5s sX
Time length for first retry, doubled on every consecutive error.
MDRetryFailover number 13 sX
The number of errors before a failover to another CA is triggered
MDServerStatus on|off on sX
Control if Managed Domain information is added to server-status.
MDStapleOthers on|off on sX
Enable stapling for certificates not managed by mod_md.
MDStapling on|off off sX
Enable stapling for all or a particular MDomain.
MDStaplingKeepResponse duration 7d sX
Controls when old responses should be removed.
MDStaplingRenewWindow duration 33% sX
Control when the stapling responses will be renewed.
MDStoreDir path md sX
Path on the local file system to store the Managed Domains data.
MDStoreLocks on|off|duration off sX
Configure locking of store for updates
MDWarnWindow duration 10% sX
Define the time window when you want to be warned about an expiring certificate.
MemcacheConnTTL num[units] 15s svE
Keepalive time for idle connections
MergeSlashes ON|OFF ON svC
Controls whether the server merges consecutive slashes in URLs.
MergeTrailers [on|off] off svC
Determines whether trailers are merged into headers
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 containing 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
ModemStandard V.21|V.26bis|V.32|V.34|V.92dX
Modem standard to simulate
ModMimeUsePathInfo On|Off Off d
path_info コンポーネントをファイル名の一部として扱うように mod_mime に通知する
MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers [Handlers|Filters] NegotiatedOnly svdh
MultiViews でのマッチングの検索に含ませる ファイルのタイプを指定する
Mutex mechanism [default|mutex-name] ... [OmitPID] default sC
Configures mutex mechanism and lock file directory for all or specified mutexes
NameVirtualHost addr[:port]sC
名前ベースのバーチャルホストのための IP アドレスを指定
NoProxy host [host] ...svE
直接接続する ホスト、ドメイン、ネットワーク
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 dhE
デフォルトのアクセス可能な状態と、AllowDeny が評価される順番を制御する
OutputSed sed-commanddhX
Sed command for filtering response content
PassEnv env-variable [env-variable] ...svdhB
シェルからの環境変数を渡す
PidFile filename logs/httpd.pid sM
デーモンのプロセス ID をサーバが記録するためのファイル
PrivilegesMode FAST|SECURE|SELECTIVE FAST svdX
Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Protocol protocolsvC
Protocol for a listening socket
ProtocolEcho On|Off Off svX
エコーサーバの有効無効を設定します。
Protocols protocol ... http/1.1 svC
Protocols available for a server/virtual host
ProtocolsHonorOrder On|Off On svC
Determines if order of Protocols determines precedence during negotiation
<Proxy wildcard-url> ...</Proxy>svE
プロキシされるリソースに適用されるコンテナ
Proxy100Continue Off|On On svdE
Forward 100-continue expectation to the origin server
ProxyAddHeaders Off|On On svdE
Add proxy information in X-Forwarded-* headers
ProxyBadHeader IsError|Ignore|StartBody IsError svE
応答におかしなヘッダがある場合の扱い方を決める
ProxyBlock *|word|host|domain [word|host|domain] ...svE
プロキシ接続を禁止する語句、ホスト名、ドメインを指定する
ProxyDomain DomainsvE
プロキシされたリクエストのデフォルトのドメイン名
ProxyErrorOverride On|Off Off svE
プロキシされたコンテンツのエラーページを上書きする
ProxyExpressDBMFile pathnamesvE
Pathname to DBM file.
ProxyExpressDBMType type default svE
DBM type of file.
ProxyExpressEnable on|off off svE
Enable the module functionality.
ProxyFCGIBackendType FPM|GENERIC FPM svdhE
Specify the type of backend FastCGI application
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]svdhE
Allow variables sent to FastCGI servers to be fixed up
ProxyFtpDirCharset character_set ISO-8859-1 svdE
Define the character set for proxied FTP listings
ProxyFtpEscapeWildcards on|off on svdE
Whether wildcards in requested filenames are escaped when sent to the FTP server
ProxyFtpListOnWildcard on|off on svdE
Whether wildcards in requested filenames trigger a file listing
ProxyHCExpr name {ap_expr expression}svE
Creates a named condition expression to use to determine health of the backend based on its response
ProxyHCTemplate name parameter=setting [...]svE
Creates a named template for setting various health check parameters
ProxyHCTPsize size 16 sE
Sets the total server-wide size of the threadpool used for the health check workers
ProxyHTMLBufSize bytes 8192 svdB
Sets the buffer size increment for buffering inline scripts and stylesheets.
ProxyHTMLCharsetOut Charset | *svdB
Specify a charset for mod_proxy_html output.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
svdB
Sets an HTML or XHTML document type declaration.
ProxyHTMLEnable On|Off Off svdB
Turns the proxy_html filter on or off.
ProxyHTMLEvents attribute [attribute ...]svdB
Specify attributes to treat as scripting events.
ProxyHTMLExtended On|Off Off svdB
Determines whether to fix links in inline scripts, stylesheets, and scripting events.
ProxyHTMLFixups [lowercase] [dospath] [reset]svdB
Fixes for simple HTML errors.
ProxyHTMLInterp On|Off Off svdB
Enables per-request interpolation of ProxyHTMLURLMap rules.
ProxyHTMLLinks element attribute [attribute2 ...]svdB
Specify HTML elements that have URL attributes to be rewritten.
ProxyHTMLMeta On|Off Off svdB
Turns on or off extra pre-parsing of metadata in HTML <head> sections.
ProxyHTMLStripComments On|Off Off svdB
Determines whether to strip HTML comments.
ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]svdB
Defines a rule to rewrite HTML links
ProxyIOBufferSize bytes 8192 svE
内部データスループットバッファのサイズを決定する
<ProxyMatch regex> ...</ProxyMatch>svE
正規表現でのマッチによるプロキシリソース用のディレクティブコンテナ
ProxyMaxForwards number 10 svE
リクエストがフォワードされるプロキシの最大数
ProxyPass [path] !|url [key=value key=value ...]]svdE
リモートサーバをローカルサーバの URL 空間にマップする
ProxyPassInherit On|Off On svE
Inherit ProxyPass directives defined from the main server
svdE
Enable Environment Variable interpolation in Reverse Proxy configurations
svdE
Maps remote servers into the local server URL-space using regular expressions
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
フォワード (標準の) プロキシリクエストを有効にする
ProxySCGIInternalRedirect On|Off|Headername On svdE
Enable or disable internal redirect responses from the backend
ProxySCGISendfile On|Off|Headername Off svdE
Enable evaluation of X-Sendfile pseudo response header
dE
Set various Proxy balancer or member parameters
ProxySourceAddress addresssvE
Set local IP address for outgoing proxy connections
svE
Show Proxy LoadBalancer status in mod_status
ProxyTimeout seconds 300 svE
プロキシされたリクエストのネットワークタイムアウト
ProxyVia On|Off|Full|Block Off svE
プロキシされたリクエストの Via HTTP 応答ヘッダ により提供される情報
ProxyWebsocketFallbackToProxyHttp On|Off On svE
Instructs this module to let mod_proxy_http handle the request
QualifyRedirectURL On|Off Off svdC
Controls whether the REDIRECT_URL environment variable is fully qualified
ReadBufferSize bytes 8192 svdC
Size of the buffers used to read data
ReadmeName filenamesvdhB
インデックス一覧の最後に挿入されるファイルの名前
ReceiveBufferSize bytes 0 sM
TCP 受信バッファサイズ
Redirect [status] URL-path URLsvdhB
クライアントが違う URL を取得するように外部へのリダイレクトを 送る
RedirectMatch [status] regex URLsvdhB
現在の URL への正規表現のマッチにより 外部へのリダイレクトを送る
RedirectPermanent URL-path URLsvdhB
クライアントが違う URL を取得するように外部への永久的な リダイレクトを送る
RedirectRelative On|Off Off svdB
Allows relative redirect targets.
RedirectTemp URL-path URLsvdhB
クライアントが違う URL を取得するように外部への一時的な リダイレクトを送る
RedisConnPoolTTL num[units] 15s svE
TTL used for the connection pool with the Redis server(s)
RedisTimeout num[units] 5s svE
R/W timeout used for the connection with the Redis server(s)
ReflectorHeader inputheader [outputheader]svdhB
Reflect an input header to the output headers
RegexDefaultOptions [none] [+|-]option [[+|-]option] ... DOTALL DOLLAR_ENDON +sC
Allow to configure global/default options for regexes
RegisterHttpMethod method [method [...]]sC
Register non-standard HTTP methods
RemoteIPHeader header-fieldsvB
Declare the header field which should be parsed for useragent IP addresses
RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPInternalProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPProxiesHeader HeaderFieldNamesvB
Declare the header field which will record all intermediate IP addresses
RemoteIPProxyProtocol On|OffsvB
Enable or disable PROXY protocol handling
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]svB
Disable processing of PROXY header for certain hosts or networks
RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPTrustedProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
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 リクエストヘッダの設定
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate] handshake=0 header= +svE
Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Require [not] entity-name [entity-name] ...dhB
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll> ... </RequireAll>dhB
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny> ... </RequireAny>dhB
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone> ... </RequireNone>dhB
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
RewriteBase URL-pathdhE
Sets the base URL for per-directory rewrites
RewriteCond TestString CondPattern [flags]svdhE
Defines a condition under which rewriting will take place
RewriteEngine on|off off svdhE
Enables or disables runtime rewriting engine
RewriteMap MapName MapType:MapSource [MapTypeOptions] svE
Defines a mapping function for key-lookup
RewriteOptions OptionssvdhE
Sets some special options for the rewrite engine
RewriteRule Pattern Substitution [flags]svdhE
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 dhE
ホストレベルのアクセス制御とユーザ認証との相互作用を指定
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 sB
CGI デーモンとの通信に使われるソケットのファイル名の接頭辞
SecureListen [IP-address:]portnumber Certificate-Name [MUTUAL]sB
Enables SSL encryption for the specified port
SeeRequestTail On|Off Off sC
Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
SendBufferSize bytes 0 sM
TCP バッファサイズ
ServerAdmin email-address|URLsvC
サーバがクライアントに送るエラーメッセージに含める電子メールの アドレス
ServerAlias hostname [hostname] ...vC
リクエストを名前ベースのバーチャルホストにマッチさせているときに 使用されるホストの別名
ServerLimit numbersM
設定可能なサーバプロセス数の上限
ServerName [scheme://]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 応答ヘッダを設定する
Session On|Off Off svdhE
Enables a session for the current directory or location
SessionCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session
SessionCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session
SessionCookieRemove On|Off Off svdhE
Control for whether session cookies should be removed from incoming HTTP headers
SessionCryptoCipher name aes256 svdhX
The crypto cipher to be used to encrypt the session
SessionCryptoDriver name [param[=value]]sX
The crypto driver to be used to encrypt the session
SessionCryptoPassphrase secret [ secret ... ] svdhX
The key used to encrypt the session
SessionCryptoPassphraseFile filenamesvdX
File containing keys used to encrypt the session
SessionDBDCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session ID
SessionDBDCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session ID
SessionDBDCookieRemove On|Off On svdhE
Control for whether session ID cookies should be removed from incoming HTTP headers
SessionDBDDeleteLabel label deletesession svdhE
The SQL query to use to remove sessions from the database
SessionDBDInsertLabel label insertsession svdhE
The SQL query to use to insert sessions into the database
SessionDBDPerUser On|Off Off svdhE
Enable a per user session
SessionDBDSelectLabel label selectsession svdhE
The SQL query to use to select sessions from the database
SessionDBDUpdateLabel label updatesession svdhE
The SQL query to use to update existing sessions in the database
SessionEnv On|Off Off svdhE
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionExclude pathsvdhE
Define URL prefixes for which a session is ignored
SessionExpiryUpdateInterval interval 0 (always update) svdhE
Define the number of seconds a session's expiry may change without the session being updated
SessionHeader headersvdhE
Import session updates from a given HTTP response header
SessionInclude pathsvdhE
Define URL prefixes for which a session is valid
SessionMaxAge maxage 0 svdhE
Define a maximum age in seconds for a session
SetEnv env-variable valuesvdhB
環境変数を設定する
SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
リクエストの属性に基づいて環境変数を設定する
svdhB
Sets environment variables based on an ap_expr expression
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 のエラーがあったときに表示されるエラーメッセージ
SSIETag on|off off dhB
Controls whether ETags are generated by the server.
SSILastModified on|off off dhB
Controls whether Last-Modified headers are generated by the server.
SSILegacyExprParser on|off off dhB
Enable compatibility mode for conditional expressions.
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
SSLCARevocationCheck chain|leaf|none [flags ...] none svE
Enable CRL-based revocation checking
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-path|certidsvE
Server PEM-encoded X.509 certificate data file or token identifier
SSLCertificateKeyFile file-path|keyidsvE
Server PEM-encoded private key file
SSLCipherSuite [protocol] cipher-spec DEFAULT (depends on +svdhE
Cipher Suite available for negotiation in SSL handshake
SSLCompression on|off off svE
Enable compression on the SSL level
SSLCryptoDevice engine builtin sE
Enable use of a cryptographic hardware accelerator
SSLEngine on|off|optional off svE
SSL Engine Operation Switch
SSLFIPS on|off off sE
SSL FIPS mode Switch
SSLHonorCipherOrder on|off off svE
Option to prefer the server's cipher preference order
SSLInsecureRenegotiation on|off off svE
Option to enable support for insecure renegotiation
SSLOCSPDefaultResponder urisvE
Set the default responder URI for OCSP validation
SSLOCSPEnable on|leaf|off off svE
Enable OCSP validation of the client certificate chain
SSLOCSPNoverify on|off off svE
skip the OCSP responder certificates verification
SSLOCSPOverrideResponder on|off off svE
Force use of the default responder URI for OCSP validation
SSLOCSPProxyURL urlsvE
Proxy URL to use for OCSP requests
SSLOCSPResponderCertificateFile filesvE
Set of trusted PEM encoded OCSP responder certificates
SSLOCSPResponderTimeout seconds 10 svE
Timeout for OCSP queries
SSLOCSPResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP responses
SSLOCSPResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP response validation
SSLOCSPUseRequestNonce on|off on svE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd command-name command-valuesvE
Configure OpenSSL parameters through its SSL_CONF API
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 -SSLv3 (up to 2 +svE
Configure usable SSL/TLS protocol versions
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
SSLProxyCARevocationCheck chain|leaf|none none svE
Enable CRL-based revocation checking 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
SSLProxyCheckPeerCN on|off on svE
Whether to check the remote server certificate's CN field
SSLProxyCheckPeerExpire on|off on svE
Whether to check if remote server certificate is expired
SSLProxyCheckPeerName on|off on svE
Configure host name checking for remote server certificates
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +svE
Cipher Suite available for negotiation in SSL proxy handshake
SSLProxyEngine on|off off svE
SSL Proxy Engine Operation Switch
SSLProxyMachineCertificateChainFile filenamesvE
File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
SSLProxyMachineCertificateFile filenamesvE
File of concatenated PEM-encoded client certificates and keys to be used by the proxy
SSLProxyMachineCertificatePath directorysvE
Directory of PEM-encoded client certificates and keys to be used by the proxy
SSLProxyProtocol [+|-]protocol ... all -SSLv3 (up to 2 +svE
Configure usable SSL protocol flavors for proxy usage
SSLProxyVerify level none svE
Type of remote server Certificate verification
SSLProxyVerifyDepth number 1 svE
Maximum depth of CA Certificates in Remote Server Certificate verification
SSLRandomSeed context source [bytes]sE
Pseudo Random Number Generator (PRNG) seeding source
SSLRenegBufferSize bytes 131072 dhE
Set the size for the SSL renegotiation buffer
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
SSLSessionTicketKeyFile file-pathsvE
Persistent encryption/decryption key for TLS session tickets
SSLSessionTickets on|off on svE
Enable or disable use of TLS session tickets
SSLSRPUnknownUserSeed secret-stringsvE
SRP unknown user seed
SSLSRPVerifierFile file-pathsvE
Path to SRP verifier file
SSLStaplingCache typesE
Configures the OCSP stapling cache
SSLStaplingErrorCacheTimeout seconds 600 svE
Number of seconds before expiring invalid responses in the OCSP stapling cache
SSLStaplingFakeTryLater on|off on svE
Synthesize "tryLater" responses for failed OCSP stapling queries
SSLStaplingForceURL urisvE
Override the OCSP responder URI specified in the certificate's AIA extension
SSLStaplingResponderTimeout seconds 10 svE
Timeout for OCSP stapling queries
SSLStaplingResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP stapling responses
SSLStaplingResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP stapling response validation
SSLStaplingReturnResponderErrors on|off on svE
Pass stapling related OCSP errors on to client
SSLStaplingStandardCacheTimeout seconds 3600 svE
Number of seconds before expiring responses in the OCSP stapling cache
SSLStrictSNIVHostCheck on|off off svE
Whether to allow non-SNI clients to access a name-based virtual host.
SSLUserName varnamesdhE
Variable name to determine user name
SSLUseStapling on|off off svE
Enable stapling of OCSP responses in the TLS handshake
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
起動時に生成されるスレッドの数
StrictHostCheck ON|OFF OFF svC
Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Substitute s/pattern/substitution/[infq]dhE
Pattern to filter the response content
SubstituteInheritBefore on|off off dhE
Change the merge order of inherited patterns
SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G) 1m dhE
Set the maximum line size
Suexec On|OffsB
Enable or disable the suEXEC feature
SuexecUserGroup User GroupsvE
CGI プログラムのユーザパーミッション、グループパーミッション
ThreadLimit numbersM
設定可能な子プロセス毎のスレッド数の上限を 設定します
ThreadsPerChild numbersM
子プロセスそれぞれに生成されるスレッド数
ThreadStackSize sizesM
クライアントのコネクションを受け持つスレッドが使用する スタックのバイト数
TimeOut seconds 60 svC
各イベントについて、リクエストを失敗させるまでにサーバが 待つ時間を設定
TraceEnable [on|off|extended] on sC
TRACE メソッドのリクエストに対する応答方法を決める
TransferLog file|pipesvB
ログファイルの位置を指定
TypesConfig file-path conf/mime.types s
mime.types ファイルの位置
UNCList hostname [hostname...]sC
Controls what UNC host names can be accessed by the server
UnDefine parameter-namesC
Undefine the existence of a variable
UndefMacro namesvdB
Undefine a macro
UnsetEnv env-variable [env-variable] ...svdhB
環境から変数を取り除く
Use name [value1 ... valueN] svdB
Use a macro
UseCanonicalName On|Off|Dns Off svdC
サーバが自分自身の名前とポートを決定する方法を設定する
UseCanonicalPhysicalPort On|Off Off svdC
自分自身の名前とポート番号を解決する方法を設定する
User unix-userid #-1 sB
The userid under which the server will answer requests
UserDir directory-filename [directory-filename] ...svB
ユーザ専用ディレクトリの位置
VHostCGIMode On|Off|Secure On vX
Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to subprocesses created by a virtual host.
VHostGroup unix-groupidvX
Sets the Group ID under which a virtual host runs.
VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to a virtual host.
VHostSecure On|Off On vX
Determines whether the server runs with enhanced security for the virtualhost.
VHostUser unix-useridvX
Sets the User ID under which a virtual host runs.
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
WatchdogInterval time-interval[s] 1 sB
Watchdog interval in seconds
XBitHack on|off|full off svdhB
実行ビットが設定されたファイルの SSI ディレクティブを 解析する
xml2EncAlias charset alias [alias ...]sB
Recognise Aliases for encoding values
xml2EncDefault namesvdhB
Sets a default encoding to assume when absolutely no information can be automatically detected
xml2StartParse element [element ...]svdhB
Advise the parser to skip leading junk.

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ext_filter.html.ko.euc-kr0000664000175100017510000004570614743132254023316 0ustar covenercovener mod_ext_filter - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_ext_filter

ֽ ƴմϴ. ֱٿ ϼ.
: ܺ α׷ ó Ŭ̾Ʈ
:Extension
:ext_filter_module
ҽ:mod_ext_filter.c

mod_ext_filter ϸ ϰ ͼ ִ. ǥԷ¿ а ǥ¿ α׷(, н ɾ) ġ ͷ ִ. ̷ ʹ ġ API ġ μ ȿ Ǵ Ϳ ſ , ִ:

ϱ⿡ , mod_ext_filter Ͽ ͸  ִ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_file_cache.html.ko.euc-kr0000664000175100017510000003472014743132254023205 0ustar covenercovener mod_file_cache - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_file_cache

ֽ ƴմϴ. ֱٿ ϼ.
:޸𸮿 ϵ ij
:Experimental
:file_cache_module
ҽ:mod_file_cache.c

ؼ ؾ Ѵ. mod_file_cache Ͽ Ʈ ⶧ IJ б ٶ.

ʰ ûǴ ij Ͽ ϸ ִ. mod_file_cache ûǴ ΰ ij Ѵ. þ Ͽ mod_file_cache (open) mmap() ƴϸ ڵ Ѵ. ϱ ʿ ۾ Ϻθ (Ư ۾) û Ź ϴ Ҷ ѹ Ͽ ϰ Ѵ.

: CGI α׷̳ Ư ڵ鷯 ϴ ӵ . ġ core ڵ鷯 ϴ ϹϿ ȴ.

ġ 1.3 ִ mod_mmap_static Ȯ .

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ident.html.ja.utf80000664000175100017510000002560414743132254021730 0ustar covenercovener mod_ident - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_ident

翻訳済み言語:  en  |  fr  |  ja  |  ko 

説明:RFC 1413 ident lookups
ステータス:Extension
モジュール識別子:ident_module
ソースファイル:mod_ident.c
互換性:Apache 2.1 で使用可能

概要

このモジュールはリモートホストの RFC 1413 互換デーモン にコネクションの所有者を訊きます。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

IdentityCheck ディレクティブ

説明:リモートユーザの RFC 1413 によるアイデンティティのロギングを 有効にする
構文:IdentityCheck On|Off
デフォルト:IdentityCheck Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Extension
モジュール:mod_ident
互換性:Apache 2.1 で core から移動

このディレクティブは、クライアントマシン上で identd やそれに類似したデーモンが動作しているときに、 それぞれの接続に対して RFC 1413 に準処したリモートユーザの 名前のロギングを行なうようにします。 この情報は、%...l フォーマット文字列を使ってアクセスログに収集されます。

ここで得られた情報は簡単なユーザ追跡に使う以外は、 まったく信頼するべきではありません。

すべてのリクエストに対してルックアップが行なわれますので、 深刻な遅延の問題を起こすかもしれないことに注意してください。 (訳注: 例えばクライアント側に) ファイアウォールやプロキシサーバがあると、 ルックアップが失敗し、各リクエストに IdentityCheckTimeoutで定義されている遅延が加わることに なる可能性があります。 従って、一般的にはインターネットからアクセス可能なパブリックなサーバで 有益なものではありません。

top

IdentityCheckTimeout ディレクティブ

説明:Ident リクエストがタイムアウトするまでの期間を決める
構文:IdentityCheckTimeout seconds
デフォルト:IdentityCheckTimeout 30
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Extension
モジュール:mod_ident

このディレクティブは ident リクエストのタイムアウト時間を決めます。 デフォルトの値である 30 秒は、主にネットワーク遅延の考慮のために RFC 1413 により 推奨されています。しかし、おそらくローカルネットワークの速度に 合わせてタイムアウト値を調節するのがよいでしょう。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_headers.html.ko.euc-kr0000664000175100017510000004705114743132254022557 0ustar covenercovener mod_headers - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_headers

ֽ ƴմϴ. ֱٿ ϼ.
:HTTP û
:Extension
:headers_module
ҽ:mod_headers.c
:RequestHeader ġ 2.0 ִ

HTTP û ϰ ϴ þ Ѵ. ġų ü, ִ.

Support Apache!

þ

Bugfix checklist

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. 信 û ð û ϴµ ɸ ð ˷ִ MyHeader ߰Ѵ. Ŭ̾Ʈ ϸ ϰų Ŭ̾Ʈ ã ִ.

    Header add MyHeader "%D %t"

    信 .

    MyHeader: D=3775428 t=991424704447256

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

  4. û "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

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}s mod_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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.ko.euc-kr0000664000175100017510000057237315032765673023323 0ustar covenercovener þ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

þ

:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

ֽ ƴմϴ. ֱٿ ϼ.

ġ þ 뵵, ⺻, , Ҹ ش. ̵ þ Ѵ.

ù° þ ̸ 뵵 ˷ش. ι° þ ⺻ ִٸ ⺻ ش. ⺻ ʹ ٸ, "+" ȣ ˸.

° ׹° Ʒ ǥ þ ִ ҿ þ ¸ Ÿ.

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
sּ
vȣƮ
ddirectory
h.htaccess
CCore
MMPM
BBase
EExtension
XExperimental
TExternal
AcceptFilter protocol accept_filtersC
Configures optimizations for a Protocol's Listener 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 encoding 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 language-tag 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...] media-type [media-type] ...svdhB
assigns an output filter to a particular media-type
AddType media-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 Ͻý ҷ Ѵ
AliasPreservePath OFF|ON OFF svdB
Map the full path after the alias in a location.
Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
Controls which hosts can access an area of the server
AllowCONNECT port[-port] [port[-port]] ... 443 563 svE
Ports that are allowed to CONNECT through the proxy
AllowEncodedSlashes On|Off|NoDecode Off svC
Determines whether encoded path separators in URLs are allowed to be passed through
AllowMethods reset|HTTP-method [HTTP-method]... reset dX
Restrict access to the listed HTTP methods
AllowOverride All|None|directive-type [directive-type] ... None (2.3.9 and lat +dC
Types of directives that are allowed in .htaccess files
AllowOverrideList None|directive [directive-type] ... None dC
Individual 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
ȣ ùٸ ڿ ּ ˻
AsyncRequestWorkerFactor factorsM
Limit concurrent connections per process
AuthBasicAuthoritative On|Off On dhB
Ѻο ⿡ Ѱ Ѵ
AuthBasicFake off|username [password]dhB
Fake basic authentication using the given expressions for username and password
AuthBasicProvider On|Off|provider-name [provider-name] ... On dhB
ġ ڸ Ѵ
AuthBasicUseDigestAlgorithm MD5|Off Off dhB
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBDUserPWQuery querydE
SQL query to look up a password for a user
AuthDBDUserRealmQuery querydE
SQL query to look up a password hash for a user and realm.
AuthDBMGroupFile file-pathdhE
׷ ϴ ͺ̽ ϸ Ѵ
AuthDBMType default|SDBM|GDBM|NDBM|DB default dhE
ȣ ϴ ͺ̽ Ѵ
AuthDBMUserFile file-pathdhE
ڿ ȣ ϴ ͺ̽ ϸ Ѵ
AuthDigestAlgorithm MD5|MD5-sess MD5 dhX
digest authentication challenge response hash ϴ ˰ Ѵ
AuthDigestDomain URI [URI] ...dhX
digest authentication ȣ ϴ URI
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
Ŭ̾Ʈ ϱ Ҵϴ ޸𸮷
AuthFormAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthFormBody fieldname httpd_body dB
The name of a form field carrying the body of the request to attempt on successful login
AuthFormDisableNoStore On|Off Off dB
Disable the CacheControl no-store header on the login page
AuthFormFakeBasicAuth On|Off Off dB
Fake a Basic Authentication header
AuthFormLocation fieldname httpd_location dB
The name of a form field carrying a URL to redirect to on successful login
AuthFormLoginRequiredLocation urldB
The URL of the page to be redirected to should login be required
AuthFormLoginSuccessLocation urldB
The URL of the page to be redirected to should login be successful
AuthFormLogoutLocation uridB
The URL to redirect to after a user has logged out
AuthFormMethod fieldname httpd_method dB
The name of a form field carrying the method of the request to attempt on successful login
AuthFormMimetype fieldname httpd_mimetype dB
The name of a form field carrying the mimetype of the body of the request to attempt on successful login
AuthFormPassword fieldname httpd_password dB
The name of a form field carrying the login password
AuthFormProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthFormSitePassphrase secretdB
Bypass authentication checks for high traffic sites
AuthFormSize size 8192 dB
The largest size of the form in bytes that will be parsed for the login details
AuthFormUsername fieldname httpd_username dB
The name of a form field carrying the login username
AuthGroupFile file-pathdhB
׷ ϴ ϸ Ѵ
AuthLDAPAuthorizePrefix prefix AUTHORIZE_ dhE
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritative off|on on dhE
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDN distinguished-namedhE
Optional DN to use in binding to the LDAP server
AuthLDAPBindPassword passworddhE
Password used in conjunction with the bind DN
AuthLDAPCharsetConfig file-pathsE
Language to charset conversion configuration file
AuthLDAPCompareAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization comparisons
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 attribute member uniqueMember +dhE
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDN on|off on dhE
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUser off|on off dhE
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPattern regex substitution (.*) $1 (remote use +dhE
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepth Number 10 dhE
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttribute uiddhE
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDN on|off off dhE
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttribute attribute member uniqueMember +dhE
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClass LdapObjectClass groupOfNames groupO +dhE
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhB
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthName auth-domaindhB
Authorization realm for use in HTTP authentication
AuthnCacheContext directory|server|custom-string directory dB
Specify a context string for use in the cache key
AuthnCacheEnablesB
Enable Authn caching configured anywhere
AuthnCacheProvideFor authn-provider [...]dhB
Specify which authn provider(s) to cache for
AuthnCacheSOCache provider-name[:provider-args]sB
Select socache backend provider to use
AuthnCacheTimeout timeout (seconds) 300 (5 minutes) dhB
Set a timeout for cache entries
<AuthnProviderAlias baseProvider Alias> ... </AuthnProviderAlias>sB
Enclose a group of directives that represent an extension of a base authentication provider and referenced by the specified alias
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Enables a FastCGI application to handle the check_authn authentication hook.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Defines a FastCGI application as a provider for authentication and/or authorization
AuthType None|Basic|Digest|FormdhB
Type of user authentication
AuthUserFile file-pathdhB
ڸ ȣ ϴ ϸ Ѵ
AuthzDBDLoginToReferer On|Off Off dE
Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
AuthzDBDQuery querydE
Specify the SQL Query for the required operation
AuthzDBDRedirectQuery querydE
Specify a query to look up a login page for the user
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
ȣ ϴ ͺ̽ Ѵ
<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> sB
Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
AuthzSendForbiddenOnFailure On|Off Off dhB
Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
BalancerGrowth # 5 svE
Number of additional Balancers that can be added Post-configuration
BalancerInherit On|Off On svE
Inherit ProxyPassed Balancers/Workers from the main server
BalancerMember [balancerurl] url [key=value [key=value ...]]dE
Add a member to a load balancing group
BalancerPersist On|Off Off svE
Attempt to persist changes made by the Balancer Manager across restarts.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
BrotliCompressionMaxInputBlock valuesvE
Maximum input block size
BrotliCompressionQuality value 5 svE
Compression quality
BrotliCompressionWindow value 18 svE
Brotli sliding compression window size
BrotliFilterNote [type] notenamesvE
Places the compression ratio in a note for logging
BrowserMatch regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
HTTP User-Agent ȯ溯 Ѵ
BrowserMatchNoCase regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
ҹڸ ʰ User-Agent ȯ溯 Ѵ
sB
Buffer log entries in memory before writing to disk
BufferSize integer 131072 svdhE
Maximum size in bytes to buffer by the buffer filter
CacheDefaultExpire seconds 3600 (one hour) svX
ð ij ⺻ Ⱓ.
svdhX
Add an X-Cache-Detail header to the response.
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Ѵ
svdhX
Add an X-Cache header to the response.
CacheIgnoreCacheControl On|Off Off svX
Ŭ̾Ʈ ijʴ û Ѵ.
CacheIgnoreHeaders header-string [header-string] ... None svX
ij HTTP () ʴ´
CacheIgnoreNoLastMod On|Off Off svX
信 Last Modified ٴ Ѵ.
svX
Ignore query string when caching
svX
Ignore defined session identifiers encoded in the URL when caching
svX
Override the base URL of reverse proxied cache keys.
CacheLastModifiedFactor float 0.1 svX
LastModified ð ð ϴµ ϴ .
svX
Enable the thundering herd lock.
svX
Set the maximum possible age of a cache lock.
svX
Set the lock path directory.
CacheMaxExpire seconds 86400 (Ϸ) svX
ijϴ ʴ ִð
CacheMaxFileSize bytes 1000000 svX
ij ִũ (Ʈ )
svdhX
The minimum time in seconds to cache a document
CacheMinFileSize bytes 1 svX
ij ּũ (Ʈ )
CacheNegotiatedDocs On|Off Off svB
Allows content-negotiated documents to be cached by proxy servers
svX
Run the cache from the quick handler.
svdhX
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
svdhX
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheRoot directorysvX
ij 丮 root
CacheSocache type[:args]svE
The shared object cache implementation to use
CacheSocacheMaxSize bytes 102400 svdhE
The maximum size (in bytes) of an entry to be placed in the cache
CacheSocacheMaxTime seconds 86400 svdhE
The maximum time (in seconds) for a document to be placed in the cache
CacheSocacheMinTime seconds 600 svdhE
The minimum time (in seconds) for a document to be placed in the cache
CacheSocacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheSocacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
svdhX
Serve stale content in place of 5xx responses.
svdhX
Attempt to cache responses that the server reports as expired
svdhX
Attempt to cache requests or responses that have been marked as no-store.
svdhX
Attempt to cache responses that the server has marked as private
CGIDScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIMapExtension cgi-path .extensiondhC
Technique for locating the interpreter for CGI scripts
CGIPassAuth On|Off Off dhC
Enables passing HTTP authorization headers to scripts as CGI variables
CGIScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIVar variable ruledhC
Controls how some CGI variables are set
CharsetDefault charsetsvdhX
ȯ
CharsetOptions option [option] ... DebugLevel=0 NoImpl +svdhX
ȯ
CharsetSourceEnc charsetsvdhX
CheckBasenameMatch on|off On svdhE
Also match files with differing file name extensions.
svdhE
Limits the action of the speling module to case corrections
CheckSpelling on|off Off svdhE
Ѵ
ChrootDir /path/to/directorysB
Directory for apache to run chroot(8) after startup.
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
CookieHTTPOnly on|off off svdhE
Adds the 'HTTPOnly' attribute to the cookie
CookieName token Apache svdhE
Name of the tracking cookie
CookieSameSite None|Lax|StrictsvdhE
Adds the 'SameSite' attribute to the cookie
CookieSecure on|off off svdhE
Adds the 'Secure' attribute to the 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 HTTP Server attempts to switch before dumping core
CustomLog file|pipe format|nickname [env=[!]environment-variable]svB
α ̸ Ѵ
Dav On|Off|provider-name Off dE
WebDAV HTTP ޽带 Ѵ
DavBasePath root-pathdE
Configure repository root path
DavDepthInfinity on|off off svdE
PROPFIND Depth: Infinity û 㰡Ѵ
DavGenericLockDB file-pathsvdE
Location of the DAV lock database
DavLockDB file-pathsvE
DAV ͺ̽ ġ
DavLockDiscovery on|off on svdhE
Enable lock discovery
DavMinTimeout seconds 0 svdE
DAV ڿ ּҽð
DBDExptime time-in-seconds 300 svE
Keepalive time for idle connections
DBDInitSQL "SQL statement"svE
Execute an SQL statement after connecting to a database
DBDKeep number 2 svE
Maximum sustained number of connections
DBDMax number 10 svE
Maximum number of connections
DBDMin number 1 svE
Minimum number of connections
DBDParams param1=value1[,param2=value2]svE
Parameters for database connection
DBDPersist On|OffsvE
Whether to use persistent connections
DBDPrepareSQL "SQL statement" labelsvE
Define an SQL prepared statement
DBDriver namesvE
Specify an SQL driver
DefaultIcon url-pathsvdhB
Ư Ͽ
DefaultLanguage language-tagsvdhB
Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
DefaultRuntimeDir directory-path DEFAULT_REL_RUNTIME +sC
Base directory for the server run-time files
DefaultType media-type|none none svdhC
This directive has no effect other than to emit warnings if the value is not none. In prior versions, DefaultType would specify a default media type to assign to response content for which no other media type configuration could be found.
Define parameter-name [parameter-value]svdC
Define a variable
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
DeflateBufferSize value 8096 svE
zlib ѹ ũ
DeflateCompressionLevel valuesvE
ϴ°
DeflateFilterNote [type] notenamesvE
α׿ Ѵ
DeflateInflateLimitRequestBody valuesvdhE
Maximum size of inflated request bodies
DeflateInflateRatioBurst value 3 svdhE
Maximum number of times the inflation ratio for request bodies can be crossed
DeflateInflateRatioLimit value 200 svdhE
Maximum inflation ratio for request bodies
DeflateMemLevel value 9 svE
zlib Ҷ ϴ ޸𸮷
DeflateWindowSize value 15 svE
Zlib window size
Deny from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
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, sub-directories, and their contents.
DirectoryCheckHandler On|Off Off svdhB
Toggle how this module responds when another handler is configured
DirectoryIndex local-url [local-url] ... index.html svdhB
Ŭ̾Ʈ 丮 ûҶ ãƺ ڿ
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code off svdhB
Configures an external redirect for directory indexes.
<DirectoryMatch regex> ... </DirectoryMatch>svC
Enclose directives that apply to the contents of file-system directories matching a regular expression.
DirectorySlash On|Off On svdhB
̷ Ű
DocumentRoot directory-path "/usr/local/apache/ +svC
Directory that forms the main document tree visible from the web
DTracePrivileges On|Off Off sX
Determines whether the privileges required by dtrace are enabled.
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
<Else> ... </Else>svdhC
Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
<ElseIf expression> ... </ElseIf>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
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 Off svdhC
Use the kernel sendfile support to deliver files to the client
Error messagesvdhC
Abort configuration parsing with a custom error message
ErrorDocument error-code documentsvdhC
What the server will return to the client in case of an error
ErrorLog file-path|syslog[:[facility][:tag]] logs/error_log (Uni +svC
Location where the server will log errors
ErrorLogFormat [connection|request] formatsvC
Format specification for error log entries
ExamplesvdhX
ġ API ϱ þ
ExpiresActive On|OffsvdhE
Expires Ѵ
ExpiresByType MIME-type <code>secondssvdhE
MIME type Expires Ѵ
ExpiresDefault <code>secondssvdhE
ð ϴ ⺻ ˰
ExtendedStatus On|Off Off[*] sC
Keep track of extended status information for each request
ExtFilterDefine filtername parameterssE
ܺ ͸ Ѵ
ExtFilterOptions option [option] ... DebugLevel=0 NoLogS +dE
mod_ext_filter ɼ Ѵ
svdhB
Define a default URL for requests that don't map to a file
FileETag component ... MTime Size svdhC
File attributes used to create the ETag HTTP response header for static files
<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 ...svdhB
Configure the filter chain
FilterDeclare filter-name [type]svdhB
Declare a smart filter
FilterProtocol filter-name [provider-name] proto-flagssvdhB
Deal with correct HTTP protocol handling
FilterProvider filter-name provider-name expressionsvdhB
Register a content filter
FilterTrace filter-name levelsvdB
Get debug/diagnostic information from mod_filter
FlushMaxPipelined number 5 svC
Maximum number of pipelined responses above which they are flushed to the network
FlushMaxThreshold number-of-bytes 65535 svC
Threshold above which pending data are flushed to the network
ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
Action to take if a single acceptable document is not found
ForceType media-type|NonedhC
Forces all matching files to be served with the specified media type in the HTTP Content-Type header field
ForensicLog filename|pipesvE
Sets filename of the forensic log
GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]sB
Sets filename and format of log file
GprofDir /tmp/gprof/|/tmp/gprof/%svC
Directory to write gmon.out profiling data to.
GracefulShutdownTimeout seconds 0 sM
Specify a timeout after which a gracefully shutdown server will exit.
Group unix-group #-1 sB
Group under which the server will answer requests
H2CopyFiles on|off off svdhE
Determine file handling in responses
H2Direct on|off on for h2c, off for +svE
H2 Direct Protocol Switch
H2EarlyHint name valuesvdhE
Add a response header to be picked up in 103 Early Hints
H2EarlyHints on|off off svE
Determine sending of 103 status codes
H2MaxDataFrameLen n 0 svE
Maximum bytes inside a single HTTP/2 DATA frame
H2MaxHeaderBlockLen n 0 svE
Maximum size of response headers
H2MaxSessionStreams n 100 svE
Maximum number of active streams per HTTP/2 session.
H2MaxWorkerIdleSeconds n 600 sE
Maximum number of seconds h2 workers remain idle until shut down.
H2MaxWorkers nsE
Maximum number of worker threads to use per child process.
H2MinWorkers nsE
Minimal number of worker threads to use per child process.
H2ModernTLSOnly on|off on svE
Require HTTP/2 connections to be "modern TLS" only
H2OutputBuffering on|off on svE
Determine buffering behaviour of output
H2Padding numbits 0 svE
Determine the range of padding bytes added to payload frames
H2ProxyRequests on|off off svE
En-/Disable forward proxy requests via HTTP/2
H2Push on|off on svdhE
H2 Server Push Switch
H2PushDiarySize n 256 svE
H2 Server Push Diary Size
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 svE
H2 Server Push Priority
H2PushResource [add] path [critical]svdhE
Declares resources for early pushing to the client
H2SerializeHeaders on|off off svE
Serialize Request/Response Processing Switch
H2StreamMaxMemSize bytes 65536 svE
Maximum amount of output data buffered per stream.
H2StreamTimeout time-interval[s]svdE
Maximum time waiting when sending/receiving data to stream processing
H2TLSCoolDownSecs seconds 1 svE
Configure the number of seconds of idle time on TLS before shrinking writes
H2TLSWarmUpSize amount 1048576 svE
Configure the number of bytes on TLS connection before doing max writes
H2Upgrade on|off on for h2c, off for +svdhE
H2 Upgrade Protocol Switch
H2WebSockets on|off off svE
En-/Disable WebSockets via HTTP/2
H2WindowSize bytes 65535 svE
Size of Stream Window for upstream data.
Header [condition] set|append|add|unset|echo header [value] [early|env=[!]variable]svdhE
HTTP Ѵ
HeaderName filenamesvdhB
ϸ ̸
HeartbeatAddress addr:portsX
Multicast address for heartbeat packets
HeartbeatListen addr:portsX
multicast address to listen for incoming heartbeat requests
HeartbeatMaxServers number-of-servers 10 sX
Specifies the maximum number of servers that will be sending heartbeat requests to this server
HeartbeatStorage file-path logs/hb.dat sX
Path to store heartbeat data when using flat-file storage
HeartbeatStorage file-path logs/hb.dat sX
Path to read heartbeat data
HostnameLookups On|Off|Double Off svdC
Enables DNS lookups on client IP addresses
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +svC
Modify restrictions on HTTP Request Messages
IdentityCheck On|Off Off svdE
RFC 1413 ſ α׿ Ѵ
IdentityCheckTimeout seconds 30 svdE
ident û ð Ѵ
<If expression> ... </If>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime
<IfDefine [!]parameter-name> ... </IfDefine>svdhC
Encloses directives that will be processed only if a test is true at startup
<IfDirective [!]directive-name> ... </IfDirective>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific directive
<IfFile [!]filename> ... </IfFile>svdhC
Encloses directives that will be processed only if file exists at startup
<IfModule [!]module-file|module-identifier> ... </IfModule>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific module
<IfSection [!]section-name> ... </IfSection>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific section directive
<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-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IncludeOptional file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
svdhB
Inserts text in the HEAD section of an index page.
IndexIgnore file [file] ...svdhB
丮 Ͽ ϸ ߰Ѵ
IndexIgnoreReset ON|OFFsvdhB
Empties the list of files to hide when listing a directory
IndexOptions [+|-]option [[+|-]option] ...svdhB
IndexOrderDefault Ascending|Descending Name|Date|Size|Description Ascending Name svdhB
丮 ⺻ Ѵ
IndexStyleSheet url-pathsvdhB
丮 Ͽ CSS ŸϽƮ ߰Ѵ
InputSed sed-commanddhX
Sed command to filter request data (typically POST data)
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 num[ms] 5 svC
Amount of time the server will wait for subsequent requests on a persistent connection
KeptBodySize maximum size in bytes 0 dB
Keep the request body instead of discarding it up to the specified maximum size, for potential use by filters such as mod_include.
LanguagePriority MIME-lang [MIME-lang] ...svdhB
The precedence 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
LDAPConnectionPoolTTL n -1 svE
Discard backend connections that have been sitting in the connection pool too long
LDAPConnectionTimeout secondssE
Specifies the socket connection timeout in seconds
LDAPLibraryDebug 7sE
Enable debugging in the LDAP SDK
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
LDAPReferralHopLimit numberdhE
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferrals On|Off|default On dhE
Enable referral chasing during queries to the LDAP server.
LDAPRetries number-of-retries 3 sE
Configures the number of LDAP server retries.
LDAPRetryDelay seconds 0 sE
Configures the delay between LDAP server retries.
LDAPSharedCacheFile directory-path/filenamesE
Sets the shared memory cache file
LDAPSharedCacheSize bytes 500000 sE
Size in bytes of the shared-memory cache
LDAPTimeout seconds 60 sE
Specifies the timeout for LDAP search and bind operations, in seconds
LDAPTrustedClientCert type directory-path/filename/nickname [password]dhE
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 typesvE
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>dhC
Restrict enclosed access controls to only certain HTTP methods
<LimitExcept method [method] ... > ... </LimitExcept>dhC
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 1073741824 svdhC
Restricts the total size of the HTTP request body sent from the client
LimitRequestFields number 100 svC
Limits the number of HTTP request header fields that will be accepted from the client
LimitRequestFieldSize bytes 8190 svC
Limits the size of the HTTP request header allowed from the client
LimitRequestLine bytes 8190 svC
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:]portnumber [protocol]sM
IP addresses and ports that the server listens to
ListenBackLog backlog 511 sM
Maximum length of the queue of pending connections
ListenCoresBucketsRatio ratio 0 (disabled) sM
Ratio between the number of CPU cores (online) and the number of listeners' buckets
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
LogFormat format|nickname [nickname] "%h %l %u %t \"%r\" +svB
αϿ Ѵ
LogIOTrackTTFB ON|OFF OFF svdhE
Enable tracking of time to first byte (TTFB)
LogLevel [module:]level [module:level] ... warn svdC
Controls the verbosity of the ErrorLog
LogMessage message [hook=hook] [expr=expression] dX
Log user-defined message to error log
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Plug an authorization provider function into mod_authz_core
LuaCodeCache stat|forever|never stat svdhE
Configure the compiled code cache.
LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the access_checker phase of request processing
LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the check_user_id phase of request processing
LuaHookFixups /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the fixups phase of a request processing
LuaHookInsertFilter /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the insert_filter phase of request processing
LuaHookLog /path/to/lua/script.lua log_function_namesvdhE
Provide a hook for the access log phase of a request processing
LuaHookMapToStorage /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslate /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]svE
Provide a hook for the translate name phase of request processing
LuaHookTypeChecker /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the type_checker phase of request processing
LuaInherit none|parent-first|parent-last parent-first svdhE
Controls how parent configuration sections are merged into children
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content input filtering
LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]svdhE
Map a path to a lua handler
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content output filtering
LuaPackageCPath /path/to/include/?.soasvdhE
Add a directory to lua's package.cpath
LuaPackagePath /path/to/include/?.luasvdhE
Add a directory to lua's package.path
LuaQuickHandler /path/to/script.lua hook_function_namesvE
Provide a hook for the quick handler of request processing
LuaRoot /path/to/a/directorysvdhE
Specify the base path for resolving relative paths for mod_lua directives
LuaScope once|request|conn|thread|server [min] [max] once svdhE
One of once, request, conn, thread -- default is once
<Macro name [par1 .. parN]> ... </Macro>svdB
Define a configuration file macro
MaxConnectionsPerChild number 0 sM
Limit on the number of connections that an individual child server will handle during its life
MaxKeepAliveRequests number 100 svC
Number of requests allowed on a persistent connection
MaxMemFree KBytes 2048 sM
Maximum amount of memory that the main allocator is allowed to hold without calling free()
MaxRangeOverlaps default | unlimited | none | number-of-ranges 20 svdC
Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
MaxRangeReversals default | unlimited | none | number-of-ranges 20 svdC
Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
MaxRanges default | unlimited | none | number-of-ranges 200 svdC
Number of ranges allowed before returning the complete resource
MaxRequestWorkers numbersM
Maximum number of connections that will be processed simultaneously
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
MDActivationDelay durationsX
How long to delay activation of new certificates
MDBaseServer on|off off sX
Control if base server may be managed or only virtual hosts.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sX
Type of ACME challenge used to prove domain ownership.
MDCertificateAgreement acceptedsX
You confirm that you accepted the Terms of Service of the Certificate Authority.
MDCertificateAuthority url letsencrypt sX
The URL(s) of the ACME Certificate Authority to use.
MDCertificateCheck name urlsX
Set name and URL pattern for a certificate monitoring site.
MDCertificateFile path-to-pem-filesX
Specify a static certificate file for the MD.
MDCertificateKeyFile path-to-filesX
Specify a static private key for for the static cerrtificate.
MDCertificateMonitor name url crt.sh https://crt. +sX
The URL of a certificate log monitor.
MDCertificateProtocol protocol ACME sX
The protocol to use with the Certificate Authority.
MDCertificateStatus on|off on sX
Exposes public certificate information in JSON.
MDChallengeDns01 path-to-commandsX
Set the command for setup/teardown of dns-01 challenges
MDChallengeDns01Version 1|2 1 sX
Set the type of arguments to call MDChallengeDns01 with
MDCheckInterval duration 12h sX
Determines how often certificates are checked
MDContactEmail addresssX
Email address used for account registration
MDDriveMode always|auto|manual auto sX
former name of MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sX
Set the external account binding keyid and hmac values to use at CA
MDHttpProxy urlsX
Define a proxy for outgoing connections.
MDMatchNames all|servernames all sX
Determines how DNS names are matched to vhosts
MDMember hostnamesX
Additional hostname for the managed domain.
MDMembers auto|manual auto sX
Control if the alias domain names are automatically added.
MDMessageCmd path-to-cmd optional-argssX
Handle events for Manage Domains
MDMustStaple on|off off sX
Control if new certificates carry the OCSP Must Staple flag.
MDNotifyCmd path [ args ]sX
Run a program when a Managed Domain is ready.
MDomain dns-name [ other-dns-name... ] [auto|manual]sX
Define list of domain names that belong to one group.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sX
Container for directives applied to the same managed domains.
MDPortMap map1 [ map2 ] http:80 https:443 sX
Map external to internal ports for domain ownership verification.
MDPrivateKeys type [ params... ] RSA 2048 sX
Set type and size of the private keys generated.
MDProfile namesX
Use a specific ACME profile from the CA
MDProfileMandatory on|off off sX
Control if an MDProfile is mandatory.
MDRenewMode always|auto|manual auto sX
Controls if certificates shall be renewed.
MDRenewWindow duration 33% sX
Control when a certificate will be renewed.
MDRequireHttps off|temporary|permanent off sX
Redirects http: traffic to https: for Managed Domains.
MDRetryDelay duration 5s sX
Time length for first retry, doubled on every consecutive error.
MDRetryFailover number 13 sX
The number of errors before a failover to another CA is triggered
MDServerStatus on|off on sX
Control if Managed Domain information is added to server-status.
MDStapleOthers on|off on sX
Enable stapling for certificates not managed by mod_md.
MDStapling on|off off sX
Enable stapling for all or a particular MDomain.
MDStaplingKeepResponse duration 7d sX
Controls when old responses should be removed.
MDStaplingRenewWindow duration 33% sX
Control when the stapling responses will be renewed.
MDStoreDir path md sX
Path on the local file system to store the Managed Domains data.
MDStoreLocks on|off|duration off sX
Configure locking of store for updates
MDWarnWindow duration 10% sX
Define the time window when you want to be warned about an expiring certificate.
MemcacheConnTTL num[units] 15s svE
Keepalive time for idle connections
MergeSlashes ON|OFF ON svC
Controls whether the server merges consecutive slashes in URLs.
MergeTrailers [on|off] off svC
Determines whether trailers are merged into headers
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
۽ ޸𸮿 Ѵ
ModemStandard V.21|V.26bis|V.32|V.34|V.92dX
Modem standard to simulate
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
Mutex mechanism [default|mutex-name] ... [OmitPID] default sC
Configures mutex mechanism and lock file directory for all or specified mutexes
NameVirtualHost addr[:port]sC
DEPRECATED: Designates an IP address for name-virtual hosting
NoProxy host [host] ...svE
Hosts, domains, or networks that will be connected to directly
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] ... FollowSymlinks svdhC
Configures what features are available in a particular directory
Order ordering Deny,Allow dhE
Controls the default access state and the order in which Allow and Deny are evaluated.
OutputSed sed-commanddhX
Sed command for filtering response content
PassEnv env-variable [env-variable] ...svdhB
ȯ溯 ´
PidFile filename logs/httpd.pid sM
File where the server records the process ID of the daemon
PrivilegesMode FAST|SECURE|SELECTIVE FAST svdX
Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Protocol protocolsvC
Protocol for a listening socket
ProtocolEcho On|OffsvX
echo Ű
Protocols protocol ... http/1.1 svC
Protocols available for a server/virtual host
ProtocolsHonorOrder On|Off On svC
Determines if order of Protocols determines precedence during negotiation
<Proxy wildcard-url> ...</Proxy>svE
Container for directives applied to proxied resources
Proxy100Continue Off|On On svdE
Forward 100-continue expectation to the origin server
ProxyAddHeaders Off|On On svdE
Add proxy information in X-Forwarded-* headers
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 Off|On [code ...] Off svdE
Override error pages for proxied content
ProxyExpressDBMFile pathnamesvE
Pathname to DBM file.
ProxyExpressDBMType type default svE
DBM type of file.
ProxyExpressEnable on|off off svE
Enable the module functionality.
ProxyFCGIBackendType FPM|GENERIC FPM svdhE
Specify the type of backend FastCGI application
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]svdhE
Allow variables sent to FastCGI servers to be fixed up
ProxyFtpDirCharset character_set ISO-8859-1 svdE
Define the character set for proxied FTP listings
ProxyFtpEscapeWildcards on|off on svdE
Whether wildcards in requested filenames are escaped when sent to the FTP server
ProxyFtpListOnWildcard on|off on svdE
Whether wildcards in requested filenames trigger a file listing
ProxyHCExpr name {ap_expr expression}svE
Creates a named condition expression to use to determine health of the backend based on its response
ProxyHCTemplate name parameter=setting [...]svE
Creates a named template for setting various health check parameters
ProxyHCTPsize size 16 sE
Sets the total server-wide size of the threadpool used for the health check workers
ProxyHTMLBufSize bytes 8192 svdB
Sets the buffer size increment for buffering inline scripts and stylesheets.
ProxyHTMLCharsetOut Charset | *svdB
Specify a charset for mod_proxy_html output.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
svdB
Sets an HTML or XHTML document type declaration.
ProxyHTMLEnable On|Off Off svdB
Turns the proxy_html filter on or off.
ProxyHTMLEvents attribute [attribute ...]svdB
Specify attributes to treat as scripting events.
ProxyHTMLExtended On|Off Off svdB
Determines whether to fix links in inline scripts, stylesheets, and scripting events.
ProxyHTMLFixups [lowercase] [dospath] [reset]svdB
Fixes for simple HTML errors.
ProxyHTMLInterp On|Off Off svdB
Enables per-request interpolation of ProxyHTMLURLMap rules.
ProxyHTMLLinks element attribute [attribute2 ...]svdB
Specify HTML elements that have URL attributes to be rewritten.
ProxyHTMLMeta On|Off Off svdB
Turns on or off extra pre-parsing of metadata in HTML <head> sections.
ProxyHTMLStripComments On|Off Off svdB
Determines whether to strip HTML comments.
ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]svdB
Defines a rule to rewrite HTML links
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 -1 svE
Maximum number of proxies that a request can be forwarded through
ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] [noquery]svdE
Maps remote servers into the local server URL-space
ProxyPassInherit On|Off On svE
Inherit ProxyPass directives defined from the main server
ProxyPassInterpolateEnv On|Off Off svdE
Enable Environment Variable interpolation in Reverse Proxy configurations
ProxyPassMatch [regex] !|url [key=value [key=value ...]]svdE
Maps remote servers into the local server URL-space using regular expressions
ProxyPassReverse [path] url [interpolate]svdE
Adjusts the URL in HTTP response headers sent from a reverse proxied server
ProxyPassReverseCookieDomain internal-domain public-domain [interpolate]svdE
Adjusts the Domain string in Set-Cookie headers from a reverse- proxied server
ProxyPassReverseCookiePath internal-path public-path [interpolate]svdE
Adjusts the Path string in Set-Cookie headers from a reverse- proxied server
ProxyPreserveHost On|Off Off svdE
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-server [username:password]svE
Remote proxy used to handle certain requests
ProxyRemoteMatch regex remote-server [username:password]svE
Remote proxy used to handle requests matched by regular expressions
ProxyRequests On|Off Off svE
Enables forward (standard) proxy requests
ProxySCGIInternalRedirect On|Off|Headername On svdE
Enable or disable internal redirect responses from the backend
ProxySCGISendfile On|Off|Headername Off svdE
Enable evaluation of X-Sendfile pseudo response header
ProxySet url key=value [key=value ...]svdE
Set various Proxy balancer or member parameters
ProxySourceAddress addresssvE
Set local IP address for outgoing proxy connections
ProxyStatus Off|On|Full Off svE
Show Proxy LoadBalancer status in mod_status
ProxyTimeout secondssvE
Network timeout for proxied requests
ProxyVia On|Off|Full|Block Off svE
Information provided in the Via HTTP response header for proxied requests
ProxyWebsocketFallbackToProxyHttp On|Off On svE
Instructs this module to let mod_proxy_http handle the request
QualifyRedirectURL On|Off Off svdC
Controls whether the REDIRECT_URL environment variable is fully qualified
ReadBufferSize bytes 8192 svdC
Size of the buffers used to read data
ReadmeName filenamesvdhB
ϸ ̸
ReceiveBufferSize bytes 0 sM
TCP receive buffer size
Redirect [status] URL-path URLsvdhB
Ŭ̾Ʈ ٸ URL ϵ ûϴ ܺ ̷
RedirectMatch [status] regex URLsvdhB
URL ǥĿ شϸ ܺ ̷
RedirectPermanent URL-path URLsvdhB
Ŭ̾Ʈ ٸ URL ϵ ûϴ ܺ ̷
RedirectRelative On|Off Off svdB
Allows relative redirect targets.
RedirectTemp URL-path URLsvdhB
Ŭ̾Ʈ ٸ URL ϵ ûϴ ܺ ӽ ̷
RedisConnPoolTTL num[units] 15s svE
TTL used for the connection pool with the Redis server(s)
RedisTimeout num[units] 5s svE
R/W timeout used for the connection with the Redis server(s)
ReflectorHeader inputheader [outputheader]svdhB
Reflect an input header to the output headers
RegexDefaultOptions [none] [+|-]option [[+|-]option] ... DOTALL DOLLAR_ENDON +sC
Allow to configure global/default options for regexes
RegisterHttpMethod method [method [...]]sC
Register non-standard HTTP methods
RemoteIPHeader header-fieldsvB
Declare the header field which should be parsed for useragent IP addresses
RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPInternalProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPProxiesHeader HeaderFieldNamesvB
Declare the header field which will record all intermediate IP addresses
RemoteIPProxyProtocol On|OffsvB
Enable or disable PROXY protocol handling
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]svB
Disable processing of PROXY header for certain hosts or networks
RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPTrustedProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
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 û Ѵ
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate] handshake=0 header= +svE
Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Require [not] entity-name [entity-name] ...dhB
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll> ... </RequireAll>dhB
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny> ... </RequireAny>dhB
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone> ... </RequireNone>dhB
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
RewriteBase URL-pathdhE
Sets the base URL for per-directory rewrites
RewriteCond TestString CondPattern [flags]svdhE
Defines a condition under which rewriting will take place
RewriteEngine on|off off svdhE
Enables or disables runtime rewriting engine
RewriteMap MapName MapType:MapSource [MapTypeOptions] svE
Defines a mapping function for key-lookup
RewriteOptions OptionssvdhE
Sets some special options for the rewrite engine
RewriteRule Pattern Substitution [flags]svdhE
Defines rules for the rewriting engine
RLimitCPU seconds|max [seconds|max]svdhC
Limits the CPU consumption of processes launched by Apache httpd children
RLimitMEM bytes|max [bytes|max]svdhC
Limits the memory consumption of processes launched by Apache httpd children
RLimitNPROC number|max [number|max]svdhC
Limits the number of processes that can be launched by processes launched by Apache httpd children
Satisfy Any|All All dhE
Interaction between host-level access control and user authentication
ScoreBoardFile file-path logs/apache_runtime +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
SeeRequestTail On|Off Off sC
Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
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 [scheme://]domain-name|ip-address[: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
Session On|Off Off svdhE
Enables a session for the current directory or location
SessionCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session
SessionCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session
SessionCookieRemove On|Off Off svdhE
Control for whether session cookies should be removed from incoming HTTP headers
SessionCryptoCipher name aes256 svdhX
The crypto cipher to be used to encrypt the session
SessionCryptoDriver name [param[=value]]sX
The crypto driver to be used to encrypt the session
SessionCryptoPassphrase secret [ secret ... ] svdhX
The key used to encrypt the session
SessionCryptoPassphraseFile filenamesvdX
File containing keys used to encrypt the session
SessionDBDCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session ID
SessionDBDCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session ID
SessionDBDCookieRemove On|Off On svdhE
Control for whether session ID cookies should be removed from incoming HTTP headers
SessionDBDDeleteLabel label deletesession svdhE
The SQL query to use to remove sessions from the database
SessionDBDInsertLabel label insertsession svdhE
The SQL query to use to insert sessions into the database
SessionDBDPerUser On|Off Off svdhE
Enable a per user session
SessionDBDSelectLabel label selectsession svdhE
The SQL query to use to select sessions from the database
SessionDBDUpdateLabel label updatesession svdhE
The SQL query to use to update existing sessions in the database
SessionEnv On|Off Off svdhE
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionExclude pathsvdhE
Define URL prefixes for which a session is ignored
SessionExpiryUpdateInterval interval 0 (always update) svdhE
Define the number of seconds a session's expiry may change without the session being updated
SessionHeader headersvdhE
Import session updates from a given HTTP response header
SessionInclude pathsvdhE
Define URL prefixes for which a session is valid
SessionMaxAge maxage 0 svdhE
Define a maximum age in seconds for a session
SetEnv env-variable valuesvdhB
ȯ溯 Ѵ
SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
û ȯ溯 Ѵ
svdhB
Sets environment variables based on an ap_expr expression
SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
ҹڸ ʰ û ȯ溯 Ѵ
SetHandler handler-name|none|expressionsvdhC
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
SSIETag on|off off dhB
Controls whether ETags are generated by the server.
SSILastModified on|off off dhB
Controls whether Last-Modified headers are generated by the server.
SSILegacyExprParser on|off off dhB
Enable compatibility mode for conditional expressions.
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
SSLCARevocationCheck chain|leaf|none [flags ...] none svE
Enable CRL-based revocation checking
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-path|certidsvE
Server PEM-encoded X.509 certificate data file or token identifier
SSLCertificateKeyFile file-path|keyidsvE
Server PEM-encoded private key file
SSLCipherSuite [protocol] cipher-spec DEFAULT (depends on +svdhE
Cipher Suite available for negotiation in SSL handshake
SSLCompression on|off off svE
Enable compression on the SSL level
SSLCryptoDevice engine builtin sE
Enable use of a cryptographic hardware accelerator
SSLEngine on|off|optional off svE
SSL Engine Operation Switch
SSLFIPS on|off off sE
SSL FIPS mode Switch
SSLHonorCipherOrder on|off off svE
Option to prefer the server's cipher preference order
SSLInsecureRenegotiation on|off off svE
Option to enable support for insecure renegotiation
SSLOCSPDefaultResponder urisvE
Set the default responder URI for OCSP validation
SSLOCSPEnable on|leaf|off off svE
Enable OCSP validation of the client certificate chain
SSLOCSPNoverify on|off off svE
skip the OCSP responder certificates verification
SSLOCSPOverrideResponder on|off off svE
Force use of the default responder URI for OCSP validation
SSLOCSPProxyURL urlsvE
Proxy URL to use for OCSP requests
SSLOCSPResponderCertificateFile filesvE
Set of trusted PEM encoded OCSP responder certificates
SSLOCSPResponderTimeout seconds 10 svE
Timeout for OCSP queries
SSLOCSPResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP responses
SSLOCSPResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP response validation
SSLOCSPUseRequestNonce on|off on svE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd command-name command-valuesvE
Configure OpenSSL parameters through its SSL_CONF API
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 -SSLv3 (up to 2 +svE
Configure usable SSL/TLS protocol versions
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
SSLProxyCARevocationCheck chain|leaf|none none svE
Enable CRL-based revocation checking 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
SSLProxyCheckPeerCN on|off on svE
Whether to check the remote server certificate's CN field
SSLProxyCheckPeerExpire on|off on svE
Whether to check if remote server certificate is expired
SSLProxyCheckPeerName on|off on svE
Configure host name checking for remote server certificates
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +svE
Cipher Suite available for negotiation in SSL proxy handshake
SSLProxyEngine on|off off svE
SSL Proxy Engine Operation Switch
SSLProxyMachineCertificateChainFile filenamesvE
File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
SSLProxyMachineCertificateFile filenamesvE
File of concatenated PEM-encoded client certificates and keys to be used by the proxy
SSLProxyMachineCertificatePath directorysvE
Directory of PEM-encoded client certificates and keys to be used by the proxy
SSLProxyProtocol [+|-]protocol ... all -SSLv3 (up to 2 +svE
Configure usable SSL protocol flavors for proxy usage
SSLProxyVerify level none svE
Type of remote server Certificate verification
SSLProxyVerifyDepth number 1 svE
Maximum depth of CA Certificates in Remote Server Certificate verification
SSLRandomSeed context source [bytes]sE
Pseudo Random Number Generator (PRNG) seeding source
SSLRenegBufferSize bytes 131072 dhE
Set the size for the SSL renegotiation buffer
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
SSLSessionTicketKeyFile file-pathsvE
Persistent encryption/decryption key for TLS session tickets
SSLSessionTickets on|off on svE
Enable or disable use of TLS session tickets
SSLSRPUnknownUserSeed secret-stringsvE
SRP unknown user seed
SSLSRPVerifierFile file-pathsvE
Path to SRP verifier file
SSLStaplingCache typesE
Configures the OCSP stapling cache
SSLStaplingErrorCacheTimeout seconds 600 svE
Number of seconds before expiring invalid responses in the OCSP stapling cache
SSLStaplingFakeTryLater on|off on svE
Synthesize "tryLater" responses for failed OCSP stapling queries
SSLStaplingForceURL urisvE
Override the OCSP responder URI specified in the certificate's AIA extension
SSLStaplingResponderTimeout seconds 10 svE
Timeout for OCSP stapling queries
SSLStaplingResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP stapling responses
SSLStaplingResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP stapling response validation
SSLStaplingReturnResponderErrors on|off on svE
Pass stapling related OCSP errors on to client
SSLStaplingStandardCacheTimeout seconds 3600 svE
Number of seconds before expiring responses in the OCSP stapling cache
SSLStrictSNIVHostCheck on|off off svE
Whether to allow non-SNI clients to access a name-based virtual host.
SSLUserName varnamesdhE
Variable name to determine user name
SSLUseStapling on|off off svE
Enable stapling of OCSP responses in the TLS handshake
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
StrictHostCheck ON|OFF OFF svC
Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Substitute s/pattern/substitution/[infq]dhE
Pattern to filter the response content
SubstituteInheritBefore on|off off dhE
Change the merge order of inherited patterns
SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G) 1m dhE
Set the maximum line size
Suexec On|OffsB
Enable or disable the suEXEC feature
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 60 svC
Amount of time the server will wait for certain events before failing a request
TraceEnable [on|off|extended] on svC
Determines the behavior on TRACE requests
TransferLog file|pipesvB
α ġ Ѵ
TypesConfig file-path conf/mime.types sB
The location of the mime.types file
UNCList hostname [hostname...]sC
Controls what UNC host names can be accessed by the server
UnDefine parameter-namesC
Undefine the existence of a variable
UndefMacro namesvdB
Undefine a macro
UnsetEnv env-variable [env-variable] ...svdhB
ȯ溯 Ѵ
Use name [value1 ... valueN] svdB
Use a macro
UseCanonicalName On|Off|DNS Off svdC
Configures how the server determines its own name and port
UseCanonicalPhysicalPort On|Off Off svdC
Configures how the server determines its own port
User unix-userid #-1 sB
The userid under which the server will answer requests
UserDir directory-filename public_html svB
ں 丮 ġ
VHostCGIMode On|Off|Secure On vX
Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to subprocesses created by a virtual host.
VHostGroup unix-groupidvX
Sets the Group ID under which a virtual host runs.
VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to a virtual host.
VHostSecure On|Off On vX
Determines whether the server runs with enhanced security for the virtualhost.
VHostUser unix-useridvX
Sets the User ID under which a virtual host runs.
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
WatchdogInterval time-interval[s] 1 sB
Watchdog interval in seconds
XBitHack on|off|full off svdhB
Parse SSI directives in files with the execute bit set
xml2EncAlias charset alias [alias ...]sB
Recognise Aliases for encoding values
xml2EncDefault namesvdhB
Sets a default encoding to assume when absolutely no information can be automatically detected
xml2StartParse element [element ...]svdhB
Advise the parser to skip leading junk.

:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_imagemap.html.ko.euc-kr0000664000175100017510000004742414743132254022730 0ustar covenercovener mod_imagemap - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_imagemap

ֽ ƴմϴ. ֱٿ ϼ.
: ̹(imagemap) ó
:Base
:imagemap_module
ҽ:mod_imagemap.c

imagemap CGI α׷ Ͽ .map óѴ. (AddHandler SetHandler Ͽ) imap-file ڵ鷯 ϵ 丮 óѴ.

Ʒ þ .map ̹ Ϸ Ѵ.

AddHandler imap-file map

Ʒ Ѵ.

AddType application/x-httpd-imap map

׷ 츮 " Ư ǹ̰ ִ MIME type" Ϸ ϱ⶧ ̴.

Support Apache!

þ

Bugfix checklist

top

ο

̹ ⿡ ̹ α׷  ο ִ.

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_imagemap

ImapBase þ ̹ Ͽ base ⺻ Ѵ. ̹ ȿ base þ ϸ ⼭ Ѵ. ٸ, basehttp://servername/̴.

top

ImapDefault þ

:̹ʿ ش ʴ ǥ ⺻ ൿ
:ImapDefault error|nocontent|map|referer|URL
⺻:ImapDefault nocontent
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Indexes
:Base
:mod_imagemap

ImapDefault þ ̹ Ͽ default ⺻ Ѵ. ̹ ȿ default þ ϸ ⼭ Ѵ. ٸ, default ൿ Ŭ̾Ʈ 204 No Content nocontent̴. Ŭ̾Ʈ ״ Ѵ.

top

ImapMenu þ

:ǥ ̹ û ൿ
:ImapMenu none|formatted|semiformatted|unformatted
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Indexes
:Base
:mod_imagemap

ImapMenu þ ̹ Ͽ ȿ ǥ ൿ Ѵ.

none
ImapMenu none̸, ޴ ʰ default ൿ Ѵ.
formatted
formatted ޴ ޴. ̹ ּ Ѵ. ū ǥ ϰ, ũ پ Ѵ. ޴ ϰǰ ϸ, 丮 ϰ ϴ.
semiformatted
semiformatted ޴ ̹ Ͽ ּ Ѵ. HTML ٲ ȯѴ. ǥ ׸ , formatted ޴ .
unformatted
ּ ϰ, Ѵ. ̹ Ͽ ִ 븸 Ѵ. ̹ ּ ʿ ٲް ǥ Ѵ. ޴ ܰ ٹ , ̹ ǻ Ϲ ƴ HTML Ѵ.

:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_info.html.ko.euc-kr0000664000175100017510000003114314743132254022072 0ustar covenercovener mod_info - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_info

ֽ ƴմϴ. ֱٿ ϼ.
: ش
:Extension
:info_module
ҽ:mod_info.c

mod_info Ϸ httpd.conf Ͽ ߰Ѵ.

<Location /server-info>
SetHandler server-info
</Location>

̷ ϸ http://your.host.example.com/server-info Ͽ ִ.

Support Apache!

þ

Bugfix checklist

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 ʰ ̹ о Ͽ ش. Ľϴ  Ѱ谡 ִ.

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.4/mod/mod_deflate.html">\
http://www.apache.org/docs/docs/2.4/mod/mod_deflate.html</a>'

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_include.html.ja.utf80000664000175100017510000015653114743132254022254 0ustar covenercovener mod_include - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_include

翻訳済み言語:  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:サーバがパースする html ドキュメント (Server Side Includes)
ステータス:Base
モジュール識別子:include_module
ソースファイル:mod_include.c
互換性:Apache 2.0 から出力フィルタとして実装されました。

概要

このモジュールはファイルがクライアントに送られる前に処理するフィルタを 提供します。処理の内容は要素と呼ばれる特別な形式の SGML コメントにより 制御されます。これらの要素は条件分岐や、他のファイルや プログラムの出力の取り込み、環境変数の設定や表示を行なうことが できます。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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-htmltext/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) を以下の表に示します。

要素説明
config configure output formats
echo print variables
exec execute external programs
fsize print size of a file
flastmod print last modification time of a file
include include a file
printenv print all available variables
set set 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 スクリプトとして 起動されます。ただし、スクリプトのあるディレクトリでは (ScriptAliasOption 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 よりも 好ましい方法です。

KeptBodySize ディレクティブが設定されていて、かつ、この対象ファイルが (訳注: POST リクエストを)受け入れできるなら、 POST リクエストを受け取ってサブリクエストを発行する際にも POST リクエストが渡されます。 このディレクティブが設定されていない場合は、 サブリクエストは GET リクエストとして処理されます。

printenv 要素

これは、存在するすべての変数とその値を表示します。Apache 1.3.12 から、 特別な文字は出力される前にエンティティエンコード (詳細は echo 要素を参照) されるようになりました。属性はありません。

<!--#printenv -->

set 要素

これは変数の値を設定します。属性は次の通りです。

var
設定する変数の名前。
value
変数に設定する値。

<!--#set var="category" value="help" -->

top

Include 変数

標準 CGI 環境の変数に加えて、echo コマンドや、 ifelif, それにドキュメントから呼び出される すべてのプログラムから使用できる変数があります。

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 文と同じように動作します。条件が評価され、結果が真であれば次の elifelseendif 要素までの文字列が出力に挿入されます。

elifelse 文は test_condition が偽のときにテキストを出力に挿入するために使われます。 これらの要素はあってもなくても構いません。

endif 要素は if 要素を終了させます。この要素は必須です。

test_condition は以下のどれかです:

string
string が空でない場合に真です
-A string

(訳注: httpd の)設定を検査して、 文字列で指定した URL にアクセスできる場合 true で、 そうでなければ false になります。 SSIAccessEnable が有効のときにのみ この検査は行われます。 承認されていないユーザからは隠しておきたい URL についての情報、 たとえば URL へのリンクなどがある場合に、便利です。 検査では URL へアクセスできるかの権限のみが行われ、URL が存在するかどうかについては検査されないことに注意してください。

Example

<!--#if expr="-A /private" -->
Click <a href="/private">here</a> to access private information.
<!--#endif -->

string1 = string2
string1 == string2
string1 != string2

string1string2 を比較します。 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
string1string2 を比較します。 文字列として比較される (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    string2string1 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

SSIETag ディレクティブ

説明:Controls whether ETags are generated by the server.
構文:SSIETag on|off
デフォルト:SSIETag off
コンテキスト:ディレクトリ, .htaccess
ステータス:Base
モジュール:mod_include
互換性:Available in version 2.2.15 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

SSILastModified ディレクティブ

説明:Controls whether Last-Modified headers are generated by the server.
構文:SSILastModified on|off
デフォルト:SSILastModified off
コンテキスト:ディレクトリ, .htaccess
ステータス:Base
モジュール:mod_include
互換性:Available in version 2.2.15 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

SSILegacyExprParser ディレクティブ

説明:Enable compatibility mode for conditional expressions.
構文:SSILegacyExprParser on|off
デフォルト:SSILegacyExprParser off
コンテキスト:ディレクトリ, .htaccess
ステータス:Base
モジュール:mod_include
互換性:Available in version 2.3.13 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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 は使わない方が良い でしょう。

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_isapi.html.ko.euc-kr0000664000175100017510000005317314743132254022253 0ustar covenercovener mod_isapi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_isapi

ֽ ƴմϴ. ֱٿ ϼ.
: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 ڿ ϱ ٶ. ̷ ġ ϸƮ ׺ ø .

Support Apache!

þ

Bugfix checklist

top

Ͽ AddHandler þ Ͽ ISAPI Ȯڿ isapi-handler ڵ鷯 Ѵ. .dll ISAPI extension óϷ httpd.conf Ͽ ߰Ѵ.

AddHandler isapi-handler .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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.tr.utf80000664000175100017510000060602415032765673023026 0ustar covenercovener Hızlı Yönerge Kılavuzu - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Hızlı Yönerge Kılavuzu

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Bu hızlı yönerge kılavuzunda Apache yapılandırma yönergelerinin kullanımı, öntanımlı değerleri, durumu ve bağlamı gösterilmiştir. Bunların her biri hakkında ayrıntılı bilgi almak için Yönerge Sözlüğüne bakınız.

İlk sütunda yönergenin ismi ve kullanımı belirtilmiştir. İkinci sütunda yönergenin varsa öntanımlı değeri gösterilmiştir. Eğer öntanımlı değer sütuna sığmayacak kadar uzunsa sığmayan kısmı kırpılıp yerine “+” imi konmuştur.

Aşağıda sağdaki gösterge tablolarına uygun olarak, üçüncü sütunda yönergenin kullanımına izin verilen bağlamlar, dördüncü sütunda ise yönergenin durumu gösterilmiştir.

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
ssunucu geneli
ksanal konak
ddizin
h.htaccess
vvekil bölümü
ÇÇekirdek
MMPM
TTemel
EEklenti
DDeneysel
HHarici
AcceptFilter protocol kabul_süzgecisÇ
Bir protokolün dinleyici soketleri için en iyilemeleri ayarlar
AcceptPathInfo On|Off|Default Default skdhÇ
Dosya isminden sonra belirtilen yol verisini kabul veya reddeder.
AccessFileName filename [filename] ... .htaccess skÇ
Dağıtık yapılandırma dosyasının ismi belirtilir.
Action action-type cgi-script [virtual]skdhT
Activates a CGI script for a particular handler or content-type
AddAlt metin dosya [dosya] ...skdhT
Dosyaya göre seçilen simgenin yerinde gösterilecek metni belirler.
AddAltByEncoding metin MIME-kodlaması [MIME-kodlaması] ...skdhT
Dosyanın MIME kodlamasına göre seçilen simgenin yerinde gösterilecek metni belirler.
AddAltByType metin MIME-türü [MIME-türü] ...skdhT
Dosyanın MIME türüne göre seçilen simgenin yerinde gösterilecek metni belirler.
AddCharset charset extension [extension] ...skdhT
Maps the given filename extensions to the specified content charset
AddDefaultCharset On|Off|karküm Off skdhÇ
Bir yanıtın içerik türü text/plain veya text/html olduğunda eklenecek öntanımlı karakter kümesi parametresini belirler.
AddDescription metin dosya [dosya] ...skdhT
Bir dosya için gösterilecek açıklama belirtilir.
AddEncoding encoding extension [extension] ...skdhT
Maps the given filename extensions to the specified encoding type
AddHandler handler-name extension [extension] ...skdhT
Maps the filename extensions to the specified handler
AddIcon simge isim [isim] ...skdhT
Bir dosya için gösterilecek simgeyi dosya adına göre belirler.
AddIconByEncoding simge MIME-kodlaması [MIME-kodlaması] ...skdhT
Bir dosya için gösterilecek simgeyi dosyanın MIME kodlamasına göre belirler.
AddIconByType simge MIME-türü [MIME-türü] ...skdhT
Bir dosya için gösterilecek simgeyi dosyanın MIME türüne göre belirler.
AddInputFilter filter[;filter...] extension [extension] ...skdhT
Maps filename extensions to the filters that will process client requests
AddLanguage language-tag extension [extension] ...skdhT
Maps the given filename extension to the specified content language
AddModuleInfo module-name stringskE
Adds additional information to the module information displayed by the server-info handler
AddOutputFilter filter[;filter...] extension [extension] ...skdhT
Maps filename extensions to the filters that will process responses from the server
AddOutputFilterByType filter[;filter...] media-type [media-type] ...skdhT
assigns an output filter to a particular media-type
AddType media-type extension [extension] ...skdhT
Maps the given filename extensions onto the specified content type
Alias [URL-yolu] dosya-yolu | dizin-yoluskdT
URL’leri dosya sistemi konumlarıyla eşler.
AliasMatch "düzenli-ifade" "dosya-yolu|dizin-yolu"skT
URL’leri dosya sistemi konumlarıyla düzenli ifadeleri kullanarak eşler.
AliasPreservePath OFF|ON OFF skdT
Map the full path after the alias in a location.
Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
Controls which hosts can access an area of the server
AllowCONNECT port[-port] [port[-port]] ... 443 563 skE
Ports that are allowed to CONNECT through the proxy
AllowEncodedSlashes On|Off|NoDecode Off skÇ
Kodlanmış dosya yolu ayracı içeren URL’lere izin verilip verilmeyeceğini belirler.
AllowMethods reset|HTTP-method [HTTP-method]... reset dD
Restrict access to the listed HTTP methods
AllowOverride All|None|yönerge-türü [yönerge-türü] ... None (2.3.9 ve sonr +dÇ
.htaccess dosyalarında bulunmasına izin verilen yönerge türleri belirtilir.
AllowOverrideList None|yönerge [yönerge-türü] ... None dÇ
.htaccess dosyalarında izin verilecek yönergeler tek tek belirtilir
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
AsyncRequestWorkerFactor factorsM
Limit concurrent connections per process
AuthBasicAuthoritative On|Off On dhT
Sets whether authorization and authentication are passed to lower level modules
AuthBasicFake off|username [password]dhT
Fake basic authentication using the given expressions for username and password
AuthBasicProvider provider-name [provider-name] ... file dhT
Sets the authentication provider(s) for this location
AuthBasicUseDigestAlgorithm MD5|Off Off dhT
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBDUserPWQuery querydE
SQL query to look up a password for a user
AuthDBDUserRealmQuery querydE
SQL query to look up a password hash for a user and realm.
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
AuthDigestAlgorithm MD5|MD5-sess MD5 dhE
Selects the algorithm used to calculate the challenge and response hashes in digest authentication
AuthDigestDomain URI [URI] ...dhE
URIs that are in the same protection space for digest authentication
AuthDigestNonceLifetime seconds 300 dhE
How long the server nonce is valid
AuthDigestProvider provider-name [provider-name] ... file dhE
Sets the authentication provider(s) for this location
AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhE
Determines the quality-of-protection to use in digest authentication
AuthDigestShmemSize size 1000 sE
The amount of shared memory to allocate for keeping track of clients
AuthFormAuthoritative On|Off On dhT
Sets whether authorization and authentication are passed to lower level modules
AuthFormBody fieldname httpd_body dT
The name of a form field carrying the body of the request to attempt on successful login
AuthFormDisableNoStore On|Off Off dT
Disable the CacheControl no-store header on the login page
AuthFormFakeBasicAuth On|Off Off dT
Fake a Basic Authentication header
AuthFormLocation fieldname httpd_location dT
The name of a form field carrying a URL to redirect to on successful login
AuthFormLoginRequiredLocation urldT
The URL of the page to be redirected to should login be required
AuthFormLoginSuccessLocation urldT
The URL of the page to be redirected to should login be successful
AuthFormLogoutLocation uridT
The URL to redirect to after a user has logged out
AuthFormMethod fieldname httpd_method dT
The name of a form field carrying the method of the request to attempt on successful login
AuthFormMimetype fieldname httpd_mimetype dT
The name of a form field carrying the mimetype of the body of the request to attempt on successful login
AuthFormPassword fieldname httpd_password dT
The name of a form field carrying the login password
AuthFormProvider provider-name [provider-name] ... file dhT
Sets the authentication provider(s) for this location
AuthFormSitePassphrase secretdT
Bypass authentication checks for high traffic sites
AuthFormSize size 8192 dT
The largest size of the form in bytes that will be parsed for the login details
AuthFormUsername fieldname httpd_username dT
The name of a form field carrying the login username
AuthGroupFile file-pathdhT
Sets the name of a text file containing the list of user groups for authorization
AuthLDAPAuthorizePrefix prefix AUTHORIZE_ dhE
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritative off|on on dhE
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDN distinguished-namedhE
Optional DN to use in binding to the LDAP server
AuthLDAPBindPassword passworddhE
Password used in conjunction with the bind DN
AuthLDAPCharsetConfig file-pathsE
Language to charset conversion configuration file
AuthLDAPCompareAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization comparisons
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 attribute member uniqueMember +dhE
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDN on|off on dhE
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUser off|on off dhE
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPattern regex substitution (.*) $1 (remote use +dhE
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepth Number 10 dhE
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttribute uiddhE
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDN on|off off dhE
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttribute attribute member uniqueMember +dhE
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClass LdapObjectClass groupOfNames groupO +dhE
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhT
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthName auth-domaindhT
Authorization realm for use in HTTP authentication
AuthnCacheContext directory|server|custom-string directory dT
Specify a context string for use in the cache key
AuthnCacheEnablesT
Enable Authn caching configured anywhere
AuthnCacheProvideFor authn-provider [...]dhT
Specify which authn provider(s) to cache for
AuthnCacheSOCache provider-name[:provider-args]sT
Select socache backend provider to use
AuthnCacheTimeout timeout (seconds) 300 (5 minutes) dhT
Set a timeout for cache entries
<AuthnProviderAlias baseProvider Alias> ... </AuthnProviderAlias>sT
Enclose a group of directives that represent an extension of a base authentication provider and referenced by the specified alias
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Enables a FastCGI application to handle the check_authn authentication hook.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Defines a FastCGI application as a provider for authentication and/or authorization
AuthType None|Basic|Digest|FormdhT
Type of user authentication
AuthUserFile file-pathdhT
Sets the name of a text file containing the list of users and passwords for authentication
AuthzDBDLoginToReferer On|Off Off dE
Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
AuthzDBDQuery querydE
Specify the SQL Query for the required operation
AuthzDBDRedirectQuery querydE
Specify a query to look up a login page for the user
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
Sets the type of database file that is used to store list of user groups
<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> sT
Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
AuthzSendForbiddenOnFailure On|Off Off dhT
Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
BalancerGrowth # 5 skE
Number of additional Balancers that can be added Post-configuration
BalancerInherit On|Off On skE
Inherit ProxyPassed Balancers/Workers from the main server
BalancerMember [balancerurl] url [key=value [key=value ...]]dE
Add a member to a load balancing group
BalancerPersist On|Off Off skE
Attempt to persist changes made by the Balancer Manager across restarts.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix skE
How the outgoing ETag header should be modified during compression
BrotliCompressionMaxInputBlock valueskE
Maximum input block size
BrotliCompressionQuality value 5 skE
Compression quality
BrotliCompressionWindow value 18 skE
Brotli sliding compression window size
BrotliFilterNote [type] notenameskE
Places the compression ratio in a note for logging
BrowserMatch düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...skdhT
Ortam değişkenlerini HTTP kullanıcı arayüzüne göre belirler.
BrowserMatchNoCase düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...skdhT
Ortam değişkenlerini HTTP kullanıcı arayüzünün harf büyüklüğüne duyarsız eşleşmelerine bağlı olarak belirler.
BufferedLogs On|Off Off sT
Günlük girdilerini diske yazmadan önce bellekte tamponlar
BufferSize integer 131072 skdhE
Maximum size in bytes to buffer by the buffer filter
CacheDefaultExpire seconds 3600 (one hour) skdhE
The default duration to cache a document when no expiry date is specified.
CacheDetailHeader on|off off skdhE
Add an X-Cache-Detail header to the response.
CacheDirLength length 2 skE
The number of characters in subdirectory names
CacheDirLevels levels 2 skE
The number of levels of subdirectories in the cache.
CacheDisable url-string | onskdhE
Disable caching of specified URLs
CacheEnable cache_type [url-string]skdE
Enable caching of specified URLs using a specified storage manager
CacheFile file-path [file-path] ...sD
Cache a list of file handles at startup time
CacheHeader on|off off skdhE
Add an X-Cache header to the response.
CacheIgnoreCacheControl On|Off Off skE
Ignore request to not serve cached content to client
CacheIgnoreHeaders header-string [header-string] ... None skE
Do not store the given HTTP header(s) in the cache.
CacheIgnoreNoLastMod On|Off Off skdhE
Ignore the fact that a response has no Last Modified header.
CacheIgnoreQueryString On|Off Off skE
Ignore query string when caching
CacheIgnoreURLSessionIdentifiers identifier [identifier] ... None skE
Ignore defined session identifiers encoded in the URL when caching
CacheKeyBaseURL URLskE
Override the base URL of reverse proxied cache keys.
CacheLastModifiedFactor float 0.1 skdhE
The factor used to compute an expiry date based on the LastModified date.
CacheLock on|off off skE
Enable the thundering herd lock.
CacheLockMaxAge integer 5 skE
Set the maximum possible age of a cache lock.
CacheLockPath directory /tmp/mod_cache-lock +skE
Set the lock path directory.
CacheMaxExpire seconds 86400 (one day) skdhE
The maximum time in seconds to cache a document
CacheMaxFileSize bytes 1000000 skdhE
The maximum size (in bytes) of a document to be placed in the cache
CacheMinExpire seconds 0 skdhE
The minimum time in seconds to cache a document
CacheMinFileSize bytes 1 skdhE
The minimum size (in bytes) of a document to be placed in the cache
CacheNegotiatedDocs On|Off Off skT
Allows content-negotiated documents to be cached by proxy servers
CacheQuickHandler on|off on skE
Run the cache from the quick handler.
CacheReadSize bytes 0 skdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheReadTime milliseconds 0 skdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheRoot directoryskE
The directory root under which cache files are stored
CacheSocache type[:args]skE
The shared object cache implementation to use
CacheSocacheMaxSize bytes 102400 skdhE
The maximum size (in bytes) of an entry to be placed in the cache
CacheSocacheMaxTime seconds 86400 skdhE
The maximum time (in seconds) for a document to be placed in the cache
CacheSocacheMinTime seconds 600 skdhE
The minimum time (in seconds) for a document to be placed in the cache
CacheSocacheReadSize bytes 0 skdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheSocacheReadTime milliseconds 0 skdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheStaleOnError on|off on skdhE
Serve stale content in place of 5xx responses.
CacheStoreExpired On|Off Off skdhE
Attempt to cache responses that the server reports as expired
CacheStoreNoStore On|Off Off skdhE
Attempt to cache requests or responses that have been marked as no-store.
CacheStorePrivate On|Off Off skdhE
Attempt to cache responses that the server has marked as private
CGIDScriptTimeout time[s|ms]skdhT
The length of time to wait for more output from the CGI program
CGIMapExtension cgi-yolu .uzantıdhÇ
CGI betik yorumlayıcısını saptama tekniğini belirler.
CGIPassAuth On|Off Off dhÇ
HTTP yetkilendirme başlıklarının betiklere CGI değişkenleri olarak aktarılmasını etkin kılar
CGIScriptTimeout time[s|ms]skdhT
The length of time to wait for more output from the CGI program
CGIVar değişken kuraldhÇ
Bazı CGI değişkenlerinin nasıl atanacağını belirler
CharsetDefault charsetskdhE
Charset to translate into
CharsetOptions option [option] ... ImplicitAdd skdhE
Configures charset translation behavior
CharsetSourceEnc charsetskdhE
Source charset of files
CheckBasenameMatch on|off On skdhE
Also match files with differing file name extensions.
CheckCaseOnly on|off Off skdhE
Limits the action of the speling module to case corrections
CheckSpelling on|off Off skdhE
Enables the spelling module
ChrootDir /dizin/yolusT
Sunucunun başlatıldıktan sonra chroot(8) yapacağı dizini belirler.
ContentDigest On|Off Off skdhÇ
Content-MD5 HTTP yanıt başlıklarının üretimini etkin kılar.
CookieDomain domainskdhE
The domain to which the tracking cookie applies
CookieExpires expiry-periodskdhE
Expiry time for the tracking cookie
CookieHTTPOnly on|off off skdhE
Adds the 'HTTPOnly' attribute to the cookie
CookieName token Apache skdhE
Name of the tracking cookie
CookieSameSite None|Lax|StrictskdhE
Adds the 'SameSite' attribute to the cookie
CookieSecure on|off off skdhE
Adds the 'Secure' attribute to the cookie
CookieStyle Netscape|Cookie|Cookie2|RFC2109|RFC2965 Netscape skdhE
Format of the cookie header field
CookieTracking on|off off skdhE
Enables tracking cookie
CoreDumpDirectory dizinsM
core dosyasını dökümlemek üzere Apache HTTP Sunucusunun geçmeye çalışacağı dizin.
CustomLog dosya|borulu-süreç biçem|takma-ad [env=[!]ortam-değişkeni]| expr=ifade]skT
Günlük dosyasın ismini ve girdi biçemini belirler.
Dav On|Off|provider-name Off dE
Enable WebDAV HTTP methods
DavBasePath root-pathdE
Configure repository root path
DavDepthInfinity on|off off skdE
Allow PROPFIND, Depth: Infinity requests
DavGenericLockDB file-pathskdE
Location of the DAV lock database
DavLockDB file-pathskE
Location of the DAV lock database
DavLockDiscovery on|off on skdhE
Enable lock discovery
DavMinTimeout seconds 0 skdE
Minimum amount of time the server holds a lock on a DAV resource
DBDExptime time-in-seconds 300 skE
Keepalive time for idle connections
DBDInitSQL "SQL statement"skE
Execute an SQL statement after connecting to a database
DBDKeep number 2 skE
Maximum sustained number of connections
DBDMax number 10 skE
Maximum number of connections
DBDMin number 1 skE
Minimum number of connections
DBDParams param1=value1[,param2=value2]skE
Parameters for database connection
DBDPersist On|OffskE
Whether to use persistent connections
DBDPrepareSQL "SQL statement" labelskE
Define an SQL prepared statement
DBDriver nameskE
Specify an SQL driver
DefaultIcon URL-yoluskdhT
Özel bir simge atanmamış dosyalar için gösterilecek simgeyi belirler.
DefaultLanguage language-tagskdhT
Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
DefaultRuntimeDir dizin-yolu DEFAULT_REL_RUNTIME +sÇ
Sunucunun çalışma anı dosyaları için temel dizin
DefaultType ortam-türü|none none skdhÇ
Değeri none olduğu takdirde, bu yönergenin bir uyarı vermekten başka bir etkisi yoktur. Önceki sürümlerde, bu yönerge, sunucunun ortam türünü saptayamadığı durumda göndereceği öntanımlı ortam türünü belirlerdi.
Define değişken-ismi [değişken-değeri]skdÇ
Bir değişken tanımlar
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix skE
How the outgoing ETag header should be modified during compression
DeflateBufferSize value 8096 skE
Fragment size to be compressed at one time by zlib
DeflateCompressionLevel valueskE
How much compression do we apply to the output
DeflateFilterNote [type] notenameskE
Places the compression ratio in a note for logging
DeflateInflateLimitRequestBody valueskdhE
Maximum size of inflated request bodies
DeflateInflateRatioBurst value 3 skdhE
Maximum number of times the inflation ratio for request bodies can be crossed
DeflateInflateRatioLimit value 200 skdhE
Maximum inflation ratio for request bodies
DeflateMemLevel value 9 skE
How much memory should be used by zlib for compression
DeflateWindowSize value 15 skE
Zlib compression window size
Deny from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
Controls which hosts are denied access to the server
<Directory dizin-yolu> ... </Directory>skÇ
Sadece ismi belirtilen dosya sistemi dizininde ve bunun altdizinlerinde ve bunların içeriğinde uygulanacak bir yönerge grubunu sarmalar.
DirectoryCheckHandler On|Off Off skdhT
Başka bir eylemci yapılandırılmışsa bu modülün nasıl yanıt vereceğini belirler
DirectoryIndex disabled | yerel-url [yerel-url] ... index.html skdhT
İstemci bir dizin istediğinde dizin içeriğini listeler.
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-kodu off skdhT
Dizin içerik listeleri için harici bir yönlendirme yapılandırır.
<DirectoryMatch düzifd> ... </DirectoryMatch>skÇ
Bir düzenli ifade ile eşleşen dosya sistemi dizinlerinin içeriklerine uygulanacak bir yönerge grubunu sarmalar.
DirectorySlash On|Off On skdhT
Bölü çizgisi ile biten yönlendirmeleri açar/kapar.
DocumentRoot dizin-yolu "/usr/local/apache/ +skÇ
İstemciye görünür olan ana belge ağacının kök dizinini belirler.
DTracePrivileges On|Off Off sD
Determines whether the privileges required by dtrace are enabled.
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
<Else> ... </Else>skdhÇ
Önceki bir <If> veya <ElseIf> bölümünün koşulu, çalışma anında bir istek tarafından yerine getirilmediği takdirde uygulanacak yönergeleri içerir
<ElseIf ifade> ... </ElseIf>skdhÇ
İçerdiği koşulun bir istek tarafınan sağlandığı ancak daha önceki bir <If> veya <ElseIf> bölümlerininkilerin sağlanmadığı durumda kapsadığı yönergelerin uygulanmasını sağlar
EnableExceptionHook On|Off Off sM
Bir çöküş sonrası olağandışılık eylemcilerini çalıştıracak kancayı etkin kılar.
EnableMMAP On|Off On skdhÇ
Teslimat sırasında okunacak dosyalar için bellek eşlemeyi etkin kılar.
EnableSendfile On|Off Off skdhÇ
Dosyaların istemciye tesliminde çekirdeğin dosya gönderme desteğinin kullanımını etkin kılar.
Error iletiskdhÇ
Özel bir hata iletisiyle yapılandırma çözümlemesini durdurur
ErrorDocument hata-kodu belgeskdhÇ
Bir hata durumunda sunucunun istemciye ne döndüreceğini belirler.
ErrorLog dosya-yolu|syslog[:[oluşum][:etiket]] logs/error_log (Uni +skÇ
Sunucunun hata günlüğünü tutacağı yeri belirler.
ErrorLogFormat [connection|request] biçemskÇ
Hata günlüğü girdileri için biçem belirtimi
ExampleskdhD
Demonstration directive to illustrate the Apache module API
ExpiresActive On|Off Off skdhE
Enables generation of Expires headers
ExpiresByType MIME-type <code>secondsskdhE
Value of the Expires header configured by MIME type
ExpiresDefault <code>secondsskdhE
Default algorithm for calculating expiration time
ExtendedStatus On|Off Off[*] sÇ
Her istekte ek durum bilgisinin izini sürer
ExtFilterDefine filtername parameterssE
Define an external filter
ExtFilterOptions option [option] ... NoLogStderr dE
Configure mod_ext_filter options
FallbackResource disabled | yerel-urlskdhT
Bir dosya ile eşleşmeyen istekler için öntanımlı URL tanımlar
FileETag bileşen ... MTime Size skdhÇ
Duruk dosyalar için ETag HTTP yanıt başlığını oluşturmakta kullanılacak dosya özniteliklerini belirler.
<Files dosya-adı> ... </Files>skdhÇ
Dosya isimleriyle eşleşme halinde uygulanacak yönergeleri içerir.
<FilesMatch düzifd> ... </FilesMatch>skdhÇ
Düzenli ifadelerin dosya isimleriyle eşleşmesi halinde uygulanacak yönergeleri içerir.
FilterChain [+=-@!]filter-name ...skdhT
Configure the filter chain
FilterDeclare filter-name [type]skdhT
Declare a smart filter
FilterProtocol filter-name [provider-name] proto-flagsskdhT
Deal with correct HTTP protocol handling
FilterProvider filter-name provider-name expressionskdhT
Register a content filter
FilterTrace filter-name levelskdT
Get debug/diagnostic information from mod_filter
FlushMaxPipelined sayı 5 skÇ
Ağa akıtılacak azami ardışık yanıt sayısı
FlushMaxThreshold bayt-sayısı 65536 skÇ
Bekleyen verilerin ağa boşaltılacağı eşik değer
ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer skdhT
Action to take if a single acceptable document is not found
ForceType ortam-türü|NonedhÇ
Bütün dosyaların belirtilen ortam türüyle sunulmasına sebep olur.
ForensicLog dosya-adı|borulu-süreçskE
Adli günlük için dosya ismini belirler.
GlobalLog dosya|boru|sağlayıcı biçem|takma_ad [env=[!]ortam_değişkeni| expr=ifade]sT
Günlük dosyasının ismini ve biçemini belirler
GprofDir /tmp/gprof/|/tmp/gprof/%skÇ
gmon.out ayrıntılı inceleme verisinin yazılacağı dizin
GracefulShutdownTimeout saniye 0 sM
Sunucunun nazikçe kapatılmasının ardından ana süreç çıkana kadar geçecek süre için bir zaman aşımı belirler.
Group unix-grubu #-1 sT
İsteklere yanıt verecek sunucunun ait olacağı grubu belirler.
H2CopyFiles on|off off skdhE
Determine file handling in responses
H2Direct on|off on for h2c, off for +skE
H2 Direct Protocol Switch
H2EarlyHint name valueskdhE
Add a response header to be picked up in 103 Early Hints
H2EarlyHints on|off off skE
Determine sending of 103 status codes
H2MaxDataFrameLen n 0 skE
Maximum bytes inside a single HTTP/2 DATA frame
H2MaxHeaderBlockLen n 0 skE
Maximum size of response headers
H2MaxSessionStreams n 100 skE
Maximum number of active streams per HTTP/2 session.
H2MaxWorkerIdleSeconds n 600 sE
Maximum number of seconds h2 workers remain idle until shut down.
H2MaxWorkers nsE
Maximum number of worker threads to use per child process.
H2MinWorkers nsE
Minimal number of worker threads to use per child process.
H2ModernTLSOnly on|off on skE
Require HTTP/2 connections to be "modern TLS" only
H2OutputBuffering on|off on skE
Determine buffering behaviour of output
H2Padding numbits 0 skE
Determine the range of padding bytes added to payload frames
H2ProxyRequests on|off off skE
En-/Disable forward proxy requests via HTTP/2
H2Push on|off on skdhE
H2 Server Push Switch
H2PushDiarySize n 256 skE
H2 Server Push Diary Size
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 skE
H2 Server Push Priority
H2PushResource [add] path [critical]skdhE
Declares resources for early pushing to the client
H2SerializeHeaders on|off off skE
Serialize Request/Response Processing Switch
H2StreamMaxMemSize bytes 65536 skE
Maximum amount of output data buffered per stream.
H2StreamTimeout time-interval[s]skdE
Maximum time waiting when sending/receiving data to stream processing
H2TLSCoolDownSecs seconds 1 skE
Configure the number of seconds of idle time on TLS before shrinking writes
H2TLSWarmUpSize amount 1048576 skE
Configure the number of bytes on TLS connection before doing max writes
H2Upgrade on|off on for h2c, off for +skdhE
H2 Upgrade Protocol Switch
H2WebSockets on|off off skE
En-/Disable WebSockets via HTTP/2
H2WindowSize bytes 65535 skE
Size of Stream Window for upstream data.
Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] skdhE
Configure HTTP response headers
HeaderName dosya-ismiskdhT
Dizin listesinin tepesine yerleştirilecek dosyanın ismini belirler.
HeartbeatAddress addr:portsD
Multicast address for heartbeat packets
HeartbeatListen addr:portsD
multicast address to listen for incoming heartbeat requests
HeartbeatMaxServers number-of-servers 10 sD
Specifies the maximum number of servers that will be sending heartbeat requests to this server
HeartbeatStorage file-path logs/hb.dat sD
Path to store heartbeat data when using flat-file storage
HeartbeatStorage file-path logs/hb.dat sD
Path to read heartbeat data
HostnameLookups On|Off|Double Off skdÇ
İstemci IP adresleri üzerinde DNS sorgularını etkin kılar.
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +skÇ
HTTP İstek İletilerindeki sınırlamalarda değişiklik yapar
IdentityCheck On|Off Off skdE
Enables logging of the RFC 1413 identity of the remote user
IdentityCheckTimeout seconds 30 skdE
Determines the timeout duration for ident requests
<If ifade> ... </If>skdhÇ
Çalışma anında bir koşul bir istek tarafından yerine getirildiği takdirde uygulanacak yönergeleri barındırır.
<IfDefine [!]parametre-adı> ... </IfDefine>skdhÇ
Başlatma sırasında bir doğruluk sınamasından sonra işleme sokulacak yönergeleri sarmalar.
<IfDirective [!]yönerge-adı> ... </IfDirective>skdhÇ
Belirtilen yönerge adının varlığı veya yokluğuna bağlı olarak çalıştırılacak yönergeleri sarmalar.
<IfFile [!]dosyaadı> ... </IfFile>skdhÇ
Başlatma sırasında bir dosyanın varlığı durumunda işleme sokulacak yönergeleri sarmalar.
<IfModule [!]modül-dosyası|modül-betimleyici> ... </IfModule>skdhÇ
Belli bir modülün varlığına veya yokluğuna göre işleme sokulacak yönergeleri sarmalar.
<IfSection [!]bölüm-adı> ... </IfSection>skdhÇ
Belirtilen bölüm adının varlığı veya yokluğuna bağlı olarak çalıştırılacak yönergeleri sarmalar.
<IfVersion [[!]operator] version> ... </IfVersion>skdhE
contains version dependent configuration
ImapBase map|referer|URL http://servername/ skdhT
Default base for imagemap files
ImapDefault error|nocontent|map|referer|URL nocontent skdhT
Default action when an imagemap is called with coordinates that are not explicitly mapped
ImapMenu none|formatted|semiformatted|unformatted formatted skdhT
Action if no coordinates are given when calling an imagemap
Include dosya-yolu|dizin-yolu|jokerskdÇ
Sunucu yapılandırma dosyalarının başka dosyaları içermesini sağlar.
IncludeOptional dosya-yolu|dizin-yolu|jokerskdÇ
Diğer yapılandırma dosyalarının sunucu yapılandırma dosyasına dahil edilmesini sağlar
IndexHeadInsert "imlenim ..."skdhT
Bir dizin sayfasının HEAD bölümüne metin yerleştirir.
IndexIgnore dosya [dosya] ... "." skdhT
Dizin içerik listesinden gizlenecek dosyaların listesi belirtilir.
IndexIgnoreReset ON|OFFskdhT
Bir dizini listelerken gizlenecek dosyalar listesini boşaltır
IndexOptions [+|-]seçenek [[+|-]seçenek] ...skdhT
Dizin içerik listesini yapılandıracak seçenekler belirtilir.
IndexOrderDefault Ascending|Descending Name|Date|Size|Description Ascending Name skdhT
Dizin içerik listesinin öntanımlı sıralamasını belirler.
IndexStyleSheet url-yoluskdhT
Dizin listesine bir biçembent ekler.
InputSed sed-commanddhD
Sed command to filter request data (typically POST data)
ISAPIAppendLogToErrors on|off off skdhT
Record HSE_APPEND_LOG_PARAMETER requests from ISAPI extensions to the error log
ISAPIAppendLogToQuery on|off on skdhT
Record HSE_APPEND_LOG_PARAMETER requests from ISAPI extensions to the query field
ISAPICacheFile file-path [file-path] ...skT
ISAPI .dll files to be loaded at startup
ISAPIFakeAsync on|off off skdhT
Fake asynchronous support for ISAPI callbacks
ISAPILogNotSupported on|off off skdhT
Log unsupported feature requests from ISAPI extensions
ISAPIReadAheadBuffer size 49152 skdhT
Size of the Read Ahead Buffer sent to ISAPI extensions
KeepAlive On|Off On skÇ
HTTP kalıcı bağlantılarını etkin kılar
KeepAliveTimeout sayı[ms] 5 skÇ
Bir kalıcı bağlantıda sunucunun bir sonraki isteği bekleme süresi
KeptBodySize azami_bayt_sayısı 0 dT
mod_include gibi süzgeçler tarafından kullanılma olasılığına karşı istek gövdesi iptal edilmek yerine belirtilen azami boyutta tutulur.
LanguagePriority MIME-lang [MIME-lang] ...skdhT
The precedence 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
LDAPConnectionPoolTTL n -1 skE
Discard backend connections that have been sitting in the connection pool too long
LDAPConnectionTimeout secondssE
Specifies the socket connection timeout in seconds
LDAPLibraryDebug 7sE
Enable debugging in the LDAP SDK
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
LDAPReferralHopLimit numberdhE
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferrals On|Off|default On dhE
Enable referral chasing during queries to the LDAP server.
LDAPRetries number-of-retries 3 sE
Configures the number of LDAP server retries.
LDAPRetryDelay seconds 0 sE
Configures the delay between LDAP server retries.
LDAPSharedCacheFile directory-path/filenamesE
Sets the shared memory cache file
LDAPSharedCacheSize bytes 500000 sE
Size in bytes of the shared-memory cache
LDAPTimeout seconds 60 sE
Specifies the timeout for LDAP search and bind operations, in seconds
LDAPTrustedClientCert type directory-path/filename/nickname [password]dhE
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 typeskE
Specifies the SSL/TLS mode to be used when connecting to an LDAP server.
LDAPVerifyServerCert On|Off On sE
Force server certificate verification
<Limit yöntem [yöntem] ... > ... </Limit>dhÇ
Erişimi sınırlanacak HTTP yöntemleri için erişim sınırlayıcıları sarmalar.
<LimitExcept yöntem [yöntem] ... > ... </LimitExcept>dhÇ
İsimleri belirtilenler dışında kalan HTTP yöntemleri için kullanılacak erişim sınırlayıcıları sarmalar.
LimitInternalRecursion sayı [sayı] 10 skÇ
Dahili yönlendirmelerin ve istek içi isteklerin azami sayısını belirler.
LimitRequestBody bayt-sayısı 1073741824 skdhÇ
İstemci tarafından gönderilen HTTP istek gövdesinin toplam uzunluğunu sınırlar.
LimitRequestFields sayı 100 skÇ
İstemciden kabul edilecek HTTP isteği başlık alanlarının sayısını sınırlar.
LimitRequestFieldSize bayt-sayısı 8190 skÇ
İstemciden kabul edilecek HTTP isteği başlık uzunluğunu sınırlar.
LimitRequestLine bayt-sayısı 8190 skÇ
İstemciden kabul edilecek HTTP istek satırının uzunluğunu sınırlar.
LimitXMLRequestBody bayt-sayısı 1000000 skdhÇ
Bir XML temelli istek gövdesinin uzunluğunu sınırlar.
Listen [IP-adresi:]port-numarası [protokol]sM
Sunucunun dinleyeceği IP adresini ve portu belirler.
ListenBackLog kuyruk-uzunluğu 511 sM
Bekleyen bağlantılar kuyruğunun azami uzunluğunu belirler
ListenCoresBucketsRatio oran 0 (iptal) sM
İşlemci çekirdek sayısının dinleyenlerin buket sayısına oranı
LoadFile dosya-ismi [dosya-ismi] ...skE
Belirtilen nesne dosyasını veya kütüphaneyi sunucu ile ilintiler.
LoadModule modül dosya-ismiskE
Belirtilen nesne dosyasını veya kütüphaneyi sunucu ile ilintiler ve etkin modül listesine ekler.
<Location URL-yolu|URL> ... </Location>skÇ
İçerdiği yönergeler sadece eşleşen URL’lere uygulanır.
<LocationMatch düzifade> ... </LocationMatch>skÇ
İçerdiği yönergeler sadece düzenli ifadelerle eşleşen URL’lere uygulanır.
LogFormat biçem|takma-ad [takma-ad] "%h %l %u %t \"%r\" +skT
Bir günlük dosyasında kullanılmak üzere girdi biçemi tanımlar.
LogIOTrackTTFB ON|OFF OFF skdhE
İlk baytın yazılmasına kadar geçen süreyi izler
LogLevel [modül:]seviye [modül:seviye] ... warn skdÇ
Hata günlüklerinin ayrıntı seviyesini belirler.
LogMessage message [hook=hook] [expr=expression] dD
Log user-defined message to error log
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Plug an authorization provider function into mod_authz_core
LuaCodeCache stat|forever|never stat skdhE
Configure the compiled code cache.
LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]skdhE
Provide a hook for the access_checker phase of request processing
LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]skdhE
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]skdhE
Provide a hook for the check_user_id phase of request processing
LuaHookFixups /path/to/lua/script.lua hook_function_nameskdhE
Provide a hook for the fixups phase of a request processing
LuaHookInsertFilter /path/to/lua/script.lua hook_function_nameskdhE
Provide a hook for the insert_filter phase of request processing
LuaHookLog /path/to/lua/script.lua log_function_nameskdhE
Provide a hook for the access log phase of a request processing
LuaHookMapToStorage /path/to/lua/script.lua hook_function_nameskdhE
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslate /path/to/lua/script.lua hook_function_nameskdhE
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]skE
Provide a hook for the translate name phase of request processing
LuaHookTypeChecker /path/to/lua/script.lua hook_function_nameskdhE
Provide a hook for the type_checker phase of request processing
LuaInherit none|parent-first|parent-last parent-first skdhE
Controls how parent configuration sections are merged into children
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content input filtering
LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]skdhE
Map a path to a lua handler
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content output filtering
LuaPackageCPath /path/to/include/?.soaskdhE
Add a directory to lua's package.cpath
LuaPackagePath /path/to/include/?.luaskdhE
Add a directory to lua's package.path
LuaQuickHandler /path/to/script.lua hook_function_nameskE
Provide a hook for the quick handler of request processing
LuaRoot /path/to/a/directoryskdhE
Specify the base path for resolving relative paths for mod_lua directives
LuaScope once|request|conn|thread|server [min] [max] once skdhE
One of once, request, conn, thread -- default is once
<Macro name [par1 .. parN]> ... </Macro>skdT
Define a configuration file macro
MaxConnectionsPerChild sayı 0 sM
Tek bir çocuk sürecin ömrü boyunca işleme sokabileceği istek sayısını sınırlamakta kullanılır.
MaxKeepAliveRequests sayı 100 skÇ
Bir kalıcı bağlantıda izin verilen istek sayısı
MaxMemFree kB-sayısı 2048 sM
free() çağrılmaksızın ana bellek ayırıcının ayırmasına izin verilen azami bellek miktarını belirler.
MaxRangeOverlaps default | unlimited | none | aralık-sayısı 20 skdÇ
Özkaynağın tamamını döndürmeden önce izin verilen üst üste binen aralık sayısı (100-200,150-300 gibi)
MaxRangeReversals default | unlimited | none | aralık-sayısı 20 skdÇ
Özkaynağın tamamını döndürmeden önce izin verilen ters sıralı aralık sayısı (100-200,50-70 gibi)
MaxRanges default | unlimited | none | aralık-sayısı 200 skdÇ
Özkaynağın tamamını döndürmeden önce izin verilen aralık sayısı
MaxRequestWorkers sayısM
Aynı anda işleme sokulacak azami bağlantı sayısı
MaxSpareServers sayı 10 sM
Boştaki çocuk süreçlerin azami sayısı
MaxSpareThreads numbersM
Boştaki azami evre sayısını belirler
MaxThreads number 2048 sM
Set the maximum number of worker threads
MDActivationDelay durationsD
How long to delay activation of new certificates
MDBaseServer on|off off sD
Control if base server may be managed or only virtual hosts.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sD
Type of ACME challenge used to prove domain ownership.
MDCertificateAgreement acceptedsD
You confirm that you accepted the Terms of Service of the Certificate Authority.
MDCertificateAuthority url letsencrypt sD
The URL(s) of the ACME Certificate Authority to use.
MDCertificateCheck name urlsD
Set name and URL pattern for a certificate monitoring site.
MDCertificateFile path-to-pem-filesD
Specify a static certificate file for the MD.
MDCertificateKeyFile path-to-filesD
Specify a static private key for for the static cerrtificate.
MDCertificateMonitor name url crt.sh https://crt. +sD
The URL of a certificate log monitor.
MDCertificateProtocol protocol ACME sD
The protocol to use with the Certificate Authority.
MDCertificateStatus on|off on sD
Exposes public certificate information in JSON.
MDChallengeDns01 path-to-commandsD
Set the command for setup/teardown of dns-01 challenges
MDChallengeDns01Version 1|2 1 sD
Set the type of arguments to call MDChallengeDns01 with
MDCheckInterval duration 12h sD
Determines how often certificates are checked
MDContactEmail addresssD
Email address used for account registration
MDDriveMode always|auto|manual auto sD
former name of MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sD
Set the external account binding keyid and hmac values to use at CA
MDHttpProxy urlsD
Define a proxy for outgoing connections.
MDMatchNames all|servernames all sD
Determines how DNS names are matched to vhosts
MDMember hostnamesD
Additional hostname for the managed domain.
MDMembers auto|manual auto sD
Control if the alias domain names are automatically added.
MDMessageCmd path-to-cmd optional-argssD
Handle events for Manage Domains
MDMustStaple on|off off sD
Control if new certificates carry the OCSP Must Staple flag.
MDNotifyCmd path [ args ]sD
Run a program when a Managed Domain is ready.
MDomain dns-name [ other-dns-name... ] [auto|manual]sD
Define list of domain names that belong to one group.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sD
Container for directives applied to the same managed domains.
MDPortMap map1 [ map2 ] http:80 https:443 sD
Map external to internal ports for domain ownership verification.
MDPrivateKeys type [ params... ] RSA 2048 sD
Set type and size of the private keys generated.
MDProfile namesD
Use a specific ACME profile from the CA
MDProfileMandatory on|off off sD
Control if an MDProfile is mandatory.
MDRenewMode always|auto|manual auto sD
Controls if certificates shall be renewed.
MDRenewWindow duration 33% sD
Control when a certificate will be renewed.
MDRequireHttps off|temporary|permanent off sD
Redirects http: traffic to https: for Managed Domains.
MDRetryDelay duration 5s sD
Time length for first retry, doubled on every consecutive error.
MDRetryFailover number 13 sD
The number of errors before a failover to another CA is triggered
MDServerStatus on|off on sD
Control if Managed Domain information is added to server-status.
MDStapleOthers on|off on sD
Enable stapling for certificates not managed by mod_md.
MDStapling on|off off sD
Enable stapling for all or a particular MDomain.
MDStaplingKeepResponse duration 7d sD
Controls when old responses should be removed.
MDStaplingRenewWindow duration 33% sD
Control when the stapling responses will be renewed.
MDStoreDir path md sD
Path on the local file system to store the Managed Domains data.
MDStoreLocks on|off|duration off sD
Configure locking of store for updates
MDWarnWindow duration 10% sD
Define the time window when you want to be warned about an expiring certificate.
MemcacheConnTTL num[units] 15s skE
Keepalive time for idle connections
MergeSlashes ON|OFF ON skÇ
Sunucunun URL’lerde ardışık bölü çizgilerini birleştirip birleştirmeyeceğini denetler.
MergeTrailers [on|off] off skÇ
Trailer alanlarının başlığa dahil edilip edilmeyeceğini belirler
MetaDir directory .web skdhE
Name of the directory to find CERN-style meta information files
MetaFiles on|off off skdhE
Activates CERN meta-file processing
MetaSuffix suffix .meta skdhE
File name suffix for the file containing CERN-style meta information
MimeMagicFile file-pathskE
Enable MIME-type determination based on file contents using the specified magic file
MinSpareServers sayı 5 sM
Boştaki çocuk süreçlerin asgari sayısı
MinSpareThreads sayısM
İsteklerin ani artışında devreye girecek boştaki evrelerin asgari sayısını belirler.
MMapFile file-path [file-path] ...sD
Map a list of files into memory at startup time
ModemStandard V.21|V.26bis|V.32|V.34|V.92dD
Modem standard to simulate
ModMimeUsePathInfo On|Off Off dT
Tells mod_mime to treat path_info components as part of the filename
MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers [Handlers|Filters] NegotiatedOnly skdhT
The types of files that will be included when searching for a matching file with MultiViews
Mutex mekanizma [default|muteks-ismi] ... [OmitPID] default sÇ
Muteks mekanizmasını ve kilit dosyası dizinini tüm muteksler veya belirtilenler için yapılandırır
NameVirtualHost adres[:port]sÇ
ÖNERİLMİYOR: İsme dayalı sanal konaklar için IP adresi belirtir
NoProxy host [host] ...skE
Hosts, domains, or networks that will be connected to directly
NWSSLTrustedCerts filename [filename] ...sT
List of additional client certificates
NWSSLUpgradeable [IP-address:]portnumbersT
Allows a connection to be upgraded to an SSL connection upon request
Options [+|-]seçenek [[+|-]seçenek] ... FollowSymlinks skdhÇ
Belli bir dizinde geçerli olacak özellikleri yapılandırır.
Order ordering Deny,Allow dhE
Controls the default access state and the order in which Allow and Deny are evaluated.
OutputSed sed-commanddhD
Sed command for filtering response content
PassEnv ortam-değişkeni [ortam-değişkeni] ...skdhT
Ortam değişkenlerini kabuktan aktarır.
PidFile dosya logs/httpd.pid sM
Ana sürecin süreç kimliğinin (PID) kaydedileceği dosyayı belirler.
PrivilegesMode FAST|SECURE|SELECTIVE FAST skdD
Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Protocol protokolskÇ
Dinlenen bir soket için protokol
ProtocolEcho On|Off Off skD
Turn the echo server on or off
Protocols protokol ... http/1.1 skÇ
Sunucu/sanal konak için kullanılabilecek protokoller
ProtocolsHonorOrder On|Off On skÇ
Uzlaşma sırasında protokollerin öncelik sırasını belirler
<Proxy wildcard-url> ...</Proxy>skE
Container for directives applied to proxied resources
Proxy100Continue Off|On On skdE
Forward 100-continue expectation to the origin server
ProxyAddHeaders Off|On On skdE
Add proxy information in X-Forwarded-* headers
ProxyBadHeader IsError|Ignore|StartBody IsError skE
Determines how to handle bad header lines in a response
ProxyBlock *|word|host|domain [word|host|domain] ...skE
Words, hosts, or domains that are banned from being proxied
ProxyDomain DomainskE
Default domain name for proxied requests
ProxyErrorOverride Off|On [code ...] Off skdE
Override error pages for proxied content
ProxyExpressDBMFile pathnameskE
Pathname to DBM file.
ProxyExpressDBMType type default skE
DBM type of file.
ProxyExpressEnable on|off off skE
Enable the module functionality.
ProxyFCGIBackendType FPM|GENERIC FPM skdhE
Specify the type of backend FastCGI application
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]skdhE
Allow variables sent to FastCGI servers to be fixed up
ProxyFtpDirCharset character_set ISO-8859-1 skdE
Define the character set for proxied FTP listings
ProxyFtpEscapeWildcards on|off on skdE
Whether wildcards in requested filenames are escaped when sent to the FTP server
ProxyFtpListOnWildcard on|off on skdE
Whether wildcards in requested filenames trigger a file listing
ProxyHCExpr name {ap_expr expression}skE
Creates a named condition expression to use to determine health of the backend based on its response
ProxyHCTemplate name parameter=setting [...]skE
Creates a named template for setting various health check parameters
ProxyHCTPsize size 16 sE
Sets the total server-wide size of the threadpool used for the health check workers
ProxyHTMLBufSize bytes 8192 skdT
Sets the buffer size increment for buffering inline scripts and stylesheets.
ProxyHTMLCharsetOut Charset | *skdT
Specify a charset for mod_proxy_html output.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
skdT
Sets an HTML or XHTML document type declaration.
ProxyHTMLEnable On|Off Off skdT
Turns the proxy_html filter on or off.
ProxyHTMLEvents attribute [attribute ...]skdT
Specify attributes to treat as scripting events.
ProxyHTMLExtended On|Off Off skdT
Determines whether to fix links in inline scripts, stylesheets, and scripting events.
ProxyHTMLFixups [lowercase] [dospath] [reset]skdT
Fixes for simple HTML errors.
ProxyHTMLInterp On|Off Off skdT
Enables per-request interpolation of ProxyHTMLURLMap rules.
ProxyHTMLLinks element attribute [attribute2 ...]skdT
Specify HTML elements that have URL attributes to be rewritten.
ProxyHTMLMeta On|Off Off skdT
Turns on or off extra pre-parsing of metadata in HTML <head> sections.
ProxyHTMLStripComments On|Off Off skdT
Determines whether to strip HTML comments.
ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]skdT
Defines a rule to rewrite HTML links
ProxyIOBufferSize bytes 8192 skE
Determine size of internal data throughput buffer
<ProxyMatch regex> ...</ProxyMatch>skE
Container for directives applied to regular-expression-matched proxied resources
ProxyMaxForwards number -1 skE
Maximum number of proxies that a request can be forwarded through
ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] [noquery]skdE
Maps remote servers into the local server URL-space
ProxyPassInherit On|Off On skE
Inherit ProxyPass directives defined from the main server
ProxyPassInterpolateEnv On|Off Off skdE
Enable Environment Variable interpolation in Reverse Proxy configurations
ProxyPassMatch [regex] !|url [key=value [key=value ...]]skdE
Maps remote servers into the local server URL-space using regular expressions
ProxyPassReverse [path] url [interpolate]skdE
Adjusts the URL in HTTP response headers sent from a reverse proxied server
ProxyPassReverseCookieDomain internal-domain public-domain [interpolate]skdE
Adjusts the Domain string in Set-Cookie headers from a reverse- proxied server
ProxyPassReverseCookiePath internal-path public-path [interpolate]skdE
Adjusts the Path string in Set-Cookie headers from a reverse- proxied server
ProxyPreserveHost On|Off Off skdE
Use incoming Host HTTP request header for proxy request
ProxyReceiveBufferSize bytes 0 skE
Network buffer size for proxied HTTP and FTP connections
ProxyRemote match remote-server [username:password]skE
Remote proxy used to handle certain requests
ProxyRemoteMatch regex remote-server [username:password]skE
Remote proxy used to handle requests matched by regular expressions
ProxyRequests On|Off Off skE
Enables forward (standard) proxy requests
ProxySCGIInternalRedirect On|Off|Headername On skdE
Enable or disable internal redirect responses from the backend
ProxySCGISendfile On|Off|Headername Off skdE
Enable evaluation of X-Sendfile pseudo response header
ProxySet url key=value [key=value ...]skdE
Set various Proxy balancer or member parameters
ProxySourceAddress addressskE
Set local IP address for outgoing proxy connections
ProxyStatus Off|On|Full Off skE
Show Proxy LoadBalancer status in mod_status
ProxyTimeout secondsskE
Network timeout for proxied requests
ProxyVia On|Off|Full|Block Off skE
Information provided in the Via HTTP response header for proxied requests
ProxyWebsocketFallbackToProxyHttp On|Off On skE
Instructs this module to let mod_proxy_http handle the request
QualifyRedirectURL On|Off Off skdÇ
REDIRECT_URL ortam değişkeninin tamamen nitelenmiş olup olmayacağını denetler
ReadBufferSize bayt-sayısı 8192 skdÇ
Veriyi okumakta kullanılacak tampon sayısı
ReadmeName dosya-ismiskdhT
Dizin listesinin sonuna yerleştirilecek dosyanın ismini belirler.
ReceiveBufferSize bayt-sayısı 0 sM
TCP alım tamponu boyu
Redirect [durum] [URL-yolu] URLskdhT
İstemciyi, bir yönlendirme isteği döndürerek farklı bir URL’ye yönlendirir.
RedirectMatch [durum] düzenli-ifade URLskdhT
Geçerli URL ile eşleşen bir düzenli ifadeye dayanarak bir harici yönlendirme gönderir.
RedirectPermanent URL-yolu URLskdhT
İstemciyi, kalıcı bir yönlendirme isteği döndürerek farklı bir URL’ye yönlendirir.
RedirectRelative On|Off Off skdT
Allows relative redirect targets.
RedirectTemp URL-yolu URLskdhT
İstemciyi, geçici bir yönlendirme isteği döndürerek farklı bir URL’ye yönlendirir.
RedisConnPoolTTL num[units] 15s skE
TTL used for the connection pool with the Redis server(s)
RedisTimeout num[units] 5s skE
R/W timeout used for the connection with the Redis server(s)
ReflectorHeader inputheader [outputheader]skdhT
Reflect an input header to the output headers
RegexDefaultOptions [none] [+|-]seçenek [[+|-]seçenek] ... DOTALL DOLLAR_ENDON +sÇ
Regex düzenli ifadeleri için öntanımlı/küresel seçenekleri yapılandırır
RegisterHttpMethod yöntem [yöntem [...]]sÇ
Standart olmayan HTTP yöntemlerini devreye alır
RemoteIPHeader header-fieldskT
Declare the header field which should be parsed for useragent IP addresses
RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...skT
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPInternalProxyList filenameskT
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPProxiesHeader HeaderFieldNameskT
Declare the header field which will record all intermediate IP addresses
RemoteIPProxyProtocol On|OffskT
Enable or disable PROXY protocol handling
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]skT
Disable processing of PROXY header for certain hosts or networks
RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...skT
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPTrustedProxyList filenameskT
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoveCharset extension [extension] ...kdhT
Removes any character set associations for a set of file extensions
RemoveEncoding extension [extension] ...kdhT
Removes any content encoding associations for a set of file extensions
RemoveHandler extension [extension] ...kdhT
Removes any handler associations for a set of file extensions
RemoveInputFilter extension [extension] ...kdhT
Removes any input filter associations for a set of file extensions
RemoveLanguage extension [extension] ...kdhT
Removes any language associations for a set of file extensions
RemoveOutputFilter extension [extension] ...kdhT
Removes any output filter associations for a set of file extensions
RemoveType extension [extension] ...kdhT
Removes any content type associations for a set of file extensions
RequestHeader add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] skdhE
Configure HTTP request headers
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate] handshake=0 header= +skE
Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Require [not] entity-name [entity-name] ...dhT
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll> ... </RequireAll>dhT
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny> ... </RequireAny>dhT
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone> ... </RequireNone>dhT
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
RewriteBase URL-pathdhE
Sets the base URL for per-directory rewrites
RewriteCond TestString CondPattern [flags]skdhE
Defines a condition under which rewriting will take place
RewriteEngine on|off off skdhE
Enables or disables runtime rewriting engine
RewriteMap MapName MapType:MapSource [MapTypeOptions] skE
Defines a mapping function for key-lookup
RewriteOptions OptionsskdhE
Sets some special options for the rewrite engine
RewriteRule Pattern Substitution [flags]skdhE
Defines rules for the rewriting engine
RLimitCPU saniye|max [saniye|max]skdhÇ
Apache httpd alt süreçleri tarafından çalıştırılan süreçlerin işlemci tüketimine sınırlama getirir.
RLimitMEM bayt-sayısı|max [bayt-sayısı|max] skdhÇ
Apache httpd alt süreçleri tarafından çalıştırılan süreçlerin bellek tüketimine sınırlama getirir.
RLimitNPROC sayı|max [sayı|max]skdhÇ
Apache httpd alt süreçleri tarafından çalıştırılabilecek süreç sayısına sınırlama getirir.
Satisfy Any|All All dhE
Interaction between host-level access control and user authentication
ScoreBoardFile dosya-yolu logs/apache_runtime +sM
Çocuk süreçler için eşgüdüm verisini saklamakta kullanılan dosyanın yerini belirler.
Script method cgi-scriptskdT
Activates a CGI script for a particular request method.
ScriptAlias [URL-yolu] dosya-yolu|dizin-yoluskdT
Bir URL’yi dosya sistemindeki bir yere eşler ve hedefi bir CGI betiği olarak çalıştırır.
ScriptAliasMatch düzenli-ifade dosya-yolu|dizin-yoluskT
Bir URL’yi dosya sistemindeki bir yere düzenli ifade kullanarak eşler ve hedefi bir CGI betiği olarak çalıştırır.
ScriptInterpreterSource Registry|Registry-Strict|Script Script skdhÇ
CGI betikleri için yorumlayıcı belirleme tekniği
ScriptLog file-pathskT
Location of the CGI script error logfile
ScriptLogBuffer bytes 1024 skT
Maximum amount of PUT or POST requests that will be recorded in the scriptlog
ScriptLogLength bytes 10385760 skT
Size limit of the CGI script logfile
ScriptSock file-path cgisock sT
The filename prefix of the socket to use for communication with the cgi daemon
SecureListen [IP-address:]portnumber Certificate-Name [MUTUAL]sT
Enables SSL encryption for the specified port
SeeRequestTail On|Off Off sÇ
İsteğin 63 karakterden büyük olduğu varsayımıyla, mod_status'un ilk 63 karakteri mi yoksa son 63 karakteri mi göstereceğini belirler.
SendBufferSize bayt-sayısı 0 sM
TCP tamponu boyu
ServerAdmin eposta-adresi|URLskÇ
Sunucunun hata iletilerinde istemciye göstereceği eposta adresi
ServerAlias konakadı [konakadı] ...kÇ
İstekleri isme dayalı sanal konaklarla eşleştirilirken kullanılacak konak adları için başka isimler belirtebilmeyi sağlar.
ServerLimit sayısM
Ayarlanabilir süreç sayısının üst sınırını belirler.
ServerName [şema://]alan-adı|ip-adresi[:port] skÇ
Sunucunun özdeşleşeceği konak ismi ve port.
ServerPath URL-yolukÇ
Uyumsuz bir tarayıcı tarafından erişilmesi için bir isme dayalı sanal konak için meşru URL yolu
ServerRoot dizin-yolu /usr/local/apache sÇ
Sunucu yapılandırması için kök dizin
ServerSignature On|Off|EMail Off skdhÇ
Sunucu tarafından üretilen belgelerin dipnotunu ayarlar.
ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full Full sÇ
Server HTTP yanıt başlığını yapılandırır.
Session On|Off Off skdhE
Enables a session for the current directory or location
SessionCookieName name attributesskdhE
Name and attributes for the RFC2109 cookie storing the session
SessionCookieName2 name attributesskdhE
Name and attributes for the RFC2965 cookie storing the session
SessionCookieRemove On|Off Off skdhE
Control for whether session cookies should be removed from incoming HTTP headers
SessionCryptoCipher name aes256 skdhD
The crypto cipher to be used to encrypt the session
SessionCryptoDriver name [param[=value]]sD
The crypto driver to be used to encrypt the session
SessionCryptoPassphrase secret [ secret ... ] skdhD
The key used to encrypt the session
SessionCryptoPassphraseFile filenameskdD
File containing keys used to encrypt the session
SessionDBDCookieName name attributesskdhE
Name and attributes for the RFC2109 cookie storing the session ID
SessionDBDCookieName2 name attributesskdhE
Name and attributes for the RFC2965 cookie storing the session ID
SessionDBDCookieRemove On|Off On skdhE
Control for whether session ID cookies should be removed from incoming HTTP headers
SessionDBDDeleteLabel label deletesession skdhE
The SQL query to use to remove sessions from the database
SessionDBDInsertLabel label insertsession skdhE
The SQL query to use to insert sessions into the database
SessionDBDPerUser On|Off Off skdhE
Enable a per user session
SessionDBDSelectLabel label selectsession skdhE
The SQL query to use to select sessions from the database
SessionDBDUpdateLabel label updatesession skdhE
The SQL query to use to update existing sessions in the database
SessionEnv On|Off Off skdhE
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionExclude pathskdhE
Define URL prefixes for which a session is ignored
SessionExpiryUpdateInterval interval 0 (always update) skdhE
Define the number of seconds a session's expiry may change without the session being updated
SessionHeader headerskdhE
Import session updates from a given HTTP response header
SessionInclude pathskdhE
Define URL prefixes for which a session is valid
SessionMaxAge maxage 0 skdhE
Define a maximum age in seconds for a session
SetEnv ortam-değişkeni [değer]skdhT
Ortam değişkenlerini tanımlar.
SetEnvIf öznitelik düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...skdhT
Ortam değişkenlerini isteğin özniteliklerine göre atar.
SetEnvIfExpr ifade [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...skdhT
Bir ap_expr ifadesine dayanarak ortam değişkenlerine değer atar
SetEnvIfNoCase öznitelik düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...skdhT
Ortam değişkenlerini isteğin özniteliklerinde harf büyüklüğüne bağlı olmaksızın yapılmış tanımlara göre atar.
SetHandler eylemci-ismi|none|ifadeskdhÇ
Eşleşen tüm dosyaların belli bir eylemci tarafından işlenmesine sebep olur.
SetInputFilter süzgeç[;süzgeç...]skdhÇ
POST girdilerini ve istemci isteklerini işleyecek süzgeçleri belirler.
SetOutputFilter süzgeç[;süzgeç...]skdhÇ
Sunucunun yanıtlarını işleyecek süzgeçleri belirler.
SSIEndTag tag "-->" skT
String that ends an include element
SSIErrorMsg message "[an error occurred +skdhT
Error message displayed when there is an SSI error
SSIETag on|off off dhT
Controls whether ETags are generated by the server.
SSILastModified on|off off dhT
Controls whether Last-Modified headers are generated by the server.
SSILegacyExprParser on|off off dhT
Enable compatibility mode for conditional expressions.
SSIStartTag tag "<!--#" skT
String that starts an include element
SSITimeFormat formatstring "%A, %d-%b-%Y %H:%M +skdhT
Configures the format in which date strings are displayed
SSIUndefinedEcho string "(none)" skdhT
String displayed when an unset variable is echoed
SSLCACertificateFile file-pathskE
File of concatenated PEM-encoded CA Certificates for Client Auth
SSLCACertificatePath directory-pathskE
Directory of PEM-encoded CA Certificates for Client Auth
SSLCADNRequestFile file-pathskE
File of concatenated PEM-encoded CA Certificates for defining acceptable CA names
SSLCADNRequestPath directory-pathskE
Directory of PEM-encoded CA Certificates for defining acceptable CA names
SSLCARevocationCheck chain|leaf|none [flags ...] none skE
Enable CRL-based revocation checking
SSLCARevocationFile file-pathskE
File of concatenated PEM-encoded CA CRLs for Client Auth
SSLCARevocationPath directory-pathskE
Directory of PEM-encoded CA CRLs for Client Auth
SSLCertificateChainFile file-pathskE
File of PEM-encoded Server CA Certificates
SSLCertificateFile file-path|certidskE
Server PEM-encoded X.509 certificate data file or token identifier
SSLCertificateKeyFile file-path|keyidskE
Server PEM-encoded private key file
SSLCipherSuite [protocol] cipher-spec DEFAULT (depends on +skdhE
Cipher Suite available for negotiation in SSL handshake
SSLCompression on|off off skE
Enable compression on the SSL level
SSLCryptoDevice engine builtin sE
Enable use of a cryptographic hardware accelerator
SSLEngine on|off|optional off skE
SSL Engine Operation Switch
SSLFIPS on|off off sE
SSL FIPS mode Switch
SSLHonorCipherOrder on|off off skE
Option to prefer the server's cipher preference order
SSLInsecureRenegotiation on|off off skE
Option to enable support for insecure renegotiation
SSLOCSPDefaultResponder uriskE
Set the default responder URI for OCSP validation
SSLOCSPEnable on|leaf|off off skE
Enable OCSP validation of the client certificate chain
SSLOCSPNoverify on|off off skE
skip the OCSP responder certificates verification
SSLOCSPOverrideResponder on|off off skE
Force use of the default responder URI for OCSP validation
SSLOCSPProxyURL urlskE
Proxy URL to use for OCSP requests
SSLOCSPResponderCertificateFile fileskE
Set of trusted PEM encoded OCSP responder certificates
SSLOCSPResponderTimeout seconds 10 skE
Timeout for OCSP queries
SSLOCSPResponseMaxAge seconds -1 skE
Maximum allowable age for OCSP responses
SSLOCSPResponseTimeSkew seconds 300 skE
Maximum allowable time skew for OCSP response validation
SSLOCSPUseRequestNonce on|off on skE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd command-name command-valueskE
Configure OpenSSL parameters through its SSL_CONF API
SSLOptions [+|-]option ...skdhE
Configure various SSL engine run-time options
SSLPassPhraseDialog type builtin sE
Type of pass phrase dialog for encrypted private keys
SSLProtocol [+|-]protocol ... all -SSLv3 (up to 2 +skE
Configure usable SSL/TLS protocol versions
SSLProxyCACertificateFile file-pathskvE
File of concatenated PEM-encoded CA Certificates for Remote Server Auth
SSLProxyCACertificatePath directory-pathskvE
Directory of PEM-encoded CA Certificates for Remote Server Auth
SSLProxyCARevocationCheck chain|leaf|none none skvE
Enable CRL-based revocation checking for Remote Server Auth
SSLProxyCARevocationFile file-pathskvE
File of concatenated PEM-encoded CA CRLs for Remote Server Auth
SSLProxyCARevocationPath directory-pathskvE
Directory of PEM-encoded CA CRLs for Remote Server Auth
SSLProxyCheckPeerCN on|off on skvE
Whether to check the remote server certificate's CN field
SSLProxyCheckPeerExpire on|off on skvE
Whether to check if remote server certificate is expired
SSLProxyCheckPeerName on|off on skvE
Configure host name checking for remote server certificates
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +skvE
Cipher Suite available for negotiation in SSL proxy handshake
SSLProxyEngine on|off off skvE
SSL Proxy Engine Operation Switch
SSLProxyMachineCertificateChainFile filenameskvE
File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
SSLProxyMachineCertificateFile filenameskvE
File of concatenated PEM-encoded client certificates and keys to be used by the proxy
SSLProxyMachineCertificatePath directoryskvE
Directory of PEM-encoded client certificates and keys to be used by the proxy
SSLProxyProtocol [+|-]protocol ... all -SSLv3 (up to 2 +skvE
Configure usable SSL protocol flavors for proxy usage
SSLProxyVerify level none skvE
Type of remote server Certificate verification
SSLProxyVerifyDepth number 1 skvE
Maximum depth of CA Certificates in Remote Server Certificate verification
SSLRandomSeed context source [bytes]sE
Pseudo Random Number Generator (PRNG) seeding source
SSLRenegBufferSize bytes 131072 dhE
Set the size for the SSL renegotiation buffer
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 skE
Number of seconds before an SSL session expires in the Session Cache
SSLSessionTicketKeyFile file-pathskE
Persistent encryption/decryption key for TLS session tickets
SSLSessionTickets on|off on skE
Enable or disable use of TLS session tickets
SSLSRPUnknownUserSeed secret-stringskE
SRP unknown user seed
SSLSRPVerifierFile file-pathskE
Path to SRP verifier file
SSLStaplingCache typesE
Configures the OCSP stapling cache
SSLStaplingErrorCacheTimeout seconds 600 skE
Number of seconds before expiring invalid responses in the OCSP stapling cache
SSLStaplingFakeTryLater on|off on skE
Synthesize "tryLater" responses for failed OCSP stapling queries
SSLStaplingForceURL uriskE
Override the OCSP responder URI specified in the certificate's AIA extension
SSLStaplingResponderTimeout seconds 10 skE
Timeout for OCSP stapling queries
SSLStaplingResponseMaxAge seconds -1 skE
Maximum allowable age for OCSP stapling responses
SSLStaplingResponseTimeSkew seconds 300 skE
Maximum allowable time skew for OCSP stapling response validation
SSLStaplingReturnResponderErrors on|off on skE
Pass stapling related OCSP errors on to client
SSLStaplingStandardCacheTimeout seconds 3600 skE
Number of seconds before expiring responses in the OCSP stapling cache
SSLStrictSNIVHostCheck on|off off skE
Whether to allow non-SNI clients to access a name-based virtual host.
SSLUserName varnamesdhE
Variable name to determine user name
SSLUseStapling on|off off skE
Enable stapling of OCSP responses in the TLS handshake
SSLVerifyClient level none skdhE
Type of Client Certificate verification
SSLVerifyDepth number 1 skdhE
Maximum depth of CA Certificates in Client Certificate verification
StartServers sayısM
Sunucunun başlatılması sırasında oluşturulan çocuk süreçlerin sayısını belirler.
StartThreads sayısM
Sunucunun başlatılması sırasında oluşturulan evrelerin sayısını belirler.
StrictHostCheck ON|OFF OFF skÇ
Sunucunun, istenen konak adının, isteği işleyen sanal konakta listelenmesini gerektirip gerektirmediğini denetler
Substitute s/pattern/substitution/[infq]dhE
Pattern to filter the response content
SubstituteInheritBefore on|off off dhE
Change the merge order of inherited patterns
SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G) 1m dhE
Set the maximum line size
Suexec On|OffsT
suEXEC özelliğini etkin veya etkisiz yapar
SuexecUserGroup Kullanıcı GrupskE
CGI betiklerini çalıştıracak kullanıcı ve grup belirtilir.
ThreadLimit sayısM
Çocuk süreç başına ayarlanabilir evre sayısının üst sınırını belirler.
ThreadsPerChild sayısM
Her çocuk süreç tarafından oluşturulan evrelerin sayısını belirler.
ThreadStackSize boyutsM
İstemci bağlantılarını elde eden evreler tarafından kullanılan yığıtın bayt cinsinden uzunluğunu belirler.
TimeOut saniye 60 skÇ
Bir istek için başarısız olmadan önce belirli olayların gerçekleşmesi için sunucunun geçmesini bekleyeceği süre.
TraceEnable [on|off|extended] on skÇ
TRACE isteklerinde davranış şeklini belirler
TransferLog dosya|borulu-süreç [takma-ad]skT
Bir günlük dosyasının yerini belirtir.
TypesConfig file-path conf/mime.types sT
The location of the mime.types file
UNCList hostname [hostname...]sÇ
Controls what UNC host names can be accessed by the server
UnDefine değişken-ismisÇ
Bir değişkeni tanımsız yapar
UndefMacro nameskdT
Undefine a macro
UnsetEnv ortam-değişkeni [ortam-değişkeni] ...skdhT
Ortamdaki değişkenleri tanımsız hale getirir.
Use name [value1 ... valueN] skdT
Use a macro
UseCanonicalName On|Off|DNS Off skdÇ
Sunucunun kendi adını ve portunu nasıl belirleyeceğini ayarlar
UseCanonicalPhysicalPort On|Off Off skdÇ
Sunucunun kendi adını ve portunu nasıl belirleyeceğini ayarlar
User unix-kullanıcısı #-1 sT
İsteklere yanıt verecek sunucunun ait olacağı kullanıcıyı belirler.
UserDir dizin [dizin] ...skT
Kullanıcıya özel dizinlerin yeri
VHostCGIMode On|Off|Secure On kD
Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...kD
Assign arbitrary privileges to subprocesses created by a virtual host.
VHostGroup unix-groupidkD
Sets the Group ID under which a virtual host runs.
VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...kD
Assign arbitrary privileges to a virtual host.
VHostSecure On|Off On kD
Determines whether the server runs with enhanced security for the virtualhost.
VHostUser unix-useridkD
Sets the User ID under which a virtual host runs.
VirtualDocumentRoot hesaplanan-dizin|none none skE
Bir sanal konağın belge kök dizinini devingen olarak yapılandırır.
VirtualDocumentRootIP hesaplanan-dizin|none none skE
Bir sanal konağın belge kök dizinini devingen olarak yapılandırır.
<VirtualHost adres[:port] [adres[:port]] ...> ... </VirtualHost>sÇ
Sadece belli bir konak ismine ve porta uygulanacak yönergeleri barındırır.
VirtualScriptAlias hesaplanan-dizin|none none skE
Bir sanal konağın CGI dizinini devingen olarak yapılandırır.
VirtualScriptAliasIP hesaplanan-dizin|none none skE
Bir sanal konağın CGI dizinini devingen olarak yapılandırır.
WatchdogInterval time-interval[s] 1 sT
Watchdog interval in seconds
XBitHack on|off|full off skdhT
Parse SSI directives in files with the execute bit set
xml2EncAlias charset alias [alias ...]sT
Recognise Aliases for encoding values
xml2EncDefault nameskdhT
Sets a default encoding to assume when absolutely no information can be automatically detected
xml2StartParse element [element ...]skdhT
Advise the parser to skip leading junk.

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.zh-cn.utf80000664000175100017510000060001515032765673023412 0ustar covenercovener 指令快速索引 - Apache HTTP 服务器 版本 2.4
<-
Apache > HTTP 服务器 > 文档 > 版本 2.4 > 模块

指令快速索引

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

此翻译可能过期。要了解最近的更改,请阅读英文版。

指令快速索引显示指令的用法,默认值,状态和上下文。要获得更多信息,请参见 描述指令的术语

第一列给出指令的名称与用法。第二列显示指令的默认值(如果有的话)。 如果因为默认值太长而被截断显示,会在最后一个字符之后显示字符 “+”。

第三列显示允许此指令的上下文,第四列显示指令的状态。

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
s服务器配置
v虚拟主机
d目录
h.htaccess
C核心
MMPM
B基础
E扩展
X实验
AcceptFilter protocol accept_filtersC
Configures optimizations for a Protocol's Listener 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 encoding 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 language-tag 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...] media-type [media-type] ...svdhB
assigns an output filter to a particular media-type
AddType media-type extension [extension] ...svdhB
Maps the given filename extensions onto the specified content type
Alias [URL-path] file-path|directory-pathsvdB
Maps URLs to filesystem locations
AliasMatch regex file-path|directory-pathsvB
Maps URLs to filesystem locations using regular expressions
AliasPreservePath OFF|ON OFF svdB
Map the full path after the alias in a location.
Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...dhE
Controls which hosts can access an area of the server
AllowCONNECT port[-port] [port[-port]] ... 443 563 svE
Ports that are allowed to CONNECT through the proxy
AllowEncodedSlashes On|Off|NoDecode Off svC
Determines whether encoded path separators in URLs are allowed to be passed through
AllowMethods reset|HTTP-method [HTTP-method]... reset dX
Restrict access to the listed HTTP methods
AllowOverride All|None|directive-type [directive-type] ... None (2.3.9 and lat +dC
Types of directives that are allowed in .htaccess files
AllowOverrideList None|directive [directive-type] ... None dC
Individual 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
AsyncRequestWorkerFactor factorsM
Limit concurrent connections per process
AuthBasicAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthBasicFake off|username [password]dhB
Fake basic authentication using the given expressions for username and password
AuthBasicProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthBasicUseDigestAlgorithm MD5|Off Off dhB
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBDUserPWQuery querydE
SQL query to look up a password for a user
AuthDBDUserRealmQuery querydE
SQL query to look up a password hash for a user and realm.
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
AuthDigestAlgorithm MD5|MD5-sess MD5 dhE
Selects the algorithm used to calculate the challenge and response hashes in digest authentication
AuthDigestDomain URI [URI] ...dhE
URIs that are in the same protection space for digest authentication
AuthDigestNonceLifetime seconds 300 dhE
How long the server nonce is valid
AuthDigestProvider provider-name [provider-name] ... file dhE
Sets the authentication provider(s) for this location
AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhE
Determines the quality-of-protection to use in digest authentication
AuthDigestShmemSize size 1000 sE
The amount of shared memory to allocate for keeping track of clients
AuthFormAuthoritative On|Off On dhB
Sets whether authorization and authentication are passed to lower level modules
AuthFormBody fieldname httpd_body dB
The name of a form field carrying the body of the request to attempt on successful login
AuthFormDisableNoStore On|Off Off dB
Disable the CacheControl no-store header on the login page
AuthFormFakeBasicAuth On|Off Off dB
Fake a Basic Authentication header
AuthFormLocation fieldname httpd_location dB
The name of a form field carrying a URL to redirect to on successful login
AuthFormLoginRequiredLocation urldB
The URL of the page to be redirected to should login be required
AuthFormLoginSuccessLocation urldB
The URL of the page to be redirected to should login be successful
AuthFormLogoutLocation uridB
The URL to redirect to after a user has logged out
AuthFormMethod fieldname httpd_method dB
The name of a form field carrying the method of the request to attempt on successful login
AuthFormMimetype fieldname httpd_mimetype dB
The name of a form field carrying the mimetype of the body of the request to attempt on successful login
AuthFormPassword fieldname httpd_password dB
The name of a form field carrying the login password
AuthFormProvider provider-name [provider-name] ... file dhB
Sets the authentication provider(s) for this location
AuthFormSitePassphrase secretdB
Bypass authentication checks for high traffic sites
AuthFormSize size 8192 dB
The largest size of the form in bytes that will be parsed for the login details
AuthFormUsername fieldname httpd_username dB
The name of a form field carrying the login username
AuthGroupFile file-pathdhB
Sets the name of a text file containing the list of user groups for authorization
AuthLDAPAuthorizePrefix prefix AUTHORIZE_ dhE
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritative off|on on dhE
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDN distinguished-namedhE
Optional DN to use in binding to the LDAP server
AuthLDAPBindPassword passworddhE
Password used in conjunction with the bind DN
AuthLDAPCharsetConfig file-pathsE
Language to charset conversion configuration file
AuthLDAPCompareAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization comparisons
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 attribute member uniqueMember +dhE
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDN on|off on dhE
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUser off|on off dhE
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPattern regex substitution (.*) $1 (remote use +dhE
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepth Number 10 dhE
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttribute uiddhE
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDN on|off off dhE
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUser on|off off dhE
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttribute attribute member uniqueMember +dhE
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClass LdapObjectClass groupOfNames groupO +dhE
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhB
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthName auth-domaindhB
Authorization realm for use in HTTP authentication
AuthnCacheContext directory|server|custom-string directory dB
Specify a context string for use in the cache key
AuthnCacheEnablesB
Enable Authn caching configured anywhere
AuthnCacheProvideFor authn-provider [...]dhB
Specify which authn provider(s) to cache for
AuthnCacheSOCache provider-name[:provider-args]sB
Select socache backend provider to use
AuthnCacheTimeout timeout (seconds) 300 (5 minutes) dhB
Set a timeout for cache entries
<AuthnProviderAlias baseProvider Alias> ... </AuthnProviderAlias>sB
Enclose a group of directives that represent an extension of a base authentication provider and referenced by the specified alias
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Enables a FastCGI application to handle the check_authn authentication hook.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Defines a FastCGI application as a provider for authentication and/or authorization
AuthType None|Basic|Digest|FormdhB
Type of user authentication
AuthUserFile file-pathdhB
Sets the name of a text file containing the list of users and passwords for authentication
AuthzDBDLoginToReferer On|Off Off dE
Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
AuthzDBDQuery querydE
Specify the SQL Query for the required operation
AuthzDBDRedirectQuery querydE
Specify a query to look up a login page for the user
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
Sets the type of database file that is used to store list of user groups
<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias> sB
Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
AuthzSendForbiddenOnFailure On|Off Off dhB
Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
BalancerGrowth # 5 svE
Number of additional Balancers that can be added Post-configuration
BalancerInherit On|Off On svE
Inherit ProxyPassed Balancers/Workers from the main server
BalancerMember [balancerurl] url [key=value [key=value ...]]dE
Add a member to a load balancing group
BalancerPersist On|Off Off svE
Attempt to persist changes made by the Balancer Manager across restarts.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
BrotliCompressionMaxInputBlock valuesvE
Maximum input block size
BrotliCompressionQuality value 5 svE
Compression quality
BrotliCompressionWindow value 18 svE
Brotli sliding compression window size
BrotliFilterNote [type] notenamesvE
Places the compression ratio in a note for logging
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
BufferSize integer 131072 svdhE
Maximum size in bytes to buffer by the buffer filter
CacheDefaultExpire seconds 3600 (one hour) svdhE
The default duration to cache a document when no expiry date is specified.
CacheDetailHeader on|off off svdhE
Add an X-Cache-Detail header to the response.
CacheDirLength length 2 svE
The number of characters in subdirectory names
CacheDirLevels levels 2 svE
The number of levels of subdirectories in the cache.
CacheDisable url-string | onsvdhE
Disable caching of specified URLs
CacheEnable cache_type [url-string]svdE
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
CacheHeader on|off off svdhE
Add an X-Cache header to the response.
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 svdhE
Ignore the fact that a response has no Last Modified header.
CacheIgnoreQueryString On|Off Off svE
Ignore query string when caching
CacheIgnoreURLSessionIdentifiers identifier [identifier] ... None svE
Ignore defined session identifiers encoded in the URL when caching
CacheKeyBaseURL URLsvE
Override the base URL of reverse proxied cache keys.
CacheLastModifiedFactor float 0.1 svdhE
The factor used to compute an expiry date based on the LastModified date.
CacheLock on|off off svE
Enable the thundering herd lock.
CacheLockMaxAge integer 5 svE
Set the maximum possible age of a cache lock.
CacheLockPath directory /tmp/mod_cache-lock +svE
Set the lock path directory.
CacheMaxExpire seconds 86400 (one day) svdhE
The maximum time in seconds to cache a document
CacheMaxFileSize bytes 1000000 svdhE
The maximum size (in bytes) of a document to be placed in the cache
CacheMinExpire seconds 0 svdhE
The minimum time in seconds to cache a document
CacheMinFileSize bytes 1 svdhE
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
CacheQuickHandler on|off on svE
Run the cache from the quick handler.
CacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheRoot directorysvE
The directory root under which cache files are stored
CacheSocache type[:args]svE
The shared object cache implementation to use
CacheSocacheMaxSize bytes 102400 svdhE
The maximum size (in bytes) of an entry to be placed in the cache
CacheSocacheMaxTime seconds 86400 svdhE
The maximum time (in seconds) for a document to be placed in the cache
CacheSocacheMinTime seconds 600 svdhE
The minimum time (in seconds) for a document to be placed in the cache
CacheSocacheReadSize bytes 0 svdhE
The minimum size (in bytes) of the document to read and be cached before sending the data downstream
CacheSocacheReadTime milliseconds 0 svdhE
The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
CacheStaleOnError on|off on svdhE
Serve stale content in place of 5xx responses.
CacheStoreExpired On|Off Off svdhE
Attempt to cache responses that the server reports as expired
CacheStoreNoStore On|Off Off svdhE
Attempt to cache requests or responses that have been marked as no-store.
CacheStorePrivate On|Off Off svdhE
Attempt to cache responses that the server has marked as private
CGIDScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIMapExtension cgi-path .extensiondhC
Technique for locating the interpreter for CGI scripts
CGIPassAuth On|Off Off dhC
Enables passing HTTP authorization headers to scripts as CGI variables
CGIScriptTimeout time[s|ms]svdhB
The length of time to wait for more output from the CGI program
CGIVar variable ruledhC
Controls how some CGI variables are set
CharsetDefault charsetsvdhE
Charset to translate into
CharsetOptions option [option] ... ImplicitAdd svdhE
Configures charset translation behavior
CharsetSourceEnc charsetsvdhE
Source charset of files
CheckBasenameMatch on|off On svdhE
Also match files with differing file name extensions.
CheckCaseOnly on|off Off svdhE
Limits the action of the speling module to case corrections
CheckSpelling on|off Off svdhE
Enables the spelling module
ChrootDir /path/to/directorysB
Directory for apache to run chroot(8) after startup.
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
CookieHTTPOnly on|off off svdhE
Adds the 'HTTPOnly' attribute to the cookie
CookieName token Apache svdhE
Name of the tracking cookie
CookieSameSite None|Lax|StrictsvdhE
Adds the 'SameSite' attribute to the cookie
CookieSecure on|off off svdhE
Adds the 'Secure' attribute to the 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 HTTP Server attempts to switch before dumping core
CustomLog file|pipe format|nickname [env=[!]environment-variable| expr=expression]svB
Sets filename and format of log file
Dav On|Off|provider-name Off dE
Enable WebDAV HTTP methods
DavBasePath root-pathdE
Configure repository root path
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
DavLockDiscovery on|off on svdhE
Enable lock discovery
DavMinTimeout seconds 0 svdE
Minimum amount of time the server holds a lock on a DAV resource
DBDExptime time-in-seconds 300 svE
Keepalive time for idle connections
DBDInitSQL "SQL statement"svE
Execute an SQL statement after connecting to a database
DBDKeep number 2 svE
Maximum sustained number of connections
DBDMax number 10 svE
Maximum number of connections
DBDMin number 1 svE
Minimum number of connections
DBDParams param1=value1[,param2=value2]svE
Parameters for database connection
DBDPersist On|OffsvE
Whether to use persistent connections
DBDPrepareSQL "SQL statement" labelsvE
Define an SQL prepared statement
DBDriver namesvE
Specify an SQL driver
DefaultIcon url-pathsvdhB
Icon to display for files when no specific icon is configured
DefaultLanguage language-tagsvdhB
Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
DefaultRuntimeDir directory-path DEFAULT_REL_RUNTIME +sC
Base directory for the server run-time files
DefaultType media-type|none none svdhC
This directive has no effect other than to emit warnings if the value is not none. In prior versions, DefaultType would specify a default media type to assign to response content for which no other media type configuration could be found.
Define parameter-name [parameter-value]svdC
Define a variable
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix svE
How the outgoing ETag header should be modified during compression
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
DeflateInflateLimitRequestBody valuesvdhE
Maximum size of inflated request bodies
DeflateInflateRatioBurst value 3 svdhE
Maximum number of times the inflation ratio for request bodies can be crossed
DeflateInflateRatioLimit value 200 svdhE
Maximum inflation ratio for request bodies
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] ...dhE
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, sub-directories, and their contents.
DirectoryCheckHandler On|Off Off svdhB
Toggle how this module responds when another handler is configured
DirectoryIndex disabled | local-url [local-url] ... index.html svdhB
List of resources to look for when the client requests a directory
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code off svdhB
Configures an external redirect for directory indexes.
<DirectoryMatch regex> ... </DirectoryMatch>svC
Enclose directives that apply to the contents of file-system directories matching a regular expression.
DirectorySlash On|Off On svdhB
Toggle trailing slash redirects on or off
DocumentRoot directory-path "/usr/local/apache/ +svC
Directory that forms the main document tree visible from the web
DTracePrivileges On|Off Off sX
Determines whether the privileges required by dtrace are enabled.
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
<Else> ... </Else>svdhC
Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
<ElseIf expression> ... </ElseIf>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
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 Off svdhC
Use the kernel sendfile support to deliver files to the client
Error messagesvdhC
Abort configuration parsing with a custom error message
ErrorDocument error-code documentsvdhC
What the server will return to the client in case of an error
ErrorLog file-path|syslog[:[facility][:tag]] logs/error_log (Uni +svC
Location where the server will log errors
ErrorLogFormat [connection|request] formatsvC
Format specification for error log entries
ExamplesvdhX
Demonstration directive to illustrate the Apache module API
ExpiresActive On|Off Off svdhE
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[*] sC
Keep track of extended status information for each request
ExtFilterDefine filtername parameterssE
Define an external filter
ExtFilterOptions option [option] ... NoLogStderr dE
Configure mod_ext_filter options
FallbackResource disabled | local-urlsvdhB
Define a default URL for requests that don't map to a file
FileETag component ... MTime Size svdhC
File attributes used to create the ETag HTTP response header for static files
<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 ...svdhB
Configure the filter chain
FilterDeclare filter-name [type]svdhB
Declare a smart filter
FilterProtocol filter-name [provider-name] proto-flagssvdhB
Deal with correct HTTP protocol handling
FilterProvider filter-name provider-name expressionsvdhB
Register a content filter
FilterTrace filter-name levelsvdB
Get debug/diagnostic information from mod_filter
FlushMaxPipelined number 5 svC
Maximum number of pipelined responses above which they are flushed to the network
FlushMaxThreshold number-of-bytes 65535 svC
Threshold above which pending data are flushed to the network
ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
Action to take if a single acceptable document is not found
ForceType media-type|NonedhC
Forces all matching files to be served with the specified media type in the HTTP Content-Type header field
ForensicLog filename|pipesvE
Sets filename of the forensic log
GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]sB
Sets filename and format of log file
GprofDir /tmp/gprof/|/tmp/gprof/%svC
Directory to write gmon.out profiling data to.
GracefulShutdownTimeout seconds 0 sM
Specify a timeout after which a gracefully shutdown server will exit.
Group unix-group #-1 sB
Group under which the server will answer requests
H2CopyFiles on|off off svdhE
Determine file handling in responses
H2Direct on|off on for h2c, off for +svE
H2 Direct Protocol Switch
H2EarlyHint name valuesvdhE
Add a response header to be picked up in 103 Early Hints
H2EarlyHints on|off off svE
Determine sending of 103 status codes
H2MaxDataFrameLen n 0 svE
Maximum bytes inside a single HTTP/2 DATA frame
H2MaxHeaderBlockLen n 0 svE
Maximum size of response headers
H2MaxSessionStreams n 100 svE
Maximum number of active streams per HTTP/2 session.
H2MaxWorkerIdleSeconds n 600 sE
Maximum number of seconds h2 workers remain idle until shut down.
H2MaxWorkers nsE
Maximum number of worker threads to use per child process.
H2MinWorkers nsE
Minimal number of worker threads to use per child process.
H2ModernTLSOnly on|off on svE
Require HTTP/2 connections to be "modern TLS" only
H2OutputBuffering on|off on svE
Determine buffering behaviour of output
H2Padding numbits 0 svE
Determine the range of padding bytes added to payload frames
H2ProxyRequests on|off off svE
En-/Disable forward proxy requests via HTTP/2
H2Push on|off on svdhE
H2 Server Push Switch
H2PushDiarySize n 256 svE
H2 Server Push Diary Size
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 svE
H2 Server Push Priority
H2PushResource [add] path [critical]svdhE
Declares resources for early pushing to the client
H2SerializeHeaders on|off off svE
Serialize Request/Response Processing Switch
H2StreamMaxMemSize bytes 65536 svE
Maximum amount of output data buffered per stream.
H2StreamTimeout time-interval[s]svdE
Maximum time waiting when sending/receiving data to stream processing
H2TLSCoolDownSecs seconds 1 svE
Configure the number of seconds of idle time on TLS before shrinking writes
H2TLSWarmUpSize amount 1048576 svE
Configure the number of bytes on TLS connection before doing max writes
H2Upgrade on|off on for h2c, off for +svdhE
H2 Upgrade Protocol Switch
H2WebSockets on|off off svE
En-/Disable WebSockets via HTTP/2
H2WindowSize bytes 65535 svE
Size of Stream Window for upstream data.
Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP response headers
HeaderName filenamesvdhB
Name of the file that will be inserted at the top of the index listing
HeartbeatAddress addr:portsX
Multicast address for heartbeat packets
HeartbeatListen addr:portsX
multicast address to listen for incoming heartbeat requests
HeartbeatMaxServers number-of-servers 10 sX
Specifies the maximum number of servers that will be sending heartbeat requests to this server
HeartbeatStorage file-path logs/hb.dat sX
Path to store heartbeat data when using flat-file storage
HeartbeatStorage file-path logs/hb.dat sX
Path to read heartbeat data
HostnameLookups On|Off|Double Off svdC
Enables DNS lookups on client IP addresses
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +svC
Modify restrictions on HTTP Request Messages
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
<If expression> ... </If>svdhC
Contains directives that apply only if a condition is satisfied by a request at runtime
<IfDefine [!]parameter-name> ... </IfDefine>svdhC
Encloses directives that will be processed only if a test is true at startup
<IfDirective [!]directive-name> ... </IfDirective>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific directive
<IfFile [!]filename> ... </IfFile>svdhC
Encloses directives that will be processed only if file exists at startup
<IfModule [!]module-file|module-identifier> ... </IfModule>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific module
<IfSection [!]section-name> ... </IfSection>svdhC
Encloses directives that are processed conditional on the presence or absence of a specific section directive
<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|unformatted formatted svdhB
Action if no coordinates are given when calling an imagemap
Include file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IncludeOptional file-path|directory-path|wildcardsvdC
Includes other configuration files from within the server configuration files
IndexHeadInsert "markup ..."svdhB
Inserts text in the HEAD section of an index page.
IndexIgnore file [file] ... "." svdhB
Adds to the list of files to hide when listing a directory
IndexIgnoreReset ON|OFFsvdhB
Empties 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
InputSed sed-commanddhX
Sed command to filter request data (typically POST data)
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 num[ms] 5 svC
Amount of time the server will wait for subsequent requests on a persistent connection
KeptBodySize maximum size in bytes 0 dB
Keep the request body instead of discarding it up to the specified maximum size, for potential use by filters such as mod_include.
LanguagePriority MIME-lang [MIME-lang] ...svdhB
The precedence 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
LDAPConnectionPoolTTL n -1 svE
Discard backend connections that have been sitting in the connection pool too long
LDAPConnectionTimeout secondssE
Specifies the socket connection timeout in seconds
LDAPLibraryDebug 7sE
Enable debugging in the LDAP SDK
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
LDAPReferralHopLimit numberdhE
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferrals On|Off|default On dhE
Enable referral chasing during queries to the LDAP server.
LDAPRetries number-of-retries 3 sE
Configures the number of LDAP server retries.
LDAPRetryDelay seconds 0 sE
Configures the delay between LDAP server retries.
LDAPSharedCacheFile directory-path/filenamesE
Sets the shared memory cache file
LDAPSharedCacheSize bytes 500000 sE
Size in bytes of the shared-memory cache
LDAPTimeout seconds 60 sE
Specifies the timeout for LDAP search and bind operations, in seconds
LDAPTrustedClientCert type directory-path/filename/nickname [password]dhE
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 typesvE
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>dhC
Restrict enclosed access controls to only certain HTTP methods
<LimitExcept method [method] ... > ... </LimitExcept>dhC
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 1073741824 svdhC
Restricts the total size of the HTTP request body sent from the client
LimitRequestFields number 100 svC
Limits the number of HTTP request header fields that will be accepted from the client
LimitRequestFieldSize bytes 8190 svC
Limits the size of the HTTP request header allowed from the client
LimitRequestLine bytes 8190 svC
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:]portnumber [protocol]sM
IP addresses and ports that the server listens to
ListenBackLog backlog 511 sM
Maximum length of the queue of pending connections
ListenCoresBucketsRatio ratio 0 (disabled) sM
Ratio between the number of CPU cores (online) and the number of listeners' buckets
LoadFile filename [filename] ...svE
Link in the named object file or library
LoadModule module filenamesvE
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
LogFormat format|nickname [nickname] "%h %l %u %t \"%r\" +svB
Describes a format for use in a log file
LogIOTrackTTFB ON|OFF OFF svdhE
Enable tracking of time to first byte (TTFB)
LogLevel [module:]level [module:level] ... warn svdC
Controls the verbosity of the ErrorLog
LogMessage message [hook=hook] [expr=expression] dX
Log user-defined message to error log
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Plug an authorization provider function into mod_authz_core
LuaCodeCache stat|forever|never stat svdhE
Configure the compiled code cache.
LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the access_checker phase of request processing
LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]svdhE
Provide a hook for the check_user_id phase of request processing
LuaHookFixups /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the fixups phase of a request processing
LuaHookInsertFilter /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the insert_filter phase of request processing
LuaHookLog /path/to/lua/script.lua log_function_namesvdhE
Provide a hook for the access log phase of a request processing
LuaHookMapToStorage /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslate /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]svE
Provide a hook for the translate name phase of request processing
LuaHookTypeChecker /path/to/lua/script.lua hook_function_namesvdhE
Provide a hook for the type_checker phase of request processing
LuaInherit none|parent-first|parent-last parent-first svdhE
Controls how parent configuration sections are merged into children
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content input filtering
LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]svdhE
Map a path to a lua handler
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Provide a Lua function for content output filtering
LuaPackageCPath /path/to/include/?.soasvdhE
Add a directory to lua's package.cpath
LuaPackagePath /path/to/include/?.luasvdhE
Add a directory to lua's package.path
LuaQuickHandler /path/to/script.lua hook_function_namesvE
Provide a hook for the quick handler of request processing
LuaRoot /path/to/a/directorysvdhE
Specify the base path for resolving relative paths for mod_lua directives
LuaScope once|request|conn|thread|server [min] [max] once svdhE
One of once, request, conn, thread -- default is once
<Macro name [par1 .. parN]> ... </Macro>svdB
Define a configuration file macro
MaxConnectionsPerChild number 0 sM
Limit on the number of connections that an individual child server will handle during its life
MaxKeepAliveRequests number 100 svC
Number of requests allowed on a persistent connection
MaxMemFree KBytes 2048 sM
Maximum amount of memory that the main allocator is allowed to hold without calling free()
MaxRangeOverlaps default | unlimited | none | number-of-ranges 20 svdC
Number of overlapping ranges (eg: 100-200,150-300) allowed before returning the complete resource
MaxRangeReversals default | unlimited | none | number-of-ranges 20 svdC
Number of range reversals (eg: 100-200,50-70) allowed before returning the complete resource
MaxRanges default | unlimited | none | number-of-ranges 200 svdC
Number of ranges allowed before returning the complete resource
MaxRequestWorkers numbersM
Maximum number of connections that will be processed simultaneously
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
MDActivationDelay durationsX
How long to delay activation of new certificates
MDBaseServer on|off off sX
Control if base server may be managed or only virtual hosts.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sX
Type of ACME challenge used to prove domain ownership.
MDCertificateAgreement acceptedsX
You confirm that you accepted the Terms of Service of the Certificate Authority.
MDCertificateAuthority url letsencrypt sX
The URL(s) of the ACME Certificate Authority to use.
MDCertificateCheck name urlsX
Set name and URL pattern for a certificate monitoring site.
MDCertificateFile path-to-pem-filesX
Specify a static certificate file for the MD.
MDCertificateKeyFile path-to-filesX
Specify a static private key for for the static cerrtificate.
MDCertificateMonitor name url crt.sh https://crt. +sX
The URL of a certificate log monitor.
MDCertificateProtocol protocol ACME sX
The protocol to use with the Certificate Authority.
MDCertificateStatus on|off on sX
Exposes public certificate information in JSON.
MDChallengeDns01 path-to-commandsX
Set the command for setup/teardown of dns-01 challenges
MDChallengeDns01Version 1|2 1 sX
Set the type of arguments to call MDChallengeDns01 with
MDCheckInterval duration 12h sX
Determines how often certificates are checked
MDContactEmail addresssX
Email address used for account registration
MDDriveMode always|auto|manual auto sX
former name of MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sX
Set the external account binding keyid and hmac values to use at CA
MDHttpProxy urlsX
Define a proxy for outgoing connections.
MDMatchNames all|servernames all sX
Determines how DNS names are matched to vhosts
MDMember hostnamesX
Additional hostname for the managed domain.
MDMembers auto|manual auto sX
Control if the alias domain names are automatically added.
MDMessageCmd path-to-cmd optional-argssX
Handle events for Manage Domains
MDMustStaple on|off off sX
Control if new certificates carry the OCSP Must Staple flag.
MDNotifyCmd path [ args ]sX
Run a program when a Managed Domain is ready.
MDomain dns-name [ other-dns-name... ] [auto|manual]sX
Define list of domain names that belong to one group.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sX
Container for directives applied to the same managed domains.
MDPortMap map1 [ map2 ] http:80 https:443 sX
Map external to internal ports for domain ownership verification.
MDPrivateKeys type [ params... ] RSA 2048 sX
Set type and size of the private keys generated.
MDProfile namesX
Use a specific ACME profile from the CA
MDProfileMandatory on|off off sX
Control if an MDProfile is mandatory.
MDRenewMode always|auto|manual auto sX
Controls if certificates shall be renewed.
MDRenewWindow duration 33% sX
Control when a certificate will be renewed.
MDRequireHttps off|temporary|permanent off sX
Redirects http: traffic to https: for Managed Domains.
MDRetryDelay duration 5s sX
Time length for first retry, doubled on every consecutive error.
MDRetryFailover number 13 sX
The number of errors before a failover to another CA is triggered
MDServerStatus on|off on sX
Control if Managed Domain information is added to server-status.
MDStapleOthers on|off on sX
Enable stapling for certificates not managed by mod_md.
MDStapling on|off off sX
Enable stapling for all or a particular MDomain.
MDStaplingKeepResponse duration 7d sX
Controls when old responses should be removed.
MDStaplingRenewWindow duration 33% sX
Control when the stapling responses will be renewed.
MDStoreDir path md sX
Path on the local file system to store the Managed Domains data.
MDStoreLocks on|off|duration off sX
Configure locking of store for updates
MDWarnWindow duration 10% sX
Define the time window when you want to be warned about an expiring certificate.
MemcacheConnTTL num[units] 15s svE
Keepalive time for idle connections
MergeSlashes ON|OFF ON svC
Controls whether the server merges consecutive slashes in URLs.
MergeTrailers [on|off] off svC
Determines whether trailers are merged into headers
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 containing 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
ModemStandard V.21|V.26bis|V.32|V.34|V.92dX
Modem standard to simulate
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
Mutex mechanism [default|mutex-name] ... [OmitPID] default sC
Configures mutex mechanism and lock file directory for all or specified mutexes
NameVirtualHost addr[:port]sC
DEPRECATED: Designates an IP address for name-virtual hosting
NoProxy host [host] ...svE
Hosts, domains, or networks that will be connected to directly
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] ... FollowSymlinks svdhC
Configures what features are available in a particular directory
Order ordering Deny,Allow dhE
Controls the default access state and the order in which Allow and Deny are evaluated.
OutputSed sed-commanddhX
Sed command for filtering response content
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
PrivilegesMode FAST|SECURE|SELECTIVE FAST svdX
Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Protocol protocolsvC
Protocol for a listening socket
ProtocolEcho On|Off Off svX
Turn the echo server on or off
Protocols protocol ... http/1.1 svC
Protocols available for a server/virtual host
ProtocolsHonorOrder On|Off On svC
Determines if order of Protocols determines precedence during negotiation
<Proxy wildcard-url> ...</Proxy>svE
Container for directives applied to proxied resources
Proxy100Continue Off|On On svdE
Forward 100-continue expectation to the origin server
ProxyAddHeaders Off|On On svdE
Add proxy information in X-Forwarded-* headers
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 Off|On [code ...] Off svdE
Override error pages for proxied content
ProxyExpressDBMFile pathnamesvE
Pathname to DBM file.
ProxyExpressDBMType type default svE
DBM type of file.
ProxyExpressEnable on|off off svE
Enable the module functionality.
ProxyFCGIBackendType FPM|GENERIC FPM svdhE
Specify the type of backend FastCGI application
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]svdhE
Allow variables sent to FastCGI servers to be fixed up
ProxyFtpDirCharset character_set ISO-8859-1 svdE
Define the character set for proxied FTP listings
ProxyFtpEscapeWildcards on|off on svdE
Whether wildcards in requested filenames are escaped when sent to the FTP server
ProxyFtpListOnWildcard on|off on svdE
Whether wildcards in requested filenames trigger a file listing
ProxyHCExpr name {ap_expr expression}svE
Creates a named condition expression to use to determine health of the backend based on its response
ProxyHCTemplate name parameter=setting [...]svE
Creates a named template for setting various health check parameters
ProxyHCTPsize size 16 sE
Sets the total server-wide size of the threadpool used for the health check workers
ProxyHTMLBufSize bytes 8192 svdB
Sets the buffer size increment for buffering inline scripts and stylesheets.
ProxyHTMLCharsetOut Charset | *svdB
Specify a charset for mod_proxy_html output.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
svdB
Sets an HTML or XHTML document type declaration.
ProxyHTMLEnable On|Off Off svdB
Turns the proxy_html filter on or off.
ProxyHTMLEvents attribute [attribute ...]svdB
Specify attributes to treat as scripting events.
ProxyHTMLExtended On|Off Off svdB
Determines whether to fix links in inline scripts, stylesheets, and scripting events.
ProxyHTMLFixups [lowercase] [dospath] [reset]svdB
Fixes for simple HTML errors.
ProxyHTMLInterp On|Off Off svdB
Enables per-request interpolation of ProxyHTMLURLMap rules.
ProxyHTMLLinks element attribute [attribute2 ...]svdB
Specify HTML elements that have URL attributes to be rewritten.
ProxyHTMLMeta On|Off Off svdB
Turns on or off extra pre-parsing of metadata in HTML <head> sections.
ProxyHTMLStripComments On|Off Off svdB
Determines whether to strip HTML comments.
ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]svdB
Defines a rule to rewrite HTML links
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 -1 svE
Maximum number of proxies that a request can be forwarded through
ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] [noquery]svdE
Maps remote servers into the local server URL-space
ProxyPassInherit On|Off On svE
Inherit ProxyPass directives defined from the main server
ProxyPassInterpolateEnv On|Off Off svdE
Enable Environment Variable interpolation in Reverse Proxy configurations
ProxyPassMatch [regex] !|url [key=value [key=value ...]]svdE
Maps remote servers into the local server URL-space using regular expressions
ProxyPassReverse [path] url [interpolate]svdE
Adjusts the URL in HTTP response headers sent from a reverse proxied server
ProxyPassReverseCookieDomain internal-domain public-domain [interpolate]svdE
Adjusts the Domain string in Set-Cookie headers from a reverse- proxied server
ProxyPassReverseCookiePath internal-path public-path [interpolate]svdE
Adjusts the Path string in Set-Cookie headers from a reverse- proxied server
ProxyPreserveHost On|Off Off svdE
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-server [username:password]svE
Remote proxy used to handle certain requests
ProxyRemoteMatch regex remote-server [username:password]svE
Remote proxy used to handle requests matched by regular expressions
ProxyRequests On|Off Off svE
Enables forward (standard) proxy requests
ProxySCGIInternalRedirect On|Off|Headername On svdE
Enable or disable internal redirect responses from the backend
ProxySCGISendfile On|Off|Headername Off svdE
Enable evaluation of X-Sendfile pseudo response header
ProxySet url key=value [key=value ...]svdE
Set various Proxy balancer or member parameters
ProxySourceAddress addresssvE
Set local IP address for outgoing proxy connections
ProxyStatus Off|On|Full Off svE
Show Proxy LoadBalancer status in mod_status
ProxyTimeout secondssvE
Network timeout for proxied requests
ProxyVia On|Off|Full|Block Off svE
Information provided in the Via HTTP response header for proxied requests
ProxyWebsocketFallbackToProxyHttp On|Off On svE
Instructs this module to let mod_proxy_http handle the request
QualifyRedirectURL On|Off Off svdC
Controls whether the REDIRECT_URL environment variable is fully qualified
ReadBufferSize bytes 8192 svdC
Size of the buffers used to read data
ReadmeName filenamesvdhB
Name of the file that will be inserted at the end of the index listing
ReceiveBufferSize bytes 0 sM
TCP receive buffer size
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
RedirectRelative On|Off Off svdB
Allows relative redirect targets.
RedirectTemp URL-path URLsvdhB
Sends an external temporary redirect asking the client to fetch a different URL
RedisConnPoolTTL num[units] 15s svE
TTL used for the connection pool with the Redis server(s)
RedisTimeout num[units] 5s svE
R/W timeout used for the connection with the Redis server(s)
ReflectorHeader inputheader [outputheader]svdhB
Reflect an input header to the output headers
RegexDefaultOptions [none] [+|-]option [[+|-]option] ... DOTALL DOLLAR_ENDON +sC
Allow to configure global/default options for regexes
RegisterHttpMethod method [method [...]]sC
Register non-standard HTTP methods
RemoteIPHeader header-fieldsvB
Declare the header field which should be parsed for useragent IP addresses
RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPInternalProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPProxiesHeader HeaderFieldNamesvB
Declare the header field which will record all intermediate IP addresses
RemoteIPProxyProtocol On|OffsvB
Enable or disable PROXY protocol handling
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]svB
Disable processing of PROXY header for certain hosts or networks
RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...svB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
RemoteIPTrustedProxyList filenamesvB
Declare client intranet IP addresses trusted to present the RemoteIPHeader value
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 add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] svdhE
Configure HTTP request headers
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate] handshake=0 header= +svE
Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Require [not] entity-name [entity-name] ...dhB
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll> ... </RequireAll>dhB
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny> ... </RequireAny>dhB
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone> ... </RequireNone>dhB
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
RewriteBase URL-pathdhE
Sets the base URL for per-directory rewrites
RewriteCond TestString CondPattern [flags]svdhE
Defines a condition under which rewriting will take place
RewriteEngine on|off off svdhE
Enables or disables runtime rewriting engine
RewriteMap MapName MapType:MapSource [MapTypeOptions] svE
Defines a mapping function for key-lookup
RewriteOptions OptionssvdhE
Sets some special options for the rewrite engine
RewriteRule Pattern Substitution [flags]svdhE
Defines rules for the rewriting engine
RLimitCPU seconds|max [seconds|max]svdhC
Limits the CPU consumption of processes launched by Apache httpd children
RLimitMEM bytes|max [bytes|max]svdhC
Limits the memory consumption of processes launched by Apache httpd children
RLimitNPROC number|max [number|max]svdhC
Limits the number of processes that can be launched by processes launched by Apache httpd children
Satisfy Any|All All dhE
Interaction between host-level access control and user authentication
ScoreBoardFile file-path logs/apache_runtime +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-pathsvdB
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 cgisock sB
The filename prefix 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
SeeRequestTail On|Off Off sC
Determine if mod_status displays the first 63 characters of a request or the last 63, assuming the request itself is greater than 63 chars.
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 [scheme://]domain-name|ip-address[: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
Session On|Off Off svdhE
Enables a session for the current directory or location
SessionCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session
SessionCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session
SessionCookieRemove On|Off Off svdhE
Control for whether session cookies should be removed from incoming HTTP headers
SessionCryptoCipher name aes256 svdhX
The crypto cipher to be used to encrypt the session
SessionCryptoDriver name [param[=value]]sX
The crypto driver to be used to encrypt the session
SessionCryptoPassphrase secret [ secret ... ] svdhX
The key used to encrypt the session
SessionCryptoPassphraseFile filenamesvdX
File containing keys used to encrypt the session
SessionDBDCookieName name attributessvdhE
Name and attributes for the RFC2109 cookie storing the session ID
SessionDBDCookieName2 name attributessvdhE
Name and attributes for the RFC2965 cookie storing the session ID
SessionDBDCookieRemove On|Off On svdhE
Control for whether session ID cookies should be removed from incoming HTTP headers
SessionDBDDeleteLabel label deletesession svdhE
The SQL query to use to remove sessions from the database
SessionDBDInsertLabel label insertsession svdhE
The SQL query to use to insert sessions into the database
SessionDBDPerUser On|Off Off svdhE
Enable a per user session
SessionDBDSelectLabel label selectsession svdhE
The SQL query to use to select sessions from the database
SessionDBDUpdateLabel label updatesession svdhE
The SQL query to use to update existing sessions in the database
SessionEnv On|Off Off svdhE
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionExclude pathsvdhE
Define URL prefixes for which a session is ignored
SessionExpiryUpdateInterval interval 0 (always update) svdhE
Define the number of seconds a session's expiry may change without the session being updated
SessionHeader headersvdhE
Import session updates from a given HTTP response header
SessionInclude pathsvdhE
Define URL prefixes for which a session is valid
SessionMaxAge maxage 0 svdhE
Define a maximum age in seconds for a session
SetEnv env-variable [value]svdhB
Sets environment variables
SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on attributes of the request
SetEnvIfExpr expr [!]env-variable[=value] [[!]env-variable[=value]] ...svdhB
Sets environment variables based on an ap_expr expression
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|none|expressionsvdhC
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
SSIETag on|off off dhB
Controls whether ETags are generated by the server.
SSILastModified on|off off dhB
Controls whether Last-Modified headers are generated by the server.
SSILegacyExprParser on|off off dhB
Enable compatibility mode for conditional expressions.
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
SSLCARevocationCheck chain|leaf|none [flags ...] none svE
Enable CRL-based revocation checking
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-path|certidsvE
Server PEM-encoded X.509 certificate data file or token identifier
SSLCertificateKeyFile file-path|keyidsvE
Server PEM-encoded private key file
SSLCipherSuite [protocol] cipher-spec DEFAULT (depends on +svdhE
Cipher Suite available for negotiation in SSL handshake
SSLCompression on|off off svE
Enable compression on the SSL level
SSLCryptoDevice engine builtin sE
Enable use of a cryptographic hardware accelerator
SSLEngine on|off|optional off svE
SSL Engine Operation Switch
SSLFIPS on|off off sE
SSL FIPS mode Switch
SSLHonorCipherOrder on|off off svE
Option to prefer the server's cipher preference order
SSLInsecureRenegotiation on|off off svE
Option to enable support for insecure renegotiation
SSLOCSPDefaultResponder urisvE
Set the default responder URI for OCSP validation
SSLOCSPEnable on|leaf|off off svE
Enable OCSP validation of the client certificate chain
SSLOCSPNoverify on|off off svE
skip the OCSP responder certificates verification
SSLOCSPOverrideResponder on|off off svE
Force use of the default responder URI for OCSP validation
SSLOCSPProxyURL urlsvE
Proxy URL to use for OCSP requests
SSLOCSPResponderCertificateFile filesvE
Set of trusted PEM encoded OCSP responder certificates
SSLOCSPResponderTimeout seconds 10 svE
Timeout for OCSP queries
SSLOCSPResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP responses
SSLOCSPResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP response validation
SSLOCSPUseRequestNonce on|off on svE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd command-name command-valuesvE
Configure OpenSSL parameters through its SSL_CONF API
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 -SSLv3 (up to 2 +svE
Configure usable SSL/TLS protocol versions
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
SSLProxyCARevocationCheck chain|leaf|none none svE
Enable CRL-based revocation checking 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
SSLProxyCheckPeerCN on|off on svE
Whether to check the remote server certificate's CN field
SSLProxyCheckPeerExpire on|off on svE
Whether to check if remote server certificate is expired
SSLProxyCheckPeerName on|off on svE
Configure host name checking for remote server certificates
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +svE
Cipher Suite available for negotiation in SSL proxy handshake
SSLProxyEngine on|off off svE
SSL Proxy Engine Operation Switch
SSLProxyMachineCertificateChainFile filenamesvE
File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate
SSLProxyMachineCertificateFile filenamesvE
File of concatenated PEM-encoded client certificates and keys to be used by the proxy
SSLProxyMachineCertificatePath directorysvE
Directory of PEM-encoded client certificates and keys to be used by the proxy
SSLProxyProtocol [+|-]protocol ... all -SSLv3 (up to 2 +svE
Configure usable SSL protocol flavors for proxy usage
SSLProxyVerify level none svE
Type of remote server Certificate verification
SSLProxyVerifyDepth number 1 svE
Maximum depth of CA Certificates in Remote Server Certificate verification
SSLRandomSeed context source [bytes]sE
Pseudo Random Number Generator (PRNG) seeding source
SSLRenegBufferSize bytes 131072 dhE
Set the size for the SSL renegotiation buffer
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
SSLSessionTicketKeyFile file-pathsvE
Persistent encryption/decryption key for TLS session tickets
SSLSessionTickets on|off on svE
Enable or disable use of TLS session tickets
SSLSRPUnknownUserSeed secret-stringsvE
SRP unknown user seed
SSLSRPVerifierFile file-pathsvE
Path to SRP verifier file
SSLStaplingCache typesE
Configures the OCSP stapling cache
SSLStaplingErrorCacheTimeout seconds 600 svE
Number of seconds before expiring invalid responses in the OCSP stapling cache
SSLStaplingFakeTryLater on|off on svE
Synthesize "tryLater" responses for failed OCSP stapling queries
SSLStaplingForceURL urisvE
Override the OCSP responder URI specified in the certificate's AIA extension
SSLStaplingResponderTimeout seconds 10 svE
Timeout for OCSP stapling queries
SSLStaplingResponseMaxAge seconds -1 svE
Maximum allowable age for OCSP stapling responses
SSLStaplingResponseTimeSkew seconds 300 svE
Maximum allowable time skew for OCSP stapling response validation
SSLStaplingReturnResponderErrors on|off on svE
Pass stapling related OCSP errors on to client
SSLStaplingStandardCacheTimeout seconds 3600 svE
Number of seconds before expiring responses in the OCSP stapling cache
SSLStrictSNIVHostCheck on|off off svE
Whether to allow non-SNI clients to access a name-based virtual host.
SSLUserName varnamesdhE
Variable name to determine user name
SSLUseStapling on|off off svE
Enable stapling of OCSP responses in the TLS handshake
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
StrictHostCheck ON|OFF OFF svC
Controls whether the server requires the requested hostname be listed enumerated in the virtual host handling the request
Substitute s/pattern/substitution/[infq]dhE
Pattern to filter the response content
SubstituteInheritBefore on|off off dhE
Change the merge order of inherited patterns
SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G) 1m dhE
Set the maximum line size
Suexec On|OffsB
Enable or disable the suEXEC feature
SuexecUserGroup User GroupsvE
User and group for CGI programs to run as
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 60 svC
Amount of time the server will wait for certain events before failing a request
TraceEnable [on|off|extended] on svC
Determines the behavior on TRACE requests
TransferLog file|pipesvB
Specify location of a log file
TypesConfig file-path conf/mime.types sB
The location of the mime.types file
UNCList hostname [hostname...]sC
Controls what UNC host names can be accessed by the server
UnDefine parameter-namesC
Undefine the existence of a variable
UndefMacro namesvdB
Undefine a macro
UnsetEnv env-variable [env-variable] ...svdhB
Removes variables from the environment
Use name [value1 ... valueN] svdB
Use a macro
UseCanonicalName On|Off|DNS Off svdC
Configures how the server determines its own name and port
UseCanonicalPhysicalPort On|Off Off svdC
Configures how the server determines its own port
User unix-userid #-1 sB
The userid under which the server will answer requests
UserDir directory-filename [directory-filename] ... svB
Location of the user-specific directories
VHostCGIMode On|Off|Secure On vX
Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to subprocesses created by a virtual host.
VHostGroup unix-groupidvX
Sets the Group ID under which a virtual host runs.
VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assign arbitrary privileges to a virtual host.
VHostSecure On|Off On vX
Determines whether the server runs with enhanced security for the virtualhost.
VHostUser unix-useridvX
Sets the User ID under which a virtual host runs.
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
WatchdogInterval time-interval[s] 1 sB
Watchdog interval in seconds
XBitHack on|off|full off svdhB
Parse SSI directives in files with the execute bit set
xml2EncAlias charset alias [alias ...]sB
Recognise Aliases for encoding values
xml2EncDefault namesvdhB
Sets a default encoding to assume when absolutely no information can be automatically detected
xml2StartParse element [element ...]svdhB
Advise the parser to skip leading junk.

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

评论

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_config.html.ko.euc-kr0000664000175100017510000006304614743132254023254 0ustar covenercovener mod_log_config - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_log_config

ֽ ƴմϴ. ֱٿ ϼ.
: û α׿ Ѵ
:Base
:log_config_module
ҽ:mod_log_config.c

Ŭ̾Ʈ û α׿ Ӱ Ѵ. ڽ ϴ α׸ ְ, ̳ ܺ α׷ α׸ ִ. α׸ ϸ û ݿ û α׿ ߰ϰų ִ.

þ Ѵ. TransferLog α , LogFormat ϴ ϰ, CustomLog ѹ αϰ Ѵ. TransferLog CustomLog þ ϸ û Ͽ ִ.

Support Apache!

þ

Bugfix checklist

top

α ϱ

LogFormat CustomLog þ ƱԸƮ ڿ̴. ڿ û αϿ Ѵ. ڿ αϿ ״ Ǵ ڿ ٲް Ÿ C "\n" "\t" ڸ ִ. αϿ ǥ 齽 տ ݵ 齽 Ѵ.

û Ư¡ ڿ "%" þ Ͽ Ѵ. þ αϿ ȴ.

 ڿ
%% ۼƮ ȣ
%...a IP-ּ
%...A () IP-ּ
%...B HTTP Ʈ.
%...b HTTP Ʈ. 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.
%...t common log format ð (ǥ ) ð
%...{format}t strftime(3) format ð. (ð )
%...T û óϴµ ɸ ð ( ).
%...u (auth ϸ, (%s) 401 ̻ )
%...U ǹڿ û URL .
%...v û ServerName.
%...V UseCanonicalName .
%...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

BufferedLogs þ

:Buffer log entries in memory before writing to disk
:
:ּ
:Base
:mod_log_config

Documentation not yet translated. Please see English version of document.

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

GlobalLog þ

:Sets filename and format of log file
:GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]
:ּ
:Base
:mod_log_config
:Available in Apache HTTP Server 2.4.19 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_config.html.tr.utf80000664000175100017510000011253114743132254022762 0ustar covenercovener mod_log_config - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_log_config

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:Sunucuya yapılan isteklerin günlük kayıtlarının tutulması
Durum:Temel
Modül Betimleyici:log_config_module
Kaynak Dosyası:mod_log_config.c

Özet

Bu modül istemci isteklerinin esnek şekilde günlüklenmesi ile ilgilidir. Günlükler kişiselleştirilebilir biçemdedir ve doğrudan bir dosyaya yazılabileceği gibi boru üzerinden harici bir sürece de yazılabilir. İsteğin özelliklerine bağlı olarak bazı isteklerin günlüklere kaydedilmesi veya kaydedilmemesi mümkün kılınmıştır.

Bu modül üç yönerge içermektedir: Bir günlük dosyası oluşturmak için TransferLog, günlük biçemini kişiselleştirmek için LogFormat ve tek başına bir günlük dosyasını hem tanımlayıp hem de biçemleyen CustomLog yönergesi. Her isteğin çok sayıda dosyaya günlüklenmesini sağlamak için yapılandırma dosyasında her sunucu için birden fazla TransferLog ve CustomLog yönergesi belirtilebilir.

Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Günlük Girdilerinin Kişiselleştirilmesi

LogFormat ve CustomLog yönergelerinin biçem argümanı bir dizgedir. Bu dizge her isteği günlük dosyasına günlüklemek için kullanılır. Doğrudan günlük dosyalarına kopyalanmak üzere dizgesel sabitler içerebileceği gibi satırsonu ve sekme karakterleri olarak C tarzı "\n" ve "\t" denetim karakterlerini de içerebilir. Dizgesel sabit olarak kullanılan tırnak ve tersbölü imlerinin tersbölü ile öncelenmesi gerekir.

İstek özellikleri biçem dizgesine “%” imli belirteçler yerleştirilerek günlüklenir. Bu belirteçler ve anlamları:

Belirteç Açıklama
%% Yüzde imi.
%a Uzak IP adresi ve isteğin portu (mod_remoteip modülüne bakın).
%{c}a bağlantının emsal IP adresi and portu (mod_remoteip modülüne bakın).
%A Yerel IP adresi.
%B HTTP başlıkları hariç, yanıtın bayt cinsinden uzunluğu.
%b HTTP başlıkları hariç, yanıtın bayt cinsinden uzunluğu. OGB biçeminde hiç bayt gönderilmemişse günlüğe '-' yerine '0' çıktılanır.
%{DEĞİŞKEN}C İstek içinde sunucuya gönderilen DEĞİŞKEN çerezinin içeriği. Sadece 0 sürümlü çerezler tam olarak desteklenir.
%D Mikrosaniye cinsinden isteği sunmak için harcanan zaman.
%{DEĞİŞKEN}e DEĞİŞKEN ortam değişkeninin içeriği.
%f Dosya ismi.
%h Uzak konak ismi. HostnameLookups yönergesine öntanımlı olan Off değeri atanmışsa, IP adresi günlüğe kaydedilir. Bir kaç konak için konak ismi de günlüğe kaydoluyorsa muhtemelen onların isimlerini içeren erişim denetim yönergelerine sahipsinizdir. Bak: Require host.
%{c}h %h gibi, ancak her zaman, temel TCP bağlantısının konak adı kaydedilir, ancak mod_remoteip gibi modüller tarafından uzak konak adında yapılan değişiklikler kaydedilmez.
%H İstek Protokolü.
%{DEĞİŞKEN}i İstekle birlikte sunucuya gönderilen DEĞİŞKEN: başlık satır(lar)ının içeriği. Diğer modüllerde (örn. mod_headers) yapılan değişikliklerden etkilenir. Modüllerin çoğu bunu değiştirdiğinde önceki istek başlık isminin ne olduğuyla ilgileniyorsanız, başlığı bir ortam değişkenine kaydetmek için mod_setenvif modülünü kullanın ve yukarıda açıklandığı gibi bu değeri %{DEĞİŞKEN}e ile günlüğe kaydedin.
%k Bu bağlantıda işlenen isteklerin sayısı; yani örneğin, '1' değeri bağlantı kurulduktan sonraki ilk kalıcı bağlantıyı, '2', ikinci bağlantıyı, ..., vb. gösterir; KeepAlive kullanılmışsa değer anlamlıdır; aksi takdirde değer daima 0’dır.
%l Uzak kullanıcı kimliği (sağlanmışsa, identd üzerinden). mod_ident modülü mevcut ve IdentityCheck yönergesine değer olarak On atanmış olmadıkça bu belirteç için günlüğe tire imi yazılır.
%L Hata günlüğündeki istek günlük kimliği (veya bu istek için hata günlüğüne hiçbir şey kaydedilmemise '-'). Bu hataya neyin sebep olduğunu öğrenmek için ilgili hata günlüğü satırına bakın.
%m İstek yöntemi.
%{DEĞİŞKEN}n Diğer modüldeki DEĞİŞKEN bilgisinin içeriği.
%{DEĞİŞKEN}o Yanıttaki DEĞİŞKEN: başlık satır(lar)ının içeriği.
%p Sunucunun isteği sunduğu meşru port.
%{biçem}p Sunucunun veya istemcinin gerçek portu veya sunucunun isteği sunduğu meşru port. Geçerli biçemler: canonical, local ve remote (anlamları sırasıyla: meşru, yerel ve uzak).
%P İsteği sunan çocuk sürecin süreç kimliği.
%{biçem}P İsteği sunan çocuk sürecin süreç kimliği (pid) veya evre kimliği (tid). Geçerli biçemler: pid, tid, hextid.
%q Sorgu dizgesi (bir sorgu dizgesi mevcutsa önüne bir ? eklenir yoksa hiçbir şey eklenmez).
%r İsteğin ilk satırı.
%s Durum. Dahili olarak yönlendirilmiş istekler için isteğin özgün durumudur. İsteğin son durumu için %>s kullanınız.
%t [18/Sep/2011:19:18:28 -0400] biçeminde isteğin alındığı tarih ve saat. Sondaki sayı zaman diliminin GMT'ye uzaklığıdır.
%{biçem}t İsteğin alındığı tarih ve saat; biçem uzatılmış strftime(3) biçeminde belirtilmelidir (genelde yerelleştirme amaçlı). begin: (öntanımlı) ile başlayan biçemlerde süre isteğin başlangıcına göredir. end: ile başlayan biçemlerde ise süre isteğin işlenmesinin bi,tmesine yakın, günlük girdisinin yazılmaya başladığı ana göredir. strftime(3) tarafından desteklenen biçemlere ek olarak aşağıdaki biçem dizgecikleri de desteklenmektedir:
secMutlak zaman başlangıcından (epoch) beri geçen saniye sayısı
msecMutlak zaman başlangıcından beri geçen milisaniye sayısı
usecMutlak zaman başlangıcından beri geçen mikrosaniye sayısı
msec_fracmilisaniyelik kesir
usec_fracmikrosaniyelik kesir
Bu dizgecikler, aynı biçem dizgesi içinde bir diğeriyle birlikte veya strftime(3) biçemlemesiyle birlikte yer alamazlar fakat çok sayıda %{biçem}t kullanılabilir.
%T Saniye cinsinden, isteği sunmak için harcanan zaman.
%{BİRİM}T BİRİM ile belirtilen zaman birimi cinsinden, isteği sunmak için harcanan zaman. Geçerli birimler: milisaniye için ms, mikrosaniye için us, saniye için s. s kullanımı birimsiz %T ile aynı sonucu verir; us kullanımı %D ile aynı sonucu verir. Birimli %T kullanımı 2.4.13 ve sonrasında geçerlidir.
%u Uzak kullanıcı (kimlik doğrulaması istenmişse vardır; durum kodu (%s) 401 ise yanlış olabilir).
%U Herhangi bir sorgu dizgesi içermeksizin istenen URL yolu.
%v İsteği sunan sunucunun meşru sunucu ismi (ServerName).
%V UseCanonicalName ayarı ile ilgili sunucu ismi.
%X Yanıt tamamlandığında bağlantı durumu:
X = Yanıt tamamlanmadan bağlantı koptu.
+ = Yanıt gönderildikten sonra bağlantı canlı kalabilir.
- = Yanıt gönderildikten sonra bağlantı kapatılacak.
%I İstek ve başlıklar dahil alınan bayt sayısı. Sıfır olamaz. Bunu kullanmak için mod_logio etkin olmalıdır.
%O Başlıklar dahil gönderilen bayt sayısı. Bir yanıtın gönderilmesinden önce istekten vazgeçilmesi gibi nadir durumlarda sıfır olabilir. Bunu kullanmak için mod_logio etkin olmalıdır.
%S Aktarılan bayt sayısı (alınan ve gönderilen), istekler ve başlıklar dahil; sıfır olamaz. %I ve %O'nun birleşimidir. Bunu kullanmak için mod_logio etkinleştirilmelidir.
%{ALANADI}^ti Sunucuya gönderilen istekteki ALANADI: Trailer satır(lar)ının içeriği.
%{VARNAME}^to Sunucudan gönderilen yanıttaki ALANADI: Trailer satır(lar)ının içeriği.

Değiştiriciler

Belli öğelerin sadece belli durum kodlarıyla ilgili yanıtlarla basılabilmesi için bu durum kodları % iminden hemen sonra virgüllerle ayrılmış olarak yazılabilir. Olumsuzlama belirtmek için durum kodu listesinin önüne bir "!" konabilir.

Biçem Dizgesi Anlamı
%400,501{User-agent}i Sadece 400 ve 501 hatalarında User-agent günlüğe kaydedilir. Diğer durum kodları için günlüğe "-" yazılır.
%!200,304,302{Referer}i 200,304,302 durum kodlarından biriyle dönmeyen tüm istekler için Referer başlığı durum koduyla birlikte günlüğe kaydedilir. Aksi takdirde günlüğe "-" yazılır.

İsteğin dahili olarak yönlendirilmesinde özgün durumunun mu yoksa son durumunun mu hesaba katılacağı "<" ve ">" değiştiricileri ile belirtilebilir. Öntanımlı olarak %s, %U, %T, %D, ve %r belirteçleri isteğin özgün durumuna bakarken diğerleri son durumuna bakarlar. Bu bakımdan örneğin, %>s belirteci, özgün istekteki kimliği doğrulanmış kullanıcının, dahili olarak kimlik doğrulaması gerekmeyen bir özkaynağa yönlendirilmesi halinde isteğin son durumunu kaydetmekte kullanılabilir.

Bazı Bilgiler

Güvenlik nedeniyle, 2.0.46 sürümünden itibaren %r, %i ve %o belirteçlerinde basılamayan karakterler ve diğer özel karakterler \xhh dizilimleri biçeminde öncelenmektedir. Burada hh yerine karakter numarasının onaltılık gösterimi yazılır. Bir tersbölü ile öncelenmesi gereken " ve \ ile \n, \t gibi C tarzı gösterimler bu kuralın dışındadır. 2.0.46 sürümünün öncesinde bu dizgeler öncelenmezdi ve ham günlük dosyalarıyla çalışırken dikkatli olmak gerekirdi.

2.0 sürümünden beri 1.3 sürümünün aksine %b ve %B biçem belirteçleri, istemciye gönderilen bayt sayısını değil, HTTP yanıtının bayt sayısını ifade ederdi (bu yanıt, örneğin, SSL kullanıldığında veya bağlantı koptuğunda farklı uzunlukta olur). Artık, ağa gönderilen gerçek bayt sayısını günlüğe kaydetmek için mod_logio modülü tarafından sağlanan %O biçem belirteci kullanılmaktadır.

Ek bilgi: mod_cache standat bir eylemci olarak değil hızlı bir eylemci olarak gerçeklenmiştir. Bu nedenle, içerik arabelleklemesi sözkonusu olduğunda %R biçem dizgesi herhangi bir eylemci bilgisi döndürmeyecektir.

Örnekler

Genelde herkesçe kullanılan günlük kaydı biçemleme dizgelerinden bazıları:

Ortak Günlük Biçemi (OGB)
"%h %l %u %t \"%r\" %>s %b"
Sanal Konaklı Ortak Günlük Biçemi
"%v %h %l %u %t \"%r\" %>s %b"
NCSA uzun/birleşik günlük biçemi
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
Referer başlığını içeren günlük biçemi
"%{Referer}i -> %U"
User-agent başlığını içeren günlük biçemi
"%{User-agent}i"

msec_frac gibi ek biçem dizgeciklerini kullanan bir zaman biçemi belirtmek isterseniz %{format}t biçem dizgesini defalarca kullanabilirsiniz:

Milisaniyeleri de içeren bir zaman damgası
"%{%d/%b/%Y %T}t.%{msec_frac}t %{%z}t"
top

Güvenlik Kaygıları

Günlük dosyarının kaydedildiği dizine sunucuyu başlatan kullanıcı dışında diğer kullanıcılar tarafından yazılabiliyor olması halinde güvenliğinizden nasıl feragat etmiş olacağınız güvenlik ipuçları belgesinde açıklanmıştır.

top

BufferedLogs Yönergesi

Açıklama:Günlük girdilerini diske yazmadan önce bellekte tamponlar
Sözdizimi:BufferedLogs On|Off
Öntanımlı:BufferedLogs Off
Bağlam:sunucu geneli
Durum:Temel
Modül:mod_log_config
Uyumluluk:2.0.41 ve sonrasında mevcuttur.

BufferedLogs yönergesi, mod_log_config modülünün çeşitli günlük girdilerini her isteğin hemen ardından tek tek değil, bir bütün halinde diske yazılmak üzere bellekte saklanmasını sağlar. Bu, bazı sistemlerde daha verimli disk erişimi, dolayısıyla daha yüksek başarım sağlayabilir. Sadece sunucu geneli için belirtilebilir, sanal konaklar için ayrı ayrı yapılandırılamaz.

Bir çökme günlük verisi kaybına sebep olacağından bu yönerge dikkatli kullanılmalıdır.
top

CustomLog Yönergesi

Açıklama:Günlük dosyasın ismini ve girdi biçemini belirler.
Sözdizimi:CustomLog dosya|borulu-süreç biçem|takma-ad [env=[!]ortam-değişkeni]| expr=ifade]
Bağlam:sunucu geneli, sanal konak
Durum:Temel
Modül:mod_log_config

CustomLog yönergesi istekleri günlüğe kaydetmek için kullanılır. Yönerge ile bir günlük biçemi belirtilebilir ve günlük kaydı isteğin özelliklerine bağlı olarak ortam değişkenleri vasıtasıyla şarta bağlı kılınabilir.

İlk argümanda günlüğün yazılacağı yer belirtilir. İki tür yer belirtilebilir:

dosya
ServerRoot yönergesinin değerine göreli bir dosya ismi.
borulu-süreç
"|" boru karakteri ile öncelenmiş olarak günlük bilgisini standart girdisinden kabul edecek sürecin ismi (veya komut satırı) Daha fazla bilgi için borulu günlüklere bakınız.

Güvenlik:

Bir borulu süreç kullanılmışsa, süreç httpd’yi başlatan kullanıcı tarafından başlatılacaktır. Sunucu root tarafından başlatılıyorsa bu root olacaktır; bu bakımdan günlük kaydını alacak programın güvenilir olması önemlidir.

Bilginize

Dosya yolunu belirtirken tersbölü çizgisi kullanılan Unix dışı platformlarda bile yapılandırma dosyasında bu amaçla normal bölü çizgilerini kullanmaya özen gösterilmelidir.

İkinci argümanda günlüğe ne yazılacağı belirtilir. Ya evvelce LogFormat yönergesi ile tanımlanmış bir takma-ad ya da içeriği Günlük Girdilerinin Kişiselleştirilmesi bölümünde açıklanmış bir biçem dizgesi olabilir.

Örneğin, aşağıdaki iki yönerge kümesi aynı etkiye sahiptir:

# Biçem dizgesi yerine takma ad içeren CustomLog
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog "logs/access_log" common

# Biçem dizgesinin kendisini içeren CustomLog
CustomLog "logs/access_log" "%h %l %u %t \"%r\" %>s %b"

Üçüncü argüman isteğe bağlı olup,belli bir isteğin günlüğe kaydedilip kaydedilmeyeceğini belirler. Koşul, sunucu ortamında belli bir değişkenin varlığı veya yokluğu olabilir (bir 'env=!isim' durumu). İstenirse koşul keyfi bir mantıksal ifade olarak da belirtilebilir. Eğer koşul sağlanmazsa istek günlüğe kaydedilmez. İfadede bulunan HTTP başlıklarına başvurular bu başlık isimlerinin Vary başlığına eklenmesine sebep olmaz.

Ortam değişkenleri mod_setenvif ve/veya mod_rewrite modülleri kullanılarak her istek için ayrı ayrı atanabilir. Örneğin, GIF biçemli resimler için yapılan istekleri ana günlük dosyasına değil de başka bir dosyaya kaydetmek isterseniz:

SetEnvIf Request_URI \.gif$ gif-image
CustomLog "gif-requests.log" common env=gif-image
CustomLog "nongif-requests.log" common env=!gif-image

Veya eski RefererIgnore yönergesinin davranışını taklit etmek isterseniz:

SetEnvIf Referer example\.com localreferer
CustomLog "referer.log" referer env=!localreferer
top

GlobalLog Yönergesi

Açıklama:Günlük dosyasının ismini ve biçemini belirler
Sözdizimi:GlobalLog dosya|boru|sağlayıcı biçem|takma_ad [env=[!]ortam_değişkeni| expr=ifade]
Bağlam:sunucu geneli
Durum:Temel
Modül:mod_log_config
Uyumluluk:Apache HTTP Sunucusunun 2.4.19 ve sonraki sürümlerinde kullanılabilir.

GlobalLog yönergesi ana sunucu yapılandırması ve tüm tanımlı sanal konaklarca paylaşılan bir günlük tanımlar.

GlobalLog yönergesi aşağıdaki farklar dışında CustomLog yönergesine eşdeğerdir:

top

LogFormat Yönergesi

Açıklama:Bir günlük dosyasında kullanılmak üzere girdi biçemi tanımlar.
Sözdizimi:LogFormat biçem|takma-ad [takma-ad]
Öntanımlı:LogFormat "%h %l %u %t \"%r\" %>s %b"
Bağlam:sunucu geneli, sanal konak
Durum:Temel
Modül:mod_log_config

Bu yönerge erişim günlüğü dosyasının girdi biçemini belirler.

LogFormat yönergesi iki şekilde kullanılabilir. Tek argüman belirtilebilen ilkinde daha sonra TransferLog yönergelerinde belirtilen günlüklerde kullanılmak üzere günlük biçemini belirler. Bu günlük biçemi yukarıda açıklanan biçem belirteçlerinden oluşur. Bu tek argüman yerine aşağıda açıklandığı gibi önceki bir LogFormat yönergesinde tanımlanmış bir günlük biçemine atıf yapan bir takma-ad da belirtilebilir.

LogFormat yönergesinin ikinci kullanım şeklinde biçem bir takma-ad için tanımlanır. Bu takma ad daha sonraki LogFormat veya CustomLog yönergelerinde aynı biçem dizgesini uzun uzadıya yazmamak için takma-ad olarak kullanılır. Bir LogFormat yönergesi bir takma ad tanımlamaktan başka bir şey yapmaz; yani, yaptığı iş sadece bir takma ad tanımlamaktan ibarettir, biçemi uygulamaz veya biçemi öntanımlı hale getirmez. Bu bakımdan sonraki TransferLog yönergelerini de etkilemeyecektir. Ayrıca, LogFormat yönergesi bir takma ada başka bir takma ad tanımlamakta da kullanılamaz. Bir takma adın yüzde imi (%) içeremeyeceğine de dikkat ediniz.

LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
top

TransferLog Yönergesi

Açıklama:Bir günlük dosyasının yerini belirtir.
Sözdizimi:TransferLog dosya|borulu-süreç [takma-ad]
Bağlam:sunucu geneli, sanal konak
Durum:Temel
Modül:mod_log_config

Bir günlük biçemi tanımlanmasını ve şarta bağlı günlük kaydını mümkün kılmaması haricinde CustomLog yönergesi gibidir. Günlük biçemi yerine kendinden önce yer alan bir LogFormat yönergesinde tanımlanan bir takma ad kullanılır. Açıkça bir günlük biçemi takma adı belirtilmedikçe Ortak Günlük Biçemi öntanımlıdır.

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
TransferLog "logs/access_log"

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_forensic.html.tr.utf80000664000175100017510000003241614743132254023330 0ustar covenercovener mod_log_forensic - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_log_forensic

Mevcut Diller:  en  |  fr  |  ja  |  tr 

Açıklama:Sunucuya yapılan isteklerin adli günlük kayıtlarının tutulması
Durum:Eklenti
Modül Betimleyici:log_forensic_module
Kaynak Dosyası:mod_log_forensic.c
Uyumluluk:2.1 sürümünden beri mod_unique_id gerekmemektedir.

Özet

Bu modül istemci isteklerinin adli günlük kayıtlarının tutulmasını sağlar. Günlük kaydı bir istek işlenmeden önce ve sonra olmak üzere iki kere yapılır, böylece günlükte her istek için iki girdi bulunur. Adli günlükleyici çok sıkı kurallara tabidir, yani:

Dağıtımın support dizininde bulunan check_forensic betiği adli günlük dosyalarının değerlendirilmesinde yardımcı olabilir.

Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Adli Günlük Biçemi

Her istek günlüğe iki defa kaydedilir. İlki, işlemin başlangıcında (yani, başlıklar alındıktan hemen sonra), ikincisi ise istek işlem gördükten sonra normal günlüklemenin yapıldığı sırada yapılır.

Her isteği betimlemek için eşsiz bir istek kimliği atanır. Bu adli kimliğin normal günlüğe de yazılması istenirse bu %{forensic-id}n biçem dizgesi ile yapılabilir. mod_unique_id kullanılıyorsa, onun ürettiği kimlik kullanılır.

İlk satır günlüğe, adli kimliği, istek satırını ve alınan tüm başlıkları boru karakterleri (|) ile ayrılmış olarak kaydeder. Aşağıda bir örneğe yer verilmiştir (hepsi bir satırdadır):

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

Başlangıçtaki artı imi bu günlük satırının istekle ilgili ilk günlük kaydı olduğunu belirtir. İkinci satırda bunun yerini bir eksi imi alır:

-yQtJf8CoAB4AAFNXBIEAAAAA

check_forensic betiği komut satırı argümanı olarak günlük dosyasının ismini alır. Bu +/- kimlik çiftlerine bakarak tamamlanmamış istekler varsa bunlar hakkında uyarır.

top

Güvenlik Kaygıları

Günlük dosyarının kaydedildiği dizine sunucuyu başlatan kullanıcı dışında diğer kullanıcılar tarafından yazılabiliyor olması halinde güvenliğinizden nasıl feragat etmiş olacağınız güvenlik ipuçları belgesinde açıklanmıştır.

Günlük dosyaları, Authorization: başlıklarının (parola içerebilen) içerikleri gibi hassas veriler içerebileceğinden bunların sunucuyu başlatan kullanıcıdan başkası tarafından okunamaması sağlanmış olmalıdır.

top

ForensicLog Yönergesi

Açıklama:Adli günlük için dosya ismini belirler.
Sözdizimi:ForensicLog dosya-adı|borulu-süreç
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_log_forensic

ForensicLog yönergesi adli inceleme için sunucuya yapılan istekleri günlüğe kaydetmekte kullanılır. Her günlük girdisine, normal CustomLog yönergesinde kullanılarak istekle ilişkilendirilebilen eşsiz bir kimlik atanır. mod_log_forensic modülü, aktarım günlüğünün biçem dizgesinde %{forensic-id}n şeklinde kullanılmak üzere forensic-id adı verilen bir dizgecik oluşturur.

Günlüğün yazılacağı yeri belirleyen argüman şu iki değerden birini alabilir:

dosya-adı
ServerRoot yönergesinin değerine göreli bir dosya ismi.
borulu-süreç
"|" boru karakteri ile öncelenmiş olarak günlük bilgisini standart girdisinden kabul edecek sürecin ismi (veya komut satırı). Program adının ServerRoot yönergesinin değerine göre belirtildiği varsayılır.

Güvenlik:

Bir borulu süreç kullanılmışsa, süreç httpd’yi başlatan kullanıcı tarafından başlatılacaktır. Sunucu root tarafından başlatılıyorsa bu root olacaktır; bu bakımdan günlük kaydını alacak programın güvenilir olması veya daha az yetkili bir kullanıcıya geçiş yapması önemlidir.

Bilginize

Dosya yolunu belirtirken tersbölü çizgisi kullanılan Unix dışı platformlarda bile yapılandırma dosyasında bu amaçla normal bölü çizgilerini kullanmaya özen gösterilmelidir.

Mevcut Diller:  en  |  fr  |  ja  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_http2.html.fr.utf80000664000175100017510000023347315021032132021670 0ustar covenercovener mod_http2 - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_http2

Langues Disponibles:  en  |  fr 

Description:Support de la couche transport HTTP/2
Statut:Extension
Identificateur de Module:http2_module
Fichier Source:mod_http2.c
Compatibilité:Disponible à partir de la version 2.4.17 du serveur HTTP Apache

Sommaire

Ce module ajoute le support de HTTP/2 (RFC 7540) au serveur HTTP Apache.

Il s'appuie sur la bibliothèque libnghttp2 pour implémenter le moteur de base http/2.

Pour mettre en oeuvre les fonctionnalités décrites dans ce document, vous devez activer HTTP/2 en utilisant la directive Protocols. HTTP/2 n'imposant pas de chiffrement, deux protocoles sont disponibles : h2 (HTTP/2 avec TLS) at h2c (HTTP/2 avec TCP).

Voici deux types de configuration courant :

HTTP/2 dans un contexte de serveur virtuel (TLS seulement)

Protocols h2 http/1.1

Permet une négociation HTTP/2 (h2) via TLS ALPN au sein d'un <VirtualHost> sécurisé. La vérification du préambule HTTP/2 (mode direct, voir H2Direct) est désactivée par défaut pour h2.

HTTP/2 dans un contexte de serveur (TLS et texte pur)

Protocols h2 h2c http/1.1

Permet une négociation HTTP/2 (h2) via TLS ALPN au sein d'un <VirtualHost> sécurisé. Permet aussi une négociation HTTP/2 en texte pur (h2c) en effectuant une mise à jour depuis une connexion initiale HTTP/1.1 ou via une vérification du préambule HTTP/2 (mode direct, voir H2Direct).

Si vous avez besoin d'informations supplémentaires à propos du protocole, veuillez vous reporter à la HTTP/2 FAQ.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Comment ça marche ?

Quantification des ressources supplémentaires nécessaires à HTTP/2

Activer HTTP/2 sur votre serveur Apache a un impact sur la consommation de ressources, et si votre site est très actif, il est conseillé d'en prendre sérieusement en compte les implications.

HTTP/2 attribue à chaque requête qu'il reçoit son propre thread de travail pour son traitement, la collecte des résultats et l'envoie de ces derniers au client. Pour y parvenir, il lui faut lancer des threads supplémentaires, et ceci constituera le premier effet notable de l'activation de HTTP/2.

Dans l'implémentation actuelle, ces threads de travail font partie d'un jeu de threads distinct de celui des threads de travail du MPM avec lequel vous êtes familié. Il s'agit simplement du mode de fonctionnement actuel, et il n'en sera pas obligatoirement toujours ainsi (il est cependant probable que la situation restera inchangée avec la version 2.4.x). De par ce mode de fonctionnement, les threads de travail HTTP/2, ou plus simplement H2 ne seront pas affichés par mod_status. De même, ils ne seront pas pris en compte par les directives du style ThreadsPerChild. Par contre, ils utilisent par défaut la valeur de ThreadsPerChild si vous n'avez pas spécifié d'autres valeurs via H2MinWorkers et H2MaxWorkers.

Autre changement à surveiller : la consommation de mémoire. En effet, comme HTTP/2 conserve plus d'informations sur le serveur pour gérer toutes les requêtes en cours, leurs priorités et interdépendances, il aura toujours besoin de plus de mémoire que pour un traitement en HTTP/1.1. Trois directives permettent de limiter l'empreinte mémoire d'une connexion HTTP/2 : H2MaxSessionStreams, H2WindowSize et H2StreamMaxMemSize.

La directive H2MaxSessionStreams permet de limiter le nombre de requêtes simultanées qu'un client peut envoyer sur une connexion HTTP/2. La valeur que vous allez définir dépend de votre site. La valeur par défaut qui est de 100 est largement suffisante, et à moins que vous ne soyez un peu juste en mémoire, je vous conseille de ne pas la modifier. La plupart des requêtes qu'envoie un client sont des requêtes de type GET sans corps qui n'utilisent que très peu de mémoire en attendant le démarrage du traitement.

La directive H2WindowSize permet de définir la taille maximale que peut avoir le corps d'une requête que le client envoie avant d'attendre que le serveur en demande d'avantage. En d'autres termes, il s'agit de la quantité de données que le serveur peut stocker dans son tampon, valable pour une requête.

En outre, la directive H2StreamMaxMemSize permet de définir la quantité de données de la réponse qui doit être mise en tampon. Chaque requête étant prise en charge par un thread H2Worker et produisant des données que le serveur tente de transmettre au client via une connexion HTTP/2, si le client n'est pas en mesure de lire ces données assez rapidement, la connexion les mettra en tampon et interrompra l'exécution du thread H2Worker correspondant.

Serveurs virtuels et requêtes mal redirigées

De nombreux site utilisent le même certificat TLS pour plusieurs serveurs virtuels. Ce certificat référence un nom de serveur générique comme '*.example.org' ou plusieurs noms de serveur différents. Les navigateurs qui utilisent HTTP/2 détectent ce comportement et réutilisent une connexion déjà ouverte pour ces serveurs.

Ceci améliore considérablement les performances, mais il y a un prix à payer : il faut accorder un soin tout particulier à la configuration de tels serveurs virtuels. Le problème réside dans le fait que plusieurs requêtes pour plusieurs serveurs virtuels vont se partager la même connexion TLS, et ceci empêche toute renégociation car le standard HTTP/2 l'interdit.

Ainsi, lorsque plusieurs de vos serveurs virtuels utilisent le même certificat et si vous souhaitez utiliser HTTP/2 pour y accéder, vous devez vous assurer que tous vos serveurs virtuels possèdent exactement la même configuration SSL. En particulier, ils doivent utiliser les mêmes protocole, algorithme de chiffrement et configuration pour la vérification du client.

Dans le cas contraire, Apache httpd le détectera et renverra au client un code de réponse spécial, 421 Misdirected Request.

Variables d'environnement

Ce module peut être configuré pour fournir des informations en rapport avec HTTP/2 sous la forme de variables d'environnement supplémentaires dans l'espace de nommage SSI et CGI, ainsi que dans les configurations personnalisées de le journalisation (voir %{VAR_NAME}e).

Nom variable : Type : Description :
HTTPedrapeauHTTP/2 est utilisé.
H2PUSHdrapeauLa fonctionnalité HTTP/2 Server Push est activée pour cette requête et supportée par le client.
H2_PUSHdrapeauautre nom pour H2PUSH
H2_PUSHEDchaînevide ou PUSHED pour une requête pushée par le serveur.
H2_PUSHED_ONnombrenuméro du flux HTTP/2 qui a déclenché le push de cette requête.
H2_STREAM_IDnombrenuméro du flux HTTP/2 de cette requête.
H2_STREAM_TAGchaîneidentifiant de flux unique du processus HTTP/2 composé de l'identifiant de la connexion et de l'identifiant du flux séparés par -.
top

Directive H2CopyFiles

Description:Contrôle la gestion des fichiers dans les réponses
Syntaxe:H2CopyFiles on|off
Défaut:H2CopyFiles off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.24 du serveur HTTP Apache.

Cette directive permet de définir la manière de gérer les contenus de fichiers dans les réponses. Lorsqu'elle est à off (sa valeur par défaut), les descripteurs de fichiers sont transmis par le processus de traitement de la requête vers la connexion principale en utilisant le système habituel de mise en réserve d'Apache pour gérer le durée de vie du fichier.

Lorsqu'elle est à on, le contenu du fichier est recopier pendant le traitement de la requête et ces données mises en tampon sont transmises vers la connexion principale, ce qui s'avère avantageux lorsqu'un module tiers injecte dans la réponse des fichiers possédant des durées de vie différentes.

Un exemple de ces modules tiers : mod_wsgi qui peut injecter des descripteurs de fichiers dans la réponse. Ces fichiers sont fermés lorsque Python estime que le traitement est terminé, alors que mod_http2 est probablement encore loin d'en avoir fini avec eux.

top

Directive H2Direct

Description:Activation du protocole H2 Direct
Syntaxe:H2Direct on|off
Défaut:H2Direct on pour h2c, off pour le protocole h2
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2

Cette directive permet d'activer/désactiver l'utilisation du mode HTTP/2 Direct. Elle doit être située dans une section <VirtualHost> afin d'activer la communication directe HTTP/2 pour le serveur virtuel considéré.

La notion de communication directe signifie que si les premiers octets reçus par le serveur correspondent à un en-tête HTTP/2, le protocole HTTP/2 est utilisé sans négociation supplémentaire. Ce mode est défini pour les transmissions en clair (h2c) dans la RFC 7540. Son utilisation avec les connexions TLS n'est pas officiellement supportée.

Lorsque le protocole h2 ou h2c n'est pas activé via la directive Protocols, la recherche d'un en-tête HTTP/2 n'est jamais effectuée au sein d'une connexion. La directive H2Direct ne produit alors aucun effet. Ceci est important pour les connexions qui utilisent un protocole pour lequel une lecture initiale peut entraîner un blocage définitif comme NNTP.

Pour un client qui sait qu'un serveur supporte h2c, la communication directe HTTP/2 dispense le client d'une mise à jour HTTP/1.1, ce qui entraîne une amélioration des performances et évite les restrictions sur les corps de requête suite à une mise à jour.

Cette directive rend aussi h2c plus attractif pour les communications de serveur à serveur lorsque la connexion est sure ou peut être sécurisée d'une manière ou d'une autre.

Exemple

H2Direct on
top

Directive H2EarlyHint

Description:Ajoute un en-tête de réponse à consulter dans le code de retour 103 Early Hints
Syntaxe:H2EarlyHint name value
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache.

La directive H2EarlyHint permet d'ajouter un en-tête de réponse avant le démarrage du traitement proprement dit de la requête. Les en-têtes de ce style sont consultables dans les réponses intermédiaires "103 Early Hints" et ils ont pour but principal d'envoyer des informations de "préchargement" aux navigateurs clients.

name et value doivent être des champs d'en-tête HTTP valables sous peine de provoquer des échecs de réponse. La directive H2EarlyHints doit encore être activée pour permettre l'envoi de réponses intermédiaires de code 103. Elle peut être répétée plusieurs fois et les champs d'en-tête de même nom s'ajoutent.

Exemple

H2EarlyHint Link "</my.css>;rel=preload;as=style"
top

Directive H2EarlyHints

Description:Contrôle l'envoi de codes d'état 103
Syntaxe:H2EarlyHints on|off
Défaut:H2EarlyHints off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.24 du serveur HTTP Apache.

Cette directive permet de définir si les réponses intermédiaires contenant un code d'état HTTP 103 doivent être envoyées au client ou non. Par défaut ce n'est actuellement pas le cas car certains clients ont encore des problèmes avec les réponses intermédiaires inattendues.

Lorsque cette directive est définie à on, les ressources PUSHées définie par la directive H2PushResource déclenchent une réponse intermédiaire 103 avant la réponse finale. Cette réponse 103 comporte des en-têtes Link qui provoquent le préchargement des ressources considérées.

top

Directive H2MaxDataFrameLen

Description:Nombre maximal d'octets dans une trame HTTP/2 DATA
Syntaxe:H2MaxDataFrameLen n
Défaut:H2MaxDataFrameLen 0
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache.

La directive H2MaxDataFrameLen permet de définir le nombre maximal d'octets du corps de réponse que l'on peut placer dans une seule trame HTTP/2 DATA. La valeur 0 signifie aucune limite (mais la taille maximale permise par le protocole est respectée).

Par défaut, le module essaie d'utiliser la taille maximale possible qui est d'environ 16 Ko. Il s'agit cependant de la taille maximale, et lorsque la taille des données de la réponse est inférieure, les trames envoyées sont plus courtes.

top

Directive H2MaxHeaderBlockLen

Description:Taille maximale des en-têtes d’une réponse
Syntaxe:H2MaxHeaderBlockLen n
Défaut:H2MaxHeaderBlockLen 0
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.64 du serveur HTTP Apache.

La directive H2MaxHeaderBlockLen permet de définir la taille maximale globale des en-têtes d’une réponse. Définir cette directive à 0 implique une taille maximale de 64 ko dans nghttp2, ce qui correspond à la valeur par défaut.

Les réponses dont la somme des tailles de tous les en-têtes est supérieure à la valeur de cette directive ne seront pas traitées et provoqueront une réinitialisation du flux.

top

Directive H2MaxSessionStreams

Description:Nombre maximal de flux actifs par session HTTP/2.
Syntaxe:H2MaxSessionStreams n
Défaut:H2MaxSessionStreams 100
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2

Cette directive permet de définir le nombre maximal de flux actifs par session (connexion) HTTP/2 accepté par le serveur. Selon la RFC 7540, un flux est considéré comme actif s'il n'est ni en attente ni fermé.

Exemple

H2MaxSessionStreams 20
top

Directive H2MaxWorkerIdleSeconds

Description:Nombre maximal de secondes pendant lequel une unité de traitement h2 pourra rester inactive sans être arrêtée.
Syntaxe:H2MaxWorkerIdleSeconds n
Défaut:H2MaxWorkerIdleSeconds 600
Contexte:configuration globale
Statut:Extension
Module:mod_http2

Cette directive permet de définir le nombre maximal de secondes pendant lequel une unité de traitement h2 pourra rester inactive avant de s'arrêter elle-même. Cet arrêt ne peut cependant se produire que si le nombre d'unités de traitement h2 dépasse H2MinWorkers.

Exemple

H2MaxWorkerIdleSeconds 20
top

Directive H2MaxWorkers

Description:Nombre maximal de threads à utiliser pour chaque processus enfant.
Syntaxe:H2MaxWorkers n
Contexte:configuration globale
Statut:Extension
Module:mod_http2

Cette directive permet de définir le nombre maximal de threads à lancer pour le traitement HTTP/2 de chaque processus enfant. Si cette directive n'est pas définie, mod_http2 choisira une valeur appropriée en fonction du module mpm utilisé. This directive sets the maximum number of worker threads to spawn per child process for HTTP/2 processing. If this directive is not used, mod_http2 will chose a value suitable for the mpm module loaded.

Exemple

H2MaxWorkers 20
top

Directive H2MinWorkers

Description:Nombre minimal de threads à utiliser pour chaque processus enfant.
Syntaxe:H2MinWorkers n
Contexte:configuration globale
Statut:Extension
Module:mod_http2

Cette directive permet de définir le nombre minimal de threads à lancer pour le traitement HTTP/2 de chaque processus enfant. Si cette directive n'est pas définie, mod_http2 choisira une valeur appropriée en fonction du module mpm utilisé.

Exemple

H2MinWorkers 10
top

Directive H2ModernTLSOnly

Description:Impose les connexions HTTP/2 en mode "TLS moderne" seulement
Syntaxe:H2ModernTLSOnly on|off
Défaut:H2ModernTLSOnly on
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.18 du serveur HTTP Apache.

Cette directive permet de définir si les vérifications de sécurité sur les connexions HTTP/2 doivent être exclusivement en mode TLS (https:). Elle peut être placée au niveau du serveur principal ou dans une section <VirtualHost>.

Les vérifications de sécurité nécessitent TLSv1.2 au minimum et l'absence de tout algorithme de chiffrement listé dans la RFC 7540, Appendix A. Ces vérifications seront étendues lorsque de nouveaux prérequis en matière de sécurité seront mis en place.

Le nom provient des définitions Mozilla Security/Server Side TLS où il est question de "modern compatibility". Mozilla Firefox et d'autres navigateurs imposent la "modern compatibility" pour les connexions HTTP/2. Comme toute chose en matière de sécurité opérationnelle, c'est une cible mouvante susceptible d'évoluer dans le futur.

Un des buts de ces vérifications dans mod_http2 tend à imposer ce niveau de sécurité pour toutes les connexions, et non seulement celles en provenance des navigateurs web. Un autre but est l'interdiction d'utiliser HTTP/2 en tant que protocole dans les négociations si les prérequis ne sont pas respectés.

En fin de compte, la sécurité de la connexion TLS est déterminée par les directives de configuration du serveur pour mod_ssl.

Exemple

H2ModernTLSOnly off
top

Directive H2OutputBuffering

Description:Contrôle la mise en tampon du flux de sortie
Syntaxe:H2OutputBuffering on|off
Défaut:H2OutputBuffering on
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.48 du serveur HTTP Apache.

La directive H2OutputBuffering permet de contrôler la mise en tampon du flux de sortie. La valeur par défaut est on, ce qui correspond au comportement des versions précédentes. Lorsqu'elle est à off, chaque octet est immédiatement disponible pour envoi au client via la connexion principale. Ceci permet de résoudre les problèmes d'inter-opérations avec certaines versions de gRPC.

top

Directive H2Padding

Description:Spécifie un intervalle de nombres d'octets de bourrage à ajouter aux trames utiles
Syntaxe:H2Padding numbits
Défaut:H2Padding 0
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.39 du serveur HTTP Apache.

La valeur par défaut 0 indique qu'aucun octet de bourrage ne sera ajouté aux trames utiles comme HEADERS, DATA et PUSH_PROMISE. Ceci correspond au comportement des versions précédentes. Dans ce cas et sous certaines conditions, un observateur du trafic réseau pourra alors déterminer la longueur de ces trames dans le flux TLS.

Si on attribue à numbits la valeur 1-8, un nombre aléatoire d'octets entre 0 et 2^numbits sont ajoutés à chaque trame. Une valeur aléatoire d'octets de bourrage est attribué indépendamment à chaque trame que le module renvoie au client.

Pour améliorer la dissimulation de la longueur des trames, on peut augmenter le nombre moyen d'octets de bourrage, mais cela augmente d'autant le trafic réseau. Le nombre optimal d'octets de bourrage dépend donc du type de trafic web que le serveur engendre.

La valeur par défaut de 0 (aucun octet de bourrage) a été choisie dans un but de compatibilité ascendante. Il peut en effet exister des installations où les octets de bourrage ne sont pas souhaités ou sont néfastes. La cause principale peut provenir d'un client dont l'implémentation comporte des erreurs.

top

Directive H2ProxyRequests

Description:Active/Désactive les requêtes sous mandat direct via HTTP/2
Syntaxe:H2ProxyRequests on|off
Défaut:H2ProxyRequests off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache

La directive H2ProxyRequests permet d'activer ou de désactiver la gestion des requêtes HTTP/2 dans un contexte de mandat direct.

Similaire à ProxyRequests, cette directive déclenche le traitement nécessaire des requêtes lorsque HTTP/2 est activé dans un contexte de mandat direct.

top

Directive H2Push

Description:Activation/désactivation du server push H2
Syntaxe:H2Push on|off
Défaut:H2Push on
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.18 du serveur HTTP Apache.

Cette directive permet d'activer/désactiver l'utilisation de la fonctionnalité server push du protocole HTTP/2.

Lorsqu'un client demande une ressource particulière, le protocole HTTP/2 permet au serveur de lui fournir des ressources supplémentaires. Ceci s'avère utile lorsque ces ressources sont reliées entre elles, ce qui peut laisser supposer que le client va probablement les demander dans un délai plus ou moins long. Le mécanisme de pushing permet alors au client d'économiser le temps qu'il lui aurait fallu pour demander ces ressources supplémentaires lui-même. Par contre, fournir au client des ressources dont il n'a pas besoin ou qu'il possède déjà constitue une perte de bande passante.

Les server pushes sont détectés en inspectant les en-têtes Link des réponses (voir https://tools.ietf.org/html/rfc5988 pour la spécification). Lorsqu'un lien spécifié de cette manière possède l'attribut rel=preload, il est considéré comme devant faire l'objet d'un push.

Les en-têtes link des réponses sont soit définis par l'application, soit configurés via H2PushResource ou mod_headers comme suit :

Exemple de configuration d'en-tête link via mod_headers

<Location /index.html>
    Header add Link "</css/site.css>;rel=preload"
    Header add Link "</images/logo.jpg>;rel=preload"
</Location>

Comme le montre l'exemple, il est possible d'ajouter autant d'en-têtes link que l'on souhaite à une réponse, ce qui déclenchera autant de pushes. Cette fonctionnalité doit donc être utilisée avec prudence car le module ne vérifie pas si une ressource n'a pas déjà été "pushée" vers un client.

Les PUSH HTTP/2 sont activés par défaut. Vous pouvez activer/désactiver cette fonctionnalité pour toute connexion au serveur au niveau global ou serveur virtuel. Vous pouvez en outre désactiver PUSH pour un jeu de ressources dans une section Directory/Location. Notez que ceci permet de contrôler quelles ressources peuvent déclencher un PUSH, mais pas les ressources qui peuvent être envoyées via PUSH.

Exemple

H2Push off

Enfin, il est important de savoir que les pushes ne se produisent que si le client en manifeste le désir ; la plupart des navigateurs le font, mais certains, comme Safari 9, ne le font pas. En outre, les pushes ne se produisent que pour les ressources de la même autorité que celle de la réponse originale.

top

Directive H2PushDiarySize

Description:Taille du journal des Pushes H2
Syntaxe:H2PushDiarySize n
Défaut:H2PushDiarySize 256
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.19 du serveur HTTP Apache.

Cette directive permet de définir le nombre maximum de pushes qui seront enregistrés pour une connexion HTTP/2. Elle peut être placée dans une section <VirtualHost> afin de définir le nombre de pushes pour le serveur virtuel considéré.

Le journal des pushes enregistre un condensé des ressources préchargées (leurs URLs) afin d'éviter les duplications de pushes pour une même connexion. Cependant, ces données ne sont pas conservées, et les clients qui ouvrent une nouvelle connexion se verront à nouveau affecter les mêmes pushes.

Si la taille maximale est atteinte, les nouvelles entrées remplacent les plus anciennes. Une entrée du journal nécessitant 8 octets, un journal de 256 entrées consomme 2 Ko de mémoire.

Si cette directive est définie à 0, le journal des pushes est désactivé.

top

Directive H2PushPriority

Description:Priorité des pushes H2
Syntaxe:H2PushPriority mime-type [after|before|interleaved] [weight]
Défaut:H2PushPriority * After 16
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.18 du serveur HTTP Apache. Nécessite la bibliothèque nghttp2 version 1.5.0 ou supérieure.

Cette directive permet de définir une gestion de priorité des pushes en fonction du type de contenu de la réponse. Elle est en général définie au niveau du serveur principal, mais peut aussi l'être au niveau d'un serveur virtuel.

Les pushes HTTP/2 sont toujours liés à une requête client. Chaque paire requête/réponse de cette sorte, ou flux, possède une dépendance et un poids qui définissent la priorité du flux.

Lorsqu'un flux dépend d'un autre, disons X dépend de Y, alors Y reçoit toute la bande passante avant que X n'en reçoive ne serait-ce qu'une partie. Notez que cela ne signifie en rien que Y bloque X ; en effet, si Y n'a aucune donnée à envoyer, toute la bande passante qui lui est allouée peut être utilisée par X.

Lorsque plusieurs flux dépendent d'un même autre flux, disons X1 et X2 dépendent tous deux de Y, le poids détermine la bande passante allouée. Ainsi, si X1 et X2 possèdent le même poids, ils recevront tous deux la moitié de la bande passante disponible. Si le poids de X1 est égal au double de celui de X2, X1 recevra une bande passante double de celle de X2.

En fin de compte, tout flux dépend du flux racine qui reçoit toute la bande passante disponible mais n'envoie jamais de données. Cette bande passante est ainsi répartie entre les flux enfants selon leur poids. Ces derniers l'utilisent alors pour envoyer leurs données ou pour la répartir entre leurs propres flux enfants, et ainsi de suite. Si aucun des flux enfants n'a de données à envoyer, la bande passante est attribuée à d'autres flux selon les mêmes règles.

Ce système de priorités a été conçu de façon a toujours pouvoir utiliser la bande passante disponible tout en définissant des priorités et en attribuant des poids aux différents flux. Ainsi, tous les flux sont en général initialisés par le client qui lui-même définit les priorités.

Seul le fait de savoir qu'un flux implique un PUSH permet au serveur de décider quelle est la priorité initiale d'un tel flux. Dans les exemples ci-dessous, X est le flux client. Il dépend de Y et le serveur décide de "PUSHer" les flux P1 et P2 sur X.

La règle de priorité par défaut est :

Règle de priorité par défaut

H2PushPriority * After 16

Elle peut se traduire par "Envoyer un flux PUSH avec tout type de contenu et dépendant du flux client avec le poids 16". P1 et P2 seront alors envoyés après X, et comme leurs poids sont identiques, il se verront allouer la même quantité de bande passante.

Règle de priorité entrelacée

H2PushPriority text/css Interleaved 256

Ce qui peut se traduire par "Envoyer toute ressource CSS dans la même dépendance et avec le même poids que le flux client". Si le type de contenu de P1 est "text/css", il dépendra de Y (comme X) et son poids effectif sera calculé selon la formule : P1ew = Xw * (P1w / 256). Si P1w est de 256, Le poids effectif de P1 sera le même que celui de X. Si X et P1 ont des données à envoyer, il se verront allouer la même quantité de bande passante.

Avec un Pw de 512, un flux entrelacé et PUSHé aura un poids double de celui de X. Avec un poids de 128, son poids ne sera que la moitié de celui de X. Notez que les poids effectifs sont toujours plafonnés à 256.

Règle de priorité Before

H2PushPriority application/json Before

Dans cet exemple, tout flux PUSHé dont le contenu est de type 'application/json' sera envoyé avant X, ce qui rend P1 dépendant de Y et X dépendant de P1. Ainsi, X sera mis en attente aussi longtemps que P1 aura des données à envoyer. Le poids effectif est hérité du flux client, et l'attribution d'un poids spécifique n'est pas autorisée.

Vous devez garder à l'esprit que les spécifications en matière de priorités sont limitées par les ressources disponibles du serveur. Si un serveur ne dispose d'aucun processus/thread de travail pour les flux PUSHés, les données du flux considéré ne seront envoyées que lorsque les autres flux auront terminé l'envoi des leurs.

Enfin et surtout, il convient de tenir compte de certaines particularités de la syntaxe de cette directive :

  1. '*' est la seule expression permettant de remplacer tout type de contenu. 'image/*' ne fonctionnera pas.
  2. La dépendance par défaut est 'After'.
  3. Il existe aussi des poids par défaut : pour 'After' le poids est de 16, alors que pour 'interleaved' il est de 256.

Exemples de règles

H2PushPriority application/json 32         # une règle de priorité 'After'
H2PushPriority image/jpeg before           # poid hérité
H2PushPriority text/css   interleaved      # poids de 256 par défaut
top

Directive H2PushResource

Description:Déclare des ressources à proposer ("pusher") au client
Syntaxe:H2PushResource [add] path [critical]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.24 du serveur HTTP Apache.

Lorsqu'il sont activés pour un répertoire, les PUSHes HTTP/2 seront tentés pour tous les chemins ajoutés via cette directive. Cette dernière peut être utilisée plusieurs fois pour le même répertoire.

Cette directive propose des ressources beaucoup plus tôt que les en-têtes Link de mod_headers. mod_http2 présente ces ressources au client via une réponse intermédiaire 103 Early Hints. Ceci implique que les clients qui ne supportent pas PUSH recevront quand-même rapidement des propositions de préchargement.

A la différence de la définition d'en-têtes de réponse Link via mod_headers, cette directive n'aura d'effet que pour les connexions HTTP/2.

En ajoutant l'option critical à une telle ressource, le serveur la traitera prioritairement, et une fois les données disponibles, ces dernières seront envoyées avant les données de la requête principale.

top

Directive H2SerializeHeaders

Description:Active/désactive la sérialisation du traitement des requêtes/réponses
Syntaxe:H2SerializeHeaders on|off
Défaut:H2SerializeHeaders off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2

Cette directive permet de définir si les requêtes HTTP/2 doivent être sérialisées au format HTTP/1.1 pour être traitées par le noyau de httpd, ou si les données binaires reçues doivent être passées directement aux request_recs.

La sérialisation dégrade les performances, mais garantit une meilleure compatibilité ascendante lorsque des filtres ou programmes accroche personnalisés en ont besoin.

Exemple

H2SerializeHeaders on
top

Directive H2StreamMaxMemSize

Description:Quantité maximale de données en sortie mises en tampon par flux.
Syntaxe:H2StreamMaxMemSize bytes
Défaut:H2StreamMaxMemSize 65536
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2

Cette directive permet de définir la quantité maximale de données en sortie mises en tampon mémoire pour un flux actif. Ce tampon mémoire n'est pas alloué pour chaque flux en tant que tel. Les quantités de mémoire sont définies en fonction de cette limite lorsqu'elles sont sur le point d'être allouées. Le flux s'arrête lorsque la limite a été atteinte, et ne reprendra que lorsque les données du tampon auront été transmises au client.

Exemple

H2StreamMaxMemSize 128000
top

Directive H2StreamTimeout

Description:Temps d'attente maximum lors de l'envoi/réception de données pour le traitement d'un flux
Syntaxe:H2StreamTimeout time-interval[s]
Défaut:La valeur de la directive Timeout
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.55 du serveur HTTP Apache.

H2StreamTimeout permet de spécifier le temps maximum pendant lequel un flux en cours de traitement attendra pour l'envoi/réception de ses données.

top

Directive H2TLSCoolDownSecs

Description:Durée d'inactivité d'une connexion TLS avant diminution de la taille des paquets
Syntaxe:H2TLSCoolDownSecs seconds
Défaut:H2TLSCoolDownSecs 1
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.18 du serveur HTTP Apache.

Cette directive permet de spécifier le nombre de secondes avant lequel une connexion TLS inactive va diminuer la taille des paquets de données à une valeur inférieure (~1300 octets). Elle peut être définie au niveau du serveur principal ou pour un <serveur virtuel> spécifique.

Voir la directive H2TLSWarmUpSize pour une description du "préchauffage" de TLS. La directive H2TLSCoolDownSecs met en lumière le fait que les connexions peuvent se détériorer au bout d'un certain temps (et au fur et à mesure des corrections du flux TCP), et cela même si elle sont inactives. Pour ne pas détériorer les performances d'une manière générale, il est par conséquent préférable de revenir à la phase de préchauffage lorsqu'aucune donnée n'a été transmise pendant un certain nombre de secondes.

Dans les situations où les connexions peuvent être considérées comme fiables, ce délai peut être désactivé en définissant cette directive à 0.

Dans l'exemple suivant, la directive est définie à 0, ce qui désactive tout retour à une phase de préchauffage des connexions TLS. Les connexions TLS déjà préchauffées conservent donc toujours leur taille de paquet de données maximale.

Exemple

H2TLSCoolDownSecs 0
top

Directive H2TLSWarmUpSize

Description:Taille des paquets durant la phase initiale de la connexion TLS
Syntaxe:H2TLSWarmUpSize amount
Défaut:H2TLSWarmUpSize 1048576
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.18 du serveur HTTP Apache.

Cette directive permet de définir le nombre d'octets à envoyer dans les petits enregistrements TLS (~1300 octets) avant d'atteindre leur taille maximale de 16 ko pour les connexions https: HTTP/2. Elle peut être définie au niveau du serveur principal ou pour des <Serveurs virtuels> spécifiques.

Les mesures effectuées par les laboratoires de performances de Google montrent que les meilleurs performances sont atteintes pour les connexions TLS si la taille initiale des enregistrements reste en deça du niveau du MTU afin de permettre à la totatlité d'un enregistrement d'entrer dans un paquet IP.

Comme TCP ajuste son contrôle de flux et sa taille de fenêtre, des enregistrements TLS trop longs peuvent rester en file d'attente ou même être perdus et devoir alors être réémis. Ceci est bien entendu vrai pour tous les paquets ; cependant, TLS a besoin de la totalité de l'enregistrement pour pouvoir le déchiffrer. Tout octet manquant rendra impossible l'utilisation de ceux qui ont été reçus.

Lorqu'un nombre suffisant d'octets a été transmis avec succès, la connexion TCP est stable, et la taille maximale (16 ko) des enregistrements TLS peut être utilisée pour des performances optimales.

Dans les architectures où les serveurs sont atteints par des machines locales ou pour les connexions de confiance seulement, la valeur de cette directive peut être définie à 0, ce qui a pour effet de désactiver la "phase de chauffage".

Dans l'exemple suivant, la phase de chauffage est effectivement désactivée en définissant la directive à 0.

Exemple

H2TLSWarmUpSize 0
top

Directive H2Upgrade

Description:Activation/Désactivation du protocole de mise à jour H2
Syntaxe:H2Upgrade on|off
Défaut:H2Upgrade on pour h2c, off pour h2
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_http2

Cette directive permet d'activer/désactiver l'utilisation de la méthode de mise à jour pour passer de HTTP/1.1 à HTTP/2. Elle doit être placée dans une section <VirtualHost> afin d'activer la mise à jour vers HTTP/2 pour le serveur virtuel considéré.

Cette méthode de changement de protocole est définie dans HTTP/1.1 et utilise l'en-tête "Upgrade" (d'où son nom) pour indiquer l'intention d'utiliser un autre protocole. Cet en-tête peut être présent dans toute requête sur une connexion HTTP/1.1.

Elle activée par défaut pour les transmissions en clair (h2c), et désactivée avec TLS (h2), comme préconisé par la RFC 7540.

Sachez cependant que les mises à jour ne sont acceptées que pour les requêtes qui ne possèdent pas de corps. Le requêtes de type POST et PUT avec un contenu ne feront jamais l'objet d'une mise à jour vers HTTP/2. Se référer à la documentation de la directive H2Direct pour envisager une alternative à Upgrade.

Cette directive n'a d'effet que si h2 ou h2c est activé via la directive Protocols.

Exemple

H2Upgrade on
top

Directive H2WebSockets

Description:Active/désactive les WebSockets via HTTP/2
Syntaxe:H2WebSockets on|off
Défaut:H2WebSockets off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache

La directive H2WebSockets permet d'activer ou de désactiver l'amorçage des WebSockets via le protocole HTTP/2. Cette extension du protocole est définie dans la RFC 8441.

Ces requêtes sont similaires à CONNECT, mais elles possèdent l'en-tête supplémentaire ':protocol'. Elles sont transformées au sein du module en leurs équivalents HTTP/1.1 avant d'être soumises au traitement interne.

Cela signifie que les WebSockets HTTP/2 peuvent être utilisés dans le cadre d'une directive ProxyPass avec le paramètre 'upgrade=websocket' sans autres modifications.

Pour les modules tiers qui gèrent les WebSockets directement dans le serveur, l'amorçage du protocole lui-même fonctionnera aussi. Dans le cas de HTTP/2 cependant, le transfert de données nécessite une prise en charge supplémentaire. Le WebSocket négocié sera incapable d'utiliser le socket de connexion du client pour examiner les évènements d'entrée/sortie concernés.

Cette fonctionnalité étant susceptible de briser la compatibilité ascendante pour de tels modules tiers, elle n'est pas activée par défaut.

top

Directive H2WindowSize

Description:Taille maximale des paquets de données pour les transmissions client vers serveur.
Syntaxe:H2WindowSize bytes
Défaut:H2WindowSize 65535
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_http2

Cette directive permet de définir la taille maximale des paquets de données envoyés par le client au serveur, et limite la quantité de données que le serveur doit mettre en tampon. Le client arrêtera d'envoyer des données sur un flux lorsque cette limite sera atteinte jusqu'à ce que le serveur indique qu'il dispose d'un espace suffisant (car il aura traité une partie des données).

Cette limite n'affecte que les corps de requêtes, non les métadonnées comme les en-têtes. Par contre, elle n'affecte pas les corps de réponses car la taille maximale de ces derniers est gérée au niveau des clients.

Exemple

H2WindowSize 128000

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_logio.html.tr.utf80000664000175100017510000002515714743132254021774 0ustar covenercovener mod_logio - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_logio

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:Her isteğin girdi ve çıktı uzunluklarının günlüklenmesi.
Durum:Eklenti
Modül Betimleyici:logio_module
Kaynak Dosyası:mod_logio.c

Özet

Bu modül her istekte alınan ve gönderilen bayt sayısının günlüklenmesini sağlar. Sayılar, istekte ve yanıtta yer alan başlıklar ve gövdeleri hesaba dahil ederek ağ üzerinde gerçekte gidip gelen bayt sayısını gösterir. Bayt sayımı, girdide SSL/TLS öncesinde ve çıktıda SSL/TLS sonrasında yapılır, böylece sayıların, şifrelemeyle herhangi bir değişikliği doğru olarak yansıtması sağlanmış olur.

Bu modül mod_log_config modülünü gerektirir.

SSL ile KeepAlive bağlantılar kullanıldığında, SSL uzlaşımının ek yükü, bağlantı üzerinden yapılan ilk isteğin bayt sayısını yansıtır. Her dizin için yeniden uzlaşım gerektiği takdirde bayt sayısı yeniden uzlaşımı tetikleyen istekle ilişkilendirilir.
Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Özel Günlük Biçemleri

İsteğin belirgin özellikleri için, biçem dizgesinde yer alan % imli biçem belirteçlerinin yerine günlük dosyasında değerleri yazılır. Bu modül üç yeni biçem belirteci ekler:

Biçem Belirteci Açıklama
%I İstek gövdesi ve başlıklar dahil alınan bayt sayısı; sıfır olamaz.
%O Başlıklar dahil gönderilen bayt sayısı; sıfır olamaz.
%S Aktarılan bayt sayısı (alınan ve gönderilen), istekler ve başlıklar dahil; sıfır olamaz. %I ve %O'nun birleşimidir.
Apache 2.4.7 ve sonrasında kullanılabilmektedir.
%^FB İstek gelip yanıt başlıklarının ilk baytı yazılana kadar mikrosaniye cinsinden geçen zaman. Sadece LogIOTrackTTFB yönergesine ON atanmışsa kullanılabilir.
Apache 2.4.13 ve sonrasında kullanılabilir.

Genel olarak, işlevsellik şöyle kullanılır:

Birleşik G/Ç günlükleme biçemi:
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %I %O"
top

LogIOTrackTTFB Yönergesi

Açıklama:İlk baytın yazılmasına kadar geçen süreyi izler
Sözdizimi:LogIOTrackTTFB ON|OFF
Öntanımlı:LogIOTrackTTFB OFF
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:All
Durum:Eklenti
Modül:mod_logio
Uyumluluk:Apache 2.4.13 ve sonrasında kullanılabilir

Bu yönerge isteğin okunmasından yanıt başlığının ilk baytının yazılmasına kadar geçen sürenin izlenmesini yapılandırır. Sonuçlanan değeri %^FB biçemi ile günlüğe kaydettirebilirsiniz.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_mime.html.ja.utf80000664000175100017510000021511614743132254021553 0ustar covenercovener mod_mime - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_mime

翻訳済み言語:  en  |  fr  |  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' コマンドを実行する (最終更新日を更新する) 必要があるかもしれません。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

複数の拡張子のあるファイル

ファイルは複数の拡張子を持つことができ、拡張子の順番は通常は関係ありません。例えば、ファイル welcome.html.fr がコンテントタイプは text/html に、言語はフランス語にマップされる場合、welcome.fr.html もまったく同じ情報にマップされます。 同じメタ情報にマップされる拡張子が複数あるときには、言語と コンテントエンコーディングを除いて、 右側にあるものが使用されます。たとえば、.gifMIME タイプ image/gif にマップされ、.html が MIME タイプ text/html にマップされる場合は、ファイル welcome.gif.html は MIME タイプ text/html に関連付けられます。

リソースに複数の言語やエンコーディングを関連付けること ができるため、 言語コンテントエンコーディングは前のものに追加されていきます。 たとえば、ファイル welcome.html.en.deContent-Language: en, deContent-Type: text/html として送信されます。

複数の拡張子のあるファイルが MIME タイプとハンドラの両方に関連付けられているときは注意する必要があります。 その場合、普通はリクエストがハンドラに関連付けられた モジュールによって扱われることになります。たとえば、拡張子 .imap が (mod_imagemap の) imap-file にマップされていて、.html が MIME タイプ text/html にマップされているときは、ファイル world.imap.htmlimap-file ハンドラと text/html MIME タイプに関連付けられます。ファイルが処理されるときは imap-file ハンドラが使用されますので、そのファイルは mod_imagemap のイメージマップファイルとして扱われることになります。

ファイル名のドット区切りでの最後の部分を使って、 特定の部分のメタデータにマッピングしたい場合は、 Add* ディレクティブは使わないでください。 たとえば foo.html.cgi を CGI スクリプトとして処理したいけれども、 bar.cgi.html は CGI スクリプトとしては処理したくない場合、 AddHandler cgi-script .cgi とする代わりに 次のようにしてください

Configure handler based on final extension only

<FilesMatch \.cgi$> SetHandler cgi-script </FilesMatch>

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は大文字小文字を区別せず、 最初のドットはあってもなくても構いません。 ファイル名は複数の拡張子を持つことができ、 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-zipx-compress が返ってくることを期待しますが、標準規格ではそれぞれ gzipcompress と等価であることになっています。Apache は、コンテントエンコーディングの比較をするときには、先頭にある x- を無視します。Apache がエンコーディング付きで応答を返すときは、クライアントが要求した形式 (すなわちx-foofoo) を使用します。要するに、この二つのエンコーディングの場合は常に x-gzipx-compress を使うべきである、ということです。deflate のようなより新しいエンコーディングでは、x- なしで指定してください。

引数 extension は大文字小文字を区別せず、 最初のドットはあってもなくても構いません。 ファイル名は複数の拡張子を持つことができ、 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 は大文字小文字を区別せず、 最初のドットはあってもなくても構いません。 ファイル名は複数の拡張子を持つことができ、 extensionはそれぞれと比較されます。

参照

top

AddInputFilter ディレクティブ

説明:ファイルの拡張子をクライアントのリクエストを処理する フィルタにマップする
構文:AddInputFilter filter[;filter...] extension [extension] ...
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:
モジュール:mod_mime
互換性:2.0.26 以降で使用可能

AddInputFilter はファイルの拡張子 extension をクライアントのリクエストや POST がサーバに来たときに 処理をするフィルタにマップします。 これは、SetInputFilter ディレクティブも 含め、他の場所で定義されているフィルタに加えられます。 このマッピングはすでにあるものより優先されてマージされ、 同じ extension に対する既存のマッピングを上書きします。

複数のfilterを指定するときは、データを処理する順番にセミコロンで 繋いで書く必要があります。filter は大文字小文字を区別しません。

引数 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 は大文字小文字を区別せず、 最初のドットはあってもなくても構いません。 ファイル名は複数の拡張子を持つことができ、 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 は大文字小文字を区別せず、 最初のドットはあってもなくても構いません。 ファイル名は複数の拡張子を持つことができ、 extensionはそれぞれと比較されます。

参照

top

AddType ディレクティブ

説明:ファイル名の拡張子を指定されたコンテントタイプにマップ
構文:AddType MIME-type extension [extension] ...
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:
モジュール:mod_mime

AddType ディレクティブは、 与えられた拡張子を指定されたコンテントタイプにマップします。 MIME-type は拡張子 extension を含んだドキュメントに使用する MIME タイプです。 この新しいマッピングは既にあるマッピングに追加され、同じ拡張子 extension のためのマッピングを上書きします。 このディレクティブは MIME タイプファイル (TypesConfig ディレクティブを参照) に無いマッピングを追加するために使用することができます。

AddType image/gif .gif

あるいは、ひとつのディレクティブで複数のファイル拡張子を指定する場合:

Example

AddType image/jpeg jpeg jpg jpe

新しい MIME タイプは、TypesConfig ファイルを変更するのではなく、AddType ディレクティブを使って追加することが推奨されています。

引数 extension は大文字小文字を区別せず、 最初のドットはあってもなくても構いません。 ファイル名は複数の拡張子を持つことができ、 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 は存在しない) ModMimeUsePathInfoOn であるとして、 /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.frindex.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 はエンコードされていないプレーンテキストの ファイルであるということを指定します。

注意

RemoveEncodingAddEncoding ディレクティブので処理されますので、 同じディレクトリの設定中に両方が現れると、 後者の効果が打ち消される可能性があります。

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 タイプ 設定ファイルの位置を設定します。file-pathServerRoot からの相対パスです。 このファイルはファイルの拡張子からコンテントタイプへの デフォルトのマッピングを設定します。 ほとんどの管理者は、よく使われるファイル名の拡張子を IANA に登録されたコンテントタイプに関連付けている、 Apache の mime.types ファイルを使います。 現在の一覧は http://www.iana.org/assignments/media-types/index.html で管理されています。これは、主要なメディアタイプの定義を提供して、 必要ところを AddType で 上書きする、という方法で httpd.conf を簡略にします。 mime.types はサーバをアップグレードしたときに 置き換えられるかもしれないので、そのファイルを直接 編集しないでください。

ファイルは、AddType ディレクティブの引数と同じ形式の行で構成されます。

MIME-type [extension] ...

拡張子の大文字小文字は区別されません。空行やハッシュ (`#') で始まる行は無視されます。

(1) IANA に既に登録されている、あるいは (2) 広く受け入れられていてプラットホーム間でファイル拡張子に衝突がない、 という場合でなければ、配布中の mime.types ファイルに新たなものを登録するように Apache HTTP Server Project にリクエストしないでください。 category/x-subtype のリクエストは自動的に却下されますし、 言語や文字セットの名前空間で既に使用されていて、衝突の可能性のある 2 文字の拡張子も却下されます。

参照

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy.html.ja.utf80000664000175100017510000027024714743132254022013 0ustar covenercovener mod_proxy - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_proxy

翻訳済み言語:  en  |  fr  |  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_sslSSLProxy* ディレクティブで 提供されています。これらの機能を利用するためには、該当するモジュールを 組み込んで設定しなければなりません。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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

遅い起動

ProxyBlock ディレクティブを使っている場合、 後のテストのために起動時にホストの IP アドレスが調べられてキャッシュされます。ホスト名のルックアップの 速さによっては、数秒 (かそれ以上) かかるかもしれません。

top

イントラネットプロキシ

イントラネットにある Apache プロキシサーバは外部へのリクエストを 会社のファイアウォールを通して送らなければなりません。(このためには 個々の scheme についてそれぞれ、ファイアウォールの プロキシにフォワードされるように ProxyRemote ディレクティブを 設定してください)。しかしイントラネット内のリソースにアクセスするときは、 ファイアウォールを通さないでもアクセスできます。 どのホストがイントラネットに属し、直接アクセスすべきかを指定するには、 NoProxy ディレクティブが 役に立ちます。

イントラネット内のユーザは WWW のリクエストでローカルドメインを 省略することがよくあります。http://somehost.example.com/ というリクエストの代わりに "http://somehost/" をリクエストしたりします。 このようなリクエストを受け付け、サーバに設定されているローカルドメインが 暗黙のうちに使われていると解釈して、単純にリクエストを処理するものも 商用プロキシサーバの中にはあります。 サーバが プロキシのサービス用に設定されていて ProxyDomain ディレクティブが 使用された場合には、Apache はクライアントにリダイレクト応答を送って、 正しい、完全な ((訳注: fully qualified)) サーバのアドレスに送ることができます。このように リダイレクトすると、ユーザのブックマークが正しい完全なホスト名を含む ことにもなるため、より好ましい方法と言えるでしょう。

top

プロトコルの調整

Keepalive や HTTP/1.1 を適切に実装していないアプリケーションサーバに対して mod_proxy がリクエストを送信する場合、 HTTP/1.0 を使って keepalive を無しにしてリクエストを送るようにする 環境変数が二つあります。これらは SetEnv ディレクティブで設定します。

force-proxy-request-1.0proxy-nokeepalive がその環境変数です。

<Location /buggyappserver/>
ProxyPass http://buggyappserver:7001/foo/
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
</Location>

top

リクエストボディ

POST メソッドなどのリクエストには、リクエストボディがあります。 HTTP プロトコル仕様によると、ボディのあるリクエストは chunked 転送を使うか、Content-Length ヘッダを送信しなければなりません。 このようなリクエストをオリジンサーバに送信する場合、 mod_proxy_http は常に Content-Length を送ろうと試みます。しかし。ボディが大きく、オリジナルのリクエストで chunked 転送が使われている場合、上流へのリクエストに chunked 転送も使われます。 この挙動は 環境変数で制御できます。 proxy-sendcl を設定すると、可能な限り常に Content-Length を付与して、 上流サーバに送信するようになります。 逆に proxy-sendchunked を設定すると、リソース消費を抑え、 chnked エンコードを使って送信するようになります。

top

BalancerGrowth ディレクティブ

説明:Number of additional Balancers that can be added Post-configuration
構文:BalancerGrowth #
デフォルト:BalancerGrowth 5
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_proxy
互換性:BalancerGrowth is only available in Apache HTTP Server 2.3.13 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

BalancerInherit ディレクティブ

説明:Inherit ProxyPassed Balancers/Workers from the main server
構文:BalancerInherit On|Off
デフォルト:BalancerInherit On
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_proxy
互換性:BalancerInherit is only available in Apache HTTP Server 2.4.5 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

BalancerMember ディレクティブ

説明:Add a member to a load balancing group
構文:
コンテキスト:ディレクトリ
ステータス:Extension
モジュール:mod_proxy

Documentation not yet translated. Please see English version of document.

top

BalancerPersist ディレクティブ

説明:Attempt to persist changes made by the Balancer Manager across restarts.
構文:BalancerPersist On|Off
デフォルト:BalancerPersist Off
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_proxy
互換性:BalancerPersist is only available in Apache HTTP Server 2.4.4 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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.

DomainHostname と区別するために (意味的にも構文的にも。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 ビット有効な SubNetIPAddr と同等で、 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.comwww.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.comfoo ディレクトリの すべてのファイルに対して、プロキシサーバを通して送られたときには INCLUDES フィルタを通して送るように設定します:

<Proxy http://example.com/foo/*>
SetOutputFilter INCLUDES
</Proxy>

top

Proxy100Continue ディレクティブ

説明:Forward 100-continue expectation to the origin server
構文:Proxy100Continue Off|On
デフォルト:Proxy100Continue On
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Extension
モジュール:mod_proxy
互換性:Available in version 2.4.40 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

ProxyAddHeaders ディレクティブ

説明:Add proxy information in X-Forwarded-* headers
構文:ProxyAddHeaders Off|On
デフォルト:ProxyAddHeaders On
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Extension
モジュール:mod_proxy
互換性:Available in version 2.3.10 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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

パラメータ デフォルト値 説明
min 0 バックエンドサーバとの接続で 常に開いているコネクション数の最小値
max 1...n バックエンドサーバとの接続数の Hard Maximum (訳注: ハードリミット)。 デフォルト値は、使用している MPM のプロセスあたりのスレッド数になっています。 Prefork MPM では常に 1 で、Worker MPM では ThreadsPerChild で調節できます。Hard Maximum 以上にバックエンドサーバとのコネクションを 生成することはありません。
smax max 接続数の Soft Maximum (訳注: ソフトリミット)まで、 コネクションは必要に応じて生成されます。 smax を超えた数のコネクションは生存時間 ttl で切断されます。
ttl - smax 数を超えた非活動状態のコネクションの生存時間を、 秒で指定します。この期間内に使用されなかったコネクションは、 全て閉じられます。
timeout Timeout コネクションタイムアウトを秒で指定します。特に指定されなければ、 フリーなコネクションを取得できるまで待ちます。このディレクティブは max パラメータと合わせて使うことで、バックエンドサーバとの 接続数を制御するのに使います。
acquire - 設定すると、コネクションプールからフリーのコネクションを取得するために 待機する待ち時間の最大値になります。フリーのコネクションがプールになかった場合は、 SERVER_BUSY ステータスがクライアントに返されます。
keepalive Off バックエンドサーバと Apache の間にファイアーウォールがある場合には、 このパラメータを使ってください。ファイアウォールは往々にして、 非活動状態のコネクションを落とそうとします。 このフラグは OS に指示して、KEEP_ALIVE メッセージを非活動状態の コネクションでも送るようにします (間隔は OS のグローバル設定に依存し、 通常は 120ms 間隔) 。これによってファイアウォールによってコネクションが 落とされることを防げます。keepalive を有効にするには、このプロパティを On にしてください。
retry 60 コネクションをプーリングするための、リトライのタイムアウトを秒で 指定します。バックエンドサーバへのコネクションプーリングが失敗した場合は、 タイムアウトの期間が過ぎるまで、そのサーバにリクエストをフォワードしません。 この機能を使うと、バックエンドサーバをメンテナンスのためにシャットダウンし、 後でオンラインに復帰させるといったことができます。
loadfactor 1 ワーカーあたりの負荷係数です。BalancerMember で使います。 1 から 100 までの数字でそのワーカーに対する正規化された負荷率を指定します。
route - ロードバランサで使った場合、ワーカーのルーティングをします。 ルートはセッション ID に付加された値になります。
redirect - ワーカーのリダイレクション経路です。この値は通常は、 安全にクラスタからノードを取り去る設定を動的に入れるために使います。 セッション ID の無いリクエスト全てを指定した場合は、 この値と同じルーティングパラメータを持つ BalancerMember にリダイレクトされます。

Proxy ディレクティブのスキームが balancer:// になっている場合は、 バックエンドサーバと実際には通信しない仮想ワーカーが生成されます。 このワーカーは幾つかの "本物の" ワーカーの管理をつかさどります。 この場合パラメータは、この仮想ワーカーに対して設定されます。

パラメータ デフォルト値 説明
lbmethod - Balancer のロードバランス方法。使用するロードバランスの スケジューリング方法を選びます。処理したリクエストの数で重み付けする byrequests か、転送量のバイト数で重み付けする bytraffic を設定できます。デフォルトは byrequests です。
stickysession - バランサーのスティッキーセッション名です。通常はこの値は JSESSIONIDPHPSESSIONID といったものになりますが、この値は バックエンドアプリケーションのサポートするセッションに依存します。
nofailover Off On になっていると、ワーカーがエラーを起こしたり 無効になっている場合にセッションが切れます。 バックエンドサーバがセッションレプリケーションをサポートしていない場合は、 On にしてください。
timeout 0 バランサーのタイムアウトを秒で指定します。 この値を設定すると、フリーのワーカーを取得するまでの最大待機時間になります。 デフォルトでは待機しません。
maxattempts 1 フェイルオーバーを試みる最大の回数を指定します。

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

ProxyPassInherit ディレクティブ

説明:Inherit ProxyPass directives defined from the main server
構文:ProxyPassInherit On|Off
デフォルト:ProxyPassInherit On
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_proxy
互換性:ProxyPassInherit is only available in Apache HTTP Server 2.4.5 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

ProxyPassInterpolateEnv ディレクティブ

説明:Enable Environment Variable interpolation in Reverse Proxy configurations
構文:
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Extension
モジュール:mod_proxy

Documentation not yet translated. Please see English version of document.

top

ProxyPassMatch ディレクティブ

説明:Maps remote servers into the local server URL-space using regular expressions
構文:
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Extension
モジュール:mod_proxy

Documentation not yet translated. Please see English version of document.

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/barhttp://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_httpmod_proxy_ftp が サーバに組み込まれていなければなりません。

警告

サーバを安全にするまで ProxyRequests は有効にしないでください。 オープンプロキシサーバはあなた自身のネットワークにとっても、 インターネット全体にとっても危険です。

top

ProxySet ディレクティブ

説明:Set various Proxy balancer or member parameters
構文:
コンテキスト:ディレクトリ
ステータス:Extension
モジュール:mod_proxy

Documentation not yet translated. Please see English version of document.

top

ProxySourceAddress ディレクティブ

説明:Set local IP address for outgoing proxy connections
構文:ProxySourceAddress address
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_proxy
互換性:Available in version 2.3.9 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

ProxyStatus ディレクティブ

説明:Show Proxy LoadBalancer status in mod_status
構文:
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_proxy

Documentation not yet translated. Please see English version of document.

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 節を読んでください。

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/quickreference.html.fr.utf80000664000175100017510000063440115021032132022757 0ustar covenercovener Document de référence rapide des directives - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Document de référence rapide des directives

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Le document de référence rapide des directives montre l'usage, les valeurs par défaut, le statut, et le contexte de chaque directive de configuration d'Apache. Pour plus d'informations sur chacun de ces termes, voir le Dictionnaire des directives.

La première colonne donne le nom de la directive et son usage. Si la directive possède une valeur par défaut, elle est indiquée dans la deuxième colonne. Si la valeur par défaut est trop grande pour pouvoir être affichée, elle sera tronquée et suivie d'un "+".

La troisième colonne énumère les contextes dans lesquels la directive est applicable, et la quatrième indique son statut en accord avec le tableau des légendes ci-dessous.

 A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  Q  |  R  |  S  |  T  |  U  |  V  |  W  |  X 
sconfiguration globale
vserveur virtuel
drépertoire
h.htaccess
psection proxy
CNoyau httpd
MMPM
BBase
EExtension
XExpérimental
TExterne
AcceptFilter protocole filtre d'acceptationsC
Permet d'optimiser la configuration d'une socket pour l'écoute d'un protocole
AcceptPathInfo On|Off|Default Default svdhC
Les ressources acceptent des informations sous forme d'un nom de chemin en fin de requête.
AccessFileName nom-du-fichier [nom-du-fichier] ... .htaccess svC
Nom du fichier de configuration distribué
Action type d'action script cgi [virtual]svdhB
Active un script CGI pour un gestionnaire ou un type de contenu particulier
AddAlt texte fichier [fichier] ...svdhB
Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son nom
AddAltByEncoding texte codage MIME [codage MIME] ...svdhB
Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son codage MIME
AddAltByType texte type MIME [type MIME] ...svdhB
Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son type MIME
AddCharset jeu-car extension [extension] ...svdhB
Associe les extensions de noms de fichiers spécifiées au jeu de caractères spécifié
AddDefaultCharset On|Off|jeu de caractères Off svdhC
Paramètre jeu de caractères par défaut à ajouter quand le type de contenu d'une réponse est text/plain ou text/html
AddDescription texte [fichier] ...svdhB
Afficher la description d'un fichier
AddEncoding codage extension [extension] ...svdhB
Associe les extensions de noms de fichiers données au type de codage spécifié
AddHandler nom-gestionnaire extension [extension] ...svdhB
Associe les extensions de noms de fichiers données au gestionnaire spécifié
AddIcon icône nom [nom] ...svdhB
Icône à afficher pour un fichier en fonction de son nom
AddIconByEncoding icône codage MIME [codage MIME] ...svdhB
Icône à afficher à côté d'un fichier en fonction de son codage MIME
AddIconByType icône type MIME [type MIME] ...svdhB
Icône à afficher à côté d'un fichier en fonction de son type MIME
AddInputFilter filtre[;filtre...] extension [extension] ...svdhB
Associe les extensions de noms de fichiers aux filtres spécifiés qui traiteront les requêtes clients
AddLanguage symbole-langue extension [extension] ...svdhB
Associe l'extension de nom de fichier donnée à la langue spécifié
AddModuleInfo nom-module chaînesvE
Ajoute des données supplémentaires aux informations de module affichées par le gestionnaire server-info
AddOutputFilter filtre[;filtre...] extension [extension] ...svdhB
Associe les extensions de noms de fichiers aux filtres spécifiés qui traiteront les réponses en provenance du serveur
AddOutputFilterByType filtre[;filtre...] type_de_média [type_de_média] ...svdhB
assigne un filtre en sortie pour un type de média particulier
AddType type-médium extension [extension] ...svdhB
Associe les extensions de noms de fichiers au type de contenu spécifié
Alias [chemin URL] chemin fichier|chemin répertoiresvB
Met en correspondance des URLs avec des chemins du système de fichiers
AliasMatch regex chemin fichier|chemin répertoiresvB
Met en correspondance des URLs avec le système de fichiers en faisant intervenir les expressions rationnelles
AliasPreservePath OFF|ON OFF svdB
Associer le chemin entier à l'alias dans une section location.
Allow from all|hôte|env=[!]variable d'environnement [hôte|env=[!]variable d'environnement] ...dhE
Spécifie quels hôtes peuvent accéder à une certaine zone du serveur
AllowCONNECT port[-port] [port[-port]] ... 443 563 svE
Ports autorisés à se CONNECTer à travers le mandataire
AllowEncodedSlashes On|Off|NoDecode Off svC
Détermine si les séparateurs de chemin encodés sont autorisés à transiter dans les URLs tels quels
AllowMethods reset|HTTP-method [HTTP-method]... reset dX
Restreint l'accès aux méthodes HTTP spécifiées
AllowOverride All|None|type directive [type directive] ... None à partir de la +dC
Types de directives autorisées dans les fichiers .htaccess
AllowOverrideList None|directive [directive-type] ... None dC
Directives autorisées dans les fichiers .htaccess
Anonymous utilisateur [utilisateur] ...dhE
Définit la liste des identifiants utilisateur autorisés à accéder sans vérification du mot de passe
Anonymous_LogEmail On|Off On dhE
Détermine si le mot de passe fourni sera enregistré dans le journal des erreurs
Anonymous_MustGiveEmail On|Off On dhE
Détermine si l'abscence de mot de passe est autorisée
Anonymous_NoUserID On|Off Off dhE
Détermine si le champ identifiant peut être vide
Anonymous_VerifyEmail On|Off Off dhE
Détermine s'il faut vérifier que le format de l'adresse email fournie comme mot de passe est correct
AsyncRequestWorkerFactor facteursM
Limite le nombre de connexions simultanées par thread
AuthBasicAuthoritative On|Off On dhB
Définit si les processus d'autorisation et d'authentification peuvent être confiés à des modules de plus bas niveau
AuthBasicFake off|username [password]dhB
Authentification de base simulée à l'aide des nom d'utilisateur et mot de passe fournis
AuthBasicProvider nom fournisseur [nom fournisseur] ... file dhB
Définit le(les) fournisseur(s) d'authentification pour cette zone du site web
AuthBasicUseDigestAlgorithm MD5|Off Off dhB
Vérifie les mots de passe auprès des fournisseurs d'authentification à la manière de l'authentification de type Digest.
AuthDBDUserPWQuery requêtedE
Requête SQL servant à vérifier le mot de passe d'un utilisateur
AuthDBDUserRealmQuery requêtedE
Requête SQL servant à vérifier une empreinte de mot de passe pour un utilisateur et un identifiant d'authentification.
AuthDBMGroupFile chemin-fichierdhE
Définit le nom du fichier de base de données contenant la liste des groupes d'utilisateurs permettant de définir les autorisations des utilisateurs
AuthDBMType default|SDBM|GDBM|NDBM|DB default dhE
Définit le type de fichier de base de données utilisé pour stocker les mots de passe
AuthDBMUserFile chemin-fichierdhE
Définit le nom d'un fichier de base de données pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe
AuthDigestAlgorithm MD5|MD5-sess MD5 dhE
Sélectionne l'algorithme utilisé pour calculer les condensés du défit et de sa réponse
AuthDigestDomain URI [URI] ...dhE
Les URIs qui se trouvent dans le même espace de protection concernant l'authentification à base de condensés
AuthDigestNonceLifetime secondes 300 dhE
Durée de validité du nombre à valeur unique du serveur (nonce)
AuthDigestProvider nom fournisseur [nom fournisseur] ... file dhE
Définit le(s) fournisseurs(s) d'authentification pour la zone du site web concernée
AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhE
Détermine le niveau de protection fourni par l'authentification à base de condensé
AuthDigestShmemSize taille 1000 sE
La quantité de mémoire partagée à allouer afin de conserver les informations à propos des clients
AuthFormAuthoritative On|Off On dhB
Détermine si l'autorisation et l'authentification sont confiés à des modules de plus bas niveau
AuthFormBody nom du champ httpd_body dB
Le nom du champ de formulaire contenant le corps de la requête à effectuer en cas de connexion réussie
AuthFormDisableNoStore On|Off Off dB
Désactive l'en-tête CacheControl no-store sur la page de connexion
AuthFormFakeBasicAuth On|Off Off dB
Simule une en-tête d'authentification de base
AuthFormLocation nom du champ httpd_location dB
Le nom du champ de formulaire qui contiendra l'URL vers laquelle l'utilisateur sera redirigé en cas de connexion réussie
AuthFormLoginRequiredLocation urldB
L'URL de la page vers laquelle on doit être redirigé si une authentification est requise
AuthFormLoginSuccessLocation urldB
L'URL de la page vers laquelle on doit être redirigé en cas de connexion réussie
AuthFormLogoutLocation uridB
L'URL vers laquelle un utilisateur devra être redirigé après s'être déconnecté
AuthFormMethod nom du champ httpd_method dB
Le nom du champ de formulaire contenant la méthode de la requête à effectuer en cas de connexion réussie
AuthFormMimetype nom du champ httpd_mimetype dB
Le nom du champ de formulaire contenant le type MIME du corps de la requête à effectuer en cas de connexion réussie
AuthFormPassword nom du champ httpd_password dB
Le nom du champ de formulaire qui contient le mot de passe de connexion
AuthFormProvider nom fournisseur [nom fournisseur] ... file dhB
Définit le(s) fournisseur(s) d'authentification pour la zone concernée
AuthFormSitePassphrase secretdB
Court-circuite l'authentification pour les sites à fort trafic
AuthFormSize taille 8192 dB
La taille maximale en octets du formulaire dont seront extraites les informations de connexion
AuthFormUsername nom du champ httpd_username dB
Le nom du champ de formulaire qui contient le nom de connexion
AuthGroupFile chemin-fichierdhB
Définit le nom d'un fichier texte contenant la liste des groupes d'utilisateurs permettant de définir les autorisations des utilisateurs
AuthLDAPAuthorizePrefix préfixe AUTHORIZE_ dhE
Spécifie le préfixe ajouté aux variables d'environnement durant la phase d'autorisation
AuthLDAPBindAuthoritative off|on on dhE
Détermine si l'on doit utiliser d'autres fournisseurs d'authentification lorsque le serveur ne peut pas valider les données d'authentification de l'utilisateur, alors que ce dernier possède un DN.
AuthLDAPBindDN dndhE
Un DN optionnel pour se connecter au serveur LDAP
AuthLDAPBindPassword mot-de-passedhE
Mot de passe à utiliser en conjonction avec le DN de connexion
AuthLDAPCharsetConfig chemin-fichiersE
Chemin du fichier de configuration de la correspondance langage/jeu de caractères
AuthLDAPCompareAsUser on|off off dhE
Utilisation des données d'authentification de l'utilisateur pour effectuer les comparaisons pour l'attribution des autorisations
AuthLDAPCompareDNOnServer on|off on dhE
Utilise le serveur LDAP pour comparer les DNs
AuthLDAPDereferenceAliases never|searching|finding|always always dhE
À quel moment le module va déréférencer les alias
AuthLDAPGroupAttribute attribut member uniqueMember +dhE
L'attribut LDAP utilisé pour vérifier l'appartenance d'un utilisateur à un groupe.
AuthLDAPGroupAttributeIsDN on|off on dhE
Utilise le DN de l'utilisateur pour vérifier son appartenance à un groupe
AuthLDAPInitialBindAsUser off|on off dhE
Détermine si le serveur effectue la recherche initiale du DN en utilisant le nom propre de l'utilisateur pour l'authentification de base et non de manière anonyme, ou en utilisant des données d'authentification codées en dur pour le serveur
AuthLDAPInitialBindPattern regex substitution (.*) $1 (nom de l'u +dhE
Spécifie la modification a apporter au nom d'utilisateur pour l'authentification de base lors de l'authentification auprès du serveur LDAP pour effectuer une recherche de DN
AuthLDAPMaxSubGroupDepth Nombre 10 dhE
Spécifie la profondeur d'imbrication des sous-groupes maximale prise en compte avant l'abandon de la recherche de l'utilisateur.
AuthLDAPRemoteUserAttribute uiddhE
Spécifie l'attribut dont la valeur renvoyée au cours de la requête de l'utilisateur sera utilisée pour définir la variable d'environnement REMOTE_USER
AuthLDAPRemoteUserIsDN on|off off dhE
Utilise le DN de l'utilisateur pour définir la variable d'environnement REMOTE_USER
AuthLDAPSearchAsUser on|off off dhE
Utilise les données d'authentification de l'utilisateur pour la recherche des autorisations
AuthLDAPSubGroupAttribute attributdhE
Spécifie les noms d'attribut, un par directive, utilisés pour différencier les membres du groupe courant qui sont eux-mêmes des groupes.
AuthLDAPSubGroupClass ObjectClass-LDAP groupOfNames groupO +dhE
Spécifie quelles valeurs d'objectClass LDAP identifient les objets de l'annuaire qui sont des groupes au cours du traitement des sous-groupes.
AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]dhE
URL specifying the LDAP search parameters
AuthMerging Off | And | Or Off dhB
Définit la manière dont chaque logique d'autorisation des sections de configuration se combine avec celles des sections de configuration précédentes.
AuthName domaine d'autorisationdhB
L'identifiant de l'autorisation à utiliser avec l'authentification HTTP
AuthnCacheContext directory|server|custom-string directory dB
Spécifie une chaîne de contexte à utiliser dans la clé du cache
AuthnCacheEnablesB
Active la mise en cache de l'authentification en tout endroit
AuthnCacheProvideFor fournisseur-authn [...]dhB
Spécifie le fournisseur pour lequel on veut effectuer une mise en cache
AuthnCacheSOCache nom-fournisseur[:arguments-fournisseur]sB
Sélectionne le fournisseur socache d'arrière-plan à utiliser
AuthnCacheTimeout durée-de-vie (secondes) 300 (5 minutes) dhB
Définit une durée de vie pour les entrées du cache
<AuthnProviderAlias alias-fournisseur> ... </AuthnProviderAlias>sB
Regroupe un ensemble de directives qui constituent une extension d'un fournisseur d'authentification de base et lui attribue l'alias spécifié
AuthnzFcgiCheckAuthnProvider provider-name|None option ...dE
Permet à une application FastCGI de gérer l'accroche d'authentification check_authn.
AuthnzFcgiDefineProvider type provider-name backend-addresssE
Définit une application FastCGI en tant que fournisseur d'authentification et/ou autorisation
AuthType None|Basic|Digest|FormdhB
Type d'authentification utilisateur
AuthUserFile chemin-fichierdhB
Définit le nom d'un fichier texte pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe
AuthzDBDLoginToReferer On|Off Off dE
Définit si le client doit être redirigé vers la page d'origine en cas de connexion ou de déconnexion réussie si un en-tête de requête Referer est présent
AuthzDBDQuery requêtedE
Définit la requête SQL pour l'opération requise
AuthzDBDRedirectQuery requêtedE
Définit une requête pour rechercher une page vers laquelle rediriger l'utilisateur après une connexion réussie
AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
Définit le type de fichier de base de données contenant la liste des groupes d'utilisateurs
<AuthzProviderAlias fournisseur-de-base Alias Paramètres-Require> ... </AuthzProviderAlias> sB
Regroupe des directives représentant une extension d'un fournisseur d'autorisation de base qui pourra être référencée à l'aide de l'alias spécifié
AuthzSendForbiddenOnFailure On|Off Off dhB
Envoie '403 FORBIDDEN' au lieu de '401 UNAUTHORIZED' si l'authentification réussit et si l'autorisation a été refusée.
BalancerGrowth # 5 svE
Nombre de membres supplémentaires pouvant être ajoutés après la configuration initiale
BalancerInherit On|Off On svE
Héritage des membres du groupes de répartition de charge du mandataire définis au niveau du serveur principal
BalancerMember [balancerurl] url [clé=valeur [clé=valeur ...]]dE
Ajoute un membre à un groupe de répartition de charge
BalancerPersist On|Off Off svE
Tente de conserver les changements effectués par le gestionnaire de répartition de charge après un redémarrage du serveur.
BrotliAlterETag AddSuffix|NoChange|Remove AddSuffix svE
Comment l'en-tête de réponse ETag doit être modifié au cours de la compression
BrotliCompressionMaxInputBlock valuesvE
Taille maximale du bloc de données en entrée
BrotliCompressionQuality value 5 svE
Qualité de la compression
BrotliCompressionWindow value 18 svE
Taille de la fenêtre de compression glissante brotli
BrotliFilterNote [type] notenamesvE
Enregistre le taux de compression dans une note à des fins de journalisation
BrowserMatch regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...svdhB
Définit des variables d'environnement en fonction du contenu de l'en-tête HTTP User-Agent
BrowserMatchNoCase regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...svdhB
Définit des variables d'environnement en fonction du contenu de l'en-tête HTTP User-Agent sans tenir compte de la casse
BufferedLogs On|Off Off sB
Enregistre les entrées du journal dans un tampon en mémoire avant de les écrire sur disque
BufferSize entier 131072 svdhE
Taille maximale en octets du filtre par tampon
CacheDefaultExpire secondes 3600 (une heure) svdhE
La durée par défaut de mise en cache d'un document lorsqu'aucune date d'expiration n'a été spécifiée.
CacheDetailHeader on|off off svdhE
Ajoute un en-tête X-Cache-Detail à la réponse.
CacheDirLength longueur 2 svE
Le nombre de caractères des noms des sous-répertoires
CacheDirLevels niveaux 2 svE
Le nombre de niveaux de sous-répertoires que comportera le cache.
CacheDisable chaîne-url | onsvdhE
Désactive la mise en cache des URLs spécifiées
CacheEnable type de cache [chaîne URL]svdE
Active la mise en cache des URLs spécifiées en utilisant le gestionnaire de stockage précisé
CacheFile chemin fichier [chemin fichier] ...sX
Met en cache une liste de gestionnaires de fichiers au démarrage
CacheHeader on|off off svdhE
Ajoute un en-tête X-Cache à la réponse.
CacheIgnoreCacheControl On|Off Off svE
Ignore les en-têtes de requête enjoignant de ne pas servir le contenu au client depuis le cache
CacheIgnoreHeaders en-tête [en-tête] ... None svE
Ne pas stocker le(s) en-tête(s) spécifié(s) dans le cache.
CacheIgnoreNoLastMod On|Off Off svdhE
Ignore le fait qu'une réponse ne possède pas d'en-tête Last Modified.
CacheIgnoreQueryString On|Off Off svE
Ignore la chaîne de paramètres lors de la mise en cache
CacheIgnoreURLSessionIdentifiers identifiant [identifiant] ... None svE
Ignore les identifiants de session définis encodés dans l'URL lors de la mise en cache
CacheKeyBaseURL URLsvE
Remplace l'URL de base des clés du cache mandatées en inverse
CacheLastModifiedFactor flottant 0.1 svdhE
Le facteur utilisé pour générer une date d'expiration en fonction de la date de dernière modification.
CacheLock on|off off svE
Active la protection contre les tempêtes de requêtes.
CacheLockMaxAge entier 5 svE
Définit la durée de vie maximale d'un verrou de cache.
CacheLockPath répertoire /tmp/mod_cache-lock +svE
Définit le répertoire des verrous.
CacheMaxExpire secondes 86400 (une journée) +svdhE
La durée maximale en secondes de mise en cache d'un document
CacheMaxFileSize octets 1000000 svdhE
>La taille maximale (en octets) d'un document pour pouvoir être stocké dans le cache
CacheMinExpire secondes 0 svdhE
La durée minimale en secondes de mise en cache d'un document
CacheMinFileSize octets 1 svdhE
La taille minimale (en octets) d'un document pour pouvoir être stocké dans le cache
CacheNegotiatedDocs On|Off Off svB
Permet la mise en cache au niveau des serveurs mandataires des documents dont le contenu a été négocié
CacheQuickHandler on|off on svE
Exécute le cache à partir d'un gestionnaire rapide.
CacheReadSize octets 0 svdhE
La quantité minimale (en octets) de données à lire et à mettre en cache avant de les envoyer au client
CacheReadTime millisecondes 0 svdhE
Le temps minimum (en millisecondes) qui doit s'écouler avant d'envoyer les données au client
CacheRoot répertoiresvE
La racine du répertoire dans lequel les fichiers du cache seront stockés
CacheSocache type[:args]svE
Implémentation du cache d'objets partagés à utiliser
CacheSocacheMaxSize octets 102400 svdhE
La taille maximale d'une entrée pouvant être placée dans le cache
CacheSocacheMaxTime secondes 86400 svdhE
La durée maximale de stockage d'un document dans le cache avant péremption
CacheSocacheMinTime seconds 600 svdhE
La durée minimale de stockage d'un document dans le cache
CacheSocacheReadSize octets 0 svdhE
La quantité minimale de données du document à lire et mettre en cache avant envoi au client
CacheSocacheReadTime millisecondes 0 svdhE
La durée minimale de lecture avant l'envoi des données
CacheStaleOnError on|off on svdhE
Sert du contenu non à jour à la place de réponses 5xx.
CacheStoreExpired On|Off Off svdhE
Tente de mettre en cache les réponses que le serveur considère comme arrivées à expiration
CacheStoreNoStore On|Off Off svdhE
Tente de mettre en cache les requêtes ou réponses dont l'entête Cache-Control: a pour valeur no-store.
CacheStorePrivate On|Off Off svdhE
Tente de mettre en cache des réponses que le serveur a marquées comme privées
CGIDScriptTimeout time[s|ms]svdhB
Durée maximale d'attente de la prochaine sortie du programme CGI
CGIMapExtension chemin CGI .extensiondhC
Technique permettant de localiser l'interpréteur des scripts CGI
CGIPassAuth On|Off Off dhC
Active la transmission d'en-têtes d'autorisation HTTP aux scripts en tant que variables CGI
CGIScriptTimeout time[s|ms]svdhB
Le temps d'attente maximum pour une sortie du programme CGI
CGIVar variable ruledhC
Contrôle la manière dont certaines variables CGI sont définies
CharsetDefault jeu de caractèressvdhE
Jeu de caractère vers lequel la traduction doit s'effectuer
CharsetOptions option [option] ... ImplicitAdd svdhE
Précise les détails de la traduction du jeu de caractères
CharsetSourceEnc jeu de caractèressvdhE
Jeu de caractères source des fichiers
CheckBasenameMatch on|off On svdhE
Vérifie aussi la correspondance des fichiers, même avec des extensions différentes
CheckCaseOnly on|off Off svdhE
Limite l'action du module aux corrections de majuscules
CheckSpelling on|off Off svdhE
Active le module de correction
ChrootDir chemin-répertoiresB
Répertoire dans lequel Apache doit se positionner au démarrage après avoir effectué un chroot(8).
ContentDigest On|Off Off svdhC
Active la génération d'un en-tête Content-MD5 dans la réponse HTTP
CookieDomain domainesvdhE
Le domaine auquel le cookie traceur s'applique
CookieExpires duréesvdhE
Durée avant expiration du cookie traceur
CookieHTTPOnly on|off off svdhE
Ajoute l'attribut 'HTTPOnly' au cookie
CookieName symbole Apache svdhE
Nom du cookie traceur
CookieSameSite None|Lax|StrictsvdhE
Ajoute l'attribut 'SameSite' au cookie
CookieSecure on|off off svdhE
Ajoute l'attribut 'Secure' au cookie
CookieStyle Netscape|Cookie|Cookie2|RFC2109|RFC2965 Netscape svdhE
Format du champ d'en-tête cookie
CookieTracking on|off off svdhE
Active le cookie traceur
CoreDumpDirectory répertoiresM
Le répertoire dans lequel le serveur HTTP Apache va tenter de se positionner avant d'effectuer un vidage mémoire
CustomLog fichier|pipe format|alias [env=[!]variable-environnement| expr=expression]svB
Définit le nom et le format du fichier journal
Dav On|Off|nom fournisseur Off dE
Active les méthodes HTTP WebDAV
DavBasePath root-pathdE
Définir le chemin de la racine du répertoire
DavDepthInfinity on|off off svdE
Autorise les requêtes PROPFIND avec en-tête Depth: Infinity
DavGenericLockDB chemin fichiersvdE
Chemin de la base de données des verrous DAV
DavLockDB chemin fichiersvE
Chemin de la base de données des verrous DAV
DavLockDiscovery on|off on svdhE
Active la découverte des verrous
DavMinTimeout secondes 0 svdE
Durée minimale pendant laquelle le serveur maintient un verrou sur une ressource DAV
DBDExptime durée en secondes 300 svE
Durée de vie des connexions inactives
DBDInitSQL "instruction SQL"svE
Exécute une instruction SQL après connexion à une base de données
DBDKeep nombre 2 svE
Nombre maximum de connexions maintenues
DBDMax nombre 10 svE
Nombre maximum de connexions
DBDMin nombre 1 svE
Nombre minimum de connexions
DBDParams param1=valeur1[,param2=valeur2]svE
Paramètres de la connexion à la base de données
DBDPersist On|OffsvE
Utiliser ou non des connexions persistentes
DBDPrepareSQL "requête SQL" étiquettesvE
Définit une requête SQL préparée
DBDriver nomsvE
Spécifie un pilote SQL
DefaultIcon chemin URLsvdhB
Icône à afficher par défaut lorsqu'aucun icône spécifique n'est précisé
DefaultLanguage symbole-languesvdhB
Définit un symbole de langue par défaut à affecter au champ d'en-tête Content-Language pour toutes les ressources dans le contexte courant auxquelles aucun symbole de langue n'a été associé.
DefaultRuntimeDir chemin-répertoire DEFAULT_REL_RUNTIME +sC
Répertoire de base des fichiers créés au cours de l'exécution du serveur
DefaultType type média|none none svdhC
Les seuls effets de cette directive sont des émissions d'avertissements si sa valeur est différente de none. Dans les versions précédentes, DefaultType permettait de spécifier un type de média à assigner par défaut au contenu d'une réponse pour lequel aucun autre type de média n'avait été trouvé.
Define nom-paramètre [valeur-paramètre]svdC
Permet de définir une variable
DeflateAlterETag AddSuffix|NoChange|Remove AddSuffix svE
Comment l'en-tête sortant ETag doit être modifié au cours de la compression
DeflateBufferSize valeur 8096 svE
Taille du fragment que zlib devra comprimer en une seule fois
DeflateCompressionLevel valeursvE
Le niveau de compression que nous appliquons à la sortie
DeflateFilterNote [type] nom de la notesvE
Enregistre le taux de compression sous la forme d'une note à des fins de journalisation
DeflateInflateLimitRequestBody valuesvdhE
Taille maximale des corps de requête décompressés
DeflateInflateRatioBurst value 3 svdhE
Nombre maximal de fois que le ratio de décompression d'un corps de requête peut être dépassé
DeflateInflateRatioLimit value 200 svdhE
Ratio de décompression maximum pour les corps de requêtes
DeflateMemLevel valeur 9 svE
La quantité de mémoire utilisable par zlib pour la compression
DeflateWindowSize valeur 15 svE
Taille de la fenêtre de compression zlib
Deny from all|hôte|env=[!]variable d'environnement [hôte|env=[!]variable d'environnement] ...dhE
Définit quels hôtes ne sont pas autorisés à accéder au serveur
<Directory chemin répertoire> ... </Directory>svC
Regroupe un ensemble de directives qui ne s'appliquent qu'au répertoire concerné du système de fichiers, à ses sous-répertoires, et à leur contenu.
DirectoryCheckHandler On|Off Off svdhB
Définit la réponse de ce module lorsqu'un autre gestionnaire est utilisé
DirectoryIndex disabled | url locale [url locale] ... index.html svdhB
Liste des fichiers ressources à rechercher lorsque le client envoie une requête pour un répertoire
DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code off svdhB
Définit une redirection externe pour les index de répertoires.
<DirectoryMatch regex> ... </DirectoryMatch>svC
Regroupe des directives qui s'appliquent au contenu de répertoires du système de fichiers correspondant à une expression rationnelle
DirectorySlash On|Off On svdhB
Activation/Désactivation de la redirection "slash de fin"
DocumentRoot chemin répertoire "/usr/local/apache/ +svC
Racine principale de l'arborescence des documents visible depuis Internet
DTracePrivileges On|Off Off sX
Détermine si les privilèges requis par dtrace sont activés.
DumpIOInput On|Off Off sE
Enregistre toutes les entrées dans le journal des erreurs
DumpIOOutput On|Off Off sE
Enregistre toutes les sorties dans le journal des erreurs
<Else> ... </Else>svdhC
Contient des directives qui ne s'appliquent que si la condition correspondant à la section <If> ou <ElseIf> précédente n'est pas satisfaite par la requête à l'exécution
<ElseIf expression> ... </ElseIf>svdhC
Contient des directives qui ne s'appliquent que si la condition correspondante est satisfaite par une requête à l'exécution, alors que la condition correspondant à la section <If> ou <ElseIf> précédente ne l'était pas.
EnableExceptionHook On|Off Off sM
Active un hook ("point d'accrochage logiciel") qui exécute des gestionnaires d'exception après un crash
EnableMMAP On|Off On svdhC
Utilise la projection en mémoire (Memory-Mapping) pour lire les fichiers pendant qu'ils sont servis
EnableSendfile On|Off Off svdhC
Utilise le support sendfile du noyau pour servir les fichiers aux clients
Error messagesvdhC
Interrompt la lecture de la configuration avec un message d'erreur personnalisé
ErrorDocument code erreur documentsvdhC
Document que le serveur renvoie au client en cas d'erreur
ErrorLog file-path|syslog[:[facility][:tag]] logs/error_log (Uni +svC
Définition du chemin du journal des erreurs
ErrorLogFormat [connection|request] formatsvC
Spécification du format des entrées du journal des erreurs
ExamplesvdhX
Directive de démonstration pour illustrer l'API des modules Apache
ExpiresActive On|Off Off svdhE
Active la génération d'en-têtes Expires
ExpiresByType type MIME <code>secondessvdhE
Définition de la valeur de l'en-tête Expires en fonction du type MIME
ExpiresDefault <code>secondessvdhE
Mode de calcul par défaut de la date d'expiration
ExtendedStatus On|Off Off sC
Extrait des informations d'état étendues pour chaque requête
ExtFilterDefine nom_filtre paramètressE
Définit un filtre externe
ExtFilterOptions option [option] ... NoLogStderr dE
Configure les options de mod_ext_filter
FallbackResource disabled | url-localesvdhB
Définit une URL par défaut pour les requêtes qui ne ciblent aucun fichier
FileETag composant ... MTime Size svdhC
Caractéristiques de fichier utilisées lors de la génération de l'en-tête de réponse HTTP ETag pour les fichiers statiques
<Files nom fichier> ... </Files>svdhC
Contient des directives qui s'appliquent aux fichiers précisés
<FilesMatch expression rationnelle> ... </FilesMatch>svdhC
Contient des directives qui s'appliquent à des fichiers spécifiés sous la forme d'expressions rationnelles
FilterChain [+=-@!]nom_filtre ...svdhB
Configure la chaîne de filtrage
FilterDeclare nom_filtre [type]svdhB
Déclare un filtre intelligent
FilterProtocol nom_filtre [nom_fournisseur] drapeaux_protocolesvdhB
Vérifie le respect du protocole HTTP
FilterProvider nom_filtre nom_fournisseur expressionsvdhB
Enregistre un filtre de contenu
FilterTrace nom_filtre niveausvdB
Obtention d'informations de débogage/diagnostique en provenance de mod_filter
FlushMaxPipelined number 5 svC
Nombre maximal de réponses en attente (pipelined) au-delà duquel elles sont envoyées sur le réseau
FlushMaxThreshold number-of-bytes 65535 svC
Seuil au-delà duquel les données en attente sont envoyées sur le réseau
ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
Action à entreprendre si un document acceptable unique n'est pas trouvé
ForceType type médium|NonedhC
Force le type de médium spécifié dans le champ d'en-tête HTTP Content-Type pour les fichiers correspondants
ForensicLog nom-fichier|pipesvE
Définit le nom de fichier du journal légal
GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]sB
Définit le nom et le format du fichier journal
GprofDir /tmp/gprof/|/tmp/gprof/%svC
Répertoire dans lequel écrire les données de profiling gmon.out.
GracefulShutdownTimeout seconds 0 sM
Spécifie le délai maximum après lequel le serveur va s'arrêter dans le cas d'un arrêt "en douceur"
Group groupe unix #-1 sB
Groupe sous lequel le serveur va traiter les requêtes
H2CopyFiles on|off off svdhE
Contrôle la gestion des fichiers dans les réponses
H2Direct on|off on pour h2c, off po +svE
Activation du protocole H2 Direct
H2EarlyHint name valuesvdhE
Ajoute un en-tête de réponse à consulter dans le code de retour 103 Early Hints
H2EarlyHints on|off off svE
Contrôle l'envoi de codes d'état 103
H2MaxDataFrameLen n 0 svE
Nombre maximal d'octets dans une trame HTTP/2 DATA
H2MaxHeaderBlockLen n 0 svE
Taille maximale des en-têtes d’une réponse
H2MaxSessionStreams n 100 svE
Nombre maximal de flux actifs par session HTTP/2.
H2MaxWorkerIdleSeconds n 600 sE
Nombre maximal de secondes pendant lequel une unité de traitement h2 pourra rester inactive sans être arrêtée.
H2MaxWorkers nsE
Nombre maximal de threads à utiliser pour chaque processus enfant.
H2MinWorkers nsE
Nombre minimal de threads à utiliser pour chaque processus enfant.
H2ModernTLSOnly on|off on svE
Impose les connexions HTTP/2 en mode "TLS moderne" seulement
H2OutputBuffering on|off on svE
Contrôle la mise en tampon du flux de sortie
H2Padding numbits 0 svE
Spécifie un intervalle de nombres d'octets de bourrage à ajouter aux trames utiles
H2ProxyRequests on|off off svE
Active/Désactive les requêtes sous mandat direct via HTTP/2
H2Push on|off on svdhE
Activation/désactivation du server push H2
H2PushDiarySize n 256 svE
Taille du journal des Pushes H2
H2PushPriority mime-type [after|before|interleaved] [weight] * After 16 svE
Priorité des pushes H2
H2PushResource [add] path [critical]svdhE
Déclare des ressources à proposer ("pusher") au client
H2SerializeHeaders on|off off svE
Active/désactive la sérialisation du traitement des requêtes/réponses
H2StreamMaxMemSize bytes 65536 svE
Quantité maximale de données en sortie mises en tampon par flux.
H2StreamTimeout time-interval[s]svdE
Temps d'attente maximum lors de l'envoi/réception de données pour le traitement d'un flux
H2TLSCoolDownSecs seconds 1 svE
Durée d'inactivité d'une connexion TLS avant diminution de la taille des paquets
H2TLSWarmUpSize amount 1048576 svE
Taille des paquets durant la phase initiale de la connexion TLS
H2Upgrade on|off on pour h2c, off po +svdhE
Activation/Désactivation du protocole de mise à jour H2
H2WebSockets on|off off svE
Active/désactive les WebSockets via HTTP/2
H2WindowSize bytes 65535 svE
Taille maximale des paquets de données pour les transmissions client vers serveur.
Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note en-tête [[expr=]valeur [remplacement] [early|env=[!]variable|expr=expression]] svdhE
Configure les en-têtes d'une réponse HTTP
HeaderName nom fichiersvdhB
Nom du fichier qui sera inséré au début de la page contenant l'index
HeartbeatAddress addr:portsX
Adresse multicast à laquelle envoyer les requêtes heartbeat
HeartbeatListen addr:portsX
Adresse multicast d'écoute des requêtes entrantes heartbeat
HeartbeatMaxServers nombre-de-serveurs 10 sX
Spécifie le nombre maximal de serveurs qui pourront envoyer des requêtes heartbeat à ce serveur.
HeartbeatStorage chemin fichier logs/hb.dat sX
Chemin vers le stockage des données heartbeat lorsqu'on utilise un fichier bidimensionnel (flat-file)
HeartbeatStorage chemin-fichier logs/hb.dat sX
Indique le chemin permettant de lire les données heartbeat
HostnameLookups On|Off|Double Off svdC
Active la recherche DNS sur les adresses IP des clients
HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0] Strict LenientMetho +svC
Modifie les contraintes sur les messages des requêtes HTTP
IdentityCheck On|Off Off svdE
Active la journalisation de l'identité RFC 1413 de l'utilisateur distant
IdentityCheckTimeout secondes 30 svdE
Détermine le délai d'attente pour les requêtes ident
<If expression> ... </If>svdhC
Contient des directives qui ne s'appliquent que si une condition est satisfaite au cours du traitement d'une requête
<IfDefine [!]paramètre> ... </IfDefine>svdhC
Contient des directives qui ne s'appliqueront que si un test retourne "vrai" au démarrage du serveur
<IfDirective [!]directive-name> ... </IfDirective>svdhC
Regroupe des directives dont le traitement est conditionné par la présence ou l'absence d'une directive particulière
<IfFile [!]filename> ... </IfFile>svdhC
Regroupe des directives qui ne seront traitées que si un fichier existe au démarrage
<IfModule [!]fichier module|identificateur module> ... </IfModule>svdhC
Contient des directives qui ne s'appliquent qu'en fonction de la présence ou de l'absence d'un module spécifique
<IfSection [!]section-name> ... </IfSection>svdhC
Regroupe des directives dont le traitement est conditionné par la présence ou l'absence d'une section particulière
<IfVersion [[!]opérateur] version> ... </IfVersion>svdhE
Contient des portions de configuration dépendantes de la version
ImapBase map|referer|URL http://nom_serveur/ +svdhB
Valeur par défaut de la directive base des fichiers imagemap
ImapDefault error|nocontent|map|referer|URL nocontent svdhB
Action à entreprendre par défaut lorsqu'un fichier imagemap est invoqué avec des coordonnées qui ne correspondent à aucune cible
ImapMenu none|formatted|semiformatted|unformatted formatted svdhB
Action à entreprendre si aucune coordonnée n'est fournie lorsqu'on invoque un fichier imagemap
Include chemin-fichier|chemin-répertoire|wildcardsvdC
Inclut d'autres fichiers de configuration dans un des fichiers de configuration du serveur
IncludeOptional file-path|directory-path|wildcardsvdC
Inclusion de fichiers dans le fichier de configuration
IndexHeadInsert "marque ..."svdhB
Insère du texte dans la section HEAD de la page d'index.
IndexIgnore fichier [fichier] ... "." svdhB
Ajouts à la liste des fichiers à cacher lors de l'affichage de l'index d'un répertoire
IndexIgnoreReset ON|OFFsvdhB
Vide la liste des fichiers à cacher lors de l'affichage du contenu d'un répertoire
IndexOptions [+|-]option [[+|-]option] ...svdhB
Diverses options de configuration pour l'indexation d'un répertoire
IndexOrderDefault Ascending|Descending Name|Date|Size|Description Ascending Name svdhB
Définit l'ordre d'affichage par défaut d'un index de répertoire
IndexStyleSheet chemin-urlsvdhB
Ajoute une feuille de style CSS à l'index du répertoire
InputSed commande-seddh
Commande sed à exécuter pour le filtrage des données d'une requête (en général des données POST)
ISAPIAppendLogToErrors on|off off svdhB
Enregistrement des requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans le journal des erreurs
ISAPIAppendLogToQuery on|off on svdhB
Enregistre les requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans la partie arguments de la requête
ISAPICacheFile chemin-fichier [chemin-fichier] ...svB
Fichiers .dll ISAPI devant être chargés au démarrage
ISAPIFakeAsync on|off off svdhB
Emulation du support des entrées/sorties asynchrones pour les appels ISAPI
ISAPILogNotSupported on|off off svdhB
Journalisation des demandes de fonctionnalités non supportées de la part des extensions ISAPI
ISAPIReadAheadBuffer taille 49152 svdhB
Taille du tampon de lecture anticipée envoyé aux extensions ISAPI
KeepAlive On|Off On svC
Active les connexions HTTP persistantes
KeepAliveTimeout nombre[ms] 5 svC
Durée pendant laquelle le serveur va attendre une requête avant de fermer une connexion persistante
KeptBodySize taille maximale en octets 0 dB
Conserve le corps de la requête à concurrence de la taille maximale spécifiée, pour une utilisation éventuelle par des filtres comme mod_include.
LanguagePriority langage-MIME [langage-MIME] ...svdhB
L'ordre de priorité des variantes de langages pour les cas où le client n'a pas formulé de préférences
LDAPCacheEntries nombre 1024 sE
Nombre maximum d'entrées dans le cache LDAP primaire
LDAPCacheTTL secondes 600 sE
Durée pendant laquelle les entrées du cache restent valides.
LDAPConnectionPoolTTL n -1 svE
Désactive les connexions d'arrière-plan qui sont restées inactives trop longtemps au sein du jeu de connexions.
LDAPConnectionTimeout secondessE
Spécifie le délai d'attente en secondes de la socket de connexion
LDAPLibraryDebug 7sE
Active le débogage dans le SDK LDAP
LDAPOpCacheEntries nombre 1024 sE
Nombre d'entrées utilisées pour mettre en cache les opérations de comparaison LDAP
LDAPOpCacheTTL secondes 600 sE
Durée pendant laquelle les entrées du cache d'opérations restent valides
LDAPReferralHopLimit nombredhE
Le nombre maximum de redirections vers des serveurs alternatifs (referrals) avant l'abandon de la requête LDAP.
LDAPReferrals On|Off|default On dhE
Active la redirection vers des serveurs alternatifs au cours des requêtes vers le serveur LDAP.
LDAPRetries nombre d'essais 3 sE
Définit le nombre maximum de tentatives de connexions au serveur LDAP.
LDAPRetryDelay secondes 0 sE
Définit le temps d'attente avant un autre essai de connexion au serveur LDAP.
LDAPSharedCacheFile chemin/fichiersE
Définit le fichier du cache en mémoire partagée
LDAPSharedCacheSize octets 500000 sE
Taille en octets du cache en mémoire partagée
LDAPTimeout secondes 60 sE
Spécifie le délai d'attente pour les opérations de recherche et d'identification LDAP en secondes
LDAPTrustedClientCert type chemin/nom-fichier/alias [mot de passe]svdhE
Définit le nom de fichier contenant un certificat client ou un alias renvoyant vers un certificat client spécifique à une connexion. Tous les SDK LDAP ne supportent pas les certificats clients par connexion.
LDAPTrustedGlobalCert type chemin/nom-fichier [mot de passe]sE
Définit le nom de fichier ou la base de données contenant les Autorités de Certification de confiance globales ou les certificats clients globaux
LDAPTrustedMode typesvE
Spécifie le mode (SSL ou TLS) à utiliser lors de la connexion à un serveur LDAP.
LDAPVerifyServerCert On|Off On sE
Force la vérification du certificat du serveur
<Limit méthode [méthode] ... > ... </Limit>dhC
Limite les contrôles d'accès que la section contient à certaines méthodes HTTP
<LimitExcept méthode [méthode] ... > ... </LimitExcept>dhC
Applique les contrôles d'accès à toutes les méthodes HTTP, sauf celles qui sont spécifiées
LimitInternalRecursion nombre [nombre] 10 svC
Détermine le nombre maximal de redirections internes et de sous-requêtes imbriquées
LimitRequestBody octets 1073741824 svdhC
limite la taille maximale du corps de la requête HTTP envoyée par le client
LimitRequestFields nombre 100 svC
Limite le nombre de champs d'en-tête autorisés dans une requête HTTP
LimitRequestFieldSize octets 8190 svC
Dédinit la taille maximale autorisée d'un en-tête de requête HTTP
LimitRequestLine octets 8190 svC
Définit la taille maximale d'une ligne de requête HTTP
LimitXMLRequestBody octets 1000000 svdhC
Définit la taille maximale du corps d'une requête au format XML
Listen [adresse IP:]numéro port [protocole]sM
Les adresses IP et ports sur lesquels le serveur écoute
ListenBackLog backlog 511 sM
Longueur maximale de la liste d'attente des connexions
ListenCoresBucketsRatio ratio 0 (disabled) sM
Rapport entre le nombre de coeurs de processeur activés et le nombre de segments d'écoute
LoadFile nom-fichier [nom-fichier] ...svE
Liaison du fichier objet ou de la bibliothèque spécifié
LoadModule module nom-fichiersvE
Liaison avec le serveur du fichier objet ou de la bibliothèque spécifié, et ajout de ce dernier à la liste des modules actifs
<Location chemin URL|URL> ... </Location>svC
N'applique les directives contenues qu'aux URLs spécifiées
<LocationMatch regex> ... </LocationMatch>svC
N'applique les directives contenues qu'aux URLs correspondant à une expression rationnelle
LogFormat format|alias [alias] "%h %l %u %t \"%r\" +svB
Décrit un format utilisable dans un fichier journal
LogIOTrackTTFB ON|OFF OFF svdhE
Permet d'enregistrer le délai avant le premier octet (time to first byte - TTFB)
LogLevel [module:]niveau [module:niveau] ... warn svdC
Contrôle la verbosité du journal des erreurs
LogMessage message [hook=hook] [expr=expression] dX
Enregistre des messages personnalisés dans le journal des erreurs
LuaAuthzProvider provider_name /path/to/lua/script.lua function_namesE
Branche une fonction fournisseur d'autorisation dans mod_authz_core
LuaCodeCache stat|forever|never stat svdhE
Configure le cache de code compilé.
LuaHookAccessChecker /chemin/vers/lua/script.lua hook_function_name [early|late]svdhE
Fournit un point d'entrée pour la phase access_checker du traitement de la requête
LuaHookAuthChecker /chemin/vers/lua/script.lua hook_function_name [early|late]svdhE
Fournit un point d'entrée pour la phase auth_checker du traitement de la requête
LuaHookCheckUserID /chemin/vers/lua/script.lua hook_function_name [early|late]svdhE
Fournit un point d'entrée pour la phase check_user_id du traitement de la requête
LuaHookFixups /chemin/vers/lua/script.lua hook_function_namesvdhE
Fournit un point d'entrée pour la phase de correction du traitement de la requête
LuaHookInsertFilter /chemin/vers/lua/script.lua hook_function_namesvdhE
Fournit un point d'entrée pour la phase insert_filter du traitement de la requête
LuaHookLog /path/to/lua/script.lua log_function_namesvdhE
Permet une insertion dans la phase de journalisation du traitement d'une requête
LuaHookMapToStorage /chemin/vers/lua/script.lua hook_function_namesvdhE
Fournit un point d'entrée pour la phase map_to_storage du traitement de la requête
LuaHookPreTranslate /path/to/lua/script.lua hook_function_namesvdhE
Fournit un point d'entrée pour la phase de pré-traduction du traitement d'une requête
LuaHookTranslateName /chemin/vers/lua/script.lua nom_fonction_hook [early|late]svE
Fournit un point d'entrée à la phase du nom de traduction du traitement de la requête
LuaHookTypeChecker /chemin/vers/lua/script.lua hook_function_namesvdhE
Fournit un point d'entrée pour la phase type_checker du traitement de la requête
LuaInherit none|parent-first|parent-last parent-first svdhE
Contrôle la manière dont les sections de configuration parentes sont fusionnées dans les enfants
LuaInputFilter filter_name /path/to/lua/script.lua function_namesE
Fournit une fonction Lua pour le filtrage en entrée
LuaMapHandler modele-uri /chemin/vers/lua/script.lua [nom-fonction]svdhE
Met en correspondance un chemin avec un gestionnaire lua
LuaOutputFilter filter_name /path/to/lua/script.lua function_namesE
Fournit une fonction Lua pour le filtrage de contenu en sortie
LuaPackageCPath /chemin/vers/include/?.soasvdhE
Ajoute un répertoire au package.cpath de lua
LuaPackagePath /chemin/vers/include/?.luasvdhE
Ajoute un répertoire au package.path de lua
LuaQuickHandler /path/to/script.lua hook_function_namesvdhE
Fournit un point d'entrée pour la gestion rapide du traitement de la requête
LuaRoot /chemin/vers/un/répertoiresvdhE
Spécifie le chemin de base pour la résolution des chemins relatifs dans les directives de mod_lua
LuaScope once|request|conn|thread|server [min] [max] once svdhE
Une valeur parmi once, request, conn, thread -- la valeur par défaut est once
<Macro nom [par1 .. parN]> ... </Macro>svdB
Définition d'une macro dans un fichier de configuration
MaxConnectionsPerChild number 0 sM
Limite le nombre de connexions qu'un processus enfant va traiter au cours de son fonctionnement
MaxKeepAliveRequests nombre 100 svC
Nombre de requêtes permises pour une connexion persistante
MaxMemFree KOctets 2048 sM
Quantité maximale de mémoire que l'allocateur principal est autorisé à conserver sans appeler free()
MaxRangeOverlaps default | unlimited | none | nombre de chevauchements 20 svdC
Nombre de chevauchements de segments de données autorisé (par exemple 100-200,150-300) avant le renvoi de la ressource complète
MaxRangeReversals default | unlimited | none | nombre d'inversions 20 svdC
Nombre d'inversions d'ordre autorisé dans la spécification des segments de données (par exemple 100-200,50-70) avant le renvoi de la ressource complète
MaxRanges default | unlimited | none | nombre de segments 200 svdC
Nombre de segments de données autorisé avant le renvoi de l'intégralité de la ressource
MaxRequestWorkers nombresM
Nombre maximum de connexions pouvant être traitées simultanément
MaxSpareServers nombre 10 sM
Nombre maximum de processus serveurs enfants inactifs
MaxSpareThreads nombresM
Nombre maximum de threads inactifs
MaxThreads nombre 2048 sM
Définit le nombre maximum de threads esclaves
MDActivationDelay durationsX
Définit le délai d'activation des nouveaux certificats
MDBaseServer on|off off sX
Définit si le serveur global peut être géré ou seulement les serveurs virtuels.
MDCAChallenges name [ name ... ] tls-alpn-01 http-01 +sX
Type de négociation ACME utilisée pour prouver l'appartenance du domaine.
MDCertificateAgreement acceptedsX
Acceptation des conditions d'utilisation de l'autorité de certification.
MDCertificateAuthority url letsencrypt sX
Les URLs du service ACME de l'autorité de certification.
MDCertificateCheck name urlsX
Définit le motif de nom et d’URL pour un nom de site de vérification de certificat.
MDCertificateFile path-to-pem-filesX
Définit un fichier de certificat statique pour le domaine géré.
MDCertificateKeyFile path-to-filesX
Définit une clé privée statique pour le certificat statique.
MDCertificateMonitor name url crt.sh https://crt. +sX
L'URL d'un moniteur d'enregistrement de certificat.
MDCertificateProtocol protocol ACME sX
Le protocole à utiliser avec l'autorité de certification.
MDCertificateStatus on|off on sX
Extrait les informations publiques du certificat au format JSON.
MDChallengeDns01 path-to-commandsX
Définit la commande d'activation/désactivation des vérifications dns-01
MDChallengeDns01Version 1|2 1 sX
Définit le type des arguments avec lesquels appeler MDChallengeDns01
MDCheckInterval duration 12h sX
Détermine la périodicité de la vérification des certificats
MDContactEmail addresssX
Adresse Email pour l'enregistrement du compte
MDDriveMode always|auto|manual auto sX
Ancien nom de MDRenewMode.
MDExternalAccountBinding key-id hmac-64 | none | file none sX
Définit les valeurs keyid et hmac de liaison avec les comptes externes à utiliser dans les CA
MDHttpProxy urlsX
Spécifie un serveur mandataire pour les connexions sortantes.
MDMatchNames all|servernames all sX
Définit comment les noms DNS sont comparés aux vhosts
MDMember hostnamesX
Nom d'hôte additionnel pour le domaine géré.
MDMembers auto|manual auto sX
Définit si les alias de noms de domaines sont automatiquement ajoutés.
MDMessageCmd path-to-cmd optional-argssX
Gère les évènements pour les domaines gérés
MDMustStaple on|off off sX
Définit si les nouveaux certificats doivent avoir le drapeau OCSP Must Staple activé.
MDNotifyCmd path [ args ]sX
Lance un programme lorsqu'un domaine géré est opérationnel.
MDomain dns-name [ other-dns-name... ] [auto|manual]sX
Définit une liste de noms de domaines qui appartiennent à un groupe.
<MDomainSet dns-name [ other-dns-name... ]>...</MDomainSet>sX
Conteneur de directives à appliquer à un ou plusieurs domaines gérés.
MDPortMap map1 [ map2 ] http:80 https:443 sX
Mappage des ports externes avec les ports internes pour vérifier à qui appartient le domaine.
MDPrivateKeys type [ params... ] RSA 2048 sX
Définit le type et la taille des clés privées générées.
MDProfile namesX
Utiliser un profile ACME spécifique depuis le CA
MDProfileMandatory on|off off sX
Contrôler si un MDProfile est obligatoire.
MDRenewMode always|auto|manual auto sX
Contrôle le renouvellement des certificats.
MDRenewWindow duration 33% sX
Définit le moment auquel un certificat doit être renouvelé.
MDRequireHttps off|temporary|permanent off sX
Redirige le trafic http: vers https: pour les domaines gérés.
MDRetryDelay duration 5s sX
Temps d'attente avant de réessayer, doublé à chaque erreur consécutive
MDRetryFailover number 13 sX
Le nombre d'erreurs avant de se tourner vers un autre CA
MDServerStatus on|off on sX
Définit si les informations à propos des domaines gérés sont ajoutés ou non à server-status.
MDStapleOthers on|off on sX
Active l'agrafage pour les certificats non gérés par mod_md.
MDStapling on|off off sX
Active l'agrafage pour un ou plusieurs domaines.
MDStaplingKeepResponse duration 7d sX
Contrôle la durée au bout de laquelle les anciennes réponses doivent être supprimées.
MDStaplingRenewWindow duration 33% sX
Contrôle l'ancienneté des réponses OCSP au dela de laquelle ces dernières seront renouvelées.
MDStoreDir path md sX
Chemin dans le système de fichiers local du répertoire où seront stockées les données à propos des domaines gérés.
MDStoreLocks on|off|duration off sX
Configure le verrouillage du magasin pour les mises à jour
MDWarnWindow duration 10% sX
Définit la fenêtre de temps pendant laquelle vous serez informé de l'expiration prochaine d'un certificat.
MemcacheConnTTL num[units] 15s svE
Durée de conservation des connexions inactives
MergeSlashes ON|OFF ON svC
Fusion des slashes consécutifs dans les URLs par le serveur.
MergeTrailers [on|off] off svC
Détermine si les données supplémentaires (trailers) sont fusionnées avec les en-têtes
MetaDir répertoire .web svdhE
Le nom du répertoire où trouver les fichiers de métainformations dans le style du CERN
MetaFiles on|off off svdhE
Active le traitement des métafichiers du CERN
MetaSuffix suffixe .meta svdhE
Suffixe du fichier contenant les métainformations dans le style du CERN
MimeMagicFile chemin-fichiersvE
Active la détermination du type MIME en se basant sur le contenu du fichier et en utilisant le fichier magique spécifié
MinSpareServers nombre 5 sM
Nombre minimum de processus serveurs enfants inactifs
MinSpareThreads nombresM
Nombre minimum de threads inactifs qui seront disponibles pour pouvoir traiter les pics de requêtes
MMapFile chemin fichier [chemin fichier] ...sX
Charge au démarrage une liste de fichiers en mémoire
ModemStandard V.21|V.26bis|V.32|V.34|V.92dX
Standard de modem à simuler
ModMimeUsePathInfo On|Off Off dB
Indique à mod_mime de traiter les éléments de path_info en tant que parties du nom de fichier
MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers [Handlers|Filters] NegotiatedOnly svdhB
Les types de fichiers qui seront inclus lors d'une recherche de correspondance de fichier avec les vues multiples (MultiViews)
Mutex mécanisme [default|nom-mutex] ... [OmitPID] default sC
Définit les mécanismes de mutex et le repertoire du fichier verrou pour tous les mutex ou seulement les mutex spécifiés
NameVirtualHost adresse[:port]sC
OBSOLETE : Définit une adresse IP pour les serveurs virtuels à base de nom
NoProxy domaine [domaine] ...svE
Serveurs, domaines ou réseaux auquels on se connectera directement
NWSSLTrustedCerts nom-fichier [nom-fichier] ...sB
Liste de certificats clients supplémentaires
NWSSLUpgradeable [adresse-IP:]num-portsB
Permet de promouvoir une connexion non SSL au statut de connexion SSL à la demande
Options [+|-]option [[+|-]option] ... FollowSymlinks svdhC
Définit les fonctionnalités disponibles pour un répertoire particulier
Order ordre Deny,Allow dhE
Définit le statut d'accès par défaut et l'ordre dans lequel les directives Allow et Deny sont évaluées.
OutputSed commande-seddh
Commande sed pour le filtrage des contenus de type réponse
PassEnv var-env [var-env] ...svdhB
Transmet des variables d'environnement depuis le shell
PidFile nom fichier logs/httpd.pid sM
Ficher dans lequel le serveur enregistre l'identificateur de processus du démon
PrivilegesMode FAST|SECURE|SELECTIVE FAST svdX
Fait un compromis entre d'une part l'efficacité et la vitesse de traitement et d'autre part la sécurité à l'encontre des codes malicieux supportant les privilèges.
Protocol protocolesvC
Protocole pour une socket d'écoute
ProtocolEcho On|Off Off svX
Active ou désactive le serveur d'écho
Protocols protocole ... http/1.1 svC
Protocoles disponibles pour un serveur virtuel ou non
ProtocolsHonorOrder On|Off On svC
Détermine qui du client ou du serveur détermine l'ordre des protocoles au cours de la négociation de la connexion
<Proxy url-avec-jokers> ...</Proxy>svE
Conteneur de directives s'appliquant à des ressources mandatées
Proxy100Continue Off|On On svdE
Transmission du message "100-continue" au serveur d'origine
ProxyAddHeaders Off|On On svdE
Ajoute des informations à propos du mandataire aux en-têtes X-Forwarded-*
ProxyBadHeader IsError|Ignore|StartBody IsError svE
Détermine la manière de traiter les lignes d'en-tête incorrectes d'une réponse
ProxyBlock *|terme|serveur|domaine [terme|serveur|domaine] ...svE
Termes, serveurs ou domaines bloqués par le mandataire
ProxyDomain DomainesvE
Nom de domaine par défaut pour les requêtes mandatées
ProxyErrorOverride Off|On [code ...] Off svdE
Outrepasser les pages d'erreur pour les contenus mandatés
ProxyExpressDBMFile pathnamesvE
Chemin du fichier DBM.
ProxyExpressDBMType type default svE
Type de fichier DBM.
ProxyExpressEnable on|off off svE
Active la fonctionnalité du module.
ProxyFCGIBackendType FPM|GENERIC FPM svdhE
Spécifie le type de l'application FastCGI d'arrière-plan
ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]svdhE
Permet d'adapter la valeur des variables envoyées aux serveurs FastCGI
ProxyFtpDirCharset character_set ISO-8859-1 svdE
Définit le jeu de caractères des listings FTP mandatés
ProxyFtpEscapeWildcards on|off on svdE
Les caractères génériques dans les noms de fichiers doivent-ils être échappés lorsqu'ils sont envoyés au serveur FTP ?
ProxyFtpListOnWildcard on|off on svdE
Les caractères génériques dans les noms de fichiers demandés doivent-ils déclencher l'affichage d'un listing ?
ProxyHCExpr name {ap_expr expression}svE
Crée et nomme une expression conditionnelle à utiliser pour déterminer la santé d'un serveur d'arrière-plan en fonction de sa valeur
ProxyHCTemplate name parameter=setting [...]svE
Crée et nomme un modèle permettant de définir différents paramètres de check up
ProxyHCTPsize size 16 sE
Définit la taille totale, pour l'ensemble du serveur, du jeu de threads utilisé pour le check up des équipiers
ProxyHTMLBufSize nb-octets 8192 svdB
Définit l'incrément de la taille du tampon, ainsi que sa taille initiale, pour la mise en tampon des scripts en ligne et des feuilles de style.
ProxyHTMLCharsetOut jeu-de-caractères | *svdB
Spécifie un jeu de caractères pour la sortie de mod_proxy_html.
ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
svdB
Définit une déclaration de type de document HTML ou XHTML.
ProxyHTMLEnable On|Off Off svdB
Permet d'activer/désactiver le filtre proxy_html.
ProxyHTMLEvents attribut [attribut ...]svdB
Spécifie les attributs à traiter comme des évènements de type scripting.
ProxyHTMLExtended On|Off Off svdB
Détermine si l'on doit corriger les liens dans les scripts en ligne, les feuilles de style et les évènements de type scripting.
ProxyHTMLFixups [lowercase] [dospath] [reset]svdB
Corrige les erreurs HTML simples.
ProxyHTMLInterp On|Off Off svdB
Active la réinterprétation des règles ProxyHTMLURLMap pour chaque requête.
ProxyHTMLLinks élément attribut [attribut2 ...]svdB
Spécifie les éléments HTML dont les attributs d'URL doivent être réécrits.
ProxyHTMLMeta On|Off Off svdB
Active ou désactive une préinterprétation supplémentaire des métadonnées dans les sections HTML <head>.
ProxyHTMLStripComments On|Off Off svdB
Détermine si les commentaires HTML doivent être supprimés.
ProxyHTMLURLMap modèle-source modèle-cible [drapeaux] [cond]svdB
Définit une règle de réécriture des liens HTML
ProxyIOBufferSize octets 8192 svE
Détermine la taille du tampon interne de transfert de données
<ProxyMatch regex> ...</ProxyMatch>svE
Conteneur de directives s'appliquant à des ressources mandatées correspondant à une expression rationnelle
ProxyMaxForwards nombre -1 svE
Nombre maximum de mandataires à travers lesquelles une requête peut être redirigée
ProxyPass [chemin] !|url [clé=valeur [clé=valeur ...]] [nocanon] [interpolate] [noquery]svdE
Référencer des serveurs distants depuis l'espace d'URLs du serveur local
ProxyPassInherit On|Off On svE
Héritage des directives ProxyPass définies au niveau du serveur principal
ProxyPassInterpolateEnv On|Off Off svdE
Active l'interpolation des variables d'environnement dans les configurations de mandataires inverses
ProxyPassMatch [regex] !|url [key=value [key=value ...]]svdE
Fait correspondre des serveurs distants dans l'espace d'URL du serveur local en utilisant des expressions rationnelles
ProxyPassReverse [chemin] url [interpolate]svdE
Ajuste l'URL dans les en-têtes de la réponse HTTP envoyée par un serveur mandaté en inverse
ProxyPassReverseCookieDomain domaine-interne domaine-public [interpolate]svdE
Ajuste la chaîne correspondant au domaine dans les en-têtes Set-Cookie en provenance d'un serveur mandaté
ProxyPassReverseCookiePath chemin-interne chemin-public [interpolate]svdE
Ajuste la chaîne correspondant au chemin dans les en-têtes Set-Cookie en provenance d'un serveur mandaté
ProxyPreserveHost On|Off Off svdE
Utilise l'en-tête de requête entrante Host pour la requête du mandataire
ProxyReceiveBufferSize octets 0 svE
Taille du tampon réseau pour les connexions mandatées HTTP et FTP
ProxyRemote match remote-server [username:password]svE
Mandataire distant à utiliser pour traiter certaines requêtes
ProxyRemoteMatch regex remote-server [username:password]svE
Le mandataire distant à utiliser pour traiter les requêtes correspondant à une expression rationnelle
ProxyRequests On|Off Off svE
Active la fonctionnalité (standard) de mandataire direct
ProxySCGIInternalRedirect On|Off|Headername On svdE
Active ou désactive les réponses de redirection interne en provenance du serveur cible.
ProxySCGISendfile On|Off|nom-en-tête Off svdE
Active l'évaluation du pseudo en-tête de réponse X-Sendfile
ProxySet url clé=valeur [clé=valeur ...]svdE
Définit différents paramètres relatifs à la répartition de charge des mandataires et aux membres des groupes de répartition de charge
ProxySourceAddress adressesvE
Définit l'adresse IP locale pour les connexions mandatées sortantes
ProxyStatus Off|On|Full Off svE
Affiche l'état du répartiteur de charge du mandataire dans mod_status
ProxyTimeout secondessvE
Délai d'attente réseau pour les requêtes mandatées
ProxyVia On|Off|Full|Block Off svE
Information fournie dans l'en-tête de réponse HTTP Via pour les requêtes mandatées
ProxyWebsocketFallbackToProxyHttp On|Off On svE
Demande à ce module de laisser mod_proxy_http gérer la requête
QualifyRedirectURL On|Off Off svdC
Vérifie si la variable d'environnement REDIRECT_URL est pleinement qualifiée
ReadBufferSize bytes 8192 svdC
Taille des tampons utilisés pour lire les données
ReadmeName nom-fichiersvdhB
Nom du fichier dont le contenu sera inséré à la fin de l'index
ReceiveBufferSize octets 0 sM
Taille du tampon TCP en entrée
Redirect [état] [URL-path] URLsvdhB
Envoie une redirection externe demandant au client d'effectuer une autre requête avec une URL différente
RedirectMatch [état] regex URLsvdhB
Envoie une redirection externe faisant appel aux expressions rationnelles pour la mise en correspondance de l'URL courante
RedirectPermanent chemin URL URLsvdhB
Envoie une redirection externe permanente demandant au client d'effectuer une nouvelle requête avec une URL différente
RedirectRelative On|Off Off svdB
Redirection relative de cibles.
RedirectTemp chemin URL URLsvdhB
Envoie une redirection externe temporaire demandant au client d'effectuer une nouvelle requête avec une URL différente
RedisConnPoolTTL num[units] 15s svE
Durée de vie du jeu de connexions avec le(s) serveur(s) Redis.
RedisTimeout num[units] 5s svE
Durée maximale de lecture/écriture sur la connexion avec le(s) serveur(s) Redis.
ReflectorHeader en-tête-entrée [en-tête-sortie]svdhB
Renvoie un en-tête d'entrée dans les en-têtes de sortie
RegexDefaultOptions [none] [+|-]option [[+|-]option] ... DOTALL DOLLAR_ENDON +sC
Configuration des options globales par défaut pour les expressions rationnelles
RegisterHttpMethod méthode [méthode [...]]sC
Enregistrement de méthodes HTTP non standards
RemoteIPHeader en-têtesvB
Définit le champ d'en-tête qui contiendra les adresses IP du client
RemoteIPInternalProxy ip-mandataire|ip-mandataire/sous-réseau|nom-hôte ...svB
Déclare les adresses IP intranet clients comme dignes de confiance pour présenter la valeur RemoteIPHeader
RemoteIPInternalProxyList nom-fichiersvB
Déclare les adresses IP intranet clients comme dignes de confiance pour présenter la valeur RemoteIPHeader
RemoteIPProxiesHeader Nom_en-têtesvB
Déclare le champ d'en-tête qui contiendra toutes les adresses IP intermédiaires
RemoteIPProxyProtocol On|OffsvB
Active ou désactive la gestion du protocole PROXY
RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]svB
Désactive la prise en compte de l'en-tête PROXY pour certains hôtes ou réseaux
RemoteIPTrustedProxy ip-mandataire|ip-mandataire/sous-réseau|nom-hôte ...svB
Déclare les adresses IP clientes de l'intranet dignes de confiance pour présenter la valeur RemoteIPHeader
RemoteIPTrustedProxyList nom-fichiersvB
Déclare les adresses IP intranet clients comme dignes de confiance pour présenter la valeur RemoteIPHeader
RemoveCharset extension [extension] ...vdhB
Supprime toute association de jeu de caractères pour un ensemble d'extensions de noms de fichiers
RemoveEncoding extension [extension] ...vdhB
Supprime toute association de codage de contenu pour un ensemble d'extensions de noms de fichiers
RemoveHandler extension [extension] ...vdhB
Supprime toute association de gestionnaire à un ensemble d'extensions de noms de fichiers
RemoveInputFilter extension [extension] ...vdhB
Supprime toute association de filtre en entrée à un ensemble d'extensions de noms de fichiers
RemoveLanguage extension [extension] ...vdhB
Supprime toute association de langue à un ensemble d'extensions de noms de fichiers
RemoveOutputFilter extension [extension] ...vdhB
Supprime toute association de filtre en sortie à un ensemble d'extensions de noms de fichiers
RemoveType extension [extension] ...vdhB
Supprime toute association de type de contenu à un ensemble d'extensions de noms de fichiers
RequestHeader add|append|edit|edit*|merge|set|setifempty|unset en-tête [[expr=]valeur [remplacement] [early|env=[!]variable|expr=expression]] svdhE
Configure les en-têtes d'une requête HTTP
RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=MinRate] [body=timeout[-maxtimeout][,MinRate=MinRate] handshake=0 header= +svE
Définit des délais maximums pour la négociation TLS, la réception des en-têtes et/ou corps des requêtes en provenance du client.
Require [not] nom-entité [nom-entité] ...dhB
Vérifie si un utilisateur authentifié a une autorisation d'accès accordée par un fournisseur d'autorisation.
<RequireAll> ... </RequireAll>dhB
Regroupe plusieurs directives d'autorisation dont aucune ne doit échouer et dont au moins une doit retourner un résultat positif pour que la directive globale retourne elle-même un résultat positif.
<RequireAny> ... </RequireAny>dhB
Regroupe des directives d'autorisation dont au moins une doit retourner un résultat positif pour que la directive globale retourne elle-même un résultat positif.
<RequireNone> ... </RequireNone>dhB
Regroupe des directives d'autorisation dont aucune ne doit retourner un résultat positif pour que la directive globale n'échoue pas.
RewriteBase chemin_URLdhE
Définit l'URL de base pour les réécritures au niveau répertoire
RewriteCond chaîne_de_test expression_de_comparaison [drapeaux]svdhE
Définit une condition qui devra être satisfaite pour que la réécriture soit effectuée
RewriteEngine on|off off svdhE
Active ou désactive l'exécution du moteur de réécriture
RewriteMap MapName MapType:MapSource [MapTypeOptions] svE
Définit une fonction de mise en correspondance pour la recherche de mots-clés
RewriteOptions OptionssvdhE
Configure certaines options spéciales pour le moteur de réécriture
RewriteRule Modèle Substitution [drapeaux]svdhE
Définit les règles pour le moteur de réécriture
RLimitCPU secondes|max [secondes|max]svdhC
Limite le temps CPU alloué aux processus initiés par les processus enfants d'Apache httpd
RLimitMEM octets|max [octets|max]svdhC
Limite la mémoire allouée aux processus initiés par les processus enfants d'Apache httpd
RLimitNPROC nombre|max [nombre|max]svdhC
Limite le nombre de processus qui peuvent être initiés par les processus initiés par les processus enfants d'Apache httpd
Satisfy Any|All All dhE
Interaction entre le contrôle d'accès en fonction de l'hôte et l'authentification utilisateur
ScoreBoardFile chemin fichier logs/apache_runtime +sM
Chemin du fichier où sont stockées les données concernant la coordination des processus enfants
Script méthode script cgisvdB
Active un script CGI dans le cas d'une méthode de requête particulière.
ScriptAlias [chemin URL] chemin fichier|chemin répertoiresvdB
Fait correspondre une URL à une zone du système de fichiers et désigne la cible comme script CGI
ScriptAliasMatch regex chemin fichier|chemin répertoiresvB
Fait correspondre une URL à une zone du système de fichiers en faisant appel aux expressions rationnelles et en désignant la cible comme un script CGI
ScriptInterpreterSource Registry|Registry-Strict|Script Script svdhC
Permet de localiser l'interpréteur des scripts CGI
ScriptLog chemin fichiersvB
Chemin du fichier journal des erreurs du script CGI
ScriptLogBuffer octets 1024 svB
Taille maximale des requêtes PUT ou POST qui seront enregistrées dans le journal du script
ScriptLogLength octets 10385760 svB
Taille maximale du fichier journal des scripts CGI
ScriptSock chemin fichier cgisock sB
Le préfixe du nom de fichier du socket à utiliser pour communiquer avec le démon CGI
SecureListen [adresse-IP:]num-port nom-certificat [MUTUAL]sB
Active le chiffrement SSL pour le port spécifié
SeeRequestTail On|Off Off sC
Détermine si mod_status affiche les 63 premiers caractères d'une requête ou les 63 derniers, en supposant que la requête elle-même possède plus de 63 caractères.
SendBufferSize octets 0 sM
Taille du tampon TCP en sortie
ServerAdmin adresse électronique|URLsvC
L'adresse électronique que le serveur inclut dans les messages d'erreur envoyés au client
ServerAlias nom serveur [nom serveur] ...vC
Autres noms d'un serveur utilisables pour atteindre des serveurs virtuels à base de nom
ServerLimit nombresM
Limite supérieure de la définition du nombre de processus
ServerName [protocole://]nom-de-domaine|adresse-ip[:port]svC
Nom d'hôte et port que le serveur utilise pour s'authentifier lui-même
ServerPath chemin d'URLvC
Nom de chemin d'URL hérité pour un serveur virtuel à base de nom accédé par un navigateur incompatible
ServerRoot chemin de répertoire /usr/local/apache sC
Racine du répertoire d'installation du serveur
ServerSignature On|Off|EMail Off svdhC
Définit un pied de page pour les documents générés par le serveur
ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full Full sC
Configure l'en-tête Server de la réponse HTTP
Session On|Off Off svdhE
Ouvre une session pour le contexte courant
SessionCookieName nom attributssvdhE
Nom et attributs du cookie RFC2109 dans lequel la session est stockée
SessionCookieName2 nom attributssvdhE
Nom et attributs pour le cookie RFC2965 dans lequel est stockée la session
SessionCookieRemove On|Off Off svdhE
Détermine si les cookies de session doivent être supprimés des en-têtes HTTP entrants
SessionCryptoCipher algorithme aes256 svdhX
L'algorithme à utiliser pour le chiffrement de la session
SessionCryptoDriver nom [param[=valeur]]sX
Le pilote de chiffrement à utiliser pour chiffrer les sessions
SessionCryptoPassphrase secret [ secret ... ] svdhX
La clé utilisée pour chiffrer la session
SessionCryptoPassphraseFile nom-fichiersvdX
Le fichier contenant les clés utilisées pour chiffrer la session
SessionDBDCookieName nom attributssvdhE
Nom et attributs du cookie RFC2109 qui contient l'identifiant de session
SessionDBDCookieName2 nom attributssvdhE
Nom et attributs du cookie RFC2965 qui contient l'identifiant de session
SessionDBDCookieRemove On|Off On svdhE
Détermine si les cookies de session doivent être supprimés des en-têtes HTTP entrants
SessionDBDDeleteLabel étiquette deletesession svdhE
La requête SQL à utiliser pour supprimer des sessions de la base de données
SessionDBDInsertLabel étiquette insertsession svdhE
La requête SQL à utiliser pour insérer des sessions dans la base de données
SessionDBDPerUser On|Off Off svdhE
Active une session propre à un utilisateur
SessionDBDSelectLabel étiquette selectsession svdhE
La requête SQL à utiliser pour sélectionner des sessions dans la base de données
SessionDBDUpdateLabel étiquette updatesession svdhE
La requête SQL à utiliser pour mettre à jour des sessions préexistantes dans la base de données
SessionEnv On|Off Off svdhE
Définit si le contenu de la session doit être enregistré dans la variable d'environnement HTTP_SESSION
SessionExclude cheminsvdhE
Définit les préfixes d'URLs pour lesquels une session sera ignorée
SessionExpiryUpdateInterval interval 0 (mise à jour syst +svdhE
Définit le nombre de secondes dont la durée d'expiration d'une session peut changer sans que cette session soit mise à jour
SessionHeader en-têtesvdhE
Importation des mises à jour de session depuis l'en-tête de réponse HTTP spécifié
SessionInclude cheminsvdhE
Définit les préfixes d'URL pour lesquels une session est valide
SessionMaxAge durée de vie maximale 0 svdhE
Définit une durée de vie maximale pour la session en secondes
SetEnv var-env [valeur]svdhB
Définit des variables d'environnement
SetEnvIf attribut regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...svdhB
Définit des variables d'environnement en fonction des attributs de la requête
SetEnvIfExpr expr [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...svdhB
Définit des variables d'environnement en fonction d'une expression ap_expr
SetEnvIfNoCase attribut regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...svdhB
Définit des variables d'environnement en fonction des attributs de la requête sans tenir compte de la casse
SetHandler handler-name|none|expressionsvdhC
Force le traitement des fichiers spécifiés par un gestionnaire particulier
SetInputFilter filtre[;filtre...]svdhC
Définit les filtres par lesquels vont passer les requêtes client et les données POST
SetOutputFilter filtre[;filtre...]svdhC
Définit les filtres par lesquels vont passer les réponses du serveur
SSIEndTag tag "-->" svB
Chaîne qui termine l'élément include
SSIErrorMsg message "[an error occurred +svdhB
Message d'erreur affiché lorsqu'une erreur SSI survient
SSIETag on|off off dhB
Définit si des en-têtes ETags sont générés par le serveur.
SSILastModified on|off off dhB
Définit si des en-têtes Last-Modified sont générés par le serveur.
SSILegacyExprParser on|off off dhB
Active le mode de compatibilité pour les expressions conditionnelles.
SSIStartTag tag "<!--#" svB
Chaîne qui marque le début d'un élément include
SSITimeFormat chaîne de formatage "%A, %d-%b-%Y %H:%M +svdhB
Configuration du format d'affichage des dates
SSIUndefinedEcho chaîne "(none)" svdhB
Chaîne à afficher lorsqu'on tente d'extraire le contenu d'une variable non définie
SSLCACertificateFile file-pathsvE
Fichier contenant une concaténation des certificats de CA codés en PEM pour l'authentification des clients
SSLCACertificatePath chemin-répertoiresvE
Répertoire des certificats de CA codés en PEM pour l'authentification des clients
SSLCADNRequestFile file-pathsvE
Fichier contenant la concaténation des certificats de CA codés en PEM pour la définition de noms de CA acceptables
SSLCADNRequestPath chemin-répertoiresvE
Répertoire contenant des fichiers de certificats de CA codés en PEM pour la définition de noms de CA acceptables
SSLCARevocationCheck chain|leaf|none [flags ...] none svE
Active la vérification des révocations basée sur les CRL
SSLCARevocationFile file-pathsvE
Fichier contenant la concaténation des CRLs des CA codés en PEM pour l'authentification des clients
SSLCARevocationPath chemin-répertoiresvE
Répertoire des CRLs de CA codés en PEM pour l'authentification des clients
SSLCertificateChainFile file-pathsvE
Fichier contenant les certificats de CA du serveur codés en PEM
SSLCertificateFile file-path|certidsvE
Fichier de données contenant les informations de certificat X.509 du serveur codées au format PEM ou identificateur de jeton
SSLCertificateKeyFile file-path|keyidsvE
Fichier contenant la clé privée du serveur codée en PEM
SSLCipherSuite [protocol] cipher-spec DEFAULT (dépend de +svdhE
Algorithmes de chiffrement disponibles pour la négociation au cours de l'initialisation de la connexion SSL
SSLCompression on|off off svE
Permet d'activer la compression au niveau SSL
SSLCryptoDevice moteur builtin sE
Active l'utilisation d'un accélérateur matériel de chiffrement
SSLEngine on|off|optional off svE
Interrupteur marche/arrêt du moteur SSL
SSLFIPS on|off off sE
Coimmutateur du mode SSL FIPS
SSLHonorCipherOrder on|off off svE
Option permettant de classer les algorithmes de chiffrement du serveur par ordre de préférence
SSLInsecureRenegotiation on|off off svE
Option permettant d'activer le support de la renégociation non sécurisée
SSLOCSPDefaultResponder urisvE
Définit l'URI du répondeur par défaut pour la validation OCSP
SSLOCSPEnable on|leaf|off off svE
Active la validation OCSP de la chaîne de certificats du client
SSLOCSPNoverify on|off off svE
Evite la vérification des certificats des répondeurs OCSP
SSLOCSPOverrideResponder on|off off svE
Force l'utilisation de l'URI du répondeur par défaut pour la validation OCSP
SSLOCSPProxyURL urlsvE
Adresse de mandataire à utiliser pour les requêtes OCSP
SSLOCSPResponderCertificateFile filesvE
Fournit un jeu de certificats de confiance du répondeur OCSP avec encodage PEM
SSLOCSPResponderTimeout secondes 10 svE
Délai d'attente pour les requêtes OCSP
SSLOCSPResponseMaxAge secondes -1 svE
Age maximum autorisé pour les réponses OCSP
SSLOCSPResponseTimeSkew secondes 300 svE
Dérive temporelle maximale autorisée pour la validation des réponses OCSP
SSLOCSPUseRequestNonce on|off on svE
Use a nonce within OCSP queries
SSLOpenSSLConfCmd commande valeursvE
Configuration des paramètres d'OpenSSL via son API SSL_CONF
SSLOptions [+|-]option ...svdhE
Configure différentes options d'exécution du moteur SSL
SSLPassPhraseDialog type builtin sE
Méthode utilisée pour entrer le mot de passe pour les clés privées chiffrées
SSLProtocol [+|-]protocole ... all -SSLv3 (jusqu'à +svE
Indique les versions du protocole SSL/TLS disponibles
SSLProxyCACertificateFile file-pathsvpE
Fichier contenant la concaténation des certificats de CA codés en PEM pour l'authentification des serveurs distants
SSLProxyCACertificatePath chemin-répertoiresvpE
Répertoire des certificats de CA codés en PEM pour l'authentification des serveurs distants
SSLProxyCARevocationCheck chain|leaf|none none svpE
Active la vérification des révocations basée sur les CRLs pour l'authentification du serveur distant
SSLProxyCARevocationFile file-pathsvpE
Fichier contenant la concaténation des CRLs de CA codés en PEM pour l'authentification des serveurs distants
SSLProxyCARevocationPath chemin-répertoiresvpE
Répertoire des CRLs de CA codés en PEM pour l'authentification des serveurs distants
SSLProxyCheckPeerCN on|off on svpE
Configuration de la vérification du champ CN du certificat du serveur distant
SSLProxyCheckPeerExpire on|off on svpE
Configuration de la vérification de l'expiration du certificat du serveur distant
SSLProxyCheckPeerName on|off on svpE
Configure la vérification du nom d'hôte dans les certificats serveur distants
SSLProxyCipherSuite [protocol] cipher-spec ALL:!ADH:RC4+RSA:+H +svpE
Algorithmes de chiffrement disponibles pour la négociation lors de l'initialisation d'une connexion SSL de mandataire
SSLProxyEngine on|off off svpE
Interrupteur marche/arrêt du moteur de mandataire SSL
SSLProxyMachineCertificateChainFile nom-fichiersvpE
Fichier de certificats de CA encodés PEM concaténés permettant au mandataire de choisir un certificat
SSLProxyMachineCertificateFile chemin-fichiersvpE
Fichier contenant la concaténation des clés et certificats clients codés en PEM que le mandataire doit utiliser
SSLProxyMachineCertificatePath chemin-répertoiresvpE
Répertoire des clés et certificats clients codés en PEM que le mandataire doit utiliser
SSLProxyProtocol [+|-]protocole ... all -SSLv3 (jusqu'à +svpE
Définit les protocoles SSL disponibles pour la fonction de mandataire
SSLProxyVerify niveau none svpE
Niveau de vérification du certificat du serveur distant
SSLProxyVerifyDepth niveau 1 svpE
Niveau de profondeur maximum dans les certificats de CA lors de la vérification du certificat du serveur distant
SSLRandomSeed contexte source [nombre]sE
Source de déclenchement du Générateur de Nombres Pseudo-Aléatoires (PRNG)
SSLRenegBufferSize taille 131072 dhE
Définit la taille du tampon de renégociation SSL
SSLRequire expressiondhE
N'autorise l'accès que lorsqu'une expression booléenne complexe et arbitraire est vraie
SSLRequireSSLdhE
Interdit l'accès lorsque la requête HTTP n'utilise pas SSL
SSLSessionCache type none sE
Type du cache de session SSL global et inter-processus
SSLSessionCacheTimeout secondes 300 svE
Nombre de secondes avant l'expiration d'une session SSL dans le cache de sessions
SSLSessionTicketKeyFile file-pathsvE
Clé de chiffrement/déchiffrement permanente pour les tickets de session TLS
SSLSessionTickets on|off on svE
Active ou désactive les tickets de session TLS
SSLSRPUnknownUserSeed secret-stringsvE
Source d'aléa pour utilisateur SRP inconnu
SSLSRPVerifierFile file-pathsvE
Chemin du fichier de vérification SRP
SSLStaplingCache typesE
Configuration du cache pour l'agrafage OCSP
SSLStaplingErrorCacheTimeout secondes 600 svE
Durée de vie des réponses invalides dans le cache pour agrafage OCSP
SSLStaplingFakeTryLater on|off on svE
Génère une réponse "tryLater" pour les requêtes OCSP échouées
SSLStaplingForceURL urisvE
Remplace l'URI du serveur OCSP spécifié dans l'extension AIA du certificat
SSLStaplingResponderTimeout secondes 10 svE
Temps d'attente maximum pour les requêtes vers les serveurs OCSP
SSLStaplingResponseMaxAge secondes -1 svE
Age maximum autorisé des réponses OCSP incluses dans la négociation TLS
SSLStaplingResponseTimeSkew secondes 300 svE
Durée de vie maximale autorisée des réponses OCSP incluses dans la négociation TLS
SSLStaplingReturnResponderErrors on|off on svE
Transmet au client les erreurs survenues lors des requêtes OCSP
SSLStaplingStandardCacheTimeout secondes 3600 svE
Durée de vie des réponses OCSP dans le cache
SSLStrictSNIVHostCheck on|off off svE
Contrôle de l'accès des clients non-SNI à un serveur virtuel à base de nom.
SSLUserName nom-varsdhE
Nom de la variable servant à déterminer le nom de l'utilisateur
SSLUseStapling on|off off svE
Active l'ajout des réponses OCSP à la négociation TLS
SSLVerifyClient niveau none svdhE
Niveau de vérification du certificat client
SSLVerifyDepth nombre 1 svdhE
Profondeur maximale des certificats de CA pour la vérification des certificats clients
StartServers nombresM
Nombre de processus enfants du serveur créés au démarrage
StartThreads nombresM
Nombre de threads créés au démarrage
StrictHostCheck ON|OFF OFF svC
Détermine si le nom d'hôte contenu dans une requête doit être explicitement spécifié au niveau du serveur virtuel qui a pris en compte cette dernière.
Substitute s/modèle/substitution/[infq]dhE
Modèle de substition dans le contenu de la réponse
SubstituteInheritBefore on|off on dhE
Modifie l'ordre de fusion des modèles hérités
SubstituteMaxLineLength octets(b|B|k|K|m|M|g|G) 1m dhE
Définit la longueur de ligne maximale
Suexec On|OffsB
Active ou désactive la fonctionnalité suEXEC
SuexecUserGroup Utilisateur GroupesvE
L'utilisateur et le groupe sous lesquels les programmes CGI doivent s'exécuter
ThreadLimit nombresM
Le nombre de threads maximum que l'on peut définir par processus enfant
ThreadsPerChild nombresM
Nombre de threads créés par chaque processus enfant
ThreadStackSize taillesM
La taille en octets de la pile qu'utilisent les threads qui traitent les connexions clients
TimeOut secondes 60 svC
Temps pendant lequel le serveur va attendre certains évènements avant de considérer qu'une requête a échoué
TraceEnable [on|off|extended] on svC
Détermine le comportement des requêtes TRACE
TransferLog fichier|pipesvB
Spécifie l'emplacement d'un fichier journal
TypesConfig chemin-fichier conf/mime.types sB
Le chemin du fichier mime.types
UNCList hostname [hostname...]sC
Définit quels sont les noms d’hôte UNC auxquels le serveur peut accéder
UnDefine nom-variablesC
Invalide la définition d'une variable
UndefMacro nomsvdB
Supprime une macro
UnsetEnv var-env [var-env] ...svdhB
Supprime des variables de l'environnement
Use nom [valeur1 ... valeurN] svdB
Utilisation d'une macro
UseCanonicalName On|Off|DNS Off svdC
Définit la manière dont le serveur détermine son propre nom et son port
UseCanonicalPhysicalPort On|Off Off svdC
Définit la manière dont le serveur détermine son propre port
User utilisateur unix #-1 sB
L'utilisateur sous lequel le serveur va traiter les requêtes
UserDir nom-répertoire [nom-répertoire] ... svB
Chemin des répertoires propres à un utilisateur
VHostCGIMode On|Off|Secure On vX
Détermine si le serveur virtuel peut exécuter des sous-processus, et définit les privilèges disponibles pour ces dernier.
VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...vX
Assigne des privilèges au choix aux sous-processus créés par un serveur virtuel.
VHostGroup identifiant-groupe-unixvX
Définit l'identifiant du groupe sous lequel s'exécute un serveur virtuel.
VHostPrivs [+-]?nom-privilège [[+-]?nom-privilège] ...vX
Assigne des privilèges à un serveur virtuel.
VHostSecure On|Off On vX
Détermine si le serveur s'exécute avec une sécurité avancée pour les serveurs virtuels.
VHostUser identifiant-utilisateur-unixvX
Définit l'identifiant utilisateur sous lequel s'exécute un serveur virtuel.
VirtualDocumentRoot répertoire-interpolé|none none svE
Permet une configuration dynamique de la racine des documents d'un serveur virtuel donné
VirtualDocumentRootIP répertoire-interpolé|none none svE
Configuration dynamique de la racine des documents pour un serveur virtuel donné
<VirtualHost adresse IP[:port] [adresse IP[:port]] ...> ... </VirtualHost>sC
Contient des directives qui ne s'appliquent qu'à un nom d'hôte spécifique ou à une adresse IP
VirtualScriptAlias répertoire-interpolé|none none svE
Configuration dynamique du répertoire des scripts CGI pour un serveur virtuel donné
VirtualScriptAliasIP répertoire-interpolé|none none svE
Configuration dynamique du répertoire des scripts CGI pour un serveur virtuel donné
WatchdogInterval time-interval[s] 1 sB
Intervalle Watchdog en secondes
XBitHack on|off|full off svdhB
Interprète les directives SSI dans les fichiers dont le bit d'exécution est positionné
xml2EncAlias jeu-de-caractères alias [alias ...]sB
Définit des alias pour les valeurs d'encodage
xml2EncDefault nomsvdhB
Définit un encodage par défaut à utiliser lorsqu'aucune information ne peut être automatiquement détectée
xml2StartParse élément [élément ...]svdhB
Indique à l'interpréteur à partir de quelle balise il doit commencer son traitement.

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_connect.html.ja.utf80000664000175100017510000002232014743132254023507 0ustar covenercovener mod_proxy_connect - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_proxy_connect

翻訳済み言語:  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:CONNECT リクエストを扱う mod_proxy 用の拡張
ステータス:Extension
モジュール識別子:proxy_connect_module
ソースファイル:mod_proxy_connect.c

概要

本モジュールには mod_proxy必要ですCONNECT HTTP メソッドをサポートします。 このメソッドは主にプロキシに SSL リクエストを通す (訳注: SSLトンネリング)に使われます。

CONNECT リクエストを扱えるようにするには mod_proxymod_proxy_connect をサーバに組み込む必要があります。

警告

安全なサーバにするまでプロキシ機能は有効にしないでください。 オープンプロキシサーバはあなた自身のネットワークにとっても、 インターネット全体にとっても危険です。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

AllowCONNECT ディレクティブ

説明:Ports that are allowed to CONNECT through the proxy
構文:AllowCONNECT port[-port] [port[-port]] ...
デフォルト:AllowCONNECT 443 563
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_proxy_connect
互換性:Moved from mod_proxy in Apache 2.3.5. Port ranges available since Apache 2.3.7.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_ajp.html.ja.utf80000664000175100017510000010037414743132254022636 0ustar covenercovener mod_proxy_ajp - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_proxy_ajp

翻訳済み言語:  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:mod_proxy で AJP をサポートするためのモジュール
ステータス:Extension
モジュール識別子:proxy_ajp_module
ソースファイル:mod_proxy_ajp.c

概要

本モジュールには mod_proxy必要ですApache JServ Protocol version 1.3 (以降 AJP13) をサポートします。

AJP13 プロトコルを扱えるようにするには mod_proxymod_proxy_ajp をサーバに組み込む必要があります。

警告

安全なサーバにするまでプロクシ機能は有効にしないでください。 オープンプロキシサーバはあなた自身のネットワークにとっても、 インターネット全体にとっても危険です。

Support Apache!

トピック

ディレクティブ

このモジュールにディレクティブはありません。

Bugfix checklist

参照

top

プロトコルの概要

AJP13 プロトコルはパケット指向です。 可読なプレーンテキスト形式ではなくバイナリ形式になったのは、 おそらくパフォーマンス上の理由によります。 ウェブサーバはサーブレットコンテナと TCP コネクションで通信します。 ソケット生成は重い処理なので、負荷を減らすために、サーブレットコンテナとの TCP 接続を維持し、複数のリクエスト・レスポンス処理サイクルに対して一つの コネクションを使いまわすようになっています。

あるリクエストにコネクションが割り当てられると、その処理サイクルが 完了するまで他のものに使われることはありません。 つまりコネクション上では、リクエストの同時処理は行われません。 このため、コネクション両端での実行するコードを簡潔にできる一方で、 同時に開くコネクションは多くなっています。

サーブレットコンテナへのコネクションを開いた後は、コネクションの状態は 次のどれかになります:

コネクションが特定のリクエストにアサインされると、基本的な情報 (例えば HTTP ヘッダ等) が圧縮された形 (例えば通常の文字列は整数にエンコードされます) で転送されます。詳細は下記の「リクエストパケットの構造」を参照してください。 リクエストにボディが存在 (content-length > 0) すれば、 基本的な情報の直後に別パケットで転送されます。

この時点でおそらく、サーブレットコンテナは処理を開始できるようになります。 ですので、次のメッセージをウェブサーバに戻して知らせられるようになります。

個々のメッセージはそれぞれ異なるデータパケット形式になっています。 後述の「レスポンスパケットの構造」を参照してください。

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)
Byte 0 1 2 3 4...(n+3)
Contents 0x12 0x34 データ長 (n) Data
パケット形式 (Container->Server)
Byte 0 1 2 3 4...(n+3)
Contents A B データ長 (n) Data

ほとんどのパケットで、ペイロードの最初のバイトがメッセージの型をエンコード しています。例外はサーバからコンテナに送られるリクエストボディパケットです ――これらは標準的なパケット形式 (0x1234 とパケット長) ですが、その後に続くプレフィックスコードがありません。

ウェブサーバは次のメッセージをサーブレットコンテナに送出できます。

コード パケットの型 意味
2 Forward Request リクエスト処理サイクルを後続のデータとともに開始する。
7 Shutdown ウェブサーバがコンテナに、コンテナを終了するように伝える。
8 Ping ウェブサーバがコンテナに制御を受け持つように伝える (セキュアログインフェーズ) 。
10 CPing ウェブサーバがコンテナに CPong で即座に応答するように伝える。
none Data サイズ (2 バイト) とそれに続くボディデータ。

基本的なセキュリティを確保するため、ホストされているマシンと同一の マシンからのリクエストに対してのみ、コンテナは実際に Shutdown を実行します。

最初の Data パケットは、Forward Request の直後にウェブサーバから送られます。

サーブレットコンテナはウェブサーバに、次のタイプのメッセージを送ることが できます :

コード パケットの型 意味
3 Send Body Chunk サーブレットコンテナからウェブサーバに (そしておそらくそのままブラウザに)、ボディのチャンクを送る。
4 Send Headers サーブレットコンテナからウェブサーバに (そしておそらくそのままブラウザに) レスポンスヘッダを送る。
5 End Response レスポンス (つまりリクエスト処理サイクル) 終了の目印を送る。
6 Get Body Chunk まだ全て転送されていない場合、残っているリクエストのデータを受け取る。
9 CPong 応答 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 ValueType Of ValueNote
?context0x01-未実装
?servlet_path0x02-未実装
?remote_user0x03String
?auth_type0x04String
?query_string0x05String
?jvm_route0x06String
?ssl_cert0x07String
?ssl_cipher0x08String
?ssl_session0x09String
?req_attribute0x0AStringName (the name of the attribute follows)
?ssl_key_size0x0BInteger
are_done0xFF-request_terminator

contextservlet_path は現在の C の コードではセットされていません。また、ほとんどの Java のコードでも、 このフィールドで何が送られても無視されます (これらのコードの後に文字列が 送られると壊れるものもあります)。 これがバグなのか、単に未実装なのか、歴史的経緯で残っているコードなのか 分かりませんが、コネクションの両側ともで見当たりません。

remote_userauth_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)
  chunk_terminator (byte) Ox00

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 の通信にはあります (例 200OK)。レスポンスヘッダ名は、 リクエストヘッダ名と同様の方法でエンコードされます。 コードと文字列の判別方法の詳細に関しては、上記の 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) を送り返します。

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_request.html.tr.utf80000664000175100017510000002327714743132254022354 0ustar covenercovener mod_request - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_request

Mevcut Diller:  en  |  fr  |  tr 

Açıklama:HTTP istek gövdelerini işleme sokup kullanılabilir kılan süzgeçler
Durum:Temel
Modül Betimleyici:request_module
Kaynak Dosyası:mod_request.c
Uyumluluk:Apache 2.3 ve sonrasında mevcuttur.
Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

KeptBodySize Yönergesi

Açıklama:mod_include gibi süzgeçler tarafından kullanılma olasılığına karşı istek gövdesi iptal edilmek yerine belirtilen azami boyutta tutulur.
Sözdizimi:KeptBodySize azami_bayt_sayısı
Öntanımlı:KeptBodySize 0
Bağlam:dizin
Durum:Temel
Modül:mod_request

Normal şartlar altında, durağan dosyaların öntanımlı eylemcileri gibi istek eylemcileri gerek kalmadığında istek gövdesini iptal ederler. Sonuç olarak, mod_include gibi süzgeçler, özgün istek (süzme işlemi gerçekleştikten sonra artık gerekmediğinden istek gövdesini iptal eden) bir POST isteği olsa bile, GET isteklerinin yapılmasına sadece diğer URL’lerin alt istekler olarak içerilmesi şartıyla izin verir.

Bu yönergede belirtilen değer sıfırdan büyük olduğunda, istek eylemciler, istek gövdesini iptal etmek yerine süzgeçler tarafından kullanılmak üzere belirtilen azami boyuta ayarlarlar. mod_include süzgecinin kullanılması durumunda, bir durağan shtml dosyası için bir POST isteği, ardından gelen isteklerin, önceki gibi GET istekleri değil, POST istekleri olmasına yol açacaktır.

Bu özellik, mod_include kullanılarak, karmaşık HTML sayfalarının ve uygulamalarının küçük küçük bileşenlere bölünüp sonra da sayfa yapısıyla birlikte sarmalanarak birleştirilmesini mümkün kılar. Bileşenler, CGI programları veya betik dilleri biçiminde olabileceği gibi, mod_proxy kullanarak başka bir sunucudaki URL uzayına ters vekil URL’ler şeklinde bile olabilir.

Bilginize: İstekler tamamlanana kadar alınan istekler geçici RAM içinde biriktirilir. Sonuç olarak, bahsi geçen yükü karşılamak için yeterince RAM’in mevcut olması gerekir. Bu yönergeyi kullanmakla, istek gövdesini saklamaya yetecek olası en düşük değerle bile URL uzayınız için gereken yeri kısıtlamış olursunuz.

Eğer isteğin uzunluğu bu yönerge ile ayrılan azami uzunluğu aşarsa sunucu yanıt olarak 413 Request Entity Too Large (413 İstenen Öğe Çok Büyük) hatasını döndürür.

İstek gövdesini iptal etmek yerine kendi amaçları doğrultusunda bunları biriktiren mod_cgi gibi eylemciler bu yönergeyi dikkate almazlar.

Ayrıca bakınız:

Mevcut Diller:  en  |  fr  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_setenvif.html.ko.euc-kr0000664000175100017510000004264014743132254022766 0ustar covenercovener mod_setenvif - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_setenvif

ֽ ƴմϴ. ֱٿ ϼ.
:û ݿ ȯ溯 Ѵ
:Base
:setenvif_module
ҽ:mod_setenvif.c

mod_setenvif û ǥĿ شϴ η ȯ溯 Ѵ. ٸ κ ൿ Ҷ ȯ溯 ִ.

Ͽ þ óѴ. ׷ MSIE ƴ϶ mozilla netscape ϴ Ʒ þ Բ ִ.

BrowserMatch ^Mozilla netscape
BrowserMatch MSIE !netscape

Support Apache!

þ

Bugfix checklist

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

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. û ϳ:
    • 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) ȣƮ κ
  3. û ȯ溯 ̸. ׷ SetEnvIf þ þ ˻ ִ. SetEnvIf[NoCase] þ ȯ溯 ˻ ִ. ''̶ ( ) Ȥ þ Ѵ. û ƴϰ ǥ ƴ attribute ȯ溯 Ѵ.

ι° ƱԸƮ (regex) Perl ȣȯ ǥ̴. ̴ POSIX.2 egrep ǥİ ϴ. regex attribute ϸ ƱԸƮ óѴ.

ƱԸƮ () ̴. ̴

  1. varname, Ȥ
  2. !varname, Ȥ
  3. varname=value

ù° ´ "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

SetEnvIfExpr þ

:Sets environment variables based on an ap_expr expression
:
:ּ, ȣƮ, directory, .htaccess
:Base
:mod_setenvif

Documentation not yet translated. Please see English version of document.

top

SetEnvIfNoCase þ

:ҹڸ ʰ û ȯ溯 Ѵ
:SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...
:ּ, ȣƮ, directory, .htaccess
Override ɼ:FileInfo
:Base
:mod_setenvif

SetEnvIfNoCase ǹ̻ SetEnvIf þ , ҹڸ ʰ ǥ ã´. :

SetEnvIfNoCase Host Apache\.Org site=apache

HTTP û Host: Apache.Org, apache.org ϸ site ȯ溯 "apache" Ѵ.

:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_actions.html.de0000664000175100017510000003344314744525602021402 0ustar covenercovener mod_actions - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Apache-Modul mod_actions

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

Diese Übersetzung ist möglicherweise nicht mehr aktuell. Bitte prüfen Sie die englische Version auf die neuesten Änderungen.
Beschreibung:Dieses Modul ermöglicht die Ausführung von CGI-Skripten in Abhängigkeit von Medientypen und Anfragemethoden.
Status:Basis
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.

Support Apache!

Direktiven

Bugfix checklist

Siehe auch

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:Basis
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:Basis
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  |  fr  |  ja  |  ko 

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/prefork.html.de0000664000175100017510000004023214744525602020545 0ustar covenercovener prefork - Apache HTTP Server Version 2.4
<-
Apache > HTTP-Server > Dokumentation > Version 2.4 > Module

Apache-MPM prefork

Verfügbare Sprachen:  de  |  en  |  fr  |  ja  |  tr 

Diese Übersetzung ist möglicherweise nicht mehr aktuell. Bitte prüfen Sie die englische Version auf die neuesten Änderungen.
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.

Support Apache!

Themen

Direktiven

Bugfix checklist

Siehe auch

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  |  fr  |  ja  |  tr 

top

Kommentare

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_setenvif.html.tr.utf80000664000175100017510000005444514743132254022510 0ustar covenercovener mod_setenvif - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_setenvif

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.
Açıklama:Ortam değişkenlerinin isteğin özelliklerine uygun olarak atanmasını sağlar
Durum:Temel
Modül Betimleyici:setenvif_module
Kaynak Dosyası:mod_setenvif.c

Özet

mod_setenvif modülü dahili ortam değişkenlerinin isteğin farklı bileşenlerinin belirttiğiniz düzenli ifade ile eşleşmesine bağlı olarak atanmasını mümkün kılar. Bu ortam değişkenleri sunucunun çeşitli kısımlarında yapılacak eylemlerin yanında CGI betiklerinde ve SSI sayfalarında kullanılabilir hale gelmelerine karar verilirken kullanılır.

Yönergeler yapılandırma dosyasında yer aldıkları sıraya göre ele alınırlar. Böylece daha karmaşık dizilimler kullanılabilir, bu örnekteki tarayıcı Mozilla ise netscape ortam değişkeni atanmakta, MSIE ise atanmamaktadır.

BrowserMatch ^Mozilla netscape
BrowserMatch MSIE !netscape

mod_autoindex ile dizin listesi oluşturulması veya bir DirectoryIndex için yol aranması gibi bir dahili alt istek için sunucu yol araması yaparken isteklere özgü ortam değişkenleri alt istekler tarafından miras alınMAZ. Buna ek olarak, mod_setenvif modülünün devreye girdiği API fazlarından dolayı yapılan alt isteklerde SetEnvIf yönergeleri ayrı ayrı değerlendirilMEZ.

Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

BrowserMatch Yönergesi

Açıklama:Ortam değişkenlerini HTTP kullanıcı arayüzüne göre belirler.
Sözdizimi:BrowserMatch düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_setenvif

BrowserMatch yönergesi SetEnvIf yönergesinin özel bir halidir ve ortam değişkenlerine User-Agent HTTP istek başlığının değerine göre atama yapar. Aşağıdaki iki satır aynı etkiye sahiptir:

BrowserMatch Robot is_a_robot
SetEnvIf User-Agent Robot is_a_robot

Başka örnekler:

BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
BrowserMatch MSIE !javascript
top

BrowserMatchNoCase Yönergesi

Açıklama:Ortam değişkenlerini HTTP kullanıcı arayüzünün harf büyüklüğüne duyarsız eşleşmelerine bağlı olarak belirler.
Sözdizimi:BrowserMatchNoCase düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_setenvif

BrowserMatchNoCase yönergesi sözdizimsel ve anlamsal olarak BrowserMatch yönergesinin eşdeğeridir. Ancak, eşleşmelerde harf büyüklüğüne duyarsızdır. Örnek:

BrowserMatchNoCase mac platform=macintosh
BrowserMatchNoCase win platform=windows

BrowserMatch ve BrowserMatchNoCase yönergeleri SetEnvIf ve SetEnvIfNoCase yönergelerinin özel halleridir. Bu bakımda aşağıdaki iki satır aynı etkiye sahiptir:

BrowserMatchNoCase Robot is_a_robot
SetEnvIfNoCase User-Agent Robot is_a_robot
top

SetEnvIf Yönergesi

Açıklama:Ortam değişkenlerini isteğin özniteliklerine göre atar.
Sözdizimi:SetEnvIf öznitelik düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_setenvif

SetEnvIf yönergesi ortam değişkenlerini isteğin özniteliklerine göre tanımlar. İlk bileşen olarak belirtilen öznitelik şu dört şeyden biri olabilir:

  1. Bir HTTP istek başlığı alanı (ayrıntılı bilgi için bak: RFC2616); örneğin: Host, User-Agent, Referer ve Accept-Language. Bir düzenli ifade kullanılarak birden fazla istek başlığı belirtilebilir.
  2. İsteğin aşağıdaki bileşenlerinden biri:
    • Remote_Host - isteği yapan istemcinin konak ismi (varsa)
    • Remote_Addr -isteği yapan istemcinin IP adresi
    • Server_Addr - isteği alan sunucunun IP adresi (sadece 2.0.43 sonrası sürümler için)
    • Request_Method - kullanılan yöntemin ismi (GET, POST, vs.)
    • Request_Protocol - İsteğin yapıldığı protokolün ismi ve numarası ("HTTP/0.9", "HTTP/1.1" gibi)
    • Request_URI - HTTP istek satırında belirtilen özkaynak; genellikle sorgu dizgesi olmaksızın şema ve konak ismini içeren bir URL parçasıdır. Sorgu dizgeleriyle eşleşmeler hakkında ayrıntılı bilgi edinmek için mod_rewrite modülünün RewriteCond yönergesinin açıklamasına bakınız.
  3. İstek ile evvelce ilişkilendirilmiş bir ortam değişkeninin ismi. Bu sayede önceki bir eşleşmenin sonucuna karşı yeni bir sınama yapma imkanı ortaya çıkar. Böyle bir sınama için sadece evvelce SetEnvIf[NoCase] yönergeleri ile yapılmış atamalardaki ortam değişkenleri kullanılabilir. ‘Evvelce’ derken, sunucu genelinde veya bölüm içinde bu yönergeden önce yer alan SetEnvIf[NoCase] yönerge satırları kastedilmektedir. Ortam değişkenlerinin dikkate alınabilmesi için istek öznitelikleri arasında hiçbir eşleşme olmaması ve öznitelik olarak bir düzenli ifade belirtilmemiş olması gerekir.

İkinci bileşen (düzifd) bir düzenli ifadedir. düzifd ile öznitelik eşleştiği takdirde yönergenin kalan bileşenleri değerlendirmeye alınır.

Kalan bileşenler atanacak ortam değişkenlerinin isimleri ve isteğe bağlı olarak bunlara atanacak değerlerden oluşur. Bunlar şöyle belirtilebilir:

  1. değişken-adı veya
  2. !değişken-adı ya da
  3. değişken-adı=değer

İlk biçemde değişkene "1" değeri atanır. İkincisinde atanmış bir değişken atanmamış yapılır. Üçüncüsünde ise değişkene belirtilen değer bire bir atanır. 2.0.51 sürümünden itibaren Apache httpd parantezli düzenli ifadelerin sonuçları ile değiştirilmek üzere value içinde $1..$9 gösterimleri tanınmaktadır. $0 bu kalıp ile eşleşen tüm dizgeye erişir.

SetEnvIf Request_URI "\.gif$" nesne_bir_resim=gif
SetEnvIf Request_URI "\.jpg$" nesne_bir_resim=jpg
SetEnvIf Request_URI "\.xbm$" nesne_bir_resim=xbm

SetEnvIf Referer belgeler\.alanismi\.example\.com dahili_site_istendi

SetEnvIf object_is_image xbm XBIT_PROCESSING=1

SetEnvIf Request_URI "\.(.*)$" EXTENSION=$1

SetEnvIf ^TS  ^[a-z]  TS_VAR

İlk üçünde istek bir resim dosyası için yapılmışsa nesne_bir_resim ortam değişkeni atanmakta, dördüncüsünde istenen sayfa belgeler.alanismi.example.com adlı sitede bulunuyorsa dahili_site_istendi ortam değişkeni atanmaktadır.

Son örnekte ise istekte "TS" ile başlayıp [a-z] arasındaki karakterlerle devam eden bir başlık alanı varsa TS_VAR ortam değişkeni atanmaktadır.

Ayrıca bakınız:

top

SetEnvIfExpr Yönergesi

Açıklama:Bir ap_expr ifadesine dayanarak ortam değişkenlerine değer atar
Sözdizimi:SetEnvIfExpr ifade [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_setenvif

SetEnvIfExpr yönergesi bir <If> ap_expr ifadesine dayanarak ortam değişkenlerine değer atar. Bu ifadeler çalışma anında değerlendirilirerek SetEnvIf yönergesindeki gibi ort-değişkenine uygulanır.

SetEnvIfExpr "tolower(req('X-Sendfile')) == 'd:\images\very_big.iso')" iso_delivered

Burada uygulamamızın her X-Sendfile göndermeye çalışmasında ortam değişkenine iso_delivered değeri atanmaktadır.

Uzak IP adresi RFC 1918'e göre özel bir adres ise rfc1918 değişkenine 1 atanması daha kullanışlı bir örnek olurdu:

SetEnvIfExpr "-R '10.0.0.0/8' || -R '172.16.0.0/12' || -R '192.168.0.0/16'" rfc1918

Ayrıca bakınız:

top

SetEnvIfNoCase Yönergesi

Açıklama:Ortam değişkenlerini isteğin özniteliklerinde harf büyüklüğüne bağlı olmaksızın yapılmış tanımlara göre atar.
Sözdizimi:SetEnvIfNoCase öznitelik düzifd [!]ort-değişkeni[=değer] [[!]ort-değişkeni[=değer]] ...
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_setenvif

SetEnvIfNoCase yönergesi sözdizimsel ve anlamsal olarak SetEnvIf yönergesinin eşdeğeridir. Ancak, eşleşmelerde harf büyüklüğüne duyarsızdır. Örnek:

SetEnvIfNoCase Host Example\.Org site=example

Burada, Host: HTTP istek başlığında Example.Org, example.org veya harf büyüklüğünce farklı benzerleri belirtilmişse site ortam değişkenine "example" değeri atanmaktadır.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_so.html.ko.euc-kr0000664000175100017510000003062314743132254021562 0ustar covenercovener mod_so - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_so

ֽ ƴմϴ. ֱٿ ϼ.
:Ҷ Ȥ Ҷ డ ڵ оδ
:Extension
:so_module
ҽ:mod_so.c
: (׻ ϴ) Base ̴.

ü ġ ü (DSO) Ͽ ٽ ʰ ߿ о ִ.

о ڵ, н (.so Ȯڸ ) Ϲ ṵ̈,  .so Ȥ .dll Ȯڸ .

ġ 1.3 ġ 2.0 . ġ 2.0 о̰ų ġ Ϸ ؾ Ѵ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_speling.html.ko.euc-kr0000664000175100017510000002740214743132254022603 0ustar covenercovener mod_speling - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_speling

ֽ ƴմϴ. ֱٿ ϼ.
:ڰ ҹڸ ߸ ϰų Ʋ ѹ Ͽ ߸ URL ġ õѴ
:Extension
:speling_module
ҽ:mod_speling.c

Ʋų ҹڸ ߸ Ͽ ġ û 찡 ִ. ٸ û شϴ ã´. û 丮 ȿ ִ û ̸ ҹ ( ÷ / / ü Ȥ ߸ ) ѹ Ʋ ָ Ѵ. ̷ .

丮 캻 Ŀ,

Support Apache!

þ

Bugfix checklist

top

CheckBasenameMatch þ

:Also match files with differing file name extensions.
:CheckBasenameMatch on|off
⺻:CheckBasenameMatch On
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Options
:Extension
:mod_speling
:Available in httpd 2.4.50 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

CheckCaseOnly þ

:Limits the action of the speling module to case corrections
:
:ּ, ȣƮ, directory, .htaccess
:Extension
:mod_speling

Documentation not yet translated. Please see English version of document.

top

CheckSpelling þ

: Ѵ
:CheckSpelling on|off
⺻:CheckSpelling Off
:ּ, ȣƮ, directory, .htaccess
Override ɼ:Options
:Extension
:mod_speling
:ġ 1.1 CheckSpelling Ͽ, ҹڰ ٸ 츸 ó ־. ġ 1.3 ġ Ϻΰ Ǿ. ġ 1.3.2 CheckSpelling þ "ּ" "ȣƮ" ҿ ־.

þ 뿩θ Ѵ. Ѵٸ ϶

DAV ϴ 丮 mod_speling ϸ ȵȴ. εϷ doc43.html ϰ doc34.html Ϸ ̷Ʈϴ , DAV ҽ ϸ " " õϱ ̴.

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_so.html.tr.utf80000664000175100017510000003601214743132254021274 0ustar covenercovener mod_so - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_so

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:Modüllerin ve çalıştırılabilir kodun sunucunun başlatılması veya yeniden başlatılması sırasında yüklenmesini sağlar.
Durum:Eklenti
Modül Betimleyici:so_module
Kaynak Dosyası:mod_so.c
Uyumluluk:Windows için bu bir temel modüldür (sunucu bunu daima içerir).

Özet

Seçilen işletim sistemleri üzerinde bu modül Apache HTTP Sunucusunun yeniden derlenmesini gerektirmeden modüllerin Devingen Paylaşımlı Nesne (DSO) mekanizması üzerinden kullanılabilmesini sağlar.

Unix’te yüklenen kod genellikle paylaşımlı nesne dosyalarından (.so uzantılı dosyalar), Windows’ta ise ya .so ya da .dll uzantılı dosyalardan gelir.

Uyarı

Apache HTTP Sunucusunun ana sürümlerinden biri (1.3, 2.0, 2.2, 2.4 gibi) için derlenmiş modüller genelde bir diğerinde çalışmaz. Genellikle aralarında API değişikliği sözkonusu olduğundan çalışması için modüllerde yeni sürüme göre değişiklik yapılması gerekir.

Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Yüklenebilir Modüllerin Windows için Oluşturulması

Bilginize

Windows üzeinde yüklenebilir dosyalar genelde .dll sonekini alırlar. Apache httpd modülleri ise diğer platformlardaki gibi mod_filanca.so biçeminde isimlendirilmektedir. Bununla birlikte, üçüncü parti modüllerden bazılarının (PHP gibi) hala .dll sonekini kullandığı görülmektedir.

mod_so modülü ApacheModuleFoo.dll biçeminde isimlendirilmiş modülleri hala yüklemekteyse de yeni adlandırma uzlaşımı tercih edilmelidir. Yüklenebilir modülleri 2.0’a dönüştürüyorsanız, lütfen isimlerini de 2.0 uzlaşımına uygun hale getiriniz.

Apache httpd modül programlama arayüzü Unix ve Windows sürümleri arasında değişiklik göstermez. Unix için kullanılan çoğu modül hiç değişiklik yapmadan ya da çok küçük bir değişiklikle Windows’ta da çalışmaktadır. Çalışmayanlar Unix platformunun sahip olduğu ancak Windows platformunun sahip olmadığı nitelikleri kullanan modüllerdir.

Bir modül Windows’ta çalıştığı zaman, sunucuya iki şekilde yüklenebilir. Unix’te olduğu gibi, doğrudan sunucunun içinde derlenebilir. Windows için hazırlanan Apache httpd paketi, Unix için geçerli olan Configure betiğini içermediğinden modülün kaynak dosyası ApacheCore proje dosyasına, sembolleri de os\win32\modules.c dosyasına eklenmelidir.

İkinci yol ise modülü bir paylaşımlı kütüphane olarak çalışma anında LoadModule yönergesi ile yüklemek için bir DLL olarak derlemektir. Bu DLL modüller dağıtılabilir ve sunucuyu yeniden derlemek gerekmeksizin her Windows için Apache httpd kurulumunda çalışabilir.

Bir modül DLL’i oluşturmak için modülün kaynak dosyasında küçük bir değişiklik yapmak gerekir: Modül kaydının daha sonra oluşturulacak olan DLL’den ihraç edilebilmesi gerekir (aşağıya bakınız). Bunu yapmak için modülün modül kaydı tanımına (Apache httpd başlık dosyalarında tanımlanmış olan) AP_MODULE_DECLARE_DATA eklenmelidir. Örneğin, modülünüz

module foo_module;

diye bir satır içeriyorsa bunu,

module AP_MODULE_DECLARE_DATA foo_module;

olarak değiştirmelisiniz. Bunun yalnız Windows üzerinde etkili olduğunu ve Unix için modül kodunda bir değişiklik gerekmediğini unutmayınız. Ayrıca, .DEF dosyaları hakkında bilgi sahibi iseniz modül kodunda değişiklik yapmak yerine modül kaydını bu yöntemle de ihraç edebilirsiniz.

Artık modülü içeren bir DLL oluşturmaya hazırsınız. Bunu, libhttpd.dll paylaşımlı kütüphanesi derlenirken oluşturulan libhttpd.lib ihraç kütüphanesi ile ilintilemeniz gerekecektir. Ayrıca, Apache httpd başlık dosyalarının doğru konumlandığından emin olmak için derleyici seçeneklerinde değişiklik yapmanız gerekebilir. Bu kütüphaneyi sunucunuzun kök dizini altındaki modules dizininde bulabilirsiniz. En iyisi derleme ortamının doğru yapılandırıldığından emin olmak için ya ağaçta mevcut modüllerden birinin .dsp dosyasını gaspedersiniz ya da kendi .dsp dosyanızın ilintileme seçenekleriyle derleyicininkileri karşılaştırırsınız.

Artık modülünüzün DLL sürümünü oluşturmalısınız. DLL’i sunucunuzun kök dizininin altında bulunan modules dizinine yerleştirdikten sonra LoadModule yönergesi ile sunucunuza yükleyebilirsiniz.

top

LoadFile Yönergesi

Açıklama:Belirtilen nesne dosyasını veya kütüphaneyi sunucu ile ilintiler.
Sözdizimi:LoadFile dosya-ismi [dosya-ismi] ...
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_so

LoadFile yönergesi ismi belirtilen kütüphaneleri veya nesne dosyalarını sunucu başlatılırken veya yeniden başlatılırken sunucu ile ilintiler. Yönerge, bazı modüllerin çalışması sırasında gereken ek kodların yüklenmesi için kullanılır. dosya-ismi olarak mutlak bir dosya yolu belirtilebileceği gibi ServerRoot’a göreli bir dosya yolu da belirtilebilir.

Örnek:

LoadFile libexec/libxmlparse.so
top

LoadModule Yönergesi

Açıklama:Belirtilen nesne dosyasını veya kütüphaneyi sunucu ile ilintiler ve etkin modül listesine ekler.
Sözdizimi:LoadModule modül dosya-ismi
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_so

LoadModule yönergesi dosya-ismi ile belirtilen nesne dosyasını veya kütüphaneyi sunucu ile ilintiler ve etkin modül listesine belirtilen modül ismiyle ekler. modül, modülün kaynak dosyasında module türündeki tek harici değişkenin ismi olup modül belgelerinde Modül Betimleyici olarak geçer.

Örneğin,

LoadModule status_module modules/mod_status.so

satırı ile ismi belirtilen dosya ServerRoot dizini altındaki modules alt dizininden yüklenir.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directive-dict.html.es0000664000175100017510000004674614743132254022027 0ustar covenercovener Términos que se Usan para Describir Directivas - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4

Términos que se Usan para Describir Directivas

Idiomas disponibles:  en  |  es  |  fr  |  ja  |  ko  |  tr 

Este documento describe los términos que se usan para describir cada directiva de configuración de Apache.

Support Apache!

Consulte también

top

Descripción

Una breve descripción del propósito de la directiva.

top

Sintaxis

Indica el formato de la directiva tal y como aparecería en un fichero de configuración. Esta sintaxis es muy específica de cada directiva, y se describe con detalle en la definición de la directiva. Generalmente, el nombre de la directiva va seguido de una serie de uno o más parámetros separados por un espacio. Si un parámetro contiene un espacio, éste debe especificarse entre comillas dobles. Los parámetros opcionales van especificados entre corchetes. Donde un parámetro puede tener uno o más valores, los valores posibles se separan con barras verticales "|". El Texto Literal se muestra con la fuente por defecto, mientras que los distintos tipos de parámetros para los que una sustitución resulta necesaria son enfatizados. Las directivas que pueden tomar una lista variada de parámetros acaban en "..." indicando que el último parámetro se repite.

Las Directivas usan un gran número de diferentes tipos de parámetros. A continuación definimos algunos de los más comunes.

URL
Un Localizador de Recursos Uniforme, incluye un esquema, nombre de host, y un path opcional como en http://www.example.com/path/to/file.html
Ruta de URL
La parte de una url que sigue al esquema y el nombre de host como en /path/to/file.html. El url-path representa una vista-web de un recurso, en contraposición a una vista de sistema-de-ficheros.
Ruta del Fichero
La ruta a un fichero en el sistema de ficheros local que comienza desde el directorio raíz como en /usr/local/apache/htdocs/path/to/file.html. A menos que se especifique, una ruta de fichero que no comienza con una barra "/" se tratará como una ruta relativa a ServerRoot.
Ruta del Directorio
La ruta a un directorio en el sistema de ficheros local que comienza con el directorio ráiz como en /usr/local/apache/htdocs/path/to/.
Nombre del Fichero
El nombre de un fichero sin ir acompañado de información de la ruta como en file.html.
regex
Una expresión regular compatible con Perl. La definición de directiva especificará contra qué se compara la regex.
extensión
En general, esta es la parte del nombre de fichero que sigue al último punto. Sin embargo, Apache reconoce múltiples extensiones de fichero, así que si un nombre de fichero contiene más de un punto, cada parte separada por un punto del nombre de fichero después del primer punto es una extensión. Por ejemplo, el nombre de fichero file.html.en contiene dos extensiones: .html y .en. Para las directivas de Apache, podrá especificar la extensiones con o sin el punto inicial. Además, las extensiones no son sensibles a mayúsculas o minúsculas.
Tipo MIME
Un método de describir el formato de un fichero que está formado por un tipo de formato mayor y un tipo de formato menor, separados de de una barra como en text/html.
Variable de Entorno
El nombre de una variable de entorno definida en el proceso de configuración de Apache. Tenga en cuenta que esto no es necesariamente lo mismo que la variable de entorno de un sistema operativo. Vea la documentación de variable de entorno para más detalles.
top

Por defecto

Si la directiva tiene un valor por defecto (p.ej., si la omite de la configuración completamente, el servidor Web Apache se comportará como si la hubiera configurado con un valor en particular), se describe aquí. Si no tiene valor por defecto, esta sección debería indicar "Ninguno". Tenga en cuenta que el valor por defecto listado aquí no es necesariamente el mismo que el valor que toma la directiva en el httpd.conf por defecto distribuido con el servidor.

top

Contexto

Esto indica dónde se acepta la directiva en los ficheros de configuración. Es una lista separada por comas para uno o más de los siguientes valores:

server config
Esto indica que la directiva puede usarse en los ficheros de configuración del servidor (p.ej., httpd.conf), pero not dentro de cualquier contenedor <VirtualHost> o <Directory>. No se permite en ficheros .htaccess de ninguna manera.
virtual host
Este contexto significa que la directiva puede aparecer dentro de un contenedor <VirtualHost> en el fichero de configuración del servidor.
directory
Una directiva marcada como válida en este contexto puede usarse dentro de contenedores <Directory>, <Location>, <Files>, <If>, <Proxy> en los ficheros de configuración del servidor, sujeta a las restricciones destacadas en las Secciones de Configuración.
.htaccess
Si una directiva es válida en este contexto, significa que puede aparecer dentro de ficheros .htaccess de contexto de directorio. Aunque podría no ser procesada, dependiendo de la configuración activa de AllowOverride en ese momento.

La directiva solo se permite dentro del contexto designado; si intenta usarlo en algún otro, obtendrá un error de configuración que impedirá que el servidor gestione correctamente las solicitudes en ese contexto, o impedirá que el servidor pueda funcionar completamente -- p.ej., el servidor no arrancará.

Las ubicaciones válidas para la directiva son actualmente el resultado de un Boolean OR de todos los contextos listados. En otras palabras, una directiva que está marcada como válida en "server config, .htaccess" puede usarse en el fichero httpd.conf y en ficheros .htaccess, pero no dentro de contenedores <Directory> o <VirtualHost>.

top

Override

Este atributo de directiva indica qué Override de configuración debe estar activo para que la directiva se procese cuando aparece en un fichero .htaccess. Si el contexto de la directiva no permite que aparezca en ficheros .htaccess, entonces no se listará ningún contexto.

Los Override se activan con la directiva AllowOverride, si se aplican a un ámbito en particular (como por ejemplo un directorio) y todos sus descendientes, a menos que se modifique más adelante por otras directivas AllowOverride en niveles inferiores. La documentación para la directiva también muestra una lista de los posibles nombres de Override disponibles.

top

Estado

Esto indica cuan vinculada está esta directiva al servidor Web de Apache; o en otras palabras, puede que necesite recompilar el servidor con un conjunto mejor de módulos para obtener acceso a esta directiva y su funcionalidad. Valores posibles para estar directiva son:

Core
Si una directiva aparece listada con estado "Core", eso significa que forma parte de las partes más internas del Servidor Apache Web, y que siempre está disponible.
MPM
La directivas facilitadas por un Módulo de Multi-Proceso están etiquetadas con Estado "MPM". Este tipo de directiva estará disponible si y sólo si está usando uno de los MPM listados en la línea Módulo de la definición de la directiva.
Base
Una directiva listada con estado "Base" está facilitada por uno de los módulos estándar de Apache que están compilados con el servidor por defecto, y por tanto está normalmente disponible a menos que usted haga las acciones necesarias para eliminar este módulo de su configuración.
Extensión
Una directiva con estado "Extensión" está facilitada por uno de los módulos incluidos en el kit del servidor Apache, pero el módulo no está compilado generalmente dentro del servidor. Para activar esta y su funcionalidad, necesirará cambiar la configuración de compilación del servidor y recompilar Apache.
Experimental
El estado "Experimental" indica que la directiva está disponible como parte del kit de Apache, pero usted tendrá que ir por su cuenta si intenta usarla. La directiva se documenta para aportar información, pero no tiene por qué estar soportada de manera oficial. El módulo que provee esta directiva puede o puede que no esté compilado por defecto, compruebe la parte superior de la página que describe la direcitiva y el módulo para ver las anotaciones sobre su disponibilidad.
top

Módulo

Esto simplemente hace referencia al nombre del módulo original que provee la directiva.

top

Compatibilidad

Si la directiva no era parte de la distribución original de Apache versión 2, la versión en la que se introdujo debería estar referida aquí. Además, si la direcitva solo está disponible en ciertas plataformas, se verá anotado aquí.

Idiomas disponibles:  en  |  es  |  fr  |  ja  |  ko  |  tr 

top

Comentarios

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_status.html.ja.utf80000664000175100017510000002665414743132254022156 0ustar covenercovener mod_status - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_status

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:サーバの活動状況と性能に関する情報を提供する
ステータス:Base
モジュール識別子:status_module
ソースファイル:mod_status.c

概要

この Status モジュールによりサーバ管理者はサーバがどのくらい の性能で動作しているかを知ることができるようになります。 現時点でのサーバの統計情報を読みやすい形式で表した HTML ページが 表示されます。必要であれば、このページは自動的にリフレッシュさせる こともできます (互換性のあるブラウザを使用している場合)。 別に、現時点でのサーバの状態を単純な機械読み取り可能なリストで 表すページもあります。

表示される情報は:

"(*)" の付いている情報を表示するには ExtendedStatusOn になっている必要があります。

Support Apache!

トピック

ディレクティブ

このモジュールにディレクティブはありません。

Bugfix checklist

参照

top

Status を使用可能にする

example.com ドメインからのブラウザのみに対して ステータスの報告を使用可能にするには 以下のコードを httpd.conf 設定ファイルに追加します

<Location /server-status>
SetHandler server-status

Order Deny,Allow
Deny from all
Allow from .example.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) も含むすべての 設定ファイルで使用可能になることには注意をしておく必要があります。 これは、サイトによってはセキュリティに関する望ましくない結果を もたらすことがあるかもしれません。

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_suexec.html.ja.utf80000664000175100017510000002166614743132254022125 0ustar covenercovener mod_suexec - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_suexec

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:指定されたユーザとグループで CGI スクリプトを実行する
ステータス:Extension
モジュール識別子:suexec_module
ソースファイル:mod_suexec.c
互換性:Apache 2.0 以降で使用可能

概要

このモジュールと suexec サポートプログラム により、CGI スクリプトが指定されたユーザとグループで 実行されるようにできます。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

SuexecUserGroup ディレクティブ

説明:CGI プログラムのユーザパーミッション、グループパーミッション
構文:SuexecUserGroup User Group
コンテキスト:サーバ設定ファイル, バーチャルホスト
ステータス:Extension
モジュール:mod_suexec
互換性:SuexecUserGroup は 2.0 以降でのみ使用可能。

SuexecUserGroup ディレクティブは CGI プログラム が実行されるユーザとグループを指定できるようにします。CGI 以外の リクエストは User ディレクティブで指定されたユーザのままで処理されます。 このディレクティブは Apache 1.3 における VirtualHosts の中で User ディレクティブと Group ディレクティブを使う用法の代わりになります。

SuexecUserGroup nobody nogroup

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_status.html.tr.utf80000664000175100017510000003122314743132254022175 0ustar covenercovener mod_status - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_status

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:Sunucu etkinliği ve başarımı hakkında bilgi sağlar.
Durum:Temel
Modül Betimleyici:status_module
Kaynak Dosyası:mod_status.c

Özet

mod_status modülü, sunucu yöneticisinin, HTTP sunucusunun ne kadar başarılı olduğu hakkında bilgi edinmesini sağlar. Bilgiler, kolayca okunabilen bir HTML sayfası olarak sunulur ve o anki sunucu istatistiklerinden oluşur. Gerekirse sayfa kendiliğinden tazelenebilir (uyumlu bir tarayıcı gerekir). Diğer sayfa o anki sunucu durumunu makine tarafından okunabilen biçimde listeler.

Sunulan bilgiler şunlardır:

"(*)" imli bilgiler sadece ExtendedStatus yönergesinin değeri On olduğu takdirde mevcuttur. 2.3.6 sürümünde, bu modulün yüklenmesi öntanımlı olarak ExtendedStatus yönergesinin değerini On yapacaktır.

Support Apache!

Konular

Yönergeler

Bu modül yönerge içermez.

Bulunan hatalar

Ayrıca bakınız:

top

Durum Bilgisi Desteğinin Etkinleştirilmesi

Durum raporları, sadece example.com alanından ve sadece tarayıcılar için etkin kılınmak istenirse httpd.conf dosyasına şu satırlar eklenebilir:

<Location "/server-status">
    SetHandler server-status
    Require host example.com
</Location>

Sunucu istatistiklerine tarayıcınızla erişmek isterseniz, http://sunucunuzun.ismi.buraya/server-status şeklinde bir istek yapabilirsiniz.

top

Sayfanın Tazelenmesi

Tarayıcınız “tazeleme” yeteneğine sahipse durum sayfası düzenli aralıklarla güncellenecektir. Sayfanın N saniyede bir güncellenmesini isterseniz isteği şöyle yapabilirsiniz:
http://sunucunuzun.ismi.buraya/server-status?refresh=N

top

Makine Tarafından Okunabilen Durum Dosyası

Durum dosyasının makine tarafından okunabilen sürümüne http://sunucunuzun.ismi.buraya/server-status?auto şeklinde bir istek yaparak erişebilirsiniz. Bu, kendiliğinden çalıştığı takdirde yararlıdır; Apache HTTP Sunucusu kurulumunuzun /support dizininde bulunan log_server_status isimli Perl betiğine bakınız.

Güvenlik

mod_status sunucuya yüklendiği takdirde istatistikleri raporlama yeteneği dizin içi yapılandırma dosyaları (.htaccess gibi) dahil tüm yapılandırma dosyaları için kullanılabilir olacaktır. Bu durum güvenlik ile ilgili olarak siteniz için içinden çıkılması güç durumlara yol açabilir (çapanoğlu durumu).
top

Sorun gidermek için server-status kullanımı

Sunucunuzun kullanılabilir tüm özkaynakları (işlemci veya bellek) sömürdüğü ve sizin de bu soruna hangi istemcilerin veya isteklerin yol açtığını saptamak istediğiniz durumda sorunu gidermek için başlangıç yeri olarak server-status sayfası kullanılabilir.

Önce ExtendedStatus yönergesine On atadığınızsan emin olun. Böylece her çocuk süreç veya evre için tüm istek ve istemci bilgilerini görebilirsiniz.

(top veya benzeri bir süreç izleme aracı kullanarak) Artık kendi süreç listenize ana zanlılar olan süreçleri bulmak için bakabilirsiniz. Sorunun çeşidine bağlı olarak top çıktısını işlemci kullanımına veya bellek kullanımına göre sıralatabilirsiniz.

server-status sayfasını yeniden yükleyip bu süreç kimliklerine bakın. Böylece, bu süreçler tarafından hangi isteklerin hangi istemcilere sunulduğunu görebilirsiniz. İstekler kısa sürelerle görünürler, bu bakımdan iş üstünde yakalamak için çeşitli denemeler yapmanız gerekebilir.

Bu işlem, yük sorununuzdan birinci derecede sorumlu istek türleri veya istemciler hakkında bir fikir verecektir. Çoğu durumda belli bir HTTP uygulamasının yanlış davrandığını veya belli bir istemcinin sitenize saldırmakta olduğunu farkedersiniz.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_suexec.html.tr.utf80000664000175100017510000002051114743132254022144 0ustar covenercovener mod_suexec - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_suexec

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:CGI betiklerinin belli bir kullanıcı ve grubun aidiyetinde çalışmasını mümkün kılar.
Durum:Eklenti
Modül Betimleyici:suexec_module
Kaynak Dosyası:mod_suexec.c

Özet

Bu modül suexec programı ile birlikte CGI betiklerinin belli bir kullanıcı ve grubun aidiyetinde çalışmasını mümkün kılar.

Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

SuexecUserGroup Yönergesi

Açıklama:CGI betiklerini çalıştıracak kullanıcı ve grup belirtilir.
Sözdizimi:SuexecUserGroup Kullanıcı Grup
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_suexec

SuexecUserGroup yönergesi CGI programlarını çalıştıracak kullanıcı ve grubu belirtmeye yarar. CGI harici istekler hala User yönergesinde belirtilen kullanıcı tarafından yerine getirilir.

SuexecUserGroup nobody nogroup

Bu yönerge belirtildiği halde Suexec özelliği etkinleştirilmemişse Apache httpd başlatılamaz.

Ayrıca bakınız:

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/index.html.ja.utf80000664000175100017510000006002214743132254021066 0ustar covenercovener モジュール一覧 - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4

モジュール一覧

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

以下は Apache HTTP サーバの配布物に同梱されているモジュールの 一覧です。Apache HTTP サーバ ディレクティブ のアルファベット順のリストもご覧ください。

参照

top

コア機能と MPM

core
常に使用可能な Apache HTTP サーバのコア機能
mpm_common
二つ以上のマルチプロセッシングモジュール (MPM) で実装されているディレクティブのコレクション
event
A variant of the worker MPM with the goal of consuming threads only for connections with active processing
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
prefork
スレッドを使わず、先行して fork を行なうウェブサーバを実装
mpm_winnt
Windows NT 向けに最適化されたマルチプロセッシングモジュール
worker
マルチスレッドとマルチプロセスのハイブリッド型 ウェブサーバを実装したマルチプロセッシングモジュール
top

他のモジュール

 A  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
ホスト (名前もしくは IP アドレス) に基づいたグループ承認
mod_actions
メディアタイプやリクエストメソッドに応じて CGI スクリプトを実行する機能を提供
mod_alias
ホストファイルシステム上のいろいろな違う場所を ドキュメントツリーにマップする機能と、 URL のリダイレクトを行なう機能を提供する
mod_allowmethods
Easily restrict what HTTP methods can be used on the server
mod_asis
自分用の HTTP ヘッダの書かれているファイルを送信する
mod_auth_basic
基本認証
mod_auth_digest
User authentication using MD5 Digest Authentication
mod_auth_form
Form authentication
mod_authn_anon
認証が必要な領域への "anonymous" ユーザのアクセスを許可する
mod_authn_core
Core Authentication
mod_authn_dbd
User authentication using an SQL database
mod_authn_dbm
DBM ファイルを用いたユーザ認証
mod_authn_file
テキストファイルを用いたユーザ認証
mod_authn_socache
Manages a cache of authentication credentials to relieve the load on backends
mod_authnz_fcgi
Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
mod_authnz_ldap
Allows an LDAP directory to be used to store the database for HTTP Basic authentication.
mod_authz_core
Core Authorization
mod_authz_dbd
Group Authorization and Login using SQL
mod_authz_dbm
Group authorization using DBM files
mod_authz_groupfile
プレーンテキストファイルを用いたグループ承認
mod_authz_host
Group authorizations based on host (name or IP address)
mod_authz_owner
ファイルの所有者に基づいた承認
mod_authz_user
ユーザ承認
mod_autoindex
Unix の ls コマンドや Win32 の dir シェルコマンドに似た ディレクトリインデックスを生成する
mod_brotli
Compress content via Brotli before it is delivered to the client
mod_buffer
Support for request buffering
mod_cache
URI をキーにしたコンテンツのキャッシュ
mod_cache_disk
URI をキーにしたコンテンツキャッシュストレージ管理
mod_cache_socache
Shared object cache (socache) based storage module for the HTTP caching filter.
mod_cern_meta
CERN httpd metafile semantics
mod_cgi
CGI スクリプトの実行
mod_cgid
外部 CGI デーモンを使った CGI スクリプトの実行
mod_charset_lite
Specify character set translation or recoding
mod_data
Convert response body into an RFC2397 data URL
mod_dav
分散オーサリングとバージョン管理 (WebDAV) 機能
mod_dav_fs
mod_dav のためのファイルシステムプロバイダ
mod_dav_lock
mod_dav 用の汎用ロックモジュール
mod_dbd
Manages SQL database connections
mod_deflate
クライアントへ送られる前にコンテンツを圧縮する
mod_dialup
Send static content at a bandwidth rate limit, defined by the various old modem standards
mod_dir
「最後のスラッシュ」のリダイレクトと、ディレクトリの インデックスファイルを扱う機能を提供する
mod_dumpio
望むようにすべての I/O をエラーログにダンプする
mod_echo
プロトコルモジュールの概要を示すための単純なエコーサーバ
mod_env
CGI スクリプト及び SSI ページに渡される環境変数を変更する機能を提供する
mod_example_hooks
Illustrates the Apache module API
mod_expires
ユーザの指定した基準に基づいた ExpiresCache-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_heartbeat
Sends messages with server status to frontend proxy
mod_heartmonitor
Centralized monitor for mod_heartbeat origin servers
mod_http2
Support for the HTTP/2 transport layer
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_lbmethod_bybusyness
Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_byrequests
Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_bytraffic
Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_heartbeat
Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_ldap
LDAP connection pooling and result caching services for use by other LDAP modules
mod_log_config
サーバへのリクエストのロギング
mod_log_debug
Additional configurable debug logging
mod_log_forensic
サーバに送られたリクエストの forensic ロギング
mod_logio
リクエスト毎に入力バイト数と出力バイト数とをロギング
mod_lua
Provides Lua hooks into various portions of the httpd request processing
mod_macro
Provides macros within apache httpd runtime configuration files
mod_md
Managing domains across virtual hosts, certificate provisioning via the ACME protocol
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_privileges
Support for Solaris privileges and for running virtual hosts under different user IDs.
mod_proxy
HTTP/1.1 プロキシ/ゲートウェイサーバ
mod_proxy_ajp
mod_proxy で AJP をサポートするためのモジュール
mod_proxy_balancer
負荷分散のための mod_proxy 拡張
mod_proxy_connect
CONNECT リクエストを扱う mod_proxy 用の拡張
mod_proxy_express
Dynamic mass reverse proxy extension for mod_proxy
mod_proxy_fcgi
FastCGI support module for mod_proxy
mod_proxy_fdpass
fdpass external process support module for mod_proxy
mod_proxy_ftp
FTP support module for mod_proxy
mod_proxy_hcheck
Dynamic health check of Balancer members (workers) for mod_proxy
mod_proxy_html
Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
mod_proxy_http
HTTP support module for mod_proxy
mod_proxy_http2
HTTP/2 support module for mod_proxy
mod_proxy_scgi
SCGI gateway module for mod_proxy
mod_proxy_uwsgi
UWSGI gateway module for mod_proxy
mod_proxy_wstunnel
Websockets support module for mod_proxy
mod_ratelimit
Bandwidth Rate Limiting for Clients
mod_reflector
Reflect a request body as a response via the output filter stack.
mod_remoteip
Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
mod_reqtimeout
Set timeout and minimum data rate for receiving requests
mod_request
Filters to handle and make available HTTP request bodies
mod_rewrite
Provides a rule-based rewriting engine to rewrite requested URLs on the fly
mod_sed
Filter Input (request) and Output (response) content using sed syntax
mod_session
Session support
mod_session_cookie
Cookie based session support
mod_session_crypto
Session encryption support
mod_session_dbd
DBD/SQL based session support
mod_setenvif
リクエストの特徴に基づいた環境変数の設定を可能にする
mod_slotmem_plain
Slot-based shared memory provider.
mod_slotmem_shm
Slot-based shared memory provider.
mod_so
起動時や再起動時に実行コードとモジュールをサーバにロードする
mod_socache_dbm
DBM based shared object cache provider.
mod_socache_dc
Distcache based shared object cache provider.
mod_socache_memcache
Memcache based shared object cache provider.
mod_socache_redis
Redis based shared object cache provider.
mod_socache_shmcb
shmcb based shared object cache provider.
mod_speling
ユーザが入力したであろう間違った URL を、 大文字小文字の区別を無視することと一つ以下の綴り間違いを許容することで 修正を試みる
mod_ssl
Strong cryptography using the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols
mod_status
サーバの活動状況と性能に関する情報を提供する
mod_substitute
Perform search and replace operations on response bodies
mod_suexec
指定されたユーザとグループで CGI スクリプトを実行する
mod_systemd
Provides better support for systemd integration
mod_unique_id
それぞれのリクエストに対する一意な識別子の入った環境変数を 提供する
mod_unixd
Basic (required) security for Unix-family platforms.
mod_userdir
ユーザ専用のディレクトリを提供
mod_usertrack
Clickstream logging of user activity on a site
mod_version
バージョン依存の設定
mod_vhost_alias
Provides for dynamically configured mass virtual hosting
mod_watchdog
provides infrastructure for other modules to periodically run tasks
mod_xml2enc
Enhanced charset/internationalisation support for libxml2-based filter modules

翻訳済み言語:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/mod_alias.html.tr.utf80000664000175100017510000012364114743132254021751 0ustar covenercovener mod_alias - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_alias

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.
Açıklama:Belge ağacının parçalarının dosya sisteminin parçalarıyla eşlenmesini sağlar ve URL yönlendirmesi yapar.
Durum:Temel
Modül Betimleyici:alias_module
Kaynak Dosyası:mod_alias.c

Özet

Bu modülde bulunan yönergeler sunucuya istek olarak gelen URL’lerin denetlenmesini ve değiştirilmesini mümkün kılar. Alias ve ScriptAlias yönergeleri URL’lerin dosya sisteminin dizinlerine eşlenmesini sağlar. Böylece, kök dizini DocumentRoot ile belirtilen site belge ağacı altında bulunmayan içeriğe erişmek mümkün olur. ScriptAlias yönergesi buna ek olarak hedef dizini sadece CGI betiklerini içeren dizin olarak imler.

Redirect yönergesi, farklı bir URL ile yeni bir istek yapmaları için istemcileri yönlendirmekte kullanılır. Çoğunlukla özkaynak başka bir yere taşındığında kullanılır.

Alias, ScriptAlias ve Redirect yönergeleri <Location> veya <LocationMatch> bölümleri içinde kullanıldığında hedef yolu veya URL'yi betimlemek için ifade sözdizimi kullanılabilir.

mod_alias modülü basit URL değiştirme görevlerini yerine getirmek için tasarlanmıştır. Sorgu dizgelerini işleme sokmak gibi daha karmaşık görevler için mod_rewrite modülü ile sağlanan araçlar kullanılır.

Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

İşlem Sırası

Farklı bağlamlarda bulunan Alias ve Redirect yönergeleri standart katıştırma kuralları ile ilgili diğer yönergeler gibi işleme sokulur. Fakat aynı bağlam dahilinde (örneğin, aynı <VirtualHost> bölümünde) çok fazla Alias ve Redirect varsa bunlar belli bir sıraya göre işleme sokulurlar.

İlk adımda, Alias’lardan önce bütün Redirect yönergeleri işleme sokulur. Bu bakımdan bir Redirect veya RedirectMatch ile eşleşen bir istek için hiçbir Alias uygulanmayacaktır. İkinci adımda yapılandırma dosyasında yer aldıkları sıraya göre Redirect ve Alias yönergeleri işleme sokulurlar, dolayısıyla ilk eşleşme öncelikli olmuş olur.

İlk eşleşmenin öncelikli olması sebebiyle, bu yönergelerin birden fazlası aynı alt yola uygulandığı takdirde, tüm yönergelerin etkili olabilmesi için en uzun yolu sıralamada en öne almalısınız. Örneğin aşağıdaki yapılandırma beklendiği gibi çalışacaktır:

Alias "/foo/bar" "/baz"
Alias "/foo" "/gaq"

Ama yukarıdaki iki satır ters sırada yerleştirilmiş olsaydı, /foo rumuzu daima /foo/bar rumuzundan önce eşleşecek, dolayısıyla ikinci yönerge yok sayılacaktı.

Alias, ScriptAlias ve Redirect yönergeleri <Location> veya <LocationMatch> bölümleri içinde kullanıldığında bu yönergeler küresel olarak tanımlı Alias, ScriptAlias ve Redirect yönergelerinden öncelikli olur.

top

Alias Yönergesi

Açıklama:URL’leri dosya sistemi konumlarıyla eşler.
Sözdizimi:Alias [URL-yolu] dosya-yolu | dizin-yolu
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Temel
Modül:mod_alias

Alias yönergesi, belgelerin DocumentRoot dizininden farklı bir yerde saklanmasını mümkün kılar. URL-yolu ile başlayan URL’ler (% imlemesi çözüldükten sonra) dizin-yolu ile başlayan yerel dosyalarla eşlenir. URL-yolu, harf büyüklüğüne duyarsız sistemlerde bile harf büyüklüğüne duyarlıdır.

Alias "/image" "/ftp/pub/image"

http://example.com/image/foo.gif şeklinde bir istek, sunucunun /ftp/pub/image/foo.gif dosyasıyla yanıt vermesine sebep olurdu. Sadece tam yol parçaları eşleştirilir; bu bakımdan yukarıdaki Alias yapılandırması http://example.com/imagefoo.gif ile eşleşmez. Düzenli ifadelerin kullanıldığı daha karmaşık eşleşmeler için AliasMatch yönergesine bakınız.

URL-yolu’nu bir / ile sonlandırırsanız Alias yönergesini yorumlarken sunucunun da sona bir / ekleyeceğine dikkat ediniz. Yani, eğer

Alias "/icons/" "/usr/local/apache/icons/"

diye bir tanım yaparsanız sona bir / ekleme ihtiyacından dolayı /icons URL’si için bir Alias kullanılmayacaktır.

Alias hedefleri için ek <Directory> bölümleri belirtmeniz gerekebileceğine dikkat ediniz. <Directory> bölümlerinden önce yer alan Alias yönergelerine özellikle bakılır, dolayısıyla sadece Alias hedefleri etkilenir. (Bununla birlikte, Alias yönergelerinden önce işleme sokulan <Location> bölümlerinin uygulanacağına dikkat ediniz.)

Özellikle, DocumentRoot dışında bir dizine bir Alias oluşturuyorsanız hedef dizine doğrudan erişim izni vermeniz gerekebilir.

Alias "/image" "/ftp/pub/image"
<Directory "/ftp/pub/image">
    Require all granted
</Directory>

URL-yolu değiştirgesindeki bölü çizgilerinin sayısı istek URL-yolundakiler kadardır.

Eğer Alias yönergesi <Location> veya <LocationMatch> bölümleri içinde kullanılırsa URL-yolu yoksayılır ve dosya-yolu ifade sözdizimi kullanılarak yorumlanır.
Bu sözdizimi Apache 2.4.19 ve sonrasında kulanılabilir.

<Location "/image">
    Alias "/ftp/pub/image"
</Location>
<LocationMatch "/error/(?<NUMBER>[0-9]+)">
    Alias "/usr/local/apache/errors/%{env:MATCH_NUMBER}.html"
</LocationMatch>
top

AliasMatch Yönergesi

Açıklama:URL’leri dosya sistemi konumlarıyla düzenli ifadeleri kullanarak eşler.
Sözdizimi:AliasMatch "düzenli-ifade" "dosya-yolu|dizin-yolu"
Bağlam:sunucu geneli, sanal konak
Durum:Temel
Modül:mod_alias

Bu yönerge URL-yolu ile eşleşmek üzere bir düzenli ifade kabul etmesi dışında Alias yönergesine eşdeğerdir. Belirtilen düzenli ifade URL-yolu ile eşleşiyorsa sunucu parantezli eşleşmeleri belirtilen dizgede kullanarak dosya yolunu elde eder. Örneğin, /icons dizinini etkinleştirmek için şu yazılabilir:

AliasMatch "^/icons(.*)" "/usr/local/apache/icons$1"

Düzenli ifadelerin tamamı kullanılabilmektedir. Örneğin, URL-yolu ile harf büyüklüğüne duyarsız eşleşmeler sağlayacak takma adlar kullanılabilir:

AliasMatch "(?i)^/image(.*)" "/ftp/pub/image$1"

Alias ve AliasMatch yönergeleri arasındaki başlıca fark Alias yönergesinin, URI'nin ek parçasını, eşleşen parçayı geçip sağ tarafta dosya yolunun ucuna kendiliğinden kopyalamasıdır. AliasMatch bunu böyle yapmaz. Yani hemen her durumda, düzenli ifadenin istenen URI'nin tamamıyla baştan sona eşleşmesi ve yer değiştirmeyi sağ tarafta yapması istenir.

Başka bir deyişle, basitçe Alias yerine AliasMatch yazmakla aynı etkiyi alamazsınız. En azından düzenli ifadenin başına bir ^ ve sonuna bir (.*)$, ikinci değiştirgenin sonuna da bir $1 eklemeniz gerekir.

Örneğin aşağıdakini AliasMatch ile değiştirmek isteyelim:

Alias "/image/" "/ftp/pub/image/"

Bu eşdeğer DEĞİLdir - bunu yapmayın! Bu herhangi bir yerinde /image/ dizgesi bulunan tüm istekleri /ftp/pub/image/ altına gönderecektir:

AliasMatch "/image/" "/ftp/pub/image/"

Aynı etkiyi elde etmek için bu gerekiyor:

AliasMatch "^/image/(.*)$" "/ftp/pub/image/$1"

Şüphesiz, Alias yönergesini çalıştığı yerde AliasMatch kullanmanın hiç gereği yoktur. AliasMatch daha karmaşık şeyler yapmamızı sağlar. Örneğin farklı dosya çeşitlerini farklı dizinlerden sunmak isteyelim:

AliasMatch "^/image/(.*)\.jpg$" "/files/jpg.images/$1.jpg"
AliasMatch "^/image/(.*)\.gif$" "/files/gif.images/$1.gif"

İstek URL'sinin başındaki bölü çizgileri, bu modüldeki yönergeler istek URL-yolu ile eşleştirilmeye çalışılmadan önce sunucu tarafından yokedilir.

top

AliasPreservePath Yönergesi

Açıklama:Map the full path after the alias in a location.
Sözdizimi:AliasPreservePath OFF|ON
Öntanımlı:AliasPreservePath OFF
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Temel
Modül:mod_alias
Uyumluluk:2.4.58 and later

Bu yönergenin belgesi henüz Türkçeye çevrilmedi. Lütfen İngilizce sürümüne bakınız.

top

Redirect Yönergesi

Açıklama:İstemciyi, bir yönlendirme isteği döndürerek farklı bir URL’ye yönlendirir.
Sözdizimi:Redirect [durum] [URL-yolu] URL
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_alias

Redirect yönergesi istemciye bir yönlendirme isteği döndürerek eski URL’yi yenisiyle eşler.

Eski URL-yolu bir bölü çizgisi ile başlar ve harf büyüklüğüne duyarlıdır (% imlemesi çözüldükten sonra). URL-yolu olarak göreli yollara izin verilmez.

URL ise ya bir şema ve konak ismi ile başlayan bir mutlak URL ya da bir bölü çizgisi ile başlayan bir URL yolu olabilir. İkinci durumda URL yolunun başına geçerli sunucu ismi ve şemayı sunucu ekler.

URL-yolu ile başlayan istekler istemciye hedef URL konumuna bir yönlendirme isteği olarak dönecektir. URL-yolu’nun devamı niteliğindeki ek yol hedef URL’ye eklenir.

# Farklı bir konaktaki bir URL'ye yönlendirme
Redirect "/hizmet" "http://iki.example.com/hizmet"

# Aynı konak üzerinde yönlendirme
Redirect "/bir" "/iki"

İstemcinin yaptığı http://example.com/hizmet/fesmekan.txt isteğine karşılık istemciye isteği http://iki.example.com/hizmet/fesmekan.txt olarak yapması söylenecektir. Bu GET isteklerinde de geçerlidir. Örneğin, http://example.com/hizmet/foo.pl?q=23&a=42 isteği http://iki.example.com/hizmet/foo.pl?q=23&a=42 adresine yönlendirilir. POST'ların iptal edileceğini unutmayın.
Sadece tam yol parçaları eşleştirilir, bu nedenle http://example.com/hizmetfesmekan.txt isteği yukarıdaki yönlendirme ile eşleşmeyecektir. İfade sözdizimi kullanılan daha karmaşık eşleşmeler için URL-yolu seçeneği aşağıda açıklandığı gibi yoksayılır. Düzenli ifadelerin kullanıldığı daha karmaşık eşleşmeler için RedirectMatch yönergesine de bakınız.

Bilginize

Yapılandırma dosyasında yer alış sırasına bakmaksızın Redirect yönergeleri Alias ve ScriptAlias yönergelerinden önce ele alınır. <Location> bölümü içinde kullanılmış bir Redirect yönergesi URL-yolu belirtilmiş Redirect ve Alias yönergelerine göre önceliklidir.

Herhangi bir durum belirtilmemişse "geçici" yönlendirme (HTTP durum kodu: 302) yapılır. Bu, istemciye özkaynağın geçici olarak başka yere taşındığını belirtir. Diğer HTTP durum kodlarını döndürmek için kullanılabilecek durum değerleri:

permanent
İstemciye özkaynağın kalıcı olarak taşındığını belirten kalıcı yönlendirme durumu (301) döndürülür.
temp
İstemciye geçici yönlendirme durumu (302) döner. Bu öntanımlıdır.
seeother
İstemciye özkaynağın yerine başka bir şey konduğunu belirten "diğerine bak" durumu (303) döndürülür.
gone
İstemciye özkaynağın kalıcı olarak kaldırıldığını belirten "ölü bağlantı" durumu (410) döner. Bu durumda URL belirtilmez.

Diğer durum kodları için durum değiştirgesiyle sayısal durum kodu belirtilir. Eğer durum 300 ile 399 arasındaysa bir URL belirtmek gereklidir. Aksi takdirde, URL bileşeni ihmal edilmelidir. Belirtilecek durum kodunun geçerli bir HTTP Status kodu olmalı ve Apache HTTP Sunucusu kodu bilmelidir (http_protocol.c dosyasında bulunan send_error_response işlevine bakınız).

Redirect permanent "/bir" "http://example.com/iki"
Redirect 30" "/yedi" http://example.com/baskabisey"

Eğer Redirect yönergesi URL-yolu belirtilmemiş bir <Location> veya <LocationMatch> bölümü içinde yer alıyorsa, URL seçeneği ifade sözdizimi kullanılarak yorumlanır.
Bu sözdizimi Apache 2.4.19 ve sonrasında kullanılabilir.

<Location "/bir">
    Redirect permanent "http://example.com/iki"
</Location>
<Location "/yedi">
    Redirect 303 "http://example.com/baskabisey"
</Location>
<LocationMatch "/error/(?<NUMBER>[0-9]+)">
    Redirect permanent "http://example.com/errors/%{env:MATCH_NUMBER}.html"
</LocationMatch>
top

RedirectMatch Yönergesi

Açıklama:Geçerli URL ile eşleşen bir düzenli ifadeye dayanarak bir harici yönlendirme gönderir.
Sözdizimi:RedirectMatch [durum] düzenli-ifade URL
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_alias

Bu yönerge URL-yolu ile eşleşmek üzere bir düzenli ifade kabul etmesi dışında Redirect yönergesine eşdeğerdir. Belirtilen düzenli ifade URL-yolu ile eşleşiyorsa sunucu parantezli eşleşmeleri belirtilen dizgede kullanarak dosya yolunu elde eder. Örneğin, tüm GIF dosyası isteklerini başka bir sunucudaki aynı isimli JPEG dosyalarına yönlendirmek için şu yazılabilir:

RedirectMatch "(.*)\.gif$" "http://baska.example.com$1.jpg"

Alias ve AliasMatch arasındaki farklarla ilgili hususlar Redirect ve RedirectMatch arasındakilere de uygulanır. Ayrıntılar için AliasMatch yönergesine bakınız.

top

RedirectPermanent Yönergesi

Açıklama:İstemciyi, kalıcı bir yönlendirme isteği döndürerek farklı bir URL’ye yönlendirir.
Sözdizimi:RedirectPermanent URL-yolu URL
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_alias

Bu yönerge istemciye daima kalıcı yönlendirme durumu (301) döndürür. Yani, Redirect permanent ile aynı işi yapar.

top

RedirectRelative Yönergesi

Açıklama:Allows relative redirect targets.
Sözdizimi:RedirectRelative On|Off
Öntanımlı:RedirectRelative Off
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Temel
Modül:mod_alias
Uyumluluk:2.4.58 and later

Bu yönergenin belgesi henüz Türkçeye çevrilmedi. Lütfen İngilizce sürümüne bakınız.

top

RedirectTemp Yönergesi

Açıklama:İstemciyi, geçici bir yönlendirme isteği döndürerek farklı bir URL’ye yönlendirir.
Sözdizimi:RedirectTemp URL-yolu URL
Bağlam:sunucu geneli, sanal konak, dizin, .htaccess
Geçersizleştirme:FileInfo
Durum:Temel
Modül:mod_alias

Bu yönerge istemciye daima geçici yönlendirme durumu (302) döndürür. Yani, Redirect temp ile aynı işi yapar.

top

ScriptAlias Yönergesi

Açıklama:Bir URL’yi dosya sistemindeki bir yere eşler ve hedefi bir CGI betiği olarak çalıştırır.
Sözdizimi:ScriptAlias [URL-yolu] dosya-yolu|dizin-yolu
Bağlam:sunucu geneli, sanal konak, dizin
Durum:Temel
Modül:mod_alias

Hedef dizini, mod_cgi modülünün CGI betiği yorumlayıcısı tarafından çalıştırılacak betikleri içeren dizin olarak imlemesi dışında Alias yönergesinin yaptığı işi yapar. URL-yolu ile başlayan harf büyüklüğüne duyarlı URL’ler (% imlemesi çözüldükten sonra), dosya sistemindeki bir tam yol olarak belirtilmiş dizin-yolu ile başlayan betiklerle eşlenir.

ScriptAlias "/cgi-bin/" "/siteler/cgi-bin/"

http://example.com/cgi-bin/foo şeklindeki bir istek sunucunun /siteler/cgi-bin/foo betiğini çalıştırmasına sebep olur. Bu yapılandırma aslında şuna eşdeğerdir:

Alias "/cgi-bin/" "/siteler/cgi-bin/"
<Location "/cgi-bin">
    SetHandler cgi-script
    Options +ExecCGI
</Location>

ScriptAlias yönergesini bir betik veya eylemci ile birlikte de kullanabilirsiniz. Örnek:

ScriptAlias "/cgi-bin/" "/siteler/cgi-handler.pl"

Bu senaryoda /cgi-bin/’den istenen tüm dosyalar sizin belirttiğiniz dosya tarafından işleme sokulacaktır. Bu yöntemle kendi özel eylemcinizi kullanabilirsiniz. İsterseniz, bunu içerik eklemek ya da ısmarlama bir eylem için bir CGI sarmalayıcısı olarak da kullanabilirsiniz.

Yapılandırma değiştiğinde kaynak kodlarının ister istemez açığa çıkmasını istemiyorsanız CGI betiklerinizi DocumentRoot altına koymayınız. ScriptAlias yönergesi URL’yi doğru yere eşlemekten başka orayı bir CGI betikleri dizini olarak imler. CGI betiklerinizi DocumentRoot altına koyarsanız çalıştırmak için ScriptAlias değil, <Directory>, SetHandler ve Options yönergelerini örnekteki gibi kullanın:
<Directory "/usr/local/apache2/htdocs/cgi-bin" >
    SetHandler cgi-script
    Options ExecCGI
</Directory>
Aynı dosya sistemi konumu ile çok sayıda URL-yolu eşleşebileceğinden, bir Directory bölümü ile sınırlanmadığı takdirde CGI betiklerinin kaynak kodları açığa çıkabilir; bu bakımdan ScriptAlias yönergesini yok sayan URL yollarının belirtilebilme olasılığı gözardı edilmemelidir.

Eğer ScriptAlias yönergesi URL-yolu belirtilmemiş bir <Location> veya <LocationMatch> bölümü içinde yer alıyorsa, URL seçeneği ifade sözdizimi kullanılarak yorumlanır.
Bu sözdizimi Apache 2.4.19 ve sonrasında kullanılabilir.

<Location "/cgi-bin">
    ScriptAlias "/siteler/cgi-bin/"
</Location>
<LocationMatch "/cgi-bin/errors/(?<NUMBER>[0-9]+)">
    ScriptAlias "/siteler/cgi-bin/errors/%{env:MATCH_NUMBER}.cgi"
</LocationMatch>

Ayrıca bakınız:

top

ScriptAliasMatch Yönergesi

Açıklama:Bir URL’yi dosya sistemindeki bir yere düzenli ifade kullanarak eşler ve hedefi bir CGI betiği olarak çalıştırır.
Sözdizimi:ScriptAliasMatch düzenli-ifade dosya-yolu|dizin-yolu
Bağlam:sunucu geneli, sanal konak
Durum:Temel
Modül:mod_alias

Bu yönerge URL-yolu ile eşleşmek üzere bir düzenli ifade kabul etmesi dışında ScriptAlias yönergesine eşdeğerdir. Belirtilen düzenli ifade URL-yolu ile eşleşiyorsa sunucu parantezli eşleşmeleri belirtilen dizgede kullanarak dosya yolunu elde eder. Örneğin, standart /cgi-bin dizinini etkin kılmak için şu yazılabilir:

ScriptAliasMatch "^/cgi-bin(.*)" "/usr/local/apache/cgi-bin$1"

AliasMatch yönergesindeki gibi, düzenli ifadelerin tamamı tüm güçleriyle kullanılabilmektedir. Örneğin, URL-yolu için harf büyüklüğüne duyarsız eşleşmeli bir takma ad oluşturmak mümkünür:

ScriptAliasMatch "(?i)^/cgi-bin(.*)" "/usr/local/apache/cgi-bin$1"

Alias ve AliasMatch arasındaki farklarla ilgili hususlar ScriptAlias ve ScriptAliasMatch arasındakilere de uygulanır. Ayrıntılar için AliasMatch yönergesine bakınız.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_basic.html.ja.utf80000664000175100017510000004050714743132254022726 0ustar covenercovener mod_auth_basic - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_auth_basic

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:基本認証
ステータス:Base
モジュール識別子:auth_basic_module
ソースファイル:mod_auth_basic.c
互換性:Apache 2.1 以降

概要

与えられたプロバイダ (訳注: 認証での照会を行う問い合わせ先) でユーザを検索し、HTTP 基本認証でアクセス制限できるようになります。 HTTP ダイジェスト認証については mod_auth_digest で提供されます。このモジュールを使う際はこのモジュールのほかに mod_authn_file といった認証モジュールと、 mod_authz_user といった承認モジュールとの両方を、 それぞれひとつ以上組み合わせて使うことになります。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

AuthBasicAuthoritative ディレクティブ

説明:認証と承認を、より低いレベルのモジュールに移行させるかを 設定します。
構文:AuthBasicAuthoritative On|Off
デフォルト:AuthBasicAuthoritative On
コンテキスト:ディレクトリ, .htaccess
上書き:AuthConfig
ステータス:Base
モジュール:mod_auth_basic

通常は、AuthBasicProvider ディレクティブで指定した承認モジュールを順に使ってユーザを検査しようとして、 どのプロバイダでもユーザを検査できなかった場合、アクセス拒否します。 AuthBasicAuthoritativeOff と明示的に設定すると ユーザ ID がなかったりルールがなかったりする際に、認証と承認の両方について、 プロバイダー機構で実装されていないモジュールに処理を移行させることができます。 AuthBasicProvider ディレクティブで設定できないサードパーティ製のモジュールと、 mod_auth_basic とを組み合わせるときにのみ必要になるでしょう。 そのようなモジュールを使う場合、処理順序はモジュールのソースコードが どうなっているかによって決まり、処理順序を指定することはできません。

top

AuthBasicFake ディレクティブ

説明:Fake basic authentication using the given expressions for username and password
構文:AuthBasicFake off|username [password]
デフォルト:none
コンテキスト:ディレクトリ, .htaccess
上書き:AuthConfig
ステータス:Base
モジュール:mod_auth_basic
互換性:Apache HTTP Server 2.4.5 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

AuthBasicProvider ディレクティブ

説明:この位置に対する認証プロバイダを設定します。
構文:AuthBasicProvider provider-name [provider-name] ...
デフォルト:AuthBasicProvider file
コンテキスト:ディレクトリ, .htaccess
上書き:AuthConfig
ステータス:Base
モジュール:mod_auth_basic

AuthBasicProvider ディレクティブで、 この位置に対するユーザ認証に用いられる認証プロバイダを設定します。 デフォルトになっている file プロバイダは mod_authn_file モジュールで実装されています。 指定したプロバイダを実装しているモジュールが、 必ずサーバに組み込まれているようにしてください。

Example

<Location /secure>
AuthType basic
AuthName "private area"
AuthBasicProvider dbm
AuthDBMType SDBM
AuthDBMUserFile /www/etc/dbmpasswd
Require valid-user
</Location>

認証プロバイダは mod_authn_dbm, mod_authn_file, mod_authn_dbd, mod_authnz_ldap で実装されています。

top

AuthBasicUseDigestAlgorithm ディレクティブ

説明:Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
構文:AuthBasicUseDigestAlgorithm MD5|Off
デフォルト:AuthBasicUseDigestAlgorithm Off
コンテキスト:ディレクトリ, .htaccess
上書き:AuthConfig
ステータス:Base
モジュール:mod_auth_basic
互換性:Apache HTTP Server 2.4.7 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_dbm.html.ko.euc-kr0000664000175100017510000002461614743132254023123 0ustar covenercovener mod_authz_dbm - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_authz_dbm

ֽ ƴմϴ. ֱٿ ϼ.
:DBM ׷
:Extension
:authz_dbm_module
ҽ:mod_authz_dbm.c
:ġ 2.1 ĺ

׷ Ϻθ ִ Ͽ Ѻο Ѵ. mod_authz_groupfile ϴ.

Support Apache!

þ

Bugfix checklist

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

AuthzDBMType þ

:ȣ ϴ ͺ̽ Ѵ
:AuthzDBMType default|SDBM|GDBM|NDBM|DB
⺻:AuthzDBMType default
:directory, .htaccess
Override ɼ:AuthConfig
:Extension
:mod_authz_dbm

ȣ ϴ ͺ̽ Ѵ. ͺ̽ ⺻ ϶ . ִ ٸ ͺ̽ ޷ȴ.

ȣ α׷ ͺ̽ ϵ ؾ Ѵ.

:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_owner.html.ja.utf80000664000175100017510000003166614743132254023177 0ustar covenercovener mod_authz_owner - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_authz_owner

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:ファイルの所有者に基づいた承認
ステータス:Extension
モジュール識別子:authz_owner_module
ソースファイル:mod_authz_owner.c
互換性:Apache 2.1 以降で使用可能

概要

このモジュールはリクエストされたファイルのファイルシステムの 所有者やグループを HTTP 認証に使われたユーザ ID (ウェブユーザ ID) と 比較することでアクセスを承認します。提供されたユーザ名とパスワードは mod_auth_basicmod_auth_digest のような認証モジュールで既に 適切に検証されている必要があります。mod_authz_owner は以下のように、Require ディレクティブの file-ownerfile-group という二つの引数を認識します:

file-owner
提供されたウェブユーザ名はリクエストされたファイルの所有者の システムにおける名前と一致する必要があります。つまり、オペレーティング システムがファイルは jones により所有されている と言ったときは、ウェブからのアクセスに使われるユーザ名も jones でなければなりません。
file-group
ファイルを所有するシステムのグループの名前が、例えば mod_authz_groupfilemod_authz_dbm により提供されるグループデータベースに存在していて、 ウェブユーザ名がそのグループに属していなければなりません。 例えば、オペレーティングシステムがファイルは (システムの) グループ accounts により所有されていると言ったときは、 accounts がグループデータベースに存在して、 リクエストに使用されたウェブユーザ名がそのグループに属している 必要があります。

ファイルシステムに実際には存在しないリソース (つまり バーチャルなリソース) の承認に mod_authz_owner が使用されたときは、 アクセスは拒否されます。

特に、コンテント ネゴシエーションされた"MultiViews" のリソースは 決して承認しません。

Support Apache!

トピック

ディレクティブ

このモジュールにディレクティブはありません。

Bugfix checklist

参照

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
Require file-owner
</Directory>

Require file-group

上記のようなシステムで、数人のユーザがプロジェクトのファイルを ~/public_html/project-foo で共有しているとします。 ファイルはシステムのグループ foo に所有されていて、 AuthDBMGroupFile データベースが一つだけあり、そこにすべてのウェブユーザ名と グループのメンバが列挙されている、つまり、それらの ユーザは少なくとも foo というグループに属している、とします。 jonessmith の二人共がグループ 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>

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_user.html.ko.euc-kr0000664000175100017510000001554614743132254023341 0ustar covenercovener mod_authz_user - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_authz_user

ֽ ƴմϴ. ֱٿ ϼ.
: Ѻο
:Base
:authz_user_module
ҽ:mod_authz_user.c
:ġ 2.1 ĺ

οϿ, ڰ Ʈ Ϻο ִ Ѵ. mod_authz_user Require user þ Ͽ ڰ Ѵ. , require valid-user ο Ѵ.

Support Apache!

þ

⿡ þ ϴ.

Bugfix checklist

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/module-dict.html.ja.utf80000664000175100017510000002444514743132254022176 0ustar covenercovener Apache モジュールの解説で使用する用語 - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4

Apache モジュールの解説で使用する用語

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この文書は Apache の各 モジュール を説明するために 使われている用語を説明します。

Support 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 の配布に含まれていなかった場合、 そのモジュールが導入されたバージョンがここに書かれています。 また、モジュールが特定のプラットフォームにのみ存在するときも 詳細はここに書かれています。

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_unixd.html.tr.utf80000664000175100017510000003453514743132254022012 0ustar covenercovener mod_unixd - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_unixd

Mevcut Diller:  en  |  fr  |  tr 

Açıklama:Unix ailesi platformlar için temel (gerekli) güvenlik.
Durum:Temel
Modül Betimleyici:unixd_module
Kaynak Dosyası:mod_unixd.c
Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

ChrootDir Yönergesi

Açıklama:Sunucunun başlatıldıktan sonra chroot(8) yapacağı dizini belirler.
Sözdizimi:ChrootDir /dizin/yolu
Öntanımlı:none
Bağlam:sunucu geneli
Durum:Temel
Modül:mod_unixd
Uyumluluk:Apache HTTP Sunucusunun 2.2.10 and laterve sonraki sürümlerinde kullanılabilir.

Bu yönerge sunucuya başlatıldıktan sonra ağdan gelen istekleri kabul etmeden önce belirtilen dizine chroot(8) yapmasını söyler.

Sunucuyu chroot altında çalıştırmanın basit bir işlem olmadığına ve özellikle CGI veya PHP gibi betikler çalıştırıyorsanız ek ayarlamalar yapmanız gerektiğine dikkat ediniz. Lütfen, bu özelliği kullanmaya çalışmadan önce chroot işlemleri hakkında gerektiği kadar bilgi sahibi olduğunuzdan emin olunuz.

top

Group Yönergesi

Açıklama:İsteklere yanıt verecek sunucunun ait olacağı grubu belirler.
Sözdizimi:Group unix-grubu
Öntanımlı:Group #-1
Bağlam:sunucu geneli
Durum:Temel
Modül:mod_unixd

Group yönergesi, sunucunun hangi grup altında isteklere yanıt vereceğini belirler. Bu yönergenin uygulanabilmesi için sunucunun root olarak çalıştırılmış olması gerekir. Sunucuyu root dışında bir kullanıcı başlattığı takdirde, sunucu belirtilen gruba geçemez ve kullanıcının kendi grubunda çalışmaya devam eder. unix-grubu şunlardan biri olabilir:

Bir grup adı
Gruba ismiyle başvurulur.
# ardından grup numarası
Gruba numarası ile başvurulur.
Group www-group

Çalışan sunucu için özellikle yeni bir grup atamanız önerilir. Bazı sistem yöneticileri nobody grubunu kullanırlar fakat bu her zaman mümkün olmadığı gibi arzulanan da değildir.

Güvenlik

Ne yaptığınızı ve ne tehlikelere yol açacağınızı bilmiyorsanız Group (veya User) yönergesine değer olarak root atamayınız.

Ayrıca bakınız:

top

Suexec Yönergesi

Açıklama:suEXEC özelliğini etkin veya etkisiz yapar
Sözdizimi:Suexec On|Off
Öntanımlı:suexec çalıştırılabiliri uygun sahip ve kip ile mevcutsa On, değilse Off
Bağlam:sunucu geneli
Durum:Temel
Modül:mod_unixd

On olduğunda, suexec çalıştırılabiliri yoksa veya dosya kipi ve sahibi geçersizse httpd başlatılamaz.

Off olduğunda, suexec çalıştırılabiliri varsa ve hatta dosya kipi ve sahibi geçerli olsa bile suEXEC özelliği iptal edilir.

top

User Yönergesi

Açıklama:İsteklere yanıt verecek sunucunun ait olacağı kullanıcıyı belirler.
Sözdizimi:User unix-kullanıcısı
Öntanımlı:User #-1
Bağlam:sunucu geneli
Durum:Temel
Modül:mod_unixd

User yönergesi, sunucunun hangi kullanıcı olarak isteklere yanıt vereceğini belirler. Bu yönergenin uygulanabilmesi için sunucunun root olarak çalıştırılmış olması gerekir. Sunucuyu root dışında bir kullanıcı başlattığı takdirde, sunucu belirtilen kullanıcıya geçemez ve mevcut kullanıcıyla çalışmaya devam eder. Eğer sunucuyu root olarak başlatmışsanız ana süreç root olarak çalışmaya devam edecektir. unix-kullanıcısı şunlardan biri olabilir:

Bir kullanıcı adı
Gruba ismiyle başvurulur.
# ardından kullanıcı numarası
Kullanıcıya numarası ile başvurulur.

Bu yönergede belirtilecek kullanıcının, başkaları tarafından üzerinde değişiklik yapılabilecek dosyalardan başkasına erişemeyen bir kullanıcı olmaması gerektiği gibi, HTTP isteklerini işlemek dışında işlemler de yapabilen bir kullanıcı olmamalıdır. Çalışan sunucu için özellikle yeni bir grup atamanız önerilir. Bazı sistem yöneticileri nobody kullanıcısını kullanırlar fakat nobody kullanıcısı sistemde başka amaçlarla kullanılabildiğinden bu her zaman mümkün olmadığı gibi arzulanan da değildir.

Güvenlik

Ne yaptığınızı ve ne tehlikelere yol açacağınızı bilmiyorsanız User (veya Group) yönergesine değer olarak root atamayınız.

Ayrıca bakınız:

Mevcut Diller:  en  |  fr  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_userdir.html.tr.utf80000664000175100017510000003234614743132254022336 0ustar covenercovener mod_userdir - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_userdir

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Açıklama:Kullanıcılara özel dizinler
Durum:Temel
Modül Betimleyici:userdir_module
Kaynak Dosyası:mod_userdir.c

Özet

Bu modülü kullanarak, birden çok kullanıcının içeriği aynı kaynaktan almasına izin verirsiniz. Aynı kaynak politikası Javascript ve http güvenliğinin temelidir. Http sayfalarının aynı kaynaktan alınması nedeniyle bu sayfalar birbirini okuyabilir, denetleyebilir ve bir sayfadaki güvenlik sorunları başka bir sayfayı etkileyebilir. Bu, özellikle özdevinimli içerik ve kimlik doğrulaması içeren https sayfalarıyla birlikte ve kullanıcılarınızın birbirlerine güvenmeleri gerekmediğinde tehlikelidir.

Bu modül kullanıcılara özel dizinlere http://example.com/~kullanıcı/ sözdizimi kullanılarak erişilebilmesini mümkün kılar.

Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

UserDir Yönergesi

Açıklama:Kullanıcıya özel dizinlerin yeri
Sözdizimi:UserDir dizin [dizin] ...
Bağlam:sunucu geneli, sanal konak
Durum:Temel
Modül:mod_userdir

UserDir yönergesi, bir kullanıcıya ait bir belge için bir istek yapıldığında, isteğin kullanıcının ev dizininde bulunan belli bir dizinden karşılanmasını sağlar. dizin olarak şunlar belirtilebilir:

Userdir yönergesinde ne enabled ne de disabled varsa, argüman bir dosya ismi kalıbı olarak ele alınır ve kullanıcı belge kök dizininin yolunu oluşturmakta kullanılır. http://example.com/~ali/bir/iki.html şöyle dönüştürülür:

Kullanılan UserDir yönergesi     Elde edilen yol
UserDir public_html ~ali/public_html/bir/iki.html
UserDir /usr/siteler /usr/siteler/ali/bir/iki.html
UserDir /home/*/htdocs /home/ali/htdocs/bir/iki.html

Aşağıdaki yönergelerle istemciye gönderilecek yönlendirmeler:

Kullanılan UserDir yönergesi     Elde edilen yönlendirme
UserDir http://example.com/users http://example.com/users/ali/bir/iki.html
UserDir http://example.com/*/usr http://example.com/ali/usr/bir/iki.html
UserDir http://example.com/~*/ http://example.com/~ali/bir/iki.html
Bu yönergeyi kullanırken dikkatli olun; örneğin, "UserDir ./" şeklinde bir atama "/~root" isteklerini "/" dizinine yönlendirir ki bu elbette istenmez. Bu bakımdan yapılandırmanızda mutlaka bir "UserDir disabled root" satırının yer almasını tavsiye ederiz. Daha fazla bilgi için Directory yönergesine ve Güvenlik İpuçları sayfasına bakınız.

Diğer örnekler:

Bir kaç kullanıcı hariç kalan herkesin UserDir dizinlerini iptal etmek için şunu yapabilirsiniz:

UserDir disabled
UserDir enabled birey1 birey2 birey3

Bir kaç kullanıcı hariç kalan herkesin UserDir dizinlerini etkin kılmak için şunu yapabilirsiniz:

UserDir disabled birey4 birey5 birey6

Birden fazla dizin belirtmek de mümkündür:

Userdir "public_html" "/usr/siteler" "http://example.com/"

Bu örneğe göre, http://example.com/~ali/bir/iki.html şeklinde bir istek alındığında sunucu önce http://example.com/~ali/bir/iki.html yönlendirmesini deneyecektir. Onu bulamazsa isteği /usr/siteler/ali/bir/iki.html dosyasını arayacak onu da bulamazsa istemciyi http://example.com/ali/bir/iki.html adresine yönlendirecektir.

Argüman listesine bir yönlendirme ekleyecekseniz, bu, listenin son elemanı olmalıdır. Apache httpd yönlendirmenin başarılı sonuç verip vermediğini bilemeyecektir. Bu bakımdan, listede bu yönlendirmeden sonra bir yönlendirme daha bulunması daha iyi olacaktır.

Kullanıcı dizini dönüşümü Apache 2.1.4 sürümü ve sonrasında öntanımlı olarak etkin değildir. Daha önceki sürümlerde bir UserDir yönergesinin yokluğunda UserDir public_html öntanımlıydı.

Ayrıntıların birleştirilmesi

Etkinleştirilen ve etkisizleştirilen kullanıcılara özgü listeler küresel etki alanından sanal konak etki alanına aktarılırken yer değiştirme yapılır, mevcutla birleştirilmez.

Ayrıca bakınız:

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_vhost_alias.html.tr.utf80000664000175100017510000005300214743132254023165 0ustar covenercovener mod_vhost_alias - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache Modülü mod_vhost_alias

Mevcut Diller:  en  |  fr  |  tr 

Açıklama:Kitlesel sanal konakların devingen olarak yapılandırılmasını sağlar
Durum:Eklenti
Modül Betimleyici:vhost_alias_module
Kaynak Dosyası:mod_vhost_alias.c

Özet

Bu modül, hangi dosyaların sunulacağını saptamak için dosya yolunun parçası olarak HTTP isteğinin Host: başlığının ve/veya IP adresinin kullanılmasını mümkün kılarak devingen yapılandırmalı sanal konaklar oluşturur. Böylece benzer yapılandırmaya sahip çok büyük sayıda sanal konak kullanımı kolaşlaşır.

Bilginize

URI’leri dosya isimlerine dönüştürmek için mod_alias veya mod_userdir kullanılmışsa bunlar mod_vhost_alias yönergeleri tarafından aşağıda açıklandığı gibi geçersiz kılınırlar. Örneğin, aşağıdaki yapılandırma her durumda /cgi-bin/script.pl betiğini /usr/local/apache2/cgi-bin/script.pl betiğine eşleyecektir:

ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
VirtualScriptAlias "/nerede/bilinmiyor/%0/cgi-bin/"
Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Dizin İsimlerinin Elde Edilmesi

Bu modüldeki tüm yönergeler bir dizgeyi bir dosya yoluna dönüştürerek çalışırlar. Dönüşüm dizgesi (bundan sonra “isim” diyeceğiz) ya sunucu ismi olur (bunun nasıl belirlendiğini öğrenmek için UseCanonicalName yönergesine bakınız) ya da sunucu üzerindeki sanal konağın IP adresi olur. Dönüşümü, printf’inkilerin benzeri birkaç biçem belirteci denetler:

%% Bir % imi yerleştirir.
%p Sanal konağın IP adresini yerleştirir.
%N.M İsmin parçalarını yerleştirir.

N ve M ismin alt dizgelerini belirtmek için kullanılır. N, ismin noktalarla ayrılmış bileşenlerinden seçim yaparken M, N ile seçilen parçadan karakter seçmekte kullanılır. M isteğe bağlı olup mevcut olmaması halinde öntanımlı olarak sıfırdır. Noktanın varlığı M’nin varlığına bağlıdır. Dönüşüm şöyle uygulanır:

0 ismin tamamı
1 ilk parça
2 ikinci parça
-1 son parça
-2 sondan bir önceki parça
2+ ikinci parça ve sonraki parçaların hepsi
-2+ sondan bir önceki parça ve daha önceki parçaların hepsi
1+ ve -1+ 0 ile aynı

N veya M parça sayısından büyükse dönüşüm dizgesi sadece alt çizgi karakterini içerir.

top

Örnekler

Sunucu yapılandırma dosyanızda isme dayalı sanal konaklar için aşağıdaki yönergeler kullanılıyor olsun:

UseCanonicalName    Off
VirtualDocumentRoot "/usr/local/apache/sankonlar/%0"

http://example.com/dizin/dosya.html için yapılan bir istek /usr/local/apache/sankonlar/example.com/dizin/dosya.html dosyası ile yerine getirilecektir.

Çok büyük sayıda sanal konak için sankonlar dizininin boyutlarını küçük tutmak amacıyla dosyalar düzenlenebilir. Bunu yapılandırma dosyanızda şöyle yapabilirsiniz:

UseCanonicalName    Off
VirtualDocumentRoot "/usr/local/apache/sankonlar/%3+/%2.1/%2.2/%2.3/%2"

http://falan.filan.example.com/dizin/dosya.html için yapılan bir istek /usr/local/apache/sankonlar/example.com/f/i/l/filan/dizin/dosya.html ile yerine getirilecektir.

Bu sefer de parçaları ismin sonundan toplayalım:

VirtualDocumentRoot "/usr/local/apache/sankonlar/%3+/%2.-1/%2.-2/%2.-3/%2"

Bu durumda istek /usr/local/apache/sankonlar/example.com/n/a/l/filan/dizin/dosya.html ile karşılanırdı.

Şöyle bir şey de yapabilirsiniz:

VirtualDocumentRoot "/usr/local/apache/sankonlar/%3+/%2.1/%2.2/%2.3/%2.4+"

Bu örnek için istek /usr/local/apache/sankonlar/example.com/f/i/l/an/dizin/dosya.html dosyasından karşılanırdı.

Kullanıcıların çoğunun ortak isteği, istenen konak adının uzunluğu veya sayısı için endişelenmeksizin çok sayıda belge köküne çok sayıda alan adından erişilebilmesidir. Eğer istenen konak adı www.domain.example.com değil de sub.www.domain.example.com ise %3+ kullanımı, belge kök dizininin düşünüldüğü gibi example.com değil /usr/local/apache/vhosts/domain.example.com/... olmasını sağlar. Böyle durumlarda, daima alan adı ve tld ile sonuçlanan %-2.0.%-1.0 birleşiminin kullanımı daha yararlı olabilir. Böylece, tüm ilk, ikinci ve üçüncü seviye alt alan adlarını aynı dizine yönlendirecek bir yapılandırma yapılabilir:

VirtualDocumentRoot "/usr/local/apache/vhosts/%-2.0.%-1.0"

Yukarıdaki örnekte, example.com, www.example.com ve hatta www.sub.example.com bile /usr/local/apache/vhosts/example.com dizinine yönlendirilecektir.

IP’ye dayalı sanal konaklar için yapılandırma dosyanızda şu satırlar olabilirdi:

UseCanonicalName DNS
VirtualDocumentRootIP "/usr/local/apache/sankonlar/%1/%2/%3/%4/belgeler"
VirtualScriptAliasIP  "/usr/local/apache/sankonlar/%1/%2/%3/%4/cgi-bin"

http://falan.filan.example.com/dizin/dosya.html için yapılan bir istek eğer falan.filan.example.com’un IP adresi 10.20.30.40 olsaydı, /usr/local/apache/sankonlar/10/20/30/40/belgeler/dizin/dosya.html dosyası ile karşılanırdı. http://falan.filan.example.com/cgi-bin/betik.pl için yapılan bir istek ise /usr/local/apache/sankonlar/10/20/30/40/cgi-bin/betik.pl betiğinin çalıştırılması ile sağlanırdı.

Bir VirtualDocumentRoot yönergesinin . karakterini içermesini isterseniz, bir biçem belirteci ile karışıklığa sebep olmaksızın bunu şöyle sağlayabilirsiniz:

VirtualDocumentRoot "/usr/local/apache/sankonlar/%2.0.%3.0"

Bu durumda http://falan.filan.example.com/dizin/dosya.html için yapılan bir istek /usr/local/apache/sankonlar/filan.mesela/dizin/dosya.html dosyası ile karşılanacaktır.

LogFormat yönergesinin %V ve %A biçem belirteçleri bu modülle birlikte kullanıldığında çok yararlı olurlar.

top

VirtualDocumentRoot Yönergesi

Açıklama:Bir sanal konağın belge kök dizinini devingen olarak yapılandırır.
Sözdizimi:VirtualDocumentRoot hesaplanan-dizin|none
Öntanımlı:VirtualDocumentRoot none
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_vhost_alias

VirtualDocumentRoot yönergesi sunucu ismine göre belgelerin bulunacağı yeri Apache HTTP Sunucusunun saptamasını sağlar. hesaplanan-dizin’in dönüşüm sonucu DocumentRoot yönergesinin değeriymiş gibi belge ağacının kök dizini olarak kullanılır. hesaplanan-dizin yerine none belirtilmişse VirtualDocumentRoot iptal edilmiş olur. Bu yönerge VirtualDocumentRootIP yönergesinin kullanıldığı bağlamda yer alamaz.

Bilginize

VirtualDocumentRoot yönergesi aynı bağlamda veya alt bağlamlarda da kullanılabilen DocumentRoot yönergelerini geçersiz kılar. Genel sunucu etki alanına bir VirtualDocumentRoot konulması, daha sonra yer alan her sanal konak tanımı içinde VirtualDocumentRoot yönergesine None atamadıkça bu sanal konaklarda yapılmış DocumentRoot atamalarını geçersiz kılacaktır.
top

VirtualDocumentRootIP Yönergesi

Açıklama:Bir sanal konağın belge kök dizinini devingen olarak yapılandırır.
Sözdizimi:VirtualDocumentRootIP hesaplanan-dizin|none
Öntanımlı:VirtualDocumentRootIP none
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_vhost_alias

VirtualDocumentRootIP yönergesi, dizinin saptanmasında sunucu ismi yerine bağlantının sonlandığı sunucunun IP adresini kullanması dışında VirtualDocumentRoot gibidir.

top

VirtualScriptAlias Yönergesi

Açıklama:Bir sanal konağın CGI dizinini devingen olarak yapılandırır.
Sözdizimi:VirtualScriptAlias hesaplanan-dizin|none
Öntanımlı:VirtualScriptAlias none
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_vhost_alias

VirtualScriptAlias yönergesi, CGI betiklerinin bulunacağı yeri Apache httpd’nin saptamasını sağlamak bakımından VirtualDocumentRoot yönergesinin yaptığını yapar. /cgi-bin/ ile başlayan istekler için ise ScriptAlias yönergesinin yaptığını yapar.

top

VirtualScriptAliasIP Yönergesi

Açıklama:Bir sanal konağın CGI dizinini devingen olarak yapılandırır.
Sözdizimi:VirtualScriptAliasIP hesaplanan-dizin|none
Öntanımlı:VirtualScriptAliasIP none
Bağlam:sunucu geneli, sanal konak
Durum:Eklenti
Modül:mod_vhost_alias

VirtualScriptAliasIP yönergesi, dizinin saptanmasında sunucu ismi yerine bağlantının sonlandığı sunucunun IP adresini kullanması dışında VirtualScriptAlias gibidir.

Mevcut Diller:  en  |  fr  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/module-dict.html.tr.utf80000664000175100017510000002266614743132254022234 0ustar covenercovener Modülleri Tanımlamakta Kullanılan Terimler - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4

Modülleri Tanımlamakta Kullanılan Terimler

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

Bu belgede Apache modüllerini tanımlarken kullanılan terimler açıklanmıştır.

Support Apache!

Ayrıca bakınız:

top

Açıklama

Modülün kullanım amacının kısa bir açıklaması.

top

Durum

Modülün Apache HTTP sunucusuna ne kadar sıkı bağlı olduğunu belirtir. Başka bir deyişle, modüle ve işlevselliğine erişim kazanmak için sunucuyu yeniden derlemek gerekip gerekmediği ile ilgili durumu belirtir. Bu özniteliğin olası değerleri şunlardır:

MPM
“MPM” durumlu bir modül bir Çok Süreçlilik Modülüdür. Diğer modül türlerinin aksine, sunucunun kullandığı MPM modülü sayısı birden fazla olamaz. Bu modül türü temelde sunucuya gelen isteklerin ele alınmasından ve öldürülmesinden sorumludur.
Temel
“Temel” durumuyla etiketlenmiş bir modül öntanımlı olarak olarak derlenir ve sunucuya öntanımlı olarak yüklenir. Bu bakımdan derleme öncesi paket yapılandırması sırasında modülün derlenmemesi özellikle istenmedikçe bu modül derlenecek ve sunucuya yüklenecektir.
Eklenti
“Eklenti” durumundaki bir modül normal olarak derlenmez ve sunucuya yüklenmez. Modülü ve işlevselliğini etkin kılmak için sunucunun derleme öncesi paket yapılandırması sırasında modülün derleneceğini açıkça belirttikten sonra gerekirse yeniden derlemeniz gerekir.
Deneysel
“Deneysel” durumu modülün Apache sunucusunun bir parçası olarak kabul edildiğini ancak modülü denemenin tamamen sizin insiyatifinize bırakıldığı anlamına gelir. Böyle bir modül her şeyiyle belgelenmiştir fakat gerektiği gibi desteklenmemiştir.
Harici
“Harici” durumu temel Apache dağıtımında bulunmayan (“üçüncü parti”) modüller için kullanılır. Böyle modüller için sorumluluk kabul etmediğimiz gibi bunları desteklemiyoruz.
top

Kaynak Dosyası

Karşısına modül kodunu içeren kaynak dosyasının ismi yazılır. Bu isim ayrıca <IfModule> yönergesi tarafından da kullanılır.

top

Modül Betimleyici

Modüller devingen olarak yüklenirken LoadModule yönergesinde kullanmak için modülü betimleyen dizgedir. Aslında, kaynak dosyasında module türündeki harici değişkenin ismidir.

top

Uyumluluk

Eğer modül Apache’nin 2. sürüm dağıtımının özgün parçası değilse söz konusu sürüm burada belirtilir. Ayrıca, modülün kullanımı belli platformlarla sınırlıysa bunun ayrıntıları da burada belirtilir.

Mevcut Diller:  en  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_winnt.html.ja.utf80000664000175100017510000002035114743132254021770 0ustar covenercovener mpm_winnt - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache MPM winnt

翻訳済み言語:  de  |  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:Windows NT 向けに最適化されたマルチプロセッシングモジュール
ステータス:MPM
モジュール識別子:mpm_winnt_module
ソースファイル:mpm_winnt.c

概要

このマルチプロセッシングモジュール (MPM) は Windows NT でのデフォルトになります。 一つの制御用プロセスを用い、これが一つの子プロセスを起動し、 そして子プロセスがリクエストを取り扱うためにスレッドを 起動します。

Support Apache!

ディレクティブ

Bugfix checklist

参照

翻訳済み言語:  de  |  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgi.html.ja.utf80000664000175100017510000005232114743132254021363 0ustar covenercovener mod_cgi - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_cgi

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:CGI スクリプトの実行
ステータス:Base
モジュール識別子:cgi_module
ソースファイル:mod_cgi.c

概要

ハンドラ cgi-script が指定されているファイルは CGI スクリプトとして扱われ、 サーバにより実行され、その出力がクライアントに返されます。 ファイルは、AddHandler ディレクティブに指定された 拡張子を名前に含むか、 ScriptAlias ディレクトリに存在することによりこのハンドラになります。

Apache で CGI スクリプトを使用するためのイントロダクションは、 CGI による動的コンテンツ を参照してください。

Unix でマルチスレッドの MPM を使っている場合は、このモジュールの 代わりに mod_cgid を使う必要があります。 ユーザレベルではこの二つのモジュールは本質的には同一です。

後方互換性のため、 MIME タイプが application/x-httpd-cgi であるファイルでも cgi-script ハンドラが有効になります。この特殊な MIME タイプを 使う方法は非推奨です。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

CGI 環境変数

サーバは CGI 規格 で決められている CGI 環境変数を設定します。以下のものは、条件付きで設定されます。

PATH_INFO
これは AcceptPathInfo ディレクティブが明示的に off に設定されている場合は設定されません。デフォルトの、 AcceptPathInfo が 指定されていないときの振る舞いでは、mod_cgi はパス情報 (URI のスクリプトのファイル名の後に続く /more/path/info) を 受け付けますが、コアはサーバはパス情報のあるリクエストに 対して 404 NOT FOUND エラーを返します。AcceptPathInfo ディレクティブを 省略すると、mod_cgi へのリクエストに対して On を 設定したのと同じ効果になります。
REMOTE_HOST
HostnameLookupson (デフォルトでは off です) で、アクセスしているホストのアドレスの DNS の逆引きが実際にホスト名を見つけたときにのみ設定されます。
REMOTE_IDENT
IdentityCheckon に設定されていて、アクセスしているホストが ident プロトコルをサポートしているときにのみ設定されます。 これは簡単に偽ることができ、クライアントとサーバの間に プロキシがあればまったく役に立たないので、 この変数の値は信用できないということに注意してください。
REMOTE_USER
CGI スクリプトに認証が必要なときにのみ設定されます。
top

CGI のデバッグ

CGI スクリプトのデバッグは、正しく動作していないスクリプトの出力 (標準出力とエラー) を調べることができないために、難しい状態が続いていました。 これらのディレクティブはより詳細なエラーのログ収集を提供します。

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

CGIScriptTimeout ディレクティブ

説明:The length of time to wait for more output from the CGI program
構文:CGIScriptTimeout time[s|ms]
デフォルト:value of Timeout directive when unset
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Base
モジュール:mod_cgi
互換性:Available in version 2.4.59 and later.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgid.html.ko.euc-kr0000664000175100017510000002531214743132254022046 0ustar covenercovener mod_cgid - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_cgid

ֽ ƴմϴ. ֱٿ ϼ.
:ܺ 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 þ ߰ ̴.

Support Apache!

þ

Bugfix checklist

top

CGIDScriptTimeout þ

:The length of time to wait for more output from the CGI program
:CGIDScriptTimeout time[s|ms]
⺻:value of Timeout directive when unset or set to 0
:ּ, ȣƮ, directory, .htaccess
:Base
:mod_cgid
:Available in httpd 2.4.10 and later; in prior releases no timeout was applied

The documentation for this directive has not been translated yet. Please have a look at the English version.

top

ScriptSock þ

:cgi ̸
:ScriptSock file-path
⺻:ScriptSock logs/cgisock
:ּ, ȣƮ
:Base
:mod_cgid

þ CGI ̸ Ѵ. ġ ( root) . CGI ũƮ ٸ ڰ ִ 丮 ʴ ߿ϴ.

ScriptSock /var/run/cgid.sock

:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav.html.ko.euc-kr0000664000175100017510000004561014743132254021715 0ustar covenercovener mod_dav - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_dav

ֽ ƴմϴ. ֱٿ ϼ.
: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 Ȯ ̴.

Support Apache!

þ

Bugfix checklist

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

DavBasePath þ

:Configure repository root path
:DavBasePath root-path
⺻:None
:directory
:Extension
:mod_dav
:Available in version 2.4.58 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav_lock.html.ja.utf80000664000175100017510000002501114743132254022377 0ustar covenercovener mod_dav_lock - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_dav_lock

翻訳済み言語:  en  |  fr  |  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 を指定して使う必要が あります。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

DavGenericLockDB ディレクティブ

説明:DAV ロックデータベースの場所
構文:DavGenericLockDB file-path
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ
ステータス:Extension
モジュール:mod_dav_lock

DavGenericLockDB ディレクティブを 使って、拡張子を除いたロックデータベースへのフルパスを 指定します。絶対パスでないときは ServerRoot からの相対パスとして 扱われます。mod_dav_lock の実装ではユーザの ロックを追跡するのに SDBM データベースを使います。

DavGenericLockDB var/DavLock

ロックデータベースファイルのあるディレクトリは Apache が実行されている UserGroup によって 書き込み可能でなければなりません。セキュリティ上の理由から、 既存のディレクトリのパーミッションを変更するのではなく、 専用のディレクトリを作るのが良いでしょう。上の例では、 Apache は ServerRoot の下の var/ ディレクトリに、ファイル名の本体が DavLock で サーバが追加する拡張子を持つファイルを作成します。

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dir.html.ja.utf80000664000175100017510000004724114743132254021404 0ustar covenercovener mod_dir - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_dir

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:「最後のスラッシュ」のリダイレクトと、ディレクトリの インデックスファイルを扱う機能を提供する
ステータス:Base
モジュール識別子:dir_module
ソースファイル:mod_dir.c

概要

ディレクトリインデックスは、次の二つのうちどちらかが利用されます:

自動的なインデックス生成機能を削除 (もしくは交換) できるように、この二つの機能は分離されています。

なお http://servername/foo/dirname という URL へのリクエストがあった際に、dirname というディレクトリがあれば、「最後にスラッシュをつけた形」の URL へのリダイレクトを送出します。 ディレクトリへのアクセスはスラッシュで終わっている必要があり、 mod_dir は、http://servername/foo/dirname/ へのリダイレクトを送出することになります。

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

DirectoryCheckHandler ディレクティブ

説明:Toggle how this module responds when another handler is configured
構文:DirectoryCheckHandler On|Off
デフォルト:DirectoryCheckHandler Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Indexes
ステータス:Base
モジュール:mod_dir
互換性:Available in 2.4.8 and later. Releases prior to 2.4 implicitly act as if "DirectoryCheckHandler ON" was specified.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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.htmlindex.txt のどちらもディレクトリ内に存在しない場合、CGI スクリプト /cgi-bin/index.pl が実行されます。

top

DirectoryIndexRedirect ディレクティブ

説明:Configures an external redirect for directory indexes.
構文:DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code
デフォルト:DirectoryIndexRedirect off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Indexes
ステータス:Base
モジュール:mod_dir
互換性:Available in version 2.3.14 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

DirectorySlash ディレクティブ

説明:パス末尾のスラッシュでリダイレクトするかどうかのオンオフをトグルさせる
構文:DirectorySlash On|Off
デフォルト:DirectorySlash On
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Indexes
ステータス:Base
モジュール:mod_dir
互換性:2.0.51 以降

要求のあった URL がディレクトリを指すかどうかを、 mod_dir が調整するべきかどうかを DirectorySlash ディレクティブで設定します。

典型的には、ユーザが末尾のスラッシュ無しでリソースへのリクエストを発行し、 そして、そのリソースがディレクトリを指していた場合、mod_dir は、末尾にスラッシュを付加した上で同じリソースにリダイレクトさせます。 この挙動には幾つか理由があります:

とはいえ、もしこういった効果を望まない、かつ、 上記のような理由が当てはまらない場合は、リダイレクトを次のようにしてオフにできます:

# see security warning below!
<Location /some/path>
DirectorySlash Off
SetHandler some-handler
</Location>

セキュリティ警告

末尾のスラッシュでのリダイレクトをオフにすると、結果的に情報漏洩を 招くことになるかもしれません。 mod_autoindex が有効 (Options +Indexes) で、 DirectoryIndex が有効なリソース (例えば index.html) を指していて、また、要求のあった URL に特別な ハンドラが設定されていない場合を考えてみてください。 この場合末尾にスラッシュのついているリクエストに対しては index.html ファイルが返されます。しかしスラッシュのないリクエストに対しては、 ディレクトリの内容一覧を返してしまいます。

top

FallbackResource ディレクティブ

説明:Define a default URL for requests that don't map to a file
構文:
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Base
モジュール:mod_dir

Documentation not yet translated. Please see English version of document.

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dumpio.html.ja.utf80000664000175100017510000002450514743132254022121 0ustar covenercovener mod_dumpio - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_dumpio

翻訳済み言語:  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:望むようにすべての I/O をエラーログにダンプする
ステータス:Extension
モジュール識別子:dumpio_module
ソースファイル:mod_dumpio.c

概要

mod_dumpio を使うと、Apache が受け取ったすべての入力と Apache により送られたすべての出力との、両方もしくはどちらか一方を、 エラーログファイルにログ収集 (訳注: ダンプ dump) できます。

データのロギングは、SSL 復号化の直後 (入力) と SSL 暗号化の直前 (出力) に行なわれます。ご想像の通り、 このモジュールはとてつもないデータ量を出力しますので、 問題をデバッグしているときにのみ使用するようにしてください。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_env.html.ja.utf80000664000175100017510000002611414743132254021412 0ustar covenercovener mod_env - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_env

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:CGI スクリプト及び SSI ページに渡される環境変数を変更する機能を提供する
ステータス:Base
モジュール識別子:env_module
ソースファイル:mod_env.c

概要

このモジュールにより CGI スクリプトと SSI ページに適用される環境変数を制御することができるようになります。 環境変数は httpd プロセスを起動したシェルから渡されます。また、 設定ファイルで環境変数を設定したり、削除したりすることができます。

Support Apache!

ディレクティブ

Bugfix checklist

参照

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

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_example_hooks.html.ko.euc-kr0000664000175100017510000002541014743132254023775 0ustar covenercovener mod_example_hooks - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_example_hooks

ֽ ƴմϴ. ֱٿ ϼ.
:ġ API Ѵ
:Experimental
:example_hooks_module
ҽ:mod_example_hooks.c

ġ modules/examples 丮 ִ ϵ ġ API Ͽ ۼϷ .

mod_example_hooks.c ݹ(callback) ȣ ϴ ̴. ⿡ ݹ ʿ䰡 . ݴ!

example ϴ ̴. ϰ Ư ġ "example-hooks-handler" ڵ鷯 ҴϿ װ ¡ϸ example ݹ Ȯ ִ.

Support Apache!

þ

Bugfix checklist

top

example ϱ

example Ϸ ģ:

  1. --enable-example-hooks ɼǰ Բ configure Ѵ.
  2. Ѵ ("make" Ѵ).

ڽ ߰Ϸ:

  1. cp modules/examples/mod_example_hooks.c modules/new_module/mod_myexample.c
  2. Ѵ.
  3. modules/new_module/config.m4 .
    1. APACHE_MODPATH_INIT(new_module) ߰Ѵ.
    2. modules/examples/config.m4 Ͽ "example_hooks" ִ APACHE_MODULE ؿ´.
    3. ù° ƱԸƮ "example_hooks" myexample Ѵ.
    4. ι° ƱԸƮ ڸ ڽ ⿡ ´. configure --help ϸ ⿡ ش.
    5. Ҷ Ư C Ϸ ɼ, Ŀ ɼ, ̺귯 ʿϸ CFLAGS, LDFLAGS, LIBS ߰Ѵ. modules 丮 ִ ٸ config.m4 ϵ ϶.
    6. APACHE_MODPATH_FINISH ߰Ѵ.
  4. module/new_module/Makefile.in . ϴµ Ư ɾ ʿٸ, Ͽ include $(top_srcdir)/build/special.mk ־ ȴ.
  5. ֻ 丮 ./buildconf Ѵ.
  6. --enable-myexample ɼ Ͽ Ѵ
top

mod_example_hooks ϱ

example Ϸ httpd.conf Ͽ ߰϶:

<Location /example-hooks-info>
SetHandler example-hooks-handler
</Location>

ƴϸ .htaccess Ͽ ߰ϰ, ġ "test.example" û϶:

AddHandler example-hooks-handler .example

ġ ¡ϸ տ Ե ̴.

top

Example þ

:ġ API ϱ þ
:Example
:ּ, ȣƮ, directory, .htaccess
:Experimental
:mod_example_hooks

Example þ example ڵ鷯 θ Ѵ. þ ƱԸƮ ʴ´. example ڵ鷯 URL ϸ û ϱ ȿ Լ  ׸  Ҹ ִ. þ ȿ "Example directive declared here: YES/NO" Ȯ ִ.

:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ext_filter.html.ja.utf80000664000175100017510000005556014743132254022776 0ustar covenercovener mod_ext_filter - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_ext_filter

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:レスポンスのボディをクライアントに送る前に外部プログラムで処理する
ステータス:Extension
モジュール識別子:ext_filter_module
ソースファイル:mod_ext_filter.c

概要

mod_ext_filter では フィルタ の慣れ親しんだ単純なプログラミングモデルが提供されます。このモジュールを 使えば、標準入力から読み込んで、標準出力に書き出すプログラム (すなわち Unix 形式のフィルタコマンド) を Apache のフィルタにすることが できます。このフィルタの機構は、Apache API 向けに書かれた Apache サーバプロセス内で実行される専用のフィルタよりもずっと遅いですが、 以下のような利点もあります。

性能の問題により実運用に適さないとしても、フィルタのプロトタイプ用の 環境としては mod_ext_filter は使えます。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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
DebugLevelmod_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 からは デバッグメッセージは生成されません。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_common.html.ja.utf80000664000175100017510000020524714743132254022132 0ustar covenercovener mpm_common - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache MPM 共通ディレクティブ

翻訳済み言語:  de  |  en  |  fr  |  ja  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:二つ以上のマルチプロセッシングモジュール (MPM) で実装されているディレクティブのコレクション
ステータス:MPM
Support Apache!

ディレクティブ

Bugfix checklist

参照

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_whatkilledusmod_backtrace がこのフックを活用します。これらの詳細については Jeff Trawick さんの EnableExceptionHook site を参照してください。

top

GracefulShutdownTimeout ディレクティブ

説明:穏やかな停止をかけた後、終了するまで待つ時間
構文:GracefulShutDownTimeout seconds
デフォルト:GracefulShutDownTimeout 0
コンテキスト:サーバ設定ファイル
ステータス:MPM
モジュール:prefork, worker, event
互換性:2.2 以降

GracefulShutdownTimeout には サーバーが "graceful-stop" シグナルを受け取ってから現在の リクエストの処理を最大で何秒間続けるかを指定します。

この値をゼロに設定すると、処理中として残っているリクエストが 全て完了するまでサーバーは終了しません。

top

Listen ディレクティブ

説明:サーバが listen するIP アドレスとポート番号
構文:Listen [IP-address:]portnumber [protocol]
コンテキスト:サーバ設定ファイル
ステータス:MPM
モジュール:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker, event
互換性:Apache 2.0 から必須ディレクティブ。protocol 引数は 2.1.5 で追加。

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 [2001:db8::a00:20ff:fea7:ccea]:80

protocol オプション引数は通常の設定では必要ありません。 無指定の場合、443 番ポートには https が、他のポートには http がデフォルト値として使用されます。 protocol 指定は、どのモジュールがリクエストを処理するかを決定し、 AcceptFilter によるプロトコル特有の最適化を行うようにします。

非標準なポートで運用している際にのみ protocol 指定が必要になります。 たとえば https なサイトを 8443 番ポートで運用している場合 :

Listen 192.170.2.1:8443 https

エラー条件

同一 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

ListenCoresBucketsRatio ディレクティブ

説明:Ratio between the number of CPU cores (online) and the number of listeners' buckets
構文:ListenCoresBucketsRatio ratio
デフォルト:ListenCoresBucketsRatio 0 (disabled)
コンテキスト:サーバ設定ファイル
ステータス:MPM
モジュール:event, worker, prefork
互換性:Available in Apache HTTP Server 2.4.17, with a kernel supporting the socket option SO_REUSEPORT and distributing new connections evenly across listening processes' (or threads') sockets using it (eg. Linux 3.9 and later, but not the current implementations of SO_REUSEPORT in *BSDs.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

MaxConnectionsPerChild ディレクティブ

説明:Limit on the number of connections that an individual child server will handle during its life
構文:MaxConnectionsPerChild number
デフォルト:MaxConnectionsPerChild 0
コンテキスト:サーバ設定ファイル
ステータス:MPM
モジュール:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
互換性:Available Apache HTTP Server 2.3.9 and later. The old name MaxRequestsPerChild is still supported.

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

MaxMemFree ディレクティブ

説明:free() が呼ばれない限り、 主メモリアロケータが保持し続けられるメモリの最大量
構文:MaxMemFree KBytes
デフォルト:MaxMemFree 0
コンテキスト:サーバ設定ファイル
ステータス:MPM
モジュール:beos, leader, mpm_netware, prefork, threadpool, worker, mpm_winnt

MaxMemFree ディレクティブは free() が呼ばれない限り、 主アロケータが保持できる空のメモリの最大値をキロバイト単位で設定します。 設定されていないか、零に設定されているときは、無制限になります。

top

MaxRequestWorkers ディレクティブ

説明:Maximum number of connections that will be processed simultaneously
構文:MaxRequestWorkers number
デフォルト:See usage for details
コンテキスト:サーバ設定ファイル
ステータス:MPM
モジュール:event, worker, prefork

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

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 はシングルプロセスで実行されますので、 スペアスレッド数もサーバ全体で勘定します。

beosmpmt_os2mpm_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 で、 アイドルスレッド数を子プロセス毎に監視します。 もし子プロセスに十分な数のスレッドがなければ、 サーバはその子プロセスに新しいスレッドを作り始めます。 ですから、NumServers10 に、MinSpareThreads5 にした場合は、最小でも 50 のアイドルスレッドが システム上にあることになります。

worker, leader, threadpool では、 デフォルトは MinSpareThreads 75 で、 アイドルスレッド数をサーバ全体で監視します。 もしサーバに十分な数のアイドルスレッドがなければ、 アイドルスレッド数がこの数 number よりも大きくなるまで 新しい子プロセスが生成されます。

mpm_netware では、 デフォルトは MinSpareThreads 10 で、 シングルプロセス MPM ですので、サーバ全体で管理されます。

beosmpmt_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

サーバが ErrorLogTransferLog を閉じて開き直したり、設定ファイルを 再読込したりさせるために、サーバにシグナルを送ることができると 便利なことがあります。 これは SIGHUP (kill -1) シグナルを PidFile に書かれているプロセス ID に送ることでできます。

PidFile には、ログファイルの設置位置や セキュリティ と全く同じ注意点があります。

注意

Apache 2 では、 apachectl スクリプトのみを使用してサーバの (再) 起動や停止を 行なうことを推奨しています。

top

ReceiveBufferSize ディレクティブ

説明:TCP 受信バッファサイズ
構文:ReceiveBufferSize bytes
デフォルト:ReceiveBufferSize 0
コンテキスト:サーバ設定ファイル
ステータス:MPM
モジュール:beos, mpm_netware, mpm_winnt, mpmt_os2, prefork, worker

サーバは TCP 受信バッファサイズを指定されたバイト数に設定します。

0にした場合、OS のデフォルト値が使用されます。

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 に設定可能な上限値を設定することになります。 このディレクティブを変更して再起動(訳注: apachectl restart)しても無視されますが、 MaxClients は再起動で変更することができます。

このディレクティブを使用する際は特に注意してください。 ServerLimit が必要以上に大きな値に 設定された場合は、余計な未使用共有メモリが割り当てられます。 ServerLimitMaxClients がシステムの扱える範囲を越えた設定値になっていると、 Apache は起動しないか、起動しても不安定になるでしょう。

prefork MPM では、 MaxClients を 256 (デフォルト) よりも大きな値に設定する必要がある時にだけ使用してください。 希望の MaxClients 数とくらべて、必要以上に大きな値を指定することは避けてください。

worker, leader, threadpool MPM では、 MaxClientsThreadsPerChild の設定で 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, workerStartServers 3 です。 prefork5 で、 mpmt_os22 です。

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 は再起動中に、このディレクティブで指定された上限値まで 変更することができます。

このディレクティブを使用する際は特に注意してください。 ThreadLimitThreadsPerChild よりもずっと大きな値に設定された場合は、 余計な未使用共有メモリが割り当てられてしまいます。 ThreadLimitThreadsPerChild の両方がシステムの扱える範囲を超えている場合は、 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 の指定しているスタックサイズのデフォルト値は 適切なものですが、調整が必要になる場合もあります:

翻訳済み言語:  de  |  en  |  fr  |  ja  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/prefork.html.ja.utf80000664000175100017510000004175214743132254021440 0ustar covenercovener prefork - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache MPM prefork

翻訳済み言語:  de  |  en  |  fr  |  ja  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:スレッドを使わず、先行して fork を行なうウェブサーバを実装
ステータス:MPM
モジュール識別子:mpm_prefork_module
ソースファイル:prefork.c

概要

このマルチプロセッシングモジュール (MPM) は、 Unix 上での Apache 1.3 のデフォルトの挙動と非常によく似た方法で リクエストを処理する、スレッドを使わず、先行して fork を行なう ウェブサーバを実装しています。 スレッドセーフでないライブラリとの互換性をとるために、 スレッドを避ける必要のあるサイトでは、このモジュールの使用が適切でしょう。 あるリクエストで発生した問題が他のリクエストに影響しないように、 個々のリクエストを単離するのにも、最適な MPM です。

この MPM は非常に自律的なので、この MPM の設定ディレクティブを 調整する必要はほとんどないでしょう。もっとも重要なことは、 MaxClients が、予想される同時リクエスト数を十分扱えるぐらいは大きいけれども、 全プロセスに十分な物理メモリが確実に行き渡る程度には小さい値にする、 ということです。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

動作方法

一つのコントロールプロセスが、 コネクションに対して listen して、しかるべき時に応答する 子プロセスを起動します。Apache は常に幾つかのスペア かアイドルなサーバプロセスを維持していて、それらは入ってきた リクエストに応答できるように待機しています。 このようにしてクライアントは、リクエストが応答される前に、 新しい子プロセスが fork されるのを待たなくてもよいように なっています。

親プロセスがリクエストに応答するの子プロセスを どのように生成するかは、 StartServers, MinSpareServers, MaxSpareServers, MaxClients で調整します。一般的に、Apache は非常に自律的なので、 大抵のサイトではこれらのディレクティブをデフォルト値から調整する 必要はないでしょう。 同時に 256 を超えるリクエストに応答しないといけないサイトでは、 MaxClients を増やす必要があるでしょう。 一方、メモリの限られているサイトでは、スラッシング (メモリとディスク間で何度もスワップ) が起こるのを防ぐために MaxClients を減らす必要があるでしょう。プロセス生成のチューニングに関する 詳しい情報は、性能に関するヒント にあります。

通常 Unix では親プロセスは 80 番ポートにバインドするために root で起動されますが、子プロセスやスレッドは もっと低い権限のユーザで Apache によって起動されます。 UserGroup ディレクティブは 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 個の割合で新しい子プロセスを生成します。

非常に混んでいるサイトでのみ、このパラメータをチューニングするべきです。 このパラメータを大きくするということは、大抵の場合は悪い発想です。

参照

翻訳済み言語:  de  |  en  |  fr  |  ja  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_headers.html.ja.utf80000664000175100017510000006201614743132254022236 0ustar covenercovener mod_headers - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_headers

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:HTTP リクエストのヘッダと応答のヘッダのカスタマイズ
ステータス:Extension
モジュール識別子:headers_module
ソースファイル:mod_headers.c
互換性:RequestHeader は Apache 2.0 以降のみで使用可能

概要

このモジュールは HTTP のリクエストヘッダと応答ヘッダを制御し、 変更するためのディレクティブを提供します。ヘッダを追加したり、 置き換えたり、削除したりすることができます。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

処理の順番

mod_headers のディレクティブはサーバ設定のほぼどこにでも 書くことができ、影響する範囲を設定用セクションで囲むことで限定する ことができます。

処理の順番は重要で、設定ファイル中の順番と、設定用セクション内の位置との両方に 影響されます。以下の二つのヘッダは順番が逆になると 違う結果になります:

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. リクエストを受け付けた時刻とリクエストを処理した時間を入れたヘッダ、 MyHeader を応答に追加します。このヘッダはクライアントが サーバの負荷を直観的に知るためや、クライアント-サーバ間の ボトルネックを調べるために使うことができます。

    Header add MyHeader "%D %t"

    上記の設定では、以下のようなヘッダが応答に追加されることになります:

    MyHeader: D=3775428 t=991424704447256

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

  4. リクエストに "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

top

Header ディレクティブ

説明:HTTP 応答ヘッダの設定
構文:Header [condition] set|append|add|unset|echo header [value] [early|env=[!]variable]
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Extension
モジュール:mod_headers

このディレクティブは HTTP 応答ヘッダを置換、追加、削除できます。 ヘッダはコンテントハンドラや出力フィルタが実行された直後に実行され、 出て行くヘッダを変更できるようになっています。

オプションの conditiononsuccessalways のどちらかを指定できます。これは内部ヘッダテーブルのどれを 操作するかを決定します。onsuccess2xx ステータスコードの、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}s mod_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 の入力フィルタにより 生成されたヘッダを上書きしたり修正したりできるようになっています。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ident.html.ko.euc-kr0000664000175100017510000002274314743132254022250 0ustar covenercovener mod_ident - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_ident

:RFC 1413 ident ˻
:Extension
:ident_module
ҽ:mod_ident.c
:ġ 2.1 ĺ

ڸ ã ȣƮ ִ RFC 1413 ȣȯ ˻Ѵ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_info.html.ja.utf80000664000175100017510000003617614743132254021566 0ustar covenercovener mod_info - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_info

翻訳済み言語:  en  |  fr  |  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 にアクセスすることでサーバの情報を得られるようになります。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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 は、元の設定ファイルを読むのではなく、 既にパースされた設定を読み込むことで情報を提供します。従って、 パース済みの設定情報の木が生成される方法による制限がいくつかあります:

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.4/mod/mod_deflate.html">\
http://www.apache.org/docs/2.4/mod/mod_deflate.html</a>'

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_forensic.html.ja.utf80000664000175100017510000003431014743132254023270 0ustar covenercovener mod_log_forensic - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_log_forensic

翻訳済み言語:  en  |  fr  |  ja  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:サーバに送られたリクエストの forensic ロギング
ステータス:Extension
モジュール識別子:log_forensic_module
ソースファイル:mod_log_forensic.c
互換性:mod_unique_id はバージョン 2.1 からは必須では なくなった

概要

このモジュールはクライアントリクエストの forensic ロギングを 行ないます。ログ収集はリクエストの処理の前と後に行なわれますので、 forensic ログは各リクエストに対して二行ログ収集します。 Forensic ロガーは非常に厳密です。これは以下のことを意味します:

Forensic ログの出力を検査するためには、 配布物の support ディレクトリにある check_forensic スクリプトが役に立つでしょう。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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_forensicforensic-id というトークンを作成し、フォーマット文字列 %{forensic-id}n を使うことでそのトークンを transfer ログに 追加することができます。

引数はログが書き出される位置を指定し、以下の 2種類の値のどちらかを 取ることができます:

filename
ServerRoot からの 相対ファイル名
pipe
パイプ文字 "|" と、その後にログ情報を標準入力から 受け取るプログラム。プログラム名は ServerRoot からの相対パスとしても 指定できます。

セキュリティ:

プログラムを使う場合、そのプログラムは httpd を起動したユーザで 実行されます。つまり、サーバが root で実行された場合は root で 実行されるということです。プログラムが安全であるか、より権限の少ない ユーザに切り替えるようになっていることを確かめてください。

Unix 以外のプラットフォームでファイル名を入力するときは、 プラットフォームがバックスラッシュの使用を許可している場合でも、 スラッシュのみが使われるように気をつけてください。 普通は設定ファイルすべてにおいて、スラッシュの方を使用するように してください。

翻訳済み言語:  en  |  fr  |  ja  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_logio.html.ko.euc-kr0000664000175100017510000002235514743132254022255 0ustar covenercovener mod_logio - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_logio

ֽ ƴմϴ. ֱٿ ϼ.
:û Ʈ
:Extension
:logio_module
ҽ:mod_logio.c

û Ʈ Ѵ. ڴ Ʈ ְ Ʈ Ÿ, û Ѵ. Է SSL/TLS , SSL/TLS Ŀ ⶧ ȣȭ ùٷ ݿȴ.

Ϸ mod_log_config ʿϴ.

Support Apache!

þ

Bugfix checklist

top

α

ΰ ο αþ ߰Ѵ. ûü Ư Ĺڿ "%" þ Ͽ Ѵ. þ αϿ Ѵ:

Ĺڿ
%...I û Ͽ Ʈ. 0 .
%...O Ͽ Ʈ. 0 .

Ѵ:

յ α :
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %I %O"
top

LogIOTrackTTFB þ

:Enable tracking of time to first byte (TTFB)
:LogIOTrackTTFB ON|OFF
⺻:LogIOTrackTTFB OFF
:ּ, ȣƮ, directory, .htaccess
Override ɼ:All
:Extension
:mod_logio
:Apache HTTP Server 2.4.13 and later

The documentation for this directive has not been translated yet. Please have a look at the English version.

:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/worker.html.tr.utf80000664000175100017510000004020414743132254021323 0ustar covenercovener worker - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache MPM worker

Mevcut Diller:  de  |  en  |  fr  |  ja  |  tr 

Açıklama:Çok evreli ve çok süreçli melez bir HTTP sunucusu oluşturan çok süreçlilik modülü.
Durum:MPM
Modül Betimleyici:mpm_worker_module
Kaynak Dosyası:worker.c

Özet

Bu çok süreçlilik modülü (MPM) hem çok süreçli hem de çok evreli olabilen melez bir sunucu oluşturur. İstekleri sunmak için evreleri kullanması sebebiyle çok süreçli bir sunucudan daha az sistem kaynağı harcayarak daha çok isteğe hizmet sunabilir. Bununla birlikte, herbiri çok sayıda evreye sahip çok sayıda süreci canlı tutarak bir çok süreçli sunucu kadar kararlı olur.

Bu MPM’i denetim altında tutmakta kullanılan en önemli yönergeler, her çocuk süreç için konuşlandırılacak evre sayısını belirleyen ThreadsPerChild yönergesi ile devreye sokulacak toplam evre sayısının azamisini belirleyen MaxRequestWorkers yönergesidir.

Support Apache!

Konular

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

Nasıl çalışır?

Çocuk süreçleri devreye almaktan tek bir süreç (ana süreç) sorumludur. Her çocuk süreç ThreadsPerChild yönergesinde belirtilen sayıda evre konuşlandırır. Bunlardan ayrı olarak, bir dinleyici evre bağlantıları dinleyip gelenleri işlenmek üzere bu sunucu evrelerinden birine aktarır.

Apache HTTP Sunucusu daima, gelen isteklere hizmet sunmaya hazır yedek veya boştaki sunucu evrelerinden oluşan bir havuzu canlı tutmaya çalışır. Bu suretle, istemcilere isteklerinin sunulması için yeni çocuk süreçlerin çatallanmasını, dolayısıyla yeni evrelerin konuşlandırılmasını beklemek gerekmez. Başlangıçta çalıştırılacak çocuk süreçlerin sayısı StartServers yönergesinde belirtilir. Apache httpd, çalışma süresi boyunca MinSpareThreads ve MaxSpareThreads yönergeleri ile belirtilen sınırlar dahilinde kalmak üzere gerektiğinde süreçleri öldürerek gerektiğinde yenilerini devreye alarak tüm süreçlerdeki toplam evre sayısını sabit tutmaya çalışır. Bu işlem kendiliğinden çok iyi yürüdüğünden bu yönergelere öntanımlı değerlerinden farklı değerlerin atanması nadiren gerekli olur. Aynı anda hizmet sunulabilecek istemcilerin sayısı (yani, tüm süreçlerin toplam evre sayısı) MaxRequestWorkers yönergesi ile belirlenir. Etkin çocuk süreçlerin sayısı ise MaxRequestWorkers yönergesindeki değerin ThreadsPerChild yönergesindeki değere bölünmesi ile elde edilir.

Bu iki yönerge aynı anda etkin olabilecek çocuk süreçlerin ve her çocuk süreçteki sunucu evreleri sayısının üst sınırını belirler ve bu sınır sadece ana sunucu tamamen durdurulup yeniden başlatılarak değiştirilebilir. ServerLimit yönergesinin değeri etkin çocuk süreç sayısının üst sınırı olup MaxRequestWorkers yönergesindeki değerin ThreadsPerChild yönergesindeki değere bölünmesi ile elde değere eşit veya bundan küçük olması gerekir. ThreadLimit yönergesinin değeri ise sunucu evreleri sayısının üst sınırını belirler ve ThreadsPerChild yönergesindeki değerden büyük veya ona eşit olması gerekir.

Sonlandırma sırasında etkin çocuk süreçlere ek olarak mevcut istemci bağlantılarını işleme sokmaya çalışan tek bir sunucu evresinden başka fazladan bir çocuk süreç etkin kalabileceği gibi sonlandırılacak süreç sayısının en fazla MaxRequestWorkers olması gerekirse de gerçekte sayı bundan küçük olabilir. Şöyle bir işlemle tek bir çocuk sürecin sonlandırılması iptal edilerek bu gibi durumlara karşı önlem alınabilir:

worker modülünün öntanımlı süreç-evre yapılandırması genelde şöyledir:

ServerLimit         16
StartServers         2
MaxRequestWorkers  150
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25

Unix altında 80. portu dinleyebilmek için ana sürecin root tarafından çalıştırılmış olması gerekirse de çocuk süreçler ve evreler Apache httpd tarafından daha az yetkili bir kullanıcının aidiyetinde çalıştırılırlar. Apache httpd’nin çocuk süreçlerinin kullanıcı ve gruplarını ayarlamak için User ve Group yönergeleri kullanılır. Çocuk süreçlerin sunacakları içeriği okumaya yetkili olmaları gerekir, fakat bu yetkinin mümkün olduğunca kısıtlı tutulmasına çalışılmalıdır. Bundan başka, suexec kullanılmadığı takdirde, bu yönergeler CGI betikleri tarafından miras alınacak yetkili kullanıcı ve grubu da ayarlarlar.

MaxConnectionsPerChild yönergesi ana sunucunun eski süreçleri öldürüp yenilerini oluşturmayı ne kadar sıklıkla yapacağını denetler.

Bu MPM, gürleyen sürü sorunu ortaya çıktığında (genelde çok sayıda dinlenen soket varlığında) gelen bağlantılara erişimi dizgileştirmek için mpm-accept muteksini kullanır. Bu muteksin gerçeklenimle ilgili hususları Mutex yönergesi ile yapılandırılabilir. Bu muteks hakkında ek bilgi için başarımın arttırılması belgesine bakınız.

Mevcut Diller:  de  |  en  |  fr  |  ja  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_negotiation.html.ja.utf80000664000175100017510000005503514743132254023146 0ustar covenercovener mod_negotiation - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_negotiation

翻訳済み言語:  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:コンテントネゴシエーション 機能を提供する
ステータス:Base
モジュール識別子:negotiation_module
ソースファイル:mod_negotiation.c

概要

コンテントネゴシエーション、より正確にはコンテンツの選択機能は、 複数用意されているドキュメントから、クライアントの能力に一番合った ドキュメントを選択する機能です。この実装は二つあります。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

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 ヘッダでは ende の品質が共に .500 (同じくらい許容) であるときは、 最初にマッチする variant の en が送られます。

LanguagePriority en fr de
ForceLanguagePriority Prefer

ForceLanguagePriority Fallback では、HTTP 406 (NOT ACCEPTABLE) を送信する代わりに、 LanguagePriority が正しい結果を送ります。 以下のディレクティブが指定されていて、ユーザの Accept-Languagees 言語のみを許可していて、さらにそのような variant がないときには、 以下の LanguagePriority のリストの最初の variant が送られます。

LanguagePriority en fr de
ForceLanguagePriority Fallback

PreferFallback の両方のオプションを 同時に指定することができます。 ですから、複数の 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.frfoo.html.de が両方存在し、 ブラウザが言語の優先順位を提供してない場合は foo.html.fr が返されます。

このディレクティブは他の方法で「最善」 の言語が決定できないときか、ForceLanguagePriority ディレクティブが None 以外のときにのみ効果があることに注意してください。 一般的には、サーバ側ではなくクライアント側で好みの言語を決定します。

参照

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/worker.html.ja.utf80000664000175100017510000004117714743132254021302 0ustar covenercovener worker - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache MPM worker

翻訳済み言語:  de  |  en  |  fr  |  ja  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:マルチスレッドとマルチプロセスのハイブリッド型 ウェブサーバを実装したマルチプロセッシングモジュール
ステータス:MPM
モジュール識別子:mpm_worker_module
ソースファイル:worker.c

概要

このマルチプロセッシングモジュール (MPM) は、マルチスレッドとマルチプロセスのハイブリッド型サーバを 実装しています。リクエストの応答にスレッドを使うと、 プロセスベースのサーバよりも少ないシステム資源で、 多くのリクエストに応答することができます。 それにもかかわらず、多くのスレッドを持った複数のプロセスを 維持することで、 プロセスベースのサーバの持つ安定性も保持しています。

この MPM を制御するのに使われる最も重要なディレクティブは、 ThreadsPerChildMaxClients です。 ThreadsPerChild は 各子プロセスで用意されるスレッド数を制御して、 MaxClients は 起動されるスレッドの総数の最大値を制限します。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

動作方法

一つの制御用プロセス (親) が子プロセスを起動します。 子プロセスは ThreadsPerChild ディレクティブで指定された一定数のサーバスレッドと接続を listen するスレッドを一つ作ります。 Listener スレッドは接続が来たときにサーバプロセスに渡します。

Apache はスペアの、つまりアイドルなサーバスレッドの プールを常に維持していて、それらは入ってくるリクエストに 答えられるように待機しています。 このようにして、クライアントはリクエストの応答が得られるようになるために 新しいスレッドやプロセスが生成されるのを 待たなくてもよいようになっています。 起動初期時のプロセス総数は、 StartServers ディレクティブで設定されます。稼働中に、 Apache は全プロセスのアイドルスレッドの合計数を見積もって、 MinSpareThreadsMaxSpareThreads で指定された範囲の中にこの数が収まるように fork したり kill したりします。この操作は非常に自律的なので、 これらのディレクティブをデフォルト値から変更する必要は めったにないでしょう。 同時に応答することのできるクライアント数の最大数 (つまり全プロセス中の総スレッド数の最大値) は MaxClients ディレクティブで決定されます。 活動中の子プロセス数の最大値は MaxClientsThreadsPerChild で割った ものになります。

活動中の子プロセスの数と子プロセス中のサーバスレッドの数の越えられない 上限を設定するディレクティブが二つあります。これらはサーバを 完全に停止して、再起動することでしか変更することはできません。 ServerLimit は活動中の子プロセスの越えられない上限を設定し、 MaxClients ディレクティブ の値を ThreadsPerChild の値で割った値以上である 必要があります。ThreadLimit は サーバスレッドの越えられない上限で、ThreadsPerChild ディレクティブの 値以上である必要があります。

活動中の子プロセス群に加えて、少なくとも一つのサーバスレッドが 既存のクライアントからの接続を扱っている終了しようとしている 子プロセスがある可能性があります。終了中のプロセスは MaxClients で指定された数まで 存在できますが、実際に期待される数はずっと少なくなります。この 振舞いは各子プロセスを終了させないようにすることで回避できます。 これは以下の様にして実現できます。

worker MPM の典型的なプロセス・スレッド制御の 設定では、次のようになります。

ServerLimit 16
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25

通常 Unix では親プロセスは 80 番ポートにバインドするために root で起動されますが、子プロセスやスレッドは もっと低い権限のユーザで Apache によって起動されます。 UserGroup ディレクティブは Apache の子プロセスの権限を設定するのに用いられます。 子プロセスはクライアントに送るコンテンツ全てを読めないといけませんが、 可能な限り必要最小限の権限のみを持っているようにするべきです。 さらに、suexec が使用されていない限り、これらのディレクティブは CGI スクリプトで継承される権限も設定します。

MaxRequestsPerChild は、古いプロセスを停止して新しいプロセスを起動することによって、 どの程度の頻度でサーバがプロセスをリサイクルするかを制御します。

翻訳済み言語:  de  |  en  |  fr  |  ja  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/index.html.fr.utf80000664000175100017510000006172514740503670021117 0ustar covenercovener Index des modules - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4

Index des modules

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Ci-dessous se trouve la liste de tous les modules qui font partie de la distribution du serveur HTTP Apache. Voir aussi la liste alphabétique complète de toutes les directives du serveur HTTP Apache.

Voir aussi

top

Fonctionalités de Base et Modules Multi-Processus (MPM)

core
Fonctionnalités de base du serveur HTTP Apache toujours disponibles
mpm_common
Une série de directives implémentées par plusieurs modules multi-processus (MPM)
event
Une variante du MPM worker conçue pour ne mobiliser des threads que pour les connexions en cours de traitement
mpm_netware
Module multi-processus implémentant un serveur web basé exclusivement sur les threads et optimisé pour Novell NetWare
mpmt_os2
MPM hybride multi-processus, multi-thread pour OS/2
prefork
Implémente un serveur web avec démarrage anticipé de processus, sans thread
mpm_winnt
Module multi-processus optimisé pour Windows NT.
worker
Module multi-processus implémentant un serveur web hybride multi-processus multi-thread
top

Autres Modules

 A  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
Autorisations de groupe à base de nom d'hôte (nom ou adresse IP)
mod_actions
Exécution des scripts CGI en fonction du type de média ou de la méthode de requête.
mod_alias
Permet d'atteindre différentes parties du système de fichiers depuis l'arborescence des documents du site web, ainsi que la redirection d'URL
mod_allowmethods
Ce module permet de restreindre aisément les méthodes HTTP pouvant être utilisées sur le serveur
mod_asis
Envoie des fichiers contenant leurs propres en-têtes HTTP
mod_auth_basic
Authentification HTTP de base
mod_auth_digest
Authentification utilisateur utilisant les condensés MD5
mod_auth_form
Authentification à l'aide d'un formulaire
mod_authn_anon
Permet un accès "anonyme" à des zones protégées
mod_authn_core
Le noyau de l'authentification
mod_authn_dbd
Authentification utilisateur à l'aide d'une base de données SQL
mod_authn_dbm
Authentification utilisateur utilisant des fichiers DBM
mod_authn_file
Authentification utilisateur à l'aide de fichiers texte
mod_authn_socache
Gère un cache des données d'authentification pour diminuer la charge des serveurs d'arrière-plan
mod_authnz_fcgi
Permet à une application d'autorisation FastCGI de gérer l'authentification et l'autorisation httpd.
mod_authnz_ldap
Permet d'utiliser un annuaire LDAP pour l'authentification HTTP de base.
mod_authz_core
Autorisation basique
mod_authz_dbd
Autorisation en groupe et reconnaissance d'identité avec base SQL
mod_authz_dbm
Autorisation basée sur les groupes à l'aide de fichiers DBM
mod_authz_groupfile
Autorisation basée sur les groupes à l'aide de fichiers textes
mod_authz_host
Autorisations de groupe basées sur l'hôte (nom ou adresse IP)
mod_authz_owner
Autorisation basée sur l'appartenance des fichiers
mod_authz_user
Autorisation basée sur l'utilisateur
mod_autoindex
Génère automatiquement des index de répertoires d'une manière similaire à la commande Unix ls, ou à la commande shell Win32 dir
mod_brotli
Compression du contenu via Brotli avant sa livraison au client
mod_buffer
Support de la mise en tampon des requêtes
mod_cache
Filtre de mise en cache HTTP conforme à la RFC 2616
mod_cache_disk
Module de stockage sur disque pour le filtre de mise en cache HTTP.
mod_cache_socache
Module de stockage à base de cache d'objets partagés (socache) pour le filtre de mise en cache HTTP.
mod_cern_meta
La sémantique des métafichiers du serveur httpd du CERN
mod_cgi
Exécution des scripts CGI
mod_cgid
Exécution des scripts CGI par l'intermédiaire d'un démon CGI externe
mod_charset_lite
Spécifie dans quel jeu de caractère doivent s'effectuer les traductions ou les réencodages
mod_data
Convertit un corps de réponse en URL de type données RFC2397
mod_dav
Fonctionnalité de création et gestion de versions de documents via le web (WebDAV)
mod_dav_fs
Implémente le fournisseur filesystem pour mod_dav
mod_dav_lock
Module de verrouillage générique pour mod_dav
mod_dbd
Gestion des connexions à une base de données SQL
mod_deflate
Comprime le contenu avant de le servir au client
mod_dialup
Envoie le contenu statique avec une bande passante limitée définie par les différents standards des anciens modems.
mod_dir
Permet la redirection des adresses se terminant par un répertoire sans slash de fin et la mise à disposition des fichiers index de répertoire
mod_dumpio
Enregistre toutes les entrées/sorties dans le journal des erreurs de la manière souhaitée.
mod_echo
Un simple serveur d'écho pour illustrer les modules de protocole
mod_env
Modifie l'environnement transmis aux scripts CGI et aux pages SSI
mod_example_hooks
Illustration de l'API des modules Apache
mod_expires
Génération des en-têtes HTTP Expires et Cache-Control en fonction de critères spécifiés par l'utilisateur
mod_ext_filter
Fait traiter le corps de la réponse par un programme externe avant de l'envoyer au client
mod_file_cache
Mise en cache mémoire d'une liste statique de fichiers
mod_filter
Module de configuration de filtre intelligent sensible au contexte
mod_headers
Personnalisation des en-têtes de requêtes et de réponses HTTP
mod_heartbeat
Envoie des messages d'état au mandataire frontal
mod_heartmonitor
Moniteur centralisé pour les serveurs d'origine mod_heartbeat
mod_http2
Support de la couche transport HTTP/2
mod_ident
Recherche d'identité conformément à la RFC 1413
mod_imagemap
Traitement des cartes des zones interactives d'une image (imagemaps) au niveau du serveur
mod_include
Documents html interprétés par le serveur (Server Side Includes ou SSI)
mod_info
Affiche une présentation complète de la configuration du serveur
mod_isapi
Extensions ISAPI dans Apache pour Windows
mod_lbmethod_bybusyness
Algorithme de planification avec répartition de charge de l'attribution des requêtes en attente pour le module mod_proxy_balancer
mod_lbmethod_byrequests
Algorithme de planification avec répartition de charge du traitement des requêtes pour le module mod_proxy_balancer
mod_lbmethod_bytraffic
Algorithme de planification avec répartition de charge en fonction d'un niveau de trafic pour le module mod_proxy_balancer
mod_lbmethod_heartbeat
Algorithme d'ordonnancement de répartition de charge pour mod_proxy_balancer basé sur le comptage de trafic Heartbeat
mod_ldap
Conservation des connexions LDAP et services de mise en cache du résultat à destination des autres modules LDAP
mod_log_config
Journalisation des requêtes envoyées au serveur
mod_log_debug
Journalisation supplémentaire à des fins de débogage
mod_log_forensic
Journalisation légale des requêtes envoyées au serveur
mod_logio
Journalisation des octets en entrée et en sortie pour chaque requête
mod_lua
Fournit des points d'entrée Lua dans différentes parties du traitement des requêtes httpd
mod_macro
Ce module permet d'utiliser des macros dans les fichiers de configuration Apache.
mod_md
Gestion des domaines au sein des serveurs virtuels et obtention de certificats via le protocole ACME
mod_mime
Associe les extensions des fichiers demandés avec l'action déclenchée par ces fichiers et avec leur contenu (type MIME, langue, jeu de caractère et codage)
mod_mime_magic
Détermine le type MIME d'un fichier à partir de quelques octets de son contenu
mod_negotiation
Effectue la négociation de contenu
mod_nw_ssl
Active le chiffrement SSL pour Netware
mod_privileges
Support des privilèges de Solaris et de l'exécution des serveurs virtuels sous différents identifiants utilisateurs.
mod_proxy
Serveur mandataire/passerelle multi-protocole
mod_proxy_ajp
Module de support AJP pour mod_proxy
mod_proxy_balancer
Extension de mod_proxy pour le support de la répartition de charge
mod_proxy_connect
Extension de mod_proxy pour le traitement des requêtes CONNECT
mod_proxy_express
Extension à mod_proxy pour le mandatement dynamique inverse de masse
mod_proxy_fcgi
Module fournissant le support de FastCGI à mod_proxy
mod_proxy_fdpass
Module fournissant le support des processus externes fdpass à mod_proxy
mod_proxy_ftp
Module fournissant le support FTP à mod_proxy
mod_proxy_hcheck
Check up dynamique des membres du groupe de répartition de charge (équipiers) pour mod_proxy
mod_proxy_html
Réécrit les liens HTML afin de s'assurer qu'ils soient bien adressables depuis les réseaux des clients dans un contexte de mandataire.
mod_proxy_http
Module fournissant le support HTTP à mod_proxy
mod_proxy_http2
Support de HTTP/2 pour mod_proxy
mod_proxy_scgi
Module fournissant le support de la passerelle SCGI à mod_proxy
mod_proxy_uwsgi
Module de passerelle UWSGI pour mod_proxy
mod_proxy_wstunnel
Module pour mod_proxy supportant les websockets
mod_ratelimit
Limitation de la bande passante pour les clients
mod_reflector
Renvoie un corps de requête comme réponse via la pile de filtres en sortie.
mod_remoteip
Remplace l'adresse IP du client pour la requête par l'adresse IP présentée par un mandataire ou un répartiteur de charge via les en-têtes de la requête.
mod_reqtimeout
Définit le délai maximum et le taux minimum de transfert des données pour la réception des requêtes
mod_request
Filtres permettant de traiter et de mettre à disposition les corps de requêtes HTTP
mod_rewrite
Ce module fournit un moteur de réécriture à base de règles permettant de réécrire les URLs des requêtes à la volée
mod_sed
Filtre les contenus en entrée (requêtes) et en sortie (réponses) en utilisant la syntaxe de sed
mod_session
Support des sessions
mod_session_cookie
Support des sessions basé sur les cookies
mod_session_crypto
Support du chiffrement des sessions
mod_session_dbd
Support des session basé sur DBD/SQL
mod_setenvif
Permet de définir des variables d'environnement en fonction de certainescaractéristiques de la requête
mod_slotmem_plain
Fournisseur de mémoire partagée à base de slots.
mod_slotmem_shm
Fournisseur de mémoire partagée basée sur les slots.
mod_so
Chargement de modules ou de code exécutable au cours du démarrage ou du redémarrage du serveur
mod_socache_dbm
Fournisseur de cache d'objets partagés basé sur DBM.
mod_socache_dc
Fournisseur de cache d'objets partagés basé sur dc.
mod_socache_memcache
Fournisseur de cache d'objets partagés basé sur Memcache.
mod_socache_redis
Fournisseur de cache d'objets partagé basé sur Redis.
mod_socache_shmcb
Fournisseur de cache d'objets partagés basé sur shmcb.
mod_speling
Tente de corriger les erreurs de casse dans les URLs ou les fautes de frappe mineures.
mod_ssl
Chiffrement de haut niveau basé sur les protocoles Secure Sockets Layer (SSL) et Transport Layer Security (TLS)
mod_status
Fournit des informations sur les performances et l'activité du serveur
mod_substitute
Effectue des opérations de recherche/remplacement sur les corps de réponses
mod_suexec
Permet l'exécution des scripts CGI sous l'utilisateur et le groupe spécifiés
mod_systemd
Fournit un support amélioré pour l'intégration de systemd
mod_unique_id
Fournit une variable d'environnement contenant un identifiant unique pour chaque requête
mod_unixd
Sécurité de base (nécessaire) pour les plates-formes de la famille Unix.
mod_userdir
Répertoires propres à un utilisateur
mod_usertrack
Journalisation Clickstream des liens parcourus par un utilisateur sur un site
mod_version
Configuration dépendant de la version
mod_vhost_alias
Permet de configurer dynamiquement l'hébergement virtuel de masse
mod_watchdog
Fournit une infrastructure permettant à d'autres modules d'exécuter des tâches périodiques.
mod_xml2enc
Support avancé de l'internationalisation et des jeux de caractères pour les modules de filtrage basés sur libxml2

Langues Disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/event.html.fr.utf80000664000175100017510000007656014740503670021134 0ustar covenercovener event - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Apache MPM event

Langues Disponibles:  en  |  fr 

Description:Une variante du MPM worker conçue pour ne mobiliser des threads que pour les connexions en cours de traitement
Statut:MPM
Identificateur de Module:mpm_event_module
Fichier Source:event.c

Sommaire

Le module multi-processus (MPM) event est conçu pour permettre le traitement d'un nombre accru de requêtes simultanées en déléguant certaines tâches aux threads d'écoute, libérant par là-même les threads de travail et leur permettant de traiter les nouvelles requêtes.

Pour utiliser le MPM event, ajoutez --with-mpm=event aux arguments du script configure lorsque vous compilez le programme httpd.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Relations avec le MPM Worker

Le MPM event s'inspire du MPM worker qui implémente un serveur hybride multi-processus et multi-threads. Un processus de contrôle unique (le parent) est chargé de lancer des processus enfants. Chaque processus enfant crée un nombre de threads serveurs défini via la directive ThreadsPerChild, ainsi qu'un thread d'écoute qui surveille les requêtes entrantes et les distribue aux threads de travail pour traitement au fur et à mesure de leur arrivée.

Les directives de configuration à l'exécution sont identiques à celles que propose le MPM worker, avec l'unique addition de la directive AsyncRequestWorkerFactor.

top

Comment tout cela fonctionne

Ce module MPM tente de résoudre le "problème keep alive" de HTTP. Lorsqu'un client a effectué une première requête, il peut garder la connexion ouverte et envoyer les requêtes suivante en utilisant le même socket, ce qui diminue considérablement la charge qui aurait été induite par la création de nouvelles connexions TCP. Cependant, le fonctionnement du serveur HTTP Apache impose de réserver un couple processus enfant/thread pour attendre les données en provenance du client, ce qui présente certains inconvénients. Pour résoudre ce problème, le MPM Event utilise un thread d'écoute dédié pour chaque processus pour gérer les sockets d'écoute, tous les sockets qui sont dans un état de connexion persistante, les sockets où les filtres de gestionnaire et de protocole ont fait leur travail, et ceux pour lesquels la seule chose restant à faire est l'envoi des données au client.

Cette nouvelle architecture, en exploitant les sockets non blocants et les fonctionnalités des noyaux modernes mis en valeur par APR (comme epoll de Linux), n'a plus besoin du Mutex mpm-accept pour éviter le problème de "thundering herd".

La directive AsyncRequestWorkerFactor permet de définir le nombre total de connexions qu'un bloc processus/thread peut gérer.

Connexions asynchrones

Avec les MPM précédents, les connexions asynchrones nécessitaient un thread de travail dédié, mais ce n'est plus le cas avec le MPM Event. La page d'état de mod_status montre de nouvelles colonnes dans la section "Async connections" :

Writing
Lors de l'envoi de la réponse au client, il peut arriver que le tampon d'écriture TCP soit plein si la connexion est trop lente. Si cela se produit, une instruction write() vers le socket renvoie en général EWOULDBLOCK ou EAGAIN pour que l'on puisse y écrire à nouveau après un certain temps d'inactivité. Le thread de travail qui utilise le socket doit alors être en mesure de récupérer la tâche en attente et la restituer au thread d'écoute qui, à son tour, la réattribuera au premier thread de travail disponible, lorsqu'un évènement sera généré pour le socket (par exemple, "il est maintenant possible d'écrire dans le socket"). Veuillez vous reporter à la section à propos des limitations pour plus de détails.
Keep-alive
La gestion des connexions persistantes constitue la principale amélioration par rapport au MPM Worker. Lorsqu'un thread de travail a terminé l'envoi d'une réponse à un client, il peut restituer la gestion du socket au thread d'écoute, qui à son tour va attendre un évènement en provenance du système d'exploitation comme "le socket est lisible". Si une nouvelle requête arrive en provenance du client, le thread d'écoute l'attribuera au premier thread de travail disponible. Inversement, si le délai KeepAliveTimeout est atteint, le socket sera fermé par le thread d'écoute. Les threads de travail n'ont donc plus à s'occuper des sockets inactifs et ils peuvent être réutilisés pour traiter d'autres requêtes.
Closing
Parfois, le MPM doit effectuer une fermeture progressive, c'est à dire envoyer au client une erreur survenue précédemment alors que ce dernier est en train de transmettre des données à httpd. Envoyer la réponse et fermer immédiatement la connexion n'est pas une bonne solution car le client (qui est encore en train d'envoyer le reste de la requête) verrait sa connexion réinitialisée et ne pourrait pas lire la réponse de httpd. La fermeture progressive est limitée dans le temps, mais elle peut tout de même être assez longue, si bien qu'elle est confiée à un thread de travail (y compris les procédures d'arrêt et la fermeture effective du socket). A partir de la version 2.4.28, c'est aussi le cas lorsque des connexions finissent par dépasser leur délai d'attente (le thread d'écoute ne gère jamais les connexions, si ce n'est attendre et dispatcher les évènements qu'elles génèrent).

Ces améliorations sont disponible pour les connexions HTTP ou HTTPS.

Arrêt de processus en douceur et utilisation du scoreboard

Ce MPM présentait dans le passé des limitations de montée en puissance qui provoquaient l'erreur suivante : "scoreboard is full, not at MaxRequestWorkers". La directive MaxRequestWorkers permet de limiter le nombre de requêtes pouvant être servies simultanément à un moment donné ainsi que le nombre de processus autorisés (MaxRequestWorkers / ThreadsPerChild), alors que le scoreboard représente l'ensemble des processus en cours d'exécution et l'état de leurs threads de travail. Si le scoreboard est plein (autrement dit si aucun des threads n'est dans un état inactif) et si le nombre de requêtes actives servies est inférieur à MaxRequestWorkers, cela signifie que certains d'entre eux bloquent les nouvelles requêtes qui pourraient être servies et sont en l'occurrence mises en attente (dans la limite de la valeur imposée par la directive ListenBacklog). La plupart du temps, ces threads sont bloqués dans un état d'arrêt en douceur car ils attendent de terminer leur travail sur une connexion TCP pour s'arrêter et ainsi libérer une entrée dans le scoreboard (par exemple dans le cas du traitement des requêtes de longue durée, des clients lents ou des connexions en keep-alive). Voici deux scénarios courants :

A partir de la version 2.4.24, mpm-event est plus intelligent et peut traiter les arrêts graceful de manière plus efficace. Voici certaines de ces améliorations :

Le comportement décrit dans le dernier point est bien visible via mod_status dans la table des connexions avec les deux nouvelles colonnes "Slot" et "Stopping". La première indique le PID et la seconde si le processus est en cours d'arrêt ou non ; l'état supplémentaire "Yes (old gen)" indique un processus encore en exécution après un redémarrage graceful.

Limitations

La gestion améliorée des connexions peut ne pas fonctionner pour certains filtres de connexion qui se sont déclarés eux-mêmes incompatibles avec le MPM Event. Dans ce cas, le MPM Event réadoptera le comportement du MPM worker et réservera un thread de travail par connexion. Notez que tous les modules inclus dans la distribution du serveur httpd sont compatibles avec le MPM Event.

Une restriction similaire apparaît lorsqu'une requête utilise un filtre en sortie qui doit pouvoir lire et/ou modifier la totalité du corps de la réponse. Si la connexion avec le client se bloque pendant que le filtre traite les données, et si la quantité de données produites par le filtre est trop importante pour être stockée en mémoire, le thread utilisé pour la requête n'est pas libéré pendant que httpd attend que les données soient transmises au client.
Pour illustrer ce cas de figure, nous pouvons envisager les deux situations suivantes : servir une ressource statique (comme un fichier CSS) ou servir un contenu issu d'un programme FCGI/CGI ou d'un serveur mandaté. La première situation est prévisible ; en effet, le MPM Event a une parfaite visibilité sur la fin du contenu, et il peut utiliser les évènements : le thread de travail qui sert la réponse peut envoyer les premiers octets jusqu'à ce que EWOULDBLOCK ou EAGAIN soit renvoyé, et déléguer le reste de la réponse au thread d'écoute. Ce dernier en retour attend un évènement sur le socket, et délègue le reste de la réponse au premier thread de travail disponible. Dans la deuxième situation par contre (FCGI/CGI/contenu mandaté), le MPM n'a pas de visibilité sur la fin de la réponse, et le thread de travail doit terminer sa tâche avant de rendre le contrôle au thread d'écoute. La seule solution consisterait alors à stocker la réponse en mémoire, mais ce ne serait pas l'option la plus sure en matière de stabilité du serveur et d'empreinte mémoire.

Matériel d'arrière-plan

Le modèle event a été rendu possible par l'introduction de nouvelles APIs dans les systèmes d'exploitation supportés :

Avant que ces APIs soient mises à disposition, les APIs traditionnelles select et poll devaient être utilisées. Ces APIs deviennent lentes si on les utilise pour gérer de nombreuses connexions ou si le jeu de connexions possède un taux de renouvellement élevé. Les nouvelles APIs permettent de gérer beaucoup plus de connexions et leur performances sont meilleures lorsque le jeu de connexions à gérer change fréquemment. Ces APIs ont donc rendu possible l'écriture le MPM Event qui est mieux adapté à la situation HTTP typique où de nombreuses connexions sont inactives.

Le MPM Event suppose que l'implémentation de apr_pollset sous-jacente est raisonnablement sure avec l'utilisation des threads (threadsafe). Ceci évite au MPM de devoir effectuer trop verrouillages de haut niveau, ou d'avoir à réveiller le thread d'écoute pour lui envoyer un socket keep-alive. Ceci n'est possible qu'avec KQueue et EPoll.

top

Prérequis

Ce MPM dépend des opérations atomiques compare-and-swap d'APR pour la synchronisation des threads. Si vous compilez pour une plate-forme x86 et n'avez pas besoin du support 386, ou si vous compilez pour une plate-forme SPARC et n'avez pas besoin du support pre-UltraSPARC, ajoutez --enable-nonportable-atomics=yes aux arguments du script configure. Ceci permettra à APR d'implémenter les opérations atomiques en utilisant des instructions performantes indisponibles avec les processeurs plus anciens.

Ce MPM ne fonctionne pas de manière optimale sur les plates-formes plus anciennes qui ne gèrent pas correctement les threads, mais ce problème est sans objet du fait du prérequis concernant EPoll ou KQueue.

top

Directive AsyncRequestWorkerFactor

Description:Limite le nombre de connexions simultanées par thread
Syntaxe:AsyncRequestWorkerFactor facteur
Défaut:2
Contexte:configuration globale
Statut:MPM
Module:event
Compatibilité:Disponible depuis la version 2.3.13

Le MPM event gère certaines connexions de manière asynchrone ; dans ce cas, les threads traitant la requête sont alloués selon les besoins et pour de courtes périodes. Dans les autres cas, un thread est réservé par connexion. Ceci peut conduire à des situations où tous les threads sont saturés et où aucun thread n'est capable d'effectuer de nouvelles tâches pour les connexions asynchrones établies.

Pour minimiser les effets de ce problème, le MPM event utilise deux méthodes :

Cette directive permet de personnaliser finement la limite du nombre de connexions par thread. Un processus n'acceptera de nouvelles connexions que si le nombre actuel de connexions (sans compter les connexions à l'état "closing") est inférieur à :

ThreadsPerChild + (AsyncRequestWorkerFactor * nombre de threads inactifs)

Il est possible d'effectuer une estimation du nombre maximum de connexions simultanées pour tous les processus et pour un nombre donné moyen de threads de travail inactifs comme suit :

(ThreadsPerChild + (AsyncRequestWorkerFactor * number of idle workers)) * ServerLimit

Exemple

ThreadsPerChild = 10
ServerLimit = 4
AsyncRequestWorkerFactor = 2
MaxRequestWorkers = 40

idle_workers = 4 (moyenne pour tous les processus pour faire simple)

max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit 
                = (10 + (2 * 4)) * 4 = 72

Lorsque tous les threads de travail sont inactifs, le nombre maximum absolu de connexions simultanées peut être calculé de manière plus simple :

(AsyncRequestWorkerFactor + 1) * MaxRequestWorkers

Exemple

ThreadsPerChild = 10 
ServerLimit = 4
MaxRequestWorkers = 40
AsyncRequestWorkerFactor = 2

Si tous les threads de tous les processus sont inactifs, alors :

idle_workers = 10

Nous pouvons calculer le nombre maximum absolu de connexions simultanées de deux manières :

max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit 
                = (10 + (2 * 10)) * 4 = 120
    
max_connections = (AsyncRequestWorkerFactor + 1) * MaxRequestWorkers 
                = (2 + 1) * 40 = 120

Le réglage de la directive AsyncRequestWorkerFactor nécessite de connaître le trafic géré par httpd pour chaque style d'utilisation spécifique ; si vous modifiez la valeur par défaut, vous devrez par conséquent effectuer des tests approfondis en vous appuyant étroitement sur les données fournies par mod_status.

La directive MaxRequestWorkers se nommait MaxClients avant la version 2.3.13. La valeur ci-dessus montre que cet ancien nom ne correspondait pas à sa signification exacte pour le MPM event.

La directive AsyncRequestWorkerFactor accepte des valeurs d'argument de type non entier, comme "1.5".

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_actions.html.fr.utf80000664000175100017510000003251414740503670022301 0ustar covenercovener mod_actions - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_actions

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

Description:Exécution des scripts CGI en fonction du type de média ou de la méthode de requête.
Statut:Base
Identificateur de Module:actions_module
Fichier Source:mod_actions.c

Sommaire

Ce module possède deux directives. La directive Action vous permet de lancer l'exécution de scripts CGI chaque fois qu'un fichier possédant un certain type de contenu MIME fait l'objet d'une requête. La directive Script vous permet de lancer l'exécution de scripts CGI chaque fois que la requête utilise une méthode particulière. Ceci facilite grandement l'exécution de scripts qui traitent des fichiers.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive Action

Description:Active un script CGI pour un gestionnaire ou un type de contenu particulier
Syntaxe:Action type d'action script cgi [virtual]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_actions
Compatibilité:Le modificateur virtual et le passage de gestionnaire ont été introduits dans Apache 2.1

Cette directive ajoute une action qui va activer script cgi lorsque type d'action est déclenché par la requête. script cgi est un chemin URL vers une ressource qui a été désignée comme script CGI à l'aide des directives ScriptAlias ou AddHandler. type d'action peut être soit un gestionnaire, soit un type de contenu MIME. L'URL et le chemin du document correspondant sont envoyés en utilisant les variables d'environnement CGI standards PATH_INFO et PATH_TRANSLATED. Le gestionnaire utilisé pour cette requête particulière est transmis à l'aide de la variable REDIRECT_HANDLER.

Exemple : type MIME

# Requests for files of a particular MIME content type:
Action image/gif /cgi-bin/images.cgi

Dans cet exemple, les requêtes pour des fichiers possédant le type de contenu MIME image/gif seront traitées par le script CGI /cgi-bin/images.cgi.

Example: File extension

# Files of a particular file extension
AddHandler my-file-type .xyz
Action my-file-type "/cgi-bin/program.cgi"

Dans cet exemple, les requêtes pour des fichiers possédant l'extension .xyz seront traitées par le script CGI /cgi-bin/programme.cgi.

Le modificateur optionnel virtual permet de désactiver la vérification de l'existence du fichier demandé. Ceci peut s'avérer utile, par exemple, si vous voulez utiliser la directive Action pour des localisations virtuelles.

<Location "/news">
    SetHandler news-handler
    Action news-handler "/cgi-bin/news.cgi" virtual
</Location>

Voir aussi

top

Directive Script

Description:Active un script CGI dans le cas d'une méthode de requête particulière.
Syntaxe:Script méthode script cgi
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_actions

Cette directive ajoute une action qui va activer script cgi lorsqu'un fichier est demandé en utilisant la méthode méthode. script cgi est le chemin URL d'une ressource qui a été désignée comme script CGI en utilisant les directives ScriptAlias ou AddHandler. L'URL et le chemin du document demandé sont envoyés en utilisant les variables d'environnement CGI standards PATH_INFO et PATH_TRANSLATED.

Tous les noms de méthode peuvent être utilisés. Les noms de méthode sont sensibles à la casse, si bien que Script PUT et Script put ont des effets totalement différents.

Notez que la commande Script ne définit que des actions par défaut. Si un script CGI est appelé, ou toute autre ressource capable de gérer la méthode de la requête en interne, il agira en conséquence. Notez aussi que Script avec une méthode GET ne sera appelé que si la requête possède des arguments (par exemple foo.html?hi). Dans le cas contraire, la requête sera traitée normalement.

# All GET requests go here
Script GET "/cgi-bin/search"

# A CGI PUT handler
Script PUT "/~bob/put.cgi"

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

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_balancer.html.ja.utf80000664000175100017510000004550614743132254023640 0ustar covenercovener mod_proxy_balancer - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_proxy_balancer

翻訳済み言語:  en  |  fr  |  ja 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:負荷分散のための mod_proxy 拡張
ステータス:Extension
モジュール識別子:proxy_balancer_module
ソースファイル:mod_proxy_balancer.c
互換性:2.1 以降

概要

本モジュールには mod_proxy必要ですHTTP, FTPAJP13 プロトコルのロードバランス機能を持っています。

ですから、 ロードバランスを有効にする場合 mod_proxymod_proxy_balancer がサーバに組み込まれて いなければいけません。

警告

安全なサーバにするまでプロクシ機能は有効にしないでください。 オープンプロキシサーバはあなた自身のネットワークにとっても、 インターネット全体にとっても危険です。

Support Apache!

トピック

ディレクティブ

このモジュールにディレクティブはありません。

Bugfix checklist

参照

top

ロードバランサのスケジューラのアルゴリズム

現時点では 2 種類のロードバランサスケジューラアルゴリズムから選べます。 リクエスト回数によるもの (訳注: Request Counting) と、トラフィック量によるもの (訳注: Weighted Traffic Counting) があります。バランサの設定 lbmethod 値で、どちらを使うか指定します。 詳細は Proxy ディレクティブを 参照してください。

top

Request Counting アルゴリズム

lbmethod=byrequests で有効になります。 このスケジューラの背景にある考え方は、様々なワーカーがそれぞれ、 設定されている分担リクエスト数をきちんと受け取れるように、 リクエストを扱うという考え方です。次のように動作します:

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

バランサを次のように設定した場合:

worker a b c d
lbfactor 25 25 25 25
lbstatus 0 0 0 0

そして b が無効になった場合、次のようなスケジュールが 行われます。

worker a b c d
lbstatus -50 0 25 25
lbstatus -25 0 -25 50
lbstatus 0 0 0 0
(repeat)

つまりこのようにスケジュールされます: a c d a c d a c d ... 次の点に注意してください:

worker a b c d
lbfactor 25 25 25 25

この挙動は、次の設定と全く同じになります:

worker a b c d
lbfactor 1 1 1 1

This is because all values of lbfactor are normalized with respect to the others. For:

lbfactor は全て正規化されたもので、 他との相対値だからです。次の設定では:

worker a b c
lbfactor 1 4 1

ワーカー b は、平均して、ac の 4 倍の数のリクエストを受け持つことになります。

次のような非対称な設定では、こうなると予想されるでしょう:

worker a b
lbfactor 70 30
 
lbstatus -30 30
lbstatus 40 -40
lbstatus 10 -10
lbstatus -20 20
lbstatus -50 50
lbstatus 20 -20
lbstatus -10 10
lbstatus -40 40
lbstatus 30 -30
lbstatus 0 0
(repeat)

スケジュールは 10 スケジュール後に繰り返され、a 7 回と b 3 回でまばらに選ばれます。

top

Weighted Traffic Counting アルゴリズム

lbmethod=bytraffic で有効になります。 このスケジューラの背景にある考え方は、Request Counting と非常に似ていますが、次の違いがあります:

lbfactorどれだけのバイト数のトラフィック量を、 このワーカーに処理してもらいたいか を表します。 この値も同様に正規化された値で、ワーカー全体のうちでの "分担" 量を表現しています。リクエスト数を単純に数える代わりに、 どれだけの転送量を処理したかを数えます。

次のようにバランサを設定した場合:

worker a b c
lbfactor 1 2 1

b には ac の 2 倍 処理してほしいということになります。 b は 2 倍の I/O を処理するという意味になり、 2 倍のリクエスト数を処理するということにはなりません。 ですからリクエストとレスポンスのサイズが、 重み付けと振り分けのアルゴリズムに効いています。

top

バランサマネージャのサポートを有効にする

このモジュールは mod_status のサービスを 必要とします。 バランサマネージャを使うと、バランサのメンバーの動的な更新が できます。バランサマネージャを使って、バランス係数 (lbfactor) を変更したり、メンバーを変更したり、特定のメンバーを オフラインモードにしたりできます。

ですから、ロードバランサ管理機能を使いたければ、 mod_statusmod_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 のページ経由で、ウェブブラウザからロードバランサマネージャに アクセスできるようになります。

翻訳済み言語:  en  |  fr  |  ja 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_setenvif.html.ja.utf80000664000175100017510000005323414743132254022450 0ustar covenercovener mod_setenvif - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_setenvif

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:リクエストの特徴に基づいた環境変数の設定を可能にする
ステータス:Base
モジュール識別子:setenvif_module
ソースファイル:mod_setenvif.c

概要

mod_setenvif モジュールは、リクエストのある側面が指定された正規表現 に合うかどうかによって環境変数を設定する機能を提供します。 これらの環境変数を使用して、サーバの他の部分がどのような動作をするかを 決定することができます。

このモジュールが提供するディレクティブは、 設定ファイルに現れる順番に適用されます。 それを使って、次の例のようにより複雑な設定をすることができます。 これは、ブラウザが mozilla ではあるけれど、MSIE ではないときに netscape を設定します。

BrowserMatch ^Mozilla netscape
BrowserMatch MSIE !netscape

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

BrowserMatch ディレクティブ

説明:HTTP User-Agent に基づいて環境変数を設定する
構文:BrowserMatch regex [!]env-variable[=value] [[!]env-variable[=value]] ...
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Base
モジュール:mod_setenvif

BrowserMatchSetEnvIf ディレクティブの 特例で、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

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 は以下の 4 つのどれかです:

  1. HTTP リクエストヘッダフィールド (詳しい情報は RFC 2616 を 参照してください)。例えば、Host, User-Agent, Referer, Accept-Language です。リクエストヘッダの集合を現すために 正規表現を使うこともできます。
  2. 以下のリクエストの一部分のどれか:
    • 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 のスキームとホストの後の部分。 追加の情報として、クエリーストリングにマッチさせる場合については RewriteCond ディレクティブを参照してください。
  3. リクエストと関連付けられる環境変数のリスト。これにより SetEnvIf ディレクティブが以前のマッチの結果を 使うことができるようになります。この方法のテストでは前の部分にある SetEnvIf[NoCase] の結果のみを使用可能です。「前」とは、 より広い範囲に対して定義されている (サーバ全体のように) か、現在のディレクティブの 範囲でより前の部分で定義されているか、ということです。 環境変数である可能性は、リクエストの特性に対するマッチが存在せず、 attribute に正規表現が使われなかったときにのみ考慮されます。
  4. SSL クライアント証明書拡張への参照で、oid オブジェクト ID で指定されるもの。 SSL リクエストでない場合や oid が設定されていなかった場合は、 変数はセットされません。oid が複数見つかった場合は それらの文字列はカンマ ',' 区切りで連結されます。 oid は文字列型拡張への参照でなければなりません。

二つ目の引数 (regex) は 正規表現です。 これは POSIX.2 の egrep 形式の正規表現と似ています。regexattribute にマッチする場合は、残りの引数が評価されます。

残りの引数は設定する変数の名前で、設定される値を指定することもできます。 これは、

  1. varname
  2. !varname
  3. varname=value

のどれかの形式になります。

最初の形式では、値は "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\.example\.com intra_site_referral
:
SetEnvIf object_is_image xbm XBIT_PROCESSING=1
:
SetEnvIf OID("2.16.840.1.113730.1.13") "(.*)" NetscapeComment=$1
:
SetEnvIf ^TS* ^[a-z].* HAVE_TS

初めの三つはリクエストが画像であるときに環境変数 object_is_image を設定します。四つ目は 参照元のページがウェブサイト www.mydomain.example.com にあるときに intra_site_referral を設定します。

6番目の例では環境変数 NetscapeComment を定義して、 その値が SSL クライアント証明書の対応するフィールドの文字列であるようにします。 ただし SSL クライアント証明書の対応するフィールドに文字列が存在する ときにのみ、環境変数は設定されます。

最後の例は、リクエストに "TS" で始まり、値が集合 [a-z] のどれかで 始まるヘッダがあるときに HAVE_TS を設定します。

参照

top

SetEnvIfExpr ディレクティブ

説明:Sets environment variables based on an ap_expr expression
構文:
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Base
モジュール:mod_setenvif

Documentation not yet translated. Please see English version of document.

top

SetEnvIfNoCase ディレクティブ

説明:リクエストの属性に基づいて大文字小文字を区別せずに環境変数を設定する
構文:SetEnvIfNoCase attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
ステータス:Base
モジュール:mod_setenvif

SetEnvIfNoCase は意味的には SetEnvIf ディレクティブと 同じです。違いは、正規表現のマッチングが大文字小文字を区別しないで 行なわれることです。例えば:

SetEnvIfNoCase Host Apache\.Org site=apache

これは HTTP リクエストヘッダにフィールド Host: が あり、その値が Apache.Orgapache.org、 その他の大文字小文字の組み合わせであったときに site 環境変数を "apache" に設定します。

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_so.html.ja.utf80000664000175100017510000004045514743132254021247 0ustar covenercovener mod_so - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_so

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:起動時や再起動時に実行コードとモジュールをサーバにロードする
ステータス:Extension
モジュール識別子:so_module
ソースファイル:mod_so.c
互換性:このモジュールは Window では (常に含まれている) Base モジュールです

概要

いくつかのオペレーティングシステムでは、サーバの再コンパイルをする代わりに、 このモジュールを使用して 動的共有オブジェクト (DSO) 機構により、実行時に Apache HTTP Server にモジュールを読み込ませることが できます。

Unix 上では、読み込まれるコードは通常は共有オブジェクトファイル (普通 .so という拡張子が付いています) からです。 Windows 上ではこのモジュールの拡張子は .so.dll です。

警告

Apache HTTP Server のあるメジャーバージョン向けにビルドされたモジュールは一般に 他のメジャーバージョンでは動きません。(例えば 1.3 と 2.0、 2.0 と 2.2) またメジャーバージョン間ではAPIの変更がしばしば発生し、そのため新しい メジャーバージョン向けにモジュールの修正が必要になることがあります。

Support Apache!

トピック

ディレクティブ

Bugfix checklist

参照

top

Windows 用のロード可能なモジュールを作成する

Windows において動的にロードされるモジュールの拡張子は普通 .dll ですが、Apache httpd のモジュールは mod_whatever.so といった名前を持ちます。これは、他のプラットフォームでの通常の形式に あわせたものです。しかしながら、サードパーティ製モジュール、例えばPHPなど、 は今でも .dll の拡張子を使っています。

まだ mod_soApacheModuleFoo.dll という名前の モジュールもロードされますが、新しい名前の付け方を使う方が好まれます。 モジュールを 2.0 用に移植しているのであれば、2.0 の習慣に合うように名前を 修正してください。

Apache httpd のモジュール API は UNIX と Windows 間では変更されていません。 多くのモジュールは全く変更なし、もしくは簡単な変更により Windows で実行できるようになります。ただし、それ以外の Windows には無い Unix アーキテクチャーの機能に依存したモジュールは動作しません。

モジュールが実際に動作するときは、 二つの方法のどちらかでサーバに追加することができます。まず、Unix と同様にサーバにコンパイルして組み込むことができます。Windows 用の Apache httpd は Unix 用の Apache にある Configure プログラムがありませんので、モジュールのソースファイルを ApacheCore プロジェクトファイルに追加し、シンボルを os\win32\modules.c ファイルに追加する必要があります。

二つ目はモジュールを DLL としてコンパイルする方法です。 DLL は共有ライブラリで、実行時に LoadModule ディレクティブによりサーバに読み込むことができます。これらのモジュール DLL はそのまま配布することが可能で、サーバを再コンパイルすることなく、Windows 用の Apache httpd のすべてのインストールで実行することができます。

モジュール DLL を作成するためには、 モジュールの作成に小さな変更を行なう必要があります。 つまり、モジュールのレコード (これは後で作成されます。 以下を参照してください) が DLL からエクスポートされなければなりません。 これを行なうには、AP_MODULE_DECLARE_DATA (Apache httpd のヘッダファイルで定義されています) をモジュールのモジュールレコード 定義の部分に追加してください。たとえば、モジュールに

module foo_module;

があるとすると、それを次のもので置き換えてください。

module AP_MODULE_DECLARE_DATA foo_module;

Unix 上でもこのモジュールを 変更無しで使い続けられるように、このマクロは Windows 上でのみ効力を持ちます。.DEF ファイルの方を良く知っているという場合は、 代わりにそれを使ってモジュールレコードを エクスポートすることもできます。

さあ、あなたのモジュールの DLL を作成しましょう。これを、 libhttpd.lib 共有ライブラリがコンパイルされたときに作成された ibhttpd.lib エクスポートライブラリとリンクしてください。この時に、 Apache httpd のヘッダファイルが正しい位置にあるように、 コンパイラの設定を変える必要があるかもしれません。 このライブラリはサーバルートの 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 サブディレクトリから指定された名前の モジュールをロードします。

翻訳済み言語:  en  |  fr  |  ja  |  ko  |  tr 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_speling.html.ja.utf80000664000175100017510000003503414743132254022264 0ustar covenercovener mod_speling - Apache HTTP サーバ バージョン 2.4
<-
Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > モジュール

Apache モジュール mod_speling

翻訳済み言語:  en  |  fr  |  ja  |  ko 

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。
説明:ユーザが入力したであろう間違った URL を、 大文字小文字の区別を無視することと一つ以下の綴り間違いを許容することで 修正を試みる
ステータス:Extension
モジュール識別子:speling_module
ソースファイル:mod_speling.c

概要

リクエストの綴りが間違っていたり、 大文字小文字が違っていたりするために、Apache のコアサーバが ドキュメントへのリクエストへの応答を正しく提供できないことがあります。 このモジュールは、他のすべてのモジュールがあきらめた後であったとしても、 リクエストに合うドキュメントを見つけようとすることによりこの問題の 解決を試みます。このモジュールはリクエストされたディレクトリにある それぞれのドキュメントの名前と、リクエストされたドキュメントの名前とを 大文字小文字の区別を無視し一文字までの 綴りの間違い (文字の挿入/省略/隣合う文字の置換、間違った文字) を許可して比較することにより、目的を達成しようとします。 この方法でリクエストに合うドキュメントの一覧が作成されます。

ディレクトリをスキャンした後に、

Support Apache!

ディレクティブ

Bugfix checklist

参照

top

CheckBasenameMatch ディレクティブ

説明:Also match files with differing file name extensions.
構文:CheckBasenameMatch on|off
デフォルト:CheckBasenameMatch On
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Options
ステータス:Extension
モジュール:mod_speling
互換性:Available in httpd 2.4.50 and later

このディレクティブの解説文書は まだ翻訳されていません。英語版をご覧ください。

top

CheckCaseOnly ディレクティブ

説明:大文字小文字の修正だけ行うようにする
構文:CheckCaseOnly on|off
デフォルト:CheckCaseOnly Off
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:Options
ステータス:Extension
モジュール:mod_speling

このディレクティブがセットされると、 綴り訂正機能は大文字小文字の修正のみ働き、他の修正機能は働きません。

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 ディレクティブは「サーバ」と「バーチャルホスト」コンテキストでのみ 使用可能でした

このディレクティブは綴り用のモジュールを使用するかどうかを 決めます。使用時には、以下のことを覚えておいてください

DAV が有効なディレクトリでは mod_speling は有効にしないでください。 新しく作成したリソース名を既に存在するファイル名に「修正」しようとする、 例えば、新規ドキュメント doc43.html が既に存在する doc34.html にリダイレクトされて、 期待とは違う挙動になるからです。

翻訳済み言語:  en  |  fr  |  ja  |  ko 

top

コメント

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_alias.html.fr.utf80000664000175100017510000013020014740503670021721 0ustar covenercovener mod_alias - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_alias

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Permet d'atteindre différentes parties du système de fichiers depuis l'arborescence des documents du site web, ainsi que la redirection d'URL
Statut:Base
Identificateur de Module:alias_module
Fichier Source:mod_alias.c

Sommaire

Les directives fournies par ce module permettent de manipuler et de contrôler les URLs à l'arrivée des requêtes sur le serveur. Les directives Alias et ScriptAlias permettent de faire correspondre des URLs avec des chemins du système de fichiers. Ceci permet de servir des contenus qui ne sont pas situés dans l'arborescence de DocumentRoot comme s'ils y étaient réellement. La directive ScriptAlias a pour effet supplémentaire de marquer le répertoire cible comme conteneur de scripts CGI.

Les directives Redirect indiquent aux clients qu'ils doivent effectuer une nouvelle requête avec une URL différente. Elles sont souvent utilisées lorsqu'une ressource a été déplacée.

Lorsque les directives Alias, ScriptAlias ou Redirect sont définies au sein d'une section <Location> ou <LocationMatch>, vous pouvez utiliser la syntaxe des expressions pour manipuler l'URL ou le chemin de destination.

mod_alias est conçu pour traiter des tâches simples de manipulation d'URL. Pour des tâches plus complexes comme la manipulation des chaînes d'arguments des requêtes, utilisez plutôt les outils fournis par le module mod_rewrite

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Chronologie du traitement

Les alias et redirections apparaissant dans différents contextes sont traités comme les autres directives en respectant les règles de fusion standards. Par contre, ils sont traités selon une chronologie particulière lorsqu'ils apparaissent dans le même contexte (par exemple, dans la même section <VirtualHost>).

Premièrement, toutes les redirections sont traitées avant les alias, et ainsi, une requête qui correspond à une directive Redirect ou RedirectMatch ne se verra jamais appliquer d'alias. Deuxièmement, les alias et redirections sont traités selon l'ordre dans lequel ils apparaissent dans le fichier de configuration, seule la première correspondance étant prise en compte.

Ainsi, lorsqu'une ou plusieurs de ces directives s'appliquent au même sous-répertoire, vous devez classer les chemins du plus précis au moins précis afin que toutes les directives puissent éventuellement s'appliquer, comme dans l'exemple suivant :

Alias "/foo/bar" "/baz"
Alias "/foo" "/gaq"

Si l'ordre des directives était inversé, la directive Alias ayant pour argument /foo serait toujours appliquée avant la directive Alias ayant pour argument /foo/bar, et cette dernière serait toujours ignorée.

La définition de directives Alias, ScriptAlias ou Redirect au sein de sections <Location> ou <LocationMatch> l'emporte sur d'autres définitions éventuelles de ces mêmes directives au niveau de la configuration générale du serveur.

top

Directive Alias

Description:Met en correspondance des URLs avec des chemins du système de fichiers
Syntaxe:Alias [chemin URL] chemin fichier|chemin répertoire
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_alias

La directive Alias permet de stocker des documents (destinés à être servis) dans des zones du système de fichiers situées en dehors de l'arborescence du site web DocumentRoot. Les URLs dont le chemin (décodé avec caractères %) commence par chemin URL seront mises en correspondance avec des fichiers locaux dont le chemin commence par chemin répertoire. Le chemin URL est sensible à la casse, même sur les systèmes de fichiers insensibles à la casse.

Alias "/image" "/ftp/pub/image"

Une requête pour http://example.com/image/foo.gif fera renvoyer par le serveur le fichier /ftp/pub/image/foo.gif. Seuls les éléments de chemin complets sont testés ; ainsi l'alias précédent ne conviendra pas pour une requête du style http://example.com/imagefoo.gif. Pour des mises en correspondance plus complexes faisant intervenir les expressions rationnelles, veuillez vous reporter à la directive AliasMatch.

Notez que si vous ajoutez un slash de fin au chemin URL, vous devrez aussi ajouter un slash de fin au chemin de la requête. Autrement dit, si vous définissez

Alias "/icons/" "/usr/local/apache/icons/"

l'alias précédent ne s'appliquera pas à l'URL /icons à cause de l'absence du slash final. Ainsi, si le slash final est absent du chemin de l'URL, il doit aussi l'être du chemin du fichier.

Notez qu'il pourra s'avérer nécessaire de définir des sections <Directory> supplémentaires qui couvriront la destination des alias. Le traitement des alias intervenant avant le traitement des sections <Directory>, seules les cibles des alias sont affectées (Notez cependant que les sections <Location> sont traitées avant les alias, et s'appliqueront donc).

En particulier, si vous créez un alias ayant pour cible un répertoire situé en dehors de l'arborescence de votre site web DocumentRoot, vous devrez probablement permettre explicitement l'accès à ce répertoire.

Alias "/image" "/ftp/pub/image"
<Directory "/ftp/pub/image">
    Require all granted
</Directory>

Le nombre de slashes dans le paramètre chemin URL doit correspondre au nombre de slashes dans le chemin URL de la requête.

Si la directive Alias est définie au sein d'une section <Location> ou <LocationMatch>, chemin URL est omis et chemin fichier est interprété en utilisant la syntaxe des expressions.
Cette syntaxe est disponible à partir de la version 2.4.19 du serveur HTTP Apache.

<Location "/image">
    Alias "/ftp/pub/image"
</Location>
<LocationMatch "/error/(?<NUMBER>[0-9]+)">
    Alias "/usr/local/apache/errors/%{env:MATCH_NUMBER}.html"
</LocationMatch>

Notez que lorsque la directive AliasPreservePath est à "on", la destination contient le chemin entier, alors que lorsque la directive AliasPreservePath est à "off", tous les URLs sont associés à l'URL cible unique.

# /files/foo et /files/bar associés à /ftp/pub/files/foo et /ftp/pub/files/bar
<Location "/files">
    AliasPreservePath on
    Alias "/ftp/pub/files"
</Location>
# /errors/foo et /errors/bar associés à /var/www/errors.html
<Location "/errors">
    AliasPreservePath off
    Alias "/var/www/errors.html"
</Location>
top

Directive AliasMatch

Description:Met en correspondance des URLs avec le système de fichiers en faisant intervenir les expressions rationnelles
Syntaxe:AliasMatch regex chemin fichier|chemin répertoire
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_alias

Cette directive est identique à la directive Alias, mais fait appel aux expressions rationnelles, à la place d'une simple mise en correspondance de préfixe. L'expression rationnelle fournie est mise en correspondance avec le chemin URL, et si elle correspond, le serveur va substituer toute partie de chemin correspondant à l'expression entre parenthèses dans la chaîne fournie et l'utiliser comme nom de fichier. Par exemple, pour activer le répertoire /icons, on peut utiliser :

AliasMatch "^/icons(.*)" "/usr/local/apache/icons$1$2"

Toute la puissance des expressions rationnelles peut être mise à contribution. Par exemple, il est possible de construire un alias avec un modèle de chemin URL insensible à la casse :

AliasMatch "(?i)^/image(.*)" "/ftp/pub/image$1"

Il existe une différence subtile entre Alias et AliasMatch : Alias copie automatiquement toute portion supplémentaire de l'URI située après la partie du modèle qui correspond, à la fin du chemin du fichier de la partie droite, alors que AliasMatch ne le fait pas. Cela signifie qu'il sera préférable dans la plupart des cas de comparer l'expression rationnelle du modèle à la totalité de l'URI de la requête, et d'utiliser les substitutions dans la partie droite.

En d'autres termes, le remplacement d'Alias par AliasMatch ne produira pas le même résultat. Au minimum, vous devez ajouter ^ au début de l'expression rationnelle, (.*)$ à sa fin et $1 à la fin de la chaîne de remplacement.

Par exemple, supposons que nous voulions reformuler cet alias avec AliasMatch :

Alias "/image/" "/ftp/pub/image/"

Le simple remplacement d'Alias par AliasMatch ne produira pas le même résultat. Ainsi, ce qui suit va rediriger toutes les requêtes qui contiennent /image/ vers /ftp/pub/image/ :

AliasMatch "/image/" "/ftp/pub/image/"

Voici la directive AliasMatch qui produira le même résultat que la directive Alias ci-dessus :

AliasMatch "^/image/(.*)$" "/ftp/pub/image/$1"

Bien entendu, il n'y a aucune raison d'utiliser AliasMatch dans le cas où Alias suffit. AliasMatch vous permet d'effectuer des choses beaucoup plus sophistiquées. Par exemple, vous pouvez servir différentes sortes de fichiers à partir de répertoires différents :

      AliasMatch "^/image/(.*)\.jpg$" "/fichiers/jpg.images/$1.jpg"
      AliasMatch "^/image/(.*)\.gif$" "/fichiers/gif.images/$1.gif"

Les éventuels slashes de tête multiples seront supprimés par le serveur avant que les directives de ce module n'effectuent des comparaisons avec le chemin URL de la requête.

top

Directive AliasPreservePath

Description:Associer le chemin entier à l'alias dans une section location.
Syntaxe:AliasPreservePath OFF|ON
Défaut:AliasPreservePath OFF
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_alias
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache.

Lorsqu'on utilise la version à deux paramètres de la directive Alias, le chemin complet après l'alias est préservé. Lorsqu'on utilise la version à un paramètre de la directive Alias dans une section Location, le chemin entier est supprimé, et tous les URLs sont associés à l'expression cible.

Pour que la version à un paramètre de la directive Alias préserve les chemins de la même façon que la version à deux paramètres, activez cette directive.

top

Directive Redirect

Description:Envoie une redirection externe demandant au client d'effectuer une autre requête avec une URL différente
Syntaxe:Redirect [état] [URL-path] URL
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_alias

La directive Redirect permet de faire correspondre une ancienne URL à une nouvelle en demandant au client d'aller chercher la ressource à une autre localisation.

L'ancien URL-path est un chemin sensible à la casse (décodé à l'aide de caractères %) commençant par un slash. Les chemins relatifs ne sont pas autorisés.

La nouvelle URL peut être une URL absolue commençant par un protocole et un nom d'hôte, mais on peut aussi utiliser un chemin URL commençant par un slash, auquel cas le protocole et le nom d'hôte du serveur local seront ajoutés.

Ensuite, toute requête commençant par URL-path va renvoyer une redirection au client vers l'URL cible. Tout élément de chemin supplémentaire situé en aval du URL-path sera ajouté à l'URL cible.

# Redirige vers une URL sur un serveur différent
Redirect "/service" "http://foo2.example.com/service"

# Redirige vers une URL sur le même serveur
Redirect "/one" "/two"

Si le client effectue une requête pour l'URL http://example.com/service/foo.txt, il lui sera demandé d'en effectuer une autre pour l'URL http://foo2.example.com/service/foo.txt. Ceci concerne les requêtes avec paramètres GET, comme http://example.com/service/foo.pl?q=23&a=42, qui seront redirigées vers http://foo2.example.com/service/foo.pl?q=23&a=42. Notez que les POSTs seront ignorés.
Seuls les éléments de chemin complets sont testés, si bien que l'exemple précédent ne s'appliquera pas à l'URL http://example.com/servicefoo.txt. Pour des mises en correspondance plus complexes utilisant la syntaxe des expressions, ne spécifiez pas d'argument URL-path comme décrit ci-dessous. En outre, pour une mise en correspondance en utilisant les expressions rationnelles, veuillez vous reporter à la directive RedirectMatch.

Note

Les directives Redirect ont priorité sur les directives Alias et ScriptAlias, quel que soit leur ordre d'apparition dans le fichier de configuration. Les directives Redirect définies au sein d'une section Location l'emportent sur les directives Redirect et Alias comportant un argument URL-path.

Si aucun argument état n'est spécifié, la redirection sera temporaire (code HTTP 302). Le client est alors informé que la ressource a été temporairement déplacée. On peut utiliser l'argument état pour renvoyer d'autres codes HTTP :

permanent
Renvoie un code de redirection permanente (301), indiquant que la ressource a été définitivement déplacée.
temp
Renvoie un code de redirection temporaire (302). C'est le comportement par défaut.
seeother
Renvoie un code "See Other" (303) indiquant que la ressource a été remplacée par une autre.
gone
Renvoie un code "Gone" (410) indiquant que la ressource a été définitivement supprimée. Lorsque ce code est utilisé, on ne doit pas utiliser l'argument URL.

On peut renvoyer d'autres codes en spécifiant le code numérique comme valeur de l'argument of état. Si le code est compris entre 300 et 399, l'argument URL doit être présent. Si le code n'est pas compris entre 300 et 399, l'argument URL ne doit pas apparaître. Le code doit être un code HTTP valide, connu du serveur HTTP Apache (voir la fonction send_error_response dans http_protocol.c).

Redirect permanent "/one" "http://example.com/two"
Redirect 303 "/three" "http://example.com/other"

Si une directive Redirect est définie au sein d'une section <Location> ou <LocationMatch> et si l'argument URL-path est omis, l'argument URL sera interprété en utilisant la syntaxe des expressions.
Cette syntaxe est disponible à partir de la version 2.4.19 du serveur HTTP Apache.

<Location "/one">
    Redirect permanent "http://example.com/two"
</Location>
<Location "/three">
    Redirect 303 "http://example.com/other"
</Location>
<LocationMatch "/error/(?<NUMBER>[0-9]+)">
    Redirect permanent "http://example.com/errors/%{env:MATCH_NUMBER}.html"
</LocationMatch>
top

Directive RedirectMatch

Description:Envoie une redirection externe faisant appel aux expressions rationnelles pour la mise en correspondance de l'URL courante
Syntaxe:RedirectMatch [état] regex URL
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_alias

Cette directive est identique à la directive Redirect, mais fait appel aux expressions rationnelles, à la place d'une simple mise en correspondance de préfixe. L'expression rationnelle fournie est mise en correspondance avec le chemin URL, et si elle correspond, le serveur va substituer toute partie de chemin correspondante entre parenthèses dans la chaîne spécifiée et l'utiliser comme nom de fichier. Par exemple, pour rediriger tous les fichiers GIF vers les fichiers JPEG de même nom sur un autre serveur, on peut utiliser :

RedirectMatch "(.*)\.gif$" "http://autre.example.com$1.jpg"

Les remarques à propos de la différence entre Alias et AliasMatch s'appliquent aussi à la différence entre les directives Redirect et RedirectMatch. Voir la directive AliasMatch pour plus de détails.

top

Directive RedirectPermanent

Description:Envoie une redirection externe permanente demandant au client d'effectuer une nouvelle requête avec une URL différente
Syntaxe:RedirectPermanent chemin URL URL
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_alias

Cette directive informe le client que la redirection est permanente (code 301). Son comportement est exactement le même que celui de Redirect permanent.

top

Directive RedirectRelative

Description:Redirection relative de cibles.
Syntaxe:RedirectRelative On|Off
Défaut:RedirectRelative Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_alias
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache

Par défaut, si l'URL cible d'une directive Redirect est une URL relative commençant par un caractère '/', le serveur convertit cette dernière en URL absolue avant de répondre au client. En définissant RedirectRelative à "On", l'URL relative est présentée au client sans modification.

top

Directive RedirectTemp

Description:Envoie une redirection externe temporaire demandant au client d'effectuer une nouvelle requête avec une URL différente
Syntaxe:RedirectTemp chemin URL URL
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_alias

Cette directive informe le client que la redirection n'est que temporaire (code 302). Son comportement est exactement le même que celui de Redirect temp.

top

Directive ScriptAlias

Description:Fait correspondre une URL à une zone du système de fichiers et désigne la cible comme script CGI
Syntaxe:ScriptAlias [chemin URL] chemin fichier|chemin répertoire
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_alias

La directive ScriptAlias présente le même comportement que la directive Alias, mais désigne en plus le répertoire cible comme conteneur de scripts CGI qui seront traitées par le gestionnaire cgi-script du module mod_cgi. Les URLs dont le chemin URL sensible à la casse (décodé avec caractères %) commence par chemin URL seront mises en correspondance avec les scripts dont le chemin commence par le second argument, qui est un chemin complet dans le système de fichiers local.

ScriptAlias "/cgi-bin/" "/web/cgi-bin/"

Une requête pour http://example.com/cgi-bin/foo ferait exécuter par le serveur le script /web/cgi-bin/foo. Cette configuration est sensiblement équivalente à :

Alias "/cgi-bin/" "/web/cgi-bin/"
<Location "/cgi-bin">
    SetHandler cgi-script
    Options +ExecCGI
</Location>

Vous pouvez aussi utiliser ScriptAlias avec un script ou gestionnaire de votre cru. Par exemple :

ScriptAlias "/cgi-bin/" "/web/cgi-handler.pl"

Dans ce scénario, tous les fichiers faisant l'objet d'une requête dans /cgi-bin/ seront traités par le fichier que vous avez spécifié, ce qui vous permet d'utiliser votre propre gestionnaire. Vous pouvez l'utiliser comme enveloppe (wrapper) pour les scripts CGI afin d'ajouter du contenu, ou autre action "maison".

Il est préférable d'éviter de placer les scripts CGI dans l'arborescence de DocumentRoot afin d'éviter de révéler accidentellement leur code source lors d'une modification de configuration. On y parvient aisément avec ScriptAlias en mettant en correspondance une URL et en désignant la cible comme scripts CGI par la même occasion. Si vous choisissez de placer vos scripts CGI dans un répertoire accessible depuis le web, n'utilisez pas ScriptAlias. Utilisez plutôt <Directory>, SetHandler, et Options comme dans l'exemple suivant :
<Directory "/usr/local/apache2/htdocs/cgi-bin">
    SetHandler cgi-script
    Options ExecCGI
</Directory>
Ceci est nécessaire car plusieurs chemins URL peuvent correspondre à la même zone du système de fichiers, court-circuitant ainsi la directive ScriptAlias et révélant le code source des scripts CGI s'ils ne sont pas protégés par une section Directory.

Si la directive ScriptAlias est définie au sein d'une section <Location> ou <LocationMatch> et si l'argument chemin URL est omis, l'argument URL sera interprété en utilisant la syntaxe des expressions.
Cette syntaxe est disponible à partir de la version 2.4.19 du serveur HTTP Apache.

<Location "/cgi-bin">
    ScriptAlias "/web/cgi-bin/"
</Location>
<LocationMatch "/cgi-bin/errors/(?<NUMBER>[0-9]+)">
    ScriptAlias "/web/cgi-bin/errors/%{env:MATCH_NUMBER}.cgi"
</LocationMatch>

Voir aussi

top

Directive ScriptAliasMatch

Description:Fait correspondre une URL à une zone du système de fichiers en faisant appel aux expressions rationnelles et en désignant la cible comme un script CGI
Syntaxe:ScriptAliasMatch regex chemin fichier|chemin répertoire
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_alias

Cette directive est équivalente à la directive ScriptAlias, mais fait appel aux expressions rationnelles, à la place d'une simple mise en correspondance de préfixe. L'expression rationnelle fournie est mise en correspondance avec le chemin URL, et si elle correspond, le serveur va substituer toute partie de chemin entre parenthèses dans la chaîne spécifiée et l'utiliser comme nom de fichier. Par exemple, pour activer le répertoire standard /cgi-bin, on peut utiliser :

ScriptAliasMatch "^/cgi-bin(.*)" "/usr/local/apache/cgi-bin$1"

Comme dans le cas d'AliasMatch, toute la puissance des expressions rationnelles peut être mise à contribution. Par exemple, il est possible de construire un alias avec une comparaison du modèle du chemin URL insensible à la casse :

ScriptAliasMatch "(?i)^/cgi-bin(.*)" "/usr/local/apache/cgi-bin$1"

Les remarques à propos de la différence entre Alias et AliasMatch s'appliquent aussi à la différence entre les directives ScriptAlias et ScriptAliasMatch. Voir la directive AliasMatch pour plus de détails.

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_basic.html.fr.utf80000664000175100017510000005314714740503670022750 0ustar covenercovener mod_auth_basic - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_auth_basic

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Authentification HTTP de base
Statut:Base
Identificateur de Module:auth_basic_module
Fichier Source:mod_auth_basic.c
Compatibilité:Disponible depuis la version 2.1 d'Apache

Sommaire

Ce module permet d'utiliser l'authentification basique HTTP pour restreindre l'accès en recherchant les utilisateurs dans les fournisseurs d'authentification spécifiés. Il est en général combiné avec au moins un module d'authentification comme mod_authn_file et un module d'autorisation comme mod_authz_user. L'authentification HTTP à base de condensé (digest), quant à elle, est fournie par le module mod_auth_digest.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive AuthBasicAuthoritative

Description:Définit si les processus d'autorisation et d'authentification peuvent être confiés à des modules de plus bas niveau
Syntaxe:AuthBasicAuthoritative On|Off
Défaut:AuthBasicAuthoritative On
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_auth_basic

Normalement, chaque module d'autorisation énuméré dans la directive AuthBasicProvider va tenter de vérifier l'utilisateur, et si ce dernier n'est trouvé dans aucun des fournisseurs, l'accès sera refusé. Définir explicitement la directive AuthBasicAuthoritative à Off permet de confier l'autorisation et l'authentification à d'autres modules non basés sur les fournisseurs si aucun identifiant utilisateur ou aucune règle ne correspondent à l'identifiant utilisateur spécifié. Ceci ne peut s'avérer nécessaire que lorsque mod_auth_basic est combiné avec des modules tiers qui n'ont pas été configurés à l'aide de la directive AuthBasicProvider. Lorsqu'on utilise de tels modules, l'ordre dans lequel s'effectue le traitement est défini dans le code source des modules et n'est pas configurable.

top

Directive AuthBasicFake

Description:Authentification de base simulée à l'aide des nom d'utilisateur et mot de passe fournis
Syntaxe:AuthBasicFake off|username [password]
Défaut:none
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_auth_basic
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

Les nom d'utilisateur et mot de passe spécifiés sont rassemblés dans un en-tête d'autorisation qui est transmis au serveur ou au service sous-jacent au serveur. Ces nom d'utilisateur et mot de passe sont interprétés par l'interpréteur d'expression, ce qui permet de les définir en fonction de paramètres de la requête.

Si aucun mot de passe n'est spécifié, la valeur par défaut "password" sera utilisée. Pour désactiver l'authentification de base simulée pour un espace d'URL, définissez AuthBasicFake à "off".

Dans l'exemple suivant, un nom d'utilisateur et un mot de passe prédéfinis sont transmis à un serveur d'arrière-plan :

Exemple de transmission d'un nom d'utilisateur et d'un mot de passe prédéfinis

<Location "/demo">
    AuthBasicFake demo demopass
</Location>

Dans l'exemple suivant, l'adresse email extraite d'un certificat client est transmise au serveur, étendant par là-même la fonctionnalité de l'option FakeBasicAuth de la directive SSLOptions. Comme avec l'option FakeBasicAuth, le mot de passe se voit attribué le contenu fixe de la chaîne "password".

Exemple d'utilisation avec un certificat

<Location "/secure">
    AuthBasicFake "%{SSL_CLIENT_S_DN_Email}"
</Location>

Pour compléter l'exemple précédent, il est possible de générer la valeur du mot de passe en procédant à un hashage de l'adresse email à partir d'un mot d'une passphrase initial fixée, puis de transmettre le résultat obtenu au serveur d'arrière-plan. Ceci peut s'avérer utile pour donner accès à des serveurs anciens qui ne supportent pas les certificats clients.

Exemple de génération de mot de passe par hashage de l'adresse email

<Location "/secure">
    AuthBasicFake "%{SSL_CLIENT_S_DN_Email}" "%{sha1:passphrase-%{SSL_CLIENT_S_DN_Email}}"
</Location>

Désactivation de l'authentification simulée

<Location "/public">
    AuthBasicFake off
</Location>
top

Directive AuthBasicProvider

Description:Définit le(les) fournisseur(s) d'authentification pour cette zone du site web
Syntaxe:AuthBasicProvider nom fournisseur [nom fournisseur] ...
Défaut:AuthBasicProvider file
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_auth_basic

La directive AuthBasicProvider permet de définir le fournisseur utilisé pour authentifier les utilisateurs pour la zone du site web concernée. Le fournisseur par défaut file est implémenté par le module mod_authn_file. Assurez-vous que le module implémentant le fournisseur choisi soit bien présent dans le serveur.

Exemple

<Location "/secure">
    AuthType basic
    AuthName "private area"
    AuthBasicProvider  dbm
    AuthDBMType        SDBM
    AuthDBMUserFile    "/www/etc/dbmpasswd"
    Require            valid-user
</Location>

Les fournisseurs sont sollicités dans l'ordre jusqu'à ce que l'un d'entre eux trouve une correspondance pour le nom d'utilisateur de la requête ; alors, ce dernier fournisseur sera le seul à vérifier le mot de passe. Un échec dans la vérification du mot de passe n'entraîne pas le passage du contrôle au fournisseur suivant.

Les différents fournisseurs disponibles sont implémentés par les modules mod_authn_dbm, mod_authn_file, mod_authn_dbd, mod_authnz_ldap et mod_authn_socache.

top

Directive AuthBasicUseDigestAlgorithm

Description:Vérifie les mots de passe auprès des fournisseurs d'authentification à la manière de l'authentification de type Digest.
Syntaxe:AuthBasicUseDigestAlgorithm MD5|Off
Défaut:AuthBasicUseDigestAlgorithm Off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_auth_basic
Compatibilité:Disponible à partir de la version 2.4.7 du serveur HTTP Apache

Normalement, lorsqu'on utilise l'authentification basique, les fournisseurs spécifiés via la directive AuthBasicProvider tentent de contrôler l'identité d'un utilisateur en recherchant dans leurs bases de données l'existence d'un couple utilisateur/mot de passe correspondant. Les mots de passe enregistrés sont en général chiffrés, mais ce n'est pas systématique ; chaque fournisseur peut choisir son propre mode de stockage des mots de passe.

Lorsqu'on utilise l'authentification de type Digest, les fournisseurs spécifiés par la directive AuthDigestProvider effectuent une recherche similaire dans leurs bases de données pour trouver un couple utilisateur/mot de passe correspondant. Cependant, à la différence de l'authentification basique, les données associées à chaque utilisateur et comportant le nom d'utilisateur, le domaine de protection (realm) et le mot de passe doivent être contenues dans une chaîne chiffrée (Voir le document RFC 2617, Section 3.2.2.2 pour plus de détails à propos du type de chiffrement utilisé pour cette chaîne).

A cause de la différence entre les méthodes de stockage des données des authentifications de type basique et digest, le passage d'une méthode d'authentification de type digest à une méthode d'authentification de type basique requiert l'attribution de nouveaux mots de passe à chaque utilisateur, car leur mots de passe existant ne peut pas être extrait à partir du schéma de stockage utilisé par les fournisseurs d'authentification de type digest.

Si la directive AuthBasicUseDigestAlgorithm est définie à la valeur MD5, le mot de passe d'un utilisateur dans le cas de l'authentification basique sera vérifié en utilisant le même format de chiffrement que dans le cas de l'authentification de type digest. Tout d'abord, une chaîne comportant le nom d'utilisateur, le domaine de protection (realm) et le mot de passe est générée sous forme de condensé (hash) en utilisant l'algorithme MD5 ; puis le nom d'utilisateur et cette chaîne chiffrée sont transmis aux fournisseurs spécifiés via la directive AuthBasicProvider comme si la directive AuthType était définie à Digest et si l'authentification de type Digest était utilisée.

Grâce à cette directive, un site peut basculer d'une authentification de type digest à basique sans devoir changer les mots de passe des utilisateurs.

Le processus inverse consistant à passer d'une authentification de type basique à digest sans changer les mots de passe n'est en général pas possible. Les mots de passe enregistrés dans le cas d'une authentification de type basique ne pourront être extraits et chiffrés à nouveau selon le schéma de l'authentification de type digest, que s'ils ont été stockés en clair ou selon un schéma de chiffrement réversible.
Seuls les fournisseurs qui supportent l'authentification de type digest pourront authentifier les utilisateurs lorsque la directive AuthBasicUseDigestAlgorithm est définie à MD5. L'utilisation d'un autre fournisseur provoquera un message d'erreur et le client se verra refuser l'accès.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_anon.html.fr.utf80000664000175100017510000004374614740503670023004 0ustar covenercovener mod_authn_anon - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authn_anon

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Permet un accès "anonyme" à des zones protégées
Statut:Extension
Identificateur de Module:authn_anon_module
Fichier Source:mod_authn_anon.c
Compatibilité:Disponible depuis la version 2.1 d'Apache

Sommaire

Ce module permet aux frontaux d'authentification comme mod_auth_basic d'authentifier les utilisateurs à la manière des sites FTP anonymes, c'est à dire en fournissant l'identifiant utilisateur spécial 'anonymous' et l'adresse email comme mot de passe. Ces adresses email peuvent être journalisées.

En combinaison avec d'autres méthodes de contrôle d'accès (base de données), ce module permet d'effectuer un véritable suivi des utilisateurs et une personnalisation de leurs accès en fonction de leur profil, tout en conservant l'accessibilité du site aux utilisateurs 'non enregistrés'. Un avantage du suivi des utilisateurs basé sur l'authentification réside dans le fait qu'il est, à l'opposé des cookies magiques et des drôles d'URLs avec préfixes ou suffixes, entièrement indépendant du navigateur et qu'il permet de partager des URLs entre plusieurs utilisateurs.

Si l'on utilise le module mod_auth_basic, le module mod_authn_anon est invoqué en affectant la valeur anon à la directive AuthBasicProvider.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemple

L'exemple ci-dessous présente un exemple de combinaison avec l'authentification à base de fichier htpasswd "normale", et permet la connexion d'utilisateurs en tant qu'invités avec les propriétés suivantes :

Exemple

<Directory "/var/www/html/private">
    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

    Require valid-user
</Directory>
top

Directive Anonymous

Description:Définit la liste des identifiants utilisateur autorisés à accéder sans vérification du mot de passe
Syntaxe:Anonymous utilisateur [utilisateur] ...
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authn_anon

Une liste d'un ou plusieurs identifiants utilisateur spéciaux autorisés à accéder sans vérification du mot de passe. Les identifiants doivent être séparés par un espace. Pour spécifier un identifiant contenant un espace, on peut utiliser les guillemets ' ou ", ou le caractère d'échappement \.

Veuillez noter que la vérification n'est pas sensible à la casse.
Il est fortement conseillé d'intégrer l'utilisateur spécial 'anonymous' dans la liste des identifiants.

Exemple:

Anonymous anonymous "Not Registered" "I don't know"

Dans cet exemple, l'utilisateur peut accéder au site sans vérification du mot de passe en utilisant l'identifiant "anonymous", "Not Registered", "I Don't Know" ou encore "AnonyMous".

Depuis Apache 2.1, il est possible de remplacer la liste des identifiants autorisés par le caractère "*", ce qui permet d'utiliser n'importe quel identifiant pour pouvoir accéder au site.

top

Directive Anonymous_LogEmail

Description:Détermine si le mot de passe fourni sera enregistré dans le journal des erreurs
Syntaxe:Anonymous_LogEmail On|Off
Défaut:Anonymous_LogEmail On
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authn_anon

Lorsque cette directive est définie à On, valeur par défaut, le 'mot de passe' fourni (censé contenir une adresse email valide) est enregistré dans le journal des erreurs.

top

Directive Anonymous_MustGiveEmail

Description:Détermine si l'abscence de mot de passe est autorisée
Syntaxe:Anonymous_MustGiveEmail On|Off
Défaut:Anonymous_MustGiveEmail On
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authn_anon

Détermine si l'utilisateur doit spécifier une adresse email comme mot de passe. Lorsque cette directive est définie à On, l'abscence de mot de passe est interdite.

top

Directive Anonymous_NoUserID

Description:Détermine si le champ identifiant peut être vide
Syntaxe:Anonymous_NoUserID On|Off
Défaut:Anonymous_NoUserID Off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authn_anon

Lorsque cette directive est définie à On, les utilisateurs peuvent laisser le champ identifiant vide (et peut-être aussi le champ mot de passe selon la définition de la directive Anonymous_MustGiveEmail). Ceci peut s'avérer très utile pour les utilisateurs de MS-Explorer qui n'ont pour seule possibilité que d'appuyer sur Entrée ou de cliquer directement sur le bouton OK, ce qui semble être une réaction naturelle.

top

Directive Anonymous_VerifyEmail

Description:Détermine s'il faut vérifier que le format de l'adresse email fournie comme mot de passe est correct
Syntaxe:Anonymous_VerifyEmail On|Off
Défaut:Anonymous_VerifyEmail Off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authn_anon

Lorsque cette directive est définie à On, Apache vérifie que le 'mot de passe' entré contient au moins un '@' et un '.' afin d'inciter les utilisateurs à fournir des adresses email valides (voir ci-dessus la directive Anonymous_LogEmail).

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_dbm.html.fr.utf80000664000175100017510000003313514740503670022602 0ustar covenercovener mod_authn_dbm - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authn_dbm

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Authentification utilisateur utilisant des fichiers DBM
Statut:Extension
Identificateur de Module:authn_dbm_module
Fichier Source:mod_authn_dbm.c
Compatibilité:Disponible depuis les versions 2.1 et supérieures d'Apache

Sommaire

Ce module permet aux frontaux comme mod_auth_digest et mod_auth_basic d'authentifier les utilisateurs en les recherchant dans des fichiers de mots de passe dbm. mod_authn_file fournit une fonctionnalité similaire.

Lorsqu'on utilise mod_auth_basic ou mod_auth_digest, ce module est invoqué en affectant la valeur dbm à la directive AuthBasicProvider ou AuthDigestProvider.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive AuthDBMType

Description:Définit le type de fichier de base de données utilisé pour stocker les mots de passe
Syntaxe:AuthDBMType default|SDBM|GDBM|NDBM|DB
Défaut:AuthDBMType default
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authn_dbm

Cette directive permet de définir le type de fichier de base de données utilisé pour stocker les mots de passe. Le type de base de données par défaut est défini à la compilation. La liste des autres types de bases de données disponibles dépend aussi de la configuration de la compilation.

Par exemple, pour activer le support de Berkeley DB (correspondant au type db), il faut ajouter l'option --with-berkeley-db à la ligne de commande configure de httpd pour générer le DSO approprié.

Il est impératif que le programme que vous utilisez pour créer vos fichiers de mots de passe soit configuré pour utiliser le même type de base de données.

top

Directive AuthDBMUserFile

Description:Définit le nom d'un fichier de base de données pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe
Syntaxe:AuthDBMUserFile chemin-fichier
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authn_dbm

La directive AuthDBMUserFile permet de définir le nom d'un fichier de base de données pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe. chemin-fichier doit être un chemin absolu vers le fichier de base de données.

La clé du fichier de base de données est le nom de l'utilisateur. La valeur associée est le mot de passe chiffré, éventuellement suivi par un ':' et des données arbitraires. Ce ':' ainsi que les données arbitraires qui suivent seront ignorées par le serveur.

Sécurité :

Faites en sorte que le fichier spécifié par la directive AuthDBMUserFile soit stocké en dehors de l'arborescence des documents du serveur web ; en particulier, ne l'enregistrez pas dans le répertoire qu'il protège, faute de quoi, les clients auraient la possibilité de télécharger le fichier des mots de passe.

Le format de mot de passe chiffré dépend du frontal d'authentification utilisé (par exemple mod_auth_basic ou mod_auth_digest). Voir la documentation sur les Formats de mots de passe pour plus de détails.

Note importante concernant la compatibilité : l'implémentation de dbmopen dans les modules d'Apache lit la longueur de la chaîne correspondant aux données chiffrées dans la structure des données DBM, plutôt que de calculer cette longueur en se basant sur le caractère nul final. Certaines applications par contre, comme le serveur web Netscape, calculent cette longueur en se basant sur le caractère nul final ; par conséquent, si vous rencontrez des difficultés en échangeant des fichiers DBM entre plusieurs applications, le problème peut éventuellement s'expliquer par cette différence d'implémentation.

Un script perl nommé dbmmanage est fourni avec Apache. On peut utiliser ce programme pour créer et mettre à jour les fichiers de mots de passe au format DBM que ce module utilise. Il existe également un autre outil pour gérer les fichiers DBM, inclus dans le programme htdbm.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_asis.html.fr.utf80000664000175100017510000002226714740503670021604 0ustar covenercovener mod_asis - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_asis

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Envoie des fichiers contenant leurs propres en-têtes HTTP
Statut:Base
Identificateur de Module:asis_module
Fichier Source:mod_asis.c

Sommaire

Ce module fournit le gestionnaire send-as-is qui permet au serveur HTTP Apache d'envoyer le document sans ajouter la plupart des en-têtes HTTP habituels.

On peut l'utiliser pour envoyer tous types de données en provenance du serveur, y compris les redirections et autres réponses HTTP spéciales, sans devoir faire appel à un script CGI ou nph.

Pour des raisons historiques, ce module traitera aussi tout fichier dont le type MIME est httpd/send-as-is.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Mode d'emploi

Dans le fichier de configuration, associez les fichiers asis au gestionnaire send-as-is comme ceci :

AddHandler send-as-is asis

Le contenu de tout fichier possédant l'extension .asis sera envoyé par Apache httpd au client pratiquement tel quel. En particulier, les en-têtes HTTP seront déduits du fichier lui-même selon les règles du module mod_cgi, si bien qu'un fichier asis doit inclure des en-têtes valides, et utiliser l'en-tête CGI Status: pour déterminer le code de réponse HTTP. L'en-tête Content-Length: sera automatiquement inséré ou, s'il est déjà présent, corrigé par httpd.

Voici un exemple de fichier dont le contenu est envoyé tel quel pour informer un client qu'un fichier a été déplacé.

Status: 301 Ou se trouve cette URL maintenant
Location: http://xyz.example.com/foo/bar.html
Content-type: text/html

<html>
<head>
<title>Mauvaises excuses</title>
</head>
<body>
<h1>La merveilleuse page de Fred a été déplacée vers
<a href="http://xyz.example.com/foo/bar.html">le site de Joe</a>.
</h1>
</body>
</html>

Notes :

Le serveur ajoute systématiquement les en-têtes Date: et Server: aux données qu'il envoie au client, si bien qu'ils n'ont pas besoin d'être inclus dans le fichier. Le serveur n'ajoute pas d'en-tête Last-Modified, ce qu'il devrait probablement faire.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_form.html.fr.utf80000664000175100017510000015526214740503670022633 0ustar covenercovener mod_auth_form - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_auth_form

Langues Disponibles:  en  |  fr 

Description:Authentification à l'aide d'un formulaire
Statut:Base
Identificateur de Module:auth_form_module
Fichier Source:mod_auth_form.c
Compatibilité:Disponible à partir d'Apache 2.3

Sommaire

Avertissement

L'authentification à base de formulaire dépend des modules mod_session qui utilisent les cookies HTTP, et en tant que tels s'exposent à des attaques de type Cross Site Scripting, ou risquent de divulguer des informations à caractère privé aux clients. Assurez-vous que ces risques ont bien été pris en compte avant d'activer les sessions sur votre serveur.

Ce module permet de restreindre l'accès en recherchant les utilisateurs dans les fournisseurs spécifiés à l'aide d'un formulaire de connexion HTML. Les formulaires HTML requièrent davantage de configuration que les méthodes d'authentification alternatives, mais ils peuvent s'avérer beaucoup plus conviviaux pour les utilisateurs.

L'authentification HTTP de base est fournie par le module mod_auth_basic, et l'authentification HTTP à base de condensé par le module mod_auth_digest. Le module mod_auth_form doit être utilisé avec au moins un module d'authentification du style mod_authn_file et un module d'autorisation comme mod_authz_user.

Lorsque l'utilisateur a été authentifié avec succès, ses informations de connexion sont stockés dans une session fournie par le module mod_session.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Configuration de base

Pour protéger une URL particulière avec le module mod_auth_form, vous devez déterminer l'endroit où vous allez stocker votre session, ainsi que la méthode d'authentification. Dans cet exemple simple, les informations de connexion sont stockées dans une session à l'aide du module mod_session_cookie, et l'authentification utilise un fichier en s'appuyant sur le module mod_authn_file. Si l'authentification échoue, l'utilisateur dera redirigé vers la page du formulaire de connexion.

Exemple simple

<Location "/admin">
    AuthFormProvider file
    AuthUserFile "conf/passwd"
    AuthType form
    AuthName "/admin"
    AuthFormLoginRequiredLocation "http://example.com/login.html"

    Session On
    SessionCookieName session path=/

    Require valid-user
</Location>

L'authentification mod_auth_form est activée en affectant la valeur form à la directive AuthType. Les directives AuthFormProvider et AuthUserFile spécifient que les noms d'utilisateurs et mots de passe seront vérifiés en utilisant le fichier choisi.

Les directives Session et SessionCookieName créent une session chiffrée stockée dans un cookie HTTP au niveau du navigateur. Pour plus d'informations à propos des différentes options de configuration des sessions, reportez-vous à la documentation du module mod_session.

Vous pouvez éventuellement ajouter une directive SessionCryptoPassphrase pour créer un cookie de session chiffré. Pour utiliser cette directive, le module mod_session_crypto doit avoir été préalablement chargé.

Dans l'exemple simple ci-dessus, une URL a été protégée par mod_auth_form, mais on doit maintenant fournir à l'utilisateur un moyen d'entrer un nom et un mot de passe. À cet effet, on peut soit écrire une page de connexion indépendante dédiée, soit inclure le formulaire de connexion dans la page courante.

top

Page de connexion dédiée

Le formulaire de connexion peut être contenu dans une page indépendante, ou être inclus dans la page courante.

Lorsque la connexion s'effectue à partir d'une page indépendante et si la tentative d'authentification échoue, l'utilisateur doit être redirigé vers un formulaire de connexion, créé à cet effet sur le site web, en utilisant la directive AuthFormLoginRequiredLocation. En général, la page de connexion contiendra un formulaire HTML demandant à l'utilisateur de fournir un nom et un mot de passe.

Exemple de formulaire de connexion

<form method="POST" action="/dologin.html">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
</form>

La partie où s'effectue la connexion proprement dite est traitée par le gestionnaire form-login-handler. L'action de ce formulaire doit pointer vers ce gestionnaire, ce que l'on configure dans Apache httpd comme suit :

Exemple de configuration du gestionnaire de formulaire de connexion

<Location "/dologin.html">
    SetHandler form-login-handler
    AuthFormLoginRequiredLocation "http://example.com/login.html"
    AuthFormLoginSuccessLocation "http://example.com/admin/index.html"
    AuthFormProvider file
    AuthUserFile "conf/passwd"
    AuthType form
    AuthName /admin
    Session On
    SessionCookieName session path=/
    SessionCryptoPassphrase secret
</Location>

L'URL spécifiée par la directive AuthFormLoginRequiredLocation référencera en général une page expliquant à l'utilisateur que sa tentative de connexion a échoué, et qu'il doit la renouveler. La directive AuthFormLoginSuccessLocation spécifie l'URL vers laquelle l'utilisateur doit être redirigé s'il s'est authentifié avec succès.

Alternativement, l'URL vers laquelle doit être redirigé l'utilisateur s'il s'est authentifié avec succès peut être intégrée dans le formulaire de connexion, comme dans l'exemple ci-dessous. Il en découle que le même gestionnaire form-login-handler pourra être utilisé pour différentes zones du site web.

Exemple de formulaire d'authentification multizone

<form method="POST" action="/dologin.html">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
  <input type="hidden" name="httpd_location" value="http://example.com/success.html" />
</form>
top

Connexion à la volée

Avertissement

Il existe un risque, dans certaines circonstances, que le formulaire de connexion configuré pour une connexion à la volée soit soumis plusieurs fois, révélant de ce fait les paramètres de connexion à l'application sous-jacente. L'administrateur doit s'assurer que cette dernière est correctement sécurisée afin d'éviter les éventuels abus. En cas de doute, utilisez une page de connexion indépendante dédiée.

Comme alternative à la page de connexion dédiée pour un site web, il est possible de configurer mod_auth_form pour authentifier les utilisateurs à la volée, sans les rediriger vers une autre page, ce qui permet de conserver l'état de la page courante au cours de la tentative de connexion. Ceci peut s'avérer utile dans le cas d'une session limitée dans le temps, si le délai de la session a expiré pendant la requête de l'utilisateur. Ce dernier peut alors se réauthentifier à la même place, et poursuivre son activité à partir du point où il en était resté.

Si un utilisateur non authentifié tente d'accéder à une page protégée par mod_auth_form, et si ce dernier n'est pas configuré avec une directive AuthFormLoginRequiredLocation, un code de statut HTTP_UNAUTHORIZED est renvoyé vers le navigateur, indiquant à l'utilisateur qu'il n'est pas autorisé à accéder à cette page.

Pour configurer l'authentification à la volée, l'administrateur remplace le message d'erreur renvoyé par le code de statut HTTP_UNAUTHORIZED par un message d'erreur personnalisé contenant le formulaire de connexion comme suit :

Exemple simple d'authentification à la volée

AuthFormProvider file
ErrorDocument 401 "/login.shtml"
AuthUserFile "conf/passwd"
AuthType form
AuthName realm
Session On
SessionCookieName session path=/

La page du message d'erreur doit contenir un formulaire de connexion dont la propriété action est vide, comme dans l'exemple ci-dessous. Ceci a pour effet de soumettre le formulaire à l'URL protégée originale, cette dernière n'ayant pas besoin d'être connue de la page en cours.

Exemple de formulaire de connexion à la volée

<form method="POST" action="">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
</form>

Lorsque l'utilisateur final a entré ses informations de connexion, le formulaire effectue une requête HTTP POST pour l'URL originale protégée par mot de passe. mod_auth_form va alors intercepter cette requête POST, et dans le cas où des champs HTML Utilisateur et Mot de passe corrects sont présents, l'utilisateur sera connecté, et l'URL originale protégée par mot de passe lui sera retournée en tant que requête GET.

top

Connexion à la volée avec conservation du contenu

Il existe une limite à la technique de connexion à la volée décrite ci-dessus ; si un formulaire HTML POST entraîne une demande d'authentification ou de réauthentification, le contenu du formulaire original envoyé par le navigateur sera perdu. Cela peut s'avérer plus ou moins gênant pour l'utilisateur final selon la fonction du site web.

Comme solution à ce problème, mod_auth_form permet d'intégrer la méthode et le contenu de la requête originale dans le formulaire de connexion. Si l'authentification réussit, Apache httpd pourra refaire une tentative avec la méthode et le contenu originaux, tout en conservant l'état de la requête originale.

Pour mettre en oeuvre la conservation du contenu, vous devez ajouter trois champs supplémentaires au formulaire de connexion comme dans l'exemple suivant :

Exemple de formulaire avec conservation du contenu

<form method="POST" action="">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
  
<input type="hidden" name="httpd_method" value="POST" /> <input type="hidden" name="httpd_mimetype" value="application/x-www-form-urlencoded" /> <input type="hidden" name="httpd_body" value="name1=value1&name2=value2" />
</form>

La manière dont la méthode, le type MIME et le contenu de la requête originale seront intégrés dans le formulaire de connexion vont dépendre de la plate-forme et de la technologie utilisées au sein du site web.

Une option consiste à utiliser le module mod_include en association avec la directive KeptBodySize, ainsi qu'un script CGI adapté pour intégrer les variables dans le formulaire.

Une autre option consiste à présenter le formulaire de connexion en utilisant un script CGI ou une autre technologie dynamique.

Exemple avec script CGI

        AuthFormProvider file
        ErrorDocument 401 "/cgi-bin/login.cgi"
        ...
top

Déconnexion

Pour permettre à un utilisateur de se déconnecter d'une session particulière, vous devez configurer une page pour qu'elle soit traitée par le gestionnaire form-logout-handler. Tout accès à cette URL va entraîner la suppression de l'Utilisateur et du Mot de passe de la session courante, ce qui aura pour effet de déconnecter l'utilisateur.

Vous pouvez spécifier une URL vers laquelle le navigateur sera redirigé en cas de déconnection réussie, en définissant la directive AuthFormLogoutLocation. Cette URL devra expliquer à l'utilisateur qu'il a été déconnecté, et lui donner la possibilité de se connecter à nouveau.

Exemple simple de configuration de la déconnexion

SetHandler form-logout-handler
AuthName realm
AuthFormLogoutLocation "http://example.com/loggedout.html"
Session On
SessionCookieName session path=/

Notez que la déconnexion d'un utilisateur ne supprime pas la session ; elle supprime seulement l'utilisateur et le mot de passe de la session. Si la session qui en résulte est vide, elle sera probablement supprimée, mais ce n'est pas garanti. Si vous voulez être sûr que la session sera supprimée, affectez une valeur faible à la directive SessionMaxAge, par exemple 1 (affecter à cette directive la valeur zéro signifie une session sans limite d'âge).

Exemple simple avec durée de validité de session limitée

SetHandler form-logout-handler
AuthFormLogoutLocation "http://example.com/loggedout.html"
Session On
SessionMaxAge 1
SessionCookieName session path=/
top

Noms d'utilisateurs et mots de passe

Notez que la soumission d'un formulaire implique l'encodage URL (URLEncoding) des données du formulaire, ici le nom d'utilisateur et le mot de passe. Vous devez donc choisir des noms d'utilisateurs et mots de passe qui ne contiennent pas de caractères susceptibles d'être encodés URL lors de la soumission du formulaire, sous peine d'obtenir des résultats inattendus.

top

Directive AuthFormAuthoritative

Description:Détermine si l'autorisation et l'authentification sont confiés à des modules de plus bas niveau
Syntaxe:AuthFormAuthoritative On|Off
Défaut:AuthFormAuthoritative On
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_auth_form

Normalement, chacun des modules d'autorisation spécifiés par la directive AuthFormProvider va tenter de vérifier l'identité de l'utilisateur, et si ce dernier n'est trouvé dans aucun fournisseur, l'accès sera refusé. En définissant explicitement la directive AuthFormAuthoritative à Off on confie les processus d'authentification et d'autorisation à des modules ne s'appuyant pas sur des fournisseurs, si aucun identifiant utilisateur ou aucune règle ne correspond à l'identifiant utilisateur fourni. Ceci ne peut s'avérer nécessaire que si l'on combine mod_auth_form avec des modules tiers qui ne se configurent pas avec la directive AuthFormProvider. Lorsqu'on utilise de tels modules, la chronologie du processus est déterminée dans leur code source, et n'est pas configurable.

top

Directive AuthFormBody

Description:Le nom du champ de formulaire contenant le corps de la requête à effectuer en cas de connexion réussie
Syntaxe:AuthFormBody nom du champ
Défaut:AuthFormBody httpd_body
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive AuthFormBody spécifie le nom du champ HTML qui, s'il existe, contiendra le corps de la requête à effectuer en cas de connexion réussie.

En ajoutant au formulaire les champs décrits dans AuthFormMethod, AuthFormMimetype et AuthFormBody, un site web sera en mesure de relancer une requête qui a été éventuellement interrompue par l'écran de connexion, ou par l'expiration d'un délai de session.

top

Directive AuthFormDisableNoStore

Description:Désactive l'en-tête CacheControl no-store sur la page de connexion
Syntaxe:AuthFormDisableNoStore On|Off
Défaut:AuthFormDisableNoStore Off
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

Le drapeau AuthFormDisableNoStore supprime l'envoi d'un en-tête Cache-Control no-store lorsqu'une page avec code d'erreur 401 est renvoyée, si l'utilisateur n'est pas encore connecté. Avec cette en-tête, il est plus difficile pour une application ecmascript de resoumettre un formulaire de connexion, et ainsi révéler le nom d'utilisateur et le mot de passe à l'application sous-jacente. Vous devez être conscient des risques encourus si vous le désactivez.

top

Directive AuthFormFakeBasicAuth

Description:Simule une en-tête d'authentification de base
Syntaxe:AuthFormFakeBasicAuth On|Off
Défaut:AuthFormFakeBasicAuth Off
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

Le drapeau AuthFormFakeBasicAuth détermine si une en-tête d'Authentification de base sera ajoutée aux en-têtes de la requête. On peut utiliser cette méthode pour présenter le nom d'utilisateur et le mot de passe à l'application sous-jacente, sans que cette dernière ait besoin de connaître la manière dont le processus de connexion a été mené à bien.

top

Directive AuthFormLocation

Description:Le nom du champ de formulaire qui contiendra l'URL vers laquelle l'utilisateur sera redirigé en cas de connexion réussie
Syntaxe:AuthFormLocation nom du champ
Défaut:AuthFormLocation httpd_location
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive AuthFormLocation spécifie le nom du champ HTML qui, s'il existe, contiendra l'URL vers laquelle rediriger le navigateur en cas de connexion réussie.

top

Directive AuthFormLoginRequiredLocation

Description:L'URL de la page vers laquelle on doit être redirigé si une authentification est requise
Syntaxe:AuthFormLoginRequiredLocation url
Défaut:none
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache. L'interprétation des expressions rationnelles est supportée depuis la version 2.4.4.

La directive AuthFormLoginRequiredLocation spécifie l'URL vers laquelle l'utilisateur devra être redirigé s'il n'est pas autorisé à accéder à une page. Sa valeur est interprétée via l'interpréteur ap_expr avant d'être envoyée au client. Par défaut, si un utilisateur n'est pas autorisé à accéder à une page, le code de réponse HTTP HTTP_UNAUTHORIZED est renvoyé avec la page spécifiée par la directive ErrorDocument. La directive AuthFormLoginRequiredLocation permet de remplacer cette valeur par défaut.

Vous pouvez utiliser cette directive si vous voulez présenter une page de connexion personnalisée à vos utilisateurs.

top

Directive AuthFormLoginSuccessLocation

Description:L'URL de la page vers laquelle on doit être redirigé en cas de connexion réussie
Syntaxe:AuthFormLoginSuccessLocation url
Défaut:none
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache. L'interprétation des expressions rationnelles est supportée depuis la version 2.4.4.

La directive AuthFormLoginSuccessLocation spécifie l'URL vers laquelle l'utilisateur doit être redirigé en cas de connexion réussie. Sa valeur est interprétée via l'interpréteur ap_expr avant d'être envoyée au client. L'effet de cette directive peut être annulé si l'on a défini un champ de formulaire contenant une autre URL à l'aide de la directive AuthFormLocation.

Vous pouvez utiliser cette directive si vous possédez une URL de connexion personnalisée, et si vous n'avez pas intégré la page de destination dans le formulaire de connexion.

top

Directive AuthFormLogoutLocation

Description:L'URL vers laquelle un utilisateur devra être redirigé après s'être déconnecté
Syntaxe:AuthFormLogoutLocation uri
Défaut:none
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache. L'interprétation des expressions rationnelles est supportée depuis la version 2.4.4.

La directive AuthFormLogoutLocation spécifie l'URL de la page du serveur vers laquelle l'utilisateur devra être redirigé s'il se déconnecte. Sa valeur est interprétée via l'interpréteur ap_expr avant d'être envoyée au client.

Lorsqu'un accès est tenté sur un URI traité par le gestionnaire form-logout-handler, la page spécifiée par cette directive sera présentée à l'utilisateur final. Par exemple :

Exemple

<Location "/logout">
    SetHandler form-logout-handler
    AuthFormLogoutLocation "http://example.com/loggedout.html"
    Session on
    #...
</Location>

Si un utilisateur tente d'accéder à l'URI /logout/, il sera déconnecté, et la page /loggedout.html lui sera présentée. Assurez-vous que la page loggedout.html n'est pas protégée par mot de passe, car dans le cas contraire, elle ne serait pas affichée.

top

Directive AuthFormMethod

Description:Le nom du champ de formulaire contenant la méthode de la requête à effectuer en cas de connexion réussie
Syntaxe:AuthFormMethod nom du champ
Défaut:AuthFormMethod httpd_method
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive AuthFormMethod spécifie le nom du champ HTML qui, s'il existe, contiendra le type MIME de la requête à effectuer en cas de connexion réussie.

En ajoutant au formulaire les champs décrits dans AuthFormMethod, AuthFormMimetype et AuthFormBody, un site web sera en mesure de relancer une requête qui a été éventuellement interrompue par l'écran de connexion, ou par l'expiration d'un délai de session.

top

Directive AuthFormMimetype

Description:Le nom du champ de formulaire contenant le type MIME du corps de la requête à effectuer en cas de connexion réussie
Syntaxe:AuthFormMimetype nom du champ
Défaut:AuthFormMimetype httpd_mimetype
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive AuthFormMimetype spécifie le nom du champ HTML qui, s'il existe, contiendra le type MIME de la requête à effectuer en cas de connexion réussie.

En ajoutant au formulaire les champs décrits dans AuthFormMethod, AuthFormMimetype et AuthFormBody, un site web sera en mesure de relancer une requête qui a été éventuellement interrompue par l'écran de connexion, ou par l'expiration d'un délai de session.

top

Directive AuthFormPassword

Description:Le nom du champ de formulaire qui contient le mot de passe de connexion
Syntaxe:AuthFormPassword nom du champ
Défaut:AuthFormPassword httpd_password
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive AuthFormPassword permet de spécifier le nom du champ HTML qui, s'il existe, contiendra le mot de passe qui sera utilisé pour la connexion.

top

Directive AuthFormProvider

Description:Définit le(s) fournisseur(s) d'authentification pour la zone concernée
Syntaxe:AuthFormProvider nom fournisseur [nom fournisseur] ...
Défaut:AuthFormProvider file
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_auth_form

La directive AuthFormProvider permet de définir quel fournisseur sera utilisé pour authentifier les utilisateurs pour la zone concernée. Le fournisseur par défaut file est implémenté par le module mod_authn_file. Assurez-vous que le fournisseur choisi soit bien présent dans le serveur.

Exemple

<Location "/secure">
    AuthType form
    AuthName "private area"
    AuthFormProvider  dbm
    AuthDBMType        SDBM
    AuthDBMUserFile    "/www/etc/dbmpasswd"
    Require            valid-user
    #...
</Location>

Les différents fournisseurs sont implémentés par les modules mod_authn_dbm, mod_authn_file, mod_authn_dbd et mod_authnz_ldap.

top

Directive AuthFormSitePassphrase

Description:Court-circuite l'authentification pour les sites à fort trafic
Syntaxe:AuthFormSitePassphrase secret
Défaut:none
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive AuthFormSitePassphrase spécifie un mot de passe qui, s'il est présent dans la session utilisateur, indique à Apache httpd de court-circuiter l'authentification pour l'URL considérée. On peut l'utiliser dans le cas de sites web à fort trafic afin de réduire la charge induite sur l'infrastructure d'authentification.

On peut insérer le mot de passe dans une session utilisateur en ajoutant cette directive à la configuration concernant le gestionnaire form-login-handler. Le gestionnaire form-login-handler, quant à lui, effectuera toujours les vérifications d'authentification, qu'un mot de passe soit spécifié ou non.

Avertissement

Si la session est présentée à l'utilisateur à l'aide du module mod_session_cookie, et si la session n'est pas protégée par le module mod_session_crypto, le mot de passe peut faire l'objet d'une attaque de type dictionnaire. Quelle que soit la configuration de la session, assurez-vous que cette directive n'est pas utilisée dans un espace d'URLs contenant des données privées, ou à partir desquelles des transactions sensibles pourraient être menées. En tout état de cause, vous devez être conscient des risques encourus avant de l'utiliser.

top

Directive AuthFormSize

Description:La taille maximale en octets du formulaire dont seront extraites les informations de connexion
Syntaxe:AuthFormSize taille
Défaut:AuthFormSize 8192
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive AuthFormSize spécifie la taille maximale du corps de la requête qui sera utilisée pour trouver le formulaire de connexion.

Si une requête de connexion entrante possède une taille supérieure à cette valeur, elle sera rejetée avec le code de réponse HTTP HTTP_REQUEST_TOO_LARGE.

Si vous avez ajouté au formulaire des champs décrits dans AuthFormMethod, AuthFormMimetype et AuthFormBody, il est recommandé de définir cette directive à une valeur similaire à celle de la directive KeptBodySize.

top

Directive AuthFormUsername

Description:Le nom du champ de formulaire qui contient le nom de connexion
Syntaxe:AuthFormUsername nom du champ
Défaut:AuthFormUsername httpd_username
Contexte:répertoire
Statut:Base
Module:mod_auth_form
Compatibilité:Disponible depuis la version 2.3.3 du serveur HTTP Apache

La directive AuthFormUsername permet de spécifier le nom du champ HTML qui, s'il existe, contiendra le nom d'utilisateur qui sera utilisé pour la connexion.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_dbm.html.fr.utf80000664000175100017510000003340514740503670022616 0ustar covenercovener mod_authz_dbm - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authz_dbm

Langues Disponibles:  en  |  fr  |  ko 

Description:Autorisation basée sur les groupes à l'aide de fichiers DBM
Statut:Extension
Identificateur de Module:authz_dbm_module
Fichier Source:mod_authz_dbm.c
Compatibilité:Disponible depuis les versions 2.1 et supérieures d'Apache

Sommaire

Ce module permet d'autoriser ou d'interdire l'accès à certaines zones du site web aux utilisateurs authentifiés en fonction de leur appartenance à un groupe spécifié. Le module mod_authz_groupfile fournit une fonctionnalité similaire.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

The Require Directives

Les directives Require d'Apache permettent, au cours de la phase d'autorisation, de s'assurer qu'un utilisateur est bien autorisé à accéder à une ressource. mod_authz_dbm ajoute les types d'autorisation dbm-group et dbm-file-group.

A partir de la version 2.4.8, les directives require DBM supportent les expressions.

Require dbm-group

Cette directive permet de spécifier à quel groupe un utilisateur doit appartenir pour obtenir l'autorisation d'accès.

Require dbm-group admin

Require dbm-file-group

Lorsque cette directive est définie, l'utilisateur doit appartenir au groupe du fichier pour pouvoir y accéder.

Require dbm-file-group
top

Exemple d'utilisation

Notez que si vous utilisez mod_authz_dbm, le mot-clé pour les groupes d'authentification qui était auparavant group est maintenant dbm-group :

<Directory "/foo/bar">
  AuthType Basic 
  AuthName "Secure Area"
  AuthBasicProvider dbm 
  AuthDBMUserFile "site/data/users"
  AuthDBMGroupFile "site/data/users" 
  Require dbm-group admin 
</Directory>
top

Directive AuthDBMGroupFile

Description:Définit le nom du fichier de base de données contenant la liste des groupes d'utilisateurs permettant de définir les autorisations des utilisateurs
Syntaxe:AuthDBMGroupFile chemin-fichier
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authz_dbm

La directive AuthDBMGroupFile sert à définir le nom d'un fichier DBM contenant la liste des groupes d'utilisateurs. Les utilisateurs peuvent dès lors se voir autoriser ou refuser leurs accès selon l'appartenance à tel ou tel groupe. chemin-fichier est le chemin absolu du fichier de groupes.

La clé du fichier de groupes est le nom d'utilisateur. La valeur de chaque clé est la liste des groupes, séparés par des virgules, auxquels l'utilisateur appartient. Cette liste ne doit comporter ni espace, ni caractère ':'.

Sécurité

Le fichier spécifié par la directive AuthDBMGroupFile doit être situé en dehors de l'arborescence des documents du serveur web. Ne le placez surtout pas dans le répertoire qu'il protège, faute de quoi, les clients pourraient le télécharger, en l'abscence de protection supplémentaire.

Utilisation combinée de fichiers DBM de groupes et de mots de passe : dans certains cas, il est plus simple de gérer une seule base de données contenant les groupes et mots de passe de chaque utilisateur. L'écriture de programmes de support en est ainsi simplifiée car ils n'ont plus qu'un seul fichier DBM à gérer et à verrouiller. Pour ce faire, on attribue le même nom de fichier DBM aux fichiers de groupes et de mots de passe :

AuthDBMGroupFile "/www/userbase"
AuthDBMUserFile "/www/userbase"

La clé du fichier DBM unique est le nom d'utilisateur. La valeur associée à la clé contient :

Mot de passe chiffré : Liste de groupes [ : (ignoré) ]

La partie mot de passe contient comme d'habitude le mot de passe chiffré. Viennent ensuite le caractère ':' et la liste des groupes séparés par des virgules. Il est possible d'ajouter d'autres données en fin de ligne après un autre caractère ':', mais elles seront ignorées par le module d'autorisation. Il s'agit du format utilisé par www.telescope.org pour sa base de données combinée groupes et mots de passe.

top

Directive AuthzDBMType

Description:Définit le type de fichier de base de données contenant la liste des groupes d'utilisateurs
Syntaxe:AuthzDBMType default|SDBM|GDBM|NDBM|DB
Défaut:AuthzDBMType default
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authz_dbm

Définit le type de fichier de base de données contenant la liste des groupes d'utilisateurs. Le type de base de données par défaut est déterminé à la compilation. Les autres types de bases de données disponibles dépendent aussi de la configuration de la compilation.

Quel que soit le programme que vous utilisez pour créer votre fichier de groupes, il est impératif que celui-ci soit configuré pour utiliser le même type de base de données.

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_status.html.ko.euc-kr0000664000175100017510000002307014743132254022462 0ustar covenercovener mod_status - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_status

ֽ ƴմϴ. ֱٿ ϼ.
: Ȱ ɿ Ѵ
:Base
:status_module
ҽ:mod_status.c

Status ڿ ¸ ش. ִ HTML 踦 ش. ʿϴٸ (ǥ ) ڵ ִ. ¸ ǻͰ ִ ִ.

˷ִ :

ǥ ġ "(*)" ǥ 踦 . Ͻ ɼ ؾ Ѵ.

Support Apache!

þ

⿡ þ ϴ.

Bugfix checklist

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) Ͽ Ͽ ڵ鷯 ִ. ׷ Ʈ ߻ ִ.

:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_suexec.html.ko.euc-kr0000664000175100017510000002010514743132254022427 0ustar covenercovener mod_suexec - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_suexec

ֽ ƴմϴ. ֱٿ ϼ.
:CGI ũƮ Ư ڿ ׷ Ѵ
:Extension
:suexec_module
ҽ:mod_suexec.c
:ġ 2.0 ĺ

suexec α׷ Ͽ CGI ũƮ Ư ڿ ׷ Ѵ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_unique_id.html.ko.euc-kr0000664000175100017510000003213614743132254023124 0ustar covenercovener mod_unique_id - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_unique_id

ֽ ƴմϴ. ֱٿ ϼ.
: û ĺڸ ȯ溯 Ѵ
:Extension
:unique_id_module
ҽ:mod_unique_id.c

 Ư Ȳ "" û߿ ϵ ĺ(identifier) û Ѵ. ĺڴ Ưϰ Ŭ ǻ͵ ߿ ϴ. û ȯ溯 UNIQUE_ID Ѵ. ĺڴ 뵵 , Ѿ.

Support Apache!

þ

⿡ þ ϴ.

Bugfix checklist

top

̷

н ýۿ ġ  ϴ 캸. Windows NT ʴ´. н ġ ڽ , ڽ μ ѹ û óѴ. ڽ ߿ û óѴ. ⼭ ߿ ڽĵ ڷḦ ʴ´ٴ ̴. ڽ httpd μ Ѵ.

ǻͷ Ʈ Ѵٸ Ŭ(cluster) θ. ǻʹ ġ ִ. ̵ θ "" , ŬͿ ִ ǻ͵鰣 ž û ֿ ĺڸ ִ.

ŬͿ ִ ǻʹ 䱸 ؾ Ѵ. (ǻ͸ Ѵ븸 ϴ ǻ ð NTP ؾ Ѵ.)

ü 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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_userdir.html.ko.euc-kr0000664000175100017510000002545314743132254022623 0ustar covenercovener mod_userdir - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_userdir

ֽ ƴմϴ. ֱٿ ϼ.
:ں 丮
:Base
:userdir_module
ҽ:mod_userdir.c

ϸ http://example.com/~user/ ں 丮 ִ.

Support Apache!

þ

Bugfix checklist

top

UserDir þ

:ں 丮 ġ
:UserDir directory-filename
⺻:UserDir public_html
:ּ, ȣƮ
:Base
:mod_userdir

UserDir þ û Ȩ丮 ȿ 丮 Ѵ. Directory-filename ϳ̴:

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_version.html.ko.euc-kr0000664000175100017510000002443614743132254022633 0ustar covenercovener mod_version - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 >

ġ mod_version

ֽ ƴմϴ. ֱٿ ϼ.
:
:Extension
:version_module
ҽ:mod_version.c
:ġ 2.1 ĺ

ٸ ٷ ū Ʈ ׽Ʈ ϱ . 񱳳 ǥ Ͽ ο ˻簡 <IfVersion> Ѵ.

<IfVersion 2.1.0>
# Ȯ 2.1.0̴
</IfVersion>

<IfVersion >= 2.2>
# ¥ ο Ѵ :-)
</IfVersion>

ٸ Ʒ Ѵ.

Support Apache!

þ

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/module-dict.html.ko.euc-kr0000664000175100017510000002077014743132254022512 0ustar covenercovener ϱ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

ϱ

ġ ϱ  Ѵ.

Support Apache!

top

.

top

ġ 󸶳 ִ Ÿ. , Ư ϱؼ ٽ ؾ 찡 ִ. Ӽ :

MPM
° "MPM" ó ̴. ٸ ޸ ġ MPM Ѵ. ̷ ⺻ û ó й踦 Ѵ.
Base
° "Base" ⺻ ϵǹǷ, ʴ ִ.
Extension
° "Extension" ϵ ʴ´. Ϸ ϰ ġ ٽ ؾ Ѵ.
Experimental
"Experimental" ´ ġ Ե, Ϸ ؾ Ѵ. ⿡ , Ѵٴ ƴϴ.
External
"External" ´ ⺻ ġ Ե ("ڰ ")̴. 츮 ̷ ⿡ å ʴ´.
top

ҽ

ϰ ؼ ҽڵ尡 ִ ҽϸ̴. <IfModule> þ ϴ ̸̱⵵ ϴ.

top

Īϴ ڿ, о̴ LoadModule þ Ѵ. Ȯ ϸ ҽϿ module ܺκ ̸̴.

top

ġ 2 Ե ʾҴٸ, ó Ұ ˷ش. , Ư ÷̶ Ѵ.

:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authnz_fcgi.html.fr.utf80000664000175100017510000007251614740503670023150 0ustar covenercovener mod_authnz_fcgi - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authnz_fcgi

Langues Disponibles:  en  |  fr 

Description:Permet à une application d'autorisation FastCGI de gérer l'authentification et l'autorisation httpd.
Statut:Extension
Identificateur de Module:authnz_fcgi_module
Fichier Source:mod_authnz_fcgi.c
Compatibilité:Disponible à partir de la version 2.4.10 du serveur HTTP Apache

Sommaire

Ce module permet aux applications d'autorisation FastCGI d'authentifier les utilisateurs et de contrôler leur accès aux ressources. Il supporte les systèmes d'autorisation FastCGI génériques qui participent en une seule phase à l'authentification et à l'autorisation, ainsi que les processus d'authentification et d'autorisation spécifiques à Apache httpd qui interviennent en une ou plusieurs phases.

Les processus d'autorisation FastCGI peuvent authentifier un utilisateur via son identificateur et son mot de passe comme dans le processus d'authentification basique, ou via un mécanisme arbitraire.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Modes d'invocation

Les modes d'invocation des processus d'autorisation FastCGI que ce module supporte se distinguent par deux caractéristiques : le type et le mécanisme d'authentification.

Le Type est simplement authn pour l'authentification, authz pour l'autorisation et authnz l'authentification et l'autorisation.

Le mécanisme d'authentification fait référence aux mécanismes d'authentification et aux phases de traitement de la configuration de Apache httpd, et peut être AuthBasicProvider, Require, ou check_user_id. Les deux premiers mécanismes correspondent aux directives utilisées pour participer aux phases de traitement appropriées.

Description de chaque mode:

Type authn, mechanism AuthBasicProvider
Dans ce mode, la variable FCGI_ROLE est définie à AUTHORIZER, et la variable FCGI_APACHE_ROLE à AUTHENTICATOR. L'application doit être spécifiée en tant que fournisseur de type authn via la directive AuthnzFcgiDefineProvider, et activée via la directive AuthBasicProvider. Lorsqu'elle est invoquée, l'application est censée authentifier le client à l'aide de l'identifiant et du mot de passe de l'utilisateur. Exemple d'application :
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHENTICATOR";
    die if $ENV{'FCGI_ROLE'}        ne "AUTHORIZER";
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" ) {
        print "Status: 200\n";
        print "Variable-AUTHN_1: authn_01\n";
        print "Variable-AUTHN_2: authn_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
    }
}
Exemple de configuration httpd :
AuthnzFcgiDefineProvider authn FooAuthn fcgi://localhost:10102/
<Location "/protected/">
  AuthType Basic
  AuthName "Restricted"
  AuthBasicProvider FooAuthn
  Require ...
</Location>
Type authz, mechanism Require
Dans ce mode, la variable FCGI_ROLE est définie à AUTHORIZER et FCGI_APACHE_ROLE à AUTHORIZER. L'application doit être spécifiée en tant que fournisseur de type authz via la directive AuthnzFcgiDefineProvider. Lorsqu'elle est invoquée, l'application est censée contrôler les accès du client à l'aide de l'identifiant utilisateur et d'autres données contenues dans la requête. Exemple d'application :
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHORIZER";
    die if $ENV{'FCGI_ROLE'}        ne "AUTHORIZER";
    die if $ENV{'REMOTE_PASSWD'};

    print STDERR "This text is written to the web server error log.\n";

    if ($ENV{'REMOTE_USER'} eq "foo1") {
        print "Status: 200\n";
        print "Variable-AUTHZ_1: authz_01\n";
        print "Variable-AUTHZ_2: authz_02\n";
        print "\n";
    }
    else {
        print "Status: 403\n\n";
    }
}
Exemple de configuration httpd :
AuthnzFcgiDefineProvider authz FooAuthz fcgi://localhost:10103/
<Location "/protected/">
  AuthType ...
  AuthName ...
  AuthBasicProvider ...
  Require FooAuthz
</Location>
Type authnz, mechanism AuthBasicProvider + Require
Dans ce mode qui supporte le protocole d'autorisation web server-agnostic FastCGI, la variable FCGI_ROLE est définie à AUTHORIZER et FCGI_APACHE_ROLE n'est pas définie. L'application doit être spécifiée en tant que fournisseur de type authnz via la directive AuthnzFcgiDefineProvider. L'application est censée assurer l'authentification et l'autorisation au cours d'une même invocation à l'aide de l'identifiant et du mot de passe de l'utilisateur et d'autres données contenues dans la requête. L'invocation de l'application intervient au cours de la phase d'authentification de l'API Apache httpd. Si l'application renvoie le code 200, et si le même fournisseur est invoqué au cours de la phase d'autorisation (via une directive Require), mod_authnz_fcgi renverra un code de type success pour la phase d'autorisation sans invoquer l'application. Exemple d'application :
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'};
    die if $ENV{'FCGI_ROLE'} ne "AUTHORIZER";
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" &&
        $ENV{'REQUEST_URI'} =~ m%/bar/.*%) {
        print "Status: 200\n";
        print "Variable-AUTHNZ_1: authnz_01\n";
        print "Variable-AUTHNZ_2: authnz_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
    }
}
Exemple de configuration httpd :
AuthnzFcgiDefineProvider authnz FooAuthnz fcgi://localhost:10103/
<Location "/protected/">
  AuthType Basic
  AuthName "Restricted"
  AuthBasicProvider FooAuthnz
  Require FooAuthnz
</Location>
Type authn, mechanism check_user_id
Dans ce mode, la variable FCGI_ROLE est définie à AUTHORIZER et FCGI_APACHE_ROLE à AUTHENTICATOR. L'application doit être spécifiée en tant que fournisseur de type authn via une directive AuthnzFcgiDefineProvider. La directive AuthnzFcgiCheckAuthnProvider permet de l'invoquer. Exemple d'application :
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHENTICATOR";
    die if $ENV{'FCGI_ROLE'} ne "AUTHORIZER";

    # This authorizer assumes that the RequireBasicAuth option of 
    # AuthnzFcgiCheckAuthnProvider is On:
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" ) {
        print "Status: 200\n";
        print "Variable-AUTHNZ_1: authnz_01\n";
        print "Variable-AUTHNZ_2: authnz_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
        # If a response body is written here, it will be returned to
        # the client.
    }
}
Exemple de configuration httpd :
AuthnzFcgiDefineProvider authn FooAuthn fcgi://localhost:10103/
<Location "/protected/">
  AuthType ...
  AuthName ...
  AuthnzFcgiCheckAuthnProvider FooAuthn \
                               Authoritative On \
                               RequireBasicAuth Off \
                               UserExpr "%{reqenv:REMOTE_USER}"
  Require ...
</Location>
top

Exemples supplémentaires

  1. Si votre application supporte séparément les rôles d'authentification et d'autorisation (AUTHENTICATOR et AUTHORIZER), vous pouvez définir des fournisseurs séparés comme suit, même s'ils correspondent à la même application :
    AuthnzFcgiDefineProvider authn  FooAuthn  fcgi://localhost:10102/
    AuthnzFcgiDefineProvider authz  FooAuthz  fcgi://localhost:10102/
    Spécifie le fournisseur authn via la directive AuthBasicProvider et le fournisseur authz via la directive Require:
    AuthType Basic
    AuthName "Restricted"
    AuthBasicProvider FooAuthn
    Require FooAuthz
  2. Si votre application supporte le rôle générique AUTHORIZER (authentification et autorisation en une seule invocation), vous pouvez définir un fournisseur unique comme suit :
    AuthnzFcgiDefineProvider authnz FooAuthnz fcgi://localhost:10103/
    Spécifie le fournisseur authnz via les directives AuthBasicProvider et Require :
    AuthType Basic
    AuthName "Restricted"
    AuthBasicProvider FooAuthnz
    Require FooAuthnz
top

Limitations

Les fonctionnalités suivantes ne sont pas encore implémentées :

Vérificateur d'accès d'Apache httpd
La phase access check de l'API Apache httpd est distincte des phases d'authentification et d'autorisation. Certaines autres implémentations de FastCGI supportent cette phase et lorsque c'est le cas, la variable FCGI_APACHE_ROLE est définie à ACCESS_CHECKER.
Redirections (pipes) ou sockets locaux (Unix)
Seuls les sockets TCP sont actuellement supportés.
Support de mod_authn_socache
Le support de l'interaction avec mod_authn_socache pour les applications qui interviennent dans le processus d'authentification d'Apache httpd serait souhaitable.
Support de l'authentification de type digest à l'aide de AuthDigestProvider
Cette limitation ne sera probablement jamais franchie car il n'existe aucun flux de données d'autorisation capable de lire dans un condensé de type hash.
Gestion des processus applicatifs
Cette fonctionnalité restera probablement hors de portée de ce module. Il faudra donc gérer les processus applicatifs d'une autre manière ; par exemple, fcgistarter permet de les démarrer.
AP_AUTH_INTERNAL_PER_URI
Tous les fournisseurs sont actuellement enregistrés en tant que AP_AUTH_INTERNAL_PER_CONF, ce qui signifie que les vérifications ne sont pas effectuées pour les sous-requêtes internes avec la même configuration de contrôle d'accès que la requête initiale.
Conversion du jeu de caractères des données de protocole
Si mod_authnz_fcgi s'exécute dans un environnement de compilation EBCDIC, toutes les données de protocole FastCGI sont écrites en EBCDIC et doivent être disponibles en EBCDIC.
Plusieurs requêtes pour une connexion
Actuellement, la connexion au fournisseur d'autorisation FastCGI est fermée après chaque phase de traitement. Par exemple, si le fournisseur d'autorisation gère séparément les phases authn et authz, deux connexions seront nécessaires.
Redirection de certains URIs
Les URIs en provenance des clients ne peuvent pas être redirigés selon une table de redirection, comme avec la directive ProxyPass utilisée avec les répondeurs FastCGI.
top

Journalisation

  1. Les erreurs de traitement sont journalisées à un niveau error ou supérieur.
  2. Les messages envoyés par l'application sont journalisés au niveau warn.
  3. Les messages de deboguage à caractère général sont journalisés au niveau debug.
  4. Les variables d'environnement transmises à l'application sont journalisées au niveau trace2. La valeur de la variable REMOTE_PASSWD sera occultée, mais toute autre donnée sensible sera visible dans le journal.
  5. Toutes les entrées/sorties entre le module et l'application FastCGI, y compris les variables d'environnement, seront journalisées au format imprimable et hexadécimal au niveau trace5. Toutes les données sensibles seront visibles dans le journal.

La directive LogLevel permet de configurer un niveau de journalisation spécifique à mod_authnz_fcgi. Par exemple :

LogLevel info authnz_fcgi:trace8
top

Directive AuthnzFcgiCheckAuthnProvider

Description:Permet à une application FastCGI de gérer l'accroche d'authentification check_authn.
Syntaxe:AuthnzFcgiCheckAuthnProvider provider-name|None option ...
Défaut:none
Contexte:répertoire
Statut:Extension
Module:mod_authnz_fcgi

Cette directive permet de confier à une application FastCGI la gestion d'une phase spécifique du processus d'authentification ou d'autorisation.

Certaines fonctionnalités des fournisseurs d'autorisation FastCGI nécessitent cette directive en lieu et place de AuthBasicProvider pour pouvoir être activées :

provider-name
C'est le nom du fournisseur défini au préalable via la directive AuthnzFcgiDefineProvider.
None
Spécifiez None pour désactiver un fournisseur activé avec cette même directive dans une autre portée, par exemple dans un répertoire parent.
option
Les options suivantes sont supportées :
Authoritative On|Off (par défaut On)
Cette option permet de définir si l'appel à d'autres modules est autorisé lorsqu'un fournisseur d'autorisation FastCGI a été configuré et si la requête échoue.
DefaultUser id utilisateur
Lorsque le fournisseur d'autorisation donne son accord, et si UserExpr est défini et correspond à une chaîne vide, (par exemple, si le fournisseur d'autorisation ne renvoie aucune variable), c'est cette valeur qui sera utilisée comme id utilisateur par défaut. Cela se produit souvent lorsqu'on se trouve dans un contexte d'invité, ou d'utilisateur non authentifié ; les utilisateurs et invités se voient alors attribué un id utilisateur spécifique qui permettra de se connecter et d'accéder à certaines ressources.
RequireBasicAuth On|Off (par défaut Off)
Cette option permet de définir si l'authentification basique est requise avant de transmettre la requête au fournisseur d'autorisation. Dans l'affirmative, le fournisseur d'autorisation ne sera invoqué qu'en présence d'un id utilisateur et d'un mot de passe ; si ces deux éléments ne sont pas présents, un code d'erreur 401 sera renvoyé
UserExpr expr (pas de valeur par défaut)
Lorsque le client ne fournit pas l'authentification basique et si le fournisseur d'autorisation détermine l'id utilisateur, cette expression, évaluée après l'appel au fournisseur d'autorisation, permet de déterminer l'id utilisateur. Cette expression se conforme à la syntaxe ap_expr et doit correspondre à une chaîne de caractères. Une utilisation courante consiste à référencer la définition d'une Variable-XXX renvoyée par le fournisseur d'autorisation via une option du style UserExpr "%{reqenv:XXX}". Si cette option est spécifiée, et si l'id utilisateur ne peut pas être définie via l'expression après une authentification réussie, la requête sera rejetée avec un code d'erreur 500.
top

Directive AuthnzFcgiDefineProvider

Description:Définit une application FastCGI en tant que fournisseur d'authentification et/ou autorisation
Syntaxe:AuthnzFcgiDefineProvider type provider-name backend-address
Défaut:none
Contexte:configuration globale
Statut:Extension
Module:mod_authnz_fcgi

Cette directive permet de définir une application FastCGI en tant que fournisseur pour une phase particulière d'authentification ou d'autorisation.

type
Les valeurs de ce paramètre sont authn pour l'authentification, authz pour l'autorisation, ou authnz pour un fournisseur d'autorisation générique FastCGI qui effectue les deux vérifications.
provider-name
Ce paramètre permet d'associer un nom au fournisseur ; ce nom pourra être utilisé dans des directives comme AuthBasicProvider et Require.
backend-address
Ce paramètre permet de spécifier l'adresse de l'application sous la forme fcgi://hostname:port/. Le ou les processus de l'application doivent être gérés indépendamment comme avec fcgistarter.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_core.html.fr.utf80000664000175100017510000012006114740503670022777 0ustar covenercovener mod_authz_core - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authz_core

Langues Disponibles:  en  |  fr 

Description:Autorisation basique
Statut:Base
Identificateur de Module:authz_core_module
Fichier Source:mod_authz_core.c
Compatibilité:Disponible depuis la version 2.3 d'Apache HTTPD

Sommaire

Ce module fournit des fonctionnalités d'autorisation basiques permettant d'accorder ou refuser l'accès à certaines zones du site web aux utilisateurs authentifiés. mod_authz_core donne la possibilité d'enregistrer divers fournisseurs d'autorisation. Il est en général utilisé avec un module fournisseur d'authentification comme mod_authn_file, et un module d'autorisation comme mod_authz_user. Il permet aussi l'application d'une logique élaborée au déroulement du processus d'autorisation.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Conteneurs d'autorisation

Les directives de conteneur d'autorisation <RequireAll>, <RequireAny> et <RequireNone> peuvent être combinées entre elles et avec la directive Require pour confectionner une logique d'autorisation complexe.

L'exemple ci-dessous illustre la logique d'autorisation suivante. Pour pouvoir accéder à la ressource, l'utilisateur doit être l'utilisateur superadmin, ou appartenir aux deux groupes LDAP admins et Administrateurs et soit appartenir au groupe ventes ou avoir ventes comme valeur de l'attribut LDAP dept. De plus, pour pouvoir accéder à la ressource, l'utilisateur ne doit appartenir ni au groupe temps, ni au groupe LDAP Employés temporaires.

<Directory "/www/mydocs">
    <RequireAll>
        <RequireAny>
            Require user superadmin
            <RequireAll>
            Require group admins
            Require ldap-group "cn=Administrators,o=Airius"
                <RequireAny>
                Require group sales
                Require ldap-attribute dept="sales"
                </RequireAny>
            </RequireAll>
        </RequireAny>
        <RequireNone>
            Require group temps
            Require ldap-group "cn=Temporary Employees,o=Airius"
        </RequireNone>
    </RequireAll>
</Directory>
top

Les directives Require

Le module mod_authz_core met à disposition des fournisseurs d'autorisation génériques utilisables avec la directive Require.

Require env

Le fournisseur env permet de contrôler l'accès au serveur en fonction de l'existence d'une variable d'environnement. Lorsque Require env env-variable est spécifié, la requête se voit autoriser l'accès si la variable d'environnement env-variable existe. Le serveur permet de définir facilement des variables d'environnement en fonction des caractéristiques de la requête du client via les directives fournies par le module mod_setenvif. Cette directive Require env permet donc de contrôler l'accès en fonction des valeurs des en-têtes de la requête HTTP tels que User-Agent (type de navigateur), Referer, entre autres.

SetEnvIf User-Agent "^KnockKnock/2\.0" let_me_in
<Directory "/docroot">
    Require env let_me_in
</Directory>

Avec cet exemple, les navigateurs dont la chaîne user-agent commence par KnockKnock/2.0 se verront autoriser l'accès, alors que tous les autres seront rejetés.

Lorsque le serveur cherche un chemin via une sous-requête interne (par exemple la recherche d'un DirectoryIndex), ou lorsqu'il génère un listing du contenu d'un répertoire via le module mod_autoindex, la sous-requête n'hérite pas des variables d'environnement spécifiques à la requête. En outre, à cause des phases de l'API auxquelles mod_setenvif prend part, les directives SetEnvIf ne sont pas évaluées séparément dans la sous-requête.

Require all

Le fournisseur all reproduit la fonctionnalité précédemment fournie par les directives 'Allow from all' et 'Deny from all'. Il accepte un argument dont les deux valeurs possibles sont : 'granted' ou 'denied'. Les exemples suivants autorisent ou interdisent l'accès à toutes les requêtes.

Require all granted
Require all denied

Require method

Le fournisseur method permet d'utiliser la méthode HTTP dans le processus d'autorisation. Les méthodes GET et HEAD sont ici considérées comme équivalentes. La méthode TRACE n'est pas supportée par ce fournisseur ; utilisez à la place la directive TraceEnable.

Dans l'exemple suivant, seules les méthodes GET, HEAD, POST, et OPTIONS sont autorisées :

Require method GET POST OPTIONS

Dans l'exemple suivant, les méthodes GET, HEAD, POST, et OPTIONS sont autorisées sans authentification, alors que toutes les autres méthodes nécessitent un utilisateur valide :

<RequireAny>
     Require method GET POST OPTIONS
     Require valid-user
</RequireAny>

Require expr

Le fournisseur expr permet d'accorder l'autorisation d'accès de base en fonction d'expressions arbitraires.

Require expr "%{TIME_HOUR} -ge 9 && %{TIME_HOUR} -le 17"
<RequireAll>
    Require expr "!(%{QUERY_STRING} =~ /secret/)"
    Require expr "%{REQUEST_URI} in { '/example.cgi', '/other.cgi' }" 
</RequireAll>
Require expr "!(%{QUERY_STRING} =~ /secret/) && %{REQUEST_URI} in { '/example.cgi', '/other.cgi' }"

La syntaxe de l'expression est décrite dans la documentation de ap_expr. Avant la version 2.4.16, les doubles-quotes étaient prohibées

Normalement, l'expression est évaluée avant l'authentification. Cependant, si l'expression renvoie false et se réfère à la variable %{REMOTE_USER}, le processus d'authentification sera engagé et l'expression réévaluée.

top

Création des alias du fournisseur d'autorisation

Il est possible de créer des fournisseurs d'autorisation étendus dans le fichier de configuration et de leur assigner un nom d'alias. On peut ensuite utiliser ces fournisseurs aliasés dans une directive Require de la même manière qu'on le ferait pour des fournisseurs d'autorisation de base. En plus de la possibilité de créer et d'aliaser un fournisseur étendu, le même fournisseur d'autorisation étendu peut être référencé par plusieurs localisations.

Exemple

Dans l'exemple suivant, on crée deux alias de fournisseur d'autorisation ldap différents basés sur le fournisseur d'autorisation ldap-group. Il est ainsi possible pour un seul répertoire de vérifier l'appartenance à un groupe dans plusieurs serveurs ldap :

<AuthzProviderAlias ldap-group ldap-group-alias1 "cn=my-group,o=ctx">
    AuthLDAPBindDN "cn=youruser,o=ctx"
    AuthLDAPBindPassword yourpassword
    AuthLDAPURL "ldap://ldap.host/o=ctx"
</AuthzProviderAlias>

<AuthzProviderAlias ldap-group ldap-group-alias2 "cn=my-other-group,o=dev">
    AuthLDAPBindDN "cn=yourotheruser,o=dev"
    AuthLDAPBindPassword yourotherpassword
    AuthLDAPURL "ldap://other.ldap.host/o=dev?cn"
</AuthzProviderAlias>

Alias "/secure" "/webpages/secure"
<Directory "/webpages/secure">
    Require all granted
    
    AuthBasicProvider file
    
    AuthType Basic
    AuthName LDAP_Protected_Place
    
    #implied OR operation
    Require ldap-group-alias1
    Require ldap-group-alias2
</Directory>
top

Directive AuthMerging

Description:Définit la manière dont chaque logique d'autorisation des sections de configuration se combine avec celles des sections de configuration précédentes.
Syntaxe:AuthMerging Off | And | Or
Défaut:AuthMerging Off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authz_core

Lorsque l'autorisation est activée, elle est normalement héritée par chaque section de configuration suivante, à moins qu'un jeu de directives d'autorisations différent ne soit spécifié. Il s'agit du comportement par défaut, qui correspond à la définition explicite AuthMerging Off.

Dans certaines situations cependant, il peut être souhaitable de combiner la logique d'autorisation d'une section de configuration avec celle de la section précédente lorsque les sections de configuration se combinent entre elles. Dans ce cas, deux options sont disponibles, And et Or.

Lorsqu'une section de configuration contient AuthMerging And ou AuthMerging Or, sa logique d'autorisation se combine avec celle de la section de configuration qui la précède (selon l'ordre général des sections de configuration), et qui contient aussi une logique d'autorisation, comme si les deux sections étaient concaténées respectivement dans une directive <RequireAll> ou <RequireAny>.

La définition de la directive AuthMerging ne concerne que la section de configuration dans laquelle elle apparaît. Dans l'exemple suivant, seuls les utilisateurs appartenant au groupe alpha sont autorisés à accéder à /www/docs. Les utilisateurs appartenant au groupe alpha ou au groupe beta sont autorisés à accéder à /www/docs/ab. Cependant, la définition implicite à Off de la directive AuthMerging s'applique à la section de configuration <Directory> concernant le répertoire /www/docs/ab/gamma, ce qui implique que les directives d'autorisation de cette section l'emportent sur celles des sections précédentes. Par voie de conséquence, seuls les utilisateurs appartenant au groupe gamma sont autorisés à accéder à /www/docs/ab/gamma.
<Directory "/www/docs">
    AuthType Basic
    AuthName Documents
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require group alpha
</Directory>

<Directory "/www/docs/ab">
    AuthMerging Or
    Require group beta
</Directory>

<Directory "/www/docs/ab/gamma">
    Require group gamma
</Directory>
top

Directive <AuthzProviderAlias>

Description:Regroupe des directives représentant une extension d'un fournisseur d'autorisation de base qui pourra être référencée à l'aide de l'alias spécifié
Syntaxe:<AuthzProviderAlias fournisseur-de-base Alias Paramètres-Require> ... </AuthzProviderAlias>
Contexte:configuration globale
Statut:Base
Module:mod_authz_core

Les balises <AuthzProviderAlias> et </AuthzProviderAlias> permettent de regrouper des directives d'autorisation auxquelles on pourra faire référence à l'aide de l'alias spécifié dans une directive Require.

Si Require-Parameters comporte plusieurs paramètres, la liste de ces derniers doit être entourée de guillemets. Dans le cas contraire, seul le premier paramètre de la liste sera pris en compte.

# Dans cet exemple, pour que les deux adresses IP soient prises en compte, elles
# DOIVENT être entourées de guillemets
<AuthzProviderAlias ip reject-ips "XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY">
</AuthzProviderAlias>

<Directory "/path/to/dir">
    <RequireAll>
        Require not reject-ips
        Require all granted
    </RequireAll>
</Directory>
top

Directive AuthzSendForbiddenOnFailure

Description:Envoie '403 FORBIDDEN' au lieu de '401 UNAUTHORIZED' si l'authentification réussit et si l'autorisation a été refusée.
Syntaxe:AuthzSendForbiddenOnFailure On|Off
Défaut:AuthzSendForbiddenOnFailure Off
Contexte:répertoire, .htaccess
Statut:Base
Module:mod_authz_core
Compatibilité:Disponible depuis la version 2.3.11 d'Apache HTTPD

Par défaut, si l'authentification réussit, alors que l'autorisation est refusée, Apache HTTPD renvoie un code de réponse HTTP '401 UNAUTHORIZED'. En général, les navigateurs proposent alors une nouvelle fois à l'utilisateur la boîte de dialogue de saisie du mot de passe, ce qui n'est pas toujours souhaitable. La directive AuthzSendForbiddenOnFailure permet de changer le code de réponse en '403 FORBIDDEN'.

Avertissement de sécurité

La modification de la réponse en cas de refus d'autorisation diminue la sécurité du mot de passe, car elle indique à un éventuel attaquant que le mot de passe qu'il a saisi était correct.

top

Directive Require

Description:Vérifie si un utilisateur authentifié a une autorisation d'accès accordée par un fournisseur d'autorisation.
Syntaxe:Require [not] nom-entité [nom-entité] ...
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authz_core

Cette directive permet de vérifier si un utilisateur authentifié a l'autorisation d'accès accordée pour un certain fournisseur d'autorisation et en tenant compte de certaines restrictions. mod_authz_core met à disposition les fournisseurs d'autorisation génériques suivants :

Require all granted
L'accès est autorisé sans restriction.
Require all denied
L'accès est systématiquement refusé.
Require env env-var [env-var] ...
L'accès n'est autorisé que si l'une au moins des variables d'environnement spécifiées est définie.
Require method http-method [http-method] ...
L'accès n'est autorisé que pour les méthodes HTTP spécifiées.
Require expr expression
L'accès est autorisé si expression est évalué à vrai.

Voici quelques exemples de syntaxes autorisées par mod_authz_user, mod_authz_host et mod_authz_groupfile :

Require user identifiant utilisateur [identifiant utilisateur] ...
Seuls les utilisateurs spécifiés auront accès à la ressource.
Require group nom groupe [nom groupe] ...
Seuls les utilisateurs appartenant aux groupes spécifiés auront accès à la ressource.
Require valid-user
Tous les utilisateurs valides auront accès à la ressource.
Require ip 10 172.20 192.168.2
Les clients dont les adresses IP font partie des tranches spécifiées auront accès à la ressource.
Require forward-dns dynamic.example.org
Un client dont l'adresse IP est résolue à partir du nom dynamic.example.org aura l'autorisation d'accès.

D'autres modules d'autorisation comme mod_authnz_ldap, mod_authz_dbm, mod_authz_dbd, mod_authz_owner et mod_ssl implémentent des options de la directive Require.

Pour qu'une configuration d'authentification et d'autorisation fonctionne correctement, la directive Require doit être accompagnée dans la plupart des cas de directives AuthName, AuthType et AuthBasicProvider ou AuthDigestProvider, ainsi que de directives telles que AuthUserFile et AuthGroupFile (pour la définition des utilisateurs et des groupes). Exemple :

AuthType Basic
AuthName "Restricted Resource"
AuthBasicProvider file
AuthUserFile "/web/users"
AuthGroupFile "/web/groups"
Require group admin

Les contrôles d'accès appliqués de cette manière sont effectifs pour toutes les méthodes. C'est d'ailleurs ce que l'on souhaite en général. Si vous voulez n'appliquer les contrôles d'accès qu'à certaines méthodes, tout en laissant les autres méthodes sans protection, placez la directive Require dans une section <Limit>.

Le résultat de la directive Require peut être inversé en utilisant l'option not. Comme dans le cas de l'autre directive d'autorisation inversée <RequireNone>, si la directive Require est inversée, elle ne peut qu'échouer ou produire un résultat neutre ; elle ne peut donc alors pas autoriser une requête de manière indépendante.

Dans l'exemple suivant, tous les utilisateurs appartenant aux groupes alpha et beta ont l'autorisation d'accès, à l'exception de ceux appartenant au groupe reject.

<Directory "/www/docs">
    <RequireAll>
        Require group alpha beta
        Require not group reject
    </RequireAll>
</Directory>

Lorsque plusieurs directives Require sont placées dans une même section de configuration, et ne se trouvent pas dans une autre directive d'autorisation comme <RequireAll>, elles sont implicitement contenues dans une directive <RequireAny>. Ainsi, la première directive Require qui autorise l'accès à un utilisateur autorise l'accès pour l'ensemble de la requête, et les directives Require suivantes sont ignorées.

Avertissement à propos de la sécurité

Prettez une attention particulière aux directives d'autorisation définies au sein des sections Location qui se chevauchent avec des contenus servis depuis le système de fichiers. Par défaut, les configurations définies dans ces sections l'emportent sur les configurations d'autorisations définies au sein des sections Directory et Files sections.

La directive AuthMerging permet de contrôler la manière selon laquelle les configurations d'autorisations sont fusionnées au sein des sections précitées.

Voir aussi

top

Directive <RequireAll>

Description:Regroupe plusieurs directives d'autorisation dont aucune ne doit échouer et dont au moins une doit retourner un résultat positif pour que la directive globale retourne elle-même un résultat positif.
Syntaxe:<RequireAll> ... </RequireAll>
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authz_core

Les balises <RequireAll> et </RequireAll> permettent de regrouper des directives d'autorisation dont aucune ne doit échouer, et dont au moins une doit retourner un résultat positif pour que la directive <RequireAll> retourne elle-même un résultat positif.

Si aucune des directives contenues dans la directive <RequireAll> n'échoue, et si au moins une retourne un résultat positif, alors la directive <RequireAll> retourne elle-même un résultat positif. Si aucune ne retourne un résultat positif, et si aucune n'échoue, la directive globale retourne un résultat neutre. Dans tous les autres cas, elle échoue.

Voir aussi

top

Directive <RequireAny>

Description:Regroupe des directives d'autorisation dont au moins une doit retourner un résultat positif pour que la directive globale retourne elle-même un résultat positif.
Syntaxe:<RequireAny> ... </RequireAny>
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authz_core

Les balises <RequireAny> et </RequireAny> permettent de regrouper des directives d'autorisation dont au moins une doit retourner un résultat positif pour que la directive <RequireAny> retourne elle-même un résultat positif.

Si une ou plusieurs directives contenues dans la directive <RequireAny> retournent un résultat positif, alors la directive <RequireAny> retourne elle-même un résultat positif. Si aucune ne retourne un résultat positif et aucune n'échoue, la directive globale retourne un résultat neutre. Dans tous les autres cas, elle échoue.

Comme les directives d'autorisation inversées sont incapables de retourner un résultat positif, elles ne peuvent pas impacter de manière significative le résultat d'une directive <RequireAny> (elles pourraient tout au plus faire échouer la directive dans le cas où elles échoueraient elles-mêmes, et où toutes les autres directives retourneraient un résultat neutre). C'est pourquoi il n'est pas permis d'utiliser les directives d'autorisation inversées dans une directive <RequireAny>.

Voir aussi

top

Directive <RequireNone>

Description:Regroupe des directives d'autorisation dont aucune ne doit retourner un résultat positif pour que la directive globale n'échoue pas.
Syntaxe:<RequireNone> ... </RequireNone>
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authz_core

Les balises <RequireNone> et </RequireNone> permettent de regrouper des directives d'autorisation dont aucune ne doit retourner un résultat positif pour que la directive <RequireNone> n'échoue pas.

Si une ou plusieurs directives contenues dans la directive <RequireNone> retournent un résultat positif, la directive <RequireNone> échouera. Dans tous les autres cas, cette dernière retournera un résultat neutre. Ainsi, comme pour la directive d'autorisation inversée Require not, elle ne peut jamais autoriser une requête de manière indépendante car elle ne pourra jamais retourner un résultat positif. Par contre, on peut l'utiliser pour restreindre l'ensemble des utilisateurs autorisés à accéder à une ressource.

Comme les directives d'autorisation inversées sont incapables de retourner un résultat positif, elles ne peuvent pas impacter de manière significative le résultat d'une directive <RequireNone>. C'est pourquoi il n'est pas permis d'utiliser les directives d'autorisation inversées dans une directive <RequireNone>.

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_groupfile.html.fr.utf80000664000175100017510000002566614740503670024062 0ustar covenercovener mod_authz_groupfile - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authz_groupfile

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Autorisation basée sur les groupes à l'aide de fichiers textes
Statut:Base
Identificateur de Module:authz_groupfile_module
Fichier Source:mod_authz_groupfile.c
Compatibilité:Disponible depuis les versions 2.1 et supérieures d'Apache

Sommaire

Ce module permet d'autoriser ou d'interdire l'accès à certaines zones du site web aux utilisateurs authentifiés en fonction de leur appartenance à un groupe spécifié. Le module mod_authz_dbm fournit une fonctionnalité similaire.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Les directives Require

Les directives Require d'Apache permettent, au cours de la phase d'autorisation, de s'assurer qu'un utilisateur est bien autorisé à accéder à une ressource. mod_authz_groupfile ajoute les types d'autorisation group et file-group.

A partir de la version 2.4.8, les directives require groupfile supportent les expressions.

Require group

Cette directive permet de spécifier à quel groupe un utilisateur doit appartenir pour obtenir l'autorisation d'accès.

Require group admin

Require file-group

Lorsque cette directive est définie, Les permissions système du fichier auquel on veut accéder sont vérifiées. L'utilisateur doit être un membre d'un groupe de même nom que le groupe qui possède le fichier. Voir mod_authz_owner pour plus de détails.

Require file-group
top

Directive AuthGroupFile

Description:Définit le nom d'un fichier texte contenant la liste des groupes d'utilisateurs permettant de définir les autorisations des utilisateurs
Syntaxe:AuthGroupFile chemin-fichier
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authz_groupfile

La directive AuthGroupFile permet de définir le nom d'un fichier texte contenant la liste des groupes d'utilisateurs. L'appartenance d'un utilisateur à tel ou tel groupe pourra dès lors être utilisée pour définir les permissions d'accès de l'utilisateur. chemin-fichier est le chemin du fichier de groupes. S'il n'est pas absolu, ce chemin est considéré comme relatif au répertoire défini par la directive ServerRoot.

Chaque ligne du fichier de groupes contient un nom de groupe suivi du caractère ':' et des noms des utilisateurs membres du groupe séparés par des espaces.

Exemple :

mon-groupe : bob joe anne

Notez que la recherche dans de grands fichiers textes est très inefficace ; la directive AuthDBMGroupFile fournit de bien meilleures performances.

Sécurité

Le fichier AuthGroupFile ne doit pas être stocké dans l'arborescence des documents du site web ; ne le placez surtout pas dans le répertoire qu'il protège, faute de quoi les clients pourraient le télécharger.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_user.html.fr.utf80000664000175100017510000002057114740503670023032 0ustar covenercovener mod_authz_user - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authz_user

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Autorisation basée sur l'utilisateur
Statut:Base
Identificateur de Module:authz_user_module
Fichier Source:mod_authz_user.c
Compatibilité:Disponible depuis les versions 2.1 et supérieures d'Apache

Sommaire

Ce module permet d'accorder ou de refuser l'accès à certaines zones du site web aux utilisateurs authentifiés. mod_authz_user accorde l'accès si l'utilisateur authentifié fait partie de la liste spécifiée par une directive Require user. On peut aussi utiliser la directive Require valid-user pour accorder l'accès à tous les utilisateurs qui ont été authentifiés avec succès.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

The Require Directives

Les directives Require d'Apache permettent, au cours de la phase d'autorisation, de s'assurer qu'un utilisateur est bien autorisé à accéder à une ressource. mod_authz_user ajoute les types d'autorisation user et valid-user.

A partir de la version 2.4.8, les directives require user supportent les expressions.

Require user

Cette directive permet de spécifier une liste d'utilisateurs autorisés à accéder à la ressource.

Require user john paul george ringo

Require valid-user

Lorsque cette directive est définie, tout utilisateur qui s'est authentifié avec succès aura l'autorisation d'accès à la ressource.

Require valid-user

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_buffer.html.fr.utf80000664000175100017510000002310314740503670022104 0ustar covenercovener mod_buffer - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_buffer

Langues Disponibles:  en  |  fr 

Description:Support de la mise en tampon des requêtes
Statut:Extension
Identificateur de Module:buffer_module
Fichier Source:mod_buffer.c
Compatibilité:Disponible depuis les versions 2.3 et supérieures d'Apache

Sommaire

Ce module fournit la possibilité de mettre en tampon les piles des filtres en entrée et sortie.

Dans certaines situations, les générateurs de contenu créent des contenus composés de petits tronçons. Afin de permettre la réutilisation de la mémoire, les éléments de mémoire attribués aux tronçons ont toujours une taille de 8k, quelle que soit la taille du tronçon lui-même. Lorsqu'une requête génère de nombreux petits tronçons, une grande quantité de mémoire peut être mobilisée par le traitement de la requête, et une grande quantité de données transmises sans nécessité. Pour y remédier, l'utilisation d'un tampon rassemble la réponse en un nombre de tronçons le plus petit possible.

Lorsque httpd est utilisé comme frontal d'un générateur de contenu consommant beaucoup de ressources, la mise en tampon de la réponse peut permettre à ce dernier d'effectuer le traitement et de libérer les ressources plus ou moins rapidement, en fonction de la manière dont il a été conçu.

Le filtre de mise en tampon peut être ajouté aux piles des filtres en entrée ou en sortie, selon les besoins, à l'aide des directives SetInputFilter, SetOutputFilter, AddOutputFilter ou AddOutputFilterByType.

Utilisation d'un tampon avec mod_include

AddOutputFilterByType INCLUDES;BUFFER text/html
Les filtres de mise en tampon lisent la requête/réponse en RAM, puis la reconditionnent sous la forme d'un nombre d'éléments mémoire le plus petit possible, au prix d'une consommation de temps CPU. Lorsque la requête/réponse est déjà conditionnée de manière satisfaisante, sa mise en tampon pourrait s'avérer encore plus lente qu'en l'absence d'utilisation de tampon. C'est pourquoi ces filtres doivent être utilisés avec précautions, et seulement si nécessaire.
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive BufferSize

Description:Taille maximale en octets du filtre par tampon
Syntaxe:BufferSize entier
Défaut:BufferSize 131072
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_buffer

La directive BufferSize permet de spécifier la quantité de données en octets qui sera mise en tampon avant d'être lue depuis ou écrite vers chaque requête. La valeur par défaut est 128 ko.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache_socache.html.fr.utf80000664000175100017510000004607514740503670023400 0ustar covenercovener mod_cache_socache - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_cache_socache

Langues Disponibles:  en  |  fr 

Description:Module de stockage à base de cache d'objets partagés (socache) pour le filtre de mise en cache HTTP.
Statut:Extension
Identificateur de Module:cache_socache_module
Fichier Source:mod_cache_socache.c

Sommaire

Le module mod_cache_socache implémente un gestionnaire de stockage à base de cache d'objets partagés (socache) pour le module mod_cache.

Les en-têtes et corps des réponses mises en cache sont rassemblés et stockés sous une même clé dans le cache d'objets partagés. Il est possible de choisir entre plusieurs implémentations de caches d'objets partagés.

Des réponses avec différents contenus négociés peuvent être stockées simultanément ; cependant, la mise en cache de contenus partiels n'est pas encore supportée par ce module.

# Activation de la mise en cache
CacheSocache shmcb
CacheSocacheMaxSize 102400
<Location "/foo">
    CacheEnable socache
</Location>

# Possibilité de se rabattre sur le cache disque
CacheSocache shmcb
CacheSocacheMaxSize 102400
<Location "/foo">
    CacheEnable socache
    CacheEnable disk
</Location>

Note :

Le module mod_cache_socache requiert les services du module mod_cache qui doit donc avoir été préalablement chargé.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive CacheSocache

Description:Implémentation du cache d'objets partagés à utiliser
Syntaxe:CacheSocache type[:args]
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache_socache
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

La directive CacheSocache définit l'implémentation du cache d'objets partagés à utiliser, suivie d'arguments optionnels. Il est possible de choisir entre plusieurs implémentations de caches d'objets partagés.

CacheSocache shmcb
top

Directive CacheSocacheMaxSize

Description:La taille maximale d'une entrée pouvant être placée dans le cache
Syntaxe:CacheSocacheMaxSize octets
Défaut:CacheSocacheMaxSize 102400
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_socache
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

La directive CacheSocacheMaxSize définit la taille maximale, en octets, de la somme des en-têtes et du corps d'un document pouvant être stocké dans le cache. Bien entendu, plus la taille des en-têtes sera grande, plus la taille maximale du corps du document s'en trouvera réduite.

Le module mod_cache_socache ne tentera de mettre en cache que des réponses qui possèdent une taille de contenu explicite, ou dont la taille est suffisamment petite pour qu'elles soient écrites en une seule passe. Ceci permet au module mod_cache_disk de mettre en cache des réponses dont la taille est trop importante pour pouvoir être mises en cache par mod_cache_socache.

CacheSocacheMaxSize 102400
top

Directive CacheSocacheMaxTime

Description:La durée maximale de stockage d'un document dans le cache avant péremption
Syntaxe:CacheSocacheMaxTime secondes
Défaut:CacheSocacheMaxTime 86400
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_socache
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

La directive CacheSocacheMaxTime définit la durée de stockage maximale en secondes d'un document dans le cache avant péremption. Cette définition l'emporte sur la durée de fraîcheur définie pour le document par le protocole HTTP.

CacheSocacheMaxTime 86400
top

Directive CacheSocacheMinTime

Description:La durée minimale de stockage d'un document dans le cache
Syntaxe:CacheSocacheMinTime seconds
Défaut:CacheSocacheMinTime 600
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_socache
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

La directive CacheSocacheMinTime définit le nombre de secondes au delà de la durée de fraîcheur de la réponse pendant lesquelles cette dernière devra être stockée dans le cache d'objets partagés. En effet, si une réponse n'est stockée que pour une durée égale à sa durée de fraîcheur, elle n'a pas besoin d'être rafraîchie.

CacheSocacheMinTime 600
top

Directive CacheSocacheReadSize

Description:La quantité minimale de données du document à lire et mettre en cache avant envoi au client
Syntaxe:CacheSocacheReadSize octets
Défaut:CacheSocacheReadSize 0
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_socache
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

La directive CacheSocacheReadSize définit la quantité minimale de données, en octets, à lire depuis l'arrière-plan avant envoi au client. Avec la valeur par défaut 0, les données sont transmises au client dès leur arrivée et quelle que soit leur taille. Si la valeur définie est non nulle, le cache disque va mettre en tampon au moins la quantité de données correspondante avant envoi au client. Ceci peut améliorer les performances en cas de mise en cache de contenu en provenance d'un mandataire inverse lent.

Cette directive n'a d'effet qu'au moment où les données sont stockées dans le cache, et non lorsqu'elles sont servies depuis le cache.

CacheSocacheReadSize 102400
top

Directive CacheSocacheReadTime

Description:La durée minimale de lecture avant l'envoi des données
Syntaxe:CacheSocacheReadTime millisecondes
Défaut:CacheSocacheReadTime 0
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_socache
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

La directive CacheSocacheReadTime définit le temps minimal qui doit s'écouler avant de tenter l'envoi des données au client. Cette durée sera mise à profit pour lire et mettre en tampon les données avant leur envoi au client. Ceci peut améliorer les performances en cas de mise en cache de contenu en provenance d'un mandataire inverse.

La valeur par défaut 0 désactive cette directive.

Cette directive n'a d'effet qu'au moment où les données sont stockées dans le cache, et non lorsqu'elles sont servies depuis le cache. Il est recommandé d'utiliser cette directive en concomitance avec la directive CacheSocacheReadSize afin de s'assurer que le serveur ne mette pas les données en tampon de manière excessive dans le cas où les données arriveraient plus vite que prévu.

CacheSocacheReadTime 1000

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_owner.html.fr.utf80000664000175100017510000002765514740503670023220 0ustar covenercovener mod_authz_owner - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authz_owner

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Autorisation basée sur l'appartenance des fichiers
Statut:Extension
Identificateur de Module:authz_owner_module
Fichier Source:mod_authz_owner.c
Compatibilité:Disponible depuis les versions 2.1 et supérieures d'Apache

Sommaire

Ce module permet de contrôler l'accès aux fichiers en comparant l'identifiant utilisateur ayant servi à l'authentification HTTP (l'identifiant utilisateur web) avec le propriétaire ou le groupe du fichier demandé du point de vue du système de fichiers. Le nom d'utilisateur et le mot de passe doivent déjà avoir été vérifiés par un module d'authentification comme mod_auth_basic ou mod_auth_digest. mod_authz_owner reconnaît deux arguments pour la directive Require : file-owner et file-group :

file-owner
Le nom d'utilisateur web utilisé pour l'authentification doit correspondre au nom système du propriétaire du fichier demandé. En d'autres termes, si le système indique jones comme propriétaire du fichier demandé, le nom d'utilisateur fourni pour l'authentification HTTP doit aussi être jones.
file-group
Le nom du groupe système du fichier demandé doit être présent dans une base de données de groupes fournie, par exemple, par mod_authz_groupfile ou mod_authz_dbm, et le nom d'utilisateur web fourni pour l'authentification doit être un membre de ce groupe. Par exemple, si le système indique que le groupe (système) du fichier demandé est accounts, le groupe accounts doit apparaître dans la base de données des groupes, et le nom d'utilisateur web utilisé pour l'authentification doit être un membre de ce groupe.

Note

Si le module mod_authz_owner est utilisé pour vérifier l'autorisation d'accès à une ressource qui n'est pas vraiment présente dans le système de fichiers (en d'autres termes une ressource virtuelle), il refusera l'accès.

En particulier, il n'accordera jamais l'accès à une ressource du type "Vues multiples" (MultiViews) d'un contenu négocié.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Exemples de configuration

Require file-owner

Considérons un serveur Web Apache fonctionnant sous un système multi-utilisateurs, où les fichiers de chaque utilisateur sont stockés dans ~/public_html/private. En supposant qu'il n'existe qu'une seule base de données contenant les noms d'utilisateurs web, et que ces noms d'utilisateurs correspondent aux noms d'utilisateurs système qui sont les propriétaires effectifs des fichiers, la configuration de l'exemple suivant n'accordera l'autorisation d'accès aux fichiers qu'à leur propriétaire. L'utilisateur jones ne sera pas autorisé à accéder aux fichiers situés dans /home/smith/public_html/private, à moins que leur propriétaire ne soit jones au lieu de smith.

<Directory "/home/*/public_html/private">
    AuthType Basic
    AuthName MyPrivateFiles
    AuthBasicProvider dbm
    AuthDBMUserFile "/usr/local/apache2/etc/.htdbm-all"
    Require file-owner
</Directory>

Require file-group

Considérons un système similaire à celui décrit ci-dessus, mais où certains utilisateurs partagent leurs fichiers de projets dans ~/public_html/project-foo. Le groupe système des fichiers est foo, et il n'existe qu'une seule base de données AuthDBMGroupFile qui contient tous les noms d'utilisateurs web et leurs groupes d'appartenance. Ces noms d'utilisateurs web doivent alors appartenir au moins au groupe foo. En d'autres termes, si jones et smith sont tous deux membres du groupe foo, ils seront autorisés à accéder aux répertoires project-foo de chacun d'entre eux.

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

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_brotli.html.fr.utf80000664000175100017510000005477714740503670022153 0ustar covenercovener mod_brotli - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_brotli

Langues Disponibles:  en  |  fr 

Description:Compression du contenu via Brotli avant sa livraison au client
Statut:Extension
Identificateur de Module:brotli_module
Fichier Source:mod_brotli.c
Compatibilité:Disponible à partir de la version 2.4.26 du serveur HTTP Apache

Sommaire

Le module mod_brotli fournit le filtre en sortie BROTLI_COMPRESS qui permet de compresser un contenu avant sa livraison au client en utilisant la bibliothèque brotli. Ce filtre est implémenté en utilisant la bibliothèque Brotli que l'on peut trouver à https://github.com/google/brotli.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples de configurations

Compression et TLS

Certaines applications web sont vulnérables à une attaque de type vol d'informations lorsqu'une connexion TLS transmet des données compressées. Pour plus d'informations, étudiez en détail la famille d'attaques "BREACH".

Voici une configuration simple qui compresse des types de contenus courants au format texte :

Compression de certains types seulement

AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript
top

Activation de la compression

Compression et TLS

Certaines applications web sont vulnérables à une attaque de type vol d'informations lorsqu'une connexion TLS transmet des données compressées. Pour plus d'informations, étudiez en détail la famille d'attaques "BREACH".

Compression en sortie

La compression est implémentée par le filtre BROTLI_COMPRESS. La directive suivante active la compression pour les documents correspondant au conteneur dans lequel elle est placée :

SetOutputFilter BROTLI_COMPRESS
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli

Si vous voulez restreindre la compression à certains types MIME particuliers, vous pouvez utiliser la directive AddOutputFilterByType. Dans l'exemple suivant, l'activation de la compression est restreinte aux fichiers html de la documentation d'Apache :

<Directory "/your-server-root/manual">
    AddOutputFilterByType BROTLI_COMPRESS text/html
</Directory>

Note

Le filtre BROTLI_COMPRESS est toujours inséré après les filtres RESOURCE comme PHP ou SSI. Il n'affecte jamais les sous-requêtes internes.

Note

Définie via SetEnv, la variable d'environnement no-brotli permet de désactiver la compression brotli pour une requête particulière, et ceci même si elle est supportée par le client.
top

Interaction avec les serveurs mandataires

Le module mod_brotli envoie un en-tête de réponse HTTP Vary:Accept-Encoding pour indiquer aux mandataires qu'une réponse mise en cache ne doit être envoyée qu'aux clients qui envoient l'en-tête de requête Accept-Encoding approprié. Ceci permet d'éviter d'envoyer du contenu compressé à un client qui ne sera pas en mesure de le décompresser.

Si vous utilisez des exclusions spéciales dépendant, par exemple, de l'en-tête User-Agent, vous devez faire un ajout manuel à l'en-tête Vary afin d'informer les mandataires des restrictions supplémentaires. Par exemple, dans une configuration typique où l'addition du filtre BROTLI_COMPRESS dépend de l'en-tête User-Agent, vous devez ajouter :

Header append Vary User-Agent

Si votre décision d'utiliser la compression ou non dépend d'autres informations que le contenu d'en-têtes de requêtes (par exemple la version HTTP), vous devez affecter la valeur * à l'en-tête Vary. Ceci permet d'éviter que des mandataires qui le supportent n'effectuent une mise en cache intégrale.

Exemple

Header set Vary *
top

Servir un contenu pré-compressé

comme mod_brotli compresse systématiquement un contenu pour chaque requête le concernant, il est possible d'obtenir un gain en performance en pré-compressant le contenu et en disant à mod_brotli de le servir sans le recompresser. Pour cela, vous pouvez utiliser une configuration du style :

<IfModule mod_headers.c>
    # Sert des fichiers CSS compressés par brotli, s'ils existent
    # et si le client supporte brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.css"              "$1\.css\.br" [QSA]

    # Sert des fichiers JS compressés par brotli, s'ils existent
    # et si le client supporte brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.js"               "$1\.js\.br" [QSA]


    # Sert des types de contenu corrects, et évite la double compression.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-brotli:1]
    RewriteRule "\.js\.gz$"  "-" [T=text/javascript,E=no-brotli:1]


    <FilesMatch "(\.js\.br|\.css\.br)$">
      # Sert un type d'encodage correct.
      Header append Content-Encoding br

      # Force les mandataires à mettre en cache séparément les fichiers css/js
      # compressés ou non par brotli.
      Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>
top

Directive BrotliAlterETag

Description:Comment l'en-tête de réponse ETag doit être modifié au cours de la compression
Syntaxe:BrotliAlterETag AddSuffix|NoChange|Remove
Défaut:BrotliAlterETag AddSuffix
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_brotli

La directive BrotliAlterETag permet d'indiquer comment l'en-tête ETag doit être modifié lorsqu'une réponse est compressée.

AddSuffix

Ajoute la méthode de compression à la fin de l'en-tête ETag, ce qui implique que les représentations compressées et non compressées possèderont des en-têtes ETag uniques. C'est le comportement par défaut depuis la version 2.4.0 avec un autre module de compression dynamique, mod-deflate. Ce paramètre permet d'éviter l'envoi de messages "HTTP Not Modified" (304) en réponse aux requêtes conditionnelles pour des contenus compressés.

NoChange

Ne modifie pas l'en-tête ETag d'une réponse compressée. C'était le comportement par défaut avant la version 2.4.0 avec un autre module de compression dynamique, mod-deflate. Ce paramètre ne respecte pas la propriété HTTP/1.1 selon laquelle toutes les représentations d'une même ressource ont des en-têtes ETag uniques.

Remove

Supprime l'en-tête ETag des réponses compressées, ce qui rend impossibles certaines requêtes conditionnelles, mais évite les inconvénients des options précédentes.

top

Directive BrotliCompressionMaxInputBlock

Description:Taille maximale du bloc de données en entrée
Syntaxe:BrotliCompressionMaxInputBlock value
Défaut:(automatic)
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_brotli

La directive BrotliCompressionMaxInputBlock permet de spécifier la taille maximale du bloc de données en entrée entre 16 et 24, sachant que plus cette taille sera grande, plus grande sera la quantité de mémoire consommée.

top

Directive BrotliCompressionQuality

Description:Qualité de la compression
Syntaxe:BrotliCompressionQuality value
Défaut:BrotliCompressionQuality 5
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_brotli

La directive BrotliCompressionQuality permet de spécifier la qualité de la compression (une valeur entre 0 et 11). Les valeurs les plus hautes correspondent à une compression de meilleure qualité mais plus lente.

top

Directive BrotliCompressionWindow

Description:Taille de la fenêtre de compression glissante brotli
Syntaxe:BrotliCompressionWindow value
Défaut:BrotliCompressionWindow 18
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_brotli

La directive BrotliCompressionWindow permet de spécifier la taille de la fenêtre de compression glissante brotli (une valeur comprise entre 10 et 24). Une taille de fenêtre plus grande peut améliorer la qualité de la compression mais consomme d'avantage de mémoire.

top

Directive BrotliFilterNote

Description:Enregistre le taux de compression dans une note à des fins de journalisation
Syntaxe:BrotliFilterNote [type] notename
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_brotli

La directive BrotliFilterNote permet d'indiquer qu'une note à propos du taux de compression doit être attachée à la requête. L'argument notename permet de spécifier le nom de la note. Vous pouvez utiliser cette note à des fins de statistiques en ajoutant l'information correspondante à votre access log.

Exemple

BrotliFilterNote ratio

LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' brotli
CustomLog "logs/brotli_log" brotli

Si vous souhaitez que l'information enregistrée dans vos journaux soit plus pertinente, vous pouvez renseigner l'argument optionnel type afin de spécifier le type de données à enregistrer dans la note à journaliser. L'argument type accepte les valeurs suivantes :

Input
Enregistre dans la note le nombre d'octets contenus dans le flux d'entrée du filtre.
Output
Enregistre dans la note le nombre d'octets contenus dans le flux de sortie du filtre.
Ratio
Enregistre dans la note le taux de compression (output/input * 100). Il s'agit de l'option par défaut si l'argument type est omis.

Vous pouvez alors configurer vos journaux de la manière suivante :

Journalisation spécifique

BrotliFilterNote Input instream
BrotliFilterNote Output outstream
BrotliFilterNote Ratio ratio

LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' brotli
CustomLog "logs/brotli_log" brotli

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache_disk.html.fr.utf80000664000175100017510000005241314740503670022716 0ustar covenercovener mod_cache_disk - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_cache_disk

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Module de stockage sur disque pour le filtre de mise en cache HTTP.
Statut:Extension
Identificateur de Module:cache_disk_module
Fichier Source:mod_cache_disk.c

Sommaire

mod_cache_disk implémente un gestionnaire de stockage sur disque pour le module mod_cache.

Les en-têtes et corps des réponses mises en cache sont stockés séparément sur le disque, dans une structure de répertoires basée sur le condensé md5 de l'URL mise en cache.

Plusieurs réponses au contenu négocié peuvent être stockées en même temps, mais la mise en cache de contenus partiels n'est pas supportée actuellement par ce module.

Les mises à jour atomiques du cache pour les fichiers d'en-tête et de corps peuvent être effectuées sans verrouillage en enregistrant les numéros d'inode et de périphérique du fichier de corps dans le fichier d'en-tête. Ceci implique que les entrées du cache déplacées manuellement dans le cache seront ignorées.

L'utilitaire htcacheclean permet de lister et de supprimer les URLs du cache, ou de maintenir le cache en deçà de certaines limites de taille et/ou de nombre d'inodes. L'utilitaire peut être exécuté à la demande, ou automatiquement pour assurer un contrôle continu des tailles des répertoires.

Note :

mod_cache doit être chargé avant mod_cache_disk pour que ce dernier puisse fonctionner.

Note :

Lorsque la plate-forme la supporte, et si elle est activée via la directive EnableSendfile, mod_cache_disk utilise la fonctionnalité sendfile pour servir les fichiers à partir du cache. Cependant, mod_cache_disk ignore la configuration de la directive EnableSendfile dans un contexte de répertoire ou de fichier .htaccess, car le module ne dispose pas des définitions correspondantes lorsque la requête est servie depuis le cache.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive CacheDirLength

Description:Le nombre de caractères des noms des sous-répertoires
Syntaxe:CacheDirLength longueur
Défaut:CacheDirLength 2
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache_disk

la directive CacheDirLength permet de définir le nombre de caractères que comportera chaque nom de sous-répertoire de la hiérarchie du cache. On peut l'utiliser en conjonction avec CacheDirLevels pour déterminer une structure approximative de la hiérarchie de cache.

Une valeur haute pour CacheDirLength combinée avec une valeur basse pour CacheDirLevels générera une hiérarchie relativement peu profonde, avec un grand nombre de sous-répertoires à chaque niveau.

La valeur du produit CacheDirLevels * CacheDirLength ne doit pas dépasser 20.

top

Directive CacheDirLevels

Description:Le nombre de niveaux de sous-répertoires que comportera le cache.
Syntaxe:CacheDirLevels niveaux
Défaut:CacheDirLevels 2
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache_disk

La directive CacheDirLevels permet de définir le nombre de niveaux de sous-répertoires que comportera le cache. Les données du cache seront stokées au niveau correspondant par rapport au répertoire CacheRoot.

Une valeur haute pour CacheDirLevels combinée avec une valeur basse pour CacheDirLength générera une arborescence très développée, avec un petit nombre de sous-répertoires à chaque niveau.

La valeur du produit CacheDirLevels * CacheDirLength ne doit pas dépasser 20.

top

Directive CacheMaxFileSize

Description:>La taille maximale (en octets) d'un document pour pouvoir être stocké dans le cache
Syntaxe:CacheMaxFileSize octets
Défaut:CacheMaxFileSize 1000000
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_disk

La directive CacheMaxFileSize permet de définir la taille maximale d'un document, en octets, pour que celui-ci puisse faire l'objet d'un stockage dans le cache.

CacheMaxFileSize 64000
top

Directive CacheMinFileSize

Description:La taille minimale (en octets) d'un document pour pouvoir être stocké dans le cache
Syntaxe:CacheMinFileSize octets
Défaut:CacheMinFileSize 1
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_disk

La directive CacheMinFileSize permet de définir la taille minimale d'un document, en octets, pour que celui-ci puisse faire l'objet d'un stockage dans le cache.

CacheMinFileSize 64
top

Directive CacheReadSize

Description:La quantité minimale (en octets) de données à lire et à mettre en cache avant de les envoyer au client
Syntaxe:CacheReadSize octets
Défaut:CacheReadSize 0
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_disk

La directive CacheReadSize permet de définir la quantité minimale de données, en octets, à lire depuis le serveur d'arrière-plan avant de les envoyer au client. Avec la valeur par défaut zéro, toute donnée de toutes tailles est envoyée au client dès qu'elle est disponible. Avec une valeur non nulle, le cache disque met en tampon au moins la quantité de données correspondante avant d'envoyer la réponse au client. Les performances peuvent s'en trouver améliorées lorsqu'on met en cache du contenu en provenance d'un mandataire inverse.

Cette directive ne prend effet que lorsque les données sont enregistrées dans le cache, et non lorsque les données sont servies à partir du cache.

CacheReadSize 102400
top

Directive CacheReadTime

Description:Le temps minimum (en millisecondes) qui doit s'écouler avant d'envoyer les données au client
Syntaxe:CacheReadTime millisecondes
Défaut:CacheReadTime 0
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache_disk

La directive CacheReadTime permet de définir le temps minimum qui doit s'écouler avant d'essayer d'envoyer des données au client. Pendant ce temps, les données sont mises en tampon avant de pouvoir être envoyées au client. Les performances peuvent s'en trouver améliorées lorsqu'on met en cache du contenu en provenance d'un mandataire inverse.

La valeur par défaut zéro désactive cette option.

Cette directive ne prend effet que lorsque les données sont enregistrées dans le cache, et non lorsque les données sont servies à partir du cache. Il est recommandé d'harmoniser l'utilisation de cette directive avec celle de la directive CacheReadSize, afin de s'assurer que le serveur n'effectue pas une mise en tampon excessive au cas où les données arriveraient plus vite que prévu.

CacheReadTime 1000
top

Directive CacheRoot

Description:La racine du répertoire dans lequel les fichiers du cache seront stockés
Syntaxe:CacheRoot répertoire
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache_disk

La directive CacheRoot permet de définir le nom du répertoire sur disque qui contiendra les fichiers du cache. Si le module mod_cache_disk a été chargé ou compilé dans le serveur Apache, cette directive doit être définie. L'absence de définition de la directive CacheRoot provoquera une erreur de traitement du fichier de configuration. Les directives CacheDirLevels et CacheDirLength permettent de définir la structure des sous-répertoires du répertoire racine spécifié.

CacheRoot c:/cacheroot

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgid.html.fr.utf80000664000175100017510000003023514740503670021545 0ustar covenercovener mod_cgid - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_cgid

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Exécution des scripts CGI par l'intermédiaire d'un démon CGI externe
Statut:Base
Identificateur de Module:cgid_module
Fichier Source:mod_cgid.c
Compatibilité:Uniquement compatible avec les MPMs Unix threadés

Sommaire

Exceptées les optimisations et la directive additionnelle ScriptSock décrite ci-dessous, mod_cgid a un comportement similaire à celui de mod_cgi. Voir le résumé de mod_cgi pour plus de détails à propos d'Apache et CGI.

Sur certains systèmes d'exploitation de type unix, le lancement (forking) d'un processus depuis un serveur multi-threadé est une opération très lourde car le nouveau processus va répliquer tous les threads du processus parent. Pour éviter cette dépense de ressouces pour chaque invocation d'un programme CGI, mod_cgid crée un démon externe qui est responsable du branchement de processus enfants destinés au lancement de scripts CGI. Le serveur principal communique avec ce démon par l'intermédiaire d'une socket de domaine unix.

Si un MPM multi-threadé a été sélectionné lors du processus de compilation, c'est ce module qui est utilisé par défaut à la place de mod_cgi. Du point de vue de l'utilisateur, ce module est identique à mod_cgi quant à sa configuration et son utilisation. La seule différence est la directive additionnelle ScriptSock qui permet de définir le nom du socket à utiliser pour la communication avec le démon CGI.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive CGIDScriptTimeout

Description:Durée maximale d'attente de la prochaine sortie du programme CGI
Syntaxe:CGIDScriptTimeout time[s|ms]
Défaut:Si non définie ou définie à 0, valeur de la directive Timeout
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Base
Module:mod_cgid
Compatibilité:Disponible à partir de la version 2.4.10 du serveur HTTP Apache ; dans les versions précédentes, aucune durée d'attente n'était définie

Cette directive permet de limiter la durée d'attente avant les prochaines données reçues en sortie du programme CGI. Si ce temps est dépassé, la requête et le programme CGI se terminent.

Exemple

CGIDScriptTimeout 20
top

Directive ScriptSock

Description:Le préfixe du nom de fichier du socket à utiliser pour communiquer avec le démon CGI
Syntaxe:ScriptSock chemin fichier
Défaut:ScriptSock cgisock
Contexte:configuration globale
Statut:Base
Module:mod_cgid

Cette directive permet de définir le préfixe du nom de fichier de la socket à utiliser pour communiquer avec le démon CGI, préfixe auquel sera ajouté une extension correspondant à l'identifiant processus du serveur. La socket sera ouverte avec les permissions de l'utilisateur qui a démarré Apache (en général root). Afin de préserver la sécurité des communications avec les scripts CGI, il est impératif de n'accorder à aucun autre utilisateur la permission d'écrire dans le répertoire où se trouve la socket.

Si chemin fichier n'est pas un chemin absolu, il est relatif au chemin défini par la directive DefaultRuntimeDir.

Exemple

ScriptSock /var/run/cgid.sock

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav.html.fr.utf80000664000175100017510000005304614740503670021416 0ustar covenercovener mod_dav - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_dav

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Fonctionnalité de création et gestion de versions de documents via le web (WebDAV)
Statut:Extension
Identificateur de Module:dav_module
Fichier Source:mod_dav.c

Sommaire

Ce module ajoute à Apache une fonctionnalité WebDAV de classes 1 et 2 ('Web-based Distributed Authoring and Versioning' ou Création et gestion de versions de documents via le web). Il s'agit d'une extension du protocole HTTP qui permet de créer, déplacer, copier et supprimer des ressources ou collections de ressources sur un serveur web distant.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Activation de WebDAV

Pour activer le module mod_dav, ajoutez la ligne suivante à un conteneur de votre fichier httpd.conf :

Dav On

Ceci active le fournisseur de système de fichier DAV implémenté par le module mod_dav_fs. Ce dernier doit donc être compilé dans le serveur ou chargé au démarrage à l'aide de la directive LoadModule.

En outre, vous devez indiquer où se trouve la base de données des verrous DAV via une directive DavLockDB dans la section globale de votre fichier httpd.conf :

DavLockDB /usr/local/apache2/var/DavLock

Le répertoire contenant le fichier de la base de données des verrous doit avoir des droits en écriture pour l'utilisateur et le groupe sous lesquels Apache s'exécute et définis respectivement par les directives User et Group.

Si vous souhaitez limiter l'accès aux répertoires où DAV est activé, vous pouvez ajouter une clause <Limit> dans la section <Location> considérée. Pour définir la quantité maximale de données en octets qu'un client DAV peut envoyer par requête, vous devez utiliser la directive LimitXMLRequestBody, car La directive LimitRequestBody "habituelle" n'a aucune incidence sur les requêtes DAV.

Exemple complet

DavLockDB "/usr/local/apache2/var/DavLock"

<Directory "/usr/local/apache2/htdocs/foo">
    Require all granted
    Dav On

    AuthType Basic
    AuthName DAV
    AuthUserFile "user.passwd"

    <LimitExcept GET POST OPTIONS>
        Require user admin
    </LimitExcept>
</Directory>
top

Problèmes concernant la sécurité

Etant donné que les méthodes d'accès DAV permettent à des clients distants de manipuler des fichiers sur le serveur, vous devez vous assurer que votre serveur est bien sécurisé avant d'activer mod_dav.

Tout répertoire du serveur où DAV est activé doit être protégé par une procédure d'authentification. L'utilisation de l'authentification HTTP de base n'est pas recommandée. Vous devez utiliser au moins l'authentification HTTP à base de condensés qu'implémente le module mod_auth_digest. Pratiquement tous les clients WebDAV supportent cette méthode d'authentification. Vous pouvez aussi utiliser l'authentification de base sur une connexion où SSL est activé.

Pour que mod_dav puisse manipuler des fichiers, il doit avoir des permissions en écriture sur les répertoires et les fichiers qui sont sous son contrôle ; en d'autre termes, c'est l'utilisateur et le groupe sous lesquels Apache s'exécute et définis par les directives User et Group qui doivent avoir les droits en écriture sur ces fichiers et répertoires. Les fichiers nouvellement créés appartiendront aussi à ces utilisateur et groupe. Par conséquent, il est important de contrôler l'accès à ce compte. Les répertoires DAV sont considérés comme privés du point de vue d'Apache, et la modification des fichiers qu'ils contiennent autrement que par l'intermédiaire d'Apache (par exemple par FTP ou par des outils du niveau du système de fichiers) ne doit pas être permise.

mod_dav peut faire l'objet de plusieurs sortes d'attaques par déni de service. La directive LimitXMLRequestBody permet de limiter la quantité de mémoire consommée pour interpréter des requêtes DAV de grande taille. En outre, la directive DavDepthInfinity permet d'empêcher les requêtes PROPFIND concernant un répertoire de très grande taille de consommer de grandes quantités de mémoire. Un autre type d'attaque par déni de service peut aussi être mené par un client qui remplit simplement tout l'espace disque disponible avec des fichiers de très grande taille. Etant donné qu'il n'existe aucun moyen direct d'éviter ce genre d'attaque dans Apache, vous ne devez accorder des accès DAV qu'à des utilisateurs de confiance.

top

Configurations complexes

Les requêtes ayant pour but de manipuler des fichiers dynamiques (scripts PHP, scripts CGI, etc...) en utilisant mod_dav sont courantes. Ce traitement n'est pas évident car une requête GET va toujours tenter d'exécuter le script, plutôt que de télécharger son contenu. Pour éviter cet inconvénient, une méthode possible consiste à faire correspondre deux URLs différentes au même contenu, l'une d'entre elles servant à lancer le script, alors que l'autre peut être utilisée pour le télécharger et le manipuler avec DAV.

Alias "/phparea" "/home/gstein/php_files"
Alias "/php-source" "/home/gstein/php_files"
<Location "/php-source">
Dav On
ForceType text/plain
</Location>

Avec cette configuration, on peut utiliser http://example.com/phparea pour afficher le résultat de l'exécution des scripts PHP, et http://example.com/php-source pour les manipuler avec DAV.

top

Directive Dav

Description:Active les méthodes HTTP WebDAV
Syntaxe:Dav On|Off|nom fournisseur
Défaut:Dav Off
Contexte:répertoire
Statut:Extension
Module:mod_dav

La directive Dav permet d'activer les méthodes HTTP WebDAV pour le conteneur condidéré :

<Location "/foo">
    Dav On
</Location>

La valeur On est en fait un alias vers le fournisseur par défaut filesystem implémenté par le module mod_dav_fs. Notez que lorsque DAV est activé pour un conteneur, on ne peut pas le désactiver pour ses sous-conteneurs. Pour un exemple de configuration complet, reportez-vous à la section précédente.

N'activez pas WebDAV tant que votre serveur n'est pas sécurisé. Si vous passez outre cette recommandation, tout le monde pourra enregistrer des fichiers sur votre système.
top

Directive DavBasePath

Description:Définir le chemin de la racine du répertoire
Syntaxe:DavBasePath root-path
Défaut:None
Contexte:répertoire
Statut:Extension
Module:mod_dav
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache

Si le répertoire DAV est défini en utilisant une correspondance d'expression rationnelle (comme LocationMatch), mod_dav ne sera pas en mesure de déterminer de lui-même la racine du répertoire à partir du chemin seul. En conséquence, des fournisseurs tiers (par exemple le module mod_dav_svn de Subversion) pourront échouer à traiter des requêtes sans disposer de la valeur correcte de la racine du répertoire.

Pour permettre aux fournisseurs de travailler correctement en présence d'une telle configuration, vous devez utiliser DavBasePath.

<LocationMatch "^/repos/">
    Dav svn
    DavBasePath /repos
    SVNParentPath /var/svn
</LocationMatch>
top

Directive DavDepthInfinity

Description:Autorise les requêtes PROPFIND avec en-tête Depth: Infinity
Syntaxe:DavDepthInfinity on|off
Défaut:DavDepthInfinity off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_dav

La directive DavDepthInfinity permet d'autoriser le traitement des requêtes PROPFIND contenant l'en-tête Depth: Infinity. Par défaut, ce type de requête n'est pas autorisé, car il peut favoriser les attaques de type Déni de service.

top

Directive DavMinTimeout

Description:Durée minimale pendant laquelle le serveur maintient un verrou sur une ressource DAV
Syntaxe:DavMinTimeout secondes
Défaut:DavMinTimeout 0
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_dav

Lorsqu'un client demande le verrouillage d'une ressource DAV, il peut aussi spécifier une durée au bout de laquelle le verrou sera automatiquement supprimé par le serveur. Cette valeur ne constitue qu'une demande, et le serveur peut l'ignorer ou informer le client qu'il va utiliser une valeur arbitraire.

La directive DavMinTimeout permet de spécifier, en secondes, la durée minimale de verrouillage à renvoyer au client. Les Répertoires Web de Microsoft présentent une durée par défaut de 120 secondes ; la directive DavMinTimeout permet de définir une valeur supérieure (par exemple 600 secondes), afin de réduire les risques de perte du verrou par le client suite à une surcharge du réseau.

Exemple

<Location "/MSWord">
    DavMinTimeout 600
</Location>

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_common.html.tr.utf80000664000175100017510000021355414743132254022165 0ustar covenercovener mpm_common - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Modüller

Apache MPM Ortak Yönergeleri

Mevcut Diller:  de  |  en  |  fr  |  ja  |  tr 

Açıklama:Birden fazla Çok Süreçlilik Modülü (MPM) tarafından gerçeklenmiş yönergeler bütünü.
Durum:MPM
Support Apache!

Yönergeler

Bulunan hatalar

Ayrıca bakınız:

top

CoreDumpDirectory Yönergesi

Açıklama:core dosyasını dökümlemek üzere Apache HTTP Sunucusunun geçmeye çalışacağı dizin.
Sözdizimi:CoreDumpDirectory dizin
Öntanımlı:Öntanımlı değer için aşağıdaki açıklamaya bakınız
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork

Bu yönerge core dosyasını dökümlemek üzere Apache httpd’nin geçmeye çalışacağı dizini belirler. Eğer işletim sisteminiz, çöken bir sürecin olması durumunda core dosyasını çöken sürecin çalışma dizinine yazacak şekilde yapılandırılmışsa, CoreDumpDirectory yönergesinin değeri olarak, öntanımlı olan ve sunucuyu çalıştıran kullanıcı tarafından yazılamayan ServerRoot dizini yerine başka bir çalışma dizini belirtmek gerekir.

Hata ayıklamak amacıyla bir core dosyası dökümlemek isterseniz farklı bir yer belirtmek için bu yönergeyi kullanabilirsiniz. Eğer işletim sisteminiz çöken bir sürecin olması durumunda core dosyasını çöken sürecin çalışma dizinine yazacak şekilde yapılandırılmamışsa, bu yönergenin bir etkisi olmaz.

Linux sistemleri için güvenlik bilgisi

Bu yönergenin Linux'ta kullanılması, sistemdeki diğer işlemlerin (benzer yetkilerle çalıştırılan CGI komut dosyaları gibi) ptrace sistem çağrısı yoluyla httpd çocuklarına eklenmesine izin verebilir. Bu, bazı güvenlik saldırılarına karşı korumayı zayıflatabilir. Bu yönergenin üretim sistemlerinde kullanılması önerilmez.

Linux üzerinde core dökümlemek

Apache httpd root olarak başlatılıp başka bir kullanıcıya geçilirse Linux çekirdeği, süreç tarafından yazılabilir olsa bile core dökümlemeyi iptal eder. Eğer CoreDumpDirectory yönergesi ile açıkça bir dizin belirtirseniz, Apache httpd (2.0.46 ve sonraki sürümleri), Linux 2.4 ve sonrasında core dökümlemeyi yeniden etkinleştirecektir.

BSD üzerinde core dökümlemek

BSD sistemlerinde (FreeBSD gibi) suid bitli çalıştırılabilirlerin core dökümlemesini etkin kılmak için kern.sugid_coredump değişkenine 1 değerini atayın.

Özel sinyaller

CoreDumpDirectory işlemi sadece belli sinyaller için gerçekleşir: SIGFPE, SIGILL, SIGABORT, SIGSEGV ve SIGBUS.

Bazı işletim sistemlerinde SIGQUIT sinyali de bir core dosyası dökümler ancak bunu CoreDumpDirectory veya EnableExceptionHook işlemi üzerinden yapmaz, dolayısıyla core dosyasının yeri tamamen işletim sisteminin belirlediği yer olur.

top

EnableExceptionHook Yönergesi

Açıklama:Bir çöküş sonrası olağandışılık eylemcilerini çalıştıracak kancayı etkin kılar.
Sözdizimi:EnableExceptionHook On|Off
Öntanımlı:EnableExceptionHook Off
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork

Güvenlik sebebiyle bu yönerge sadece Apache --enable-exception-hook seçeneği ile yapılandırılmışsa kullanılabilir olacaktır. Bu, harici modüllerin eklenmesine ve bir çocuk sürecin çöküşü sonrası bir şeyler yapmaya izin veren bir kancayı etkin kılar.

Bu kancayı kullanan iki modül (mod_whatkilledus ve mod_backtrace) zaten vardır. bunlar hakkında daha fazla bilgi edinmek için Jeff Trawick'in EnableExceptionHook sitesine bakabilirsiniz.

top

GracefulShutdownTimeout Yönergesi

Açıklama:Sunucunun nazikçe kapatılmasının ardından ana süreç çıkana kadar geçecek süre için bir zaman aşımı belirler.
Sözdizimi:GracefulShutdownTimeout saniye
Öntanımlı:GracefulShutdownTimeout 0
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork
Uyumluluk:Sürüm 2.2 ve sonrasında mevcuttur

GracefulShutdownTimeout yönergesi, sunucuya "nazikçe dur" sinyali gönderildikten sonra mevcut bağlantılara hizmet sunmaya daha kaç saniye devam edebileceğini belirtir.

Bu değerin 0 olarak belirtilmesi, sunucunun bekleyen bütün isteklere hizmet sunumu tamamlanıncaya kadar (gerekirse sonsuza kadar) bekleyebileceği anlamına gelir.

top

Listen Yönergesi

Açıklama:Sunucunun dinleyeceği IP adresini ve portu belirler.
Sözdizimi:Listen [IP-adresi:]port-numarası [protokol]
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
Uyumluluk:protokol değiştirgesi 2.1.5 sürümünde eklenmiştir.

Listen yönergesi Apache httpd’yi sadece belli IP adreslerini ve portlarını dinlemeye sevkeder. Listen artık belirtilmesi zorunlu yönergelerden biridir. Yapılandırma dosyasında bulunmadığı takdirde sunucu başlatılırken başarısız olacaktır. Bu Apache HTTP Sunucusunun önceki sürümünde böyle değildi.

Listen yönergesi Apache httpd’ye, sadece belli portlardan veya IP adresi ve port çiftlerinden gelen istekleri kabul etmesini söyler. Eğer sadece port numarası belirtilmişse sunucu belirtilen portu bütün ağ arabirimlerinde dinleyecektir. Eğer portla birlikte bir IP adresi de belirtilmişse, sunucu belirtilen portu sadece belirtilen arabirimden dinleyecektir.

Çok sayıda IP adresi ve port belirtmek için çok sayıda Listen yönergesi kullanılabilir. Sunucu bu durumda belirtilen bütün IP adreslerinden ve portlardan gelecek isteklere yanıt verecektir.

Örneğin sunucunun hem port 80 hem de port 8000’den istek kabul etmesini istiyorsanız bunu şöyle belirtebilirsiniz:

Listen 80
Listen 8000

Sunucunun belirtilen iki ağ arabiriminden ve port numarasından gelen bağlantıları kabul etmesi için şu yapılandırmayı kullanabilirsiniz:

Listen 192.170.2.1:80
Listen 192.170.2.5:8000

IPv6 adresleri belirtilirken örnekteki gibi köşeli ayraçlar arasına alınmalıdır:

Listen [2001:db8::a00:20ff:fea7:ccea]:80

İsteğe bağlı protocol argümanı çoğu yapılandırmada gerekli değildir. Belirtilmediği takdirde. port 443 için https ve tüm diğer portlar için http öntanımlıdır. Protokol, isteği hangi modülün elde edeceğinin ve AcceptFilter yönergesi ile protokole özgü hangi en iyilemelerin uygulanacağının saptanmasında kullanılır.

Protokol belirtme ihtiyacını sadece standartdışı portlar çalıştırıyorsanız duyarsınız. Örneğin, port 8443 üzerinde bir https sitesi çalıştırmak istiyorsanız bunu şöyle belirtebilirsiniz:

Listen 192.170.2.1:8443 https

Hata durumu

Aynı IP adresi ve portun çok sayıda Listen yönergesinde belirtilmesi bir "adres kullanımda" (Address already in use) hatasına yol açar.

Ayrıca bakınız:

top

ListenBackLog Yönergesi

Açıklama:Bekleyen bağlantılar kuyruğunun azami uzunluğunu belirler
Sözdizimi:ListenBackLog kuyruk-uzunluğu
Öntanımlı:ListenBackLog 511
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

Bekleyen bağlantılar kuyruğunun azami uzunluğu. Genellikle bu ayar ne gerekir ne de istenir. Ancak bazı sistemlerde TCP SYN yüklenme saldırılarına karşı bu değerin arttırılması gerekebilir. kuyruk-uzunluğu parametresi için listen(2) işlevinin açıklamasına bakınız.

Bu değer çoğunlukla işletim sistemi tarafından daha küçük bir sayıyla sınırlanır. Bu, işletim sistemine bağlı olarak değişiklik gösterir. Ayrıca, çoğu işletim sisteminin kuyruk-uzunluğu parametresi ile ne belirttiğinize bakmaksızın kendisi için atanmış değeri (fakat normal olarak daha büyüğünü) kullanacağına dikkat ediniz.

top

ListenCoresBucketsRatio Yönergesi

Açıklama:İşlemci çekirdek sayısının dinleyenlerin buket sayısına oranı
Sözdizimi:ListenCoresBucketsRatio oran
Öntanımlı:ListenCoresBucketsRatio 0 (iptal)
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork
Uyumluluk:Apache HTTP Server 2.4.17 ve sonrasında, SO_REUSEPORT soket seçeneğini destekleyen bir Linux çekirdeğinin varlığında ve yeni bağlantıların bunu kullanan dinleme süreçlerinin (veya evrelerinin) soketleri arasında eşit paylaştırılıyor olması halinde kullanılır. Örneğin Linux 3.9 ve sonrasında kullanılabilirken *BSD'lerin şu anki SO_REUSEPORT gerçeklenimi ile kullanılamaz.

(çevrimiçi) İşlemci çekirdek sayısının dinleyenlerin buket sayısına oranı, Apache HTTP Sunucusunun işlemci_çekirdek_sayısı / oran sayıda dinleme buketi oluşturması için kullanılabilir ve bu buketlerin herbiri aynı portlar üzerinde kendi Listen soketlerini içeriyor olurlar. Bu durumda, her çocuk süreç tek bir buketle çalışır (çocukların oluşturulması sırasında buketler döner dağılımla eşleştirilir).

"çevrimiçi" İşlemci çekirdek sayısının anlamı

Linux için (ve ayrıca BSD) bir işlemci çekirdeği Hotplug yapılandırılarak açılıp kapatıalbilir. Dolayısıyla, ListenCoresBucketsRatio yönergesi oluşturulacak buket sayısını hesaplarken bu yapılandırmayı esas alır.

ListenCoresBucketsRatio yeni bağlantılar kabul edilirken/darboğazlar oluşurken ölçeklenebilirliği arttırabilir. Çok sayıda işlemci çekirdekli sistemlerde bu özelliğin etkinleştirilmesinin önemli başarım artışları ve daha kısa yanıt süreleri oluşturduğu gözlenmiştir.

Bu oranın etkin olabilmesi için işlemci çekirdeği çift sayıda olmalıdır. oran için önerilen değer 8 olup bu durumda çalışma anında en azından 16 çekirdek kullanılabiliyor olmalıdır. En iyi başarımı elde etmek gereken oran her sistem için hesaplanmalı, çok sayıda değer denenmeli ve başlıca başarım ölçütlerinizin çeşitli sonuçları iyi gözlemlenmelidir.

Bu yönerge aşağı yuvarlanan MinSpareThreads ve MaxSpareThreads değerlerinin hesabını etkiler. Bağlantıları en uygun şekilde kabul etmek için çocuk süreçlerin sayısının buket sayısının katları olması gerekir.

Çok sayıda Listen veya aynı adres veya port üstünda çok sayıda Apache HTTP sunucusu

Dinleyen soketler üzerinde SO_REUSEPORT seçeneğini tanımlamak normal bir durumda sistem tarafından oluşturulmuş bir bağlama hatası olmaksızın çok sayıda sürecin aynı adres ve porta bağlanması sonucunu doğurur.

Bu ayrıca pozitif bir ListenCoresBucketsRatio değeriyle aynı IP:port üzerinde yapılandırılmış çok sayıda Apache httpd örneğinin hatasız başlamasının yanında gelen çağrıların her iki örneğe eşit olarak dağıtılacağı anlamına da gelir. (Bu, herhangi bir durumda bir öneri veya makul bir kullanım DEĞİL, böyle bir olası sorunun algılanmasının engelleneceğine dair bir uyarıdır.)

Aynı örnek dahilinde, çok sayıda Listen yönergesinin tam olarak aynı IP ve port üzerinde yapılandırılması durumunda Apache httpd gerekli sınamaları yaptıktan sonra başlamayacak, böylelikle birbirinin benzeri çok sayıda kullanışsız buketin oluşturulması engellenecektir. Ancak, olası tüm örtüşmeler (bir konak adının başka bir yerde kullanılmış bir IP'ye çözümlenmesi gibi) yakalanamayacaktır.

top

MaxConnectionsPerChild Yönergesi

Açıklama:Tek bir çocuk sürecin ömrü boyunca işleme sokabileceği istek sayısını sınırlamakta kullanılır.
Sözdizimi:MaxConnectionsPerChild sayı
Öntanımlı:MaxConnectionsPerChild 0
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
Uyumluluk:Apache HTTP Sunucusunun 2.3.9 ve sonraki sürümlerinde kullanılabilmektedir. Eski isim MaxRequestsPerChild hala desteklenmektedir.

MaxConnectionsPerChild yönergesi, tek bir çocuk sürecin işleme sokabileceği istek sayısını sınırlamakta kullanılır. MaxConnectionsPerChild istekten sonra çocuk süreç ölür. Eğer MaxConnectionsPerChild için 0 belirtilmişse sürecin ömrü sonsuz olacaktır.

MaxConnectionsPerChild için sıfırdan farklı bir değer belirtilmesi sürecin kullanacağı bellek miktarını sınırlamak suretiyle olası bellek sızıntılarını engeller.

top

MaxMemFree Yönergesi

Açıklama:free() çağrılmaksızın ana bellek ayırıcının ayırmasına izin verilen azami bellek miktarını belirler.
Sözdizimi:MaxMemFree kB-sayısı
Öntanımlı:MaxMemFree 2048
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt, mpm_netware

MaxMemFree yönergesi, free() çağrılmaksızın her bellek ayırıcının ayırmasına izin verilen azami bellek miktarını kB cinsinden belirler. Evreli MPM'lerde her evre kendi ayırıcısına sahiptir. 0 değeri belirtildiğinde eşik sınırsız olacaktır.

top

MaxRequestWorkers Yönergesi

Açıklama:Aynı anda işleme sokulacak azami bağlantı sayısı
Sözdizimi:MaxRequestWorkers sayı
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork

MaxRequestWorkers yönergesi aynı anda işleme sokulacak bağlantı sayısını sınırlamak için kullanılır. MaxRequestWorkers bağlantı isteğinden fazlası geldiği takdirde bu istekler normal olarak kuyruğa alınıp bekletilir. Kuyrukta bekletilecek isteklerin azami sayısı ise ListenBacklog yönergesi ile belirlenir. İstek sunmakta olan çocuk süreçlerden biri serbest kaldığında bekletilen bağlantılardan birine hizmet sunulmaya başlanır.

Evreli olmayan sunucularda (prefork gibi) MaxRequestWorkers yönergesi istekleri sunmak için başlatılacak çocuk süreçlerin azami sayısını belirler. Öntanımlı değer 256 olup bu değeri arttırmak isterseniz ServerLimit değerini de arttırmalısınız.

Çok evreli ve melez sunucularda (event veya worker gibi) MaxRequestWorkers yönergesi istemcilere hizmet verecek evre sayısını sınırlar. Öntanımlı değer melez MPM’ler için 16'dır (ServerLimit ile ThreadsPerChild çarpılır: 16 x 25). Bu bakımdan MaxRequestWorkers değerini 16 süreçten fazlasına ayarlamak için ServerLimit değerini de arttırmalısınız.

MaxRequestWorkers yerine 2.3.13 öncesinde MaxClients kullanılırdı. Eski isim hala desteklenmektedir.

top

MaxSpareThreads Yönergesi

Açıklama:Boştaki azami evre sayısını belirler
Sözdizimi:MaxSpareThreads number
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, mpm_netware, mpmt_os2

Boştaki azami evre sayısı. Her MPM bu yönerge karşısında farklı davranır.

worker ve event için MaxSpareThreads 250 öntanımlıdır. Bu MPM'ler boştaki evreleri sunucu genelinde izler. Eğer sunucuda çok fazla boşta evre varsa, sunucu boştaki evrelerin sayısı bu sınırın altına inene kadar çocuk süreçleri öldürür. ListenCoresBucketsRatio yönergesi etkinse ek süreçler/evreler oluşabilir.

mpm_netware için MaxSpareThreads 100 öntanımlıdır. Bu MPM tek bir süreç olarak çalıştığından boştaki evre sayısı aynı zamanda sunucu genelinde boştaki evre sayısıdır.

mpmt_os2 modülü mpm_netware modülü gibi çalışır. mpmt_os2 için öntanımlı değer 10'dur.

Kısıtlamalar

MaxSpareThreads için değer aralığı sınırlıdır. Apache httpd belirtilen değeri aşağıdaki kurallara uygun olarak kendiliğinden düzeltecektir:

Ayrıca bakınız:

top

MinSpareThreads Yönergesi

Açıklama:İsteklerin ani artışında devreye girecek boştaki evrelerin asgari sayısını belirler.
Sözdizimi:MinSpareThreads sayı
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, mpm_netware, mpmt_os2

İsteklerin ani artışında devreye girecek boştaki evrelerin asgari sayısı. Her MPM bu yönerge karşısında farklı davranır.

worker ve event modülü için MinSpareThreads 75 öntanımlıdır ve bu modül boştaki evreleri sunucu genelinde izler. Eğer sunucuda boştaki evre sayısı yetersizse, sunucu, boştaki evrelerin sayısı bu sınırın üstüne çıkana kadar çocuk süreç oluşturur. ListenCoresBucketsRatio yönergesi etkinse ek süreçler/evreler oluşabilir.

mpm_netware için MinSpareThreads 10 öntanımlıdır ve tek süreç kendisi olduğundan izleme sunucu genelinde yapılır.

mpmt_os2 modülü mpm_netware modülü gibi çalışır. mpmt_os2 için öntanımlı değer 5'tir.

Ayrıca bakınız:

top

PidFile Yönergesi

Açıklama:Ana sürecin süreç kimliğinin (PID) kaydedileceği dosyayı belirler.
Sözdizimi:PidFile dosya
Öntanımlı:PidFile logs/httpd.pid
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt, mpmt_os2

PidFile yönergesi, sunucunun artalan sürecinin süreç kimliğinin kaydedileceği dosyayı belirler. Dosya ismi mutlak dosya yoluyla belirtilmemişse dosya yolunun ServerRoot dizinine göre belirtildiği kabul edilir.

PidFile /var/run/apache.pid

Sunucuya sinyal gönderebilmek çoğunlukla işe yarar. Böylece ErrorLog ve TransferLog dosyaları kapatılıp yeniden açılır ve yapılandırma dosyaları yeniden okunur. Bu, PidFile dosyasında belirtilen süreç kimliğine bir SIGHUP (kill -1) sinyali gönderilerek yapılır.

Günlük dosyasının yeri ve güvenlik ile ilgili uyarılar PidFile dosyası içinde sözkonusu olabilir.

Ek Bilgi

Apache HTTP Sunucusunu (yeniden) başlatırken veya durdururken sadece apachectl betiğini kullanmanız önerilir.

top

ReceiveBufferSize Yönergesi

Açıklama:TCP alım tamponu boyu
Sözdizimi:ReceiveBufferSize bayt-sayısı
Öntanımlı:ReceiveBufferSize 0
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

Sunucunun TCP alım tamponu boyunu bayt-sayısı ile belirtilen bayta ayarlar.

0 değeri atarsanız sunucu işletim sistemi öntanımlısını kullanacaktır.

top

ScoreBoardFile Yönergesi

Açıklama:Çocuk süreçler için eşgüdüm verisini saklamakta kullanılan dosyanın yerini belirler.
Sözdizimi:ScoreBoardFile dosya-yolu
Öntanımlı:ScoreBoardFile logs/apache_runtime_status
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt

Apache HTTP Sunucusu ana ve çocuk süreçler arasında iletişim için bir çetele tutar. Bazı mimariler bu iletişimi kolaylaştırmak için bir dosya gerektirir. Eğer yönerge belirtilmezse Apache httpd çeteleyi önce tamamen bellekte oluşturmayı dener (anonim paylaşımlı bellek kullanarak); bunda başarılı olamazsa dosyayı diskte oluşturmaya çalışacaktır (paylaşımlı belleğe eşlemli dosya kullanarak). Bu yönergenin belirtilmesi Apache httpd'nin dosyayı daima diskte oluşturmasına sebep olur.

ScoreBoardFile /var/run/apache_status

Paylaşımlı belleğe eşlemli dosya, çeteleye doğrudan erişmesi gereken üçüncü parti uygulamalar için yararlıdır.

Eğer ScoreBoardFile yönergesi ile bir dosya belirtecekseniz, dosyayı bir RAM diske yerleştirerek hız artışı sağlayabilirsiniz. Fakat, günlük dosyası yerleştirme ve güvenlik ile ilgili uyarılara benzer uyarılara karşı dikkatli olunuz.

Ayrıca bakınız:

top

SendBufferSize Yönergesi

Açıklama:TCP tamponu boyu
Sözdizimi:SendBufferSize bayt-sayısı
Öntanımlı:SendBufferSize 0
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

Sunucu TCP gönderim tamponu boyunu bayt-sayısı ile belirtilen bayta ayarlayacaktır. Yüksek hızlı yüksek yataklık süreli bağlantılarda işletim sisteminin öntanımlı değerini aşacak şekilde (örn, kıtalararası hızlı hatlarda 100ms veya fazlası) ayarlamak çoğunlukla kullanışlıdır.

0 değeri atarsanız sunucu işletim sistemi öntanımlısını kullanacaktır.

İşletim sisteminizin ilaveten yapılandırılması, yüksek hız, yüksek gecikme bağlantılarında daha yüksek başarım elde etmek için gerekli olabilir.

Bazı işletim sistemlerinde, TCP davranışı, EnableSendfile yönergesine Off değeri atanmadıkça görülemeyen, büyükçe bir SendBufferSize değerinden kaynaklanarak değişir. Bu etkileşim sadece duruk dosyalarda görülür.

top

ServerLimit Yönergesi

Açıklama:Ayarlanabilir süreç sayısının üst sınırını belirler.
Sözdizimi:ServerLimit sayı
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork

prefork modülü söz konusu olduğunda bu yönerge, Apache httpd sürecinin ömrü boyunca MaxRequestWorkers yönergesine atanabilecek azami değeri belirler. worker ve event modülü sözkonusu olduğunda ise, Apache httpd sürecinin ömrü boyunca MaxRequestWorkers yönergesine atanabilecek azami değeri ThreadLimit ile birlikte belirler. event modülü için bu yönerge kaç eski sunucunun çalışmayı sürdüreceğini ve kaçının açık bağlantıları işlemeyi bitireceğini belirler. Bu yönergeyi bir yeniden başlatma sırasında değiştirirseniz bu değişiklik yok sayılır fakat MaxRequestWorkers değişiklikleri dikkate alınır.

Bu yönergenin kullanılması özel bir dikkat gerektirir. Eğer ServerLimit gereğinden yüksek bir değere ayarlanırsa, gereksiz yere paylaşımlı bellek ayrılmış olur. Eğer ServerLimit ve MaxRequestWorkers değerleri sistemin işleyebileceğinden daha yüksek değerlere ayarlanırsa Apache httpd başlayamayacağı gibi sistemi kararsız hale de getirebilir.

Bu yönergeyi prefork modülü ile sadece MaxRequestWorkers yönergesine 256’dan (öntanımlı) daha büyük bir değer atayacaksanız kullanınız. Bu yönergeye MaxRequestWorkers için atamak istediğiniz değerden fazlasını atamayınız.

worker modülü söz konusu olduğunda bu yönergeyi MaxRequestWorkers ve ThreadsPerChild ayarları 16 sunucu sürecinden (16 öntanımlıdır) fazlasını gerektiriyorsa ayarlayınız. Bu yönergeye MaxRequestWorkers ve ThreadsPerChild için gerekli gördüğünüz sunucu süreci sayısından fazlasını atamayınız.

event modülü söz konusu olduğunda, MaxRequestWorkers ve ThreadsPerChild yönergeleri ile belirlenen süreç sayısına ek olarak zarifçe kapatılan süreçlerin sayısıyla arttırıp 16 sunucu sürecinden (16 öntanımlıdır) fazlasına ayarlayınız.

Ek Bilgi

Sunucu içinde derlenmiş olarak ServerLimit 20000 şeklinde bir zorlayıcı sınır vardır (prefork için 200000’dir). Bu önlem, yazım hatalarının istenmeyen sonuçlara yol açmasını engellemek için düşünülmüştür. Bu sınırı daha da arttırmak için mpm kaynak dosyasındaki MAX_SERVER_LIMIT değerini değiştirip sunucuyu yeniden derlemeniz gerekir.

Ayrıca bakınız:

top

StartServers Yönergesi

Açıklama:Sunucunun başlatılması sırasında oluşturulan çocuk süreçlerin sayısını belirler.
Sözdizimi:StartServers sayı
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, prefork, mpmt_os2

StartServers yönergesi, sunucunun başlatılması sırasında oluşturulan çocuk süreçlerin sayısını belirler. Süreç sayısı normal olarak yüke bağlı olarak değişse de bu değerin ayarlanmasını gerektirecek küçük bir sebep vardır. (MinSpareThreads, MaxSpareThreads, MinSpareServers, MaxSpareServers yönergelerine bakınız.)

Öntanımlı değer MPM’den MPM’e fark eder. Öntanımlı değer worker ve event için 3 iken prefork için 5, mpmt_os2 için 2'dir.

top

StartThreads Yönergesi

Açıklama:Sunucunun başlatılması sırasında oluşturulan evrelerin sayısını belirler.
Sözdizimi:StartThreads sayı
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:mpm_netware

StartThreads yönergesi, sunucunun başlatılması sırasında oluşturulan evrelerin sayısını belirler. Evre sayısı normal olarak yüke bağlı olarak değişse de bu değerin ayarlanmasını gerektirecek küçük bir sebep vardır. (MinSpareThreads, MaxSpareThreads, MinSpareServers, MaxSpareServers yönergelerine bakınız.)

mpm_netware için StartThreads 50 öntanımlı olup, sadece tek bir süreç olduğundan, sunucunun başlatılması sırasında oluşturulan evrelerin toplam sayısı 50’dir.

top

ThreadLimit Yönergesi

Açıklama:Çocuk süreç başına ayarlanabilir evre sayısının üst sınırını belirler.
Sözdizimi:ThreadLimit sayı
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, mpm_winnt

Bu yönerge, Apache httpd sürecinin ömrü boyunca ThreadsPerChild yönergesine atanabilecek azami değeri belirler. Bu yönergeyi bir yeniden başlatma sırasında değiştirirseniz bu değişiklik yok sayılır fakat ThreadsPerChild değişiklikleri dikkate alınır.

Bu yönergenin kullanılması özel bir dikkat gerektirir. Eğer ThreadLimit değeri ThreadsPerChild değerinden yüksek bir değere ayarlanırsa, gereksiz yere paylaşımlı bellek ayrılmış olur. Eğer ThreadLimit ve ThreadsPerChild değerleri sistemin işleyebileceğinden daha yüksek değerlere ayarlanırsa Apache httpd başlayamayacağı gibi sistemi kararsız hale de getirebilir. Bu yönergeye Apache httpd'nin çalışması için öngörülmüş en büyük değerden daha yükseğini atamayınız.

ThreadLimit yönergesinin öntanımlı değeri mpm_winnt için 1920, diğerleri için 64’tür.

Ek Bilgi

Sunucu içinde derlenmiş olarak ThreadLimit 20000 şeklinde bir zorlayıcı sınır vardır (mpm_winnt için 15000, event için ThreadLimit 100000). Bu önlem, yazım hatalarının istenmeyen sonuçlara yol açmasını engellemek için düşünülmüştür. Bu sınırı daha da arttırmak için mpm kaynak dosyasındaki MAX_SERVER_LIMIT değerini değiştirip sunucuyu yeniden derlemeniz gerekir.

top

ThreadsPerChild Yönergesi

Açıklama:Her çocuk süreç tarafından oluşturulan evrelerin sayısını belirler.
Sözdizimi:ThreadsPerChild sayı
Öntanımlı:Ayrıntılar için aşağıdaki açıklamaya bakınız.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, mpm_winnt

Bu yönerge, her çocuk süreç tarafından oluşturulan evrelerin sayısını belirler. Çocuk süreçler bu evreleri başlatıldıklarında oluştururlar ve bundan daha fazlasını asla oluşturmazlar. mpm_winnt gibi sadece bir çocuk sürecin bulunduğu bir MPM kullanıyorsanız, bu sayı Apache httpd'nin tüm yükünü kaldırabilecek kadar büyük olmalıdır. worker gibi çok çocuk süreçli bir MPM kullanıyorsanız, toplam evre sayısı Apache httpd'nin tüm yükünü kaldırabilecek kadar büyük olmalıdır.

ThreadsPerChild için öntanımlı değer mpm_winnt kullanıldığında 64 diğerleri için 25’tir.

ThreadsPerChild değeri ThreadLimit değerini aşamaz. Eğer daha yüksek bir değer verilirse sunucu başlatılırken düşürülür ve günlüğe bir uyarı kaydedilir. Bu iki yönerge arasındaki ilişki ThreadLimit belgelsinde açıklanmıştır.

top

ThreadStackSize Yönergesi

Açıklama:İstemci bağlantılarını elde eden evreler tarafından kullanılan yığıtın bayt cinsinden uzunluğunu belirler.
Sözdizimi:ThreadStackSize boyut
Öntanımlı:NetWare üzerinde 65536; diğer işletim sistemlerinde değişir.
Bağlam:sunucu geneli
Durum:MPM
Modül:event, worker, mpm_winnt, mpm_netware, mpmt_os2
Uyumluluk:Apache HTTP Sunucusu 2.1 ve sonrasında kullanılabilir.

ThreadStackSize yönergesi, istemci bağlantılarını elde eden evreler ve bu bağlantıları işlemekte yardımcı olan modül çağrıları tarafından kullanılan yığıtın bayt cinsinden uzunluğunu belirler. Çoğu durumda işletim sistemi yığıtı uygun bir boyuta ayarlar, fakat yine de ayarlanmasını gerektirecek bazı durumlar olabilir:

Çocuk süreç başına yüksek bir evre sayısı gerekmedikçe ThreadStackSize değerinin azaltılmaması önerilir. Bazı platformlarda (Linux dahil), 128000 ayarı zaten çok düşüktür ve daha da azaltmak bazı modüllerle çökmeye sebep olur.

Mevcut Diller:  de  |  en  |  fr  |  ja  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directive-dict.html.fr.utf80000664000175100017510000004615714740503670022711 0ustar covenercovener Termes utilisés pour la description des directives - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4

Termes utilisés pour la description des directives

Langues Disponibles:  en  |  es  |  fr  |  ja  |  ko  |  tr 

Ce document décrit les termes utilisés pour décrire chaque directive de configuration d'Apache.

Support Apache!

Voir aussi

top

Description

Une brève description des fonctions de cette directive.

top

Syntaxe

Ce terme introduit le format sous lequel la directive doit apparaître dans le fichier de configuration. Cette syntaxe est très spécifique à la directive et est décrite en détail dans la définition de cette dernière. En général, le nom de la directive est suivi d'un ou plusieurs arguments séparés par des espaces. Si un argument contient un espace, il doit être entouré de guillemets. Les arguments optionnels sont entourés de crochets. Lorsqu'un argument accepte une valeur parmi une liste de valeurs possibles, cette liste est spécifiée en séparant les valeurs par une barre verticale "|". Les textes littéraux sont présentés dans la fonte par défaut, alors que les types d'argument pour lesquels une substitution est nécessaire sont en gras. La syntaxe des directives acceptant un nombre variable d'arguments se termine par "...", ce qui indique que le dernier argument peut être répété.

Les directives utilisent un grand nombre de types d'arguments différents. Les plus courants sont définis ci-dessous.

URL
Un Localisateur de Ressource Uniforme (Uniform Resource Locator) complet comportant un protocole, un nom d'hôte et un nom de chemin optionnel comme dans http://www.example.com/chemin/vers/fichier.html
chemin-URL
La partie de l'url qui suit le protocole et le nom d'hôte comme dans /chemin/vers/fichier.html. Le chemin-URL représente la ressource vue du web, et est différente de la représentation de cette même ressource vue du système de fichiers.
chemin-fichier
Le chemin d'un fichier dans le système de fichiers local commençant par le répertoire racine comme dans /usr/local/apache/htdocs/chemin/vers/fichier.html. Sauf mention contraire, un chemin-fichier qui ne commence pas par un slash sera considéré comme relatif au répertoire défini par la directive ServerRoot.
chemin-répertoire
Le chemin d'un répertoire dans le système de fichiers local commençant par le répertoire racine comme dans /usr/local/apache/htdocs/chemin/vers/.
nom-fichier
Le nom d'un fichier sans son chemin comme dans fichier.html.
regex
Une expression rationnelle compatible Perl. La définition de la directive spécifiera à quoi regex sera comparée.
extension
En général, c'est la partie du nom de fichier qui suit le dernier point. Cependant, Apache reconnaît plusieurs extensions de noms de fichiers ; ainsi, si un nom de fichier contient plusieurs points, chacune des parties du nom de fichier séparées par des points et situées après le premier point est une extension. Par exemple, le nom de fichier fichier.html.en comporte deux extensions : .html et .en. Pour les directives Apache, vous pouvez spécifier les extensions avec ou sans le point initial. Enfin, les extensions ne sont pas sensibles à la casse.
MIME-type
Une méthode de description du format d'un fichier consistant en un type de format majeur et un type de format mineur séparés par un slash comme dans text/html.
env-variable
Le nom d'une variable d'environnement définie au cours du processus de configuration d'Apache. Notez qu'elle peut être différente d'une variable d'environnement du système d'exploitation. Voir la documentation sur les variables d'environnement pour plus de détails.
top

Défaut

Si la directive possède une valeur par défaut (en d'autres termes, si le serveur Web Apache se comporte comme si vous l'aviez définie à une valeur particulière, alors que vous l'avez omise dans votre configuration), elle est spécifiée ici. Si la directive ne possède pas de valeur par défaut, cette section doit spécifier "Aucune". Notez que la valeur par défaut dont il est question n'est pas nécessairement la même que la valeur attribuée à la directive dans le fichier httpd.conf par défaut distribué avec le serveur.

top

Contexte

Indique les parties des fichiers de configuration du serveur où cette directive est valide. Il s'agit d'une liste d'une ou plusieurs des valeurs suivantes séparées par des virgules :

configuration globale
Signifie que la directive peut être utilisée dans les fichiers de configuration globale (par exemple httpd.conf), mais pas à l'intérieur d'un conteneur <VirtualHost> ou <Directory>. De même, elle n'est pas valide dans les fichiers .htaccess.
serveur virtuel
Signifie que la directive peut apparaître à l'intérieur d'un conteneur <VirtualHost> dans les fichiers de configuration du serveur.
répertoire
Une directive spécifiée comme valide dans ce contexte peut être utilisée à l'intérieur de conteneurs <Directory>, <Location>, <Files>, <If>, et <Proxy> dans les fichiers de configuration du serveur, en tenant compte des restrictions précisées dans la documentation sur les Sections de configuration.
.htaccess
Si une directive est valide dans ce contexte, cela signifie qu'elle peut apparaître à l'intérieur de fichiers de configuration de niveau répertoire .htaccess. Elle sera ou ne sera pas traitée, selon la définition de l'option overrides pour le contexte courant.

La directive n'est autorisée que dans le contexte désigné ; si vous essayez de l'utiliser ailleurs, vous générerez une erreur de configuration qui va soit empêcher le serveur de traiter les requêtes correctement dans ce contexte, soit tout simplement empêcher le serveur de fonctionner -- en d'autres termes, le serveur refusera de démarrer.

Les lieux de définition valides pour une directive résultent en fait d'un OU logique de tous les contextes spécifiés. En d'autres termes, une directive spécifiée comme valide dans "configuration globale, .htaccess" peut être utilisée dans le fichier httpd.conf et dans les fichiers .htaccess, mais pas dans un conteneur <Directory> ou <VirtualHost>.

top

Surcharge/Écrasement

Ce terme indique quelle autorisation de surcharge ("override") doit être active pour que la directive puisse être traitée lorsqu'elle apparaît dans un fichier .htaccess. Si le context de la directive ne lui permet pas d'apparaître dans un fichier .htaccess, aucun contexte ne sera spécifié.

Les autorisations de surcharge sont activées via la directive AllowOverride, et possèdent une portée particulière, comme un répertoire et tous ses sous-répertoires, sauf si une autre directive AllowOverride apparaît à un niveau inférieur. La documentation pour cette directive spécifie aussi les noms d'autorisations de surcharge disponibles.

top

Statut

Cet attribut indique le degré de rapprochement de la directive du coeur d'Apache ; en d'autres termes, vous pouvez être amené à recompiler le serveur avec un jeu de modules supplémentaires pour pouvoir utiliser la directive, et ainsi accéder à ses fonctionnalités. Les valeurs possible pour cet attribut sont :

Core
Lorsqu'une directive a pour statut "Core", cela signifie qu'elle fait partie du coeur du serveur web Apache, et est de ce fait toujours disponible.
MPM
Une directive dont le statut est "MPM" est fournie par un module Multi-Processus. Ce type de directive sera disponible si et seulement si vous utilisez un des MPMs spécifiés dans la ligne Module de la définition de la directive.
Base
Une directive dont le statut est "Base" est fournie par un des modules Apache standards qui sont compilés dans le serveur par défaut, et sont de ce fait toujours disponibles, sauf si vous avez fait en sorte de les supprimer de votre configuration.
Extension
Une directive dont le statut est "Extension" est fournie par un des modules inclus dans le kit du serveur Apache, mais qui ne sont pas compilés dans le serveur par défaut. Pour activer la directive et accéder à ses fonctionnalités, vous devez modifier les fichiers de configuration de la compilation du serveur, et recompiler Apache.
Expérimental
Le statut "Expérimental" indique que la directive fait partie du kit Apache, mais que vous l'utilisez à vos risques et périls. La directive est documentée à titre d'exhaustivité, et n'est pas obligatoirement supportée. Le module qui fournit la directive peut être compilé par défaut dans le serveur ou non ; consultez le haut de la page qui décrit la directive et son module pour vérifier sa disponibilité.
top

Module

Il s'agit d'une simple liste des noms des modules sources qui fournissent la directive.

top

Compatibilité

Si la directive ne faisait pas partie de la distribution originale d'Apache version 2, la version dans laquelle elle a été introduite est indiquée ici. Cette section indique aussi si la directive n'est disponible que sur certaines plates-formes.

Langues Disponibles:  en  |  es  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_access_compat.html.fr.utf80000664000175100017510000007634414740503670023456 0ustar covenercovener mod_access_compat - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_access_compat

Langues Disponibles:  en  |  fr  |  ja 

Description:Autorisations de groupe à base de nom d'hôte (nom ou adresse IP)
Statut:Extension
Identificateur de Module:access_compat_module
Fichier Source:mod_access_compat.c
Compatibilité:Disponible dans la version 2.3 du serveur HTTP Apache à des fins de compatibilité avec les précédentes versions d'Apache httpd 2.x. Les directives fournies par ce module sont devenues obsolètes depuis la refonte d'authz. Voir mod_authz_host

Sommaire

Les directives fournies par le module mod_access_compat s'utilisent dans les sections <Directory>, <Files> et <Location>, ainsi que dans les fichiers .htaccess et permettent de contrôler l'accès à certaines parties du serveur. On peut contrôler cet accès en fonction du nom d'hôte du client, de son adresse IP ou d'autres caractéristiques de la requête, telles qu'elles sont enregistrées dans les variables d'environnement. Les directives Allow et Deny permettent de spécifier quels clients sont ou ne sont pas autorisés à accéder au serveur, alors que la directive Order définit le statut d'accès par défaut, et détermine la manière dont les directives Allow et Deny interagissent entre elles.

Les restrictions d'accès à base de nom d'hôte et l'authentification à base de mot de passe peuvent être implémentées simultanément. Dans ce cas, on utilise la directive Satisfy pour déterminer la manière dont ces deux modes de restrictions interagissent.

Note

Les directives fournies par le module mod_access_compat sont devenues obsolètes depuis la refonte du module mod_authz_host. Mélanger d'anciennes directives comme Order, Allow ou Deny avec des nouvelles comme Require est techniquement possible mais déconseillé. En effet, mod_access_compat a été conçu pour supporter des configurations ne contenant que des anciennes directives afin de faciliter le passage à la version 2.4. Voir le document upgrading pour plus de détails.

En général, les directives de restriction d'accès s'appliquent à toutes les méthodes d'accès (GET, PUT, POST, etc...). C'est d'ailleurs ce que l'on souhaite dans la plupart des cas. Il est cependant possible de restreindre certaines méthodes, alors que les autres méthodes ne se verront imposée aucune restriction, en regroupant les directives à l'intérieur d'une section <Limit>.

Fusion des sections de configuration

Lorsqu'une directive fournie par ce module est utilisée dans une nouvelle section de configuration, cette dernière n'hérite d'aucune directive définie dans une section précédente.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive Allow

Description:Spécifie quels hôtes peuvent accéder à une certaine zone du serveur
Syntaxe: Allow from all|hôte|env=[!]variable d'environnement [hôte|env=[!]variable d'environnement] ...
Contexte:répertoire, .htaccess
Surcharges autorisées:Limit
Statut:Extension
Module:mod_access_compat

La directive Allow permet de définir quels hôtes ont le droit d'accéder à une certaine partie du serveur. On peut contrôler l'accès par nom d'hôte, adresse IP, intervalle d'adresses IP, ou toute autre caractéristique de la requête client enregistrée dans les variables d'environnement.

Le premier argument de cette directive est toujours from. Les arguments suivants peuvent prendre trois formes différentes. Si Allow from all est spécifié, tout hôte se voit accordé l'accès, en tenant compte des directives Deny et Order comme décrit plus loin. Pour ne permettre l'accès au serveur qu'à un hôte ou un groupe d'hôtes particuliers, on peut spécifier un nom d'hôte sous une des formes suivantes :

Un nom de domaine (partiel)
Allow from example.org
Allow from .net example.edu

Les hôtes dont les noms correspondent ou se terminent par la chaîne spécifiée ont l'autorisation d'accès. Seules les composantes entières du nom d'hôte doivent correspondre ; ainsi, dans l'exemple ci-dessus, foo.example.org correspondra, mais fooexample.org ne conviendra pas. Avec cette configuration, Apache httpd va effectuer une double recherche DNS sur l'adresse IP du client, sans tenir compte de la définition de la directive HostnameLookups. Tout d'abord, une recherche DNS inverse sur l'adresse IP est effectuée pour déterminer le nom d'hôte associé, puis une recherche directe sur le nom d'hôte est effectuée afin de s'assurer qu'il correspond bien à l'adresse IP originale. L'accès ne sera accordé que si le nom d'hôte correspond et si les recherches DNS inverse et directe concordent.

Une adresse IP complète
Allow from 10.1.2.3
Allow from 192.168.1.104 192.168.1.205

L'adresse IP d'un hôte auquel on a accordé l'accès

Une adresse IP partielle
Allow from 10.1
Allow from 10 172.20 192.168.2

De un à trois des premiers octets d'une adresse IP, afin de restreindre l'accès à un sous-réseau.

Une paire réseau/masque de sous-réseau
Allow from 10.1.0.0/255.255.0.0

Un réseau a.b.c.d, et un masque de sous-réseau w.x.y.z, pour une définition plus précise de la restriction d'accès imposée à un sous-réseau.

Une spécification CIDR réseau/nnn
Allow from 10.1.0.0/16

Identique au cas précédent, mis à part que le masque est constitué des nnn bits de poids fort.

Notez que les trois derniers exemples désignent le même ensemble d'hôtes.

On peut spécifier des adresses et sous-réseaux IPv6 de la manière suivante :

Allow from 2001:db8::a00:20ff:fea7:ccea
Allow from 2001:db8::a00:20ff:fea7:ccea/10

Le troisième format d'argument de la directive Allow permet de contrôler l'accès au serveur en fonction de l'existence d'une variable d'environnement. Lorsque Allow from env=variable d'environnement est spécifié, la requête est autorisée si la variable d'environnement variable d'environnement existe. En revanche, lorsque Allow from env=!env-variable est spécifié, la requête est autorisée si la variable d'environnement variable d'environnement n'existe pas. Le serveur permet de définir avec souplesse des variables d'environnement en se basant sur les caractéristiques de la requête client et en utilisant les directives fournies par le module mod_setenvif. Ainsi, on peut utiliser la directive Allow pour permettre l'accès en fonction de paramètres comme le User-Agent (type de navigateur) des clients, le Referer, ou d'autres champs d'en-tête de la requête 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>

Dans cet exemple, les navigateurs dont la chaîne user-agent commence par KnockKnock/2.0 se verront accorder l'accès, alors que tous les autres seront rejetés.

Fusion des sections de configuration

Lorsqu'une directive fournie par ce module est utilisée dans une nouvelle section de configuration, cette dernière n'hérite d'aucune directive définie dans une section précédente.

top

Directive Deny

Description:Définit quels hôtes ne sont pas autorisés à accéder au serveur
Syntaxe: Deny from all|hôte|env=[!]variable d'environnement [hôte|env=[!]variable d'environnement] ...
Contexte:répertoire, .htaccess
Surcharges autorisées:Limit
Statut:Extension
Module:mod_access_compat

Cette directive permet de restreindre l'accès au serveur en fonction du nom d'hôte, de l'adresse IP ou de variables d'environnement. Les arguments de la directive Deny sont identiques aux arguments de la directive Allow.

top

Directive Order

Description:Définit le statut d'accès par défaut et l'ordre dans lequel les directives Allow et Deny sont évaluées.
Syntaxe: Order ordre
Défaut:Order Deny,Allow
Contexte:répertoire, .htaccess
Surcharges autorisées:Limit
Statut:Extension
Module:mod_access_compat

La directive Order, associée aux directives Allow et Deny, implémente un système de contrôle d'accès en trois passes. Au cours de la première passe, ce sont soit toutes les directives Allow, soit toutes les directives Deny qui sont traitées, selon la définition de la directive Order. Le reste des directives (Deny ou Allow) est traité au cours de la seconde passe. La troisième passe s'applique à toutes les requêtes qui ne sont concernées par aucune des deux premières passes.

Notez que toutes les directives Allow et Deny sont traitées, à la différence d'un pare-feu classique où seule la première règle qui correspond est utilisée. La dernière directive qui correspond s'applique ( à la différence là encore d'un pare-feu classique). De plus, l'ordre dans lequel les lignes apparaissent dans le fichier de configuration n'a pas d'incidence -- toutes les lignes Allow sont considérées comme un groupe, toutes les lignes Deny comme un autre, et le statut par défaut a son existence propre.

Ordre peut être :

Allow,Deny
Dans un premier temps, toutes les directives Allow sont évaluées ; au moins une d'entre elles doit correspondre, sinon la requête est rejetée. Ensuite, toutes les directives Deny sont évaluées. Si au moins l'une d'entre elles correspond, la requête est rejetée. Enfin, toute requête qui ne correspond à aucune directive Allow ou Deny est rejetée par défaut.
Deny,Allow
Dans un premier temps, toutes les directives Deny sont évaluées ; Si au moins une d'entre elles correspond, la requête est rejetée, à moins qu'elle corresponde aussi à une directive Allow. Toute requête qui ne correspond à aucune directive Allow ou Deny est autorisée.
Mutual-failure
Cet argument a le même effet que Allow,Deny et est devenu de ce fait obsolète.

Les mots-clés ne peuvent être séparés que par des virgules ; aucun espace ne doit s'intercaler entre eux.

Match Résultat Allow,Deny Résultat Deny,Allow
Correspond à Allow seulement Requête autorisée Requête autorisée
Correspond à Deny seulement Requête rejetée Requête rejetée
Aucune correspondance Par défaut la seconde directive : rejet Par défaut la seconde directive : autorisation
Correspond à Allow & Deny La dernière correspondance l'emporte : rejet La dernière correspondance l'emporte : autorisation

Dans cet exemple, tous les hôtes du domaine example.org ont l'autorisation d'accès ; tous les autres voient leur accès refusé.

Order Deny,Allow
Deny from all
Allow from example.org

Dans l'exemple suivant, tous les hôtes du domaine example.org ont l'autorisation d'accès, sauf ceux du sous-domaine foo.example.org qui voient leur accès refusé. Tous les hôtes qui ne sont pas dans le domaine example.org sont rejetés car le statut par défaut est positionné sur Deny, et consiste donc en un refus d'accès.

Order Allow,Deny
Allow from example.org
Deny from foo.example.org

Par contre, si la valeur de la directive Order, dans l'exemple précédent, est Deny,Allow, tout le monde a l'autorisation d'accès. Ceci est dû au fait que Allow from example.org sera évalué en dernier, sans tenir compte de l'ordre réel dans lequel les directives apparaissent dans le fichier de configuration, et va l'emporter sur Deny from foo.example.org. Tout hôte qui n'est pas dans le domaine example.org aura aussi l'autorisation d'accès car le statut par défaut est positionné sur Allow et constitue donc une autorisation d'accès.

La présence d'une directive Order peut affecter le contrôle d'accès à une partie du serveur même en l'abscence de directives Allow et Deny associées, à cause de son influence sur le statut par défaut. Par exemple,

<Directory "/www">
    Order Allow,Deny
</Directory>

va interdire tout accès au répertoire /www à cause du statut d'accès par défaut qui est défini à Deny.

La directive Order ne contrôle l'ordre dans lequel sont traitées les directives d'accès qu'au cours de chaque phase du traitement de la configuration du serveur. Ceci implique, par exemple, qu'une directive Allow ou Deny située dans une section <Location> sera toujours évaluée après une directive Allow ou Deny située dans une section <Directory> ou un fichier .htaccess, sans tenir compte de la définition de la directive Order. Pour plus de détails à propos de la fusion des sections de configuration, voir le document Comment fonctionnent les sections Directory, Location et Files.

Fusion des sections de configuration

Lorsqu'une directive fournie par ce module est utilisée dans une nouvelle section de configuration, cette dernière n'hérite d'aucune directive définie dans une section précédente.

top

Directive Satisfy

Description:Interaction entre le contrôle d'accès en fonction de l'hôte et l'authentification utilisateur
Syntaxe:Satisfy Any|All
Défaut:Satisfy All
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_access_compat
Compatibilité:Affecté par <Limit> et <LimitExcept> à partir de la version 2.0.51

Politique d'accès dans le cas où on utilise à la fois Allow et Require. L'argument est soit All, soit Any. L'utilisation de cette directive n'a de sens que si l'accès à une zone particulière du serveur est restreinte par utilisateur/mot de passe et en fonction de l'adresse IP de l'hôte client. Dans ce cas, par défaut (All), le client doit satisfaire à la restriction d'adresse, et fournir un couple utilisateur/mot de passe valide. Avec l'argument Any, le client se verra accorder l'accès s'il satisfait à la restriction d'adresse ou fournit un couple utilisateur/mot de passe valide. On peut utiliser cette dernière définition pour restreindre l'accès à une zone par mot de passe, mais accorder l'accès aux clients possédant certaines adresses IP sans qu'ils aient à fournir de mot de passe.

Par exemple, si vous souhaitez que les utilisateurs de votre réseau accèdent à une zone de votre site web sans restriction, mais que l'accès à cette zone nécessite un mot de passe pour les autres utilisateurs, vous pouvez utiliser une configuration du style :

Require valid-user
Allow from 192.168.1
Satisfy Any

Une autre utilisation fréquente de la directive Satisfy est l'allègement des restrictions d'accès à un sous-répertoire par rapport aux restrictions d'accès au répertoire parent :

<Directory "/var/www/private">
    Require valid-user
</Directory>

<Directory "/var/www/private/public">
    Allow from all
    Satisfy Any
</Directory>

Dans l'exemple ci-dessus, l'accès au répertoire /var/www/private nécessitera une authentification, alors que l'accès au répertoire /var/www/private/public sera accordé sans restriction.

Depuis la version 2.0.51, les directives Satisfy peuvent être restreintes à certaines méthodes particulières à l'aide des sections <Limit> et <LimitExcept>.

Fusion des sections de configuration

Lorsqu'une directive fournie par ce module est utilisée dans une nouvelle section de configuration, cette dernière n'hérite d'aucune directive définie dans une section précédente.

Voir aussi

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_allowmethods.html.fr.utf80000664000175100017510000002063414740503670023343 0ustar covenercovener mod_allowmethods - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_allowmethods

Langues Disponibles:  en  |  fr 

Description:Ce module permet de restreindre aisément les méthodes HTTP pouvant être utilisées sur le serveur
Statut:Expérimental
Identificateur de Module:allowmethods_module
Fichier Source:mod_allowmethods.c
Compatibilité:Disponible à partir de la version 2.3 du serveur HTTP Apache

Sommaire

Ce module permet de restreindre aisément les méthodes HTTP pouvant être utilisées sur le serveur. La configuration la plus courante est du style :

<Location "/">
   AllowMethods GET POST OPTIONS
</Location>
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive AllowMethods

Description:Restreint l'accès aux méthodes HTTP spécifiées
Syntaxe:AllowMethods reset|HTTP-method [HTTP-method]...
Défaut:AllowMethods reset
Contexte:répertoire
Statut:Expérimental
Module:mod_allowmethods

Les noms des méthodes HTTP sont sensibles à la casse, et sont en général définis en majuscules, comme dans les RFCs. Les méthodes GET et HEAD sont considérées comme équivalentes. Le mot-clé reset permet de désactiver mod_allowmethods dans les niveaux inférieurs d'imbrication :

<Location "/svn">
   AllowMethods reset
</Location>

Avertissement

La méthode TRACE ne peut pas être rejetée par ce module ; pour ce faire, vous devez utiliser la directive TraceEnable.

Le module mod_allowmethods a été écrit pour remplacer l'implémentation "bricolée" des directives Limit et LimitExcept.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_digest.html.fr.utf80000664000175100017510000005363214740503670023145 0ustar covenercovener mod_auth_digest - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_auth_digest

Langues Disponibles:  en  |  fr  |  ko 

Description:Authentification utilisateur utilisant les condensés MD5
Statut:Extension
Identificateur de Module:auth_digest_module
Fichier Source:mod_auth_digest.c

Sommaire

Ce module implémente l'authentification HTTP basée sur les condensés MD5 (RFC2617), et fournit une alternative à mod_auth_basic en ne transmettant plus le mot de passe en clair. Cependant, cela ne suffit pas pour améliorer la sécurité de manière significative par rapport à l'authentification basique. En outre, le stockage du mot de passe sur le serveur est encore moins sûr dans le cas d'une authentification à base de condensé que dans le cas d'une authentification basique. C'est pourquoi l'utilisation de l'authentification basique associée à un chiffrement de la connexion via mod_ssl constitue une bien meilleure alternative.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Utilisation de l'authentification à base de condensés

Pour utiliser l'authentification à base de condensés MD5, vous devez simplement remplacer AuthType Basic et AuthBasicProvider respectivement par AuthType Digest et AuthDigestProvider lorsque vous configurez l'authentification, puis ajouter une directive AuthDigestDomain contenant au moins la(les) URI(s) racine(s) de la zone à protéger.

On peut créer les fichiers utilisateur appropriés (au format texte) à l'aide de l'outil htdigest.

Exemple :

<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

L'authentification à base de condensé a été conçue pour améliorer la sécurité par rapport à l'authentification basique, mais il s'avère que ce but n'a pas été atteint. Un attaquant de type "man-in-the-middle" peut facilement forcer le navigateur à revenir à une authentification basique. Même une oreille indiscrète passive peut retrouver le mot de passe par force brute avec les moyens modernes, car l'algorithme de hashage utilisé par l'authentification à base de condensé est trop rapide. Autre problème, le stockage des mots de passe sur le serveur n'est pas sûr. Le contenu d'un fichier htdigest volé peut être utilisé directement pour l'authentification à base de condensé. Il est donc fortement recommandé d'utiliser mod_ssl pour chiffrer la connexion.

mod_auth_digest ne fonctionne correctement que sur les plates-formes où APR supporte la mémoire partagée.

top

Directive AuthDigestAlgorithm

Description:Sélectionne l'algorithme utilisé pour calculer les condensés du défit et de sa réponse
Syntaxe:AuthDigestAlgorithm MD5|MD5-sess
Défaut:AuthDigestAlgorithm MD5
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_auth_digest

La directive AuthDigestAlgorithm permet de sélectionner l'algorithme utilisé pour calculer les condensés du défit et de sa réponse.

MD5-sess n'est pas encore correctement implémenté.
top

Directive AuthDigestDomain

Description:Les URIs qui se trouvent dans le même espace de protection concernant l'authentification à base de condensés
Syntaxe:AuthDigestDomain URI [URI] ...
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_auth_digest

La directive AuthDigestDomain vous permet de spécifier un ou plusieurs URIs se trouvant dans le même espace de protection (c'est à dire utilisant le même utilisateur/mot de passe et se trouvant dans le même domaine). Les URIs spécifiés sont des préfixes ; le client doit savoir que tous les URIs situés sous ces préfixes seront protégés par le même utilisateur/mot de passe. Les URIs peuvent être soit des URIs absolus (c'est à dire avec protocole, nom serveur, port, etc...), soit des URIs relatifs.

Cette directive doit toujours être présente et contenir au moins le(s) URI(s) racine(s) pour cet espace. Dans le cas contraire, le client va envoyer un en-tête d'autorisation avec chaque requête à destination de ce serveur.

Les URIs spécifiés peuvent aussi référencer différents serveurs, auquel cas les clients (qui sont à même de le comprendre) vont partager l'utilisateur/mot de passe entre plusieurs serveurs sans le demander à l'utilisateur à chaque fois.

top

Directive AuthDigestNonceLifetime

Description:Durée de validité du nombre à valeur unique du serveur (nonce)
Syntaxe:AuthDigestNonceLifetime secondes
Défaut:AuthDigestNonceLifetime 300
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_auth_digest

La directive AuthDigestNonceLifetime permet de contrôler la durée de validité du nombre à valeur unique du serveur (nonce). Lorsque le client contacte le serveur en utilisant un nonce dont la validité a expiré, le serveur renvoie un code d'erreur 401 avec stale=true. Si secondes est supérieur à 0, il spécifie la durée de validité du nonce ; il est en général déconseillé d'affecter à cet argument une valeur inférieure à 10 secondes. Si secondes est inférieur à 0, le nonce n'expire jamais.

top

Directive AuthDigestProvider

Description:Définit le(s) fournisseurs(s) d'authentification pour la zone du site web concernée
Syntaxe:AuthDigestProvider nom fournisseur [nom fournisseur] ...
Défaut:AuthDigestProvider file
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_auth_digest

La directive AuthDigestProvider permet de définir quel fournisseur d'authentification sera utilisé pour authentifier les utilisateurs pour la zone du site web concernée. Assurez-vous que le module implémentant le fournisseur d'authentification choisi soit bien présent dans le serveur. Le fournisseur par défaut file est implémenté par le module mod_authn_file.

Voir mod_authn_dbm, mod_authn_file, mod_authn_dbd et mod_authn_socache pour la liste des fournisseurs disponibles.

top

Directive AuthDigestQop

Description:Détermine le niveau de protection fourni par l'authentification à base de condensé
Syntaxe:AuthDigestQop none|auth|auth-int [auth|auth-int]
Défaut:AuthDigestQop auth
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_auth_digest

La directive AuthDigestQop permet de définir le niveau de protection fourni. auth ne fournit que l'authentification (nom utilisateur/mot de passe) ; auth-int fournit l'authentification plus un contrôle d'intégrité (un condensé MD5 de l'entité est aussi calculé et vérifié) ; avec none, le module va utiliser l'ancien algorithme de condensés RFC-2069 (qui n'effectue pas de contrôle d'intégrité). On peut spécifier à la fois auth et auth-int, auquel cas c'est le navigateur qui va choisir lequel des deux utiliser. none ne doit être utilisé que dans le cas où le navigateur ne serait pas à même (pour une raison ou pour une autre) de relever le défit qu'il recevrait si un autre niveau de protection était défini.

auth-int n'est pas encore implémenté.
top

Directive AuthDigestShmemSize

Description:La quantité de mémoire partagée à allouer afin de conserver les informations à propos des clients
Syntaxe:AuthDigestShmemSize taille
Défaut:AuthDigestShmemSize 1000
Contexte:configuration globale
Statut:Extension
Module:mod_auth_digest

La directive AuthDigestShmemSize permet de définir la quantité de mémoire partagée à allouer au démarrage du serveur afin de conserver les informations à propos des clients. Notez que le segment de mémoire partagée ne peut pas être défini à une taille inférieure à l'espace nécessaire pour conserver les informations à propos d'un client. Cette valeur dépend de votre système. Si vous voulez en déterminer la valeur exacte, vous pouvez simplement définir AuthDigestShmemSize à 0 et consulter le message d'erreur que renverra le serveur lorsqu'on essaiera de le démarrer.

L'argument size s'exprime par défaut en octets, mais vous pouvez suffixer le nombre par un K ou un M pour spécifier respectivement des KiloOctets ou des MégaOctets. Par exemple, les directives qui suivent sont toutes équivalentes :

AuthDigestShmemSize 1048576
AuthDigestShmemSize 1024K
AuthDigestShmemSize 1M

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_core.html.fr.utf80000664000175100017510000004311614740503670022770 0ustar covenercovener mod_authn_core - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authn_core

Langues Disponibles:  en  |  fr 

Description:Le noyau de l'authentification
Statut:Base
Identificateur de Module:authn_core_module
Fichier Source:mod_authn_core.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

Ce module fournit le coeur des fonctionnalités d'authentification permettant d'accorder ou de refuser l'accès à certaines zones du site web. Les directives fournies par le module mod_authn_core sont communes à tous les fournisseurs d'authentification.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Création d'alias de fournisseurs d'authentification

Il est possible de créer des fournisseurs d'authentification étendus dans le fichier de configuration et de leur assigner un alias. Le fournisseur ainsi nommé peut alors être référencé à l'aide des directives AuthBasicProvider ou AuthDigestProvider tout comme un fournisseur d'authentification de base. Outre la possibilité de créer et attribuer un alias à un fournisseur étendu, le même fournisseur d'authentification peut aussi être référencé par plusieurs sections relatives à une zone du site web.

Exemples

Cet exemple vérifie les mots de passe dans deux fichiers textes différents.

Vérification dans plusieurs fichiers de mots de passe au format texte

# Première vérification
<AuthnProviderAlias file file1>
    AuthUserFile "/www/conf/passwords1"
</AuthnProviderAlias>

# Vérification suivante
<AuthnProviderAlias file file2>   
    AuthUserFile "/www/conf/passwords2"
</AuthnProviderAlias>

<Directory "/var/web/pages/secure">
    AuthBasicProvider file1 file2
    
    AuthType Basic
    AuthName "Protected Area"
    Require valid-user
</Directory>

Dans l'exemple ci-dessous, deux fournisseurs d'authentification ldap sont créés à partir du fournisseur ldap de base, et se voient attribuer un alias. L'authentification d'une même zone peut alors être traitée par plusieurs serveurs ldap :

Vérification auprès de plusieurs serveurs LDAP

<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">
    
    AuthBasicProvider ldap-other-alias  ldap-alias1
    
    AuthType Basic
    AuthName LDAP_Protected Place
    Require valid-user
    # Notez que Require ldap-* ne fonctionnerait pas ici, car
    # AuthnProviderAlias ne fournit pas de configuration pour les
    # fournisseurs d'autorisation implémentés dans le même module que le
    # fournisseur d'authentification.
</Directory>
top

Directive AuthName

Description:L'identifiant de l'autorisation à utiliser avec l'authentification HTTP
Syntaxe:AuthName domaine d'autorisation
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authn_core

Cette directive permet de définir l'identifiant d'autorisation pour un répertoire. Cet identifiant est fourni au client de façon à ce qu'il sache quels nom d'utilisateur et mot de passe envoyer. AuthName accepte un seul argument ; s'il contient des espaces, il doit être entouré de guillemets. Pour pouvoir fonctionner, la directive AuthName doit être utilisée en combinaison avec les directives AuthType et Require, ainsi que des directives comme AuthUserFile et AuthGroupFile.

Par exemple :

AuthName "Top Secret"

La chaîne fournie comme argument à AuthName apparaîtra dans la boîte de dialogue d'authentification pour la plupart des navigateurs.

A partir de la version 2.4.55 du serveur HTTP Apache, il est possible de définir cette directive en utilisant la syntaxe des expressions pour spécifier l'identifiant d'autorisation de manière dynamique.

Exemple :

AuthName "%{HTTP_HOST}"

Voir aussi

top

Directive <AuthnProviderAlias>

Description:Regroupe un ensemble de directives qui constituent une extension d'un fournisseur d'authentification de base et lui attribue l'alias spécifié
Syntaxe:<AuthnProviderAlias alias-fournisseur> ... </AuthnProviderAlias>
Contexte:configuration globale
Statut:Base
Module:mod_authn_core

Les balises <AuthnProviderAlias> et </AuthnProviderAlias> permettent de regrouper un ensemble de directives d'authentification qui seront référencées par l'alias spécifié à l'aide des directives AuthBasicProvider ou AuthDigestProvider.

Cette directive n'a aucune influence sur le processus d'autorisation, même pour les modules qui fournissent à la fois l'authentification et l'autorisation.
top

Directive AuthType

Description:Type d'authentification utilisateur
Syntaxe:AuthType None|Basic|Digest|Form
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authn_core

Cette directive permet de définir le type d'authentification utilisateur pour un répertoire. Les types d'authentification disponibles sont None, Basic (implémenté par mod_auth_basic), Digest (implémenté par mod_auth_digest), et Form (implémenté par mod_auth_form).

Pour mettre en oeuvre l'authentification, vous devez aussi utiliser les directives AuthName et Require. De plus, le serveur doit pouvoir disposer d'un module fournisseur d'authentification comme mod_authn_file et d'un module d'autorisation comme mod_authz_user.

Le type d'authentification None désactive l'authentification. Lorsqu'une authentification est définie, elle est en général héritée par chacune des sections de configuration qui suivent, à moins qu'un autre type d'authentification ne soit spécifié. Si l'on ne souhaite pas mettre en oeuvre d'authentification pour une sous-section d'une section authentifiée, on doit utiliser le type d'authentification None ; dans l'exemple suivant, les clients peuvent accéder au répertoire /www/docs/public sans devoir s'authentifier :

<Directory "/www/docs">
    AuthType Basic
    AuthName Documents
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require valid-user
</Directory>

<Directory "/www/docs/public">
    AuthType None
    Require all granted
</Directory>

A partir de la version 2.4.55, il est possible de définir cette directive en utilisant la syntaxe des expressions pour spécifier le type d'authentification de manière dynamique.

Veuillez noter que, lorsque l'authentification n'est pas activée, les clients qui se sont déjà authentifiés pour une autre zone de l'arborescence du site continueront en général à envoyer des en-tête d'authentification HTTP ou des cookies avec chaque requête, sans se préoccuper de savoir si le serveur nécessite vraiment une authentification pour chaque ressource.

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_file.html.fr.utf80000664000175100017510000003033414740503670022755 0ustar covenercovener mod_authn_file - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authn_file

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Authentification utilisateur à l'aide de fichiers texte
Statut:Base
Identificateur de Module:authn_file_module
Fichier Source:mod_authn_file.c
Compatibilité:Disponible depuis les versions 2.1 et supérieures d'Apache

Sommaire

Ce module permet aux frontaux d'authentification comme mod_auth_digest et mod_auth_basic d'authentifier les utilisateurs en les recherchant dans des fichiers de mots de passe au format texte. mod_authn_dbm fournit une fonctionnalité similaire.

Lorsqu'on utilise mod_auth_basic ou mod_auth_digest, ce module peut être invoqué en affectant la valeur file à la directive AuthBasicProvider ou AuthDigestProvider.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive AuthUserFile

Description:Définit le nom d'un fichier texte pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe
Syntaxe:AuthUserFile chemin-fichier
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Base
Module:mod_authn_file

La directive AuthUserFile permet de définir le nom d'un fichier texte pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe. chemin-fichier est le chemin vers le fichier des utilisateurs. S'il n'est pas absolu, il est considéré comme relatif au répertoire défini par la directive ServerRoot.

Chaque ligne du fichier des utilisateurs se compose du nom de l'utilisateur, du caractère ':' et du mot de passe chiffré. Si le même identifiant utilisateur est référencé plusieurs fois, mod_authn_file utilisera la première occurrence pour vérifier le mot de passe.

Le format du mot de passe chiffré dépend du frontal d'authentification utilisé (par exemple mod_auth_basic ou mod_auth_digest). Voir la documentation sur les Formats de mots de passe pour plus de détails.

Pour mod_auth_basic, utilisez le programme htpasswd fourni avec la distribution binaire, mais que vous trouverez aussi dans le répertoire src/support de l'arborescence des sources. Voir sa page de manuel pour plus de détails. En bref :

On crée un fichier de mots de passe nom-fichier avec nom-utilisateur comme identifiant initial. Le mot de passe correspondant sera alors demandé :

htpasswd -c nom-fichier nom-utilisateur

Pour ajouter ou modifier nom-utilisateur2 dans le fichier de mots de passe nom-fichier :

htpasswd nom-fichier nom-utilisateur2

Noter qu'une recherche dans de grands fichiers texte peut être très longue ; dans ce cas, il vaut mieux utiliser les fichiers DBM avec la directive AuthDBMUserFile.

Pour mod_auth_digest, vous devez utiliser le programme htdigest. Notez que vous ne pouvez pas mélanger des données utilisateur pour l'Authentification HTTP à base de condensé et des données pour l'Authentification de Base dans le même fichier.

Sécurité

Assurez-vous que le fichier AuthUserFile soit bien stocké en dehors de l'arborescence des documents du serveur web. Ne placez pas ce fichier dans le répertoire qu'il protège. Dans le cas contraire, les clients seraient en mesure de télécharger le fichier des mots de passe.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgi.html.fr.utf80000664000175100017510000005335414740503670021410 0ustar covenercovener mod_cgi - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_cgi

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Exécution des scripts CGI
Statut:Base
Identificateur de Module:cgi_module
Fichier Source:mod_cgi.c

Sommaire

Tout fichier pris en compte par le gestionnaire cgi-script sera traité en tant que script CGI et exécuté par le serveur, sa sortie étant renvoyée au client. Les fichiers sont associés à ce gestionnaire soit parce qu'ils possèdent un nom contenant une extension définie par la directive AddHandler, soit parce qu'ils se situent dans un répertoire défini par une directive ScriptAlias.

Comme introduction à l'utilisation des scripts CGI avec Apache, voir notre tutoriel Les contenus dynamiques avec CGI.

Il est recommandé d'utiliser le module mod_cgid à la place de mod_cgi lorsqu'on utilise un module MPM multi-threadé sous Unix. Vus de l'utilisateur, les deux modules sont pratiquement identiques.

À des fins de compatibilité ascendante, le gestionnaire cgi-script sera aussi activé pour tout fichier possédant le type MIME application/x-httpd-cgi. L'utilisation du type MIME magic est obsolète.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Les variables d'environnement CGI

Le serveur va définir les variables d'environnement CGI comme décrit dans la Spécification CGI, de la manière suivante :

PATH_INFO
Cette variable ne sera pas disponible si la directive AcceptPathInfo est explicitement définie à off. Par défaut, si la directive AcceptPathInfo n'est pas définie, mod_cgi acceptera des informations de chemin (en ajoutant /infos/chemin après le nom du script dans l'URI), alors que le serveur de base retournera une erreur 404 NOT FOUND pour les requêtes contenant des informations de chemin supplémentaires. Ne pas définir la directive AcceptPathInfo a le même effet sur les requêtes avec mod_cgi que de la définir à On.
REMOTE_HOST
Cette variable ne sera définie que si la directive HostnameLookups est définie à on (elle est à off par défaut), et si une recherche DNS inverse sur l'adresse IP de l'hôte client aboutit effectivement à un nom d'hôte.
REMOTE_IDENT
Cette variable ne sera définie que si la directive IdentityCheck est définie à on, et si l'hôte client supporte le protocole ident. Notez que l'on ne peut accorder une confiance aveugle au contenu de cette variable car il peut être aisément falsifié, et si un mandataire s'intercale entre le client et le serveur, il est totalement inutilisable.
REMOTE_USER
Cette variable ne sera définie que si le script CGI fait l'objet d'une authentification.

Ce module utilise aussi les fonctions de base ap_add_common_vars et ap_add_cgi_vars pour ajouter des variables d'environnement comme :

DOCUMENT_ROOT
Prend la valeur définie par la directive DocumentRoot.
SERVER_NAME
Le nom de domaine pleinement qualifié pour la requête considérée
SERVER_ADDR
L'adresse IP du serveur virtuel qui traite la requête
SERVER_ADMIN
Prend la valeur définie par la directive ServerAdmin.

Pour une liste exhaustive de ces variables, vous pouvez écrire un script CGI basique qui extrait toutes les variables d'environnement passées par Apache selon un format adapté.

top

Débogage des scripts CGI

Le débogage des scripts CGI était difficile par le passé, principalement parce qu'il n'était pas possible d'étudier la sortie (sortie standard et erreurs) des scripts dont l'exécution échouait. Les directives qui suivent permettent une journalisation plus détaillée des erreurs.

Format du fichier journal CGI

Lorsqu'il est configuré, le journal des erreurs CGI enregistre la sortie de tout programme CGI dont l'exécution ne s'effectue pas correctement. Un script CGI dont l'exécution échoue provoque la journalisation d'une grande quantité d'informations. Les deux premières lignes possèdent toujours le format suivant :

%% [date] requête
%% état HTTP nom du script CGI

Si le script CGI n'a pas pu démarrer, le fichier journal contiendra les deux lignes supplémentaires suivantes :

%%erreur
message d'erreur

Par contre, si l'erreur provient du renvoi par le script d'informations incorrectes dans les en-têtes (dû souvent à une bogue du script), les informations suivantes sont journalisées :

%requête
Tous les en-têtes de requête HTTP reçus
Les entités POST ou PUT (s'il en existe)
%réponse
Tous les en-têtes générés par le script CGI
%stdout
la sortie standard CGI
%stderr
la sortie d'erreurs standard CGI

(Les parties %stdout et %stderr seront absentes si le script n'a rien envoyé sur la sortie standard ou la sortie d'erreurs).

top

Directive CGIScriptTimeout

Description:Le temps d'attente maximum pour une sortie du programme CGI
Syntaxe:CGIScriptTimeout time[s|ms]
Défaut:La valeur par défaut de la directive Timeout lorsqu'elle n'est pas définie
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Base
Module:mod_cgi
Compatibilité:Disponible à partir de la version 2.4.59 du serveur HTTP Apache.

Cette directive permet de limiter le temps d'attente jusqu'à une prochaine sortie du programme CGI. Si ce temps est dépassé, le traitement de la requête et l'exécution du programme CGI sont terminés.

Exemple

CGIScriptTimeout 20
top

Directive ScriptLog

Description:Chemin du fichier journal des erreurs du script CGI
Syntaxe:ScriptLog chemin fichier
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_cgi, mod_cgid

La directive ScriptLog permet de définir le chemin du fichier journal des erreurs du script CGI. Si cette directive n'est pas définie, aucune journalisation des erreurs n'est effectuée. Si elle est définie, toute erreur CGI sera enregistrée dans le fichier dont le nom est fourni en argument. S'il s'agit d'un chemin de fichier relatif, il est considéré par rapport au répertoire défini par la directive ServerRoot.

Exemple

ScriptLog logs/cgi_log

Ce journal sera ouvert par l'utilisateur sous lequel les processus enfants s'exécutent, c'est à dire l'utilisateur spécifié par la directive du serveur User. Ceci implique que le répertoire dans lequel se trouve le journal doit être accessible en écriture pour cet utilisateur, ou bien que le fichier est créé manuellement et accessible en écriture pour cet utilisateur. Si vous placez le journal du script dans votre répertoire principal des journaux, ne modifiez JAMAIS les permissions de ce dernier afin de le le rendre accessible en écriture par l'utilisateur sous lequel les processus enfants s'exécutent.

Notez que l'on ne doit activer la journalisation des scripts qu'à des fins de débogage lors de l'écriture de scripts CGI, et non de manière permanente sur un serveur en production. Elle n'est pas optimisée en terme de performances et d'efficacité, et peut présenter des problèmes de sécurité si on l'utilise dans un cadre autre que celui pour lequel elle a été conçue.

top

Directive ScriptLogBuffer

Description:Taille maximale des requêtes PUT ou POST qui seront enregistrées dans le journal du script
Syntaxe:ScriptLogBuffer octets
Défaut:ScriptLogBuffer 1024
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_cgi, mod_cgid

Cette directive permet de limiter la taille du corps de toute entité PUT ou POST qui sera enregistrée dans le journal, afin de prévenir une croissance trop importante et trop rapide du fichier journal due à la réception de corps de requête de grandes tailles. Cette directive permet de modifier cette taille maximale, dont la valeur par défaut est de 1024 octets.

top

Directive ScriptLogLength

Description:Taille maximale du fichier journal des scripts CGI
Syntaxe:ScriptLogLength octets
Défaut:ScriptLogLength 10385760
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_cgi, mod_cgid

La directive ScriptLogLength permet de définir la taille maximale du fichier journal des scripts CGI. Comme le fichier journal accumule une grande quantité d'informations par erreur CGI (tous les en-têtes de la requête, toutes les sorties du script), il peut vite atteindre une grande taille. En limitant la taille du fichier, cette directive permet d'éviter les problèmes que causerait sa croissance sans limites. Lorsque le fichier a atteint cette taille maximale, plus aucune information n'y est enregistrée.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_data.html.fr.utf80000664000175100017510000001727114740503670021555 0ustar covenercovener mod_data - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_data

Langues Disponibles:  en  |  fr 

Description:Convertit un corps de réponse en URL de type données RFC2397
Statut:Extension
Identificateur de Module:data_module
Fichier Source:mod_data.c
Compatibilité:Disponible depuis la version 2.3 du serveur HTTP Apache

Sommaire

Ce module permet de convertir une réponse en URL de type données RFC2397.

Les URLs de type données peuvent être incluses en ligne dans les pages web via le module mod_include par exemple, afin d'éviter aux clients d'avoir à effectuer des connexions séparées pour éventuellement extraire un grand nombre de petites images. Les URLs de type données peuvent aussi être incluses dans des pages générées par langages de scripting tels que PHP.

Un exemple d'URL de type données

data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
hhx4dbgYKAAA7

Le filtre n'accepte aucun paramètre, et peut être ajouté à la pile des filtres via la directive SetOutputFilter, ou toute autre directive supportée par le module mod_filter.

Configuration du filtre

<Location "/data/images">
    SetOutputFilter DATA
</Location>
Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav_lock.html.fr.utf80000664000175100017510000002451414740503670022424 0ustar covenercovener mod_dav_lock - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_dav_lock

Langues Disponibles:  en  |  fr  |  ja 

Description:Module de verrouillage générique pour mod_dav
Statut:Extension
Identificateur de Module:dav_lock_module
Fichier Source:mod_dav_lock.c
Compatibilité:Disponible depuis la version 2.1 d'Apache

Sommaire

ce module implémente une API de verrouillage générique que tout fournisseur support de mod_dav peut utiliser. Son activation nécessite l'utilisation de mod_dav. Mais sans fournisseur support pour l'utiliser, il n'est d'aucun service et ne doit pas être chargé dans le serveur. mod_dav_svn, le module qui implémente le fournisseur subversion, est un exemple de module de support qui utilise effectivement mod_dav_lock.

Notez que mod_dav_fs n'a pas besoin de ce module de verrouillage générique, car il utilise sa propre version plus spécifique.

Pour que mod_dav_lock puisse fonctionner, il vous suffit de spécifier le chemin de la base de données des verrous à l'aide de la directive DavGenericLockDB décrite ci-dessous.

Note du développeur

Pour déterminer le pointeur de la fonction du fournisseur de verrouillage, vous devez utiliser l'API ap_lookup_provider avec les arguments dav-lock, generic et 0.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive DavGenericLockDB

Description:Chemin de la base de données des verrous DAV
Syntaxe:DavGenericLockDB chemin fichier
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_dav_lock

La directive DavLockDB permet de spécifier le chemin complet de la base de données des verrous, sans extension. Si le chemin n'est pas absolu, il sera considéré comme relatif au répertoire défini par la directive ServerRoot. L'implémentation de mod_dav_lock utilise une base de données SDBM pour surveiller les verrous utilisateurs.

Exemple

DavGenericLockDB var/DavLock

Les utilisateur et groupe sous lesquels Apache s'exécute et qui sont respectivement définis par les directives User et Group doivent pouvoir écrire dans le répertoire qui contient le fichier de la base de données des verrous. Pour des raisons de sécurité, il est recommandé de créer un répertoire dédié à la base de données des verrous, plutôt que de modifier les permissions d'un répertoire existant. Dans l'exemple ci-dessus, Apache va créer des fichiers dans le répertoire var/, lui-même sous-répertoire du répertoire défini par la directive ServerRoot, avec le nom de base DavLock suivi d'une extension choisie par le serveur.

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dialup.html.fr.utf80000664000175100017510000001747314740503670022126 0ustar covenercovener mod_dialup - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_dialup

Langues Disponibles:  en  |  fr 

Description:Envoie le contenu statique avec une bande passante limitée définie par les différents standards des anciens modems.
Statut:Expérimental
Identificateur de Module:dialup_module
Fichier Source:mod_dialup.c

Sommaire

Il s'agit d'un module qui envoie le contenu statique avec une bande passante limitée définie par les différents standards des anciens modems. Ainsi, il est possible de naviguer sur votre site avec un modem 56k V.92 en positionnant une configuration de ce type :

<Location "/mysite">
    ModemStandard "V.92"
</Location>

Auparavant, pour faire des modules de limitation de bande passante, il fallait monopoliser un thread, pour chaque client, et insérer des temporisations pour diminuer la bande passante. Grâce à cette nouvelle fonctionnalité, un gestionnaire peut recevoir les réponses à ses callbacks après N millisecondes, et il sera invoqué par le module MPM Event dans un thread différent à la fin du délai indiqué. À partir de ce moment, le gestionnaire peut continuer à envoyer des données au client.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive ModemStandard

Description:Standard de modem à simuler
Syntaxe:ModemStandard V.21|V.26bis|V.32|V.34|V.92
Contexte:répertoire
Statut:Expérimental
Module:mod_dialup

Cette directive permet de spécifier le standard de modem que vous souhaitez simuler.

<Location "/mysite">
    ModemStandard "V.26bis"
</Location>

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authnz_ldap.html.fr.utf80000664000175100017510000026030614740503670023154 0ustar covenercovener mod_authnz_ldap - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authnz_ldap

Langues Disponibles:  en  |  fr 

Description:Permet d'utiliser un annuaire LDAP pour l'authentification HTTP de base.
Statut:Extension
Identificateur de Module:authnz_ldap_module
Fichier Source:mod_authnz_ldap.c
Compatibilité:Disponible depuis les versions 2.1 et supérieures d'Apache

Sommaire

Ce module permet aux frontaux d'authentification comme mod_auth_basic d'authentifier les utilisateurs via un annuaire ldap.

mod_authnz_ldap supporte les fonctionnalités suivantes :

Lorsqu'on utilise mod_auth_basic, ce module est invoqué en affectant la valeur ldap à la directive AuthBasicProvider.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Sommaire

top

Mises en garde à caractère général

Ce module effectue une mise en cache des résultats du processus d'authentification et d'autorisation en fonction de la configuration du module mod_ldap. Les modifications effectuées au niveau du serveur LDAP d'arrière-plan comme les verrouillages ou révocations d'utilisateurs, les changements de mot de passe, ou les changements d'appartenance à un groupe (et cette liste n'est pas exhaustive), ne seront pas immédiatement propagées jusqu'au serveur HTTP. Consultez les directives du module mod_ldap pour plus de détails à propos de la configuration de la mise en cache.

top

Mode opératoire

L'utilisateur se voit accorder l'accès selon un processus en deux phases. La première phase est l'authentification, au cours de laquelle le fournisseur d'authentification mod_authnz_ldap vérifie que les informations de connexion de l'utilisateur sont valides. Elle est aussi connue sous le nom de phase de recherche/connexion (NdT : en anglais ou dans le code source : search/bind). La deuxième phase est l'autorisation, au cours de laquelle mod_authnz_ldap détermine si l'utilisateur authentifié a la permission d'accéder à la ressource considérée. Elle est aussi connue sous le nom de phase de comparaison (compare).

mod_authnz_ldap comporte un fournisseur d'authentification authn_ldap et un gestionnaire d'autorisation authz_ldap. Le fournisseur d'authentification authn_ldap peut être invoqué en affectant la valeur ldap à la directive AuthBasicProvider. Le gestionnaire d'autorisation authz_ldap enrichit la liste des types d'autorisations de la directive Require en y ajoutant les valeurs ldap-user, ldap-dn et ldap-group.

La phase d'authentification

Au cours de la phase d'authentification, mod_authnz_ldap recherche une entrée de l'annuaire LDAP qui correspond au nom d'utilisateur fourni par le client HTTP. Si une correspondance unique est trouvée, mod_authnz_ldap tente de se connecter au serveur hébergeant l'annuaire LDAP en utilisant le DN de l'entrée et le mot de passe fourni par le client HTTP. Comme ce processus effectue tout d'abord une recherche, puis une connexion, il est aussi connu sous le nom de phase de recherche/connexion. Voici le détail des étapes constituant la phase de recherche/connexion :

  1. Confection d'un filtre de recherche en combinant les attribut et filtre définis par la directive AuthLDAPURL avec le nom d'utilisateur et le mot de passe fournis par le client HTTP.
  2. Recherche dans l'annuaire LDAP en utilisant le filtre confectionné précédemment. Si le résultat de la recherche est négatif ou comporte plusieurs entrées, refus ou restriction de l'accès.
  3. Extraction du DN (distinguished name) de l'entrée issue du résultat de la recherche, et tentative de connexion au serveur LDAP en utilisant ce DN et le mot de passe fournis par le client HTTP. Si la connexion échoue, refus ou restriction de l'accès.

Les directives utilisées durant la phase de recherche/connexion sont les suivantes :

AuthLDAPURL Spécifie le serveur LDAP, le DN de base, l'attribut à utiliser pour la recherche, ainsi que les filtres de recherche supplémentaires.
AuthLDAPBindDN Un DN optionnel pour se connecter durant la phase de recherche.
AuthLDAPBindPassword Un mot de passe optionnel pour se connecter durant la phase de recherche.

La phase d'autorisation

Au cours de la phase d'autorisation, mod_authnz_ldap tente de déterminer si l'utilisateur est autorisé à accéder à la ressource considérée. Une grande partie de cette vérification consiste pour mod_authnz_ldap en des opérations de comparaison au niveau du serveur LDAP. C'est pourquoi cette phase est aussi connue sous le nom de phase de comparaison. mod_authnz_ldap accepte les directives Require suivantes pour déterminer si les informations de connexion permettent d'accorder l'accès à l'utilisateur :

Sous réserve du chargement de modules d'autorisation supplémentaires, d'autres valeurs de la directive Require peuvent être spécifiées.

Durant la phase de comparaison, mod_authnz_ldap utilise les directives suivantes :

AuthLDAPURL On utilise l'attribut spécifié dans l'URL pour les opérations de comparaison initiées par la directive Require ldap-user.
AuthLDAPCompareDNOnServer Détermine le comportement de la directive Require ldap-dn.
AuthLDAPGroupAttribute Détermine l'attribut utilisé pour les opérations de comparaison initiées par la directive Require ldap-group.
AuthLDAPGroupAttributeIsDN Spécifie si l'on doit utiliser le DN ou le nom de l'utilisateur lors des opérations de comparaison initiées par la directive Require ldap-group.
AuthLDAPMaxSubGroupDepth Détermine la profondeur maximale de l'arborescence des sous-groupes qui seront évalués au cours des opérations de comparaisons initiées par la directive Require ldap-group.
AuthLDAPSubGroupAttribute Détermine l'attribut à utiliser lors de l'extraction de membres de sous-groupes du groupe courant au cours des opérations de comparaison initiées par la directive Require ldap-group.
AuthLDAPSubGroupClass Spécifie les valeurs de classe d'objet LDAP à utiliser pour déterminer si les objets extraits de l'annuaire sont bien des objets de type groupe (et non des objets de type utilisateur), au cours du traitement des sous-groupes initié par la directive Require ldap-group.
top

Les directives requises

Les directives Require d'Apache sont utilisées au cours de la phase d'autorisation afin de s'assurer que l'utilisateur est autorisé à accéder à une ressource. mod_authnz_ldap enrichit la liste des types d'autorisations avec les valeurs ldap-user, ldap-dn, ldap-group, ldap-attribute et ldap-filter. D'autres types d'autorisations sont disponibles, sous réserve du chargement de modules d'autorisation supplémentaires.

Depuis la version 2.4.8, les directives require LDAP supportent les expressions.

Require ldap-user

La directive Require ldap-user permet de spécifier les noms des utilisateurs autorisés à accéder à la ressource. Lorsque mod_authnz_ldap a extrait un DN unique de l'annuaire LDAP, il effectue une opération de comparaison LDAP en utilisant le nom d'utilisateur spécifié par la directive Require ldap-user, pour vérifier si ce nom d'utilisateur correspond à l'entrée LDAP extraite. On peut accorder l'accès à plusieurs utilisateurs en plaçant plusieurs nom d'utilisateurs sur la même ligne séparés par des espaces. Si un nom d'utilisateur contient des espaces, il doit être entouré de guillemets. On peut aussi accorder l'accès à plusieurs utilisateurs en utilisant une directive Require ldap-user par utilisateur. Par exemple, avec la directive AuthLDAPURL définie à ldap://ldap/o=Example?cn (spécifiant donc que l'attribut cn sera utilisé pour les recherches), on pourra utiliser les directives Require suivantes pour restreindre l'accès :

Require ldap-user "Barbara Jenson"
Require ldap-user "Fred User"
Require ldap-user "Joe Manager"

De par la manière dont mod_authnz_ldap traite cette directive, Barbara Jenson peut s'authentifier comme Barbara Jenson, Babs Jenson ou tout autre cn sous lequel elle est enregistrée dans l'annuaire LDAP. Une seule ligne Require ldap-user suffit pour toutes les valeurs de l'attribut dans l'entrée LDAP de l'utilisateur.

Si l'attribut uid avait été spécifié à la place de l'attribut cn dans l'URL précédente, les trois lignes ci-dessus auraient pû être condensées en une seule ligne :

Require ldap-user bjenson fuser jmanager

Require ldap-group

Cette directive permet de spécifier un groupe LDAP dont les membres auront l'autorisation d'accès. Elle prend comme argument le DN du groupe LDAP. Note : n'entourez pas le nom du groupe avec des guillemets. Par exemple, supposons que l'entrée suivante existe dans l'annuaire LDAP :

dn: cn=Administrators, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Example
uniqueMember: cn=Fred User, o=Example

La directive suivante autoriserait alors l'accès à Fred et Barbara :

Require ldap-group cn=Administrators, o=Example

Les membres peuvent aussi se trouver dans les sous-groupes du groupe LDAP spécifié si la directive AuthLDAPMaxSubGroupDepth a été définie à une valeur supérieure à 0. Par exemple, supposons que les entrées suivantes existent dans l'annuaire LDAP :

dn: cn=Employees, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Managers, o=Example
uniqueMember: cn=Administrators, o=Example
uniqueMember: cn=Users, o=Example

dn: cn=Managers, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Bob Ellis, o=Example
uniqueMember: cn=Tom Jackson, o=Example

dn: cn=Administrators, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Example
uniqueMember: cn=Fred User, o=Example

dn: cn=Users, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Allan Jefferson, o=Example
uniqueMember: cn=Paul Tilley, o=Example
uniqueMember: cn=Temporary Employees, o=Example

dn: cn=Temporary Employees, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Jim Swenson, o=Example
uniqueMember: cn=Elliot Rhodes, o=Example

Les directives suivantes autoriseraient alors l'accès à Bob Ellis, Tom Jackson, Barbara Jenson, Fred User, Allan Jefferson, et Paul Tilley, mais l'interdiraient à Jim Swenson, ou Elliot Rhodes (car ils sont situés dans un sous-groupe de niveau de profondeur 2) :

Require ldap-group cn=Employees, o=Example
AuthLDAPMaxSubGroupDepth 1

Le comportement de cette directive est modifié par les directives AuthLDAPGroupAttribute, AuthLDAPGroupAttributeIsDN, AuthLDAPMaxSubGroupDepth, AuthLDAPSubGroupAttribute, et AuthLDAPSubGroupClass.

Require ldap-dn

La directive Require ldap-dn permet à l'administrateur d'accorder l'utorisation d'accès en fonction du DN. Elle permet de spécifier un DN pour lequel l'accès est autorisé. Si le DN extrait de l'annuaire correspond au DN spécifié par la directive Require ldap-dn, l'autorisation d'accès est accordée. Note : n'entourez pas Le DN de guillemets.

La directive suivante accorderait l'accès à un DN spécifique :

Require ldap-dn cn=Barbara Jenson, o=Example

Le comportement ce cette directive est modifié par la directive AuthLDAPCompareDNOnServer.

Require ldap-attribute

La directive Require ldap-attribute permet à l'administrateur d'accorder l'autorisation d'accès en fonction des attributs de l'utilisateur authentifié dans l'annuaire LDAP. Si la valeur de l'attribut dans l'annuaire correspond à la valeur spécifiée par la directive, l'autorisation d'accès est accordée.

La directive suivante accorderait l'autorisation d'accès à tout utilisateur dont l'attribut employeeType a pour valeur "actif" :

Require ldap-attribute employeeType="active"

Plusieurs paires attribut/valeur peuvent être spécifiées par une même directive en les séparant par des espaces, ou en définissant plusieurs directives Require ldap-attribute. La logique sous-jacente à une liste de paires attribut/valeur est une opération OU. L'autorisation d'accès sera accordée si au moins une paire attribut/valeur de la liste spécifiée correspond à la paire attribut/valeur de l'utilisateur authentifié. Si elle contient des espaces, la valeur, et seulement la valeur, doit être entourée de guillemets.

La directive suivante accorderait l'autorisation d'accès à tout utilisateur dont l'attribut city aurait pour valeur "San Jose", ou donc l'attribut status aurait pour valeur "actif" :

Require ldap-attribute city="San Jose" status="active"

Require ldap-filter

La directive Require ldap-filter permet à l'administrateur d'accorder l'autorisation d'accès en fonction d'un filtre de recherche LDAP complexe. L'autorisation d'accès est accordée si le DN renvoyé par le filtre de recherche correspond au DN de l'utilisateur authentifié.

La directive suivante accorderait l'autorisation d'accès à tout utilisateur possédant un téléphone cellulaire et faisant partie du département "marketing" :

Require ldap-filter &(cell=*)(department=marketing)

Alors que la directive Require ldap-attribute se contente d'une simple comparaison d'attributs, la directive Require ldap-filter effectue une opération de recherche dans l'annuaire LDAP en utilisant le filtre de recherche spécifié. Si une simple comparaison d'attributs suffit, l'opération de comparaison effectuée par ldap-attribute sera plus rapide que l'opération de recherche effectuée par ldap-filter, en particulier dans le cas d'un annuaire LDAP de grande taille.

Lorsqu'on utilise une expression dans un filtre, il faut s'assurer que les filtres LDAP sont correctement échappés afin de se prémunir contre toute injection LDAP. Pour ce faire, il est possible d'utiliser la fonction ldap.

<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
  Require ldap-filter (memberOf=cn=%{ldap:%{unescape:%{env:MATCH_SITENAME}},ou=Websites,o=Example)
</LocationMatch>

Require ldap-search

La directive Require ldap-search permet à l'administrateur d'autoriser l'accès en fonction d'un filtre de recherche LDAP générique contenant une expression rationnelle. Si le filtre de recherche renvoie une et une seule correspondance, l'accès est accordé sans tenir compte du DN.

La directive suivante accorderait l'accès aux URLs correspondant aux objets spécifiés dans le serveur LDAP :

<LocationMatch "^/dav/(?<SITENAME>[^/]+)/">
Require ldap-search "(cn=%{ldap:%{unescape:%{env:MATCH_SITENAME}}
Website)"
</LocationMatch>

Note : il faut bien s'assurer que les expressions sont correctement échappés afin de se prémunir contre toute injection LDAP. A cet effet, il est possible d'utiliser la fonction ldap comme dans l'exemple ci-dessus.

top

Exemples

top

Utilisation de TLS

Pour l'utilisation de TLS, voir les directives du module mod_ldap LDAPTrustedClientCert, LDAPTrustedGlobalCert et LDAPTrustedMode.

Un second paramètre optionnel peut être ajouté à la directive AuthLDAPURL pour remplacer le type de connexion par défaut défini par la directive LDAPTrustedMode. Ceci permettra de promouvoir la connexion établie via une URL du type ldap:// au statut de connection sécurisée sur le même port.

top

Utilisation de SSL

Pour l'utilisation de SSL, voir les directives du module mod_ldap LDAPTrustedClientCert, LDAPTrustedGlobalCert et LDAPTrustedMode.

Pour spécifier un serveur LDAP sécurisé, utilisez ldaps:// au lieu de ldap:// dans la directive AuthLDAPURL.

top

Mise à disposition des informations de connexion

Au cours du processus d'authentification, les attributs LDAP spécifiés par la directive AuthLDAPURL sont enregistrés dans des variables d'environnement préfixées par la chaîne "AUTHENTICATE_".

Au cours du processus d'autorisation, les attributs LDAP spécifiés par la directive AuthLDAPURL sont enregistrés dans des variables d'environnement préfixées par la chaîne "AUTHORIZE_".

Si les champs attribut contiennent le nom, le CN et le numéro de téléphone d'un utilisateur, un programme CGI pourra accéder à ces informations sans devoir effectuer une autre requête LDAP pour les extraire de l'annuaire.

Ceci a pour effet de simplifier considérablement le code et la configuration nécessaire de certaines applications web.

top

Utilisation d'Active Directory

Active Directory peut supporter plusieurs domaines à la fois. Pour faire la distinction entre les utilisateurs de plusieurs domaines, on peut ajouter à l'entrée de l'utilisateur dans l'annuaire un identifiant appelé Nom Principal d'Utilisateur (User Principle Name ou UPN). Cet UPN se compose en général du nom de compte de l'utilisateur, suivi du nom du domaine considéré, par exemple untel@nz.example.com.

Vous voudrez probablement configurer le module mod_authnz_ldap afin de pouvoir authentifier les utilisateurs de n'importe quel domaine de la forêt Active Directory. Ainsi, untel@nz.example.com et untel@au.example.com pourront être authentifiés en une seule fois par la même requête.

Pour y parvenir, on utilise le concept de Catalogue Global d'Active Directory. Ce Catalogue Global est une copie en lecture seule des attributs sélectionnés de tous les serveurs de la forêt Active Directory. Une requête vers le Catalogue Global permet donc d'atteindre tous les domaines en une seule fois, sans avoir à se connecter aux différents serveurs, via des liaisons dont certaines peuvent être lentes.

Lorsqu'il est activé, la Catalogue Global est un serveur d'annuaire indépendant accessible sur le port 3268 (3269 pour SSL). Pour rechercher un utilisateur, effectuez une recherche sur l'attribut userPrincipalName, avec une base de recherche vide, comme suit :

AuthLDAPBindDN apache@example.com
AuthLDAPBindPassword password
AuthLDAPURL ldap://10.0.0.1:3268/?userPrincipalName?sub

Les utilisateurs devront s'authentifier en entrant leur UPN, de la formeuntel@nz.example.com.

top

Utilisation de Microsoft FrontPage avec mod_authnz_ldap

Normalement, FrontPage utilise des fichiers utilisateur/groupe spécifiques à FrontPage-web (c'est à dire les modules mod_authn_file et mod_authz_groupfile) pour effectuer toute l'authentification. Malheureusement, il ne suffit pas de modifier l'authentification LDAP en ajoutant les directives appropriées, car ceci corromprait les formulaires de Permissions dans le client FrontPage, qui sont censés modifier les fichiers d'autorisation standards au format texte.

Lorsqu'un site web FrontPage a été créé, lui adjoindre l'authentification LDAP consiste à ajouter les directives suivantes à chaque fichier .htaccess qui sera créé dans le site web :

AuthLDAPURL       "the url"
AuthGroupFile     "mygroupfile"
Require group     "mygroupfile"

Comment ça marche

FrontPage restreint l'accès à un site web en ajoutant la directive Require valid-user aux fichiers .htaccess. La directive Require valid-user permettra l'accès à tout utilisateur valide du point de vue LDAP. Cela signifie que tout utilisateur possédant une entrée dans l'annuaire LDAP sera considéré comme valide, alors que FrontPage ne considère comme valides que les utilisateurs enregistrés dans le fichier des utilisateurs local. En remplaçant l'autorisation par groupe LDAP par une autorisation par fichier de groupe, Apache sera en mesure de consulter le fichier des utilisateurs local (géré par FrontPage) - au lieu de l'annuaire LDAP - lors du processus d'autorisation des utilisateurs.

Une fois les directives ajoutées selon ce qui précède, les utilisateurs FrontPage pourront effectuer toutes les opérations de gestion à partir du client FrontPage.

Avertissements

top

Directive AuthLDAPAuthorizePrefix

Description:Spécifie le préfixe ajouté aux variables d'environnement durant la phase d'autorisation
Syntaxe:AuthLDAPAuthorizePrefix préfixe
Défaut:AuthLDAPAuthorizePrefix AUTHORIZE_
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible depuis la version 2.3.6

Cette directive permet de spécifier le préfixe ajouté aux variables d'environnement durant la phase d'autorisation. Si la valeur spécifiée est AUTHENTICATE_, les utilisateurs de ces variables d'environnement verront les mêmes informations, que le serveur effectue une authentification, une autorisation, ou les deux.

Note

Aucune variable d'autorisation n'est définie lorsqu'un utilisateur s'est vu autoriser l'accès via la directive Require valid-user.
top

Directive AuthLDAPBindAuthoritative

Description:Détermine si l'on doit utiliser d'autres fournisseurs d'authentification lorsque le serveur ne peut pas valider les données d'authentification de l'utilisateur, alors que ce dernier possède un DN.
Syntaxe:AuthLDAPBindAuthoritative off|on
Défaut:AuthLDAPBindAuthoritative on
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Par défaut, des fournisseurs d'authentification sont appelés si un utilisateur ne possède pas de DN, mais ne le sont pas si l'utilisateur possède un DN et si son mot de passe ne peut pas être vérifié lors d'une connexion au serveur LDAP. Si la directive AuthLDAPBindAuthoritative est définie à off, d'autres modules d'authentification configurés auront une chance de valider le mot de passe de l'utilisateur si la tentative de connexion au serveur LDAP échoue pour une raison quelconque (avec les données d'authentification fournies).

Ceci permet aux utilisateurs présent à la fois dans l'annuaire LDAP et dans un fichier AuthUserFile de s'authentifier lorsque le serveur LDAP est disponible, alors que le compte de l'utilisateur est verrouillé ou que son mot de passe est inutilisable pour une raison quelconque.

Voir aussi

top

Directive AuthLDAPBindDN

Description:Un DN optionnel pour se connecter au serveur LDAP
Syntaxe:AuthLDAPBindDN dn
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Cette directive permet de définir un DN optionnel pour se connecter au serveur afin d'y rechercher des entrées. Si aucun DN n'est spécifié, mod_authnz_ldap tentera une connexion anonyme.

top

Directive AuthLDAPBindPassword

Description:Mot de passe à utiliser en conjonction avec le DN de connexion
Syntaxe:AuthLDAPBindPassword mot-de-passe
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:exec: est disponible depuis la version 2.4.5 du serveur HTTP Apache.

Cette directive permet de spécifier un mot de passe à utiliser en conjonction avec le DN de connexion. Notez que ce mot de passe constitue en général une donnée sensible, et doit donc être protégé de manière appropriée. Vous ne devez utiliser les directives AuthLDAPBindDN et AuthLDAPBindPassword que si vous en avez vraiment besoin pour effectuer une recherche dans l'annuaire.

Si la valeur spécifiée débute par "exec:", la commande qui suit sera exécutée, et la première ligne renvoyée par la commande sur la sortie standard sera utilisée comme mot de passe.

# Mot de passe spécifié directement
AuthLDAPBindPassword secret

# Exécution de /path/to/program pour obtenir le mot de passe
AuthLDAPBindPassword exec:/path/to/program

# Exécution de /path/to/otherProgram avec un argument pour obtenir le mot de passe
AuthLDAPBindPassword "exec:/path/to/otherProgram argument1"
top

Directive AuthLDAPCharsetConfig

Description:Chemin du fichier de configuration de la correspondance langage/jeu de caractères
Syntaxe:AuthLDAPCharsetConfig chemin-fichier
Contexte:configuration globale
Statut:Extension
Module:mod_authnz_ldap

La directive AuthLDAPCharsetConfig permet de définir le chemin du fichier de configuration de la correspondance langage/jeu de caractères. chemin-fichier est un chemin relatif au répertoire défini par la directive ServerRoot. Ce fichier contient une liste de correspondances extension de langage/jeu de caractères. La plupart des administrateurs utilisent le fichier charset.conv fourni qui associe les extensions de langage courantes à leurs jeux de caractères.

Le fichier contient des lignes au format suivant :

extension de langage jeu de caractères [Nom du langage] ...

L'extension est insensible à la casse. Les lignes vides et les lignes commençant par un dièse (#) sont ignorées.

top

Directive AuthLDAPCompareAsUser

Description:Utilisation des données d'authentification de l'utilisateur pour effectuer les comparaisons pour l'attribution des autorisations
Syntaxe:AuthLDAPCompareAsUser on|off
Défaut:AuthLDAPCompareAsUser off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible depuis la version version 2.3.6

Lorsque cette directive est définie, et si mod_authnz_ldap a authentifié l'utilisateur, les recherches LDAP pour les autorisations utilisent le nom distinctif trouvé (DN) et le mot de passe d'authentification basique HTTP de l'utilisateur authentifié au lieu des données d'authentification configurées au niveau du serveur.

Les vérifications d'autorisation ldap-attribute, ldap-user, et ldap-group (niveau simple seulement) utilisent des comparaisons.

Cette directive n'a d'effet sur les comparaisons effectuées au cours des traitements de groupe imbriqués, et lorsque la directive AuthLDAPSearchAsUser est aussi activée.

Cette directive ne doit être utilisée que si votre serveur LDAP n'autorise pas les recherches anonymes, ou si vous ne pouvez pas utiliser de nom d'utilisateur dédié via la directive AuthLDAPBindDN.

Voir aussi

top

Directive AuthLDAPCompareDNOnServer

Description:Utilise le serveur LDAP pour comparer les DNs
Syntaxe:AuthLDAPCompareDNOnServer on|off
Défaut:AuthLDAPCompareDNOnServer on
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Lorsque cette directive est définie à on, mod_authnz_ldap utilise le serveur LDAP pour comparer les DNs. Il s'agit de la seule méthode infaillible pour comparer les DNs. mod_authnz_ldap va rechercher dans l'annuaire le DN spécifié par la directive Require dn, puis extraire ce DN et le comparer avec le DN extrait de l'entrée de l'utilisateur. Si cette directive est à off, mod_authnz_ldap effectue une simple comparaison de chaînes. Cette dernière approche peut produire des faux négatifs, mais elle est beaucoup plus rapide. Notez cependant que le cache de mod_ldap peut accélérer la comparaison de DNs dans la plupart des situations.

top

Directive AuthLDAPDereferenceAliases

Description:À quel moment le module va déréférencer les alias
Syntaxe:AuthLDAPDereferenceAliases never|searching|finding|always
Défaut:AuthLDAPDereferenceAliases always
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Cette directive permet de spécifier à quel moment mod_authnz_ldap va déréférencer les alias au cours des opérations liées à LDAP. La valeur par défaut est always.

top

Directive AuthLDAPGroupAttribute

Description:L'attribut LDAP utilisé pour vérifier l'appartenance d'un utilisateur à un groupe.
Syntaxe:AuthLDAPGroupAttribute attribut
Défaut:AuthLDAPGroupAttribute member uniqueMember
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Cette directive permet de spécifier quel attribut LDAP est utilisé pour vérifier l'appartenance d'un utilisateur à un groupe. On peut spécifier plusieurs attributs en répétant cette directive plusieurs fois. Si la directive n'est pas définie, mod_authnz_ldap utilise les attributs member et uniqueMember.

top

Directive AuthLDAPGroupAttributeIsDN

Description:Utilise le DN de l'utilisateur pour vérifier son appartenance à un groupe
Syntaxe:AuthLDAPGroupAttributeIsDN on|off
Défaut:AuthLDAPGroupAttributeIsDN on
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Lorsqu'elle est définie à on, cette directive indique que c'est le DN de l'utilisateur qui doit être utilisé pour vérifier son appartenance à un groupe. Dans le cas contraire, c'est le nom de l'utilisateur qui sera utilisé. Par exemple, supposons que le client envoie le nom d'utilisateur bjenson, qui correspond au DN LDAP cn=Babs Jenson,o=Example. Si la directive est à on, mod_authnz_ldap va vérifier si cn=Babs Jenson, o=Example est un membre du groupe. Dans le cas contraire, mod_authnz_ldap vérifiera si bjenson est un membre du groupe.

top

Directive AuthLDAPInitialBindAsUser

Description:Détermine si le serveur effectue la recherche initiale du DN en utilisant le nom propre de l'utilisateur pour l'authentification de base et non de manière anonyme, ou en utilisant des données d'authentification codées en dur pour le serveur
Syntaxe:AuthLDAPInitialBindAsUser off|on
Défaut:AuthLDAPInitialBindAsUser off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible depuis la version 2.3.6

Par défaut, le serveur convertit le nom d'utilisateur pour l'authentification de base en nom distinctif LDAP (DN) soit de manière anonyme, soit avec un couple nom/mot de passe dédié. Cette directive permet de forcer le serveur à utiliser les véritables nom d'utilisateur et mot de passe fournis par l'utilisateur pour effectuer la recherche initiale du DN.

Si le nom d'utilisateur ne peut pas s'authentifier directement et nécessite de légères modifications, voir la directive AuthLDAPInitialBindPattern.

Cette directive ne doit être utilisée que si votre serveur LDAP n'autorise pas les recherches anonymes, ou si vous ne pouvez pas utiliser de nom d'utilisateur dédié via la directive AuthLDAPBindDN.

Non disponible dans la cas d'une autorisation seule

On ne peut utiliser cette directive que si ce module effectue une authentification, et n'a aucun effet si ce module n'est utilisé que pour les processus d'autorisation.

Voir aussi

top

Directive AuthLDAPInitialBindPattern

Description:Spécifie la modification a apporter au nom d'utilisateur pour l'authentification de base lors de l'authentification auprès du serveur LDAP pour effectuer une recherche de DN
Syntaxe:AuthLDAPInitialBindPattern regex substitution
Défaut:AuthLDAPInitialBindPattern (.*) $1 (nom de l'utilisateur distant utilisé tel quel)
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible depuis la version 2.3.6

Si la directive AuthLDAPInitialBindAsUser est définie à ON, le nom utilisateur pour l'authentification de base sera transformé selon l'expression rationnelle regex et l'argument substitution spécifiés.

L'expression rationnelle est comparée au nom d'utilisateur pour l'authentification de base courant. L'argument substitution peut contenir des références arrières, mais n'effectue aucune autre interpolation de variable.

Cette directive ne doit être utilisée que si votre serveur LDAP n'autorise pas les recherches anonymes, ou si vous ne pouvez pas utiliser de nom d'utilisateur dédié via la directive AuthLDAPBindDN.

AuthLDAPInitialBindPattern (.+) $1@example.com
AuthLDAPInitialBindPattern (.+) cn=$1,dc=example,dc=com

Non disponible dans la cas d'une autorisation seule

On ne peut utiliser cette directive que si ce module effectue une authentification, et n'a aucun effet si ce module n'est utilisé que pour les processus d'autorisation.

Débogage

Le DN de substitution est enregistré dans la variable d'environnement LDAP_BINDASUSER. Si l'expression rationnelle ne convient pas, le nom d'utilisateur est utilisé tel quel.

Voir aussi

top

Directive AuthLDAPMaxSubGroupDepth

Description:Spécifie la profondeur d'imbrication des sous-groupes maximale prise en compte avant l'abandon de la recherche de l'utilisateur.
Syntaxe:AuthLDAPMaxSubGroupDepth Nombre
Défaut:AuthLDAPMaxSubGroupDepth 10
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible à partir de la version 2.3.0 du serveur HTTP Apache

Lorsque cette directive est définie à une valeur X non nulle, en combinaison avec l'utilisation de la directive Require ldap-group DN-groupe, les données de connexion fournies seront utilisées pour vérifier l'appartenance de l'utilisateur à l'objet de l'annuaire DN-groupe ou à tout sous-groupe du groupe courant en tenant compte de la profondeur d'imbrication maximale X spécifiée par la directive.

Se référer à la section Require ldap-group pour un exemple plus détaillé.

Performances dans le cas des groupes imbriqués

Lorsque les directives AuthLDAPSubGroupAttribute et AuthLDAPGroupAttribute se recouvrent (comme c'est le cas par défaut et requis par les schémas LDAP courants), la recherche de sous-groupes au sein de grands groupes peut être très longue. Si vos groupes sont très grands et non imbriqués, définissez la directive AuthLDAPMaxSubGroupDepth à 0.

top

Directive AuthLDAPRemoteUserAttribute

Description:Spécifie l'attribut dont la valeur renvoyée au cours de la requête de l'utilisateur sera utilisée pour définir la variable d'environnement REMOTE_USER
Syntaxe:AuthLDAPRemoteUserAttribute uid
Défaut:none
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Lorsque cette directive est définie, la variable d'environnement REMOTE_USER sera définie à la valeur de l'attribut spécifié. Assurez-vous que cet attribut soit bien inclus dans la liste d'attributs spécifiés dans la définition de AuthLDAPURL ; dans le cas contraire, cette directive n'aurait aucun effet. Si elle est présente, cette directive l'emporte sur AuthLDAPRemoteUserIsDN. Elle peut s'avérer utile par exemple, si vous souhaitez que les utilisateurs se connectent à un site web en utilisant leur adresse email, alors qu'une application sous-jacente nécessite un nom d'utilisateur comme identifiant.

top

Directive AuthLDAPRemoteUserIsDN

Description:Utilise le DN de l'utilisateur pour définir la variable d'environnement REMOTE_USER
Syntaxe:AuthLDAPRemoteUserIsDN on|off
Défaut:AuthLDAPRemoteUserIsDN off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

Lorsque cette directive est à on, la variable d'environnement REMOTE_USER sera définie avec la valeur du DN complet de l'utilisateur authentifié, et non plus avec simplement le nom d'utilisateur fourni par le client. Elle est définie à off par défaut.

top

Directive AuthLDAPSearchAsUser

Description:Utilise les données d'authentification de l'utilisateur pour la recherche des autorisations
Syntaxe:AuthLDAPSearchAsUser on|off
Défaut:AuthLDAPSearchAsUser off
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible depuis la version 2.3.6

Lorsque cette directive est définie, et si mod_authnz_ldap a authentifié l'utilisateur, les recherches LDAP pour définir les autorisations utilisent le nom distinctif (DN) trouvé et le mot de passe pour l'authentification de base HTTP de l'utilisateur authentifié, au lieu des données d'authentification configurées au niveau du serveur.

Les vérifications d'autorisation ldap-filter et ldap-dn utilisent des recherches.

Cette directive n'a d'effet sur les comparaisons effectuées au cours des traitements de groupe imbriqués, et lorsque la directive AuthLDAPCompareAsUser est aussi activée.

Cette directive ne doit être utilisée que si votre serveur LDAP n'autorise pas les recherches anonymes, ou si vous ne pouvez pas utiliser de nom d'utilisateur dédié via la directive AuthLDAPBindDN.

Voir aussi

top

Directive AuthLDAPSubGroupAttribute

Description:Spécifie les noms d'attribut, un par directive, utilisés pour différencier les membres du groupe courant qui sont eux-mêmes des groupes.
Syntaxe:AuthLDAPSubGroupAttribute attribut
Défaut:AuthLDAPSubgroupAttribute member uniqueMember
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible à partir de la version 2.3.0 du serveur HTTP Apache

Un objet groupe LDAP peut contenir des membres qui sont des utilisateurs et des membres qui sont eux-mêmes des groupes (appelés sous-groupes ou groupes imbriqués). La directive AuthLDAPSubGroupAttribute spécifie l'attribut utilisé pour identifier les groupes, alors que la directive AuthLDAPGroupAttribute spécifie l'attribut utilisé pour identifier les utilisateurs. On peut spécifier plusieurs attributs en répétant la directive plusieurs fois. Si elle n'est pas définie, mod_authnz_ldap utilise les attributs member et uniqueMember.

top

Directive AuthLDAPSubGroupClass

Description:Spécifie quelles valeurs d'objectClass LDAP identifient les objets de l'annuaire qui sont des groupes au cours du traitement des sous-groupes.
Syntaxe:AuthLDAPSubGroupClass ObjectClass-LDAP
Défaut:AuthLDAPSubGroupClass groupOfNames groupOfUniqueNames
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap
Compatibilité:Disponible à partir de la version 2.3.0 du serveur HTTP Apache

Un objet groupe LDAP peut contenir des membres qui sont des utilisateurs et des membres qui sont eux-mêmes des groupes (appelés sous-groupes ou groupes imbriqués). La directive AuthLDAPSubGroupAttribute permet d'identifier les membres qui sont des sous-groupes du groupe courant (à l'opposé des membres utilisateurs). La directive AuthLDAPSubGroupClass permet de spécifier les valeurs d'objectClass LDAP utilisées pour vérifier que certains membres sont en fait des objets groupe. Les sous-groupes ainsi identifiés peuvent alors faire l'objet d'une recherche d'autres membres utilisateurs ou sous-groupes. On peut spécifier plusieurs attributs en répétant cette directive plusieurs fois. Si cette directive n'est pas définie, mod_authnz_ldap utilise les attributs groupOfNames et groupOfUniqueNames.

top

Directive AuthLDAPURL

Description:URL specifying the LDAP search parameters
Syntaxe:AuthLDAPURL url [NONE|SSL|TLS|STARTTLS]
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_authnz_ldap

La documentation de cette directive n'a pas encore t traduite. Veuillez vous reporter la version en langue anglaise.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_dbd.html.fr.utf80000664000175100017510000004775014740503670022615 0ustar covenercovener mod_authz_dbd - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authz_dbd

Langues Disponibles:  en  |  fr 

Description:Autorisation en groupe et reconnaissance d'identité avec base SQL
Statut:Extension
Identificateur de Module:authz_dbd_module
Fichier Source:mod_authz_dbd.c
Compatibilité:Disponible dans les versions 2.4 et supérieures d'Apache

Sommaire

Ce module fournit des fonctionnalités d'autorisation permettant d'accorder ou de refuser aux utilisateurs authentifiés l'accès à certaines zones du site web en fonction de leur appartenance à tel ou tel groupe. Les modules mod_authz_groupfile et mod_authz_dbm fournissent une fonctionnalité similaire, mais ici le module interroge une base de données SQL pour déterminer si un utilisateur appartient ou non à tel ou tel groupe.

Ce module propose également des fonctionnalités de connexion utilisateur s'appuyant sur une base de données, ce qui peut se révéler particulièrement utile lorsque le module est utilisé conjointement avec mod_authn_dbd.

Ce module s'appuie sur mod_dbd pour spécifier le pilote de la base de données sous-jacente et les paramètres de connexion, et gérer les connexions à la base de données.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Les directives Require

Les directives Require d'Apache permettent, au cours de la phase d'autorisation, de s'assurer qu'un utilisateur est bien autorisé à accéder à une ressource. mod_authz_dbd ajoute les types d'autorisation dbd-group, dbd-login et dbd-logout.

A partir de la version 2.4.8, les directives require DBD supportent les expressions.

Require dbd-group

Cette directive permet de spécifier à quel groupe un utilisateur doit appartenir pour obtenir l'autorisation d'accès.

Require dbd-group team
AuthzDBDQuery "SELECT user_group FROM authz WHERE user = %s"

Require dbd-login

Cette directive permet de spécifier une requête à exécuter pour indiquer que l'utilisateur s'est authentifié.

Require dbd-login
AuthzDBDQuery "UPDATE authn SET login = 'true' WHERE user = %s"

Require dbd-logout

Cette directive permet de spécifier une requête à exécuter pour indiquer que l'utilisateur s'est déconnecté.

Require dbd-logout
AuthzDBDQuery "UPDATE authn SET login = 'false' WHERE user = %s"
top

Reconnaissance d'identité s'appuyant sur une base de données

Outre sa fonction d'autorisation standard consistant à vérifier l'appartenance à des groupes, ce module permet aussi de gérer des sessions utilisateur côté serveur grâce à sa fonctionnalité de connexion utilisateur en s'appuyant sur une base de données. En particulier, il peut mettre à jour le statut de session de l'utilisateur dans la base de données chaque fois que celui-ci visite certaines URLs (sous réserve bien entendu que l'utilisateur fournissent les informations de connexion nécessaires).

Pour cela, il faut definir deux directives Require spéciales : Require dbd-login et Require dbd-logout. Pour les détails de leur utilisation, voir l'exemple de configuration ci-dessous.

top

Reconnaissance d'identité côté client

Certains administrateurs peuvent vouloir implémenter une gestion de session côté client fonctionnant de concert avec les fonctionnalités de connexion/déconnexion des utilisateurs côté serveur offertes par ce module, en définissant ou en annulant par exemple un cookie HTTP ou un jeton similaire lorsqu'un utilisateur se connecte ou se déconnecte.

Pour supporter une telle intégration, mod_authz_dbd exporte un programme à déclenchement optionnel (hook) qui sera lancé chaque fois que le statut d'un utilisateur sera mis à jour dans la base de données. D'autres modules de gestion de session pourront alors utiliser ce programme pour implémenter des fonctions permettant d'ouvrir et de fermer des sessions côté client.

top

Exemple de configuration

# configuration de mod_dbd
DBDriver pgsql
DBDParams "dbname=apacheauth user=apache pass=xxxxxx"

DBDMin  4
DBDKeep 8
DBDMax  20
DBDExptime 300

<Directory "/usr/www/mon.site/team-private/">
  # configuration de mod_authn_core et mod_auth_basic
  # pour mod_authn_dbd
  AuthType Basic
  AuthName Team
  AuthBasicProvider dbd

  # requête SQL de mod_authn_dbd pour authentifier un utilisateur qui se
  # connecte
  AuthDBDUserPWQuery \
    "SELECT password FROM authn WHERE user = %s AND login = 'true'"

  # configuration de mod_authz_core pour mod_authz_dbd
  Require dbd-group team

  # configuration de mod_authz_dbd
  AuthzDBDQuery "SELECT group FROM authz WHERE user = %s"

  # lorsqu'un utilisateur échoue dans sa tentative d'authentification ou
  # d'autorisation, on l'invite à se connecter ; cette page doit
  # contenir un lien vers /team-private/login.html
  ErrorDocument 401 "/login-info.html"

  <Files "login.html">
    # il n'est pas nécessaire que l'utilisateur soit déjà connecté !
    AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"

    # le processus de connexion dbd exécute une requête pour enregistrer
    # la connexion de l'utilisateur
    Require dbd-login
    AuthzDBDQuery "UPDATE authn SET login = 'true' WHERE user = %s"

    # redirige l'utilisateur vers la page d'origine (si elle existe)
    # après une connexion réussie
    AuthzDBDLoginToReferer On
  </Files>

  <Files "logout.html">
    # le processus de déconnexion dbd exécute une requête pour
    # enregistrer la déconnexion de l'utilisateur
    Require dbd-logout
    AuthzDBDQuery "UPDATE authn SET login = 'false' WHERE user = %s"
  </Files>
</Directory>
top

Directive AuthzDBDLoginToReferer

Description:Définit si le client doit être redirigé vers la page d'origine en cas de connexion ou de déconnexion réussie si un en-tête de requête Referer est présent
Syntaxe:AuthzDBDLoginToReferer On|Off
Défaut:AuthzDBDLoginToReferer Off
Contexte:répertoire
Statut:Extension
Module:mod_authz_dbd

Utilisée en conjonction avec Require dbd-login ou Require dbd-logout, cette directive permet de rediriger le client vers la page d'origine (l'URL contenue dans l'en-tête de requête HTTP Referer, s'il est présent). En l'absence d'en-tête Referer, la définition AuthzDBDLoginToReferer On sera ignorée.

top

Directive AuthzDBDQuery

Description:Définit la requête SQL pour l'opération requise
Syntaxe:AuthzDBDQuery requête
Contexte:répertoire
Statut:Extension
Module:mod_authz_dbd

La directive AuthzDBDQuery permet de spécifier une requête SQL à exécuter. Le but de cette requête dépend de la directive Require en cours de traitement.

Dans tous les cas, l'identifiant utilisateur sera transmis comme paramètre sous la forme d'une simple chaîne lorsque la requête SQL sera exécutée. Il y sera fait référence dans la requête en utilisant le spécificateur de format %s.

top

Directive AuthzDBDRedirectQuery

Description:Définit une requête pour rechercher une page vers laquelle rediriger l'utilisateur après une connexion réussie
Syntaxe:AuthzDBDRedirectQuery requête
Contexte:répertoire
Statut:Extension
Module:mod_authz_dbd

Spécifie une requête SQL optionnelle à utiliser après une connexion (ou une déconnexion) réussie pour rediriger l'utilisateur vers une URL, qui peut être spécifique à l'utilisateur. L'identifiant utilisateur sera transmis comme paramètre sous la forme d'une simple chaîne lorsque la requête SQL sera exécutée. Il y sera fait référence dans la requête en utilisant le spécificateur de format %s.

AuthzDBDRedirectQuery "SELECT userpage FROM userpages WHERE user = %s"

La première colonne du premier enregistrement renvoyé par la requête doit contenir une chaîne de caractères correspondant à une URL vers laquelle rediriger le client. Les enregistrements suivants sont ignorés. Si aucun enregistrement n'est renvoyé, le client ne sera pas redirigé.

Notez que AuthzDBDLoginToReferer l'emporte sur cette directive si les deux sont définies.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_host.html.fr.utf80000664000175100017510000003454714740503670023041 0ustar covenercovener mod_authz_host - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_authz_host

Langues Disponibles:  en  |  fr 

Description:Autorisations de groupe basées sur l'hôte (nom ou adresse IP)
Statut:Base
Identificateur de Module:authz_host_module
Fichier Source:mod_authz_host.c
Compatibilité:Le fournisseur forward-dns est disponible à partir de la version 2.4.19 du serveur HTTP Apache

Sommaire

Les fournisseurs d'autorisation implémentés par le module mod_authz_host sont enregistrés à l'aide de la directive Require. On peut utiliser cette directive à l'intérieur de sections <Directory>, <Files>, ou <Location> ou de fichiers .htaccess pour contrôler l'accès à certaines zones du serveur. Le contrôle d'accès peut être effectué en fonction du nom d'hôte ou de l'adresse IP.

En général, les directives de restriction d'accès s'appliquent à toutes les méthodes d'accès (GET, PUT, POST, etc...). C'est d'ailleurs ce que l'on souhaite dans la plupart des cas. Il est cependant possible de ne restreindre l'accès que pour certaines méthodes, tout en laissant les autres méthodes sans protection, en plaçant les directives dans une section <Limit>.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Les directives Require

La directive Apache Require est utilisée au cours de la phase d'autorisation pour vérifier si un utilisateur se voit accorder ou refuser l'accès à une ressource. mod_authz_host fournit les types d'autorisation ip, host, forward-dns et local. D'autres types d'autorisation sont aussi disponibles, mais nécessitent le chargement des modules d'autorisation appropriés.

Ces fournisseurs d'autorisation permettent de déterminer quels hôtes peuvent accéder à une zone du serveur. On peut contrôler l'accès en fonction du nom d'hôte, de l'adresse IP, ou d'un intervalle d'adresses IP.

A partir de la version 2.4.8, les directives require host supportent les expressions.

Require ip

Le fournisseur ip permet de contrôler l'accès au serveur en fonction de l'adresse IP du client distant. Lorsque Require ip adresse-ip est spécifié, la requête est autorisée si l'adresse IP du client distant correspond à

Une adresse IP complète :

Require ip 10.1.2.3
Require ip 192.168.1.104 192.168.1.205

L'adresse IP d'un hôte pour qui l'accès est accordé

Une adresse IP partielle :

Require ip 10.1
Require ip 10 172.20 192.168.2

Les 1 à 3 premiers octets d'une adresse IP, pour une restriction à un sous-réseau.

Une paire réseau/masque de sous-réseau :

Require ip 10.1.0.0/255.255.0.0

Un réseau a.b.c.d, et un masque de sous-réseau w.x.y.z. pour une restriction de sous-réseau plus fine.

Une spécification CIDR réseau/nnn :

Require ip 10.1.0.0/16

Identique au cas précédent, excepté que le masque de sous-réseau représente les nnn premiers bits de poids fort.

Notez que les trois derniers exemples correspondent exectement au même ensemble d'hôtes.

On peut spécifier des adresses et des sous-réseaux IPv6 comme suit :

Require ip 2001:db8::a00:20ff:fea7:ccea
Require ip 2001:db8:1:1::a
Require ip 2001:db8:2:1::/64
Require ip 2001:db8:3::/48

Note: comme les adresses IP sont lues au démarrage, les expressions ne sont pas évaluées au moment de la requête.

Require host

Le fournisseur host permet de contrôler l'accès au serveur en fonction du nom d'hôte du client distant. Lorsque Require host nom-hôte est spécifié, la requête est autorisée si le nom d'hôte correspond à

Un nom de domaine (éventuellement partiel)

Require host example.org
Require host .net example.edu

Les hôtes dont les noms correspondent ou se terminent par la chaîne spécifiée se voient accorder l'accès. Seuls les élément de nom de domaine complets sont mis en correspondance ; ainsi, l'exemple ci-dessus correspondra à foo.example.org, mais ne correspondra pas à fooexample.org. Avec cette configuration, Apache va effectuer une double recherche DNS sur l'adresse IP du client, sans tenir compte de la définition de la directive HostnameLookups. Il va effectuer une recherche DNS inverse sur l'adresse IP pour trouver le nom d'hôte associé, puis une recherche DNS directe sur le nom d'hôte pour vérifier qu'il correspond bien à l'adresse IP originale. L'accès ne sera accordé que si le nom d'hôte correspond et si les recherches DNS inverse et directe sont cohérentes.

Require forward-dns

Le fournisseur forward-dns permet d'accéder au serveur sécurisé en fonction de simples noms d'hôte. Lorsque Require forward-dns host-name est spécifié, toute adresse IP correspondant à host-name se voit autoriser l'accès.

A la différence du fournisseur host, ce fournisseur n'effectue pas de recherche DNS inverse : il effectue simplement une requête DNS directe pour le nom d'hôte spécifié et donne accès au client si son adresse IP correspond. Il ne fonctionnera donc qu'avec des noms d'hôte complets qui peuvent être résolus par le DNS, et non avec des noms de domaine partiels. Par contre, comme le DNS inverse n'est pas sollicité, et comme les recherches DNS interviennent au moment du traitement de la requête (et non au démarrage), il fonctionnera avec des clients qui utilisent un service de DNS dynamique.

Require forward-dns dynamic.example.org

Un client dont l'adresse IP correspond au nom d'hôte dynamic.example.org se verra autoriser l'accès.

Require local

Le fournisseur local autorise l'accès au serveur si l'une au moins de ces conditions est satisfaite :

L'exemple suivant montre une méthode simple pour sélectionner les connexions en provenance de l'hôte local :

Require local

Note concernant la sécurité

Si le contenu de votre serveur est mandaté, vous devez garder à l'esprit que l'adresse client correspondra à l'adresse de votre serveur mandataire et non à l'adresse du client, et l'utilisation de la directive Require dans ce contexte ne provoquera pas forcément l'effet désiré. Voir mod_remoteip pour une solution possible à ce problème.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_autoindex.html.fr.utf80000664000175100017510000020643714740503670022650 0ustar covenercovener mod_autoindex - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_autoindex

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Génère automatiquement des index de répertoires d'une manière similaire à la commande Unix ls, ou à la commande shell Win32 dir
Statut:Base
Identificateur de Module:autoindex_module
Fichier Source:mod_autoindex.c

Sommaire

L'index d'un répertoire peut être généré de deux manières :

Les deux fonctions sont séparées, si bien que vous pouvez entièrement supprimer (ou remplacer) la génération automatique d'index, si vous le souhaitez.

On active la génération automatique d'index en spécifiant Options +Indexes. Voir la directive Options pour plus de détails.

Si la directive IndexOptions est spécifiée avec l'option FancyIndexing, les en-têtes de colonnes sont des liens qui permettent de contrôler l'ordre de tri de l'affichage. Si vous actionnez le lien d'un en-tête, le listing sera généré à nouveau, trié en fonction des valeurs de la colonne concernée. Si l'on actionne de manière répétitive le même en-tête, l'ordre de tri est commuté entre les ordres croissant et décroissant. On peut supprimer ces liens d'en-têtes de colonnes à l'aide de l'option SuppressColumnSorting de la directive IndexOptions.

Notez que lorsque l'affichage est trié en fonction de la taille, c'est la taille réelle qui est prise en compte, et non la valeur affichée - ainsi, un fichier de 1010 octets sera toujours affiché avant un fichier de 1011 octets (en ordre croissant), même si la taille affichée des deux fichiers est "1K".

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Arguments de la requête d'autoindexation

La chaîne de paramètres de la requête peut contenir de nombreux arguments permettant dans une certaine mesure au client de contrôler l'ordre de l'index du répertoire, ainsi que la liste des fichiers à afficher. Si vous souhaitez désactiver cette fonctionnalité, utilisez l'option IndexOptions IgnoreClient.

Les en-têtes de tri des colonnes eux-mêmes sont des hyper-liens auto-référant qui ajoutent les options de tri à la requête énumérées ci-dessous qui peuvent être ajoutées à toute requête concernant la ressource répertoire.

Notez que l'argument 'P' (pour Pattern) n'est testé qu'après que les directives habituelles IndexIgnore ont été traitées, et que tous les noms de fichiers sont encore assujettis aux mêmes critères que pour tout autre listing auto-indexé. L'interpréteur d'arguments de requête de mod_autoindex s'arrête immédiatement s'il rencontre une option non reconnue. Les arguments de requête doivent être bien formés, selon la table ci-dessus.

Les options de requêtes sont illustrées par l'exemple ci-dessous, qui peut être copié et collé dans un fichier header.html. Notez que l'argument inconnu "X", pour le bouton submit, est introduit en dernier afin de s'assurer que tous les arguments ont été interprétés avant que mod_autoindex ne rencontre l'entrée X=Go.

Exemple

<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

Directive AddAlt

Description:Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son nom
Syntaxe:AddAlt texte fichier [fichier] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive AddAlt permet d'afficher un texte optionnel pour un fichier, à la place d'un icône, dans le cas d'un affichage FancyIndexing. fichier est une extension de fichier, un nom de fichier partiel, une expression avec caractères génériques ou un nom de fichier complet permettant de caractériser le(s) fichier(s) concerné(s). Si texte contient des espaces, vous devez l'entourer de guillemets ou d'apostrophes (" ou '). Ce texte optionnel sera affiché si le client ne peut pas afficher d'images, si le chargement d'images est désactivé ou si l'icône ne peut pas être trouvé.

AddAlt "PDF file" *.pdf
AddAlt Compressed *.gz *.zip *.Z
top

Directive AddAltByEncoding

Description:Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son codage MIME
Syntaxe:AddAltByEncoding texte codage MIME [codage MIME] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive AddAltByEncoding permet d'afficher un texte optionnel à la place d'un icône pour un fichier dans le cas d'un affichage FancyIndexing. codage MIME doit être un type valide, comme x-compress. Si texte contient des espaces, vous devez l'entourer de guillemets ou d'apostrophes (" ou '). Ce texte optionnel sera affiché si le client ne peut pas afficher d'images, si le chargement d'images est désactivé ou si l'icône ne peut pas être trouvé.

AddAltByEncoding gzip x-gzip
top

Directive AddAltByType

Description:Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son type MIME
Syntaxe:AddAltByType texte type MIME [type MIME] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive AddAltByType permet d'afficher un texte optionnel à la place d'un icône pour un fichier dans le cas d'un affichage FancyIndexing. type MIME doit être un type MIME valide, comme text/html. Si texte contient des espaces, vous devez l'entourer de guillemets ou d'apostrophes (" ou '). Ce texte optionnel sera affiché si le client ne peut pas afficher d'images, si le chargement d'images est désactivé ou si l'icône ne peut pas être trouvé.

AddAltByType 'Fichier texte' text/plain
top

Directive AddDescription

Description:Afficher la description d'un fichier
Syntaxe:AddDescription texte [fichier] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

Cette directive permet d'afficher une description pour un fichier, dans le cas d'un affichage FancyIndexing. fichier est une extension de fichier, un nom de fichier partiel, une expression avec caractères génériques ou un nom de fichier complet permettant de caractériser le fichier. texte doit être entouré de guillemets (").

AddDescription "The planet Mars" mars.gif
AddDescription "My friend Marshall" friends/mars.gif

La taille par défaut, habituelle du champ de description est de 23 octets. L'option IndexOptions SuppressIcon ajoute 6 octets, l'option IndexOptions SuppressSize en ajoute 7 et l'option IndexOptions SuppressLastModified en ajoute 19. Ainsi, la plus grande taille par défaut qui peut être assignée à la colonne description est de 55 octets.

Comme l'argument fichier peut être un nom de fichier partiel, vous devez garder à l'esprit qu'un nom de fichier partiel trop court pourra correspondre à des fichiers non voulus. Par exemple, le.html correspondra au fichier le.html, mais aussi au fichier example.html. En cas d'ambiguïté, utilisez un nom de fichier aussi complet que possible, et ordonnez votre liste de directives AddDescription en conséquence.

Voir le mot-clé DescriptionWidth de la directive IndexOptions pour plus de détails sur la manière d'augmenter la taille de cette colonne, ou pour permettre des descriptions de taille illimitée.

Avertissement

Le texte descriptif défini par la directive AddDescription peut contenir des marquages HTML, comme des balises ou des entités caractères. Si la limite de taille de la colonne description venait à tronquer une balise (par exemple couper la fin d'une phrase en caractères gras), le résultat pourrait en affecter toute la suite du listing du répertoire.

Arguments avec chemins

Les chemins absolus ne sont actuellement pas supportés et ne peuvent correspondre à aucun chemin réel à l'exécution. Les arguments contenant des chemins relatifs, qui ne devraient être normalement utilisés que dans les fichiers htaccess, sont implicitement préfixés par '*/' afin d'éviter toute association avec des noms de répertoires partiels.

top

Directive AddIcon

Description:Icône à afficher pour un fichier en fonction de son nom
Syntaxe:AddIcon icône nom [nom] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

Cette directive permet de déterminer l'icône à afficher à côté d'un fichier dont le nom se termine par nom, dans le cas d'un affichage FancyIndexing. icône est une URL relative (échappée par des caractères '%') vers l'icône, une URL distante pleinement qualifiée, ou de la forme (alttext,url), où alttext est le symbole texte correspondant à l'icône à afficher dans les navigateurs en mode texte.

nom correspond à ^^DIRECTORY^^ pour les répertoires, ^^BLANKICON^^ pour les lignes vides (pour personnaliser la présentation du listing), une extension de fichier, une expression avec caractères génériques, un nom de fichier partiel ou un nom de fichier complet.

^^BLANKICON^^ n'est utilisé que pour le formatage, et n'est donc pas nécessaire si vous utilisez IndexOptions HTMLTable.

#Examples
AddIcon (IMG,/icons/image.png) .gif .jpg .png
AddIcon /icons/dir.png ^^DIRECTORY^^
AddIcon /icons/backup.png *~

Lorsque c'est possible, il est préférable d'utiliser AddIconByType plutôt que AddIcon.

top

Directive AddIconByEncoding

Description:Icône à afficher à côté d'un fichier en fonction de son codage MIME
Syntaxe:AddIconByEncoding icône codage MIME [codage MIME] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

Cette directive permet de déterminer l'icône à afficher à côté d'un fichier dans le cas d'un affichage FancyIndexing. icône est une URL relative (échappée par des caractères '%') vers l'icône, une URL pleinement qualifiée, ou de la forme (alttext,url), où alttext est le symbole texte correspondant à l'icône à afficher dans les navigateurs en mode texte.

codage MIME doit être un codage valide, comme x-compress.

AddIconByEncoding /icons/compress.png x-compress
top

Directive AddIconByType

Description:Icône à afficher à côté d'un fichier en fonction de son type MIME
Syntaxe:AddIconByType icône type MIME [type MIME] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

Cette directive permet de déterminer l'icône à afficher à côté d'un fichier de type MIME type MIME dans le cas d'un affichage FancyIndexing. icône est une URL relative (échappée par des caractères '%') vers l'icône, une URL pleinement qualifiée, ou de la forme (alttext,url), où alttext est le symbole texte correspondant à l'icône à afficher dans les navigateurs en mode texte.

type MIME est une expression avec caractères génériques représentant le type MIME.

AddIconByType (IMG,/icons/image.png) image/*
top

Directive DefaultIcon

Description:Icône à afficher par défaut lorsqu'aucun icône spécifique n'est précisé
Syntaxe:DefaultIcon chemin URL
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive DefaultIcon permet de définir l'icône à afficher à côté d'un fichier lorsqu'aucun icône spécifique n'a été précisé, dans le cas d'un affichage FancyIndexing. chemin URL est une URL relative (échappée par des caractères '%') vers l'icône ou une URL pleinement qualifiée.

DefaultIcon /icon/unknown.png
top

Directive HeaderName

Description:Nom du fichier qui sera inséré au début de la page contenant l'index
Syntaxe:HeaderName nom fichier
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive HeaderName permet de définir le nom du fichier qui sera inséré au début de la page contenant l'index. nom fichier est le nom du fichier à inclure.

HeaderName HEADER.html

Les deux directives HeaderName et ReadmeName traitent maintenant nom fichier comme un chemin URI relatif au chemin utilisé pour accéder au répertoire faisant l'objet de l'index. Si nom fichier commence par un slash '/', il sera considéré comme relatif au répertoire défini par la directive DocumentRoot.

HeaderName /include/HEADER.html

nom fichier doit correspondre à un document dont le type MIME est du style text/* (par exemple text/html, text/plain, etc...). Cela signifie que nom fichier peut faire référence à un script CGI si le véritable type MIME du script (et non celui de sa sortie) est marqué comme text/html par exemple à l'aide d'une directive comme :

AddType text/html .cgi

Une négociation de contenu sera effectuée si Options MultiViews a été précisé. Si nom fichier correspond à un document statique text/html (et non à un script CGI), et une des deux options Includes ou IncludesNOEXEC est activée, le fichier sera traité en tant qu'inclusion côté serveur (Server Side Include) (voir la documentation de mod_include).

Si le fichier spécifié par la directive HeaderName contient les en-têtes d'un document HTML (<html>, <head>, etc...), vous serez probablement amenés à définir IndexOptions +SuppressHTMLPreamble, de manière à ce que ces balises ne soient pas répétées.

Voir aussi

top

Directive IndexHeadInsert

Description:Insère du texte dans la section HEAD de la page d'index.
Syntaxe:IndexHeadInsert "marque ..."
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive IndexHeadInsert permet de spécifier une chaîne de caractères à insérer dans la section <head> du code HTML généré pour la page d'index.

IndexHeadInsert "<link rel=\"sitemap\" href=\"/sitemap.html\">"
top

Directive IndexIgnore

Description:Ajouts à la liste des fichiers à cacher lors de l'affichage de l'index d'un répertoire
Syntaxe:IndexIgnore fichier [fichier] ...
Défaut:IndexIgnore "."
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive IndexIgnore permet d'effectuer des ajouts à la liste des fichiers à cacher lors de l'affichage de l'index d'un répertoire. fichier est une expression avec caractères génériques de style shell ou un nom de fichier complet. Plusieurs directives IndexIgnore effectuent des ajouts à la liste, et ne remplacent pas la liste des fichiers à ignorer. Par défaut, la liste contient . (le répertoire courant).

IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t

Expressions rationnelles

Cette directive est actuellement incompatible avec les sections de configuration qui comportent des arguments avec expressions rationnelles comme <DirectoryMatch>

top

Directive IndexIgnoreReset

Description:Vide la liste des fichiers à cacher lors de l'affichage du contenu d'un répertoire
Syntaxe:IndexIgnoreReset ON|OFF
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex
Compatibilité:Versions 2.3.10 et supérieures

La directive IndexIgnoreReset supprime toute liste de fichiers définie par la directive IndexIgnore et héritée par ailleurs d'autres sections de configuration.

<Directory "/var/www">
    IndexIgnore *.bak .??* *~ *# HEADER* README* RCS CVS *,v *,t
</Directory>
<Directory "/var/www/backups">
    IndexIgnoreReset ON
    IndexIgnore .??* *# HEADER* README* RCS CVS *,v *,t
</Directory>

Revoyez la configuration par défaut pour une liste de modèles que vous voulez ignorer explicitement après usage de cette directive.

top

Directive IndexOptions

Description:Diverses options de configuration pour l'indexation d'un répertoire
Syntaxe:IndexOptions [+|-]option [[+|-]option] ...
Défaut:Par défaut, aucune option n'est activée.
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive IndexOptions permet de spécifier les options de configuration de l'indexation du répertoire. option peut prendre l'une des valeurs suivantes :

AddAltClass
Ajoute une déclaration de classe CSS supplémentaire à chaque enregistrement de la table du listing du répertoire dans le cas où IndexOptions HTMLTable est activé et où un IndexStyleSheet a été défini. Plutôt que d'appliquer à chaque enregistrement de la table les classes standards even et odd, c'est ici une classe even-ALT ou odd-ALT qui sera appliquée, où ALT sera soit le texte alternatif standard associé au style du fichier (par exemple snd, txt, img, etc...), soit le texte alternatif défini par une des différentes directives AddAlt*.
Charset=jeu de caractères
Le mot-clé Charset vous permet de spécifier le jeu de caractères de la page générée. La valeur par défaut est UTF-8 sous Windows et MAC OS X, et ISO-8859-1 dans les autres cas (en fait selon que le système de fichiers sous-jacent utilise les noms de fichiers en Unicode ou non).
IndexOptions Charset=UTF-8
DescriptionWidth=[n | *]
Le mot-clé DescriptionWidth vous permet de spécifier la taille en caractères de la colonne description.
Avec -DescriptionWidth (ou si l'option n'est pas définie), mod_autoindex calcule la meilleure taille.
DescriptionWidth=n fixe la taille de la colonne à n octets.
DescriptionWidth=* ajuste la taille de la colonne à la plus longue chaîne de description. Voir la section concernant AddDescription pour les dangers inhérants à la troncature des descriptions.
FancyIndexing
Cette option active l'indexation "améliorée" des répertoires, c'est à dire avec en-têtes de colonnes sous forme d'hyper-liens auto-référants.
FoldersFirst
Lorsque cette option est activée, la liste des sous-répertoires apparaîtra toujours en premier, suivie de la liste des fichiers normaux du répertoire. Le listing comporte principalement deux parties, les fichiers et les sous-répertoires, chacun d'eux étant trié séparément et les sous-répertoires affichés en premier. Par exemple, si l'ordre de tri est décroissant par nom, et si FoldersFirst est activé, le sous-répertoire Zed sera affiché avant le sous-répertoire Beta, qui sera lui-même affiché avant les fichiers normaux Gamma et Alpha. Cette option n'a d'effet que si FancyIndexing est aussi activé.
HTMLTable
Cette option pour l'affichage FancyIndexing permet de construire une table simple pour l'affichage de l'index du répertoire. Cette option s'avèrera particulièrement nécessaire pour les plates-formes où utf-8 est activé et dans le cas où les noms de fichiers ou les chaînes de description alternent entre les ordres de lecture gauche à droite et droite à gauche.
IconsAreLinks
Configure la partie réservée aux icônes de l'ancrage pour le nom de fichier, dans le cas d'un affichage "amélioré".
IconHeight[=pixels]
Si cette option est présente, en combinaison avec IconWidth, le serveur va inclure les attributs height et width dans la balise img qui référence le fichier de l'icône. Ceci va permettre au navigateur de prévoir les caractéristiques de la page sans devoir attendre que toutes les images aient été chargées. En l'absence de cette option, c'est la hauteur standard définie par le logiciel Apache httpd qui est choisie comme valeur par défaut. Cette option n'a d'effet que si FancyIndexing est aussi activé.
IconWidth[=pixels]
Si cette option est présente, en combinaison avec IconHeight, le serveur va inclure les attributs height et width dans la balise img qui référence le fichier de l'icône. Ceci va permettre au navigateur de prévoir les caractéristiques de la page sans devoir attendre que toutes les images aient été chargées. En l'absence de cette option, c'est la largeur standard définie par le logiciel Apache httpd qui est choisie comme valeur par défaut.
IgnoreCase
Si cette option est activée, les noms sont triés sans tenir compte de la casse. Par exemple, si le tri s'effectue sur les noms dans l'ordre croissant, et si IgnoreCase est activé, le fichier Zeta apparaîtra après le fichier alfa (Note : le fichier GAMMA apparaîtra toujours avant le fichier gamma).
IgnoreClient
Si cette option est activée, mod_autoindex va ignorer toutes les variables de requête fournies par le client, y compris les informations de tri (ce qui implique l'activation de l'option SuppressColumnSorting).
NameWidth=[n | *]
Le mot-clé NameWidth vous permet de spécifier la largeur en octets de la colonne correspondant au nom du fichier.
Avec -NameWidth (ou si l'option n'est pas définie), mod_autoindex va calculer la meilleure largeur possible, mais jusqu'à une largeur maximale de 20 octets.
NameWidth=n fixe la largeur de la colonne à n octets.
NameWidth=* définit la largeur de colonne à la valeur nécessaire.
ScanHTMLTitles
L'activation de cette option permet d'extraire le titre des documents HTML dans le cas d'un affichage "amélioré". Si le fichier ne possède aucune description définie par la directive AddDescription, httpd va lire le document pour tenter d'en extraire le titre. Ce processus est coûteux en ressources disque et CPU.
ShowForbidden
Si cette option est activée, Apache httpd affichera les fichiers normalement cachés suite au retour des valeurs HTTP_UNAUTHORIZED ou HTTP_FORBIDDEN par la sous-requête.
SuppressColumnSorting
Si cette option est activée, Apache httpd supprimera les liens hyper-texte dans les en-têtes de colonnes dans le cas d'un affichage "amélioré". Par défaut, ces en-têtes constituent des liens hyper-texte, et la sélection de l'un d'entre eux va trier l'index du répertoire en fonction des valeurs de la colonne correspondante. Cependant, les arguments de la chaîne de paramètres de la requête ajoutés à l'URL seront toujours ignorés. Ce comportement est contrôlé par l'option IndexOptions IgnoreClient.
SuppressDescription
L'activation de cette option va supprimer la description des fichiers dans le cas d'un affichage "amélioré". Par défaut aucune description de fichier n'est définie, et par conséquent l'utilisation de cette option va permettre de récupérer un espace à l'écran de 23 caractères pouvant être utilisé pour autre chose. Voir la directive AddDescription pour plus d'informations à propos de la définition des descriptions de fichiers. Voir aussi l'option d'index DescriptionWidth pour limiter la taille de la colonne description. Cette option n'a d'effet que si FancyIndexing est aussi activé.
SuppressHTMLPreamble
Si le répertoire contient effectivement le fichier spécifié par la directive HeaderName, le module inclut en général le contenu du fichier après avoir inséré un préambule HTML standard (<html>, <head>, etc...). L'activation de l'option SuppressHTMLPreamble supprime l'insertion de ce préambule, et le module va alors commencer l'affichage directement par le contenu du fichier d'en-tête. Dans ce cas par contre, le fichier d'en-tête doit contenir des instructions HTML appropriées. S'il n'y a pas de fichier d'en-tête, le préambule est généré comme dans le cas général. Si vous spécifiez aussi une directive ReadmeName, et si ce fichier existe, les balises de fermeture closing </body></html> seront aussi omises dans la sortie, en supposant que vous ayez placé ces balises de fermeture dans ce fichier.
SuppressIcon
L'activation de cette option supprime l'affichage des icônes dans le cas d'un affichage "amélioré". La combinaison de SuppressIcon et SuppressRules permet de générer une sortie au format HTML 3.2 qui, selon les dernières spécifications, interdit les éléments img et hr dans les blocs pre (utilisés pour formater les affichages "améliorés").
SuppressLastModified
L'activation de cette option supprime l'affichage de la date de dernière modification dans le cas d'un affichage "amélioré". Cette option n'a d'effet que si FancyIndexing est aussi activé.
SuppressRules
L'activation de cette option supprime l'affichage des lignes horizontales (éléments hr) dans les index de répertoires. La combinaison de SuppressIcon et SuppressRules permet de générer une sortie au format HTML 3.2 qui, selon les dernières spécifications, interdit les éléments img et hr dans les blocs pre (utilisés pour formater les affichages "améliorés"). Cette option n'a d'effet que si FancyIndexing est aussi activé.
SuppressSize
L'activation de cette option supprime l'affichage de la taille du fichier dans le cas d'un affichage "amélioré". Cette option n'a d'effet que si FancyIndexing est aussi activé.
TrackModified
Cette option renvoie les valeurs Last-Modified et ETag pour le répertoire indexé dans l'en-tête HTTP. Elle n'est valide que si le système d'exploitation et le système de fichiers renvoient des résultats appropriés pour la fonction stat(). C'est le cas de certains systèmes Unix, ainsi que JFS sous OS/2 ou les volumes NTFS sous Win32. Ce n'est par contre pas le cas des volumes FAT Win32 et OS/2. Lorsque cette option est activée, le client ou le mandataire peuvent détecter les changements dans la liste des fichiers lorsqu'ils effectuent une requête HEAD. Notez que certains systèmes d'exploitation détectent correctement les nouveaux fichiers et les fichiers supprimés, mais ne détectent pas les modifications de tailles ou de dates des fichiers du répertoire. Les modifications de taille ou de date d'un fichier existant ne mettent pas à jour l'en-tête Last-Modified sur toutes les plate-formes Unix. Si c'est le cas, laissez cette option désactivée.
Type=type MIME
Le mot-clé Type vous permet de spécifier le type MIME de la page générée. La valeur par défaut est text/html.
IndexOptions Type=text/plain
UseOldDateFormat (Apache HTTP Server versions 2.4.26 et ultérieures)
Le format de date utilisé dans le champ Last Modified avait été modifié par inadvertance de "%d-%b-%Y %H:%M" en "%Y-%m-%d %H:%M" dans la version 2.4.0. Cette option permet de restaurer le format de date des versions 2.2 et antérieures.
VersionSort
Le mot-clé VersionSort permet de trier les fichiers contenant des numéros de version d'une manière spécifique. Les chaînes sont triées comme d'habitude, excepté les sous-chaînes de chiffres du nom de fichier et de sa description qui sont comparées en fonction de leur valeur numérique.

Exemple :

foo-1.7
foo-1.7.2
foo-1.7.12
foo-1.8.2
foo-1.8.2a
foo-1.12

Si le nombre commence par le chiffre 0, il est considéré comme la partie fractionnaire d'un nombre :

foo-1.001
foo-1.002
foo-1.030
foo-1.04

XHTML
Le mot-clé XHTML enjoint mod_autoindex de générer du code XHTML 1.0 au lieu de HTML 3.2. Cette option n'a d'effet que si FancyIndexing est aussi activé.
Options d'index incrémentales

Vous devez porter une attention particulière à la manière dont les IndexOptions multiples sont traitées.

  • Plusieurs directives IndexOptions apparaissant dans la même section directory sont maintenant fusionnées. Le résultat de :
    <Directory "/foo">
        IndexOptions HTMLTable
        IndexOptions SuppressColumnsorting
    </Directory>

    est équivalent à

    IndexOptions HTMLTable SuppressColumnsorting
  • L'ajout de la syntaxe incrémentale (en préfixant les mots-clés avec + ou -).

Chaque fois qu'un mot-clé préfixé par '+' ou '-' est trouvé, il est appliqué aux définitions des IndexOptions courantes (qui ont été éventuellement héritées d'un directory de niveau supérieur). Par contre, si un mot-clé non préfixé est trouvé, il supprime toutes les definitions héritées, ainsi que toute définition incrémentale. Considérons l'exemple suivant :

IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
IndexOptions +SuppressSize

L'effet global est équivalent à l'effet qu'aurait provoqué IndexOptions FancyIndexing +SuppressSize, car l'option non préfixée FancyIndexing annule les mots-clés incrémentaux situés avant elle, mais leur permet ensuite de s'incrémenter à nouveau.

Pour définir inconditionnellement les IndexOptions pour un répertoire particulier, tout en supprimant les définitions héritées, spécifiez les mots-clés sans préfixe + ou -

top

Directive IndexOrderDefault

Description:Définit l'ordre d'affichage par défaut d'un index de répertoire
Syntaxe:IndexOrderDefault Ascending|Descending Name|Date|Size|Description
Défaut:IndexOrderDefault Ascending Name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive IndexOrderDefault s'utilise en combinaison avec l'option d'index FancyIndexing. Par défaut, les index de répertoires "améliorés" sont affichés selon l'ordre croissant des noms de fichiers ; la directive IndexOrderDefault vous permet de modifier ce comportement.

La directive IndexOrderDefault accepte deux arguments. Le premier est soit Ascending, soit Descending, et indique l'ordre de tri. Le second doit prendre une des valeurs Name, Date, Size, ou Description, et permet d'identifier la clé primaire. La clé secondaire est toujours le nom du fichier selon un ordre croissant.

Si vous le désirez, vous pouvez empêcher le client de modifier l'ordre de tri de la liste en ajoutant l'option d'index SuppressColumnSorting qui supprime le lien de définition du tri de l'en-tête de la colonne, ainsi que l'option IgnoreClient qui empêche ce même client de passer outre vos préférences de tri en ajoutant manuellement des options de tri à la chaîne de paramètres de la requête.

top

Directive IndexStyleSheet

Description:Ajoute une feuille de style CSS à l'index du répertoire
Syntaxe:IndexStyleSheet chemin-url
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive IndexStyleSheet permet de définir le nom du fichier qui servira de feuille de style CSS pour l'index.

IndexStyleSheet "/css/style.css"

L'utilisation de cette directive en conjonction avec IndexOptions HTMLTable ajoute plusieurs classes CSS au document HTML résultant. Un identifiant CSS indexlist est attribué à l'ensemble de la table et les classes suivantes sont associées aux différentes parties du listing :

ClasseDéfinition
tr.indexheadLigne d'en-tête du listing
th.indexcolicon and td.indexcolicon Colonne de l'icône
th.indexcolname and td.indexcolname Colonne du nom du fichier
th.indexcollastmod and td.indexcollastmod Colonne de la date de dernière modification
th.indexcolsize and td.indexcolsize Colonne de la taille du fichier
th.indexcoldesc and td.indexcoldesc Colonne de la description
tr.breakrow Pied de page
tr.odd and tr.even Alternance des lignes paires et impaires
top

Directive ReadmeName

Description:Nom du fichier dont le contenu sera inséré à la fin de l'index
Syntaxe:ReadmeName nom-fichier
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_autoindex

La directive ReadmeName permet de définir le nom du fichier dont le contenu sera ajouté à la fin de l'index. nom-fichier est le nom du fichier à inclure, et est considéré comme relatif au répertoire faisant l'objet de l'index. Si nom-fichier commence par un slash '/', comme dans l'exemple 2, il sera considéré comme relatif au répertoire défini par la directive DocumentRoot.

# Example 1
ReadmeName FOOTER.html
# Example 2
ReadmeName /include/FOOTER.html

Voir aussi la directive HeaderName, où cette fonctionnalité est décrite plus en détails.

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dbd.html.fr.utf80000664000175100017510000006570214740503670021377 0ustar covenercovener mod_dbd - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_dbd

Langues Disponibles:  en  |  fr 

Description:Gestion des connexions à une base de données SQL
Statut:Extension
Identificateur de Module:dbd_module
Fichier Source:mod_dbd.c
Compatibilité:Versions 2.1 and supérieures

Sommaire

Le module mod_dbd gère les connexions à une base de données SQL via APR. Il permet aux modules qui requièrent des fonctions liées aux bases de données SQL de se connecter à une base de données à la demande, et s'efforce de conférer aux bases de données une efficacité et une évolutivité optimales pour les MPMs threadés ou non threadés. Pour plus de détails, voir le site web APR, ainsi que cette vue d'ensemble de l'environnement de développement d'Apache DBD par son développeur initial.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Regroupement des connexions

Ce module gère de manière optimisée en fonction de la plate-forme les connexions aux bases de données. Sur les plates-formes non threadées, il maintient une connexion persistente à la manière d'un LAMP classique (Linux, Apache, Mysql, Perl/PHP/Python). Sur les plates-formes threadées, il maintient un groupe de connexions à la fois plus évolutif et plus efficace, comme décrit dans cet article d'ApacheTutor. Notez que mod_dbd remplace les modules présentés dans cet article.

top

Connexion

Pour vous connecter à votre base de données, vous devez spécifier un pilote et des paramètres de connexion qui diffèrent selon le moteur de base de données. Par exemple, pour vous connecter à mysql, spécifiez ce qui suit :

DBDriver mysql
DBDParams host=localhost,dbname=pony,user=shetland,pass=appaloosa

Vous pourrez alors utiliser cette connexion dans de nombreux autres modules comme mod_rewrite, mod_authn_dbd et mod_lua. Vous trouverez des exemples d'utilisation dans la documentation de ces modules.

Voir la syntaxe de la directive DBDParams pour les informations à fournir dans la chaîne de connexion en fonction des différents pilotes de base de données supportés.

top

API DBD d'Apache

mod_dbd exporte cinq fonctions que d'autres modules pourront utiliser. L'API se présente comme suit :

typedef struct {
    apr_dbd_t *handle;
    apr_dbd_driver_t *driver;
    apr_hash_t *prepared;
} ap_dbd_t;

/* Fonctions exportées pour accéder à la base de données */

/* ouvre une connexion qui DOIT avoir été explicitement fermée.
 * Renvoie NULL en cas d'erreur
 */
AP_DECLARE(ap_dbd_t*) ap_dbd_open(apr_pool_t*, server_rec*);

/* ferme une connexion ouverte avec ap_dbd_open */
AP_DECLARE(void) ap_dbd_close(server_rec*, ap_dbd_t*);

/* acquiert une connexion qui aura la durée de vie de la requête et qui
 * NE DOIT PAS avoir été explicitement fermée. Renvoie NULL en cas
 * d'erreur. C'est la fonction recommandée pour la plupart des
 * applications.
 */
AP_DECLARE(ap_dbd_t*) ap_dbd_acquire(request_rec*);

/* acquiert une connexion qui aura la durée de vie d'une connexion et
 * qui NE DOIT PAS avoir été explicitement fermée. Renvoie NULL en cas
 * d'erreur.
 */
AP_DECLARE(ap_dbd_t*) ap_dbd_cacquire(conn_rec*);

/* Prépare une requête qu'un module client pourra utiliser */
AP_DECLARE(void) ap_dbd_prepare(server_rec*, const char*, const char*);

/* Exporte aussi ces fonctions à titre optionnel mour les modules qui
 * péfèreraient les utiliser */
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*));
APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_cacquire, (conn_rec*));
APR_DECLARE_OPTIONAL_FN(void, ap_dbd_prepare, (server_rec*, const char*, const char*));
top

Requêtes SQL préparées

mod_dbd supporte les requêtes SQL préparées à destination des modules qui pourraient les utiliser. Chaque requête préparée doit posséder un nom (étiquette), et est stockée dans un condensé (hash) : les condensés sont du type apr_dbd_prepared_t et s'utilisent dans toute requête SQL ou commande select préparée par apr_dbd.

Il est du ressort des modules utilisateurs de dbd d'utiliser les requêtes préparées et de préciser quelles requêtes doivent être spécifiées dans httpd.conf, ou de fournir leurs propres directives et d'utiliser ap_dbd_prepare.

Avertissement

Lorsqu'on utilise des requêtes préparées avec des bases de données MySQL, il est préférable de définir reconnect à 0 dans la chaîne de connexion, afin d'éviter des erreurs provoquées par un client MySQL qui se reconnecterait sans réinitialiser correctement les requêtes préparées. Si reconnect est défini à 1, toute connexion défectueuse sera sensée être réparée, mais comme mod_dbd n'en est pas informé, les requêtes préparées seront invalidées.
top

AVERTISSEMENT DE SECURITE

Toute application web impliquant une base de données doit se protéger elle-même contre les attaques de type injection SQL. Dans la plupart des cas Apache DBD est sûr, car les applications utilisent des requêtes préparées, et les entrées non sures ne seront utilisées qu'à titre de données. Bien entendu, si vous l'utilisez via un module tiers, vous devez être au fait des précautions à prendre.

Cependant, le pilote FreeTDS est non sûr de par sa nature-même. Comme la bibliothèque sous-jacente ne supporte pas les requêtes préparées, le pilote en effectue une émulation, et les entrées non sûres sont fusionnées avec la requête SQL.

Il peut être sécurisé en décontaminant toutes les entrées : un processus inspiré de la recherche de contaminations (taint mode) de Perl. Chaque entrée est comparée à une expression rationnelle, et seules les entrées qui correspondent sont utilisées, en accord avec le langage Perl :

  $untrusted =~ /([a-z]+)/;
  $trusted = $1;

Pour utiliser ceci, les expressions rationnelles de décontamination doivent être incluses dans les requêtes préparées. L'expression rationnelle doit se situer immédiatement après le caractère % dans la requête préparée, et doit être entourée d'accolades {}. Par exemple, si votre application attend une entrée alphanumérique, vous pouvez utiliser :

"SELECT foo FROM bar WHERE input = %s"

avec d'autres pilotes, et ne risquer au pire qu'une requête échouée. Mais avec FreeTDS, vous devez utiliser :

"SELECT foo FROM bar WHERE input = %{([A-Za-z0-9]+)}s"

tout ce qui ne correspond pas à l'expression rationnelle est alors rejeté, et la requête est maintenant sûre.

Alternativement, vous pouvez utiliser le pilote ODBC tiers, qui offre la sécurité des requêtes préparées authentiques.

top

Directive DBDExptime

Description:Durée de vie des connexions inactives
Syntaxe:DBDExptime durée en secondes
Défaut:DBDExptime 300
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Cette directive permet de définir la durée de vie des connexions inactives lorsque le nombre de connexions spécifié par la directive DBDKeep a été dépassé (plates-formes threadées uniquement).

top

Directive DBDInitSQL

Description:Exécute une instruction SQL après connexion à une base de données
Syntaxe:DBDInitSQL "instruction SQL"
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Les modules qui le souhaitent peuvent exécuter une ou plusieurs instructions SQL après connexion à une base de données. Par exemple initialiser certaines valeurs, ou ajouter une entrée dans le journal lors d'une nouvelle connexion à la base de données.

top

Directive DBDKeep

Description:Nombre maximum de connexions maintenues
Syntaxe:DBDKeep nombre
Défaut:DBDKeep 2
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Cette directive permet de définir le nombre maximum de connexions à maintenir par processus, en dehors de celles servant à gérer les pics de demandes (plates-formes threadées uniquement).

top

Directive DBDMax

Description:Nombre maximum de connexions
Syntaxe:DBDMax nombre
Défaut:DBDMax 10
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Cette directive permet de définir le nombre maximum effectif de connexions par processus (plates-formes threadées uniquement).

top

Directive DBDMin

Description:Nombre minimum de connexions
Syntaxe:DBDMin nombre
Défaut:DBDMin 1
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Cette directive permet de définir le nombre minimum de connexions par processus (plates-formes threadées uniquement).

top

Directive DBDParams

Description:Paramètres de la connexion à la base de données
Syntaxe:DBDParams param1=valeur1[,param2=valeur2]
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Cette directive permet de spécifier des paramètres selon les besoins du pilote concerné. En général, les paramètres à passer concernent tout ce qui n'a pas de valeur par défaut comme le nom d'utilisateur, le mot de passe, le nom de la base de données, le nom d'hôte et le numéro de port de la connexion.

Les paramètres de la chaîne de connexion en fonction des différents pilotes comprennent :

FreeTDS (pour MSSQL et SyBase)
username, password, appname, dbname, host, charset, lang, server
MySQL
host, port, user, pass, dbname, sock, flags, fldsz, group, reconnect
Oracle
user, pass, dbname, server
PostgreSQL
La chaîne de connexion est passée directement à PQconnectdb
SQLite2
La chaîne de connexion est scindée avec comme séparateur le caractère ':', et partie1:partie2 est utilisé dans sqlite_open(partie1, atoi(partie2), NULL)
SQLite3
La chaîne de connexion est passée directement à sqlite3_open
ODBC
datasource, user, password, connect, ctimeout, stimeout, access, txmode, bufsize
top

Directive DBDPersist

Description:Utiliser ou non des connexions persistentes
Syntaxe:DBDPersist On|Off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Si cette directive est définie à Off, les connexions persistentes et les connexions groupées sont désactivées. À la demande d'un client, une nouvelle connexion à la base de données est ouverte, et fermée immédiatement à l'issue du traitement. Cette configuration ne doit être utilisée qu'à des fins de débogage, ou sur des serveurs à charge faible.

Par défaut, les groupes de connexions persistentes sont activés (ou une seule connexion persistente du style LAMP pour les serveurs non threadés), et c'est la configuration qui devrait être utilisée dans la plupart des cas sur un serveur en production.

Avant la version 2.2.2, cette directive n'acceptait que les valeurs 0 et 1 au lieu de Off et On, respectivement.

top

Directive DBDPrepareSQL

Description:Définit une requête SQL préparée
Syntaxe:DBDPrepareSQL "requête SQL" étiquette
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Pour les modules tels que les modules d'authentification, qui utilisent de manière répétée la même requête SQL, on peut optimiser les performances en préparant la requête une fois pour toutes au démarrage, plutôt qu'à chaque utilisation. Cette directive permet de préparer une requête SQL et de lui assigner une étiquette.

top

Directive DBDriver

Description:Spécifie un pilote SQL
Syntaxe:DBDriver nom
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dbd

Cette directive permet de spécifier un pilote apr_dbd par son nom. Le pilote doit être installé sur votre système (sur la plupart des systèmes, il s'agit d'un objet partagé ou d'une dll). Par exemple, DBDriver mysql va sélectionner le pilote MySQL dans la bibliothèque apr_dbd_mysql.so.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dir.html.fr.utf80000664000175100017510000006067514740503670021430 0ustar covenercovener mod_dir - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_dir

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Permet la redirection des adresses se terminant par un répertoire sans slash de fin et la mise à disposition des fichiers index de répertoire
Statut:Base
Identificateur de Module:dir_module
Fichier Source:mod_dir.c

Sommaire

L'index d'un répertoire peut provenir de deux sources :

Les deux fonctions sont bien distinctes, si bien que vous pouvez supprimer (ou remplacer) la génération automatique d'index, si vous le souhaitez.

Une redirection "slash de fin" est effectuée lorsque le serveur reçoit une requête pour une URL du style http://nom-serveur/foo/nom-repnom-rep est le nom d'un répertoire. Comme les répertoires nécessitent un slash de fin, mod_dir effectue une redirection vers http://nom-serveur/foo/nom-rep/.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive DirectoryCheckHandler

Description:Définit la réponse de ce module lorsqu'un autre gestionnaire est utilisé
Syntaxe:DirectoryCheckHandler On|Off
Défaut:DirectoryCheckHandler Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_dir
Compatibilité:Disponible depuis la version 2.4.8 du serveur HTTP Apache. Les versions antérieures à 2.4 se comportaient implicitement comme si "DirectoryCheckHandler ON" avait été spécifié.

La directive DirectoryCheckHandler permet de faire en sorte que mod_dir recherche un index de répertoire ou ajoute des slashes de fin lorsqu'un autre gestionnaire à été défini pour l'URL considérée. Les gestionnaires peuvent être définis à via des directives telles que SetHandler ou par d'autres modules tels que mod_rewrite au cours des substitutions de niveau répertoire.

Dans les versions antérieures à 2.4, ce module ne modifiait pas son comportement si un autre gestionnaire avait été défini pour l'URL considérée. Ceci permettait de servir des index de répertoires même si une directive SetHandler avait été définie pour un répertoire entier, mais pouvait aussi être à l'origine de conflits avec d'autres modules comme mod_rewrite.

top

Directive DirectoryIndex

Description:Liste des fichiers ressources à rechercher lorsque le client envoie une requête pour un répertoire
Syntaxe:DirectoryIndex disabled | url locale [url locale] ...
Défaut:DirectoryIndex index.html
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_dir

La directive DirectoryIndex permet de définir une liste de fichiers ressources à rechercher lorsqu'un client envoie une requête pour l'index d'un répertoire, en ajoutant un '/' à la fin du nom de ce dernier. url locale est l'URL (codée avec caractères '%') d'un document du serveur, relative au répertoire faisant l'objet de la requête ; il s'agit en général du nom d'un fichier situé dans le répertoire. Si plusieurs URLs sont fournies, le serveur renverra la première d'entre elles qui correspond à une ressource existante. Si aucune ressource ne correspond à la liste des URLs spécifiées, et si l'option Indexes est définie, le serveur générera son propre listing du répertoire.

Exemple

DirectoryIndex index.html

Avec cette configuration, une requête pour l'URL http://example.com/docs/ renverrait au client la ressource http://example.com/docs/index.html si elle existe, ou provoquerait la génération du listing du répertoire si la ressource n'existe pas.

Notez qu'il n'est pas nécessaire que les documents soient relatifs au répertoire ;

DirectoryIndex index.html index.txt  /cgi-bin/index.pl

provoquerait l'exécution du script CGI /cgi-bin/index.pl si aucun des fichiers index.html ou index.txt n'existe dans le répertoire considéré.

La spécification du seul argument "disabled" empêche mod_dir de rechercher un index. Un argument "disabled" sera interprété de manière littérale si d'autres arguments sont présents avant ou après lui, même s'ils sont eux-mêmes des arguments "disabled".

Note: Positionner plusieurs directives DirectoryIndex au coeur du même context complète la liste des ressources et ne l'écrase pas :

# Exemple A: Positionner index.html en page d'index, puis ajouter index.php.
<Directory "/foo">
    DirectoryIndex index.html
    DirectoryIndex index.php
</Directory>

# Exemple B: La même chose que l'exemple A, mais réalisé au moyen d'une seule directive.
<Directory "/foo">
    DirectoryIndex index.html index.php
</Directory>

# Exemple C: Pour remplacer la liste des ressources, il faut d'abord la vider :
# Ici, seul index.php restera référencé comme ressource d'index.
<Directory "/foo">
    DirectoryIndex index.html
    DirectoryIndex disabled
    DirectoryIndex index.php
</Directory>
top

Directive DirectoryIndexRedirect

Description:Définit une redirection externe pour les index de répertoires.
Syntaxe:DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code
Défaut:DirectoryIndexRedirect off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_dir
Compatibilité:Disponible depuis la version 2.3.14

Par défaut, c'est la page définie par la directive DirectoryIndex qui est sélectionnée et renvoyée de manière transparente au client. La directive DirectoryIndexRedirect permet de rediriger le client via une redirection de type 3xx.

Les arguments acceptés sont :

Exemple

DirectoryIndexRedirect on

Une requête pour http://example.com/docs/ se solderait par une redirection temporaire vers http://example.com/docs/index.html si cette ressource existe.

top

Directive DirectorySlash

Description:Activation/Désactivation de la redirection "slash de fin"
Syntaxe:DirectorySlash On|Off
Défaut:DirectorySlash On
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_dir

La directive DirectorySlash permet de déterminer si mod_dir doit corriger ou non les URLs pointant vers un répertoire.

En général, si un utilisateur envoie une requête pour une ressource sans slash de fin, cette ressource représentant un répertoire, mod_dir le redirige vers la même ressource, mais en ajoutant un slash de fin, et ceci pour plusieurs bonnes raisons :

Si vous ne souhaitez pas voir ces effets, et si les raisons évoquées ci-dessus ne s'appliquent pas à vous, vous pouvez désactiver la redirection comme indiqué ci-dessous. Gardez cependant à l'esprit que ceci peut avoir des répercutions en matière de sécurité.

# voir l'avertissement de sécurité ci-dessous !
<Location "/some/path">
    DirectorySlash Off
    SetHandler some-handler
</Location>

Avertissement de sécurité

La désactivation de la redirection "slash de fin" peut entraîner la divulgation d'informations. Considérons la situation où mod_autoindex est actif (Options +Indexes), où la directive DirectoryIndex a pour valeur une ressource valide (par exemple index.html), et où aucun gestionnaire particulier n'a été défini pour cette URL. Dans ce cas, une requête avec slash de fin afficherait le contenu du fichier index.html ; par contre, une requête sans slash de fin afficherait un listing du contenu du répertoire.

Notez aussi que certains navigateurs peuvent modifier par erreur des requêtes POST en requêtes GET lors d'une redirection, les données POST étant alors perdues.

top

Directive FallbackResource

Description:Définit une URL par défaut pour les requêtes qui ne ciblent aucun fichier
Syntaxe:FallbackResource disabled | url-locale
Défaut:disabled - httpd renvoie un code d'erreur 404 (Not Found)
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Base
Module:mod_dir
Compatibilité:L'argument disabled est disponible à partir de la version 2.4.4 du serveur HTTP Apache.

Cette directive permet de définir un traitement pour toute URL qui ne correspond à aucune ressource de votre système de fichiers, et qui provoquerait sans cela l'envoi d'un code d'erreur HTTP 404 (Not Found). Par exemple

FallbackResource /not-404.php

fait en sorte que les requêtes ne correspondant à aucun fichier soient traitées par non-404.php, sans affecter les requêtes pour des fichiers existants.

Il est souvent souhaitable qu'un seul fichier ou ressource traite toutes les requêtes à destination d'un répertoire particulier, sauf pour les requêtes qui correspondent à un fichier ou script existant. On y fait souvent référence sous le terme 'contrôleur frontal'.

Dans les versions plus anciennes de httpd, cet effet nécessitait en général mod_rewrite, et l'utilisation des tests conditionnels -f et -d pour vérifier l'existence des fichiers et répertoires. Maintenant, une seule ligne de configuration est nécessaire.

FallbackResource /index.php

Les fichiers existants comme des images, des fichiers css, etc... seront traités normalement.

L'argument disabled permet de désactiver cette fonctionnalité dans le cas où l'héritage d'un répertoire parent n'est pas souhaité.

Pour un URI intermédiaire tel que http://example.com/blog/, cet URI intermédiaire doit être spécifié en tant que url-locale :

<Directory "/web/example.com/htdocs/blog">
    FallbackResource /blog/index.php
</Directory>
<Directory "/web/example.com/htdocs/blog/images">
    FallbackResource disabled
</Directory>

Un gestionnaire de ressource par défaut (dans l'exemple ci-dessus /blog/index.php) peut accéder à l'URL de la requête originale via la variable de serveur REQUEST_URI. Pour accéder à cette variable en PHP, par exemple, utilisez $_SERVER['REQUEST_URI'].

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_env.html.fr.utf80000664000175100017510000003012614740503670021426 0ustar covenercovener mod_env - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_env

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Modifie l'environnement transmis aux scripts CGI et aux pages SSI
Statut:Base
Identificateur de Module:env_module
Fichier Source:mod_env.c

Sommaire

Ce module permet de contrôler les variables d'environnement internes utilisées par divers modules du serveur HTTP Apache. Ces variables sont aussi accessibles aux scripts CGI en tant que variables d'environnement système natives, et disponibles dans les pages SSI. Les variables d'environnement peuvent être transmises depuis le shell qui a lancé le processus httpd. Elles peuvent également être définies ou supprimées au cours du processus de configuration.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive PassEnv

Description:Transmet des variables d'environnement depuis le shell
Syntaxe:PassEnv var-env [var-env] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_env

Cette directive permet de spécifier quelles variables d'environnement système natives doivent être disponibles en tant que variables d'environnement internes pour les modules du serveur HTTP Apache, et propagées vers les scripts CGI et les pages SSI. Leurs valeurs sont issues de l'environnement natif de l'OS associé au shell qui a invoqué le processus httpd.

Exemple

PassEnv LD_LIBRARY_PATH
top

Directive SetEnv

Description:Définit des variables d'environnement
Syntaxe:SetEnv var-env [valeur]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_env

Définit une variable d'environnement interne, cette dernière étant ensuite disponible pour les modules du serveur HTTP Apache et transmise aux scripts CGI et aux pages SSI.

Exemple

SetEnv SPECIAL_PATH /foo/bin

Si l'argument valeur est absent, la variable est définie à la valeur d'une chaîne vide.

Les variables d'environnement internes définies par cette directive le sont après l'exécution de la plupart des directives du traitement initial des requêtes, comme les contrôles d'accès et la mise en correspondance des URIs avec les noms de fichiers. Si la variable d'environnement est sensée intervenir au cours de cette phase initiale du traitement, par exemple pour la directive RewriteRule, vous devez plutôt utiliser la directive SetEnvIf pour définir cette variable.

Voir aussi

top

Directive UnsetEnv

Description:Supprime des variables de l'environnement
Syntaxe:UnsetEnv var-env [var-env] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_env

Supprime une ou plusieurs variables d'environnement internes parmi celles qui sont transmises aux scripts CGI et aux pages SSI.

Exemple

UnsetEnv LD_LIBRARY_PATH

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ext_filter.html.fr.utf80000664000175100017510000004732314740503670023012 0ustar covenercovener mod_ext_filter - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_ext_filter

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Fait traiter le corps de la réponse par un programme externe avant de l'envoyer au client
Statut:Extension
Identificateur de Module:ext_filter_module
Fichier Source:mod_ext_filter.c

Sommaire

mod_ext_filter représente un modèle de programmation simple et bien connu pour les filtres. Avec ce module, tout programme qui lit l'entrée standard stdin et écrit sur la sortie standard stdout (autrement dit une commande filtre de style Unix) peut servir de filtre pour Apache. Ce mécanisme de filtrage est beaucoup plus lent qu'un filtre spécialement écrit pour l'API d'Apache et faisant partie intégrante du processus du serveur Apache, mais il présente les avantages suivants :

Même dans le cas où le niveau de performance est insuffisant pour une utilisation en production, on peut utiliser mod_ext_filter comme prototype d'environnement pour les filtres.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples

Générer du HTML à partir d'un autre type de contenu

# la directive de mod_ext_filter définissant un filtre
# permettant de mettre des fichiers text/c au format HTML en
# utilisant le programme externe /usr/bin/enscript, le type du
# fichier résultant étant défini à 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">
    # directive de base permettant de traiter la sortie avec le
    # nouveau filtre
    SetOutputFilter c-to-html

    # directive de mod_mime définissant le type des fichiers dont
    # le nom possède l'extension .c à text/c
    AddType text/c .c
</Directory>

Implémentation d'un filtre de codage de contenu

Note : cet exemple avec gzip n'est fourni qu'à titre d'illustration. Veuillez vous reporter à la documentation de mod_deflate pour un exemple d'implémentation plus pratique.

# la directive de mod_ext_filter qui définit le filtre externe
ExtFilterDefine gzip mode=output cmd=/bin/gzip

<Location "/gzipped">

    # directive de base permettant de traiter la sortie avec le
  # filtre gzip
    SetOutputFilter gzip

    # la directive de mod_headers permettant d'ajouter le champ
  # d'en-tête "Content-Encoding: gzip"
    Header set Content-Encoding gzip
</Location>

Ralentissement du serveur

# directive de mod_ext_filter définissant un filtre qui fait
# passer tous les flux en sortie par la commande cat ; cat ne
# modifie rien ; elle ne fait que compliquer le cheminement des
# flux et consommer des ressources supplémentaires
       ExtFilterDefine slowdown mode=output cmd=/bin/cat \
ExtFilterDefine slowdown mode=output cmd=/bin/cat \
    preservescontentlength

<Location "/">
    # directive de base permettant de traiter plusieurs fois la
    # sortie avec le filtre slowdown
    #
    SetOutputFilter slowdown;slowdown;slowdown
</Location>

Utilisation de sed pour remplacer du texte dans la réponse

# directive de mod_ext_filter définissant un filtre qui
# remplace du texte dans la réponse
#
ExtFilterDefine fixtext mode=output intype=text/html \
    cmd="/bin/sed s/verdana/arial/g"

<Location "/">
    # directive de base permettant de traiter la sortie avec le
    # filtre fixtext
    SetOutputFilter fixtext
</Location>

Vous pouvez aussi utiliser mod_substitute pour effectuer le même traitement sans avoir à invoquer un programme externe.

Tracer un autre filtre

# Trace les données lues et écrites par mod_deflate pour un
# client particulier (IP 192.168.1.31) qui a des problèmes de
# compression.
# Ce premier filtre va tracer ce qui entre dans mod_deflate.
ExtFilterDefine tracebefore \
    cmd="/bin/tracefilter.pl /tmp/tracebefore" \
    EnableEnv=trace_this_client

# Ce second filtre va tracer ce qui sort de mod_deflate.
# Notez que sans le paramètre ftype, le type de filtre par
# défaut AP_FTYPE_RESOURCE placerait le filtre *avant*
# mod_deflate dans la chaîne de filtrage. Le fait d'affecter
# à ce paramètre une valeur numérique sensiblement supérieure à
# AP_FTYPE_CONTENT_SET permet de s'assurer que le filtre sera
# placé après 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>

Voici le filtre qui trace les données :

#!/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

Directive ExtFilterDefine

Description:Définit un filtre externe
Syntaxe:ExtFilterDefine nom_filtre paramètres
Contexte:configuration globale
Statut:Extension
Module:mod_ext_filter

La directive ExtFilterDefine définit les caractéristiques d'un filtre externe, et en particulier le programme à exécuter ainsi que ses arguments.

nom_filtre spécifie le nom du filtre en cours de définition. On peut ensuite utiliser ce nom pour référencer le filtre dans les directives SetOutputFilter. Il doit être unique parmi les noms de tous les filtres enregistrés. Pour le moment, aucune erreur n'est signalée par l'API register-filter, si bien qu'un problème de noms dupliqués ne sera pas porté à la connaissance de l'utilisateur.

Viennent ensuite un ou plusieurs paramètres dans un ordre indéfini, qui permettent de spécifier la commande externe à exécuter et certaines autres caractéristiques. Le seul paramètre obligatoire est cmd=. Voici la liste de ces paramètres :

cmd=ligne de commande
Le mot-clé cmd= spécifie la commande externe à exécuter. Si la ligne de commande comporte des arguments, elle doit être entourée de guillemets (par exemple cmd="/bin/mypgm arg1 arg2"). Les guillemets habituels du shell ne sont pas nécessaires car le programme est lancé directement, sans passer par le shell. Les arguments du programme doivent être séparés par des espaces. Si un argument contient des espaces, ces derniers doivent être échappés par un antislash '\'. Si un argument contient des antislashes '\', ces derniers doivent être eux-mêmes échappés par un antislash '\'. Outre les variables d'environnement CGI standards, les variables DOCUMENT_URI, DOCUMENT_PATH_INFO, et QUERY_STRING_UNESCAPED seront également définies pour le programme.
mode=mode
Utilisez mode=output (valeur par défaut) pour les filtres qui traitent les réponses. Utilisez mode=input pour les filtres qui traitent les requêtes. mode=input est disponible depuis la version 2.1 d'Apache.
intype=type MIME
Ce paramètre spécifie le type de médium Internet (c'est à dire le type MIME) des documents qui doivent être filtrés. Par défaut, tous les documents sont filtrés. Aucun des documents possédant un type MIME autre que celui spécifié par intype= ne sera filtré.
outtype=type MIME
Ce paramètre spécifie le type de médium Internet (c'est à dire le type MIME) des documents filtrés. Il intervient lorsque les opérations de filtrage comprennent une modification du type MIME. Par défaut, le type MIME n'est pas modifié.
PreservesContentLength
Le mot-clé PreservesContentLength indique que le filtre doit conserver la taille du contenu. Ce n'est pas le comportement par défaut, car la plupart des filtres modifient cette taille. Ce mot-clé doit être spécifié si le filtre ne doit pas modifier la taille du contenu.
ftype=type de filtre
Ce paramètre spécifie une valeur numérique représentant le type de filtre sous lequel le filtre doit être enregistré. La valeur par défaut, AP_FTYPE_RESOURCE, convient dans la plupart des situations. Ce paramètre devient nécessaire dès lors que le filtre doit opérer à un autre point de la chaîne de filtrage que les filtres de ressources. Voir les définitions de AP_FTYPE_... dans util_filter.h pour trouver une valeur appropriée.
disableenv=env
Ce paramètre spécifie le nom d'une variable d'environnement qui, si elle est définie, va désactiver le filtre.
enableenv=env
Ce paramètre spécifie le nom d'une variable d'environnement qui doit être définie pour que le filtre ne soit pas désactivé.
top

Directive ExtFilterOptions

Description:Configure les options de mod_ext_filter
Syntaxe:ExtFilterOptions option [option] ...
Défaut:ExtFilterOptions NoLogStderr
Contexte:répertoire
Statut:Extension
Module:mod_ext_filter

La directive ExtFilterOptions spécifie des options de traitement particulières pour mod_ext_filter. Les arguments option peuvent contenir :

LogStderr | NoLogStderr
Le mot-clé LogStderr indique que les messages envoyés par le programme de filtrage externe sur la sortie d'erreurs standard doivent être enregistrés dans le journal des erreurs d'Apache. NoLogStderr inverse ce comportement.
Onfail=[abort|remove]
Indique la marche à suivre si le programme de filtrage externe ne peut pas démarrer. Avec abort (la valeur par défaut), le traitement de la requête sera abandonné. Avec remove, le filtre est supprimé, et le traitement de la requête se poursuit sans lui.
ExtFilterOptions LogStderr

Les messages envoyés vers la sortie d'erreurs standard du filtre seront enregistrés dans le journal des erreurs d'Apache.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_headers.html.fr.utf80000664000175100017510000011233114740503670022250 0ustar covenercovener mod_headers - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_headers

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Personnalisation des en-têtes de requêtes et de réponses HTTP
Statut:Extension
Identificateur de Module:headers_module
Fichier Source:mod_headers.c

Sommaire

Ce module fournit des directives permettant de contrôler et modifier les en-têtes de requêtes et de réponses HTTP. Les en-têtes peuvent être fusionnés, remplacés ou supprimés.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Chronologie du traitement

Les directives fournies par mod_headers peuvent s'insérer presque partout dans la configuration du serveur, et on peut limiter leur portée en les plaçant dans des sections de configuration.

La chronologie du traitement est importante et est affectée par l'ordre d'apparition des directives dans le fichier de configuration et par leur placement dans les sections de configuration. Ainsi, ces deux directives ont un effet différent si leur ordre est inversé :

RequestHeader append MirrorID "mirror 12"
RequestHeader unset MirrorID

Dans cet ordre, l'en-tête MirrorID n'est pas défini. Si l'ordre des directives était inversé, l'en-tête MirrorID serait défini à "mirror 12".

top

Traitement précoce et traitement tardif

mod_headers peut agir soir précocement, soit tardivement au niveau de la requête. Le mode normal est le mode tardif, lorsque les en-têtes de requête sont définis, immédiatement avant l'exécution du générateur de contenu, et pour les en-têtes de réponse, juste au moment où la réponse est envoyée sur le réseau. Utilisez toujours le mode tardif sur un serveur en production.

Le mode précoce a été conçu à des fins d'aide aux tests et au débogage pour les développeurs. Les directives définies en utilisant le mot-clé early sont censées agir au tout début du traitement de la requête. Cela signifie que l'on peut les utiliser pour simuler différentes requêtes et définir des situations de test, tout en gardant à l'esprit que les en-têtes peuvent être modifiés à tout moment par d'autres modules avant que le réponse ne soit générée.

Comme les directives précoces sont traitées avant que le chemin de la requête ne soit parcouru, les en-têtes précoces ne peuvent être définis que dans un contexte de serveur principal ou de serveur virtuel. Les directives précoces ne peuvent pas dépendre d'un chemin de requête, si bien qu'elles échoueront dans des contextes tels que <Directory> ou <Location>.

top

Exemples

  1. Copie tous les en-têtes de requête qui commencent par "TS" vers les en-têtes de la réponse :
    Header echo ^TS
  2. Ajoute à la réponse un en-tête, mon-en-tête, qui contient un horodatage permettant de déterminer le moment où la requête a été reçue, et le temps qui s'est écoulé jusqu'à ce que la requête ait commencé à être servie. Cet en-tête peut être utilisé par le client pour estimer la charge du serveur ou isoler les goulets d'étranglement entre le client et le serveur.
    Header set mon-en-tête "%D %t"

    le résultat est l'ajout à la réponse d'un en-tête du type :

    mon-en-tête: D=3775428 t=991424704447256

  3. Dit Bonjour à Joe

    Header set mon-en-tête "Bonjour Joe. Il a fallu %D microsecondes \
    à Apache pour servir cette requête."

    le résultat est l'ajout à la réponse d'un en-tête du type :

    	Header set MyHeader "Bonjour Joe. Il a fallu D=3775428 microsecondes à Apache
              pour servir cette requête."
  4. Ajoute l'en-tête mon-en-tête à la réponse si et seulement si l'en-tête mon-en-tête-requête est présent dans la requête. Ceci peut s'avérer utile pour générer des en-têtes de réponse "à la tête du client". Notez que cet exemple nécessite les services du module mod_setenvif.
    SetEnvIf MyRequestHeader myvalue HAVE_MyRequestHeader
    Header set MyHeader "%D %t mytext" env=HAVE_MyRequestHeader

    Si l'en-tête mon-en-tête-requête: mavaleur est présent dans la requête HTTP, la réponse contiendra un en-tête du type :

    mon-en-tête: D=3775428 t=991424704447256 montexte

  5. Permet à DAV de fonctionner avec Apache sur SSL (voir la description du problème) en remplaçant https: par http: dans l'en-tête Destination :
    RequestHeader edit Destination ^https: http: early
  6. Définit la valeur d'un même en-tête sous de multiples conditions non exclusives, mais ne duplique pas une valeur déjà définie dans l'en-tête qui en résulte. Si toutes les conditions suivantes sont satisfaites pour une requête (en d'autres termes, si les trois variables d'environnement CGI, NO_CACHE et NO_STORE existent pour la requête) :
    Header merge Cache-Control no-cache env=CGI
    Header merge Cache-Control no-cache env=NO_CACHE
    Header merge Cache-Control no-store env=NO_STORE

    alors, la réponse contiendra l'en-tête suivant :

    Cache-Control: no-cache, no-store

    Si append avait été utilisé à la place de merge, la réponse aurait contenu l'en-tête suivant :

    Cache-Control: no-cache, no-cache, no-store

  7. Définit un cookie de test si et seulement si le client n'envoie pas de cookie
    Header set Set-Cookie testcookie "expr=-z %{req:Cookie}"
  8. Ajoute un en-tête de mise en cache pour les réponses avec un code d'état HTTP de 200
    Header append Cache-Control s-maxage=600 "expr=%{REQUEST_STATUS} == 200"
top

Directive Header

Description:Configure les en-têtes d'une réponse HTTP
Syntaxe:Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note en-tête [[expr=]valeur [remplacement] [early|env=[!]variable|expr=expression]]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_headers
Compatibilité:SetIfEmpty est disponible depuis la version 2.4.7 du serveur HTTP Apache ; le paramètre expr=valeur a été introduit avec la version 2.4.10

Cette directive permet de remplacer, fusionner, ou supprimer des en-têtes de réponse HTTP. L'en-tête est modifié juste après que le gestionnaire de contenu et les filtres en sortie ne s'exécutent, ce qui permet la modification des en-têtes sortants.

L'argument optionnel condition permet de déterminer sur quelle table interne d'en-têtes de réponses cette directive va opérer : onsuccess (valeur par défaut, peut être omis) ou always. A la différence de ceux de la première table, les en-têtes de la seconde sont ajoutés à la réponse même en cas d'erreur et sont conservés au fil des redirections internes (par exemple les gestionnaires ErrorDocument). Notez aussi que la répétition de cette directive avec les deux conditions peut être pertinente dans certains scénarios, car always n'englobe pas onsuccess en ce qui concerne les en-têtes existants :

Comme il n'y a pas de liste unique "normalisée" d'en-têtes, la manière dont httpd stocke en interne les en-têtes des réponses HTTP est à l'origine de la fonctionnalité que constitue la différence entre onsuccess et always. Si vous ne gardez pas à l'esprit le concept ci-après lors de l'écriture de votre configuration, certaines réponses HTTP pourront contenir des en-têtes dupliqués (ce qui pourra dérouter les utilisateurs ou même parfois les clients HTTP). Supposons par exemple que votre configuration comporte un mandataire PHP simple avec mod_proxy_fcgi et que votre script PHP d'arrière-plan ajoute l'en-tête X-Foo: bar à chaque réponse HTTP. Comme décrit plus haut, mod_proxy_fcgi utilise la table always pour stocker les en-têtes, et une configuration comme la suivante n'aboutira pas au résultat attendu car l'en-tête sera dupliqué avec les deux valeurs :

# la valeur de X-Foo est définie dans la table d'en-têtes 'onsuccess'
Header set X-Foo: baz

Plusieurs modèles de configuration permettent de contourner ce problème, comme celui-ci :

# 'onsuccess' peut être omis car il s'agit de la valeur par défaut
Header onsuccess unset X-Foo
Header always set X-Foo "baz"

Outre le paramètre condition décrit ci-dessus, vous pouvez limiter une action en fonction de codes d'état HTTP, par exemple pour les requêtes mandatées ou générées par un programme CGI. Voir l'exemple qui utilise %{REQUEST_STATUS} dans la section ci-dessus.

L'action que cette directive provoque est déterminée par le premier argument (ou par le second argument si une condition est spécifiée). Il peut prendre une des valeurs suivantes :

Avertissement

Vous devez lire la différence, décrite plus haut, entre les listes d'en-têtes always et onsuccess avant de lire la liste d'actions ci-dessous car cet important concept s'applique encore ici. En fait, chaque action fonctionne telle qu'elle est décrite mais seulement pour la liste d'en-têtes cible.

add
L'en-tête est ajouté au jeu d'en-têtes préexistant, même s'il existe déjà. Ceci peut conduire à la présence de deux (ou plusieurs) en-têtes possèdant le même nom et donc induire des conséquences imprévues ; en général, il est préférable d'utiliser set, append ou merge.
append
La valeur d'en-tête est ajoutée à tout en-tête existant de même nom. Lorsqu'une nouvelle valeur est ainsi ajoutée, elle est séparée de celles qui sont déjà présentes par une virgule. Il s'agit de la méthode HTTP standard permettant d'affecter plusieurs valeurs à un en-tête.
echo
Les en-têtes de la requête possédant le nom spécifié sont recopiés vers les en-têtes de la réponse. en-tête peut être une expression rationnelle, et valeur ne doit pas être présent.
edit
edit*
Si l'en-tête existe, sa valeur est modifiée en fonction d'une expression rationnelle de type recherche/remplacement. L'argument valeur est une expression rationnelle, et l'argument remplacement une chaîne de caractères de remplacement qui peut contenir des références arrières ou des spécificateurs de format. La forme edit n'effectuera une recherche/remplacement qu'une seule fois dans la valeur de l'en-tête, alors que la forme edit* en effectuera autant que le nombre d'apparition de la chaîne à remplacer.
merge
La valeur d'en-tête est ajoutée à tout en-tête de même nom, sauf si elle apparaît déjà dans la liste des valeurs préexistantes de l'en-tête séparées par des virgules. Lorsqu'une nouvelle valeur est ainsi ajoutée, elle est séparée de celles qui sont déjà présentes par une virgule. Il s'agit de la méthode HTTP standard permettant d'affecter plusieurs valeurs à un en-tête. Les valeurs sont comparées en tenant compte de la casse, et après le traitement de tous les spécificateurs de format. Une valeur entourée de guillemets est considérée comme différente de la même valeur mais sans guillemets.
set
L'en-tête est défini, remplaçant tout en-tête préexistant avec le même nom. L'argument valeur peut être une chaîne de formatage.
setifempty
L'en-tête est défini, mais seulement s'il n'existe aucun en-tête avec le même nom.
L'en-tête Content-Type est un cas particulier car il est possible que sa valeur ait été déterminée mais que l'en-tête ne soit pas présent dans la réponse lorsque setifempty est évalué. Dans ce cas, il est préférable d'utiliser set comme dans l'exemple suivant :
Header set Content-Type "text/plain" "expr=-z %{CONTENT_TYPE}"
unset
L'en-tête est supprimé s'il existe. Si plusieurs en-têtes possèdent le même nom, ils seront tous supprimés. L'argument value ne doit pas apparaître.
note
La valeur de l'en-tête considéré est copiée dans une note interne dont le nom est spécifié via l'argument valeur. Ceci permet de journaliser la valeur d'un en-tête envoyé par un programme CGI ou une ressource mandatée, même s'il est prévu de l'effacer.
Disponible à partir de la version 2.4.7 du serveur HTTP Apache.

Cet argument est suivi d'un nom d'en-tête qui peut se terminer par un caractère ':', mais ce n'est pas obligatoire. La casse est ignorée avec set, append, merge, add, unset et edit. Le nom d'en-tête est sensible à la casse pour echo et peut être une expression rationnelle.

Avec set, append, merge et add, une valeur est spécifiée comme argument suivant. Si valeur contient des espaces, elle doit être entourée de guillemets. valeur peut être une chaîne de caractères, une chaîne contenant des spécificateurs de format propres à mod_headers (et des caractères littéraux), ou une expression ap_expr préfixée par expr=.

valeur supporte les spécificateurs de format suivants :

FormatDescription
%% Le caractère pourcentage
%t Le moment de réception de la requête en temps universel coordonné depuis le temps epoch (Jan. 1, 1970) et exprimé en microsecondes. La valeur est précédée de t=.
%D Le temps écoulé entre la réception de la requête et l'envoi des en-têtes sur le réseau. Il s'agit de la durée de traitement de la requête. La valeur est précédée de D=. La valeur est exprimée en microsecondes.
%l La charge moyenne courante du serveur proprement dit. Ce sont les valeurs obtenues par getloadavg() qui représentent la charge moyenne courante, sur 5 minutes et sur 15 minutes. Chaque valeur est précédée de l= et séparée de la suivante par un /.
Disponible depuis la version 2.4.4 du serveur HTTP Apache.
%i Le pourcentage courant de httpd au repos (de 0 à 100) en se basant sur le nombre de processus et threads disponibles. La valeur est précédée de i=.
Disponible depuis la version 2.4.4 du serveur HTTP Apache.
%b Le pourcentage courant de httpd utilisé (de 0 à 100) en se basant sur le nombre de processus et threads disponibles. La valeur est précédée de b=.
Disponible depuis la version 2.4.4 du serveur HTTP Apache.
%{NOM_VARIABLE}e Le contenu de la variable d'environnement NOM_VARIABLE.
%{NOM_VARIABLE}s Le contenu de la variable d'environnement SSL NOM_VARIABLE, si mod_ssl est activé.

Note

Le spécificateur de format %s est disponible depuis la version 2.1 d'Apache ; il peut être utilisé à la place de %e pour éviter de devoir spécifier SSLOptions +StdEnvVars. Cependant, si SSLOptions +StdEnvVars doit tout de même être spécifié pour une raison quelconque, %e sera plus efficace que %s.

Note à propos des valeurs des expressions

Lorsque le paramètre valeur utilise l'interpréteur ap_expr, certaines syntaxes d'expressions seront différentes des exemples qui évaluent des expressions booléennes telles que <If> :

  • Le point de départ de la syntaxe est 'string' au lieu de 'expr'.
  • Les appels de fonction utilisent la syntaxe %{funcname:arg} au lieu de funcname(arg).
  • Les fonctions multi-arguments ne sont pas encore disponibles depuis le point de départ 'string'.
  • Il faut mettre entre guillemets l'ensemble du paramètre, comme dans l'exemple suivant :
    Header set foo-checksum "expr=%{md5:foo}"

editnécessite les deux arguments valeur, qui est une expression rationnelle, et une chaîne additionnelle remplacement. Depuis la version 2.4.7, la chaîne de remplacement peut aussi contenir des spécificateurs de format.

La directive Header peut être suivie d'un argument additionnel qui peut prendre les valeurs suivantes :

early
Spécifie traitement préalable.
env=[!]variable
La directive est appliquée si et seulement si la variable d'environnement variable existe. Un ! devant variable inverse le test, et la directive ne s'appliquera alors que si variable n'est pas définie.
expr=expression
La directive s'applique si et seulement si expression est évaluée à true. Vous trouverez plus de détails à propos de la syntaxe et de l'évaluation des expressions dans la documentation ap_expr.
         # Cet exemple retarde l'évaluation de la clause de condition par
	 # rapport à <If>
         Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path.php$#"

Excepté le cas du mode précoce, les directives Header sont traitées juste avant l'envoi de la réponse sur le réseau. Cela signifie qu'il est possible de définir et/ou modifier la plupart des en-têtes, à l'exception de certains en-têtes qui sont ajoutés par le filtre d'en-tête HTTP. Avant la version 2.2.12, il n'était pas possible de modifier l'en-tête Content-Type avec cette directive.

top

Directive RequestHeader

Description:Configure les en-têtes d'une requête HTTP
Syntaxe:RequestHeader add|append|edit|edit*|merge|set|setifempty|unset en-tête [[expr=]valeur [remplacement] [early|env=[!]variable|expr=expression]]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_headers
Compatibilité:SetIfEmpty est disponible depuis la version 2.4.7 du serveur HTTP Apache ; le paramètre expr=valeur a été introduit avec la version 2.4.10

Cette directive permet de remplacer, fusionner, modifier ou supprimer des en-têtes de requête HTTP. L'en-tête est modifié juste avant que le gestionnaire de contenu ne s'exécute, ce qui permet la modification des en-têtes entrants. L'action effectuée est déterminée par le premier argument. Ce dernier accepte les valeurs suivantes :

add
L'en-tête est ajouté au jeu d'en-têtes préexistant, même s'il existe déjà. Ceci peut conduire à la présence de deux (ou plusieurs) en-têtes possèdant le même nom et donc induire des conséquences imprévues ; en général, il est préférable d'utiliser set, append ou merge.
append
La valeur d'en-tête est ajoutée à tout en-tête existant de même nom. Lorsqu'une nouvelle valeur est ainsi ajoutée, elle est séparée de celles qui sont déjà présentes par une virgule. Il s'agit de la méthode HTTP standard permettant d'affecter plusieurs valeurs à un en-tête.
edit
edit*
Si l'en-tête existe, sa valeur est modifiée en fonction d'une expression rationnelle de type recherche/remplacement. L'argument valeur est une expression rationnelle, et l'argument remplacement une chaîne de caractères de remplacement qui peut contenir des références arrières ou des spécificateurs de format. Avec edit, la chaîne de l'en-tête correspondant au modèle ne sera recherchée et remplacée qu'une seule fois, alors qu'avec edit*, elle le sera pour chacune de ses instances si elle apparaît plusieurs fois.
merge
La valeur d'en-tête est ajoutée à tout en-tête de même nom, sauf si elle apparaît déjà dans la liste des valeurs préexistantes de l'en-tête séparées par des virgules. Lorsqu'une nouvelle valeur est ainsi ajoutée, elle est séparée de celles qui sont déjà présentes par une virgule. Il s'agit de la méthode HTTP standard permettant d'affecter plusieurs valeurs à un en-tête. Les valeurs sont comparées en tenant compte de la casse, et après le traitement de tous les spécificateurs de format. Une valeur entourée de guillemets est considérée comme différente de la même valeur mais sans guillemets.
set
L'en-tête est défini, remplaçant tout en-tête préexistant avec le même nom.
setifempty
L'en-tête est défini, mais seulement s'il n'existe aucun en-tête avec le même nom.
Disponible depuis la version 2.4.7 du serveur HTTP Apache.
unset
L'en-tête est supprimé s'il existe. Si plusieurs en-têtes possèdent le même nom, ils seront tous supprimés. L'argument value ne doit pas apparaître.

Cet argument est suivi d'un nom d'en-tête qui peut se terminer par un caractère ':', mais ce n'est pas obligatoire. La casse est ignorée. Avec set, append, merge et add, une valeur est fournie en troisième argument. Si une valeur contient des espaces, elle doit être entourée de guillemets. Avec unset, aucune valeur ne doit apparaître. valeur peut être une chaîne de caractères, une chaîne contenant des spécificateurs de format, ou une combinaison des deux. Les spécificateurs de format supportés sont les mêmes que ceux de la directive Header, à laquelle vous pouvez vous reporter pour plus de détails. Avec edit, les deux arguments valeur et remplacement sont obligatoires, et correspondent respectivement à une expression rationnelle et à une chaîne de remplacement.

La directive RequestHeader peut être suivie d'un argument supplémentaire, qui pourra prendre les valeurs suivantes :

early
Spécifie traitement préalable.
env=[!]variable
La directive est appliquée si et seulement si la variable d'environnement variable existe. Un ! devant variable inverse le test, et la directive ne s'appliquera alors que si variable n'est pas définie.
expr=expression
La directive s'applique si et seulement si expression est évaluée à true. Vous trouverez plus de détails à propos de la syntaxe et de l'évaluation des expressions dans la documentation ap_expr.

Excepté le cas du mode précoce, la directive RequestHeader est traitée juste avant la prise en compte de la requête par son gestionnaire, au cours de la phase de vérification. Ceci permet la modification des en-têtes générés par le navigateur, ou par les filtres en entrée d'Apache.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ident.html.fr.utf80000664000175100017510000002471614740503670021751 0ustar covenercovener mod_ident - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_ident

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Recherche d'identité conformément à la RFC 1413
Statut:Extension
Identificateur de Module:ident_module
Fichier Source:mod_ident.c
Compatibilité:Disponible depuis la version 2.2 d'Apache

Sommaire

Ce module interroge un démon compatible RFC 1413 sur un serveur distant afin de déterminer le propriétaire d'une connexion.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive IdentityCheck

Description:Active la journalisation de l'identité RFC 1413 de l'utilisateur distant
Syntaxe:IdentityCheck On|Off
Défaut:IdentityCheck Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_ident
Compatibilité:Retiré du serveur de base depuis Apache 2.1

Cette directive permet d'activer la journalisation compatible RFC 1413 du nom de l'utilisateur distant pour chaque connexion, si la machine du client exécute identd ou un démon similaire. Cette information est enregistrée dans le journal des accès en utilisant la chaîne de formatage %...l.

Cette information ne doit pas faire l'objet d'une confiance absolue, et elle ne doit être utilisée que dans le cadre d'un traçage grossier.

Notez que de sérieux problèmes de délais peuvent survenir lors des accès à votre serveur, car chaque requête nécessite l'exécution d'un de ces processus de recherche. Lorsque des pare-feu ou des serveurs mandataires sont impliqués, chaque recherche est susceptible d'échouer et ajouter un temps de latence conformément à la directive IdentityCheckTimeout. En général, ces recherches ne se révèlent donc pas très utiles sur des serveurs publics accessibles depuis l'Internet.

top

Directive IdentityCheckTimeout

Description:Détermine le délai d'attente pour les requêtes ident
Syntaxe:IdentityCheckTimeout secondes
Défaut:IdentityCheckTimeout 30
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_ident

Cette directive permet de spécifier le délai d'attente d'une requête ident. Une valeur par défaut de 30 secondes est recommandée par la RFC 1413, principalement pour prévenir les problèmes qui pourraient être induits par la charge du réseau. Vous pouvez cependant ajuster la valeur de ce délai en fonction du débit de votre réseau local.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_info.html.fr.utf80000664000175100017510000003704114740503670021574 0ustar covenercovener mod_info - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_info

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Affiche une présentation complète de la configuration du serveur
Statut:Extension
Identificateur de Module:info_module
Fichier Source:mod_info.c

Sommaire

Pour activer mod_info, ajoutez les lignes suivantes à votre fichier httpd.conf.

<Location "/server-info">
    SetHandler server-info
</Location>

Il est recommandé d'utiliser mod_authz_host à l'intérieur de la section <Location> afin de restreindre l'accès aux informations de configuration de votre serveur :

<Location "/server-info">
    SetHandler server-info
    Require host example.com
</Location>

Une fois cette configuration effectuée, les informations du serveur sont disponibles à l'adresse http://votre-serveur.com/infos-serveur.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Problèmes liés à la sécurité

Une fois mod_info chargé dans le serveur, sa fonctionnalité de gestionnaire est disponible dans tous les fichiers de configuration, y compris les fichiers de configuration des répertoires (par exemple .htaccess). Ceci peut avoir des répercutions en matière de sécurité pour votre site.

En particulier, l'utilisation de ce module peut conduire à la divulgation d'informations sensibles à partir des directives de configuration d'autres modules Apache comme des chemins systèmes, des couples nom d'utilisateur/mot de passe, des noms de bases de données, etc... C'est pourquoi ce module ne doit être utilisé que dans un environnement sous contrôle et toujours avec les plus grandes précautions.

Il est recommandé d'utiliser mod_authz_host pour restreindre l'accès aux informations de configuration de votre serveur.

Contrôle d'accès

<Location "/server-info">
    SetHandler server-info
    # Autorisation d'accès depuis le serveur lui-même
    Require ip 127.0.0.1

    # Autorisation d'accès depuis une station de travail du réseau
# local
    Require ip 192.168.1.17
</Location>
top

Filtrage des informations affichées

Par défaut, les informations affichées comprennent une liste de tous les modules activés, et pour chaque module, une description des directives qu'il accepte, les branchements (hooks) qu'il implémente, ainsi que les directives concernées dans la configuration courante.

Il est possible d'afficher d'autres vues de la configuration en ajoutant un argument à la requête infos-serveur. Par exemple, http://votre-serveur.com/infos-serveur?config affichera toutes les directives de configuration.

?<module-name>
Uniquement les informations relatives au module spécifié
?config
Uniquement les directives de configuration, non triées par module
?hooks
Uniquement la liste des branchements (hooks) auxquels le module est attaché
?list
Une simple liste des modules activés
?server
Uniquement des informations de base sur le serveur
?providers
Liste des fournisseurs disponibles sur votre serveur
top

Affichage de la configuration au démarrage

Si la directive de configuration define -DDUMP_CONFIG est utilisée, mod_info va envoyer la configuration préinterprétée vers stdout au cours du démarrage du serveur.

httpd -DDUMP_CONFIG -k start

"Préinterprétée" signifie que les directives telles que <IfDefine> et <IfModule> sont évaluées et les variables d'environnement remplacées par leurs valeurs. Cela ne représente cependant pas la configuration définitive. En particulier, les fusions ou écrasementsde définitions en cas de directives multiples ne sont pas représentés.

Le résultat est équivalent à celui de la requête ?config.

top

Limitations connues

mod_info tire ses informations de la configuration interprétée, et non du fichier de configuration original. La manière dont l'arbre de configuration interprété est créé induit quelques limitations :

top

Directive AddModuleInfo

Description:Ajoute des données supplémentaires aux informations de module affichées par le gestionnaire server-info
Syntaxe:AddModuleInfo nom-module chaîne
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_info

Cette directive permet d'afficher le contenu de chaîne en tant qu'Information supplémentaire interprétée en HTML pour le module nom-module. Exemple :

AddModuleInfo mod_deflate.c 'See <a \
    href="http://httpd.apache.org/docs/2.4/mod/mod_deflate.html">\
    http://httpd.apache.org/docs/2.4/mod/mod_deflate.html</a>'

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_echo.html.fr.utf80000664000175100017510000001712214740503670021555 0ustar covenercovener mod_echo - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_echo

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Un simple serveur d'écho pour illustrer les modules de protocole
Statut:Expérimental
Identificateur de Module:echo_module
Fichier Source:mod_echo.c

Sommaire

Ce module est un module de protocole exemple permettant d'en illustrer le concept. Il fournit un simple serveur d'écho. Envoyez lui une phrase par telnet, et il vous la renverra.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive ProtocolEcho

Description:Active ou désactive le serveur d'écho
Syntaxe:ProtocolEcho On|Off
Défaut:ProtocolEcho Off
Contexte:configuration globale, serveur virtuel
Statut:Expérimental
Module:mod_echo

La directive ProtocolEcho permet d'activer ou de désactiver le serveur d'écho.

Exemple

ProtocolEcho On

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_expires.html.fr.utf80000664000175100017510000004347714740503670022332 0ustar covenercovener mod_expires - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_expires

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Génération des en-têtes HTTP Expires et Cache-Control en fonction de critères spécifiés par l'utilisateur
Statut:Extension
Identificateur de Module:expires_module
Fichier Source:mod_expires.c

Sommaire

Ce module permet de contrôler la définition de l'en-tête HTTP Expires et la directive max-age de l'en-tête HTTP Cache-Control dans les réponses du serveur. La date d'expiration peut être définie soit par rapport à la date de dernière modification du fichier source, soit par rapport à l'heure d'accès du client.

Ces en-têtes HTTP permettent d'informer le client quant à la validité et à la persistence du document. S'il est présent dans le cache, et tant qu'il n'est pas arrivé à expiration, le document sera servi à partir de ce dernier, plutôt qu'à partir du document source. Après expiration, la copie du document dans le cache sera considérée comme "expirée" et donc invalide, et une nouvelle copie devra être obtenue à partir du document source.

Pour modifier les directives de contrôle du cache autres que max-age (voir la RFC 2616 section 14.9), vous pouvez utiliser la directive Header.

Lorsque l'en-tête Expires est déjà présent dans la réponse générée par le serveur, par exemple s'il a été créé par un script CGI ou un serveur original via un serveur mandataire, ce module n'ajoute aucun en-tête Expires ou Cache-Control.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Autre syntaxe de définition de l'intervalle

Pour une syntaxe plus lisible, on peut aussi utiliser les directives ExpiresDefault et ExpiresByType comme suit :

ExpiresDefault "base  [plus num type] [num type] ..."
ExpiresByType type/encoding "base  [plus num type] [num type] ..."

base peut être :

Le mot-clé plus est optionnel. num doit correspondre à une valeur entière [compatible avec atoi()], et type peut être choisi parmi :

Par exemple, pour faire expirer par défaut les documents 1 mois après leur accès, on peut utiliser une des directives suivantes :

ExpiresDefault "access plus 1 month"
ExpiresDefault "access plus 4 weeks"
ExpiresDefault "access plus 30 days"

La date d'expiration peut être définie plus précisément en ajoutant plusieurs clauses 'num type' :

ExpiresByType text/html "access plus 1 month 15 days 2 hours"
ExpiresByType image/gif "modification plus 5 hours 3 minutes"

Notez que si vous utilisez une configuration basée sur la date de modification, l'en-tête Expires ne sera pas ajouté à un contenu qui ne provient pas directement d'un fichier sur disque ; et ceci tout simplement parce que ce type de contenu ne possède pas de date de modification.

top

Directive ExpiresActive

Description:Active la génération d'en-têtes Expires
Syntaxe:ExpiresActive On|Off
Défaut:ExpiresActive Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Extension
Module:mod_expires

Cette directive permet d'activer ou de désactiver la génération des en-têtes Expires et Cache-Control pour les documents concernés ; en d'autres termes, si cette directive se trouve dans un fichier .htaccess, par exemple, elle ne s'applique qu'aux documents générés à partir du répertoire considéré. Si elle est définie à Off, les en-têtes ne seront générés pour aucun document du domaine considéré (sauf surcharge de la configuration à un niveau inférieur, comme un fichier .htaccess qui l'emporterait sur le fichier de configuration du serveur). Si elle est définie à On, les en-têtes seront ajoutés aux documents servis en fonction des critères définis par les directives ExpiresByType et ExpiresDefault (voir plus loin).

Notez que cette directive ne permet pas de garantir qu'un en-tête Expires ou Cache-Control sera généré. Si les critères ne sont pas respectés, aucun en-tête ne sera généré, et la directive produira le même effet que si elle n'avait pas été définie.

top

Directive ExpiresByType

Description:Définition de la valeur de l'en-tête Expires en fonction du type MIME
Syntaxe:ExpiresByType type MIME <code>secondes
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Extension
Module:mod_expires

Cette directive permet de définir la valeur de l'en-tête Expires et de la directive max-age de l'en-tête Cache-Control générés pour les documents du type MIME spécifié (par exemple, text/html). Le second argument définit le nombre de secondes qui seront ajoutées à un temps de base pour calculer la date d'expiration. Cache-Control: max-age se calcule en soustrayant la date de la requête de la date d'expiration et s'exprime en secondes.

Le champ <code> permet de spécifier quel temps doit être utilisé comme temps de base; M signifie que c'est la date de dernière modification du fichier qui doit être utilisée comme temps de base, alors que A signifie que c'est le moment où le client a accédé au document qui doit être utilisé comme temps de base.

La différence d'effet est subtile. Si on utilise M, toutes les copies existantes du document dans tous les caches expireront au même moment, ce qui peut convenir par exemple pour une notice hebdomadaire qui correspond toujours à la même URL. Si on utilise A, la date d'expiration sera différente pour chaque client, ce qui peut convenir pour des fichiers d'images qui ne changent pas très souvent, et en particulier pour un ensemble de documents en relation qui se réfèrent tous aux mêmes images (ces images sont alors accédées de manière répétitive dans un intervalle de temps assez court).

Exemple :

# active la génération des en-têtes Expires
ExpiresActive On
# les images GIF expirent au bout d'un mois dans le cache du
# client
ExpiresByType image/gif A2592000
# les documents HTML restent valables une semaine après leur date
# de dernière modification
ExpiresByType text/html M604800

Notez que cette directive ne produit d'effet que si ExpiresActive On a été spécifié. Elle l'emporte, mais seulement pour le type MIME spécifié, sur toute date d'expiration définie par la directive ExpiresDefault.

Vous pouvez aussi définir le mode de calcul de la date d'expiration en utilisant une syntaxe alternative, comme décrit plus haut dans ce document.

top

Directive ExpiresDefault

Description:Mode de calcul par défaut de la date d'expiration
Syntaxe:ExpiresDefault <code>secondes
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Extension
Module:mod_expires

Cette directive permet de définir le mode de calcul par défaut de la date d'expiration pour tous les documents du domaine considéré. Elle peut être annulée pour certains types de documents par la directive ExpiresByType. Voir la description de cette dernière directive pour plus de détails à propos de la syntaxe de l'argument, ainsi que la description de la syntaxe alternative.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_filter.html.fr.utf80000664000175100017510000010550014740503670022122 0ustar covenercovener mod_filter - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_filter

Langues Disponibles:  en  |  fr 

Description:Module de configuration de filtre intelligent sensible au contexte
Statut:Base
Identificateur de Module:filter_module
Fichier Source:mod_filter.c
Compatibilité:Versions 2.1 et supérieures

Sommaire

Ce module permet une configuration intelligente et dépendant du contexte des filtres de contenu en sortie. Par exemple, Apache peut être configuré pour faire traiter différents types de contenus par différents filtres, même lorsque le type de contenu n'est pas connu à l'avance (par exemple dans un serveur mandataire).

Le fonctionnement de mod_filter consiste à introduire des branchements dans la chaîne de filtrage. Plutôt que d'insérer directement des filtres dans la chaîne, on insère un sélecteur de filtre qui va effectuer un branchement conditionnel vers un fournisseur de filtre. mod_filter peut utiliser tout filtre de contenu comme fournisseur ; aucune modification des modules de filtrage existants n'est nécessaire (bien qu'il soit tout de même possible de les simplifier).

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Filtrage intelligent

Dans le modèle de filtrage traditionnel, les filtres sont insérés sans condition à l'aide de la directive AddOutputFilter et des directives apparentées. Chaque filtre doit ensuite déterminer s'il doit s'exécuter ou non, et les administrateurs du serveur disposent de peu de souplesse pour faire en sorte que la chaîne soit traitée de manière dynamique.

mod_filter, à l'opposé, fournit aux administrateurs du serveur un grand degré de souplesse pour configurer la chaîne de filtrage. Concrètement, la décision d'insérer un filtre peut être prise en fonction d'une expression booléenne complexe. Ceci généralise le fonctionnement relativement souple de la directive AddOutputFilterByType.

top

Déclarations de filtres, fournisseurs et chaînes

[Cette image illustre le modèle de filtrage traditionnel]
Figure 1: Le modèle de filtrage traditionnel

Dans le modèle traditionnel, les filtres en sortie constituent une simple chaîne s'étendant depuis le générateur de contenu (ou gestionnaire) jusqu'au client. Ce fonctionnement peut convenir s'il permet d'atteindre le but recherché, mais pose problème lorsque cette chaîne doit être configurée dynamiquement en fonction de la sortie du gestionnaire.

[Cette image illustre le modèle de fonctionnement de     mod_filter]
Figure 2: Le modèle de fonctionnement de mod_filter

Le fonctionnement de mod_filter consiste à introduire des branchements dans la chaîne de filtrage. Plutôt que d'insérer directement des filtres dans la chaîne, on insère un sélecteur de filtre qui va effectuer un branchement conditionnel vers un fournisseur de filtre. mod_filter peut utiliser tout filtre de contenu comme fournisseur ; aucune modification des modules de filtrage existants n'est nécessaire (bien qu'il soit tout de même possible de les simplifier). Il peut y avoir plusieurs fournisseurs pour un seul filtre, mais un seul fournisseur sera choisi pour chaque requête.

Une chaîne de filtrage peut comporter autant d'instances du sélecteur de filtre que l'on souhaite, chacune d'entre elles pouvant disposer de plusieurs fournisseurs. Un sélecteur de filtre possédant un seul fournisseur dont le choix est inconditionnel constitue un cas particulier : cette situation est équivalente à l'insertion directe du filtre dans la chaîne.

top

Configuration de la chaîne de filtrage

Trois étapes sont nécessaires pour configurer une chaîne de filtrage avec mod_filter. Voir ci-dessous la description détaillée des directives.

Déclaration des filtres
La directive FilterDeclare permet de déclarer un filtre en lui assignant un nom et un type. Elle n'est obligatoire que si le filtre n'est pas du type par défaut AP_FTYPE_RESOURCE.
Enregistrement des fournisseurs
La directive FilterProvider permet d'associer un fournisseur à un filtre. Le filtre a été éventuellement déclaré à l'aide de la directive FilterDeclare ; si ce n'est pas le cas, FilterProvider va le déclarer implicitement avec le type par défaut AP_FTYPE_RESOURCE. Le fournisseur doit avoir été enregistré à l'aide de ap_register_output_filter par un module quelconque. Le dernier argument de la directive FilterProvider est une expression : le fournisseur s'exécutera pour une requête si et seulement si l'expression est évaluée vraie. L'expression peut évaluer une requête HTTP ou les en-têtes de la réponse, des variables d'environnement, ou le gestionnaire utilisé par cette requête. À la différence des version précédentes, mod_filter supporte désormais les expressions complexes associant des critères multiples au moyen d'une logique AND / OR (&& / ||) et de parenthèses. Pour les détails sur la syntaxe de l'expression, voir la documentation sur ap_expr.
Configuration de la chaîne de filtrage
Les directives ci-dessus permettent d'élaborer les éléments d'une chaîne de filtrage intelligente, mais pas de les configurer en vue de leur exécution. La directive FilterChain élabore une chaîne de filtrage à partir de filtres intelligents déclarés, permettant avec souplesse d'insérer des filtres au début ou à la fin de la chaîne, de supprimer un filtre ou même la chaîne complète.
top

Filtrage et statut de la réponse

Normalement, mod_filter n'applique les filtres qu'aux réponses possédant un statut HTTP 200 (OK). Pour pouvoir filtrer des documents possédant un autre statut, vous devez définir la variable d'environnement filter-errordocs, les réponses étant alors filtrées sans se préoccuper de leur statut. Pour définir ce comportement de manière plus fine, vous pouvez utiliser des conditions dans la directive FilterProvider.

top

Mise à jour depuis une configuration du serveur HTTP Apache 2.2

La directive FilterProvider a été modifiée par rapport à httpd 2.2 : les arguments match et dispatch ont été remplacés par l'argument unique expression plus polyvalent. En général, il est possible de convertir une paire match/dispatch vers les deux côtés d'une expression, de la manière suivante :

"dispatch = 'match'"

Les en-têtes de requête et de réponse et les variables d'environnement sont maintenant interprétés selon les syntaxes respectives %{req:foo}, %{resp:foo} et %{env:foo}. Les variables %{HANDLER} et %{CONTENT_TYPE} sont également supportées.

Notez que l'évaluation de l'expression ne supporte plus les comparaisons de sous-chaînes. Ces dernières peuvent être remplacées par des comparaisons d'expressions rationnelles.

top

Exemples

Inclusions côté serveur (SSI)
Un exemple simple de remplacement de la directive AddOutputFilterByType
FilterDeclare SSI
FilterProvider SSI INCLUDES "%{CONTENT_TYPE} =~ m|^text/html|"
FilterChain SSI
Inclusions côté serveur (SSI)
Même exemple que ci-dessus, mais envoi vers un gestionnaire (comportement classique des SSI ; les fichiers .shtml sont traités).
FilterProvider SSI INCLUDES "%{HANDLER} = 'server-parsed'"
FilterChain SSI
Émulation de mod_gzip avec mod_deflate
Insertion du filtre INFLATE seulement si l'en-tête Accept-Encoding a une valeur autre que "gzip". Ce filtre s'exécute avec le type ftype CONTENT_SET.
FilterDeclare gzip CONTENT_SET
FilterProvider gzip inflate "%{req:Accept-Encoding} !~ /gzip/"
FilterChain gzip
Diminution de la résolution d'une image
Supposons que nous voulions réduire la résolution de toutes les images web, et que nous disposions de filtres pour les images GIF, JPEG et 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} = m|^image/(jpeg|gif|png)|"
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

Gestion de protocole

Historiquement, tout filtre doit s'assurer que toute modification qu'il effectue est correctement représentée dans les en-têtes de la réponse HTTP, et qu'il ne s'exécutera pas si cette exécution résultait en une modification interdite. Ceci impose aux auteurs de filtres la corvée de réimplémenter certaines fonctionnalités communes dans chaque filtre :

mod_filter a pour but de gérer de manière générale ces détails de l'implémentation des filtres, réduisant par là-même la complexité des modules de filtrage de contenu. Le travail permettant d'atteindre ce but est cependant toujours en cours ; la directive FilterProtocol implémente certaines de ces fonctionnalités à des fins de compatibilité ascendante avec les modules d'Apache 2.0. Pour les versions 2.1 et supérieures de httpd, les API ap_register_output_filter_protocol et ap_filter_protocol permettent aux modules de filtrage de définir leurs propres comportements.

Cependant, mod_filter ne doit pas interférer avec un filtre qui gère déjà tous les aspects du protocole. Par défaut (c'est à dire en l'absence de toute directive FilterProtocol), mod_filter ne modifiera donc pas les en-têtes.

Au moment où ces lignes sont écrites, cette fonctionnalité a été très peu testée, car les modules d'usage courant ont été conçus pour fonctionner avec httpd 2.0. Les modules qui l'utilisent devront donc l'expérimenter avec précautions.

top

Directive AddOutputFilterByType

Description:assigne un filtre en sortie pour un type de média particulier
Syntaxe:AddOutputFilterByType filtre[;filtre...] type_de_média [type_de_média] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_filter
Compatibilité:Présentait de sévères limitations avant d'être déplacé dans mod_filter dans la version 2.3.7

Cette directive active un filtre en sortie particulier pour une requête en fonction du type de média de la réponse.

L'exemple suivant active le filtre DEFLATE qui est fourni par le module mod_deflate. Il va compresser toute sortie dont le type MIME est text/html ou text/plain avant de l'envoyer au client.

AddOutputFilterByType DEFLATE text/html text/plain

Si vous voulez assigner plusieurs filtres au contenu, leurs noms doivent être séparés par des points-virgules. On peut aussi utiliser une directive AddOutputFilterByType pour chacun des filtres à assigner.

La configuration ci-dessous impose le traitement de toute sortie de script dont le type MIME est text/html en premier lieu par le filtre INCLUDES, puis par le filtre DEFLATE.

<Location "/cgi-bin/">
    Options Includes
    AddOutputFilterByType INCLUDES;DEFLATE text/html
</Location>

Voir aussi

top

Directive FilterChain

Description:Configure la chaîne de filtrage
Syntaxe:FilterChain [+=-@!]nom_filtre ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Base
Module:mod_filter

Cette directive permet de configurer une chaîne de filtrage composée de filtres déclarés. FilterChain accepte un nombre illimité d'arguments, chacun d'entre eux étant précédé d'un caractère de contrôle unique qui détermine l'action à entreprendre :

+nom filtre
Ajoutenom filtre à la fin de la chaîne de filtrage
@nom filtre
Ajoute nom filtre au début de la chaîne de filtrage
-nom filtre
Supprime nom filtre de la chaîne de filtrage
=nom filtre
Supprime tous les filtres de la chaîne de filtrage existante et les remplace par nom filtre
!
Supprime tous les filtres de la chaîne de filtrage existante
nom filtre
Équivalent à +nom filtre
top

Directive FilterDeclare

Description:Déclare un filtre intelligent
Syntaxe:FilterDeclare nom_filtre [type]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Base
Module:mod_filter

Cette directive permet de déclarer un filtre en sortie associé à un en-tête ou une variable d'environnement qui déterminera les conditions de son exécution. Le premier argument est le nom du filtre destiné à être utilisé dans les directives FilterProvider, FilterChain et FilterProtocol.

Le dernier argument (optionnel) est le type du filtre, et peut prendre les valeurs de ap_filter_type, à savoir RESOURCE (valeur par défaut), CONTENT_SET, PROTOCOL, TRANSCODE, CONNECTION ou NETWORK.

top

Directive FilterProtocol

Description:Vérifie le respect du protocole HTTP
Syntaxe:FilterProtocol nom_filtre [nom_fournisseur] drapeaux_protocole
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Base
Module:mod_filter

Cette directive permet à mod_filter de s'assurer qu'un filtre ne s'exécutera pas s'il ne doit pas le faire, et que les en-têtes de la réponse HTTP sont définis correctement en tenant compte des effets du filtre.

Cette directive se présente sous deux formes. Avec trois arguments, elle s'applique de manière spécifique à un nom filtre et un nom fournisseur pour ce filtre. Avec deux arguments, elle s'applique à un nom filtre pour tout fournisseur qu'il actionne.

Les drapeaux spécifiés sont fusionnés avec les drapeaux que les fournisseurs sous-jacents ont éventuellement enregistrés avec mod_filter. Par exemple, un filtre peut avoir spécifié en interne un drapeau équivalent à change=yes, mais une configuration particulière du module peut le surcharger en spécifiant change=no.

drapeaux_protocole peut contenir un ou plusieurs drapeaux parmi les suivants :

change=yes|no
Indique si le filtre doit modifier le contenu, y compris éventuellement sa taille
change=1:1
Le filtre modifie le contenu, mais pas sa taille
byteranges=no
Le filtre ne peut pas traiter de réponses à des sous-requêtes et nécessite des réponses complètes en entrée
proxy=no
Le filtre ne doit pas s'exécuter dans un contexte de mandataire
proxy=transform
Le filtre transforme la réponse de manière incompatible avec l'en-tête HTTP Cache-Control: no-transform
cache=no
Le filtre fait en sorte que la sortie ne puisse pas être mise en cache (par exemple en introduisant des modifications de contenu aléatoires)
top

Directive FilterProvider

Description:Enregistre un filtre de contenu
Syntaxe:FilterProvider nom_filtre nom_fournisseur expression
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Base
Module:mod_filter

Cette directive permet d'associer un fournisseur au filtre intelligent. Le fournisseur sera invoqué si et seulement si l'expression est évaluée vraie lorsque le sélecteur de filtre est appelé pour la première fois.

nom fournisseur doit avoir été enregistré au cours du chargement d'un module à l'aide de ap_register_output_filter.

expression est une expression ap_expr.

Voir aussi

top

Directive FilterTrace

Description:Obtention d'informations de débogage/diagnostique en provenance de mod_filter
Syntaxe:FilterTrace nom_filtre niveau
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_filter

Cette directive permet d'obtenir des informations de débogage en provenance de mod_filter. Elle est conçue pour aider à tester et déboguer les fournisseurs (ou modules de filtrage) ; elle peut aussi apporter une aide à l'utilisation de mod_filter lui-même.

La sortie de débogage dépend de la définition d'argument level :

0 (valeur par défaut)
Aucune information de débogage n'est générée.
1
mod_filter va enregistrer les ensembles de conteneurs de données (buckets and brigades) qui traversent le filtre dans le journal des erreurs, avant que le fournisseur ne les traite. Ces informations sont similaires à celles générées par mod_diagnostics.
2 (pas encore implémenté)
Ce niveau permettra d'enregistrer l'ensemble des données qui traversent le filtre dans un fichier temporaire avant de les envoyer au fournisseur. Pour un débogage mono-utilisateur seulement ; l'enregistrement des données concernant plusieurs requêtes simultannées ne sera pas supporté.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_heartmonitor.html.fr.utf80000664000175100017510000003123514740503670023353 0ustar covenercovener mod_heartmonitor - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_heartmonitor

Langues Disponibles:  en  |  fr 

Description:Moniteur centralisé pour les serveurs d'origine mod_heartbeat
Statut:Expérimental
Identificateur de Module:heartmonitor_module
Fichier Source:mod_heartmonitor.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

mod_heartmonitor interprète les messages d'état générés par les serveurs d'origine pour lesquels mod_heartbeat est activé et fournit ces informations à mod_lbmethod_heartbeat, ce qui permet d'utiliser la lbmethod "heartbeat" au sein des directives ProxyPass.

Ce module utilise les services de mod_slotmem_shm, lorsqu'il est disponible, au lieu d'un simple fichier texte. Aucune configuration supplémentaire n'est requise pour utiliser mod_slotmem_shm.

Pour utiliser mod_heartmonitor, mod_status et mod_watchdog doivent être soit des modules statiques, soit des modules dynamiques, et dans ce dernier cas, ils doivent être chargés avant mod_heartmonitor.
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive HeartbeatListen

Description:Adresse multicast d'écoute des requêtes entrantes heartbeat
Syntaxe:HeartbeatListen addr:port
Défaut:disabled
Contexte:configuration globale
Statut:Expérimental
Module:mod_heartmonitor

La directive HeartbeatListen permet de spécifier l'adresse multicast sur laquelle le serveur va surveiller les informations d'état en provenance de serveurs où mod_heartbeat est activé. Cette adresse correspond en général à la valeur de la directive HeartbeatAddress sur le serveur d'origine.

HeartbeatListen 239.0.0.1:27999

Tant que cette directive n'est pas utilisée, le module est désactivé.

top

Directive HeartbeatMaxServers

Description:Spécifie le nombre maximal de serveurs qui pourront envoyer des requêtes heartbeat à ce serveur.
Syntaxe:HeartbeatMaxServers nombre-de-serveurs
Défaut:HeartbeatMaxServers 10
Contexte:configuration globale
Statut:Expérimental
Module:mod_heartmonitor
Compatibilité:La valeur 0 est prise en charge à partir de la version 2.4.55 du serveur HTTP Apache

La directive HeartbeatMaxServers spécifie le nombre maximal de serveurs qui pourront envoyer des requêtes heartbeat à ce serveur de monitoring. Elle permet ainsi de contrôler la quantité de mémoire partagée allouée pour le stockage des données heartbeat lorsqu'on utilise mod_slotmem_shm.

Pour utiliser un stockage de type fichier bidimensionnel (flat-file) lorque le module mod_slotmem_shm n'est pas chargé, cette directive doit être définie à 0. La valeur doit être soit égale à 0, soit supérieure ou égale à 10.

top

Directive HeartbeatStorage

Description:Chemin vers le stockage des données heartbeat lorsqu'on utilise un fichier bidimensionnel (flat-file)
Syntaxe:HeartbeatStorage chemin fichier
Défaut:HeartbeatStorage logs/hb.dat
Contexte:configuration globale
Statut:Expérimental
Module:mod_heartmonitor

La directive HeartbeatStorage permet de spécifier le chemin de stockage des données heartbeat. Ce fichier bidimensionnel n'est utilisé que si mod_slotmem_shm n'est pas chargé et si la directive HeartbeatMaxServers est définie à 0.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_include.html.fr.utf80000664000175100017510000020265714740503670022273 0ustar covenercovener mod_include - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_include

Langues Disponibles:  en  |  fr  |  ja 

Description:Documents html interprétés par le serveur (Server Side Includes ou SSI)
Statut:Base
Identificateur de Module:include_module
Fichier Source:mod_include.c

Sommaire

Ce module fournit un filtre qui va traiter les fichiers avant de les envoyer au client. Le traitement est contrôlé via des commentaires SGML spécialement formatés, aussi nommés éléments. Ces éléments permettent l'insertion conditionnelle de texte, l'inclusion d'autres fichiers ou programmes, ainsi que la définition et l'affichage de variables d'environnement.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Activation des SSI

Les SSI sont implémentés par le filtre INCLUDES. Si des documents contenant des directives SSI possèdent une extension .shtml, les directives suivantes indiqueront à Apache de les interpréter et d'assigner le type MIME text/html au document obtenu :

AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

L'option suivante doit être définie pour les répertoires qui contiennent les fichiers shtml (en général dans une section <Directory>, mais cette option peut également être définie dans un fichier .htaccess si AllowOverride Options a été défini pour le répertoire considéré) :

Options +Includes

Pour des raisons de compatibilité ascendante, le gestionnaire server-parsed peut aussi activer le filtre INCLUDES. Ainsi, Apache va activer le filtre INCLUDES pour tout document de type MIME text/x-server-parsed-html ou text/x-server-parsed-html3 (et le document obtenu aura pour type MIME text/html).

Pour plus d'informations, voyez notre Tutoriel SSI.

top

PATH_INFO et SSI

Les fichiers traités dans le cadre des SSI n'acceptent plus par défaut les requêtes avec PATH_INFO (les informations relatives au chemin en fin de requête). La directive AcceptPathInfo permet de configurer le serveur de façon à ce qu'il accepte ce genre de requête.

top

Eléments disponibles

Le document est interprété comme un document HTML, avec des commandes spéciales incluses sous forme de commentaires SGML. La syntaxe d'une commande est la suivante :

<!--#élément attribut=valeur attribut=valeur ... -->

Les valeurs sont souvent entourées de guillemets, mais on peut aussi utiliser des apostrophes (') ou des apostrophes inverses (`). De nombreuses commandes n'acceptent qu'une seule paire attribut-valeur. Notez que le terminateur de commentaire (-->) doit être précédé d'un espace afin d'être sûr qu'il ne soit pas considéré comme un élément de commande SSI. Notez aussi que le délimiteur de début <!--# est un élément de commande et ne doit donc pas contenir d'espace.

La table suivante contient la liste des éléments autorisés :

ElémentDescription
comment commentaire SSI
config configure les formats de sortie
echo affiche le contenu de variables
exec exécute des programmes externes
fsize affiche la taille d'un fichier
flastmod affiche la date de dernière modification d'un fichier
include inclut un fichier
printenv affiche toutes les variables disponibles
set définit la valeur d'une variable

Les éléments SSI peuvent être définis par d'autres modules que mod_include. À ce titre, l'élément exec est fourni par mod_cgi, et ne sera disponible que si ce module est chargé.

L'élément comment

Cette commande n'affiche aucune information. Elle n'a pour but que l'ajout de commentaires dans un fichier et ces commentaires ne sont pas affichés.

Cette syntaxe est disponible à partir de la version 2.4.21 du serveur HTTP Apache.

<!--#comment Blah Blah Blah -->
   or
<!--#comment text="Blah Blah Blah" -->

L'élément config

Cette commande contrôle divers aspects de l'interprétation. Les attributs valides sont :

echomsg (Versions 2.1 et supérieures d'Apache)

La valeur est un message qui sera envoyé au client si l'élément echo tente d'afficher le contenu d'une variable non définie. Cet attribut l'emporte sur toute directive SSIUndefinedEcho.

<!--#config echomsg="[Valeur non définie]" -->

errmsg

La valeur est un message qui sera envoyé au client si une erreur survient lors de l'interprétation du document. Cet attribut l'emporte sur toute directive SSIErrorMsg.

<!--#config errmsg="[Zut, quelque chose s'est mal passé.]" -->

sizefmt

La valeur définit l'unité employée lors de l'affichage de la taille d'un fichier. Les valeurs possibles sont bytes pour une taille en octets, ou abbrev pour une taille en Ko ou Mo selon son importance ; par exemple, une taille de 1024 octets sera affichée sous la forme "1K".

<!--#config sizefmt="abbrev" -->

timefmt

La valeur est une chaîne que pourra utiliser la fonction de la bibliothèque standard strftime(3) lors de l'affichage des dates.

<!--#config timefmt=""%R, %B %d, %Y"" -->

L'élément echo

Cette commande affiche le contenu d'une des variables include définies ci-dessous. Si la variable n'est pas définie, le résultat est déterminé par la valeur de la directive SSIUndefinedEcho. Le format d'affichage des dates est défini par l'attribut timefmt de la commande config.

Attributs:

var
La valeur est le nom de la variable à afficher.
decoding

Spécifie si Apache doit effectuer un décodage dans la variable avant son traitement ultérieur. La valeur par défaut est none, et dans ce cas, aucun décodage n'est effectué. Si la valeur est url, un décodage de type URL sera effectué (il s'agit du codage de type %-encoding utilisé dans les URLs des liens, etc...). Si la valeur est urlencoded, c'est un décodage des éléments de type application/x-www-form-urlencode (que l'on trouve dans les chaînes de paramètres) qui sera effectué. Si la valeur est base64, un decodage de type base64 sera effectué, et si elle est entity, c'est un décodage des entités HTML qui sera effectué. Ce décodage est effectué avant tout codage ultérieur de la variable. Il est possible d'effectuer plusieurs décodages en spécifiant plusieurs valeurs séparées par des virgules. Les spécifications de décodages restent valables jusqu'au prochain attribut de décodage, ou la fin de l'élément.

Pour être pris en compte, l'attribut de décodage doit précéder l'attribut var correspondant.

encoding

Spécifie la manière dont Apache va coder les caractères spéciaux que la variable contient avant leur affichage. S'il est défini à none, aucun codage ne sera effectué. S'il est défini à url, un codage de type URL sera effectué (aussi connu sous le nom de codage avec caractères % , il convient pour les URLS des liens, etc...). S'il est défini à urlencoded, c'est un codage compatible application/x-www-form-urlencoded qui sera effectué (à utiliser dans les chaînes de paramètres). S'il est défini à base64, c'est un encodage de type base64 qui sera effectué. Au début d'un élément echo, la valeur par défaut est définie à entity, ce qui correspond à un codage de type entité (codage qui convient pour un élément HTML de type bloc, comme le paragraphe d'un texte). Cette valeur par défaut peut être modifiée en ajoutant un attribut encoding, qui fera effet jusqu'à la définition d'un nouvel attribut encoding ou la fin de l'élément echo.

Pour produire son effet, l'attribut encoding doit précéder l'attribut var concerné.

Afin de prévenir les attaques de type cross-site scripting, il est recommandé de toujours encoder les données fournies par les utilisateurs.

Example

<!--#echo encoding="entity" var="QUERY_STRING" -->

L'élément exec

La commande exec exécute la commande shell ou le script spécifié. Elle nécessite le chargement du module mod_cgi. Si Options IncludesNOEXEC est définie, cette commande est désactivée. Les attributs disponibles sont :

cgi

La valeur spécifie un chemin URL vers le script CGI (encodé avec caractères %). Si le chemin ne commence pas par un slash (/), il est considéré comme relatif au document courant. Le document référencé par ce chemin est invoqué en tant que script CGI, même s'il n'est pas censé être reconnu comme tel par le serveur. Les scripts CGI doivent cependant être activés dans le répertoire qui contient les scripts (via la directive ScriptAlias ou l'Options ExecCGI).

Le PATH_INFO et la chaîne d'arguments (QUERY_STRING) de la requête originale du client sont fournis au script CGI ; ils ne peuvent pas être spécifiés dans le chemin de l'URL. Le script disposera des variables include en plus de l'environnement standard CGI.

Exemple

<!--#exec cgi="/cgi-bin/exemple.cgi" -->

Si, à la place d'un flux de sortie, le script renvoie un en-tête Location:, ce dernier sera traduit en ancrage HTML.

L'élément include virtual doit être préféré à exec cgi. En particulier, si vous devez transmettre des arguments supplémentaires à un programme CGI en utilisant la chaîne d'arguments de la requête, c'est impossible avec exec cgi, mais vous pouvez y parvenir avec include virtual comme suit :

<!--#include virtual="/cgi-bin/exemple.cgi?argument=valeur" -->

cmd

Le serveur va exécuter la commande fournie en utilisant /bin/sh. La commande dispose des variables include, en plus du jeu habituel de variables CGI.

Il est toujours préférable d'utiliser #include virtual à la place de #exec cgi ou #exec cmd. #include virtual utilise le mécanisme standard des sous-requêtes d'Apache pour inclure des fichiers ou des scripts. Il a fait l'objet de tests plus approfondis et sa maintenance est mieux suivie.

De plus, sur certaines plate-formes, comme Win32, et sous unix, si l'on utilise suexec, il est impossible de transmettre des arguments à une commande dans une directive exec, à moins d'insérer des espaces dans la commande. Ainsi, alors que ce qui suit fonctionnera sous unix avec une configuration sans suexec, l'effet produit ne sera pas celui désiré sous Win32, ou dans le cas de l'utilisation de suexec :

<!--#exec cmd="perl /chemin/vers/script_perl arg1 arg2" -->

L'élément fsize

Cette commande permet d'afficher la taille du fichier spécifié en fonction des spécifications de format de sizefmt. Attributs :

file
La valeur est le chemin du fichier, relatif au répertoire contenant le document en cours d'interprétation.

Ce fichier a une taille de <!--#fsize file="mod_include.html" --> octets.

La valeur de file ne peut pas faire référence à un fichier situé à un niveau supérieur de l'arborescence du répertoire courant ou en dehors de la racine des documents ; il ne peut donc ni commencer par un slash, ni contenir la séquence de caractères ../. Si c'est le cas, le message d'erreur The given path was above the root path sera renvoyé.
virtual
La valeur est un chemin URL (codé avec caractères %). S'il ne commence pas par un slash (/), il est considéré comme relatif au document courant. Notez que cette commande n'affiche pas la taille de la sortie d'un programme CGI, mais la taille du programme CGI lui-même.

Ce fichier a une taille de <!--#fsize virtual="/docs/mod/mod_include.html" --> octets.

Notez que dans la plupart des cas, ces deux attributs sont identiques. Cependant, l'attribut file ne respecte pas les aliases URL-space.

L'élément flastmod

Cette commande permet d'afficher la date de dernière modification du fichier spécifié, en fonction des spécifications de format de timefmt. Les attributs sont les mêmes que ceux de la commande fsize.

L'élément include

Cette commande permet d'insérer le texte d'un autre document ou fichier dans le fichier en cours d'interprétation. Tout fichier inclus est soumis au contrôle d'accès habituel. Si Options IncludesNOEXEC est défini pour le répertoire contenant le fichier interprété, seuls les documents possèdant un type MIME de type texte (text/plain, text/html, etc...) seront inclus. Les scripts CGI, quant à eux, sont invoqués de manière habituelle en utilisant l'URL complète fournie avec la commande, y compris toute chaîne d'arguments éventuelle.

Un attribut définit le chemin du document à inclure, et peut apparaître plusieurs fois dans l'élément à inclure ; en retour, pour chaque attribut fourni à la commande include, une inclusion est effectuée. Les attributs disponibles sont :

file
La valeur est un chemin relatif au répertoire contenant le fichier en cours d'interprétation. Elle ne peut ni contenir ../, ni être un chemin absolu. Ainsi, vous ne pouvez pas inclure de fichiers situés en dehors de l'arborescence du site web ou dans un niveau supérieur à celui du fichier courant dans cette arborescence. Il est toujours préférable d'utiliser l'attribut virtual.
virtual

La valeur est un chemin URL (codé avec caractères %). L'URL ne peut contenir qu'un chemin et une chaîne d'arguments éventuelle, à l'exclusion de tout protocole ou nom d'hôte. S'il ne commence pas par un slash (/), il est considéré comme relatif au document courant.

Une URL est construite à partir de l'attribut, et la sortie que renverrait le serveur si l'URL était accédée par le client est incluse dans la sortie interprétée. Les inclusions de fichiers peuvent ainsi être imbriquées.

Si l'URL spécifiée correspond à un programme CGI, le programme sera exécuté, et son flux de sortie inséré à la place de la directive dans le fichier interprété. Vous pouvez insérer une chaîne d'arguments dans une URL correspond à un programme CGI :

<!--#include virtual="/cgi-bin/exemple.cgi?argument=valeur" -->

include virtual doit être préféré à exec cgi pour inclure le flux de sortie d'un programme CGI dans un document HTML.

Si la directive KeptBodySize est correctement définie et valide pour le fichier inclus, les tentatives de requêtes POST vers le document HTML qui inclut des fichiers seront transmises aux sous-requêtes en tant que requêtes POST elles-mêmes. Sans cette directive, toutes les sous-requêtes sont traitées en tant que requêtes GET.

onerror

La valeur est un chemin-URL (codé-%) qui est affiché si une tentative précédente d'inclure un fichier ou un attribut virtuel a échoué. Pour produire son effet, cet attribut doit être spécifié après le fichier ou les attributs virtuels concernés. Si la tentative d'inclure le chemin onerror échoue, ou si onerror n'est pas spécifié, c'est le message d'erreur par défaut qui sera inclus.

# Exemple simple
<!--#include virtual="/not-exist.html" onerror="/error.html" -->

# Chemins onerror dédiés
<!--#include virtual="/path-a.html" onerror="/error-a.html" virtual="/path-b.html" onerror="/error-b.html" -->

L'élément printenv

Cette commande affiche la liste en mode texte de toutes les variables et de leurs valeurs. Les caractères spéciaux sont encodés entity avant d'être affichés (se reporter à l'élément echo pour plus de détails). Cette commande ne comporte pas d'attributs.

Exemple

<pre> <!--#printenv --> </pre>

L'élément set

Cette commande permet de définir la valeur d'une variable. Les attributs sont :

var
Le nom de la variable à définir.
value
La valeur à affecter à la variable.
decoding

Spécifie si Apache doit effectuer un décodage dans la variable avant son traitement ultérieur. La valeur par défaut est none, et dans ce cas, aucun décodage n'est effectué. Si la valeur est url, urlencoded, base64 ou entity, c'est un décodage de type URL, application/x-www-form-urlencoded, base64 ou entité HTML qui sera respectivement effectué. Il est possible d'effectuer plusieurs décodages en spécifiant plusieurs valeurs séparées par des virgules. Les spécifications de décodages restent valables jusqu'au prochain attribut de décodage, ou la fin de l'élément. Pour être pris en compte, l'attribut de décodage doit précéder l'attribut var correspondant.

encoding

Spécifie la manière dont Apache va encoder les caractères spéciaux que la variable contient avant leur affichage. S'il est défini à none, aucun encodage ne sera effectué. Si la valeur est url, urlencoding, base64 ou entity, c'est un encodage de type URL, application/x-www-form-urlencoded, base64 ou entité HTML qui sera respectivement effectué. Il est possible de spécifier plusieurs types d'encodage en les séparant par des virgules. La spécification du type d'encodage fera effet jusqu'à la définition d'un nouvel attribut encoding ou la fin de l'élément. Pour produire son effet, l'attribut encoding doit précéder l'attribut var concerné. Les encodages sont effectués après les opérations de décodage.

Exemple

<!--#set var="category" value="help" -->

top

Variables include

À l'instar des variables de l'environnement CGI standard, ces variables sont mises à la disposition de la commande echo, des opérateurs conditionnels if et elif, et de tout programme invoqué par le document.

DATE_GMT
La date GMT (Greenwich Mean Time) courante.
DATE_LOCAL
La date locale courante.
DOCUMENT_ARGS
Cette variable contient la chaîne de paramètres de la requête du document SSI actif, ou la chaîne vide si aucune chaîne de paramètres de requête n'est incluse. Pour les sous-requêtes invoquées par la directive SSI include, QUERY_STRING contiendra la chaîne de paramètres de la sous-requête et DOCUMENT_ARGS la chaîne de paramètres du document SSI (disponible à partir de la version 2.4.19 du serveur HTTP Apache).
DOCUMENT_NAME
Le nom de base du fichier demandé par l'utilisateur (sans son chemin).
DOCUMENT_PATH_INFO
La partie terminale du chemin du fichier. Voir la directive AcceptPathInfo pour plus d'informations à propos de PATH_INFO.
DOCUMENT_URI
Le chemin URL (caractères % décodés) du document demandé par l'utilisateur. Notez que dans le cas d'inclusions de fichiers imbriquées, il ne s'agit pas de l'URL du document courant. Notez également que si l'URL est modifiée en interne (par exemple via une directive alias ou directoryindex), c'est l'URL modifiée que contiendra la variable.
LAST_MODIFIED
La date de dernière modification du document demandé par l'utilisateur.
QUERY_STRING_UNESCAPED
Si une chaîne d'arguments est présente dans la requête pour le document SSI actif, elle sera affectée à cette variable, les caractères %-décodés, et éventuellement échappés pour qu'ils ne soient pas interprétés par le shell (les caractères spéciaux comme &,etc... sont précédés d'anti-slashes). Cette variable n'est pas définie si aucune chaîne d'arguments n'est présente. Utilisez DOCUMENT_ARGS si l'échappement des caractères du shell n'est pas souhaité.
USER_NAME
Le nom d'utilisateur du propriétaire du fichier.
top

Substitution de variable

Une substitution de variable à l'intérieur d'une chaîne entre guillemets s'effectue dans la plupart des situations où cette dernière peut raisonablement constituer un argument d'une directive SSI. Sont concernées les directives config, exec, flastmod, fsize, include, echo, et set. Si la directive SSILegacyExprParser est définie à on, la substitution s'effectue aussi dans les arguments des opérateurs conditionnels. Vous pouvez insérer un signe dollar en tant que caractère littéral dans une chaîne en utilisant un anti-slash :

<!--#set var="cur" value="\$test" -->

Si une référence de variable doit être substituée au beau milieu d'une séquence de caractères qui pourrait être elle-même considérée comme un identifiant valide, l'ambiguïté peut être levée en entourant la référence d'accolades, à la manière du shell :

<!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" -->

Dans cet exemple, la variable Zed se verra affecter la valeur "X_Y" si REMOTE_HOST et REQUEST_METHOD contiennent respectivement "X" et "Y".

top

Eléments de contrôle d'inclusion conditionnelle

Les éléments de base du contrôle d'inclusion conditionnelle sont :

<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->

L'élément if fonctionne de la même manière que la directive if d'un langage de programmation. La condition est évaluée et si le résultat est vrai, le texte qui suit jusqu'au prochain élément elif, else ou endif sera inclus dans le flux de sortie.

Les éléments elif ou else permettent d'insérer du texte dans le flux de sortie si test_condition s'est révélé faux. Ces éléments sont optionnels.

L'élément endif termine le bloc de traitement conditionnel if et est obligatoire.

test_condition est une expression booléenne qui emprunte la syntaxe ap_expr. La directive SSILegacyExprParser permet de modifier cette syntaxe pour la rendre compatible avec Apache HTTPD 2.2.x.

Le jeu de variables SSI avec l'élément var sont exportées vers l'environnement de la requête et sont accessibles via la fonction reqenv. Pour faire simple, le nom de fonction v est aussi disponible dans le module mod_include.

Dans l'exemple suivant, "depuis le réseau local" sera affiché si l'adresse IP du client appartient au sous-réseau 10.0.0.0/8.

<!--#if expr='-R "10.0.0.0/8"' -->
depuis le réseau local
<!--#else -->
depuis ailleurs
<!--#endif -->

Dans l'exemple suivant, "foo vaut bar" sera affiché si la variable foo contient la valeur "bar".

<!--#if expr='v("foo") = "bar"' -->
foo vaut bar
<!--#endif -->

Documentation de référence

Voir aussi Les expressions dans le serveur HTTP Apache pour une référence complète et des exemples. Les fonctions restricted ne sont pas disponibles dans mod_include.

top

Syntaxe des expressions héritée

Cette section décrit la syntaxe de l'élément #if expr dans le cas où la directive SSILegacyExprParser est définie à on.

chaîne
vrai si chaîne n'est pas vide
-A string

vrai si l'URL que contient la chaîne est accessible du point de vue de la configuration, faux sinon. Il s'avère utile lorsqu'un lien vers une URL doit être caché aux utilisateurs qui ne sont pas autorisés à voir cette URL. Notez que le test porte sur l'autorisation d'accès à l'URL, et non sur son existence.

Exemple

<!--#if expr="-A /prive" -->
Cliquez <a href="/prive">ici</a> pour accéder aux informations privées.
<!--#endif -->

chaîne1 = chaîne2
chaîne1 == chaîne2
chaîne1 != chaîne2

Compare chaîne1 à chaîne2. Si chaîne2 est de la forme /chaîne2/, elle est traitée comme une expression rationnelle. Les expressions rationnelles sont implémentées par le moteur PCRE et possèdent la même syntaxe que celles de perl 5. Notez que == n'est qu'un alias pour = et se comporte exactement de la même manière que ce dernier.

Si vous faites une comparaison directe (= ou ==), vous pouvez extraire des parties de l'expression rationnelle. Les parties extraites sont stockées dans les variables spéciales $1 .. $9. L'ensemble de la chaîne correspondant à l'expression rationnelle est stocké dans la variable spéciale $0.

Exemple

<!--#if expr="$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/" -->
<!--#set var="session" value="$1" -->
<!--#endif -->

chaîne1 < chaîne2
chaîne1 <= chaîne2
chaîne1 > chaîne2
chaîne1 >= chaîne2
Compare chaîne1 à chaîne2. Notez que les chaînes sont comparées de manière littérale (en utilisant strcmp(3)). Ainsi, la chaîne "100" est inférieure à "20".
( test_condition )
vrai si test_condition est vrai
! test_condition
vrai si test_condition est faux
test_condition1 && test_condition2
vrai si test_condition1 et test_condition2 sont tous les deux vrais
test_condition1 || test_condition2
vrai si au moins un des tests test_condition1 ou test_condition2 est vrai

"=" et "!=" ont une priorité supérieure à "&&" et "||". "!" a la priorité la plus haute. Ainsi, les deux directives suivantes sont équivalentes :

<!--#if expr="$a = test1 && $b = test2" -->
<!--#if expr="($a = test1) && ($b = test2)" -->

Les opérateurs booléens && et || ont la même priorité. Ainsi, si vous voulez augmenter la priorité d'un de ces opérateurs, vous devez utiliser des parenthèses.

Tout ce qui n'est pas reconnu comme variable ou opérateur est traité comme une chaîne. Les chaînes peuvent aussi être entourées d'apostrophes : 'chaîne'. Les chaînes sans apostrophe ne peuvent pas contenir d'espaces (espaces ou tabulations) car ceux-ci servent à séparer certains éléments comme les variables. Si plusieurs chaînes se trouvent dans une ligne, elles sont concaténées en utilisant des espaces. Ainsi,

chaîne1    chaîne2 devient chaîne1 chaîne2

et

'chaîne1    chaîne2' devient chaîne1    chaîne2.

Optimisation des expressions booléennes

Si les expressions atteignent une complexité suffisante pour ralentir les traitements de manière significative, vous pouvez essayer de les optimiser en fonction des règles d'évaluation :

  • Les expressions sont évaluées de la gauche vers la droite
  • Les opérateurs booléens binaires (&& et ||) font l'objet d'une évaluation abrégée chaque fois que cela est possible. En d'autres termes, et selon la règle ci-dessus, mod_include évalue tout d'abord la partie gauche de l'expression. Si le résultat de l'évaluation de cette partie gauche suffit à déterminer le résultat final, l'évaluation s'arrête ici. Dans le cas contraire, la partie droite est évaluée, et le résultat final tient compte des résultats des évaluations des parties gauche et droite.
  • L'évaluation abrégée est désactivée tant qu'il reste des expressions régulières à traiter. Ces dernières doivent être évaluées afin de définir les variables correspondant aux références arrières ($1 .. $9).

Si vous voulez déterminer la manière dont une expression est traitée, vous pouvez recompiler mod_include en utilisant l'option de compilation -DDEBUG_INCLUDE. Ceci a pour effet d'insérer, pour chaque expression interprétée, des informations étiquetées, l'arbre d'interprétation et la manière dont elle est évaluée au sein du flux de sortie envoyé au client.

Slashes d'échappement dans les expressions rationnelles

Tous les caractères slashes qui ne sont pas des séparateurs dans votre expression rationnelle doivent être échappés, et ceci sans tenir compte de leur signification du point de vue du moteur d'expressions rationnelles.

Documentation de référence

Voir le document Les expressions dans le serveur HTTP Apache, pour une référence complète et des exemples.

top

Directive SSIEndTag

Description:Chaîne qui termine l'élément include
Syntaxe:SSIEndTag tag
Défaut:SSIEndTag "-->"
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_include

Cette directive permet de modifier la chaîne que mod_include interprète comme la fin d'un élément include.

SSIEndTag "%>"

Voir aussi

top

Directive SSIErrorMsg

Description:Message d'erreur affiché lorsqu'une erreur SSI survient
Syntaxe:SSIErrorMsg message
Défaut:SSIErrorMsg "[an error occurred while processing this directive]"
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Base
Module:mod_include

La directive SSIErrorMsg permet de modifier le message d'erreur affiché lorsqu'une erreur SSI survient. Pour les serveurs en production, il est recommandé de modifier le message d'erreur par défaut en "<!-- Error -->", de façon à ce que le message ne soit pas présenté à l'utilisateur.

Cette directive a le même effet que l'élément <!--#config errmsg=message -->.

SSIErrorMsg "<!-- Error -->"
top

Directive SSIETag

Description:Définit si des en-têtes ETags sont générés par le serveur.
Syntaxe:SSIETag on|off
Défaut:SSIETag off
Contexte:répertoire, .htaccess
Statut:Base
Module:mod_include
Compatibilité:Disponible à partir de la version 2.2.15 du serveur HTTP Apache.

Dans le cas général, un fichier filtré par mod_include peut contenir des éléments soit générés dynamiquement, soit éventuellement modifiés indépendemment du fichier original. En conséquence, il est demandé par défaut au serveur de ne pas générer d'en-tête ETag à la réponse en ajoutant no-etag aux informations de requête.

Ce comportement peut être modifié via la directive SSIETag qui permet au serveur de générer un en-tête ETag. On peut aussi l'utiliser pour la mise en cache de la sortie. Notez qu'un serveur d'arrière-plan ou un générateur de contenu dynamique peut lui-même générer un en-tête ETag, en ignorant l'information no-etag, cet en-tête ETag étant transmis par mod_include sans tenir compte de la définition de la présente directive. La directive SSIETag peut prendre une des valeurs suivantes :

off
no-etag sera ajouté aux informations de requête, et il sera demandé au serveur de ne pas générer d'en-tête ETag. Lorsqu'un serveur ignore la valeur de no-etag et génère tout de même un en-tête ETag, ce dernier sera respecté.
on
Les en-têtes ETag existants seront respectés, et ceux générés par le serveur seront ajoutés à la réponse.
top

Directive SSILastModified

Description:Définit si des en-têtes Last-Modified sont générés par le serveur.
Syntaxe:SSILastModified on|off
Défaut:SSILastModified off
Contexte:répertoire, .htaccess
Statut:Base
Module:mod_include
Compatibilité:Disponible à partir de la version 2.2.15 du serveur HTTP Apache.

Dans le cas général, un fichier filtré par mod_include peut contenir des éléments soit générés dynamiquement, soit éventuellement modifiés indépendemment du fichier original. En conséquence, l'en-tête Last-Modified est supprimé par défaut de la réponse.

La directive SSILastModified permet de modifier ce comportement en faisant en sorte que l'en-tête Last-Modified soit respecté s'il est déjà présent, ou défini dans le cas contraire. On peut aussi l'utiliser pour la mise en cache de la sortie. La directive SSILastModified peut prendre une des valeurs suivantes :

off
L'en-tête Last-Modified sera supprimé des réponses, à moins que la directive XBitHack ne soit définie à full comme décrit plus loin.
on
L'en-tête Last-Modified sera respecté s'il est déjà présent, et ajouté à la réponse si cette dernière est un fichier et si l'en-tête est manquant. La directive SSILastModified l'emporte sur la directive XBitHack.
top

Directive SSILegacyExprParser

Description:Active le mode de compatibilité pour les expressions conditionnelles.
Syntaxe:SSILegacyExprParser on|off
Défaut:SSILegacyExprParser off
Contexte:répertoire, .htaccess
Statut:Base
Module:mod_include
Compatibilité:Disponible à partir de la version 2.3.13.

Depuis la version 2.3.13, mod_include a adopté la nouvelle syntaxe ap_expr pour ses expressions conditionnelles dans les éléments de contrôle de flux #if. Cette directive permet de réactiver l'ancienne syntaxe qui est compatible avec les versions 2.2.x et antérieures d'Apache HTTPD.

top

Directive SSIStartTag

Description:Chaîne qui marque le début d'un élément include
Syntaxe:SSIStartTag tag
Défaut:SSIStartTag "<!--#"
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_include

Cette directive permet de modifier la chaîne que mod_include interprète comme le début d'un élément include.

Cette option peut vous être utile si vous avez deux serveurs qui interprètent un fichier avec des commandes différentes (et éventuellement à des moments différents).

SSIStartTag "<%"
SSIEndTag   "%>"

Avec l'exemple ci-dessus, qui définit aussi une directive SSIEndTag, vous pourrez inscrire des directives SSI comme dans l'exemple suivant :

Directives SSI avec marques de début et de fin personnalisées

<%printenv %>

Voir aussi

top

Directive SSITimeFormat

Description:Configuration du format d'affichage des dates
Syntaxe:SSITimeFormat chaîne de formatage
Défaut:SSITimeFormat "%A, %d-%b-%Y %H:%M:%S %Z"
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Base
Module:mod_include

Cette directive permet de modifier le format d'affichage des variables d'environnement DATE. La chaîne de formatage est identique à celle de la fonction strftime(3) de la bibliothèque C standard.

Cette directive a le même effet que l'élément <!--#config timefmt=chaîne de formatage -->.

SSITimeFormat "%R, %B %d, %Y"

Avec l'exemple ci-dessus, les dates seront affichées dans le style "22:26, June 14, 2002".

top

Directive SSIUndefinedEcho

Description:Chaîne à afficher lorsqu'on tente d'extraire le contenu d'une variable non définie
Syntaxe:SSIUndefinedEcho chaîne
Défaut:SSIUndefinedEcho "(none)"
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Base
Module:mod_include

Cette directive permet de modifier la chaîne affichée par mod_include lorsqu'on tente d'extraire le contenu d'une variable non définie.

SSIUndefinedEcho "<!-- nondef -->"
top

Directive XBitHack

Description:Interprète les directives SSI dans les fichiers dont le bit d'exécution est positionné
Syntaxe:XBitHack on|off|full
Défaut:XBitHack off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Base
Module:mod_include

La directive XBitHack permet de contrôler l'interprétation des documents html standards. Elle n'affecte que les fichiers dont le type MIME est text/html. XBitHack peut prendre les valeurs suivantes :

off
Aucun traitement particulier pour les fichiers exécutables.
on
Tout fichier text/html dont le bit d'exécution est positionné pour le propriétaire sera traité en tant que document html interprété par le serveur.
full
Identique à on, avec test du bit d'exécution pour le groupe. Si ce dernier est positionné, la date de dernière modification du fichier renvoyé est définie à la date de dernière modification du fichier. Dans le cas contraire, aucune date de dernière modification n'est renvoyée. Le positionnement de ce bit permet aux clients et aux mandataires de gérer la mise en cache du résultat de la requête.

Note

Il est recommandé de n'utiliser l'option full que dans le cas où vous êtes certain que le bit d'exécution du groupe est non positionné pour les scripts SSI qui pourraient effectuer l'#include d'un programme CGI ou bien produire des sorties différentes à chaque accès (ou seraient susceptibles d'être modifiées au cours des requêtes ultérieures).

Lorsqu'elle est définie à on, la directive SSILastModified l'emporte sur la directive XBitHack.

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_bybusyness.html.fr.utf80000664000175100017510000002037614740503670024730 0ustar covenercovener mod_lbmethod_bybusyness - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_lbmethod_bybusyness

Langues Disponibles:  en  |  fr 

Description:Algorithme de planification avec répartition de charge de l'attribution des requêtes en attente pour le module mod_proxy_balancer
Statut:Extension
Identificateur de Module:lbmethod_bybusyness_module
Fichier Source:mod_lbmethod_bybusyness.c
Compatibilité:Dissocié de mod_proxy_balancer depuis la version 2.3

Sommaire

Ce module ne fournit pas lui-même de directive de configuration. Il nécessite les services de mod_proxy_balancer, et fournit la méthode de répartition de charge bybusyness.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Algorithme d'attribution des requêtes en attente

Activé via lbmethod=bybusyness, ce planificateur surveille le nombre de requêtes assignées à chaque processus worker à l'instant présent. Une nouvelle requête est automatiquement assignée au processus worker auquel est assigné le plus petit nombre de requêtes. Ceci s'avère utile dans le cas où les processus worker mettent en file d'attente les requêtes entrantes indépendamment d'Apache, et permet de s'assurer que la longueur des files reste raisonnable, et qu'une requête est toujours assignée au processus worker qui sera à même de la servir le plus rapidement et avec une latence réduite.

Si plusieurs processus worker s'avèrent les moins chargés, le choix d'un de ces derniers est effectué à partir des statistiques (et des estimations de charges) qu'utilise la méthode de décompte des requêtes. Au fil du temps, la distribution des tâches finit par ressembler à celle de byrequests (tel qu'implémenté par mod_lbmethod_byrequests).

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_heartbeat.html.fr.utf80000664000175100017510000002123114740503670024450 0ustar covenercovener mod_lbmethod_heartbeat - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_lbmethod_heartbeat

Langues Disponibles:  en  |  fr 

Description:Algorithme d'ordonnancement de répartition de charge pour mod_proxy_balancer basé sur le comptage de trafic Heartbeat
Statut:Expérimental
Identificateur de Module:lbmethod_heartbeat_module
Fichier Source:mod_lbmethod_heartbeat.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

lbmethod=heartbeat utilise les services du module mod_heartmonitor pour répartir la charge entre les serveurs d'origine qui fournissent des données heartbeat via le module mod_heartbeat.

Son algorithme de répartition de charge favorise les serveurs dont la capacité de traitement moyenne répartie dans le temps est la plus importante, mais il ne sélectionne pas forcément le serveur qui présente la disponibilité instantanée la plus importante. Les serveurs qui ne possèdent aucun client actif sont pénalisés, car ils sont considérés comme non entièrement initialisés.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive HeartbeatStorage

Description:Indique le chemin permettant de lire les données heartbeat
Syntaxe:HeartbeatStorage chemin-fichier
Défaut:HeartbeatStorage logs/hb.dat
Contexte:configuration globale
Statut:Expérimental
Module:mod_lbmethod_heartbeat

La directive HeartbeatStorage permet de spécifier le chemin d'accès aux données heartbeat. Ce fichier texte n'est utilisé que si le module mod_slotmem_shm n'est pas chargé.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_byrequests.html.fr.utf80000664000175100017510000003212414740503670024722 0ustar covenercovener mod_lbmethod_byrequests - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_lbmethod_byrequests

Langues Disponibles:  en  |  fr 

Description:Algorithme de planification avec répartition de charge du traitement des requêtes pour le module mod_proxy_balancer
Statut:Extension
Identificateur de Module:lbmethod_byrequests_module
Fichier Source:mod_lbmethod_byrequests.c
Compatibilité:Dissocié de mod_proxy_balancer dans la version 2.3

Sommaire

Ce module ne fournit pas lui-même de directive de configuration. Il nécessite les services de mod_proxy_balancer, et fournit la méthode de répartition de charge byrequests.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Algorithme d'attribution des requêtes

Activé via lbmethod=byrequests, ce planificateur a été conçu dans le but de distribuer les requêtes à tous les processus worker afin qu'ils traitent tous le nombre de requêtes pour lequel ils ont été configurés. Il fonctionne de la manière suivante :

lbfactor correspond à la quantité de travail que nous attendons de ce processus worker, ou en d'autres termes son quota de travail. C'est une valeur normalisée représentant leur part du travail à accomplir.

lbstatus représente combien il est urgent que ce processus worker travaille pour remplir son quota de travail.

Le worker est un membre du dispositif de répartition de charge, en général un serveur distant traitant un des protocoles supportés.

On distribue à chaque processus worker son quota de travail, puis on regarde celui qui a le plus besoin de travailler (le plus grand lbstatus). Ce processus est alors sélectionné pour travailler, et son lbstatus diminué de l'ensemble des quotas de travail que nous avons distribués à tous les processus. La somme de tous les lbstatus n'est ainsi pas modifiée, et nous pouvons distribuer les requêtes selon nos souhaits.

Si certains processus workers sont désactivés, les autres feront l'objet d'une planification normale.

for each worker in workers
    worker lbstatus += worker lbfactor
    total factor    += worker lbfactor
    if worker lbstatus > candidate lbstatus
        candidate = worker

candidate lbstatus -= total factor

Si un répartiteur de charge est configuré comme suit :

worker a b c d
lbfactor 25 25 25 25
lbstatus 0 0 0 0

Et si b est désactivé, la planification suivante est mise en oeuvre :

worker a b c d
lbstatus -50 0 25 25
lbstatus -25 0 -25 50
lbstatus 0 0 0 0
(repeat)

C'est à dire la chronologie suivante : a c d a c d a c d ... Veuillez noter que :

worker a b c d
lbfactor 25 25 25 25

A le même effet que :

worker a b c d
lbfactor 1 1 1 1

Ceci est dû au fait que toutes les valeurs de lbfactor sont normalisées et évaluées en fonction des autres. Avec :

worker a b c
lbfactor 1 4 1

le processus b va, en moyenne, se voir assigner 4 fois plus de requêtes que a et c.

La configuration suivante, asymétrique, fonctionne comme on peut s'y attendre :

worker a b
lbfactor 70 30
 
lbstatus -30 30
lbstatus 40 -40
lbstatus 10 -10
lbstatus -20 20
lbstatus -50 50
lbstatus 20 -20
lbstatus -10 10
lbstatus -40 40
lbstatus 30 -30
lbstatus 0 0
(repeat)

Après 10 distributions, la planification se répète et 7 a sont sélectionnés avec 3 b intercalés.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ldap.html.fr.utf80000664000175100017510000016352114740503670021564 0ustar covenercovener mod_ldap - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_ldap

Langues Disponibles:  en  |  fr 

Description:Conservation des connexions LDAP et services de mise en cache du résultat à destination des autres modules LDAP
Statut:Extension
Identificateur de Module:ldap_module
Fichier Source:util_ldap.c

Sommaire

Ce module a été conçu dans le but d'améliorer les performances des sites web s'appuyant sur des connexions en arrière-plan vers des serveurs LDAP. Il ajoute aux fonctions fournies par les bibliothèques standards LDAP la conservation des connexions LDAP ainsi qu'un cache LDAP partagé en mémoire.

Pour activer ce module, le support LDAP doit être compilé dans apr-util. Pour ce faire, on ajoute l'option --with-ldap au script configure lorsqu'on construit Apache.

Le support SSL/TLS est conditionné par le kit de développement LDAP qui a été lié à APR. Au moment où ces lignes sont écrites, APR-util supporte OpenLDAP SDK (version 2.x ou supérieure), Novell LDAP SDK, Mozilla LDAP SDK, le SDK LDAP Solaris natif (basé sur Mozilla) ou le SDK LDAP Microsoft natif. Voir le site web APR pour plus de détails.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemple de configuration

Ce qui suit est un exemple de configuration qui utilise mod_ldap pour améliorer les performances de l'authentification HTTP de base fournie par mod_authnz_ldap.

# Active la conservation des connexions LDAP et le cache partagé en
# mémoire. Active le gestionnaire de statut du cache LDAP.
# Nécessite le chargement de mod_ldap et de mod_authnz_ldap.
# Remplacez "votre-domaine.example.com" par le nom de votre
# domaine.

LDAPSharedCacheSize 500000
LDAPCacheEntries 1024
LDAPCacheTTL 600
LDAPOpCacheEntries 1024
LDAPOpCacheTTL 600

<Location "/ldap-status">
    SetHandler ldap-status
    
    Require host yourdomain.example.com
    
    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldap://127.0.0.1/dc=example,dc=com?uid?one"
    Require valid-user
</Location>
top

Conservation des connexions LDAP

Les connexions LDAP sont conservées de requête en requête. Ceci permet de rester connecté et identifié au serveur LDAP, ce dernier étant ainsi prêt pour la prochaine requête, sans avoir à se déconnecter, reconnecter et réidentifier. Le gain en performances est similaire à celui des connexions persistantes (keepalives) HTTP.

Sur un serveur très sollicité, il est possible que de nombreuses requêtes tentent d'accéder simultanément à la même connexion au serveur LDAP. Lorsqu'une connexion LDAP est utilisée, Apache en crée une deuxième en parallèle à la première, ce qui permet d'éviter que le système de conservation des connexions ne devienne un goulot d'étranglement.

Il n'est pas nécessaire d'activer explicitement la conservation des connexions dans la configuration d'Apache. Tout module utilisant le module ldap pour accéder aux services LDAP partagera le jeu de connexions.

Les connexions LDAP peuvent garder la trace des données d'identification du client ldap utilisées pour l'identification auprès du serveur LDAP. Ces données peuvent être fournies aux serveurs LDAP qui ne permettent pas les connexions anonymes au cours lors des tentatives de sauts vers des serveurs alternatifs. Pour contrôler cette fonctionnalité, voir les directives LDAPReferrals et LDAPReferralHopLimit. Cette fonctionnalité est activée par défaut.

top

Cache LDAP

Pour améliorer les performances, mod_ldap met en oeuvre une stratégie de mise en cache agressive visant à minimiser le nombre de fois que le serveur LDAP doit être contacté. La mise en cache peut facilement doubler et même tripler le débit d'Apache lorsqu'il sert des pages protégées par mod_authnz_ldap. De plus, le serveur LDAP verra lui-même sa charge sensiblement diminuée.

mod_ldap supporte deux types de mise en cache LDAP : un cache recherche/identification durant la phase de recherche/identification et deux caches d'opérations durant la phase de comparaison. Chaque URL LDAP utilisée par le serveur a son propre jeu d'instances dans ces trois caches.

Le cache recherche/identification

Les processus de recherche et d'identification sont les opérations LDAP les plus consommatrices en temps, en particulier si l'annuaire est de grande taille. Le cache de recherche/identification met en cache toutes les recherches qui ont abouti à une identification positive. Les résultats négatifs (c'est à dire les recherches sans succès, ou les recherches qui n'ont pas abouti à une identification positive) ne sont pas mis en cache. La raison de cette décision réside dans le fait que les connexions avec des données d'identification invalides ne représentent qu'un faible pourcentage du nombre total de connexions, et ainsi, le fait de ne pas mettre en cache les données d'identification invalides réduira d'autant la taille du cache.

mod_ldap met en cache le nom d'utilisateur, le DN extrait, le mot de passe utilisé pour l'identification, ainsi que l'heure de l'identification. Chaque fois qu'une nouvelle connexion est initialisée avec le même nom d'utilisateur, mod_ldap compare le mot de passe de la nouvelle connexion avec le mot de passe enregistré dans le cache. Si les mots de passe correspondent, et si l'entrée du cache n'est pas trop ancienne, mod_ldap court-circuite la phase de recherche/identification.

Le cache de recherche/identification est contrôlé par les directives LDAPCacheEntries et LDAPCacheTTL.

Les caches d'opérations

Au cours des opérations de comparaison d'attributs et de noms distinctifs (DN), mod_ldap utilise deux caches d'opérations pour mettre en cache les opérations de comparaison. Le premier cache de comparaison sert à mettre en cache les résultats de comparaisons effectuées pour vérifier l'appartenance à un groupe LDAP. Le second cache de comparaison sert à mettre en cache les résultats de comparaisons entre DNs.

Notez que, lorsque l'appartenance à un groupe est vérifiée, toute comparaison de sous-groupes est mise en cache afin d'accélérer les comparaisons de sous-groupes ultérieures.

Le comportement de ces deux caches est contrôlé par les directives LDAPOpCacheEntries et LDAPOpCacheTTL.

Superviser le cache

mod_ldap possède un gestionnaire de contenu qui permet aux administrateurs de superviser les performances du cache. Le nom du gestionnaire de contenu est ldap-status, et on peut utiliser les directives suivantes pour accéder aux informations du cache de mod_ldap :

<Location "/server/cache-info">
    SetHandler ldap-status
</Location>

En se connectant à l'URL http://nom-serveur/infos-cache, l'administrateur peut obtenir un rapport sur le statut de chaque cache qu'utilise mod_ldap. Notez que si Apache ne supporte pas la mémoire partagée, chaque instance de httpd possèdera son propre cache, et chaque fois que l'URL sera rechargée, un résultat différent pourra être affiché, en fonction de l'instance de httpd qui traitera la requête.

top

Utiliser SSL/TLS

La possibilité de créer des connexions SSL et TLS avec un serveur LDAP est définie par les directives LDAPTrustedGlobalCert, LDAPTrustedClientCert et LDAPTrustedMode. Ces directives permettent de spécifier l'autorité de certification (CA), les certificats clients éventuels, ainsi que le type de chiffrement à utiliser pour la connexion (none, SSL ou TLS/STARTTLS).

# Etablissement d'une connexion SSL LDAP sur le port 636.
# Nécessite le chargement de mod_ldap et mod_authnz_ldap.
# Remplacez "votre-domaine.example.com" par le nom de votre
# domaine.

LDAPTrustedGlobalCert CA_DER "/certs/certfile.der"

<Location "/ldap-status">
    SetHandler ldap-status
    
    Require host yourdomain.example.com
    
    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldaps://127.0.0.1/dc=example,dc=com?uid?one"
    Require valid-user
</Location>
# Etablissement d'une connexion TLS LDAP sur le port 389.
# Nécessite le chargement de mod_ldap et mod_authnz_ldap.
# Remplacez "votre-domaine.example.com" par le nom de votre
# domaine.

LDAPTrustedGlobalCert CA_DER "/certs/certfile.der"

<Location "/ldap-status">
    SetHandler ldap-status
    
    Require host yourdomain.example.com
    
    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldap://127.0.0.1/dc=example,dc=com?uid?one" TLS
    Require valid-user
</Location>
top

Certificats SSL/TLS

Les différents SDKs LDAP disposent de nombreuses méthodes pour définir et gérer les certificats des clients et des autorités de certification (CA).

Si vous avez l'intention d'utiliser SSL ou TLS, lisez cette section ATTENTIVEMENT de façon à bien comprendre les différences de configurations entre les différents SDKs LDAP supportés.

SDK Netscape/Mozilla/iPlanet

Les certificat de CA sont enregistrés dans un fichier nommé cert7.db. Le SDK ne dialoguera avec aucun serveur LDAP dont le certificat n'a pas été signé par une CA spécifiée dans ce fichier. Si des certificats clients sont requis, un fichier key3.db ainsi qu'un mot de passe optionnels peuvent être spécifiés. On peut aussi spécifier le fichier secmod si nécessaire. Ces fichiers sont du même format que celui utilisé par les navigateurs web Netscape Communicator ou Mozilla. Le moyen le plus simple pour obtenir ces fichiers consiste à les extraire de l'installation de votre navigateur.

Les certificats clients sont spécifiés pour chaque connexion en utilisant la directive LDAPTrustedClientCert et en se référant au certificat "nickname". On peut éventuellement spécifier un mot de passe pour déverrouiller la clé privée du certificat.

Le SDK supporte seulement SSL. Toute tentative d'utilisation de STARTTLS engendrera une erreur lors des tentatives de contacter le serveur LDAP pendant l'exécution.

# Spécifie un fichier de certificats de CA Netscape
LDAPTrustedGlobalCert CA_CERT7_DB "/certs/cert7.db"
# Spécifie un fichier key3db optionnel pour le support des
# certificats clients
LDAPTrustedGlobalCert CERT_KEY3_DB "/certs/key3.db"
# Spécifie le fichier secmod si nécessaire
LDAPTrustedGlobalCert CA_SECMOD "/certs/secmod"
<Location "/ldap-status">
    SetHandler ldap-status

    Require host yourdomain.example.com

    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    LDAPTrustedClientCert CERT_NICKNAME <nickname> [password]
    AuthLDAPURL "ldaps://127.0.0.1/dc=example,dc=com?uid?one"
    Require valid-user
</Location>

SDK Novell

Un ou plusieurs certificats de CA doivent être spécifiés pour que le SDK Novell fonctionne correctement. Ces certificats peuvent être spécifiés sous forme de fichiers au format binaire DER ou codés en Base64 (PEM).

Note: Les certificats clients sont spécifiés globalement plutôt qu'à chaque connexion, et doivent être spécifiés à l'aide de la directive LDAPTrustedGlobalCert comme ci-dessous. Définir des certificats clients via la directive LDAPTrustedClientCert engendrera une erreur qui sera journalisée, au moment de la tentative de connexion avec le serveur LDAP.

Le SDK supporte SSL et STARTTLS, le choix étant défini par le paramètre de la directive LDAPTrustedMode. Si une URL de type ldaps:// est spécifiée, le mode SSL est forcé, et l'emporte sur cette directive.

# Spécifie deux fichiers contenant des certificats de CA
LDAPTrustedGlobalCert CA_DER "/certs/cacert1.der"
LDAPTrustedGlobalCert CA_BASE64 "/certs/cacert2.pem"
# Spécifie un fichier contenant des certificats clients
# ainsi qu'une clé
LDAPTrustedGlobalCert CERT_BASE64 "/certs/cert1.pem"
LDAPTrustedGlobalCert KEY_BASE64 "/certs/key1.pem" [password]
# N'utilisez pas cette directive, sous peine de provoquer
# une erreur
#LDAPTrustedClientCert CERT_BASE64 "/certs/cert1.pem"

SDK OpenLDAP

Un ou plusieurs certificats de CA doivent être spécifiés pour que le SDK OpenLDAP fonctionne correctement. Ces certificats peuvent être spécifiés sous forme de fichiers au format binaire DER ou codés en Base64 (PEM).

Les certificats clients et CA peuvent être spécifiés globalement (LDAPTrustedGlobalCert) ou pour chaque connexion (LDAPTrustedClientCert). Les définitions au niveau d'une connexion l'emportent sur les définitions globales.

La documentation du SDK prétend que SSL et STARTTLS sont supportés ; cependant, STARTTLS semble ne pas fonctionner avec toutes les versions du SDK. Le mode SSL/TLS peut être défini en utilisant le paramètre de la directive LDAPTrustedMode. Si une URL de type ldaps:// est spécifiée, le mode SSL est forcé. La documentation OpenLDAP indique que le support SSL (ldaps://) tend à être remplacé par TLS, bien que le mode SSL fonctionne toujours.

# Spécifie deux fichiers contenant des certificats de CA
LDAPTrustedGlobalCert CA_DER "/certs/cacert1.der"
LDAPTrustedGlobalCert CA_BASE64 "/certs/cacert2.pem"
<Location /ldap-status>
    SetHandler ldap-status
    
    Require host yourdomain.example.com
    
    LDAPTrustedClientCert CERT_BASE64 "/certs/cert1.pem"
    LDAPTrustedClientCert KEY_BASE64 "/certs/key1.pem"
    # CA certs respecified due to per-directory client certs
    LDAPTrustedClientCert CA_DER "/certs/cacert1.der"
    LDAPTrustedClientCert CA_BASE64 "/certs/cacert2.pem"
    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldaps://127.0.0.1/dc=example,dc=com?uid?one"
    Require valid-user
</Location>

SDK Solaris

SSL/TLS pour les bibliothèques LDAP propres à Solaris n'est pas encore supporté. Si nécessaire, installez et utilisez plutôt les bibliothèques OpenLDAP.

SDK Microsoft

La configuration des certificats SSL/TLS pour les bibliothèques LDAP propres à Microsoft s'effectue à l'intérieur du registre système, et aucune directive de configuration n'est requise.

SSL et TLS sont tous deux supportés en utilisant des URLs de type ldaps://, ou en définissant la directive LDAPTrustedMode à cet effet.

Note: L'état du support des certificats clients n'est pas encore connu pour ce SDK.

top

Directive LDAPCacheEntries

Description:Nombre maximum d'entrées dans le cache LDAP primaire
Syntaxe:LDAPCacheEntries nombre
Défaut:LDAPCacheEntries 1024
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier la taille maximale du cache LDAP primaire. Ce cache contient les résultats de recherche/identification positifs. Définissez-la à 0 pour désactiver la mise en cache des résultats de recherche/identification positifs. La taille par défaut est de 1024 recherches en cache.

top

Directive LDAPCacheTTL

Description:Durée pendant laquelle les entrées du cache restent valides.
Syntaxe:LDAPCacheTTL secondes
Défaut:LDAPCacheTTL 600
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier la durée (en secondes) pendant laquelle une entrée du cache de recherche/identification reste valide. La valeur par défaut est de 600 secondes (10 minutes).

top

Directive LDAPConnectionPoolTTL

Description:Désactive les connexions d'arrière-plan qui sont restées inactives trop longtemps au sein du jeu de connexions.
Syntaxe:LDAPConnectionPoolTTL n
Défaut:LDAPConnectionPoolTTL -1
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ldap
Compatibilité:Disponible à partir de la version 2.3.12 du serveur HTTP Apache

Cette directive permet de spécifier la durée maximale, en secondes, pendant laquelle une connexion LDAP du jeu de connexions peut demeurer inactive, mais rester quand-même disponible pour une utilisation éventuelle. Le jeu de connexions est nettoyé au fur et à mesure des besoins, de manière non asynchrone.

Si cette directive est définie à 0, les connexions ne sont jamais sauvegardées dans le jeu de connexions d'arrière-plan. Avec la valeur par défaut -1, ou toute autre valeur négative, les connexions peuvent être réutilisées sans limite de durée.

Dans le but d'améliorer les performances, le temps de référence qu'utilise cette directive correspond au moment où la connexion LDAP est enregistrée ou remise dans le jeu de connexions, et non au moment du dernier échange réussi avec le serveur LDAP.

La version 2.4.10 a introduit de nouvelles mesures permettant d'éviter une augmentation excessive du temps de référence due à des correspondances positives dans le cache ou des requêtes lentes. A cet effet, le temps de référence n'est pas réactualisé si aucune connexion LDAP d'arrière-plan n'est requise ; d'autre part, le temps de référence se base sur le moment où la requête HTTP est reçue, et non sur le moment où la requête a été traitée.

Cette durée de vie s'exprime par défaut en secondes, mais il est possible d'utiliser d'autres unités en ajoutant un suffixe : millisecondes (ms), minutes (min), ou heures (h).

top

Directive LDAPConnectionTimeout

Description:Spécifie le délai d'attente en secondes de la socket de connexion
Syntaxe:LDAPConnectionTimeout secondes
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive configure l'option LDAP_OPT_NETWORK_TIMEOUT (ou LDAP_OPT_CONNECT_TIMEOUT) dans la bibliothèque client LDAP sous-jacente, si elle est disponible. Cette valeur représente la durée pendant laquelle la bibliothèque client LDAP va attendre que le processus de connexion TCP au serveur LDAP soit achevé.

Si la connexion n'a pas réussi avant ce délai, une erreur sera renvoyée, ou la bibliothèque client LDAP tentera de se connecter à un second serveur LDAP, s'il en a été défini un (via une liste de noms d'hôtes séparés par des espaces dans la directive AuthLDAPURL).

La valeur par défaut est 10 secondes, si la bibliothèque client LDAP liée avec le serveur supporte l'option LDAP_OPT_NETWORK_TIMEOUT.

LDAPConnectionTimeout n'est disponible que si la bibliothèque client LDAP liée avec le serveur supporte l'option LDAP_OPT_NETWORK_TIMEOUT (ou LDAP_OPT_CONNECT_TIMEOUT), et le comportement final est entièrement dicté par la bibliothèque client LDAP.
top

Directive LDAPLibraryDebug

Description:Active le débogage dans le SDK LDAP
Syntaxe:LDAPLibraryDebug 7
Défaut:disabled
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Active les options de débogage LDAP spécifiques au SDK, qui entraînent en général une journalisation d'informations verbeuses du SDK LDAP dans le journal principal des erreurs d'Apache. Les messages de traces en provenance du SDK LDAP fournissent des informations très détaillées qui peuvent s'avérer utiles lors du débogage des problèmes de connexion avec des serveurs LDAP d'arrière-plan.

Cette option n'est configurable que lorsque le serveur HTTP Apache est lié avec un SDK LDAP qui implémente LDAP_OPT_DEBUG ou LDAP_OPT_DEBUG_LEVEL, comme OpenLDAP (une valeur de 7 est verbeuse) ou Tivoli Directory Server (une valeur de 65535 est verbeuse).

Les informations journalisées peuvent contenir des données d'authentification en clair utilisées ou validées lors de l'authentification LDAP ; vous devez donc prendre soin de protéger et de purger le journal des erreurs lorsque cette directive est utilisée.

top

Directive LDAPOpCacheEntries

Description:Nombre d'entrées utilisées pour mettre en cache les opérations de comparaison LDAP
Syntaxe:LDAPOpCacheEntries nombre
Défaut:LDAPOpCacheEntries 1024
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier le nombre d'entrées que mod_ldap va utiliser pour mettre en cache les opérations de comparaison LDAP. La valeur par défaut est de 1024 entrées. Si elle est définie à 0, la mise en cache des opérations de comparaison LDAP est désactivée.

top

Directive LDAPOpCacheTTL

Description:Durée pendant laquelle les entrées du cache d'opérations restent valides
Syntaxe:LDAPOpCacheTTL secondes
Défaut:LDAPOpCacheTTL 600
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier la durée (en secondes) pendant laquelle les entrées du cache d'opérations restent valides. La valeur par défaut est de 600 secondes.

top

Directive LDAPReferralHopLimit

Description:Le nombre maximum de redirections vers des serveurs alternatifs (referrals) avant l'abandon de la requête LDAP.
Syntaxe:LDAPReferralHopLimit nombre
Défaut:Dépend du SDK, en général entre 5 et 10
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ldap

Si elle est activée par la directive LDAPReferrals, cette directive permet de définir le nombre maximum de sauts vers des serveurs alternatifs (referrals) avant l'abandon de la requête LDAP.

L'ajustement de ce paramètre n'est pas commun à tous les SDKs LDAP.

top

Directive LDAPReferrals

Description:Active la redirection vers des serveurs alternatifs au cours des requêtes vers le serveur LDAP.
Syntaxe:LDAPReferrals On|Off|default
Défaut:LDAPReferrals On
Contexte:répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_ldap
Compatibilité:Le paramètre default est disponible depuis la version 2.4.7 du serveur HTTP Apache.

Certains serveurs LDAP partagent leur annuaire en plusieurs domaines et utilisent le système des redirections (referrals) pour aiguiller un client lorsque les limites d'un domaine doivent être franchies. Ce processus est similaire à une redirection HTTP. Les bibliothèques client LDAP ne respectent pas forcément ces redirections par défaut. Cette directive permet de configurer explicitement les redirections LDAP dans le SDK sous-jacent.

La directive LDAPReferrals accepte les valeurs suivantes :

"on"

Avec la valeur "on", la prise en compte des redirections LDAP par le SDK sous-jacent est activée, la directive LDAPReferralHopLimit permet de surcharger la "hop limit" du SDK, et un "LDAP rebind callback" est enregistré.

"off"

Avec la valeur "off", la prise en compte des redirections LDAP par le SDK sous-jacent est complètement désactivée.

"default"

Avec la valeur "default", la prise en compte des redirections LDAP par le SDK sous-jacent n'est pas modifiée, la directive LDAPReferralHopLimit ne permet pas de surcharger la "hop limit" du SDK, et aucun "LDAP rebind callback" n'est enregistré.

La directive LDAPReferralHopLimit travaille en conjonction avec cette directive pour limiter le nombre de redirections à suivre pour achever le traitement de la requête LDAP. Lorsque le processus de redirection est activé par la valeur "On", les données d'authentification du client sont transmises via un "rebind callback" à tout serveur LDAP qui en fait la demande.

top

Directive LDAPRetries

Description:Définit le nombre maximum de tentatives de connexions au serveur LDAP.
Syntaxe:LDAPRetries nombre d'essais
Défaut:LDAPRetries 3
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Suite à des échecs de connexion au serveur LDAP, le serveur tentera de se connecter autant de fois qu'indiqué par la directive LDAPRetries. Si cette directive est définie à 0, le serveur ne tentera pas d'autre connexion après un échec.

Il est possible d'effectuer une autre tentative de connexion en cas d'erreurs LDAP du type délai dépassé ou connexion refusée.

top

Directive LDAPRetryDelay

Description:Définit le temps d'attente avant un autre essai de connexion au serveur LDAP.
Syntaxe:LDAPRetryDelay secondes
Défaut:LDAPRetryDelay 0
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Si la directive LDAPRetryDelay est définie à une valeur différente de 0, le serveur attendra pendant la durée spécifiée pour envoyer à nouveau sa requête LDAP. Une valeur de 0 implique une absence de délai pour les essais successifs.

Il est possible d'effectuer une autre tentative de connexion en cas d'erreurs LDAP du type délai dépassé ou connexion refusée.

top

Directive LDAPSharedCacheFile

Description:Définit le fichier du cache en mémoire partagée
Syntaxe:LDAPSharedCacheFile chemin/fichier
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier le chemin du fichier du cache en mémoire partagée. Si elle n'est pas définie, la mémoire partagée anonyme sera utilisée si la plate-forme la supporte.

top

Directive LDAPSharedCacheSize

Description:Taille en octets du cache en mémoire partagée
Syntaxe:LDAPSharedCacheSize octets
Défaut:LDAPSharedCacheSize 500000
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier le nombre d'octets à allouer pour le cache en mémoire partagée. La valeur par défaut est 500kb. Si elle est définie à 0, le cache en mémoire partagée ne sera pas utilisé et chaque processus HTTPD va créer son propre cache.

top

Directive LDAPTimeout

Description:Spécifie le délai d'attente pour les opérations de recherche et d'identification LDAP en secondes
Syntaxe:LDAPTimeout secondes
Défaut:LDAPTimeout 60
Contexte:configuration globale
Statut:Extension
Module:mod_ldap
Compatibilité:Disponible à partir de la version 2.3.5 du serveur HTTP Apache

Cette directive permet de spécifier le délai d'attente pour les opérations de recherche et d'identification, ainsi que l'option LDAP_OPT_TIMEOUT dans la bibliothèque LDAP client sous-jacente, lorsqu'elle est disponible.

Lorsque le délai est atteint, httpd va refaire un essai dans le cas où une connexion existante a été silencieusement fermée par un pare-feu. Les performances seront cependant bien meilleures si le pare-feu est configuré pour envoyer des paquets TCP RST au lieu de rejeter silencieusement les paquets.

Les délais pour les opérations de comparaison LDAP nécessitent un SDK avec LDAP_OPT_TIMEOUT, comme OpenLDAP >= 2.4.4.

top

Directive LDAPTrustedClientCert

Description:Définit le nom de fichier contenant un certificat client ou un alias renvoyant vers un certificat client spécifique à une connexion. Tous les SDK LDAP ne supportent pas les certificats clients par connexion.
Syntaxe:LDAPTrustedClientCert type chemin/nom-fichier/alias [mot de passe]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier le chemin et le nom de fichier ou l'alias d'un certificat client par connexion utilisé lors de l'établissement d'une connexion SSL ou TLS avec un serveur LDAP. Les sections directory ou location peuvent posséder leurs propres configurations de certificats clients. Certains SDK LDAP (en particulier Novell) ne supportent pas les certificats clients par connexion, et renvoient une erreur lors de la connexion au serveur LDAP si vous tenter d'utiliser cette directive (Utilisez à la place la directive LDAPTrustedGlobalCert pour les certificats clients sous Novell - Voir plus haut le guide des certificats SSL/TLS pour plus de détails). Le paramètre type spécifie le type du certificat en cours de définition, en fonction du SDK LDAP utilisé. Les types supportés sont :

top

Directive LDAPTrustedGlobalCert

Description:Définit le nom de fichier ou la base de données contenant les Autorités de Certification de confiance globales ou les certificats clients globaux
Syntaxe:LDAPTrustedGlobalCert type chemin/nom-fichier [mot de passe]
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier le chemin et le nom du fichier contenant les certificats des CA de confiance et/ou les certificats clients du système global que mod_ldap utilisera pour établir une connexion SSL ou TLS avec un serveur LDAP. Notez que toute information relative aux certificats spécifiée en utilisant cette directive s'applique globalement à l'ensemble de l'installation du serveur. Certains SDK LDAP (en particulier Novell) nécessitent la définition globale de tous les certificats clients en utilisant cette directive. La plupart des autres SDK nécessitent la définition des certificats clients dans une section Directory ou Location en utilisant la directive LDAPTrustedClientCert. Si vous ne définissez pas ces directives correctement, une erreur sera générée lors des tentatives de contact avec un serveur LDAP, ou la connexion échouera silencieusement (Voir plus haut le guide des certificats SSL/TLS pour plus de détails). Le paramètre type spécifie le type de certificat en cours de définition, en fonction du SDK LDAP utilisé. Les types supportés sont :

top

Directive LDAPTrustedMode

Description:Spécifie le mode (SSL ou TLS) à utiliser lors de la connexion à un serveur LDAP.
Syntaxe:LDAPTrustedMode type
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_ldap

Les modes suivants sont supportés :

Les modes ci-dessus ne sont pas supportés par tous les SDK LDAP. Un message d'erreur sera généré à l'exécution si un mode n'est pas supporté, et la connexion au serveur LDAP échouera.

Si une URL de type ldaps:// est spécifiée, le mode est forcé à SSL et la définition de LDAPTrustedMode est ignorée.

top

Directive LDAPVerifyServerCert

Description:Force la vérification du certificat du serveur
Syntaxe:LDAPVerifyServerCert On|Off
Défaut:LDAPVerifyServerCert On
Contexte:configuration globale
Statut:Extension
Module:mod_ldap

Cette directive permet de spécifier s'il faut forcer la vérification d'un certificat de serveur lors de l'établissement d'une connexion SSL avec un serveur LDAP.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_forensic.html.fr.utf80000664000175100017510000003461014740503670023311 0ustar covenercovener mod_log_forensic - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_log_forensic

Langues Disponibles:  en  |  fr  |  ja  |  tr 

Description:Journalisation légale des requêtes envoyées au serveur
Statut:Extension
Identificateur de Module:log_forensic_module
Fichier Source:mod_log_forensic.c
Compatibilité:mod_unique_id n'est plus obligatoire depuis la version 2.1

Sommaire

Ce module permet la journalisation légale des requêtes client. La journalisation s'effectuant avant et après le traitement de la requête, le journal légal contient deux lignes pour chaque requête. Le processus de journalisation légale est très strict, à savoir :

Pour interpréter les données du journal légal, vous pouvez vous aider du script check_forensic qui se trouve dans le répertoire support de la distribution.

Note de traduction : le terme "légal" utilisé dans le présent document ne suggère aucunement que ce module apporte une valeur juridique aux journaux. Il est à comprendre dans le contexte similaire à ce que l'on trouve en analyse medico-légale. En d'autres termes, la finalité de ce module est de simplifier les opérations d'investigation autour du traitement des requêtes par le serveur.
Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Format du journal Forensic

Chaque requête fait l'objet d'une double journalisation. La requête est journalisée une première fois avant son traitement (c'est à dire après la réception des en-têtes). La deuxième entrée du journal est écrite après le traitement de la requête, en fait au moment de la journalisation habituelle.

Un identifiant unique est attribué à chaque requête afin de pouvoir l'identifier. Cette identifiant légal peut faire l'objet d'un enregistrement dans le journal standard en utilisant l'élément de chaîne de format %{forensic-id}n. Si vous utilisez mod_unique_id, c'est l'identifiant qu'il génère qui sera utilisé.

La première partie de la journalisation de la requête enregistre l'identifiant légal, la ligne de la requête et tous les en-têtes reçus séparés par des caractères pipe (|). Voici à titre d'exemple à quoi pourrait ressembler une telle entrée (tout étant rassemblé sur une seule ligne) :

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

Le caractère plus ('+') de début indique qu'il s'agit de la première entrée de journal pour cette requête. La seconde entrée ne contiendra qu'un caractère moins ('-') suivi de l'identifiant :

-yQtJf8CoAB4AAFNXBIEAAAAA

Le script check_forensic prend comme argument le nom du fichier journal. Il recherche ces paires d'identifiants +/- et affiche un message d'erreur si la journalisation d'une requête n'est pas complète.

top

Considérations à propos de sécurité

Voir le document conseils en matière de sécurité pour des détails sur les raisons pour lesquelles votre sécurité pourrait être compromise si le répertoire dans lequel les fichiers journaux sont stockés sont inscriptibles par tout autre utilisateur que celui qui démarre le serveur.

Les fichiers journaux peuvent contenir des données sensibles comme le contenu des en-têtes Authorization: (qui peuvent contenir des mots de passe) ; ils ne doivent donc être lisibles que par l'utilisateur qui démarre le serveur.

top

Directive ForensicLog

Description:Définit le nom de fichier du journal légal
Syntaxe:ForensicLog nom-fichier|pipe
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_log_forensic

La directive ForensicLog permet de contrôler la journalisation des requêtes à des fins d'analyse légale. Chaque entrée du journal se voit assigner un identifiant unique qui peut être associé à la requête en utilisant la directive CustomLog habituelle. mod_log_forensic crée un élément nommé forensic-id, qui peut être ajouté au journal standard en utilisant l'élément de format %{forensic-id}n.

L'argument, qui permet de spécifier l'emplacement vers lequel le journal légal sera écrit, peut contenir les deux types de valeurs suivants :

nom-fichier
Un nom de fichier relatif au répertoire défini par la directive ServerRoot.
pipe
Le caractère pipe "|", suivi du chemin vers un programme qui recevra les informations de la journalisation sur son entrée standard. Le nom du programme peut être relatif au répertoire défini par la directive ServerRoot.

Sécurité :

Si les journaux sont redirigés vers un programme, ce dernier s'exécutera sous l'utilisateur qui a démarré httpd. Ce sera l'utilisateur root si le serveur a été démarré par root ; vérifiez que le programme est sécurisé ou passe sous le contrôle d'un utilisateur possédant des droits restreints.

Note

Lors de la spécification d'un chemin de fichier sur les plate-formes non-Unix, il faut prendre soin de ne pas oublier que seuls les slashes directs doivent être utilisés, même si la plate-forme autorise l'emploi d'anti-slashes. D'une manière générale, c'est une bonne idée que de n'utiliser que des slashes directs dans les fichiers de configuration.

Langues Disponibles:  en  |  fr  |  ja  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache.html.fr.utf80000664000175100017510000022421514740503670021705 0ustar covenercovener mod_cache - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_cache

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Filtre de mise en cache HTTP conforme à la RFC 2616
Statut:Extension
Identificateur de Module:cache_module
Fichier Source:mod_cache.c

Sommaire

Ce module doit être utilisé avec précautions car lorsque la directive CacheQuickHandler est définie à sa valeur par défaut on, les directives Allow and Deny sont court-circuitées. Vous ne devez donc pas activer la gestion rapide de la mise en cache pour un contenu auquel vous souhaitez limiter l'accès en fonction du nom d'hôte du client, de l'adresse IP ou d'une variable d'environnement.

mod_cache implémente un filtre de mise en cache de contenu HTTP conforme à la RFC 2616, avec support de la mise en cache des réponses dont le contenu a été négocié et comportant l'en-tête Vary.

La mise en cache conforme à la RFC 2616 fournit un mécanisme permettant de vérifier si un contenu expiré ou dépassé est encore à jour, et peut apporter un gain de performances significatif si le serveur original supporte les requêtes conditionnelles en prenant en compte l'en-tête de requête HTTP If-None-Match. Le contenu n'est ainsi régénéré que lorsqu'il a été modifié, et non lorsqu'il a expiré.

En tant que filtre, mod_cache peut être placé en face d'un contenu issu de tout gestionnaire, y compris des fichiers à accès séquentiel (servis depuis un disque lent mis en cache sur un gros disque), la sortie d'un script CGI ou d'un générateur de contenu dynamique, ou du contenu mandaté depuis un autre serveur.

Dans la configuration par défaut, mod_cache place le filtre de mise en cache aussi loin que possible dans la pile de filtres, utilisant le gestionnaire rapide pour court-circuiter tout traitement par requête lors de l'envoi du contenu au client. Dans ce mode opératoire, mod_cache peut être considéré comme un serveur mandataire avec cache fixé en tête du serveur web, alors qu'il s'exécute dans ce même serveur web.

Lorsque le gestionnaire rapide est désactivé via la directive CacheQuickHandler, il devient possible d'insérer le filtre CACHE à un point de la pile de filtres choisi par l'administrateur. Ceci permet de mettre en cache un contenu avant que celui-ci ne soit personnalisé par le filtre mod_include, ou éventuellement compressé par le filtre mod_deflate.

Dans le mode de fonctionnement normal, mod_cache peut être contrôlé par les en-têtes Cache-Control et Pragma envoyés par un client dans une requête, ou par un serveur dans une réponse. Dans des circonstances exceptionnelles, mod_cache peut cependant être configuré pour outrepasser ces en-têtes et forcer un comportement spécifique au site, bien qu'un tel comportement sera limité à ce cache seulement, et n'affectera pas les opérations des autres caches qui peuvent s'insérer entre le client et le serveur, et ce type de configuration ne doit donc être utiliser qu'en cas de nécessité absolue.

La RFC 2616 permet au cache de renvoyer des données périmées pendant que l'entrée périmée correspondante est mise à jour depuis le serveur original, et mod_cache supporte cette fonctionnalité lorsque la directive CacheLock est configurée en conséquence. De telles réponses comportent un en-tête HTTP Warning contenant un code de réponse 110. La RFC 2616 permet aussi au cache de renvoyer des données périmées lorsque la tentative de mise à jour des données périmées renvoie une erreur 500 ou supérieure, et cette fonctionnalité est supportée par défaut par mod_cache. De telles réponses comportent un en-tête HTTP Warning contenant un code de réponse 111.

mod_cache requiert les services d'un ou plusieurs modules de gestion de stockage. La distribution Apache de base inclut les modules de gestion de stockage suivants :

mod_cache_disk
implémente un gestionnaire de stockage sur disque. Les en-têtes et corps sont stockés séparément sur le disque dans une structure de répertoires basée sur le condensé md5 de l'URL mise en cache. Plusieurs réponses à contenu négocié peuvent être stockées en même temps, mais la mise en cache de contenus partiels n'est pas supportée par ce module. L'utilitaire htcacheclean permet de lister et de supprimer les URLs mises en cache, et de maintenir le cache en deçà de certaines limites de taille et de nombre d'inodes.
mod_cache_socache
Implémente un gestionnaire de stockage basé sur un cache d'objets partagés. Les en-têtes et corps sont stockés ensemble sous une seule clé basée sur l'URL de la réponse mise en cache. Des réponses à contenus multiples négociés peuvent être stockées simultanément, mais ce module ne supporte pas la mise en cache de contenus partiels.

Pour de plus amples détails, une description, et des exemples, reportez-vous au Guide de la mise en cache.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Modules apparentés et directives

top

Exemple de configuration

Extrait de httpd.conf

#
# Exemple de configuration du cache
#
LoadModule cache_module modules/mod_cache.so
<IfModule mod_cache.c>
    LoadModule cache_disk_module modules/mod_cache_disk.so
    <IfModule mod_cache_disk.c>
        CacheRoot "c:/cacheroot"
        CacheEnable disk  "/"
        CacheDirLevels 5
        CacheDirLength 3
    </IfModule>
    
    # Lorsqu'on sert de mandataire, on ne met pas en cache la liste
# des mises à jour de sécurité
    CacheDisable "http://security.update.server/update-list/"
</IfModule>
top

Eviter une tempête de requête

Lorsqu'une entrée du cache est périmée, mod_cache soumet une requête conditionnelle au processus d'arrière-plan, qui est censé confirmer la validité de l'entrée du cache, ou dans la négative envoyer une entrée mise à jour.

Un court mais non négligeable laps de temps existe entre le moment où l'entrée du cache est périmée, et le moment où elle est mise à jour. Sur un serveur fortement chargé, un certain nombre de requêtes peut arriver pendant ce laps de temps, et provoquer une tempête de requêtes susceptibles de saturer le processus d'arrière-plan de manière soudaine et imprédictible.

Pour contenir cette tempête, on peut utiliser la directive CacheLock afin de définir un répertoire où seront créés à la volée des verrous pour les URLs. Ces verrous sont utilisés comme autant d'indications par les autres requêtes, soit pour empêcher une tentative de mise en cache (un autre processus est en train de récupérer l'entité), soit pour indiquer qu'une entrée périmée est en cours de mise à jour (pendant ce temps, c'est le contenu périmé qui sera renvoyé).

Mise en cache initiale d'une entrée

Lorsqu'une entité est mise en cache pour la première fois, un verrou est créé pour cette entité jusqu'à ce que la réponse ait été entièrement mise en cache. Pendant la durée de vie du verrou, le cache va empêcher une seconde tentative de mise en cache de la même entité. Bien que cela ne suffise pas à contenir la tempête de requêtes, toute tentative de mettre en cache la même entité plusieurs fois simultanément est stoppée.

Mise à jour d'une entrée périmée

Lorsqu'une entrée atteint la limite de sa durée de vie, et devient par conséquent périmée, un verrou est créé pour cette entité jusqu'à ce que la réponse ait été soit confirmée comme encore valide, soit remplacée par le processus d'arrière-plan. Pendant la durée de vie du verrou, une seconde requête entrante va provoquer le renvoi de la donnée périmée, et la tempête de requêtes sera contenue.

Verrous et en-tête Cache-Control: no-cache

Les verrous ne sont utilisés qu'à titre indicatif pour enjoindre le cache à être plus coopératif avec les serveurs d'arrière-plan, et il est possible de passer outre si nécessaire. Si le client envoie une requête contenant un en-tête Cache-Control imposant un nouveau téléchargement de l'entité, tout verrou éventuel sera ignoré, la requête du client sera honorée immédiatement, et l'entrée du cache mise à jour.

Comme mécanisme de sécurité supplémentaire, la durée de vie maximale des verrous est configurable. Lorsque cette limite est atteinte, le verrou est supprimé et une autre requête peut alors en créer un nouveau. Cette durée de vie peut être définie via la directive CacheMaxExpire, et sa valeur par défaut est de 5 secondes.

Exemple de configuration

Activation du verrouillage du cache

#
# Active le verrouillage du cache
#
<IfModule mod_cache.c>
    CacheLock on
    CacheLockPath "/tmp/mod_cache-lock"
    CacheLockMaxAge 5
</IfModule>
top

Contrôle fin via le filtre CACHE

Dans son mode de fonctionnement par défaut, le cache s'exécute sous la forme d'un gestionnaire rapide, court-circuitant la majorité des traitements du serveur et fournissant ainsi une mise en cache possédant les plus hautes performances disponibles.

Dans ce mode, le cache s'incruste devant le serveur, comme si un mandataire de mise en cache indépendant RFC 2616 était placé devant ce dernier.

Bien que que ce mode offre les meilleures performances, les administrateurs peuvent souhaiter, dans certaines circonstances, effectuer des traitements sur la requête après que cette dernière ait été mise en cache, comme ajouter du contenu personnalisé à la page mise en cache, ou appliquer des restrictions d'autorisations au contenu. Pour y parvenir, l'administrateur sera alors souvent forcé de placer des serveurs mandataires inverses indépendants soit derrière, soit devant le serveur de mise en cache.

Pour résoudre ce problème, la directive CacheQuickHandler peut être définie à off, afin que le serveur traite toutes les phases normalement exécutées par une requête non mise en cache, y compris les phases d'authentification et d'autorisation.

En outre, l'administrateur peut éventuellement spécifier le point précis dans la chaîne de filtrage où devra intervenir la mise en cache en ajoutant le filtre CACHE à la chaîne de filtrage en sortie.

Par exemple, pour mettre en cache le contenu avant d'appliquer une compression à la réponse, placez le filtre CACHE avant le filtre DEFLATE comme dans l'exemple suivant :

# Mise en cache du contenu avant la compression optionnelle
CacheQuickHandler off
AddOutputFilterByType CACHE;DEFLATE text/plain

Une autre possibilité consiste à mettre en cache le contenu avant l'ajout de contenu personnalisé via mod_include (ou tout autre filtre de traitement de contenu). Dans l'exemple suivant, les modèles contenant des balises comprises par mod_include sont mis en cache avant d'être interprétés :

# Mise en cache du contenu avant l'intervention de mod_include et
   # mod_deflate
CacheQuickHandler off
AddOutputFilterByType CACHE;INCLUDES;DEFLATE text/html

Vous pouvez insérer le filtre CACHE en tout point de la chaîne de filtrage. Dans l'exemple suivant, le contenu est mis en cache après avoir été interprété par mod_include, mais avant d'être traité par mod_deflate :

# Mise en cache du contenu entre les interventions de mod_include et
   # mod_deflate
CacheQuickHandler off
AddOutputFilterByType INCLUDES;CACHE;DEFLATE text/html

Avertissement :

Si pour une raison ou pour une autre, le point d'insertion du filtre CACHE dans la chaîne de filtrage est modifié, vous devez vider votre cache pour être sûr que les données servies soient à jour. En effet, mod_cache n'est pas en mesure d'effectuer cette opération à votre place.
top

Etat du cache et journalisation

Lorsque mod_cache a décidé s'il devait ou non servir une entité depuis le cache, les raisons précises de cette décision sont enregistrées dans l'environnement du sous-processus interne à la requête sous la clé cache-status. Cette information peut être journalisée via la directive LogFormat comme suit :

LogFormat "%{cache-status}e ..."

En fonction de la décision prise, l'information est aussi écrite dans l'environnement du sous-processus sous une des quatre clés suivantes :

cache-hit
Le contenu a été servi depuis le cache.
cache-revalidate
Le contenu du cache était périmé, a été mis à jour avec succès, puis servi depuis le cache.
cache-miss
Le contenu n'était pas dans le cache et a été servi directement depuis le serveur demandé.
cache-invalidate
L'entité du cache est devenue invalide suite à une requête d'un type autre que GET ou HEAD.

Il est alors possible d'envisager une journalisation conditionnelle du traitement des requêtes par rapport au cache comme dans l'exemple suivant :

CustomLog "cached-requests.log" common env=cache-hit
CustomLog "uncached-requests.log" common env=cache-miss
CustomLog "revalidated-requests.log" common env=cache-revalidate
CustomLog "invalidated-requests.log" common env=cache-invalidate

Pour les concepteurs de modules, une accroche (hook) nommée cache_status est disponible et permet aux modules de répondre aux résultats de la vérification du cache ci-dessus de manière personnalisée.

top

Directive CacheDefaultExpire

Description:La durée par défaut de mise en cache d'un document lorsqu'aucune date d'expiration n'a été spécifiée.
Syntaxe:CacheDefaultExpire secondes
Défaut:CacheDefaultExpire 3600 (une heure)
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

La directive CacheDefaultExpire permet de spécifier un temps par défaut, en secondes, pendant lequel sera conservé dans le cache un document qui ne possède ni date d'expiration, ni date de dernière modification. La valeur de cette directive n'est pas écrasée par la valeur de la directive CacheMaxExpire, même si cette dernière est utilisée.

CacheDefaultExpire 86400
top

Directive CacheDetailHeader

Description:Ajoute un en-tête X-Cache-Detail à la réponse.
Syntaxe:CacheDetailHeader on|off
Défaut:CacheDetailHeader off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache
Compatibilité:Disponible depuis la version 2.3.9 d'Apache

Lorsque la directive CacheDetailHeader est définie à on, un en-tête X-Cache-Detail est ajouté à la réponse et contient les raisons précises d'une décision d'utilisation du cache vis à vis de cette dernière.

Ceci peut s'avérer utile au cours du développement de services RESTful mis en cache pour obtenir des informations supplémentaires à propos des décisions vis à vis du cache écrites dans les en-têtes de la réponse. Il est ainsi possible de vérifier si Cache-Control et d'autres en-têtes ont été correctement utilisés par le service et le client.

Si le gestionnaire normal est utilisé, cette directive peut se situer dans une section <Directory> ou <Location>. Si c'est le gestionnaire rapide qui est utilisé, elle doit se situer dans un contexte de serveur principal ou de serveur virtuel, sinon elle sera ignorée.

# Active l'en-tête X-Cache-Detail
CacheDetailHeader on

X-Cache-Detail: "conditional cache hit: entity refreshed" from localhost

top

Directive CacheDisable

Description:Désactive la mise en cache des URLs spécifiées
Syntaxe:CacheDisable chaîne-url | on
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

La directive CacheDisable enjoint mod_cache de ne pas mettre en cache l'URL spécifiée par chaîne URL, ainsi que les URLs de niveaux inférieurs.

Exemple

CacheDisable "/fichiers_locaux"

Si la directive se trouve à l'intérieur d'une section <Location>, le chemin doit être spécifié en dessous de la Location, et si le mot "on" est utilisé, la mise en cache sera désactivée pour l'ensemble de l'arborescence concernée par la section Location.

Exemple

<Location "/foo">
    CacheDisable on
</Location>

Avec les versions 2.2.12 et ultérieures, on peut définir la variable d'environnement no-cache pour une définition plus fine des ressources à mettre en cache.

Voir aussi

top

Directive CacheEnable

Description:Active la mise en cache des URLs spécifiées en utilisant le gestionnaire de stockage précisé
Syntaxe:CacheEnable type de cache [chaîne URL]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_cache
Compatibilité:Une chaîne URL telle que '/' s'appliquait à tout contenu en mandat direct dans les versions 2.2 et antérieures.

La directive CacheEnable enjoint mod_cache de mettre en cache l'URL précisée par chaîne URL, ainsi que les URLs de niveaux inférieurs. Le gestionnaire de stockage du cache est spécifié à l'aide de l'argument type de cache. La directive CacheEnable peut être placée à l'intérieur d'une section <Location> ou <LocationMatch> pour indiquer que le contenu considéré peut être mis en cache. Si type de cache a pour valeur disk, mod_cache utilisera le gestionnaire de stockage sur disque implémenté par mod_cache_disk. Pour que mod_cache utilise le gestionnaire de stockage basé sur le cache d'objets partagés implémenté par mod_cache_socache, spécifiez socache comme valeur du paramètre type de cache.

Si les différentes directives CacheEnable spécifient des URLs qui se recoupent (comme dans l'exemple ci-dessous), tous les gestionnaires de stockage possibles seront lancés, jusqu'au premier d'entre eux qui traitera effectivement la requête. L'ordre dans lequel les gestionnaires de stockage sont lancés est déterminé par l'ordre dans lequel apparaissent les directives CacheEnable dans le fichier de configuration. Les directives CacheEnable situées à l'intérieur de sections <Location> ou <LocationMatch> sont traitées avant les directives CacheEnable définies au niveau global.

En fonctionnement du type serveur mandataire direct, chaîne URL doit au moins débuter par un protocole pour lequel la mise en cache doit être activée.

# Mise en cache de contenu (gestionnaire normal seulement)
CacheQuickHandler off
<Location "/foo">
    CacheEnable disk
</Location>

# Mise en cache via une expression rationnelle (gestionnaire normal seulement)
CacheQuickHandler off
<LocationMatch "foo$">
    CacheEnable disk
</LocationMatch>

# Mise en cache de tous les contenus, à l'exception des URLs
# mandatées en direct (gestionnaire normal ou rapide)
CacheEnable  disk  /

# Mise en cache des URLs FTP mandatées (gestionnaire normal ou rapide)
CacheEnable  disk  ftp://

# Mise en cache des contenus mandatés en direct depuis www.example.org (gestionnaire normal ou rapide)
CacheEnable  disk  http://www.example.org/

Un nom d'hôte commençant par un caractère "*" correspondra à tout nom d'hôte se terminant par le suffixe considéré. Un nom d'hôte commençant par un caractère "." correspondra à tout nom d'hôte contenant le composant de nom de domaine qui suit ce caractère.

# Correspond à www.example.org et fooexample.org
CacheEnable  disk  "http://*example.org/"
# Correspond à www.example.org, mais pas à fooexample.org
CacheEnable  disk  "http://.example.org/"

Depuis la version 2.2.12, on peut définir la variable d'environnement no-cache pour une définition plus fine des ressources à mettre en cache.

Voir aussi

top

Directive CacheHeader

Description:Ajoute un en-tête X-Cache à la réponse.
Syntaxe:CacheHeader on|off
Défaut:CacheHeader off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache
Compatibilité:Disponible depuis la version 2.3.9 d'Apache

Lorsque la directive CacheHeader est définie à on, un en-tête X-Cache est ajouté à la réponse et contient l'état du cache pour cette dernière. Si le gestionnaire normal est utilisé, cette directive peut se situer dans une section <Directory> ou <Location>. Si c'est le gestionnaire rapide qui est utilisé, elle doit se situer dans un contexte de serveur principal ou de serveur virtuel, sinon elle sera ignorée.

HIT
Le contenu était à jour et a été servi depuis le cache.
REVALIDATE
Le contenu était périmé, a été mis à jour, puis a été servi depuis le cache.
MISS
Le contenu n'a pas été servi depuis le cache, mais directement depuis le serveur demandé.
# Active l'en-tête X-Cache
CacheHeader on
X-Cache: HIT from localhost
top

Directive CacheIgnoreCacheControl

Description:Ignore les en-têtes de requête enjoignant de ne pas servir le contenu au client depuis le cache
Syntaxe:CacheIgnoreCacheControl On|Off
Défaut:CacheIgnoreCacheControl Off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache

Normalement, les requêtes contenant des en-têtes tels que Cache-Control: no-cache ou Pragma: no-cache ne sont pas servies depuis le cache. La directive CacheIgnoreCacheControl permet de modifier ce comportement. Avec CacheIgnoreCacheControl On, le serveur tentera de servir la ressource depuis le cache, même si la requête contient un des en-têtes cités plus haut. Les ressources qui requièrent une autorisation ne seront jamais mises en cache.

CacheIgnoreCacheControl On

Avertissement :

Cette directive permet de servir des ressources depuis le cache, même si le client a demandé à ce qu'il n'en soit pas ainsi. Le contenu servi est ainsi susceptible d'être périmé.

Voir aussi

top

Directive CacheIgnoreHeaders

Description:Ne pas stocker le(s) en-tête(s) spécifié(s) dans le cache.
Syntaxe:CacheIgnoreHeaders en-tête [en-tête] ...
Défaut:CacheIgnoreHeaders None
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache

En accord avec la RFC 2616, les en-têtes HTTP hop-by-hop ne sont pas stockés dans le cache. Les en-têtes HTTP suivant sont des en-têtes hop-by-hop, et en tant que tels, ne sont en aucun cas stockés dans le cache, quelle que soit la définition de la directive CacheIgnoreHeaders :

La directive CacheIgnoreHeaders permet de spécifier quels en-têtes HTTP ne doivent pas être stockés dans le cache. Par exemple, il peut s'avérer pertinent dans certains cas de ne pas stocker les cookies dans le cache.

La directive CacheIgnoreHeaders accepte une liste d'en-têtes HTTP séparés par des espaces, qui ne doivent pas être stockés dans le cache. Si les en-têtes hop-by-hop sont les seuls à ne pas devoir être stockés dans le cache (le comportement compatible RFC 2616), la directive CacheIgnoreHeaders peut être définie à None.

Exemple 1

CacheIgnoreHeaders Set-Cookie

Exemple 2

CacheIgnoreHeaders None

Avertissement :

Si des en-têtes nécessaires à la bonne gestion du cache, comme Expires, ne sont pas stockés suite à la définition d'une directive CacheIgnoreHeaders, le comportement de mod_cache sera imprévisible.
top

Directive CacheIgnoreNoLastMod

Description:Ignore le fait qu'une réponse ne possède pas d'en-tête Last Modified.
Syntaxe:CacheIgnoreNoLastMod On|Off
Défaut:CacheIgnoreNoLastMod Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

Normalement, les documents qui ne possèdent pas de date de dernière modification ne sont pas mis en cache. Dans certaines circonstances, la date de dernière modification est supprimée (au cours des traitements liés à mod_include par exemple), ou n'existe tout simplement pas. La directive CacheIgnoreNoLastMod permet de spécifier si les documents ne possèdant pas de date de dernière modification doivent être mis en cache, même sans date de dernière modification. Si le document ne possède ni date d'expiration, ni date de dernière modification, la valeur spécifiée par la directive CacheDefaultExpire servira à générer une date d'expiration.

CacheIgnoreNoLastMod On
top

Directive CacheIgnoreQueryString

Description:Ignore la chaîne de paramètres lors de la mise en cache
Syntaxe:CacheIgnoreQueryString On|Off
Défaut:CacheIgnoreQueryString Off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache

Normalement, les requêtes comportant une chaîne de paramètres sont mises en cache séparément si leurs chaînes de paramètres diffèrent. En accord avec la RFC 2616/13.9, cette mise en cache n'est effectuée séparément que si une date d'expiration est spécifiée. La directive CacheIgnoreQueryString permet la mise en cache de requêtes même si aucune date d'expiration est spécifiée, et de renvoyer une réponse depuis la cache même si les chaînes de paramètres diffèrent. Du point de vue du cache, la requête est traitée comme si elle ne possèdait pas de chaîne de paramètres lorsque cette directive est activée.

CacheIgnoreQueryString On
top

Directive CacheIgnoreURLSessionIdentifiers

Description:Ignore les identifiants de session définis encodés dans l'URL lors de la mise en cache
Syntaxe:CacheIgnoreURLSessionIdentifiers identifiant [identifiant] ...
Défaut:CacheIgnoreURLSessionIdentifiers None
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache

Certaines applications encodent l'identifiant de session dans l'URL comme dans l'exemple suivant :

Ceci implique la mise en cache des ressources séparément pour chaque session, ce qui n'est en général pas souhaité. La directive CacheIgnoreURLSessionIdentifiers permet de définir une liste d'identifiants qui seront supprimés de la clé utilisée pour identifier une entité dans le cache, de façon à ce que les ressources ne soient pas stockées séparément pour chaque session.

CacheIgnoreURLSessionIdentifiers None vide la liste des identifiants ignorés. Autrement, chaque identifiant spécifié est ajouté à la liste.

Exemple 1

CacheIgnoreURLSessionIdentifiers jsessionid

Exemple 2

CacheIgnoreURLSessionIdentifiers None
top

Directive CacheKeyBaseURL

Description:Remplace l'URL de base des clés du cache mandatées en inverse
Syntaxe:CacheKeyBaseURL URL
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache
Compatibilité:Disponible depuis la version 2.3.9 d'Apache

Lorsque la directive CacheKeyBaseURL est utilisée, l'URL spécifiée sera utilisée comme URL de base pour calculer l'URL des clés du cache dans la configuration du mandataire inverse. Par défaut, c'est le protocole/nom d'hôte/port du serveur virtuel courant qui sera utilisé pour construire la clé de cache. Dans le cas d'un cluster de machines, si toutes les entrées du cache doivent posséder la même clé, cette directive permet de spécifier une nouvelle URL de base.

# Remplace l'URL de base de la clé de cache.
CacheKeyBaseURL "http://www.example.com/"
Prenez garde en définissant cette directive. Si deux serveurs virtuels distincts possèdent accidentellement la même URL de base, les entrées en provenance d'un serveur virtuel seront servies par l'autre.
top

Directive CacheLastModifiedFactor

Description:Le facteur utilisé pour générer une date d'expiration en fonction de la date de dernière modification.
Syntaxe:CacheLastModifiedFactor flottant
Défaut:CacheLastModifiedFactor 0.1
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

Si un document ne possède pas de date d'expiration, elle peut être calculée en fonction de la date de dernière modification, si elle existe. La directive CacheLastModifiedFactor permet de spécifier un facteur à utiliser pour la génération de cette date d'expiration au sein de la formule suivante : délai-expiration = durée-depuis-date-dernière-modification * facteur date-expiration = date-courante + délai-expiration Par exemple, si la dernière modification du document date de 10 heures, et si facteur a pour valeur 0.1, le délai d'expiration sera de 10*0.1 = 1 heure. Si l'heure courante est 3:00pm, la date d'expiration calculée sera 3:00pm + 1 heure = 4:00pm. Si le délai d'expiration est supérieur à celui spécifié par la directive CacheMaxExpire, c'est ce dernier qui l'emporte.

CacheLastModifiedFactor 0.5
top

Directive CacheLock

Description:Active la protection contre les tempêtes de requêtes.
Syntaxe:CacheLock on|off
Défaut:CacheLock off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache
Compatibilité:Disponible depuis la version 2.2.15 d'Apache

La directive CacheLock active la protection contre les tempêtes de requêtes pour l'espace d'adressage donné.

La configuration minimale pour activer le verrouillage contre les tempêtes de requêtes dans le répertoire temp par défaut du système est la suivante :

# Active le verrouillage du cache
CacheLock on
top

Directive CacheLockMaxAge

Description:Définit la durée de vie maximale d'un verrou de cache.
Syntaxe:CacheLockMaxAge entier
Défaut:CacheLockMaxAge 5
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache

La directive CacheLockMaxAge permet de spécifier la durée de vie maximale d'un verrou de cache.

Un verrou plus ancien que cette valeur exprimée en secondes sera ignoré, et la prochaine requête entrante sera alors en mesure de recréer le verrou. Ce mécanisme permet d'éviter les mises à jour trop longues initiées par des clients lents.

top

Directive CacheLockPath

Description:Définit le répertoire des verrous.
Syntaxe:CacheLockPath répertoire
Défaut:CacheLockPath /tmp/mod_cache-lock
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache

La directive CacheLockPath permet de spécifier le répertoire dans lequel les verrous sont créés. Par défaut, c'est le répertoire temporaire du système qui est utilisé. Les verrous sont des fichiers vides qui n'existent que pour les URLs périmées en cours de mise à jour, et consomment donc bien moins de ressources que le traditionnel cache sur disque.

top

Directive CacheMaxExpire

Description:La durée maximale en secondes de mise en cache d'un document
Syntaxe:CacheMaxExpire secondes
Défaut:CacheMaxExpire 86400 (une journée)
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

La directive CacheMaxExpire permet de spécifier le nombre maximum de secondes pendant lequel les documents HTTP suceptibles d'être mis en cache seront conservés sans vérifier leur contenu sur le serveur d'origine. Ce nombre de secondes correspond donc à la durée maximale pendant laquelle un document ne sera pas à jour. L'utilisation de cette valeur maximale est forcée, même si le document possède une date d'expiration.

CacheMaxExpire 604800
top

Directive CacheMinExpire

Description:La durée minimale en secondes de mise en cache d'un document
Syntaxe:CacheMinExpire secondes
Défaut:CacheMinExpire 0
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

La directive CacheMinExpire permet de spécifier le nombre minimum de secondes pendant lequel les documents HTTP susceptibles d'être mis en cache seront conservés sans vérifier leur contenu sur le serveur d'origine. Elle n'est prise en compte que dans le cas où le document ne possède aucune date d'expiration valide.

CacheMinExpire 3600
top

Directive CacheQuickHandler

Description:Exécute le cache à partir d'un gestionnaire rapide.
Syntaxe:CacheQuickHandler on|off
Défaut:CacheQuickHandler on
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_cache
Compatibilité:Disponible à partir de la version 2.3.3 du serveur HTTP Apache

La directive CacheQuickHandler permet de contrôler la phase au cours de laquelle la mise en cache est effectuée.

Avec la configuration par défaut, le cache agit au cours de la phase du gestionnaire rapide. Cette phase court-circuite la majorité des traitements du serveur, et constitue le mode d'opération le plus performant pour un serveur typique. Le cache s'incruste devant le serveur, et la majorité des traitements du serveur est court-circuitée.

Lorsque cette directive est définie à off, le cache agit comme un gestionnaire normal, et est concerné par toutes les phases de traitement d'une requête. Bien que ce mode soit moins performant que le mode par défaut, il permet d'utiliser le cache dans les cas où un traitement complet de la requête est nécessaire, comme par exemple lorsque le contenu est soumis à autorisation.

# Exécute le cache comme un gestionnaire normal
CacheQuickHandler off

Lorsque le gestionnaire rapide est désactivé, l'administrateur a aussi la possibilité de choisir avec précision le point de la chaîne de filtrage où la mise en cache sera effectuée, en utilisant le filtre CACHE.

# Mise en cache du contenu avant l'intervention de mod_include et
     # mod_deflate
CacheQuickHandler off
AddOutputFilterByType CACHE;INCLUDES;DEFLATE text/html

Si le filtre CACHE est spécifié plusieurs fois, c'est la dernière instance qui sera prise en compte.

top

Directive CacheStaleOnError

Description:Sert du contenu non à jour à la place de réponses 5xx.
Syntaxe:CacheStaleOnError on|off
Défaut:CacheStaleOnError on
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache
Compatibilité:Disponible depuis la version 2.3.9 d'Apache

Lorsque la directive CacheStaleOnError est définie à on, et si des données non mises à jour sont disponibles dans le cache, ce dernier renverra ces données, plutôt qu'une éventuelle réponse 5xx en provenance du serveur d'arrière-plan. Alors que l'en-tête Cache-Control envoyé par les clients sera respecté, et que les clients recevront donc dans ce cas la réponse 5xx brute à leur requête, cette réponse 5xx renvoyée au client n'invalidera pas le contenu dans le cache.

# Sert des données non mises à jour en cas d'erreur.
CacheStaleOnError on
top

Directive CacheStoreExpired

Description:Tente de mettre en cache les réponses que le serveur considère comme arrivées à expiration
Syntaxe:CacheStoreExpired On|Off
Défaut:CacheStoreExpired Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

Depuis la version 2.2.4, les réponses qui sont arrivées à expiration ne sont pas stockées dans le cache. La directive CacheStoreExpired permet de modifier ce comportement. Avec CacheStoreExpired On, le serveur tente de mettre en cache la ressource si elle est périmée. Les requêtes suivantes vont déclencher une requête si-modifié-depuis de la part du serveur d'origine, et la réponse sera renvoyée à partir du cache si la ressource d'arrière-plan n'a pas été modifiée.

CacheStoreExpired On
top

Directive CacheStoreNoStore

Description:Tente de mettre en cache les requêtes ou réponses dont l'entête Cache-Control: a pour valeur no-store.
Syntaxe:CacheStoreNoStore On|Off
Défaut:CacheStoreNoStore Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

Normalement, les requêtes ou réponses dont l'en-tête Cache-Control: no-store ne sont pas stockées dans le cache. La directive CacheStoreNoStore permet de modifier ce comportement. Si CacheStoreNoStore est définie à On, le serveur tente de mettre la ressource en cache même si elle contient des en-têtes ayant pour valeur no-store. Les ressources nécessitant une autorisation ne sont jamais mises en cache.

CacheStoreNoStore On

Avertissement :

Selon la RFC 2616, la valeur d'en-tête no-store est censée "prévenir la suppression ou la rétention par inadvertance d'informations sensibles (par exemple, sur des bandes de sauvegarde)". Autrement dit, l'activation de la directive CacheStoreNoCache pourrait provoquer le stockage d'informations sensibles dans le cache. Vous avez donc été prévenus.

Voir aussi

top

Directive CacheStorePrivate

Description:Tente de mettre en cache des réponses que le serveur a marquées comme privées
Syntaxe:CacheStorePrivate On|Off
Défaut:CacheStorePrivate Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_cache

Normalement, les réponse comportant un en-tête Cache-Control: private ne seront pas stockées dans le cache. La directive CacheStorePrivate permet de modifier ce comportement. Si CacheStorePrivate est définie à On, le serveur tentera de mettre la ressource en cache, même si elle contient des en-têtes ayant pour valeur private. Les ressources nécessitant une autorisation ne sont jamais mises en cache.

CacheStorePrivate On

Avertissement :

Cette directive autorise la mise en cache même si le serveur indique que la ressource ne doit pas être mise en cache. Elle n'est de ce fait appropriée que dans le cas d'un cache 'privé'.

Voir aussi

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cern_meta.html.fr.utf80000664000175100017510000002707714740503670022606 0ustar covenercovener mod_cern_meta - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_cern_meta

Langues Disponibles:  en  |  fr  |  ko 

Description:La sémantique des métafichiers du serveur httpd du CERN
Statut:Extension
Identificateur de Module:cern_meta_module
Fichier Source:mod_cern_meta.c

Sommaire

Il s'agit d'une émulation de la sémantique des métafichiers du serveur httpd du CERN. Les métafichiers consistent en en-têtes HTTP qui peuvent s'ajouter au jeu d'en-têtes habituels pour chaque fichier accédé. Ils ressemblent beaucoup aux fichiers .asis d'Apache, et permettent d'influencer de manière rudimentaire l'en-tête Expires:, ainsi que d'autres curiosités. Il existe de nombreuses méthodes pour gérer les métainformations, mais le choix s'est porté sur celle-ci car il existe déjà un grand nombre d'utilisateurs du CERN qui peuvent exploiter ce module.

Pour plus d'information, voir le document sur la sémantique des métafichiers du CERN.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive MetaDir

Description:Le nom du répertoire où trouver les fichiers de métainformations dans le style du CERN
Syntaxe:MetaDir répertoire
Défaut:MetaDir .web
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Extension
Module:mod_cern_meta

Spécifie le nom du répertoire dans lequel Apache pourra trouver les fichiers de métainformations. Ce répertoire est en général un sous-répertoire 'caché' du répertoire qui contient le fichier à accéder. Définissez cette directive à "." pour rechercher les métafichiers dans le même répertoire que le fichier à accéder :

MetaDir .

Ou, pour rechercher dans un sous-répertoire du répertoire contenant le fichier à accéder :

MetaDir .meta
top

Directive MetaFiles

Description:Active le traitement des métafichiers du CERN
Syntaxe:MetaFiles on|off
Défaut:MetaFiles off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Extension
Module:mod_cern_meta

Active ou désactive le traitement des métafichiers pour certains répertoires.

top

Directive MetaSuffix

Description:Suffixe du fichier contenant les métainformations dans le style du CERN
Syntaxe:MetaSuffix suffixe
Défaut:MetaSuffix .meta
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Indexes
Statut:Extension
Module:mod_cern_meta

Spécifie le suffixe du fichier contenant les métainformations. Par exemple, si on conserve les valeurs par défaut des deux directives précédentes, une requête pour DOCUMENT_ROOT/un-rep/index.html provoquera la recherche du métafichier DOCUMENT_ROOT/un-rep/.web/index.html.meta, et utilisera son contenu pour générer les informations quant aux en-têtes MIME additionnels.

Exemple :

MetaSuffix .meta

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_charset_lite.html.fr.utf80000664000175100017510000004105414740503670023306 0ustar covenercovener mod_charset_lite - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_charset_lite

Langues Disponibles:  en  |  fr  |  ko 

Description:Spécifie dans quel jeu de caractère doivent s'effectuer les traductions ou les réencodages
Statut:Extension
Identificateur de Module:charset_lite_module
Fichier Source:mod_charset_lite.c

Sommaire

Le module mod_charset_lite permet au serveur de modifier le jeu de caractères des réponses avant de les envoyer aux clients. Dans un environnement EBCDIC, Apache traduit toujours les contenus au protocole HTTP (par exemples les en-têtes de réponses) de la page de code de la locale du processus Apache vers ISO-8859-1, mais pas le corps des réponses. Dans tous les environnements, on peut utiliser mod_charset_lite pour spécifier que les corps des réponses doivent être traduits. Par exemple, si les fichiers sont stockés sous forme EBCDIC, mod_charset_lite pourra les traduire en ISO-8859-1 avant de les envoyer au client.

Ce module fournit quelques procédés de configuration implémentés par Apache version russe, ainsi que son module mod_charset associé.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Problèmes courants

Noms de jeux de caractères non valides

Les noms des jeux de caractères passés en paramètres aux directives CharsetSourceEnc et CharsetDefault doivent être reconnus par le mécanisme de traduction utilisé par APR sur le système où mod_charset_lite est utilisé. Ces noms de jeux de caractères ne sont pas standardisés, et sont en général différents des valeurs qui leur correspondent dans les en-têtes HTTP. Actuellement, APR ne peut utiliser que iconv(3) ; vous pouvez donc tester facilement vos noms de jeux de caractères en utilisant le programme iconv(1), de la manière suivante :

iconv -f valeur-charsetsourceenc -t valeur-charsetdefault

Incompatibilité entre le jeu de caractères du contenu et les règles de traduction

Si les règles de traduction ne peuvent s'appliquer au contenu, la traduction peut échouer avec des conséquences diverses, comme :

top

Directive CharsetDefault

Description:Jeu de caractère vers lequel la traduction doit s'effectuer
Syntaxe:CharsetDefault jeu de caractères
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_charset_lite

La directive CharsetDefault permet de spécifier le jeu de caractères vers lequel le contenu situé dans le conteneur associé devra être traduit.

La valeur de l'argument jeu de caractères doit être un nom de jeu de caractères valide du point de vue du support des jeux de caractères dans APR. En général, cela implique qu'elle doit être reconnue par iconv.

Exemple

<Directory "/export/home/trawick/apacheinst/htdocs/convert">
    CharsetSourceEnc  UTF-16BE
    CharsetDefault    ISO-8859-1
</Directory>
Spécifier le même jeu de caractères pour les deux directives CharsetSourceEnc et CharsetDefault désactive la traduction. Le jeu de caractères ne doit pas forcément correspondre au jeu de caractères de la réponse, mais il doit être valide du point de vue du système.
top

Directive CharsetOptions

Description:Précise les détails de la traduction du jeu de caractères
Syntaxe:CharsetOptions option [option] ...
Défaut:CharsetOptions ImplicitAdd
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_charset_lite

La directive CharsetOptions permet de préciser certains détails du comportement du module mod_charset_lite. Option accepte les valeurs suivantes :

ImplicitAdd | NoImplicitAdd
Le mot-clé ImplicitAdd indique que mod_charset_lite doit insérer son filtre de manière implicite lorsque la configuration indique que le jeu de caractère du contenu doit être traduit. Si la chaîne de filtrage est configurée de manière explicite via la directive AddOutputFilter, l'option NoImplicitAdd doit être utilisée afin que mod_charset_lite n'ajoute pas son propre filtre.
TranslateAllMimeTypes | NoTranslateAllMimeTypes
Normalement, mod_charset_lite n'effectuera une traduction qu'en présence d'un petit nombre de types MIME parmi tous les types possibles. Lorsque l'option TranslateAllMimeTypes est utilisée pour une section de configuration donnée, la traduction est effectuée sans se préoccuper du type MIME.
top

Directive CharsetSourceEnc

Description:Jeu de caractères source des fichiers
Syntaxe:CharsetSourceEnc jeu de caractères
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_charset_lite

La directive CharsetSourceEnc permet de spécifier un jeu de caractères source pour les fichiers situés dans le conteneur associé.

La valeur de l'argument jeu de caractères doit être un nom de jeu de caractères valide du point de vue du support des jeux de caractères dans APR. En général, cela implique qu'elle doit être reconnue par iconv.

Exemple

<Directory "/export/home/trawick/apacheinst/htdocs/convert">
    CharsetSourceEnc  UTF-16BE
    CharsetDefault    ISO-8859-1
</Directory>

Les noms de jeux de caractères de cet exemple sont reconnus par le mécanisme de traduction d'iconv sous Solaris 8.

Spécifier le même jeu de caractères pour les deux directives CharsetSourceEnc et CharsetDefault désactive la traduction. Le jeu de caractères ne doit pas forcément correspondre au jeu de caractères de la réponse, mais il doit être valide du point de vue du système.

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav_fs.html.fr.utf80000664000175100017510000002663314740503670022110 0ustar covenercovener mod_dav_fs - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_dav_fs

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Implémente le fournisseur filesystem pour mod_dav
Statut:Extension
Identificateur de Module:dav_fs_module
Fichier Source:mod_dav_fs.c

Sommaire

L'activation de ce module nécessite l'utilisation de mod_dav. C'est un module de support pour mod_dav et à ce titre, il permet l'accès à des ressources situées dans le système de fichiers du serveur. Le nom formel de ce fournisseur est filesystem. Les fournisseurs supports de mod_dav sont invoqués via la directive Dav :

Exemple

Dav filesystem

Comme filesystem est le fournisseur par défaut de mod_dav, vous pouvez vous contenter d'utiliser la valeur On comme argument de Dav.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive DavLockDB

Description:Chemin de la base de données des verrous DAV
Syntaxe:DavLockDB chemin fichier
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_dav_fs

La directive DavLockDB permet de spécifier le chemin complet de la base de données des verrous, sans extension. Si le chemin n'est pas absolu, il sera considéré comme relatif au répertoire défini par la directive ServerRoot. L'implémentation de mod_dav_fs utilise une base de données SDBM pour surveiller les verrous utilisateurs.

Exemple

DavLockDB "var/DavLock"

Les utilisateur et groupe sous lesquels Apache s'exécute et qui sont respectivement définis par les directives User et Group doivent pouvoir écrire dans le répertoire qui contient le fichier de la base de données des verrous. Pour des raisons de sécurité, il est recommandé de créer un répertoire dédié à la base de données des verrous, plutôt que de modifier les permissions d'un répertoire existant. Dans l'exemple ci-dessus, Apache va créer des fichiers dans le répertoire var/, lui-même sous-répertoire du répertoire défini par la directive ServerRoot, avec le nom de base DavLock suivi d'une extension choisie par le serveur.

top

Directive DavLockDiscovery

Description:Active la découverte des verrous
Syntaxe:DavLockDiscovery on|off
Défaut:DavLockDiscovery on
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_dav_fs
Compatibilité:Disponible à partir de la version 2.4.55 du serveur HTTP Apache.

DavLockDiscovery contrôle la découverte des verrous par la méthode PROPFIND. Lorsqu'elle est désactivée, PROPFIND renvoie toujours une section lockdiscovery vide. Ce réglage améliore les performances dans le cas où des clients utilisent beaucoup PROPFIND.

Example

DavLockDiscovery off

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_deflate.html.fr.utf80000664000175100017510000010146014740503670022242 0ustar covenercovener mod_deflate - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_deflate

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Comprime le contenu avant de le servir au client
Statut:Extension
Identificateur de Module:deflate_module
Fichier Source:mod_deflate.c

Sommaire

Le module mod_deflate implémente le filtre de sortie DEFLATE qui permet de comprimer la sortie de votre serveur avant de l'envoyer au client sur le réseau.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Codages supportés

Le seul codage supporté est gzip afin d'assurer une complète compatibilité avec les anciens navigateurs. Le codage deflate n'est donc pas supporté ; voir à ce sujet la documentation de zlib pour une explication détaillée.

top

Exemples de configurations

Compression et TLS

Certaines applications web sont vulnérables aux attaques visant le vol d'information lorsqu'une connexion TLS transmet des données compressées par deflate. Pour plus de détails, étudiez les attaques de la famille "BREACH".

Voici une configuration simple qui comprime les contenus à base de texte courants.

Ne comprime que certains types de documents

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
top

Activation de la compression

Compression et TLS

Certaines applications web sont vulnérables aux attaques pour vol d'information lorsque la connexion TLS transmet des données compressées par deflate. Pour plus d'informations, voir en détails la famille d'attaques de type "BREACH".

Compression de la sortie

La compression est implémentée par le filtre DEFLATE. La directive suivante active la compression des documents dans le conteneur où elle est placée :

SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI "\.(?:gif|jpe?g|png)$" no-gzip

Si vous voulez limiter la compression à certains types MIME particuliers, vous pouvez utiliser la directive AddOutputFilterByType. Voici un exemple où la compression n'est activée que pour les fichiers html de la documentation d'Apache :

<Directory "/your-server-root/manual">
    AddOutputFilterByType DEFLATE text/html
</Directory>

Note

Le filtre DEFLATE est toujours inséré après les filtres RESOURCE comme PHP ou SSI. Il n'affecte jamais les sous-requêtes internes.

Note

La variable d'environnement force-gzip, définie à l'aide de la directive SetEnv, permet d'ignorer la configuration de votre navigateur quant aux codages acceptés, et d'envoyer sans condition une sortie comprimée.

Décompression de la sortie

Le module mod_deflate fournit aussi un filtre permettant de décomprimer un corps de réponse comprimé par gzip. Pour activer cette fonctionnalité, vous devez insérer le filtre INFLATE dans la chaîne de filtrage en sortie via la directive SetOutputFilter ou AddOutputFilter, comme dans l'exemple suivant :

<Location "/dav-area">
    ProxyPass "http://example.com/"
    SetOutputFilter INFLATE
</Location>

Dans cet exemple, les sorties comprimées par gzip en provenance de example.com seront décomprimées afin de pouvoir être éventuellement traitées par d'autres filtres.

Décompression de l'entrée

Le module mod_deflate fournit également un filtre permettant de décomprimer un corps de requête comprimé par gzip. Pour activer cette fonctionnalité, vous devez insérer le filtre DEFLATE dans la chaîne de filtrage en entrée via la directive SetInputFilter ou AddInputFilter, comme dans l'exemple suivant :

<Location "/dav-area">
    SetInputFilter DEFLATE
</Location>

Désormais, si une requête contient un en-tête Content-Encoding: gzip, son corps sera automatiquement décomprimé. Peu de navigateurs sont actuellement en mesure de comprimer les corps de requêtes. Cependant, certaines applications spécialisées supportent les requêtes comprimées, comme par exemple certains clients WebDAV.

Note à propos de l'en-tête Content-Length

Si vous évaluez vous-même la taille du corps de requête, ne faites pas confiance à l'en-tête Content-Length! L'en-tête Content-Length indique la longueur des données en provenance du client, et non la quantité d'octets que représente le flux de données décompressé.

top

Prise en compte des serveurs mandataires

Le module mod_deflate envoie un en-tête de réponse HTTP Vary: Accept-Encoding pour avertir les mandataires qu'une réponse enregistrée dans le cache ne doit être envoyée qu'aux clients qui ont envoyé l'en-tête de requête Accept-Encoding approprié. Ceci permet d'éviter l'envoi d'un contenu comprimé à un client qui ne sera pas en mesure de l'interpréter.

Si vous avez défini des exclusions spécifiques dépendant, par exemple, de l'en-tête User-Agent, vous devez ajouter manuellement des données à l'en-tête Vary afin d'informer les mandataires des restrictions supplémentaires. Par exemple, dans la configuration classique où l'addition du filtre DEFLATE dépend du contenu de l'en-tête User-Agent, vous devez spécifier :

Header append Vary User-Agent

Si votre décision de comprimer le contenu dépend d'autres informations que celles contenues dans les en-têtes de la requête (par exemple la version HTTP), vous devez attribuer à l'en-tête Vary la valeur *, ce qui permet d'empêcher les mandataires compatibles de tout mettre en cache.

Exemple

Header set Vary *
top

Servir du contenu précompressé

Comme mod_deflate recompresse le contenu demandé à chaque requête, il est possible de gagner en performances en précompressant ce contenu, et en forçant mod_deflate à servir ce contenu précompressé sans avoir à le recompresser à chaque requête. Pour ce faire, utilisez une configuration du style :

<IfModule mod_headers.c>
    # Servir des fichiers CSS et JS compressés avec gzip, s'ils existent, et
    # si le client accepte gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.(css|js)"         "$1\.$2\.gz" [QSA]

    # Servir des types de contenus corrects, et empêcher mod_deflate
    # d'effectuer un double gzip.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
    RewriteRule "\.js\.gz$"  "-" [T=text/javascript,E=no-gzip:1]


    <FilesMatch "(\.js\.gz|\.css\.gz)$">
      # Servir le type de codage correct.
      Header append Content-Encoding gzip

      # Force les mandataires à mettre en cache séparément les fichiers
      # css/js gzippés & non gzippés.
      Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>
top

Directive DeflateAlterETag

Description:Comment l'en-tête sortant ETag doit être modifié au cours de la compression
Syntaxe:DeflateAlterETag AddSuffix|NoChange|Remove
Défaut:DeflateAlterETag AddSuffix
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_deflate
Compatibilité:Disponible à partir de la version 2.4.58 du serveur HTTP Apache

La directive DeflateAlterETag permet de spécifier comment l'en-tête ETag doit être modifié lorsqu'une réponse est compressée.

AddSuffix

Ajoute la méthode de compression à la fin de l'en-tête, ce qui a pour effet d'attribuer un en-tête ETag unique aux représentations compressées et non compressées. C'est l'option par défaut depuis la version 2.4.0, mais empêche de servir des codes d'état "HTTP Not Modified" (304) en réponse aux requêtes pour un contenu compressé.

NoChange

Ne modifie pas l'en-tête ETag dans une réponse compressée. C'était l'option par défaut avant la version 2.4.0, mais cela ne respectait pas la préconisation HTTP/1.1 selon laquelle chaque représentation de la même ressource doit posséder un en-tête ETag unique.

Remove

Supprime l'en-tête ETag dans les réponses compressées, ce qui a pour effet de rendre impossibles certaines requêtes conditionnelles, mais permet d'éviter les inconvénients des options précédentes.

top

Directive DeflateBufferSize

Description:Taille du fragment que zlib devra comprimer en une seule fois
Syntaxe:DeflateBufferSize valeur
Défaut:DeflateBufferSize 8096
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_deflate

La directive DeflateBufferSize permet de spécifier la taille en octets du fragment que zlib devra comprimer en une seule fois. Si la taille de la réponse compressée est supérieure à celle spécifiée par cette directive, httpd passera à un mode d'encodage fragmenté (l'en-tête HTTP Transfer-Encoding prend la valeur Chunked), ceci ayant comme effet de bord de ne définir aucun en-tête HTTP Content-Length. Il est important de connaître ce comportement, particulièrement lorsque httpd travaille derrière des mandataires inverses avec mise en cache, ou lorsque httpd est configuré pour utiliser mod_cache et mod_cache_disk car les réponses HTTP sans en-tête Content-Length peuvent ne pas être mises en cache.

top

Directive DeflateCompressionLevel

Description:Le niveau de compression que nous appliquons à la sortie
Syntaxe:DeflateCompressionLevel valeur
Défaut:La valeur par défaut de zlib
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_deflate

La directive DeflateCompressionLevel permet de spécifier le niveau de compression à utiliser ; plus grande est la valeur, meilleure sera la compression, mais plus grand sera aussi le temps CPU nécessaire pour effectuer le traitement.

La valeur doit être comprise entre 1 (compression minimale) et 9 (compression maximale).

top

Directive DeflateFilterNote

Description:Enregistre le taux de compression sous la forme d'une note à des fins de journalisation
Syntaxe:DeflateFilterNote [type] nom de la note
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_deflate

La directive DeflateFilterNote permet de spécifier qu'une note à propos du taux de compression doit être attachée à la requête. Le nom de la note est passé sous la forme d'un argument de la directive. Vous pouvez utiliser cette note à des fins statistiques en enregistrant sa valeur dans votre journal des accès.

Exemple

      DeflateFilterNote ratio
    
      LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
      CustomLog "logs/deflate_log" deflate

Pour extraire des informations plus précises de vos journaux, vous pouvez utiliser l'argument type pour spécifier le type de données de la note enregistrée dans le journal. type peut prendre une des valeurs suivantes :

Input
Enregistre dans la note la taille en octets du flux en entrée du filtre.
Output
Enregistre dans la note la taille en octets du flux en sortie du filtre.
Ratio
Enregistre le taux de compression (sortie/entrée * 100) dans la note. Il s'agit de la valeur par défaut si l'argument type est omis.

Vous pouvez donc configurer votre journalisation de la manière suivante :

Journalisation détaillée

DeflateFilterNote Input instream
DeflateFilterNote Output outstream
DeflateFilterNote Ratio ratio

LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
CustomLog "logs/deflate_log" deflate

Voir aussi

top

Directive DeflateInflateLimitRequestBody

Description:Taille maximale des corps de requête décompressés
Syntaxe:DeflateInflateLimitRequestBody value
Défaut:Aucune limite, mais LimitRequestBody s'applique après la compression
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_deflate
Compatibilité:Disponible à partir de la version 2.4.10 du serveur HTTP Apache

La directive DeflateInflateLimitRequestBody permet de spécifier la taille maximale d'un corps de requête décompressé. Si elle n'est pas définie, c'est la valeur de la directive LimitRequestBody qui s'applique au corps de requête décompressé.

top

Directive DeflateInflateRatioBurst

Description:Nombre maximal de fois que le ratio de décompression d'un corps de requête peut être dépassé
Syntaxe:DeflateInflateRatioBurst value
Défaut:DeflateInflateRatioBurst 3
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_deflate
Compatibilité:Disponible à partir de la version 2.4.10 du serveur HTTP Apache

La directive DeflateInflateRatioBurst permet de spécifier le nombre maximal de fois que la valeur de la directive DeflateInflateRatioLimit peut être dépassé avant l'arrêt du traitement de la requête.

top

Directive DeflateInflateRatioLimit

Description:Ratio de décompression maximum pour les corps de requêtes
Syntaxe:DeflateInflateRatioLimit value
Défaut:DeflateInflateRatioLimit 200
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_deflate
Compatibilité:Disponible à partir de la version 2.4.10 du serveur HTTP Apache

La directive DeflateInflateRatioLimit permet de définir le ratio maximum entre la taille d'un corps de requête compressé et sa taille décompressée. Ce ratio est vérifié au fur et à mesure de l'arrivée du corps de requête, et s'il est dépassé plus de DeflateInflateRatioBurst fois, le traitement de la requête est interrompu.

top

Directive DeflateMemLevel

Description:La quantité de mémoire utilisable par zlib pour la compression
Syntaxe:DeflateMemLevel valeur
Défaut:DeflateMemLevel 9
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_deflate

La directive DeflateMemLevel permet de spécifier la quantité de mémoire utilisable par zlib pour la compression (une valeur comprise entre 1 et 9).

top

Directive DeflateWindowSize

Description:Taille de la fenêtre de compression zlib
Syntaxe:DeflateWindowSize valeur
Défaut:DeflateWindowSize 15
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_deflate

La directive DeflateWindowSize permet de spécifier la fenêtre de compression zlib (une valeur comprise entre 1 et 15). En général, plus grande sera la taille de la fenêtre, plus grand sera le taux de compression auquel on pourra s'attendre.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dumpio.html.fr.utf80000664000175100017510000002377014740503670022142 0ustar covenercovener mod_dumpio - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_dumpio

Langues Disponibles:  en  |  fr  |  ja 

Description:Enregistre toutes les entrées/sorties dans le journal des erreurs de la manière souhaitée.
Statut:Extension
Identificateur de Module:dumpio_module
Fichier Source:mod_dumpio.c

Sommaire

mod_dumpio permet d'enregistrer toutes les entrées reçues par Apache et/ou toutes les sorties envoyées par ce dernier dans le fichier error.log.

L'enregistrement des données s'effectue juste après le décodage SSL (pour les entrées), et juste avant le codage SSL (pour les sorties). Comme on peut s'y attendre, tout ceci peut représenter un volume important de données, et ne doit être utilisé qu'à des fins de débogage.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Activation du support dumpio

Pour activer le module, ce dernier doit être compilé et chargé par l'intermédiaire de la configuration de votre instance d'Apache. La journalisation peut ensuite être activée ou désactivée séparément pour les entrées et sorties à l'aide des directives ci-dessous. En outre, mod_dumpio doit être configuré à LogLevel trace7 :

LogLevel dumpio:trace7
top

Directive DumpIOInput

Description:Enregistre toutes les entrées dans le journal des erreurs
Syntaxe:DumpIOInput On|Off
Défaut:DumpIOInput Off
Contexte:configuration globale
Statut:Extension
Module:mod_dumpio
Compatibilité:DumpIOInput est disponible depuis la version 2.1.3 d'Apache.

Active la journalisation de toutes les entrées.

Exemple

DumpIOInput On
top

Directive DumpIOOutput

Description:Enregistre toutes les sorties dans le journal des erreurs
Syntaxe:DumpIOOutput On|Off
Défaut:DumpIOOutput Off
Contexte:configuration globale
Statut:Extension
Module:mod_dumpio
Compatibilité:DumpIOOutput est disponible depuis la version 2.1.3 d'Apache.

Active la journalisation de toutes les sorties.

Exemple

DumpIOOutput On

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_file_cache.html.fr.utf80000664000175100017510000004321414740503670022702 0ustar covenercovener mod_file_cache - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_file_cache

Langues Disponibles:  en  |  fr  |  ko 

Description:Mise en cache mémoire d'une liste statique de fichiers
Statut:Expérimental
Identificateur de Module:file_cache_module
Fichier Source:mod_file_cache.c

Sommaire

Ce module doit être utilisé avec précautions. Il est recommandé de lire attentivement ce document, car l'utilisation de mod_file_cache peut facilement conduire à la création d'un site inopérant.

La mise en cache de fichiers souvent demandés mais rarement modifiés est une technique permettant de réduire la charge du serveur. mod_file_cache met en oeuvre deux techniques de mise en cache de fichiers statiques fréquemment demandés. Des directives de configuration vous permettent d'indiquer à mod_file_cache soit d'ouvrir et de charger une image en mémoire d'un fichier avec mmap(), soit de préouvrir un fichier et de maintenir en service le gestionnaire du fichier. Les deux techniques permettent de réduire la charge du serveur lors du traitement des requêtes concernant ces fichiers, en accomplissant une partie du travail nécessaire à la mise à disposition de ces fichiers (en particulier les opérations d'entrées/sorties sur les fichiers) au démarrage du serveur, plutôt qu'au cours de chaque requête.

Note : ces techniques sont inutilisables pour accélérer des programmes CGI ou d'autres fichiers servis par des gestionnaires de contenu spéciaux. Elles ne peuvent être utilisées que pour des fichiers standards, normalement servis par le gestionnaire de contenu de base d'Apache.

Ce module est une extension du module d'Apache 1.3 mod_mmap_staticet s'en inspire fortement .

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Utilisation de mod_file_cache

mod_file_cache gère la mise en cache d'une liste de fichiers définie de manière statique via une des directives MMapFile ou CacheFile au niveau de la configuration du serveur principal.

Les deux directives ne sont pas supportées par toutes les plates-formes. Par exemple, Apache pour Windows ne supporte pas actuellement la directive MMapFile, alors que d'autres plates-formes, comme AIX, supportent les deux. Vous recevrez un message d'erreur dans le journal des erreurs du serveur si vous essayez d'utiliser une directive non supportée. Si vous utilisez une directive non supportée, le serveur démarrera, mais les fichiers ne seront pas mis en cache. Sur les plates-formes qui supportent les deux directives, vous devez faire des essais afin de déterminer quelle directive vous convient le mieux.

Directive MMapFile

La directive MMapFile du module mod_file_cache permet de transférer en mémoire une liste statique de fichiers à l'aide de l'appel système mmap(). Cet appel système est disponible sur la plupart des plates-formes de style Unix, mais pas sur toutes. Il existe parfois des limites spécifiques au système quant à la taille et au nombre de fichiers qui peuvent être mmap()és, et l'expérimentation est probablement la méthode la plus simple pour déterminer ces limites.

Ce mmap()age n'est effectué qu'une seul fois au démarrage ou redémarrage du serveur. Ainsi, chaque fois qu'un des fichiers chargés en mémoire est modifié au niveau du système de fichiers, vous devez redémarrer le serveur (voir la documentation sur l'Arrêt et redémarrage). Pour bien insister sur ce point, si des fichiers sont modifiés sur disque, et si vous ne redémarrez pas le serveur, vous allez finir par servir des contenus complètement obsolètes. Vous devez mettre à jour les fichiers en renommant l'ancienne version et en enregistrant la nouvelle sur disque. Pour y parvenir, on peut utiliser des outils comme rdist et mv. La raison pour laquelle ce module ne prend pas en compte les modifications de fichiers réside dans le fait que cette vérification nécessiterait un appel à stat() à chaque accès, et en fin de compte, l'augmentation de la consommation de ressources finirait par aller contre le but initial de réduire les entrées/sorties.

Directive CacheFile

La directive CacheFile du module mod_file_cache permet d'associer un gestionnaire ou descripteur de fichier à chaque fichier énuméré dans la directive de configuration et place ces gestionnaires de fichiers ouverts dans le cache. Lorsqu'un des fichier est demandé, le serveur sélectionne son gestionnaire dans le cache et le transmet à l'API sendfile() (ou TransmitFile() sous Windows).

Cette mise en cache des gestionnaire n'est effectuée qu'une seule fois au démarrage ou redémarrage du système. Ainsi, chaque fois qu'un des fichiers chargés en mémoire est modifié au niveau du système de fichiers, vous devez redémarrer le serveur (voir la documentation sur l'Arrêt et redémarrage). Pour bien insister sur ce point, si des fichiers sont modifiés sur disque, et si vous ne redémarrez pas le serveur, vous allez finir par servir des contenus complètement obsolètes. Vous devez mettre à jour les fichiers en renommant l'ancienne version et en enregistrant la nouvelle sur disque. Pour y parvenir, on peut utiliser des outils comme rdist et mv.

Note

Ne cherchez pas à trouver de directive qui met tous les fichiers d'un répertoire en cache, de manière récursive. Pour y parvenir, vous pouvez vous reporter à la directive Include directive, et considérer cette commande :

find /www/htdocs -type f -print \
| sed -e 's/.*/mmapfile &/' > /www/conf/mmap.conf

top

Directive CacheFile

Description:Met en cache une liste de gestionnaires de fichiers au démarrage
Syntaxe:CacheFile chemin fichier [chemin fichier] ...
Contexte:configuration globale
Statut:Expérimental
Module:mod_file_cache

La directive CacheFile permet d'associer des gestionnaires à un ou plusieurs fichiers (séparés par des espaces), et de placer ceux-ci dans le cache au démarrage du serveur. Les gestionnaires des fichiers mis en cache sont automatiquement fermés à l'arrêt du serveur. Lorsqu'un ou plusieurs fichiers ont été modifiés sur disque, le serveur doit être redémarré afin que les modifications soient prises en compte par le cache.

Soyez prudent avec les arguments chemin fichier : ils doivent correspondre exactement au chemin du système de fichier que créent les gestionnaires de traduction URL-vers-nom-fichier d'Apache. On ne peut pas comparer des inodes ou autres identifiants pour mettre en correspondance des chemins à l'aide de liens symboliques (etc...), car là encore, ceci nécessiterait un appel à stat() supplémentaire, ce qui n'est pas acceptable. Il n'est pas garanti que ce module fonctionne avec des noms de fichiers réécrits par mod_alias ou mod_rewrite.

Exemple

CacheFile /usr/local/apache/htdocs/index.html
top

Directive MMapFile

Description:Charge au démarrage une liste de fichiers en mémoire
Syntaxe:MMapFile chemin fichier [chemin fichier] ...
Contexte:configuration globale
Statut:Expérimental
Module:mod_file_cache

La directive MMapFile permet de charger un ou plusieurs fichiers (séparés par des espaces) en mémoire au démarrage du serveur. Ceux-ci sont automatiquement déchargés de la mémoire à l'arrêt du serveur. Lorsqu'un ou plusieurs fichiers ont été modifiés sur disque, on doit au minimum envoyer un signal HUP ou USR1 au serveur afin de les remmap()er.

Soyez prudent avec les arguments chemin fichier : ils doivent correspondre exactement au chemin du système de fichier que créent les gestionnaires de traduction URL-vers-nom-fichier d'Apache. On ne peut pas comparer des inodes ou autres identifiants pour mettre en correspondance des chemins à l'aide de liens symboliques (etc...), car là encore, ceci nécessiterait un appel à stat() supplémentaire, ce qui n'est pas acceptable. Il n'est pas garanti que ce module fonctionne avec des noms de fichiers réécrits par mod_alias ou mod_rewrite.

Exemple

MMapFile /usr/local/apache/htdocs/index.html

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_heartbeat.html.fr.utf80000664000175100017510000002346614740503670022606 0ustar covenercovener mod_heartbeat - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_heartbeat

Langues Disponibles:  en  |  fr 

Description:Envoie des messages d'état au mandataire frontal
Statut:Expérimental
Identificateur de Module:heartbeat_module
Fichier Source:mod_heartbeat
Compatibilité:Disponible à partir de la version 2.3 du serveur HTTP Apache

Sommaire

mod_heartbeat envoie à un moniteur mod_heartmonitor des messages multicast l'informant du nombre de connexions courantes. En général, mod_heartmonitor est chargé sur un serveur mandataire où mod_lbmethod_heartbeat est chargé, ce qui permet d'utiliser la lbmethod "heartbeat" au sein des directives ProxyPass.

Le module mod_heartbeat est chargé sur le serveur d'origine qui sert les requêtes via le serveur mandataire.

Pour utiliser mod_heartbeat, mod_status et mod_watchdog doivent être soit des modules statiques, soit des modules dynamiques, et dans ce dernier cas, ils doivent être chargés avant mod_heartbeat.
Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Utilisation de la sortie de mod_heartbeat

Chaque seconde, ce module génère un paquet multicast UDP contenant le nombre de threads/processus occupés et en attente. Le paquet possède un format ASCII simple similaire aux paramètres de requête GET en HTTP.

Exemple de paquet

v=1&ready=75&busy=0

Les utilisateurs disposeront dans le futur de nouvelles variables en plus de busy et ready, et toujours séparées par des '&'.

top

Directive HeartbeatAddress

Description:Adresse multicast à laquelle envoyer les requêtes heartbeat
Syntaxe:HeartbeatAddress addr:port
Défaut:disabled
Contexte:configuration globale
Statut:Expérimental
Module:mod_heartbeat

La directive HeartbeatAddress permet de spécifier l'adresse multicast à laquelle mod_heartbeat va envoyer ses informations. En général, cette adresse correspond à la valeur définie par la directive HeartbeatListen sur le serveur mandataire frontal.

HeartbeatAddress 239.0.0.1:27999

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_isapi.html.fr.utf80000664000175100017510000006275214740503670021755 0ustar covenercovener mod_isapi - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_isapi

Langues Disponibles:  en  |  fr  |  ko 

Description:Extensions ISAPI dans Apache pour Windows
Statut:Base
Identificateur de Module:isapi_module
Fichier Source:mod_isapi.c
Compatibilité:Win32 only

Sommaire

Ce module implémente l'API des extensions du Serveur Internet. Il permet à Apache pour Windows de servir les extensions du Serveur Internet (par exemple les modules .dll ISAPI), compte tenu des restrictions spécifiées.

Les modules d'extension ISAPI (fichiers .dll) sont des modules tiers. Leur auteur n'est pas le Groupe Apache, et nous n'assurons donc pas leur support. Veuillez contacter directement l'auteur d'ISAPI si vous rencontrez des problèmes à l'exécution d'une extension ISAPI. Merci de ne pas soumettre ce genre de problème dans les listes d'Apache ou dans les pages de rapports de bogues.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Utilisation

Dans le fichier de configuration du serveur, utilisez la directive AddHandler pour associer les fichiers ISAPI au gestionnaire isapi-handler à l'aide de l'extension de leur nom de fichier. Pour faire en sorte que tout fichier .dll soit traité en tant qu'extension ISAPI, éditez le fichier httpd.conf et ajoutez les lignes suivantes :

AddHandler isapi-handler .dll
Dans les versions plus anciennes du serveur Apache, le nom du gestionnaire était isapi-isa au lieu de isapi-handler. Depuis les versions de développement 2.3 du serveur Apache, isapi-isa n'est plus valide, et vous devrez éventuellement modifier votre configuration pour utiliser isapi-handler à la place.

Le serveur Apache ne propose aucun moyen de conserver en mémoire un module chargé. Vous pouvez cependant précharger et garder un module spécifique en mémoire en utilisant la syntaxe suivante dans votre httpd.conf :

ISAPICacheFile c:/WebWork/Scripts/ISAPI/mytest.dll

Que vous ayez ou non préchargé une extension ISAPI, ces dernières sont toutes soumises au mêmes restrictions et possèdent les mêmes permissions que les scripts CGI. En d'autres termes, Options ExecCGI doit être défini pour le répertoire qui contient le fichier .dll ISAPI.

Reportez-vous aux Notes additionnelles et au Journal du programmeur pour plus de détails et une clarification à propos du support spécifique ISAPI fourni par le module mod_isapi.

top

Notes additionnelles

L'implémentation ISAPI d'Apache se conforme à toutes les spécifications ISAPI 2.0, à l'exception de certaines extensions "spécifiques Microsoft" utilisant des entrées/sorties asynchrones. Le modèle des entrées/sorties d'Apache ne permet pas l'écriture et la lecture asynchrone de la manière dont ISAPI pourrait le faire. Si une extension tente d'utiliser des fonctionnalités non supportées, comme les entrées/sorties asynchrones, un message est enregistré dans le journal des erreurs afin d'aider au débogage. Comme ces messages peuvent devenir envahissants, la directive ISAPILogNotSupported Off permet de filter ce bruit de fond.

Si aucune option de configuration particulière n'est spécifiée, certains serveurs, comme Microsoft IIS, chargent l'extension ISAPI dans le serveur et la conservent en mémoire jusqu'à ce que l'utilisation de cette dernière devienne trop élevée. Apache, par contre, charge et décharge réellement l'extension ISAPI chaque fois qu'elle est invoquée, si la directive ISAPICacheFile n'a pas été spécifiée. Ce n'est pas très performant, mais le modèle de mémoire d'Apache fait que cette méthode est la plus efficace. De nombreux modules ISAPI présentent des incompatibilités subtiles avec le serveur Apache, et le déchargement de ces modules permet d'assurer la stabilité du serveur.

En outre, gardez à l'esprit que si Apache supporte les extensions ISAPI, il ne supporte pas les filtres ISAPI. Le support des filtres sera peut-être ajouté dans le futur, mais n'a pas encore été planifié.

top

Journal du programmeur

Si vous écrivez des modules mod_isapi Apache 2.0, vous devez limiter vos appels à ServerSupportFunction aux directives suivantes :

HSE_REQ_SEND_URL_REDIRECT_RESP
Redirige l'utilisateur vers une autre adresse.
Il doit s'agir d'une URL pleinement qualifiée (comme http://serveur/chemin).
HSE_REQ_SEND_URL
Redirige l'utilisateur vers une autre adresse.
Ce ne doit pas être une URL pleinement qualifiée ; la mention du protocole ou du nom du serveur n'est pas autorisée (par exemple, utilisez simplement /chemin).
La redirection n'est pas assurée par le navigateur mais par le serveur lui-même.

Avertissement

Dans sa documentation récente, Microsoft semble avoir abandonné la distinction entre les deux fonctions HSE_REQ_SEND_URL. Apache, quant à lui, continue de les traiter comme deux fonctions distinctes avec des contraintes et des comportements spécifiques.

HSE_REQ_SEND_RESPONSE_HEADER
Apache accepte un corps de réponse après l'en-tête s'il se situe après la ligne vide (deux caractères newline consécutifs) dans la chaîne des arguments d'en-têtes. Ce corps ne doit pas contenir de caractères NULL, car l'argument des en-têtes est lui-même terminé par un caractère NULL.
HSE_REQ_DONE_WITH_SESSION
Apache considère ceci comme sans objet, car la session est fermée lorsque l'extension ISAPI termine son traitement.
HSE_REQ_MAP_URL_TO_PATH
Apache va traduire un nom virtuel en nom physique.
HSE_APPEND_LOG_PARAMETER
Ce paramètre peut intervenir dans un de ces journaux :

La première option, le composant %{isapi-parameter}n, est préférable et toujours disponible.

HSE_REQ_IS_KEEP_CONN
retourne le statut négocié Keep-Alive.
HSE_REQ_SEND_RESPONSE_HEADER_EX
se comportera comme indiqué dans le documentation, bien que le drapeau fKeepConn soit ignoré.
HSE_REQ_IS_CONNECTED
renverra faux si la requête a été abandonnée.

Apache renvoie FALSE pour tout appel non supporté à ServerSupportFunction, et GetLastError renverra la valeur ERROR_INVALID_PARAMETER.

ReadClient extrait la partie du corps de la requête qui dépasse le tampon initial (défini par la directive ISAPIReadAheadBuffer). En fonction de la définition de la directive ISAPIReadAheadBuffer (nombre d'octets à mettre dans le tampon avant d'appeler le gestionnaire ISAPI), les requêtes courtes sont envoyées en entier à l'extension lorsque celle-ci est invoquée. Si la taille de la requête est trop importante, l'extension ISAPI doit faire appel à ReadClient pour extraire la totalité du corps de la requête.

WriteClient est supporté, mais seulement avec le drapeau HSE_IO_SYNC ou le drapeau "aucune option" (valeur 0). Toute autre requête WriteClient sera rejetée avec une valeur de retour FALSE, et GetLastError renverra la valeur ERROR_INVALID_PARAMETER

GetServerVariable est supporté, bien que les variables étendues de serveur n'existent pas (comme défini par d'autres serveurs). Toutes les variables d'environnement CGI usuelles d'Apache sont disponibles à partir de GetServerVariable, ainsi que les valeurs ALL_HTTP et ALL_RAW.

Depuis httpd 2.0, mod_isapi propose des fonctionnalités supplémentaires introduites dans les versions actualisées de la spécification ISAPI, ainsi qu'une émulation limitée des entrées/sorties asynchrones et la sémantique TransmitFile. Apache httpd supporte aussi le préchargement des .dlls ISAPI à des fins de performances.

top

Directive ISAPIAppendLogToErrors

Description:Enregistrement des requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans le journal des erreurs
Syntaxe:ISAPIAppendLogToErrors on|off
Défaut:ISAPIAppendLogToErrors off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_isapi

Cette directive permet d'enregistrer les requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans le journal des erreurs.

top

Directive ISAPIAppendLogToQuery

Description:Enregistre les requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans la partie arguments de la requête
Syntaxe:ISAPIAppendLogToQuery on|off
Défaut:ISAPIAppendLogToQuery on
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_isapi

Cette directive permet d'enregistrer les requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans la partie arguments de la requête (ajouté au composant %q de la directive CustomLog).

top

Directive ISAPICacheFile

Description:Fichiers .dll ISAPI devant être chargés au démarrage
Syntaxe:ISAPICacheFile chemin-fichier [chemin-fichier] ...
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_isapi

Cette directive permet de spécifier une liste, séparés par des espaces, de noms de fichiers devant être chargés au démarrage du serveur Apache, et rester en mémoire jusqu'à l'arrêt du serveur. Cette directive peut être répétée pour chaque fichier .dll ISAPI souhaité. Le chemin complet du fichier doit être spécifié. Si le chemin n'est pas absolu, il sera considéré comme relatif au répertoire défini par la directive ServerRoot.

top

Directive ISAPIFakeAsync

Description:Emulation du support des entrées/sorties asynchrones pour les appels ISAPI
Syntaxe:ISAPIFakeAsync on|off
Défaut:ISAPIFakeAsync off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_isapi

Lorsquelle est définie à "on", cette directive permet d'émuler le support des entrées/sorties asynchrones pour les appels ISAPI.

top

Directive ISAPILogNotSupported

Description:Journalisation des demandes de fonctionnalités non supportées de la part des extensions ISAPI
Syntaxe:ISAPILogNotSupported on|off
Défaut:ISAPILogNotSupported off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_isapi

Cette directive permet d'enregistrer dans le journal des erreurs toutes les demandes de fonctionnalités non supportées de la part des extensions ISAPI. Ceci peut aider les administrateurs à décortiquer certains problèmes. Lorsqu'elle a été définie à "on" et si tous les modules ISAPI fonctionnent, elle peut être redéfinie à "off".

top

Directive ISAPIReadAheadBuffer

Description:Taille du tampon de lecture anticipée envoyé aux extensions ISAPI
Syntaxe:ISAPIReadAheadBuffer taille
Défaut:ISAPIReadAheadBuffer 49152
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_isapi

Cette directive permet de définir la taille maximale du tampon de lecture anticipée envoyé aux extensions ISAPI lorsqu'elles sont initialement invoquées. Toute donnée restante doit être extraite en faisant appel à ReadClient ; certaines extensions ISAPI peuvent ne pas supporter la fonction ReadClient. Pour plus de détails, veuillez vous adresser à l'auteur de l'extension ISAPI.

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_bytraffic.html.fr.utf80000664000175100017510000002114314740503670024464 0ustar covenercovener mod_lbmethod_bytraffic - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_lbmethod_bytraffic

Langues Disponibles:  en  |  fr 

Description:Algorithme de planification avec répartition de charge en fonction d'un niveau de trafic pour le module mod_proxy_balancer
Statut:Extension
Identificateur de Module:lbmethod_bytraffic_module
Fichier Source:mod_lbmethod_bytraffic.c
Compatibilité:Dissocié de mod_proxy_balancer depuis la version 2.3

Sommaire

Ce module ne fournit pas lui-même de directive de configuration. Il nécessite les services de mod_proxy_balancer, et fournit la méthode de répartition de charge bytraffic.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Algorithme de répartition en fonction d'un certain trafic

Activé via lbmethod=bytraffic, l'idée directrice de ce planificateur est similaire à celle de la méthode reposant sur le nombre de requêtes, avec les différences suivantes :

lbfactor représente la quantité de trafic, en octets, que nous voulons voir traitée par le processus. Il s'agit là aussi d'une valeur normalisée représentant la part de travail à effectuer par le processus, mais au lieu de se baser sur un nombre de requêtes, on prend en compte la quantité de trafic que ce processus a traité.

Si un répartiteur est configuré comme suit :

worker a b c
lbfactor 1 2 1

Cela signifie que nous souhaitons que b traite 2 fois plus d'octets que a ou c. Cela n'entraîne pas nécessairement que b va traiter deux fois plus de requêtes, mais qu'il va traiter deux fois plus de trafic en termes d'entrées/sorties. A cet effet, les tailles de la requête et de sa réponse assocciée sont prises en compte par l'algorithme de sélection et d'évaluation du trafic.

Note : les octets en entrée sont évalués avec la même pondération que les octets en sortie.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_logio.html.fr.utf80000664000175100017510000002602314740503670021750 0ustar covenercovener mod_logio - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_logio

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Journalisation des octets en entrée et en sortie pour chaque requête
Statut:Extension
Identificateur de Module:logio_module
Fichier Source:mod_logio.c

Sommaire

Ce module permet d'enregistrer le nombre d'octets reçus et envoyés pour chaque requête. Ce nombre reflète le nombre réel d'octets transmis sur le réseau, et prend en compte les en-têtes et corps des requêtes et des réponses. Le décompte est effectué avant SSL/TLS en entrée et après SSL/TLS en sortie, si bien que le résultat reflètera toute modification introduite par le chiffrement.

Pour fonctionner, ce module requiert le chargement du module mod_log_config.

Lorsqu'on utilise les connexions persistantes avec SSL, le supplément de trafic induit par la négociation SSL est enregistré dans le décompte des octets transmis dans le cadre de la première requête de la connexion. Lors d'une renégociation SSL au niveau d'un répertoire, le décompte d'octets est associé à la requête qui a déclenché la renégociation.
Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Formats de journaux personnalisés

Ce module introduit trois nouvelles directives de journalisation. Les caractéristiques de la requête en elle-même sont journalisées en insérant des directives "%" dans la chaîne de format, qui seront remplacées comme suit dans le fichier journal :

Chaîne de Format Description
%I Octets reçus, en-têtes et corps de requête inclus ; ne peut pas être nul.
%O Octets envoyés, en-têtes inclus ; ne peut pas être nul.
%S Nombre d'octets transmis (en émission et réception), y compris corps et en-têtes de requête. Ce nombre ne peut pas être nul, et il correspond à la combinaison des formats %I et %O.
Disponible depuis la version 2.4.7 du serveur HTTP Apache.
%^FB Délai en microsecondes entre l'arrivée de la requête et l'écriture du premier octet des en-têtes de la réponse. Disponible uniquement si la directive LogIOTrackTTFB a été définie à ON.
Disponible à partir de la version 2.4.13 du serveur HTTP Apache

En général, cette fonctionnalité s'utilise comme suit :

Format de journal d'entrées/sorties combiné :
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %I %O"
top

Directive LogIOTrackTTFB

Description:Permet d'enregistrer le délai avant le premier octet (time to first byte - TTFB)
Syntaxe:LogIOTrackTTFB ON|OFF
Défaut:LogIOTrackTTFB OFF
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_logio
Compatibilité:Disponible à partir de la version 2.4.13 du serveur HTTP Apache

Cette directive permet de définir si ce module mesure le délai entre la lecture de la requête et l'écriture du premier octet des en-têtes de la réponse. La valeur obtenue peut être enregistrée dans le journal via le format %^FB.

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_macro.html.fr.utf80000664000175100017510000004015414740503670021741 0ustar covenercovener mod_macro - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_macro

Langues Disponibles:  en  |  fr 

Description:Ce module permet d'utiliser des macros dans les fichiers de configuration Apache.
Statut:Base
Identificateur de Module:macro_module
Fichier Source:mod_macro.c
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

Sommaire

Ce module permet d'utiliser des macros dans les fichiers de configuration à l'exécution du serveur HTTP Apache afin de faciliter la création de nombreux blocs de configuration similaires. Quand le serveur démarre, les macros sont exécutées avec les paramètres fournis, et le résultat obtenu est traité au même titre que le reste du fichier de configuration.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Utilisation

On définit une macro à l'aide des blocs <Macro> qui contiennent la portion de votre configuration qui intervient de manière répétitive, y compris les variables pour les parties qui devront être substituées.

Par exemple, vous pouvez utiliser une macro pour définir un bloc <VirtualHost>, afin de pouvoir définir de nombreux serveurs virtuels similaires :

<Macro VHost $name $domain>
<VirtualHost *:80>
    ServerName $domain
    ServerAlias www.$domain

    DocumentRoot "/var/www/vhosts/$name"
    ErrorLog "/var/log/httpd/$name.error_log"
    CustomLog "/var/log/httpd/$name.access_log" combined
</VirtualHost>
</Macro>

Comme les directives de configuration httpd, les noms des macros sont insensibles à la casse, à la différence des variables qui y sont, elles, sensibles.

Vous pouvez alors invoquer cette macro autant de fois que vous le voulez pour créer des serveurs virtuels

Use VHost example example.com
Use VHost myhost hostname.org
Use VHost apache apache.org

UndefMacro VHost

Au démarrage du serveur, chacune de ces invocations Use sera remplacée par une définition de serveur virtuel complète, comme décrit dans la définition de la <Macro>.

La directive UndefMacro permet d'éviter les conflits de définitions qui pourraient provenir de l'utilisation ultérieure de macros contenant les mêmes noms de variables.

Vous trouverez une version plus élaborée de cet exemple plus loin dans la section Exemples.

top

Conseils

Les noms de paramètres doivent commencer par un sigil tel que $, %, ou @, de façon à ce qu'ils soient clairement identifiables, mais aussi afin de faciliter les interactions avec les autres directives, comme la directive de base Define. Dans le cas contraire, vous recevrez un avertissement. En tout état de cause, il est conseillé d'avoir une bonne connaissance globale de la configuration du serveur, afin d'éviter la réutilisation des mêmes variables à différents niveaux, ce qui peut être à l'origine de confusions.

Les paramètres préfixés par $ ou % ne sont pas échappés. Les paramètres préfixés par @ sont échappés entre guillemets.

Evitez de préfixer un paramètre par le nom d'un autre paramètre (par exemple, présence simultanée des paramètres $win et $winter), car ceci peut introduire de la confusion lors de l'évaluation des expressions. Si cela se produit, c'est le nom de paramètre le plus long possible qui sera utilisé.

Si vous désirez insérer une valeur dans une chaîne, il est conseillé de l'entourer d'accolades afin d'éviter toute confusion :

<Macro DocRoot ${docroot}>
    DocumentRoot "/var/www/${docroot}/htdocs"
</Macro>
top

Exemples

Définition de serveurs virtuels

Un exemple typique d'utilisation de mod_macro est la création dynamique de serveurs virtuels.

## Définition d'une macro VHost pour les configurations répétitives

<Macro VHost $host $port $dir>
  Listen $port
  <VirtualHost *:$port>

    ServerName $host
    DocumentRoot "$dir"

    # Racine des documents publique
    <Directory "$dir">
      Require all granted
    </Directory>

    # restriction d'accès au sous-répertoire intranet.
    <Directory "$dir/intranet">
      Require ip 10.0.0.0/8
    </Directory>
  </VirtualHost>
</Macro>

## Utilisation de la macro VHost avec différents arguments.

Use VHost www.apache.org 80 /vhosts/apache/htdocs
Use VHost example.org 8080 /vhosts/example/htdocs
Use VHost www.example.fr 1234 /vhosts/example.fr/htdocs

Suppression d'une définition de macro

Il est recommandé de supprimer la définition d'une macro après l'avoir utilisée. Ceci permet d'éviter les confusions au sein d'un fichier de configuration complexe où des conflits entre noms de variables peuvent survenir.

<Macro DirGroup $dir $group>
  <Directory "$dir">
    Require group $group
  </Directory>
</Macro>

Use DirGroup /www/apache/private private
Use DirGroup /www/apache/server  admin

UndefMacro DirGroup
top

Directive <Macro>

Description:Définition d'une macro dans un fichier de configuration
Syntaxe: <Macro nom [par1 .. parN]> ... </Macro>
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_macro

La directive <Macro> permet de définir une macro dans un fichier de configuration Apache. Le premier argument est le nom de la macro, et les arguments suivants sont les paramètres. Il est de bon aloi de préfixer les noms des paramètres d'une macro avec un caractère parmi '$%@', et d'éviter d'en faire de même avec les noms de macros.

<Macro LocalAccessPolicy>
  Require ip 10.2.16.0/24
</Macro>

<Macro RestrictedAccessPolicy $ipnumbers>
   Require ip $ipnumbers
</Macro>
top

Directive UndefMacro

Description:Supprime une macro
Syntaxe:UndefMacro nom
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_macro

La directive UndefMacro annule la définition d'une macro qui doit avoir été définie auparavant.

UndefMacro LocalAccessPolicy
UndefMacro RestrictedAccessPolicy
top

Directive Use

Description:Utilisation d'une macro
Syntaxe:Use nom [valeur1 ... valeurN]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_macro

La directive Use permet d'utiliser une macro. La macro considérée est expansée. Son nombre d'arguments doit être égal au nombre de paramètres précisés dans sa définition. Les valeurs passées en argument sont attribuées aux paramètres correspondants et substituées avant l'interprétation du texte de la macro.

Use LocalAccessPolicy
...
Use RestrictedAccessPolicy "192.54.172.0/24 192.54.148.0/24"

est équivalent, avec les macros définies ci-dessus à :

Require ip 10.2.16.0/24
...
Require ip 192.54.172.0/24 192.54.148.0/24

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_negotiation.html.fr.utf80000664000175100017510000005613514740503670023166 0ustar covenercovener mod_negotiation - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_negotiation

Langues Disponibles:  en  |  fr  |  ja 

Description:Effectue la négociation de contenu
Statut:Base
Identificateur de Module:negotiation_module
Fichier Source:mod_negotiation.c

Sommaire

La négociation de contenu, ou plus précisément la sélection de contenu, est la sélection parmi plusieurs documents disponibles, du document qui "colle" au plus près des possibilités du client. Pour y parvenir, deux méthodes sont employées.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Tables de correspondances de types

Une table de correspondances de types possède un format similaire à celui des en-têtes de messagerie RFC822. Elle contient des descriptions de documents séparées par des lignes vides, toute ligne commençant par un dièse ('#') étant considérée comme un commentaire. Une description de document comporte plusieurs enregistrements d'en-têtes ; chaque enregistrement peut être réparti sur plusieurs lignes à condition que les lignes supplémentaires commencent par un ou plusieurs espaces. Lors du traitement, les espaces de début de ligne seront supprimés et les lignes concaténées. L'enregistrement d'un en-tête comprend un mot-clé qui se termine toujours par un caractère "deux-points" ':', suivi d'une valeur. Les espaces sont autorisés entre le nom d'en-tête et sa valeur, ainsi qu'entre les différents éléments de la valeur. Les en-têtes autorisés sont :

Content-Encoding:
Le codage du fichier. Apache ne reconnaît que les codages définis par une directive AddEncoding. Sont normalement inclus les codages x-compress pour les fichiers compressés avec compress, et x-gzip pour les fichiers compressés avec gzip. Le préfixe x- est ignoré lors des comparaisons de codages.
Content-Language:
Le(s) langage(s) de la variante, sous la forme d'un symbole de langage Internet standard (RFC 1766). Par exemple, en correspond à l'anglais. Si la variante contient plusieurs langages, ils sont séparés par des virgules.
Content-Length:
La taille du fichier en octets. Si cet en-tête n'est pas présent, c'est la taille réelle du fichier qui est utilisée.
Content-Type:
Le type MIME du document avec des paramètres optionnels. Les paramètres sont séparés du type de médium ainsi qu'entre eux par un point-virgule, et possèdent la syntaxe nom=valeur. Les paramètres courants sont :
level
un entier spécifiant la version du type de média. Pour text/html, la valeur par défaut est 2, sinon 0.
qs
un nombre en virgule flottante de 0[.000] à 1[.000], indiquant la "qualité" relative de la variante courante par rapport aux autres variantes disponibles, indépendamment des possibilités du client. Par exemple, un fichier jpeg est en général une source de qualité supérieure à un fichier ascii s'il est censé représenter une image. Cependant, si la ressource représentée est une image ascii, un fichier ascii possèdera une qualité supérieure à un fichier jpeg. Toutes les valeurs de qs sont donc spécifiques à une certaine ressource.

Exemple

Content-Type: image/jpeg; qs=0.8

URI:
l'URI du fichier contenant la variante (du type de médium donné, codé selon le codage de contenu donné). Cet URI est considéré comme relatif au fichier de correspondances ; il doit être situé sur le même serveur, et doit faire référence au fichier auquel le client se verrait accorder l'accès s'il était requis directement.
Body:
Le contenu réel de la ressource peut être inclus dans la table de correspondances en utilisant l'en-tête Body. Cet en-tête doit contenir une chaîne désignant un délimiteur pour le contenu du corps. Les lignes suivantes du fichier de correspondances de types seront alors considérées comme parties du corps de la ressource jusqu'à ce que le délimiteur soit détecté.

Exemple:

Body:----xyz----
<html>
<body>
<p>Contenu de la page.</p>
</body>
</html>
----xyz----

Considérons une ressource, document.html, disponible en anglais, en français et en allemand. Les fichiers correspondants se nomment respectivement document.html.en, document.html.fr, et document.html.de. Le fichier de correspondances de types se nommera document.html.var et contiendra ce qui suit :

URI: document.html

Content-language: en
Content-type: text/html
URI: document.html.en

Content-language: fr
Content-type: text/html
URI: document.html.fr

Content-language: de
Content-type: text/html
URI: document.html.de

Ces quatre fichiers doivent se trouver dans le même répertoire, et le fichier .var doit être associé au gestionnaire type-map via une directive AddHandler :

AddHandler type-map .var

A l'arrivée d'une requête pour la ressource document.html.var, la variante de document.html qui correspond le mieux à la préference de langage spécifiée dans l'en-tête de la requête de l'utilisateur Accept-Language sera choisie.

Si Multiviews est activée, et si MultiviewsMatch est définie à "handlers" ou "any", une requête pour document.html va rechercher document.html.var, et continuer la négociation avec le gestionnaire explicite type-map.

D'autres directives de configuration, comme Alias, peuvent être utilisées pour associer document.html avec document.html.var.

top

Multivues

Une recherche Multivues est activée par l'Options Multiviews. Si le serveur reçoit une requête pour /un/répertoire/foo, et si /un/répertoire/foo n'existe pas, le serveur parcourt le répertoire à la recherche de tous les fichiers de nom foo.*, et simule véritablement une correspondance de type qui nomme tous ces fichiers en leur assignant les mêmes type de média et codage de contenu qu'ils auraient eus si le client avait requis l'un d'entre eux avec son nom complet. Il choisit ensuite le fichier qui correspond le mieux au profile du client, puis renvoie le document.

La directive MultiviewsMatch définit si Apache doit prendre en compte les fichiers qui ne comportent pas de métadonnées de négociation de contenu lors du choix du fichier à servir.

top

Directive CacheNegotiatedDocs

Description:Permet la mise en cache au niveau des serveurs mandataires des documents dont le contenu a été négocié
Syntaxe:CacheNegotiatedDocs On|Off
Défaut:CacheNegotiatedDocs Off
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_negotiation

Si elle est définie à "on", cette directive permet la mise en cache au niveau des serveurs mandataires des documents dont le contenu a été négocié. Le processus de mise en cache sera alors plus efficace, mais des clients se trouvant derrière le mandataire seront alors susceptibles de se voir servir des versions de documents qui ne correspondent pas forcément à leurs attentes.

Cette directive ne s'applique qu'aux requêtes en provenance de navigateurs HTTP/1.0. HTTP/1.1 fournit un bien meilleur contrôle de la mise en cache des documents au contenu négocié, et cette directive n'a aucun effet sur les réponses aux requêtes HTTP/1.1.

top

Directive ForceLanguagePriority

Description:Action à entreprendre si un document acceptable unique n'est pas trouvé
Syntaxe:ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback]
Défaut:ForceLanguagePriority Prefer
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_negotiation

La directive ForceLanguagePriority utilise le langage défini par la directive LanguagePriority pour terminer la négociation lorsque le serveur n'est pas en mesure de trouver une solution satisfaisante unique.

ForceLanguagePriority Prefer utilise la directive LanguagePriority pour servir le résultat d'un choix unique, au lieu de renvoyer un résultat HTTP 300 (MULTIPLE CHOICES), lorsque que plusieurs choix équivalents sont disponibles. Par exemple, avec les deux directives ci-dessous, si l'en-tête Accept-Language de l'utilisateur assigne à en et de une qualité de .500 (les deux langages sont également acceptables), alors c'est la première variante acceptable de langue en qui sera servie.

LanguagePriority en fr de
ForceLanguagePriority Prefer

ForceLanguagePriority Fallback utilise la directive LanguagePriority pour servir un résultat valide, au lieu de renvoyer un résultat HTTP 406 (NOT ACCEPTABLE). Avec les deux directives ci-dessous, si l'en-tête Accept-Language de l'utilisateur ne mentionne que les réponses de langage es, et si aucune variante dans cette langue n'est trouvée, c'est la première variante de la liste définie par la directive LanguagePriority qui sera servie.

LanguagePriority en fr de
ForceLanguagePriority Fallback

Les deux options, Prefer et Fallback, peuvent être spécifiées, de façon à ce que la variante servie soit la première variante qui convient définie par la directive LanguagePriority si plusieurs variantes sont également acceptables, ou le premier document disponible si aucune variante ne convient à la liste de langages acceptables fournie par le client.

Voir aussi

top

Directive LanguagePriority

Description:L'ordre de priorité des variantes de langages pour les cas où le client n'a pas formulé de préférences
Syntaxe:LanguagePriority langage-MIME [langage-MIME] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_negotiation

La directive LanguagePriority permet de définir, au cours du traitement d'une requête Multivues, l'ordre de priorité des variantes de langages pour les cas où le client n'a pas formulé de préférences. La liste énumère les langages-MIME dans un ordre de préférences décroissantes.

LanguagePriority en fr de

Dans le cas d'une requête pour foo.html, si foo.html.fr et foo.html.de existent, et si le client n'a pas formulé de préférences, c'est le fichier foo.html.fr qui sera renvoyé.

Notez que cette directive n'a d'effet que si le 'meilleur' langage n'a pas pu être déterminé d'une autre manière ou si la valeur de la directive ForceLanguagePriority est différente de None. En général, c'est le client qui détermine le langage préféré, non le serveur.

Voir aussi

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_mime_magic.html.fr.utf80000664000175100017510000004337214740503670022734 0ustar covenercovener mod_mime_magic - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_mime_magic

Langues Disponibles:  en  |  fr 

Description:Détermine le type MIME d'un fichier à partir de quelques octets de son contenu
Statut:Extension
Identificateur de Module:mime_magic_module
Fichier Source:mod_mime_magic.c

Sommaire

Ce module permet de déterminer le type MIME des fichiers de la même manière que la commande Unix file(1), à savoir en se basant sur les premiers octets du fichier. Il est conçu comme une "seconde ligne de défense" pour les cas où mod_mime ne parvient pas à déterminer le type du fichier.

Ce module est dérivé d'une version libre de la commande Unix file(1) qui utilise des "nombres magiques" et autres marques distinctives issus du contenu du fichier pour essayer de déterminer le type de contenu. Ce module n'est activé que si le fichier magique est spécifié par la directive MimeMagicFile.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Format du fichier magique

Le fichier contient du texte ASCII sur 4 à 5 colonnes. Les lignes vides sont autorisées mais ignorées. Toute ligne commençant par un dièse (#) est un commentaire. Les autres lignes sont interprétées en colonnes comme suit :

ColonneDescription
1 numéro de l'octet à partir duquel la vérification débute
">" indique une dépendance par rapport à la dernière ligne non-">"
2

type de donnée à rechercher

byte caractère unique
short entier sur 16 bits selon l'ordre de la machine
long entier sur 32 bits selon l'ordre de la machine
string chaîne de taille choisie
date date au format entier long (secondes depuis le temps Unix epoch/1970)
beshort entier 16 bits big-endian
belong entier 32 bits big-endian
bedate date au format entier 32 bits big-endian
leshort entier 16 bits little-endian
lelong entier 32 bits little-endian
ledate date au format entier 32 bits little-endian
3 contenu des données à rechercher
4 type MIME si correspondance
5 codage MIME si correspondance (optionnel)

Par exemple, les lignes du fichier magique suivantes permettraient de reconnaître certains formats audio :

# 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

Et celles-ci permettraient de reconnaître la différence entre les fichiers *.doc qui contiennent des documents Microsoft Word et les documents FrameMaker (ce sont des formats de fichiers incompatibles qui possèdent le même suffixe).

# 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

Un champ optionnel codage MIME peut être ajouté dans la cinquième colonne. Par exemple, cette ligne permet de reconnaître les fichiers compressés par gzip et définissent le type de codage.

# gzip (GNU zip, à ne pas confondre avec
#       l'archiveur zip [Info-ZIP/PKWARE])

0  string  \037\213  application/octet-stream  x-gzip
top

Problèmes liés aux performances

Ce module n'est pas fait pour tous les systèmes. Si votre système parvient à peine à supporter sa charge, ou si vous testez les performances d'un serveur web, il est déconseillé d'utiliser ce module car son fonctionnement a un prix en matière de ressources consommées.

Des efforts ont cependant été fournis pour améliorer les performances du code original de la commande file(1) en l'adaptant pour fonctionner sur un serveur web à forte charge. Il a été conçu pour un serveur sur lequel des milliers d'utilisateurs publient leurs propres documents, ce qui est probablement très courant sur un intranet. Il s'avère souvent bénéfique qu'un serveur puisse prendre des décisions plus pertinentes à propos du contenu d'un fichier que celles se basant sur le nom du fichier seul, ne serait-ce que pour diminuer le nombre d'appels du type "pourquoi ma page ne s'affiche-t-elle pas ?" survenant lorsque les utilisateurs nomment leurs fichiers incorrectement. Vous devez déterminer si la charge supplémentaire convient à votre environnement.

top

Notes

Les notes suivantes s'appliquent au module mod_mime_magic et sont incluses ici pour conformité avec les restrictions de copyright des contributeurs qui requièrent de les accepter.

Note de traduction : ces informations de type légal ne sont pas traductibles

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

Directive MimeMagicFile

Description:Active la détermination du type MIME en se basant sur le contenu du fichier et en utilisant le fichier magique spécifié
Syntaxe:MimeMagicFile chemin-fichier
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_mime_magic

La directive MimeMagicFile permet d'activer ce module, le fichier par défaut fourni étant conf/magic. Les chemins sans slash '/' de début sont relatifs au répertoire défini par la directive ServerRoot. Les serveurs virtuels utilisent le même fichier que le serveur principal sauf si un fichier spécifique a été défini pour ce serveur virtuel, auquel cas c'est ce dernier fichier qui sera utilisé.

Exemple

MimeMagicFile conf/magic

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_privileges.html.fr.utf80000664000175100017510000010135114740503670023006 0ustar covenercovener mod_privileges - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_privileges

Langues Disponibles:  en  |  fr 

Description:Support des privilèges de Solaris et de l'exécution des serveurs virtuels sous différents identifiants utilisateurs.
Statut:Expérimental
Identificateur de Module:privileges_module
Fichier Source:mod_privileges.c
Compatibilité:Disponible depuis la version 2.3 d'Apache sur les plates-formes Solaris 10 et OpenSolaris

Sommaire

Ce module permet l'exécution de différents serveurs virtuels sous différents identifiants Unix User et Group, et avec différents Privilèges Solaris. En particulier, il apporte au problème de séparation des privilèges entre les différents serveurs virtuels la solution que devait apporter le module MPM abandonné perchild. Il apporte aussi d'autres améliorations en matière de sécurité.

À la différence de perchild, mod_privileges n'est pas un module MPM. Il travaille au sein d'un modèle de traitement pour définir les privilèges et les User/Group pour chaque requête dans un même processus. Il n'est donc pas compatible avec les MPM threadés, et refusera de s'exécuter en cas d'utilisation d'un de ces derniers.

mod_privileges traite des problèmes de sécurité similaires à ceux de suexec ; mais à la différence de ce dernier, il ne s'applique pas seulement aux programmes CGI, mais à l'ensemble du cycle de traitement d'une requête, y compris les applications in-process et les sous-processus. Il convient particulièrement à l'exécution des applications PHP sous mod_php, qui est lui-même incompatible avec les modules MPM threadés. Il est également bien adapté aux autres applications de type script in-process comme mod_perl, mod_python, et mod_ruby, ainsi qu'aux applications en langage C telles que les modules Apache pour lesquels la séparation des privilèges constitue un problème.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Considérations à propos de sécurité

mod_privileges introduit de nouveaux problèmes de sécurité dans les situations où du code non sûr peut s'exécuter à l'intérieur du processus du serveur web. Ceci s'applique aux modules non sûrs, et aux scripts s'exécutant sous des modules comme mod_php ou mod_perl. Les scripts s'exécutant en externe (comme par exemple les scripts CGI ou ceux s'exécutant sur un serveur d'applications derrière mod_proxy ou mod_jk) ne sont pas concernés.

Les principaux problèmes de sécurité que l'on rencontre avec mod_privileges sont :

La directive PrivilegesMode vous permet de sélectionner soit le mode FAST, soit le mode SECURE. Vous pouvez panacher les modes en utilisant par exemple le mode FAST pour les utilisateurs de confiance et les chemins contenant du code entièrement audité, tout en imposant le mode SECURE où un utilisateur non sûr a la possibilité d'introduire du code.

Avant de décrire les modes, il nous faut présenter les cas d'utilisation de la cible : "Benign" ou "Hostile". Dans une situation "Benign", vous voulez séparer les utilisateurs pour leur confort, et les protéger, ainsi que le serveur, contre les risques induits par les erreurs involontaires. Dans une situation "Hostile" - par exemple l'hébergement d'un site commercial - il se peut que des utilisateurs attaquent délibérément le serveur ou s'attaquent entre eux.

Mode FAST
En mode FAST, les requêtes sont traitées "in-process" avec les uid/gid et privilèges sélectionnés, si bien que la surcharge est négligeable. Ceci convient aux situations "Benign", mais n'est pas sécurisé contre un attaquant augmentant ses privilèges avec un module ou script "in-process".
Mode SECURE
Une requête en mode SECURE génère un sous-processus qui supprime les privilèges. Ce comportement est très similaire à l'exécution d'un programme CGI avec suexec, mais il reste valable tout au long du cycle de traitement de la requête, avec en plus l'avantage d'un contrôle précis des privilèges.

Vous pouvez sélectionner différents PrivilegesModes pour chaque serveur virtuel, et même dans un contexte de répertoire à l'intérieur d'un serveur virtuel. Le mode FAST convient lorsque les utilisateurs sont sûrs et/ou n'ont pas le privilège de charger du code "in-process". Le mode SECURE convient dans les cas où du code non sûr peut s'exécuter "in-process". Cependant, même en mode SECURE, il n'y a pas de protection contre un utilisateur malveillant qui a la possibilité d'introduire du code supportant les privilèges avant le début du cycle de traitement de la requête.

top

Directive DTracePrivileges

Description:Détermine si les privilèges requis par dtrace sont activés.
Syntaxe:DTracePrivileges On|Off
Défaut:DTracePrivileges Off
Contexte:configuration globale
Statut:Expérimental
Module:mod_privileges
Compatibilité:>Disponible sous Solaris 10 et OpenSolaris avec les modules MPM non-threadés (prefork ou MPM personnalisé).

Cette directive qui s'applique à l'ensemble du serveur permet de déterminer si Apache s'exécutera avec les privilèges requis pour exécuter dtrace. Notez que la définition DTracePrivileges On n'activera pas à elle-seule DTrace, mais que DTracePrivileges Off l'empêchera de fonctionner.

top

Directive PrivilegesMode

Description:Fait un compromis entre d'une part l'efficacité et la vitesse de traitement et d'autre part la sécurité à l'encontre des codes malicieux supportant les privilèges.
Syntaxe:PrivilegesMode FAST|SECURE|SELECTIVE
Défaut:PrivilegesMode FAST
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Expérimental
Module:mod_privileges
Compatibilité:Disponible sous Solaris 10 et OpenSolaris avec des modules MPMs non threadés (comme prefork ou un module personnalisé).

Cette directive permet de faire un compromis entre les performances et la sécurité à l'encontre des codes malicieux supportant les privilèges. En mode SECURE, chaque requête est traitée dans un sous-processus sécurisé, ce qui induit une dégradation sensible des performances. En mode FAST, le serveur n'est pas protégé contre l'augmentation de privilège comme décrit plus haut.

Cette directive est sensiblement différente selon qu'elle se trouve dans une section <Directory> (ou Location/Files/If) ou au niveau global ou dans un <VirtualHost>.

Au niveau global, elle définit un comportement par défaut dont hériteront les serveurs virtuels. Dans un serveur virtuel, les modes FAST ou SECURE agissent sur l'ensemble de la requête HTTP, et toute définition de ces modes dans une section <Directory> sera ignorée. Le pseudo-mode SELECTIVE confie le choix du mode FAST ou SECURE aux directives contenues dans une section<Directory>.

Dans une section <Directory>, elle ne s'applique que lorsque le mode SELECTIVE a été défini pour le serveur virtuel. Seuls FAST ou SECURE peuvent être définis dans ce contexte (SELECTIVE n'aurait pas de sens).

Avertissement

Lorsque le mode SELECTIVE a été défini pour un serveur virtuel, l'activation des privilèges doit être reportée après la détermination, par la phase de comparaison du traitement de la requête, du contexte <Directory> qui s'applique à la requête. Ceci peut donner à un attaquant l'opportunité d'introduire du code via une directive RewriteMap s'exécutant au niveau global ou d'un serveur virtuel avant que les privilèges n'aient été supprimés et l'uid/gid défini.
top

Directive VHostCGIMode

Description:Détermine si le serveur virtuel peut exécuter des sous-processus, et définit les privilèges disponibles pour ces dernier.
Syntaxe:VHostCGIMode On|Off|Secure
Défaut:VHostCGIMode On
Contexte:serveur virtuel
Statut:Expérimental
Module:mod_privileges
Compatibilité:Disponible sous Solaris 10 et OpenSolaris avec les modules MPM non-threadés (prefork ou MPM personnalisé).

Détermine si le serveur virtuel est autorisé à exécuter fork et exec, et définit les privilèges requis pour exécuter des sous-processus. Si cette directive est définie à Off le serveur virtuel ne disposera d'aucun privilège et ne pourra exécuter ni des programmes ou scripts CGI classiques via le module traditionnel mod_cgi, ni des programmes externes similaires tels que ceux créés via le module mod_ext_filter ou les programmes de réécriture externes utilisés par la directive RewriteMap. Notez que ceci n'empêche pas l'exécution de programmes CGI via d'autres processus et sous d'autres modèles de sécurité comme mod_fcgid, ce qui est la solution recommandée sous Solaris.

Si cette directive est définie à On ou Secure, le serveur virtuel pourra exécuter les scripts et programmes externes cités ci-dessus. Définir la directive VHostCGIMode à Secure a pour effet supplémentaire de n'accorder aucun privilège aux sous-processus, comme décrit dans la directive VHostSecure.

top

Directive VHostCGIPrivs

Description:Assigne des privilèges au choix aux sous-processus créés par un serveur virtuel.
Syntaxe:VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...
Défaut:Aucun
Contexte:serveur virtuel
Statut:Expérimental
Module:mod_privileges
Compatibilité:Disponible sous Solaris 10 et OpenSolaris avec les modules MPM non-threadés (prefork ou MPM personnalisé) et lorsque mod_privileges est construit avec l'option de compilation BIG_SECURITY_HOLE.

La directive VHostCGIPrivs permet d'assigner des privilèges au choix aux sous-processus créés par un serveur virtuel, comme décrit dans la directive VHostCGIMode. Chaque privilege-name correspond à un privilège Solaris tel que file_setid ou sys_nfs.

privilege-name peut être éventuellement préfixé par + ou -, ce qui va respectivement accorder ou refuser le privilège. Si nom-privilège est spécifié sans + ni -, tous les autres privilèges préalablement assignés au serveur virtuel seront refusés. Cette directive permet de construire aisément votre propre jeu de privilèges en annulant tout réglage par défaut.

Sécurité

L'utilisation de cette directive peut ouvrir d'immenses trous de sécurité dans les sous-processus Apache, jusqu'à leur exécution avec les droits de root. Ne l'utilisez que si vous êtes absolument sûr de comprendre ce que vous faites !

top

Directive VHostGroup

Description:Définit l'identifiant du groupe sous lequel s'exécute un serveur virtuel.
Syntaxe:VHostGroup identifiant-groupe-unix
Défaut:Hérite de l'identifiant du groupe spécifié par la directive Group
Contexte:serveur virtuel
Statut:Expérimental
Module:mod_privileges
Compatibilité:Disponible sous Solaris 10 et OpenSolaris avec les modules MPM non-threadés (prefork ou MPM personnalisé).

La directive VHostGroup permet de définir l'identifiant du groupe unix sous lequel le serveur va traiter les requêtes par l'intermédiaire d'un serveur virtuel. L'identifiant du groupe est défini avant le traitement de la requête, puis restauré à sa valeur de départ via les Privilèges Solaris. Comme la définition s'applique au processus, cette directive est incompatible avec les modules MPM threadés.

Unix-group peut être :

Un nom de groupe
Fait référence au groupe donné par son nom.
# suivi d'un numéro de groupe.
Fait référence au groupe donné par son numéro.

Sécurité

Cette directive ne peut pas être utilisée pour exécuter Apache en tant que root ! Elle est tout de même susceptible de poser des problèmes de sécurité similaires à ceux décrits dans la documentation de suexec.

Voir aussi

top

Directive VHostPrivs

Description:Assigne des privilèges à un serveur virtuel.
Syntaxe:VHostPrivs [+-]?nom-privilège [[+-]?nom-privilège] ...
Défaut:Aucun
Contexte:serveur virtuel
Statut:Expérimental
Module:mod_privileges
Compatibilité:Disponible sous Solaris 10 et OpenSolaris avec les modules MPM non-threadés (prefork ou MPM personnalisé) et lorsque mod_privileges est construit avec l'option de compilation BIG_SECURITY_HOLE.

La directive VHostPrivs permet d'assigner des privilèges au choix à un serveur virtuel. Chaque nom-privilège correspond à un privilège Solaris tel que file_setid ou sys_nfs.

nom-privilège peut être éventuellement préfixé par + ou -, ce qui va respectivement accorder ou refuser le privilège. Si nom-privilège est spécifié sans + ni -, tous les autres privilèges préalablement assignés au serveur virtuel seront refusés. Cette directive permet de construire aisément votre propre jeu de privilèges en annulant tout réglage par défaut.

Sécurité

L'utilisation de cette directive peut ouvrir d'immenses trous de sécurité dans Apache, jusqu'au traitement de requêtes avec les droits de root. Ne l'utilisez que si vous êtes absolument sûr de comprendre ce que vous faites !

top

Directive VHostSecure

Description:Détermine si le serveur s'exécute avec une sécurité avancée pour les serveurs virtuels.
Syntaxe:VHostSecure On|Off
Défaut:VHostSecure On
Contexte:serveur virtuel
Statut:Expérimental
Module:mod_privileges
Compatibilité:Disponible sous Solaris 10 et OpenSolaris avec les modules MPM non-threadés (prefork ou MPM personnalisé).

Détermine si les serveurs virtuels traitent les requêtes avec une sécurité avancée en supprimant les Privilèges rarement requis par un serveur web, mais disponibles par défaut pour un utilisateur Unix standard, et donc susceptibles d'être demandés par des modules et des applications. Il est recommandé de conserver la définition par défaut (On), sauf si elle empêche une application de fonctionner. Comme la définition s'applique au processus, cette directive est incompatible avec les modules MPM threadés.

Note

Le fait que la directive VHostSecure empêche une application de fonctionner peut constituer un signal d'avertissement indiquant que la sécurité de l'application doit être revue.

top

Directive VHostUser

Description:Définit l'identifiant utilisateur sous lequel s'exécute un serveur virtuel.
Syntaxe:VHostUser identifiant-utilisateur-unix
Défaut:Hérite de l'identifiant utilisateur spécifié par la directive User
Contexte:serveur virtuel
Statut:Expérimental
Module:mod_privileges
Compatibilité:Disponible sous Solaris 10 et OpenSolaris avec les modules MPM non-threadés (prefork ou MPM personnalisé).

La directive VHostUser permet de définir l'identifiant utilisateur unix sous lequel le serveur va traiter les requêtes par l'intermédiaire d'un serveur virtuel. L'identifiant utilisateur est défini avant le traitement de la requête, puis restauré à sa valeur de départ via les Privilèges Solaris. Comme la définition s'applique au processus, cette directive est incompatible avec les modules MPM threadés.

identifiant-utilisateur-unix peut être :

Un nom d'utilisateur
Fait référence à l'utilisateur donné par son nom.
# suivi d'un numéro d'utilisateur.
Fait référence à l'utilisateur donné par son numéro.

Sécurité

Cette directive ne peut pas être utilisée pour exécuter Apache en tant que root ! Elle est tout de même susceptible de poser des problèmes de sécurité similaires à ceux décrits dans la documentation de suexec.

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_balancer.html.fr.utf80000664000175100017510000006332714740503670023657 0ustar covenercovener mod_proxy_balancer - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_balancer

Langues Disponibles:  en  |  fr  |  ja 

Description:Extension de mod_proxy pour le support de la répartition de charge
Statut:Extension
Identificateur de Module:proxy_balancer_module
Fichier Source:mod_proxy_balancer.c
Compatibilité:Disponible depuis la version 2.1 d'Apache

Sommaire

Pour pouvoir fonctionner, ce module requiert le chargement de mod_proxy, et il fournit le support de la répartition de charge pour tous les protocoles supportés. Parmi ces protocoles, les plus importants sont :

L'algorithme de planification de la répartition de charge n'est pas fourni par ce module, mais par ceux-ci :

Ainsi, pour mettre en oeuvre la répartition de charge, mod_proxy, mod_proxy_balancer et au moins un des modules fournissant l'algorithme de planification de la répartition de charge doivent être chargés dans le serveur.

Avertissement

N'activez pas la fonctionnalité de mandataire avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

L'algorithme de planification de la répartition de charge

A l'heure actuelle, 4 algorithmes de planification de la répartition de charge sont disponibles : ils se basent respectivement sur le comptage des requêtes (mod_lbmethod_byrequests), la mesure de l'intensité du trafic (mod_lbmethod_bytraffic), le comptage des requêtes en attente (mod_lbmethod_bybusyness) et la mesure de l'activité du serveur (mod_lbmethod_heartbeat). Ils sont contrôlés par la valeur de lbmethod dans la définition du répartiteur. Voir la directive ProxyPass pour plus de détails, et en particulier la configuration du répartiteur et de ses membres.

top

Répartition de charge avec abonnement utilisateur (stickyness)

Le répartiteur supporte l'abonnement utilisateur. Lorsqu'une requête est mandatée vers un serveur d'arrière-plan particulier, toutes les requêtes suivantes du même utilisateur seront alors mandatées vers le même serveur d'arrière-plan. De nombreux répartiteurs de charge implémentent cette fonctionnalité via une table qui associe les adresses IP des clients aux serveurs d'arrière-plan. Cette approche est transparente aux clients et aux serveurs d'arrière-plan, mais induit certains problèmes : distribution de charge inégale si les clients se trouvent eux-mêmes derrière un mandataire, erreurs d'abonnement lorsqu'un client possède une adresse IP dynamique qui peut changer au cours d'une session et perte d'abonnement en cas de dépassement de la table de correspondances.

Le module mod_proxy_balancer implémente l'abonnement selon deux alternatives : les cookies et le codage d'URL. Le cookie peut être fourni par le serveur d'arrière-plan ou par le serveur web Apache lui-même, alors que le codage d'URL est en général effectué par le serveur d'arrière-plan.

top

Exemples de configuration d'un répartiteur

Avant de nous plonger dans les détails techniques, voici un exemple d'utilisation de mod_proxy_balancer mettant en oeuvre la répartition de charge entre deux serveurs d'arrière-plan :

<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80"
    BalancerMember "http://192.168.1.51:80"
</Proxy>
ProxyPass        "/test" "balancer://mycluster"
ProxyPassReverse "/test" "balancer://mycluster"

Voici un autre exemple de répartiteur de charge avec abonnement utilisant mod_headers, fonctionnant même si le serveur d'arrière-plan ne définit pas de cookie de session approprié :

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80" route=1
    BalancerMember "http://192.168.1.51:80" route=2
    ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass        "/test" "balancer://mycluster"
ProxyPassReverse "/test" "balancer://mycluster"
top

Variables d'environnement exportées

A l'heure actuelle, 6 variables d'environnement sont exportées :

BALANCER_SESSION_STICKY

Cette variable se voir assignée la valeur de stickysession pour la requête courante. Il s'agit du nom du cookie ou du paramètre de requête utilisé pour les sessions avec abonnement.

BALANCER_SESSION_ROUTE

Cette variable se voit assignée la route interprétée pour la requête courante.

BALANCER_NAME

Cette variable se voit assigné le nom du répartiteur pour la requête courante. Il s'agit d'une valeur du style balancer://foo.

BALANCER_WORKER_NAME

Cette variable se voit assigné le nom du membre du groupe de répartition de charge utilisé pour la requête courante. Il s'agit d'une valeur du style http://hostA:1234.

BALANCER_WORKER_ROUTE

Cette variable se voit assignée la route du membre du groupe de répartition de charge qui sera utilisé pour la requête courante.

BALANCER_ROUTE_CHANGED

Cette variable est définie à 1 si la route de la session ne correspond pas à celle du membre du groupe de répartition de charge (BALANCER_SESSION_ROUTE != BALANCER_WORKER_ROUTE), ou si la session ne possède pas encore de route établie. Elle peut servir à déterminer quand il est éventuellement nécessaire d'envoyer au client une route mise à jour lorsque les sessions persistantes sont utilisées.

top

Activation du support du gestionnaire de répartiteur

Cette fonctionnalité nécessite le chargement du module mod_status. Le gestionnaire de répartiteur permet la mise à jour dynamique des membres du groupe de répartition de charge. Vous pouvez utiliser le gestionnaire de répartiteur pour modifier le facteur de charge d'un membre particulier, ou passer ce dernier en mode hors ligne.

Ainsi, pour mettre en oeuvre la gestion du répartiteur de charge, mod_status et mod_proxy_balancer doivent être chargés dans le serveur.

Pour permettre la gestion du répartiteur de charge aux navigateurs appartenant au domaine example.com, ajoutez ces lignes à votre fichier de configuration httpd.conf :

<Location "/balancer-manager">
    SetHandler balancer-manager
    Require host example.com
</Location>

Vous pourrez alors accéder au gestionnaire du répartiteur de charge en utilisant un navigateur web pour afficher la page http://nom.de.votre.serveur/balancer-manager. Notez que pour pouvoir contrôler dynamiquement un membre de groupe de répartition, ce dernier ne doit pas être défini au sein d'une section <Location ...>.

top

Détails à propos de la répartition de charge par abonnement (stickyness)

Si l'abonnement s'appuie sur un cookie, vous devez définir le nom de ce cookie dont le contenu précise le serveur d'arrière-plan à utiliser. Pour ce faire, on utilise l'attribut stickysession avec la directive ProxyPass ou ProxySet. Le nom du cookie est sensible à la casse. Le répartiteur extrait le contenu du cookie et recherche un serveur membre dont la route correspond à cette valeur. La route doit aussi être définie dans la directive ProxyPass ou ProxySet. Le cookie peut être défini soit par le serveur d'arrière-plan, soit, comme indiqué dans l'exemple ci-dessus par le serveur web Apache lui-même.

Certains serveurs d'arrière-plan, tels qu'Apache Tomcat, utilisent une forme sensiblement différente de cookie d'abonnement. Tomcat ajoute le nom de l'instance Tomcat à la fin de son identifiant de session, précédé par un point. Ainsi, si le serveur web Apache trouve un point dans la valeur du cookie d'abonnement, il n'utilisera que la partie située après ce point pour rechercher sa route. Pour que Tomcat puisse connaître son nom d'instance, vous devez définir l'attribut jvmRoute dans son fichier de configuration conf/server.xml à la valeur de la route du serveur qui se connecte au Tomcat considéré. Le nom du cookie de session utilisé par Tomcat (et plus généralement par les applications web Java à base de servlets) est JSESSIONID (en majuscules), mais peut être modifié.

La seconde méthode pour implémenter l'abonnement est le codage d'URL. Ici, le serveur web recherche un paramètre dans l'URL de la requête. Le nom du paramètre est spécifié par l'attribut stickysession. Pour trouver un serveur membre, on recherche un serveur dont la route est égale à la valeur du paramètre. Comme il n'est pas aisé d'extraire et de manipuler tous les liens URL contenus dans les réponses, le travail consistant à ajouter les paramètres à chaque lien est généralement effectué par le serveur d'arrière-plan qui génère le contenu. Bien qu'il soit possible dans certains cas d'effectuer ces ajouts au niveau du serveur web via les modules mod_substitute ou mod_sed, cette méthode peut dégrader les performances.

Les standards Java implémentent le codage d'URL de manière sensiblement différente. Ils ajoutent une information de chemin à l'URL en utilisant un point-virgule (;) comme séparateur, puis ajoutent enfin l'identifiant de session. Comme dans le cas des cookies, Apache Tomcat peut insérer la valeur de l'attribut jvmRoute dans cette information de chemin. Pour qu'Apache puisse trouver ce genre d'information de chemin, vous devez définir scolonpathdelim à On dans la directive ProxyPass ou ProxySet.

Enfin, vous pouvez utiliser simultanément les cookies et le codage d'URL en définissant le nom du cookie et le nom du paramètre d'URL séparés par une barre verticale (|) comme dans l'exemple suivant :

ProxyPass "/test" "balancer://mycluster" stickysession=JSESSIONID|jsessionid scolonpathdelim=On
<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80" route=node1
    BalancerMember "http://192.168.1.51:80" route=node2
</Proxy>

Si le cookie et le paramètre de requête fournissent tous deux une information de route correcte pour la même requête, c'est l'information en provenance du paramètre de requête qui sera retenue.

top

Résolution des problèmes liés à la répartition de charge par abonnement

Si vous êtes confronté à des erreurs d'abonnement, comme la nécessité pour les utilisateurs de se reconnecter suite à une perte de session d'application, vous devez tout d'abord vérifier si ceci n'est pas du à une indisponibilité sporadique des serveurs d'arrière-plan ou à une erreur de configuration. La présence de messages d'erreur de type proxy dans le journal des erreurs d'Apache pourra révéler des problèmes de stabilité au niveau des serveurs d'arrière-plan.

Pour contrôler votre configuration, regardez tout d'abord si l'abonnement est à base de cookie ou de codage d'URL. L'étape suivante consiste à enregistrer certaines données dans le journal des accès en utilisant un format de journalisation personnalisé. Les champs intéressants sont les suivants :

%{MONCOOKIE}C
La valeur que contient le cookie de nom MONCOOKIE. Le nom doit correspondre au nom défini par l'attribut stickysession.
%{Set-Cookie}o
Ce champ contient tout cookie défini par le serveur d'arrière-plan. Vous pouvez ainsi vérifier si le serveur d'arrière-plan définit bien le cookie de session auquel vous vous attendez, et à quelle valeur il est défini.
%{BALANCER_SESSION_STICKY}e
Le nom du cookie ou du paramètre de requête utilisé pour la recherche de l'information de routage.
%{BALANCER_SESSION_ROUTE}e
L'information de routage extraite de la requête.
%{BALANCER_WORKER_ROUTE}e
La route du serveur choisi.
%{BALANCER_ROUTE_CHANGED}e
Contient la valeur 1 si la route extraite de la requête est différente de la route du serveur ; autrement dit, le traitement de la requête n'a pas pu être effectué dans le cadre d'une répartition de charge par abonnement.

Les pertes de session sont souvent dues à des expirations de session dont la valeur peut en général être configurée au niveau du serveur d'arrière-plan.

Si le niveau de journalisation est défini à debug ou plus, le répartiteur journalise aussi des informations détaillées à propos de l'abonnement dans le journal des erreurs, ce qui facilite la résolution des problèmes d'abonnement. Notez cependant que le volume de journalisation pourra alors s'avérer trop important pour un serveur en production sous forte charge.

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lua.html.fr.utf80000664000175100017510000031300114740503670021413 0ustar covenercovener mod_lua - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_lua

Langues Disponibles:  en  |  fr 

Description:Fournit des points d'entrée Lua dans différentes parties du traitement des requêtes httpd
Statut:Extension
Identificateur de Module:lua_module
Fichier Source:mod_lua.c
Compatibilité:versions 2.3 et supérieures

Sommaire

Ce module permet d'ajouter au serveur des extensions sous forme de scripts écrits dans le langage de programmation Lua. mod_lua fournit de nombreuses extensions (hooks) disponibles avec les modules natifs du serveur HTTP Apache, comme les associations de requêtes à des fichiers, la génération de réponses dynamiques, le contrôle d'accès, l'authentification et l'autorisation.

Vous trouverez davantage d'informations à propos du langage de programmation Lua sur le site web de Lua.

Avertissement

Ce module possède une grande capacité d'action sur le fonctrionnement de httpd, ce qui lui confère une grande puissance, mais peut aussi induire un risque de sécurité. Il est déconseillé d'utiliser ce module sur un serveur partagé avec des utilisateurs auxquels vous ne pouvez pas accorder une confiance absolue, car il peut permettre de modifier le fonctionnement interne de httpd.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Configuration de base

La directive de base pour le chargement du module est

LoadModule lua_module modules/mod_lua.so

mod_lua fournit un gestionnaire nommé lua-script qui peut être utilisé avec une directive AddHandler ou SetHandler :

<Files "*.lua">
    SetHandler lua-script
</Files>

Ceci aura pour effet de faire traiter les requêtes pour les fichiers dont l'extension est .lua par mod_lua en invoquant cette fonction de gestion de fichier.

Pour plus de détails, voir la directive LuaMapHandler.

top

Ecrire des gestionnaires

Dans l'API du serveur HTTP Apache, un gestionnaire est une sorte de point d'accroche (hook) spécifique responsable de la génération de la réponse. mod_proxy, mod_cgi et mod_status sont des exemples de modules comportant un gestionnaire.

mod_lua cherche toujours à invoquer une fonction Lua pour le gestionnaire, plutôt que de simplement évaluer le corps d'un script dans le style de CGI. Une fonction de gestionnaire se présente comme suit :

example.lua
-- exemple de gestionnaire require "string" --[[ Il s'agit du nom de méthode par défaut pour les gestionnaires Lua ; voir les noms de fonctions optionnels dans la directive LuaMapHandler pour choisir un point d'entrée différent. --]] function handle(r) r.content_type = "text/plain" if r.method == 'GET' then r:puts("Hello Lua World!\n") for k, v in pairs( r:parseargs() ) do r:puts( string.format("%s: %s\n", k, v) ) end elseif r.method == 'POST' then r:puts("Hello Lua World!\n") for k, v in pairs( r:parsebody() ) do r:puts( string.format("%s: %s\n", k, v) ) end else elseif r.method == 'PUT' then -- message d'erreur personnalisé r:puts("Unsupported HTTP method " .. r.method) r.status = 405 return apache2.OK else -- message d'erreur ErrorDocument return 501 end return apache2.OK end

Ce gestionnaire se contente d'afficher les arguments codés d'un uri ou d'un formulaire dans un page au format texte.

Cela signifie que vous pouvez (et êtes encouragé à) avoir plusieurs gestionnaires (ou points d'entrée, ou filtres) dans le même script.

top

Ecriture de fournisseurs d'autorisation

mod_authz_core fournit une interface d'autorisation de haut niveau bien plus facile à utiliser que dans les hooks correspondants. Le premier argument de la directive Require permet de spécifier le fournisseur d'autorisation à utiliser. Pour chaque directive Require, mod_authz_core appellera le fournisseur d'autorisation spécifié, le reste de la ligne constituant les paramètres. Le fournisseur considéré va alors vérifier les autorisations et fournir le résultat dans une valeur de retour.

En général, le fournisseur authz est appelé avant l'authentification. S'il doit connaître le nom d'utilisateur authentifié (ou si l'utilisateur est appelé à être authentifié), le fournisseur doit renvoyer apache2.AUTHZ_DENIED_NO_USER, ce qui va déclancher le processus d'authentification et un deuxième appel du fournisseur authz.

La fonction du fournisseur authz ci-dessous accepte deux arguments, une adresse IP et un nom d'utilisateur. Elle autorise l'accès dans le cas où la requête provient de l'adresse IP spécifiée, ou si l'utilisateur authentifié correspond au second argument :

authz_provider.lua
require 'apache2' function authz_check_foo(r, ip, user) if r.useragent_ip == ip then return apache2.AUTHZ_GRANTED elseif r.user == nil then return apache2.AUTHZ_DENIED_NO_USER elseif r.user == user then return apache2.AUTHZ_GRANTED else return apache2.AUTHZ_DENIED end end

La configuration suivante enregistre cette fonction en tant que fournisseur foo, et la configure por l'URL / :

LuaAuthzProvider foo authz_provider.lua authz_check_foo
<Location "/">
  Require foo 10.1.2.3 john_doe
</Location>
top

Ecriture de fonctions d'accroche (hooks)

Les fonctions d'accroche déterminent la manière dont les modules (et les scripts Lua) participent au traitement des requêtes. Chaque type d'accroche proposé par le serveur a un rôle spécifique, comme l'association de requêtes au système de fichiers, le contrôle d'accès, ou la définition de types MIME :

Phase d'accroche Directive mod_lua Description
Gestionnaire rapide LuaQuickHandler Il s'agit de la première accroche appelée lorsqu'une requête a été associée à un serveur ou un serveur virtuel.
Phase de pré-traduction LuaHookPreTranslateName Cette phase traduit l'URI de la requête en nom de fichier sur le système avant la phase de décodage. Des modules comme mod_proxy peuvent agir au cours de cette phase.
Phase de traduction LuaHookTranslateName Cette phase traduit l'URI de la requête en nom de fichier sur le système. Ce sont des modules comme mod_alias et mod_rewrite qui interviennent au cours de cette phase.
Choix du lieu de stockage de la ressource LuaHookMapToStorage Cette phase définit le lieu de stockage de la ressource : physique, en cache ou externe/mandaté. Elle est assurée par les modules de mandat ou de mise en cache.
Autorisation d'accès LuaHookAccessChecker Cette phase vérifie si un client a l'autorisation d'accès à la ressource. Elle s'exécute avant l'authentification de l'utisateur ; il faut donc être prudent.
Vérification de l'identifiant utilisateur LuaHookCheckUserID Cette phase vérifie l'identifiant de l'utilisateur ayant fait l'objet d'une négociation.
Vérification de l'autorisation d'accès LuaHookAuthChecker ou LuaAuthzProvider Cette phase vérifie l'autorisation d'accès d'un utilisateur en fonction des ses paramètres de connexion, comme l'identifiant, le certificat, etc...
Vérification du type de la ressource LuaHookTypeChecker Cette phase assigne un type de contenu et un gestionnaire à la ressource.
Derniers réglages LuaHookFixups C'est la dernière phase avant l'activation des gestionnaires de contenu. Toute modification de dernière minute à la requête doit être effectuée ici.
Gestionnaire de contenu fichiers fx. .lua ou directive LuaMapHandler C'est durant cette phase que le contenu est traité. Les fichiers sont lus, interprétés, certains sont exécutés, et le résultat obtenu est envoyé au client.
Journalisation LuaHookLog Lorsqu'une requête a été traitée, plusieurs phases de journalisation interviennent, et enregistrent leurs résultats dans les fichiers d'erreur ou d'accès. Mod_lua peut s'intercaler au départ de ce processus et ainsi contrôler la journalisation.

Les fonctions d'accroche reçoivent l'objet de la requête comme seul argument (sauf LuaAuthzProvider qui reçoit aussi des arguments en provenance de la directive Require). Elles peuvent renvoyer une valeur, selon la fonction, mais il s'agit en général d'un code d'état HTTP ou des valeurs OK, DONE, ou DECLINED, que vous pouvez écrire dans Lua sous la forme apache2.OK, apache2.DONE, ou apache2.DECLINED.

translate_name.lua
-- exemple d'accroche qui réécrit un URI en chemin du système de fichiers. require 'apache2' function translate_name(r) if r.uri == "/translate-name" then r.filename = r.document_root .. "/find_me.txt" return apache2.OK end -- on ne gère pas cette URL et on donne sa chance à un autre module return apache2.DECLINED end
translate_name2.lua
--[[ exemple d'accroche qui réécrit un URI vers un autre URI. Il renvoie un apache2.DECLINED pour permettre à un autre interpréteur d'URL de travailler sur la substitution, y compris l'accroche translate_name de base dont les tables de correspondances se basent sur DocumentRoot. Note: utilisez le drapeau early/late de la directive pour l'exécuter avant ou après mod_alias. --]] require 'apache2' function translate_name(r) if r.uri == "/translate-name" then r.uri = "/find_me.txt" return apache2.DECLINED end return apache2.DECLINED end
top

Structures de données

request_rec

request_rec est considérée en tant que donnée utilisateur. Elle possède une métatable qui vous permet d'accomplir des choses intéressantes. Pour la plus grande partie, elle possède les mêmes champs que la structure request_rec, la plupart d'entre eux étant accessibles en lecture et écriture (le contenu des champs de la table peut être modifié, mais les champs eux-mêmes ne peuvent pas être établis en tant que tables distinctes).

Nom Type Lua Modifiable Description
allowoverrides string non L'option AllowOverride s'applique à la requête courante.
ap_auth_type string oui Ce champ contient le type d'authentification effectuée (par exemple basic)
args string oui La chaîne de paramètres de la requête (par exemple foo=bar&name=johnsmith)
assbackwards boolean non contient true s'il s'agit d'une requête de style HTTP/0.9 (par exemple GET /foo (sans champs d'en-tête) )
auth_name string non La chaîne d'identification utilisée pour la vérification de l'autorisation d'accès (si elle est disponible).
banner string non La bannière du serveur, par exemple Apache HTTP Server/2.4.3 openssl/0.9.8c
basic_auth_pw string non Le mot de passe pour l'authentification de base envoyé avec la requête, s'il existe
canonical_filename string non Le nom de fichier canonique de la requête
content_encoding string non Le type de codage du contenu de la requête courante
content_type string oui Le type de contenu de la requête courante, tel qu'il a été déterminé au cours de la phase type_check (par exemple image/gif ou text/html)
context_prefix string non
context_document_root string non
document_root string non La racine des documents du serveur
err_headers_out table non L'en-tête MIME de l'environnement pour la réponse, écrit même en cas d'erreur et conservé pendant les redirections internes. Une table lua en lecture seule est disponible pour l'itération sous la forme r:err_headers_out_table().
filename string oui Le nom de fichier correspondant à la requête, par exemple /www/example.com/foo.txt. Il peut être modifié au cours des phases pre-translate-name, translate-name ou map-to-storage du traitement de la requête pour permettre au gestionnaire par défaut (ou aux gestionnaires de script) de servir une version du fichier autre que celle demandée.
handler string oui Le nom du gestionnaire qui doit traiter la requête, par exemple lua-script si elle doit être traitée par mod_lua. Cette valeur est en général définie via les directives AddHandler ou SetHandler, mais peut aussi l'être via mod_lua pour permettre à un autre gestionnaire de traiter une requête spécifique qui ne serait pas traitée par défaut par ce dernier.
headers_in table oui Les en-têtes MIME de l'environnement de la requête. Il s'agit des en-têtes comme Host, User-Agent, Referer, etc... Une table lua en lecture seule est disponible pour l'itération sous la forme r:headers_in_table().
headers_out table oui Les en-têtes MIME de l'environnement de la réponse. Une table lua en lecture seule est disponible pour l'itération sous la forme r:headers_out_table().
hostname string non Le nom d'hôte, tel que défini par l'en-tête Host: ou par un URI complet.
is_https boolean non Indique si la requête à été faite via HTTPS
is_initial_req boolean non Indique si la requête courante est la requête initiale ou une sous-requête.
limit_req_body number non La taille maximale du corps de la requête, ou 0 si aucune limite.
log_id string non L'identifiant de la requête dans les journaux d'accès ou d'erreur.
method string non La méthode de la requête, par exemple GET ou POST.
notes table oui Une liste de notes qui peuvent être transmises d'un module à l'autre. Une table lua en lecture seule est disponible pour l'itération sous la forme r:notes_table().
options string non La valeur de la directive Options pour la requête courante.
path_info string non La valeur de PATH_INFO extraite de la requête.
port number non Le port du serveur utilisé par la requête.
protocol string non Le protocole utilisé, par exemple HTTP/1.1
proxyreq string oui Indique s'il s'agit d'une requête mandatée ou non. Cette valeur est en général définie au cours de la phase post_read_request/pre_translate_name/translate_name du traitement de la requête.
range string non Le contenu de l'en-tête Range:.
remaining number non Le nombre d'octets du corps de la requête restant à lire.
server_built string non La date de compilation du serveur.
server_name string non Le nom du serveur pour cette requête.
some_auth_required boolean non Indique si une autorisation est/était requise pour cette requête.
subprocess_env table oui Le jeu de variables d'environnement pour cette requête. Une table lua en lecture seule est disponible pour l'itération sous la forme r:subprocess_env_table().
started number non Le moment où le serveur a été (re)démarré, en secondes depuis epoch (1er janvier 1970)
status number oui Le code de retour (courant) pour cette requête, par exemple 200 ou 404.
the_request string non La chaîne de la requête telle qu'elle a été envoyée par le client, par exemple GET /foo/bar HTTP/1.1.
unparsed_uri string non La partie URI non interprétée de la requête
uri string oui L'URI après interprétation par httpd
user string oui Si une authentification a été effectuée, nom de l'utilisateur authentifié.
useragent_ip string non L'adresse IP de l'agent qui a envoyé la requête
top

Méthodes de l'objet request_rec

L'objet request_rec possède (au minimum) les méthodes suivantes :

r:flush()   -- vide le tampon de sortie
            -- Renvoie true si le vidage a été effectué avec succès,
	    -- false dans le cas contraire.

while nous_avons_des_données_à_envoyer do
    r:puts("Bla bla bla\n") -- envoi des données à envoyer vers le tampon
    r:flush() -- vidage du tampon (envoi au client)
    r.usleep(500000) -- mise en attente pendant 0.5 secondes et bouclage
end
r:add_output_filter(filter_name) -- ajoute un filtre en sortie

r:add_output_filter("fooFilter") -- insère le filtre fooFilter dans le flux de sortie
r:sendfile(filename) -- envoie un fichier entier au client en utilisant sendfile s'il est
                     -- supporté par la plateforme :

if use_sendfile_thing then
    r:sendfile("/var/www/large_file.img")
end
r:parseargs() -- renvoie deux tables : une table standard de couples
              -- clé/valeur pour les données GET simples,
              -- et une autre pour les données
              -- multivaluées (par exemple foo=1&foo=2&foo=3) :

local GET, GETMULTI = r:parseargs()
r:puts("Votre nom est : " .. GET['name'] or "Unknown")
r:parsebody()([sizeLimit]) -- interprète le corps de la
                           -- requête en tant que POST et renvoie
                           -- deux tables lua, comme r:parseargs(). Un
                           -- nombre optionnel peut être fourni
                           -- pour spécifier le nombre maximal
                           -- d'octets à interpréter. La
                           -- valeur par défaut est 8192.

local POST, POSTMULTI = r:parsebody(1024*1024)
r:puts("Votre nom est : " .. POST['name'] or "Unknown")
r:puts("bonjour", " le monde", "!") -- affichage dans le corps de la réponse
r:write("une simple chaîne") -- affichage dans le corps de la réponse
r:escape_html("<html>test</html>") -- Echappe le code HTML et renvoie le résultat
r:base64_encode(string) -- Encode une chaîne à l'aide du standard de codage Base64.

local encoded = r:base64_encode("This is a test") -- returns VGhpcyBpcyBhIHRlc3Q=
r:base64_decode(string) -- Décode une chaîne codée en Base64.

local decoded = r:base64_decode("VGhpcyBpcyBhIHRlc3Q=") -- returns 'This is a test'
r:md5(string) -- Calcule et renvoie le condensé MD5 d'une chaîne en mode binaire (binary safe).

local hash = r:md5("This is a test") -- returns ce114e4501d2f4e2dcea3e17b546f339
r:sha1(string) -- Calcule et renvoie le condensé SHA1 d'une chaîne en mode binaire (binary safe).

local hash = r:sha1("This is a test") -- returns a54d88e06612d820bc3be72877c74f257b561b19
r:escape(string) -- Echappe une chaîne de type URL.

local url = "http://foo.bar/1 2 3 & 4 + 5"
local escaped = r:escape(url) -- renvoie 'http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5'
r:unescape(string) -- Déséchappe une chaîne de type URL.

local url = "http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5"
local unescaped = r:unescape(url) -- renvoie 'http://foo.bar/1 2 3 & 4 + 5'
r:construct_url(string) -- Construit une URL à partir d'un URI

local url = r:construct_url(r.uri)
r.mpm_query(number) -- Interroge le serveur à propos de son module MPM via la requête ap_mpm_query.

local mpm = r.mpm_query(14)
if mpm == 1 then
    r:puts("Ce serveur utilise le MPM Event")
end
r:expr(string) -- Evalue une chaîne de type expr.

if r:expr("%{HTTP_HOST} =~ /^www/") then
    r:puts("Ce nom d'hôte commence par www")
end
r:scoreboard_process(a) -- Interroge le serveur à propos du
                        -- processus à la position a.

local process = r:scoreboard_process(1)
r:puts("Le serveur 1 a comme PID " .. process.pid)
r:scoreboard_worker(a, b) -- Interroge le serveur à propos du
                          -- thread b, dans le processus a.

local thread = r:scoreboard_worker(1, 1)
r:puts("L'ID du thread 1 du serveur 1 est " .. thread.tid .. " et son
état est " .. thread.status)
r:clock() -- Renvoie l'heure courante avec une précision d'une microseconde.
r:requestbody(filename) -- Lit et renvoie le corps d'une requête.
                        -- Si 'filename' est spécifié, le
                        -- corps de requête n'est pas
                        -- renvoyé, mais sauvegardé dans
                        -- le fichier correspondant.

local input = r:requestbody()
r:puts("Vous m'avez envoyé le corps de requête suivant :\n")
r:puts(input)
r:add_input_filter(filter_name) -- Ajoute le filtre en entrée 'filter_name'.
r:module_info(module_name) -- Interroge le serveur à propos d'un module.

local mod = r.module_info("mod_lua.c")
if mod then
    for k, v in pairs(mod.commands) do
       r:puts( ("%s: %s\n"):format(k,v)) -- affiche toutes les directives
                                         -- implémentées par ce module.
    end
end
r:loaded_modules() -- Renvoie une liste des modules chargés par httpd.

for k, module in pairs(r:loaded_modules()) do
    r:puts("J'ai chargé le module " .. module .. "\n")
end
r:runtime_dir_relative(filename) -- Génère le nom d'un fichier run-time
                                 -- (par exemple la mémoire partagée
                                 -- "file") relativement au répertoire de run-time.
r:server_info() -- Renvoie une table contenant des informations à
                -- propos du serveur, comme le nom de
                -- l'exécutable httpd, le module mpm utilisé, etc...
r:set_document_root(file_path) -- Définit la racine des documents
                               -- pour la requête à file_path.
r:add_version_component(component_string) -- Ajoute un élément à
                                          -- la bannière du serveur.
r:set_context_info(prefix, docroot) -- Définit le préfixe et la
                                    -- racine des documents du contexte pour une requête.
r:os_escape_path(file_path) -- Convertit un chemin du système de
                            -- fichiers en URL indépendamment du système d'exploitation.
r:escape_logitem(string) -- Echappe une chaîne pour journalisation.
r.strcmp_match(string, pattern) -- Vérifie si 'string' correspond à
                                -- 'pattern' via la fonction strcmp_match (GLOBs). Par exemple, est-ce que
                                -- 'www.example.com' correspond à '*.example.com' ?

local match = r.strcmp_match("foobar.com", "foo*.com")
if match then 
    r:puts("foobar.com matches foo*.com")
end
r:set_keepalive() -- Définit l'état de persistance d'une requête.
                  -- Renvoie true dans la mesure du possible, false dans le cas contraire.
r:make_etag() -- Génère et renvoie le etag pour la requête courante.
r:send_interim_response(clear) -- Renvoie une réponse d'intérim (1xx) au
                               -- client. Si 'clear' est vrai, les en-têtes disponibles
                               -- seront envoyés et effacés.
r:custom_response(status_code, string) -- Génère et définit une réponse
                                       -- personnalisée pour un code d'état particulier.
                                       -- Le fonctionnement est très proche de celui de la directive ErrorDocument.

r:custom_response(404, "Baleted!")
r.exists_config_define(string) -- Vérifie si une définition de configuration existe.

if r.exists_config_define("FOO") then
    r:puts("httpd a probablement été lancé avec l'option -DFOO, ou FOO a
    été défini dans la configuration")
end
r:state_query(string) -- Interroge le serveur à propos de son état.
r:stat(filename [,wanted]) -- Exécute stat() sur un fichier, et renvoie une table contenant
                           -- des informations à propos de ce fichier.

local info = r:stat("/var/www/foo.txt")
if info then
    r:puts("Ce fichier existe et a été modifié pour la dernière fois à : " .. info.modified)
end
r:regex(string, pattern [,flags]) -- Exécute une recherche à base d'expression rationnelle
                                  -- sur une chaîne, et renvoie les éventuelles correspondances trouvées.

local matches = r:regex("foo bar baz", [[foo (\w+) (\S*)]])
if matches then
    r:puts("L'expression rationnelle correspond et le dernier mot
    capturé ($2) est : " .. matches[2])
end

-- Exemple avec insensibilité à la casse :
local matches = r:regex("FOO bar BAz", [[(foo) bar]], 1)

-- les drapeaux peuvent être une combibaison bit à bit de :
-- 0x01: insensibilité à la casse
-- 0x02: recherche multiligne
r.usleep(microsecondes) -- Interrompt l'exécution du script pendant le nombre de microsecondes spécifié.
r:dbacquire(dbType[, dbParams]) -- Acquiert une connexion à une base de données et renvoie une classe database.
                                -- Voir 'Connectivité aux bases de données'
				-- pour plus de détails.
r:ivm_set("key", value) -- Défini une variable Inter-VM avec une valeur spécifique.
                        -- Ces valeurs sont conservées même si la VM est
			-- arrêtée ou non utilisée, et ne doivent donc être
			-- utilisées que si MaxConnectionsPerChild > 0.
			-- Les valeurs peuvent être de type number, string
			-- ou boolean et sont stockées séparément pour
			-- chaque processus (elles ne seront donc pas d'une
			-- grande utilité si l'on utilise le mpm prefork).
                        
r:ivm_get("key")        -- Lit le contenu d'une variable définie via ivm_set. Renvoie
			-- le contenu de la variable si elle existe, ou nil
			-- dans le cas contraire.
                        
-- Voici un exemple de lecture/écriture qui sauvegarde une variable
-- globale en dehors de la VM :
function handle(r)
    -- La première VM qui effectue l'appel suivant n'obtiendra aucune
    -- valeur, et devra la créer
    local foo = r:ivm_get("cached_data")
    if not foo then
        foo = do_some_calcs() -- simulation de valeurs de retour
        r:ivm_set("cached_data", foo) -- définition globale de la variable
    end
    r:puts("La donnée en cache est : ", foo)
end
r:htpassword(string [,algorithm [,cost]]) -- Génère un hash de mot de passe à partir d'une chaîne.
                                          -- algorithm: 0 = APMD5 (défaut), 1 = SHA, 2 = BCRYPT, 3 = CRYPT.
                                          -- cost: ne s'utilise qu'avec l'algorythme BCRYPT (défaut = 5).
r:mkdir(dir [,mode]) -- Crée un répertoire et définit son mode via le paramètre optionnel mode.
r:mkrdir(dir [,mode]) -- Crée des répertoires de manière récursive et définit
                      -- leur mode via le paramètre optionnel mode.
r:rmdir(dir) -- Supprime un répertoire.
r:touch(file [,mtime]) -- Définit la date de modification d'un fichier à la date courante ou à
                       -- la valeur optionnelle mtime en msec.
r:get_direntries(dir) -- Renvoie une table contenant toutes les entrées de répertoires.

-- Renvoie un chemin sous forme éclatée en chemin, fichier, extension
function handle(r)
  local dir = r.context_document_root
  for _, f in ipairs(r:get_direntries(dir)) do
    local info = r:stat(dir .. "/" .. f)
    if info then
      local mtime = os.date(fmt, info.mtime / 1000000)
      local ftype = (info.filetype == 2) and "[dir] " or "[file]"
      r:puts( ("%s %s %10i %s\n"):format(ftype, mtime, info.size, f) )
    end
  end
end
r.date_parse_rfc(string) -- Interprète une chaîne date/heure et renvoie l'équivalent en secondes depuis epoche.
r:getcookie(key) -- Obtient un cookie HTTP
r:setcookie(key, value, secure, expires) -- Définit un cookie HTTP, par exemple :
r:setcookie("foo", "bar and stuff", false, os.time() + 86400)
r:wsupgrade() -- Met à jour une connexion vers les WebSockets si possible (et si demandé) :
if r:wsupgrade() then -- si la mise à jour est possible :
    r:wswrite("Bienvenue dans les websockets!") -- écrit quelque chose à l'intention du client
    r:wsclose()  -- Au revoir !
end
r:wsread() -- Lit un cadre de websocket depuis une connexion vers websocket mise à jour (voir ci-dessus) :
           
local line, isFinal = r:wsread() -- isFinal indique s'il s'agit du cadre final.
                                 -- dans le cas contraire, on peut lire les cadres suivants
r:wswrite("Vous avez écrit : " .. line)
r:wswrite(line) -- écrit un cadre vers un client WebSocket :
r:wswrite("Bonjour le Monde !")
r:wsclose() -- ferme une requête WebSocket et l'achève pour httpd :

if r:wsupgrade() then
    r:wswrite("Ecrire quelque chose : ")
    local line = r:wsread() or "nothing"
    r:wswrite("Vous avez écrit : " .. line);
    r:wswrite("Au revoir !")
    r:wsclose()
end
top

Fonctions de journalisation

	-- exemples de messages de journalisation
	r:trace1("Ceci est un message de journalisation de niveau
	trace") -- les niveaux valides vont de trace1 à trace8 
        r:debug("Ceci est un message de journalisation de niveau debug")
        r:info("Ceci est un message de journalisation de niveau info")
        r:notice("Ceci est un message de journalisation de niveau notice")
        r:warn("Ceci est un message de journalisation de niveau warn")
        r:err("Ceci est un message de journalisation de niveau err")
        r:alert("Ceci est un message de journalisation de niveau alert")
        r:crit("Ceci est un message de journalisation de niveau crit")
        r:emerg("Ceci est un message de journalisation de niveau emerg")
top

Paquet apache2

Le paquet nommé apache2 est fourni avec (au minimum) le contenu suivant :

apache2.OK
Constante interne OK. Les gestionnaires renverront cette valeur s'ils ont traité la requête.
apache2.DECLINED
Constante interne DECLINED. Les gestionnaires renverront cette valeur s'ils n'ont pas l'intention de traiter la requête.
apache2.DONE
Constante interne DONE.
apache2.version
Chaîne contenant la version du serveur HTTP Apache
apache2.HTTP_MOVED_TEMPORARILY
Code d'état HTTP
apache2.PROXYREQ_NONE, apache2.PROXYREQ_PROXY, apache2.PROXYREQ_REVERSE, apache2.PROXYREQ_RESPONSE
Constantes internes utilisées par mod_proxy
apache2.AUTHZ_DENIED, apache2.AUTHZ_GRANTED, apache2.AUTHZ_NEUTRAL, apache2.AUTHZ_GENERAL_ERROR, apache2.AUTHZ_DENIED_NO_USER
constantes internes utilisées par mod_authz_core

Les autres codes d'état HTTP ne sont pas encore implémentés.

top

Modification de contenu avec les filtres lua

Les fonctions de filtrage implémentées via les directives LuaInputFilter ou LuaOutputFilter sont conçues comme des fonctions de 3ème phase non blocantes utilisant des sous-routines pour suspendre et reprendre l'exécution d'une fonction lorsque des paquets de données sont envoyés à la chaîne de filtrage. La structure de base d'une telle fonction est :

function filter(r)
    -- Nous indiquons tout d'abord que nous sommes prêts à recevoir des
    -- blocs de données.
    -- Avant ceci, nous pouvons définir notre environnement, tester
    -- certaines conditions, et, si nous le jugeons nécessaire, refuser le
    -- filtrage d'une requête :
    if something_bad then
        return -- Le filtrage est sauté
    end
    -- Sans se préoccuper des données que nous devons éventuellement ajouter, un arrêt est réalisé ici.
    -- Noter que les filtres de sortie sont les seuls capables d'ajouter des éléments au début des données.
    -- Les filtres en entrée peuvent ajouter des éléments à la fin des données au stade final.

    coroutine.yield([optional header to be prepended to the content])

    -- Après cet arrêt, nous allons recevoir d'autres blocs de données, un par un ;
    -- nous pouvons les traiter comme il nous plaît et procéder à la réponse.
    -- Ces blocs sont conservés dans la variable globale 'bucket', nous réalisons donc
    -- une boucle pour vérifier que 'bucket' n'est pas vide :
    while bucket ~= nil do
        local output = mangle(bucket) -- Do some stuff to the content
        coroutine.yield(output) -- Return our new content to the filter chain
    end

    -- Une fois les blocs de données épuisés, 'bucket' est positionné à une valeur vide ('nil'),
    -- ce qui va nous faire sortir de cette boucle et nous amener à l'étape suivante.
    -- On peut ajouter ce qu'on veut à la fin des données à cette étape, qui constitue le dernier
    -- arrêt. Les filtres d'entrée comme de sortie peuvent servir à ajouter des éléments à la fin
    --  des données à cette étape.
    coroutine.yield([optional footer to be appended to the content])
end
top

Connectivité aux bases de données

Mod_lua implémente une fonctionnalité basique de connexion aux bases de données permettant d'envoyer des requêtes ou d'exécuter des commandes auprès des moteurs de base de données les plus courants (mySQL, PostgreSQL, FreeTDS, ODBC, SQLite, Oracle), ainsi que mod_dbd.

dbType, le premier paramètre de dbacquire, est sensible à la casse.

Ses valeurs possibles sont mysql, pgsql, freetds, odbc, sqlite2, sqlite3, oracle ou mod_dbd.

L'exemple suivant montre comment se connecter à une base de données et extraire des informations d'une table :

function handle(r)
    -- connexion à la base de données
    local database, err = r:dbacquire("mysql", "server=localhost,user=someuser,pass=somepass,dbname=mydb")
    if not err then
        -- Sélection de certaines informations
        local results, err = database:select(r, "SELECT `name`, `age` FROM `people` WHERE 1")
        if not err then
            local rows = results(0) -- extrait tous les enregistrements en mode synchrone
            for k, row in pairs(rows) do
                r:puts( string.format("Name: %s, Age: %s<br/>", row[1], row[2]) )
            end
        else
            r:puts("Database query error: " .. err)
        end
        database:close()
    else
        r:puts("Connexion à la base de données impossible : " .. err)
    end
end

Pour utiliser mod_dbd, spécifiez mod_dbd comme type de base de données, ou laissez le champ vide :

local database = r:dbacquire("mod_dbd")

L'objet database et ses méthodes

L'objet database renvoyé par dbacquire possède les méthodes suivantes :

Sélection normale et requête vers une base de données :

-- Exécution d'une requête et renvoie du nombre d'enregistrements
affectés :
local affected, errmsg = database:query(r, "DELETE FROM `tbl` WHERE 1")

-- Exécution d'une requête et renvoie du résultat qui peut être utilisé
en mode synchrone ou asynchrone :
local result, errmsg = database:select(r, "SELECT * FROM `people` WHERE 1")

Utilisation de requêtes préparées (recommandé) :

-- Création et exécution d'une requête préparée :
local statement, errmsg = database:prepare(r, "DELETE FROM `tbl` WHERE `age` > %u")
if not errmsg then
    local result, errmsg = statement:query(20) -- exécute la requête pour age > 20
end

-- Extrait une requête préparée depuis une directive DBDPrepareSQL :
local statement, errmsg = database:prepared(r, "someTag")
if not errmsg then
    local result, errmsg = statement:select("John Doe", 123) -- injecte les valeurs "John Doe" et 123 dans la requête
end

Echappement de valeurs, fermeture de la base données, etc...

-- Echappe une valeur pour pouvoir l'utiliser dans une requête :
local escaped = database:escape(r, [["'|blabla]])

-- Ferme une base de données et libère les liens vers cette dernière :
database:close()

-- Vérifie si une connexion à une base de données est en service et
opérationnelle :
local connected = database:active()

Travail avec les jeux d'enregistrements renvoyés par les requêtes

Les jeux d'enregistrements renvoyés par db:select ou par des requêtes préparées créées par db:prepare permettent de sélectionner des enregistrements en mode synchrone ou asynchrone, selon le nombre d'enregistrements spécifié :
result(0) sélectionne tous les enregistrements en mode synchrone en renvoyant une table d'enregistrements.
result(-1) sélectionne le prochain enregistrement disponible en mode asynchrone.
result(N) sélectionne l'enregistrement numéro N en mode asynchrone.

-- extrait un jeu d'enregistrements via une requête régulière :
local result, err = db:select(r, "SELECT * FROM `tbl` WHERE 1")

local rows = result(0) -- sélectionne tous les enregistrements en mode synchrone
local row = result(-1) -- sélectionne le prochain enregistrement disponible en mode asynchrone
local row = result(1234) -- sélectionne l'enregistrement 1234 en mode asynchrone
local row = result(-1, true) -- Lit l'enregistrement suivant en utilisant les noms d'enregistrements comme index.

Il est possible de construire une fonction qui renvoie une fonction itérative permettant de traiter tous les enregistrement en mode synchrone ou asynchrone selon la valeur de l'argument async :

function rows(resultset, async)
    local a = 0
    local function getnext()
        a = a + 1
        local row = resultset(-1)
        return row and a or nil, row
    end
    if not async then
        return pairs(resultset(0))
    else
        return getnext, self
    end
end

local statement, err = db:prepare(r, "SELECT * FROM `tbl` WHERE `age` > %u")
if not err then
     -- sélectionne des enregistrements en mode asynchrone :
    local result, err = statement:select(20)
    if not err then
        for index, row in rows(result, true) do
            ....
        end
    end

     -- sélectionne des enregistrements en mode synchrone :
    local result, err = statement:select(20)
    if not err then
        for index, row in rows(result, false) do
            ....
        end
    end
end

Fermeture d'une connexion à une base de données

Lorsqu'elles ne sont plus utilisées, les connexions aux bases de données doivent être fermées avec database:close(). Si vous ne les fermez pas manuellement, mod_lua les fermera peut-être en tant que résidus collectés, mais si ce n'est pas le cas, vous pouvez finir pas avoir trop de connexions vers la base de données inutilisées. Les deux mesures suivantes sont pratiquement identiques :

-- Méthode 1 : fermeture manuelle de la connexion
local database = r:dbacquire("mod_dbd")
database:close() -- c'est tout

-- Méthode 2 : on laisse le collecteur de résidus la fermer
local database = r:dbacquire("mod_dbd")
database = nil -- on coupe le lien
collectgarbage() -- fermeture de la connexion par le collecteur de résidus

Précautions à prendre lorsque l'on travaille avec les bases de données

Bien que les fonctions query et run soient toujours disponibles, il est recommandé d'utiliser des requêtes préparées chaque fois que possible, afin d'une part d'optimiser les performances (si votre connexion reste longtemps en vie), et d'autre part minimiser le risque d'attaques par injection SQL. Les fonctions run et query ne doivent être utilisées que lorsque la requête ne contient pas de variables (requête statique). Dans le cas des requêtes dynamiques, utilisez db:prepare ou db:prepared.

top

Directive LuaAuthzProvider

Description:Branche une fonction fournisseur d'autorisation dans mod_authz_core
Syntaxe:LuaAuthzProvider provider_name /path/to/lua/script.lua function_name
Contexte:configuration globale
Statut:Extension
Module:mod_lua
Compatibilité:Disponible depuis la version 2.4.3 du serveur HTTP Apache

Lorsqu'une fonction lua a été enregistrée en tant que fournisseur d'autorisation, elle peut être appelée via la directive Require :

LuaRoot "/usr/local/apache2/lua"
LuaAuthzProvider foo authz.lua authz_check_foo
<Location "/">
  Require foo johndoe
</Location>
require "apache2"
function authz_check_foo(r, who)
    if r.user ~= who then return apache2.AUTHZ_DENIED
    return apache2.AUTHZ_GRANTED
end
top

Directive LuaCodeCache

Description:Configure le cache de code compilé.
Syntaxe:LuaCodeCache stat|forever|never
Défaut:LuaCodeCache stat
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette directive permet de définir le comportement du cache de code en mémoire. La valeur par défaut est stat ; dans ce cas, le script du niveau le plus haut (et pas les scripts inclus) est vérifié à chaque fois que ce fichier est nécessaire, et est rechargé si la date de modification est plus récente que celle du script déjà chargé. Les autres valeurs permettent respectivement de garder le fichier en cache perpétuellement (forever - jamais vérifié ni remplacé), ou de ne jamais le mettre en cache (never).

En général, les valeurs stat et forever sont utilisées pour un serveur en production, et les valeurs stat ou never pour un serveur en développement.

Exemples :

LuaCodeCache stat
LuaCodeCache forever
LuaCodeCache never
top

Directive LuaHookAccessChecker

Description:Fournit un point d'entrée pour la phase access_checker du traitement de la requête
Syntaxe:LuaHookAccessChecker /chemin/vers/lua/script.lua hook_function_name [early|late]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua
Compatibilité:Le troisième argument optionnel est disponible depuis la version 2.3.15 du serveur HTTP Apache.

Ajoute votre fonction d'accroche à la phase access_checker. Une fonction d'accroche access checker renvoie en général OK, DECLINED, ou HTTP_FORBIDDEN.

Ordonnancement

Les arguments optionnels "early" ou "late" permettent de contrôler le moment auquel ce script s'exécute par rapport aux autres modules.

top

Directive LuaHookAuthChecker

Description:Fournit un point d'entrée pour la phase auth_checker du traitement de la requête
Syntaxe:LuaHookAuthChecker /chemin/vers/lua/script.lua hook_function_name [early|late]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua
Compatibilité:Le troisième argument optionnel est disponible depuis la version 2.3.15 du serveur HTTP Apache.

Invoque une fonction lua au cours de la phase auth_checker du traitement de la requête. Cette directive peut s'utiliser pour implémenter une vérification arbitraire de l'authentification et de l'autorisation. Voici un exemple très simple :

require 'apache2'

-- fonction d'accroche authcheck fictive
-- Si la requête ne contient aucune donnée d'authentification, l'en-tête
-- de la réponse est défini et un code 401 est renvoyé afin de demander au
-- navigateur d'effectuer une authentification basique. Si la requête
-- comporte des données d'authentification, elles ne sont pas vraiment
-- consultées, mais on admet la prise en compte de l'utilisateur 'foo' et
-- on la valide. On vérifie ensuite si l'utilisateur est bien 'foo' et on
-- accepte la requête.
function authcheck_hook(r)

   -- recherche des informations d'authentification
   auth = r.headers_in['Authorization']
   if auth ~= nil then
     -- définition d'un utilisateur par défaut
     r.user = 'foo'
   end

   if r.user == nil then
      r:debug("authcheck: user is nil, returning 401")
      r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
      return 401
   elseif r.user == "foo" then
      r:debug('user foo: OK')
   else
      r:debug("authcheck: user='" .. r.user .. "'")
      r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
      return 401
   end
   return apache2.OK
end

Ordonnancement

Les arguments optionnels "early" ou "late" permettent de contrôler le moment auquel ce script s'exécute par rapport aux autres modules.

top

Directive LuaHookCheckUserID

Description:Fournit un point d'entrée pour la phase check_user_id du traitement de la requête
Syntaxe:LuaHookCheckUserID /chemin/vers/lua/script.lua hook_function_name [early|late]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua
Compatibilité:Le troisième argument optionnel est disponible depuis la version 2.3.15 du serveur HTTP Apache.

...

Ordonnancement

Les arguments optionnels "early" ou "late" permettent de contrôler le moment auquel ce script s'exécute par rapport aux autres modules.

top

Directive LuaHookFixups

Description:Fournit un point d'entrée pour la phase de correction du traitement de la requête
Syntaxe:LuaHookFixups /chemin/vers/lua/script.lua hook_function_name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Idem LuaHookTranslateName, mais s'exécute durant la phase de correction.

top

Directive LuaHookInsertFilter

Description:Fournit un point d'entrée pour la phase insert_filter du traitement de la requête
Syntaxe:LuaHookInsertFilter /chemin/vers/lua/script.lua hook_function_name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Non encore implémenté

top

Directive LuaHookLog

Description:Permet une insertion dans la phase de journalisation du traitement d'une requête
Syntaxe:LuaHookLog /path/to/lua/script.lua log_function_name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Ce dispositif d'insertion simple permet d'exécuter une fonction lorsque httpd entre dans la phase de journalisation du traitement d'une requête. Vous pouvez ainsi ajouter des données à vos propres entrées de journalisation, manipuler les entrées du journal standard avant leur enregistrement ou empêcher l'enregistrement d'une entrée dans le journal. Pour empêcher l'enregistrement normal des entrées du journal, renvoyez simplement apache2.DONE dans votre gestionnaire de journalisation, ou au contraire, renvoyez apache2.OK pour que httpd effectue une journalisation normale.

Exemple :

LuaHookLog "/path/to/script.lua" logger
-- /path/to/script.lua --
function logger(r)
    -- on joue à pile ou face :
    -- Si on obtient 1, on écrit dans notre propre journal Lua et on dit
    -- à httpd de ne pas enregistrer d'entrée dans le journal standard..
    -- Si on obtient 2, on nettoie un peu les données avant que httpd ne
    -- les enregistre dans le journal standard.

    if math.random(1,2) == 1 then
        -- On effectue notre propre journalisation et le journal
	-- standard n'est pas alimenté
        local f = io.open("/foo/secret.log", "a")
        if f then
            f:write("Quelque chose de secret est arrivé à " .. r.uri .. "\n")
            f:close()
        end
        return apache2.DONE -- On dit à httpd de ne rien enregistrer
			    --dans le journal standard
    else
        r.uri = r.uri:gsub("somesecretstuff", "") -- nettoie les données
        return apache2.OK -- et httpd doit alors les enregistrer.
    end
end
top

Directive LuaHookMapToStorage

Description:Fournit un point d'entrée pour la phase map_to_storage du traitement de la requête
Syntaxe:LuaHookMapToStorage /chemin/vers/lua/script.lua hook_function_name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Identique à la directive LuaHookTranslateName, mais s'exécute à la phase map-to-storage du traitement de la requête. Les modules comme mod_cache agissent pendant cette phase, ce qui permet de présenter un exemple intéressant de ce que l'on peut faire ici :

LuaHookMapToStorage "/path/to/lua/script.lua" check_cache
require"apache2"
cached_files = {}

function read_file(filename)
    local input = io.open(filename, "r")
    if input then
        local data = input:read("*a")
        cached_files[filename] = data
        file = cached_files[filename]
        input:close()
    end
    return cached_files[filename]
end

function check_cache(r)
    if r.filename:match("%.png$") then -- Ne concerne que les fichiers PNG
        local file = cached_files[r.filename] -- Vérifie les entrées du cache
        if not file then
            file = read_file(r.filename)  -- Lit le fichier vers le cache
        end
        if file then -- Si le fichier existe, on l'envoie
            r.status = 200
            r:write(file)
            r:info(("%s a été envoyé au client depuis le cache"):format(r.filename))
            return apache2.DONE -- cout-circuite le gestionnaire par défaut des fichiers PNG
        end
    end
    return apache2.DECLINED -- Si nous n'avons rien eu à faire, nous laissons les autres s'en charger
end
top

Directive LuaHookPreTranslate

Description:Fournit un point d'entrée pour la phase de pré-traduction du traitement d'une requête
Syntaxe:LuaHookPreTranslate /path/to/lua/script.lua hook_function_name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Identique à LuaHookTranslateName, mais s'exécute au cours de la phase de pré-traduction où les pourcentages du chemin de l'URI ne sont pas encore décodés.

top

Directive LuaHookTranslateName

Description:Fournit un point d'entrée à la phase du nom de traduction du traitement de la requête
Syntaxe:LuaHookTranslateName /chemin/vers/lua/script.lua nom_fonction_hook [early|late]
Contexte:configuration globale, serveur virtuel
Surcharges autorisées:All
Statut:Extension
Module:mod_lua
Compatibilité:Le troisième argument optionnel est disponible depuis la version 2.3.15 du serveur HTTP Apache.

Cette directive permet d'ajouter un point d'entrée (à APR_HOOK_MIDDLE) à la phase du nom de traduction du traitement de la requête. La fonction hook accepte un seul argument, le request_rec, et doit renvoyer un code d'état qui est soit un code d'erreur HTTP, ou une constante définie dans le module apache2 : apache2.OK, apache2.DECLINED, ou apache2.DONE.

Pour ceux qui ne sont pas familiers avec les points d'entrée (hook), en gros, chaque hook sera invoqué jusqu'à ce que l'un d'entre eux renvoie apache2.OK. Si un hook n'effectuer pas la traduction, il doit juste renvoyer apache2.DECLINED. Si le traitement de la requête doit être interrompu, la valeur renvoyée doit être apache2.DONE.

Exemple :

# httpd.conf
LuaHookTranslateName "/scripts/conf/hooks.lua" silly_mapper
-- /scripts/conf/hooks.lua --
require "apache2"
function silly_mapper(r)
    if r.uri == "/" then
        r.filename = "/var/www/home.lua"
        return apache2.OK
    else
        return apache2.DECLINED
    end
end

Contexte

Cette directive ne peut être utilisée ni à l'intérieur d'une section <Directory> ou <Files>, ni dans un fichier htaccess.

Ordonnancement

Les arguments optionnels "early" ou "late" permettent de contrôler le moment auquel ce script s'exécute par rapport aux autres modules.

top

Directive LuaHookTypeChecker

Description:Fournit un point d'entrée pour la phase type_checker du traitement de la requête
Syntaxe:LuaHookTypeChecker /chemin/vers/lua/script.lua hook_function_name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette directive fournit un point d'entrée pour la phase type_checker du traitement de la requête. Cette phase correspond au moment où la requête se voit assigner un type et un gestionnaire de contenu, et peut donc être utilisée pour modifier le type et le gestionnaire en fonction de l'entrée :

LuaHookTypeChecker "/path/to/lua/script.lua" type_checker
    function type_checker(r)
        if r.uri:match("%.to_gif$") then -- foo.png.to_gif convient
            r.content_type = "image/gif" -- affectation du type image/gif
            r.handler = "gifWizard"      -- force le traitement de la requête par le module gifWizard
            r.filename = r.uri:gsub("%.to_gif$", "") -- corrige le nom du fichier demandé
            return apache2.OK
        end

        return apache2.DECLINED
    end
top

Directive LuaInherit

Description:Contrôle la manière dont les sections de configuration parentes sont fusionnées dans les enfants
Syntaxe:LuaInherit none|parent-first|parent-last
Défaut:LuaInherit parent-first
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua
Compatibilité:Versions 2.4.0 et supérieures

Par défaut, si des directives LuaHook* se trouvent dans des sections de configuration Directory ou Location qui se chevauchent, les scripts définis dans les sections les plus spécifiques s'exécutent après ceux définis dans les sections plus génériques (LuaInherit parent-first). Vous pouvez inverser cet ordre, ou faire en sorte que le contexte parent ne s'applique pas du tout.

Jusqu'aux versions 2.3.x, le comportement par défaut consistait à ignorer les directives LuaHook* situées dans les sections de configuration parentes.

top

Directive LuaInputFilter

Description:Fournit une fonction Lua pour le filtrage en entrée
Syntaxe:LuaInputFilter filter_name /path/to/lua/script.lua function_name
Contexte:configuration globale
Statut:Extension
Module:mod_lua
Compatibilité:Disponible depuis la version 2.4.5 du serveur HTTP Apache

Cette directive permet d'ajouter un filtre en entrée sous la forme d'une fonction Lua. A l'instar des filtres en sorties, les filtres en entrée fonctionnent comme des sous-routines, intervenant dans un premier temps avant l'envoi du contenu des tampons, puis chaque fois qu'un paquet de données doit être transmis à la chaîne, et éventuellement produisant toute donnée à ajouter aux données en entrée. La variable globale bucket contient les paquets de données tels qu'ils sont transmis au script Lua :

LuaInputFilter myInputFilter "/www/filter.lua" input_filter
<Files "*.lua">
  SetInputFilter myInputFilter
</Files>
--[[
    Exemple de filtre en entrée qui convertit toutes les données POST en
    majuscules.
]]--
function input_filter(r)
    print("luaInputFilter called") -- pour débogage
    coroutine.yield() -- attend des paquets de données
    while bucket do -- Pour chaque paquet, faire ...
        local output = string.upper(bucket) -- Convertit toutes les données POST en majuscules
        coroutine.yield(output) -- Envoie les données traitées à la chaîne de filtrage
    end
    -- plus aucune donnée à traiter.
    coroutine.yield("&filterSignature=1234") -- Ajoute une signature à la fin
end

Le filtre en entrée peut interdire ou sauter un filtre s'il est considéré comme indésirable :

function input_filter(r)
    if not good then
        return -- Empêche tout simplement le filtrage et transmet le contenu original
    end
    coroutine.yield() -- attend des paquets de données
    ...               -- insert les filtres ici
end

Voir "Modification de contenu avec les filtres Lua" pour plus de détails.

top

Directive LuaMapHandler

Description:Met en correspondance un chemin avec un gestionnaire lua
Syntaxe:LuaMapHandler modele-uri /chemin/vers/lua/script.lua [nom-fonction]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette directive permet de faire correspondre un modèle d'uri avec une fonction de gestionnaire située dans un fichier spécifique. Elle utilise les expressions rationnelles PCRE pour mettre en correspondance l'uri, et supporte les groupes de correspondance d'interpolation dans le chemin du fichier et le nom de la fonction. Prenez garde aux problèmes de sécurité en écrivant vos expressions rationnelles.

Exemples :

LuaMapHandler "/(\w+)/(\w+)" "/scripts/$1.lua" "handle_$2"

Cette directive va faire correspondre des uri comme /photos/show?id=9 au fichier /scripts/photos.lua, et invoquera la fonction de gestionnaire handle_show au niveau de la vm lua après chargement de ce fichier.

LuaMapHandler "/bingo" "/scripts/wombat.lua"

Cette directive invoquera la fonction "handle" qui est la valeur par défaut si aucun nom de fonction spécifique n'est spécifié.

top

Directive LuaOutputFilter

Description:Fournit une fonction Lua pour le filtrage de contenu en sortie
Syntaxe:LuaOutputFilter filter_name /path/to/lua/script.lua function_name
Contexte:configuration globale
Statut:Extension
Module:mod_lua
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

>Cette directive permet d'ajouter un filtre en sortie sous la forme d'une fonction Lua. A l'instar des filtres en sorties, les filtres en entrée fonctionnent comme des sous-routines, intervenant dans un premier temps avant l'envoi du contenu des tampons, puis chaque fois qu'un paquet de données doit être transmis à la chaîne, et éventuellement produisant toute donnée à ajouter aux données en sortie. La variable globale bucket contient les paquets de données tels qu'ils sont transmis au script Lua :

LuaOutputFilter myOutputFilter "/www/filter.lua" output_filter
<Files "*.lua">
  SetOutputFilter myOutputFilter
</Files>
--[[
    Exemple de filtre en sortie qui échappe toutes les entités HTML en
    sortie
]]--
function output_filter(r)
    coroutine.yield("(Handled by myOutputFilter)<br/>\n") -- Ajoute des données au début de la sortie,
                                                                -- puis attend des paquets de données à traiter
    while bucket do -- Pour chaque paquet, faire ...
        local output = r:escape_html(bucket) -- Echappe les données en sortie
        coroutine.yield(output) -- Envoie les données traitées à la chaîne
    end
    -- plus aucune donnée à traiter.
end

Comme les filres en entrée, le filtre en sortie peut interdire ou sauter un filtre s'il est considéré comme indésirable :

function output_filter(r)
    if not r.content_type:match("text/html") then
        return -- Empêche tout simplement le filtrage et transmet le contenu original
    end
    coroutine.yield() -- attend des paquets de données
    ...               -- insert les filtres ici
end

Les filtres Lua avec mod_filter

Lorsqu'on utilise un filtre Lua comme fournisseur sous-jacent via la directive FilterProvider, le filtrage ne fonctionnera que si filter-name est identique à provider-name.

Voir "Modification de contenu avec les filtres Lua" pour plus de détails.

top

Directive LuaPackageCPath

Description:Ajoute un répertoire au package.cpath de lua
Syntaxe:LuaPackageCPath /chemin/vers/include/?.soa
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette directive permet d'ajouter un chemin à la liste des chemins de recherche des bibliothèques partagées de lua. Ceci modifie le package.cpath dans les vms lua.

top

Directive LuaPackagePath

Description:Ajoute un répertoire au package.path de lua
Syntaxe:LuaPackagePath /chemin/vers/include/?.lua
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette directive permet d'ajouter un chemin à la liste des chemins de recherche du module lua. Elle suit les mêmes conventions que lua. Ceci modifie le package.path dans les vms lua.

Exemples :

LuaPackagePath "/scripts/lib/?.lua"
LuaPackagePath "/scripts/lib/?/init.lua"
top

Directive LuaQuickHandler

Description:Fournit un point d'entrée pour la gestion rapide du traitement de la requête
Syntaxe:LuaQuickHandler /path/to/script.lua hook_function_name
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette phase s'exécute juste après l'attribution de la requête à un serveur virtuel, et permet d'effectuer certains traitements avant le déroulement des autres phases, ou de servir une requête sans avoir à la traduire, l'associer à un espace de stockage, etc... Comme cette phase s'exécute avant toute autre, les directives telles que <Location> ou <Directory> ne sont pas encore prises en compte, car Les URI n'ont pas encore été entièrement interprétés.

Contexte

Cette directive ne peut être utilisée ni à l'intérieur d'une section <Directory> ou <Files>, ni dans un fichier htaccess.

top

Directive LuaRoot

Description:Spécifie le chemin de base pour la résolution des chemins relatifs dans les directives de mod_lua
Syntaxe:LuaRoot /chemin/vers/un/répertoire
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette directive permet de spécifier le chemin de base qui sera utilisé pour évaluer tous les chemins relatifs dans mod_lua. En l'absence de cette directive, les chemins relatifs sont résolus par rapport au répertoire de travail courant, ce qui ne sera pas toujours approprié pour un serveur.

top

Directive LuaScope

Description:Une valeur parmi once, request, conn, thread -- la valeur par défaut est once
Syntaxe:LuaScope once|request|conn|thread|server [min] [max]
Défaut:LuaScope once
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_lua

Cette directive permet de spécifier la durée de vie de l'interpréteur Lua qui sera utilisé dans ce "répertoire". La valeur par défaut est "once".

once:
utilise l'interpréteur une fois.
request:
utilise l'interpréteur pour traiter tout ce qui est basé sur le même fichier dans la requête, et qui se trouve aussi dans la portée de la requête.
conn:
idem request, mais attaché à connection_rec
thread:
Utilise l'interpréteur pendant toute la durée de vie du thread qui traite la requête (disponible seulement avec les MPMs threadés).
server:
Le comportement est ici différent, car la portée du serveur présente une durée de vie assez longue, et plusieurs threads vont partager le même server_rec. Pour gérer tout ceci, les états lua du serveur sont stockés dans une liste de ressources apr. Les arguments min et max permettent de spécifier les nombres minimaux et maximaux d'états lua à stocker dans la liste.

En général, les portées thread et server sont 2 à 3 fois plus rapides que les autres, car elles n'ont pas besoin de régénérer de nouveaux états Lua à chaque requête (comme c'est le cas avec le MPM event, où même les connexions persistantes utilisent un nouveau thread pour chaque requête). Si vous pensez que vos scripts n'auront pas de problème s'il réutilisent un état, alors les portées thread ou server doivent être utilisées car elles présenteront de meilleures performances. Alors que la portée thread fournira les réponses les plus rapides, la portée server utilisera moins de mémoire car les états sont rassemblés dans des jeux, permettant par exemple à 1000 threads de partager 100 états Lua, ne nécessitant ainsi que 10% de la mémoire requise par la portée thread.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_mime.html.fr.utf80000664000175100017510000021503014740503670021564 0ustar covenercovener mod_mime - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_mime

Langues Disponibles:  en  |  fr  |  ja 

Description:Associe les extensions des fichiers demandés avec l'action déclenchée par ces fichiers et avec leur contenu (type MIME, langue, jeu de caractère et codage)
Statut:Base
Identificateur de Module:mime_module
Fichier Source:mod_mime.c

Sommaire

Ce module permet d'assigner des métadonnées aux contenus sélectionnés pour une réponse HTTP, en associant des modèles d'URI ou de noms de fichiers aux valeurs des métadonnées. Par exemple, les extensions de noms de fichiers définissent souvent le type de médium Internet, la langue, le jeu de caractères et le codage du contenu. Ces informations sont relayées par les messages HTTP véhiculant ces contenus, et utilisées au cours de la négociation de contenu lors de la sélection des différentes possibilités, de manière à ce que les préférences des utilisateurs soient respectées lors du choix d'un contenu à servir parmi plusieurs autres contenus. Voir mod_negotiation pour plus d'informations à propos de la négociation de contenu.

Les directives AddCharset, AddEncoding, AddLanguage et AddType permettent d'associer des extensions de fichiers aux métadonnées de ces fichiers. Elles définissent respectivement le jeu de caractères, le codage du contenu, la langue du contenu et le type de médium (content-type) des documents. La directive TypesConfig permet de spécifier un fichier qui contient lui-même des associations entre extensions et types de media.

De plus, mod_mime peut définir le gestionnaire et les filtres qui sont à l'origine du contenu et le traitent. Les directives AddHandler, AddOutputFilter, et AddInputFilter permettent de contrôler les modules ou les scripts qui vont servir le document. La directive MultiviewsMatch permet à mod_negotiation de déterminer les extensions de fichiers à inclure lors des tests de correspondances multivues.

Alors que mod_mime associe des métadonnées avec des extensions de fichiers, le serveur de base core fournit des directives permettant d'associer tous les fichiers d'un conteneur donné (par exemple <Location>, <Directory>, ou <Files>) avec des métadonnées particulières. Parmi ces directives, on trouve ForceType, SetHandler, SetInputFilter, et SetOutputFilter. Les directives du serveur de base l'emportent sur toute directive d'association d'extensions de noms de fichiers définie par mod_mime.

Notez que la modification des métadonnées d'un fichier ne modifie pas la valeur de l'en-tête Last-Modified. Ainsi, certaines copies de documents préalablement mises en cache peuvent encore être utilisées par un client ou un mandataire avec les anciens en-têtes. Si vous modifiez les métadonnées (langue, type de contenu, jeu de caractère ou codage), vous devez donc enregistrer une modification du fichier concerné (afin de mettre à jour sa date de dernière modification), pour être sûr que tous les visiteurs recevront le documents avec les en-têtes corrects.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Fichiers avec extensions multiples

Les fichiers peuvent posséder plusieurs extensions dont l'ordre est normalement sans importance. Par exemple, si le fichier welcome.html.fr est associé au type de contenu text/html et à la langue française, le fichier welcome.fr.html possèdera exactement les même métadonnées. Si le fichier possède plusieurs extensions associées au même type de métadonnée, c'est celle de ces extensions la plus à droite qui sera utilisée, excepté pour ce qui concerne les langues et les codages de contenu. Par exemple, si .gif est associé au type de médium image/gif, et .html au type de médium text/html, le fichier welcome.gif.html sera associé au type de médium text/html.

Les Languages et les codages de contenu sont traités de manière cumulative, car il est possible d'assigner plusieurs langues ou codages à une ressource particulière. Par exemple, le fichier welcome.html.en.de sera servi avec les en-têtes Content-Language: en, de et Content-Type: text/html.

Des précautions doivent être prises lorsqu'un fichier avec extensions multiples est associé à la fois à un type de médium et à un gestionnaire. En général, cela impliquera la gestion de la requête par le module associé au gestionnaire. Par exemple, si l'extension .imap est associée au gestionnaire imap-file (du module mod_imagemap), et si l'extension .html est associée au type de médium text/html, le fichier world.imap.html sera à la fois associé au gestionnaire imap-file et au type de médium text/html. Pour son traitement, c'est le gestionnaire imap-file qui sera utilisé, et il sera donc traité en tant que fichier imagemap.

Si vous préférez que seule la dernière partie d'un nom de fichier séparée du reste du nom par un point soit associée à une métadonnée particulière, n'utilisez pas les directives Add*. Par exemple, si vous souhaitez que le fichier foo.html.cgi soit traité en tant que script CGI, mais pas le fichier bar.cgi.html, alors, au lieu d'utiliser AddHandler cgi-script .cgi, utilisez plutôt :

Configuration du gestionnaire en se basant seulement sur la dernière extension

<FilesMatch "[^.]+\.cgi$">
  SetHandler cgi-script
</FilesMatch>
top

Codage du contenu

Un fichier d'un type de médium particulier peut être également codé d'une certaine manière pour simplifier sa transmission sur Internet. Alors que cela concerne en général la compression, comme gzip, il peut aussi s'agir de chiffrement, comme pgp ou d'un codage comme UUencoding, qui est conçu pour transmettre un fichier binaire sous un format ASCII (texte).

La RFC HTTP/1.1, section 14.11 stipule à ce titre :

Le champ d'en-tête Content-Encoding de l'entité est utilisé en tant que modificateur du type de médium. Lorsqu'il est présent, sa valeur indique quels codages de contenu additionnels ont été appliqués au corps de l'entité, et ainsi quels mécanismes de décodage doivent être appliqués afin de retrouver le type de médium référencé par le champ d'en-tête Content-Type. Le codage de contenu est principalement utilisé pour permettre la compression d'un document sans perdre l'information concernant le type de médium sous-jacent.

En utilisant plusieurs extensions (voir la section ci-dessus à propos des extensions de fichiers multiples), vous pouvez indiquer qu'un fichier est d'un type, particulier, et possède aussi un codage particulier.

Considérons par exemple un fichier contenant un document Microsoft Word et compressé par pkzip pour réduire sa taille. Si l'extension .doc est associée au type de fichier Microsoft Word, et si l'extension .zip est associée au codage de fichier pkzip, alors le fichier Resume.doc.zip sera identifié comme document Word compressé par pkzip.

Apache joint un en-tête Content-encoding à la ressource afin d'informer le navigateur client à propos de la méthode de codage.

Content-encoding: pkzip
top

Jeux de caractères et langues

En plus du type de fichier et du codage, un autre élément important d'information est la langue dans laquelle le document est écrit, et avec quel jeu de caractères le contenu du fichier doit être affiché. Par exemple, un document peut être écrit en alphabet vietnamien ou cyrillique, et doit être affiché en conséquence. Cette information est également transmise via des en-têtes HTTP.

Les jeu de caractères, langue, codage et type MIME sont tous utilisés au cours du processus de négociation de contenu (voir mod_negotiation) afin de déterminer quel document servir au client, lorsque plusieurs choix sont possibles en fonction du jeu de caractères, de la langue, du codage ou du type MIME. Toutes les associations d'extensions de noms de fichiers créées via les directives AddCharset, AddEncoding, AddLanguage et AddType (ainsi que les associations d'extensions listées dans le fichier défini par la directive MimeMagicFile), participent à ce processus de sélection. Les extensions de noms de fichiers qui n'ont été associés que par des directives AddHandler, AddInputFilter ou AddOutputFilter, peuvent être incluses ou exclues du processus de sélection en utilisant la directive MultiviewsMatch.

Jeu de caractères

Pour transmettre cette information supplémentaire, Apache peut ajouter un en-tête Content-Language, afin de spécifier la langue dans laquelle le document est écrit, et peut ajouter des informations additionnelles à l'en-tête Content-Type pour indiquer le jeu de caractères particulier qui doit être utilisé pour restituer correctement le document.

Content-Language: en, fr Content-Type: text/plain; charset=ISO-8859-1

La langue est spécifiée via son abréviation en deux lettres. Le jeu de caractères est le nom du jeu de caractères particulier qui doit être utilisé.

top

Directive AddCharset

Description:Associe les extensions de noms de fichiers spécifiées au jeu de caractères spécifié
Syntaxe:AddCharset jeu-car extension [extension] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive AddCharset permet d'associer les extensions de noms de fichiers spécifiées au jeu de caractères spécifié (le nom enregistré sur l'Internet d'un codage de caractères donné). jeu-car est le paramètre jeu de caractères du type de médium pour les ressources dont le nom de fichier contient extension. Cette association est ajoutée à toutes les autres déjà en vigueur, et écrase toute association préexistante pour la même extension.

Exemple

AddLanguage ja .ja
AddCharset EUC-JP .euc
AddCharset ISO-2022-JP .jis
AddCharset SHIFT_JIS .sjis

Avec cet exemple, le document xxxx.ja.jis sera traité en tant que document japonais dont le jeu de caractère est ISO-2022-JP (idem pour le document xxxx.jis.ja). La directive AddCharset sert à la fois à informer le client sur le codage des caractères du document afin que ce dernier puisse être interprété et affiché correctement, et à la négociation de contenu, au cours de laquelle le serveur décide lequel parmi plusieurs documents possibles il renvoie au client en fonction des préférences de ce dernier en matière de jeu de caractères.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial. Les noms de fichiers peuvent posséder plusieurs extensions, et l'argument extension sera comparé à chacune d'entre elles.

Voir aussi

top

Directive AddEncoding

Description:Associe les extensions de noms de fichiers données au type de codage spécifié
Syntaxe:AddEncoding codage extension [extension] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive AddEncoding permet d'associer les extensions de noms de fichiers données au codage de contenu HTTP spécifié. codage est le codage de contenu HTTP à ajouter à la valeur du champ d'en-tête Content-Encoding pour les documents possédant l'extension spécifiée. Cette association est ajoutée à toutes les autres déjà en vigueur, et écrase toute association préexistante pour la même extension.

Exemple

AddEncoding x-gzip .gz
AddEncoding x-compress .Z

Avec cet exemple, les noms de fichiers possédant l'extension .gz seront marqués comme codés à l'aide du codage x-gzip, et les noms de fichiers possédant l'extension .Z comme codés avec x-compress.

Les clients anciens n'acceptent que x-gzip et x-compress, bien que les standards stipulent qu'ils sont respectivement équivalents à gzip et compress. Apache effectue ses comparaisons de codages de contenu en ignorant tout préfixe x-. Lorsqu'il répond avec un codage, Apache utilise l'une ou l'autre forme (c'est à dire x-foo ou foo) selon les besoins du client. Si le client n'a pas besoin d'une forme particulière, Apache utilisera la forme employée par la directive AddEncoding. Pour résumer, vous devez toujours utiliser x-gzip et x-compress pour ces deux codages spécifiques. Certains codages plus récents, comme deflate, doivent être spécifiés sans le préfixe x-.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial. Les noms de fichiers peuvent posséder plusieurs extensions, et l'argument extension sera comparé à chacune d'entre elles.

top

Directive AddHandler

Description:Associe les extensions de noms de fichiers données au gestionnaire spécifié
Syntaxe:AddHandler nom-gestionnaire extension [extension] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

Les fichiers dont le nom a pour extension extension seront servis par le nom-gestionnaire spécifié. Cette association est ajoutée à toutes les autres déjà en vigueur, et écrase toute association préexistante pour la même extension. Par exemple, pour associer les scripts CGI avec l'extension de fichier .cgi, vous pouvez utiliser :

AddHandler cgi-script .cgi

Une fois cette ligne insérée dans votre fichier httpd.conf, tout fichier possédant l'extension .cgi sera traité en tant que programme CGI.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial. Les noms de fichiers peuvent posséder plusieurs extensions, et l'argument extension sera comparé à chacune d'entre elles.

Voir aussi

top

Directive AddInputFilter

Description:Associe les extensions de noms de fichiers aux filtres spécifiés qui traiteront les requêtes clients
Syntaxe:AddInputFilter filtre[;filtre...] extension [extension] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive AddInputFilter permet d'associer l'extension de nom de fichier extension aux filtres spécifiés qui traiteront les requêtes clients et les entrées POST à leur réception par le serveur. Ceci s'ajoute à toute définition de filtre préexistante, y compris la directive SetInputFilter. Cette association est ajoutée à toutes les autres déjà en vigueur, et écrase toute association préexistante pour la même extension.

Si plusieurs filtres sont spécifiés, ils doivent être séparés par des points-virgules et inscrits dans l'ordre selon lequel ils devront traiter le contenu. L'argument filtre est insensible à la casse.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial. Les noms de fichiers peuvent posséder plusieurs extensions, et l'argument extension sera comparé à chacune d'entre elles.

Voir aussi

top

Directive AddLanguage

Description:Associe l'extension de nom de fichier donnée à la langue spécifié
Syntaxe:AddLanguage symbole-langue extension [extension] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive AddLanguage permet d'associer l'extension de nom de fichier donnée à la langue spécifiée. Les fichiers dont l'extension correspond à la valeur de l'argument extension se voient attribuer la valeur de l'argument symbole-langue comme en-tête HTTP Content-Language en accord avec les identifiants de langues définis par la RFC 3066. Cette directive l'emporte sur toute association préexistante pour la même extension.

Exemple

AddEncoding x-compress .Z
AddLanguage en .en
AddLanguage fr .fr

Avec cet exemple, le document xxxx.en.Z sera traité en tant que document compressé de langue anglaise (idem pour le document xxxx.Z.en). Bien que la langue soit fournie au client, le navigateur n'utilise habituellement pas cette information. La directive AddLanguage est principalement utilisée au cours de la négociation de contenu, où le serveur choisit d'envoyer un document parmi plusieurs documents possibles en fonction de la préférence du client en matière de langue.

Si une extension fait l'objet de plusieurs associations de langues, c'est la dernière qui sera utilisée. Ainsi, dans le cas suivant,

AddLanguage en .en
AddLanguage en-gb .en
AddLanguage en-us .en

les documents possédant l'extension .en seront traités en tant que documents de langue en-us.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial. Les noms de fichiers peuvent posséder plusieurs extensions, et l'argument extension sera comparé à chacune d'entre elles.

Voir aussi

top

Directive AddOutputFilter

Description:Associe les extensions de noms de fichiers aux filtres spécifiés qui traiteront les réponses en provenance du serveur
Syntaxe:AddOutputFilter filtre[;filtre...] extension [extension] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive AddOutputFilter permet d'associer l'extension de nom de fichier définie par l'argument extension aux filtres qui traiteront les réponses en provenance du serveur avant de les envoyer au client. Ces filtres s'ajoutent à tout filtre défini par d'autres directives comme SetOutputFilter et AddOutputFilterByType. Cette association est fusionnée avec toute autre association en vigueur, et l'emporte sur toute association préexistante pour la même extension.

Avec l'exemple suivant, tous les fichiers .shtml seront traités en tant qu'inclusions côté serveur (SSI), et la sortie sera compressée à l'aide du module mod_deflate.

AddOutputFilter INCLUDES;DEFLATE shtml

Si plusieurs filtres sont spécifiés, ils doivent être séparés par des points-virgules et inscrits dans l'ordre selon lequel il devront traiter le contenu. L'argument filtre est insensible à la casse.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial. Les noms de fichiers peuvent posséder plusieurs extensions, et l'argument extension sera comparé à chacune d'entre elles.

Notez que toute définition de filtres via la directive AddOutputFilter remplace toutes les définitions précédentes effectuées via cette même directive.

# Filtre spécifié "DEFLATE"
AddOutputFilter DEFLATE shtml
<Location "/foo">
  # Filtre spécifié "INCLUDES", remplace "DEFLATE"
  AddOutputFilter INCLUDES shtml
</Location>
<Location "/bar">
  # Filtre spécifié "INCLUDES;DEFLATE", remplace "DEFLATE"
  AddOutputFilter INCLUDES;DEFLATE shtml
</Location>
<Location "/bar/baz">
  # Filtre spécifié "BUFFER", remplace "INCLUDES;DEFLATE"
  AddOutputFilter BUFFER shtml
</Location>
<Location "/bar/baz/buz">
  # Pas de filtre spécifié, suppression de "BUFFER"
  RemoveOutputFilter shtml
</Location>

Voir aussi

top

Directive AddType

Description:Associe les extensions de noms de fichiers au type de contenu spécifié
Syntaxe:AddType type-médium extension [extension] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive AddType permet d'associer les extensions de noms de fichiers données au type de contenu spécifié. type-médium est le Type MIME à utiliser pour les fichiers dont le nom possède l'extension extension. Cette association s'ajoute à toute autre association en vigueur, et l'emporte sur toute association préexistante pour la même extension.

Plutôt que d'éditer directement le fichier TypesConfig, il est recommandé d'utiliser la directive AddType pour ajouter de nouveaux types de médias.

Exemple

AddType image/gif .gif

Ou, pour spécifier plusieurs extensions dans une seule directive :

Exemple

AddType image/jpeg jpeg jpg jpe

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial. Les noms de fichiers peuvent posséder plusieurs extensions, et l'argument extension sera comparé à chacune d'entre elles.

Il est possible d'obtenir un effet similaire à celui de la directive LanguagePriority du module mod_negotiation en qualifiant un type de média avec qs :

Exemple

AddType application/rss+xml;qs=0.8 .xml

Ceci peut s'avérer utile dans certaines situations, par exemple lorsqu'un client qui a ajouté un en-tête Accept: */* à sa requête n'est pas en mesure de traiter le contenu renvoyé par le serveur.

À la base, cette directive configure le type de contenu généré pour les fichiers statiques servis à partir du système de fichiers. Dans le cas des ressources autres que les fichiers statiques pour lesquelles le générateur de la réponse spécifie en général un Content-Type, cette directive n'a aucun effet.

Note

Si aucun gestionnaire n'est explicitement défini pour une requête, le type de contenu spécifié sera aussi utilisé comme nom du gestionnaire.

Lorsqu'aucune directive comme SetHandler ou AddHandler ne s'applique à une requête, le nom de gestionnaire interne normalement défini par une de ces directives est en fait défini par le type de contenu spécifié par la présente directive.

Pour des raisons historiques, certains modules tiers comme mod_php peuvent adopter ce type de comportement pour prendre en compte la requête concernée.

Il est conseillé d'éviter les configurations qui reposent sur de tels types "synthétiques". En outre, les configurations qui limitent l'accès aux directives SetHandler ou AddHandler doivent aussi limiter l'accès à la directive AddType.

Voir aussi

top

Directive DefaultLanguage

Description:Définit un symbole de langue par défaut à affecter au champ d'en-tête Content-Language pour toutes les ressources dans le contexte courant auxquelles aucun symbole de langue n'a été associé.
Syntaxe:DefaultLanguage symbole-langue
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive DefaultLanguage permet d'indiquer à Apache que toutes les ressources du contexte courant (par exemple, toutes les ressources concernées par le conteneur <Directory> courant) qui ne possèdent pas d'extension de langue explicite (comme .fr ou .de tel que défini par la directive AddLanguage), verront leur en-tête HTTP Content-Language affecté de la langue symbole-langue. Ceci permet de marquer des arborescences de répertoires entières comme contenant des documents en français, par exemple, sans avoir à renommer chaque fichier. Notez qu'à la différence de l'utilisation des extensions pour spécifier des langues, DefaultLanguage ne permet de spécifier qu'une seule langue.

Si aucune directive DefaultLanguage n'est en vigueur, et si un fichier ne possède pas d'extension configurée par la directive AddLanguage, aucun champ d'en-tête Content-Language ne sera généré.

Exemple

DefaultLanguage en

Voir aussi

top

Directive ModMimeUsePathInfo

Description:Indique à mod_mime de traiter les éléments de path_info en tant que parties du nom de fichier
Syntaxe:ModMimeUsePathInfo On|Off
Défaut:ModMimeUsePathInfo Off
Contexte:répertoire
Statut:Base
Module:mod_mime

La directive ModMimeUsePathInfo permet de combiner le nom de fichier avec la partie path_info de l'URL pour appliquer les directives mod_mime à la requête. La valeur par défaut est Off - situation dans laquelle l'élément path_info est ignoré.

L'utilisation de cette directive est conseillée si vous utilisez un système de fichiers virtuel.

Exemple

ModMimeUsePathInfo On

Considérons une requête pour /index.php/foo.shtml, mod_mime ne traitera pas la requête entrante comme /index.php/foo.shtml et les directives comme AddOutputFilter INCLUDES .shtml ajouteront le filtre INCLUDES à la requête. Si la directive ModMimeUsePathInfo n'est pas définie, le filtre INCLUDES ne sera pas ajouté. Le fonctionnement sera identique dans le cas des chemins virtuels, tels que ceux définis par la directive <Location>

Voir aussi

top

Directive MultiviewsMatch

Description:Les types de fichiers qui seront inclus lors d'une recherche de correspondance de fichier avec les vues multiples (MultiViews)
Syntaxe:MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers [Handlers|Filters]
Défaut:MultiviewsMatch NegotiatedOnly
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive MultiviewsMatch permet trois comportements différents pour la fonctionnalité Multiviews du module mod_negotiation. Les vues multiples permettent d'associer une requête pour un fichier, par exemple index.html, à toute extension négociée s'ajoutant à la requête de base, par exemple index.html.en, index.html.fr, ou index.html.gz.

L'option NegotiatedOnly implique que toute extension s'ajoutant au nom de base doit correspondre à une extension de mod_mime reconnue pour la négociation de contenu, par exemple Charset, Content-Type, Language, ou Encoding. C'est la valeur d'option par défaut, et la contrainte la plus stricte dont les effets de bord inattendus sont les moins nombreux.

Pour inclure des extensions associées avec des gestionnaires et/ou des filtres, définissez la directive MultiviewsMatch avec les mots-clés Handlers, Filters, ou les deux. Si tous les autres facteurs sont égaux, c'est le fichier de plus petite taille qui sera servi ; par exemple, si le choix doit s'opérer entre index.html.cgi de 500 octets et index.html.pl de 1000 octets, c'est le fichier .cgi qui l'emportera dans cet exemple. Les utilisateurs de fichiers .asis auront avantage à utiliser l'option Handler, si les fichiers .asis sont associés au gestionnaire asis-handler.

Vous pouvez enfin autoriser l'association de toute extension avec l'option Any, même si mod_mime ne reconnaît pas l'extension. Ceci peut conduire à des résultats imprévisibles, comme l'envoi de fichiers .old ou .bak contrairement aux souhaits du webmaster.

Par exemple, la configuration suivante va permettre l'inclusion des extensions associées aux gestionnaires et aux filtres dans les vues multiples, tout en excluant les fichiers de type inconnu :

MultiviewsMatch Handlers Filters

L'utilisation de la directive MultiviewsMatch dans une section <Location> ou <LocationMatch> n'est pas permise.

Voir aussi

top

Directive RemoveCharset

Description:Supprime toute association de jeu de caractères pour un ensemble d'extensions de noms de fichiers
Syntaxe:RemoveCharset extension [extension] ...
Contexte:serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive RemoveCharset permet de supprimer toute association de jeu de caractères pour les fichiers dont les noms possèdent les extensions spécifiées. Ceci permet, au sein des fichiers .htaccess, d'annuler toute association héritée du répertoire parent ou de la configuration du serveur pour un répertoire particulier.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial.

Exemple

RemoveCharset .html .shtml
top

Directive RemoveEncoding

Description:Supprime toute association de codage de contenu pour un ensemble d'extensions de noms de fichiers
Syntaxe:RemoveEncoding extension [extension] ...
Contexte:serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive RemoveEncoding permet de supprimer toute association de codage pour les fichiers dont les noms possèdent les extensions spécifiées. Ceci permet, au sein des fichiers .htaccess, d'annuler toute association héritée du répertoire parent ou de la configuration du serveur pour un répertoire particulier. Voici un exemple d'utilisation de cette directive :

/foo/.htaccess:

AddEncoding x-gzip .gz
AddType text/plain .asc
<Files "*.gz.asc">
    RemoveEncoding .gz
</Files>

Avec cette configuration, le fichier foo.gz sera marqué comme codé avec gzip, mais foo.gz.asc sera marqué comme fichier texte non codé.

Note

Les directives RemoveEncoding étant traitées après toute directive AddEncoding, il est possible qu'elles annulent les effets de ces dernières si les deux apparaissent dans la configuration du même répertoire.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial.

top

Directive RemoveHandler

Description:Supprime toute association de gestionnaire à un ensemble d'extensions de noms de fichiers
Syntaxe:RemoveHandler extension [extension] ...
Contexte:serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive RemoveHandler permet de supprimer toute association de gestionnaire à des fichiers dont le nom possède l'extension donnée. Ceci permet, au sein des fichiers .htaccess, d'annuler toute association héritée du répertoire parent ou de la configuration du serveur pour un répertoire particulier. Voici un exemple d'utilisation de cette directive :

/foo/.htaccess:

AddHandler server-parsed .html

/foo/bar/.htaccess:

RemoveHandler .html

Avec cette dernière ligne, les fichiers .html du répertoire /foo/bar seront traités en tant que fichiers normaux, au lieu d'être traités en tant que candidats à l'interprétation (voir le module mod_include module).

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial.

top

Directive RemoveInputFilter

Description:Supprime toute association de filtre en entrée à un ensemble d'extensions de noms de fichiers
Syntaxe:RemoveInputFilter extension [extension] ...
Contexte:serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive RemoveInputFilter permet de supprimer toute association de filtre en entrée à des fichiers dont le nom possède l'extension donnée. Ceci permet, au sein des fichiers .htaccess, d'annuler toute association héritée du répertoire parent ou de la configuration du serveur pour un répertoire particulier.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial.

Voir aussi

top

Directive RemoveLanguage

Description:Supprime toute association de langue à un ensemble d'extensions de noms de fichiers
Syntaxe:RemoveLanguage extension [extension] ...
Contexte:serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive RemoveLanguage permet de supprimer toute association de langue à des fichiers dont le nom possède l'extension donnée. Ceci permet, au sein des fichiers .htaccess, d'annuler toute association héritée du répertoire parent ou de la configuration du serveur pour un répertoire particulier.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial.

top

Directive RemoveOutputFilter

Description:Supprime toute association de filtre en sortie à un ensemble d'extensions de noms de fichiers
Syntaxe:RemoveOutputFilter extension [extension] ...
Contexte:serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive RemoveOutputFilter permet de supprimer toute association de filtre en sortie à des fichiers dont le nom possède l'extension donnée. Ceci permet, au sein des fichiers .htaccess, d'annuler toute association héritée du répertoire parent ou de la configuration du serveur pour un répertoire particulier.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial.

Exemple

RemoveOutputFilter shtml

Voir aussi

top

Directive RemoveType

Description:Supprime toute association de type de contenu à un ensemble d'extensions de noms de fichiers
Syntaxe:RemoveType extension [extension] ...
Contexte:serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_mime

La directive RemoveType permet de supprimer toute association de type de médium à des fichiers dont le nom possède l'extension donnée. Ceci permet, au sein des fichiers .htaccess, d'annuler toute association héritée du répertoire parent ou de la configuration du serveur pour un répertoire particulier. Voici un exemple d'utilisation de cette directive :

/foo/.htaccess:

RemoveType .cgi

Cette ligne aura pour effet de supprimer tout traitement spécifique des fichiers .cgi dans le répertoire /foo/ et ses sous-répertoires, et les réponses contenant ce type de fichier ne possèderont pas de champ d'en-tête HTTP Content-Type.

Note

Les directives RemoveType sont traitées après toutes les directives AddType, et il est possible que les effets de ces dernières soient annulés si les deux types de directives sont présents au sein de la configuration du même répertoire.

L'argument extension est insensible à la casse et peut être spécifié avec ou sans le point initial.

top

Directive TypesConfig

Description:Le chemin du fichier mime.types
Syntaxe:TypesConfig chemin-fichier
Défaut:TypesConfig conf/mime.types
Contexte:configuration globale
Statut:Base
Module:mod_mime

La directive TypesConfig permet de définir le chemin du fichier de configuration des types de média. L'argument chemin-fichier est un chemin relatif au répertoire défini par la directive ServerRoot. Ce fichier contient la liste des associations par défaut des extensions de noms de fichiers aux types de contenus. La plupart des administrateurs utilisent le fichier mime.types fourni par leur système d'exploitation, qui associe les extensions de noms de fichiers courantes à la liste officielle des types de média enregistrés par l'IANA et maintenue à http://www.iana.org/assignments/media-types/index.html, ainsi qu'un grand nombre de types non officiels. Ce fichier permet de simplifier le fichier httpd.conf en fournissant la majorité des définitions de types de média, et ses définitions peuvent être écrasées par des directives AddType, selon les besoins. Il est déconseillé de modifier le contenu du fichier mime.types car il peut être remplacé lors d'une mise à jour du serveur.

Le fichier contient des lignes dont le format est identique à celui des arguments d'une directive AddType :

type-médium [extension] ...

Les extensions sont insensibles à la casse. Les lignes vides et les lignes commençant par un dièse (#) sont ignorées. Les lignes vides servent à compléter le fichier mime.types. Apache httpd peut encore déterminer ces types via le module mod_mime_magic.

Merci de ne pas soumettre de requêtes au Projet de Serveur HTTP Apache pour ajouter une entrée dans le fichier mime.types fourni, sauf si : 1) le type de médium est déjà enregistré à l'IANA 2) et si l'extension est largement acceptée et ne provoque pas de conflits d'extensions entre les différentes plate-formes. Les requêtes du type catégorie/x-sous-type seront systématiquement rejetées, ainsi que toute nouvelle extension de deux lettres, car elle ont de fortes chances d'entrer en conflit par la suite avec les inombrables langues préexistantes et les espaces de nommage des jeux de caractères.

Voir aussi

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_nw_ssl.html.fr.utf80000664000175100017510000002346514740503670022153 0ustar covenercovener mod_nw_ssl - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_nw_ssl

Langues Disponibles:  en  |  fr 

Description:Active le chiffrement SSL pour Netware
Statut:Base
Identificateur de Module:nwssl_module
Fichier Source:mod_nw_ssl.c
Compatibilité:NetWare seulement

Sommaire

Ce module active le chiffrement SSL sur un port spécifique. Il s'appuie sur la fonctionnalité de chiffrement SSL intégrée au système d'exploitation Netware.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive NWSSLTrustedCerts

Description:Liste de certificats clients supplémentaires
Syntaxe:NWSSLTrustedCerts nom-fichier [nom-fichier] ...
Contexte:configuration globale
Statut:Base
Module:mod_nw_ssl

Cette directive permet de spécifier une liste de fichiers (au format DER) contenant des certificats clients utilisés lors de l'établissement d'une connexion SSL mandatée. Chaque certificat client utilisé par un serveur doit être enregistré séparément dans son propre fichier .der.

top

Directive NWSSLUpgradeable

Description:Permet de promouvoir une connexion non SSL au statut de connexion SSL à la demande
Syntaxe:NWSSLUpgradeable [adresse-IP:]num-port
Contexte:configuration globale
Statut:Base
Module:mod_nw_ssl

Cette directive permet de promouvoir une connexion établie sur l'adresse IP et/ou le port spécifiés au statut de connexion SSL à la demande du client. L'adresse et/ou le port doivent avoir été définis au préalable par une directive Listen.

top

Directive SecureListen

Description:Active le chiffrement SSL pour le port spécifié
Syntaxe:SecureListen [adresse-IP:]num-port nom-certificat [MUTUAL]
Contexte:configuration globale
Statut:Base
Module:mod_nw_ssl

Cette directive permet de spécifier le port et le nom de certificat de style eDirectory qui seront utilisés pour activer le chiffrement SSL. En outre, un troisième paramètre optionnel permet d'activer l'authentification mutuelle.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_ajp.html.fr.utf80000664000175100017510000010633714740503670022661 0ustar covenercovener mod_proxy_ajp - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_ajp

Langues Disponibles:  en  |  fr  |  ja 

Description:Module de support AJP pour mod_proxy
Statut:Extension
Identificateur de Module:proxy_ajp_module
Fichier Source:mod_proxy_ajp.c
Compatibilité:Disponible à partir de la version 2.1 du serveur HTTP Apache

Sommaire

Ce module nécessite le chargement de mod_proxy. Il fournit le support du Protocole Apache JServ version 1.3 (nommé dans la suite de ce document AJP13).

Pour être en mesure d'exploiter le protocole AJP13, il est donc nécessaire de charger les modules mod_proxy et mod_proxy_ajp.

Avertissement

N'activez pas la fonctionnalité de mandataire avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Utilisation

Ce module permet de mandater en inverse un serveur d'application d'arrière-plan (comme Apache Tomcat) qui utilise le protocole AJP13. Son utilisation est similaire à celle d'un mandataire inverse HTTP, mais s'appuie sur le prefixe ajp:// :

Mandataire inverse simple

ProxyPass "/app" "ajp://backend.example.com:8009/app"

Les options telles que l'option secret de Tomcat (requise par défaut depuis Tomcat 8.5.51 et 9.0.31) peut tout simplement être ajoutée en tant que paramètre séparé à la fin des directives ProxyPass ou BalancerMember. Ce paramètre est disponible à partir de la version 2.4.42 du serveur HTTP Apache :

Mandataire inverse simple avec l'option secret

ProxyPass "/app" "ajp://backend.example.com:8009/app" secret=YOUR_AJP_SECRET

On peut aussi configurer un répartiteur de charge :

Mandataire inverse avec répartiteur de charge

<Proxy "balancer://cluster">
    BalancerMember "ajp://app1.example.com:8009" loadfactor=1
    BalancerMember "ajp://app2.example.com:8009" loadfactor=2
    ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass "/app" "balancer://cluster/app"

Notez qu'en général, la directive ProxyPassReverse n'est pas nécessaire. La requête AJP inclut l'en-tête host original fourni au mandataire, et le serveur d'application est sensé générer des en-têtes auto-référençants relatifs à cet hôte ; aucune réécriture n'est donc nécessaire.

La situation la plus courante dans laquelle la directive ProxyPassReverse est nécessaire se rencontre lorsque le chemin de l'URL au niveau du mandataire est différente de celle du serveur d'arrière-plan. Dans ce cas, un en-tête redirect peut être réécrit relativement à l'URL de l'hôte original (et non du serveur d'arrière-plan ajp:// URL) ; par exemple :

Réécriture d'un chemin mandaté

ProxyPass "/apps/foo" "ajp://backend.example.com:8009/foo"
ProxyPassReverse "/apps/foo" "http://www.example.com/foo"

Il est cependant préférable en général de déployer l'application sur le serveur d'arrière-plan avec le même chemin que sur le mandataire.

top

Variables d'environnement

Les variables d'environnement dont le nom possède le préfixe AJP_ sont transmises au serveur original en tant qu'attributs de requête AJP (le préfixe AJP_ étant supprimé du nom de la clé).

top

Vue d'ensemble du protocole

Le protocole AJP13 est orienté paquet. Le format binaire a été préféré, probablement pour des raisons de performances, au format texte pourtant plus lisible. Le serveur web communique avec le conteneur de servlets sur une connexion TCP. Pour diminuer la charge induite par le processus de création de socket, le serveur web va tenter d'utiliser des connexions TCP persistantes avec le conteneur de servlets, et de réutiliser les connexions pendant plusieurs cycles requêtes/réponse.

Lorsqu'une connexion a été assignée à une requête particulière, elle ne sera utilisée pour aucune autre jusqu'à ce que le cycle de traitement de la requête se soit terminé. En d'autres termes, il n'y a pas de multiplexage des requêtes sur une connexion. Ceci se traduit par un code beaucoup plus simple à chaque extrémité de la connexion, un nombre plus important de connexions étant cependant ouvertes en même temps.

Lorsque le serveur web a ouvert une connexion vers le conteneur de servlets, celle-ci peut se trouver dans l'un des états suivants :

Lorsqu'une connexion est assignée au traitement d'une requête particulière, les informations de base de cette dernière (comme les en-têtes HTTP, etc...) sont envoyées sur la connexion sous une forme très condensée (par exemple les chaînes courantes sont codées sous forme d'entiers). Vous trouverez des détails sur ce format plus loin dans la structure des paquets de requête. Si la requête possède un corps (content-length > 0), il est envoyé dans un paquet séparé immédiatement après.

A ce moment, le conteneur est probablement prêt à traiter la requête. Au cours de ce traitement, il peut renvoyer les messages suivants au serveur web :

Chaque message est associé à un paquet de données formaté différemment. Voir plus loin les structures des paquets de réponses pour plus de détails.

top

Structure de base des paquets

Ce protocole hérite en partie de XDR, mais il diffère sur de nombreux points (pas d'alignement sur 4 bits, par exemple).

AJP13 utilise les octets selon leur ordre d'arrivée par le réseau pour tous les types de données.

Le protocole comporte quatre types de données : octets, booléens, entiers et chaînes de caractères.

Octet
Un seul octet.
Booléen
Un seul octet, 1 = vrai, 0 = faux. L'utilisation d'autres valeurs non nulles (dans le style C) peut fonctionner dans certains cas, mais pas dans certains autres..
Entier
Un nombre compris entre 0 et 2^16 (32768), stocké sur 2 octets en débutant par l'octet de poids forts.
Chaîne
Une chaîne de taille variable (longueur limitée à 2^16). Elle est codée comme suit : les deux premiers octets représentent la longueur de la chaîne, les octets suivants constituent la chaîne proprement dite (y compris le '\0' final). Notez que la longueur encodée dans les deux premiers octets ne prend pas en compte le '\0' final, de la même manière que strlen. Cela peut prêter à confusion du point de vue de Java qui est surchargé de déclarations d'autoincrémentation étranges destinées à traiter ces terminateurs. Je suppose que le but dans lequel cela a été conçu ainsi était de permettre au code C d'être plus efficace lors de la lecture de chaînes en provenance du conteneur de servlets -- avec le caractère \0 final, le code C peut transmettre des références dans un seul tampon, sans avoir à effectuer de copie. En l'absence du caractère \0 final, le code C doit effectuer une copie afin de pouvoir tenir compte de sa notion de chaîne.

Taille du paquet

Selon la majorité du code, la taille maximale du paquet est de 8 * 1024 bytes (8K). La taille réelle du paquet est encodée dans l'en-tête.

En-têtes de paquet

Les paquets envoyés par le serveur vers le conteneur commencent par 0x1234. Les paquets envoyés par le conteneur vers le serveur commencent par AB (c'est à dire le code ASCII de A suivi du code ASCII de B). Ensuite, vient un entier (codé comme ci-dessus) représentant la longueur des données transmises. Bien que ceci puisse faire croire que la taille maximale des données est de 2^16, le code définit en fait ce maximum à 8K.

Format du paquet (Serveur->Conteneur)
Octet 0 1 2 3 4...(n+3)
Contenu 0x12 0x34 Taille des données (n) Data
Format du paquet (Conteneur->Serveur)
Octet 0 1 2 3 4...(n+3)
Contenu A B Taille des données (n) Data

Pour la plupart des paquets, le premier octet de la charge utile encode le type de message, à l'exception des paquets contenant un corps de requête envoyés du serveur vers le conteneur -- ils comportent un en-tête standard (0x1234 suivi de la taille du paquet), mais celui-ci n'est suivi d'aucun préfixe.

Le serveur web peut envoyer les messages suivants au conteneur de servlets :

Code Type de paquet Signification
2 Fait suivre la requête Débute le cycle de traitement de la requête avec les données qui suivent.
7 Arrêt Le serveur web demande au conteneur de s'arrêter.
8 Ping Le serveur web demande au conteneur de prendre le contrôle (phase de connexion sécurisée).
10 CPing Le serveur web demande au conteneur de répondre rapidement avec un CPong.
none Données Taille (2 octets) et les données correspondantes.

À des fins de sécurité, le conteneur n'effectuera réellement son Arrêt que si la demande provient de la machine par laquelle il est hébergé.

Le premier paquet Données est envoyé immédiatement après le paquet Faire suivre la requête par le serveur web.

Le conteneur de servlets peut envoyer les types de messages suivants au serveur web :

Code Type de paquet Signification
3 Envoi d'un tronçon de corps Envoi d'un tronçon de corps depuis le conteneur de servlets vers le serveur web (et probablement vers le navigateur).
4 Envoie les en-têtes Envoi des en-têtes de réponse depuis le conteneur de servlets vers le serveur web (et probablement vers le navigateur).
5 Fin de la réponse Marque la fin de la réponse (et par conséquent du cycle de traitement de la requête).
6 Réception du tronçon de corps suivant Réception de la suite des données de la requête si elles n'ont pas encore été entièrement transmises.
9 Réponse CPong La réponse à une requête CPing

Chacun des messages ci-dessus possède une structure interne différente dont vous trouverez les détails ci-dessous.

top

Structure des paquets de requête

Pour les messages de type Faire suivre la requête depuis le serveur vers le conteneur :

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

Les request_headers possèdent la structure suivante :

req_header_name :=
    sc_req_header_name | (string)  [voir ci-dessous pour la manière dont
    ceci est interprété]

sc_req_header_name := 0xA0xx (integer)

req_header_value := (string)

Les attributes sont optionnels et possèdent la structure suivante :

attribute_name := sc_a_name | (sc_a_req_attribute string)

attribute_value := (string)

Un des en-têtes les plus importants est content-length, car il indique si le conteneur doit ou non attendre un autre paquet immédiatement.

Description détaillée de la requête que le serveur fait suivre vers le conteneur

Préfixe de la requête

Pour toutes les requêtes, ce préfixe est 2. Voir ci-dessus pour les détails des autres codes de préfixes.

Méthode

La méthode HTTP, encodée sous la forme d'un seul octet :

Nom commandeCode
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

Les versions futures d'ajp13 pourront transmettre des méthodes supplémentaires, même si elles ne font pas partie de cette liste.

protocol, req_uri, remote_addr, remote_host, server_name, server_port, is_ssl

Les significations de ces éléments sont triviales. Ils sont tous obligatoires et seront envoyés avec chaque requête.

En-têtes

La structure de request_headers est la suivante : tout d'abord, le nombre d'en-têtes num_headers est encodé, suivi d'une liste de paires nom d'en-tête req_header_name / valeur req_header_value. Les noms d'en-têtes courants sont codés sous forme d'entiers afin de gagner de la place. Si le nom d'en-tête ne fait partie de la liste des en-têtes courants, il est encodé normalement (une chaîne de caractères préfixée par la taille). La liste des en-têtes courants sc_req_header_name avec leurs codes se présente comme suit (il sont tous sensibles à la casse) :

NomValeur du codeNom du code
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

Le code Java qui lit ceci extrait l'entier représenté par les deux premiers octets, et si le premier octet est '0xA0', il utilise l'entier représenté par le deuxième octet comme index d'un tableau de noms d'en-têtes. Si le premier octet n'est pas 0xA0, l'entier représenté par les deux octets est considéré comme la longueur d'une chaîne qui est alors lue.

Ceci ne peut fonctionner que si aucun nom d'en-tête ne possède une taille supérieure à 0x9FFF (==0xA000 - 1), ce qui est vraisemblable, bien qu'un peu arbitraire.

Note:

L'en-tête content-length est extrêmement important. S'il est présent et non nul, le conteneur considère que la requête possède un corps (une requête POST, par exemple), et lit immédiatement le paquet suivant dans le flux d'entrée pour extraire ce corps.

Attributs

Les attributs préfixés par ? (par exemple ?context) sont tous optionnels. Chacun d'eux est représenté par un octet correspondant au type de l'attribut et par sa valeur (chaîne ou entier). Ils peuvent être envoyés dans un ordre quelconque (bien que le code C les envoie dans l'ordre ci-dessous). Un code de terminaison spécial est envoyé pour signaler la fin de la liste des attributs optionnels. La liste des codes est la suivante :

InformationValeur codeType de valeurNote
?context0x01-Non implémenté actuellement
?servlet_path0x02-Non implémenté actuellement
?remote_user0x03String
?auth_type0x04String
?query_string0x05String
?jvm_route0x06String
?ssl_cert0x07String
?ssl_cipher0x08String
?ssl_session0x09String
?req_attribute0x0AStringNom (le nom de l'attribut vient ensuite)
?ssl_key_size0x0BInteger
?secret0x0CStringSupporté depuis la version 2.4.42
are_done0xFF-request_terminator

context et servlet_path ne sont pas définis actuellement par le code C, et la majorité du code Java ignore complètement ce qui est envoyé par l'intermédiaire de ces champs (il va même parfois s'interrompre si une chaîne est envoyée après un de ces codes). Je ne sais pas si c'est une bogue ou une fonctionnalité non implémentée, ou tout simplement du code obsolète, mais en tout cas, il n'est pris en charge par aucune des deux extrémités de la connexion.

remote_user et auth_type concernent probablement l'authentification au niveau HTTP, et contiennent le nom de l'utilisateur distant ainsi que le type d'authentification utilisée pour établir son identité (à savoir Basic, Digest).

query_string, ssl_cert, ssl_cipher, ssl_session et ssl_key_size contiennent les éléments HTTP et HTTPS correspondants.

jvm_route est utilisé dans le cadre des sessions persistantes, en associant une session utilisateur à une instance Tomcat particulière en présence de plusieurs répartiteurs de charge.

Le mot de passe est envoyé lorsque la directive ProxyPass ou BalancerMember utilise le paramètre secret=secret_keyword. Le serveur d'arrière-plan doit savoir utiliser les mots de passe et les valeurs doivent correspondre. request.secret ou requiredSecret sont documentés dans la configuration AJP d'Apache Tomcat.

Au delà de cette liste de base, tout autre attribut supplémentaire peut être envoyé via le code req_attribute 0x0A. Une paire de chaînes représentant le nom et la valeur de l'attribut est envoyée immédiatement après chaque instance de ce code. Les variables d'environnement sont transmises par cette méthode.

Enfin, lorsque tous les attributs ont été transmis, le terminateur d'attributs, 0xFF, est envoyé. Ce dernier indique à la fois la fin de la liste d'attributs et la fin du paquet de la requête

top

Structure du paquet de la réponse

Pour les messages que le conteneur peut renvoyer au serveur.

AJP13_SEND_BODY_CHUNK :=
  prefix_code   3
  chunk_length  (integer)
  chunk        *(byte)
  chunk_terminator (byte) Ox00


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)   [voir ci-dessous pour la manière
    dont ceci est interprété]

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)

Détails:

Envoi d'un tronçon de corps

Le tronçon se compose essentiellement de données binaires et est renvoyé directement au navigateur.

Envoi des en-têtes

Les code et message d'état correspondent aux code et message HTTP habituels (par exemple 200 et OK). Les noms d'en-têtes de réponses sont codés de la même façon que les noms d'en-têtes de requêtes. Voir ci-dessus le codage des en-têtes pour plus de détails à propos de la manière dont les codes se distinguent des chaînes.
Les codes des en-têtes courants sont ::

NomValeur code
Content-Type0xA001
Content-Language0xA002
Content-Length0xA003
Date0xA004
Last-Modified0xA005
Location0xA006
Set-Cookie0xA007
Set-Cookie20xA008
Servlet-Engine0xA009
Status0xA00A
WWW-Authenticate0xA00B

La valeur de l'en-tête est codée immédiatement après le code ou la chaîne du nom d'en-tête.

Fin de la réponse

Signale la fin de ce cycle de traitement de requête. Si le drapeau reuse est à true (toute valeur autre que 0 en langage C pur), cette connexion TCP peut être réutilisée pour traiter de nouvelles requêtes entrantes. Si reuse est à false (==0), la connexion sera fermée.

Réception d'un tronçon de corps

Le conteneur réclame la suite des données de la requête (dans le cas où la taille du corps était trop importante pour pouvoir être contenue dans le premier paquet envoyé, où lorsque la requête est fractionnée). Le serveur va alors envoyer un paquet contenant une quantité de données correspondant au minimum de la request_length, la taille maximale de corps envoyée (8186 (8 Koctets - 6)), et le nombre réel d'octets restants à envoyer pour ce corps de requête.
S'il ne reste plus de données à transmettre pour ce corps de requête (c'est à dire si le conteneur de servlets tente de lire au delà de la fin du corps), le serveur va renvoyer un paquet vide dont la charge utile est de longueur 0 et se présentant sous la forme (0x12,0x34,0x00,0x00).

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_express.html.fr.utf80000664000175100017510000003412514740503670023573 0ustar covenercovener mod_proxy_express - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_express

Langues Disponibles:  en  |  fr 

Description:Extension à mod_proxy pour le mandatement dynamique inverse de masse
Statut:Extension
Identificateur de Module:proxy_express_module
Fichier Source:mod_proxy_express.c
Compatibilité:Disponible à partir de la version 2.3.13 du serveur HTTP Apache

Sommaire

Ce module crée dynamiquement en masse des mandataires inverses en faisant correspondre l'en-tête Host: de la requête HTTP à un nom de serveur et une URL d'arrière-plan stockés dans un fichier DBM. Il est ainsi plus aisé d'utiliser un grand nombre de mandataires inverses sans avoir à modifier la configuration. Il est loin de posséder autant de fonctionnalités que mod_proxy_balancer qui propose aussi la croissance dynamique, mais il est conçu pour gérer un nombre beaucoup plus important de serveurs d'arrière-plan. Il convient parfaitement pour créer un commutateur HTTP frontal et pour les architectures Microservices.

Pour pouvoir être utilisé, ce module nécessite le chargement de mod_proxy.

Avertissement

N'activez le mandatement que si vous avez sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux pour votre réseau, et dans une plus large mesure pour Internet.

Limitations

  • Ce module n'est pas conçu pour remplacer les fonctionnalités dynamiques de mod_proxy_balancer. Par contre, il peut constituer une alternative légère et rapide à mod_rewrite lorsque ce dernier utilise la directive RewriteMap et le drapeau [P] pour le mandatement inverse à partir d'une table de correspondances.
  • Il ne supporte pas les mises en correspondance basées sur les expressions rationnelles ou les modèles.
  • Il émule :
    <VirtualHost *:80>
       ServerName front.end.server
       ProxyPass "/" "back.end.server:port"
       ProxyPassReverse "/" "back.end.server:port"
    </VirtualHost>
    En d'autres termes, l'URL dans son ensemble est ajoutée à l'URL d'arrière-plan correspondante, tout ceci dans le but de proposer un commutateur mandataire inverse simple mais rapide.
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive ProxyExpressDBMFile

Description:Chemin du fichier DBM.
Syntaxe:ProxyExpressDBMFile pathname
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy_express

La directive ProxyExpressDBMFile permet de définir le chemin du fichier DBM de correspondance Express. Ce fichier permet de faire correspondre le nom de serveur extrait de l'en-tête Host: de la requête entrante avec une URL d'arrière-plan.

Note

Ce fichier est élaboré à partir d'un fichier texte à l'aide de l'utilitaire httxt2dbm.

Fichier de correspondances ProxyExpress

##
##express-map.txt:
##

www1.example.com http://192.168.211.2:8080
www2.example.com http://192.168.211.12:8088
www3.example.com http://192.168.212.10

Création du fichier DBM

httxt2dbm -i express-map.txt -o emap

Configuration

ProxyExpressEnable on
ProxyExpressDBMFile emap
top

Directive ProxyExpressDBMType

Description:Type de fichier DBM.
Syntaxe:ProxyExpressDBMType type
Défaut:ProxyExpressDBMType default
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy_express

La directive ProxyExpressDBMType permet de définir le type de fichier DBM requis par le module. La valeur par défaut correspond au type DBM par défaut du fichier créé par l'utilitaire httxt2dbm.

Les valeurs possibles sont (mais toutes ne seront pas disponibles à l'exécution) :

ValueDescription
dbFichiers Berkeley DB
gdbmFichiers GDBM
ndbmFichiers NDBM
sdbmFichiers SDBM (toujours disponible)
defaulttype DBM par défaut
top

Directive ProxyExpressEnable

Description:Active la fonctionnalité du module.
Syntaxe:ProxyExpressEnable on|off
Défaut:ProxyExpressEnable off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy_express

La directive ProxyExpressEnable permet d'activer/désactiver le module.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_ftp.html.fr.utf80000664000175100017510000005052614740503670022676 0ustar covenercovener mod_proxy_ftp - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_ftp

Langues Disponibles:  en  |  fr 

Description:Module fournissant le support FTP à mod_proxy
Statut:Extension
Identificateur de Module:proxy_ftp_module
Fichier Source:mod_proxy_ftp.c

Sommaire

Pour pouvoir fonctionner, ce module requiert le chargement de mod_proxy. Il fournit le support du mandatement des sites FTP. Notez que le support FTP est actuellement limité à la méthode GET.

Ainsi, pour pouvoir traiter les requêtes FTP mandatées, mod_proxy, et mod_proxy_ftp doivent être chargés dans le serveur.

Avertissement

N'activez pas la fonctionnalité de mandataire avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Pourquoi les fichiers du type xxx ne sont-ils pas téléchargeables par FTP ?

Ce type particulier de fichier n'est probablement pas défini en temps que application/octet-stream dans le fichier de configuration mime.types de votre mandataire. La ligne suivante peut y remédier :

application/octet-stream   bin dms lha lzh exe class tgz taz

Vous pouvez aussi utiliser la directive ForceType pour définir par défaut tous les types de fichiers en tant que fichiers binaires :

ForceType application/octet-stream
top

Comment puis-je forcer le téléchargement FTP en mode ASCII du fichier xxx ?

Dans les rares siruations où vous devez télécharger un fichier spécifique en utilisant la méthode de transfert FTP ASCII (alors que le mode transfert par défaut est binary), vous pouvez modifier le mode de transfert de mod_proxy en suffixant la requête avec ;type=a pour forcer un transfert en mode ASCII (les listings de répertoires FTP sont cependant quant à eux transmis en mode ASCII).

top

Comment puis-je effectuer un chargement FTP ?

Actuellement, seule la méthode GET est supportée pour FTP dans mod_proxy. Vous pouvez par contre utiliser le chargement HTTP (POST or PUT) via un mandataire Apache.

top

Comment puis-je accéder par FTP à des fichiers situés en dehors de mon répertoire home ?

Un URI FTP est considéré comme relatif au répertoire home de l'utilisateur connecté. Hélas, vous ne pouvez pas utiliser /../ pour atteindre des répertoires de niveau supérieur, car les points sont interprétés par le navigateur et ne sont donc pas vraiment envoyés au serveur FTP. Pour traiter ce problème, une méthode nommée Squid %2f hack a été implémentée dans le mandataire FTP Apache ; cette solution est aussi utilisée par d'autres serveurs mandataires courants comme le Cache mandataire Squid. En préfixant par /%2f le chemin de votre requête, vous pouvez faire en sorte que le mandataire modifie le répertoire FTP racine en / (au lieu du répertoire home). Par exemple, pour extraire le fichier /etc/motd, vous pourriez utiliser l'URL :

ftp://utilisateur@serveur/%2f/etc/motd

top

Comment puis-je dissimuler le mot de passe FTP apparaissant en clair dans la ligne d'URL de mon navigateur ?

Apache utilise différentes stratégies pour effectuer une connexion à un serveur FTP à l'aide d'un nom d'utilisateur et d'un mot de passe. En l'absence de nom d'utilisateur et de mot de passe dans l'URL, Apache tente une connexion anonyme auprès du serveur FTP comme suit :

utilisateur : anonymous
mot de passe : apache-proxy@

Ceci fonctionne avec tous les serveurs FTP courants configurés pour accepter les connexions anonymes.

Pour une connexion personnalisée avec un nom d'utilisateur spécifique, vous pouvez intégrer ce dernier dans l'URL comme suit :

ftp://nom-utilisateur@serveur/mon-fichier

Si le serveur FTP demande un mot de passe pour ce nom d'utilisateur (ce qu'il est censé faire), Apache va renvoyer au client une réponse 401 (Autorisation requise), ce qui fera afficher au navigateur une boîte de dialogue utilisateur/mot de passe. Une fois le mot de passe saisi, la connexion est tentée à nouveau, et si elle réussit, la ressource demandée est présentée. L'avantage de cette procédure réside dans le fait que votre navigateur n'affiche pas le mot de passe en clair, ce qu'il aurait fait si vous aviez utilisé l'URL :

ftp://nom-utilisateur:mot-de-passe@serveur/mon-fichier

Note

Le mot de passe transmis de cette manière n'est pas chiffré lorsqu'il est envoyé. Il transite entre votre navigateur et le serveur mandataire Apache sous la forme d'une chaîne de texte en clair codée en base64, et entre le mandataire Apache et le serveur FTP en texte pur. Vous devez par conséquent réfléchir à deux fois avant d'accéder à votre serveur FTP via HTTP (et d'une manière générale avant d'accéder à vos fichiers personnels via FTP !) sur des canaux non sécurisés, car des oreilles indiscrètes pourraient intercepter votre mot de passe au cours de son transfert.

top

Pourquoi reçois-je un listing de fichiers alors que j'ai demandé le téléchargement d'un fichier ?

Apache examine l'URL de la requête afin de permettre la navigation dans les répertoires d'un serveur FTP ainsi que le téléchargement de fichiers. Si elle ressemble à un répertoire, ou contient des caractères génériques ("*?[{~"), alors Apache considère que c'est un listing qui est demandé, et non un téléchargement.

Vous pouvez désactiver le traitement spécial des noms contenant des caractères génériques. Voir à cet effet la directive ProxyFtpListOnWildcard.

top

Directive ProxyFtpDirCharset

Description:Définit le jeu de caractères des listings FTP mandatés
Syntaxe:ProxyFtpDirCharset character_set
Défaut:ProxyFtpDirCharset ISO-8859-1
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy_ftp
Compatibilité:Disponible à partir de la version 2.2.7 du serveur HTTP Apache. Déplacé depuis mod_proxy à partir de la version 2.3.5

La directive ProxyFtpDirCharset permet de définir le jeu de caractères à utiliser pour les listings FTP en HTML générés par mod_proxy_ftp.

top

Directive ProxyFtpEscapeWildcards

Description:Les caractères génériques dans les noms de fichiers doivent-ils être échappés lorsqu'ils sont envoyés au serveur FTP ?
Syntaxe:ProxyFtpEscapeWildcards on|off
Défaut:ProxyFtpEscapeWildcards on
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy_ftp
Compatibilité:Disponible depuis la version 2.3.3 du serveur HTTP Apache

La directive ProxyFtpEscapeWildcards permet de déterminer si les caractères génériques ("*?[{~") que contiennent les noms de fichiers demandés doivent être échappés pas un slash inversé avant d'être envoyés au serveur FTP. Il s'agit du comportement par défaut ; cependant, de nombreux serveurs FTP n'ont aucune connaissance de la notion d'échappement, et tentent de servir le fichier demandé sous sa forme littérale, en incluant les slashes inversés dans son nom.

Définissez cette directive à "off" pour permettre le téléchargement de fichiers dont les noms contiennent des caractères génériques depuis des serveurs FTP qui ne connaissent pas l'échappement des caractères génériques.

top

Directive ProxyFtpListOnWildcard

Description:Les caractères génériques dans les noms de fichiers demandés doivent-ils déclencher l'affichage d'un listing ?
Syntaxe:ProxyFtpListOnWildcard on|off
Défaut:ProxyFtpListOnWildcard on
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy_ftp
Compatibilité:Disponible depuis la version 2.3.3 du serveur HTTP Apache

La directive ProxyFtpListOnWildcard permet de déterminer si les caractères génériques ("*?[{~") que contiennent les noms de fichiers demandés provoquent l'affichage d'un listing de fichiers par mod_proxy_ftp au lieu de télécharger un fichier. Il s'agit de leur comportement par défaut (valeur on).

Définissez cette directive à "off" pour permettre le téléchargement de fichiers même si leur nom contient des caractères génériques.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_http.html.fr.utf80000664000175100017510000003131414740503670023056 0ustar covenercovener mod_proxy_http - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_http

Langues Disponibles:  en  |  fr 

Description:Module fournissant le support HTTP à mod_proxy
Statut:Extension
Identificateur de Module:proxy_http_module
Fichier Source:mod_proxy_http.c

Sommaire

Pour pouvoir fonctionner, ce module requiert le chargement de mod_proxy. Il fournit le support du mandatement des requêtes HTTP et HTTPS. mod_proxy_http supporte HTTP/0.9, HTTP/1.0 et HTTP/1.1. Il ne fournit aucune fonctionnalité de mise en cache. Si vous souhaitez mettre en oeuvre un mandataire qui assure aussi les fonctions de mise en cache, vous devez utiliser les services du module mod_cache.

Ainsi, pour pouvoir traiter les requêtes HTTP mandatées, mod_proxy, et mod_proxy_http doivent être chargés dans le serveur.

Avertissement

N'activez pas la fonctionnalité de mandataire avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Variables d'environnement

Outre les directives de configuration qui contrôlent le comportement de mod_proxy, plusieurs variables d'environnement permettent de contrôler le fournisseur du protocole HTTP. Parmi les variables suivantes, celle qui ne nécessitent pas de valeur particulière sont définies quelle que soit la valeur qu'on leur affecte.

proxy-sendextracrlf
Provoque l'envoi par le mandataire d'une nouvelle ligne CR-LF supplémentaire à la fin de la requête. Ceci constitue un moyen de contournement d'une bogue de certains navigateurs.
force-proxy-request-1.0
Force le mandataire à envoyer des requêtes vers le serveur cible selon le protocole HTTP/1.0 et désactive les fonctionnalités propres à HTTP/1.1.
proxy-nokeepalive
Force le mandataire à fermer la connexion avec le serveur cible après chaque requête.
proxy-chain-auth
Si le mandataire requiert une authentification, il va lire et exploiter les données d'authentification pour mandataire envoyées par le client. Si proxy-chain-auth est définie, il va aussi faire suivre ces données vers le mandataire suivant dans la chaîne. Ceci peut s'avérer nécessaire si une chaîne de mandataires partagent les informations d'authentification. Avertissement concernant la sécurité : Ne définissez cette variable que si vous êtes sûr d'en avoir besoin, car elle peut provoquer la divulgation d'informations sensibles !
proxy-sendcl
Avec HTTP/1.0, toutes les requêtes qui possèdent un corps (par exemple les requêtes POST) doivent comporter un en-tête Content-Length. Cette variable d'environnement force le mandataire Apache à envoyer cet en-tête au serveur cible, sans tenir compte de ce que lui a envoyé le client. Ceci permet d'assurer la compatibilité lorsqu'on mandate un serveur cible mettant en oeuvre un protocole de type HTTP/1.0 ou inconnu. Elle peut cependant nécessiter la mise en tampon de l'intégralité de la requête par le mandataire, ce qui s'avère très inefficace pour les requêtes de grande taille.
proxy-sendchunks ou proxy-sendchunked
Cette variable constitue l'opposé de proxy-sendcl. Elle permet la transmission des corps de requêtes vers le serveur cible en utilisant un codage de transfert fractionné. Ceci permet une transmission des requêtes plus efficace, mais nécessite que le serveur cible supporte le protocole HTTP/1.1.
proxy-interim-response
Cette variable peut prendre les valeurs RFC (valeur par défaut) ou Suppress. Les versions précédentes de httpd supprimaient les réponses intermédiaires HTTP (1xx) envoyées par le serveur cible. En pratique, si un serveur cible envoie une réponse intermédiaire, il se peut qu'il étende lui-même le protocole d'une manière dont nous n'avons pas connaissance, ou tout simplement non conforme. Le comportement du mandataire est donc maintenant configurable : définissez proxy-interim-response RFC pour être totalement compatible avec le protocole, ou proxy-interim-response Suppress pour supprimer les réponses intermédiaires.
proxy-initial-not-pooled
Si cette variable est définie, aucune connexion faisant partie d'un jeu ne sera réutilisée si la requête du client est la requête initiale pour une connexion. Ceci permet d'éviter le message d'erreur "proxy: error reading status line from remote server" causé par la situation de compétition au cours de laquelle le serveur cible ferme la connexion du jeu après la vérification de la connexion par le mandataire, et avant que les données envoyées par le mandataire n'atteignent le serveur cible. Il faut cependant garder à l'esprit que la définition de cette variable dégrade les performances, particulièrement avec les clients HTTP/1.0.
top

Informations sur les requêtes

mod_proxy_http enregistre les informations suivantes pour journalisation via le format %{NOMVAR}n dans les directives LogFormat ou ErrorLogFormat :

proxy-source-port
Le port local utilisé pour la connexion vers le serveur d'arrière-plan.
proxy-status
Le code d'état HTTP reçu du serveur d'arrière-plan.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_fcgi.html.fr.utf80000664000175100017510000006101014740503670023003 0ustar covenercovener mod_proxy_fcgi - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_fcgi

Langues Disponibles:  en  |  fr 

Description:Module fournissant le support de FastCGI à mod_proxy
Statut:Extension
Identificateur de Module:proxy_fcgi_module
Fichier Source:mod_proxy_fcgi.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

Pour fonctionner, ce module nécessite le chargement de mod_proxy. Il fournit le support du protocole FastCGI.

Ainsi, pour pouvoir traiter le protocole FastCGI, mod_proxy et mod_proxy_fcgi doivent être chargés dans le serveur.

A la différence de mod_fcgid et mod_fastcgi, mod_proxy_fcgi n'est pas en mesure de démarrer le processus de l'application ; fcgistarter est fourni à cet effet sur certaines plateformes. Le framework applicatif FastCGI utilisé peut aussi fournir la gestion des processus ou des lancements de programmes externes.

Avertissement

N'activez pas la fonctionnalité de mandataire avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples

Pour que ces exemples fonctionnent, vous ne devez pas oublier d'activer mod_proxy et mod_proxy_fcgi.

Instance d'application unique

ProxyPass "/mon_appli/" "fcgi://localhost:4000/"

mod_proxy_fcgi interdisant par défaut la réutilisation des connexions, lorsqu'une requête a été traitée, la connexion ne sera pas maintenue ouverte par le processus enfant httpd, et ne sera donc pas réutilisée. Cependant, si l'application FastCGI supporte les connexions httpd simultanées, vous pouvez opter pour la réutilisation des connexions comme dans l'exemple suivant :

Instance d'application unique, réutilisation des connexions (versions 2.4.11 et supérieures)

ProxyPass "/myapp/" "fcgi://localhost:4000/" enablereuse=on

Active la réutilisation des connexions vers un serveur FCGI d'arrière-plan tel que PHP-FPM

Il faut garder à l'esprit que PHP-FPM (en février 2018) utilise un modèle du style prefork ; autrement dit, chacun de ses processus de travail ne peut gérer qu'une connexion à la fois.
Par défaut et lorsqu'il est configuré avec enablereuse=on et lorsqu'un MPM à base de threads est utilisé (comme worker ou event), mod_proxy autorise un jeu de ThreadsPerChild connexions vers le serveur d'arrière-plan pour chaque processus httpd, et par conséquent, il faut prêter une attention particulière aux situations suivantes :

  • Avec une charge en HTTP/1, il est fort probable que le nombre de connexions vers le serveur FCGI d'arrière-plan augmente jusqu'à atteindre MaxRequestWorkers.
  • Avec une charge en HTTP/2, et vue la manière dont mod_http2 est implémenté, il y a des threads de travail h2 additionnels qui peuvent forcer la création de connexions supplémentaires vers le serveur d'arrière-plan. Le nombre total de connexions que contiennent les jeux de connexions peut alors dépasser MaxRequestWorkers.

Le nombre maximum de processus de travail PHP-FPM doit être défini judicieusement car il est possible qu'ils finissent par rester dans l'état occupé ("busy") pour ne gérer que des connexions persistantes inactives, sans avoir la possibilité d'en établir de nouvelles ; ce qui se traduira pour l'utilisateur final par une pile de "HTTP request timeouts".

Dans l'exemple suivant, l'URI de la requête est transmis en tant que chemin du système de fichiers pour l'exécution du démon PHP-FPM. L'URL de la requête est implicitement ajoutée au second paramètre. PHP-FPM est à l'écoute de l'hôte et du port qui suivent fcgi://. La conservation/réutilisation des connexions est activée.

PHP-FPM

ProxyPassMatch "^/myapp/.*\.php(/.*)?$" "fcgi://localhost:9000/var/www/" enablereuse=on

Dans l'exemple suivant, l'URI de la requête est transmis en tant que chemin du système de fichiers pour l'exécution du démon PHP-FPM. Dans ce cas cependant, PHP-FPM est à l'écoute d'un socket de domaine unix (UDS). Cette fonctionnalité est disponible à partir de la version 2.4.9. Avec cette syntaxe, si un nom d'hôte et un port sont ajoutés après fcgi://, ils seront ignorés.

PHP-FPM with UDS

ProxyPassMatch "^/(.*\.php(/.*)?)$" "unix:/var/run/php5-fpm.sock|fcgi://localhost/var/www/"

La passerelle à répartition de charge nécessite le chargement du module mod_proxy_balancer et d'au moins un module fournissant un algorithme de répartition de charge, comme mod_lbmethod_byrequests en plus des modules déjà cités. mod_lbmethod_byrequests est le module par défaut et sera utilisé dans cet exemple de configuration.

Passerelle à répartition de charge vers plusieurs instances de l'application

ProxyPass "/myapp/" "balancer://myappcluster/"
<Proxy "balancer://myappcluster/">
    BalancerMember "fcgi://localhost:4000"
    BalancerMember "fcgi://localhost:4001"
</Proxy>

Vous pouvez aussi forcer le traitement d'une requête en tant que requête de mandataire inverse en créant un court-circuiteur de gestionnaire approprié. Dans l'exemple ci-dessous, toutes les requêtes pour des scripts PHP seront transmises au serveur FastCGI spécifié par mandat inverse. Cette fonctionnalité est disponible à partir de la version 2.4.10 du serveur HTTP Apache. Pour des raisons de performances, il est recommandé de définir un worker (configuration d'un mandataire) représentant le même serveur fcgi:// d'arrière-plan. Avec cette configuration, il est possible d'effectuer une correspondance directe entre l'URI et le chemin du fichier sur le serveur, et le chemin local du fichier sera alors transmis au serveur d'arrière-plan. Lorsque FastCGI est configuré ainsi, le serveur est en mesure de calculer le PATH_INFO le plus approprié.

Mandataire via un gestionnaire

<FilesMatch "\.php$">
    # Note : la seule partie variable est /path/to/app.sock
    SetHandler  "proxy:unix:/path/to/app.sock|fcgi://localhost/"
</FilesMatch>
   # Définition d'une configuration de mandataire qui convient.
   # La partie qui est mise en correspondance avec la valeur de
   # SetHandler est la partie qui suit le "pipe". Si vous devez faire
   # une distinction, "localhost" peut être changé en un nom de serveur
   # unique.
   <Proxy "fcgi://localhost/" enablereuse=on max=10>
   </Proxy>

<FilesMatch ...>
    SetHandler  "proxy:fcgi://localhost:9000"
</FilesMatch>

<FilesMatch ...>
    SetHandler  "proxy:balancer://myappcluster/"
</FilesMatch>
top

Variables d'environnement

En plus des directives de configuration qui contrôlent le comportement de mod_proxy, de nombreuses variables d'environnement permettent de piloter le fournisseur du protocole FCGI :

proxy-fcgi-pathinfo
Lorsqu'il est configuré via les directives ProxyPass ou ProxyPassMatch, mod_proxy_fcgi ne définit pas la variable d'environnement PATH_INFO, ce qui permet au serveur FCGI d'arrière-plan de déterminer correctement SCRIPT_NAME et Script-URI, et de se conformer à la section 3.3 de la RFC 3875. Si au contraire vous avez souhaitez que mod_proxy_fcgi génère une "estimation la plus exacte possible" de PATH_INFO, définissez la variable d'environnement proxy-fcgi-pathinfo. Ceci peut servir de contournement pour une bogue présente dans certaines implémentations de FCGI. Cette variable peut être multivaluée afin de pouvoir choisir la valeur la plus appropriée (versions 2.4.11 et supérieures) :
first-dot
PATH_INFO est extrait à partir du slash qui suit le premier "." de l'URL.
last-dot
PATH_INFO est extrait à partir du slash qui suit le dernier "." de l'URL.
full
PATH_INFO est calculé en supposant que l'URL correspond au chemin du système de fichiers.
unescape
PATH_INFO correspond à la partie chemin de l'URL avec ses séquences d'échappement décodées.
toute autre valeur
PATH_INFO correspond à la partie chemin de l'URL. Auparavant, c'était la seule option pour proxy-fcgi-pathinfo.
top

Directive ProxyFCGIBackendType

Description:Spécifie le type de l'application FastCGI d'arrière-plan
Syntaxe:ProxyFCGIBackendType FPM|GENERIC
Défaut:ProxyFCGIBackendType FPM
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_proxy_fcgi
Compatibilité:Disponible à partir de la version 2.4.26 du serveur HTTP Apache

Cette directive permet de spécifier le type de l'application FastCGI d'arrière-plan. Certains serveurs FastCGI, comme PHP-FPM, utilisent de manière historique des variables d'environnement exotiques pour identifier le type du serveur mandataire utilisé. Définissez cette directive à "GENERIC" si votre application n'est pas de type PHP-FPM et n'interpréter pas correctement des variables d'environnement comme SCRIPT_FILENAME ou PATH_TRANSLATED telles qu'elles sont définies par le serveur.

SCRIPT_FILENAME est un exemple de valeur modifiée par la définition de cette directive. Historiquement, lorsqu'on utilisait le module mod_proxy_fcgi, SCRIPT_FILENAME était préfixé par la chaîne "proxy:fcgi://". C'est cette variable que lisent certaines applications FastCGI génériques en tant que valeur en entrée pour leur script ; cependant, PHP-FPM peut supprimer le préfixe, puis garder en mémoire qu'il communique avec Apache. Avec les versions 2.4.21 à 2.4.25, ce préfixe était automatiquement supprimé par le serveur, empêchant ainsi PHP-FPM de détecter et interopérer avec Apache dans certains scénarios.

top

Directive ProxyFCGISetEnvIf

Description:Permet d'adapter la valeur des variables envoyées aux serveurs FastCGI
Syntaxe:ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_proxy_fcgi
Compatibilité:Disponible à partir de la version 2.4.26 du serveur HTTP Apache.

Juste avant la transmission d'une requête au serveur FastCGI configuré, le coeur du programme du serveur web définit un certain nombre de variables d'environnement en fonction de certains détails de la requête considérée. Les programmes FastCGI utilisent souvent ces variables comme données en entrée afin de déterminer quels scripts sous-jacents ils vont exécuter, ou quelles données en sortie doivent être produites.

Voici quelques exemples de variables d'environnement importantes :

Cette directive permet de passer outre les variables d'environnement ci-dessus, entre autres. Elle est évaluée après la définition de la valeur initiale de ces variables ; elle peuvent donc être utilisées comme entrées dans les expressions définissants les conditions et les valeurs.

Syntaxe des paramètres :

conditional-expression
Définit une condition en fonction de laquelle la variable d'environnement qui suit sera modifiée ou non. Pour la syntaxe de cette expression, reportez-vous aux exemples qui suivent ou à la spécification détaillée dans le document ap_expr.
environment-variable-name
Spécifie le nom de la variable d'environnement à modifier, par exemple PATH_INFO. Si elle est précédée d'un point d'exclamation, la définition de la variable sera annulée.
value-expression
Spécifie la nouvelle valeur de la variable "environment-variable-name". On peut inclure des références arrières, comme "$1", issues de captures en provenance de l'expression rationnelle conditional-expression. Si cette valeur est omise, la variable est définie (ou sa valeur est écrasée) par une chaîne vide — voir cependant la note ci-après.
# Une modification basique, inconditionnelle
ProxyFCGISetEnvIf "true" PATH_INFO "/example"

# Utilisation d'une variable d'environnement pour spécifier la nouvelle valeur
ProxyFCGISetEnvIf "true" PATH_INFO "%{reqenv:SCRIPT_NAME}"

# Utilisation de captures dans la condition et de références arrières dans la # nouvelle valeur ProxyFCGISetEnvIf "reqenv('PATH_TRANSLATED') =~ m#(/.*prefix)(\d+)(.*)#" PATH_TRANSLATED "$1$3"

Note : Annulation définition ou valeur vide

La ligne suivante annule la définition de la variable VARIABLE, ce qui l'empêche d'être envoyée au serveur FastCGI :
ProxyFCGISetEnvIf true !VARIABLE
La ligne suivante, quant à elle, efface la valeur de la variable VARIABLE en lui affectant la chaîne vide ; cette variable VARIABLE sera alors tout de même envoyée au serveur FastCGI :
ProxyFCGISetEnvIf true VARIABLE
La spécification CGI/1.1 ne fait pas de distinction entre une variable contenant une chaîne vide et une variable qui n'existe pas. De nombreuses implémentations CGI et FastCGI font cependant cette distinction (ou permettent aux scripts de la faire). Le choix de celle que vous allez utiliser dépend de votre implémentation et de la raison qui vous pousse à modifier cette variable.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_hcheck.html.fr.utf80000664000175100017510000004537514740503670023340 0ustar covenercovener mod_proxy_hcheck - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_hcheck

Langues Disponibles:  en  |  fr 

Description:Check up dynamique des membres du groupe de répartition de charge (équipiers) pour mod_proxy
Statut:Extension
Identificateur de Module:proxy_hcheck_module
Fichier Source:mod_proxy_hcheck.c
Compatibilité:Disponible à partir de la version 2.4.21 du serveur HTTP Apache

Sommaire

Ce module permet d'effectuer un check up dynamique des membres du groupe de répartition de charge (équipiers). Ce check up peut être activé pour un ou plusieurs équipiers et il est indépendant des requêtes de mandataire inverse proprement dites.

Pour fonctionner, ce module nécessite le chargement préalable de mod_watchdog.

Paramètres

Le mécanisme de check up est activé via l'utilisation de paramètres supplémentaires de la directive BalancerMember configurés de manière standard via la directive ProxyPass :

Ce module définit un nouveau drapeau d'état status pour BalancerMember : "C". Lorsque l'équipier est mis hors service suite à un disfonctionnement déterminé par le module de check up, ce drapeau est activé et peut être lu (et modifié) via le balancer-manager.

Paramètre Défaut Description
hcmethod None Aucun check up dynamique n'est effectué. Les choix possibles sont :
MethodDescriptionNote
NoneAucun check up dynamique effectué
TCPVérifie qu'un socket vers le serveur d'arrière-plan peut être créé ; par exemple "es-tu en état de fonctionner"
OPTIONSEnvoie une requête HTTP OPTIONS au serveur d'arrière-plan via HTTP/1.0*
HEADEnvoie une requête HTTP HEAD au serveur d'arrière-plan via HTTP/1.0*
GETEnvoie une requête HTTP GET au serveur d'arrière-plan via HTTP/1.0*
OPTIONS11Envoie une requête HTTP OPTIONS au serveur d'arrière-plan via HTTP/1.1*
HEAD11Envoie une requête HTTP HEAD au serveur d'arrière-plan via HTTP/1.1*
GET11Envoie une requête HTTP GET au serveur d'arrière-plan via HTTP/1.1*
*: si hcexpr n'est pas utilisé, un retour HTTP 2xx ou 3xx sera interprété comme un passage avec succès du check up.
hcpasses 1 Nombre de check up à passer avec succès avant de remettre en service l'équipier
hcfails 1 Nombre de check up échoués avant mettre hors service l'équipier
hcinterval 30 Intervalle entre deux check up en secondes (par défaut effectué toutes les 30 secondes)
hcuri   URI supplémentaire à ajouter à l'URL de l'équipier pour le check up.
hctemplate   Nom du modèle créé via ProxyHCTemplate à utiliser pour définir les paramètres de check up de cet équipier
hcexpr   Nom de l'expression créée via ProxyHCExpr utilisée pour analyser les en-têtes de la réponse du check up.
Si ce paramètre est absent, un état HTTP de 2xx à 3xx est interprété comme un check up réussi.

Compatibilité :

OPTIONS11, HEAD11 et GET11 sont disponibles à partir de la version 2.4.55 du serveur HTTP Apache.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples d'utilisation

L'exemple suivant montre comment configurer le check up pour différents serveurs d'arrière-plan :

ProxyHCExpr ok234 {%{REQUEST_STATUS} =~ /^[234]/}
ProxyHCExpr gdown {%{REQUEST_STATUS} =~ /^[5]/}
ProxyHCExpr in_maint {hc('body') !~ /Under maintenance/}

<Proxy balancer://foo>
  BalancerMember http://www.example.com/  hcmethod=GET hcexpr=in_maint hcuri=/status.php
  BalancerMember http://www2.example.com/ hcmethod=HEAD hcexpr=ok234 hcinterval=10
  BalancerMember http://www3.example.com/ hcmethod=TCP hcinterval=5 hcpasses=2 hcfails=3
  BalancerMember http://www4.example.com/
</Proxy>

ProxyPass "/" "balancer://foo"
ProxyPassReverse "/" "balancer://foo"

Dans ce scénario, on teste l'équipier http://www.example.com/ en lui envoyant une requête GET /status.php et en regardant si la réponse contient la chaîne Under maintenance. Si c'est le cas, le check up est considéré comme ayant échoué et l'équipier est mis hors service. Ce check up dynamique est effectué toutes les 30 secondes, ce qui correspond à la valeur par défaut.

On teste l'équipier http://www2.example.com/ en lui envoyant simplement une requête HEAD toutes les 10 secondes et en vérifiant que la réponse HTTP est bien un code d'état de 2xx, 3xx ou 4xx. On teste l'équipier http://www3.example.com/ en vérifiant simplement toutes les 5 secondes que le socket vers ce serveur est bien opérationnel. Si ce serveur est marqué "hors service", il lui faudra 2 check up réussis pour être réactivé et participer à nouveau à la répartition de charge. Si à ce moment-là il échoue à 3 check up successifs, il sera à nouveau mis hors service. Enfin, l'équipier http://www4.example.com/ ne fait l'objet d'aucun check up.

top

Directive ProxyHCExpr

Description:Crée et nomme une expression conditionnelle à utiliser pour déterminer la santé d'un serveur d'arrière-plan en fonction de sa valeur
Syntaxe:ProxyHCExpr name {ap_expr expression}
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy_hcheck

La directive ProxyHCExpr permet de créer et nommer une expression conditionnelle dont la valeur calculée en fonction des en-têtes de la réponse du serveur d'arrière-plan permettra d'évaluer la santé de ce dernier. Cette expression nommée peut alors être assignée aux serveurs d'arrière-plan via le paramètre hcexpr.

ProxyHCExpr: interprète les réponses 2xx/3xx/4xx comme des check up réussis

ProxyHCExpr ok234 {%{REQUEST_STATUS} =~ /^[234]/}
ProxyPass "/apps"     "balancer://foo"

<Proxy balancer://foo>
  BalancerMember http://www2.example.com/  hcmethod=HEAD hcexpr=ok234 hcinterval=10
</Proxy>
L'expression peut utiliser des accolades ("{}") comme délimiteurs en plus des guillemets normaux.

Si l'on utilise une méthode de check up (par exemple GET) qui génère un corps de réponse, ce corps peut lui-même être ausculté via ap_expr en utilisant la fonction associée aux expressions hc() spécifique à ce module.

Dans l'exemple suivant, on envoie une requête GET au serveur d'arrière-plan, et si le corps de la réponse contient la chaîne Under maintenance, ce serveur d'arrière-plan est mis hors service.

ProxyHCExpr: auscultation du corps de la réponse

ProxyHCExpr in_maint {hc('body') !~ /Under maintenance/}
ProxyPass "/apps"     "balancer://foo"

<Proxy balancer://foo>
  BalancerMember http://www.example.com/ hcexpr=in_maint hcmethod=get hcuri=/status.php
</Proxy>

NOTE: Comme le corps de la réponse peut être assez grand, il est recommandé de privilégier un check up basé sur les codes d'état.

top

Directive ProxyHCTemplate

Description:Crée et nomme un modèle permettant de définir différents paramètres de check up
Syntaxe:ProxyHCTemplate name parameter=setting [...]
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy_hcheck

La directive ProxyHCTemplate permet de créer et nommer un modèle de paramètres de check up qui peut alors être assigné aux équipiers via le paramètre hctemplate.

ProxyHCTemplate

ProxyHCTemplate tcp5 hcmethod=tcp hcinterval=5
ProxyPass "/apps"     "balancer://foo"

<Proxy balancer://foo>
  BalancerMember http://www2.example.com/ hctemplate=tcp5
</Proxy>
top

Directive ProxyHCTPsize

Description:Définit la taille totale, pour l'ensemble du serveur, du jeu de threads utilisé pour le check up des équipiers
Syntaxe:ProxyHCTPsize size
Défaut:ProxyHCTPsize 16
Contexte:configuration globale
Statut:Extension
Module:mod_proxy_hcheck

Si Apache httpd et APR ont été compilés avec le support des threads, le module de check up peut confier ce travail à un jeu de threads associé au processus Watchdog, ce qui permet l'exécution des check up en parallèle. La directive ProxyHCTPsize permet de déterminer la taille de ce jeu de threads. Une valeur de 0 signifie qu'aucun jeu de threads ne sera utilisé, et le check up des différents équipiers sera alors effectué séquentiellement.

ProxyHCTPsize

ProxyHCTPsize 32

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_http2.html.fr.utf80000664000175100017510000002550214740503670023142 0ustar covenercovener mod_proxy_http2 - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_http2

Langues Disponibles:  en  |  fr 

Description:Support de HTTP/2 pour mod_proxy
Statut:Extension
Identificateur de Module:proxy_http2_module
Fichier Source:mod_proxy_http2.c
Compatibilité:Disponible à partir de la version 2.4.19 du serveur HTTP Apache

Sommaire

mod_proxy_http2 ne supporte que HTTP/2 et ne permet pas de rétrogradation vers HTTP/1.1. Cela signifie que le serveur d'arrière-plan doit supporter HTTP/2 car HTTP/1.1 ne pourra alors pas être utilisé.

Ce module nécessite la présence de mod_proxy ; pour pouvoir traiter les requêtes mandatées HTTP/2, mod_proxy et mod_proxy_http2 doivent donc être chargés par le serveur.

mod_proxy_http2 travaille avec des requêtes entrantes en HTTP/1.1 ou HTTP/2. Dans les deux cas, les requêtes vers le même serveur d'arrière-plan sont envoyées via une seule connexion TCP, dans la mesure du possible (autrement dit lorsque la connexion peut être réutilisée).

Avertissement : il ne sera effectué aucune tentative de fusion de plusieurs requêtes entrantes HTTP/1 (devant être mandatées vers le même serveur d'arrière-plan) vers des flux HTTP/2 appartenant à la même requête HTTP/2. Chaque requête HTTP/1 entrante sera mandatée vers le serveur d'arrière-plan en utilisant une requête HTTP/2 séparée (tout en réutilisant si possible la même connexion TCP).

Ce module s'appuie sur libnghttp2 pour fournir le moteur central http/2.

Avertissement

Ce module en est au stade expérimental. Ses comportement, directives et valeurs par défauts sont donc susceptibles de modifications d'une version à l'autre plus fréquentes que pour les autres modules. A ce titre, il est fortement conseillé aux utilisateurs de consulter le fichier "CHANGES" pour prendre connaissance de ces modifications.

Avertissement

N'activez pas le mandatement avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre propre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Exemples de base

Les exemples ci-dessous montrent comment configurer HTTP/2 pour des connexions d'arrière-plan vers un mandataire inverse.

HTTP/2 (TLS)

ProxyPass "/app" "h2://app.example.com"
ProxyPassReverse "/app" "https://app.example.com"

HTTP/2 (non sécurisé)

ProxyPass "/app" "h2c://app.example.com"
ProxyPassReverse "/app" "http://app.example.com"

Pour mandater en inverse les protocoles h2 ou h2c, on utilise la directive ProxyPassReverse avec les schèmes habituels https et respectivement http qui sont connus et utilisés par l'agent utilisateur.

top

Informations sur les requêtes

mod_proxy_http fournit les informations sur les requêtes suivantes pour enregistrement dans les journaux en utilisant le format %{VARNAME}n avec les directives LogFormat ou ErrorLogFormat :

proxy-source-port
Le numéro de port local utilisé pour la connexion vers le serveur d'arrière-plan.
proxy-status
Le statut HTTP/2 en provenance du serveur d'arrière-plan.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_wstunnel.html.fr.utf80000664000175100017510000002716614740503670023770 0ustar covenercovener mod_proxy_wstunnel - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_wstunnel

Langues Disponibles:  en  |  fr 

Description:Module pour mod_proxy supportant les websockets
Statut:Extension
Identificateur de Module:proxy_wstunnel_module
Fichier Source:mod_proxy_wstunnel.c
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache

Sommaire

Obsolescence

Depuis la version 2.4.47 du serveur HTTP Apache, la promotion de protocole (tunneling) peut être pris en charge de manière plus efficace par mod_proxy_http.

Voir Promotion de protocole.

Pour utiliser ce module, mod_proxy doit être chargé. Il fournit le support du tunnelling pour les connexions websocket vers un serveur websockets d'arrière-plan. La connexion est automatiquement promue en connexion websocket :

Réponse HTTP

Upgrade: WebSocket
Connection: Upgrade

Le mandatement des requêtes vers un serveur websockets comme echo.websocket.org peut être configuré via la directive ProxyPass :

ProxyPass "/ws2/"  "ws://echo.websocket.org/"
ProxyPass "/wss2/" "wss://echo.websocket.org/"

Il est possible de mandater les websockets et HTTP en même temps, avec un jeu spécifique d'URLs pour les websockets, en définissant la directive ProxyPass concernant les websockets avant celle concernant HTTP :

ProxyPassMatch ^/(myApp/ws)$  ws://backend.example.com:9080/$1
ProxyPass / http://backend.example.com:9080/

Il est possible de mandater les websockets et HTTP en même temps, lorsque les URLs websockets ne concernent pas uniquement les websockets ou ne sont pas connues à l'avance, en utilisant la directive RewriteRule pour configurer le mandatement des websockets :

ProxyPass / http://example.com:9080/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://example.com:9080/$1" [P,L]

La répartition de charge entre plusieurs serveurs d'arrière-plan peut être configurée via le module mod_proxy_balancer.

Ce module peut aussi être utilisé pour la promotion vers des protocoles autres que WebSocket en définissant le paramètre upgrade de la directive ProxyPass avec un nom de protocole particulier. Les valeurs spéciales upgrade=NONE et upgrade=ANY peuvent être utilisées pour tester ou forcer la promotion de protocole mais leur utilisation n'est pas recommandée en production pour des raisons de sécurité. NONE signifie que la vérification de l'en-tête est omise mais que la promotion (tunneling) vers WebSocket s'effectuera quand-même. ANY signifie que la promotion (tunneling) s'effectuera en utilisant tout protocole demandé par le client.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive ProxyWebsocketFallbackToProxyHttp

Description:Demande à ce module de laisser mod_proxy_http gérer la requête
Syntaxe:ProxyWebsocketFallbackToProxyHttp On|Off
Défaut:ProxyWebsocketFallbackToProxyHttp On
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy_wstunnel
Compatibilité:Disponible à partir de la version 2.4.48 du serveur HTTP Apache

Depuis la version 2.4.47 de httpd, mod_proxy_http peut gérer le tunneling et la mise à jour via les WebSockets en accord avec la RFC 7230 ; cette directive permet de définir si, pour ces actions, mod_proxy_wstunnel doit passer la main à mod_proxy_http, ce qui est le cas par défaut.

Définir cette directive à Off revient à laisser mod_proxy_wstunnel gérer les requêtes WebSocket, comme avec les versions 2.4.46 et antérieures de httpd.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_remoteip.html.fr.utf80000664000175100017510000007246614740503670022477 0ustar covenercovener mod_remoteip - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_remoteip

Langues Disponibles:  en  |  fr 

Description:Remplace l'adresse IP du client pour la requête par l'adresse IP présentée par un mandataire ou un répartiteur de charge via les en-têtes de la requête.
Statut:Base
Identificateur de Module:remoteip_module
Fichier Source:mod_remoteip.c

Sommaire

Ce module permet de traiter le client qui a initié la requête en tant que client original du point de vue de httpd à des fins d'autorisation et de connexion, même si ce client se trouve derrière un répartiteur de charge, un serveur frontal, ou un serveur mandataire.

Le module remplace l'adresse IP du client pour la connexion par l'adresse IP indiquée dans l'en-tête de requête configuré via la directive RemoteIPHeader.

Ce module implémente aussi la partie serveur du protocole PROXY de HAProxy via la directive RemoteIPProxyProtocol.

Une fois sa valeur modifiée comme indiqué, cette adresse IP client est utilisée pour la fonctionnalité Require ip de mod_authz_host ; elle est aussi affichée par mod_status, et enregistrée via les chaînes de formatage %a des modules mod_log_config et core. L'adresse IP client sous-jacente de la connexion est enregistrée via la chaîne de formatage %{c}a.

Il est essentiel de n'activer cette fonctionnalité que pour les requêtes en provenance des serveurs intermédiaires (mandataires, etc...) auxquels le serveur peut faire confiance, car il est trivial pour le client distant d'usurper l'identité d'un autre client.
Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Traitement des adresses distantes

Par défaut, Apache identifie le client via la valeur client_ip de la connexion, et de cette valeur découlent les valeurs remote_host et remote_logname de la connexion. Ces champs jouent un rôle dans l'authentification, l'autorisation et la journalisation, ainsi que dans d'autres traitements effectués par d'autres modules chargeables.

mod_remoteip remplace l'adresse IP client de la connexion par l'adresse IP client indiquée par exemple par un mandataire ou un répartiteur de charge pour toute la durée de la requête. Un répartiteur de charge pourra ainsi établir une connexion keepalive de longue durée avec le serveur, chaque requête conservant alors l'adresse IP client correcte bien que l'adresse IP client sous-jacente du répartiteur de charge reste inchangée.

Lorsque la valeur de l'en-tête comporte plusieurs adresses IP client séparées par des virgules, celles-ci sont traitées de la droite vers la gauche. Le traitement s'arrête lorsque l'adresse IP client courante n'est pas digne de confiance pour présenter l'adresse IP précédente. Le champ d'en-tête est alors mis à jour de façon à ne contenir que cette liste d'adresses non confirmées, ou bien, si toutes les adresses IP sont dignes de confiance, cet en-tête est tout bonnement supprimé de la requête.

Lors du remplacement de l'adresse IP client, le module stocke la liste des hôtes intermédiaires dans un mémo remoteip-proxy-ip-list, que l'on peut faire enregistrer par mod_log_config en utilisant le symbole de format %{remoteip-proxy-ip-list}n. Si l'administrateur doit stocker ceci dans un en-tête additionnel, la même valeur peut aussi être enregistrée sous la forme d'un en-tête en utilisant la directive RemoteIPProxiesHeader.

Adresses IPv4 converties au format IPv6

Avec httpd, d'une manière générale, toute adresse IPv4 convertie au format IPv6 est enregistrée sous sa forme IPv4.

Adresses internes (privées)

Tous les blocs d'adresses internes 10/8, 172.16/12, 192.168/16, 169.254/16 and 127/8 (ainsi que les adresses IPv6 en dehors du bloc public 2000::/3 block) ne sont évaluées par mod_remoteip que lorsque des mandataires internes (intranet) RemoteIPInternalProxy sont enregistrés.
top

Directive RemoteIPHeader

Description:Définit le champ d'en-tête qui contiendra les adresses IP du client
Syntaxe:RemoteIPHeader en-tête
Défaut:none
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip

La directive RemoteIPHeader indique à mod_remoteip de traiter la valeur de l'en-tête spécifié comme l'adresse IP du client, ou comme une liste d'adresses IP clients intermédiaires, en fonction de la configuration des directives RemoteIPInternalProxy et RemoteIPTrustedProxy. Si ces deux dernières directives ne sont pas utilisées, mod_remoteip traitera tout hôte présentant une adresse non interne dans l'en-tête RemoteIPHeader comme hôte de confiance.

Si ces deux dernières directives ne sont pas utilisées, mod_remoteip traitera tout hôte présentant une adresse non interne dans l'en-tête RemoteIPHeader comme hôte de confiance.

Exemple à usage interne (répartiteur de charge)

RemoteIPHeader X-Client-IP

Exemple dans le cas d'un mandataire

RemoteIPHeader X-Forwarded-For
top

Directive RemoteIPInternalProxy

Description:Déclare les adresses IP intranet clients comme dignes de confiance pour présenter la valeur RemoteIPHeader
Syntaxe:RemoteIPInternalProxy ip-mandataire|ip-mandataire/sous-réseau|nom-hôte ...
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip

La directive RemoteIPInternalProxy permet d'ajouter une ou plusieurs adresses (ou blocs d'adresses) auxquelles on peut faire confiance pour présenter une valeur RemoteIPHeader valide de l'adresse IP du client. A la différence de la directive RemoteIPTrustedProxy, toute adresse IP présentée dans cet en-tête, y comprises les adresses intranet privées, sont considérées comme dignes de confiance lorsqu'elles sont indiquées par ces mandataires.

Exemple à usage interne (répartiteur de charge)

RemoteIPHeader X-Client-IP
RemoteIPInternalProxy 10.0.2.0/24
RemoteIPInternalProxy gateway.localdomain
top

Directive RemoteIPInternalProxyList

Description:Déclare les adresses IP intranet clients comme dignes de confiance pour présenter la valeur RemoteIPHeader
Syntaxe:RemoteIPInternalProxyList nom-fichier
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip

La directive RemoteIPInternalProxyList permet de spécifier un fichier parcouru au démarrage du serveur pour construire une liste d'adresses (ou blocs d'adresses), auxquelles on peut faire confiance pour présenter une valeur RemoteIPHeader valide de l'adresse IP du client.

Le caractère '#' indique une ligne de commentaires, sinon, toutes les lignes séparées par un caractère nouvelle ligne ou tous les éléments d'une ligne séparés par un espace sont traités de la même façon qu'avec la directive RemoteIPInternalProxy.

Exemple à usage interne (répartiteur de charge)

RemoteIPHeader X-Client-IP
RemoteIPInternalProxyList conf/trusted-proxies.lst

contenu de conf/mandataires-de-confiance.lst

         # Nos mandataires internes de confiance
         10.0.2.0/24         # Tout le monde dans le groupe de test
         passerelle.domaine-local # Le frontal répartiteur de charge
top

Directive RemoteIPProxiesHeader

Description:Déclare le champ d'en-tête qui contiendra toutes les adresses IP intermédiaires
Syntaxe:RemoteIPProxiesHeader Nom_en-tête
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip

La directive RemoteIPProxiesHeader permet de spécifier l'en-tête dans lequel mod_remoteip va collecter une liste de toutes les adresses IP clients intermédiaires auxquelles on pourra faire confiance pour résoudre l'adresse IP client de la requête. Notez que les adresses intermédiaires RemoteIPTrustedProxy sont enregistrées dans cet en-tête, alors que toute adresse intermédiaire RemoteIPInternalProxy est omise.

Exemple

RemoteIPHeader X-Forwarded-For
RemoteIPProxiesHeader X-Forwarded-By
top

Directive RemoteIPProxyProtocol

Description:Active ou désactive la gestion du protocole PROXY
Syntaxe:RemoteIPProxyProtocol On|Off
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip
Compatibilité:Disponible à partir de la version 2.4.31 du serveur HTTP Apache

La directive RemoteIPProxyProtocol permet d'activer ou de désactiver la prise en compte et la gestion de l'en-tête de connexion du protocole PROXY. Si elle est définie à On, la demande du client doit envoyer l'en-tête approprié pour chaque nouvelle connexion, sinon cette dernière sera fermée à moins qu'il ne fasse partie de la liste, définie via la directive RemoteIPProxyProtocolDisableHosts, des hôtes pour lesquels le protocole PROXY est désactivé.

Bien que cette directive peut être définie au niveau de n'importe quel serveur virtuel, il est important de garder à l'esprit que, étant donné que le protocole PROXY est basé sur la connexion et agnostique quant au protocle, son activation/désactivation est basée sur le couple adresse IP/port. Cela signifie que si plusieurs serveurs virtuels à base de nom sont configurés avec le même couple adresse IP/port, et si vous activez le protocole PROXY pour l'un d'entre eux, il le sera aussi pour tous les autres (avec le même couple adresse IP/port). Cela signifie aussi que si vous tentez d'activer le protocole PROXY pour un serveur virtuel et de le désactiver pour un autre, cela ne marchera pas ; dans ce dernier cas, la dernière directive l'emporte sur les autres et une notification sera enregistrée dans le journal pour indiquer les réglages qui ont été annulés.

Listen 80
<VirtualHost *:80>
    ServerName www.example.com
    RemoteIPProxyProtocol On

    #Les requêtes pour ce serveur virtuel doivent contenir un en-tête du
    #protocole PROXY. Si ce n'est pas le cas, la connexion sera fermée.
</VirtualHost>

Listen 8080
<VirtualHost *:8080>
    ServerName www.example.com
    RemoteIPProxyProtocol On
    RemoteIPProxyProtocolExceptions 127.0.0.1 10.0.0.0/8

    #Les requêtes pour ce serveur virtuel doivent contenir un en-tête du
    #protocole PROXY. Si ce n'est pas le cas, la connexion sera fermée à moins
    que sa source ne soit localhost ou la gamme d'adresses RFC1918 10.x.x.x
</VirtualHost>
top

Directive RemoteIPProxyProtocolExceptions

Description:Désactive la prise en compte de l'en-tête PROXY pour certains hôtes ou réseaux
Syntaxe:RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip
Compatibilité:RemoteIPProxyProtocolExceptions est disponible à partir de la version 2.4.31 du serveur HTTP Apache

La directive RemoteIPProxyProtocol permet de contrôler la prise en compte de l'en-tête de connexion du protocole PROXY. Il est parfois souhaitable d'exiger pour certains clients la présence de l'en-tête PROXY, mais aussi de permettre aux autres clients de se connecter sans ce dernier. Cette directive permet à l'administrateur du serveur d'autoriser cette possibilité à un hôte isolé ou à une gamme d'hôtes au format CIDR.

top

Directive RemoteIPTrustedProxy

Description:Déclare les adresses IP clientes de l'intranet dignes de confiance pour présenter la valeur RemoteIPHeader
Syntaxe:RemoteIPTrustedProxy ip-mandataire|ip-mandataire/sous-réseau|nom-hôte ...
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip

La directive RemoteIPTrustedProxy permet d'ajouter une ou plusieurs adresses, ou blocs d'adresses, auxquelles on peut faire confiance pour présenter une valeur RemoteIPHeader valide de l'adresse IP du client. A la différence de la directive RemoteIPInternalProxy, toutes les adresses IP intranet ou privées indiquées par de tels mandataires, y compris les blocs d'adresses 10/8, 172.16/12, 192.168/16, 169.254/16 et 127/8 (ou située en dehors du bloc IPv6 public 2000::/3), ne sont pas dignes de confiance en tant qu'adresses IP distantes, et se situent à gauche dans le contenu de l'en-tête RemoteIPHeader.

Exemple d'adresse de confiance (répartiteur de charge

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.2.16/28
RemoteIPTrustedProxy proxy.example.com
top

Directive RemoteIPTrustedProxyList

Description:Déclare les adresses IP intranet clients comme dignes de confiance pour présenter la valeur RemoteIPHeader
Syntaxe:RemoteIPTrustedProxyList nom-fichier
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_remoteip

La directive RemoteIPTrustedProxyList permet de spécifier un fichier parcouru au démarrage du serveur pour construire une liste d'adresses (ou blocs d'adresses), auxquelles on peut faire confiance pour présenter une valeur RemoteIPHeader valide de l'adresse IP du client.

Le caractère '#' indique une ligne de commentaires, sinon, toutes les lignes séparées par un caractère nouvelle ligne ou tous les éléments d'une ligne séparés par un espace sont traités de la même façon qu'avec la directive RemoteIPTrustedProxy.

Exemple d'adresse de confiance (répartiteur de charge

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxyList conf/trusted-proxies.lst

conf/mandataires-de-confiance.lst contents

# Mandataires externes identifiés
192.0.2.16/28 #groupe wap phone de mandataires
proxy.isp.example.com #un FAI bien connu

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy.html.fr.utf80000664000175100017510000045235414740503670022032 0ustar covenercovener mod_proxy - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy

Langues Disponibles:  en  |  fr  |  ja 

Description:Serveur mandataire/passerelle multi-protocole
Statut:Extension
Identificateur de Module:proxy_module
Fichier Source:mod_proxy.c

Sommaire

Avertissement

N'activez pas la fonctionnalité de mandataire avec la directive ProxyRequests avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux pour votre réseau, mais aussi pour l'Internet au sens large.

mod_proxy et ses modules associés implémentent un mandataire/passerelle pour le serveur HTTP Apache, et supportent de nombreux protocoles courants, ainsi que plusieurs algorithmes de répartition de charge. Le support de protocoles et d'algorithmes de répartition de charge supplémentaires peut être assuré par des modules tiers.

Un jeu de modules chargés dans le serveur permet de fournir les fonctionnalités souhaitées. Ces modules peuvent être inclus statiquement à la compilation, ou dynamiquement via la directive LoadModule. Ce jeu de module doit comporter :

En outre, d'autres modules fournissent des fonctionnalités étendues. mod_cache et ses modules associés fournissent la mise en cache. Les directives SSLProxy* du module mod_ssl permettent de contacter des serveurs distants en utilisant le protocole SSL/TLS. Ces modules additionnels devront être chargés et configurés pour pouvoir disposer de ces fonctionnalités.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Mandataires directs et mandataires/passerelles inverses

Le serveur HTTP Apache peut être configuré dans les deux modes mandataire direct et mandataire inverse (aussi nommé mode passerelle).

Un mandataire direct standard est un serveur intermédiaire qui s'intercale entre le client et le serveur demandé. Pour obtenir un contenu hébergé par le serveur demandé, le client envoie une requête au mandataire en nommant le serveur demandé comme cible. Le mandataire extrait alors le contenu depuis le serveur demandé et le renvoie enfin au client. Le client doit être configuré de manière appropriée pour pouvoir utiliser le mandataire direct afin d'accéder à d'autres sites.

L'accès à Internet depuis des clients situés derrière un pare-feu est une utilisation typique du mandataire direct. Le mandataire direct peut aussi utiliser la mise en cache (fournie par mod_cache) pour réduire la charge du réseau.

La fonctionnalité de mandataire direct est activée via la directive ProxyRequests. Comme les mandataires directs permettent aux clients d'accéder à des sites quelconques via votre serveur et de dissimuler leur véritable origine, il est indispensable de sécuriser votre serveur de façon à ce que seuls les clients autorisés puissent accéder à votre serveur avant d'activer la fonctionnalité de mandataire direct.

Un mandataire inverse (ou passerelle), quant à lui, apparaît au client comme un serveur web standard. Aucune configuration particulière du client n'est nécessaire. Le client adresse ses demandes de contenus ordinaires dans l'espace de nommage du mandataire inverse. Ce dernier décide alors où envoyer ces requêtes, et renvoie le contenu au client comme s'il l'hébergeait lui-même.

L'accès d'utilisateurs depuis Internet vers un serveur situé derrière un pare-feu est une utilisation typique du mandataire inverse. On peut aussi utiliser les mandataires inverses pour mettre en oeuvre une répartition de charge entre plusieurs serveurs en arrière-plan, ou fournir un cache pour un serveur d'arrière-plan plus lent. Les mandataires inverses peuvent aussi tout simplement servir à rassembler plusieurs serveurs dans le même espace de nommage d'URLs.

La fonctionnalité de mandataire inverse est activée via la directive ProxyPass ou le drapeau [P] de la directive RewriteRule. Il n'est pas nécessaire de définir ProxyRequests pour configurer un mandataire inverse.

top

Exemples simples

Les exemples ci-dessous illustrent de manière très basique la mise en oeuvre de la fonctionnalité de mandataire et ne sont là que pour vous aider à démarrer. Reportez-vous à la documentation de chaque directive.

Si en outre, vous désirez activer la mise en cache, consultez la documentation de mod_cache.

Mandataire inverse

ProxyPass "/foo" "http://foo.example.com/bar"
ProxyPassReverse "/foo" "http://foo.example.com/bar"

Mandataire direct

ProxyRequests On
ProxyVia On

<Proxy "*">
  Require host internal.example.com
</Proxy>

Promotion de protocole vers Websocket (versions 2.4.47 et ultérieures)

ProxyPass "/some/ws/capable/path/" "http://example.com/some/ws/capable/path/" upgrade=websocket
top

Accès via un gestionnaire

Vous pouvez aussi forcer le traitement d'une requête en tant que requête de mandataire inverse en créant un gestionnaire de transfert approprié. Dans l'exemple suivant, toutes les requêtes pour des scripts PHP seront transmises au serveur FastCGI spécifié via un mandat inverse :

Scripts PHP et mandataire inverse

<FilesMatch "\.php$">
    # Les sockets Unix nécessitent une version 2.4.7 ou supérieure du
    # serveur HTTP Apache
    SetHandler  "proxy:unix:/path/to/app.sock|fcgi://localhost/"
</FilesMatch>

Cette fonctionnalité est disponible à partir de la version 2.4.10 du serveur HTTP Apache.

top

Workers

Le mandataire gère la configuration et les paramètres de communication des serveurs originaux au sein d'objets nommés workers. Deux types de worker sont fournis : le worker par défaut du mandataire direct et le worker par défaut du mandataire inverse. Il est aussi possible de définir explicitement des workers supplémentaires.

Les deux workers par défaut possèdent une configuration figée et seront utilisés si aucun autre worker ne correspond à la requête. Ils ne réutilisent pas les connexions et n'utilisent pas les connexions HTTP persistantes (Keep-Alive). En effet, les connexions TCP vers le serveur original sont fermées et ouvertes pour chaque requête.

Les workers définis explicitement sont identifiés par leur URL. Ils sont en général définis via les directives ProxyPass ou ProxyPassMatch lorsqu'on les utilise dans le cadre d'un mandataire inverse :

ProxyPass "/example" "http://backend.example.com" connectiontimeout=5 timeout=30

Cette directive va créer un worker associé à l'URL du serveur original http://backend.example.com qui utilisera les valeurs de timeout données. Lorsqu'ils sont utilisés dans le cadre d'un mandataire direct, les workers sont en général définis via la directive ProxySet,

ProxySet "http://backend.example.com" connectiontimeout=5 timeout=30

ou encore via les directives Proxy et ProxySet :

<Proxy "http://backend.example.com">
  ProxySet connectiontimeout=5 timeout=30
</Proxy>

L'utilisation de workers définis explicitement dans le mode mandataire direct n'est pas très courante, car les mandataires directs communiquent en général avec de nombreux serveurs originaux. La création explicite de workers pour certains serveurs originaux peut cependant s'avérer utile si ces serveurs sont très souvent sollicités. A leur niveau, les workers explicitement définis ne possèdent aucune notion de mandataire direct ou inverse. Ils encapsulent un concept de communication commun avec les serveurs originaux. Un worker créé via la directive ProxyPass pour être utilisé dans le cadre d'un mandataire inverse sera aussi utilisé dans le cadre d'un mandataire directe chaque fois que l'URL vers le serveur original correspondra à l'URL du worker, et vice versa.

L'URL qui identifie un worker correspond à l'URL de son serveur original, y compris un éventuel chemin donné :

ProxyPass "/examples" "http://backend.example.com/examples"
ProxyPass "/docs" "http://backend.example.com/docs"

Dans cet exemple, deux workers différents sont définis, chacun d'eux utilisant des configurations et jeux de connexions séparés.

Partage de workers

Le partage de workers intervient lorsque les URLs des workers s'entrecoupent, ce qui arrive lorsque l'URL d'un worker correspond au début de l'URL d'un autre worker défini plus loin dans le fichier de configuration. Dans l'exemple suivant,

ProxyPass "/apps" "http://backend.example.com/" timeout=60
ProxyPass "/examples" "http://backend.example.com/examples" timeout=10

le second worker n'est pas vraiment créé. C'est le premier worker qui est en fait utilisé. L'avantage de ceci réside dans le fait qu'il n'existe qu'un seul jeu de connexions, ces dernières étant donc réutilisées plus souvent. Notez que tous les attributs de configuration définis explicitement pour le deuxième worker seront ignorés, ce qui sera journalisé en tant qu'avertissement. Ainsi, dans l'exemple ci-dessus, la valeur de timeout retenue pour l'URL /exemples sera 60, et non 10 !

Si vous voulez empêcher le partage de workers, classez vos définitions de workers selon la longueur des URLs, de la plus longue à la plus courte. Si au contraire vous voulez favoriser ce partage, utilisez l'ordre de classement inverse. Voir aussi l'avertissement à propos de l'ordre de classement des directives ProxyPass.

Les workers définis explicitement sont de deux sortes : workers directs et workers de répartition (de charge). Ils supportent de nombreux attributs de configuration importants décrits dans la directive ProxyPass. Ces mêmes attributs peuvent aussi être définis via la directive ProxySet.

Le jeu d'options disponibles pour un worker direct dépend du protocole spécifié dans l'URL du serveur original. Les protocoles disponibles comprennent ajp, fcgi, ftp, http et scgi.

Les workers de répartition sont des workers virtuels qui utilisent les workers directs, connus comme faisant partie de leurs membres, pour le traitement effectif des requêtes. Chaque répartiteur peut comporter plusieurs membres. Lorsqu'il traite une requête, il choisit un de ses membres en fonction de l'algorithme de répartition de charge défini.

Un worker de répartition est créé si son URL de worker comporte balancer comme indicateur de protocole. L'URL du répartiteur permet d'identifier de manière unique le worker de répartition. La directive BalancerMember permet d'ajouter des membres au répartiteur.

Résolution DNS pour les domaines originaux

La résolution DNS s'effectue lorsque le socket vers le domaine original est créé pour la première fois. Lorsque la réutilisation des connexions est activée, chaque domaine d'arrière-plan n'est résolu qu'une seule fois pour chaque processus enfant, et cette résolution est mise en cache pour toutes les connexions ultérieures jusqu'à ce que le processus enfant soit recyclé. Ce comportement doit être pris en considération lorsqu'on planifie des tâches de maintenance du DNS impactant les domaines d'arrière-plan. Veuillez aussi vous reporter aux paramètres de la directive ProxyPass pour plus de détails à propos de la réutilisation des connexions.

top

Contrôler l'accès à votre mandataire

Vous pouvez restreindre l'accès à votre mandataire via le bloc de contrôle <Proxy> comme dans l'exemple suivant :

<Proxy "*">
  Require ip 192.168.0
</Proxy>

Pour plus de détails sur les directives de contrôle d'accès, voir la documentation du module mod_authz_host.

Restreindre l'accès de manière stricte est essentiel si vous mettez en oeuvre un mandataire direct (en définissant la directive ProxyRequests à "on"). Dans le cas contraire, votre serveur pourrait être utilisé par n'importe quel client pour accéder à des serveurs quelconques, tout en masquant sa véritable identité. Ceci représente un danger non seulement pour votre réseau, mais aussi pour l'Internet au sens large. Dans le cas de la mise en oeuvre d'un mandataire inverse (en utilisant la directive ProxyPass avec ProxyRequests Off), le contrôle d'accès est moins critique car les clients ne peuvent contacter que les serveurs que vous avez spécifiés.

Voir aussi la variable d'environnement Proxy-Chain-Auth.

top

Ralentissement au démarrage

Si vous utilisez la directive ProxyBlock, les noms d'hôtes sont résolus en adresses IP puis ces dernières mises en cache au cours du démarrage à des fins de tests de comparaisons ultérieurs. Ce processus peut durer plusieurs secondes (ou d'avantage) en fonction de la vitesse à laquelle s'effectue la résolution des noms d'hôtes.

top

Mandataire en Intranet

Un serveur mandataire Apache httpd situé à l'intérieur d'un Intranet doit faire suivre les requêtes destinées à un serveur externe à travers le pare-feu de l'entreprise (pour ce faire, définissez la directive ProxyRemote de façon à ce qu'elle fasse suivre le protocole concerné vers le mandataire du pare-feu). Cependant, lorsqu'il doit accéder à des ressources situées dans l'Intranet, il peut se passer du pare-feu pour accéder aux serveurs. A cet effet, la directive NoProxy permet de spécifier quels hôtes appartiennent à l'Intranet et peuvent donc être accédés directement.

Les utilisateurs d'un Intranet ont tendance à oublier le nom du domaine local dans leurs requêtes WWW, et demandent par exemple "http://un-serveur/" au lieu de http://un-serveur.example.com/. Certains serveurs mandataires commerciaux acceptent ce genre de requête et les traitent simplement en utilisant un nom de domaine local implicite. Lorsque la directive ProxyDomain est utilisée et si le serveur est configuré comme mandataire, Apache httpd peut renvoyer une réponse de redirection et ainsi fournir au client l'adresse de serveur correcte, entièrement qualifiée. C'est la méthode à privilégier car le fichier des marque-pages de l'utilisateur contiendra alors des noms de serveurs entièrement qualifiés.

top

Ajustements relatifs au protocole

Pour les cas où mod_proxy envoie des requêtes vers un serveur qui n'implémente pas correctement les connexions persistantes ou le protocole HTTP/1.1, il existe deux variables d'environnement qui permettent de forcer les requêtes à utiliser le protocole HTTP/1.0 avec connexions non persistantes. Elles peuvent être définies via la directive SetEnv.

Il s'agit des variables force-proxy-request-1.0 et proxy-nokeepalive.

<Location "/buggyappserver/">
  ProxyPass "http://buggyappserver:7001/foo/"
  SetEnv force-proxy-request-1.0 1
  SetEnv proxy-nokeepalive 1
</Location>

A partir de la version 2.4.26 du serveur HTTP Apache, la définition de la variable d'environnement "no-proxy" permet de désactiver mod_proxy dans le traitement de la requête courante. Cette variable doit être définie via la directive SetEnvIf car la directive SetEnv n'est pas évaluée assez tôt.

top

Corps de requêtes

Certaines méthodes de requêtes comme POST comportent un corps de requête. Le protocole HTTP stipule que les requêtes qui comportent un corps doivent soit utiliser un codage de transmission fractionnée (chunked transfer encoding), soit envoyer un en-tête de requête Content-Length. Lorsqu'il fait suivre ce genre de requête vers le serveur demandé, mod_proxy_http s'efforce toujours d'envoyer l'en-tête Content-Length. Par contre, si la taille du corps est importante, et si la requête originale utilise un codage à fractionnement, ce dernier peut aussi être utilisé dans la requête montante. Ce comportement peut être contrôlé à l'aide de variables d'environnement. Ainsi, si elle est définie, la variable proxy-sendcl assure une compatibilité maximale avec les serveurs demandés en imposant l'envoi de l'en-tête Content-Length, alors que proxy-sendchunked diminue la consommation de ressources en imposant l'utilisation d'un codage à fractionnement.

Dans certaines circonstances, le serveur doit mettre en file d'attente sur disque les corps de requêtes afin de satisfaire le traitement demandé des corps de requêtes. Par exemple, cette mise en file d'attente se produira si le corps original a été envoyé selon un codage morcelé (et possède une taille importante), alors que l'administrateur a demandé que les requêtes du serveur d'arrière-plan soient envoyées avec l'en-tête Content-Length ou en HTTP/1.0. Cette mise en file d'attente se produira aussi si le corps de la requête contient déjà un en-tête Content-Length, alors que le serveur est configuré pour filtrer les corps des requêtes entrantes.

top

En-têtes de requête du mandataire inverse

Lorsqu'il est configuré en mode mandataire inverse (en utilisant par exemple la directive ProxyPass), mod_proxy_http ajoute plusieurs en-têtes de requête afin de transmettre des informations au serveur demandé. Ces en-têtes sont les suivants :

X-Forwarded-For
L'adresse IP du client.
X-Forwarded-Host
L'hôte d'origine demandé par le client dans l'en-tête de requête HTTP Host.
X-Forwarded-Server
Le nom d'hôte du serveur mandataire.

Ces en-têtes doivent être utilisés avec précautions sur le serveur demandé, car ils contiendront plus d'une valeur (séparées par des virgules) si la requête originale contenait déjà un de ces en-têtes. Par exemple, vous pouvez utiliser %{X-Forwarded-For}i dans la chaîne de format du journal du serveur demandé pour enregistrer les adresses IP des clients originaux, mais il est possible que vous obteniez plusieurs adresses si la requête passe à travers plusieurs mandataires.

Voir aussi les directives ProxyPreserveHost et ProxyVia directives, qui permettent de contrôler d'autres en-têtes de requête.

Note : Si vous devez ajouter des en-têtes particuliers à la requête mandatée, utilisez la directive RequestHeader.

top

Directive BalancerGrowth

Description:Nombre de membres supplémentaires pouvant être ajoutés après la configuration initiale
Syntaxe:BalancerGrowth #
Défaut:BalancerGrowth 5
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:BalancerGrowth est disponible depuis la version 2.3.13 du serveur HTTP Apache

Cette directive permet de définir le nombre de membres pouvant être ajoutés au groupe de répartition de charge préconfiguré d'un serveur virtuel. Elle n'est active que si le groupe a été préconfiguré avec un membre au minimum.

top

Directive BalancerInherit

Description:Héritage des membres du groupes de répartition de charge du mandataire définis au niveau du serveur principal
Syntaxe:BalancerInherit On|Off
Défaut:BalancerInherit On
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache.

Cette directive permet d'attribuer au serveur virtuel courant l'héritage des membres de groupes de répartition de charge définis au niveau du serveur principal. Elle ne doit pas être activée si vous utilisez la fonctionnalité de modifications dynamiques du gestionnaire de répartition de charge (Balancer Manager) pour éviter des problèmes et des comportements inattendus.

Les définitions au niveau du serveur principal constituent les définitions par défaut au niveau des serveurs virtuels.

top

Directive BalancerMember

Description:Ajoute un membre à un groupe de répartition de charge
Syntaxe:BalancerMember [balancerurl] url [clé=valeur [clé=valeur ...]]
Contexte:répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible depuis la version 2.2 du serveur HTTP Apache.

Cette directive permet d'ajouter un membre à un groupe de répartition de charge. Elle peut se trouver dans un conteneur <Proxy balancer://...>, et accepte tous les paramètres de paires clé/valeur que supporte la directive ProxyPass.

La directive BalancerMember accepte un paramètre supplémentaire : loadfactor. Il s'agit du facteur de charge du membre - un nombre décimal entre 1.0 (valeur par défaut) et 100.0, qui définit la charge à appliquer au membre en question.

L'argument balancerurl n'est requis que s'il ne se trouve pas dèjà dans la directive de conteneur <Proxy balancer://...>. Il correspond à l'URL d'un répartiteur de charge défini par une directive ProxyPass.

La partie chemin de l'URL du répartiteur dans toute directive de conteneur <Proxy balancer://...> est ignorée.

En particulier, le slash de fin de l'URL d'un BalancerMember doit être supprimé.

top

Directive BalancerPersist

Description:Tente de conserver les changements effectués par le gestionnaire de répartition de charge après un redémarrage du serveur.
Syntaxe:BalancerPersist On|Off
Défaut:BalancerPersist Off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:BalancerPersist n'est disponible qu'à partir de la version 2.4.4 du serveur HTTP Apache.

Cette directive permet de conserver le contenu de l'espace mémoire partagé associé aux répartiteurs de charge et à leurs membres après un redémarrage du serveur. Ces modifications locales ne sont ainsi pas perdues lors des transitions d'état dues à un redémarrage.

top

Directive NoProxy

Description:Serveurs, domaines ou réseaux auquels on se connectera directement
Syntaxe:NoProxy domaine [domaine] ...
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

Cette directive n'a d'utilité que pour les serveurs mandataires Apache httpd au sein d'Intranets. La directive NoProxy permet de spécifier une liste de sous-réseaux, d'adresses IP, de serveurs et/ou de domaines séparés par des espaces. Une requête pour un serveur qui correspond à un ou plusieurs critères sera toujours servie par ce serveur directement, sans être redirigée vers le(s) serveur(s) mandataire(s) défini(s) par la directive ProxyRemote.

Exemple

ProxyRemote  "*"  "http://firewall.example.com:81"
NoProxy         ".example.com" "192.168.112.0/21"

Le type des arguments serveur de la directive NoProxy appartiennent à la liste suivante :

Domaine

Un domaine est ici un nom de domaine DNS partiellement qualifié précédé d'un point. Il représente une liste de serveurs qui appartiennent logiquement au même domaine ou à la même zonz DNS (en d'autres termes, les nom des serveurs se terminent tous par domaine).

Exemple

.com .example.org.

Pour faire la distinction entre domaines et nom d'hôtes (des points de vue à la fois syntaxique et sémantique, un domaine DNS pouvant aussi avoir un enregistrement DNS de type A !), les domaines sont toujours spécifiés en les préfixant par un point.

Note

Les comparaisons de noms de domaines s'effectuent sans tenir compte de la casse, et les parties droites des Domaines sont toujours censées correspondre à la racine de l'arborescence DNS, si bien que les domaines .ExEmple.com et .exemple.com. (notez le point à la fin du nom) sont considérés comme identiques. Comme une comparaison de domaines ne nécessite pas de recherche DNS, elle est beaucoup plus efficace qu'une comparaison de sous-réseaux.

Sous-réseau

Un Sous-réseau est une adresse internet partiellement qualifiée sous forme numérique (quatre nombres séparés par des points), optionnellement suivie d'un slash et du masque de sous-réseau spécifiant le nombre de bits significatifs dans le Sous-réseau. Il représente un sous-réseau de serveurs qui peuvent être atteints depuis la même interface réseau. En l'absence de masque de sous-réseau explicite, il est sous-entendu que les digits manquants (ou caractères 0) de fin spécifient le masque de sous-réseau (Dans ce cas, le masque de sous-réseau ne peut être qu'un multiple de 8). Voici quelques exemples :

192.168 ou 192.168.0.0
le sous-réseau 192.168.0.0 avec un masque de sous-réseau implicite de 16 bits significatifs (parfois exprimé sous la forme 255.255.0.0)
192.168.112.0/21
le sous-réseau 192.168.112.0/21 avec un masque de sous-réseau implicite de 21 bits significatifs (parfois exprimé sous la forme255.255.248.0)

Comme cas extrêmes, un Sous-réseau avec un masque de sous-réseau de 32 bits significatifs est équivalent à une adresse IP, alors qu'un Sous-réseau avec un masque de sous-réseau de 0 bit significatif (c'est à dire 0.0.0.0/0) est identique à la constante _Default_, et peut correspondre à toute adresse IP.

Adresse IP

Une Adresse IP est une adresse internet pleinement qualifiée sous forme numérique (quatre nombres séparés par des points). En général, cette adresse représente un serveur, mais elle ne doit pas nécessairement correspondre à un nom de domaine DNS.

Exemple

192.168.123.7

Note

Une Adresse IP ne nécessite pas de résolution DNS, et peut ainsi s'avérer plus efficace quant aux performances d'Apache.

Nom de serveur

Un Nom de serveur est un nom de domaine DNS pleinement qualifié qui peut être résolu en une ou plusieurs adresses IP par le service de noms de domaines DNS. Il représente un hôte logique (par opposition aux Domaines, voir ci-dessus), et doit pouvoir être résolu en une ou plusieurs adresses IP (ou souvent en une liste d'hôtes avec différentes adresses IP).

Exemples

prep.ai.example.edu
www.example.org

Note

Dans de nombreuses situations, il est plus efficace de spécifier une adresse IP qu'un Nom de serveur car cela évite d'avoir à effectuer une recherche DNS. La résolution de nom dans Apache httpd peut prendre un temps très long lorsque la connexion avec le serveur de noms utilise une liaison PPP lente.

Les comparaisons de Nom de serveur s'effectuent sans tenir compte de la casse, et les parties droites des Noms de serveur sont toujours censées correspondre à la racine de l'arborescence DNS, si bien que les domaines WWW.ExEmple.com et www.example.com. (notez le point à la fin du nom) sont considérés comme identiques.

Voir aussi

top

Directive <Proxy>

Description:Conteneur de directives s'appliquant à des ressources mandatées
Syntaxe:<Proxy url-avec-jokers> ...</Proxy>
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

Les directives situées dans une section <Proxy> ne s'appliquent qu'au contenu mandaté concerné. Les jokers de style shell sont autorisés.

Par exemple, les lignes suivantes n'autoriseront à accéder à un contenu via votre serveur mandataire que les hôtes appartenant à votre-reseau.example.com :

<Proxy "*">
  Require host votre-reseau.example.com
</Proxy>

Dans l'exemple suivant, tous les fichiers du répertoire foo de example.com seront traités par le filtre INCLUDES lorsqu'ils seront envoyés par l'intermédiaire du serveur mandataire :

<Proxy "http://example.com/foo/*">
  SetOutputFilter INCLUDES
</Proxy>

Différences avec la section de configuration Location

Une URL d'arrière-plan sera concernée par le conteneur Proxy si elle commence par la url-avec-jokers, même si le dernier segment de chemin de la directive ne correspond qu'à un préfixe de segment dee chemin de l'URL d'arrière-plan. Par exemple, <Proxy "http://example.com/foo"> correspondra entre autres aux URLs http://example.com/foo, http://example.com/foo/bar, et http://example.com/foobar. La correspondance de l'URL finale diffère du comportement de la section <Location> qui, pour le cas de cette note, traitera le segment de chemin final comme s'il se terminait par un slash.

Pour un contrôle plus fin de la correspondance des URL, voir la directive <ProxyMatch>.

Voir aussi

top

Directive Proxy100Continue

Description:Transmission du message "100-continue" au serveur d'origine
Syntaxe:Proxy100Continue Off|On
Défaut:Proxy100Continue On
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible à partir de la version 2.4.40 du serveur HTTP Apache

Cette directive permet de contrôler le transfert par le mandataire du message "100-continue" (Expect:ation) vers le serveur d'origine. Si elle est définie à "On", le serveur d'origine décidera lui-même si le corps de la requête HTTP doit être lu. Si elle est définie à "Off", le mandataire générera lui-même une réponse intermédiaire 100 Continue avant de transférer le corps de la requête.

Contexte d'utilisation

Cette option n'est utilisable qu'avec les mandataires HTTP gérés par mod_proxy_http.

top

Directive ProxyAddHeaders

Description:Ajoute des informations à propos du mandataire aux en-têtes X-Forwarded-*
Syntaxe:ProxyAddHeaders Off|On
Défaut:ProxyAddHeaders On
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible depuis la version 2.3.10

Cette directive permet de passer au serveur d'arrière-plan des informations à propos du mandataire via les en-têtes HTTP X-Forwarded-For, X-Forwarded-Host et X-Forwarded-Server.

Utilité

Cette option n'est utile que dans le cas du mandat HTTP traité par mod_proxy_http.

top

Directive ProxyBadHeader

Description:Détermine la manière de traiter les lignes d'en-tête incorrectes d'une réponse
Syntaxe:ProxyBadHeader IsError|Ignore|StartBody
Défaut:ProxyBadHeader IsError
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

La directive ProxyBadHeader permet de déterminer le comportement de mod_proxy lorsqu'il reçoit des lignes d'en-tête de réponse dont la syntaxe n'est pas valide (c'est à dire ne contenant pas de caractère ':') en provenance du serveur original. Les arguments disponibles sont :

IsError
Annule la requête et renvoie une réponse de code 502 (mauvaise passerelle). C'est le comportement par défaut.
Ignore
Traite les lignes d'en-tête incorrectes comme si elles n'avaient pas été envoyées.
StartBody
A la réception de la première ligne d'en-tête incorrecte, les autres en-têtes sont lus et ce qui reste est traité en tant que corps. Ceci facilite la prise en compte des serveurs d'arrière-plan bogués qui oublient d'insérer une ligne vide entre les en-têtes et le corps.
top

Directive ProxyBlock

Description:Termes, serveurs ou domaines bloqués par le mandataire
Syntaxe:ProxyBlock *|terme|serveur|domaine [terme|serveur|domaine] ...
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

La directive ProxyBlock permet de spécifier une liste de termes, serveurs et/ou domaines, séparés par des espaces. Les requêtes de documents HTTP, HTTPS, FTP vers des sites dont les noms contiennent des termes, noms de serveur ou domaine correspondants seront bloqués par le serveur mandataire. La module proxy va aussi tenter de déterminer les adresses IP des éléments de la liste qui peuvent correspondre à des noms d'hôtes au cours du démarrage, et les mettra en cache à des fins de comparaisons ultérieures. Ceci peut ralentir le démarrage du serveur.

Exemple

ProxyBlock "news.example.com" "auctions.example.com" "friends.example.com"

Notez qu'example suffirait aussi pour atteindre ces sites.

Hosts conviendrait aussi s'il était référencé par adresse IP.

Notez aussi que

ProxyBlock "*"

bloque les connexions vers tous les sites.

top

Directive ProxyDomain

Description:Nom de domaine par défaut pour les requêtes mandatées
Syntaxe:ProxyDomain Domaine
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

Cette directive n'a d'utilité que pour les serveurs mandataires Apache httpd au sein d'un Intranet. La directive ProxyDomain permet de spécifier le domaine par défaut auquel le serveur mandataire apache appartient. Si le serveur reçoit une requête pour un hôte sans nom de domaine, il va générer une réponse de redirection vers le même hôte suffixé par le Domaine spécifié.

Exemple

ProxyRemote  "*"  "http://firewall.example.com:81"
NoProxy         ".example.com" "192.168.112.0/21"
ProxyDomain     ".example.com"
top

Directive ProxyErrorOverride

Description:Outrepasser les pages d'erreur pour les contenus mandatés
Syntaxe:ProxyErrorOverride Off|On [code ...]
Défaut:ProxyErrorOverride Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:La liste de codes d'états a été ajoutée à partir de la version 2.4.47 du serveur HTTP Apache.

Cette directive est utile pour les configurations de mandataires inverses, lorsque vous souhaitez que les pages d'erreur envoyées aux utilisateurs finaux présentent un aspect homogène. Elle permet aussi l'inclusion de fichiers (via les SSI de mod_include) pour obtenir le code d'erreur et agir en conséquence (le comportement par défaut afficherait la page d'erreur du serveur mandaté, alors que c'est le message d'erreur SSI qui sera affiché si cette directive est à "on").

Cette directive n'affecte pas le traitement des réponses informatives (1xx), de type succès normal (2xx), ou de redirection (3xx).

Par défaut, ProxyErrorOverride affecte toutes les réponses avec un code compris entre 400 inclus et 600 exclus.

Exemple de configuration par défaut

ProxyErrorOverride  On

Pour n'affecter que les réponses possèdant certains codes d'état particuliers, vous pouvez spécifier ces derniers sous la forme d'une liste en les séparant par des espaces. Les réponses dont le code d'état ne fait pas partie de la liste ne seront pas affectées. Vous ne pouvez spécifier que des codes d'erreurs, donc compris entre 400 inclus et 600 exclus.

Exemple de configuration personnalisée

ProxyErrorOverride  On 403 405 500 501 502 503 504
top

Directive ProxyIOBufferSize

Description:Détermine la taille du tampon interne de transfert de données
Syntaxe:ProxyIOBufferSize octets
Défaut:ProxyIOBufferSize 8192
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

La directive ProxyIOBufferSize permet d'ajuster la taille du tampon interne utilisé comme bloc-note pour les transferts de données entre entrée et sortie. La taille minimale est de 512 octets.

Dans la plupart des cas, il n'y a aucune raison de modifier cette valeur.

Si elle est utilisée avec AJP, cette directive permet de définir la taille maximale du paquet AJP en octets. Si la valeur spécifiée est supérieure à 65536, elle est corrigée et prend la valeur 65536. Si vous ne conservez pas la valeur par défaut, vous devez aussi modifier l'attribut packetSize de votre connecteur AJP du côté de Tomcat ! L'attribut packetSize n'est disponible que dans Tomcat 5.5.20+ et 6.0.2+.

Il n'est normalement pas nécessaire de modifier la taille maximale du paquet. Des problèmes ont cependant été rapportés avec la valeur par défaut lors de l'envoi de certificats ou de chaînes de certificats.

top

Directive <ProxyMatch>

Description:Conteneur de directives s'appliquant à des ressources mandatées correspondant à une expression rationnelle
Syntaxe:<ProxyMatch regex> ...</ProxyMatch>
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

La directive <ProxyMatch> est identique à la directive <Proxy>, à l'exception qu'elle définit les URLs auxquelles elle s'applique en utilisant une expression rationnelle.

A partir de la version 2.4.8, les groupes nommés et les références arrières sont extraits et enregistrés dans l'environnement avec leur nom en majuscules et préfixé par "MATCH_". Ceci permet de référencer des URLs dans des expressions ou au sein de modules comme mod_rewrite. Pour éviter toute confusion, les références arrières numérotées (non nommées) sont ignorées. Vous devez utiliser à la place des groupes nommés.

<ProxyMatch "^http://(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</ProxyMatch>

Voir aussi

top

Directive ProxyMaxForwards

Description:Nombre maximum de mandataires à travers lesquelles une requête peut être redirigée
Syntaxe:ProxyMaxForwards nombre
Défaut:ProxyMaxForwards -1
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:Comportement par défaut modifié dans 2.2.7

La directive ProxyMaxForwards permet de spécifier le nombre maximum de mandataires à travers lesquels une requête peut passer dans le cas où la la requête ne contient pas d'en-tête Max-Forwards. Ceci permet de se prémunir contre les boucles infinies de mandataires ou contre les attaques de type déni de service.

Exemple

ProxyMaxForwards 15

Notez que la définition de la directive ProxyMaxForwards constitue une violation du protocole HTTP/1.1 (RFC2616), qui interdit à un mandataire de définir Max-Forwards si le client ne l'a pas fait lui-même. Les versions précédentes d'Apache httpd la définissaient systématiquement. Une valeur négative de ProxyMaxForwards, y compris la valeur par défaut -1, implique un comportement compatible avec le protocole, mais vous expose aux bouclages infinis.

top

Directive ProxyPass

Description:Référencer des serveurs distants depuis l'espace d'URLs du serveur local
Syntaxe:ProxyPass [chemin] !|url [clé=valeur [clé=valeur ...]] [nocanon] [interpolate] [noquery]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:Les sockets de style Unix (Unix Domain Socket - UDS) sont supportés à partir de la version 2.4.7 du serveur HTTP Apache

Cette directive permet de référencer des serveurs distants depuis l'espace d'URLs du serveur local. Le serveur local n'agit pas en tant que mandataire au sens conventionnel, mais plutôt comme miroir du serveur distant. Le serveur local est souvent nommé mandataire inverse ou passerelle. L'argument chemin est le nom d'un chemin virtuel local ; url est une URL partielle pour le serveur distant et ne doit pas contenir de chaîne d'arguments.

Il est fortement recommandé de revoir le concept de Worker avant d'aller plus loin.
Cette directive n'est pas supportée au sein des sections <Directory>, <If> et <Files>.
En général, la directive ProxyRequests doit être définie à off lorsqu'on utilise la directive ProxyPass.

Les sockets de style Unix sont supportés à partir de la version 2.4.7 du serveur HTTP Apache ; pour utiliser cette fonctionnalité, il suffit d'utiliser une URL cible préfixée par unix:/path/lis.sock|. Par exemple, pour mandater HTTP et cibler l'UDS /home/www.socket, vous devez utiliser unix:/home/www.socket|http://localhost/whatever/.

Note :Le chemin associé à l'URL unix: tient compte de la directive DefaultRuntimeDir.

Lorsque cette directive est utilisée dans une section <Location>, le premier argument est omis et le répertoire local est obtenu à partir de l'argument de la directive <Location>. Il en est de même à l'intérieur d'une section <LocationMatch>, mais le résultat ne sera probablement pas celui attendu car ProxyPassReverse va interpréter l'expression rationnelle littéralement comme un chemin ; si besoin est dans ce cas, définissez la directive ProxyPassReverse en dehors de la section, ou dans une section <Location> séparée.

Supposons que le serveur local a pour adresse http://example.com/ ; alors la ligne

<Location "/mirror/foo/">
    ProxyPass "http://backend.example.com/"
</Location>

va convertir en interne toute requête pour http://example.com/mirror/foo/bar en une requête mandatée pour http://backend.example.com/bar.

Si vous avez besoin d'un configuration de mandataire inverse plus souple, reportez-vous à la documentaion de la directive RewriteRule et son drapeau [P].

La syntaxe alternative suivante est valide, bien qu'elle puisse induire une dégradation des performances lorsqu'elle est présente en très grand nombre. Elle possède l'avantage de permettre un contrôle dynamique via l'interface Balancer Manager :

ProxyPass "/mirror/foo/" "http://backend.example.com/"

Si le premier argument se termine par un slash /, il doit en être de même pour le second argument et vice versa. Dans le cas contraire, il risque de manquer des slashes nécessaires dans la requête résultante vers le serveur d'arrière-plan et les résulats ne seront pas ceux attendus.

Le drapeau ! permet de soustraire un sous-répertoire du mandat inverse, comme dans l'exemple suivant :

<Location "/mirror/foo/">
    ProxyPass "http://backend.example.com/"
</Location>
<Location "/mirror/foo/i">
    ProxyPass "!"
</Location>
ProxyPass "/mirror/foo/i" "!"
ProxyPass "/mirror/foo" "http://backend.example.com"

va mandater toutes les requêtes pour /mirror/foo vers backend.example.com, sauf les requêtes pour /mirror/foo/i.

Mélanger plusieurs configurations ProxyPass dans différents contextes ne fonctionne pas :

ProxyPass "/mirror/foo/i" "!"
<Location "/mirror/foo/">
    ProxyPass "http://backend.example.com/"
</Location>

Dans ce cas, une requête pour /mirror/foo/i sera tout de même mandatée car c'est la directive ProxyPass de la section Location qui sera évaluée en premier. Le fait que la directive ProxyPass supporte les deux contextes serveur principal et répertoire ne signifie pas que sa portée et sa position dans le fichier de configuration va garantir une quelconque priorité et/ou chronologie de prise en compte.

Ordre de classement des directives ProxyPass

Les directives ProxyPass et ProxyPassMatch sont évaluées dans l'ordre de leur apparition dans le fichier de configuration. La première règle qui correspond s'applique. Vous devez donc en général classer les règles ProxyPass qui entrent en conflit de l'URL la plus longue à la plus courte. Dans le cas contraire, les règles situées après une règle dont l'URL correspond au début de leur propre URL seront ignorées. Notez que tout ceci est en relation avec le partage de workers.

Chronologie de prise en compte des directives ProxyPass au sein des sections Locations

On ne peut placer qu'une seule directive ProxyPass dans une section Location, et c'est la section la plus spécifique qui l'emportera.

Exclusions et variable d'environnement no-proxy

Les exclusions doivent se situer avant les directives ProxyPass générales. A partir de la version 2.4.26 du serveur HTTP Apache, la variable d'environnement "no-proxy" est une alternative aux exclusions et constitue le seul moyen de configurer une exclusion pour une directive ProxyPass dans le contexte d'une section Location. Cette variable doit être définie via la directive SetEnvIf car la directive SetEnv n'est pas évaluée assez tôt.

ProxyPass clé=valeur Paramètres

Depuis la version 2.1 du serveur HTTP Apache, mod_proxy supporte les groupements de connexions vers un serveur d'arrière-plan. Les connexions créées à la demande peuvent être enregistrées dans un groupement pour une utilisation ultérieure. La taille du groupe ainsi que d'autres caractéristiques peuvent être définies via la directive ProxyPass au moyen de paramètres clé=valeur dont la description fait l'objet des tableaux ci-dessous.

Nombre maximum de connexions vers l'arrière-plan

Par défaut, mod_proxy permet et met en réserve le nombre maximum de connexions pouvant être utilisées simultanément par le processus enfant concerné du serveur web. Le paramètre max permet de réduire cette valeur par défaut. Le jeu de connexions est maintenu au niveau de chaque processus enfant du serveur web, max et les autres réglages n'étant pas coordonnés entre ces différents processus, sauf bien entendu lorsqu'un seul processus enfant n'est autorisé par la configuration ou le MPM utilisé.

Le paramètre ttl, quant à lui, permet de définir une durée de vie optionnelle ; les connexions qui n'ont pas été utilisées pendant au moins ttl secondes seront fermées. ttl permet aussi d'empêcher l'utilisation d'une connexion susceptible d'être fermée suite à une fin de vie de connexion persistante sur le serveur d'arrière-plan.

Exemple

ProxyPass "/example" "http://backend.example.com" max=20 ttl=120 retry=300
Paramètres de worker (directive BalancerMember)
Paramètre Défaut Description
min 0 Nombre minimum d'entrées dans le pool de connexions, distinct du nombre de connexions effectif. La valeur par défaut ne doit être modifiée que dans des circonstances particulières où la mémoire associée aux connexions avec le serveur d'arrière-plan doit être préallouée ou réservée dans le tas.
max 1...n Nombre maximum de connexions autorisées vers le serveur d'arrière-plan. La valeur par défaut correspond au nombre de threads par processus pour le MPM (Module Multi Processus) actif. La valeur sera toujours 1 pour le MPM Prefork, alors qu'elle dépendra de la définition de la directive ThreadsPerChild pour les autres MPMs.
smax max Les entrées du pool de connexions conservées au delà de cette limite sont libérées au cours de certaines opérations si elles n'ont pas été utilisées au cours de leur durée de vie, définie par le paramètre ttl. Si l'entrée du pool de connexions est associée à une connexion, cette dernière sera fermée. La valeur par défaut ne doit être modifiée que dans des circonstances particulières où les entrées du pool de connexions et toutes connexions associées qui ont dépassé leur durée de vie doivent être libérées ou fermées de manière plus autoritaire.
acquire - Cette clé permet de définir le délai maximum d'attente pour une connexion libre dans le jeu de connexions, en millisecondes. S'il n'y a pas de connexion libre dans le jeu, Apache httpd renverra l'état SERVER_BUSY au client.
connectiontimeout timeout Délai d'attente d'une connexion en secondes. La durée en secondes pendant laquelle Apache httpd va attendre pour l'établissement d'une connexion vers le serveur d'arrière-plan. Le délai peut être spécifié en millisecondes en ajoutant le suffixe ms.
disablereuse Off Vous pouvez utiliser cette clé pour forcer mod_proxy à fermer immédiatement une connexion vers le serveur d'arrière-plan après utilisation, et ainsi désactiver le jeu de connexions permanentes vers ce serveur. Ceci peut s'avérer utile dans des situations où un pare-feu situé entre Apache httpd et le serveur d'arrière-plan (quelque soit le protocole) interrompt des connexions de manière silencieuse, ou lorsque le serveur d'arrière-plan lui-même est accessible par rotation de DNS (round-robin DNS). Lorsque la réutilisation des connexions est activée, chaque domaine d'arrière-plan n'est résolu (via une requête DNS) qu'une seule fois par chaque processus enfant et mis en cache pour toutes les connexions ultérieures jusqu'au recyclage du processus concerné. Pour désactiver la réutilisation du jeu de connexions, définissez cette clé à On.
enablereuse On Ce paramètre est utilisé par les gestionnaires de protocole pour lesquels la réutilisation des connexions est optionnelle (comme mod_proxy_fcgi). C'est le contraire du paramètre 'disablereuse' ci-dessus, et il est supporté par les versions 2.4.11 et supérieures du serveur HTTP Apache.
flushpackets off Permet de définir si le module mandataire doit vider automatiquement le tampon de sortie après chaque tronçon de données. 'off' signifie que le tampon sera vidé si nécessaire ; 'on' signifie que le tampon sera vidé après chaque envoi d'un tronçon de données, et 'auto' que le tampon sera vidé après un délai de 'flushwait' millisecondes si aucune entrée n'est reçue. Actuellement, cette clé n'est supportée que par mod_proxy_ajp et mod_proxy_fcgi.
flushwait 10 Le délai d'attente pour une entrée additionnelle, en millisecondes, avant le vidage du tampon en sortie dans le cas où 'flushpackets' est à 'auto'.
iobuffersize 8192 Permet de définir la taille du tampon d'entrées/sorties du bloc-notes interne. Cette clé vous permet d'outrepasser la directive ProxyIOBufferSize pour un serveur cible spécifique. La valeur doit être au minimum 512 ou définie à 0 pour la valeur par défaut du système de 8192.
responsefieldsize 8192 Contrôle la taille du tampon pour le champ de la réponse mandatée. Cette taille doit être au moins égale à la taille attendue du plus grand en-tête d'une réponse mandatée. Une valeur de 0 implique l'utilisation de la valeur par défaut du système, à savoir 8192 octets.
Disponible à partir de la version 2.4.34 du serveur HTTP Apache.
keepalive Off

Cette clé doit être utilisée lorsque vous avez un pare-feu entre Apache httpd et le serveur d'arrière-plan, et si ce dernier tend à interrompre les connexions inactives. Cette clé va faire en sorte que le système d'exploitation envoie des messages KEEP_ALIVE sur chacune des connexions inactives et ainsi éviter la fermeture de la connexion par le pare-feu. Pour conserver les connexions persistantes, definissez cette propriété à On.

La fréquence de vérification des connexions TCP persistantes initiale et subséquentes dépend de la configuration globale de l'OS, et peut atteindre 2 heures. Pour être utile, la fréquence configurée dans l'OS doit être inférieure au seuil utilisé par le pare-feu.

lbset 0 Définit le groupe de répartition de charge dont le serveur cible est membre. Le répartiteur de charge va essayer tous les membres d'un groupe de répartition de charge de numéro inférieur avant d'essayer ceux dont le groupe possède un numéro supérieur.
ping 0 Avec la clé Ping, le serveur web va "tester" la connexion vers le serveur d'arrière-plan avant de transmettre la requête. Avec AJP, mod_proxy_ajp envoie une requête CPING sur la connexion ajp13 (implémenté sur Tomcat 3.3.2+, 4.1.28+ et 5.0.13+). Avec HTTP, mod_proxy_http envoie 100-Continue au serveur d'arrière-plan (seulement avecHTTP/1.1 - pour les serveurs d'arrière-plan non HTTP/1.1, cette clé ne produit aucun effet). Dans les deux cas, ce paramètre correspond au délai en secondes pour l'attente de la réponse. Cette fonctionnalité a été ajoutée pour éviter les problèmes avec les serveurs d'arrière-plan bloqués ou surchargés. Le trafic réseau peut s'en trouver augmenté en fonctionnement normal, ce qui peut poser problème, mais peut s'en trouver diminué dans les cas où les noeuds de cluster sont arrêtés ou surchargés. Le délai peut aussi être défini en millisecondes en ajoutant le suffixe ms.
receivebuffersize 0 Définit la taille du tampon réseau explicite (TCP/IP) pour les connexions mandatées. Cette clé vous permet d'outrepasser la directive ProxyReceiveBufferSize pour un serveur cible spécifique. Sa valeur doit être au minimum 512 ou définie à 0 pour la valeur par défaut du système.
redirect - Route pour la redirection du serveur cible. Cette valeur est en général définie dynamiquement pour permettre une suppression sécurisée du noeud du cluster. Si cette clé est définie, toutes les requêtes sans identifiant de session seront redirigées vers le membre de groupe de répartition de charge dont la route correspond à la valeur de la clé.
retry 60 Délai entre deux essais du serveur cible du jeu de connexions en secondes. Si le serveur cible du jeu de connexions vers le serveur d'arrière-plan est dans un état d'erreur, Apache httpd ne redirigera pas de requête vers ce serveur avant l'expiration du délai spécifié. Ceci permet d'arrêter le serveur d'arrière-plan pour maintenance, et de le remettre en ligne plus tard. Une valeur de 0 implique de toujours essayer les serveurs cibles dans un état d'erreur sans délai.
route - La route du serveur cible lorsqu'il est utilisé au sein d'un répartiteur de charge. La route est une valeur ajoutée à l'identifiant de session.
status - Valeur constituée d'une simple lettre et définissant l'état initial de ce serveur cible.
D: le serveur cible est désactivé et n'accepte aucune requête.
S: le serveur cible est arrêté.
I: le serveur cible est en mode "erreurs ignorées", et sera toujours considéré comme disponible.
R: Le serveur cible sert de remplaçant à chaud. Lorsqu'un serveur cible avec un lbset donné est inutilisable (maintenance, arrêt, en erreur, etc...), un serveur de remplacement à chaud libre de même lbset sera utilisé à sa place. Les remplaçants à chaud permettent de s'assurer qu'un nombre déterminé de serveurs cibles sera toujours disponible pour un répartiteur de charge.
H: le serveur cible est en mode d'attente et ne sera utilisé que si aucun autre serveur ou remplaçant à chaud n'est disponible dans le jeu de serveurs cibles.
E: le serveur cible est en erreur.
N: le serveur cible est en mode vidage, n'acceptera que les sessions persistantes qui lui appartiennent, et refusera toutes les autres requêtes.
Une valeur d'état peut être définie (ce qui correspond au comportement par défaut) en préfixant la valeur par '+', ou annulée en préfixant la valeur par '-'. Ainsi, la valeur 'S-E' définit l'état de ce serveur cible à "arrêté" et supprime le drapeau "en-erreur".
timeout ProxyTimeout Délai d'attente du socket en secondes. Le nombre de secondes pendant lesquelles Apache httpd attend l'envoi de données vers le serveur d'arrière-plan.
ttl - Durée de vie des connexions inactives et des entrées du pool de connexions associées en secondes. Une fois cette limite atteinte, une connexion ne sera pas réutilisée ; elle sera fermée après un délai variable.
flusher flush

Nom du fournisseur utilisé par mod_proxy_fdpass. Voir la documentation de ce module pour plus de détails.

secret - Le mot de passe utilisé par mod_proxy_ajp. Il doit identique au mot de passe configuré sur le côté serveur de la connexion AJP.
Disponible à partir de la version 2.4.42 du serveur HTTP Apache.
upgrade -

Protocole pris en charge par mod_proxy_http ou mod_proxy_wstunnel pour le mécanisme de promotion de protocole HTTP lors d'une négociation du client/navigateur HTTP (en accord avec RFC 9110 - Upgrade). Voir la note Promotion de protocole ci-dessous

mapping -

Type de mappage entre le chemin et l'url. Détermine la normalisation et/ou le (non-)décodage que mod_proxy appliquera au chemin de l'uri demandé avant de rechercher une correspondance avec le chemin. Si un mappage correspond, il est appliqué au chemin de l'uri de façon à ce que tous les contextes de répertoire qui utilisent un chemin (comme <Location>) fassent l'objet d'une recherche de correspondance en utilisant le même mappage.

mapping=encoded empêche le décodage des caractères % contenus dans le chemin de l'uri de façon à ce que l'on puisse par exemple utiliser des configurations telles que :

ProxyPass "/special%3Fsegment" "https://example.com/special%3Fsegment" mapping=encoded
<Location "/special%3Fsegment">
  Require ip 172.17.2.0/24
</Location>

mapping=servlet se réfère à la normalisation définie par la spécification de la Servlet qui sera par exemple appliquée par Apache Tomcat pour les conteneurs de servlet (en particulier, les paramètres du chemin sont ignorés pour le mappage). Un chemin d'uri comme /some;foo/path sera alors mappé comme /some/path et correspondra donc à tout ce qui suit sans tenir compte des paramètres du chemin demandé :

ProxyPass "/some/path" "https://servlet.example.com/some/path" mapping=servlet
<Location "/some/path">
  Require valid-user
</Location>

Note

Il est recommandé d'utiliser le même mappage côté Apache httpd que celui utilisé côté arrière-plan. Par exemple, lors de la configuration des autorisations dans les sections <Location> pour des chemins mappés par mod_proxy comme conteneurs de servlet (comme les applications s'exécutant sous Apache Tomcat), on doit utiliser la définition mapping=servlet pour éviter que les paramètres du chemin et similaires n'interfèrent avec les autorisations qui doivent être définies par Apache httpd.

addressttl -1

Durée de vie (TTL) en secondes des résolutions DNS de l'adresse du serveur d'arrière-plan dans le cache. -1 signifie jusqu'au redémarrage de Apache httpd.

Si l'URL de la directive Proxy débute par balancer:// (par exemple: balancer://cluster, toute information relative au chemin est ignorée), alors un serveur cible virtuel ne communiquant pas réellement avec le serveur d'arrière-plan sera créé. Celui-ci sera en fait responsable de la gestion de plusieurs serveurs cibles "réels". Dans ce cas, un jeu de paramètres particuliers s'applique à ce serveur cible virtuel. Voir mod_proxy_balancer pour plus d'informations à propos du fonctionnement du répartiteur de charge.

Paramètres du répartiteur
Paramètre Défaut Description
lbmethod byrequests Méthode de répartition de charge utilisée. Permet de sélectionner la méthode de planification de la répartition de charge à utiliser. La valeur est soit byrequests, pour effectuer un décompte de requêtes pondérées, soit bytraffic, pour effectuer une répartition en fonction du décompte des octets transmis, soit bybusyness, pour effectuer une répartition en fonction des requêtes en attente. La valeur par défaut est byrequests.
maxattempts 1 de moins que le nombre de workers, ou 1 avec un seul worker Nombre maximum d'échecs avant abandon.
nofailover Off Si ce paramètre est défini à On, la session va s'interrompre si le serveur cible est dans un état d'erreur ou désactivé. Définissez ce paramètre à On si le serveur d'arrière-plan ne supporte pas la réplication de session.
stickysession - Nom de session persistant du répartiteur. La valeur est généralement du style JSESSIONID ou PHPSESSIONID, et dépend du serveur d'application d'arrière-plan qui supporte les sessions. Si le serveur d'application d'arrière-plan utilise un nom différent pour les cookies et les identifiants codés d'URL (comme les conteneurs de servlet), séparez-les par le caractère '|'. La première partie contient le cookie et la seconde le chemin.
Disponible depuis la version 2.4.4 du serveur HTTP Apache.
stickysessionsep "." Définit le caractère de séparation dans le cookie de session. Certains serveurs d'application d'arrière-plan n'utilisent pas le caractère '.' comme séparateur. Par exemple le serveur Oracle Weblogic utilise le caractère '!'. Cette option permet d'attribuer au caractère de séparation la valeur appropriée. Si elle est définie à 'Off', aucun caractère de séparation n'est utilisé.
scolonpathdelim Off Si ce paramètre est défini à On, le caractère ';' sera utilisé comme séparateur de chemin de session persistante additionnel. Ceci permet principalement de simuler le comportement de mod_jk lorsqu'on utilise des chemins du style JSESSIONID=6736bcf34;foo=aabfa.
timeout 0 Délai du répartiteur en secondes. Si ce paramètre est défini, sa valeur correspond à la durée maximale d'attente pour un serveur cible libre. Le comportement par défaut est de ne pas attendre.
failonstatus - Une liste de codes d'état HTTP séparés par des virgules. Si ce paramètre est présent, le worker se mettra en erreur si le serveur d'arrière-plan renvoie un des codes d'état spécifiés dans la liste. La récupération du worker s'effectue comme dans le cas des autres erreurs de worker.
failontimeout Off Si ce paramètre est défini à "On", un délai d'attente dépassé en entrée/sortie après envoi d'une requête au serveur d'arrière-plan va mettre le processus en état d'erreur. La sortie de cet état d'erreur se passe de la même façon que pour les autres erreurs.
Disponible à partir de la version 2.4.5 du serveur HTTP Apache.
nonce <auto> Le nombre à usage unique de protection utilisé dans la page de l'application balancer-manager. Par défaut, la protection de la page est assurée par un nombre à usage unique automatique à base d'UUID. Si une valeur est précisée, elle sera utilisée comme nombre à usage unique. La valeur None désactive la vérification du nombre à usage unique.

Note

En plus du nombre à usage unique, la page de l'application balancer-manager peut être protégée par une ACL.

growth 0 Nombre de membres supplémentaires que l'on peut ajouter à ce répartiteur en plus de ceux définis au niveau de la configuration.
forcerecovery On Force la relance immédiate de tous les membres sans tenir compte de leur paramètre retry dans le cas où ils sont tous en état d'erreur. Il peut cependant arriver qu'un membre déjà surchargé entre dans une situation critique si la relance de tous les membres est forcée sans tenir compte du paramètre retry de chaque membre. Dans ce cas, définissez ce paramètre à Off.
Disponible depuis la version 2.4.2 du serveur HTTP Apache.

Exemple de configuration d'un répartiteur de charge

ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On
<Proxy "balancer://mycluster">
    BalancerMember "ajp://1.2.3.4:8009"
    BalancerMember "ajp://1.2.3.5:8009" loadfactor=20
    # Less powerful server, don't send as many requests there,
    BalancerMember "ajp://1.2.3.6:8009" loadfactor=5
</Proxy>

La définition de remplaçants à chaud permet de s'assurer qu'un nombre déterminé de serveurs sera toujours disponible dans le jeu de serveurs cibles :

ProxyPass "/" "balancer://sparecluster/"
<Proxy balancer://sparecluster>
    BalancerMember ajp://1.2.3.4:8009
    BalancerMember ajp://1.2.3.5:8009
    # Les serveurs ci-dessous sont des remplaçants à chaud. Pour chaque serveur
    # ci-dessus qui viendrait à être inutilisable (maintenance, arrêt, non
    # contactable, en erreur, etc...), un de ces remplaçants à chaud prendra sa
    # place. Deux serveurs seront toujours disponibles pour traiter une requête
    # (à moins qu'un ou plusieurs remplaçant à chaud soit lui aussi
    # indisponible).
    BalancerMember ajp://1.2.3.6:8009 status=+R
    BalancerMember ajp://1.2.3.7:8009 status=+R
</Proxy>

Configuration d'un serveur cible de réserve qui ne sera utilisé que si aucun autre serveur cible ou remplaçant à chaud n'est disponible dans le jeu de serveurs cibles :

ProxyPass "/" "balancer://hotcluster/"
<Proxy "balancer://hotcluster">
    BalancerMember "ajp://1.2.3.4:8009" loadfactor=1
    BalancerMember "ajp://1.2.3.5:8009" loadfactor=2.25
    # The server below is on hot standby
    BalancerMember "ajp://1.2.3.6:8009" status=+H
    ProxySet lbmethod=bytraffic
</Proxy>

Mots-clés additionnels de ProxyPass

Normalement, mod_proxy va mettre sous leur forme canonique les URLs traitées par ProxyPass. Mais ceci peut être incompatible avec certains serveurs d'arrière-plan, et en particulier avec ceux qui utilisent PATH_INFO. Le mot-clé optionnel nocanon modifie ce comportement et permet de transmettre le chemin d'URL sous sa forme brute au serveur d'arrière-plan. Notez que ceci peut affecter la sécurité de votre serveur d'arrière-plan, car la protection limitée contre les attaques à base d'URL que fournit le mandataire est alors supprimée.

Par défaut, mod_proxy inclut la chaîne de paramètres lors de la génération de la variable d'environnement SCRIPT_FILENAME. Le mot-clé optionnel noquery (disponible à partir de la version 2.4.1) permet d'exclure cette chaîne.

Lorsque la directive ProxyPass est utilisée à l'intérieur d'une section <Location>, le premier argument est omis et le répertoire local est obtenu à partir de la section <Location>. Il en sera de même dans une section <LocationMatch> ; cependant, ProxyPass n'interprète pas les expressions rationnelles, et il sera ici nécessaire d'utiliser la directive ProxyPassMatch à la place.

Cette directive ne peut pas être placée dans une section <Directory> ou <Files>.

Si vous avez besoin d'un configuration de mandataire inverse plus souple, reportez-vous à la documentaion de la directive RewriteRule et son drapeau [P].

Le mot-clé optionnel interpolate, en combinaison avec la directive ProxyPassInterpolateEnv, permet à ProxyPass d'interpoler les variables d'environnement à l'aide de la syntaxe ${VARNAME}. Notez que de nombreuses variables d'environnement standard dérivées de CGI n'existeront pas lorsque l'interpolation se produit ; vous devrez alors encore avoir avoir recours à mod_rewrite pour des règles complexes. Notez aussi que l'interpolation n'est supportée dans la partie protocole/hostname/port d'une URL que pour les variables qui sont disponibles au moment où la directive est interprétée (comme pour la directive Define). La détermination dynamique de ces champs peut être effectuée à l'aide de mod_rewrite, et l'exemple suivant décrit comment utiliser mod_rewrite pour définir dynamiquement le protocole à http ou https :

RewriteEngine On

RewriteCond "%{HTTPS}" =off
RewriteRule "". "-" [E=protocol:http]
RewriteCond "%{HTTPS}" =on
RewriteRule "." "-" [E=protocol:https]

RewriteRule "^/mirror/foo/(.*)" "%{ENV:protocol}://backend.example.com/$1" [P]
ProxyPassReverse  "/mirror/foo/" "http://backend.example.com/"
ProxyPassReverse  "/mirror/foo/" "https://backend.example.com/"

Promotion de protocole

Depuis la version 2.4.47 du serveur HTTP Apache, la promotion de protocole (tunneling) peut être géré bout à bout par mod_proxy_http en utilisant le paramètre upgrade.

Bout à bout signifie que la requête de promotion de protocole en provenance du client/navigateur est tout d'abord transmise par mod_proxy_http au serveur origine et que le protocole de la connexion ne sera modifié (et « tunnelisé » par mod_proxy_http) que si le serveur origine accepte/initie la promotion (réponse HTTP 101 Switching Protocols). Si le serveur origine renvoie une réponse différente, mod_proxy_http continuera la transmission en utilisant (et en forçant) le protocole HTTP habituel pour cette connexion.

Voir Promotion de protocole vers Websocket (versions 2.4.47 et ultérieures) pour un exemple de configuration qui utilisemod_proxy_http.

Avec les versions 2.4.46 et antérieures du serveur HTTP Apache (ou si la directive ProxyWebsocketFallbackToProxyHttp des versions 2.4.48 et ultérieures désactive la prise en charge par mod_proxy_http), voir la documentation de mod_proxy_wstunnel pour la méthode permettant de mandater le protocole WebSocket.

top

Directive ProxyPassInherit

Description:Héritage des directives ProxyPass définies au niveau du serveur principal
Syntaxe:ProxyPassInherit On|Off
Défaut:ProxyPassInherit On
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible à partir de la version 2.4.5 du serveur HTTP Apache.

Cette directive permet à un serveur virtuel d'hériter des directives ProxyPass définies au niveau du serveur principal. Si vous utilisez la fonctionnalité de modifications dynamiques du Balancer Manager, cette directive peut causer des problèmes et des comportements inattendus et doit donc être désactivée.

Les valeurs définies au niveau du serveur principal constituent les valeurs par défaut pour tous les serveurs virtuels.

La désactivation de ProxyPassInherit désactive aussi la directive BalancerInherit.

top

Directive ProxyPassInterpolateEnv

Description:Active l'interpolation des variables d'environnement dans les configurations de mandataires inverses
Syntaxe:ProxyPassInterpolateEnv On|Off
Défaut:ProxyPassInterpolateEnv Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible depuis la version 2.2.9 d'Apache

Cette directive, ainsi que l'argument interpolate des directives ProxyPass, ProxyPassReverse, ProxyPassReverseCookieDomain et ProxyPassReverseCookiePath, permet de configurer dynamiquement un mandataire inverse à l'aide de variables d'environnement, ces dernières pouvant être définies par un autre module comme mod_rewrite. Elle affecte les directives ProxyPass, ProxyPassReverse, ProxyPassReverseCookieDomain, et ProxyPassReverseCookiePath, en leur indiquant de remplacer la chaîne ${nom_var} dans les directives de configuration par la valeur de la variable d'environnement nom_var (si l'option interpolate est spécifiée).

La partie protocole/hostname/port de ProxyPass peut contenir des variables, mais seulement celles qui sont accessibles au moment où la directive est interprétée (similairement à la directive Define). Pour tous les autres cas, utilisez plutôt mod_rewrite.

Avertissement concernant les performances

Laissez cette directive à off, à moins que vous n'en ayez réellemnt besoin ! Par exemple, ajouter des variables à ProxyPass peut entraîner l'utilisation des serveurs d'arrière-plan de mod_proxy configurés par défaut, et ceux-ci ne permettent pas un réglage fin comme la réutilisation des connexions, entre autres...).

top

Directive ProxyPassMatch

Description:Fait correspondre des serveurs distants dans l'espace d'URL du serveur local en utilisant des expressions rationnelles
Syntaxe:ProxyPassMatch [regex] !|url [key=value [key=value ...]]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:Depuis la version 2.4.47, les paramètres key=value sont pris en compte lorsque le paramètre url contient des références arrières (voir note ci-dessous).

Cette directive est identique à la directive ProxyPass, mais fait usage des expressions rationnelles, au lieu d'une simple comparaison de préfixes. L'expression rationnelle spécifiée est comparée à l'url, et si elle correspond, le serveur va substituer toute correspondance entre parenthèses dans la chaîne donnée et l'utiliser comme nouvelle url.

Note : Cette directive ne peut pas être utilisée dans un contexte de niveau répertoire.

Supposons que le serveur local a pour adresse http://example.com/ ; alors

ProxyPassMatch "^(/.*\.gif)$" "http://backend.example.com/$1"

va provoquer la conversion interne de la requête locale http://example.com/foo/bar.gif en une requête mandatée pour http://backend.example.com/foo/bar.gif.

Le drapeau ! vous permet de ne pas mandater un sous-répertoire donné.

Dans une section <LocationMatch>, le premier argument est omis et l'expression rationnelle est obtenue à partir de la directive <LocationMatch>.

Si vous avez besoin d'une configuration du mandataire inverse plus flexible, voyez la directive RewriteRule avec le drapeau [P].

Substitution par défaut

Lorsque le paramètre URL n'utilise pas de références arrières dans l'expression rationnelle, l'URL originale sera ajoutée au paramètre URL.

Paramètres key=value et url avec références arrières

Depuis la version 2.4.47, les paramètres key=value ne sont plus ignorés dans une directive ProxyPassMatch lorsqu'on utilise une url contenant des références arrières. Cependant, pour conserver le comportement précédent relatif à la réutilisation/conservation des connexions d'arrière-plan (qui n'avaient jamais été réutilisées auparavant pour ces URLs), les paramètres enablereuse et disablereuse prendront dans ce cas respectivement comme valeurs par défaut off et on. Définir explicitement enablereuse=on permet de réutiliser les connexions, sauf si des références arrières se trouvent dans la partie authority (nom d'hôte et/ou port) de l'url (cette condition est imposée depuis la version 2.4.55 du serveur HTTP Apache et provoque un avertissement au démarrage car ces URLs ne sont pas réutilisables sous cette forme).

Avertissement à propos de la sécurité

Lors de la construction de l'URL cible de la règle, il convient de prendre en compte l'impact en matière de sécurité qu'aura le fait de permettre au client d'influencer le jeu d'URLs pour lesquelles votre serveur agira en tant que mandataire. Assurez-vous que la partie protocole://nom-serveur de l'URL soit fixe, ou ne permette pas au client de l'influencer induement.

top

Directive ProxyPassReverse

Description:Ajuste l'URL dans les en-têtes de la réponse HTTP envoyée par un serveur mandaté en inverse
Syntaxe:ProxyPassReverse [chemin] url [interpolate]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy

Cette directive permet de faire en sorte qu'Apache httpd ajuste l'URL dans les en-têtes Location, Content-Location et URI des réponses de redirection HTTP. Ceci est essentiel lorsqu'Apache httpd est utilisé en tant que mandataire inverse (ou passerelle), afin d'éviter de court-circuiter le mandataire inverse suite aux redirections HTTP sur le serveur d'arrière-plan qui restent derrière le mandataire inverse.

Seuls les en-têtes de réponse HTTP spécialement mentionnés ci-dessus seront réécrits. Apache httpd ne réécrira ni les autres en-têtes de réponse, ni par défaut les références d'URLs dans les pages HTML. Cela signifie que dans le cas où un contenu mandaté contient des références à des URLs absolues, elles court-circuiteront le mandataire. Pour réécrire un contenu HTML afin qu'il corresponde au mandataire, vous devez charger et activer le module mod_proxy_html.

chemin est le nom d'un chemin virtuel local. url est une URL partielle pour le serveur distant. Ces paramètres s'utilisent de la même façon qu'avec la directive ProxyPass.

Supposons par exemple que le serveur local a pour adresse http://example.com/ ; alors

ProxyPass         "/mirror/foo/" "http://backend.example.com/"
ProxyPassReverse  "/mirror/foo/" "http://backend.example.com/"
ProxyPassReverseCookieDomain  "backend.example.com" "public.example.com"
ProxyPassReverseCookiePath  "/"  "/mirror/foo/"

ne va pas seulement provoquer la conversion interne d'une requête locale pour http://example.com/mirror/foo/bar en une requête mandatée pour http://backend.example.com/bar (la fonctionnalité fournie par ProxyPass). Il va aussi s'occuper des redirections que le serveur backend.example.com envoie lorsqu'il redirige http://backend.example.com/bar vers http://backend.example.com/quux. Apache httpd corrige ceci en http://example.com/mirror/foo/quux avant de faire suivre la redirection HTTP au client. Notez que le nom d'hôte utilisé pour construire l'URL est choisi en respectant la définition de la directive UseCanonicalName.

Notez que la directive ProxyPassReverse peut aussi être utilisée en conjonction avec la fonctionnalité de mandataire (RewriteRule ... [P]) du module mod_rewrite, car elle ne dépend pas d'une directive ProxyPass correspondante.

Le mot-clé optionnel interpolate, en combinaison avec la directive ProxyPassInterpolateEnv, permet l'interpolation des variables d'environnement spécifiées en utilisant le format ${VARNAME} Notez que l'interpolation n'est pas supportée dans la partie protocole d'une URL.

Lorsque cette directive est utilisée dans une section <Location>, le premier argument est omis et le répertoire local est obtenu à partir de l'argument de la directive <Location>. Il en est de même à l'intérieur d'une section <LocationMatch>, mais le résultat ne sera probablement pas celui attendu car ProxyPassReverse va interpréter l'expression rationnelle littéralement comme un chemin ; si besoin est dans ce cas, définissez la directive ProxyPassReverse en dehors de la section, ou dans une section <Location> séparée.

Cette directive ne peut pas être placée dans une section <Directory> ou <Files>.

top

Directive ProxyPassReverseCookieDomain

Description:Ajuste la chaîne correspondant au domaine dans les en-têtes Set-Cookie en provenance d'un serveur mandaté
Syntaxe:ProxyPassReverseCookieDomain domaine-interne domaine-public [interpolate]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy

L'utilisation de cette directive est similaire à celle de la directive ProxyPassReverse, mais au lieu de réécrire des en-têtes qui contiennent des URLs, elle réécrit la chaîne correspondant au domaine dans les en-têtes Set-Cookie.

top

Directive ProxyPassReverseCookiePath

Description:Ajuste la chaîne correspondant au chemin dans les en-têtes Set-Cookie en provenance d'un serveur mandaté
Syntaxe:ProxyPassReverseCookiePath chemin-interne chemin-public [interpolate]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy

Cette directive s'avère utile en conjonction avec la directive ProxyPassReverse dans les situations où les chemins d'URL d'arrière-plan correspondent à des chemins publics sur le mandataire inverse. Cette directive permet de réécrire la chaîne path dans les en-têtes Set-Cookie. Si le début du chemin du cookie correspond à chemin-interne, le chemin du cookie sera remplacé par chemin-public.

Dans l'exemple fourni avec la directive ProxyPassReverse, la directive :

ProxyPassReverseCookiePath  "/"  "/mirror/foo/"

va réécrire un cookie possédant un chemin d'arrière-plan / (ou /example ou en fait tout chemin) en /mirror/foo/..

top

Directive ProxyPreserveHost

Description:Utilise l'en-tête de requête entrante Host pour la requête du mandataire
Syntaxe:ProxyPreserveHost On|Off
Défaut:ProxyPreserveHost Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:Utilisable dans un contexte de répertoire depuis la version 2.3.3.

Lorsqu'elle est activée, cette directive va transmettre l'en-tête Host: de la requête entrante vers le serveur mandaté, au lieu du nom d'hôte spécifié par la directive ProxyPass.

Cette directive est habituellement définie à Off. Elle est principalement utile dans les configurations particulières comme l'hébergement virtuel mandaté en masse à base de nom, où l'en-tête Host d'origine doit être évalué par le serveur d'arrière-plan.

top

Directive ProxyReceiveBufferSize

Description:Taille du tampon réseau pour les connexions mandatées HTTP et FTP
Syntaxe:ProxyReceiveBufferSize octets
Défaut:ProxyReceiveBufferSize 0
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

La directive ProxyReceiveBufferSize permet de spécifier une taille de tampon réseau explicite (TCP/IP) pour les connexions mandatées HTTP et FTP, afin d'améliorer le débit de données. Elle doit être supérieure à 512 ou définie à 0 pour indiquer que la taille de tampon par défaut du système doit être utilisée.

Exemple

ProxyReceiveBufferSize 2048
top

Directive ProxyRemote

Description:Mandataire distant à utiliser pour traiter certaines requêtes
Syntaxe:ProxyRemote match remote-server [username:password]
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:Le troisième argument facultatif est disponible depuis la version 2.4.59 du serveur HTTP Apache.

Cette directive permet de définir des mandataires distants pour ce mandataire. match est soit le nom d'un protocole que supporte le serveur distant, soit une URL partielle pour laquelle le serveur distant devra être utilisé, soit * pour indiquer que le serveur distant doit être utilisé pour toutes les requêtes. remote-server est une URL partielle correspondant au serveur distant. Syntaxe :

remote-server = scheme://hostname[:port]

scheme est effectivement le protocole à utiliser pour communiquer avec le serveur distant ; ce module ne supporte que http et https. Lorsqu'on utilise https, les requêtes sont redirigées par le mandataire distant en utilisant la méthode HTTP CONNECT.

Exemple

ProxyRemote "http://goodguys.example.com/" "http://mirrorguys.example.com:8000"
ProxyRemote "*" "http://cleverproxy.localdomain"
ProxyRemote "ftp" "http://ftpproxy.mydomain:8080"

Dans la dernière ligne de l'exemple, le mandataire va faire suivre les requêtes FTP, encapsulées dans une autre requête mandatée HTTP, vers un autre mandataire capable de les traiter.

Cette directive supporte aussi les configurations de mandataire inverse ; un serveur web d'arrière-plan peut être intégré dans l'espace d'URL d'un serveur virtuel, même si ce serveur est caché par un autre mandataire direct.

Le troisième argument optionnel username:password permet de spécifier des données d'authentification basiques à transmettre au mandataire distant défini. Ces données d'authentification seront toujoujours envoyées sans attendre que le mandataire distant n'effectue une demande d'authentification. La variable d'environnement Proxy-Chain-Auth n'est plus prise en compte si cet argument est utilisé.

top

Directive ProxyRemoteMatch

Description:Le mandataire distant à utiliser pour traiter les requêtes correspondant à une expression rationnelle
Syntaxe:ProxyRemoteMatch regex remote-server [username:password]
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:Le troisième argument facultatif est disponible à partir de la version 2.4.59 du serveur HTTP Apache.

La directive ProxyRemoteMatch est identique à la directive ProxyRemote, à l'exception du premier argument qui est une expression rationnelle à mettre en correspondance avec l'URL de la requête.

top

Directive ProxyRequests

Description:Active la fonctionnalité (standard) de mandataire direct
Syntaxe:ProxyRequests On|Off
Défaut:ProxyRequests Off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

Cette directive permet d'activer/désactiver la fonctionnalité de serveur mandataire direct d'Apache httpd. Définir ProxyRequests à Off n'interdit pas l'utilisation de la directive ProxyPass.

Pour une configuration typique de mandataire inverse ou passerelle, cette directive doit être définie à Off.

Afin d'activer la fonctionnalité de mandataire pour des sites HTTP et/ou FTP, les modules mod_proxy_http et/ou mod_proxy_ftp doivent également être chargés dans le serveur.

Pour activer la fonctionnalité de mandataire sur les sites chiffrés en HTTPS, le module mod_proxy_connect doit également être chargé dans le serveur.

Avertissement

N'activez pas la fonctionnalité de mandataire avec la directive ProxyRequests avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Voir aussi

top

Directive ProxySet

Description:Définit différents paramètres relatifs à la répartition de charge des mandataires et aux membres des groupes de répartition de charge
Syntaxe:ProxySet url clé=valeur [clé=valeur ...]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy
Compatibilité:ProxySet n'est disponible que depuis la version 2.2 du serveur HTTP Apache.

Cette directive propose une méthode alternative pour définir tout paramètre relatif aux répartiteurs de charge et serveurs cibles de mandataires normalement définis via la directive ProxyPass. Si elle se trouve dans un conteneur <Proxy url de répartiteur|url de serveur cible>, l'argument url n'est pas nécessaire. Comme effet de bord, le répartiteur ou serveur cible respectif est créé. Ceci peut s'avérer utile pour la mise en oeuvre d'un mandataire inverse via une directive RewriteRule au lieu de ProxyPass.

<Proxy "balancer://hotcluster">
    BalancerMember "http://www2.example.com:8080" loadfactor=1
    BalancerMember "http://www3.example.com:8080" loadfactor=2
    ProxySet lbmethod=bytraffic
</Proxy>
<Proxy "http://backend">
    ProxySet keepalive=On
</Proxy>
ProxySet "balancer://foo" lbmethod=bytraffic timeout=15
ProxySet "ajp://backend:7001" timeout=15

Avertissement

Gardez à l'esprit qu'une même clé de paramètre peut avoir différentes significations selon qu'elle s'applique à un répartiteur ou à un serveur cible, et ceci est illustré par les deux exemples précédents où il est question d'un timeout.

top

Directive ProxySourceAddress

Description:Définit l'adresse IP locale pour les connexions mandatées sortantes
Syntaxe:ProxySourceAddress adresse
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible depuis la version 2.3.9

Cette directive permet de définir une adresse IP locale spécifique à laquelle faire référence lors d'une connexion à un serveur d'arrière-plan.

top

Directive ProxyStatus

Description:Affiche l'état du répartiteur de charge du mandataire dans mod_status
Syntaxe:ProxyStatus Off|On|Full
Défaut:ProxyStatus Off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy
Compatibilité:Disponible depuis la version 2.2 d'Apache

Cette directive permet de spécifier si les données d'état du répartiteur de charge du mandataire doivent être affichées via la page d'état du serveur du module mod_status.

Note

L'argument Full produit le même effet que l'argument On.

top

Directive ProxyTimeout

Description:Délai d'attente réseau pour les requêtes mandatées
Syntaxe:ProxyTimeout secondes
Défaut:Valeur de la directive Timeout
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

Cette directive permet à l'utilisateur de spécifier un délai pour les requêtes mandatées. Ceci s'avère utile dans le cas d'un serveur d'applications lent et bogué qui a tendance à se bloquer, et si vous préférez simplement renvoyer une erreur timeout et abandonner la connexion en douceur plutôt que d'attendre jusqu'à ce que le serveur veuille bien répondre.

top

Directive ProxyVia

Description:Information fournie dans l'en-tête de réponse HTTP Via pour les requêtes mandatées
Syntaxe:ProxyVia On|Off|Full|Block
Défaut:ProxyVia Off
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy

Cette directive permet de contrôler l'utilisation de l'en-tête HTTP Via: par le mandataire. Le but recherché est de contrôler le flux des requêtes mandatées tout au long d'une chaîne de serveurs mandataires. Voir RFC 2616 (HTTP/1.1), section 14.45 pour une description des lignes d'en-tête Via:.

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_connect.html.fr.utf80000664000175100017510000002507214740503670023534 0ustar covenercovener mod_proxy_connect - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_connect

Langues Disponibles:  en  |  fr  |  ja 

Description:Extension de mod_proxy pour le traitement des requêtes CONNECT
Statut:Extension
Identificateur de Module:proxy_connect_module
Fichier Source:mod_proxy_connect.c

Sommaire

Pour fonctionner, ce module nécessite le chargement de mod_proxy. Il fournit le support de la méthode HTTP CONNECT. Cette méthode est principalement utilisée pour faire franchir les serveurs mandataires aux requêtes SSL à l'aide d'un tunnel.

Ainsi, pour pouvoir traiter les requêtes CONNECT, mod_proxy et mod_proxy_connect doivent être chargés dans le serveur.

CONNECT est aussi utilisée lorsque le serveur doit envoyer une requête HTTPS via un mandataire. Dans ce cas, le serveur se comporte comme un client CONNECT. Cette fonctionnalité étant fournie par le module mod_proxy, le module mod_proxy_connect n'est dans ce cas pas nécessaire.

Avertissement

N'activez pas la fonctionnalité de mandataire avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Informations sur les requêtes

mod_proxy_connect enregistre les informations suivantes pour journalisation via le format %{NOMVAR}n dans les directives LogFormat ou ErrorLogFormat :

proxy-source-port
Le port local utilisé pour la connexion vers le serveur d'arrière-plan.
top

Directive AllowCONNECT

Description:Ports autorisés à se CONNECTer à travers le mandataire
Syntaxe:AllowCONNECT port[-port] [port[-port]] ...
Défaut:AllowCONNECT 443 563
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_proxy_connect
Compatibilité:Déplacé depuis mod_proxy à partir d'Apache 2.3.5. Plages de ports disponibles depuis Apache 2.3.7.

La directive AllowCONNECT permet de spécifier une liste de numéros ou de plages de ports auxquels la méthode de mandataire CONNECT pourra se connecter. Les navigateurs récents utilisent cette méthode dans le cas où une connexion https est requise et où le tunneling mandataire sur HTTP est en service.

Par défaut, seuls les ports par défauts https (443) et snews (563) sont pris en compte. Vous pouvez utiliser la directive AllowCONNECT pour outrepasser ces valeurs par défaut et n'autoriser les connexions que vers les ports spécifiés.

Langues Disponibles:  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_fdpass.html.fr.utf80000664000175100017510000001734614740503670023370 0ustar covenercovener mod_proxy_fdpass - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_fdpass

Langues Disponibles:  en  |  fr 

Description:Module fournissant le support des processus externes fdpass à mod_proxy
Statut:Extension
Identificateur de Module:proxy_fdpass_module
Fichier Source:mod_proxy_fdpass.c
Compatibilité:Disponible pour unix depuis la version 2.3 d'Apache

Sommaire

Pour fonctionner, ce module nécessite le chargement de mod_proxy. Il permet le passage de la socket du client vers un autre processus.

mod_proxy_fdpass utilise la capacité des sockets de domaine AF_UNIX à transmettre un descripteur de fichier ouvert afin de permettre à un autre processus de terminer le traitement de la requête.

Le module possède une interface de fournisseur proxy_fdpass_flusher qui permet éventuellement à un autre module d'envoyer les en-têtes de la réponse, ou même le début du corps de la réponse. Le fournisseur par défaut flush désactive la persistence, et envoie les en-têtes de la réponse, laissant le soin au processus externe d'envoyer le corps de la réponse.

Pour utiliser un autre fournisseur, vous devez spécifier le paramètre flusher de la directive ProxyPass.

À l'heure actuelle, la seule donnée transmise au processus externe est la socket du client. Pour recevoir une socket client, appelez recvfrom avec une structure struct cmsghdr allouée. Les versions futures de ce module pourront transmettre d'autres données que le socket client.

Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_html.html.fr.utf80000664000175100017510000011453614740503670023053 0ustar covenercovener mod_proxy_html - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_html

Langues Disponibles:  en  |  fr 

Description:Réécrit les liens HTML afin de s'assurer qu'ils soient bien adressables depuis les réseaux des clients dans un contexte de mandataire.
Statut:Base
Identificateur de Module:proxy_html_module
Fichier Source:mod_proxy_html.c
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures

Sommaire

Ce module fournit un filtre en sortie permettant de réécrire les liens HTML dans un contexte de mandataire, afin de s'assurer que ces liens fonctionnent pour les utilisateurs en dehors du mandataire. Il accomplit la même tâche que la directive ProxyPassReverse d'Apache accomplit pour les en-têtes HTTP, et fait partie des composants essentiels d'un mandataire inverse.

Par exemple, si une entreprise possède un serveur d'applications nommé appserver.example.com qui n'est visible que depuis son réseau interne, et un serveur web public www.example.com, il peut être souhaitable de fournir une passerelle vers le serveur d'application à l'adresse http://www.example.com/appserver/. Lorsque le serveur d'applications présente un lien vers lui-même, ce lien doit être réécrit pour fonctionner à travers la passerelle. A cet effet, mod_proxy_html permet de réécrire <a href="http://appserver.example.com/foo/bar.html">foobar</a> en <a href="http://www.example.com/appserver/foo/bar.html">foobar</a>, ce qui permet de rendre le serveur d'applications accessible depuis l'extérieur.

mod_proxy_html a été développé à l'origine à WebÞing, dont la documentation détaillée pourra s'avérer utile aux utilisateurs.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive ProxyHTMLBufSize

Description:Définit l'incrément de la taille du tampon, ainsi que sa taille initiale, pour la mise en tampon des scripts en ligne et des feuilles de style.
Syntaxe:ProxyHTMLBufSize nb-octets
Défaut:ProxyHTMLBufSize 8192
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Pour pouvoir interpréter du contenu non HTML (feuilles de style et scripts) embarqué dans des documents HTML, mod_proxy_html doit le lire et le mémoriser en entier dans un tampon. Ce tampon devra être étendu autant que nécessaire afin de pouvoir accueillir le plus grand script ou la plus grande feuille de style de la page, selon un incrément de nb-octets que cette directive permet de définir.

La valeur par défaut est 8192 et sera suffisante pour la plupart des pages. Cependant, si vous savez que vous allez mandater des pages contenant des feuilles de style et/ou scripts plus grands que 8k (cette taille s'entend pour chaque script ou feuilles de style, non pour leur ensemble), il sera plus efficace de définir une taille de tampon initiale plus grande afin d'éviter d'avoir à le redimensionner dynamiquement au cours du traitement d'une requête.

top

Directive ProxyHTMLCharsetOut

Description:Spécifie un jeu de caractères pour la sortie de mod_proxy_html.
Syntaxe:ProxyHTMLCharsetOut jeu-de-caractères | *
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Cette directive permet de spécifier un jeu de caractères pour la sortie de mod_proxy_html. Elle ne devrait jamais être utilisée, car tout changement par rapport à la valeur par défaut UTF-8 (Unicode - utilisé en interne par libxml2) induit une charge supplémentaire de traitement. La définition spéciale ProxyHTMLCharsetOut * permet de générer une sortie qui utilisera le même encodage que l'entrée.

Notez que tout ceci ne fonctionne que si le module mod_xml2enc est chargé.

top

Directive ProxyHTMLDocType

Description:Définit une déclaration de type de document HTML ou XHTML.
Syntaxe:ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Avec la première syntaxe, les documents seront déclarés de type HTML 4.01 ou XHTML 1.0 selon l'option spécifiée. Cette option détermine aussi si la syntaxe utilisée en sortie est HTML ou XHTML. Notez que le format des documents en provenance du serveur d'arrière-plan n'est pas important, car l'interpréteur le détectera automatiquement. Si le second argument optionnel est défini à Legacy, les documents seront déclarés de type "Transitional" ; cette option peut être nécessaire si vous mandatez du contenu datant d'avant 1998, ou si vous travaillez avec des outils de création/publication déficients.

Avec la deuxième syntaxe, cette directive vous permet d'insérer votre propre FPI (Formal Public Identifier). Le second argument optionnel détermine si la syntaxe utilisée sera SGML/HTML ou XML/XHTML.

Par défaut, aucun FPI n'est inséré, étant donné qu'il vaut mieux pas de FPI du tout qu'un FPI bogué. Si par contre votre serveur d'arrière-plan génère du contenu HTML ou XHTML correct, vous pouvez définir cette directive en conséquence.

Avec la première syntaxe, mod_proxy_html va aussi mettre le code HTML en conformité avec le standard spécifié. Il ne pourra pas corriger toutes les erreurs, mais il va supprimer les éléments et attributs non conformes. Il peut aussi journaliser les autres erreurs si la directive LogLevel est définie à Debug.

top

Directive ProxyHTMLEnable

Description:Permet d'activer/désactiver le filtre proxy_html.
Syntaxe:ProxyHTMLEnable On|Off
Défaut:ProxyHTMLEnable Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Cette directive est un simple commutateur permettant d'activer/désactiver le filtre proxy_html. Si mod_xml2enc est chargé, elle va aussi activer automatiquement le support de l'internationalisation.

Notez que le filtre proxy_html s'agira que si les données sont de type HTML (Content-Type text/html ou application/xhtml+xml), et si elles passent par un mandataire. Vous pouvez passer outre ces contraintes (à vos risques et périls) en définissant la variable d'environnement PROXY_HTML_FORCE.

top

Directive ProxyHTMLEvents

Description:Spécifie les attributs à traiter comme des évènements de type scripting.
Syntaxe:ProxyHTMLEvents attribut [attribut ...]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Cette directive permet de spécifier un ou plusieurs attributs à traiter comme des évènements de type scripting et de leur appliquer les règles ProxyHTMLURLMap lorsqu'elles ont été définies. Vous pouvez spécifier un nombre quelconque d'attributs dans une ou plusieurs directives ProxyHTMLEvents.

Normalement, cette directive est définie globalement. Si vous définissez ProxyHTMLEvents à plusieurs niveaux, certains niveaux l'emportant sur d'autres, vous devrez spécifier un jeu complet d'évènements pour chaque niveau.

Le fichier proxy-html.conf fournit une configuration par défaut et définit les évènements selon les standards HTML 4 et XHTML 1.

top

Directive ProxyHTMLExtended

Description:Détermine si l'on doit corriger les liens dans les scripts en ligne, les feuilles de style et les évènements de type scripting.
Syntaxe:ProxyHTMLExtended On|Off
Défaut:ProxyHTMLExtended Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Si cette directive est définie à Off, les liens HTML sont réécrits en fonction des directives ProxyHTMLURLMap, mais les liens qui apparaissent dans le code Javascript et les feuilles de style restent inchangés.

Si elle est définie à On, tous les évènements de type scripting (définis par la directive ProxyHTMLEvents) et les scripts inclus ou les feuilles de style sont aussi traités par les règles ProxyHTMLURLMap, en fonction des drapeaux définis pour chacune d'entre elles. Ne définissez cette directive à On qu'en cas de nécessité absolue, car la charge supplémentaire induite impacte les performances.

Vous devez aussi prêter attention aux modèles de comparaison, car l'interpréteur n'a aucune notion de la forme que pourrait prendre une URL dans un script embarqué ou une feuille de style. En particulier, la comparaison étendus du caractère / a de fortes chances d'induire des correspondances erronées.

top

Directive ProxyHTMLFixups

Description:Corrige les erreurs HTML simples.
Syntaxe:ProxyHTMLFixups [lowercase] [dospath] [reset]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Cette directive accepte un à trois arguments parmi les suivants :

Cette directive doit être utilisée avec prudence. Elle peut corriger certaines erreurs de création, mais risque aussi de modifier par erreur des liens corrects. Ne l'utilisez que si vous êtes sûr que le serveur d'arrière-plan est déficient.

top

Directive ProxyHTMLInterp

Description:Active la réinterprétation des règles ProxyHTMLURLMap pour chaque requête.
Syntaxe:ProxyHTMLInterp On|Off
Défaut:ProxyHTMLInterp Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Cette directive permet d'activer le réinterprétation pour chaque requête des modèles source et cible de la directive ProxyHTMLURLMap.

Si la réinterprétation n'est pas activée, toutes les règles sont précompilées au démarrage du serveur. Si elle est activée, les règles doivent être recompilées pour chaque requête, ce qui induit une charge de traitement supplémentaire. Elle ne doit donc être activée que si cela s'avère nécessaire.

top

Directive ProxyHTMLLinks

Description:Spécifie les éléments HTML dont les attributs d'URL doivent être réécrits.
Syntaxe:ProxyHTMLLinks élément attribut [attribut2 ...]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Cette directive permet de spécifier les éléments dont les attributs d'URL doivent être réécrits en utilisant les règles standards ProxyHTMLURLMap. Vous devez définir une directive ProxyHTMLLinks pour chaque élément, mais chacune d'entre elles peut spécifier un nombre quelconque d'attributs

Normalement, cette directive est définie globalement. Si vous définissez ProxyHTMLLinks à plusieurs niveaux, certains niveaux l'emportant sur d'autres, vous devrez spécifier un jeu complet de liens pour chaque niveau.

Le fichier proxy-html.conf fournit une configuration par défaut et définit les liens HTML selon les standards HTML 4 et XHTML 1.

Exemples issus de proxy-html.conf

ProxyHTMLLinks  a          href
ProxyHTMLLinks  area       href
ProxyHTMLLinks  link       href
ProxyHTMLLinks  img        src longdesc usemap
ProxyHTMLLinks  object     classid codebase data usemap
ProxyHTMLLinks  q          cite
ProxyHTMLLinks  blockquote cite
ProxyHTMLLinks  ins        cite
ProxyHTMLLinks  del        cite
ProxyHTMLLinks  form       action
ProxyHTMLLinks  input      src usemap
ProxyHTMLLinks  head       profile
ProxyHTMLLinks  base       href
ProxyHTMLLinks  script     src for
top

Directive ProxyHTMLMeta

Description:Active ou désactive une préinterprétation supplémentaire des métadonnées dans les sections HTML <head>.
Syntaxe:ProxyHTMLMeta On|Off
Défaut:ProxyHTMLMeta Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible à partir de la version 2.4 du serveur HTTP Apache ; proposé en tant que module tiers dans les versions 2.x précédentes.

Cette directive permet d'activer ou désactiver une préinterprétation supplémentaire des métadonnées dans les sections HTML <head>. Si cette préinterprétation n'est pas requise, définissez ProxyHTMLMeta à Off et les performances seront légèrement améliorées. Cependant, elle s'avère parfois nécessaire pour assurer un fonctionnement correct de l'internationalisation.

La directive ProxyHTMLMeta a deux effets. Le premier et le plus important est la détection des codages de caractères déclarés sous la forme

<meta http-equiv="Content-Type" content="text/html;charset=foo">

ou, dans le cas d'un document XHTML, sous la forme d'une déclaration XML. Elle n'est pas nécessaire si le jeu de caractères est déclaré explicitement dans un en-tête HTTP (ce qui est préférable) en provenance du serveur d'arrière-plan, ou si le document est en utf-8 (unicode) ou un de ses sous-ensembles comme ASCII. Vous pourrez aussi vous en passer lorsque le document utilise une valeur par défaut déclarée via la directive xml2EncDefault, avec le risque de propager une déclaration incorrecte. Une directive ProxyHTMLCharsetOut permettra d'annuler ce risque, mais pourra induire une surcharge de traitement supérieure à celle de ProxyHTMLMeta.

Le deuxième effet est l'interprétation de toutes les déclarations <meta http-equiv=...> et leur conversion en en-têtes HTTP, afin de conserver le but original de cette forme de métaélément HTML.

Avertissement

Compte tenu du fait que la directive ProxyHTMLMeta promeut tous les éléments http-equiv au rang d'en-têtes HTTP, il est conseillé de ne l'activer que si vous faites autant confiance au contenu HTML qu'à votre serveur mandataire. Avec cette directive en effet, si ce contenu est géré par des gens malintentionnés, ces derniers seront en mesure d'injecter des en-têtes HTTP arbitraires et peut-être malveillants dans les réponses de votre serveur.
top

Directive ProxyHTMLStripComments

Description:Détermine si les commentaires HTML doivent être supprimés.
Syntaxe:ProxyHTMLStripComments On|Off
Défaut:ProxyHTMLStripComments Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Si cette directive est définie à On, mod_proxy_html supprimera les commentaires HTML. Notez que cela supprimera aussi tout script ou style inclus dans les commentaires (une monstruosité introduite en 1995/1996 avec Netscape 2 pour les navigateurs plus anciens, et encore utilisée de nos jours). Cette directive peut aussi interférer avec des processeurs basés sur les commentaires comme SSI ou ESI : assurez-vous d'exécuter ces derniers avant mod_proxy_html dans la chaîne de filtrage si vous supprimez les commentaires !

top

Directive ProxyHTMLURLMap

Description:Définit une règle de réécriture des liens HTML
Syntaxe:ProxyHTMLURLMap modèle-source modèle-cible [drapeaux] [cond]
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Base
Module:mod_proxy_html
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.x antérieures.

Il s'agit de la directive la plus importante pour la réécriture des liens HTML. Lors de l'interprétation d'un document, chaque fois qu'un lien correspond à modèle-source, la partie du lien concernée sera réécrite en modèle-cible, en tenant compte des modifications induites par les drapeaux éventuellement spécifiés et par la directive ProxyHTMLExtended. Ne seront considérés comme des liens HTML que les éléments spécifiés via la directive ProxyHTMLLinks.

Le troisième argument optionnel permet de définir un des drapeaux suivants (les drapeaux sont sensibles à la casse) :

h

Ignore les liens HTML (les traverse sans les modifier)

e

Ignore les évènements de scripting (les traverse sans les modifier)

c

Traverse les sections de type style ou script sans les modifier.

L

Last-match. Si cette règle s'applique, aucune autre règle ne sera prise en compte (notez qu'il s'agit du comportement automatique pour les liens HTML).

l

L'opposé de L. Passe outre le comportement par défaut du changement unique pour les liens HTML.

R

Utilise des expressions rationnelles pour les modèles. modèle-source est une expression rationnelle, et modèle-cible une chaîne de remplacement qui peut être basée elle aussi sur une expression rationnelle. La mémorisation dans les expressions rationnelles est supportée : vous pouvez utiliser des parenthèses () dans le modèle-source, et récupérer la correspondance de leur contenu via les variables $1 à $9 dans le modèle-cible.

Si le drapeau R n'est pas fourni, la directive utilisera des chaînes littérales pour les différents modèles de recherche/remplacement. La logique de recherche est "commence par" dans les liens HTML, et "contient" dans les évènements de scripting et les sections de type style ou script.

x

Utilise les expressions rationnelles étendues POSIX. Ne s'applique qu'avec R.

i

Recherche de correspondance sensible à la casse. Ne s'applique qu'avec R.

n

Désactive la mémorisation dans les expressions rationnelles (pour améliorer les performances). Ne s'applique qu'avec R.

s

Recherche de correspondance dans les expressions rationnelles basée sur la ligne. Ne s'applique qu'avec R.

^

Recherche de correspondance au début seulement. Ne concerne que les recherches de correspondance par rapport à des chaînes, et ne s'applique pas aux liens HTML.

$

Recherche de correspondance à la fin seulement. Ne concerne que les recherches de correspondance par rapport à des chaînes, et ne s'applique pas aux liens HTML.

V

Insère des variables d'environnement dans le modèle-cible. Un modèle-cible de la forme ${varname|default} sera remplacé par la valeur de la variable d'environnement varname. Si cette dernière n'est pas définie, modèle-cible sera remplacé par default. La spécification de |default est facultative.

NOTE: l'insertion de variables d'environnement n'est possible que si la directive ProxyHTMLInterp a été définie à On.

v

Insère des variables d'environnement dans le modèle-source. La syntaxe du modèle est identique à la syntaxe précédente.

NOTE: l'insertion de variables d'environnement n'est possible que si la directive ProxyHTMLInterp a été définie à On.

Le quatrième argument optionnel cond définit une condition qui sera évaluée pour chaque requête, sous réserve que la directive ProxyHTMLInterp ait été définie à On. Si la condition est évaluée à FALSE, la règle ne sera pas appliquée à la requête. Si elle est évaluée à TRUE, ou si aucune condition n'est définie, la règle s'applique.

La condition est évaluée par l'interpréteur d'expression. La syntaxe simple des conditions dans mod_proxy_html 3.x pour HTTPD 2.0 et 2.2 est aussi supportée.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_scgi.html.fr.utf80000664000175100017510000003713514740503670023033 0ustar covenercovener mod_proxy_scgi - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_proxy_scgi

Langues Disponibles:  en  |  fr 

Description:Module fournissant le support de la passerelle SCGI à mod_proxy
Statut:Extension
Identificateur de Module:proxy_scgi_module
Fichier Source:mod_proxy_scgi.c
Compatibilité:Disponible depuis la version 2.2.14 d'Apache

Sommaire

Pour pouvoir fonctionner, ce module requiert le chargement de mod_proxy. Il fournit le support du protocole SCGI, version 1.

Ainsi, pour être en mesure de traiter le protocole SCGI, mod_proxy et mod_proxy_scgi doivent être chargés dans le serveur.

Avertissement

N'activez pas la fonctionnalité de mandataire avant d'avoir sécurisé votre serveur. Les serveurs mandataires ouverts sont dangereux non seulement pour votre réseau, mais aussi pour l'Internet au sens large.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples

Rappelez-vous, pour que les exemples suivants puissent fonctionner, vous devez activer mod_proxy et mod_proxy_scgi.

Passerelle simple

ProxyPass "/scgi-bin/" "scgi://localhost:4000/"

La passerelle à répartition de charge nécessite le chargement du module mod_proxy_balancer et d'au moins un module fournissant un algorithme de répartition de charge, comme mod_lbmethod_byrequests en plus des modules déjà cités. mod_lbmethod_byrequests est le module par défaut et sera utilisé dans cet exemple de configuration.

Passerelle à répartition de charge

ProxyPass "/scgi-bin/" "balancer://somecluster/"
<Proxy "balancer://somecluster">
    BalancerMember "scgi://localhost:4000"
    BalancerMember "scgi://localhost:4001"
</Proxy>
top

Variables d'environnement

En plus des directives de configuration qui permettent de contrôler le comportement de mod_proxy, une variable d'environnement peut aussi contrôler le fournisseur de protocole SCGI :

proxy-scgi-pathinfo
Par défaut, mod_proxy_scgi ne créera ni exportera jamais la variable d'environnement PATH_INFO. Ceci permet au serveur SCGI d'arrière-plan de déterminer correctement SCRIPT_NAME et Script-URI, et de rester en conformité avec la section 3.3 de la RFC 3875. Si au contraire vous souhaitez que mod_proxy_scgi génère une estimation la plus précise possible de PATH_INFO, définissez cette variable d'environnement. La variable doit être définie avant que la directive SetEnv ne soit effective. Il est possible d'utiliser à la place la directive SetEnvIf : SetEnvIf Request_URI . proxy-scgi-pathinfo
top

Directive ProxySCGIInternalRedirect

Description:Active ou désactive les réponses de redirection interne en provenance du serveur cible.
Syntaxe:ProxySCGIInternalRedirect On|Off|Headername
Défaut:ProxySCGIInternalRedirect On
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy_scgi
Compatibilité:Le paramètre Headername est disponible depuis la version 2.4.13 du serveur HTTP Apache.

La directive ProxySCGIInternalRedirect permet au serveur cible de rediriger en interne la passerelle vers une URL différente. Cette fonctionnalité trouve son origine dans mod_cgi qui redirige la réponse en interne si l'état de la réponse est OK (200), et si la réponse contient un en-tête Location (ou un autre en-tête défini) dont la valeur débute par un slash (/). Cette valeur est interprétée comme une nouvelle URL locale vers laquelle Apache httpd effectue sa redirection.

De ce point de vue, mod_proxy_scgi fait la même chose que mod_cgi, mais vous pouvez en plus désactiver la fonctionnalité ou spécifier l'utilisation d'un en-tête autre que Location.

Exemple

    ProxySCGIInternalRedirect Off
# Django et certains autres frameworks qualifient pleinement les "URLs
# locales" définies par l'application ; il faut donc utiliser un autre
# en-tête.
<Location /django-app/>
    ProxySCGIInternalRedirect X-Location
</Location>
top

Directive ProxySCGISendfile

Description:Active l'évaluation du pseudo en-tête de réponse X-Sendfile
Syntaxe:ProxySCGISendfile On|Off|nom-en-tête
Défaut:ProxySCGISendfile Off
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Extension
Module:mod_proxy_scgi

La directive ProxySCGISendfile permet au serveur cible SCGI de faire servir les fichiers directement par la passerelle. Ceci s'avère bénéfique en matière de performances — httpd peut alors utiliser sendfile ou d'autres optimisations, ce qui n'est pas possible si les fichiers passent par la socket du serveur cible. En outre, les fichiers ne sont transmis qu'une seule fois.

L'argument de la directive ProxySCGISendfile détermine le comportement de la passerelle :

Off
Aucun traitement particulier n'est effectué.
On
La passerelle recherche un en-tête dans la réponse du serveur cible nommé X-Sendfile, et interprète sa valeur comme le nom du fichier à servir. L'en-tête est ensuite supprimé de la réponse finale. Cet argument produit le même effet que ProxySCGISendfile X-Sendfile.
toute autre valeur
Identique à On, mais au lieu de rechercher le nom d'en-tête codé en dur X-Sendfile, c'est la valeur de l'argument qui constitue le nom de l'en-tête à rechercher.

Exemple

    # Utilise le nom d'en-tête par défaut (X-Sendfile)
    ProxySCGISendfile On

    # Utilise un nom d'en-tête différent
    ProxySCGISendfile X-Send-Static

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ratelimit.html.fr.utf80000664000175100017510000001660714740503670022640 0ustar covenercovener mod_ratelimit - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_ratelimit

Langues Disponibles:  en  |  fr 

Description:Limitation de la bande passante pour les clients
Statut:Extension
Identificateur de Module:ratelimit_module
Fichier Source:mod_ratelimit.c
Compatibilité: rate-initial-burst est disponible à partir de la version 2.4.24 du serveur HTTP Apache. La limitation de bande passante pour les contenus mandatés ne fonctionne pas correctement jusqu'à la version 2.4.33.

Sommaire

Ce module fournit un filtre RATE_LIMIT pour limiter la bande passante des clients. Cette contrainte s'applique à chaque réponse HTTP au moment où elle est envoyée au client ; elle n'affecte pas les autres échanges entre le client et le serveur. La variable d'environnement rate-limit permet de spécifier, en kb/s, le débit de la connexion à simuler.

Optionnellement, il est possible, via la variable d'environnement rate-initial-burst, de définir une quantité de données en kOctets à transmettre à pleine vitesse avant de limiter la bande passante à la valeur voulue.

Exemple de configuration

<Location "/downloads">
    SetOutputFilter RATE_LIMIT
    SetEnv rate-limit 400
    SetEnv rate-initial-burst 512
</Location>
Si la valeur affectée à rate-limit dépasse la valeur maximale à affecter à un entier, la limitation de bande passante sera désactivée. Si la valeur affectée à rate-limit-burst dépasse la valeur maximale à affecter à un entier, la transmission du burst initial sans limitation de bande passante sera désactivée.
Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_reqtimeout.html.fr.utf80000664000175100017510000003322114740503670023033 0ustar covenercovener mod_reqtimeout - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_reqtimeout

Langues Disponibles:  en  |  fr 

Description:Définit le délai maximum et le taux minimum de transfert des données pour la réception des requêtes
Statut:Extension
Identificateur de Module:reqtimeout_module
Fichier Source:mod_reqtimeout.c
Compatibilité:Disponible depuis la version 2.2.15 du serveur HTTP Apache

Sommaire

Ce module permet de définir aisément le délai maximum et le taux de transfert des données minimum pour la réception des requêtes. Si ce délai est dépassé ou ce taux trop faible, la connexion concernée sera fermée par le serveur.

Cet évènement sera alors enregistré dans le journal au niveau de LogLevel info.

Au besoin, la directive LogLevel peut être modifiée pour un enregistrement dans le journal plus explicite :

LogLevel reqtimeout:info
Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples

  1. Accorde 5 secondes pour terminer la négociation TLS, 10 secondes pour la réception des en-têtes de la requête et 30 secondes pour la réception du corps :
    RequestReadTimeout handshake=5 header=10 body=30
  2. Accorde au moins 10 secondes pour la réception du corps de la requête. Si le client envoie des données, augmente ce délai d'une seconde pour chaque paquet de 1000 octets reçus, sans limite supérieure (sauf si une limite a été spécifiée via la directive LimitRequestBody) :
    RequestReadTimeout body=10,MinRate=1000
  3. Accorde au moins 10 secondes pour la réception des en-têtes de la requête. Si le client envoie des données, augmente ce délai d'une seconde pour chaque paquet de 500 octets reçus, mais n'alloue que 30 secondes pour les en-têtes de la requête :
    RequestReadTimeout header=10-30,MinRate=500
  4. En général, un serveur doit avoir ses délais d'en-tête et de corps configurés. Si les serveurs virtuels http et https utilisent une configuration commune, les délais ne doivent pas être définis trop bas :
    RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
top

Directive RequestReadTimeout

Description:Définit des délais maximums pour la négociation TLS, la réception des en-têtes et/ou corps des requêtes en provenance du client.
Syntaxe:RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=MinRate] [body=timeout[-maxtimeout][,MinRate=MinRate]
Défaut:RequestReadTimeout handshake=0 header=20-40,MinRate=500 body=20,MinRate=500
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_reqtimeout
Compatibilité:Disponible depuis la version 2.2.15 du serveur HTTP Apache ; désactivée par défaut depuis la version 2.3.14. La phase de négociation est prise en compte à partir de la version 2.4.39.

Cette directive permet de définir différents timeouts pour la négociation TLS, la réception des en-têtes et/ou corps des requêtes en provenance du client. Si le client ne parvient pas à respecter ces timeouts, un code d'erreur 408 REQUEST TIME OUT est envoyé.

Pour les serveurs virtuels SSL, la valeur de timeout pour la négociation correspond au temps nécessaire pour la négociation SSL initiale. Si le navigateur du client est configuré pour demander des listes de révocations de certificats, et si le serveur correspondant n'est pas disponible, le timeout avant lequel le navigateur va abandonner son attente de CRL au cours de la négociation SSL initiale peut être assez important. Par conséquent, les valeurs de timeouts pour la négociation doivent prendre en compte un temps supplémentaire pour les serveurs virtuels SSL (si nécessaire). Le timeout concernant le corps inclut le temps nécessaire à la renégociation SSL (si elle est nécessaire).

Lorsqu'une directive AcceptFilter est active (ce qui est en général le cas sous Linux et FreeBSD), la socket n'est envoyée au processus du serveur qu'après la réception du premier octet (ou de l'ensemble de la requête si httpready est défini). Les timeouts configurés pour la négociation et les en-têtes via la directive RequestReadTimeout n'entrent en ligne de compte qu'une fois le socket reçu par le processus du serveur.

Il existe trois méthodes pour spécifier le timeout pour chacune des trois phases (négociation, en-tête ou corps) :

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_rewrite.html.fr.utf80000664000175100017510000025360114740503670022324 0ustar covenercovener mod_rewrite - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_rewrite

Langues Disponibles:  en  |  fr 

Description:Ce module fournit un moteur de réécriture à base de règles permettant de réécrire les URLs des requêtes à la volée
Statut:Extension
Identificateur de Module:rewrite_module
Fichier Source:mod_rewrite.c

Sommaire

Le module mod_rewrite utilise un moteur de réécriture à base de règles, basé sur un interpréteur d'expressions rationnelles PCRE, pour réécrire les URLs à la volée. Par défaut, mod_rewrite met en correspondance une URL avec le système de fichiers. Cependant, on peut aussi l'utiliser pour rediriger une URL vers une autre URL, ou pour invoquer une requête interne à destination du mandataire.

mod_rewrite fournit une méthode souple et puissante pour manipuler les URLs en utilisant un nombre illimité de règles. Chaque règle peut être associée à un nombre illimité de conditions, afin de vous permettre de réécrire les URLs en fonction de variables du serveur, de variables d'environnement, d'en-têtes HTTP, ou de repères temporels.

mod_rewrite agit sur la totalité de l'URL, y compris la partie chemin. Une règle de réécriture peut être invoquée dans httpd.conf ou dans un fichier .htaccess. Le chemin généré par une règle de réécriture peut inclure une chaîne de paramètres, ou peut renvoyer vers un traitement secondaire interne, une redirection vers une requête externe ou vers le mandataire interne.

Vous trouverez d'avantage de détails, discussions et exemples dans la documentation détaillée sur mod_rewrite.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Journalisation

mod_rewrite offre une journalisation détaillée de ses actions aux niveaux de journalisation trace1 à trace8. Le niveau de journalisation peut être défini de manière spécifique à mod_rewrite via la directive LogLevel : jusqu'au niveau debug aucune action n'est journalisée, alors qu'elles le sont pratiquement toutes au niveau trace8.

L'utilisation d'un niveau de journalisation élevé pour mod_rewrite va ralentir votre serveur HTTP Apache de manière dramatique ! N'utilisez un niveau de journalisation supérieur à trace2 qu'à des fins de débogage !

Exemple

LogLevel alert rewrite:trace3

RewriteLog

Ceux qui sont familiers avec les versions précédentes de mod_rewrite vont probablement rechercher en vain les directives RewriteLog et RewriteLogLevel. Elles ont été en effet remplacées par une configuration de la journalisation par module, comme mentionné plus haut.

Pour extraire les traces spécifiques à mod_rewrite, affichez le fichier journal en redirigeant la sortie vers grep :

tail -f error_log|fgrep '[rewrite:'

top

Directive RewriteBase

Description:Définit l'URL de base pour les réécritures au niveau répertoire
Syntaxe:RewriteBase chemin_URL
Défaut:Pas de valeur par défaut
Contexte:répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteBase permet de spécifier le préfixe d'URL à utiliser dans un contexte de répertoire (htaccess) pour les directives RewriteRule qui réécrivent vers un chemin relatif.

Cette directive est obligatoire si vous utilisez un chemin relatif dans une substitution, et dans un contexte de répertoire (htaccess), sauf si au moins une de ces conditions est vérifiée :

Dans l'exemple ci-dessous, la directive RewriteBase est nécessaire afin d'éviter une réécriture en http://example.com/opt/myapp-1.2.3/welcome.html car la ressource n'était pas relative à la racine des documents. Cette erreur de configuration aurait conduit le serveur à rechercher un répertoire "opt" à la racine des documents.

DocumentRoot "/var/www/example.com"
AliasMatch "^/myapp" "/opt/myapp-1.2.3"
<Directory "/opt/myapp-1.2.3">
 RewriteEngine On
    RewriteBase "/myapp/"
    RewriteRule "^index\.html$"  "welcome.html"
</Directory>
top

Directive RewriteCond

Description:Définit une condition qui devra être satisfaite pour que la réécriture soit effectuée
Syntaxe: RewriteCond chaîne_de_test expression_de_comparaison [drapeaux]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteCond permet de définir une condition d'exécution d'une règle. Une ou plusieurs conditions RewriteCond peuvent précéder une directive RewriteRule. La règle de réécriture correspondante n'est ainsi exécutée que si ces conditions sont satisfaites, et si l'URI correspond au modèle spécifié dans la règle.

TestString est une chaîne qui peut contenir les extensions suivantes en plus du texte simple :

Si la chaîne_de_test contient la valeur spéciale expr, expression_de_comparaison sera traité en tant qu'expression rationnelle de type ap_expr. Si des en-têtes HTTP sont référencés dans l'expression rationnelle, et si le drapeau novary n'est pas activé, ils seront ajoutés à l'en-tête Vary.

Autres points à connaître ::

  1. Les variables SCRIPT_FILENAME et REQUEST_FILENAME contiennent toutes deux la valeur du champ filename de la structure interne request_recdu serveur HTTP Apache. Le premier nom correspond au nom de variable bien connu CGI, alors que le second est l'équivalent de REQUEST_URI (qui contient la valeur du champ uri de request_rec).

    Si une substitution intervient et si la réécriture se poursuit, la valeur des deux variables sera mise à jour en conséquence.

    Dans le contexte du serveur principal (c'est à dire avant que la requête ne soit mise en correspondance avec le système de fichiers), SCRIPT_FILENAME et REQUEST_FILENAME ne peuvent pas contenir le chemin entier dans le système de fichiers local car ce chemin b'est pas connu à ce stade du traitement. Dans ce cas, les deux variables contiendront la valeur de REQUEST_URI. Pour obtenir le chemin complet de la requête dans le système de fichiers local dans le contexte du serveur principal, utilisez une référence avant à base d'URL %{LA-U:REQUEST_FILENAME} pour déterminer la valeur finale de REQUEST_FILENAME.

  2. %{ENV:variable}, où variable peut correspondre à une variable d'environnement quelconque.
  3. %{ENV:variable} est aussi disponible, où variable peut correspondre à toute variable d'environnement. Peut être consulté via des structures internes d'Apache httpd et (si on ne les trouve pas ici) via la fonction getenv() à partir du processus du serveur Apache httpd.
  4. Que mod_ssl soit chargé ou non, on peut utiliser %{SSL:variable}, où variable peut être remplacé par le nom d'une variable d'environnement SSL . Si mod_ssl n'est pas chargé, cette variable contiendra toujours une chaîne vide. Exemple : %{SSL:SSL_CIPHER_USEKEYSIZE} pourra contenir la valeur 128. Ces variables sont disponibles même si l'option StdEnvVars de la directive SSLOptions n'a pas été définie.
  5. On peut utiliser %{HTTP:en-tête}, où en-tête peut correspondre à tout nom d'en-tête MIME HTTP, pour extraire la valeur d'un en-tête envoyé dans la requête HTTP. Par exemple, %{HTTP:Proxy-Connection} contiendra la valeur de l'en-tête HTTP "Proxy-Connection:". Si on utilise un en-tête HTTP dans une condition, et si cette condition est évaluée à vrai pour la requête, cet en-tête sera ajouté à l'en-tête Vary de la réponse. Il ne le sera pas si la condition est évaluée à faux. L'ajout de l'en-tête HTTP à l'en-tête Vary est nécessaire à une mise en cache appropriée.

    Il faut garder à l'esprit que les conditions suivent une logique de cout-circuit si le drapeau 'ornext|OR' est utilisé, et que de ce fait, certaines d'entre elles ne seront pas évaluées.

  6. A des fins de référence avant, on peut utiliser, %{LA-U:variable}, qui permet d'effectuer une sous-requête interne à base d'URL, afin de déterminer la valeur finale de variable. Ceci permet d'accéder à la valeur d'une variable pour la réécriture inconnue à ce stade du traitement, mais qui sera définie au cours d'une phase ultérieure.

    Par exemple, pour effectuer une réécriture dépendant de la variable REMOTE_USER dans le contexte du serveur principal (fichier httpd.conf), vous devez utiliser %{LA-U:REMOTE_USER} - cette variable est définie par la phase d'autorisation qui intervient après la phase de traduction d'URL (pendant laquelle mod_rewrite opère).

    Par contre, comme mod_rewrite implémente son contexte de répertoire (fichier .htaccess) via la phase Fixup de l'API, et comme la phase d'autorisation intervient avant cette dernière, vous pouvez vous contenter d'utiliser %{REMOTE_USER} dans ce contexte.

  7. %{LA-F:variable} peut être utilisée pour effectuer une sous-requête interne (basée sur le nom de fichier), afin de déterminer la valeur finale de variable. La plupart du temps, elle est identique à LA-U (voir ci-dessus).

expression_de_comparaison est une expression rationnelle qui est appliquée à l'instance actuelle de chaîne_de_test. chaîne_de_test est d'abord évaluée, puis comparée à l'expression_de_comparaison.

expression_de_comparaison est en général une expression rationnelle compatible perl, mais vous disposez des syntaxes supplémentaires suivantes pour effectuer d'autres tests utiles sur chaîne_de_test :

  1. Vous pouvez préfixer l'expression avec un caractère '!' (point d'exclamation) pour inverser le résultat de la condition, quelle que soit l'expression de comparaison utilisée.
  2. Vous pouvez effectuer des comparaisons lexicographiques de chaînes :
    <expression
    inférieur au sens lexicographique
    Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à chaîne_de_test. La condition est satisfaite si chaîne_de_test est inférieure au sens lexicographique à l'expression.
    >expression
    supérieur au sens lexicographique
    Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à chaîne_de_test. La condition est satisfaite si chaîne_de_test est supérieure au sens lexicographique à l'expression.
    =expression
    égal au sens lexicographique
    Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à chaîne_de_test. La condition est satisfaite si chaîne_de_test est égale au sens lexicographique à l'expression (les deux chaînes sont exactement identiques, caractère pour caractère). Si expression est "" (deux guillemets), chaîne_de_test est comparée à la chaîne vide.
    <=expression de comparaison
    inférieur ou égal à au sens lexicographique
    Considère l'expression_de_comparaison comme une chaîne de caractères et la compare au sens lexicographique à la chaîne_de_test. Vrai si chaîne_de_test précède lexicographiquement expression_de_comparaison, ou est égale à expression_de_comparaison (les deux chaînes sont identiques, caractère pour caractère).
    >=expression de comparaison
    supérieur ou égal à au sens lexicographique
    Considère l'expression_de_comparaison comme une chaîne de caractères et la compare au sens lexicographique à la chaîne_de_test. Vrai si chaîne_de_test suit lexicographiquement expression_de_comparaison, ou est égale à expression_de_comparaison (les deux chaînes sont identiques, caractère pour caractère).

    Note

    L'opérateur de comparaison de chaînes fait partie des arguments de la CondPattern et doit par conséquent se trouver entre les guillemets s'ils sont présents. Exemple :
    RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0"
  3. Vous pouvez effectuer des comparaisons d'entiers :
    -eq
    est numériquement égal à
    La chaîne_de_test est considérée comme un entier, et est comparée numériquement à l'expression de comparaison. Vrai si les deux expressions sont numériquement égales.
    -ge
    est numériquement supérieur ou égal à
    La chaîne_de_test est considérée comme un entier, et est comparée numériquement à l'expression de comparaison. Vrai si chaîne_de_test est numériquement supérieure ou égale à expression_de_comparaison.
    -gt
    est numériquement supérieur à
    La chaîne_de_test est considérée comme un entier, et est comparée numériquement à l'expression de comparaison. Vrai si chaîne_de_test est numériquement supérieure à expression_de_comparaison.
    -le
    est numériquement inférieur ou égal à
    La chaîne_de_test est considérée comme un entier, et est comparée numériquement à l'expression de comparaison. Vrai si chaîne_de_test est numériquement inférieure ou égale à expression_de_comparaison. Attention à la confusion avec le drapeau -l en utilisant la variante the -L ou -h.
    -lt
    est numériquement inférieur à
    La chaîne_de_test est considérée comme un entier, et est comparée numériquement à l'expression de comparaison. Vrai si chaîne_de_test est numériquement inférieure à expression_de_comparaison. Attention à la confusion avec le drapeau -l en utilisant la variante the -L ou -h.
    -ne
    Est numériquement non égal à
    La Chaîne de test est considérée comme un entier et est numériquement comparée à l'expression de comparaison. Vrai si les deux éléments comparés sont numériquement différents. Equivalent à !-eq.
  4. Vous pouvez effectuer différents tests sur les attributs de fichier :
    -d
    est un répertoire
    Traite chaîne_de_test comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un répertoire.
    -f
    est un fichier régulier
    Traite chaîne_de_test comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un fichier régulier.
    -F
    test de l'existence d'un fichier via une sous-requête
    Vérifie si chaîne_de_test est un fichier valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à utiliser avec précautions car les performances du serveur peuvent s'en trouver affectées !
    -h
    est un lien symbolique, selon la convention bash
    Voir -l.
    -l
    est un lien symbolique
    Considère la chaîne_de_test comme un chemin et vérifie son existence et si elle est un lien symbolique. On peut aussi utiliser la convention bash -L ou -h lorsqu'il y a risque de confusion avec les tests -lt ou -le.
    -L
    est un lien symbolique, selon la convention bash
    Voir -l.
    -s
    est un fichier régulier d'une certaine taille
    Considère la chaîne_de_test comme un chemin et vérifie son existence et si elle est un fichier régulier d'une taille supérieure à zéro.
    -U

    test de l'existence d'une URL via une sous-requête
    Vérifie si chaîne_de_test est une URL valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à utiliser avec précautions car les performances du serveur peuvent s'en trouver affectées !

    Ce drapeau ne renvoie que des informations concernant le contrôle d'accès, l'authentification et l'autorisation. Il ne renvoie pas d'informations concernant le code d'état que le gestionnaire configuré (static file, CGI, proxy, etc...) aurait, quant à lui, retourné.

    -x
    a l'attribut d'exécution positionné
    Considère la chaîne_de_test comme un chemin et vérifie son existence et si elle a son attribut d'exécution positionné. Ce positionnement est déterminé en fonction de l'OS sous-jacent.
    Par exemple:
    RewriteCond /var/www/%{REQUEST_URI} !-f
    RewriteRule ^(.+) /other/archive/$1 [R]
  5. Si la chaîne_de_test contient la valeur spéciale expr, la chaîne de comparaison sera traitée en tant qu'expression rationnelle de type ap_expr.

    Dans l'exemple ci-dessous, on utilise -strmatch pour comparer le REFERER avec le nom d'hôte du site afin de bloquer le hotlinking (référencement direct) non désiré.

               RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
               RewriteRule "^/images" "-" [F]

Vous pouvez aussi définir certains drapeaux pour l'expression_de_comparaison en ajoutant ces [drapeaux] comme troisième argument de la directive RewriteCond, où drapeaux est un sous-ensemble séparé par des virgules des drapeaux suivants :

Exemple :

Pour réécrire la page d'accueil d'un site en fonction de l'en-tête ``User-Agent:'' de la requête, vous pouvez utiliser ce qui suit :

RewriteCond  "%{HTTP_USER_AGENT}"  "(iPhone|Blackberry|Android)"
RewriteRule  "^/$"               "/homepage.mobile.html"  [L]

RewriteRule  "^/$"                 "/homepage.std.html"  [L]

Explications : si vous utilisez un navigateur qui s'identifie comme un navigateur de plateforme mobile (notez que l'exemple est incomplet car il existe de nombreuses autres plateformes mobiles), c'est la version pour mobile de la page d'accueil qui sera renvoyée. Dans le cas contraire, ce sera la page d'accueil standard.

Par défaut, plusieurs directives RewriteCond sont évaluées de manière séquentielle et combinées à l'aide d'un ET logique. Si une condition n'est pas vérifiée et en l'absence d'un opérateur logique OU, l'ensemble du jeu de règles est abandonné et les conditions restantes ne sont pas évaluées.

top

Directive RewriteEngine

Description:Active ou désactive l'exécution du moteur de réécriture
Syntaxe:RewriteEngine on|off
Défaut:RewriteEngine off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteEngine active ou désactive l'exécution du moteur de réécriture. Si sa valeur est off, ce module n'exécutera aucun traitement et ne mettra pas à jour les variables d'environnement SCRIPT_URx.

Plutôt que de commenter toutes les directives RewriteRule, il est préférable d'utiliser cette directive si l'on souhaite désactiver les règles de réécriture dans un contexte particulier.

Notez que les hôtes virtuels n'héritent pas des configurations de réécriture. Ceci implique que vous devez insérer une directive RewriteEngine on dans chaque hôte virtuel pour lequel vous souhaitez utiliser des règles de réécriture.

Les directives RewriteMap du type prg ne sont pas prises en compte au cours de l'initialisation du serveur si elle ont été définies dans un contexte où la directive RewriteEngine n'a pas été définie à on.

top

Directive RewriteMap

Description:Définit une fonction de mise en correspondance pour la recherche de mots-clés
Syntaxe:RewriteMap MapName MapType:MapSource [MapTypeOptions]
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_rewrite
Compatibilité:Le troisième paramètre, MapTypeOptions, est disponible à partir de la version 2.4.29 du serveur HTTP Apache

La directive RewriteMap définit une Table de correspondance pour la réécriture que les fonctions de mise en correspondance peuvent utiliser dans les chaînes de substitution des règles pour insérer/substituer des champs en recherchant des mots-clés. La source utilisée pour cette recherche peut être de plusieurs types.

MapName est le nom de la table de correspondance et servira à spécifier une fonction de mise en correspondance pour les chaînes de substitution d'une règle de réécriture selon une des constructions suivantes :

${ MapName : mot-clé }
${ MapName : mot-clé | valeur par défaut }

Lorsqu'une telle construction est rencontrée, la table de correspondance MapName est consultée et la clé mot-clé recherchée. Si la clé est trouvée, la construction est remplacée par la valeur de remplacement. Si la clé n'est pas trouvée, elle est remplacée par la valeur par défaut, ou par une chaîne vide si aucune valeur par défaut n'est spécifiée. La valeur vide se comporte comme si la clé était absente ; il est donc impossible de distinguer une valeur vide d'une absence de clé.

Par exemple, vous pouvez définir une directive RewriteMap comme suit

RewriteMap map-exemple "txt:/chemin/vers/fichier/map.txt"

Vous pourrez ensuite utiliser cette table dans une directive RewriteRule comme suit :

RewriteRule "^/ex/(.*)" "${map-exemple:$1}"

La signification de l'argument MapTypeOptions dépend du MapType spécifié. Veuillez vous référer au document Utiliser RewriteMap pour plus de détails.

Les combinaisons suivantes pour type de correspondance et MapSource peuvent être utilisées :

txt
Un fichier texte contenant des paires clé-valeur séparées par des espaces, une paire par ligne (Détails ...).
rnd
Sélection aléatoire d'une entrée depuis un fichier texte (Détails ...).
dbm
Recherche une entrée dans un fichier dbm contenant des paires nom-valeur. Le condensé hash est élaboré à partir d'un format de fichier texte via l'utilitaire httxt2dbm (Détails ...).
int
Une des quatre fonctions internes disponibles que fournit RewriteMap: toupper, tolower, escape ou unescape (Détails ...).
prg
Appelle un programme externe ou un script pour effectuer la réécriture (Détails ...).
dbd or fastdbd
Une commande SQL SELECT à exécuter pour rechercher la cible de réécriture (Détails ...).

Vous trouverez plus de détails et de nombreux exemples dans le RewriteMap HowTo.

top

Directive RewriteOptions

Description:Configure certaines options spéciales pour le moteur de réécriture
Syntaxe:RewriteOptions Options
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteOptions définit certaines options spéciales pour la configuration au niveau du serveur ou du répertoire. La chaîne de caractères Option ne peut actuellement prendre qu'une des valeurs suivantes :

Inherit

Ceci force la configuration locale à hériter de la configuration du niveau supérieur. Dans le contexte des hôtes virtuels, cela signifie que les correspondances, conditions et règles du serveur principal sont héritées. Dans le contexte des répertoires, cela signifie que les conditions et règles de la configuration .htaccess ou les sections <Directory> du répertoire parent sont héritées. Les règles héritées sont virtuellement copiées dans la section où cette directive est utilisée. Si elles sont utilisées avec des règles locales, les règles héritées sont placées après ces dernières. La place de cette directive - avant ou après les règles locales - n'a aucune influence sur ce comportement. Si des règles locales ont forcé l'arrêt de la réécriture, les règles héritées ne seront pas traitées.

Les règles héritées du niveau parent sont appliquées after après les règles spécifiées dans le niveau enfant.
InheritBefore

Même effet que l'option Inherit ci-dessus, mais les règles spécifiées dans le niveau parent s'appliquent avant les règles spécifiées dans le niveau enfant.
Disponible depuis la version 2.3.10 du serveur HTTP Apache.

InheritDown

Si cette option est activée, toutes les configurations enfants hériteront de la configuration courante. Il en est de même si l'on spécifie RewriteOptions Inherit dans toutes les configurations enfants. Voir l'option Inherit pour plus de détails à propos de la manière dont les relations parent-enfants sont traitées.
Cette option est disponible à partir de la version 2.4.8 du serveur HTTP Apache.

InheritDownBefore

L'effet de cette option est équivalent à celui de l'option InheritDown ci-dessus, mais les règles de la configuration parente s'appliquent avant toute règle de la configuration enfant.
Cette option est disponible à partir de la version 2.4.8 du serveur HTTP Apache.

IgnoreInherit

Si cette option est activée, les configurations courante et enfants ignoreront toute règle héritée d'une configuration parente via les options InheritDown ou InheritDownBefore.
Cette option est disponible à partir de la version 2.4.8 du serveur HTTP Apache.

AllowNoSlash

Par défaut, mod_rewrite ignore les URLs qui correspondent à un répertoire sur disque, mais ne comportent pas de slash final, afin que le module mod_dir redirige le client vers l'URL canonique avec un slash final.

Lorsque la directive DirectorySlash est définie à off, il est possible de spécifier l'option AllowNoSlash pour s'assurer que les règles de réécriture ne soient plus ignorées. Si on le souhaite, cette option permet de faire s'appliquer des règles de réécriture qui correspondent à un répertoire sans slash final au sein de fichiers .htaccess.
Elle est disponible à partir de la version 2.4.0 du serveur HTTP Apache.

AllowAnyURI

A partir de la version 2.2.22 de httpd, lorsqu'une directive RewriteRule se situe dans un contexte de serveur virtuel ou de serveur principal, mod_rewrite ne traitera les règles de réécriture que si l'URI de la requête respecte la syntaxe d'un chemin URL. Ceci permet d'éviter certains problèmes de sécurité où des règles particulières pourraient permettre des développements de modèles inattendus (voir CVE-2011-3368 et CVE-2011-4317). Pour s'affranchir de la restriction relative à la syntaxe des chemins URL, on peut utiliser l'option AllowAnyURI, afin de permettre à mod_rewrite d'appliquer le jeu de règles à toute chaîne de requête URI, sans vérifier si cette dernière respecte la grammaire des chemins URL définie dans la spécification HTTP.
Disponible depuis la version 2.4.3 du serveur HTTP Apache.

Avertissement à propos de la sécurité

L'utilisation de cette option rendra le serveur vulnérable à certains problèmes de sécurité si les règles de réécritures concernées n'ont pas été rédigées avec soin. Il est par conséquent fortement recommandé de ne pas utiliser cette option. En particulier, prêtez attention aux chaînes en entrée contenant le caractère '@', qui peuvent modifier l'interprétation de l'URI réécrite, comme indiqué dans les liens ci-dessus.

MergeBase

Avec cette option, la valeur de la directive RewriteBase est recopiée depuis une valeur explicitement définie dans tout sous-répertoire qui ne définit pas sa propre directive RewriteBase. Il s'agissait du comportement par défaut avec les versions 2.4.0 à 2.4.3, et ce drapeau qui permet de retrouver ce comportement est disponible depuis la version 2.4.4 du serveur HTTP Apache.

IgnoreContextInfo

Lors d'une substitution relative dans un contexte de répertoire (htaccess), et si la directive RewriteBase n'a pas été définie, ce module utilise des informations en provenance d'une extension d'URL et du contexte du système de fichiers pour transformer la sustitution relative en URL. Par exemple, les modules mod_userdir et mod_alias utilisent ces informations de contexte étendu. Disponible à partir de la version 2.4.16 du serveur HTTP Apache.

LegacyPrefixDocRoot

Avant la version 2.4.26, si une substitution était une URL absolue qui correspondait au serveur virtuel courant, l'URL pouvait être tout d'abord réduite à sa partie chemin, puis enfin en chemin local. Comme l'URL peut être réduite en chemin local, le chemin doit être préfixé par la valeur de la directive DocumentRoot, ce qui permet d'interdire l'accès à un fichier tel que /tmp/myfile suite à une requête pour http://host/file/myfile avec la RewriteRule suivante :

RewriteRule /file/(.*) http://localhost/tmp/$1

Cette option permet de restaurer l'ancien comportement lorsqu'un chemin local obtenu à partir de la réduction d'une URL n'est pas préfixé par la valeur de la directive DocumentRoot. Disponible à partir de la version 2.4.26 du serveur HTTP Apache.

top

Directive RewriteRule

Description:Définit les règles pour le moteur de réécriture
Syntaxe:RewriteRule Modèle Substitution [drapeaux]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteRule est le véritable cheval de trait de la réécriture. La directive peut apparaître plusieurs fois, chaque instance définissant une règle de réécriture particulière. L'ordre dans lequel ces règles sont définies est important - il s'agit de l'ordre dans lequel les règles seront appliquées au cours du processus de réécriture.

Modèle est une expression rationnelle compatible perl. Ce avec quoi ce modèle est comparé dépend de l'endroit où la directive RewriteRule est définie.

Qu'est-ce qui est comparé ?

  • Dans un contexte de serveur virtuel VirtualHost, le modèle est tout d'abord comparé à la portion de l'URL située entre le nom d'hôte éventuellement accompagné du port, et la chaîne de paramètres (par exemple "/app1/index.html"). Il s'agit du URL-path décodé de sa valeur "%xx".

  • Dans un contexte de répertoire (sections Directory et fichiers .htaccess), le Modèle est comparé avec une partie de chemin ; par exemple une requête pour "/app1/index.html" entraînera une comparaison avec "app1/index.html" ou "index.html" selon l'endroit où la directive RewriteRule est définie.

    Le chemin où la règle est défini est supprimé du chemin correspondant du système de fichiers avant comparaison (jusqu'au slash final compris). En conséquence de cette suppression, les règles définies dans ce contexte n'effectuent des comparaisons qu'avec la portion du chemin du système de fichiers "en dessous" de l'endroit où la règle est définie.

    Le chemin correspondant actuel du système de fichiers est déterminé par des directives telles que DocumentRoot et Alias, ou même le résultat de substitutions dans des règles RewriteRule précédentes.

  • Si vous souhaitez faire une comparaison sur le nom d'hôte, le port, ou la chaîne de requête, utilisez une directive RewriteCond comportant respectivement les variables %{HTTP_HOST}, %{SERVER_PORT}, ou %{QUERY_STRING}.

Réécritures dans un contexte de répertoire

  • L'utilisation du moteur de réécriture dans les fichiers .htaccess et les sections <Directory> est un peu plus complexe.
  • Pour activer le moteur de réécriture dans ces contextes, vous devez définir "RewriteEngine On" et "Options FollowSymLinks". Si l'administrateur a désactivé la possibilité de modifier l'option FollowSymLinks au niveau du répertoire d'un utilisateur, vous ne pouvez pas utiliser le moteur de réécriture. Cette restriction a été instaurée à des fins de sécurité.
  • Voir la directive RewriteBase pour plus de détails à propos de l'ajout du préfixe après les substitutions relatives.
  • Si vous souhaitez effectuer une comparaison en prenant en compte l'intégralité du chemin de l'URL dans un contexte de répertoire (htaccess), vous devez utiliser la variable %{REQUEST_URI} dans la directive RewriteCond.
  • Le prefixe supprimé se termine toujours par un slash, ce qui signifie que la comparaison s'effectue avec une chaîne qui ne comporte jamais de slash de début. Ainsi, un modèle contenant ^/ ne correspondra jamais dans un contexte de répertoire.
  • Bien que les règles de réécriture soient permises du point de vue de la syntaxe dans les sections <Location> et <Files> (y compris leurs versions sous forme d'expression rationnelle), elles n'y sont pas prises en compte, et n'y sont à priori d'aucune utilité. Les substitutions relatives sont une fonctionnalité qui n'est, elle non-plus pas supportée dans ce genre de contexte.
  • Les blocs If suivent les règles du contexte de répertoire.
  • Par défaut, mod_rewrite écrase les règles précédentes au sein de sections combinées appartenant au même contexte. Pour modifier ce comportement, on peut utiliser la directive RewriteOptions pour définir par exemple l'option Inherit.
  • La directive RewriteOptions permet aussi de contrôler le comportement des sections définies au même niveau d'imbrication dans la configuration. Dans l'exemple suivant, par défaut seule la règle RewriteRules définie dans le second bloc If est prise en compte car celle définie dans le premier bloc est écrasée. Définir RewriteOptions Inherit force mod_rewrite à combiner les deux sections en prenant en compte les deux règles et pas seulement la dernière.
<If "true">
  # Sans RewriteOptions Inherit, cette règle est écrasée par celle de la section
  # suivante et aucune redirection ne sera effectuée pour les URIs contenant
  # 'foo'
  RewriteRule foo http://example.com/foo [R]
</If>
<If "true">
  RewriteRule bar http://example.com/bar [R]
</If>

Pour quelques conseils à propos des expressions rationnelles, voir le document Introduction à mod_rewrite.

Dans mod_rewrite, on peut aussi utiliser le caractère NOT ('!') comme préfixe de modèle. Ceci vous permet d'inverser la signification d'un modèle, soit pour dire ``si l'URL considérée ne correspond PAS à ce modèle''. Le caractère NON peut donc être utilisé à titre exceptionnel, lorsqu'il est plus simple d'effectuer une comparaison avec le modèle inversé, ou dans la dernière règle par défaut.

Note

Si vous utilisez le caractère NON pour inverser la signification d'un modèle, vous ne pouvez pas inclure de parties génériques groupées dans le modèle. Ceci est dû au fait que, lorsque le modèle ne correspond pas (autrement dit, sa négation correspond), les groupes sont vides. Ainsi, si vous utilisez des modèles inversés, vous ne pouvez pas vous référer aux groupes par $N dans la chaîne de substitution !

Dans une règle de réécriture, Substitution est la chaîne de caractères qui remplace le chemin de l'URL original qui correspondait au Modèle. Substitution peut être :

un chemin du système de fichiers
Il indique alors la localisation dans le système de fichiers de la ressource qui doit être envoyée au client. Les substitutions ne sont traitées en tant que chemins du système de fichiers que si la règle est configurée dans un contexte de serveur (serveur virtuel), et si le premier composant du chemin dans la substitution existe dans le système de fichiers.
chemin d'URL
Un chemin relatif à la valeur de DocumentRoot vers la ressource qui doit être servie. Notez que mod_rewrite essaie de deviner si vous avez spécifié un chemin du système de fichiers ou un chemin d'URL en vérifiant si la première partie du chemin existe à la racine du système de fichiers. Par exemple, si vous avez spécifié comme chaîne de Substitution /www/file.html, cette dernière sera traitée comme un chemin d'URL à moins qu'un répertoire nommé www n'existe à la racine de votre système de fichiers (ou dans le cas d'une réécriture au sein d'un fichier .htaccess, relativement à la racine des documents), auquel cas la chaîne de substitution sera traitée comme un chemin du système de fichiers. Si vous désirez que d'autres directives de correspondance d'URL (comme la directive Alias) soient appliquées au chemin d'URL résultant, utilisez le drapeau [PT] comme décrit ci-dessous.
URL absolue

Si une URL absolue est spécifiée, mod_rewrite vérifie si le nom d'hôte correspond à celui de l'hôte local. Si c'est le cas, le protocole et le nom d'hôte sont supprimés, et ce qui reste est traité comme un chemin d'URL. Dans le cas contraire, une redirection externe vers l'URL indiquée est effectuée. Pour forcer une redirection externe vers l'hôte local, voir le drapeau [R] ci-dessous.

Notez qu'une redirection (implicite ou non) qui utilise une URI absolue inclura la chaîne de paramètres de la requête ; pour éviter ceci, voir le drapeau [QSD] ci-dessous.

- (tiret)
Un tiret indique qu'aucune substitution ne doit être effectuée (le chemin considéré est transmis sans changement). Ceci est utile quand un drapeau doit être appliqué sans modifier le chemin (voir ci-dessous).

En plus du texte, la chaîne Substitution peut comporter :

  1. des références arrières ($N) vers le modèle d'une directive RewriteRule
  2. des références arrières (%N) vers le dernier modèle d'une directive RewriteCond qui correspondait
  3. des variables du serveur comme dans les chaînes de test de condition d'une règle (%{VARNAME})
  4. des appels de fonctions de comparaison (${nom correspondance:clé|défaut})

Les références arrières sont des identificateurs de la forme $N (N=0..9), qui seront remplacés par le contenu du Nème groupe du Modèle qui correspondait. Les variables du serveur sont les mêmes que dans la Chaîne_de_test d'une directive RewriteCond. Les fonctions de comparaison sont issues de la directive RewriteMap dans la section de laquelle elles sont décrites. Ces trois types de variables sont évaluées dans l'ordre ci-dessus.

Chaque règle de réécriture s'applique au résultat de la règle précédente, selon l'ordre dans lequel elles ont été définies dans le fichier de configuration. Le chemin de l'URL ou du système de fichier (voir ci-dessus Qu'est-ce qui est comparé ?) est intégralement remplacée par la chaîne de Substitution et le processus de réécriture se poursuit jusqu'à ce que toutes les règles aient été appliquées, ou qu'il soit explicitement stoppé par un drapeau L, ou par un autre drapeau qui implique un arrêt immédiat, comme END ou F.

Modifier la chaîne de requête

Par défaut, la chaîne de requête est transmise sans modification. Vous pouvez cependant créer dans la chaîne de substitution des URLs dont une partie constitue une chaîne de requête. Pour cela, ajoutez simplement un point d'interrogation dans la chaîne de substitution pour indiquer que le texte qui suit doit être réinjecté dans la chaîne de requête. Pour supprimer une chaîne de requête, terminez simplement la chaîne de substitution par un point d'interrogation. Pour combiner les nouvelles chaînes de requête avec les anciennes, utilisez le drapeau [QSA].

En outre, vous pouvez spécifier des actions spéciales à effectuer en ajoutant des [drapeaux] comme troisième argument de la directive RewriteRule. Séparés par des virgules au sein d'une liste encadrée par des crochets, les drapeaux peuvent être choisis dans la table suivante. Vous trouverez plus de détails, et des exemples pour chaque drapeau dans le document à propos des drapeaux de réécriture.

Drapeaux et syntaxe Fonction
B Echappe les caractères non-alphanumériques dans les références arrières avant d'appliquer la transformation. Pour un échappement similaire des variables du serveur, voir la fonction de mappage "escape".détails ...
BCTLS Identique à [B], mais n'échappe que les espaces et les caractères de contrôle. détails ...
BNE Les caractères de [B] ou [BCTLS] qui ne doivent pas être échappés. détails ...
backrefnoplus|BNP Avec ce drapeau, si les références arrières sont échappées, les espaces seront échappés en %20 au lieu de +. Ceci s'avère utile lorsqu'une référence arrière est utilisée dans la partie chemin, et non dans la chaîne de paramètres de la requête ; pour plus de détails, voir ici.
chain|C La règle est chaînée avec la règle suivante. Si la règle échoue, la ou les règles avec lesquelles elle est est chaînée seront sautées. détails ...
cookie|CO=NAME:VAL Définit un cookie au niveau du navigateur client. La syntaxe complète est : CO=NAME:VAL:domain[:lifetime[:path[:secure[:httponly[samesite]]]]] details ... détails ...
discardpath|DPI Supprime la partie PATH_INFO de l'URI réécrit. détails ...
END Stoppe le processus de réécriture immédiatement et n'applique plus aucune règle. Empêche aussi l'application ultérieure de règles de réécriture dans les contextes de répertoire et de fichier .htaccess (disponible à partir de la version 2.3.9 du serveur HTTP Apache). détails ...
env|E=[!]VAR[:VAL] Définit la variable d'environnement VAR (à la valeur VAL si elle est fournie). La variante !VAR annule la définition de la variable VAR.détails ...
forbidden|F Renvoie une réponse 403 FORBIDDEN au navigateur client. détails ...
gone|G Renvoie un message d'erreur 410 GONE au navigateur client. détails ...
Handler|H=Gestionnaire de contenu L'URI résultant est envoyé au Gestionnaire de contenu pour traitement. détails ...
last|L Arrête le processus de réécriture immédiatement et n'applique plus aucune règle. Prêtez une attention particulière aux mises en garde concernant les contextes de niveau répertoire et .htaccess (voir aussi le drapeau END). détails ...
next|N Réexécute le processus de réécriture à partir de la première règle, en utilisant le résultat du jeu de règles, sous réserve qu'il y ait un point de départ. détails ...
nocase|NC Rend la comparaison entre modèles insensible à la casse. détails ...
noescape|NE Empêche mod_rewrite d'effectuer un échappement hexadécimal des caractères spéciaux dans le résultat des réécritures qui aboutissent à une redirection. détails ...
nosubreq|NS La règle est sautée si la requête courante est une sous-requête interne. détails ...
proxy|P Force l'envoi en interne de l'URL de substitution en tant que requête mandataire. détails ...
passthrough|PT L'URI résultant est repassé au moteur de mise en correspondance des URLs pour y être traité par d'autres traducteurs URI-vers-nom de fichier, comme Alias ou Redirect. détails ...
qsappend|QSA Ajoute toute chaîne de paramètres présente dans l'URL de la requête originale à toute chaîne de paramètres créée dans la cible de réécriture. détails ...
qsdiscard|QSD Supprime toute chaîne de paramètres de l'URI entrant. détails ...
qslast|QSL Interprète le dernier (le plus à droite) point d'interrogation comme le délimiteur de la chaîne de paramètres de la requête, au lieu du premier (le plus à gauche) comme c'est le cas habituellement. Disponble à partir de la version 2.4.19 du serveur HTTP Apache. détails ...
redirect|R[=code] Force une redirection externe, avec un code de statut HTTP optionnel. détails ...
skip|S=nombre Si la règle courante s'applique, le moteur de réécriture doit sauter les nombre règles suivantes. détails ...
type|T=MIME-type Force l'attribution du Type-MIME spécifié au fichier cible. détails ...
UnsafeAllow3F Autorise les substitutions à partir d’URL potentiellement non fiables. détails ...
UnsafePrefixStat Autorise les substitutions potentiellement non fiables à partir d’une variable de tête ou d’une référence arrière vers un chemin du système de fichiers. détails ...
Disponible à partir de la version 2.4.60 du serveur HTTP Apache.
UNC Empêche la fusion des slashes de début multiples tels que ceux utilisés dans les chemins UNC de Windows. détails ...
Disponible à partir de la version 2.4.62 du serveur HTTP Apache.

Développement du répertoire home

Quand la chaîne de substitution commence par quelque chose comme "/~user" (de manière explicite ou par références arrières), mod_rewrite développe le répertoire home sans tenir compte de la présence ou de la configuration du module mod_userdir.

Ce développement n'est pas effectué si le drapeau PT est utilisé dans la directive RewriteRule

Voici toutes les combinaisons de substitution et leurs significations :

Dans la configuration au niveau du serveur principal (httpd.conf)
pour la requête ``GET /chemin/infochemin'':

Règle Résultat de la substitution
^/un_chemin(.*) autre_chemin$1 invalide, non supporté
^/un_chemin(.*) autre_chemin$1 [R] invalide, non supporté
^/un_chemin(.*) autre_chemin$1 [P] invalide, non supporté
^/un_chemin(.*) /autre_chemin$1 /autre_chemin/info_chemin
^/un_chemin(.*) /autre_chemin$1 [R] http://cet_hote/autre_chemin/info_chemin via une redirection externe
^/un_chemin(.*) /autre_chemin$1 [P] sans objet, non supporté
^/un_chemin(.*) http://cet_hote/autre_chemin$1 /autre_chemin/info_chemin
^/un_chemin(.*) http://cet_hote/autre_chemin$1 [R] http://cet_hote/autre_chemin/info_chemin via une redirection externe
^/un_chemin(.*) http://cet_hote/autre_chemin$1 [P] sans objet, non supporté
^/un_chemin(.*) http://autre_hote/autre_chemin$1 http://autre_hote/autre_chemin/info_chemin via une redirection externe
^/un_chemin(.*) http://autre_hote/autre_chemin$1 [R] http://autre_hote/autre_chemin/info_chemin (le drapeau [R] est redondant)
^/somepath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo via internal proxy

Dans une configuration de niveau répertoire pour /chemin
(/chemin/physique/vers/chemin/.htacccess, avec RewriteBase "/chemin")
pour la requête ``GET /chemin/chemin-local/infochemin'':

Règle Résultat de la substitution
^chemin-local(.*) autre-chemin$1 /chemin/autre-chemin/infochemin
^chemin-local(.*) autre-chemin$1 [R] http://cet-hôte/chemin/autre-chemin/infochemin via redirection externe
^chemin-local(.*) autre-chemin$1 [P] n'a pas lieu d'être, non supporté
^chemin-local(.*) /autre-chemin$1 /autre-chemin/infochemin
^chemin-local(.*) /autre-chemin$1 [R] http://cet-hôte/autre-chemin/infochemin via redirection externe
^chemin-local(.*) /autre-chemin$1 [P] n'a pas lieu d'être, non supporté
^chemin-local(.*) http://cet-hôte/autre-chemin$1 /autre-chemin/infochemin
^chemin-local(.*) http://cet-hôte/autre-chemin$1 [R] http://cet-hôte/autre-chemin/infochemin via redirection externe
^chemin-local(.*) http://cet-hôte/autre-chemin$1 [P] n'a pas lieu d'être, non supporté
^chemin-local(.*) http://autre hôte/autre-chemin$1 http://autre hôte/autre-chemin/infochemin via redirection externe
^chemin-local(.*) http://autre hôte/autre-chemin$1 [R] http://autre hôte/autre-chemin/infochemin via redirection externe (le drapeau [R] est redondant)
^chemin-local(.*) http://autre hôte/autre-chemin$1 [P] http://autre hôte/autre-chemin/infochemin via un mandataire interne

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session_cookie.html.fr.utf80000664000175100017510000003472214740503670023660 0ustar covenercovener mod_session_cookie - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_session_cookie

Langues Disponibles:  en  |  fr 

Description:Support des sessions basé sur les cookies
Statut:Extension
Identificateur de Module:session_cookie_module
Fichier Source:mod_session_cookie.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

Avertissement

Les modules de session font usage des cookies HTTP, et peuvent à ce titre être victimes d'attaques de type Cross Site Scripting, ou divulguer des informations à caractère privé aux clients. Veuillez vous assurer que les risques ainsi encourus ont été pris en compte avant d'activer le support des sessions sur votre serveur.

Ce sous-module du module mod_session fournit le support du stockage des sessions utilisateur au niveau du navigateur distant dans des cookies HTTP.

L'utilisation de cookies pour stocker les sessions décharge le serveur ou le groupe de serveurs de la nécessité de stocker les sessions localement, ou de collaborer pour partager les sessions, et peut être utile dans les environnements à fort trafic où le stockage des sessions sur le serveur pourrait s'avérer trop consommateur de ressources.

Si la confidentialité de la session doit être préservée, le contenu de cette dernière peut être chiffré avant d'être enregistré au niveau du client à l'aide du module mod_session_crypto.

Pour plus de détails à propos de l'interface des sessions, voir la documentation du module mod_session.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples simples

Pour créer une session et la stocker dans un cookie nommé session, configurez-la comme suit :

Session stockée au niveau du navigateur

Session On
SessionCookieName session path=/

Pour plus d'exemples sur la manière dont une session doit être configurée pour qu'une application CGI puisse l'utiliser, voir la section exemples de la documentation du module mod_session.

Pour des détails sur la manière dont une session peut être utilisée pour stocker des informations de type nom d'utilisateur/mot de passe, voir la documentation du module mod_auth_form.

top

Directive SessionCookieName

Description:Nom et attributs du cookie RFC2109 dans lequel la session est stockée
Syntaxe:SessionCookieName nom attributs
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_cookie

La directive SessionCookieName permet de spécifier le nom et les attributs optionnels d'un cookie compatible RFC2109 dans lequel la session sera stockée. Les cookies RFC2109 sont définis en utilisant l'en-tête HTTP Set-Cookie.

Une liste optionnelle d'attributs peut être spécifiée, comme dans l'exemple suivant. Ces attributs sont insérés tels quels dans le cookie, et ne sont pas interprétés par Apache. Assurez-vous que vos attributs soient définis correctement selon la spécification des cookies.

Cookie avec attributs

Session On
SessionCookieName session path=/private;domain=example.com;httponly;secure;version=1;
top

Directive SessionCookieName2

Description:Nom et attributs pour le cookie RFC2965 dans lequel est stockée la session
Syntaxe:SessionCookieName2 nom attributs
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_cookie

La directive SessionCookieName2 permet de spécifier le nom et les attributs optionnels d'un cookie compatible RFC2965 dans lequel la session sera stockée. Les cookies RFC2965 sont définis en utilisant l'en-tête HTTP Set-Cookie2.

Une liste optionnelle d'attributs peut être spécifiée, comme dans l'exemple suivant. Ces attributs sont insérés tels quels dans le cookie, et ne sont pas interprétés par Apache. Assurez-vous que vos attributs soient définis correctement selon la spécification des cookies.

Cookie2 avec attributs

Session On
SessionCookieName2 session path=/private;domain=example.com;httponly;secure;version=1;
top

Directive SessionCookieRemove

Description:Détermine si les cookies de session doivent être supprimés des en-têtes HTTP entrants
Syntaxe:SessionCookieRemove On|Off
Défaut:SessionCookieRemove Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_cookie

La directive SessionCookieRemove permet de déterminer si les cookies contenant la session doivent être supprimés des en-têtes pendant le traitement de la requête.

Dans le cas d'un mandataire inverse où le serveur Apache sert de frontal à un serveur d'arrière-plan, révéler le contenu du cookie de session à ce dernier peut conduire à une violation de la confidentialité. À ce titre, si cette directive est définie à "on", le cookie de session sera supprimé des en-têtes HTTP entrants.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_reflector.html.fr.utf80000664000175100017510000002156614740503670022633 0ustar covenercovener mod_reflector - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_reflector

Langues Disponibles:  en  |  fr 

Description:Renvoie un corps de requête comme réponse via la pile de filtres en sortie.
Statut:Base
Identificateur de Module:reflector_module
Fichier Source:mod_reflector.c
Compatibilité:Versions 2.3 et ultérieures

Sommaire

Ce module permet de renvoyer un corps de requête au client, après l'avoir fait passer par la pile de filtres en sortie. Une chaîne de filtres configurée de manière appropriée peut être utilisée pour transformer la requête en réponse. Ce module peut ainsi être utilisé pour transformer un filtre en sortie en service HTTP.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemples

Service de compression
Fait passer le corps de la requête par le filtre DEFLATE pour le compresser. Cette requête nécessite un en-tête Content-Encoding contenant la valeur "gzip" pour que le filtre renvoie les données compressées.
<Location "/compress">
    SetHandler reflector
    SetOutputFilter DEFLATE
</Location>
Service d'abaissement de l'échantillonnage d'image
Fait passer le corps de la requête par un filtre d'abaissement de l'échantillonnage d'image, et renvoie le résultat au client.
<Location "/downsample">
    SetHandler reflector
    SetOutputFilter DOWNSAMPLE
</Location>
top

Directive ReflectorHeader

Description:Renvoie un en-tête d'entrée dans les en-têtes de sortie
Syntaxe:ReflectorHeader en-tête-entrée [en-tête-sortie]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Base
Module:mod_reflector

Cette directive permet de contrôler la répercution des en-têtes de la requête dans la réponse. Le premier argument correspond au nom de l'en-tête à copier. Si le second argument (optionnel) est spécifié, il définit le nom sous lequel l'en-tête sera répercuté dans la réponse ; dans le cas contraire, c'est le nom de l'en-tête original qui sera utilisé.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_request.html.fr.utf80000664000175100017510000002364414740503670022335 0ustar covenercovener mod_request - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_request

Langues Disponibles:  en  |  fr  |  tr 

Description:Filtres permettant de traiter et de mettre à disposition les corps de requêtes HTTP
Statut:Base
Identificateur de Module:request_module
Fichier Source:mod_request.c
Compatibilité:Disponible depuis la version 2.3 d'Apache
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive KeptBodySize

Description:Conserve le corps de la requête à concurrence de la taille maximale spécifiée, pour une utilisation éventuelle par des filtres comme mod_include.
Syntaxe:KeptBodySize taille maximale en octets
Défaut:KeptBodySize 0
Contexte:répertoire
Statut:Base
Module:mod_request

Dans une situation normale, les gestionnaires de requête tels que le gestionnaire par défaut des fichiers statiques suppriment le corps de la requête s'il n'est pas nécessaire au gestionnaire de requête. Il en résulte que les filtres comme mod_include sont limités à des requêtes GET lors de l'inclusion d'autres URLs en tant que sous-requêtes, et ceci même si la requête originale était une requête POST, car le corps de la requête a été supprimé et n'est donc plus disponible une fois le traitement du filtre mis en oeuvre.

Lorsque l'argument de cette directive a une valeur supérieure à zéro, les gestionnaires de requête qui suppriment habituellement les corps de requête vont alors conserver ces corps de requête, à concurrence de la taille maximale spécifiée, pour être éventuellement utilisés par des filtres. Dans le cas du filtre mod_include, une tentative de requête POST pour un fichier shtml statique se traduira par des sous-requêtes POST, et non par des sous-requêtes GET comme avant.

Cette fonctionnalité permet de découper des pages web complexes et des applications web en petits éléments individuels, et de combiner ces éléments avec la structure de la page web sous-jacente en utilisant mod_include. Les éléments peuvent se présenter sous la forme de programmes CGI, de langages de scripts, ou d'URLs issues d'un mandataire inverse dans l'espace d'URL d'un autre serveur en utilisant mod_proxy.

Note : Chaque requête dont le corps est ainsi conservé doit être enregistrée temporairement en mémoire vive jusqu'à la fin du traitement de la requête. Il faut donc s'assurer que la mémoire RAM du serveur est suffisante pour pouvoir supporter la charge induite. L'utilisation de cette directive doit être limitée à certaines portions de votre espace d'URL bien précises qui le nécessitent, et en spécifiant comme taille maximale une valeur la plus petite possible, mais tout de même suffisante pour un corps de requête.

Si la taille de la requête envoyée par le client dépasse la taille maximale autorisée par cette directive, le serveur renverra l'erreur 413 Request Entity Too Large.

Voir aussi

Langues Disponibles:  en  |  fr  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_setenvif.html.fr.utf80000664000175100017510000005613614740503670022472 0ustar covenercovener mod_setenvif - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_setenvif

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Permet de définir des variables d'environnement en fonction de certainescaractéristiques de la requête
Statut:Base
Identificateur de Module:setenvif_module
Fichier Source:mod_setenvif.c

Sommaire

Le module mod_setenvif vous permet de définir des variables d'environnement internes de manière conditionnelle en fonction de critères que vous pouvez spécifier. Ces variables d'environnement peuvent être utilisées par d'autres parties du serveur pour prendre des décisions quant aux actions à entreprendre, et pour déterminer si les scripts CGI et les pages SSI doivent pouvoir y accéder.

Les directives sont interprétées selon l'ordre dans lequel elles apparaîssent dans les fichiers de configuration. Ainsi, des séquences plus complexes peuvent être utilisées, comme dans cet exemple qui définit netscape si le navigateur est Mozilla et non MSIE.

BrowserMatch ^Mozilla netscape
BrowserMatch MSIE !netscape

Lorsque le serveur cherche un chemin via une sous-requête interne (par exemple la recherche d'un DirectoryIndex), ou lorsqu'il génère un listing du contenu d'un répertoire via le module mod_autoindex, la sous-requête n'hérite pas des variables d'environnement spécifiques à la requête. En outre, à cause des phases de l'API auxquelles mod_setenvif prend part, les directives SetEnvIf ne sont pas évaluées séparément dans la sous-requête.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive BrowserMatch

Description:Définit des variables d'environnement en fonction du contenu de l'en-tête HTTP User-Agent
Syntaxe:BrowserMatch regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_setenvif

La directive BrowserMatch est un cas particulier de la directive SetEnvIf, qui définit des variables d'environnement en fonction du contenu de l'en-tête de requête HTTP User-Agent. Les deux lignes suivantes produisent le même effet :

BrowserMatch Robot is_a_robot
SetEnvIf User-Agent Robot is_a_robot

Quelques exemples supplémentaires :

BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
BrowserMatch MSIE !javascript
top

Directive BrowserMatchNoCase

Description:Définit des variables d'environnement en fonction du contenu de l'en-tête HTTP User-Agent sans tenir compte de la casse
Syntaxe:BrowserMatchNoCase regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_setenvif

La directive BrowserMatchNoCase est identique sur le plan sémantique à la directive BrowserMatch. Elle permet cependant une comparaison insensible à la casse. Par exemple :

BrowserMatchNoCase mac platform=macintosh
BrowserMatchNoCase win platform=windows

Les directives BrowserMatch et BrowserMatchNoCase sont des cas particuliers des directives SetEnvIf et SetEnvIfNoCase. Ainsi, les deux lignes suivantes produisent le même effet :

BrowserMatchNoCase Robot is_a_robot
SetEnvIfNoCase User-Agent Robot is_a_robot
top

Directive SetEnvIf

Description:Définit des variables d'environnement en fonction des attributs de la requête
Syntaxe:SetEnvIf attribut regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_setenvif

La directive SetEnvIf permet de définir des variables d'environnement en fonction des attributs de la requête. L'attribut spécifié comme premier argument peut se présenter sous l'une des trois formes suivantes :

  1. Un champ d'en-tête de requête HTTP (voir la RFC2616 pour plus d'information à leur propos) ; par exemple : Host, User-Agent, Referer, ou Accept-Language. Il est possible d'utiliser une expression rationnelle pour spécifier un jeu d'en-têtes de requête.
  2. Une des caractéristiques de la requête suivantes :
    • Remote_Host - le nom d'hôte (s'il est disponible) du client qui effectue la requête
    • Remote_Addr - l'adresse IP du client qui effectue la requête
    • Server_Addr - l'adresse IP du serveur qui a reçu la requête (uniquement à partir des versions supérieures à 2.0.43)
    • Request_Method - Le nom de la méthode HTTP utilisée (GET, POST, et cetera...)
    • Request_Protocol - le nom et la version du protocole utilisé pour la requête (par exemple "HTTP/0.9", "HTTP/1.1", etc...)
    • Request_URI - la ressource demandée dans la ligne de requête HTTP -- en général la partie de l'URL suivant le protocole et le nom du serveur, sans la chaîne d'arguments. Voir la directive RewriteCond du module mod_rewrite pour plus d'informations sur la manière de mettre en correspondance votre chaîne d'arguments.
  3. Le nom d'une variable d'environnement parmi la liste de celles qui sont associées à la requête. Ceci permet à la directive SetEnvIf d'effectuer des tests en fonction du résultat de comparaisons précédentes. Seules les variables d'environnement définies par des directives SetEnvIf[NoCase] précédentes sont disponibles pour effectuer des tests de cette manière. 'Précédentes' signifie qu'elles se trouvent à un niveau plus global de la configuration (par exemple au niveau du serveur principal), ou plus haut chronologiquement dans le contexte de la directive. Les variables d'environnement ne seront prises en compte que si aucune correspondance n'a été trouvée parmi les caractéristiques de la requête, et si attribut n'a pas été spécifié sous la forme d'une expression rationnelle.

Le second argument (regex) est une expression rationnelle. Si regex correspond à l'attribut, les arguments suivants sont évalués.

Le reste des arguments constitue les noms des variables à définir, ainsi que les valeurs optionnelles qui doivent leur être affectées. Ils peuvent se présenter sous les formes suivantes :

  1. nom-variable, ou
  2. !nom-variable, ou
  3. nom-variable=valeur

Dans la première forme, la valeur sera définie à "1". Dans la seconde forme, la variable sera supprimée si elle a été définie au préalable, et dans la troisième forme, la variable sera définie à la valeur littérale spécifiée par valeur. Depuis la version 2.0.51, Apache httpd reconnaît les occurrences de variables $1..$9 à l'intérieur de valeur, et les remplace par les sous-expressions entre parenthèses correspondantes de regex. $0 permet d'accéder à l'ensemble de la chaîne qui correspond à ce modèle.

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\.example\.com intra_site_referral
    
SetEnvIf object_is_image xbm XBIT_PROCESSING=1

SetEnvIf Request_URI "\.(.*)$" EXTENSION=$1
    
SetEnvIf ^TS  ^[a-z]  HAVE_TS

Les trois premières lignes définissent la variable d'environnement objet_est_une_image si l'objet de la requête est un fichier image, et la quatrième définit la variable intra_site_referral si la page référante se trouve quelque part dans le site web www.mydomain.example.com.

La dernière ligne définit la variable d'environnement HAVE_TS si la requête contient un en-tête dont le nom commence par "TS" et dont la valeur commence par tout caractère du jeu [a-z].

Voir aussi

top

Directive SetEnvIfExpr

Description:Définit des variables d'environnement en fonction d'une expression ap_expr
Syntaxe:SetEnvIfExpr expr [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_setenvif

La directive SetEnvIfExpr permet de définir des variables d'environnement en fonction d'une expression. Cette expression est évaluée à l'exécution, et les différentes variables d'environnement env-variable définies de la même manière que la directive SetEnvIf, y compris les références arrières.

    SetEnvIfExpr "tolower(req('X-Sendfile')) == 'd:\images\very_big.iso')" iso_delivered
    SetEnvIfExpr "tolower(req('X-Sendfile')) =~ /(.*\.iso$)/" iso-path=$1

Dans cet exemple, la variable d'environnement iso_delivered est définie chaque fois que notre application tente de l'envoyer via X-Sendfile.

Il pourrait être plus utile de définir une variable rfc1918 si l'adresse IP distante est une adresse privée au sens de la RFC 1918 :

SetEnvIfExpr "-R '10.0.0.0/8' || -R '172.16.0.0/12' || -R '192.168.0.0/16'" rfc1918

Voir aussi

top

Directive SetEnvIfNoCase

Description:Définit des variables d'environnement en fonction des attributs de la requête sans tenir compte de la casse
Syntaxe:SetEnvIfNoCase attribut regex [!]env-variable[=valeur] [[!]env-variable[=valeur]] ...
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Base
Module:mod_setenvif

La directive SetEnvIfNoCase est identique d'un point de vue sémantique à la directive SetEnvIf, et ne s'en distingue que par le fait que la comparaison des expressions rationnelles est effectuée sans tenir compte de la casse. Par exemple :

SetEnvIfNoCase Host Example\.Org site=example

Cette ligne va définir la variable d'environnement site avec la valeur "example" si le champ d'en-tête de requête HTTP Host: est présent et contient Example.Org, example.org, ou une autre combinaison des mêmes caractères, sans tenir compte de la casse.

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_so.html.fr.utf80000664000175100017510000003614014740503670021261 0ustar covenercovener mod_so - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_so

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Chargement de modules ou de code exécutable au cours du démarrage ou du redémarrage du serveur
Statut:Extension
Identificateur de Module:so_module
Fichier Source:mod_so.c
Compatibilité:Sous Windows, c'est un module de base (toujours inclus)

Sommaire

Sur les systèmes d'exploitation sélectionnés, ce module peut être utilisé pour charger des modules dans le serveur HTTP Apache en cours d'exécution grâce au mécanisme des Dynamic Shared Object ou Objets Partagés Dynamiquement (DSO), et évite ainsi de devoir effectuer une recompilation.

Sous Unix, le code chargé provient en général de fichiers objet partagés possèdant en général l'extension .so, alors que sous Windows, l'extension peut être soit .so, soit .dll.

Avertissement

En général, les modules compilés pour une version majeure du serveur HTTP Apache ne fonctionneront pas avec une autre (par exemple de 1.3 à 2.0 ou 2.0 à 2.2). D'une version majeure à l'autre, il y a souvent des modifications d'API qui nécessitent des modifications du module pour qu'il puisse fonctionner avec la nouvelle version.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Création de modules chargeables pour Windows

Note

Sous Windows, où les modules chargeables possèdent en général l'extension de nom de fichier .dll, les modules Apache httpd se nomment mod_nom-module.so, tout comme sur les autres plates-formes. Vous trouverez cependant encore des modules tiers, comme PHP par exemple, qui continuent d'utiliser la convention de nommage avec extension .dll.

Bien que mod_so puisse encore charger des modules possèdant un nom du style ApacheModuleFoo.dll, il est préférable d'utiliser la nouvelle convention de nommage ; si vous modifiez votre module chargeable pour la version 2.0, veuillez aussi modifier son nom pour respecter cette nouvelle convention.

Les API des modules Apache httpd sous Unix et Windows sont identiques. Alors que certains modules s'appuient sur certains aspects de l'architecture Unix non présents dans Windows, et ne fonctionneront donc pas sur cette dernière plate-forme, de nombreux modules fonctionnent sous Windows avec peu ou pas de modification par rapport à leur version Unix.

Lorsqu'un module fonctionne, il peut être ajouté au serveur de deux manières. Sous Unix, il peut être compilé dans le serveur. Comme Apache httpd pour Windows ne dispose pas du programme Configure propre à Apache httpd pour Unix, le fichier source du module doit être ajouté au fichier projet Apache de base, et ses symboles ajoutés au fichier os\win32\modules.c.

La seconde méthode consiste à compiler le module en tant que DLL, à savoir une bibliothèque partagée qui pourra être chargée dans le serveur en cours d'exécution via la directive LoadModule. Ces modules DLL peuvent être distribués et exécutés sur toute installation d'Apache httpd pour Windows, sans avoir à recompiler le serveur.

Pour créer un module DLL, il est nécessaire d'apporter une légère modification à son fichier source : l'enregistrement du module doit être exporté depuis la DLL (qui sera elle-même créée plus tard ; voir plus loin). Pour ce faire, ajoutez la macro AP_MODULE_DECLARE_DATA (définie dans les fichiers d'en-têtes d'Apache httpd) à la définition de l'enregistrement de votre module. Par exemple, si votre module est déclaré comme suit :

module foo_module;

Remplacez cette ligne par :

module AP_MODULE_DECLARE_DATA foo_module;

Notez que cette macro ne sera prise en compte que sous Windows, si bien que le module poura être utilisé sans changement sous Unix, si besoin est. Alternativement, si vous êtes familier avec les fichiers .DEF, vous pouvez les utiliser pour exporter l'enregistrement du module.

Maintenant, nous sommes prêts à créer une DLL contenant notre module. Il va falloir pour cela la lier avec la bibliothèque d'export libhttpd.lib qui a été créée au cours de la compilation de la bibliothèque partagée libhttpd.dll. Il sera peut-être aussi nécessaire de modifier la configuration du compilateur pour s'assurer que les fichiers d'en-têtes d'Apache httpd seront correctement localisés. Vous trouverez cette bibliothèque à la racine du répertoire des modules de votre serveur. Il est souhaitable d'utiliser un fichier de module .dsp existant dans l'arborescence afin de s'assurer que l'environnement de compilation est correctement configuré, mais vous pouvez aussi comparer les options de compilation et d'édition de liens à votre fichier .dsp.

Ceci devrait créer une version DLL de votre module. Il vous suffit maintenant de l'enregistrer dans le répertoire modules à la racine de votre serveur, et d'utiliser la directive LoadModule pour la charger.

top

Directive LoadFile

Description:Liaison du fichier objet ou de la bibliothèque spécifié
Syntaxe:LoadFile nom-fichier [nom-fichier] ...
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_so

La directive LoadFile permet de lier le fichier objet ou la bibliothèque spécifié au serveur lors du démarrage ou du redémarrage de ce dernier ; ceci permet d'ajouter tout code additionnel nécessaire au fonctionnement d'un module. nom-fichier est soit un chemin absolu, soit un chemin relatif au répertoire défini par la directive ServerRoot.

Par exemple :

LoadFile "libexec/libxmlparse.so"
top

Directive LoadModule

Description:Liaison avec le serveur du fichier objet ou de la bibliothèque spécifié, et ajout de ce dernier à la liste des modules actifs
Syntaxe:LoadModule module nom-fichier
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_so

La directive LoadModule permet de lier le fichier objet ou la bibliothèque nom-fichier avec le serveur, et d'ajouter la structure de module nommée module à la liste des modules actifs. module est le nom de la variable externe de type module dans le fichier, et est référencé comme Identificateur de module dans la documentation des modules.

Par exemple :

LoadModule status_module "modules/mod_status.so"

charge le module spécifié depuis le sous-répertoire des modules situé à la racine du serveur.

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_memcache.html.fr.utf80000664000175100017510000002224614740503670024071 0ustar covenercovener mod_socache_memcache - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_socache_memcache

Langues Disponibles:  en  |  fr 

Description:Fournisseur de cache d'objets partagés basé sur Memcache.
Statut:Extension
Identificateur de Module:socache_memcache_module
Fichier Source:mod_socache_memcache.c

Sommaire

Le module mod_socache_memcache est un fournisseur de cache d'objets partagés qui permet la création et l'accès à un cache maintenu par le système de mise en cache d'objets en mémoire distribuée à hautes performances memcached.

Cette méthode "create" du fournisseur de cache d'objets partagés requiert une liste de spécifications hôte/port en cache mémoire séparées par des virgules. Si vous utilisez ce fournisseur dans la configuration d'autres modules (comme SSLSessionCache), vous devez fournir la liste des serveurs sous la forme du paramètre optionnel "arg".

SSLSessionCache memcache:memcache.example.com:12345,memcache2.example.com:12345

Vous trouverez des détails à propos des autres fournisseurs de cache d'objets partagés ici.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive MemcacheConnTTL

Description:Durée de conservation des connexions inactives
Syntaxe:MemcacheConnTTL num[units]
Défaut:MemcacheConnTTL 15s
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_socache_memcache
Compatibilité:Disponible à partir de la version 2.4.17 du serveur HTTP Apache.

Définit la durée pendant laquelle les connexions inactives avec le(s) serveur(s) memcache seront conservées (plateformes threadées seulement).

Les valeurs valides de la directive MemcacheConnTTL sont des durées d'une heure maximum. La valeur 0 signifie une absence de péremption

L'unité par défaut pour ce délai est la seconde, mais vous pouvez ajouter un suffixe pour spécifier une unité différente ; ms pour milliseconde, s pour seconde, min pour minute et h pour heure..

Dans les versions antérieures à 2.4.17, ce délai était codé en dur et sa valeur était 600 microsecondes. La valeur la plus proche de cette ancienne valeur pour la directive MemcacheConnTTL est donc 1ms.

# Définition d'un délai de 10 minutes
MemcacheConnTTL 10min
# Définition d'un délai de 60 secondes
MemcacheConnTTL 60

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_speling.html.fr.utf80000664000175100017510000003311114740503670022274 0ustar covenercovener mod_speling - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_speling

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Tente de corriger les erreurs de casse dans les URLs ou les fautes de frappe mineures.
Statut:Extension
Identificateur de Module:speling_module
Fichier Source:mod_speling.c

Sommaire

Il arrive que des requêtes pour des documents ne puissent pas être traitées par le serveur Apache de base à cause d'une erreur de frappe ou de casse. Ce module permet de traiter ce problème en essayant de trouver un document correspondant, même lorsque tous les autres modules y ont renoncé. Sa méthode de travail consiste à comparer chaque nom de document du répertoire demandé avec le document de la requête sans tenir compte de la casse, et en acceptant jusqu'à une erreur (insertion, omission, inversion de caractère ou caractère erroné). Une liste de tous les documents qui correspondent est alors élaborée en utilisant cette stratégie. Ce module traite aussi les erreurs dans les extensions de fichiers.

Si après le parcours du répertoire,

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive CheckBasenameMatch

Description:Vérifie aussi la correspondance des fichiers, même avec des extensions différentes
Syntaxe:CheckBasenameMatch on|off
Défaut:CheckBasenameMatch On
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Extension
Module:mod_speling
Compatibilité:Disponible à partir de la version 2.4.50 du serveur HTTP Apache

Lorsqu'elle est définie, cette directive étend le processus de correction orthographique à l'extension des noms de fichiers. Par exemple, un fichier de nom foo.gif sera pris en compte par une requête pour foo ou foo.jpg. Ceci peut s'avérer particulièrement utile en conjonction avec les MultiViews.

top

Directive CheckCaseOnly

Description:Limite l'action du module aux corrections de majuscules
Syntaxe:CheckCaseOnly on|off
Défaut:CheckCaseOnly Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Extension
Module:mod_speling

Lorsqu'elle est définie à "on", cette directive permet de limiter l'action du module aux inversions majuscule/minuscule. Les autres corrections éventuelles ne seront effectuées que si la directive CheckBasenameMatch est elle aussi définie.

top

Directive CheckSpelling

Description:Active le module de correction
Syntaxe:CheckSpelling on|off
Défaut:CheckSpelling Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:Options
Statut:Extension
Module:mod_speling

Cette directive permet d'activer ou de désactiver le module de correction. Lorsqu'il est activé, rappelez-vous que :

mod_speling ne doit pas être activé pour des répertoires où DAV l'est aussi, car il va essayer de "corriger" les noms des ressources nouvellement créées en fonction des noms de fichiers existants ; par exemple, lors du chargement d'un nouveau document doc43.html, il est possible qu'il redirige vers un document existant doc34.html, ce qui ne correspond pas à ce que l'on souhaite.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_sed.html.fr.utf80000664000175100017510000003032714740503670021414 0ustar covenercovener mod_sed - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_sed

Langues Disponibles:  en  |  fr 

Description:Filtre les contenus en entrée (requêtes) et en sortie (réponses) en utilisant la syntaxe de sed
Statut:
Identificateur de Module:sed_module
Fichier Source:mod_sed.c sed0.c sed1.c regexp.c regexp.h sed.h
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

mod_sed est un filtre de contenu "in-process". Le filtre mod_sed fournit les commandes d'édition de sed implémentées par le programme sed de Solaris 10 comme décrit dans la page de manuel. Cependant, à la différence de sed, mod_sed ne reçoit pas de données sur son entrée standard. Au lieu de cela, le filtre agit sur les données échangées entre le client et le serveur. mod_sed peut être utilisé comme filtre en entrée ou en sortie. mod_sed est un filtre de contenu, ce qui signifie qu'on ne peut pas l'utiliser pour modifier les en-têtes http du client ou du serveur.

Le filtre en sortie mod_sed accepte un tronçon de données, exécute le script sed sur ces données, puis génère une sortie qui est transmise au filtre suivant dans la chaîne.

Le filtre en entrée mod_sed reçoit des données en provenance du filtre suivant dans la chaîne, exécute les scripts sed, et renvoie les données générées au filtre appelant dans la chaîne de filtrage.

Les filtres en entrée ou en sortie ne traitent les données que si des caractères newline sont détectés dans le contenu à filtrer. A la fin des données, ce qui reste est traité comme la dernière ligne. A partir de la version 2.4.54 du serveur HTTP Apache, les lignes d'une taille supérieure à 8 Mo provoquent une erreur.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Exemple de configuration

Ajout d'un filtre en sortie

# Dans l'exemple suivant, le filtre sed va remplacer la chaîne
	 # "monday" par "MON" et la chaîne "sunday" par "SUN" dans les
	 # documents html avant de les envoyer au client.
<Directory "/var/www/docs/sed"> 
    AddOutputFilter Sed html 
    OutputSed "s/monday/MON/g" 
    OutputSed "s/sunday/SUN/g" 
</Directory>

Ajout d'un filtre en entrée

         # Dans l'exemple suivant, le filtre sed va remplacer la chaîne
	 # "monday" par "MON" et la chaîne "sunday" par "SUN" dans les
	 # données POST envoyées à PHP.
        <Directory "/var/www/docs/sed"> 
    AddInputFilter Sed php 
    InputSed "s/monday/MON/g" 
    InputSed "s/sunday/SUN/g" 
</Directory>
top

Commandes sed

Vous trouverez tous les détails à propos de la commande sed dans sa page de manuel.

b
Saut vers le label spécifié (similaire à goto).
h
Copie la ligne courante dans le tampon.
H
Ajoute la ligne courante au tampon.
g
Copie le contenu du tampon dans la ligne courante.
G
Ajoute le contenu du tampon à la ligne courante.
x
Echange les contenus du tampon et de la ligne courante.
top

Directive InputSed

Description:Commande sed à exécuter pour le filtrage des données d'une requête (en général des données POST)
Syntaxe:InputSed commande-sed
Contexte:répertoire, .htaccess
Statut:
Module:mod_sed

La directive InputSed permet de spécifier la commande sed à exécuter pour le filtrage des données (en général des données POST) d'une requête.

top

Directive OutputSed

Description:Commande sed pour le filtrage des contenus de type réponse
Syntaxe:OutputSed commande-sed
Contexte:répertoire, .htaccess
Statut:
Module:mod_sed

La directive OutputSed permet de spécifier la commande sed à exécuter dans le cadre du traitement d'une réponse.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session_crypto.html.fr.utf80000664000175100017510000004643414740503670023732 0ustar covenercovener mod_session_crypto - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_session_crypto

Langues Disponibles:  en  |  fr 

Description:Support du chiffrement des sessions
Statut:Expérimental
Identificateur de Module:session_crypto_module
Fichier Source:mod_session_crypto.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

Avertissement

Les modules de session font usage des cookies HTTP, et peuvent à ce titre être victimes d'attaques de type Cross Site Scripting, ou divulguer des informations à caractère privé aux clients. Veuillez vous assurer que les risques ainsi encourus ont été pris en compte avant d'activer le support des sessions sur votre serveur.

Ce sous-module du module mod_session fournit le support du chiffrement des sessions utilisateur avant de les enregistrer dans une base de données locale, ou dans un cookie HTTP au niveau du navigateur distant.

Il peut contribuer à préserver la confidentialité des sessions lorsque leur contenu doit rester privé pour l'utilisateur, ou lorsqu'une protection contre les attaques de type cross site scripting est nécessaire.

Pour plus de détails à propos de l'interface des sessions, voir la documentation du module mod_session.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Utilisation de base

Pour créer une session chiffrée et la stocker dans un cookie nommé session, configurez la comme suit :

Session chiffrée stockée au niveau du serveur

Session On
SessionCookieName session path=/
SessionCryptoPassphrase secret

La session sera chiffrée avec la clé spécifiée. Il est possible de configurer plusieurs serveurs pour qu'ils puissent partager des sessions, en s'assurant que la même clé de chiffrement est utilisée sur chaque serveur.

Si la clé de chiffrement est modifiée, les sessions seront automatiquement invalidées.

Pour des détails sur la manière dont une session peut être utilisée pour stocker des informations de type nom d'utilisateur/mot de passe, voir la documentation du module mod_auth_form.

top

Directive SessionCryptoCipher

Description:L'algorithme à utiliser pour le chiffrement de la session
Syntaxe:SessionCryptoCipher algorithme
Défaut:SessionCryptoCipher aes256
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Expérimental
Module:mod_session_crypto
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive SessionCryptoCipher permet de spécifier l'algorithme à utiliser pour le chiffrement. En l'absence de spécification, l'algorithme par défaut est aes256.

L'algorithme peut être choisi, en fonction du moteur de chiffrement utilisé, parmi les valeurs suivantes :

top

Directive SessionCryptoDriver

Description:Le pilote de chiffrement à utiliser pour chiffrer les sessions
Syntaxe:SessionCryptoDriver nom [param[=valeur]]
Défaut:aucun
Contexte:configuration globale
Statut:Expérimental
Module:mod_session_crypto
Compatibilité:Disponible depuis la version 2.3.0 d'Apache

La directive SessionCryptoDriver permet de spécifier le nom du pilote à utiliser pour le chiffrement. Si aucun pilote n'est spécifié, le pilote utilisé par défaut sera le pilote recommandé compilé avec APR-util.

Le pilote de chiffrement NSS nécessite certains paramètres de configuration, qui seront spécifiés comme arguments de la directive avec des valeurs optionnelles après le nom du pilote.

NSS sans base de données de certificats

SessionCryptoDriver nss

NSS avec base de données de certificats

SessionCryptoDriver nss dir=certs

NSS avec base de données de certificats et paramètres

SessionCryptoDriver nss dir=certs clé3=clé3.db cert7=cert7.db secmod=secmod

NSS avec chemins contenant des espaces

SessionCryptoDriver nss "dir=My Certs" key3=key3.db cert7=cert7.db secmod=secmod

Le pilote de chiffrement NSS peut avoir été configuré au préalable dans une autre partie du serveur, par exemple depuis mod_nss ou mod_ldap. Si c'est le cas, un avertissement sera enregistré dans le journal, et la configuration existante s'en trouvera affectée. Pour éviter cet avertissement, utilisez le paramètre noinit comme suit :

NSS avec base de données de certificats

SessionCryptoDriver nss noinit

Pour éviter la confusion, assurez-vous que tous les modules utilisant NSS soient configurés avec des paramètres identiques.

Le pilote de chiffrement openssl accepte un paramètre optionnel permettant de spécifier le moteur de chiffrement à utiliser.

OpenSSL avec spécification du moteur de chiffrement

SessionCryptoDriver openssl engine=nom-moteur
top

Directive SessionCryptoPassphrase

Description:La clé utilisée pour chiffrer la session
Syntaxe:SessionCryptoPassphrase secret [ secret ... ]
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Expérimental
Module:mod_session_crypto
Compatibilité:Disponible depuis la version 2.3.0 d'Apache

La directive SessionCryptoPassphrase permet de spécifier les clés à utiliser pour chiffrer de manière symétrique le contenu de la session avant de l'enregistrer, ou pour déchiffrer le contenu de la session après sa lecture.

L'utilisation de clés longues et composées de caractères vraiment aléatoires est plus performant en matière de sécurité. Modifier une clé sur un serveur a pour effet d'invalider toutes les sessions existantes.

Il est possible de spécifier plusieurs clés afin de mettre en oeuvre la rotation de clés. La première clé spécifiée sera utilisée pour le chiffrement, alors que l'ensemble des clés spécifiées le sera pour le déchiffrement. Pour effectuer une rotation périodique des clés sur plusieurs serveurs, ajoutez une nouvelle clé en fin de liste, puis, une fois la rotation complète effectuée, supprimez la première clé de la liste.

Depuis la version 2.4.7, si la valeur de l'argument commence par exec: , la commande spécifiée sera exécutée, et la première ligne que cette dernière renverra sur la sortie standard sera utilisée comme clé.

# clé spécifiée et utilisée en tant que tel
SessionCryptoPassphrase secret

# exécution de /path/to/program pour générer la clé
SessionCryptoPassphrase exec:/path/to/program

# exécution de /path/to/program avec un argument pour générer la clé
SessionCryptoPassphrase "exec:/path/to/otherProgram argument1"
top

Directive SessionCryptoPassphraseFile

Description:Le fichier contenant les clés utilisées pour chiffrer la session
Syntaxe:SessionCryptoPassphraseFile nom-fichier
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire
Statut:Expérimental
Module:mod_session_crypto
Compatibilité:Disponible depuis la version 2.3.0 du serveur HTTP Apache

La directive SessionCryptoPassphraseFile permet de spécifier le nom d'un fichier de configuration contenant les clés à utiliser pour le chiffrement et le déchiffrement de la session (une clé par ligne). Le fichier est lu au démarrage du serveur, et un redémarrage graceful est nécessaire pour prendre en compte un éventuel changement de clés.

À la différence de la directive SessionCryptoPassphrase, les clés ne sont pas présentes dans le fichier de configuration de httpd et peuvent être cachées via une protection appropriée du fichier de clés.

Il est possible de spécifier plusieurs clés afin de mettre en oeuvre la rotation de clés. La première clé spécifiée sera utilisée pour le chiffrement, alors que l'ensemble des clés spécifiées le sera pour le déchiffrement. Pour effectuer une rotation périodique des clés sur plusieurs serveurs, ajoutez une nouvelle clé en fin de liste, puis, une fois la rotation complète effectuée, supprimez la première clé de la liste.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_slotmem_plain.html.fr.utf80000664000175100017510000002071514740503670023504 0ustar covenercovener mod_slotmem_plain - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_slotmem_plain

Langues Disponibles:  en  |  fr 

Description:Fournisseur de mémoire partagée à base de slots.
Statut:Extension
Identificateur de Module:slotmem_plain_module
Fichier Source:mod_slotmem_plain.c

Sommaire

mod_slotmem_plain est un fournisseur de mémoire qui permet la création et l'utilisation d'un segment de mémoire contigu dans lequel les ensembles de données sont organisés en "slots".

Si la mémoire doit être partagée entre des threads et des processus, il est préférable d'utiliser le fournisseur mod_slotmem_shm.

mod_slotmem_plain fournit une API comprenant les fonctions suivantes :

/* appelle le callback sur tous les slots actifs */
apr_status_t doall(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)      

/* crée un nouveau slot de mémoire dont chaque item aura une taille de item_size. */
apr_status_t create(ap_slotmem_instance_t **new, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool)      

/* rattache à un slot de mémoire existant. */
apr_status_t attach(ap_slotmem_instance_t **new, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)      

/* indique la mémoire associée à ce slot actif. */
apr_status_t dptr(ap_slotmem_instance_t *s, unsigned int item_id, void **mem)      

/* lit la mémoire depuis ce slot et la transfert vers dest */
apr_status_t get(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len)      

/* écrit dans ce slot la mémoire en provenance de src */
apr_status_t put(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len)      

/* renvoie le nombre total de slots contenus dans ce segment */
unsigned int num_slots(ap_slotmem_instance_t *s)      

/* renvoie la taille totale des données, en octets, contenues dans un slot de ce segment */
apr_size_t slot_size(ap_slotmem_instance_t *s)      

/* alloue le premier slot libre et le marque comme utilisé (n'effectue aucune copie de données) */
apr_status_t grab(ap_slotmem_instance_t *s, unsigned int *item_id)      

/* appropriation ou allocation forcée du slot spécifié et marquage comme utilisé (n'effectue aucune copie de données) */
apr_status_t fgrab(ap_slotmem_instance_t *s, unsigned int item_id)      
        
/* libère un slot et le marque comme non utilisé (n'effectue aucune copie de données) */
apr_status_t release(ap_slotmem_instance_t *s, unsigned int item_id)
Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_suexec.html.fr.utf80000664000175100017510000002057014740503670022134 0ustar covenercovener mod_suexec - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_suexec

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Permet l'exécution des scripts CGI sous l'utilisateur et le groupe spécifiés
Statut:Extension
Identificateur de Module:suexec_module
Fichier Source:mod_suexec.c

Sommaire

Ce module, en combinaison avec son programme support suexec, permet l'exécution des scripts CGI sous l'utilisateur et le groupe spécifiés.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive SuexecUserGroup

Description:L'utilisateur et le groupe sous lesquels les programmes CGI doivent s'exécuter
Syntaxe:SuexecUserGroup Utilisateur Groupe
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_suexec

La directive SuexecUserGroup permet de spécifier l'utilisateur et le groupe sous lesquels les programmes CGI doivent s'exécuter. Les requêtes non CGI seront toujours traitées avec l'utilisateur spécifié par la directive User.

Exemple

SuexecUserGroup nobody nogroup

Le démarrage échouera si cette directive est spécifiée et si la fonctionnalité suEXEC est désactivée.

Voir aussi

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_unixd.html.fr.utf80000664000175100017510000003530614740503670021772 0ustar covenercovener mod_unixd - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_unixd

Langues Disponibles:  en  |  fr  |  tr 

Description:Sécurité de base (nécessaire) pour les plates-formes de la famille Unix.
Statut:Base
Identificateur de Module:unixd_module
Fichier Source:mod_unixd.c
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive ChrootDir

Description:Répertoire dans lequel Apache doit se positionner au démarrage après avoir effectué un chroot(8).
Syntaxe:ChrootDir chemin-répertoire
Défaut:Non défini
Contexte:configuration globale
Statut:Base
Module:mod_unixd
Compatibilité:Disponible depuis la version 2.2.10 d'Apache

Cette directive fait en sorte que le serveur effectue un chroot(8) vers le répertoire spécifié après le démarrage, mais avant d'accepter les requêtes en provenance du réseau.

Notez que l'exécution du serveur dans un environnement chroot n'est pas simple et nécessite une configuration particulière, en particulier si vous utilisez des scripts CGI ou PHP. Il est conseillé de se familiariser avec l'opération chroot avant d'essayer d'utiliser cette fonctionnalité.

top

Directive Group

Description:Groupe sous lequel le serveur va traiter les requêtes
Syntaxe:Group groupe unix
Défaut:Group #-1
Contexte:configuration globale
Statut:Base
Module:mod_unixd

La directive Group permet de définir le groupe sous lequel le serveur va traiter les requêtes. Pour utiliser cette directive, le serveur doit avoir été démarré par root. Si vous démarrez le serveur en tant qu'utilisateur non root, celui-ci ne pourra pas adopter le groupe spécifié comme groupe d'exécution, et continuera à s'exécuter sous le groupe de l'utilisateur qui l'aura lancé. groupe unix peut se présenter sous la forme :

d'un nom de groupe
Référence le groupe spécifié par son nom.
du caractère # suivi d'un numéro de groupe.
Référence le groupe spécifié par son numéro.

Exemple

Group www-group

Il est conseillé de créer un groupe dédié à l'exécution du serveur. Certains administrateurs utilisent l'utilisateur nobody, mais ce n'est pas toujours souhaitable ou même possible.

Sécurité

Ne définissez pas la directive Group (ou User) à root à moins de savoir exactement ce que vous faites ainsi que les dangers encourus.

Voir aussi

top

Directive Suexec

Description:Active ou désactive la fonctionnalité suEXEC
Syntaxe:Suexec On|Off
Défaut:On si le binaire suexec existe avec les mode et propriétaire appropriés, Off dans le cas contraire
Contexte:configuration globale
Statut:Base
Module:mod_unixd

Lorsque cette directive est définie à On, le démarrage échouera si le binaire suexec n'existe pas, ou possède un propriétaire ou mode fichier invalide.

Lorsque cette directive est définie à Off, suEXEC sera désactivé, même si le binaire suexec existe et possède un propriétaire et mode fichier valides.

top

Directive User

Description:L'utilisateur sous lequel le serveur va traiter les requêtes
Syntaxe:User utilisateur unix
Défaut:User #-1
Contexte:configuration globale
Statut:Base
Module:mod_unixd

La directive User permet de définir l'utilisateur sous lequel le serveur va traiter les requêtes. Pour utiliser cette directive, le serveur doit avoir été démarré par root. Si vous démarrez le serveur en tant qu'utilisateur non root, celui-ci ne pourra pas adopter l'utilisateur avec privilèges restreints comme utilisateur d'exécution, et continuera à s'exécuter sous l'utilisateur qui l'aura lancé. Si vous démarrez le serveur en tant que root, il est normal que le processus parent continue à s'exécuter sous root. utilisateur unix peut se présenter sous la forme :

d'un nom d'utilisateur
Référence l'utilisateur spécifié par son nom.
le caractère # suivi d'un numéro d'utilisateur.
Référence l'utilisateur spécifié par son numéro.

L'utilisateur ne doit pas posséder de privilèges qui lui permettraient d'accéder à des fichiers non destinés au monde extérieur, et parallèlement, l'utilisateur ne doit pas exécuter de code dont l'usage soit destiné à un usage autre que les requêtes HTTP. Il est conseillé de créer un utilisateur et un groupe dédiés à l'exécution du serveur. Certains administrateurs utilisent l'utilisateur nobody, mais ce n'est pas toujours souhaitable, car l'utilisateur nobody peut avoir diverses utilisations dans le système.

Sécurité

Ne définissez pas la directive Group (ou User) à root à moins de savoir exactement ce que vous faites ainsi que les dangers encourus.

Voir aussi

Langues Disponibles:  en  |  fr  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_version.html.fr.utf80000664000175100017510000002572114740503670022330 0ustar covenercovener mod_version - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_version

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Configuration dépendant de la version
Statut:Extension
Identificateur de Module:version_module
Fichier Source:mod_version.c

Sommaire

Ce module a été conçu pour être utilisé dans les suites de tests et les grands réseaux qui doivent prendre en compte différentes versions de httpd et différentes configurations. Il fournit un nouveau conteneur -- <IfVersion>, qui apporte une grande souplesse dans la vérification de version en permettant une comparaison numérique et l'utilisation d'expressions rationnelles.

Exemples

<IfVersion 2.4.2>
    # la version actuelle de httpd est exactement 2.4.2
</IfVersion>

<IfVersion >= 2.5>
    # utilise vraiment les nouvelles fonctionnalités :-)
</IfVersion>

Voir ci-dessous pour d'autres exemples.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive <IfVersion>

Description:Contient des portions de configuration dépendantes de la version
Syntaxe:<IfVersion [[!]opérateur] version> ... </IfVersion>
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:All
Statut:Extension
Module:mod_version

La section <IfVersion> rassemble des directives de configuration qui ne sont exécutées que si la version de httpd satisfait aux critères spécifiés. Pour une comparaison normale (numérique), l'argument version doit être spécifié sous le format majeur[.mineur[.patch]], comme par exemple 2.1.0 ou 2.2. mineur et patch sont optionnels. Si ces numéros sont absents, il se voient affectée implicitement la valeur 0. Les opérateurs numériques suivants sont autorisés :

opérateurdescription
= ou == La version de httpd est égale à la valeur spécifiée
> La version de httpd est supérieure à la valeur spécifiée
>= La version de httpd est supérieure ou égale à la valeur spécifiée
< La version de httpd est inférieure à la valeur spécifiée
<= La version de httpd est inférieure ou égale à la valeur spécifiée

Exemple

<IfVersion >= 2.3>
    # la condition n'est satisfaite que pour les versions de httpd
	# supérieures ou égales à 2.3
</IfVersion>

En plus d'une comparaison numérique, il est possible de comparer la version de httpd avec une expression rationnelle. Il existe deux méthodes pour spécifier cette dernière :

opérateurdescription
= ou == version est de la forme /regex/
~ version est de la forme regex

Exemple

<IfVersion = /^2.4.[01234]$/>
    # exemple de contournement pour les versions boguées
</IfVersion>

Pour inverser la condition, tous les opérateurs peuvent être préfixés par un point d'exclamation (!) :

<IfVersion !~ ^2.4.[01234]$>
    # pas pour ces versions
</IfVersion>

Si opérateur est absent, sa valeur implicite est =.

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_xml2enc.html.fr.utf80000664000175100017510000004143614740503670022214 0ustar covenercovener mod_xml2enc - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_xml2enc

Langues Disponibles:  en  |  fr 

Description:Support avancé de l'internationalisation et des jeux de caractères pour les modules de filtrage basés sur libxml2
Statut:Base
Identificateur de Module:xml2enc_module
Fichier Source:mod_xml2enc.c
Compatibilité:Disponible depuis la version 2.4 du serveur HTTP Apache. Disponible en tant que module tiers dans les versions 2.2.x

Sommaire

Ce module fournit un support avancé de l'internationalisation pour les modules de filtrage supportant les balises (markup-aware) comme mod_proxy_html. Il est capable de détecter automatiquement l'encodage des données en entrée et de s'assurer qu'elle sont traitées correctement par l'interpréteur libxml2, y compris la conversion en Unicode (UTF-8) si nécessaire. Il peut aussi convertir les données dans l'encodage de votre choix après le traitement des balises, et s'assurera que le jeu de caractères approprié sera défini dans l'en-tête HTTP Content-Type.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Utilisation

Il existe deux scénarios d'utilisation : le cas des modules programmés pour travailler avec mod_xml2enc ; et les autres :

Modules de filtrages programmés pour mod_xml2enc

Les modules comme mod_proxy_html versions 3.1 et supérieures utilisent la fonction optionnelle xml2enc_charset pour déterminer la valeur de l'argument "jeu de caractères" à transmettre à l'interpréteur libxml2, et disposent de la fonction optionnelle xml2enc_filter pour effectuer un encodage ultérieur éventuel. L'utilisation de mod_xml2enc avec un module préprogrammé à cet effet ne nécessite aucune configuration : ce dernier configurera mod_xml2enc pour vous (sachant que vous pouvez tout de même le personnaliser via les directives de configuration ci-dessous).

Modules de filtrages non programmés pour mod_xml2enc

Pour utiliser mod_xml2enc avec un module basé sur libxml2 qui n'a pas été explicitement programmé pour mod_xml2enc, vous devrez configurer la chaîne de filtrage vous-même. Ainsi, pour utiliser mod_xml2enc avec un filtre foo fourni par un module mod_foo et pour améliorer le support i18n de ce dernier avec HTML et XML, vous pouvez utiliser les directives suivantes :


    FilterProvider iconv    xml2enc Content-Type $text/html
    FilterProvider iconv    xml2enc Content-Type $xml
    FilterProvider markup   foo Content-Type $text/html
    FilterProvider markup   foo Content-Type $xml
    FilterChain     iconv markup
    

mod_foo supportera alors tout jeu de caractère supporté soit par libxml2, soit par apr_xlate/iconv, soit par les deux.

top

API de programmation

Les programmeurs de modules de filtrage basés sur libxml2 sont encouragés à les préprogrammer pour mod_xml2enc, afin de fournir un support i18n solide aux utilisateurs sans avoir à réinventer la roue. L'API de programmation est décrite dans mod_xml2enc.h, et mod_proxy_html est un exemple de son utilisation.

top

Détection et encodage

A la différence de mod_charset_lite, mod_xml2enc est conçu pour travailler avec des données dont l'encodage ne peut pas être connu, et donc configuré, à l'avance. Il utilise donc les techniques de 'reniflage' suivantes pour détecter le type d'encodage des données HTTP :

  1. Si l'en-tête HTTP Content-Type contient un paramètre charset, c'est ce dernier qui sera utilisé.
  2. Si les données commancent par une balise XML concernant l'ordre des octets (BOM) ou par une déclaration d'encodage XML, c'est celle-ci qui sera utilisée.
  3. Si un type d'encodage est déclaré dans un élément HTML <META>, c'est ce dernier qui sera utilisé.
  4. Si aucun des éléments précédents n'est trouvé, c'est la valeur par défaut définie par la directive xml2EncDefault qui sera utilisée.

Les conditions sont testées dans cet ordre . Dès qu'une règle s'applique, elle est utilisée et la détection est terminée.

top

Codage en sortie

libxml2 utilise toujours UTF-8 (Unicode) en interne, et les modules de filtrage basés sur libxml2 utiliseront cet encodage en sortie par défaut. mod_xml2enc peut modifier l'encodage en sortie via l'API, mais il n'y a actuellement aucun moyen de le configurer directement.

La modification de l'encodage en sortie ne devrait (du moins en théorie) jamais être nécessaire, et est même déconseillée à cause de la charge de traitement supplémentaire imposée au serveur par une conversion non nécessaire.

top

Codages non supportés

Si vous travaillez avec des encodages non supportés par aucune des méthodes de conversion disponibles sur votre plateforme, vous pouvez tout de même leur associer un alias vers un code supporté via la directive xml2EncAlias.

top

Directive xml2EncAlias

Description:Définit des alias pour les valeurs d'encodage
Syntaxe:xml2EncAlias jeu-de-caractères alias [alias ...]
Contexte:configuration globale
Statut:Base
Module:mod_xml2enc

Cette directive de niveau serveur permet de définir un ou plusieurs alias pour un encodage. Elle permet au support d'encodage de libxml2 de traiter en interne des encodages non reconnus par libxml2 en utilisant la table de conversion pour un encodage reconnu. Elle permet d'atteindre deux objectifs : supporter des jeux (ou noms) de caractères non reconnus par libxml2 ou iconv, et éviter une conversion pour un encodage lorsque cela n'est pas nécessaire.

top

Directive xml2EncDefault

Description:Définit un encodage par défaut à utiliser lorsqu'aucune information ne peut être automatiquement détectée
Syntaxe:xml2EncDefault nom
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Base
Module:mod_xml2enc

Si vous traitez des données dont l'encodage est connu, mais ne contenant aucune information à propos de ce dernier, vous pouvez définir une valeur par défaut afin d'aider mod_xml2enc à traiter correctement les données. Par exemple, pour définir la valeur par défaut Latin1 (iso-8859-1) specifiée dans HTTP/1.0, utilisez :

xml2EncDefault iso-8859-1
top

Directive xml2StartParse

Description:Indique à l'interpréteur à partir de quelle balise il doit commencer son traitement.
Syntaxe:xml2StartParse élément [élément ...]
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Base
Module:mod_xml2enc

Cette directive permet de spécifier à partir de quelle balise, parmi les éléments spécifiés, l'interpréteur de balise doit commencer son traitement. Ccei permet de contourner le problème des serveurs d'arrière-plan qui insèrent des éléments non conformes en début de données, ce qui a pour effet de perturber l'interpréteur (voir un exemple ici).

Elle ne doit être utilisée ni pour les documents XML, ni pour les documents HTML correctement formatés.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session.html.fr.utf80000664000175100017510000011406114740503670022322 0ustar covenercovener mod_session - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_session

Langues Disponibles:  en  |  fr 

Description:Support des sessions
Statut:Extension
Identificateur de Module:session_module
Fichier Source:mod_session.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

Avertissement

Le module session fait usage des cookies HTTP, et peut à ce titre être victime d'attaques de type Cross Site Scripting, ou divulguer des informations à caractère privé aux clients. Veuillez vous assurer que les risques ainsi encourus ont été pris en compte avant d'activer le support des sessions sur votre serveur.

Ce module fournit le support d'une interface de session pour chaque utilisateur au niveau du serveur global. Les sessions permettent de transmettre diverses informations : l'utilisateur est-il connecté ou non, ou toute autre information qui doit être conservée d'une requête à l'autre.

Les sessions peuvent être stockées sur le serveur, ou au niveau du navigateur. Les sessions peuvent également être chiffrées pour une sécurité accrue. Ces fonctionnalités sont réparties entre différents modules complémentaires de mod_session : mod_session_crypto, mod_session_cookie et mod_session_dbd. Chargez les modules appropriés en fonction des besoins du serveur (soit statiquement à la compilation, soit dynamiquement via la directive LoadModule).

Les sessions peuvent être manipulées par d'autres modules qui dépendent de la session, ou la session peut être lue et écrite dans des variables d'environnement et des en-têtes HTTP, selon les besoins.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Qu'est-ce qu'une session ?

Au coeur de l'interface de session se trouve une table de paires clé/valeur qui sont accessibles d'une requête du navigateur à l'autre. Les valeurs de clés peuvent se voir affecter toute chaîne de caractères valide, en fonction des besoins de l'application qui fait usage de la session.

Une "session" est une chaîne application/x-www-form-urlencoded qui contient la paire clé/valeur définie par la spécification HTML.

Selon les souhaits de l'administrateur, la session peut être chiffrée et codée en base64 avant d'être soumise au dispositif de stockage.

top

Qui peut utiliser une session ?

L'interface de session a été conçue à l'origine pour être utilisée par d'autres modules du serveur comme mod_auth_form ; les applications à base de programmes CGI peuvent cependant se voir accorder l'accès au contenu d'une session via la variable d'environnement HTTP_SESSION. Il est possible de modifier et/ou de mettre à jour une session en insérant un en-tête de réponse HTTP contenant les nouveaux paramètres de session.

top

Stockage des sessions sur le serveur

Apache peut être configuré pour stocker les sessions utilisateurs sur un serveur particulier ou un groupe de serveurs. Cette fonctionnalité est similaire aux sessions disponibles sur les serveurs d'applications courants.

Selon la configuration, les sessions sont suivies à partir d'un identifiant de session stocké dans un cookie, ou extraites de la chaîne de paramètres de l'URL, comme dans les requêtes GET courantes.

Comme le contenu de la session est stocké exclusivement sur le serveur, il est nécessaire de préserver la confidentialité de ce contenu. Ceci a des implications en matière de performance et de consommation de ressources lorsqu'un grand nombre de sessions est stocké, ou lorsqu'un grand nombre de serveurs doivent se partager les sessions entre eux.

Le module mod_session_dbd permet de stocker les sessions utilisateurs dans une base de données SQL via le module mod_dbd.

top

Stockage des sessions au niveau du navigateur

Dans les environnements à haut trafic où le stockage d'une session sur un serveur consomme trop de ressources, il est possible de stocker le contenu de la session dans un cookie au niveau du navigateur client.

Ceci a pour avantage de ne nécessiter qu'une quantité minimale de ressources sur le serveur pour suivre les sessions, et évite à plusieurs serveurs parmi une forêt de serveurs de devoir partager les informations de session.

Le contenu de la session est cependant présenté au client, avec pour conséquence un risque de perte de confidentialité. Le module mod_session_crypto peut être configuré pour chiffrer le contenu de la session avant qu'elle soit stockée au niveau du client.

Le module mod_session_cookie permet de stocker les sessions au niveau du navigateur dans un cookie HTTP.

top

Exemples simples

La création d'une session consiste simplement à ouvrir la session, et à décider de l'endroit où elle doit être stockée. Dans l'exemple suivant, la session sera stockée au niveau du navigateur, dans un cookie nommé session.

Session stockée au niveau du navigateur

Session On
SessionCookieName session path=/

Une session est inutile s'il n'est pas possible d'y lire ou d'y écrire. L'exemple suivant montre comment des valeurs peuvent être injectées dans une session à l'aide d'un en-tête de réponse HTTP prédéterminé nommé X-Replace-Session.

Ecriture dans une session

Session On
SessionCookieName session path=/
SessionHeader X-Replace-Session

L'en-tête doit contenir des paires clé/valeur sous le même format que celui de la chaîne d'argument d'une URL, comme dans l'exemple suivant. Donner pour valeur à une clé la chaîne vide a pour effet de supprimer la clé de la session.

Script CGI pour écrire dans une session

#!/bin/bash
echo "Content-Type: text/plain"
echo "X-Replace-Session: key1=foo&key2=&key3=bar"
echo
env

Selon la configuration, les informations de la session peuvent être extraites de la variable d'environnement HTTP_SESSION. Par défaut la session est privée, et cette fonctionnalité doit donc être explicitement activée via la directive SessionEnv.

Lecture depuis une session

Session On
SessionEnv On
SessionCookieName session path=/
SessionHeader X-Replace-Session

Une fois la lecture effectuée, la variable CGI HTTP_SESSION doit contenir la valeur clé1=foo&clé3=bar.

top

Confidentialité des sessions

En utilisant la fonctionnalité de votre navigateur "Afficher les cookies", vous pouvez voir une réprésentation de la session sous forme de texte en clair. Ceci peut poser problème si le contenu de la session doit être dissimulé à l'utilisateur final, ou si un tiers accède sans autorisation aux informations de session.

À ce titre, le contenu de la session peut être chiffré à l'aide du module mod_session_crypto avant d'être stocké au niveau du navigateur.

Session chiffrée avant stockage au niveau du navigateur

Session On
SessionCryptoPassphrase secret
SessionCookieName session path=/

La session sera automatiquement déchiffrée à la lecture, et rechiffrée par Apache lors de la sauvegarde, si bien que l'application sous-jacente qui utilise la session n'a pas à se préoccuper de savoir si un chiffrement a été mis en oeuvre ou non.

Les sessions stockées sur le serveur plutôt qu'au niveau du navigateur peuvent aussi être chiffrées, préservant par là-même la confidentialité lorsque des informations sensibles sont partagées entre les serveurs web d'une forêt de serveurs à l'aide du module mod_session_dbd.

top

Confidentialité du cookie

Le mécanisme de cookie HTTP offre aussi des fonctionnalités quant à la confidentialité, comme la possibilité de restreindre le transport du cookie aux pages protégées par SSL seulement, ou l'interdiction pour les scripts java qui s'exécutent au niveau du navigateur d'obtenir l'accès au contenu du cookie.

Avertissement

Certaines fonctionnalités de confidentialité du cookie HTTP ne sont pas standardisées, ou ne sont pas toujours implémentées au niveau du navigateur. Les modules de session vous permettent de définir les paramètres du cookie, mais il n'est pas garanti que la confidentialité sera respectée par le navigateur. Si la sécurité est la principale préoccupation, chiffrez le contenu de la session avec le module mod_session_crypto, ou stockez la session sur le serveur avec le module mod_session_dbd.

Les paramètres standards du cookie peuvent être spécifiés après le nom du cookie comme dans l'exemple suivant :

Définition des paramètres du cookie

Session On
SessionCryptoPassphrase secret
SessionCookieName session path=/private;domain=example.com;httponly;secure;

Dans les cas où le serveur Apache sert de frontal pour des serveurs d'arrière-plan, il est possible de supprimer les cookies de session des en-têtes HTTP entrants à l'aide de la directive SessionCookieRemove. Ceci permet d'empêcher les serveurs d'arrière-plan d'accéder au contenu des cookies de session.

top

Support des sessions pour l'authentification

Comme il est possible de le faire avec de nombreux serveurs d'applications, les modules d'authentification peuvent utiliser une session pour stocker le nom d'utilisateur et le mot de passe après connexion. Le module mod_auth_form par exemple, sauvegarde les nom de connexion et mot de passe de l'utilisateur dans une session.

Authentification à base de formulaire

Session On
SessionCryptoPassphrase secret
SessionCookieName session path=/
AuthFormProvider file
AuthUserFile "conf/passwd"
AuthType form
AuthName "realm"
#...

Pour la documentation et des exemples complets, voir le module mod_auth_form.

top

Intégration des sessions avec les applications externes

Pour que les sessions soient utiles, leur contenu doit être accessible aux applications externes, et ces dernières doivent elles-mêmes être capables d'écrire une session.

L'exemple type est une application qui modifie le mot de passe d'un utilisateur défini par mod_auth_form. Cette application doit pouvoir extraire les nom d'utilisateur et mot de passe courants de la session, effectuer les modifications demandées, puis écrire le nouveau mot de passe dans la session, afin que la transition vers le nouveau mot de passe soit transparente.

Un autre exemple met en jeu une application qui enregistre un nouvel utilisateur pour la première fois. Une fois l'enregistrement terminé, le nom d'utilisateur et le mot de passe sont écrits dans la session, fournissant là aussi une transition transparente.

Modules Apache
Selon les besoins, les modules du serveur peuvent utiliser l'API mod_session.h pour lire et écrire dans les sessions. Les modules tels que mod_auth_form utilisent ce mécanisme.
Programmes CGI et langages de script
Les applications qui s'exécutent au sein du serveur web peuvent éventuellement extraire la valeur de la session de la variable d'environnement HTTP_SESSION. La session doit être codée sous la forme d'une chaîne application/x-www-form-urlencoded selon les préconisations de la specification HTML. Cette variable d'environnement est définie via la directive SessionEnv. Un script peut écrire dans la session en renvoyant un en-tête de réponse application/x-www-form-urlencoded dont le nom est défini via la directive SessionHeader. Dans les deux cas, tout chiffrement ou déchiffrement, ainsi que la lecture ou l'écriture de ou vers la session à partir du mécanisme de stockage choisi sont gérés par le module mod_session et la configuration correspondante.
Applications situées derrière mod_proxy
Si la directive SessionHeader est utilisée pour définir un en-tête de requête HTTP, la session codée sous la forme d'une chaîne application/x-www-form-urlencoded sera accessible pour l'application. Si ce même en-tête est fourni dans la réponse, sa valeur sera utilisée pour remplacer la session. Comme précédemment, tout chiffrement ou déchiffrement, ainsi que la lecture ou l'écriture de ou vers la session à partir du mécanisme de stockage choisi sont gérés par le module mod_session et la configuration correspondante.
Applications indépendantes
Les applications peuvent choisir de manipuler la session en s'affranchissant du contrôle du serveur HTTP Apache. Dans ce cas, c'est l'application qui doit prendre en charge la lecture de la session depuis le mécanisme de stockage choisi, son déchiffrement, sa mise à jour, son chiffrement et sa réécriture vers le mécanisme de stockage choisi de manière appropriée.
top

Directive Session

Description:Ouvre une session pour le contexte courant
Syntaxe:Session On|Off
Défaut:Session Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_session

La directive Session permet d'ouvrir une session pour le contexte ou conteneur courant. Les directives suivantes permettent de définir où la session sera stockée et comment sera assurée la confidentialité.

top

Directive SessionEnv

Description:Définit si le contenu de la session doit être enregistré dans la variable d'environnement HTTP_SESSION
Syntaxe:SessionEnv On|Off
Défaut:SessionEnv Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_session

Lorsque la directive SessionEnv est définie à On, le contenu de la session est enregistré dans une variable d'environnement CGI nommée HTTP_SESSION.

La chaîne est écrite sous le même format que celui de la chaîne d'arguments d'une URL, comme dans l'exemple suivant :

clé1=foo&clé3=bar

top

Directive SessionExclude

Description:Définit les préfixes d'URLs pour lesquels une session sera ignorée
Syntaxe:SessionExclude chemin
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session

La directive SessionExclude permet de définir les préfixes d'URLs pour lesquels la session sera désactivée. Ceci peut améliorer l'efficacité d'un site web, en ciblant de manière plus précise l'espace d'URL pour lequel une session devra être maintenue. Par défaut, toutes les URLs du contexte ou du conteneur courant sont incluses dans la session. La directive SessionExclude l'emporte sur la directive SessionInclude.

Avertissement

Cette directive a un comportement similaire à celui de l'attribut chemin des cookies HTTP, mais ne doit pas être confondue avec cet attribut. En effet, cette directive ne définit pas l'attribut chemin, qui doit être configuré séparément.

top

Directive SessionExpiryUpdateInterval

Description:Définit le nombre de secondes dont la durée d'expiration d'une session peut changer sans que cette session soit mise à jour
Syntaxe:SessionExpiryUpdateInterval interval
Défaut:SessionExpiryUpdateInterval 0 (mise à jour systématique)
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session
Compatibilité:Disponible à partir de la version 2.4.41 du serveur HTTP Apache

La directive SessionExpiryUpdateInterval permet d'éviter le coût de l'écriture d'une session pour chaque requête en n'effectuant cette mise à jour que lorsque la date d'expiration a changé. Ceci permet d'améliorer les performances d'un site web ou de réduire la charge d'une base de données lorsqu'on utilise mod_session_dbd. La session est systématiquement mise à jour si les données stockées dans la session ont été modifiées ou si la durée d'expiration a été modifiée d'une durée supérieure à l'intervalle spécifié.

Définir l'intervalle à 0 désactive cette directive, et l'expiration de la session sera alors rafraîchie pour chaque requête.

Cette directive n'a d'effet que si on l'utilise en combinaison avec la directive SessionMaxAge qui active l'expiration des sessions. Les sessions sans date d'expiration ne sont écrites que lorsque les données qu'elles renferment ont été modifiées.

Avertissement

Comme l'expiration de la session n'est pas systématiquement rafraîchie à chaque requête, une session peut arriver à expiration plus tôt d'un nombre de secondes spécifié dans le paramètre interval. Définir un petit intervalle est en général assez sur, mais en revenche n'a qu'un effet minime sur la prise en compte des durées d'expiration.

top

Directive SessionHeader

Description:Importation des mises à jour de session depuis l'en-tête de réponse HTTP spécifié
Syntaxe:SessionHeader en-tête
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_session

La directive SessionHeader permet de définir le nom d'un en-tête de réponse HTTP qui, s'il est présent, sera lu et son contenu écrit dans la session courante.

Le contenu de l'en-tête doit se présenter sous le même format que celui de la chaîne d'arguments d'une URL, comme dans l'exemple suivant :

clé1=foo&clé2=&clé3=bar

Si une clé a pour valeur la chaîne vide, elle sera supprimée de la session.

top

Directive SessionInclude

Description:Définit les préfixes d'URL pour lesquels une session est valide
Syntaxe:SessionInclude chemin
Défaut:toutes URLs
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_session

La directive SessionInclude permet de définir les préfixes d'URL spécifiques pour lesquels une session sera valide. Ceci peut améliorer l'efficacité d'un site web, en ciblant de manière plus précise l'espace d'URL pour lequel une session devra être maintenue. Par défaut, toutes les URLs du contexte ou du conteneur courant sont incluses dans la session.

Avertissement

Cette directive a un comportement similaire à celui de l'attribut chemin des cookies HTTP, mais ne doit pas être confondue avec cet attribut. En effet, cette directive ne définit pas l'attribut chemin, qui doit être configuré séparément.

top

Directive SessionMaxAge

Description:Définit une durée de vie maximale pour la session en secondes
Syntaxe:SessionMaxAge durée de vie maximale
Défaut:SessionMaxAge 0
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:AuthConfig
Statut:Extension
Module:mod_session

La directive SessionMaxAge permet de définir la durée maximale pendant laquelle une session restera valide. Lorsqu'une session est sauvegardée, cette durée est réinitialisée et la session peut continuer d'exister. Si la durée d'une session dépasse cette limite sans qu'une requête au serveur ne vienne la rafraîchir, la session va passer hors délai et sera supprimée. Lorsqu'une session est utilisée pour stocker les informations de connexion d'un utilisateur, ceci aura pour effet de le déconnecter automatiquement après le délai spécifié.

Donner à cette directive la valeur 0 empêche l'expiration de la session.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session_dbd.html.fr.utf80000664000175100017510000006572314740503670023145 0ustar covenercovener mod_session_dbd - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_session_dbd

Langues Disponibles:  en  |  fr 

Description:Support des session basé sur DBD/SQL
Statut:Extension
Identificateur de Module:session_dbd_module
Fichier Source:mod_session_dbd.c
Compatibilité:Disponible depuis la version 2.3 d'Apache

Sommaire

Avertissement

Les modules de session font usage des cookies HTTP, et peuvent à ce titre être victimes d'attaques de type Cross Site Scripting, ou divulguer des informations à caractère privé aux clients. Veuillez vous assurer que les risques ainsi encourus ont été pris en compte avant d'activer le support des sessions sur votre serveur.

Ce sous-module du module mod_session fournit le support du stockage des sessions utilisateur dans une base de données SQL en utilisant le module mod_dbd.

Les sessions sont soit anonymes, et la session est alors identifiée par un UUID unique stocké dans un cookie au niveau du navigateur, soit propres à l'utilisateur, et la session est alors identifiée par l'identifiant de l'utilisateur connecté.

Les sessions basées sur SQL sont dissimulées au navigateur, et permettent ainsi de préserver la confidentialité sans avoir recours au chiffrement.

Plusieurs serveurs web d'une forêt de serveurs peuvent choisir de partager une base de données, et ainsi partager les sessions entre eux.

Pour plus de détails à propos de l'interface des sessions, voir la documentation du module mod_session.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Configuration de DBD

Pour que le module mod_session_dbd puisse être configuré et maintenir une session, il faut tout d'abord configurer le module mod_dbd pour que le serveur puisse exécuter des requêtes vers la base de données.

Quatre types de requêtes sont nécessaires pour maintenir une session, sélectionner ou mettre à jour une session existante, insérer une nouvelle session et supprimer une session vide ou arrivée à expiration. Ces requêtes sont configurées comme dans l'exemple suivant :

Exemple de configuration de DBD

DBDriver pgsql
DBDParams "dbname=apachesession user=apache password=xxxxx host=localhost"
DBDPrepareSQL "delete from session where key = %s" deletesession
DBDPrepareSQL "update session set value = %s, expiry = %lld, key = %s where key = %s" updatesession
DBDPrepareSQL "insert into session (value, expiry, key) values (%s, %lld, %s)" insertsession
DBDPrepareSQL "select value from session where key = %s and (expiry = 0 or expiry > %lld)" selectsession
DBDPrepareSQL "delete from session where expiry != 0 and expiry < %lld" cleansession
top

Sessions anonymes

Les sessions anonymes sont identifiées par un UUID unique, et stockées dans un cookie au niveau du navigateur. Cette méthode est similaire à celle utilisée par la plupart des serveurs d'applications pour stocker les informations de session.

Pour créer une session anonyme, la stocker dans une table de base de donnée postgres nommée apachesession, et sauvegarder l'identifiant de session dans un cookie nommé session, configurez la session comme suit :

Session anonyme basée sur SQL

Session On
SessionDBDCookieName session path=/

Pour plus d'exemples sur la manière dont une application CGI peut accéder aux informations de session, voir la section exemples de la documentation du module mod_session.

Pour des détails sur la manière dont une session peut être utilisée pour stocker des informations de type nom d'utilisateur/mot de passe, voir la documentation du module mod_auth_form.

top

Sessions propres à un utilisateur

Les sessions propres à un utilisateur sont identifiées par le nom de l'utilisateur authentifié avec succès. Ceci permet d'assurer une confidentialité optimale, car aucun traitement externe à la session n'existe en dehors du contexte authentifié.

Les sessions propres à un utilisateur ne fonctionnent que dans un environnement d'authentification correctement configuré, qu'il s'agisse d'une authentification de base, à base de condensés (digest) ou de certificats client SSL. Suite à des limitations dues à des dépendances mutuelles, les sessions propres à un utilisateur ne peuvent pas être utilisées pour stocker les données d'authentification en provenance d'un module comme mod_auth_form.

Pour créer une session propre à un utilisateur, la stocker dans une table de base de données postgres nommée apachesession, avec comme clé de session l'identifiant utilisateur, ajoutez les lignes suivantes :

Session propre à un utilisateur basée sur SQL

Session On
SessionDBDPerUser On
top

Nettoyage de la base de données

Avec le temps, la base de données va commencer à accumuler des sessions expirées. Pour le moment, le module mod_session_dbd n'est pas en mesure de gérer automatiquement l'expiration des sessions.

Avertissement

L'administrateur devra mettre en oeuvre un traitement externe via cron pour nettoyer les sessions expirées.

top

Directive SessionDBDCookieName

Description:Nom et attributs du cookie RFC2109 qui contient l'identifiant de session
Syntaxe:SessionDBDCookieName nom attributs
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDCookieName permet de spécifier le nom et les attributs optionnels d'un cookie compatible RFC2109 qui contiendra l'identifiant de session. Les cookies RFC2109 sont définis à l'aide de l'en-tête HTTP Set-Cookie.

Une liste optionnelle d'attributs peut être spécifiée pour ce cookie, comme dans l'exemple ci-dessous. Ces attributs sont insérés dans le cookie tels quels, et ne sont pas interprétés par Apache. Assurez-vous que vos attributs sont définis correctement selon la spécification des cookies.

Cookie avec attributs

Session On
SessionDBDCookieName session path=/private;domain=example.com;httponly;secure;version=1;
top

Directive SessionDBDCookieName2

Description:Nom et attributs du cookie RFC2965 qui contient l'identifiant de session
Syntaxe:SessionDBDCookieName2 nom attributs
Défaut:none
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDCookieName2 permet de spécifier le nom et les attributs optionnels d'un cookie compatible RFC2965 qui contiendra l'identifiant de session. Les cookies RFC2965 sont définis à l'aide de l'en-tête HTTP Set-Cookie2.

Une liste optionnelle d'attributs peut être spécifiée pour ce cookie, comme dans l'exemple ci-dessous. Ces attributs sont insérés dans le cookie tel quel, et ne sont pas interprétés par Apache. Assurez-vous que vos attributs sont définis correctement selon la spécification des cookies.

Cookie2 avec attributs

Session On
SessionDBDCookieName2 session path=/private;domain=example.com;httponly;secure;version=1;
top

Directive SessionDBDCookieRemove

Description:Détermine si les cookies de session doivent être supprimés des en-têtes HTTP entrants
Syntaxe:SessionDBDCookieRemove On|Off
Défaut:SessionDBDCookieRemove On
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDCookieRemove permet de déterminer si les cookies contenant l'identifiant de session doivent être supprimés des en-têtes pendant le traitement de la requête.

Dans le cas d'un mandataire inverse où le serveur Apache sert de frontal à un serveur d'arrière-plan, révéler le contenu du cookie de session à ce dernier peut conduire à une violation de la confidentialité. À ce titre, si cette directive est définie à "on", le cookie de session sera supprimé des en-têtes HTTP entrants.

top

Directive SessionDBDDeleteLabel

Description:La requête SQL à utiliser pour supprimer des sessions de la base de données
Syntaxe:SessionDBDDeleteLabel étiquette
Défaut:SessionDBDDeleteLabel deletesession
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDDeleteLabel permet de définir l'étiquette de la requête de suppression à utiliser par défaut pour supprimer une session vide ou expirée. Cette étiquette doit avoir été définie au préalable via une directive DBDPrepareSQL.

top

Directive SessionDBDInsertLabel

Description:La requête SQL à utiliser pour insérer des sessions dans la base de données
Syntaxe:SessionDBDInsertLabel étiquette
Défaut:SessionDBDInsertLabel insertsession
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDInsertLabel permet de définir l'étiquette de la requête d'insertion par défaut à charger dans une session. Cette étiquette doit avoir été définie au préalable via une directive DBDPrepareSQL.

Si une tentative de mise à jour d'une session ne concerne aucun enregistrement, c'est cette requête qui sera utilisée pour insérer la session dans la base de données.

top

Directive SessionDBDPerUser

Description:Active une session propre à un utilisateur
Syntaxe:SessionDBDPerUser On|Off
Défaut:SessionDBDPerUser Off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDPerUser permet d'activer une session propre à un utilisateur, dont la clé sera le nom de l'utilisateur connecté. Si l'utilisateur n'est pas connecté, la directive sera ignorée.

top

Directive SessionDBDSelectLabel

Description:La requête SQL à utiliser pour sélectionner des sessions dans la base de données
Syntaxe:SessionDBDSelectLabel étiquette
Défaut:SessionDBDSelectLabel selectsession
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDSelectLabel permet de définir l'étiquette de la requête de sélection par défaut à utiliser pour charger une session. Cette étiquette doit avoir été définie au préalable via une directive DBDPrepareSQL.

top

Directive SessionDBDUpdateLabel

Description:La requête SQL à utiliser pour mettre à jour des sessions préexistantes dans la base de données
Syntaxe:SessionDBDUpdateLabel étiquette
Défaut:SessionDBDUpdateLabel updatesession
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_session_dbd

La directive SessionDBDUpdateLabel permet de définir l'étiquette de la requête de mise à jour par défaut à charger dans une session. Cette étiquette doit avoir été définie au préalable via une directive DBDPrepareSQL.

Si une tentative de mise à jour d'une session ne concerne aucun enregistrement, c'est la requête d'insertion qui sera appelée pour insérer la session dans la base de données. Si la base de données supporte InsertOrUpdate, modifiez cette requête pour effectuer la mise à jour en une seule requête au lieu de deux.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_netware.html.fr.utf80000664000175100017510000002511714740503670022321 0ustar covenercovener mpm_netware - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Apache MPM netware

Langues Disponibles:  en  |  fr 

Description:Module multi-processus implémentant un serveur web basé exclusivement sur les threads et optimisé pour Novell NetWare
Statut:MPM
Identificateur de Module:mpm_netware_module
Fichier Source:mpm_netware.c

Sommaire

Ce module multi-processus (MPM) implémente un serveur web basé exclusivement sur les threads et optimisé pour Novell NetWare.

Le thread maître est chargé du lancement de threads esclaves qui attendent les connexions et les traitent au fur et à mesure de leur arrivée. Le serveur HTTP Apache essaie toujours de maintenir plusieurs threads esclaves en spare (en réserve) ou inactifs. De cette façon, les clients n'ont pas besoin d'attendre le lancement d'un nouveau thread enfant pour que leurs requêtes soient traitées.

Les directives StartThreads, MinSpareThreads, MaxSpareThreads, et MaxThreads contrôlent la manière dont le thread maître crée les threads esclaves afin de traiter les requêtes. En général, Apache httpd s'auto-régule correctement, et la plupart des sites ne nécessitent aucune modification des valeurs par défaut de ces directives. Pour les sites dont le serveur est limité en mémoire, il peut s'avérer nécessaire de diminuer la valeur de la directive MaxThreads afin d'éviter une hyper-activité du serveur (arrêts de threads inactifs et lancement incessant de nouveau threads). Vous trouverez plus d'informations à propos du contrôle de la création de processus dans le document conseils en matière de performances.

La directive MaxRequestsPerChild contrôle la fréquence à laquelle le serveur recycle ses processus en arrêtant les anciens et en en lançant de nouveaux. Sous le système d'exploitation NetWare, il est vivement recommandé de laisser cette directive à 0, ce qui permet aux threads esclaves de continuer à traiter les requêtes indéfiniment.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive MaxThreads

Description:Définit le nombre maximum de threads esclaves
Syntaxe:MaxThreads nombre
Défaut:MaxThreads 2048
Contexte:configuration globale
Statut:MPM
Module:mpm_netware

La directive MaxThreads définit le nombre maximum de threads esclaves que l'on désire autoriser. La valeur par défaut correspondant à la valeur codée en dur à la compilation, la valeur de cette directive ne peut donc qu'être diminuée, comme dans l'exemple suivant :

MaxThreads 512

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_dbm.html.fr.utf80000664000175100017510000001444414740503670023072 0ustar covenercovener mod_socache_dbm - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_socache_dbm

Langues Disponibles:  en  |  fr 

Description:Fournisseur de cache d'objets partagés basé sur DBM.
Statut:Extension
Identificateur de Module:socache_dbm_module
Fichier Source:mod_socache_dbm.c

Sommaire

Le module mod_socache_dbm est un fournisseur de cache d'objets partagés qui permet la création et l'accès à un cache maintenu par une base de données DBM.

dbm:/chemin/vers/datafile

Vous trouverez des détails à propos des autres fournisseurs de cache d'objets partagés ici.

Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_redis.html.fr.utf80000664000175100017510000002570614740503670023441 0ustar covenercovener mod_socache_redis - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_socache_redis

Langues Disponibles:  en  |  fr 

Description:Fournisseur de cache d'objets partagé basé sur Redis.
Statut:Extension
Identificateur de Module:socache_redis_module
Fichier Source:mod_socache_redis.c
Compatibilité:Disponible à partir de la version 2.4.39 du serveur HTTP Apache

Sommaire

mod_socache_redis implémente un fournisseur de cache d'objets partagé qui permet la création et l'accès à un cache hébergé par le système de mise en cache d'objets en mémoire partagée à hautes performances Redis.

La méthode "create" de ce fournisseur de cache d'objets partagé nécessite une liste en mémoire de spécifications hôte/port séparées par des virgules. Si vous utilisez ce fournisseur dans une directive de configuration d'un autre module comme SSLSessionCache, spécifiez la liste des serveurs sous la forme du paramètre optionnel "arg" :

SSLSessionCache redis:redis.example.com:12345,redis2.example.com:12345

Vous trouverez une description détaillée des autres fournisseurs de cache d'objets partagé ici.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive RedisConnPoolTTL

Description:Durée de vie du jeu de connexions avec le(s) serveur(s) Redis.
Syntaxe:RedisConnPoolTTL num[units]
Défaut:RedisConnPoolTTL 15s
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_socache_redis
Compatibilité:Disponible à partir de la version 2.4.39 du serveur HTTP Apache.

Cette directive permet de définir la durée pendant laquelle les connexions inactives avec le(s) serveur(s) Redis seront conservées (plateformes threadées seulement).

Les valeurs valides pour RedisConnPoolTTL sont des durées limitées à 1 heure . 0 signifie aucune limite.

Par défaut, l'unité de ces valeurs est la secondes, mais on peut spécifier via un suffixe des valeurs en millisecondes (ms), en secondes (s), en minutes (min) ou en heures (h).

# Définit une durée de vie de 10 minutes
RedisConnPoolTTL 10min
# Définit une durée de vie de 60 secondes
RedisConnPoolTTL 60
top

Directive RedisTimeout

Description:Durée maximale de lecture/écriture sur la connexion avec le(s) serveur(s) Redis.
Syntaxe:RedisTimeout num[units]
Défaut:RedisTimeout 5s
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_socache_redis
Compatibilité:Disponible à partir de la version 2.4.39 du serveur HTTP Apache.

Cette directive permet de définir la durée maximale de lecture/écriture sur la connexion avec le(s) serveur(s) Redis.

Les valeurs valides pour RedisTimeout sont des durées limitées à 1 heure . 0 signifie aucune limite.

Par défaut, l'unité de ces valeurs est la secondes, mais on peut spécifier via un suffixe des valeurs en millisecondes (ms), en secondes (s), en minutes (min) ou en heures (h).

# Définit une durée de 10 minutes
RedisTimeout 10min
# Définit une durée de 60 secondes
RedisTimeout 60

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_status.html.fr.utf80000664000175100017510000003151414740503670022163 0ustar covenercovener mod_status - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_status

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Fournit des informations sur les performances et l'activité du serveur
Statut:Base
Identificateur de Module:status_module
Fichier Source:mod_status.c

Sommaire

Le module Status permet à un administrateur de déterminer le niveau de performances de son serveur. Les statistiques instantanées du serveur sont présentées dans une page HTML sous une forme aisément lisible. Si nécessaire, cette page peut être configurée pour être automatiquement actualisée (sous réserve de compatibilité du navigateur). Une autre page fournit l'état instantané du serveur sous la forme d'une simple liste lisible par une machine.

Les détails fournis sont :

Les lignes se terminant par "(*)" ne sont disponibles que si la directive ExtendedStatus est définie à On. Depuis la version 2.3.6, le chargement de mod_status définit automatiquement ExtendedStatus à On.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Activation du rapport d'état

Pour n'activer les rapports d'état que pour les navigateurs appartenent au domaine example.com, ajoutez ces lignes à votre fichier de configuration httpd.conf :

<Location "/etat-serveur">
    SetHandler server-status
    Require host example.com
</Location>

Il est alors possible d'obtenir les statistiques du serveur en utilisant un navigateur web et en accédant à la page http://votre.serveur/etat-serveur.

top

Actualisation automatique

Vous pouvez faire en sorte que cette page d'état s'actualise elle-même automatiquement si votre navigateur supporte "refresh". Pour ce faire, accédez à la page http://votre.serveur/etat-serveur?refresh=N, pour que cette dernière soit actualisée toutes les N secondes.

top

Fichier d'état lisible par une machine

La page http://votre.serveur/etat-serveur?auto permet d'obtenir une version du fichier d'état lisible par une machine. Ceci s'avère intéressant dans le cadre d'une exécution automatique : voir le programme en Perl log_server_status situé dans le répertoire /support de votre distribution du serveur HTTP Apache.

Veuillez noter que si mod_status a été chargé dans le serveur, son gestionnaire sera disponible dans tous les fichiers de configuration, y compris les fichiers de configuration de niveau répertoire (par exemple .htaccess), ce qui peut avoir des répercutions quant à la sécurité de votre site.
top

Utilisation de server-status pour la recherche de défauts de fonctionnement

La page server-status peut servir de point de départ à la recherche de défauts de fonctionnement lorsque votre serveur mobilise toutes les ressources disponibles (CPU ou mémoire), pour identifier quels clients ou requêtes sont la cause du problème.

Tout d'abord, assurez-vous que la directive ExtendedStatus est bien définie à on, de façon à ce que vous puissiez avoir accès à toutes les informations à propos de la requête et du client pour chaque processus enfant ou thread.

Consultez ensuite la liste des processus en cours (à l'aide de top, ou d'un utilitaire de listage des processus similaire), afin d'identifier les processus coupables. Triez l'affichage de top par utilisation CPU ou mémoire, en fonction du problème rencontré.

Rechargez la page server-status et recherchez les identifiants des processus trouvés précédemment ; vous pourrez alors déterminer quelle requête est traitée par ces processus, pour quel client. Les requêtes peuvent apparaître de manière fugitive, et il se peut que vous deviez effectuer plusieurs essais avant de parvenir à les prendre en flagrant délit, pour ainsi dire.

Cette procédure devrait vous permettre de cerner quel client, ou type de requête, sont à l'origine de vos problèmes de charge. Il est probable que vous identifiiez une application web au comportement anormal, ou un client en train d'attaquer votre site.

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_systemd.html.fr.utf80000664000175100017510000002015714740503670022331 0ustar covenercovener mod_systemd - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_systemd

Langues Disponibles:  en  |  fr 

Description:Fournit un support amélioré pour l'intégration de systemd
Statut:Extension
Identificateur de Module:systemd_module
Fichier Source:mod_systemd.c

Sommaire

Ce module implémente le support de l'intégration de systemd. Il permet d'utiliser httpd en temps que service avec le paramètre de systemd Type=notify (voir la page de manuel systemd.service(5) pour plus de détails). Le module est activé s'il est chargé.

Exemple basique d'unité de service systemd (à étoffer pour un système en production)

[Unit]
Description=The Apache HTTP Server
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/apache2/bin/httpd -D FOREGROUND -k start
ExecReload=/usr/local/apache2/bin/httpd -k graceful
KillMode=mixed

[Install]
WantedBy=multi-user.target

Si vous utilisez ExecStop et/ou KillMode, vous devez prêter une attention particulière à leur configuration pour ce service. Si elle est présente, une commande ExecStop doit être une operation synchrone qui se termine elle-même en même temps que le démon. Cette condition n'est pas satisfaite si vous exécutez la commande httpd -k stop de manière asynchrone, car elle initie l'arrêt du démon. L'exemple ci-dessus utilise KillMode=mixed afin que systemd envoie SIGTERM au processus parent (et seulement à ce dernier) pour lui indiquer qu'il doit s'arrêter. Les processus encore en cours d'exécution après un temps égal à TimeoutStopSec recevront alors le signal SIGKILL. Voir systemd.kill(5) pour plus d'informations.

Ce module ne fournit pas le support de l'activation du socket Systemd.

ExtendedStatus est activé par défaut si le module est chargé. Si ExtendedStatus n'est pas explicitement désactivé dans le fichier de configuration, les statistiques à propos de la charge et des requêtes pendant l'exécution apparaîtront dans la sortie de la commande systemctl status.

Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_userdir.html.fr.utf80000664000175100017510000003332414740503670022316 0ustar covenercovener mod_userdir - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_userdir

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Description:Répertoires propres à un utilisateur
Statut:Base
Identificateur de Module:userdir_module
Fichier Source:mod_userdir.c

Sommaire

En activant ce module, vous permettez à plusieurs utilisateurs de stocker des contenus sous un seul noeud de l'arborescence. La politique de stockage sous un seul noeud de l'arborescence est un principe clé de Javascript et de la sécurité du web. En stockant des pages web sous un seul noeud de l'arborescence, celles-ci peuvent se lire et se contrôler mutuellement et d'éventuels problèmes de sécurité liés à une page peut affecter les autres. Ceci peut s'avérer particulièrement dangereux dans le cas des pages web mettant en oeuvre du contenu dynamique et de l'authentification et lorsque les utilisateurs ne se voient pas tous forcément d'un bon oeil.

Ce module permet l'accès aux répertoires propres à un utilisateur en utilisant la syntaxe http://example.com/~utilisateur/.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive UserDir

Description:Chemin des répertoires propres à un utilisateur
Syntaxe:UserDir nom-répertoire [nom-répertoire] ...
Contexte:configuration globale, serveur virtuel
Statut:Base
Module:mod_userdir

La directive UserDir permet de définir le répertoire réel du répertoire home d'un utilisateur à utiliser à la réception d'une requête pour un document de cet utilisateur. nom-répertoire peut se présenter sous la forme suivante :

Si aucun mot-clé enabled ou disabled n'apparait dans la directive Userdir, l'argument est traité en tant que modèle de fichier, et utilisé pour traduire le nom d'utilisateur en une spécification de répertoire. Une requête pour http://www.example.com/~bob/un/deux.html sera traduite en :

Directive Userdir utilisée Chemin traduit
UserDir public_html ~bob/public_html/un/deux.html
UserDir /usr/web /usr/web/bob/un/deux.html
UserDir /home/*/www /home/bob/www/un/deux.html

Les directives suivantes vont envoyer des redirections au client :

Directive Userdir utilisée Chemin traduit
UserDir http://www.example.com/utilisateurs http://www.example.com/utilisateurs/bob/un/deux.html
UserDir http://www.example.com/*/usr http://www.example.com/bob/usr/un/deux.html
UserDir http://www.example.com/~*/ http://www.example.com/~bob/un/deux.html
Soyez prudent avec cette directive ; par exemple, "UserDir ./" ferait correspondre "/~root" à "/" - ce qui n'est probablement pas souhaité. Il est fortement recommandé d'inclure une déclaration "UserDir disabled root" dans votre configuration. Voir aussi la directive Directory et la page Conseils en matière de sécurité pour plus d'informations.

Exemples supplémentaires :

Pour permettre à quelques utilisateurs et seulement à ceux-ci de posséder des répertoires UserDir, utilisez la configuration suivante :

UserDir disabled
UserDir enabled user1 user2 user3

Pour permettre à la plupart des utilisateurs de posséder des répertoires UserDir, mais l'interdire à quelques uns, utilisez la configuration suivante :

UserDir disabled utilisateur4 utilisateur5 utilisateur6

Il est aussi possible de spécifier des répertoires utilisateurs alternatifs. Si vous utilisez une commande comme :

UserDir "public_html" "/usr/web" "http://www.example.com/"

Avec une requête pour http://www.example.com/~bob/un/deux.html, le serveur tentera tout d'abord de trouver la page à ~bob/public_html/un/deux.html, puis à /usr/web/bob/un/deux.html, et enfin il enverra une redirection vers http://www.example.com/bob/un/deux.html.

Si vous spécifiez une redirection, elle doit être la dernière alternative de la liste. Apache httpd ne pouvant pas déterminer si la redirection a réussi, si cette dernière ne se trouve pas en fin de liste, c'est cette alternative qui sera toujours utilisée.

La substitution de répertoire utilisateur n'est pas activée par défaut depuis la version 2.1.4. Dans les versions précédentes, UserDir public_html était sous-entendu si aucune directive UserDir n'était présente.

Détails à propos de la fusion

Lorsqu'on passe du contexte global au contexte de serveur virtuel, les listes d'utilisateurs spécifiques activés ou désactivés sont remplacées par les listes du contexte, et non fusionnées.

Voir aussi

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_vhost_alias.html.fr.utf80000664000175100017510000005444014740503670023157 0ustar covenercovener mod_vhost_alias - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_vhost_alias

Langues Disponibles:  en  |  fr  |  tr 

Description:Permet de configurer dynamiquement l'hébergement virtuel de masse
Statut:Extension
Identificateur de Module:vhost_alias_module
Fichier Source:mod_vhost_alias.c

Sommaire

Ce module permet de créer des serveurs virtuels configurés dynamiquement, en autorisant l'utilisation de l'adresse IP et/ou de l'en-tête Host: de la requête HTTP comme partie du nom de chemin afin de déterminer les fichiers à servir. Ceci facilite la gestion d'un grand nombre de serveurs virtuels possèdant des configurations similaires.

Note

Si les modules mod_alias ou mod_userdir sont utilisés pour traduire les URIs en noms de fichiers, ils l'emportent sur les directives du module mod_vhost_alias décrites ci-dessous. Par exemple, la configuration suivante fera correspondre /cgi-bin/script.pl à /usr/local/apache2/cgi-bin/script.pl dans tous les cas :

ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
VirtualScriptAlias "/never/found/%0/cgi-bin/"
Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Interpolation du nom de répertoire

Toutes les directives de ce module insèrent une chaîne dans un nom de chemin. La chaîne insérée (que nous appellerons maintenant le "nom") peut être soit le nom du serveur (voir la directive UseCanonicalName pour les détails sur la manière dont il est déterminé), soit l'adresse IP du serveur virtuel hébergé par le serveur sous la forme d'un quadruplet d'octets séparés par des points. L'insertion est contrôlée par des spécificateurs inspirés de printf et possèdant de nombreux formats :

%% insère un %
%p insère le numéro de port du serveur virtuel
%N.M insère le nom (en partie)

N et M permettent de spécifier des sous-chaînes du nom. N sélectionne un des composants du nom séparés par des points, et M sélectionne des caractères à l'intérieur de ce que N a sélectionné. M est optionnel et sa valeur par défaut est 0 s'il n'est pas spécifié ; le point doit être présent si et seulement si M l'est aussi. Les modes d'insertion sont les suivants :

0 le nom en entier
1 la première partie
2 la seconde partie
-1 la dernière partie
-2 l'avant-dernière partie
2+ toutes les parties à partir de la seconde
-2+ toutes les parties jusqu'à l'avant-dernière
1+ et -1+ identique à 0

Si N ou M est plus grand que le nombre de parties disponibles, seul un caractère de soulignement est inséré.

top

Exemples

Pour des serveurs virtuels simples à base de nom, utilisez les directives suivantes dans le fichier de configuration de votre serveur :

UseCanonicalName    Off
VirtualDocumentRoot "/usr/local/apache/vhosts/%0"

Une requête pour http://www.example.com/repertoire/fichier.html concernera alors la ressource /usr/local/apache/vhosts/www.example.com/repertoire/fichier.html.

Pour un très grand nombre de serveurs virtuels, il est avantageux d'organiser les fichiers de façon à réduire la taille du répertoire vhosts. Pour ce faire, insérez les lignes suivantes dans votre fichier de configuration :

UseCanonicalName    Off
VirtualDocumentRoot "/usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2"

Une requête pour http://www.domaine.example.com/repertoire/fichier.html concernera alors la ressource /usr/local/apache/vhosts/example.com/d/o/m/domaine/repertoire/fichier.html.

Une répartition plus régulière des fichiers peut être obtenue en partant de la fin d'un composant du nom, comme dans l'exemple suivant :

VirtualDocumentRoot "/usr/local/apache/vhosts/%3+/%2.-1/%2.-2/%2.-3/%2"

La requête précédente concernerait alors /usr/local/apache/vhosts/example.com/e/n/i/domaine/repertoire/fichier.html.

Vous pouvez également utiliser :

VirtualDocumentRoot "/usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2.4+"

La requête précédente concernerait alors /usr/local/apache/vhosts/example.com/d/o/m/aine/repertoire/fichier.html.

Une demande très courante des utilisateurs concerne la possibilité de faire correspondre plusieurs racines de documents à plusieurs domaines, sans avoir à se préoccuper de la longueur ou du nombre de parties du nom d'hôte faisant partie de la requête. Si le nom d'hôte de la requête est sub.www.domain.example.com au lieu de simplement www.domain.example.com, alors en utilisant %3+, la racine des documents sera /usr/local/apache/vhosts/domain.example.com/... au lieu du répertoire example.com attendu. Dans ce genre de situation, il peut s'avérer préférable d'utiliser la combinaison %-2.0.%-1.0 qui fournira toujours le nom de domaine et le tld, par exemple example.com sans tenir compte du nombre de sous-domaines ajoutés au nom d'hôte. Dans ces conditions, il est possible d'élaborer une configuration qui associera les sous-domaines de premier, second et troisième niveau au même répertoire :

VirtualDocumentRoot "/usr/local/apache/vhosts/%-2.0.%-1.0"

Dans l'exemple ci-dessus, www.example.com, www.sub.example.com ou example.com correspondront tous au répertoire /usr/local/apache/vhosts/example.com.

Pour l'hébergement virtuel à base d'adresse IP, vous pouvez insérer les lignes suivantes dans votre fichier de configuration :

UseCanonicalName DNS
VirtualDocumentRootIP "/usr/local/apache/vhosts/%1/%2/%3/%4/docs"
VirtualScriptAliasIP  "/usr/local/apache/vhosts/%1/%2/%3/%4/cgi-bin"

Si l'adresse IP de www.domaine.example.com est 10.20.30.40, une requête pour http://www.domaine.example.com/repertoire/fichier.html concernera la ressource /usr/local/apache/vhosts/10/20/30/40/docs/repertoire/fichier.html. Une requête pour http://www.domaine.example.com/cgi-bin/script.pl concernera la ressource /usr/local/apache/vhosts/10/20/30/40/cgi-bin/script.pl.

Si vous voulez insérer le caractère . dans une directive VirtualDocumentRoot, et si cela crée un conflit avec un spécificateur %, vous pouvez contourner le problème de la manière suivante :

VirtualDocumentRoot "/usr/local/apache/vhosts/%2.0.%3.0"

Une requête pour http://www.domaine.example.com/repertoire/fichier.html concernera alors la ressource /usr/local/apache/vhosts/domaine.exemple/repertoire/fichier.html.

Les spécificateurs de format %V et %A de la directive LogFormat s'avèrent très utiles lorsqu'ils sont utilisés en conjonction avec ce module.

top

Directive VirtualDocumentRoot

Description:Permet une configuration dynamique de la racine des documents d'un serveur virtuel donné
Syntaxe:VirtualDocumentRoot répertoire-interpolé|none
Défaut:VirtualDocumentRoot none
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_vhost_alias

La directive VirtualDocumentRoot vous permet de spécifier où le serveur HTTP Apache pourra trouver vos documents en se basant sur le nom du serveur. Le résultat de l'expansion du répertoire-interpolé est utilisé comme racine de l'arborescence des documents d'une manière similaire à l'argument de la directive DocumentRoot. Si répertoire-interpolé a pour valeur none, la directive VirtualDocumentRoot est désactivée. Cette directive ne peut pas être utilisée dans le même contexte que la directive VirtualDocumentRootIP.

Note

La directive VirtualDocumentRoot l'emporte sur toute directive DocumentRoot définie dans le même contexte ou dans des contextes enfants. Le fait de définir une directive VirtualDocumentRoot dans le contexte du serveur principal va effectivement l'emporter sur toute directive DocumentRoot définie dans un serveur virtuel quelconque, si vous n'avez pas défini VirtualDocumentRoot à None dans ce serveur virtuel.
top

Directive VirtualDocumentRootIP

Description:Configuration dynamique de la racine des documents pour un serveur virtuel donné
Syntaxe:VirtualDocumentRootIP répertoire-interpolé|none
Défaut:VirtualDocumentRootIP none
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_vhost_alias

La directive VirtualDocumentRootIP est identique à la directive VirtualDocumentRoot à l'exception près qu'elle utilise l'adresse IP du serveur virtuel pour l'interpolation du répertoire à la place du nom du serveur.

top

Directive VirtualScriptAlias

Description:Configuration dynamique du répertoire des scripts CGI pour un serveur virtuel donné
Syntaxe:VirtualScriptAlias répertoire-interpolé|none
Défaut:VirtualScriptAlias none
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_vhost_alias

La directive VirtualScriptAlias vous permet de spécifier où Apache httpd pourra trouver les scripts CGI selon une méthode similaire à celle qu'utilise la directive VirtualDocumentRoot pour les autres documents. Elle recherche des requêtes dont l'URI commence par /cgi-bin/, comme le ferait la directive ScriptAlias.

top

Directive VirtualScriptAliasIP

Description:Configuration dynamique du répertoire des scripts CGI pour un serveur virtuel donné
Syntaxe:VirtualScriptAliasIP répertoire-interpolé|none
Défaut:VirtualScriptAliasIP none
Contexte:configuration globale, serveur virtuel
Statut:Extension
Module:mod_vhost_alias

La directive VirtualScriptAliasIP est identique à la directive VirtualScriptAlias à l'exception près qu'elle utilise l'adresse IP du serveur virtuel pour l'interpolation du répertoire à la place du nom du serveur.

Langues Disponibles:  en  |  fr  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/module-dict.html.fr.utf80000664000175100017510000002276014740503670022212 0ustar covenercovener Termes utilisés pour décrire les modules - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4

Termes utilisés pour décrire les modules

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

Ce document décrit les termes utilisés pour décrire chaque module Apache.

Support Apache!

Voir aussi

top

Description

Une brève description des fonctions du module.

top

Statut

Ce terme indique le degré de rapprochement du module par rapport au coeur du serveur web Apache ; en d'autres termes, vous pouvez être amené à recompiler le serveur pour pouvoir accéder au module et à ses fonctionnalités. Les valeurs possibles de cet attribut sont :

MPM
Un module dont le statut est "MPM" est un module Multi-Processus. A la différence des autres modules, un seul module MPM peut et doit être utilisé par Apache à la fois. Ce type de module est responsable de la répartition et du traitement de base des requêtes.
Base
Un module dont le statut est "Base" est compilé dans le serveur et chargé avec ce dernier par défaut ; il est donc toujours disponible à moins que vous n'ayez fait en sorte de supprimer le module de votre configuration.
Extension
Un module dont le statut est "Extension" n'est pas compilé et chargé dans le serveur par défaut. Pour activer le module et accéder à ses fonctionnalités, vous devez modifier la configuration de la compilation du serveur et recompiler Apache.
Expérimental
Le statut "Experimental" indique que le module fait partie du kit Apache, mais que vous devez l'utiliser à vos risques et périls. Le module est documenté à des fins d'exhaustivité, et n'est pas obligatoirement supporté.
Externe
Ce statut indique que le module ("module tiers") ne fait pas partie de la distribution de base d'Apache. Nous ne sommes pas responsables de ces modules et n'en assurons pas le support.
top

Fichier source

Il s'agit tout simplement de la liste des noms des fichiers source qui contiennent le code du module. C'est aussi le nom utilisé par la directive <IfModule>.

top

Identificateur de module

C'est une chaîne permettant d'identifier le module à utiliser dans la directive LoadModule pour le chargement dynamique des modules. En particulier, c'est le nom de la variable externe de type module dans le fichier source.

top

Compatibilité

Si le module ne faisait pas partie de la distribution originale d'Apache version 2, la version à partir de laquelle il est disponible est indiquée ici. En outre, si le module n'est disponible que sur certaines plates-formes, cela sera mentionné ici.

Langues Disponibles:  en  |  fr  |  ja  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_winnt.html.fr.utf80000664000175100017510000002660114740503670022012 0ustar covenercovener mpm_winnt - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Apache MPM winnt

Langues Disponibles:  de  |  en  |  fr  |  ja 

Description:Module multi-processus optimisé pour Windows NT.
Statut:MPM
Identificateur de Module:mpm_winnt_module
Fichier Source:mpm_winnt.c

Sommaire

Ce module multi-processus (MPM) est le module par défaut pour les systèmes d'exploitation de style Windows NT. Il consiste en un processus de contrôle unique qui lance un processus enfant unique, ce dernier créant à son tour des threads pour traiter les requêtes.

La directive ThreadsPerChild définit le nombre maximal de connexions clientes simultanées.

Ce MPM utilise par défaut les APIs Windows avancées pour accepter les nouvelles connexions des clients. Avec certaines configurations, des produits tiers peuvent interférer avec cette implémentation, et provoquer l'enregistrement des messages suivants dans les journaux du serveur :

Child: Encountered too many AcceptEx faults accepting client connections.
winnt_mpm: falling back to 'AcceptFilter none'.

Le MPM se rabat sur une implémentation plus sûre, mais certaines requêtes n'ont pas été traitées correctement. Pour éviter cette erreur, définissez la directive AcceptFilter à none.

AcceptFilter http none
AcceptFilter https none

Avec les versions 2.0 et 2.2 d'Apache httpd, c'est la directive Win32DisableAcceptEx qui était utilisée à cet effet.

Le MPM WinNT diffère des autres MPMs Unix comme worker et event à bien des égards :

Support Apache!

Directives

Traitement des bugs

Voir aussi

Langues Disponibles:  de  |  en  |  fr  |  ja 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/prefork.html.fr.utf80000664000175100017510000004264114740503670021454 0ustar covenercovener prefork - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Apache MPM prefork

Langues Disponibles:  de  |  en  |  fr  |  ja  |  tr 

Description:Implémente un serveur web avec démarrage anticipé de processus, sans thread
Statut:MPM
Identificateur de Module:mpm_prefork_module
Fichier Source:prefork.c

Sommaire

Ce module multi-processus (MPM) implémente un serveur web avec démarrage anticipé de processus. Chaque processus du serveur peut répondre aux requêtes entrantes, et un processus parent contrôle la taille du jeu de processus enfants. Il est particulièrement indiqué pour les sites qui ne doivent pas utiliser les threads afin de maintenir une compatibilité avec certaines bibliothèques non sûres du point de vue des threads. C'est également le MPM le plus approprié si l'on veut isoler les requêtes les unes des autres, de façon à ce qu'un problème concernant une requête n'affecte pas les autres.

Ce MPM s'auto-contrôle de manière efficace, de sorte qu'il est rarement nécessaire d'ajuster ses directives de configuration. Le plus important est la définition de la directive MaxRequestWorkers ; sa valeur doit être assez grande pour pouvoir traiter autant de requêtes simultanées que vous pensez recevoir, mais assez petite pour conserver suffisamment de mémoire RAM pour tous les processus.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Comment ça marche

Un processus de contrôle unique a pour tâche de lancer les processus enfants qui attendent les connexions et les traitent au fur et à mesure qu'elles arrivent. Apache httpd essaie toujours de maintenir plusieurs processus serveurs inactifs ou en réserve, afin de pouvoir traiter les requêtes entrantes. De cette façon, les clients n'ont pas besoin d'attendre le démarrage d'un nouveau processus enfant pour que leurs requêtes puissent être traitées.

Les directives StartServers, MinSpareServers, MaxSpareServers et MaxRequestWorkers permettent de contrôler la manière dont le processus parent crée les processus enfants pour traiter les requêtes. En général, Apache httpd s'auto-contrôle de manière efficace, de sorte que la plupart des sites peuvent conserver les valeurs par défaut des directives. Les sites qui doivent traiter plus de 256 requêtes simultanées doivent augmenter la valeur de MaxRequestWorkers, alors que les sites dont la ressource mémoire est limitée doivent la diminuer afin d'éviter une hyperactivité du serveur (utilisation excessive de la mémoire virtuelle sur disque). Vous trouverez plus d'informations à propos du contrôle de la création de processus dans le document conseils en matière de performances

Alors que le processus parent est en général démarré en tant que root sous Unix afin de pouvoir se mettre à l'écoute sur le port 80, les processus enfants sont lancés par Apache httpd sous un utilisateur avec privilèges restreints. On peut contrôler les privilèges accordés aux processus enfants d'Apache httpd à l'aide des directives User et Group. Les processus enfants doivent être en mesure de lire tous les contenus destinés à être servis, mais leurs privilèges doivent être aussi bas que possible.

La directive MaxConnectionsPerChild permet de contrôler la fréquence à laquelle le serveur recycle ses processus en arrêtant les plus anciens et en en lançant de nouveaux.

Ce module MPM utilise le mutex mpm-accept pour sérialiser l'accès aux connexions entrantes lorsque peut se présenter un problème d'afflux de requêtes (en général quand il y a plusieurs sockets en écoute). Les aspects de l'implémentation de ce mutex peuvent être configurés via la directive Mutex. Vous trouverez des informations supplémentaires à propos de ce mutex dans la documentation à propos des conseils en matière de performances

top

Directive MaxSpareServers

Description:Nombre maximum de processus serveurs enfants inactifs
Syntaxe:MaxSpareServers nombre
Défaut:MaxSpareServers 10
Contexte:configuration globale
Statut:MPM
Module:prefork

La directive MaxSpareServers permet de définir le nombre maximum souhaité de processus serveurs enfants inactifs. Un processus inactif est un processus qui ne traite pas de requête. S'il y a plus de MaxSpareServers processus inactifs, le processus parent arrêtera les processus excédentaires.

La modification de ce paramètre n'est nécessaire que dans le cas de sites très sollicités. Définir ce paramètre à une valeur très grande est cependant dans la plupart des cas une mauvaise idée. Si vous essayez d'affecter à ce paramètre une valeur égale ou inférieure à la valeur de MinSpareServers, le serveur HTTP Apache l'ajustera automatiquement à la valeur de MinSpareServers + 1.

Voir aussi

top

Directive MinSpareServers

Description:Nombre minimum de processus serveurs enfants inactifs
Syntaxe:MinSpareServers nombre
Défaut:MinSpareServers 5
Contexte:configuration globale
Statut:MPM
Module:prefork

La directive MinSpareServers permet de définir le nombre minimum désiré de processus serveurs enfants inactifs. Un processus inactif est un processus qui ne traite pas de requête. S'il y a moins de MinSpareServers processus inactifs, le processus parent va créer de nouveaux enfants de la manière suivante : il en crée un, attend une seconde, il en crée deux, attend une seconde, il en crée quatre, puis continue ainsi exponentiellement jusu'à ce que son taux de création de processus enfants soit de 32 par seconde. Il ne s'arrête que lorsque le nombre de processus enfants correspond à la définition de la directive MinSpareServers.

La modification de ce paramètre n'est nécessaire que dans le cas de sites très sollicités. Définir ce paramètre à une valeur très grande est dans la plupart des cas une mauvaise idée.

Voir aussi

Langues Disponibles:  de  |  en  |  fr  |  ja  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/overrides.html.fr.utf80000664000175100017510000022460214740503670022005 0ustar covenercovener Index par classes des directives autorisées dans .htaccess - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4

Index par classes des directives autorisées dans .htaccess

Langues Disponibles:  en  |  fr 

Ceci est un index, organisé en classes, des directives autorisées dans les fichiers .htaccess pour différentes définitions de la directive AllowOverride. Il a pour but d'aider les administrateurs à contrôler les privilèges qu'ils accordent aux utilisateurs via les fichiers .htaccess. Pour une présentation de la manière dont fonctionnent les fichiers .htaccess, voir le tutoriel .htaccess.

Pour déterminer le jeu de directives que la configuration de votre serveur autorise aux utilisateurs dans les fichiers .htaccess :

  1. Commencez par rechercher la présence d'une directive AllowOverrideList dans la section directory concernée. Sa définition vous indiquera la liste des directives autorisées (La valeur par défaut de cette directive est None).
  2. Recherchez ensuite la présence d'une directive AllowOverride dans cette même section (sa valeur par défaut est None). Il y a tout d'abord deux cas particuliers :
    1. Si la directive AllowOverride est définie à All, vous pouvez ajouter toutes les directives indiquées sur cette page à la liste préexistante.
    2. Si la directive AllowOverride est définie à None, inutile d'aller plus loin. Seules les directives indiquées par la directive AllowOverrideList (si elle est présente) seront autorisées.
  3. En dehors de ces deux cas, la directive AllowOverride définit une liste de classes de directives (vous trouverez plus loin le jeu de directives correspondant à chacune de ces classes), et vous pourrez alors les ajouter à la liste définie par la directive AllowOverrideList.
  4. Ajoutez enfin à la liste le jeu de directives toujours autorisées dans les fichiers .htaccess (elles sont listées dans la section All ci-dessous).

De nombreuses classes de directives sont assez puissantes et peuvent permettre aux utilisateurs des fichiers .htaccess de contrôler une grande partie du serveur. Pour une approche plus sure, définissez AllowOverride None, et utilisez la directive AllowOverrideList pour spécifier la liste exacte de directives que les utilisateurs de fichiers .htaccess pourront utiliser.

Sujets

Voir aussi

top

All

Les directives suivantes sont autorisées dans les fichiers .htaccess, sous réserve que la surcharge soit autorisée dans la configuration du serveur.

<Else>core
Contient des directives qui ne s'appliquent que si la condition correspondant à la section <If> ou <ElseIf> précédente n'est pas satisfaite par la requête à l'exécution
<ElseIf>core
Contient des directives qui ne s'appliquent que si la condition correspondante est satisfaite par une requête à l'exécution, alors que la condition correspondant à la section <If> ou <ElseIf> précédente ne l'était pas.
<Files>core
Contient des directives qui s'appliquent aux fichiers précisés
<FilesMatch>core
Contient des directives qui s'appliquent à des fichiers spécifiés sous la forme d'expressions rationnelles
<If>core
Contient des directives qui ne s'appliquent que si une condition est satisfaite au cours du traitement d'une requête
<IfDefine>core
Contient des directives qui ne s'appliqueront que si un test retourne "vrai" au démarrage du serveur
<IfDirective>core
Regroupe des directives dont le traitement est conditionné par la présence ou l'absence d'une directive particulière
<IfFile>core
Regroupe des directives qui ne seront traitées que si un fichier existe au démarrage
<IfModule>core
Contient des directives qui ne s'appliquent qu'en fonction de la présence ou de l'absence d'un module spécifique
<IfSection>core
Regroupe des directives dont le traitement est conditionné par la présence ou l'absence d'une section particulière
<IfVersion>mod_version
Contient des portions de configuration dépendantes de la version
LimitRequestBodycore
limite la taille maximale du corps de la requête HTTP envoyée par le client
LimitXMLRequestBodycore
Définit la taille maximale du corps d'une requête au format XML
LogIOTrackTTFBmod_logio
Permet d'enregistrer le délai avant le premier octet (time to first byte - TTFB)
LuaCodeCachemod_lua
Configure le cache de code compilé.
LuaHookAccessCheckermod_lua
Fournit un point d'entrée pour la phase access_checker du traitement de la requête
LuaHookAuthCheckermod_lua
Fournit un point d'entrée pour la phase auth_checker du traitement de la requête
LuaHookCheckUserIDmod_lua
Fournit un point d'entrée pour la phase check_user_id du traitement de la requête
LuaHookFixupsmod_lua
Fournit un point d'entrée pour la phase de correction du traitement de la requête
LuaHookInsertFiltermod_lua
Fournit un point d'entrée pour la phase insert_filter du traitement de la requête
LuaHookLogmod_lua
Permet une insertion dans la phase de journalisation du traitement d'une requête
LuaHookMapToStoragemod_lua
Fournit un point d'entrée pour la phase map_to_storage du traitement de la requête
LuaHookPreTranslatemod_lua
Fournit un point d'entrée pour la phase de pré-traduction du traitement d'une requête
LuaHookTranslateNamemod_lua
Fournit un point d'entrée à la phase du nom de traduction du traitement de la requête
LuaHookTypeCheckermod_lua
Fournit un point d'entrée pour la phase type_checker du traitement de la requête
LuaInheritmod_lua
Contrôle la manière dont les sections de configuration parentes sont fusionnées dans les enfants
LuaMapHandlermod_lua
Met en correspondance un chemin avec un gestionnaire lua
LuaPackageCPathmod_lua
Ajoute un répertoire au package.cpath de lua
LuaPackagePathmod_lua
Ajoute un répertoire au package.path de lua
LuaQuickHandlermod_lua
Fournit un point d'entrée pour la gestion rapide du traitement de la requête
LuaRootmod_lua
Spécifie le chemin de base pour la résolution des chemins relatifs dans les directives de mod_lua
LuaScopemod_lua
Une valeur parmi once, request, conn, thread -- la valeur par défaut est once
RLimitCPUcore
Limite le temps CPU alloué aux processus initiés par les processus enfants d'Apache httpd
RLimitMEMcore
Limite la mémoire allouée aux processus initiés par les processus enfants d'Apache httpd
RLimitNPROCcore
Limite le nombre de processus qui peuvent être initiés par les processus initiés par les processus enfants d'Apache httpd
ServerSignaturecore
Définit un pied de page pour les documents générés par le serveur
SSIErrorMsgmod_include
Message d'erreur affiché lorsqu'une erreur SSI survient
SSITimeFormatmod_include
Configuration du format d'affichage des dates
SSIUndefinedEchomod_include
Chaîne à afficher lorsqu'on tente d'extraire le contenu d'une variable non définie
top

AuthConfig

Les directives suivantes sont autorisées dans les fichiers .htaccess lorsque AllowOverride AuthConfig a été spécifié. Elles permettent aux utilisateurs de fichiers .htaccess de contrôler les méthodes d'authentification et d'autorisation qui s'appliquent à l'arborescence de leur répertoire, y compris de nombreuses directives utilitaires pour la gestion de session et la configuration TLS.

Anonymousmod_authn_anon
Définit la liste des identifiants utilisateur autorisés à accéder sans vérification du mot de passe
Anonymous_LogEmailmod_authn_anon
Détermine si le mot de passe fourni sera enregistré dans le journal des erreurs
Anonymous_MustGiveEmailmod_authn_anon
Détermine si l'abscence de mot de passe est autorisée
Anonymous_NoUserIDmod_authn_anon
Détermine si le champ identifiant peut être vide
Anonymous_VerifyEmailmod_authn_anon
Détermine s'il faut vérifier que le format de l'adresse email fournie comme mot de passe est correct
AuthBasicAuthoritativemod_auth_basic
Définit si les processus d'autorisation et d'authentification peuvent être confiés à des modules de plus bas niveau
AuthBasicFakemod_auth_basic
Authentification de base simulée à l'aide des nom d'utilisateur et mot de passe fournis
AuthBasicProvidermod_auth_basic
Définit le(les) fournisseur(s) d'authentification pour cette zone du site web
AuthBasicUseDigestAlgorithmmod_auth_basic
Vérifie les mots de passe auprès des fournisseurs d'authentification à la manière de l'authentification de type Digest.
AuthDBMGroupFilemod_authz_dbm
Définit le nom du fichier de base de données contenant la liste des groupes d'utilisateurs permettant de définir les autorisations des utilisateurs
AuthDBMTypemod_authn_dbm
Définit le type de fichier de base de données utilisé pour stocker les mots de passe
AuthDBMUserFilemod_authn_dbm
Définit le nom d'un fichier de base de données pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe
AuthDigestAlgorithmmod_auth_digest
Sélectionne l'algorithme utilisé pour calculer les condensés du défit et de sa réponse
AuthDigestDomainmod_auth_digest
Les URIs qui se trouvent dans le même espace de protection concernant l'authentification à base de condensés
AuthDigestNonceLifetimemod_auth_digest
Durée de validité du nombre à valeur unique du serveur (nonce)
AuthDigestProvidermod_auth_digest
Définit le(s) fournisseurs(s) d'authentification pour la zone du site web concernée
AuthDigestQopmod_auth_digest
Détermine le niveau de protection fourni par l'authentification à base de condensé
AuthFormAuthoritativemod_auth_form
Détermine si l'autorisation et l'authentification sont confiés à des modules de plus bas niveau
AuthFormProvidermod_auth_form
Définit le(s) fournisseur(s) d'authentification pour la zone concernée
AuthGroupFilemod_authz_groupfile
Définit le nom d'un fichier texte contenant la liste des groupes d'utilisateurs permettant de définir les autorisations des utilisateurs
AuthLDAPAuthorizePrefixmod_authnz_ldap
Spécifie le préfixe ajouté aux variables d'environnement durant la phase d'autorisation
AuthLDAPBindAuthoritativemod_authnz_ldap
Détermine si l'on doit utiliser d'autres fournisseurs d'authentification lorsque le serveur ne peut pas valider les données d'authentification de l'utilisateur, alors que ce dernier possède un DN.
AuthLDAPBindDNmod_authnz_ldap
Un DN optionnel pour se connecter au serveur LDAP
AuthLDAPBindPasswordmod_authnz_ldap
Mot de passe à utiliser en conjonction avec le DN de connexion
AuthLDAPCompareAsUsermod_authnz_ldap
Utilisation des données d'authentification de l'utilisateur pour effectuer les comparaisons pour l'attribution des autorisations
AuthLDAPCompareDNOnServermod_authnz_ldap
Utilise le serveur LDAP pour comparer les DNs
AuthLDAPDereferenceAliasesmod_authnz_ldap
À quel moment le module va déréférencer les alias
AuthLDAPGroupAttributemod_authnz_ldap
L'attribut LDAP utilisé pour vérifier l'appartenance d'un utilisateur à un groupe.
AuthLDAPGroupAttributeIsDNmod_authnz_ldap
Utilise le DN de l'utilisateur pour vérifier son appartenance à un groupe
AuthLDAPInitialBindAsUsermod_authnz_ldap
Détermine si le serveur effectue la recherche initiale du DN en utilisant le nom propre de l'utilisateur pour l'authentification de base et non de manière anonyme, ou en utilisant des données d'authentification codées en dur pour le serveur
AuthLDAPInitialBindPatternmod_authnz_ldap
Spécifie la modification a apporter au nom d'utilisateur pour l'authentification de base lors de l'authentification auprès du serveur LDAP pour effectuer une recherche de DN
AuthLDAPMaxSubGroupDepthmod_authnz_ldap
Spécifie la profondeur d'imbrication des sous-groupes maximale prise en compte avant l'abandon de la recherche de l'utilisateur.
AuthLDAPRemoteUserAttributemod_authnz_ldap
Spécifie l'attribut dont la valeur renvoyée au cours de la requête de l'utilisateur sera utilisée pour définir la variable d'environnement REMOTE_USER
AuthLDAPRemoteUserIsDNmod_authnz_ldap
Utilise le DN de l'utilisateur pour définir la variable d'environnement REMOTE_USER
AuthLDAPSearchAsUsermod_authnz_ldap
Utilise les données d'authentification de l'utilisateur pour la recherche des autorisations
AuthLDAPSubGroupAttributemod_authnz_ldap
Spécifie les noms d'attribut, un par directive, utilisés pour différencier les membres du groupe courant qui sont eux-mêmes des groupes.
AuthLDAPSubGroupClassmod_authnz_ldap
Spécifie quelles valeurs d'objectClass LDAP identifient les objets de l'annuaire qui sont des groupes au cours du traitement des sous-groupes.
AuthLDAPURlmod_authnz_ldap
L'URL permettant de spécifier les paramètres de la recherche LDAP
AuthMergingmod_authz_core
Définit la manière dont chaque logique d'autorisation des sections de configuration se combine avec celles des sections de configuration précédentes.
AuthNamemod_authn_core
L'identifiant de l'autorisation à utiliser avec l'authentification HTTP
AuthnCacheProvideFormod_authn_socache
Spécifie le fournisseur pour lequel on veut effectuer une mise en cache
AuthnCacheTimeoutmod_authn_socache
Définit une durée de vie pour les entrées du cache
AuthTypemod_authn_core
Type d'authentification utilisateur
AuthUserFilemod_authn_file
Définit le nom d'un fichier texte pour l'authentification contenant la liste des utilisateurs et de leurs mots de passe
AuthzDBMTypemod_authz_dbm
Définit le type de fichier de base de données contenant la liste des groupes d'utilisateurs
CGIPassAuthcore
Active la transmission d'en-têtes d'autorisation HTTP aux scripts en tant que variables CGI
LDAPReferralHopLimitmod_ldap
Le nombre maximum de redirections vers des serveurs alternatifs (referrals) avant l'abandon de la requête LDAP.
LDAPReferralsmod_ldap
Active la redirection vers des serveurs alternatifs au cours des requêtes vers le serveur LDAP.
<Limit>core
Limite les contrôles d'accès que la section contient à certaines méthodes HTTP
<LimitExcept>core
Applique les contrôles d'accès à toutes les méthodes HTTP, sauf celles qui sont spécifiées
Requiremod_authz_core
Vérifie si un utilisateur authentifié a une autorisation d'accès accordée par un fournisseur d'autorisation.
<RequireAll>mod_authz_core
Regroupe plusieurs directives d'autorisation dont aucune ne doit échouer et dont au moins une doit retourner un résultat positif pour que la directive globale retourne elle-même un résultat positif.
<RequireAny>mod_authz_core
Regroupe des directives d'autorisation dont au moins une doit retourner un résultat positif pour que la directive globale retourne elle-même un résultat positif.
<RequireNone>mod_authz_core
Regroupe des directives d'autorisation dont aucune ne doit retourner un résultat positif pour que la directive globale n'échoue pas.
Satisfymod_access_compat
Interaction entre le contrôle d'accès en fonction de l'hôte et l'authentification utilisateur
Sessionmod_session
Ouvre une session pour le contexte courant
SessionEnvmod_session
Définit si le contenu de la session doit être enregistré dans la variable d'environnement HTTP_SESSION
SessionHeadermod_session
Importation des mises à jour de session depuis l'en-tête de réponse HTTP spécifié
SessionIncludemod_session
Définit les préfixes d'URL pour lesquels une session est valide
SessionMaxAgemod_session
Définit une durée de vie maximale pour la session en secondes
SSLCipherSuitemod_ssl
Algorithmes de chiffrement disponibles pour la négociation au cours de l'initialisation de la connexion SSL
SSLRenegBufferSizemod_ssl
Définit la taille du tampon de renégociation SSL
SSLRequiremod_ssl
N'autorise l'accès que lorsqu'une expression booléenne complexe et arbitraire est vraie
SSLRequireSSLmod_ssl
Interdit l'accès lorsque la requête HTTP n'utilise pas SSL
SSLUserNamemod_ssl
Nom de la variable servant à déterminer le nom de l'utilisateur
SSLVerifyClientmod_ssl
Niveau de vérification du certificat client
SSLVerifyDepthmod_ssl
Profondeur maximale des certificats de CA pour la vérification des certificats clients
top

FileInfo

Les directives suivantes sont autorisées dans les fichiers .htaccess lorsque AllowOverride FileInfo a été spécifié. Elles accordent aux utilisateurs de fichiers .htaccess un grand nombre de contrôles sur les réponses et les métadonnées fournies par le serveur.

AcceptPathInfocore
Les ressources acceptent des informations sous forme d'un nom de chemin en fin de requête.
Actionmod_actions
Active un script CGI pour un gestionnaire ou un type de contenu particulier
AddCharsetmod_mime
Associe les extensions de noms de fichiers spécifiées au jeu de caractères spécifié
AddDefaultCharsetcore
Paramètre jeu de caractères par défaut à ajouter quand le type de contenu d'une réponse est text/plain ou text/html
AddEncodingmod_mime
Associe les extensions de noms de fichiers données au type de codage spécifié
AddHandlermod_mime
Associe les extensions de noms de fichiers données au gestionnaire spécifié
AddInputFiltermod_mime
Associe les extensions de noms de fichiers aux filtres spécifiés qui traiteront les requêtes clients
AddLanguagemod_mime
Associe l'extension de nom de fichier donnée à la langue spécifié
AddOutputFiltermod_mime
Associe les extensions de noms de fichiers aux filtres spécifiés qui traiteront les réponses en provenance du serveur
AddOutputFilterByTypemod_filter
assigne un filtre en sortie pour un type de média particulier
AddTypemod_mime
Associe les extensions de noms de fichiers au type de contenu spécifié
BrowserMatchmod_setenvif
Définit des variables d'environnement en fonction du contenu de l'en-tête HTTP User-Agent
BrowserMatchNoCasemod_setenvif
Définit des variables d'environnement en fonction du contenu de l'en-tête HTTP User-Agent sans tenir compte de la casse
CGIMapExtensioncore
Technique permettant de localiser l'interpréteur des scripts CGI
CGIVarcore
Contrôle la manière dont certaines variables CGI sont définies
CharsetDefaultmod_charset_lite
Jeu de caractère vers lequel la traduction doit s'effectuer
CharsetOptionsmod_charset_lite
Précise les détails de la traduction du jeu de caractères
CharsetSourceEncmod_charset_lite
Jeu de caractères source des fichiers
CookieDomainmod_usertrack
Le domaine auquel le cookie traceur s'applique
CookieExpiresmod_usertrack
Durée avant expiration du cookie traceur
CookieHTTPOnlymod_usertrack
Ajoute l'attribut 'HTTPOnly' au cookie
CookieNamemod_usertrack
Nom du cookie traceur
CookieSameSitemod_usertrack
Ajoute l'attribut 'SameSite' au cookie
CookieSecuremod_usertrack
Ajoute l'attribut 'Secure' au cookie
CookieStylemod_usertrack
Format du champ d'en-tête cookie
CookieTrackingmod_usertrack
Active le cookie traceur
DefaultLanguagemod_mime
Définit un symbole de langue par défaut à affecter au champ d'en-tête Content-Language pour toutes les ressources dans le contexte courant auxquelles aucun symbole de langue n'a été associé.
DefaultTypecore
Les seuls effets de cette directive sont des émissions d'avertissements si sa valeur est différente de none. Dans les versions précédentes, DefaultType permettait de spécifier un type de média à assigner par défaut au contenu d'une réponse pour lequel aucun autre type de média n'avait été trouvé.
EnableMMAPcore
Utilise la projection en mémoire (Memory-Mapping) pour lire les fichiers pendant qu'ils sont servis
EnableSendfilecore
Utilise le support sendfile du noyau pour servir les fichiers aux clients
ErrorDocumentcore
Document que le serveur renvoie au client en cas d'erreur
FileETagcore
Caractéristiques de fichier utilisées lors de la génération de l'en-tête de réponse HTTP ETag pour les fichiers statiques
ForceLanguagePrioritymod_negotiation
Action à entreprendre si un document acceptable unique n'est pas trouvé
ForceTypecore
Force le type de médium spécifié dans le champ d'en-tête HTTP Content-Type pour les fichiers correspondants
Headermod_headers
Configure les en-têtes d'une réponse HTTP
ISAPIAppendLogToErrorsmod_isapi
Enregistrement des requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans le journal des erreurs
ISAPIAppendLogToQuerymod_isapi
Enregistre les requêtes HSE_APPEND_LOG_PARAMETER de la part des extensions ISAPI dans la partie arguments de la requête
ISAPIFakeAsyncmod_isapi
Emulation du support des entrées/sorties asynchrones pour les appels ISAPI
ISAPILogNotSupportedmod_isapi
Journalisation des demandes de fonctionnalités non supportées de la part des extensions ISAPI
ISAPIReadAheadBuffermod_isapi
Taille du tampon de lecture anticipée envoyé aux extensions ISAPI
LanguagePrioritymod_negotiation
L'ordre de priorité des variantes de langages pour les cas où le client n'a pas formulé de préférences
MultiviewsMatchmod_mime
Les types de fichiers qui seront inclus lors d'une recherche de correspondance de fichier avec les vues multiples (MultiViews)
PassEnvmod_env
Transmet des variables d'environnement depuis le shell
QualifyRedirectURLcore
Vérifie si la variable d'environnement REDIRECT_URL est pleinement qualifiée
Redirectmod_alias
Envoie une redirection externe demandant au client d'effectuer une autre requête avec une URL différente
RedirectMatchmod_alias
Envoie une redirection externe faisant appel aux expressions rationnelles pour la mise en correspondance de l'URL courante
RedirectPermanentmod_alias
Envoie une redirection externe permanente demandant au client d'effectuer une nouvelle requête avec une URL différente
RedirectTempmod_alias
Envoie une redirection externe temporaire demandant au client d'effectuer une nouvelle requête avec une URL différente
RemoveCharsetmod_mime
Supprime toute association de jeu de caractères pour un ensemble d'extensions de noms de fichiers
RemoveEncodingmod_mime
Supprime toute association de codage de contenu pour un ensemble d'extensions de noms de fichiers
RemoveHandlermod_mime
Supprime toute association de gestionnaire à un ensemble d'extensions de noms de fichiers
RemoveInputFiltermod_mime
Supprime toute association de filtre en entrée à un ensemble d'extensions de noms de fichiers
RemoveLanguagemod_mime
Supprime toute association de langue à un ensemble d'extensions de noms de fichiers
RemoveOutputFiltermod_mime
Supprime toute association de filtre en sortie à un ensemble d'extensions de noms de fichiers
RemoveTypemod_mime
Supprime toute association de type de contenu à un ensemble d'extensions de noms de fichiers
RequestHeadermod_headers
Configure les en-têtes d'une requête HTTP
RewriteBasemod_rewrite
Définit l'URL de base pour les réécritures au niveau répertoire
RewriteCondmod_rewrite
Définit une condition qui devra être satisfaite pour que la réécriture soit effectuée
RewriteEnginemod_rewrite
Active ou désactive l'exécution du moteur de réécriture
RewriteOptionsmod_rewrite
Configure certaines options spéciales pour le moteur de réécriture
RewriteRulemod_rewrite
Définit les règles pour le moteur de réécriture
ScriptInterpreterSourcecore
Permet de localiser l'interpréteur des scripts CGI
SetEnvmod_env
Définit des variables d'environnement
SetEnvIfmod_setenvif
Définit des variables d'environnement en fonction des attributs de la requête
SetEnvIfExprmod_setenvif
Définit des variables d'environnement en fonction d'une expression ap_expr
SetEnvIfNoCasemod_setenvif
Définit des variables d'environnement en fonction des attributs de la requête sans tenir compte de la casse
SetHandlercore
Force le traitement des fichiers spécifiés par un gestionnaire particulier
SetInputFiltercore
Définit les filtres par lesquels vont passer les requêtes client et les données POST
SetOutputFiltercore
Définit les filtres par lesquels vont passer les réponses du serveur
Substitutemod_substitute
Modèle de substition dans le contenu de la réponse
SubstituteInheritBeforemod_substitute
Modifie l'ordre de fusion des modèles hérités
SubstituteMaxLineLengthmod_substitute
Définit la longueur de ligne maximale
UnsetEnvmod_env
Supprime des variables de l'environnement
top

Indexes

Les directives suivantes sont autorisées dans les fichiers .htaccess lorsque AllowOverride Indexes a été spécifié. Elles permettent aux utilisateurs de fichiers .htaccess de contrôler certains aspects des pages d'index de répertoires fournies par le serveur, y compris la génération d'autoindex.

AddAltmod_autoindex
Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son nom
AddAltByEncodingmod_autoindex
Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son codage MIME
AddAltByTypemod_autoindex
Texte optionnel à afficher à la place d'un icône pour un fichier en fonction de son type MIME
AddDescriptionmod_autoindex
Afficher la description d'un fichier
AddIconmod_autoindex
Icône à afficher pour un fichier en fonction de son nom
AddIconByEncodingmod_autoindex
Icône à afficher à côté d'un fichier en fonction de son codage MIME
AddIconByTypemod_autoindex
Icône à afficher à côté d'un fichier en fonction de son type MIME
DefaultIconmod_autoindex
Icône à afficher par défaut lorsqu'aucun icône spécifique n'est précisé
DirectoryCheckHandlermod_dir
Définit la réponse de ce module lorsqu'un autre gestionnaire est utilisé
DirectoryIndexmod_dir
Liste des fichiers ressources à rechercher lorsque le client envoie une requête pour un répertoire
DirectoryIndexRedirectmod_dir
Définit une redirection externe pour les index de répertoires.
DirectorySlashmod_dir
Activation/Désactivation de la redirection "slash de fin"
ExpiresActivemod_expires
Active la génération d'en-têtes Expires
ExpiresByTypemod_expires
Définition de la valeur de l'en-tête Expires en fonction du type MIME
ExpiresDefaultmod_expires
Mode de calcul par défaut de la date d'expiration
FallbackResourcemod_dir
Définit une URL par défaut pour les requêtes qui ne ciblent aucun fichier
HeaderNamemod_autoindex
Nom du fichier qui sera inséré au début de la page contenant l'index
ImapBasemod_imagemap
Valeur par défaut de la directive base des fichiers imagemap
ImapDefaultmod_imagemap
Action à entreprendre par défaut lorsqu'un fichier imagemap est invoqué avec des coordonnées qui ne correspondent à aucune cible
ImapMenumod_imagemap
Action à entreprendre si aucune coordonnée n'est fournie lorsqu'on invoque un fichier imagemap
IndexHeadInsertmod_autoindex
Insère du texte dans la section HEAD de la page d'index.
IndexIgnoremod_autoindex
Ajouts à la liste des fichiers à cacher lors de l'affichage de l'index d'un répertoire
IndexIgnoreResetmod_autoindex
Vide la liste des fichiers à cacher lors de l'affichage du contenu d'un répertoire
IndexOptionsmod_autoindex
Diverses options de configuration pour l'indexation d'un répertoire
IndexOrderDefaultmod_autoindex
Définit l'ordre d'affichage par défaut d'un index de répertoire
IndexStyleSheetmod_autoindex
Ajoute une feuille de style CSS à l'index du répertoire
MetaDirmod_cern_meta
Le nom du répertoire où trouver les fichiers de métainformations dans le style du CERN
MetaFilesmod_cern_meta
Active le traitement des métafichiers du CERN
MetaSuffixmod_cern_meta
Suffixe du fichier contenant les métainformations dans le style du CERN
ReadmeNamemod_autoindex
Nom du fichier dont le contenu sera inséré à la fin de l'index
top

Limit

Les directives suivantes sont autorisées dans les fichiers .htaccess lorsque AllowOverride Limit a été spécifié. Cette autorisation de surcharge très restreinte permet principalement d'utiliser les directives d'autorisation héritées fournies par mod_access_compat.

Allowmod_access_compat
Spécifie quels hôtes peuvent accéder à une certaine zone du serveur
Denymod_access_compat
Définit quels hôtes ne sont pas autorisés à accéder au serveur
<Limit>core
Limite les contrôles d'accès que la section contient à certaines méthodes HTTP
<LimitExcept>core
Applique les contrôles d'accès à toutes les méthodes HTTP, sauf celles qui sont spécifiées
Ordermod_access_compat
Définit le statut d'accès par défaut et l'ordre dans lequel les directives Allow et Deny sont évaluées.
top

Options

Les directives suivantes sont autorisées dans les fichiers .htaccess lorsque AllowOverride Options a été spécifié. Elles permettent aux utilisateurs de fichiers .htaccess d'utiliser la directive Options et d'autres directives similaires, ainsi que les directives qui contrôlent la chaîne de filtrage.

CheckBasenameMatchmod_speling
Vérifie aussi la correspondance des fichiers, même avec des extensions différentes
CheckCaseOnlymod_speling
Limite l'action du module aux corrections de majuscules
CheckSpellingmod_speling
Active le module de correction
ContentDigestcore
Active la génération d'un en-tête Content-MD5 dans la réponse HTTP
FilterChainmod_filter
Configure la chaîne de filtrage
FilterDeclaremod_filter
Déclare un filtre intelligent
FilterProtocolmod_filter
Vérifie le respect du protocole HTTP
FilterProvidermod_filter
Enregistre un filtre de contenu
Optionscore
Définit les fonctionnalités disponibles pour un répertoire particulier
ReflectorHeadermod_reflector
Renvoie un en-tête d'entrée dans les en-têtes de sortie
SSLOptionsmod_ssl
Configure différentes options d'exécution du moteur SSL
XBitHackmod_include
Interprète les directives SSI dans les fichiers dont le bit d'exécution est positionné

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_slotmem_shm.html.fr.utf80000664000175100017510000002215214740503670023165 0ustar covenercovener mod_slotmem_shm - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_slotmem_shm

Langues Disponibles:  en  |  fr 

Description:Fournisseur de mémoire partagée basée sur les slots.
Statut:Extension
Identificateur de Module:slotmem_shm_module
Fichier Source:mod_slotmem_shm.c

Sommaire

mod_slotmem_shm est un fournisseur de mémoire qui permet la création et l'accès à un segment de mémoire partagée dans lequel les ensembles de données sont organisés en "slots".

L'ensemble de la mémoire partagée est effacé à chaque redémarrage, que ce dernier soit graceful ou non. Les données sont stockées et restituées dans/à partir d'un fichier défini par le paramètre name des appels create et attach. Si son chemin absolu n'est pas spécifié, le chemin du fichier sera relatif au chemin défini par la directive DefaultRuntimeDir.

mod_slotmem_shm fournit les fonctions d'API suivantes :

/* appelle le callback pour tous les slots actifs */
apr_status_t doall(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)

/* crée un nouveau slot de mémoire dont chaque taille d'item est
      item_size. 'name' est utilisé pour générer le nom du fichier
      permettant de stocker/restaurer le contenu de la mémoire partagée,
      si elle est configurée. Les valeurs possibles sont :
      "none"                - Mémoire partagée anonyme et pas de stockage permanent
      "file-name"           - [DefaultRuntimeDir]/file-name
      "/absolute-file-name" - Chemin absolu du fichier */
apr_status_t create(ap_slotmem_instance_t **new, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool)

/* attache à un slot de mémoire existant. Voir
      'create' pour la description du paramètre
      'name'. */
apr_status_t attach(ap_slotmem_instance_t **new, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)

/* obtient la mémoire associée à ce slot actif. */
apr_status_t dptr(ap_slotmem_instance_t *s, unsigned int item_id, void **mem)

/* lit la mémoire depuis ce slot et la transfert vers dest */
apr_status_t get(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len)

/* écrit dans ce slot la mémoire en provenance de src */
apr_status_t put(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len)

/* renvoie le nombre total de slots contenus dans ce segment */
unsigned int num_slots(ap_slotmem_instance_t *s)

/* renvoie la taille totale des données, en octets, contenues
      dans un slot de ce segment */
apr_size_t slot_size(ap_slotmem_instance_t *s)

/* alloue le premier slot libre et le marque comme utilisé (n'effectue aucune
      copie de données) */
apr_status_t grab(ap_slotmem_instance_t *s, unsigned int *item_id)

/* appropriation ou allocation forcée du slot spécifié et marquage comme
      utilisé (n'effectue aucune copie de données) */
apr_status_t fgrab(ap_slotmem_instance_t *s, unsigned int item_id)

/* libère un slot et le marque comme non utilisé (n'effectue aucune
      copie de données) */
apr_status_t release(ap_slotmem_instance_t *s, unsigned int item_id)
Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_dc.html.fr.utf80000664000175100017510000001453114740503670022713 0ustar covenercovener mod_socache_dc - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_socache_dc

Langues Disponibles:  en  |  fr 

Description:Fournisseur de cache d'objets partagés basé sur dc.
Statut:Extension
Identificateur de Module:socache_dc_module
Fichier Source:mod_socache_dc.c

Sommaire

Le module mod_socache_dc est un fournisseur de cache d'objets partagés qui permet la création et l'accès à un cache maintenu par les bibliothèques de mise en cache de sessions distribuées distcache.

Vous trouverez des détails à propos des autres fournisseurs de cache d'objets partagés ici.

Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_shmcb.html.fr.utf80000664000175100017510000001461014740503670023417 0ustar covenercovener mod_socache_shmcb - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_socache_shmcb

Langues Disponibles:  en  |  fr 

Description:Fournisseur de cache d'objets partagés basé sur shmcb.
Statut:Extension
Identificateur de Module:socache_shmcb_module
Fichier Source:mod_socache_shmcb.c

Sommaire

Le module mod_socache_shmcb est un fournisseur de cache d'objets partagés qui permet la création et l'accès à un cache maintenu par un tampon cyclique à hautes performances au sein d'un segment de mémoire partagée.

shmcb:/chemin/vers/datafile(512000)

Vous trouverez des détails à propos des autres fournisseurs de cache d'objets partagés ici.

Support Apache!

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_substitute.html.fr.utf80000664000175100017510000003706014740503670023055 0ustar covenercovener mod_substitute - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_substitute

Langues Disponibles:  en  |  fr 

Description:Effectue des opérations de recherche/remplacement sur les corps de réponses
Statut:Extension
Identificateur de Module:substitute_module
Fichier Source:mod_substitute.c
Compatibilité:Disponible depuis la version 2.2.7 du serveur HTTP Apache

Sommaire

mod_substitute fournit un mécanisme permettant d'effectuer des substitutions de chaînes fixes ou d'expressions rationnelles sur les corps de réponses.

Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive Substitute

Description:Modèle de substition dans le contenu de la réponse
Syntaxe:Substitute s/modèle/substitution/[infq]
Contexte:répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_substitute

La directive Substitute permet de spécifier un modèle de recherche/remplacement à appliquer au corps de la réponse.

La signification du modèle peut être modifiée via toute combinaison de ces drapeaux :

i
Effectue une comparaison sans tenir compte de la casse.
n
Par défaut, le modèle est traité en tant qu'expression rationnelle. Le drapeau n force le traitement du modèle en tant que chaîne fixe.
f
Avec le drapeau f, mod_substitute met à plat le résultat d'une substitution (les conteneurs ou buckets ne sont pas dissociés), ce qui permet à d'éventuelles substitutions ultérieures de s'effectuer sur cette dernière. C'est le comportement par défaut.
q
Avec le drapeau q, mod_substitute dissocie les conteneurs (ou buckets) après chaque substitution. Ceci peut améliorer la rapidité de la réponse et diminuer la quantité de mémoire utilisée, mais ne doit être utilisé que s'il n'existe aucune possibilité pour que le résultat d'une substitution ne corresponde au modèle ou à l'expression rationnelle d'une substitution ultérieure.

substitution peut contenir du texte et des références arrières d'expressions rationnelles.

Exemple

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s/foo/bar/ni"
</Location>

Le caractère utilisé pour séparer (ou "délimiter") les différentes partie de la valeur de substitution est référencé sous le nom de "délimiteur", et il s'agit le plus souvent d'un "slash".

Si le modèle ou la chaîne de substitution contient un caractère slash '/', il est possible d'utiliser un autre délimiteur afin de rendre la directive plus lisible :

Exemple d'utilisation d'un délimiteur alternatif

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|<BR */?>|<br />|i"
</Location>

Lorsqu'on utilise des expressions rationnelles, on peut insérer des références arrières dans les opérations de comparaison et de substitution, comme illustré dans l'exemple suivant :

Exemple d'utilisation de références arrières et de captures

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    # "foo=k,bar=k" -> "foo/bar=k"
    Substitute "s|foo=(\w+),bar=\1|foo/bar=$1|"
</Location>

Un scénario courant d'utilisation de mod_substitute est la situation où un serveur frontal mandate des requêtes pour un serveur d'arrière-plan qui renvoie des documents HTML contenant des URLs intégrées codées en dur qui font référence à ce serveur d'arrière-plan. Ces URLs ne fonctionnent pas pour l'utilisateur final car le serveur d'arrière-plan est hors d'atteinte.

On peut, dans ce cas, utiliser mod_substitute pour réécrire ces URLs afin qu'elles soit utilisables dans la partie située derrière le mandataire :

Réécriture des URLs intégrées à un contenu mandaté

ProxyPass        "/blog/" "http://internal.blog.example.com/"
ProxyPassReverse "/blog/" "http://internal.blog.example.com/"

Substitute "s|http://internal.blog.example.com/|http://www.example.com/blog/|i"

La directive ProxyPassReverse modifie tout en-tête Location (redirection) envoyé par le serveur d'arrière-plan et, dans cet exemple, la directive Substitute se charge à son tour de la modification de la réponse HTML.

top

Directive SubstituteInheritBefore

Description:Modifie l'ordre de fusion des modèles hérités
Syntaxe:SubstituteInheritBefore on|off
Défaut:SubstituteInheritBefore on
Contexte:répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_substitute
Compatibilité:Disponible à partir de la version 2.4.17 du serveur HTTP Apache

Cette directive permet de définir si l'on applique les modèles Substitute hérités en premier (valeur on), ou après ceux du contexte courant (valeur off). La valeur de la directive SubstituteInheritBefore est elle-même héritée, et les contextes qui en héritent (ceux qui ne définissent pas explicitement leur propre directive SubstituteInheritBefore) appliqueront donc l'ordre de fusion défini le plus proche.

top

Directive SubstituteMaxLineLength

Description:Définit la longueur de ligne maximale
Syntaxe:SubstituteMaxLineLength octets(b|B|k|K|m|M|g|G)
Défaut:SubstituteMaxLineLength 1m
Contexte:répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_substitute
Compatibilité:Disponible à partir de la version 2.4.11 du serveur HTTP Apache

La taille de la ligne traitée par mod_substitute est limitée afin de restreindre l'utilisation des ressources mémoire. La directive SubstituteMaxLineLength permet de définir cette limite. La valeur de la limite peut être spécifiée sous la forme d'un nombre d'octets, et peut être suffixée par une des lettres b, B, k, K, m, M, g ou G pour fournir une valeur respectivement en octets, kiloOctets, mégaOctets ou gigaOctets.

Example

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    SubstituteMaxLineLength 10m
    Substitute "s/foo/bar/ni"
</Location>

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_unique_id.html.fr.utf80000664000175100017510000004263314740503670022626 0ustar covenercovener mod_unique_id - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_unique_id

Langues Disponibles:  en  |  fr  |  ja  |  ko 

Description:Fournit une variable d'environnement contenant un identifiant unique pour chaque requête
Statut:Extension
Identificateur de Module:unique_id_module
Fichier Source:mod_unique_id.c

Sommaire

Ce module fournit un identifiant dont l'unicité est garantie parmi "toutes" les requêtes sous des conditions très précises. L'identifiant unique le sera aussi parmi plusieurs machines appartenant à un cluster correctement configuré. L'identifiant est affecté à la variable d'environnement UNIQUE_ID pour chaque requête. Les identifiants uniques sont utiles pour diverses raisons dont la nature se situe au delà de la portée de ce document.

Support Apache!

Sujets

Directives

Ce module ne fournit aucune directive.

Traitement des bugs

Voir aussi

top

Théorie

Tout d'abord un bref rappel de la manière dont le serveur Apache fonctionne sous Unix (cette fonctionnalité n'étant actuellement pas supportée sous Windows NT). Sous Unix, Apache crée plusieurs processus enfants, ces derniers traitant les requêtes une par une. Chaque processus enfant peut traiter plusieurs requêtes pendant sa durée de vie. Dans le cadre de cette discussion, nous supposerons que les différents processus enfants ne s'échangent pas de données entre eux. Nous nous référerons aux processus enfants sous le nom de processus httpd.

Votre site web est réparti entre une ou plusieurs machines dont vous êtes l'administrateur, et que nous nommerons cluster de serveurs. Chaque serveur peut exécuter plusieurs instances d'Apache. L'ensemble de ces dernières sera considéré comme "l'Univers", et sous certaines hypothèses, nous montrerons qu'il est possible dans cet univers, de générer des identifiants uniques pour chaque requête, sans pour autant nécessiter une communication importante entre les différents serveurs du cluster.

Les machines de votre cluster doivent satisfaire ces conditions (même si le cluster ne comporte qu'une machine, vous devez synchroniser son horloge avec NTP) :

Au vu des caractéristiques actuelles du système d'exploitation, nous supposerons que les pids (identifiants processus) sont codés sur 32 bits. Si le système d'exploitation utilise plus de 32 bits pour un pid, la correction est triviale mais doit être effectuée dans le code.

Ces hypothèses posées, à un instant donné, nous pouvons distinguer tout processus httpd sur toute machine du cluster de tous les autres processus httpd. Pour ce faire, il suffit d'utiliser l'adresse IP de la machine et le pid du processus httpd. Un processus httpd peut traiter plusieurs requêtes simultanément si vous utilisez un module MPM multi-threadé. Pour identifier les threads, Apache httpd utilise en interne un index de threads. Ainsi, afin de générer des identifiants uniques pour chaque requête, il suffit d'effectuer une distinction en fonction du temps.

Pour déterminer le temps, nous utiliserons un repère de temps Unix (les secondes écoulées depuis le 1er janvier 1970 UTC), et un compteur 16 bits. La précision du repère de temps n'étant que d'une seconde, le compteur va représenter 65536 valeurs par seconde. Le quadruplet (adresse IP, pid, repère de temps, compteur) est en mesure de distinguer 65536 requêtes par seconde par processus httpd. Il peut cependant arriver que le même pid soit réutilisé au cours du temps, et le compteur est là pour pallier cet inconvénient.

Lorsqu'un processus enfant httpd est créé, le compteur est initialisé avec (nombre de microsecondes actuel divisé par 10) modulo 65536 (cette formule a été choisie pour éliminer certains problème de variance avec les bits de poids faibles du compteur de microsecondes sur certains systèmes). Lorsqu'un identifiant unique est généré, le repère de temps utilisé est le moment où la requête arrive sur le serveur web. Le compteur est incrémenté à chaque création d'identifiant (et peut repasser à 0 lorsqu'il a atteint sa valeur maximale).

Le noyau génère un pid pour chaque processus lors de sa création, et le compteur de pid est réinitialisé à une certaine valeur lorsqu'il a atteint sa valeur maximale (les pid sont codés sur 16 bits sous de nombreux Unixes, mais les systèmes les plus récents les ont étendus à 32 bits). La même valeur de pid pourra donc être réutilisée au cours du temps. Cependant, tant qu'elle n'est pas réutilisée dans la même seconde, elle ne remet pas en cause l'unicité de notre quadruplet. Nous supposerons donc que le système ne créera pas plus de 65536 processus en une seconde (ce nombre peut être de 32768 sous certains Unixes, mais même dans ce cas, on est en général loin de cette situation).

Il est possible que le temps se répète pour une raison quelconque. Supposons par exemple que l'horloge système soit retardée et repasse par un temps passé (ou bien, comme elle avançait, elle a été remise à l'heure, et elle repasse par un temps futur). Dans ce cas, il peut être facilement démontré que le couple pid/repère de temps peut être réutilisé. Le choix de la formule d'initialisation du compteur a été effectué dans l'intention de pallier ce problème. Notez qu'un nombre vraiment aléatoire serait souhaitable pour initialiser le compteur, mais il n'existe pas de tel nombre directement lisible sur la plupart des systèmes (c'est à dire que vous ne pouvez pas utiliser rand() car vous devez déclencher le générateur avec une valeur unique, et vous ne pouvez pas utiliser le temps à cet effet car celui-ci , au moins à la seconde près, s'est répété). Il ne s'agit donc pas d'une défense parfaite.

Même si elle n'est pas parfaite, quel est le degré d'efficacité de cette défense ? Supposons qu'une de vos machines serve au plus 500 requêtes par seconde (ce qui constitue une limite supérieure très raisonnable au moment où ce document est écrit, car les systèmes ne se contentent en général pas de débiter des fichiers statiques). Pour y parvenir, un certain nombre de processus enfants sera nécessaire, qui dépendra du nombre de clients simultanés présents. Mais soyons pessimiste et supposons qu'un seul processus enfant soit capable de servir 500 requêtes par secondes. Il existe 1000 valeurs de démarrage possibles du compteur pour lesquelles deux séquences de 500 requêtes puissent se recouvrir. Il y a donc 1,5% de chance que le processus enfant répète une valeur de compteur si le temps se répète (avec une résolution d'une seconde), et l'unicité sera alors remise en cause. C'est cependant un exemple très pessimiste, et avec les valeurs du monde réel, il y a bien moins de chances que cela ne se produise. Si vous estimez que ceci a tout de même quelque chances de se produire sur votre système, vous pouvez migrer vers un compteur à 32 bits (en modifiant le code).

On pourrait supposer que ceci a plus de chance de se produire lors du passage à l'heure d'hiver où l'horloge est "retardée". Cela ne constitue cependant pas un problème car les temps pris en compte ici sont des temps UTC, qui vont "toujours" de l'avant. Notez que les Unixes à base de processeur x86 peuvent nécessiter une configuration particulière pour que ceci soit vrai -- il doivent être configurés pour assumer que l'horloge système est en UTC et compenser de manière appropriée. Mais même dans ce cas, si vous utilisez NTP, votre temps UTC sera correct peu après le redémarrage.

La variable d'environnement UNIQUE_ID est construite par codage du quadruplet de 144 bits (adresse IP sur 32 bits, pid sur 32 bits, repère de temps sur 32 bits, compteur 16 bits et index de threads sur 32 bits) en utilisant l'alphabet [A-Za-z0-9@-] d'une manière similaire à celle du codage MIME base64, et sa valeur se présente sous la forme d'une chaîne de 24 caractères. L'alphabet MIME base64 est en fait [A-Za-z0-9+/] ; cependant, les caractères + et / nécessitent un codage particulier dans les URLs, ce qui rend leur utilisation peu commode. Toutes les valeurs sont codées dans l'ordre des octets d'une adresse réseau de façon à ce que le codage soit comparable entre des architectures où l'ordre des octets est différent. L'ordre réel de codage est : repère de temps, adresse IP, pid, compteur. Cet ordre de codage possède un but précis, mais il faut souligner que les applications n'ont aucun intérêt à entrer dans les détails de ce codage. Les applications doivent se contenter de traiter la variable UNIQUE_ID comme un symbole opaque, qui peut être comparé avec d'autres UNIQUE_IDs en ne testant que leur égalité.

L'ordre a été choisi de façon à ce qu'il soit possible de modifier le codage dans le futur sans avoir à se préoccuper de conflits éventuels avec une base de données de UNIQUE_IDs existante. Les nouveaux codages doivent conserver le repère de temps comme premier élément, et pour le reste, utiliser les même alphabet et longueur en bits. Comme les repères de temps constituent essentiellement un séquence croissante, il suffit que toutes les machines du cluster arrêtent de traiter toute requête dans la même seconde repère, et n'utilisent alors plus l'ancien format de codage. Ensuite, elles peuvent reprendre le traitement des requêtes en utilisant les nouveaux codages.

Nous pensons que ceci apporte une solution relativement portable au problème. Les identifiants générés possèdent une durée de vie pratiquement infinie car les identifiants futurs pourront être allongés selon les besoins. Pratiquement aucune communication n'est requise entre les machines du cluster (seule la synchronisation NTP est requise, ce qui représente une charge très faible), et aucune communication entre les processus httpd n'est nécessaire (la communication est implicite et incluse dans le pid assigné par le noyau). Dans des situations très spécifiques, l'identifiant peut être raccourci, mais dans ce cas, d'avantage d'informations doivent être admises (par exemple, les 32 bits de l'adresse IP sont excessifs pour la plupart des sites, mais il n'existe pas de valeur de remplacement portable plus courte).

Langues Disponibles:  en  |  fr  |  ja  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_usertrack.html.fr.utf80000664000175100017510000005165314740503670022651 0ustar covenercovener mod_usertrack - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_usertrack

Langues Disponibles:  en  |  fr 

Description: Journalisation Clickstream des liens parcourus par un utilisateur sur un site
Statut:Extension
Identificateur de Module:usertrack_module
Fichier Source:mod_usertrack.c

Sommaire

Ce module permet de suivre le parcours d'un utilisateur à travers votre site web en faisant appel aux cookies de navigateur.

Support Apache!

Sujets

Directives

Traitement des bugs

Voir aussi

top

Journalisation

mod_usertrack définit un cookie qui peut être journalisé via les formats configurables du module mod_log_config :

LogFormat "%{Apache}n %r %t" usertrack
CustomLog "logs/clickstream.log" usertrack
top

Directive CookieDomain

Description:Le domaine auquel le cookie traceur s'applique
Syntaxe:CookieDomain domaine
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack

Cette directive permet de définir le domaine auquel le cookie traceur s'applique. Si elle n'est pas présente, aucun domaine n'est inclus dans le champ d'en-tête cookie.

La chaîne dommaine doit commencer par un point, et doit comporter au moins un point entouré d'autres caractères. Par exemple, .example.com est une chaîne valide, mais www.example.com et .com ne le sont pas.

La plupart des navigateurs utilisés actuellement n'autorisent pas la définition de cookies pour un domaine racine de deux niveaux, tel que .co.uk, bien qu'un tel domaine remplisse les conditions de validité décrites ci-dessus.
Ces domaines sont équivalents à des domaines racines comme .com, et autoriser de tels cookies peut constituer un risque en matière de sécurité. Ainsi, si vous vous situez sous un domaine racine de deux niveaux, vous devez encore utiliser votre domaine véritable, comme vous le feriez avec tout autre domaine racine (par exemple .example.co.uk).
CookieDomain .example.com
top

Directive CookieExpires

Description:Durée avant expiration du cookie traceur
Syntaxe:CookieExpires durée
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack

Lorsqu'elle est utilisée, cette directive définit une durée avant l'expiration du cookie généré par le module usertrack. La durée peut être spécifiée sous la forme d'un nombre de secondes, ou sous une forme du style "2 weeks 3 days 7 hours". les termes valides sont : years, months, weeks, days, hours, minutes et seconds. Si la durée est spécifiée dans un format autre qu'un nombre de secondes, elle doit être entourée de guillemets.

Si cette directive est absente, la durée de vie des cookies est limitée à la session actuelle du navigateur.

CookieExpires "3 weeks"
top

Directive CookieHTTPOnly

Description:Ajoute l'attribut 'HTTPOnly' au cookie
Syntaxe:CookieHTTPOnly on|off
Défaut:CookieHTTPOnly off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

Lorsqu'elle est définie à 'ON', cette directive ajoute l'attribut 'HTTPOnly' au cookie de traçage. Cet attribut indique aux navigateurs qu'ils doivent bloquer javascript au cours de la lecture de la valeur du cookie.

top

Directive CookieName

Description:Nom du cookie traceur
Syntaxe:CookieName symbole
Défaut:CookieName Apache
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack

Cette directive vous permet de modifier le nom du cookie que ce module utilise pour sa journalisation. Le nom par défaut du cookie est "Apache".

Vous devez spécifier un nom de cookie valide ; les résultats sont imprévisibles si vous utilisez un nom contenant des caractères inhabituels. Les caractères valides font partie des intervales A-Z, a-z, 0-9, "_", et "-".

CookieName clicktrack
top

Directive CookieSameSite

Description:Ajoute l'attribut 'SameSite' au cookie
Syntaxe:CookieSameSite None|Lax|Strict
Défaut:unset
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

Lorsque cette directive est définie à 'None', 'Lax', ou 'Strict', l'attribut 'SameSite' est ajouté au cookie de traçage avec la valeur correspondante. Cet attribut indique aux navigateurs de quelle manière ils doivent traiter le cookie lorsqu'il est demandé dans un contexte cross-site.

'None' définit l'attribut 'SameSite' à 'None', ce qui correspond à la configuration la plus permissive. Pour ne pas ajouter cet attribut au cookie, il est donc préférable de ne pas définir du tout cette directive.

top

Directive CookieSecure

Description:Ajoute l'attribut 'Secure' au cookie
Syntaxe:CookieSecure on|off
Défaut:CookieSecure off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack
Compatibilité:Disponible à partir de la version 2.4.42 du serveur HTTP Apache

Lorsqu'elle est définie à 'ON', cette directive ajoute l'attribut 'Secure' au cookie de traçage. Cet attribut indique aux navigateurs qu'il ne doivent transmettre le cookie que via HTTPS.

top

Directive CookieStyle

Description:Format du champ d'en-tête cookie
Syntaxe:CookieStyle Netscape|Cookie|Cookie2|RFC2109|RFC2965
Défaut:CookieStyle Netscape
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack

Cette directive permet de contrôler le format du champ d'en-tête cookie. Les trois formats autorisés sont :

Tous les clients ne supportent pas l'ensemble de ces formats, mais il est conseillé d'utiliser le plus récent qui sera en général supporté par le navigateur utilisé par vos utilisateurs. A l'heure où ce document est écrit, la plupart des navigateurs supportent ces trois formats, Cookie2 étant le format recommandé.

CookieStyle Cookie2
top

Directive CookieTracking

Description:Active le cookie traceur
Syntaxe:CookieTracking on|off
Défaut:CookieTracking off
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Surcharges autorisées:FileInfo
Statut:Extension
Module:mod_usertrack

Lorsque le module mod_usertrack est chargé, et si CookieTracking on est définie, Apache enverra un cookie traceur pour toute nouvelle requête. Cette directive peut être utilisée pour activer ou désactiver ce comportement pour un serveur virtuel ou un répertoire. Par défaut, l'activation de mod_usertrack ne suffit pas pour activer les cookies.

CookieTracking on

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_watchdog.html.fr.utf80000664000175100017510000002047714740503670022446 0ustar covenercovener mod_watchdog - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Module Apache mod_watchdog

Langues Disponibles:  en  |  fr 

Description:Fournit une infrastructure permettant à d'autres modules d'exécuter des tâches périodiques.
Statut:Base
Identificateur de Module:watchdog_module
Fichier Source:mod_watchdog.c
Compatibilité:Disponible à partir de la version 2.3 du serveur HTTP Apache

Sommaire

Le module mod_watchdog définit des branchements (hooks) programmés pour permettre à d'autres modules d'exécuter des tâches périodiques. Ces modules peuvent enregistrer des gestionnaires (handlers) pour les branchements de mod_watchdog. Actuellement, seuls les modules suivants de la distribution Apache utilisent cette fonctionnalité :

Pour qu'un module puisse utiliser la fonctionnalité de mod_watchdog, ce dernier doit être lié statiquement avec le serveur httpd ; s'il a été lié dynamiquement, il doit être chargé avant l'appel au module qui doit utiliser sa fonctionnalité.
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive WatchdogInterval

Description:Intervalle Watchdog en secondes
Syntaxe:WatchdogInterval time-interval[s]
Défaut:WatchdogInterval 1
Contexte:configuration globale
Statut:Base
Module:mod_watchdog

Cette directive permet de définir l'intervalle entre chaque exécution du branchement watchdog. La valeur par défaut est de 1 seconde.

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_common.html.fr.utf80000664000175100017510000022036714740503670022150 0ustar covenercovener mpm_common - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Apache MPM : Directives Communes

Langues Disponibles:  de  |  en  |  fr  |  ja  |  tr 

Description:Une série de directives implémentées par plusieurs modules multi-processus (MPM)
Statut:MPM
Support Apache!

Directives

Traitement des bugs

Voir aussi

top

Directive CoreDumpDirectory

Description:Le répertoire dans lequel le serveur HTTP Apache va tenter de se positionner avant d'effectuer un vidage mémoire
Syntaxe:CoreDumpDirectory répertoire
Défaut:Voir ci-dessous pour le répertoire par défaut
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork

Cette directive permet de définir le répertoire dans lequel Apache httpd va tenter de se positionner avant d'effectuer un vidage mémoire sur disque. Si votre système d'exploitation est configuré pour créer des fichiers de vidage mémoire dans le répertoire de travail des processus qui se sont crashés, CoreDumpDirectory est nécessaire pour définir un répertoire de travail autre que le répertoire par défaut ServerRoot, ce répertoire de travail ne devant pas être accessible en écriture par l'utilisateur sous lequel le serveur s'exécute.

Si vous avez besoin d'un vidage mémoire pour le débogage, vous pouvez utiliser cette directive pour le placer à un endroit différent. Cette directive n'a aucun effet si votre système d'exploitation n'est pas configuré pour créer des fichiers de vidage mémoire dans le répertoire de travail des processus qui se sont crashés.

Note de sécurité pour les systèmes de type Linux

Utiliser cette directive sous Linux peut permettre aux autres processus du système s'exécutant avec les même privilèges (comme les scripts CGI) de se rattacher aux processus httpd enfants via l'appel système ptrace. La protection contre certaines attaques engageant la sécurité peut s'en trouver affectée. Il est par conséquent déconseillé d'utiliser cette directive sur les systèmes en production.

Vidages mémoire sous Linux

Si Apache httpd est démarré sous l'utilisateur root puis bascule vers un autre utilisateur, le noyau Linux désactive les vidages mémoire, même si le répertoire est accessible en écriture au processus. Apache httpd (versions 2.0.46 et supérieures) réactive les vidages mémoire sous Linux 2.4 et au delà, mais seulement si vous définissez une directive CoreDumpDirectory.

Vidages mémoire sous BSD

Pour activer le vidage mémoire des exécutables suid sur les systèmes de style BSD (comme FreeBSD), définissez kern.sugid_coredump à 1.

Signaux spécifiques

CoreDumpDirectory n'est traité qu'à la reception d'un certain nombre de signaux , SIGFPE, SIGILL, SIGABORT, SIGSEGV, et SIGBUS.

Sur certains systèmes d'exploitation, SIGQUIT provoque aussi un vidage mémoire, mais n'est pas traité par les directives CoreDumpDirectory ou EnableExceptionHook, si bien que la définition du répertoire d'enregistrement du vidage mémoire est entièrement dévolue au système d'exploitation.

top

Directive EnableExceptionHook

Description:Active un hook ("point d'accrochage logiciel") qui exécute des gestionnaires d'exception après un crash
Syntaxe:EnableExceptionHook On|Off
Défaut:EnableExceptionHook Off
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork

Pour des raisons de sécurité, cette directive n'est disponible que si la compilation du serveur a été configurée avec l'option --enable-exception-hook. Elle permet d'activer un hook ("point d'accrochage logiciel") qui autorise certains modules externes à effectuer un branchement et accomplir telle ou telle action après le crash d'un processus enfant.

Deux modules, mod_whatkilledus et mod_backtrace utilisent ce hook. Veuillez vous référer à la page EnableExceptionHook de Jeff Trawick pour plus d'informations à leur sujet.

top

Directive GracefulShutdownTimeout

Description:Spécifie le délai maximum après lequel le serveur va s'arrêter dans le cas d'un arrêt "en douceur"
Syntaxe:GracefulShutdownTimeout seconds
Défaut:GracefulShutdownTimeout 0
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork
Compatibilité:Disponible dans les versions 2.2 et supérieures

La directive GracefulShutdownTimeout permet de spécifier le temps, en secondes, pendant lequel le serveur va continuer à fonctionner après avoir reçu un signal "graceful-stop" ("Arrêt en douceur"), afin de terminer le traitement des connexions en cours.

Définir cette valeur à zéro signifie au serveur d'attendre jusqu'à ce que toutes les requêtes en cours aient été traitées.

top

Directive Listen

Description:Les adresses IP et ports sur lesquels le serveur écoute
Syntaxe:Listen [adresse IP:]numéro port [protocole]
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
Compatibilité:L'argument protocole est supporté depuis la version 2.1.5

La directive Listen permet de signifier à Apache httpd de ne se mettre à l'écoute que sur les adresses IP et ports spécifiés ; par défaut, le serveur répond aux requêtes en provenance de toutes les interfaces réseau. La directive Listen est dorénavant requise, et si elle est absente du fichier de configuration, le serveur refusera de démarrer. Ceci constitue un changement par rapport aux versions précédentes d'Apache httpd.

La directive Listen signifie au serveur de n'accepter les requêtes entrantes que vers le port ou le couple adresse-port spécifié. Si seulement un port est spécifié, le serveur se met à l'écoute sur ce port sur toutes les interfaces réseau. Si une adresse IP et un port sont spécifiés, le serveur va se mettre à l'écoute sur ce port sur l'interface réseau correspondant à l'adresse IP.

On peut utiliser autant de directives Listen que nécessaire pour spécifier plusieurs adresses et/ou ports à écouter. Le serveur répondra aux requêtes vers tous les adresses et ports spécifiés.

Par exemple, pour que le serveur accepte les connexions sur les ports 80 et 8000, utilisez :

Listen 80
Listen 8000

Pour que le serveur accepte les connexions sur deux interfaces et ports particuliers, spécifiez :

Listen 192.170.2.1:80
Listen 192.170.2.5:8000

Les adressee IPv6 doivent être entourées de crochets, comme dans l'exemple suivant :

Listen [2001:db8::a00:20ff:fea7:ccea]:80

L'argument optionnel protocole n'est pas nécessaire dans la plupart des configurations. S'il est absent, https est la valeur par défaut pour le port 443 et http l'est pour tous les autres ports. L'argument protocole sert à déterminer quel module doit traiter une requête, et à appliquer des optimisations spécifiques à certains protocoles à l'aide de la directive AcceptFilter.

La spécification d'un protocole n'est nécessaire que si vous utilisez des ports non standards. Par exemple, pour configurer un site en https sur le port 8443 :

Listen 192.170.2.1:8443 https

Condition d'erreur

Plusieurs directives Listen pour les mêmes adresse IP/port vont provoquer l'envoi d'un message d'erreur Address already in use.

Voir aussi

top

Directive ListenBackLog

Description:Longueur maximale de la liste d'attente des connexions
Syntaxe:ListenBackLog backlog
Défaut:ListenBackLog 511
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

La longueur maximale de la liste d'attente des connexions. En général, aucune modification n'est nécessaire, ni même souhaitable ; cependant, sur certains systèmes, il peut être nécessaire d'en augmenter la valeur en cas d'attaque TCP SYN flood (envoi en masse de requêtes SYN pour saturer le serveur). Voir le paramètre backlog de l'appel système listen(2).

En fait, l'argument backlog sera souvent limité à une valeur inférieure en fonction du système d'exploitation. Notez aussi que de nombreux systèmes d'exploitation ne tiennent pas vraiment compte de la valeur spécifiée pour l'argument backlog, mais s'en inspirent seulement (et choisissent en général une valeur supérieure).

top

Directive ListenCoresBucketsRatio

Description:Rapport entre le nombre de coeurs de processeur activés et le nombre de segments d'écoute
Syntaxe:ListenCoresBucketsRatio ratio
Défaut:ListenCoresBucketsRatio 0 (disabled)
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork
Compatibilité:Disponible à partir de la version 2.4.13 du serveur HTTP Apache, avec un noyau supportant l'option de socket SO_REUSEPORT, et distribuant uniformément les nouvelles connexions aux sockets d'écoute des processus (ou threads) qui l'utilisent (par exemple Linux versions 3.9 et ultérieures, mais pas l'implémentation courante de SO_REUSEPORT par les plateformes de type BSD.

Vous pouvez utiliser la directive ListenCoresBucketsRatio pour spécifier un ratio entre le nombre de coeurs de CPU activés et le nombre de segments d'écoute (listeners' buckets) souhaités ; le serveur HTTP Apache va alors créernum_cpu_cores / ratio segments d'écoute, chacun contenant son propre socket d'écoute Listen sur le ou les mêmes ports ; chaque processus enfant sera associé à un seul segment d'écoute (avec une distribution de type round-robin des segments à la création des processus enfants).

Définition du terme coeur de CPU activé ("online")

Sous Linux et BSD, un coeur de CPU peut être activé ou désactivé si Hotplug a été configuré ; la directive ListenCoresBucketsRatio doit donc tenir compte de ce paramètre pour calculer le nombre de segments d'écoute à créer.

La directive ListenCoresBucketsRatio peut améliorer le support de la montée en charge lorsque l'arrivée de nouvelles connexions est/devient un goulot d'étranglement. Le test de cette fonctionnalité avec des machines possédant un nombre de coeurs de CPU important a permit de constater une amélioration des performances significative et des temps de réponse plus courts.

Pour que cette fonctionnalité soit activée, le nombre de coeurs de CPU doit être égal au moins au double du ratio spécifié. Si vous spécifiez la valeur recommandée pour ratio, à savoir 8, le nombre minimum de coeurs de processeurs disponibles sera alors de 16. La valeur optimale de ratio permettant d'obtenir des performances maximales doit être calculée pour chaque système cible, en testant plusieurs valeurs et en observant les résultats.

Cette directive influence le calcul des valeurs limites inférieures de MinSpareThreads et MaxSpareThreads. En effet, pour accepter les connexions de manière optimale, le nombre de processus enfants doit être un multiple du nombre de segments d'écoute.

Cas où plusieurs Listeners ou serveurs HTTP Apache partagent la même adresse IP et port

La définition de l'option SO_REUSEPORT pour les sockets d'écoute permet à plusieurs processus (partageant le même EUID, par exemple root) de se rattacher à la même adresse IP et port, sans obtenir l'erreur de rattachement que le système génère habituellement lorsque ce cas se produit.

Cela signifie aussi que plusieurs instances d'Apache httpd configurées avec le même IP:port et avec une valeur ListenCoresBucketsRatio positive pourraient démarrer sans erreur, et fonctionner ensuite avec une répartition uniforme des connexions entrantes sur ces différentes instances (ce n'est PAS une recommandation et ne constitue pas un usage approprié à tous les cas, mais juste un avertissement sur le fait qu'un véritable problème de rattachement multiple à un IP:port pourrait alors être occulté).

Au sein d'une même instance, Apache httpd vérifie la présence de directives Listen multiples avec la même adresse IP (ou nom d'hôte) et le même port, et refuse de démarrer si c'est le cas, ce qui permet d'éviter la création de segments d'écoute dupliqués qui seraient du coup inutiles et affecteraient les performances. Cependant, il ne peut pas (et n'essaiera pas de le faire) intercepter tous les cas possibles de recouvrement (comme un nom d'hôte correspondant à une adresse IP utilisée quelque part ailleurs).

top

Directive MaxConnectionsPerChild

Description:Limite le nombre de connexions qu'un processus enfant va traiter au cours de son fonctionnement
Syntaxe:MaxConnectionsPerChild number
Défaut:MaxConnectionsPerChild 0
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
Compatibilité:Disponible depuis la version 2.3.9 du serveur HTTP Apache. L'ancien nom MaxRequestsPerChild est encore supporté.

La directive MaxConnectionsPerChild permet de définir le nombre maximum de connexions qu'un processus enfant va pouvoir traiter au cours de son fonctionnement. Lorsqu'il a traité MaxConnectionsPerChild connexions, le processus enfant est arrêté. Si MaxConnectionsPerChild est définie à 0, il n'y a plus aucune limite sur le nombre de connexions que le processus pourra traiter.

Définir MaxConnectionsPerChild à une valeur non nulle limite la quantité de mémoire qu'un processus peut consommer à cause de fuites (accidentelles) de mémoire.

top

Directive MaxMemFree

Description:Quantité maximale de mémoire que l'allocateur principal est autorisé à conserver sans appeler free()
Syntaxe:MaxMemFree KOctets
Défaut:MaxMemFree 2048
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware

La directive MaxMemFree permet de définir le nombre maximum de KOctets libres que tout allocateur est autorisé à conserver sans appeler free(). Dans les MPMs threadés, chaque thread possède son propre allocateur. Si elle est définie à 0, la quantité de mémoire libre que peut conserver un allocateur est illimitée.

top

Directive MaxRequestWorkers

Description:Nombre maximum de connexions pouvant être traitées simultanément
Syntaxe:MaxRequestWorkers nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork

La directive MaxRequestWorkers permet de fixer le nombre maximum de requêtes pouvant être traitées simultanément. Si la limite MaxRequestWorkers est atteinte, toute tentative de connexion sera normalement mise dans une file d'attente, et ceci jusqu'à un certain nombre dépendant de la directive ListenBacklog. Lorsqu'un processus enfant se libèrera suite à la fin du traitement d'une requête, la connexion en attente pourra être traitée à son tour.

Pour les serveurs non threadés (c'est à dire utilisant prefork), la directive MaxRequestWorkers définit alors le nombre maximum de processus enfants qui pourront être lancés simultanément pour traiter les requêtes. La valeur par défaut est 256 ; si vous l'augmentez, vous devez aussi augmenter la valeur de la directive ServerLimit.

Pour les serveur threadés et hybrides (utilisant par exemple event ou worker), MaxRequestWorkers définit alors le nombre total de threads qui seront disponibles pour servir les clients. Dans le cas des MPMs hybrides, la valeur par défaut est 16 (directive ServerLimit) multiplié par la valeur 25 (directive ThreadsPerChild). Par conséquent, pour affecter à la directive MaxRequestWorkers une valeur qui requiert plus de 16 processus, vous devez aussi augmenter la valeur de la directive ServerLimit.

Le nom de la directive MaxRequestWorkers était MaxClients avant la version 2.3.13. Cet ancien nom est encore supporté.

top

Directive MaxSpareThreads

Description:Nombre maximum de threads inactifs
Syntaxe:MaxSpareThreads nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:event, worker, mpm_netware, mpmt_os2

C'est le nombre maximum de threads inactifs. Les MPMs utilisent cette directive de différentes manières.

Pour worker et event, la définition par défaut est MaxSpareThreads 250. Ce MPM gère les threads inactifs au niveau du serveur. Si le serveur possède trop de threads inactifs, des processus enfants seront arrêtés jusqu'à ce que le nombre de threads inactifs repasse en dessous de cette limite. Des processus/threads supplémentaires sont susceptibles d'être créés si ListenCoresBucketsRatio est activée.

Pour mpm_netware, la définition par défaut est MaxSpareThreads 100. Comme ce MPM n'exécute qu'un seul processus, le nombre de processus inactifs est surveillé au niveau du serveur.

mpmt_os2 fonctionne de manière similaire à mpm_netware. Pour mpmt_os2, la valeur par défaut est 10.

Contraintes

La gamme de valeurs pour MaxSpareThreads est limitée. Apache httpd corrigera automatiquement cette valeur selon les règles suivantes :

Voir aussi

top

Directive MinSpareThreads

Description:Nombre minimum de threads inactifs qui seront disponibles pour pouvoir traiter les pics de requêtes
Syntaxe:MinSpareThreads nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:event, worker, mpm_netware, mpmt_os2

C'est le nombre minimum de threads inactifs pour être en mesure de traiter les pics de requêtes. Les MPMs utilisent cette directive de différentes manières.

Avec worker et event, la définition par défaut est MinSpareThreads 75, et le nombre de threads inactifs est surveillé au niveau du serveur. Si le serveur ne possède pas assez de threads inactifs, des processus enfants sont créés jusqu'à ce que le nombre de threads inactifs repasse au dessus de nombre. Des processus/threads supplémentaires peuvent être créés si ListenCoresBucketsRatio est activée.

Avec mpm_netware, la définition par défaut est MinSpareThreads 10 et, comme ce MPM n'exécute qu'un seul processus, le nombre de threads est surveillé au niveau général du serveur.

mpmt_os2 fonctionne de manière similaire à mpm_netware. Pour mpmt_os2, la valeur par défaut est 5.

Voir aussi

top

Directive PidFile

Description:Ficher dans lequel le serveur enregistre l'identificateur de processus du démon
Syntaxe:PidFile nom fichier
Défaut:PidFile logs/httpd.pid
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt, mpmt_os2

La directive PidFile permet de définir le ficher dans lequel le serveur enregistre l'identificateur de processus du démon. Si le chemin du fichier n'est pas absolu, il est considéré comme relatif au chemin défini par la directive ServerRoot.

Exemple

PidFile /var/run/apache.pid

Il est souvent utile de pouvoir envoyer un signal au serveur afin qu'il ferme et ouvre à nouveau ses journaux d'erreur et de transfert, et recharge son fichier de configuration. Pour ce faire, on envoie un signal SIGHUP (kill -1) à l'identificateur de processus enregistré dans le fichier défini par la directive PidFile.

La directive PidFile fait l'objet des mêmes avertissements que ceux concernant le chemin d'enregistrement des fichiers journaux et la sécurité.

Note

Depuis la version 2 du serveur HTTP Apache, nous recommandons de n'utiliser que le script apachectl, ou le script de démarrage fourni avec votre système d'exploitation pour (re)démarrer ou arrêter le serveur.

top

Directive ReceiveBufferSize

Description:Taille du tampon TCP en entrée
Syntaxe:ReceiveBufferSize octets
Défaut:ReceiveBufferSize 0
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

Le serveur va fixer la taille du tampon TCP en entrée au nombre d'octets spécifié.

Si la directive est définie à 0, le serveur va utiliser la valeur par défaut adoptée par le système d'exploitation.

top

Directive ScoreBoardFile

Description:Chemin du fichier où sont stockées les données concernant la coordination des processus enfants
Syntaxe:ScoreBoardFile chemin fichier
Défaut:ScoreBoardFile logs/apache_runtime_status
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt

Le serveur HTTP Apache utilise un tableau de bord pour la communication entre le processus parent et les processus enfants. Pour faciliter cette communication, certaines architectures nécessitent un fichier. En l'absence de cette directive, donc si aucun nom de fichier n'est spécifié, Apache httpd tentera tout d'abord de créer un tableau uniquement en mémoire (en utilisant la mémoire partagée anonyme) ; et si il n'y parvient pas, il tentera de créer un fichier sur disque (en utilisant la mémoire partagée à base de fichier). Si cette directive est utilisée, Apache httpd créera systématiquement un fichier sur disque.

Exemple

ScoreBoardFile /var/run/apache_runtime_status

Une mémoire partagée sous forme de fichier est utile pour les applications tierces qui nécessitent un accès direct au tableau de bord des processus.

Si vous utilisez un ScoreBoardFile, vous pourrez constater une amélioration des performances en le plaçant sur un disque virtuel en RAM. Assurez-vous cependant de tenir compte des mêmes avertissements que ceux concernant le chemin du fichier journal et la sécurité.

Voir aussi

top

Directive SendBufferSize

Description:Taille du tampon TCP en sortie
Syntaxe:SendBufferSize octets
Défaut:SendBufferSize 0
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

Définit la taille du tampon TCP en sortie avec le nombre d'octets spécifié. Ceci s'avère souvent très utile pour augmenter les valeurs par défaut standards du passé des systèmes d'exploitation pour les transmissions à grande vitesse et haute densité (c'est à dire de l'ordre de 100ms comme sur les liaisons rapides transcontinentales).

Si la directive est définie à 0, le serveur va utiliser la valeur par défaut adoptée par le système d'exploitation.

L'amélioration des performances des connexions à grande vitesse et à temps de latence élevé, peut nécessiter une intervention au niveau de la configuration de votre système d'exploitation.

Sous certains systèmes d'exploitation, la modification du comportement TCP via une augmentation de la valeur de SendBufferSize risque de ne pas être perceptible, si la directive EnableSendfile n'est pas définie à OFF. Cette interaction ne s'applique qu'aux fichiers statiques.

top

Directive ServerLimit

Description:Limite supérieure de la définition du nombre de processus
Syntaxe:ServerLimit nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork

Avec le MPM prefork, cette directive définit le nombre maximum que l'on peut affecter à la directive MaxRequestWorkers, et ceci pour la durée de vie du processus Apache httpd. Avec les MPMs worker et event, cette directive, en combinaison avec ThreadLimit, définit le nombre maximum que l'on peut affecter à MaxRequestWorkers, et ceci pour la durée de vie du processus Apache httpd. Avec le MPM event, cette directive permet aussi de définir le nombre de processus anciens du serveur pouvant continuer à s'exécuter pour terminer le traitement des connexions ouvertes. Au cours d'un redémarrage, vous pouvez modifier la valeur de la directive MaxRequestWorkers, alors que toute tentative de modification de la valeur de la directive ServerLimit sera ignorée.

Cette directive doit être utilisée avec précaution. Si ServerLimit est définie à une valeur beaucoup plus grande que nécessaire, de la mémoire partagée supplémentaire sera inutilement allouée. Si à la fois ServerLimit et MaxRequestWorkers possèdent des valeurs supérieures à ce que le système peut supporter, ce dernier peut devenir instable ou Apache httpd peut tout simplement refuser de démarrer.

Avec les MPMs prefork et event, n'utilisez cette directive que si vous devez définir MaxRequestWorkers à une valeur supérieure à 256 (valeur par défaut). N'affectez pas à la directive ServerLimit une valeur supérieure à celle que vous avez prévu d'affecter à la directive MaxRequestWorkers.

Avec worker, n'utilisez cette directive que si la définition de vos directives MaxRequestWorkers et ThreadsPerChild nécessitent plus de 16 processus serveurs (valeur par défaut). N'affectez pas à la directive ServerLimit une valeur supérieure au nombre de processus requis pour la définition des directives MaxRequestWorkers et ThreadsPerChild.

Note

Il existe une limite de ServerLimit 20000 codée en dur dans le serveur (200000 pour le MPM prefork). Ceci est censé éviter les effets désastreux que pourrait provoquer une faute de frappe. Pour dépasser cette limite, vous devez modifier la valeur de MAX_SERVER_LIMIT dans le fichier source du mpm et recompiler le serveur.

Voir aussi

top

Directive StartServers

Description:Nombre de processus enfants du serveur créés au démarrage
Syntaxe:StartServers nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:event, worker, prefork, mpmt_os2

La directive StartServers permet de définir le nombre de processus enfants du serveur créés au démarrage. Comme le nombre de processus est contrôlé dynamiquement en fonction de la charge (voir MinSpareThreads, MaxSpareThreads, MinSpareServers, MaxSpareServers), il n'est en général pas nécessaire d'ajuster ce paramètre.

La valeur par défaut diffère d'un MPM à l'autre. Pour worker et event, la définition par défaut est StartServers 3 ; la valeur par défaut est 5 pour prefork et 2 pour mpmt_os2.

top

Directive StartThreads

Description:Nombre de threads créés au démarrage
Syntaxe:StartThreads nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:mpm_netware

C'est le nombre de threads créés au démarrage du serveur. Comme le nombre de threads est contrôlé dynamiquement en fonction de la charge (voir MinSpareThreads, MaxSpareThreads, MinSpareServers, MaxSpareServers), il n'est en général pas nécessaire d'ajuster ce paramètre.

Pour mpm_netware, la définition par défaut est StartThreads 50 et, comme il n'y a qu'un processus, il s'agit du nombre total de threads créés au démarrage pour servir les requêtes.

top

Directive ThreadLimit

Description:Le nombre de threads maximum que l'on peut définir par processus enfant
Syntaxe:ThreadLimit nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:event, worker, mpm_winnt

Cette directive permet de définir le nombre maximum que l'on peut affecter à la directive ThreadsPerChild pour la durée de vie du processus Apache httpd. La directive ThreadsPerChild peut être modifiée au cours d'un redémarrage jusqu'à la valeur de la directive ThreadLimit, mais toute tentative de modification de la directive ThreadLimit au cours d'un redémarrage sera ignorée.

L'utilisation de cette directive doit faire l'objet de précautions particulières. Si ThreadLimit est définie à une valeur très supérieure à la directive ThreadsPerChild, de la mémoire partagée supplémentaire sera inutilement allouée. Si les directives ThreadLimit et ThreadsPerChild sont définies à des valeurs supérieures à ce que le système peut supporter, ce dernier peut devenir instable, ou Apache httpd peut tout simplement refuser de démarrer. Ne définissez pas cette directive à une valeur supérieure à la valeur maximale que vous pensez affecter à la directive ThreadsPerChild pour le processus Apache httpd en cours d'exécution.

La valeur par défaut de la directive ThreadLimit est 1920 avec mpm_winnt, et 64 avec les autres MPMs.

Note

Il existe une limite de ThreadLimit 20000 (ou ThreadLimit 100000 avec event, ThreadLimit 15000 avec mpm_winnt) codée en dur dans le serveur. Ceci est censé éviter les effets désastreux que pourrait provoquer une faute de frappe. Pour dépasser cette limite, vous devez modifier la valeur de MAX_THREAD_LIMIT dans le fichier source du mpm et recompiler le serveur.

top

Directive ThreadsPerChild

Description:Nombre de threads créés par chaque processus enfant
Syntaxe:ThreadsPerChild nombre
Défaut:Voir ci-dessous pour plus de détails
Contexte:configuration globale
Statut:MPM
Module:event, worker, mpm_winnt

Cette directive permet de définir le nombre de threads que va créer chaque processus enfant. Un processus enfant crée ces threads au démarrage et n'en crée plus d'autres par la suite. Si l'on utilise un MPM comme mpm_winnt qui ne lance qu'un processus enfant, ce nombre doit être suffisamment grand pour supporter la charge du serveur. Avec un MPM comme worker qui lance plusieurs processus enfants, c'est le nombre total de threads qui doit être suffisamment grand pour supporter la charge du serveur.

La valeur par défaut de la directive ThreadsPerChild est 64 avec mpm_winnt, et 25 avec les autres MPMs.

La valeur de la directive ThreadsPerChild ne peut pas dépasser la valeur de la directive ThreadLimit. Si on spécifie une valeur supérieure, elle sera automatiquement réduite au démarrage du serveur et un avertissement sera enregistré dans le journal. La relation entre ces deux directives est expliquée dans la documentation de la directive ThreadLimit.

top

Directive ThreadStackSize

Description:La taille en octets de la pile qu'utilisent les threads qui traitent les connexions clients
Syntaxe:ThreadStackSize taille
Défaut:65536 sous NetWare; varie en fonction des autres systèmes d'exploitation
Contexte:configuration globale
Statut:MPM
Module:event, worker, mpm_winnt, mpm_netware, mpmt_os2
Compatibilité:Disponible dans les versions 2.1 et supérieures du serveur HTTP Apache

La directive ThreadStackSize permet de définir la taille de la pile (pour les données propres) qu'utilisent les threads qui traitent les connexions clients en faisant appel à des modules. Dans la plupart des cas, la valeur par défaut de la taille de la pile du système d'exploitation convient, mais il existe certaines situations où il peut s'avérer nécessaire de l'ajuster :

Il est recommandé de ne pas réduire ThreadStackSize, à moins qu'un grand nombre de threads par processus enfant ne soit nécessaire. Sur certaines plates-formes (y compris Linux), une valeur de 128000 est déjà trop basse et provoque des crashes avec certains modules courants.

Langues Disponibles:  de  |  en  |  fr  |  ja  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpmt_os2.html.fr.utf80000664000175100017510000001772414740503670021550 0ustar covenercovener mpmt_os2 - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Modules

Apache MPM os2

Langues Disponibles:  en  |  fr 

Description:MPM hybride multi-processus, multi-thread pour OS/2
Statut:MPM
Identificateur de Module:mpm_mpmt_os2_module
Fichier Source:mpmt_os2.c

Sommaire

Le serveur se compose d'un processus principal parent, et d'un petit nombre fixe de processus enfants.

La tâche du processus parent consiste à gérer les processus enfants, c'est à dire lancer ces processus de manière à ce qu'il y en ait toujours un nombre égal à la valeur de la directive StartServers pour traiter les connexions.

Chaque processus enfant comporte un jeu de threads esclaves et un thread maître qui accepte les connexions et les distribue aux esclaves via une file de travail. Le jeu de threads esclaves est dynamique et géré par un thread de maintenance de façon à ce que le nombre de threads inactifs soit maintenu entre MinSpareThreads et MaxSpareThreads.

Support Apache!

Directives

Traitement des bugs

Voir aussi

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/index.html.en0000664000175100017510000005537214737542416020235 0ustar covenercovener Module Index - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Module Index

Available Languages:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Below is a list of all of the modules that come as part of the Apache HTTP Server distribution. See also the complete alphabetical list of all Apache HTTP Server directives.

See also

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)
event
A variant of the worker MPM with the goal of consuming threads only for connections with active processing
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
prefork
Implements a non-threaded, pre-forking web server
mpm_winnt
Multi-Processing Module optimized for Windows NT.
worker
Multi-Processing Module implementing a hybrid multi-threaded multi-process web server
top

Other Modules

 A  |  B  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V  |  W  |  X 

mod_access_compat
Group authorizations based on host (name or IP address)
mod_actions
Execute 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_allowmethods
Easily restrict what HTTP methods can be used on the server
mod_asis
Sends files that contain their own HTTP headers
mod_auth_basic
Basic HTTP authentication
mod_auth_digest
User authentication using MD5 Digest Authentication
mod_auth_form
Form authentication
mod_authn_anon
Allows "anonymous" user access to authenticated areas
mod_authn_core
Core Authentication
mod_authn_dbd
User authentication using an SQL database
mod_authn_dbm
User authentication using DBM files
mod_authn_file
User authentication using text files
mod_authn_socache
Manages a cache of authentication credentials to relieve the load on backends
mod_authnz_fcgi
Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
mod_authnz_ldap
Allows an LDAP directory to be used to store the database for HTTP Basic authentication.
mod_authz_core
Core Authorization
mod_authz_dbd
Group Authorization and Login using SQL
mod_authz_dbm
Group authorization using DBM files
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_brotli
Compress content via Brotli before it is delivered to the client
mod_buffer
Support for request buffering
mod_cache
RFC 2616 compliant HTTP caching filter.
mod_cache_disk
Disk based storage module for the HTTP caching filter.
mod_cache_socache
Shared object cache (socache) based storage module for the HTTP caching filter.
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_data
Convert response body into an RFC2397 data URL
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_dialup
Send static content at a bandwidth rate limit, defined by the various old modem standards
mod_dir
Provides for "trailing slash" redirects and serving directory index files
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_hooks
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_heartbeat
Sends messages with server status to frontend proxy
mod_heartmonitor
Centralized monitor for mod_heartbeat origin servers
mod_http2
Support for the HTTP/2 transport layer
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_lbmethod_bybusyness
Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_byrequests
Request Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_bytraffic
Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
mod_lbmethod_heartbeat
Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
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_debug
Additional configurable debug logging
mod_log_forensic
Forensic Logging of the requests made to the server
mod_logio
Logging of input and output bytes per request
mod_lua
Provides Lua hooks into various portions of the httpd request processing
mod_macro
Provides macros within apache httpd runtime configuration files
mod_md
Managing domains across virtual hosts, certificate provisioning via the ACME protocol
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_privileges
Support for Solaris privileges and for running virtual hosts under different user IDs.
mod_proxy
Multi-protocol 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_express
Dynamic mass reverse proxy extension for mod_proxy
mod_proxy_fcgi
FastCGI support module for mod_proxy
mod_proxy_fdpass
fdpass external process support module for mod_proxy
mod_proxy_ftp
FTP support module for mod_proxy
mod_proxy_hcheck
Dynamic health check of Balancer members (workers) for mod_proxy
mod_proxy_html
Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
mod_proxy_http
HTTP support module for mod_proxy
mod_proxy_http2
HTTP/2 support module for mod_proxy
mod_proxy_scgi
SCGI gateway module for mod_proxy
mod_proxy_uwsgi
UWSGI gateway module for mod_proxy
mod_proxy_wstunnel
Websockets support module for mod_proxy
mod_ratelimit
Bandwidth Rate Limiting for Clients
mod_reflector
Reflect a request body as a response via the output filter stack.
mod_remoteip
Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
mod_reqtimeout
Set timeout and minimum data rate for receiving requests
mod_request
Filters to handle and make available HTTP request bodies
mod_rewrite
Provides a rule-based rewriting engine to rewrite requested URLs on the fly
mod_sed
Filter Input (request) and Output (response) content using sed syntax
mod_session
Session support
mod_session_cookie
Cookie based session support
mod_session_crypto
Session encryption support
mod_session_dbd
DBD/SQL based session support
mod_setenvif
Allows the setting of environment variables based on characteristics of the request
mod_slotmem_plain
Slot-based shared memory provider.
mod_slotmem_shm
Slot-based shared memory provider.
mod_so
Loading of executable code and modules into the server at start-up or restart time
mod_socache_dbm
DBM based shared object cache provider.
mod_socache_dc
Distcache based shared object cache provider.
mod_socache_memcache
Memcache based shared object cache provider.
mod_socache_redis
Redis based shared object cache provider.
mod_socache_shmcb
shmcb based shared object cache provider.
mod_speling
Attempts to correct mistaken URLs by ignoring capitalization, or attempting to correct various minor misspellings.
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_substitute
Perform search and replace operations on response bodies
mod_suexec
Allows CGI scripts to run as a specified user and Group
mod_systemd
Provides better support for systemd integration
mod_unique_id
Provides an environment variable with a unique identifier for each request
mod_unixd
Basic (required) security for Unix-family platforms.
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
mod_watchdog
provides infrastructure for other modules to periodically run tasks
mod_xml2enc
Enhanced charset/internationalisation support for libxml2-based filter modules

Available Languages:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/mod/mod_authz_dbd.html.en0000664000175100017510000004431014737542416021717 0ustar covenercovener mod_authz_dbd - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authz_dbd

Available Languages:  en  |  fr 

Description:Group Authorization and Login using SQL
Status:Extension
Module Identifier:authz_dbd_module
Source File:mod_authz_dbd.c
Compatibility:Available in Apache 2.4 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 and mod_authz_dbm, with the exception that this module queries a SQL database to determine whether a user is a member of a group.

This module can also provide database-backed user login/logout capabilities. These are likely to be of most value when used in conjunction with mod_authn_dbd.

This module relies on mod_dbd to specify the backend database driver and connection parameters, and manage the database connections.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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_authz_dbd extends the authorization types with dbd-group, dbd-login and dbd-logout.

Since v2.4.8, expressions are supported within the DBD require directives.

Require dbd-group

This directive specifies group membership that is required for the user to gain access.

Require dbd-group team
AuthzDBDQuery "SELECT user_group FROM authz WHERE user = %s"

Require dbd-login

This directive specifies a query to be run indicating the user has logged in.

Require dbd-login
AuthzDBDQuery "UPDATE authn SET login = 'true' WHERE user = %s"

Require dbd-logout

This directive specifies a query to be run indicating the user has logged out.

Require dbd-logout
AuthzDBDQuery "UPDATE authn SET login = 'false' WHERE user = %s"
top

Database Login

In addition to the standard authorization function of checking group membership, this module can also provide server-side user session management via database-backed login/logout capabilities. Specifically, it can update a user's session status in the database whenever the user visits designated URLs (subject of course to users supplying the necessary credentials).

This works by defining two special Require types: Require dbd-login and Require dbd-logout. For usage details, see the configuration example below.

top

Client Login integration

Some administrators may wish to implement client-side session management that works in concert with the server-side login/logout capabilities offered by this module, for example, by setting or unsetting an HTTP cookie or other such token when a user logs in or out.

To support such integration, mod_authz_dbd exports an optional hook that will be run whenever a user's status is updated in the database. Other session management modules can then use the hook to implement functions that start and end client-side sessions.

top

Configuration example

# mod_dbd configuration
DBDriver pgsql
DBDParams "dbname=apacheauth user=apache pass=xxxxxx"

DBDMin  4
DBDKeep 8
DBDMax  20
DBDExptime 300

<Directory "/usr/www/my.site/team-private/">
  # mod_authn_core and mod_auth_basic configuration
  # for mod_authn_dbd
  AuthType Basic
  AuthName Team
  AuthBasicProvider dbd

  # mod_authn_dbd SQL query to authenticate a logged-in user
  AuthDBDUserPWQuery \
    "SELECT password FROM authn WHERE user = %s AND login = 'true'"

  # mod_authz_core configuration for mod_authz_dbd
  Require dbd-group team

  # mod_authz_dbd configuration
  AuthzDBDQuery "SELECT group FROM authz WHERE user = %s"

  # when a user fails to be authenticated or authorized,
  # invite them to login; this page should provide a link
  # to /team-private/login.html
  ErrorDocument 401 "/login-info.html"

  <Files "login.html">
    # don't require user to already be logged in!
    AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"

    # dbd-login action executes a statement to log user in
    Require dbd-login
    AuthzDBDQuery "UPDATE authn SET login = 'true' WHERE user = %s"

    # return user to referring page (if any) after
    # successful login
    AuthzDBDLoginToReferer On
  </Files>

  <Files "logout.html">
    # dbd-logout action executes a statement to log user out
    Require dbd-logout
    AuthzDBDQuery "UPDATE authn SET login = 'false' WHERE user = %s"
  </Files>
</Directory>
top

AuthzDBDLoginToReferer Directive

Description:Determines whether to redirect the Client to the Referring page on successful login or logout if a Referer request header is present
Syntax:AuthzDBDLoginToReferer On|Off
Default:AuthzDBDLoginToReferer Off
Context:directory
Status:Extension
Module:mod_authz_dbd

In conjunction with Require dbd-login or Require dbd-logout, this provides the option to redirect the client back to the Referring page (the URL in the Referer HTTP request header, if present). When there is no Referer header, AuthzDBDLoginToReferer On will be ignored.

top

AuthzDBDQuery Directive

Description:Specify the SQL Query for the required operation
Syntax:AuthzDBDQuery query
Context:directory
Status:Extension
Module:mod_authz_dbd

The AuthzDBDQuery specifies an SQL query to run. The purpose of the query depends on the Require directive in effect.

In all cases, the user's ID will be passed as a single string parameter when the SQL query is executed. It may be referenced within the query statement using a %s format specifier.

top

AuthzDBDRedirectQuery Directive

Description:Specify a query to look up a login page for the user
Syntax:AuthzDBDRedirectQuery query
Context:directory
Status:Extension
Module:mod_authz_dbd

Specifies an optional SQL query to use after successful login (or logout) to redirect the user to a URL, which may be specific to the user. The user's ID will be passed as a single string parameter when the SQL query is executed. It may be referenced within the query statement using a %s format specifier.

AuthzDBDRedirectQuery "SELECT userpage FROM userpages WHERE user = %s"

The first column value of the first row returned by the query statement should be a string containing a URL to which to redirect the client. Subsequent rows will be ignored. If no rows are returned, the client will not be redirected.

Note that AuthzDBDLoginToReferer takes precedence if both are set.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_host.html.en0000664000175100017510000003261614737542416022151 0ustar covenercovener mod_authz_host - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authz_host

Available Languages:  en  |  fr 

Description:Group authorizations based on host (name or IP address)
Status:Base
Module Identifier:authz_host_module
Source File:mod_authz_host.c
Compatibility:The forward-dns provider was added in 2.4.19

Summary

The authorization providers implemented by mod_authz_host are registered using the Require directive. The directive can be referenced within a <Directory>, <Files>, or <Location> section as well as .htaccess files to control access to particular parts of the server. Access can be controlled based on the client hostname or IP address.

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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

The Require Directives

Apache's Require directive is used during the authorization phase to ensure that a user is allowed or denied access to a resource. mod_authz_host extends the authorization types with ip, host, forward-dns and local. Other authorization types may also be used but may require that additional authorization modules be loaded.

These authorization providers affect which hosts can access an area of the server. Access can be controlled by hostname, IP Address, or IP Address range.

Since v2.4.8, expressions are supported within the host require directives.

Require ip

The ip provider allows access to the server to be controlled based on the IP address of the remote client. When Require ip ip-address is specified, then the request is allowed access if the IP address matches.

A full IP address:

Require ip 10.1.2.3
Require ip 192.168.1.104 192.168.1.205

An IP address of a host allowed access

A partial IP address:

Require ip 10.1
Require ip 10 172.20 192.168.2

The first 1 to 3 bytes of an IP address, for subnet restriction.

A network/netmask pair:

Require ip 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:

Require ip 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:

Require ip 2001:db8::a00:20ff:fea7:ccea
Require ip 2001:db8:1:1::a
Require ip 2001:db8:2:1::/64
Require ip 2001:db8:3::/48

Note: As the IP addresses are parsed on startup, expressions are not evaluated at request time.

Require host

The host provider allows access to the server to be controlled based on the host name of the remote client. When Require host host-name is specified, then the request is allowed access if the host name matches.

A (partial) domain-name

Require host example.org
Require host .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.example.org but it will not match fooexample.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.

Require forward-dns

The forward-dns provider allows access to the server to be controlled based on simple host names. When Require forward-dns host-name is specified, all IP addresses corresponding to host-name are allowed access.

In contrast to the host provider, this provider does not rely on reverse DNS lookups: it simply queries the DNS for the host name and allows a client if its IP matches. As a consequence, it will only work with complete host names that can be resolved in DNS, not partial domain names. However, as the reverse DNS is not used, and DNS lookups occur at request processing time (instead of startup), it will work with clients which use a dynamic DNS service.

Require forward-dns dynamic.example.org

A client the IP of which is resolved from the name dynamic.example.org will be granted access.

The forward-dns provider was added in 2.4.19.

Require local

The local provider allows access to the server if any of the following conditions is true:

This allows a convenient way to match connections that originate from the local host:

Require local

Security Note

If you are proxying content to your server, you need to be aware that the client address will be the address of your proxy server, not the address of the client, and so using the Require directive in this context may not do what you mean. See mod_remoteip for one possible solution to this problem.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_autoindex.html.en0000664000175100017510000017143614737542416021765 0ustar covenercovener mod_autoindex - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_autoindex

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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:

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

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Autoindex Request Query Arguments

Various query string arguments are available to give the client some control over the ordering of the directory listing, as well as what files are listed. If you do not wish to give the client this control, the IndexOptions IgnoreClient option disables that functionality.

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.

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.

Example

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

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.

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.

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 (").

AddDescription "The planet Mars" mars.gif
AddDescription "My friend Marshall" friends/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.

Since the File argument may be a partial file name, please remember that a too-short partial filename may match unintended files. For example, le.html will match the file le.html but will also match the file example.html. In the event that there may be ambiguity, use as complete a filename as you can, but keep in mind that the first match encountered will be used, and order your list of AddDescription directives accordingly.

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.

Arguments with path information

Absolute paths are not currently supported and do not match anything at runtime. Arguments with relative path information, which would normally only be used in htaccess context, are implicitly prefixed with '*/' to avoid matching partial directory names.

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, a fully qualified remote URL, 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.

^^BLANKICON^^ is only used for formatting, and so is unnecessary if you're using IndexOptions HTMLTable.

#Examples
AddIcon (IMG,/icons/image.png) .gif .jpg .png
AddIcon /icons/dir.png ^^DIRECTORY^^
AddIcon /icons/backup.png *~

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, a fully qualified remote URL, or of the format (alttext,url) where alttext is the text tag given for an icon for non-graphical browsers.

MIME-encoding is a valid content-encoding, such as x-compress.

AddIconByEncoding /icons/compress.png 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, a fully qualified remote URL, 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.

AddIconByType (IMG,/icons/image.png) 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, or a fully qualified remote URL.

DefaultIcon /icon/unknown.png
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.

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.

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.

See also

top

IndexHeadInsert Directive

Description:Inserts text in the HEAD section of an index page.
Syntax:IndexHeadInsert "markup ..."
Context:server config, virtual host, directory, .htaccess
Override:Indexes
Status:Base
Module:mod_autoindex

The IndexHeadInsert directive specifies a string to insert in the <head> section of the HTML generated for the index page.

IndexHeadInsert "<link rel=\"sitemap\" href=\"/sitemap.html\">"
top

IndexIgnore Directive

Description:Adds to the list of files to hide when listing a directory
Syntax:IndexIgnore file [file] ...
Default:IndexIgnore "."
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 replacing the list of ignored files. By default, the list contains . (the current directory).

IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t

Regular Expressions

This directive does not currently work in configuration sections that have regular expression arguments, such as <DirectoryMatch>

top

IndexIgnoreReset Directive

Description:Empties the list of files to hide when listing a directory
Syntax:IndexIgnoreReset ON|OFF
Context:server config, virtual host, directory, .htaccess
Override:Indexes
Status:Base
Module:mod_autoindex
Compatibility:2.3.10 and later

The IndexIgnoreReset directive removes any files ignored by IndexIgnore otherwise inherited from other configuration sections.

<Directory "/var/www">
    IndexIgnore *.bak .??* *~ *# HEADER* README* RCS CVS *,v *,t
</Directory>
<Directory "/var/www/backups">
    IndexIgnoreReset ON
    IndexIgnore .??* *# HEADER* README* RCS CVS *,v *,t
</Directory>

Review the default configuration for a list of patterns that you might want to explicitly ignore after using this directive.

top

IndexOptions Directive

Description:Various configuration settings for directory indexing
Syntax:IndexOptions [+|-]option [[+|-]option] ...
Default:By default, no options are enabled.
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

AddAltClass
Adds an additional CSS class declaration to each row of the directory listing table when IndexOptions HTMLTable is in effect and an IndexStyleSheet is defined. Rather than the standard even and odd classes that would otherwise be applied to each row of the table, a class of even-ALT or odd-ALT where ALT is either the standard alt text associated with the file style (eg. snd, txt, img, etc) or the alt text defined by one of the various AddAlt* directives.
Charset=character-set
The Charset keyword allows you to specify the character set of the generated page. The default is UTF-8 on Windows and Mac OS X, and ISO-8859-1 elsewhere. (It depends on whether the underlying file system uses Unicode filenames or not.)
IndexOptions Charset=UTF-8
DescriptionWidth=[n | *]
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
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
This option with FancyIndexing constructs a simple table for the fancy directory listing. It is necessary for utf-8 enabled platforms or if file names or description text will alternate between left-to-right and right-to-left reading order.
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 httpd software. This option only has an effect if FancyIndexing is also enabled.
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 httpd 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, but only up to 20 bytes wide.
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 httpd will show files normally hidden because the subrequest returned HTTP_UNAUTHORIZED or HTTP_FORBIDDEN
SuppressColumnSorting
If specified, Apache httpd 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. However, query string arguments which are appended to the URL will still be honored. That behavior is controlled by IndexOptions IgnoreClient.
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. This option only has an effect if FancyIndexing is also enabled.
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. If you also specify a ReadmeName, and if that file exists, The closing </body></html> tags are also omitted from the output, under the assumption that you'll likely put those closing tags in that file.
SuppressIcon
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. This option only has an effect if FancyIndexing is also enabled.
SuppressRules
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.) This option only has an effect if FancyIndexing is also enabled.
SuppressSize
This will suppress the file size in fancy indexing listings. This option only has an effect if FancyIndexing is also enabled.
TrackModified
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.
Type=MIME content-type
The Type keyword allows you to specify the MIME content-type of the generated page. The default is text/html.
IndexOptions Type=text/plain
UseOldDateFormat (Apache HTTP Server 2.4.26 and later)
The date format used for the Last Modified field was inadvertently changed to "%Y-%m-%d %H:%M" from "%d-%b-%Y %H:%M" in 2.4.0. Setting this option restores the date format from 2.2 and earlier.
VersionSort
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
The XHTML keyword forces mod_autoindex to emit XHTML 1.0 code instead of HTML 3.2. This option only has an effect if FancyIndexing is also enabled.
Incremental IndexOptions

Be aware of how multiple IndexOptions are handled.

  • 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, if desired, prevent the client from reordering the list by also adding the SuppressColumnSorting index option to remove the sort link from the top of the column, along with the IgnoreClient index option to prevent them from manually adding sort options to the query string in order to override your ordering preferences.

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.

IndexStyleSheet "/css/style.css"

Using this directive in conjunction with IndexOptions HTMLTable adds a number of CSS classes to the resulting HTML. The entire table is given a CSS id of indexlist and the following classes are associated with the various parts of the listing:

ClassDefinition
tr.indexheadHeader row of listing
th.indexcolicon and td.indexcolicon Icon column
th.indexcolname and td.indexcolname File name column
th.indexcollastmod and td.indexcollastmod Last modified column
th.indexcolsize and td.indexcolsize File size column
th.indexcoldesc and td.indexcoldesc Description column
tr.breakrow Horizontal rule at the bottom of the table
tr.odd and tr.even Alternating even and odd rows
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, as in example 2, it will be taken to be relative to the DocumentRoot.

# Example 1
ReadmeName FOOTER.html
# Example 2
ReadmeName /include/FOOTER.html

See also HeaderName, where this behavior is described in greater detail.

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_core.html.en0000664000175100017510000011205614737542416022121 0ustar covenercovener mod_authz_core - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authz_core

Available Languages:  en  |  fr 

Description:Core Authorization
Status:Base
Module Identifier:authz_core_module
Source File:mod_authz_core.c
Compatibility:Available in Apache HTTPD 2.3 and later

Summary

This module provides core authorization capabilities so that authenticated users can be allowed or denied access to portions of the web site. mod_authz_core provides the functionality to register various authorization providers. It is usually used in conjunction with an authentication provider module such as mod_authn_file and an authorization module such as mod_authz_user. It also allows for advanced logic to be applied to the authorization processing.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Authorization Containers

The authorization container directives <RequireAll>, <RequireAny> and <RequireNone> may be combined with each other and with the Require directive to express complex authorization logic.

The example below expresses the following authorization logic. In order to access the resource, the user must either be the superadmin user, or belong to both the admins group and the Administrators LDAP group and either belong to the sales group or have the LDAP dept attribute sales. Furthermore, in order to access the resource, the user must not belong to either the temps group or the LDAP group Temporary Employees.

<Directory "/www/mydocs">
    <RequireAll>
        <RequireAny>
            Require user superadmin
            <RequireAll>
                Require group admins
                Require ldap-group "cn=Administrators,o=Airius"
                <RequireAny>
                    Require group sales
                    Require ldap-attribute dept="sales"
                </RequireAny>
            </RequireAll>
        </RequireAny>
        <RequireNone>
            Require group temps
            Require ldap-group "cn=Temporary Employees,o=Airius"
        </RequireNone>
    </RequireAll>
</Directory>
top

The Require Directives

mod_authz_core provides some generic authorization providers which can be used with the Require directive.

Require env

The env provider allows access to the server to be controlled based on the existence of an environment variable. When Require 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.

SetEnvIf User-Agent "^KnockKnock/2\.0" let_me_in
<Directory "/docroot">
    Require 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.

When the server looks up a path via an internal subrequest such as looking for a DirectoryIndex or generating a directory listing with mod_autoindex, per-request environment variables are not inherited in the subrequest. Additionally, SetEnvIf directives are not separately evaluated in the subrequest due to the API phases mod_setenvif takes action in.

Require all

The all provider mimics the functionality that was previously provided by the 'Allow from all' and 'Deny from all' directives. This provider can take one of two arguments which are 'granted' or 'denied'. The following examples will grant or deny access to all requests.

Require all granted
Require all denied

Require method

The method provider allows using the HTTP method in authorization decisions. The GET and HEAD methods are treated as equivalent. The TRACE method is not available to this provider, use TraceEnable instead.

The following example will only allow GET, HEAD, POST, and OPTIONS requests:

Require method GET POST OPTIONS

The following example will allow GET, HEAD, POST, and OPTIONS requests without authentication, and require a valid user for all other methods:

<RequireAny>
     Require method GET POST OPTIONS
     Require valid-user
</RequireAny>

Require expr

The expr provider allows basing authorization decisions on arbitrary expressions.

Require expr "%{TIME_HOUR} -ge 9 && %{TIME_HOUR} -le 17"
<RequireAll>
    Require expr "!(%{QUERY_STRING} =~ /secret/)"
    Require expr "%{REQUEST_URI} in { '/example.cgi', '/other.cgi' }"
</RequireAll>
Require expr "!(%{QUERY_STRING} =~ /secret/) && %{REQUEST_URI} in { '/example.cgi', '/other.cgi' }"

The syntax is described in the ap_expr documentation. Before httpd 2.4.16, the surrounding double-quotes MUST be omitted.

Normally, the expression is evaluated before authentication. However, if the expression returns false and references the variable %{REMOTE_USER}, authentication will be performed and the expression will be re-evaluated.

top

Creating Authorization Provider Aliases

Extended authorization providers can be created within the configuration file and assigned an alias name. The alias providers can then be referenced through the Require directive in the same way as a base authorization provider. Besides the ability to create and alias an extended provider, it also allows the same extended authorization provider to be referenced by multiple locations.

Example

The example below creates two different ldap authorization provider aliases based on the ldap-group authorization provider. This example allows a single authorization location to check group membership within multiple ldap hosts:

<AuthzProviderAlias ldap-group ldap-group-alias1 "cn=my-group,o=ctx">
    AuthLDAPBindDN "cn=youruser,o=ctx"
    AuthLDAPBindPassword yourpassword
    AuthLDAPUrl "ldap://ldap.host/o=ctx"
</AuthzProviderAlias>

<AuthzProviderAlias ldap-group ldap-group-alias2 "cn=my-other-group,o=dev">
    AuthLDAPBindDN "cn=yourotheruser,o=dev"
    AuthLDAPBindPassword yourotherpassword
    AuthLDAPUrl "ldap://other.ldap.host/o=dev?cn"
</AuthzProviderAlias>

Alias "/secure" "/webpages/secure"
<Directory "/webpages/secure">
    Require all granted

    AuthBasicProvider file

    AuthType Basic
    AuthName LDAP_Protected_Place

    #implied OR operation
    Require ldap-group-alias1
    Require ldap-group-alias2
</Directory>
top

AuthMerging Directive

Description:Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
Syntax:AuthMerging Off | And | Or
Default:AuthMerging Off
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

When authorization is enabled, it is normally inherited by each subsequent configuration section, unless a different set of authorization directives is specified. This is the default action, which corresponds to an explicit setting of AuthMerging Off.

However, there may be circumstances in which it is desirable for a configuration section's authorization to be combined with that of its predecessor while configuration sections are being merged. Two options are available for this case, And and Or.

When a configuration section contains AuthMerging And or AuthMerging Or, its authorization logic is combined with that of the nearest predecessor (according to the overall order of configuration sections) which also contains authorization logic as if the two sections were jointly contained within a <RequireAll> or <RequireAny> directive, respectively.

The setting of AuthMerging is not inherited outside of the configuration section in which it appears. In the following example, only users belonging to group alpha may access /www/docs. Users belonging to either groups alpha or beta may access /www/docs/ab. However, the default Off setting of AuthMerging applies to the <Directory> configuration section for /www/docs/ab/gamma, so that section's authorization directives override those of the preceding sections. Thus only users belong to the group gamma may access /www/docs/ab/gamma.
<Directory "/www/docs">
    AuthType Basic
    AuthName Documents
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require group alpha
</Directory>

<Directory "/www/docs/ab">
    AuthMerging Or
    Require group beta
</Directory>

<Directory "/www/docs/ab/gamma">
    Require group gamma
</Directory>
top

<AuthzProviderAlias> Directive

Description:Enclose a group of directives that represent an extension of a base authorization provider and referenced by the specified alias
Syntax:<AuthzProviderAlias baseProvider Alias Require-Parameters> ... </AuthzProviderAlias>
Context:server config
Status:Base
Module:mod_authz_core

<AuthzProviderAlias> and </AuthzProviderAlias> are used to enclose a group of authorization directives that can be referenced by the alias name using the directive Require.

If several parameters are needed in Require-Parameters, they must be enclosed in quotation marks. Otherwise, only the first one is taken into account.

# In this example, for both addresses to be taken into account, they MUST be enclosed
# between quotation marks
<AuthzProviderAlias ip reject-ips "XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY">
</AuthzProviderAlias>

<Directory "/path/to/dir">
    <RequireAll>
        Require not reject-ips
        Require all granted
    </RequireAll>
</Directory>
top

AuthzSendForbiddenOnFailure Directive

Description:Send '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authentication succeeds but authorization fails
Syntax:AuthzSendForbiddenOnFailure On|Off
Default:AuthzSendForbiddenOnFailure Off
Context:directory, .htaccess
Status:Base
Module:mod_authz_core
Compatibility:Available in Apache HTTPD 2.3.11 and later

If authentication succeeds but authorization fails, Apache HTTPD will respond with an HTTP response code of '401 UNAUTHORIZED' by default. This usually causes browsers to display the password dialogue to the user again, which is not wanted in all situations. AuthzSendForbiddenOnFailure allows to change the response code to '403 FORBIDDEN'.

Security Warning

Modifying the response in case of missing authorization weakens the security of the password, because it reveals to a possible attacker, that his guessed password was right.

top

Require Directive

Description:Tests whether an authenticated user is authorized by an authorization provider.
Syntax:Require [not] entity-name [entity-name] ...
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

This directive tests whether an authenticated user is authorized according to a particular authorization provider and the specified restrictions. mod_authz_core provides the following generic authorization providers:

Require all granted
Access is allowed unconditionally.
Require all denied
Access is denied unconditionally.
Require env env-var [env-var] ...
Access is allowed only if one of the given environment variables is set.
Require method http-method [http-method] ...
Access is allowed only for the given HTTP methods.
Require expr expression
Access is allowed if expression evaluates to true.

Some of the allowed syntaxes provided by mod_authz_user, mod_authz_host, and mod_authz_groupfile 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 ip 10 172.20 192.168.2
Clients in the specified IP address ranges can access the resource.
Require forward-dns dynamic.example.org
A client the IP of which is resolved from the name dynamic.example.org will be granted access.

Other authorization modules that implement require options include mod_authnz_ldap, mod_authz_dbm, mod_authz_dbd, mod_authz_owner and mod_ssl.

In most cases, for a complete authentication and authorization configuration, Require must be accompanied by AuthName, AuthType and AuthBasicProvider or AuthDigestProvider directives, and directives such as AuthUserFile and AuthGroupFile (to define users and groups) in order to work correctly. Example:

AuthType Basic
AuthName "Restricted Resource"
AuthBasicProvider file
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.

The result of the Require directive may be negated through the use of the not option. As with the other negated authorization directive <RequireNone>, when the Require directive is negated it can only fail or return a neutral result, and therefore may never independently authorize a request.

In the following example, all users in the alpha and beta groups are authorized, except for those who are also in the reject group.

<Directory "/www/docs">
    <RequireAll>
        Require group alpha beta
        Require not group reject
    </RequireAll>
</Directory>

When multiple Require directives are used in a single configuration section and are not contained in another authorization directive like <RequireAll>, they are implicitly contained within a <RequireAny> directive. Thus the first one to authorize a user authorizes the entire request, and subsequent Require directives are ignored.

Security Warning

Exercise caution when setting authorization directives in Location sections that overlap with content served out of the filesystem. By default, these configuration sections overwrite authorization configuration in Directory, and Files sections.

The AuthMerging directive can be used to control how authorization configuration sections are merged.

See also

top

<RequireAll> Directive

Description:Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
Syntax:<RequireAll> ... </RequireAll>
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

<RequireAll> and </RequireAll> are used to enclose a group of authorization directives of which none must fail and at least one must succeed in order for the <RequireAll> directive to succeed.

If none of the directives contained within the <RequireAll> directive fails, and at least one succeeds, then the <RequireAll> directive succeeds. If none succeed and none fail, then it returns a neutral result. In all other cases, it fails.

See also

top

<RequireAny> Directive

Description:Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
Syntax:<RequireAny> ... </RequireAny>
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

<RequireAny> and </RequireAny> are used to enclose a group of authorization directives of which one must succeed in order for the <RequireAny> directive to succeed.

If one or more of the directives contained within the <RequireAny> directive succeed, then the <RequireAny> directive succeeds. If none succeed and none fail, then it returns a neutral result. In all other cases, it fails.

Because negated authorization directives are unable to return a successful result, they can not significantly influence the result of a <RequireAny> directive. (At most they could cause the directive to fail in the case where they failed and all other directives returned a neutral value.) Therefore negated authorization directives are not permitted within a <RequireAny> directive.

See also

top

<RequireNone> Directive

Description:Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
Syntax:<RequireNone> ... </RequireNone>
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authz_core

<RequireNone> and </RequireNone> are used to enclose a group of authorization directives of which none must succeed in order for the <RequireNone> directive to not fail.

If one or more of the directives contained within the <RequireNone> directive succeed, then the <RequireNone> directive fails. In all other cases, it returns a neutral result. Thus as with the other negated authorization directive Require not, it can never independently authorize a request because it can never return a successful result. It can be used, however, to restrict the set of users who are authorized to access a resource.

Because negated authorization directives are unable to return a successful result, they can not significantly influence the result of a <RequireNone> directive. Therefore negated authorization directives are not permitted within a <RequireNone> directive.

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_groupfile.html.en0000664000175100017510000002463414737542416023171 0ustar covenercovener mod_authz_groupfile - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authz_groupfile

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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_authz_groupfile extends the authorization types with group and group-file.

Since v2.4.8, expressions are supported within the groupfile require directives.

Require group

This directive specifies group membership that is required for the user to gain access.

Require group admin

Require file-group

When this directive is specified, the filesystem permissions on the file being accessed are consulted. The user must be a member of a group with the same name as the group that owns the file. See mod_authz_owner for more details.

Require file-group
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.

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_user.html.en0000664000175100017510000002015414737542416022144 0ustar covenercovener mod_authz_user - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authz_user

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

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_authz_user extends the authorization types with user and valid-user.

Since v2.4.8, expressions are supported within the user require directives.

Require user

This directive specifies a list of users that are allowed to gain access.

Require user john paul george ringo

Require valid-user

When this directive is specified, any successfully authenticated user will be allowed to gain access.

Require valid-user

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_buffer.html.en0000664000175100017510000002207514737542416021230 0ustar covenercovener mod_buffer - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_buffer

Available Languages:  en  |  fr 

Description:Support for request buffering
Status:Extension
Module Identifier:buffer_module
Source File:mod_buffer.c
Compatibility:Available in Apache 2.3 and later

Summary

This module provides the ability to buffer the input and output filter stacks.

Under certain circumstances, content generators might create content in small chunks. In order to promote memory reuse, in memory chunks are always 8k in size, regardless of the size of the chunk itself. When many small chunks are generated by a request, this can create a large memory footprint while the request is being processed, and an unnecessarily large amount of data on the wire. The addition of a buffer collapses the response into the fewest chunks possible.

When httpd is used in front of an expensive content generator, buffering the response may allow the backend to complete processing and release resources sooner, depending on how the backend is designed.

The buffer filter may be added to either the input or the output filter stacks, as appropriate, using the SetInputFilter, SetOutputFilter, AddOutputFilter or AddOutputFilterByType directives.

Using buffer with mod_include

AddOutputFilterByType INCLUDES;BUFFER text/html
The buffer filters read the request/response into RAM and then repack the request/response into the fewest memory buckets possible, at the cost of CPU time. When the request/response is already efficiently packed, buffering the request/response could cause the request/response to be slower than not using a buffer at all. These filters should be used with care, and only where necessary.
Support Apache!

Directives

Bugfix checklist

See also

top

BufferSize Directive

Description:Maximum size in bytes to buffer by the buffer filter
Syntax:BufferSize integer
Default:BufferSize 131072
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_buffer

The BufferSize directive specifies the amount of data in bytes that will be buffered before being read from or written to each request. The default is 128 kilobytes.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache_socache.html.en0000664000175100017510000004443614737542416022514 0ustar covenercovener mod_cache_socache - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_cache_socache

Available Languages:  en  |  fr 

Description:Shared object cache (socache) based storage module for the HTTP caching filter.
Status:Extension
Module Identifier:cache_socache_module
Source File:mod_cache_socache.c

Summary

mod_cache_socache implements a shared object cache (socache) based storage manager for mod_cache.

The headers and bodies of cached responses are combined, and stored underneath a single key in the shared object cache. A number of implementations of shared object caches are available to choose from.

Multiple content negotiated responses can be stored concurrently, however the caching of partial content is not yet supported by this module.

# Turn on caching
CacheSocache shmcb
CacheSocacheMaxSize 102400
<Location "/foo">
    CacheEnable socache
</Location>

# Fall back to the disk cache
CacheSocache shmcb
CacheSocacheMaxSize 102400
<Location "/foo">
    CacheEnable socache
    CacheEnable disk
</Location>

Note:

mod_cache_socache requires the services of mod_cache, which must be loaded before mod_cache_socache.

Support Apache!

Directives

Bugfix checklist

See also

top

CacheSocache Directive

Description:The shared object cache implementation to use
Syntax:CacheSocache type[:args]
Context:server config, virtual host
Status:Extension
Module:mod_cache_socache
Compatibility:Available in Apache 2.4.5 and later

The CacheSocache directive defines the name of the shared object cache implementation to use, followed by optional arguments for that implementation. A number of implementations of shared object caches are available to choose from.

CacheSocache shmcb
top

CacheSocacheMaxSize Directive

Description:The maximum size (in bytes) of an entry to be placed in the cache
Syntax:CacheSocacheMaxSize bytes
Default:CacheSocacheMaxSize 102400
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache_socache
Compatibility:Available in Apache 2.4.5 and later

The CacheSocacheMaxSize directive sets the maximum size, in bytes, for the combined headers and body of a document to be considered for storage in the cache. The larger the headers that are stored alongside the body, the smaller the body may be.

The mod_cache_socache module will only attempt to cache responses that have an explicit content length, or that are small enough to be written in one pass. This is done to allow the mod_cache_disk module to have an opportunity to cache responses larger than those cacheable within mod_cache_socache.

CacheSocacheMaxSize 102400
top

CacheSocacheMaxTime Directive

Description:The maximum time (in seconds) for a document to be placed in the cache
Syntax:CacheSocacheMaxTime seconds
Default:CacheSocacheMaxTime 86400
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache_socache
Compatibility:Available in Apache 2.4.5 and later

The CacheSocacheMaxTime directive sets the maximum freshness lifetime, in seconds, for a document to be stored in the cache. This value overrides the freshness lifetime defined for the document by the HTTP protocol.

CacheSocacheMaxTime 86400
top

CacheSocacheMinTime Directive

Description:The minimum time (in seconds) for a document to be placed in the cache
Syntax:CacheSocacheMinTime seconds
Default:CacheSocacheMinTime 600
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache_socache
Compatibility:Available in Apache 2.4.5 and later

The CacheSocacheMinTime directive sets the amount of seconds beyond the freshness lifetime of the response that the response should be cached for in the shared object cache. If a response is only stored for its freshness lifetime, there will be no opportunity to revalidate the response to make it fresh again.

CacheSocacheMinTime 600
top

CacheSocacheReadSize Directive

Description:The minimum size (in bytes) of the document to read and be cached before sending the data downstream
Syntax:CacheSocacheReadSize bytes
Default:CacheSocacheReadSize 0
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache_socache
Compatibility:Available in Apache 2.4.5 and later

The CacheSocacheReadSize directive sets the minimum amount of data, in bytes, to be read from the backend before the data is sent to the client. The default of zero causes all data read of any size to be passed downstream to the client immediately as it arrives. Setting this to a higher value causes the disk cache to buffer at least this amount before sending the result to the client. This can improve performance when caching content from a slow reverse proxy.

This directive only takes effect when the data is being saved to the cache, as opposed to data being served from the cache.

CacheSocacheReadSize 102400
top

CacheSocacheReadTime Directive

Description:The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
Syntax:CacheSocacheReadTime milliseconds
Default:CacheSocacheReadTime 0
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache_socache
Compatibility:Available in Apache 2.4.5 and later

The CacheSocacheReadTime directive sets the minimum amount of elapsed time that should pass before making an attempt to send data downstream to the client. During the time period, data will be buffered before sending the result to the client. This can improve performance when caching content from a reverse proxy.

The default of zero disables this option.

This directive only takes effect when the data is being saved to the cache, as opposed to data being served from the cache. It is recommended that this option be used alongside the CacheSocacheReadSize directive to ensure that the server does not buffer excessively should data arrive faster than expected.

CacheSocacheReadTime 1000

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authnz_ldap.html.en0000664000175100017510000025272614737542416022300 0ustar covenercovener mod_authnz_ldap - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authnz_ldap

Available Languages:  en  |  fr 

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 allows authentication front-ends such as mod_auth_basic to authenticate users through an ldap directory.

mod_authnz_ldap supports the following features:

When using mod_auth_basic, this module is invoked via the AuthBasicProvider directive with the ldap value.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Contents

top

General caveats

This module caches authentication and authorization results based on the configuration of mod_ldap. Changes made to the backing LDAP server will not be immediately reflected on the HTTP Server, including but not limited to user lockouts/revocations, password changes, or changes to group memberships. Consult the directives in mod_ldap for details of the cache tunables.

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. Search the directory using the generated filter. If the search does not return exactly one entry, deny or decline access.
  3. Fetch the distinguished name of the entry retrieved from the search and attempt to bind to the LDAP server using that DN and the password passed by the HTTP client. If the bind is unsuccessful, deny or decline access.

The following directives are used during the search/bind phase

AuthLDAPURL Specifies the LDAP server, the base DN, the attribute to use in the search, as well as the extra search filter to use.
AuthLDAPBindDN An optional DN to bind with during the search phase.
AuthLDAPBindPassword An 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:

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.
AuthLDAPCompareDNOnServer Determines the behavior of the Require ldap-dn directive.
AuthLDAPGroupAttribute Determines the attribute to use for comparisons in the Require ldap-group directive.
AuthLDAPGroupAttributeIsDN Specifies whether to use the user DN or the username when doing comparisons for the Require ldap-group directive.
AuthLDAPMaxSubGroupDepth Determines the maximum depth of sub-groups that will be evaluated during comparisons in the Require ldap-group directive.
AuthLDAPSubGroupAttribute Determines the attribute to use when obtaining sub-group members of the current group during comparisons in the Require ldap-group directive.
AuthLDAPSubGroupClass Specifies the LDAP objectClass values used to identify if queried directory objects really are group objects (as opposed to user objects) during the Require ldap-group directive's sub-group processing.
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.

Since v2.4.8, expressions are supported within the LDAP require directives.

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=Example?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=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Example
uniqueMember: cn=Fred User, o=Example

The following directive would grant access to both Fred and Barbara:

Require ldap-group cn=Administrators, o=Example

Members can also be found within sub-groups of a specified LDAP group if AuthLDAPMaxSubGroupDepth is set to a value greater than 0. For example, assume the following entries exist in the LDAP directory:

dn: cn=Employees, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Managers, o=Example
uniqueMember: cn=Administrators, o=Example
uniqueMember: cn=Users, o=Example

dn: cn=Managers, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Bob Ellis, o=Example
uniqueMember: cn=Tom Jackson, o=Example

dn: cn=Administrators, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Example
uniqueMember: cn=Fred User, o=Example

dn: cn=Users, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Allan Jefferson, o=Example
uniqueMember: cn=Paul Tilley, o=Example
uniqueMember: cn=Temporary Employees, o=Example

dn: cn=Temporary Employees, o=Example
objectClass: groupOfUniqueNames
uniqueMember: cn=Jim Swenson, o=Example
uniqueMember: cn=Elliot Rhodes, o=Example

The following directives would allow access for Bob Ellis, Tom Jackson, Barbara Jenson, Fred User, Allan Jefferson, and Paul Tilley but would not allow access for Jim Swenson, or Elliot Rhodes (since they are at a sub-group depth of 2):

Require ldap-group cn=Employees, o=Example
AuthLDAPMaxSubGroupDepth 1

Behavior of this directive is modified by the AuthLDAPGroupAttribute, AuthLDAPGroupAttributeIsDN, AuthLDAPMaxSubGroupDepth, AuthLDAPSubGroupAttribute, and AuthLDAPSubGroupClass 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=Example

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.

When using an expression within the filter, care must be taken to ensure that LDAP filters are escaped correctly to guard against LDAP injection. The ldap function can be used for this purpose.

<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
  Require ldap-filter (memberOf=cn=%{ldap:%{unescape:%{env:MATCH_SITENAME}},ou=Websites,o=Example)
</LocationMatch>

Require ldap-search

The Require ldap-search directive allows the administrator to grant access based on a generic LDAP search filter using an expression. If there is exactly one match to the search filter, regardless of the distinguished name, access is granted.

The following directive would grant access to URLs that match the given objects in the LDAP server:

<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
Require ldap-search (cn=%{ldap:%{unescape:%{env:MATCH_SITENAME}} Website)
</LocationMatch>

Note: care must be taken to ensure that any expressions are properly escaped to guard against LDAP injection. The ldap function can be used as per the example above.

top

Examples

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

Exposing Login Information

when this module performs authentication, ldap attributes specified in the AuthLDAPURL directive are placed in environment variables with the prefix "AUTHENTICATE_".

when this module performs authorization, ldap attributes specified in the AuthLDAPURL directive are placed in environment variables with the prefix "AUTHORIZE_".

If the attribute field contains the username, common name and telephone number of a user, a CGI program will have access to this information without the need to make a second independent LDAP query to gather this additional information.

This has the potential to dramatically simplify the coding and configuration required in some web applications.

top

Using Active Directory

An Active Directory installation may support multiple domains at the same time. To distinguish users between domains, an identifier called a User Principle Name (UPN) can be added to a user's entry in the directory. This UPN usually takes the form of the user's account name, followed by the domain components of the particular domain, for example somebody@nz.example.com.

You may wish to configure the mod_authnz_ldap module to authenticate users present in any of the domains making up the Active Directory forest. In this way both somebody@nz.example.com and someone@au.example.com can be authenticated using the same query at the same time.

To make this practical, Active Directory supports the concept of a Global Catalog. This Global Catalog is a read only copy of selected attributes of all the Active Directory servers within the Active Directory forest. Querying the Global Catalog allows all the domains to be queried in a single query, without the query spanning servers over potentially slow links.

If enabled, the Global Catalog is an independent directory server that runs on port 3268 (3269 for SSL). To search for a user, do a subtree search for the attribute userPrincipalName, with an empty search root, like so:

AuthLDAPBindDN apache@example.com
AuthLDAPBindPassword password
AuthLDAPURL ldap://10.0.0.1:3268/?userPrincipalName?sub

Users will need to enter their User Principal Name as a login, in the form somebody@nz.example.com.

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"
AuthGroupFile     "mygroupfile"
Require group     "mygroupfile"

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

top

AuthLDAPAuthorizePrefix Directive

Description:Specifies the prefix for environment variables set during authorization
Syntax:AuthLDAPAuthorizePrefix prefix
Default:AuthLDAPAuthorizePrefix AUTHORIZE_
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.6 and later

This directive allows you to override the prefix used for environment variables set during LDAP authorization. If AUTHENTICATE_ is specified, consumers of these environment variables see the same information whether LDAP has performed authentication, authorization, or both.

Note

No authorization variables are set when a user is authorized on the basis of Require valid-user.
top

AuthLDAPBindAuthoritative Directive

Description:Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
Syntax:AuthLDAPBindAuthoritative off|on
Default:AuthLDAPBindAuthoritative on
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap

By default, subsequent authentication providers are only queried if a user cannot be mapped to a DN, but not if the user can be mapped to a DN and their password cannot be verified with an LDAP bind. If AuthLDAPBindAuthoritative is set to off, other configured authentication modules will have a chance to validate the user if the LDAP bind (with the current user's credentials) fails for any reason.

This allows users present in both LDAP and AuthUserFile to authenticate when the LDAP server is available but the user's account is locked or password is otherwise unusable.

See also

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 conjunction with the bind DN
Syntax:AuthLDAPBindPassword password
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:exec: was added in 2.4.5.

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.

If the value begins with exec: the resulting command will be executed and the first line returned to standard output by the program will be used as the password.

#Password used as-is
AuthLDAPBindPassword secret

#Run /path/to/program to get my password
AuthLDAPBindPassword exec:/path/to/program

#Run /path/to/otherProgram and provide arguments
AuthLDAPBindPassword "exec:/path/to/otherProgram argument1"
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

AuthLDAPCompareAsUser Directive

Description:Use the authenticated user's credentials to perform authorization comparisons
Syntax:AuthLDAPCompareAsUser on|off
Default:AuthLDAPCompareAsUser off
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.6 and later

When set, and mod_authnz_ldap has authenticated the user, LDAP comparisons for authorization use the queried distinguished name (DN) and HTTP basic authentication password of the authenticated user instead of the servers configured credentials.

The ldap-attribute, ldap-user, and ldap-group (single-level only) authorization checks use comparisons.

This directive only has effect on the comparisons performed during nested group processing when AuthLDAPSearchAsUser is also enabled.

This directive should only be used when your LDAP server doesn't accept anonymous comparisons and you cannot use a dedicated AuthLDAPBindDN.

See also

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 identify the user members of groups.
Syntax:AuthLDAPGroupAttribute attribute
Default:AuthLDAPGroupAttribute member uniqueMember
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap

This directive specifies which LDAP attributes are used to check for user members within groups. 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=Example. If this directive is set, mod_authnz_ldap will check if the group has cn=Babs Jenson, o=Example as a member. If this directive is not set, then mod_authnz_ldap will check if the group has bjenson as a member.

top

AuthLDAPInitialBindAsUser Directive

Description:Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
Syntax:AuthLDAPInitialBindAsUser off|on
Default:AuthLDAPInitialBindAsUser off
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.6 and later

By default, the server either anonymously, or with a dedicated user and password, converts the basic authentication username into an LDAP distinguished name (DN). This directive forces the server to use the verbatim username and password provided by the incoming user to perform the initial DN search.

If the verbatim username can't directly bind, but needs some cosmetic transformation, see AuthLDAPInitialBindPattern.

This directive should only be used when your LDAP server doesn't accept anonymous searches and you cannot use a dedicated AuthLDAPBindDN.

Not available with authorization-only

This directive can only be used if this module authenticates the user, and has no effect when this module is used exclusively for authorization.

See also

top

AuthLDAPInitialBindPattern Directive

Description:Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
Syntax:AuthLDAPInitialBindPattern regex substitution
Default:AuthLDAPInitialBindPattern (.*) $1 (remote username used verbatim)
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.6 and later

If AuthLDAPInitialBindAsUser is set to ON, the basic authentication username will be transformed according to the regular expression and substitution arguments.

The regular expression argument is compared against the current basic authentication username. The substitution argument may contain backreferences, but has no other variable interpolation.

This directive should only be used when your LDAP server doesn't accept anonymous searches and you cannot use a dedicated AuthLDAPBindDN.

AuthLDAPInitialBindPattern (.+) $1@example.com
AuthLDAPInitialBindPattern (.+) cn=$1,dc=example,dc=com

Not available with authorization-only

This directive can only be used if this module authenticates the user, and has no effect when this module is used exclusively for authorization.

debugging

The substituted DN is recorded in the environment variable LDAP_BINDASUSER. If the regular expression does not match the input, the verbatim username is used.

See also

top

AuthLDAPMaxSubGroupDepth Directive

Description:Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
Syntax:AuthLDAPMaxSubGroupDepth Number
Default:AuthLDAPMaxSubGroupDepth 10
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.0 and later

When this directive is set to a non-zero value X combined with use of the Require ldap-group someGroupDN directive, the provided user credentials will be searched for as a member of the someGroupDN directory object or of any group member of the current group up to the maximum nesting level X specified by this directive.

See the Require ldap-group section for a more detailed example.

Nested groups performance

When AuthLDAPSubGroupAttribute overlaps with AuthLDAPGroupAttribute (as it does by default and as required by common LDAP schemas), uncached searching for subgroups in large groups can be very slow. If you use large, non-nested groups, set AuthLDAPMaxSubGroupDepth to zero.

top

AuthLDAPRemoteUserAttribute Directive

Description:Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
Syntax:AuthLDAPRemoteUserAttribute uid
Default:none
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap

If this directive is set, the value of the REMOTE_USER environment variable will be set to the value of the attribute specified. Make sure that this attribute is included in the list of attributes in the AuthLDAPURL definition, otherwise this directive will have no effect. This directive, if present, takes precedence over AuthLDAPRemoteUserIsDN. This directive is useful should you want people to log into a website using an email address, but a backend application expects the username as a userid.

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

AuthLDAPSearchAsUser Directive

Description:Use the authenticated user's credentials to perform authorization searches
Syntax:AuthLDAPSearchAsUser on|off
Default:AuthLDAPSearchAsUser off
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.6 and later

When set, and mod_authnz_ldap has authenticated the user, LDAP searches for authorization use the queried distinguished name (DN) and HTTP basic authentication password of the authenticated user instead of the servers configured credentials.

The ldap-filter and ldap-dn authorization checks use searches.

This directive only has effect on the comparisons performed during nested group processing when AuthLDAPCompareAsUser is also enabled.

This directive should only be used when your LDAP server doesn't accept anonymous searches and you cannot use a dedicated AuthLDAPBindDN.

See also

top

AuthLDAPSubGroupAttribute Directive

Description:Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
Syntax:AuthLDAPSubGroupAttribute attribute
Default:AuthLDAPSubGroupAttribute member uniqueMember
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.0 and later

An LDAP group object may contain members that are users and members that are groups (called nested or sub groups). The AuthLDAPSubGroupAttribute directive identifies the labels of group members and the AuthLDAPGroupAttribute directive identifies the labels of the user members. 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

AuthLDAPSubGroupClass Directive

Description:Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
Syntax:AuthLDAPSubGroupClass LdapObjectClass
Default:AuthLDAPSubGroupClass groupOfNames groupOfUniqueNames
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_authnz_ldap
Compatibility:Available in version 2.3.0 and later

An LDAP group object may contain members that are users and members that are groups (called nested or sub groups). The AuthLDAPSubGroupAttribute directive identifies the labels of members that may be sub-groups of the current group (as opposed to user members). The AuthLDAPSubGroupClass directive specifies the LDAP objectClass values used in verifying that these potential sub-groups are in fact group objects. Verified sub-groups can then be searched for more user or sub-group members. Multiple attributes can be used by specifying this directive multiple times. If not specified, then mod_authnz_ldap uses the groupOfNames and groupOfUniqueNames values.

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

If you want to specify more than one LDAP URL that Apache should try in turn, the syntax is:

AuthLDAPURL "ldap://ldap1.example.com ldap2.example.com/dc=..."

Caveat: If you specify multiple servers, you need to enclose the entire URL string in quotes; otherwise you will get an error: "AuthLDAPURL takes one argument, URL to define LDAP connection.." You can of course use search parameters on each of these.

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. If multiple ldap servers are specified, then entire LDAP URL must be encapsulated in double quotes.

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. All attributes listed will be put into the environment with an AUTHENTICATE_ prefix for use by other modules.
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 more than sufficient for any application. In 2.4.10 and later, the keyword none disables the use of a filter; this is required by some primitive LDAP servers.

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.example.com/o=Example?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.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_dbm.html.en0000664000175100017510000003156214737542416021735 0ustar covenercovener mod_authz_dbm - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authz_dbm

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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_authz_dbm extends the authorization types with dbm-group.

Since v2.4.8, expressions are supported within the DBM require directives.

Require dbm-group

This directive specifies group membership that is required for the user to gain access.

Require dbm-group admin

Require dbm-file-group

When this directive is specified, the user must be a member of the group assigned to the file being accessed.

Require dbm-file-group
top

Example usage

Note that using mod_authz_dbm requires you to require dbm-group instead of group:

<Directory "/foo/bar">
  AuthType Basic
  AuthName "Secure Area"
  AuthBasicProvider dbm
  AuthDBMUserFile "site/data/users"
  AuthDBMGroupFile "site/data/users"
  Require dbm-group admin
</Directory>
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

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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authz_owner.html.en0000664000175100017510000002645314737542416022330 0ustar covenercovener mod_authz_owner - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authz_owner

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

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

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_brotli.html.en0000664000175100017510000005222114737542416021246 0ustar covenercovener mod_brotli - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_brotli

Available Languages:  en  |  fr 

Description:Compress content via Brotli before it is delivered to the client
Status:Extension
Module Identifier:brotli_module
Source File:mod_brotli.c
Compatibility:Available in version 2.4.26 and later.

Summary

The mod_brotli module provides the BROTLI_COMPRESS output filter that allows output from your server to be compressed using the brotli compression format before being sent to the client over the network. This module uses the Brotli library found at https://github.com/google/brotli.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Sample Configurations

Compression and TLS

Some web applications are vulnerable to an information disclosure attack when a TLS connection carries compressed data. For more information, review the details of the "BREACH" family of attacks.

This is a simple configuration that compresses common text-based content types.

Compress only a few types

AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript
top

Enabling Compression

Compression and TLS

Some web applications are vulnerable to an information disclosure attack when a TLS connection carries compressed data. For more information, review the details of the "BREACH" family of attacks.

Output Compression

Compression is implemented by the BROTLI_COMPRESS filter. The following directive will enable compression for documents in the container where it is placed:

SetOutputFilter BROTLI_COMPRESS
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli

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 BROTLI_COMPRESS text/html
</Directory>

Note

The BROTLI_COMPRESS filter is always inserted after RESOURCE filters like PHP or SSI. It never touches internal subrequests.

Note

There is an environment variable no-brotli, set via SetEnv, which will disable brotli compression for a particular request, even if it is supported by the client.
top

Dealing with proxy servers

The mod_brotli 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 BROTLI_COMPRESS 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

Serving pre-compressed content

Since mod_brotli re-compresses content each time a request is made, some performance benefit can be derived by pre-compressing the content and telling mod_brotli to serve them without re-compressing them. This may be accomplished using a configuration like the following:

<IfModule mod_headers.c>
    # Serve brotli compressed CSS files if they exist
    # and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.css"              "$1\.css\.br" [QSA]

    # Serve brotli compressed JS files if they exist
    # and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.js"               "$1\.js\.br" [QSA]


    # Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli:1]
    RewriteRule "\.js\.br$"  "-" [T=text/javascript,E=no-brotli:1]


    <FilesMatch "(\.js\.br|\.css\.br)$">
      # Serve correct encoding type.
      Header append Content-Encoding br

      # Force proxies to cache brotli &
      # non-brotli css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>
top

BrotliAlterETag Directive

Description:How the outgoing ETag header should be modified during compression
Syntax:BrotliAlterETag AddSuffix|NoChange|Remove
Default:BrotliAlterETag AddSuffix
Context:server config, virtual host
Status:Extension
Module:mod_brotli

The BrotliAlterETag directive specifies how the ETag hader should be altered when a response is compressed.

AddSuffix

Append the compression method onto the end of the ETag, causing compressed and uncompressed representations to have unique ETags. In another dynamic compression module, mod_deflate, this has been the default since 2.4.0. This setting prevents serving "HTTP Not Modified" (304) responses to conditional requests for compressed content.

NoChange

Don't change the ETag on a compressed response. In another dynamic compression module, mod_deflate, this has been the default prior to 2.4.0. This setting does not satisfy the HTTP/1.1 property that all representations of the same resource have unique ETags.

Remove

Remove the ETag header from compressed responses. This prevents some conditional requests from being possible, but avoids the shortcomings of the preceding options.

top

BrotliCompressionMaxInputBlock Directive

Description:Maximum input block size
Syntax:BrotliCompressionMaxInputBlock value
Default:(automatic)
Context:server config, virtual host
Status:Extension
Module:mod_brotli

The BrotliCompressionMaxInputBlock directive specifies the maximum input block size between 16 and 24, with the caveat that larger block sizes require more memory.

top

BrotliCompressionQuality Directive

Description:Compression quality
Syntax:BrotliCompressionQuality value
Default:BrotliCompressionQuality 5
Context:server config, virtual host
Status:Extension
Module:mod_brotli

The BrotliCompressionQuality directive specifies the compression quality (a value between 0 and 11). Higher quality values result in better, but also slower compression.

top

BrotliCompressionWindow Directive

Description:Brotli sliding compression window size
Syntax:BrotliCompressionWindow value
Default:BrotliCompressionWindow 18
Context:server config, virtual host
Status:Extension
Module:mod_brotli

The BrotliCompressionWindow directive specifies the brotli sliding compression window size (a value between 10 and 24). Larger window sizes can improve compression quality, but require more memory.

top

BrotliFilterNote Directive

Description:Places the compression ratio in a note for logging
Syntax:BrotliFilterNote [type] notename
Context:server config, virtual host
Status:Extension
Module:mod_brotli

The BrotliFilterNote 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

BrotliFilterNote ratio

LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' brotli
CustomLog "logs/brotli_log" brotli

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

BrotliFilterNote Input instream
BrotliFilterNote Output outstream
BrotliFilterNote Ratio ratio

LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' brotli
CustomLog "logs/brotli_log" brotli

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache_disk.html.en0000664000175100017510000005014514737542416022033 0ustar covenercovener mod_cache_disk - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_cache_disk

Available Languages:  en  |  fr  |  ja  |  ko 

Description:Disk based storage module for the HTTP caching filter.
Status:Extension
Module Identifier:cache_disk_module
Source File:mod_cache_disk.c

Summary

mod_cache_disk implements a disk based storage manager for mod_cache.

The headers and bodies of cached responses are stored separately on disk, in a directory structure derived from the md5 hash of the cached URL.

Multiple content negotiated responses can be stored concurrently, however the caching of partial content is not yet supported by this module.

Atomic cache updates to both header and body files are achieved without the need for locking by storing the device and inode numbers of the body file within the header file. This has the side effect that cache entries manually moved into the cache will be ignored.

The htcacheclean tool is provided to list cached URLs, remove cached URLs, or to maintain the size of the disk cache within size and/or inode limits. The tool can be run on demand, or can be daemonized to offer continuous monitoring of directory sizes.

Note:

mod_cache_disk requires the services of mod_cache, which must be loaded before mod_cache_disk.

Note:

mod_cache_disk uses the sendfile feature to serve files from the cache when supported by the platform, and when enabled with EnableSendfile. However, per-directory and .htaccess configuration of EnableSendfile are ignored by mod_cache_disk as the corresponding settings are not available to the module when a request is being served from the cache.

Support Apache!

Directives

Bugfix checklist

See also

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_cache_disk

The CacheDirLength directive sets the number of characters for each subdirectory name in the cache hierarchy. It can be used in conjunction with CacheDirLevels to determine the approximate structure of your cache hierarchy.

A high value for CacheDirLength combined with a low value for CacheDirLevels will result in a relatively flat hierarchy, with a large number of subdirectories at each level.

The result of CacheDirLevels* CacheDirLength must not be higher than 20.

top

CacheDirLevels Directive

Description:The number of levels of subdirectories in the cache.
Syntax:CacheDirLevels levels
Default:CacheDirLevels 2
Context:server config, virtual host
Status:Extension
Module:mod_cache_disk

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.

A high value for CacheDirLevels combined with a low value for CacheDirLength will result in a relatively deep hierarchy, with a small number of subdirectories at each level.

The result of CacheDirLevels* CacheDirLength must not be higher than 20.

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, directory, .htaccess
Status:Extension
Module:mod_cache_disk

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, directory, .htaccess
Status:Extension
Module:mod_cache_disk

The CacheMinFileSize directive sets the minimum size, in bytes, for a document to be considered for storage in the cache.

CacheMinFileSize 64
top

CacheReadSize Directive

Description:The minimum size (in bytes) of the document to read and be cached before sending the data downstream
Syntax:CacheReadSize bytes
Default:CacheReadSize 0
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache_disk

The CacheReadSize directive sets the minimum amount of data, in bytes, to be read from the backend before the data is sent to the client. The default of zero causes all data read of any size to be passed downstream to the client immediately as it arrives. Setting this to a higher value causes the disk cache to buffer at least this amount before sending the result to the client. This can improve performance when caching content from a reverse proxy.

This directive only takes effect when the data is being saved to the cache, as opposed to data being served from the cache.

CacheReadSize 102400
top

CacheReadTime Directive

Description:The minimum time (in milliseconds) that should elapse while reading before data is sent downstream
Syntax:CacheReadTime milliseconds
Default:CacheReadTime 0
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache_disk

The CacheReadTime directive sets the minimum amount of elapsed time that should pass before making an attempt to send data downstream to the client. During the time period, data will be buffered before sending the result to the client. This can improve performance when caching content from a reverse proxy.

The default of zero disables this option.

This directive only takes effect when the data is being saved to the cache, as opposed to data being served from the cache. It is recommended that this option be used alongside the CacheReadSize directive to ensure that the server does not buffer excessively should data arrive faster than expected.

CacheReadTime 1000
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_cache_disk

The CacheRoot directive defines the name of the directory on the disk to contain cache files. If the mod_cache_disk 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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cgi.html.en0000664000175100017510000004773014737542416020526 0ustar covenercovener mod_cgi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_cgi

Available Languages:  en  |  fr  |  ja  |  ko 

Description:Execution of CGI scripts
Status:Base
Module Identifier:cgi_module
Source File:mod_cgi.c

Summary

Any file that has the handler cgi-script will be treated as a CGI script, and run by the server, with its output being returned to the client. Files acquire this handler either by having a name containing an extension defined by the AddHandler directive, or by being in a ScriptAlias directory.

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.

For backward-compatibility, the cgi-script handler will also be activated for any file with the mime-type application/x-httpd-cgi. The use of the magic mime-type is deprecated.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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.

This module also leverages the core functions ap_add_common_vars and ap_add_cgi_vars to add environment variables like:

DOCUMENT_ROOT
Set with the content of the related DocumentRoot directive.
SERVER_NAME
The fully qualified domain name related to the request.
SERVER_ADDR
The IP address of the Virtual Host serving the request.
SERVER_ADMIN
Set with the content of the related ServerAdmin directive.

For an exhaustive list it is suggested to write a basic CGI script that dumps all the environment variables passed by Apache in a convenient format.

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

CGIScriptTimeout Directive

Description:The length of time to wait for more output from the CGI program
Syntax:CGIScriptTimeout time[s|ms]
Default:value of Timeout directive when unset
Context:server config, virtual host, directory, .htaccess
Status:Base
Module:mod_cgi
Compatibility:Available in version 2.4.59 and later.

This directive limits the length of time to wait for more output from the CGI program. If the time is exceeded, the request and CGI are terminated.

Example

CGIScriptTimeout 20
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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_data.html.en0000664000175100017510000001676514737542416020701 0ustar covenercovener mod_data - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_data

Available Languages:  en  |  fr 

Description:Convert response body into an RFC2397 data URL
Status:Extension
Module Identifier:data_module
Source File:mod_data.c
Compatibility:Available in Apache 2.3 and later

Summary

This module provides the ability to convert a response into an RFC2397 data URL.

Data URLs can be embedded inline within web pages using something like the mod_include module, to remove the need for clients to make separate connections to fetch what may potentially be many small images. Data URLs may also be included into pages generated by scripting languages such as PHP.

An example of a data URL

data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
hhx4dbgYKAAA7

The filter takes no parameters, and can be added to the filter stack using the SetOutputFilter directive, or any of the directives supported by the mod_filter module.

Configuring the filter

<Location "/data/images">
    SetOutputFilter DATA
</Location>
Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav_lock.html.en0000664000175100017510000002340714737542416021541 0ustar covenercovener mod_dav_lock - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_dav_lock

Available Languages:  en  |  fr  |  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 its 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.

Support Apache!

Directives

Bugfix checklist

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 interpreted 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 an extension added by the server.

Available Languages:  en  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dialup.html.en0000664000175100017510000001677114737542416021243 0ustar covenercovener mod_dialup - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_dialup

Available Languages:  en  |  fr 

Description:Send static content at a bandwidth rate limit, defined by the various old modem standards
Status:Experimental
Module Identifier:dialup_module
Source File:mod_dialup.c

Summary

It is a module that sends static content at a bandwidth rate limit, defined by the various old modem standards. So, you can browse your site with a 56k V.92 modem, by adding something like this:

<Location "/mysite">
    ModemStandard "V.92"
</Location>

Previously to do bandwidth rate limiting modules would have to block an entire thread, for each client, and insert sleeps to slow the bandwidth down. Using the new suspend feature, a handler can get callback N milliseconds in the future, and it will be invoked by the Event MPM on a different thread, once the timer hits. From there the handler can continue to send data to the client.

Support Apache!

Directives

Bugfix checklist

See also

top

ModemStandard Directive

Description:Modem standard to simulate
Syntax:ModemStandard V.21|V.26bis|V.32|V.34|V.92
Context:directory
Status:Experimental
Module:mod_dialup

Specify what modem standard you wish to simulate.

<Location "/mysite">
    ModemStandard "V.26bis"
</Location>

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cache.html.en0000664000175100017510000021012714737542416021017 0ustar covenercovener mod_cache - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_cache

Available Languages:  en  |  fr  |  ja  |  ko 

Description:RFC 2616 compliant HTTP caching filter.
Status:Extension
Module Identifier:cache_module
Source File:mod_cache.c

Summary

This module should be used with care, as when the CacheQuickHandler directive is in its default value of on, the Allow and Deny directives will be circumvented. You should not enable quick handler caching for any content to which you wish to limit access by client host name, address or environment variable.

mod_cache implements an RFC 2616 compliant HTTP content caching filter, with support for the caching of content negotiated responses containing the Vary header.

RFC 2616 compliant caching provides a mechanism to verify whether stale or expired content is still fresh, and can represent a significant performance boost when the origin server supports conditional requests by honouring the If-None-Match HTTP request header. Content is only regenerated from scratch when the content has changed, and not when the cached entry expires.

As a filter, mod_cache can be placed in front of content originating from any handler, including flat files (served from a slow disk cached on a fast disk), the output of a CGI script or dynamic content generator, or content proxied from another server.

In the default configuration, mod_cache inserts the caching filter as far forward as possible within the filter stack, utilising the quick handler to bypass all per request processing when returning content to the client. In this mode of operation, mod_cache may be thought of as a caching proxy server bolted to the front of the webserver, while running within the webserver itself.

When the quick handler is switched off using the CacheQuickHandler directive, it becomes possible to insert the CACHE filter at a point in the filter stack chosen by the administrator. This provides the opportunity to cache content before that content is personalised by the mod_include filter, or optionally compressed by the mod_deflate filter.

Under normal operation, mod_cache will respond to and can be controlled by the Cache-Control and Pragma headers sent from a client in a request, or from a server within a response. Under exceptional circumstances, mod_cache can be configured to override these headers and force site specific behaviour, however such behaviour will be limited to this cache only, and will not affect the operation of other caches that may exist between the client and server, and as a result is not recommended unless strictly necessary.

RFC 2616 allows for the cache to return stale data while the existing stale entry is refreshed from the origin server, and this is supported by mod_cache when the CacheLock directive is suitably configured. Such responses will contain a Warning HTTP header with a 110 response code. RFC 2616 also allows a cache to return stale data when the attempt made to refresh the stale data returns an error 500 or above, and this behaviour is supported by default by mod_cache. Such responses will contain a Warning HTTP header with a 111 response code.

mod_cache requires the services of one or more storage management modules. The following storage management modules are included in the base Apache distribution:

mod_cache_disk
Implements a disk based storage manager. Headers and bodies are stored separately on disk, in a directory structure derived from the md5 hash of the cached URL. Multiple content negotiated responses can be stored concurrently, however the caching of partial content is not supported by this module. The htcacheclean tool is provided to list cached URLs, remove cached URLs, or to maintain the size of the disk cache within size and inode limits.
mod_cache_socache
Implements a shared object cache based storage manager. Headers and bodies are stored together beneath a single key based on the URL of the response being cached. Multiple content negotiated responses can be stored concurrently, however the caching of partial content is not supported by this module.

Further details, discussion, and examples, are provided in the Caching Guide.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Related Modules and Directives

top

Sample Configuration

Sample httpd.conf

#
# Sample Cache Configuration
#
LoadModule cache_module modules/mod_cache.so
<IfModule mod_cache.c>
    LoadModule cache_disk_module modules/mod_cache_disk.so
    <IfModule mod_cache_disk.c>
        CacheRoot "c:/cacheroot"
        CacheEnable disk  "/"
        CacheDirLevels 5
        CacheDirLength 3
    </IfModule>

    # When acting as a proxy, don't cache the list of security updates
    CacheDisable "http://security.update.server/update-list/"
</IfModule>
top

Avoiding the Thundering Herd

When a cached entry becomes stale, mod_cache will submit a conditional request to the backend, which is expected to confirm whether the cached entry is still fresh, and send an updated entity if not.

A small but finite amount of time exists between the time the cached entity becomes stale, and the time the stale entity is fully refreshed. On a busy server, a significant number of requests might arrive during this time, and cause a thundering herd of requests to strike the backend suddenly and unpredictably.

To keep the thundering herd at bay, the CacheLock directive can be used to define a directory in which locks are created for URLs in flight. The lock is used as a hint by other requests to either suppress an attempt to cache (someone else has gone to fetch the entity), or to indicate that a stale entry is being refreshed (stale content will be returned in the mean time).

Initial caching of an entry

When an entity is cached for the first time, a lock will be created for the entity until the response has been fully cached. During the lifetime of the lock, the cache will suppress the second and subsequent attempt to cache the same entity. While this doesn't hold back the thundering herd, it does stop the cache attempting to cache the same entity multiple times simultaneously.

Refreshment of a stale entry

When an entity reaches its freshness lifetime and becomes stale, a lock will be created for the entity until the response has either been confirmed as still fresh, or replaced by the backend. During the lifetime of the lock, the second and subsequent incoming request will cause stale data to be returned, and the thundering herd is kept at bay.

Locks and Cache-Control: no-cache

Locks are used as a hint only to enable the cache to be more gentle on backend servers, however the lock can be overridden if necessary. If the client sends a request with a Cache-Control header forcing a reload, any lock that may be present will be ignored, and the client's request will be honored immediately and the cached entry refreshed.

As a further safety mechanism, locks have a configurable maximum age. Once this age has been reached, the lock is removed, and a new request is given the opportunity to create a new lock. This maximum age can be set using the CacheLockMaxAge directive, and defaults to 5 seconds.

Example configuration

Enabling the cache lock

#
# Enable the cache lock
#
<IfModule mod_cache.c>
    CacheLock on
    CacheLockPath "/tmp/mod_cache-lock"
    CacheLockMaxAge 5
</IfModule>
top

Fine Control with the CACHE Filter

Under the default mode of cache operation, the cache runs as a quick handler, short circuiting the majority of server processing and offering the highest cache performance available.

In this mode, the cache bolts onto the front of the server, acting as if a free standing RFC 2616 caching proxy had been placed in front of the server.

While this mode offers the best performance, the administrator may find that under certain circumstances they may want to perform further processing on the request after the request is cached, such as to inject personalisation into the cached page, or to apply authorization restrictions to the content. Under these circumstances, an administrator is often forced to place independent reverse proxy servers either behind or in front of the caching server to achieve this.

To solve this problem the CacheQuickHandler directive can be set to off, and the server will process all phases normally handled by a non-cached request, including the authentication and authorization phases.

In addition, the administrator may optionally specify the precise point within the filter chain where caching is to take place by adding the CACHE filter to the output filter chain.

For example, to cache content before applying compression to the response, place the CACHE filter before the DEFLATE filter as in the example below:

# Cache content before optional compression
CacheQuickHandler off
AddOutputFilterByType CACHE;DEFLATE text/plain

Another option is to have content cached before personalisation is applied by mod_include (or another content processing filter). In this example templates containing tags understood by mod_include are cached before being parsed:

# Cache content before mod_include and mod_deflate
CacheQuickHandler off
AddOutputFilterByType CACHE;INCLUDES;DEFLATE text/html

You may place the CACHE filter anywhere you wish within the filter chain. In this example, content is cached after being parsed by mod_include, but before being processed by mod_deflate:

# Cache content between mod_include and mod_deflate
CacheQuickHandler off
AddOutputFilterByType INCLUDES;CACHE;DEFLATE text/html

Warning:

If the location of the CACHE filter in the filter chain is changed for any reason, you may need to flush your cache to ensure that your data served remains consistent. mod_cache is not in a position to enforce this for you.
top

Cache Status and Logging

Once mod_cache has made a decision as to whether or not an entity is to be served from cache, the detailed reason for the decision is written to the subprocess environment within the request under the cache-status key. This reason can be logged by the LogFormat directive as follows:

LogFormat "%{cache-status}e ..."

Based on the caching decision made, the reason is also written to the subprocess environment under one the following four keys, as appropriate:

cache-hit
The response was served from cache.
cache-revalidate
The response was stale and was successfully revalidated, then served from cache.
cache-miss
The response was served from the upstream server.
cache-invalidate
The cached entity was invalidated by a request method other than GET or HEAD.

This makes it possible to support conditional logging of cached requests as per the following example:

CustomLog "cached-requests.log" common env=cache-hit
CustomLog "uncached-requests.log" common env=cache-miss
CustomLog "revalidated-requests.log" common env=cache-revalidate
CustomLog "invalidated-requests.log" common env=cache-invalidate

For module authors, a hook called cache_status is available, allowing modules to respond to the caching outcomes above in customised ways.

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, directory, .htaccess
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

CacheDetailHeader Directive

Description:Add an X-Cache-Detail header to the response.
Syntax:CacheDetailHeader on|off
Default:CacheDetailHeader off
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache
Compatibility:Available in Apache 2.3.9 and later

When the CacheDetailHeader directive is switched on, an X-Cache-Detail header will be added to the response containing the detailed reason for a particular caching decision.

It can be useful during development of cached RESTful services to have additional information about the caching decision written to the response headers, so as to confirm whether Cache-Control and other headers have been correctly used by the service and client.

If the normal handler is used, this directive may appear within a <Directory> or <Location> directive. If the quick handler is used, this directive must appear within a server or virtual host context, otherwise the setting will be ignored.

# Enable the X-Cache-Detail header
CacheDetailHeader on

X-Cache-Detail: "conditional cache hit: entity refreshed" from localhost

top

CacheDisable Directive

Description:Disable caching of specified URLs
Syntax:CacheDisable url-string | on
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache

The CacheDisable directive instructs mod_cache to not cache urls at or below url-string.

Example

CacheDisable "/local_files"

If used in a <Location> directive, the path needs to be specified below the Location, or if the word "on" is used, caching for the whole location will be disabled.

Example

<Location "/foo">
    CacheDisable on
</Location>

The no-cache environment variable can be set to disable caching on a finer grained set of resources in versions 2.2.12 and later.

See also

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, directory
Status:Extension
Module:mod_cache
Compatibility:A url-string of '/' applied to forward proxy content in 2.2 and earlier.

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. The CacheEnable directive can alternatively be placed inside either <Location> or <LocationMatch> sections to indicate the content is cacheable. cache_type disk instructs mod_cache to use the disk based storage manager implemented by mod_cache_disk. cache_type socache instructs mod_cache to use the shared object cache based storage manager implemented by mod_cache_socache.

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 directives within <Location> or <LocationMatch> sections are processed before globally defined CacheEnable directives.

When acting as a forward proxy server, url-string must minimally begin with a protocol for which caching should be enabled.

# Cache content (normal handler only)
CacheQuickHandler off
<Location "/foo">
    CacheEnable disk
</Location>

# Cache regex (normal handler only)
CacheQuickHandler off
<LocationMatch "foo$">
    CacheEnable disk
</LocationMatch>

# Cache all but forward proxy url's (normal or quick handler)
CacheEnable  disk  /

# Cache FTP-proxied url's (normal or quick handler)
CacheEnable  disk  ftp://

# Cache forward proxy content from www.example.org (normal or quick handler)
CacheEnable  disk  http://www.example.org/

A hostname starting with a "*" matches all hostnames with that suffix. A hostname starting with "." matches all hostnames containing the domain components that follow.

# Match www.example.org, and fooexample.org
CacheEnable  disk  "http://*example.org/"
# Match www.example.org, but not fooexample.org
CacheEnable  disk  "http://.example.org/"

The no-cache environment variable can be set to disable caching on a finer grained set of resources in versions 2.2.12 and later.

See also

top

CacheHeader Directive

Description:Add an X-Cache header to the response.
Syntax:CacheHeader on|off
Default:CacheHeader off
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache
Compatibility:Available in Apache 2.3.9 and later

When the CacheHeader directive is switched on, an X-Cache header will be added to the response with the cache status of this response. If the normal handler is used, this directive may appear within a <Directory> or <Location> directive. If the quick handler is used, this directive must appear within a server or virtual host context, otherwise the setting will be ignored.

HIT
The entity was fresh, and was served from cache.
REVALIDATE
The entity was stale, was successfully revalidated and was served from cache.
MISS
The entity was fetched from the upstream server and was not served from cache.
# Enable the X-Cache header
CacheHeader on
X-Cache: HIT from localhost
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:

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, directory, .htaccess
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

CacheIgnoreQueryString Directive

Description:Ignore query string when caching
Syntax:CacheIgnoreQueryString On|Off
Default:CacheIgnoreQueryString Off
Context:server config, virtual host
Status:Extension
Module:mod_cache

Ordinarily, requests with query string parameters are cached separately for each unique query string. This is according to RFC 2616/13.9 done only if an expiration time is specified. The CacheIgnoreQueryString directive tells the cache to cache requests even if no expiration time is specified, and to reply with a cached reply even if the query string differs. From a caching point of view the request is treated as if having no query string when this directive is enabled.

CacheIgnoreQueryString On
top

CacheIgnoreURLSessionIdentifiers Directive

Description:Ignore defined session identifiers encoded in the URL when caching
Syntax:CacheIgnoreURLSessionIdentifiers identifier [identifier] ...
Default:CacheIgnoreURLSessionIdentifiers None
Context:server config, virtual host
Status:Extension
Module:mod_cache

Sometimes applications encode the session identifier into the URL like in the following Examples:

This causes cacheable resources to be stored separately for each session, which is often not desired. CacheIgnoreURLSessionIdentifiers lets define a list of identifiers that are removed from the key that is used to identify an entity in the cache, such that cacheable resources are not stored separately for each session.

CacheIgnoreURLSessionIdentifiers None clears the list of ignored identifiers. Otherwise, each identifier is added to the list.

Example 1

CacheIgnoreURLSessionIdentifiers jsessionid

Example 2

CacheIgnoreURLSessionIdentifiers None
top

CacheKeyBaseURL Directive

Description:Override the base URL of reverse proxied cache keys.
Syntax:CacheKeyBaseURL URL
Context:server config, virtual host
Status:Extension
Module:mod_cache
Compatibility:Available in Apache 2.3.9 and later

When the CacheKeyBaseURL directive is specified, the URL provided will be used as the base URL to calculate the URL of the cache keys in the reverse proxy configuration. When not specified, the scheme, hostname and port of the current virtual host is used to construct the cache key. When a cluster of machines is present, and all cached entries should be cached beneath the same cache key, a new base URL can be specified with this directive.

# Override the base URL of the cache key.
CacheKeyBaseURL "http://www.example.com/"
Take care when setting this directive. If two separate virtual hosts are accidentally given the same base URL, entries from one virtual host will be served to the other.
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, directory, .htaccess
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

CacheLock Directive

Description:Enable the thundering herd lock.
Syntax:CacheLock on|off
Default:CacheLock off
Context:server config, virtual host
Status:Extension
Module:mod_cache
Compatibility:Available in Apache 2.2.15 and later

The CacheLock directive enables the thundering herd lock for the given URL space.

In a minimal configuration the following directive is all that is needed to enable the thundering herd lock in the default system temp directory.

# Enable cache lock
CacheLock on
top

CacheLockMaxAge Directive

Description:Set the maximum possible age of a cache lock.
Syntax:CacheLockMaxAge integer
Default:CacheLockMaxAge 5
Context:server config, virtual host
Status:Extension
Module:mod_cache

The CacheLockMaxAge directive specifies the maximum age of any cache lock.

A lock older than this value in seconds will be ignored, and the next incoming request will be given the opportunity to re-establish the lock. This mechanism prevents a slow client taking an excessively long time to refresh an entity.

top

CacheLockPath Directive

Description:Set the lock path directory.
Syntax:CacheLockPath directory
Default:CacheLockPath /tmp/mod_cache-lock
Context:server config, virtual host
Status:Extension
Module:mod_cache

The CacheLockPath directive allows you to specify the directory in which the locks are created. By default, the system's temporary folder is used. Locks consist of empty files that only exist for stale URLs in flight, so is significantly less resource intensive than the traditional disk cache.

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, directory, .htaccess
Status:Extension
Module:mod_cache

The CacheMaxExpire directive specifies the maximum number of seconds for which cacheable 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

CacheMinExpire Directive

Description:The minimum time in seconds to cache a document
Syntax:CacheMinExpire seconds
Default:CacheMinExpire 0
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache

The CacheMinExpire directive specifies the minimum number of seconds for which cacheable HTTP documents will be retained without checking the origin server. This is only used if no valid expire time was supplied with the document.

CacheMinExpire 3600
top

CacheQuickHandler Directive

Description:Run the cache from the quick handler.
Syntax:CacheQuickHandler on|off
Default:CacheQuickHandler on
Context:server config, virtual host
Status:Extension
Module:mod_cache
Compatibility:Apache HTTP Server 2.3.3 and later

The CacheQuickHandler directive controls the phase in which the cache is handled.

In the default enabled configuration, the cache operates within the quick handler phase. This phase short circuits the majority of server processing, and represents the most performant mode of operation for a typical server. The cache bolts onto the front of the server, and the majority of server processing is avoided.

When disabled, the cache operates as a normal handler, and is subject to the full set of phases when handling a server request. While this mode is slower than the default, it allows the cache to be used in cases where full processing is required, such as when content is subject to authorization.

# Run cache as a normal handler
CacheQuickHandler off

It is also possible, when the quick handler is disabled, for the administrator to choose the precise location within the filter chain where caching is to be performed, by adding the CACHE filter to the chain.

# Cache content before mod_include and mod_deflate
CacheQuickHandler off
AddOutputFilterByType CACHE;INCLUDES;DEFLATE text/html

If the CACHE filter is specified more than once, the last instance will apply.

top

CacheStaleOnError Directive

Description:Serve stale content in place of 5xx responses.
Syntax:CacheStaleOnError on|off
Default:CacheStaleOnError on
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache
Compatibility:Available in Apache 2.3.9 and later

When the CacheStaleOnError directive is switched on, and when stale data is available in the cache, the cache will respond to 5xx responses from the backend by returning the stale data instead of the 5xx response. While the Cache-Control headers sent by clients will be respected, and the raw 5xx responses returned to the client on request, the 5xx response so returned to the client will not invalidate the content in the cache.

# Serve stale data on error.
CacheStaleOnError on
top

CacheStoreExpired Directive

Description:Attempt to cache responses that the server reports as expired
Syntax:CacheStoreExpired On|Off
Default:CacheStoreExpired Off
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_cache

Since httpd 2.2.4, responses which have already expired are not stored in the cache. The CacheStoreExpired directive allows this behavior to be overridden. CacheStoreExpired On tells the server to attempt to cache the resource if it is stale. Subsequent requests would trigger an If-Modified-Since request of the origin server, and the response may be fulfilled from cache if the backend resource has not changed.

CacheStoreExpired On
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, directory, .htaccess
Status:Extension
Module:mod_cache

Ordinarily, requests or responses with Cache-Control: no-store header values will not be stored in the cache. The CacheStoreNoStore directive allows this behavior to be overridden. CacheStoreNoStore 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, directory, .htaccess
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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_cern_meta.html.en0000664000175100017510000002577614737542416021727 0ustar covenercovener mod_cern_meta - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_cern_meta

Available Languages:  en  |  fr  |  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.

Support Apache!

Directives

Bugfix checklist

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 containing 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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_charset_lite.html.en0000664000175100017510000003654614737542416022435 0ustar covenercovener mod_charset_lite - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_charset_lite

Available Languages:  en  |  fr  |  ko 

Description:Specify character set translation or recoding
Status:Extension
Module Identifier:charset_lite_module
Source File:mod_charset_lite.c

Summary

mod_charset_lite allows the server to change the character set of responses before sending them to the client. In an EBCDIC environment, Apache always translates HTTP protocol content (e.g. response headers) from the code page of the Apache process locale to ISO-8859-1, but not the body of responses. In any environment, mod_charset_lite can be used to specify that response bodies should be translated. For example, if files are stored in EBCDIC, then mod_charset_lite can translate them to ISO-8859-1 before sending them to the client.

This module provides a small subset of configuration mechanisms implemented by Russian Apache and its associated mod_charset.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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:

top

CharsetDefault Directive

Description:Charset to translate into
Syntax:CharsetDefault charset
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
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>
Specifying the same charset for both CharsetSourceEnc and CharsetDefault disables translation. The charset need not match the charset of the response, but it must be a valid charset on the system.
top

CharsetOptions Directive

Description:Configures charset translation behavior
Syntax:CharsetOptions option [option] ...
Default:CharsetOptions ImplicitAdd
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_charset_lite

The CharsetOptions directive configures certain behaviors of mod_charset_lite. Option can be one of

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.
TranslateAllMimeTypes | NoTranslateAllMimeTypes
Normally, mod_charset_lite will only perform translation on a small subset of possible mimetypes. When the TranslateAllMimeTypes keyword is specified for a given configuration section, translation is performed without regard for mimetype.
top

CharsetSourceEnc Directive

Description:Source charset of files
Syntax:CharsetSourceEnc charset
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
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.

Specifying the same charset for both CharsetSourceEnc and CharsetDefault disables translation. The charset need not match the charset of the response, but it must be a valid charset on the system.

Available Languages:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav_fs.html.en0000664000175100017510000002537714737542416021231 0ustar covenercovener mod_dav_fs - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_dav_fs

Available Languages:  en  |  fr  |  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.

Support Apache!

Directives

Bugfix checklist

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.

top

DavLockDiscovery Directive

Description:Enable lock discovery
Syntax:DavLockDiscovery on|off
Default:DavLockDiscovery on
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_dav_fs
Compatibility:Available from Apache 2.4.55 and later.

DavLockDiscovery controls if the lock discovery feature is enabled for PROPFIND method. When disabled, PROPFIND always returns an empty lockdiscovery section. This improves performance if clients use PROPFIND a lot.

Example

DavLockDiscovery off

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_deflate.html.en0000664000175100017510000007477714737542416021403 0ustar covenercovener mod_deflate - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_deflate

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Supported Encodings

The gzip encoding is the only one supported to ensure complete compatibility with old browser implementations. The deflate encoding is not supported, please check the zlib's documentation for a complete explanation.

top

Sample Configurations

Compression and TLS

Some web applications are vulnerable to an information disclosure attack when a TLS connection carries deflate compressed data. For more information, review the details of the "BREACH" family of attacks.

This is a simple configuration that compresses common text-based content types.

Compress only a few types

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
top

Enabling Compression

Compression and TLS

Some web applications are vulnerable to an information disclosure attack when a TLS connection carries deflate compressed data. For more information, review the details of the "BREACH" family of attacks.

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
SetEnvIfNoCase Request_URI "\.(?:gif|jpe?g|png)$" no-gzip

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>

Note

The DEFLATE filter is always inserted after RESOURCE filters like PHP or SSI. It never touches internal subrequests.

Note

There is an 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 output filter 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

Serving pre-compressed content

Since mod_deflate re-compresses content each time a request is made, some performance benefit can be derived by pre-compressing the content and telling mod_deflate to serve them without re-compressing them. This may be accomplished using a configuration like the following:

<IfModule mod_headers.c>
    # Serve gzip compressed CSS and JS files if they exist
    # and the client accepts gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.(css|js)"         "$1\.$2\.gz" [QSA]

    # Serve correct content types, and prevent mod_deflate double gzip.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
    RewriteRule "\.js\.gz$"  "-" [T=text/javascript,E=no-gzip:1]


    <FilesMatch "(\.js\.gz|\.css\.gz)$">
      # Serve correct encoding type.
      Header append Content-Encoding gzip

      # Force proxies to cache gzipped &
      # non-gzipped css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>
top

DeflateAlterETag Directive

Description:How the outgoing ETag header should be modified during compression
Syntax:DeflateAlterETag AddSuffix|NoChange|Remove
Default:DeflateAlterETag AddSuffix
Context:server config, virtual host
Status:Extension
Module:mod_deflate
Compatibility:Available in Apache 2.4.58 and later

The DeflateAlterETag directive specifies how the ETag header should be altered when a response is compressed.

AddSuffix

Append the compression method onto the end of the ETag, causing compressed and uncompressed representations to have unique ETags. This has been the default since 2.4.0, but prevents serving "HTTP Not Modified" (304) responses to conditional requests for compressed content.

NoChange

Don't change the ETag on a compressed response. This was the default prior to 2.4.0, but does not satisfy the HTTP/1.1 property that all representations of the same resource have unique ETags.

Remove

Remove the ETag header from compressed responses. This prevents some conditional requests from being possible, but avoids the shortcomings of the preceding options.

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. If the compressed response size is bigger than the one specified by this directive then httpd will switch to chunked encoding (HTTP header Transfer-Encoding set to Chunked), with the side effect of not setting any Content-Length HTTP header. This is particularly important when httpd works behind reverse caching proxies or when httpd is configured with mod_cache and mod_cache_disk because HTTP responses without any Content-Length header might not be cached.

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

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

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

DeflateInflateLimitRequestBody Directive

Description:Maximum size of inflated request bodies
Syntax:DeflateInflateLimitRequestBody value
Default:None, but LimitRequestBody applies after deflation
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_deflate
Compatibility:2.4.10 and later

The DeflateInflateLimitRequestBody directive specifies the maximum size of an inflated request body. If it is unset, LimitRequestBody is applied to the inflated body.

top

DeflateInflateRatioBurst Directive

Description:Maximum number of times the inflation ratio for request bodies can be crossed
Syntax:DeflateInflateRatioBurst value
Default:DeflateInflateRatioBurst 3
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_deflate
Compatibility:2.4.10 and later

The DeflateInflateRatioBurst directive specifies the maximum number of times the DeflateInflateRatioLimit can be crossed before terminating the request.

top

DeflateInflateRatioLimit Directive

Description:Maximum inflation ratio for request bodies
Syntax:DeflateInflateRatioLimit value
Default:DeflateInflateRatioLimit 200
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_deflate
Compatibility:2.4.10 and later

The DeflateInflateRatioLimit directive specifies the maximum ratio of deflated to inflated size of an inflated request body. This ratio is checked as the body is streamed in, and if crossed more than DeflateInflateRatioBurst times, the request will be terminated.

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_wstunnel.html.en0000664000175100017510000002601114737542416023071 0ustar covenercovener mod_proxy_wstunnel - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_wstunnel

Available Languages:  en  |  fr 

Description:Websockets support module for mod_proxy
Status:Extension
Module Identifier:proxy_wstunnel_module
Source File:mod_proxy_wstunnel.c
Compatibility:Available in httpd 2.4.5 and later

Summary

Deprecation

Since Apache HTTP Server 2.4.47, protocol Upgrade (tunneling) can be better handled by mod_proxy_http.

See Protocol Upgrade.

This module requires the service of mod_proxy. It provides support for the tunnelling of web socket connections to a backend websockets server. The connection is automatically upgraded to a websocket connection:

HTTP Response

Upgrade: WebSocket
Connection: Upgrade

Proxying requests to a websockets server like echo.websocket.org can be done using the ProxyPass directive:

ProxyPass "/ws2/"  "ws://echo.websocket.org/"
ProxyPass "/wss2/" "wss://echo.websocket.org/"

Proxying both HTTP and websockets at the same time, with a specific set of URL's being websocket-only, can be done by specifying the websockets ProxyPass directive before the HTTP directive:

ProxyPassMatch ^/(myApp/ws)$  ws://backend.example.com:9080/$1
ProxyPass / http://backend.example.com:9080/

Proxying both HTTP and websockets at the same time, where the websockets URL's are not websocket-only or not known in advance can be done by using the RewriteRule directive to configure the websockets proxying:

ProxyPass / http://example.com:9080/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://example.com:9080/$1" [P,L]

Load balancing for multiple backends can be achieved using mod_proxy_balancer.

The module can also be used to upgrade to other protocols than WebSocket, by setting the upgrade parameter in the ProxyPass directive to some custom protocol name. Special upgrade=NONE and upgrade=ANY values may be used for testing/forcing the upgrade but they are not recommended in production for security reasons. NONE means that the check for the header is omitted but still the upgrade/tunneling to WebSocket always happens. ANY means that the upgrade/tunneling will happen using any protocol asked by the client.

Support Apache!

Directives

Bugfix checklist

See also

top

ProxyWebsocketFallbackToProxyHttp Directive

Description:Instructs this module to let mod_proxy_http handle the request
Syntax:ProxyWebsocketFallbackToProxyHttp On|Off
Default:ProxyWebsocketFallbackToProxyHttp On
Context:server config, virtual host
Status:Extension
Module:mod_proxy_wstunnel
Compatibility:Available in httpd 2.4.48 and later

Since httpd 2.4.47, mod_proxy_http can handle WebSocket upgrading and tunneling in accordance to RFC 7230, this directive controls whether mod_proxy_wstunnel should hand over to mod_proxy_http to this, which is the case by default.

Setting to Off lets mod_proxy_wstunnel handle WebSocket requests as in httpd 2.4.46 and earlier.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_echo.html.en0000664000175100017510000001670714737542416020702 0ustar covenercovener mod_echo - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_echo

Available Languages:  en  |  fr  |  ja  |  ko 

Description:A simple echo server to illustrate protocol modules
Status:Experimental
Module Identifier:echo_module
Source File:mod_echo.c

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.

Support Apache!

Directives

Bugfix checklist

See also

top

ProtocolEcho Directive

Description:Turn the echo server on or off
Syntax:ProtocolEcho On|Off
Default:ProtocolEcho Off
Context:server config, virtual host
Status:Experimental
Module:mod_echo

The ProtocolEcho directive enables or disables the echo server.

Example

ProtocolEcho On

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_expires.html.en0000664000175100017510000004133014737542416021431 0ustar covenercovener mod_expires - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_expires

Available Languages:  en  |  fr  |  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.

When the Expires header is already part of the response generated by the server, for example when generated by a CGI script or proxied from an origin server, this module does not change or add an Expires or Cache-Control header.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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] [num type] ..."
ExpiresByType type/encoding "base  [plus num type] [num type] ..."

where base is one of:

The plus keyword is optional. num should be an integer value [acceptable to atoi()], and type is one of:

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
Default:ExpiresActive 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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dumpio.html.en0000664000175100017510000002316614737542416021256 0ustar covenercovener mod_dumpio - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_dumpio

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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 separately for input and output via the below directives. Additionally, mod_dumpio needs to be configured to LogLevel trace7:

LogLevel dumpio:trace7
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  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_example_hooks.html.en0000664000175100017510000002631314737542416022614 0ustar covenercovener mod_example_hooks - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_example_hooks

Available Languages:  en  |  fr  |  ko 

Description:Illustrates the Apache module API
Status:Experimental
Module Identifier:example_hooks_module
Source File:mod_example_hooks.c

Summary

The files in the modules/examples 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_hooks.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-hooks-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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Compiling the example_hooks module

To include the example_hooks module in your server, follow the steps below:

  1. Run configure with --enable-example-hooks option.
  2. Make the server (run "make").

To add another module of your own:

  1. cp modules/examples/mod_example_hooks.c modules/new_module/mod_myexample.c
  2. Modify the file.
  3. Create modules/new_module/config.m4.
    1. Add APACHE_MODPATH_INIT(new_module).
    2. Copy APACHE_MODULE line with "example_hooks" from modules/examples/config.m4.
    3. Replace the first argument "example_hooks" with myexample.
    4. Replace the second argument with brief description of your module. It will be used in configure --help.
    5. 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.
    6. Add APACHE_MODPATH_FINISH.
  4. 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.
  5. Run ./buildconf from the top-level directory.
  6. Build the server with --enable-myexample
top

Using the mod_example_hooks Module

To activate the example_hooks module, include a block similar to the following in your httpd.conf file:

<Location "/example-hooks-info">
   SetHandler example-hooks-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-hooks-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_hooks

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-hooks 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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dav.html.en0000664000175100017510000004745014737542416020535 0ustar covenercovener mod_dav - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_dav

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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"

<Directory "/usr/local/apache2/htdocs/foo">
    Require all granted
    Dav On

    AuthType Basic
    AuthName DAV
    AuthUserFile "user.passwd"

    <LimitExcept GET POST OPTIONS>
        Require user admin
    </LimitExcept>
</Directory>
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

DavBasePath Directive

Description:Configure repository root path
Syntax:DavBasePath root-path
Default:None
Context:directory
Status:Extension
Module:mod_dav
Compatibility:Available in version 2.4.58 and later

If a DAV repository is configured using a regular expression match (such as LocationMatch) then mod_dav will not be able to find the root of the repository from the pathname alone. Third-party providers (for example, Subversion's mod_dav_svn) may fail to handle requests without the correct repository root.

To allow providers to work correctly in such a configuration, DavBasePath must be used.

<LocationMatch "^/repos/">
    Dav svn
    DavBasePath /repos
    SVNParentPath /var/svn
</LocationMatch>
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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dbd.html.en0000664000175100017510000006132214737542416020506 0ustar covenercovener mod_dbd - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_dbd

Available Languages:  en  |  fr 

Description:Manages SQL database connections
Status:Extension
Module Identifier:dbd_module
Source File:mod_dbd.c
Compatibility:Version 2.1 and later

Summary

mod_dbd manages SQL database connections using APR. 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. For details, see the APR website and this overview of the Apache DBD Framework by its original developer.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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. Note that mod_dbd supersedes the modules presented in that article.

top

Connecting

To connect to your database, you'll need to specify a driver, and connection parameters. These vary from one database engine to another. For example, to connect to mysql, do the following:

DBDriver mysql
DBDParams host=localhost,dbname=pony,user=shetland,pass=appaloosa

You can then use this connection in a variety of other modules, including mod_rewrite, mod_authn_dbd, and mod_lua. Further usage examples appear in each of those modules' documentation.

See DBDParams for connection string information for each of the supported database drivers.

top

Apache DBD API

mod_dbd exports five 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*);

/* acquire a connection that will have the lifetime of a connection
 * and MUST NOT be explicitly closed.  Return NULL on error.
 */
AP_DECLARE(ap_dbd_t*) ap_dbd_cacquire(conn_rec*);

/* Prepare a statement for use by a client module */
AP_DECLARE(void) ap_dbd_prepare(server_rec*, const char*, const char*);

/* 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*));
APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_cacquire, (conn_rec*));
APR_DECLARE_OPTIONAL_FN(void, ap_dbd_prepare, (server_rec*, const char*, const char*));
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, or to provide their own directives and use ap_dbd_prepare.

Caveat

When using prepared statements with a MySQL database, it is preferred to set reconnect to 0 in the connection string as to avoid errors that arise from the MySQL client reconnecting without properly resetting the prepared statements. If set to 1, any broken connections will be attempted fixed, but as mod_dbd is not informed, the prepared statements will be invalidated.
top

SECURITY WARNING

Any web/database application needs to secure itself against SQL injection attacks. In most cases, Apache DBD is safe, because applications use prepared statements, and untrusted inputs are only ever used as data. Of course, if you use it via third-party modules, you should ascertain what precautions they may require.

However, the FreeTDS driver is inherently unsafe. The underlying library doesn't support prepared statements, so the driver emulates them, and the untrusted input is merged into the SQL statement.

It can be made safe by untainting all inputs: a process inspired by Perl's taint checking. Each input is matched against a regexp, and only the match is used, according to the Perl idiom:

  $untrusted =~ /([a-z]+)/;
  $trusted = $1;

To use this, the untainting regexps must be included in the prepared statements configured. The regexp follows immediately after the % in the prepared statement, and is enclosed in curly brackets {}. For example, if your application expects alphanumeric input, you can use:

"SELECT foo FROM bar WHERE input = %s"

with other drivers, and suffer nothing worse than a failed query. But with FreeTDS you'd need:

"SELECT foo FROM bar WHERE input = %{([A-Za-z0-9]+)}s"

Now anything that doesn't match the regexp's $1 match is discarded, so the statement is safe.

An alternative to this may be the third-party ODBC driver, which offers the security of genuine prepared statements.

top

DBDExptime Directive

Description:Keepalive time for idle connections
Syntax:DBDExptime time-in-seconds
Default:DBDExptime 300
Context:server config, virtual host
Status:Extension
Module:mod_dbd

Set the time to keep idle connections alive when the number of connections specified in DBDKeep has been exceeded (threaded platforms only).

top

DBDInitSQL Directive

Description:Execute an SQL statement after connecting to a database
Syntax:DBDInitSQL "SQL statement"
Context:server config, virtual host
Status:Extension
Module:mod_dbd

Modules, that wish it, can have one or more SQL statements executed when a connection to a database is created. Example usage could be initializing certain values or adding a log entry when a new connection is made to the database.

top

DBDKeep Directive

Description:Maximum sustained number of connections
Syntax:DBDKeep number
Default:DBDKeep 2
Context:server config, virtual host
Status:Extension
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
Default:DBDMax 10
Context:server config, virtual host
Status:Extension
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
Default:DBDMin 1
Context:server config, virtual host
Status:Extension
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:Extension
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.

Connection string parameters for current drivers include:

FreeTDS (for MSSQL and SyBase)
username, password, appname, dbname, host, charset, lang, server
MySQL
host, port, user, pass, dbname, sock, flags, fldsz, group, reconnect
Oracle
user, pass, dbname, server
PostgreSQL
The connection string is passed straight through to PQconnectdb
SQLite2
The connection string is split on a colon, and part1:part2 is used as sqlite_open(part1, atoi(part2), NULL)
SQLite3
The connection string is passed straight through to sqlite3_open
ODBC
datasource, user, password, connect, ctimeout, stimeout, access, txmode, bufsize
top

DBDPersist Directive

Description:Whether to use persistent connections
Syntax:DBDPersist On|Off
Context:server config, virtual host
Status:Extension
Module:mod_dbd

If set to Off, 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.

Prior to version 2.2.2, this directive accepted only the values 0 and 1 instead of Off and On, respectively.

top

DBDPrepareSQL Directive

Description:Define an SQL prepared statement
Syntax:DBDPrepareSQL "SQL statement" label
Context:server config, virtual host
Status:Extension
Module:mod_dbd

For modules such as authentication that 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:Extension
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  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_dir.html.en0000664000175100017510000005461614737542416020543 0ustar covenercovener mod_dir - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_dir

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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:

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

Support Apache!

Directives

Bugfix checklist

See also

top

DirectoryCheckHandler Directive

Description:Toggle how this module responds when another handler is configured
Syntax:DirectoryCheckHandler On|Off
Default:DirectoryCheckHandler Off
Context:server config, virtual host, directory, .htaccess
Override:Indexes
Status:Base
Module:mod_dir
Compatibility:Available in 2.4.8 and later. Releases prior to 2.4 implicitly act as if "DirectoryCheckHandler ON" was specified.

The DirectoryCheckHandler directive determines whether mod_dir should check for directory indexes or add trailing slashes when some other handler has been configured for the current URL. Handlers can be set by directives such as SetHandler or by other modules, such as mod_rewrite during per-directory substitutions.

In releases prior to 2.4, this module did not take any action if any other handler was configured for a URL. This allows directory indexes to be served even when a SetHandler directive is specified for an entire directory, but it can also result in some conflicts with modules such as mod_rewrite.

top

DirectoryIndex Directive

Description:List of resources to look for when the client requests a directory
Syntax:DirectoryIndex disabled | 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://example.com/docs/ would return http://example.com/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.

A single argument of "disabled" prevents mod_dir from searching for an index. An argument of "disabled" will be interpreted literally if it has any arguments before or after it, even if they are "disabled" as well.

Note: Multiple DirectoryIndex directives within the same context will add to the list of resources to look for rather than replace:

# Example A: Set index.html as an index page, then add index.php to that list as well.
<Directory "/foo">
    DirectoryIndex index.html
    DirectoryIndex index.php
</Directory>

# Example B: This is identical to example A, except it's done with a single directive.
<Directory "/foo">
    DirectoryIndex index.html index.php
</Directory>

# Example C: To replace the list, you must explicitly reset it first:
# In this example, only index.php will remain as an index resource.
<Directory "/foo">
    DirectoryIndex index.html
    DirectoryIndex disabled
    DirectoryIndex index.php
</Directory>
top

DirectoryIndexRedirect Directive

Description:Configures an external redirect for directory indexes.
Syntax:DirectoryIndexRedirect on | off | permanent | temp | seeother | 3xx-code
Default:DirectoryIndexRedirect off
Context:server config, virtual host, directory, .htaccess
Override:Indexes
Status:Base
Module:mod_dir
Compatibility:Available in version 2.3.14 and later

By default, the DirectoryIndex is selected and returned transparently to the client. DirectoryIndexRedirect causes an external redirect to instead be issued.

The argument can be:

Example

DirectoryIndexRedirect on

A request for http://example.com/docs/ would return a temporary redirect to http://example.com/docs/index.html if it exists.

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

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 resource, but with trailing slash for some good reasons:

If you don't want this effect and the reasons above don't apply to you, you can turn off the redirect as shown below. However, be aware that there are possible security implications to doing this.

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

Also note that some browsers may erroneously change POST requests into GET (thus discarding POST data) when a redirect is issued.

top

FallbackResource Directive

Description:Define a default URL for requests that don't map to a file
Syntax:FallbackResource disabled | local-url
Default:disabled - httpd will return 404 (Not Found)
Context:server config, virtual host, directory, .htaccess
Override:Indexes
Status:Base
Module:mod_dir
Compatibility:The disabled argument is available in version 2.4.4 and later

Use this to set a handler for any URL that doesn't map to anything in your filesystem, and would otherwise return HTTP 404 (Not Found). For example

FallbackResource /not-404.php

will cause requests for non-existent files to be handled by not-404.php, while requests for files that exist are unaffected.

It is frequently desirable to have a single file or resource handle all requests to a particular directory, except those requests that correspond to an existing file or script. This is often referred to as a 'front controller.'

In earlier versions of httpd, this effect typically required mod_rewrite, and the use of the -f and -d tests for file and directory existence. This now requires only one line of configuration.

FallbackResource /index.php

Existing files, such as images, css files, and so on, will be served normally.

Use the disabled argument to disable that feature if inheritance from a parent directory is not desired.

In a sub-URI, such as http://example.com/blog/ this sub-URI has to be supplied as local-url:

<Directory "/web/example.com/htdocs/blog">
    FallbackResource /blog/index.php
</Directory>
<Directory "/web/example.com/htdocs/blog/images">
    FallbackResource disabled
</Directory>

A fallback handler (in the above case, /blog/index.php) can access the original requested URL via the server variable REQUEST_URI. For example, to access this variable in PHP, use $_SERVER['REQUEST_URI'].

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_env.html.en0000664000175100017510000002715214737542416020550 0ustar covenercovener mod_env - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_env

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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 internal environment variables that are used by various Apache HTTP Server modules. These variables are also provided to CGI scripts as native system environment variables, and available for use in 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.

Support Apache!

Directives

Bugfix checklist

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 native system environment variables to make available as internal environment variables, which are available to Apache HTTP Server modules as well as propagated to CGI scripts and SSI pages. Values come from the native OS 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 internal environment variable, which is then available to Apache HTTP Server modules, and passed on to CGI scripts and SSI pages.

Example

SetEnv SPECIAL_PATH /foo/bin

If you omit the value argument, the variable is set to an empty string.

The internal environment variables set by this directive are set after most early request processing directives are run, such as access control and URI-to-filename mapping. If the environment variable you're setting is meant as input into this early phase of processing such as the RewriteRule directive, you should instead set the environment variable with SetEnvIf.

See also

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 internal environment variables from those passed on to CGI scripts and SSI pages.

Example

UnsetEnv LD_LIBRARY_PATH

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_filter.html.en0000664000175100017510000007633514737542416021254 0ustar covenercovener mod_filter - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_filter

Available Languages:  en  |  fr 

Description:Context-sensitive smart filter configuration module
Status:Base
Module Identifier:filter_module
Source File:mod_filter.c
Compatibility:Version 2.1 and later

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

Support Apache!

Topics

Directives

Bugfix checklist

See also

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 complex boolean expressions This generalises the limited flexibility offered by AddOutputFilterByType.

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 final argument to FilterProvider is an expression: the provider will be selected to run for a request if and only if the expression evaluates to true. The expression may evaluate HTTP request or response headers, environment variables, or the Handler used by this request. Unlike earlier versions, mod_filter now supports complex expressions involving multiple criteria with AND / OR logic (&& / ||) and brackets. The details of the expression syntax are described in the ap_expr documentation.
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

Filtering and Response Status

mod_filter normally only runs filters on responses with HTTP status 200 (OK). If you want to filter documents with other response statuses, you can set the filter-errordocs environment variable, and it will work on all responses regardless of status. To refine this further, you can use expression conditions with FilterProvider.

top

Upgrading from Apache HTTP Server 2.2 Configuration

The FilterProvider directive has changed from httpd 2.2: the match and dispatch arguments are replaced with a single but more versatile expression. In general, you can convert a match/dispatch pair to the two sides of an expression, using something like:

"dispatch = 'match'"

The Request headers, Response headers and Environment variables are now interpreted from syntax %{req:foo}, %{resp:foo} and %{env:foo} respectively. The variables %{HANDLER} and %{CONTENT_TYPE} are also supported.

Note that the match no longer support substring matches. They can be replaced by regular expression matches.

top

Examples

Server side Includes (SSI)
A simple case of replacing AddOutputFilterByType
FilterDeclare SSI
FilterProvider SSI INCLUDES "%{CONTENT_TYPE} =~ m|^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} = m|^image/(jpeg|gif|png)|"
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:

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 for back-compatibility with Apache 2.0 modules. For httpd 2.1 and later, the ap_register_output_filter_protocol and ap_filter_protocol API enables filter modules to declare their own behaviour.

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.

At the time of writing, this feature is largely untested, as modules in common use are designed to work with 2.0. Modules using it should test it carefully.

top

AddOutputFilterByType Directive

Description:assigns an output filter to a particular media-type
Syntax:AddOutputFilterByType filter[;filter...] media-type [media-type] ...
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Base
Module:mod_filter
Compatibility:Had severe limitations before being moved to mod_filter in version 2.3.7

This directive activates a particular output filter for a request depending on the response media-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>

See also

top

FilterChain Directive

Description:Configure the filter chain
Syntax:FilterChain [+=-@!]filter-name ...
Context:server config, virtual host, directory, .htaccess
Override:Options
Status:Base
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:Base
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:Base
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.

Flags specified with this directive are merged with the flags that underlying providers may have registered with mod_filter. For example, a filter may internally specify the equivalent of change=yes, but a particular configuration of the module can override with change=no.

proto-flags is one or more of

change=yes|no
Specifies whether the filter changes the content, including possibly the content length. The "no" argument is supported in 2.4.7 and later.
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 expression
Context:server config, virtual host, directory, .htaccess
Override:Options
Status:Base
Module:mod_filter

This directive registers a provider for the smart filter. The provider will be called if and only if the expression declared evaluates to true when the harness is first called.

provider-name must have been registered by loading a module that registers the name with ap_register_output_filter.

expression is an ap_expr.

See also

top

FilterTrace Directive

Description:Get debug/diagnostic information from mod_filter
Syntax:FilterTrace filter-name level
Context:server config, virtual host, directory
Status:Base
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  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_heartmonitor.html.en0000664000175100017510000003017214737542416022467 0ustar covenercovener mod_heartmonitor - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_heartmonitor

Available Languages:  en  |  fr 

Description:Centralized monitor for mod_heartbeat origin servers
Status:Experimental
Module Identifier:heartmonitor_module
Source File:mod_heartmonitor.c
Compatibility:Available in Apache 2.3 and later

Summary

mod_heartmonitor listens for server status messages generated by mod_heartbeat enabled origin servers and makes their status available to mod_lbmethod_heartbeat. This allows ProxyPass to use the "heartbeat" lbmethod inside of ProxyPass.

This module uses the services of mod_slotmem_shm when available instead of flat-file storage. No configuration is required to use mod_slotmem_shm.

To use mod_heartmonitor, mod_status and mod_watchdog must be either a static modules or, if a dynamic module, it must be loaded before mod_heartmonitor.
Support Apache!

Directives

Bugfix checklist

See also

top

HeartbeatListen Directive

Description:multicast address to listen for incoming heartbeat requests
Syntax:HeartbeatListen addr:port
Default:disabled
Context:server config
Status:Experimental
Module:mod_heartmonitor

The HeartbeatListen directive specifies the multicast address on which the server will listen for status information from mod_heartbeat-enabled servers. This address will usually correspond to a configured HeartbeatAddress on an origin server.

HeartbeatListen 239.0.0.1:27999

This module is inactive until this directive is used.

top

HeartbeatMaxServers Directive

Description:Specifies the maximum number of servers that will be sending heartbeat requests to this server
Syntax:HeartbeatMaxServers number-of-servers
Default:HeartbeatMaxServers 10
Context:server config
Status:Experimental
Module:mod_heartmonitor
Compatibility:The value of 0 is accepted only in 2.4.55 and above

The HeartbeatMaxServers directive specifies the maximum number of servers that will be sending requests to this monitor server. It is used to control the size of the shared memory allocated to store the heartbeat info when mod_slotmem_shm is in use.

For using flat-file storage (without loading mod_slotmem_shm), this must be set to 0. The value must be either 0, or bigger or equals 10.

top

HeartbeatStorage Directive

Description:Path to store heartbeat data when using flat-file storage
Syntax:HeartbeatStorage file-path
Default:HeartbeatStorage logs/hb.dat
Context:server config
Status:Experimental
Module:mod_heartmonitor

The HeartbeatStorage directive specifies the path to store heartbeat data. This flat-file is used only when mod_slotmem_shm is not loaded and HeartbeatMaxServers is set to 0.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_remoteip.html.en0000664000175100017510000006532014737542416021603 0ustar covenercovener mod_remoteip - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_remoteip

Available Languages:  en  |  fr 

Description:Replaces the original client IP address for the connection with the useragent IP address list presented by a proxies or a load balancer via the request headers.
Status:Base
Module Identifier:remoteip_module
Source File:mod_remoteip.c

Summary

This module is used to treat the useragent which initiated the request as the originating useragent as identified by httpd for the purposes of authorization and logging, even where that useragent is behind a load balancer, front end server, or proxy server.

The module overrides the client IP address for the connection with the useragent IP address reported in the request header configured with the RemoteIPHeader directive.

Additionally, this module implements the server side of HAProxy's PROXY Protocol when using the RemoteIPProxyProtocol directive.

Once replaced as instructed, this overridden useragent IP address is then used for the mod_authz_host Require ip feature, is reported by mod_status, and is recorded by mod_log_config %a and core %a format strings. The underlying client IP of the connection is available in the %{c}a format string.

It is critical to only enable this behavior from intermediate hosts (proxies, etc) which are trusted by this server, since it is trivial for the remote useragent to impersonate another useragent.
Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Remote IP Processing

Apache by default identifies the useragent with the connection's client_ip value, and the connection remote_host and remote_logname are derived from this value. These fields play a role in authentication, authorization and logging and other purposes by other loadable modules.

mod_remoteip overrides the client IP of the connection with the advertised useragent IP as provided by a proxy or load balancer, for the duration of the request. A load balancer might establish a long lived keepalive connection with the server, and each request will have the correct useragent IP, even though the underlying client IP address of the load balancer remains unchanged.

When multiple, comma delimited useragent IP addresses are listed in the header value, they are processed in Right-to-Left order. Processing halts when a given useragent IP address is not trusted to present the preceding IP address. The header field is updated to this remaining list of unconfirmed IP addresses, or if all IP addresses were trusted, this header is removed from the request altogether.

In overriding the client IP, the module stores the list of intermediate hosts in a remoteip-proxy-ip-list note, which mod_log_config can record using the %{remoteip-proxy-ip-list}n format token. If the administrator needs to store this as an additional header, this same value can also be recording as a header using the directive RemoteIPProxiesHeader.

IPv4-over-IPv6 Mapped Addresses

As with httpd in general, any IPv4-over-IPv6 mapped addresses are recorded in their IPv4 representation.

Internal (Private) Addresses

All internal addresses 10/8, 172.16/12, 192.168/16, 169.254/16 and 127/8 blocks (and IPv6 addresses outside of the public 2000::/3 block) are only evaluated by mod_remoteip when RemoteIPInternalProxy internal (intranet) proxies are registered.
top

RemoteIPHeader Directive

Description:Declare the header field which should be parsed for useragent IP addresses
Syntax:RemoteIPHeader header-field
Default:none
Context:server config, virtual host
Status:Base
Module:mod_remoteip

The RemoteIPHeader directive triggers mod_remoteip to treat the value of the specified header-field header as the useragent IP address, or list of intermediate useragent IP addresses, subject to further configuration of the RemoteIPInternalProxy and RemoteIPTrustedProxy directives. Unless these other directives are used, mod_remoteip will trust all hosts presenting a RemoteIPHeader IP value.

Internal (Load Balancer) Example

RemoteIPHeader X-Client-IP

Proxy Example

RemoteIPHeader X-Forwarded-For
top

RemoteIPInternalProxy Directive

Description:Declare client intranet IP addresses trusted to present the RemoteIPHeader value
Syntax:RemoteIPInternalProxy proxy-ip|proxy-ip/subnet|hostname ...
Context:server config, virtual host
Status:Base
Module:mod_remoteip

The RemoteIPInternalProxy directive adds one or more addresses (or address blocks) to trust as presenting a valid RemoteIPHeader value of the useragent IP. Unlike the RemoteIPTrustedProxy directive, any IP address presented in this header, including private intranet addresses, are trusted when passed from these proxies.

Internal (Load Balancer) Example

RemoteIPHeader X-Client-IP
RemoteIPInternalProxy 10.0.2.0/24
RemoteIPInternalProxy gateway.localdomain
top

RemoteIPInternalProxyList Directive

Description:Declare client intranet IP addresses trusted to present the RemoteIPHeader value
Syntax:RemoteIPInternalProxyList filename
Context:server config, virtual host
Status:Base
Module:mod_remoteip

The RemoteIPInternalProxyList directive specifies a file parsed at startup, and builds a list of addresses (or address blocks) to trust as presenting a valid RemoteIPHeader value of the useragent IP.

The '#' hash character designates a comment line, otherwise each whitespace or newline separated entry is processed identically to the RemoteIPInternalProxy directive.

Internal (Load Balancer) Example

RemoteIPHeader X-Client-IP
RemoteIPInternalProxyList conf/trusted-proxies.lst

conf/trusted-proxies.lst contents

# Our internally trusted proxies;
10.0.2.0/24         #Everyone in the testing group
gateway.localdomain #The front end balancer
top

RemoteIPProxiesHeader Directive

Description:Declare the header field which will record all intermediate IP addresses
Syntax:RemoteIPProxiesHeader HeaderFieldName
Context:server config, virtual host
Status:Base
Module:mod_remoteip

The RemoteIPProxiesHeader directive specifies a header into which mod_remoteip will collect a list of all of the intermediate client IP addresses trusted to resolve the useragent IP of the request. Note that intermediate RemoteIPTrustedProxy addresses are recorded in this header, while any intermediate RemoteIPInternalProxy addresses are discarded.

Example

RemoteIPHeader X-Forwarded-For
RemoteIPProxiesHeader X-Forwarded-By
top

RemoteIPProxyProtocol Directive

Description:Enable or disable PROXY protocol handling
Syntax:RemoteIPProxyProtocol On|Off
Context:server config, virtual host
Status:Base
Module:mod_remoteip
Compatibility:RemoteIPProxyProtocol is only available in httpd 2.4.31 and newer

The RemoteIPProxyProtocol directive enables or disables the reading and handling of the PROXY protocol connection header. If enabled with the On flag, the upstream client must send the header every time it opens a connection or the connection will be aborted unless it is in the list of disabled hosts provided by the RemoteIPProxyProtocolExceptions directive.

While this directive may be specified in any virtual host, it is important to understand that because the PROXY protocol is connection based and protocol agnostic, the enabling and disabling is actually based on IP address and port. This means that if you have multiple name-based virtual hosts for the same host and port, and you enable it for any one of them, then it is enabled for all of them (with that host and port). It also means that if you attempt to enable the PROXY protocol in one and disable in the other, that won't work; in such a case, the last one wins and a notice will be logged indicating which setting was being overridden.

Listen 80
<VirtualHost *:80>
    ServerName www.example.com
    RemoteIPProxyProtocol On

    #Requests to this virtual host must have a PROXY protocol
    # header provided. If it is missing, the connection will
    # be aborted
</VirtualHost>

Listen 8080
<VirtualHost *:8080>
    ServerName www.example.com
    RemoteIPProxyProtocol On
    RemoteIPProxyProtocolExceptions 127.0.0.1 10.0.0.0/8

    #Requests to this virtual host must have a PROXY protocol
    # header provided. If it is missing, the connection will
    # be aborted except when coming from localhost or the
    # 10.x.x.x RFC1918 range
</VirtualHost>
top

RemoteIPProxyProtocolExceptions Directive

Description:Disable processing of PROXY header for certain hosts or networks
Syntax:RemoteIPProxyProtocolExceptions host|range [host|range] [host|range]
Context:server config, virtual host
Status:Base
Module:mod_remoteip
Compatibility:RemoteIPProxyProtocolExceptions is only available in httpd 2.4.31 and newer

The RemoteIPProxyProtocol directive enables or disables the reading and handling of the PROXY protocol connection header. Sometimes it is desirable to require clients to provide the PROXY header, but permit other clients to connect without it. This directive allows a server administrator to configure a single host or CIDR range of hosts that may do so. This is generally useful for monitoring and administrative traffic to a virtual host direct to the server behind the upstream load balancer.

top

RemoteIPTrustedProxy Directive

Description:Declare client intranet IP addresses trusted to present the RemoteIPHeader value
Syntax:RemoteIPTrustedProxy proxy-ip|proxy-ip/subnet|hostname ...
Context:server config, virtual host
Status:Base
Module:mod_remoteip

The RemoteIPTrustedProxy directive adds one or more addresses (or address blocks) to trust as presenting a valid RemoteIPHeader value of the useragent IP. Unlike the RemoteIPInternalProxy directive, any intranet or private IP address reported by such proxies, including the 10/8, 172.16/12, 192.168/16, 169.254/16 and 127/8 blocks (or outside of the IPv6 public 2000::/3 block) are not trusted as the useragent IP, and are left in the RemoteIPHeader header's value.

Trusted (Load Balancer) Example

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.2.16/28
RemoteIPTrustedProxy proxy.example.com
top

RemoteIPTrustedProxyList Directive

Description:Declare client intranet IP addresses trusted to present the RemoteIPHeader value
Syntax:RemoteIPTrustedProxyList filename
Context:server config, virtual host
Status:Base
Module:mod_remoteip

The RemoteIPTrustedProxyList directive specifies a file parsed at startup, and builds a list of addresses (or address blocks) to trust as presenting a valid RemoteIPHeader value of the useragent IP.

The '#' hash character designates a comment line, otherwise each whitespace or newline separated entry is processed identically to the RemoteIPTrustedProxy directive.

Trusted (Load Balancer) Example

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxyList conf/trusted-proxies.lst

conf/trusted-proxies.lst contents

# Identified external proxies;
192.0.2.16/28 #wap phone group of proxies
proxy.isp.example.com #some well known ISP

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_file_cache.html.en0000664000175100017510000003663414737542416022027 0ustar covenercovener mod_file_cache - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_file_cache

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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. 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 derivatives, 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 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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_heartbeat.html.en0000664000175100017510000002305714737542416021717 0ustar covenercovener mod_heartbeat - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_heartbeat

Available Languages:  en  |  fr 

Description:Sends messages with server status to frontend proxy
Status:Experimental
Module Identifier:heartbeat_module
Source File:mod_heartbeat
Compatibility:Available in Apache 2.3 and later

Summary

mod_heartbeat sends multicast messages to a mod_heartmonitor listener that advertises the servers current connection count. Usually, mod_heartmonitor will be running on a proxy server with mod_lbmethod_heartbeat loaded, which allows ProxyPass to use the "heartbeat" lbmethod inside of ProxyPass.

mod_heartbeat itself is loaded on the origin server(s) that serve requests through the proxy server(s).

To use mod_heartbeat, mod_status and mod_watchdog must be either a static modules or, if a dynamic module, must be loaded before mod_heartbeat.
Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Consuming mod_heartbeat Output

Every 1 second, this module generates a single multicast UDP packet, containing the number of busy and idle workers. The packet is a simple ASCII format, similar to GET query parameters in HTTP.

An Example Packet

v=1&ready=75&busy=0

Consumers should handle new variables besides busy and ready, separated by '&', being added in the future.

top

HeartbeatAddress Directive

Description:Multicast address for heartbeat packets
Syntax:HeartbeatAddress addr:port
Default:disabled
Context:server config
Status:Experimental
Module:mod_heartbeat

The HeartbeatAddress directive specifies the multicast address to which mod_heartbeat will send status information. This address will usually correspond to a configured HeartbeatListen on a frontend proxy system.

HeartbeatAddress 239.0.0.1:27999

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ext_filter.html.en0000664000175100017510000004433614737542416022130 0ustar covenercovener mod_ext_filter - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_ext_filter

Available Languages:  en  |  fr  |  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:

Even when the performance characteristics are not suitable for production use, mod_ext_filter can be used as a prototype environment for filters.

Support Apache!

Topics

Directives

Bugfix checklist

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
</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_headers 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>

You can do the same thing using mod_substitute without invoking an external process.

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 available in Apache 2.1 and later.
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 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

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.
Onfail=[abort|remove]
Determines how to proceed if the external filter program cannot be started. With abort (the default value) the request will be aborted. With remove, the filter is removed and the request continues without it.
ExtFilterOptions LogStderr

Messages written to the filter's standard error will be stored in the Apache error log.

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_imagemap.html.en0000664000175100017510000005234514737542416021542 0ustar covenercovener mod_imagemap - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_imagemap

Available Languages:  en  |  fr  |  ko 

Description:Server-side imagemap processing
Status:Base
Module Identifier:imagemap_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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

New Features

The imagemap module adds some new features that were not possible with previously distributed imagemap programs.

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 be 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 be 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://example.com/">Menu text</a>

If no quoted text is present, the name of the link will be used as the text:

<a href="http://example.com/">http://example.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.example.com/lincoln/feedback/ 195,0 305,27
rect another_file "in same directory as referer" 306,0 419,27
point http://www.zyzzyva.example.com/ 100,100
point http://www.tripod.example.com/ 200,200
rect mailto:nate@tripod.example.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
Default:ImapMenu formatted
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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_headers.html.en0000664000175100017510000010355214737542416021372 0ustar covenercovener mod_headers - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_headers

Available Languages:  en  |  fr  |  ja  |  ko 

Description:Customization of HTTP request and response headers
Status:Extension
Module Identifier:headers_module
Source File:mod_headers.c

Summary

This module provides directives to control and modify HTTP request and response headers. Headers can be merged, replaced or removed.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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 directives 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. 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 set MyHeader "%D %t"

    results in this header being added to the response:

    MyHeader: D=3775428 t=991424704447256

  3. Say hello to Joe
    Header set 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.

  4. 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 myvalue HAVE_MyRequestHeader
    Header set MyHeader "%D %t mytext" env=HAVE_MyRequestHeader

    If the header MyRequestHeader: myvalue is present on the HTTP request, the response will contain the following header:

    MyHeader: D=3775428 t=991424704447256 mytext

  5. Enable DAV to work with Apache running HTTP through SSL hardware (problem description) by replacing https: with http: in the Destination header:
    RequestHeader edit Destination ^https: http: early
  6. Set the same header value under multiple nonexclusive conditions, but do not duplicate the value in the final header. If all of the following conditions applied to a request (i.e., if the CGI, NO_CACHE and NO_STORE environment variables all existed for the request):
    Header merge Cache-Control no-cache env=CGI
    Header merge Cache-Control no-cache env=NO_CACHE
    Header merge Cache-Control no-store env=NO_STORE

    then the response would contain the following header:

    Cache-Control: no-cache, no-store

    If append was used instead of merge, then the response would contain the following header:

    Cache-Control: no-cache, no-cache, no-store

  7. Set a test cookie if and only if the client didn't send us a cookie
    Header set Set-Cookie testcookie "expr=-z %{req:Cookie}"
  8. Append a Caching header for responses with a HTTP status code of 200
    Header append Cache-Control s-maxage=600 "expr=%{REQUEST_STATUS} == 200"
top

Header Directive

Description:Configure HTTP response headers
Syntax:Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]]
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_headers
Compatibility:SetIfEmpty available in 2.4.7 and later, expr=value available in 2.4.10 and later

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 argument determines which internal table of responses headers this directive will operate against: onsuccess (default, can be omitted) or always. The difference between the two lists is that the headers contained in the latter are added to the response even on error, and persisted across internal redirects (for example, ErrorDocument handlers). Note also that repeating this directive with both conditions makes sense in some scenarios because always is not a superset of onsuccess with respect to existing headers:

This difference between onsuccess and always is a feature that resulted as a consequence of how httpd internally stores headers for a HTTP response, since it does not offer any "normalized" single list of headers. The main problem that can arise if the following concept is not kept in mind while writing the configuration is that some HTTP responses might end up with the same header duplicated (confusing users or sometimes even HTTP clients). For example, suppose that you have a simple PHP proxy setup with mod_proxy_fcgi and your backend PHP scripts adds the X-Foo: bar header to each HTTP response. As described above, mod_proxy_fcgi uses the always table to store headers, so a configuration like the following ends up in the wrong result, namely having the header duplicated with both values:

# X-Foo's value is set in the 'onsuccess' headers table
Header set X-Foo: baz

To circumvent this limitation, there are some known configuration patterns that can help, like the following:

# 'onsuccess' can be omitted since it is the default
Header onsuccess unset X-Foo
Header always set X-Foo "baz"

Separately from the condition parameter described above, you can limit an action based on HTTP status codes for e.g. proxied or CGI requests. See the example that uses %{REQUEST_STATUS} in the section above.

The action it performs is determined by the first argument (second argument if a condition is specified). This can be one of the following values:

Warning

Please read the difference between always and onsuccess headers list described above before start reading the actions list, since that important concept still applies. Each action, in fact, works as described but only on the target headers list.

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 set, append or merge should be used instead.
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.
echo
Request headers with this name are echoed back in the response headers. header may be a regular expression. value must be omitted.
edit
edit*
If this response header exists, its value is transformed according to a regular expression search-and-replace. The value argument is a regular expression, and the replacement is a replacement string, which may contain backreferences or format specifiers. The edit form will match and replace exactly once in a header value, whereas the edit* form will replace every instance of the search pattern if it appears more than once.
merge
The response header is appended to any existing header of the same name, unless the value to be appended already appears in the header's comma-delimited list of values. 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. Values are compared in a case sensitive manner, and after all format specifiers have been processed. Values in double quotes are considered different from otherwise identical unquoted values.
set
The response header is set, replacing any previous header with this name. The value may be a format string.
setifempty
The request header is set, but only if there is no previous header with this name.
The Content-Type header is a special use case since there might be the chance that its value have been determined but the header is not part of the response when setifempty is evaluated. It is safer to use set for this use case like in the following example:
Header set Content-Type "text/plain" "expr=-z %{CONTENT_TYPE}"
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.
note
The value of the named response header is copied into an internal note whose name is given by value. This is useful if a header sent by a CGI or proxied resource is configured to be unset but should also be logged.
Available in 2.4.7 and later.

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, merge, add, unset and edit. The header name for echo is case sensitive and may be a regular expression.

For set, append, merge and add a value is specified as the next argument. If value contains spaces, it should be surrounded by double quotes. value may be a character string, a string containing mod_headers specific format specifiers (and character literals), or an ap_expr expression prefixed with expr=

The following format specifiers are supported in value:

FormatDescription
%% The percent sign
%t The time the request was received in Universal Coordinated Time since the epoch (Jan. 1, 1970) measured in microseconds. The value is preceded by t=.
%D The 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=. The value is measured in microseconds.
%l The current load averages of the actual server itself. It is designed to expose the values obtained by getloadavg() and this represents the current load average, the 5 minute average, and the 15 minute average. The value is preceded by l= with each average separated by /.
Available in 2.4.4 and later.
%i The current idle percentage of httpd (0 to 100) based on available processes and threads. The value is preceded by i=.
Available in 2.4.4 and later.
%b The current busy percentage of httpd (0 to 100) based on available processes and threads. The value is preceded by b=.
Available in 2.4.4 and later.
%{VARNAME}e The contents of the environment variable VARNAME.
%{VARNAME}s The contents of the SSL environment variable VARNAME, 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.

Note on expression values

When the value parameter uses the ap_expr parser, some expression syntax will differ from examples that evaluate boolean expressions such as <If>:

  • The starting point of the grammar is 'string' rather than 'expr'.
  • Function calls use the %{funcname:arg} syntax rather than funcname(arg).
  • Multi-argument functions are not currently accessible from this starting point
  • Quote the entire parameter, such as
    Header set foo-checksum "expr=%{md5:foo}"

For edit there is both a value argument which is a regular expression, and an additional replacement string. As of version 2.4.7 the replacement string may also contain format specifiers.

The Header directive may be followed by an additional argument, which may be any of:

early
Specifies early processing.
env=[!]varname
The directive is applied if and only if the environment variable varname exists. A ! in front of varname reverses the test, so the directive applies only if varname is unset.
expr=expression
The directive is applied if and only if expression evaluates to true. Details of expression syntax and evaluation are documented in the ap_expr documentation.
# This delays the evaluation of the condition clause compared to <If>
Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path.php$#"

Except in early mode, the Header directives are processed just before the response is sent to the network. This means that it is possible to set and/or override most headers, except for some headers added by the HTTP header filter. Prior to 2.2.12, it was not possible to change the Content-Type header with this directive.

top

RequestHeader Directive

Description:Configure HTTP request headers
Syntax:RequestHeader add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]]
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_headers
Compatibility:SetIfEmpty available in 2.4.7 and later, expr=value available in 2.4.10 and later

This directive can replace, merge, change 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:

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 set, append or merge should be used instead.
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.
edit
edit*
If this request header exists, its value is transformed according to a regular expression search-and-replace. The value argument is a regular expression, and the replacement is a replacement string, which may contain backreferences or format specifiers. The edit form will match and replace exactly once in a header value, whereas the edit* form will replace every instance of the search pattern if it appears more than once.
merge
The request header is appended to any existing header of the same name, unless the value to be appended already appears in the existing header's comma-delimited list of values. 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. Values are compared in a case sensitive manner, and after all format specifiers have been processed. Values in double quotes are considered different from otherwise identical unquoted values.
set
The request header is set, replacing any previous header with this name
setifempty
The request header is set, but only if there is no previous header with this name.
Available in 2.4.7 and later.
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 set, append, merge and add a value is given as the third argument. If a 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. For edit both a value and a replacement are required, and are a regular expression and a replacement string respectively.

The RequestHeader directive may be followed by an additional argument, which may be any of:

early
Specifies early processing.
env=[!]varname
The directive is applied if and only if the environment variable varname exists. A ! in front of varname reverses the test, so the directive applies only if varname is unset.
expr=expression
The directive is applied if and only if expression evaluates to true. Details of expression syntax and evaluation are documented in the ap_expr documentation.

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ident.html.en0000664000175100017510000002370314737542416021061 0ustar covenercovener mod_ident - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_ident

Available Languages:  en  |  fr  |  ja  |  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.

Support Apache!

Directives

Bugfix checklist

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_include.html.en0000664000175100017510000016755314737542416021415 0ustar covenercovener mod_include - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_include

Available Languages:  en  |  fr  |  ja 

Description:Server-parsed html documents (Server Side Includes)
Status:Base
Module Identifier:include_module
Source File:mod_include.c

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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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

Available 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
comment SSI comment
config configure output formats
echo print variables
exec execute external programs
fsize print size of a file
flastmod print last modification time of a file
include include a file
printenv print all available variables
set set 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 comment Element

This command doesn't output anything. Its only use is to add comments within a file. These comments are not printed.

This syntax is available in version 2.4.21 and later.

<!--#comment Blah Blah Blah -->
   or
<!--#comment text="Blah Blah Blah" -->

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.

<!--#config echomsg="[Value Undefined]" -->

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.

<!--#config errmsg="[Oops, something broke.]" -->

sizefmt

The value sets the format to be used when 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".

<!--#config sizefmt="abbrev" -->

timefmt

The value is a string to be used by the strftime(3) library routine when printing dates.

<!--#config timefmt=""%R, %B %d, %Y"" -->

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

Specifies whether Apache should strip an encoding from the variable before processing the variable further. The default is none, where no decoding will be done. If set to url, then URL decoding (also known as %-encoding; this is appropriate for use within URLs in links, etc.) will be performed. If set to urlencoded, application/x-www-form-urlencoded compatible encoding (found in query strings) will be stripped. If set to base64, base64 will be decoded, and if set to entity, HTML entity encoding will be stripped. Decoding is done prior to any further encoding on the variable. Multiple encodings can be stripped by specifying more than one comma separated encoding. The decoding setting will remain in effect until the next decoding attribute is encountered, or the element ends.

The decoding attribute must precede the corresponding var attribute to be effective.

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. If set to urlencoded, application/x-www-form-urlencoded compatible encoding will be performed instead, and should be used with query strings. If set to base64, base64 encoding 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.

In order to avoid cross-site scripting issues, you should always encode user supplied data.

Example

<!--#echo encoding="entity" var="QUERY_STRING" -->

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

This file is <!--#fsize file="mod_include.html" --> bytes.

The value of file cannot start with a slash (/), nor can it contain ../ so as to refer to a file above the current directory or outside of the document root. Attempting to so will result in the error message: The given path was above the root path.
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.

This file is <!--#fsize virtual="/docs/mod/mod_include.html" --> bytes.

Note that in many cases these two are exactly the same thing. However, the file attribute doesn't respect URL-space aliases.

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, and may appear more than once in an include element; an inclusion is done for each attribute given to the include command in turn. 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.

If the KeptBodySize directive is correctly configured and valid for this included file, attempts to POST requests to the enclosing HTML document will be passed through to subrequests as POST requests as well. Without the directive, all subrequests are processed as GET requests.

onerror

The value is a (%-encoded) URL-path which is shown should a previous attempt to include a file or virtual attribute failed. To be effective, this attribute must be specified after the file or virtual attributes being covered. If the attempt to include the onerror path fails, or if onerror is not specified, the default error message will be included.

# Simple example
<!--#include virtual="/not-exist.html" onerror="/error.html" -->

# Dedicated onerror paths
<!--#include virtual="/path-a.html" onerror="/error-a.html" virtual="/path-b.html" onerror="/error-b.html" -->

The printenv Element

This prints out a plain text 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

<pre> <!--#printenv --> </pre>

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

Specifies whether Apache should strip an encoding from the variable before processing the variable further. The default is none, where no decoding will be done. If set to url, urlencoded, base64 or entity, URL decoding, application/x-www-form-urlencoded decoding, base64 decoding or HTML entity decoding will be performed respectively. More than one decoding can be specified by separating with commas. The decoding setting will remain in effect until the next decoding attribute is encountered, or the element ends. The decoding attribute must precede the corresponding var attribute to be effective.

encoding

Specifies how Apache should encode special characters contained in the variable before setting them. The default is none, where no encoding will be done. If set to url, urlencoding, base64 or entity, URL encoding, application/x-www-form-urlencoded encoding, base64 encoding or HTML entity encoding will be performed respectively. More than one encoding can be specified by separating with commas. The encoding setting will remain in effect until the next encoding attribute is encountered, or the element ends. The encoding attribute must precede the corresponding var attribute to be effective. Encodings are applied after all decodings have been stripped.

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_ARGS
This variable contains the query string of the active SSI document, or the empty string if a query string is not included. For subrequests invoked through the include SSI directive, QUERY_STRING will represent the query string of the subrequest and DOCUMENT_ARGS will represent the query string of the SSI document. (Available in Apache HTTP Server 2.4.19 and later.)
DOCUMENT_NAME
The filename (excluding directories) of the document requested by the user.
DOCUMENT_PATH_INFO
The trailing pathname information. See directive AcceptPathInfo for more information about PATH_INFO.
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. Note also that if the URL is modified internally (e.g. by an alias or directoryindex), the modified URL is shown.
LAST_MODIFIED
The last modification date of the document requested by the user.
QUERY_STRING_UNESCAPED
If a query string is present in the request for the active SSI document, this variable contains the (%-decoded) query string, which is escaped for shell usage (special characters like & etc. are preceded by backslashes). It is not set if a query string is not present. Use DOCUMENT_ARGS if shell escaping is not desired.
USER_NAME
The user name of the owner of the file.
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. If SSILegacyExprParser is set to on, substitution also occurs in the arguments to conditional operators. You can insert a literal dollar sign into the string using backslash quoting:

<!--#set var="cur" value="\$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".

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 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 a boolean expression which follows the ap_expr syntax. The syntax can be changed to be compatible with Apache HTTPD 2.2.x using SSILegacyExprParser.

The SSI variables set with the var element are exported into the request environment and can be accessed with the reqenv function. As a short-cut, the function name v is also available inside mod_include.

The below example will print "from local net" if client IP address belongs to the 10.0.0.0/8 subnet.

<!--#if expr='-R "10.0.0.0/8"' -->
from local net
<!--#else -->
from somewhere else
<!--#endif -->

The below example will print "foo is bar" if the variable foo is set to the value "bar".

<!--#if expr='v("foo") = "bar"' -->
foo is bar
<!--#endif -->

Reference Documentation

See also: Expressions in Apache HTTP Server, for a complete reference and examples. The restricted functions are not available inside mod_include

top

Legacy expression syntax

This section describes the syntax of the #if expr element if SSILegacyExprParser is set to on.

string
true if string is not empty
-A string

true if the URL represented by the string is accessible by configuration, false otherwise. This is useful where content on a page is to be hidden from users who are not authorized to view the URL, such as a link to that URL. Note that the URL is only tested for whether access would be granted, not whether the URL exists.

Example

<!--#if expr="-A /private" -->
Click <a href="/private">here</a> to access private information.
<!--#endif -->

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. The whole string matched by the regular expression is stored in the special variable $0

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.

Escaping slashes in regex strings

All slashes which are not intended to act as delimiters in your regex must be escaped. This is regardless of their meaning to the regex engine.

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

This directive changes the string that mod_include looks for to mark the end of an include element.

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

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.

SSIErrorMsg "<!-- Error -->"
top

SSIETag Directive

Description:Controls whether ETags are generated by the server.
Syntax:SSIETag on|off
Default:SSIETag off
Context:directory, .htaccess
Status:Base
Module:mod_include
Compatibility:Available in version 2.2.15 and later.

Under normal circumstances, a file filtered by mod_include may contain elements that are either dynamically generated, or that may have changed independently of the original file. As a result, by default the server is asked not to generate an ETag header for the response by adding no-etag to the request notes.

The SSIETag directive suppresses this behaviour, and allows the server to generate an ETag header. This can be used to enable caching of the output. Note that a backend server or dynamic content generator may generate an ETag of its own, ignoring no-etag, and this ETag will be passed by mod_include regardless of the value of this setting. SSIETag can take on the following values:

off
no-etag will be added to the request notes, and the server is asked not to generate an ETag. Where a server ignores the value of no-etag and generates an ETag anyway, the ETag will be respected.
on
Existing ETags will be respected, and ETags generated by the server will be passed on in the response.
top

SSILastModified Directive

Description:Controls whether Last-Modified headers are generated by the server.
Syntax:SSILastModified on|off
Default:SSILastModified off
Context:directory, .htaccess
Status:Base
Module:mod_include
Compatibility:Available in version 2.2.15 and later.

Under normal circumstances, a file filtered by mod_include may contain elements that are either dynamically generated, or that may have changed independently of the original file. As a result, by default the Last-Modified header is stripped from the response.

The SSILastModified directive overrides this behaviour, and allows the Last-Modified header to be respected if already present, or set if the header is not already present. This can be used to enable caching of the output. SSILastModified can take on the following values:

off
The Last-Modified header will be stripped from responses, unless the XBitHack directive is set to full as described below.
on
The Last-Modified header will be respected if already present in a response, and added to the response if the response is a file and the header is missing. The SSILastModified directive takes precedence over XBitHack.
top

SSILegacyExprParser Directive

Description:Enable compatibility mode for conditional expressions.
Syntax:SSILegacyExprParser on|off
Default:SSILegacyExprParser off
Context:directory, .htaccess
Status:Base
Module:mod_include
Compatibility:Available in version 2.3.13 and later.

As of version 2.3.13, mod_include has switched to the new ap_expr syntax for conditional expressions in #if flow control elements. This directive allows to switch to the old syntax which is compatible with Apache HTTPD version 2.2.x and earlier.

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

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

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

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.

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

This directive changes the string that mod_include displays when a variable is not set and "echoed".

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

The SSILastModified directive takes precedence over the XBitHack directive when SSILastModified is set to on.

Available Languages:  en  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_bybusyness.html.en0000664000175100017510000001754614737542416024052 0ustar covenercovener mod_lbmethod_bybusyness - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_lbmethod_bybusyness

Available Languages:  en  |  fr 

Description:Pending Request Counting load balancer scheduler algorithm for mod_proxy_balancer
Status:Extension
Module Identifier:lbmethod_bybusyness_module
Source File:mod_lbmethod_bybusyness.c
Compatibility:Split off from mod_proxy_balancer in 2.3

Summary

This module does not provide any configuration directives of its own. It requires the services of mod_proxy_balancer, and provides the bybusyness load balancing method.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Pending Request Counting Algorithm

Enabled via lbmethod=bybusyness, this scheduler keeps track of how many requests each worker is currently assigned at present. A new request is automatically assigned to the worker with the lowest number of active requests. This is useful in the case of workers that queue incoming requests independently of Apache, to ensure that queue length stays even and a request is always given to the worker most likely to service it the fastest and reduce latency.

In the case of multiple least-busy workers, the statistics (and weightings) used by the Request Counting method are used to break the tie. Over time, the distribution of work will come to resemble that characteristic of byrequests (as implemented by mod_lbmethod_byrequests).

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_heartbeat.html.en0000664000175100017510000002045014737542416023567 0ustar covenercovener mod_lbmethod_heartbeat - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_lbmethod_heartbeat

Available Languages:  en  |  fr 

Description:Heartbeat Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
Status:Experimental
Module Identifier:lbmethod_heartbeat_module
Source File:mod_lbmethod_heartbeat.c
Compatibility:Available in version 2.3 and later

Summary

lbmethod=heartbeat uses the services of mod_heartmonitor to balance between origin servers that are providing heartbeat info via the mod_heartbeat module.

This modules load balancing algorithm favors servers with more ready (idle) capacity over time, but does not select the server with the most ready capacity every time. Servers that have 0 active clients are penalized, with the assumption that they are not fully initialized.

Support Apache!

Directives

Bugfix checklist

See also

top

HeartbeatStorage Directive

Description:Path to read heartbeat data
Syntax:HeartbeatStorage file-path
Default:HeartbeatStorage logs/hb.dat
Context:server config
Status:Experimental
Module:mod_lbmethod_heartbeat

The HeartbeatStorage directive specifies the path to read heartbeat data. This flat-file is used only when mod_slotmem_shm is not loaded.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_debug.html.en0000664000175100017510000002425514737542416021710 0ustar covenercovener mod_log_debug - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_log_debug

Available Languages:  en  |  fr 

Description:Additional configurable debug logging
Status:Experimental
Module Identifier:log_debug_module
Source File:mod_log_debug.c
Compatibility:Available in Apache 2.3.14 and later
Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Examples

  1. Log message after request to /foo/* is processed:
    <Location "/foo/">
      LogMessage "/foo/ has been requested"
    </Location>
  2. Log message if request to /foo/* is processed in a sub-request:
    <Location "/foo/">
      LogMessage "subrequest to /foo/" hook=type_checker "expr=-T %{IS_SUBREQ}"
    </Location>
    The default log_transaction hook is not executed for sub-requests, therefore we have to use a different hook.
  3. Log message if an IPv6 client causes a request timeout:
    LogMessage "IPv6 timeout from %{REMOTE_ADDR}" "expr=-T %{IPV6} && %{REQUEST_STATUS} = 408"
    Note the placing of the double quotes for the expr= argument.
  4. Log the value of the "X-Foo" request environment variable in each stage of the request:
    <Location "/">
      LogMessage "%{reqenv:X-Foo}" hook=all
    </Location>
    Together with microsecond time stamps in the error log, hook=all also lets you determine the times spent in the different parts of the request processing.
top

LogMessage Directive

Description:Log user-defined message to error log
Syntax:LogMessage message [hook=hook] [expr=expression]
Default:Unset
Context:directory
Status:Experimental
Module:mod_log_debug

This directive causes a user defined message to be logged to the error log. The message can use variables and functions from the ap_expr syntax. References to HTTP headers will not cause header names to be added to the Vary header. The messages are logged at loglevel info.

The hook specifies before which phase of request processing the message will be logged. The following hooks are supported:

Name
pre_translate_name
translate_name
type_checker
quick_handler
map_to_storage
check_access
check_access_ex
insert_filter
check_authn
check_authz
fixups
handler
log_transaction

The default is log_transaction. The special value all is also supported, causing a message to be logged at each phase. Not all hooks are executed for every request.

The optional expression allows to restrict the message if a condition is met. The details of the expression syntax are described in the ap_expr documentation. References to HTTP headers will not cause the header names to be added to the Vary header.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_isapi.html.en0000664000175100017510000005670614737542416021074 0ustar covenercovener mod_isapi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_isapi

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Usage

In the server configuration file, use the AddHandler directive to associate ISAPI files with the isapi-handler 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-handler .dll
In older versions of the Apache server, isapi-isa was the proper handler name, rather than isapi-handler. As of 2.3 development versions of the Apache server, isapi-isa is no longer valid. You will need to change your configuration to use isapi-handler instead.

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.

Since httpd 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 httpd also supports preloading ISAPI .dlls for performance.

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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_bytraffic.html.en0000664000175100017510000002031614737542416023602 0ustar covenercovener mod_lbmethod_bytraffic - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_lbmethod_bytraffic

Available Languages:  en  |  fr 

Description:Weighted Traffic Counting load balancer scheduler algorithm for mod_proxy_balancer
Status:Extension
Module Identifier:lbmethod_bytraffic_module
Source File:mod_lbmethod_bytraffic.c
Compatibility:Split off from mod_proxy_balancer in 2.3

Summary

This module does not provide any configuration directives of its own. It requires the services of mod_proxy_balancer, and provides the bytraffic load balancing method.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Weighted Traffic Counting Algorithm

Enabled via lbmethod=bytraffic, 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 either seen or produced.

If a balancer is configured as follows:

worker a b c
lbfactor 1 2 1

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.

Note: input and output bytes are weighted the same.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_config.html.en0000664000175100017510000010675614737542416022076 0ustar covenercovener mod_log_config - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_log_config

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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 backslashes should be escaped with backslashes.

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 String Description
%% The percent sign.
%a Client IP address of the request (see the mod_remoteip module).
%{c}a Underlying peer IP address of the connection (see the mod_remoteip module).
%A Local IP-address.
%B Size of response in bytes, excluding HTTP headers.
%b Size of response in bytes, excluding HTTP headers. In CLF format, i.e. a '-' rather than a 0 when no bytes are sent.
%{VARNAME}C The contents of cookie VARNAME in the request sent to the server. Only version 0 cookies are fully supported.
%D The time taken to serve the request, in microseconds.
%{VARNAME}e The contents of the environment variable VARNAME.
%f Filename.
%h Remote hostname. Will log the IP address if HostnameLookups is set to Off, which is the default. If it logs the hostname for only a few hosts, you probably have access control directives mentioning them by name. See the Require host documentation.
%{c}h Like %h, but always reports on the hostname of the underlying TCP connection and not any modifications to the remote hostname by modules like mod_remoteip.
%H The request protocol.
%{VARNAME}i The contents of VARNAME: header line(s) in the request sent to the server. Changes made by other modules (e.g. mod_headers) affect this. If you're interested in what the request header was prior to when most modules would have modified it, use mod_setenvif to copy the header into an internal environment variable and log that value with the %{VARNAME}e described above.
%k Number of keepalive requests handled on this connection. Interesting if KeepAlive is being used, so that, for example, a '1' means the first keepalive request after the initial one, '2' the second, etc...; otherwise this is always 0 (indicating the initial request).
%l Remote logname (from identd, if supplied). This will return a dash unless mod_ident is present and IdentityCheck is set On.
%L The request log ID from the error log (or '-' if nothing has been logged to the error log for this request). Look for the matching error log line to see what request caused what error.
%m The request method.
%{VARNAME}n The contents of note VARNAME from another module.
%{VARNAME}o The contents of VARNAME: header line(s) in the reply.
%p The canonical port of the server serving the request.
%{format}p The canonical port of the server serving the request, or the server's actual port, or the client's actual port. Valid formats are canonical, local, or remote.
%P The process ID of the child that serviced the request.
%{format}P The process ID or thread ID of the child that serviced the request. Valid formats are pid, tid, and hextid.
%q The query string (prepended with a ? if a query string exists, otherwise an empty string).
%r First line of request.
%R The handler generating the response (if any).
%s Status. For requests that have been internally redirected, this is the status of the original request. Use %>s for the final status.
%t Time the request was received, in the format [18/Sep/2011:19:18:28 -0400]. The last number indicates the timezone offset from GMT
%{format}t The time, in the form given by format, which should be in an extended strftime(3) format (potentially localized). If the format starts with begin: (default) the time is taken at the beginning of the request processing. If it starts with end: it is the time when the log entry gets written, close to the end of the request processing. In addition to the formats supported by strftime(3), the following format tokens are supported:
secnumber of seconds since the Epoch
msecnumber of milliseconds since the Epoch
usecnumber of microseconds since the Epoch
msec_fracmillisecond fraction
usec_fracmicrosecond fraction
These tokens can not be combined with each other or strftime(3) formatting in the same format string. You can use multiple %{format}t tokens instead.
%T The time taken to serve the request, in seconds.
%{UNIT}T The time taken to serve the request, in a time unit given by UNIT. Valid units are ms for milliseconds, us for microseconds, and s for seconds. Using s gives the same result as %T without any format; using us gives the same result as %D. Combining %T with a unit is available in 2.4.13 and later.
%u Remote user if the request was authenticated. May be bogus if return status (%s) is 401 (unauthorized).
%U The URL path requested, not including any query string.
%v The canonical ServerName of the server serving the request.
%V The server name according to the UseCanonicalName setting.
%X Connection 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.
%I Bytes received, including request and headers. Cannot be zero. You need to enable mod_logio to use this.
%O Bytes sent, including headers. May be zero in rare cases such as when a request is aborted before a response is sent. You need to enable mod_logio to use this.
%S Bytes transferred (received and sent), including request and headers, cannot be zero. This is the combination of %I and %O. You need to enable mod_logio to use this.
%{VARNAME}^ti The contents of VARNAME: trailer line(s) in the request sent to the server.
%{VARNAME}^to The contents of VARNAME: trailer line(s) in the response sent from the server.

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 "%". The status code list may be preceded by a "!" to indicate negation.

Format String Meaning
%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.
%!200,304,302{Referer}i Logs Referer on all requests that do not return one of the three specified codes, "-" otherwise.

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.

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

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

Note: mod_cache is implemented as a quick-handler and not as a standard handler. Therefore, the %R format string will not return any handler information when content caching is involved.

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"

You can use the %{format}t directive multiple times to build up a time format using the extended format tokens like msec_frac:

Timestamp including milliseconds
"%{%d/%b/%Y %T}t.%{msec_frac}t %{%z}t"
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

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 should be used with caution as a crash might cause loss of logging data.
top

CustomLog Directive

Description:Sets filename and format of log file
Syntax:CustomLog file|pipe format|nickname [env=[!]environment-variable| expr=expression]
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. See the notes on piped logs for more information.

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. The condition can be the presence or absence (in the case of a 'env=!name' clause) of a particular variable in the server environment. Alternatively, the condition can be expressed as arbitrary boolean expression. If the condition is not satisfied, the request will not be logged. References to HTTP headers in the expression will not cause the header names to be added to the Vary header.

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

GlobalLog Directive

Description:Sets filename and format of log file
Syntax:GlobalLogfile|pipe format|nickname [env=[!]environment-variable| expr=expression]
Context:server config
Status:Base
Module:mod_log_config
Compatibility:Available in Apache HTTP Server 2.4.19 and later

The GlobalLog directive defines a log shared by the main server configuration and all defined virtual hosts.

The GlobalLog directive is identical to the CustomLog directive, apart from the following differences:

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_logio.html.en0000664000175100017510000002460614737542416021072 0ustar covenercovener mod_logio - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_logio

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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.

When KeepAlive connections are used with SSL, the overhead of the SSL handshake is reflected in the byte count of the first request on the connection. When per-directory SSL renegotiation occurs, the bytes are associated with the request that triggered the renegotiation.
Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Custom Log Formats

This module adds three 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 String Description
%I Bytes received, including request and headers, cannot be zero.
%O Bytes sent, including headers, cannot be zero.
%S Bytes transferred (received and sent), including request and headers, cannot be zero. This is the combination of %I and %O.
Available in Apache 2.4.7 and later
%^FB Delay in microseconds between when the request arrived and the first byte of the response headers are written. Only available if LogIOTrackTTFB is set to ON.
Available in Apache 2.4.13 and later

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"
top

LogIOTrackTTFB Directive

Description:Enable tracking of time to first byte (TTFB)
Syntax:LogIOTrackTTFB ON|OFF
Default:LogIOTrackTTFB OFF
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_logio
Compatibility:Apache HTTP Server 2.4.13 and later

This directive configures whether this module tracks the delay between the request being read and the first byte of the response headers being written. The resulting value may be logged with the %^FB format.

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_info.html.en0000664000175100017510000003515314737542416020713 0ustar covenercovener mod_info - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_info

Available Languages:  en  |  fr  |  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_authz_host inside the <Location> directive to limit access to your server configuration information:

<Location "/server-info">
    SetHandler server-info
    Require host example.com
</Location>

Once configured, the server information is obtained by accessing http://your.host.example.com/server-info

Support Apache!

Topics

Directives

Bugfix checklist

See also

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
    # Allow access from server itself
    Require ip 127.0.0.1

    # Additionally, allow access from local workstation
    Require ip 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
?providers
List the providers that are available on your server
top

Dumping the configuration on startup

If the config define -DDUMP_CONFIG is set, mod_info will dump the pre-parsed configuration to stdout during server startup.

httpd -DDUMP_CONFIG -k start

Pre-parsed means that directives like <IfDefine> and <IfModule> are evaluated and environment variables are replaced. However it does not represent the final state of the configuration. In particular, it does not represent the merging or overriding that may happen for repeated directives.

This is roughly equivalent to the ?config query.

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:

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

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://httpd.apache.org/docs/2.4/mod/mod_deflate.html">\
    http://httpd.apache.org/docs/2.4/mod/mod_deflate.html</a>'

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lbmethod_byrequests.html.en0000664000175100017510000003105714737542416024043 0ustar covenercovener mod_lbmethod_byrequests - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_lbmethod_byrequests

Available Languages:  en  |  fr 

Description:Request Counting load balancer scheduler algorithm for mod_proxy_balancer
Status:Extension
Module Identifier:lbmethod_byrequests_module
Source File:mod_lbmethod_byrequests.c
Compatibility:Split off from mod_proxy_balancer in 2.3

Summary

This module does not provide any configuration directives of its own. It requires the services of mod_proxy_balancer, and provides the byrequests load balancing method.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Request Counting Algorithm

Enabled via lbmethod=byrequests, 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' 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:

worker a b c d
lbfactor 25 25 25 25
lbstatus 0 0 0 0

And b gets disabled, the following schedule is produced:

worker a b c d
lbstatus -50 0 25 25
lbstatus -25 0 -25 50
lbstatus 0 0 0 0
(repeat)

That is it schedules: a c d a c d a c d ... Please note that:

worker a b c d
lbfactor 25 25 25 25

Has the exact same behavior as:

worker a b c d
lbfactor 1 1 1 1

This is because all values of lbfactor are normalized with respect to the others. For:

worker a b c
lbfactor 1 4 1

worker b will, on average, get 4 times the requests that a and c will.

The following asymmetric configuration works as one would expect:

worker a b
lbfactor 70 30
 
lbstatus -30 30
lbstatus 40 -40
lbstatus 10 -10
lbstatus -20 20
lbstatus -50 50
lbstatus 20 -20
lbstatus -10 10
lbstatus -40 40
lbstatus 30 -30
lbstatus 0 0
(repeat)

That is after 10 schedules, the schedule repeats and 7 a are selected with 3 b interspersed.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ldap.html.en0000664000175100017510000015105514737542416020700 0ustar covenercovener mod_ldap - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_ldap

Available Languages:  en  |  fr 

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

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 dependent 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) or the native Microsoft LDAP SDK. See the APR website for details.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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 500000
LDAPCacheEntries 1024
LDAPCacheTTL 600
LDAPOpCacheEntries 1024
LDAPOpCacheTTL 600

<Location "/ldap-status">
    SetHandler ldap-status

    Require host yourdomain.example.com

    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldap://127.0.0.1/dc=example,dc=com?uid?one"
    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.

LDAP connections can keep track of the ldap client credentials used when binding to an LDAP server. These credentials can be provided to LDAP servers that do not allow anonymous binds during referral chasing. To control this feature, see the LDAPReferrals and LDAPReferralHopLimit directives. By default, this feature is enabled.

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.

Note that, when group membership is being checked, any sub-group comparison results are cached to speed future sub-group comparisons.

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

    Require host yourdomain.example.com

    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldaps://127.0.0.1/dc=example,dc=com?uid?one"
    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

    Require host yourdomain.example.com

    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldap://127.0.0.1/dc=example,dc=com?uid?one" TLS
    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

    Require host yourdomain.example.com

    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    LDAPTrustedClientCert CERT_NICKNAME <nickname> [password]
    AuthLDAPURL "ldaps://127.0.0.1/dc=example,dc=com?uid?one"
    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.

Both CA and client certificates may be specified globally (LDAPTrustedGlobalCert) or per-connection (LDAPTrustedClientCert). When any settings are specified per-connection, the global settings are superseded.

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

    Require host yourdomain.example.com

    LDAPTrustedClientCert CERT_BASE64 "/certs/cert1.pem"
    LDAPTrustedClientCert KEY_BASE64 "/certs/key1.pem"
    # CA certs respecified due to per-directory client certs
    LDAPTrustedClientCert CA_DER "/certs/cacert1.der"
    LDAPTrustedClientCert CA_BASE64 "/certs/cacert2.pem"
    Satisfy any
    AuthType Basic
    AuthName "LDAP Protected"
    AuthBasicProvider ldap
    AuthLDAPURL "ldaps://127.0.0.1/dc=example,dc=com?uid?one"
    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

LDAPConnectionPoolTTL Directive

Description:Discard backend connections that have been sitting in the connection pool too long
Syntax:LDAPConnectionPoolTTL n
Default:LDAPConnectionPoolTTL -1
Context:server config, virtual host
Status:Extension
Module:mod_ldap
Compatibility:Apache HTTP Server 2.3.12 and later

Specifies the maximum age, in seconds, that a pooled LDAP connection can remain idle and still be available for use. Connections are cleaned up when they are next needed, not asynchronously.

A setting of 0 causes connections to never be saved in the backend connection pool. The default value of -1, and any other negative value, allows connections of any age to be reused.

For performance reasons, the reference time used by this directive is based on when the LDAP connection is returned to the pool, not the time of the last successful I/O with the LDAP server.

Since 2.4.10, new measures are in place to avoid the reference time from being inflated by cache hits or slow requests. First, the reference time is not updated if no backend LDAP conncetions were needed. Second, the reference time uses the time the HTTP request was received instead of the time the request is completed.

This timeout defaults to units of seconds, but accepts suffixes for milliseconds (ms), minutes (min), and hours (h).

top

LDAPConnectionTimeout Directive

Description:Specifies the socket connection timeout in seconds
Syntax:LDAPConnectionTimeout seconds
Context:server config
Status:Extension
Module:mod_ldap

This directive configures the LDAP_OPT_NETWORK_TIMEOUT (or LDAP_OPT_CONNECT_TIMEOUT) option in the underlying LDAP client library, when available. This value typically controls how long the LDAP client library will wait for the TCP connection to the LDAP server to complete.

If a connection is not successful with the timeout period, either an error will be returned or the LDAP client library will attempt to connect to a secondary LDAP server if one is specified (via a space-separated list of hostnames in the AuthLDAPURL).

The default is 10 seconds, if the LDAP client library linked with the server supports the LDAP_OPT_NETWORK_TIMEOUT option.

LDAPConnectionTimeout is only available when the LDAP client library linked with the server supports the LDAP_OPT_NETWORK_TIMEOUT (or LDAP_OPT_CONNECT_TIMEOUT) option, and the ultimate behavior is dictated entirely by the LDAP client library.
top

LDAPLibraryDebug Directive

Description:Enable debugging in the LDAP SDK
Syntax:LDAPLibraryDebug 7
Default:disabled
Context:server config
Status:Extension
Module:mod_ldap

Turns on SDK-specific LDAP debug options that generally cause the LDAP SDK to log verbose trace information to the main Apache error log. The trace messages from the LDAP SDK provide gory details that can be useful during debugging of connectivity problems with backend LDAP servers

This option is only configurable when Apache HTTP Server is linked with an LDAP SDK that implements LDAP_OPT_DEBUG or LDAP_OPT_DEBUG_LEVEL, such as OpenLDAP (a value of 7 is verbose) or Tivoli Directory Server (a value of 65535 is verbose).

The logged information will likely contain plaintext credentials being used or validated by LDAP authentication, so care should be taken in protecting and purging the error log when this directive is used.

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

LDAPReferralHopLimit Directive

Description:The maximum number of referral hops to chase before terminating an LDAP query.
Syntax:LDAPReferralHopLimit number
Default:SDK dependent, typically between 5 and 10
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_ldap

This directive, if enabled by the LDAPReferrals directive, limits the number of referral hops that are followed before terminating an LDAP query.

Support for this tunable is uncommon in LDAP SDKs.

top

LDAPReferrals Directive

Description:Enable referral chasing during queries to the LDAP server.
Syntax:LDAPReferrals On|Off|default
Default:LDAPReferrals On
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_ldap
Compatibility:The default parameter is available in Apache 2.4.7 and later

Some LDAP servers divide their directory among multiple domains and use referrals to direct a client when a domain boundary is crossed. This is similar to a HTTP redirect. LDAP client libraries may or may not chase referrals by default. This directive explicitly configures the referral chasing in the underlying SDK.

LDAPReferrals takes the following values:

"on"

When set to "on", the underlying SDK's referral chasing state is enabled, LDAPReferralHopLimit is used to override the SDK's hop limit, and an LDAP rebind callback is registered.

"off"

When set to "off", the underlying SDK's referral chasing state is disabled completely.

"default"

When set to "default", the underlying SDK's referral chasing state is not changed, LDAPReferralHopLimit is not used to override the SDK's hop limit, and no LDAP rebind callback is registered.

The directive LDAPReferralHopLimit works in conjunction with this directive to limit the number of referral hops to follow before terminating the LDAP query. When referral processing is enabled by a value of "On", client credentials will be provided, via a rebind callback, for any LDAP server requiring them.

top

LDAPRetries Directive

Description:Configures the number of LDAP server retries.
Syntax:LDAPRetries number-of-retries
Default:LDAPRetries 3
Context:server config
Status:Extension
Module:mod_ldap

The server will retry failed LDAP requests up to LDAPRetries times. Setting this directive to 0 disables retries.

LDAP errors such as timeouts and refused connections are retryable.

top

LDAPRetryDelay Directive

Description:Configures the delay between LDAP server retries.
Syntax:LDAPRetryDelay seconds
Default:LDAPRetryDelay 0
Context:server config
Status:Extension
Module:mod_ldap

If LDAPRetryDelay is set to a non-zero value, the server will delay retrying an LDAP request for the specified amount of time. Setting this directive to 0 will result in any retry to occur without delay.

LDAP errors such as timeouts and refused connections are retryable.

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 500000
Context:server config
Status:Extension
Module:mod_ldap

Specifies the number of bytes to allocate for the shared memory cache. The default is 500kb. If set to 0, shared memory caching will not be used and every HTTPD process will create its own cache.

top

LDAPTimeout Directive

Description:Specifies the timeout for LDAP search and bind operations, in seconds
Syntax:LDAPTimeout seconds
Default:LDAPTimeout 60
Context:server config
Status:Extension
Module:mod_ldap
Compatibility:Apache HTTP Server 2.3.5 and later

This directive configures the timeout for bind and search operations, as well as the LDAP_OPT_TIMEOUT option in the underlying LDAP client library, when available.

If the timeout expires, httpd will retry in case an existing connection has been silently dropped by a firewall. However, performance will be much better if the firewall is configured to send TCP RST packets instead of silently dropping packets.

Timeouts for ldap compare operations requires an SDK with LDAP_OPT_TIMEOUT, such as OpenLDAP >= 2.4.4.

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: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 independent 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:

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:

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
Status:Extension
Module:mod_ldap

The following modes are supported:

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

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_log_forensic.html.en0000664000175100017510000003141614737542416022427 0ustar covenercovener mod_log_forensic - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_log_forensic

Available Languages:  en  |  fr  |  ja  |  tr 

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 check_forensic script, which can be found in the distribution's support directory, may be helpful in evaluating the forensic log output.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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.

The log files may contain sensitive data such as the contents of Authorization: headers (which can contain passwords), so they should not be readable by anyone except 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 slashes 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  |  fr  |  ja  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_macro.html.en0000664000175100017510000003622014737542416021055 0ustar covenercovener mod_macro - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_macro

Available Languages:  en  |  fr 

Description:Provides macros within apache httpd runtime configuration files
Status:Base
Module Identifier:macro_module
Source File:mod_macro.c
Compatibility:Available in httpd 2.4.5 and later

Summary

Provides macros within Apache httpd runtime configuration files, to ease the process of creating numerous similar configuration blocks. When the server starts up, the macros are expanded using the provided parameters, and the result is processed as along with the rest of the configuration file.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Usage

Macros are defined using <Macro> blocks, which contain the portion of your configuration that needs to be repeated, complete with variables for those parts that will need to be substituted.

For example, you might use a macro to define a <VirtualHost> block, in order to define multiple similar virtual hosts:

<Macro VHost $name $domain>
<VirtualHost *:80>
    ServerName $domain
    ServerAlias www.$domain

    DocumentRoot "/var/www/vhosts/$name"
    ErrorLog "/var/log/httpd/$name.error_log"
    CustomLog "/var/log/httpd/$name.access_log" combined
</VirtualHost>
</Macro>

Macro names are case-insensitive, like httpd configuration directives. However, variable names are case sensitive.

You would then invoke this macro several times to create virtual hosts:

Use VHost example example.com
Use VHost myhost hostname.org
Use VHost apache apache.org

UndefMacro VHost

At server startup time, each of these Use invocations would be expanded into a full virtualhost, as described by the <Macro> definition.

The UndefMacro directive is used so that later macros using the same variable names don't result in conflicting definitions.

A more elaborate version of this example may be seen below in the Examples section.

top

Tips

Parameter names should begin with a sigil such as $, %, or @, so that they are clearly identifiable, and also in order to help deal with interactions with other directives, such as the core Define directive. Failure to do so will result in a warning. Nevertheless, you are encouraged to have a good knowledge of your entire server configuration in order to avoid reusing the same variables in different scopes, which can cause confusion.

Parameters prefixed with either $ or % are not escaped. Parameters prefixes with @ are escaped in quotes.

Avoid using a parameter which contains another parameter as a prefix, (For example, $win and $winter) as this may cause confusion at expression evaluation time. In the event of such confusion, the longest possible parameter name is used.

If you want to use a value within another string, it is useful to surround the parameter in braces, to avoid confusion:

<Macro DocRoot ${docroot}>
    DocumentRoot "/var/www/${docroot}/htdocs"
</Macro>
top

Examples

Virtual Host Definition

A common usage of mod_macro is for the creation of dynamically-generated virtual hosts.

## Define a VHost Macro for repetitive configurations

<Macro VHost $host $port $dir>
  Listen $port
  <VirtualHost *:$port>

    ServerName $host
    DocumentRoot "$dir"

    # Public document root
    <Directory "$dir">
        Require all granted
    </Directory>

    # limit access to intranet subdir.
    <Directory "$dir/intranet">
      Require ip 10.0.0.0/8
    </Directory>
  </VirtualHost>
</Macro>

## Use of VHost with different arguments.

Use VHost www.apache.org 80 /vhosts/apache/htdocs
Use VHost example.org 8080 /vhosts/example/htdocs
Use VHost www.example.fr 1234 /vhosts/example.fr/htdocs

Removal of a macro definition

It's recommended that you undefine a macro once you've used it. This avoids confusion in a complex configuration file where there may be conflicts in variable names.

<Macro DirGroup $dir $group>
  <Directory "$dir">
    Require group $group
  </Directory>
</Macro>

Use DirGroup /www/apache/private private
Use DirGroup /www/apache/server  admin

UndefMacro DirGroup
top

<Macro> Directive

Description:Define a configuration file macro
Syntax: <Macro name [par1 .. parN]> ... </Macro>
Context:server config, virtual host, directory
Status:Base
Module:mod_macro

The <Macro> directive controls the definition of a macro within the server runtime configuration files. The first argument is the name of the macro. Other arguments are parameters to the macro. It is good practice to prefix parameter names with any of '$%@', and not macro names with such characters.

<Macro LocalAccessPolicy>
    Require ip 10.2.16.0/24
</Macro>

<Macro RestrictedAccessPolicy $ipnumbers>
    Require ip $ipnumbers
</Macro>
top

UndefMacro Directive

Description:Undefine a macro
Syntax:UndefMacro name
Context:server config, virtual host, directory
Status:Base
Module:mod_macro

The UndefMacro directive undefines a macro which has been defined before hand.

UndefMacro LocalAccessPolicy
UndefMacro RestrictedAccessPolicy
top

Use Directive

Description:Use a macro
Syntax:Use name [value1 ... valueN]
Context:server config, virtual host, directory
Status:Base
Module:mod_macro

The Use directive controls the use of a macro. The specified macro is expanded. It must be given the same number of arguments as in the macro definition. The provided values are associated to their corresponding initial parameters and are substituted before processing.

Use LocalAccessPolicy
...
Use RestrictedAccessPolicy "192.54.172.0/24 192.54.148.0/24"

is equivalent, with the macros defined above, to:

Require ip 10.2.16.0/24
...
Require ip 192.54.172.0/24 192.54.148.0/24

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_negotiation.html.en0000664000175100017510000005256214737542416022303 0ustar covenercovener mod_negotiation - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_negotiation

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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[.000] to 1[.000], 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:
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----

Consider, for example, a resource called document.html which is available in English, French, and German. The files for each of these are called document.html.en, document.html.fr, and document.html.de, respectively. The type map file will be called document.html.var, and will contain the following:

URI: document.html

Content-language: en
Content-type: text/html
URI: document.html.en

Content-language: fr
Content-type: text/html
URI: document.html.fr

Content-language: de
Content-type: text/html
URI: document.html.de

All four of these files should be placed in the same directory, and the .var file should be associated with the type-map handler with an AddHandler directive:

AddHandler type-map .var

A request for document.html.var in this directory will result in choosing the variant which most closely matches the language preference specified in the user's Accept-Language request header.

If Multiviews is enabled, and MultiviewsMatch is set to "handlers" or "any", a request to document.html will discover document.html.var and continue negotiating with the explicit type map.

Other configuration directives, such as Alias can be used to map document.html to document.html.var.

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

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.

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

The ForceLanguagePriority directive uses the given LanguagePriority to satisfy negotiation 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 precedence 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.

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  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_lua.html.en0000664000175100017510000026736514737542416020555 0ustar covenercovener mod_lua - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_lua

Available Languages:  en  |  fr 

Description:Provides Lua hooks into various portions of the httpd request processing
Status:Extension
Module Identifier:lua_module
Source File:mod_lua.c
Compatibility:2.3 and later

Summary

This module allows the server to be extended with scripts written in the Lua programming language. The extension points (hooks) available with mod_lua include many of the hooks available to natively compiled Apache HTTP Server modules, such as mapping requests to files, generating dynamic responses, access control, authentication, and authorization

More information on the Lua programming language can be found at the the Lua website.

Warning

This module holds a great deal of power over httpd, which is both a strength and a potential security risk. It is not recommended that you use this module on a server that is shared with users you do not trust, as it can be abused to change the internal workings of httpd.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Basic Configuration

The basic module loading directive is

LoadModule lua_module modules/mod_lua.so

mod_lua provides a handler named lua-script, which can be used with a SetHandler or AddHandler directive:

<Files "*.lua">
    SetHandler lua-script
</Files>

This will cause mod_lua to handle requests for files ending in .lua by invoking that file's handle function.

For more flexibility, see LuaMapHandler.

top

Writing Handlers

In the Apache HTTP Server API, the handler is a specific kind of hook responsible for generating the response. Examples of modules that include a handler are mod_proxy, mod_cgi, and mod_status.

mod_lua always looks to invoke a Lua function for the handler, rather than just evaluating a script body CGI style. A handler function looks something like this:

example.lua
-- example handler require "string" --[[ This is the default method name for Lua handlers, see the optional function-name in the LuaMapHandler directive to choose a different entry point. --]] function handle(r) r.content_type = "text/plain" if r.method == 'GET' then r:puts("Hello Lua World!\n") for k, v in pairs( r:parseargs() ) do r:puts( string.format("%s: %s\n", k, v) ) end elseif r.method == 'POST' then r:puts("Hello Lua World!\n") for k, v in pairs( r:parsebody() ) do r:puts( string.format("%s: %s\n", k, v) ) end elseif r.method == 'PUT' then -- use our own Error contents r:puts("Unsupported HTTP method " .. r.method) r.status = 405 return apache2.OK else -- use the ErrorDocument return 501 end return apache2.OK end

This handler function just prints out the uri or form encoded arguments to a plaintext page.

This means (and in fact encourages) that you can have multiple handlers (or hooks, or filters) in the same script.

top

Writing Authorization Providers

mod_authz_core provides a high-level interface to authorization that is much easier to use than using into the relevant hooks directly. The first argument to the Require directive gives the name of the responsible authorization provider. For any Require line, mod_authz_core will call the authorization provider of the given name, passing the rest of the line as parameters. The provider will then check authorization and pass the result as return value.

The authz provider is normally called before authentication. If it needs to know the authenticated user name (or if the user will be authenticated at all), the provider must return apache2.AUTHZ_DENIED_NO_USER. This will cause authentication to proceed and the authz provider to be called a second time.

The following authz provider function takes two arguments, one ip address and one user name. It will allow access from the given ip address without authentication, or if the authenticated user matches the second argument:

authz_provider.lua
require 'apache2' function authz_check_foo(r, ip, user) if r.useragent_ip == ip then return apache2.AUTHZ_GRANTED elseif r.user == nil then return apache2.AUTHZ_DENIED_NO_USER elseif r.user == user then return apache2.AUTHZ_GRANTED else return apache2.AUTHZ_DENIED end end

The following configuration registers this function as provider foo and configures it for URL /:

LuaAuthzProvider foo authz_provider.lua authz_check_foo
<Location "/">
  Require foo 10.1.2.3 john_doe
</Location>
top

Writing Hooks

Hook functions are how modules (and Lua scripts) participate in the processing of requests. Each type of hook exposed by the server exists for a specific purpose, such as mapping requests to the file system, performing access control, or setting mime types:

Hook phase mod_lua directive Description
Quick handler LuaQuickHandler This is the first hook that will be called after a request has been mapped to a host or virtual host
Pre-Translate name LuaHookPreTranslateName This phase translates the requested URI into a filename on the system, before decoding occurs. Modules such as mod_proxy can operate in this phase.
Translate name LuaHookTranslateName This phase translates the requested URI into a filename on the system. Modules such as mod_alias and mod_rewrite operate in this phase.
Map to storage LuaHookMapToStorage This phase maps files to their physical, cached or external/proxied storage. It can be used by proxy or caching modules
Check Access LuaHookAccessChecker This phase checks whether a client has access to a resource. This phase is run before the user is authenticated, so beware.
Check User ID LuaHookCheckUserID This phase it used to check the negotiated user ID
Check Authorization LuaHookAuthChecker or LuaAuthzProvider This phase authorizes a user based on the negotiated credentials, such as user ID, client certificate etc.
Check Type LuaHookTypeChecker This phase checks the requested file and assigns a content type and a handler to it
Fixups LuaHookFixups This is the final "fix anything" phase before the content handlers are run. Any last-minute changes to the request should be made here.
Content handler fx. .lua files or through LuaMapHandler This is where the content is handled. Files are read, parsed, some are run, and the result is sent to the client
Logging LuaHookLog Once a request has been handled, it enters several logging phases, which logs the request in either the error or access log. Mod_lua is able to hook into the start of this and control logging output.

Hook functions are passed the request object as their only argument (except for LuaAuthzProvider, which also gets passed the arguments from the Require directive). They can return any value, depending on the hook, but most commonly they'll return OK, DONE, or DECLINED, which you can write in Lua as apache2.OK, apache2.DONE, or apache2.DECLINED, or else an HTTP status code.

translate_name.lua
-- example hook that rewrites the URI to a filesystem path. require 'apache2' function translate_name(r) if r.uri == "/translate-name" then r.filename = r.document_root .. "/find_me.txt" return apache2.OK end -- we don't care about this URL, give another module a chance return apache2.DECLINED end
translate_name2.lua
--[[ example hook that rewrites one URI to another URI. It returns a apache2.DECLINED to give other URL mappers a chance to work on the substitution, including the core translate_name hook which maps based on the DocumentRoot. Note: Use the early/late flags in the directive to make it run before or after mod_alias. --]] require 'apache2' function translate_name(r) if r.uri == "/translate-name" then r.uri = "/find_me.txt" return apache2.DECLINED end return apache2.DECLINED end
top

Data Structures

request_rec

The request_rec is mapped in as a userdata. It has a metatable which lets you do useful things with it. For the most part it has the same fields as the request_rec struct, many of which are writable as well as readable. (The table fields' content can be changed, but the fields themselves cannot be set to different tables.)

Name Lua type Writable Description
allowoverrides string no The AllowOverride options applied to the current request.
ap_auth_type string yes If an authentication check was made, this is set to the type of authentication (f.x. basic)
args string yes The query string arguments extracted from the request (f.x. foo=bar&name=johnsmith)
assbackwards boolean no Set to true if this is an HTTP/0.9 style request (e.g. GET /foo (with no headers) )
auth_name string no The realm name used for authorization (if applicable).
banner string no The server banner, f.x. Apache HTTP Server/2.4.3 openssl/0.9.8c
basic_auth_pw string no The basic auth password sent with this request, if any
canonical_filename string no The canonical filename of the request
content_encoding string no The content encoding of the current request
content_type string yes The content type of the current request, as determined in the type_check phase (f.x. image/gif or text/html)
context_prefix string no
context_document_root string no
document_root string no The document root of the host
err_headers_out table no MIME header environment for the response, printed even on errors and persist across internal redirects. A read-only lua table suitable for iteration is available as r:err_headers_out_table().
filename string yes The file name that the request maps to, f.x. /www/example.com/foo.txt. This can be changed in the pre-translate-name, translate-name or map-to-storage phases of a request to allow the default handler (or script handlers) to serve a different file than what was requested.
handler string yes The name of the handler that should serve this request, f.x. lua-script if it is to be served by mod_lua. This is typically set by the AddHandler or SetHandler directives, but could also be set via mod_lua to allow another handler to serve up a specific request that would otherwise not be served by it.
headers_in table yes MIME header environment from the request. This contains headers such as Host, User-Agent, Referer and so on. A read-only lua table suitable for iteration is available as r:headers_in_table().
headers_out table yes MIME header environment for the response. A read-only lua table suitable for iteration is available as r:headers_out_table().
hostname string no The host name, as set by the Host: header or by a full URI.
is_https boolean no Whether or not this request is done via HTTPS
is_initial_req boolean no Whether this request is the initial request or a sub-request
limit_req_body number no The size limit of the request body for this request, or 0 if no limit.
log_id string no The ID to identify request in access and error log.
method string no The request method, f.x. GET or POST.
notes table yes A list of notes that can be passed on from one module to another. A read-only lua table suitable for iteration is available as r:notes_table().
options string no The Options directive applied to the current request.
path_info string no The PATH_INFO extracted from this request.
port number no The server port used by the request.
protocol string no The protocol used, f.x. HTTP/1.1
proxyreq string yes Denotes whether this is a proxy request or not. This value is generally set in the post_read_request/pre_translate_name/translate_name phase of a request.
range string no The contents of the Range: header.
remaining number no The number of bytes remaining to be read from the request body.
server_built string no The time the server executable was built.
server_name string no The server name for this request.
some_auth_required boolean no Whether some authorization is/was required for this request.
subprocess_env table yes The environment variables set for this request. A read-only lua table suitable for iteration is available as r:subprocess_env_table().
started number no The time the server was (re)started, in seconds since the epoch (Jan 1st, 1970)
status number yes The (current) HTTP return code for this request, f.x. 200 or 404.
the_request string no The request string as sent by the client, f.x. GET /foo/bar HTTP/1.1.
unparsed_uri string no The unparsed URI of the request
uri string yes The URI after it has been parsed by httpd
user string yes If an authentication check has been made, this is set to the name of the authenticated user.
useragent_ip string no The IP of the user agent making the request
top

Built in functions

The request_rec object has (at least) the following methods:

r:flush()   -- flushes the output buffer.
            -- Returns true if the flush was successful, false otherwise.

while we_have_stuff_to_send do
    r:puts("Bla bla bla\n") -- print something to client
    r:flush() -- flush the buffer (send to client)
    r.usleep(500000) -- fake processing time for 0.5 sec. and repeat
end
r:add_output_filter(filter_name) -- add an output filter:

r:add_output_filter("fooFilter") -- add the fooFilter to the output stream
r:sendfile(filename) -- sends an entire file to the client, using sendfile if supported by the current platform:

if use_sendfile_thing then
    r:sendfile("/var/www/large_file.img")
end
r:parseargs() -- returns two tables; one standard key/value table for regular GET data, 
              -- and one for multi-value data (fx. foo=1&foo=2&foo=3):

local GET, GETMULTI = r:parseargs()
r:puts("Your name is: " .. GET['name'] or "Unknown")
r:parsebody([sizeLimit]) -- parse the request body as a POST and return two lua tables,
                         -- just like r:parseargs().
                         -- An optional number may be passed to specify the maximum number 
                         -- of bytes to parse. Default is 8192 bytes:
                 
local POST, POSTMULTI = r:parsebody(1024*1024)
r:puts("Your name is: " .. POST['name'] or "Unknown")
r:puts("hello", " world", "!") -- print to response body, self explanatory
r:write("a single string") -- print to response body, self explanatory
r:escape_html("<html>test</html>") -- Escapes HTML code and returns the escaped result
r:base64_encode(string) -- Encodes a string using the Base64 encoding standard:

local encoded = r:base64_encode("This is a test") -- returns VGhpcyBpcyBhIHRlc3Q=
r:base64_decode(string) -- Decodes a Base64-encoded string:

local decoded = r:base64_decode("VGhpcyBpcyBhIHRlc3Q=") -- returns 'This is a test'
r:md5(string) -- Calculates and returns the MD5 digest of a string (binary safe):

local hash = r:md5("This is a test") -- returns ce114e4501d2f4e2dcea3e17b546f339
r:sha1(string) -- Calculates and returns the SHA1 digest of a string (binary safe):

local hash = r:sha1("This is a test") -- returns a54d88e06612d820bc3be72877c74f257b561b19
r:escape(string) -- URL-Escapes a string:

local url = "http://foo.bar/1 2 3 & 4 + 5"
local escaped = r:escape(url) -- returns 'http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5'
r:unescape(string) -- Unescapes an URL-escaped string:

local url = "http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5"
local unescaped = r:unescape(url) -- returns 'http://foo.bar/1 2 3 & 4 + 5'
r:construct_url(string) -- Constructs an URL from an URI

local url = r:construct_url(r.uri)
r.mpm_query(number) -- Queries the server for MPM information using ap_mpm_query:

local mpm = r.mpm_query(14)
if mpm == 1 then
    r:puts("This server uses the Event MPM")
end
r:expr(string) -- Evaluates an expr string.

if r:expr("%{HTTP_HOST} =~ /^www/") then
    r:puts("This host name starts with www")
end
r:scoreboard_process(a) -- Queries the server for information about the process at position a:

local process = r:scoreboard_process(1)
r:puts("Server 1 has PID " .. process.pid)
r:scoreboard_worker(a, b) -- Queries for information about the worker thread, b, in process a:

local thread = r:scoreboard_worker(1, 1)
r:puts("Server 1's thread 1 has thread ID " .. thread.tid .. " and is in " .. thread.status .. " status")
r:clock() -- Returns the current time with microsecond precision
r:requestbody(filename) -- Reads and returns the request body of a request.
                -- If 'filename' is specified, it instead saves the
                -- contents to that file:
                
local input = r:requestbody()
r:puts("You sent the following request body to me:\n")
r:puts(input)
r:add_input_filter(filter_name) -- Adds 'filter_name' as an input filter
r.module_info(module_name) -- Queries the server for information about a module

local mod = r.module_info("mod_lua.c")
if mod then
    for k, v in pairs(mod.commands) do
       r:puts( ("%s: %s\n"):format(k,v)) -- print out all directives accepted by this module
    end
end
r:loaded_modules() -- Returns a list of modules loaded by httpd:

for k, module in pairs(r:loaded_modules()) do
    r:puts("I have loaded module " .. module .. "\n")
end
r:runtime_dir_relative(filename) -- Compute the name of a run-time file (e.g., shared memory "file") 
                         -- relative to the appropriate run-time directory.
r:server_info() -- Returns a table containing server information, such as 
                -- the name of the httpd executable file, mpm used etc.
r:set_document_root(file_path) -- Sets the document root for the request to file_path
r:set_context_info(prefix, docroot) -- Sets the context prefix and context document root for a request
r:os_escape_path(file_path) -- Converts an OS path to a URL in an OS dependent way
r:escape_logitem(string) -- Escapes a string for logging
r.strcmp_match(string, pattern) -- Checks if 'string' matches 'pattern' using strcmp_match (globs).
                        -- fx. whether 'www.example.com' matches '*.example.com':
                        
local match = r.strcmp_match("foobar.com", "foo*.com")
if match then 
    r:puts("foobar.com matches foo*.com")
end
r:set_keepalive() -- Sets the keepalive status for a request. Returns true if possible, false otherwise.
r:make_etag() -- Constructs and returns the etag for the current request.
r:send_interim_response(clear) -- Sends an interim (1xx) response to the client.
                       -- if 'clear' is true, available headers will be sent and cleared.
r:custom_response(status_code, string) -- Construct and set a custom response for a given status code.
                               -- This works much like the ErrorDocument directive:
                               
r:custom_response(404, "Baleted!")
r.exists_config_define(string) -- Checks whether a configuration definition exists or not:

if r.exists_config_define("FOO") then
    r:puts("httpd was probably run with -DFOO, or it was defined in the configuration")
end
r:state_query(string) -- Queries the server for state information
r:stat(filename [,wanted]) -- Runs stat() on a file, and returns a table with file information:

local info = r:stat("/var/www/foo.txt")
if info then
    r:puts("This file exists and was last modified at: " .. info.modified)
end
r:regex(string, pattern [,flags]) -- Runs a regular expression match on a string, returning captures if matched:

local matches = r:regex("foo bar baz", [[foo (\w+) (\S*)]])
if matches then
    r:puts("The regex matched, and the last word captured ($2) was: " .. matches[2])
end

-- Example ignoring case sensitivity:
local matches = r:regex("FOO bar BAz", [[(foo) bar]], 1)

-- Flags can be a bitwise combination of:
-- 0x01: Ignore case
-- 0x02: Multiline search
r.usleep(number_of_microseconds) -- Puts the script to sleep for a given number of microseconds.
r:dbacquire(dbType[, dbParams]) -- Acquires a connection to a database and returns a database class.
                        -- See 'Database connectivity' for details.
r:ivm_set("key", value) -- Set an Inter-VM variable to hold a specific value.
                        -- These values persist even though the VM is gone or not being used,
                        -- and so should only be used if MaxConnectionsPerChild is > 0
                        -- Values can be numbers, strings and booleans, and are stored on a 
                        -- per process basis (so they won't do much good with a prefork mpm)
                        
r:ivm_get("key")        -- Fetches a variable set by ivm_set. Returns the contents of the variable
                        -- if it exists or nil if no such variable exists.
                        
-- An example getter/setter that saves a global variable outside the VM:
function handle(r)
    -- First VM to call this will get no value, and will have to create it
    local foo = r:ivm_get("cached_data")
    if not foo then
        foo = do_some_calcs() -- fake some return value
        r:ivm_set("cached_data", foo) -- set it globally
    end
    r:puts("Cached data is: ", foo)
end
r:htpassword(string [,algorithm [,cost]]) -- Creates a password hash from a string.
                                          -- algorithm: 0 = APMD5 (default), 1 = SHA, 2 = BCRYPT, 3 = CRYPT.
                                          -- cost: only valid with BCRYPT algorithm (default = 5).
r:mkdir(dir [,mode]) -- Creates a directory and sets mode to optional mode parameter.
r:mkrdir(dir [,mode]) -- Creates directories recursive and sets mode to optional mode parameter.
r:rmdir(dir) -- Removes a directory.
r:touch(file [,mtime]) -- Sets the file modification time to current time or to optional mtime msec value.
r:get_direntries(dir) -- Returns a table with all directory entries.

function handle(r)
  local dir = r.context_document_root
  for _, f in ipairs(r:get_direntries(dir)) do
    local info = r:stat(dir .. "/" .. f)
    if info then
      local mtime = os.date(fmt, info.mtime / 1000000)
      local ftype = (info.filetype == 2) and "[dir] " or "[file]"
      r:puts( ("%s %s %10i %s\n"):format(ftype, mtime, info.size, f) )
    end
  end
end
r.date_parse_rfc(string) -- Parses a date/time string and returns seconds since epoche.
r:getcookie(key) -- Gets a HTTP cookie
r:setcookie{
  key = [key],
  value = [value],
  expires = [expiry],
  secure = [boolean],
  httponly = [boolean],
  path = [path],
  domain = [domain]
} -- Sets a HTTP cookie, for instance:

r:setcookie{
  key = "cookie1",
  value = "HDHfa9eyffh396rt",
  expires = os.time() + 86400,
  secure = true
}
r:wsupgrade() -- Upgrades a connection to WebSockets if possible (and requested):
if r:wsupgrade() then -- if we can upgrade:
    r:wswrite("Welcome to websockets!") -- write something to the client
    r:wsclose()  -- goodbye!
end
r:wsread() -- Reads a WebSocket frame from a WebSocket upgraded connection (see above):

local line, isFinal = r:wsread() -- isFinal denotes whether this is the final frame.
                                 -- If it isn't, then more frames can be read
r:wswrite("You wrote: " .. line)
r:wswrite(line) -- Writes a frame to a WebSocket client:
r:wswrite("Hello, world!")
r:wsclose() -- Closes a WebSocket request and terminates it for httpd:

if r:wsupgrade() then
    r:wswrite("Write something: ")
    local line = r:wsread() or "nothing"
    r:wswrite("You wrote: " .. line);
    r:wswrite("Goodbye!")
    r:wsclose()
end
top

Logging Functions

-- examples of logging messages
r:trace1("This is a trace log message") -- trace1 through trace8 can be used
r:debug("This is a debug log message")
r:info("This is an info log message")
r:notice("This is a notice log message")
r:warn("This is a warn log message")
r:err("This is an err log message")
r:alert("This is an alert log message")
r:crit("This is a crit log message")
r:emerg("This is an emerg log message")
top

apache2 Package

A package named apache2 is available with (at least) the following contents.

apache2.OK
internal constant OK. Handlers should return this if they've handled the request.
apache2.DECLINED
internal constant DECLINED. Handlers should return this if they are not going to handle the request.
apache2.DONE
internal constant DONE.
apache2.version
Apache HTTP server version string
apache2.HTTP_MOVED_TEMPORARILY
HTTP status code
apache2.PROXYREQ_NONE, apache2.PROXYREQ_PROXY, apache2.PROXYREQ_REVERSE, apache2.PROXYREQ_RESPONSE
internal constants used by mod_proxy
apache2.AUTHZ_DENIED, apache2.AUTHZ_GRANTED, apache2.AUTHZ_NEUTRAL, apache2.AUTHZ_GENERAL_ERROR, apache2.AUTHZ_DENIED_NO_USER
internal constants used by mod_authz_core

(Other HTTP status codes are not yet implemented.)

top

Modifying contents with Lua filters

Filter functions implemented via LuaInputFilter or LuaOutputFilter are designed as three-stage non-blocking functions using coroutines to suspend and resume a function as buckets are sent down the filter chain. The core structure of such a function is:

function filter(r)
    -- Our first yield is to signal that we are ready to receive buckets.
    -- Before this yield, we can set up our environment, check for conditions,
    -- and, if we deem it necessary, decline filtering a request altogether:
    if something_bad then
        return -- This would skip this filter.
    end
    -- Regardless of whether we have data to prepend, a yield MUST be called here.
    -- Note that only output filters can prepend data. Input filters must use the 
    -- final stage to append data to the content.
    coroutine.yield([optional header to be prepended to the content])
    
    -- After we have yielded, buckets will be sent to us, one by one, and we can 
    -- do whatever we want with them and then pass on the result.
    -- Buckets are stored in the global variable 'bucket', so we create a loop
    -- that checks if 'bucket' is not nil:
    while bucket ~= nil do
        local output = mangle(bucket) -- Do some stuff to the content
        coroutine.yield(output) -- Return our new content to the filter chain
    end

    -- Once the buckets are gone, 'bucket' is set to nil, which will exit the 
    -- loop and land us here. Anything extra we want to append to the content
    -- can be done by doing a final yield here. Both input and output filters 
    -- can append data to the content in this phase.
    coroutine.yield([optional footer to be appended to the content])
end
top

Database connectivity

Mod_lua implements a simple database feature for querying and running commands on the most popular database engines (mySQL, PostgreSQL, FreeTDS, ODBC, SQLite, Oracle) as well as mod_dbd.

The dbType to use as the first parameter of dbacquire is case sensitive.

It should be one of mysql, pgsql, freetds, odbc, sqlite2, sqlite3, oracle or mod_dbd.

The example below shows how to acquire a database handle and return information from a table:

function handle(r)
    -- Acquire a database handle
    local database, err = r:dbacquire("mysql", "server=localhost,user=someuser,pass=somepass,dbname=mydb")
    if not err then
        -- Select some information from it
        local results, err = database:select(r, "SELECT `name`, `age` FROM `people` WHERE 1")
        if not err then
            local rows = results(0) -- fetch all rows synchronously
            for k, row in pairs(rows) do
                r:puts( string.format("Name: %s, Age: %s<br/>", row[1], row[2]) )
            end
        else
            r:puts("Database query error: " .. err)
        end
        database:close()
    else
        r:puts("Could not connect to the database: " .. err)
    end
end

To utilize mod_dbd, specify mod_dbd as the database type, or leave the field blank:

local database = r:dbacquire("mod_dbd")

Database object and contained functions

The database object returned by dbacquire has the following methods:

Normal select and query from a database:

-- Run a statement and return the number of rows affected:
local affected, errmsg = database:query(r, "DELETE FROM `tbl` WHERE 1")

-- Run a statement and return a result set that can be used synchronously or async:
local result, errmsg = database:select(r, "SELECT * FROM `people` WHERE 1")

Using prepared statements (recommended):

-- Create and run a prepared statement:
local statement, errmsg = database:prepare(r, "DELETE FROM `tbl` WHERE `age` > %u")
if not errmsg then
    local result, errmsg = statement:query(20) -- run the statement with age > 20
end

-- Fetch a prepared statement from a DBDPrepareSQL directive:
local statement, errmsg = database:prepared(r, "someTag")
if not errmsg then
    local result, errmsg = statement:select("John Doe", 123) -- inject the values "John Doe" and 123 into the statement
end

Escaping values, closing databases etc:

-- Escape a value for use in a statement:
local escaped = database:escape(r, [["'|blabla]])

-- Close a database connection and free up handles:
database:close()

-- Check whether a database connection is up and running:
local connected = database:active()

Working with result sets

The result set returned by db:select or by the prepared statement functions created through db:prepare can be used to fetch rows synchronously or asynchronously, depending on the row number specified:
result(0) fetches all rows in a synchronous manner, returning a table of rows.
result(-1) fetches the next available row in the set, asynchronously.
result(N) fetches row number N, asynchronously:

-- fetch a result set using a regular query:
local result, err = db:select(r, "SELECT * FROM `tbl` WHERE 1")

local rows = result(0) -- Fetch ALL rows synchronously
local row = result(-1) -- Fetch the next available row, asynchronously
local row = result(1234) -- Fetch row number 1234, asynchronously
local row = result(-1, true) -- Fetch the next available row, using row names as key indexes.

One can construct a function that returns an iterative function to iterate over all rows in a synchronous or asynchronous way, depending on the async argument:

function rows(resultset, async)
    local a = 0
    local function getnext()
        a = a + 1
        local row = resultset(-1)
        return row and a or nil, row
    end
    if not async then
        return pairs(resultset(0))
    else
        return getnext, self
    end
end

local statement, err = db:prepare(r, "SELECT * FROM `tbl` WHERE `age` > %u")
if not err then
     -- fetch rows asynchronously:
    local result, err = statement:select(20)
    if not err then
        for index, row in rows(result, true) do
            ....
        end
    end

     -- fetch rows synchronously:
    local result, err = statement:select(20)
    if not err then
        for index, row in rows(result, false) do
            ....
        end
    end
end

Closing a database connection

Database handles should be closed using database:close() when they are no longer needed. If you do not close them manually, they will eventually be garbage collected and closed by mod_lua, but you may end up having too many unused connections to the database if you leave the closing up to mod_lua. Essentially, the following two measures are the same:

-- Method 1: Manually close a handle
local database = r:dbacquire("mod_dbd")
database:close() -- All done

-- Method 2: Letting the garbage collector close it
local database = r:dbacquire("mod_dbd")
database = nil -- throw away the reference
collectgarbage() -- close the handle via GC

Precautions when working with databases

Although the standard query and run functions are freely available, it is recommended that you use prepared statements whenever possible, to both optimize performance (if your db handle lives on for a long time) and to minimize the risk of SQL injection attacks. run and query should only be used when there are no variables inserted into a statement (a static statement). When using dynamic statements, use db:prepare or db:prepared.

top

LuaAuthzProvider Directive

Description:Plug an authorization provider function into mod_authz_core
Syntax:LuaAuthzProvider provider_name /path/to/lua/script.lua function_name
Context:server config
Status:Extension
Module:mod_lua
Compatibility:2.4.3 and later

After a lua function has been registered as authorization provider, it can be used with the Require directive:

LuaRoot "/usr/local/apache2/lua"
LuaAuthzProvider foo authz.lua authz_check_foo
<Location "/">
  Require foo johndoe
</Location>
require "apache2"
function authz_check_foo(r, who)
    if r.user ~= who then return apache2.AUTHZ_DENIED
    return apache2.AUTHZ_GRANTED
end
top

LuaCodeCache Directive

Description:Configure the compiled code cache.
Syntax:LuaCodeCache stat|forever|never
Default:LuaCodeCache stat
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Specify the behavior of the in-memory code cache. The default is stat, which stats the top level script (not any included ones) each time that file is needed, and reloads it if the modified time indicates it is newer than the one it has already loaded. The other values cause it to keep the file cached forever (don't stat and replace) or to never cache the file.

In general stat or forever is good for production, and stat or never for development.

Examples:

LuaCodeCache stat
LuaCodeCache forever
LuaCodeCache never
top

LuaHookAccessChecker Directive

Description:Provide a hook for the access_checker phase of request processing
Syntax:LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua
Compatibility:The optional third argument is supported in 2.3.15 and later

Add your hook to the access_checker phase. An access checker hook function usually returns OK, DECLINED, or HTTP_FORBIDDEN.

Ordering

The optional arguments "early" or "late" control when this script runs relative to other modules.

top

LuaHookAuthChecker Directive

Description:Provide a hook for the auth_checker phase of request processing
Syntax:LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua
Compatibility:The optional third argument is supported in 2.3.15 and later

Invoke a lua function in the auth_checker phase of processing a request. This can be used to implement arbitrary authentication and authorization checking. A very simple example:

require 'apache2'

-- fake authcheck hook
-- If request has no auth info, set the response header and
-- return a 401 to ask the browser for basic auth info.
-- If request has auth info, don't actually look at it, just
-- pretend we got userid 'foo' and validated it.
-- Then check if the userid is 'foo' and accept the request.
function authcheck_hook(r)

   -- look for auth info
   auth = r.headers_in['Authorization']
   if auth ~= nil then
     -- fake the user
     r.user = 'foo'
   end

   if r.user == nil then
      r:debug("authcheck: user is nil, returning 401")
      r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
      return 401
   elseif r.user == "foo" then
      r:debug('user foo: OK')
   else
      r:debug("authcheck: user='" .. r.user .. "'")
      r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
      return 401
   end
   return apache2.OK
end

Ordering

The optional arguments "early" or "late" control when this script runs relative to other modules.

top

LuaHookCheckUserID Directive

Description:Provide a hook for the check_user_id phase of request processing
Syntax:LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua
Compatibility:The optional third argument is supported in 2.3.15 and later

...

Ordering

The optional arguments "early" or "late" control when this script runs relative to other modules.

top

LuaHookFixups Directive

Description:Provide a hook for the fixups phase of a request processing
Syntax:LuaHookFixups /path/to/lua/script.lua hook_function_name
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Just like LuaHookTranslateName, but executed at the fixups phase

top

LuaHookInsertFilter Directive

Description:Provide a hook for the insert_filter phase of request processing
Syntax:LuaHookInsertFilter /path/to/lua/script.lua hook_function_name
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Not Yet Implemented

top

LuaHookLog Directive

Description:Provide a hook for the access log phase of a request processing
Syntax:LuaHookLog /path/to/lua/script.lua log_function_name
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

This simple logging hook allows you to run a function when httpd enters the logging phase of a request. With it, you can append data to your own logs, manipulate data before the regular log is written, or prevent a log entry from being created. To prevent the usual logging from happening, simply return apache2.DONE in your logging handler, otherwise return apache2.OK to tell httpd to log as normal.

Example:

LuaHookLog "/path/to/script.lua" logger
-- /path/to/script.lua --
function logger(r)
    -- flip a coin:
    -- If 1, then we write to our own Lua log and tell httpd not to log
    -- in the main log.
    -- If 2, then we just sanitize the output a bit and tell httpd to 
    -- log the sanitized bits.

    if math.random(1,2) == 1 then
        -- Log stuff ourselves and don't log in the regular log
        local f = io.open("/foo/secret.log", "a")
        if f then
            f:write("Something secret happened at " .. r.uri .. "\n")
            f:close()
        end
        return apache2.DONE -- Tell httpd not to use the regular logging functions
    else
        r.uri = r.uri:gsub("somesecretstuff", "") -- sanitize the URI
        return apache2.OK -- tell httpd to log it.
    end
end
top

LuaHookMapToStorage Directive

Description:Provide a hook for the map_to_storage phase of request processing
Syntax:LuaHookMapToStorage /path/to/lua/script.lua hook_function_name
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Like LuaHookTranslateName but executed at the map-to-storage phase of a request. Modules like mod_cache run at this phase, which makes for an interesting example on what to do here:

LuaHookMapToStorage "/path/to/lua/script.lua" check_cache
require"apache2"
cached_files = {}

function read_file(filename) 
    local input = io.open(filename, "r")
    if input then
        local data = input:read("*a")
        cached_files[filename] = data
        file = cached_files[filename]
        input:close()
    end
    return cached_files[filename]
end

function check_cache(r)
    if r.filename:match("%.png$") then -- Only match PNG files
        local file = cached_files[r.filename] -- Check cache entries
        if not file then
            file = read_file(r.filename)  -- Read file into cache
        end
        if file then -- If file exists, write it out
            r.status = 200
            r:write(file)
            r:info(("Sent %s to client from cache"):format(r.filename))
            return apache2.DONE -- skip default handler for PNG files
        end
    end
    return apache2.DECLINED -- If we had nothing to do, let others serve this.
end
top

LuaHookPreTranslate Directive

Description:Provide a hook for the pre_translate phase of a request processing
Syntax:LuaHookPreTranslate /path/to/lua/script.lua hook_function_name
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Just like LuaHookTranslateName, but executed at the pre_translate phase, where the URI-path is not percent decoded.

top

LuaHookTranslateName Directive

Description:Provide a hook for the translate name phase of request processing
Syntax:LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]
Context:server config, virtual host
Override:All
Status:Extension
Module:mod_lua
Compatibility:The optional third argument is supported in 2.3.15 and later

Add a hook (at APR_HOOK_MIDDLE) to the translate name phase of request processing. The hook function receives a single argument, the request_rec, and should return a status code, which is either an HTTP error code, or the constants defined in the apache2 module: apache2.OK, apache2.DECLINED, or apache2.DONE.

For those new to hooks, basically each hook will be invoked until one of them returns apache2.OK. If your hook doesn't want to do the translation it should just return apache2.DECLINED. If the request should stop processing, then return apache2.DONE.

Example:

# httpd.conf
LuaHookTranslateName "/scripts/conf/hooks.lua" silly_mapper
-- /scripts/conf/hooks.lua --
require "apache2"
function silly_mapper(r)
    if r.uri == "/" then
        r.filename = "/var/www/home.lua"
        return apache2.OK
    else
        return apache2.DECLINED
    end
end

Context

This directive is not valid in <Directory>, <Files>, or htaccess context.

Ordering

The optional arguments "early" or "late" control when this script runs relative to other modules.

top

LuaHookTypeChecker Directive

Description:Provide a hook for the type_checker phase of request processing
Syntax:LuaHookTypeChecker /path/to/lua/script.lua hook_function_name
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

This directive provides a hook for the type_checker phase of the request processing. This phase is where requests are assigned a content type and a handler, and thus can be used to modify the type and handler based on input:

LuaHookTypeChecker "/path/to/lua/script.lua" type_checker
    function type_checker(r)
        if r.uri:match("%.to_gif$") then -- match foo.png.to_gif
            r.content_type = "image/gif" -- assign it the image/gif type
            r.handler = "gifWizard"      -- tell the gifWizard module to handle this
            r.filename = r.uri:gsub("%.to_gif$", "") -- fix the filename requested
            return apache2.OK
        end

        return apache2.DECLINED
    end
top

LuaInherit Directive

Description:Controls how parent configuration sections are merged into children
Syntax:LuaInherit none|parent-first|parent-last
Default:LuaInherit parent-first
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua
Compatibility:2.4.0 and later

By default, if LuaHook* directives are used in overlapping Directory or Location configuration sections, the scripts defined in the more specific section are run after those defined in the more generic section (LuaInherit parent-first). You can reverse this order, or make the parent context not apply at all.

In previous 2.3.x releases, the default was effectively to ignore LuaHook* directives from parent configuration sections.

top

LuaInputFilter Directive

Description:Provide a Lua function for content input filtering
Syntax:LuaInputFilter filter_name /path/to/lua/script.lua function_name
Context:server config
Status:Extension
Module:mod_lua
Compatibility:2.4.5 and later

Provides a means of adding a Lua function as an input filter. As with output filters, input filters work as coroutines, first yielding before buffers are sent, then yielding whenever a bucket needs to be passed down the chain, and finally (optionally) yielding anything that needs to be appended to the input data. The global variable bucket holds the buckets as they are passed onto the Lua script:

LuaInputFilter myInputFilter "/www/filter.lua" input_filter
<Files "*.lua">
  SetInputFilter myInputFilter
</Files>
--[[
    Example input filter that converts all POST data to uppercase.
]]--
function input_filter(r)
    print("luaInputFilter called") -- debug print
    coroutine.yield() -- Yield and wait for buckets
    while bucket do -- For each bucket, do...
        local output = string.upper(bucket) -- Convert all POST data to uppercase
        coroutine.yield(output) -- Send converted data down the chain
    end
    -- No more buckets available.
    coroutine.yield("&filterSignature=1234") -- Append signature at the end
end

The input filter supports denying/skipping a filter if it is deemed unwanted:

function input_filter(r)
    if not good then
        return -- Simply deny filtering, passing on the original content instead
    end
    coroutine.yield() -- wait for buckets
    ... -- insert filter stuff here
end

See "Modifying contents with Lua filters" for more information.

top

LuaMapHandler Directive

Description:Map a path to a lua handler
Syntax:LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

This directive matches a uri pattern to invoke a specific handler function in a specific file. It uses PCRE regular expressions to match the uri, and supports interpolating match groups into both the file path and the function name. Be careful writing your regular expressions to avoid security issues.

Examples:

LuaMapHandler "/(\w+)/(\w+)" "/scripts/$1.lua" "handle_$2"

This would match uri's such as /photos/show?id=9 to the file /scripts/photos.lua and invoke the handler function handle_show on the lua vm after loading that file.

LuaMapHandler "/bingo" "/scripts/wombat.lua"

This would invoke the "handle" function, which is the default if no specific function name is provided.

top

LuaOutputFilter Directive

Description:Provide a Lua function for content output filtering
Syntax:LuaOutputFilter filter_name /path/to/lua/script.lua function_name
Context:server config
Status:Extension
Module:mod_lua
Compatibility:2.4.5 and later

Provides a means of adding a Lua function as an output filter. As with input filters, output filters work as coroutines, first yielding before buffers are sent, then yielding whenever a bucket needs to be passed down the chain, and finally (optionally) yielding anything that needs to be appended to the input data. The global variable bucket holds the buckets as they are passed onto the Lua script:

LuaOutputFilter myOutputFilter "/www/filter.lua" output_filter
<Files "*.lua">
  SetOutputFilter myOutputFilter
</Files>
--[[
    Example output filter that escapes all HTML entities in the output
]]--
function output_filter(r)
    coroutine.yield("(Handled by myOutputFilter)<br/>\n") -- Prepend some data to the output,
                                                          -- yield and wait for buckets.
    while bucket do -- For each bucket, do...
        local output = r:escape_html(bucket) -- Escape all output
        coroutine.yield(output) -- Send converted data down the chain
    end
    -- No more buckets available.
end

As with the input filter, the output filter supports denying/skipping a filter if it is deemed unwanted:

function output_filter(r)
    if not r.content_type:match("text/html") then
        return -- Simply deny filtering, passing on the original content instead
    end
    coroutine.yield() -- wait for buckets
    ... -- insert filter stuff here
end

Lua filters with mod_filter

When a Lua filter is used as the underlying provider via the FilterProvider directive, filtering will only work when the filter-name is identical to the provider-name.

See "Modifying contents with Lua filters" for more information.

top

LuaPackageCPath Directive

Description:Add a directory to lua's package.cpath
Syntax:LuaPackageCPath /path/to/include/?.soa
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Add a path to lua's shared library search path. Follows the same conventions as lua. This just munges the package.cpath in the lua vms.

top

LuaPackagePath Directive

Description:Add a directory to lua's package.path
Syntax:LuaPackagePath /path/to/include/?.lua
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Add a path to lua's module search path. Follows the same conventions as lua. This just munges the package.path in the lua vms.

Examples:

LuaPackagePath "/scripts/lib/?.lua"
LuaPackagePath "/scripts/lib/?/init.lua"
top

LuaQuickHandler Directive

Description:Provide a hook for the quick handler of request processing
Syntax:LuaQuickHandler /path/to/script.lua hook_function_name
Context:server config, virtual host
Override:All
Status:Extension
Module:mod_lua

This phase is run immediately after the request has been mapped to a virtual host, and can be used to either do some request processing before the other phases kick in, or to serve a request without the need to translate, map to storage et cetera. As this phase is run before anything else, directives such as <Location> or <Directory> are void in this phase, just as URIs have not been properly parsed yet.

Context

This directive is not valid in <Directory>, <Files>, or htaccess context.

top

LuaRoot Directive

Description:Specify the base path for resolving relative paths for mod_lua directives
Syntax:LuaRoot /path/to/a/directory
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Specify the base path which will be used to evaluate all relative paths within mod_lua. If not specified they will be resolved relative to the current working directory, which may not always work well for a server.

top

LuaScope Directive

Description:One of once, request, conn, thread -- default is once
Syntax:LuaScope once|request|conn|thread|server [min] [max]
Default:LuaScope once
Context:server config, virtual host, directory, .htaccess
Override:All
Status:Extension
Module:mod_lua

Specify the life cycle scope of the Lua interpreter which will be used by handlers in this "Directory." The default is "once"

once:
use the interpreter once and throw it away.
request:
use the interpreter to handle anything based on the same file within this request, which is also request scoped.
conn:
Same as request but attached to the connection_rec
thread:
Use the interpreter for the lifetime of the thread handling the request (only available with threaded MPMs).
server:
This one is different than others because the server scope is quite long lived, and multiple threads will have the same server_rec. To accommodate this, server scoped Lua states are stored in an apr resource list. The min and max arguments specify the minimum and maximum number of Lua states to keep in the pool.

Generally speaking, the thread and server scopes execute roughly 2-3 times faster than the rest, because they don't have to spawn new Lua states on every request (especially with the event MPM, as even keepalive requests will use a new thread for each request). If you are satisfied that your scripts will not have problems reusing a state, then the thread or server scopes should be used for maximum performance. While the thread scope will provide the fastest responses, the server scope will use less memory, as states are pooled, allowing f.x. 1000 threads to share only 100 Lua states, thus using only 10% of the memory required by the thread scope.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_mime_magic.html.en0000664000175100017510000004126214737542416022045 0ustar covenercovener mod_mime_magic - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_mime_magic

Available Languages:  en  |  fr 

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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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
1 byte number to begin checking from
">" indicates a dependency upon the previous non-">" line
2

type of data to match

byte single character
short machine-order 16-bit integer
long machine-order 32-bit integer
string arbitrary-length string
date long integer date (seconds since Unix epoch/1970)
beshort big-endian 16-bit integer
belong big-endian 32-bit integer
bedate big-endian 32-bit integer date
leshort little-endian 16-bit integer
lelong little-endian 32-bit integer
ledate little-endian 32-bit integer date
3 contents of data to match
4 MIME type if matched
5 MIME 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. 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 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  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_privileges.html.en0000664000175100017510000007256014737542416022134 0ustar covenercovener mod_privileges - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_privileges

Available Languages:  en  |  fr 

Description:Support for Solaris privileges and for running virtual hosts under different user IDs.
Status:Experimental
Module Identifier:privileges_module
Source File:mod_privileges.c
Compatibility:Available in Apache 2.3 and up, on Solaris 10 and OpenSolaris platforms

Summary

This module enables different Virtual Hosts to run with different Unix User and Group IDs, and with different Solaris Privileges. In particular, it offers a solution to the problem of privilege separation between different Virtual Hosts, first promised by the abandoned perchild MPM. It also offers other security enhancements.

Unlike perchild, mod_privileges is not itself an MPM. It works within a processing model to set privileges and User/Group per request in a running process. It is therefore not compatible with a threaded MPM, and will refuse to run under one.

mod_privileges raises security issues similar to those of suexec. But unlike suexec, it applies not only to CGI programs but to the entire request processing cycle, including in-process applications and subprocesses. It is ideally suited to running PHP applications under mod_php, which is also incompatible with threaded MPMs. It is also well-suited to other in-process scripting applications such as mod_perl, mod_python, and mod_ruby, and to applications implemented in C as apache modules where privilege separation is an issue.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Security Considerations

mod_privileges introduces new security concerns in situations where untrusted code may be run within the webserver process. This applies to untrusted modules, and scripts running under modules such as mod_php or mod_perl. Scripts running externally (e.g. as CGI or in an appserver behind mod_proxy or mod_jk) are NOT affected.

The basic security concerns with mod_privileges are:

The PrivilegesMode directive allows you to select either FAST or SECURE mode. You can mix modes, using FAST mode for trusted users and fully-audited code paths, while imposing SECURE mode where an untrusted user has scope to introduce code.

Before describing the modes, we should also introduce the target use cases: Benign vs Hostile. In a benign situation, you want to separate users for their convenience, and protect them and the server against the risks posed by honest mistakes, but you trust your users are not deliberately subverting system security. In a hostile situation - e.g. commercial hosting - you may have users deliberately attacking the system or each other.

FAST mode
In FAST mode, requests are run in-process with the selected uid/gid and privileges, so the overhead is negligible. This is suitable for benign situations, but is not secure against an attacker escalating privileges with an in-process module or script.
SECURE mode
A request in SECURE mode forks a subprocess, which then drops privileges. This is a very similar case to running CGI with suexec, but for the entire request cycle, and with the benefit of fine-grained control of privileges.

You can select different PrivilegesModes for each virtual host, and even in a directory context within a virtual host. FAST mode is appropriate where the user(s) are trusted and/or have no privilege to load in-process code. SECURE mode is appropriate to cases where untrusted code might be run in-process. However, even in SECURE mode, there is no protection against a malicious user who is able to introduce privileges-aware code running before the start of the request-processing cycle.

top

DTracePrivileges Directive

Description:Determines whether the privileges required by dtrace are enabled.
Syntax:DTracePrivileges On|Off
Default:DTracePrivileges Off
Context:server config
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM).

This server-wide directive determines whether Apache will run with the privileges required to run dtrace. Note that DTracePrivileges On will not in itself activate DTrace, but DTracePrivileges Off will prevent it working.

top

PrivilegesMode Directive

Description:Trade off processing speed and efficiency vs security against malicious privileges-aware code.
Syntax:PrivilegesMode FAST|SECURE|SELECTIVE
Default:PrivilegesMode FAST
Context:server config, virtual host, directory
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM).

This directive trades off performance vs security against malicious, privileges-aware code. In SECURE mode, each request runs in a secure subprocess, incurring a substantial performance penalty. In FAST mode, the server is not protected against escalation of privileges as discussed above.

This directive differs slightly between a <Directory> context (including equivalents such as Location/Files/If) and a top-level or <VirtualHost>.

At top-level, it sets a default that will be inherited by virtualhosts. In a virtual host, FAST or SECURE mode acts on the entire HTTP request, and any settings in a <Directory> context will be ignored. A third pseudo-mode SELECTIVE defers the choice of FAST vs SECURE to directives in a <Directory> context.

In a <Directory> context, it is applicable only where SELECTIVE mode was set for the VirtualHost. Only FAST or SECURE can be set in this context (SELECTIVE would be meaningless).

Warning

Where SELECTIVE mode is selected for a virtual host, the activation of privileges must be deferred until after the mapping phase of request processing has determined what <Directory> context applies to the request. This might give an attacker opportunities to introduce code through a RewriteMap running at top-level or <VirtualHost> context before privileges have been dropped and userid/gid set.
top

VHostCGIMode Directive

Description:Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.
Syntax:VHostCGIMode On|Off|Secure
Default:VHostCGIMode On
Context:virtual host
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM).

Determines whether the virtual host is allowed to run fork and exec, the privileges required to run subprocesses. If this is set to Off the virtualhost is denied the privileges and will not be able to run traditional CGI programs or scripts under the traditional mod_cgi, nor similar external programs such as those created by mod_ext_filter or RewriteMap prog. Note that it does not prevent CGI programs running under alternative process and security models such as mod_fcgid, which is a recommended solution in Solaris.

If set to On or Secure, the virtual host is permitted to run external programs and scripts as above. Setting VHostCGIMode Secure has the effect of denying privileges to the subprocesses, as described for VHostSecure.

top

VHostCGIPrivs Directive

Description:Assign arbitrary privileges to subprocesses created by a virtual host.
Syntax:VHostCGIPrivs [+-]?privilege-name [[+-]?privilege-name] ...
Default:None
Context:virtual host
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM) and when mod_privileges is compiled with the BIG_SECURITY_HOLE compile-time option.

VHostCGIPrivs can be used to assign arbitrary privileges to subprocesses created by a virtual host, as discussed under VHostCGIMode. Each privilege-name is the name of a Solaris privilege, such as file_setid or sys_nfs.

A privilege-name may optionally be prefixed by + or -, which will respectively allow or deny a privilege. If used with neither + nor -, all privileges otherwise assigned to the virtualhost will be denied. You can use this to override any of the default sets and construct your own privilege set.

Security

This directive can open huge security holes in apache subprocesses, up to and including running them with root-level powers. Do not use it unless you fully understand what you are doing!

top

VHostGroup Directive

Description:Sets the Group ID under which a virtual host runs.
Syntax:VHostGroup unix-groupid
Default:Inherits the group id specified in Group
Context:virtual host
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM).

The VHostGroup directive sets the Unix group under which the server will process requests to a virtualhost. The group is set before the request is processed and reset afterwards using Solaris Privileges. Since the setting applies to the process, this is not compatible with threaded MPMs.

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.

Security

This directive cannot be used to run apache as root! Nevertheless, it opens potential security issues similar to those discussed in the suexec documentation.

See also

top

VHostPrivs Directive

Description:Assign arbitrary privileges to a virtual host.
Syntax:VHostPrivs [+-]?privilege-name [[+-]?privilege-name] ...
Default:None
Context:virtual host
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM) and when mod_privileges is compiled with the BIG_SECURITY_HOLE compile-time option.

VHostPrivs can be used to assign arbitrary privileges to a virtual host. Each privilege-name is the name of a Solaris privilege, such as file_setid or sys_nfs.

A privilege-name may optionally be prefixed by + or -, which will respectively allow or deny a privilege. If used with neither + nor -, all privileges otherwise assigned to the virtualhost will be denied. You can use this to override any of the default sets and construct your own privilege set.

Security

This directive can open huge security holes in apache, up to and including running requests with root-level powers. Do not use it unless you fully understand what you are doing!

top

VHostSecure Directive

Description:Determines whether the server runs with enhanced security for the virtualhost.
Syntax:VHostSecure On|Off
Default:VHostSecure On
Context:virtual host
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM).

Determines whether the virtual host processes requests with security enhanced by removal of Privileges that are rarely needed in a webserver, but which are available by default to a normal Unix user and may therefore be required by modules and applications. It is recommended that you retain the default (On) unless it prevents an application running. Since the setting applies to the process, this is not compatible with threaded MPMs.

Note

If VHostSecure prevents an application running, this may be a warning sign that the application should be reviewed for security.

top

VHostUser Directive

Description:Sets the User ID under which a virtual host runs.
Syntax:VHostUser unix-userid
Default:Inherits the userid specified in User
Context:virtual host
Status:Experimental
Module:mod_privileges
Compatibility:Available on Solaris 10 and OpenSolaris with non-threaded MPMs (prefork or custom MPM).

The VHostUser directive sets the Unix userid under which the server will process requests to a virtualhost. The userid is set before the request is processed and reset afterwards using Solaris Privileges. Since the setting applies to the process, this is not compatible with threaded MPMs.

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.

Security

This directive cannot be used to run apache as root! Nevertheless, it opens potential security issues similar to those discussed in the suexec documentation.

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_balancer.html.en0000664000175100017510000005574314737542416022777 0ustar covenercovener mod_proxy_balancer - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_balancer

Available Languages:  en  |  fr  |  ja 

Description:mod_proxy extension for load balancing
Status:Extension
Module Identifier:proxy_balancer_module
Source File:mod_proxy_balancer.c
Compatibility:Available in version 2.1 and later

Summary

This module requires the service of mod_proxy and it provides load balancing for all the supported protocols. The most important ones are:

The Load balancing scheduler algorithm is not provided by this module but from other ones such as:

Thus, in order to get the ability of load balancing, mod_proxy, mod_proxy_balancer and at least one of load balancing scheduler algorithm modules 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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Load balancer scheduler algorithm

At present, there are 4 load balancer scheduler algorithms available for use: Request Counting (mod_lbmethod_byrequests), Weighted Traffic Counting (mod_lbmethod_bytraffic), Pending Request Counting (mod_lbmethod_bybusyness) and Heartbeat Traffic Counting (mod_lbmethod_heartbeat). These are controlled via the lbmethod value of the Balancer definition. See the ProxyPass directive for more information, especially regarding how to configure the Balancer and BalancerMembers.

top

Load balancer stickyness

The balancer supports stickyness. When a request is proxied to some back-end, then all following requests from the same user should be proxied to the same back-end. Many load balancers implement this feature via a table that maps client IP addresses to back-ends. This approach is transparent to clients and back-ends, but suffers from some problems: unequal load distribution if clients are themselves hidden behind proxies, stickyness errors when a client uses a dynamic IP address that changes during a session and loss of stickyness, if the mapping table overflows.

The module mod_proxy_balancer implements stickyness on top of two alternative means: cookies and URL encoding. Providing the cookie can be either done by the back-end or by the Apache web server itself. The URL encoding is usually done on the back-end.

top

Examples of a balancer configuration

Before we dive into the technical details, here's an example of how you might use mod_proxy_balancer to provide load balancing between two back-end servers:

<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80"
    BalancerMember "http://192.168.1.51:80"
</Proxy>
ProxyPass        "/test" "balancer://mycluster"
ProxyPassReverse "/test" "balancer://mycluster"

Another example of how to provide load balancing with stickyness using mod_headers, even if the back-end server does not set a suitable session cookie:

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80" route=1
    BalancerMember "http://192.168.1.51:80" route=2
    ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass        "/test" "balancer://mycluster"
ProxyPassReverse "/test" "balancer://mycluster"
top

Exported Environment Variables

At present there are 6 environment variables exported:

BALANCER_SESSION_STICKY

This is assigned the stickysession value used for the current request. It is the name of the cookie or request parameter used for sticky sessions

BALANCER_SESSION_ROUTE

This is assigned the route parsed from the current request.

BALANCER_NAME

This is assigned the name of the balancer used for the current request. The value is something like balancer://foo.

BALANCER_WORKER_NAME

This is assigned the name of the worker used for the current request. The value is something like http://hostA:1234.

BALANCER_WORKER_ROUTE

This is assigned the route of the worker that will be used for the current request.

BALANCER_ROUTE_CHANGED

This is set to 1 if the session route does not match the worker route (BALANCER_SESSION_ROUTE != BALANCER_WORKER_ROUTE) or the session does not yet have an established route. This can be used to determine when/if the client needs to be sent an updated route when sticky sessions are used.

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 of 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 example.com domain add this code to your httpd.conf configuration file

<Location "/balancer-manager">
    SetHandler balancer-manager
    Require host example.com
</Location>

You can now access load balancer manager by using a Web browser to access the page http://your.server.name/balancer-manager. Please note that only Balancers defined outside of <Location ...> containers can be dynamically controlled by the Manager.

top

Details on load balancer stickyness

When using cookie based stickyness, you need to configure the name of the cookie that contains the information about which back-end to use. This is done via the stickysession attribute added to either ProxyPass or ProxySet. The name of the cookie is case-sensitive. The balancer extracts the value of the cookie and looks for a member worker with route equal to that value. The route must also be set in either ProxyPass or ProxySet. The cookie can either be set by the back-end, or as shown in the above example by the Apache web server itself.

Some back-ends use a slightly different form of stickyness cookie, for instance Apache Tomcat. Tomcat adds the name of the Tomcat instance to the end of its session id cookie, separated with a dot (.) from the session id. Thus if the Apache web server finds a dot in the value of the stickyness cookie, it only uses the part behind the dot to search for the route. In order to let Tomcat know about its instance name, you need to set the attribute jvmRoute inside the Tomcat configuration file conf/server.xml to the value of the route of the worker that connects to the respective Tomcat. The name of the session cookie used by Tomcat (and more generally by Java web applications based on servlets) is JSESSIONID (upper case) but can be configured to something else.

The second way of implementing stickyness is URL encoding. The web server searches for a query parameter in the URL of the request. The name of the parameter is specified again using stickysession. The value of the parameter is used to lookup a member worker with route equal to that value. Since it is not easy to extract and manipulate all URL links contained in responses, generally the work of adding the parameters to each link is done by the back-end generating the content. In some cases it might be feasible doing this via the web server using mod_substitute or mod_sed. This can have negative impact on performance though.

The Java standards implement URL encoding slightly different. They use a path info appended to the URL using a semicolon (;) as the separator and add the session id behind. As in the cookie case, Apache Tomcat can include the configured jvmRoute in this path info. To let Apache find this sort of path info, you need to set scolonpathdelim to On in ProxyPass or ProxySet.

Finally you can support cookies and URL encoding at the same time, by configuring the name of the cookie and the name of the URL parameter separated by a vertical bar (|) as in the following example:

ProxyPass "/test" "balancer://mycluster" stickysession=JSESSIONID|jsessionid scolonpathdelim=On
<Proxy "balancer://mycluster">
    BalancerMember "http://192.168.1.50:80" route=node1
    BalancerMember "http://192.168.1.51:80" route=node2
</Proxy>

If the cookie and the request parameter both provide routing information for the same request, the information from the request parameter is used.

top

Troubleshooting load balancer stickyness

If you experience stickyness errors, e.g. users lose their application sessions and need to login again, you first want to check whether this is because the back-ends are sometimes unavailable or whether your configuration is wrong. To find out about possible stability problems with the back-ends, check your Apache error log for proxy error messages.

To verify your configuration, first check, whether the stickyness is based on a cookie or on URL encoding. Next step would be logging the appropriate data in the access log by using an enhanced LogFormat. The following fields are useful:

%{MYCOOKIE}C
The value contained in the cookie with name MYCOOKIE. The name should be the same given in the stickysession attribute.
%{Set-Cookie}o
This logs any cookie set by the back-end. You can track, whether the back-end sets the session cookie you expect, and to which value it is set.
%{BALANCER_SESSION_STICKY}e
The name of the cookie or request parameter used to lookup the routing information.
%{BALANCER_SESSION_ROUTE}e
The route information found in the request.
%{BALANCER_WORKER_ROUTE}e
The route of the worker chosen.
%{BALANCER_ROUTE_CHANGED}e
Set to 1 if the route in the request is different from the route of the worker, i.e. the request couldn't be handled sticky.

Common reasons for loss of session are session timeouts, which are usually configurable on the back-end server.

The balancer also logs detailed information about handling stickyness to the error log, if the log level is set to debug or higher. This is an easy way to troubleshoot stickyness problems, but the log volume might be too high for production servers under high load.

Available Languages:  en  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_mime.html.en0000664000175100017510000020120414737542416020677 0ustar covenercovener mod_mime - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_mime

Available Languages:  en  |  fr  |  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 assign content metadata to the content selected for an HTTP response by mapping patterns in the URI or filenames to the metadata values. For example, the filename extensions of content files often define the content's Internet media type, language, character set, and content-encoding. This information is sent in HTTP messages containing that content and used in content negotiation when selecting alternatives, such that the user's preferences are respected when choosing one of several possible contents 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 metadata for that file. Respectively they set the character set, content-encoding, content-language, and media-type (content-type) of documents. The directive TypesConfig is used to specify a file which also maps extensions onto media 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 metadata 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 metadata. These directives include ForceType, SetHandler, SetInputFilter, and SetOutputFilter. The core directives override any filename extension mappings defined in mod_mime.

Note that changing the metadata 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 metadata (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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Files with Multiple Extensions

Files can have more than one extension; 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 that maps onto the same type of metadata, then the one to the right will be used, except for languages and content encodings. For example, if .gif maps to the media-type image/gif and .html maps to the media-type text/html, then the file welcome.gif.html will be associated with the media-type text/html.

Languages and content encodings are treated accumulative, because one can assign more than one language or encoding to a particular resource. 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 media-type and a handler. This will usually result in the request being handled 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 media-type text/html, then the file world.imap.html will be associated with both the imap-file handler and text/html media-type. When it is processed, the imap-file handler will be used, and so it will be treated as a mod_imagemap imagemap file.

If you would prefer only the last dot-separated part of the filename to be mapped to a particular piece of meta-data, then do not use the Add* directives. For example, if you wish to have the file foo.html.cgi processed as a CGI script, but not the file bar.cgi.html, then instead of using AddHandler cgi-script .cgi, use

Configure handler based on final extension only

<FilesMatch "[^.]+\.cgi$">
  SetHandler cgi-script
</FilesMatch>
top

Content encoding

A file of a particular media-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 (the Internet registered name for a given character encoding). charset is the media type's charset parameter for resources with 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. Filenames may have multiple extensions and the extension argument will be compared against each of them.

See also

top

AddEncoding Directive

Description:Maps the given filename extensions to the specified encoding type
Syntax:AddEncoding encoding 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 HTTP content-encoding. encoding is the HTTP content coding to append to the value of the Content-Encoding header field for documents named with 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. Filenames may have multiple extensions and the extension argument will be compared against each of them.

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. Filenames may have multiple extensions and the extension argument will be compared against each of them.

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

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. The filter is case-insensitive.

The extension argument is case-insensitive and can be specified with or without a leading dot. Filenames may have multiple extensions and the extension argument will be compared against each of them.

See also

top

AddLanguage Directive

Description:Maps the given filename extension to the specified content language
Syntax:AddLanguage language-tag 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. Files with the filename extension are assigned an HTTP Content-Language value of language-tag corresponding to the language identifiers defined by RFC 3066. This directive overrides 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. Filenames may have multiple extensions and the extension argument will be compared against each of them.

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

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. The filter argument is case-insensitive.

The extension argument is case-insensitive and can be specified with or without a leading dot. Filenames may have multiple extensions and the extension argument will be compared against each of them.

Note that when defining a set of filters using the AddOutputFilter directive, any definition made will replace any previous definition made by the AddOutputFilter directive.

# Effective filter "DEFLATE"
AddOutputFilter DEFLATE shtml
<Location "/foo">
  # Effective filter "INCLUDES", replacing "DEFLATE"
  AddOutputFilter INCLUDES shtml
</Location>
<Location "/bar">
  # Effective filter "INCLUDES;DEFLATE", replacing "DEFLATE"
  AddOutputFilter INCLUDES;DEFLATE shtml
</Location>
<Location "/bar/baz">
  # Effective filter "BUFFER", replacing "INCLUDES;DEFLATE"
  AddOutputFilter BUFFER shtml
</Location>
<Location "/bar/baz/buz">
  # No effective filter, replacing "BUFFER"
  RemoveOutputFilter shtml
</Location>

See also

top

AddType Directive

Description:Maps the given filename extensions onto the specified content type
Syntax:AddType media-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. media-type is the media 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.

It is recommended that new media types be added using the AddType directive rather than changing the TypesConfig file.

Example

AddType image/gif .gif

Or, to specify multiple file extensions in one directive:

Example

AddType image/jpeg jpeg jpg jpe

The extension argument is case-insensitive and can be specified with or without a leading dot. Filenames may have multiple extensions and the extension argument will be compared against each of them.

A similar effect to mod_negotiation's LanguagePriority can be achieved by qualifying a media-type with qs:

Example

AddType application/rss+xml;qs=0.8 .xml

This is useful in situations, e.g. when a client requesting Accept: */* can not actually processes the content returned by the server.

This directive primarily configures the content types generated for static files served out of the filesystem. For resources other than static files, where the generator of the response typically specifies a Content-Type, this directive has no effect.

Note

If no handler is explicitly set for a request, the specified content type will also be used as the handler name.

When explicit directives such as SetHandler or AddHandler do not apply to the current request, the internal handler name normally set by those directives is instead set to the content type specified by this directive.

This is a historical behavior that may be used by some third-party modules (such as mod_php) for taking responsibility for the matching request.

Configurations that rely on such "synthetic" types should be avoided. Additionally, configurations that restrict access to SetHandler or AddHandler should restrict access to this directive as well.

See also

top

DefaultLanguage Directive

Description:Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
Syntax:DefaultLanguage language-tag
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Base
Module:mod_mime

The DefaultLanguage directive tells Apache that all resources in the directive's scope (e.g., all resources 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 assigned a Content-Language of language-tag. This allows entire directory trees 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 no Content-Language header field will be generated.

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

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 /index.php/foo.shtml mod_mime will now treat the incoming request as /index.php/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. This will work analogously for virtual paths, such as those defined by <Location>

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

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 negotiation, 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 can cause unpredictable 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

MultiviewsMatch is not allowed in a <Location> or <LocationMatch> section.

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

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

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

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

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 media 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 responses containing those files to omit the HTTP Content-Type header field.

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 media 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 mime.types file provided by their OS, which associates common filename extensions with the official list of IANA registered media types maintained at http://www.iana.org/assignments/media-types/index.html as well as a large number of unofficial 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:

media-type [extension] ...

The case of the extension does not matter. Blank lines, and lines beginning with a hash character (#) are ignored. Empty lines are there for completeness (of the mime.types file). Apache httpd can still determine these types with mod_mime_magic.

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  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_nw_ssl.html.en0000664000175100017510000002300014737542416021251 0ustar covenercovener mod_nw_ssl - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_nw_ssl

Available Languages:  en  |  fr 

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.

Support Apache!

Directives

Bugfix checklist

See also

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

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_ajp.html.en0000664000175100017510000010015114737542416021762 0ustar covenercovener mod_proxy_ajp - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_ajp

Available Languages:  en  |  fr  |  ja 

Description:AJP support module for mod_proxy
Status:Extension
Module Identifier:proxy_ajp_module
Source File:mod_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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Usage

This module is used to reverse proxy to a backend application server (e.g. Apache Tomcat) using the AJP13 protocol. The usage is similar to an HTTP reverse proxy, but uses the ajp:// prefix:

Simple Reverse Proxy

ProxyPass "/app" "ajp://backend.example.com:8009/app"

Options such as the secret option of Tomcat (required by default since Tomcat 8.5.51 and 9.0.31) can just be added as a separate parameter at the end of ProxyPass or BalancerMember. This parameter is available in Apache HTTP Server 2.4.42 and later:

Simple Reverse Proxy with secret option

ProxyPass "/app" "ajp://backend.example.com:8009/app" secret=YOUR_AJP_SECRET

Balancers may also be used:

Balancer Reverse Proxy

<Proxy "balancer://cluster">
    BalancerMember "ajp://app1.example.com:8009" loadfactor=1
    BalancerMember "ajp://app2.example.com:8009" loadfactor=2
    ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass "/app" "balancer://cluster/app"

Note that usually no ProxyPassReverse directive is necessary. The AJP request includes the original host header given to the proxy, and the application server can be expected to generate self-referential headers relative to this host, so no rewriting is necessary.

The main exception is when the URL path on the proxy differs from that on the backend. In this case, a redirect header can be rewritten relative to the original host URL (not the backend ajp:// URL), for example:

Rewriting Proxied Path

ProxyPass "/apps/foo" "ajp://backend.example.com:8009/foo"
ProxyPassReverse "/apps/foo" "http://www.example.com/foo"

However, it is usually better to deploy the application on the backend server at the same path as the proxy rather than to take this approach.

top

Environment Variables

Environment variables whose names have the prefix AJP_ are forwarded to the origin server as AJP request attributes (with the AJP_ prefix removed from the name of the key).

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:

Once a connection is assigned to handle a particular request, the basic request information (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:

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

AJP13 uses network byte order for all data types.

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)
Byte 0 1 2 3 4...(n+3)
Contents 0x12 0x34 Data Length (n) Data
Packet Format (Container->Server)
Byte 0 1 2 3 4...(n+3)
Contents A B Data 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:

Code Type of Packet Meaning
2 Forward Request Begin the request-processing cycle with the following data
7 Shutdown The web server asks the container to shut itself down.
8 Ping The web server asks the container to take control (secure login phase).
10 CPing The web server asks the container to respond quickly with a CPong.
none Data Size (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 immediately after the Forward Request by the web server.

The servlet container can send the following types of messages to the webserver:

Code Type of Packet Meaning
3 Send Body Chunk Send a chunk of the body from the servlet container to the web server (and presumably, onto the browser).
4 Send Headers Send the response headers from the servlet container to the web server (and presumably, onto the browser).
5 End Response Marks the end of the response (and thus the request-handling cycle).
6 Get Body Chunk Get further data from the request if it hasn't all been transferred yet.
9 CPong Reply The 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 0x9FFF (==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 its value (string or integer). They can be sent in any order (though 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 ValueType Of ValueNote
?context0x01-Not currently implemented
?servlet_path0x02-Not currently implemented
?remote_user0x03String
?auth_type0x04String
?query_string0x05String
?jvm_route0x06String
?ssl_cert0x07String
?ssl_cipher0x08String
?ssl_session0x09String
?req_attribute0x0AStringName (the name of the attribute follows)
?ssl_key_size0x0BInteger
?secret0x0CStringSupported since 2.4.42
are_done0xFF-request_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, ssl_session and ssl_key_size 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.

The secret is sent when the secret=secret_keyword parameter is used in ProxyPass or BalancerMember directives. The backend needs to support secret and the values must match. request.secret or requiredSecret are documented in the AJP configuration of the Apache Tomcat.

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)
  chunk_terminator (byte) Ox00


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 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 (anything other than 0 in the actual C code), this TCP connection can now be used to handle new incoming requests. If reuse is false (==0), 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 chunked). 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  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_express.html.en0000664000175100017510000003264014737542416022710 0ustar covenercovener mod_proxy_express - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_express

Available Languages:  en  |  fr 

Description:Dynamic mass reverse proxy extension for mod_proxy
Status:Extension
Module Identifier:proxy_express_module
Source File:mod_proxy_express.c
Compatibility:Available in Apache 2.3.13 and later

Summary

This module creates dynamically configured mass reverse proxies, by mapping the Host: header of the HTTP request to a server name and backend URL stored in a DBM file. This allows for easy use of a huge number of reverse proxies with no configuration changes. It is much less feature-full than mod_proxy_balancer, which also provides dynamic growth, but is intended to handle much, much larger numbers of backends. It is ideally suited as a front-end HTTP switch and for micro-services architectures.

This module requires the service of mod_proxy.

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.

Limitations

  • This module is not intended to replace the dynamic capability of mod_proxy_balancer. Instead, it is intended to be mostly a lightweight and fast alternative to using mod_rewrite with RewriteMap and the [P] flag for mapped reverse proxying.
  • It does not support regex or pattern matching at all.
  • It emulates:
    <VirtualHost *:80>
       ServerName front.end.server
       ProxyPass        "/" "back.end.server:port"
       ProxyPassReverse "/" "back.end.server:port"
    </VirtualHost>
    That is, the entire URL is appended to the mapped backend URL. This is in keeping with the intent of being a simple but fast reverse proxy switch.
Support Apache!

Directives

Bugfix checklist

See also

top

ProxyExpressDBMFile Directive

Description:Pathname to DBM file.
Syntax:ProxyExpressDBMFile pathname
Context:server config, virtual host
Status:Extension
Module:mod_proxy_express

The ProxyExpressDBMFile directive points to the location of the Express map DBM file. This file serves to map the incoming server name, obtained from the Host: header, to a backend URL.

Note

The file is constructed from a plain text file format using the httxt2dbm utility.

ProxyExpress map file

##
##express-map.txt:
##

www1.example.com http://192.168.211.2:8080
www2.example.com http://192.168.211.12:8088
www3.example.com http://192.168.212.10

Create DBM file

httxt2dbm -i express-map.txt -o emap

Configuration

ProxyExpressEnable on
ProxyExpressDBMFile emap
top

ProxyExpressDBMType Directive

Description:DBM type of file.
Syntax:ProxyExpressDBMType type
Default:ProxyExpressDBMType default
Context:server config, virtual host
Status:Extension
Module:mod_proxy_express

The ProxyExpressDBMType directive controls the DBM type expected by the module. The default is the default DBM type created with httxt2dbm.

Possible values are (not all may be available at run time):

ValueDescription
db Berkeley DB files
gdbm GDBM files
ndbm NDBM files
sdbm SDBM files (always available)
default default DBM type
top

ProxyExpressEnable Directive

Description:Enable the module functionality.
Syntax:ProxyExpressEnable on|off
Default:ProxyExpressEnable off
Context:server config, virtual host
Status:Extension
Module:mod_proxy_express

The ProxyExpressEnable directive controls whether the module will be active.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_ftp.html.en0000664000175100017510000004455014737542416022013 0ustar covenercovener mod_proxy_ftp - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_ftp

Available Languages:  en  |  fr 

Description:FTP support module for mod_proxy
Status:Extension
Module Identifier:proxy_ftp_module
Source File:mod_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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

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 use the ForceType directive to default everything to binary:

ForceType application/octet-stream
top

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

top

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.

top

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

top

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 absence 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 insecure channels, an eavesdropper might intercept your password on its way.

top

Why do I get a file listing when I expected a file to be downloaded?

In order to allow both browsing the directories on an FTP server and downloading files, Apache looks at the request URL. If it looks like a directory, or contains wildcard characters ("*?[{~"), then it guesses that a listing is wanted instead of a download.

You can disable the special handling of names with wildcard characters. See the ProxyFtpListOnWildcard directive.

top

ProxyFtpDirCharset Directive

Description:Define the character set for proxied FTP listings
Syntax:ProxyFtpDirCharset character_set
Default:ProxyFtpDirCharset ISO-8859-1
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy_ftp
Compatibility:Available in Apache 2.2.7 and later. Moved from mod_proxy in Apache 2.3.5.

The ProxyFtpDirCharset directive defines the character set to be set for FTP directory listings in HTML generated by mod_proxy_ftp.

top

ProxyFtpEscapeWildcards Directive

Description:Whether wildcards in requested filenames are escaped when sent to the FTP server
Syntax:ProxyFtpEscapeWildcards on|off
Default:ProxyFtpEscapeWildcards on
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy_ftp
Compatibility:Available in Apache 2.3.3 and later

The ProxyFtpEscapeWildcards directive controls whether wildcard characters ("*?[{~") in requested filenames are escaped with backslash before sending them to the FTP server. That is the default behavior, but many FTP servers don't know about the escaping and try to serve the literal filenames they were sent, including the backslashes in the names.

Set to "off" to allow downloading files with wildcards in their names from FTP servers that don't understand wildcard escaping.

top

ProxyFtpListOnWildcard Directive

Description:Whether wildcards in requested filenames trigger a file listing
Syntax:ProxyFtpListOnWildcard on|off
Default:ProxyFtpListOnWildcard on
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy_ftp
Compatibility:Available in Apache 2.3.3 and later

The ProxyFtpListOnWildcard directive controls whether wildcard characters ("*?[{~") in requested filenames cause mod_proxy_ftp to return a listing of files instead of downloading a file. By default (value on), they do.

Set to "off" to allow downloading files even if they have wildcard characters in their names.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_http.html.en0000664000175100017510000002751414737542416022202 0ustar covenercovener mod_proxy_http - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_http

Available Languages:  en  |  fr 

Description:HTTP support module for mod_proxy
Status:Extension
Module Identifier:proxy_http_module
Source File:mod_proxy_http.c

Summary

This module requires the service of mod_proxy. It provides the features used for proxying HTTP and HTTPS 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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Environment Variables

In addition to the configuration directives that control the behaviour of mod_proxy, there are a number of environment variables that control the HTTP protocol provider. Environment variables below that don't specify specific values are enabled when set to any value.

proxy-sendextracrlf
Causes proxy to send an extra CR-LF newline on the end of a request. This is a workaround for a bug in some browsers.
force-proxy-request-1.0
Forces the proxy to send requests to the backend as HTTP/1.0 and disables HTTP/1.1 features.
proxy-nokeepalive
Forces the proxy to close the backend connection after each request.
proxy-chain-auth
If the proxy requires authentication, it will read and consume the proxy authentication credentials sent by the client. With proxy-chain-auth it will also forward the credentials to the next proxy in the chain. This may be necessary if you have a chain of proxies that share authentication information. Security Warning: Do not set this unless you know you need it, as it forwards sensitive information!
proxy-sendcl
HTTP/1.0 required all HTTP requests that include a body (e.g. POST requests) to include a Content-Length header. This environment variable forces the Apache proxy to send this header to the backend server, regardless of what the Client sent to the proxy. It ensures compatibility when proxying for an HTTP/1.0 or unknown backend. However, it may require the entire request to be buffered by the proxy, so it becomes very inefficient for large requests.
proxy-sendchunks or proxy-sendchunked
This is the opposite of proxy-sendcl. It allows request bodies to be sent to the backend using chunked transfer encoding. This allows the request to be efficiently streamed, but requires that the backend server supports HTTP/1.1.
proxy-interim-response
This variable takes values RFC (the default) or Suppress. Earlier httpd versions would suppress HTTP interim (1xx) responses sent from the backend. This is technically a violation of the HTTP protocol. In practice, if a backend sends an interim response, it may itself be extending the protocol in a manner we know nothing about, or just broken. So this is now configurable: set proxy-interim-response RFC to be fully protocol compliant, or proxy-interim-response Suppress to suppress interim responses.
proxy-initial-not-pooled
If this variable is set, no pooled connection will be reused if the client request is the initial request on the frontend connection. This avoids the "proxy: error reading status line from remote server" error message caused by the race condition that the backend server closed the pooled connection after the connection check by the proxy and before data sent by the proxy reached the backend. It has to be kept in mind that setting this variable downgrades performance, especially with HTTP/1.0 clients.
top

Request notes

mod_proxy_http creates the following request notes for logging using the %{VARNAME}n format in LogFormat or ErrorLogFormat:

proxy-source-port
The local port used for the connection to the backend server.
proxy-status
The HTTP status received from the backend server.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_uwsgi.html.en0000664000175100017510000002062614737542416022356 0ustar covenercovener mod_proxy_uwsgi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_uwsgi

Available Languages:  en  |  fr 

Description:UWSGI gateway module for mod_proxy
Status:Extension
Module Identifier:proxy_uwsgi_module
Source File:mod_proxy_uwsgi.c
Compatibility:Available in version 2.4.30 and later

Summary

This module requires the service of mod_proxy. It provides support for the UWSGI protocol.

Thus, in order to get the ability of handling the UWSGI protocol, mod_proxy and mod_proxy_uwsgi 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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Examples

Remember, in order to make the following examples work, you have to enable mod_proxy and mod_proxy_uwsgi.

Simple gateway

ProxyPass "/uwsgi-bin/" "uwsgi://localhost:4000/"

The balanced gateway needs mod_proxy_balancer and at least one load balancer algorithm module, such as mod_lbmethod_byrequests, in addition to the proxy modules listed above. mod_lbmethod_byrequests is the default, and will be used for this example configuration.

Balanced gateway

ProxyPass "/uwsgi-bin/" "balancer://somecluster/"
<Proxy balancer://somecluster>
    BalancerMember uwsgi://localhost:4000
    BalancerMember uwsgi://localhost:4001
</Proxy>

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_reflector.html.en0000664000175100017510000002104214737542416021735 0ustar covenercovener mod_reflector - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_reflector

Available Languages:  en  |  fr 

Description:Reflect a request body as a response via the output filter stack.
Status:Base
Module Identifier:reflector_module
Source File:mod_reflector.c
Compatibility:Version 2.3 and later

Summary

This module allows request bodies to be reflected back to the client, in the process passing the request through the output filter stack. A suitably configured chain of filters can be used to transform the request into a response. This module can be used to turn an output filter into an HTTP service.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Examples

Compression service
Pass the request body through the DEFLATE filter to compress the body. This request requires a Content-Encoding request header containing "gzip" for the filter to return compressed data.
<Location "/compress">
    SetHandler reflector
    SetOutputFilter DEFLATE
</Location>
Image downsampling service
Pass the request body through an image downsampling filter, and reflect the results to the caller.
<Location "/downsample">
    SetHandler reflector
    SetOutputFilter DOWNSAMPLE
</Location>
top

ReflectorHeader Directive

Description:Reflect an input header to the output headers
Syntax:ReflectorHeader inputheader [outputheader]
Context:server config, virtual host, directory, .htaccess
Override:Options
Status:Base
Module:mod_reflector

This directive controls the reflection of request headers to the response. The first argument is the name of the request header to copy. If the optional second argument is specified, it will be used as the name of the response header, otherwise the original request header name will be used.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_request.html.en0000664000175100017510000002247414737542416021452 0ustar covenercovener mod_request - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_request

Available Languages:  en  |  fr  |  tr 

Description:Filters to handle and make available HTTP request bodies
Status:Base
Module Identifier:request_module
Source File:mod_request.c
Compatibility:Available in Apache 2.3 and later
Support Apache!

Directives

Bugfix checklist

See also

top

KeptBodySize Directive

Description:Keep the request body instead of discarding it up to the specified maximum size, for potential use by filters such as mod_include.
Syntax:KeptBodySize maximum size in bytes
Default:KeptBodySize 0
Context:directory
Status:Base
Module:mod_request

Under normal circumstances, request handlers such as the default handler for static files will discard the request body when it is not needed by the request handler. As a result, filters such as mod_include are limited to making GET requests only when including other URLs as subrequests, even if the original request was a POST request, as the discarded request body is no longer available once filter processing is taking place.

When this directive has a value greater than zero, request handlers that would otherwise discard request bodies will instead set the request body aside for use by filters up to the maximum size specified. In the case of the mod_include filter, an attempt to POST a request to the static shtml file will cause any subrequests to be POST requests, instead of GET requests as before.

This feature makes it possible to break up complex web pages and web applications into small individual components, and combine the components and the surrounding web page structure together using mod_include. The components can take the form of CGI programs, scripted languages, or URLs reverse proxied into the URL space from another server using mod_proxy.

Note: Each request set aside has to be set aside in temporary RAM until the request is complete. As a result, care should be taken to ensure sufficient RAM is available on the server to support the intended load. Use of this directive should be limited to where needed on targeted parts of your URL space, and with the lowest possible value that is still big enough to hold a request body.

If the request size sent by the client exceeds the maximum size allocated by this directive, the server will return 413 Request Entity Too Large.

See also

Available Languages:  en  |  fr  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session.html.en0000664000175100017510000010570514737542416021444 0ustar covenercovener mod_session - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_session

Available Languages:  en  |  fr 

Description:Session support
Status:Extension
Module Identifier:session_module
Source File:mod_session.c
Compatibility:Available in Apache 2.3 and later

Summary

Warning

The session modules make use of HTTP cookies, and as such can fall victim to Cross Site Scripting attacks, or expose potentially private information to clients. Please ensure that the relevant risks have been taken into account before enabling the session functionality on your server.

This module provides support for a server wide per user session interface. Sessions can be used for keeping track of whether a user has been logged in, or for other per user information that should be kept available across requests.

Sessions may be stored on the server, or may be stored on the browser. Sessions may also be optionally encrypted for added security. These features are divided into several modules in addition to mod_session; mod_session_crypto, mod_session_cookie and mod_session_dbd. Depending on the server requirements, load the appropriate modules into the server (either statically at compile time or dynamically via the LoadModule directive).

Sessions may be manipulated from other modules that depend on the session, or the session may be read from and written to using environment variables and HTTP headers, as appropriate.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

What is a session?

At the core of the session interface is a table of key and value pairs that are made accessible across browser requests. These pairs can be set to any valid string, as needed by the application making use of the session.

The "session" is a application/x-www-form-urlencoded string containing these key value pairs, as defined by the HTML specification.

The session can optionally be encrypted and base64 encoded before being written to the storage mechanism, as defined by the administrator.

top

Who can use a session?

The session interface is primarily developed for the use by other server modules, such as mod_auth_form, however CGI based applications can optionally be granted access to the contents of the session via the HTTP_SESSION environment variable. Sessions have the option to be modified and/or updated by inserting an HTTP response header containing the new session parameters.

top

Keeping sessions on the server

Apache can be configured to keep track of per user sessions stored on a particular server or group of servers. This functionality is similar to the sessions available in typical application servers.

If configured, sessions are tracked through the use of a session ID that is stored inside a cookie, or extracted from the parameters embedded within the URL query string, as found in a typical GET request.

As the contents of the session are stored exclusively on the server, there is an expectation of privacy of the contents of the session. This does have performance and resource implications should a large number of sessions be present, or where a large number of webservers have to share sessions with one another.

The mod_session_dbd module allows the storage of user sessions within a SQL database via mod_dbd.

top

Keeping sessions on the browser

In high traffic environments where keeping track of a session on a server is too resource intensive or inconvenient, the option exists to store the contents of the session within a cookie on the client browser instead.

This has the advantage that minimal resources are required on the server to keep track of sessions, and multiple servers within a server farm have no need to share session information.

The contents of the session however are exposed to the client, with a corresponding risk of a loss of privacy. The mod_session_crypto module can be configured to encrypt the contents of the session before writing the session to the client.

The mod_session_cookie allows the storage of user sessions on the browser within an HTTP cookie.

top

Basic Examples

Creating a session is as simple as turning the session on, and deciding where the session will be stored. In this example, the session will be stored on the browser, in a cookie called session.

Browser based session

Session On
SessionCookieName session path=/

The session is not useful unless it can be written to or read from. The following example shows how values can be injected into the session through the use of a predetermined HTTP response header called X-Replace-Session.

Writing to a session

Session On
SessionCookieName session path=/
SessionHeader X-Replace-Session

The header should contain name value pairs expressed in the same format as a query string in a URL, as in the example below. Setting a key to the empty string has the effect of removing that key from the session.

CGI to write to a session

#!/bin/bash
echo "Content-Type: text/plain"
echo "X-Replace-Session: key1=foo&key2=&key3=bar"
echo
env

If configured, the session can be read back from the HTTP_SESSION environment variable. By default, the session is kept private, so this has to be explicitly turned on with the SessionEnv directive.

Read from a session

Session On
SessionEnv On
SessionCookieName session path=/
SessionHeader X-Replace-Session

Once read, the CGI variable HTTP_SESSION should contain the value key1=foo&key3=bar.

top

Session Privacy

Using the "show cookies" feature of your browser, you would have seen a clear text representation of the session. This could potentially be a problem should the end user need to be kept unaware of the contents of the session, or where a third party could gain unauthorised access to the data within the session.

The contents of the session can be optionally encrypted before being placed on the browser using the mod_session_crypto module.

Browser based encrypted session

Session On
SessionCryptoPassphrase secret
SessionCookieName session path=/

The session will be automatically decrypted on load, and encrypted on save by Apache, the underlying application using the session need have no knowledge that encryption is taking place.

Sessions stored on the server rather than on the browser can also be encrypted as needed, offering privacy where potentially sensitive information is being shared between webservers in a server farm using the mod_session_dbd module.

top

Cookie Privacy

The HTTP cookie mechanism also offers privacy features, such as the ability to restrict cookie transport to SSL protected pages only, or to prevent browser based javascript from gaining access to the contents of the cookie.

Warning

Some of the HTTP cookie privacy features are either non-standard, or are not implemented consistently across browsers. The session modules allow you to set cookie parameters, but it makes no guarantee that privacy will be respected by the browser. If security is a concern, use the mod_session_crypto to encrypt the contents of the session, or store the session on the server using the mod_session_dbd module.

Standard cookie parameters can be specified after the name of the cookie, as in the example below.

Setting cookie parameters

Session On
SessionCryptoPassphrase secret
SessionCookieName session path=/private;domain=example.com;httponly;secure;

In cases where the Apache server forms the frontend for backend origin servers, it is possible to have the session cookies removed from the incoming HTTP headers using the SessionCookieRemove directive. This keeps the contents of the session cookies from becoming accessible from the backend server.

top

Session Support for Authentication

As is possible within many application servers, authentication modules can use a session for storing the username and password after login. The mod_auth_form saves the user's login name and password within the session.

Form based authentication

Session On
SessionCryptoPassphrase secret
SessionCookieName session path=/
AuthFormProvider file
AuthUserFile "conf/passwd"
AuthType form
AuthName "realm"
#...

See the mod_auth_form module for documentation and complete examples.

top

Integrating Sessions with External Applications

In order for sessions to be useful, it must be possible to share the contents of a session with external applications, and it must be possible for an external application to write a session of its own.

A typical example might be an application that changes a user's password set by mod_auth_form. This application would need to read the current username and password from the session, make the required changes to the user's password, and then write the new password to the session in order to provide a seamless transition to the new password.

A second example might involve an application that registers a new user for the first time. When registration is complete, the username and password is written to the session, providing a seamless transition to being logged in.

Apache modules
Modules within the server that need access to the session can use the mod_session.h API in order to read from and write to the session. This mechanism is used by modules like mod_auth_form.
CGI programs and scripting languages
Applications that run within the webserver can optionally retrieve the value of the session from the HTTP_SESSION environment variable. The session should be encoded as a application/x-www-form-urlencoded string as described by the HTML specification. The environment variable is controlled by the setting of the SessionEnv directive. The session can be written to by the script by returning a application/x-www-form-urlencoded response header with a name set by the SessionHeader directive. In both cases, any encryption or decryption, and the reading the session from or writing the session to the chosen storage mechanism is handled by the mod_session modules and corresponding configuration.
Applications behind mod_proxy
If the SessionHeader directive is used to define an HTTP request header, the session, encoded as a application/x-www-form-urlencoded string, will be made available to the application. If the same header is provided in the response, the value of this response header will be used to replace the session. As above, any encryption or decryption, and the reading the session from or writing the session to the chosen storage mechanism is handled by the mod_session modules and corresponding configuration.
Standalone applications
Applications might choose to manipulate the session outside the control of the Apache HTTP server. In this case, it is the responsibility of the application to read the session from the chosen storage mechanism, decrypt the session, update the session, encrypt the session and write the session to the chosen storage mechanism, as appropriate.
top

Session Directive

Description:Enables a session for the current directory or location
Syntax:Session On|Off
Default:Session Off
Context:server config, virtual host, directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_session

The Session directive enables a session for the directory or location container. Further directives control where the session will be stored and how privacy is maintained.

top

SessionEnv Directive

Description:Control whether the contents of the session are written to the HTTP_SESSION environment variable
Syntax:SessionEnv On|Off
Default:SessionEnv Off
Context:server config, virtual host, directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_session

If set to On, the SessionEnv directive causes the contents of the session to be written to a CGI environment variable called HTTP_SESSION.

The string is written in the URL query format, for example:

key1=foo&key3=bar

top

SessionExclude Directive

Description:Define URL prefixes for which a session is ignored
Syntax:SessionExclude path
Default:none
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session

The SessionExclude directive allows sessions to be disabled relative to URL prefixes only. This can be used to make a website more efficient, by targeting a more precise URL space for which a session should be maintained. By default, all URLs within the directory or location are included in the session. The SessionExclude directive takes precedence over the SessionInclude directive.

Warning

This directive has a similar purpose to the path attribute in HTTP cookies, but should not be confused with this attribute. This directive does not set the path attribute, which must be configured separately.

top

SessionExpiryUpdateInterval Directive

Description:Define the number of seconds a session's expiry may change without the session being updated
Syntax:SessionExpiryUpdateInterval interval
Default:SessionExpiryUpdateInterval 0 (always update)
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session
Compatibility:Available in Apache 2.4.41 and later

The SessionExpiryUpdateInterval directive allows sessions to avoid the cost associated with writing the session each request when only the expiry time has changed. This can be used to make a website more efficient or reduce load on a database when using mod_session_dbd. The session is always written if the data stored in the session has changed or the expiry has changed by more than the configured interval.

Setting the interval to zero disables this directive, and the session expiry is refreshed for each request.

This directive only has an effect when combined with SessionMaxAge to enable session expiry. Sessions without an expiry are only written when the data stored in the session has changed.

Warning

Because the session expiry may not be refreshed with each request, it's possible for sessions to expire up to interval seconds early. Using a small interval usually provides sufficient savings while having a minimal effect on expiry resolution.

top

SessionHeader Directive

Description:Import session updates from a given HTTP response header
Syntax:SessionHeader header
Default:none
Context:server config, virtual host, directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_session

The SessionHeader directive defines the name of an HTTP response header which, if present, will be parsed and written to the current session.

The header value is expected to be in the URL query format, for example:

key1=foo&key2=&key3=bar

Where a key is set to the empty string, that key will be removed from the session.

top

SessionInclude Directive

Description:Define URL prefixes for which a session is valid
Syntax:SessionInclude path
Default:all URLs
Context:server config, virtual host, directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_session

The SessionInclude directive allows sessions to be made valid for specific URL prefixes only. This can be used to make a website more efficient, by targeting a more precise URL space for which a session should be maintained. By default, all URLs within the directory or location are included in the session.

Warning

This directive has a similar purpose to the path attribute in HTTP cookies, but should not be confused with this attribute. This directive does not set the path attribute, which must be configured separately.

top

SessionMaxAge Directive

Description:Define a maximum age in seconds for a session
Syntax:SessionMaxAge maxage
Default:SessionMaxAge 0
Context:server config, virtual host, directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_session

The SessionMaxAge directive defines a time limit for which a session will remain valid. When a session is saved, this time limit is reset and an existing session can be continued. If a session becomes older than this limit without a request to the server to refresh the session, the session will time out and be removed. Where a session is used to stored user login details, this has the effect of logging the user out automatically after the given time.

Setting the maxage to zero disables session expiry.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_fcgi.html.en0000664000175100017510000005446414737542416022137 0ustar covenercovener mod_proxy_fcgi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_fcgi

Available Languages:  en  |  fr 

Description:FastCGI support module for mod_proxy
Status:Extension
Module Identifier:proxy_fcgi_module
Source File:mod_proxy_fcgi.c
Compatibility:Available in version 2.3 and later

Summary

This module requires the service of mod_proxy. It provides support for the FastCGI protocol.

Thus, in order to get the ability of handling the FastCGI protocol, mod_proxy and mod_proxy_fcgi have to be present in the server.

Unlike mod_fcgid and mod_fastcgi, mod_proxy_fcgi has no provision for starting the application process; fcgistarter is provided (on some platforms) for that purpose. Alternatively, external launching or process management may be available in the FastCGI application framework in use.

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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Examples

Remember, in order to make the following examples work, you have to enable mod_proxy and mod_proxy_fcgi.

Single application instance

ProxyPass "/myapp/" "fcgi://localhost:4000/"

mod_proxy_fcgi disables connection reuse by default, so after a request has been completed the connection will NOT be held open by that httpd child process and won't be reused. If the FastCGI application is able to handle concurrent connections from httpd, you can opt-in to connection reuse as shown in the following example:

Single application instance, connection reuse (2.4.11 and later)

ProxyPass "/myapp/" "fcgi://localhost:4000/" enablereuse=on

Enable connection reuse to a FCGI backend like PHP-FPM

Please keep in mind that PHP-FPM (at the time of writing, February 2018) uses a prefork model, namely each of its worker processes can handle one connection at the time.
By default mod_proxy (configured with enablereuse=on) allows a connection pool of ThreadsPerChild connections to the backend for each httpd process when using a threaded mpm (like worker or event), so the following use cases should be taken into account:

  • Under HTTP/1.1 load it will likely cause the creation of up to MaxRequestWorkers connections to the FCGI backend.
  • Under HTTP/2 load, due to how mod_http2 is implemented, there are additional h2 worker threads that may force the creation of other backend connections. The overall count of connections in the pools may raise to more than MaxRequestWorkers.

The maximum number of PHP-FPM worker processes needs to be configured wisely, since there is the chance that they will all end up "busy" handling idle persistent connections, without any room for new ones to be established, and the end user experience will be a pile of HTTP request timeouts.

The following example passes the request URI as a filesystem path for the PHP-FPM daemon to run. The request URL is implicitly added to the 2nd parameter. The hostname and port following fcgi:// are where PHP-FPM is listening. Connection pooling/reuse is enabled.

PHP-FPM

ProxyPassMatch "^/myapp/.*\.php(/.*)?$" "fcgi://localhost:9000/var/www/" enablereuse=on

The following example passes the request URI as a filesystem path for the PHP-FPM daemon to run. In this case, PHP-FPM is listening on a unix domain socket (UDS). Requires 2.4.9 or later. With this syntax, the hostname and optional port following fcgi:// are ignored.

PHP-FPM with UDS

ProxyPassMatch "^/(.*\.php(/.*)?)$" "unix:/var/run/php5-fpm.sock|fcgi://localhost/var/www/"

The balanced gateway needs mod_proxy_balancer and at least one load balancer algorithm module, such as mod_lbmethod_byrequests, in addition to the proxy modules listed above. mod_lbmethod_byrequests is the default, and will be used for this example configuration.

Balanced gateway to multiple application instances

ProxyPass "/myapp/" "balancer://myappcluster/"
<Proxy "balancer://myappcluster/">
    BalancerMember "fcgi://localhost:4000"
    BalancerMember "fcgi://localhost:4001"
</Proxy>

You can also force a request to be handled as a reverse-proxy request, by creating a suitable Handler pass-through. The example configuration below will pass all requests for PHP scripts to the specified FastCGI server using reverse proxy. This feature is available in Apache HTTP Server 2.4.10 and later. For performance reasons, you will want to define a worker representing the same fcgi:// backend. The benefit of this form is that it allows the normal mapping of URI to filename to occur in the server, and the local filesystem result is passed to the backend. When FastCGI is configured this way, the server can calculate the most accurate PATH_INFO.

Proxy via Handler

<FilesMatch "\.php$">
    # Note: The only part that varies is /path/to/app.sock
    SetHandler  "proxy:unix:/path/to/app.sock|fcgi://localhost/"
</FilesMatch>

# Define a matching worker.
# The part that is matched to the SetHandler is the part that
# follows the pipe. If you need to distinguish, "localhost; can
# be anything unique.
<Proxy "fcgi://localhost/" enablereuse=on max=10>
</Proxy>

<FilesMatch ...>
    SetHandler  "proxy:fcgi://localhost:9000"
</FilesMatch>

<FilesMatch ...>
    SetHandler  "proxy:balancer://myappcluster/"
</FilesMatch>
top

Environment Variables

In addition to the configuration directives that control the behaviour of mod_proxy, there are a number of environment variables that control the FCGI protocol provider:

proxy-fcgi-pathinfo
When configured via ProxyPass or ProxyPassMatch, mod_proxy_fcgi will not set the PATH_INFO environment variable. This allows the backend FCGI server to correctly determine SCRIPT_NAME and Script-URI and be compliant with RFC 3875 section 3.3. If instead you need mod_proxy_fcgi to generate a "best guess" for PATH_INFO, set this env-var. This is a workaround for a bug in some FCGI implementations. This variable can be set to multiple values to tweak at how the best guess is chosen (In 2.4.11 and later only):
first-dot
PATH_INFO is split from the slash following the first "." in the URL.
last-dot
PATH_INFO is split from the slash following the last "." in the URL.
full
PATH_INFO is calculated by an attempt to map the URL to the local filesystem.
unescape
PATH_INFO is the path component of the URL, unescaped / decoded.
any other value
PATH_INFO is the same as the path component of the URL. Originally, this was the only proxy-fcgi-pathinfo option.
top

ProxyFCGIBackendType Directive

Description:Specify the type of backend FastCGI application
Syntax:ProxyFCGIBackendType FPM|GENERIC
Default:ProxyFCGIBackendType FPM
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_proxy_fcgi
Compatibility:Available in version 2.4.26 and later

This directive allows the type of backend FastCGI application to be specified. Some FastCGI servers, such as PHP-FPM, use historical quirks of environment variables to identify the type of proxy server being used. Set this directive to "GENERIC" if your non PHP-FPM application has trouble interpreting environment variables such as SCRIPT_FILENAME or PATH_TRANSLATED as set by the server.

One example of values that change based on the setting of this directive is SCRIPT_FILENAME. When using mod_proxy_fcgi historically, SCRIPT_FILENAME was prefixed with the string "proxy:fcgi://". This variable is what some generic FastCGI applications would read as their script input, but PHP-FPM would strip the prefix then remember it was talking to Apache. In 2.4.21 through 2.4.25, this prefix was automatically stripped by the server, breaking the ability of PHP-FPM to detect and interoperate with Apache in some scenarios.

top

ProxyFCGISetEnvIf Directive

Description:Allow variables sent to FastCGI servers to be fixed up
Syntax:ProxyFCGISetEnvIf conditional-expression [!]environment-variable-name [value-expression]
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_proxy_fcgi
Compatibility:Available in version 2.4.26 and later

Just before passing a request to the configured FastCGI server, the core of the web server sets a number of environment variables based on details of the current request. FastCGI programs often uses these environment variables as inputs that determine what underlying scripts they will process, or what output they directly produce.

Examples of noteworthy environment variables are:

This directive allows the environment variables above, or any others of interest, to be overridden. This directive is evaluated after the initial values for these variables are set, so they can be used as input into both the condition expressions and value expressions.

Parameter syntax:

conditional-expression
Specifies an expression that controls whether the environment variable that follows will be modified. For information on the expression syntax, see the examples that follow or the full specification at the ap_expr documentation.
environment-variable-name
Specifies the CGI environment variable to change, such as PATH_INFO. If preceded by an exclamation point, the variable will be unset.
value-expression
Specifies the replacement value for the preceding environment variable. Backreferences, such as "$1", can be included from regular expression captures in conditional-expression. If omitted, the variable is set (or overridden) to an empty string — but see the Note below.
# A basic, unconditional override
ProxyFCGISetEnvIf "true" PATH_INFO "/example"

# Use an environment variable in the value
ProxyFCGISetEnvIf "true" PATH_INFO "%{reqenv:SCRIPT_NAME}"

# Use captures in the conditions and backreferences in the replacement
ProxyFCGISetEnvIf "reqenv('PATH_TRANSLATED') =~ m|(/.*prefix)(\d+)(.*)|" PATH_TRANSLATED "$1$3"

Note: Unset vs. Empty

The following will unset VARIABLE, preventing it from being sent to the FastCGI server:
ProxyFCGISetEnvIf true !VARIABLE
Whereas the following will erase any existing value of VARIABLE (by setting it to the empty string), but the empty VARIABLE will still be sent to the server:
ProxyFCGISetEnvIf true VARIABLE
The CGI/1.1 specification does not distinguish between a variable with an empty value and a variable that does not exist. However, many CGI and FastCGI implementations distinguish (or allow scripts to distinguish) between the two. The choice of which to use is dependent upon your implementation and your reason for modifying the variable.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_hcheck.html.en0000664000175100017510000004310014737542416022435 0ustar covenercovener mod_proxy_hcheck - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_hcheck

Available Languages:  en  |  fr 

Description:Dynamic health check of Balancer members (workers) for mod_proxy
Status:Extension
Module Identifier:proxy_hcheck_module
Source File:mod_proxy_hcheck.c
Compatibility:Available in Apache 2.4.21 and later

Summary

This module provides for dynamic health checking of balancer members (workers). This can be enabled on a worker-by-worker basis. The health check is done independently of the actual reverse proxy requests.

This module requires the service of mod_watchdog.

Parameters

The health check mechanism is enabled via the use of additional BalancerMember parameters, which are configured in the standard way via ProxyPass:

A new BalancerMember status state (flag) is defined via this module: "C". When the worker is taken offline due to failures as determined by the health check module, this flag is set, and can be seen (and modified) via the balancer-manager.

Parameter Default Description
hcmethod None No dynamic health check performed. Choices are:
MethodDescriptionNote
NoneNo dynamic health checking done
TCPCheck that a socket to the backend can be created: e.g. "are you up"
OPTIONSSend a HTTP OPTIONS request to the backend via HTTP/1.0*
HEADSend a HTTP HEAD request to the backend via HTTP/1.0*
GETSend a HTTP GET request to the backend via HTTP/1.0*
OPTIONS11Send a HTTP OPTIONS request to the backend via HTTP/1.1*
HEAD11Send a HTTP HEAD request to the backend via HTTP/1.1*
GET11Send a HTTP GET request to the backend via HTTP/1.1*
*: Unless hcexpr is used, a 2xx or 3xx HTTP status will be interpreted as passing the health check
hcpasses 1 Number of successful health check tests before worker is re-enabled
hcfails 1 Number of failed health check tests before worker is disabled
hcinterval 30 Period of health checks in seconds (e.g. performed every 30 seconds)
hcuri   Additional URI to be appended to the worker URL for the health check.
hctemplate   Name of template, created via ProxyHCTemplate, to use for setting health check parameters for this worker
hcexpr   Name of expression, created via ProxyHCExpr, used to check response headers for health.
If not used, 2xx thru 3xx status codes imply success

Compatibility:

OPTIONS11, HEAD11 and GET11 are available in 2.4.55 and above.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Usage examples

The following example shows how one might configured health checking for various backend servers:

ProxyHCExpr ok234 {%{REQUEST_STATUS} =~ /^[234]/}
ProxyHCExpr gdown {%{REQUEST_STATUS} =~ /^[5]/}
ProxyHCExpr in_maint {hc('body') !~ /Under maintenance/}

<Proxy balancer://foo>
  BalancerMember http://www.example.com/  hcmethod=GET hcexpr=in_maint hcuri=/status.php
  BalancerMember http://www2.example.com/ hcmethod=HEAD hcexpr=ok234 hcinterval=10
  BalancerMember http://www3.example.com/ hcmethod=TCP hcinterval=5 hcpasses=2 hcfails=3
  BalancerMember http://www4.example.com/
</Proxy>

ProxyPass "/" "balancer://foo"
ProxyPassReverse "/" "balancer://foo"

In this scenario, http://www.example.com/ is health checked by sending a GET /status.php request to that server and seeing that the returned page does not include the string Under maintenance. If it does, that server is put in health-check fail mode, and disabled. This dynamic check is performed every 30 seconds, which is the default.

http://www2.example.com/ is checked by sending a simple HEAD request every 10 seconds and making sure that the response status is 2xx, 3xx or 4xx. http://www3.example.com/ is checked every 5 seconds by simply ensuring that the socket to that server is up. If the backend is marked as "down" and it passes 2 health check, it will be re-enabled and added back into the load balancer. It takes 3 back-to-back health check failures to disable the server and move it out of rotation. Finally, http://www4.example.com/ is not dynamically checked at all.

top

ProxyHCExpr Directive

Description:Creates a named condition expression to use to determine health of the backend based on its response
Syntax:ProxyHCExpr name {ap_expr expression}
Context:server config, virtual host
Status:Extension
Module:mod_proxy_hcheck

The ProxyHCExpr directive allows for creating a named condition expression that checks the response headers of the backend server to determine its health. This named condition can then be assigned to balancer members via the hcexpr parameter.

ProxyHCExpr: Allow for 2xx/3xx/4xx as passing

ProxyHCExpr ok234 {%{REQUEST_STATUS} =~ /^[234]/}
ProxyPass "/apps"     "balancer://foo"

<Proxy balancer://foo>
  BalancerMember http://www2.example.com/  hcmethod=HEAD hcexpr=ok234 hcinterval=10
</Proxy>
The expression can use curly-parens ("{}") as quoting deliminators in addition to normal quotes.

If using a health check method (eg: GET) which results in a response body, that body itself can be checked via ap_expr using the hc() expression function, which is unique to this module.

In the following example, we send the backend a GET request and if the response body contains the phrase Under maintenance, we want to disable the backend.

ProxyHCExpr: Checking response body

ProxyHCExpr in_maint {hc('body') !~ /Under maintenance/}
ProxyPass "/apps"     "balancer://foo"

<Proxy balancer://foo>
  BalancerMember http://www.example.com/ hcexpr=in_maint hcmethod=get hcuri=/status.php
</Proxy>

NOTE: Since response body can quite large, it is best if used against specific status pages.

top

ProxyHCTemplate Directive

Description:Creates a named template for setting various health check parameters
Syntax:ProxyHCTemplate name parameter=setting [...]
Context:server config, virtual host
Status:Extension
Module:mod_proxy_hcheck

The ProxyHCTemplate directive allows for creating a named set (template) of health check parameters that can then be assigned to balancer members via the hctemplate parameter.

ProxyHCTemplate

ProxyHCTemplate tcp5 hcmethod=tcp hcinterval=5
ProxyPass "/apps"     "balancer://foo"

<Proxy balancer://foo>
  BalancerMember http://www2.example.com/ hctemplate=tcp5
</Proxy>
top

ProxyHCTPsize Directive

Description:Sets the total server-wide size of the threadpool used for the health check workers
Syntax:ProxyHCTPsize size
Default:ProxyHCTPsize 16
Context:server config
Status:Extension
Module:mod_proxy_hcheck

If Apache httpd and APR are built with thread support, the health check module will offload the work of the actual checking to a threadpool associated with the Watchdog process, allowing for parallel checks. The ProxyHCTPsize directive determines the size of this threadpool. If set to 0, no threadpool is used at all, resulting in serialized health checks.

ProxyHCTPsize

ProxyHCTPsize 32

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_http2.html.en0000664000175100017510000002437414737542416022265 0ustar covenercovener mod_proxy_http2 - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_http2

Available Languages:  en  |  fr 

Description:HTTP/2 support module for mod_proxy
Status:Extension
Module Identifier:proxy_http2_module
Source File:mod_proxy_http2.c
Compatibility:Available in httpd 2.4.19 and later

Summary

mod_proxy_http2 supports HTTP/2 only, it does not provide any downgrades to HTTP/1.1. This means that the backend needs to support HTTP/2 because HTTP/1.1 will not be used instead.

This module requires the service of mod_proxy, so in order to get the ability of handling HTTP/2 proxy requests, mod_proxy and mod_proxy_http2 need to be both loaded by the server.

mod_proxy_http2 works with incoming fronted requests using HTTP/1.1 or HTTP/2. In both cases, requests proxied to the same backend are sent over a single TCP connection whenever possible (namely when the connection can be re-used).

Caveat: there will be no attempt to consolidate multiple HTTP/1.1 frontend requests (configured to be proxied to the same backend) into HTTP/2 streams belonging to the same HTTP/2 request. Each HTTP/1.1 frontend request will be proxied to the backend using a separate HTTP/2 request (trying to re-use the same TCP connection if possible).

This module relies on libnghttp2 to provide the core http/2 engine.

Warning

This module is experimental. Its behaviors, directives, and defaults are subject to more change from release to release relative to other standard modules. Users are encouraged to consult the "CHANGES" file for potential updates.

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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Basic Examples

The examples below demonstrate how to configure HTTP/2 for backend connections for a reverse proxy.

HTTP/2 (TLS)

ProxyPass "/app" "h2://app.example.com"
ProxyPassReverse "/app" "https://app.example.com"

HTTP/2 (cleartext)

ProxyPass "/app" "h2c://app.example.com"
ProxyPassReverse "/app" "http://app.example.com"

The schemes to configure above in ProxyPassReverse for reverse proxying h2 (or h2c) protocols are the usual https (resp. http) as expected/used by the user agent.

top

Request notes

mod_proxy_http creates the following request notes for logging using the %{VARNAME}n format in LogFormat or ErrorLogFormat:

proxy-source-port
The local port used for the connection to the backend server.
proxy-status
The HTTP/2 status received from the backend server.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy.html.en0000664000175100017510000041060014737542416021133 0ustar covenercovener mod_proxy - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy

Available Languages:  en  |  fr  |  ja 

Description:Multi-protocol 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.

mod_proxy and related modules implement a proxy/gateway for Apache HTTP Server, supporting a number of popular protocols as well as several different load balancing algorithms. Third-party modules can add support for additional protocols and load balancing algorithms.

A set of modules must be loaded into the server to provide the necessary features. These modules can be included statically at build time or dynamically via the LoadModule directive). The set must include:

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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Forward Proxies and Reverse Proxies/Gateways

Apache HTTP Server can be configured in both a forward and reverse proxy (also known as gateway) 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. 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 proxies 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 (or gateway), 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 namespace of the reverse proxy. The reverse proxy then decides where to send those requests and returns the content as if it were 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.

Reverse Proxy

ProxyPass "/foo" "http://foo.example.com/bar"
ProxyPassReverse "/foo" "http://foo.example.com/bar"

Forward Proxy

ProxyRequests On
ProxyVia On

<Proxy "*">
  Require host internal.example.com
</Proxy>

Websocket Upgrade (2.4.47 and later)

ProxyPass "/some/ws/capable/path/" "http://example.com/some/ws/capable/path/" upgrade=websocket
top

Access via Handler

You can also force a request to be handled as a reverse-proxy request, by creating a suitable Handler pass-through. The example configuration below will pass all requests for PHP scripts to the specified FastCGI server using reverse proxy:

Reverse Proxy PHP scripts

<FilesMatch "\.php$">
    # Unix sockets require 2.4.7 or later
    SetHandler  "proxy:unix:/path/to/app.sock|fcgi://localhost/"
</FilesMatch>

This feature is available in Apache HTTP Server 2.4.10 and later.

top

Workers

The proxy manages the configuration of origin servers and their communication parameters in objects called workers. There are two built-in workers: the default forward proxy worker and the default reverse proxy worker. Additional workers can be configured explicitly.

The two default workers have a fixed configuration and will be used if no other worker matches the request. They do not use HTTP Keep-Alive or connection reuse. The TCP connections to the origin server will instead be opened and closed for each request.

Explicitly configured workers are identified by their URL. They are usually created and configured using ProxyPass or ProxyPassMatch when used for a reverse proxy:

ProxyPass "/example" "http://backend.example.com" connectiontimeout=5 timeout=30

This will create a worker associated with the origin server URL http://backend.example.com that will use the given timeout values. When used in a forward proxy, workers are usually defined via the ProxySet directive:

ProxySet "http://backend.example.com" connectiontimeout=5 timeout=30

or alternatively using Proxy and ProxySet:

<Proxy "http://backend.example.com">
  ProxySet connectiontimeout=5 timeout=30
</Proxy>

Using explicitly configured workers in the forward mode is not very common, because forward proxies usually communicate with many different origin servers. Creating explicit workers for some of the origin servers can still be useful if they are used very often. Explicitly configured workers have no concept of forward or reverse proxying by themselves. They encapsulate a common concept of communication with origin servers. A worker created by ProxyPass for use in a reverse proxy will also be used for forward proxy requests whenever the URL to the origin server matches the worker URL, and vice versa.

The URL identifying a direct worker is the URL of its origin server including any path components given:

ProxyPass "/examples" "http://backend.example.com/examples"
ProxyPass "/docs" "http://backend.example.com/docs"

This example defines two different workers, each using a separate connection pool and configuration.

Worker Sharing

Worker sharing happens if the worker URLs overlap, which occurs when the URL of some worker is a leading substring of the URL of another worker defined later in the configuration file. In the following example

ProxyPass "/apps" "http://backend.example.com/" timeout=60
ProxyPass "/examples" "http://backend.example.com/examples" timeout=10

the second worker isn't actually created. Instead the first worker is used. The benefit is, that there is only one connection pool, so connections are more often reused. Note that all configuration attributes given explicitly for the later worker will be ignored. This will be logged as a warning. In the above example, the resulting timeout value for the URL /examples will be 60 instead of 10!

If you want to avoid worker sharing, sort your worker definitions by URL length, starting with the longest worker URLs. If you want to maximize worker sharing, use the reverse sort order. See also the related warning about ordering ProxyPass directives.

Explicitly configured workers come in two flavors: direct workers and (load) balancer workers. They support many important configuration attributes which are described below in the ProxyPass directive. The same attributes can also be set using ProxySet.

The set of options available for a direct worker depends on the protocol which is specified in the origin server URL. Available protocols include ajp, fcgi, ftp, http and scgi.

Balancer workers are virtual workers that use direct workers known as their members to actually handle the requests. Each balancer can have multiple members. When it handles a request, it chooses a member based on the configured load balancing algorithm.

A balancer worker is created if its worker URL uses balancer as the protocol scheme. The balancer URL uniquely identifies the balancer worker. Members are added to a balancer using BalancerMember.

DNS resolution for origin domains

DNS resolution happens when the socket to the origin domain is created for the first time. When connection reuse is enabled, each backend domain is resolved only once per child process, and cached for all further connections until the child is recycled. This information should to be considered while planning DNS maintenance tasks involving backend domains. Please also check ProxyPass parameters for more details about connection reuse.

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 "*">
  Require ip 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.

See Also the Proxy-Chain-Auth environment variable.

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 httpd 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 httpd 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 mod_proxy is sending requests to an origin server that doesn't properly implement keepalives or HTTP/1.1, there are two environment variables that can force the request to use 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>

In 2.4.26 and later, the "no-proxy" environment variable can be set to disable mod_proxy processing the current request. This variable should be set with SetEnvIf, as SetEnv is not evaluated early enough.

top

Request Bodies

Some request methods such as POST include a request body. The HTTP protocol requires that requests which include a body either use chunked transfer encoding or send a Content-Length request header. When passing these requests on to the origin server, mod_proxy_http will always attempt to send the Content-Length. But if the body is large and the original request used chunked encoding, then chunked encoding may also be used in the upstream request. You can control this selection using environment variables. Setting proxy-sendcl ensures maximum compatibility with upstream servers by always sending the Content-Length, while setting proxy-sendchunked minimizes resource usage by using chunked encoding.

Under some circumstances, the server must spool request bodies to disk to satisfy the requested handling of request bodies. For example, this spooling will occur if the original body was sent with chunked encoding (and is large), but the administrator has asked for backend requests to be sent with Content-Length or as HTTP/1.0. This spooling can also occur if the request body already has a Content-Length header, but the server is configured to filter incoming request bodies.

top

Reverse Proxy Request Headers

When acting in a reverse-proxy mode (using the ProxyPass directive, for example), mod_proxy_http adds several request headers in order to pass information to the origin server. These headers are:

X-Forwarded-For
The IP address of the client.
X-Forwarded-Host
The original host requested by the client in the Host HTTP request header.
X-Forwarded-Server
The hostname of the proxy server.

Be careful when using these headers on the origin server, since they will contain more than one (comma-separated) value if the original request already contained one of these headers. For example, you can use %{X-Forwarded-For}i in the log format string of the origin server to log the original clients IP address, but you may get more than one address if the request passes through several proxies.

See also the ProxyPreserveHost and ProxyVia directives, which control other request headers.

Note: If you need to specify custom request headers to be added to the forwarded request, use the RequestHeader directive.

top

BalancerGrowth Directive

Description:Number of additional Balancers that can be added Post-configuration
Syntax:BalancerGrowth #
Default:BalancerGrowth 5
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:BalancerGrowth is only available in Apache HTTP Server 2.3.13 and later.

This directive allows for growth potential in the number of Balancers available for a virtualhost in addition to the number pre-configured. It only takes effect if there is at least one pre-configured Balancer.

top

BalancerInherit Directive

Description:Inherit ProxyPassed Balancers/Workers from the main server
Syntax:BalancerInherit On|Off
Default:BalancerInherit On
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:BalancerInherit is only available in Apache HTTP Server 2.4.5 and later.

This directive will cause the current server/vhost to "inherit" ProxyPass Balancers and Workers defined in the main server. This can cause issues and inconsistent behavior if using the Balancer Manager and so should be disabled if using that feature.

The setting in the global server defines the default for all vhosts.

top

BalancerMember Directive

Description:Add a member to a load balancing group
Syntax:BalancerMember [balancerurl] url [key=value [key=value ...]]
Context:directory
Status:Extension
Module:mod_proxy
Compatibility:BalancerMember is only available in Apache HTTP Server 2.2 and later.

This directive adds a member to a load balancing group. It can be used within a <Proxy balancer://...> container directive and can take any of the key value pair parameters available to ProxyPass directives.

One additional parameter is available only to BalancerMember directives: loadfactor. This is the member load factor - a decimal number between 1.0 (default) and 100.0, which defines the weighted load to be applied to the member in question.

The balancerurl is only needed when not within a <Proxy balancer://...> container directive. It corresponds to the url of a balancer defined in ProxyPass directive.

The path component of the balancer URL in any <Proxy balancer://...> container directive is ignored.

Trailing slashes should typically be removed from the URL of a BalancerMember.

top

BalancerPersist Directive

Description:Attempt to persist changes made by the Balancer Manager across restarts.
Syntax:BalancerPersist On|Off
Default:BalancerPersist Off
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:BalancerPersist is only available in Apache HTTP Server 2.4.4 and later.

This directive will cause the shared memory storage associated with the balancers and balancer members to be persisted across restarts. This allows these local changes to not be lost during the normal restart/graceful state transitions.

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 httpd 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.example.com:81"
NoProxy         ".example.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 .example.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, the two domains .ExAmple.com and .example.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.example.edu
www.example.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 httpd 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, the two hosts WWW.ExAmple.com and www.example.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 "*">
  Require host 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>

Differences from the Location configuration section

A backend URL matches the configuration section if it begins with the the wildcard-url string, even if the last path segment in the directive only matches a prefix of the backend URL. For example, <Proxy "http://example.com/foo"> matches all of http://example.com/foo, http://example.com/foo/bar, and http://example.com/foobar. The matching of the final URL differs from the behavior of the <Location> section, which for purposes of this note treats the final path component as if it ended in a slash.

For more control over the matching, see <ProxyMatch>.

See also

top

Proxy100Continue Directive

Description:Forward 100-continue expectation to the origin server
Syntax:Proxy100Continue Off|On
Default:Proxy100Continue On
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy
Compatibility:Available in version 2.4.40 and later

This directive determines whether the proxy should forward 100-continue Expect:ation to the origin server and thus let it decide when/if the HTTP request body should be read, or when Off the proxy should generate 100 Continue intermediate response by itself before forwarding the request body.

Effectiveness

This option is of use only for HTTP proxying, as handled by mod_proxy_http.

top

ProxyAddHeaders Directive

Description:Add proxy information in X-Forwarded-* headers
Syntax:ProxyAddHeaders Off|On
Default:ProxyAddHeaders On
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy
Compatibility:Available in version 2.3.10 and later

This directive determines whether or not proxy related information should be passed to the backend server through X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Server HTTP headers.

Effectiveness

This option is of use only for HTTP proxying, as handled by mod_proxy_http.

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

The ProxyBadHeader directive determines the behavior of mod_proxy if it receives syntactically invalid response header lines (i.e. containing no colon) from the origin server. The following arguments are possible:

IsError
Abort the request and end up with a 502 (Bad Gateway) response. This is the default behavior.
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 "news.example.com" "auctions.example.com" "friends.example.com"

Note that example would also be sufficient to match any of these sites.

Hosts would also be matched if referenced by IP address.

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 httpd 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.example.com:81"
NoProxy         ".example.com" "192.168.112.0/21"
ProxyDomain     ".example.com"
top

ProxyErrorOverride Directive

Description:Override error pages for proxied content
Syntax:ProxyErrorOverride Off|On [code ...]
Default:ProxyErrorOverride Off
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy
Compatibility:The list of status codes was added in 2.4.47

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

This directive does not affect the processing of informational (1xx), normal success (2xx), or redirect (3xx) responses.

By default ProxyErrorOverride affects all responses with codes between 400 (including) and 600 (excluding).

Example for default behavior

ProxyErrorOverride  On

To change the default behavior, you can specify the status codes to consider, separated by spaces. If you do so, all other status codes will be ignored. You can only specify status codes, that are considered error codes: between 400 (including) and 600 (excluding).

Example for custom status codes

ProxyErrorOverride  On 403 405 500 501 502 503 504
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 at least 512.

In almost every case, there's no reason to change that value.

If used with AJP, this directive sets the maximum AJP packet size in bytes. Values larger than 65536 are set to 65536. If you change it from the default, you must also change the packetSize attribute of your AJP connector on the Tomcat side! The attribute packetSize is only available in Tomcat 5.5.20+ and 6.0.2+

Normally it is not necessary to change the maximum packet size. Problems with the default value have been reported when sending certificates or certificate chains.

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 that it matches URLs using regular expressions.

From 2.4.8 onwards, named groups and backreferences are captured and written to the environment with the corresponding name prefixed with "MATCH_" and in upper case. This allows elements of URLs to be referenced from within expressions and modules like mod_rewrite. In order to prevent confusion, numbered (unnamed) backreferences are ignored. Use named groups instead.

<ProxyMatch "^http://(?<sitename>[^/]+)">
    Require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</ProxyMatch>

See also

top

ProxyMaxForwards Directive

Description:Maximum number of proxies that a request can be forwarded through
Syntax:ProxyMaxForwards number
Default:ProxyMaxForwards -1
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:Default behaviour changed in 2.2.7

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 may be set to prevent infinite proxy loops or a DoS attack.

Example

ProxyMaxForwards 15

Note that setting ProxyMaxForwards is a violation of the HTTP/1.1 protocol (RFC2616), which forbids a Proxy setting Max-Forwards if the Client didn't set it. Earlier Apache httpd versions would always set it. A negative ProxyMaxForwards value, including the default -1, gives you protocol-compliant behavior but may leave you open to loops.

top

ProxyPass Directive

Description:Maps remote servers into the local server URL-space
Syntax:ProxyPass [path] !|url [key=value [key=value ...]] [nocanon] [interpolate] [noquery]
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy
Compatibility:Unix Domain Socket (UDS) support added in 2.4.7

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. The local server is often called a reverse proxy or gateway. The path is the name of a local virtual path; url is a partial URL for the remote server and cannot include a query string.

It is strongly suggested to review the concept of a Worker before proceeding any further with this section.
This directive is not supported within <Directory>, <If> and <Files> containers.
The ProxyRequests directive should usually be set off when using ProxyPass.

In 2.4.7 and later, support for using a Unix Domain Socket is available by using a target which prepends unix:/path/lis.sock|. For example, to proxy HTTP and target the UDS at /home/www.socket, you would use unix:/home/www.socket|http://localhost/whatever/.

Note: The path associated with the unix: URL is DefaultRuntimeDir aware.

When used inside a <Location> section, the first argument is omitted and the local directory is obtained from the <Location>. The same will occur inside a <LocationMatch> section; however, ProxyPass does not interpret the regexp as such, so it is necessary to use ProxyPassMatch in this situation instead.

Suppose the local server has address http://example.com/; then

<Location "/mirror/foo/">
    ProxyPass "http://backend.example.com/"
</Location>

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.

If you require a more flexible reverse-proxy configuration, see the RewriteRule directive with the [P] flag.

The following alternative syntax is possible; however, it can carry a performance penalty when present in very large numbers. The advantage of the below syntax is that it allows for dynamic control via the Balancer Manager interface:

ProxyPass "/mirror/foo/" "http://backend.example.com/"

If the first argument ends with a trailing /, the second argument should also end with a trailing /, and vice versa. Otherwise, the resulting requests to the backend may miss some needed slashes and do not deliver the expected results.

The ! directive is useful in situations where you don't want to reverse-proxy a subdirectory, e.g.

<Location "/mirror/foo/">
    ProxyPass "http://backend.example.com/"
</Location>
<Location "/mirror/foo/i">
    ProxyPass "!"
</Location>
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.

Mixing ProxyPass settings in different contexts does not work:

ProxyPass "/mirror/foo/i" "!"
<Location "/mirror/foo/">
    ProxyPass "http://backend.example.com/"
</Location>

In this case, a request to /mirror/foo/i will get proxied, because the ProxyPass directive in the Location block will be evaluated first. The fact that ProxyPass supports both server and directory contexts does not mean that their scope and position in the configuration file will guarantee any ordering or override.

Ordering ProxyPass Directives

The configured ProxyPass and ProxyPassMatch rules are checked in the order of configuration. The first rule that matches wins. So usually you should sort conflicting ProxyPass rules starting with the longest URLs first. Otherwise, later rules for longer URLS will be hidden by any earlier rule which uses a leading substring of the URL. Note that there is some relation with worker sharing.

Ordering ProxyPass Directives in Locations

Only one ProxyPass directive can be placed in a Location block, and the most specific location will take precedence.

Exclusions and the no-proxy environment variable

Exclusions must come before the general ProxyPass directives. In 2.4.26 and later, the "no-proxy" environment variable is an alternative to exclusions, and is the only way to configure an exclusion of a ProxyPass directive in Location context. This variable should be set with SetEnvIf, as SetEnv is not evaluated early enough.

ProxyPass key=value Parameters

In Apache HTTP Server 2.1 and later, mod_proxy supports pooled connections to a backend server. Connections created on demand can be retained in a pool for future use. Limits on the pool size and other settings can be coded on the ProxyPass directive using key=value parameters, described in the tables below.

Maximum connections to the backend

By default, mod_proxy will allow and retain the maximum number of connections that could be used simultaneously by that web server child process. Use the max parameter to reduce the number from the default. The pool of connections is maintained per web server child process, and max and other settings are not coordinated among all child processes, except when only one child process is allowed by configuration or MPM design.

Use the ttl parameter to set an optional time to live; connections which have been unused for at least ttl seconds will be closed. ttl can be used to avoid using a connection which is subject to closing because of the backend server's keep-alive timeout.

Example

ProxyPass "/example" "http://backend.example.com" max=20 ttl=120 retry=300
Worker|BalancerMember parameters
Parameter Default Description
min 0 Minimum number of connection pool entries, unrelated to the actual number of connections. This only needs to be modified from the default for special circumstances where heap memory associated with the backend connections should be preallocated or retained.
max 1...n Maximum number of connections that will be allowed to the backend server. The default for this limit is the number of threads per process in the active MPM. In the Prefork MPM, this is always 1, while with other MPMs, it is controlled by the ThreadsPerChild directive.
smax max Retained connection pool entries above this limit are freed during certain operations if they have been unused for longer than the time to live, controlled by the ttl parameter. If the connection pool entry has an associated connection, it will be closed. This only needs to be modified from the default for special circumstances where connection pool entries and any associated connections which have exceeded the time to live need to be freed or closed more aggressively.
acquire - If set, this will be the maximum time to wait for a free connection in the connection pool, in milliseconds. If there are no free connections in the pool, the Apache httpd will return SERVER_BUSY status to the client.
connectiontimeout timeout Connect timeout in seconds. The number of seconds Apache httpd waits for the creation of a connection to the backend to complete. By adding a postfix of ms, the timeout can be also set in milliseconds.
disablereuse Off This parameter should be used when you want to force mod_proxy to immediately close a connection to the backend after being used, and thus, disable its persistent connection and pool for that backend. This helps in various situations where a firewall between Apache httpd and the backend server (regardless of protocol) tends to silently drop connections or when backends themselves may be under round- robin DNS. When connection reuse is enabled each backend domain is resolved (with a DNS query) only once per child process and cached for all further connections until the child is recycled. To disable connection reuse, set this property value to On.
enablereuse On This is the inverse of 'disablereuse' above, provided as a convenience for scheme handlers that require opt-in for connection reuse (such as mod_proxy_fcgi). 2.4.11 and later only.
flushpackets off Determines whether the proxy module will auto-flush the output brigade after each "chunk" of data. 'off' means that it will flush only when needed; 'on' means after each chunk is sent; and 'auto' means poll/wait for a period of time and flush if no input has been received for 'flushwait' milliseconds. Currently, this is in effect only for mod_proxy_ajp and mod_proxy_fcgi.
flushwait 10 The time to wait for additional input, in milliseconds, before flushing the output brigade if 'flushpackets' is 'auto'.
iobuffersize 8192 Adjusts the size of the internal scratchpad IO buffer. This allows you to override the ProxyIOBufferSize for a specific worker. This must be at least 512 or set to 0 for the system default of 8192.
responsefieldsize 8192 Adjust the size of the proxy response field buffer. The buffer size should be at least the size of the largest expected header size from a proxied response. Setting the value to 0 will use the system default of 8192 bytes.
Available in Apache HTTP Server 2.4.34 and later.
keepalive Off

This parameter should be used when you have a firewall between your Apache httpd and the backend server, which tends to drop inactive connections. This flag will tell the Operating System to send KEEP_ALIVE messages on inactive connections and thus prevent the firewall from dropping the connection. To enable keepalive, set this property value to On.

The frequency of initial and subsequent TCP keepalive probes depends on global OS settings, and may be as high as 2 hours. To be useful, the frequency configured in the OS must be smaller than the threshold used by the firewall.

lbset 0 Sets the load balancer cluster set that the worker is a member of. The load balancer will try all members of a lower numbered lbset before trying higher numbered ones.
ping 0 Ping property tells the webserver to "test" the connection to the backend before forwarding the request. For AJP, it causes mod_proxy_ajp to send a CPING request on the ajp13 connection (implemented on Tomcat 3.3.2+, 4.1.28+ and 5.0.13+). For HTTP, it causes mod_proxy_http to send a 100-Continue to the backend (only valid for HTTP/1.1 - for non HTTP/1.1 backends, this property has no effect). In both cases, the parameter is the delay in seconds to wait for the reply. This feature has been added to avoid problems with hung and busy backends. This will increase the network traffic during the normal operation which could be an issue, but it will lower the traffic in case some of the cluster nodes are down or busy. By adding a postfix of ms, the delay can be also set in milliseconds.
receivebuffersize 0 Adjusts the size of the explicit (TCP/IP) network buffer size for proxied connections. This allows you to override the ProxyReceiveBufferSize for a specific worker. This must be at least 512 or set to 0 for the system default.
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 parameter equal to this value.
retry 60 Connection pool worker retry timeout in seconds. If the connection pool worker to the backend server is in the error state, Apache httpd 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. A value of 0 means always retry workers in an error state with no timeout.
route - Route of the worker when used inside load balancer. The route is a value appended to session id.
status - Single letter value defining the initial status of this worker.
D: Worker is disabled and will not accept any requests.
S: Worker is administratively stopped.
I: Worker is in ignore-errors mode and will always be considered available.
R: Worker is a hot spare. For each worker in a given lbset that is unusable (draining, stopped, in error, etc.), a usable hot spare with the same lbset will be used in its place. Hot spares can help ensure that a specific number of workers are always available for use by a balancer.
H: Worker is in hot-standby mode and will only be used if no other viable workers or spares are available in the balancer set.
E: Worker is in an error state.
N: Worker is in drain mode and will only accept existing sticky sessions destined for itself and ignore all other requests.
Status can be set (which is the default) by prepending with '+' or cleared by prepending with '-'. Thus, a setting of 'S-E' sets this worker to Stopped and clears the in-error flag.
timeout ProxyTimeout Socket timeout in seconds. The number of seconds Apache httpd waits for data sent by / to the backend.
ttl - Time to live for inactive connections and associated connection pool entries, in seconds. Once reaching this limit, a connection will not be used again; it will be closed at some later time.
flusher flush

Name of the provider used by mod_proxy_fdpass. See the documentation of this module for more details.

secret - Value of secret used by mod_proxy_ajp. It must be identical to the secret configured on the server side of the AJP connection.
Available in Apache HTTP Server 2.4.42 and later.
upgrade -

Protocol accepted by mod_proxy_http or mod_proxy_wstunnel for the HTTP Upgrade mechanism upon negotiation by the HTTP client/browser (per RFC 9110 - Upgrade). See the Protocol Upgrade note below

mapping -

Type of mapping between the path and the url. This determines the normalization and/or (non-)decoding that mod_proxy will apply to the requested uri-path before matching the path. If a mapping matches, it's committed to the uri-path such that all the directory contexts that use a path (like <Location>) will be matched using the same mapping.

mapping=encoded prevents the %-decoding of the uri-path so that one can use for instance configurations like:

ProxyPass "/special%3Fsegment" "https://example.com/special%3Fsegment" mapping=encoded
<Location "/special%3Fsegment">
  Require ip 172.17.2.0/24
</Location>

mapping=servlet refers to the normalization defined by the Servlet specification, which is for instance applied by Apache Tomcat for servlet containers (notably the path parameters are ignored for the mapping). An uri-path like /some;foo/path is then mapped as /some/path hence matches any of the below regardless of the requested path parameters:

ProxyPass "/some/path" "https://servlet.example.com/some/path" mapping=servlet
<Location "/some/path">
  Require valid-user
</Location>

Note

It is recommended to use the same mapping on the Apache httpd side than the one used on the backend side. For instance when configuring authorizations in <Location> blocks for paths that are mapped by mod_proxy to some servlet containers (like applications running on Apache Tomcat), one should use the mapping=servlet setting to prevent path parameters and alike from interfering with the authorizations that are to be enforced in by the Apache httpd.

addressttl -1

TTL in seconds for how long DNS resolutions of the backend address are cached. -1 means until restart of Apache httpd.

If the Proxy directive scheme starts with the balancer:// (eg: balancer://cluster, any path information is ignored), 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 added to this virtual worker. See mod_proxy_balancer for more information about how the balancer works.

Balancer parameters
Parameter Default Description
lbmethod byrequests Balancer load-balance method. Select the load-balancing scheduler method to use. Either byrequests, to perform weighted request counting; bytraffic, to perform weighted traffic byte count balancing; or bybusyness, to perform pending request balancing. The default is byrequests.
maxattempts One less than the number of workers, or 1 with a single worker. Maximum number of failover attempts before giving up.
nofailover Off If 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.
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. If the backend application server uses different name for cookies and url encoded id (like servlet containers) use | to separate them. The first part is for the cookie the second for the path.
Available in Apache HTTP Server 2.4.4 and later.
stickysessionsep "." Sets the separation symbol in the session cookie. Some backend application servers do not use the '.' as the symbol. For example, the Oracle Weblogic server uses '!'. The correct symbol can be set using this option. The setting of 'Off' signifies that no symbol is used.
scolonpathdelim Off If set to On, the semi-colon character ';' will be used as an additional sticky session path delimiter/separator. This is mainly used to emulate mod_jk's behavior when dealing with paths such as JSESSIONID=6736bcf34;foo=aabfa
timeout 0 Balancer timeout in seconds. If set, this will be the maximum time to wait for a free worker. The default is to not wait.
failonstatus - A single or comma-separated list of HTTP status codes. If set, this will force the worker into error state when the backend returns any status code in the list. Worker recovery behaves the same as other worker errors.
failontimeout Off If set, an IO read timeout after a request is sent to the backend will force the worker into error state. Worker recovery behaves the same as other worker errors.
Available in Apache HTTP Server 2.4.5 and later.
nonce <auto> The protective nonce used in the balancer-manager application page. The default is to use an automatically determined UUID-based nonce, to provide for further protection for the page. If set, then the nonce is set to that value. A setting of None disables all nonce checking.

Note

In addition to the nonce, the balancer-manager page should be protected via an ACL.

growth 0 Number of additional BalancerMembers to allow to be added to this balancer in addition to those defined at configuration.
forcerecovery On Force the immediate recovery of all workers without considering the retry parameter of the workers if all workers of a balancer are in error state. There might be cases where an already overloaded backend can get into deeper trouble if the recovery of all workers is enforced without considering the retry parameter of each worker. In this case, set to Off.
Available in Apache HTTP Server 2.4.2 and later.

A sample balancer setup:

ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On
<Proxy "balancer://mycluster">
    BalancerMember "ajp://1.2.3.4:8009"
    BalancerMember "ajp://1.2.3.5:8009" loadfactor=20
    # Less powerful server, don't send as many requests there,
    BalancerMember "ajp://1.2.3.6:8009" loadfactor=5
</Proxy>

Configuring hot spares can help ensure that a certain number of workers are always available for use per load balancer set:

ProxyPass "/" "balancer://sparecluster/"
<Proxy balancer://sparecluster>
    BalancerMember ajp://1.2.3.4:8009
    BalancerMember ajp://1.2.3.5:8009
    # The servers below are hot spares. For each server above that is unusable
    # (draining, stopped, unreachable, in error state, etc.), one of these spares
    # will be used in its place. Two servers will always be available for a request
    # unless one or more of the spares is also unusable.
    BalancerMember ajp://1.2.3.6:8009 status=+R
    BalancerMember ajp://1.2.3.7:8009 status=+R
</Proxy>

Setting up a hot-standby that will only be used if no other members (or spares) are available in the load balancer set:

ProxyPass "/" "balancer://hotcluster/"
<Proxy "balancer://hotcluster">
    BalancerMember "ajp://1.2.3.4:8009" loadfactor=1
    BalancerMember "ajp://1.2.3.5:8009" loadfactor=2.25
    # The server below is on hot standby
    BalancerMember "ajp://1.2.3.6:8009" status=+H
    ProxySet lbmethod=bytraffic
</Proxy>

Additional ProxyPass Keywords

Normally, mod_proxy will canonicalise ProxyPassed URLs. But this may be incompatible with some backends, particularly those that make use of PATH_INFO. The optional nocanon keyword suppresses this and passes the URL path "raw" to the backend. Note that this keyword may affect the security of your backend, as it removes the normal limited protection against URL-based attacks provided by the proxy.

Normally, mod_proxy will include the query string when generating the SCRIPT_FILENAME environment variable. The optional noquery keyword (available in httpd 2.4.1 and later) prevents this.

The optional interpolate keyword, in combination with ProxyPassInterpolateEnv, causes the ProxyPass to interpolate environment variables, using the syntax ${VARNAME}. Note that many of the standard CGI-derived environment variables will not exist when this interpolation happens, so you may still have to resort to mod_rewrite for complex rules. Also note that interpolation is supported within the scheme/hostname/port portion of a URL only for variables that are available when the directive is parsed (like Define). Dynamic determination of those fields can be accomplished with mod_rewrite. The following example describes how to use mod_rewrite to dynamically set the scheme to http or https:

RewriteEngine On

RewriteCond "%{HTTPS}" =off
RewriteRule "." "-" [E=protocol:http]
RewriteCond "%{HTTPS}" =on
RewriteRule "." "-" [E=protocol:https]

RewriteRule "^/mirror/foo/(.*)" "%{ENV:protocol}://backend.example.com/$1" [P]
ProxyPassReverse  "/mirror/foo/" "http://backend.example.com/"
ProxyPassReverse  "/mirror/foo/" "https://backend.example.com/"

Protocol Upgrade

Since Apache HTTP Server 2.4.47, protocol Upgrade (tunneling) can be handled end-to-end by mod_proxy_http using the ProxyPass parameter upgrade.

End-to-end means that the HTTP Upgrade request from the client/browser is first forwarded by mod_proxy_http to the origin server and the connection will be upgraded (and tunneled by mod_proxy_http) only if the origin server accepts/initiates the upgrade (HTTP response 101 Switching Protocols). If the origin server responds with anything else mod_proxy_http will continue forwarding (and enforcing) the HTTP protocol as usual for this connection.

See Websocket Upgrade (2.4.47 and later) for an example of configuration using mod_proxy_http.

For Apache HTTP Server 2.4.46 and earlier (or if ProxyWebsocketFallbackToProxyHttp from 2.4.48 and later disables mod_proxy_http handling), see the documentation of mod_proxy_wstunnel for how to proxy the WebSocket protocol.

top

ProxyPassInherit Directive

Description:Inherit ProxyPass directives defined from the main server
Syntax:ProxyPassInherit On|Off
Default:ProxyPassInherit On
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:ProxyPassInherit is only available in Apache HTTP Server 2.4.5 and later.

This directive will cause the current server/vhost to "inherit" ProxyPass directives defined in the main server. This can cause issues and inconsistent behavior if using the Balancer Manager for dynamic changes and so should be disabled if using that feature.

The setting in the global server defines the default for all vhosts.

Disabling ProxyPassInherit also disables BalancerInherit.

top

ProxyPassInterpolateEnv Directive

Description:Enable Environment Variable interpolation in Reverse Proxy configurations
Syntax:ProxyPassInterpolateEnv On|Off
Default:ProxyPassInterpolateEnv Off
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy
Compatibility:Available in httpd 2.2.9 and later

This directive, together with the interpolate argument to ProxyPass, ProxyPassReverse, ProxyPassReverseCookieDomain, and ProxyPassReverseCookiePath, enables reverse proxies to be dynamically configured using environment variables which may be set by another module such as mod_rewrite. It affects the ProxyPass, ProxyPassReverse, ProxyPassReverseCookieDomain, and ProxyPassReverseCookiePath directives and causes them to substitute the value of an environment variable varname for the string ${varname} in configuration directives if the interpolate option is set.

The scheme/hostname/port portion of ProxyPass may contain variables, but only the ones available when the directive is parsed (for example, using Define). For all the other use cases, please consider using mod_rewrite instead.

Performance warning

Keep this turned off unless you need it! Adding variables to ProxyPass for example may lead to the use of the default mod_proxy's workers configured (that don't allow any fine tuning like connections reuse, etc..).

top

ProxyPassMatch Directive

Description:Maps remote servers into the local server URL-space using regular expressions
Syntax:ProxyPassMatch [regex] !|url [key=value [key=value ...]]
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy
Compatibility:Since 2.4.47 the key=value Parameters are honored when the url parameter contains backreference(s) (see note below).

This directive is equivalent to ProxyPass but makes use of regular expressions instead of simple prefix matching. The supplied regular expression is matched against the url, and if it matches, the server will substitute any parenthesized matches into the given string and use it as a new url.

Note: This directive cannot be used within a <Directory> context.

Suppose the local server has address http://example.com/; then

ProxyPassMatch "^/(.*\.gif)$" "http://backend.example.com/$1"

will cause a local request for http://example.com/foo/bar.gif to be internally converted into a proxy request to http://backend.example.com/foo/bar.gif.

The ! directive is useful in situations where you don't want to reverse-proxy a subdirectory.

When used inside a <LocationMatch> section, the first argument is omitted and the regexp is obtained from the <LocationMatch>.

If you require a more flexible reverse-proxy configuration, see the RewriteRule directive with the [P] flag.

Default Substitution

When the URL parameter doesn't use any backreferences into the regular expression, the original URL will be appended to the URL parameter.

key=value Parameters versus url with backreference(s)

Since Apache HTTP Server 2.4.47, the key=value Parameters are no longer ignored in a ProxyPassMatch using an url with backreference(s). However to keep the existing behavior regarding reuse/keepalive of backend connections (which were never reused before for these URLs), the parameter enablereuse (or disablereuse) default to off (resp. on) in this case. Setting enablereuse=on explicitely allows to reuse connections unless some backreference(s) belong in the authority part (hostname and/or port) of the url (this condition is enforced since Apache HTTP Server 2.4.55, and produces a warning at startup because these URLs are not reusable per se).

Security Warning

Take care when constructing the target URL of the rule, considering the security impact from allowing the client influence over the set of URLs to which your server will act as a proxy. Ensure that the scheme and hostname part of the URL is either fixed or does not allow the client undue influence.

top

ProxyPassReverse Directive

Description:Adjusts the URL in HTTP response headers sent from a reverse proxied server
Syntax:ProxyPassReverse [path] url [interpolate]
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy

This directive lets Apache httpd adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses. This is essential when Apache httpd is used as a reverse proxy (or gateway) to avoid bypassing 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 httpd will not rewrite other response headers, nor will it by default rewrite URL references inside HTML pages. This means that if the proxied content contains absolute URL references, they will bypass the proxy. To rewrite HTML content to match the proxy, you must load and enable mod_proxy_html.

path is the name of a local virtual path; url is a partial URL for the remote server. These parameters are used the same way as 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 which ProxyPass provides here). It also takes care of redirects which the server backend.example.com sends when redirecting http://backend.example.com/bar to http://backend.example.com/quux . Apache httpd 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 feature (RewriteRule ... [P]) from mod_rewrite because it doesn't depend on a corresponding ProxyPass directive.

The optional interpolate keyword, used together with ProxyPassInterpolateEnv, enables interpolation of environment variables specified using the format ${VARNAME}. Note that interpolation is not supported within the scheme portion of a URL.

When used inside a <Location> section, the first argument is omitted and the local directory is obtained from the <Location>. The same occurs inside a <LocationMatch> section, but will probably not work as intended, as ProxyPassReverse will interpret the regexp literally as a path; if needed in this situation, specify the ProxyPassReverse outside the section or in a separate <Location> section.

This directive is not supported in <Directory> or <Files> sections.

top

ProxyPassReverseCookieDomain Directive

Description:Adjusts the Domain string in Set-Cookie headers from a reverse- proxied server
Syntax:ProxyPassReverseCookieDomain internal-domain public-domain [interpolate]
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 [interpolate]
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy

Useful in conjunction with ProxyPassReverse in situations where backend URL paths are mapped to public paths on the reverse proxy. This directive rewrites the path string in Set-Cookie headers. If the beginning of the cookie path matches internal-path, the cookie path will be replaced with public-path.

In the example given with ProxyPassReverse, the directive:

ProxyPassReverseCookiePath  "/"  "/mirror/foo/"

will rewrite a cookie with backend path / (or /example or, in fact, anything) to /mirror/foo/.

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, directory
Status:Extension
Module:mod_proxy
Compatibility:Usable in directory context in 2.3.3 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 [username:password]
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:The optional third argument is usable only in httpd 2.4.59 and later.

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 and https are supported by this module. When using https, the requests are forwarded through the remote proxy using the HTTP CONNECT method.

Example

ProxyRemote "http://goodguys.example.com/" "http://mirrorguys.example.com:8000"
ProxyRemote "*" "http://cleverproxy.localdomain"
ProxyRemote "ftp" "http://ftpproxy.mydomain: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.

An optional third argument username:password may be given, which defines the Basic authentication credentials to pass to the configured remote proxy. The credentials will always be sent without first waiting for the remote proxy to send a Basic authentication challenge. The Proxy-Chain-Auth environment variable has no effect if this argument is used.

top

ProxyRemoteMatch Directive

Description:Remote proxy used to handle requests matched by regular expressions
Syntax:ProxyRemoteMatch regex remote-server [username:password]
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:The optional third argument is usable only in httpd 2.4.59 and later.

The ProxyRemoteMatch is identical to the ProxyRemote directive, except that 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 httpd from functioning as a forward proxy server. (Setting ProxyRequests to Off does not disable use of the ProxyPass directive.)

In a typical reverse proxy or gateway 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.

In order to get the functionality of (forward) proxying HTTPS sites, you need mod_proxy_connect enabled 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.

See also

top

ProxySet Directive

Description:Set various Proxy balancer or member parameters
Syntax:ProxySet url key=value [key=value ...]
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy
Compatibility:ProxySet is only available in Apache HTTP Server 2.2 and later.

This directive is used as an alternate method of setting any of the parameters available to Proxy balancers and workers normally done via the ProxyPass directive. If used within a <Proxy balancer url|worker url> container directive, the url argument is not required. As a side effect the respective balancer or worker gets created. This can be useful when doing reverse proxying via a RewriteRule instead of a ProxyPass directive.

<Proxy "balancer://hotcluster">
    BalancerMember "http://www2.example.com:8080" loadfactor=1
    BalancerMember "http://www3.example.com:8080" loadfactor=2
    ProxySet lbmethod=bytraffic
</Proxy>
<Proxy "http://backend">
    ProxySet keepalive=On
</Proxy>
ProxySet "balancer://foo" lbmethod=bytraffic timeout=15
ProxySet "ajp://backend:7001" timeout=15

Warning

Keep in mind that the same parameter key can have a different meaning depending whether it is applied to a balancer or a worker, as shown by the two examples above regarding timeout.

top

ProxySourceAddress Directive

Description:Set local IP address for outgoing proxy connections
Syntax:ProxySourceAddress address
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:Available in version 2.3.9 and later

This directive allows to set a specific local address to bind to when connecting to a backend server.

top

ProxyStatus Directive

Description:Show Proxy LoadBalancer status in mod_status
Syntax:ProxyStatus Off|On|Full
Default:ProxyStatus Off
Context:server config, virtual host
Status:Extension
Module:mod_proxy
Compatibility:Available in version 2.2 and later

This directive determines whether or not proxy loadbalancer status data is displayed via the mod_status server-status page.

Note

Full is synonymous with On

top

ProxyTimeout Directive

Description:Network timeout for proxied requests
Syntax:ProxyTimeout seconds
Default:Value of Timeout
Context:server config, virtual host
Status:Extension
Module:mod_proxy

This directive allows a user to specify 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.

Available Languages:  en  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_connect.html.en0000664000175100017510000002406614737542416022653 0ustar covenercovener mod_proxy_connect - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_connect

Available Languages:  en  |  fr  |  ja 

Description:mod_proxy extension for CONNECT request handling
Status:Extension
Module Identifier:proxy_connect_module
Source File:mod_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.

CONNECT is also used when the server needs to send an HTTPS request through a forward proxy. In this case the server acts as a CONNECT client. This functionality is part of mod_proxy and mod_proxy_connect is not needed in this case.

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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Request notes

mod_proxy_connect creates the following request notes for logging using the %{VARNAME}n format in LogFormat or ErrorLogFormat:

proxy-source-port
The local port used for the connection to the backend server.
top

AllowCONNECT Directive

Description:Ports that are allowed to CONNECT through the proxy
Syntax:AllowCONNECT port[-port] [port[-port]] ...
Default:AllowCONNECT 443 563
Context:server config, virtual host
Status:Extension
Module:mod_proxy_connect
Compatibility:Moved from mod_proxy in Apache 2.3.5. Port ranges available since Apache 2.3.7.

The AllowCONNECT directive specifies a list of port numbers or ranges 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.

Available Languages:  en  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_fdpass.html.en0000664000175100017510000001677114737542416022506 0ustar covenercovener mod_proxy_fdpass - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_fdpass

Available Languages:  en  |  fr 

Description:fdpass external process support module for mod_proxy
Status:Extension
Module Identifier:proxy_fdpass_module
Source File:mod_proxy_fdpass.c
Compatibility:Available for unix in version 2.3 and later

Summary

This module requires the service of mod_proxy. It provides support for the passing the socket of the client to another process.

mod_proxy_fdpass uses the ability of AF_UNIX domain sockets to pass an open file descriptor to allow another process to finish handling a request.

The module has a proxy_fdpass_flusher provider interface, which allows another module to optionally send the response headers, or even the start of the response body. The default flush provider disables keep-alive, and sends the response headers, letting the external process just send a response body.

In order to use another provider, you have to set the flusher parameter in the ProxyPass directive.

At this time the only data passed to the external process is the client socket. To receive a client socket, call recvfrom with an allocated struct cmsghdr. Future versions of this module may include more data after the client socket, but this is not implemented at this time.

Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_html.html.en0000664000175100017510000010316214737542416022161 0ustar covenercovener mod_proxy_html - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_html

Available Languages:  en  |  fr 

Description:Rewrite HTML links in to ensure they are addressable from Clients' networks in a proxy context.
Status:Base
Module Identifier:proxy_html_module
Source File:mod_proxy_html.c
Compatibility:Version 2.4 and later. Available as a third-party module for earlier 2.x versions

Summary

This module provides an output filter to rewrite HTML links in a proxy situation, to ensure that links work for users outside the proxy. It serves the same purpose as Apache's ProxyPassReverse directive does for HTTP headers, and is an essential component of a reverse proxy.

For example, if a company has an application server at appserver.example.com that is only visible from within the company's internal network, and a public webserver www.example.com, they may wish to provide a gateway to the application server at http://www.example.com/appserver/. When the application server links to itself, those links need to be rewritten to work through the gateway. mod_proxy_html serves to rewrite <a href="http://appserver.example.com/foo/bar.html">foobar</a> to <a href="http://www.example.com/appserver/foo/bar.html">foobar</a> making it accessible from outside.

mod_proxy_html was originally developed at WebÞing, whose extensive documentation may be useful to users.

Support Apache!

Directives

Bugfix checklist

See also

top

ProxyHTMLBufSize Directive

Description:Sets the buffer size increment for buffering inline scripts and stylesheets.
Syntax:ProxyHTMLBufSize bytes
Default:ProxyHTMLBufSize 8192
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

In order to parse non-HTML content (stylesheets and scripts) embedded in HTML documents, mod_proxy_html has to read the entire script or stylesheet into a buffer. This buffer will be expanded as necessary to hold the largest script or stylesheet in a page, in increments of bytes as set by this directive.

The default is 8192, and will work well for almost all pages. However, if you know you're proxying pages containing stylesheets and/or scripts bigger than 8K (that is, for a single script or stylesheet, NOT in total), it will be more efficient to set a larger buffer size and avoid the need to resize the buffer dynamically during a request.

top

ProxyHTMLCharsetOut Directive

Description:Specify a charset for mod_proxy_html output.
Syntax:ProxyHTMLCharsetOut Charset | *
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

This selects an encoding for mod_proxy_html output. It should not normally be used, as any change from the default UTF-8 (Unicode - as used internally by libxml2) will impose an additional processing overhead. The special token ProxyHTMLCharsetOut * will generate output using the same encoding as the input.

Note that this relies on mod_xml2enc being loaded.

top

ProxyHTMLDocType Directive

Description:Sets an HTML or XHTML document type declaration.
Syntax:ProxyHTMLDocType HTML|XHTML [Legacy]
OR
ProxyHTMLDocType fpi [SGML|XML]
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

In the first form, documents will be declared as HTML 4.01 or XHTML 1.0 according to the option selected. This option also determines whether HTML or XHTML syntax is used for output. Note that the format of the documents coming from the backend server is immaterial: the parser will deal with it automatically. If the optional second argument is set to Legacy, documents will be declared "Transitional", an option that may be necessary if you are proxying pre-1998 content or working with defective authoring/publishing tools.

In the second form, it will insert your own FPI. The optional second argument determines whether SGML/HTML or XML/XHTML syntax will be used.

The default is changed to omitting any FPI, on the grounds that no FPI is better than a bogus one. If your backend generates decent HTML or XHTML, set it accordingly.

If the first form is used, mod_proxy_html will also clean up the HTML to the specified standard. It cannot fix every error, but it will strip out bogus elements and attributes. It will also optionally log other errors at LogLevel Debug.

top

ProxyHTMLEnable Directive

Description:Turns the proxy_html filter on or off.
Syntax:ProxyHTMLEnable On|Off
Default:ProxyHTMLEnable Off
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party module for earlier 2.x versions.

A simple switch to enable or disable the proxy_html filter. If mod_xml2enc is loaded it will also automatically set up internationalisation support.

Note that the proxy_html filter will only act on HTML data (Content-Type text/html or application/xhtml+xml) and when the data are proxied. You can override this (at your own risk) by setting the PROXY_HTML_FORCE environment variable.

top

ProxyHTMLEvents Directive

Description:Specify attributes to treat as scripting events.
Syntax:ProxyHTMLEvents attribute [attribute ...]
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

Specifies one or more attributes to treat as scripting events and apply ProxyHTMLURLMaps to where enabled. You can specify any number of attributes in one or more ProxyHTMLEvents directives.

Normally you'll set this globally. If you set ProxyHTMLEvents in more than one scope so that one overrides the other, you'll need to specify a complete set in each of those scopes.

A default configuration is supplied in proxy-html.conf and defines the events in standard HTML 4 and XHTML 1.

top

ProxyHTMLExtended Directive

Description:Determines whether to fix links in inline scripts, stylesheets, and scripting events.
Syntax:ProxyHTMLExtended On|Off
Default:ProxyHTMLExtended Off
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

Set to Off, HTML links are rewritten according to the ProxyHTMLURLMap directives, but links appearing in Javascript and CSS are ignored.

Set to On, all scripting events (as determined by ProxyHTMLEvents) and embedded scripts or stylesheets are also processed by the ProxyHTMLURLMap rules, according to the flags set for each rule. Since this requires more parsing, performance will be best if you only enable it when strictly necessary.

You'll also need to take care over patterns matched, since the parser has no knowledge of what is a URL within an embedded script or stylesheet. In particular, extended matching of / is likely to lead to false matches.

top

ProxyHTMLFixups Directive

Description:Fixes for simple HTML errors.
Syntax:ProxyHTMLFixups [lowercase] [dospath] [reset]
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

This directive takes one to three arguments as follows:

Take care when using these. The fixes will correct certain authoring mistakes, but risk also erroneously fixing links that were correct to start with. Only use them if you know you have a broken backend server.

top

ProxyHTMLInterp Directive

Description:Enables per-request interpolation of ProxyHTMLURLMap rules.
Syntax:ProxyHTMLInterp On|Off
Default:ProxyHTMLInterp Off
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party module for earlier 2.x versions

This enables per-request interpolation in ProxyHTMLURLMap to- and from- patterns.

If interpolation is not enabled, all rules are pre-compiled at startup. With interpolation, they must be re-compiled for every request, which implies an extra processing overhead. It should therefore be enabled only when necessary.

top

ProxyHTMLLinks Directive

Description:Specify HTML elements that have URL attributes to be rewritten.
Syntax:ProxyHTMLLinks element attribute [attribute2 ...]
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

Specifies elements that have URL attributes that should be rewritten using standard ProxyHTMLURLMaps. You will need one ProxyHTMLLinks directive per element, but it can have any number of attributes.

Normally you'll set this globally. If you set ProxyHTMLLinks in more than one scope so that one overrides the other, you'll need to specify a complete set in each of those scopes.

A default configuration is supplied in proxy-html.conf and defines the HTML links for standard HTML 4 and XHTML 1.

Examples from proxy-html.conf

ProxyHTMLLinks  a          href
ProxyHTMLLinks  area       href
ProxyHTMLLinks  link       href
ProxyHTMLLinks  img        src longdesc usemap
ProxyHTMLLinks  object     classid codebase data usemap
ProxyHTMLLinks  q          cite
ProxyHTMLLinks  blockquote cite
ProxyHTMLLinks  ins        cite
ProxyHTMLLinks  del        cite
ProxyHTMLLinks  form       action
ProxyHTMLLinks  input      src usemap
ProxyHTMLLinks  head       profile
ProxyHTMLLinks  base       href
ProxyHTMLLinks  script     src for
top

ProxyHTMLMeta Directive

Description:Turns on or off extra pre-parsing of metadata in HTML <head> sections.
Syntax:ProxyHTMLMeta On|Off
Default:ProxyHTMLMeta Off
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party module for earlier 2.x versions.

This turns on or off pre-parsing of metadata in HTML <head> sections.

If not required, turning ProxyHTMLMeta Off will give a small performance boost by skipping this parse step. However, it is sometimes necessary for internationalisation to work correctly.

ProxyHTMLMeta has two effects. Firstly and most importantly it enables detection of character encodings declared in the form

<meta http-equiv="Content-Type" content="text/html;charset=foo">

or, in the case of an XHTML document, an XML declaration. It is NOT required if the charset is declared in a real HTTP header (which is always preferable) from the backend server, nor if the document is utf-8 (unicode) or a subset such as ASCII. You may also be able to dispense with it where documents use a default declared using xml2EncDefault, but that risks propagating an incorrect declaration. A ProxyHTMLCharsetOut can remove that risk, but is likely to be a bigger processing overhead than enabling ProxyHTMLMeta.

The other effect of enabling ProxyHTMLMeta is to parse all <meta http-equiv=...> declarations and convert them to real HTTP headers, in keeping with the original purpose of this form of the HTML <meta> element.

Warning

Because ProxyHTMLMeta promotes all http-equiv elements to HTTP headers, it is important that you only enable it in cases where you trust the HTML content as much as you trust the upstream server. If the HTML is controlled by bad actors, it will be possible for them to inject arbitrary, possibly malicious, HTTP headers into your server's responses.
top

ProxyHTMLStripComments Directive

Description:Determines whether to strip HTML comments.
Syntax:ProxyHTMLStripComments On|Off
Default:ProxyHTMLStripComments Off
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party for earlier 2.x versions

This directive will cause mod_proxy_html to strip HTML comments. Note that this will also kill off any scripts or styles embedded in comments (a bogosity introduced in 1995/6 with Netscape 2 for the benefit of then-older browsers, but still in use today). It may also interfere with comment-based processors such as SSI or ESI: be sure to run any of those before mod_proxy_html in the filter chain if stripping comments!

top

ProxyHTMLURLMap Directive

Description:Defines a rule to rewrite HTML links
Syntax:ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]
Context:server config, virtual host, directory
Status:Base
Module:mod_proxy_html
Compatibility:Version 2.4 and later; available as a third-party module for earlier 2.x versions.

This is the key directive for rewriting HTML links. When parsing a document, whenever a link target matches from-pattern, the matching portion will be rewritten to to-pattern, as modified by any flags supplied and by the ProxyHTMLExtended directive. Only the elements specified using the ProxyHTMLLinks directive will be considered as HTML links.

The optional third argument may define any of the following Flags. Flags are case-sensitive.

h

Ignore HTML links (pass through unchanged)

e

Ignore scripting events (pass through unchanged)

c

Pass embedded script and style sections through untouched.

L

Last-match. If this rule matches, no more rules are applied (note that this happens automatically for HTML links).

l

Opposite to L. Overrides the one-change-only default behaviour with HTML links.

R

Use Regular Expression matching-and-replace. from-pattern is a regexp, and to-pattern a replacement string that may be based on the regexp. Regexp memory is supported: you can use brackets () in the from-pattern and retrieve the matches with $1 to $9 in the to-pattern.

If R is not set, it will use string-literal search-and-replace. The logic is starts-with in HTML links, but contains in scripting events and embedded script and style sections.

x

Use POSIX extended Regular Expressions. Only applicable with R.

i

Case-insensitive matching. Only applicable with R.

n

Disable regexp memory (for speed). Only applicable with R.

s

Line-based regexp matching. Only applicable with R.

^

Match at start only. This applies only to string matching (not regexps) and is irrelevant to HTML links.

$

Match at end only. This applies only to string matching (not regexps) and is irrelevant to HTML links.

V

Interpolate environment variables in to-pattern. A string of the form ${varname|default} will be replaced by the value of environment variable varname. If that is unset, it is replaced by default. The |default is optional.

NOTE: interpolation will only be enabled if ProxyHTMLInterp is On.

v

Interpolate environment variables in from-pattern. Patterns supported are as above.

NOTE: interpolation will only be enabled if ProxyHTMLInterp is On.

The optional fourth cond argument defines a condition that will be evaluated per Request, provided ProxyHTMLInterp is On. If the condition evaluates FALSE the map will not be applied in this request. If TRUE, or if no condition is defined, the map is applied.

A cond is evaluated by the Expression Parser. In addition, the simpler syntax of conditions in mod_proxy_html 3.x for HTTPD 2.0 and 2.2 is also supported.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_proxy_scgi.html.en0000664000175100017510000003520414737542416022143 0ustar covenercovener mod_proxy_scgi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_proxy_scgi

Available Languages:  en  |  fr 

Description:SCGI gateway module for mod_proxy
Status:Extension
Module Identifier:proxy_scgi_module
Source File:mod_proxy_scgi.c
Compatibility:Available in version 2.2.14 and later

Summary

This module requires the service of mod_proxy. It provides support for the SCGI protocol, version 1.

Thus, in order to get the ability of handling the SCGI protocol, mod_proxy and mod_proxy_scgi 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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Examples

Remember, in order to make the following examples work, you have to enable mod_proxy and mod_proxy_scgi.

Simple gateway

ProxyPass "/scgi-bin/" "scgi://localhost:4000/"

The balanced gateway needs mod_proxy_balancer and at least one load balancer algorithm module, such as mod_lbmethod_byrequests, in addition to the proxy modules listed above. mod_lbmethod_byrequests is the default, and will be used for this example configuration.

Balanced gateway

ProxyPass "/scgi-bin/" "balancer://somecluster/"
<Proxy "balancer://somecluster">
    BalancerMember "scgi://localhost:4000"
    BalancerMember "scgi://localhost:4001"
</Proxy>
top

Environment Variables

In addition to the configuration directives that control the behaviour of mod_proxy, an environment variable may also control the SCGI protocol provider:

proxy-scgi-pathinfo
By default mod_proxy_scgi will neither create nor export the PATH_INFO environment variable. This allows the backend SCGI server to correctly determine SCRIPT_NAME and Script-URI and be compliant with RFC 3875 section 3.3. If instead you need mod_proxy_scgi to generate a "best guess" for PATH_INFO, set this env-var. The variable must be set before SetEnv is effective. SetEnvIf can be used instead: SetEnvIf Request_URI . proxy-scgi-pathinfo
top

ProxySCGIInternalRedirect Directive

Description:Enable or disable internal redirect responses from the backend
Syntax:ProxySCGIInternalRedirect On|Off|Headername
Default:ProxySCGIInternalRedirect On
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy_scgi
Compatibility:The Headername feature is available in version 2.4.13 and later

The ProxySCGIInternalRedirect enables the backend to internally redirect the gateway to a different URL. This feature originates in mod_cgi, which internally redirects the response if the response status is OK (200) and the response contains a Location (or configured alternate header) and its value starts with a slash (/). This value is interpreted as a new local URL that Apache httpd internally redirects to.

mod_proxy_scgi does the same as mod_cgi in this regard, except that you can turn off the feature or specify the use of a header other than Location.

Example

    ProxySCGIInternalRedirect Off

# Django and some other frameworks will fully qualify "local URLs"
# set by the application, so an alternate header must be used.
<Location /django-app/>
    ProxySCGIInternalRedirect X-Location
</Location>
top

ProxySCGISendfile Directive

Description:Enable evaluation of X-Sendfile pseudo response header
Syntax:ProxySCGISendfile On|Off|Headername
Default:ProxySCGISendfile Off
Context:server config, virtual host, directory
Status:Extension
Module:mod_proxy_scgi

The ProxySCGISendfile directive enables the SCGI backend to let files be served directly by the gateway. This is useful for performance purposes — httpd can use sendfile or other optimizations, which are not possible if the file comes over the backend socket. Additionally, the file contents are not transmitted twice.

The ProxySCGISendfile argument determines the gateway behaviour:

Off
No special handling takes place.
On
The gateway looks for a backend response header called X-Sendfile and interprets the value as the filename to serve. The header is removed from the final response headers. This is equivalent to ProxySCGISendfile X-Sendfile.
anything else
Similar to On, but instead of the hardcoded header name X-Sendfile, the argument is used as the header name.

Example

# Use the default header (X-Sendfile)
ProxySCGISendfile On

# Use a different header
ProxySCGISendfile X-Send-Static

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_ratelimit.html.en0000664000175100017510000001606314737542416021751 0ustar covenercovener mod_ratelimit - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_ratelimit

Available Languages:  en  |  fr 

Description:Bandwidth Rate Limiting for Clients
Status:Extension
Module Identifier:ratelimit_module
Source File:mod_ratelimit.c
Compatibility: rate-initial-burst available in httpd 2.4.24 and later. Rate limiting proxied content does not work correctly up to httpd 2.4.33.

Summary

Provides a filter named RATE_LIMIT to limit client bandwidth. The throttling is applied to each HTTP response while it is transferred to the client, and not aggregated at IP/client level. The connection speed to be simulated is specified, in KiB/s, using the environment variable rate-limit.

Optionally, an initial amount of burst data, in KiB, may be configured to be passed at full speed before throttling to the specified rate limit. This value is optional, and is set using the environment variable rate-initial-burst.

Example Configuration

<Location "/downloads">
    SetOutputFilter RATE_LIMIT
    SetEnv rate-limit 400 
    SetEnv rate-initial-burst 512
</Location>
If the value specified for rate-limit causes integer overflow, the rate-limited will be disabled. If the value specified for rate-limit-burst causes integer overflow, the burst will be disabled.
Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_reqtimeout.html.en0000664000175100017510000003140214737542416022147 0ustar covenercovener mod_reqtimeout - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_reqtimeout

Available Languages:  en  |  fr 

Description:Set timeout and minimum data rate for receiving requests
Status:Extension
Module Identifier:reqtimeout_module
Source File:mod_reqtimeout.c
Compatibility:Available in Apache HTTPD 2.2.15 and later

Summary

This module provides a convenient way to set timeouts and minimum data rates for receiving requests. Should a timeout occur or a data rate be to low, the corresponding connection will be closed by the server.

This is logged at LogLevel info.

If needed, the LogLevel directive can be tweaked to explicitly log it:

LogLevel reqtimeout:info
Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Examples

  1. Allow for 5 seconds to complete the TLS handshake, 10 seconds to receive the request headers and 30 seconds for receiving the request body:
    RequestReadTimeout handshake=5 header=10 body=30
  2. Allow at least 10 seconds to receive the request body. If the client sends data, increase the timeout by 1 second for every 1000 bytes received, with no upper limit for the timeout (except for the limit given indirectly by LimitRequestBody):
    RequestReadTimeout body=10,MinRate=1000
  3. Allow at least 10 seconds to receive the request headers. If the client sends data, increase the timeout by 1 second for every 500 bytes received. But do not allow more than 30 seconds for the request headers:
    RequestReadTimeout header=10-30,MinRate=500
  4. Usually, a server should have both header and body timeouts configured. If a common configuration is used for http and https virtual hosts, the timeouts should not be set too low:
    RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
top

RequestReadTimeout Directive

Description:Set timeout values for completing the TLS handshake, receiving the request headers and/or body from client.
Syntax:RequestReadTimeout [handshake=timeout[-maxtimeout][,MinRate=rate] [header=timeout[-maxtimeout][,MinRate=rate] [body=timeout[-maxtimeout][,MinRate=rate]
Default:RequestReadTimeout handshake=0 header=20-40,MinRate=500 body=20,MinRate=500
Context:server config, virtual host
Status:Extension
Module:mod_reqtimeout
Compatibility:Available in version 2.2.15 and later; defaulted to disabled in version 2.3.14 and earlier. The handshake stage is available since version 2.4.39.

This directive can set various timeouts for completing the TLS handshake, receiving the request headers and/or the request body from the client. If the client fails to complete each of these stages within the configured time, a 408 REQUEST TIME OUT error is sent.

For SSL virtual hosts, the handshake timeout values is the time needed to do the initial SSL handshake. If the user's browser is configured to query certificate revocation lists and the CRL server is not reachable, the initial SSL handshake may take a significant time until the browser gives up waiting for the CRL. Therefore the handshake timeout should take this possible overhead into consideration for SSL virtual hosts (if necessary). The body timeout values include the time needed for SSL renegotiation (if necessary).

When an AcceptFilter is in use (usually the case on Linux and FreeBSD), the socket is not sent to the server process before at least one byte (or the whole request for httpready) is received. The handshake and header timeouts configured with RequestReadTimeout are only effective after the server process has received the socket.

For each of the three timeout stages (handshake, header or body), there are three ways to specify the timeout:

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_sed.html.en0000664000175100017510000002726314737542416020536 0ustar covenercovener mod_sed - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_sed

Available Languages:  en  |  fr 

Description:Filter Input (request) and Output (response) content using sed syntax
Status:Experimental
Module Identifier:sed_module
Source File:mod_sed.c sed0.c sed1.c regexp.c regexp.h sed.h
Compatibility:Available in Apache 2.3 and later

Summary

mod_sed is an in-process content filter. The mod_sed filter implements the sed editing commands implemented by the Solaris 10 sed program as described in the manual page. However, unlike sed, mod_sed doesn't take data from standard input. Instead, the filter acts on the entity data sent between client and server. mod_sed can be used as an input or output filter. mod_sed is a content filter, which means that it cannot be used to modify client or server http headers.

The mod_sed output filter accepts a chunk of data, executes the sed scripts on the data, and generates the output which is passed to the next filter in the chain.

The mod_sed input filter reads the data from the next filter in the chain, executes the sed scripts, and returns the generated data to the caller filter in the filter chain.

Both the input and output filters only process the data if newline characters are seen in the content. At the end of the data, the rest of the data is treated as the last line. Lines greater than 8MB in length result in an error, in 2.4.54 and later.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Sample Configuration

Adding an output filter

# In the following example, the sed filter will change the string
# "monday" to "MON" and the string "sunday" to SUN in html documents
# before sending to the client.
<Directory "/var/www/docs/sed"> 
    AddOutputFilter Sed html 
    OutputSed "s/monday/MON/g" 
    OutputSed "s/sunday/SUN/g" 
</Directory>

Adding an input filter

# In the following example, the sed filter will change the string
# "monday" to "MON" and the string "sunday" to SUN in the POST data
# sent to PHP.
<Directory "/var/www/docs/sed"> 
    AddInputFilter Sed php 
    InputSed "s/monday/MON/g" 
    InputSed "s/sunday/SUN/g" 
</Directory>
top

Sed Commands

Complete details of the sed command can be found from the sed manual page.

b
Branch to the label specified (similar to goto).
h
Copy the current line to the hold buffer.
H
Append the current line to the hold buffer.
g
Copy the hold buffer to the current line.
G
Append the hold buffer to the current line.
x
Swap the contents of the hold buffer and the current line.
top

InputSed Directive

Description:Sed command to filter request data (typically POST data)
Syntax:InputSed sed-command
Context:directory, .htaccess
Status:Experimental
Module:mod_sed

The InputSed directive specifies the sed command to execute on the request data e.g., POST data.

top

OutputSed Directive

Description:Sed command for filtering response content
Syntax:OutputSed sed-command
Context:directory, .htaccess
Status:Experimental
Module:mod_sed

The OutputSed directive specifies the sed command to execute on the response.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_rewrite.html.en0000664000175100017510000023627414737542416021450 0ustar covenercovener mod_rewrite - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_rewrite

Available Languages:  en  |  fr 

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

Summary

The mod_rewrite module uses a rule-based rewriting engine, based on a PCRE regular-expression parser, to rewrite requested URLs on the fly. By default, mod_rewrite maps a URL to a filesystem path. However, it can also be used to redirect one URL to another URL, or to invoke an internal proxy fetch.

mod_rewrite provides a flexible and powerful way to manipulate URLs using an unlimited number of rules. Each rule can have an unlimited number of attached rule conditions, to allow you to rewrite URL based on server variables, environment variables, HTTP headers, or time stamps.

mod_rewrite operates on the full URL path, including the path-info section. A rewrite rule can be invoked in httpd.conf or in .htaccess. The path generated by a rewrite rule can include a query string, or can lead to internal sub-processing, external request redirection, or internal proxy throughput.

Further details, discussion, and examples, are provided in the detailed mod_rewrite documentation.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Logging

mod_rewrite offers detailed logging of its actions at the trace1 to trace8 log levels. The log level can be set specifically for mod_rewrite using the LogLevel directive: Up to level debug, no actions are logged, while trace8 means that practically all actions are logged.

Using a high trace log level for mod_rewrite will slow down your Apache HTTP Server dramatically! Use a log level higher than trace2 only for debugging!

Example

LogLevel alert rewrite:trace3

RewriteLog

Those familiar with earlier versions of mod_rewrite will no doubt be looking for the RewriteLog and RewriteLogLevel directives. This functionality has been completely replaced by the new per-module logging configuration mentioned above.

To get just the mod_rewrite-specific log messages, pipe the log file through grep:

tail -f error_log|fgrep '[rewrite:'

top

RewriteBase Directive

Description:Sets the base URL for per-directory rewrites
Syntax:RewriteBase URL-path
Default:None
Context:directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_rewrite

The RewriteBase directive specifies the URL prefix to be used for per-directory (htaccess) RewriteRule directives that substitute a relative path.

This directive is required when you use a relative path in a substitution in per-directory (htaccess) context unless any of the following conditions are true:

In the example below, RewriteBase is necessary to avoid rewriting to http://example.com/opt/myapp-1.2.3/welcome.html since the resource was not relative to the document root. This misconfiguration would normally cause the server to look for an "opt" directory under the document root.

DocumentRoot "/var/www/example.com"
AliasMatch "^/myapp" "/opt/myapp-1.2.3"
<Directory "/opt/myapp-1.2.3">
    RewriteEngine On
    RewriteBase "/myapp/"
    RewriteRule "^index\.html$"  "welcome.html"
</Directory>
top

RewriteCond Directive

Description:Defines a condition under which rewriting will take place
Syntax: RewriteCond TestString CondPattern [flags]
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_rewrite

The RewriteCond directive defines a rule condition. One or more RewriteCond can precede a RewriteRule directive. The following rule is then only used if both the current state of the URI matches its pattern, and if these conditions are met.

TestString is a string which can contain the following expanded constructs in addition to plain text:

If the TestString has the special value expr, the CondPattern will be treated as an ap_expr. HTTP headers referenced in the expression will be added to the Vary header if the novary flag is not given.

Other things you should be aware of:

  1. The variables SCRIPT_FILENAME and REQUEST_FILENAME contain the same value - the value of the filename field of the internal request_rec structure of the Apache HTTP Server. The first name is the commonly known CGI variable name while the second is the appropriate counterpart of REQUEST_URI (which contains the value of the uri field of request_rec).

    If a substitution occurred and the rewriting continues, the value of both variables will be updated accordingly.

    If used in per-server context (i.e., before the request is mapped to the filesystem) SCRIPT_FILENAME and REQUEST_FILENAME cannot contain the full local filesystem path since the path is unknown at this stage of processing. Both variables will initially contain the value of REQUEST_URI in that case. In order to obtain the full local filesystem path of the request in per-server context, use an URL-based look-ahead %{LA-U:REQUEST_FILENAME} to determine the final value of REQUEST_FILENAME.

  2. %{ENV:variable}, where variable can be any environment variable, is also available. This is looked-up via internal Apache httpd structures and (if not found there) via getenv() from the Apache httpd server process.
  3. %{SSL:variable}, where variable is the name of an SSL environment variable, 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. These variables are available even without setting the StdEnvVars option of the SSLOptions directive.
  4. %{HTTP:header}, where header can be any HTTP MIME-header name, can always be used to obtain the value of a header sent in the HTTP request. Example: %{HTTP:Proxy-Connection} is the value of the HTTP header ``Proxy-Connection:''.

    If a HTTP header is used in a condition this header is added to the Vary header of the response in case the condition evaluates to true for the request. It is not added if the condition evaluates to false for the request. Adding the HTTP header to the Vary header of the response is needed for proper caching.

    It has to be kept in mind that conditions follow a short circuit logic in the case of the 'ornext|OR' flag so that certain conditions might not be evaluated at all.

  5. %{LA-U:variable} can be used for look-aheads which perform an internal (URL-based) sub-request to determine the final value of variable. This can be used to access variable for rewriting which is not available at the current stage, but will be set in a later phase.

    For instance, to rewrite according to the REMOTE_USER variable from within the per-server context (httpd.conf file) you must use %{LA-U:REMOTE_USER} - this variable is set by the authorization phases, which come after the URL translation phase (during which 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} in that context.

  6. %{LA-F:variable} can be used to perform 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.

CondPattern is the condition pattern, a regular expression which is applied to the current instance of the TestString. TestString is first evaluated, before being matched against CondPattern.

CondPattern is usually a perl compatible regular expression, but there is additional syntax available to perform other useful tests against the Teststring:

  1. You can prefix the pattern string with a '!' character (exclamation mark) to negate the result of the condition, no matter what kind of CondPattern is used.
  2. You can perform lexicographical string comparisons:
    <CondPattern
    Lexicographically precedes
    Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString lexicographically precedes CondPattern.
    >CondPattern
    Lexicographically follows
    Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString lexicographically follows CondPattern.
    =CondPattern
    Lexicographically equal
    Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString is lexicographically equal to CondPattern (the two strings are exactly equal, character for character). If CondPattern is "" (two quotation marks) this compares TestString to the empty string.
    <=CondPattern
    Lexicographically less than or equal to
    Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString lexicographically precedes CondPattern, or is equal to CondPattern (the two strings are equal, character for character).
    >=CondPattern
    Lexicographically greater than or equal to
    Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString lexicographically follows CondPattern, or is equal to CondPattern (the two strings are equal, character for character).

    Note

    The string comparison operator is part of the CondPattern argument and must be included in the quotes if those are used. Eg.
    RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0"
  3. You can perform integer comparisons:
    -eq
    Is numerically equal to
    The TestString is treated as an integer, and is numerically compared to the CondPattern. True if the two are numerically equal.
    -ge
    Is numerically greater than or equal to
    The TestString is treated as an integer, and is numerically compared to the CondPattern. True if the TestString is numerically greater than or equal to the CondPattern.
    -gt
    Is numerically greater than
    The TestString is treated as an integer, and is numerically compared to the CondPattern. True if the TestString is numerically greater than the CondPattern.
    -le
    Is numerically less than or equal to
    The TestString is treated as an integer, and is numerically compared to the CondPattern. True if the TestString is numerically less than or equal to the CondPattern. Avoid confusion with the -l by using the -L or -h variant.
    -lt
    Is numerically less than
    The TestString is treated as an integer, and is numerically compared to the CondPattern. True if the TestString is numerically less than the CondPattern. Avoid confusion with the -l by using the -L or -h variant.
    -ne
    Is numerically not equal to
    The TestString is treated as an integer, and is numerically compared to the CondPattern. True if the two are numerically different. This is equivalent to !-eq.
  4. You can perform various file attribute tests:
    -d
    Is directory.
    Treats the TestString as a pathname and tests whether or not it exists, and is a directory.
    -f
    Is regular file.
    Treats the TestString as a pathname and tests whether or not it exists, and is a regular file.
    -F
    Is existing file, via subrequest.
    Checks whether or not TestString is a valid file, accessible via all the server's currently-configured access controls for that path. This uses an internal subrequest to do the check, so use it with care - it can impact your server's performance!
    -h
    Is symbolic link, bash convention.
    See -l.
    -l
    Is symbolic link.
    Treats the TestString as a pathname and tests whether or not it exists, and is a symbolic link. May also use the bash convention of -L or -h if there's a possibility of confusion such as when using the -lt or -le tests.
    -L
    Is symbolic link, bash convention.
    See -l.
    -s
    Is regular file, with size.
    Treats the TestString as a pathname and tests whether or not it exists, and is a regular file with size greater than zero.
    -U

    Is existing URL, via subrequest.
    Checks whether or not TestString is a valid URL, accessible via all the server's currently-configured access controls for that path. This uses an internal subrequest to do the check, so use it with care - it can impact your server's performance!

    This flag only returns information about things like access control, authentication, and authorization. This flag does not return information about the status code the configured handler (static file, CGI, proxy, etc.) would have returned.

    -x
    Has executable permissions.
    Treats the TestString as a pathname and tests whether or not it exists, and has executable permissions. These permissions are determined according to the underlying OS.
    For example:
    RewriteCond /var/www/%{REQUEST_URI} !-f
    RewriteRule ^(.+) /other/archive/$1 [R]
  5. If the TestString has the special value expr, the CondPattern will be treated as an ap_expr.

    In the below example, -strmatch is used to compare the REFERER against the site hostname, to block unwanted hotlinking.

    RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
    RewriteRule "^/images" "-" [F]

You can also set special flags for CondPattern by appending [flags] as the third argument to the RewriteCond directive, where flags is a comma-separated list of any of the following flags:

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}"  "(iPhone|Blackberry|Android)"
RewriteRule  "^/$"                 "/homepage.mobile.html"  [L]

RewriteRule  "^/$"                 "/homepage.std.html"     [L]

Explanation: If you use a browser which identifies itself as a mobile browser (note that the example is incomplete, as there are many other mobile platforms), the mobile version of the homepage is served. Otherwise, the standard page is served.

By default, multiple RewriteConds are evaluated in sequence with an implied logical AND. If a condition fails, in the absence of an OR flag, the entire ruleset is abandoned, and further conditions are not evaluated.

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 rules in a particular context, rather than commenting out all the RewriteRule directives.

Note that rewrite configurations are not inherited by virtual hosts. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.

RewriteMap directives of the type prg are not started during server initialization if they're defined in a context that does not have RewriteEngine set to on

top

RewriteMap Directive

Description:Defines a mapping function for key-lookup
Syntax:RewriteMap MapName MapType:MapSource [MapTypeOptions]
Context:server config, virtual host
Status:Extension
Module:mod_rewrite
Compatibility:The 3rd parameter, MapTypeOptions, in only available from Apache 2.4.29 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. Empty values behave as if the key was absent, therefore it is not possible to distinguish between empty-valued keys and absent keys.

For example, you might define a RewriteMap as:

RewriteMap examplemap "txt:/path/to/file/map.txt"

You would then be able to use this map in a RewriteRule as follows:

RewriteRule "^/ex/(.*)" "${examplemap:$1}"

The meaning of the MapTypeOptions argument depends on particular MapType. See the Using RewriteMap for more information.

The following combinations for MapType and MapSource can be used:

txt
A plain text file containing space-separated key-value pairs, one per line. (Details ...)
rnd
Randomly selects an entry from a plain text file (Details ...)
dbm
Looks up an entry in a dbm file containing name, value pairs. Hash is constructed from a plain text file format using the httxt2dbm utility. (Details ...)
int
One of the four available internal functions provided by RewriteMap: toupper, tolower, escape or unescape. (Details ...)
prg
Calls an external program or script to process the rewriting. (Details ...)
dbd or fastdbd
A SQL SELECT statement to be performed to look up the rewrite target. (Details ...)

Further details, and numerous examples, may be found in the RewriteMap HowTo

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

The RewriteOptions directive sets some special options for the current per-server or per-directory configuration. The Option string can currently only be one of the following:

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 or <Directory> sections are inherited. The inherited rules are virtually copied to the section where this directive is being used. If used in combination with local rules, the inherited rules are copied behind the local rules. The position of this directive - below or above of local rules - has no influence on this behavior. If local rules forced the rewriting to stop, the inherited rules won't be processed.

Rules inherited from the parent scope are applied after rules specified in the child scope.
InheritBefore

Like Inherit above, but the rules from the parent scope are applied before rules specified in the child scope.
Available in Apache HTTP Server 2.3.10 and later.

InheritDown

If this option is enabled, all child configurations will inherit the configuration of the current configuration. It is equivalent to specifying RewriteOptions Inherit in all child configurations. See the Inherit option for more details on how the parent-child relationships are handled.
Available in Apache HTTP Server 2.4.8 and later.

InheritDownBefore

Like InheritDown above, but the rules from the current scope are applied before rules specified in any child's scope.
Available in Apache HTTP Server 2.4.8 and later.

IgnoreInherit

This option forces the current and child configurations to ignore all rules that would be inherited from a parent specifying InheritDown or InheritDownBefore.
Available in Apache HTTP Server 2.4.8 and later.

AllowNoSlash

By default, mod_rewrite will ignore URLs that map to a directory on disk but lack a trailing slash, in the expectation that the mod_dir module will issue the client with a redirect to the canonical URL with a trailing slash.

When the DirectorySlash directive is set to off, the AllowNoSlash option can be enabled to ensure that rewrite rules are no longer ignored. This option makes it possible to apply rewrite rules within .htaccess files that match the directory without a trailing slash, if so desired.
Available in Apache HTTP Server 2.4.0 and later.

AllowAnyURI

When RewriteRule is used in VirtualHost or server context with version 2.2.22 or later of httpd, mod_rewrite will only process the rewrite rules if the request URI is a URL-path. This avoids some security issues where particular rules could allow "surprising" pattern expansions (see CVE-2011-3368 and CVE-2011-4317). To lift the restriction on matching a URL-path, the AllowAnyURI option can be enabled, and mod_rewrite will apply the rule set to any request URI string, regardless of whether that string matches the URL-path grammar required by the HTTP specification.
Available in Apache HTTP Server 2.4.3 and later.

Security Warning

Enabling this option will make the server vulnerable to security issues if used with rewrite rules which are not carefully authored. It is strongly recommended that this option is not used. In particular, beware of input strings containing the '@' character which could change the interpretation of the transformed URI, as per the above CVE names.

MergeBase

With this option, the value of RewriteBase is copied from where it's explicitly defined into any sub-directory or sub-location that doesn't define its own RewriteBase. This was the default behavior in 2.4.0 through 2.4.3, and the flag to restore it is available Apache HTTP Server 2.4.4 and later.

IgnoreContextInfo

When a relative substitution is made in directory (htaccess) context and RewriteBase has not been set, this module uses some extended URL and filesystem context information to change the relative substitution back into a URL. Modules such as mod_userdir and mod_alias supply this extended context info. Available in 2.4.16 and later.

LegacyPrefixDocRoot

Prior to 2.4.26, if a substitution was an absolute URL that matched the current virtual host, the URL might first be reduced to a URL-path and then later reduced to a local path. Since the URL can be reduced to a local path, the path should be prefixed with the document root. This prevents a file such as /tmp/myfile from being accessed when a request is made to http://host/file/myfile with the following RewriteRule.

RewriteRule /file/(.*) http://localhost/tmp/$1

This option allows the old behavior to be used where the document root is not prefixed to a local path that was reduced from a URL. Available in 2.4.26 and later.

top

RewriteRule Directive

Description:Defines rules for the rewriting engine
Syntax:RewriteRule Pattern Substitution [flags]
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_rewrite

The RewriteRule directive is the real rewriting workhorse. The directive can occur more than once, with each instance defining a single rewrite rule. The order in which these rules are defined is important - this is the order in which they will be applied at run-time.

Pattern is a perl compatible regular expression. What this pattern is compared against varies depending on where the RewriteRule directive is defined.

What is matched?

  • In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html"). This is the (%-decoded) URL-path.

  • In per-directory context (Directory and .htaccess), the Pattern is matched against only a partial path, for example a request of "/app1/index.html" may result in comparison against "app1/index.html" or "index.html" depending on where the RewriteRule is defined.

    The directory path where the rule is defined is stripped from the currently mapped filesystem path before comparison (up to and including a trailing slash). The net result of this per-directory prefix stripping is that rules in this context only match against the portion of the currently mapped filesystem path "below" where the rule is defined.

    Directives such as DocumentRoot and Alias, or even the result of previous RewriteRule substitutions, determine the currently mapped filesystem path.

  • If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.

Per-directory Rewrites

  • The rewrite engine may be used in .htaccess files and in <Directory> sections, with some additional complexity.
  • To enable the rewrite engine in this context, you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled. If your administrator has disabled override of FollowSymLinks for a user's directory, then you cannot use the rewrite engine. This restriction is required for security reasons.
  • See the RewriteBase directive for more information regarding what prefix will be added back to relative substitutions.
  • If you wish to match against the full URL-path in a per-directory (htaccess) RewriteRule, use the %{REQUEST_URI} variable in a RewriteCond.
  • The removed prefix always ends with a slash, meaning the matching occurs against a string which never has a leading slash. Therefore, a Pattern with ^/ never matches in per-directory context.
  • Although rewrite rules are syntactically permitted in <Location> and <Files> sections (including their regular expression counterparts), this should never be necessary and is unsupported. A likely feature to break in these contexts is relative substitutions.
  • The If blocks follow the rules of the directory context.
  • By default, mod_rewrite overrides rules when merging sections belonging to the same context. The RewriteOptions directive can change this behavior, for example using the Inherit setting.
  • The RewriteOptions also regulates the behavior of sections that are stated at the same nesting level of the configuration. In the following example, by default only the RewriteRules stated in the second If block are considered, since the first ones are overridden. Using RewriteOptions Inherit forces mod_rewrite to merge the two sections and consider both set of statements, rather than only the last one.
<If "true">
  # Without RewriteOptions Inherit, this rule is overridden by the next
  # section and no redirect will happen for URIs containing 'foo'
  RewriteRule foo http://example.com/foo [R]
</If>
<If "true">
  RewriteRule bar http://example.com/bar [R]
</If>

For some hints on regular expressions, see the mod_rewrite Introduction.

In mod_rewrite, the NOT character ('!') is also available as a possible pattern prefix. This enables you 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.

Note

When using the NOT character to negate a pattern, you cannot include grouped wildcard parts in that pattern. This is because, when the pattern does NOT match (ie, the negation matches), there are no contents for the groups. Thus, if negated patterns are used, you cannot use $N in the substitution string!

The Substitution of a rewrite rule is the string that replaces the original URL-path that was matched by Pattern. The Substitution may be a:

file-system path
Designates the location on the file-system of the resource to be delivered to the client. Substitutions are only treated as a file-system path when the rule is configured in server (virtualhost) context and the first component of the path in the substitution exists in the file-system
URL-path
A DocumentRoot-relative path to the resource to be served. Note that mod_rewrite tries to guess whether you have specified a file-system path or a URL-path by checking to see if the first segment of the path exists at the root of the file-system. For example, if you specify a Substitution string of /www/file.html, then this will be treated as a URL-path unless a directory named www exists at the root or your file-system (or, in the case of using rewrites in a .htaccess file, relative to your document root), in which case it will be treated as a file-system path. If you wish other URL-mapping directives (such as Alias) to be applied to the resulting URL-path, use the [PT] flag as described below.
Absolute URL

If an absolute URL is specified, mod_rewrite checks to see whether the hostname matches the current host. If it does, the scheme and hostname are stripped out and the resulting path is treated as a URL-path. Otherwise, an external redirect is performed for the given URL. To force an external redirect back to the current host, see the [R] flag below.

Note that a redirect (implicit or not) using an absolute URI will include the requested query-string, to prevent this see the [QSD] flag below.

- (dash)
A dash indicates that no substitution should be performed (the existing path is passed through untouched). This is used when a flag (see below) needs to be applied without changing the path.

In addition to plain text, the Substitution string can include

  1. back-references ($N) to the RewriteRule pattern
  2. back-references (%N) to the last matched RewriteCond pattern
  3. server-variables as in rule condition test-strings (%{VARNAME})
  4. mapping-function calls (${mapname:key|default})

Back-references are identifiers of the form $N (N=0..9), 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 above.

Rewrite rules are applied to the results of previous rewrite rules, in the order in which they are defined in the config file. The URL-path or file-system path (see "What is matched?", above) is completely replaced by the Substitution and the rewriting process continues until all rules have been applied, or it is explicitly terminated by an L flag, or other flag which implies immediate termination, such as END or F.

Modifying the Query String

By default, the query string is passed through unchanged. You can, however, create URLs in the substitution string containing a query string part. Simply use a question mark inside the substitution string to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine new and old query strings, use the [QSA] flag.

Additionally you can set special actions to be performed by appending [flags] as the third argument to the RewriteRule directive. Flags is a comma-separated list, surround by square brackets, of any of the flags in the following table. More details, and examples, for each flag, are available in the Rewrite Flags document.

Flag and syntax Function
B Escape non-alphanumeric characters in backreferences before applying the transformation. For similar escaping of server-variables, see the "escape" mapping-function.details ...
BCTLS Like [B], but only escape control characters and spaces. details ...
BNE Characters of [B] or [BCTLS] which should not be escaped. details ...
backrefnoplus|BNP If backreferences are being escaped, spaces should be escaped to %20 instead of +. Useful when the backreference will be used in the path component rather than the query string.details ...
chain|C Rule is chained to the following rule. If the rule fails, the rule(s) chained to it will be skipped. details ...
cookie|CO=NAME:VAL Sets a cookie in the client browser. Full syntax is: CO=NAME:VAL:domain[:lifetime[:path[:secure[:httponly[samesite]]]]] details ...
discardpath|DPI Causes the PATH_INFO portion of the rewritten URI to be discarded. details ...
END Stop the rewriting process immediately and don't apply any more rules. Also prevents further execution of rewrite rules in per-directory and .htaccess context. (Available in 2.3.9 and later) details ...
env|E=[!]VAR[:VAL] Causes an environment variable VAR to be set (to the value VAL if provided). The form !VAR causes the environment variable VAR to be unset. details ...
forbidden|F Returns a 403 FORBIDDEN response to the client browser. details ...
gone|G Returns a 410 GONE response to the client browser. details ...
Handler|H=Content-handler Causes the resulting URI to be sent to the specified Content-handler for processing. details ...
last|L Stop the rewriting process immediately and don't apply any more rules. Especially note caveats for per-directory and .htaccess context (see also the END flag). details ...
next|N Re-run the rewriting process, starting again with the first rule, using the result of the ruleset so far as a starting point. details ...
nocase|NC Makes the pattern comparison case-insensitive. details ...
noescape|NE Prevent mod_rewrite from applying hexcode escaping of special characters in the result of rewrites that result in redirection. details ...
nosubreq|NS Causes a rule to be skipped if the current request is an internal sub-request. details ...
proxy|P Force the substitution URL to be internally sent as a proxy request. details ...
passthrough|PT Forces the resulting URI to be passed back to the URL mapping engine for processing of other URI-to-filename translators, such as Alias or Redirect. details ...
qsappend|QSA Appends any query string from the original request URL to any query string created in the rewrite target.details ...
qsdiscard|QSD Discard any query string attached to the incoming URI. details ...
qslast|QSL Interpret the last (right-most) question mark as the query string delimiter, instead of the first (left-most) as normally used. Available in 2.4.19 and later. details ...
redirect|R[=code] Forces an external redirect, optionally with the specified HTTP status code. details ...
skip|S=num Tells the rewriting engine to skip the next num rules if the current rule matches. details ...
type|T=MIME-type Force the MIME-type of the target file to be the specified type. details ...
UnsafeAllow3F Allows substitutions from URL's that may be unsafe. details ...
UnsafePrefixStat Allows potentially unsafe substitutions from a leading variable or backreference to a filesystem path. details ...
Available in Apache HTTP Server 2.4.60 and later.
UNC Prevents the merging of multiple leading slashes, as used by Windows UNC paths. details ...
Available in Apache HTTP Server 2.4.62 and later.

Home directory expansion

When the substitution string begins with a string resembling "/~user" (via explicit text or backreferences), mod_rewrite performs home directory expansion independent of the presence or configuration of mod_userdir.

This expansion does not occur when the PT flag is used on the RewriteRule directive.

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 invalid, not supported
^/somepath(.*) otherpath$1 [R] invalid, not supported
^/somepath(.*) otherpath$1 [P] invalid, not supported
^/somepath(.*) /otherpath$1 /otherpath/pathinfo
^/somepath(.*) /otherpath$1 [R] http://thishost/otherpath/pathinfo via external redirection
^/somepath(.*) /otherpath$1 [P] doesn't make sense, not supported
^/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] doesn't make sense, not supported
^/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
(/physical/path/to/somepath/.htaccess, with 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] doesn't make sense, not supported
^localpath(.*) /otherpath$1 /otherpath/pathinfo
^localpath(.*) /otherpath$1 [R] http://thishost/otherpath/pathinfo via external redirection
^localpath(.*) /otherpath$1 [P] doesn't make sense, not supported
^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] doesn't make sense, not supported
^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

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session_cookie.html.en0000664000175100017510000003332414737542416022772 0ustar covenercovener mod_session_cookie - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_session_cookie

Available Languages:  en  |  fr 

Description:Cookie based session support
Status:Extension
Module Identifier:session_cookie_module
Source File:mod_session_cookie.c
Compatibility:Available in Apache 2.3 and later

Summary

Warning

The session modules make use of HTTP cookies, and as such can fall victim to Cross Site Scripting attacks, or expose potentially private information to clients. Please ensure that the relevant risks have been taken into account before enabling the session functionality on your server.

This submodule of mod_session provides support for the storage of user sessions on the remote browser within HTTP cookies.

Using cookies to store a session removes the need for the server or a group of servers to store the session locally, or collaborate to share a session, and can be useful for high traffic environments where a server based session might be too resource intensive.

If session privacy is required, the mod_session_crypto module can be used to encrypt the contents of the session before writing the session to the client.

For more details on the session interface, see the documentation for the mod_session module.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Basic Examples

To create a simple session and store it in a cookie called session, configure the session as follows:

Browser based session

Session On
SessionCookieName session path=/

For more examples on how the session can be configured to be read from and written to by a CGI application, see the mod_session examples section.

For documentation on how the session can be used to store username and password details, see the mod_auth_form module.

top

SessionCookieName Directive

Description:Name and attributes for the RFC2109 cookie storing the session
Syntax:SessionCookieName name attributes
Default:none
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_cookie

The SessionCookieName directive specifies the name and optional attributes of an RFC2109 compliant cookie inside which the session will be stored. RFC2109 cookies are set using the Set-Cookie HTTP header.

An optional list of cookie attributes can be specified, as per the example below. These attributes are inserted into the cookie as is, and are not interpreted by Apache. Ensure that your attributes are defined correctly as per the cookie specification.

Cookie with attributes

Session On
SessionCookieName session path=/private;domain=example.com;httponly;secure;version=1;
top

SessionCookieName2 Directive

Description:Name and attributes for the RFC2965 cookie storing the session
Syntax:SessionCookieName2 name attributes
Default:none
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_cookie

The SessionCookieName2 directive specifies the name and optional attributes of an RFC2965 compliant cookie inside which the session will be stored. RFC2965 cookies are set using the Set-Cookie2 HTTP header.

An optional list of cookie attributes can be specified, as per the example below. These attributes are inserted into the cookie as is, and are not interpreted by Apache. Ensure that your attributes are defined correctly as per the cookie specification.

Cookie2 with attributes

Session On
SessionCookieName2 session path=/private;domain=example.com;httponly;secure;version=1;
top

SessionCookieRemove Directive

Description:Control for whether session cookies should be removed from incoming HTTP headers
Syntax:SessionCookieRemove On|Off
Default:SessionCookieRemove Off
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_cookie

The SessionCookieRemove flag controls whether the cookies containing the session will be removed from the headers during request processing.

In a reverse proxy situation where the Apache server acts as a server frontend for a backend origin server, revealing the contents of the session cookie to the backend could be a potential privacy violation. When set to on, the session cookie will be removed from the incoming HTTP headers.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_setenvif.html.en0000664000175100017510000005261314737542416021603 0ustar covenercovener mod_setenvif - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_setenvif

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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 internal 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, as well as becoming available to CGI scripts and SSI pages.

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

When the server looks up a path via an internal subrequest such as looking for a DirectoryIndex or generating a directory listing with mod_autoindex, per-request environment variables are not inherited in the subrequest. Additionally, SetEnvIf directives are not separately evaluated in the subrequest due to the API phases mod_setenvif takes action in.

Support Apache!

Directives

Bugfix checklist

See also

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:

BrowserMatch Robot is_a_robot
SetEnvIf 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

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 four 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. 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. See the RewriteCond directive of mod_rewrite for extra information on how to match your query string.
  3. 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.

The second argument (regex) is a 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. !varname, or
  3. varname=value

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 httpd will recognize occurrences of $1..$9 within value and replace them by parenthesized subexpressions of regex. $0 provides access to the whole string matched by that pattern.

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\.example\.com intra_site_referral
    
SetEnvIf object_is_image xbm XBIT_PROCESSING=1
    
SetEnvIf Request_URI "\.(.*)$" EXTENSION=$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.example.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

SetEnvIfExpr Directive

Description:Sets environment variables based on an ap_expr expression
Syntax:SetEnvIfExpr expr [!]env-variable[=value] [[!]env-variable[=value]] ...
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Base
Module:mod_setenvif

The SetEnvIfExpr directive defines environment variables based on an expression. These expressions will be evaluated at runtime, and applied env-variable in the same fashion as SetEnvIf, including backreferences.

    SetEnvIfExpr "tolower(req('X-Sendfile')) == 'd:\images\very_big.iso')" iso_delivered
    SetEnvIfExpr "tolower(req('X-Sendfile')) =~ /(.*\.iso$)/" iso-path=$1

This would set the environment variable iso_delivered every time our application attempts to send it via X-Sendfile

A more useful example would be to set the variable rfc1918 if the remote IP address is a private address according to RFC 1918:

SetEnvIfExpr "-R '10.0.0.0/8' || -R '172.16.0.0/12' || -R '192.168.0.0/16'" rfc1918

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

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 Example\.Org site=example

This will cause the site environment variable to be set to "example" if the HTTP request header field Host: was included and contained Example.Org, example.org, or any other combination.

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_so.html.en0000664000175100017510000003324314737542416020377 0ustar covenercovener mod_so - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_so

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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 HTTP Server 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 be the .so or .dll extension.

Warning

Modules built for one major version of the Apache HTTP Server will generally not work on another. (e.g. 1.3 vs. 2.0, or 2.0 vs. 2.2) There are usually API changes between one major version and another that require that modules be modified to work with the new version.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Creating Loadable Modules for Windows

Note

On Windows, where loadable files typically have a file extension of .dll, Apache httpd modules are called mod_whatever.so, just as they are on other platforms. However, you may encounter third-party modules, such as PHP for example, that continue to use the .dll convention.

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 httpd 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 httpd for Windows does not have the Configure program of Apache httpd 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 httpd 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 httpd 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 httpd 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, virtual host
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, virtual host
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.

For example:

LoadModule status_module "modules/mod_status.so"

loads the named module from the modules subdirectory of the ServerRoot.

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_memcache.html.en0000664000175100017510000002123214737542416023200 0ustar covenercovener mod_socache_memcache - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_socache_memcache

Available Languages:  en  |  fr 

Description:Memcache based shared object cache provider.
Status:Extension
Module Identifier:socache_memcache_module
Source File:mod_socache_memcache.c

Summary

mod_socache_memcache is a shared object cache provider which provides for creation and access to a cache backed by the memcached high-performance, distributed memory object caching system.

This shared object cache provider's "create" method requires a comma separated list of memcached host/port specifications. If using this provider via another modules configuration (such as SSLSessionCache), provide the list of servers as the optional "arg" parameter.

SSLSessionCache memcache:memcache.example.com:12345,memcache2.example.com:12345

Details of other shared object cache providers can be found here.

Support Apache!

Directives

Bugfix checklist

See also

top

MemcacheConnTTL Directive

Description:Keepalive time for idle connections
Syntax:MemcacheConnTTL num[units]
Default:MemcacheConnTTL 15s
Context:server config, virtual host
Status:Extension
Module:mod_socache_memcache
Compatibility:Available in Apache 2.4.17 and later

Set the time to keep idle connections with the memcache server(s) alive (threaded platforms only).

Valid values for MemcacheConnTTL are times up to one hour. 0 means no timeout.

This timeout defaults to units of seconds, but accepts suffixes for milliseconds (ms), seconds (s), minutes (min), and hours (h).

Before Apache 2.4.17, this timeout was hardcoded and its value was 600 usec. So, the closest configuration to match the legacy behaviour is to set MemcacheConnTTL to 1ms.

# Set a timeout of 10 minutes
MemcacheConnTTL 10min
# Set a timeout of 60 seconds
MemcacheConnTTL 60

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_speling.html.en0000664000175100017510000003155714737542416021425 0ustar covenercovener mod_speling - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_speling

Available Languages:  en  |  fr  |  ja  |  ko 

Description:Attempts to correct mistaken URLs by ignoring capitalization, or attempting to correct various minor misspellings.
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. Erroneous extension can also be fixed by this module.

If, after scanning the directory,

Support Apache!

Directives

Bugfix checklist

See also

top

CheckBasenameMatch Directive

Description:Also match files with differing file name extensions.
Syntax:CheckBasenameMatch on|off
Default:CheckBasenameMatch On
Context:server config, virtual host, directory, .htaccess
Override:Options
Status:Extension
Module:mod_speling
Compatibility:Available in httpd 2.4.50 and later

When set, this directive extends the action of the spelling correction to the file name extension. For example a file foo.gif will match a request for foo or foo.jpg. This can be particularly useful in conjunction with MultiViews.

top

CheckCaseOnly Directive

Description:Limits the action of the speling module to case corrections
Syntax:CheckCaseOnly on|off
Default:CheckCaseOnly Off
Context:server config, virtual host, directory, .htaccess
Override:Options
Status:Extension
Module:mod_speling

When set, this directive limits the action of the spelling correction to lower/upper case changes. Other potential corrections are not performed, except when CheckBasenameMatch is also set.

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

This directive enables or disables the spelling module. When enabled, keep in mind that

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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session_dbd.html.en0000664000175100017510000006211214737542416022247 0ustar covenercovener mod_session_dbd - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_session_dbd

Available Languages:  en  |  fr 

Description:DBD/SQL based session support
Status:Extension
Module Identifier:session_dbd_module
Source File:mod_session_dbd.c
Compatibility:Available in Apache 2.3 and later

Summary

Warning

The session modules make use of HTTP cookies, and as such can fall victim to Cross Site Scripting attacks, or expose potentially private information to clients. Please ensure that the relevant risks have been taken into account before enabling the session functionality on your server.

This submodule of mod_session provides support for the storage of user sessions within a SQL database using the mod_dbd module.

Sessions can either be anonymous, where the session is keyed by a unique UUID string stored on the browser in a cookie, or per user, where the session is keyed against the userid of the logged in user.

SQL based sessions are hidden from the browser, and so offer a measure of privacy without the need for encryption.

Different webservers within a server farm may choose to share a database, and so share sessions with one another.

For more details on the session interface, see the documentation for the mod_session module.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

DBD Configuration

Before the mod_session_dbd module can be configured to maintain a session, the mod_dbd module must be configured to make the various database queries available to the server.

There are four queries required to keep a session maintained, to select an existing session, to update an existing session, to insert a new session, and to delete an expired or empty session. These queries are configured as per the example below.

Sample DBD configuration

DBDriver pgsql
DBDParams "dbname=apachesession user=apache password=xxxxx host=localhost"
DBDPrepareSQL "delete from session where key = %s" deletesession
DBDPrepareSQL "update session set value = %s, expiry = %lld, key = %s where key = %s" updatesession
DBDPrepareSQL "insert into session (value, expiry, key) values (%s, %lld, %s)" insertsession
DBDPrepareSQL "select value from session where key = %s and (expiry = 0 or expiry > %lld)" selectsession
DBDPrepareSQL "delete from session where expiry != 0 and expiry < %lld" cleansession
top

Anonymous Sessions

Anonymous sessions are keyed against a unique UUID, and stored on the browser within an HTTP cookie. This method is similar to that used by most application servers to store session information.

To create a simple anonymous session and store it in a postgres database table called apachesession, and save the session ID in a cookie called session, configure the session as follows:

SQL based anonymous session

Session On
SessionDBDCookieName session path=/

For more examples on how the session can be configured to be read from and written to by a CGI application, see the mod_session examples section.

For documentation on how the session can be used to store username and password details, see the mod_auth_form module.

top

Per User Sessions

Per user sessions are keyed against the username of a successfully authenticated user. It offers the most privacy, as no external handle to the session exists outside of the authenticated realm.

Per user sessions work within a correctly configured authenticated environment, be that using basic authentication, digest authentication or SSL client certificates. Due to the limitations of who came first, the chicken or the egg, per user sessions cannot be used to store authentication credentials from a module like mod_auth_form.

To create a simple per user session and store it in a postgres database table called apachesession, and with the session keyed to the userid, configure the session as follows:

SQL based per user session

Session On
SessionDBDPerUser On
top

Database Housekeeping

Over the course of time, the database can be expected to start accumulating expired sessions. At this point, the mod_session_dbd module is not yet able to handle session expiry automatically.

Warning

The administrator will need to set up an external process via cron to clean out expired sessions.

top

SessionDBDCookieName Directive

Description:Name and attributes for the RFC2109 cookie storing the session ID
Syntax:SessionDBDCookieName name attributes
Default:none
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDCookieName directive specifies the name and optional attributes of an RFC2109 compliant cookie inside which the session ID will be stored. RFC2109 cookies are set using the Set-Cookie HTTP header.

An optional list of cookie attributes can be specified, as per the example below. These attributes are inserted into the cookie as is, and are not interpreted by Apache. Ensure that your attributes are defined correctly as per the cookie specification.

Cookie with attributes

Session On
SessionDBDCookieName session path=/private;domain=example.com;httponly;secure;version=1;
top

SessionDBDCookieName2 Directive

Description:Name and attributes for the RFC2965 cookie storing the session ID
Syntax:SessionDBDCookieName2 name attributes
Default:none
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDCookieName2 directive specifies the name and optional attributes of an RFC2965 compliant cookie inside which the session ID will be stored. RFC2965 cookies are set using the Set-Cookie2 HTTP header.

An optional list of cookie attributes can be specified, as per the example below. These attributes are inserted into the cookie as is, and are not interpreted by Apache. Ensure that your attributes are defined correctly as per the cookie specification.

Cookie2 with attributes

Session On
SessionDBDCookieName2 session path=/private;domain=example.com;httponly;secure;version=1;
top

SessionDBDCookieRemove Directive

Description:Control for whether session ID cookies should be removed from incoming HTTP headers
Syntax:SessionDBDCookieRemove On|Off
Default:SessionDBDCookieRemove On
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDCookieRemove flag controls whether the cookies containing the session ID will be removed from the headers during request processing.

In a reverse proxy situation where the Apache server acts as a server frontend for a backend origin server, revealing the contents of the session ID cookie to the backend could be a potential privacy violation. When set to on, the session ID cookie will be removed from the incoming HTTP headers.

top

SessionDBDDeleteLabel Directive

Description:The SQL query to use to remove sessions from the database
Syntax:SessionDBDDeleteLabel label
Default:SessionDBDDeleteLabel deletesession
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDDeleteLabel directive sets the default delete query label to be used to delete an expired or empty session. This label must have been previously defined using the DBDPrepareSQL directive.

top

SessionDBDInsertLabel Directive

Description:The SQL query to use to insert sessions into the database
Syntax:SessionDBDInsertLabel label
Default:SessionDBDInsertLabel insertsession
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDInsertLabel directive sets the default insert query label to be used to load in a session. This label must have been previously defined using the DBDPrepareSQL directive.

If an attempt to update the session affects no rows, this query will be called to insert the session into the database.

top

SessionDBDPerUser Directive

Description:Enable a per user session
Syntax:SessionDBDPerUser On|Off
Default:SessionDBDPerUser Off
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDPerUser flag enables a per user session keyed against the user's login name. If the user is not logged in, this directive will be ignored.

top

SessionDBDSelectLabel Directive

Description:The SQL query to use to select sessions from the database
Syntax:SessionDBDSelectLabel label
Default:SessionDBDSelectLabel selectsession
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDSelectLabel directive sets the default select query label to be used to load in a session. This label must have been previously defined using the DBDPrepareSQL directive.

top

SessionDBDUpdateLabel Directive

Description:The SQL query to use to update existing sessions in the database
Syntax:SessionDBDUpdateLabel label
Default:SessionDBDUpdateLabel updatesession
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_session_dbd

The SessionDBDUpdateLabel directive sets the default update query label to be used to load in a session. This label must have been previously defined using the DBDPrepareSQL directive.

If an attempt to update the session affects no rows, the insert query will be called to insert the session into the database. If the database supports InsertOrUpdate, override this query to perform the update in one query instead of two.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_slotmem_shm.html.en0000664000175100017510000002131214737542416022277 0ustar covenercovener mod_slotmem_shm - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_slotmem_shm

Available Languages:  en  |  fr 

Description:Slot-based shared memory provider.
Status:Extension
Module Identifier:slotmem_shm_module
Source File:mod_slotmem_shm.c

Summary

mod_slotmem_shm is a memory provider which provides for creation and access to a shared memory segment in which the datasets are organized in "slots."

All shared memory is cleared and cleaned with each restart, whether graceful or not. The data itself is stored and restored within a file noted by the name parameter in the create and attach calls. If not specified with an absolute path, the file will be created relative to the path specified by the DefaultRuntimeDir directive.

mod_slotmem_shm provides the following API functions:

/* call the callback on all worker slots */
apr_status_t doall(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)

/* create a new slotmem with each item size is item_size. 'name' is used to generate a filename for the persistent
   store of the shared memory if configured. Values are:
      "none"                - Anonymous shared memory and no persistent store
      "file-name"           - [DefaultRuntimeDir]/file-name
      "/absolute-file-name" - Absolute file name */
apr_status_t create(ap_slotmem_instance_t **new, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool)

/* attach to an existing slotmem. See 'create()' for description of 'name' parameter */
apr_status_t attach(ap_slotmem_instance_t **new, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)

/* get the direct pointer to the memory associated with this worker slot */
apr_status_t dptr(ap_slotmem_instance_t *s, unsigned int item_id, void **mem)

/* get/read the memory from this slot to dest */
apr_status_t get(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len)

/* put/write the data from src to this slot */
apr_status_t put(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len)

/* return the total number of slots in the segment */
unsigned int num_slots(ap_slotmem_instance_t *s)

/* return the total data size, in bytes, of a slot in the segment */
apr_size_t slot_size(ap_slotmem_instance_t *s)

/* grab or allocate the first free slot and mark as in-use (does not do any data copying) */
apr_status_t grab(ap_slotmem_instance_t *s, unsigned int *item_id)

/* forced grab or allocate the specified slot and mark as in-use (does not do any data copying) */
apr_status_t fgrab(ap_slotmem_instance_t *s, unsigned int item_id)

/* release or free a slot and mark as not in-use (does not do any data copying) */
apr_status_t release(ap_slotmem_instance_t *s, unsigned int item_id)
Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_dc.html.en0000664000175100017510000001432314737542416022027 0ustar covenercovener mod_socache_dc - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_socache_dc

Available Languages:  en  |  fr 

Description:Distcache based shared object cache provider.
Status:Extension
Module Identifier:socache_dc_module
Source File:mod_socache_dc.c

Summary

mod_socache_dc is a shared object cache provider which provides for creation and access to a cache backed by the distcache distributed session caching libraries.

Details of other shared object cache providers can be found here.

Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_shmcb.html.en0000664000175100017510000001436514737542416022543 0ustar covenercovener mod_socache_shmcb - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_socache_shmcb

Available Languages:  en  |  fr 

Description:shmcb based shared object cache provider.
Status:Extension
Module Identifier:socache_shmcb_module
Source File:mod_socache_shmcb.c

Summary

mod_socache_shmcb is a shared object cache provider which provides for creation and access to a cache backed by a high-performance cyclic buffer inside a shared memory segment.

shmcb:/path/to/datafile(512000)

Details of other shared object cache providers can be found here.

Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_substitute.html.en0000664000175100017510000003517214737542416022174 0ustar covenercovener mod_substitute - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_substitute

Available Languages:  en  |  fr 

Description:Perform search and replace operations on response bodies
Status:Extension
Module Identifier:substitute_module
Source File:mod_substitute.c
Compatibility:Available in Apache HTTP Server 2.2.7 and later

Summary

mod_substitute provides a mechanism to perform both regular expression and fixed string substitutions on response bodies.

Support Apache!

Directives

Bugfix checklist

See also

top

Substitute Directive

Description:Pattern to filter the response content
Syntax:Substitute s/pattern/substitution/[infq]
Context:directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_substitute

The Substitute directive specifies a search and replace pattern to apply to the response body.

The meaning of the pattern can be modified by using any combination of these flags:

i
Perform a case-insensitive match.
n
By default the pattern is treated as a regular expression. Using the n flag forces the pattern to be treated as a fixed string.
f
The f flag causes mod_substitute to flatten the result of a substitution allowing for later substitutions to take place on the boundary of this one. This is the default.
q
The q flag causes mod_substitute to not flatten the buckets after each substitution. This can result in much faster response and a decrease in memory utilization, but should only be used if there is no possibility that the result of one substitution will ever match a pattern or regex of a subsequent one.

The substitution may contain literal text and regular expression backreferences

Example

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s/foo/bar/ni"
</Location>

The character which is used to separate (or "delimit") the various parts of the substitution string is referred to as the "delimiter", and it is most common to use a slash for this purpose.

If either the pattern or the substitution contain a slash character then an alternative delimiter may be used to make the directive more readable:

Example of using an alternate delimiter

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|<BR */?>|<br />|i"
</Location>

Backreferences can be used in the comparison and in the substitution, when regular expressions are used, as illustrated in the following example:

Example of using backreferences and captures

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    # "foo=k,bar=k" -> "foo/bar=k"
    Substitute "s|foo=(\w+),bar=\1|foo/bar=$1|"
</Location>

A common use scenario for mod_substitute is the situation in which a front-end server proxies requests to a back-end server which returns HTML with hard-coded embedded URLs that refer to the back-end server. These URLs don't work for the end-user, since the back-end server is unreachable.

In this case, mod_substitute can be used to rewrite those URLs into something that will work from the front end:

Rewriting URLs embedded in proxied content

ProxyPass        "/blog/" "http://internal.blog.example.com/"
ProxyPassReverse "/blog/" "http://internal.blog.example.com/"

Substitute "s|http://internal.blog.example.com/|http://www.example.com/blog/|i"

ProxyPassReverse modifies any Location (redirect) headers that are sent by the back-end server, and, in this example, Substitute takes care of the rest of the problem by fixing up the HTML response as well.

top

SubstituteInheritBefore Directive

Description:Change the merge order of inherited patterns
Syntax:SubstituteInheritBefore on|off
Default:SubstituteInheritBefore off
Context:directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_substitute
Compatibility:Available in httpd 2.4.17 and later

Whether to apply the inherited Substitute patterns first (on), or after the ones of the current context (off). SubstituteInheritBefore is itself inherited, hence contexts that inherit it (those that don't specify their own SubstituteInheritBefore value) will apply the closest defined merge order.

top

SubstituteMaxLineLength Directive

Description:Set the maximum line size
Syntax:SubstituteMaxLineLength bytes(b|B|k|K|m|M|g|G)
Default:SubstituteMaxLineLength 1m
Context:directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_substitute
Compatibility:Available in httpd 2.4.11 and later

The maximum line size handled by mod_substitute is limited to restrict memory use. The limit can be configured using SubstituteMaxLineLength. The value can be given as the number of bytes and can be suffixed with a single letter b, B, k, K, m, M, g, G to provide the size in bytes, kilobytes, megabytes or gigabytes respectively.

Example

<Location "/">
    AddOutputFilterByType SUBSTITUTE text/html
    SubstituteMaxLineLength 10m
    Substitute "s/foo/bar/ni"
</Location>

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_unique_id.html.en0000664000175100017510000003622014737542416021736 0ustar covenercovener mod_unique_id - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_unique_id

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

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

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. A httpd process can handle multiple requests simultaneously if you use a multi-threaded MPM. In order to identify threads, we use a thread index Apache httpd uses internally. 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 144-bit (32-bit IP address, 32 bit pid, 32 bit time stamp, 16 bit counter, 32 bit thread index) quadruple using the alphabet [A-Za-z0-9@-] in a manner similar to MIME base64 encoding, producing 24 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 any 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. 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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_suexec.html.en0000664000175100017510000002016014737542416021244 0ustar covenercovener mod_suexec - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_suexec

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

Description:Allows CGI scripts to run as a specified user and Group
Status:Extension
Module Identifier:suexec_module
Source File:mod_suexec.c

Summary

This module, in combination with the suexec support program allows CGI scripts to run as a specified user and Group.

Support Apache!

Directives

Bugfix checklist

See also

top

SuexecUserGroup Directive

Description:User and group for CGI programs to run as
Syntax:SuexecUserGroup User Group
Context:server config, virtual host
Status:Extension
Module:mod_suexec

The SuexecUserGroup directive allows you to specify a user and group for CGI programs to run as. Non-CGI requests are still processed with the user specified in the User directive.

Example

SuexecUserGroup nobody nogroup

Startup will fail if this directive is specified but the suEXEC feature is disabled.

See also

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_unixd.html.en0000664000175100017510000003321314737542416021102 0ustar covenercovener mod_unixd - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_unixd

Available Languages:  en  |  fr  |  tr 

Description:Basic (required) security for Unix-family platforms.
Status:Base
Module Identifier:unixd_module
Source File:mod_unixd.c
Support Apache!

Directives

Bugfix checklist

See also

top

ChrootDir Directive

Description:Directory for apache to run chroot(8) after startup.
Syntax:ChrootDir /path/to/directory
Default:none
Context:server config
Status:Base
Module:mod_unixd
Compatibility:Available in Apache 2.2.10 and later

This directive tells the server to chroot(8) to the specified directory after startup, but before accepting requests over the 'net.

Note that running the server under chroot is not simple, and requires additional setup, particularly if you are running scripts such as CGI or PHP. Please make sure you are properly familiar with the operation of chroot before attempting to use this feature.

top

Group Directive

Description:Group under which the server will answer requests
Syntax:Group unix-group
Default:Group #-1
Context:server config
Status:Base
Module:mod_unixd

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.

See also

top

Suexec Directive

Description:Enable or disable the suEXEC feature
Syntax:Suexec On|Off
Default:On if suexec binary exists with proper owner and mode, Off otherwise
Context:server config
Status:Base
Module:mod_unixd

When On, startup will fail if the suexec binary doesn't exist or has an invalid owner or file mode.

When Off, suEXEC will be disabled even if the suexec binary exists and has a valid owner and file mode.

top

User Directive

Description:The userid under which the server will answer requests
Syntax:User unix-userid
Default:User #-1
Context:server config
Status:Base
Module:mod_unixd

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.

See also

Available Languages:  en  |  fr  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_version.html.en0000664000175100017510000002452514737542416021446 0ustar covenercovener mod_version - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_version

Available Languages:  en  |  fr  |  ja  |  ko 

Description:Version dependent configuration
Status:Extension
Module Identifier:version_module
Source File:mod_version.c

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.4.2>
    # current httpd version is exactly 2.4.2
</IfVersion>

<IfVersion >= 2.5>
    # use really new features :-)
</IfVersion>

See below for further possibilities.

Support Apache!

Directives

Bugfix checklist

See also

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.3>
    # this happens only in versions greater or
    # equal 2.3.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.4.[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.4.[01234]$>
    # not for those versions
</IfVersion>

If the operator is omitted, it is assumed to be =.

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_xml2enc.html.en0000664000175100017510000003643414737542416021333 0ustar covenercovener mod_xml2enc - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_xml2enc

Available Languages:  en  |  fr 

Description:Enhanced charset/internationalisation support for libxml2-based filter modules
Status:Base
Module Identifier:xml2enc_module
Source File:mod_xml2enc.c
Compatibility:Version 2.4 and later. Available as a third-party module for 2.2.x versions

Summary

This module provides enhanced internationalisation support for markup-aware filter modules such as mod_proxy_html. It can automatically detect the encoding of input data and ensure they are correctly processed by the libxml2 parser, including converting to Unicode (UTF-8) where necessary. It can also convert data to an encoding of choice after markup processing, and will ensure the correct charset value is set in the HTTP Content-Type header.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Usage

There are two usage scenarios: with modules programmed to work with mod_xml2enc, and with those that are not aware of it:

Filter modules enabled for mod_xml2enc

Modules such as mod_proxy_html version 3.1 and up use the xml2enc_charset optional function to retrieve the charset argument to pass to the libxml2 parser, and may use the xml2enc_filter optional function to postprocess to another encoding. Using mod_xml2enc with an enabled module, no configuration is necessary: the other module will configure mod_xml2enc for you (though you may still want to customise it using the configuration directives below).

Non-enabled modules

To use it with a libxml2-based module that isn't explicitly enabled for mod_xml2enc, you will have to configure the filter chain yourself. So to use it with a filter foo provided by a module mod_foo to improve the latter's i18n support with HTML and XML, you could use


    FilterProvider iconv    xml2enc Content-Type $text/html
    FilterProvider iconv    xml2enc Content-Type $xml
    FilterProvider markup   foo Content-Type $text/html
    FilterProvider markup   foo Content-Type $xml
    FilterChain     iconv markup
    

mod_foo will now support any character set supported by either (or both) of libxml2 or apr_xlate/iconv.

top

Programming API

Programmers writing libxml2-based filter modules are encouraged to enable them for mod_xml2enc, to provide strong i18n support for your users without reinventing the wheel. The programming API is exposed in mod_xml2enc.h, and a usage example is mod_proxy_html.

top

Detecting an Encoding

Unlike mod_charset_lite, mod_xml2enc is designed to work with data whose encoding cannot be known in advance and thus configured. It therefore uses 'sniffing' techniques to detect the encoding of HTTP data as follows:

  1. If the HTTP Content-Type header includes a charset parameter, that is used.
  2. If the data start with an XML Byte Order Mark (BOM) or an XML encoding declaration, that is used.
  3. If an encoding is declared in an HTML <META> element, that is used.
  4. If none of the above match, the default value set by xml2EncDefault is used.

The rules are applied in order. As soon as a match is found, it is used and detection is stopped.

top

Output Encoding

libxml2 always uses UTF-8 (Unicode) internally, and libxml2-based filter modules will output that by default. mod_xml2enc can change the output encoding through the API, but there is currently no way to configure that directly.

Changing the output encoding should (in theory, at least) never be necessary, and is not recommended due to the extra processing load on the server of an unnecessary conversion.

top

Unsupported Encodings

If you are working with encodings that are not supported by any of the conversion methods available on your platform, you can still alias them to a supported encoding using xml2EncAlias.

top

xml2EncAlias Directive

Description:Recognise Aliases for encoding values
Syntax:xml2EncAlias charset alias [alias ...]
Context:server config
Status:Base
Module:mod_xml2enc

This server-wide directive aliases one or more encoding to another encoding. This enables encodings not recognised by libxml2 to be handled internally by libxml2's encoding support using the translation table for a recognised encoding. This serves two purposes: to support character sets (or names) not recognised either by libxml2 or iconv, and to skip conversion for an encoding where it is known to be unnecessary.

top

xml2EncDefault Directive

Description:Sets a default encoding to assume when absolutely no information can be automatically detected
Syntax:xml2EncDefault name
Context:server config, virtual host, directory, .htaccess
Status:Base
Module:mod_xml2enc

If you are processing data with known encoding but no encoding information, you can set this default to help mod_xml2enc process the data correctly. For example, to work with the default value of Latin1 (iso-8859-1) specified in HTTP/1.0, use:

xml2EncDefault iso-8859-1
top

xml2StartParse Directive

Description:Advise the parser to skip leading junk.
Syntax:xml2StartParse element [element ...]
Context:server config, virtual host, directory, .htaccess
Status:Base
Module:mod_xml2enc

Specify that the markup parser should start at the first instance of any of the elements specified. This can be used as a workaround where a broken backend inserts leading junk that messes up the parser (example here).

It should never be used for XML, nor well-formed HTML.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_usertrack.html.en0000664000175100017510000004727214737542416021770 0ustar covenercovener mod_usertrack - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_usertrack

Available Languages:  en  |  fr 

Description: Clickstream logging of user activity on a site
Status:Extension
Module Identifier:usertrack_module
Source File:mod_usertrack.c

Summary

Provides tracking of a user through your website via browser cookies.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Logging

mod_usertrack sets a cookie which can be logged via mod_log_config configurable logging formats:

LogFormat "%{Apache}n %r %t" usertrack
CustomLog "logs/clickstream.log" usertrack
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, .example.com is legal, but www.example.com and .com are not.

Most browsers in use today will not allow cookies to be set for a two-part top level domain, such as .co.uk, although such a domain ostensibly fulfills the requirements above.
These domains are equivalent to top level domains such as .com, and allowing such cookies may be a security risk. Thus, if you are under a two-part top level domain, you should still use your actual domain, as you would with any other top level domain (for example .example.co.uk).
CookieDomain .example.com
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.

CookieExpires "3 weeks"
top

CookieHTTPOnly Directive

Description:Adds the 'HTTPOnly' attribute to the cookie
Syntax:CookieHTTPOnly on|off
Default:CookieHTTPOnly off
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_usertrack
Compatibility:2.4.42 and later

When set to 'ON', the 'HTTPOnly' cookie attribute is added to this modules tracking cookie. This attribute instructs browsers to block javascript from reading the value of the cookie.

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

CookieName clicktrack
top

CookieSameSite Directive

Description:Adds the 'SameSite' attribute to the cookie
Syntax:CookieSameSite None|Lax|Strict
Default:unset
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_usertrack
Compatibility:2.4.42 and later

When set to 'None', 'Lax', or 'Strict', the 'SameSite' cookie attribute is added to this modules tracking cookie with the corresponding value. This attribute instructs browser on how to treat the cookie when it is requested in a cross-site context.

A value of 'None' sets 'SameSite=None', which is the most liberal setting. To omit this attribute, omit the directive entirely.

top

CookieSecure Directive

Description:Adds the 'Secure' attribute to the cookie
Syntax:CookieSecure on|off
Default:CookieSecure off
Context:server config, virtual host, directory, .htaccess
Override:FileInfo
Status:Extension
Module:mod_usertrack
Compatibility:2.4.42 and later

When set to 'ON', the 'Secure' cookie attribute is added to this modules tracking cookie. This attribute instructs browsers to only transmit the cookie over HTTPS.

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:

Not all clients can understand all of these formats, but you should use the newest one that is generally acceptable to your users' browsers. At the time of writing, most browsers support all three of these formats, with Cookie2 being the preferred format.

CookieStyle Cookie2
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 mod_usertrack is loaded, and CookieTracking on is set, Apache will send 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, enabling mod_usertrack will not activate cookies.

CookieTracking on

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_watchdog.html.en0000664000175100017510000002003214737542416021546 0ustar covenercovener mod_watchdog - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_watchdog

Available Languages:  en  |  fr 

Description:provides infrastructure for other modules to periodically run tasks
Status:Base
Module Identifier:watchdog_module
Source File:mod_watchdog.c
Compatibility:Available in Apache 2.3 and later

Summary

mod_watchdog defines programmatic hooks for other modules to periodically run tasks. These modules can register handlers for mod_watchdog hooks. Currently, the following modules in the Apache distribution use this functionality:

To allow a module to use mod_watchdog functionality, mod_watchdog itself must be statically linked to the server core or, if a dynamic module, be loaded before the calling module.
Support Apache!

Directives

Bugfix checklist

See also

top

WatchdogInterval Directive

Description:Watchdog interval in seconds
Syntax:WatchdogInterval time-interval[s]
Default:WatchdogInterval 1
Context:server config
Status:Base
Module:mod_watchdog

Sets the interval at which the watchdog_step hook runs. Default is to run every second.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_session_crypto.html.en0000664000175100017510000004356714737542416023053 0ustar covenercovener mod_session_crypto - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_session_crypto

Available Languages:  en  |  fr 

Description:Session encryption support
Status:Experimental
Module Identifier:session_crypto_module
Source File:mod_session_crypto.c
Compatibility:Available in Apache 2.3 and later

Summary

Warning

The session modules make use of HTTP cookies, and as such can fall victim to Cross Site Scripting attacks, or expose potentially private information to clients. Please ensure that the relevant risks have been taken into account before enabling the session functionality on your server.

This submodule of mod_session provides support for the encryption of user sessions before being written to a local database, or written to a remote browser via an HTTP cookie.

This can help provide privacy to user sessions where the contents of the session should be kept private from the user, or where protection is needed against the effects of cross site scripting attacks.

For more details on the session interface, see the documentation for the mod_session module.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Basic Usage

To create a simple encrypted session and store it in a cookie called session, configure the session as follows:

Browser based encrypted session

Session On
SessionCookieName session path=/
SessionCryptoPassphrase secret

The session will be encrypted with the given key. Different servers can be configured to share sessions by ensuring the same encryption key is used on each server.

If the encryption key is changed, sessions will be invalidated automatically.

For documentation on how the session can be used to store username and password details, see the mod_auth_form module.

top

SessionCryptoCipher Directive

Description:The crypto cipher to be used to encrypt the session
Syntax:SessionCryptoCipher name
Default:SessionCryptoCipher aes256
Context:server config, virtual host, directory, .htaccess
Status:Experimental
Module:mod_session_crypto
Compatibility:Available in Apache 2.3.0 and later

The SessionCryptoCipher directive allows the cipher to be used during encryption. If not specified, the cipher defaults to aes256.

Possible values depend on the crypto driver in use, and could be one of:

top

SessionCryptoDriver Directive

Description:The crypto driver to be used to encrypt the session
Syntax:SessionCryptoDriver name [param[=value]]
Default:none
Context:server config
Status:Experimental
Module:mod_session_crypto
Compatibility:Available in Apache 2.3.0 and later

The SessionCryptoDriver directive specifies the name of the crypto driver to be used for encryption. If not specified, the driver defaults to the recommended driver compiled into APR-util.

The NSS crypto driver requires some parameters for configuration, which are specified as parameters with optional values after the driver name.

NSS without a certificate database

SessionCryptoDriver nss

NSS with certificate database

SessionCryptoDriver nss dir=certs

NSS with certificate database and parameters

SessionCryptoDriver nss dir=certs key3=key3.db cert7=cert7.db secmod=secmod

NSS with paths containing spaces

SessionCryptoDriver nss "dir=My Certs" key3=key3.db cert7=cert7.db secmod=secmod

The NSS crypto driver might have already been configured by another part of the server, for example from mod_nss or mod_ldap. If found to have already been configured, a warning will be logged, and the existing configuration will have taken affect. To avoid this warning, use the noinit parameter as follows.

NSS with certificate database

SessionCryptoDriver nss noinit

To prevent confusion, ensure that all modules requiring NSS are configured with identical parameters.

The openssl crypto driver supports an optional parameter to specify the engine to be used for encryption.

OpenSSL with engine support

SessionCryptoDriver openssl engine=name
top

SessionCryptoPassphrase Directive

Description:The key used to encrypt the session
Syntax:SessionCryptoPassphrase secret [ secret ... ]
Default:none
Context:server config, virtual host, directory, .htaccess
Status:Experimental
Module:mod_session_crypto
Compatibility:Available in Apache 2.3.0 and later

The SessionCryptoPassphrase directive specifies the keys to be used to enable symmetrical encryption on the contents of the session before writing the session, or decrypting the contents of the session after reading the session.

Keys are more secure when they are long, and consist of truly random characters. Changing the key on a server has the effect of invalidating all existing sessions.

Multiple keys can be specified in order to support key rotation. The first key listed will be used for encryption, while all keys listed will be attempted for decryption. To rotate keys across multiple servers over a period of time, add a new secret to the end of the list, and once rolled out completely to all servers, remove the first key from the start of the list.

As of version 2.4.7 if the value begins with exec: the resulting command will be executed and the first line returned to standard output by the program will be used as the key.

#key used as-is
SessionCryptoPassphrase secret

#Run /path/to/program to get key
SessionCryptoPassphrase exec:/path/to/program

#Run /path/to/otherProgram and provide arguments
SessionCryptoPassphrase "exec:/path/to/otherProgram argument1"
top

SessionCryptoPassphraseFile Directive

Description:File containing keys used to encrypt the session
Syntax:SessionCryptoPassphraseFile filename
Default:none
Context:server config, virtual host, directory
Status:Experimental
Module:mod_session_crypto
Compatibility:Available in Apache 2.3.0 and later

The SessionCryptoPassphraseFile directive specifies the name of a configuration file containing the keys to use for encrypting or decrypting the session, specified one per line. The file is read on server start, and a graceful restart will be necessary for httpd to pick up changes to the keys.

Unlike the SessionCryptoPassphrase directive, the keys are not exposed within the httpd configuration and can be hidden by protecting the file appropriately.

Multiple keys can be specified in order to support key rotation. The first key listed will be used for encryption, while all keys listed will be attempted for decryption. To rotate keys across multiple servers over a period of time, add a new secret to the end of the list, and once rolled out completely to all servers, remove the first key from the start of the list.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_slotmem_plain.html.en0000664000175100017510000002014614737542416022617 0ustar covenercovener mod_slotmem_plain - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_slotmem_plain

Available Languages:  en  |  fr 

Description:Slot-based shared memory provider.
Status:Extension
Module Identifier:slotmem_plain_module
Source File:mod_slotmem_plain.c

Summary

mod_slotmem_plain is a memory provider which provides for creation and access to a plain memory segment in which the datasets are organized in "slots."

If the memory needs to be shared between threads and processes, a better provider would be mod_slotmem_shm.

mod_slotmem_plain provides the following API functions:

/* call the callback on all worker slots */
apr_status_t doall(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)

/* create a new slotmem with each item size is item_size */
apr_status_t create(ap_slotmem_instance_t **new, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool)

/* attach to an existing slotmem */
apr_status_t attach(ap_slotmem_instance_t **new, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)

/* get the direct pointer to the memory associated with this worker slot */
apr_status_t dptr(ap_slotmem_instance_t *s, unsigned int item_id, void **mem)

/* get/read the memory from this slot to dest */
apr_status_t get(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len)

/* put/write the data from src to this slot */
apr_status_t put(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len)

/* return the total number of slots in the segment */
unsigned int num_slots(ap_slotmem_instance_t *s)

/* return the total data size, in bytes, of a slot in the segment */
apr_size_t slot_size(ap_slotmem_instance_t *s)

/* grab or allocate the first free slot and mark as in-use (does not do any data copying) */
apr_status_t grab(ap_slotmem_instance_t *s, unsigned int *item_id)

/* forced grab or allocate the specified slot and mark as in-use (does not do any data copying) */
apr_status_t fgrab(ap_slotmem_instance_t *s, unsigned int item_id)

/* release or free a slot and mark as not in-use (does not do any data copying) */
apr_status_t release(ap_slotmem_instance_t *s, unsigned int item_id)
Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_dbm.html.en0000664000175100017510000001424014737542416022201 0ustar covenercovener mod_socache_dbm - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_socache_dbm

Available Languages:  en  |  fr 

Description:DBM based shared object cache provider.
Status:Extension
Module Identifier:socache_dbm_module
Source File:mod_socache_dbm.c

Summary

mod_socache_dbm is a shared object cache provider which provides for creation and access to a cache backed by a DBM database.

dbm:/path/to/datafile

Details of other shared object cache providers can be found here.

Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_socache_redis.html.en0000664000175100017510000002443014737542416022547 0ustar covenercovener mod_socache_redis - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_socache_redis

Available Languages:  en  |  fr 

Description:Redis based shared object cache provider.
Status:Extension
Module Identifier:socache_redis_module
Source File:mod_socache_redis.c
Compatibility:Available in Apache 2.4.39 and later

Summary

mod_socache_redis is a shared object cache provider which provides for creation and access to a cache backed by the Redis high-performance, distributed memory object caching system.

This shared object cache provider's "create" method requires a comma separated list of memcached host/port specifications. If using this provider via another modules configuration (such as SSLSessionCache), provide the list of servers as the optional "arg" parameter.

SSLSessionCache redis:redis.example.com:12345,redis2.example.com:12345

Details of other shared object cache providers can be found here.

Support Apache!

Directives

Bugfix checklist

See also

top

RedisConnPoolTTL Directive

Description:TTL used for the connection pool with the Redis server(s)
Syntax:RedisConnPoolTTL num[units]
Default:RedisConnPoolTTL 15s
Context:server config, virtual host
Status:Extension
Module:mod_socache_redis
Compatibility:Available in Apache 2.4.39 and later

Set the time to keep idle connections with the Redis server(s) alive (threaded platforms only).

Valid values for RedisConnPoolTTL are times up to one hour. 0 means no timeout.

This timeout defaults to units of seconds, but accepts suffixes for milliseconds (ms), seconds (s), minutes (min), and hours (h).

# Set a timeout of 10 minutes
RedisConnPoolTTL 10min
# Set a timeout of 60 seconds
RedisConnPoolTTL 60
top

RedisTimeout Directive

Description:R/W timeout used for the connection with the Redis server(s)
Syntax:RedisTimeout num[units]
Default:RedisTimeout 5s
Context:server config, virtual host
Status:Extension
Module:mod_socache_redis
Compatibility:Available in Apache 2.4.39 and later

Set the Read/Write timeout used for the connection with the Redis server(s).

Valid values for RedisTimeout are times up to one hour. 0 means no timeout.

This timeout defaults to units of seconds, but accepts suffixes for milliseconds (ms), seconds (s), minutes (min), and hours (h).

# Set a timeout of 10 minutes
RedisTimeout 10min
# Set a timeout of 60 seconds
RedisTimeout 60

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_status.html.en0000664000175100017510000002767114737542416021311 0ustar covenercovener mod_status - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_status

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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 lines marked "(*)" are only available if ExtendedStatus is On. In version 2.3.6, loading mod_status will toggle ExtendedStatus On by default.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

See also

top

Enabling Status Support

To enable status reports only for browsers from the example.com domain add this code to your httpd.conf configuration file

<Location "/server-status">
    SetHandler server-status
    Require host example.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 log_server_status, which you will find in the /support directory of your Apache HTTP Server installation.

It should be noted that if mod_status 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.
top

Using server-status to troubleshoot

The server-status page may be used as a starting place for troubleshooting a situation where your server is consuming all available resources (CPU or memory), and you wish to identify which requests or clients are causing the problem.

First, ensure that you have ExtendedStatus set on, so that you can see the full request and client information for each child or thread.

Now look in your process list (using top, or similar process viewing utility) to identify the specific processes that are the main culprits. Order the output of top by CPU usage, or memory usage, depending on what problem you're trying to address.

Reload the server-status page, and look for those process ids, and you'll be able to see what request is being served by that process, for what client. Requests are transient, so you may need to try several times before you catch it in the act, so to speak.

This process should give you some idea what client, or what type of requests, are primarily responsible for your load problems. Often you will identify a particular web application that is misbehaving, or a particular client that is attacking your site.

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_systemd.html.en0000664000175100017510000001762714737542416021456 0ustar covenercovener mod_systemd - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_systemd

Available Languages:  en  |  fr 

Description:Provides better support for systemd integration
Status:Extension
Module Identifier:systemd_module
Source File:mod_systemd.c
Compatibility:Available in Apache 2.4.42 and later

Summary

This module provides support for systemd integration. It allows httpd to be used in a service with the systemd Type=notify (see systemd.service(5) for more information). The module is activated if loaded.

Example of systemd service unit (more settings are probably needed for production systems)

[Unit]
Description=The Apache HTTP Server
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/apache2/bin/httpd -D FOREGROUND -k start
ExecReload=/usr/local/apache2/bin/httpd -k graceful
KillMode=mixed

[Install]
WantedBy=multi-user.target

Special attention should be given to how ExecStop and/or KillMode are configured for the service. If configured, an ExecStop command should be a synchronous operation which itself exits when the daemon has terminated. Running httpd -k stop asynchronously initiates daemon termination, so does not satisfy this condition. The example above uses KillMode=mixed so that systemd sends SIGTERM to signal the parent process (and only the parent) to shut down. The entire process group is then sent SIGKILL after TimeoutStopSec elapses, if any processes are still running. See systemd.kill(5) for more information.

This module does not provide support for Systemd socket activation.

ExtendedStatus is enabled by default if the module is loaded. If ExtendedStatus is not disabled in the configuration, run-time load and request statistics are made available in the systemctl status output.

Support Apache!

Directives

This module provides no directives.

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_userdir.html.en0000664000175100017510000003111014737542416021422 0ustar covenercovener mod_userdir - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_userdir

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

Description:User-specific directories
Status:Base
Module Identifier:userdir_module
Source File:mod_userdir.c

Summary

By using this module you are allowing multiple users to host content within the same origin. The same origin policy is a key principle of Javascript and web security. By hosting web pages in the same origin these pages can read and control each other and security issues in one page may affect another. This is particularly dangerous in combination with web pages involving dynamic content and authentication and when your users don't necessarily trust each other.

This module allows user-specific directories to be accessed using the http://example.com/~user/ syntax.

Support Apache!

Directives

Bugfix checklist

See also

top

UserDir Directive

Description:Location of the user-specific directories
Syntax:UserDir directory-filename [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:

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.example.com/~bob/one/two.html will be translated to:

UserDir directive used Translated 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 used Translated path
UserDir http://www.example.com/users http://www.example.com/users/bob/one/two.html
UserDir http://www.example.com/*/usr http://www.example.com/bob/usr/one/two.html
UserDir http://www.example.com/~*/ http://www.example.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 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.example.com/"

With a request for http://www.example.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.example.com/bob/one/two.html.

If you add a redirect, it must be the last alternative in the list. Apache httpd 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.

Merging details

Lists of specific enabled and disabled users are replaced, not merged, from global to virtual host scope

See also

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_vhost_alias.html.en0000664000175100017510000005176014737542416022276 0ustar covenercovener mod_vhost_alias - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_vhost_alias

Available Languages:  en  |  fr  |  tr 

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/"
Support Apache!

Topics

Directives

Bugfix checklist

See also

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 %
%p insert the port number of the virtual host
%N.M insert (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:

0 the whole name
1 the first part
2 the second part
-1 the last part
-2 the 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.

A very common request by users is the ability to point multiple domains to multiple document roots without having to worry about the length or number of parts of the hostname being requested. If the requested hostname is sub.www.domain.example.com instead of simply www.domain.example.com, then using %3+ will result in the document root being /usr/local/apache/vhosts/domain.example.com/... instead of the intended example.com directory. In such cases, it can be beneficial to use the combination %-2.0.%-1.0, which will always yield the domain name and the tld, for example example.com regardless of the number of subdomains appended to the hostname. As such, one can make a configuration that will direct all first, second or third level subdomains to the same directory:

VirtualDocumentRoot "/usr/local/apache/vhosts/%-2.0.%-1.0"

In the example above, both www.example.com as well as www.sub.example.com or example.com will all point to /usr/local/apache/vhosts/example.com.

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

Note

VirtualDocumentRoot will override any DocumentRoot directives you may have put in the same context or child contexts. Putting a VirtualDocumentRoot in the global server scope will effectively override DocumentRoot directives in any virtual hosts defined later on, unless you set VirtualDocumentRoot to None in each virtual host.
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 httpd 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  |  fr  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/module-dict.html.en0000664000175100017510000002234514737542416021326 0ustar covenercovener Terms Used to Describe Modules - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Terms Used to Describe Modules

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

This document describes the terms that are used to describe each Apache module.

Support Apache!

See also

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  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_netware.html.en0000664000175100017510000002407214737542416021435 0ustar covenercovener mpm_netware - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache MPM netware

Available Languages:  en  |  fr 

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 HTTP Server 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 httpd 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.

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

Support Apache!

Directives

Bugfix checklist

See also

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

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_common.html.en0000664000175100017510000020236614737542416021264 0ustar covenercovener mpm_common - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache MPM Common Directives

Available Languages:  de  |  en  |  fr  |  ja  |  tr 

Description:A collection of directives that are implemented by more than one multi-processing module (MPM)
Status:MPM
Support Apache!

Directives

Bugfix checklist

See also

top

CoreDumpDirectory Directive

Description:Directory where Apache HTTP Server attempts to switch before dumping core
Syntax:CoreDumpDirectory directory
Default:See usage for the default setting
Context:server config
Status:MPM
Module:event, worker, prefork

This controls the directory to which Apache httpd attempts to switch before dumping core. If your operating system is configured to create core files in the working directory of the crashing process, CoreDumpDirectory is necessary to change working directory from the default ServerRoot directory, which should not be writable by the user the server runs as.

If you want a core dump for debugging, you can use this directive to place it in a different location. This directive has no effect if your operating system is not configured to write core files to the working directory of the crashing processes.

Security note for Linux systems

Using this directive on Linux may allow other processes on the system (if running with similar privileges, such as CGI scripts) to attach to httpd children via the ptrace system call. This may make weaken the protection from certain security attacks. It is not recommended to use this directive on production systems.

Core Dumps on Linux

If Apache httpd starts as root and switches to another user, the Linux kernel disables core dumps even if the directory is writable for the process. Apache httpd (2.0.46 and later) reenables core dumps on Linux 2.4 and beyond, but only if you explicitly configure a CoreDumpDirectory.

Core Dumps on BSD

To enable core-dumping of suid-executables on BSD-systems (such as FreeBSD), set kern.sugid_coredump to 1.

Specific signals

CoreDumpDirectory processing only occurs for a select set of fatal signals: SIGFPE, SIGILL, SIGABORT, SIGSEGV, and SIGBUS.

On some operating systems, SIGQUIT also results in a core dump but does not go through CoreDumpDirectory or EnableExceptionHook processing, so the core location is dictated entirely by the operating system.

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:event, worker, prefork

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

GracefulShutdownTimeout Directive

Description:Specify a timeout after which a gracefully shutdown server will exit.
Syntax:GracefulShutdownTimeout seconds
Default:GracefulShutdownTimeout 0
Context:server config
Status:MPM
Module:event, worker, prefork
Compatibility:Available in version 2.2 and later

The GracefulShutdownTimeout specifies how many seconds after receiving a "graceful-stop" signal, a server should continue to run, handling the existing connections.

Setting this value to zero means that the server will wait indefinitely until all remaining requests have been fully served.

top

Listen Directive

Description:IP addresses and ports that the server listens to
Syntax:Listen [IP-address:]portnumber [protocol]
Context:server config
Status:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
Compatibility:The protocol argument was added in 2.1.5

The Listen directive instructs Apache httpd 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 httpd.

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 [2001:db8::a00:20ff:fea7:ccea]:80

The optional protocol argument is not required for most configurations. If not specified, https is the default for port 443 and http the default for all other ports. The protocol is used to determine which module should handle a request, and to apply protocol specific optimizations with the AcceptFilter directive.

You only need to set the protocol if you are running on non-standard ports. For example, running an https site on port 8443:

Listen 192.170.2.1:8443 https

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:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

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

ListenCoresBucketsRatio Directive

Description:Ratio between the number of CPU cores (online) and the number of listeners' buckets
Syntax:ListenCoresBucketsRatio ratio
Default:ListenCoresBucketsRatio 0 (disabled)
Context:server config
Status:MPM
Module:event, worker, prefork
Compatibility:Available in Apache HTTP Server 2.4.17, with a kernel supporting the socket option SO_REUSEPORT and distributing new connections evenly across listening processes' (or threads') sockets using it (eg. Linux 3.9 and later, but not the current implementations of SO_REUSEPORT in *BSDs.

A ratio between the number of (online) CPU cores and the number of listeners' buckets can be used to make Apache HTTP Server create num_cpu_cores / ratio listening buckets, each containing its own Listen-ing socket(s) on the same port(s), and then make each child handle a single bucket (with round-robin distribution of the buckets at children creation time).

Meaning of "online" CPU core

On Linux (and also BSD) a CPU core can be turned on/off if Hotplug is configured, therefore ListenCoresBucketsRatio needs to take this parameter into account while calculating the number of buckets to create.

ListenCoresBucketsRatio can improve the scalability when accepting new connections is/becomes the bottleneck. On systems with a large number of CPU cores, enabling this feature has been tested to show significant performances improvement and shorter responses time.

There must be at least twice the number of CPU cores than the configured ratio for this to be active. The recommended ratio is 8, hence at least 16 cores should be available at runtime when this value is used. The right ratio to obtain maximum performance needs to be calculated for each target system, testing multiple values and observing the variations in your key performance metrics.

This directive influences the calculation of the MinSpareThreads and MaxSpareThreads lower bound values. The number of children processes needs to be a multiple of the number of buckets to optimally accept connections.

Multiple Listeners or Apache HTTP servers on the same IP address and port

Setting the SO_REUSEPORT option on the listening socket(s) consequently allows multiple processes (sharing the same EUID, e.g. root) to bind to the the same IP address and port, without the binding error raised by the system in the usual case.

This also means that multiple instances of Apache httpd configured on a same IP:port and with a positive ListenCoresBucketsRatio would start without an error too, and then run with incoming connections evenly distributed across both instances (this is NOT a recommendation or a sensible usage in any case, but just a notice that it would prevent such possible issues to be detected).

Within the same instance, Apache httpd will check and fail to start if multiple Listen directives on the exact same IP (or hostname) and port are configured, thus avoiding the creation of some duplicated buckets which would be useless and kill performances. However it can't (and won't try harder to) catch all the possible overlapping cases (like a hostname resolving to an IP used elsewhere).

top

MaxConnectionsPerChild Directive

Description:Limit on the number of connections that an individual child server will handle during its life
Syntax:MaxConnectionsPerChild number
Default:MaxConnectionsPerChild 0
Context:server config
Status:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
Compatibility:Available Apache HTTP Server 2.3.9 and later. The old name MaxRequestsPerChild is still supported.

The MaxConnectionsPerChild directive sets the limit on the number of connections that an individual child server process will handle. After MaxConnectionsPerChild connections, the child process will die. If MaxConnectionsPerChild is 0, then the process will never expire.

Setting MaxConnectionsPerChild to a non-zero value limits the amount of memory that a process can consume by (accidental) memory leakage.

top

MaxMemFree Directive

Description:Maximum amount of memory that the main allocator is allowed to hold without calling free()
Syntax:MaxMemFree KBytes
Default:MaxMemFree 2048
Context:server config
Status:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware

The MaxMemFree directive sets the maximum number of free Kbytes that every allocator is allowed to hold without calling free(). In threaded MPMs, every thread has its own allocator. When set to zero, the threshold will be set to unlimited.

top

MaxRequestWorkers Directive

Description:Maximum number of connections that will be processed simultaneously
Syntax:MaxRequestWorkers number
Default:See usage for details
Context:server config
Status:MPM
Module:event, worker, prefork

The MaxRequestWorkers directive sets the limit on the number of simultaneous requests that will be served. Any connection attempts over the MaxRequestWorkers 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), MaxRequestWorkers 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. event or worker), MaxRequestWorkers restricts the total number of threads that will be available to serve clients. For hybrid MPMs, the default value is 16 (ServerLimit) multiplied by the value of 25 (ThreadsPerChild). Therefore, to increase MaxRequestWorkers to a value that requires more than 16 processes, you must also raise ServerLimit.

MaxRequestWorkers was called MaxClients before version 2.3.13. The old name is still supported.

top

MaxSpareThreads Directive

Description:Maximum number of idle threads
Syntax:MaxSpareThreads number
Default:See usage for details
Context:server config
Status:MPM
Module:event, worker, mpm_netware, mpmt_os2

Maximum number of idle threads. Different MPMs deal with this directive differently.

For worker and event, 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. Additional processes/threads might be created if ListenCoresBucketsRatio is enabled.

For mpm_netware the default is MaxSpareThreads 100. Since this MPM runs a single-process, the spare thread count is also server-wide.

mpmt_os2 works similar to mpm_netware. For mpmt_os2 the default value is 10.

Restrictions

The range of the MaxSpareThreads value is restricted. Apache httpd 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:event, worker, mpm_netware, mpmt_os2

Minimum number of idle threads to handle request spikes. Different MPMs deal with this directive differently.

worker and event 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. Additional processes/threads might be created if ListenCoresBucketsRatio is enabled.

mpm_netware uses a default of MinSpareThreads 10 and, since it is a single-process MPM, tracks this on a server-wide basis.

mpmt_os2 works similar to mpm_netware. 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:event, worker, prefork, mpm_winnt, mpmt_os2

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 HTTP Server 2, we recommended that you only use the apachectl script, or the init script that your OS provides, for (re-)starting or stopping the server.

top

ReceiveBufferSize Directive

Description:TCP receive buffer size
Syntax:ReceiveBufferSize bytes
Default:ReceiveBufferSize 0
Context:server config
Status:MPM
Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

The server will set the TCP receive buffer size to the number of bytes specified.

If set to the value of 0, the server will use the OS default.

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_runtime_status
Context:server config
Status:MPM
Module:event, worker, prefork, mpm_winnt

Apache HTTP Server 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 httpd 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 httpd to always create the file on the disk.

Example

ScoreBoardFile /var/run/apache_runtime_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:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2

Sets the server's TCP send buffer size to the number of bytes specified. It is often useful to set this past the OS's standard default value on high speed, high latency connections (i.e., 100ms or so, such as transcontinental fast pipes).

If set to the value of 0, the server will use the default value provided by your OS.

Further configuration of your operating system may be required to elicit better performance on high speed, high latency connections.

On some operating systems, changes in TCP behavior resulting from a larger SendBufferSize may not be seen unless EnableSendfile is set to OFF. This interaction applies only to static files.

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:event, worker, prefork

For the prefork MPM, this directive sets the maximum configured value for MaxRequestWorkers for the lifetime of the Apache httpd process. For the worker and event MPMs, this directive in combination with ThreadLimit sets the maximum configured value for MaxRequestWorkers for the lifetime of the Apache httpd process. For the event MPM, this directive also defines how many old server processes may keep running and finish processing open connections. Any attempts to change this directive during a restart will be ignored, but MaxRequestWorkers 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 MaxRequestWorkers are set to values higher than the system can handle, Apache httpd may not start or the system may become unstable.

With the prefork MPM, use this directive only if you need to set MaxRequestWorkers higher than 256 (default). Do not set the value of this directive any higher than what you might want to set MaxRequestWorkers to.

With worker, use this directive only if your MaxRequestWorkers 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 MaxRequestWorkers and ThreadsPerChild.

With event, increase this directive if the process number defined by your MaxRequestWorkers and ThreadsPerChild settings, plus the number of gracefully shutting down processes, is more than 16 server processes (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. To increase it even further past this limit, you will need to modify the value of MAX_SERVER_LIMIT in the mpm source file and rebuild the server.

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:event, worker, prefork, mpmt_os2

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, (see MinSpareThreads, MaxSpareThreads, MinSpareServers, MaxSpareServers) there is usually little reason to adjust this parameter.

The default value differs from MPM to MPM. worker and event default to StartServers 3; prefork defaults to 5; mpmt_os2 defaults 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:mpm_netware

Number of threads created on startup. As the number of threads is dynamically controlled depending on the load, (see MinSpareThreads, MaxSpareThreads, MinSpareServers, MaxSpareServers) there is usually little reason to adjust this parameter.

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.

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:event, worker, mpm_winnt

This directive sets the maximum configured value for ThreadsPerChild for the lifetime of the Apache httpd 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 httpd 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 httpd.

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 100000 with event, ThreadLimit 15000 with mpm_winnt) compiled into the server. This is intended to avoid nasty effects caused by typos. To increase it even further past this limit, you will need to modify the value of MAX_THREAD_LIMIT in the mpm source file and rebuild the server.

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:event, worker, mpm_winnt

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.

The value of ThreadsPerChild can not exceed the value of ThreadLimit. If a higher value is configured, it will be automatically reduced at start-up and a warning will be logged. The relationship between these 2 directives is explained in ThreadLimit.

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:event, worker, mpm_winnt, mpm_netware, mpmt_os2
Compatibility:Available in Apache HTTP Server 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:

It is recommended to not reduce ThreadStackSize unless a high number of threads per child process is needed. On some platforms (including Linux), a setting of 128000 is already too low and causes crashes with some common modules.

Available Languages:  de  |  en  |  fr  |  ja  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpmt_os2.html.en0000664000175100017510000001743114737542416020660 0ustar covenercovener mpmt_os2 - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache MPM os2

Available Languages:  en  |  fr 

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

Support Apache!

Directives

Bugfix checklist

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/overrides.html.en0000664000175100017510000021131714737542416021121 0ustar covenercovener Override Class Index for .htaccess - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Override Class Index for .htaccess

Available Languages:  en  |  fr 

This is an index of the directives that are allowed in .htaccess files for various AllowOverride settings, organized by class. Its intended purpose is to help server administrators verify the privileges they're granting to .htaccess users. For an overview of how .htaccess works, see the .htaccess tutorial.

To determine the set of directives that your server configuration allows .htaccess users to use:

  1. Start with the set of directives in the AllowOverrideList for the directory in question. (By default, this is set to None.)
  2. Find the AllowOverride setting for the directory in question. (By default, it is set to None.) There are two special cases:
    1. If your AllowOverride setting is All, add every directive listed on this page to the list.
    2. If your AllowOverride setting is None, you're done. Only the directives in the AllowOverrideList (if any) will be allowed.
  3. For each override class listed in AllowOverride, look up the corresponding set of directives below and add them to the list.
  4. Finally, add the set of directives that is always allowed in .htaccess (these are listed in the All section, below).

Several of the override classes are quite powerful and give .htaccess users a large amount of control over the server. For a stricter approach, set AllowOverride None and use AllowOverrideList to specify the exact list of directives that .htaccess users are allowed to use.

Topics

See also

top

All

The following directives are allowed in any .htaccess file, as long as overrides are enabled in the server configuration.

<Else>core
Contains directives that apply only if the condition of a previous <If> or <ElseIf> section is not satisfied by a request at runtime
<ElseIf>core
Contains directives that apply only if a condition is satisfied by a request at runtime while the condition of a previous <If> or <ElseIf> section is not satisfied
<Files>core
Contains directives that apply to matched filenames
<FilesMatch>core
Contains directives that apply to regular-expression matched filenames
<If>core
Contains directives that apply only if a condition is satisfied by a request at runtime
<IfDefine>core
Encloses directives that will be processed only if a test is true at startup
<IfDirective>core
Encloses directives that are processed conditional on the presence or absence of a specific directive
<IfFile>core
Encloses directives that will be processed only if file exists at startup
<IfModule>core
Encloses directives that are processed conditional on the presence or absence of a specific module
<IfSection>core
Encloses directives that are processed conditional on the presence or absence of a specific section directive
<IfVersion>mod_version
contains version dependent configuration
LimitRequestBodycore
Restricts the total size of the HTTP request body sent from the client
LimitXMLRequestBodycore
Limits the size of an XML-based request body
LogIOTrackTTFBmod_logio
Enable tracking of time to first byte (TTFB)
LuaCodeCachemod_lua
Configure the compiled code cache.
LuaHookAccessCheckermod_lua
Provide a hook for the access_checker phase of request processing
LuaHookAuthCheckermod_lua
Provide a hook for the auth_checker phase of request processing
LuaHookCheckUserIDmod_lua
Provide a hook for the check_user_id phase of request processing
LuaHookFixupsmod_lua
Provide a hook for the fixups phase of a request processing
LuaHookInsertFiltermod_lua
Provide a hook for the insert_filter phase of request processing
LuaHookLogmod_lua
Provide a hook for the access log phase of a request processing
LuaHookMapToStoragemod_lua
Provide a hook for the map_to_storage phase of request processing
LuaHookPreTranslatemod_lua
Provide a hook for the pre_translate phase of a request processing
LuaHookTranslateNamemod_lua
Provide a hook for the translate name phase of request processing
LuaHookTypeCheckermod_lua
Provide a hook for the type_checker phase of request processing
LuaInheritmod_lua
Controls how parent configuration sections are merged into children
LuaMapHandlermod_lua
Map a path to a lua handler
LuaPackageCPathmod_lua
Add a directory to lua's package.cpath
LuaPackagePathmod_lua
Add a directory to lua's package.path
LuaQuickHandlermod_lua
Provide a hook for the quick handler of request processing
LuaRootmod_lua
Specify the base path for resolving relative paths for mod_lua directives
LuaScopemod_lua
One of once, request, conn, thread -- default is once
RLimitCPUcore
Limits the CPU consumption of processes launched by Apache httpd children
RLimitMEMcore
Limits the memory consumption of processes launched by Apache httpd children
RLimitNPROCcore
Limits the number of processes that can be launched by processes launched by Apache httpd children
ServerSignaturecore
Configures the footer on server-generated documents
SSIErrorMsgmod_include
Error message displayed when there is an SSI error
SSITimeFormatmod_include
Configures the format in which date strings are displayed
SSIUndefinedEchomod_include
String displayed when an unset variable is echoed
top

AuthConfig

The following directives are allowed in .htaccess files when AllowOverride AuthConfig is in effect. They give .htaccess users control over the authentication and authorization methods that are applied to their directory subtrees, including several related utility directives for session handling and TLS settings.

Anonymousmod_authn_anon
Specifies userIDs that are allowed access without password verification
Anonymous_LogEmailmod_authn_anon
Sets whether the password entered will be logged in the error log
Anonymous_MustGiveEmailmod_authn_anon
Specifies whether blank passwords are allowed
Anonymous_NoUserIDmod_authn_anon
Sets whether the userID field may be empty
Anonymous_VerifyEmailmod_authn_anon
Sets whether to check the password field for a correctly formatted email address
AuthBasicAuthoritativemod_auth_basic
Sets whether authorization and authentication are passed to lower level modules
AuthBasicFakemod_auth_basic
Fake basic authentication using the given expressions for username and password
AuthBasicProvidermod_auth_basic
Sets the authentication provider(s) for this location
AuthBasicUseDigestAlgorithmmod_auth_basic
Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
AuthDBMGroupFilemod_authz_dbm
Sets the name of the database file containing the list of user groups for authorization
AuthDBMTypemod_authn_dbm
Sets the type of database file that is used to store passwords
AuthDBMUserFilemod_authn_dbm
Sets the name of a database file containing the list of users and passwords for authentication
AuthDigestAlgorithmmod_auth_digest
Selects the algorithm used to calculate the challenge and response hashes in digest authentication
AuthDigestDomainmod_auth_digest
URIs that are in the same protection space for digest authentication
AuthDigestNonceLifetimemod_auth_digest
How long the server nonce is valid
AuthDigestProvidermod_auth_digest
Sets the authentication provider(s) for this location
AuthDigestQopmod_auth_digest
Determines the quality-of-protection to use in digest authentication
AuthFormAuthoritativemod_auth_form
Sets whether authorization and authentication are passed to lower level modules
AuthFormProvidermod_auth_form
Sets the authentication provider(s) for this location
AuthGroupFilemod_authz_groupfile
Sets the name of a text file containing the list of user groups for authorization
AuthLDAPAuthorizePrefixmod_authnz_ldap
Specifies the prefix for environment variables set during authorization
AuthLDAPBindAuthoritativemod_authnz_ldap
Determines if other authentication providers are used when a user can be mapped to a DN but the server cannot successfully bind with the user's credentials.
AuthLDAPBindDNmod_authnz_ldap
Optional DN to use in binding to the LDAP server
AuthLDAPBindPasswordmod_authnz_ldap
Password used in conjunction with the bind DN
AuthLDAPCompareAsUsermod_authnz_ldap
Use the authenticated user's credentials to perform authorization comparisons
AuthLDAPCompareDNOnServermod_authnz_ldap
Use the LDAP server to compare the DNs
AuthLDAPDereferenceAliasesmod_authnz_ldap
When will the module de-reference aliases
AuthLDAPGroupAttributemod_authnz_ldap
LDAP attributes used to identify the user members of groups.
AuthLDAPGroupAttributeIsDNmod_authnz_ldap
Use the DN of the client username when checking for group membership
AuthLDAPInitialBindAsUsermod_authnz_ldap
Determines if the server does the initial DN lookup using the basic authentication users' own username, instead of anonymously or with hard-coded credentials for the server
AuthLDAPInitialBindPatternmod_authnz_ldap
Specifies the transformation of the basic authentication username to be used when binding to the LDAP server to perform a DN lookup
AuthLDAPMaxSubGroupDepthmod_authnz_ldap
Specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.
AuthLDAPRemoteUserAttributemod_authnz_ldap
Use the value of the attribute returned during the user query to set the REMOTE_USER environment variable
AuthLDAPRemoteUserIsDNmod_authnz_ldap
Use the DN of the client username to set the REMOTE_USER environment variable
AuthLDAPSearchAsUsermod_authnz_ldap
Use the authenticated user's credentials to perform authorization searches
AuthLDAPSubGroupAttributemod_authnz_ldap
Specifies the attribute labels, one value per directive line, used to distinguish the members of the current group that are groups.
AuthLDAPSubGroupClassmod_authnz_ldap
Specifies which LDAP objectClass values identify directory objects that are groups during sub-group processing.
AuthLDAPURLmod_authnz_ldap
URL specifying the LDAP search parameters
AuthMergingmod_authz_core
Controls the manner in which each configuration section's authorization logic is combined with that of preceding configuration sections.
AuthNamemod_authn_core
Authorization realm for use in HTTP authentication
AuthnCacheProvideFormod_authn_socache
Specify which authn provider(s) to cache for
AuthnCacheTimeoutmod_authn_socache
Set a timeout for cache entries
AuthTypemod_authn_core
Type of user authentication
AuthUserFilemod_authn_file
Sets the name of a text file containing the list of users and passwords for authentication
AuthzDBMTypemod_authz_dbm
Sets the type of database file that is used to store list of user groups
CGIPassAuthcore
Enables passing HTTP authorization headers to scripts as CGI variables
LDAPReferralHopLimitmod_ldap
The maximum number of referral hops to chase before terminating an LDAP query.
LDAPReferralsmod_ldap
Enable referral chasing during queries to the LDAP server.
<Limit>core
Restrict enclosed access controls to only certain HTTP methods
<LimitExcept>core
Restrict access controls to all HTTP methods except the named ones
Requiremod_authz_core
Tests whether an authenticated user is authorized by an authorization provider.
<RequireAll>mod_authz_core
Enclose a group of authorization directives of which none must fail and at least one must succeed for the enclosing directive to succeed.
<RequireAny>mod_authz_core
Enclose a group of authorization directives of which one must succeed for the enclosing directive to succeed.
<RequireNone>mod_authz_core
Enclose a group of authorization directives of which none must succeed for the enclosing directive to not fail.
Satisfymod_access_compat
Interaction between host-level access control and user authentication
Sessionmod_session
Enables a session for the current directory or location
SessionEnvmod_session
Control whether the contents of the session are written to the HTTP_SESSION environment variable
SessionHeadermod_session
Import session updates from a given HTTP response header
SessionIncludemod_session
Define URL prefixes for which a session is valid
SessionMaxAgemod_session
Define a maximum age in seconds for a session
SSLCipherSuitemod_ssl
Cipher Suite available for negotiation in SSL handshake
SSLRenegBufferSizemod_ssl
Set the size for the SSL renegotiation buffer
SSLRequiremod_ssl
Allow access only when an arbitrarily complex boolean expression is true
SSLRequireSSLmod_ssl
Deny access when SSL is not used for the HTTP request
SSLUserNamemod_ssl
Variable name to determine user name
SSLVerifyClientmod_ssl
Type of Client Certificate verification
SSLVerifyDepthmod_ssl
Maximum depth of CA Certificates in Client Certificate verification
top

FileInfo

The following directives are allowed in .htaccess files when AllowOverride FileInfo is in effect. They give .htaccess users a wide range of control over the responses and metadata given by the server.

AcceptPathInfocore
Resources accept trailing pathname information
Actionmod_actions
Activates a CGI script for a particular handler or content-type
AddCharsetmod_mime
Maps the given filename extensions to the specified content charset
AddDefaultCharsetcore
Default charset parameter to be added when a response content-type is text/plain or text/html
AddEncodingmod_mime
Maps the given filename extensions to the specified encoding type
AddHandlermod_mime
Maps the filename extensions to the specified handler
AddInputFiltermod_mime
Maps filename extensions to the filters that will process client requests
AddLanguagemod_mime
Maps the given filename extension to the specified content language
AddOutputFiltermod_mime
Maps filename extensions to the filters that will process responses from the server
AddOutputFilterByTypemod_filter
assigns an output filter to a particular media-type
AddTypemod_mime
Maps the given filename extensions onto the specified content type
BrowserMatchmod_setenvif
Sets environment variables conditional on HTTP User-Agent
BrowserMatchNoCasemod_setenvif
Sets environment variables conditional on User-Agent without respect to case
CGIMapExtensioncore
Technique for locating the interpreter for CGI scripts
CGIVarcore
Controls how some CGI variables are set
CharsetDefaultmod_charset_lite
Charset to translate into
CharsetOptionsmod_charset_lite
Configures charset translation behavior
CharsetSourceEncmod_charset_lite
Source charset of files
CookieDomainmod_usertrack
The domain to which the tracking cookie applies
CookieExpiresmod_usertrack
Expiry time for the tracking cookie
CookieHTTPOnlymod_usertrack
Adds the 'HTTPOnly' attribute to the cookie
CookieNamemod_usertrack
Name of the tracking cookie
CookieSameSitemod_usertrack
Adds the 'SameSite' attribute to the cookie
CookieSecuremod_usertrack
Adds the 'Secure' attribute to the cookie
CookieStylemod_usertrack
Format of the cookie header field
CookieTrackingmod_usertrack
Enables tracking cookie
DefaultLanguagemod_mime
Defines a default language-tag to be sent in the Content-Language header field for all resources in the current context that have not been assigned a language-tag by some other means.
DefaultTypecore
This directive has no effect other than to emit warnings if the value is not none. In prior versions, DefaultType would specify a default media type to assign to response content for which no other media type configuration could be found.
EnableMMAPcore
Use memory-mapping to read files during delivery
EnableSendfilecore
Use the kernel sendfile support to deliver files to the client
ErrorDocumentcore
What the server will return to the client in case of an error
FileETagcore
File attributes used to create the ETag HTTP response header for static files
ForceLanguagePrioritymod_negotiation
Action to take if a single acceptable document is not found
ForceTypecore
Forces all matching files to be served with the specified media type in the HTTP Content-Type header field
Headermod_headers
Configure HTTP response headers
ISAPIAppendLogToErrorsmod_isapi
Record HSE_APPEND_LOG_PARAMETER requests from ISAPI extensions to the error log
ISAPIAppendLogToQuerymod_isapi
Record HSE_APPEND_LOG_PARAMETER requests from ISAPI extensions to the query field
ISAPIFakeAsyncmod_isapi
Fake asynchronous support for ISAPI callbacks
ISAPILogNotSupportedmod_isapi
Log unsupported feature requests from ISAPI extensions
ISAPIReadAheadBuffermod_isapi
Size of the Read Ahead Buffer sent to ISAPI extensions
LanguagePrioritymod_negotiation
The precedence of language variants for cases where the client does not express a preference
MultiviewsMatchmod_mime
The types of files that will be included when searching for a matching file with MultiViews
PassEnvmod_env
Passes environment variables from the shell
QualifyRedirectURLcore
Controls whether the REDIRECT_URL environment variable is fully qualified
Redirectmod_alias
Sends an external redirect asking the client to fetch a different URL
RedirectMatchmod_alias
Sends an external redirect based on a regular expression match of the current URL
RedirectPermanentmod_alias
Sends an external permanent redirect asking the client to fetch a different URL
RedirectTempmod_alias
Sends an external temporary redirect asking the client to fetch a different URL
RemoveCharsetmod_mime
Removes any character set associations for a set of file extensions
RemoveEncodingmod_mime
Removes any content encoding associations for a set of file extensions
RemoveHandlermod_mime
Removes any handler associations for a set of file extensions
RemoveInputFiltermod_mime
Removes any input filter associations for a set of file extensions
RemoveLanguagemod_mime
Removes any language associations for a set of file extensions
RemoveOutputFiltermod_mime
Removes any output filter associations for a set of file extensions
RemoveTypemod_mime
Removes any content type associations for a set of file extensions
RequestHeadermod_headers
Configure HTTP request headers
RewriteBasemod_rewrite
Sets the base URL for per-directory rewrites
RewriteCondmod_rewrite
Defines a condition under which rewriting will take place
RewriteEnginemod_rewrite
Enables or disables runtime rewriting engine
RewriteOptionsmod_rewrite
Sets some special options for the rewrite engine
RewriteRulemod_rewrite
Defines rules for the rewriting engine
ScriptInterpreterSourcecore
Technique for locating the interpreter for CGI scripts
SetEnvmod_env
Sets environment variables
SetEnvIfmod_setenvif
Sets environment variables based on attributes of the request
SetEnvIfExprmod_setenvif
Sets environment variables based on an ap_expr expression
SetEnvIfNoCasemod_setenvif
Sets environment variables based on attributes of the request without respect to case
SetHandlercore
Forces all matching files to be processed by a handler
SetInputFiltercore
Sets the filters that will process client requests and POST input
SetOutputFiltercore
Sets the filters that will process responses from the server
Substitutemod_substitute
Pattern to filter the response content
SubstituteInheritBeforemod_substitute
Change the merge order of inherited patterns
SubstituteMaxLineLengthmod_substitute
Set the maximum line size
UnsetEnvmod_env
Removes variables from the environment
top

Indexes

The following directives are allowed in .htaccess files when AllowOverride Indexes is in effect. They allow .htaccess users to control aspects of the directory index pages provided by the server, including autoindex generation.

AddAltmod_autoindex
Alternate text to display for a file, instead of an icon selected by filename
AddAltByEncodingmod_autoindex
Alternate text to display for a file instead of an icon selected by MIME-encoding
AddAltByTypemod_autoindex
Alternate text to display for a file, instead of an icon selected by MIME content-type
AddDescriptionmod_autoindex
Description to display for a file
AddIconmod_autoindex
Icon to display for a file selected by name
AddIconByEncodingmod_autoindex
Icon to display next to files selected by MIME content-encoding
AddIconByTypemod_autoindex
Icon to display next to files selected by MIME content-type
DefaultIconmod_autoindex
Icon to display for files when no specific icon is configured
DirectoryCheckHandlermod_dir
Toggle how this module responds when another handler is configured
DirectoryIndexmod_dir
List of resources to look for when the client requests a directory
DirectoryIndexRedirectmod_dir
Configures an external redirect for directory indexes.
DirectorySlashmod_dir
Toggle trailing slash redirects on or off
ExpiresActivemod_expires
Enables generation of Expires headers
ExpiresByTypemod_expires
Value of the Expires header configured by MIME type
ExpiresDefaultmod_expires
Default algorithm for calculating expiration time
FallbackResourcemod_dir
Define a default URL for requests that don't map to a file
HeaderNamemod_autoindex
Name of the file that will be inserted at the top of the index listing
ImapBasemod_imagemap
Default base for imagemap files
ImapDefaultmod_imagemap
Default action when an imagemap is called with coordinates that are not explicitly mapped
ImapMenumod_imagemap
Action if no coordinates are given when calling an imagemap
IndexHeadInsertmod_autoindex
Inserts text in the HEAD section of an index page.
IndexIgnoremod_autoindex
Adds to the list of files to hide when listing a directory
IndexIgnoreResetmod_autoindex
Empties the list of files to hide when listing a directory
IndexOptionsmod_autoindex
Various configuration settings for directory indexing
IndexOrderDefaultmod_autoindex
Sets the default ordering of the directory index
IndexStyleSheetmod_autoindex
Adds a CSS stylesheet to the directory index
MetaDirmod_cern_meta
Name of the directory to find CERN-style meta information files
MetaFilesmod_cern_meta
Activates CERN meta-file processing
MetaSuffixmod_cern_meta
File name suffix for the file containing CERN-style meta information
ReadmeNamemod_autoindex
Name of the file that will be inserted at the end of the index listing
top

Limit

The following directives are allowed in .htaccess files when AllowOverride Limit is in effect. This extremely narrow override type mostly allows the use of the legacy authorization directives provided by mod_access_compat.

Allowmod_access_compat
Controls which hosts can access an area of the server
Denymod_access_compat
Controls which hosts are denied access to the server
<Limit>core
Restrict enclosed access controls to only certain HTTP methods
<LimitExcept>core
Restrict access controls to all HTTP methods except the named ones
Ordermod_access_compat
Controls the default access state and the order in which Allow and Deny are evaluated.
top

Options

The following directives are allowed in .htaccess files when AllowOverride Options is in effect. They give .htaccess users access to Options and similar directives, as well as directives that control the filter chain.

CheckBasenameMatchmod_speling
Also match files with differing file name extensions.
CheckCaseOnlymod_speling
Limits the action of the speling module to case corrections
CheckSpellingmod_speling
Enables the spelling module
ContentDigestcore
Enables the generation of Content-MD5 HTTP Response headers
FilterChainmod_filter
Configure the filter chain
FilterDeclaremod_filter
Declare a smart filter
FilterProtocolmod_filter
Deal with correct HTTP protocol handling
FilterProvidermod_filter
Register a content filter
Optionscore
Configures what features are available in a particular directory
ReflectorHeadermod_reflector
Reflect an input header to the output headers
SSLOptionsmod_ssl
Configure various SSL engine run-time options
XBitHackmod_include
Parse SSI directives in files with the execute bit set

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/worker.html.en0000664000175100017510000003664414737542416020440 0ustar covenercovener worker - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache MPM worker

Available Languages:  de  |  en  |  fr  |  ja  |  tr 

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 fewer system resources than a process-based server. However, 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 MaxRequestWorkers, which controls the maximum total number of threads that may be launched.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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 HTTP Server 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 launch is set by the StartServers directive. During operation, the server 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 MaxRequestWorkers directive. The maximum number of active child processes is determined by the MaxRequestWorkers 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 MaxRequestWorkers 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.

In addition to 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 MaxRequestWorkers 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 using the following:

A typical configuration of the process-thread controls in the worker MPM could look as follows:

ServerLimit         16
StartServers         2
MaxRequestWorkers  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 the server as a less-privileged user. The User and Group directives are used to set the privileges of the Apache HTTP Server 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.

MaxConnectionsPerChild controls how frequently the server recycles processes by killing old ones and launching new ones.

This MPM uses the mpm-accept mutex to serialize access to incoming connections when subject to the thundering herd problem (generally, when there are multiple listening sockets). The implementation aspects of this mutex can be configured with the Mutex directive. The performance hints documentation has additional information about this mutex.

Available Languages:  de  |  en  |  fr  |  ja  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/event.html.en0000664000175100017510000007153214737241666020246 0ustar covenercovener event - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache MPM event

Available Languages:  en  |  fr 

Description:A variant of the worker MPM with the goal of consuming threads only for connections with active processing
Status:MPM
Module Identifier:mpm_event_module
Source File:event.c

Summary

The event Multi-Processing Module (MPM) is designed to allow more requests to be served simultaneously by passing off some processing work to the listeners threads, freeing up the worker threads to serve new requests.

To use the event MPM, add --with-mpm=event to the configure script's arguments when building the httpd.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Relationship with the Worker MPM

event is based on the worker MPM, which implements a hybrid multi-process multi-threaded server. 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 worker thread for processing when they arrive.

Run-time configuration directives are identical to those provided by worker, with the only addition of the AsyncRequestWorkerFactor.

top

How it Works

This MPM tries to fix the 'keep alive problem' in HTTP. After a client completes the first request, it can keep the connection open, sending further requests using the same socket and saving significant overhead in creating TCP connections. However, Apache HTTP Server traditionally keeps an entire child process/thread waiting for data from the client, which brings its own disadvantages. To solve this problem, this MPM uses a dedicated listener thread for each process to handle both the Listening sockets, all sockets that are in a Keep Alive state, sockets where the handler and protocol filters have done their work and the ones where the only remaining thing to do is send the data to the client.

This new architecture, leveraging non-blocking sockets and modern kernel features exposed by APR (like Linux's epoll), no longer requires the mpm-accept Mutex configured to avoid the thundering herd problem.

The total amount of connections that a single process/threads block can handle is regulated by the AsyncRequestWorkerFactor directive.

Async connections

Async connections would need a fixed dedicated worker thread with the previous MPMs but not with event. The status page of mod_status shows new columns under the Async connections section:

Writing
While sending the response to the client, it might happen that the TCP write buffer fills up because the connection is too slow. Usually in this case, a write() to the socket returns EWOULDBLOCK or EAGAIN to become writable again after an idle time. The worker holding the socket might be able to offload the waiting task to the listener thread, that in turn will re-assign it to the first idle worker thread available once an event will be raised for the socket (for example, "the socket is now writable"). Please check the Limitations section for more information.
Keep-alive
Keep Alive handling is the most basic improvement from the worker MPM. Once a worker thread finishes to flush the response to the client, it can offload the socket handling to the listener thread, that in turn will wait for any event from the OS, like "the socket is readable". If any new request comes from the client, then the listener will forward it to the first worker thread available. Conversely, if the KeepAliveTimeout occurs then the socket will be closed by the listener. In this way, the worker threads are not responsible for idle sockets, and they can be re-used to serve other requests.
Closing
Sometimes the MPM needs to perform a lingering close, namely sending back an early error to the client while it is still transmitting data to httpd. Sending the response and then closing the connection immediately is not the correct thing to do since the client (still trying to send the rest of the request) would get a connection reset and could not read the httpd's response. The lingering close is time-bounded, but it can take a relatively long time, so it's offloaded to a worker thread (including the shutdown hooks and real socket close). From 2.4.28 onward, this is also the case when connections finally timeout (the listener thread never handles connections besides waiting for and dispatching their events).

These improvements are valid for both HTTP/HTTPS connections.

Graceful process termination and Scoreboard usage

This mpm showed some scalability bottlenecks in the past, leading to the following error: "scoreboard is full, not at MaxRequestWorkers". MaxRequestWorkers limits the number of simultaneous requests that will be served at any given time and also the number of allowed processes (MaxRequestWorkers / ThreadsPerChild); meanwhile, the Scoreboard is a representation of all the running processes and the status of their worker threads. If the scoreboard is full (so all the threads have a state that is not idle) but the number of active requests served is not MaxRequestWorkers, it means that some of them are blocking new requests that could be served but that are queued instead (up to the limit imposed by ListenBacklog). Most of the time, the threads are stuck in the Graceful state, namely they are waiting to finish their work with a TCP connection to safely terminate and free up a scoreboard slot (for example, handling long-running requests, slow clients or connections with keep-alive enabled). Two scenarios are very common:

From 2.4.24 onward, mpm-event is smarter and it is able to handle graceful terminations in a much better way. Some of the improvements are:

The behavior described in the last point is completely observable via mod_status in the connection summary table through two new columns: "Slot" and "Stopping". The former indicates the PID and the latter if the process is stopping or not; the extra state "Yes (old gen)" indicates a process still running after a graceful restart.

Limitations

The improved connection handling may not work for certain connection filters that have declared themselves as incompatible with event. In these cases, this MPM will fall back to the behavior of the worker MPM and reserve one worker thread per connection. All modules shipped with the server are compatible with the event MPM.

A similar restriction is currently present for requests involving an output filter that needs to read and/or modify the whole response body. If the connection to the client blocks while the filter is processing the data, and the amount of data produced by the filter is too big to be buffered in memory, the thread used for the request is not freed while httpd waits until the pending data is sent to the client.
To illustrate this point, we can think about the following two situations: serving a static asset (like a CSS file) versus serving content retrieved from FCGI/CGI or a proxied server. The former is predictable, namely the event MPM has full visibility on the end of the content and it can use events: the worker thread serving the response content can flush the first bytes until EWOULDBLOCK or EAGAIN is returned, delegating the rest to the listener. This one in turn waits for an event on the socket and delegates the work to flush the rest of the content to the first idle worker thread. Meanwhile in the latter example (FCGI/CGI/proxied content), the MPM can't predict the end of the response and a worker thread has to finish its work before returning the control to the listener. The only alternative is to buffer the response in memory, but it wouldn't be the safest option for the sake of the server's stability and memory footprint.

Background material

The event model was made possible by the introduction of new APIs into the supported operating systems:

Before these new APIs where made available, the traditional select and poll APIs had to be used. Those APIs get slow if used to handle many connections or if the set of connections rate of change is high. The new APIs allow to monitor many more connections, and they perform way better when the set of connections to monitor changes frequently. So these APIs made it possible to write the event MPM, that scales much better with the typical HTTP pattern of many idle connections.

The MPM assumes that the underlying apr_pollset implementation is reasonably threadsafe. This enables the MPM to avoid excessive high level locking, or having to wake up the listener thread in order to send it a keep-alive socket. This is currently only compatible with KQueue and EPoll.

top

Requirements

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.

This MPM does not perform well on older platforms which lack good threading, but the requirement for EPoll or KQueue makes this moot.

top

AsyncRequestWorkerFactor Directive

Description:Limit concurrent connections per process
Syntax:AsyncRequestWorkerFactor factor
Default:2
Context:server config
Status:MPM
Module:event
Compatibility:Available in version 2.3.13 and later

The event MPM handles some connections in an asynchronous way, where request worker threads are only allocated for short periods of time as needed, and other connections with one request worker thread reserved per connection. This can lead to situations where all workers are tied up and no worker thread is available to handle new work on established async connections.

To mitigate this problem, the event MPM does two things:

This directive can be used to fine-tune the per-process connection limit. A process will only accept new connections if the current number of connections (not counting connections in the "closing" state) is lower than:

ThreadsPerChild + (AsyncRequestWorkerFactor * number of idle workers)

An estimation of the maximum concurrent connections across all the processes given an average value of idle worker threads can be calculated with:

(ThreadsPerChild + (AsyncRequestWorkerFactor * number of idle workers)) * ServerLimit

Example

ThreadsPerChild = 10
ServerLimit = 4
AsyncRequestWorkerFactor = 2
MaxRequestWorkers = 40

idle_workers = 4 (average for all the processes to keep it simple)

max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit
                = (10 + (2 * 4)) * 4 = 72

When all the worker threads are idle, then absolute maximum numbers of concurrent connections can be calculared in a simpler way:

(AsyncRequestWorkerFactor + 1) * MaxRequestWorkers

Example

ThreadsPerChild = 10
ServerLimit = 4
MaxRequestWorkers = 40
AsyncRequestWorkerFactor = 2

If all the processes have all threads idle then:

idle_workers = 10

We can calculate the absolute maximum numbers of concurrent connections in two ways:

max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit
                = (10 + (2 * 10)) * 4 = 120

max_connections = (AsyncRequestWorkerFactor + 1) * MaxRequestWorkers
                = (2 + 1) * 40 = 120

Tuning AsyncRequestWorkerFactor requires knowledge about the traffic handled by httpd in each specific use case, so changing the default value requires extensive testing and data gathering from mod_status.

MaxRequestWorkers was called MaxClients prior to version 2.3.13. The above value shows that the old name did not accurately describe its meaning for the event MPM.

AsyncRequestWorkerFactor can take non-integer arguments, e.g "1.5".

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mpm_winnt.html.en0000664000175100017510000002554114737542416021131 0ustar covenercovener mpm_winnt - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache MPM winnt

Available Languages:  de  |  en  |  fr  |  ja 

Description:Multi-Processing Module 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

Capacity is configured using the ThreadsPerChild directive, which sets the maximum number of concurrent client connections.

By default, this MPM uses advanced Windows APIs for accepting new client connections. In some configurations, third-party products may interfere with this implementation, with the following messages written to the web server log:

Child: Encountered too many AcceptEx faults accepting client connections.
winnt_mpm: falling back to 'AcceptFilter none'.

The MPM falls back to a safer implementation, but some client requests were not processed correctly. In order to avoid this error, use AcceptFilter with accept filter none.

AcceptFilter http none
AcceptFilter https none

In Apache httpd 2.0 and 2.2, Win32DisableAcceptEx was used for this purpose.

The WinNT MPM differs from the Unix MPMs such as worker and event in several areas:

Support Apache!

Directives

Bugfix checklist

See also

Available Languages:  de  |  en  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/prefork.html.en0000664000175100017510000004012314737542416020562 0ustar covenercovener prefork - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache MPM prefork

Available Languages:  de  |  en  |  fr  |  ja  |  tr 

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. Each server process may answer incoming requests, and a parent process manages the size of the server pool. 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 MaxRequestWorkers 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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

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 httpd 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 MaxRequestWorkers regulate how the parent process creates children to serve requests. In general, Apache httpd 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 MaxRequestWorkers, while sites with limited memory may need to decrease MaxRequestWorkers 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 httpd as a less-privileged user. The User and Group directives are used to set the privileges of the Apache httpd 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.

MaxConnectionsPerChild controls how frequently the server recycles processes by killing old ones and launching new ones.

This MPM uses the mpm-accept mutex to serialize access to incoming connections when subject to the thundering herd problem (generally, when there are multiple listening sockets). The implementation aspects of this mutex can be configured with the Mutex directive. The performance hints documentation has additional information about this mutex.

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 HTTP Server 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: 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.

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  |  fr  |  ja  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/directive-dict.html.en0000664000175100017510000004345414737241666022026 0ustar covenercovener Terms Used to Describe Directives - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Terms Used to Describe Directives

Available Languages:  en  |  es  |  fr  |  ja  |  ko  |  tr 

This document describes the terms that are used to describe each Apache configuration directive.

Support Apache!

See also

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>, <If>, 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  |  es  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_actions.html.en0000664000175100017510000003134114737241666021416 0ustar covenercovener mod_actions - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_actions

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

Description:Execute 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.

Support Apache!

Directives

Bugfix checklist

See also

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.

Example: MIME type

# Requests for files of a particular MIME content type:
Action image/gif /cgi-bin/images.cgi

In this example, requests for files with a MIME content type of image/gif will be handled by the specified cgi script /cgi-bin/images.cgi.

Example: File extension

# Files of a particular file extension
AddHandler my-file-type .xyz
Action my-file-type "/cgi-bin/program.cgi"

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

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

# All GET requests go here
Script GET "/cgi-bin/search"

# A CGI PUT handler
Script PUT "/~bob/put.cgi"

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

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_access_compat.html.en0000664000175100017510000007064314737241666022572 0ustar covenercovener mod_access_compat - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_access_compat

Available Languages:  en  |  fr  |  ja 

Description:Group authorizations based on host (name or IP address)
Status:Extension
Module Identifier:access_compat_module
Source File:mod_access_compat.c
Compatibility:Available in Apache HTTP Server 2.3 as a compatibility module with previous versions of Apache httpd 2.x. The directives provided by this module have been deprecated by the new authz refactoring. Please see mod_authz_host

Summary

The directives provided by mod_access_compat 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.

Note

The directives provided by mod_access_compat have been deprecated by mod_authz_host. Mixing old directives like Order, Allow or Deny with new ones like Require is technically possible but discouraged. This module was created to support configurations containing only old directives to facilitate the 2.4 upgrade. Please check the upgrading guide for more information.

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.

Merging of configuration sections

When any directive provided by this module is used in a new configuration section, no directives provided by this module are inherited from previous configuration sections.

Support Apache!

Directives

Bugfix checklist

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:Extension
Module:mod_access_compat

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
Allow from example.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.example.org but it will not match fooexample.org. This configuration will cause Apache httpd to perform a double 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
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
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
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
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 2001:db8::a00:20ff:fea7:ccea
Allow from 2001:db8::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. When Allow from env=!env-variable is specified, then the request is allowed access if the environment variable env-variable doesn't exist. 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.

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.

Merging of configuration sections

When any directive provided by this module is used in a new configuration section, no directives provided by this module are inherited from previous configuration sections.

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:Extension
Module:mod_access_compat

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:Extension
Module:mod_access_compat

The Order directive, along with the Allow and Deny directives, controls a three-pass access control system. The first pass processes either all Allow or all Deny directives, as specified by the Order directive. The second pass parses the rest of the directives (Deny or Allow). The third pass applies to all requests which do not match either of the first two.

Note that all Allow and Deny directives are processed, unlike a typical firewall, where only the first match is used. The last match is effective (also unlike a typical firewall). Additionally, the order in which lines appear in the configuration files is not significant -- all Allow lines are processed as one group, all Deny lines are considered as another, and the default state is considered by itself.

Ordering is one of:

Allow,Deny
First, all Allow directives are evaluated; at least one must match, or the request is rejected. Next, all Deny directives are evaluated. If any matches, the request is rejected. Last, any requests which do not match an Allow or a Deny directive are denied by default.
Deny,Allow
First, all Deny directives are evaluated; if any match, the request is denied unless it also matches an Allow directive. Any requests which do not match any Allow or Deny directives are permitted.
Mutual-failure
This order has the same effect as Order Allow,Deny and is deprecated in its favor.

Keywords may only be separated by a comma; no whitespace is allowed between them.

Match Allow,Deny result Deny,Allow result
Match Allow only Request allowed Request allowed
Match Deny only Request denied Request denied
No match Default to second directive: Denied Default to second directive: Allowed
Match both Allow & Deny Final match controls: Denied Final match controls: Allowed

In the following example, all hosts in the example.org domain are allowed access; all other hosts are denied access.

Order Deny,Allow
Deny from all
Allow from example.org

In the next example, all hosts in the example.org domain are allowed access, except for the hosts which are in the foo.example.org subdomain, who are denied access. All hosts not in the example.org domain are denied access because the default state is to Deny access to the server.

Order Allow,Deny
Allow from example.org
Deny from foo.example.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 example.org will be evaluated last and will override the Deny from foo.example.org. All hosts not in the example.org domain will also be allowed access because the default state is 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 is 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.

Merging of configuration sections

When any directive provided by this module is used in a new configuration section, no directives provided by this module are inherited from previous configuration sections.

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:Extension
Module:mod_access_compat
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

Another frequent use of the Satisfy directive is to relax access restrictions for a subdirectory:

<Directory "/var/www/private">
    Require valid-user
</Directory>

<Directory "/var/www/private/public">
    Allow from all
    Satisfy Any
</Directory>

In the above example, authentication will be required for the /var/www/private directory, but will not be required for the /var/www/private/public directory.

Since version 2.0.51 Satisfy directives can be restricted to particular methods by <Limit> and <LimitExcept> sections.

Merging of configuration sections

When any directive provided by this module is used in a new configuration section, no directives provided by this module are inherited from previous configuration sections.

See also

Available Languages:  en  |  fr  |  ja 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_allowmethods.html.en0000664000175100017510000002013614737241666022460 0ustar covenercovener mod_allowmethods - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_allowmethods

Available Languages:  en  |  fr 

Description:Easily restrict what HTTP methods can be used on the server
Status:Experimental
Module Identifier:allowmethods_module
Source File:mod_allowmethods.c
Compatibility:Available in Apache 2.3 and later

Summary

This module makes it easy to restrict what HTTP methods can be used on a server. The most common configuration would be:

<Location "/">
   AllowMethods GET POST OPTIONS
</Location>
Support Apache!

Directives

Bugfix checklist

See also

top

AllowMethods Directive

Description:Restrict access to the listed HTTP methods
Syntax:AllowMethods reset|HTTP-method [HTTP-method]...
Default:AllowMethods reset
Context:directory
Status:Experimental
Module:mod_allowmethods

The HTTP-methods are case sensitive and are generally, as per RFC, given in upper case. The GET and HEAD methods are treated as equivalent. The reset keyword can be used to turn off mod_allowmethods in a deeper nested context:

<Location "/svn">
   AllowMethods reset
</Location>

Caution

The TRACE method cannot be denied by this module; use TraceEnable instead.

mod_allowmethods was written to replace the rather kludgy implementation of Limit and LimitExcept.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_digest.html.en0000664000175100017510000005016514737241666022263 0ustar covenercovener mod_auth_digest - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_auth_digest

Available Languages:  en  |  fr  |  ko 

Description:User authentication using MD5 Digest Authentication
Status:Extension
Module Identifier:auth_digest_module
Source File:mod_auth_digest.c

Summary

This module implements HTTP Digest Authentication (RFC2617), and provides an alternative to mod_auth_basic where the password is not transmitted as cleartext. However, this does not lead to a significant security advantage over basic authentication. On the other hand, the password storage on the server is much less secure with digest authentication than with basic authentication. Therefore, using basic auth and encrypting the whole connection using mod_ssl is a much better alternative.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Using Digest Authentication

To use MD5 Digest authentication, configure the location to be protected as shown in the below example:

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>

AuthDigestDomain should list the locations that will be protected by this configuration.

The password file referenced in the AuthUserFile directive may be created and managed using the htdigest tool.

Note

Digest authentication was intended to be more secure than basic authentication, but no longer fulfills that design goal. A man-in-the-middle attacker can trivially force the browser to downgrade to basic authentication. And even a passive eavesdropper can brute-force the password using today's graphics hardware, because the hashing algorithm used by digest authentication is too fast. Another problem is that the storage of the passwords on the server is insecure. The contents of a stolen htdigest file can be used directly for digest authentication. Therefore using mod_ssl to encrypt the whole connection is strongly recommended.

mod_auth_digest only works properly on platforms where APR supports shared memory.

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

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

AuthDigestNonceLifetime Directive

Description:How long the server nonce is valid
Syntax:AuthDigestNonceLifetime seconds
Default:AuthDigestNonceLifetime 300
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
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 provider-name [provider-name] ...
Default:AuthDigestProvider file
Context:directory, .htaccess
Override:AuthConfig
Status:Extension
Module:mod_auth_digest

The AuthDigestProvider directive sets which provider is used to authenticate the users for this location. The default file provider is implemented by the mod_authn_file module. Make sure that the chosen provider module is present in the server.

See mod_authn_dbm, mod_authn_file, mod_authn_dbd and mod_authn_socache for providers.

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:Extension
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:Extension
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 dependent 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 follow the number with 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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_core.html.en0000664000175100017510000004065614737241666022116 0ustar covenercovener mod_authn_core - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authn_core

Available Languages:  en  |  fr 

Description:Core Authentication
Status:Base
Module Identifier:authn_core_module
Source File:mod_authn_core.c
Compatibility:Available in Apache 2.3 and later

Summary

This module provides core authentication capabilities to allow or deny access to portions of the web site. mod_authn_core provides directives that are common to all authentication providers.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Creating Authentication Provider Aliases

Extended authentication providers can 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.

Examples

This example checks for passwords in two different text files.

Checking multiple text password files

# Check here first
<AuthnProviderAlias file file1>
    AuthUserFile "/www/conf/passwords1"
</AuthnProviderAlias>

# Then check here
<AuthnProviderAlias file file2>   
    AuthUserFile "/www/conf/passwords2"
</AuthnProviderAlias>

<Directory "/var/web/pages/secure">
    AuthBasicProvider file1 file2
    
    AuthType Basic
    AuthName "Protected Area"
    Require valid-user
</Directory>

The example below creates two different ldap authentication provider aliases based on the ldap provider. This allows a single authenticated location to be serviced by multiple ldap hosts:

Checking multiple LDAP servers

<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">
    AuthBasicProvider ldap-other-alias  ldap-alias1
    
    AuthType Basic
    AuthName "LDAP Protected Place"
    Require valid-user
    # Note that Require ldap-* would not work here, since the 
    # AuthnProviderAlias does not provide the config to authorization providers
    # that are implemented in the same module as the authentication provider.
</Directory>
top

AuthName Directive

Description:Authorization realm for use in HTTP authentication
Syntax:AuthName auth-domain
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authn_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.

From 2.4.55, expression syntax can be used inside the directive to produce the name dynamically.

For example:

AuthName "%{HTTP_HOST}"

See also

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
Status:Base
Module:mod_authn_core

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

This directive has no affect on authorization, even for modules that provide both authentication and authorization.
top

AuthType Directive

Description:Type of user authentication
Syntax:AuthType None|Basic|Digest|Form
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authn_core

This directive selects the type of user authentication for a directory. The authentication types available are None, Basic (implemented by mod_auth_basic), Digest (implemented by mod_auth_digest), and Form (implemented by mod_auth_form).

To implement authentication, you must also use the AuthName and Require directives. In addition, the server must have an authentication-provider module such as mod_authn_file and an authorization module such as mod_authz_user.

The authentication type None disables authentication. When authentication is enabled, it is normally inherited by each subsequent configuration section, unless a different authentication type is specified. If no authentication is desired for a subsection of an authenticated section, the authentication type None may be used; in the following example, clients may access the /www/docs/public directory without authenticating:

<Directory "/www/docs">
    AuthType Basic
    AuthName Documents
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require valid-user
</Directory>

<Directory "/www/docs/public">
    AuthType None
    Require all granted
</Directory>

From 2.4.55, expression syntax can be used inside the directive to specify the type dynamically.

When disabling authentication, note that clients which have already authenticated against another portion of the server's document tree will typically continue to send authentication HTTP headers or cookies with each request, regardless of whether the server actually requires authentication for every resource.

See also

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_file.html.en0000664000175100017510000002665414737241666022107 0ustar covenercovener mod_authn_file - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authn_file

Available Languages:  en  |  fr  |  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.

Support Apache!

Directives

Bugfix checklist

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 encrypted password format depends on which authentication frontend (e.g. mod_auth_basic or mod_auth_digest) is being used. See Password Formats for more information.

For mod_auth_basic, use the utility htpasswd which is installed as part of the binary distribution, or which can be found in src/support. 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.

For mod_auth_digest, 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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_alias.html.en0000664000175100017510000012126514737241666021054 0ustar covenercovener mod_alias - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_alias

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

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.

When the Alias, ScriptAlias and Redirect directives are used within a <Location> or <LocationMatch> section, expression syntax can be used to manipulate the destination path or URL.

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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Order of Processing

Aliases and Redirects occurring 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.

When the Alias, ScriptAlias and Redirect directives are used within a <Location> or <LocationMatch> section, these directives will take precedence over any globally defined Alias, ScriptAlias and Redirect directives.

top

Alias Directive

Description:Maps URLs to filesystem locations
Syntax:Alias [URL-path] file-path|directory-path
Context:server config, virtual host, directory
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. The URL-path is case-sensitive, even on case-insensitive file systems.

Alias "/image" "/ftp/pub/image"

A request for http://example.com/image/foo.gif would cause the server to return the file /ftp/pub/image/foo.gif. Only complete path segments are matched, so the above alias would not match a request for http://example.com/imagefoo.gif. For more complex matching using regular expressions, see the AliasMatch directive.

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, as it lacks that trailing /. Likewise, if you omit the slash on the URL-path then you must also omit it from the file-path.

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.

Alias "/image" "/ftp/pub/image"
<Directory "/ftp/pub/image">
    Require all granted
</Directory>

Any number slashes in the URL-path parameter matches any number of slashes in the requested URL-path.

If the Alias directive is used within a <Location> or <LocationMatch> section the URL-path is omitted, and the file-path is interpreted using expression syntax.
This syntax is available in Apache 2.4.19 and later.

<Location "/image">
    Alias "/ftp/pub/image"
</Location>
<LocationMatch "/error/(?<NUMBER>[0-9]+)">
    Alias "/usr/local/apache/errors/%{env:MATCH_NUMBER}.html"
</LocationMatch>

Note that when the AliasPreservePath directive is on, the full path is mapped to the destination. When the directive is off, all URLs are mapped to the single target URL.

# /files/foo and /files/bar mapped to /ftp/pub/files/foo and /ftp/pub/files/bar
<Location "/files">
    AliasPreservePath on
    Alias "/ftp/pub/files"
</Location>
# /errors/foo and /errors/bar mapped to /var/www/errors.html
<Location "/errors">
    AliasPreservePath off
    Alias "/var/www/errors.html"
</Location>
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 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$2"

The full range of regular expression power is available. For example, it is possible to construct an alias with case-insensitive matching of the URL-path:

AliasMatch "(?i)^/image(.*)" "/ftp/pub/image$1"

One subtle difference between Alias and AliasMatch is that Alias will automatically copy any additional part of the URI, past the part that matched, onto the end of the file path on the right side, while AliasMatch will not. This means that in almost all cases, you will want the regular expression to match the entire request URI from beginning to end, and to use substitution on the right side.

In other words, just changing Alias to AliasMatch will not have the same effect. At a minimum, you need to add ^ to the beginning of the regular expression and add (.*)$ to the end, and add $1 to the end of the replacement.

For example, suppose you want to replace this with AliasMatch:

Alias "/image/" "/ftp/pub/image/"

This is NOT equivalent - don't do this! This will send all requests that have /image/ anywhere in them to /ftp/pub/image/:

AliasMatch "/image/" "/ftp/pub/image/"

This is what you need to get the same effect:

AliasMatch "^/image/(.*)$" "/ftp/pub/image/$1"

Of course, there's no point in using AliasMatch where Alias would work. AliasMatch lets you do more complicated things. For example, you could serve different kinds of files from different directories:

AliasMatch "^/image/(.*)\.jpg$" "/files/jpg.images/$1.jpg"
AliasMatch "^/image/(.*)\.gif$" "/files/gif.images/$1.gif"

Multiple leading slashes in the requested URL are discarded by the server before directives from this module compares against the requested URL-path.

top

AliasPreservePath Directive

Description:Map the full path after the alias in a location.
Syntax:AliasPreservePath OFF|ON
Default:AliasPreservePath OFF
Context:server config, virtual host, directory
Status:Base
Module:mod_alias
Compatibility:2.4.58 and later

When using the two parameter version of the Alias directive, the full path after the alias is preserved. When using the one parameter version of the Alias directive inside a Location directive, the full path is dropped, and all URLs are mapped to the target expression.

To make the one parameter version of the Alias directive preserve paths in the same way that the two parameter version of the Alias directive, enable this setting.

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 by asking the client to refetch the resource at the new location.

The old URL-path is a case-sensitive (%-decoded) path beginning with a slash. A relative path is not allowed.

The new URL may be either an absolute URL beginning with a scheme and hostname, or a URL-path beginning with a slash. In this latter case the scheme and hostname of the current server will be added.

Then any request beginning with URL-path will return a redirect request to the client at the location of the target URL. Additional path information beyond the matched URL-path will be appended to the target URL.

# Redirect to a URL on a different host
Redirect "/service" "http://foo2.example.com/service"

# Redirect to a URL on the same host
Redirect "/one" "/two"

If the client requests http://example.com/service/foo.txt, it will be told to access http://foo2.example.com/service/foo.txt instead. This includes requests with GET parameters, such as http://example.com/service/foo.pl?q=23&a=42, it will be redirected to http://foo2.example.com/service/foo.pl?q=23&a=42. Note that POSTs will be discarded.
Only complete path segments are matched, so the above example would not match a request for http://example.com/servicefoo.txt. For more complex matching using the expression syntax, omit the URL-path argument as described below. Alternatively, for matching using regular expressions, see the RedirectMatch directive.

Note

Redirect directives take precedence over Alias and ScriptAlias directives, irrespective of their ordering in the configuration file. Redirect directives inside a Location take precedence over Redirect and Alias directives with an URL-path.

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. If the status is not between 300 and 399, the URL argument must be omitted. The status must be a valid HTTP status code, known to the Apache HTTP Server (see the function send_error_response in http_protocol.c).

Redirect permanent "/one" "http://example.com/two"
Redirect 303 "/three" "http://example.com/other"

If the Redirect directive is used within a <Location> or <LocationMatch> section with the URL-path omitted, then the URL parameter will be interpreted using expression syntax.
This syntax is available in Apache 2.4.19 and later.

<Location "/one">
    Redirect permanent "http://example.com/two"
</Location>
<Location "/three">
    Redirect 303 "http://example.com/other"
</Location>
<LocationMatch "/error/(?<NUMBER>[0-9]+)">
    Redirect permanent "http://example.com/errors/%{env:MATCH_NUMBER}.html"
</LocationMatch>
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 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://other.example.com$1.jpg"

The considerations related to the difference between Alias and AliasMatch also apply to the difference between Redirect and RedirectMatch. See AliasMatch for details.

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

RedirectRelative Directive

Description:Allows relative redirect targets.
Syntax:RedirectRelative On|Off
Default:RedirectRelative Off
Context:server config, virtual host, directory
Status:Base
Module:mod_alias
Compatibility:2.4.58 and later

By default, if the target URL of a Redirect directive is a relative URL beginning with a '/' character, the server converts it to an absolute URL before responding to the client. By setting RedirectRelative to the value "On", the relative URL is presented to the client directly.

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, directory
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 case-sensitive (%-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.

ScriptAlias "/cgi-bin/" "/web/cgi-bin/"

A request for http://example.com/cgi-bin/foo would cause the server to run the script /web/cgi-bin/foo. This configuration is essentially equivalent to:

Alias "/cgi-bin/" "/web/cgi-bin/"
<Location "/cgi-bin">
    SetHandler cgi-script
    Options +ExecCGI
</Location>

ScriptAlias can also be used in conjunction with a script or handler you have. For example:

ScriptAlias "/cgi-bin/" "/web/cgi-handler.pl"

In this scenario all files requested in /cgi-bin/ will be handled by the file you have configured, this allows you to use your own custom handler. You may want to use this as a wrapper for CGI so that you can add content, or some other bespoke action.

It is safer to avoid placing CGI scripts under the DocumentRoot in order to avoid accidentally revealing their source code if the configuration is ever changed. The ScriptAlias makes this easy by mapping a URL and designating CGI scripts at the same time. If you do choose to place your CGI scripts in a directory already accessible from the web, do not use ScriptAlias. Instead, use <Directory>, SetHandler, and Options as in:
<Directory "/usr/local/apache2/htdocs/cgi-bin">
    SetHandler cgi-script
    Options ExecCGI
</Directory>
This is necessary since multiple URL-paths can map to the same filesystem location, potentially bypassing the ScriptAlias and revealing the source code of the CGI scripts if they are not restricted by a Directory section.

If the ScriptAlias directive is used within a <Location> or <LocationMatch> section with the URL-path omitted, then the URL parameter will be interpreted using expression syntax.
This syntax is available in Apache 2.4.19 and later.

<Location "/cgi-bin">
    ScriptAlias "/web/cgi-bin/"
</Location>
<LocationMatch "/cgi-bin/errors/(?<NUMBER>[0-9]+)">
    ScriptAlias "/web/cgi-bin/errors/%{env:MATCH_NUMBER}.cgi"
</LocationMatch>

See also

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

As for AliasMatch, the full range of regular expression power is available. For example, it is possible to construct an alias with case-insensitive matching of the URL-path:

ScriptAliasMatch "(?i)^/cgi-bin(.*)" "/usr/local/apache/cgi-bin$1"

The considerations related to the difference between Alias and AliasMatch also apply to the difference between ScriptAlias and ScriptAliasMatch. See AliasMatch for details.

Available Languages:  en  |  fr  |  ja  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_basic.html.en0000664000175100017510000004710614737241666022066 0ustar covenercovener mod_auth_basic - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_auth_basic

Available Languages:  en  |  fr  |  ja  |  ko 

Description:Basic HTTP 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. This module should usually be combined with at least one authentication module such as mod_authn_file and one authorization module such as mod_authz_user.

Support Apache!

Directives

Bugfix checklist

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

Normally, each authorization module listed in AuthBasicProvider will attempt to verify the user, and if the user is not found in any provider, access will be denied. Setting the AuthBasicAuthoritative directive explicitly to Off allows for both authentication and authorization to be passed on to other non-provider-based modules if there is no userID or rule matching the supplied userID. This should only be necessary when combining mod_auth_basic with third-party modules that are not configured with the AuthBasicProvider directive. When using such modules, the order of processing is determined in the modules' source code and is not configurable.

top

AuthBasicFake Directive

Description:Fake basic authentication using the given expressions for username and password
Syntax:AuthBasicFake off|username [password]
Default:none
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_auth_basic
Compatibility:Apache HTTP Server 2.4.5 and later

The username and password specified are combined into an Authorization header, which is passed to the server or service behind the webserver. Both the username and password fields are interpreted using the expression parser, which allows both the username and password to be set based on request parameters.

If the password is not specified, the default value "password" will be used. To disable fake basic authentication for an URL space, specify "AuthBasicFake off".

In this example, we pass a fixed username and password to a backend server.

Fixed Example

<Location "/demo">
    AuthBasicFake demo demopass
</Location>

In this example, we pass the email address extracted from a client certificate, extending the functionality of the FakeBasicAuth option within the SSLOptions directive. Like the FakeBasicAuth option, the password is set to the fixed string "password".

Certificate Example

<Location "/secure">
    AuthBasicFake "%{SSL_CLIENT_S_DN_Email}"
</Location>

Extending the above example, we generate a password by hashing the email address with a fixed passphrase, and passing the hash to the backend server. This can be used to gate into legacy systems that do not support client certificates.

Password Example

<Location "/secure">
    AuthBasicFake "%{SSL_CLIENT_S_DN_Email}" "%{sha1:passphrase-%{SSL_CLIENT_S_DN_Email}}"
</Location>

Exclusion Example

<Location "/public">
    AuthBasicFake off
</Location>
top

AuthBasicProvider Directive

Description:Sets the authentication provider(s) for this location
Syntax:AuthBasicProvider provider-name [provider-name] ...
Default:AuthBasicProvider file
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. The default file provider is implemented by the mod_authn_file module. Make sure that the chosen provider module is present in the server.

Example

<Location "/secure">
    AuthType basic
    AuthName "private area"
    AuthBasicProvider  dbm
    AuthDBMType        SDBM
    AuthDBMUserFile    "/www/etc/dbmpasswd"
    Require            valid-user
</Location>

Providers are queried in order until a provider finds a match for the requested username, at which point this sole provider will attempt to check the password. A failure to verify the password does not result in control being passed on to subsequent providers.

Providers are implemented by mod_authn_dbm, mod_authn_file, mod_authn_dbd, mod_authnz_ldap and mod_authn_socache.

top

AuthBasicUseDigestAlgorithm Directive

Description:Check passwords against the authentication providers as if Digest Authentication was in force instead of Basic Authentication.
Syntax:AuthBasicUseDigestAlgorithm MD5|Off
Default:AuthBasicUseDigestAlgorithm Off
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_auth_basic
Compatibility:Apache HTTP Server 2.4.7 and later

Normally, when using Basic Authentication, the providers listed in AuthBasicProvider attempt to verify a user by checking their data stores for a matching username and associated password. The stored passwords are usually encrypted, but not necessarily so; each provider may choose its own storage scheme for passwords.

When using AuthDigestProvider and Digest Authentication, providers perform a similar check to find a matching username in their data stores. However, unlike in the Basic Authentication case, the value associated with each stored username must be an encrypted string composed from the username, realm name, and password. (See RFC 2617, Section 3.2.2.2 for more details on the format used for this encrypted string.)

As a consequence of the difference in the stored values between Basic and Digest Authentication, converting from Digest Authentication to Basic Authentication generally requires that all users be assigned new passwords, as their existing passwords cannot be recovered from the password storage scheme imposed on those providers which support Digest Authentication.

Setting the AuthBasicUseDigestAlgorithm directive to MD5 will cause the user's Basic Authentication password to be checked using the same encrypted format as for Digest Authentication. First a string composed from the username, realm name, and password is hashed with MD5; then the username and this encrypted string are passed to the providers listed in AuthBasicProvider as if AuthType was set to Digest and Digest Authentication was in force.

Through the use of AuthBasicUseDigestAlgorithm a site may switch from Digest to Basic Authentication without requiring users to be assigned new passwords.

The inverse process of switching from Basic to Digest Authentication without assigning new passwords is generally not possible. Only if the Basic Authentication passwords have been stored in plain text or with a reversible encryption scheme will it be possible to recover them and generate a new data store following the Digest Authentication password storage scheme.
Only providers which support Digest Authentication will be able to authenticate users when AuthBasicUseDigestAlgorithm is set to MD5. Use of other providers will result in an error response and the client will be denied access.

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_anon.html.en0000664000175100017510000004077414737241666022122 0ustar covenercovener mod_authn_anon - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authn_anon

Available Languages:  en  |  fr  |  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.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Example

The example below is combined with "normal" htpasswd-file based authentication and allows users in additionally as 'guests' with the following properties:

Example

<Directory "/var/www/html/private">
    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
    
    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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_dbm.html.en0000664000175100017510000003127614737241666021726 0ustar covenercovener mod_authn_dbm - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authn_dbm

Available Languages:  en  |  fr  |  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.

Support Apache!

Directives

Bugfix checklist

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.

For example, in order to enable the support for Berkeley DB (correspondent to the db type) the --with-berkeley-db option needs to be added to httpd's configure to generate the necessary DSO.

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.

The encrypted password format depends on which authentication frontend (e.g. mod_auth_basic or mod_auth_digest) is being used. See Password Formats for more information.

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. Another tool for maintaining the DBM files is the included program htdbm.

Available Languages:  en  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authnz_fcgi.html.en0000664000175100017510000006575614737241666022300 0ustar covenercovener mod_authnz_fcgi - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authnz_fcgi

Available Languages:  en  |  fr 

Description:Allows a FastCGI authorizer application to handle Apache httpd authentication and authorization
Status:Extension
Module Identifier:authnz_fcgi_module
Source File:mod_authnz_fcgi.c
Compatibility:Available in version 2.4.10 and later

Summary

This module allows FastCGI authorizer applications to authenticate users and authorize access to resources. It supports generic FastCGI authorizers which participate in a single phase for authentication and authorization as well as Apache httpd-specific authenticators and authorizors which participate in one or both phases.

FastCGI authorizers can authenticate using user id and password, such as for Basic authentication, or can authenticate using arbitrary mechanisms.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Invocation modes

The invocation modes for FastCGI authorizers supported by this module are distinguished by two characteristics, type and auth mechanism.

Type is simply authn for authentication, authz for authorization, or authnz for combined authentication and authorization.

Auth mechanism refers to the Apache httpd configuration mechanisms and processing phases, and can be AuthBasicProvider, Require, or check_user_id. The first two of these correspond to the directives used to enable participation in the appropriate processing phase.

Descriptions of each mode:

Type authn, mechanism AuthBasicProvider
In this mode, FCGI_ROLE is set to AUTHORIZER and FCGI_APACHE_ROLE is set to AUTHENTICATOR. The application must be defined as provider type authn using AuthnzFcgiDefineProvider and enabled with AuthBasicProvider. When invoked, the application is expected to authenticate the client using the provided user id and password. Example application:
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHENTICATOR";
    die if $ENV{'FCGI_ROLE'}        ne "AUTHORIZER";
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" ) {
        print "Status: 200\n";
        print "Variable-AUTHN_1: authn_01\n";
        print "Variable-AUTHN_2: authn_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
    }
}
Example configuration:
AuthnzFcgiDefineProvider authn FooAuthn fcgi://localhost:10102/
<Location "/protected/">
  AuthType Basic
  AuthName "Restricted"
  AuthBasicProvider FooAuthn
  Require ...
</Location>
Type authz, mechanism Require
In this mode, FCGI_ROLE is set to AUTHORIZER and FCGI_APACHE_ROLE is set to AUTHORIZER. The application must be defined as provider type authz using AuthnzFcgiDefineProvider. When invoked, the application is expected to authorize the client using the provided user id and other request data. Example application:
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHORIZER";
    die if $ENV{'FCGI_ROLE'}        ne "AUTHORIZER";
    die if $ENV{'REMOTE_PASSWD'};

    print STDERR "This text is written to the web server error log.\n";

    if ($ENV{'REMOTE_USER'} eq "foo1") {
        print "Status: 200\n";
        print "Variable-AUTHZ_1: authz_01\n";
        print "Variable-AUTHZ_2: authz_02\n";
        print "\n";
    }
    else {
        print "Status: 403\n\n";
    }
}
Example configuration:
AuthnzFcgiDefineProvider authz FooAuthz fcgi://localhost:10103/
<Location "/protected/">
  AuthType ...
  AuthName ...
  AuthBasicProvider ...
  Require FooAuthz
</Location>
Type authnz, mechanism AuthBasicProvider + Require
In this mode, which supports the web server-agnostic FastCGI AUTHORIZER protocol, FCGI_ROLE is set to AUTHORIZER and FCGI_APACHE_ROLE is not set. The application must be defined as provider type authnz using AuthnzFcgiDefineProvider. The application is expected to handle both authentication and authorization in the same invocation using the user id, password, and other request data. The invocation occurs during the Apache httpd API authentication phase. If the application returns 200 and the same provider is invoked during the authorization phase (via Require), mod_authnz_fcgi will return success for the authorization phase without invoking the application. Example application:
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'};
    die if $ENV{'FCGI_ROLE'} ne "AUTHORIZER";
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" &&
        $ENV{'REQUEST_URI'} =~ m%/bar/.*%) {
        print "Status: 200\n";
        print "Variable-AUTHNZ_1: authnz_01\n";
        print "Variable-AUTHNZ_2: authnz_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
    }
}
Example configuration:
AuthnzFcgiDefineProvider authnz FooAuthnz fcgi://localhost:10103/
<Location "/protected/">
  AuthType Basic
  AuthName "Restricted"
  AuthBasicProvider FooAuthnz
  Require FooAuthnz
</Location>
Type authn, mechanism check_user_id
In this mode, FCGI_ROLE is set to AUTHORIZER and FCGI_APACHE_ROLE is set to AUTHENTICATOR. The application must be defined as provider type authn using AuthnzFcgiDefineProvider. AuthnzFcgiCheckAuthnProvider specifies when it is called. Example application:
#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while ($request->Accept() >= 0) {
    die if $ENV{'FCGI_APACHE_ROLE'} ne "AUTHENTICATOR";
    die if $ENV{'FCGI_ROLE'} ne "AUTHORIZER";

    # This authorizer assumes that the RequireBasicAuth option of 
    # AuthnzFcgiCheckAuthnProvider is On:
    die if !$ENV{'REMOTE_PASSWD'};
    die if !$ENV{'REMOTE_USER'};

    print STDERR "This text is written to the web server error log.\n";

    if ( ($ENV{'REMOTE_USER' } eq "foo" || $ENV{'REMOTE_USER'} eq "foo1") &&
        $ENV{'REMOTE_PASSWD'} eq "bar" ) {
        print "Status: 200\n";
        print "Variable-AUTHNZ_1: authnz_01\n";
        print "Variable-AUTHNZ_2: authnz_02\n";
        print "\n";
    }
    else {
        print "Status: 401\n\n";
        # If a response body is written here, it will be returned to
        # the client.
    }
}
Example configuration:
AuthnzFcgiDefineProvider authn FooAuthn fcgi://localhost:10103/
<Location "/protected/">
  AuthType ...
  AuthName ...
  AuthnzFcgiCheckAuthnProvider FooAuthn \
                               Authoritative On \
                               RequireBasicAuth Off \
                               UserExpr "%{reqenv:REMOTE_USER}"
  Require ...
</Location>
top

Additional examples

  1. If your application supports the separate authentication and authorization roles (AUTHENTICATOR and AUTHORIZER), define separate providers as follows, even if they map to the same application:
    AuthnzFcgiDefineProvider authn  FooAuthn  fcgi://localhost:10102/
    AuthnzFcgiDefineProvider authz  FooAuthz  fcgi://localhost:10102/
    Specify the authn provider on AuthBasicProvider and the authz provider on Require:
    AuthType Basic
    AuthName "Restricted"
    AuthBasicProvider FooAuthn
    Require FooAuthz
  2. If your application supports the generic AUTHORIZER role (authentication and authorizer in one invocation), define a single provider as follows:
    AuthnzFcgiDefineProvider authnz FooAuthnz fcgi://localhost:10103/
    Specify the authnz provider on both AuthBasicProvider and Require:
    AuthType Basic
    AuthName "Restricted"
    AuthBasicProvider FooAuthnz
    Require FooAuthnz
top

Limitations

The following are potential features which are not currently implemented:

Apache httpd access checker
The Apache httpd API access check phase is a separate phase from authentication and authorization. Some other FastCGI implementations implement this phase, which is denoted by the setting of FCGI_APACHE_ROLE to ACCESS_CHECKER.
Local (Unix) sockets or pipes
Only TCP sockets are currently supported.
Support for mod_authn_socache
mod_authn_socache interaction should be implemented for applications which participate in Apache httpd-style authentication.
Support for digest authentication using AuthDigestProvider
This is expected to be a permanent limitation as there is no authorizer flow for retrieving a hash.
Application process management
This is expected to be permanently out of scope for this module. Application processes must be controlled by other means. For example, fcgistarter can be used to start them.
AP_AUTH_INTERNAL_PER_URI
All providers are currently registered as AP_AUTH_INTERNAL_PER_CONF, which means that checks are not performed again for internal subrequests with the same access control configuration as the initial request.
Protocol data charset conversion
If mod_authnz_fcgi runs in an EBCDIC compilation environment, all FastCGI protocol data is written in EBCDIC and expected to be received in EBCDIC.
Multiple requests per connection
Currently the connection to the FastCGI authorizer is closed after every phase of processing. For example, if the authorizer handles separate authn and authz phases then two connections will be used.
URI Mapping
URIs from clients can't be mapped, such as with the ProxyPass used with FastCGI responders.
top

Logging

  1. Processing errors are logged at log level error and higher.
  2. Messages written by the application are logged at log level warn.
  3. General messages for debugging are logged at log level debug.
  4. Environment variables passed to the application are logged at log level trace2. The value of the REMOTE_PASSWD variable will be obscured, but any other sensitive data will be visible in the log.
  5. All I/O between the module and the FastCGI application, including all environment variables, will be logged in printable and hex format at log level trace5. All sensitive data will be visible in the log.

LogLevel can be used to configure a log level specific to mod_authnz_fcgi. For example:

LogLevel info authnz_fcgi:trace8
top

AuthnzFcgiCheckAuthnProvider Directive

Description:Enables a FastCGI application to handle the check_authn authentication hook.
Syntax:AuthnzFcgiCheckAuthnProvider provider-name|None option ...
Default:none
Context:directory
Status:Extension
Module:mod_authnz_fcgi

This directive is used to enable a FastCGI authorizer to handle a specific processing phase of authentication or authorization.

Some capabilities of FastCGI authorizers require enablement using this directive instead of AuthBasicProvider:

provider-name
This is the name of a provider defined with AuthnzFcgiDefineProvider.
None
Specify None to disable a provider enabled with this directive in an outer scope, such as in a parent directory.
option
The following options are supported:
Authoritative On|Off (default On)
This controls whether or not other modules are allowed to run when this module has a FastCGI authorizer configured and it fails the request.
DefaultUser userid
When the authorizer returns success and UserExpr is configured and evaluates to an empty string (e.g., authorizer didn't return a variable), this value will be used as the user id. This is typically used when the authorizer has a concept of guest, or unauthenticated, users and guest users are mapped to some specific user id for logging and other purposes.
RequireBasicAuth On|Off (default Off)
This controls whether or not Basic auth is required before passing the request to the authorizer. If required, the authorizer won't be invoked without a user id and password; 401 will be returned for a request without that.
UserExpr expr (no default)
When Basic authentication isn't provided by the client and the authorizer determines the user, this expression, evaluated after calling the authorizer, determines the user. The expression follows ap_expr syntax and must resolve to a string. A typical use is to reference a Variable-XXX setting returned by the authorizer using an option like UserExpr "%{reqenv:XXX}". If this option is specified and the user id can't be retrieved using the expression after a successful authentication, the request will be rejected with a 500 error.
top

AuthnzFcgiDefineProvider Directive

Description:Defines a FastCGI application as a provider for authentication and/or authorization
Syntax:AuthnzFcgiDefineProvider type provider-name backend-address
Default:none
Context:server config
Status:Extension
Module:mod_authnz_fcgi

This directive is used to define a FastCGI application as a provider for a particular phase of authentication or authorization.

type
This must be set to authn for authentication, authz for authorization, or authnz for a generic FastCGI authorizer which performs both checks.
provider-name
This is used to assign a name to the provider which is used in other directives such as AuthBasicProvider and Require.
backend-address
This specifies the address of the application, in the form fcgi://hostname:port/. The application process(es) must be managed independently, such as with fcgistarter.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_asis.html.en0000664000175100017510000002162614737241666020722 0ustar covenercovener mod_asis - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_asis

Available Languages:  en  |  fr  |  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 HTTP Server 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.

Support Apache!

Topics

Directives

This module provides no directives.

Bugfix checklist

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 httpd to the client with almost no changes. In particular, HTTP headers are derived from the file itself according to mod_cgi rules, so an asis file must include valid headers, and may also use the CGI Status: header to determine the HTTP response code. The Content-Length: header will automatically be inserted or, if included, corrected by httpd.

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.example.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.example.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  |  fr  |  ja  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_auth_form.html.en0000664000175100017510000014454314737241666021753 0ustar covenercovener mod_auth_form - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_auth_form

Available Languages:  en  |  fr 

Description:Form authentication
Status:Base
Module Identifier:auth_form_module
Source File:mod_auth_form.c
Compatibility:Available in Apache 2.3 and later

Summary

Warning

Form authentication depends on the mod_session modules, and these modules make use of HTTP cookies, and as such can fall victim to Cross Site Scripting attacks, or expose potentially private information to clients. Please ensure that the relevant risks have been taken into account before enabling the session functionality on your server.

This module allows the use of an HTML login form to restrict access by looking up users in the given providers. HTML forms require significantly more configuration than the alternatives, however an HTML login form can provide a much friendlier experience for end users.

HTTP basic authentication is provided by mod_auth_basic, and HTTP digest authentication is provided by mod_auth_digest. This module should be combined with at least one authentication module such as mod_authn_file and one authorization module such as mod_authz_user.

Once the user has been successfully authenticated, the user's login details will be stored in a session provided by mod_session.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Basic Configuration

To protect a particular URL with mod_auth_form, you need to decide where you will store your session, and you will need to decide what method you will use to authenticate. In this simple example, the login details will be stored in a session based on mod_session_cookie, and authentication will be attempted against a file using mod_authn_file. If authentication is unsuccessful, the user will be redirected to the form login page.

Basic example

<Location "/admin">
    AuthFormProvider file
    AuthUserFile "conf/passwd"
    AuthType form
    AuthName "/admin"
    AuthFormLoginRequiredLocation "http://example.com/login.html"

    Session On
    SessionCookieName session path=/

    Require valid-user
</Location>

The directive AuthType will enable the mod_auth_form authentication when set to the value form. The directives AuthFormProvider and AuthUserFile specify that usernames and passwords should be checked against the chosen file.

The directives Session and SessionCookieName session stored within an HTTP cookie on the browser. For more information on the different options for configuring a session, read the documentation for mod_session.

You can optionally add a SessionCryptoPassphrase to create an encrypted session cookie. This required the additional module mod_session_crypto be loaded.

In the simple example above, a URL has been protected by mod_auth_form, but the user has yet to be given an opportunity to enter their username and password. Options for doing so include providing a dedicated standalone login page for this purpose, or for providing the login page inline.

top

Standalone Login

The login form can be hosted as a standalone page, or can be provided inline on the same page.

When configuring the login as a standalone page, unsuccessful authentication attempts should be redirected to a login form created by the website for this purpose, using the AuthFormLoginRequiredLocation directive. Typically this login page will contain an HTML form, asking the user to provide their usename and password.

Example login form

<form method="POST" action="/dologin.html">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
</form>

The part that does the actual login is handled by the form-login-handler. The action of the form should point at this handler, which is configured within Apache httpd as follows:

Form login handler example

<Location "/dologin.html">
    SetHandler form-login-handler
    AuthFormLoginRequiredLocation "http://example.com/login.html"
    AuthFormLoginSuccessLocation "http://example.com/admin/index.html"
    AuthFormProvider file
    AuthUserFile "conf/passwd"
    AuthType form
    AuthName /admin
    Session On
    SessionCookieName session path=/
</Location>

The URLs specified by the AuthFormLoginRequiredLocation directive will typically point to a page explaining to the user that their login attempt was unsuccessful, and they should try again. The AuthFormLoginSuccessLocation directive specifies the URL the user should be redirected to upon successful login.

Alternatively, the URL to redirect the user to on success can be embedded within the login form, as in the example below. As a result, the same form-login-handler can be reused for different areas of a website.

Example login form with location

<form method="POST" action="/dologin.html">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
  <input type="hidden" name="httpd_location" value="http://example.com/success.html" />
</form>
top

Inline Login

Warning

A risk exists that under certain circumstances, the login form configured using inline login may be submitted more than once, revealing login credentials to the application running underneath. The administrator must ensure that the underlying application is properly secured to prevent abuse. If in doubt, use the standalone login configuration.

As an alternative to having a dedicated login page for a website, it is possible to configure mod_auth_form to authenticate users inline, without being redirected to another page. This allows the state of the current page to be preserved during the login attempt. This can be useful in a situation where a time limited session is in force, and the session times out in the middle of the user request. The user can be re-authenticated in place, and they can continue where they left off.

If a non-authenticated user attempts to access a page protected by mod_auth_form that isn't configured with a AuthFormLoginRequiredLocation directive, a HTTP_UNAUTHORIZED status code is returned to the browser indicating to the user that they are not authorized to view the page.

To configure inline authentication, the administrator overrides the error document returned by the HTTP_UNAUTHORIZED status code with a custom error document containing the login form, as follows:

Basic inline example

AuthFormProvider file
ErrorDocument 401 "/login.shtml"
AuthUserFile "conf/passwd"
AuthType form
AuthName realm
Session On
SessionCookieName session path=/

The error document page should contain a login form with an empty action property, as per the example below. This has the effect of submitting the form to the original protected URL, without the page having to know what that URL is.

Example inline login form

<form method="POST" action="">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
</form>

When the end user has filled in their login details, the form will make an HTTP POST request to the original password protected URL. mod_auth_form will intercept this POST request, and if HTML fields are found present for the username and password, the user will be logged in, and the original password protected URL will be returned to the user as a GET request.

top

Inline Login with Body Preservation

A limitation of the inline login technique described above is that should an HTML form POST have resulted in the request to authenticate or reauthenticate, the contents of the original form posted by the browser will be lost. Depending on the function of the website, this could present significant inconvenience for the end user.

mod_auth_form addresses this by allowing the method and body of the original request to be embedded in the login form. If authentication is successful, the original method and body will be retried by Apache httpd, preserving the state of the original request.

To enable body preservation, add three additional fields to the login form as per the example below.

Example with body preservation

<form method="POST" action="">
  Username: <input type="text" name="httpd_username" value="" />
  Password: <input type="password" name="httpd_password" value="" />
  <input type="submit" name="login" value="Login" />
  
<input type="hidden" name="httpd_method" value="POST" /> <input type="hidden" name="httpd_mimetype" value="application/x-www-form-urlencoded" /> <input type="hidden" name="httpd_body" value="name1=value1&name2=value2" />
</form>

How the method, mimetype and body of the original request are embedded within the login form will depend on the platform and technology being used within the website.

One option is to use the mod_include module along with the KeptBodySize directive, along with a suitable CGI script to embed the variables in the form.

Another option is to render the login form using a CGI script or other dynamic technology.

CGI example

AuthFormProvider file
ErrorDocument 401 "/cgi-bin/login.cgi"
...
top

Logging Out

To enable a user to log out of a particular session, configure a page to be handled by the form-logout-handler. Any attempt to access this URL will cause the username and password to be removed from the current session, effectively logging the user out.

By setting the AuthFormLogoutLocation directive, a URL can be specified that the browser will be redirected to on successful logout. This URL might explain to the user that they have been logged out, and give the user the option to log in again.

Basic logout example

SetHandler form-logout-handler
AuthName realm
AuthFormLogoutLocation "http://example.com/loggedout.html"
Session On
SessionCookieName session path=/

Note that logging a user out does not delete the session; it merely removes the username and password from the session. If this results in an empty session, the net effect will be the removal of that session, but this is not guaranteed. If you want to guarantee the removal of a session, set the SessionMaxAge directive to a small value, like 1 (setting the directive to zero would mean no session age limit).

Basic session expiry example

SetHandler form-logout-handler
AuthFormLogoutLocation "http://example.com/loggedout.html"
Session On
SessionMaxAge 1
SessionCookieName session path=/
top

Usernames and Passwords

Note that form submission involves URLEncoding the form data: in this case the username and password. You should therefore pick usernames and passwords that avoid characters that are URLencoded in form submission, or you may get unexpected results.

top

AuthFormAuthoritative Directive

Description:Sets whether authorization and authentication are passed to lower level modules
Syntax:AuthFormAuthoritative On|Off
Default:AuthFormAuthoritative On
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_auth_form

Normally, each authorization module listed in AuthFormProvider will attempt to verify the user, and if the user is not found in any provider, access will be denied. Setting the AuthFormAuthoritative directive explicitly to Off allows for both authentication and authorization to be passed on to other non-provider-based modules if there is no userID or rule matching the supplied userID. This should only be necessary when combining mod_auth_form with third-party modules that are not configured with the AuthFormProvider directive. When using such modules, the order of processing is determined in the modules' source code and is not configurable.

top

AuthFormBody Directive

Description:The name of a form field carrying the body of the request to attempt on successful login
Syntax:AuthFormBody fieldname
Default:AuthFormBody httpd_body
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormBody directive specifies the name of an HTML field which, if present, will contain the body of the request to submit should login be successful.

By populating the form with fields described by AuthFormMethod, AuthFormMimetype and AuthFormBody, a website can retry a request that may have been interrupted by the login screen, or by a session timeout.

top

AuthFormDisableNoStore Directive

Description:Disable the CacheControl no-store header on the login page
Syntax:AuthFormDisableNoStore On|Off
Default:AuthFormDisableNoStore Off
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormDisableNoStore flag disables the sending of a Cache-Control no-store header with the error 401 page returned when the user is not yet logged in. The purpose of the header is to make it difficult for an ecmascript application to attempt to resubmit the login form, and reveal the username and password to the backend application. Disable at your own risk.

top

AuthFormFakeBasicAuth Directive

Description:Fake a Basic Authentication header
Syntax:AuthFormFakeBasicAuth On|Off
Default:AuthFormFakeBasicAuth Off
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormFakeBasicAuth flag determines whether a Basic Authentication header will be added to the request headers. This can be used to expose the username and password to an underlying application, without the underlying application having to be aware of how the login was achieved.

top

AuthFormLocation Directive

Description:The name of a form field carrying a URL to redirect to on successful login
Syntax:AuthFormLocation fieldname
Default:AuthFormLocation httpd_location
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormLocation directive specifies the name of an HTML field which, if present, will contain a URL to redirect the browser to should login be successful.

top

AuthFormLoginRequiredLocation Directive

Description:The URL of the page to be redirected to should login be required
Syntax:AuthFormLoginRequiredLocation url
Default:none
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later. The use of the expression parser has been added in 2.4.4.

The AuthFormLoginRequiredLocation directive specifies the URL to redirect to should the user not be authorised to view a page. The value is parsed using the ap_expr parser before being sent to the client. By default, if a user is not authorised to view a page, the HTTP response code HTTP_UNAUTHORIZED will be returned with the page specified by the ErrorDocument directive. This directive overrides this default.

Use this directive if you have a dedicated login page to redirect users to.

top

AuthFormLoginSuccessLocation Directive

Description:The URL of the page to be redirected to should login be successful
Syntax:AuthFormLoginSuccessLocation url
Default:none
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later. The use of the expression parser has been added in 2.4.4.

The AuthFormLoginSuccessLocation directive specifies the URL to redirect to should the user have logged in successfully. The value is parsed using the ap_expr parser before being sent to the client. This directive can be overridden if a form field has been defined containing another URL using the AuthFormLocation directive.

Use this directive if you have a dedicated login URL, and you have not embedded the destination page in the login form.

top

AuthFormLogoutLocation Directive

Description:The URL to redirect to after a user has logged out
Syntax:AuthFormLogoutLocation uri
Default:none
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later. The use of the expression parser has been added in 2.4.4.

The AuthFormLogoutLocation directive specifies the URL of a page on the server to redirect to should the user attempt to log out. The value is parsed using the ap_expr parser before being sent to the client.

When a URI is accessed that is served by the handler form-logout-handler, the page specified by this directive will be shown to the end user. For example:

Example

<Location "/logout">
    SetHandler form-logout-handler
    AuthFormLogoutLocation "http://example.com/loggedout.html"
    Session on
    #...
</Location>

An attempt to access the URI /logout/ will result in the user being logged out, and the page /loggedout.html will be displayed. Make sure that the page loggedout.html is not password protected, otherwise the page will not be displayed.

top

AuthFormMethod Directive

Description:The name of a form field carrying the method of the request to attempt on successful login
Syntax:AuthFormMethod fieldname
Default:AuthFormMethod httpd_method
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormMethod directive specifies the name of an HTML field which, if present, will contain the method of the request to submit should login be successful.

By populating the form with fields described by AuthFormMethod, AuthFormMimetype and AuthFormBody, a website can retry a request that may have been interrupted by the login screen, or by a session timeout.

top

AuthFormMimetype Directive

Description:The name of a form field carrying the mimetype of the body of the request to attempt on successful login
Syntax:AuthFormMimetype fieldname
Default:AuthFormMimetype httpd_mimetype
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormMimetype directive specifies the name of an HTML field which, if present, will contain the mimetype of the request to submit should login be successful.

By populating the form with fields described by AuthFormMethod, AuthFormMimetype and AuthFormBody, a website can retry a request that may have been interrupted by the login screen, or by a session timeout.

top

AuthFormPassword Directive

Description:The name of a form field carrying the login password
Syntax:AuthFormPassword fieldname
Default:AuthFormPassword httpd_password
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormPassword directive specifies the name of an HTML field which, if present, will contain the password to be used to log in.

top

AuthFormProvider Directive

Description:Sets the authentication provider(s) for this location
Syntax:AuthFormProvider provider-name [provider-name] ...
Default:AuthFormProvider file
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_auth_form

The AuthFormProvider directive sets which provider is used to authenticate the users for this location. The default file provider is implemented by the mod_authn_file module. Make sure that the chosen provider module is present in the server.

Example

<Location "/secure">
    AuthType form
    AuthName "private area"
    AuthFormProvider  dbm
    AuthDBMType        SDBM
    AuthDBMUserFile    "/www/etc/dbmpasswd"
    Require            valid-user
    #...
</Location>

Providers are implemented by mod_authn_dbm, mod_authn_file, mod_authn_dbd, mod_authnz_ldap and mod_authn_socache.

top

AuthFormSitePassphrase Directive

Description:Bypass authentication checks for high traffic sites
Syntax:AuthFormSitePassphrase secret
Default:none
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormSitePassphrase directive specifies a passphrase which, if present in the user session, causes Apache httpd to bypass authentication checks for the given URL. It can be used on high traffic websites to reduce the load induced on authentication infrastructure.

The passphrase can be inserted into a user session by adding this directive to the configuration for the form-login-handler. The form-login-handler itself will always run the authentication checks, regardless of whether a passphrase is specified or not.

Warning

If the session is exposed to the user through the use of mod_session_cookie, and the session is not protected with mod_session_crypto, the passphrase is open to potential exposure through a dictionary attack. Regardless of how the session is configured, ensure that this directive is not used within URL spaces where private user data could be exposed, or sensitive transactions can be conducted. Use at own risk.

top

AuthFormSize Directive

Description:The largest size of the form in bytes that will be parsed for the login details
Syntax:AuthFormSize size
Default:AuthFormSize 8192
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormSize directive specifies the maximum size of the body of the request that will be parsed to find the login form.

If a login request arrives that exceeds this size, the whole request will be aborted with the HTTP response code HTTP_REQUEST_TOO_LARGE.

If you have populated the form with fields described by AuthFormMethod, AuthFormMimetype and AuthFormBody, you probably want to set this field to a similar size as the KeptBodySize directive.

top

AuthFormUsername Directive

Description:The name of a form field carrying the login username
Syntax:AuthFormUsername fieldname
Default:AuthFormUsername httpd_username
Context:directory
Status:Base
Module:mod_auth_form
Compatibility:Available in Apache HTTP Server 2.3.0 and later

The AuthFormUsername directive specifies the name of an HTML field which, if present, will contain the username to be used to log in.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_dbd.html.en0000664000175100017510000003614114737241666021711 0ustar covenercovener mod_authn_dbd - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authn_dbd

Available Languages:  en  |  fr 

Description:User authentication using an SQL database
Status:Extension
Module Identifier:authn_dbd_module
Source File:mod_authn_dbd.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 SQL tables. Similar functionality is provided by, for example, mod_authn_file.

This module relies on mod_dbd to specify the backend database driver and connection parameters, and manage the database connections.

When using mod_auth_basic or mod_auth_digest, this module is invoked via the AuthBasicProvider or AuthDigestProvider with the dbd value.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Performance and Caching

Some users of DBD authentication in HTTPD 2.2/2.4 have reported that it imposes a problematic load on the database. This is most likely where an HTML page contains hundreds of objects (e.g. images, scripts, etc) each of which requires authentication. Users affected (or concerned) by this kind of problem should use mod_authn_socache to cache credentials and take most of the load off the database.

top

Configuration Example

This simple example shows use of this module in the context of the Authentication and DBD frameworks.

# mod_dbd configuration
# UPDATED to include authentication caching
DBDriver pgsql
DBDParams "dbname=apacheauth user=apache password=xxxxxx"

DBDMin  4
DBDKeep 8
DBDMax  20
DBDExptime 300

<Directory "/usr/www/myhost/private">
  # mod_authn_core and mod_auth_basic configuration
  # for mod_authn_dbd
  AuthType Basic
  AuthName "My Server"

  # To cache credentials, put socache ahead of dbd here
  AuthBasicProvider socache dbd

  # Also required for caching: tell the cache to cache dbd lookups!
  AuthnCacheProvideFor dbd
  AuthnCacheContext my-server

  # mod_authz_core configuration
  Require valid-user

  # mod_authn_dbd SQL query to authenticate a user
  AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"
</Directory>
top

Exposing Login Information

Whenever a query is made to the database server, all column values in the first row returned by the query are placed in the environment, using environment variables with the prefix "AUTHENTICATE_".

If a database query for example returned the username, full name and telephone number of a user, a CGI program will have access to this information without the need to make a second independent database query to gather this additional information.

This has the potential to dramatically simplify the coding and configuration required in some web applications.

top

AuthDBDUserPWQuery Directive

Description:SQL query to look up a password for a user
Syntax:AuthDBDUserPWQuery query
Context:directory
Status:Extension
Module:mod_authn_dbd

The AuthDBDUserPWQuery specifies an SQL query to look up a password for a specified user. The user's ID will be passed as a single string parameter when the SQL query is executed. It may be referenced within the query statement using a %s format specifier.

AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"

The first column value of the first row returned by the query statement should be a string containing the encrypted password. Subsequent rows will be ignored. If no rows are returned, the user will not be authenticated through mod_authn_dbd.

Any additional column values in the first row returned by the query statement will be stored as environment variables with names of the form AUTHENTICATE_COLUMN.

The encrypted password format depends on which authentication frontend (e.g. mod_auth_basic or mod_auth_digest) is being used. See Password Formats for more information.

top

AuthDBDUserRealmQuery Directive

Description:SQL query to look up a password hash for a user and realm.
Syntax:AuthDBDUserRealmQuery query
Context:directory
Status:Extension
Module:mod_authn_dbd

The AuthDBDUserRealmQuery specifies an SQL query to look up a password for a specified user and realm in a digest authentication process. The user's ID and the realm, in that order, will be passed as string parameters when the SQL query is executed. They may be referenced within the query statement using %s format specifiers.

AuthDBDUserRealmQuery "SELECT password FROM authn WHERE user = %s AND realm = %s"

The first column value of the first row returned by the query statement should be a string containing the encrypted password. Subsequent rows will be ignored. If no rows are returned, the user will not be authenticated through mod_authn_dbd.

Any additional column values in the first row returned by the query statement will be stored as environment variables with names of the form AUTHENTICATE_COLUMN.

The encrypted password format depends on which authentication frontend (e.g. mod_auth_basic or mod_auth_digest) is being used. See Password Formats for more information.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_socache.html.en0000664000175100017510000004550714737241666022573 0ustar covenercovener mod_authn_socache - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Modules

Apache Module mod_authn_socache

Available Languages:  en  |  fr 

Description:Manages a cache of authentication credentials to relieve the load on backends
Status:Base
Module Identifier:authn_socache_module
Source File:mod_authn_socache.c
Compatibility:Version 2.3 and later

Summary

Maintains a cache of authentication credentials, so that a new backend lookup is not required for every authenticated request.

Support Apache!

Topics

Directives

Bugfix checklist

See also

top

Authentication Caching

Some users of more heavyweight authentication such as SQL database lookups (mod_authn_dbd) have reported it putting an unacceptable load on their authentication provider. A typical case in point is where an HTML page contains hundreds of objects (images, scripts, stylesheets, media, etc), and a request to the page generates hundreds of effectively-immediate requests for authenticated additional contents.

mod_authn_socache provides a solution to this problem by maintaining a cache of authentication credentials.

top

Usage

The authentication cache should be used where authentication lookups impose a significant load on the server, or a backend or network. Authentication by file (mod_authn_file) or dbm (mod_authn_dbm) are unlikely to benefit, as these are fast and lightweight in their own right (though in some cases, such as a network-mounted file, caching may be worthwhile). Other providers such as SQL or LDAP based authentication are more likely to benefit, particularly where there is an observed performance issue. Amongst the standard modules, mod_authnz_ldap manages its own cache, so only mod_authn_dbd will usually benefit from this cache.

The basic rules to cache for a provider are:

  1. Include the provider you're caching for in an AuthnCacheProvideFor directive.
  2. List socache ahead of the provider you're caching for in your AuthBasicProvider or AuthDigestProvider directive.

A simple usage example to accelerate mod_authn_dbd using dbm as a cache engine:

#AuthnCacheSOCache is optional.  If specified, it is server-wide
AuthnCacheSOCache dbm
<Directory "/usr/www/myhost/private">
    AuthType Basic
    AuthName "Cached Authentication Example"
    AuthBasicProvider socache dbd
    AuthDBDUserPWQuery "SELECT password FROM authn WHERE user = %s"
    AuthnCacheProvideFor dbd
    Require valid-user
    #Optional
    AuthnCacheContext dbd-authn-example
</Directory>
top

Caching with custom modules

Module developers should note that their modules must be enabled for caching with mod_authn_socache. A single optional API function ap_authn_cache_store is provided to cache credentials a provider has just looked up or generated. Usage examples are available in r957072, in which three authn providers are enabled for caching.

top

AuthnCacheContext Directive

Description:Specify a context string for use in the cache key
Syntax:AuthnCacheContext directory|server|custom-string
Default:AuthnCacheContext directory
Context:directory
Status:Base
Module:mod_authn_socache

This directive specifies a string to be used along with the supplied username (and realm in the case of Digest Authentication) in constructing a cache key. This serves to disambiguate identical usernames serving different authentication areas on the server.

Two special values for this are directory, which uses the directory context of the request as a string, and server which uses the virtual host name.

The default is directory, which is also the most conservative setting. This is likely to be less than optimal, as it (for example) causes $app-base, $app-base/images, $app-base/scripts and $app-base/media each to have its own separate cache key. A better policy is to name the AuthnCacheContext for the password provider: for example a htpasswd file or database table.

Contexts can be shared across different areas of a server, where credentials are shared. However, this has potential to become a vector for cross-site or cross-application security breaches, so this directive is not permitted in .htaccess contexts.

top

AuthnCacheEnable Directive

Description:Enable Authn caching configured anywhere
Syntax:AuthnCacheEnable
Context:server config
Status:Base
Module:mod_authn_socache

This directive is not normally necessary: it is implied if authentication caching is enabled anywhere in httpd.conf. However, if it is not enabled anywhere in httpd.conf it will by default not be initialised, and is therefore not available in a .htaccess context. This directive ensures it is initialised so it can be used in .htaccess.

top

AuthnCacheProvideFor Directive

Description:Specify which authn provider(s) to cache for
Syntax:AuthnCacheProvideFor authn-provider [...]
Default:None
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authn_socache

This directive specifies an authentication provider or providers to cache for. Credentials found by a provider not listed in an AuthnCacheProvideFor directive will not be cached.

For example, to cache credentials found by mod_authn_dbd or by a custom provider myprovider, but leave those looked up by lightweight providers like file or dbm lookup alone:

AuthnCacheProvideFor dbd myprovider
top

AuthnCacheSOCache Directive

Description:Select socache backend provider to use
Syntax:AuthnCacheSOCache provider-name[:provider-args]
Context:server config
Status:Base
Module:mod_authn_socache
Compatibility:Optional provider arguments are available in Apache HTTP Server 2.4.7 and later

This is a server-wide setting to select a provider for the shared object cache, followed by optional arguments for that provider. Some possible values for provider-name are "dbm", "dc", "memcache", or "shmcb", each subject to the appropriate module being loaded. If not set, your platform's default will be used.

top

AuthnCacheTimeout Directive

Description:Set a timeout for cache entries
Syntax:AuthnCacheTimeout timeout (seconds)
Default:AuthnCacheTimeout 300 (5 minutes)
Context:directory, .htaccess
Override:AuthConfig
Status:Base
Module:mod_authn_socache

Caching authentication data can be a security issue, though short-term caching is unlikely to be a problem. Typically a good solution is to cache credentials for as long as it takes to relieve the load on a backend, but no longer, though if changes to your users and passwords are infrequent then a longer timeout may suit you. The default 300 seconds (5 minutes) is both cautious and ample to keep the load on a backend such as dbd (SQL database queries) down.

This should not be confused with session timeout, which is an entirely separate issue. However, you may wish to check your session-management software for whether cached credentials can "accidentally" extend a session, and bear it in mind when setting your timeout.

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/mod/mod_authn_core.html0000664000175100017510000000033313710016232021454 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authn_core.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authn_core.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_actions.html0000664000175100017510000000075113710016232020771 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: mod_actions.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_actions.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_actions.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_auth_form.html0000664000175100017510000000033113710016232021307 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_auth_form.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_auth_form.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_allowmethods.html0000664000175100017510000000033713710016232022033 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_allowmethods.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_allowmethods.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_asis.html0000664000175100017510000000060213710016232020263 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_asis.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_asis.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_asis.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_asis.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_authn_file.html0000664000175100017510000000063213710016232021445 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authn_file.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authn_file.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_authn_file.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_authn_file.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_proxy_fdpass.html0000664000175100017510000000033713710016232022052 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_fdpass.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_fdpass.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_privileges.html0000664000175100017510000000033313710016232021476 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_privileges.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_privileges.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_ftp.html0000664000175100017510000000033113710016232021355 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_ftp.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_ftp.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/index.html0000664000175100017510000000132013710016232017572 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: index.html.es Content-Language: es Content-type: text/html; charset=ISO-8859-1 URI: index.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: index.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: index.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: index.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 URI: index.html.zh-cn.utf8 Content-Language: zh-cn Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/core.html0000664000175100017510000000102713710016232017417 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: core.html.es Content-Language: es Content-type: text/html; charset=ISO-8859-1 URI: core.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: core.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: core.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/event.html0000664000175100017510000000031113710016232017603 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: event.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: event.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authz_dbm.html0000664000175100017510000000047113710016232021305 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authz_dbm.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authz_dbm.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_authz_dbm.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_proxy_fcgi.html0000664000175100017510000000033313710016232021476 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_fcgi.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_fcgi.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_lbmethod_bytraffic.html0000664000175100017510000000035313710016232023156 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_lbmethod_bytraffic.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_lbmethod_bytraffic.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_http.html0000664000175100017510000000033313710016232021545 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_http.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_http.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/directive-dict.html0000664000175100017510000000112613710016232021366 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: directive-dict.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: directive-dict.html.es Content-Language: es Content-type: text/html; charset=ISO-8859-1 URI: directive-dict.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: directive-dict.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: directive-dict.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: directive-dict.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/directives.html0000664000175100017510000000137013710016232020631 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: directives.html.es Content-Language: es Content-type: text/html; charset=ISO-8859-1 URI: directives.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: directives.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: directives.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: directives.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 URI: directives.html.zh-cn.utf8 Content-Language: zh-cn Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_alias.html0000664000175100017510000000073713710016232020426 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_alias.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_alias.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_alias.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_alias.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_alias.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_access_compat.html0000664000175100017510000000050213710016232022127 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_access_compat.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_access_compat.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_access_compat.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_auth_basic.html0000664000175100017510000000063213710016232021431 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_auth_basic.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_auth_basic.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_auth_basic.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_auth_basic.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_proxy_html.html0000664000175100017510000000033313710016232021532 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_html.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_html.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_auth_digest.html0000664000175100017510000000047713710016232021636 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_auth_digest.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_auth_digest.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_auth_digest.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_authn_anon.html0000664000175100017510000000063213710016232021461 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authn_anon.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authn_anon.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_authn_anon.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_authn_anon.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_proxy_balancer.html0000664000175100017510000000050513710016232022336 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_balancer.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_balancer.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_proxy_balancer.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_log_config.html0000664000175100017510000000077013710016232021440 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_log_config.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_log_config.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_log_config.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_log_config.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_log_config.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_hcheck.html0000664000175100017510000000033713710016232022017 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_hcheck.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_hcheck.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authnz_ldap.html0000664000175100017510000000033513710016232021640 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authnz_ldap.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authnz_ldap.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authn_dbm.html0000664000175100017510000000062613710016232021273 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authn_dbm.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authn_dbm.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_authn_dbm.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_authn_dbm.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_authnz_fcgi.html0000664000175100017510000000033513710016232021630 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authnz_fcgi.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authnz_fcgi.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authz_dbd.html0000664000175100017510000000033113710016232021267 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authz_dbd.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authz_dbd.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authz_host.html0000664000175100017510000000033313710016232021515 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authz_host.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authz_host.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_autoindex.html0000664000175100017510000000076313710016232021334 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_autoindex.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_autoindex.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_autoindex.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_autoindex.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_autoindex.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authn_dbd.html0000664000175100017510000000033113710016232021253 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authn_dbd.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authn_dbd.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authn_socache.html0000664000175100017510000000034113710016232022130 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authn_socache.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authn_socache.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authz_core.html0000664000175100017510000000033313710016232021470 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authz_core.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authz_core.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authz_groupfile.html0000664000175100017510000000065613710016232022544 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authz_groupfile.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authz_groupfile.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_authz_groupfile.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_authz_groupfile.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_authz_user.html0000664000175100017510000000063213710016232021520 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authz_user.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authz_user.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_authz_user.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_authz_user.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_buffer.html0000664000175100017510000000032313710016232020575 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_buffer.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_buffer.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_http2.html0000664000175100017510000000032113710016232020363 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_http2.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_http2.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_include.html0000664000175100017510000000046013710016232020751 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_include.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_include.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_include.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_lbmethod_bybusyness.html0000664000175100017510000000035513710016232023415 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_lbmethod_bybusyness.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_lbmethod_bybusyness.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_lbmethod_heartbeat.html0000664000175100017510000000035313710016232023144 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_lbmethod_heartbeat.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_lbmethod_heartbeat.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_log_debug.html0000664000175100017510000000033113710016232021252 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_log_debug.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_log_debug.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_mime.html0000664000175100017510000000044713710016232020262 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_mime.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_mime.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_mime.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_nw_ssl.html0000664000175100017510000000032313710016232020631 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_nw_ssl.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_nw_ssl.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_logio.html0000664000175100017510000000073713710016232020446 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_logio.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_logio.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_logio.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_logio.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_logio.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_md.html0000664000175100017510000000031313710016232017723 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_md.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_md.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_authz_owner.html0000664000175100017510000000063613710016232021700 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_authz_owner.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_authz_owner.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_authz_owner.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_authz_owner.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_brotli.html0000664000175100017510000000032313710016232020617 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_brotli.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_brotli.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_cache_disk.html0000664000175100017510000000063213710016232021404 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_cache_disk.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_cache_disk.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_cache_disk.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_cache_disk.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_cgi.html0000664000175100017510000000057613710016232020100 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_cgi.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_cgi.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_cgi.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_cgi.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_data.html0000664000175100017510000000031713710016232020240 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_data.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_data.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_negotiation.html0000664000175100017510000000047413710016232021653 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_negotiation.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_negotiation.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_negotiation.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy.html0000664000175100017510000000045213710016232020510 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_proxy.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_dav_lock.html0000664000175100017510000000046313710016232021113 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_dav_lock.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_dav_lock.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_dav_lock.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_cache.html0000664000175100017510000000060613710016232020373 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_cache.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_cache.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_cache.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_cache.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_cern_meta.html0000664000175100017510000000047113710016232021265 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_cern_meta.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_cern_meta.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_cern_meta.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_charset_lite.html0000664000175100017510000000050213710016232021771 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_charset_lite.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_charset_lite.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_charset_lite.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_dav_fs.html0000664000175100017510000000061213710016232020567 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_dav_fs.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_dav_fs.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_dav_fs.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_dav_fs.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_cache_socache.html0000664000175100017510000000034113710016232022054 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_cache_socache.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_cache_socache.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_connect.html0000664000175100017510000000050213710016232022215 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_connect.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_connect.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_proxy_connect.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_cgid.html0000664000175100017510000000060213710016232020232 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_cgid.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_cgid.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_cgid.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_cgid.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_dav.html0000664000175100017510000000057613710016232020110 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_dav.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_dav.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_dav.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_dav.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_dbd.html0000664000175100017510000000031513710016232020056 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_dbd.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_dbd.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_dir.html0000664000175100017510000000072513710016232020110 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_dir.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_dir.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_dir.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_dir.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_dir.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_dialup.html0000664000175100017510000000032313710016232020602 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_dialup.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_dialup.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_deflate.html0000664000175100017510000000061613710016232020735 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_deflate.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_deflate.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_deflate.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_deflate.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_proxy_scgi.html0000664000175100017510000000033313710016232021513 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_scgi.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_scgi.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_uwsgi.html0000664000175100017510000000033513710016232021726 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_uwsgi.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_uwsgi.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_echo.html0000664000175100017510000000060213710016232020242 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_echo.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_echo.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_echo.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_echo.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_expires.html0000664000175100017510000000061613710016232021010 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_expires.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_expires.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_expires.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_expires.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_filter.html0000664000175100017510000000032313710016232020611 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_filter.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_filter.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_heartmonitor.html0000664000175100017510000000033713710016232022044 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_heartmonitor.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_heartmonitor.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_imagemap.html0000664000175100017510000000046613710016232021114 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_imagemap.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_imagemap.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_imagemap.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_isapi.html0000664000175100017510000000045513710016232020437 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_isapi.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_isapi.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_isapi.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_dumpio.html0000664000175100017510000000045513710016232020627 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_dumpio.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_dumpio.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_dumpio.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_example_hooks.html0000664000175100017510000000050513710016232022164 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_example_hooks.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_example_hooks.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_example_hooks.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_file_cache.html0000664000175100017510000000047413710016232021375 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_file_cache.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_file_cache.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_file_cache.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_heartbeat.html0000664000175100017510000000033113710016232021262 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_heartbeat.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_heartbeat.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_ident.html0000664000175100017510000000060613710016232020433 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_ident.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_ident.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_ident.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_ident.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_info.html0000664000175100017510000000060213710016232020257 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_info.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_info.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_info.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_info.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_lbmethod_byrequests.html0000664000175100017510000000035513710016232023415 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_lbmethod_byrequests.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_lbmethod_byrequests.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_ldap.html0000664000175100017510000000031713710016232020247 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_ldap.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_ldap.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_log_forensic.html0000664000175100017510000000063713710016232022005 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_log_forensic.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_log_forensic.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_log_forensic.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_log_forensic.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_macro.html0000664000175100017510000000032113710016232020423 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_macro.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_macro.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_mime_magic.html0000664000175100017510000000033313710016232021414 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_mime_magic.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_mime_magic.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_env.html0000664000175100017510000000072513710016232020122 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_env.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_env.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_env.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_env.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_env.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_ext_filter.html0000664000175100017510000000063213710016232021474 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_ext_filter.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_ext_filter.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_ext_filter.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_ext_filter.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_headers.html0000664000175100017510000000061613710016232020744 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_headers.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_headers.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_headers.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_headers.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_lua.html0000664000175100017510000000031513710016232020106 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_lua.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_lua.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_ajp.html0000664000175100017510000000046613710016232021347 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_ajp.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_ajp.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_proxy_ajp.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_express.html0000664000175100017510000000034113710016232022256 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_express.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_express.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_http2.html0000664000175100017510000000033513710016232021631 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_http2.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_http2.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_ratelimit.html0000664000175100017510000000033113710016232021315 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_ratelimit.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_ratelimit.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_reqtimeout.html0000664000175100017510000000033313710016232021523 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_reqtimeout.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_reqtimeout.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_proxy_wstunnel.html0000664000175100017510000000034313710016232022446 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_proxy_wstunnel.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_proxy_wstunnel.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_remoteip.html0000664000175100017510000000032713710016232021154 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_remoteip.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_remoteip.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_rewrite.html0000664000175100017510000000032513710016232021007 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_rewrite.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_rewrite.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_session_cookie.html0000664000175100017510000000034313710016232022342 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_session_cookie.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_session_cookie.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_setenvif.html0000664000175100017510000000075613710016232021161 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_setenvif.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_setenvif.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_setenvif.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_setenvif.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_setenvif.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_reflector.html0000664000175100017510000000033113710016232021310 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_reflector.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_reflector.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_request.html0000664000175100017510000000046013710016232021016 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_request.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_request.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_request.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_session.html0000664000175100017510000000032513710016232021011 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_session.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_session.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_session_dbd.html0000664000175100017510000000033513710016232021623 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_session_dbd.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_session_dbd.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_slotmem_shm.html0000664000175100017510000000033513710016232021656 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_slotmem_shm.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_slotmem_shm.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_socache_dc.html0000664000175100017510000000033313710016232021400 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_socache_dc.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_socache_dc.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_socache_shmcb.html0000664000175100017510000000034113710016232022105 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_socache_shmcb.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_socache_shmcb.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_status.html0000664000175100017510000000074413710016232020656 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_status.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_status.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_status.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_status.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_status.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_systemd.html0000664000175100017510000000032513710016232021016 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_systemd.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_systemd.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_userdir.html0000664000175100017510000000075113710016232021006 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_userdir.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_userdir.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_userdir.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_userdir.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_userdir.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_vhost_alias.html0000664000175100017510000000047413710016232021647 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_vhost_alias.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_vhost_alias.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_vhost_alias.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/module-dict.html0000664000175100017510000000075113710016232020700 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: module-dict.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: module-dict.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: module-dict.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: module-dict.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: module-dict.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_sed.html0000664000175100017510000000031513710016232020100 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_sed.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_sed.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_session_crypto.html0000664000175100017510000000034313710016232022411 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_session_crypto.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_session_crypto.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_slotmem_plain.html0000664000175100017510000000034113710016232022167 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_slotmem_plain.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_slotmem_plain.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_socache_dbm.html0000664000175100017510000000033513710016232021556 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_socache_dbm.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_socache_dbm.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_socache_redis.html0000664000175100017510000000034113710016232022117 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_socache_redis.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_socache_redis.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_ssl.html0000664000175100017510000000031513710016232020126 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_ssl.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_ssl.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_suexec.html0000664000175100017510000000074413710016232020627 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_suexec.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_suexec.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_suexec.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_suexec.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_suexec.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_unixd.html0000664000175100017510000000045213710016232020456 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_unixd.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_unixd.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_unixd.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_version.html0000664000175100017510000000061613710016232021016 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_version.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_version.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_version.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_version.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_xml2enc.html0000664000175100017510000000032513710016232020676 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_xml2enc.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_xml2enc.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mpm_netware.html0000664000175100017510000000032513710016232021005 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mpm_netware.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mpm_netware.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_so.html0000664000175100017510000000072013710016232017746 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_so.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_so.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_so.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_so.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: mod_so.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_socache_memcache.html0000664000175100017510000000034713710016232022561 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_socache_memcache.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_socache_memcache.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_speling.html0000664000175100017510000000061613710016232020772 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_speling.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_speling.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_speling.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_speling.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_substitute.html0000664000175100017510000000033313710016232021540 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_substitute.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_substitute.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_unique_id.html0000664000175100017510000000062613710016232021314 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_unique_id.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_unique_id.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mod_unique_id.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mod_unique_id.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/mod/mod_usertrack.html0000664000175100017510000000033113710016232021326 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_usertrack.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_usertrack.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mod_watchdog.html0000664000175100017510000000032713710016232021130 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mod_watchdog.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mod_watchdog.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mpm_common.html0000664000175100017510000000074113710016232020632 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: mpm_common.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mpm_common.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: mpm_common.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mpm_winnt.html0000664000175100017510000000060313710016232020476 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: mpm_winnt.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: mpm_winnt.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/overrides.html0000664000175100017510000000032113710016232020465 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: overrides.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: overrides.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/worker.html0000664000175100017510000000071513710016232020003 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: worker.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: worker.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: worker.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/mpmt_os2.html0000664000175100017510000000031713710016232020230 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: mpmt_os2.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: mpmt_os2.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/quickreference.html0000664000175100017510000000143013710016232021460 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: quickreference.html.es Content-Language: es Content-type: text/html; charset=ISO-8859-1 URI: quickreference.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: quickreference.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: quickreference.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: quickreference.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 URI: quickreference.html.zh-cn.utf8 Content-Language: zh-cn Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mod/prefork.html0000664000175100017510000000072213710016232020140 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT 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=UTF-8 URI: prefork.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: prefork.html.ja.utf8 Content-Language: ja Content-type: text/html; charset=UTF-8 URI: prefork.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/mpm.html.es0000664000175100017510000002473314743132254017132 0ustar covenercovener Módulos de MultiProcesamiento (MPMs) - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4

Módulos de MultiProcesamiento (MPMs)

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

Este documento describe que es un Módulo de Multiprocesamiento y como los usa Apache.

Support Apache!

Consulte también

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 en tiempo de ejecución.

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, aceptar 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:

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

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.

Netwarempm_netware
OS/2mpmt_os2
Unixprefork, worker, or event, depending on platform capabilities
Windowsmpm_winnt

aquí, 'Unix' se usa para designar a los sistemas operativos "Unix-like", como Linux, BSD, Solaris, Mac OS X, etc.

En el caso de los Unix, la decisión de que MPM se va a instalar depende de dos pregunas:

1. ¿Nos permite el Sistema Operativo hilos?

2. -¿Nos permite el sistema operativo soporte a pila de hilos seguros (Especificamente, las funciones kqueue y epoll)?

Idiomas disponibles:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

top

Comentarios

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/filter.html.es0000664000175100017510000004243314743132254017623 0ustar covenercovener Filtros - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4

Filtros

Idiomas disponibles:  en  |  es  |  fr  |  ja  |  ko  |  tr 

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 cómo usar filtros en Apache.

Support Apache!

Consulte también

top

Filtros en Apache 2

La cadena de filtrado está disponible en Apache 2.0 y superiores. 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. Todo este proceso es independiente de las tradicionales fase de peticiones

Filters can be chained, in a Data Axis orthogonal to request processing

Algunos ejemplos de filtrado en la distribución estándar de Apache son:

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.

Una mayor amplitud de aplicaciones son implementadas con módulos de filtros de terceros que estan disponibles en modules.apache.org y en otros lados. algunos de ellos son:

top

Filtrado Inteligente

Smart filtering applies different filter providers according to the state of request processing

mod_filter, incluido en Apache 2.1 y posterior, habilita la cadena de filtrado para ser configurada dinámicamente en tiempo de ejecución. Así, por ejemplo, usted puede configurar un proxy para que reescriba HTML con un filtro de HTML y imágenes JPEG con filtros completos por separado, a pesar de que el proxy no tiene información previa sobre lo que enviará al servidor de origen. Esto funciona usando un engranaje filtros, que envía a diferentes proveedores dependiendo del contenido en tiempo de ejecución. Cualquier filtro puede ser, ya sea insertado directamente en la cadena y ejecutado incondicionalmente, o usado como proveedor y añadido dinámicamente Por ejemplo:

top

Filtros expuestos como un servicio HTTP

Los filtros pueden ser usados para procesar contenido originado desde el cliente además de usarse para procesar el contenido originado desde el propio servidor usando el módulo mod_reflector.

mod_reflector acepta peticiones POST de los clientes, y refleja el cuerpo de la petición POST recibida, dentro del contenido de la respuesta de la petición, pasa a través de la pila del filtro de salida en el camino de vuelta al cliente.

Esta técnica se puede utilizar como una alternativa a un servicio web que se ejecuta en una pila de de aplicaciones dentro del servidor, en donde el filtro de salida proporciona la transformación requerida en el cuerpo de la petición. Por ejemplo, el módulo mod_deflate puede ser usado para proporcionar un servicio de compresión general, o un filtro de transformación de imagen, puede ser convertido en un servicio de conversión de imágenes.

top

Usando los Filtros

Hay dos formas de usar el filtrado: de forma Simple y Dinámica. Generalmente, deberá usar una forma u otra; ya que mezclarlas puede causar consecuencias inesperadas (a pesar de que reglas de Entrada de tipo simple pueden ser combinadas libremente con reglas de filtrado de Salidas de tipo simple o dinámico).

La forma más sencilla es la única manera de configurar filtros de Entrada, y es suficiente para filtros de Salida donde se necesita una cadena de filtros estática. Las directivas más relevantes son: SetInputFilter, SetOutputFilter, AddInputFilter, AddOutputFilter, RemoveInputFilter, and RemoveOutputFilter.

La forma Dinámica habilita ambas configuraciones estática, y dinámica, para los filtros de Salida, como se plantea en la página mod_filter. Las directivas más relevantes son: FilterChain, FilterDeclare, and FilterProvider.

Una directiva más como es AddOutputFilterByType sigue siendo soportada pero esta obsoleta. Usa en cambio la configuración dinámica.

Idiomas disponibles:  en  |  es  |  fr  |  ja  |  ko  |  tr 

top

Comentarios

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/glossary.html.tr.utf80000664000175100017510000010215514743132254021102 0ustar covenercovener Terim Sözlüğü - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4

Terim Sözlüğü

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr 

Bu sözlük, genelinde HTML sayfa sunumuna, özelinde Apache HTTP Sunucusuna özgü ortak terminolojinin bir kısmını içerir. Her kavram ile ilgili daha ayrıntılı bilgi bağlarla sağlanmıştır.

top

Tanımlar

Algoritma
Bir sorunu sonlu sayıda adımda çözümlemek için uygulanan kurallar kümesi veya anlam belirsizliği içermeyen bir formül. Şifreleme için kullanılan algoritmalara şifre denir.
Aktarım Katmanı Güvenliği
İngilizcesi: Transport Layer Security (TLS)
TCP/IP ağları üzerinden genel iletişimin kimlik doğrulamalı ve şifreli yapılabilmesi için SSL’nin ardılı olarak Genel Ağ Mühendisliği Görev Gücü (IETF) tarafından oluşturulmuş protokol. TLS’nin 1. sürümü ile SSL’in 3. sürümü hemen hemen aynıdır.
Bakınız: SSL/TLS Şifrelemesi
Alt istek
Diğer dosya sistemlerini veya URL yollarını kısmen veya tamamen değerlendiren modüller için sunucuda bir alt istek API'si mevcuttur. Bu API'nin olası müşterileri için DirectoryIndex, mod_autoindex ve mod_include örnek verilebilir.
Anahtar Parolası
Özel anahtar dosyalarını yetkisiz kişilerden koruyan sözcük veya cümle. Genellikle sadece şifreler için kullanılan gizli şifreleme/şifre çözme anahtarını korur.
Bakınız: SSL/TLS Şifrelemesi
Apache Eklenti Aracı (apxs)
İngilizcesi: APache eXtension Tool - apxs
Modül kaynak kodlarının devinen paylaşımlı nesneler (DSO) halinde derlenmesine ve Apache Sunucusu içinde kurulmasına yardım eden bir Perl betiği.
Daha ayrıntılı bilgi için apxs kılavuz sayfasına bakınız.
Apache Taşınabilir Arayüzü (APR)
İngilizcesi: Apache Portable Runtime - APR
Sunucu ile işletim sistemi arasındaki temel arayüzleri oluşturan kütüphaneler kümesine verilen ad. APR, Apache HTTP Sunucusuna paralel bağımsız bir proje olarak geliştirilmektedir.
Bakınız: Apache Taşınabilir Arayüzü Projesi
Bağlam
Yapılandırma dosyalarında sadece belli türdeki yönergelerin bulunmasına izin verilen bir bölge.
Bakınız: Apache Yönergelerini Açıklamak için Kullanılan Terimler
Bakışımlı Şifreleme Tekniği
Şifreleme ve şifre çözme için tek bir anahtarın kullanıldığı bir şifreleme tekniği.
Bakınız: SSL/TLS Şifrelemesi
Başlık
Bir HTTP isteğinin parçası olarak, gönderilen yanıtta asıl içerikten önce yer alan ve içerik hakkında mecazlar içeren veri.
CONNECT
Ham veri kanallarını HTTP üzerinden yönlendirmek için kullanılan bir HTTP yöntemi. SSL protokolü gibi diğer protokolleri sarmalamakta kullanılabilir.
Devingen Paylaşımlı Nesne (DSO)
İngilizcesi: Dynamic Shared Object (DSO)
İstek halinde yüklenebilen, Apache httpd çalıştırılabilir dosyasından ayrı olarak derlenmiş modüllerin ortak adı.
Bakınız: Devingen Paylaşımlı Nesne Desteği
Düz Metin
Şifrelenmemiş metin.
Düzenli İfade (Regex)
Metin içinde bir şablon tanımlama yolu. Örneğin, “A harfi ile başlayan bütün sözcükler” veya “10 rakamlı telefon numaraları” ya da “Baş harfi Z olmayan ve iki virgül içeren cümleler” gibi. Düzenli ifadeler, Apache’de belli özniteliklere uygun dosya veya özkaynakları toplamak için esnek bir yol sağlamasından ötürü oldukça yararlıdır. Örneğin, “resimler” dizini altındaki dosyalardan .gif ve .jpg uzantılı olanları toplamak için “/resimler/.*(jpg|gif)$” düzenli ifadesi yazılabilir. Dizgileri değiştirmek için düzenli ifadelerin kullanıldığı yerlerde, eşleşen (parantezlerin içinde) gruplanmış parçalara başvurmak için $1 ... $9 özel değişkenleri kullanılır. $0 özel değişkeni eşleşen ifadenin tamamına karşılık gelir. Bir dizgi içinde $ işaretini kendisi olarak kullanmak isterseniz önüne bir \ imi koymalısınız. Geçmişe uyumluluk adına bazı yerlerde $0 yerine & değişkeni kullanılabilir. Ancak 2.3.6 sürümünden beri bu artık mümkün değildir. Apache, PCRE kütüphanesi ile sağlanan Perl uyumlu düzenli ifadeleri kullanır. PCRE düzenli ifadelerinin sözdizimi ile ilgili ayrıntılı bilgiyi Wikipedia'da bulabilirsiniz.
Erişim Denetimi
Ağ bölgelerine erişimin kısıtlanması. Apache bağlamında normal olarak belli URL’lere erişimi kısıtlamak şeklinde uygulanır.
Bakınız: Kimlik Doğrulama, Yetkilendirme ve Erişim Denetimi
Eylemci
Bir dosya istendiğinde uygulanacak eylemi Apache içinde gerçekleştiren nesne. Genellikle dosyalar, dosya türüne bağlı dolaylı eylemcilere sahiptir. Normalde tüm dosyalar sunucu tarafından sıradan birer dosya olarak işleme sokulduğu halde bazı belli dosyalar diğerlerinden ayrı ele alınır. Örneğin, cgi-script eylemcisi dosyaları CGI’ler tarafından işlenebilir hale getirmek üzere işleme sokar.
Bakınız: Apache Eylemcilerinin Kullanımı
Genel Anahtar
Genel Anahtarlı Şifreleme Tekniğinde, sahibinin yaptığı imzaları çözmeye ve sahibine gönderilen iletileri şifrelemeye yarayan genel erişime açık anahtar.
Bakınız: SSL/TLS Şifrelemesi
Genel Anahtarlı Şifreleme Tekniği
Şifreleme ve şifre çözme için iki ayrı anahtarın kullanıldığı bakışımsız şifreleme sistemlerinin konusu veya uygulaması. Bu amaçla kullanılan anahtarlar bir anahtar çiftinden oluşur. Genel Anahtarlı Şifrelemeye Bakışımsız Şifreleme de denir.
Bakınız: SSL/TLS Şifrelemesi
Gizli Anahtar
Genel Anahtarlı Şifreleme Tekniğinde, giden iletileri imzalamak ve gelen iletilerin şifrelerini çözmek amacıyla kullanılan gizli anahtar.
Bakınız: SSL/TLS Şifrelemesi
Güvenli Hiper Metin Aktarım Protokolü (HTTPS)
İngilizcesi: The HyperText Transfer Protocol (Secure), (HTTPS)
Güvenli Hiper Metin Aktarım Protokolü, Genel Ağ’da kullanılan standart şifreli iletişim mekanizmasıdır. Aslında HTTP protokolünün SSL üzerinden gerçekleştirilmesinden başka bir şey değildir.
Bakınız: SSL/TLS Şifrelemesi
Güvenli Soket Katmanı
İngilizcesi: Secure Sockets Layer (SSL)
TCP/IP ağları üzerinden genel iletişimin kimlik doğrulamalı ve şifreli yapılabilmesi için Netscape Communications Corporation tarafından oluşturulmuş bir protokol. Günümüzde en çok HTTPS, yani SSL üzerinden Hiper Metin Aktarım Protokolü şeklinde kullanılmaktadır.
Bakınız: SSL/TLS Şifrelemesi
Hiper Metin Aktarım Protokolü (HTTP)
İngilizcesi: HyperText Transfer Protocol (HTTP)
Genel Ağ’da kullanılan standart aktarım protokollerinden biri. Apache, RFC 2616 ile tanımlanmış protokolün HTTP/1.1 olarak bilinen 1.1 sürümünü gerçekler.
.htaccess
Belge dosyaları ağacı içine yerleştirilen bir yapılandırma dosyası olup yerleştiği dizine ve o dizinin alt dizinlerine yapılandırma yönergeleri uygulanmasını sağlar. İsmine rağmen böyle bir dosyanın içerebileceği yönergeler erişim denetleme yönergeleri ile sınırlı değildir; hemen her tür yönergeyi içerebilir.
Bakınız: Yapılandırma Dosyaları
httpd.conf
Ana Apache yapılandırma dosyası. Dosya sistemindeki öntanımlı yeri /usr/local/apache2/conf/httpd.conf olup derleme sırasındaki yapılandırmayla veya çalışma anındaki yapılandırmayla başka bir yer belirtilebilir.
Bakınız: Yapılandırma Dosyaları
İhracat Engelli
İngilizcesi: Export-Crippled
Amerika Birleşik Devletlerinin İhracat Yönetim Düzenlemelerine (EAR) uymak için şifreleme yoluyla sakatlanmış yazılım. İhracat engelli olması için şifrelenmiş yazılımları birer şifreli metin haline getiren şifre anahtarları küçük boyutlu olduğundan şifreleme zor kullanılarak kırılabilir.
Bakınız: SSL/TLS Şifrelemesi
İleti Özeti
İngilizcesi: Message Digest
Aktarım sırasında içeriğinin değişme olasılığı bulunan bir iletinin içeriğini doğrulamak için kullanılan bir özet.
Bakınız: SSL/TLS Şifrelemesi
Karşı Vekil
İstemciye kendini asıl sunucu imiş gibi gösteren bir vekil sunucu. Güvenlik, yük dengelemesi gibi sebeplerle asıl sunucuyu istemcilerden gizlemek için yararlıdır.
Kimlik Doğrulama
Sunucu, istemci veya kullanıcı gibi bir ağ öğesinin kimliğinin olumlanması.
Bakınız: Kimlik Doğrulama, Yetkilendirme ve Erişim Denetimi
MIME türü
Aktarılan belgenin çeşidini betimlemenin bir yolu. MIME, Türkçe’ye ‘Çok Amaçlı Genel Ağ Posta Eklentileri’ olarak çevrilebilecek olan "Multipurpose Internet Mail Extensions" sözcüklerinden türetilmiş bir kısaltmadır. MIME türleri bir bölü çizgisi ile ayrılmış bir ana ve bir alt belge türünün birleşiminden oluşur. text/html, image/gif ve application/octet-stream örnek olarak verilebilir. HTTP protokolünde MIME türleri Content-Type başlığında aktarılır.
Bakınız: mod_mime
Modül
Bir programın bağımsız parçalarından her biri. Apache işlevselliğinin çoğu yapılandırmaya dahil edilip edilmeyeceğine kullanıcı tarafından karar verilebilen modüllerden oluşur. Apache httpd çalıştırılabiliri içinde derlenmiş modüllere durağan modüller adı verilirken ayrı bir yerde saklanan ve çalışma anında isteğe bağlı olarak yüklenebilen modüllere devingen modüller veya DSO’lar denir. Yapılandırmaya öntanımlı olarak dahil edilen modüllere temel modüller denir. Apache için kullanılabilecek modüllerin çoğu Apache HTTP Sunucusunun tar paketi içinde dağıtılmaz; bunlara üçüncü parti modüller denir.
Bakınız: Modül Dizini
OpenSSL
SSL/TLS için açık kaynak kodlu araç kiti.
Daha ayrıntılı bilgi için http://www.openssl.org/ adresine bakınız.
Ortak Ağgeçidi Arayüzü (CGI)
İngilizcesi: Common Gateway Interface (CGI)
Bir HTTP sunucusunun bir harici programa hizmet istekleri yapmasını mümkün kılan, sunucu ile bir harici program arasındaki bir arayüz standardı. Özellikleri kapsayan bir Bilgilendirici RFC vardır.
Bakınız: CGI ile Devingen İçerik
Ortam Değişkeni (ortam-değişkeni)
İşletim sistemi kabuğu tarafından yönetilen ve programlar arasında bilgi alışverişi amacıyla kullanılan isimli değişkenler. Ayrıca, Apache de ortam değişkenleri olarak tanımlanabilecek dahili değişkenler içerir fakat bunlar kabuk ortamında değil dahili Apache yapıları içinde saklanır.
Bakınız: Apache Ortam Değişkenleri
Oturum
Bir iletişimin bağlamsal bilgileri.
Özet
Uzunluğu değişebilen bir dizgenin belli bir durumuna ilişkin sabit uzunlukta bir dizge üretmek için kullanılan geri dönüşümsüz bir algoritma. Algoritmaya girdi olan farklı uzunluktaki dizgeler (özet işlevine bağlı olarak) aynı uzunlukta farklı özetler üretir.
Sanal Konaklık
Tek bir Apache sunucusundan çok sayıda site sunulması. IP tabanlı sanal konaklıkta siteler birbirlerinden IP adreslerine göre ayrılırken, isim tabanlı sanal konaklıkta siteler aynı IP adresinden kendi isimleriyle sunulabilirler.
Bakınız: Apache Sanal Konak Belgeleri
Sayısal İmza
Bir sertifikayı veya bir dosyayı doğrulamakta kullanılan şifreli bir metin. Bir imza Sertifika Makamı tarafından bir sertifikaya gömülü olan genel anahtardan bir özet üretilerek oluşturulur. İmza şifresi sadece sertifika sahibi ağ öğesinin kimliğini doğrulayacak SM’nin genel anahtarı kullanılarak çözülebilir.
Bakınız: SSL/TLS Şifrelemesi
Sertifika
Sunucu, istemci gibi ağ öğelerinin kimliğini kanıtlamakta kullanılan bir veri kaydı. Bir sertifika, sertifika sahibi (buna sertifikanın konusu da denir), sertifikayı imzalayan Sertifika Makamı (SM) (buna sertifika yayıncısı da denir), sertifika sahibinin genel anahtarı ve SM tarafından üretilen imza gibi parçalardan oluşan X.509 bilgisi içerir. Ağ öğeleri bu imzaları SM sertifikalarını kullanarak doğrular.
Bakınız: SSL/TLS Şifrelemesi
Sertifika İmzalama İsteği (Sİİ)
İngilizcesi: Certificate Signing Request (CSR)
İmzasız bir sertifikayı Sertifika Makamına kendi SM Sertifikasının özel anahtarı ile imzalaması için yapılan istek. Sİİ imzalanınca bir gerçek sertifika haline gelir.
Bakınız: SSL/TLS Şifrelemesi
Sertifika Makamı (SM)
İngilizcesi: Certification Authority (CA)
Ağ öğelerinin güvenilir olarak kimliklerinin doğrulanması için sertifikaları imzalayan güvenilir üçüncü şahıs. Diğer ağ öğeleri, sertifikalı bir öğenin kimliğini kanıtlayan bir SM’yi doğrulamak için imzayı sınayabilir.
Bakınız: SSL/TLS Şifrelemesi
Sihirli Modül Numarası (SMN)
Sihirli Modül Numarası, modüllerin ikil uyumluluğu ile ilgili olarak Apache kaynak kodunda tanımlanmış bir sabittir. Apache dahili yapıları, uygulama programlama arayüzünün önemli parçaları ve işlev çağrıları artık ikil uyumluluğun garanti edilemeyeceği kadar değiştiği zaman SMN değiştirilir. Bir SMN değişikliğinde ve bazen de sırf yeni bir Apache sürümü ile çalışmak icabettiğinde tüm üçüncü parti modüllerin en azından yeniden derlenmesi gerekir.
SSLeay
Eric A. Young tarafından geliştirilmiş özgün SSL/TLS gerçeklenim kütüphanesi.
Sunucu Adı Belirtimi
İngilizcesi: Server Name Indication (SNI)
İlk SSL uzlaşımı sırasında istenen sunucu isminin aktarılmasını mümkün kılan bir SSL işlevidir. Böylece sunucunun, SSL uzlaşım işlemlerlerinde kullanılacak sanal konak yapılandırmasını doğru bir şekilde seçebilmesi sağlanmıştır. Bu özellik RFC 3546'da TLS eklentili SSL başlatma bölümüne eklenmiştir.
Bakınız: SSL SSS ve RFC 3546
Sunucu Taraflı İçerik Yerleştirme
İngilizcesi: Server Side Includes (SSI)
İşlem yönergelerini HTML dosyalara gömme tekniği.
Bakınız: Sunucu Taraflı İçerik Yerleştirmeye Giriş
Süzgeç
Sunucu tarafından alınan ve gönderilen veriye uygulanan bir işlem. Giriş süzgeçleri sunucuya istemci tarafından gönderilen veriyi işlerken çıkış süzgeçleri sunucu tarafından istemciye gönderilen belgeleri işler. Örneğin, INCLUDES çıkış süzgeci, belgeleri sunucu taraflı içerik için işleme sokar.
Bakınız: Süzgeçler
Şifre
Veri şifrelemek için kullanılan bir algoritma veya sistem. DES, IDEA veya RC4 örnek verilebilir.
Bakınız: SSL/TLS Şifrelemesi
Şifreli Metin
Bir Düz Metin bir Şifreden geçirilince elde edilen sonuç.
Bakınız: SSL/TLS Şifrelemesi
Tam Alan Adı (TAA)
İngilizcesi: Fully-Qualified Domain-Name (FQDN)
Bir IP adresiyle eşleşebilen, bir konak adıyla bir alan adının birleşiminden oluşan eşsiz bir ağ öğesi ismi. Örneğin, httpd.apache.org tam alan adında httpd bir konak adıyken apache.org bir alan adıdır.
Tar Paketi
tar uygulaması kullanılarak bir araya getirilmiş dosyalardan oluşan bir paket. Apache dağıtımları sıkıştırılmış tar arşivleri içinde veya pkzip kullanılarak saklanır.
Tektip Özkaynak Betimleyici
İngilizcesi: Uniform Resource Identifier (URI)
Soyut veya somut bir özkaynağı betimlemek için kullanılan bütünleşik bir karakter dizisi. Aslen RFC 2396 tarafından tanımlanmıştır. Genel Ağ’da kullanılan URI’lerden genellikle URL’ler olarak bahsedilir.
Tektip Özkaynak Konumlayıcı
İngilizcesi: Uniform Resource Locator (URL)
Genel Ağ üzerindeki bir özkaynağın ismi veya adresi. Aslen Tektip Özkaynak Betimleyici denilen terimin gayrı resmi karşılığıdır. URL’ler http veya https gibi bir şemayı takip eden bir konak adı ve bir dosya yolundan oluşurlar. Örneğin, bu sayfanın URL’si http://httpd.apache.org/docs/2.4/glossary.html olurdu.
Vekil
Asıl sunucu ile istemci arasında aracılık yapan sunucu. İstemciden aldığı istekleri asıl sunucuya gönderip, ondan aldığı yanıtları istemciye gönderir. Aynı içeriğe birden fazla istemci talip olursa vekil sunucu bu istekleri her seferinde asıl sunucudan istemek yerine kendi deposundan karşılar, böylece yanıt zamanı kısalır.
Bakınız: mod_proxy
Yapılandırma Dosyası
Apache yapılandırmasını denetim altına alan yönergeleri içeren bir metin dosyası.
Bakınız: Yapılandırma Dosyaları
Yapılandırma Yönergesi
Bakınız: Yönerge
Yönerge
Belli Apache davranışlarından bir veya daha fazlasını denetim altına alan bir yapılandırma komutu. Yönergeler yapılandırma dosyalarına yerleştirilir.
Bakınız: Yönerge Dizini
Yöntem
HTTP bağlamında, istemci tarafından istek satırında belirtilen, bir özkaynağa uygulanacak bir eylem. HTTP bağlamında belirtilebilecek yöntemlere örnek olarak GET, POST ve PUT verilebilir.
X.509
SSL/TLS kimlik doğrulamasında kullanılmak üzere Uluslararası Telekom Birliği (ITU-T) tarafından önerilmiş bir kimlik doğrulama sertitifası şeması
Bakınız: SSL/TLS Şifrelemesi

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/bind.html.en0000664000175100017510000003630414737241666017260 0ustar covenercovener Binding to Addresses and Ports - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Binding to Addresses and Ports

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

Configuring Apache HTTP Server to listen on specific addresses and ports.

Support Apache!

See also

top

Overview

When httpd 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 may need to be told to listen on specific ports, or only on selected addresses, or a combination of both. This is often combined with the Virtual Host feature, which determines how httpd responds to different IP addresses, hostnames and ports.

The Listen directive tells the server to accept incoming requests only on the specified port(s) 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, on all interfaces, use:

Listen 80
Listen 8000

To make the server accept connections on port 80 for one interface, and port 8000 on another, use

Listen 192.0.2.1:80
Listen 192.0.2.5:8000

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

Listen [2001:db8::a00:20ff:fea7:ccea]:80

Overlapping Listen directives will result in a fatal error which will prevent the server from starting up.

(48)Address already in use: make_sock: could not bind to address [::]:80

See the discussion in the wiki for further troubleshooting tips.

top

Changing Listen configuration on restart

When httpd is restarted, special consideration must be made for changes to Listen directives. During a restart, httpd keeps ports bound (as in the original configuration) to avoid generating "Connection refused" errors for any new attempts to connect to the server. If changes are made to the set of Listen directives used which conflict with the old configuration, configuration will fail and the server will terminate.

For example, changing from configuration:

Listen 127.0.0.1:80

to the following may fail, because binding to port 80 across all addresses conflicts with binding to port 80 on just 127.0.0.1.

Listen 80

To have such configuration changes take effect, it is necessary to stop and then start the server.

top

Special IPv6 Considerations

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

One complicating factor for httpd 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. On systems where it is disallowed by default, a special configure parameter can change this behavior for httpd.

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 httpd 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 except FreeBSD, NetBSD, and OpenBSD, so this is probably how your httpd was built.

If you want httpd 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.0.2.1:80

If your platform supports it and you want httpd 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

Specifying the protocol with Listen

The optional second protocol argument of Listen is not required for most configurations. If not specified, https is the default for port 443 and http the default for all other ports. The protocol is used to determine which module should handle a request, and to apply protocol specific optimizations with the AcceptFilter directive.

You only need to set the protocol if you are running on non-standard ports. For example, running an https site on port 8443:

Listen 192.170.2.1:8443 https
top

How This Works With Virtual Hosts

The Listen directive does not implement Virtual Hosts - it only tells the main server what addresses and ports to listen on. If no <VirtualHost> directives are used, the server will behave in the same way for all accepted requests. However, <VirtualHost> can be used to specify a different behavior for one or more of the addresses or 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 the 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  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/0000775000175100017510000000000015032766627016671 5ustar covenercovenerhttpd-2.4.64/docs/manual/platform/perf-hp.html0000664000175100017510000000044713710016232021102 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: perf-hp.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: perf-hp.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: perf-hp.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/platform/index.html0000664000175100017510000000057413710016232020651 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: index.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: index.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: index.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: index.html.zh-cn.utf8 Content-Language: zh-cn Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/platform/win_compiling.html0000664000175100017510000000047113710016232022374 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: win_compiling.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: win_compiling.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: win_compiling.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/platform/index.html.zh-cn.utf80000664000175100017510000001266514743132254022572 0ustar covenercovener 平台相关说明 - Apache HTTP 服务器 版本 2.4
<-
Apache > HTTP 服务器 > 文档 > 版本 2.4

平台相关说明

可用语言:  en  |  fr  |  ko  |  zh-cn 

此翻译可能过期。要了解最近的更改,请阅读英文版。
Support Apache!
top

Microsoft Windows

使用 Apache

这篇文档解释了如何在 Microsoft Windows 中安装,配置,以及运行 Apache 2.0 。

参见: 在 Microsoft Windows 中使用 Apache

编译 Apache

这篇文档解释了编译 Apache 的要点。

参见: 为 Microsoft Windows 编译 Apache

top

其它平台

Novell NetWare

这篇文档解释了如何在 Novell NetWare 5.1 或更新的版本中,如何安装,配置,以及运行 Apache 2.0 。

参见: 在 Novell NetWare 中使用 Apache

EBCDIC

从 Apache HTTP 版本 1.3 开始支持使用 EBCDIC 字符集作为原生字符集的(非 ASCII)主机。

警告: 这篇文档尚未完全更新,以反映自 Apache HTTP 服务器版本 2.0 之后的修改。某些信息可能仍旧适用,但请小心使用它。

参见: Apache 与 EBCDIC 系统

可用语言:  en  |  fr  |  ko  |  zh-cn 

httpd-2.4.64/docs/manual/platform/index.html.ko.euc-kr0000664000175100017510000001261414743132254022456 0ustar covenercovener ÷ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

÷

ֽ ƴմϴ. ֱٿ ϼ.
Support Apache!
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  |  fr  |  ko  |  zh-cn 

httpd-2.4.64/docs/manual/platform/ebcdic.html.ko.euc-kr0000664000175100017510000005337714743132254022573 0ustar covenercovener ġ EBCDIC - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

ġ EBCDIC

ֽ ƴմϴ. ֱٿ ϼ.
ġ 2.0 ʴ. ȿ , ؼ ϱ ٶ.
Support Apache!

top

ġ EBCDIC

ġ 1.3 ó EBCDIC ⺻ ϴ (-ASCII) ÷ ǻͷ õǾ.

(BS2000/OSD ü ϴ SIEMENS 迭 ÷ Ѵ. ÷ ü SVR4迭 POSIX ý ִ).

ó ۵Ǿ

ý Ѵ.

top

ǥ

EBCDIC ϳ ο ȯ ϰ ȯ ֵ (EBCDIC) CERN ȣȯ ϴ ̴. ׷ HTML ( CERN νϴ ) ASCII (POSIX ý ⺻ . ׷Ƿ grep̳ sed POSIX ִ ) EBCDIC ־ Ѵ. ذå ġ ߰ ä ľϴ " MIME "̴ (Ʒ ). ȯؾ "ebcdic-handler" ϴ ذ ̴.

top

ذå

ġ BUFF ڷ ޽带 Ͽ ϹǷ BUFF ó Լ ȯ ߰ϴ ̴. ȯ ־ ϱ⶧ BUFF ü ȯؾ ϴ ˷ִ BUFF ǥø ߰ߴ. ǥô HTTP ܰ迡 ִ:

top

ÿ ؼ

  1. ҽ ȭ ΰ #ifdef ִ:

    #ifdef CHARSET_EBCDIC

    EBCDIC ǻͿ ʿ ڵ. ںȯ, հ ӵ ڰ ,  HTTP κ ȯǾ ϴ ˷ִ ǥ .

    #ifdef _OSD_POSIX

    SIEMENS BS2000/OSD ÷ ÷ ʿ ڵ. BS2000/OSD ÷ ʿ ̿ ٷ.

  2. ؿ ASCII EBCDIC ȭ (BS2000 POSIX ϴ ɼ ִ) HTTP ؿ ۵Ǵ ڷῡ ݰ ڿ ݰ Ϲ ֱ⶧ ǵ ʾҴ. HTTP ڿ (GET û, Header: , Ÿ .) ׻ ASCII ̰, κ (, GIF ׸, CGI .) ׻ "ȯʰ ׳" Ѵ. ڵ " ڿ" "Ϲ ڷ", ڿ bgets() rvputs(), ̳ʸ ڷῡ bgets() rvputs() Լ Ͽ Ѵ. ׷Ƿ ȯϴ ʴ.

    ( EBCDIC ׻ ASCII ϵ غؾ Ѵ)

  3. ׷ ÿ (Ϸ EBCDIC ڿ ȯ) ڿ ⺻ ؿ ȯϴ ִ. ڵ忡 ASCII escape \012 \015 ܴ: ̵ ̹ ASCII \n \r ̳ʸ ̱⶧ ASCII ι ȯϸ ȵȴ. ܴ ڿ ȴ; ܺ EBCDIC ASCII ٹٲ޹ڸ ϸ ȵȴ.

  4. BUFF Լ ϴ 캻 puts/write/get/gets ġԵǴ "ebcdic/ascii ȯ " ߰ϰ, ȯ ִ ȯ ǥø ߰ߴ. (̳ CGI ) (û Ŭ̾Ʈ) ̵Ҷ ׻ ι : -> ġ, ġ -> Ŭ̾Ʈ.

    EBCDIC CGI ũƮ а, ũƮ ASCII ˾Ƴ ִ (WWW 湮ڼ α׷ : GIF ׸̴). ⺻ EBCDIC óѴ; ׷ type ̹ ASCII Ȥ EBCDIC ȯ ؾ ϴ Ѵ.

  5. (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" ִ.

  6. Ϲ ڰ ƴ ȯ ׻ "̳ʸ" Ѵ. , GIF/ZIP/AU Ŀ ̴. ڴ "rcp -b" ̳ʸ ɼ Ͽ ÷ ȣƮ ߾ Ѵ.

  7. Ľ ׻ ǻͰ ϴ ⺻ (, EBCDIC) Ǿٰ ϰ, óĿ ȯѴ.

  8. CGI CGI ũƮ ȯ ʿ Ѵ: Content-Type Ͽ, ȯϰ, GIF ȯ ִ. 츮 wwwcount α׷ .

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_imagemap +
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

ڰ

JK (mod_jserv) - JAVA ̴.
mod_php3 + mod_php3 LDAP, GD, FreeType ̺귯 Բ Ѵ.
mod_put ? ׽Ʈȵ
mod_session - ׽Ʈȵ

:  en  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/netware.html.ko.euc-kr0000664000175100017510000006452314743132254023022 0ustar covenercovener Novell NetWare ġ ϱ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Novell NetWare ġ ϱ

ֽ ƴմϴ. ֱٿ ϼ.

Novell NetWare 6.0 ̻󿡼 ġ 2.0 ġ, , ϴ Ѵ. ׸ ãҰų ٸ ʹٸ, ̿ϱ ٶ.

dev-httpd ϸƮ ġ ࿡ ʴ´. ׸ ϱ  (FAQ) , ٸ ù . ׷ ñ ̳ ִٸ, NetWare ġ 뿡 ư ο ġ ڰ ִ novell.devsup.webserver ׷쿡 ø ٶ.

̳ʸ ġ ġߴٰ Ѵ. (Ƹ ߿ ְų ׸ ã) ġ Ϸ Ʒ NetWare ġ ϱ ϶.

Support Apache!

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 ġѴٰ Ѵ):

ҽ NetWare ġ ġϴ (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

ġ ġ ã ˾Ƶξ Ѵ. ࿡ ϴ ΰ:

apache2 -f "vol:/my server/conf/my.conf"

apache -f test/test.conf

ùٸ ServerRoot ؾ Ѵ.

-f ϸ , ġ ϵ ϸ ( conf/httpd.conf) Ѵ. -V ɼ ġ ϸ SERVER_CONFIG_FILE̶ ׸ ش. ġ ServerRoot ã´:

ϵ 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 þ:

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 Ͽ ġ ϱ:

߰ make ɼ

:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/index.html.fr.utf80000664000175100017510000001457314740503670022163 0ustar covenercovener Notes spécifiques aux différentes plateformes. - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4

Notes spécifiques aux différentes plateformes.

Langues Disponibles:  en  |  fr  |  ko  |  zh-cn 

Support Apache!
top

Microsoft Windows

Utilisation d'Apache

Ce document explique comment installer, configurer et exécuter Apache 2.4 sous Microsoft Windows.

Voir : Utilisation d'Apache avec Microsoft Windows

Compilation d'Apache

Il y a de nombreux points importants à connaître avant de se lancer dans la compilation d'Apache. Ce document en donne la description.

Voir : Compilation d'Apache pour Microsoft Windows

top

Systèmes de type Unix

Systèmes à base de paquets RPM (Redhat / CentOS / Fedora)

Ce document explique comment installer, configurer et exécuter Apache 2.4 sur des systèmes qui supportent le format de paquet RPM.

Voir : Utilisation d'Apache avec les systèmes à base de paquets RPM

top

Autres plateformes

Novell NetWare

Ce document explique comment installer, configurer et exécuter Apache 2.4 sous Novell NetWare versions 5.1 et supérieures.

Voir : Utilisation d'Apache avec Novell NetWare

EBCDIC

La version 1.3 du serveur HTTP Apache est la première à avoir été portée vers une machine de type mainframe (non-ASCII) qui utilisait le jeu de caractères EBCDIC comme jeu de caractères natif.

Avertissement :Ce document n'a pas fait l'objet d'une mise à jour pour intégrer les modifications intervenues à partir de la version 2.4 du serveur HTTP Apache. Certaines des informations qu'il contient sont toujours pertinentes, mais il est conseillé de les utiliser avec prudence.

Voir : Le portage d'Apache vers EBCDIC

Langues Disponibles:  en  |  fr  |  ko  |  zh-cn 

httpd-2.4.64/docs/manual/platform/windows.html.ko.euc-kr0000664000175100017510000007740114743132254023046 0ustar covenercovener Microsoft Windows ġ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Microsoft Windows ġ

ֽ ƴմϴ. ֱٿ ϼ.

Microsoft Windows ġ 2.0 ġ, , ϴ Ѵ. ߸ κ ְų ٸ ַ, ϱ ٶ.

ġ ̳ʸ ġѴٰ Ѵ. (Ƹ Ȥ ׸ ã) ġ Ϸ Microsoft Windows ġ ϶.

Microsoft Windows ü å Ѵ:

Support Apache!

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. (Server Name). ü DNS ̸. ⿡ server.mydomain.net ԷѴ.

  3. ڿ ּ (Administrator's Email Address). ⿡ ڳ ڿ ּҸ ԷѴ. ⺻ Ŭ̾Ʈ ּҸ Ѵ.

  4. (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 Ʈ, ) Ѵ.

  5. ġ (The installation type). ߿ ʿ ҽڵ ̺귯 ġϷ Typical Ѵ. Custom ϸ ġ ִ. ü ġ ũ 13 ްƮ ʿϴ. ġ Ʈ ũ⸦ ̴.

  6. ġ (Where to install). ⺻ δ C:\Program Files\Apache Group̰, ̰ Apache2 丮 .

ġ ġ conf 丮 ִ ϵ ġ 丮 ° Ѵ. ׷ 丮 ̹ ִٸ ״ д. , ش ο 纻 Ȯ .default δ. , conf\httpd.conf ̹ ִٸ conf\httpd.conf.default ̸ Ѵ. ġ .default 캸, ʿϴٸ ؾ Ѵ.

, ̹ htdocs\index.html̶ ִٸ ״ д (index.html.default ʴ´). , ġ ġִ ϰ ġ ġ ִ. ġϱ ߴϰ, ġ ο ؾ Ѵ.

ġ ġ ʿϴٸ conf 丮 ִ ؾ Ѵ. ġ ġ 丮 htdocs 丮 ִ ϵ ִ. ġ ϱ ؾ ɼ . ׷ غ ֵ ⺻ Ϸε Ѵ.

top

Windows ġ ϱ

ġ conf 丮 ִ Ϸ Ѵ. н , Windows ġ Ư þ  ִ. 밡 þ þ ϶.

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. 񽺷 α׿  ü Ϻη Ȱ οѴ. Windows NT 4.0 User Manager for Domains ο ְ, Windows 2000 XP Ƹ "׷ å" ؾ Ѵ. " " MMC ο ִ.
  3. Users ׷쿡 ϴ ȮѴ.
  4. ũƮ ( htdocs cgi-bin) б (RX) οѴ.
  5. ġ logs 丮 (RWXD) οѴ.
  6. Apache.exe Ͽ б (RX) οѴ.
ġ 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 ߿ :

ġ ܼ α׷ ȮϿٸ 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

ġ ٷ궧 ġ  ã ƴ ߿ϴ. ΰ ࿡ ִ:

ServerRoot ؾ Ѵ.

-f -n , ġ conf\httpd.conf ϵ ϸ Ѵ. ⺻ δ ġ 丮 ̴. -V ɼ ġ ϸ SERVER_CONFIG_FILE̶ ׸񿡼 ִ:

apache -V

ġ ServerRoot ã´:

  1. -C ɼǿ ServerRoot þ.
  2. -d ɼ.
  3. ۾ 丮.
  4. ̳ʸ ġ ߴٸ ġҶ registry ׸.
  5. ϵ server root. ⺻ /apachḛ, apache -V ϸ HTTPD_ROOT ׸񿡼 Ȯ ִ.

ġҶ Ʈ Ư Ʈ Ű . Ű ġ ġ ٸ. 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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/perf-hp.html.ko.euc-kr0000664000175100017510000001735714743132254022721 0ustar covenercovener HPUX ϱ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > 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

:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/win_compiling.html.fr.utf80000664000175100017510000007651014740503670023711 0ustar covenercovener Compiler Apache pour Microsoft Windows - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Notes spécifiques à certaines plates-formes

Compiler Apache pour Microsoft Windows

Langues Disponibles:  en  |  fr  |  ko 

Il y a de nombreux points importants à connaître avant de compiler Le serveur HTTP Apache pour Microsoft Windows. Avant de commencer, lisez le document Utiliser le serveur HTTP Apache avec Microsoft Windows.

httpd peut être compilé sous Windows en utilisant une chaîne de compilation basée sur cmake, ou à partir de fichiers projet Visual Studio maintenus par les développeurs de httpd. La chaîne de compilation basée sur cmake supporte directement davantage de versions de Visual Studio, mais possède actuellement des fonctionnalités très limitées.

Support Apache!

Voir aussi

top

Prérequis

Pour compiler Apache, l'environnement doit satisfaire aux conditions suivantes :

top

Compilation à partir des sources Unix

Le projet du serveur HTTP Apache à pour politique de ne fournir que des sources de type Unix. Les paquets source de type Windows disponibles en téléchargement ont été élaborés par des contributeurs, et ne seront pas forcément reconduits pour toutes les versions. Vous pouvez cependant compiler le serveur sous Windows à partir des sources Unix en ajoutant quelques étapes supplémentaires.

  1. Téléchargez et ouvrez le tarball source Unix de la dernière version du serveur HTTP Apache.
  2. Téléchargez et ouvrez le tarball source Unix de la dernière version de APR, APR-Util et APR-Iconv, et copier l'arborescence obtenue dans httpd-2.x.x\srclib\apr, httpd-2.x.x\srclib\apr-util et httpd-2.x.x\srclib\apr-iconv
  3. Ouvrez la console et placez-vous au niveau du répertoire httpd-2.x.x
  4. Exécutez l'utilitaire de conversion de fins de ligne

perl srclib\apr\build\lineends.pl

Vous pouvez maintenant compiler le serveur via l'environnement de développement Visual Studio en utilisant l'IDE. Les compilations du serveur en ligne de commande ne sont possibles avec des sources de type Unix que si vous exportez les fichiers .mak comme indiqué ci-dessous.

top

Compilation à partir de la ligne de commandes

Makefile.win est le makefile principal ou racine d'Apache. Pour compiler Apache sous Windows, utilisez simplement une des commandes suivantes pour compiler la version release ou debug :

nmake /f Makefile.win _apacher

nmake /f Makefile.win _apached

Ces deux commandes effectuent la compilation d'Apache. Cependant, avec la deuxième, les fichiers résultants ne seront pas optimisés, ce qui va faciliter l'examen pas à pas du code pour trouver des bogues et résoudre les problèmes.

Vous pouvez indiquer vos choix en matière de fournisseurs dbd et dbm à l'aide des variables (d'environnement) additionnelles de make DBD_LIST et DBM_LIST ; voir les commentaires à propos des [Optionnel] Bibliothèques de bases de données ci-dessus. Consultez les commentaires initiaux dans Makefile.win pour plus d'options pouvant être fournies lors de la compilation.

top

Compilation depuis l'espace de travail IDE de Developer Studio

Apache peut aussi être compilé depuis l'environnement de développement Visual Studio de VC++. Pour simplifier ce processus, l'espace de travail Visual Studio Apache.dsw est fourni. Cet espace de travail expose la liste complète des projets .dsp actifs nécessaires à l'installation binaire complète d'Apache. Il inclut les dépendances entre projets afin que ces derniers soient compilés selon l'ordre approprié.

Ouvrez l'espace de travail Apache.dsw, et sélectionnez InstallBin (compilation Release ou Debug, selon vos souhaits) comme Active Project. InstallBin provoque la compilation de tous les projets concernés, puis invoque Makefile.win pour installer les exécutables et dlls compilés. Vous pouvez modifier la valeur de INSTDIR= via la configuration de InstallBin, onglet Général, entrée ligne de commandes de compilation. La valeur par défaut de INSTDIR est le répertoire /Apache2. Si vous désirez effectuer un test de compilation (sans installation), sélectionnez le projet BuildBin.

Les fichiers projets .dsp sont distribués au format Visual Studio 6.0 (98). Visual C++ 5.0 (97) les reconnaît. Les utilisateurs de Visual Studio 2002 (.NET) et versions supérieures doivent convertir Apache.dsw et les fichiers .dsp en un projet Apache.sln, ainsi que les fichiers .msproj ; assurez-vous de reconvertir le fichier .msproj si l'un des fichiers source .dsp est modifié ! Cette opération est vraiment très simple, il suffit de réouvrir Apache.dsw dans l'IDE VC++ 7.0 et de le reconvertir.

Il y a une erreur dans la conversion .vcproj des fichiers .dsp. devenv.exe interprète mal le drapeau /D pour les drapeaux RC contenant de grandes /D'éfinitions entourées de guillemets, et contenant elles-mêmes des espaces. Ainsi, la commande :

perl srclib\apr\build\cvtdsp.pl -2005

va convertir les drapeaux /D pour les drapeaux RC afin d'utiliser une syntaxe alternative, interprétable ; malheureusement, cette syntaxe n'est pas supportée par Visual Studio 97 ou ses fichiers .mak exportés. Ces drapeaux /D permettent de transmettre la longue description des fichiers de mod_apachemodule.so à leurs compilations d'identificateur de version de ressource .rc partagée.
Compilation avec OpenSSL versions 1.1.0 et supérieures Suite à une modification de la structure de compilation d'OpenSSL à partir de la version 1.1.0, vous devez convertir les fichiers dsp concernés via la commance cvtdsp.pl fournie par APR versions 1.6 et supérieures :

perl srclib\apr\build\cvtdsp.pl -ossl11

Les utilisateurs de Visual Studio 2002 (.NET) et versions supérieures doivent aussi utiliser la boîte de dialogue Configuration Manager du menu Build pour décocher les deux versions Debug et Release des modules mod_ssl et mod_deflate pour abs. Ces modules sont compilés en invoquant nmake ou directement l'IDE avec la cible BinBuild pour compiler ces modules de manière conditionnelle si les sous-répertoires de srclib openssl et/ou zlib existent, et en fonction des définitions des variables d'environnement DBD_LIST et DBM_LIST.

top

Export des fichiers .mak de la ligne de commandes

Les fichiers .mak exportés posent plus de problèmes, mais les utilisateurs de Visual C++ 5.0 en ont besoin pour compiler mod_ssl, abs (ab avec support SSL) et/ou mod_deflate. Les fichiers .mak supportent aussi un choix plus large de distributions de chaînes d'outils C++, comme Visual Studio Express.

Vous devez tout d'abord compiler tous les projets afin de créer toutes les cibles dynamiques auto-générées, de façon à ce que les dépendances puissent être interprétées correctement. Compilez l'ensemble du projet depuis l'IDE Visual Studio 6.0 (98), en utilisant la cible BuildAll, puis utilisez le menu de projet Export pour tous les makefiles (en cochant "with dependencies"). Utilisez la commande suivante pour transformer les chemins absolus en chemins relatifs de façon à ce que la compilation puisse s'effectuer depuis n'importe quelle position dans l'arborescence :

perl srclib\apr\build\fixwin32mak.pl

Vous devez exécuter cette commande depuis la racine de l'arborescence des sources de httpd. Tout fichier projet .mak et .dep du répertoire courant et de ses sous-répertoires sera corrigé, et les repères de temps ajustés en fonction des .dsp.

Vérifiez toujours le SDK de la plate-forme ou autres chemins fichiers locaux, spécifiques à la machine dans les fichiers .mak et .dep générés. Le répertoire DevStudio\Common\MSDev98\bin\ (VC6) contient un fichier sysincl.dat qui énumère toutes les exceptions. Mettez à jour ce fichier (en particulier les chemins avec slashes et anti-slashes, tels que sys/time.h et sys\time.h) de façon à ignorer ces nouvelles dépendances. Inclure les chemins d'installation locale dans un fichier .mak distribué fera échouer la compilation.

Si vous soumettez un patch qui modifie les fichiers projet, nous devons valider la modification de ces fichiers projet au format Visual Studio 6.0. Les modifications doivent êtres simples, avec un minimum de drapeaux de compilation et d'édition de liens qui pourront être reconnus par tous les environnements Visual Studio.

top

Installation

Une fois compilé, Apache doit être installé dans le répertoire racine du serveur. La valeur par défaut est le répertoire \Apache2, sur le même disque.

Pour compiler et installer automatiquement tous les fichiers dans le répertoire rep désiré, utilisez une des commandes nmake suivantes :

nmake /f Makefile.win installr INSTDIR=dir
nmake /f Makefile.win installd INSTDIR=dir

L'argument rep de INSTDIR permet de spécifier le répertoire d'installation ; il peut être omis si Apache doit être installé dans \Apache22 (du lecteur de disque courant.

top

Avertissement à propos de la compilation d'Apache à partir de l'arborescence de développement

Notez que seuls les fichiers .dsp sont maintenus d'une distribution release à l'autre. Les fichiers .mak ne sont PAS régénérés, suite à l'énorme perte de temps des relecteurs . Vous ne pouvez donc pas utiliser les commandes NMAKE ci-dessus pour compiler des fichiers de projet .dsp révisés si vous n'exporter pas ensuite vous-même tous les fichiers .mak du projet. Ceci n'est pas nécessaire si vous effectuez la compilation depuis l'environnement Microsoft Developer Studio.
top

Compilation de httpd avec cmake

La documentation principale pour ce mécanisme de compilation se trouve dans le fichier README.cmake situé dans l'arborescence des sources. Consultez ce fichier pour des instructions détaillées.

Pour compiler httpd avec cmake, vous devez compiler APR et APR-util séparément. Consultez les fichiers README.cmake de ces projets pour obtenir des instructions.

Les principales limitations de la compilation basée sur cmake sont héritées du projet APR-util et sont énumérées ci-dessous à cause de leur impact sur httpd :

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/rpm.html.fr.utf80000664000175100017510000003171214740503670021644 0ustar covenercovener Utiliser Apache sur les systèmes à base de paquets RPM (Redhat / CentOS / Fedora) - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Notes spécifiques aux différentes plateformes

Utiliser Apache sur les systèmes à base de paquets RPM (Redhat / CentOS / Fedora)

Langues Disponibles:  en  |  fr 

Alors que de nombreuses distributions mettent à disposition des paquets Apache httpd supportés par le système d'exploitation sous-jacent, il peut s'avérer nécessaire d'installer et d'utiliser la version de base d'Apache httpd en remplacement de la version des paquets.

Bien que le projet Apache httpd ne crée pas actuellement de paquets RPM pour les différentes distributions, il est aisé de construire votre propre paquet RPM à partir du tarball de base d'Apache httpd.

Ce document explique comment construire, installer, configurer et exécuter Apache httpd 2.4 sur les systèmes Unix à base de paquets RPM.

Support Apache!

Voir aussi

top

Création d'un paquet RPM source

Le tarball d'Apache httpd peut être converti en paquet SRPM de la manière suivante :

rpmbuild -ts httpd-2.4.x.tar.bz2

top

Création d'un paquet RPM

Le tarball d'Apache httpd peut être converti en paquet RPM de la manière suivante :

rpmbuild -tb httpd-2.4.x.tar.bz2

Il sera nécessaire d'installer les paquets "-devel" correspondants avant de construire les RPMs ; à cet effet, la commande rpmbuild détecte automatiquement les RPMs requis et en donne la liste sous forme de dépendances manquantes sur votre système. Ces paquets "-devel" ne seront d'ailleurs plus nécessaires une fois la création des RPMs terminée, et pourront alors être supprimés sans risque.

Si tout va bien, les RPMs suivants seront créés :

httpd-2.4.x-1.i686.rpm
Le serveur de base et le jeu de modules standards.
httpd-debuginfo-2.4.x-1.i686.rpm
Les symboles de débogage pour le serveur et tous les modules.
httpd-devel-2.4.x-1.i686.rpm
Les en-têtes et fichiers de développement pour le serveur.
httpd-manual-2.4.x-1.i686.rpm
Le manuel du serveur web.
httpd-tools-2.4.x-1.i686.rpm
Les utilitaires du serveur web.
mod_authnz_ldap-2.4.x-1.i686.rpm
Les modules mod_ldap et mod_authnz_ldap avec les dépendances correspondantes sur openldap.
mod_lua-2.4.x-1.i686.rpm
Le module mod_lua avec les dépendances correspondantes sur lua.
mod_proxy_html-2.4.x-1.i686.rpm
Le module mod_proxy_html avec les dépendances correspondantes sur libxml2.
mod_socache_dc-2.4.x-1.i686.rpm
Le module mod_socache_dc avec les dépendances correspondantes sur distcache.
mod_ssl-2.4.x-1.i686.rpm
Le module mod_ssl avec les dépendances correspondantes sur openssl.
top

Installation du serveur

Le RPM httpd est le seul paquet nécessaire pour obtenir un serveur de base fonctionnel. Vous pouvez l'installer comme suit :

rpm -U httpd-2.4.x-1.i686.rpm

Le jeu de modules standards est inclus dans le serveur. Les modules qui dépendent de bibliothèques externes sont fournis en tant que paquets RPM séparés et doivent être installés si nécessaire.

top

Configuration de l'instance par défaut d'Apache httpd

Les répertoires par défaut sont /etc/httpd pour la configuration du serveur, et /var/log/httpd pour la journalisation. L'environnement par défaut du serveur web est défini dans le répertoire optionnel /etc/sysconfig/httpd.

Démarrez le serveur comme suit :

service httpd restart

top

Configuration d'instances d'Apache httpd supplémentaires sur la même machine

Il est possible d'exécuter simultanément plusieurs instances du serveur Apache httpd sur la même machine. Chaque instance peut posséder sa propre configuration et en fonction de cette dernière, s'exécuter sous un utilisateur différent.

Pour parvenir à ce résultat, on a fait en sorte que le script de démarrage de httpd ait connaissance de son propre nom. Ce nom est par la suite utilisé pour trouver le fichier d'environnement associé au serveur, et par conséquent, la racine de l'instance du serveur considéré.

Pour créer une instance supplémentaire appelée httpd-additional, suivez ces étapes :

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/win_compiling.html.ko.euc-kr0000664000175100017510000005244014743132254024206 0ustar covenercovener Microsoft Windows ġ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Microsoft Windows ġ

ֽ ƴմϴ. ֱٿ ϼ.

ġ ϱ . ̸ Microsoft Windows ġ ϶.

Support Apache!

top

ġ Ϸ ġǾ Ѵ:

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. srclib\apr\libapr.dsp
  3. srclib\apr-util\uri\gen_uri_delims.dsp
  4. srclib\apr-util\xml\expat\lib\xml.dsp
  5. srclib\apr-util\aprutil.dsp
  6. srclib\apr-util\libaprutil.dsp
  7. srclib\pcre\dftables.dsp
  8. srclib\pcre\pcre.dsp
  9. srclib\pcre\pcreposix.dsp
  10. server\gen_test_char.dsp
  11. libhttpd.dsp
  12. Apache.dsp

, modules\ 丮 Ʒ κ ⿡ Ʈ ִ.

support\ 丮 ġ ϴµ ʿ , ڰ ġ ˻ϰų ȣϰ α ϴµ ߰ α׷ Ʈ ִ. Windows α׷ support\win32\ 丮 ִ.

  1. support\ab.dsp
  2. support\htdigest.dsp
  3. support\htpasswd.dsp
  4. support\logresolve.dsp
  5. support\rotatelogs.dsp
  6. support\win32\ApacheMonitor.dsp
  7. support\win32\wintty.dsp

ġ ϸ server root 丮 ġؾ Ѵ. ⺻ ũ \Apache2 丮̴.

ϰ ϴ dir ڵ ġϷ nmake ɾ ϳ Ѵ:

nmake /f Makefile.win installr INSTDIR=dir

nmake /f Makefile.win installd INSTDIR=dir
    

INSTDIR dir ƱԸƮ ġ丮 Ѵ. ϸ \Apache2 ġ ġѴ.

ġѴ:

ġ Ҷ

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

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/perf-hp.html.fr.utf80000664000175100017510000002176714740503670022420 0ustar covenercovener Mise en oeuvre d'un serveur Web hautes performances sous HPUX - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Notes spécifiques aux plates-formes

Mise en oeuvre d'un serveur Web hautes performances sous HPUX

Langues Disponibles:  en  |  fr  |  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

Traduction du corps du message cité ci-dessus :

Voici quelques conseils de personnalisation pour HPUX à ajouter à la page de personnalisation.

Pour HP-UX 9.X: mettre à jour vers la version 10.20
Pour HP-UX 10.[00|01|10]: mettre à jour vers la version 10.20

Pour HP-UX 10.20:

Installez le dernier patch cumulatif à propos du transport ARPA. Ceci va vous permettre de configurer la taille de la table de hashage de recherche de connexion TCP. La valeur par défaut est 256 conteneurs et doit être une puissance de deux. À cet effet, utilisez adb pour modifier l'image *disque* du noyau. Le nom de la variable est tcp_hash_size. Notez qu'il est impératif d'utiliser "W" pour spécifier une quantité sur 32 bits, et non "w" qui indique une valeur sur 16 bits, lors de la modification de l'image disque car la variable tcp_hash_size est une quantité sur 32 bits.

Comment déterminer cette valeur ? Examinez la sortie de ftp://ftp.cup.hp.com/dist/networking/tools/connhist, et comptez le nombre total de connexions TCP existant sur le système. Il est en général souhaitable que ce nombre divisé par la taille de la table de hashage soit raisonnablement petit, disons inférieur à 10. Les administrateurs peuvent consulter le document SPECweb96 de HP pour quelques réglages courants. On peut les trouver à http://www.specbench.org/. Si un système HP-UX traite 1000 connexions SPECweb96 par seconde, une valeur de temps TIME_WAIT de 60 secondes permettrait le suivi de 60000 connexions TCP.

Les administrateurs peuvent tester la profondeur de leur file d'attente d'écoute avec ftp://ftp.cup.hp.com/dist/networking/misc/listenq.

Si Apache s'exécute sur un système à base de PA-8000, il est conseillé de modifier l'exécutable Apache avec la commande chatr afin d'utiliser une page de grande taille. La commande sera du style "chatr +pi L <BINARY>". Le GID de l'exécutable en cours de fonctionnement doit posséder le privilège MLOCK. Pour assigner ce privilège MLOCK, consultez Setprivgrp(1m). La modification peut être validée en exécutant Glance et en examinant les portions de mémoire du/des serveur(s) afin de s'assurer qu'elles montrent une fraction non triviale du segment de texte verrouillé.

Si Apache s'exécute sur un système MP (multi-processeurs), il est conseillé d'écrire un petit programme qui utilise mpctl() et permettant d'associer les processus aux processeurs. Un simple algorithme pid % numcpu suffira probablement. Cette modification peut aussi être ajoutée dans le code source.

Si l'administrateur s'intéresse au nombre de connexions FIN_WAIT_2, il peut utiliser nettune pour diminuer la valeur de tcp_keepstart. Il devra cependant être prudent - surtout ne pas diminuer cette valeur en dessous de, disons deux à quatre minutes. Si tcp_hash_size a été défini, il est probablement approprié de laisser les connexions FIN_WAIT_2 prendre plus de temps à expirer (peut-être même la valeur par défaut de deux heures) - elles n'auront en général pas un grand impact sur les performances.

On peut ajouter d'autres choses au code de base, mais elles feront peut-être l'objet d'un autre email. N'hésitez pas à m'envoyer un message si vous êtes intéressé.

sincèrement ,

rick jones

http://www.netperf.org/netperf/

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/index.html.en0000664000175100017510000001407514737241666021300 0ustar covenercovener Platform Specific Notes - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Platform Specific Notes

Available Languages:  en  |  fr  |  ko  |  zh-cn 

Support Apache!
top

Microsoft Windows

Using Apache

This document explains how to install, configure and run Apache 2.4 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

Unix Systems

RPM Based Systems (Redhat / CentOS / Fedora)

This document explains how to build, install, and run Apache 2.4 on systems supporting the RPM packaging format.

See: Using Apache With RPM Based Systems

top

Other Platforms

Novell NetWare

This document explains how to install, configure and run Apache 2.4 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.4 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  |  fr  |  ko  |  zh-cn 

httpd-2.4.64/docs/manual/platform/netware.html.fr.utf80000664000175100017510000010673214740503670022520 0ustar covenercovener Utilisation d'Apache avec Novell NetWare - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Notes spécifiques à un système

Utilisation d'Apache avec Novell NetWare

Langues Disponibles:  en  |  fr  |  ko 

Ce document explique l'installation, la configuration et le lancement d'Apache 2.0 sous Novell NetWare 6.0 et les versions ultérieures. Si vous trouvez une bogue, ou voulez tout simplement contribuer de quelque manière que ce soit, utilisez s'il vous plait notre page des rapports de bogues.

La page des rapports de bogues et la liste de diffusion dev-httpd ne doivent pas être utilisées pour poser des questions à propos de la configuration ou du lancement d'Apache. Avant de soumettre un rapport de bogue ou une question, consultez ce document, la FAQ ou tout autre sujet de la documentation en rapport avec votre problème. Si vous n'avez toujours pas résolu votre problème, postez votre question dans le newsgroup novell.devsup.webserver, où de nombreux utilisateurs d'Apache sont prêts à répondre à toutes les nouvelles et obscures questions à propos de l'utilisation d'Apache sous Netware.

Dans la majeure partie de ce document, vous êtes sensé avoir installé Apache à partir d'une distribution binaire. Si vous voulez compiler Apache vous-même (par exemple pour aider au développement, ou pour rechercher des bogues), reportez-vous à la section traitant de la Compilation d'Apache pour Netware ci-dessous.

Support Apache!

Voir aussi

top

Prérequis

Apache 2.0 nécessite NetWare 6.0 service pack 3 et supérieurs pour fonctionner. Si vous utilisez un service pack antérieur à SP3, vous devez installer les dernières Bibliothèques Netware pour C (LibC).

Vous trouverez les service packs Netware ici.

Apache 2.0 pour NetWare peut aussi fonctionner dans un environnement NetWare 5.1, à partir du moment où le dernier service pack ou la dernière version des Bibliothèques Netware pour C (LibC) ont été installés. ATTENTION : Apache 2.0 pour NetWare n'a pas été testé dans cet environnement car il n'a pas été conçu pour ce dernier.

top

Téléchargement d'Apache pour NetWare

Les informations à propos de la dernière version d'Apache sont disponibles sur le site web d'Apache à http://www.apache.org/. Vous y trouverez la version courante, des versions alpha ou bêta-test plus récentes, ainsi que des sites miroirs et des sites FTP anonymes. Les distributions binaires des dernières versions d'Apache 2.0 pour NetWare sont disponibles ici.

top

Installation d'Apache pour NetWare

Il n'existe pas actuellement de programme d'installation d'Apache pour Netware. Si vous installez Apache 2.0 pour NetWare à partir des sources, vous devrez copier les fichiers sur le serveur manuellement.

Suivez ces instructions pour installer Apache sous Netware à partir de la distribution binaire (en supposant que vous effectuez l'installation dans sys:/apache2) :

Suivez ces instructions pour installer Apache pour Netware manuellement à partir de votre propre répertoire de sources (en supposant que vous effectuez l'installation dans sys:/apache2) :

Outre le volume par défaut SYS, Apache peut être installé dans tout autre volume.

Au cours du processus d'installation, l'ajout du mot-clé "install" à la ligne de commande du makefile va provoquer la construction d'une distribution complète sous forme d'un paquetage dans le sous-répertoire DIST. Vous pouvez simplement installer Apache en copiant la distribution créée précédemment à la racine d'un volume Netware (voir Compilation d'Apache pour NetWare ci-dessous).

top

Exécuter Apache pour NetWare

Pour démarrer Apache, tapez simplement apache dans la console. Ceci aura pour effet de charger Apache dans l'espace d'adressage du système d'exploitation. Si vous préférez charger Apache dans un espace d'adressage protégé, vous pouvez spécifier cet espace d'adressage à l'aide de l'instruction de chargement suivante :

load address space = apache2 apache2

Cette instruction va charger Apache dans un espace d'adressage appelé apache2. Il est possible d'exécuter plusieurs instances simultanées d'Apache sous Netware, en chargeant chacune d'entre elles dans son propre espace d'adressage protégé.

Une fois démarré, Apache écoute le port 80 (à moins que vous n'ayez modifié la directive Listen dans les fichiers de configuration). Pour vous connecter au serveur et afficher la page par défaut, lancez un navigateur et entrez le nom du serveur ou son adresse IP. Vous devriez voir une page de bienvenue, et un lien vers le manuel Apache. Si rien ne se produit, ou si vous obtenez un message d'erreur, consultez le fichier error_log dans le répertoire logs.

Lorsque votre installation de base fonctionne, vous devez la configurer correctement en éditant les fichiers du répertoire conf.

Pour arrêter une instance d'Apache s'exécutant dans l'espace d'adressage du système d'exploitation, entrez simplement dans la console :

unload apache2

ou

apache2 shutdown

Si Apache s'exécute dans un espace d'adressage protégé, spécifiez cet espace d'adressage dans l'instruction d'arrêt :

unload address space = apache2 apache2

Lorsqu'on travaille avec Apache, il est important de savoir comment il trouve ses fichiers de configuration. Vous pouvez spécifier un fichier de configuration sur la ligne de commande de deux manières :

apache2 -f "vol:/nom-serveur/conf/fich-conf.conf"

apache -f test/test.conf

Dans ces cas, la directive ServerRoot doit être correctement définie dans le fichier de configuration.

Si vous ne spécifiez pas de nom de fichier de configuration avec l'option -f, Apache utilisera le nom de fichier codé en dur dans le serveur, en général conf/httpd.conf. L'invocation d'Apache avec l'option -V indiquera ce nom comme valeur de l'étiquette SERVER_CONFIG_FILE. Apache va ensuite déterminer son ServerRoot en effectuant les tests suivants, dans cet ordre

La racine du répertoire d'installation codée en dur dans le serveur est en général sys:/apache2. L'invocation d'Apache avec l'option -V indiquera ce chemin comme valeur de l'étiquette HTTPD_ROOT.

Apache 2.0 pour Netware comporte un jeu d'options de ligne de commande permettant d'afficher ou de modifier certaines caractéristiques de l'instance du serveur web en cours d'exécution. Ces options ne sont disponibles que lorsqu'Apache est en cours d'exécution. Chacune de ces options doit être précédée du mot-clé APACHE2.

RESTART
Demande à Apache d'arrêter tout worker thread en cours d'exécution lorsqu'il devient inactif, de recharger le fichier de configuration, et de redémarrer chaque worker thread en fonction de la nouvelle configuration.
VERSION
Affiche des informations à propos de la version de l'instance d'Apache en cours d'exécution.
MODULES
Affiche la liste des modules chargés (intégrés et externes).
DIRECTIVES
Affiche la liste des directives disponibles.
SETTINGS
Active ou désactive l'affichage du statut des threads sur la console. En cas d'activation, l'état de chaque thread en cours d'exécution s'affiche sur l'écran de la console Apache.
SHUTDOWN
Arrête l'instance du serveur web Apache en cours d'exécution.
HELP
Décrit chacune des options disponibles au cours de l'exécution d'Apache.

Par défaut, ces options sont passées à l'instance d'apache s'exécutant dans l'espace d'adressage du système d'exploitation. Pour passer une option à une instance d'Apache spécifique s'exécutant dans un espace d'adressage protégé, ajouter le paramètre -p suivi du nom de l'espace d'adressage. Pour plus d'informations, tapez "apache2 Help" sur la ligne de commande.

top

Configuration d'Apache pour NetWare

Apache lit en général ses fichiers de configuration dans le répertoire conf. Ces fichiers sont les mêmes que ceux de la version Unix, mais quelques directives sont différentes sous Netware. Voir la Documentation Apache pour l'ensemble des directives disponibles.

Les principales différences propres à Apache pour NetWare sont :

Autres directives spécifiques à Netware :

top

Compilation d'Apache pour NetWare

La compilation d'Apache nécessite MetroWerks CodeWarrior 6.x ou supérieur. Une fois compilé, Apache peut être installé à la racine de tout volume Netware. Le répertoire d'installation par défaut est sys:/Apache2.

Avant de démarrer Apache, vous devez remplir le répertoire conf. Copiez le fichier HTTPD-STD.CONF depuis le répertoire conf de la distribution et renommez-le en HTTPD.CONF. Editez le fichier HTTPD.CONF en recherchant les repères @@Value@@, et remplacez ces derniers par la valeur appropriée. Copiez de même les fichiers conf/magic et conf/mime.types. Vous pouvez aussi construire une distribution complète en ajoutant le mot-clé install lors de l'invocation des makefiles.

Prérequis :

Les outils de développement suivants sont nécessaires pour la compilation d'Apache pour Netware :

Compiler Apache en utilisant les makefiles Netware :

Options de make supplémentaires

Variables d'environnement supplémentaires

Compilation de mod_ssl pour la plate-forme Netware

Pour fournir les services SSL, Apache pour Netware utilise par défaut le module intégré mod_nw_ssl. Ce module ne fournit que les services SSL implémentés par le système d'exploitation Netware lui-même pour gérer tous les chiffrements pour un port donné. Cependant, on peut aussi utiliser mod_ssl de la même manière que sur les autres plate-formes.

Afin de pouvoir compiler mod_ssl pour la plate-forme Netware, les bibliothèques OpenSSL doivent être disponibles. Elles peuvent être installées de la manière suivante :

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/netware.html.en0000664000175100017510000010127714737241666021637 0ustar covenercovener Using Apache With Novell NetWare - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Using Apache With Novell NetWare

Available Languages:  en  |  fr  |  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.

Support Apache!

See also

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):

Follow these steps to install Apache on NetWare manually from your own build source (assuming you will install to 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:

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:

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 module documentation for all the available directives.

The main differences in Apache for NetWare are:

Additional NetWare specific directives:

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:

Additional make options

Additional environment variable options

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:

Available Languages:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/win_compiling.html.en0000664000175100017510000006603314737241666023030 0ustar covenercovener Compiling Apache for Microsoft Windows - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Compiling Apache for Microsoft Windows

Available Languages:  en  |  fr  |  ko 

There are many important points to consider before you begin compiling Apache HTTP Server (httpd). See Using Apache HTTP Server on Microsoft Windows before you begin.

httpd can be built on Windows using a cmake-based build system or with Visual Studio project files maintained by httpd developers. The cmake-based build system directly supports more versions of Visual Studio but currently has considerable functional limitations.

Support Apache!

See also

top

Building httpd with the included Visual Studio project files

Requirements

Compiling Apache requires the following environment to be properly installed:

Building from Unix sources

The policy of the Apache HTTP Server project is to only release Unix sources. Windows source packages made available for download have been supplied by volunteers and may not be available for every release. You can still build the server on Windows from the Unix source tarball with just a few additional steps.

  1. Download and unpack the Unix source tarball for the latest version.
  2. Download and unpack the Unix source tarball for latest version of APR, AR-Util and APR-Iconv, place these sources in directories httpd-2.x.x\srclib\apr, httpd-2.x.x\srclib\apr-util and httpd-2.x.x\srclib\apr-iconv
  3. Open a Command Prompt and CD to the httpd-2.x.x folder
  4. Run the line endings conversion utility at the prompt;

perl srclib\apr\build\lineends.pl

You can now build the server with the Visual Studio development environment using the IDE. Command-Line builds of the server are not possible from Unix sources unless you export .mak files as explained below.

Command-Line Build

Makefile.win is the top level Apache makefile. To compile Apache on Windows, simply use one of the following commands to build the release or debug flavor:

nmake /f Makefile.win _apacher

nmake /f Makefile.win _apached

Either command will compile Apache. The latter will disable optimization of the resulting files, making it easier to single step the code to find bugs and track down problems.

You can add your apr-util dbd and dbm provider choices with the additional make (environment) variables DBD_LIST and DBM_LIST, see the comments about [Optional] Database libraries, above. Review the initial comments in Makefile.win for additional options that can be provided when invoking the build.

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 Studio 6.0 (98) format. Visual C++ 5.0 (97) will recognize them. Visual Studio 2002 (.NET) and later users must convert Apache.dsw plus the .dsp files into an Apache.sln plus .msproj files. Be sure you reconvert the .msproj file again if its source .dsp file changes! This is really trivial, just open Apache.dsw in the VC++ 7.0 IDE once again and reconvert.

There is a flaw in the .vcproj conversion of .dsp files. devenv.exe will mis-parse the /D flag for RC flags containing long quoted /D'efines which contain spaces. The command:

perl srclib\apr\build\cvtdsp.pl -2005

will convert the /D flags for RC flags to use an alternate, parseable syntax; unfortunately this syntax isn't supported by Visual Studio 97 or its exported .mak files. These /D flags are used to pass the long description of the mod_apachemodule.so files to the shared .rc resource version-identifier build.
Building with OpenSSL 1.1.0 and up Due to difference in the build structure of OpenSSL begining with version 1.1.0 you will need to convert the dsp files affected with cvtdsp.pl from APR 1.6 or greater. The command:

perl srclib\apr\build\cvtdsp.pl -ossl11

Visual Studio 2002 (.NET) and later users should also use the Build menu, Configuration Manager dialog to uncheck both the Debug and Release Solution modules abs, mod_deflate and mod_ssl components, as well as every component starting with apr_db*. These modules are built by invoking nmake, or the IDE directly with the BinBuild target, which builds those modules conditionally if the srclib directories openssl and/or zlib exist, and based on the setting of DBD_LIST and DBM_LIST environment variables.

Exporting command-line .mak files

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. The .mak files also support a broader range of C++ tool chain distributions, such as Visual Studio Express.

You must first build all projects in order to create all dynamic auto-generated targets, so that dependencies can be parsed correctly. Build the entire project from within the Visual Studio 6.0 (98) IDE, using the BuildAll target, then use the Project Menu Export for all makefiles (checking on "with dependencies".) Run the following command to correct absolute paths into relative 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.

Always review the generated .mak and .dep files for Platform SDK or other local, machine specific file paths. The DevStudio\Common\MSDev98\bin\ (VC6) directory contains a sysincl.dat file, which lists all exceptions. Update this file (including both forward and backslashed paths, such as both sys/time.h and sys\time.h) to ignore such newer dependencies. Including local-install paths in a distributed .mak file will cause the build to fail completely.

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 can be recognized by all Visual Studio environments.

Installation

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 provides the installation directory; it can be omitted if Apache is to be installed into \Apache22 (of the current drive).

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

Building httpd with cmake

The primary documentation for this build mechanism is in the README.cmake file in the source distribution. Refer to that file for detailed instructions.

Building httpd with cmake requires building APR and APR-util separately. Refer to their README.cmake files for instructions.

The primary limitations of the cmake-based build are inherited from the APR-util project, and are listed below because of their impact on httpd:

Available Languages:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/ebcdic.html.en0000664000175100017510000005773414737241666021413 0ustar covenercovener The Apache EBCDIC Port - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

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.
Support Apache!

See also

top

Overview of the Apache EBCDIC Port

Version 1.3 of the Apache HTTP Server was the first version which included 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

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:

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

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

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

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

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

  7. Server parsed files are always assumed to be in native (i.e., EBCDIC) format as used on the machine, and are converted after processing.

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

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

Module Status Notes
core +
mod_access +
mod_actions +
mod_alias +
mod_asis +
mod_auth +
mod_authn_anon +
mod_authn_dbm ? with own libdb.a
mod_authz_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

Module Status Notes
JK (Formerly 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 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/rpm.html.en0000664000175100017510000003021314737241666020757 0ustar covenercovener Using Apache With RPM Based Systems (Redhat / CentOS / Fedora) - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Using Apache With RPM Based Systems (Redhat / CentOS / Fedora)

Available Languages:  en  |  fr 

While many distributions make Apache httpd available as operating system supported packages, it can sometimes be desirable to install and use the canonical version of Apache httpd on these systems, replacing the natively provided versions of the packages.

While the Apache httpd project does not currently create binary RPMs for the various distributions out there, it is easy to build your own binary RPMs from the canonical Apache httpd tarball.

This document explains how to build, install, configure and run Apache httpd 2.4 under Unix systems supporting the RPM packaging format.

Support Apache!

See also

top

Creating a Source RPM

The Apache httpd source tarball can be converted into an SRPM as follows:

rpmbuild -ts httpd-2.4.x.tar.bz2

top

Building RPMs

RPMs can be built directly from the Apache httpd source tarballs using the following command:

rpmbuild -tb httpd-2.4.x.tar.bz2

Corresponding "-devel" packages will be required to be installed on your build system prior to building the RPMs, the rpmbuild command will automatically calculate what RPMs are required and will list any dependencies that are missing on your system. These "-devel" packages will not be required after the build is completed, and can be safely removed.

If successful, the following RPMs will be created:

httpd-2.4.x-1.i686.rpm
The core server and basic module set.
httpd-debuginfo-2.4.x-1.i686.rpm
Debugging symbols for the server and all modules.
httpd-devel-2.4.x-1.i686.rpm
Headers and development files for the server.
httpd-manual-2.4.x-1.i686.rpm
The webserver manual.
httpd-tools-2.4.x-1.i686.rpm
Supporting tools for the webserver.
mod_authnz_ldap-2.4.x-1.i686.rpm
mod_ldap and mod_authnz_ldap, with corresponding dependency on openldap.
mod_lua-2.4.x-1.i686.rpm
mod_lua module, with corresponding dependency on lua.
mod_proxy_html-2.4.x-1.i686.rpm
mod_proxy_html module, with corresponding dependency on libxml2.
mod_socache_dc-2.4.x-1.i686.rpm
mod_socache_dc module, with corresponding dependency on distcache.
mod_ssl-2.4.x-1.i686.rpm
mod_ssl module, with corresponding dependency on openssl.
top

Installing the Server

The httpd RPM is the only RPM necessary to get a basic server to run. Install it as follows:

rpm -U httpd-2.4.x-1.i686.rpm

Self contained modules are included with the server. Modules that depend on external libraries are provided as separate RPMs to install if needed.

top

Configuring the Default Instance of Apache httpd

The default configuration for the server is installed by default beneath the /etc/httpd directory, with logs written by default to /var/log/httpd. The environment for the webserver is set by default within the optional /etc/sysconfig/httpd file.

Start the server as follows:

service httpd restart

top

Configuring Additional Instances of Apache httpd on the Same Machine

It is possible to configure additional instances of the Apache httpd server running independently alongside each other on the same machine. These instances can have independent configurations, and can potentially run as separate users if so configured.

This was done by making the httpd startup script aware of its own name. This name is then used to find the environment file for the server, and in turn, the server root of the server instance.

To create an additional instance called httpd-additional, follow these steps:

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/windows.html.en0000664000175100017510000010172314737241666021660 0ustar covenercovener Using Apache HTTP Server on Microsoft Windows - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Using Apache HTTP Server on Microsoft Windows

Available Languages:  en  |  fr  |  ko 

This document explains how to install, configure and run Apache 2.4 under Microsoft Windows. If you have questions after reviewing the documentation (and any event and error logs), you should consult the peer-supported users' mailing list.

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.

Support Apache!

See also

top

Operating System Requirements

The primary Windows platform for running Apache 2.4 is Windows 2000 or later. Always obtain and install the current service pack to avoid operating system bugs.

Apache HTTP Server versions later than 2.2 will not run on any operating system earlier than Windows 2000.
top

Downloading Apache for Windows

The Apache HTTP Server Project itself does not provide binary releases of software, only source code. Individual committers may provide binary packages as a convenience, but it is not a release deliverable.

If you cannot compile the Apache HTTP Server yourself, you can obtain a binary package from numerous binary distributions available on the Internet.

Popular options for deploying Apache httpd, and, optionally, PHP and MySQL, on Microsoft Windows, include:

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 default configuration of the source distribution expects the server to be installed into \Apache24. This can be customized at compilation time, but it's important that ultimately the ServerRoot in httpd.conf match the actual installation root. Binary distributions may customize either the default installation root or the overall layout of the initial configuration.

The main differences in Apache for Windows are:

top

Running Apache as a Service

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:

httpd.exe -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. If you specify a name during the install, you have to also specify it during any other -k operation.

httpd.exe -k install -n "MyServiceName"

If you need to have specifically named configuration files for different services, you must use this:

httpd.exe -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.4 and the configuration will be assumed to be conf\httpd.conf.

Removing an Apache service is easy. Just use:

httpd.exe -k uninstall

The specific Apache service to be uninstalled can be specified by using:

httpd.exe -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.4 and NET STOP Apache2.4 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:

httpd.exe -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:

httpd.exe -k start -n "MyServiceName"

To stop an Apache service via the command line switches, use this:

httpd.exe -k stop -n "MyServiceName"

or

httpd.exe -k shutdown -n "MyServiceName"

You can also restart a running service and force it to reread its configuration file by using:

httpd.exe -k restart -n "MyServiceName"

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.

It is recommended that users create a separate account for running Apache service(s). If you have to access network resources via Apache, this is required.

  1. Create a normal domain user account, and be sure to memorize its password.
  2. 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.
  3. Confirm that the created account is a member of the Users group.
  4. Grant the account read and execute (RX) rights to all document and script folders (htdocs and cgi-bin for example).
  5. Grant the account change (RWXD) rights to the Apache logs directory.
  6. Grant the account read and execute (RX) rights to the httpd.exe binary executable.
It is usually a good practice to grant the user the Apache service runs as read and execute (RX) access to the whole Apache2.4 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.4 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.

If you are having problems with the service, it is suggested you follow the instructions below to try starting httpd.exe from a console window, and work out the errors before struggling to start it as a service again.

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, especially during initial configuration and testing.

To run Apache from the command line as a console application, use the following command:

httpd.exe

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

If Apache is running as a service, you can tell it to stop by opening another console window and entering:

httpd.exe -k shutdown

Running as a service should be preferred over running in a console window because this lets Apache end any current operations and clean up gracefully.

But if the server is running in a console window, you can only stop it by pressing Control-C in the same window.

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, either press Control-Break in the console window you used for starting Apache, or enter

httpd.exe -k restart

if the server is running as a service.

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 httpd.exe, and read the error message. Then change to the logs folder, and review the error.log file for configuration mistakes. Assuming httpd was installed into C:\Program Files\Apache Software Foundation\Apache2.4\, you can do the following:

c:
cd "\Program Files\Apache Software Foundation\Apache2.4\bin"
httpd.exe

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:

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:

httpd.exe -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. The -d switch on the command line.
  3. Current working directory.
  4. A registry entry which was created if you did a binary installation.
  5. The server root compiled into the server. This is /apache by default, you can verify it by using httpd.exe -V and looking for a value labelled as HTTPD_ROOT.

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 you should see "It Works!". 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, some firewall implementations, and even some client applications (such as Skype) which will use port 80 to attempt to bypass firewall issues.

top

Configuring Access to Network Resources

Access to files over the network can be specified using two mechanisms provided by Windows:

Mapped drive letters
e.g., Alias "/images/" "Z:/"
UNC paths
e.g., Alias "/images/" "//imagehost/www/images/"

Mapped drive letters allow the administrator to maintain the mapping to a specific machine and path outside of the Apache httpd configuration. However, these mappings are associated only with interactive sessions and are not directly available to Apache httpd when it is started as a service. Use only UNC paths for network resources in httpd.conf so that the resources can be accessed consistently regardless of how Apache httpd is started. (Arcane and error prone procedures may work around the restriction on mapped drive letters, but this is not recommended.)

Example DocumentRoot with UNC path

  UNCList dochost
  DocumentRoot "//dochost/www/html/"

Example DocumentRoot with IP address in UNC path

  UNCList 192.168.1.50
  DocumentRoot "//192.168.1.50/docs/"

Example Alias and corresponding Directory with UNC path

UNCList imagehost1 imagehost2
Alias "/images/" "//imagehost/www/images/"
Alias "/images2/" "//imagehost2/www/images/"

<Directory "//imagehost/www/images/">
#...
</Directory>
<Directory "//imagehost2/www/images/">
#...
</Directory>

When running Apache httpd as a service, you must create a separate account in order to access network resources, as described above.

top

Windows Tuning

Available Languages:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/netware.html0000664000175100017510000000044713710016232021206 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: netware.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: netware.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: netware.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/platform/windows.html0000664000175100017510000000044713710016232021233 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: windows.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: windows.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: windows.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/platform/windows.html.fr.utf80000664000175100017510000011231314740503670022535 0ustar covenercovener Utilisation du serveur HTTP Apache sous Microsoft Windows - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Notes spécifiques à un système

Utilisation du serveur HTTP Apache sous Microsoft Windows

Langues Disponibles:  en  |  fr  |  ko 

Ce document décrit l'installation, la configuration et l'exécution d'Apache 2.4 sous Microsoft Windows. Si vous avez des questions après avoir lu la documentation, ou si vous avez rencontré des évènements particuliers ou des rapports d'erreur, vous pouvez consultez la liste de diffusion de la communauté des utilisateurs.

Dans ce document, nous supposons que vous installez une distribution binaire d'Apache. Si vous voulez compiler Apache vous-même (par exemple pour aider au développement ou pour rechercher des bogues), référez-vous au document Compilation d'Apache pour Microsoft Windows.

Support Apache!

Voir aussi

top

Prérequis du système d'exploitation

La plate-forme Windows de base pour l'exécution d'Apache 2.4 est Windows 2000 ou supérieur. Veillez à toujours vous procurer et installer le dernier service pack afin d'éviter les bogues du système d'exploitation.

Les versions du serveur HTTP Apache supérieures à 2.2 ne fonctionneront sous aucun système d'exploitation d'une version antérieure à Windows 2000.
top

Téléchargement d'Apache pour Windows

Le projet du serveur HTTP Apache proprement dit ne fournit pas de distribution binaire mais seulement le code source. Certains membres du projet peuvent mettre à disposition des paquets binaires à titre individuel, mais ceux-ci n'ont pas vocation à être distribués publiquement.

Si vous n'êtes pas en mesure de compiler le serveur HTTP Apache vous-même, vous pouvez vous procurer un paquet binaire auprès des nombreuses distributions disponibles sur Internet.

Quelques solutions populaires pour déployer Apache httpd, et éventuellement PHP et MySQL sous Microsoft Windows :

top

Personnaliser Apache pour Windows

La configuration d'Apache est enregistrée dans les fichiers du sous-répertoire conf. Ce sont les même fichiers que ceux utilisés pour configurer la version Unix, mais il y a quelques directives spécifiques à Apache pour Windows. Voir l'index des directives pour la liste des directives disponibles.

La configuration par défaut de la distribution source installe le serveur dans \Apache2x. Cet emplacement peut être modifié à la compilation, mais il est important qu'en fin de compte, la directive ServerRoot dans httpd.conf corresponde effectivement à la racine de l'installation. Les distributions binaires peuvent parfois modifier la racine de l'installation par défaut, ou même la structure complète de la configuration initiale.

Les principales spécificités d'Apache pour Windows sont :

top

Exécuter Apache en tant que service

Apache fournit un utilitaire nommé Apache Service Monitor (Moniteur du service Apache). Grâce à lui, vous pouvez voir et gérer l'état de tous les services Apache installés sur toutes les machines du réseau. Pour pouvoir gérer un service Apache avec le moniteur, vous devez d'abord installer le service (soit automatiquement au cours de l'installation, soit manuellement).

Vous pouvez installer Apache en tant que service Windows NT à partir de la ligne de commandes et depuis le sous-répertoire Apache bin comme suit :

httpd.exe -k install

Si vous avez installé plusieurs services Apache sur votre ordinateur, vous devrez spécifier le nom du service que vous voulez installer en utilisant la commande suivante (notez que si vous spécifiez un nom durant l'installation, vous devrez aussi le spécifier pour toute opération comportant l'option -k) :

httpd.exe -k install -n "Nom-service"

Si un service doit utiliser un fichier de configuration spécifique, utilisez ceci :

httpd.exe -k install -n "Nom-service" -f "c:\fichiers\Nom-service.conf"

Si vous utilisez la première commande sans paramètre particulier, excepté -k install, le service aura pour nom Apache2.4 et le fichier de configuration sera censé être conf\httpd.conf.

Supprimer un service Apache est très simple. Utilisez simplement :

httpd.exe -k uninstall

On peut spécifier un service Apache particulier en utilisant :

httpd.exe -k uninstall -n "Nom service"

Normalement, le démarrage, le redémarrage et l'arrêt d'un service Apache s'effectuent via le Moniteur de Service Apache, ou en utilisant des commandes telles que NET START Apache2.4 et NET STOP Apache2.4, ou encore via le gestionnaire de services standard de Windows. Avant de démarrer Apache en tant que service dans quelque but que ce soit, vous devez tester le fichier de configuration du service en utilisant :

httpd.exe -n "Nom-service" -t

Vous pouvez aussi contrôler un service Apache à l'aide de ses options de ligne de commande. Avec cette méthode, pour démarrer un service Apache installé, vous utiliserez :

httpd.exe -k start -n "Nom-Service"

Pour arrêter un service Apache via les options de lignes de commande, utilisez ceci :

httpd.exe -k stop -n "Nom-Service"

ou

httpd.exe -k shutdown -n "Nom-Service"

Vous pouvez aussi redémarrer un service en exécution et le forcer à relire son fichier de configuration en utilisant :

httpd.exe -k restart -n "Nom-Service"

Par défaut, tous les services Apache sont configurés pour s'exécuter sous l'utilisateur system (le compte LocalSystem). Le compte LocalSystem n'a pas de privilèges sur votre réseau, que ce soit via un mécanisme sécurisé de Windows, y compris le système de fichiers, des tubes nommés, DCOM ou des RPC sécurisés. Il a cependant des privilèges élevés en local.

N'accordez jamais de privilèges réseau au compte LocalSystem ! Si Apache doit pouvoir accéder à des ressources réseau, créez un compte séparé pour Apache comme indiqué ci-dessous.

Il est fortement fortement conseillé aux utilisateurs de créer un compte séparé pour exécuter le(s) service(s) Apache, et même obligatoire si vous devez accéder à des ressources réseau via Apache.

  1. Créez un compte d'utilisateur du domaine normal, et assurez-vous de retenir son mot de passe.
  2. Accordez à l'utilisateur nouvellement créé les privilèges Log on as a service et Act as part of the operating system. Sous Windows NT 4.0, ces privilèges sont accordés via le Gestionnaire des utilisateurs du Domaine, mais sous Windows 2000 et XP, vous aurez plutôt intérêt à utiliser une GPO pour propager ces configurations. Vous pouvez aussi effectuer ces réglages via la Politique de Sécurité Locale intégrée à la MMC.
  3. Vérifiez que le compte nouvellement créé est membre du groupe Utilisateurs
  4. Accordez à ce compte les droits Lecture et Exécution (RX) sur tous les documents et répertoires de scripts (htdocs et cgi-bin par exemple), et aussi sur l'exécutable binaire httpd.exe.
  5. Accordez aussi à ce compte les droits de modification sur le répertoire logs.
Il est en général de bonne pratique d'accorder à l'utilisateur sous lequel le service Apache s'exécute les droits en lecture et exécution (RX) sur l'ensemble du répertoire Apache2.4, sauf pour le sous-répertoire logs, sur lequel l'utilisateur doit avoir au moins les droits de modification (RWXD).

Si vous permettez à ce compte de se connecter en tant qu'utilisateur et service, vous pouvez ouvrir une session sous ce compte et vérifier s'il a bien le droit d'exécuter les scripts, de lire les pages web, et si vous pouvez démarrer Apache à partir d'une console Windows. Si tout fonctionne, et si vous avez suivi les étapes ci-dessus, Apache devrait s'exécuter en tant que service sans problème.

Le code d'erreur 2186 indique probablement qu'Apache ne peut pas accéder à une ressource réseau nécessaire, et que vous devez revoir la configuration "Log On As" (Se connecter en tant que ...) du service.

Lorsqu'Apache démarre en tant que service, il se peut que vous obteniez un message d'erreur du Gestionnaire de Services Windows. Par exemple, si vous essayez de démarrer Apache en utilisant l'applet Services du Panneau de configuration de Windows, vous pouvez obtenir le message suivant :

Could not start the Apache2.4 service on \\COMPUTER
Error 1067; The process terminated unexpectedly.

Vous obtiendrez cette erreur à caractère général pour tout problème survenant au cours du démarrage du service Apache. Afin de déterminer exactement la cause du problème, vous devez suivre les instructions permettant d'exécuter Apache pour Windows depuis la ligne de commande.

Si vous rencontrez des problèmes avec le service, il est conseillé de suivre les instructions ci-dessous afin d'essayer de démarrer httpd.exe depuis une console, et d'analyser les erreurs plutôt que vous démener à essayer de démarrer le service.

top

Exécuter Apache depuis la console

Il est en général recommandé d'exécuter Apache en tant que service, mais il est parfois plus simple d'utiliser la ligne de commande, en particulier au cours de la configuration initiale et les tests.

Pour exécuter Apache depuis la ligne de commande et en tant qu'application de console, utilisez la commande suivante :

httpd.exe

Apache va démarrer, et continuera son exécution jusqu'à ce qu'on l'arrête en tapant Ctrl-C.

Vous pouvez également démarrer Apache via le raccourci "Démarrer Apache dans une console" placé dans Démarrer --> Programmes --> Apache HTTP Server 2.4.xx --> Control Apache Server au cours de l'installation. Ceci va ouvrir une console Windows, et y démarrer Apache. Si vous n'avez pas installé Apache en tant que service, la fenêtre Windows restera ouverte jusqu'à ce que vous arrêtiez Apache en tapant Ctrl-C dans cette fenêtre. Le serveur va alors s'arrêter au bout de quelques secondes. Cependant, si vous avez installé Apache en tant que service, c'est ce dernier que le raccourci ci-dessus va lancer. Si le service Apache est déjà en cours d'exécution, le raccourci va rester sans effet.

Si Apache s'exécute en tant que service, vous pouvez l'arrêter en ouvrant une autre console et en entrant :

httpd.exe -k shutdown

Plutôt que de lancer Apache à partir d'une console, il est préférable de l'exécuter en tant que service car dans ce cas, il termine proprement les opérations en cours avant de s'éteindre.

Si le serveur a été lancé depuis une console, vous ne pouvez l'arrêter qu'en pressant la combinaison de touches Ctrl-C dans la même fenêtre.

Vous pouvez aussi redémarrer Apache. Ceci le force à recharger son fichier de configuration. Toute opération en cours peut être achevée sans interruption. Pour redémarrer Apache, vous pouvez soit taper Control-Break dans la fenêtre de console que vous avez utilisée pour le démarrer, soit entrer :

httpd.exe -k restart

si le serveur s'exécute en tant que service.

Note pour les utilisateurs familiers de la version Unix d'Apache : les commandes ci-dessus représentent pour Windows l'équivalent des commandes kill -TERM pid et kill -USR1 pid. L'option de ligne de commande -k a été choisie à titre de rapprochement avec la commande kill utilisée sous Unix.

Si la fenêtre de la console Apache se ferme immédiatement ou inopinément après le démarrage d'Apache, ouvrez une console Windows depuis le menu Démarrer --> Programmes. Placez-vous dans le répertoire d'installation d'Apache, tapez la commande httpd.exe, et observez le message d'erreur. Allez ensuite dans le répertoire des journaux, et visualisez le fichier error.log pour détecter d'éventuelles erreurs de configuration. Si Apache a été installé dans C:\Program Files\Apache Software Foundation\Apache2.4\, vous pouvez entrer ce qui suit :

c:
cd "\Program Files\Apache Software Foundation\Apache2.4\bin"
httpd.exe

Attendez ensuite qu'Apache s'arrête ou tapez Ctrl-C. Entrez alors la commande suivante :

cd ..\logs
more < error.log

Lorsqu'on travaille avec Apache, il est important de comprendre comment ce dernier trouve son fichier de configuration. Vous pouvez spécifier un fichier de configuration à partir de la ligne de commande de deux façons :

Dans les deux cas, la directive ServerRoot doit être correctement définie dans le fichier de configuration.

Si vous ne spécifiez aucun fichier de configuration à l'aide des options -f ou -n, Apache utilisera le nom du fichier de configuration compilé dans le serveur, en général conf\httpd.conf. Ce chemin codé en dur est relatif au répertoire d'installation. Vous pouvez vérifier ce chemin à partir de la valeur de l'étiquette SERVER_CONFIG_FILE en invoquant Apache avec l'option -V, comme ceci :

httpd.exe -V

Apache va ensuite essayer de déterminer la valeur de son ServerRoot en effectuant les recherches suivantes, dans cet ordre :

  1. Une directive ServerRoot via l'option de ligne de commande -C.
  2. L'option de ligne de commande -d.
  3. Le répertoire de travail courant.
  4. Une entrée de la base de registre créée dans le cas d'une installation binaire.
  5. La racine des documents (DocumentRoot) codée en dur dans le serveur. Elle correspond par défaut à /apache, et vous pouvez le vérifier en tapant httpd.exe -V et en recherchant l'étiquette HTTPD_ROOT.

Si vous n'avez pas effectué d'installation binaire, dans certains scénarios, Apache va signaler l'absence de cette clé de registre. On peut passer outre cet avertissement si le serveur a été en mesure de trouver son fichier de configuration d'une autre manière.

La valeur de cette clé correspond au répertoire ServerRoot qui contient lui-même le sous-répertoire conf. Lors de son démarrage, Apache lit le fichier httpd.conf à partir de ce répertoire. Si ce fichier contient une directive ServerRoot qui spécifie un répertoire différent de celui que contient la clé de registre ci-dessus, Apache oubliera la clé de registre, et utilisera le répertoire spécifié par le fichier de configuration. Si vous déplacez le répertoire Apache ou ses fichiers de configuration, il est vital de mettre à jour la directive ServerRoot dans httpd.conf afin de refléter la nouvelle localisation.

top

Vérification de l'installation

Une fois Apache démarré (soit à partir d'une console Windows, soit en tant que service), ce dernier va se mettre à l'écoute sur le port 80 (à moins que vous ayiez modifié la directive Listen dans les fichiers de configuration ou que vous ayiez installé Apache pour l'utilisateur courant seulement). Pour vous connecter au serveur et accéder à la page par défaut, lancez un navigateur et entrez cette URL :

http://localhost/

Apache devrait renvoyer une page de bienvenue et vous devriez voir s'afficher "It Works!". Si rien ne se passe ou si vous obtenez une erreur, consultez le fichier error.log dans le sous-répertoire logs. Si votre serveur n'est pas connecté au réseau, ou si vous avez de sérieux problèmes avec la configuration de votre DNS (Domain Name Service), vous devez utiliser cette URL :

http://127.0.0.1/

Si Apache écoute un port non standard, vous devez le préciser explicitement dans l'URL :

http://127.0.0.1:8080/

Après que votre installation de base fonctionne, vous devez la configurer correctement en éditant les fichiers du sous-répertoire conf. Encore une fois, si vous modifiez la configuration du service Apache sous Windows NT, essayez d'abord de redémarrer le service depuis la ligne de commande afin de vous assurer de l'absence d'erreur.

Comme Apache ne peut pas partager le même port avec d'autres applications TCP/IP, il se peut que vous soyez amené à arrêter, désinstaller ou reconfigurer certains services avant de démarrer Apache. Ces services entrant en conflit avec Apache comprennent les autres serveurs WWW, certaines implémentations de pare-feu, et même certaines applications client (comme Skype) qui utilisent le port 80 afin de contourner les pare-feu.

top

Configuration de l'accès aux ressources réseau

L'accès à des fichiers par le réseau peut être spécifié via deux mécanismes fournis par Windows :

Association de lettres de lecteur
Par exemple, Alias "/images/" "Z:/"
chemins UNC
Par exemple, Alias "/images/" "//imagehost/www/images/"

L'association de lettres de lecteur permet à l'administrateur de maintenir une correspondance avec une certaine machine et un certain chemin en dehors de la configuration d'Apache httpd. Cependant, ces associations ne sont possibles que dans le cadre des sessions interactives, et ne sont pas directement disponibles pour Apache httpd lorsqu'il est démarré en tant que service. N'utilisez par conséquent que des chemins UNC pour les ressources réseau dans httpd.conf, de façon à ce que les ressources soient accessibles quelle que soit la manière dont Apache httpd a été démarré (des procédures exotiques et probablement sujettes aux erreurs peuvent permettre de contourner la restriction due aux associations de lettres de lecteur, mais leur utilisation est déconseillée).

Exemple de DocumentRoot avec chemin UNC

  UNCList dochost
  DocumentRoot "//dochost/www/html/"

Exemple de DocumentRoot avec adresse IP dans le chemin UNC

  UNCList 192.168.1.50
  DocumentRoot "//192.168.1.50/docs/"

Exemple d'Alias et répertoire correspondant avec chemin UNC

UNCList imagehost1 imagehost2  
Alias "/images/" "//imagehost/www/images/"
Alias "/images2/" "//imagehost2/www/images/"

<Directory "//imagehost/www/images/">
#...
</Directory>
<Directory "//imagehost2/www/images/">
#...
</Directory>

Lorsqu'Apache s'exécute en tant que service, vous devez créer un compte spécifique afin de pouvoir accéder aux ressources réseau, comme décrit ci-dessus.

top

Personnalisation sous Windows

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/perf-hp.html.en0000664000175100017510000002043114737241666021523 0ustar covenercovener Running a High-Performance Web Server on HPUX - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Platform Specific Notes

Running a High-Performance Web Server on HPUX

Available Languages:  en  |  fr  |  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.netperf.org/netperf/

Available Languages:  en  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/platform/ebcdic.html0000664000175100017510000000031613710016232020745 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: ebcdic.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: ebcdic.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/platform/rpm.html0000664000175100017510000000030513710016232020330 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: rpm.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: rpm.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/misc/0000775000175100017510000000000015032766627016000 5ustar covenercovenerhttpd-2.4.64/docs/manual/misc/index.html.ko.euc-kr0000664000175100017510000001221714743132254021564 0ustar covenercovener Ÿ ġ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Ÿ ġ

ֽ ƴմϴ. ֱٿ ϼ.

Ʒ ġ Ʈ ߰ ̴.

Ʒ ġ 2.1 ʴ. ȿ , ؼ ϱ ٶ.

ġ

ְ ġ (, Ͻ) ϴ ٷ. ġ  ۾ ϰ (ġ ų )  ۾ ʴ Ѵ.

ġ ϰ ϱ " " " ƾ ".

URL ۼ ħ

mod_rewrite Ѵ. ڰ ۾ εġԵǴ URL ذϱؼ  ġ mod_rewrite ϴ Ѵ.

ǥ

ġ ǥص Ѵ.

:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/misc/index.html.es0000664000175100017510000001333114743132254020373 0ustar covenercovener Documentación Variada de Apache - Servidor HTTP Apache Versión 2.4
<-
Apache > Servidor HTTP > Documentación > Versión 2.4

Documentación Variada de Apache

Idiomas disponibles:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

A continuación verá una lista de páginas adicionales de documentación que aplican al proyecto de desarrollo del servidor web Apache.

Atención

Los documentos no han sido completamente actualizados para tener en cuenta los cambios realizados en la versión 2.1 del Servidor Apache HTTP. Alguna información todavía puede ser relevante, por favor revísela con cuidado.

Notas de Rendimiento - Mejorando Apache

Notas sobre como configurar (en tiempo real y tiempo de compilación) Apache para el mejor rendimiento. Notas explicando por qué Apache hace ciertas cosas y por qué no hace otras (que le hacen ser más lento/rápido).

Escalado de Rendimiento

Alguna configuración de fácil acceso y opciones de mejora para Apache httpd 2.2 y 2.4 así como herramientas de motorización.

Consejos de Seguridad

Algunas de las cosas que se deben y no deben hacer para mantener seguro su sitio web Apache.

Estándares Relevantes

Este documento actúa como una página de referencia para la mayor parte de estándares relevantes que Apache sigue.

Formatos de Cifrado de Contraseñas

Discusión de los distintos cifrados soportados por Apache para el proceso de autenticación.

Idiomas disponibles:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/misc/perf-tuning.html.ko.euc-kr0000664000175100017510000013540414743132254022717 0ustar covenercovener ġ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Miscellaneous Documentation

ġ

ֽ ƴմϴ. ֱٿ ϼ.

ġ 2.0 ɰ ðɼ µ ̴. ġũ ʾ ġ 2.0 .

ġ 1.3 ؼ 2.0 ó Ȯ强(scalability) ̱ ȭ ߴ. ⺻ κ ȭ Ѵ. ׷ Ͻ Ȥ ɿ ū ִ. ġ 2.0 ϱ ڰ ִ ɼ Ѵ.  ɼ ϵ ü Ȱϵ ϴ ݸ,  ɼ ӵ Ѵ.

Support Apache!

top

ϵ ü ؼ

ɿ ū ִ ޸𸮴. û ð ڰ " ٰ" ϰ ø⶧ ϸ ȵȴ. ڴ ϰ ٽ Ͽ ϰ Ѵ. MaxClients þ Ͽ ڽ ʵ ؾ Ѵ. ϴ: top μ ġ μ ޸ 뷮 ˾Ƴ, ü 밡 ޸𸮿 ٸ μ .

ϴ: CPU, Ʈī, ũ, ⼭ " " ؼ ؾ Ѵ.

ü ˾Ƽ ̴. ׷ Ϲ ϴٰ Ǹ  ħ ִ:

top

ؼ

HostnameLookups DNS

ġ 1.3 HostnameLookupsOn̿. û ġ 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) Ѵٸ ޸𸮴Ѵ.

÷ ޸𸮴 Ѵ. ׷ ޸𸮴 Ʈ ġ 찡 ִ:

ǿ شϸ ϴ ޸𸮴 ʵ EnableMMAP off ؾ Ѵ. (: þ 丮 ִ.)

Sendfile

ġ ü sendfile(2) ϸ Ŀ sendfile Ͽ -- , Ҷ -- ִ.

÷ sendfile ϸ read send ʿ䰡  . ׷ sendfile ϸ ġԵǴ 찡 ִ:

ǿ شϸ sendfile ʵ EnableSendfile off ؾ Ѵ. (: þ 丮 ִ.)

μ

ġ 1.3 MinSpareServers, MaxSpareServers, StartServers ġũ ū ƴ. Ư ġ ۾ ϱ ڽļ ٴٸ "" Ⱓ ʿߴ. ó StartServers ڽ , MinSpareServers ʴ ڽ ϳ . ׷ StartServers5 Ŭ̾Ʈ 100 ÿ ϸ ϸ óϱ⿡ ڽ 95ʰ ɷȴ. ʴ , 10а ϴ ġũ ſ ڰ ´.

ʴ Ѱ Ģ ڽ ϸ鼭 ߴ. ǻͰ ڽ ϴ ٻڸ û . ׷ Ģ ġ ü ɿ ǿ ־ Ͽ. ġ 1.3 ʴ Ѱ Ģ ȭǾ. ڵ ڽ Ѱ , 1 , ΰ , 1 , װ , ̷ ʴ ڽ 32 鶧 Ѵ. ڽļ MinSpareServers ٴٸ ߴѴ.

ӵ MinSpareServers, MaxSpareServers, StartServers ʿ䰡 . ʿ ڽ 4 ̻ ϸ ErrorLog Ѵ. ̷ ̸ ϱ ٶ. mod_status ̴.

μ Ͽ MaxRequestsPerChild μ Ѵ. ⺻ ڽĴ ó û ٴ 0̴. 30 ſ ִٸ, ʿ䰡 ִ. SunOS Solaris Ѵٸ, ޸⶧ 10000 ϶.

(keep-alive) Ѵٸ ڽĵ ̹ ῡ ߰ û ٸ ƹ͵ ʱ⶧ ٻڴ. KeepAliveTimeout15 ʴ ̷ ּȭѴ. Ʈ 뿪 ڿ ° Ѵ. κ ⶧  쿡 60 ̻ ø .

top

Ͻ ؼ

MPM

ġ 2.x ó (MPMs)̶ ü ִ ȭ Ѵ. ġ Ҷ MPM ؾ Ѵ. beos, mpm_netware, mpmt_os2, mpm_winnt Ư ÷ ִ MPM ִ. Ϲ н ý MPM ߿ ϳ ִ. ӵ Ȯ强(scalability)  MPM ߳Ŀ ޷ȴ:

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 ɼ ÷ ִ:

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  |  fr  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/security_tips.html.tr.utf80000664000175100017510000007245014743132254023104 0ustar covenercovener Güvenlik İpuçları - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Çeşitli Belgeler

Güvenlik İpuçları

Mevcut Diller:  en  |  fr  |  ko  |  tr 

Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.

Bir HTTP Sunucusunu ayarlarken dikkat edilmesi gerekenler ve bazı ipuçları. Öneriler kısmen Apache’ye özel kısmen de genel olacaktır.

Support Apache!

Ayrıca bakınız:

top

Güncel Tutma

Apache HTTP Sunucusu iyi bir güvenlik sicilinin yanında güvenlik konularıyla oldukça ilgili bir geliştirici topluluğuna sahiptir. Fakat, bir yazılımın dağıtılmasının ardından küçük ya da büyük bazı sorunların keşfedilmesi kaçınılmazdır. Bu sebeple, yazılım güncellemelerinden haberdar olmak oldukça önem kazanır. HTTP sunucunuzu doğrudan Apache’den temin ediyorsanız yeni sürümler ve güvenlik güncellemeleri ile ilgili bilgileri tam zamanında alabilmek için Apache HTTP Sunucusu Duyuru Listesine mutlaka üye olmanızı öneririz. Apache yazılımının üçüncü parti dağıtımlarını yapanların da buna benzer hizmetleri vardır.

Şüphesiz, bir HTTP sunucusu, sunucu kodunda bir sorun olmasa da tehlike altındadır. Eklenti kodları, CGI betikleri hatta işletim sisteminden kaynaklanan sorunlar nedeniyle bu ortaya çıkabilir. Bu bakımdan, sisteminizdeki tüm yazılımların sorunları ve güncellemeleri hakkında bilgi sahibi olmalısınız.

top

Hizmet Reddi (DoS) Saldırıları

Tüm ağ sunucuları, istemcilerin sistem kaynaklarından yararlanmalarını engellemeye çalışan hizmet reddi saldırılarına (HRS) maruz kalabilir. Bu tür saldırıları tamamen engellemek mümkün değildir, fakat yarattıkları sorunları azaltmak için bazı şeyler yapabilirsiniz.

Çoğunlukla en etkili anti-HRS aracı bir güvenlik duvarı veya başka bir işletim sistemi yapılandırmasıdır. Örneğin, çoğu güvenlik duvarı herhangi bir IP adresinden aynı anda yapılan bağlantıların sayısına bir sınırlama getirmek üzere yapılandırılabilir. Böylece basit saldırılar engellenebilir. Ancak bunun dağıtık hizmet reddi saldırılarına (DHRS) karşı bir etkisi olmaz.

Bunların yanında Apache HTTP Sunucusunun da sorunları azaltıcı tedbirler alınmasını sağlayacak bazı yapılandırmaları vardır:

top

ServerRoot Dizinlerinin İzinleri

Normalde, Apache root kullanıcı tarafından başlatılır ve hizmetleri sunarken User yönergesi tarafından tanımlanan kullanıcının aidiyetinde çalışır. Root tarafından çalıştırılan komutlarda olduğu gibi, root olmayan kullanıcıların yapacakları değişikliklerden korunmak konusunda da dikkatli olmalısınız. Dosyaların sadece root tarafından yazılabilir olmasını sağlamak yeterli değildir, bu dizinler ve üst dizinler için de yapılmalıdır. Örneğin, sunucu kök dizininin /usr/local/apache olmasına karar verdiyseniz, bu dizini root olarak şöyle oluşturmanız önerilir:

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 dizinlerinde sadece root tarafından değişiklik yapılabileceği kabul edilir. httpd çalıştırılabilirini kurarken de benzer bir önlemin alındığından emin olmalısınız:

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

Diğer kullanıcıların değişiklik yapabileceği bir dizin olarak bir htdocs dizini oluşturabilirsiniz. Bu dizine root tarafından çalıştırılabilecek dosyalar konulmamalı ve burada root tarafından hiçbir dosya oluşturulmamalıdır.

Diğer kullanıcılara root tarafından yazılabilen ve çalıştırılabilen dosyalarda değişiklik yapma hakkını tanırsanız, onlara root kullanıcısını ele geçirilebilme hakkını da tanımış olursunuz. Örneğin, biri httpd çalıştırılabilirini zararlı bir programla değiştirebilir ve o programı tekrar çalıştırdığınız sırada program yapacağını yapmış olur. Günlükleri kaydettiğiniz dizin herkes tarafından yazılabilen bir dizin olduğu takdirde, birileri bir günlük dosyasını bir sistem dosyasına sembolik bağ haline getirerek root kullanıcısının bu dosyaya ilgisiz şeyler yazmasına sebep olabilir. Günlüklerin dosyaları herkes tarafından yazılabilir olduğu takdirde ise birileri dosyaya yanıltıcı veriler girebilir.

top

Sunucu Taraflı İçerik Yerleştirme

SSI sayfaları bir sunucu yöneticisi açısından çeşitli olası risklere kaynaklık edebilir.

İlk risk, sunucu yükündeki artış olasılığıdır. Tüm SSI sayfaları, SSI kodu içersin içermesin Apache tarafından çözümlenir. Bu küçük bir artış gibi görünürse de bir paylaşımlı sunucu ortamında önemli bir yük haline gelebilir.

SSI sayfaları, CGI betikleriyle ilgili riskleri de taşır. exec cmd elemanı kullanılarak bir SSI sayfasından herhangi bir CGI betiğini veya bir sistem programını Apache’nin aidiyetinde olduğu kullanıcının yetkisiyle çalıştırmak mümkündür.

SSI sayfalarının yararlı özelliklerinden yararlanırken güvenliğini de arttırmanın bazı yolları vardır.

Sunucu yöneticisi, bir başıbozuk SSI sayfasının sebep olabileceği zararları bertaraf etmek için CGI Genelinde bölümünde açıklandığı gibi suexec’i etkin kılabilir.

SSI sayfalarını .html veya .htm uzantılarıyla etkinleştirmek tehlikeli olabilir. Bu özellikle paylaşımlı ve yüksek trafikli bir sunucu ortamında önemlidir. SSI sayfalarını normal sayfalardan farklı olarak .shtml gibi bildik bir uzantıyla etkinleştirmek gerekir. Bu, sunucu yükünü asgari düzeyde tutmaya ve risk yönetimini kolaylaştırmaya yarar.

Diğer bir çözüm de SSI sayfalarından betik ve program çalıştırmayı iptal etmektir. Bu, Options yönergesine değer olarak Includes yerine IncludesNOEXEC vererek sağlanır. Ancak, eğer betiklerin bulunduğu dizinde ScriptAlias yönergesiyle CGI betiklerinin çalışması mümkün kılınmışsa, kullanıcıların <--#include virtual="..." --> ile bu betikleri çalıştırabileceklerine dikkat ediniz.

top

CGI Genelinde

Herşeyden önce ya CGI betiğini/programını yazanlara ya da kendinizin CGI'deki güvenlik açıklarını (ister kasıtlı olsun ister tesadüfi) yakalama becerinize güvenmek zorundasınız. CGI betikleri esasen sisteminizdeki komutları site kullanıcılarının izinleriyle çalıştırırlar. Bu bakımdan dikkatle denenmedikleri takdirde oldukça tehlikeli olabilirler.

CGI betiklerinin hepsi aynı kullanıcının aidiyetinde çalışırsa diğer betiklerle aralarında çelişkilerin ortaya çıkması ister istemez kaçınılmazdır. Örneğin A kullanıcısının B kullanıcısına garezi varsa bir betik yazıp B’nin CGI veritabanını silebilir. Bu gibi durumların ortaya çıkmaması için betiklerin farklı kullanıcıların aidiyetlerinde çalışmasını sağlayan ve 1.2 sürümünden beri Apache ile dağıtılan suEXEC diye bir program vardır. Başka bir yol da CGIWrap kullanmaktır.

top

ScriptAlias’sız CGI

Kullanıcıların sitenin her yerinde CGI betiklerini çalıştırmalarına izin vermek ancak şu koşullarda mümkün olabilir:

top

ScriptAlias’lı CGI

CGI’yi belli dizinlerle sınırlamak yöneticiye bu dizinlerde daha iyi denetim imkanı sağlar. Bu kaçınılmaz olarak ScriptAlias’sız CGI’den çok daha güvenlidir, ancak bu dizinlere yazma hakkı olan kullanıcılarınız güvenilir kişiler olması ve site yöneticisinin de olası güvenlik açıklarına karşı CGI betiklerini ve programlarını denemeye istekli olması şartıyla.

Çoğu site yöneticisi ScriptAlias’sız CGI yerine bu yaklaşımı seçer.

top

Devingen içerikli kaynaklar

Sunucunun bir parçası gibi çalışan, mod_php, mod_perl, mod_tcl ve mod_python gibi gömülü betik çalıştırma seçenekleri sunucuyu çalıştıran kullanıcının aidiyetinde çalışırlar (User yönergesine bakınız). Bu bakımdan bu betik yorumlayıcılar tarafından çalıştırılan betikler, sunucu kullanıcısının eriştiği herşeye erişebilirler. Bazı betik yorumlayıcıların getirdiği bazı sınırlamalar varsa da bunlara pek güvenmemek, gerekli sınamaları yine de yapmak gerekir.

top

Devingen içeriğin güvenliği

mod_php, mod_perl veya mod_python gibi devingen içeriği yapılandırırken güvenlikle ilgili değerlendirmelerin çoğu httpd'nin kapsamından çıkar ve bu modüllerin belgelerini incelemek ihtiyacı duyarsınız. Örneğin, PHP çoğu zaman kapalı tutulan Güvenli Kip ayarını etkin kılmanızı önerir. Daha fazla güvenlik için bir diğer örnek bir PHP eklentisi olan Suhosin'dir. Bunlar hakkında daha ayrıntılı bilgi için her projenin kendi belgelerine başvurun.

Apache seviyesinde, mod_security adı verilen modülü bir HTTP güvenlik duvarı gibi ele alabilir, devingen içeriğin güvenliğini arttırmanıza yardımcı olmak üzere inceden inceye yapılandırabilirsiniz.

top

Sistem Ayarlarının Korunması

Güvenliği gerçekten sıkı tutmak istiyorsanız, kullanıcılarınızın yapılandırmanızdaki güvenlik ayarlarını geçersiz kılmak için .htaccess dosyalarını kullanabilmelerinin de önüne geçmelisiniz. Bunu yapmanın tek bir yolu vardır.

Sunucu yapılandırma dosyanıza şunu yerleştirin:

<Directory "/">
    AllowOverride None
</Directory>

Böylece, belli dizinlerde özellikle etkinleştirilmedikçe bütün dizinlerde .htaccess dosyalarının kullanımını engellemiş olursunuz.

Bu ayar Apache 2.3.9 itibariyle öntanımlıdır.

top

Sunucu dosyalarının öntanımlı olarak korunması

Apache’nin ister istemez yanlış anlaşılan yönlerinden biri öntanımlı erişim özelliğidir. Yani siz aksine bir şeyler yapmadıkça, sunucu normal URL eşleme kurallarını kullanarak bir dosyayı bulabildiği sürece onu istemciye sunacaktır.

Örneğin, aşağıdaki durumu ele alalım:

# cd /; ln -s / public_html

Ve, tarayıcınıza http://localhost/~root/ yazın.

Böylece, istemcilerin tüm dosya sisteminizi gezmelerine izin vermiş olursunuz. Bu işlemin sonuçlarının önünü almak için sunucu yapılandırma dosyanıza şunları yazın:

<Directory "/">
    Require all denied
</Directory>

Bu suretle, dosya sisteminize öntanımlı erişimi yasaklamış olursunuz. Erişime izin vermek istediğiniz dizinler için uygun Directory bölümleri eklemeniz yeterli olacaktır. Örnek:

<Directory "/usr/users/*/public_html">
    Require all granted
</Directory>
<Directory "/usr/local/httpd">
    Require all granted
</Directory>

Location ve Directory yönergelerinin etkileşimine de özellikle önem vermelisiniz; örneğin <Directory "/"> erişimi yasaklarken bir <Location "/"> yönergesi bunu ortadan kaldırabilir.

UserDir yönergesi de size buna benzer bir oyun oynayabilir; yönergeye ./ atamasını yaparsanız, root kullanıcısı söz konusu olduğunda yukarıda ilk örnekteki durumla karşılaşırız. Sunucu yapılandırma dosyanızda aşağıdaki satırın mutlaka bulunmasını öneririz:

UserDir disabled root
top

Günlüklerin İzlenmesi

Sunucunuzda olup biteni günü gününe bilmek istiyorsanız günlük dosyalarına bakmalısınız. Günlük dosyaları sadece olup biteni raporlamakla kalmaz, sunucunuza ne tür saldırılar yapıldığını ve güvenlik seviyenizin yeterli olup olmadığını anlamanızı da sağlarlar.

Bazı örnekler:

grep -c "/jsp/source.jsp?/jsp/ /jsp/source.jsp??" access_log
grep "client denied" error_log | tail -n 10

İlk örnek, Apache Tomcat Source.JSP Bozuk İstek Bilgilerini İfşa Açığını istismar etmeyi deneyen saldırıların sayısını verirken ikinci örnek, reddedilen son on istemciyi listeler; örnek:

[Thu Jul 11 17:18:39 2002] [error] [client foo.example.com] client denied by server configuration: /usr/local/apache/htdocs/.htpasswd

Gördüğünüz gibi günlük dosyaları sadece ne olup bittiğini raporlar, bu bakımdan eğer istemci .htpasswd dosyasına erişebiliyorsa erişim günlüğünüzde şuna benzer bir kayıt görürsünüz:

foo.example.com - - [12/Jul/2002:01:59:13 +0200] "GET /.htpasswd HTTP/1.1"

Bu, sunucu yapılandırma dosyanızda aşağıdaki yapılandırmayı iptal ettiğiniz anlamına gelir:

<Files ".ht*">
    Require all denied
</Files>
top

Yapılandırma bölümlerinin birleştirilmesi

Yapılandırma bölümlerinin birleştirilmesi karmaşık bir işlem olup bazı durumlarda yönergelere bağlıdır. Yönergeleri bir araya getirirken aralarındaki bağımlılıkları daima sınayın.

mod_access_compat gibi henüz yönerge katıştırma mantığını gerçeklememiş modüller için sonraki bölümlerdeki davranış, bu modüllerin yönergelerini içerip içermemesine bağlıdır. Yapılandırmada yönergelerin yerleri değiştirildiğinde fakat bir katıştırma yapılmadığında, yapılandırma bir değişiklik yapılana kadar miras alınır.

Mevcut Diller:  en  |  fr  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/index.html.zh-cn.utf80000664000175100017510000001140014743132254021663 0ustar covenercovener Apache 杂项文档 - Apache HTTP 服务器 版本 2.4
<-
Apache > HTTP 服务器 > 文档 > 版本 2.4

Apache 杂项文档

可用语言:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

下面是适用于 Apache 服务器开发项目的附加文档。

警告

下面的文档尚未完全更新,以反映自 Apache HTTP 服务器版本 2.1 之后的修改。某些信息可能仍旧适用,但请小心使用它。

Apache 性能调谐

对如何在编译或运行时,配置 Apache,以便性能更高的说明。 解释了为什么 Apache 这样做,而不那样做 (这会让它更慢或更快)。

安全技巧

做和不做 - 如何让你的 Apache 站点保持安全。

相关标准

这篇文档是 Apache 遵循的相关标准的参考页面。

密码加密格式

对 Apache 身份认证支持的各种密码加密格式的讨论。

可用语言:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/misc/security_tips.html.ko.euc-kr0000664000175100017510000004503214743132254023364 0ustar covenercovener - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Miscellaneous Documentation

ֽ ƴմϴ. ֱٿ ϼ.

Ҷ Ʈ ̴.  Ϲ̰,  ġ شϴ ̴.

Support Apache!

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 ũƮ ڷ DZ⶧ ٸ ũƮ (ǰ Ǽ̰) 浹 ɼ ִ. , 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 þ ) DZ⶧, ũƮ ϴ ũƮ ڰ ִ Ϳ ִ.  ũƮ , ϴٰ ʴ .

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  |  fr  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/perf-tuning.html.fr.utf80000664000175100017510000016231714740503670022421 0ustar covenercovener Optimisation des performances d'Apache - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Documentations diverses

Optimisation des performances d'Apache

Langues Disponibles:  en  |  fr  |  ko  |  tr 

Apache 2.x est un serveur web à usage général, conçu dans un but d'équilibre entre souplesse, portabilité et performances. Bien que non conçu dans le seul but d'établir une référence en la matière, Apache 2.x est capable de hautes performances dans de nombreuses situations du monde réel.

Comparée à Apache 1.3, la version 2.x comporte de nombreuses optimisations supplémentaires permettant d'améliorer le débit du serveur et sa personnalisation. La plupart de ces améliorations sont activées par défaut. Cependant, certains choix de configuration à la compilation et à l'exécution peuvent affecter les performances de manière significative. Ce document décrit les options qu'un administrateur de serveur peut configurer pour améliorer les performances d'une installation d'Apache 2.x. Certaines de ces options de configuration permettent au démon httpd de mieux tirer parti des possibilités du matériel et du système d'exploitation, tandis que d'autres permettent à l'administrateur de privilégier la vitesse par rapport aux fonctionnalités.

Support Apache!

Voir aussi

top

Problèmes matériels et relatifs au système d'exploitation

Le principal problème matériel qui affecte les performances du serveur web est la mémoire vive (RAM). Un serveur web ne devrait jamais avoir à utiliser le swap, car le swapping augmente le temps de réponse de chaque requête au delà du point que les utilisateurs considèrent comme "trop lent". Ceci incite les utilisateurs à cliquer sur "Stop", puis "Charger à nouveau", ce qui a pour effet d'augmenter encore la charge du serveur. Vous pouvez, et même devez définir la valeur de la directive MaxRequestWorkers de façon à ce que votre serveur ne lance pas un nombre de processus enfants tel qu'il commence à faire du swapping. La méthode pour y parvenir est simple : déterminez la taille de votre processus Apache standard en consultant votre liste de processus à l'aide d'un outil tel que top, et divisez votre quantité totale de mémoire disponible par cette taille, tout en gardant un espace suffisant pour les autres processus.

Hormis ce réglage relatif à la mémoire, le reste est trivial : le processeur, la carte réseau et les disques doivent être suffisamment rapides, où "suffisamment rapide" doit être déterminé par l'expérience.

Le choix du système d'exploitation dépend principalement du contexte local. Voici cependant quelques conseils qui se sont généralement avérés utiles :

top

Optimisation de la configuration à l'exécution

HostnameLookups et autres considérations à propos du DNS

Avant Apache 1.3, la directive HostnameLookups était positionnée par défaut à On. Ce réglage augmente le temps de réponse de chaque requête car il entraîne une recherche DNS et le traitement de la requête ne pourra pas être achevé tant que cette recherche ne sera pas terminée. Avec Apache 1.3, ce réglage est défini par défaut à Off. Si vous souhaitez que les adresses dans vos fichiers journaux soient résolues en noms d'hôtes, utilisez le programme logresolve fourni avec Apache, ou un des nombreux paquets générateurs de rapports sur les journaux disponibles.

Il est recommandé d'effectuer ce genre de traitement a posteriori de vos fichiers journaux sur une autre machine que celle qui héberge le serveur web en production, afin que cette activité n'affecte pas les performances du serveur.

Si vous utilisez une directive Allowfrom domain ou Deny from domain (ce qui signifie que vous utilisez un nom d'hôte ou un nom de domaine à la place d'une adresse IP), vous devrez compter avec deux recherches DNS (une recherche inverse suivie d'une recherche directe pour s'assurer que l'adresse IP n'a pas été usurpée). C'est pourquoi il est préférable, pour améliorer les performances, d'utiliser des adresses IP plutôt que des noms lorsqu'on utilise ces directives, du moins chaque fois que c'est possible.

Notez qu'il est possible de modifier la portée des directives, en les plaçant par exemple à l'intérieur d'une section <Location "/server-status">. Les recherches DNS ne seront alors effectuées que pour les requêtes qui satisfont aux critères. Voici un exemple qui désactive les recherches DNS sauf pour les fichiers .html et .cgi :

HostnameLookups off
<Files ~ "\.(html|cgi)$">
  HostnameLookups on
</Files>

Mais même dans ce cas, si vous n'avez besoin de noms DNS que dans certains CGIs, vous pouvez effectuer l'appel à gethostbyname dans les CGIs spécifiques qui en ont besoin.

FollowSymLinks et SymLinksIfOwnerMatch

Chaque fois que la ligne Options FollowSymLinks sera absente, ou que la ligne Options SymLinksIfOwnerMatch sera présente dans votre espace d'adressage, Apache devra effectuer des appels système supplémentaires pour vérifier la présence de liens symboliques. Un appel supplémentaire par élément du chemin du fichier. Par exemple, si vous avez :

DocumentRoot "/www/htdocs"
<Directory "/">
  Options SymLinksIfOwnerMatch
</Directory>

et si une requête demande l'URI /index.html, Apache effectuera un appel à lstat(2) pour /www, /www/htdocs, et /www/htdocs/index.html. Les résultats de ces appels à lstat ne sont jamais mis en cache, ils devront donc être générés à nouveau pour chaque nouvelle requête. Si vous voulez absolument vérifier la sécurité des liens symboliques, vous pouvez utiliser une configuration du style :

DocumentRoot "/www/htdocs"
<Directory "/">
  Options FollowSymLinks
</Directory>

<Directory "/www/htdocs">
  Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>

Ceci évite au moins les vérifications supplémentaires pour le chemin défini par DocumentRoot. Notez que vous devrez ajouter des sections similaires si vous avez des chemins définis par les directives Alias ou RewriteRule en dehors de la racine de vos documents. Pour améliorer les performances, et supprimer toute protection des liens symboliques, ajoutez l'option FollowSymLinks partout, et n'utilisez jamais l'option SymLinksIfOwnerMatch.

AllowOverride

Dans toute partie de votre espace d'adressage où vous autoriserez la surcharge de la configuration (en général à l'aide de fichiers .htaccess), Apache va tenter d'ouvrir .htaccess pour chaque élément du chemin du fichier demandé. Par exemple, si vous avez :

DocumentRoot "/www/htdocs"
<Directory "/">
  AllowOverride all
</Directory>

et qu'une requête demande l'URI /index.html, Apache tentera d'ouvrir /.htaccess, /www/.htaccess, et /www/htdocs/.htaccess. Les solutions sont similaires à celles évoquées précédemment pour Options FollowSymLinks. Pour améliorer les performances, utilisez AllowOverride None pour tous les niveaux de votre espace d'adressage.

Négociation

Dans la mesure du possible, évitez toute négociation de contenu si vous tenez au moindre gain en performances. En pratique toutefois, les bénéfices de la négociation l'emportent souvent sur la diminution des performances. Il y a cependant un cas dans lequel vous pouvez accélérer le serveur. Au lieu d'utiliser une directive générique comme :

DirectoryIndex index

utilisez une liste explicite d'options :

DirectoryIndex index.cgi index.pl index.shtml index.html

où vous placez le choix courant en première position.

Notez aussi que créer explicitement un fichier de correspondances de type fournit de meilleures performances que l'utilisation des MultiViews, car les informations nécessaires peuvent être simplement obtenues en lisant ce fichier, sans avoir à parcourir le répertoire à la recherche de types de fichiers.

Par conséquent, si la négociation de contenu est nécessaire pour votre site, préférez les fichiers de correspondances de type aux directives Options MultiViews pour mener à bien cette négociation. Se référer au document sur la Négociation de contenu pour une description complète des méthodes de négociation, et les instructions permettant de créer des fichiers de correspondances de type.

Transfert en mémoire

Dans les situations où Apache 2.x doit consulter le contenu d'un fichier en train d'être servi - par exemple à l'occasion du traitement d'une inclusion côté serveur - il transfère en général le fichier en mémoire si le système d'exploitation supporte une forme quelconque de mmap(2).

Sur certains systèmes, ce transfert en mémoire améliore les performances. Dans certains cas, ce transfert peut toutefois les dégrader et même diminuer la stabilité du démon httpd :

Pour les installations où une de ces situations peut se produire, vous devez utiliser EnableMMAP off afin de désactiver le transfert en mémoire des fichiers servis. (Note : il est possible de passer outre cette directive au niveau de chaque répertoire.)

Sendfile

Dans les cas où Apache peut se permettre d'ignorer le contenu du fichier à servir - par exemple, lorsqu'il sert un contenu de fichier statique - il utilise en général le support sendfile du noyau si le système d'exploitation supporte l'opération sendfile(2).

Sur la plupart des plateformes, l'utilisation de sendfile améliore les performances en éliminant les mécanismes de lecture et envoi séparés. Dans certains cas cependant, l'utilisation de sendfile peut nuire à la stabilité du démon httpd :

Pour les installations où une de ces situations peut se produire, vous devez utiliser EnableSendfile off afin de désactiver la mise à disposition de contenus de fichiers par sendfile. (Note : il est possible de passer outre cette directive au niveau de chaque répertoire.)

Process Creation

Avant Apache 1.3, les directives MinSpareServers, MaxSpareServers, et StartServers avaient des effets drastiques sur les performances de référence. En particulier, Apache avait besoin d'un délai de "montée en puissance" afin d'atteindre un nombre de processus enfants suffisant pour supporter la charge qui lui était appliquée. Après le lancement initial des processus enfants par StartServers, seulement un processus enfant par seconde était créé afin d'atteindre la valeur de la directive MinSpareServers. Ainsi, un serveur accédé par 100 clients simultanés et utilisant la valeur par défaut de 5 pour la directive StartServers, nécessitait environ 95 secondes pour lancer suffisamment de processus enfants permettant de faire face à la charge. Ceci fonctionne en pratique pour les serveurs en production, car ils sont rarement redémarrés. Ce n'est cependant pas le cas pour les tests de référence (benchmarks) où le serveur ne fonctionne que 10 minutes.

La règle "un processus par seconde" avait été implémentée afin d'éviter l'enlisement de la machine dans le démarrage de nouveaux processus enfants. Pendant que la machine est occupée à lancer des processus enfants, elle ne peut pas traiter les requêtes. Mais cette règle impactait tellement la perception des performances d'Apache qu'elle a dû être remplacée. A partir d'Apache 1.3, le code a assoupli la règle "un processus par seconde". Il va en lancer un, attendre une seconde, puis en lancer deux, attendre une seconde, puis en lancer quatre et ainsi de suite jusqu'à lancer 32 processus. Il s'arrêtera lorsque le nombre de processus aura atteint la valeur définie par la directive MinSpareServers.

Ceci s'avère suffisamment réactif pour pouvoir en général se passer de manipuler les valeurs des directives MinSpareServers, MaxSpareServers et StartServers. Lorsque plus de 4 processus enfants sont lancés par seconde, un message est émis vers le journal des erreurs. Si vous voyez apparaître souvent ce genre de message, vous devez vous pencher sur ces réglages. Pour vous guider, utilisez les informations délivrées par le module mod_status.

À mettre en relation avec la création de processus, leur destruction est définie par la valeur de la directive MaxConnectionsPerChild. Sa valeur par défaut est 0, ce qui signifie qu'il n'y a pas de limite au nombre de connexions qu'un processus enfant peut traiter. Si votre configuration actuelle a cette directive réglée à une valeur très basse, de l'ordre de 30, il est conseillé de l'augmenter de manière significative. Si vous utilisez SunOs ou une ancienne version de Solaris, utilisez une valeur de l'ordre de 10000 à cause des fuites de mémoire.

Lorsqu'ils sont en mode "keep-alive", les processus enfants sont maintenus et ne font rien sinon attendre la prochaine requête sur la connexion déjà ouverte. La valeur par défaut de 5 de la directive KeepAliveTimeout tend à minimiser cet effet. Il faut trouver le bon compromis entre la bande passante réseau et les ressources du serveur. En aucun cas vous ne devez choisir une valeur supérieure à 60 seconds, car la plupart des bénéfices sont alors perdus.

top

Optimisation de la configuration à la compilation

Choisir un Module Multi-Processus (MPM)

Apache 2.x supporte les modèles simultanés enfichables, appelés Modules Multi-Processus (MPMs). Vous devez choisir un MPM au moment de la construction d'Apache. Certaines plateformes ont des modules MPM spécifiques : mpm_netware, mpmt_os2 et mpm_winnt. Sur les systèmes de type Unix, vous avez le choix entre un grand nombre de modules MPM. Le choix du MPM peut affecter la vitesse et l'évolutivité du démon httpd :

Pour plus d'informations sur ces deux MPMs et les autres, veuillez vous référer à la documentation sur les MPM.

Modules

Comme le contrôle de l'utilisation de la mémoire est très important en matière de performance, il est conseillé d'éliminer les modules que vous n'utilisez pas vraiment. Si vous avez construit ces modules en tant que DSOs, leur élimination consiste simplement à commenter la directive LoadModule associée à ce module. Ceci vous permet de vérifier si votre site fonctionne toujours après la suppression de tel ou tel module.

Par contre, si les modules que vous voulez supprimer sont liés statiquement à votre binaire Apache, vous devrez recompiler ce dernier afin de pouvoir les éliminer.

La question qui découle de ce qui précède est évidemment de savoir de quels modules vous avez besoin et desquels vous pouvez vous passer. La réponse sera bien entendu différente d'un site web à l'autre. Cependant, la liste minimale de modules nécessaire à la survie de votre site contiendra certainement mod_mime, mod_dir et mod_log_config. mod_log_config est bien entendu optionnel puisque vous pouvez faire fonctionner un site web en se passant de fichiers journaux ; ceci est cependant déconseillé.

Opérations atomiques

Certains modules, à l'instar de mod_cache et des versions de développement récentes du MPM worker, utilisent l'API atomique d'APR. Cette API propose des opérations atomiques que l'on peut utiliser pour alléger la synchronisation des threads.

Par défaut, APR implémente ces opérations en utilisant les mécanismes les plus efficaces disponibles sur chaque plateforme cible (Système d'exploitation et processeur). De nombreux processeurs modernes, par exemple, possèdent une instruction qui effectue une opération atomique de type comparaison et échange ou compare-and-swap (CAS) au niveau matériel. Sur certaines platesformes cependant, APR utilise par défaut une implémentation de l'API atomique plus lente, basée sur les mutex, afin d'assurer la compatibilité avec les anciens modèles de processeurs qui ne possèdent pas ce genre d'instruction. Si vous construisez Apache pour une de ces platesformes, et ne prévoyez de l'exécuter que sur des processeurs récents, vous pouvez sélectionner une implémentation atomique plus rapide à la compilation en utilisant l'option --enable-nonportable-atomics du script configure :

./buildconf
./configure --with-mpm=worker --enable-nonportable-atomics=yes

L'option --enable-nonportable-atomics concerne les platesformes suivantes :

Module mod_status et ExtendedStatus On

Si vous incluez le module mod_status à la construction d'Apache et ajoutez ExtendedStatus On à sa configuration, Apache va effectuer pour chaque requête deux appels à gettimeofday(2) (ou times(2) selon votre système d'exploitation), et (pour les versions antérieures à 1.3) de nombreux appels supplémentaires à time(2). Tous ces appels sont effectués afin que le rapport de statut puisse contenir des indications temporelles. Pour améliorer les performances, utilisez ExtendedStatus off (qui est le réglage par défaut).

accept Serialization - points de connexion à un programme (sockets) multiples

Mise en garde :

Cette section n'a pas été totalement mise à jour car elle ne tient pas compte des changements intervenus dans la version 2.x du Serveur HTTP Apache. Certaines informations sont encore pertinentes, il vous est cependant conseillé de les utiliser avec prudence.

Ce qui suit est une brève discussion à propos de l'API des sockets Unix. Supposons que votre serveur web utilise plusieurs directives Listen afin d'écouter plusieurs ports ou de multiples adresses. Afin de tester chaque socket pour voir s'il a une connexion en attente, Apache utilise select(2). select(2) indique si un socket a zéro ou au moins une connexion en attente. Le modèle d'Apache comporte plusieurs processus enfants, et tous ceux qui sont inactifs testent la présence de nouvelles connexions au même moment. Une implémentation rudimentaire de ceci pourrait ressembler à l'exemple suivant (ces exemples ne sont pas extraits du code d'Apache, ils ne sont proposés qu'à des fins pédagogiques) :

        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);
        }

Mais cette implémentation rudimentaire présente une sérieuse lacune. Rappelez-vous que les processus enfants exécutent cette boucle au même moment ; ils vont ainsi bloquer sur select s'ils se trouvent entre deux requêtes. Tous ces processus bloqués vont se réactiver et sortir de select quand une requête va apparaître sur un des sockets (le nombre de processus enfants qui se réactivent varie en fonction du système d'exploitation et des réglages de synchronisation). Ils vont alors tous entrer dans la boucle et tenter un "accept" de la connexion. Mais seulement un d'entre eux y parviendra (en supposant qu'il ne reste q'une seule connexion en attente), les autres vont se bloquer au niveau de accept. Ceci verrouille vraiment ces processus de telle sorte qu'ils ne peuvent plus servir de requêtes que par cet unique socket, et il en sera ainsi jusqu'à ce que suffisamment de nouvelles requêtes apparaissent sur ce socket pour les réactiver tous. Cette lacune a été documentée pour la première fois dans PR#467. Il existe au moins deux solutions.

La première consiste à rendre les sockets non blocants. Dans ce cas, accept ne bloquera pas les processus enfants, et ils pourront continuer à s'exécuter immédiatement. Mais ceci consomme des ressources processeur. Supposons que vous ayez dix processus enfants inactifs dans select, et qu'une connexion arrive. Neuf des dix processus vont se réactiver, tenter un accept de la connexion, échouer, et boucler dans select, tout en n'ayant finalement rien accompli. Pendant ce temps, aucun de ces processus ne traite les requêtes qui arrivent sur d'autres sockets jusqu'à ce qu'ils retournent dans select. Finalement, cette solution ne semble pas très efficace, à moins que vous ne disposiez d'autant de processeurs inactifs (dans un serveur multiprocesseur) que de processus enfants inactifs, ce qui n'est pas une situation très courante.

Une autre solution, celle qu'utilise Apache, consiste à sérialiser les entrées dans la boucle interne. La boucle ressemble à ceci (les différences sont mises en surbrillance) :

        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;
        }

Les fonctions accept_mutex_on et accept_mutex_off implémentent un sémaphore permettant une exclusion mutuelle. Un seul processus enfant à la fois peut posséder le mutex. Plusieurs choix se présentent pour implémenter ces mutex. Ce choix est défini dans src/conf.h (versions antérieures à 1.3) ou src/include/ap_config.h (versions 1.3 ou supérieures). Certaines architectures ne font pas ce choix du mode de verrouillage ; l'utilisation de directives Listen multiples sur ces architectures est donc peu sûr.

La directive Mutex permet de modifier l'implémentation du mutex mpm-accept à l'exécution. Des considérations spécifiques aux différentes implémentations de mutex sont documentées avec cette directive.

Une autre solution qui a été imaginée mais jamais implémentée, consiste à sérialiser partiellement la boucle -- c'est à dire y faire entrer un certain nombre de processus. Ceci ne présenterait un intérêt que sur les machines multiprocesseurs où plusieurs processus enfants peuvent s'exécuter simultanément, et encore, la sérialisation ne tire pas vraiment parti de toute la bande passante. C'est une possibilité d'investigation future, mais demeure de priorité basse car les serveurs web à architecture hautement parallèle ne sont pas la norme.

Pour bien faire, vous devriez faire fonctionner votre serveur sans directives Listen multiples si vous visez les performances les plus élevées. Mais lisez ce qui suit.

accept Serialization - point de connexion à un programme (sockets) unique

Ce qui précède convient pour les serveurs à sockets multiples, mais qu'en est-il des serveurs à socket unique ? En théorie, ils ne devraient pas rencontrer les mêmes problèmes car tous les processus enfants peuvent se bloquer dans accept(2) jusqu'à ce qu'une connexion arrive, et ils ne sont pas utilisés à ne rien faire. En pratique, ceci dissimule un même comportement de bouclage discuté plus haut dans la solution non-blocante. De la manière dont sont implémentées les piles TCP, le noyau réactive véritablement tous les processus bloqués dans accept quand une seule connexion arrive. Un de ces processus prend la connexion en compte et retourne dans l'espace utilisateur, les autres bouclant dans l'espace du noyau et se désactivant quand ils s'aperçoivent qu'il n'y a pas de connexion pour eux. Ce bouclage est invisible depuis le code de l'espace utilisateur, mais il est quand-même présent. Ceci peut conduire à la même augmentation de charge à perte que la solution non blocante au cas des sockets multiples peut induire.

Pour cette raison, il apparaît que de nombreuses architectures se comportent plus "proprement" si on sérialise même dans le cas d'une socket unique. Il s'agit en fait du comportement par défaut dans la plupart des cas. Des expériences poussées sous Linux (noyau 2.0.30 sur un biprocesseur Pentium pro 166 avec 128 Mo de RAM) ont montré que la sérialisation d'une socket unique provoque une diminution inférieure à 3% du nombre de requêtes par secondes par rapport au traitement non sérialisé. Mais le traitement non sérialisé des sockets uniques induit un temps de réponse supplémentaire de 100 ms pour chaque requête. Ce temps de réponse est probablement provoqué par une limitation sur les lignes à haute charge, et ne constitue un problème que sur les réseaux locaux. Si vous voulez vous passer de la sérialisation des sockets uniques, vous pouvez définir SINGLE_LISTEN_UNSERIALIZED_ACCEPT et les serveurs à socket unique ne pratiqueront plus du tout la sérialisation.

Fermeture en prenant son temps (Lingering close)

Comme discuté dans draft-ietf-http-connection-00.txt section 8, pour implémenter de manière fiable le protocole, un serveur HTTP doit fermer les deux directions d'une communication indépendamment (rappelez-vous qu'une connexion TCP est bidirectionnelle, chaque direction étant indépendante de l'autre).

Quand cette fonctionnalité fut ajoutée à Apache, elle causa une avalanche de problèmes sur plusieurs versions d'Unix à cause d'une implémentation à courte vue. La spécification TCP ne précise pas que l'état FIN_WAIT_2 possède un temps de réponse mais elle ne l'exclut pas. Sur les systèmes qui n'introduisent pas ce temps de réponse, Apache 1.2 induit de nombreux blocages définitifs de socket dans l'état FIN_WAIT_2. On peut eviter ceci dans de nombreux cas tout simplement en mettant à jour TCP/IP avec le dernier patch mis à disposition par le fournisseur. Dans les cas où le fournisseur n'a jamais fourni de patch (par exemple, SunOS4 -- bien que les utilisateurs possédant une license source puissent le patcher eux-mêmes), nous avons décidé de désactiver cette fonctionnalité.

Il y a deux méthodes pour arriver à ce résultat. La première est l'option de socket SO_LINGER. Mais le sort a voulu que cette solution ne soit jamais implémentée correctement dans la plupart des piles TCP/IP. Et même dans les rares cas où cette solution a été implémentée correctement (par exemple Linux 2.0.31), elle se montre beaucoup plus gourmande (en temps processeur) que la solution suivante.

Pour la plus grande partie, Apache implémente cette solution à l'aide d'une fonction appelée lingering_close (définie dans http_main.c). La fonction ressemble approximativement à ceci :

        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);
        }

Ceci ajoute naturellement un peu de charge à la fin d'une connexion, mais s'avère nécessaire pour une implémentation fiable. Comme HTTP/1.1 est de plus en plus présent et que toutes les connexions sont persistentes, la charge sera amortie par la multiplicité des requêtes. Si vous voulez jouer avec le feu en désactivant cette fonctionnalité, vous pouvez définir NO_LINGCLOSE, mais c'est fortement déconseillé. En particulier, comme les connexions persistantes en pipeline de HTTP/1.1 commencent à être utilisées, lingering_close devient une absolue nécessité (et les connexions en pipeline sont plus rapides ; vous avez donc tout intérêt à les supporter).

Fichier tableau de bord (Scoreboard file)

Les processus parent et enfants d'Apache communiquent entre eux à l'aide d'un objet appelé "Tableau de bord" (Scoreboard). Idéalement, cet échange devrait s'effectuer en mémoire partagée. Pour les systèmes d'exploitation auxquels nous avons eu accès, ou pour lesquels nous avons obtenu des informations suffisamment détaillées pour effectuer un portage, cet échange est en général implémenté en utilisant la mémoire partagée. Pour les autres, on utilise par défaut un fichier d'échange sur disque. Le fichier d'échange sur disque est non seulement lent, mais aussi peu fiable (et propose moins de fonctionnalités). Recherchez dans le fichier src/main/conf.h correspondant à votre architecture soit USE_MMAP_SCOREBOARD, soit USE_SHMGET_SCOREBOARD. La définition de l'un des deux (ainsi que leurs compagnons respectifs HAVE_MMAP et HAVE_SHMGET), active le code fourni pour la mémoire partagée. Si votre système propose une autre solution pour la gestion de la mémoire partagée, éditez le fichier src/main/http_main.c et ajoutez la portion de code nécessaire pour pouvoir l'utiliser dans Apache (Merci de nous envoyer aussi le patch correspondant).

Note à caractère historique : le portage d'Apache sous Linux n'utilisait pas la mémoire partagée avant la version 1.2. Ceci entraînait un comportement très rudimentaire et peu fiable des versions antérieures d'Apache sous Linux.

DYNAMIC_MODULE_LIMIT

Si vous n'avez pas l'intention d'utiliser les modules chargés dynamiquement (ce qui est probablement le cas si vous êtes en train de lire ce document afin de personnaliser votre serveur en recherchant le moindre des gains en performances), vous pouvez ajouter la définition -DDYNAMIC_MODULE_LIMIT=0 à la construction de votre serveur. Ceci aura pour effet de libérer la mémoire RAM allouée pour le chargement dynamique des modules.

top

Appendice : Analyse détaillée d'une trace

Voici la trace d'un appel système d'Apache 2.0.38 avec le MPM worker sous Solaris 8. Cette trace a été collectée à l'aide de la commande :

truss -l -p httpd_child_pid.

L'option -l demande à truss de tracer l'ID du LWP (lightweight process--la version de Solaris des threads niveau noyau) qui invoque chaque appel système.

Les autres systèmes peuvent proposer des utilitaires de traçage des appels système différents comme strace, ktrace, ou par. Ils produisent cependant tous une trace similaire.

Dans cette trace, un client a demandé un fichier statique de 10 ko au démon httpd. Le traçage des requêtes pour des contenus non statiques ou comportant une négociation de contenu a une présentation différente (et même assez laide dans certains cas).

/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9

Dans cette trace, le thread à l'écoute s'exécute à l'intérieur de LWP #67.

Notez l'absence de la sérialisation d'accept(2). Sur cette plateforme spécifique, le MPM worker utilise un accept non sérialisé par défaut sauf s'il est en écoute sur des ports multiples.
/65:    lwp_park(0x00000000, 0)                         = 0
/67:    lwp_unpark(65, 1)                               = 0

Après avoir accepté la connexion, le thread à l'écoute réactive un thread du worker pour effectuer le traitement de la requête. Dans cette trace, le thread du worker qui traite la requête est associé à LWP #65.

/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0

Afin de pouvoir implémenter les hôtes virtuels, Apache doit connaître l'adresse du socket local utilisé pour accepter la connexion. On pourrait supprimer cet appel dans de nombreuses situations (par exemple dans le cas où il n'y a pas d'hôte virtuel ou dans le cas où les directives Listen contiennent des adresses sans caractères de substitution). Mais aucun effort n'a été accompli à ce jour pour effectuer ces optimisations.

/65:    brk(0x002170E8)                                 = 0
/65:    brk(0x002190E8)                                 = 0

L'appel brk(2) alloue de la mémoire dans le tas. Ceci est rarement visible dans une trace d'appel système, car le démon httpd utilise des allocateurs mémoire de son cru (apr_pool et apr_bucket_alloc) pour la plupart des traitements de requêtes. Dans cette trace, le démon httpd vient juste de démarrer, et il doit appeler malloc(3) pour réserver les blocs de mémoire nécessaires à la création de ses propres allocateurs de mémoire.

/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

Ensuite, le thread de worker passe la connexion du client (descripteur de fichier 9) en mode non blocant. Les appels setsockopt(2) et getsockopt(2) constituent un effet de bord de la manière dont la libc de Solaris utilise fcntl(2) pour les sockets.

/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97

Le thread de worker lit la requête du 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

Ce démon httpd a été configuré avec les options Options FollowSymLinks et AllowOverride None. Il n'a donc ni besoin d'appeler lstat(2) pour chaque répertoire du chemin du fichier demandé, ni besoin de vérifier la présence de fichiers .htaccess. Il appelle simplement stat(2) pour vérifier d'une part que le fichier existe, et d'autre part que c'est un fichier régulier, et non un répertoire.

/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269

Dans cet exemple, le démon httpd peut envoyer l'en-tête de la réponse HTTP et le fichier demandé à l'aide d'un seul appel système sendfilev(2). La sémantique de sendfile varie en fonction des systèmes d'exploitation. Sur certains autres systèmes, il faut faire un appel à write(2) ou writev(2) pour envoyer les en-têtes avant d'appeler sendfile(2).

/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78

Cet appel à write(2) enregistre la requête dans le journal des accès. Notez qu'une des choses manquant à cette trace est un appel à time(2). A la différence d'Apache 1.3, Apache 2.x utilise gettimeofday(3) pour consulter l'heure. Sur certains systèmes d'exploitation, comme Linux ou Solaris, gettimeofday est implémenté de manière optimisée de telle sorte qu'il consomme moins de ressources qu'un appel système habituel.

/65:    shutdown(9, 1, 1)                               = 0
/65:    poll(0xFAF7B980, 1, 2000)                       = 1
/65:    read(9, 0xFAF7BC20, 512)                        = 0
/65:    close(9)                                        = 0

Le thread de worker effectue une fermeture "en prenant son temps" (lingering close) de la connexion.

/65:    close(10)                                       = 0
/65:    lwp_park(0x00000000, 0)         (sleeping...)

Enfin, le thread de worker ferme le fichier qu'il vient de délivrer et se bloque jusqu'à ce que le thread en écoute lui assigne une autre connexion.

/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)

Pendant ce temps, le thread à l'écoute peut accepter une autre connexion à partir du moment où il a assigné la connexion présente à un thread de worker (selon une certaine logique de contrôle de flux dans le MPM worker qui impose des limites au thread à l'écoute si tous les threads de worker sont occupés). Bien que cela n'apparaisse pas dans cette trace, l'accept(2) suivant peut (et le fait en général, en situation de charge élevée) s'exécuter en parallèle avec le traitement de la connexion qui vient d'être acceptée par le thread de worker.

Langues Disponibles:  en  |  fr  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/index.html.tr.utf80000664000175100017510000001242414743132254021300 0ustar covenercovener Çeşitli Belgeler - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4

Çeşitli Belgeler

Mevcut Diller:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

Aşağıda listelenen belgeler de Apache HTTP sunucusu geliştirme projesi kapsamındadır.

Uyarı

Aşağıdaki belgeler, Apache HTTP Sunucusunun 2.1 sürümünde yapılmış değişikliklere göre tam olarak güncellenmemiştir. Hala güncel kalmış bazı bilgiler olabilir, fakat siz yine de bu belgeleri kullanırken dikkatli olun.

Başarım Arttırma İpuçları - Apache’ye İnce Ayar Çekilmesi

Yüksek başarım elde etmek için Apache yapılandırmasında (çalışma anında ve derleme sırasında) yapılacaklar ile ilgili bazı bilgiler yanında Apache’de bazı şeylerin (bir şeyleri hızlandıran ve yavaşlatan şeylerin) yapılma ve yapılmama sebepleri açıklanmıştır.

Güvenlik İpuçları

Apache HTTP sitenizi güvenli kılmak için yapılacaklar ve yapılmayacaklar.

İlgili Standartlar

Bu belge Apache’nin uyacağı standartların bir çoğuna atıfta bulunmak amacıyla hazırlanmıştır.

Parola Şifreleme Biçimleri

Belgede, kimlik doğrulama amacıyla Apache tarafından desteklenen çeşitli şifreleme tekniklerinden bahsedilmiştir.

Mevcut Diller:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/misc/relevant_standards.html.ko.euc-kr0000664000175100017510000002614514743132254024345 0ustar covenercovener ǥ - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Miscellaneous Documentation

ǥ

ֽ ƴմϴ. ֱٿ ϼ.

Բ ġ ǥ Ѵ.

Ʒ Ͽ ڷᵵ Ѵ:

ʴ.

Support Apache!

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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/password_encryptions.html.fr.utf80000664000175100017510000003260514740503670024456 0ustar covenercovener Formats de mots de passe - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Documentations diverses

Formats de mots de passe

Langues Disponibles:  en  |  fr 

Notes à propos des formats de chiffrement des mots de passe générés et compris par Apache.

Support Apache!

Voir aussi

top

Authentification de base

Voici les cinq formats de mots de passe qu'Apache reconnaît pour l'authentification de base. Notez que tous les formats ne sont pas supportés par toutes les plates-formes :

bcrypt
"$2y$" + the result of the crypt_blowfish algorithm. Dérivé de l'algorythme de chiffrement crypt_blowfish. Voir le fichier source APR crypt_blowfish.c pour plus de détails à propos de cet algorithme.
MD5
"$apr1$" + le résultat d'un algorithme spécifique à Apache utilisant un condensé MD5 réitéré (1000 fois) de combinaisons variées du mot de passe et d'une source d'entropie sur 32 bits. Voir le fichier source APR apr_md5.c pour les détails de l'algorithme.
SHA1
"{SHA}" + un condensé SHA-1 du mot de passe codé en Base64. Non sûr.
CRYPT
Unix seulement. Utilise la fonction Unix traditionnelle crypt(3) avec une source d'entropie sur 32 bits (seuls 12 bits sont utilisés), et seulement les 8 premiers caractères du mot de passe. Non sûr.
PLAIN TEXT (autrement dit non chiffré)
Windows & Netware seulement. Non sûr.

Générer des mots de passe avec htpasswd

bcrypt

$ htpasswd -nbB monNom monMot-de-passe
monNom:$2y$05$c4WoMPo3SXsafkva.HHa6uXQZWr7oboPiC2bT/r7q1BB8I2s0BRqC

MD5

$ htpasswd -nbm monNom monMot-de-passe
monNom:$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/

SHA1

$ htpasswd -nbs monNom monMot-de-passe
monNom:{SHA}VBPuJHI7uixaa6LQGWx4s+5GKNE=

CRYPT

$ htpasswd -nbd monNom monMot-de-passe
monNom:rqXexS6ZhobKA

Générer des mots de passe CRYPT and MD5 avec le programme OpenSSL en ligne de commande

OpenSSL connaît l'algorithme MD5 spécifique à Apache.

MD5

$ openssl passwd -apr1 monMot-de-passe
$apr1$qHDFfhPC$nITSVHgYbDAK1Y0acGRnY0

CRYPT

openssl passwd -crypt monMot-de-passe
qQ5vTYO3c8dsU

Valider des mots de passe CRYPT and MD5 avec le programme OpenSSL en ligne de commande

La source d'entropie pour un mot de passe CRYPT est constituée des deux premiers caractères (convertis en valeur binaire). Pour valider monMot-de-passe par rapport à rqXexS6ZhobKA

CRYPT

$ openssl passwd -crypt -salt rq monMot-de-passe
Warning: truncating password to 8 characters
rqXexS6ZhobKA

Notez que spécifier monMot-d au lieu de monMot-de-passe produira le même résultat car seuls les 8 premiers caractères des mots de passe CRYPT sont pris en compte.

La source d'entropie pour un mot de passe MD5 se situe entre $apr1$ et le caractère $ suivant (sous la forme d'une valeur binaire codée en Base64 - au maximum 8 caractères). Pour valider monMot-de-passe par rapport à $apr1$r31.....$HqJZimcKQFAMYayBlzkrA/

MD5

$ openssl passwd -apr1 -salt r31..... monMot-de-passe
$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/

Champs mot de passe de base de données pour mod_dbd

La variante SHA1 constitue probablement le format le mieux approprié pour l'authentification DBD. Comme les fonctions SHA1 et Base64 sont en général disponibles, d'autres logiciels peuvent renseigner une base de données avec des mots de passe chiffrés utilisables par l'authentification basique d'Apache.

Pour créer des mots de passe au format SHA1 pour l'authentification de base d'Apache dans divers langages :

PHP

'{SHA}' . base64_encode(sha1($password, TRUE))

Java

"{SHA}" + new sun.misc.BASE64Encoder().encode(java.security.MessageDigest.getInstance("SHA1").digest(password.getBytes()))

ColdFusion

"{SHA}" & ToBase64(BinaryDecode(Hash(password, "SHA1"), "Hex"))

Ruby

require 'digest/sha1'
require 'base64'
'{SHA}' + Base64.encode64(Digest::SHA1.digest(password))

C ou C++

Utilisez la fonction APR : apr_sha1_base64

Python

import base64
import hashlib
"{SHA}" + format(base64.b64encode(hashlib.sha1(password).digest()))

PostgreSQL (avec les fonctions contrib/pgcrypto installées)

'{SHA}'||encode(digest(password,'sha1'),'base64')

top

Authentification à base de condensés

Apache ne reconnaît qu'un format pour les mots de passe d'authentification à base de condensés - le condensé MD5 de la chaîne utilisateur:domaine-de-protection:mot-de-passe sous la forme d'une chaîne de 32 caractères au format hexadécimal. domaine-de-protection est l'identifiant du domaine de protection de l'autorisation passé en argument à la directive AuthName dans httpd.conf.

Champs de mot de passe de base de données pour mod_dbd

Comme la fonction MD5 est en général disponible, d'autres logiciels peuvent renseigner une base de données avec des mots de passe chiffrés utilisables par l'authentification à base de condensés d'Apache.

Pour créer des mots de passe pour l'authentification à base de condensés d'Apache dans divers langages :

PHP

md5($user . ':' . $realm . ':' .$password)

Java

byte b[] = java.security.MessageDigest.getInstance("MD5").digest( (user + ":" + realm + ":" + password ).getBytes());
java.math.BigInteger bi = new java.math.BigInteger(1, b);
String s = bi.toString(16);
while (s.length() < 32)
s = "0" + s; // La chaîne s contient le mot de passe chiffré

ColdFusion

LCase(Hash( (user & ":" & realm & ":" & password) , "MD5"))

Ruby

require 'digest/md5'
Digest::MD5.hexdigest(user + ':' + realm + ':' + password)

PostgreSQL (avec les fonctions contrib/pgcrypto installées)

encode(digest( user || ':' || realm || ':' || password , 'md5'), 'hex')

Langues Disponibles:  en  |  fr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/perf-tuning.html.tr.utf80000664000175100017510000016021414743132254022430 0ustar covenercovener Apache’de Başarımın Arttırılması - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.4 > Çeşitli Belgeler

Apache’de Başarımın Arttırılması

Mevcut Diller:  en  |  fr  |  ko  |  tr 

Apache 2.x, esneklik, taşınabilirlik ve başarım arasında bir denge sağlamak üzere tasarlanmış genel amaçlı bir HTTP sunucusudur. Başka sunucularla kıyaslama denemelerinde öne geçmek üzere tasarlanmamış olsa da Apache 2.x gerçek yaşamda karşılaşılan pek çok durumda oldukça yüksek bir başarıma ulaşacak yetenektedir.

Apache 1.3 ile karşılaştırıldığında 2.x sürümleri toplam veri hızını ve ölçeklenebilirliği arttırmak için pek çok en iyileme seçeneği içerir. Bu iyileştirmelerin pek çoğu zaten öntanımlı olarak etkin olmakla birlikte derleme ve kullanım sırasında başarımı önemli ölçüde etkileyebilen yapılandırma seçenekleri de mevcuttur. Bu belgede, bir Apache 2.x kurulumunda sunucu yöneticisinin sunucunun başarımını arttırmak amacıyla yapılandırma sırasında neler yapabileceğinden bahsedilmiştir. Bu yapılandırma seçeneklerinden bazıları, httpd’nin donanımın ve işletim sisteminin olanaklarından daha iyi yararlanabilmesini sağlarken bir kısmı da daha hızlı bir sunum için yöneticinin işlevsellikten ödün verebilmesini olanaklı kılar.

Support Apache!

Ayrıca bakınız:

top

Donanım ve İşletim Sistemi ile İlgili Konular

HTTP sunucusunun başarımını etkileyen en önemli donanım bellektir (RAM). Bir HTTP sunucusu asla takaslama yapmamalıdır. Çünkü takaslama, kullanıcının "yeterince hız" umduğu noktada sunumun gecikmesine sebep olur. Böyle bir durumda kullanıcılar yüklemeyi durdurup tekrar başlatma eğilimindedirler; sonuçta yük daha da artar. MaxRequestWorkers yönergesinin değerini değiştirerek takaslamaya sebep olabilecek kadar çok çocuk süreç oluşturulmasını engelleyebilirsiniz ve böyle bir durumda bunu mutlaka yapmalısınız. Bunun için yapacağınız işlem basittir: top benzeri bir araç üzerinden çalışan süreçlerinizin bir listesini alıp Apache süreçlerinizin ortalama büyüklüğünü saptayıp, mevcut bellekten bir kısmını diğer süreçler için ayırdıktan sonra kalan miktarı bu değere bölerseniz yönergeye atayacağınız değeri bulmuş olursunuz.

Donanımın diğer unsurları için kararı siz verin: Daha hızlı işlemci, daha hızlı ağ kartı, daha hızlı disk; daha hızlının ne kadar hızlı olacağını deneyimlerinize bağlı olarak tamamen sizin ihtiyaçlarınız belirler.

İşletim sistemi seçimi büyük oranda yerel ilgi konusudur. Fakat yine de, genelde yararlılığı kanıtlanmış bazı kurallar bu seçimde size yardımcı olabilir:

top

Çalışma Anı Yapılandırması ile İlgili Konular

HostnameLookups ve DNS ile ilgili diğer konular

Apache 1.3 öncesinde, HostnameLookups yönergesinin öntanımlı değeri On idi. İstek yerine getirilmeden önce bir DNS sorgusu yapılmasını gerektirmesi sebebiyle bu ayarlama her istekte bir miktar gecikmeye sebep olurdu. Apache 1.3’ten itibaren yönergenin öntanımlı değeri Off yapılmıştır. Eğer günlük dosyalarınızda konak isimlerinin bulunmasını isterseniz, Apache ile birlikte gelen logresolve programını kullanabileceğiniz gibi günlük raporlarını çözümleyen Apache ile gelmeyen programlardan herhangi birini de kullanabilirsiniz.

Günlük dosyaları üzerindeki bu işlemi sunucu makinesi dışında günlük dosyasının bir kopyası üzerinde yapmanızı öneririz. Aksi takdirde sunucunuzun başarımı önemli ölçüde etkilenebilir.

Allow veya Deny yönergelerinde IP adresi yerine bir konak veya alan ismi belirtirseniz, iki DNS sorguluk bir bedel ödersiniz (biri normal, diğeri IP taklidine karşı ters DNS sorgusu). Başarımı en iyilemek için bu yönergelerde mümkün olduğunca isim yerine IP adreslerini kullanınız.

HostnameLookups yönergelerinin <Location "/server-status"> gibi bölüm yönergelerinin içinde de yer alabileceğini unutmayın. Bu gibi durumlarda DNS sorguları sadece istek kuralla eşleştiği takdirde yapılacaktır. Aşağıdaki örnekte .html ve .cgi dosyalarına yapılan istekler hariç DNS sorguları iptal edilmektedir:

HostnameLookups off
<Files ~ "\.(html|cgi)$">
  HostnameLookups on
</Files>

Yine de bazı CGI’lerin DNS isimlerine ihtiyacı olursa bu CGI’lerin bu ihtiyaçlarına yönelik olarak gethostbyname çağrıları yapabileceğini gözardı etmeyiniz.

FollowSymLinks ve SymLinksIfOwnerMatch

URL uzayınızda geçerli olmak üzere bir Options FollowSymLinks yoksa veya Options SymLinksIfOwnerMatch yönergeleri varsa, Apache her sembolik bağın üzerinde bazı sınamalar yapmak için ek bir sistem çağrısından başka istenen her dosya için de ayrı bir çağrı yapacaktır.

DocumentRoot "/siteler/htdocs"
<Directory />
  Options SymLinksIfOwnerMatch
</Directory>

Bu durumda /index.html için bir istek yapıldığında Apache, /siteler, /siteler/htdocs ve
/siteler/htdocs/index.html üzerinde lstat(2) çağrıları yapacaktır. lstat sonuçları önbelleğe kaydedilmediğinden bu işlem her istekte yinelenecektir. Amacınız gerçekten sembolik bağları güvenlik açısından sınamaksa bunu şöyle yapabilirsiniz:

DocumentRoot "/siteler/htdocs"
<Directory "/">
  Options FollowSymLinks
</Directory>

<Directory "/siteler/htdocs">
  Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>

Böylece DocumentRoot altındaki dosyalar için fazladan bir çağrı yapılmasını engellemiş olursunuz. Eğer bazı bölümlerde Alias, RewriteRule gibi yönergeler üzerinden belge kök dizininizin dışında kalan dosya yollarına sahipseniz benzer işlemleri onlar için de yapmalısınız. Sembolik bağ koruması yapmamak suretiyle başarımı arttırmak isterseniz, FollowSymLinks seçeneğini her yerde etkin kılın ve SymLinksIfOwnerMatch seçeneğini asla etkinleştirmeyin.

AllowOverride

Genellikle .htaccess dosyaları üzerinden yapıldığı gibi URL uzayınızda geçersizleştirmelere izin veriyorsanız, Apache her dosya bileşeni için bu .htaccess dosyalarını açmaya çalışacaktır.

DocumentRoot "/siteler/htdocs"
<Directory "/">
  AllowOverride all
</Directory>

Bu durumda /index.html sayfasına yapılan bir istek için Apache, /.htaccess, /siteler/.htaccess ve /siteler/htdocs/.htaccess dosyalarını açmaya çalışacaktır. Çözüm Options FollowSymLinks durumunun benzeridir; başarımı arttırmak için dosya sisteminizin her yerinde AllowOverride None olsun.

Dil Uzlaşımı

Başarımı son kırıntısına kadar arttırmak istiyorsanız, mümkünse içerik dili uzlaşımı da yapmayın. Dil uzlaşımından yararlanmak isterken büyük başarım kayıplarına uğrayabilirsiniz. Böyle bir durumda sunucunun başarımını arttırmanın tek bir yolu vardır.

DirectoryIndex index

Yukarıdaki gibi bir dosya ismi kalıbı kullanmak yerine, aşağıdaki gibi seçenekleri tam bir liste halinde belirtin:

DirectoryIndex index.cgi index.pl index.shtml index.html

Buradaki sıralama öncelik sırasını belirler; yani, öncelikli olmasını istediğiniz seçeneği listenin başına yazmalısınız.

İstenen dosya için MultiViews kullanarak dizini taratmak yerine, gerekli bilgiyi tek bir dosyadan okutmak suretiyle başarımı arttırabilirsiniz. Bu amaçla türeşlem (type-map) dosyaları kullanmanız yeterli olacaktır.

Sitenizde içerik dili uzlaşımına gerek varsa, bunu Options MultiViews yönergesi üzerinden değil, türeşlem dosyaları kullanarak yapmayı deneyin. İçerik dili uzlaşımı ve türeşlem dosyalarının oluşturulması hakkında daha ayrıntılı bilgi edinmek için İçerik Uzlaşımı belgesine bakınız.

Bellek Eşlemleri

Apache’nin SSI sayfalarında olduğu gibi teslim edilecek dosyanın içeriğine bakma gereği duyduğu durumlarda, eğer işletim sistemi mmap(2) ve benzerlerini destekliyorsa çekirdek normal olarak dosyayı belleğe kopyalayacaktır.

Bazı platformlarda bu belleğe eşleme işlemi başarımı arttırsa da başarımın veya httpd kararlılığının zora girdiği durumlar olabilmektedir:

Böyle durumların olasılık dahilinde olduğu kurulumlarda içeriği sunucu tarafından işlenecek dosyaların belleğe kopyalanmaması için yapılandırmanıza EnableMMAP off satırını ekleyiniz. (Dikkat: Bu yönerge dizin seviyesinde geçersizleştirilebilen yönergelerdendir.)

sendfile

Apache’nin duruk dosyalarda olduğu gibi teslim edilecek dosyanın içeriğine bakmadığı durumlarda, eğer işletim sistemi sendfile(2) desteğine sahipse çekirdek normal olarak bu desteği kullanacaktır.

Bazı platformlarda sendfile kullanımı, okuma ve yazma işlemlerinin ayrı ayrı yapılmamasını sağlasa da sendfile kullanımının httpd kararlılığını bozduğu bazı durumlar sözkonusudur:

Böyle durumların olasılık dahilinde olduğu kurulumlarda içeriğin sendfile desteğiyle teslim edilmemesi için yapılandırmanıza EnableSendfile off satırını ekleyiniz. (Dikkat: Bu yönerge dizin seviyesinde geçersizleştirilebilen yönergelerdendir.)

Süreç Oluşturma

Apache 1.3 öncesinde MinSpareServers, MaxSpareServers ve StartServers ayarları, başka sunucularla kıyaslama denemelerinde olağanüstü kötü sonuçlar alınmasına sebep olmaktaydı. Özellikle uygulanan yükü karşılamaya yetecek sayıda çocuk süreç oluşturulması aşamasında Apache’nin elde ettiği ivme bunlardan biriydi. Başlangıçta StartServers yönergesiyle belli sayıda süreç oluşturulduktan sonra her saniyede bir tane olmak üzere MinSpareServers sayıda çocuk süreç oluşturulmaktaydı. Örneğin, aynı anda 100 isteğe yanıt vermek için StartServers yönergesinin öntanımlı değeri olarak başta 5 süreç oluşturulduğundan kalan süreçler için 95 saniye geçmesi gerekirdi. Sık sık yeniden başlatılmadıklarından dolayı gerçek hayatta sunucuların başına gelen de buydu. Başka sunucularla kıyaslama denemelerinde ise işlem sadece on dakika sürmekte ve içler acısı sonuçlar alınmaktaydı.

Saniyede bir kuralı, sunucunun yeni çocukları oluşturması sırasında sistemin aşırı meşgul duruma düşmemesi için alınmış bir önlemdi. Makine çocuk süreç oluşturmakla meşgul edildiği sürece isteklere yanıt veremeyecektir. Böylesi bir durum Apache’nin başarımını kötüleştirmekten başka işe yaramayacaktır. Apache 1.3’te saniyede bir kuralı biraz esnetildi. Yeni gerçeklenimde artık bir süreç oluşturduktan bir saniye sonra iki süreç, bir saniye sonra dört süreç oluşturulmakta ve işlem, saniyede 32 çocuk süreç oluşturulur duruma gelene kadar böyle ivmelenmektedir. Çocuk süreç oluşturma işlemi MinSpareServers değerine ulaşılınca durmaktadır.

Bu, MinSpareServers, MaxSpareServers ve StartServers ayarlarıyla oynamayı neredeyse gereksiz kılacak kadar iyi sonuçlar verecek gibi görünmektedir. Saniyede 4 çocuktan fazlası oluşturulmaya başlandığında hata günlüğüne bazı iletiler düşmeye başlar. Bu iletilerin sayısı çok artarsa bu ayarlarla oynama vakti gelmiş demektir. Bunun için mod_status çıktısını bir kılavuz olarak kullanabilirsiniz.

Süreç oluşturmayla ilgili olarak süreç ölümü MaxConnectionsPerChild değeri ile sağlanır. Bu değer öntanımlı olarak 0 olup, çocuk süreç başına istek sayısının sınırsız olduğu anlamına gelir. Eğer yapılandırmanızda bu değeri 30 gibi çok düşük bir değere ayarlarsanız bunu hemen kaldırmak zorunda kalabilirsiniz. Sunucunuzu SunOS veya Solaris’in eski bir sürümü üzerinde çalıştırıyorsanız bellek kaçaklarına sebep olmamak için bu değeri 10000 ile sınırlayınız.

Kalıcı bağlantı özelliğini kullanıyorsanız, çocuk süreçler zaten açık bağlantılardan istek beklemekte olacaklardır. KeepAliveTimeout yönergesinin öntanımlı değeri 5 saniye olup bu etkiyi en aza indirmeye yönelik süredir. Burada ağ band genişliği ile sunucu kaynaklarının kullanımı arasında bir seçim yapmak söz konusudur. Hiçbir şey umurunuzda değilse çoğu ayrıcalığın yitirilmesi pahasına bu değeri rahatça 60 saniyenin üzerine çıkarabilirsiniz.

top

Derleme Sırasında Yapılandırma ile İlgili Konular

MPM Seçimi

Apache 2.x, Çok Süreçlilik Modülleri (MPM) adı verilen eklemlenebilir çok görevlilik modellerini destekler. Apache’yi derlerken bu MPM’lerden birini seçmeniz gerekir. MPM’lerden bazıları platformlara özeldir: mpm_netware, mpmt_os2 ve mpm_winnt. Unix benzeri sistemler için ise seçebileceğiniz modül sayısı birden fazladır. MPM seçiminin httpd’nin hızında ve ölçeklenebilirliğinde bazı etkileri olabilir:

Bu modüller ve diğerleri hakkında daha ayrıntılı bilgi edinmek için Çok Süreçlilik Modülleri belgesine bakınız.

Modüller

Bellek kullanımı başarım konusunda önemli olduğundan gerçekte kullanmadığınız modülleri elemeye çalışmalısınız. Modülleri birer DSO olarak derlediyseniz LoadModule yönergesinin bulunduğu satırı açıklama haline getirmeniz modülden kurtulmanız için yeterli olacaktır. Modülleri bu şekilde kaldırarak onların yokluğunda sitenizin hala işlevlerini yerine getirdiğini görme şansına da kavuşmuş olursunuz.

Ancak, eğer modülleri Apache çalıştırılabilirinin içine gömmüşseniz istenmeyen modülleri kaldırmak için Apache'yi yeniden derlemeniz gerekir.

Bu noktada bir soru akla gelebilir: Hangi modüller gerekli, hangileri değil? Bu sorunun yanıtı şüphesiz siteden siteye değişir. Ancak, olmazsa olmaz moüller olarak mod_mime, mod_dir ve mod_log_config modüllerini sayabiliriz. Bunlardan mod_log_config olmadan da bir sitenin çalışabileceğinden hareketle bu modülün varlığı isteğe bağlı olsa da bu modülü kaldırmanızı önermiyoruz.

Atomik İşlemler

Worker MPM'nin en son geliştirme sürümleri ve mod_cache gibi bazı modüller APR'nin atomik API'sini kullanırlar. Bu API, düşük ayarlı evre eşzamanlamasında atomik işlemler yapar.

Öntanımlı olarak, APR bu işlemleri hedef işletim sistemi/işlemci platformunda kullanılabilecek en verimli mekanizmayı kullanarak gerçekleştirir. Günümüz işlemcilerinin çoğu, örneğin, bir atomik karşılaştırma ve takas (CAS) işlemini donanımda gerçekleştirmektedir. Bazı platformlarda APR'nin atomik işlemler için öntanımlı olarak daha yavaş olan mutekslere dayalı gerçeklenimi kullanmasının sebebi eski işlemcilerde bu tür makine kodlarının yokluğudur. Apache'yi bu tür platformalarda günümüz işlemcileriyde çalıştırmayı düşünüyorsanız Apache'yi derlemek için yapılandırırken en hızlı atomik işlemin seçilebilmesi için --enable-nonportable-atomics seçeneğini kullanın:

./buildconf
./configure --with-mpm=worker --enable-nonportable-atomics=yes

--enable-nonportable-atomics seçeneği şu platformlar için uygundur:

mod_status ve ExtendedStatus On

mod_status modülünü derlemiş ve Apache'yi yapılandırır ve çalıştırırken ExtendedStatus On satırını da kullanmışsanız Apache her istek üzerinde gettimeofday(2) (veya işletim sistemine bağlı olarak time(2)) çağrısından başka (1.3 öncesinde) fazladan defalarca time(2) çağrıları yapacaktır. Bu çağrılarla durum raporununun zamanlama bilgilerini içermesi sağlanır. Başarımı arttırmak için ExtendedStatus off yapın (zaten öntanımlı böyledir).

accept dizgilemesi ve çok soketli işlem

Uyarı:

Bu bölüm, Apache HTTP sunucusunun 2.x sürümlerinde yapılan değişikliklere göre tamamen güncellenmemiştir. Bazı bilgiler hala geçerliyse de lütfen dikkatli kullanınız.

Burada Unix soket arayüzü gerçeklenirken ihmal edilen bir durumdan bahsedeceğiz. HTTP sunucunuzun çok sayıda adresten çok sayıda portu dinlemek için çok sayıda Listen yönergesi kullanmakta olduğunu varsayalım. Her soketi çalıştığını görmek için denerken Apache bağlantı için select(2) kullanacaktır. select(2) çağrısı bu soketin üzerinde sıfır veya en azından bir bağlantının beklemekte olduğu anlamına gelir. Apache'nin modeli çok sayıda çocuk süreç içerir ve boşta olanların tümünde aynı anda yeni bağlantılar denenebilir. Gerçekte çalışan kod bu olmasa da meramımızı anlatmak için kodun şöyle bir şey olduğunu varsayabiliriz:

        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);
        }

Bu özet gerçeklenim bir takım açlık sorunlarına sebep olur. Bu döngünün çalışması sırasında aynı anda çok sayıda çocuk süreç yeniden çağrılır ve istekler arasında kalan çoğu çocuk da select ile engellenir. Engellenen tüm bu çocuklar soketlerden herhangi biri üzerinde tek bir istek göründüğünde select tarafından uyandırılıp işleme sokulmak üzere döndürülürler. (Uyandırılan çocuk sayısı işletim sistemine ve zamanlama ayarlarına göre değişiklik gösterir,) Bunların hepsi döngüye katılıp bağlantı kabul etmeye (accept) çalışırlar. Fakat içlerinden yalnız biri (sadece bir bağlantı isteğinin mevcut olduğu varsayımıyla) bunu başarabilir. Kalanının bağlantı kabul etmesi (accept) engellenir. Bu durum, bu çocukları istekleri başka başka soketlerden değil mecburen tek bir soketten kabul etmeye kilitler ve bu soket üzerinde yeni bir istek belirip uyandırılana kadar bu durumda kalırlar. Bu açlık sorunu ilk olarak PR#467 sayılı raporla belgelenmiştir. Bu sorunun en az iki çözümü vardır.

Çözümün biri engellenmeyen soket kullanımıdır. Bu durumda accept çocukları engellemeyecek ve yapılan bir bağlantının ardından diğer çocuklar durumları değişmeksizin bağlantı beklemeye devam edeceklerdir. Fakat bu durum işlemci zamanının boşa harcanmasına sebep olur. Seçilmiş (select) boşta on çocuğun olduğunu ve bir bağlantı geldiğini varsayalım. Kalan dokuz çocuk işine devam edip bağlantı kabul etmeyi (accept) deneyecek, başarızsız olacak, dönecek başa, tekrar seçilecek (select) ve böyle hiçbir iş yapmadan dönüp duracaktır. Bu arada hizmet sunmakta olanlar da işlerini bitirdikten sonra bu döngüdeki yerlerini alacaklardır. Aynı kutunun içinde boşta bir sürü işlemciniz (çok işlemcili sistemler) yoksa bu çözüm pek verimli olmayacaktır.

Diğer çözüm ise Apache tarafından kullanılan çözüm olup, girdiyi bir iç döngüde sıraya sokmaktır. Döngü aşağıda örneklenmiştir (farklar vurgulanmıştır):

        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 ve accept_mutex_off işlevleri bir karşılıklı red semoforu oluştururlar. Mutekse aynı anda sadece bir çocuk sahip olabilir. Bu muteksleri gerçeklemek için çeşitli seçenekler vardır. Seçim, src/conf.h (1.3 öncesi) veya src/include/ap_config.h (1.3 ve sonrası) dosyasında tanımlanmıştır. Bazı mimariler bir kilitleme seçeneğine sahip değildir. Böyle mimarilerde çok sayıda Listen yönergesi kullanmak güvenilir olmayacaktır.

Mutex yönergesi, mpm-accept muteks gerçeklenimini çalışma anında değiştirmek için kullanılabilir. Farklı muteks gerçeklenimleri ile ilgili hususlar bu yönergede belgelenmiştir.

Başka bir çözüm daha vardır ancak döngü kısmen dizgilenmeyeceğinden (yani belli sayıda sürece izin verilemeyeceğinden) asla gerçeklenmemiştir. Bu sadece, aynı anda çok sayıda çocuk sürecin çalışabileceği ve dolayısıyla band genişliğinin tüm yönleriyle kullanılabileceği çok işlemcili sistemlerde ilginç olabilirdi. Bu gelecekte incelenmeye değer bir konu olmakla beraber çok sayıda HTTP sunucusunun aynı anda aynı amaca hizmet edecek şekilde çalışması standart olarak pek mümkün görülmediğinden bu olasılık çok düşüktür.

En yüksek başarımı elde etmek için ideal olanı sunucuları çalıştırırken çok sayıda Listen yönergesi kullanmamaktır. Fakat siz yine de okumaya devam edin.

accept dizgilemesi - tek soket

Çok soketli sunucular için yukarıda açıklananlar iyi güzel de tek soketli sunucularda durum ne? Kuramsal olarak, bunların hiçbiriyle bir sorunları olmaması gerekir. Çünkü yeni bir bağlantı gelene kadar tüm çocuklar accept(2) ile engellenirler dolayısıyla hiçbir açlık sorununun ortaya çıkmaması gerekir. Uygulamada ise son kullanıcıdan gizli olarak, yukarıda engellenmeyen çocuklar çözümünde bahsedilenle hemen hemen aynı "boşa dönüp durma" davranışı mevcuttur. Çoğu TCP yığıtı bu yolu gerçeklemiştir. Çekirdek, yeni bir bağlantı ortaya çıktığında accept ile engellenen tüm süreçleri uyandırır. Bu süreçlerden bağlantıyı alan kullanıcı bölgesine geçerken çekirdek içinde döngüde olan diğerleri de yeni bağlantı keşfedilene kadar uykularına geri dönerler. Bu çekirdek içi döngü, kullanıcı bölgesindeki kodlara görünür değildir ama bu olmadıkları anlamına gelmez. Bu durum, çok soketli engellenmeyen çocuklar çözümündeki boşa döngünün sebep olduğu gereksiz işlemci yükü sorununu içinde barındırır.

Bununla birlikte, tek soketli durumda bile bundan daha verimli bir davranış sergileyen bir çok mimari bulduk. Bu aslında hemen hemen her durumda öntanımlı olarak böyledir. Linux altında yapılan üstünkörü denemelerde (128MB bellekli çift Pentium pro 166 işlemcili makinede Linux 2.0.30) tek sokette dizgilemenin dizgilenmemiş duruma göre saniyede %3 daha az istekle sonuçlandığı gösterilmiştir. Fakat dizgilenmemiş tek soket durumunda her istekte 100ms'lik ek bir gecikme olduğu görülmüştür. Bu gecikmenin sebebi muhtemelen uzun mesafeli hatlar olup sadece yerel ağlarda söz konusudur. Tek soketli dizgilemeyi geçersiz kılmak için SINGLE_LISTEN_UNSERIALIZED_ACCEPT tanımlarsanız tek soketli sunucularda artık dizgileme yapılmayacaktır.

Kapatmayı zamana yaymak

draft-ietf-http-connection-00.txt taslağının 8. bölümünde bahsedildiği gibi, bir HTTP sunucusunun protokolü güvenilir şekilde gerçeklemesi için her iki yöndeki iletişimi birbirinden bağımsız olarak (iki yönlü bir TCP bağlantısının her yarısını diğerinden bağımsız olarak) kapatması gerekir.

Bu özellik Apache'ye eklendiğinde Unix'in çeşitli sürümlerinde uzgörüsüzlükten dolayı bir takım geçici telaş sorunlarına sebep oldu. TCP belirtimi FIN_WAIT_2 durumunda bir zaman aşımından bahsetmez ama yasaklamaz da. Zaman aşımı olmayan sistemlerde, Apache 1.2 çoğu soketin sonsuza kadar FIN_WAIT_2 durumunda takılıp kalmasına sebep olur. Çoğu durumda, satıcıdan sağlanan en son TCP/IP yamalarını uygulanarak bu önlenebilir. Satıcının hiçbir yeni yama dağıtmadığı durumlarda (örneğin, SunOS4 -- bir kaynak lisansı ile insanlar bunu kendileri yamayabilirse de) bu özelliği devre dışı bırakmaya karar verdik.

Bunun üstesinden gelmenin iki yolu vardır. Bunlardan biri SO_LINGER soket seçeneğidir. Bu işin kaderi buymuş gibi görünürse de çoğu TCP/IP yığıtında bu gerektiği gibi gerçeklenmemiştir. Bu yığıtlar üzerinde, bu yöntemin, doğru bir gerçeklenimle bile (örneğin, Linux 2.0.31) sonraki çözümden daha pahalı olduğu ortaya çıkmıştır.

Çoğunlukla, Apache bunu (http_main.c içindeki) lingering_close adında bir işlevle gerçekler. Bu işlev kabaca şöyle görünür:

        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);
        }

Bağlantı sonunda bu doğal olarak biraz daha masrafa yol açar, fakat güvenilir bir gerçeklenim için bu gereklidir. HTTP/1.1'in daha yaygın kullanılmaya başlanması ve tüm bağlantıların kalıcı hale gelmesiyle bu gerçeklenim daha fazla istek üzerinden kendi masrafını karşılayacaktır. Ateşle oynamak ve bu özelliği devre dışı bırakmak isterseniz NO_LINGCLOSE'u tanımlayabilirsiniz, fakat bu asla önerilmez. Özellikle, HTTP/1.1'den itibaren boruhatlı kalıcı bağlantıların lingering_close kullanmaya başlaması mutlak bir gerekliliktir (ve boruhatlı bağlantıların daha hızlı olması nedeniyle bu bağlantıları desteklemek isteyebilirsiniz).

Çetele Dosyası

Apache'nin ana ve alt süreçleri birbirleriyle çetele denen birşey üzerinden haberleşirler. Bunun en mükemmel şekilde paylaşımlı bellekte gerçeklenmesi gerekir. Eriştiğimiz veya portlarını ayrıntılı olarak belirttiğimiz işletim sistemleri için bu, genellikle paylaşımlı bellek kullanılarak gerçeklenir. Geri kalanlar, öntanımlı olarak bunu bir disk dosyası kullanarak gerçekler. Bir disk dosyaı yavaş olmanın yanı sıra güvenilir de değildir (ve daha az özelliğe sahiptir). Mimarinizin src/main/conf.h dosyasını inceleyin ve USE_MMAP_SCOREBOARD veya USE_SHMGET_SCOREBOARD'a bakın. Bu ikisinden birinin (ve yanı sıra sırasıyla HAVE_MMAP veya HAVE_SHMGET'in) tanımlanmış olması, sağlanan paylaşımlı bellek kodunu etkinleştirir. Eğer sisteminiz diğer türdeki paylaşımlı belleğe sahipse, src/main/http_main.c dosyasını açıp, Apache'de bu belleği kullanması gereken kanca işlevleri ekleyin (Bize de bir yama yollayın, lütfen).

Tarihsel bilgi: Apache'nin Linux uyarlaması, Apache'nin 1.2 sürümüne kadar paylaşımlı belleği kullanmaya başlamamıştı. Bu kusur, Apache'nin Linux üzerindeki erken dönem sürümlerinin davranışlarının zayıf ve güvenilmez olmasına yol açmıştı.

DYNAMIC_MODULE_LIMIT

Devingen olarak yüklenen modülleri kullanmamak niyetindeyseniz (burayı okuyan ve sunucunuzun başarımını son kırıntısına kadar arttırmakla ilgilenen biriyseniz bunu düşünmezsiniz), sunucunuzu derlerken seçenekler arasına -DDYNAMIC_MODULE_LIMIT=0 seçeneğini de ekleyin. Bu suretle, sadece, devingen olarak yüklenen modüller için ayrılacak belleği kazanmış olacaksınız.

top

Ek: Bir çağrı izlemesinin ayrıntılı çözümlemesi

Burada, Solaris 8 üzerinde worker MPM'li Apache 2.0.38'in bir sistem çağrısı izlenmektedir. Bu izleme şu komutla elde edilmiştir:

truss -l -p httpd_çocuk_pidi.

-l seçeneği, truss'a hafif bir sürecin yaptığı her sistem çağrısını (hafif süreç -- HS -- Solaris'in bir çekirdek seviyesi evreleme biçimi) günlüğe yazmasını söyler.

Diğer sistemlerin sistem çağrılarını izleyen farklı araçları vardır (strace, ktrace, par gibi). Bunlar da benzer çıktılar üretirler.

Bu izleme sırasında, bir istemci httpd'den 10 KB'lık duruk bir dosya talebinde bulunmuştur. Duruk olmayan veya içerik uzlaşımlı isteklerin izleme kayıtları vahşice (bazı durumlarda epey çirkince) farklı görünür.

/67: accept(3, 0x00200BEC, 0x00200C0C, 1) (uykuda...)
/67: accept(3, 0x00200BEC, 0x00200C0C, 1) = 9

Bu izlemede, dinleyen evre HS #67 içinde çalışmaktadır.

accept(2) dizgelemesinin olmayışına dikkat edin. Özellikle bu platformda worker MPM, çok sayıda portu dinlemedikçe, öntanımlı olarak dizgeleştirilmemiş bir accept çağrısı kullanır.

/65: lwp_park(0x00000000, 0) = 0
/67: lwp_unpark(65, 1) = 0

Bağlantının kabul edilmesiyle, dinleyici evre isteği yerine getirmek üzere bir worker evresini uyandırır. Bu izlemede, isteği yerine getiren worker evresi HS #65'e aittir.

/65: getsockname(9, 0x00200BA4, 0x00200BC4, 1) = 0

Sanal konakların gerçeklenimi sırasında, Apache'nin, bağlantıları kabul etmek için kullanılan yerel soket adreslerini bilmesi gerekir. Çoğu durumda bu çağrıyı bertaraf etmek mümkündür (hiç sanal konağın olmadığı veya Listen yönergelerinin mutlak adreslerle kullanıldığı durumlarda). Fakat bu en iyilemeleri yapmak için henüz bir çaba harcanmamıştır.

/65: brk(0x002170E8) = 0
/65: brk(0x002190E8) = 0

brk(2) çağrıları devingen bellekten bellek ayırır. httpd çoğu isteği yerine getirirken özel bellek ayırıcılar (apr_pool ve apr_bucket_alloc) kullandığından bunlar bir sistem çağrısı izlemesinde nadiren görünür. Bu izlemede, httpd henüz yeni başlatıldığından, özel bellek ayırıcıları oluşturmak için ham bellek bloklarını ayırmak amacıyla malloc(3) çağrıları yapması gerekir.

/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

Ardından, worker evresi istemciye (dosya tanıtıcısı 9) engellenmeyen kipte bir bağlantı açar. setsockopt(2) ve getsockopt(2) çağrıları, Solaris libc'sinin soketler üzerindeki fcntl(2) çağrısı yanında birer yan etkiden ibarettirler.

/65: read(9, " G E T / 1 0 k . h t m".., 8000) = 97

Worker evresi istemciden isteği okur.

/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

Bu httpd Options FollowSymLinks ve AllowOverride None ile yapılandırılmıştır. Bu bakımdan, ne istenen dosya ile sonuçlanan yol üzerindeki her dizinde lstat(2) çağrısına ne de .htaccess dosyalarına bakılmasına gerek vardır. stat(2) çağrısı basitçe dosya için şunları doğrulamak amacıyla yapılır: 1) dosya mevcuttur ve 2) bir dizin değil normal bir dosyadır.

/65: sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C) = 10269

Bu örnekte, httpd, istenen dosyayı ve HTTP yanıt başlığını tek bir sendfilev(2) sistem çağrısı ile göndermektedir. Dosya gönderim işleminin anlamı sistemden sisteme değişiklik gösterir. Bazı sistemlerde, sendfile(2) çağrısından önce başlıkları göndermek için write(2) veya writev(2) çağrısı yapmak gerekir.

/65: write(4, " 1 2 7 . 0 . 0 . 1 - ".., 78) = 78

Bu write(2) çağrısı isteği erişim günlüğüne kaydeder. Bu izlemede eksik olan tek şey, time(2) çağrısıdır. Apache 1.3'ün aksine, Apache 2.x zamana bakmak için gettimeofday(3) çağırısını kullanır. Linux ve Solaris gibi bazı işletim sistemleri, gettimeofday işlevinin, sıradan bir sistem çağrısından daha fazla götürüsü olmayan en iyilenmiş bir gerçeklenimine sahiptir.

/65: shutdown(9, 1, 1) = 0
/65: poll(0xFAF7B980, 1, 2000) = 1
/65: read(9, 0xFAF7BC20, 512) = 0
/65: close(9) = 0

Burada worker evresi bağlantıyı zamana yaymaktadır.

/65: close(10) = 0
/65: lwp_park(0x00000000, 0) (uykuda...)

Son olarak, worker evresi teslim edilen dosyayı kapattıktan sonra dinleyici evre tarafından başka bir bağlantı atanıncaya kadar beklemeye alınır.

/67: accept(3, 0x001FEB74, 0x001FEB94, 1) (uykuda...)

Bu arada, dinleyici evre bağlantıyı bir worker evresine atar atamaz başka bir bağlantıyı beklemeye başlar (Mevcut tüm evreler meşgulse dinleyici evreyi baskılayan worker MPM'nin akış denetim şemasına konu olur). Bu izlemede görünmüyor olsa da sonraki accept(2) çağrısı, yeni bağlantı kabul eden worker evresine paralel olarak yapılabilir (aşırı yük durumlarında normal olarak, bu yapılır).

Mevcut Diller:  en  |  fr  |  ko  |  tr 

top

Yorumlar

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/index.html.fr.utf80000664000175100017510000001257114740503670021266 0ustar covenercovener Documentations diverses sur Apache - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4

Documentations diverses sur Apache

Langues Disponibles:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

Vous trouverez plus loin une liste de pages de documentation additionnelles concernant le projet de développement du serveur web Apache.

Avertissement

La mise à jour des documents ci-dessous permettant de prendre en compte les modifications apportées par la version 2.1 du serveur HTTP Apache n'a pas été entièrement menée à bien. Certaines informations sont probablement encore pertinentes, mais utilisez-les tout de même avec précautions.

Notes à propos des performances - Réglages fins d'Apache

Notes à propos de la configuration d'Apache pour de plus hautes performances (à l'exécution et à la compilation). Notes expliquant pourquoi Apache accomplit certaines choses et n'en accomplit pas certaines autres (les premières l'accélérant et les deuxièmes le ralentissant).

Conseils concernant la sécurité

Quelques conseils de type "faites" ou "ne faites pas" pour que votre site web Apache reste sécurisé.

Standards concernés

Ce document constitue une page de référence pour la plupart des standards concernés par Apache.

Formats de chiffrement des mots de passe

Discussion à propos des divers algorithmes de chiffrement supportés par Apache à des fins d'authentification.

Langues Disponibles:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/misc/relevant_standards.html.fr.utf80000664000175100017510000003201614740503670024036 0ustar covenercovener Standards applicables - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Documentations diverses

Standards applicables

Langues Disponibles:  en  |  fr  |  ko 

Cette page documente tous les standards applicables que suit le serveur HTTP Apache, accompagnés d'une brève description.

Pour compléter les informations fournies ci-dessous, vous pouvez consulter les ressources suivantes :

Avertissement

Ce document n'est pas encore finalisé.

Support Apache!

Voir aussi

top

Recommandations HTTP

Indépendamment des modules compilés et utilisés, Apache en tant que serveur web de base respecte les recommandations IETF suivantes :

RFC 1945 (Informations)
Le Protocole de Transfert Hypertexte (Hypertext Transfer Protocol - HTTP) est un protocole de niveau application avec la clarté et la vitesse nécessaires pour les systèmes d'informations distribués, collaboratifs et hypermédia. Cette RFC documente le protocole HTTP/1.0.
RFC 2616 (Série de standards)
Le Protocole de Transfert Hypertexte (Hypertext Transfer Protocol - HTTP) est un protocole de niveau application pour les systèmes d'informations distribués, collaboratifs et hypermédia. Cette RFC documente le protocole HTTP/1.1.
RFC 2396 (Série de standards)
Un Identificateur de Ressource Uniforme (Uniform Resource Identifier - URI) est une chaîne de caractères compacte permettant d'identifier une ressource physique ou abstraite.
RFC 4346 (Série de standards)
Le protocole TLS permet l'utilisation de communications sécurisées sur l'Internet. Il fournit le chiffrement, et a été conçu pour se prémunir contre l'interception, la modification et la falsification de messages.
top

Recommandations HTML

En ce qui concerne le langage HTML, Apache respecte les recommandations IETF et W3C suivantes :

RFC 2854 (Informations)
Ce document résume l'historique du développement de HTML, et définit le type MIME "text/html" en pointant les recommandations W3C correspondantes.
Spécification HTML 4.01 (Corrections d'erreurs)
Cette spécification définit le Langage à Balises HyperTexte (HyperText Markup Language - HTML), le langage de publication du World Wide Web. Elle définit HTML 4.01, qui est une sous-version de HTML 4.
Référence HTML 3.2
Le langage à Balises HyperTexte (HyperText Markup Language - HTML) est un langage à balises simple permettant de créer des documents hypertextes portables. Les documents HTML sont aussi des documents SGML.
XHTML 1.1 - XHTML sous forme de modules (Corrections d'erreurs)
Cette recommandation définit un nouveau type de document XHTML basé sur le cadre de développement des modules et les modules définis dans la modularisation de XHTML.
XHTML 1.0, le Langage à Balises Hypertexte Extensible (Extensible HyperText Markup Language) - Seconde édition (Corrections d'erreurs)
Cette spécification définit la seconde édition de XHTML 1.0, une reformulation de HTML 4 en tant qu'application XML 1.0, ainsi que trois DTDs correspondant à celles définies par HTML 4.
top

Authentification

En ce qui concerne les différentes méthodes d'authentification, Apache respecte les recommandations IETF suivantes :

RFC 2617 (Le track des standards)
"HTTP/1.0", y compris la spécification d'un protocole basique d'authentification et de contrôle d'accès.
top

Codes de langues et de pays

Les liens suivants fournissent des informations à propos des codes de langues et de pays aux normes ISO ou autres :

ISO 639-2
ISO 639 fournit deux jeux de codes de langues permettant de représenter les noms des langues ; le premier est un jeu de codes sur deux lettres (639-1), le second (celui présenté dans le lien ci-dessus), est un jeu de codes sur trois lettres (639-2).
ISO 3166-1
Ce document présente les noms de pays (les noms raccourcis officiels en anglais) dans l'ordre alphabétique, tels qu'ils sont présentés dans la norme ISO 3166-1 et les éléments de codes correspondants de la norme ISO 3166-1-alpha-2.
BCP 47 (Les meilleurs pratiques courantes), RFC 3066
Ce document décrit une balise de langue permettant de spécifier la langue utilisé dans un objet contenant des informations, la manière d'enregistrer des valeurs à utiliser dans cette balise de langage, et une méthode pour comparer les balises de langue de ce style.
RFC 3282 (Série de standards)
Ce document définit un en-tête "Content-language:" permettant de spécifier le langage d'un élément possédant des en-têtes du style RFC 822, comme les portions de corps MIME ou les documents Web, et un en-tête "Accept-Language:" permettant de spécifier des préférences en matière de langue.

Langues Disponibles:  en  |  fr  |  ko 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/password_encryptions.html.en0000664000175100017510000003067014737241666023576 0ustar covenercovener Password Formats - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Miscellaneous Documentation

Password Formats

Available Languages:  en  |  fr 

Notes about the password encryption formats generated and understood by Apache.

Support Apache!

See also

top

Basic Authentication

There are five formats that Apache recognizes for basic-authentication passwords. Note that not all formats work on every platform:

bcrypt
"$2y$" + the result of the crypt_blowfish algorithm. See the APR source file crypt_blowfish.c for the details of the algorithm.
MD5
"$apr1$" + the result of an Apache-specific algorithm using an iterated (1,000 times) MD5 digest of various combinations of a random 32-bit salt and the password. See the APR source file apr_md5.c for the details of the algorithm.
SHA1
"{SHA}" + Base64-encoded SHA-1 digest of the password. Insecure.
CRYPT
Unix only. Uses the traditional Unix crypt(3) function with a randomly-generated 32-bit salt (only 12 bits used) and the first 8 characters of the password. Insecure.
PLAIN TEXT (i.e. unencrypted)
Windows & Netware only. Insecure.

Generating values with htpasswd

bcrypt

$ htpasswd -nbB myName myPassword
myName:$2y$05$c4WoMPo3SXsafkva.HHa6uXQZWr7oboPiC2bT/r7q1BB8I2s0BRqC

MD5

$ htpasswd -nbm myName myPassword
myName:$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/

SHA1

$ htpasswd -nbs myName myPassword
myName:{SHA}VBPuJHI7uixaa6LQGWx4s+5GKNE=

CRYPT

$ htpasswd -nbd myName myPassword
myName:rqXexS6ZhobKA

Generating CRYPT and MD5 values with the OpenSSL command-line program

OpenSSL knows the Apache-specific MD5 algorithm.

MD5

$ openssl passwd -apr1 myPassword
$apr1$qHDFfhPC$nITSVHgYbDAK1Y0acGRnY0

CRYPT

openssl passwd -crypt myPassword
qQ5vTYO3c8dsU

Validating CRYPT or MD5 passwords with the OpenSSL command line program

The salt for a CRYPT password is the first two characters (converted to a binary value). To validate myPassword against rqXexS6ZhobKA

CRYPT

$ openssl passwd -crypt -salt rq myPassword
Warning: truncating password to 8 characters
rqXexS6ZhobKA

Note that using myPasswo instead of myPassword will produce the same result because only the first 8 characters of CRYPT passwords are considered.

The salt for an MD5 password is between $apr1$ and the following $ (as a Base64-encoded binary value - max 8 chars). To validate myPassword against $apr1$r31.....$HqJZimcKQFAMYayBlzkrA/

MD5

$ openssl passwd -apr1 -salt r31..... myPassword
$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/

Database password fields for mod_dbd

The SHA1 variant is probably the most useful format for DBD authentication. Since the SHA1 and Base64 functions are commonly available, other software can populate a database with encrypted passwords that are usable by Apache basic authentication.

To create Apache SHA1-variant basic-authentication passwords in various languages:

PHP

'{SHA}' . base64_encode(sha1($password, TRUE))

Java

"{SHA}" + new sun.misc.BASE64Encoder().encode(java.security.MessageDigest.getInstance("SHA1").digest(password.getBytes()))

ColdFusion

"{SHA}" & ToBase64(BinaryDecode(Hash(password, "SHA1"), "Hex"))

Ruby

require 'digest/sha1'
require 'base64'
'{SHA}' + Base64.encode64(Digest::SHA1.digest(password))

C or C++

Use the APR function: apr_sha1_base64

Python

import base64
import hashlib
"{SHA}" + format(base64.b64encode(hashlib.sha1(password).digest()))

PostgreSQL (with the contrib/pgcrypto functions installed)

'{SHA}'||encode(digest(password,'sha1'),'base64')

top

Digest Authentication

Apache recognizes one format for digest-authentication passwords - the MD5 hash of the string user:realm:password as a 32-character string of hexadecimal digits. realm is the Authorization Realm argument to the AuthName directive in httpd.conf.

Database password fields for mod_dbd

Since the MD5 function is commonly available, other software can populate a database with encrypted passwords that are usable by Apache digest authentication.

To create Apache digest-authentication passwords in various languages:

PHP

md5($user . ':' . $realm . ':' .$password)

Java

byte b[] = java.security.MessageDigest.getInstance("MD5").digest( (user + ":" + realm + ":" + password ).getBytes());
java.math.BigInteger bi = new java.math.BigInteger(1, b);
String s = bi.toString(16);
while (s.length() < 32)
s = "0" + s; // String s is the encrypted password

ColdFusion

LCase(Hash( (user & ":" & realm & ":" & password) , "MD5"))

Ruby

require 'digest/md5'
Digest::MD5.hexdigest(user + ':' + realm + ':' + password)

PostgreSQL (with the contrib/pgcrypto functions installed)

encode(digest( user || ':' || realm || ':' || password , 'md5'), 'hex')

Available Languages:  en  |  fr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/perf-tuning.html.en0000664000175100017510000014276314737241666021544 0ustar covenercovener Apache Performance Tuning - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Miscellaneous Documentation

Apache Performance Tuning

Available Languages:  en  |  fr  |  ko  |  tr 

Apache 2.x 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.x is capable of high performance in many real-world situations.

Compared to Apache 1.3, release 2.x 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.x 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.

Support Apache!

See also

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 MaxRequestWorkers setting so that your server does not spawn so many children that it starts swapping. The 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:

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, or 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 two DNS lookups (a reverse, followed by a forward lookup 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 need 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.x 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:

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.x can ignore the contents of the file to be delivered -- for example, when serving static file content -- it normally uses the kernel sendfile support for 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:

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 of 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 it 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 MaxConnectionsPerChild setting. By default this is 0, which means that there is no limit to the number of connections 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: 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:

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 you are 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 absence.

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:

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.x 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 Mutex directive can be used to change the mutex implementation of the mpm-accept mutex at run-time. Special considerations for different mutex implementations are documented with that directive.

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 that 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 the children can just block in accept(2) until a connection arrives, and no starvation results. In practice this hides almost the same "spinning" behavior 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 behavior 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 shut down each direction of the communication independently. (Recall that a TCP connection is bi-directional. Each half is independent of the other.)

When this feature was added to Apache, it caused a flurry of problems on various versions of Unix because of 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 to accomplish 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 behavior 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' 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' 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.x 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  |  fr  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/index.html0000664000175100017510000000104613710016232017753 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: index.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: index.html.es Content-Language: es Content-type: text/html; charset=ISO-8859-1 URI: index.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: index.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: index.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 URI: index.html.zh-cn.utf8 Content-Language: zh-cn Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/misc/security_tips.html0000664000175100017510000000062613710016232021555 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: security_tips.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: security_tips.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: security_tips.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: security_tips.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/misc/relevant_standards.html0000664000175100017510000000051013710016232022522 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: relevant_standards.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: relevant_standards.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: relevant_standards.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR httpd-2.4.64/docs/manual/misc/index.html.en0000664000175100017510000001205414737241666020402 0ustar covenercovener Apache Miscellaneous Documentation - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4

Apache Miscellaneous Documentation

Available Languages:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

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.

Relevant Standards

This document acts as a reference page for most of the relevant standards that Apache follows.

Password Encryption Formats

Discussion of the various ciphers supported by Apache for authentication purposes.

Available Languages:  en  |  es  |  fr  |  ko  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/misc/security_tips.html.en0000664000175100017510000006431714737241666022212 0ustar covenercovener Security Tips - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Miscellaneous Documentation

Security Tips

Available Languages:  en  |  fr  |  ko  |  tr 

Some hints and tips on security issues in setting up a web server. Some of the suggestions will be general, others specific to Apache.

Support Apache!

See also

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

Denial of Service (DoS) attacks

All network servers can be subject to denial of service attacks that attempt to prevent responses to clients by tying up the resources of the server. It is not possible to prevent such attacks entirely, but you can do certain things to mitigate the problems that they create.

Often the most effective anti-DoS tool will be a firewall or other operating-system configurations. For example, most firewalls can be configured to restrict the number of simultaneous connections from any individual IP address or network, thus preventing a range of simple attacks. Of course this is no help against Distributed Denial of Service attacks (DDoS).

There are also certain Apache HTTP Server configuration settings that can help mitigate problems:

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 designated 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:

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

Dynamic content security

When setting up dynamic content, such as mod_php, mod_perl or mod_python, many security considerations get out of the scope of httpd itself, and you need to consult documentation from those modules. For example, PHP lets you setup Safe Mode, which is most usually disabled by default. Another example is Suhosin, a PHP addon for more security. For more information about those, consult each project documentation.

At the Apache level, a module named mod_security can be seen as a HTTP firewall and, provided you configure it finely enough, can help you enhance your dynamic content security.

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.

Note that this setting is the default since Apache 2.3.9.

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 "/">
    Require all denied
</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">
    Require all granted
</Directory>
<Directory "/usr/local/httpd">
    Require all granted
</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. 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 allow 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.example.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.example.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*">
    Require all denied
</Files>
top

Merging of configuration sections

The merging of configuration sections is complicated and sometimes directive specific. Always test your changes when creating dependencies on how directives are merged.

For modules that don't implement any merging logic, such as mod_access_compat, the behavior in later sections depends on whether the later section has any directives from the module. The configuration is inherited until a change is made, at which point the configuration is replaced and not merged.

Available Languages:  en  |  fr  |  ko  |  tr 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/perf-tuning.html0000664000175100017510000000061613710016232021104 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: perf-tuning.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: perf-tuning.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 URI: perf-tuning.html.ko.euc-kr Content-Language: ko Content-type: text/html; charset=EUC-KR URI: perf-tuning.html.tr.utf8 Content-Language: tr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/misc/security_tips.html.fr.utf80000664000175100017510000007055114740503670023067 0ustar covenercovener Conseils sur la sécurité - Serveur HTTP Apache Version 2.4
<-
Apache > Serveur HTTP > Documentation > Version 2.4 > Documentations diverses

Conseils sur la sécurité

Langues Disponibles:  en  |  fr  |  ko  |  tr 

Ce document propose quelques conseils et astuces concernant les problèmes de sécurité liés à l'installation d'un serveur web. Certaines suggestions seront à caractère général, tandis que d'autres seront spécifiques à Apache.

Support Apache!

Voir aussi

top

Maintenez votre serveur à jour

Le serveur HTTP Apache a une bonne réputation en matière de sécurité et possède une communauté de développeurs très sensibilisés aux problèmes de sécurité. Mais il est inévitable de trouver certains problèmes -- petits ou grands -- une fois le logiciel mis à disposition. C'est pour cette raison qu'il est crucial de se tenir informé des mises à jour. Si vous avez obtenu votre version du serveur HTTP directement depuis Apache, nous vous conseillons grandement de vous abonner à la Liste de diffusion des annonces du serveur HTTP qui vous informera de la parution des nouvelles versions et des mises à jour de sécurité. La plupart des distributeurs tiers d'Apache fournissent des services similaires.

Gardez cependant à l'esprit que lorsqu'un serveur web est compromis, le code du serveur HTTP n'est la plupart du temps pas en cause. Les problèmes proviennent plutôt de code ajouté, de scripts CGI, ou du système d'exploitation sous-jacent. Vous devez donc vous tenir informé des problèmes et mises à jour concernant tous les logiciels présents sur votre système.

top

Attaques de type "Déni de service" (Denial of Service - DoS)

Tous les services réseau peuvent faire l'objet d'attaques de type "Déni de service" qui tentent de les empêcher de répondre aux clients en saturant leurs ressources. Il est impossible de se prémunir totalement contre ce type d'attaques, mais vous pouvez accomplir certaines actions afin de minimiser les problèmes qu'elles créent.

Souvent, l'outil anti-DoS le plus efficace sera constitué par le pare-feu ou certaines configurations du système d'exploitation. Par exemple, la plupart des pare-feu peuvent être configurés de façon à limiter le nombre de connexions simultanées depuis une adresse IP ou un réseau, ce qui permet de prévenir toute une gamme d'attaques simples. Bien sûr, ceci n'est d'aucun secours contre les attaques de type "Déni de service" distribuées (DDoS).

Certains réglages de la configuration d'Apache peuvent aussi minimiser les problèmes :

top

Permissions sur les répertoires de la racine du serveur

Typiquement, Apache est démarré par l'utilisateur root, puis il devient la propriété de l'utilisateur défini par la directive User afin de répondre aux demandes. Comme pour toutes les commandes exécutées par root, vous devez vous assurer qu'elle n'est pas modifiable par les utilisateurs autres que root. Les fichiers eux-mêmes, mais aussi les répertoires ainsi que leurs parents ne doivent être modifiables que par root. Par exemple, si vous avez choisi de placer la racine du serveur dans /usr/local/apache, il est conseillé de créer le répertoire en tant que root, avec des commandes du style :

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

Nous supposerons que /, /usr et /usr/local ne sont modifiables que par root. Quand vous installez l'exécutable httpd, vous devez vous assurer qu'il possède des protections similaires :

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

Vous pouvez créer un sous-répertoire htdocs modifiable par d'autres utilisateurs -- car root ne crée ni exécute aucun fichier dans ce sous-répertoire.

Si vous permettez à des utilisateurs non root de modifier des fichiers que root écrit ou exécute, vous exposez votre système à une compromission de l'utilisateur root. Par exemple, quelqu'un pourrait remplacer le binaire httpd de façon à ce que la prochaine fois que vous le redémarrerez, il exécutera un code arbitraire. Si le répertoire des journaux a les droits en écriture (pour un utilisateur non root), quelqu'un pourrait remplacer un fichier journal par un lien symbolique vers un autre fichier système, et root pourrait alors écraser ce fichier avec des données arbitraires. Si les fichiers journaux eux-mêmes ont des droits en écriture (pour un utilisateur non root), quelqu'un pourrait modifier les journaux eux-mêmes avec des données fausses.

top

Inclusions côté serveur

Les inclusions côté serveur (Server Side Includes - SSI) exposent l'administrateur du serveur à de nombreux risques potentiels en matière de sécurité.

Le premier risque est l'augmentation de la charge du serveur. Tous les fichiers où SSI est activé doivent être analysés par Apache, qu'ils contiennent des directives SSI ou non. L'augmentation de la charge induite est minime, mais peut devenir significative dans le contexte d'un serveur partagé.

Les fichiers SSI présentent les mêmes risques que les scripts CGI en général. Les fichiers où SSI est activé peuvent exécuter tout script CGI ou autre programme à l'aide de la commande "exec cmd" avec les permissions des utilisateur et groupe sous lesquels Apache s'exécute, comme défini dans httpd.conf.

Des méthodes existent pour améliorer la sécurité des fichiers SSI, tout en tirant parti des bénéfices qu'ils apportent.

Pour limiter les dommages qu'un fichier SSI agressif pourrait causer, l'administrateur du serveur peut activersuexec comme décrit dans la section Les CGI en général.

L'activation des SSI pour des fichiers possédant des extensions .html ou .htm peut s'avérer dangereux. Ceci est particulièrement vrai dans un environnement de serveur partagé ou étant le siège d'un traffic élevé. Les fichiers où SSI est activé doivent posséder une extension spécifique, telle que la conventionnelle .shtml. Ceci permet de limiter la charge du serveur à un niveau minimum et de simplifier la gestion des risques.

Une autre solution consiste à interdire l'exécution de scripts et programmes à partir de pages SSI. Pour ce faire, remplacez Includes par IncludesNOEXEC dans la directive Options. Notez que les utilisateurs pourront encore utiliser <--#include virtual="..." --> pour exécuter des scripts CGI si ces scripts sont situés dans des répertoires spécifiés par une directive ScriptAlias.

top

Les CGI en général

Tout d'abord, vous devez toujours garder à l'esprit que vous devez faire confiance aux développeurs de scripts ou programmes CGI ainsi qu'à vos compétences pour déceler les trous de sécurité potentiels dans les CGI, que ceux-ci soient délibérés ou accidentels. Les scripts CGI peuvent essentiellement exécuter des commandes arbitraires sur votre système avec les droits de l'utilisateur du serveur web, et peuvent par conséquent être extrèmement dangereux s'ils ne sont pas vérifiés avec soin.

Tous les scripts CGI s'exécutent sous le même utilisateur, il peuvent donc entrer en conflit (accidentellement ou délibérément) avec d'autres scripts. Par exemple, l'utilisateur A hait l'utilisateur B, il écrit donc un script qui efface la base de données CGI de l'utilisateur B. Vous pouvez utiliser le programme suEXEC pour faire en sorte que les scripts s'exécutent sous des utilisateurs différents. Ce programme est inclus dans la distribution d'Apache depuis la version 1.2 et est appelé à partir de certaines portions de code du serveur Apache. Une autre méthode plus connue est l'utilisation de CGIWrap.

top

CGI sans alias de script

Vous ne devez permettre aux utilisateurs d'exécuter des scripts CGI depuis n'importe quel répertoire que dans l'éventualité où :

top

CGI avec alias de script

Le confinement des CGI dans des répertoires spécifiques permet à l'administrateur de contrôler ce que l'on met dans ces répertoires. Ceci est bien entendu mieux sécurisé que les CGI sans alias de script, mais seulement à condition que les utilisateurs avec les droits en écriture sur les répertoires soient dignes de confiance, et que l'administrateur ait la volonté de tester chaque programme ou script CGI à la recherche d'éventuels trous de sécurité.

La plupart des sites choisissent cette approche au détriment des CGI sans alias de script.

top

Autres sources de contenu dynamique

Les options de scripting intégrées qui s'exécutent en tant que partie du serveur lui-même, comme mod_php, mod_perl, mod_tcl, et mod_python, s'exécutent sous le même utilisateur que le serveur (voir la directive User), et par conséquent, les scripts que ces moteurs exécutent peuvent accéder aux mêmes ressources que le serveur. Certains moteurs de scripting peuvent proposer des restrictions, mais pour plus de sûreté, il vaut mieux partir du principe que ce n'est pas le cas.

top

Protection de la configuration du système

Pour contrôler étroitement votre serveur, vous pouvez interdire l'utilisation des fichiers .htaccess qui permettent de passer outre les fonctionnalités de sécurité que vous avez configurées. Voici un moyen pour y parvenir :

Ajoutez dans le fichier de configuration du serveur

<Directory "/">
    AllowOverride None
</Directory>

Ceci interdit l'utilisation des fichiers .htaccess dans tous les répertoires, sauf ceux pour lesquels c'est explicitement autorisé.

Notez que c'est la configuration par défaut depuis Apache 2.3.9.

top

Protection par défaut des fichiers du serveur

Le concept d'accès par défaut est un aspect d'Apache qui est parfois mal compris. C'est à dire que, à moins que vous ne changiez explicitement ce comportement, si le serveur trouve son chemin vers un fichier en suivant les règles normales de correspondance URL - fichier, il peut le retourner aux clients.

Considérons l'exemple suivant :

# cd /; ln -s / public_html
puis accès à http://localhost/~root/

Ceci permettrait aux clients de parcourir l'ensemble du système de fichiers. Pour l'éviter, ajoutez le bloc suivant à la configuration de votre serveur :

<Directory "/">
    Require all denied
</Directory>

ceci va interdire l'accès par défaut à tous les fichiers du système de fichiers. Vous devrez ensuite ajouter les blocs Directory appropriés correspondant aux répertoires auxquels vous voulez autorisez l'accès. Par exemple,

<Directory "/usr/users/*/public_html">
    Require all granted
</Directory>
<Directory "/usr/local/httpd">
    Require all granted
</Directory>

Portez une attention particulière aux interactions entre les directives Location et Directory ; par exemple, si une directive <Directory ""/> interdit un accès, une directive <Location "/"> pourra passer outre.

De même, soyez méfiant en jouant avec la directive UserDir ; la positionner à "./" aurait le même effet, pour root, que le premier exemple plus haut. Nous vous conseillons fortement d'inclure la ligne suivante dans le fichier de configuration de votre serveur :

UserDir disabled root
top

Surveillez vos journaux

Pour vous tenir informé de ce qui se passe réellement dans votre serveur, vous devez consulter vos fichiers journaux. Même si les fichiers journaux ne consignent que des évènements qui se sont déjà produits, ils vous informeront sur la nature des attaques qui sont lancées contre le serveur et vous permettront de vérifier si le niveau de sécurité nécessaire est atteint.

Quelques exemples :

grep -c "/jsp/source.jsp?/jsp/ /jsp/source.jsp??" access_log
grep "client denied" error_log | tail -n 10

Le premier exemple listera les attaques essayant d'exploiter la vulnérabilité d'Apache Tomcat pouvant provoquer la divulgation d'informations par des requêtes Source.JSP mal formées, le second donnera la liste des dix dernières interdictions client ; par exemple :

[Thu Jul 11 17:18:39 2002] [error] [client foo.example.com] client denied by server configuration: /usr/local/apache/htdocs/.htpasswd

Comme vous le voyez, les fichiers journaux ne consignent que ce qui s'est déjà produit ; ainsi, si le client a pu accéder au fichier .htpasswd, vous devriez avoir quelque chose du style :

foo.example.com - - [12/Jul/2002:01:59:13 +0200] "GET /.htpasswd HTTP/1.1"

dans votre journal des accès ; ce qui signifie que vous avez probablement mis en commentaire ce qui suit dans le fichier de configuration de votre serveur :

<Files ".ht*">
    Require all denied
</Files>
top

Fusion des sections de configuration

La fusion des sections de configuration est complexe et dépend souvent des directives utilisées. Vous devez systématiquement tester vos modifications pour vérifier la manière dont les directives sont fusionnées.

Concernant les modules qui n'implémentent aucune logique de fusion, comme mod_access_compat, le comportement des sections suivantes est tributaire de la présence dans ces dernières de directives appartenant à ces modules. La configuration est héritée jusqu'à ce qu'une modification soit effectuée ; à ce moment, la configuration est remplacée et non fusionnée.

Langues Disponibles:  en  |  fr  |  ko  |  tr 

top

Commentaires

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/relevant_standards.html.en0000664000175100017510000003021314737241666023153 0ustar covenercovener Relevant Standards - Apache HTTP Server Version 2.4
<-
Apache > HTTP Server > Documentation > Version 2.4 > Miscellaneous Documentation

Relevant Standards

Available Languages:  en  |  fr  |  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.

Support Apache!

See also

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.
RFC 4346 (Standards Track)
The TLS protocol provides communications security over the Internet. It provides encryption, and is designed to prevent eavesdropping, tampering, and message forgery.
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 (Standards Track)
"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  |  fr  |  ko 

top

Comments

Notice:
This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our mailing lists.
httpd-2.4.64/docs/manual/misc/password_encryptions.html0000664000175100017510000000034713710016232023146 0ustar covenercovener# GENERATED FROM XML -- DO NOT EDIT URI: password_encryptions.html.en Content-Language: en Content-type: text/html; charset=UTF-8 URI: password_encryptions.html.fr.utf8 Content-Language: fr Content-type: text/html; charset=UTF-8 httpd-2.4.64/docs/manual/index.html.tr.utf80000664000175100017510000002253314743132254020347 0ustar covenercovener Apache HTTP Sunucusu Sürüm 2.4 Belgeleri - Apache HTTP Sunucusu Sürüm 2.4
<-
Apache > HTTP Sunucusu > Belgeleme

Apache HTTP Sunucusu Sürüm 2.4 Belgeleri

Mevcut Diller:  da  |  de  |  en  |  es  |  fr  |  ja  |  ko  |  pt-br  |  ru  |  tr  |  zh-cn 

Mevcut Diller:  da  |  de  |  en  |  es  |  fr  |  ja  |  ko  |  pt-br  |  ru  |  tr  |  zh-cn 

httpd-2.4.64/docs/manual/style/0000775000175100017510000000000015032766627016205 5ustar covenercovenerhttpd-2.4.64/docs/manual/style/scripts/0000775000175100017510000000000015032766612017666 5ustar covenercovenerhttpd-2.4.64/docs/manual/style/scripts/MINIFY0000664000175100017510000000024712273656627020617 0ustar covenercovener#!/bin/sh (echo '// see prettify.js for copyright, license and expanded version'; python -mrjsmin prettify.min.js # needs python and rjsmin installed httpd-2.4.64/docs/manual/style/scripts/prettify.js0000664000175100017510000022151314737561063022102 0ustar covenercovener// Copyright (C) 2006 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * @fileoverview * some functions for browser-side pretty printing of code contained in html. * *

* For a fairly comprehensive set of languages see the * README * file that came with this source. At a minimum, the lexer should work on a * number of languages including C and friends, Java, Python, Bash, SQL, HTML, * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk * and a subset of Perl, but, because of commenting conventions, doesn't work on * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. *

* Usage:

    *
  1. include this source file in an html page via * {@code } *
  2. define style rules. See the example page for examples. *
  3. mark the {@code
    } and {@code } tags in your source with
     *    {@code class=prettyprint.}
     *    You can also use the (html deprecated) {@code } tag, but the pretty
     *    printer needs to do more substantial DOM manipulations to support that, so
     *    some css styles may not be preserved.
     * </ol>
     * That's it.  I wanted to keep the API as simple as possible, so there's no
     * need to specify which language the code is in, but if you wish, you can add
     * another class to the {@code <pre>} or {@code <code>} element to specify the
     * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
     * starts with "lang-" followed by a file extension, specifies the file type.
     * See the "lang-*.js" files in this directory for code that implements
     * per-language file handlers.
     * <p>
     * Change log:<br>
     * cbeust, 2006/08/22
     * <blockquote>
     *   Java annotations (start with "@") are now captured as literals ("lit")
     * </blockquote>
     * @requires console
     */
    
    // JSLint declarations
    /*global console, document, navigator, setTimeout, window, define */
    
    /**
     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
     * UI events.
     * If set to {@code false}, {@code prettyPrint()} is synchronous.
     */
    window['PR_SHOULD_USE_CONTINUATION'] = true;
    
    /**
     * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
     * {@code class=prettyprint} and prettify them.
     *
     * @param {Function?} opt_whenDone if specified, called when the last entry
     *     has been finished.
     */
    var prettyPrintOne;
    /**
     * Pretty print a chunk of code.
     *
     * @param {string} sourceCodeHtml code as html
     * @return {string} code as html, but prettier
     */
    var prettyPrint;
    
    
    (function () {
      var win = window;
      // Keyword lists for various languages.
      // We use things that coerce to strings to make them compact when minified
      // and to defeat aggressive optimizers that fold large string constants.
      var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
      var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + 
          "double,enum,extern,float,goto,int,long,register,short,signed,sizeof,module," +
          "static,struct,switch,typedef,union,unsigned,void,volatile"];
      var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
          "new,operator,private,protected,public,this,throw,true,try,typeof"];
      var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
          "concept,concept_map,const_cast,constexpr,decltype," +
          "dynamic_cast,explicit,export,friend,inline,late_check," +
          "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
          "template,typeid,typename,using,virtual,where,request_req"];
      var JAVA_KEYWORDS = [COMMON_KEYWORDS,
          "abstract,boolean,byte,extends,final,finally,implements,import," +
          "instanceof,null,native,package,strictfp,super,synchronized,throws," +
          "transient"];
      var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
          "as,base,by,checked,decimal,delegate,descending,dynamic,event," +
          "fixed,foreach,from,group,implicit,in,interface,internal,into,is,let," +
          "lock,object,out,override,orderby,params,partial,readonly,ref,sbyte," +
          "sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort," +
          "var,virtual,where"];
      var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
          "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
          "throw,true,try,unless,until,when,while,yes";
      var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
          "debugger,eval,export,function,get,null,set,undefined,var,with," +
          "Infinity,NaN"];
      var PERL_KEYWORDS = "caller,delete,die,do,dump,else,elsif,eval,exit,foreach,for," +
          "goto,if,import,last,local,my,next,no,our,print,printf,package,redo,require," +
          "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
      var PHP_KEYWORDS = "abstract,and,array,as,break,case,catch,cfunction,class," +
          "clone,const,continue,declare,default,do,else,elseif,enddeclare,endfor," + 
          "endforeach,endif,endswitch,endwhile,extends,final,for,foreach,function," +
          "global,goto,if,implements,interface,instanceof,namespace,new,old_function," +
          "or,private,protected,public,static,switch,throw,try,use,var,while,xor," + 
          "die,echo,empty,exit,eval,include,include_once,isset,list,require," + 
          "require_once,return,print,unset";
      var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
          "elif,except,exec,finally,from,global,import,in,is,lambda," +
          "nonlocal,not,or,pass,print,raise,try,with,yield," +
          "False,True,None"];
      var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
          "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
          "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
          "BEGIN,END"];
      var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
          "function,in,local,set,then,until,echo"];
      var CONFIG_ENVS = ["User-Agent,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,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,REQUEST_SCHEME"];
      var CONFIG_KEYWORDS = ["AcceptFilter,AcceptPathInfo,AccessFileName,Action,AddAlt,AddAltByEncoding,AddAltByType,AddCharset,AddDefaultCharset,AddDescription,AddEncoding,AddHandler,AddIcon,AddIconByEncoding,AddIconByType,AddInputFilter,AddLanguage,AddModuleInfo,AddOutputFilter,AddOutputFilterByType,AddType,Alias,AliasMatch,Allow,AllowCONNECT,AllowEncodedSlashes,AllowMethods,AllowOverride,AllowOverrideList,Anonymous,Anonymous_LogEmail,Anonymous_MustGiveEmail,Anonymous_NoUserID,Anonymous_VerifyEmail,AsyncRequestWorkerFactor,AuthBasicAuthoritative,AuthBasicFake,AuthBasicProvider,AuthBasicUseDigestAlgorithm,AuthDBDUserPWQuery,AuthDBDUserRealmQuery,AuthDBMGroupFile,AuthDBMType,AuthDBMUserFile,AuthDigestAlgorithm,AuthDigestDomain,AuthDigestNonceLifetime,AuthDigestProvider,AuthDigestQop,AuthDigestShmemSize,AuthFormAuthoritative,AuthFormBody,AuthFormDisableNoStore,AuthFormFakeBasicAuth,AuthFormLocation,AuthFormLoginRequiredLocation,AuthFormLoginSuccessLocation,AuthFormLogoutLocation,AuthFormMethod,AuthFormMimetype,AuthFormPassword,AuthFormProvider,AuthFormSitePassphrase,AuthFormSize,AuthFormUsername,AuthGroupFile,AuthLDAPAuthorizePrefix,AuthLDAPBindAuthoritative,AuthLDAPBindDN,AuthLDAPBindPassword,AuthLDAPCharsetConfig,AuthLDAPCompareAsUser,AuthLDAPCompareDNOnServer,AuthLDAPDereferenceAliases,AuthLDAPGroupAttribute,AuthLDAPGroupAttributeIsDN,AuthLDAPInitialBindAsUser,AuthLDAPInitialBindPattern,AuthLDAPMaxSubGroupDepth,AuthLDAPRemoteUserAttribute,AuthLDAPRemoteUserIsDN,AuthLDAPSearchAsUser,AuthLDAPSubGroupAttribute,AuthLDAPSubGroupClass,AuthLDAPURL,AuthMerging,AuthName,AuthnCacheContext,AuthnCacheEnable,AuthnCacheProvideFor,AuthnCacheSOCache,AuthnCacheTimeout,<AuthnProviderAlias>,AuthnzFcgiCheckAuthnProvider,AuthnzFcgiDefineProvider,AuthType,AuthUserFile,AuthzDBDLoginToReferer,AuthzDBDQuery,AuthzDBDRedirectQuery,AuthzDBMType,<AuthzProviderAlias>,AuthzSendForbiddenOnFailure,BalancerGrowth,BalancerInherit,BalancerMember,BalancerPersist,BrotliAlterETag,BrotliCompressionMaxInputBlock,BrotliCompressionQuality,BrotliCompressionWindow,BrotliFilterNote,BrowserMatch,BrowserMatchNoCase,BufferedLogs,BufferSize,CacheDefaultExpire,CacheDetailHeader,CacheDirLength,CacheDirLevels,CacheDisable,CacheEnable,CacheFile,CacheHeader,CacheIgnoreCacheControl,CacheIgnoreHeaders,CacheIgnoreNoLastMod,CacheIgnoreQueryString,CacheIgnoreURLSessionIdentifiers,CacheKeyBaseURL,CacheLastModifiedFactor,CacheLock,CacheLockMaxAge,CacheLockPath,CacheMaxExpire,CacheMaxFileSize,CacheMinExpire,CacheMinFileSize,CacheNegotiatedDocs,CacheQuickHandler,CacheReadSize,CacheReadTime,CacheRoot,CacheSocache,CacheSocacheMaxSize,CacheSocacheMaxTime,CacheSocacheMinTime,CacheSocacheReadSize,CacheSocacheReadTime,CacheStaleOnError,CacheStoreExpired,CacheStoreNoStore,CacheStorePrivate,CGIDScriptTimeout,CGIMapExtension,CGIPassAuth,CGIScriptTimeout,CGIVar,CharsetDefault,CharsetOptions,CharsetSourceEnc,CheckBasenameMatch,CheckCaseOnly,CheckSpelling,ChrootDir,ContentDigest,CookieDomain,CookieExpires,CookieHTTPOnly,CookieName,CookieSameSite,CookieSecure,CookieStyle,CookieTracking,CoreDumpDirectory,CustomLog,Dav,DavBasePath,DavDepthInfinity,DavGenericLockDB,DavLockDB,DavLockDiscovery,DavMinTimeout,DBDExptime,DBDInitSQL,DBDKeep,DBDMax,DBDMin,DBDParams,DBDPersist,DBDPrepareSQL,DBDriver,DefaultIcon,DefaultLanguage,DefaultRuntimeDir,DefaultType,Define,DeflateAlterETag,DeflateBufferSize,DeflateCompressionLevel,DeflateFilterNote,DeflateInflateLimitRequestBody,DeflateInflateRatioBurst,DeflateInflateRatioLimit,DeflateMemLevel,DeflateWindowSize,Deny,<Directory>,DirectoryCheckHandler,DirectoryIndex,DirectoryIndexRedirect,<DirectoryMatch>,DirectorySlash,DocumentRoot,DTracePrivileges,DumpIOInput,DumpIOOutput,<Else>,<ElseIf>,EnableExceptionHook,EnableMMAP,EnableSendfile,Error,ErrorDocument,ErrorLog,ErrorLogFormat,Example,ExpiresActive,ExpiresByType,ExpiresDefault,ExtendedStatus,ExtFilterDefine,ExtFilterOptions,FallbackResource,FileETag,<Files>,<FilesMatch>,FilterChain,FilterDeclare,FilterProtocol,FilterProvider,FilterTrace,FlushMaxPipelined,FlushMaxThreshold,ForceLanguagePriority,ForceType,ForensicLog,GlobalLog,GprofDir,GracefulShutdownTimeout,Group,H2CopyFiles,H2Direct,H2EarlyHint,H2EarlyHints,H2MaxDataFrameLen,H2MaxSessionStreams,H2MaxWorkerIdleSeconds,H2MaxWorkers,H2MinWorkers,H2ModernTLSOnly,H2OutputBuffering,H2Padding,H2ProxyRequests,H2Push,H2PushDiarySize,H2PushPriority,H2PushResource,H2SerializeHeaders,H2StreamMaxMemSize,H2StreamTimeout,H2TLSCoolDownSecs,H2TLSWarmUpSize,H2Upgrade,H2WebSockets,H2WindowSize,Header,HeaderName,HeartbeatAddress,HeartbeatListen,HeartbeatMaxServers,HeartbeatStorage,HeartbeatStorage,HostnameLookups,HttpProtocolOptions,IdentityCheck,IdentityCheckTimeout,<If>,<IfDefine>,<IfDirective>,<IfFile>,<IfModule>,<IfSection>,<IfVersion>,ImapBase,ImapDefault,ImapMenu,Include,IncludeOptional,IndexHeadInsert,IndexIgnore,IndexIgnoreReset,IndexOptions,IndexOrderDefault,IndexStyleSheet,InputSed,ISAPIAppendLogToErrors,ISAPIAppendLogToQuery,ISAPICacheFile,ISAPIFakeAsync,ISAPILogNotSupported,ISAPIReadAheadBuffer,KeepAlive,KeepAliveTimeout,KeptBodySize,LanguagePriority,LDAPCacheEntries,LDAPCacheTTL,LDAPConnectionPoolTTL,LDAPConnectionTimeout,LDAPLibraryDebug,LDAPOpCacheEntries,LDAPOpCacheTTL,LDAPReferralHopLimit,LDAPReferrals,LDAPRetries,LDAPRetryDelay,LDAPSharedCacheFile,LDAPSharedCacheSize,LDAPTimeout,LDAPTrustedClientCert,LDAPTrustedGlobalCert,LDAPTrustedMode,LDAPVerifyServerCert,<Limit>,<LimitExcept>,LimitInternalRecursion,LimitRequestBody,LimitRequestFields,LimitRequestFieldSize,LimitRequestLine,LimitXMLRequestBody,Listen,ListenBackLog,ListenCoresBucketsRatio,LoadFile,LoadModule,<Location>,<LocationMatch>,LogFormat,LogIOTrackTTFB,LogLevel,LogMessage,LuaAuthzProvider,LuaCodeCache,LuaHookAccessChecker,LuaHookAuthChecker,LuaHookCheckUserID,LuaHookFixups,LuaHookInsertFilter,LuaHookLog,LuaHookMapToStorage,LuaHookPreTranslate,LuaHookTranslateName,LuaHookTypeChecker,LuaInherit,LuaInputFilter,LuaMapHandler,LuaOutputFilter,LuaPackageCPath,LuaPackagePath,LuaQuickHandler,LuaRoot,LuaScope,<Macro>,MaxConnectionsPerChild,MaxKeepAliveRequests,MaxMemFree,MaxRangeOverlaps,MaxRangeReversals,MaxRanges,MaxRequestWorkers,MaxSpareServers,MaxSpareThreads,MaxThreads,MDActivationDelay,MDBaseServer,MDCAChallenges,MDCertificateAgreement,MDCertificateAuthority,MDCertificateCheck,MDCertificateFile,MDCertificateKeyFile,MDCertificateMonitor,MDCertificateProtocol,MDCertificateStatus,MDChallengeDns01,MDChallengeDns01Version,MDContactEmail,MDDriveMode,MDExternalAccountBinding,MDHttpProxy,MDMatchNames,MDMember,MDMembers,MDMessageCmd,MDMustStaple,MDNotifyCmd,MDomain,<MDomainSet>,MDPortMap,MDPrivateKeys,MDRenewMode,MDRenewWindow,MDRequireHttps,MDRetryDelay,MDRetryFailover,MDServerStatus,MDStapleOthers,MDStapling,MDStaplingKeepResponse,MDStaplingRenewWindow,MDStoreDir,MDStoreLocks,MDWarnWindow,MemcacheConnTTL,MergeSlashes,MergeTrailers,MetaDir,MetaFiles,MetaSuffix,MimeMagicFile,MinSpareServers,MinSpareThreads,MMapFile,ModemStandard,ModMimeUsePathInfo,MultiviewsMatch,Mutex,NameVirtualHost,NoProxy,NWSSLTrustedCerts,NWSSLUpgradeable,Options,Order,OutputSed,PassEnv,PidFile,PrivilegesMode,Protocol,ProtocolEcho,Protocols,ProtocolsHonorOrder,<Proxy>,Proxy100Continue,ProxyAddHeaders,ProxyBadHeader,ProxyBlock,ProxyDomain,ProxyErrorOverride,ProxyExpressDBMFile,ProxyExpressDBMType,ProxyExpressEnable,ProxyFCGIBackendType,ProxyFCGISetEnvIf,ProxyFtpDirCharset,ProxyFtpEscapeWildcards,ProxyFtpListOnWildcard,ProxyHCExpr,ProxyHCTemplate,ProxyHCTPsize,ProxyHTMLBufSize,ProxyHTMLCharsetOut,ProxyHTMLDocType,ProxyHTMLEnable,ProxyHTMLEvents,ProxyHTMLExtended,ProxyHTMLFixups,ProxyHTMLInterp,ProxyHTMLLinks,ProxyHTMLMeta,ProxyHTMLStripComments,ProxyHTMLURLMap,ProxyIOBufferSize,<ProxyMatch>,ProxyMaxForwards,ProxyPass,ProxyPassInherit,ProxyPassInterpolateEnv,ProxyPassMatch,ProxyPassReverse,ProxyPassReverseCookieDomain,ProxyPassReverseCookiePath,ProxyPreserveHost,ProxyReceiveBufferSize,ProxyRemote,ProxyRemoteMatch,ProxyRequests,ProxySCGIInternalRedirect,ProxySCGISendfile,ProxySet,ProxySourceAddress,ProxyStatus,ProxyTimeout,ProxyVia,ProxyWebsocketFallbackToProxyHttp,QualifyRedirectURL,ReadBufferSize,ReadmeName,ReceiveBufferSize,Redirect,RedirectMatch,RedirectPermanent,RedirectRelative,RedirectTemp,RedisConnPoolTTL,RedisTimeout,ReflectorHeader,RegexDefaultOptions,RegisterHttpMethod,RemoteIPHeader,RemoteIPInternalProxy,RemoteIPInternalProxyList,RemoteIPProxiesHeader,RemoteIPProxyProtocol,RemoteIPProxyProtocolExceptions,RemoteIPTrustedProxy,RemoteIPTrustedProxyList,RemoveCharset,RemoveEncoding,RemoveHandler,RemoveInputFilter,RemoveLanguage,RemoveOutputFilter,RemoveType,RequestHeader,RequestReadTimeout,Require,<RequireAll>,<RequireAny>,<RequireNone>,RewriteBase,RewriteCond,RewriteEngine,RewriteMap,RewriteOptions,RewriteRule,RLimitCPU,RLimitMEM,RLimitNPROC,Satisfy,ScoreBoardFile,Script,ScriptAlias,ScriptAliasMatch,ScriptInterpreterSource,ScriptLog,ScriptLogBuffer,ScriptLogLength,ScriptSock,SecureListen,SeeRequestTail,SendBufferSize,ServerAdmin,ServerAlias,ServerLimit,ServerName,ServerPath,ServerRoot,ServerSignature,ServerTokens,Session,SessionCookieName,SessionCookieName2,SessionCookieRemove,SessionCryptoCipher,SessionCryptoDriver,SessionCryptoPassphrase,SessionCryptoPassphraseFile,SessionDBDCookieName,SessionDBDCookieName2,SessionDBDCookieRemove,SessionDBDDeleteLabel,SessionDBDInsertLabel,SessionDBDPerUser,SessionDBDSelectLabel,SessionDBDUpdateLabel,SessionEnv,SessionExclude,SessionExpiryUpdateInterval,SessionHeader,SessionInclude,SessionMaxAge,SetEnv,SetEnvIf,SetEnvIfExpr,SetEnvIfNoCase,SetHandler,SetInputFilter,SetOutputFilter,SSIEndTag,SSIErrorMsg,SSIETag,SSILastModified,SSILegacyExprParser,SSIStartTag,SSITimeFormat,SSIUndefinedEcho,SSLCACertificateFile,SSLCACertificatePath,SSLCADNRequestFile,SSLCADNRequestPath,SSLCARevocationCheck,SSLCARevocationFile,SSLCARevocationPath,SSLCertificateChainFile,SSLCertificateFile,SSLCertificateKeyFile,SSLCipherSuite,SSLCompression,SSLCryptoDevice,SSLEngine,SSLFIPS,SSLHonorCipherOrder,SSLInsecureRenegotiation,SSLOCSPDefaultResponder,SSLOCSPEnable,SSLOCSPNoverify,SSLOCSPOverrideResponder,SSLOCSPProxyURL,SSLOCSPResponderCertificateFile,SSLOCSPResponderTimeout,SSLOCSPResponseMaxAge,SSLOCSPResponseTimeSkew,SSLOCSPUseRequestNonce,SSLOpenSSLConfCmd,SSLOptions,SSLPassPhraseDialog,SSLProtocol,SSLProxyCACertificateFile,SSLProxyCACertificatePath,SSLProxyCARevocationCheck,SSLProxyCARevocationFile,SSLProxyCARevocationPath,SSLProxyCheckPeerCN,SSLProxyCheckPeerExpire,SSLProxyCheckPeerName,SSLProxyCipherSuite,SSLProxyEngine,SSLProxyMachineCertificateChainFile,SSLProxyMachineCertificateFile,SSLProxyMachineCertificatePath,SSLProxyProtocol,SSLProxyVerify,SSLProxyVerifyDepth,SSLRandomSeed,SSLRenegBufferSize,SSLRequire,SSLRequireSSL,SSLSessionCache,SSLSessionCacheTimeout,SSLSessionTicketKeyFile,SSLSessionTickets,SSLSRPUnknownUserSeed,SSLSRPVerifierFile,SSLStaplingCache,SSLStaplingErrorCacheTimeout,SSLStaplingFakeTryLater,SSLStaplingForceURL,SSLStaplingResponderTimeout,SSLStaplingResponseMaxAge,SSLStaplingResponseTimeSkew,SSLStaplingReturnResponderErrors,SSLStaplingStandardCacheTimeout,SSLStrictSNIVHostCheck,SSLUserName,SSLUseStapling,SSLVerifyClient,SSLVerifyDepth,StartServers,StartThreads,StrictHostCheck,Substitute,SubstituteInheritBefore,SubstituteMaxLineLength,Suexec,SuexecUserGroup,ThreadLimit,ThreadsPerChild,ThreadStackSize,TimeOut,TraceEnable,TransferLog,TypesConfig,UNCList,UnDefine,UndefMacro,UnsetEnv,Use,UseCanonicalName,UseCanonicalPhysicalPort,User,UserDir,VHostCGIMode,VHostCGIPrivs,VHostGroup,VHostPrivs,VHostSecure,VHostUser,VirtualDocumentRoot,VirtualDocumentRootIP,<VirtualHost>,VirtualScriptAlias,VirtualScriptAliasIP,WatchdogInterval,XBitHack,xml2EncAlias,xml2EncDefault,xml2StartParse"];
      var CONFIG_OPTIONS = /^[\\+\\-]?(AuthConfig|IncludesNOEXEC|ExecCGI|FollowSymLinks|MultiViews|Includes|Indexes|SymLinksIfOwnerMatch)\b/i;
      var ALL_KEYWORDS = [
          CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS +
          PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS, CONFIG_KEYWORDS, PHP_KEYWORDS];
      var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float|char|void|const|static|struct)\d*(_t)?\b)|[a-z_]+_rec|cmd_parms\b/;
    
      // token style names.  correspond to css classes
      /**
       * token style for a string literal
       * @const
       */
      var PR_STRING = 'str';
      /**
       * token style for a keyword
       * @const
       */
      var PR_KEYWORD = 'kwd';
      /**
       * token style for a comment
       * @const
       */
      var PR_COMMENT = 'com';
      /**
       * token style for a type
       * @const
       */
      var PR_TYPE = 'typ';
      /**
       * token style for a literal value.  e.g. 1, null, true.
       * @const
       */
      var PR_LITERAL = 'lit';
      /**
       * token style for a punctuation string.
       * @const
       */
      var PR_PUNCTUATION = 'pun';
      /**
       * token style for plain text.
       * @const
       */
      var PR_PLAIN = 'pln';
    
      /**
       * token style for an sgml tag.
       * @const
       */
      var PR_TAG = 'tag';
      /**
       * token style for a markup declaration such as a DOCTYPE.
       * @const
       */
      var PR_DECLARATION = 'dec';
      /**
       * token style for embedded source.
       * @const
       */
      var PR_SOURCE = 'src';
      /**
       * token style for an sgml attribute name.
       * @const
       */
      var PR_ATTRIB_NAME = 'atn';
      /**
       * token style for an sgml attribute value.
       * @const
       */
      var PR_ATTRIB_VALUE = 'atv';
    
      /**
       * A class that indicates a section of markup that is not code, e.g. to allow
       * embedding of line numbers within code listings.
       * @const
       */
      var PR_NOCODE = 'nocode';
    
    
    
    /**
     * A set of tokens that can precede a regular expression literal in
     * javascript
     * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
     * has the full list, but I've removed ones that might be problematic when
     * seen in languages that don't support regular expression literals.
     *
     * <p>Specifically, I've removed any keywords that can't precede a regexp
     * literal in a syntactically legal javascript program, and I've removed the
     * "in" keyword since it's not a keyword in many languages, and might be used
     * as a count of inches.
     *
     * <p>The link above does not accurately describe EcmaScript rules since
     * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
     * very well in practice.
     *
     * @private
     * @const
     */
    var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    
    // CAVEAT: this does not properly handle the case where a regular
    // expression immediately follows another since a regular expression may
    // have flags for case-sensitivity and the like.  Having regexp tokens
    // adjacent is not valid in any language I'm aware of, so I'm punting.
    // TODO: maybe style special characters inside a regexp as punctuation.
    
    
      /**
       * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
       * matches the union of the sets of strings matched by the input RegExp.
       * Since it matches globally, if the input strings have a start-of-input
       * anchor (/^.../), it is ignored for the purposes of unioning.
       * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
       * @return {RegExp} a global regex.
       */
      function combinePrefixPatterns(regexs) {
        var capturedGroupIndex = 0;
      
        var needToFoldCase = false;
        var ignoreCase = false;
        for (var i = 0, n = regexs.length; i < n; ++i) {
          var regex = regexs[i];
          if (regex.ignoreCase) {
            ignoreCase = true;
          } else if (/[a-z]/i.test(regex.source.replace(
                         /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
            needToFoldCase = true;
            ignoreCase = false;
            break;
          }
        }
      
        var escapeCharToCodeUnit = {
          'b': 8,
          't': 9,
          'n': 0xa,
          'v': 0xb,
          'f': 0xc,
          'r': 0xd
        };
      
        function decodeEscape(charsetPart) {
          var cc0 = charsetPart.charCodeAt(0);
          if (cc0 !== 92 /* \\ */) {
            return cc0;
          }
          var c1 = charsetPart.charAt(1);
          cc0 = escapeCharToCodeUnit[c1];
          if (cc0) {
            return cc0;
          } else if ('0' <= c1 && c1 <= '7') {
            return parseInt(charsetPart.substring(1), 8);
          } else if (c1 === 'u' || c1 === 'x') {
            return parseInt(charsetPart.substring(2), 16);
          } else {
            return charsetPart.charCodeAt(1);
          }
        }
      
        function encodeEscape(charCode) {
          if (charCode < 0x20) {
            return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
          }
          var ch = String.fromCharCode(charCode);
          return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
              ? "\\" + ch : ch;
        }
      
        function caseFoldCharset(charSet) {
          var charsetParts = charSet.substring(1, charSet.length - 1).match(
              new RegExp(
                  '\\\\u[0-9A-Fa-f]{4}'
                  + '|\\\\x[0-9A-Fa-f]{2}'
                  + '|\\\\[0-3][0-7]{0,2}'
                  + '|\\\\[0-7]{1,2}'
                  + '|\\\\[\\s\\S]'
                  + '|-'
                  + '|[^-\\\\]',
                  'g'));
          var ranges = [];
          var inverse = charsetParts[0] === '^';
      
          var out = ['['];
          if (inverse) { out.push('^'); }
      
          for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
            var p = charsetParts[i];
            if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
              out.push(p);
            } else {
              var start = decodeEscape(p);
              var end;
              if (i + 2 < n && '-' === charsetParts[i + 1]) {
                end = decodeEscape(charsetParts[i + 2]);
                i += 2;
              } else {
                end = start;
              }
              ranges.push([start, end]);
              // If the range might intersect letters, then expand it.
              // This case handling is too simplistic.
              // It does not deal with non-latin case folding.
              // It works for latin source code identifiers though.
              if (!(end < 65 || start > 122)) {
                if (!(end < 65 || start > 90)) {
                  ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
                }
                if (!(end < 97 || start > 122)) {
                  ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
                }
              }
            }
          }
      
          // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
          // -> [[1, 12], [14, 14], [16, 17]]
          ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
          var consolidatedRanges = [];
          var lastRange = [];
          for (var i = 0; i < ranges.length; ++i) {
            var range = ranges[i];
            if (range[0] <= lastRange[1] + 1) {
              lastRange[1] = Math.max(lastRange[1], range[1]);
            } else {
              consolidatedRanges.push(lastRange = range);
            }
          }
      
          for (var i = 0; i < consolidatedRanges.length; ++i) {
            var range = consolidatedRanges[i];
            out.push(encodeEscape(range[0]));
            if (range[1] > range[0]) {
              if (range[1] + 1 > range[0]) { out.push('-'); }
              out.push(encodeEscape(range[1]));
            }
          }
          out.push(']');
          return out.join('');
        }
      
        function allowAnywhereFoldCaseAndRenumberGroups(regex) {
          // Split into character sets, escape sequences, punctuation strings
          // like ('(', '(?:', ')', '^'), and runs of characters that do not
          // include any of the above.
          var parts = regex.source.match(
              new RegExp(
                  '(?:'
                  + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
                  + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
                  + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
                  + '|\\\\[0-9]+'  // a back-reference or octal escape
                  + '|\\\\[^ux0-9]'  // other escape sequence
                  + '|\\(\\?[:!=]'  // start of a non-capturing group
                  + '|[\\(\\)\\^]'  // start/end of a group, or line start
                  + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
                  + ')',
                  'g'));
          var n = parts.length;
      
          // Maps captured group numbers to the number they will occupy in
          // the output or to -1 if that has not been determined, or to
          // undefined if they need not be capturing in the output.
          var capturedGroups = [];
      
          // Walk over and identify back references to build the capturedGroups
          // mapping.
          for (var i = 0, groupIndex = 0; i < n; ++i) {
            var p = parts[i];
            if (p === '(') {
              // groups are 1-indexed, so max group index is count of '('
              ++groupIndex;
            } else if ('\\' === p.charAt(0)) {
              var decimalValue = +p.substring(1);
              if (decimalValue) {
                if (decimalValue <= groupIndex) {
                  capturedGroups[decimalValue] = -1;
                } else {
                  // Replace with an unambiguous escape sequence so that
                  // an octal escape sequence does not turn into a backreference
                  // to a capturing group from an earlier regex.
                  parts[i] = encodeEscape(decimalValue);
                }
              }
            }
          }
      
          // Renumber groups and reduce capturing groups to non-capturing groups
          // where possible.
          for (var i = 1; i < capturedGroups.length; ++i) {
            if (-1 === capturedGroups[i]) {
              capturedGroups[i] = ++capturedGroupIndex;
            }
          }
          for (var i = 0, groupIndex = 0; i < n; ++i) {
            var p = parts[i];
            if (p === '(') {
              ++groupIndex;
              if (!capturedGroups[groupIndex]) {
                parts[i] = '(?:';
              }
            } else if ('\\' === p.charAt(0)) {
              var decimalValue = +p.substring(1);
              if (decimalValue && decimalValue <= groupIndex) {
                parts[i] = '\\' + capturedGroups[decimalValue];
              }
            }
          }
      
          // Remove any prefix anchors so that the output will match anywhere.
          // ^^ really does mean an anchored match though.
          for (var i = 0; i < n; ++i) {
            if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
          }
      
          // Expand letters to groups to handle mixing of case-sensitive and
          // case-insensitive patterns if necessary.
          if (regex.ignoreCase && needToFoldCase) {
            for (var i = 0; i < n; ++i) {
              var p = parts[i];
              var ch0 = p.charAt(0);
              if (p.length >= 2 && ch0 === '[') {
                parts[i] = caseFoldCharset(p);
              } else if (ch0 !== '\\') {
                // TODO: handle letters in numeric escapes.
                parts[i] = p.replace(
                    /[a-zA-Z]/g,
                    function (ch) {
                      var cc = ch.charCodeAt(0);
                      return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
                    });
              }
            }
          }
      
          return parts.join('');
        }
      
        var rewritten = [];
        for (var i = 0, n = regexs.length; i < n; ++i) {
          var regex = regexs[i];
          if (regex.global || regex.multiline) { throw new Error('' + regex); }
          rewritten.push(
              '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
        }
      
        return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
      }
    
    
      /**
       * Split markup into a string of source code and an array mapping ranges in
       * that string to the text nodes in which they appear.
       *
       * <p>
       * The HTML DOM structure:</p>
       * <pre>
       * (Element   "p"
       *   (Element "b"
       *     (Text  "print "))       ; #1
       *   (Text    "'Hello '")      ; #2
       *   (Element "br")            ; #3
       *   (Text    "  + 'World';")) ; #4
       * </pre>
       * <p>
       * corresponds to the HTML
       * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
       *
       * <p>
       * It will produce the output:</p>
       * <pre>
       * {
       *   sourceCode: "print 'Hello '\n  + 'World';",
       *   //                     1          2
       *   //           012345678901234 5678901234567
       *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
       * }
       * </pre>
       * <p>
       * where #1 is a reference to the {@code "print "} text node above, and so
       * on for the other text nodes.
       * </p>
       *
       * <p>
       * The {@code} spans array is an array of pairs.  Even elements are the start
       * indices of substrings, and odd elements are the text nodes (or BR elements)
       * that contain the text for those substrings.
       * Substrings continue until the next index or the end of the source.
       * </p>
       *
       * @param {Node} node an HTML DOM subtree containing source-code.
       * @param {boolean} isPreformatted true if white-space in text nodes should
       *    be considered significant.
       * @return {Object} source code and the text nodes in which they occur.
       */
      function extractSourceSpans(node, isPreformatted) {
        var nocode = /(?:^|\s)nocode(?:\s|$)/;
      
        var chunks = [];
        var length = 0;
        var spans = [];
        var k = 0;
      
        function walk(node) {
          switch (node.nodeType) {
            case 1:  // Element
              if (nocode.test(node.className)) { return; }
              for (var child = node.firstChild; child; child = child.nextSibling) {
                walk(child);
              }
              var nodeName = node.nodeName.toLowerCase();
              if ('br' === nodeName || 'li' === nodeName) {
                chunks[k] = '\n';
                spans[k << 1] = length++;
                spans[(k++ << 1) | 1] = node;
              }
              break;
            case 3: case 4:  // Text
              var text = node.nodeValue;
              if (text.length) {
                if (!isPreformatted) {
                  text = text.replace(/[ \t\r\n]+/g, ' ');
                } else {
                  text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
                  text = text.replace(/^(\r?\n\s*)+/g, '');  // Remove leading newlines
                  text = text.replace(/^\s*/g, '');  // Remove leading spaces due to indented formatting
                  text = text.replace(/(\r?\n\s*)+$/g, '');  // Remove ending newlines
                  
                }
                // TODO: handle tabs here?
                chunks[k] = text;
                spans[k << 1] = length;
                length += text.length;
                spans[(k++ << 1) | 1] = node;
              }
              break;
          }
        }
      
        walk(node);
      
        return {
          sourceCode: chunks.join('').replace(/\n$/, ''),
          spans: spans
        };
      }
    
    
      /**
       * Apply the given language handler to sourceCode and add the resulting
       * decorations to out.
       * @param {number} basePos the index of sourceCode within the chunk of source
       *    whose decorations are already present on out.
       */
      function appendDecorations(basePos, sourceCode, langHandler, out) {
        if (!sourceCode) { return; }
        var job = {
          sourceCode: sourceCode,
          basePos: basePos
        };
        langHandler(job);
        out.push.apply(out, job.decorations);
      }
    
      var notWs = /\S/;
    
      /**
       * Given an element, if it contains only one child element and any text nodes
       * it contains contain only space characters, return the sole child element.
       * Otherwise returns undefined.
       * <p>
       * This is meant to return the CODE element in {@code <pre><code ...>} when
       * there is a single child element that contains all the non-space textual
       * content, but not to return anything where there are multiple child elements
       * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
       * is textual content.
       */
      function childContentWrapper(element) {
        var wrapper = undefined;
        for (var c = element.firstChild; c; c = c.nextSibling) {
          var type = c.nodeType;
          wrapper = (type === 1)  // Element Node
              ? (wrapper ? element : c)
              : (type === 3)  // Text Node
              ? (notWs.test(c.nodeValue) ? element : wrapper)
              : wrapper;
        }
        return wrapper === element ? undefined : wrapper;
      }
    
      /** Given triples of [style, pattern, context] returns a lexing function,
        * The lexing function interprets the patterns to find token boundaries and
        * returns a decoration list of the form
        * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
        * where index_n is an index into the sourceCode, and style_n is a style
        * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
        * all characters in sourceCode[index_n-1:index_n].
        *
        * The stylePatterns is a list whose elements have the form
        * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
        *
        * Style is a style constant like PR_PLAIN, or can be a string of the
        * form 'lang-FOO', where FOO is a language extension describing the
        * language of the portion of the token in $1 after pattern executes.
        * E.g., if style is 'lang-lisp', and group 1 contains the text
        * '(hello (world))', then that portion of the token will be passed to the
        * registered lisp handler for formatting.
        * The text before and after group 1 will be restyled using this decorator
        * so decorators should take care that this doesn't result in infinite
        * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
        * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
        * '<script>foo()<\/script>', which would cause the current decorator to
        * be called with '<script>' which would not match the same rule since
        * group 1 must not be empty, so it would be instead styled as PR_TAG by
        * the generic tag rule.  The handler registered for the 'js' extension would
        * then be called with 'foo()', and finally, the current decorator would
        * be called with '<\/script>' which would not match the original rule and
        * so the generic tag rule would identify it as a tag.
        *
        * Pattern must only match prefixes, and if it matches a prefix, then that
        * match is considered a token with the same style.
        *
        * Context is applied to the last non-whitespace, non-comment token
        * recognized.
        *
        * Shortcut is an optional string of characters, any of which, if the first
        * character, guarantee that this pattern and only this pattern matches.
        *
        * @param {Array} shortcutStylePatterns patterns that always start with
        *   a known character.  Must have a shortcut string.
        * @param {Array} fallthroughStylePatterns patterns that will be tried in
        *   order if the shortcut ones fail.  May have shortcuts.
        *
        * @return {function (Object)} a
        *   function that takes source code and returns a list of decorations.
        */
      function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
        var shortcuts = {};
        var tokenizer;
        (function () {
          var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
          var allRegexs = [];
          var regexKeys = {};
          for (var i = 0, n = allPatterns.length; i < n; ++i) {
            var patternParts = allPatterns[i];
            var shortcutChars = patternParts[3];
            if (shortcutChars) {
              for (var c = shortcutChars.length; --c >= 0;) {
                shortcuts[shortcutChars.charAt(c)] = patternParts;
              }
            }
            var regex = patternParts[1];
            var k = '' + regex;
            if (!regexKeys.hasOwnProperty(k)) {
              allRegexs.push(regex);
              regexKeys[k] = null;
            }
          }
          allRegexs.push(/[\0-\uffff]/);
          tokenizer = combinePrefixPatterns(allRegexs);
        })();
    
        var nPatterns = fallthroughStylePatterns.length;
    
        /**
         * Lexes job.sourceCode and produces an output array job.decorations of
         * style classes preceded by the position at which they start in
         * job.sourceCode in order.
         *
         * @param {Object} job an object like <pre>{
         *    sourceCode: {string} sourceText plain text,
         *    basePos: {int} position of job.sourceCode in the larger chunk of
         *        sourceCode.
         * }</pre>
         */
        var decorate = function (job) {
          var sourceCode = job.sourceCode, basePos = job.basePos;
          /** Even entries are positions in source in ascending order.  Odd enties
            * are style markers (e.g., PR_COMMENT) that run from that position until
            * the end.
            * @type {Array.<number|string>}
            */
          var decorations = [basePos, PR_PLAIN];
          var pos = 0;  // index into sourceCode
          var tokens = sourceCode.match(tokenizer) || [];
          var styleCache = {};
    
          for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
            var token = tokens[ti];
            var style = styleCache[token];
            var match = void 0;
    
            var isEmbedded;
            if (typeof style === 'string') {
              isEmbedded = false;
            } else {
              var patternParts = shortcuts[token.charAt(0)];
              if (patternParts) {
                match = token.match(patternParts[1]);
                style = patternParts[0];
              } else {
                for (var i = 0; i < nPatterns; ++i) {
                  patternParts = fallthroughStylePatterns[i];
                  match = token.match(patternParts[1]);
                  if (match) {
                    style = patternParts[0];
                    break;
                  }
                }
    
                if (!match) {  // make sure that we make progress
                  style = PR_PLAIN;
                }
              }
    
              isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
              if (isEmbedded && !(match && typeof match[1] === 'string')) {
                isEmbedded = false;
                style = PR_SOURCE;
              }
    
              if (!isEmbedded) { styleCache[token] = style; }
            }
    
            var tokenStart = pos;
            pos += token.length;
    
            if (!isEmbedded) {
              decorations.push(basePos + tokenStart, style);
            } else {  // Treat group 1 as an embedded block of source code.
              var embeddedSource = match[1];
              var embeddedSourceStart = token.indexOf(embeddedSource);
              var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
              if (match[2]) {
                // If embeddedSource can be blank, then it would match at the
                // beginning which would cause us to infinitely recurse on the
                // entire token, so we catch the right context in match[2].
                embeddedSourceEnd = token.length - match[2].length;
                embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
              }
              var lang = style.substring(5);
              // Decorate the left of the embedded source
              appendDecorations(
                  basePos + tokenStart,
                  token.substring(0, embeddedSourceStart),
                  decorate, decorations);
              // Decorate the embedded source
              appendDecorations(
                  basePos + tokenStart + embeddedSourceStart,
                  embeddedSource,
                  langHandlerForExtension(lang, embeddedSource),
                  decorations);
              // Decorate the right of the embedded section
              appendDecorations(
                  basePos + tokenStart + embeddedSourceEnd,
                  token.substring(embeddedSourceEnd),
                  decorate, decorations);
            }
          }
          job.decorations = decorations;
        };
        return decorate;
      }
    
      /** returns a function that produces a list of decorations from source text.
        *
        * This code treats ", ', and ` as string delimiters, and \ as a string
        * escape.  It does not recognize perl's qq() style strings.
        * It has no special handling for double delimiter escapes as in basic, or
        * the tripled delimiters used in python, but should work on those regardless
        * although in those cases a single string literal may be broken up into
        * multiple adjacent string literals.
        *
        * It recognizes C, C++, and shell style comments.
        *
        * @param {Object} options a set of optional parameters.
        * @return {function (Object)} a function that examines the source code
        *     in the input job and builds the decoration list.
        */
      function sourceDecorator(options) {
        var shortcutStylePatterns = [], fallthroughStylePatterns = [];
        if (options['tripleQuotedStrings']) {
          // '''multi-line-string''', 'single-line-string', and double-quoted
          shortcutStylePatterns.push(
              [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
               null, '\'"']);
        } else if (options['multiLineStrings']) {
          // 'multi-line-string', "multi-line-string"
          shortcutStylePatterns.push(
              [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
               null, '\'"`']);
        } else {
          // 'single-line-string', "single-line-string"
          shortcutStylePatterns.push(
              [PR_STRING,
               /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
               null, '"\'']);
        }
        if (options['verbatimStrings']) {
          // verbatim-string-literal production from the C# grammar.  See issue 93.
          fallthroughStylePatterns.push(
              [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
        }
        var hc = options['hashComments'];
        if (hc) {
          if (options['cStyleComments']) {
            if (hc > 1) {  // multiline hash comments
              shortcutStylePatterns.push(
                  [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
            } else {
              // Stop C preprocessor declarations at an unclosed open comment
              shortcutStylePatterns.push(
                  [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
                   null, '#']);
            }
            // #include <stdio.h>
            fallthroughStylePatterns.push(
                [PR_STRING,
                 /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
                 null]);
          } else {
            shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
          }
        }
        if (options['cStyleComments']) {
          fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
          fallthroughStylePatterns.push(
              [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
        }
        if (options['regexLiterals']) {
          /**
           * @const
           */
          var REGEX_LITERAL = (
              // A regular expression literal starts with a slash that is
              // not followed by * or / so that it is not confused with
              // comments.
              '/(?=[^/*])'
              // and then contains any number of raw characters,
              + '(?:[^/\\x5B\\x5C]'
              // escape sequences (\x5C),
              +    '|\\x5C[\\s\\S]'
              // or non-nesting character sets (\x5B\x5D);
              +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
              // finally closed by a /.
              + '/');
          fallthroughStylePatterns.push(
              ['lang-regex',
               new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
               ]);
        }
    
        var types = options['types'];
        if (types) {
          fallthroughStylePatterns.push([PR_TYPE, types]);
        }
    
        if (options['strings']) {
            var strings = ("" + options['strings']).replace(/^ | $/g, '').replace(/-/g, '\\-');
            fallthroughStylePatterns.push(
                [PR_STRING,
                new RegExp('(?:' + strings.replace(/[\s,]+/g, '|') + ')'),
                , null]
            );
        }
        
        var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
        if (keywords.length) {
          fallthroughStylePatterns.push(
              [PR_KEYWORD,
               new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
               null]);
        }
    
        shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
        if (options['httpdComments']) {
            fallthroughStylePatterns.push(
                [PR_PLAIN,     /^.*\S.*#/i, null]
            );
        }
        
        fallthroughStylePatterns.push(
            // TODO(mikesamuel): recognize non-latin letters and numerals in idents
            [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*|\bNULL\b/i, null],
            [PR_LITERAL,     CONFIG_OPTIONS, null],
            //[PR_STRING,     CONFIG_ENVS, null],
            [PR_TAG,     /^\b(AuthnProviderAlias|AuthzProviderAlias|Directory|DirectoryMatch|Else|ElseIf|Files|FilesMatch|If|IfDefine|IfDirective|IfFile|IfModule|IfSection|IfVersion|Limit|LimitExcept|Location|LocationMatch|Macro|MDomainSet|Proxy|ProxyMatch|RequireAll|RequireAny|RequireNone|VirtualHost)\b/, null],
            [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_(t|req|module)\b)/, null],
            [PR_TAG,     /^apr_[a-z_0-9]+|ap_[a-z_0-9]+/i, null],
            [PR_PLAIN,       /^[a-z_$][a-z_$@0-9\-]*/i, null],
            [PR_LITERAL,
             new RegExp(
                 '^(?:'
                 // A hex number
                 + '0x[a-f0-9]+'
                 // An IPv6 Address
                 + '|[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+'
                 // or an octal or decimal number,
                 + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
                 // possibly in scientific notation
                 + '(?:e[+\\-]?\\d+)?'
                 + ')'
                 // with an optional modifier like UL for unsigned long
                 + '[a-z]*', 'i'),
             null, '0123456789'],
            // Don't treat escaped quotes in bash as starting strings.  See issue 144.
            [PR_PLAIN,       /^\\[\s\S]?/, null],
            [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]);
    
        return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
      }
    
      var decorateSource = sourceDecorator({
            'keywords': ALL_KEYWORDS,
            'hashComments': true,
            'cStyleComments': true,
            'multiLineStrings': true,
            'regexLiterals': true
          });
    
      /**
       * Given a DOM subtree, wraps it in a list, and puts each line into its own
       * list item.
       *
       * @param {Node} node modified in place.  Its content is pulled into an
       *     HTMLOListElement, and each line is moved into a separate list item.
       *     This requires cloning elements, so the input might not have unique
       *     IDs after numbering.
       * @param {boolean} isPreformatted true iff white-space in text nodes should
       *     be treated as significant.
       */
      function numberLines(node, opt_startLineNum, isPreformatted) {
        var nocode = /(?:^|\s)nocode(?:\s|$)/;
        var lineBreak = /\r\n?|\n/;
      
        var document = node.ownerDocument;
      
        var li = document.createElement('li');
        while (node.firstChild) {
          li.appendChild(node.firstChild);
        }
        // An array of lines.  We split below, so this is initialized to one
        // un-split line.
        var listItems = [li];
      
        function walk(node) {
          switch (node.nodeType) {
            case 1:  // Element
              if (nocode.test(node.className)) { break; }
              if ('br' === node.nodeName) {
                breakAfter(node);
                // Discard the <BR> since it is now flush against a </LI>.
                if (node.parentNode) {
                  node.parentNode.removeChild(node);
                }
              } else {
                for (var child = node.firstChild; child; child = child.nextSibling) {
                  walk(child);
                }
              }
              break;
            case 3: case 4:  // Text
              if (isPreformatted) {
                var text = node.nodeValue;
                var match = text.match(lineBreak);
                if (match) {
                  var firstLine = text.substring(0, match.index);
                  node.nodeValue = firstLine;
                  var tail = text.substring(match.index + match[0].length);
                  if (tail) {
                    var parent = node.parentNode;
                    parent.insertBefore(
                        document.createTextNode(tail), node.nextSibling);
                  }
                  breakAfter(node);
                  if (!firstLine) {
                    // Don't leave blank text nodes in the DOM.
                    node.parentNode.removeChild(node);
                  }
                }
              }
              break;
          }
        }
      
        // Split a line after the given node.
        function breakAfter(lineEndNode) {
          // If there's nothing to the right, then we can skip ending the line
          // here, and move root-wards since splitting just before an end-tag
          // would require us to create a bunch of empty copies.
          while (!lineEndNode.nextSibling) {
            lineEndNode = lineEndNode.parentNode;
            if (!lineEndNode) { return; }
          }
      
          function breakLeftOf(limit, copy) {
            // Clone shallowly if this node needs to be on both sides of the break.
            var rightSide = copy ? limit.cloneNode(false) : limit;
            var parent = limit.parentNode;
            if (parent) {
              // We clone the parent chain.
              // This helps us resurrect important styling elements that cross lines.
              // E.g. in <i>Foo<br>Bar</i>
              // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
              var parentClone = breakLeftOf(parent, 1);
              // Move the clone and everything to the right of the original
              // onto the cloned parent.
              var next = limit.nextSibling;
              parentClone.appendChild(rightSide);
              for (var sibling = next; sibling; sibling = next) {
                next = sibling.nextSibling;
                parentClone.appendChild(sibling);
              }
            }
            return rightSide;
          }
      
          var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
      
          // Walk the parent chain until we reach an unattached LI.
          for (var parent;
               // Check nodeType since IE invents document fragments.
               (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
            copiedListItem = parent;
          }
          // Put it on the list of lines for later processing.
          listItems.push(copiedListItem);
        }
      
        // Split lines while there are lines left to split.
        for (var i = 0;  // Number of lines that have been split so far.
             i < listItems.length;  // length updated by breakAfter calls.
             ++i) {
          walk(listItems[i]);
        }
      
        // Make sure numeric indices show correctly.
        if (opt_startLineNum === (opt_startLineNum|0)) {
          listItems[0].setAttribute('value', opt_startLineNum);
        }
      
        var ol = document.createElement('ol');
        ol.className = 'linenums';
        var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
        for (var i = 0, n = listItems.length; i < n; ++i) {
          li = listItems[i];
          // Stick a class on the LIs so that stylesheets can
          // color odd/even rows, or any other row pattern that
          // is co-prime with 10.
          li.className = 'L' + ((i + offset) % 1);
          if (!li.firstChild) {
            li.appendChild(document.createTextNode('\xA0'));
          }
          ol.appendChild(li);
        }
      
        node.appendChild(ol);
      }
    
      /**
       * Breaks {@code job.sourceCode} around style boundaries in
       * {@code job.decorations} and modifies {@code job.sourceNode} in place.
       * @param {Object} job like <pre>{
       *    sourceCode: {string} source as plain text,
       *    spans: {Array.<number|Node>} alternating span start indices into source
       *       and the text node or element (e.g. {@code <BR>}) corresponding to that
       *       span.
       *    decorations: {Array.<number|string} an array of style classes preceded
       *       by the position at which they start in job.sourceCode in order
       * }</pre>
       * @private
       */
      function recombineTagsAndDecorations(job) {
        var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
        isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
        var newlineRe = /\n/g;
      
        var source = job.sourceCode;
        var sourceLength = source.length;
        // Index into source after the last code-unit recombined.
        var sourceIndex = 0;
      
        var spans = job.spans;
        var nSpans = spans.length;
        // Index into spans after the last span which ends at or before sourceIndex.
        var spanIndex = 0;
      
        var decorations = job.decorations;
        var nDecorations = decorations.length;
        // Index into decorations after the last decoration which ends at or before
        // sourceIndex.
        var decorationIndex = 0;
      
        // Remove all zero-length decorations.
        decorations[nDecorations] = sourceLength;
        var decPos, i;
        for (i = decPos = 0; i < nDecorations;) {
          if (decorations[i] !== decorations[i + 2]) {
            decorations[decPos++] = decorations[i++];
            decorations[decPos++] = decorations[i++];
          } else {
            i += 2;
          }
        }
        nDecorations = decPos;
      
        // Simplify decorations.
        for (i = decPos = 0; i < nDecorations;) {
          var startPos = decorations[i];
          // Conflate all adjacent decorations that use the same style.
          var startDec = decorations[i + 1];
          var end = i + 2;
          while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
            end += 2;
          }
          decorations[decPos++] = startPos;
          decorations[decPos++] = startDec;
          i = end;
        }
      
        nDecorations = decorations.length = decPos;
      
        var sourceNode = job.sourceNode;
        var oldDisplay;
        if (sourceNode) {
          oldDisplay = sourceNode.style.display;
          sourceNode.style.display = 'none';
        }
        try {
          var decoration = null;
          var X = 0;
          while (spanIndex < nSpans) {
            X = X + 1;
            if (X > 5000) { break; }
            var spanStart = spans[spanIndex];
            var spanEnd = spans[spanIndex + 2] || sourceLength;
      
            var decEnd = decorations[decorationIndex + 2] || sourceLength;
      
            var end = Math.min(spanEnd, decEnd);
      
            var textNode = spans[spanIndex + 1];
            var styledText;
            if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
                // Don't introduce spans around empty text nodes.
                && (styledText = source.substring(sourceIndex, end))) {
              // This may seem bizarre, and it is.  Emitting LF on IE causes the
              // code to display with spaces instead of line breaks.
              // Emitting Windows standard issue linebreaks (CRLF) causes a blank
              // space to appear at the beginning of every line but the first.
              // Emitting an old Mac OS 9 line separator makes everything spiffy.
              if (isIE8OrEarlier) {
                styledText = styledText.replace(newlineRe, '\r');
              }
              textNode.nodeValue = styledText;
              var document = textNode.ownerDocument;
              var span = document.createElement('span');
              span.className = decorations[decorationIndex + 1];
              var parentNode = textNode.parentNode;
              parentNode.replaceChild(span, textNode);
              span.appendChild(textNode);
              if (sourceIndex < spanEnd) {  // Split off a text node.
                spans[spanIndex + 1] = textNode
                    // TODO: Possibly optimize by using '' if there's no flicker.
                    = document.createTextNode(source.substring(end, spanEnd));
                parentNode.insertBefore(textNode, span.nextSibling);
              }
            }
      
            sourceIndex = end;
      
            if (sourceIndex >= spanEnd) {
              spanIndex += 2;
            }
            if (sourceIndex >= decEnd) {
              decorationIndex += 2;
            }
          }
        } finally {
          if (sourceNode) {
            sourceNode.style.display = oldDisplay;
          }
        }
      }
    
    
      /** Maps language-specific file extensions to handlers. */
      var langHandlerRegistry = {};
      /** Register a language handler for the given file extensions.
        * @param {function (Object)} handler a function from source code to a list
        *      of decorations.  Takes a single argument job which describes the
        *      state of the computation.   The single parameter has the form
        *      {@code {
        *        sourceCode: {string} as plain text.
        *        decorations: {Array.<number|string>} an array of style classes
        *                     preceded by the position at which they start in
        *                     job.sourceCode in order.
        *                     The language handler should assigned this field.
        *        basePos: {int} the position of source in the larger source chunk.
        *                 All positions in the output decorations array are relative
        *                 to the larger source chunk.
        *      } }
        * @param {Array.<string>} fileExtensions
        */
      function registerLangHandler(handler, fileExtensions) {
        for (var i = fileExtensions.length; --i >= 0;) {
          var ext = fileExtensions[i];
          if (!langHandlerRegistry.hasOwnProperty(ext)) {
            langHandlerRegistry[ext] = handler;
          } else if (win['console']) {
            console['warn']('cannot override language handler %s', ext);
          }
        }
      }
      function langHandlerForExtension(extension, source) {
        if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
          // Treat it as markup if the first non whitespace character is a < and
          // the last non-whitespace character is a >.
          extension = /^\s*</.test(source)
              ? 'default-markup'
              : 'default-code';
        }
        return langHandlerRegistry[extension];
      }
      registerLangHandler(decorateSource, ['default-code']);
      registerLangHandler(
          createSimpleLexer(
              [],
              [
               [PR_PLAIN,       /^[^<?]+/],
               [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
               [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
               // Unescaped content in an unknown language
               ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
               ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
               [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
               ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
               // Unescaped content in javascript.  (Or possibly vbscript).
               ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
               // Contains unescaped stylesheet content
               ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
               ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
              ]),
          ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
      registerLangHandler(
          createSimpleLexer(
              [
               [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
               [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
               ],
              [
               [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
               [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
               ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
               [PR_PUNCTUATION,  /^[=<>\/]+/],
               ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
               ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
               ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
               ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
               ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
               ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
               ]),
          ['in.tag']);
      registerLangHandler(
          createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
      registerLangHandler(sourceDecorator({
              'keywords': CPP_KEYWORDS,
              'hashComments': true,
              'cStyleComments': true,
              'types': C_TYPES
            }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
      registerLangHandler(sourceDecorator({
              'keywords': PHP_KEYWORDS,
              'hashComments': false,
              'cStyleComments': true,
              'multiLineStrings': true,
              'regexLiterals': true
    //          'types': C_TYPES,
            }), ['php', 'phtml', 'inc']);
      registerLangHandler(sourceDecorator({
              'keywords': 'null,true,false'
            }), ['json']);
      registerLangHandler(sourceDecorator({
              'keywords': CSHARP_KEYWORDS,
              'hashComments': true,
              'cStyleComments': true,
              'verbatimStrings': true,
              'types': C_TYPES
            }), ['cs']);
      registerLangHandler(sourceDecorator({
              'keywords': JAVA_KEYWORDS,
              'cStyleComments': true
            }), ['java']);
      registerLangHandler(sourceDecorator({
              'keywords': SH_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true
            }), ['bsh', 'csh', 'sh']);
      registerLangHandler(sourceDecorator({
              'keywords': PYTHON_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true,
              'tripleQuotedStrings': true
            }), ['cv', 'py']);
      registerLangHandler(sourceDecorator({
              'keywords': PERL_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true,
              'regexLiterals': true
            }), ['perl', 'pl', 'pm']);
      registerLangHandler(sourceDecorator({
              'keywords': RUBY_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true,
              'regexLiterals': true
            }), ['rb']);
      registerLangHandler(sourceDecorator({
              'keywords': JSCRIPT_KEYWORDS,
              'cStyleComments': true,
              'regexLiterals': true
            }), ['js']);
      registerLangHandler(sourceDecorator({
              'keywords': COFFEE_KEYWORDS,
              'hashComments': 3,  // ### style block comments
              'cStyleComments': true,
              'multilineStrings': true,
              'tripleQuotedStrings': true,
              'regexLiterals': true
            }), ['coffee']);
      registerLangHandler(
          createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
      registerLangHandler(sourceDecorator({
              'keywords': CONFIG_KEYWORDS,
              'literals': CONFIG_OPTIONS,
              'strings': CONFIG_ENVS,
              'hashComments': true,
              'cStyleComments': false,
              'multiLineStrings': false,
              'regexLiterals': false,
              'httpdComments': true
            }), ['config']);
    
      function applyDecorator(job) {
        var opt_langExtension = job.langExtension;
    
        try {
          // Extract tags, and convert the source code to plain text.
          var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
          /** Plain text. @type {string} */
          var source = sourceAndSpans.sourceCode;
          job.sourceCode = source;
          job.spans = sourceAndSpans.spans;
          job.basePos = 0;
    
          // Apply the appropriate language handler
          langHandlerForExtension(opt_langExtension, source)(job);
    
          // Integrate the decorations and tags back into the source code,
          // modifying the sourceNode in place.
          recombineTagsAndDecorations(job);
        } catch (e) {
          if (win['console']) {
            console['log'](e && e['stack'] ? e['stack'] : e);
          }
        }
      }
    
      /**
       * @param sourceCodeHtml {string} The HTML to pretty print.
       * @param opt_langExtension {string} The language name to use.
       *     Typically, a filename extension like 'cpp' or 'java'.
       * @param opt_numberLines {number|boolean} True to number lines,
       *     or the 1-indexed number of the first line in sourceCodeHtml.
       */
      function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
        var container = document.createElement('pre');
        // This could cause images to load and onload listeners to fire.
        // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
        // We assume that the inner HTML is from a trusted source.
        container.innerHTML = sourceCodeHtml;
        if (opt_numberLines) {
          numberLines(container, opt_numberLines, true);
        }
    
        var job = {
          langExtension: opt_langExtension,
          numberLines: opt_numberLines,
          sourceNode: container,
          pre: 1
        };
        applyDecorator(job);
        return container.innerHTML;
      }
    
      function prettyPrint(opt_whenDone) {
        function byTagName(tn) { return document.getElementsByTagName(tn); }
        // fetch a list of nodes to rewrite
        var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
        var elements = [];
        for (var i = 0; i < codeSegments.length; ++i) {
          for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
            elements.push(codeSegments[i][j]);
          }
        }
        codeSegments = null;
    
        var clock = Date;
        if (!clock['now']) {
          clock = { 'now': function () { return +(new Date); } };
        }
    
        // The loop is broken into a series of continuations to make sure that we
        // don't make the browser unresponsive when rewriting a large page.
        var k = 0;
        var prettyPrintingJob;
    
        var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
        var prettyPrintRe = /\bprettyprint\b/;
        var prettyPrintedRe = /\bprettyprinted\b/;
        var preformattedTagNameRe = /pre|xmp/i;
        var codeRe = /^code$/i;
        var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
    
        function doWork() {
          var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
                         clock['now']() + 250 /* ms */ :
                         Infinity);
          for (; k < elements.length && clock['now']() < endTime; k++) {
            var cs = elements[k];
            var className = cs.className;
            if (prettyPrintRe.test(className)
                // Don't redo this if we've already done it.
                // This allows recalling pretty print to just prettyprint elements
                // that have been added to the page since last call.
                && !prettyPrintedRe.test(className)) {
    
              // make sure this is not nested in an already prettified element
              var nested = false;
              for (var p = cs.parentNode; p; p = p.parentNode) {
                var tn = p.tagName;
                if (preCodeXmpRe.test(tn)
                    && p.className && prettyPrintRe.test(p.className)) {
                  nested = true;
                  break;
                }
              }
              if (!nested) {
                // Mark done.  If we fail to prettyprint for whatever reason,
                // we shouldn't try again.
                cs.className += ' prettyprinted';
    
                // If the classes includes a language extensions, use it.
                // Language extensions can be specified like
                //     <pre class="prettyprint lang-cpp">
                // the language extension "cpp" is used to find a language handler
                // as passed to PR.registerLangHandler.
                // HTML5 recommends that a language be specified using "language-"
                // as the prefix instead.  Google Code Prettify supports both.
                // http://dev.w3.org/html5/spec-author-view/the-code-element.html
                var langExtension = className.match(langExtensionRe);
                // Support <pre class="prettyprint"><code class="language-c">
                var wrapper;
                if (!langExtension && (wrapper = childContentWrapper(cs))
                    && codeRe.test(wrapper.tagName)) {
                  langExtension = wrapper.className.match(langExtensionRe);
                }
    
                if (langExtension) { langExtension = langExtension[1]; }
    
                var preformatted;
                if (preformattedTagNameRe.test(cs.tagName)) {
                  preformatted = 1;
                } else {
                  var currentStyle = cs['currentStyle'];
                  var whitespace = (
                      currentStyle
                      ? currentStyle['whiteSpace']
                      : (document.defaultView
                         && document.defaultView.getComputedStyle)
                      ? document.defaultView.getComputedStyle(cs, null)
                      .getPropertyValue('white-space')
                      : 0);
                  preformatted = whitespace
                      && 'pre' === whitespace.substring(0, 3);
                }
    
                // Look for a class like linenums or linenums:<n> where <n> is the
                // 1-indexed number of the first line.
                var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/);
                lineNums = lineNums
                    ? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
                    : false;
                if (lineNums) { numberLines(cs, lineNums, preformatted); }
    
                // do the pretty printing
                prettyPrintingJob = {
                  langExtension: langExtension,
                  sourceNode: cs,
                  numberLines: lineNums,
                  pre: preformatted
                };
                applyDecorator(prettyPrintingJob);
              }
            }
          }
          if (k < elements.length) {
            // finish up in a continuation
            setTimeout(doWork, 250);
          } else if (opt_whenDone) {
            opt_whenDone();
          }
        }
    
        doWork();
      }
    
      /**
       * Contains functions for creating and registering new language handlers.
       * @type {Object}
       */
      var PR = win['PR'] = {
            'createSimpleLexer': createSimpleLexer,
            'registerLangHandler': registerLangHandler,
            'sourceDecorator': sourceDecorator,
            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
            'PR_COMMENT': PR_COMMENT,
            'PR_DECLARATION': PR_DECLARATION,
            'PR_KEYWORD': PR_KEYWORD,
            'PR_LITERAL': PR_LITERAL,
            'PR_NOCODE': PR_NOCODE,
            'PR_PLAIN': PR_PLAIN,
            'PR_PUNCTUATION': PR_PUNCTUATION,
            'PR_SOURCE': PR_SOURCE,
            'PR_STRING': PR_STRING,
            'PR_TAG': PR_TAG,
            'PR_TYPE': PR_TYPE,
            'prettyPrintOne': win['prettyPrintOne'] = prettyPrintOne,
            'prettyPrint': win['prettyPrint'] = prettyPrint
          };
       
    
    /* Register Lua syntaxes */   
       PR['registerLangHandler'](
        PR['createSimpleLexer'](
            [
             // Whitespace
             [PR['PR_PLAIN'],       /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'],
             // A double or single quoted, possibly multi-line, string.
             [PR['PR_STRING'],      /^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/, null, '"\'']
            ],
            [
             // A comment is either a line comment that starts with two dashes, or
             // two dashes preceding a long bracketed block.
             [PR['PR_COMMENT'], /^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],
             [PR['PR_TYPE'], /^nil|false|true/],
             // A long bracketed block not preceded by -- is a string.
             [PR['PR_STRING'],  /^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],
             [PR['PR_KEYWORD'], /^(?:and|break|do|else|elseif|end|for|function|if|in|local|not|or|repeat|require|return|then|until|while)\b/, null],
             // A number is a hex integer literal, a decimal real literal, or in
             // scientific notation.
             [PR['PR_LITERAL'],
              /^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],
             // An identifier
             [PR['PR_PLAIN'], /^[a-z_]\w*/i],
             // A run of punctuation
             [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]
            ]),
        ['lua']);
    
    
      // Make PR available via the Asynchronous Module Definition (AMD) API.
      // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
      // The Asynchronous Module Definition (AMD) API specifies a
      // mechanism for defining modules such that the module and its
      // dependencies can be asynchronously loaded.
      // ...
      // To allow a clear indicator that a global define function (as
      // needed for script src browser loading) conforms to the AMD API,
      // any global define function SHOULD have a property called "amd"
      // whose value is an object. This helps avoid conflict with any
      // other existing JavaScript code that could have defined a define()
      // function that does not conform to the AMD API.
      if (typeof define === "function" && define['amd']) {
        define("google-code-prettify", [], function () {
          return PR; 
        });
      }
    })();
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/scripts/prettify.min.js����������������������������������������������0000664�0001751�0001751�00000114610�14737563440�022664� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// see prettify.js for copyright, license and expanded version
    window['PR_SHOULD_USE_CONTINUATION']=true;var prettyPrintOne;var prettyPrint;(function(){var win=window;var FLOW_CONTROL_KEYWORDS=["break,continue,do,else,for,if,return,while"];var C_KEYWORDS=[FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default,"+"double,enum,extern,float,goto,int,long,register,short,signed,sizeof,module,"+"static,struct,switch,typedef,union,unsigned,void,volatile"];var COMMON_KEYWORDS=[C_KEYWORDS,"catch,class,delete,false,import,"+"new,operator,private,protected,public,this,throw,true,try,typeof"];var CPP_KEYWORDS=[COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool,"+"concept,concept_map,const_cast,constexpr,decltype,"+"dynamic_cast,explicit,export,friend,inline,late_check,"+"mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,"+"template,typeid,typename,using,virtual,where,request_req"];var JAVA_KEYWORDS=[COMMON_KEYWORDS,"abstract,boolean,byte,extends,final,finally,implements,import,"+"instanceof,null,native,package,strictfp,super,synchronized,throws,"+"transient"];var CSHARP_KEYWORDS=[JAVA_KEYWORDS,"as,base,by,checked,decimal,delegate,descending,dynamic,event,"+"fixed,foreach,from,group,implicit,in,interface,internal,into,is,let,"+"lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,"+"sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,"+"var,virtual,where"];var COFFEE_KEYWORDS="all,and,by,catch,class,else,extends,false,finally,"+"for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,"+"throw,true,try,unless,until,when,while,yes";var JSCRIPT_KEYWORDS=[COMMON_KEYWORDS,"debugger,eval,export,function,get,null,set,undefined,var,with,"+"Infinity,NaN"];var PERL_KEYWORDS="caller,delete,die,do,dump,else,elsif,eval,exit,foreach,for,"+"goto,if,import,last,local,my,next,no,our,print,printf,package,redo,require,"+"sub,undef,unless,until,use,wantarray,while,BEGIN,END";var PHP_KEYWORDS="abstract,and,array,as,break,case,catch,cfunction,class,"+"clone,const,continue,declare,default,do,else,elseif,enddeclare,endfor,"+"endforeach,endif,endswitch,endwhile,extends,final,for,foreach,function,"+"global,goto,if,implements,interface,instanceof,namespace,new,old_function,"+"or,private,protected,public,static,switch,throw,try,use,var,while,xor,"+"die,echo,empty,exit,eval,include,include_once,isset,list,require,"+"require_once,return,print,unset";var PYTHON_KEYWORDS=[FLOW_CONTROL_KEYWORDS,"and,as,assert,class,def,del,"+"elif,except,exec,finally,from,global,import,in,is,lambda,"+"nonlocal,not,or,pass,print,raise,try,with,yield,"+"False,True,None"];var RUBY_KEYWORDS=[FLOW_CONTROL_KEYWORDS,"alias,and,begin,case,class,"+"def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,"+"rescue,retry,self,super,then,true,undef,unless,until,when,yield,"+"BEGIN,END"];var SH_KEYWORDS=[FLOW_CONTROL_KEYWORDS,"case,done,elif,esac,eval,fi,"+"function,in,local,set,then,until,echo"];var CONFIG_ENVS=["User-Agent,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,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,REQUEST_SCHEME"];var CONFIG_KEYWORDS=["AcceptFilter,AcceptPathInfo,AccessFileName,Action,AddAlt,AddAltByEncoding,AddAltByType,AddCharset,AddDefaultCharset,AddDescription,AddEncoding,AddHandler,AddIcon,AddIconByEncoding,AddIconByType,AddInputFilter,AddLanguage,AddModuleInfo,AddOutputFilter,AddOutputFilterByType,AddType,Alias,AliasMatch,Allow,AllowCONNECT,AllowEncodedSlashes,AllowMethods,AllowOverride,AllowOverrideList,Anonymous,Anonymous_LogEmail,Anonymous_MustGiveEmail,Anonymous_NoUserID,Anonymous_VerifyEmail,AsyncRequestWorkerFactor,AuthBasicAuthoritative,AuthBasicFake,AuthBasicProvider,AuthBasicUseDigestAlgorithm,AuthDBDUserPWQuery,AuthDBDUserRealmQuery,AuthDBMGroupFile,AuthDBMType,AuthDBMUserFile,AuthDigestAlgorithm,AuthDigestDomain,AuthDigestNonceLifetime,AuthDigestProvider,AuthDigestQop,AuthDigestShmemSize,AuthFormAuthoritative,AuthFormBody,AuthFormDisableNoStore,AuthFormFakeBasicAuth,AuthFormLocation,AuthFormLoginRequiredLocation,AuthFormLoginSuccessLocation,AuthFormLogoutLocation,AuthFormMethod,AuthFormMimetype,AuthFormPassword,AuthFormProvider,AuthFormSitePassphrase,AuthFormSize,AuthFormUsername,AuthGroupFile,AuthLDAPAuthorizePrefix,AuthLDAPBindAuthoritative,AuthLDAPBindDN,AuthLDAPBindPassword,AuthLDAPCharsetConfig,AuthLDAPCompareAsUser,AuthLDAPCompareDNOnServer,AuthLDAPDereferenceAliases,AuthLDAPGroupAttribute,AuthLDAPGroupAttributeIsDN,AuthLDAPInitialBindAsUser,AuthLDAPInitialBindPattern,AuthLDAPMaxSubGroupDepth,AuthLDAPRemoteUserAttribute,AuthLDAPRemoteUserIsDN,AuthLDAPSearchAsUser,AuthLDAPSubGroupAttribute,AuthLDAPSubGroupClass,AuthLDAPURL,AuthMerging,AuthName,AuthnCacheContext,AuthnCacheEnable,AuthnCacheProvideFor,AuthnCacheSOCache,AuthnCacheTimeout,<AuthnProviderAlias>,AuthnzFcgiCheckAuthnProvider,AuthnzFcgiDefineProvider,AuthType,AuthUserFile,AuthzDBDLoginToReferer,AuthzDBDQuery,AuthzDBDRedirectQuery,AuthzDBMType,<AuthzProviderAlias>,AuthzSendForbiddenOnFailure,BalancerGrowth,BalancerInherit,BalancerMember,BalancerPersist,BrotliAlterETag,BrotliCompressionMaxInputBlock,BrotliCompressionQuality,BrotliCompressionWindow,BrotliFilterNote,BrowserMatch,BrowserMatchNoCase,BufferedLogs,BufferSize,CacheDefaultExpire,CacheDetailHeader,CacheDirLength,CacheDirLevels,CacheDisable,CacheEnable,CacheFile,CacheHeader,CacheIgnoreCacheControl,CacheIgnoreHeaders,CacheIgnoreNoLastMod,CacheIgnoreQueryString,CacheIgnoreURLSessionIdentifiers,CacheKeyBaseURL,CacheLastModifiedFactor,CacheLock,CacheLockMaxAge,CacheLockPath,CacheMaxExpire,CacheMaxFileSize,CacheMinExpire,CacheMinFileSize,CacheNegotiatedDocs,CacheQuickHandler,CacheReadSize,CacheReadTime,CacheRoot,CacheSocache,CacheSocacheMaxSize,CacheSocacheMaxTime,CacheSocacheMinTime,CacheSocacheReadSize,CacheSocacheReadTime,CacheStaleOnError,CacheStoreExpired,CacheStoreNoStore,CacheStorePrivate,CGIDScriptTimeout,CGIMapExtension,CGIPassAuth,CGIScriptTimeout,CGIVar,CharsetDefault,CharsetOptions,CharsetSourceEnc,CheckBasenameMatch,CheckCaseOnly,CheckSpelling,ChrootDir,ContentDigest,CookieDomain,CookieExpires,CookieHTTPOnly,CookieName,CookieSameSite,CookieSecure,CookieStyle,CookieTracking,CoreDumpDirectory,CustomLog,Dav,DavBasePath,DavDepthInfinity,DavGenericLockDB,DavLockDB,DavLockDiscovery,DavMinTimeout,DBDExptime,DBDInitSQL,DBDKeep,DBDMax,DBDMin,DBDParams,DBDPersist,DBDPrepareSQL,DBDriver,DefaultIcon,DefaultLanguage,DefaultRuntimeDir,DefaultType,Define,DeflateAlterETag,DeflateBufferSize,DeflateCompressionLevel,DeflateFilterNote,DeflateInflateLimitRequestBody,DeflateInflateRatioBurst,DeflateInflateRatioLimit,DeflateMemLevel,DeflateWindowSize,Deny,<Directory>,DirectoryCheckHandler,DirectoryIndex,DirectoryIndexRedirect,<DirectoryMatch>,DirectorySlash,DocumentRoot,DTracePrivileges,DumpIOInput,DumpIOOutput,<Else>,<ElseIf>,EnableExceptionHook,EnableMMAP,EnableSendfile,Error,ErrorDocument,ErrorLog,ErrorLogFormat,Example,ExpiresActive,ExpiresByType,ExpiresDefault,ExtendedStatus,ExtFilterDefine,ExtFilterOptions,FallbackResource,FileETag,<Files>,<FilesMatch>,FilterChain,FilterDeclare,FilterProtocol,FilterProvider,FilterTrace,FlushMaxPipelined,FlushMaxThreshold,ForceLanguagePriority,ForceType,ForensicLog,GlobalLog,GprofDir,GracefulShutdownTimeout,Group,H2CopyFiles,H2Direct,H2EarlyHint,H2EarlyHints,H2MaxDataFrameLen,H2MaxSessionStreams,H2MaxWorkerIdleSeconds,H2MaxWorkers,H2MinWorkers,H2ModernTLSOnly,H2OutputBuffering,H2Padding,H2ProxyRequests,H2Push,H2PushDiarySize,H2PushPriority,H2PushResource,H2SerializeHeaders,H2StreamMaxMemSize,H2StreamTimeout,H2TLSCoolDownSecs,H2TLSWarmUpSize,H2Upgrade,H2WebSockets,H2WindowSize,Header,HeaderName,HeartbeatAddress,HeartbeatListen,HeartbeatMaxServers,HeartbeatStorage,HeartbeatStorage,HostnameLookups,HttpProtocolOptions,IdentityCheck,IdentityCheckTimeout,<If>,<IfDefine>,<IfDirective>,<IfFile>,<IfModule>,<IfSection>,<IfVersion>,ImapBase,ImapDefault,ImapMenu,Include,IncludeOptional,IndexHeadInsert,IndexIgnore,IndexIgnoreReset,IndexOptions,IndexOrderDefault,IndexStyleSheet,InputSed,ISAPIAppendLogToErrors,ISAPIAppendLogToQuery,ISAPICacheFile,ISAPIFakeAsync,ISAPILogNotSupported,ISAPIReadAheadBuffer,KeepAlive,KeepAliveTimeout,KeptBodySize,LanguagePriority,LDAPCacheEntries,LDAPCacheTTL,LDAPConnectionPoolTTL,LDAPConnectionTimeout,LDAPLibraryDebug,LDAPOpCacheEntries,LDAPOpCacheTTL,LDAPReferralHopLimit,LDAPReferrals,LDAPRetries,LDAPRetryDelay,LDAPSharedCacheFile,LDAPSharedCacheSize,LDAPTimeout,LDAPTrustedClientCert,LDAPTrustedGlobalCert,LDAPTrustedMode,LDAPVerifyServerCert,<Limit>,<LimitExcept>,LimitInternalRecursion,LimitRequestBody,LimitRequestFields,LimitRequestFieldSize,LimitRequestLine,LimitXMLRequestBody,Listen,ListenBackLog,ListenCoresBucketsRatio,LoadFile,LoadModule,<Location>,<LocationMatch>,LogFormat,LogIOTrackTTFB,LogLevel,LogMessage,LuaAuthzProvider,LuaCodeCache,LuaHookAccessChecker,LuaHookAuthChecker,LuaHookCheckUserID,LuaHookFixups,LuaHookInsertFilter,LuaHookLog,LuaHookMapToStorage,LuaHookPreTranslate,LuaHookTranslateName,LuaHookTypeChecker,LuaInherit,LuaInputFilter,LuaMapHandler,LuaOutputFilter,LuaPackageCPath,LuaPackagePath,LuaQuickHandler,LuaRoot,LuaScope,<Macro>,MaxConnectionsPerChild,MaxKeepAliveRequests,MaxMemFree,MaxRangeOverlaps,MaxRangeReversals,MaxRanges,MaxRequestWorkers,MaxSpareServers,MaxSpareThreads,MaxThreads,MDActivationDelay,MDBaseServer,MDCAChallenges,MDCertificateAgreement,MDCertificateAuthority,MDCertificateCheck,MDCertificateFile,MDCertificateKeyFile,MDCertificateMonitor,MDCertificateProtocol,MDCertificateStatus,MDChallengeDns01,MDChallengeDns01Version,MDContactEmail,MDDriveMode,MDExternalAccountBinding,MDHttpProxy,MDMatchNames,MDMember,MDMembers,MDMessageCmd,MDMustStaple,MDNotifyCmd,MDomain,<MDomainSet>,MDPortMap,MDPrivateKeys,MDRenewMode,MDRenewWindow,MDRequireHttps,MDRetryDelay,MDRetryFailover,MDServerStatus,MDStapleOthers,MDStapling,MDStaplingKeepResponse,MDStaplingRenewWindow,MDStoreDir,MDStoreLocks,MDWarnWindow,MemcacheConnTTL,MergeSlashes,MergeTrailers,MetaDir,MetaFiles,MetaSuffix,MimeMagicFile,MinSpareServers,MinSpareThreads,MMapFile,ModemStandard,ModMimeUsePathInfo,MultiviewsMatch,Mutex,NameVirtualHost,NoProxy,NWSSLTrustedCerts,NWSSLUpgradeable,Options,Order,OutputSed,PassEnv,PidFile,PrivilegesMode,Protocol,ProtocolEcho,Protocols,ProtocolsHonorOrder,<Proxy>,Proxy100Continue,ProxyAddHeaders,ProxyBadHeader,ProxyBlock,ProxyDomain,ProxyErrorOverride,ProxyExpressDBMFile,ProxyExpressDBMType,ProxyExpressEnable,ProxyFCGIBackendType,ProxyFCGISetEnvIf,ProxyFtpDirCharset,ProxyFtpEscapeWildcards,ProxyFtpListOnWildcard,ProxyHCExpr,ProxyHCTemplate,ProxyHCTPsize,ProxyHTMLBufSize,ProxyHTMLCharsetOut,ProxyHTMLDocType,ProxyHTMLEnable,ProxyHTMLEvents,ProxyHTMLExtended,ProxyHTMLFixups,ProxyHTMLInterp,ProxyHTMLLinks,ProxyHTMLMeta,ProxyHTMLStripComments,ProxyHTMLURLMap,ProxyIOBufferSize,<ProxyMatch>,ProxyMaxForwards,ProxyPass,ProxyPassInherit,ProxyPassInterpolateEnv,ProxyPassMatch,ProxyPassReverse,ProxyPassReverseCookieDomain,ProxyPassReverseCookiePath,ProxyPreserveHost,ProxyReceiveBufferSize,ProxyRemote,ProxyRemoteMatch,ProxyRequests,ProxySCGIInternalRedirect,ProxySCGISendfile,ProxySet,ProxySourceAddress,ProxyStatus,ProxyTimeout,ProxyVia,ProxyWebsocketFallbackToProxyHttp,QualifyRedirectURL,ReadBufferSize,ReadmeName,ReceiveBufferSize,Redirect,RedirectMatch,RedirectPermanent,RedirectRelative,RedirectTemp,RedisConnPoolTTL,RedisTimeout,ReflectorHeader,RegexDefaultOptions,RegisterHttpMethod,RemoteIPHeader,RemoteIPInternalProxy,RemoteIPInternalProxyList,RemoteIPProxiesHeader,RemoteIPProxyProtocol,RemoteIPProxyProtocolExceptions,RemoteIPTrustedProxy,RemoteIPTrustedProxyList,RemoveCharset,RemoveEncoding,RemoveHandler,RemoveInputFilter,RemoveLanguage,RemoveOutputFilter,RemoveType,RequestHeader,RequestReadTimeout,Require,<RequireAll>,<RequireAny>,<RequireNone>,RewriteBase,RewriteCond,RewriteEngine,RewriteMap,RewriteOptions,RewriteRule,RLimitCPU,RLimitMEM,RLimitNPROC,Satisfy,ScoreBoardFile,Script,ScriptAlias,ScriptAliasMatch,ScriptInterpreterSource,ScriptLog,ScriptLogBuffer,ScriptLogLength,ScriptSock,SecureListen,SeeRequestTail,SendBufferSize,ServerAdmin,ServerAlias,ServerLimit,ServerName,ServerPath,ServerRoot,ServerSignature,ServerTokens,Session,SessionCookieName,SessionCookieName2,SessionCookieRemove,SessionCryptoCipher,SessionCryptoDriver,SessionCryptoPassphrase,SessionCryptoPassphraseFile,SessionDBDCookieName,SessionDBDCookieName2,SessionDBDCookieRemove,SessionDBDDeleteLabel,SessionDBDInsertLabel,SessionDBDPerUser,SessionDBDSelectLabel,SessionDBDUpdateLabel,SessionEnv,SessionExclude,SessionExpiryUpdateInterval,SessionHeader,SessionInclude,SessionMaxAge,SetEnv,SetEnvIf,SetEnvIfExpr,SetEnvIfNoCase,SetHandler,SetInputFilter,SetOutputFilter,SSIEndTag,SSIErrorMsg,SSIETag,SSILastModified,SSILegacyExprParser,SSIStartTag,SSITimeFormat,SSIUndefinedEcho,SSLCACertificateFile,SSLCACertificatePath,SSLCADNRequestFile,SSLCADNRequestPath,SSLCARevocationCheck,SSLCARevocationFile,SSLCARevocationPath,SSLCertificateChainFile,SSLCertificateFile,SSLCertificateKeyFile,SSLCipherSuite,SSLCompression,SSLCryptoDevice,SSLEngine,SSLFIPS,SSLHonorCipherOrder,SSLInsecureRenegotiation,SSLOCSPDefaultResponder,SSLOCSPEnable,SSLOCSPNoverify,SSLOCSPOverrideResponder,SSLOCSPProxyURL,SSLOCSPResponderCertificateFile,SSLOCSPResponderTimeout,SSLOCSPResponseMaxAge,SSLOCSPResponseTimeSkew,SSLOCSPUseRequestNonce,SSLOpenSSLConfCmd,SSLOptions,SSLPassPhraseDialog,SSLProtocol,SSLProxyCACertificateFile,SSLProxyCACertificatePath,SSLProxyCARevocationCheck,SSLProxyCARevocationFile,SSLProxyCARevocationPath,SSLProxyCheckPeerCN,SSLProxyCheckPeerExpire,SSLProxyCheckPeerName,SSLProxyCipherSuite,SSLProxyEngine,SSLProxyMachineCertificateChainFile,SSLProxyMachineCertificateFile,SSLProxyMachineCertificatePath,SSLProxyProtocol,SSLProxyVerify,SSLProxyVerifyDepth,SSLRandomSeed,SSLRenegBufferSize,SSLRequire,SSLRequireSSL,SSLSessionCache,SSLSessionCacheTimeout,SSLSessionTicketKeyFile,SSLSessionTickets,SSLSRPUnknownUserSeed,SSLSRPVerifierFile,SSLStaplingCache,SSLStaplingErrorCacheTimeout,SSLStaplingFakeTryLater,SSLStaplingForceURL,SSLStaplingResponderTimeout,SSLStaplingResponseMaxAge,SSLStaplingResponseTimeSkew,SSLStaplingReturnResponderErrors,SSLStaplingStandardCacheTimeout,SSLStrictSNIVHostCheck,SSLUserName,SSLUseStapling,SSLVerifyClient,SSLVerifyDepth,StartServers,StartThreads,StrictHostCheck,Substitute,SubstituteInheritBefore,SubstituteMaxLineLength,Suexec,SuexecUserGroup,ThreadLimit,ThreadsPerChild,ThreadStackSize,TimeOut,TraceEnable,TransferLog,TypesConfig,UNCList,UnDefine,UndefMacro,UnsetEnv,Use,UseCanonicalName,UseCanonicalPhysicalPort,User,UserDir,VHostCGIMode,VHostCGIPrivs,VHostGroup,VHostPrivs,VHostSecure,VHostUser,VirtualDocumentRoot,VirtualDocumentRootIP,<VirtualHost>,VirtualScriptAlias,VirtualScriptAliasIP,WatchdogInterval,XBitHack,xml2EncAlias,xml2EncDefault,xml2StartParse"];var CONFIG_OPTIONS=/^[\\+\\-]?(AuthConfig|IncludesNOEXEC|ExecCGI|FollowSymLinks|MultiViews|Includes|Indexes|SymLinksIfOwnerMatch)\b/i;var ALL_KEYWORDS=[CPP_KEYWORDS,CSHARP_KEYWORDS,JSCRIPT_KEYWORDS,PERL_KEYWORDS+
    PYTHON_KEYWORDS,RUBY_KEYWORDS,SH_KEYWORDS,CONFIG_KEYWORDS,PHP_KEYWORDS];var C_TYPES=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float|char|void|const|static|struct)\d*(_t)?\b)|[a-z_]+_rec|cmd_parms\b/;var PR_STRING='str';var PR_KEYWORD='kwd';var PR_COMMENT='com';var PR_TYPE='typ';var PR_LITERAL='lit';var PR_PUNCTUATION='pun';var PR_PLAIN='pln';var PR_TAG='tag';var PR_DECLARATION='dec';var PR_SOURCE='src';var PR_ATTRIB_NAME='atn';var PR_ATTRIB_VALUE='atv';var PR_NOCODE='nocode';var REGEXP_PRECEDER_PATTERN='(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';function combinePrefixPatterns(regexs){var capturedGroupIndex=0;var needToFoldCase=false;var ignoreCase=false;for(var i=0,n=regexs.length;i<n;++i){var regex=regexs[i];if(regex.ignoreCase){ignoreCase=true;}else if(/[a-z]/i.test(regex.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,''))){needToFoldCase=true;ignoreCase=false;break;}}
    var escapeCharToCodeUnit={'b':8,'t':9,'n':0xa,'v':0xb,'f':0xc,'r':0xd};function decodeEscape(charsetPart){var cc0=charsetPart.charCodeAt(0);if(cc0!==92){return cc0;}
    var c1=charsetPart.charAt(1);cc0=escapeCharToCodeUnit[c1];if(cc0){return cc0;}else if('0'<=c1&&c1<='7'){return parseInt(charsetPart.substring(1),8);}else if(c1==='u'||c1==='x'){return parseInt(charsetPart.substring(2),16);}else{return charsetPart.charCodeAt(1);}}
    function encodeEscape(charCode){if(charCode<0x20){return(charCode<0x10?'\\x0':'\\x')+charCode.toString(16);}
    var ch=String.fromCharCode(charCode);return(ch==='\\'||ch==='-'||ch===']'||ch==='^')?"\\"+ch:ch;}
    function caseFoldCharset(charSet){var charsetParts=charSet.substring(1,charSet.length-1).match(new RegExp('\\\\u[0-9A-Fa-f]{4}'
    +'|\\\\x[0-9A-Fa-f]{2}'
    +'|\\\\[0-3][0-7]{0,2}'
    +'|\\\\[0-7]{1,2}'
    +'|\\\\[\\s\\S]'
    +'|-'
    +'|[^-\\\\]','g'));var ranges=[];var inverse=charsetParts[0]==='^';var out=['['];if(inverse){out.push('^');}
    for(var i=inverse?1:0,n=charsetParts.length;i<n;++i){var p=charsetParts[i];if(/\\[bdsw]/i.test(p)){out.push(p);}else{var start=decodeEscape(p);var end;if(i+2<n&&'-'===charsetParts[i+1]){end=decodeEscape(charsetParts[i+2]);i+=2;}else{end=start;}
    ranges.push([start,end]);if(!(end<65||start>122)){if(!(end<65||start>90)){ranges.push([Math.max(65,start)|32,Math.min(end,90)|32]);}
    if(!(end<97||start>122)){ranges.push([Math.max(97,start)&~32,Math.min(end,122)&~32]);}}}}
    ranges.sort(function(a,b){return(a[0]-b[0])||(b[1]-a[1]);});var consolidatedRanges=[];var lastRange=[];for(var i=0;i<ranges.length;++i){var range=ranges[i];if(range[0]<=lastRange[1]+1){lastRange[1]=Math.max(lastRange[1],range[1]);}else{consolidatedRanges.push(lastRange=range);}}
    for(var i=0;i<consolidatedRanges.length;++i){var range=consolidatedRanges[i];out.push(encodeEscape(range[0]));if(range[1]>range[0]){if(range[1]+1>range[0]){out.push('-');}
    out.push(encodeEscape(range[1]));}}
    out.push(']');return out.join('');}
    function allowAnywhereFoldCaseAndRenumberGroups(regex){var parts=regex.source.match(new RegExp('(?:'
    +'\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'
    +'|\\\\u[A-Fa-f0-9]{4}'
    +'|\\\\x[A-Fa-f0-9]{2}'
    +'|\\\\[0-9]+'
    +'|\\\\[^ux0-9]'
    +'|\\(\\?[:!=]'
    +'|[\\(\\)\\^]'
    +'|[^\\x5B\\x5C\\(\\)\\^]+'
    +')','g'));var n=parts.length;var capturedGroups=[];for(var i=0,groupIndex=0;i<n;++i){var p=parts[i];if(p==='('){++groupIndex;}else if('\\'===p.charAt(0)){var decimalValue=+p.substring(1);if(decimalValue){if(decimalValue<=groupIndex){capturedGroups[decimalValue]=-1;}else{parts[i]=encodeEscape(decimalValue);}}}}
    for(var i=1;i<capturedGroups.length;++i){if(-1===capturedGroups[i]){capturedGroups[i]=++capturedGroupIndex;}}
    for(var i=0,groupIndex=0;i<n;++i){var p=parts[i];if(p==='('){++groupIndex;if(!capturedGroups[groupIndex]){parts[i]='(?:';}}else if('\\'===p.charAt(0)){var decimalValue=+p.substring(1);if(decimalValue&&decimalValue<=groupIndex){parts[i]='\\'+capturedGroups[decimalValue];}}}
    for(var i=0;i<n;++i){if('^'===parts[i]&&'^'!==parts[i+1]){parts[i]='';}}
    if(regex.ignoreCase&&needToFoldCase){for(var i=0;i<n;++i){var p=parts[i];var ch0=p.charAt(0);if(p.length>=2&&ch0==='['){parts[i]=caseFoldCharset(p);}else if(ch0!=='\\'){parts[i]=p.replace(/[a-zA-Z]/g,function(ch){var cc=ch.charCodeAt(0);return'['+String.fromCharCode(cc&~32,cc|32)+']';});}}}
    return parts.join('');}
    var rewritten=[];for(var i=0,n=regexs.length;i<n;++i){var regex=regexs[i];if(regex.global||regex.multiline){throw new Error(''+regex);}
    rewritten.push('(?:'+allowAnywhereFoldCaseAndRenumberGroups(regex)+')');}
    return new RegExp(rewritten.join('|'),ignoreCase?'gi':'g');}
    function extractSourceSpans(node,isPreformatted){var nocode=/(?:^|\s)nocode(?:\s|$)/;var chunks=[];var length=0;var spans=[];var k=0;function walk(node){switch(node.nodeType){case 1:if(nocode.test(node.className)){return;}
    for(var child=node.firstChild;child;child=child.nextSibling){walk(child);}
    var nodeName=node.nodeName.toLowerCase();if('br'===nodeName||'li'===nodeName){chunks[k]='\n';spans[k<<1]=length++;spans[(k++<<1)|1]=node;}
    break;case 3:case 4:var text=node.nodeValue;if(text.length){if(!isPreformatted){text=text.replace(/[ \t\r\n]+/g,' ');}else{text=text.replace(/\r\n?/g,'\n');text=text.replace(/^(\r?\n\s*)+/g,'');text=text.replace(/^\s*/g,'');text=text.replace(/(\r?\n\s*)+$/g,'');}
    chunks[k]=text;spans[k<<1]=length;length+=text.length;spans[(k++<<1)|1]=node;}
    break;}}
    walk(node);return{sourceCode:chunks.join('').replace(/\n$/,''),spans:spans};}
    function appendDecorations(basePos,sourceCode,langHandler,out){if(!sourceCode){return;}
    var job={sourceCode:sourceCode,basePos:basePos};langHandler(job);out.push.apply(out,job.decorations);}
    var notWs=/\S/;function childContentWrapper(element){var wrapper=undefined;for(var c=element.firstChild;c;c=c.nextSibling){var type=c.nodeType;wrapper=(type===1)?(wrapper?element:c):(type===3)?(notWs.test(c.nodeValue)?element:wrapper):wrapper;}
    return wrapper===element?undefined:wrapper;}
    function createSimpleLexer(shortcutStylePatterns,fallthroughStylePatterns){var shortcuts={};var tokenizer;(function(){var allPatterns=shortcutStylePatterns.concat(fallthroughStylePatterns);var allRegexs=[];var regexKeys={};for(var i=0,n=allPatterns.length;i<n;++i){var patternParts=allPatterns[i];var shortcutChars=patternParts[3];if(shortcutChars){for(var c=shortcutChars.length;--c>=0;){shortcuts[shortcutChars.charAt(c)]=patternParts;}}
    var regex=patternParts[1];var k=''+regex;if(!regexKeys.hasOwnProperty(k)){allRegexs.push(regex);regexKeys[k]=null;}}
    allRegexs.push(/[\0-\uffff]/);tokenizer=combinePrefixPatterns(allRegexs);})();var nPatterns=fallthroughStylePatterns.length;var decorate=function(job){var sourceCode=job.sourceCode,basePos=job.basePos;var decorations=[basePos,PR_PLAIN];var pos=0;var tokens=sourceCode.match(tokenizer)||[];var styleCache={};for(var ti=0,nTokens=tokens.length;ti<nTokens;++ti){var token=tokens[ti];var style=styleCache[token];var match=void 0;var isEmbedded;if(typeof style==='string'){isEmbedded=false;}else{var patternParts=shortcuts[token.charAt(0)];if(patternParts){match=token.match(patternParts[1]);style=patternParts[0];}else{for(var i=0;i<nPatterns;++i){patternParts=fallthroughStylePatterns[i];match=token.match(patternParts[1]);if(match){style=patternParts[0];break;}}
    if(!match){style=PR_PLAIN;}}
    isEmbedded=style.length>=5&&'lang-'===style.substring(0,5);if(isEmbedded&&!(match&&typeof match[1]==='string')){isEmbedded=false;style=PR_SOURCE;}
    if(!isEmbedded){styleCache[token]=style;}}
    var tokenStart=pos;pos+=token.length;if(!isEmbedded){decorations.push(basePos+tokenStart,style);}else{var embeddedSource=match[1];var embeddedSourceStart=token.indexOf(embeddedSource);var embeddedSourceEnd=embeddedSourceStart+embeddedSource.length;if(match[2]){embeddedSourceEnd=token.length-match[2].length;embeddedSourceStart=embeddedSourceEnd-embeddedSource.length;}
    var lang=style.substring(5);appendDecorations(basePos+tokenStart,token.substring(0,embeddedSourceStart),decorate,decorations);appendDecorations(basePos+tokenStart+embeddedSourceStart,embeddedSource,langHandlerForExtension(lang,embeddedSource),decorations);appendDecorations(basePos+tokenStart+embeddedSourceEnd,token.substring(embeddedSourceEnd),decorate,decorations);}}
    job.decorations=decorations;};return decorate;}
    function sourceDecorator(options){var shortcutStylePatterns=[],fallthroughStylePatterns=[];if(options['tripleQuotedStrings']){shortcutStylePatterns.push([PR_STRING,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,'\'"']);}else if(options['multiLineStrings']){shortcutStylePatterns.push([PR_STRING,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,'\'"`']);}else{shortcutStylePatterns.push([PR_STRING,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,'"\'']);}
    if(options['verbatimStrings']){fallthroughStylePatterns.push([PR_STRING,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);}
    var hc=options['hashComments'];if(hc){if(options['cStyleComments']){if(hc>1){shortcutStylePatterns.push([PR_COMMENT,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,'#']);}else{shortcutStylePatterns.push([PR_COMMENT,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,'#']);}
    fallthroughStylePatterns.push([PR_STRING,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null]);}else{shortcutStylePatterns.push([PR_COMMENT,/^#[^\r\n]*/,null,'#']);}}
    if(options['cStyleComments']){fallthroughStylePatterns.push([PR_COMMENT,/^\/\/[^\r\n]*/,null]);fallthroughStylePatterns.push([PR_COMMENT,/^\/\*[\s\S]*?(?:\*\/|$)/,null]);}
    if(options['regexLiterals']){var REGEX_LITERAL=('/(?=[^/*])'
    +'(?:[^/\\x5B\\x5C]'
    +'|\\x5C[\\s\\S]'
    +'|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
    +'/');fallthroughStylePatterns.push(['lang-regex',new RegExp('^'+REGEXP_PRECEDER_PATTERN+'('+REGEX_LITERAL+')')]);}
    var types=options['types'];if(types){fallthroughStylePatterns.push([PR_TYPE,types]);}
    if(options['strings']){var strings=(""+options['strings']).replace(/^ | $/g,'').replace(/-/g,'\\-');fallthroughStylePatterns.push([PR_STRING,new RegExp('(?:'+strings.replace(/[\s,]+/g,'|')+')'),,null]);}
    var keywords=(""+options['keywords']).replace(/^ | $/g,'');if(keywords.length){fallthroughStylePatterns.push([PR_KEYWORD,new RegExp('^(?:'+keywords.replace(/[\s,]+/g,'|')+')\\b'),null]);}
    shortcutStylePatterns.push([PR_PLAIN,/^\s+/,null,' \r\n\t\xA0']);if(options['httpdComments']){fallthroughStylePatterns.push([PR_PLAIN,/^.*\S.*#/i,null]);}
    fallthroughStylePatterns.push([PR_LITERAL,/^@[a-z_$][a-z_$@0-9]*|\bNULL\b/i,null],[PR_LITERAL,CONFIG_OPTIONS,null],[PR_TAG,/^\b(AuthnProviderAlias|AuthzProviderAlias|Directory|DirectoryMatch|Else|ElseIf|Files|FilesMatch|If|IfDefine|IfDirective|IfFile|IfModule|IfSection|IfVersion|Limit|LimitExcept|Location|LocationMatch|Macro|MDomainSet|Proxy|ProxyMatch|RequireAll|RequireAny|RequireNone|VirtualHost)\b/,null],[PR_TYPE,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_(t|req|module)\b)/,null],[PR_TAG,/^apr_[a-z_0-9]+|ap_[a-z_0-9]+/i,null],[PR_PLAIN,/^[a-z_$][a-z_$@0-9\-]*/i,null],[PR_LITERAL,new RegExp('^(?:'
    +'0x[a-f0-9]+'
    +'|[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+:[a-f0-9:]+'
    +'|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    +'(?:e[+\\-]?\\d+)?'
    +')'
    +'[a-z]*','i'),null,'0123456789'],[PR_PLAIN,/^\\[\s\S]?/,null],[PR_PUNCTUATION,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return createSimpleLexer(shortcutStylePatterns,fallthroughStylePatterns);}
    var decorateSource=sourceDecorator({'keywords':ALL_KEYWORDS,'hashComments':true,'cStyleComments':true,'multiLineStrings':true,'regexLiterals':true});function numberLines(node,opt_startLineNum,isPreformatted){var nocode=/(?:^|\s)nocode(?:\s|$)/;var lineBreak=/\r\n?|\n/;var document=node.ownerDocument;var li=document.createElement('li');while(node.firstChild){li.appendChild(node.firstChild);}
    var listItems=[li];function walk(node){switch(node.nodeType){case 1:if(nocode.test(node.className)){break;}
    if('br'===node.nodeName){breakAfter(node);if(node.parentNode){node.parentNode.removeChild(node);}}else{for(var child=node.firstChild;child;child=child.nextSibling){walk(child);}}
    break;case 3:case 4:if(isPreformatted){var text=node.nodeValue;var match=text.match(lineBreak);if(match){var firstLine=text.substring(0,match.index);node.nodeValue=firstLine;var tail=text.substring(match.index+match[0].length);if(tail){var parent=node.parentNode;parent.insertBefore(document.createTextNode(tail),node.nextSibling);}
    breakAfter(node);if(!firstLine){node.parentNode.removeChild(node);}}}
    break;}}
    function breakAfter(lineEndNode){while(!lineEndNode.nextSibling){lineEndNode=lineEndNode.parentNode;if(!lineEndNode){return;}}
    function breakLeftOf(limit,copy){var rightSide=copy?limit.cloneNode(false):limit;var parent=limit.parentNode;if(parent){var parentClone=breakLeftOf(parent,1);var next=limit.nextSibling;parentClone.appendChild(rightSide);for(var sibling=next;sibling;sibling=next){next=sibling.nextSibling;parentClone.appendChild(sibling);}}
    return rightSide;}
    var copiedListItem=breakLeftOf(lineEndNode.nextSibling,0);for(var parent;(parent=copiedListItem.parentNode)&&parent.nodeType===1;){copiedListItem=parent;}
    listItems.push(copiedListItem);}
    for(var i=0;i<listItems.length;++i){walk(listItems[i]);}
    if(opt_startLineNum===(opt_startLineNum|0)){listItems[0].setAttribute('value',opt_startLineNum);}
    var ol=document.createElement('ol');ol.className='linenums';var offset=Math.max(0,((opt_startLineNum-1))|0)||0;for(var i=0,n=listItems.length;i<n;++i){li=listItems[i];li.className='L'+((i+offset)%1);if(!li.firstChild){li.appendChild(document.createTextNode('\xA0'));}
    ol.appendChild(li);}
    node.appendChild(ol);}
    function recombineTagsAndDecorations(job){var isIE8OrEarlier=/\bMSIE\s(\d+)/.exec(navigator.userAgent);isIE8OrEarlier=isIE8OrEarlier&&+isIE8OrEarlier[1]<=8;var newlineRe=/\n/g;var source=job.sourceCode;var sourceLength=source.length;var sourceIndex=0;var spans=job.spans;var nSpans=spans.length;var spanIndex=0;var decorations=job.decorations;var nDecorations=decorations.length;var decorationIndex=0;decorations[nDecorations]=sourceLength;var decPos,i;for(i=decPos=0;i<nDecorations;){if(decorations[i]!==decorations[i+2]){decorations[decPos++]=decorations[i++];decorations[decPos++]=decorations[i++];}else{i+=2;}}
    nDecorations=decPos;for(i=decPos=0;i<nDecorations;){var startPos=decorations[i];var startDec=decorations[i+1];var end=i+2;while(end+2<=nDecorations&&decorations[end+1]===startDec){end+=2;}
    decorations[decPos++]=startPos;decorations[decPos++]=startDec;i=end;}
    nDecorations=decorations.length=decPos;var sourceNode=job.sourceNode;var oldDisplay;if(sourceNode){oldDisplay=sourceNode.style.display;sourceNode.style.display='none';}
    try{var decoration=null;var X=0;while(spanIndex<nSpans){X=X+1;if(X>5000){break;}
    var spanStart=spans[spanIndex];var spanEnd=spans[spanIndex+2]||sourceLength;var decEnd=decorations[decorationIndex+2]||sourceLength;var end=Math.min(spanEnd,decEnd);var textNode=spans[spanIndex+1];var styledText;if(textNode.nodeType!==1&&(styledText=source.substring(sourceIndex,end))){if(isIE8OrEarlier){styledText=styledText.replace(newlineRe,'\r');}
    textNode.nodeValue=styledText;var document=textNode.ownerDocument;var span=document.createElement('span');span.className=decorations[decorationIndex+1];var parentNode=textNode.parentNode;parentNode.replaceChild(span,textNode);span.appendChild(textNode);if(sourceIndex<spanEnd){spans[spanIndex+1]=textNode=document.createTextNode(source.substring(end,spanEnd));parentNode.insertBefore(textNode,span.nextSibling);}}
    sourceIndex=end;if(sourceIndex>=spanEnd){spanIndex+=2;}
    if(sourceIndex>=decEnd){decorationIndex+=2;}}}finally{if(sourceNode){sourceNode.style.display=oldDisplay;}}}
    var langHandlerRegistry={};function registerLangHandler(handler,fileExtensions){for(var i=fileExtensions.length;--i>=0;){var ext=fileExtensions[i];if(!langHandlerRegistry.hasOwnProperty(ext)){langHandlerRegistry[ext]=handler;}else if(win['console']){console['warn']('cannot override language handler %s',ext);}}}
    function langHandlerForExtension(extension,source){if(!(extension&&langHandlerRegistry.hasOwnProperty(extension))){extension=/^\s*</.test(source)?'default-markup':'default-code';}
    return langHandlerRegistry[extension];}
    registerLangHandler(decorateSource,['default-code']);registerLangHandler(createSimpleLexer([],[[PR_PLAIN,/^[^<?]+/],[PR_DECLARATION,/^<!\w[^>]*(?:>|$)/],[PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],['lang-',/^<\?([\s\S]+?)(?:\?>|$)/],['lang-',/^<%([\s\S]+?)(?:%>|$)/],[PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],['lang-',/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],['lang-js',/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],['lang-css',/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],['lang-in.tag',/^(<\/?[a-z][^<>]*>)/i]]),['default-markup','htm','html','mxml','xhtml','xml','xsl']);registerLangHandler(createSimpleLexer([[PR_PLAIN,/^[\s]+/,null,' \t\r\n'],[PR_ATTRIB_VALUE,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,'\"\'']],[[PR_TAG,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[PR_ATTRIB_NAME,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],['lang-uq.val',/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[PR_PUNCTUATION,/^[=<>\/]+/],['lang-js',/^on\w+\s*=\s*\"([^\"]+)\"/i],['lang-js',/^on\w+\s*=\s*\'([^\']+)\'/i],['lang-js',/^on\w+\s*=\s*([^\"\'>\s]+)/i],['lang-css',/^style\s*=\s*\"([^\"]+)\"/i],['lang-css',/^style\s*=\s*\'([^\']+)\'/i],['lang-css',/^style\s*=\s*([^\"\'>\s]+)/i]]),['in.tag']);registerLangHandler(createSimpleLexer([],[[PR_ATTRIB_VALUE,/^[\s\S]+/]]),['uq.val']);registerLangHandler(sourceDecorator({'keywords':CPP_KEYWORDS,'hashComments':true,'cStyleComments':true,'types':C_TYPES}),['c','cc','cpp','cxx','cyc','m']);registerLangHandler(sourceDecorator({'keywords':PHP_KEYWORDS,'hashComments':false,'cStyleComments':true,'multiLineStrings':true,'regexLiterals':true}),['php','phtml','inc']);registerLangHandler(sourceDecorator({'keywords':'null,true,false'}),['json']);registerLangHandler(sourceDecorator({'keywords':CSHARP_KEYWORDS,'hashComments':true,'cStyleComments':true,'verbatimStrings':true,'types':C_TYPES}),['cs']);registerLangHandler(sourceDecorator({'keywords':JAVA_KEYWORDS,'cStyleComments':true}),['java']);registerLangHandler(sourceDecorator({'keywords':SH_KEYWORDS,'hashComments':true,'multiLineStrings':true}),['bsh','csh','sh']);registerLangHandler(sourceDecorator({'keywords':PYTHON_KEYWORDS,'hashComments':true,'multiLineStrings':true,'tripleQuotedStrings':true}),['cv','py']);registerLangHandler(sourceDecorator({'keywords':PERL_KEYWORDS,'hashComments':true,'multiLineStrings':true,'regexLiterals':true}),['perl','pl','pm']);registerLangHandler(sourceDecorator({'keywords':RUBY_KEYWORDS,'hashComments':true,'multiLineStrings':true,'regexLiterals':true}),['rb']);registerLangHandler(sourceDecorator({'keywords':JSCRIPT_KEYWORDS,'cStyleComments':true,'regexLiterals':true}),['js']);registerLangHandler(sourceDecorator({'keywords':COFFEE_KEYWORDS,'hashComments':3,'cStyleComments':true,'multilineStrings':true,'tripleQuotedStrings':true,'regexLiterals':true}),['coffee']);registerLangHandler(createSimpleLexer([],[[PR_STRING,/^[\s\S]+/]]),['regex']);registerLangHandler(sourceDecorator({'keywords':CONFIG_KEYWORDS,'literals':CONFIG_OPTIONS,'strings':CONFIG_ENVS,'hashComments':true,'cStyleComments':false,'multiLineStrings':false,'regexLiterals':false,'httpdComments':true}),['config']);function applyDecorator(job){var opt_langExtension=job.langExtension;try{var sourceAndSpans=extractSourceSpans(job.sourceNode,job.pre);var source=sourceAndSpans.sourceCode;job.sourceCode=source;job.spans=sourceAndSpans.spans;job.basePos=0;langHandlerForExtension(opt_langExtension,source)(job);recombineTagsAndDecorations(job);}catch(e){if(win['console']){console['log'](e&&e['stack']?e['stack']:e);}}}
    function prettyPrintOne(sourceCodeHtml,opt_langExtension,opt_numberLines){var container=document.createElement('pre');container.innerHTML=sourceCodeHtml;if(opt_numberLines){numberLines(container,opt_numberLines,true);}
    var job={langExtension:opt_langExtension,numberLines:opt_numberLines,sourceNode:container,pre:1};applyDecorator(job);return container.innerHTML;}
    function prettyPrint(opt_whenDone){function byTagName(tn){return document.getElementsByTagName(tn);}
    var codeSegments=[byTagName('pre'),byTagName('code'),byTagName('xmp')];var elements=[];for(var i=0;i<codeSegments.length;++i){for(var j=0,n=codeSegments[i].length;j<n;++j){elements.push(codeSegments[i][j]);}}
    codeSegments=null;var clock=Date;if(!clock['now']){clock={'now':function(){return+(new Date);}};}
    var k=0;var prettyPrintingJob;var langExtensionRe=/\blang(?:uage)?-([\w.]+)(?!\S)/;var prettyPrintRe=/\bprettyprint\b/;var prettyPrintedRe=/\bprettyprinted\b/;var preformattedTagNameRe=/pre|xmp/i;var codeRe=/^code$/i;var preCodeXmpRe=/^(?:pre|code|xmp)$/i;function doWork(){var endTime=(win['PR_SHOULD_USE_CONTINUATION']?clock['now']()+250:Infinity);for(;k<elements.length&&clock['now']()<endTime;k++){var cs=elements[k];var className=cs.className;if(prettyPrintRe.test(className)&&!prettyPrintedRe.test(className)){var nested=false;for(var p=cs.parentNode;p;p=p.parentNode){var tn=p.tagName;if(preCodeXmpRe.test(tn)&&p.className&&prettyPrintRe.test(p.className)){nested=true;break;}}
    if(!nested){cs.className+=' prettyprinted';var langExtension=className.match(langExtensionRe);var wrapper;if(!langExtension&&(wrapper=childContentWrapper(cs))&&codeRe.test(wrapper.tagName)){langExtension=wrapper.className.match(langExtensionRe);}
    if(langExtension){langExtension=langExtension[1];}
    var preformatted;if(preformattedTagNameRe.test(cs.tagName)){preformatted=1;}else{var currentStyle=cs['currentStyle'];var whitespace=(currentStyle?currentStyle['whiteSpace']:(document.defaultView&&document.defaultView.getComputedStyle)?document.defaultView.getComputedStyle(cs,null).getPropertyValue('white-space'):0);preformatted=whitespace&&'pre'===whitespace.substring(0,3);}
    var lineNums=cs.className.match(/\blinenums\b(?::(\d+))?/);lineNums=lineNums?lineNums[1]&&lineNums[1].length?+lineNums[1]:true:false;if(lineNums){numberLines(cs,lineNums,preformatted);}
    prettyPrintingJob={langExtension:langExtension,sourceNode:cs,numberLines:lineNums,pre:preformatted};applyDecorator(prettyPrintingJob);}}}
    if(k<elements.length){setTimeout(doWork,250);}else if(opt_whenDone){opt_whenDone();}}
    doWork();}
    var PR=win['PR']={'createSimpleLexer':createSimpleLexer,'registerLangHandler':registerLangHandler,'sourceDecorator':sourceDecorator,'PR_ATTRIB_NAME':PR_ATTRIB_NAME,'PR_ATTRIB_VALUE':PR_ATTRIB_VALUE,'PR_COMMENT':PR_COMMENT,'PR_DECLARATION':PR_DECLARATION,'PR_KEYWORD':PR_KEYWORD,'PR_LITERAL':PR_LITERAL,'PR_NOCODE':PR_NOCODE,'PR_PLAIN':PR_PLAIN,'PR_PUNCTUATION':PR_PUNCTUATION,'PR_SOURCE':PR_SOURCE,'PR_STRING':PR_STRING,'PR_TAG':PR_TAG,'PR_TYPE':PR_TYPE,'prettyPrintOne':win['prettyPrintOne']=prettyPrintOne,'prettyPrint':win['prettyPrint']=prettyPrint};PR['registerLangHandler'](PR['createSimpleLexer']([[PR['PR_PLAIN'],/^[\t\n\r \xA0]+/,null,'\t\n\r \xA0'],[PR['PR_STRING'],/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'"\'']],[[PR['PR_COMMENT'],/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],[PR['PR_TYPE'],/^nil|false|true/],[PR['PR_STRING'],/^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],[PR['PR_KEYWORD'],/^(?:and|break|do|else|elseif|end|for|function|if|in|local|not|or|repeat|require|return|then|until|while)\b/,null],[PR['PR_LITERAL'],/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR['PR_PLAIN'],/^[a-z_]\w*/i],[PR['PR_PUNCTUATION'],/^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]]),['lua']);if(typeof define==="function"&&define['amd']){define("google-code-prettify",[],function(){return PR;});}})();������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/xsl/�����������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�017013� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/xsl/util/������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�017770� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/lang/����������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�017126� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/version.ent����������������������������������������������������������0000664�0001751�0001751�00000001635�14744525602�020402� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='UTF-8' ?>
    
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
     contributor license agreements.  See the NOTICE file distributed with
     this work for additional information regarding copyright ownership.
     The ASF licenses this file to You under the Apache License, Version 2.0
     (the "License"); you may not use this file except in compliance with
     the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
    -->
    
    <!ENTITY httpd.major "2">
    <!ENTITY httpd.minor "4">
    <!ENTITY httpd.patch "64">
    
    <!ENTITY httpd.docs "2.4">
    ���������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/latex/���������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�017322� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/latex/atbeginend.sty�������������������������������������������������0000664�0001751�0001751�00000005026�10455056574�022163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% atbeginend.sty 
    %
    % Licensed to the Apache Software Foundation (ASF) under one or more
    % contributor license agreements.  See the NOTICE file distributed with
    % this work for additional information regarding copyright ownership.
    % The ASF licenses this file to You under the Apache License, Version 2.0
    % (the "License"); you may not use this file except in compliance with
    % the License.  You may obtain a copy of the License at
    %
    %     http://www.apache.org/licenses/LICENSE-2.0
    %
    % Unless required by applicable law or agreed to in writing, software
    % distributed under the License is distributed on an "AS IS" BASIS,
    % WITHOUT 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}}
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/common.dtd�����������������������������������������������������������0000664�0001751�0001751�00000013425�14655360273�020174� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='UTF-8' ?>
    
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
     contributor license agreements.  See the NOTICE file distributed with
     this work for additional information regarding copyright ownership.
     The ASF licenses this file to You under the Apache License, Version 2.0
     (the "License"); you may not use this file except in compliance with
     the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
    -->
    
    <!-- Character mnemonic entities -->
    
    <!ENTITY % HTMLlat1 PUBLIC
       "-//W3C//ENTITIES Latin 1 for XHTML//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
    %HTMLlat1;
    
    <!ENTITY % HTMLsymbol PUBLIC
       "-//W3C//ENTITIES Symbols for XHTML//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
    %HTMLsymbol;
    
    <!ENTITY % HTMLspecial PUBLIC
       "-//W3C//ENTITIES Special for XHTML//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
    %HTMLspecial;
    
    <!-- HTTPD Version -->
    
    <!ENTITY % HTTPD-VERSION SYSTEM "version.ent">
    %HTTPD-VERSION;
    
    <!-- Generic tag entities -->
    
    <!ENTITY % inlinetags "em | strong | code | a | br | directive | module |
    program | img | cite | q | dfn | var | transnote | glossary | phonetic | since">
    
    <!ENTITY % blocktags "p | example | note | table | ul | ol | dl | pre | 
    highlight | blockquote">
    
    <!ENTITY % Block "(%blocktags;)*">
    <!ENTITY % Inline "(#PCDATA | %inlinetags;)*">
    <!ENTITY % BlockOrInline "(#PCDATA | %inlinetags; | %blocktags;)*">
    
    <!-- Common Elements -->
    
    <!ELEMENT title %Inline;>
    
    <!ELEMENT summary %Block;>
    
    <!ELEMENT seealso %Inline;>
    
    <!ELEMENT modulelist (module)+>
    
    <!-- a page may have one or more sections. Each section is named by an
         unique id. A section must have a title and some text. It may have
         subsections and a list of related modules and directives -->
    <!ELEMENT section (title, related?, (section | %blocktags;)*)>
    <!ATTLIST section id ID #IMPLIED>
    
    <!-- the lists of related modules and/or related directives -->
    <!ELEMENT related (modulelist | directivelist)+>
    
    <!-- list of related directives -->
    <!ELEMENT directivelist (directive)+>
    
    <!ELEMENT module (#PCDATA)>
    <!ATTLIST module status   CDATA  #IMPLIED
                     outdated (true) #IMPLIED>
    
    <!ELEMENT directive (#PCDATA)>
    <!-- name attribute is preferred over contents when generating links,
         and idtype is used to disambiguate two directives sharing the
         same name but with different type (for example section and non-section).
    -->
    <!ATTLIST directive  module CDATA  #IMPLIED
                         type   CDATA  #IMPLIED
                         idtype CDATA  #IMPLIED
                         status CDATA  #IMPLIED
                         name   CDATA  #IMPLIED >
    
    <!ELEMENT program (#PCDATA)>
    
    <!ELEMENT p %Inline;>
    <!ATTLIST p class CDATA  #IMPLIED>
    
    <!-- the indent element is used to indent code examples. example/indent and
         code/indent is now replacing pre. -->
    <!ELEMENT indent ( #PCDATA | indent | %inlinetags; )*>
    
    <!ELEMENT em %Inline;>
    
    <!ELEMENT strong %Inline;>
    
    <!ELEMENT code (#PCDATA | indent | %inlinetags;)*>
    
    <!ELEMENT cite %Inline;>
    
    <!ELEMENT q %Inline;>
    
    <!ELEMENT dfn %Inline;>
    
    <!ELEMENT var %Inline;>
    
    <!ELEMENT since %Inline;>
    
    <!-- translators note -->
    <!ELEMENT transnote %Inline;>
    
    <!ELEMENT a %Inline;>
    <!ATTLIST a  href CDATA #IMPLIED
                 name CDATA #IMPLIED
                 id   CDATA #IMPLIED
                 rel  CDATA #IMPLIED >
    
    <!ELEMENT br EMPTY>
    
    <!-- Note: The example and note elements should not have more then one
               title. -->
    <!ELEMENT example (#PCDATA | title | indent | %inlinetags; | %blocktags;)*>
    
    <!ELEMENT note (#PCDATA | title | %inlinetags; | %blocktags;)*>
    <!ATTLIST note type CDATA #IMPLIED>
    
    <!ELEMENT table (columnspec | tr)+>
    <!ATTLIST table summary     CDATA  #IMPLIED
                    width       CDATA  #IMPLIED
                    bgcolor     CDATA  #IMPLIED
                    cellspacing CDATA  #IMPLIED
                    cellpadding CDATA  #IMPLIED
                    border      CDATA  #IMPLIED
                    style       CDATA  #IMPLIED>
    
    <!ELEMENT columnspec (column)+>
    
    <!ELEMENT column EMPTY>
    <!ATTLIST column width CDATA #IMPLIED>
    
    <!ELEMENT tr (th | td)+>
    <!ATTLIST tr valign CDATA #IMPLIED >
    
    <!ELEMENT th %BlockOrInline;>
    <!ATTLIST th  colspan  CDATA  #IMPLIED
                  rowspan  CDATA  #IMPLIED
                  class    CDATA  #IMPLIED >
    
    <!ELEMENT td %BlockOrInline;>
    <!ATTLIST td  colspan  CDATA  #IMPLIED
                  rowspan  CDATA  #IMPLIED
                  class    CDATA  #IMPLIED >
    
    <!ELEMENT ul (li+)>
    
    <!ELEMENT ol (li+)>
    <!ATTLIST ol type CDATA  #IMPLIED>
    
    <!ELEMENT li %BlockOrInline;>
    <!ATTLIST li class    CDATA   #IMPLIED >
    
    <!ELEMENT dl (dd | dt)+>
    
    <!ELEMENT dt %Inline;>
    
    <!ELEMENT dd %BlockOrInline;>
    
    <!ELEMENT pre %Inline;>
    
    <!ELEMENT highlight %Inline;>
    <!ATTLIST highlight language CDATA #IMPLIED>
    
    <!ELEMENT img EMPTY>
    <!ATTLIST img
      src         CDATA   #REQUIRED
      alt         CDATA   #REQUIRED
      border      CDATA   #IMPLIED
      height      CDATA   #IMPLIED
      width       CDATA   #IMPLIED >
    
    <!ELEMENT blockquote %Block;>
    <!ATTLIST blockquote cite CDATA #IMPLIED >
    
    <!-- The path and title of the parent document -->
    <!ELEMENT parentdocument (#PCDATA)>
    <!ATTLIST parentdocument href CDATA #REQUIRED >
    
    <!-- The glossary element defines a special case of link. The referenced
         target is the name of an anchor within the glossary -->
    <!ELEMENT glossary %Inline;>
    <!ATTLIST glossary ref CDATA #IMPLIED>
    
    <!-- The phonetic element should be used only within the glossary. It
         describes a pronunciation -->
    <!ELEMENT phonetic (#PCDATA)>
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/css/�����������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766612�016767� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/css/prettify.css�����������������������������������������������������0000664�0001751�0001751�00000007040�12113256271�021340� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Pretty printing styles. Used with prettify.js. */
    
    /* SPAN elements with the classes below are added by prettyprint. */
    .pln { color: #000 }  /* plain text */
    
    @media screen {
      .str { color: #060 }  /* string content */
      .kwd { color: #006 }  /* a keyword */
      .com { color: #600 }  /* a comment */
      .typ { color: #404 }  /* a type name */
      .lit { color: #066 }  /* a literal value */
      /* punctuation, lisp open bracket, lisp close bracket */
      .pun, .opn, .clo { color: #660 }
      .tag { color: #008 }  /* a markup tag name */
      .atn { color: #606 }  /* a markup attribute name */
      .atv { color: #080 }  /* a markup attribute value */
      .dec, .var { color: #606 }  /* a declaration; a variable name */
      .fun { color: red }  /* a function name */
    }
    
    /* Use higher contrast and text-weight for printable form. */
    @media print, projection {
      .str { color: #060 }
      .kwd { color: #006; font-weight: bold }
      .com { color: #600; font-style: italic }
      .typ { color: #404; font-weight: bold }
      .lit { color: #044 }
      .pun, .opn, .clo { color: #440 }
      .tag { color: #006; font-weight: bold }
      .atn { color: #404 }
      .atv { color: #060 }
    }
    
    /* Put a border around prettyprinted code snippets. */
    pre.prettyprint { padding: 2px; border: 1px solid #888; tab-size: 4; overflow: auto; overflow-y: hidden; }
    
    /* Specify class=linenums on a pre to get line numbering */
    ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
    li.L0,
    li.L1,
    li.L2,
    li.L3,
    li.L5,
    li.L6,
    li.L7,
    li.L8 { list-style-type: none }
    /* Alternate shading for lines */
    li.L1,
    li.L3,
    li.L5,
    li.L7,
    li.L9 { background: #eee }
    
    
    
    /* Highlighting style for Apache configuration files */
    pre.lang-config{ 
        background-color: #e5ecf3;
        color: #000;
        padding: 0.5em;
        margin: 1em 2em 1em 1em;
        border: none;
    }
    .lang-config .tag { color: #821; font-weight: bold }  /* enclosures */
    .lang-config .kwd { color: #128; font-weight: bold }  /* directives */
    .lang-config .com { color: #c46d34 }  /* comments */
    .lang-config .lit { color: #077 }  /* miscellaneous types: Options arguments, handler names etc */
    
    
    
    /* Highlighting style for C source code */
    pre.lang-c{ 
        background-color: #f8f6ee;
        color: #000;
        padding: 0.5em;
        margin: 1em 2em 1em 1em;
        border: 1px dotted #666;
    }
    
    .lang-c .com { color: #c46d34 }  /* a comment */
    .lang-c .lit { color: #088 } /* a literal */
    .lang-c .str { color: #009606 } /* string content */
    .lang-c .kwd { color: #00C; font-weight: bold }  /* a keyword */
    .lang-c .typ { color: #808 }  /* a type name */
    .lang-c .tag { color: #248 }  /* a markup tag name */
    
    
    
    
    /* Highlighting style for Lua source code */
    pre.lang-lua{ 
        background-color: #f8f6ee;
        color: #000;
        padding: 0.5em;
        margin: 1em 2em 1em 1em;
        border: 1px dotted #666;
    }
    
    .lang-lua .com { color: #c34e00 }  /* a comment */
    .lang-lua .lit { color: #088 } /* a literal (in this context; a known directive argument, a number or an IP address) */
    .lang-lua .str { color: #009606 } /* string content */
    .lang-lua .kwd { color: #00C; font-weight: bold }  /* a keyword */
    .lang-lua .typ { color: #808 }  /* a type name */
    
    
    
    
    /* Highlighting style for Perl source code */
    pre.lang-perl{ 
        background-color: #f8f6ee;
        color: #000;
        padding: 0.5em;
        margin: 1em 2em 1em 1em;
        border: 1px dotted #666;
    }
    
    .lang-perl .com { color: #c34e00 }  /* a comment */
    .lang-perl .lit { color: #088 } /* a literal */
    .lang-perl .str { color: #009606 } /* string content */
    .lang-perl .kwd { color: #00C; font-weight: bold }  /* a keyword */
    .lang-perl .typ { color: #808 }  /* a type name */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/css/manual-chm.css���������������������������������������������������0000664�0001751�0001751�00000001623�10455056330�021516� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@import url(manual-loose-100pc.css);
    
    /* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 */
    �������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/css/manual-zip.css���������������������������������������������������0000664�0001751�0001751�00000001552�10455056330�021552� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@import url(manual.css);
    
    /* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 */
    ������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/css/manual-loose-100pc.css�������������������������������������������0000664�0001751�0001751�00000005771�10455056330�022721� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * manual.css - no sidebar, 100% normal font height
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    
    /* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <-
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    �������httpd-2.4.64/docs/manual/style/css/manual-print.css�������������������������������������������������0000664�0001751�0001751�00000031620�10455056330�022103� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * manual.css for printers
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    
    /* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <a name>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 <a name>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
     * <code class="directive"> or
     * <code class="module">
     */
    
    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 <-
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    ����������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/css/manual.css�������������������������������������������������������0000664�0001751�0001751�00000045211�13154522721�020753� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * manual.css
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    
    /* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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;
    }
    
    /* glossary [links] */
    /* ====================== */
    .glossarylink {
        cursor: help;
        border-bottom: 1px dashed #0073c7;
        text-decoration: none;
    }
    
    
    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * 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 <a name>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 <a name>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
     * <code class="directive"> or
     * <code class="module">
     */
    
    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;
    }
    
    /* override index */
    /* ============== */
    div#override-list td.module {
        width: 20%;
    }
    
    /* 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#quickview a.badge {
        /* Temporary hack for the Support Apache badge */
        background-color: transparent;
    }
    
    div#quickview a.badge img {
        /* Temporary hack for the Support Apache badge */
        width: 95px;
        height: 95px;
    }
    
    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,
    div.retired{
        background-color: #ffffc0;
        color: #036;
        padding: 0.5em;
        margin: 1em 2em 1em 1em;
    }
    div.retired{
        border: solid 1px #ff0000;
        margin-left: 3em;
    }
    
    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * 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 <-
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/css/manual-zip-100pc.css���������������������������������������������0000664�0001751�0001751�00000001565�10455056330�022377� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@import url(manual-loose-100pc.css);
    
    /* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 */
    �������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/modulesynopsis.dtd���������������������������������������������������0000664�0001751�0001751�00000005434�13206512634�021771� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='UTF-8' ?>
    
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
     contributor license agreements.  See the NOTICE file distributed with
     this work for additional information regarding copyright ownership.
     The ASF licenses this file to You under the Apache License, Version 2.0
     (the "License"); you may not use this file except in compliance with
     the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
    -->
    
    <!ENTITY % sitemap SYSTEM "sitemap.dtd">
    %sitemap;
    
    <!ELEMENT modulesynopsis (name , description, status, hint?, sourcefile?,
    identifier? , compatibility? , summary? , seealso* , section*,
    directivesynopsis*)>
    
    <!ATTLIST modulesynopsis metafile CDATA  #REQUIRED
                             upgrade  CDATA  #IMPLIED>
    
    <!ELEMENT directivesynopsis (name , description? , syntax? , default?
    , contextlist? , override? , modulelist?, status?, compatibility? ,
    usage?, seealso*)>
    
    <!ELEMENT name (#PCDATA)>
    
    <!ELEMENT status (#PCDATA)>
    
    <!ELEMENT hint %Inline;>
    
    <!ELEMENT identifier (#PCDATA)>
    
    <!ELEMENT sourcefile (#PCDATA)>
    
    <!ELEMENT compatibility %Inline;>
    
    <!ELEMENT description %Inline;>
    
    <!-- 
     idtype is appended to the directive name when generating links to allow
     a directive of type section to share the name with another directive.
     The attribute type could have been (re)used instead but it would have broken
     pre-existing links.
    -->
    <!ATTLIST directivesynopsis  type       CDATA  #IMPLIED
                                 idtype     CDATA  #IMPLIED
                                 location   CDATA  #IMPLIED >
    
    <!ELEMENT syntax %Inline;>
    
    <!ELEMENT default (#PCDATA | directive | br)*>
    
    <!ELEMENT contextlist (context+)+>
    
    <!ELEMENT context (#PCDATA)>
    
    <!ELEMENT override (#PCDATA)>
    
    <!ELEMENT usage %Block;>
    
    <!-- Used in index.xml -->
    <!ELEMENT moduleindex (title, summary, seealso*)>
    
    <!ATTLIST moduleindex metafile CDATA  #REQUIRED>
    
    <!-- Used in directive.xml -->
    <!ELEMENT directiveindex (title | summary)+>
    
    <!ATTLIST directiveindex metafile CDATA  #REQUIRED>
    
    <!-- Used in quickreference.xml -->
    <!ELEMENT quickreference (title | summary | legend)+>
    <!ATTLIST quickreference metafile CDATA  #REQUIRED>
    
    <!ELEMENT legend (table, table)>
    
    <!-- Used in overrides.xml -->
    <!ELEMENT overrideindex (title | summary | overridesummary)+>
    <!ATTLIST overrideindex metafile CDATA #REQUIRED>
    
    <!ELEMENT overridesummary %Block;>
    <!ATTLIST overridesummary class    CDATA #IMPLIED
                              fallback CDATA #IMPLIED>
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/faq.dtd��������������������������������������������������������������0000664�0001751�0001751�00000002337�12273272705�017447� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='UTF-8' ?>
    
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
     contributor license agreements.  See the NOTICE file distributed with
     this work for additional information regarding copyright ownership.
     The ASF licenses this file to You under the Apache License, Version 2.0
     (the "License"); you may not use this file except in compliance with
     the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
    -->
    
    <!ENTITY % common SYSTEM "common.dtd">
    %common;
    
    <!-- <faq> is the root element -->
    <!ELEMENT faq (parentdocument?, title, description?, summary?,
    seealso*, (section | categories))>
    
    <!ATTLIST faq metafile   CDATA        #REQUIRED
                  all-in-one (yes | no ) "no"
                  upgrade    CDATA        #IMPLIED
    >
    
    <!ELEMENT categories (categoryfile*)>
    
    <!ELEMENT categoryfile (#PCDATA)>
    
    <!ELEMENT description %Inline;>
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/manualpage.dtd�������������������������������������������������������0000664�0001751�0001751�00000002072�12273272705�021006� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='UTF-8' ?>
    
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
     contributor license agreements.  See the NOTICE file distributed with
     this work for additional information regarding copyright ownership.
     The ASF licenses this file to You under the Apache License, Version 2.0
     (the "License"); you may not use this file except in compliance with
     the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
    -->
    
    <!ENTITY % common SYSTEM "common.dtd">
    %common;
    
    <!-- <manualpage> is the root element -->
    <!ELEMENT manualpage (parentdocument?, title, summary?,
    seealso*, section*)>
    
    <!ATTLIST manualpage metafile CDATA  #REQUIRED
                         upgrade  CDATA  #IMPLIED
    >
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/build.properties�����������������������������������������������������0000664�0001751�0001751�00000000741�12273272705�021415� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This file contains version specific properties
    
    # No xml files yet or anymore
    #noxml.fr = rewrite/rewrite_guide.html.fr rewrite/rewrite_guide_advanced.html.fr
    
    # This httpd version is not retired
    # (run build bootstrap on change)
    retired = no
     
    
    manpages.8 = \
        apachectl \
        fcgistarter \
        htcacheclean \
        httpd \
        rotatelogs \
        suexec
    
    manpages.1 = \
        ab \
        apxs \
        dbmmanage \
        htdbm \
        htdigest \
        htpasswd \
        httxt2dbm \
        logresolve
    �������������������������������httpd-2.4.64/docs/manual/style/lang.dtd�������������������������������������������������������������0000664�0001751�0001751�00000001613�10455053115�017605� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='UTF-8' ?>
    
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
     contributor license agreements.  See the NOTICE file distributed with
     this work for additional information regarding copyright ownership.
     The ASF licenses this file to You under the Apache License, Version 2.0
     (the "License"); you may not use this file except in compliance with
     the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
    -->
    
    <!ENTITY % HTTPD-VERSION SYSTEM "version.ent">
    %HTTPD-VERSION;
    
    <!ENTITY nbsp "&#160;">
    
    ���������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/style/sitemap.dtd����������������������������������������������������������0000664�0001751�0001751�00000002621�12273272705�020336� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0' encoding='UTF-8' ?>
    
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
     contributor license agreements.  See the NOTICE file distributed with
     this work for additional information regarding copyright ownership.
     The ASF licenses this file to You under the Apache License, Version 2.0
     (the "License"); you may not use this file except in compliance with
     the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
    -->
    
    <!ENTITY % common SYSTEM "common.dtd">
    %common;
    
    <!-- <sitemap> is the root element -->
    <!ELEMENT sitemap (title, summary?, seealso*, category*)>
    
    <!ATTLIST sitemap metafile CDATA  #REQUIRED
                      upgrade  CDATA  #IMPLIED
    >
    
    <!-- <indexpage> is another root element -->
    <!ELEMENT indexpage (parentdocument, title, category*)>
    
    <!ATTLIST indexpage metafile CDATA  #REQUIRED
                        upgrade  CDATA  #IMPLIED
    >
    
    <!ELEMENT category (title, page*)>
    <!ATTLIST category id ID #IMPLIED>
    
    <!ELEMENT page (#PCDATA)>
    <!ATTLIST page href CDATA #IMPLIED
                   separate (yes | no) "no" >
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/configuring.html.de��������������������������������������������������������0000664�0001751�0001751�00000041325�14744525602�020634� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Konfigurationsdateien - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Konfigurationsdateien</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/configuring.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
        <p>Dieses Dokument beschreibt die Dateien, die zur Konfiguration des Apache
          HTTP Servers verwendet werden.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#main">Hauptkonfigurationsdateien</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#syntax">Syntax der Konfigurationsdateien</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Module</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#scope">Der G&#252;ltigkeitsbereich von Direktiven</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#htaccess">.htaccess-Dateien</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">Hauptkonfigurationsdateien</a></h2>
        
        <table class="related"><tr><th>Referenzierte Module</th><th>Referenzierte Direktiven</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#include">Include</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code></li></ul></td></tr></table>
    
        <p>Der Apache wird konfiguriert, indem <a href="mod/directives.html">Direktiven</a> in einfache Textdateien
          eingetragen werden. Die Hauptkonfigurationsdatei hei&#223;t
          &#252;blicherweise <code>httpd.conf</code>. Der Ablageort dieser Datei
          wird bei der Kompilierung festgelegt, kann jedoch mit der
          Befehlszeilenoption <code>-f</code> &#252;berschrieben werden. Durch
          Verwendung der Direktive  <code class="directive"><a href="./mod/core.html#include">Include</a></code>
          k&#246;nnen au&#223;erdem weitere Konfigurationsdateien hinzugef&#252;gt
          werden. Zum Einf&#252;gen von mehreren Konfigurationsdateien k&#246;nnen
          Platzhalter verwendet werden. Jede Direktive darf in jeder dieser
          Konfigurationsdateien angegeben werden. &#196;nderungen in den
          Hauptkonfigurationsdateien werden vom Apache nur beim Start oder Neustart
          erkannt.</p>
    
        <p>Der Server liest auch eine Datei mit MIME-Dokumenttypen ein. Der
          Name dieser Datei wird durch die Direktive <code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code> bestimmt. Die Voreinstellung
          ist <code>mime.types</code>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="syntax" id="syntax">Syntax der Konfigurationsdateien</a></h2>
        
    
        <p>Die Konfigurationsdateien des Apache enthalten eine Direktive pro Zeile.
          Der Backslash "\" l&#228;&#223;t sich als letztes Zeichen in einer Zeile
          dazu verwenden, die Fortsetzung der Direktive in der n&#228;chsten Zeile
          anzuzeigen. Es darf kein weiteres Zeichen oder Whitespace zwischen dem
          Backslash und dem Zeilenende folgen.</p>
    
        <p>In den Konfigurationsdateien wird bei den Direktiven nicht zwischen
          Gro&#223;- und Kleinschreibung unterschieden. Bei den Argumenten der
          Direktiven wird dagegen oftmals zwischen Gro&#223;- und Kleinschreibung
          differenziert. Zeilen, die mit dem Doppelkreuz "#" beginnen, werden als
          Kommentare betrachtet und ignoriert. Kommentare d&#252;rfen
          <strong>nicht</strong> am Ende einer Zeile nach der Direktive
          eingef&#252;gt werden. Leerzeilen und Whitespaces vor einer Direktive
          werden ignoriert. Dadurch lassen sich Direktiven zur besseren Lesbarbeit
          einr&#252;cken.</p>
    
        <p>Sie k&#246;nnen die Syntax Ihrer Konfigurationsdateien auf Fehler
          pr&#252;fen, ohne den Server zu starten, indem Sie <code>apachectl
            configtest</code> oder die Befehlszeilenoption <code>-t</code>
          verwenden.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="modules" id="modules">Module</a></h2>
        
    
        <table class="related"><tr><th>Referenzierte Module</th><th>Referenzierte Direktiven</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>Der Apache ist ein modularer Server. Das bedeutet, dass nur die abolute
          Grundfunktionalit&#228;t im Kernserver enthalten ist. Weitergehende
          F&#228;higkeiten sind mittels <a href="mod/">Modulen</a> verf&#252;gbar,
          die in den Apache geladen werden k&#246;nnen. Standardm&#228;&#223;ig
          wird bei der Kompilierung ein Satz von Basismodulen <span class="transnote">(<em>Anm.d.&#220;.:</em> die so
            genannten <a href="mod/module-dict.html#Status">Base</a>-Module)</span> in den Server eingebunden. Wenn der
          Server f&#252;r die Verwendung von <a href="dso.html">dynamisch
            ladbaren</a> Modulen kompiliert wurde, dann k&#246;nnen Module separat
          kompiliert und jederzeit mittels der Direktive <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> hinzugef&#252;gt werden.
          Andernfalls muss der Apache neu kompiliert werden, um Module
          hinzuzuf&#252;gen oder zu entfernen. Konfigurationsanweisungen k&#246;nnen
          abh&#228;ngig vom Vorhandensein eines bestimmten Moduls eingesetzt werden,
          indem sie in einen <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>-Block eingeschlossen werden.</p>
    
        <p>Um zu sehen, welche Module momentan in den Server einkompiliert sind,
          kann die Befehlszeilenoption <code>-l</code> verwendet werden.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="scope" id="scope">Der G&#252;ltigkeitsbereich von Direktiven</a></h2>
        
    
        <table class="related"><tr><th>Referenzierte Module</th><th>Referenzierte Direktiven</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>Direktiven in den Hauptkonfigurationsdateien gelten f&#252;r den
          gesamten Server. Wenn Sie die Konfiguration nur f&#252;r einen Teil des
          Servers ver&#228;ndern m&#246;chten, k&#246;nnen Sie den
          G&#252;ltigkeitsbereich der Direktiven beschr&#228;nken, indem Sie diese
          in <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>-,
          <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>-,
          <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>-,
          <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>-,
          <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>- oder
          <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>-Abschnitte eingef&#252;gen.
          Diese Abschnitte begrenzen die Anwendung der umschlossenen Direktiven
          auf bestimmte Pfade des Dateisystems oder auf
          bestimmte URLs. Sie k&#246;nnen f&#252;r eine fein abgestimmte
          Konfiguration auch ineinander verschachtelt werden.</p>
        
        
        <p>Der Apache besitzt die F&#228;higkeit, mehrere verschiedene Websites
          gleichzeitig zu bedienen. Dies wird <a href="vhosts/">virtuelles
            Hosten</a> genannt. Direktiven k&#246;nnen auch in ihrem
          G&#252;ltigkeitsgereich eingeschr&#228;nkt werden, indem sie innerhalb
          eines <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Abschnittes angegeben werden.
          Sie werden dann nur auf Anfragen f&#252;r eine bestimmte Website
          angewendet.</p>
    
        <p>Obwohl die meisten Direktiven in jedem dieser Abschnitte platziert
          werden k&#246;nnen, ergeben einige Direktiven in manchen Kontexten
          keinen Sinn. Direktiven zur Prozesssteuerung beispielsweise
          d&#252;rfen nur im Kontext des Hauptservers angegeben werden. Pr&#252;fen
          Sie den <a href="mod/directive-dict.html#Context">Kontext</a> der
          Direktive, um herauszufinden, welche Direktiven in welche Abschnitte
          eingef&#252;gt werden k&#246;nnen.  Weitere Informationen finden Sie unter
          "<a href="sections.html">Wie Directory-, Location- und Files-Abschnitte
            arbeiten</a>".</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">.htaccess-Dateien</a></h2>
        
    
        <table class="related"><tr><th>Referenzierte Module</th><th>Referenzierte Direktiven</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
    
        <p>Der Apache erm&#246;glicht die dezentrale Verwaltung der
          Konfiguration mittes spezieller Dateien innerhalb des
          Web-Verzeichnisbaums. Diese speziellen Dateien hei&#223;en
          gew&#246;hnlich <code>.htaccess</code>, mit der Direktive <code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code> kann jedoch auch ein anderer
          Name festgelegt werden. In <code>.htaccess</code>-Dateien angegebene
          Direktiven werden auf das Verzeichnis und dessen Unterverzeichnisse
          angewendet, in dem die Datei abgelegt ist. <code>.htaccess</code>-Dateien
          folgen der gleichen Syntax wie die Hauptkonfigurationsdateien. Da
          <code>.htaccess</code>-Dateien bei jeder Anfrage eingelesen werden,
          werden &#196;nderungen in diesen Dateien sofort wirksam.</p>
    
        <p>Pr&#252;fen Sie den <a href="mod/directive-dict.html#Context">Kontext</a> der Direktive, um
          herauszufinden, welche Direktiven in <code>.htaccess</code>-Dateien
          angegeben werden k&#246;nnen. Dar&#252;ber hinaus steuert der
          Serveradministrator mit der Einstellung der Direktive <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> in den
          Hauptkonfigurationsdateien welche Direktiven in
          <code>.htaccess</code>-Dateien verwendet werden d&#252;rfen.</p>
    
        <p>Weitere Informationen &#252;ber <code>.htaccess</code>-Dateien finden
          Sie in der <a href="howto/htaccess.html">.htaccess-Einf&#252;hrung</a>.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/configuring.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/configuring.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/install.html.de������������������������������������������������������������0000664�0001751�0001751�00000063077�14744525602�020000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Kompilieren und Installieren - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Kompilieren und Installieren</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/install.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
        <p>Dieses Dokument umfa&#223;t nur die Kompilierung und Installation des
        Apache auf Unix und Unix-&#228;hnlichen Systemen. F&#252;r die
        Kompilierung und Installation unter Windows lesen Sie bitte <a href="platform/windows.html">Den Apache unter Microsoft Windows
        betreiben</a>. F&#252;r andere Plattformen lesen Sie bitte die
        Dokumentation <a href="platform/">Plattformen</a>.</p>
    
        <p>Die Konfigurations- und Installationsumgebung des Apache 2.0 hat sich
        seit dem Apache 1.3 komplett ver&#228;ndert. Der Apache 1.3 benutzt einen
        speziellen Satz von Skripten, um eine einfache Installation zu
        erm&#246;glichen. Der Apache 2.0 dagegen verwendet nun
        <code>libtool</code> und <code>autoconf</code>, um eine Umgebung zu
        schaffen, die der vieler anderer Open Source Projekte &#228;hnlich
        sieht.</p>
    
        <p>Wenn Sie von einer Unterversion auf die n&#228;chste aktualisieren (z.B.
        von 2.0.50 auf 2.0.51), springen Sie bitte zum Abschnitt <a href="#upgrading">Upgrade</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">&#220;berblick f&#252;r die Ungeduldigen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#requirements">Anforderungen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#download">Download</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extract">Auspacken</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configure">Den Codebaum konfigurieren</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compile">Erstellen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">Installieren</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#customize">Anpassen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#test">Testen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#upgrading">Upgrade</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><a href="programs/configure.html">Den Quellcode konfigurieren</a></li><li><a href="invoking.html">Apache starten</a></li><li><a href="stopping.html">Beenden und Neustarten</a></li><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">&#220;berblick f&#252;r die Ungeduldigen</a></h2>
    
        <table>
          
          <tr>
            <td><a href="#download">Download</a></td>
    
            <td><code>$ lynx http://httpd.apache.org/download.cgi</code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#extract">Auspacken</a></td>
    
            <td><code>$ gzip -d httpd-2_1_<em>NN</em>.tar.gz<br />
             $ tar xvf httpd-2_1_<em>NN</em>.tar</code> </td>
          </tr>
    
          <tr>
            <td><a href="#configure">Konfigurieren</a></td>
    
            <td><code>$ ./configure --prefix=<em>PREFIX</em></code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#compile">Kompilieren</a></td>
    
            <td><code>$ make</code> </td>
          </tr>
    
          <tr>
            <td><a href="#install">Installieren</a></td>
    
            <td><code>$ make install</code> </td>
          </tr>
    
          <tr>
            <td><a href="#customize">Anpassen</a></td>
    
            <td><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code> </td>
          </tr>
    
          <tr>
            <td><a href="#test">Testen</a></td>
    
            <td><code>$ <em>PREFIX</em>/bin/apachectl start</code>
            </td>
          </tr>
        </table>
    
        <p><em>NN</em> muss durch die Nummer der Unterversion ersetzt werden,
        und <em>PREFIX</em> durch den Verzeichnispfad,
        in dem der Server installiert werden soll. Wenn <em>PREFIX</em> nicht
        angegeben ist, wird die Voreinstellung <code>/usr/local/apache2</code>
        verwendet.</p>
    
        <p>Beginnend mit den Anforderungen
        f&#252;r die Kompilierung und Installation des Apache HTTPD ist
        weiter unten jeder Abschnitt des Kompilierungs- und
        Installationsvorganges genauer beschrieben.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">Anforderungen</a></h2>
    
        <p>Folgende Anforderungen gelten f&#252;r die Erstellung des
        Apache:</p>
    
        <dl>
          <dt>Plattenplatz</dt>
          <dd>Stellen Sie sicher, dass Sie kurzzeitig wenigstens 50 MB freien
          Festplattenplatz zur Verf&#252;gung haben. Nach der Installation
          belegt der Apache ungef&#228;hr 10 MB Plattenplatz. Der
          tats&#228;chliche Platzbedarf variiert in Abh&#228;ngigkeit von den
          gew&#228;hlten Konfigurationseinstellungen und
          Modulen von Drittanbietern.</dd>
    
          <dt>ANSI-C-Compiler und Generierungswerkzeuge</dt>
          <dd>Stellen Sie sicher, dass Sie einen ANSI-C Compiler installiert
          haben. Der <a href="http://www.gnu.org/software/gcc/gcc.html">GNU C
          Compiler (GCC)</a> der <a href="http://www.gnu.org/">Free Software
          Foundation (FSF)</a> 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&#223;erdem muss Ihr
          <code>PATH</code> wesentliche Generierungswerkzeuge wie
          <code>make</code> enthalten.</dd>
    
          <dt>Zeitgenauigkeit bewahren</dt>
          <dd>Elemente des HTTP-Protokolls werden in Form einer Tageszeit
          ausgedr&#252;ckt. Darum sollten Sie jetzt pr&#252;fen, ob Ihr System
          die F&#228;higkeit zur Zeitsynchronisation besitzt, und diese
          gegebenenfalls installieren. &#220;blicherweise werden hierf&#252;r
          die Programme <code>ntpdate</code> oder <code>xntpd</code> verwendet,
          die auf dem Network Time Protocol (NTP) basieren. N&#228;here
          Informationen &#252;ber NTP Software und &#246;ffentliche Zeitserver
          finden Sie in der Usenet Newsgroup <a href="news:comp.protocols.time.ntp">comp.protocols.time.ntp</a>
          und auf der <a href="http://www.ntp.org">NTP
          Homepage</a>.</dd>
    
          <dt><a href="http://www.perl.org/">Perl 5</a>
          [OPTIONAL]</dt>
          <dd>F&#252;r einige Hilfsskripte wie <code class="program"><a href="./programs/apxs.html">apxs</a></code>
          oder <code class="program"><a href="./programs/dbmmanage.html">dbmmanage</a></code> (die in Perl
          geschrieben sind) wird der Perl 5 Interpreter ben&#246;tigt (die
          Versionen ab 5.003 sind ausreichend). Wenn Sie mehrere Perl
          Interpreter haben (beispielsweise eine systemweite Installation von
          Perl 4 und Ihre eigene Perl 5-Installation), dann sollten Sie die
          <code>--with-perl</code>-Option (siehe unten) verwenden, um
          sicherzustellen, dass der richtige Interpreter von
          <code class="program"><a href="./programs/configure.html">configure</a></code> ausgew&#228;hlt wird.
          Wenn kein Perl 5-Interpreter vom <code class="program"><a href="./programs/configure.html">configure</a></code>-Skript
          gefunden werden kann, k&#246;nnen Sie die betroffenen Hilfsskripte nicht
          verwenden, sind jedoch selbstverst&#228;ndlich nach wie vor in der Lage,
          den Apache 2.0 zu bauen und zu installieren.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="download" id="download">Download</a></h2>
    
        <p>Der Apache kann von der <a href="http://httpd.apache.org/download.cgi">Apache HTTP Server
        Downloadseite</a> heruntergeladen werden, auf der verschiedene Spiegelserver
        angegeben sind. F&#252;r die meisten Benutzer des Apache ist es auf
        Unix-&#228;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&#252;rfnissen anzupassen.
        Dazu kommt, dass Bin&#228;rdistributionen gegen&#252;ber der aktuellen
        Quellcodeversion oft veraltet sind. Wenn Sie tats&#228;chlich ein
        Bin&#228;rpaket herunterladen, folgen Sie bitte den Anweisungen in der Datei
        <code>INSTALL.bindist</code>, die der Distribution beiliegt.</p>
    
        <p>Es ist wichtig, dass Sie nach dem Herunterladen &#252;berpr&#252;fen,
        dass es sich um einer vollst&#228;ndige und unver&#228;nderte Version des
        Apache HTTP Servers handelt. Das k&#246;nnen Sie erreichen, indem Sie das
        heruntergeladene Paket gegen die PGP-Signatur pr&#252;fen. Einzelheiten dazu
        erfahren Sie auf der <a href="http://httpd.apache.org/download.cgi#verify">Download-Seite</a>. Es
        ist auch ein erweitertes Beispiel verf&#252;gbar, dass die <a href="http://httpd.apache.org/dev/verification.html">Anwendung von PGP</a>
        beschreibt.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extract" id="extract">Auspacken</a></h2>
    
        <p>Das Auspacken des Quellcodes aus dem Apache HTTPD Tarball besteht
        aus einem simplen Dekomprimieren und danach "Ent-tarren":</p>
    
      <div class="example"><p><code>
          $ gzip -d httpd-2_1_<em>NN</em>.tar.gz<br />
          $ tar xvf httpd-2_1_<em>NN</em>.tar
      </code></p></div>
    
        <p>Dies erstellt unterhalb des aktuellen Verzeichnisses ein neues
        Verzeichnis, das den Quellcode f&#252;r die Distribution enth&#228;lt.
        Sie sollten mit <code>cd</code> in dieses Verzeichnis wechseln,
        bevor Sie mit der Kompilierung des Servers weitermachen. </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">Den Codebaum konfigurieren</a></h2>
    
        <p>Der n&#228;chste Schritt ist die Konfiguration des
        Apache-Codebaumes f&#252;r Ihre spezielle Plattform und Ihre
        pers&#246;nlichen Bed&#252;rfnisse. Dies wird mit dem Skript
        <code class="program"><a href="./programs/configure.html">configure</a></code> durchgef&#252;hrt, das im Wurzelverzeichnis
        der Distribution enthalten ist. (Entwickler, welche die CVS Version
        des Apache-Codebaumes herunterladen, m&#252;ssen <code>autoconf</code>
        und <code>libtool</code> installiert haben und m&#252;ssen
        <code>buildconf</code> ausf&#252;hren, bevor sie mit den
        n&#228;chsten Schritten fortfahren k&#246;nnen. Dies wird bei
        offiziellen Releases nicht notwendig sein.)</p>
    
        <p>Um den Codebaum mit den Standardeinstellungen zu konfigurieren,
        geben Sie einfach <code>./configure</code> ein. Zur &#196;nderung
        dieser Voreinstellungen akzeptiert <code class="program"><a href="./programs/configure.html">configure</a></code> eine
        Reihe von Variablen und Kommandozeilenoptionen.</p>
    
        <p>Die wichtigste Option ist <code>--prefix</code>, der Ablageort, an dem
        der Apache sp&#228;ter installiert wird, da er f&#252;r diesen Ort
        konfiguriert werden muss, um korrekt zu arbeiten. Eine feinere Einstellung
        der Dateiablagen ist mit weiteren <a href="programs/configure.html#installationdirectories">configure-Optionen</a>
        m&#246;glich.</p>
    
        <p>Weiterhin k&#246;nnen Sie zu diesem Zeitpunkt festlegen, welche <a href="programs/configure.html#optionalfeatures">Funktionalit&#228;t</a> Sie
        in den Apache aufnehmen m&#246;chten, indem Sie <a href="mod/">Module</a>
        aktivieren oder deaktivieren. Der Apache bindet standardm&#228;&#223;ig
        einen Satz von <a href="mod/module-dict.html#Status">Basismodulen</a> ein.
        Andere Module werden mit Hilfe der Option
        <code>--enable-<var>module</var></code> aktiviert, wobei <var>module</var>
        den Namen des Moduls ohne das Pr&#228;fix <code>mod_</code> darstellt.
        Ausserdem sind alle Unterstriche durch Bindestriche zu ersetzen. Sie
        k&#246;nnen sich auch entscheiden, Module als "<a href="dso.html">Shared
        Objects (DSOs)</a>" zu kompilieren, welche zur Laufzeit ge- und entladen
        werden k&#246;nnen. Dazu verwenden Sie die Option
        <code>--enable-<var>module</var>=shared</code>. Entsprechend k&#246;nnen Sie
        Basismodule mit der Option <code>--disable-<var>module</var></code>
        deaktivieren. Lassen Sie Vorsicht walten. wenn Sie diese Optionen verwenden,
        da <code class="program"><a href="./programs/configure.html">configure</a></code> Sie nicht warnen kann, wenn die von Ihnen
        angegebenen Module nicht existieren; die Option wird dann einfach
        ignoriert.</p>
    
        <p>Zus&#228;tzlich ist es zuweilen notwendig, das
        <code class="program"><a href="./programs/configure.html">configure</a></code>-Skript mit Extrainformationen zum Ablageort
        Ihres Compilers, Ihrer Bibliotheken oder Header-Dateien zu versorgen. Das
        tun Sie, indem Sie entweder Umgebungsvariablen oder Kommandozeilenoptionen
        an <code class="program"><a href="./programs/configure.html">configure</a></code> &#252;bergeben. F&#252;r mehr Informationen
        lesen Sie bitte die Hilfeseite zu <code class="program"><a href="./programs/configure.html">configure</a></code>.</p>
    
        <p>Um einen kurzen Eindruck zu gewinnen, welche M&#246;glichkeiten Sie
        haben, folgt hier ein typisches Beispiel, das den Apache mit einem
        speziellen Compiler und Compilerflags f&#252;r das
        Installationsverzeichnis <code>/sk/pkg/apache</code> kompiliert, sowie
        die beiden zus&#228;tzlichen Module <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> und
        <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> f&#252;r sp&#228;teres Laden durch den
        DSO-Mechanismus:</p>
    
      <div class="example"><p><code>
          $ CC="pgcc" CFLAGS="-O2" \<br />
           ./configure --prefix=/sw/pkg/apache \<br />
           --enable-rewrite=shared \<br />
           --enable-speling=shared
      </code></p></div>
    
        <p>Wenn <code class="program"><a href="./programs/configure.html">configure</a></code> startet, ben&#246;tigt es mehrere
        Minuten, um die Verf&#252;gbarkeit von Features auf Ihrem System zu
        pr&#252;fen und ein Makefile zu generieren, das sp&#228;ter zur
        Kompilierung des Servers verwendet wird.</p>
    
        <p>Einzelheiten zu den vielen verschiedenen <code class="program"><a href="./programs/configure.html">configure</a></code>-Optionen finden Sie auf der Hilfeseite zu
        <code class="program"><a href="./programs/configure.html">configure</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile" id="compile">Erstellen</a></h2>
    
        <p>Nun k&#246;nnen Sie die verschiedenen Teile, die das Apache-Paket
        bilden, einfach durch Ausf&#252;hren des folgenden Befehls erstellen:</p>
    
      <div class="example"><p><code>$ make</code></p></div>
    
        <p>Seien Sie hierbei bitte geduldig, denn eine Basiskonfiguration
        ben&#246;tigt ungef&#228;hr 3 Minuten auf einem Pentium III/Linux 2.2.
        System. Dies kann aber abh&#228;ngig von Ihrer Hardware und der Anzahl
        der Module, die Sie aktiviert haben, sehr stark variieren.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">Installieren</a></h2>
    
        <p>Nun endlich installieren Sie das Package unter dem konfigurierten
        Installations-<em>PREFIX</em> (siehe oben: Option <code>--prefix</code>
        durch Aufrufen von:</p>
    
      <div class="example"><p><code>$ make install</code></p></div>
    
        <p>Wenn Sie upgraden, wird die Installation Ihre Konfigurationsdateien
        oder Dokumente nicht &#252;berschrieben.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customize" id="customize">Anpassen</a></h2>
    
        <p>Als n&#228;chstes k&#246;nnen Sie Ihren Apache HTTP Server anpassen,
        indem Sie die <a href="configuring.html">Konfigurationsdateien</a>
        unterhalb von <code><em>PREFIX</em>/conf/</code> editieren.</p>
    
      <div class="example"><p><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code></p></div>
    
        <p>Werfen Sie auch einen Blick in das Apache-Handbuch unter <a href="./">docs/manual/</a>. Die aktuellste Version dieses Handbuchs
        sowie eine komplette Referenz der verf&#252;gbaren <a href="mod/directives.html">Konfigurationsanweisungen</a> finden
        Sie unter <a href="http://httpd.apache.org/docs/2.4/">http://httpd.apache.org/docs/2.4/</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="test" id="test">Testen</a></h2>
    
        <p>Sie k&#246;nnen nun Ihren Apache HTTP Server <a href="invoking.html">starten</a>, indem Sie einfach</p>
    
      <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl start</code></p></div>
    
        <p>ausf&#252;hren.</p>
    
        <p>Danach sollten Sie Ihr erstes Dokument unter dem URL
        <code>http://localhost/</code> anfordern k&#246;nnen. Die Webseite,
        die Sie sehen, ist im <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        abgelegt, welches &#252;blicherweise <code><em>PREFIX</em>/htdocs/</code>
        ist. Den Server <a href="stopping.html">stoppen</a> Sie wieder durch
        Ausf&#252;hren von:</p>
    
      <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl stop</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">Upgrade</a></h2>
    
        <p>Der erste Schritt beim Aktualisieren besteht darin, die
        Versionsank&#252;ndigung sowie die <code>CHANGES</code>-Datei in der
        Quelltextdistribution zu lesen, um &#196;nderungen zu finden, die Ihr
        System m&#246;glicherweise betreffen. Wenn Sie einen gr&#246;&#223;eren
        Versionssprung durchf&#252;hren (z.B. vom 1.3 auf 2.0 oder von 2.0 auf
        2.2), wird es wahrscheinlich auch gr&#246;&#223;ere Unterschiede in der
        Kompilier- und Laufzeitkonfiguration geben, die manuelle Nacharbeiten
        erfordern. Au&#223;erdem m&#252;ssen alle Module aktualisiert
        werden, um den &#196;nderungen der Modul-API gerecht zu werden.</p>
    
        <p>Die Aktualisierung einer Unterversion auf eine andere (z.B. von 2.0.55
        auf 2.0.57) ist einfacher. <code>make install</code> &#252;berschreibt
        keine der bereits existierenden Dokumente, Log- und Konfigurationsdateien.
        Ausserdem bem&#252;hen sich die Entwickler, inkompatible &#196;nderungen
        der <code class="program"><a href="./programs/configure.html">configure</a></code>-Optionen, der Laufzeitkonfiguration sowie
        der Modul-API zu vermeiden. In den meisten F&#228;llen sollten Sie in der
        Lage sein, den gleichen <code class="program"><a href="./programs/configure.html">configure</a></code>-Befehl, die gleiche
        Konfiguration und die gleichen Module wieder zu verwenden. (Das gilt erst
        seit Version 2.0.41 -- fr&#252;here Versionen enthielten noch inkompatible
        &#196;nderungen).</p>
    
        <p>Um auf eine neue Unterversion zu aktualisieren, suchen Sie zun&#228;chst
        die Datei <code>config.nice</code> im <code>build</code>-Verzeichnis
        Ihrer Serverinstallation oder im Wurzelverzeichnis des Quelltextbaums
        der alten Installation. Die Datei enth&#228;lt den genauen
        <code class="program"><a href="./programs/configure.html">configure</a></code>-Befehl, der verwendet wurde, um den
        Quellcode zu konfigurieren. Um jetzt von einer Version auf die
        n&#228;chste zu aktualisieren, kopieren Sie einfach die
        <code>config.nice</code> in das Verzeichnis der neuen Version,
        passen sie bei Bedarf an, und f&#252;hren Sie sie aus:</p>
    
        <div class="example"><p><code>
          $ ./config.nice<br />
          $ make<br />
          $ make install<br />
          $ <var>PREFIX</var>/bin/apachectl stop<br />
          $ <var>PREFIX</var>/bin/apachectl start<br />
        </code></p></div>
    
        <div class="warning">Sie sollten jede neue Version immer in Ihrer Umgebung
        testen, bevor Sie sie produktiv schalten. Beispielsweise k&#246;nnen Sie
        die neue Version neben der alten installieren, indem Sie ein anderes
        <code>--prefix</code> und einen anderen Port w&#228;hlen (durch Anpassen der
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>-Direktive). So
        k&#246;nnen Sie auf eventuelle Inkompatibilit&#228;ten testen, bevor Sie
        endg&#252;ltig die neue Version verwenden.</div>
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/install.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/install.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/bind.html.de���������������������������������������������������������������0000664�0001751�0001751�00000036436�14744525602�017245� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>An Adressen und Ports binden - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>An Adressen und Ports binden</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/bind.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
        <p>Konfiguration der vom Apache HTTP Server verwendeten Adressen und
        Ports.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">&#220;berblick</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ipv6">Betrachtung von IPv6-Besonderheiten</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#protocol">Angabe des Protokolls bei Listen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Das Zusammenspiel mit virtuellen Hosts</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><a href="vhosts/">Virtuelle Hosts</a></li><li><a href="dns-caveats.html">Probleme bez&#252;glich DNS und
        Apache</a></li><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">&#220;berblick</a></h2>
        
    
        <table class="related"><tr><th>Referenzierte Module</th><th>Referenzierte Direktiven</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mpm_common.html">mpm_common</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code></li></ul></td></tr></table>
    
        <p>Beim Start bindet sich der httpd an bestimmte Adressen und Ports
        der lokalen Maschine und wartet auf eingehende Anfragen.
        Standardm&#228;&#223;ig lauscht er an allen Adressen des Systems.
        Es kann jeodch notwendig sein, ihm mit zuteilen, nur an bestimmten
        Ports zu lauschen oder nur an ausgew&#228;hlten Adressen, bzw. einer
        Kombination aus beidem. Dies wird oft mit der Funktionalit&#228;t <a href="vhosts/">virtueller Hosts</a> kombiniert, die bestimmt, wie
        der <code>httpd</code> auf verschiedene IP-Adressen, Hostnamen und
        Ports reagiert.</p>
    
        <p>Die Direktive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        weist den Server an, eingehende Anfragen nur an bestimmten Port(s)
        oder Adress/Port-Kombinationen zu akzeptieren. Wenn bei der
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>-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&#246;nnen mehrere <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>-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&#246;rten Adressen und Ports antworten.</p>
    
        <p>Um beispielsweise den Server zu veranlassen, auf allen
        Netzwerkinterfaces sowohl an Port 80, als auch an Port 8000
        Verbindungen zu akzeptieren, geben Sie an:</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 80
    Listen 8000</pre>
    </div>
    
        <p>Um den Server Verbindungen an Port 80 auf einem Netzwerkinterface
        akzeptieren zu lassen und an Port 8080 auf einem anderen Interface, geben
        Sie an:</p>
          
        <div class="example"><pre class="prettyprint lang-config">Listen 192.0.2.1:80
    Listen 192.0.2.5:8000</pre>
    </div>
    
        <p>IPv6-Adressen m&#252;ssen wie im folgenden Beispiel in eckigen
          Klammern angegeben werden:</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen [2001:db8::a00:20ff:fea7:ccea]:80</pre>
    </div>
    
        <div class="warning"><p>Sich &#252;berlappende <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>-Direktiven generieren einen
        fatalen Fehler, der verhindert, dass der Server hochf&#228;hrt.</p>
    
        <div class="example"><p><code>
          (48)Address already in use: make_sock: could not bind to address [::]:80
        </code></p></div>
    
        <p><a href="http://wiki.apache.org/httpd/CouldNotBindToAddress">Diese
        Diskussion im Wiki</a> gibt weitere Tipps zur Fehlerbehebung.</p>
        </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipv6" id="ipv6">Betrachtung von IPv6-Besonderheiten</a></h2>
        
    
        <p>Eine wachsende Anzahl von Plattformen implementiert IPv6. Die
        <a class="glossarylink" href="./glossary.html#apr" title="siehe Glossar">APR</a> unterst&#252;tzt IPv6 auf den meisten
        dieser Plattformen und erm&#246;glicht dem httpd, IPv6-Sockets zu
        verwenden und &#252;ber IPv6 gesendete Anfragen zu behandeln.</p>
    
        <p>F&#252;r httpd-Administratoren kommt erschwerend die Frage hinzu,
        ob IPv6-Sockets sowohl IPv4- als auch IPv6-Verbindungen handhaben
        k&#246;nnen. Zum Betrieb von IPv4-Verbindungen an IPv6-Sockets
        werden auf IPv6 abgebildete IPv4-Adressen <span class="transnote">(<em>Anm.d.&#220;.:</em> so genannete
        IPv4-gemappte IPv6-Adressen)</span> verwendet, welche
        standardm&#228;&#223;ig auf den meisten Plattformen erlaubt sind.
        Unter FreeBSD, NetBSD und OpenBSD jedoch sind sie
        standardm&#228;&#223;ig deaktiviert, um den Systemgrunds&#228;tzen
        dieser Plattformen zu entsprechen. Auf Systemen, wo dies
        standardm&#228;&#223;ig dekativiert ist, kann dieses Verhalten mit
        einem speziellen <code class="program"><a href="./programs/configure.html">configure</a></code>-Parameter f&#252;r den
        httpd ge&#228;ndert werden.</p>
    
        <p>Auf der anderen Seite ist die Verwendung von gemappten Adressen
        bei einigen Plattformen wie Linux und True64 der
        <strong>einzige</strong> Weg, sowohl IPv4 wie auch IPv6 zu
        verwenden. Wenn Sie m&#246;chten, dass der <code>httpd</code> IPv4-
        und IPv6-Verbindungen mit einem Minimum an Sockets behandelt, was
        die Verwendung von IPv4-gemappten IPv6-Adressen erfordert, dann
        m&#252;ssen Sie die <code class="program"><a href="./programs/configure.html">configure</a></code>-Option
        <code>--enable-v4-mapped</code> angeben.</p>
    
        <p><code>--enable-v4-mapped</code> ist die Voreinstellung auf allen
        Plattformen au&#223;er FreeBSD, NetBSD und OpenBSD, so dass Ihr
        httpd wahrscheinlich so &#252;bersetzt wurde.</p>
    
        <p>Geben Sie wie in dem folgenden Beispiel bei allen <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>-Anweisungen eine IPv4-Adresse
        an, wenn Sie m&#246;chten, dass Ihr httpd lediglich IPv4-Adressen
        behandelt, unabh&#228;ngig davon, was Ihre Plattform und die APR
        unterst&#252;tzen:</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 0.0.0.0:80
    Listen 192.0.2.1:80</pre>
    </div>
    
        <p>Wenn Sie m&#246;chten, dass der httpd IPv4- und IPv6-Verbindungen
        an separaten Sockets behandelt (d.h. IPv4-gemappte Adressen
        deaktiviert werden sollen) und Ihre Plattform es unterst&#252;tzt,
        dann m&#252;ssen Sie die <code class="program"><a href="./programs/configure.html">configure</a></code>-Option
        <code>--disable-v4-mapped</code> angeben.  Unter FreeBSD, NetBSD und
        OpenBSD ist <code>--disable-v4-mapped</code> voreingestellt.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="protocol" id="protocol">Angabe des Protokolls bei Listen</a></h2>
        
        <p>Das optionale zweite <var>Protokoll</var>-Argument von <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> ist f&#252;r die meisten
        Konfigurationen gar nicht erforderlich. Wenn nicht angegeben, sind
        <code>https</code> f&#252;r Port 443 und <code>http</code> f&#252;r
        alle anderen Ports die Voreinstellungen. Die Protokollangabe wird
        sowohl dazu verwendet, herauszufinden, welches Modul Anfragen
        verarbeiten soll, als auch, um protokollspezifische Optimierungen
        bei der <code class="directive"><a href="./mod/core.html#acceptfilter">AcceptFilter</a></code>-Direktive
        zu aktivieren.</p>
    
        <p>Sie m&#252;ssen das Protokoll nur angeben, wenn Sie
        ungew&#246;hnliche Ports benutzen, beispielsweise <code>https</code>
        auf Port 8443:</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 192.170.2.1:8443 https</pre>
    </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Das Zusammenspiel mit virtuellen Hosts</a></h2>
        
    
        <p>Die Direktive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        implementiert keine virtuellen Hosts - sie teilt dem Hauptserver
        lediglich mit, an welchen Adressen und Ports er zu lauschen hat.
        Werden keine <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Container verwendet, dann
        verh&#228;lt sich der Server bei allen angenommenen Anfragen gleich.
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Abschnitte k&#246;nnen jedoch
        dazu verwendet werden, ein unterschiedliches Verhalten f&#252;r eine
        oder mehrere Adressen und Ports festzulegen. Um einen virtuellen
        Host einzurichten, muss dem Server zun&#228;chst mitgeteilt werden,
        an den betreffenden Adressen oder Ports zu lauschen. Dann sollte ein
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Abschnitt f&#252;r die
        angebene Adresse und den angegebenen Port erstellt werden, um das
        Verhalten dieses virtuellen Hosts festzulegen. Beachten Sie bitte,
        dass auf einen <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> nicht zugegriffen werden
        kann, wenn er f&#252;r eine Adresse und einen Port eingerichtet
        wurde, an dem der Server nicht lauscht.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/bind.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/bind.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/mpm.html.en����������������������������������������������������������������0000664�0001751�0001751�00000032406�14737241666�017134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Multi-Processing Modules (MPMs) - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Multi-Processing Modules (MPMs)</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>This document describes what a Multi-Processing Module is and
    how they are used by the Apache HTTP Server.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#defaults">MPM Defaults</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#static">Building an MPM as a static module</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#dynamic">Building an MPM as a DSO module</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    
        <p>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 httpd 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.</p>
    
        <p>Apache HTTP Server 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.</p>
    
        <p>Extending the modular design to this level of the server
        allows two important benefits:</p>
    
        <ul>
          <li>Apache httpd can more cleanly and efficiently support a wide
          variety of operating systems. In particular, the Windows
          version of the server is now much more efficient, since
          <code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code> can use native
          networking features in place of the POSIX layer used in
          Apache httpd 1.3. This benefit also extends to other operating
          systems that implement specialized MPMs.</li>
    
          <li>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
          <code class="module"><a href="./mod/worker.html">worker</a></code> or <code class="module"><a href="./mod/event.html">event</a></code>, while sites requiring
          stability or compatibility with older software can use a
          <code class="module"><a href="./mod/prefork.html">prefork</a></code>.</li>
        </ul>
    
        <p>At the user level, MPMs appear much like other Apache httpd
        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 <a href="mod/">module index page</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="defaults" id="defaults">MPM Defaults</a></h2>
    
    <p>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.</p>
    
    <table class="bordered"><tr><td>Netware</td><td><code class="module"><a href="./mod/mpm_netware.html">mpm_netware</a></code></td></tr>
    <tr class="odd"><td>OS/2</td><td><code class="module"><a href="./mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
    <tr><td>Unix</td><td><code class="module"><a href="./mod/prefork.html">prefork</a></code>, <code class="module"><a href="./mod/worker.html">worker</a></code>, or
        <code class="module"><a href="./mod/event.html">event</a></code>, depending on platform capabilities</td></tr>
    <tr class="odd"><td>Windows</td><td><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code></td></tr>
    </table>
    
    <div class="note"><p>Here, 'Unix' is used to mean Unix-like operating systems, such as
    Linux, BSD, Solaris, Mac OS X, etc.</p></div>
    
    <p>In the case of Unix, the decision as to which MPM is installed is
    based on two questions:</p>
    <p>1. Does the system support threads?</p>
    <p>2. Does the system support thread-safe polling (Specifically, the
    kqueue and epoll functions)?</p>
    
    <p>If the answer to both questions is 'yes', the default MPM is
    <code class="module"><a href="./mod/event.html">event</a></code>.</p>
    
    <p>If The answer to #1 is 'yes', but the answer to #2 is 'no', the
    default will be <code class="module"><a href="./mod/worker.html">worker</a></code>.</p>
    
    <p>If the answer to both questions is 'no', then the default MPM will be
    <code class="module"><a href="./mod/prefork.html">prefork</a></code>.</p>
    
    <p>In practical terms, this means that the default will almost always be
    <code class="module"><a href="./mod/event.html">event</a></code>, as all modern operating systems support these
    two features.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="static" id="static">Building an MPM as a static module</a></h2>
    
        <p>MPMs can be built as static modules on all platforms.  A single MPM
        is chosen at build time and linked into the server.  The server must
        be rebuilt in order to change the MPM.</p>
    
        <p>To override the default MPM choice, use the
        <code>--with-mpm=<em>NAME</em></code> option of the
        <code class="program"><a href="./programs/configure.html">configure</a></code> script. <em>NAME</em> is the name of the
        desired MPM.</p>
    
        <p>Once the server has been compiled, it is possible to determine which MPM
        was chosen by using <code>./httpd -l</code>. This command will list every
        module that is compiled into the server, including the MPM.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dynamic" id="dynamic">Building an MPM as a DSO module</a></h2>
    
        <p>On Unix and similar platforms, MPMs can be built as DSO modules and
        dynamically loaded into the server in the same manner as other DSO
        modules.  Building MPMs as DSO modules allows the MPM to be changed by
        updating the <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> directive
        for the MPM instead of by rebuilding the server.</p>
    
        <pre class="prettyprint lang-config">LoadModule mpm_prefork_module modules/mod_mpm_prefork.so</pre>
    
    
        <p>Attempting to <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        more than one MPM will result in a startup failure with the
        following error.</p>
    
        <div class="example"><p><code>AH00534: httpd: Configuration error: More than one MPM
        loaded.</code></p></div>
    
        <p>This feature is enabled using the
        <code>--enable-mpms-shared</code> option of the <code class="program"><a href="./programs/configure.html">configure</a></code>
        script.
        With argument <code><em>all</em></code>, all possible MPMs for the platform
        will be installed.  Alternately, a list of MPMs can be specified as the
        argument.</p>
    
        <p>The default MPM, either selected automatically or specified with the
        <code>--with-mpm</code> option of the <code class="program"><a href="./programs/configure.html">configure</a></code>
        script, will be loaded in the generated server configuration file.  Edit the
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> directive to select a
        different MPM.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/mpm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.de��������������������������������������������������������������0000664�0001751�0001751�00000022437�14744525602�017434� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Dokumentation zum Apache HTTP Server Version
    2.4 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a></div>
    <div id="page-content"><h1>Dokumentation zum Apache HTTP Server Version
    2.4</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Google-Suche" type="submit" /><input value="10" name="num" type="hidden" /><input value="de" name="hl" type="hidden" /><input value="ISO-8859-1" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Version 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">Hinweise zur Version</a></h2>
    <ul><li><a href="new_features_2_4.html">Neue Funktionen in Version 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Neue Funktionen in Version 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">Neue Funktionen in Version 2.0</a></li>
    <li><a href="upgrading.html">Upgrade auf Version 2.4</a></li>
    <li><a href="license.html">Apache-Lizenz</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">Bedienungsanleitung</a></h2>
    <ul><li><a href="install.html">Kompilieren und Installieren</a></li>
    <li><a href="invoking.html">Starten</a></li>
    <li><a href="stopping.html">Stoppen und Neustarten</a></li>
    <li><a href="mod/quickreference.html">Konfigurationsanweisungen</a></li>
    <li><a href="mod/">Module</a></li>
    <li><a href="mpm.html">Multi-Processing-Module (MPMs)</a></li>
    <li><a href="filter.html">Filter</a></li>
    <li><a href="handler.html">Handler</a></li>
    <li><a href="expr.html">Der Ausdrucksparser</a></li>
    <li><a href="programs/">Server und Hilfsprogramme</a></li>
    <li><a href="glossary.html">Glossar</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">Benutzerhandbuch</a></h2>
    <ul><li><a href="getting-started.html">Erste Schritte</a></li>
    <li><a href="bind.html">An Adressen und Ports binden</a></li>
    <li><a href="configuring.html">Konfigurationsdateien</a></li>
    <li><a href="sections.html">Konfigurationsabschnitte</a></li>
    <li><a href="caching.html">Caching von Inhalten</a></li>
    <li><a href="content-negotiation.html">Content Negotiation</a></li>
    <li><a href="dso.html">Dynamic Shared Objects (DSO)</a></li>
    <li><a href="env.html">Umgebungsvariablen</a></li>
    <li><a href="logs.html">Log-Dateien</a></li>
    <li><a href="urlmapping.html">URLs auf das Dateisystem abbilden</a></li>
    <li><a href="misc/perf-tuning.html">Performance-Hinweise</a></li>
    <li><a href="misc/security_tips.html">Tipps zur Sicherheit</a></li>
    <li><a href="server-wide.html">Serverweite Konfiguration</a></li>
    <li><a href="ssl/">SSL/TLS-Verschl&#252;sselung</a></li>
    <li><a href="suexec.html">Suexec f&#252;r CGI</a></li>
    <li><a href="rewrite/">Einf&#252;hrung in die
        URL-Manipulation</a></li>
    <li><a href="vhosts/">Virtual-Hosts</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">Praxis / Anleitungen</a></h2>
    <ul><li><a href="howto/auth.html">Authentisierung und Autorisierung</a></li>
    <li><a href="howto/access.html">Zugriffskontrolle</a></li>
    <li><a href="howto/cgi.html">CGI: Dynamische Inhalte</a></li>
    <li><a href="howto/htaccess.html">.htaccess-Dateien</a></li>
    <li><a href="howto/ssi.html">Server Side Includes (SSI)</a></li>
    <li><a href="howto/public_html.html">Web-Verzeichnisse f&#252;r Benutzer
        (public_html)</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">Plattform-spezifische Anmerkungen</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">RPM-basierte Systeme (Redhat / CentOS / Fedora)</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC-Portierung</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">Weitere Themen</a></h2>
    <ul><li><a href="http://wiki.apache.org/httpd/FAQ">H&#228;ufig gestellte
        Fragen (FAQ)</a></li>
    <li><a href="sitemap.html">Seitenindex</a></li>
    <li><a href="developer/">Dokumentation f&#252;r Entwickler</a></li>
    <li><a href="http://httpd.apache.org/docs-project/">Mithilfe bei der Dokumentation</a></li>
    <li><a href="misc/">Sonstiges</a></li>
    <li><a href="http://wiki.apache.org/httpd/">Wiki</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.da��������������������������������������������������������������0000664�0001751�0001751�00000021552�14744525602�017425� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="da" xml:lang="da"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server Version 2.4
    Dokumentation - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Moduler</a> | <a href="./mod/directives.html">Direktiver</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Ordbog</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a></div>
    <div id="page-content"><h1>Apache HTTP Server Version 2.4
    Dokumentation</h1>
    <div class="toplang">
    <p><span>Tilg&#230;ngelige sprog: </span><a href="./da/" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">Denne overs&#230;ttelse kan v&#230;re for&#230;ldet. Se den Engelske version for de seneste opdateringer.</div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Google S&#248;gning" type="submit" /><input value="10" name="num" type="hidden" /><input value="da" name="hl" type="hidden" /><input value="ISO-8859-1" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Version 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">Udgivelses Noter</a></h2>
    <ul><li><a href="new_features_2_4.html">Nye funktioner i Apache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Nye funktioner i Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">Nye funktioner i Apache 2.0</a></li>
    <li><a href="upgrading.html">Opgradering fra 2.2 til 2.4</a></li>
    <li><a href="license.html">Apache Licens</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">Reference Manual</a></h2>
    <ul><li><a href="install.html">Kompilering og installation</a></li>
    <li><a href="invoking.html">Opstart</a></li>
    <li><a href="stopping.html">At starte og stoppe serveren</a></li>
    <li><a href="mod/directives.html">K&#248;rselstidskonfigurationsdirektiver</a></li>
    <li><a href="mod/quickreference.html">Hurtig oversigt over direktiver</a></li>
    <li><a href="mod/">Moduler</a></li>
    <li><a href="mpm.html">Multibehandlingsmoduler (MPM)</a></li>
    <li><a href="filter.html">Filtre</a></li>
    <li><a href="handler.html">Behandlere</a></li>
    <li><a href="programs/">Serveren og underst&#248;ttende programmer</a></li>
    <li><a href="glossary.html">Anvendte gloser</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">Brugerguide</a></h2>
    <ul><li><a href="bind.html">Binding</a></li>
    <li><a href="configuring.html">Konfigurationsfiler</a></li>
    <li><a href="sections.html">Konfigurationssektioner</a></li>
    <li><a href="caching.html">Caching af indhold</a></li>
    <li><a href="content-negotiation.html">Indholdsforhandling</a></li>
    <li><a href="dso.html">Dynamisk delte objekter (DSO)</a></li>
    <li><a href="env.html">Milj&#248;variabler</a></li>
    <li><a href="logs.html">Logfiler</a></li>
    <li><a href="urlmapping.html">Afbilding af URL'er til filsystem</a></li>
    <li><a href="misc/perf-tuning.html">Justering af ydeevne</a></li>
    <li><a href="misc/security_tips.html">Sikkerhedstips</a></li>
    <li><a href="server-wide.html">Global serverkonfiguration</a></li>
    <li><a href="ssl/">SSL/TLS-Kryptering</a></li>
    <li><a href="suexec.html">Suexec-afvikling for CGI</a></li>
    <li><a href="rewrite/">URL-omskrivning med mod_rewrite</a></li>
    <li><a href="vhosts/">Virtuelle v&#230;rter</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">How-To / Gennemgange</a></h2>
    <ul><li><a href="howto/auth.html">Godkendelse, autorisation og adgangskontrol</a></li>
    <li><a href="howto/cgi.html">CGI: Dynamisk indhold</a></li>
    <li><a href="howto/htaccess.html">.htaccess filer</a></li>
    <li><a href="howto/ssi.html">Server Side Includes (SSI)</a></li>
    <li><a href="howto/public_html.html">Per-bruger webmapper (public_html)</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">Platformspecifikke noter</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC Port</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">Andre emner</a></h2>
    <ul><li><a href="faq/">Ofte stillede sp&#248;rgsm&#229;l</a></li>
    <li><a href="sitemap.html">Sitemap</a></li>
    <li><a href="developer/">Dokumentation for udviklere</a></li>
    <li><a href="misc/">Andre noter</a></li>
    <li><a href="http://wiki.apache.org/httpd/">Wiki</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>Tilg&#230;ngelige sprog: </span><a href="./da/" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licenseret under <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Moduler</a> | <a href="./mod/directives.html">Direktiver</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Ordbog</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/mpm.html.de����������������������������������������������������������������0000664�0001751�0001751�00000026205�14744525602�017113� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Multi-Processing-Module (MPMs) - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Multi-Processing-Module (MPMs)</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/mpm.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
      <p>Das Dokument beschreibt, was ein Multi-Processing-Modul ist und wie solche
        Module beim Apache HTTP Server verwendet werden.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Einf&#252;hrung</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#choosing">Auswahl eines MPMs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#defaults">MPM-Voreinstellungen</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Einf&#252;hrung</a></h2>
    
      <p>Der Apache HTTP Server wurde als leistungsf&#228;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&#228;higkeiten oder kennen verschiedene Wege, die gleiche
        Funktionalt&#228;t sehr effizient zu implementieren. Der Apache hat durch
        seinen modularen Aufbau schon immer eine breite Auswahl von Umgebungen
        unterst&#252;tzt. Dieses Design erlaubt es dem Webmaster, durch Auswahl der
        Module, die zur Kompilierungszeit oder zur Laufzeit geladen werden, die
        Features auszuw&#228;hlen, die in den Server intregiert werden.</p>
    
      <p>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&#252;r die Bindung an
        Netzwerkports der Maschine, die Annahme von Anfragen und die Abfertigung von
        Kindprozessen zur Behandlung der Anfragen zust&#228;ndig sind.</p>
    
      <p>Die Erweiterung des modularen Aufbaus auf diese Ebene des Servers
        bringt zwei wesentliche Vorteile:</p>
    
      <ul>
        <li>Der Apache kann nun eine Vielfalt von Betriebssystemen sauberer und
          effizienter unterst&#252;tzen. Insbesondere die Windows-Version des Apache
          ist jetzt deutlich effizienter, da <code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code> native
          Netzwerkf&#228;higkeiten anstelle der im Apache 1.3 verwendeten
          POSIX-Schicht benutzen kann. Dieser Vorteil gilt auch f&#252;r andere
          Betriebssysteme, f&#252;r die spezielle MPMs implementiert sind.</li>
        
        <li>Der Server l&#228;&#223;t sich besser auf die Bed&#252;rfnisse der
          jeweiligen Website anpassen. Sites beispielsweise, die eine hohe
          Skalierbarkeit ben&#246;tigen, k&#246;nnen ein Threaded-MPM wie
          <code class="module"><a href="./mod/worker.html">worker</a></code> oder <code class="module"><a href="./mod/event.html">event</a></code> w&#228;hlen,
          w&#228;hrend Sites, die Stabilit&#228;t oder Kompatibilit&#228;t mit
          &#228;lterer Software erfordern, <code class="module"><a href="./mod/prefork.html">prefork</a></code> w&#228;hlen
          k&#246;nnen.</li>
      </ul>
    
      <p>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&#252;gbaren MPMs finden Sie im <a href="mod/">Modul-Index</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="choosing" id="choosing">Auswahl eines MPMs</a></h2>
    
      <p>MPMs m&#252;ssen w&#228;hrend der
        <span class="transnote">(<em>Anm.d.&#220;.:</em> Quelltext-)</span>Konfiguration ausgew&#228;hlt und in den
        Server einkompiliert werden. Compiler sind in der Lage eine Reihe von
        Funktionen zu optimieren, wenn Threads verwendet werden. Sie k&#246;nnen
        dies allerdings nur, wenn sie wissen, dass Threads benutzt werden.</p>
    
      <p>Um das gew&#252;nschte MPM tats&#228;chlich auszuw&#228;hlen, verwenden Sie
        beim <code class="program"><a href="./programs/configure.html">configure</a></code>-Skript das Argument
        <code>--with-mpm=<em>NAME</em></code>. <em>NAME</em> ist der Name des
        gew&#252;nschten MPMs.</p>
    
      <p>Ist der Server kompiliert, so ist es mittels <code>./httpd -l</code>
        m&#246;glich, das ausgew&#228;hlte MPM zu ermitteln. Dieser Befehl listet
        alle in den Server einkompilierten Module auf, einschlie&#223;lich des
        MPM.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="defaults" id="defaults">MPM-Voreinstellungen</a></h2>
    
      <p>Die folgende Tabelle gibt die voreingestellten MPMs f&#252;r verschiedene
        Betriebssysteme an. Wenn Sie w&#228;hrend der Kompilierung keine andere
        Auswahl treffen, wird dieses MPM gew&#228;hlt.</p>
    
    <table>
    
    <tr><td>BeOS</td><td><code class="module"><a href="./mod/beos.html">beos</a></code></td></tr>
    <tr><td>Netware</td><td><code class="module"><a href="./mod/mpm_netware.html">mpm_netware</a></code></td></tr>
    <tr><td>OS/2</td><td><code class="module"><a href="./mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
    <tr><td>Unix</td><td><code class="module"><a href="./mod/prefork.html">prefork</a></code></td></tr>
    <tr><td>Windows</td><td><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code></td></tr>
    </table>
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/mpm.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/mpm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dso.html.en����������������������������������������������������������������0000664�0001751�0001751�00000046421�14737241666�017132� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Dynamic Shared Object (DSO) Support - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Dynamic Shared Object (DSO) Support</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/dso.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>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.
        Modules will be compiled as Dynamic Shared Objects (DSOs)
        that exist separately from the main <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        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 (<code class="program"><a href="./programs/apxs.html">apxs</a></code>).</p>
        <p>Alternatively, the modules can be statically compiled into
        the <code class="program"><a href="./programs/httpd.html">httpd</a></code> binary when the server is built.</p>
    
        <p>This document describes how to use DSO modules as well as
        the theory behind their use.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#implementation">Implementation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">Usage Summary</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#background">Background</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#advantages">Advantages and Disadvantages</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">Implementation</a></h2>
    
    <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>The DSO support for loading individual Apache httpd modules is based
        on a module named <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> which must be statically
        compiled into the Apache httpd core. It is the only module besides
        <code class="module"><a href="./mod/core.html">core</a></code> which cannot be put into a DSO
        itself. Practically all other distributed Apache httpd modules will then
        be placed into a DSO. After a module is compiled into a DSO named
        <code>mod_foo.so</code> you can use <code class="module"><a href="./mod/mod_so.html">mod_so</a></code>'s <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> directive in your
        <code>httpd.conf</code> file to load this module at server startup
        or restart.</p>
        <p>The DSO builds for individual modules can be disabled via
        <code class="program"><a href="./programs/configure.html">configure</a></code>'s <code>--enable-mods-static</code>
        option as discussed in the <a href="install.html">install
        documentation</a>.</p>
    
        <p>To simplify this creation of DSO files for Apache httpd modules
        (especially for third-party modules) a support program
        named <code class="program"><a href="./programs/apxs.html">apxs</a></code> (<dfn>APache
        eXtenSion</dfn>) is available. It can be used to build DSO based
        modules <em>outside of</em> the Apache httpd source tree. The idea is
        simple: When installing Apache HTTP Server the <code class="program"><a href="./programs/configure.html">configure</a></code>'s
        <code>make install</code> procedure installs the Apache httpd C
        header files and puts the platform-dependent compiler and
        linker flags for building DSO files into the <code class="program"><a href="./programs/apxs.html">apxs</a></code>
        program. This way the user can use <code class="program"><a href="./programs/apxs.html">apxs</a></code> to compile
        his Apache httpd module sources without the Apache httpd distribution
        source tree and without having to fiddle with the
        platform-dependent compiler and linker flags for DSO
        support.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">Usage Summary</a></h2>
    
        <p>To give you an overview of the DSO features of Apache HTTP Server 2.x,
        here is a short and concise summary:</p>
    
        <ol>
          <li>
            <p>Build and install a <em>distributed</em> Apache httpd module, say
            <code>mod_foo.c</code>, into its own DSO
            <code>mod_foo.so</code>:</p>
    
    <div class="example"><p><code>
    $ ./configure --prefix=/path/to/install --enable-foo<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
          <p>Configure Apache HTTP Server with all modules enabled. Only a basic
          set will be loaded during server startup. You can change the set of loaded
          modules by activating or deactivating the <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> directives in
          <code>httpd.conf</code>.</p>
    
    <div class="example"><p><code>
    $ ./configure --enable-mods-shared=all<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
          <p>Some modules are only useful for developers and will not be build.
          when using the module set <em>all</em>. To build all available modules
          including developer modules use <em>reallyall</em>. In addition the
          <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> directives for all
          built modules can be activated via the configure option
          <code>--enable-load-all-modules</code>.</p>
    
    <div class="example"><p><code>
    $ ./configure --enable-mods-shared=reallyall --enable-load-all-modules<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
            Build and install a <em>third-party</em> Apache httpd module, say
            <code>mod_foo.c</code>, into its own DSO
            <code>mod_foo.so</code> <em>outside of</em> the Apache httpd
            source tree using <code class="program"><a href="./programs/apxs.html">apxs</a></code>:
    
    <div class="example"><p><code>
    $ cd /path/to/3rdparty<br />
    $ apxs -cia mod_foo.c
    </code></p></div>
          </li>
        </ol>
    
        <p>In all cases, once the shared module is compiled, you must
        use a <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        directive in <code>httpd.conf</code> to tell Apache httpd to activate
        the module.</p>
    
        <p>See the <a href="programs/apxs.html">apxs documentation</a> for more details.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="background" id="background">Background</a></h2>
    
        <p>On modern Unix derivatives there exists a mechanism
        called dynamic linking/loading of <em>Dynamic Shared
        Objects</em> (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.</p>
    
        <p>This loading can usually be done in two ways: automatically
        by a system program called <code>ld.so</code> 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
        <code>dlopen()/dlsym()</code>.</p>
    
        <p>In the first way the DSO's are usually called <em>shared
        libraries</em> or <em>DSO libraries</em> and named
        <code>libfoo.so</code> or <code>libfoo.so.1.2</code>. They
        reside in a system directory (usually <code>/usr/lib</code>)
        and the link to the executable program is established at
        build-time by specifying <code>-lfoo</code> 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 <code>libfoo.so</code> in <code>/usr/lib</code>, in
        paths hard-coded via linker-options like <code>-R</code> or in
        paths configured via the environment variable
        <code>LD_LIBRARY_PATH</code>. It then resolves any (yet
        unresolved) symbols in the executable program which are
        available in the DSO.</p>
    
        <p>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
        <code>ld.so</code> 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 <code>libc.so</code>, saving disk
        space for every program.</p>
    
        <p>In the second way the DSO's are usually called <em>shared
        objects</em> or <em>DSO files</em> and can be named with an
        arbitrary extension (although the canonical name is
        <code>foo.so</code>). 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 <code>dlopen()</code>. 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 <code>libc.so</code>). 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.</p>
    
        <p>Finally, to take advantage of the DSO's API the executable
        program has to resolve particular symbols from the DSO via
        <code>dlsym()</code> for later use inside dispatch tables
        <em>etc.</em> 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.</p>
    
        <p>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.</p>
    
        <p>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.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advantages" id="advantages">Advantages and Disadvantages</a></h2>
    
        <p>The above DSO based features have the following
        advantages:</p>
    
        <ul>
          <li>The server package is more flexible at run-time because
          the server process can be assembled at run-time via
          <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
          <code>httpd.conf</code> configuration directives instead of
          <code class="program"><a href="./programs/configure.html">configure</a></code> options at build-time. For instance,
          this way one is able to run different server instances
          (standard &amp; SSL version, minimalistic &amp; dynamic
          version [mod_perl, mod_php], <em>etc.</em>) with only one Apache httpd
          installation.</li>
    
          <li>The server package can be easily extended with
          third-party modules even after installation. This is
          a great benefit for vendor package maintainers, who can create
          an Apache httpd core package and additional packages containing
          extensions like PHP, mod_perl, mod_security, <em>etc.</em></li>
    
          <li>Easier Apache httpd module prototyping, because with the
          DSO/<code class="program"><a href="./programs/apxs.html">apxs</a></code> pair you can both work outside the
          Apache httpd source tree and only need an <code>apxs -i</code>
          command followed by an <code>apachectl restart</code> to
          bring a new version of your currently developed module into
          the running Apache HTTP Server.</li>
        </ul>
    
        <p>DSO has the following disadvantages:</p>
    
        <ul>
          <li>The server is approximately 20% slower at startup time
          because of the symbol resolving overhead the Unix loader now
          has to do.</li>
    
          <li>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.</li>
    
          <li>Because DSO modules cannot be linked against other
          DSO-based libraries (<code>ld -lfoo</code>) 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 httpd core, from the C library
          (<code>libc</code>) and all other dynamic or static libraries
          used by the Apache httpd core, or from static library archives
          (<code>libfoo.a</code>) containing position independent code.
          The only chances to use other code is to either make sure the
          httpd core itself already contains a reference to it or
          loading the code yourself via <code>dlopen()</code>.</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/dso.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dso.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/glossary.html.de�����������������������������������������������������������0000664�0001751�0001751�00000105470�14744525602�020167� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Glossar - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Glossar</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/glossary.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
        <p>Dieses Glossar erl&#228;utert einige gebr&#228;uchliche Fachbegriffe im
          Zusammenhang mit dem Apache im Speziellen und Web-Diensten im
          Allgemeinen. Weitere Informationen zum jeweiligen Begriff erreichen Sie
          &#252;ber die Links.</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definitions" id="definitions">Definitionen</a></h2>
        
      <dl>
        <dt><a name="algorithm" id="algorithm">Algorithmus</a></dt>
        <dd>Eine eindeutige Formel oder ein Satz von Regeln zur L&#246;sung eines
          Problems in einer endlichen Anzahl von Schritten. Algorithmen zur
          Verschl&#252;sselung werden &#252;blicherweise <a class="glossarylink" href="./glossary.html#cipher" title="siehe Glossar"><dfn>Chiffre</dfn></a> genannt.
        </dd>
    
        <dt><a name="apacheextensiontool" id="apacheextensiontool">APache
          eXtension Tool</a> <a name="apxs" id="apxs">(apxs)</a></dt>
        <dd>Ein Perl-Skript zur Kompilierung von <a href="#module">Modul</a>-Quelltexten zu Dynamic-Shared-Objects
          (<a class="glossarylink" href="./glossary.html#dso" title="siehe Glossar">DSOs</a>)  und zur Installation dieser zum
          Apache-Webserver.<br />
          Siehe: <code class="program"><a href="./programs/apxs.html">apxs</a></code>-Dokumentation
        </dd>
    
        <dt><a name="apacheportableruntime" id="apacheportableruntime">Apache Portable Runtime</a> <a name="apr" id="apr">(APR)</a></dt>
        <dd>Eine Menge von Bibliotheken, die viele grundlegende Schnittstellen
          zwischen dem Server und dem Betriebssystem anbietet. Die APR
          wird parallel zum Apache HTTP Server in einem eigenst&#228;ndigen Projekt
          entwickelt.<br />
          Siehe auch: <a href="http://apr.apache.org/">Apache Portable Runtime
          Project</a>
        </dd>
    
        <dt><a name="authentication" id="authentication">Authentifizierung</a></dt> 
        <dd>Die positive Identifizierung einer Netzwerkeinheit, wie z.B.
          eines Servers, eines Clients oder eines Benutzers.<br />
          Siehe: <a href="howto/auth.html">Authentisierung, Autorisierung und
          Zugriffskontrolle</a>
        </dd>
    
        <dt><a name="certificationauthority" id="certificationauthority">Certification Authority</a>
          <span class="phonetic">[s&#601;&#712;tifi&#712;kei&#643;&#601;n
          &#596;&#720;&#952;&#596;riti]</span>
          <a name="ca" id="ca">(CA)</a></dt>
        <dd><span class="transnote">(<em>Anm.d.&#220;.:</em> die Zertifizierungsstelle)</span> Eine
          vertrauensw&#252;rdige dritte Partei, deren Zweck es ist,
          Zertifikate f&#252;r Netzwerkeinheiten zu signieren. Andere
          Netzwerkeinheiten k&#246;nnen die Signatur pr&#252;fen, um
          sicherzustellen, dass eine CA den Inhaber eines Zertifikats
          authentifiziert hat.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="certificatsigningrequest" id="certificatsigningrequest">Certificate Signing Request</a>
          <span class="phonetic">[s&#601;&#712;tifikit saini&#331;
          ri&#712;kwest]</span>  <a name="csr" id="csr">(CSR)</a></dt> 
        <dd><span class="transnote">(<em>Anm.d.&#220;.:</em> Zertifikats-Signierungsanfrage)</span> Ein unsigniertes
          <a class="glossarylink" href="./glossary.html#certificate" title="siehe Glossar">Zertifikat</a> zur Einreichung bei
          einer <a class="glossarylink" href="./glossary.html#certificationauthority" title="siehe Glossar">Zertifizierungsstelle</a>, welche
          es mit dem <a class="glossarylink" href="./glossary.html#privatekey" title="siehe Glossar">privaten Schl&#252;ssel</a>
          ihres CA-<em>Zertifikats</em> signiert. Durch die Signatur wird ein CSR
          zum echten Zertifikat.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="cipher" id="cipher">Chiffre</a></dt> 
        <dd>Die <dfn>Chiffre</dfn> ist ein Algorithmus oder System zur
          Datenverschl&#252;sselung. Beispiele sind DES, IDEA, RC4 usw. Im
          Englischen spricht man von
          <dfn>Cipher</dfn>&nbsp;<span class="phonetic">[&#712;saif&#601;]</span><br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="ciphertext" id="ciphertext">Chiffretext</a></dt>
        <dd>Das Ergebnis, nachdem ein <a class="glossarylink" href="./glossary.html#plaintext" title="siehe Glossar">Klartext</a>
          eine <a class="glossarylink" href="./glossary.html#cipher" title="siehe Glossar">Chiffre</a> durchlaufen hat.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
        
        <dt><a name="commongatewayinterface" id="commongatewayinterface">Common
          Gateway Interface</a> <span class="phonetic">[&#712;k&#596;m&#601;n geitwei
          &#712;int&#601;&#720;feis]</span>
          <a name="cgi" id="cgi">(CGI)</a></dt>
        <dd>Eine einheitliche Definition einer Schnittstelle zwischen einem
          Webserver und einem externen Programm, welcher dem externen Programm die
          Behandlung von Anfragen erm&#246;glicht. Die Schnittstelle ist
          urspr&#252;nglich von der <a href="http://hoohoo.ncsa.uiuc.edu/cgi/overview.html">NCSA</a>
          definiert worden. Es exisitert jedoch auch ein <a href="http://cgi-spec.golux.com/">RFC-Projekt</a>.<br />
          Siehe: <a href="howto/cgi.html">Dynamische Inhalte mit CGI</a>
        </dd>
    
        <dt><a name="connect" id="connect">CONNECT</a>
          <span class="phonetic">[k&#601;nekt]</span></dt> 
        <dd>Eine <a class="glossarylink" href="./glossary.html#method" title="siehe Glossar">HTTP-Methode</a> zur Weiterleitung
          von Rohdaten &#252;ber HTTP. Sie kann dazu verwendet werden, andere
          Protokolle wie zum Beispiel das SSL-Protokoll zu kapseln.
        </dd>
    
        <dt><a name="digitalsignature" id="digitalsignature">Digitale
          Signatur</a></dt>
        <dd>Ein chiffrierter Textblock, der die G&#252;ltigkeit eines Zertifikats
          oder einer anderen Datei best&#228;tigt. Eine <a class="glossarylink" href="./glossary.html#certificationauthority" title="siehe Glossar">Zertifizierungsstelle</a> erstellt 
          eine digitale Signatur durch Generierung eines <a class="glossarylink" href="./glossary.html#hash" title="siehe Glossar">Hashs</a> aus dem in einem <em>Zertifikat</em>
          enthaltenen <em>&#246;ffentlichen Schl&#252;ssel</em> und
          anschlie&#223;ender Codierung des Hashs mit dem <em>privaten
          Schl&#252;ssel</em> des Zertifikats. Nur der &#246;ffentliche
          Schl&#252;ssel der CA kann die Signatur decodieren. So wird
          sichergestellt, dass die CA die Netwerkeinheit, welche das
          <em>Zertifikat</em> besitzt, authentifiziert hat.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="directive" id="directive">Direktive</a></dt> 
        <dd>Eine Konfigurationsanweisung, die das Verhalten des Apache in einem
          oder mehreren Punkten steuert. Direktiven werden in den <a class="glossarylink" href="./glossary.html#configurationfile" title="siehe Glossar">Konfigurationsdateien</a> gesetzt.<br />
          Siehe: <a href="mod/directives.html">Verzeichnis der Direktiven</a>
        </dd>
    
        <dt><a name="dynamicsharedobject" id="dynamicsharedobject">Dynamic
          Shared Object</a> 
          <span class="phonetic">[dai&#712;n&#230;mik &#643;&#603;&#601;d
          &#712;&#596;bd&#658;ikt]</span> <a name="dso" id="dso">(DSO)</a></dt>
        <dd>Separat von der Apache-Bin&#228;rdatei <code class="program"><a href="./programs/httpd.html">httpd</a></code>
          kompilierte <a class="glossarylink" href="./glossary.html#module" title="siehe Glossar">Module</a>, die bei Bedarf
          geladen werden k&#246;nnen.<br />
          Siehe: <a href="dso.html">Unterst&#252;tzung f&#252;r
          Dynamic-Shared-Objects</a>
        </dd>
    
        <dt><a name="export-crippled" id="export-crippled">exportbeschr&#228;nkt</a></dt>
        <dd>Verminderte kryptografische St&#228;rke (und Sicherheit), um den
          Exportbesimmungen der Vereinigten Staaten <span class="transnote">(<em>Anm.d.&#220;.:</em> konkret: United
          States' Export Administration Regulations (EAR))</span> zu
          entsprechen. Exportbeschr&#228;nkte Verschl&#252;sselungssoftware ist
          auf eine kurze Schl&#252;ssell&#228;nge begrenzt, was zu
          <em>Chiffretexten</em> f&#252;hrt, die gew&#246;hnlich mittels
          Brute-Force dekodiert werden k&#246;nnen.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="filter" id="filter">Filter</a></dt>
        <dd>Ein Verfahren, dass auf vom Server empfangene oder zu sendende Daten
          angewendet wird. Eingabefilter verarbeiten vom Client an den Server
          gesendetet Daten, w&#228;hrend Ausgabefilter vom Server an den Client zu
          sendende Daten verarbeiten. Der Ausgabefilter <code>INCLUDES</code>
          beispielsweise untersucht Dokumente nach <a class="glossarylink" href="./glossary.html#ssi" title="siehe Glossar">Server-Side-Includes</a> und f&#252;hrt sie aus.<br />
          Siehe: <a href="filter.html">Filter</a>
        </dd>
    
        <dt><a name="handler" id="handler">Handler</a>
          <span class="phonetic">[&#712;h&#230;ndl&#601;]</span></dt>
        <dd>Eine Apache-interne Darstellung der Aktion, die beim Aufruf einer
          Datei auszuf&#252;hren ist. Im Allgemeinen besitzen Dateien implizite,
          auf dem Dateityp basierende Handler. Gew&#246;hnlich werden alle Dateien
          vom Server bedient, einige Dateitypen werden jedoch separat "behandelt"
          <span class="transnote">(<em>Anm.d.&#220;.:</em> besitzen einen separaten Handler)</span>. Der
          <code>cgi-script</code>-Handler beispielsweise kennzeichnet Dateien, die
          als <a class="glossarylink" href="./glossary.html#cgi" title="siehe Glossar">CGI-Programme</a> ausgef&#252;hrt werden
          sollen.<br />
          Siehe: <a href="handler.html">Verwendung von Apache-Handlern</a>
        </dd>
    
        <dt><a name="hash" id="hash">Hash</a>
          <span class="phonetic">[h&#230;&#643;]</span></dt>
        <dd>Ein mathematischer, unumkehrbarer Einweg-Algorithmus zur Generierung
          einer Zeichenfolge fester L&#228;nge aus einer anderen Zeichenfolge
          beliebiger L&#228;nge. Unterschiedliche Zeichenfolgen bei der Eingabe
          ergeben &#252;blischerweise unterschiedliche Hashes (abh&#228;ngig von
          der Hash-Funktion).
        </dd>
    
        <dt><a name="header" id="header">Header</a>
          <span class="phonetic">[hed&#601;]</span></dt>
        <dd>Der Teil der <a class="glossarylink" href="./glossary.html#http" title="siehe Glossar">HTTP</a>-Anfrage und -Antwort,
          der vor den eigentlichen Daten &#252;bermittelt wird und den Inhalt
          beschreibende Meta-Informationen enth&#228;lt.
        </dd>
    
        <dt><a name="htaccess" id="htaccess">.htaccess</a></dt>
        <dd>Eine <a class="glossarylink" href="./glossary.html#configurationfile" title="siehe Glossar">Konfigurationsdatei</a>,
          die innerhalb des Web-Verzeichnisbaums abgelegt wird und zu dem
          Verzeichnis, in dem sie abgelegt ist, sowie allen Unterverzeichnissen
          <a class="glossarylink" href="./glossary.html#directive" title="siehe Glossar">Konfigurationsdirektiven</a>
          enth&#228;lt. Trotz ihres Namens kann diese Datei nahezu alle Arten von
          Direktiven enthalten, nicht nur Direktiven zur Zugriffskontrolle.<br />
          Siehe: <a href="configuring.html">Konfigurationsdateien</a>
        </dd>
    
        <dt><a name="httpd.conf" id="httpd.conf">httpd.conf</a></dt>
        <dd>Die <a class="glossarylink" href="./glossary.html#configurationfile" title="siehe Glossar">Haupt-Konfigurationsdatei</a> ist
          <code>/usr/local/apache2/conf/httpd.conf</code>. Dies kann aber zur
          Laufzeit oder zur Kompilierungszeit anders konfiguriert werden.<br />
          Siehe: <a href="configuring.html">Konfigurationsdateien</a>
        </dd>
    
        <dt><a name="https" id="https">HTTPS</a></dt>
        <dd>Das HyperText-Transfer-Protokoll (Secure), der
          Standard-Verschl&#252;sselungsmechanismus im World Wide Web.
          Tats&#228;chlich handelt es sich hierbei um HTTP &#252;ber <a class="glossarylink" href="./glossary.html#ssl" title="siehe Glossar">SSL</a>.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
        
        <dt><a name="hypertexttransferprotocol" id="hypertexttransferprotocol">HyperText-Transfer-Protokoll</a>
          <a name="http" id="http">(HTTP)</a></dt>
        <dd>Das Standard-&#220;bertragungsprotokoll im World Wide Web. Der Apache
          implementiert die Protokollversion 1.1, bezeichnet als HTTP/1.1 und
          definiert in <a href="http://ietf.org/rfc/rfc2616.txt">RFC 2616</a>.
        </dd>
    
        <dt><a name="plaintext" id="plaintext">Klartext</a></dt>
        <dd>Der unverschl&#252;sselte Text.</dd>
    
        <dt><a name="configurationdirective" id="configurationdirective">Konfigurationsanweisung</a></dt>
        <dd>Siehe: <a class="glossarylink" href="./glossary.html#directive" title="siehe Glossar">Direktive</a></dd>
    
        <dt><a name="configurationfile" id="configurationfile">Konfigurationsdatei</a></dt>
        <dd>Eine Textdatei mit <a class="glossarylink" href="./glossary.html#directive" title="siehe Glossar">Direktiven</a>,
          welche die Konfiguration des Apache steuern.<br />
          Siehe: <a href="configuring.html">Konfigurationsdateien</a>
        </dd>
    
        <dt><a name="context" id="context">Kontext</a></dt>
        <dd>Ein Bereich in den <a class="glossarylink" href="./glossary.html#configurationfile" title="siehe Glossar">Konfigurationsdateien</a>, in dem
          verschiedene Typen von <a class="glossarylink" href="./glossary.html#directive" title="siehe Glossar">Direktiven</a>
          erlaubt sind.<br />
          Siehe: <a href="mod/directive-dict.html#Context">Erkl&#228;rung der
          Fachbegriffe zu Apache-Direktiven</a>
        </dd>
    
        <dt><a name="messagedigest" id="messagedigest">Message-Digest</a>
          <span class="phonetic">[&#712;mesid&#658;]</span></dt>
        <dd>Ein Hash einer Nachricht, mit dem sich sicherstellen l&#228;&#223;t,
          dass der Inhalt der Nachricht w&#228;hrend der &#220;bertragung nicht
          ver&#228;ndert wurde. <span class="transnote">(<em>Anm.d.&#220;.:</em> ein so genannter Extrakt der
          Nachricht)</span><br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="method" id="method">Methode</a></dt>
        <dd>Im <a class="glossarylink" href="./glossary.html#http" title="siehe Glossar">HTTP</a>-Kontext eine in der
          Anfrage(zeile) des Clients angegeben Aktion, die auf eine Ressource
          angewendet wird. <code>GET</code>, <code>POST</code> und <code>PUT</code>
          sind einige der verf&#252;gbaren HTTP-Methoden.
        </dd>
    
        <dt><a name="mime-type" id="mime-type">MIME-Typ</a>
          <span class="phonetic">[maim ty&#720;p]</span></dt>
        <dd>Eine Art und Weise, den Typ des &#252;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&#228;gstrich. Einige Beispiele sind <code>text/html</code>,
          <code>image/gif</code> und <code>application/octet-stream</code>.
          Bei HTTP wird der MIME-Typ mit dem <a class="glossarylink" href="./glossary.html#header" title="siehe Glossar">Header</a> <code>Content-Type</code>
          &#252;bermittelt.<br />
          Siehe: <a href="mod/mod_mime.html">mod_mime</a>
        </dd>
    
        <dt><a name="module" id="module">Modul</a></dt>
        <dd>Ein selbstst&#228;ndiger Teil eines Programms. Ein Gro&#223;teil der
          Funktionalit&#228;t des Apache ist in Modulen enthalten, die Sie einbinden
          oder entfernen k&#246;nnen. In die Apache-Bin&#228;rdatei <code class="program"><a href="./programs/httpd.html">httpd</a></code> einkompilierte Module werden <em>statische Module</em>
          genannt, w&#228;hrend Module, die separat gespeichert sind und optional
          zur Laufzeit geladen werden k&#246;nnen, <em>dynamische Module</em> oder
          <a class="glossarylink" href="./glossary.html#dso" title="siehe Glossar">DSOs</a> genannt werden.
          Standardm&#228;&#223;ig eingebundene Module werden <em>Basismodule</em>
          genannt. F&#252;r den Apache sind viele Module verf&#252;gbar, die nicht
          als Bestandteil des <a class="glossarylink" href="./glossary.html#tarball" title="siehe Glossar">Apache-HTTP-Server-Tarballs</a> ausgeliefert
          werden. Diese werden als <em>Drittmodule</em> bezeichnet.<br />
          Siehe: <a href="mod/">Modulverzeichnis</a>
        </dd>
    
        <dt><a name="modulemagicnumber" id="modulemagicnumber">Module-Magic-Number</a>
          <span class="phonetic">[&#712;m&#596;ju&#720;l m&#230;d&#658;ik
          &#712;n&#652;mb&#601;]</span>
          (<a name="mmn" id="mmn">MMN</a>)</dt>
        <dd>Die Module-Magic-Number ist eine Konstante, die im Apache-Quelltext
          definiert ist und im Zusammenhang mit der Bin&#228;rkompatibilit&#228;t
          von Modulen steht. Sie wird ge&#228;ndert, wenn sich interne
          Apache-Strukturen, -Funktionen oder andere signifikante Teile der API
          derart &#228;ndern, dass eine Bin&#228;rkompatibilit&#228;t nicht mehr
          gew&#228;hrleistet werden kann. Bei einer MMN-&#196;nderung m&#252;ssen
          alle Module von Drittanbietern zumindest neu kompiliert und zuweilen auch
          geringf&#252;gig angepa&#223;t werden, um mit der neuen Apache-Version zu
          funktionieren.
        </dd>
    
        <dt><a name="publickey" id="publickey">&#214;ffentlicher
          Schl&#252;ssel</a></dt>
        <dd>Der &#246;ffentlich verf&#252;gbare Schl&#252;ssel in einem <a class="glossarylink" href="./glossary.html#publickeycryptography" title="siehe Glossar">Public-Key-Kryptographie</a>-System,
          mit dem f&#252;r seinen Eigent&#252;mer bestimmte Nachrichten
          verschl&#252;sselt und Signaturen von seinem Eigent&#252;mer
          entschl&#252;sselt werden.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
        
        <dt><a name="openssl" id="openssl">OpenSSL</a>
          <span class="phonetic">[&#712;&#601;up&#601;n&#603;s&#603;s&#712;&#603;l]</span>
        </dt>
        <dd>Das Open-Source-Toolkit f&#252;r SSL/TLS<br />
          Siehe: <a href="http://www.openssl.org/">http://www.openssl.org/</a>
        </dd>
    
        <dt><a name="passphrase" id="passphrase">Passphrase</a>
          <span class="phonetic">[pa&#720;freiz]</span></dt>
        <dd>Das Wort oder die Phrase, welches private Schl&#252;ssel-Dateien
          sch&#252;tzt. Sie verhindert die Entschl&#252;sselung durch nicht
          authorisierte Benutzer. Normalerweise ist dies einfach der geheimen
          (De-)Codierungsschl&#252;ssel, der f&#252;r <a class="glossarylink" href="./glossary.html#cipher" title="siehe Glossar">Chiffren</a> verwendet wird.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="privatekey" id="privatekey">Privater Schl&#252;ssel</a></dt>
        <dd>Der geheime Schl&#252;ssel in einem <a class="glossarylink" href="./glossary.html#publickeycryptography" title="siehe Glossar">Public-Key-Kryptographie</a>-System,
          mit dem hereinkommende Nachrichten decodiert und ausgehende signiert
          werden.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="proxy" id="proxy">Proxy</a></dt>
        <dd>Ein zwischen dem Client und dem <em>urspr&#252;nglichen Server</em>
          <span class="transnote">(<em>Anm.d.&#220;.:</em> der Server, den der Client tats&#228;chlich erreichen
          m&#246;chte)</span> liegender Server. Er nimmt Anfragen von
          Clients entgegen, &#252;bermittelt diese Anfragen dem
          urspr&#252;nglichen Server und liefert die Antwort des
          urspr&#252;nglichen Servers an den Client zur&#252;ck. Wenn mehrere
          Clients den gleichen Inhalt abfragen, dann kann der Proxy diesen Inhalt
          aus seinem Zwischenspeicher ausliefern, anstatt ihn jedesmal vom
          urspr&#252;nglichen Server anzufordern, und dadurch die Antwortzeit
          verringern.<br />
          Siehe: <a href="mod/mod_proxy.html">mod_proxy</a>
        </dd>
    
        <dt><a name="publickeycryptography" id="publickeycryptography">Public-Key-Kryptographie</a>
          <span class="phonetic">[&#712;p&#652;blik ki&#720;
          &#712;kyptogra&#712;fi&#720;]</span></dt>
        <dd>Theorie und Anwendung asymmetrischer Verschl&#252;sselungssysteme,
          die einen Schl&#252;ssel zur Verschl&#252;sselung und einen anderen zur
          Entschl&#252;sselung verwenden. Zwei derart zusammengeh&#246;rende
          Schl&#252;ssel bilden Sch&#252;sselpaar. Man spricht auch von
          "Asymetrischer Kryptographie".<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
        
        <dt><a name="regularexpresion" id="regularexpresion">Regul&#228;rer
          Ausdruck</a> <a name="regex" id="regex">(Regex)</a></dt>
        <dd>Eine Form, ein Muster im Text zu beschreiben - zum Beispiel: "alle
          W&#246;rter, die mit dem Buchstaben A beginnen" oder "Jeder Satz mit
          zwei Kommata und ohne gro&#223;es Q". Beim Apache sind regul&#228;re
          Ausdr&#252;cke hilfreich, da sie auf sehr flexible Art und Weise die
          Anwendung bestimmter Eigenschaften auf eine Auswahl von Dateien oder
          Ressourcen erm&#246;glichen. - Zum Beispiel k&#246;nnen alle .gif- und
          .jpg-Dateien eines Verzeichnis "images" mit
          "<code>/images/.*(jpg|gif)$</code>" beschrieben werden. Der Apache
          verwendet Perl-kompatible regul&#228;re Ausdr&#252;cke, wie sie die
          <a href="http://www.pcre.org/">PCRE</a>-Bibliothek bereitstellt.
        </dd>
    
        <dt><a name="reverseproxy" id="reverseproxy">Reverse Proxy</a>
          <span class="phonetic">[ri&#720;v&#601;&#720;s
          &#712;pr&#596;ksi]</span></dt>
        <dd>Ein <a class="glossarylink" href="./glossary.html#proxy" title="siehe Glossar">Proxy</a>-Server, der dem Client
          gegen&#252;ber als <em>urspr&#252;nglicher Server</em> erscheint. Dies
          ist n&#252;tzlich, um den tats&#228;chlichen Server aus
          Sicherheitsgr&#252;nden oder zur Lastverteilung vor dem Client zu
          verstecken.
        </dd>
    
        <dt><a name="securesocketslayer" id="securesocketslayer">Secure Sockets
          Layer</a> <span class="phonetic">[si&#712;kju&#601; &#712;s&#596;kits
          &#712;lei&#601;]</span> <a name="ssl" id="ssl">(SSL)</a></dt>
        <dd>Ein von der Firma Netscape Communications Corporation entwickeltes
          Protokoll zur allgemeinen Authentisierung und Verschl&#252;sselung der
          Kommunikation &#252;ber TCP/IP-Netzwerke. Die meistverbreitete Nutzung
          ist <em>HTTPS</em>, d.h. HyperText Transfer Protocol (HTTP) &#252;ber
          SSL.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="serversideincludes" id="serversideincludes">Server Side
          Includes</a> <span class="phonetic">[s&#601;&#720;&#601; said
          in&#712;klu&#720;ds]</span> <a name="ssi" id="ssi">(SSI)</a></dt>
        <dd>Eine Technik zum Einbetten von weiterverarbeitenden Anweisungen in
          HMTL-Dateien.<br />
          Siehe: <a href="howto/ssi.html">Einf&#252;hrung in Server Side
          Includes</a>
        </dd>
    
        <dt><a name="session" id="session">Session</a>
          <span class="phonetic">[&#712;se&#643;&#601;n]</span></dt>
        <dd>Allgemein der Kontext einer Kommunikation.</dd>
    
        <dt><a name="ssleay" id="ssleay">SSLeay</a></dt>
        <dd>Die Bibliothek der Original-SSL/TLS-Implementation von Eric A.
          Young</dd>
    
        <dt><a name="symmetriccryptophraphy" id="symmetriccryptophraphy">Symmetrische Kryptographie</a></dt>
        <dd>Die Theorie und Anwendung von <em>Chiffren</em>, die einen einzigen
          geheimen Schl&#252;ssel sowohl zur Verschl&#252;sswelung als auch zur
          Entschl&#252;sselung benutzen.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="tarball" id="tarball">Tarball</a>
          <span class="phonetic">[ta&#720;b&#596;&#720;l]</span></dt>
        <dd>Ein Paket von Dateien, die mit dem Hilfsprogramm <code>tar</code>
          zusammengefasst wurden. Apache-Distributionen werden in komprimierten
          tar-Archiven oder unter Verwendung von pkzip gespeichert.
        </dd>
    
        <dt><a name="transportlayersecurity" id="transportlayersecurity">Transport
          Layer Security</a> <span class="phonetic">[tr&#230;ns&#712;p&#596;&#720;t
          &#712;ei&#601; si&#712;kju&#601;riti]</span>
          <a name="tls" id="tls">(TLS)</a></dt>
        <dd>Das SSL-Nachfolgeprotokoll, das von der Internet Engineering Task
          Force (IETF) zur allgemeinen Authentisierung und Verschl&#252;sselung
          einer Kommunikation &#252;ber TCP/IP-Netzwerke entwickelt worden ist.
          TLS Version 1 ist nahezu identisch mit SSL Version 3.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sseliung</a>
        </dd>
    
        <dt><a name="environmentvariable" id="environmentvariable">Umgebungsvariable</a> <a name="env-variable" id="env-variable">(env-Variable)</a></dt>
        <dd>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.<br />
          Siehe: <a href="env.html">Umgebungsvariablen im Apache</a>
        </dd>
    
        <dt><a name="uniformresourcelocator" id="uniformresourcelocator">Uniform
          Resource Locator</a> <span class="phonetic">[&#712;ju&#720;nif&#596;&#720;m
          ri&#712;s&#596;&#720;s l&#601;u&#712;keit&#601;]</span>
          <a name="url" id="url">(URL)</a></dt>
        <dd>Der Name bzw. die Adresse einer Ressource im Internet. Dies ist der
          allgemein gebr&#228;uchliche Audruck f&#252;r die formale Bezeichnung
          <a class="glossarylink" href="./glossary.html#uniformresourceidentifier" title="siehe Glossar">Uniform Resource
          Identifier</a>. URLs bestehen &#252;blicherweise aus einem
          Schema wie <code>http</code> oder <code>https</code>, einem Hostnamen
          und einem Pfad. Die URL f&#252;r diese Seite ist
          <code>http://httpd.apache.org/docs/2.4/glossary.html</code>.
        </dd>
    
        <dt><a name="uniformresourceidentifier" id="uniformresourceidentifier">Uniform Resource Identifier</a>
          <span class="phonetic">[&#712;ju&#720;nif&#596;&#720;m
          ri&#712;s&#596;&#720;s ai&#712;dentifai&#601;]</span> 
          <a name="URI" id="URI">(URI)</a></dt>
        <dd>Eine kompakte Zeichenfolge zur Identifizierung einer abstrakten oder
          physischen Ressource. Er wird in dem <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a> formell
          definiert. Im World Wide Web verwendete URIs werden &#252;blicherweise
          als <a class="glossarylink" href="./glossary.html#url" title="siehe Glossar">URLs</a> bezeichnet.
        </dd>
    
        <dt><a name="virtualhosting" id="virtualhosting">Virtual-Hosting</a>
          <span class="phonetic">[v&#601;&#712;tju&#601;l
          h&#601;usti&#331;]</span></dt>
        <dd>Die Bedienung mehrere Websites mit einer einzigen Apache-Instanz.
          <em>IP-basierte virtuelle Hosts</em> unterscheiden zwischen
          verschiedenen Websites aufgrund ihrer IP-Adressen, w&#228;hrend
          <em>namensbasierte virtuelle Hosts</em> nur den Namen des Hosts
          verwenden und daher mehrere Angebote unter der gleichen IP-Adresse
          hosten k&#246;nnen.<br />
          Siehe: <a href="vhosts/">Apache-Dokumentation zu virtuellen
          Hosts</a>
        </dd>
    
        <dt><a name="fully-qualifieddomain-name" id="fully-qualifieddomain-name">Voll-qualifizierter Domainname</a>
          <a name="fqdn" id="fqdn">(FQDN)</a></dt>
        <dd>Der eindeutige Name einer Netzwerkeinheit, bestehend aus einem
          Hostnamen und dem Domainnamen, welcher zu einer IP-Adresse
          aufgel&#246;st werden kann. Zum Beispiel ist <code>www</code> ein
          Hostname, <code>example.com</code> ein Domainname und
          <code>www.example.com</code> ein voll-qualifizierter Domainname.
        </dd>
    
        
        <dt><a name="website" id="website">Website</a>
          <span class="phonetic">[websait]</span></dt>
        <dd>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.
        </dd>
    
        <dt><a name="x.509" id="x.509">X.509</a></dt>
        <dd>Ein von der International Telecommunication Union (ITU-T) empfohlenes
          Schema f&#252;r Authentifizierungszertifikate. Es wird f&#252;r
          SSL/TLS-Authentifizierungen verwendet.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="certificate" id="certificate">Zertifikat</a></dt>
        <dd>Ein Datensatz zur <a class="glossarylink" href="./glossary.html#authentication" title="siehe Glossar">Authentisierung</a> einer 
          Nertzwerkeinheit wie Server oder Client. Ein Zertifikat
          enth&#228;lt <a class="glossarylink" href="./glossary.html#x.509" title="siehe Glossar">X.509</a>-Informationen
          &#252;ber seinen Eigent&#252;mer (das sogenannte Betreff
          <span class="transnote">(<em>Anm.d.&#220;.:</em> engl.: subject)</span>) und die
          signierende <a class="glossarylink" href="./glossary.html#certificationauthority" title="siehe Glossar">Certification
          Authority</a> (der sogenannte Aussteller <span class="transnote">(<em>Anm.d.&#220;.:</em> engl.:
          issuer)</span>) sowie den <a class="glossarylink" href="./glossary.html#publickey" title="siehe Glossar">&#246;ffentlichen Schl&#252;ssel</a> des
          Eigent&#252;mers und die Signatur der CA. Netzwerkeinheiten
          &#252;berpr&#252;fen diese Signatur mit Hilfe von CA-Zertifikaten.<br />
          Siehe: <a href="ssl/">SSL/TLS-Verschl&#252;sselung</a>
        </dd>
    
        <dt><a name="accesscontrol" id="accesscontrol">Zugriffskontrolle</a></dt>
        <dd>Die Beschr&#228;nkung des Zugriffs auf Netzwerkbereiche. Im
          Apache-Kontext in der Regel die Zugriffsbeschr&#228;nkung auf bestimmte
          <em>URLs</em>.<br />
          Siehe: <a href="howto/auth.html">Authentisierung, Autorisierung und
          Zugriffskontrolle</a>
        </dd>
      </dl>    
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/glossary.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/glossary.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html.de�����������������������������������������������������������0000664�0001751�0001751�00000033644�14744525602�020153� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache starten - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache starten</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/invoking.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
        <p>Unter Windows l&#228;uft der Apache &#252;blicherweise als Dienst
        (Windows NT, 2000 und XP) oder als Konsolenanwendung (Windows 9x und
        ME). F&#252;r Einzelheiten lesen Sie bitte <a href="platform/windows.html#winsvc">Apache als Dienst betreiben</a>
        und <a href="platform/windows.html#wincons">Apache als Konsolenanwendung betreiben</a>.</p>
    
        <p>Unter Unix wird das <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Programm als Daemon
        ausgef&#252;hrt, der im Hintergrund fortlaufend aktiv ist, um
        Anfragen zu bearbeiten. Dieses Dokument beschreibt, wie
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> aufgerufen wird.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#startup">Wie der Apache startet</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errors">Fehler w&#228;hrend des Hochfahrens</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#boot">Beim Bootvorgang starten</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#info">Weitere Informationen</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><a href="stopping.html">Beenden und Neustarten</a></li><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="startup" id="startup">Wie der Apache startet</a></h2>
    
        <p>Wenn die in der Konfigurationsdatei angegebene <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>-Anweisung auf die Voreinstellung
        von 80 gesetzt ist (oder einen anderen Port unterhalb von 1024), dann
        m&#252;ssen Sie root-Berechtigung besitzen, um den Apache starten
        zu k&#246;nnen. Nur dann kann er sich an diesen privilegierten
        Port binden. Sobald der Server gestartet ist und einige vorbereitende
        Aktionen wie das &#214;ffnen seiner Log-Dateien ausgef&#252;hrt hat,
        startet er mehrere <em>Kind</em>-Prozesse, welche die Arbeit erledigen:
        das Lauschen auf und Beantworten von Anfragen von Clients. Der
        Haupt-<code>httpd</code>-Prozess l&#228;uft unter dem Benutzer root
        weiter, die Kind-Prozesse jedoch werden unter weniger privilegierten
        Benutzerkennungen ausgef&#252;hrt. Dies wird von dem ausgew&#228;hlten
        <a href="mpm.html">Multi-Processing-Modul</a> gesteuert.</p>
    
        <p>Die Verwendung des Steuerskripts <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> ist die
        empfohlene Methode, das <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Programm zu starten.
        Dieses Skript setzt verschiedene Umgebungsvariablen, die f&#252;r die
        korrekte Funktion von <code class="program"><a href="./programs/httpd.html">httpd</a></code> unter einigen
        Betriebssystemen notwendig sind, und startet dann das
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Programm. <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>
        reicht alle Kommandozeilenargumente durch, so dass alle
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Optionen auch mit <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>
        verwendet werden k&#246;nnen. Um den korrekten Ablageort des
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Programms sowie einige Kommandozeilenargumente
        anzugeben, die Sie <em>immer</em> verwenden m&#246;chten, k&#246;nnen
        Sie auch das Skript <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> direkt editieren und die
        Variable <code>HTTPD</code> am Anfang &#228;ndern.</p>
    
        <p>Das Erste was <code>httpd</code> macht, wenn es startet, ist das
        Suchen und Einlesen der <a href="configuring.html">Konfigurationsdatei</a> <code>httpd.conf</code>.
        Der Ablageort dieser Datei wird zur Kompilierungszeit festgelegt. Es ist
        aber m&#246;glich, den Ablageort zur Laufzeit anzugeben, indem die
        Kommandozeilenoption <code>-f</code> wie folgt verwendet wird:</p>
    
        <div class="example"><p><code>/usr/local/apache2/bin/apachectl -f
          /usr/local/apache2/conf/httpd.conf</code></p></div>
    
        <p>Wenn w&#228;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&#228;uft.
        Sie k&#246;nnen nun Ihren Browser benutzen, um Verbindung zum Server
        aufzunehmen und sich die Testseite im <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>-Verzeichnis anzusehen wie auch
        die lokale Kopie der Dokumentation, die von dieser Seite aus verlinkt
        ist.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errors" id="errors">Fehler w&#228;hrend des Hochfahrens</a></h2>
    
        <p>Wenn der Apache w&#228;hrend des Hochfahrens einen schweren Fehler
        feststellt, schreibt er entweder eine Nachricht, die das Problem
        n&#228;her schildert, auf die Konsole oder ins <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code>, bevor er sich selbst beendet.
        Eine der h&#228;ufigsten Fehlermeldungen ist "<code>Unable
        to bind to Port ...</code>" <span class="transnote">(<em>Anm.d.&#220;.:</em> "Kann nicht an Port ...
        binden")</span>. Diese Meldung wird &#252;blicherweise verursacht:</p>
    
        <ul>
          <li>entweder durch den Versuch, den Server an einem privilegierten
          Port zu starten, w&#228;hrend man nicht als Benutzer root angemeldet
          ist,</li>
    
          <li>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.</li>
        </ul>
    
        <p>F&#252;r weitere Anleitungen zur Fehlerbehebung lesen Sie bitte die
        Apache-<a href="faq/">FAQ</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="boot" id="boot">Beim Bootvorgang starten</a></h2>
    
        <p>Wenn Sie m&#246;chten, dass Ihr Server direkt nach einem
        System-Neustart weiterl&#228;uft, sollten Sie einen Aufruf von
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> zu den Startdateien Ihres Systems
        hinzuf&#252;gen (&#252;blicherweise <code>rc.local</code> oder
        eine Datei in einem <code>rc.N</code>-Verzeichnis). Dies startet
        den Apache als root. Stellen Sie zuvor jedoch sicher, dass Ihr
        Server hinsichtlich Sicherheit und Zugriffsbeschr&#228;nkungen
        richtig konfiguriert ist.</p>
    
        <p>Das <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>-Skript ist daf&#252;r ausgelegt, wie
        ein Standard-SysV-init-Skript zu arbeiten. Es akzeptiert die Argumente
        <code>start</code>, <code>restart</code> und <code>stop</code>
        und &#252;bersetzt sie in die entsprechenden Signale f&#252;r
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>. Daher k&#246;nnen Sie oftmals
        einfach <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> in das entsprechende init-Verzeichnis
        linken. &#220;berpr&#252;fen Sie bitte auf jeden Fall die genauen
        Anforderungen Ihres Systems.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="info" id="info">Weitere Informationen</a></h2>
    
        <p>Weitere Informationen &#252;ber Kommandozeilenoptionen von <code class="program"><a href="./programs/httpd.html">httpd</a></code> und <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> sowie anderen
        Hilfsprogrammen, die dem Server beigef&#252;gt sind, sind auf der
        Seite <a href="programs/">Server und Hilfsprogramme</a>
        verf&#252;gbar. Es existiert au&#223;erdem eine Dokumentation
        aller in der Apache-Distribution enthaltenen <a href="mod/">Module</a> und der von ihnen bereitgestellten
        <a href="mod/directives.html">Direktiven</a>.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/invoking.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/invoking.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�015646� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/index.html.tr.utf8�����������������������������������������������������0000664�0001751�0001751�00000012156�14743132254�021150� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache SSL/TLS Şifrelemesi - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache SSL/TLS Şifrelemesi</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
      <p>Apache HTTP Sunucusunun <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> modülü, Güvenli Soketler
        Katmanı (SSL) ve Aktarım Katmanı Güvenliği (TLS) protokollerinin
        kullanıldığı Sağlam Şifreleme desteğini sağlayan <a href="http://www.openssl.org/">OpenSSL</a> kütüphanesine bir arayüz
        içerir.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#documentation">Belgeler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mod-ssl"><code>mod_ssl</code> Modülü</a></li>
    </ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">Belgeler</a></h2>
      <ul>
        <li><a href="ssl_howto.html">mod_ssl Yapılandırması Nasıl</a></li>
        <li><a href="ssl_intro.html">SSL'ye Giriş</a></li>
        <li><a href="ssl_compat.html">Uyumluluk</a></li>
        <li><a href="ssl_faq.html">Sıkça Sorulan Sorular</a></li>
        <li><a href="../glossary.html">Terimler</a></li>
      </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mod-ssl" id="mod-ssl"><code>mod_ssl</code> Modülü</a></h2>
      <p>Bu modülce sağlanan yönergeler ve ortam değişkenleri
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> başvuru kılavuzunda ayrıntılı olarak
        açıklanmıştır.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/index.html.ja.utf8�����������������������������������������������������0000664�0001751�0001751�00000012274�14743132254�021116� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache の SSL/TLS 暗号化 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache の SSL/TLS 暗号化</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>Apache HTTP サーバモジュール <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> が
    <a href="http://www.openssl.org/">OpenSSL</a>
    ライブラリへのインターフェースを提供していますが、これは
    Secure Sockts Layer と Transport Layer Security
    プロトコルを用いた強力な暗号化を提供します。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#documentation">Documentation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mod-ssl">mod_ssl</a></li>
    </ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">Documentation</a></h2>
    <ul>
    <li><a href="ssl_howto.html">mod_ssl Configuration How-To</a></li>
    <li><a href="ssl_intro.html">Introduction To SSL</a></li>
    <li><a href="ssl_compat.html">互換性</a></li>
    <li><a href="ssl_faq.html">よくある質問</a></li>
    <li><a href="../glossary.html">用語</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mod-ssl" id="mod-ssl">mod_ssl</a></h2>
    <p>このモジュールで提供されるディレクティブや環境変数に関する
    詳しい文書は、<a href="../mod/mod_ssl.html">mod_ssl
    リファレンス</a>をご覧下さい。</p>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/index.html.fr.utf8�����������������������������������������������������0000664�0001751�0001751�00000012166�14740503670�021134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache et le Chiffrement SSL/TLS - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache et le Chiffrement SSL/TLS</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>Le module <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> du serveur HTTP Apache fournit une
    interface avec la bibliothèque <a href="http://www.openssl.org/">OpenSSL</a>, qui permet d'effectuer un
    chiffrement fort en s'appuyant sur les protocoles "Couche Points d'accès
    Sécurisés" (Secure Sockets Layer - SSL) et "Sécurité de la Couche Transport"
    (Transport Layer Security - TLS).</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#documentation">Documentation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mod-ssl">mod_ssl</a></li>
    </ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">Documentation</a></h2>
    <ul>
    <li><a href="ssl_howto.html">Comment configurer SSL ?</a></li>
    <li><a href="ssl_intro.html">Introduction à SSL</a></li>
    <li><a href="ssl_compat.html">Compatibilité</a></li>
    <li><a href="ssl_faq.html">Foire aux questions</a></li>
    <li><a href="../glossary.html">Glossaire</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mod-ssl" id="mod-ssl">mod_ssl</a></h2>
    <p>La documentation complète sur les directives et les variables
    d'environnement fournies par ce module se trouve dans la
    <a href="../mod/mod_ssl.html">documentation de référence de mod_ssl</a>.
    </p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_intro.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000117147�14740503670�022046� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Chiffrement SSL/TLS fort :  Introduction - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>Chiffrement SSL/TLS fort :  Introduction</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_intro.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_intro.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/ssl_intro.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div>
    
    
    <p>Ce chapitre en guise d'introduction est destiné aux lecteurs pour lesquels
    le Web, HTTP et Apache sont familiers, mais ne sont pas des experts en matière
    de sécurité. Il n'a pas la prétention d'être un guide détaillé sur le
    protocole SSL, il ne traitera pas non plus des techniques spécifiques de gestion
    des certificats dans une organisation, ni des importants problèmes légaux de
    brevets ou des restrictions d'importation ou d'exportation. Il se veut plutôt
    une base de travail pour les utilisateurs de <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> en
    rassemblant différents concepts, définitions et exemples comme point de départ
    pour une exploration plus détaillée.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#cryptographictech">Techniques de chiffrement</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#certificates">Certificats</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssl">Couche Points d'Accès Sécurisés - Secure Sockets Layer (SSL)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#references">Références</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cryptographictech" id="cryptographictech">Techniques de chiffrement</a></h2>
    
    <p>La maîtrise de SSL nécessite la compréhension des algorithmes de
    chiffrement, des fonctions relatives aux empreintes de messages (comme les
    fonctions de type hash ou non réversibles), et des signatures numériques. Ces
    techniques pourraient faire l'objet d'un ouvrage à elles seules (voir par
    exemple [<a href="#AC96">AC96</a>]) et constituent les bases de la
    confidentialité, de l'intégrité et de l'authentification.</p>
    
    <h3><a name="cryptographicalgo" id="cryptographicalgo">Algorithmes de chiffrement</a></h3>
    
        <p>Supposons qu'Alice veuille envoyer un message à sa banque pour
        transférer une certaine somme. Alice souhaiterait que le message soit
        privé, car il contient des informations comme son numéro de compte et le
        montant du transfert. Une solution consisterait à utiliser un algorithme de
        chiffrement, technique qui permet de remplacer un message par sa version
        chiffrée, illisible jusqu'à ce qu'elle soit déchiffrée.
        Sous sa forme chiffrée,
        le message ne peut être déchiffré qu'en utilisant une clé secrète. Sans la
        clé, le message est inutilisable : les bons algorithmes de chiffrement
        rendent si difficile la restitution du texte original par des intrus que
        ceux-ci y gaspilleraient leurs efforts.</p>
    
        <p>Il existe deux catégories d'algorithmes de chiffrement : conventionnel
        ou à clé publique.</p>
    
        <dl>
        <dt>Chiffrement conventionnel</dt>
        <dd>aussi connu sous le nom de chiffrement symétrique, il nécessite le
        partage d'une clé entre l'expéditeur et le destinataire : une portion
        d'information secrète permettant de chiffrer et déchiffrer un message.
        Tant que cette clé reste secrète, personne à part l'expéditeur et le
        destinataire ne peut lire le message. Si Alice et sa banque partagent une
        clé secrète, ils peuvent donc s'envoyer l'un à l'autre des messages privés.
        Le fait de partager une clé entre l'expéditeur et le destinataire avant
        de communiquer, tout en la maintenant secrète vis à vis des autres, peut
        toutefois poser des problèmes.</dd>
    
        <dt>Chiffrement à clé publique</dt>
        <dd>aussi connu sous le nom de chiffrement asymétrique, il résoud le
        problème d'échange de clé en définissant un algorithme qui utilise deux
        clés, chacune d'entre elles pouvant être utilisée pour chiffrer un message.
        Si une des clés a été utilisée pour chiffrer le message, on doit utiliser
        l'autre clé pour le déchiffrer. Il est ainsi possible de recevoir des
        messages sécurisés simplement en rendant publique une des clés (la clé
        publique), et en gardant l'autre clé secrète (la clé privée).</dd>
        </dl>
    
        <p>Tout le monde peut chiffrer un message en utilisant la clé publique,
        mais seul le propriétaire de la clé privée sera en mesure de le lire. De
        cette façon, Alice peut envoyer des messages privés au propriétaire d'une
        paire de clés (sa banque), en les chiffrant à l'aide de la clé publique.
        Seule la banque sera en mesure de les déchiffrer.</p>
    
    
    <h3><a name="messagedigests" id="messagedigests">Empreinte d'un message</a></h3>
    
        <p>Bien qu'Alice puisse chiffrer son message pour le rendre privé, il
        subsiste toujours le risque que quelqu'un puisse modifier le message
        original ou le remplacer par un autre, afin d'effectuer le transfert de
        fonds à son profit, par exemple. Une solution pour garantir l'intégrité du
        message consisterait pour Alice à créer un résumé concentré de son message
        qu'elle enverrait à sa banque avec ce dernier. A la réception du message,
        la banque crée son propre résumé et le compare avec celui qu'Alice a
        envoyé. Si les deux résumés sont identiques, le message reçu n'a pas
        été modifié.</p>
    
        <p>Un résumé tel que celui-ci est appelé
        <dfn>empreinte numérique de message</dfn> (message digest),
        <em>fonction irréversible</em> (one-way function) ou
        <em>fonction de hashage</em> (hash function). Une empreinte de message
        constitue une représentation courte et de longueur fixe, d'un message plus
        long et de longueur variable. Les algorithmes de création d'empreintes sont
        conçus pour produire une empreinte unique pour chaque message. Les
        empreintes de messages sont conçues pour que la restitution du message
        à partir de l'empreinte soit d'une difficulté insurmontable, et qu'il soit
        (en théorie) impossible de trouver deux messages différents qui produisent
        la même empreinte -- ce qui élimine la possibilité de remplacer un message
        par un autre en conservant la même empreinte.</p>
    
        <p>Trouver le moyen d'envoyer l'empreinte de manière sécurisée à la banque
        constitue un autre défit auquel Alice doit faire face ; si l'empreinte
        n'est pas envoyée de manière sécurisée, son intégrité peut être compromise,
        et avec elle, la possibilité pour la banque de vérifier l'intégrité du
        message original. L'intégrité du message ne peut être vérifiée que si
        l'empreinte qui lui est associée est envoyée de manière sécurisée.</p>
    
        <p>Une solution pour envoyer l'empreinte de manière sécurisée consiste à
        l'inclure dans une signature numérique.</p>
    
    
    <h3><a name="digitalsignatures" id="digitalsignatures">Signatures numériques</a></h3>
    <p>Quand Alice envoie un message à sa banque, cette dernière doit s'assurer
    que le message a bien été envoyé par elle, pour éviter qu'un intrus puisse
    effectuer une transaction sur son compte. Une <em>signature numérique</em>,
    créée par Alice et incluse dans le message, permet d'atteindre cet
    objectif.</p>
    
    <p>Les signatures numériques peuvent être créées en chiffrant une empreinte de
    message, ainsi que d'autres informations (comme un numéro d'ordre) avec la clé
    privée de l'expéditeur. Bien que tout le monde puisse <em>déchiffrer</em> la
    signature à l'aide de la clé publique, seul l'expéditeur connait la clé privée.
    Ce qui implique que seul l'expéditeur peut avoir signé le message. Inclure
    l'empreinte dans la signature entraîne que cette dernière n'est valable que
    pour ce message ; ceci assure aussi l'intégrité du message car personne ne
    peut modifier l'empreinte et ensuite signer le message.</p>
    <p>Afin de se prémunir contre l'interception et la réutilisation de la
    signature par un intrus quelques jours plus tard, la signature contient un
    numéro d'ordre unique. Ceci protège la banque contre une plainte frauduleuse
    de la part d'Alice alléguant qu'elle n'a pas envoyé le message --
    elle seule peut l'avoir signé (non-répudiation).</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="certificates" id="certificates">Certificats</a></h2>
    
    <p>Bien qu'Alice soit parvenue à envoyer un message privé à sa banque, après
    l'avoir signé et avoir ainsi assuré l'intégrité du message, elle doit encore vérifier
    qu'elle communique réellement avec la banque. C'est à dire qu'elle doit
    s'assurer que la clé publique qu'elle utilise appartient bien à la paire de
    clés de la banque, et non à celle d'un intrus.
    De même, la banque doit vérifier que la
    signature du message a bien été construite avec la clé privée d'Alice.</p>
    
    <p>Si chaque partie possède un certificat qui valide l'identité de l'autre,
    confirme la clé publique, et est signé par un organisme de confiance, alors
    les deux protagonistes peuvent être sûrs que la personne avec laquelle ils
    communiquent est bien celle avec laquelle ils désirent le faire. Un tel
    organisme de confiance s'appelle une <em>Autorité de Certification</em>, et
    on utilise les certificats à des fins d'authentification.</p>
    
    <h3><a name="certificatecontents" id="certificatecontents">Contenu d'un certificat</a></h3>
    
        <p>Un certificat associe une clé publique avec l'identité réelle d'un
        individu, d'un serveur, ou d'une autre entité plus connue sous le nom de
        sujet. Comme on le voit dans le <a href="#table1">Tableau 1</a>, les
        information concernant le sujet comprennent des informations
        d'identification (le nom distinctif ou distinguished name - dn), ainsi que
        la clé publique. Il comporte aussi l'identification et la signature de
        l'autorité de certification qui a délivré le certificat, ainsi que la
        période de validité de ce dernier. Il peut aussi contenir des informations
        supplémentaires (ou extensions) telles que des informations de gestion
        destinées à l'autorité de certification, comme un numéro de série.</p>
    
        <h4><a name="table1" id="table1">Tableau 1: Information contenues dans un certificat</a></h4>
        
        <table>
        
        <tr><th>Sujet</th>
            <td>Nom distinctif, Clé publique</td></tr>
        <tr><th>Fournisseur</th>
            <td>Nom distinctif, Signature</td></tr>
        <tr><th>Période de validité</th>
            <td>Pas avant, Pas après</td></tr>
        <tr><th>Informations de gestion</th>
            <td>Version, Numéro de série</td></tr>
        <tr><th>Extensions</th>
            <td>Contraintes de base, Drapeaux Netscape, etc.</td></tr>
        </table>
        
    
        <p>Un nom distinctif sert à fournir une identité dans un contexte
        spécifique -- par exemple, un individu peut posséder un certificat
        personnel, et aussi un certificat en tant qu'employé. Les noms distinctifs
        doivent respecter le standard X509 [<a href="#X509">X509</a>], qui définit
        les champs, les noms de champs, et les abréviations utilisées pour faire
        référence aux champs (voir <a href="#table2">Tableau 2</a>).</p>
    
        <h4><a name="table2" id="table2">Tableau 2: Informations contenues dans le nom distinctif</a></h4>
        
        <table class="bordered">
        
        <tr><th>Champ du DN</th>
            <th>Abrév.</th>
            <th>Description</th>
            <th>Exemple</th></tr>
        <tr><td>Nom complet (Common Name)</td>
            <td>CN</td>
            <td>Nom certifié</td>
            <td>CN=Joe Average</td></tr>
        <tr><td>Organisation or Entreprise</td>
            <td>O</td>
            <td>Nom est associé à cette<br />organisation</td>
            <td>O=Snake Oil, Ltd.</td></tr>
        <tr><td>Unité organisationnelle (Organizational Unit)</td>
            <td>OU</td>
            <td>Nom est associé avec cette <br />unité organisationnelle,
    	par exemple un département</td>
            <td>OU=Research Institute</td></tr>
        <tr><td>Ville/Localisation</td>
            <td>L</td>
            <td>Nom est localisé dans cette ville</td>
            <td>L=Snake City</td></tr>
        <tr><td>Etat/Province</td>
            <td>ST</td>
            <td>Nom est localisé dans cet état/province</td>
            <td>ST=Desert</td></tr>
        <tr><td>Pays</td>
            <td>C</td>
            <td>Nom est localisé dans ce pays (code ISO)</td>
            <td>C=XZ</td></tr>
        </table>
        
    
        <p>Une autorité de certification peut définir une contrainte spécifiant
        quels champs du nom distinctif sont optionnels et lesquels sont
        obligatoires. Elle peut aussi imposer des contraintes sur le contenu des
        champs, ce que peuvent aussi faire les utilisateurs de certificats. Par
        exemple, un navigateur Netscape peut exiger, dans le cas d'un certificat
        de serveur, que le nom complet (Common Name) corresponde à un nom générique
        contenant le nom de domaine du serveur, comme
        <code>*.snakeoil.com</code>.</p>
    
        <p>Le format binaire d'un certificat est défini en utilisant la
        notation ASN.1 [<a href="#ASN1">ASN1</a>] [<a href="#PKCS">PKCS</a>].
        Cette notation definit la manière de spécifier les contenus, et les règles
        d'encodage définissent la manière dont ces information sont converties au
        format binaire. L'encodage binaire du certificat est défini par les Règles
        d'Encodage Distinctives (Distinguished Encoding Rules - DER), qui se basent
        d'une manière plus générale sur les Règles d'Encodage de Base (Basic
        Encoding Rules - BER). Pour les transmissions qui ne supportent pas le
        format binaire, ce dernier peut être converti au format ASCII en utilisant
        le codage Base64 [<a href="#MIME">MIME</a>]. Lorsqu'il est placé entre des
        délimiteurs de début et de fin (comme ci-dessous), on dit que le certificat
        est encodé au format PEM ("Privacy Enhanced Mail").</p>
    
        <div class="example"><h3>Exemple de certificat encodé au format PEM (snakeoil.crt)</h3><pre>-----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-----</pre></div>
    
    
    <h3><a name="certificateauthorities" id="certificateauthorities">Autorités de certification</a></h3>
    
        <p>En vérifiant les informations contenues dans une demande de certificat
        avant de l'accorder, l'autorité de certification s'assure de l'identité du
        propriétaire de la clé privée issue de sa paire de clés. Par exemple, Si
        Alice demande un certificat personnel, l'autorité de certification doit
        d'abord s'assurer qu'elle correspond vraiment à la personne à laquelle
        la demande de certificat fait référence.</p>
    
        <h4><a name="certificatechains" id="certificatechains">Chaînes de certification</a></h4>
        
            <p>Une autorité de certification peut aussi émettre un certificat à
    	destination d'une
    	autre autorité de certification. Pour vérifier un certificat, Alice
    	peut être amenée à vérifier le certificat de l'émetteur pour chaque
    	autorité de certification parente, jusqu'à ce qu'elle en atteigne une
    	en qui elle a confiance. Elle peut aussi ne faire confiance qu'aux
    	certificats faisant l'objet d'une chaîne limitée d'émetteurs, afin
    	de réduire le risque de rencontrer un "mauvais" certificat dans la
    	chaîne.</p>
        
    
        <h4><a name="rootlevelca" id="rootlevelca">Création d'une autorité de certification racine</a></h4>
        
            <p>Comme indiqué plus haut, chaque certificat nécessite la validation
    	de l'identité du sujet par un émetteur de certificats
    	de niveau supérieur, et ceci en
    	remontant jusqu'à l'Autorité de Certification (CA) racine. Ceci pose un
    	problème : qui va se porter garant du certificat de l'autorité racine
    	qui ne possède pas d'émetteur de certificat ? C'est uniquement dans ce
    	cas que le certificat est auto-signé, l'émetteur du certificat et son
    	sujet étant confondus. Les navigateurs sont préconfigurés avec une
    	liste d'autorités de certification de confiance, mais il est important
    	d'être extrèmement prudent avant de faire confiance à un certificat
    	auto-signé. La large publication d'une clé publique par l'autorité
    	racine réduit cependant les risques encourus
    	en faisant confiance à cette clé --
    	si quelqu'un publiait une clé en se faisant passer pour l'autorité, il
    	serait vite démasqué.</p>
    
            <p>Quelques compagnies, comme <a href="http://www.thawte.com/">Thawte</a> et <a href="http://www.verisign.com/">VeriSign</a>,
    	se sont proclamées elles-mêmes Autorités de Certification. Ces
    	compagnies proposent les services suivant :</p>
    
            <ul>
            <li>Vérification des demandes de certificats</li>
            <li>Traitement des demandes de certificats</li>
            <li>Emission et gestion des certificats</li>
            </ul>
    
            <p>Vous pouvez aussi créer votre propre autorité de certification. Bien
    	que risqué dans l'environnement de l'Internet, ceci peut s'avérer utile
    	dans un Intranet, où l'organisme peut vérifier facilement les identités
    	des individus et des serveurs.</p>
        
    
        <h4><a name="certificatemanagement" id="certificatemanagement">Gestion des certificats</a></h4>
        
            <p>Constituer une autorité de certification représente une
    	responsabilité qui nécessite une solide infrastructure administrative,
    	technique et gestionnaire. Les autorités de certification ne se
    	contentent pas d'émettre des certificats, elles doivent aussi les gérer
    	-- à savoir elles déterminent leur durée de validité, elles les
    	renouvellent, et elles maintiennent des listes de certificats qui ont
    	été émis dans le passé mais ne sont plus valides (Listes de révocations
    	de certificats, ou CRLs).</p>
    
            <p>Par exemple, si Alice est titulaire d'un certificat en tant
    	qu'employée d'une compagnie, mais vient de quitter cette compagnie,
    	son certificat doit être révoqué. Comme les certificats ne sont émis
    	qu'après vérification de l'identité du sujet, et peuvent être envoyés
    	à tous ceux avec lesquels le sujet peut communiquer, il est impossible
    	de discerner à partir du seul certificat s'il a été révoqué. Pour
    	vérifier la validité d'un certificat, il est donc nécessaire de
    	contacter l'autorité de certification qui l'a émis afin de pouvoir
    	consulter ses listes de révocations de certificats -- ce qui n'est
    	en général pas une partie automatique du processus.</p>
    
            <div class="note"><h3>Note</h3>
            <p>Si votre autorité de certification ne fait pas partie de la liste
    	des autorités de confiance de votre navigateur, il faut enregistrer le
    	certificat de l'autorité de certification dans ce dernier, ce qui lui
    	permettra de valider les certificats de serveurs signés par cette
    	autorité de certification. Ceci peut être dangereux, car une fois le
    	certificat enregistré, le navigateur acceptera tous les certificats
    	signés par cette autorité de certification.</p>
            </div>
        
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssl" id="ssl">Couche Points d'Accès Sécurisés - Secure Sockets Layer (SSL)</a></h2>
    
    <p>Le protocole Couche Points d'Accès Sécurisés est une couche protocolaire
    qui pourrait s'intercaler entre un protocole d'une couche réseau orientée
    connexion (comme TCP/IP) et une couche protocolaire d'application (comme HTTP).
    SSL fournit une communication sécurisée entre client et serveur en permettant
    l'authentification mutuelle, l'utilisation des signatures numériques pour la
    vérification de l'intégrité des données, et le chiffrement pour la
    confidentialité.</p>
    
    <p>Ce protocole est conçu pour supporter un grand choix d'algorithmes
    spécifiques utilisés pour la cryptographie, les empreintes et les signatures.
    Ceci permet la sélection d'un algorithme pour des serveurs spécifiques en
    respectant la légalité, les règles d'exportation ou autres contraintes, et
    permet aussi au protocole de tirer parti des nouveaux algorithmes. Ces choix
    font l'objet d'une négociation entre client et serveur lors de
    l'établissement de la session protocolaire.</p>
    
    <h3><a name="table4" id="table4">Tableau 4: Versions du protocole SSL</a></h3>
    
        <table class="bordered">
        
        <tr><th>Version</th>
            <th>Source</th>
            <th>Description</th>
        </tr>
        <tr><td>SSL v2.0</td>
            <td>Standard du fournisseur (de Netscape Corp.)</td>
            <td>Premier protocole SSL pour lequel il existe des implémentations</td>
        </tr>
        <tr><td>SSL v3.0</td>
            <td>Projet Internet arrivé à expiration (de Netscape Corp.) [<a href="#SSL3">SSL3</a>]</td>
            <td>Comporte des révisions permettant de prévenir certaines attaques de
    	sécurité spécifiques, ajout de chiffrements non RSA, et support des
    	chaînes de certification</td>
        </tr>
        <tr><td>TLS v1.0</td>
            <td>Standard proposé pour l'Internet (de l'IETF) [<a href="#TLS1">TLS1</a>]</td>
            <td>Révision de SSL 3.0 pour mettre à jour la couche MAC vers HMAC,
    	ajout du bourrage de bloc pour le chiffrement de bloc, standardisation
    	de l'ordonnancement des messages et plus de messages d'alerte.</td>
        </tr>
    	<tr><td>TLS v1.1</td>
            <td>Standard proposé pour l'Internet (de l'IETF) [<a href="#TLS11">TLS11</a>]</td>
            <td>Mise à jour de TLS 1.0 pour la protection contre les
    	attaques de type Cipher block chaining (CBC).</td>
        </tr>
        <tr><td>TLS v1.2</td>
            <td>Standard proposé pour l'Internet (de l'IETF) [<a href="#TLS12">TLS12</a>]</td>
            <td>Mise à jour de TLS 1.1 rendant les condensés MD5 obsolètes,
    	et introduisant une incompatibilité avec SSL ce qui interdit toute
    	négociation en vue d'une utilisation de SSLv2.</td>
        </tr>
        </table>
    
    
    <p>Il existe plusieurs versions du protocole SSL, comme le montre le
    <a href="#table4">Tableau 4</a>. Comme indiqué dans ce dernier, un des apports
    de SSL 3.0 est le support du chargement des chaînes de certification. Cette
    fonctionnalité permet à un serveur de passer au navigateur un certificat de
    serveur accompagné du certificat de l'émetteur. Le chargement de la
    chaîne permet aussi au navigateur de valider le certificat du serveur, même si
    les certificats de l'autorité de certification ne sont pas installés pour les
    émetteurs intermédiaires, car ils sont inclus dans la chaîne de certification.
    SSL 3.0 sert de base au standard du protocole Sécurité de la Couche Transport
    ou Transport Layer Security
    [<a href="#TLS1">TLS</a>], actuellement en développement au sein de
    l'Internet Engineering Task Force (IETF).</p>
    
    <h3><a name="session" id="session">Etablissement d'une session</a></h3>
    
        <p>La session SSL est établie en suivant une séquence d'échanges
        d'informations entre client et serveur, comme le montre la
        <a href="#figure1">Figure 1</a>. Cette séquence peut varier, selon que
        le serveur est configuré pour fournir un certificat de serveur ou
        réclame un certificat client. Bien que dans certains cas, des étapes
        d'échanges d'informations supplémentaires soient nécessaires pour la
        gestion des informations de chiffrement, cet article résume un scénario
        courant. Se reporter aux spécifications SSL pour avoir la liste de
        toutes les possibilités.</p>
    
        <div class="note"><h3>Note</h3>
        <p>Une fois la session SSL établie, elle peut être réutilisée. Ceci
        permet d'éviter la perte de performances due à la répétition des nombreuses
        étapes nécessaires à l'établissement d'une session. Pour parvenir à ceci,
        le serveur assigne un identifiant de session unique à chaque session SSL ;
        cet identifiant est mis en cache dans le serveur et le client peut
        l'utiliser pour des connexions ultérieures afin de réduire la durée des
        échanges d'informations (et ceci jusqu'à ce que l'identifiant de session
        arrive à expiration dans le cache du serveur).</p>
        </div>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig1.gif" alt="" width="423" height="327" /><br />
        <a id="figure1" name="figure1"><dfn>Figure 1</dfn></a> : Séquence
        simplifiée d'échanges d'informations SSL</p>
    
        <p>Les éléments de la séquence d'échanges d'informations, tels qu'ils
        sont utilisés par le client et le serveur, sont énumérés ci-après :</p>
    
        <ol>
        <li>Négociation de la suite de chiffrement à utiliser durant le transfert des données</li>
        <li>Elaboration et échange d'une clé de session entre le client et le serveur</li>
        <li>Authentification éventuelle du serveur par le client</li>
        <li>Authentification éventuelle du client par le serveur</li>
        </ol>
    
        <p>La première étape, la négociation de la suite de chiffrement, permet au
        client et au serveur de choisir une suite de chiffrement qu'ils supportent
        tous les deux. La spécification du protocole SSL 3.0 définit 31 suites de
        chiffrement. Une suite de chiffrement se compose des éléments
        suivants :</p>
    
        <ul>
        <li>Méthode d'échange de la clé</li>
        <li>Chiffrement du transfert des données</li>
        <li>Empreinte du message servant à créer le code d'authentification du
        message (MAC)</li>
        </ul>
    
        <p>Ces trois éléments sont décrits dans les sections suivantes.</p>
    
    
    <h3><a name="keyexchange" id="keyexchange">Méthode d'échange de la clé</a></h3>
    
        <p>La méthode d'échange de la clé définit la manière
        dont la clé de chiffrement
        symétrique secrète et partagée utilisée pour le transfert des données de
        l'application sera acceptée par le client et le serveur. SSL 2.0 utilise
        l'échange de clé RSA seulement, tandis que SSL 3.0 supporte tout un choix
        d'algorithmes d'échange de clé incluant l'échange de clé RSA (quand les
        certificats sont utilisés), et l'échange de clés Diffie-Hellman (pour
        échanger des clés sans certificat, ou en l'absence de communication
        préalable entre le client et le serveur).</p>
    
        <p>Les signatures numériques constituent une variante dans le choix des
        méthodes d'échange de clé -- utiliser les signatures ou pas, et dans
        l'affirmative, quel genre de signatures utiliser. La signature à l'aide
        d'une clé privée fournit une protection contre une attaque
        "man-in-the-middle" au cours de laquelle
        l'échange d'informations destiné à générer la
        clé partagée peut être intercepté [<a href="#AC96">AC96</a>, p516].</p>
    
    
    <h3><a name="ciphertransfer" id="ciphertransfer">Chiffrement du transfert de données</a></h3>
    
        <p>Comme décrit plus haut, SSL utilise le chiffrement symétrique
        conventionnel pour chiffrer les messages au cours d'une session. Il existe
        neuf choix possibles pour le chiffrement, y compris l'option du transfert
        non chiffré :</p>
    
        <ul>
        <li>Pas de chiffrement</li>
        <li>Chiffrement en continu (Stream Ciphers)
            <ul>
            <li>RC4 avec clés de 40 bits</li>
            <li>RC4 avec clés de 128 bits</li>
            </ul></li>
        <li>Chiffrement par blocs CBC (CBC Block Ciphers)
            <ul><li>RC2 avec clé de 40 bits</li>
            <li>DES avec clé de 40 bits</li>
            <li>DES avec clé de 56 bits</li>
            <li>Triple-DES avec clé de 168 bits</li>
            <li>Idea (clé de 128 bits)</li>
            <li>Fortezza (clé de 96 bits)</li>
            </ul></li>
        </ul>
    
        <p>"CBC" signifie Cipher Block Chaining (Chaînage de blocs chiffrés),
        c'est à dire qu'une portion du bloc de texte chiffré précédent est utilisée
        pour le chiffrement du bloc courant. "DES" signifie Data Encryption
        Standard (Standard de Chiffrement des Données)
        [<a href="#AC96">AC96</a>, ch12], et possède de nombreuses variantes
        (telles que DES40 et 3DES_EDE). Parmi les algorithmes disponibles, "Idea"
        est actuellement un des meilleurs et des plus puissants sur le plan
        cryptographique, et "RC2" est un algorithme propriétaire de RSA DSI
        [<a href="#AC96">AC96</a>, ch13].</p>
    
    
    <h3><a name="digestfunction" id="digestfunction">Fonction de création d'empreinte</a></h3>
    
        <p>Le choix d'une fonction de création d'empreinte détermine la manière
        dont une empreinte est créée à partir d'une unité de données. SSL supporte
        les fonctions suivantes :</p>
    
        <ul>
        <li>Pas d'empreinte (choix Null)</li>
        <li>MD5, une empreinte de 128 bits</li>
        <li>Algorithme d'Empreinte Sécurisée (Secure Hash Algorithm - SHA-1), une
        empreinte de 160 bits</li>
        </ul>
    
        <p>On utilise l'empreinte de message pour créer un Code d'Authentification
        de Message (Message Authentication Code - MAC) qui est chiffré avec le
        message afin de vérifier son intégrité et de se protéger contre les
        attaques de type "rejeu".</p>
    
    
    <h3><a name="handshake" id="handshake">Protocole de la séquence d'échanges d'informations</a></h3>
    
        <p>La séquence d'échanges d'informations utilise trois protocoles :</p>
    
        <ul>
        <li>Le <dfn>Protocole d'échanges d'informations SSL</dfn> pour établir
        la session SSl entre le client et le serveur.</li>
        <li>Le <dfn>Protocole de spécification du chiffrement SSL</dfn> pour
        l'agrément effectif de la suite de chiffrement à utiliser
        pour la session.</li>
        <li>Le <dfn>Protocole d'alertes SSL</dfn> pour la transmission de
        messages d'erreur SSL entre le client et le serveur.</li>
        </ul>
    
        <p>Ces protocoles, ainsi que les données du protocole de l'application,
        sont encapsulés dans le <dfn>Protocole d'enregistrement SSL
        (SSL Record Protocol)</dfn>, comme
        le montre la <a href="#figure2">Figure 2</a>. Un protocole encapsulé est
        tranféré en tant que données par le protocole de la couche de niveau
        inférieur, qui ne se préoccupe pas du contenu des données. Le protocole
        encapsulé n'a aucune connaissance du protocole sous-jacent.</p>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig2.gif" alt="" width="428" height="217" /><br />
        <a id="figure2" name="figure2"><dfn>Figure 2</dfn></a>:
        Pile du protocole SSL</p>
    
        <p>L'encapsulation des protocoles de contrôle SSL dans le protocole
        d'enregistrement signifie que si une session active est renégociée, les
        protocoles de contrôle seront transmis de manière sécurisée. S'il n'y
        avait pas de session préalable, la suite de chiffrement Null est utilisée,
        ce qui signifie que les messages ne seront pas chiffrés et ne possèderont
        pas d'empreinte d'intégrité, jusqu'à ce que la session ait été établie.</p>
    
    
    <h3><a name="datatransfer" id="datatransfer">Transmission des données</a></h3>
    
        <p>Le protocole d'enregistrement SSL, comme le montre la
        <a href="#figure3">Figure 3</a>, est utilisé pour transmettre les données
        de l'application et les données de contrôle SSL entre le client et le
        serveur, les données étant nécessairement fragmentées en éléments plus
        petits, ou plusieurs messages de données avec protocole de niveau
        supérieur pouvant être combinés en un seul élément. Ce protocole peut
        joindre des signatures d'empreintes, compresser et chiffrer ces éléments
        avant de les transmettre en utilisant le protocole fiable de transport
        sous-jacent (Note : actuellement, aucune implémentation majeure de SSL
        n'inclut le support de la compression).</p>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig3.gif" alt="" width="423" height="323" /><br />
        <a id="figure3" name="figure3"><dfn>Figure 3</dfn></a>:
        Protocole d'enregistrement SSL</p>
    
    
    <h3><a name="securehttp" id="securehttp">Sécurisation des communications HTTP</a></h3>
    
        <p>Une des utilisations courantes de SSL est la sécurisation des
        communication HTTP sur le Web entre un navigateur et un serveur web. Ceci
        n'exclut pas l'utilisation de HTTP non sécurisé - la version sécurisée
        (appelée HTTPS) est identique à du vrai HTTP sur SSL,
        mais utilise le préfixe
        d'URL <code>https</code> au lieu de <code>http</code>, et un port
        de serveur différent (par défaut le port 443).
        Ceci constitue pour une large part
        ce qu'apporte <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> au serveur web Apache.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="references" id="references">Références</a></h2>
    
    <dl>
    <dt><a id="AC96" name="AC96">[AC96]</a></dt>
    <dd>Bruce Schneier, <q>Applied Cryptography</q>, 2nd Edition, Wiley,
    1996. Voir <a href="http://www.counterpane.com/">http://www.counterpane.com/</a> pour diverses autres productions de Bruce
    Schneier.</dd>
    
    <dt><a id="ASN1" name="ASN1">[ASN1]</a></dt>
    <dd>ITU-T Recommendation X.208, <q>Specification of Abstract Syntax Notation
    One (ASN.1)</q>, dernière mise à jour en 2008. Voir <a href="http://www.itu.int/ITU-T/asn1/">http://www.itu.int/ITU-T/asn1/</a>.
    </dd>
    
    <dt><a id="X509" name="X509">[X509]</a></dt>
    <dd>ITU-T Recommendation X.509, <q>The Directory - Authentication
    Framework</q>. A titre de référence, voir <a href="http://en.wikipedia.org/wiki/X.509">http://en.wikipedia.org/wiki/X.509</a>.
    </dd>
    
    <dt><a id="PKCS" name="PKCS">[PKCS]</a></dt>
    <dd><q>Public Key Cryptography Standards (PKCS)</q>,
    RSA Laboratories Technical Notes, Voir <a href="http://www.rsasecurity.com/rsalabs/pkcs/">http://www.rsasecurity.com/rsalabs/pkcs/</a>.</dd>
    
    <dt><a id="MIME" name="MIME">[MIME]</a></dt>
    <dd>N. Freed, N. Borenstein, <q>Multipurpose Internet Mail Extensions
    (MIME) Part One: Format of Internet Message Bodies</q>, RFC2045.
    Voir par exemple <a href="http://tools.ietf.org/html/rfc2045">http://tools.ietf.org/html/rfc2045</a>.</dd>
    
    <dt><a id="SSL3" name="SSL3">[SSL3]</a></dt>
    <dd>Alan O. Freier, Philip Karlton, Paul C. Kocher, <q>The SSL Protocol
    Version 3.0</q>, 1996. Voir <a href="http://www.netscape.com/eng/ssl3/draft302.txt">http://www.netscape.com/eng/ssl3/draft302.txt</a>.</dd>
    
    <dt><a id="TLS1" name="TLS1">[TLS1]</a></dt>
    <dd>Tim Dierks, Christopher Allen, <q>The TLS Protocol Version 1.0</q>,
    1999. Voir <a href="http://ietf.org/rfc/rfc2246.txt">http://ietf.org/rfc/rfc2246.txt</a>.</dd>
    
    <dt><a id="TLS11" name="TLS11">[TLS11]</a></dt>
    <dd><q>Le protocole TLS Version 1.1</q>,
    2006. Voir <a href="http://tools.ietf.org/html/rfc4346">http://tools.ietf.org/html/rfc4346</a>.</dd>
    
    <dt><a id="TLS12" name="TLS12">[TLS12]</a></dt>
    <dd><q>Le protocole TLS Version 1.2</q>,
    2008. Voir <a href="http://tools.ietf.org/html/rfc5246">http://tools.ietf.org/html/rfc5246</a>.</dd>
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_intro.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_intro.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/ssl_intro.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_intro.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_intro.html.ja.utf8�������������������������������������������������0000664�0001751�0001751�00000121307�14743132254�022021� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>SSL/TLS 暗号化: はじめに - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>SSL/TLS 暗号化: はじめに</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/ssl/ssl_intro.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_intro.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/ssl_intro.html" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <blockquote>
    <p>標準規格の良い所は、たくさんの規格から選べるということだ。
    そして、もし本当にどの規格も気に入らなければ、
    一年待つだけで探していた規格が現れる。</p>
    
    <p class="cite">-- <cite>A. Tanenbaum</cite>, "Introduction to
    Computer Networks"</p>
    </blockquote>
    
    <p>
    入門ということで、この章は Web、HTTP、Apache に通じている
    読者向けですが、セキュリティ専門家向けではありません。
    SSL プロトコルの決定的な手引きであるつもりはありません。
    また、組織内の認証管理のための特定のテクニックや、
    特許や輸出規制などの重要な法的な問題についても扱いません。
    むしろ、更なる研究への出発点として色々な概念、定義、例を並べることで
    <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> のユーザに基礎知識を提供する事を目的としています。</p>
    
    <p>ここに示された内容は主に、原著者の許可の下
    The Open Group Research Institute の <a href="http://home.earthlink.net/~fjhirsch/">Frederick J. Hirsch</a>
     氏の記事 <a href="http://home.earthlink.net/~fjhirsch/Papers/wwwj/">
    Introducing SSL and Certificates using SSLeay</a> を基にしています。
    氏の記事は <a href="http://www.ora.com/catalog/wjsum97/">Web Security: A Matter of
    Trust</a>, World Wide Web Journal, Volume 2, Issue 3, Summer 1997
    に掲載されました。
    肯定的な意見は <a href="mailto:hirsch@fjhirsch.com">Frederick Hirsch</a> 氏
     (元記事の著者) へ全ての苦情は <a href="mailto:rse@engelschall.com">Ralf S. Engelschall</a> (
    <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> の作者) へお願いします。
    <span class="transnote">(<em>訳注:</em> 訳については <a href="mailto:apache-docs@ml.apache.or.jp">
    Apache ドキュメント翻訳プロジェクト</a>
    へお願いします。)</span></p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#cryptographictech">暗号化技術</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#certificates">証明書</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssl">Secure Sockets Layer (SSL)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#references">参考文献</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cryptographictech" id="cryptographictech">暗号化技術</a></h2>
    
    <p>SSL を理解するには、暗号アルゴリズム、
    メッセージダイジェスト関数(別名: 一方向関数、ハッシュ関数)、
    電子署名などへの理解が必要です。
    これらの技術は本が丸ごと必要な題目で
    (例えば [<a href="#AC96">AC96</a>] を参照)、
    プライバシー、信用、認証などの技術の基礎となっています。</p>
    
    <h3><a name="cryptographicalgo" id="cryptographicalgo">暗号アルゴリズム</a></h3>
    
        <p>例えば、アリスが送金のために銀行にメッセージを送りたいとします。
        口座番号や送金の金額が含まれるため、
        アリスはそのメッセージを秘密にしたいと思います。
        解決方法の一つは暗号アルゴリズムを使って、メッセージを
        復号されるまで読むことができない暗号化された
        形態に変えてしまうことです。
        その形態になると、
        メッセージは秘密の鍵によってのみ復号化することができます。
        鍵なしでは、メッセージは役に立ちません。
        良い暗号アルゴリズムは、侵入者が元のテキストを解読することを
        非常に難しくするため、努力が割に合わなくさせます。</p>
    
        <p>暗号アルゴリズムには
        従来型と公開鍵の二つの種類があります。</p>
    
        <dl>
        <dt>従来型暗号</dt>
        <dd>対称暗号としても知られ、
        送信者と受信者が鍵を共有することが必要です。
        鍵とは、メッセージを暗号化したり復号するのに使われる秘密
        の情報のことです。
        この鍵が秘密になっている限り、送信者と受信者以外は誰もメッセージを読
        むことができません。
        もしも、アリスと銀行が秘密の鍵を知っているなら、
        彼らはお互いに秘密のメッセージを送ることができるでしょう。
        ただし交信の前に、事前に内密に鍵を共有するという作業自体は難題かもしれません。</dd>
    
        <dt>公開鍵暗号</dt>
        <dd>非対称暗号としても知られ、
        メッセージを暗号化することのできる二つの鍵
        を使用するアルゴリズムを定義することで鍵のやり取りの問題を解決
        します。
        もし、ある鍵が暗号化に使われたなら、
        もう片方の鍵で復号しなければいけません。
        この方式によって、一つの鍵を公表して(公開鍵)、
        もう片方を秘密にしておく(秘密鍵)だけで、
        安全なメッセージを受け取ることができます。</dd>
        </dl>
    
        <p>公開鍵を使って誰もがメッセージを暗号化できますが、秘
        密鍵の持ち主だけがそれを読むことができます。
        この方法で、銀行の公開鍵を使って暗号化することで、
        アリスは秘密のメッセージを送ることができます。
        銀行のみが送られたメッセージを復号することができます。</p>
    
    
    <h3><a name="messagedigests" id="messagedigests">メッセージダイジェスト</a></h3>
    
        <p>アリスはメッセージを秘密にすることができますが、
        誰かが例えば自分に送金するようにメッセージを変更したり、
        別のものに置き換えてしまうかもしれないという問題があります。
        アリスのメッセージだという信憑性を保証する方法の一つは、
        メッセージの簡潔なダイジェストを作って、それも銀行に送るというものです。
        メッセージを受け取ると銀行側でもダイジェストを作成し、
        アリスが送ったダイジェストと比べます。もし一致したなら、
        受け取ったメッセージは無傷だということになります。</p>
    
        <p>このような要約は<dfn>メッセージダイジェスト</dfn>、
        <em>一方行関数</em>、または<em>ハッシュ関数</em>と呼ばれます。
        メッセージダイジェストは長い可変長のメッセージから
        短い固定長の表現を作るのに使われます。
        ダイジェストアルゴリズムはメッセージから
        一意なダイジェストを生成するように作られています。
        メッセージダイジェストはダイジェストから元のメッセージを
        判定するのがとても難しいようにできていて、
        同じ要約を作成する二つのメッセージを探すのは(理論上)不可能です。
        これによって、要約を変更することなくメッセージを置き換えられる
        可能性を排除しています。</p>
    
        <p>アリスへのもう一つの問題は、このダイジェストを安全に送る方法を探すことです。
        ダイジェストが安全に送られればダイジェストの信憑性が保障されて、
        ダイジェストの信憑性をもってオリジナルメッセージの信憑性を得ることができます。
        ダイジェストを安全に送った場合にのみ、そのメッセージの
        信憑性が得られます。</p>
    
        <p>ダイジェスト安全に送る方法の一つは、電子署名に含める方法です。</p>
    
    
    <h3><a name="digitalsignatures" id="digitalsignatures">電子署名</a></h3>
    <p>アリスが銀行にメッセージを送ったとき、
    侵入者が彼女になりすまして彼女の口座への取引を申請できないように、
    銀行側ではメッセージが本当に彼女からのものか確実に分かるようにしなければなりません。
    アリスによって作成されて、メッセージに含まれた
    <em>電子署名</em>がここで役に立ちます。</p>
    
    <p>電子署名はメッセージのダイジェストやその他の情報(処理番号など)を
    送信者の秘密鍵で暗号化することで作られます。
    誰もが公開鍵を使って署名を<em>復号</em>することができますが、
    送信者のみが秘密鍵を知っています。
    これは送信者のみが署名しえたことを意味します。
    ダイジェストを電子署名に含むことは、
    その署名がそのメッセージのみに有効であることを意味します。
    これは、誰もダイジェストを変えて署名をすることができないため、
    メッセージの信用も保証します。</p>
    
    <p>侵入者が署名を傍受して後日に再利用するのを防ぐため
    電子署名には一意な処理番号が含まれます。
    これは、アリスがそんなメッセージは送っていないと言う詐欺
    から銀行を守ります。
    彼女だけが署名しえたからです。(否認防止)</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="certificates" id="certificates">証明書</a></h2>
    
    <p>アリスは秘密のメッセージを銀行に送り、
    署名をして、メッセージの信用を保証することができるおうになりましたが、
    通信している相手が本当に銀行なのか確かめなくてはいけません。
    つまり彼女が使おうとしている公開鍵が、銀行の秘密鍵と対になっていて、
    侵入者の秘密鍵と対になっているわけではないことを
    確かめなくてはいけないことを意味しています。
    同様に銀行は、メッセージの署名が本当にアリスの持っている
    秘密鍵で署名された署名かを確認する必要があります。</p>
    
    <p>もし両者に身元を証明し、公開鍵を確認し、また信頼された機関が署名
    した証明書があれば、両者とも通信相手について正しい相手だと
    確信することができます。
    そのような信頼された機関は<em>認証局</em>
     (Certificate Authority または CA) と呼ばれ、
    証明書 (certificate) が認証 (authentication) に使われます。</p>
    
    <h3><a name="certificatecontents" id="certificatecontents">証明書の内容</a></h3>
    
        <p>証明書は公開鍵と個人、サーバ、その他の主体の実在の身元を
        関連付けます。
        <a href="#table1">表1</a>に示されるように証明対象の情報は
        身元証明の情報(識別名)と公開鍵が含まれます。
        証明書はまた、認証局の身元証明と署名、そして証明書の有効期間を
        含みます。
        シリアルナンバーなどの認証局の管理上の情報や
        その他の追加の情報が含まれているかもしれません。</p>
    
        <h4><a name="table1" id="table1">表1: 証明書情報</a></h4>
        
        <table>
        
        <tr><th>証明対象</th>
            <td>識別名、公開鍵</td></tr>
        <tr><th>発行者</th>
            <td>識別名、公開鍵</td></tr>
        <tr><th>有効期間</th>
            <td>開始日、失効日</td></tr>
        <tr><th>管理情報</th>
            <td>バージョン、シリアルナンバー</td></tr>
        <tr><th>拡張情報</th>
            <td>基本的な制約、ネットスケープフラッグ、その他</td></tr>
        </table>
        
    
        <p>識別名(ディスティングイッシュ・ネーム)は特定の状況における
        身分証明を提供するのに使われています。例えば、ある人は
        私用と会社とで別々の身分証明を持つかもしれません。
        
        識別名は X.509 標準規格 [<a href="#X509">X509</a>] で定義されています。
        X.509 標準規格は、項目、項目名、そして項目の略称を定義しています。(<a href="#table2">表
        2</a> 参照)</p>
    
        <h4><a name="table2" id="table2">表 2: 識別名情報</a></h4>
        
        <table class="bordered">
        
        <tr><th>識別名項目</th>
            <th>略称</th>
            <th>説明</th>
            <th>例</th></tr>
        <tr><td>Common Name (コモンネーム)</td>
            <td>CN</td>
            <td>認証される名前<br />
            SSL接続するURL</td>
            <td>CN=www.example.com</td></tr>
        <tr><td>Organization or Company (組織名)</td>
            <td>O</td>
            <td>団体の正式英語組織名</td>
            <td>O=Example Japan K.K.</td></tr>
        <tr><td>Organizational Unit (部門名)</td>
            <td>OU</td>
            <td>部署名など</td>
            <td>OU=Customer Service</td></tr>
        <tr><td>City/Locality (市区町村)</td>
            <td>L</td>
            <td>所在してる市区町村</td>
            <td>L=Sapporo</td></tr>
        <tr><td>State/Province (都道府県)</td>
            <td>ST</td>
            <td>所在してる都道府県</td>
            <td>ST=Hokkaido</td></tr>
        <tr><td>Country(国)</td>
            <td>C</td>
            <td>所在している国名の ISO コード<br />
            日本の場合 JP
            </td>
            <td>C=JP</td></tr>
        </table>
        
    
        <p>認証局はどの項目が省略可能でどれが必須かの方針を定義する
        かもしれません。項目の内容についても認証局や証明書のユーザからの
        要件があるかもしれません。
        例えばネットスケープのブラウザは、サーバの証明書の
         Common Name (コモンネーム)がサーバのドメイン名の
         <code>*.snakeoil.com</code> 
        というようなワイルドカードのパターンにマッチすること
        を要求します。</p>
    
        <p>バイナリ形式の証明書は ASN.1 表記法
         [<a href="#X208">X208</a>] [<a href="#PKCS">PKCS</a>] で
        定義されています。
        この表記法は内容をどのように記述するかを定義し、
        符号化の規定がこの情報がどのようにバイナリ形式に変換されるかを
        定義します。
        証明書のバイナリ符号化は Distinguished Encoding
        Rules (DER) で定義され、それはより一般的な Basic Encoding Rules
        (BER) に基づいています。
        バイナリ形式を扱うことのできない送信では、
        バイナリ形式は Base64 符号化 [<a href="#MIME">MIME</a>] で
        ASCII 形式に変換されることがあります。
        開始デリミタ行と終了デリミタ行で囲まれた、この形式のことを
        PEM ("Privacy Enhanced Mail") 符号化された証明書と言います。</p>
    
        <div class="example"><h3>PEM 符号化された証明書の例 (example.crt)</h3><pre>-----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-----</pre></div>
    
    
    <h3><a name="certificateauthorities" id="certificateauthorities">認証局</a></h3>
    
        <p>証明書を承認する前に、証明書要求に記載されている情報を確認し、
        認証局は鍵の所有者の身元を確認します。
        例えば、アリスが個人証明書を申請したとすると、
        認証局はアリスが証明書の申請が主張する通りの
        当の本人だということを確認しなくてはいけません。</p>
    
        <h4><a name="certificatechains" id="certificatechains">証明書の連鎖</a></h4>
        
            <p>認証局は他の認証局への証明書を発行することができます。
            未知の証明書を調べる時に、アリスはその証明書の発行者
            に自信が持てるまで、発行者の証明書を
            その上位階層の認証局をたどって調べる必要があります。
            「悪質な」証明書の危険性を減らすため、
            彼女は限られた連鎖の発行者のみ信頼するように
            決めることもできます。</p>
        
    
        <h4><a name="rootlevelca" id="rootlevelca">最上位認証局の作成</a></h4>
        
            <p>前に述べたように、全ての証明書について、
            最上位の認証局(CA)までそれぞれの発行者が
            対象の身元証明の有効性を明らかにする必要があります。
            問題は、誰がその最上位の認証機関の証明書を保証するのか、
            ということです。
            このような場合に限り、証明書は「自己署名」されます。
            ブラウザには、とてもよく知られている認証局が初期登録されていますが、
            自己署名された証明書を信用する際には
            細心の注意が必要です。
            最上位認証局が公開鍵を広く公表することで、
            その鍵を信頼するリスクを低くすることができます。
            もし、他人がその認証局になりすました時に、それが露見しや
            すいからです。</p>
    
            <p><a href="http://www.thawte.com/">Thawte</a> 
            や <a href="http://www.verisign.com/">VeriSign</a> 
            のような多くの会社が認証局として開設しました。
            このような会社は以下のサービスを提供します:</p>
    
            <ul>
            <li>証明書申請の確認</li>
            <li>証明書申請の処理</li>
            <li>証明書の発行と管理</li>
            </ul>
    
            <p>自分で認証局を作ることも可能です。
            インターネット環境では危険ですが、
            個人やサーバの身元証明が簡単に行える組織の
            イントラネット内では役に立つかもしれません。</p>
        
    
        <h4><a name="certificatemanagement" id="certificatemanagement">証明書管理</a></h4>
        
            <p>認証局の開設は徹底した管理、技術、運用の体制を必要とする
            責任のある仕事です。
            認証局は証明書を発行するだけでなく、
            管理もしなければなりません。
            具体的には、証明書がいつまで有効であり続けるかを決定し、更新し、
            また過去発行されて失効した証明書のリスト
            (Certificate Revocation Lists または CRL)
            を管理しなければいけません。</p>
            
            <p>例えばアリスが過去、会社の社員であることを証明する証明書を持っていたが、
            現在は退職していた際、その証明書は失効されなければなりません。
            証明書は次々と人に渡されていくものなので、
            証明書そのものから、それが取り消されたか判断することは
            不可能です。
            よって、証明書の有効性を調べるときには、
            認証局に連絡して CRL を照合する必要があります。
            普通この過程は自動化されているものではありません。</p>
    
            <div class="note"><h3>注意</h3>
            <p>ブラウザに信用できる認証局としてデフォルトで登録されていない
            認証局を使おうとした場合、
            認証局の証明書をブラウザに読み込んで、
            ブラウザがその認証局によって署名されたサーバの証明書を
            有効にする必要があります。
            一度読み込まれると、その認証局によって署名された全ての
            証明書を受け入れるため、危険を伴います。</p>
            </div>
        
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssl" id="ssl">Secure Sockets Layer (SSL)</a></h2>
    
    <p>Secure Sockets Layer プロトコルは信頼性のあるコネクション型の
    ネットワーク層のプロトコル(例えば、TCP/IP)と
    アプリケーション層のプロトコル(例えば、HTTP)
    の間に置くことができます。
    SSL は、相互認証によってサーバとクライアント間の安全な通信を、
    電子署名によってデータの完全性を、
    そして暗号化によってプライバシを提供します。</p>
    
    <p>SSL プロトコルは暗号化、ダイジェスト、電子署名について、
    様々なアルゴリズムをサポートするようにできています。
    こうすることで、法や輸出の規制を考慮に入れて、サーバに合わせた
    アルゴリズムを選ぶことができ、また、新しいアルゴリズムを
    利用していくことも可能にしています。
    アルゴリズムの選択はプロトコルセッション開始時に
    サーバとクライアント間で取り決められます。</p>
    
    <h3><a name="table4" id="table4">表4: SSL プロトコルのバージョン</a></h3>
    
        <table class="bordered">
        
        <tr><th>バージョン</th>
            <th>出典</th>
            <th>説明</th>
            <th>ブラウザのサポート</th></tr>
        <tr><td>SSL v2.0</td>
            <td>Vendor Standard (Netscape Corp. より) [<a href="#SSL2">SSL2</a>]</td>
            <td>実装が現存する初めての SSL プロトコル</td>
            <td>- NS Navigator 1.x/2.x<br />
            - MS IE 3.x<br />
            - Lynx/2.8+OpenSSL</td></tr>
        <tr><td>SSL v3.0</td>
            <td>Expired Internet Draft (Netscape Corp. より) [<a href="#SSL3">SSL3</a>]</td>
            <td>特定のセキュリティ攻撃を防ぐための改訂、
            非RSA 暗号の追加、証明書階層構造のサポート</td>
            <td>- NS Navigator 2.x/3.x/4.x<br />
            - MS IE 3.x/4.x<br />
            - Lynx/2.8+OpenSSL</td></tr>
        <tr><td>TLS v1.0</td>
            <td>Proposed Internet Standard (IETF より) [<a href="#TLS1">TLS1</a>]</td>
            <td>MAC レイヤを HMAC へ更新、ブロック暗号の block
            padding、メッセージ順序の標準化、警告文の充実などのため
            SSL 3.0 を改訂。</td>
            <td>- Lynx/2.8+OpenSSL</td></tr>
        </table>
    
    
    <p><a href="#table4">表4</a>に示されるとおり、SSL プロトコルには
    いくつものバージョンがあります。
    表にも書かれているように、SSL 3.0 の利点の一つは
    証明書階層構造をサポートすることです。
    この機能によって、サーバは自分の証明書に加えて、
    発行者の証明書をブラウザに渡すことができます。
    証明書階層構造によって、
    ブラウザに発行者の証明書が直接登録されていなくても、
    階層の中に含まれていれば、
    ブラウザはサーバの証明書を有効化することができます。
    SSL 3.0 は現在 Internet Engineering Task Force (IETF) 
    によって開発されている Transport Layer Security 
    [<a href="#TLS1">TLS</a>] プロトコル標準規格の基礎となっています。</p>
    
    <h3><a name="session" id="session">セッションの確立</a></h3>
    
        <p><a href="#figure1">図1</a>で示されるように、
        セッションの確立はクライアントとサーバ間の
        ハンドシェークシークエンスによって行なわれます。
        サーバが証明書を提供するか、クライアントの証明書をリクエストするか
        というサーバの設定により、このシークエンスは異なるものとなります。
        暗号情報の管理のために、追加のハンドシェーク過程が必要になる
        場合もありますが、この記事では
        よくあるシナリオを手短に説明します。
        全ての可能性についは、SSL 仕様書を参照してください。</p>
    
        <div class="note"><h3>注意</h3>
        <p>一度 SSL セッションが確立すると、セッションを再利用することで、
        セッションを開始するための多くの過程を繰り返すという
        パフォーマンスの損失を防ぎます。
        そのため、サーバは全てのセッションに一意なセッション識別名を
        割り当て、サーバにキャッシュし、クライアントは次回から
        (識別名がサーバのキャッシュで期限切れになるまでは)
        ハンドシェークなしで接続することができます。</p>
        </div>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig1.gif" alt="" width="423" height="327" /><br />
        <a id="figure1" name="figure1"><dfn>図1</dfn></a>: SSL
        ハンドシェークシークエンス概略</p>
    
        <p>サーバとクライアントで使われる
        ハンドシェークシークエンスの要素を以下に示します:</p>
    
        <ol>
        <li>データ通信に使われる暗号スイートの取り決め</li>
        <li>クライアントとサーバ間でのセッション鍵の確立と共有</li>
        <li>オプションとして、クライアントに対するサーバの認証</li>
        <li>オプションとして、サーバに対するクライアントの認証</li>
        </ol>
    
        <p>第一ステップの暗号スイート取り決めによって、
        サーバとクライアントはそれぞれにあった
        暗号スイートを選ぶことができます。
        SSL3.0 プロトコルの仕様書は 31 の暗号スイートを定義しています。
        暗号スイートは以下のコンポーネントにより定義されています:</p>
    
        <ul>
        <li>鍵の交換手段</li>
        <li>データ通信の暗号術</li>
        <li>Message Authentication Code (MAC) 作成のための
        メッセージダイジェスト</li>
        </ul>
    
        <p>これらの三つの要素は以下のセクションで説明されています。</p>
    
    
    <h3><a name="keyexchange" id="keyexchange">鍵の交換手段</a></h3>
    
        <p>鍵の交換手段はアプリケーションのデータ通信に使われ、
        共有される対称暗号鍵をどのようにがクライアントとサーバで
        取り決めるかを定義します。
        SSL 2.0 は RSA 鍵交換しか使いませんが、
        SSL 3.0 は (証明書が使われるときの) RSA 鍵交換や、
        (証明書無しの場合やクライアントとサーバの事前の通信が無い場合の)
        Diffie-Hellman 鍵交換
        など様々な鍵交換アルゴリズムをサポートします。</p>
    
        <p>鍵の交換方法における一つの選択肢は電子署名です。
        電子署名を使うかどうか、また、
        どの種類の署名を使うかという選択があります。
        秘密鍵で署名することで共有鍵を保護し、情報交換する時の
        マン・イン・ザ・ミドル攻撃を防ぐことができます。
        [<a href="#AC96">AC96</a>, p516]</p>
    
    
    <h3><a name="ciphertransfer" id="ciphertransfer">データ通信の暗号術</a></h3>
    
        <p>SSL はセッションのメッセージの暗号化に前述した
        対称暗号方式を用います。
        暗号化しないという選択肢も含め九つの暗号方式の選択肢があります:</p>
    
        <ul>
        <li>暗号化なし</li>
        <li>ストリーム暗号
            <ul>
            <li>40-bit 鍵での RC4</li>
            <li>128-bit 鍵での RC4</li>
            </ul></li>
        <li>CBC ブロック暗号
            <ul><li>40 bit 鍵での RC2</li>
            <li>40 bit 鍵での DES</li>
            <li>56 bit 鍵での DES</li>
            <li>168 bit 鍵での Triple-DES</li>
            <li>Idea (128 bit 鍵)</li>
            <li>Fortezza (96 bit 鍵)</li>
            </ul></li>
        </ul>
    
        <p>CBC とは暗号ブロック連鎖 (Cipher Block Chaining)
         の略で、一つ前の暗号化された暗号文の一部が
        ブロックの暗号化に使われることを意味します。
        DES はデータ暗号化標準規格 (Data Encryption Standard)
         [<a href="#AC96">AC96</a>, ch12] の略で、
        DES40 や 3DES_EDE を含むいくつもの種類があります。
        Idea は現在最高なものの一つで、暗号術的には現在ある中で
        最も強力なものです。
        RC2 は RSA DSI による独占的なアルゴリズムです。
         [<a href="#AC96">AC96</a>,
        ch13]</p>
    
    
    <h3><a name="digestfuntion" id="digestfuntion">ダイジェスト関数</a></h3>
    
        <p>
        ダイジェスト関数の選択はレコードユニットからどのようにダイジェストが生成されるかを決定します。
        SSL は以下をサポートします:</p>
    
        <ul>
        <li>ダイジェストなし</li>
        <li>MD5 (128-bit ハッシュ)</li>
        <li>Secure Hash Algorithm (SHA-1) (160-bit ハッシュ)</li>
        </ul>
    
        <p>メッセージダイジェストは Message Authentication Code (MAC) 
        の生成に使われ、メッセージと共に暗号化され、メッセージの信憑性を
        確認し、リプレイ攻撃を防ぎます。</p>
    
    
    <h3><a name="handshake" id="handshake">ハンドシェークシークエンスプロトコル</a></h3>
    
        <p>ハンドシェークシークエンスは三つのプロトコルを使います:</p>
    
        <ul>
        <li><dfn>SSL ハンドシェークプロトコル</dfn>は
        クライアントとサーバ間での SSL セッションの確立に使われます。</li>
        <li><dfn>SSL 暗号仕様変更プロトコル</dfn>は
        セッションでの暗号スイートの取り決めに使われます。</li>
        <li><dfn>SSL 警告プロトコル</dfn>は
        クライアントサーバ間で SSL エラーを伝達するのに使われます。</li>
        </ul>
    
        <p>三つのプロトコルは、アプリケーションプロトコルデータとともに、
        <a href="#figure2">図2</a>に示すとおり <dfn>SSL レコードプロトコル</dfn>
        でカプセル化されます。
        カプセル化されたプロトコルはデータを検査しない
        下層のプロトコルによってデータとして伝達されます。
        カプセル化されたプロトコルは下層のプロトコルに関して一切関知しません。</p>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig2.gif" alt="" width="428" height="217" /><br />
        <a id="figure2" name="figure2"><dfn>図2</dfn></a>: SSL プロトコルスタック
        </p>
    
        <p>
        レコードプロトコルで SSL コントロールプロトコルがカプセル化されているということは、
        アクティブなセッション上で再ネゴシエーションされたときにも、
        コントロールプロトコルは安全であることを意味します。
        既存のセッションが無い場合は、Null 暗号スイートが使われ、
        暗号化は行なわれず、セッションが確立するまでは
        ダイジェストも無い状態となります。</p>
    
    
    <h3><a name="datatransfer" id="datatransfer">データ通信</a></h3>
    
        <p><a href="#figure3">図3</a>に示される SSL レコードプロトコル
        はクライアントとサーバ間のアプリケーションや
        SSL コントロールデータの通信に使われます。
        必要に応じてこのデータはより小さいユニットに分けられたり、
        いくつかの高級プロトコルをまとめて一ユニットとして通信が
        行なわれることもあります。
        データを圧縮し、ダイジェスト署名を添付して、
        これらのユニットを暗号化したのち、ベースとなっている
        信頼性のあるトランスポートプロトコルを用いるかもしれません。
        (注意: 現在メジャーな SLL 実装で圧縮をサポートしているものはありません)</p>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig3.gif" alt="" width="423" height="323" /><br />
        <a id="figure3" name="figure3"><dfn>図 3</dfn></a>: SSL レコードプロトコル
        </p>
    
    
    <h3><a name="securehttp" id="securehttp">HTTP 通信の安全化</a></h3>
    
        <p>よくある SSL の使い方はブラウザとウェブサーバ間の HTTP 通信
        の安全化です。
        これは、従来の安全ではない HTTP の使用を除外するものではありません。
        安全化されたもの (HTTPS と呼ばれます) は、SSL 上での普通の HTTP で、
        URL スキームに <code>http</code> の代わりに <code>https</code>
        を用い、サーバで別のポートを使うことです (デフォルトでは443)。
        これが主に <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> が Apache 
        ウェブサーバに提供する機能です。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="references" id="references">参考文献</a></h2>
    
    <dl>
    <dt><a id="AC96" name="AC96">[AC96]</a></dt>
    <dd>Bruce Schneier, <q>Applied Cryptography</q>, 2nd Edition, Wiley,
    1996. See <a href="http://www.counterpane.com/">http://www.counterpane.com/</a> for various other materials by Bruce
    Schneier.</dd>
    
    <dt><a id="X208" name="X208">[X208]</a></dt>
    <dd>ITU-T Recommendation X.208, <q>Specification of Abstract Syntax Notation
    One (ASN.1)</q>, 1988. See for instance <a href="http://www.itu.int/rec/recommendation.asp?type=items&amp;lang=e&amp;parent=T-REC-X.208-198811-I">http://www.itu.int/rec/recommendation.asp?type=items&amp;lang=e&amp;parent=T-REC-X.208-198811-I</a>.
    </dd>
    
    <dt><a id="X509" name="X509">[X509]</a></dt>
    <dd>ITU-T Recommendation X.509, <q>The Directory - Authentication
    Framework</q>. See for instance <a href="http://www.itu.int/rec/recommendation.asp?type=folders&amp;lang=e&amp;parent=T-REC-X.509">http://www.itu.int/rec/recommendation.asp?type=folders&amp;lang=e&amp;parent=T-REC-X.509</a>.
    </dd>
    
    <dt><a id="PKCS" name="PKCS">[PKCS]</a></dt>
    <dd><q>Public Key Cryptography Standards (PKCS)</q>, 
    RSA Laboratories Technical Notes, See <a href="http://www.rsasecurity.com/rsalabs/pkcs/">http://www.rsasecurity.com/rsalabs/pkcs/</a>.</dd>
    
    <dt><a id="MIME" name="MIME">[MIME]</a></dt>
    <dd>N. Freed, N. Borenstein, <q>Multipurpose Internet Mail Extensions
    (MIME) Part One: Format of Internet Message Bodies</q>, RFC2045.
    See for instance <a href="http://ietf.org/rfc/rfc2045.txt">http://ietf.org/rfc/rfc2045.txt</a>.</dd>
    
    <dt><a id="SSL2" name="SSL2">[SSL2]</a></dt>
    <dd>Kipp E.B. Hickman, <q>The SSL Protocol</q>, 1995. See <a href="http://www.netscape.com/eng/security/SSL_2.html">http://www.netscape.com/eng/security/SSL_2.html</a>.</dd>
    
    <dt><a id="SSL3" name="SSL3">[SSL3]</a></dt>
    <dd>Alan O. Freier, Philip Karlton, Paul C. Kocher, <q>The SSL Protocol
    Version 3.0</q>, 1996. See <a href="http://www.netscape.com/eng/ssl3/draft302.txt">http://www.netscape.com/eng/ssl3/draft302.txt</a>.</dd>
    
    <dt><a id="TLS1" name="TLS1">[TLS1]</a></dt>
    <dd>Tim Dierks, Christopher Allen, <q>The TLS Protocol Version 1.0</q>,
    1999. See <a href="http://ietf.org/rfc/rfc2246.txt">http://ietf.org/rfc/rfc2246.txt</a>.</dd>
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/ssl/ssl_intro.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_intro.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/ssl_intro.html" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_intro.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_howto.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000062030�14740503670�022041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Chiffrement fort SSL/TLS : Mode d'emploi - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>Chiffrement fort SSL/TLS : Mode d'emploi</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_howto.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_howto.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document doit vous permettre de démarrer et de faire fonctionner
    une configuration de base. Avant de vous lancer dans l'application de
    techniques avancées, il est fortement recommandé de lire le reste
    de la documentation SSL afin d'en comprendre le fonctionnement de
    manière plus approfondie.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configexample">Exemple de configuration basique</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ciphersuites">Suites de chiffrement et mise en application de la sécurité
    de haut niveau</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ocspstapling">Agrafage OCSP</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#accesscontrol">Authentification du client et contrôle d'accès</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#logging">Journalisation</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configexample" id="configexample">Exemple de configuration basique</a></h2>
    
    
    <p>Votre configuration SSL doit comporter au moins les directives
    suivantes :</p>
    
    <pre class="prettyprint lang-config">LoadModule ssl_module modules/mod_ssl.so
    
    Listen 443
    &lt;VirtualHost *:443&gt;
        ServerName www.example.com
        SSLEngine on
        SSLCertificateFile "/path/to/www.example.com.cert"
        SSLCertificateKeyFile "/path/to/www.example.com.key"
    &lt;/VirtualHost&gt;</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ciphersuites" id="ciphersuites">Suites de chiffrement et mise en application de la sécurité
    de haut niveau</a></h2>
    
    <ul>
    <li><a href="#onlystrong">Comment créer un serveur SSL
    qui n'accepte que le chiffrement fort ?</a></li>
    <li><a href="#strongurl">Comment créer un serveur qui accepte tous les types de
    chiffrement en général, mais exige un chiffrement fort pour pouvoir
    accéder à une URL particulière ?</a></li>
    </ul>
    
    
    <h3><a name="onlystrong" id="onlystrong">Comment créer un serveur SSL qui n'accepte
    que le chiffrement fort ?</a></h3>
    
        <p>Les directives suivantes ne permettent que les
        chiffrements de plus haut niveau :</p>
        <pre class="prettyprint lang-config">SSLCipherSuite HIGH:!aNULL:!MD5</pre>
    
    
     <p>Avec la configuration qui suit, vous indiquez une préférence pour
     des algorityhmes de chiffrement spécifiques optimisés en matière de
     rapidité (le choix final sera opéré par mod_ssl, dans la mesure ou le
     client les supporte) :</p>
    
        <pre class="prettyprint lang-config">SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5
    SSLHonorCipherOrder on</pre>
    
    
    
    <h3><a name="strongurl" id="strongurl">Comment créer un serveur qui accepte tous les types de
    chiffrement en général, mais exige un chiffrement fort pour pouvoir
    accéder à une URL particulière ?</a></h3>
    
        <p>Dans ce cas bien évidemment, une directive <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code> au niveau du serveur principal
        qui restreint le choix des suites de chiffrement aux versions les plus
        fortes ne conviendra pas. <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> peut cependant être
        reconfiguré au sein de blocs <code>Location</code> qui permettent
        d'adapter la configuration générale à un répertoire spécifique ;
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> peut alors forcer automatiquement une
        renégociation des paramètres SSL pour parvenir au but recherché.
        Cette configuration peut se présenter comme suit :</p>
        <pre class="prettyprint lang-config"># soyons très tolérant a priori
    SSLCipherSuite ALL:!aNULL:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP:+eNULL
    
    &lt;Location "/strong/area"&gt;
    # sauf pour https://hostname/strong/area/ et ses sous-répertoires
    # qui exigent des chiffrements forts
    SSLCipherSuite HIGH:!aNULL:!MD5
    &lt;/Location&gt;</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ocspstapling" id="ocspstapling">Agrafage OCSP</a></h2>
    
    
    <p>Le protocole de contrôle du statut des certificats en ligne (Online
    Certificate Status Protocol - OCSP) est un mécanisme permettant de
    déterminer si un certificat a été révoqué ou non, et l'agrafage OCSP en
    est une fonctionnalité particulière par laquelle le serveur, par exemple
    httpd et mod_ssl, maintient une liste des réponses OCSP actuelles pour
    ses certificats et l'envoie aux clients qui communiquent avec lui. La
    plupart des certificats contiennent l'adresse d'un répondeur OCSP maintenu
    par l'Autorité de Certification (CA) spécifiée, et mod_ssl peut requérir
    ce répondeur pour obtenir une réponse signée qui peut être envoyée aux
    clients qui communiquent avec le serveur.</p>
    
    <p>L'agrafage OCSP est la méthode la plus performante pour obtenir le
    statut d'un certificat car il est disponible au niveau du serveur, et le
    client n'a donc pas besoin d'ouvrir une nouvelle connexion vers
    l'autorité de certification. Autres avantages de l'absence de
    communication entre le client et l'autorité de certification :
    l'autorité de certification n'a pas accès à l'historique de navigation
    du client, et l'obtention du statut du certificat est plus efficace car
    elle n'est plus assujettie à une surcharge éventuelle des serveurs de
    l'autorité de certification.</p>
    
    <p>La charge du serveur est moindre car la réponse qu'il a obtenu du
    répondeur OCSP peut être réutilisée par tous les clients qui utilisent
    le même certificat dans la limite du temps de validité de la réponse.</p>
    
    <p>Une fois le support général SSL correctement configuré, l'activation
    de l'agrafage OCSP ne requiert que des modifications mineures
    à la configuration de httpd et il suffit en général de l'ajout de ces
    deux directives :</p>
    
        <pre class="prettyprint lang-config">SSLUseStapling On
    SSLStaplingCache "shmcb:ssl_stapling(32768)"</pre>
    
    
    <p>Ces directives sont placées de façon à ce qu'elles aient une portée
    globale (et particulièrement en dehors de toute section VirtualHost), le
    plus souvent où sont placées les autres directives de configuration
    globales SSL, comme <code>conf/extra/httpd-ssl.conf</code> pour les
    installations de httpd à partir des sources, ou
    <code>/etc/apache2/mods-enabled/ssl.conf</code> pour Ubuntu ou Debian,
    etc...</p>
    
    <p>Le chemin spécifié par la directive
    <code class="directive">SSLStaplingCache</code> (par exemple <code>logs/</code>)
    doit être le même que celui spécifié par la directive
    <code class="directive">SSLSessionCache</code>. Ce chemin est relatif au chemin
    spécifié par la directive <code class="directive">ServerRoot</code>.</p>
    
    <p>Cette directive <code class="directive">SSLStaplingCache</code> particulière
    nécessite le chargement du module <code class="module"><a href="../mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code> (à
    cause du préfixe <code>shmcb</code> de son argument). Ce module est en
    général déjà activé pour la directive
    <code class="directive">SSLSessionCache</code>, ou pour des modules autres que
    <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>. Si vous activez un cache de session SSL
    utilisant un mécanisme autre que <code class="module"><a href="../mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code>,
    utilisez aussi ce mécanisme alternatif pour la directive
    <code class="directive">SSLStaplingCache</code>. Par exemple :</p>
    
        <pre class="prettyprint lang-config">SSLSessionCache "dbm:ssl_scache"
    SSLStaplingCache "dbm:ssl_stapling"</pre>
    
    
    <p>Vous pouvez utiliser la commande openssl pour vérifier que votre
    serveur envoie bien une réponse OCSP :</p>
    
    <pre>$ openssl s_client -connect www.example.com:443 -status -servername www.example.com
    ...
    OCSP response: 
    ======================================
    OCSP Response Data:
        OCSP Response Status: successful (0x0)
        Response Type: Basic OCSP Response
    ...
        Cert Status: Good
    ...</pre>
    
    <p>Les sections suivantes explicitent les situations courantes qui
    requièrent des modifications supplémentaires de la configuration. Vous
    pouvez aussi vous référer au manuel de référence de
    <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.</p>
    
    <h3>Si l'on utilise plus que quelques certificats SSL pour le serveur</h3>
    
    <p>Les réponses OCSP sont stockées dans le cache d'agrafage SSL. Alors
    que les réponses ont une taille de quelques centaines à quelques
    milliers d'octets, mod_ssl supporte des réponses d'une taille jusqu'à
    environ 10 ko. Dans notre cas, le nombre de certificats est conséquent
    et la taille du cache (32768 octets dans l'exemple ci-dessus) doit être
    augmentée. En cas d'erreur lors du stockage d'une réponse, le
    message AH01929 sera enregistré dans le journal.</p>
    
    
    <h3>Si le certificat ne spécifie pas de répondeur OCSP, ou si une
    adresse différente doit être utilisée</h3>
    
    <p>Veuillez vous référer à la documentation de la directive <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingforceurl">SSLStaplingForceURL</a></code>.</p>
    
    <p>Vous pouvez vérifier si un certificat spécifie un répondeur OCSP en
    utilisant la commande openssl comme suit :</p>
    
    <pre>$ openssl x509 -in ./www.example.com.crt -text | grep 'OCSP.*http'
    OCSP - URI:http://ocsp.example.com</pre>
    
    <p>Si un URI OCSP est fourni et si le serveur web peut communiquer
    directement avec lui sans passer par un mandataire, aucune modification
    supplémentaire de la configuration n'est requise. Notez que les règles
    du pare-feu qui contrôlent les connexions sortantes en provenance du
    serveur web devront peut-être subir quelques ajustements.</p>
    
    <p>Si aucun URI OCSP n'est fourni, contactez votre autorité de
    certification pour savoir s'il en existe une ; si c'est le
    cas, utilisez la directive <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingforceurl">SSLStaplingForceURL</a></code> pour la spécifier dans
    la configuration du serveur virtuel qui utilise le certificat.</p>
    
    
    <h3>Si plusieurs serveurs virtuels sont configurés pour utiliser SSL
    et si l'agrafage OCSP doit être désactivé pour certains d'entre eux</h3>
    
    
    <p>Ajoutez la directive <code>SSLUseStapling Off</code> à la
    configuration des serveurs virtuels pour lesquels l'agrafage OCSP doit
    être désactivé.</p>
    
    
    <h3>Si le répondeur OCSP est lent ou instable</h3>
    
    <p>De nombreuses directives permettent de gérer les temps de réponse et
    les erreurs. Référez-vous à la documentation de <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingfaketrylater">SSLStaplingFakeTryLater</a></code>, <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingrespondertimeout">SSLStaplingResponderTimeout</a></code>, et <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingreturnrespondererrors">SSLStaplingReturnResponderErrors</a></code>.</p>
    
    
    <h3>Si mod_ssl enregistre l'erreur AH02217 dans le journal</h3>
    
    <pre>AH02217: ssl_stapling_init_cert: Can't retrieve issuer certificate!</pre>
    <p>Afin de pouvoir supporter l'agrafage OCSP lorsqu'un certificat de
    serveur particulier est utilisé, une chaîne de certification pour ce
    certificat doit être spécifiée. Si cela n'a pas été fait lors de
    l'activation de SSL, l'erreur AH02217 sera enregistrée lorsque
    l'agrafage OCSP sera activé, et les clients qui utilisent le certificat
    considéré ne recevront pas de réponse OCSP.</p>
    
    <p>Veuillez vous référer à la documentation des directives <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatechainfile">SSLCertificateChainFile</a></code> et <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatefile">SSLCertificateFile</a></code> pour spécifier une
    chaîne de certification.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="accesscontrol" id="accesscontrol">Authentification du client et contrôle d'accès</a></h2>
    
    <ul>
    <li><a href="#allclients">Comment forcer les clients
    à s'authentifier à l'aide de certificats ?</a></li>
    <li><a href="#arbitraryclients">Comment forcer les clients
    à s'authentifier à l'aide de certificats pour une URL particulière,
    mais autoriser quand-même tout client anonyme
    à accéder au reste du serveur ?</a></li>
    <li><a href="#certauthenticate">Comment n'autoriser l'accès à une URL
    particulière qu'aux clients qui possèdent des certificats, mais autoriser
    l'accès au reste du serveur à tous les clients ?</a></li>
    <li><a href="#intranet">Comment imposer HTTPS avec chiffrements forts,
    et soit authentification de base, soit possession de certificats clients,
    pour l'accès à une partie de l'Intranet, pour les clients en
    provenance de l'Internet ?</a></li>
    </ul>
    
    <h3><a name="allclients" id="allclients">Comment forcer les clients
    à s'authentifier à l'aide de certificats ?
    </a></h3>
    
    
        <p>Lorsque vous connaissez tous vos clients (comme c'est en général le cas
        au sein d'un intranet d'entreprise), vous pouvez imposer une
        authentification basée uniquement sur les certificats. Tout ce dont vous
        avez besoin pour y parvenir est de créer des certificats clients signés par
        le certificat de votre propre autorité de certification
        (<code>ca.crt</code>), et d'authentifier les clients à l'aide de ces
        certificats.</p>
        <pre class="prettyprint lang-config"># exige un certificat client signé par le certificat de votre CA
    # contenu dans ca.crt
    SSLVerifyClient require
    SSLVerifyDepth 1
    SSLCACertificateFile "conf/ssl.crt/ca.crt"</pre>
    
    
    
    <h3><a name="arbitraryclients" id="arbitraryclients">Comment forcer les clients
    à s'authentifier à l'aide de certificats pour une URL particulière,
    mais autoriser quand-même tout client anonyme
    à accéder au reste du serveur ?</a></h3>
    
    
    <p>Pour forcer les clients à s'authentifier à l'aide de certificats pour une
    URL particulière, vous pouvez utiliser les fonctionnalités de reconfiguration
    de <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> en fonction du répertoire :</p>
    
        <pre class="prettyprint lang-config">SSLVerifyClient none
    SSLCACertificateFile "conf/ssl.crt/ca.crt"
    
    &lt;Location "/secure/area"&gt;
    SSLVerifyClient require
    SSLVerifyDepth 1
    &lt;/Location&gt;</pre>
    
    
    
    <h3><a name="certauthenticate" id="certauthenticate">Comment n'autoriser l'accès à une URL
    particulière qu'aux clients qui possèdent des certificats, mais autoriser
    l'accès au reste du serveur à tous les clients ?</a></h3>
    
    
        <p>La clé du problème consiste à vérifier si une partie du certificat
        client correspond à ce que vous attendez. Cela signifie en général
        consulter tout ou partie du nom distinctif (DN), afin de vérifier s'il
        contient une chaîne connue. Il existe deux méthodes pour y parvenir ;
        on utilise soit le module <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code>, soit la
        directive <code class="directive"><a href="../mod/mod_ssl.html#sslrequire">SSLRequire</a></code>.</p>
    
        <p>La méthode du module <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> est en général
        incontournable lorsque les certificats ont un contenu arbitraire, ou
        lorsque leur DN ne contient aucun champ connu
        (comme l'organisation, etc...). Dans ce cas, vous devez construire une base
        de données de mots de passe contenant <em>tous</em> les clients
        autorisés, comme suit :</p>
    
        <pre class="prettyprint lang-config">SSLVerifyClient      none
    SSLCACertificateFile "conf/ssl.crt/ca.crt"
    SSLCACertificatePath "conf/ssl.crt"
    
    &lt;Directory "/usr/local/apache2/htdocs/secure/area"&gt;
    SSLVerifyClient      require
        SSLVerifyDepth       5
        SSLOptions           +FakeBasicAuth
        SSLRequireSSL
        AuthName             "Snake Oil Authentication"
        AuthType             Basic
        AuthBasicProvider    file
        AuthUserFile         "/usr/local/apache2/conf/httpd.passwd"
        Require              valid-user
    &lt;/Directory&gt;</pre>
    
        
    
        <p>Le mot de passe utilisé dans cet exemple correspond à la chaîne de
        caractères "password" chiffrée en DES. Voir la documentation de la
        directive <code class="directive"><a href="../mod/mod_ssl.html#ssloptions">SSLOptions</a></code> pour
        plus de détails.</p>
    
        <div class="example"><h3>httpd.passwd</h3><pre>/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</pre></div>
    
        <p>Lorsque vos clients font tous partie d'une même hiérarchie, ce qui
        apparaît dans le DN, vous pouvez les authentifier plus facilement en
        utilisant la directive <code class="directive"><a href="../mod/mod_ssl.html#sslrequire">SSLRequire</a></code>, comme suit :</p>
    
    
        <pre class="prettyprint lang-config">SSLVerifyClient      none
    SSLCACertificateFile "conf/ssl.crt/ca.crt"
    SSLCACertificatePath "conf/ssl.crt"
    
    &lt;Directory "/usr/local/apache2/htdocs/secure/area"&gt;
      SSLVerifyClient      require
      SSLVerifyDepth       5
      SSLOptions           +FakeBasicAuth
      SSLRequireSSL
      SSLRequire       %{SSL_CLIENT_S_DN_O}  eq "Snake Oil, Ltd." \
                   and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
    &lt;/Directory&gt;</pre>
    
    
    
    <h3><a name="intranet" id="intranet">Comment imposer HTTPS avec chiffrements forts,
    et soit authentification de base, soit possession de certificats clients,
    pour l'accès à une partie de l'Intranet, pour les clients en
    provenance de l'Internet ? Je souhaite quand-même autoriser l'accès en HTTP
    aux clients de l'intranet.</a></h3>
    
    
       <p>On suppose dans ces exemples que les clients de l'intranet ont des
       adresses IP dans la gamme 192.168.1.0/24, et que la partie de l'intranet
       à laquelle vous voulez autoriser l'accès depuis l'Internet est
       <code>/usr/local/apache2/htdocs/subarea</code>. Ces lignes de configuration
       doivent se trouver en dehors de votre hôte virtuel HTTPS, afin qu'elles
       s'appliquent à la fois à HTTP et HTTPS.</p>
    
        <pre class="prettyprint lang-config">SSLCACertificateFile "conf/ssl.crt/company-ca.crt"
    
    &lt;Directory "/usr/local/apache2/htdocs"&gt;
    #   En dehors de subarea, seul l'accès depuis l'intranet est
    #   autorisé
        Require              ip 192.168.1.0/24
    &lt;/Directory&gt;
    
    &lt;Directory "/usr/local/apache2/htdocs/subarea"&gt;
    #   Dans subarea, tout accès depuis l'intranet est autorisé
    #   mais depuis l'Internet, seul l'accès par HTTPS + chiffrement fort + Mot de passe
    #   ou HTTPS + chiffrement fort + certificat client n'est autorisé.
    
    #   Si HTTPS est utilisé, on s'assure que le niveau de chiffrement est fort.
    #   Autorise en plus les certificats clients comme une alternative à
    #   l'authentification basique.
        SSLVerifyClient      optional
        SSLVerifyDepth       1
        SSLOptions           +FakeBasicAuth +StrictRequire
        SSLRequire           %{SSL_CIPHER_USEKEYSIZE} &gt;= 128
        
        #   ON oblige les clients venant d'Internet à utiliser HTTPS
        RewriteEngine        on
        RewriteCond          "%{REMOTE_ADDR}" "!^192\.168\.1\.[0-9]+$"
        RewriteCond          "%{HTTPS}" "!=on"
        RewriteRule          "." "-" [F]
        
        #   On permet l'accès soit sur les critères réseaux, soit par authentification Basique
        Satisfy              any
        
        #   Contrôle d'accès réseau
        Require              ip 192.168.1.0/24
        
        #   Configuration de l'authentification HTTP Basique
        AuthType             basic
        AuthName             "Protected Intranet Area"
        AuthBasicProvider    file
        AuthUserFile         "conf/protected.passwd"
        Require              valid-user
    &lt;/Directory&gt;</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="logging" id="logging">Journalisation</a></h2>
        
    
        <p><code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> peut enregistrer des informations de
        débogage très verbeuses dans le journal des erreurs, lorsque sa
        directive <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> est définie
        à des niveaux de trace élevés. Par contre, sur un serveur très
        sollicité, le niveau <code>info</code> sera probablement déjà trop
        élevé. Souvenez-vous que vous pouvez configurer la directive
        <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> par module afin de
        pourvoir à vos besoins.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_howto.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_howto.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/index.html.zh-cn.utf8��������������������������������������������������0000664�0001751�0001751�00000011724�14743132254�021542� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache SSL/TLS 加密 - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache SSL/TLS 加密</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
    <p>Apache HTTP 服务器模块 <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>
    提供了与 <a href="http://www.openssl.org/">OpenSSL</a>
    的接口,它使用安全套接字层和传输层安全协议提供了强加密。
    此模块与这篇文档都基于
    Ralf S. Engelschall 的 mod_ssl 项目。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#documentation">文档</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mod-ssl">mod_ssl</a></li>
    </ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">文档</a></h2>
    <ul>
    <li><a href="ssl_intro.html">简介</a></li>
    <li><a href="ssl_compat.html">兼容性</a></li>
    <li><a href="ssl_howto.html">常见操作</a></li>
    <li><a href="ssl_faq.html">常见问题</a></li>
    <li><a href="../glossary.html">术语</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mod-ssl" id="mod-ssl">mod_ssl</a></h2>
    <p>此模块提供的指令和环境变量的文档位于 <a href="../mod/mod_ssl.html">mod_ssl 参考手册</a>。
    </p>
    </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../en/ssl/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_faq.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000156552�14740503670�021465� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Chiffrement SSL/TLS fort: foire aux questions - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>Chiffrement SSL/TLS fort: foire aux questions</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_faq.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_faq.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <blockquote>
    <p>Le sage n'apporte pas de bonnes réponses, il pose les bonnes questions</p>
    <p class="cite">-- <cite>Claude Levi-Strauss</cite></p>
    
    </blockquote>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#installation">Installation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#aboutconfig">Configuration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#aboutcerts">Certificats</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#aboutssl">Le protocole SSL</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#support">Support de mod_ssl</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="installation" id="installation">Installation</a></h2>
    <ul>
    <li><a href="#mutex">Pourquoi le démarrage d'Apache provoque-t-il des
    erreurs de permission en rapport avec SSLMutex ?</a></li>
    <li><a href="#entropy">Pourquoi mod_ssl s'arrête-t-il avec l'erreur
    "Failed to generate temporary 512 bit RSA private key" au démarrage
    d'Apache ?</a></li>
    </ul>
    
    <h3><a name="mutex" id="mutex">Pourquoi le démarrage d'Apache provoque-t-il des
    erreurs de permission en rapport avec SSLMutex ?</a></h3>
        <p>Des erreurs telles que ``<code>mod_ssl: Child could not open
        SSLMutex lockfile /opt/apache/logs/ssl_mutex.18332 (avec l'erreur
        système qui suit) [...] System: Permission denied (errno: 13)</code>''
        sont souvent provoquées par des permissions trop restrictives sur les
        répertoires <em>parents</em>. Assurez-vous que tous les répertoires
        parents (ici <code>/opt</code>, <code>/opt/apache</code> et
        <code>/opt/apache/logs</code>) ont le bit x positionné au moins pour
        l'UID sous lequel les processus enfants d'Apache s'exécutent (voir la
        directive <code class="directive"><a href="../mod/mod_unixd.html#user">User</a></code>).</p>
    
    
    <h3><a name="entropy" id="entropy">Pourquoi mod_ssl s'arrête-t-il avec l'erreur
    "Failed to generate temporary 512 bit RSA private key" au démarrage
    d'Apache ?</a></h3>
        <p>Pour fonctionner correctement, les logiciels de cryptographie ont
        besoin d'une source de données aléatoires. De nombreux systèmes
        d'exploitation libres proposent un "périphérique source d'entropie"
        qui fournit ce service (il se nomme en général
        <code>/dev/random</code>). Sur d'autres systèmes, les applications
        doivent amorcer manuellement
        le Générateur de Nombres Pseudo-Aléatoires d'OpenSSL
        (Pseudo Random Number Generator -PRNG) à l'aide de données appropriées
        avant de générer des clés ou d'effectuer un chiffrement à clé
        publique. Depuis la version 0.9.5, les fonctions d'OpenSSL qui nécessitent
        des données aléatoires provoquent une erreur si le PRNG n'a pas été amorcé
        avec une source de données aléatoires d'au moins 128 bits.</p>
        <p>Pour éviter cette erreur, <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> doit fournir
        suffisamment d'entropie au PRNG pour lui permettre de fonctionner
        correctement. Ce niveau d'entropie est défini par la directive
        <code class="directive"><a href="../mod/mod_ssl.html#sslrandomseed">SSLRandomSeed</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="aboutconfig" id="aboutconfig">Configuration</a></h2>
    <ul>
    <li><a href="#parallel">Peut-on faire cohabiter HTTP et HTTPS sur le même
    serveur ?</a></li>
    <li><a href="#ports">Quel port HTTPS utilise-t-il ?</a></li>
    <li><a href="#httpstest">Comment s'exprimer en langage HTTPS à des fins
    de test ?</a></li>
    <li><a href="#hang">Pourquoi la communication se bloque-t-elle lorsque je
    me connecte à mon serveur Apache configuré pour SSL ?</a></li>
    <li><a href="#refused">Pourquoi, lorsque je tente d'accéder en HTTPS à mon
    serveur Apache+mod_ssl fraîchement installé, l'erreur ``Connection Refused''
    s'affiche-t-elle ?</a></li>
    <li><a href="#envvars">Pourquoi les variables <code>SSL_XXX</code>
    ne sont-elles pas disponibles dans mes scripts CGI et SSI ?</a></li>
    <li><a href="#relative">Comment puis-je basculer entre les protocoles HTTP et
    HTTPS dans les hyperliens relatifs ?</a></li>
    </ul>
    
    <h3><a name="parallel" id="parallel">Peut-on faire cohabiter HTTP et HTTPS sur le même
    serveur ?</a></h3>
        <p>Oui. HTTP et HTTPS utilisent des ports différents (HTTP écoute le port
        80 et HTTPS le port 443), si bien qu'il n'y a pas de conflit direct entre
        les deux. Vous pouvez soit exécuter deux instances séparées du serveur,
        chacune d'entre elles écoutant l'un de ces ports, soit utiliser l'élégante
        fonctionnalité d'Apache que constituent les hôtes virtuels pour créer
        deux serveurs virtuels gérés par la même instance d'Apache - le
        premier serveur répondant en HTTP aux requêtes sur le port 80,
        le second répondant en HTTPS aux requêtes sur le port
        443.</p>
    
    
    <h3><a name="ports" id="ports">Quel port HTTPS utilise-t-il ?</a></h3>
    <p>Vous pouvez associer le protocole HTTPS à n'importe quel port, mais le port
    standard est le port 443, que tout navigateur compatible HTTPS va utiliser par
    défaut. Vous pouvez forcer votre navigateur à utiliser un port différent en le
    précisant dans l'URL. Par exemple, si votre serveur est configuré pour
    servir des pages en HTTPS sur le port 8080, vous pourrez y accéder par
    l'adresse <code>https://example.com:8080/</code>.</p>
    
    
    <h3><a name="httpstest" id="httpstest">Comment s'exprimer en langage HTTPS à des fins
    de test ?</a></h3>
     <p>Alors que vous utilisez simplement</p>
    
        <div class="example"><p><code>$ telnet localhost 80<br />
        GET / HTTP/1.0</code></p></div>
    
        <p>pour tester facilement Apache via HTTP, les choses ne sont pas si
        simples pour HTTPS à cause du protocole SSL situé entre TCP et HTTP.
        La commande OpenSSL <code>s_client</code> vous permet cependant
        d'effectuer un test similaire via HTTPS :</p>
    
        <div class="example"><p><code>$ openssl s_client -connect localhost:443 -state -debug<br />
        GET / HTTP/1.0</code></p></div>
    
        <p>Avant la véritable réponse HTTP, vous recevrez des informations
        détaillées à propos de l'établissement de la connexion SSL. Si vous
        recherchez un client en ligne de commande à usage plus général qui comprend
        directement HTTP et HTTPS, qui peut effectuer des opérations GET et POST,
        peut utiliser un mandataire, supporte les requêtes portant sur une partie
        d'un fichier (byte-range), etc..., vous devriez vous tourner vers
        l'excellent outil <a href="http://curl.haxx.se/">cURL</a>. Grâce à lui,
        vous pouvez vérifier si Apache répond correctement aux requêtes via
        HTTP et HTTPS comme suit :</p>
    
        <div class="example"><p><code>$ curl http://localhost/<br />
        $ curl https://localhost/</code></p></div>
    
    
    <h3><a name="hang" id="hang">Pourquoi la communication se bloque-t-elle lorsque je
    me connecte à mon serveur Apache configuré pour SSL ?</a></h3>
    <p>Ceci peut arriver si vous vous connectez à un serveur HTTPS (ou à
    un serveur virtuel) via HTTP (par exemple, en utilisant
    <code>http://example.com/</code> au lieu de <code>https://example.com</code>).
    Cela peut aussi arriver en essayant de vous connecter via HTTPS à un
    serveur HTTP (par exemple, en utilisant <code>https://example.com/</code>
    avec un serveur qui ne supporte pas HTTPS, ou le supporte, mais sur un
    port non standard). Assurez-vous que vous vous connectez bien à un
    serveur (virtuel) qui supporte SSL.</p>
    
    
    <h3><a name="refused" id="refused">Pourquoi, lorsque je tente d'accéder en HTTPS à mon
    serveur Apache+mod_ssl fraîchement installé, l'erreur ``Connection Refused''
    s'affiche-t-elle ?</a></h3>
    <p>Une configuration incorrecte peut provoquer ce type d'erreur.
    Assurez-vous que vos directives <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> s'accordent avec vos directives
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>. Si
        l'erreur persiste, recommencez depuis le début en restaurant la
        configuration par défaut fournie par<code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.</p>
    
    
    <h3><a name="envvars" id="envvars">Pourquoi les variables <code>SSL_XXX</code>
    ne sont-elles pas disponibles dans mes scripts CGI et SSI ?</a></h3>
    <p>Assurez-vous que la directive ``<code>SSLOptions +StdEnvVars</code>'' est
    bien présente dans le contexte de vos requêtes CGI/SSI.</p>
    
    
    <h3><a name="relative" id="relative">Comment puis-je basculer entre les protocoles HTTP et
    HTTPS dans les hyperliens relatifs ?</a></h3>
    
    <p>Normalement, pour basculer entre HTTP et HTTPS, vous devez utiliser des
    hyperliens pleinement qualifiés (car vous devez modifier le schéma de l'URL).
    Cependant, à l'aide du module <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>, vous pouvez
    manipuler des hyperliens relatifs, pour obtenir le même effet.</p>
        <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/(.*)_SSL$"   "https://%{SERVER_NAME}/$1" [R,L]
    RewriteRule   "^/(.*)_NOSSL$" "http://%{SERVER_NAME}/$1"  [R,L]</pre>
    
    
        <p>Ce jeu de règles rewrite vous permet d'utiliser des hyperliens de la
        forme <code>&lt;a href="document.html_SSL"&gt;</code> pour passer en HTTPS
        dans les liens relatifs. (Remplacez SSL par NOSSL pour passer en HTTP.)</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="aboutcerts" id="aboutcerts">Certificats</a></h2>
    <ul>
    <li><a href="#keyscerts">Qu'est-ce qu'un clé privée RSA, un certificat,
    une demande de signature de certificat (CSR) ?</a></li>
    <li><a href="#startup">Y a-t-il une différence au démarrage entre un serveur
    Apache non SSL et un serveur Apache supportant SSL ?</a></li>
    <li><a href="#selfcert">Comment créer un certificat auto-signé SSL à des
    fins de test ?</a></li>
    <li><a href="#realcert">Comment créer un vrai certificat SSL ?</a></li>
    <li><a href="#ownca">Comment créer et utiliser sa propre Autorité de
    certification (CA) ?</a></li>
    <li><a href="#passphrase">Comment modifier le mot de passe
    de ma clé privée ?</a></li>
    <li><a href="#removepassphrase">Comment démarrer Apache sans avoir à entrer de
    mot de passe ?</a></li>
    <li><a href="#verify">Comment vérifier si une clé privée correspond bien
    à son certificat ?</a></li>
    <li><a href="#pemder">Comment convertir un certificat du format PEM
    au format DER ?</a></li>
    <li><a href="#gid">Pourquoi les navigateurs se plaignent-ils de ne pas pouvoir
    vérifier mon certificat de serveur ?</a></li>
    </ul>
    
    <h3><a name="keyscerts" id="keyscerts">Qu'est-ce qu'un clé privée RSA, un certificat,
    une demande de signature de certificat (CSR) ?</a></h3>
    <p>Un fichier de clé privée RSA est un fichier numérique que vous pouvez
    utiliser pour déchiffrer des messages que l'on vous a envoyés. Il a son
    pendant à caractère public que vous pouvez distribuer (par le biais de votre
    certificat), ce qui permet aux utilisateurs de chiffrer les messages qu'ils
    vous envoient.</p>
        <p>Une Demande de Signature de Certificat (CSR) est un fichier numérique
        qui contient votre clé publique et votre nom. La CSR doit être envoyée à
        une Autorité de Certification (CA), qui va la convertir en vrai certificat
        en la signant.</p>
        <p>Un certificat contient votre clé publique RSA, votre nom, le nom
        de la CA, et est signé numériquement par cette dernière. Les navigateurs
        qui reconnaissent la CA peuvent vérifier la signature du certificat, et
        ainsi en extraire votre clé publique RSA. Ceci leur permet de vous envoyer
        des messages chiffrés que vous seul pourrez déchiffrer.</p>
        <p>Se référer au chapitre <a href="ssl_intro.html">Introduction</a>
        pour une description générale du protocole SSL.</p>
    
    
    <h3><a name="startup" id="startup">Y a-t-il une différence au démarrage entre un serveur
    Apache non SSL et un serveur Apache supportant SSL ?</a></h3>
    <p>Oui. En général, avec ou sans <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> intégré, le démarrage
    d'Apache ne présente pas de différences. Cependant, si votre fichier de clé
    privée SSL possède un mot de passe, vous devrez le taper au démarrage
    d'Apache.</p>
    
        <p>Devoir entrer manuellement le mot de passe au démarrage du serveur peut
        poser quelques problèmes - par exemple, quand le serveur est démarré au
        moyen de scripts au lancement du système. Dans ce cas, vous pouvez suivre
        les étapes <a href="#removepassphrase">ci-dessous</a> pour supprimer le
        mot de passe de votre clé privée. Gardez à l'esprit qu'agir ainsi augmente
        les risques de sécurité - agissez avec précaution !</p>
    
    
    <h3><a name="selfcert" id="selfcert">Comment créer un certificat auto-signé SSL à des
    fins de test ?</a></h3>
        <ol>
        <li>Vérifiez qu'OpenSSL est installé et l'exécutable openssl dans votre
        <code>PATH</code>.<br />
        <br />
        </li>
        <li>Exécuter la commande suivante pour créer les fichiers
        <code>server.key</code> et <code>server.crt</code> :<br />
    	<code><strong>$ openssl req -new -x509 -nodes -out server.crt
    			-keyout server.key</strong></code><br />
    	Ces fichiers seront utilisés comme suit dans votre
    	<code>httpd.conf</code> :
            <pre class="prettyprint lang-config">SSLCertificateFile    "/path/to/this/server.crt"
    SSLCertificateKeyFile "/path/to/this/server.key"</pre>
    
        </li>
        <li>Il est important de savoir que le fichier <code>server.key</code> n'a
        <em>pas</em> de mot de passe. Pour ajouter un mot de passe à la clé, vous
        devez exécuter la commande suivante et confirmer le mot de passe comme
        demandé.<br />
    	<p><code><strong>$ openssl rsa -des3 -in server.key -out
    	server.key.new</strong></code><br />
    	<code><strong>$ mv server.key.new server.key</strong></code><br /></p>
    	Sauvegardez le fichier <code>server.key</code> ainsi que son mot de
    	passe en lieu sûr.
        </li>
        </ol>
    
    
    <h3><a name="realcert" id="realcert">Comment créer un vrai certificat SSL ?</a></h3>
    <p>Voici la marche à suivre pas à pas :</p>
        <ol>
        <li>Assurez-vous qu'OpenSSL est bien installé et dans votre <code>PATH</code>.
        <br />
        <br />
        </li>
        <li>Créez une clé privée RSA pour votre serveur Apache
        	(elle sera au format PEM et chiffrée en Triple-DES):<br />
           <br />
           <code><strong>$ openssl genrsa -des3 -out server.key 2048</strong></code><br />
           <br />
           Enregistrez le fichier <code>server.key</code> et le mot de passe
           éventuellement défini en lieu sûr.
           Vous pouvez afficher les détails de cette clé privée RSA à l'aide de la
           commande :<br />
    
           <br />
           <code><strong>$ openssl rsa -noout -text -in server.key</strong></code><br />
           <br />
           Si nécessaire, vous pouvez aussi créer une version PEM non chiffrée
           (non recommandé) de clé privée RSA avec :<br />
           <br />
           <code><strong>$ openssl rsa -in server.key -out server.key.unsecure</strong></code><br />
           <br />
    
        </li>
        <li>Créez une Demande de signature de Certificat (CSR) à l'aide de la
        clé privée précédemment générée (la sortie sera au format PEM):<br />
           <br />
           <code><strong>$ openssl req -new -key server.key -out server.csr</strong></code><br />
           <br />
           Vous devez entrer le Nom de Domaine Pleinement Qualifié
           ("Fully Qualified Domain Name" ou FQDN) de votre serveur lorsqu'OpenSSL
           vous demande le "CommonName", c'est à dire que si vous générez une CSR
           pour un site web auquel on accèdera par l'URL
           <code>https://www.foo.dom/</code>, le FQDN sera "www.foo.dom". Vous
           pouvez afficher les détails de ce CSR avec :<br />
    
           <br />
           <code><strong>$ openssl req -noout -text -in server.csr</strong></code><br />
           <br />
        </li>
        <li>Vous devez maintenant envoyer la CSR à une Autorité de Certification
        (CA), afin que cette dernière puisse la signer. Une fois la CSR signée,
        vous disposerez d'un véritable certificat que vous pourrez utiliser avec
        Apache. Vous pouvez faire signer votre CSR par une CA commerciale ou par
        votre propre CA.<br />
           Les CAs commerciales vous demandent en général de leur envoyer la CSR
           par l'intermédiaire d'un formulaire web, de régler le montant de la
           signature, puis vous envoient un certificat signé que vous pouvez
           enregistrer dans un fichier server.crt.
    
           Pour plus de détails sur la manière de créer sa propre CA, et de
           l'utiliser pour signer une CSR, voir <a href="#ownca">ci-dessous</a>.<br />
    
           Une fois la CSR signée, vous pouvez afficher les détails du certificat
           comme suit :<br />
           <br />
           <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br />
    
        </li>
        <li>Vous devez maintenant disposer de deux fichiers :
        <code>server.key</code> et <code>server.crt</code>. Ils sont précisés dans
        votre fichier <code>httpd.conf</code> comme suit :
           <pre class="prettyprint lang-config">SSLCertificateFile    "/path/to/this/server.crt"
    SSLCertificateKeyFile "/path/to/this/server.key"</pre>
    
           Le fichier <code>server.csr</code> n'est plus nécessaire.
        </li>
    
        </ol>
    
    
    <h3><a name="ownca" id="ownca">Comment créer et utiliser sa propre Autorité de
    certification (CA) ?</a></h3>
        <p>La solution la plus simple consiste à utiliser les scripts
        <code>CA.sh</code> ou <code>CA.pl</code> fournis avec OpenSSL. De
        préférence, utilisez cette solution, à moins que vous ayez de bonnes
        raisons de ne pas le faire. Dans ce dernier cas, vous pouvez créer un
        certificat auto-signé comme suit :</p>
    
        <ol>
        <li>Créez une clé privée RSA pour votre serveur
        	(elle sera au format PEM et chiffrée en Triple-DES) :<br />
           <br />
           <code><strong>$ openssl genrsa -des3 -out server.key 2048</strong></code><br />
           <br />
           Sauvegardez le fichier <code>server.key</code> et le mot de passe
           éventuellement défini en lieu sûr.
           Vous pouvez afficher les détails de cette clé privée RSA à l'aide de la
           commande :<br />
           <br />
           <code><strong>$ openssl rsa -noout -text -in server.key</strong></code><br />
           <br />
           Si nécessaire, vous pouvez aussi créer une version PEM non chiffrée
           (non recommandé) de cette clé privée RSA	 avec :<br />
           <br />
           <code><strong>$ openssl rsa -in server.key -out server.key.unsecure</strong></code><br />
           <br />
        </li>
        <li>Créez un certificat auto-signé (structure X509) à l'aide de la clé RSA
        que vous venez de générer (la sortie sera au format PEM) :<br />
           <br />
           <code><strong>$ openssl req -new -x509 -nodes -sha1 -days 365
    		       -key server.key -out server.crt -extensions usr_cert</strong></code><br />
           <br />
           Cette commande signe le certificat du serveur et produit un fichier
           <code>server.crt</code>. Vous pouvez afficher les détails de ce
           certificat avec :<br />
           <br />
           <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br />
           <br />
        </li>
        </ol>
    
    
    <h3><a name="passphrase" id="passphrase">Comment modifier le mot de passe
    de ma clé privée ?</a></h3>
    <p>Vous devez simplement lire la clé avec l'ancien mot de passe et la
    réécrire en spécifiant le nouveau mot de passe. Pour cela, vous pouvez
    utiliser les commandes suivantes :</p>
    
    
        <p><code><strong>$ openssl rsa -des3 -in server.key -out server.key.new</strong></code><br />
        <code><strong>$ mv server.key.new server.key</strong></code><br /></p>
    
        <p>La première fois qu'il vous est demandé un mot de passe PEM, vous
        devez entrer l'ancien mot de passe. Ensuite, on vous demandera d'entrer
        encore un mot de passe - cette fois, entrez le nouveau mot de passe. Si on
        vous demande de vérifier le mot de passe, vous devrez entrer le nouveau
        mot de passe une seconde fois.</p>
    
    
    <h3><a name="removepassphrase" id="removepassphrase">Comment démarrer Apache sans avoir à entrer de
    mot de passe ?</a></h3>
    <p>L'apparition de ce dialogue au démarrage et à chaque redémarrage provient
    du fait que la clé privée RSA contenue dans votre fichier server.key est
    enregistrée sous forme chiffrée pour des raisons de sécurité. Le
    déchiffrement de ce fichier nécessite un mot de passe, afin de pouvoir être
    lu et interprété. Cependant, La suppression du mot de passe diminue le niveau de
    sécurité du serveur - agissez avec précautions !</p>
        <ol>
        <li>Supprimer le chiffrement de la clé privée RSA (tout en conservant une
        copie de sauvegarde du fichier original) :<br />
           <br />
           <code><strong>$ cp server.key server.key.org</strong></code><br />
           <code><strong>$ openssl rsa -in server.key.org -out server.key</strong></code><br />
    
           <br />
        </li>
        <li>Assurez-vous que le fichier server.key n'est lisible que par root :<br />
           <br />
           <code><strong>$ chmod 400 server.key</strong></code><br />
           <br />
        </li>
        </ol>
    
        <p>Maintenant, <code>server.key</code> contient une copie non chiffrée de
        la clé. Si vous utilisez ce fichier pour votre serveur, il ne vous
        demandera plus de mot de passe. CEPENDANT, si quelqu'un arrive à obtenir
        cette clé, il sera en mesure d'usurper votre identité sur le réseau.
        Vous DEVEZ par conséquent vous assurer que seuls root ou le serveur web
        peuvent lire ce fichier (de préférence, démarrez le serveur web sous
        root et faites le s'exécuter sous un autre utilisateur, en n'autorisant
        la lecture de la clé que par root).</p>
    
        <p>Une autre alternative consiste à utiliser la directive
        ``<code>SSLPassPhraseDialog exec:/chemin/vers/programme</code>''. Gardez
        cependant à l'esprit que ce n'est bien entendu ni plus ni moins
        sécurisé.</p>
    
    
    <h3><a name="verify" id="verify">Comment vérifier si une clé privée correspond bien
    à son certificat ?</a></h3>
    <p>Une clé privée contient une série de nombres. Deux de ces nombres forment la
    "clé publique", les autres appartiennent à la "clé privée". Les bits de la
    "clé publique" sont inclus quand vous générez une CSR, et font par
    conséquent partie du certificat associé.</p>
        <p>Pour vérifier que la clé publique contenue dans votre certificat
        correspond bien à la partie publique de votre clé privée, il vous suffit
        de comparer ces nombres. Pour afficher le certificat et la clé,
        utilisez cette commande :</p>
    
        <p><code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br />
        <code><strong>$ openssl rsa -noout -text -in server.key</strong></code></p>
    
        <p>Les parties `modulus' et `public exponent' doivent être identiques dans
        la clé et le certificat. Comme le `public exponent' est habituellement
        65537, et comme il est difficile de vérifier visuellement que les nombreux
        nombres du `modulus' sont identiques, vous pouvez utiliser l'approche
        suivante :</p>
    
        <p><code><strong>$ openssl x509 -noout -modulus -in server.crt | openssl md5</strong></code><br />
        <code><strong>$ openssl rsa -noout -modulus -in server.key | openssl md5</strong></code></p>
    
        <p>Il ne vous reste ainsi que deux nombres relativement courts à comparer.
        Il est possible, en théorie que ces deux nombres soient les mêmes, sans que
        les nombres du modulus soient identiques, mais les chances en sont infimes.</p>
        <p>Si vous souhaitez vérifier à quelle clé ou certificat appartient une CSR
        particulière, vous pouvez effectuer le même calcul
        sur la CSR comme suit :</p>
    
        <p><code><strong>$ openssl req -noout -modulus -in server.csr | openssl md5</strong></code></p>
    
    
    <h3><a name="pemder" id="pemder">Comment convertir un certificat du format PEM
    au format DER ?</a></h3>
    <p>Le format des certificats par défaut pour OpenSSL est le format PEM,
    qui est tout simplement un format DER codé en Base64, avec des lignes
    d'en-têtes et des annotations. Certaines applications, comme
    Microsoft Internet Explorer, ont besoin d'un certificat au format DER de base.
    Vous pouvez convertir un fichier PEM <code>cert.pem</code> en son équivalent
    au format DER <code>cert.der</code> à l'aide de la commande suivante :
    <code><strong>$ openssl x509 -in cert.pem -out cert.der
    -outform DER</strong></code></p>
    
    
    <h3><a name="gid" id="gid">Pourquoi les navigateurs se plaignent-ils de ne pas pouvoir
    vérifier mon certificat de serveur ?</a></h3>
    
        <p>Ceci peut se produire si votre certificat de serveur est signé
        par une autorité de certification intermédiaire. Plusieurs CAs,
        comme Verisign ou Thawte, ont commencé à signer les certificats avec
        des certificats intermédiaires au lieu de leur certificat racine.</p>
    
        <p>Les certificats de CA intermédiaires se situe à un niveau
        intermédiaire entre le certificat racine de la CA (qui est installé dans les
        navigateurs) et le certificat du serveur (que vous avez installé sur
        votre serveur). Pour que le navigateur puisse traverser et vérifier
        la chaîne de confiance depuis le certificat du serveur jusqu'au
        certificat racine, il faut lui fournir les certificats
        intermédiaires. Les CAs devraient pouvoir fournir de tels
        paquetages de certificats intermédiaires à installer sur les
        serveurs.</p>
    
        <p>Vous devez inclure ces certificats intermédiaires via la
        directive <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatechainfile">SSLCertificateChainFile</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="aboutssl" id="aboutssl">Le protocole SSL</a></h2>
    <ul>
    <li><a href="#random">Pourquoi de nombreuses et aléatoires erreurs de
    protocole SSL apparaissent-elles en cas de forte charge du serveur ?</a></li>
    <li><a href="#load">Pourquoi la charge de mon serveur est-elle plus
    importante depuis qu'il sert des ressources chiffrées en SSL ?</a></li>
    <li><a href="#establishing">Pourquoi les connexions en HTTPS à mon serveur
    prennent-elles parfois jusqu'à 30 secondes pour s'établir ?</a></li>
    <li><a href="#ciphers">Quels sont les algorithmes de chiffrement
    supportés par mod_ssl ?</a></li>
    <li><a href="#adh">Pourquoi une erreur ``no shared cipher'' apparaît-elle
    quand j'essaie d'utiliser un algorithme de chiffrement
    Diffie-Hellman anonyme (ADH) ?</a></li>
    <li><a href="#sharedciphers">Pourquoi une erreur ``no shared cipher''
    apparaît-elle lorsqu'on se connecte à mon serveur
    fraîchement installé ?</a></li>
    <li><a href="#vhosts">Pourquoi ne peut-on pas utiliser SSL avec des hôtes
    virtuels identifiés par un nom et non par une adresse IP ?</a></li>
    <li><a href="#vhosts2">Est-il possible d'utiliser
    l'hébergement virtuel basé sur le nom d'hôte
    pour différencier plusieurs hôtes virtuels ?</a></li>
    <li><a href="#comp">Comment mettre en oeuvre la compression SSL ?</a></li>
    <li><a href="#lockicon">Lorsque j'utilise l'authentification de base sur HTTPS,
    l'icône de verrouillage des navigateurs Netscape reste ouverte quand la boîte
    de dialogue d'authentification apparaît. Cela signifie-t-il que les utilisateur
    et mot de passe sont envoyés en clair ?</a></li>
    <li><a href="#msie">Pourquoi des erreurs d'entrée/sortie apparaissent-elles
    lorsqu'on se connecte à un serveur Apache+mod_ssl avec
    Microsoft Internet Explorer (MSIE) ?</a></li>
    <li><a href="#srp">Comment activer TLS-SRP ?</a></li>
    <li><a href="#javadh">Pourquoi des erreurs de négociation apparaissent
    avec les clients basés sur Java lorsqu'on utilise un certificat de plus
    de 1024 bits ?</a></li>
    </ul>
    
    <h3><a name="random" id="random">Pourquoi de nombreuses et aléatoires erreurs de
    protocole SSL apparaissent-elles en cas de forte charge du serveur ?</a></h3>
    <p>Ce problème peut avoir plusieurs causes, mais la principale réside dans le
    cache de session SSL défini par la directive
    <code class="directive"><a href="../mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code>. Le cache de session
    DBM est souvent à la source du problème qui peut être résolu en utilisant le
    cache de session SHM (ou en n'utilisant tout simplement pas de cache).</p>
    
    
    <h3><a name="load" id="load">Pourquoi la charge de mon serveur est-elle plus
    importante depuis qu'il sert des ressources chiffrées en SSL ?</a></h3>
    <p>SSL utilise un procédé de chiffrement fort qui nécessite la manipulation
    d'une quantité très importante de nombres. Lorsque vous effectuez une requête
    pour une page web via HTTPS, tout (même les images) est chiffré avant d'être
    transmis. C'est pourquoi un accroissement du traffic HTTPS entraîne une
    augmentation de la charge.</p>
    
    
    <h3><a name="establishing" id="establishing">Pourquoi les connexions en HTTPS à mon serveur
    prennent-elles parfois jusqu'à 30 secondes pour s'établir ?</a></h3>
    <p>Ce problème provient en général d'un périphérique <code>/dev/random</code>
    qui bloque l'appel système read(2) jusqu'à ce que suffisamment d'entropie
    soit disponible pour servir la requête. Pour plus d'information, se référer au
    manuel de référence de la directive
    <code class="directive"><a href="../mod/mod_ssl.html#sslrandomseed">SSLRandomSeed</a></code>.</p>
    
    
    <h3><a name="ciphers" id="ciphers">Quels sont les algorithmes de chiffrement
    supportés par mod_ssl ?</a></h3>
    <p>En général, tous les algorithmes de chiffrement supportés par la version
    d'OpenSSL installée, le sont aussi par <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>. La liste des
    algorithmes disponibles peut dépendre de la manière dont vous avez installé
    OpenSSL. Typiquement, au moins les algorithmes suivants sont supportés :</p>
    
        <ol>
        <li>RC4 avec SHA1</li>
        <li>AES avec SHA1</li>
        <li>Triple-DES avec SHA1</li>
        </ol>
    
        <p>Pour déterminer la liste réelle des algorithmes disponibles, vous
        pouvez utiliser la commande suivante :</p>
        <div class="example"><p><code>$ openssl ciphers -v</code></p></div>
    
    
    <h3><a name="adh" id="adh">Pourquoi une erreur ``no shared cipher'' apparaît-elle
    quand j'essaie d'utiliser un algorithme de chiffrement
    Diffie-Hellman anonyme (ADH) ?</a></h3>
    <p>Par défaut et pour des raisons de sécurité, OpenSSl ne permet <em>pas</em>
    l'utilisation des algorithmes de chiffrements ADH. Veuillez vous informer
    sur les effets pervers potentiels si vous choisissez d'activer le support
    de ces algorithmes de chiffrements.</p>
    <p>Pour pouvoir utiliser les algorithmes de chiffrements Diffie-Hellman
    anonymes (ADH), vous devez compiler OpenSSL avec
    ``<code>-DSSL_ALLOW_ADH</code>'', puis ajouter ``<code>ADH</code>'' à votre
    directive <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code>.</p>
    
    
    <h3><a name="sharedciphers" id="sharedciphers">Pourquoi une erreur ``no shared cipher''
    apparaît-elle lorsqu'on se connecte à mon serveur
    fraîchement installé ?</a></h3>
    <p>Soit vous avez fait une erreur en définissant votre directive
    <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code> (comparez-la avec
    l'exemple préconfiguré dans <code>extra/httpd-ssl.conf</code>), soit vous avez
    choisi d'utiliser des algorithmes DSA/DH au lieu de RSA lorsque vous avez
    généré votre clé privée, et avez ignoré ou êtes passé outre les
    avertissements. Si vous avez choisi DSA/DH, votre serveur est incapable de
    communiquer en utilisant des algorithmes de chiffrements SSL basés sur RSA
    (du moins tant que vous n'aurez pas configuré une paire clé/certificat RSA
    additionnelle). Les navigateurs modernes tels que NS ou IE ne peuvent
    communiquer par SSL qu'avec des algorithmes RSA. C'est ce qui provoque l'erreur
    "no shared ciphers". Pour la corriger, générez une nouvelle paire
    clé/certificat pour le serveur en utilisant un algorithme de chiffrement
    RSA.</p>
    
    
    <h3><a name="vhosts" id="vhosts">Pourquoi ne peut-on pas utiliser SSL avec des hôtes
    virtuels identifiés par un nom et non par une adresse IP ?</a></h3>
    <p>La raison est très technique, et s'apparente au problème de la primauté de
    l'oeuf ou de la poule. La couche du protocole SSL se trouve en dessous de la
    couche de protocole HTTP qu'elle encapsule. Lors de l'établissement d'une
    connexion SSL (HTTPS), Apache/mod_ssl doit négocier les paramètres du
    protocole SSL avec le client. Pour cela, mod_ssl doit consulter la
    configuration du serveur virtuel (par exemple, il doit accéder à la suite
    d'algorithmes de chiffrement, au certificat du serveur, etc...). Mais afin de
    sélectionner le bon serveur virtuel, Apache doit connaître le contenu du champ
    d'en-tête HTTP <code>Host</code>. Pour cela, il doit lire l'en-tête de la
    requête HTTP. Mais il ne peut le faire tant que la négociation SSL n'est pas
    terminée, or, la phase de négociation SSL a besoin du nom d'hôte contenu
    dans l'en-tête de la requête. Voir la question suivante pour
    contourner ce problème.</p>
    
        <p>Notez que si votre certificat comporte un nom de serveur avec
        caractères génériques, ou des noms de serveurs multiples dans le
        champ subjectAltName, vous pouvez utiliser SSL avec les serveurs
        virtuels à base de noms sans avoir à contourner ce problème.</p>
    
    
    <h3><a name="vhosts2" id="vhosts2">Est-il possible d'utiliser
    l'hébergement virtuel basé sur le nom d'hôte
    pour différencier plusieurs hôtes virtuels ?</a></h3>
        <p>L'hébergement virtuel basé sur le nom est une méthode très populaire
        d'identification des différents hôtes virtuels. Il permet d'utiliser la
        même adresse IP et le même numéro de port pour de nombreux sites
        différents. Lorsqu'on se tourne vers SSL, il semble tout naturel de penser
        que l'on peut appliquer la même méthode pour gérer plusieurs hôtes
        virtuels SSL sur le même serveur.</p>
    
        <p>C'est possible, mais seulement si on utilise une version 2.2.12
        ou supérieure du serveur web compilée avec OpenSSL
        version 0.9.8j ou supérieure. Ceci est du au fait que
        l'utilisation de l'hébergement virtuel à base de nom
        avec SSL nécessite une fonctionnalité appelée
        Indication du Nom de Serveur (Server Name Indication - SNI) que
        seules les révisions les plus récentes de la
        spécification SSL supportent.</p>
    
        <p>Notez que si votre certificat comporte un nom de serveur avec
        caractères génériques, ou des noms de serveurs multiples dans le
        champ subjectAltName, vous pouvez utiliser SSL avec les serveurs
        virtuels à base de noms sans avoir à contourner ce problème.</p>
    
        <p>La raison en est que le protocole SSL constitue une couche séparée qui
        encapsule le protocole HTTP. Aini, la session SSL nécessite une
        transaction séparée qui prend place avant que la session HTTP n'ait débuté.
        Le serveur reçoit une requête SSL sur l'adresse IP X et le port Y
        (habituellement 443). Comme la requête SSL ne contenait aucun
        en-tête Host:, le serveur n'avait aucun moyen de déterminer quel hôte virtuel SSL il
        devait utiliser. En général, il utilisait le premier
        qu'il trouvait et qui
        correspondait à l'adresse IP et au port spécifiés.</p>
    
        <p>Par contre, si vous utilisez des versions du serveur web et
        d'OpenSSL qui supportent SNI, et si le navigateur du client le
        supporte aussi, alors le nom d'hôte sera inclus dans la
        requête SSL originale, et le serveur web pourra
        sélectionner le bon serveur virtuel SSL.</p>
    
        <p>Bien entendu, vous pouvez utiliser l'hébergement virtuel basé sur le nom
        pour identifier de nombreux hôtes virtuels non-SSL
        (tous sur le port 80 par exemple), et ne gérer qu'un seul hôte virtuel SSL
        (sur le port 443). Mais dans ce cas, vous devez définir le numéro de port
        non-SSL à l'aide de la directive NameVirtualHost dans ce style :</p>
    
        <pre class="prettyprint lang-config">NameVirtualHost 192.168.1.1:80</pre>
    
    
        <p>il existe d'autres solutions alternatives comme :</p>
    
        <p>Utiliser des adresses IP différentes pour chaque hôte SSL.
        Utiliser des numéros de port différents pour chaque hôte SSL.</p>
    
    
    <h3><a name="comp" id="comp">Comment mettre en oeuvre la compression SSL ?</a></h3>
    <p>Bien que la négociation pour la compression SSL ait été définie dans la
    spécification de SSLv2 et TLS, ce n'est qu'en mai 2004 que la RFC 3749 a
    défini DEFLATE comme une méthode de compression standard négociable.
    </p>
    <p>Depuis la version 0.9.8, OpenSSL supporte cette compression par défaut
    lorsqu'il est compilé avec l'option <code>zlib</code>. Si le client et le
    serveur supportent la compression, elle sera utilisée. Cependant, la
    plupart des clients essaient encore de se connecter avec un Hello SSLv2.
    Comme SSLv2 ne comportait pas de table des algorithmes de compression préférés
    dans sa négociation, la compression ne peut pas être négociée avec ces clients.
    Si le client désactive le support SSLv2, un Hello SSLv3 ou TLS peut être
    envoyé, selon la bibliothèque SSL utilisée, et la compression peut être mise
    en oeuvre. Vous pouvez vérifier si un client utilise la compression SSL en
    journalisant la variable <code>%{SSL_COMPRESS_METHOD}x</code>.
    </p>
    
    
    <h3><a name="lockicon" id="lockicon">Lorsque j'utilise l'authentification de base sur HTTPS,
    l'icône de verrouillage des navigateurs Netscape reste ouverte quand la boîte
    de dialogue d'authentification apparaît. Cela signifie-t-il que les utilisateur
    et mot de passe sont envoyés en clair ?</a></h3>
    <p>Non, le couple utilisateur/mot de passe est transmis sous forme chiffrée.
    	L'icône de chiffrement dans les navigateurs Netscape n'est pas vraiment
    	synchronisé avec la couche SSL/TLS. Il ne passe à l'état verrouillé
    	qu'au moment où la première partie des données relatives à la page web
    	proprement dite sont transférées, ce qui peut prêter à confusion. Le
    	dispositif d'authentification de base appartient à la couche HTTP, qui
    	est située au dessus de la couche SSL/TLS dans HTTPS. Avant tout
    	transfert de données HTTP sous HTTPS, la couche SSL/TLS a déjà achevé
    	sa phase de négociation et basculé dans le mode de communication
    	chiffrée. Ne vous laissez donc pas abuser par l'état de cet icône.</p>
    
    
    <h3><a name="msie" id="msie">Pourquoi des erreurs d'entrée/sortie apparaissent-elles
    lorsqu'on se connecte via HTTPS à un serveur Apache+mod_ssl avec des
    versions anciennes de
    Microsoft Internet Explorer (MSIE) ?</a></h3>
    <p>La première raison en est la présence dans l'implémentation SSL de
    certaines versions de MSIE de bogues subtils en rapport avec le
    dispositif de "maintien en vie" (keep-alive) HTTP, et les alertes de
    notification de fermeture de session SSL en cas de coupure de la
    connexion au point d'entrée (socket). De plus, l'interaction entre
    SSL et les fonctionnalités HTTP/1.1 pose problème avec certaines
    versions de MSIE. Vous pouvez contourner ces problèmes en interdisant
    à Apache l'utilisation de HTTP/1.1, les connexions avec maintien en vie
    ou l'envoi de messages de notification de fermeture de session SSL aux
    clients MSIE. Pour cela, vous pouvez utiliser la directive suivante
    dans votre section d'hôte virtuel avec support SSL :</p>
        <pre class="prettyprint lang-config">SetEnvIf User-Agent "MSIE [2-5]" \
             nokeepalive ssl-unclean-shutdown \
             downgrade-1.0 force-response-1.0</pre>
    
        <p>En outre, certaines versions de MSIE ont des problèmes avec des
        algorithmes de chiffrement particuliers. Hélas, il n'est pas
        possible d'apporter une solution spécifique à MSIE pour ces
        problèmes, car les algorithmes de chiffrement sont utilisés dès la
        phase de négociation SSL. Ainsi, une directive
        <code class="directive"><a href="../mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> spécifique
        à MSIE ne peut être d'aucun secours. Par contre, vous devrez
        ajuster les paramètres généraux de manière drastique. Avant de
        vous décider, soyez sûr que vos clients rencontrent vraiment des
        problèmes. Dans la négative, n'effectuez pas ces ajustements car
        ils affecteront <em>tous</em> vos clients, ceux utilisant MSIE,
        mais aussi les autres.</p>
    
    
    
    <h3><a name="srp" id="srp">Comment activer TLS-SRP ?</a></h3>
        <p>Le protocole TLS-SRP (Echange de clés sécurisé par mot de passe
        pour TLS comme spécifié dans la RFC 5054) peut compléter ou même
        remplacer les certificats lors du processus d'authentification des
        connexions SSL. Pour utiliser TLS-SRP, spécifiez un fichier de
        vérification SRP OpenSSL via la directive <code class="directive"><a href="../mod/mod_ssl.html#sslsrpverifierfile">SSLSRPVerifierFile</a></code>. Vous pouvez créer
        le fichier de vérification via l'utilitaire <code>openssl</code> :</p>
        <div class="example"><p><code>
        openssl srp -srpvfile passwd.srpv -add username
        </code></p></div>
        <p>Une fois ce fichier créé, vous devez le référencer dans la
        configuration du serveur SSL :</p>
        <div class="example"><p><code>
        SSLSRPVerifierFile /path/to/passwd.srpv
        </code></p></div>
        <p>Pour forcer les clients à utiliser des algorithmes de chiffrement
        basés sur TLS-SRP et s'affranchissant des certificats, utilisez la
        directive suivante :</p>
        <div class="example"><p><code>
        SSLCipherSuite "!DSS:!aRSA:SRP"
        </code></p></div>
    
    
    <h3><a name="javadh" id="javadh">Pourquoi des erreurs de négociation apparaissent
    avec les clients basés sur Java lorsqu'on utilise un certificat de plus
    de 1024 bits ?</a></h3>
        <p>Depuis la version 2.4.7,
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> utilise des paramètres DH qui comportent
        des nombres premiers de plus de 1024 bits. Cependant, java 7 et ses versions
        antérieures ne supportent que les nombres premiers DH d'une longueur
        maximale de 1024 bits.</p>
    
        <p>Si votre client basé sur Java s'arrête avec une exception telle
        que <code>java.lang.RuntimeException: Could not generate DH
        keypair</code> et
        <code>java.security.InvalidAlgorithmParameterException: Prime size
        must be multiple of 64, and can only range from 512 to 1024
        (inclusive)</code>, et si httpd enregistre le message <code>tlsv1
        alert internal error (SSL alert number 80)</code> dans son journal
        des erreurs (avec un <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code>
        <code>info</code> ou supérieur), vous pouvez soit réarranger la
        liste d'algorithmes de mod_ssl via la directive <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code> (éventuellement en
        conjonction avec la directive <code class="directive"><a href="../mod/mod_ssl.html#sslhonorcipherorder">SSLHonorCipherOrder</a></code>), soit utiliser des
        paramètres DH personnalisés avec un nombre
        premier de 1024 bits, paramètres qui seront toujours prioritaires
        par rapport à tout autre paramètre DH par défaut.</p>
    
        <p>Pour générer des paramètres DH personnalisés, utilisez la
        commande <code>openssl dhparam 1024</code>. Vous pouvez aussi
        utiliser les
        paramètres DH standards issus de la <a href="http://www.ietf.org/rfc/rfc2409.txt">RFC 2409</a>, section 6.2 :</p>
        <div class="example"><pre>-----BEGIN DH PARAMETERS-----
    MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
    Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
    /1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
    -----END DH PARAMETERS-----</pre></div>
        <p>Ajoute les paramètres personnalisés incluant les lignes "BEGIN DH
        PARAMETERS" et "END DH PARAMETERS" à la fin du premier fichier de
        certificat défini via la directive <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatefile">SSLCertificateFile</a></code>.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">Support de mod_ssl</a></h2>
    <ul>
    <li><a href="#resources">Quelles sont les sources d'informations
    disponibles en cas de problème avec mod_ssl ?</a></li>
    <li><a href="#contact">Qui peut-on contacter pour un support en cas de
    problème avec mod_ssl ?</a></li>
    <li><a href="#reportdetails">Quelles informations dois-je fournir lors
    de l'écriture d'un rapport de bogue ?</a></li>
    <li><a href="#coredumphelp">Un vidage mémoire s'est produit,
    pouvez-vous m'aider ?</a></li>
    <li><a href="#backtrace">Comment puis-je obtenir une journalisation de
    ce qui s'est passé, pour m'aider à trouver la raison de ce vidage
    mémoire ?</a></li>
    </ul>
    
    <h3><a name="resources" id="resources">Quelles sont les sources d'informations
    disponibles en cas de problème avec mod_ssl ?</a></h3>
    <p>Voici les sources d'informations disponibles ; vous devez chercher
    ici en cas de problème.</p>
    
        <dl>
        <dt>Vous trouverez des réponses dans la Foire Aux Questions du
        manuel utilisateur (ce document)</dt>
        <dd><a href="http://httpd.apache.org/docs/2.4/ssl/ssl_faq.html">
        	http://httpd.apache.org/docs/2.4/ssl/ssl_faq.html</a><br />
    	Cherchez tout d'abord dans la foire aux questions
    	(ce document). Si votre question est courante, on a déjà dû y
    	répondre de nombreuses fois, et elle fait probablement partie
    	de ce document.
        </dd>
        </dl>
    
    
    <h3><a name="contact" id="contact">Qui peut-on contacter pour un support en cas de
    problème avec mod_ssl ?</a></h3>
     <p>Voici toutes les possibilités de support pour mod_ssl, par ordre
     de préférence. Merci d'utiliser ces possibilités
     <em>dans cet ordre</em> - ne vous précipitez pas sur celle qui vous
     paraît la plus alléchante. </p>
        <ol>
        <li><em>Envoyez un rapport de problème à la liste de diffusion de
        support des utilisateurs d'Apache httpd</em><br />
            <a href="mailto:users@httpd.apache.org">
            users@httpd.apache.org</a><br />
            C'est la deuxième manière de soumettre votre rapport de
    	problème. Ici aussi, vous devez d'abord vous abonner à la
    	liste, mais vous pourrez ensuite discuter facilement de votre
    	problème avec l'ensemble de la communauté d'utilisateurs
    	d'Apache httpd.
        </li>
    
        <li><em>Ecrire un rapport de problème dans la base de données des
        bogues</em><br />
    	<a href="http://httpd.apache.org/bug_report.html">
    	http://httpd.apache.org/bug_report.html</a><br />
            C'est la dernière manière de soumettre votre rapport de
    	problème. Vous ne devez utiliser cette solution que si vous
    	avez déjà écrit aux listes de diffusion, et n'avez pas trouvé
    	de solution. Merci de suivre les instructions de la page
    	mentionnée ci-dessus <em>avec soin</em>.
        </li>
        </ol>
    
    
    <h3><a name="reportdetails" id="reportdetails">Quelles informations dois-je fournir lors
    de l'écriture d'un rapport de bogue ?</a></h3>
    <p>Vous devez toujours fournir au moins les informations
    suivantes :</p>
    
        <dl>
        <dt>Les versions d'Apache httpd et OpenSSL installées</dt>
        <dd>La version d'Apache peut être déterminée en exécutant
        <code>httpd -v</code>. La version d'OpenSSL peut être déterminée
        en exécutant <code>openssl version</code>. Si Lynx est installé,
        vous pouvez aussi exécuter la commande<code>lynx -mime_header
        http://localhost/ | grep Server</code> et ainsi obtenir ces
        informations en une seule fois.
        </dd>
    
        <dt>Les détails de votre installation d'Apache httpd et OpenSSL</dt>
        <dd>A cet effet, vous pouvez fournir un fichier journal de votre
        session de terminal qui montre les étapes de la configuration et
        de l'installation. En cas d'impossibilité, vous devez au moins
        fournir la ligne de commande <code class="program"><a href="../programs/configure.html">configure</a></code> que
        vous avez utilisée.
        </dd>
    
        <dt>En cas de vidage mémoire, inclure une trace de ce qui s'est
        passé</dt>
        <dd>Si votre serveur Apache httpd fait un vidage de sa
        mémoire, merci de fournir en pièce jointe un fichier contenant
        une trace de la zone dédiée à la pile (voir
        <a href="#backtrace">ci-dessous</a> pour des informations sur la manière
        de l'obtenir). Il est nécessaire de disposer de ces informations
        afin de pouvoir déterminer la raison de votre vidage mémoire.
        </dd>
    
        <dt>Une description détaillée de votre problème</dt>
    
        <dd>Ne riez pas, nous sommes sérieux ! De nombreux rapports
        n'incluent pas de description de la véritable nature du problème.
        Sans ces informations, il est très difficile pour quiconque de
        vous aider. Donc, et c'est votre propre intérêt (vous souhaitez
        que le problème soit résolu, n'est-ce pas ?), fournissez, s'il vous
        plait, le maximum de détails possible. Bien entendu, vous devez
        aussi inclure tout ce qui a été dit précédemment.
        </dd>
        </dl>
    
    
    <h3><a name="coredumphelp" id="coredumphelp">Un vidage mémoire s'est produit,
    pouvez-vous m'aider ?</a></h3>
    <p>En général non, du moins tant que vous n'aurez pas fourni plus de
    détails à propos de la localisation dans le code où Apache a effectué
    son vidage mémoire. Ce dont nous avons en général besoin pour vous
    aider est une trace de ce qui s'est passé (voir la question suivante).
    Sans cette information, il est pratiquement impossible de déterminer
    la nature du problème et de vous aider à le résoudre.</p>
    
    
    <h3><a name="backtrace" id="backtrace">Comment puis-je obtenir une journalisation de
    ce qui s'est passé, pour m'aider à trouver la raison de ce vidage
    mémoire ?</a></h3>
    <p>Vous trouverez ci-dessous les différentes étapes permettant
    d'obtenir une journalisation des évènements (backtrace) :</p>
        <ol>
        <li>Assurez-vous que les symboles de débogage sont disponibles, au
        moins pour Apache. Pour cela, sur les plates-formes où GCC/GDB est
        utilisé, vous devez compiler Apache+mod_ssl avec l'option
        ``<code>OPTIM="-g -ggdb3"</code>''. Sur les autres plates-formes,
        l'option ``<code>OPTIM="-g"</code>'' est un minimum.
        </li>
    
        <li>Démarrez le serveur et essayez de reproduire le vidage mémoire.
        A cet effet, vous pouvez utiliser une directive du style
        ``<code>CoreDumpDirectory /tmp</code>'' pour être sûr que le
        fichier de vidage mémoire puisse bien être écrit. Vous devriez
        obtenir un fichier <code>/tmp/core</code> ou
        <code>/tmp/httpd.core</code>. Si ce n'est pas le cas, essayez de
        lancer votre serveur sous un UID autre que root.
        Pour des raisons de sécurité, de nombreux
        noyaux modernes de permettent pas à un processus de vider sa
        mémoire une fois qu'il a accompli un <code>setuid()</code> (à moins
        qu'il effectue un <code>exec()</code>) car des informations d'un
        niveau privilégié pourraient être transmises en mémoire. Si
        nécessaire, vous pouvez exécuter <code>/chemin/vers/httpd -X</code>
        manuellement afin de ne pas permettre à Apache de se clôner (fork).
        </li>
    
        <li>Analysez le vidage mémoire. Pour cela, exécutez
        <code>gdb /path/to/httpd /tmp/httpd.core</code> ou une commande
        similaire. Dans GDB, tout ce que vous avez à faire est d'entrer
        <code>bt</code>, et voila, vous obtenez la backtrace. Pour les
        débogueurs autres que GDB consulter le manuel correspondant.
        </li>
        </ol>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_faq.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_faq.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_faq.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_compat.html.en�����������������������������������������������������0000664�0001751�0001751�00000052363�14737241666�021314� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>SSL/TLS Strong Encryption: Compatibility - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>SSL/TLS Strong Encryption: Compatibility</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_compat.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_compat.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <p>
    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 <a href="http://www.apache-ssl.org/">Apache-SSL</a> (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 <a href="http://www.redhat.com/explore/stronghold/">Stronghold</a> (based
    on a different evolution branch, named Sioux up to Stronghold 2.x, and
    based on mod_ssl since Stronghold 3.x).</p>
    
    <p>
    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.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configuration">Configuration Directives</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#variables">Environment Variables</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#customlog">Custom Log Functions</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Configuration Directives</a></h2>
    <p>The mapping between configuration directives used by Apache-SSL
    1.x and mod_ssl 2.0.x is given in <a href="#table1">Table
    1</a>. 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.</p>
    
    
    <h3><a name="table1" id="table1">Table 1: Configuration Directive Mapping</a></h3>
    
    <table><tr class="header"><th>Old Directive</th><th>mod_ssl Directive</th><th>Comment</th></tr>
    <tr class="header"><th colspan="3">Apache-SSL 1.x &amp; mod_ssl 2.0.x compatibility:</th></tr>
    <tr><td><code>SSLEnable</code></td><td><code>SSLEngine on</code></td><td>compactified</td></tr>
    <tr class="odd"><td><code>SSLDisable</code></td><td><code>SSLEngine off</code></td><td>compactified</td></tr>
    <tr><td><code>SSLLogFile</code> <em>file</em></td><td><code /></td><td>Use per-module <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> setting instead.</td></tr>
    <tr class="odd"><td><code>SSLRequiredCiphers</code> <em>spec</em></td><td><code>SSLCipherSuite</code> <em>spec</em></td><td>renamed</td></tr>
    <tr><td><code>SSLRequireCipher</code> <em>c1</em> ...</td><td><code>SSLRequire %{SSL_CIPHER} in {"</code><em>c1</em><code>",
    ...}</code></td><td>generalized</td></tr>
    <tr class="odd"><td><code>SSLBanCipher</code> <em>c1</em> ...</td><td><code>SSLRequire not (%{SSL_CIPHER} in {"</code><em>c1</em><code>",
    ...})</code></td><td>generalized</td></tr>
    <tr><td><code>SSLFakeBasicAuth</code></td><td><code>SSLOptions +FakeBasicAuth</code></td><td>merged</td></tr>
    <tr class="odd"><td><code>SSLCacheServerPath</code> <em>dir</em></td><td>-</td><td>functionality removed</td></tr>
    <tr><td><code>SSLCacheServerPort</code> <em>integer</em></td><td>-</td><td>functionality removed</td></tr>
    <tr class="header"><th colspan="3">Apache-SSL 1.x compatibility:</th></tr>
    <tr class="odd"><td><code>SSLExportClientCertificates</code></td><td><code>SSLOptions +ExportCertData</code></td><td>merged</td></tr>
    <tr><td><code>SSLCacheServerRunDir</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr class="header"><th colspan="3">Sioux 1.x compatibility:</th></tr>
    <tr class="odd"><td><code>SSL_CertFile</code> <em>file</em></td><td><code>SSLCertificateFile</code> <em>file</em></td><td>renamed</td></tr>
    <tr><td><code>SSL_KeyFile</code> <em>file</em></td><td><code>SSLCertificateKeyFile</code> <em>file</em></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CipherSuite</code> <em>arg</em></td><td><code>SSLCipherSuite</code> <em>arg</em></td><td>renamed</td></tr>
    <tr><td><code>SSL_X509VerifyDir</code> <em>arg</em></td><td><code>SSLCACertificatePath</code> <em>arg</em></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_Log</code> <em>file</em></td><td><code>-</code></td><td>Use per-module <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> setting instead.</td></tr>
    <tr><td><code>SSL_Connect</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_ClientAuth</code> <em>arg</em></td><td><code>SSLVerifyClient</code> <em>arg</em></td><td>renamed</td></tr>
    <tr><td><code>SSL_X509VerifyDepth</code> <em>arg</em></td><td><code>SSLVerifyDepth</code> <em>arg</em></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_FetchKeyPhraseFrom</code> <em>arg</em></td><td>-</td><td>not directly mappable; use SSLPassPhraseDialog</td></tr>
    <tr><td><code>SSL_SessionDir</code> <em>dir</em></td><td>-</td><td>not directly mappable; use SSLSessionCache</td></tr>
    <tr class="odd"><td><code>SSL_Require</code> <em>expr</em></td><td>-</td><td>not directly mappable; use SSLRequire</td></tr>
    <tr><td><code>SSL_CertFileType</code> <em>arg</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr class="odd"><td><code>SSL_KeyFileType</code> <em>arg</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr><td><code>SSL_X509VerifyPolicy</code> <em>arg</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr class="odd"><td><code>SSL_LogX509Attributes</code> <em>arg</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr class="header"><th colspan="3">Stronghold 2.x compatibility:</th></tr>
    <tr><td><code>StrongholdAccelerator</code> <em>engine</em></td><td><code>SSLCryptoDevice</code> <em>engine</em></td><td>renamed</td></tr>
    <tr class="odd"><td><code>StrongholdKey</code> <em>dir</em></td><td>-</td><td>functionality not needed</td></tr>
    <tr><td><code>StrongholdLicenseFile</code> <em>dir</em></td><td>-</td><td>functionality not needed</td></tr>
    <tr class="odd"><td><code>SSLFlag</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renamed</td></tr>
    <tr><td><code>SSLSessionLockFile</code> <em>file</em></td><td><code>SSLMutex</code> <em>file</em></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSLCipherList</code> <em>spec</em></td><td><code>SSLCipherSuite</code> <em>spec</em></td><td>renamed</td></tr>
    <tr><td><code>RequireSSL</code></td><td><code>SSLRequireSSL</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSLErrorFile</code> <em>file</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr><td><code>SSLRoot</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr class="odd"><td><code>SSL_CertificateLogDir</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr><td><code>AuthCertDir</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr class="odd"><td><code>SSL_Group</code> <em>name</em></td><td>-</td><td>functionality not supported</td></tr>
    <tr><td><code>SSLProxyMachineCertPath</code> <em>dir</em></td><td><code>SSLProxyMachineCertificatePath</code> <em>dir</em></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSLProxyMachineCertFile</code> <em>file</em></td><td><code>SSLProxyMachineCertificateFile</code> <em>file</em></td><td>renamed</td></tr>
    <tr><td><code>SSLProxyCipherList</code> <em>spec</em></td><td><code>SSLProxyCipherSpec</code> <em>spec</em></td><td>renamed</td></tr>
    </table>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="variables" id="variables">Environment Variables</a></h2>
    
    <p>The mapping between environment variable names used by the older
    SSL solutions and the names used by mod_ssl is given in <a href="#table2">Table 2</a>.</p>
    
    <h3><a name="table2" id="table2">Table 2: Environment Variable Derivation</a></h3>
    
    <table><tr class="header"><th>Old Variable</th><th>mod_ssl Variable</th><th>Comment</th></tr>
    <tr><td><code>SSL_PROTOCOL_VERSION</code></td><td><code>SSL_PROTOCOL</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSLEAY_VERSION</code></td><td><code>SSL_VERSION_LIBRARY</code></td><td>renamed</td></tr>
    <tr><td><code>HTTPS_SECRETKEYSIZE</code></td><td><code>SSL_CIPHER_USEKEYSIZE</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>HTTPS_KEYSIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renamed</td></tr>
    <tr><td><code>HTTPS_CIPHER</code></td><td><code>SSL_CIPHER</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>HTTPS_EXPORT</code></td><td><code>SSL_CIPHER_EXPORT</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_KEY_SIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CERTIFICATE</code></td><td><code>SSL_SERVER_CERT</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_CERT_START</code></td><td><code>SSL_SERVER_V_START</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CERT_END</code></td><td><code>SSL_SERVER_V_END</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_CERT_SERIAL</code></td><td><code>SSL_SERVER_M_SERIAL</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_SIGNATURE_ALGORITHM</code></td><td><code>SSL_SERVER_A_SIG</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_DN</code></td><td><code>SSL_SERVER_S_DN</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CN</code></td><td><code>SSL_SERVER_S_DN_CN</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_EMAIL</code></td><td><code>SSL_SERVER_S_DN_Email</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_O</code></td><td><code>SSL_SERVER_S_DN_O</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_OU</code></td><td><code>SSL_SERVER_S_DN_OU</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_C</code></td><td><code>SSL_SERVER_S_DN_C</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_SP</code></td><td><code>SSL_SERVER_S_DN_SP</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_L</code></td><td><code>SSL_SERVER_S_DN_L</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_IDN</code></td><td><code>SSL_SERVER_I_DN</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_ICN</code></td><td><code>SSL_SERVER_I_DN_CN</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_IEMAIL</code></td><td><code>SSL_SERVER_I_DN_Email</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_IO</code></td><td><code>SSL_SERVER_I_DN_O</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_IOU</code></td><td><code>SSL_SERVER_I_DN_OU</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_IC</code></td><td><code>SSL_SERVER_I_DN_C</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SERVER_ISP</code></td><td><code>SSL_SERVER_I_DN_SP</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_IL</code></td><td><code>SSL_SERVER_I_DN_L</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_CERTIFICATE</code></td><td><code>SSL_CLIENT_CERT</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_CERT_START</code></td><td><code>SSL_CLIENT_V_START</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_CERT_END</code></td><td><code>SSL_CLIENT_V_END</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_CERT_SERIAL</code></td><td><code>SSL_CLIENT_M_SERIAL</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_SIGNATURE_ALGORITHM</code></td><td><code>SSL_CLIENT_A_SIG</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_DN</code></td><td><code>SSL_CLIENT_S_DN</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_CN</code></td><td><code>SSL_CLIENT_S_DN_CN</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_EMAIL</code></td><td><code>SSL_CLIENT_S_DN_Email</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_O</code></td><td><code>SSL_CLIENT_S_DN_O</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_OU</code></td><td><code>SSL_CLIENT_S_DN_OU</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_C</code></td><td><code>SSL_CLIENT_S_DN_C</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_SP</code></td><td><code>SSL_CLIENT_S_DN_SP</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_L</code></td><td><code>SSL_CLIENT_S_DN_L</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_IDN</code></td><td><code>SSL_CLIENT_I_DN</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_ICN</code></td><td><code>SSL_CLIENT_I_DN_CN</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_IEMAIL</code></td><td><code>SSL_CLIENT_I_DN_Email</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_IO</code></td><td><code>SSL_CLIENT_I_DN_O</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_IOU</code></td><td><code>SSL_CLIENT_I_DN_OU</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_IC</code></td><td><code>SSL_CLIENT_I_DN_C</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_ISP</code></td><td><code>SSL_CLIENT_I_DN_SP</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_CLIENT_IL</code></td><td><code>SSL_CLIENT_I_DN_L</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_EXPORT</code></td><td><code>SSL_CIPHER_EXPORT</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_KEYSIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_SECKEYSIZE</code></td><td><code>SSL_CIPHER_USEKEYSIZE</code></td><td>renamed</td></tr>
    <tr><td><code>SSL_SSLEAY_VERSION</code></td><td><code>SSL_VERSION_LIBRARY</code></td><td>renamed</td></tr>
    <tr class="odd"><td><code>SSL_STRONG_CRYPTO</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_KEY_EXP</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_KEY_SIZE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_SESSIONDIR</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_CERTIFICATELOGDIR</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CERTFILE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_KEYFILE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_KEYFILETYPE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr><td><code>SSL_CLIENT_KEY_EXP</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    <tr><td><code>SSL_CLIENT_KEY_SIZE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr>
    </table>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customlog" id="customlog">Custom Log Functions</a></h2>
    <p>
    When mod_ssl is enabled, additional functions exist for the <a href="../mod/mod_log_config.html#formats">Custom Log Format</a> of
    <code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code> as documented in the Reference
    Chapter. Beside the ``<code>%{</code><em>varname</em><code>}x</code>''
    eXtension format function which can be used to expand any variables provided
    by any module, an additional Cryptography
    ``<code>%{</code><em>name</em><code>}c</code>'' cryptography format function
    exists for backward compatibility. The currently implemented function calls
    are listed in <a href="#table3">Table 3</a>.</p>
    
    <h3><a name="table3" id="table3">Table 3: Custom Log Cryptography Function</a></h3>
    
    <table>
    
    <tr><th>Function Call</th><th>Description</th></tr>
    
    <tr><td><code>%...{version}c</code></td>   <td>SSL protocol version</td></tr>
    <tr><td><code>%...{cipher}c</code></td>    <td>SSL cipher</td></tr>
    <tr><td><code>%...{subjectdn}c</code></td> <td>Client Certificate Subject Distinguished Name</td></tr>
    <tr><td><code>%...{issuerdn}c</code></td>  <td>Client Certificate Issuer Distinguished Name</td></tr>
    <tr><td><code>%...{errcode}c</code></td>   <td>Certificate Verification Error (numerical)</td></tr>
    
    <tr><td><code>%...{errstr}c</code></td>    <td>Certificate Verification Error (string)</td></tr>
    </table>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_compat.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_compat.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_compat.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/index.html�������������������������������������������������������������0000664�0001751�0001751�00000000716�13710016232�017624� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: index.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_compat.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000054160�14740503670�022171� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Chiffrement fort SSL/TLS : Compatibilité - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>Chiffrement fort SSL/TLS : Compatibilité</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_compat.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_compat.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document couvre la compatibilité ascendante entre mod_ssl et
    d'autres solutions SSL. mod_ssl n'est pas la seule solution SSL pour Apache ;
    quatre autres produits sont (ou ont été) également disponibles :
    <a href="http://www.apache-ssl.org/">Apache-SSL</a>, le produit libre de
    Ben Laurie (d'où mod_ssl est issu à l'origine en 1998), Secure
    Web Server, un produit commercial de Red Hat (basé sur mod_ssl),
    Raven SSL Module, un produit commercial
    de Covalent (basé lui aussi sur mod_ssl), et enfin <a href="http://www.redhat.com/explore/stronghold/">Stronghold</a>, produit
    commercial de C2Net et maintenant de Red Hat, (basé sur une branche
    d'évolution différente appelée Sioux jusqu'à Stronghold 2.x et basé sur
    mod_ssl depuis Stronghold 3.x).</p>
    
    <p>En plus de ses fonctionnalités propres, mod_ssl rassemble la plupart de
    celles des autres solutions SSL, si bien qu'il est très simple de
    migrer depuis un module plus ancien vers mod_ssl. Les directives de
    configuration et les noms des variables d'environnement utilisés par les
    solutions SSL plus anciennes diffèrent de ceux qu'utilise mod_ssl ;
    les tableaux de correspondance ci-dessous fournissent les équivalences
    de termes utilisés par mod_ssl.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configuration">Directives de configuration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#variables">Variables d'environnement</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#customlog">Fonctions de personnalisation des journaux</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Directives de configuration</a></h2>
    <p>La correspondance entre les directives de configuration qu'utilise
    Apache-SSL 1.x et mod_ssl 2.0.x est fournie dans le <a href="#table1">Tableau
    1</a>. La correspondance depuis Sioux 1.x et Stronghold 2.x n'est que
    partielle car certaines fonctionnalités de ces interfaces ne sont pas
    supportées par mod_ssl.</p>
    
    
    <h3><a name="table1" id="table1">Tableau 1: Correspondance entre les directives de configuration</a></h3>
    
    <table><tr class="header"><th>Ancienne directive</th><th>Directive mod_ssl</th><th>Commentaires</th></tr>
    <tr class="header"><th colspan="3">Compatibilité entre Apache-SSL 1.x et mod_ssl 2.0.x :</th></tr>
    <tr><td><code>SSLEnable</code></td><td><code>SSLEngine on</code></td><td>plus compacte</td></tr>
    <tr class="odd"><td><code>SSLDisable</code></td><td><code>SSLEngine off</code></td><td>plus compacte</td></tr>
    <tr><td><code>SSLLogFile</code>
    <em>file</em></td><td><code /></td><td>Utilisez plutôt la directive
    de niveau module <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code>.</td></tr>
    <tr class="odd"><td><code>SSLRequiredCiphers</code> <em>spec</em></td><td><code>SSLCipherSuite</code> <em>spec</em></td><td>renommée</td></tr>
    <tr><td><code>SSLRequireCipher</code> <em>c1</em> ...</td><td><code>SSLRequire %{SSL_CIPHER} in {"</code><em>c1</em><code>",
    ...}</code></td><td>plus générale</td></tr>
    <tr class="odd"><td><code>SSLBanCipher</code> <em>c1</em> ...</td><td><code>SSLRequire not (%{SSL_CIPHER} in {"</code><em>c1</em><code>",
    ...})</code></td><td>plus générale</td></tr>
    <tr><td><code>SSLFakeBasicAuth</code></td><td><code>SSLOptions +FakeBasicAuth</code></td><td>rassemblées</td></tr>
    <tr class="odd"><td><code>SSLCacheServerPath</code> <em>dir</em></td><td>-</td><td>fonctionnalité supprimée</td></tr>
    <tr><td><code>SSLCacheServerPort</code> <em>integer</em></td><td>-</td><td>fonctionnalité supprimée</td></tr>
    <tr class="header"><th colspan="3">Compatibilité avec Apache-SSL 1.x :</th></tr>
    <tr class="odd"><td><code>SSLExportClientCertificates</code></td><td><code>SSLOptions +ExportCertData</code></td><td>rassemblées</td></tr>
    <tr><td><code>SSLCacheServerRunDir</code> <em>dir</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr class="header"><th colspan="3">Compatibilité avec Sioux 1.x :</th></tr>
    <tr class="odd"><td><code>SSL_CertFile</code> <em>file</em></td><td><code>SSLCertificateFile</code> <em>file</em></td><td>renommée</td></tr>
    <tr><td><code>SSL_KeyFile</code> <em>file</em></td><td><code>SSLCertificateKeyFile</code> <em>file</em></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CipherSuite</code> <em>arg</em></td><td><code>SSLCipherSuite</code> <em>arg</em></td><td>renommée</td></tr>
    <tr><td><code>SSL_X509VerifyDir</code> <em>arg</em></td><td><code>SSLCACertificatePath</code> <em>arg</em></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_Log</code>
    <em>file</em></td><td><code>-</code></td><td>Utilisez plutôt la directive
    de niveau module <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code></td></tr>
    <tr><td><code>SSL_Connect</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_ClientAuth</code> <em>arg</em></td><td><code>SSLVerifyClient</code> <em>arg</em></td><td>renommée</td></tr>
    <tr><td><code>SSL_X509VerifyDepth</code> <em>arg</em></td><td><code>SSLVerifyDepth</code> <em>arg</em></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_FetchKeyPhraseFrom</code> <em>arg</em></td><td>-</td><td>pas de véritable équivalent ; utiliser SSLPassPhraseDialog</td></tr>
    <tr><td><code>SSL_SessionDir</code> <em>dir</em></td><td>-</td><td>pas de véritable équivalent ; utiliser SSLSessionCache</td></tr>
    <tr class="odd"><td><code>SSL_Require</code> <em>expr</em></td><td>-</td><td>pas de véritable équivalent ; utiliser SSLRequire</td></tr>
    <tr><td><code>SSL_CertFileType</code> <em>arg</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr class="odd"><td><code>SSL_KeyFileType</code> <em>arg</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr><td><code>SSL_X509VerifyPolicy</code> <em>arg</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr class="odd"><td><code>SSL_LogX509Attributes</code> <em>arg</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr class="header"><th colspan="3">Compatibilité avec Stronghold 2.x :</th></tr>
    <tr><td><code>StrongholdAccelerator</code> <em>engine</em></td><td><code>SSLCryptoDevice</code> <em>engine</em></td><td>renommée</td></tr>
    <tr class="odd"><td><code>StrongholdKey</code> <em>dir</em></td><td>-</td><td>sans objet</td></tr>
    <tr><td><code>StrongholdLicenseFile</code> <em>dir</em></td><td>-</td><td>sans objet</td></tr>
    <tr class="odd"><td><code>SSLFlag</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renommée</td></tr>
    <tr><td><code>SSLSessionLockFile</code> <em>file</em></td><td><code>SSLMutex</code> <em>file</em></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSLCipherList</code> <em>spec</em></td><td><code>SSLCipherSuite</code> <em>spec</em></td><td>renommée</td></tr>
    <tr><td><code>RequireSSL</code></td><td><code>SSLRequireSSL</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSLErrorFile</code> <em>file</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr><td><code>SSLRoot</code> <em>dir</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr class="odd"><td><code>SSL_CertificateLogDir</code> <em>dir</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr><td><code>AuthCertDir</code> <em>dir</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr class="odd"><td><code>SSL_Group</code> <em>name</em></td><td>-</td><td>fonctionnalité non supportée</td></tr>
    <tr><td><code>SSLProxyMachineCertPath</code> <em>dir</em></td><td><code>SSLProxyMachineCertificatePath</code> <em>dir</em></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSLProxyMachineCertFile</code> <em>file</em></td><td><code>SSLProxyMachineCertificateFile</code> <em>file</em></td><td>renommée</td></tr>
    <tr><td><code>SSLProxyCipherList</code> <em>spec</em></td><td><code>SSLProxyCipherSpec</code> <em>spec</em></td><td>renommée</td></tr>
    </table>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="variables" id="variables">Variables d'environnement</a></h2>
    
    <p>La correspondance entre les noms des variables d'environnement utilisés par
    les solutions SSL plus anciennes et les noms utilisés par mod_ssl est fournie
    dans le <a href="#table2">Tableau 2</a>.</p>
    
    <h3><a name="table2" id="table2">Tableau 2: Dérivation des variables d'environnement</a></h3>
    
    <table><tr class="header"><th>Ancienne variable</th><th>Variable mod_ssl</th><th>Commentaires</th></tr>
    <tr><td><code>SSL_PROTOCOL_VERSION</code></td><td><code>SSL_PROTOCOL</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSLEAY_VERSION</code></td><td><code>SSL_VERSION_LIBRARY</code></td><td>renommée</td></tr>
    <tr><td><code>HTTPS_SECRETKEYSIZE</code></td><td><code>SSL_CIPHER_USEKEYSIZE</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>HTTPS_KEYSIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renommée</td></tr>
    <tr><td><code>HTTPS_CIPHER</code></td><td><code>SSL_CIPHER</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>HTTPS_EXPORT</code></td><td><code>SSL_CIPHER_EXPORT</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_KEY_SIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CERTIFICATE</code></td><td><code>SSL_SERVER_CERT</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_CERT_START</code></td><td><code>SSL_SERVER_V_START</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CERT_END</code></td><td><code>SSL_SERVER_V_END</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_CERT_SERIAL</code></td><td><code>SSL_SERVER_M_SERIAL</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_SIGNATURE_ALGORITHM</code></td><td><code>SSL_SERVER_A_SIG</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_DN</code></td><td><code>SSL_SERVER_S_DN</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CN</code></td><td><code>SSL_SERVER_S_DN_CN</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_EMAIL</code></td><td><code>SSL_SERVER_S_DN_Email</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_O</code></td><td><code>SSL_SERVER_S_DN_O</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_OU</code></td><td><code>SSL_SERVER_S_DN_OU</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_C</code></td><td><code>SSL_SERVER_S_DN_C</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_SP</code></td><td><code>SSL_SERVER_S_DN_SP</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_L</code></td><td><code>SSL_SERVER_S_DN_L</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_IDN</code></td><td><code>SSL_SERVER_I_DN</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_ICN</code></td><td><code>SSL_SERVER_I_DN_CN</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_IEMAIL</code></td><td><code>SSL_SERVER_I_DN_Email</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_IO</code></td><td><code>SSL_SERVER_I_DN_O</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_IOU</code></td><td><code>SSL_SERVER_I_DN_OU</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_IC</code></td><td><code>SSL_SERVER_I_DN_C</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SERVER_ISP</code></td><td><code>SSL_SERVER_I_DN_SP</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_IL</code></td><td><code>SSL_SERVER_I_DN_L</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_CERTIFICATE</code></td><td><code>SSL_CLIENT_CERT</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_CERT_START</code></td><td><code>SSL_CLIENT_V_START</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_CERT_END</code></td><td><code>SSL_CLIENT_V_END</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_CERT_SERIAL</code></td><td><code>SSL_CLIENT_M_SERIAL</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_SIGNATURE_ALGORITHM</code></td><td><code>SSL_CLIENT_A_SIG</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_DN</code></td><td><code>SSL_CLIENT_S_DN</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_CN</code></td><td><code>SSL_CLIENT_S_DN_CN</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_EMAIL</code></td><td><code>SSL_CLIENT_S_DN_Email</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_O</code></td><td><code>SSL_CLIENT_S_DN_O</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_OU</code></td><td><code>SSL_CLIENT_S_DN_OU</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_C</code></td><td><code>SSL_CLIENT_S_DN_C</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_SP</code></td><td><code>SSL_CLIENT_S_DN_SP</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_L</code></td><td><code>SSL_CLIENT_S_DN_L</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_IDN</code></td><td><code>SSL_CLIENT_I_DN</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_ICN</code></td><td><code>SSL_CLIENT_I_DN_CN</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_IEMAIL</code></td><td><code>SSL_CLIENT_I_DN_Email</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_IO</code></td><td><code>SSL_CLIENT_I_DN_O</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_IOU</code></td><td><code>SSL_CLIENT_I_DN_OU</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_IC</code></td><td><code>SSL_CLIENT_I_DN_C</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_ISP</code></td><td><code>SSL_CLIENT_I_DN_SP</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_CLIENT_IL</code></td><td><code>SSL_CLIENT_I_DN_L</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_EXPORT</code></td><td><code>SSL_CIPHER_EXPORT</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_KEYSIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_SECKEYSIZE</code></td><td><code>SSL_CIPHER_USEKEYSIZE</code></td><td>renommée</td></tr>
    <tr><td><code>SSL_SSLEAY_VERSION</code></td><td><code>SSL_VERSION_LIBRARY</code></td><td>renommée</td></tr>
    <tr class="odd"><td><code>SSL_STRONG_CRYPTO</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_KEY_EXP</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_KEY_SIZE</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_SESSIONDIR</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_CERTIFICATELOGDIR</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_CERTFILE</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr><td><code>SSL_SERVER_KEYFILE</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_SERVER_KEYFILETYPE</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr><td><code>SSL_CLIENT_KEY_EXP</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr class="odd"><td><code>SSL_CLIENT_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    <tr><td><code>SSL_CLIENT_KEY_SIZE</code></td><td><code>-</code></td><td>Non supportée par mod_ssl</td></tr>
    </table>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customlog" id="customlog">Fonctions de personnalisation des journaux</a></h2>
    <p>Quand mod_ssl est activé, le <a href="../mod/mod_log_config.html#formats">Format de journal courant
    (Custom Log Format)</a> du module <code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code> possède
    des fonctions supplémentaires comme indiqué dans le chapitre de référence.
    En plus de la fonction de format étendu
    ``<code>%{</code><em>varname</em><code>}x</code>'' que l'on peut utiliser pour
    extraire le contenu d'une variable fournie par n'importe quel module,
    la fonction
    de format cryptographique ``<code>%{</code><em>name</em><code>}c</code>'' a
    été ajoutée à des fins de compatibilité ascendante. Les appels de fonctions
    actuellement implémentés sont énumérés dans le
    <a href="#table3">Tableau 3</a>.</p>
    
    <h3><a name="table3" id="table3">Table 3: Fonctions cryptographiques du format de journal courant</a></h3>
    
    <table>
    
    <tr><th>Appel de fonction</th><th>Description</th></tr>
    
    <tr><td><code>%...{version}c</code></td>   <td>Version du protocole SSL</td></tr>
    <tr><td><code>%...{cipher}c</code></td>    <td>Chiffrement SSL</td></tr>
    <tr><td><code>%...{subjectdn}c</code></td> <td>Nom distinctif du sujet du certificat du client</td></tr>
    <tr><td><code>%...{issuerdn}c</code></td>  <td>Nom distinctif de l'émetteur du certificat du client</td></tr>
    <tr><td><code>%...{errcode}c</code></td>   <td>Erreur lors de la vérification du certificat (numérique)</td></tr>
    
    <tr><td><code>%...{errstr}c</code></td>    <td>Erreur lors de la vérification du certificat (chaîne de caractères)</td></tr>
    </table>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/ssl/ssl_compat.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_compat.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_compat.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/index.html.en����������������������������������������������������������0000664�0001751�0001751�00000011734�14737241666�020254� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache SSL/TLS Encryption - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache SSL/TLS Encryption</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/ssl/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>The Apache HTTP Server module <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>
    provides an interface to the <a href="http://www.openssl.org/">OpenSSL</a> library, which provides
    Strong Encryption using the Secure Sockets Layer and Transport Layer
    Security protocols.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#documentation">Documentation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mod-ssl">mod_ssl</a></li>
    </ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">Documentation</a></h2>
    <ul>
    <li><a href="ssl_howto.html">mod_ssl Configuration How-To</a></li>
    <li><a href="ssl_intro.html">Introduction To SSL</a></li>
    <li><a href="ssl_compat.html">Compatibility</a></li>
    <li><a href="ssl_faq.html">Frequently Asked Questions</a></li>
    <li><a href="../glossary.html">Glossary</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mod-ssl" id="mod-ssl">mod_ssl</a></h2>
    <p>Extensive documentation on the directives and environment variables
    provided by this module is provided in the <a href="../mod/mod_ssl.html">mod_ssl reference documentation</a>.
    </p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/ssl/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../tr/ssl/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/ssl/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_intro.html.en������������������������������������������������������0000664�0001751�0001751�00000105374�14737241666�021165� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>SSL/TLS Strong Encryption: An Introduction - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>SSL/TLS Strong Encryption: An Introduction</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_intro.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_intro.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/ssl_intro.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div>
    
    
    <p>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 <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> users by pulling together various concepts, definitions,
    and examples as a starting point for further exploration.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#cryptographictech">Cryptographic Techniques</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#certificates">Certificates</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssl">Secure Sockets Layer (SSL)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#references">References</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cryptographictech" id="cryptographictech">Cryptographic Techniques</a></h2>
    
    <p>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 [<a href="#AC96">AC96</a>]) and provide the basis for privacy,
    integrity, and authentication.</p>
    
    <h3><a name="cryptographicalgo" id="cryptographicalgo">Cryptographic Algorithms</a></h3>
    
        <p>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 until it is
        decrypted. Once in this form, the message can only be
        decrypted by using 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.</p>
    
        <p>There are two categories of cryptographic algorithms: conventional
        and public key.</p>
    
        <dl>
        <dt>Conventional cryptography</dt>
        <dd>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. As long as this key is kept
        secret, nobody other than the sender or recipient can read the message.
        If Alice and the bank know a secret key, then they can send each other
        private messages. The task of sharing a key between sender and recipient
        before communicating, while also keeping it secret from others, can be
        problematic.</dd>
    
        <dt>Public key cryptography</dt>
        <dd>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).</dd>
        </dl>
    
        <p>Anyone can 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
        can send private messages to the owner of a key-pair (the bank), by
        encrypting them using their public key. Only the bank will be able to
        decrypt them.</p>
    
    
    <h3><a name="messagedigests" id="messagedigests">Message Digests</a></h3>
    
        <p>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 for her 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 the summaries are the same then the message has been received
        intact.</p>
    
        <p>A summary such as this is called a <dfn>message digest</dfn>, <em>one-way
        function</em> or <em>hash function</em>. Message digests are used to create
        a short, fixed-length representation of a longer, variable-length message.
        Digest algorithms are designed to produce a unique digest for each
        message. Message digests are designed to make it impractically difficult
        to determine the message from the digest and (in theory) 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.</p>
    
        <p>Another challenge that Alice faces is finding a way to send the digest
        to the bank securely; if the digest is not sent securely, its integrity may
        be compromised and with it the possibility for the bank to determine the
        integrity of the original message. Only if the digest is sent securely can
        the integrity of the associated message be determined.</p>
    
        <p>One way to send the digest securely is to include it in a digital
        signature.</p>
    
    
    <h3><a name="digitalsignatures" id="digitalsignatures">Digital Signatures</a></h3>
    <p>When Alice sends a message to the bank, the bank needs to ensure that the
    message is really from her, so an intruder cannot request a transaction
    involving her account. A <em>digital signature</em>, created by Alice and
    included with the message, serves this purpose.</p>
    
    <p>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 can <em>decrypt</em> the signature using the public key, only the
    sender knows the private key. This means that only the sender can have signed
    the message. 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.</p>
    <p>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).</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="certificates" id="certificates">Certificates</a></h2>
    
    <p>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 is part of the bank's key-pair,
    and not an intruder's. Similarly, the bank needs to verify that the message
    signature really was signed by the private key that belongs to Alice.</p>
    
    <p>If each party has a certificate which validates the other's identity,
    confirms the public key and is signed by a trusted agency, then both
    can be assured that they are communicating with whom they think they are.
    Such a trusted agency is called a <em>Certificate Authority</em> and
    certificates are used for authentication.</p>
    
    <h3><a name="certificatecontents" id="certificatecontents">Certificate Contents</a></h3>
    
        <p>A certificate associates a public key with the real identity of
        an individual, server, or other entity, known as the subject. As
        shown in <a href="#table1">Table 1</a>, 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.</p>
    
        <h4><a name="table1" id="table1">Table 1: Certificate Information</a></h4>
        
        <table>
        
        <tr><th>Subject</th>
            <td>Distinguished Name, Public Key</td></tr>
        <tr><th>Issuer</th>
            <td>Distinguished Name, Signature</td></tr>
        <tr><th>Period of Validity</th>
            <td>Not Before Date, Not After Date</td></tr>
        <tr><th>Administrative Information</th>
            <td>Version, Serial Number</td></tr>
        <tr><th>Extended Information</th>
            <td>Basic Constraints, Netscape Flags, etc.</td></tr>
        </table>
        
    
        <p>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 [<a href="#X509">X509</a>], which defines the fields, field names and
        abbreviations used to refer to the fields (see <a href="#table2">Table
        2</a>).</p>
    
        <h4><a name="table2" id="table2">Table 2: Distinguished Name Information</a></h4>
        
        <table class="bordered">
        
        <tr><th>DN Field</th>
            <th>Abbrev.</th>
            <th>Description</th>
            <th>Example</th></tr>
        <tr><td>Common Name</td>
            <td>CN</td>
            <td>Name being certified</td>
            <td>CN=Joe Average</td></tr>
        <tr><td>Organization or Company</td>
            <td>O</td>
            <td>Name is associated with this<br />organization</td>
            <td>O=Snake Oil, Ltd.</td></tr>
        <tr><td>Organizational Unit</td>
            <td>OU</td>
            <td>Name is associated with this <br />organization unit, such
            as a department</td>
            <td>OU=Research Institute</td></tr>
        <tr><td>City/Locality</td>
            <td>L</td>
            <td>Name is located in this City</td>
            <td>L=Snake City</td></tr>
        <tr><td>State/Province</td>
            <td>ST</td>
            <td>Name is located in this State/Province</td>
            <td>ST=Desert</td></tr>
        <tr><td>Country</td>
            <td>C</td>
            <td>Name is located in this Country (ISO code)</td>
            <td>C=XZ</td></tr>
        </table>
        
    
        <p>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. For example, a Netscape browser requires that the
        Common Name for a certificate representing a server matches a wildcard
        pattern for the domain name of that server, such
        as <code>*.snakeoil.com</code>.</p>
    
        <p>The binary format of a certificate is defined using the ASN.1
        notation [<a href="#ASN1">ASN1</a>] [<a href="#PKCS">PKCS</a>]. 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
        [<a href="#MIME">MIME</a>]. When placed between begin and end delimiter
        lines (as below), this encoded version is called a PEM ("Privacy Enhanced
        Mail") encoded certificate.</p>
    
        <div class="example"><h3>Example of a PEM-encoded certificate (snakeoil.crt)</h3><pre>-----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-----</pre></div>
    
    
    <h3><a name="certificateauthorities" id="certificateauthorities">Certificate Authorities</a></h3>
    
        <p>By verifying the information in a certificate request
        before granting the certificate, the Certificate Authority assures
        itself of 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 she is.</p>
    
        <h4><a name="certificatechains" id="certificatechains">Certificate Chains</a></h4>
        
            <p>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.</p>
        
    
        <h4><a name="rootlevelca" id="rootlevelca">Creating a Root-Level CA</a></h4>
        
            <p>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:
            who can vouch 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. Browsers are preconfigured to trust well-known
            certificate authorities, but it is important to 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.</p>
    
            <p>A number of companies, such as <a href="http://www.thawte.com/">Thawte</a> and <a href="http://www.verisign.com/">VeriSign</a>
            have established themselves as Certificate Authorities. These
            companies provide the following services:</p>
    
            <ul>
            <li>Verifying certificate requests</li>
            <li>Processing certificate requests</li>
            <li>Issuing and managing certificates</li>
            </ul>
    
            <p>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.</p>
        
    
        <h4><a name="certificatemanagement" id="certificatemanagement">Certificate Management</a></h4>
        
            <p>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 for how long
            certificates remain valid, they renew them and keep lists of
            certificates that were issued in the past but are no longer valid
            (Certificate Revocation Lists, or CRLs).</p>
    
            <p>For example, if Alice is entitled to a certificate as an
            employee of a company but has now left
            that company, her certificate may need to be revoked.
            Because certificates are only issued after the subject's identity has
            been verified and can then be passed around to all those with whom
            the subject may communicate, it is impossible to tell from the
            certificate alone that it has been revoked.
            Therefore when examining certificates for validity
            it is necessary to contact the issuing Certificate Authority to
            check CRLs -- this is usually not an automated part of the process.</p>
    
            <div class="note"><h3>Note</h3>
            <p>If you use a Certificate Authority that browsers are not configured
            to trust 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.</p>
            </div>
        
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssl" id="ssl">Secure Sockets Layer (SSL)</a></h2>
    
    <p>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.</p>
    
    <p>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 when
    establishing a protocol session.</p>
    
    <h3><a name="table4" id="table4">Table 4: Versions of the SSL protocol</a></h3>
    
        <table class="bordered">
        
        <tr><th>Version</th>
            <th>Source</th>
            <th>Description</th>
        </tr>
        <tr><td>SSL v2.0</td>
            <td>Vendor Standard (from Netscape Corp.)</td>
            <td>First SSL protocol for which implementations exist</td>
        </tr>
        <tr><td>SSL v3.0</td>
            <td>Expired Internet Draft (from Netscape Corp.) [<a href="#SSL3">SSL3</a>]</td>
            <td>Revisions to prevent specific security attacks, add non-RSA
            ciphers and support for certificate chains</td>
        </tr>
        <tr><td>TLS v1.0</td>
            <td>Proposed Internet Standard (from IETF) [<a href="#TLS1">TLS1</a>]</td>
            <td>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.</td>
        </tr>
        <tr><td>TLS v1.1</td>
            <td>Proposed Internet Standard (from IETF) [<a href="#TLS11">TLS11</a>]</td>
            <td>Update of TLS 1.0 to add protection against Cipher block chaining
            (CBC) attacks.</td>
        </tr>
        <tr><td>TLS v1.2</td>
            <td>Proposed Internet Standard (from IETF) [<a href="#TLS12">TLS12</a>]</td>
            <td>Update of TLS 1.1 deprecating MD5 as hash, and adding incompatibility
            to SSL so it will never negotiate the use of SSLv2.</td>
        </tr>
        </table>
    
    
    <p>There are a number of versions of the SSL protocol, as shown in
    <a href="#table4">Table 4</a>. 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
    [<a href="#TLS1">TLS</a>] protocol standard, currently in development by
    the Internet Engineering Task Force (IETF).</p>
    
    <h3><a name="session" id="session">Establishing a Session</a></h3>
    
        <p>The SSL session is established by following a handshake sequence
        between client and server, as shown in <a href="#figure1">Figure 1</a>. This sequence may vary, depending on whether the server
        is configured to provide a server certificate or request a client
        certificate. Although 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.</p>
    
        <div class="note"><h3>Note</h3>
        <p>Once an SSL session has been established, it may be reused. This
        avoids the performance penalty of repeating the many steps needed
        to start a session. To do this, the server assigns each SSL session a
        unique session identifier which is cached in the server and which the
        client can use in future connections to reduce the handshake time
        (until the session identifier expires from the cache of the server).</p>
        </div>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig1.gif" alt="" width="423" height="327" /><br />
        <a id="figure1" name="figure1"><dfn>Figure 1</dfn></a>: Simplified SSL
        Handshake Sequence</p>
    
        <p>The elements of the handshake sequence, as used by the client and
        server, are listed below:</p>
    
        <ol>
        <li>Negotiate the Cipher Suite to be used during data transfer</li>
        <li>Establish and share a session key between client and server</li>
        <li>Optionally authenticate the server to the client</li>
        <li>Optionally authenticate the client to the server</li>
        </ol>
    
        <p>The first step, Cipher Suite Negotiation, allows the client and
        server to choose a Cipher Suite supported by both of them. The SSL3.0
        protocol specification defines 31 Cipher Suites. A Cipher Suite is
        defined by the following components:</p>
    
        <ul>
        <li>Key Exchange Method</li>
        <li>Cipher for Data Transfer</li>
        <li>Message Digest for creating the Message Authentication Code (MAC)</li>
        </ul>
    
        <p>These three elements are described in the sections that follow.</p>
    
    
    <h3><a name="keyexchange" id="keyexchange">Key Exchange Method</a></h3>
    
        <p>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
        RSA key exchange (when certificates are used), and Diffie-Hellman key
        exchange (for exchanging keys without certificates, or without prior
        communication between client and server).</p>
    
        <p>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 protection
        against a man-in-the-middle-attack during the information exchange
        used to generating the shared key [<a href="#AC96">AC96</a>, p516].</p>
    
    
    <h3><a name="ciphertransfer" id="ciphertransfer">Cipher for Data Transfer</a></h3>
    
        <p>SSL uses conventional symmetric cryptography, as described earlier,
        for encrypting messages in a session.
        There are nine choices of how to encrypt, including the option not to
        encrypt:</p>
    
        <ul>
        <li>No encryption</li>
        <li>Stream Ciphers
            <ul>
            <li>RC4 with 40-bit keys</li>
            <li>RC4 with 128-bit keys</li>
            </ul></li>
        <li>CBC Block Ciphers
            <ul><li>RC2 with 40 bit key</li>
            <li>DES with 40 bit key</li>
            <li>DES with 56 bit key</li>
            <li>Triple-DES with 168 bit key</li>
            <li>Idea (128 bit key)</li>
            <li>Fortezza (96 bit key)</li>
            </ul></li>
        </ul>
    
        <p>"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 [<a href="#AC96">AC96</a>, ch12], which has a number of
        variants (including DES40 and 3DES_EDE). "Idea" is currently one of
        the best and cryptographically strongest algorithms available,
        and "RC2" is a proprietary algorithm from RSA DSI [<a href="#AC96">AC96</a>, ch13].</p>
    
    
    <h3><a name="digestfunction" id="digestfunction">Digest Function</a></h3>
    
        <p>The choice of digest function determines how a digest is created
        from a record unit. SSL supports the following:</p>
    
        <ul>
        <li>No digest (Null choice)</li>
        <li>MD5, a 128-bit hash</li>
        <li>Secure Hash Algorithm (SHA-1), a 160-bit hash</li>
        </ul>
    
        <p>The message digest is used to create a Message Authentication Code
        (MAC) which is encrypted with the message to verify integrity and to
        protect against replay attacks.</p>
    
    
    <h3><a name="handshake" id="handshake">Handshake Sequence Protocol</a></h3>
    
        <p>The handshake sequence uses three protocols:</p>
    
        <ul>
        <li>The <dfn>SSL Handshake Protocol</dfn>
        for performing the client and server SSL session establishment.</li>
        <li>The <dfn>SSL Change Cipher Spec Protocol</dfn> for actually
        establishing agreement on the Cipher Suite for the session.</li>
        <li>The <dfn>SSL Alert Protocol</dfn> for conveying SSL error
        messages between client and server.</li>
        </ul>
    
        <p>These protocols, as well as application protocol data, are
        encapsulated in the <dfn>SSL Record Protocol</dfn>, as shown in
        <a href="#figure2">Figure 2</a>. 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.</p>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig2.gif" alt="" width="428" height="217" /><br />
        <a id="figure2" name="figure2"><dfn>Figure 2</dfn></a>: SSL Protocol Stack
        </p>
    
        <p>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 was no previous session,
        the Null cipher suite is used, which means there will be no encryption and
        messages will have no integrity digests, until the session has been
        established.</p>
    
    
    <h3><a name="datatransfer" id="datatransfer">Data Transfer</a></h3>
    
        <p>The SSL Record Protocol, shown in <a href="#figure3">Figure 3</a>,
        is used to transfer application and SSL Control data between the
        client and server, where necessary 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, no major SSL implementations include support
        for compression).</p>
    
        <p class="figure">
        <img src="../images/ssl_intro_fig3.gif" alt="" width="423" height="323" /><br />
        <a id="figure3" name="figure3"><dfn>Figure 3</dfn></a>: SSL Record Protocol
        </p>
    
    
    <h3><a name="securehttp" id="securehttp">Securing HTTP Communication</a></h3>
    
        <p>One common use of SSL is to secure Web HTTP communication between
        a browser and a webserver. This does not preclude the use of
        non-secured HTTP - the secure version (called HTTPS) is the same as
        plain HTTP over SSL, but uses the URL scheme <code>https</code>
        rather than <code>http</code>, and a different server port (by default,
        port 443). This functionality is a large part of what <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> provides for the Apache webserver.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="references" id="references">References</a></h2>
    
    <dl>
    <dt><a id="AC96" name="AC96">[AC96]</a></dt>
    <dd>Bruce Schneier, <q>Applied Cryptography</q>, 2nd Edition, Wiley,
    1996. See <a href="http://www.counterpane.com/">http://www.counterpane.com/</a> for various other materials by Bruce
    Schneier.</dd>
    
    <dt><a id="ASN1" name="ASN1">[ASN1]</a></dt>
    <dd>ITU-T Recommendation X.208, <q>Specification of Abstract Syntax Notation
    One (ASN.1)</q>, last updated 2008. See <a href="http://www.itu.int/ITU-T/asn1/">http://www.itu.int/ITU-T/asn1/</a>.
    </dd>
    
    <dt><a id="X509" name="X509">[X509]</a></dt>
    <dd>ITU-T Recommendation X.509, <q>The Directory - Authentication
    Framework</q>. For references, see <a href="http://en.wikipedia.org/wiki/X.509">http://en.wikipedia.org/wiki/X.509</a>.
    </dd>
    
    <dt><a id="PKCS" name="PKCS">[PKCS]</a></dt>
    <dd><q>Public Key Cryptography Standards (PKCS)</q>,
    RSA Laboratories Technical Notes, See <a href="http://www.rsasecurity.com/rsalabs/pkcs/">http://www.rsasecurity.com/rsalabs/pkcs/</a>.</dd>
    
    <dt><a id="MIME" name="MIME">[MIME]</a></dt>
    <dd>N. Freed, N. Borenstein, <q>Multipurpose Internet Mail Extensions
    (MIME) Part One: Format of Internet Message Bodies</q>, RFC2045.
    See for instance <a href="http://tools.ietf.org/html/rfc2045">http://tools.ietf.org/html/rfc2045</a>.</dd>
    
    <dt><a id="SSL3" name="SSL3">[SSL3]</a></dt>
    <dd>Alan O. Freier, Philip Karlton, Paul C. Kocher, <q>The SSL Protocol
    Version 3.0</q>, 1996. See <a href="http://www.netscape.com/eng/ssl3/draft302.txt">http://www.netscape.com/eng/ssl3/draft302.txt</a>.</dd>
    
    <dt><a id="TLS1" name="TLS1">[TLS1]</a></dt>
    <dd>Tim Dierks, Christopher Allen, <q>The TLS Protocol Version 1.0</q>,
    1999. See <a href="http://ietf.org/rfc/rfc2246.txt">http://ietf.org/rfc/rfc2246.txt</a>.</dd>
    
    <dt><a id="TLS11" name="TLS11">[TLS11]</a></dt>
    <dd><q>The TLS Protocol Version 1.1</q>,
    2006. See <a href="http://tools.ietf.org/html/rfc4346">http://tools.ietf.org/html/rfc4346</a>.</dd>
    
    <dt><a id="TLS12" name="TLS12">[TLS12]</a></dt>
    <dd><q>The TLS Protocol Version 1.2</q>,
    2008. See <a href="http://tools.ietf.org/html/rfc5246">http://tools.ietf.org/html/rfc5246</a>.</dd>
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_intro.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_intro.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/ssl/ssl_intro.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_intro.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_howto.html���������������������������������������������������������0000664�0001751�0001751�00000000321�13710016232�020526� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: ssl_howto.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: ssl_howto.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_howto.html.en������������������������������������������������������0000664�0001751�0001751�00000055114�14737241666�021166� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>SSL/TLS Strong Encryption: How-To - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>SSL/TLS Strong Encryption: How-To</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_howto.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_howto.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document is intended to get you started, and get a few things
    working. You are strongly encouraged to read the rest of the SSL
    documentation, and arrive at a deeper understanding of the material,
    before progressing to the advanced techniques.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configexample">Basic Configuration Example</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ciphersuites">Cipher Suites and Enforcing Strong Security</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ocspstapling">OCSP Stapling</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#accesscontrol">Client Authentication and Access Control</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#logging">Logging</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configexample" id="configexample">Basic Configuration Example</a></h2>
    
    
    <p>Your SSL configuration will need to contain, at minimum, the
    following directives.</p>
    
    <pre class="prettyprint lang-config">LoadModule ssl_module modules/mod_ssl.so
    
    Listen 443
    &lt;VirtualHost *:443&gt;
        ServerName www.example.com
        SSLEngine on
        SSLCertificateFile "/path/to/www.example.com.cert"
        SSLCertificateKeyFile "/path/to/www.example.com.key"
    &lt;/VirtualHost&gt;</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ciphersuites" id="ciphersuites">Cipher Suites and Enforcing Strong Security</a></h2>
    
    <ul>
    <li><a href="#onlystrong">How can I create an SSL server which accepts strong encryption only?</a></li>
    <li><a href="#strongurl">How can I create an SSL server which accepts all types of ciphers in general, but
    requires a strong cipher for access to a particular URL?</a></li>
    </ul>
    
    <h3><a name="onlystrong" id="onlystrong">How can I create an SSL server which accepts strong encryption
    only?</a></h3>
    
        <p>The following enables only the strongest ciphers:</p>
        <pre class="prettyprint lang-config">SSLCipherSuite HIGH:!aNULL:!MD5</pre>
    
    
        <p>While with the following configuration you specify a preference
        for specific speed-optimized ciphers (which will be selected by
        mod_ssl, provided that they are supported by the client):</p>
    
        <pre class="prettyprint lang-config">SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5
    SSLHonorCipherOrder on</pre>
    
    
    
    <h3><a name="strongurl" id="strongurl">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?</a></h3>
    
        <p>Obviously, a server-wide <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code> which restricts
        ciphers to the strong variants, isn't the answer here. However,
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> can be reconfigured within <code>Location</code>
        blocks, to give a per-directory solution, and can automatically force
        a renegotiation of the SSL parameters to meet the new configuration.
        This can be done as follows:</p>
        <pre class="prettyprint lang-config"># be liberal in general
    SSLCipherSuite ALL:!aNULL:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP:+eNULL
    
    &lt;Location "/strong/area"&gt;
    # but https://hostname/strong/area/ and below
    # requires strong ciphers
    SSLCipherSuite HIGH:!aNULL:!MD5
    &lt;/Location&gt;</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ocspstapling" id="ocspstapling">OCSP Stapling</a></h2>
    
    
    <p>The Online Certificate Status Protocol (OCSP) is a mechanism for
    determining whether or not a server certificate has been revoked, and OCSP
    Stapling is a special form of this in which the server, such as httpd and
    mod_ssl, maintains current OCSP responses for its certificates and sends
    them to clients which communicate with the server.  Most certificates
    contain the address of an OCSP responder maintained by the issuing
    Certificate Authority, and mod_ssl can communicate with that responder to
    obtain a signed response that can be sent to clients communicating with
    the server.</p>
    
    <p>Because the client can obtain the certificate revocation status from
    the server, without requiring an extra connection from the client to the
    Certificate Authority, OCSP Stapling is the preferred way for the
    revocation status to be obtained.  Other benefits of eliminating the 
    communication between clients and the Certificate Authority are that the
    client browsing history is not exposed to the Certificate Authority and
    obtaining status is more reliable by not depending on potentially heavily
    loaded Certificate Authority servers.</p>
    
    <p>Because the response obtained by the server can be reused for all clients
    using the same certificate during the time that the response is valid, the
    overhead for the server is minimal.</p>
    
    <p>Once general SSL support has been configured properly, enabling OCSP
    Stapling generally requires only very minor modifications to the httpd
    configuration — the addition of these two directives:</p>
    
        <pre class="prettyprint lang-config">SSLUseStapling On
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"</pre>
    
    
    <p>These directives are placed at global scope (i.e., not within a virtual
    host definition) wherever other global SSL configuration directives are
    placed, such as in <code>conf/extra/httpd-ssl.conf</code> for normal 
    open source builds of httpd, <code>/etc/apache2/mods-enabled/ssl.conf</code>
    for the Ubuntu or Debian-bundled httpd, etc.</p>
    
    <p>The path on the <code class="directive">SSLStaplingCache</code> directive
    (e.g., <code>logs/</code>) should match the one on the 
    <code class="directive">SSLSessionCache</code> directive.  This path is relative
    to <code class="directive">ServerRoot</code>.</p>
    
    <p>This particular <code class="directive">SSLStaplingCache</code> directive requires
    <code class="module"><a href="../mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code> (from the <code>shmcb</code> prefix on the
    directive's argument).  This module is usually enabled already for
    <code class="directive">SSLSessionCache</code> or on behalf of some module other than
    <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.  If you enabled an SSL session cache using a 
    mechanism other than <code class="module"><a href="../mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code>, use that alternative
    mechanism for <code class="directive">SSLStaplingCache</code> as well.  For example:</p>
    
        <pre class="prettyprint lang-config">SSLSessionCache "dbm:logs/ssl_scache"
    SSLStaplingCache "dbm:logs/ssl_stapling"</pre>
    
    
    <p>You can use the openssl command-line program to verify that an OCSP response
    is sent by your server:</p>
    
    <pre>$ openssl s_client -connect www.example.com:443 -status -servername www.example.com
    ...
    OCSP response: 
    ======================================
    OCSP Response Data:
        OCSP Response Status: successful (0x0)
        Response Type: Basic OCSP Response
    ...
        Cert Status: Good
    ...</pre>
    
    <p>The following sections highlight the most common situations which require
    further modification to the configuration.  Refer also to the 
    <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> reference manual.</p>
    
    <h3>If more than a few SSL certificates are used for the server</h3>
    
    <p>OCSP responses are stored in the SSL stapling cache.  While the responses
    are typically a few hundred to a few thousand bytes in size, mod_ssl 
    supports OCSP responses up to around 10K bytes in size.  With more than a 
    few certificates, the stapling cache size (32768 bytes in the example above) 
    may need to be increased.  Error message AH01929 will be logged in case of
    an error storing a response.</p>
    
    
    <h3>If the certificate does not point to an OCSP responder, or if a
    different address must be used</h3>
    
    <p>Refer to the 
    <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingforceurl">SSLStaplingForceURL</a></code> directive.</p>
    
    <p>You can confirm that a server certificate points to an OCSP responder
    using the openssl command-line program, as follows:</p>
    
    <pre>$ openssl x509 -in ./www.example.com.crt -text | grep 'OCSP.*http'
    OCSP - URI:http://ocsp.example.com</pre>
    
    <p>If the OCSP URI is provided and the web server can communicate to it
    directly without using a proxy, no configuration is required.  Note that
    firewall rules that control outbound connections from the web server may
    need to be adjusted.</p>
    
    <p>If no OCSP URI is provided, contact your Certificate Authority to
    determine if one is available; if so, configure it with
    <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingforceurl">SSLStaplingForceURL</a></code> in the virtual
    host that uses the certificate.</p>
    
    
    <h3>If multiple SSL-enabled virtual hosts are configured and OCSP
    Stapling should be disabled for some</h3>
    
    
    <p>Add <code>SSLUseStapling Off</code> to the virtual hosts for which OCSP
    Stapling should be disabled.</p>
    
    
    <h3>If the OCSP responder is slow or unreliable</h3>
    
    <p>Several directives are available to handle timeouts and errors.  Refer
    to the documentation for the
    <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingfaketrylater">SSLStaplingFakeTryLater</a></code>,
    <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingrespondertimeout">SSLStaplingResponderTimeout</a></code>, and
    <code class="directive"><a href="../mod/mod_ssl.html#sslstaplingreturnrespondererrors">SSLStaplingReturnResponderErrors</a></code>
    directives.</p>
    
    
    <h3>If mod_ssl logs error AH02217</h3>
    
    <pre>AH02217: ssl_stapling_init_cert: Can't retrieve issuer certificate!</pre>
    <p>In order to support OCSP Stapling when a particular server certificate is
    used, the certificate chain for that certificate must be configured.  If it 
    was not configured as part of enabling SSL, the AH02217 error will be issued
    when stapling is enabled, and an OCSP response will not be provided for clients
    using the certificate.</p>
    
    <p>Refer to the <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatechainfile">SSLCertificateChainFile</a></code>
    and <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatefile">SSLCertificateFile</a></code> for instructions
    for configuring the certificate chain.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="accesscontrol" id="accesscontrol">Client Authentication and Access Control</a></h2>
    
    <ul>
    <li><a href="#allclients">How can I force clients to authenticate using certificates?</a></li>
    <li><a href="#arbitraryclients">How can I force clients to authenticate using certificates for a
            particular URL, but still allow arbitrary clients to access the rest of the server?</a></li>
    <li><a href="#certauthenticate">How can I allow only clients who have certificates to access a
            particular URL, but allow all clients to access the rest of the server?</a></li>
    <li><a href="#intranet">How can I require HTTPS with strong ciphers, and either
    basic authentication or client certificates, for access to part of the
    Intranet website, for clients coming from the Internet?</a></li>
    </ul>
    
    <h3><a name="allclients" id="allclients">How can I force clients to authenticate using certificates?</a></h3>
    
    
        <p>When you know all of your users (eg, as is often the case on a corporate
        Intranet), you can require plain certificate authentication. All you
        need to do is to create client certificates signed by your own CA
        certificate (<code>ca.crt</code>) and then verify the clients against this
        certificate.</p>
        <pre class="prettyprint lang-config"># 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"</pre>
    
    
    
    <h3><a name="arbitraryclients" id="arbitraryclients">How can I force clients to authenticate using certificates for a
      particular URL, but still allow arbitrary clients to access the rest of the server?</a></h3>
    
    
        <p>To force clients to authenticate using certificates for a particular URL,
        you can use the per-directory reconfiguration features of
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>:</p>
    
        <pre class="prettyprint lang-config">SSLVerifyClient none
    SSLCACertificateFile "conf/ssl.crt/ca.crt"
    
    &lt;Location "/secure/area"&gt;
    SSLVerifyClient require
    SSLVerifyDepth 1
    &lt;/Location&gt;</pre>
    
    
    
    <h3><a name="certauthenticate" id="certauthenticate">How can I allow only clients who have certificates to access a
      particular URL, but allow all clients to access the rest of the server?</a></h3>
    
    
        <p>The key to doing this is checking that part of the client certificate
        matches what you expect. Usually this means checking all or part of the
        Distinguished Name (DN), to see if it contains some known string.
        There are two ways to do this, using either <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> or
        <code class="directive"><a href="../mod/mod_ssl.html#sslrequire">SSLRequire</a></code>.</p>
    
        <p>The <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> method is generally required when
        the certificates are completely arbitrary, or when their DNs have
        no common fields (usually the organisation, etc.). In this case,
        you should establish a password database containing <em>all</em>
        clients allowed, as follows:</p>
    
        <pre class="prettyprint lang-config">SSLVerifyClient      none
    SSLCACertificateFile "conf/ssl.crt/ca.crt"
    SSLCACertificatePath "conf/ssl.crt"
    
    &lt;Directory "/usr/local/apache2/htdocs/secure/area"&gt;
        SSLVerifyClient      require
        SSLVerifyDepth       5
        SSLOptions           +FakeBasicAuth
        SSLRequireSSL
        AuthName             "Snake Oil Authentication"
        AuthType             Basic
        AuthBasicProvider    file
        AuthUserFile         "/usr/local/apache2/conf/httpd.passwd"
        Require              valid-user
    &lt;/Directory&gt;</pre>
    
    
        <p>The password used in this example is the DES encrypted string "password".
        See the <code class="directive"><a href="../mod/mod_ssl.html#ssloptions">SSLOptions</a></code> docs for more
        information.</p>
    
        <div class="example"><h3>httpd.passwd</h3><pre>/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</pre></div>
    
        <p>When your clients are all part of a common hierarchy, which is encoded
        into the DN, you can match them more easily using <code class="directive"><a href="../mod/mod_ssl.html#sslrequire">SSLRequire</a></code>, as follows:</p>
    
    
        <pre class="prettyprint lang-config">SSLVerifyClient      none
    SSLCACertificateFile "conf/ssl.crt/ca.crt"
    SSLCACertificatePath "conf/ssl.crt"
    
    &lt;Directory "/usr/local/apache2/htdocs/secure/area"&gt;
      SSLVerifyClient      require
      SSLVerifyDepth       5
      SSLOptions           +FakeBasicAuth
      SSLRequireSSL
      SSLRequire       %{SSL_CLIENT_S_DN_O}  eq "Snake Oil, Ltd." \
                   and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
    &lt;/Directory&gt;</pre>
    
    
    
    <h3><a name="intranet" id="intranet">How can I require HTTPS with strong ciphers, and either basic
    authentication or client certificates, for access to part of the
    Intranet website, for clients coming from the Internet? I still want to allow
    plain HTTP access for clients on the Intranet.</a></h3>
    
    
       <p>These examples presume that clients on the Intranet have IPs in the range
       192.168.1.0/24, and that the part of the Intranet website you want to allow
       internet access to is <code>/usr/local/apache2/htdocs/subarea</code>.
       This configuration should remain outside of your HTTPS virtual host, so
       that it applies to both HTTPS and HTTP.</p>
    
        <pre class="prettyprint lang-config">SSLCACertificateFile "conf/ssl.crt/company-ca.crt"
    
    &lt;Directory "/usr/local/apache2/htdocs"&gt;
        #   Outside the subarea only Intranet access is granted
        Require              ip 192.168.1.0/24
    &lt;/Directory&gt;
    
    &lt;Directory "/usr/local/apache2/htdocs/subarea"&gt;
        #   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} &gt;= 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
        Require              ip 192.168.1.0/24
        
        #   HTTP Basic Authentication
        AuthType             basic
        AuthName             "Protected Intranet Area"
        AuthBasicProvider    file
        AuthUserFile         "conf/protected.passwd"
        Require              valid-user
    &lt;/Directory&gt;</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="logging" id="logging">Logging</a></h2>
        
    
        <p><code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> can log extremely verbose debugging information
        to the error log, when its <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> is
        set to the higher trace levels. On the other hand, on a very busy server,
        level <code>info</code> may already be too much. Remember that you can
        configure the <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> per module to
        suite your needs.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_howto.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_howto.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_faq.html�����������������������������������������������������������0000664�0001751�0001751�00000000315�13710016232�020140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: ssl_faq.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: ssl_faq.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_faq.html.en��������������������������������������������������������0000664�0001751�0001751�00000141436�14737241666�020600� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>SSL/TLS Strong Encryption: FAQ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">SSL/TLS</a></div><div id="page-content"><div id="preamble"><h1>SSL/TLS Strong Encryption: FAQ</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_faq.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_faq.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <blockquote>
    <p>The wise man doesn't give the right answers,
    he poses the right questions.</p>
    <p class="cite">-- <cite>Claude Levi-Strauss</cite></p>
    
    </blockquote>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#installation">Installation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#aboutconfig">Configuration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#aboutcerts">Certificates</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#aboutssl">The SSL Protocol</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#support">mod_ssl Support</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="installation" id="installation">Installation</a></h2>
    <ul>
    <li><a href="#mutex">Why do I get permission errors related to
    SSLMutex when I start Apache?</a></li>
    <li><a href="#entropy">Why does mod_ssl stop with the error "Failed to
    generate temporary 512 bit RSA private key" when I start Apache?</a></li>
    </ul>
    
    <h3><a name="mutex" id="mutex">Why do I get permission errors related to
            SSLMutex when I start Apache?</a></h3>
        <p>Errors such as ``<code>mod_ssl: Child could not open
        SSLMutex lockfile /opt/apache/logs/ssl_mutex.18332 (System error follows)
        [...] System: Permission denied (errno: 13)</code>'' are usually
        caused by overly restrictive permissions on the <em>parent</em> directories.
        Make sure that all parent directories (here <code>/opt</code>,
        <code>/opt/apache</code> and <code>/opt/apache/logs</code>) have the x-bit
        set for, at minimum, the UID under which Apache's children are running (see
        the <code class="directive"><a href="../mod/mod_unixd.html#user">User</a></code> directive).</p>
    
    
    <h3><a name="entropy" id="entropy">Why does mod_ssl stop with the error
            "Failed to generate temporary 512 bit RSA private key" when I start
            Apache?</a></h3>
        <p>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
        <code>/dev/random</code>). 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.</p>
        <p>To prevent this error, <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> has to provide
        enough entropy to the PRNG to allow it to work correctly. This can
        be done via the <code class="directive"><a href="../mod/mod_ssl.html#sslrandomseed">SSLRandomSeed</a></code>
        directive.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="aboutconfig" id="aboutconfig">Configuration</a></h2>
    <ul>
    <li><a href="#parallel">Is it possible to provide HTTP and HTTPS from
    the same server?</a></li>
    <li><a href="#ports">Which port does HTTPS use?</a></li>
    <li><a href="#httpstest">How do I speak HTTPS manually for testing
    purposes?</a></li>
    <li><a href="#hang">Why does the connection hang when I connect to my
    SSL-aware Apache server?</a></li>
    <li><a href="#refused">Why do I get ``Connection Refused'' errors, when
    trying to access my newly installed Apache+mod_ssl server via HTTPS?</a></li>
    <li><a href="#envvars">Why are the <code>SSL_XXX</code> variables not
    available to my CGI &amp; SSI scripts?</a></li>
    <li><a href="#relative">How can I switch between HTTP and HTTPS in
    relative hyperlinks?</a></li>
    </ul>
    
    <h3><a name="parallel" id="parallel">Is it possible to provide HTTP and HTTPS
            from the same server?</a></h3>
        <p>Yes. HTTP and HTTPS use different server ports (HTTP binds to
        port 80, HTTPS to port 443), so there is no direct conflict between
        them. You can either run two separate server instances bound to
        these ports, or use Apache's elegant virtual hosting facility to
        create two virtual servers, both served by the same instance of Apache
        - one responding over HTTP to requests on port 80, and the other
        responding over HTTPS to requests on port 443.</p>
    
    
    <h3><a name="ports" id="ports">Which port does HTTPS use?</a></h3>
    <p>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. For
        example, if your server is set up to serve pages over HTTPS on port 8080,
        you can access them at <code>https://example.com:8080/</code></p>
    
    
    <h3><a name="httpstest" id="httpstest">How do I speak HTTPS manually for testing purposes?</a></h3>
     <p>While you usually just use</p>
    
        <div class="example"><p><code>$ telnet localhost 80<br />
        GET / HTTP/1.0</code></p></div>
    
        <p>for simple testing of Apache via HTTP, it's not so easy for
        HTTPS because of the SSL protocol between TCP and HTTP. With the
        help of OpenSSL's <code>s_client</code> command, however, you can
        do a similar check via HTTPS:</p>
    
        <div class="example"><p><code>$ openssl s_client -connect localhost:443 -state -debug<br />
        GET / HTTP/1.0</code></p></div>
    
        <p>Before the actual HTTP response you will receive detailed
        information about the SSL handshake. For a more general command
        line client which directly understands both HTTP and HTTPS, can
        perform GET and POST operations, can use a proxy, supports byte
        ranges, etc. you should have a look at the nifty
        <a href="http://curl.haxx.se/">cURL</a> tool. Using this, you can
        check that Apache is responding correctly to requests via HTTP and
        HTTPS as follows:</p>
    
        <div class="example"><p><code>$ curl http://localhost/<br />
        $ curl https://localhost/</code></p></div>
    
    
    <h3><a name="hang" id="hang">Why does the connection hang when I connect
        to my SSL-aware Apache server?</a></h3>
    
    <p>This can happen when you try to connect to a HTTPS server (or virtual
        server) via HTTP (eg, using <code>http://example.com/</code> instead of
        <code>https://example.com</code>). It can also happen when trying to
        connect via HTTPS to a HTTP server (eg, using
        <code>https://example.com/</code> on a server which doesn't support HTTPS,
        or which supports it on a non-standard port). Make sure that you're
        connecting to a (virtual) server that supports SSL.</p>
    
    <h3><a name="refused" id="refused">Why do I get ``Connection Refused'' messages,
        when trying to access my newly installed Apache+mod_ssl server via HTTPS?</a></h3>
    <p>
        This error can be caused by an incorrect configuration.
        Please make sure that your <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> directives match your
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        directives. If all else fails, please start afresh, using the default
        configuration provided by <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.</p>
    
    
    <h3><a name="envvars" id="envvars">Why are the <code>SSL_XXX</code> variables
        not available to my CGI &amp; SSI scripts?</a></h3>
    <p>Please make sure you have ``<code>SSLOptions +StdEnvVars</code>''
        enabled for the context of your CGI/SSI requests.</p>
    
    
    <h3><a name="relative" id="relative">How can I switch between HTTP and HTTPS in relative
        hyperlinks?</a></h3>
    
    <p>Usually, to switch between HTTP and HTTPS, you have to use
        fully-qualified hyperlinks (because you have to change the URL
        scheme).  Using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> however, you can
        manipulate relative hyperlinks, to achieve the same effect.</p>
        <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/(.*)_SSL$"   "https://%{SERVER_NAME}/$1" [R,L]
    RewriteRule   "^/(.*)_NOSSL$" "http://%{SERVER_NAME}/$1"  [R,L]</pre>
    
    
        <p>This rewrite ruleset lets you use hyperlinks of the form
        <code>&lt;a href="document.html_SSL"&gt;</code>, to switch to HTTPS
        in a relative link. (Replace SSL with NOSSL to switch to HTTP.)</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="aboutcerts" id="aboutcerts">Certificates</a></h2>
    <ul>
    <li><a href="#keyscerts">What are RSA Private Keys, CSRs and
    Certificates?</a></li>
    <li><a href="#startup">Is there a difference on startup between
    a non-SSL-aware Apache and an SSL-aware Apache?</a></li>
    <li><a href="#selfcert">How do I create a self-signed SSL
    Certificate for testing purposes?</a></li>
    <li><a href="#realcert">How do I create a real SSL Certificate?</a></li>
    <li><a href="#ownca">How do I create and use my own Certificate
    Authority (CA)?</a></li>
    <li><a href="#passphrase">How can I change the pass-phrase on my private
    key file?</a></li>
    <li><a href="#removepassphrase">How can I get rid of the pass-phrase
    dialog at Apache startup time?</a></li>
    <li><a href="#verify">How do I verify that a private key matches its
    Certificate?</a></li>
    <li><a href="#pemder">How can I convert a certificate from PEM to DER
    format?</a></li>
    <li><a href="#gid">Why do browsers complain that they cannot
    verify my server certificate?</a></li>
    </ul>
    
    <h3><a name="keyscerts" id="keyscerts">What are RSA Private Keys, CSRs and Certificates?</a></h3>
    <p>An 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.</p>
        <p>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), who will convert it into a real Certificate, by signing it.</p>
        <p>A Certificate contains your
        RSA public key, your name, the name of the CA, and is digitally signed by
        the 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.</p>
        <p>See the <a href="ssl_intro.html">Introduction</a> chapter for a general
        description of the SSL protocol.</p>
    
    
    <h3><a name="startup" id="startup">Is there a difference on startup between
        a non-SSL-aware Apache and an SSL-aware Apache?</a></h3>
    <p>Yes. In general, starting Apache with
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> built-in is just like starting Apache
        without it. However, if you have a passphrase on your SSL private
        key file, a startup dialog will pop up which asks you to enter the
        pass phrase.</p>
    
        <p>Having to manually enter the passphrase when starting the server
        can be problematic - for example, when starting the server from the
        system boot scripts. In this case, you can follow the steps
        <a href="#removepassphrase">below</a> to remove the passphrase from
        your private key. Bear in mind that doing so brings additional security
        risks - proceed with caution!</p>
    
    
    <h3><a name="selfcert" id="selfcert">How do I create a self-signed SSL
    Certificate for testing purposes?</a></h3>
        <ol>
        <li>Make sure OpenSSL is installed and in your <code>PATH</code>.<br />
        <br />
        </li>
        <li>Run the following command, to create <code>server.key</code> and
            <code>server.crt</code> files:<br />
            <code><strong>$ openssl req -new -x509 -nodes -out server.crt
                            -keyout server.key</strong></code><br />
            These can be used as follows in your <code>httpd.conf</code>
            file:
            <pre class="prettyprint lang-config">SSLCertificateFile    "/path/to/this/server.crt"
    SSLCertificateKeyFile "/path/to/this/server.key"</pre>
    
        </li>
        <li>It is important that you are aware that this
            <code>server.key</code> does <em>not</em> have any passphrase.
            To add a passphrase to the key, you should run the following
            command, and enter &amp; verify the passphrase as requested.<br />
            <p><code><strong>$ openssl rsa -des3 -in server.key -out
            server.key.new</strong></code><br />
            <code><strong>$ mv server.key.new server.key</strong></code><br /></p>
            Please backup the <code>server.key</code> file, and the passphrase
            you entered, in a secure location.
        </li>
        </ol>
    
    
    <h3><a name="realcert" id="realcert">How do I create a real SSL Certificate?</a></h3>
    <p>Here is a step-by-step description:</p>
        <ol>
        <li>Make sure OpenSSL is installed and in your <code>PATH</code>.
        <br />
        <br />
        </li>
        <li>Create a RSA private key for your Apache server
           (will be Triple-DES encrypted and PEM formatted):<br />
           <br />
           <code><strong>$ openssl genrsa -des3 -out server.key 2048</strong></code><br />
           <br />
           Please backup this <code>server.key</code> file and the
           pass-phrase you entered in a secure location.
           You can see the details of this RSA private key by using the command:<br />
    
           <br />
           <code><strong>$ openssl rsa -noout -text -in server.key</strong></code><br />
           <br />
           If necessary, you can also create a decrypted PEM version (not
           recommended) of this RSA private key with:<br />
           <br />
           <code><strong>$ openssl rsa -in server.key -out server.key.unsecure</strong></code><br />
           <br />
    
        </li>
        <li>Create a Certificate Signing Request (CSR) with the server RSA private
           key (output will be PEM formatted):<br />
           <br />
           <code><strong>$ openssl req -new -key server.key -out server.csr</strong></code><br />
           <br />
           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
           <code>https://www.foo.dom/</code>, enter "www.foo.dom" here.
           You can see the details of this CSR by using<br />
    
           <br />
           <code><strong>$ openssl req -noout -text -in server.csr</strong></code><br />
           <br />
        </li>
        <li>You now have to send this Certificate Signing Request (CSR) to
           a Certifying Authority (CA) to be signed. Once the CSR has been
           signed, you will have a real Certificate, which can be used by
           Apache. You can have a CSR signed by a commercial CA, or you can
           create your own CA to sign it.<br />
           Commercial CAs usually ask you to post the CSR into a web form,
           pay for the signing, and then send a signed Certificate, which
           you can store in a server.crt file.<br />
    
           For details on how to create your own CA, and use this to sign
           a CSR, see <a href="#ownca">below</a>.<br />
    
           Once your CSR has been signed, you can see the details of the
           Certificate as follows:<br />
           <br />
           <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br />
    
        </li>
        <li>You should now have two files: <code>server.key</code> and
        <code>server.crt</code>. These can be used as follows in your
        <code>httpd.conf</code> file:
           <pre class="prettyprint lang-config">SSLCertificateFile    "/path/to/this/server.crt"
    SSLCertificateKeyFile "/path/to/this/server.key"</pre>
    
           The <code>server.csr</code> file is no longer needed.
        </li>
    
        </ol>
    
    
    <h3><a name="ownca" id="ownca">How do I create and use my own Certificate Authority (CA)?</a></h3>
        <p>The short answer is to use the <code>CA.sh</code> or <code>CA.pl</code>
        script provided by OpenSSL. Unless you have a good reason not to,
        you should use these for preference. If you cannot, you can create a
        self-signed certificate as follows:</p>
    
        <ol>
        <li>Create a RSA private key for your server
           (will be Triple-DES encrypted and PEM formatted):<br />
           <br />
           <code><strong>$ openssl genrsa -des3 -out server.key 2048</strong></code><br />
           <br />
           Please backup this <code>server.key</code> file and the
           pass-phrase you entered in a secure location.
           You can see the details of this RSA private key by using the
           command:<br />
           <br />
           <code><strong>$ openssl rsa -noout -text -in server.key</strong></code><br />
           <br />
           If necessary, you can also create a decrypted PEM version (not
           recommended) of this RSA private key with:<br />
           <br />
           <code><strong>$ openssl rsa -in server.key -out server.key.unsecure</strong></code><br />
           <br />
        </li>
        <li>Create a self-signed certificate (X509 structure)
           with the RSA key you just created (output will be PEM formatted):<br />
           <br />
           <code><strong>$ openssl req -new -x509 -nodes -sha1 -days 365
                           -key server.key -out server.crt -extensions usr_cert</strong></code><br />
           <br />
           This signs the server CSR and results in a <code>server.crt</code> file.<br />
           You can see the details of this Certificate using:<br />
           <br />
           <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br />
           <br />
        </li>
        </ol>
    
    
    <h3><a name="passphrase" id="passphrase">How can I change the pass-phrase on my private key file?</a></h3>
    <p>You simply have to read it with the old pass-phrase and write it again,
        specifying the new pass-phrase. You can accomplish this with the following
        commands:</p>
    
    
        <p><code><strong>$ openssl rsa -des3 -in server.key -out server.key.new</strong></code><br />
        <code><strong>$ mv server.key.new server.key</strong></code><br /></p>
    
        <p>The first time you're asked for a PEM pass-phrase, you should
        enter the old pass-phrase. After that, you'll be asked again to
        enter a pass-phrase - this time, use the new pass-phrase. If you
        are asked to verify the pass-phrase, you'll need to enter the new
        pass-phrase a second time.</p>
    
    
    <h3><a name="removepassphrase" id="removepassphrase">How can I get rid of the pass-phrase dialog at Apache startup time?</a></h3>
    <p>The reason 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 decrypt
        this file, so it can be read and parsed. Removing the pass-phrase
        removes a layer of security from your server - proceed with caution!</p>
        <ol>
        <li>Remove the encryption from the RSA private key (while
           keeping a backup copy of the original file):<br />
           <br />
           <code><strong>$ cp server.key server.key.org</strong></code><br />
           <code><strong>$ openssl rsa -in server.key.org -out server.key</strong></code><br />
    
           <br />
        </li>
        <li>Make sure the server.key file is only readable by root:<br />
           <br />
           <code><strong>$ chmod 400 server.key</strong></code><br />
           <br />
        </li>
        </ol>
    
        <p>Now <code>server.key</code> contains 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 this
        file are 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
        user, and have the key readable only by root).</p>
    
        <p>As an alternative approach you can use the ``<code>SSLPassPhraseDialog
        exec:/path/to/program</code>'' facility. Bear in mind that this is
        neither more nor less secure, of course.</p>
    
    
    <h3><a name="verify" id="verify">How do I verify that a private key matches its Certificate?</a></h3>
    <p>A private key contains a series of numbers. Two of these numbers form
        the "public key", the others are part of the "private key". The "public
        key" bits are included when you generate a CSR, and subsequently form
        part of the associated Certificate.</p>
        <p>To check that the public key in your Certificate matches the public
        portion of your private key, you simply need to compare these numbers.
        To view the Certificate and the key run the commands:</p>
    
        <p><code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br />
        <code><strong>$ openssl rsa -noout -text -in server.key</strong></code></p>
    
        <p>The `modulus' and the `public exponent' portions in the key and the
        Certificate must match. As the public exponent is usually 65537
        and it's difficult to visually check that the long modulus numbers
        are the same, you can use the following approach:</p>
    
        <p><code><strong>$ openssl x509 -noout -modulus -in server.crt | openssl md5</strong></code><br />
        <code><strong>$ openssl rsa -noout -modulus -in server.key | openssl md5</strong></code></p>
    
        <p>This leaves you with two rather shorter numbers to compare. It is,
        in theory, possible that these numbers may be the same, without the
        modulus numbers being the same, but the chances of this are
        overwhelmingly remote.</p>
        <p>Should you wish to check to which key or certificate a particular
        CSR belongs you can perform the same calculation on the CSR as
        follows:</p>
    
        <p><code><strong>$ openssl req -noout -modulus -in server.csr | openssl md5</strong></code></p>
    
    
    <h3><a name="pemder" id="pemder">How can I convert a certificate from PEM to DER format?</a></h3>
    <p>The default certificate format for OpenSSL is PEM, which is simply
        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 <code>cert.pem</code> into the
        corresponding DER file <code>cert.der</code> using the following command:
        <code><strong>$ openssl x509 -in cert.pem -out cert.der -outform DER</strong></code></p>
    
    
    <h3><a name="gid" id="gid">Why do browsers complain that they cannot verify my server certificate?</a></h3>
    
        <p>One reason this might happen is because your server certificate is signed
        by an intermediate CA. Various CAs, such as Verisign or Thawte, have started
        signing certificates not with their root certificate but with intermediate
        certificates.</p>
    
        <p>Intermediate CA certificates lie between the root CA certificate (which is
        installed in the browsers) and the server certificate (which you installed
        on the server). In order for the browser to be able to traverse and verify
        the trust chain from the server certificate to the root certificate it
        needs need to be given the intermediate certificates. The CAs should
        be able to provide you such intermediate certificate packages that can be
        installed on the server.</p>
    
        <p>You need to include those intermediate certificates with the
        <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatechainfile">SSLCertificateChainFile</a></code>
        directive.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="aboutssl" id="aboutssl">The SSL Protocol</a></h2>
    <ul>
    <li><a href="#random">Why do I get lots of random SSL protocol
    errors under heavy server load?</a></li>
    <li><a href="#load">Why does my webserver have a higher load, now
    that it serves SSL encrypted traffic?</a></li>
    <li><a href="#establishing">Why do HTTPS connections to my server
    sometimes take up to 30 seconds to establish a connection?</a></li>
    <li><a href="#ciphers">What SSL Ciphers are supported by mod_ssl?</a></li>
    <li><a href="#adh">Why do I get ``no shared cipher'' errors, when
    trying to use Anonymous Diffie-Hellman (ADH) ciphers?</a></li>
    <li><a href="#sharedciphers">Why do I get a 'no shared ciphers'
    error when connecting to my newly installed server?</a></li>
    <li><a href="#vhosts">Why can't I use SSL with name-based/non-IP-based
    virtual hosts?</a></li>
    <li><a href="#vhosts2">Is it possible to use Name-Based Virtual
    Hosting to identify different SSL virtual hosts?</a></li>
    <li><a href="#comp">How do I get SSL compression working?</a></li>
    <li><a href="#lockicon">When I use Basic Authentication over HTTPS
    the lock icon in Netscape browsers stays unlocked when the dialog pops up.
    Does this mean the username/password is being sent unencrypted?</a></li>
    <li><a href="#msie">Why do I get I/O errors when connecting via
    HTTPS to an Apache+mod_ssl server with Microsoft Internet Explorer
    (MSIE)?</a></li>
    <li><a href="#srp">How do I enable TLS-SRP?</a></li>
    <li><a href="#javadh">Why do I get handshake failures with Java-based clients when using a certificate with more than 1024 bits?</a></li>
    </ul>
    
    <h3><a name="random" id="random">Why do I get lots of random SSL protocol
    errors under heavy server load?</a></h3>
    <p>There can be a number of reasons for this, but the main one
        is problems with the SSL session Cache specified by the
        <code class="directive"><a href="../mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code> directive. The DBM session
        cache is the most likely source of the problem, so using the SHM session cache (or
        no cache at all) may help.</p>
    
    
    <h3><a name="load" id="load">Why does my webserver have a higher load, now
    that it serves SSL encrypted traffic?</a></h3>
    <p>SSL uses strong cryptographic encryption, which necessitates a lot of
        number crunching. When you request a webpage via HTTPS, everything (even
        the images) is encrypted before it is transferred. So increased HTTPS
        traffic leads to load increases.</p>
    
    
    <h3><a name="establishing" id="establishing">Why do HTTPS connections to my server
    sometimes take up to 30 seconds to establish a connection?</a></h3>
    <p>This is usually caused by a <code>/dev/random</code> device for
        <code class="directive"><a href="../mod/mod_ssl.html#sslrandomseed">SSLRandomSeed</a></code> which blocks the
        read(2) call until enough entropy is available to service the
        request. More information is available in the reference
        manual for the <code class="directive"><a href="../mod/mod_ssl.html#sslrandomseed">SSLRandomSeed</a></code>
        directive.</p>
    
    
    <h3><a name="ciphers" id="ciphers">What SSL Ciphers are supported by mod_ssl?</a></h3>
    <p>Usually, any SSL ciphers supported by the version of OpenSSL in use,
        are also supported by <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>. Which ciphers are
        available can depend on the way you built OpenSSL. Typically, at
        least the following ciphers are supported:</p>
    
        <ol>
        <li>RC4 with SHA1</li>
        <li>AES with SHA1</li>
        <li>Triple-DES with SHA1</li>
        </ol>
    
        <p>To determine the actual list of ciphers available, you should run
        the following:</p>
        <div class="example"><p><code>$ openssl ciphers -v</code></p></div>
    
    
    <h3><a name="adh" id="adh">Why do I get ``no shared cipher'' errors, when
    trying to use Anonymous Diffie-Hellman (ADH) ciphers?</a></h3>
    <p>By default, OpenSSL does <em>not</em> allow ADH ciphers, for security
        reasons. Please be sure you are aware of the potential side-effects
        if you choose to enable these ciphers.</p>
        <p>In order to use Anonymous Diffie-Hellman (ADH) ciphers, you must
        build OpenSSL with ``<code>-DSSL_ALLOW_ADH</code>'', and then add
        ``<code>ADH</code>'' into your <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code>.</p>
    
    
    <h3><a name="sharedciphers" id="sharedciphers">Why do I get a 'no shared ciphers'
    error when connecting to my newly installed server?</a></h3>
    <p>Either you have made a mistake with your
        <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code>
        directive (compare it with the pre-configured example in
        <code>extra/httpd-ssl.conf</code>) or you chose to use 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 cannot communicate using RSA-based SSL
        ciphers (at least until you configure an additional RSA-based
        certificate/key pair). Modern browsers like NS or IE can only
        communicate over SSL using RSA ciphers. The result is the
        "no shared ciphers" error. To fix this, regenerate your server
        certificate/key pair, using the RSA algorithm.</p>
    
    
    <h3><a name="vhosts" id="vhosts">Why can't I use SSL with name-based/non-IP-based virtual hosts?</a></h3>
    <p>The reason is very technical, and a somewhat "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 go to the correct virtual server
        Apache has to know the <code>Host</code> HTTP header field. To do this, the
        HTTP request header has to be read. This cannot be done before the SSL
        handshake is finished, but the information is needed in order to
        complete the SSL handshake phase. See the next question for how to
        circumvent this issue.</p>
        
        <p>Note that if you have a wildcard SSL certificate, or a
        certificate that has multiple hostnames on it using subjectAltName
        fields, you can use SSL on name-based virtual hosts without further
        workarounds.</p>
    
    
    <h3><a name="vhosts2" id="vhosts2">Is it possible to use Name-Based
    Virtual Hosting to identify different SSL virtual hosts?</a></h3>
        <p>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.</p>
    
        <p>It is possible, but only if using a 2.2.12 or later web server,
        built with 0.9.8j or later OpenSSL.  This is because it requires a
        feature that only the most recent revisions of the SSL
        specification added, called Server Name Indication (SNI).</p>
    
        <p>Note that if you have a wildcard SSL certificate, or a
        certificate that has multiple hostnames on it using subjectAltName
        fields, you can use SSL on name-based virtual hosts without further
        workarounds.</p>
    
        <p>The reason is that the SSL protocol is a separate layer which
        encapsulates the HTTP protocol. So the SSL session is a separate
        transaction, that takes place before the HTTP session has begun.
        The server receives an SSL request on IP address X and port Y
        (usually 443). Since the SSL request did not contain any Host:
        field, the server had no way to decide which SSL virtual host to use.
        Usually, it just used the first one it found which matched the
        port and IP address specified.</p>
    
        <p>If you are using a version of the web server and OpenSSL that
        support SNI, though, and the client's browser also supports SNI,
        then the hostname is included in the original SSL request, and the
        web server can select the correct SSL virtual host.</p>
    
        <p>You can, of course, use Name-Based Virtual Hosting to identify many
        non-SSL virtual hosts (all on port 80, for example) and then
        have a single 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.</p>
    
        <pre class="prettyprint lang-config">NameVirtualHost 192.168.1.1:80</pre>
    
    
        <p>Other workaround solutions include: </p>
    
        <p>Using separate IP addresses for different SSL hosts.
        Using different port numbers for different SSL hosts.</p>
    
    
    <h3><a name="comp" id="comp">How do I get SSL compression working?</a></h3>
    <p>Although SSL compression negotiation was defined in the specification
    of SSLv2 and TLS, it took until May 2004 for RFC 3749 to define DEFLATE as
    a negotiable standard compression method.
    </p>
    <p>OpenSSL 0.9.8 started to support this by default when compiled with the
    <code>zlib</code> option. If both the client and the server support compression,
    it will be used. However, most clients still try to initially connect with an
    SSLv2 Hello. As SSLv2 did not include an array of preferred compression algorithms
    in its handshake, compression cannot be negotiated with these clients.
    If the client disables support for SSLv2, either an SSLv3 or TLS Hello
    may be sent, depending on which SSL library is used, and compression may
    be set up. You can verify whether clients make use of SSL compression by
    logging the <code>%{SSL_COMPRESS_METHOD}x</code> variable.
    </p>
    
    
    <h3><a name="lockicon" id="lockicon">When I use Basic Authentication over HTTPS
    the lock icon in Netscape browsers stays unlocked when the dialog pops up.
    Does this mean the username/password is being sent unencrypted?</a></h3>
    <p>No, the username/password is transmitted encrypted. The icon in
        Netscape browsers is not actually synchronized with the SSL/TLS layer.
        It only toggles to the locked state when the first part of the actual
        webpage data is transferred, which may confuse people. The Basic
        Authentication facility is part of the HTTP layer, which is above
        the SSL/TLS layer in HTTPS. Before any HTTP data communication takes
        place in HTTPS, the SSL/TLS layer has already completed its handshake
        phase, and switched to encrypted communication. So don't be
        confused by this icon.</p>
    
    
    <h3><a name="msie" id="msie">Why do I get I/O errors when connecting via
    HTTPS to an Apache+mod_ssl server with older versions of Microsoft Internet
    Explorer (MSIE)?</a></h3>
    <p>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 in some MSIE versions.
        You can work around these problems by forcing Apache not to use HTTP/1.1,
        keep-alive connections or send the SSL close notify messages to MSIE clients.
        This can be done by using the following directive in your SSL-aware
        virtual host section:</p>
        <pre class="prettyprint lang-config">SetEnvIf User-Agent "MSIE [2-5]" \
             nokeepalive ssl-unclean-shutdown \
             downgrade-1.0 force-response-1.0</pre>
    
        <p>Further, some MSIE versions have problems with particular ciphers.
        Unfortunately, it is not possible to implement a MSIE-specific
        workaround for this, because the ciphers are needed as early as the
        SSL handshake phase. So a MSIE-specific
        <code class="directive"><a href="../mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> won't solve these
        problems. Instead, you will have to make more drastic
        adjustments to the global parameters. Before you decide to do
        this, make sure your clients really have problems. If not, do not
        make these changes - they will affect <em>all</em> your clients, MSIE
        or otherwise.</p>
    
    
    <h3><a name="srp" id="srp">How do I enable TLS-SRP?</a></h3>
        <p>TLS-SRP (Secure Remote Password key exchange for TLS, specified in RFC 5054)
        can supplement or replace certificates in authenticating an SSL connection.
        To use TLS-SRP, set the
        <code class="directive"><a href="../mod/mod_ssl.html#sslsrpverifierfile">SSLSRPVerifierFile</a></code> directive to
        point to an OpenSSL SRP verifier file. To create the verifier file, use the
        <code>openssl</code> tool:</p>
        <div class="example"><p><code>
        openssl srp -srpvfile passwd.srpv -add username
        </code></p></div>
        <p>After creating this file, specify it in the SSL server configuration:</p>
        <div class="example"><p><code>
        SSLSRPVerifierFile /path/to/passwd.srpv
        </code></p></div>
        <p>To force clients to use non-certificate TLS-SRP cipher suites, use the
        following directive:</p>
        <div class="example"><p><code>
        SSLCipherSuite "!DSS:!aRSA:SRP"
        </code></p></div>
    
    
    <h3><a name="javadh" id="javadh">Why do I get handshake failures with Java-based clients when using a certificate with more than 1024 bits?</a></h3>
        <p>Beginning with version 2.4.7,
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> will use DH parameters which include primes
        with lengths of more than 1024 bits. Java 7 and earlier limit their
        support for DH prime sizes to a maximum of 1024 bits, however.</p>
    
        <p>If your Java-based client aborts with exceptions such as
        <code>java.lang.RuntimeException: Could not generate DH keypair</code> and
        <code>java.security.InvalidAlgorithmParameterException: Prime size must be
        multiple of 64, and can only range from 512 to 1024 (inclusive)</code>,
        and httpd logs <code>tlsv1 alert internal error (SSL alert number 80)</code>
        (at <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> <code>info</code>
        or higher), you can either rearrange mod_ssl's cipher list with
        <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code>
        (possibly in conjunction with <code class="directive"><a href="../mod/mod_ssl.html#sslhonorcipherorder">SSLHonorCipherOrder</a></code>),
        or you can use custom DH parameters with a 1024-bit prime, which
        will always have precedence over any of the built-in DH parameters.</p>
    
        <p>To generate custom DH parameters, use the <code>openssl dhparam 1024</code>
        command. Alternatively, you can use the following standard 1024-bit DH
        parameters from <a href="http://www.ietf.org/rfc/rfc2409.txt">RFC 2409</a>,
        section 6.2:</p>
        <div class="example"><pre>-----BEGIN DH PARAMETERS-----
    MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
    Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
    /1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
    -----END DH PARAMETERS-----</pre></div>
        <p>Add the custom parameters including the "BEGIN DH PARAMETERS" and
        "END DH PARAMETERS" lines to the end of the first certificate file
        you have configured using the
        <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatefile">SSLCertificateFile</a></code> directive.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">mod_ssl Support</a></h2>
    <ul>
    <li><a href="#resources">What information resources are available in
    case of mod_ssl problems?</a></li>
    <li><a href="#contact">What support contacts are available in case of
    mod_ssl problems?</a></li>
    <li><a href="#reportdetails">What information should I
    provide when writing a bug report?</a></li>
    <li><a href="#coredumphelp">I had a core dump, can you help me?</a></li>
    <li><a href="#backtrace">How do I get a backtrace, to help find the reason
    for my core dump?</a></li>
    </ul>
    
    <h3><a name="resources" id="resources">What information resources are available in case of mod_ssl problems?</a></h3>
    <p>The following information resources are available.
        In case of problems you should search here first.</p>
    
        <dl>
        <dt>Answers in the User Manual's F.A.Q. List (this)</dt>
        <dd><a href="http://httpd.apache.org/docs/2.4/ssl/ssl_faq.html">
            http://httpd.apache.org/docs/2.4/ssl/ssl_faq.html</a><br />
            First check the F.A.Q. (this text). If your problem is a common
            one, it may have been answered several times before, and been included
            in this doc.
        </dd>
        </dl>
    
    
    <h3><a name="contact" id="contact">What support contacts are available in case
    of mod_ssl problems?</a></h3>
     <p>The following lists all support possibilities for mod_ssl, in order of
             preference. Please go through these possibilities
             <em>in this order</em> - don't just pick the one you like the look of. </p>
        <ol>
    
        <li><em>Send a Problem Report to the Apache httpd Users Support Mailing List</em><br />
            <a href="mailto:users@httpd.apache.org">
            users@httpd.apache.org</a><br />
            This is the second way of submitting your problem report. Again, you must
            subscribe to the list first, but you can then easily discuss your problem
            with the whole Apache httpd user community.
        </li>
    
        <li><em>Write a Problem Report in the Bug Database</em><br />
            <a href="http://httpd.apache.org/bug_report.html">
            http://httpd.apache.org/bug_report.html</a><br />
            This is the last way of submitting your problem report. You should only
            do this if you've already posted to the mailing lists, and had no success.
            Please follow the instructions on the above page <em>carefully</em>.
        </li>
        </ol>
    
    
    <h3><a name="reportdetails" id="reportdetails">What information should I
    provide when writing a bug report?</a></h3>
    <p>You should always provide at least the following information:</p>
    
        <dl>
        <dt>Apache httpd and OpenSSL version information</dt>
        <dd>The Apache version can be determined
            by running <code>httpd -v</code>. The OpenSSL version can be
            determined by running <code>openssl version</code>. Alternatively, if
            you have Lynx installed, you can run the command <code>lynx -mime_header
            http://localhost/ | grep Server</code> to gather this information in a
            single step.
        </dd>
    
        <dt>The details on how you built and installed Apache httpd and OpenSSL</dt>
        <dd>For this you can provide a logfile of your terminal session which shows
        the configuration and install steps. If this is not possible, you
        should at least provide the <code class="program"><a href="../programs/configure.html">configure</a></code> command line you used.
        </dd>
    
        <dt>In case of core dumps please include a Backtrace</dt>
        <dd>If your Apache httpd dumps its core, please attach
        a stack-frame ``backtrace'' (see <a href="#backtrace">below</a>
        for information on how to get this). This information is required
        in order to find a reason for your core dump.
        </dd>
    
        <dt>A detailed description of your problem</dt>
        <dd>Don't laugh, we really mean it! Many problem reports don't
        include a description of what the actual problem is. Without this,
        it's very difficult for anyone to help you. So, it's in your own
        interest (you want the problem be solved, don't you?) to include as
        much detail as possible, please. Of course, you should still include
        all the essentials above too.
        </dd>
        </dl>
    
    
    <h3><a name="coredumphelp" id="coredumphelp">I had a core dump, can you help me?</a></h3>
    <p>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.</p>
    
    
    <h3><a name="backtrace" id="backtrace">How do I get a backtrace, to help find
    the reason for my core dump?</a></h3>
    <p>Following are the steps you will need to complete, to get a backtrace:</p>
        <ol>
        <li>Make sure you have debugging symbols available, at least
            in Apache. On platforms where you use GCC/GDB, you will have to build
            Apache+mod_ssl with ``<code>OPTIM="-g -ggdb3"</code>'' to get this. On
            other platforms at least ``<code>OPTIM="-g"</code>'' is needed.
        </li>
    
        <li>Start the server and try to reproduce the core-dump. For this you may
            want to use a directive like ``<code>CoreDumpDirectory /tmp</code>'' to
            make sure that the core-dump file can be written. This should result
            in a <code>/tmp/core</code> or <code>/tmp/httpd.core</code> file. If you
            don't get one of these, try running your server under a non-root UID.
            Many modern kernels do not allow a process to dump core after it has
            done a <code>setuid()</code> (unless it does an <code>exec()</code>) for
            security reasons (there can be privileged information left over in
            memory). If necessary, you can run <code>/path/to/httpd -X</code>
            manually to force Apache to not fork.
        </li>
    
        <li>Analyze the core-dump. For this, run <code>gdb /path/to/httpd
            /tmp/httpd.core</code> or a similar command. In GDB, all you
            have to do then is to enter <code>bt</code>, and voila, you get the
            backtrace. For other debuggers consult your local debugger manual.
        </li>
        </ol>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/ssl/ssl_faq.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/ssl/ssl_faq.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/ssl/ssl_faq.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_compat.html��������������������������������������������������������0000664�0001751�0001751�00000000323�13710016232�020653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: ssl_compat.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: ssl_compat.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/ssl/ssl_intro.html���������������������������������������������������������0000664�0001751�0001751�00000000452�13710016232�020526� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: ssl_intro.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: ssl_intro.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: ssl_intro.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/stopping.html.de�����������������������������������������������������������0000664�0001751�0001751�00000047032�14744525602�020166� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Beenden und Neustarten - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Beenden und Neustarten</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/stopping.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
        <p>Dieses Dokument umfasst das Beenden und Neustarten des
        Apache auf Unix-&#228;hnlichen Systemen. Anwender von Windows NT, 2000
        und XP sollten <a href="platform/windows.html#winsvc">Betreiben
        des Apache als Dienst</a> lesen, w&#228;hrend hingegen Anwender von
        Windows 9x sowie ME <a href="platform/windows.html#wincons">Betreiben
        des Apache als Konsolenanwendung</a> lesen sollten, um mehr Informationen
        zur Handhabung des Apache auf diesen Systemen zu erhalten.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Einleitung</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#term">Beenden</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#graceful">Unterbrechungsfreier Neustart</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#hup">Neustarten</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#race">Anhang: Signale und Wettkampfsituationen</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Einleitung</a></h2>
    
        <p>Um den Apache zu stoppen oder neu zu starten, m&#252;ssen Sie
        ein Signal an den laufenden <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Prozess senden. Es gibt
        zwei M&#246;glichkeiten, diese Signale zu senden. Zum einen k&#246;nnen
        Sie den Unix-Befehl <code>kill</code> verwenden, um den Prozessen
        direkt Signale zu senden. Sie werden feststellen, dass auf Ihrem
        System mehrere <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Programme laufen. Sie sollten
        jedoch nicht jedem dieser Prozesse ein Signal senden, sondern nur dem
        Elternprozess, dessen PID im <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> steht. Das hei&#223;t, Sie
        sollten es niemals n&#246;tig haben, einem anderen Prozess, als dem
        Elternprozess, ein Signal zu senden. Es gibt drei Signale, die Sie an den
        Elternprozess senden k&#246;nnen: <code><a href="#term">TERM</a></code>,
        <code><a href="#hup">HUP</a></code> und
        <code><a href="#graceful">USR1</a></code>, die nachfolgend beschrieben
        werden.</p>
    
        <p>Um dem Elternprozess ein Signal zu senden, verwenden Sie einen
        Befehl wie z.B.:</p>
    
        <div class="example"><p><code>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</code></p></div>
    
        <p>Die zweite Methode, dem <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Prozess zu
        signalisieren, ist die Verwendung der <code>-k</code>-Befehlszeilenoptionen
        <code>stop</code>, <code>restart</code> und <code>graceful</code>, wie
        unten beschrieben. Dies sind Argumente des <code class="program"><a href="./programs/httpd.html">httpd</a></code>-Programms, es wird jedoch
        empfohlen, sie unter Verwendung des Steuerskripts <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> zu senden, welches diese
        an <code class="program"><a href="./programs/httpd.html">httpd</a></code> durchreicht.</p>
    
        <p>Nachdem Sie <code class="program"><a href="./programs/httpd.html">httpd</a></code> signalisiert haben, k&#246;nnen Sie
        dessen Fortschritt beobachten, indem Sie eingeben:</p>
    
        <div class="example"><p><code>tail -f /usr/local/apache2/logs/error_log</code></p></div>
    
        <p>Passen Sie diese Beispiele entsprechend Ihren <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code>- und <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>-Einstellungen an.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="term" id="term">Beenden</a></h2>
    
        <dl><dt>Signal: TERM</dt>
          <dd><code>apachectl -k stop</code></dd>
        </dl>
    
        <p>Das Senden des <code>TERM</code>- oder <code>stop</code>-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.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="graceful" id="graceful">Unterbrechungsfreier Neustart</a></h2>
    
        <dl><dt>Signal: USR1</dt>
          <dd><code>apachectl -k graceful</code></dd>
        </dl>
    
        <p>Das <code>USR1</code>- oder <code>graceful</code>-Signal
        veranlasst den Elternprozess, die Kinder <em>anzuweisen</em>, sich
        nach Abschlu&#223; 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
        &#246;ffnet seine Logdateien neu. Wenn ein Kindprozess stirbt,
        ersetzt der Elternprozess ihn durch ein Kind der neuen
        Konfigurations-<em>Generation</em>. Dieses beginnt sofort damit,
        neue Anfragen zu bedienen.</p>
    
        <div class="note">Auf bestimmten Plattformen, welche kein <code>USR1</code>
        f&#252;r einen unterbrechungsfreien Neustart erlauben, kann ein
        alternatives Signal verwendet werden (wie z.B.
        <code>WINCH</code>). Der Befehl <code>apachectl graceful</code>
        sendet das jeweils richtige Signal f&#252;r Ihre Platform.</div>
    
        <p>Der Code ist daf&#252;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&#228;hrend
        des Neustarts auf die entsprechenden Werte gesetzt werden.
        Weiterhin wird <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code>
        auf folgende Art und Weise interpretiert: Wenn nach einer Sekunde
        nicht mindestens <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code>
        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&#252;nsche hinsichtlich des Parameters
        <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> zu
        ber&#252;cksichtigen.</p>
    
        <p>Benutzer von <code class="module"><a href="./mod/mod_status.html">mod_status</a></code> werden feststellen,
        dass die Serverstatistiken <strong>nicht</strong> auf Null
        zur&#252;ckgesetzt werden, wenn ein <code>USR1</code> 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&#252;cksichtigt werden.
        Um dies zu erreichen, muss die <em>Statustabelle</em> (Scoreboard),
        die dazu verwendet wird, alle Kinder &#252;ber mehrere Generationen
        zu verfolgen, erhalten bleiben.</p>
    
        <p>Das Statusmodul benutzt au&#223;erdem ein <code>G</code>, um
        diejenigen Kinder zu kennzeichen, die noch immer Anfragen bedienen,
        welche gestartet wurden, bevor ein unterbrechungsfreier Neustart
        veranla&#223;t wurde.</p>
    
        <p>Derzeit gibt es keine M&#246;glichkeit f&#252;r ein
        Log-Rotationsskript, das <code>USR1</code> verwendet, sicher
        festzustellen, dass alle Kinder, die in ein vor dem Neustart
        ge&#246;ffnetes Log schreiben, beendet sind. Wir schlagen vor, dass
        Sie nach dem Senden des Signals <code>USR1</code> 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&#252;r eine vollst&#228;ndige Antwort
        ben&#246;tigen, dann k&#246;nnten Sie 15 Minuten warten, bevor Sie auf
        das alte Log zugreifen.</p>
    
        <div class="note">Wenn Ihre Konfigurationsdatei Fehler enth&#228;lt, w&#228;hrend
        Sie einen Neustart anweisen, dann wird Ihr Elternprozess nicht neu starten,
        sondern sich mit einem Fehler beenden. Im Falle eines unterbrechungsfreien
        Neustarts l&#228;&#223;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&#252;hren, k&#246;nnen Sie die Syntax der Konfigurationsdateien
        mit dem Befehlszeilenargument <code>-t</code> &#252;berpr&#252;fen
        (siehe auch <code class="program"><a href="./programs/httpd.html">httpd</a></code>). Das garantiert
        allerdings nicht, dass der Server korrekt starten wird. Um sowohl die
        Syntax als auch die Semantik der Konfigurationsdateien zu pr&#252;fen,
        k&#246;nnen Sie versuchen, <code class="program"><a href="./programs/httpd.html">httpd</a></code> als nicht-root-Benutzer
        zu starten. Wenn dabei keine Fehler auftreten, wird er versuchen, seine
        Sockets und Logdateien zu &#246;ffnen und fehlschlagen, da er nicht root
        ist (oder weil sich der gegenw&#228;rtig laufende <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        bereits diese Ports gebunden hat). Wenn er aus einem anderen Grund
        fehlschl&#228;gt, dann liegt wahrscheinlich ein Konfigurationsfehler vor.
        Der Fehler sollte behoben werden, bevor der unterbrechungsfreie Neustart
        angewiesen wird.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hup" id="hup">Neustarten</a></h2>
    
        <dl><dt>Signal: HUP</dt>
          <dd><code>apachectl -k restart</code></dd>
        </dl>
    
        <p>Das Senden des Signals <code>HUP</code> oder <code>restart</code>
        veranla&#223;t den Elternprozess, wie bei <code>TERM</code> alle seine
        Kinder zu beenden. Der Elternprozess beendet sich jedoch nicht. Er liest
        seine Konfigurationsdateien neu ein und &#246;ffnet alle Logdateien
        erneut. Dann erzeugt er einen neuen Satz Kindprozesse und setzt die
        Bedienung von Zugriffen fort.</p>
    
        <p>Benutzer von <code class="module"><a href="./mod/mod_status.html">mod_status</a></code> werden feststellen, dass
        die Serverstatistiken auf Null gesetzt werden, wenn ein <code>HUP</code>
        gesendet wurde.</p>
    
        <div class="note">Wenn Ihre Konfigurationsdatei einen Fehler enth&#228;lt,
        w&#228;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&#246;nnen.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="race" id="race">Anhang: Signale und Wettkampfsituationen</a></h2>
    
        <p>Vor der Version 1.2b9 des Apache existierten verschiedene
        <em>Wettkampfsituationen</em> (race conditions), die den Neustart und
        die Signale beeinflu&#223;t haben. (Einfach erkl&#228;rt ist eine
        Wettkampfsituation ein zeitabh&#228;ngiges Problem - wenn
        etwas zum falschen Zeitpunkt erfolgt oder Dinge in der falschen
        Reihenfolge passieren, ist unerwartetes Verhalten die Folge. Wenn die
        gleichen Dinge zur richtigen Zeit geschehen, funktioniert alles korrekt.)
        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.</p>
    
        <p>Bei Architekturen, die ein <code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code> auf Platte verwenden,
        besteht die Gefahr, dass die Statustabelle besch&#228;digt wird.
        Das kann zu "bind: Address already in use" ("bind: Adresse wird
        bereits verwendet", nach einem <code>HUP</code>) oder "long lost
        child came home!" ("Der verlorene Sohn ist heimgekehrt", nach einem
        <code>USR1</code>) f&#252;hren. Ersteres ist ein schwerer Fehler,
        w&#228;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&#252;cklicherweise ben&#246;tigen die meisten Architekturen keine
        Statustabelle in Form einer Datei. Bitte lesen Sie f&#252;r Architekturen,
        die sie ben&#246;tigen, die Dokumentation zu <code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code>.</p>
    
        <p>Alle Architekturen haben in jedem Kindprozess eine kleine
        Wettkampfsituation, welche die zweite und nachfolgende Anfragen
        einer persistenten HTTP-Verbindung (KeepAlive) umfa&#223;t. Der Prozess
        kann nach dem Lesen der Anfragezeile aber vor dem Lesen der Anfrage-Header
        enden. Es existiert eine Korrektur, die f&#252;r 1.2 zu sp&#228;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&#223;t zu werden
        -- in einem Testfall wurde der Server zwanzig mal
        pro Sekunde neu gestartet, w&#228;hrend Clients das Angebot abgegrast
        haben, ohne kaputte Bilder oder leere Dokumente zu erhalten.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/stopping.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/stopping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html.de���������������������������������������������������0000664�0001751�0001751�00000043255�14744525602�021455� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>&#220;bersicht der neuen Funktionen im Apache HTTP Server 2.0 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>&#220;bersicht der neuen Funktionen im Apache HTTP Server 2.0</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/new_features_2_0.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>Dieses Dokument beschreibt einige der wichtigsten &#196;nderungen
         des Apache HTTP Servers 2.0 gegen&#252;ber der Version 1.3.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Core-Erweiterungen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Modul-Erweiterungen</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><a href="upgrading.html">Upgrade von 1.3 auf 2.0</a></li><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Core-Erweiterungen</a></h2>
        
    
        <dl>
          <dt><strong>Unix-Threading</strong></dt>
    
          <dd>Auf Unix-Systemen mit Unterst&#252;tzung f&#252;r
          POSIX-Threads, kann der Apache httpd jetzt in einem Multi-Process,
          Multi-Threaded Hybrid-Mode gestartet werden. Dies verbessert die
          Skalierf&#228;higkeit f&#252;r viele, jedoch nicht unbedingt alle
          Konfigurationen.</dd>
    
          <dt><strong>Neues Build-System</strong></dt>
    
          <dd>Das Build-System wurde komplett auf der Basis von
          <code>autoconf</code> und <code>libtool</code> neu geschrieben.
          Dadurch wird das Konfigurationssystem des Apache httpd dem vieler
          anderer Packages &#228;hnlicher.</dd>
    
          <dt><strong>Multi-Protokoll-Unterst&#252;tzung</strong></dt>
    
          <dd>Der Apache HTTP Server stellt jetzt die notwendigen
          Grundfunktionalit&#228;ten bereit, um mehrere Protokolle
          unterst&#252;tzen und verarbeiten zu k&#246;nnen.
          <code class="module"><a href="./mod/mod_echo.html">mod_echo</a></code> wurde hierf&#252;r als Beispiel
          geschrieben.</dd>
    
          <dt><strong>Bessere Unterst&#252;tzung von
          Nicht-Unix-Plattformen</strong></dt>
    
          <dd>Der Apache HTTP Server 2.0 ist schneller und stabiler auf
          Nicht-Unix-Plattformen wie BeOS, OS/2 und Windows. Mit der
          Einf&#252;hrung von Plattform-spezifischen <a href="mpm.html">Multi-Processing Modulen</a> (MPMs) und der Apache
          Portable Runtime (APR), sind diese Plattformen jetzt in ihrem
          nativen API implementiert, wodurch die Verwendung der h&#228;ufig
          fehlerbehafteten und schlecht funktionierenden
          POSIX-Emulation-Layer vermieden wird.</dd>
    
          <dt><strong>Neues Apache-httpd API</strong></dt>
    
          <dd>Das API f&#252;r Module hat sich in 2.0 stark ver&#228;ndert.
          Die meisten der Sortierungs-/Priorit&#228;tsprobleme von Modulen bei
          1.3 sollten nun verschwunden sein. In 2.0 wird hiervon vieles
          automatisch durchgef&#252;hrt. Die Modulsortierung wird jetzt
          &#252;ber einen pre-hook vorgenommen, um mehr Flexibilit&#228;t
          zu bieten. Au&#223;erdem wurden neue API-Calls hinzugef&#252;gt,
          die zus&#228;tzliche Modulf&#228;higkeiten zur Verf&#252;gung stellen,
          ohne den Kern des Apache HTTP Servers anpassen zu m&#252;ssen.</dd>
    
          <dt><strong>IPv6-Unterst&#252;tzung</strong></dt>
    
          <dd>Auf Systemen, bei denen die zugrundeliegende Apache Portable
          Runtime-Bibliothek IPv6 unterst&#252;tzt, bekommt der Apache httpd
          standarm&#228;&#223;ig IPv6 Listening Sockets. Zus&#228;tzlich
          unterst&#252;tzen die Konfigurationsanweisungen <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>, <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code> und <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> numerische IPv6-Adressangaben
          (z.B., "<code>Listen [2001:db8::1]:8080</code>").</dd>
    
          <dt><strong>Filterung</strong></dt>
    
          <dd>Apache-httpd-Module k&#246;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 <code>INCLUDES</code>-Filter
          von <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> bearbeitet werden und so
          Server-Side Include-Anweisungen ausgef&#252;hrt werden. Das Modul
          <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> erlaubt externen Programmen als
          Filter zu agieren, in der gleichen Weise wie CGI-Programme als
          Eingabe dienen k&#246;nnen.</dd>
    
          <dt><strong>Mehrsprachige Fehlermeldungen</strong></dt>
    
          <dd>Fehlermeldungen die an den Browser rausgehen, stehen jetzt als
          SSI-Dokumente in verschiedenen Sprachen zur Verf&#252;gung. Sie
          k&#246;nnen bei Bedarf durch den Administrator angepasst werden,
          um ein einheitliches Design zu erreichen.</dd>
    
          <dt><strong>Vereinfachte Konfiguration</strong></dt>
    
          <dd>Viele der verwirrenden Konfigurationsanweisungen wurden vereinfacht.
          Die oft f&#252;r Verwirrung sorgenden <code>Port</code>- und
          <code>BindAddress</code>-Anweisungen wurden entfernt.
          Ausschlie&#223;lich die <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>-Anweisung wird nun zum
          Setzen von IP-Addressen und Portnummern benutzt.
          Der Servername und die Portnummer, die f&#252;r Weiterleitungen und
          zur Erkennung virtueller Server verwendet werden, werden &#252;ber
          die <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>-Anweisung
          konfiguriert.</dd>
    
          <dt><strong>Native Windows NT Unicode-Unterst&#252;tzung</strong></dt>
    
          <dd>Der Apache httpd 2.0 auf Windows NT benutzt jetzt utf-8
          f&#252;r alle Dateinamen-Kodierungen. Diese werden direkt auf das
          zugrundeliegende Unicode-Dateisystem abgebildet, wodurch
          Mehrsprach-Unterst&#252;tzung f&#252;r alle Windows NT-basierten
          Installationen, inklusive Windows 2000 und Windows XP, zur
          Verf&#252;gung gestellt wird.  <em>Diese Unterst&#252;tzung ist
          nicht auf Windows 95, 98 oder ME verf&#252;gbar. Hier wird
          weiterhin die jeweils lokale Codepage des Rechners f&#252;r den
          Zugriff auf das Dateisystem verwendet.</em></dd>
    
          <dt>Bibliothek f&#252;r regul&#228;re Ausdr&#252;cke aktualisiert</dt>
    
          <dd>Der Apache httpd 2.0 enth&#228;lt die <a href="http://www.pcre.org/">"Perl Compatible
          Regular Expression Library"</a> (PCRE).
          Bei der Auswertung aller regul&#228;ren Ausdr&#252;cke wird nun
          die leistungsf&#228;higere Syntax von Perl 5 verwendet.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Modul-Erweiterungen</a></h2>
        
    
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd>Neues Modul in Apache httpd 2.0. Dieses Modul ist ein
          Interface zu den von OpenSSL bereitgestellten SSL/TLS
          Verschl&#252;sselungs-Protokollen.</dd>
    
          <dt><code class="module"><a href="./mod/mod_dav.html">mod_dav</a></code></dt>
    
          <dd>Neues Modul in Apache httpd 2.0. Dieses Modul implementiert
          die HTTP Distributed Authoring and Versioning (DAV) Spezifikation
          zur Erzeugung und Pflege von Web-Inhalten.</dd>
    
          <dt><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></dt>
    
          <dd>Neues Modul in Apache httpd 2.0. Dieses Modul erlaubt es
          Browsern, die dies unterst&#252;tzen, eine Komprimierung des
          Inhaltes vor der Auslieferung anzufordern, um so
          Netzwerk-Bandbreite zu sparen.</dd>
    
          <dt><code class="module">mod_auth_ldap</code></dt>
    
          <dd>Neues Modul in Apache httpd 2.0.41. Diese Modul
          erm&#246;glicht die Verwendung einer LDAP-Datenbank zur
          Speicherung von Berechtigungsdaten f&#252;r die
          HTTP-Basic-Authentication.  Ein Begleitmodul,
          <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>, stellt einen Verbindungs-Pool und die
          Pufferung von Abfrageergebnissen zur Verf&#252;gung.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_digest.html">mod_auth_digest</a></code></dt>
    
          <dd>Zus&#228;tzliche Unterst&#252;tzung f&#252;r
          prozess&#252;bergreifendes Session-Caching mittels Shared-Memory.
          </dd>
    
          <dt><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></dt>
    
          <dd>Neues Modul in Apache httpd 2.0.
          Dieses experimentelle Modul erlaubt Zeichensatz-&#220;bersetzungen oder
          -Umschl&#252;sselung.</dd>
    
          <dt><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></dt>
    
          <dd>Neues Modul in Apache httpd 2.0. Dieses Modul beinhaltet die
          Funktionalit&#228;t von <code>mod_mmap_static</code> aus Version
          1.3 des Apache HTTP Server zuz&#252;glich einiger weiterer
          Caching-Funktionen.</dd>
    
          <dt><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></dt>
    
          <dd>Dieses Modul ist in Apache httpd 2.0 deutlich flexibler
          geworden. Es kann jetzt die von <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>
          genutzten Request-Header manipulieren und es ist m&#246;glich
          Response-Header auf Basis von definierten Bedingungen zu
          ver&#228;ndern.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd>Das Proxy Modul wurde komplett neu geschrieben um die
          M&#246;glichkeiten der neuen Filter-Funktionalit&#228;t
          auszusch&#246;pfen und um einen zuverl&#228;ssigen Proxy zu haben, der
          den HTTP/1.1-Spezifikationen entspricht. Neue <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
          -Konfigurationsabschnitte bieten eine besser lesbare (und intern
          schnellere) Kontrolle der vermittelten Seiten.
          Die &#252;berladenen <code>&lt;Directory
          "proxy:..."&gt;</code>-Konfigurationen werden nicht
          mehr unterst&#252;tzt. Das Modul ist nun in mehrere Module
          unterteilt, die jeweils ein bestimmtes &#220;bertragungsprotokoll
          unterst&#252;tzen, wie <code>proxy_connect</code>,
          <code>proxy_ftp</code> und <code>proxy_http</code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></dt>
    
          <dd>Die neue Konfigurationsanweisung <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>
          kann benutzt werden, um sicherzustellen, dass ein Client auf jeden
          Fall ein einzelnes Dokument, anstatt einer NOT ACCEPTABLE- oder
          MULTIPLE CHOICES-Antwort, bekommt. Zus&#228;tzlich wurden die
          Negotiation- und Multiview-Algorithmen angepasst um einheitlichere
          Ergebnisse zu liefern. Au&#223;erdem wird ein neues
          Type-Map-Format bereitgestellt, das Dokumenteninhalte direkt
          enthalten kann.</dd>
    
          <dt><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></dt>
    
          <dd>Automatisch erzeugte Verzeichnisindizes k&#246;nnen zur besseren
          &#220;bersichtlichkeit durch HTML-Tabellen dargestellt werden.
          Genauere Sortierungen, wie Sortierung nach Versionsnummer und
          Wildcard-Filterung des Verzeichnisindizes werden unterst&#252;tzt.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
    
          <dd>Neue Anweisungen erlauben es, die Standard Start- und Endtags von
          SSI-Elementen zu &#228;ndern. Zudem k&#246;nnen die Default-Formate
          f&#252;r Fehlermeldungen und Zeitangaben nun ebenfalls in der
          Serverkonfiguration vorgenommen werden. Auf die Ergebnisse der
          Auswertung und Gruppierung von regul&#228;ren Ausdr&#252;cken (jetzt
          auf Basis der Perl-Syntax f&#252;r regul&#228;re Ausdr&#252;cke) kann
          &#252;ber die <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> Variablen <code>$0</code>
          bis <code>$9</code> zugegriffen werden.</dd>
    
          <dt><code class="module">mod_auth_dbm</code></dt>
    
          <dd>DBM-&#228;hnliche Datenbanken werden jetzt durch die
          Konfigurationsaweisung <code>AuthDBMType</code>
          unterst&#252;tzt.</dd>
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/new_features_2_0.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_0.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�016373� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/mass.html.en��������������������������������������������������������0000664�0001751�0001751�00000044434�14737241666�020640� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Dynamically Configured Mass Virtual Hosting - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Virtual Hosts</a></div><div id="page-content"><div id="preamble"><h1>Dynamically Configured Mass Virtual Hosting</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/vhosts/mass.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>This document describes how to efficiently serve an
        arbitrary number of virtual hosts with the Apache HTTP Server. A
        <a href="../rewrite/vhosts.html">separate document</a> discusses using
        <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> to create dynamic mass virtual hosts.
        </p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#motivation">Motivation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#overview">Overview</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple">Dynamic Virtual Hosts with
    mod_vhost_alias</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#homepages">Simplified Dynamic Virtual Hosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#combinations">Using Multiple Virtual
      Hosting Systems on the Same Server</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipbased">More Efficient IP-Based Virtual Hosting</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Mass virtual hosts with
    mod_rewrite</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#macro">Mass virtual hosts with mod_macro</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="motivation" id="motivation">Motivation</a></h2>
    
        <p>The techniques described here are of interest if your
        <code>httpd.conf</code> contains many
        <code>&lt;VirtualHost&gt;</code> sections that are
        substantially the same, for example:</p>
    
    <pre class="prettyprint lang-config">&lt;VirtualHost 111.22.33.44&gt;
        ServerName                 customer-1.example.com
        DocumentRoot        "/www/hosts/customer-1.example.com/docs"
        ScriptAlias  "/cgi-bin/"  "/www/hosts/customer-1.example.com/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName                 customer-2.example.com
        DocumentRoot        "/www/hosts/customer-2.example.com/docs"
        ScriptAlias  "/cgi-bin/"  "/www/hosts/customer-2.example.com/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName                 customer-N.example.com
        DocumentRoot        "/www/hosts/customer-N.example.com/docs"
        ScriptAlias  "/cgi-bin/"  "/www/hosts/customer-N.example.com/cgi-bin"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>We wish to replace these multiple
        <code>&lt;VirtualHost&gt;</code> blocks with a mechanism
        that works them out dynamically. This has a number of
        advantages:</p>
    
        <ol>
          <li>Your configuration file is smaller, so Apache starts
          more quickly and uses less memory. Perhaps more importantly, the
          smaller configuration is easier to maintain, and leaves less room
          for errors.</li>
    
          <li>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.</li>
        </ol>
    
        <p>The main disadvantage is that you cannot have a different log file for
        each virtual host; however, if you have many virtual hosts, doing
        this can be a bad idea anyway, because of the <a href="fd-limits.html">number of file descriptors needed</a>.
        It is better to <a href="../logs.html#piped">log to a pipe or a fifo</a>,
        and arrange for the process at the other end to split up the log
        files into one per virtual host. One example of such a process can
        be found in the <a href="../programs/split-logfile.html">split-logfile</a>
        utility.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Overview</a></h2>
    
        <p>A virtual host is defined by two pieces of information: its
        IP address, and the contents of the <code>Host:</code> header
        in the HTTP request. The dynamic mass virtual hosting technique
        used here is based on automatically inserting this information into the
        pathname of the file that is used to satisfy the request. This
        can be most easily done by using <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>
        with Apache httpd. Alternatively,
        <a href="../rewrite/vhosts.html">mod_rewrite can
        be used</a>.</p>
        <p>Both of these modules are disabled by default; you must enable
        one of them when configuring and building Apache httpd if you want to
        use this technique.</p>
    
        <p>A couple of things need to be determined from the request in
        order to make the dynamic
        virtual host look like a normal one. The most important is the
        server name, which is used by the server to generate
        self-referential URLs etc. It is configured with the
        <code>ServerName</code> directive, and it is available to CGIs
        via the <code>SERVER_NAME</code> environment variable. The
        actual value used at run time is controlled by the <code class="directive"><a href="../mod/core.html#usecanonicalname">UseCanonicalName</a></code>
        setting. With <code>UseCanonicalName Off</code>, the server name
        is taken from the contents of the <code>Host:</code> header in the
        request. With <code>UseCanonicalName DNS</code>, it is taken 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 httpd cannot work out
        the server name because there is no <code>Host:</code> header,
        or the DNS lookup fails, then the value configured with
        <code>ServerName</code> is used instead.</p>
    
        <p>The other thing to determine is the document root (configured
        with <code>DocumentRoot</code> and available to CGI scripts via the
        <code>DOCUMENT_ROOT</code> environment variable). In a normal
        configuration, this is used by the core module when
        mapping URIs to filenames, but when the server is configured to
        do dynamic virtual hosting, that job must be taken over by another
        module (either <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> or
        <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>), which has a different way of doing
        the mapping. Neither of these modules is responsible for
        setting the <code>DOCUMENT_ROOT</code> environment variable so
        if any CGIs or SSI documents make use of it, they will get a
        misleading value.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple" id="simple">Dynamic Virtual Hosts with
    mod_vhost_alias</a></h2>
    
        <p>This extract from <code>httpd.conf</code> implements the
        virtual host arrangement outlined in the <a href="#motivation">Motivation</a> section above
        using <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>.</p>
    
    <pre class="prettyprint lang-config"># get the server name from the Host: header
    UseCanonicalName Off
    
    # this log format can be split per-virtual-host based on the first field
    # using the split-logfile utility.
    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"</pre>
    
    
        <p>This configuration can be changed into an IP-based virtual
        hosting solution by just turning <code>UseCanonicalName
        Off</code> into <code>UseCanonicalName DNS</code>. The server
        name that is inserted into the filename is then derived from
        the IP address of the virtual host. The variable <code>%0</code>
        references the requested servername, as indicated in the
        <code>Host:</code> header.</p>
    
    <p>See the <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> documentation for more usage
    examples.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="homepages" id="homepages">Simplified Dynamic Virtual Hosts</a></h2>
    
        <p>This is an adjustment of the above system, tailored for an
        ISP's web hosting server. Using <code>%2</code>,
        we can select substrings of the server name to
        use in the filename so that, for example, the documents for
        <code>www.user.example.com</code> are found in
        <code>/home/user/www</code>. It uses a single <code>cgi-bin</code>
        directory instead of one per virtual host.</p>
    
    <pre class="prettyprint lang-config">UseCanonicalName Off
    
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log" vcommon
    
    # include part of the server name in the filenames
    VirtualDocumentRoot "/home/%2/www"
    
    # single cgi-bin directory
    ScriptAlias  "/cgi-bin/"  "/www/std-cgi/"</pre>
    
    
        <p>There are examples of more complicated
        <code>VirtualDocumentRoot</code> settings in the
        <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> documentation.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="combinations" id="combinations">Using Multiple Virtual
      Hosting Systems on the Same Server</a></h2>
    
        <p>With more complicated setups, you can use httpd's normal
        <code>&lt;VirtualHost&gt;</code> directives to control the
        scope of the various virtual hosting configurations. For
        example, you could have one IP address for general customers' homepages,
        and another for commercial customers, with the following setup.
        This can be combined with conventional
        <code>&lt;VirtualHost&gt;</code> configuration sections, as shown
        below.</p>
    
    <pre class="prettyprint lang-config">UseCanonicalName Off
    
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    
    &lt;Directory "/www/commercial"&gt;
        Options FollowSymLinks
        AllowOverride All
    &lt;/Directory&gt;
    
    &lt;Directory "/www/homepages"&gt;
        Options FollowSymLinks
        AllowOverride None
    &lt;/Directory&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName www.commercial.example.com
    
        CustomLog "logs/access_log.commercial" vcommon
    
        VirtualDocumentRoot "/www/commercial/%0/docs"
        VirtualScriptAlias  "/www/commercial/%0/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.45&gt;
        ServerName www.homepages.example.com
    
        CustomLog "logs/access_log.homepages" vcommon
    
        VirtualDocumentRoot "/www/homepages/%0/docs"
        ScriptAlias         "/cgi-bin/" "/www/std-cgi/"
    &lt;/VirtualHost&gt;</pre>
    
    
    <div class="note">
        <h3>Note</h3>
        <p>If the first VirtualHost block does <em>not</em> include a
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> directive, the reverse
        DNS of the relevant IP will be used instead.
        If this is not the server name you
        wish to use, a bogus entry (eg. <code>ServerName
        none.example.com</code>) can be added to get around this
        behaviour.</p>
    </div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipbased" id="ipbased">More Efficient IP-Based Virtual Hosting</a></h2>
    
        <p>The configuration changes suggested to turn <a href="#simple">the first
        example</a> into an IP-based virtual hosting setup result in
        a rather inefficient setup. A new DNS lookup is required for every
        request. To avoid this overhead, the filesystem can be arranged to
        correspond to the IP addresses, instead of to the host names, thereby
        negating the need for a DNS lookup. Logging will also have to be adjusted
        to fit this system.</p>
    
    <pre class="prettyprint lang-config"># 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"</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Mass virtual hosts with
    mod_rewrite</a></h2>
    
    <p>
    Mass virtual hosting may also be accomplished using
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>, either using simple <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives, or using more
    complicated techniques such as storing the vhost definitions externally
    and accessing them via <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>. These techniques are
    discussed in the <a href="../rewrite/vhosts.html">rewrite
    documentation</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="macro" id="macro">Mass virtual hosts with mod_macro</a></h2>
    
    <p>Another option for dynamically generated virtual hosts is
    <code class="module"><a href="../mod/mod_macro.html">mod_macro</a></code>, with which you can create a virtualhost
    template, and invoke it for multiple hostnames. An example of this is
    provided in the <strong>Usage</strong> section of the module
    documentation.
    </p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/vhosts/mass.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/mass.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/details.html.en�����������������������������������������������������0000664�0001751�0001751�00000044625�14737241666�021324� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>An In-Depth Discussion of Virtual Host Matching - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Virtual Hosts</a></div><div id="page-content"><div id="preamble"><h1>An In-Depth Discussion of Virtual Host Matching</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/vhosts/details.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>This document attempts to explain
        exactly what Apache HTTP Server does when deciding what virtual host to
        serve a request from.</p>
    
        <p>Most users should read about <a href="name-based.html#namevip">
        Name-based vs. IP-based Virtual Hosts</a> to decide which type they
        want to use, then read more about <a href="name-based.html">name-based</a>
        or <a href="ip-based.html">IP-based</a> virtualhosts, and then see
        <a href="examples.html">some examples</a>.</p>
    
        <p>If you want to understand all the details, then you can
        come back to this page.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configparsing">Configuration File</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#hostmatching">Virtual Host Matching</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#tips">Tips</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="ip-based.html">IP-based Virtual Host Support</a></li><li><a href="name-based.html">Name-based Virtual Hosts Support</a></li><li><a href="examples.html">Virtual Host examples for common setups</a></li><li><a href="mass.html">Dynamically configured mass virtual hosting</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configparsing" id="configparsing">Configuration File</a></h2>
    
        <p>There is a <em>main server</em> which consists of all the
        definitions appearing outside of
        <code>&lt;VirtualHost&gt;</code> sections.</p>
    
        <p>There are virtual
        servers, called <em>vhosts</em>, which are defined by
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        sections.</p>
    
        <p>Each <code>VirtualHost</code> directive includes one
        or more addresses and optional ports.</p>
    
        <p>Hostnames can be used in place of IP addresses in a virtual
        host definition, but they are resolved at startup and if any name
        resolutions fail, those virtual host definitions are ignored.
        This is, therefore, not recommended.</p>
    
        <p>The address can be specified as
        <code>*</code>, which will match a request if no
        other vhost has the explicit address on which the request was
        received. </p>
    
        <p>The address appearing in the <code>VirtualHost</code>
        directive can have an optional port. If the port is unspecified,
        it is treated as a wildcard port, which can also be indicated
        explicitly using <code>*</code>.
        The wildcard port matches any port.</p>
    
        <p>(Port numbers specified in the <code>VirtualHost</code> directive do
        not influence what port numbers Apache will listen on, they only control
        which <code>VirtualHost</code> will be selected to handle a request.
        Use the <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> directive to
        control the addresses and ports on which the server listens.)
        </p>
    
        <p>Collectively the
        entire set of addresses (including multiple
        results from DNS lookups) are called the vhost's
        <em>address set</em>.</p>
    
        <p>Apache automatically discriminates on the
        basis of the HTTP <code>Host</code> header supplied by the client
        whenever the most specific match for an IP address and port combination
        is listed in multiple virtual hosts.</p>
    
        <p>The
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> directive
        may appear anywhere within the definition of a server. However,
        each appearance overrides the previous appearance (within that
        server).  If no <code>ServerName</code> is specified, the server
        attempts to deduce it from the server's IP address.</p>
    
        <p>The first name-based vhost in the configuration file for a
        given IP:port pair is significant because it is used for all
        requests received on that address and port for which no other
        vhost for that IP:port pair has a matching ServerName or
        ServerAlias.  It is also used for all SSL connections if the
        server does not support <a class="glossarylink" href="../glossary.html#servernameindication" title="see glossary">Server Name Indication</a>.</p>
    
        <p>The complete list of names in the <code>VirtualHost</code>
        directive are treated just like a (non wildcard) <code>ServerAlias</code>
        (but are not overridden by any <code>ServerAlias</code> statement).</p>
    
        <p>For every vhost various default values are set. In
        particular:</p>
    
        <ol>
          <li>If a vhost has no <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>,
          <code class="directive"><a href="../mod/core.html#timeout">Timeout</a></code>,
          <code class="directive"><a href="../mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code>,
          <code class="directive"><a href="../mod/core.html#keepalive">KeepAlive</a></code>,
          <code class="directive"><a href="../mod/core.html#maxkeepaliverequests">MaxKeepAliveRequests</a></code>,
          <code class="directive"><a href="../mod/mpm_common.html#receivebuffersize">ReceiveBufferSize</a></code>,
          or <code class="directive"><a href="../mod/mpm_common.html#sendbuffersize">SendBufferSize</a></code>
          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.)</li>
    
          <li>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.</li>
    
          <li>The per-server configs for each module from the
          main server are merged into the vhost server.</li>
        </ol>
    
        <p>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.</p>
    
        <p>If the main server has no <code>ServerName</code> at this
        point, then the hostname of the machine that <code class="program"><a href="../programs/httpd.html">httpd</a></code>
        is running on is used instead. We will call the <em>main server address
        set</em> those IP addresses returned by a DNS lookup on the
        <code>ServerName</code> of the main server.</p>
    
        <p>For any undefined <code>ServerName</code> fields, a
        name-based vhost defaults to the address given first in the
        <code>VirtualHost</code> statement defining the vhost.</p>
    
        <p>Any vhost that includes the magic <code>_default_</code>
        wildcard is given the same <code>ServerName</code> as the
        main server.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hostmatching" id="hostmatching">Virtual Host Matching</a></h2>
    
        <p>The server determines which vhost to use for a request as
        follows:</p>
    
        <h3><a name="hashtable" id="hashtable">IP address lookup</a></h3>
    
        <p>When the connection is first received on some address and port,
        the server looks for all the <code>VirtualHost</code> definitions
        that have the same IP address and port.</p>
    
        <p>If there are no exact matches for the address and port, then
        wildcard (<code>*</code>) matches are considered.</p>
    
        <p>If no matches are found, the request is served by the
        main server.</p>
    
        <p>If there are <code>VirtualHost</code> definitions for
        the IP address, the next step is to decide if we have to
        deal with an IP-based or a name-based vhost.</p>
    
        
    
        <h3><a name="ipbased" id="ipbased">IP-based vhost</a></h3>
    
        <p>If there is exactly one <code>VirtualHost</code> directive
        listing the IP address and port combination that was determined
        to be the best match, no further actions are performed and
        the request is served from the matching vhost.</p>
    
        
    
        <h3><a name="namebased" id="namebased">Name-based vhost</a></h3>
    
        <p>If there are multiple <code>VirtualHost</code> directives listing
        the IP address and port combination that was determined to be the
        best match, the "list" in the remaining steps refers to the list of vhosts
        that matched, in the order they were in the configuration file.</p>
    
        <p>If the connection is using SSL, the server supports <a class="glossarylink" href="../glossary.html#servernameindication" title="see glossary">Server Name Indication</a>, and
        the SSL client handshake includes the TLS extension with the
        requested hostname, then that hostname is used below just like the
        <code>Host:</code> header would be used on a non-SSL connection.
        Otherwise, the first name-based vhost whose address matched is
        used for SSL connections.  This is significant because the
        vhost determines which certificate the server will use for the
        connection.</p>
    
        <p>If the request contains a <code>Host:</code> header field, the
        list is searched for the first vhost with a matching
        <code>ServerName</code> or <code>ServerAlias</code>, and the
        request is served from that vhost. A <code>Host:</code> header
        field can contain a port number, but Apache always ignores it and
        matches against the real port to which the client sent the
        request.</p>
    
        <p>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 <code>Host:</code> header field (such as a HTTP/1.0
        request).</p>
    
        
    
        <h3><a name="persistent" id="persistent">Persistent connections</a></h3>
    
        <p>The <em>IP lookup</em> described above is only done <em>once</em> for a
        particular TCP/IP session while the <em>name lookup</em> is done on
        <em>every</em> request during a KeepAlive/persistent
        connection. In other words, a client may request pages from
        different name-based vhosts during a single persistent
        connection.</p>
    
        
    
        <h3><a name="absoluteURI" id="absoluteURI">Absolute URI</a></h3>
    
        <p>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 <em>and</em> 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.</p>
    
    
    <h3><a name="observations" id="observations">Observations</a></h3>
    
        <ul>
          <li>Name-based virtual hosting is a process applied after
          the server has selected the best matching IP-based virtual
          host.</li>
    
          <li>If you don't care what IP address the client has connected to, use a
          "*" as the address of every virtual host, and name-based virtual hosting
          is applied across all configured virtual hosts.</li>
    
          <li><code>ServerName</code> and <code>ServerAlias</code>
          checks are never performed for an IP-based vhost.</li>
    
          <li>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.</li>
    
          <li>Any port in the <code>Host:</code> header field is never used during the
          matching process. Apache always uses the real port to which
          the client sent the request.</li>
    
          <li>If two vhosts have an address in common, those common addresses
          act as name-based virtual hosts implicitly.  This is new behavior as of
          2.3.11.</li>
    
          <li>The main server is only used to serve a request if the IP
          address and port number to which the client connected
          does not match any vhost (including a
          <code>*</code> vhost). In other words, the main server
          only catches a request for an unspecified address/port
          combination (unless there is a <code>_default_</code> vhost
          which matches that port).</li>
    
          <li>You should never specify DNS names in
          <code>VirtualHost</code> 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 <a href="../dns-caveats.html">more
          information</a> available on this and the next two
          topics.</li>
    
          <li><code>ServerName</code> should always be set for each
          vhost. Otherwise a DNS lookup is required for each
          vhost.</li>
          </ul>
          
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">Tips</a></h2>
    
        <p>In addition to the tips on the <a href="../dns-caveats.html#tips">DNS Issues</a> page, here are
        some further tips:</p>
    
        <ul>
          <li>Place all main server definitions before any
          <code>VirtualHost</code> 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.)</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/vhosts/details.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/details.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html.de�������������������������������������������������������0000664�0001751�0001751�00000021044�14744525602�020753� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache-Dokumentation zu virtuellen Hosts - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Module</a> | <a href="../mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossar</a> | <a href="../sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache-Dokumentation zu virtuellen Hosts</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="../de/vhosts/" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
        <p>Der Begriff <cite>virtueller Host</cite> <span class="transnote">(<em>Anm.d.&#220;.:</em> engl. 'virtual
        host')</span> bezieht sich auf die Praxis, mehr als ein Webangebot
        (z.B. <code>www.company1.com</code> und <code>www.company2.com</code>)
        auf einer einzigen Maschine zu betreiben. Virtuelle Hosts k&#246;nnen
        "<a href="ip-based.html">IP-basiert</a>" sein, was bedeutet, dass jedes
        Webangebot eine andere IP besitzt, oder  "<a href="name-based.html">Namens-basiert</a>", was bedeutet, dass
        unter jeder IP-Adresse mehrere Namen laufen. Die Tatsache, dass sie
        auf dem gleichen physischen Server laufen, ist f&#252;r den Endbenutzer
        nicht offensichtlich.</p>
    
        <p>Der Apache war einer der ersten Server, der IP-basierte
        virtuelle Hosts von Haus aus direkt unterst&#252;tzt hat. Seit Version 1.1
        unterst&#252;tzt der Apache sowohl IP-basierte als auch namensbasierte
        virtuelle Hosts (vhosts). Letzteres wird zuweilen auch
        <em>Host-basiert</em> oder <em>non-IP-Virtual-Host</em> genannt.</p>
    
        <p>Nachfolgend finden Sie eine Liste von Dokumenten, die alle Details
        der Unterst&#252;tzung von virtuellen Hosts ab Apache Version 1.3
        beschreiben.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#support">Unterst&#252;tzung virtueller Hosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#directives">Konfigurationsdirektiven</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li><li><a href="name-based.html">Namensbasierte virtuelle Hosts</a></li><li><a href="ip-based.html">IP-basierte virtuelle Hosts</a></li><li><a href="examples.html">Beispiele f&#252;r virtuelle
      Hosts</a></li><li><a href="fd-limits.html">Datei-Deskriptor-Begrenzungen</a></li><li><a href="mass.html">Massen-Virtual-Hosting</a></li><li><a href="details.html">Zuweisung virtueller Hosts</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">Unterst&#252;tzung virtueller Hosts</a></h2>
    
        <ul>
          <li><a href="name-based.html">Namensbasierte virtuelle Hosts</a> (Mehr
           als ein Webangebot pro IP-Adresse)</li>
          <li><a href="ip-based.html">IP-basierte virtuelle Hosts</a> (Eine
            IP-Adresse f&#252;r jedes Webangebot)</li>
          <li><a href="examples.html">Beispiele f&#252;r virtuelles Hosts in
            typischen Installationen</a></li>
          <li><a href="fd-limits.html">Datei-Deskriptor-Begrenzungen</a> (oder
          <em>Zu viele Protokolldateien</em>)</li>
          <li><a href="mass.html">Dynamisch konfiguriertes
            Massen-Virtual-Hosting</a></li>
          <li><a href="details.html">Tiefergehende Er&#246;rterung der Zuweisung
            virtueller Hosts</a></li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="directives" id="directives">Konfigurationsdirektiven</a></h2>
    
        <ul>
          <li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li>
        </ul>
    
        <p>Bei der Suche von Fehlern in Ihrer Virtual-Host-Konfiguration ist
        die Apache-Befehlszeilenoption <code>-S</code> m&#246;glicherweise
        hilfreich. Geben Sie dazu den folgenden Befehl ein:</p>
    
        <div class="example"><p><code>
        /usr/local/apache2/bin/httpd -S
        </code></p></div>
    
        <p>Diese Anweisung gibt eine Beschreibung aus, wie der Apache die
        Konfigurationsdatei analysiert hat. Eine sorgf&#228;ltige
        &#220;berpr&#252;fung der IP-Adressen und Servernamen kann helfen,
        Konfigurationsfehler aufzudecken. (Lesen Sie die Dokumentation zum
        <code class="program"><a href="../programs/httpd.html">httpd</a></code>-Programm f&#252;r weitere
        Befehlszeilenoptionen.)</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="../de/vhosts/" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Module</a> | <a href="../mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossar</a> | <a href="../sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/ip-based.html.en����������������������������������������������������0000664�0001751�0001751�00000032422�14737241666�021353� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache IP-based Virtual Host Support - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Virtual Hosts</a></div><div id="page-content"><div id="preamble"><h1>Apache IP-based Virtual Host Support</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/vhosts/ip-based.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#explanation">What is IP-based virtual hosting</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#requirements">System requirements</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#howto">How to set up Apache</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multiple">Setting up multiple daemons</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#single">Setting up a single daemon
      with virtual hosts</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li>
    <a href="name-based.html">Name-based Virtual Hosts Support</a>
    </li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="explanation" id="explanation">What is IP-based virtual hosting</a></h2>
    <p>IP-based virtual hosting is a method to apply different directives
    based on the IP address and port a request is received on.  Most commonly,
    this is used to serve different websites on different ports or interfaces.</p>
    
    <p>In many cases, <a href="name-based.html">name-based
    virtual hosts</a> are more convenient, because they allow
    many virtual hosts to share a single address/port.
    See <a href="name-based.html#namevip">Name-based vs. IP-based
    Virtual Hosts</a> to help you decide.  </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">System requirements</a></h2>
    
        <p>As the term <cite>IP-based</cite> indicates, the server
        <strong>must have a different IP address/port combination for each IP-based
        virtual host</strong>. 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), and/or using multiple
        port numbers.</p>
    
        <p> In the terminology of Apache HTTP Server, using a single IP address
        but multiple TCP ports, is also IP-based virtual hosting.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">How to set up Apache</a></h2>
    
        <p>There are two ways of configuring apache to support multiple
        hosts. Either by running a separate <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon for
        each hostname, or by running a single daemon which supports all the
        virtual hosts.</p>
    
        <p>Use multiple daemons when:</p>
    
        <ul>
          <li>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 <code class="directive"><a href="../mod/mod_unixd.html#user">User</a></code>, <code class="directive"><a href="../mod/mod_unixd.html#group">Group</a></code>, <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>, and <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> settings.</li>
    
          <li>You can afford the memory and file descriptor
          requirements of listening to every IP alias on the
          machine. It's only possible to <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> 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
          <code class="program"><a href="../programs/httpd.html">httpd</a></code> could listen to N-1 of the addresses, and another could
          listen to the remaining address.)</li>
        </ul>
    
        <p>Use a single daemon when:</p>
    
        <ul>
          <li>Sharing of the httpd configuration between virtual hosts
          is acceptable.</li>
    
          <li>The machine services a large number of requests, and so
          the performance loss in running separate daemons may be
          significant.</li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multiple" id="multiple">Setting up multiple daemons</a></h2>
    
        <p>Create a separate <code class="program"><a href="../programs/httpd.html">httpd</a></code> installation for each
        virtual host. For each installation, use the <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> directive in the
        configuration file to select which IP address (or virtual host)
        that daemon services. e.g.</p>
    
        <pre class="prettyprint lang-config">Listen 192.0.2.100:80</pre>
    
    
        <p>It is recommended that you use an IP address instead of a
        hostname (see <a href="../dns-caveats.html">DNS caveats</a>).</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="single" id="single">Setting up a single daemon
      with virtual hosts</a></h2>
    
        <p>For this case, a single <code class="program"><a href="../programs/httpd.html">httpd</a></code> will service
        requests for the main server and all the virtual hosts. The <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> directive
        in the configuration file is used to set the values of <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>, <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>, <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>, <code class="directive"><a href="../mod/core.html#errorlog">ErrorLog</a></code> and <code class="directive"><a href="../mod/mod_log_config.html#transferlog">TransferLog</a></code>
        or <code class="directive"><a href="../mod/mod_log_config.html#customlog">CustomLog</a></code>
        configuration directives to different values for each virtual
        host. e.g.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 172.20.30.40:80&gt;
        ServerAdmin webmaster@www1.example.com
        DocumentRoot "/www/vhosts/www1"
        ServerName www1.example.com
        ErrorLog "/www/logs/www1/error_log"
        CustomLog "/www/logs/www1/access_log" combined
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:80&gt;
        ServerAdmin webmaster@www2.example.org
        DocumentRoot "/www/vhosts/www2"
        ServerName www2.example.org
        ErrorLog "/www/logs/www2/error_log"
        CustomLog "/www/logs/www2/access_log" combined
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>It is recommended that you use an IP address instead of a
        hostname in the &lt;VirtualHost&gt; directive
        (see <a href="../dns-caveats.html">DNS caveats</a>).</p>
    
        <p> Specific IP addresses or ports have precedence over their wildcard
        equivalents, and any virtual host that matches has precedence over
        the servers base configuration.</p>
    
        <p>Almost <strong>any</strong> 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 <a href="../mod/directive-dict.html#Context">Context</a> using the
        <a href="../mod/quickreference.html">directive index</a>.</p>
    
        <p><code class="directive"><a href="../mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code>
        may be used inside a
        VirtualHost directive if the <a href="../suexec.html">suEXEC
        wrapper</a> is used.</p>
    
        <p><em>SECURITY:</em> 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 <a href="../misc/security_tips.html">security tips</a> document
        for details.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/vhosts/ip-based.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/ip-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/details.html��������������������������������������������������������0000664�0001751�0001751�00000000576�13710016232�020673� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: details.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: details.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: details.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: details.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/examples.html�������������������������������������������������������0000664�0001751�0001751�00000000732�13710016232�021056� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: examples.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: examples.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: examples.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: examples.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: examples.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������httpd-2.4.64/docs/manual/vhosts/mass.html�����������������������������������������������������������0000664�0001751�0001751�00000000562�13710016232�020204� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: mass.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: mass.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: mass.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: mass.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/details.html.ko.euc-kr����������������������������������������������0000664�0001751�0001751�00000047573�14743132254�022512� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ȣƮ ã⿡  ڼ  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">ȣƮ</a></div><div id="page-content"><div id="preamble"><h1>ȣƮ ã⿡  ڼ </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/vhosts/details.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    
        <p>ȣƮ ڵ <strong>ġ 1.3</strong>  ٽ
        ۼǾ.   ġ û   ȣƮ
         ϴ  Ѵ. ο <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> þ Ͽ
        ȣƮ  1.3     .</p>
    
        <p> ϴ ʰ  <cite>ϰԸ</cite>
        ϰ ʹٸ, <a href="examples.html"></a> ϶.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configparsing"> б</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#hostmatching">ȣƮ ã</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#tips"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configparsing" id="configparsing"> б</a></h2>
    
        <p><code>&lt;VirtualHost&gt;</code>   
        <em>ּ</em> . <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>  
        κ ȣƮ θ.</p>
    
        <p><code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>,
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>,
        <code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code>,
        <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> þ
             ִ. ׷  þ
          ( )  þ ȿϴ.</p>
    
        <p>ּ <code>Listen</code> ⺻ 80̴. ּ
        <code>ServerPath</code> <code>ServerAlias</code>
        ⺻ . <code>ServerName</code> ⺻ 
        IP ̴ּ.</p>
    
        <p>ּ Listen þ ΰ  Ѵ. ù°
        ġ  ⺻ Ʈ Ʈ ϴ ̴. °
        ̷  URI  Ʈ ȣ ϴ ̴.</p>
    
        <p>ּ ޸ ȣƮ Ʈ ġ  ٸ
        Ʈ   <em>ʴ´</em>.</p>
    
        <p><code>VirtualHost</code> þ Ʈ   ִ.
        Ʈ  ּ  ֱ <code>Listen</code>
         Ѵ. Ư Ʈ <code>*</code>  Ʈ
        Īϴ ϵī̴. (DNS ˻   <code>A</code>
        ڵ带 Ͽ) ȣƮ ּҸ  ĪϿ ȣƮ
        <em>ּ(address set)</em>̶ θ.</p>
    
        <p>Ư IP ּҿ  <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> þ ٸ
         ּҸ ϴ ù° ȣƮ IP ȣƮ Ѵ.
        IP ּҿ ϵī <code>*</code>   ִ.</p>
    
        <p≯ ȣƮ Ѵٸ ̸ ȣƮ
         IP ּҸ <code>NameVirtualHost</code> þ
        ؾ <em>Ѵ</em>. ,  <code>NameVirtualHost</code>
        þ ̸ ȣƮ ȣƮ(CNAME) شϴ
        IP ּҸ ؾ Ѵ.</p>
    
        <p>Ư IP:Ʈ ֿ    <code>NameVirtualHost</code>
        þ Ѵٸ,  <code>NameVirtualHost</code> þ
        <code>VirtualHost</code> þ    ִ.</p>
    
        <p><code>NameVirtualHost</code> <code>VirtualHost</code>
        þ  ߿ ʱ⶧     (
        <em></em> ּտ  <code>VirtualHost</code>
         ߿ϴ. Ʒ ):</p>
    
    <table><tr>
    <td><div class="example"><p><code>
      NameVirtualHost 111.22.33.44<br />
      &lt;VirtualHost 111.22.33.44&gt;<br />
      #  A<br />
      ...<br />
      &lt;/VirtualHost&gt;<br />
      &lt;VirtualHost 111.22.33.44&gt;<br />
      #  B<br />
      ...<br />
      &lt;/VirtualHost&gt;<br />
      <br />
      NameVirtualHost 111.22.33.55<br />
      &lt;VirtualHost 111.22.33.55&gt;<br />
      #  C<br />
      ...<br />
      &lt;/VirtualHost&gt;<br />
      &lt;VirtualHost 111.22.33.55&gt;<br />
      #  D<br />
      ...<br />
      &lt;/VirtualHost&gt;
    </code></p></div></td>
    <td><div class="example"><p><code>
      &lt;VirtualHost 111.22.33.44&gt;<br />
      #  A<br />
      &lt;/VirtualHost&gt;<br />
      &lt;VirtualHost 111.22.33.55&gt;<br />
      #  C<br />
      ...<br />
      &lt;/VirtualHost&gt;<br />
      &lt;VirtualHost 111.22.33.44&gt;<br />
      #  B<br />
      ...<br />
      &lt;/VirtualHost&gt;<br />
      &lt;VirtualHost 111.22.33.55&gt;<br />
      #  D<br />
      ...<br />
      &lt;/VirtualHost&gt;<br />
      <br />
      NameVirtualHost 111.22.33.44<br />
      NameVirtualHost 111.22.33.55<br />
      <br />
    </code></p></div></td>
    </tr></table>
    
    
        <p>(   б ϴ.)</p>
    
        <p><code>VirtualHost</code> þ  , ȣƮ
         <code>VirtualHost</code> þ  Ʈ ⺻
        <code>Listen</code> Ѵ.</p>
    
        <p><code>VirtualHost</code> þ ̸  
        ּտ Ѵٸ <code>ServerAlias</code>  Ѵ
        (׷ ٸ <code>ServerAlias</code>   ʴ´).
        ȣƮ ߰  <code>Listen</code> ּ
         Ʈ    ϶.</p>
    
        <p>Ҷ IP ּ   ؽ̺ ߰Ѵ.
        <code>NameVirtualHost</code> þ IP ּҸ ϸ
          IP ּҿ   ̸ ȣƮ Ѵ.
         ּҿ  ȣƮ ٸ <code>NameVirtualHost</code>
        þ ϰ α׿  Ѵ. IP ȣƮ
        ؽ̺  ߰ ʴ´.</p>
    
        <p> ؽԼ ϱ⶧ û IP ּҸ ؽϴ
        δ  .  ؽ̺ IP ּ  κ
        ̿ ȭִ.</p>
    
        <p>ȣƮ  ⺻ ȴ. Ư:</p>
    
        <ol>
          <li>ȣƮ <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>,
          <code class="directive"><a href="../mod/core.html#resourceconfig">ResourceConfig</a></code>,
          <code class="directive"><a href="../mod/core.html#accessconfig">AccessConfig</a></code>,
          <code class="directive"><a href="../mod/core.html#timeout">Timeout</a></code>,
          <code class="directive"><a href="../mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code>,
          <code class="directive"><a href="../mod/core.html#keepalive">KeepAlive</a></code>,
          <code class="directive"><a href="../mod/core.html#maxkeepaliverequests">MaxKeepAliveRequests</a></code>,
          <code class="directive"><a href="../mod/core.html#sendbuffersize">SendBufferSize</a></code>
          þ ٸ ּ ش  ´. (,
          ּ  Ѵ.)</li>
    
          <li>ȣƮ 丮 ⺻ ϴ "
          ⺻(lookup defaults)" ּ  .
           丮 (per-directory configuration)
          ⿡ شȴ.</li>
    
          <li>   (per-server config) ּ
           ȣƮ  ģ.</li>
        </ol>
    
        <p>⺻ ּ ȣƮ  "⺻" Ȥ ""
        ȴ. ׷ Ͽ ּ ϴ ġ .
          ġ  ּ   оδ.
        ׷ ּ ǰ ȣƮ  ڿ ͵ ȣƮ
        ǿ  ش.</p>
    
        <p>ּ <code>ServerName</code> ٸ  ϴ
        ǻ ȣƮ  Ѵ. ּ
        <code>ServerName</code> DNS ̻Ͽ  IP ּҵ
        <em>ּ ּ</em>̶ θ.</p>
    
        <p≯ ȣƮ <code>ServerName</code> 
         ȣƮ ϴ <code>VirtualHost</code>
        ó  ּҸ ⺻ Ѵ.</p>
    
        <p>Ư <code>_default_</code> Ʈī带 ϴ
        ȣƮ ּ  <code>ServerName</code> .</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hostmatching" id="hostmatching">ȣƮ ã</a></h2>
    
        <p> Ʒ    ȣƮ û
        ó Ѵ:</p>
    
        <h3><a name="hashtable" id="hashtable">ؽ̺ ã</a></h3>
    
        <p>Ŭ̾Ʈ ó ϸ  IP ּҸ  IP
        ؽ̺ ã´.</p>
    
        <p>IP ּҸ ã   Ŭ̾Ʈ û  Ʈ
        شϴ ȣƮ ִٸ, <code>_default_</code> ȣƮ
        û Ѵ. <code>_default_</code> ȣƮ
        ٸ ּ û Ѵ.</p>
    
        <p>ؽ̺ IP ּҰ  Ʈ ȣ
        <code>NameVirtualHost *</code> ش  ִ.  
        ̸ ȣƮó óѴ.</p>
    
        <p>ãҴٸ (Ͽ IP ּҿ شϴ ׸ ã),
        IP ȣƮ ̸ ȣƮ Ѵ.</p>
    
        
    
        <h3><a name="ipbased" id="ipbased">IP ȣƮ</a></h3>
    
        <p>ã ׸ ̸  ٸ IP ȣƮ̴.
         ̻ ۾ ʿ,  ȣƮ û óѴ.</p>
    
        
    
        <h3><a name="namebased" id="namebased"≯ ȣƮ</a></h3>
    
        <p≯ Ͽ Ѱ ̻ ȣƮ  ԵǸ
        ̸ ȣƮ̴.  Ͽ ȣƮ 
        <code>VirtualHost</code>  ġѴ.</p>
    
        <p>Ͽ ù° ȣƮ(Ͽ ش IP ּҸ
        ϴ ù° ȣƮ)   켱 ,
           ų <code>Host:</code>   û
        óѴ.</p>
    
        <p>Ŭ̾Ʈ <code>Host:</code>  ָ, Ͽ
        ù° <code>ServerName</code>̳
        <code>ServerAlias</code> ϴ ȣƮ û
        Ѵ. <code>Host:</code>  Ʈ ȣ  
        , ġ ׻ Ŭ̾Ʈ û   Ʈ
        ã´.</p>
    
        <p>Ŭ̾Ʈ <code>Host:</code>  HTTP/1.0 û
        ϸ Ŭ̾Ʈ   Ϸ   ⶧
        û URI شϴ <code>ServerPath</code> ִ ã´.
        Ͽ   ã θ ϰ,  ȣƮ
        û Ѵ.</p>
    
        <p>ϴ ȣƮ ã  ٸ, (̹ տ ߵ)
        Ŭ̾Ʈ  IP  Ͽ ġϴ Ʈ ȣ
        ϴ ù° ȣƮ û Ѵ.</p>
    
        
    
        <h3><a name="persistent" id="persistent"> </a></h3>
    
        <p>IP  ѵ Ư TCP/IP Ǵ <em>ѹ</em>
        ã, ̸ KeepAlive/ ᵿ <em></em> û
        ã´. , Ŭ̾Ʈ  ᵿ  ̸
        ȣƮ  û  ִ.</p>
    
        
    
        <h3><a name="absoluteURI" id="absoluteURI"> URI</a></h3>
    
        <p>û URI  URḬ Ŭ̾Ʈ  û
        ȣƮ Ʈ ּ Ư ȣƮ شϸ,
         ּ Ȥ ȣƮ URI  Ŵ/ȣƮ/Ʈ
        κ    URI Ѵ. شϴ
        ּ ȣƮ ٸ URI ״ ΰ û
        Ͻ û óѴ.</p>
    
    
    <h3><a name="observations" id="observations"></a></h3>
    
        <ul>
          <li≯ ȣƮ IP ȣƮ ο
           ʴ´. IP ȣƮ ڽ ̸
         IP ּҿܿ  ּҷε   . ̸
         ȣƮ . ̸ ȣƮ
         <code>NameVirtualHost</code> þ  ּ
         IP ּҸ ؼ   ִ.</li>
    
          <li>IP ȣƮ <code>ServerAlias</code>
          <code>ServerPath</code>  ˻ ʴ´.</li>
    
          <li>Ͽ ̸ ȣƮ, IP ȣƮ,
          <code>_default_</code> ȣƮ, <code>NameVirtualHost</code>
          þ  ߿ ʴ. Ư ּտ 
          ̸ ȣƮ  ߿ϴ. Ͽ
          տ  ̸ ȣƮ ڽ  ּտ
            켱 .</li>
    
          <li>  <code>Host:</code>  Ե Ʈ
          ȣ   ʴ´. ġ ׻ Ŭ̾Ʈ
          û   Ʈ Ѵ.</li>
    
          <li>( ̸  <code>Host:</code>  ٰ
          ϸ,) <code>ServerPath</code> þ Ͽ
          ڿ  ٸ <code>ServerPath</code> þ պκ
          Īϴ  ׻ տ  þ Ѵ.</li>
    
          <li> IP ȣƮ  ּҸ , ׻
          Ͽ տ  ȣƮ Ѵ. ̷ 
          ƹ 𸣰 Ͼ  ִ.  ̷ Ȳ ߰ϸ
           αϿ  Ѵ.</li>
    
          <li><code>_default_</code> ȣƮ û IP ּ<em></em>
          Ʈ ȣ شϴ ȣƮ  û óѴ.
          Ŭ̾Ʈ û  Ʈ ȣ <code>_default_</code>
          ȣƮ Ʈ ȣ(⺻ <code>Listen</code>)
           û óѴ.  Ʈ û̶ 
          (<em> </em>, <code>_default_:*</code>) ϵī
          Ʈ   ִ. <code>NameVirtualHost *</code>
          ȣƮ .</li>
    
          <li>ּ Ŭ̾Ʈ  IP ּҿ Ʈ ȣ
          شϴ (<code>_default_</code> ȣƮ Ͽ)
          ȣƮ  û Ѵ. , ּ
          ( Ʈ شϴ <code>_default_</code> ȣƮ
          ٸ)  ּ/Ʈ ֿ  û óѴ.</li>
    
          <li>Ŭ̾Ʈ (<em> </em>, <code>NameVirtualHost</code>
          þ) ̸ ȣƮ ּ( Ʈ) 
           <code>Host:</code>    ų  
          û  û <em></em> <code>_default_</code>
          ȣƮ ּ ó ʴ´.</li>
    
          <li>Ҷ  DNS   
          <code>VirtualHost</code> þ DNS ̸ .
          Դٰ    DNS  ʴ´ٸ
          Ȼ 赵 ִ. ̿  <a href="../dns-caveats.html"></a> ִ.</li>
    
          <li> ȣƮ <code>ServerName</code> ׻
          ؾ Ѵ. ȱ׷ ȣƮ DNS ã ȴ.</li>
          </ul>
          
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips"></a></h2>
    
        <p><a href="../dns-caveats.html#tips">DNS </a> 
         ߰ Ʒ  ִ:</p>
    
        <ul>
          <li> ּ Ǹ <code>VirtualHost</code>  տ
          ξ. (׷  б ϴ. ȱ׷ ߿ 
           ȣƮ ̿  ǰ  ȣƮ
             ֱ⶧ ȥ.)</li>
    
          <li>б ϵ  شϴ <code>NameVirtualHost</code>
          <code>VirtualHost</code> ǵ .</li>
    
          <li><code>ServerPath</code> ٸ <code>ServerPath</code>
          պκ Īϴ 츦 ϶.   ٸ Ͽ
          պκ   ( ڼ) ȣƮ ª ( ڼ)
          ȣƮ տ ξ. (<em> </em>,
          "ServerPath /abc" "ServerPath /abc/def"  ξ
          Ѵ.</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/vhosts/details.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/details.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/examples.html.tr.utf8�����������������������������������������������0000664�0001751�0001751�00000063675�14743132254�022420� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Sanal Konak Örnekleri - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Sanal Konaklar</a></div><div id="page-content"><div id="preamble"><h1>Sanal Konak Örnekleri</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Bu belgede <a href="index.html">sanal konaklarla</a> ile ilgili olarak
          karşılaşılması olası tüm  senaryolara yer verilmeye çalışılmıştır.
          Buradaki senaryolar, tek bir  sunucu üzerinde  <a href="name-       based.html">isme dayalı</a> veya <a href="ip-based.html">IP’ye dayalı</a>
          sanal konaklar aracılığıyla çok sayıda sitenin sunumu ile ilgilidir.
        </p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#purename">Tek bir IP ile çok sayıda isme dayalı site</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#twoips">IP adresleri farklı çok sayıda isme dayalı site</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#intraextra">Aynı içeriği farklı IP adresleriyle sunmak
        (örn., dahili ve harici ağlara)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#port">Farklı portlarla farklı siteler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ip">IP’ye dayalı sanal konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipport">Hem IP’ye hem de porta dayalı sanal konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mixed">Hem isme hem de IP‘ye dayalı sanal konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#proxy"><code>Virtualhost</code> ve
        <code>mod_proxy</code>’nin birlikte kullanımı</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#default"><code>_default_</code> sanal konakları</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#migrate">Bir isme dayalı sanal konağı bir IP’ye dayalı
        sanal konakla yansılamak</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#serverpath"><code>ServerPath</code> yönergesinin kullanımı</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="purename" id="purename">Tek bir IP ile çok sayıda isme dayalı site</a></h2>
        
    
        <p>Bu örnekte, makinenizin tek bir IP adresine çözümlenen çok sayıda konak 
          adına sahip olduğunu, <code>example.com</code> ve 
          <code>example.org</code> gibi farklı isimlere farklı yanıtlar vermek 
          istediğinizi varsayalım.</p>
        
        <div class="note"><h3>Bilginize</h3><p>Apache sunucusu üzerinde sanal konakları
          yapılandırmakla bu konak isimleri için sihirli bir şekilde DNS
          kayıtlarının da oluşturulmasını sağlamış olmazsınız. Bu isimler için
          ilgili DNS kayıtlarında sizin IP adresinize çözümlenen A kayıtlarının
          olması gerekir, yoksa sitenize kimse erişemez. Sitelere erişimi yerel
          olarak denemek isterseniz, bu girdileri <code>hosts</code> dosyanıza
          yazabilirsiniz. Fakat bu sadece sizin makinenizde çalışır. Yerel
          ağınızdaki her makinenin <code>hosts</code> dosyasına bu girdileri
          yazarak yerel ağdan erişimi bu yolla sağlayabilirsiniz ama dış ağdan
          gelecek ziyaretçileriniz için DNS kayıtlarınızın olması şarttır.</p>
        </div>
    
        <pre class="prettyprint lang-config"># Apache’nin 80. portu dinlediğinden emin olalım
    Listen 80
    &lt;VirtualHost *:80&gt;
      DocumentRoot "/siteler/ecom"
      ServerName example.com
    
      # Diğer yönergeler, burada ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
      DocumentRoot "/siteler/eorg"
      ServerName example.org
    
      # Diğer yönergeler, burada ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Yıldız imleri tüm adreslerle eşleşmeyi sağladığından ana sunucu
          (yapılandırma dosyası genelindeki yapılandırma - sunucu geneli)
          erişilebilir olmayacaktır. Yapılandırma
          dosyasındaki <code>ServerName example.com</code> yönergeli konak, ilk
          sanal konak olduğundan en yüksek önceliğe sahiptir ve
          <cite>öntanımlı</cite> veya <cite>baskın</cite> site olarak davranır.
          Yani, hiçbir <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> yönergesi 
          ile eşleşmeyen bir istek alındığında bu istek ilk <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> yapılandırması ile
          karşılanır.</p>
        
        <p>Yukarıdaki yapılandırmayı hemen hemen tüm isme dayalı sanal konaklar
          için kullanabilirsiniz. Bu yapılandırmanın çalışmayacağı tek durum,
          farklı içerikleri farklı IP adres veya portlardan sunma gereğiyle
          karşılaşmaktır.</p>
    
        <div class="note"><h3>Bilginize</h3>
          <p><code>*</code> yerine sisteminizdeki belli bir IP adresini 
            yazabilirsiniz. Böyle sanal konaklar sadece, HTTP isteklerinin sadece 
            belirtilen IP adreslerinden alınması için kullanilabilir.</p>
    
          <pre class="prettyprint lang-config">NameVirtualHost 192.168.1.22
    
    &lt;VirtualHost 192.168.1.22&gt;
      # vs. ...
    &lt;/VirtualHost&gt;</pre>
    
    
          <p>Bununla birlikte, IP adresinin önceden kestirilebilir olmadığı
            sistemlerde, örneğin, hizmet sağlayıcınıza çevirmeli ağ ile bağlanıyor
            ve onun rasgele atadığı bir IP adresi için bir devingen DNS çözümü
            kullanıyorsanız, IP adresi değil de <code>*</code> kullanmak daha çok
            işinize yarayacaktır. Yıldız imi her IP adresi ile eşleşeceğinden IP
            adresiniz değişse bile bu yapılandırmayı değiştirmeden
            kullanabilirsiniz.</p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="twoips" id="twoips">IP adresleri farklı çok sayıda isme dayalı site</a></h2>
        
    
        <div class="note"><h3>Bilginize</h3>
          <p>Burada açıklanan teknikler istendiği kadar çok IP adresine
            genişletilebilir.</p>
        </div>
    
        <p>Sunucunun iki IP adresi olsun. Birinden "ana sunucu"
          (<code>192.168.1.2</code>) diğerinden <code>example.com</code>
          <code>192.168.2.2</code> hizmet versin. Bu arada başka sanal konakları
          da sunabilelim istiyoruz.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    
    # Bu, 192.168.1.2 adresindeki "ana sunucu" olsun
    ServerName sunucu.example.com
    DocumentRoot "/siteler/anasunucu"
    
    &lt;VirtualHost 192.168.1.20&gt;
        DocumentRoot "/siteler/ecom"
        ServerName example.com
    
        # Diğer yönergeler, burada ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 192.168.1.20&gt;
        DocumentRoot "/siteler/eorg"
        ServerName example.org
    
        # Diğer yönergeler, burada ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p><code>192.168.1.20</code> adresinden gelmeyen tüm isteklere ana sunucu
          (<code>sunucu.example.com</code>), <code>192.168.1.20</code> adresinden
          gelen sunucu ismi belirtmeyenler ile <code>Host:</code> başlığı
          belirtmeyenlere ise  <code>example.com</code> hizmet verecektir.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intraextra" id="intraextra">Aynı içeriği farklı IP adresleriyle sunmak
        (örn., dahili ve harici ağlara)</a></h2>
    
        <p>Sunucu makine iki IP adresine sahip olsun. Biri iç ağa
          (<code>192.168.1.1</code>) diğeri dış ağa (<code>172.20.30.40</code>)
          bakıyor olsun. <code>sunucu.example.com</code> ismi dış ağda dış ağa
          bakan IP’ye, iç ağda ise iç ağa bakan IP’ye çözümleniyor olsun.</p>
    
        <p>Bu durumda, sunucu hem iç hem de dış ağdan gelen isteklere aynı içerik,
          dolayısıyla aynı <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümü ile hizmet verebilir.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 192.168.1.1 172.20.30.40&gt;
        DocumentRoot "/siteler/sunucu"
        ServerName sunucu.example.com
        ServerAlias sunucu
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Artık, hem iç hem de dış ağdan gelen isteklere aynı
          <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 
          bölümünden hizmet sunulacaktır.</p>
    
        <div class="note"><h3>Bilginize:</h3>
          <p>İç ağdan istek yapan biri, tam nitelenmiş konak ismi
            <code>sunucu.example.com</code> yerine makine ismini
            (<code>sunucu</code>) kullanabilir (<code>ServerAlias sunucu</code>
            satırına dikkat).</p>
    
          <p>Ayrıca, yukarıdaki gibi iki ayrı IP adresi belirtmek yerine sadece
            <code>*</code> belirtmekle sunucunun tüm IP adreslerine yine aynı
            içerikle yanıt vereceğine dikkat ediniz.</p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="port" id="port">Farklı portlarla farklı siteler</a></h2>
    
        <p>Aynı IP adresine sahip çok sayıda konak ismine sahip olduğunuzu ve
          bunların bazılarının farklı portları kullanmasını istediğinizi
          varsayalım. Aşağıdaki örnekte, isim eşleşmesinin, en iyi eşleşen IP
          adresi ve port çifti saptandıktan sonra yer alması gösterilmiştir. </p>
    
        <pre class="prettyprint lang-config">Listen 80
    Listen 8080
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        ServerName example.com
        DocumentRoot "/siteler/ecom-80"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        ServerName example.com
        DocumentRoot "/siteler/ecom-8080"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        ServerName example.org
        DocumentRoot "/siteler/eorg-80"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        ServerName example.org
        DocumentRoot "/siteler/eorg-8080"
    &lt;/VirtualHost&gt;</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ip" id="ip">IP’ye dayalı sanal konaklar</a></h2>
    
        <p>Sunucu makinenin, biri <code>example.com</code> adından çözümlenen
          <code>172.20.30.40</code>, diğeri <code>example.org</code> adından
          çözümlenen <code>172.20.30.50</code> diye iki IP adresi olsun.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/siteler/ecom"
        ServerName example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/siteler/eorg"
        ServerName example.org
    &lt;/VirtualHost&gt;</pre>
    
    
        <p><code>&lt;VirtualHost&gt;</code> yönergelerinde belirtilmeyen
          adreslerle yapılan isteklere (örneğin, <code>localhost</code>) sunucu
          genelindeki yapılandırma ile ana sunucu yanıt verecektir.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipport" id="ipport">Hem IP’ye hem de porta dayalı sanal konaklar</a></h2>
        
    
        <p>Sunucu makinenin, biri <code>example.com</code> adından çözümlenen
          <code>172.20.30.40</code>, diğeri <code>example.org</code> adından
          çözümlenen <code>172.20.30.50</code> diye iki IP adresi olsun ve iki
          konak da hem 80 hem de 8080 portlarında çalışsınlar istiyoruz.</p>
    
        <pre class="prettyprint lang-config">Listen 172.20.30.40:80
    Listen 172.20.30.40:8080
    Listen 172.20.30.50:80
    Listen 172.20.30.50:8080
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        DocumentRoot "/siteler/ecom-80"
        ServerName example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        DocumentRoot "/siteler/ecom-8080"
        ServerName example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:80&gt;
        DocumentRoot "/siteler/eorg-80"
        ServerName example.org
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:8080&gt;
        DocumentRoot "/siteler/eorg-8080"
        ServerName example.org
    &lt;/VirtualHost&gt;</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mixed" id="mixed">Hem isme hem de IP‘ye dayalı sanal konaklar</a></h2>
        
    
        <p>Bir <code>VirtualHost</code> yönergesinde belirtilen bir IP adresi başka
          bir sanal konakta görünmüyorsa bu sankon kesinlikle IP'ye dayalı bir
          sanal konaktır.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/siteler/ecom"
        ServerName example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/siteler/eorg"
        ServerName example.org
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/siteler/enet"
        ServerName example.net
    &lt;/VirtualHost&gt;
    
    # IP'ye dayalı
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/siteler/eedu"
        ServerName example.edu
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.60&gt;
        DocumentRoot "/siteler/egov"
        ServerName example.gov
    &lt;/VirtualHost&gt;</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy"><code>Virtualhost</code> ve
        <code>mod_proxy</code>’nin birlikte kullanımı</a></h2>
    
        <p>Bu örnekte bir arabirimi dışarıya bakan bir makinede, başka bir
          makinede çalışan bir sunucuya sanal konak olarak, bir vekil sunucu
          çalıştırmak istediğimizi varsayıyoruz. <code>192.168.111.2</code> IP
          adresli bir makinede aynı isimde bir sanal konak yapılandırılmış olsun.
          Çok sayıda konak ismi için vekil olarak tek bir makine kullandığımızdan
          ve konak isminin de aktarılmasını arzuladığımızdan <code class="directive"><a href="../mod/mod_proxy.html#proxypreservehost">ProxyPreserveHost
          On</a></code> yönergesini kullandık.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost *:*&gt;
        ProxyPreserveHost On
        ProxyPass        "/" "http://192.168.111.2/"
        ProxyPassReverse "/" "http://192.168.111.2/"
        ServerName konak.example.com
    &lt;/VirtualHost&gt;</pre>
    
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="default" id="default"><code>_default_</code> sanal konakları</a></h2>
    
        <h3><a name="defaultallports" id="defaultallports">Tüm portlar için <code>_default_</code></a></h3>
          
    
        <p>Bir IP adresi ve port belirtilmeyen veya hiçbir sanal konağın hiçbir
          adresi/portu ile eşleşmeyen istekleri yakalamak istersek...</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:*&gt;
        DocumentRoot "/siteler/default"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Bütün portlarla eşleşen böyle bir öntanımlı sanal konağın kullanımı
          hiçbir isteğin ana sunucuya gitmemesi sonucunu doğurur.</p>
    
        <p>Bir öntanımlı sanal konak, asla, isme dayalı sanal konaklar için
          kullanılmış bir adrese/porta gönderilmiş bir isteğe hizmet sunmaz. Eğer
          istek bilinmeyen bir <code>Host:</code> başlığına sahipse veya hiç
          <code>Host:</code> başlığı içermiyorsa isteğe daima ilk (yapılandırma
          dosyasındaki ilk) isme dayalı sanal konak hizmet sunar.</p>
    
        <p>Her isteği tek bir bilgilendirme sayfasına (veya betiğe) yönlendirmek
          isterseniz <code class="directive"><a href="../mod/mod_alias.html#aliasmatch">AliasMatch</a></code> veya
          <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> yönergesini
          kullanabilirsiniz.</p>
        
    
        <h3><a name="defaultdifferentports" id="defaultdifferentports">Farklı portlardan <code>_default_</code></a></h3>
          
    
        <p>Önceki yapılandırmaya ek olarak 80. portta ayrı bir
          <code>_default_</code> sanal konağı kullanmak istersek...</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:80&gt;
        DocumentRoot "/siteler/default80"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost _default_:*&gt;
        DocumentRoot "/siteler/default"
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>80. porttan hizmet sunan <code>_default_</code> sanal konağı IP adresi
          belirtilmeyen tüm istekleri yakalar, bunu yapabilmesi için yapılandırma
          dosyasında tüm portlara hizmet sunan benzerinden önce yer almalıdır. Bu
          durumda ana sunucu hiçbir isteğe yanıt vermeyecektir.</p>
        
    
        <h3><a name="defaultoneport" id="defaultoneport">Tek portluk <code>_default_</code></a></h3>
          
    
        <p><code>_default_</code> sanal konağının sadece 80. porttan hizmet
          sunmasını istersek...</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:80&gt;
        DocumentRoot "/siteler/default"
        ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>80. porttan gelen IP adresi belirtilmemiş isteklere
          <code>_default_</code> sanal konağı, diğer portlardan gelen adres
          belirtilmemiş isteklere ise ana sunucu hizmet verecektir.</p>
    
        <p>Bir sanal konak bildiriminde <code>*</code> kullanımı
          <code>_default_</code> kullanımından daha yüksek öncelik sağlar.</p>
       
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="migrate" id="migrate">Bir isme dayalı sanal konağı bir IP’ye dayalı
        sanal konakla yansılamak</a></h2>
    
        <p>İsme dayalı sanal konak örneklerinin <a href="#twoips">2. sinde</a> adı
          geçen <code>example.org</code> bu örnekte kendi IP adresinden hizmet
          veriyor olsun. İsme dayalı sanal konağı eski IP adresiyle kaydetmiş
          vekiller ve isim sunucularından kaynaklanacak olası sorunlardan kaçınmak
          için yansılama sırasında sanal konağı hem eski hem de yeni IP adresiyle
          sunmamız lazım.</p>
    
        <p>Çözüm kolay, çünkü yapacağımız sadece <code>VirtualHost</code>
          yönergesine yeni IP adresini (<code>192.168.1.2</code>) eklemek
          olacak.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    ServerName example.com
    DocumentRoot "/siteler/ecom"
    
    &lt;VirtualHost 192.168.1.20 192.168.1.2&gt;
        DocumentRoot "/siteler/eorg"
        ServerName example.org
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 192.168.1.20&gt;
        DocumentRoot "/siteler/enet"
        ServerName example.enet
        ServerAlias *.example.net
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Böylece sanal konağa hem yeni (bir IP’ye dayalı sanal konak olarak)
          hem de eski adresinden (bir isme dayalı sanal konak olarak)
          erişilebilecektir.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="serverpath" id="serverpath"><code>ServerPath</code> yönergesinin kullanımı</a></h2>
        
    
        <p>İsme dayalı iki sanal konağı olan bir sunucumuz olsun. Doğru sanal
          konağa erişebilmek için istemcinin doğru <code>Host:</code> başlığı
          göndermesi gerekir. Eski HTTP/1.0 istemcileri böyle bir başlık
          göndermedikleri için Apache istemcinin hangi sanal konağa erişmek
          istediğini bilemez (ve isteğe ilk sanal konaktan hizmet sunar). Daha iyi
          bir geriye uyumluluk sağlamak için isme dayalı sanal konağa bir önek
          bağlantısı içeren bir bilgilendirme sayfası sunmak üzere yeni bir sanal
          konak oluşturabiliriz.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 172.20.30.40&gt;
        # ilk sanal konak
        DocumentRoot "/siteler/baska"
        RewriteEngine On
        RewriteRule "." "/siteler/baska/index.html"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot /siteler/baska/bir
        ServerName "bir.baska.tld"
        ServerPath "/bir/"
        RewriteEngine On
        RewriteRule "^(/bir/.*) /siteler/baska$1"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/siteler/baska/iki"
        ServerName iki.baska.tld
        ServerPath "/iki/"
        RewriteEngine On
        RewriteRule "^(/iki/.*)" "/siteler/baska$1"
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code> yönergesinden dolayı
          <code>http://bir.baska.tld/bir/</code> şeklinde yapılan isteklere
          <em>daima</em> “bir” sanal konağı hizmet sunacaktır.</p>
    
        <p><code>http://bir.baska.tld/</code> şeklinde yapılan isteklere ise
          istemcinin doğru <code>Host:</code> başlığı göndermesi şartıyla
          “bir” sanal konağı hizmet sunacaktır. İstemci, bir
          <code>Host:</code> başlığı göndermediği takdirde ilk konaktan bir
          bilgilendirme sayfası alacaktır.</p>
    
        <p>Yalnız buradaki bir tuhaflığa dikkat edin: Eğer istemci bir
          <code>Host:</code> başlığı göndermeden
          <code>http://iki.baska.tld/bir/</code> şeklinde bir istek yaparsa bu
          isteğe de “bir” sanal konağı hizmet sunacaktır.</p>
    
        <p><code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> yönergesi, bir
          istemcinin, bir URL öneki belirtsin ya da belirtmesin doğru
          <code>Host:</code> başlığı gönderdiğinden emin olmak için
          kullanılmıştır.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/examples.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html.ja.utf8��������������������������������������������������0000664�0001751�0001751�00000021723�14743132254�021642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache バーチャルホスト説明書 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache バーチャルホスト説明書</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    
        <p><cite>バーチャルホスト</cite>という用語は、1 台のマシン上で
        (<code>www.company1.com</code> and <code>www.company2.com</code> のような)
        二つ以上のウェブサイトを扱う運用方法のことを指します。
        バーチャルホストには、各ウェブサイトに違う IP アドレスがある
        「<a href="ip-based.html">IP ベース</a>」と、それぞれの IP アドレスに
        複数の名前がある「<a href="name-based.html">名前ベース</a>」とがあります。
        複数のサイトが物理的に同じサーバで扱われている、ということはエンドユーザには
        明らかではありません。</p>
    
        <p>Apache は、特に手を入れない状態で IP ベースのバーチャルホスト
        をサポートした最初のサーバの一つです。バージョン 1.1 以降の Apache
        では、IP ベースとネームベースのバーチャルホストの両方をサポート
        しています。ネームベースのバーチャルホストは、<em>ホストベース</em>あるいは
        <em>非 IP ベース</em>のバーチャルホストと呼ばれることもあります。</p>
    
        <p>以下のページでは、Apache バージョン 1.3
        以降でのバーチャルホストのサポートについての詳細を説明します。</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#support">バーチャルホストのサポート</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#directives">設定ディレクティブ</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li><li><a href="name-based.html">ネームベースのバーチャルホスト</a></li><li><a href="ip-based.html">IP ベースのバーチャルホスト</a></li><li><a href="examples.html">バーチャルホストの一般的な設定例</a></li><li><a href="fd-limits.html">ファイル記述子の限界</a></li><li><a href="mass.html">大量のバーチャルホストの設定</a></li><li><a href="details.html">バーチャルホストのマッチングについての詳細</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">バーチャルホストのサポート</a></h2>
    
        <ul>
          <li><a href="name-based.html">ネームベースのバーチャルホスト</a>
          (一つの IP アドレスに複数のウェブサイト)</li>
          <li><a href="ip-based.html">IP ベースのバーチャルホスト</a>
          (各ウェブサイトに IP アドレス)</li>
          <li><a href="examples.html">バーチャルホストの一般的な設定例</a></li>
          <li><a href="fd-limits.html">ファイル記述子の限界</a>
          (または、<em>多過ぎるログファイル</em>)</li>
          <li><a href="mass.html">大量のバーチャルホストの設定</a></li>
          <li><a href="details.html">バーチャルホストのマッチングについての詳細</a></li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="directives" id="directives">設定ディレクティブ</a></h2>
    
        <ul>
          <li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li>
        </ul>
    
        <p>バーチャルホストの設定のデバッグをするには
        Apache のコマンドラインスイッチ <code>-S</code> が便利です。
        つまり、以下のコマンドを入力します:</p>
    
        <div class="example"><p><code>
        /usr/local/apache2/bin/httpd -S
        </code></p></div>
    
        <p>このコマンドは Apache が設定ファイルをどう解析したかについて出力します。
        IP アドレスとサーバ名を注意深く調べれば、
        設定の間違いを見つける助けになるでしょう。
        (他のコマンドラインのオプションは <code class="program"><a href="../programs/httpd.html">httpd</a></code>
        プログラムの説明文書を見てください)</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������httpd-2.4.64/docs/manual/vhosts/ip-based.html.ja.utf8�����������������������������������������������0000664�0001751�0001751�00000033711�14743132254�022217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache の IP ベースのバーチャルホストサポート - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">バーチャルホスト</a></div><div id="page-content"><div id="preamble"><h1>Apache の IP ベースのバーチャルホストサポート</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#requirements">システム要件</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#howto">Apache の設定方法</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multiple">複数デーモンの設定</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#single">複数のバーチャルホストの設定をした
    デーモンを一つ設定する</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li>
    <a href="name-based.html">名前ベースのバーチャルホストサポート</a>
    </li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">システム要件</a></h2>
    
        <p><cite>IP ベース</cite> という名前が示すように、サーバには
        <strong>IP ベースのバーチャルホストそれぞれにつき、別々の IP アドレスが
        必要です</strong>。複数の物理コネクションを持っているマシンを用意するか、
        最近のオペレーティングシステムでサポートされているバーチャル
        インタフェース (詳細はシステムの説明書を読んでください。たいていは
        "ip エイリアス" と呼ばれていて、設定には普通 "ifconfig" コマンドを
        使います) を使うかで実現できます。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">Apache の設定方法</a></h2>
    
        <p>複数のホストをサポートするように Apache を設定する方法は
        二通りあります。別の <code class="program"><a href="../programs/httpd.html">httpd</a></code> デーモンを各ホスト毎に実行するか、
        すべてのバーチャルホストをサポートするデーモンを一つ実行するかです。</p>
    
        <p>以下のときには複数のデーモンを使うと良いでしょう:</p>
    
        <ul>
          <li>会社1 はウェブ経由以外では会社2 からはデータを読まれたくない、
          といったセキュリティの分離の問題があるとき。この場合、それぞれ
          <code class="directive"><a href="../mod/mpm_common.html#user">User</a></code>, <code class="directive"><a href="../mod/mpm_common.html#group">Group</a></code>, <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>, <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> の設定が違う二つのデーモンを
          実行する必要があります。</li>
    
          <li>マシンのすべての IP エイリアスを listen するだけの
          メモリとファイル記述子の余裕があるとき。<code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> は「ワイルドカード」
          アドレスか、特定のアドレスのみを listen することができます。
          ですから、何らかの理由で特定のアドレスを listen しなけばならない
          ときは、その特定のアドレスをすべて listen する必要があります。
          (ただし、一つの <code class="program"><a href="../programs/httpd.html">httpd</a></code> が N-1 個のアドレスを listen し、
          別の <code class="program"><a href="../programs/httpd.html">httpd</a></code> が残りのアドレスを listen するといったことは可能です。)</li>
        </ul>
    
        <p>以下のときには単独のデーモンを使うと良いでしょう:</p>
    
        <ul>
          <li>バーチャルホスト間での httpd の設定を共有してもよいとき。</li>
    
          <li>マシンが多くのリクエストを扱うため、別デーモンを実行することによる
          性能の低下の影響が著しいとき。</li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multiple" id="multiple">複数デーモンの設定</a></h2>
    
        <p>各バーチャルホストに対して別の <code class="program"><a href="../programs/httpd.html">httpd</a></code> のインストールを行ないます。
        設定ファイル中の <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> 
        ディレクティブを使って、
        各インストールでデーモンが扱う IP アドレス (バーチャルホスト) 
        を選択します。例えば</p>
    
        <div class="example"><p><code>
        Listen www.smallco.com:80
        </code></p></div>
    
        <p>ここで、ホスト名の代わりに IP アドレスを使う方が推奨されていることに
        注意しておいてください
        (<a href="../dns-caveats.html">DNS の注意事項</a> 参照)。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="single" id="single">複数のバーチャルホストの設定をした
    デーモンを一つ設定する</a></h2>
    
        <p>この場合は、一つの <code class="program"><a href="../programs/httpd.html">httpd</a></code> が主サーバとすべてのバーチャルホストのリクエストを
        処理します。設定ファイルの <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> ディレクティブを使って、
        <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>, <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>, <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>, <code class="directive"><a href="../mod/core.html#errorlog">ErrorLog</a></code>, <code class="directive"><a href="../mod/mod_log_config.html#transferlog">TransferLog</a></code>
        や <code class="directive"><a href="../mod/mod_log_config.html#customlog">CustomLog</a></code>
        設定ディレクティブの値が各ホスト毎に異なる値に設定されるようにします。
        例えば</p>
    
        <div class="example"><p><code>
        &lt;VirtualHost www.smallco.com&gt;<br />
        ServerAdmin webmaster@mail.smallco.com<br />
        DocumentRoot /groups/smallco/www<br />
        ServerName www.smallco.com<br />
        ErrorLog /groups/smallco/logs/error_log<br />
        TransferLog /groups/smallco/logs/access_log<br />
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost www.baygroup.org&gt;<br />
        ServerAdmin webmaster@mail.baygroup.org<br />
        DocumentRoot /groups/baygroup/www<br />
        ServerName www.baygroup.org<br />
        ErrorLog /groups/baygroup/logs/error_log<br />
        TransferLog /groups/baygroup/logs/access_log<br />
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>ここで、ホスト名の代わりに IP アドレスを使う方が推奨されていることに
        注意しておいてください
        (<a href="../dns-caveats.html">DNS の注意事項</a> 参照)。</p>
    
        <p>プロセス生成を制御するディレクティブやその他のいくつかのディレクティブを
        除いて、ほぼ<strong>すべて</strong>の設定ディレクティブを VirtualHost
        ディレクティブの中に書くことができます。ディレクティブが VirtualHost
        ディレクティブで使用できるかどうかは <a href="../mod/directives.html">ディレクティブ索引</a>を使って<a href="../mod/directive-dict.html#Context">コンテキスト</a>の
        欄を調べてください。</p>
    
        <p><a href="../suexec.html">suEXECラッパー</a>を使っている場合は、
        <code class="directive"><a href="../mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code>
        ディレクティブを VirtualHost
        ディレクティブの中で使用することができます。</p>
    
        <p><em>セキュリティ:</em> ログファイルを書く場所を指定するときは、
        Apache を起動したユーザ以外がそのディレクトリに書き込み権限を
        持っている場合にセキュリティ上の危険があることに注意してください。
        詳細は<a href="../misc/security_tips.html">セキュリティのこつ</a>ドキュメントを
        参照してください。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/ip-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/mass.html.tr.utf8���������������������������������������������������0000664�0001751�0001751�00000046716�14743132254�021542� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Devingen olarak Yapılandırılan Kitlesel Sanal Barındırma - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Sanal Konaklar</a></div><div id="page-content"><div id="preamble"><h1>Devingen olarak Yapılandırılan Kitlesel Sanal Barındırma</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/mass.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Bu belgede sanal konakların sonu belirsiz bir şekilde artışı karşısında
          Apache HTTP Sunucusunun nasıl daha verimli kullanılacağı açıklanmıştır.
          Devingen kitlesel konakları oluşturmak için <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
          modülünün kullanımını açıklayan <a href="../rewrite/vhosts.html">ayrı bir
          belge</a> de mevcuttur.
        </p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#motivation">Amaç</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#overview">Genel Bakış</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple">mod_vhost_alias ile Kitlesel Sanal Konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#homepages">Basitleştirilmiş Kitlesel Sanal Konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#combinations">Aynı Sunucuda Kişisel ve Kurumsal Sanal Konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipbased">IP’ye dayalı sanal konakları daha verimli kılmak</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple.rewrite"><code>mod_rewrite</code> ile Kitlesel Sanal Konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#macro"><code>mod_macro</code> ile Kitlesel Sanal Konaklar</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="motivation" id="motivation">Amaç</a></h2>
    
        <p>Burada açıklanan teknikler, <code>httpd.conf</code> dosyanızın
          örnekteki gibi, aslında hemen hemen birbirinin aynı çok sayıda
          <code>&lt;VirtualHost&gt;</code> bölümü içereceği zaman yapılacaklar ile
          ilgilidir.</p>
    
    <pre class="prettyprint lang-config">&lt;VirtualHost 111.22.33.44&gt;
        ServerName                 musteri-1.example.com
        DocumentRoot        "/siteler/musteri-1/belgeler"
        ScriptAlias  "/cgi-bin/"  "/siteler/musteri-1/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName                 musteri-2.example.com
        DocumentRoot        "/siteler/musteri-2/belgeler"
        ScriptAlias   "/cgi-bin/"   "/siteler/musteri-2/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName                 musteri-N.example.com
        DocumentRoot          "/siteler/musteri-N/belgeler"
        ScriptAlias   "/cgi-bin/"  "/siteler/musteri-N/cgi-bin"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>İsteğimiz çok sayıda <code>&lt;VirtualHost&gt;</code> bölümünü devingen
          olarak çalışan tek bir <code>&lt;VirtualHost&gt;</code> bölümüyle
          değiştirmektir. Bunun elbette bazı getirileri olacaktır:</p>
    
        <ol>
          <li>Yapılandırma dosyanız küçüleceği için Apache daha çabuk
            başlatılabilecek ve daha az bellek harcayacaktır. Muhtemelen daha da
            önemlisi, küçülmüş bir yapılandırmanın bakımı da kolaylaşacağı için
            hatalar da azalacaktır.</li>
    
          <li>Yeni sanal konakların eklenmesi, DNS’de yeni girdiler oluşturmak ve
            dosya sisteminde bununla ilgili dizinleri açmak dışında biraz daha
            basit olacaktır; en azından Apache’yi yeniden yapılandırmak ve yeniden
            başlatmak zorunda kalmayacaksınız.</li>
        </ol>
    
        <p>Ana götürüsü ise her sanal konak için ayrı birer günlük dosyasına sahip
          olamayacak olmanızdır. Öte yandan, <a href="fd-limits.html">dosya
          tanıtıcılarının sınırlı olması</a>  nedeniyle bunu yapmayı zaten
          istemezsiniz. Günlük kayıtları için bir <a href="../logs.html#piped">fifo
          veya bir boru hattı</a> oluşturmak ve diğer uçta çalışan bir süreç
          vasıtasıyla günlükleri müşterilere paylaştırmak daha iyidir. Böyle bir
          işlemle ilgili bir örneği <a href="../programs/split-logfile.html">split-logfile</a> aracının belgesinde bulabilirsiniz.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Genel Bakış</a></h2>
    
        <p>Bir sanal konak iki bilgiye bakarak belirlenir: IP adresi ve HTTP
          isteğindeki <code>Host:</code> başlığının içeriği. Devingen sanal
          barındırma tekniği, isteği yerine getirmek için kullanılacak dosya
          yoluna bu bilgiyi kendiliğinden girmek esasına dayanır. Bu, Apache httpd
          ile <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> modülünü kullanarak oldukça kolay
          yapılabileceği gibi <a href="../rewrite/vhosts.html">mod_rewrite modülü
          de kullanılabilir</a>.</p>
    
        <p>Bu modüllerin her ikisi de öntanımlı olarak devre dışıdır. Bu tekniği
          kullanmak isterseniz  Apache httpd'yi yeniden yapılandırıp derleyerek bu
          iki modülü etkin duruma getirmeniz gerekir.</p>
    
        <p>Devingen sanal konağı normal bir sanal konak gibi göstermek için
          bazı bilgileri istekten saptamak gerekir. Bunlardan en önemlisi,
          httpd tarafından göreli URL’lerden normal URL’leri ve benzerlerini
          üretmek için kullanılan sunucu ismidir. Sunucu ismi
          <code>ServerName</code> yönergesi ile yapılandırılır ve CGI’ler
          tarafından <code>SERVER_NAME</code> ortam değişkeni üzerinden
          kullanılır. Çalışma anındaki asıl değer <code class="directive"><a href="../mod/core.html#usecanonicalname">UseCanonicalName</a></code> yönergesi tarafından denetlenir.
          <code>UseCanonicalName Off</code> olduğunda sunucu ismi isteğin
          <code>Host:</code> başlık alanından elde edilir. <code>UseCanonicalName
          DNS</code> belirtilmişse, sunucu ismi, sanal konağın IP adresinden
          tersine DNS sorgusu yapılarak elde edilir. Birincisi isme dayalı sanal
          konaklar tarafından ikincisi ise IP’ye dayalı sanal konaklar tarafından
          kullanılır. Eğer httpd, istekte <code>Host:</code> başlığının olmayışı
          veya DNS sorgusunun başarısız olması sebebiyle sunucu ismini elde
          edemezse son çare olarak <code>ServerName</code> yönergesinde yazılı
          değeri kullanır.</p>
    
        <p>Saptanan bilgilerden biri de <code>DocumentRoot</code>
          yönergesi ile yapılandırılan belge kök dizini olup CGI’ler tarafından
          <code>DOCUMENT_ROOT</code> ortam değişkeni üzerinden kullanılır. Normal
          yapılandırmada <code class="module"><a href="../mod/core.html">core</a></code> modülü tarafından dosya isimlerini
          URI’lere eşlerken kullanılır. Fakat sunucu devingen sanal konakları
          kullanmak üzere yapılandırıldığında, eşleştirmeyi farklı yollardan yapan
          başka bir modül devreye girer (<code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> veya
          <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>). <code>DOCUMENT_ROOT</code> ortam
          değişkenine değerini atamaktan sorumlu olan bu iki modülden biri
          kullanılmazsa CGI veya SSI belgeleri yanlış değerlerle üretilirler.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple" id="simple">mod_vhost_alias ile Kitlesel Sanal Konaklar</a></h2>
    
        <p>Yukarıda <a href="#motivation">Amaç</a> bölümünde özetlenen sanal konak
          düzenlemesinin <code>mod_vhost_alias</code> kullanarak gerçekleştirilmiş
          halini içeren <code>httpd.conf</code> bölümü aşağıdadır.</p>
    
    <pre class="prettyprint lang-config"># sunucu ismini Host: başlığından elde edelim
    UseCanonicalName Off
    
    # Bu günlükleme biçiminde split-logfile aracı kullanılarak
    # sanal konak günlükleri ilk alana göre ayrıştırılabilir
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log vcommon"
    
    # istekleri yerine getirmek için kullanılacak
    # dosya isimlerine sunucu ismini ekleyelim
    VirtualDocumentRoot "/siteler/%0/belgeler"
    VirtualScriptAlias  "/siteler/%0/cgi-bin"</pre>
    
    
        <p>Bu yapılandırmayı IP’ye dayalı sanal konaklar için kullanmak isterseniz
          <code>UseCanonicalName Off</code> yerine <code>UseCanonicalName
          DNS</code> yazmanız yeterlidir. Böylece dosya ismine eklenecek konak
          ismi sanal konağın IP adresinden türetilir. <code>%0</code> değişkeni,
          <code>Host:</code> başlığı ile belirlenen istekteki sunucu isminin
          ifadesidir.</p>
    
        <p>Kullanım örnekleri için <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>modülünün
          belgesine bakınız.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="homepages" id="homepages">Basitleştirilmiş Kitlesel Sanal Konaklar</a></h2>
    
        <p>Bu sistem, yukarıdaki yapılandırmanın bir ISS’nin sunucusuna
          uyarlanmasından başka bir şey değildir. <code>%2</code> değişkenini
          kullanarak, dosya isminde kullanmak üzere sunucu isminin alt dizgelerini
          seçebiliriz, böylece, örneğin <code>www.user.example.com</code> belgeleri
          <code>/home/user/www</code> dizininde bulunabilir. Farklı olarak her
          sanal konak için bir tane değil hepsi için bir tane <code>cgi-bin</code>
          olacaktır.</p>
    
        <pre class="prettyprint lang-config">UseCanonicalName Off
    
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log" vcommon
    
    # sunucu ismini içerecek dosya isimlerini oluşturalım
    VirtualDocumentRoot "/home/%2/www"
    
    # ortak cgi-bin dizini
    ScriptAlias  "/cgi-bin/"  "/siteler/std-cgi/"</pre>
    
    
        <p><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> belgesinde daha karmaşık
          <code>VirtualDocumentRoot</code> örnekleri vardır.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="combinations" id="combinations">Aynı Sunucuda Kişisel ve Kurumsal Sanal Konaklar</a></h2>
    
        <p>Daha karmaşık ayarlamalar yaparak httpd’nin normal
          <code>&lt;VirtualHost&gt;</code> bölümlerini farklı kitlesel sanal konak
          yapılandırmaları için kullanabilirsiniz. Örneğin, bireysel
          müşterileriniz için bir IP adresiniz, kurumsal müşterileriniz için de
          başka bir IP adresiniz olsun. Her biri için ayrı ayrı sanal konaklar
          ayarlamak yerine aşağıdaki gibi bir yapılandırma kullanabilirsiniz:</p>
    
    <pre class="prettyprint lang-config">UseCanonicalName Off
    
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    
    &lt;Directory "/siteler/kurumsal"&gt;
        Options FollowSymLinks
        AllowOverride All
    &lt;/Directory&gt;
    
    &lt;Directory "/siteler/bireysel"&gt;
        Options FollowSymLinks
        AllowOverride None
    &lt;/Directory&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName kurumsal.example.com
    
        CustomLog "logs/access_log.kurumsal" vcommon
    
        VirtualDocumentRoot "/siteler/kurumsal/%0/belgeler"
        VirtualScriptAlias  "/siteler/kurumsal/%0/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.45&gt;
        ServerName bireysel.example.com
    
        CustomLog "logs/access_log.bireysel" vcommon
    
        VirtualDocumentRoot "/siteler/bireysel/%0/belgeler"
        ScriptAlias         "/cgi-bin/" "/siteler/std-cgi/"
    &lt;/VirtualHost&gt;</pre>
    
    
        <div class="note"><h3>Bilginize</h3>
          <p>Eğer ilk <code>&lt;VirtualHost&gt;</code> bölümü bir <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> yönergesi içermezse ilgili IP
            için ters DNS sorgusu yapılır. Eğer sorgudan elde edilen isim
            sunucunun ismi değilse bu istenmeyen duruma bir çözüm olarak bir
            bilgilendirme bölümü (örn, <code>ServerName bilgi.example.com</code>)
            eklenebilir.</p>
        </div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipbased" id="ipbased">IP’ye dayalı sanal konakları daha verimli kılmak</a></h2>
        
    
        <p><a href="#simple">İlk örnekte</a> IP’ye dayalı sanal konaklar için
          kullanılmak istenirse yapılandırmada neyin nasıl değiştirileceği
          belirtilmişti. Her istek için ayrı bir DNS sorgusu gerekeceğinden bu
          başarım düşmesine yol açar. DNS sorgusu ihtiyacını ortadan kaldırmak
          için, bir çözüm olarak dosya sistemi, konak isimleri yerine IP
          adreslerine göre düzenlenebilir. Günlük kayıtları da IP adreslerine göre
          ayrıştırılacak şekilde ayarlanabilir.</p>
    
    <pre class="prettyprint lang-config"># Sunucu ismini IP adresinden ters DNS sorgusu ile elde edelim
    UseCanonicalName DNS
    
    # Günlük kayıtları IP adreslerine göre ayrıştırılabilsin
    LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log" vcommon
    
    # dosya isimleri IP adreslerini içersin
    VirtualDocumentRootIP "/siteler/%0/belgeler"
    VirtualScriptAliasIP  "/siteler/%0/cgi-bin"</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple.rewrite" id="simple.rewrite"><code>mod_rewrite</code> ile Kitlesel Sanal Konaklar</a></h2>
        
    
        <p>Kitlesel sanal barındırma <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> modülü kullanarak
          da gerçeklenebilir. Ya basitçe <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> yönergelerini kullanırsınız ya da daha karmaşık
          olarak sanal konak tanımlarınızı harici bir yerde tutar ve bunlara
          <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> yönergesini
          kullanarak erişirsiniz. Bu teknikler ayrıntılı olarak
          <a href="../rewrite/vhosts.html">rewrite belgelerinde</a>
          açıklanmıştır.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="macro" id="macro"><code>mod_macro</code> ile Kitlesel Sanal Konaklar</a></h2>
        
    
        <p>Devingen olarak üretilen sanal konaklar için diğer bir seçenek 
          <code class="module"><a href="../mod/mod_macro.html">mod_macro</a></code> modülüdür. Bir sanal konak şablonu oluşturup 
          bunu çok sayıda konak ismi için çağırabilirsiniz. Modül belgelerinin 
          <strong>Kullanım</strong> bölümünde böyle bir örneğe yer verilmiştir.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/mass.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/mass.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������httpd-2.4.64/docs/manual/vhosts/name-based.html.de��������������������������������������������������0000664�0001751�0001751�00000053001�14744525602�021636� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Unterst&#252;tzung namensbasierter virtueller Hosts - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Module</a> | <a href="../mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossar</a> | <a href="../sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Virtual Hosts</a></div><div id="page-content"><div id="preamble"><h1>Unterst&#252;tzung namensbasierter virtueller Hosts</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="../de/vhosts/name-based.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
      <p>Das Dokument beschreibt, wann und wie namensbasierte virtuelle Hosts zu
        verwenden sind.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#namevip">Namensbasierte gegen&#252;ber IP-basierten
        virtuellen Hosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#using">Die Verwendung von namensbasierten virtuellen Hosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#compat">Kompatibilit&#228;t mit &#228;lteren Browsern</a></li>
    </ul><h3>Siehe auch</h3><ul class="seealso"><li><a href="ip-based.html">Unterst&#252;tzung IP-basierter virtueller
        Hosts</a></li><li><a href="details.html">Tiefergehende Er&#246;rterung der Zuweisung
        virtueller Hosts</a></li><li><a href="mass.html">Dynamisch konfiguriertes
        Massen-Virtual-Hosting</a></li><li><a href="examples.html">Beispiele f&#252;r virtuelle Hosts in typischen
        Installationen</a></li><li><a href="examples.html#serverpath">ServerPath-Beispielkonfiguration</a></li><li><a href="#comments_section">Kommentare</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="namevip" id="namevip">Namensbasierte gegen&#252;ber IP-basierten
        virtuellen Hosts</a></h2>
    
      <p>IP-basierte virtuelle Hosts verwenden die IP-Adresse der Verbindung, um den
        korrekten virtuellen Host zur Bedienung einer Anfrage zu ermitteln. Folglich 
        ben&#246;tigen Sie eine IP-Adresse f&#252;r jeden virtuellen Host. Bei der 
        Verwendung von namensbasierten virtuellen Hosts verl&#228;&#223;t sich der 
        Server darauf, dass der Client den Hostnamen als Bestandteil der HTTP-Header 
        angibt. Durch Anwendung dieser Technik k&#246;nnen sich mehrere verschiedene 
        Hosts die gleiche IP-Adresse teilen.</p>
    
      <p>Die Verwendung von namensbasierten virtuellen Hosts ist gew&#246;hnlich 
        einfacher. Sie m&#252;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&#228;rfen auch den Bedarf an 
        knappen IP-Adressen. Daher sollten Sie namensbasierte virtuelle Hosts 
        verwenden, sofern kein besonderer Grund daf&#252;r existiert, IP-basierte 
        virtuelle Hosts zu w&#228;hlen. M&#246;gliche Gr&#252;nde f&#252;r die 
        Verwendung IP-basierter virtueller Hosts sind:</p>
    
      <ul>
        <li>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&#252;tzung f&#252;r veraltete Clients
          ben&#246;tigen und dennoch namensbasierte virtuelle Hosts verwenden,
          dann finden Sie eine m&#246;gliche L&#246;sung daf&#252;r am Ende des
          Dokuments.</li>
    
        <li>Namensbasierte virtuelle Hosts k&#246;nnen aufgrund der Natur des
          SSL-Protokolls nicht mit SSL-gesicherten Servern verwendet werden.</li>
    
        <li>Einige Betriebssysteme und Netzwerkanlagen setzen Techniken zum 
          Bandbreiten-Management ein, die nicht zwischen Hosts unterscheiden
          k&#246;nnen, wenn diese nicht auf verschiedenen IP-Adressen liegen.</li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Die Verwendung von namensbasierten virtuellen Hosts</a></h2>
    
      <table class="related"><tr><th>Referenzierte Module</th><th>Referenzierte Direktiven</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code></li><li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li><li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li><li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
      <p>Um namensbasierte virtuelle Hosts zu verwenden, m&#252;ssen Sie die
        IP-Adresse (und m&#246;glicherweise den Port) des Servers benennen, an
        der Anfragen f&#252;r die Hosts entgegengenommen werden. Dies wird mit
        der Direktive <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>
        eingestellt. Im Normalfall, wenn alle IP-Adressen des Server verwendet
        werden sollen, k&#246;nnen Sie <code>*</code> als Argument f&#252;r
        <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> verwenden. Wenn Sie
        vorhaben, mehrere Ports zu nutzen (etwa wenn SSL l&#228;uft), sollten
        Sie dem Argument einen Port hinzuf&#252;gen, wie zum Beispiel
        <code>*:80</code>. Beachten Sie,
        dass die Angabe einer IP-Adresse in einer <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>-Anweisung den Server nicht
        automatisch an dieser Adresse lauschen l&#228;&#223;t. Lesen Sie bitte "<a href="../bind.html">Bestimmen der vom Apache verwendeten Adressen und
        Ports</a>" f&#252;r weitere Details. Zus&#228;tzlich muss jede hier
        angegebene IP-Adresse einer Netzwerkkarte des Servers zugeordnet sein.</p>
     
      <p>Der n&#228;chste Schritt ist die Erstellung eines <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Blocks f&#252;r jeden einzelnen
        Host, den Sie bedienen wollen. Das Argument der Direktive <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> sollte das gleiche
        sein wie das Argument der <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>-Anweisung (d.h. eine IP-Adresse
        oder <code>*</code> f&#252;r alle Adressen). Innerhalb jedes <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Blocks ben&#246;tigen
        Sie zumindestens eine <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>-Anweisung, um zu bestimmen, welcher
        Host bedient wird, und eine <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>-Anweisung, um anzugeben, wo im
        Dateisystem der Inhalt des Hosts abgelegt ist.</p>
    
      <div class="note"><h3>Der Hauptserver verschwindet</h3>
        Wenn Sie virtuelle Hosts zu einem bestehenden Webserver hinzuf&#252;gen,
        m&#252;ssen Sie auch einen <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Block f&#252;r den bestehenden Host
        <span class="transnote">(<em>Anm.d.&#220;.:</em> und bisherigen Hauptserver)</span> erstellen. 
        Die <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>- und
        <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>-Anweisungen zu diesem
        virtuellen Host sollten die gleichen sein wie die globalen <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>- und <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>-Anweisungen. F&#252;hren Sie diesen
        virtuellen Host als erstes in der Konfigurationsdatei auf, so dass er als
        Standard-Host fungiert.
      </div>
    
      <p>Vorausgesetzt, Sie bedienen z.B. die Domain
        <code>www.domain.tld</code> und m&#246;chten den virtuellen Host
        <code>www.otherdomain.tld</code> hinzuf&#252;gen, welcher auf
        die gleiche IP-Adresse zeigt. Dann f&#252;gen Sie einfach Folgendes der
        <code>httpd.conf</code> hinzu:</p>
    
        <div class="example"><p><code>
        NameVirtualHost *:80<br />
        <br />
        &lt;VirtualHost *:80&gt;<br />
        <span class="indent">
        ServerName www.domain.tld<br />
        ServerAlias domain.tld *.domain.tld<br />
        DocumentRoot /www/domain<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost *:80&gt;<br />
        <span class="indent">ServerName www.otherdomain.tld<br />
        DocumentRoot /www/otherdomain<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        </code></p></div>
    
      <p>Sie k&#246;nnen anstelle des <code>*</code> bei den beiden Anweisungen 
        <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> und <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 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.</p>
      
      <p>Viele Server wollen unter mehr als einem Namen erreichbar sein. Die 
        Direktive <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>, die innerhalb 
        des <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Abschnittes angegeben wird,
        erm&#246;glicht dies. Zum Beispiel zeigt die <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>-Anweisung in dem ersten <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Block oben an, dass die
        aufgef&#252;hrten Namen alternative Namen sind, die man verwenden kann, um
        das gleiche Webangebot zu erreichen:</p>
    
        <div class="example"><p><code>
        ServerAlias domain.tld *.domain.tld
        </code></p></div>
    
      <p>Anfragen f&#252;r alle Hosts der Domain <code>domain.tld</code> werden
        von dem virtuellen Host <code>www.domain.tld</code> bedient. Die
        Platzhalter <code>*</code> und <code>?</code> k&#246;nnen anstelle
        entsprechender Namen verwendet werden. Nat&#252;rlich k&#246;nnen Sie nicht
        einfach Namen erfinden und diese bei <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> oder <code>ServerAlias</code>
        angeben, Sie m&#252;ssen zun&#228;chst Ihren DNS Server entsprechend
        konfigurieren, dass er diese Namen auf die mit Ihrem Server verkn&#252;pfte
        IP-Adresse abbildet.</p>
    
      <p>Und schlu&#223;endlich k&#246;nnen Sie die Konfiguration der virtuellen
        Hosts mittels Angabe weiterer Direktiven innherhalb der <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Container
        feineinstellen. Die meisten Direktiven k&#246;nnen in diesen Containern
        angegeben werden und ver&#228;ndern dann ausschlie&#223;lich die
        Konfiguration des entsprechenden virtuellen Hosts. Pr&#252;fen Sie den <a href="../mod/directive-dict.html#Context">Kontext</a> einer Direktive, um
        herauszufinden, ob eine bestimmte Direktive zul&#228;ssig ist.
        Im <em>Hauptserver-Kontext</em> (au&#223;erhalb der <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Container) definierte
        Konfigurationsanweisungen werden nur dann angewendet, wenn sie nicht durch
        Einstellungen des virtuellen Hosts au&#223;er Kraft gesetzt wurden.</p>
    
      <p>Wenn nun eine Anfrage eintrifft, pr&#252;ft der Server zuerst, ob sie eine
        IP-Adresse verwendet, die der <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>-Anweisung entspricht. Ist dies der
        Fall, dann sieht er sich jeden <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Abschnitt mit einer passenden
        IP-Adresse an und versucht den einen zu finden, dessen <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>- oder <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>-Anweisung mit dem gew&#252;nschten
        Hostnamen &#252;bereinstimmt. Findet er einen, dann verwendet er die
        Konfiguration dieses Servers. Wird kein passender virtueller Host gefunden,
        dann wird <strong>der erste angegeben virtuelle Host</strong> verwendet,
        dessen IP-Adresse pa&#223;t.</p>
    
      <p>Die Folge davon ist, dass der erste aufgef&#252;hrte virtuelle Host der
        <em>Standard</em>-Virtual-Host ist. Die <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>-Anweisung des <em>Hauptservers</em>
        wird <strong>niemals</strong> verwendet, wenn eine IP-Adresse mit einer 
        <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>-Anweisung
        &#252;bereinstimmt. Wenn Sie eine spezielle Konfiguration f&#252;r Anfragen
        angeben m&#246;chten, die keinem bestimmten virtuellen Host entsprechen,
        packen Sie diese Konfiguration einfach in einen <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>-Container und f&#252;hren diesen als
        erstes in der Konfigurationsdatei auf.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compat" id="compat">Kompatibilit&#228;t mit &#228;lteren Browsern</a></h2>
      
      <p>Wie zuvor erw&#228;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&#252;r
        diese IP-Adresse aufgef&#252;hrten virtuellen Hosts gesendet werden (des
        <cite>prim&#228;ren</cite> namensbasierten virtuellen Hosts).</p>
    
      <div class="note"><h3>Was bedeutet &#228;lter?</h3>
        <p>Beachten Sie bitte, wenn wir von &#228;lter sprechen, meinen wir auch
        &#228;lter. Es ist sehr unwahrscheinlich, dass sie einen dieser Browser
        heutzutage in Verwendung finden werden. Alle aktuellen Browser-Versionen
        senden den <code>Host</code>-Header, so wie er f&#252;r namensbasierte
        virtuelle Hosts ben&#228;&#246;tigt wird.</p>
      </div>
    
      <p>Mit der Direktive <code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code> existiert  
        eine m&#246;gliche Behelfskonstruktion, obgleich sie etwas schwerf&#228;llig
        ist:</p>
    
      <p>Beispielkonfiguration:</p>
    
      <div class="example"><p><code>
        NameVirtualHost 111.22.33.44<br />
        <br />
        &lt;VirtualHost 111.22.33.44&gt;<br />
        <span class="indent">
        ServerName www.domain.tld<br />
        ServerPath /domain<br />
        DocumentRoot /web/domain<br />
        </span>
        &lt;/VirtualHost&gt;<br />
      </code></p></div>
    
      <p>Was bedeutet das? Es bedeutet, dass eine Anfrage f&#252;r eine mit
        "<code>/domain</code>" beginnende URI von dem virtuellen Host
        <code>www.domain.tld</code> bedient wird. Dies hei&#223;t, dass die Seiten
        f&#252;r alle Clients unter <code>http://www.domain.tld/domain/</code>
        abrufbar sind, wenngleich Clients, die den Header <code>Host:</code>
        senden, auch &#252;ber <code>http://www.domain.tld/</code> auf sie zugreifen
        k&#246;nnen.</p>
    
      <p>Legen Sie einen Link auf der Seite Ihres prim&#228;ren virtuellen Hosts zu 
        <code>http://www.domain.tld/domain/</code>, um die Behelfsl&#246;sung
        verf&#252;gbar zu machen. Bei den Seiten der virtuellen Hosts m&#252;ssen
        Sie dann sicherstellen, entweder au&#223;schlie&#223;lich relative Links
        (<em>z.B.</em> "<code>file.html</code>" oder
        "<code>../icons/image.gif</code>") zu verwenden oder Links, die das
        einleitende <code>/domain/</code> enthalten (<em>z.B.</em>,
        "<code>http://www.domain.tld/domain/misc/file.html</code>" oder
        "<code>/domain/misc/file.html</code>").</p>
    
      <p>Dies erfordert etwas Disziplin, die Befolgung dieser Richtlinien stellt
        jedoch gr&#246;&#223;tenteils sicher, dass Ihre Seiten mit allen Browsern
        funktionieren, alten wie neuen.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="../de/vhosts/name-based.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/name-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Module</a> | <a href="../mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossar</a> | <a href="../sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/examples.html.ko.euc-kr���������������������������������������������0000664�0001751�0001751�00000062216�14743132254�022672� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ȣƮ  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">ȣƮ</a></div><div id="page-content"><div id="preamble"><h1>ȣƮ </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    
        <p>   ǵǴ ȣƮ
          Ϸ . Ȳ <a href="name-based.html"≯</a>̳ <a href="ip-based.html">IP</a> ȣƮ   
         Ʈ Ϸ ̴.  Ͻ  ڿ
          Ͽ Ʈ ϴ 츦 ٷ 
          ̴.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#purename">IP ּ Ѱ  ̸
        Ʈ ϱ.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#twoips"> IP ּҿ ̸
        ȣƮ.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#intraextra">(ο ܺ ּҿ )
        ٸ IP ּҷ   ϱ.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#port"> Ʈ  ٸ Ʈ
        ϱ.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ip">IP ȣƮ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipport">Ʈݰ ip ȥյ
        ȣƮ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mixed"≯ݰ IP ȥյ
        ȣƮ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#default"><code>_default_</code> ȣƮ
        ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#migrate"≯ ȣƮ IP
        ȣƮ ű</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#serverpath"><code>ServerPath</code>
    	þ ϱ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="purename" id="purename">IP ּ Ѱ  ̸
        Ʈ ϱ.</a></h2>
    
        <p> IP ּҰ Ѱ ְ, DNS  ּ(CNAMES)
         ǻ͸ Ų.  ǻͿ <code>www.example.com</code>
        <code>www.example.org</code>  ϰ ʹ.</p>
    
        <div class="note"><h3>Note</h3><p>ġ  ȣƮ 
              Ѵٰ  ȣƮ  DNS ׸ ڵ̷ 
              ʴ´. <em>ݵ</em> DNS IP ּҸ Ű
              ̸ ־ Ѵ. ȱ׷ ƹ Ʈ 
               . ˻غ  <code>hosts</code> Ͽ ׸
              ߰  , ̴ hosts ׸  ǻͿ
              ݿȴ.</p>
        </div>
    
        <div class="example"><h3> </h3><p><code>
        
    
        # ġ Ʈ 80 ٸ<br />
        Listen 80<br />
        <br />
        #  IP ּҿ ȣƮ û ٸ<br />
        NameVirtualHost *:80<br />
        <br />
        &lt;VirtualHost *:80&gt;<br />
        <span class="indent">
          DocumentRoot /www/example1<br />
          ServerName www.example.com<br />
          <br />
          # ٸ þ鵵 ִ<br />
          <br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost *:80&gt;<br />
        <span class="indent">
          DocumentRoot /www/example2<br />
          ServerName www.example.org<br />
          <br />
          # ٸ þ鵵 ִ<br />
          <br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>ǥ  ּҸ ŰǷ, ּ  û
         ʴ´. <code>www.example.com</code>
        Ͽ ó Ƿ   켱 ,
        <cite>⺻</cite>Ȥ <cite>ʱ</cite>  ȴ.
         <code>ServerName</code> þ شʴ û
        ù° <code>VirtualHost</code> Ѵ.</p>
    
        <div class="note">
                <h3></h3>
    
                <p>Ѵٸ <code>*</code>  ý  IP
                ּҸ   ִ.  
                <code>VirtualHost</code> ƱԸƮ
                <code>NameVirtualHost</code> ƱԸƮ ġؾ
                <em>Ѵ</em>:</p>
    
                <div class="example"><p><code>
                NameVirtualHost 172.20.30.40<br />
    						<br />
                &lt;VirtualHost 172.20.30.40&gt;<br />
     		        #  ...
                </code></p></div>
    
               <p>׷ ISP  IP ּҸ  
               IP ּҸ 𸣴 쿡 <code>*</code> ϴ
                ϴ. <code>*</code>  IP ּҿ
               شϹǷ, IP ּҰ Ǿ  
               ʿ䰡 .</p>
        </div>
    
        <p> κ ̸ ȣƮ   .
        ܴ ٸ IP ּҳ Ʈ ٸ  Ϸ
        ̴.</p>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="twoips" id="twoips"> IP ּҿ ̸
        ȣƮ.</a></h2>
    
      	<div class="note">
    		  <h3></h3><p>⼭   IP ּҰ
               밡ϴ.</p>
        </div>
    
        <p> IP ּҰ ΰִ. ϳ
        (<code>172.20.30.40</code>) "" 
        <code>server.domain.com</code> ϰ, ٸ ϳ
        (<code>172.20.30.50</code>)  ȣƮ 
        ̴.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        Listen 80<br />
    		<br />
        # 172.20.30.40 ϴ ""̴<br />
        ServerName server.domain.com<br />
        DocumentRoot /www/mainserver<br />
    		<br />
        # ٸ ּҴ<br />
        NameVirtualHost 172.20.30.50<br />
    		<br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1<br />
            ServerName www.example.com<br />
       			<br />
            # ٸ þ鵵 ִ ...<br />
    				<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
    				<br />
            # ٸ þ鵵 ִ ...<br />
    				<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p><code>172.20.30.50</code> ƴ ּҿ  û
        ּ Ѵ. ȣƮ ,  <code>Host:</code>
         <code>172.20.30.50</code> ûϸ
        <code>www.example.com</code> Ѵ.</p>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intraextra" id="intraextra">(ο ܺ ּҿ )
        ٸ IP ּҷ   ϱ.</a></h2>
    
        <p> ǻͿ IP ּҰ ΰ (<code>192.168.1.1</code>
        <code>172.20.30.40</code>) ִ. ǻʹ  (Ʈ)
        Ʈ ܺ (ͳ) Ʈ ̿ ġѴ. Ʈ ۿ
        <code>server.example.com</code> ܺ ּҸ
        (<code>172.20.30.40</code>) ǹϰ, Ʈ ο 
        ̸  ּҷ (<code>192.168.1.1</code>) Ѵ.</p>
    
        <p> <code>VirtualHost</code>  Ѱ ο ܺ
        信     ִ.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        NameVirtualHost 192.168.1.1<br />
        NameVirtualHost 172.20.30.40<br />
    		<br />
        &lt;VirtualHost 192.168.1.1 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/server1<br />
            ServerName server.example.com<br />
            ServerAlias server<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>  Ʈ  û 
        <code>VirtualHost</code> Ѵ.</p>
    
        <div class="note">
              <h3>:</h3><p> Ʈ  ȣƮ
              <code>server.example.com</code>  ̸
              <code>server</code> ϴ.</p>
    
              <p>   IP ּ  <code>*</code>
              Ͽ   ּҿ ϰ  
              ִ.</p>
        </div>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="port" id="port"> Ʈ  ٸ Ʈ
        ϱ.</a></h2>
    
        <p> IP  Ʈ  ٸ  Ѵٰ
        . ̴ "NameVirtualHost" ±׿ Ʈ ϸ
        ϴ. NameVirtualHost name:port &lt;VirtualHost
        name:port&gt; Ȥ Listen þ ϸ ȵȴ.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        Listen 80<br />
        Listen 8080<br />
    		<br />
        NameVirtualHost 172.20.30.40:80<br />
        NameVirtualHost 172.20.30.40:8080<br />
    		<br />
        &lt;VirtualHost 172.20.30.40:80&gt;<br />
        <span class="indent">
            ServerName www.example.com<br />
            DocumentRoot /www/domain-80<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40:8080&gt;<br />
        <span class="indent">
            ServerName www.example.com<br />
            DocumentRoot /www/domain-8080<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40:80&gt;<br />
        <span class="indent">
            ServerName www.example.org<br />
            DocumentRoot /www/otherdomain-80<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40:8080&gt;<br />
        <span class="indent">
            ServerName www.example.org<br />
            DocumentRoot /www/otherdomain-8080<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ip" id="ip">IP ȣƮ</a></h2>
    
        <p>  <code>www.example.com</code>
        <code>www.example.org</code> شϴ  IP ּҸ
        (<code>172.20.30.40</code> <code>172.20.30.50</code>)
        .</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        Listen 80<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1<br />
            ServerName www.example.com<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p><code>&lt;VirtualHost&gt;</code> þ  ּҿ
        شʴ ּҷ ( , <code>localhost</code>)
        û  ּ ִ  ּ Ѵ.</p>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipport" id="ipport">Ʈݰ ip ȥյ
        ȣƮ</a></h2>
    
        <p>  <code>www.example.com</code>
        <code>www.example.org</code> شϴ  IP ּҸ
        (<code>172.20.30.40</code> <code>172.20.30.50</code>)
        .  IP 80 8080 Ʈ ȣƮ .</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        Listen 172.20.30.40:80<br />
        Listen 172.20.30.40:8080<br />
        Listen 172.20.30.50:80<br />
        Listen 172.20.30.50:8080<br />
    		<br />
        &lt;VirtualHost 172.20.30.40:80&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1-80<br />
            ServerName www.example.com<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40:8080&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1-8080<br />
            ServerName www.example.com<br />
    		</span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.50:80&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2-80<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.50:8080&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2-8080<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mixed" id="mixed"≯ݰ IP ȥյ
        ȣƮ</a></h2>
    
        <p>ּ  ̸ ȣƮ, ٸ  IP
        ȣƮ ϰ ʹ.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        Listen 80<br />
    		<br />
        NameVirtualHost 172.20.30.40<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1<br />
            ServerName www.example.com<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example3<br />
            ServerName www.example3.net<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        # IP-<br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example4<br />
            ServerName www.example4.edu<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.60&gt;<br />
        <span class="indent">
            DocumentRoot /www/example5<br />
            ServerName www.example5.gov<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="default" id="default"><code>_default_</code> ȣƮ
        ϱ</a></h2>
    
      	<h3><a name="defaultallports" id="defaultallports"> Ʈ 
        <code>_default_</code> ȣƮ</a></h3>
    
        <p> ȣƮ ش IP ּҿ Ʈ 
        <em></em> û óϱ.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        &lt;VirtualHost _default_:*&gt;<br />
        <span class="indent">
            DocumentRoot /www/default<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>default(⺻) ȣƮ Ʈ ϵī带 Ͽ  û
        ּ  .</p>
    
        <p>default ȣƮ  ̸ ȣƮ ϴ
        ּ/Ʈ û  ʴ´.   ų
        <code>Host:</code>   û ׻  ̸
        ȣƮ(Ͽ
        ּ/Ʈ ó  ȣƮ) Ѵ.</p>
    
        <p><code class="directive"><a href="../mod/mod_alias.html#aliasmatch">AliasMatch</a></code>
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
        Ͽ  û Ư (Ȥ ũƮ)
        ۼ(rewrite)  ִ.</p>
        
    
        <h3><a name="defaultdifferentports" id="defaultdifferentports"> Ʈ 
        <code>_default_</code> ȣƮ</a></h3>
    
        <p>  ,   Ʈ ٸ 80
        Ʈ ؼ ߰ <code>_default_</code> ȣƮ
        ϰ ʹ.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        &lt;VirtualHost _default_:80&gt;<br />
        <span class="indent">
            DocumentRoot /www/default80<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost _default_:*&gt;<br />
        <span class="indent">
            DocumentRoot /www/default<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>80 Ʈ  default ȣƮ (<em>ݵ</em>
        ϵī Ʈ  ⺻ ȣƮ  ; Ѵ)
         IP ּҷ   û Ѵ.
        ּ  û  Ѵ.</p>
        
    
        <h3><a name="defaultoneport" id="defaultoneport"> Ʈ 
        <code>_default_</code> ȣƮ</a></h3>
    
        <p>80 Ʈ ؼ default ȣƮ  ʹ.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        &lt;VirtualHost _default_:80&gt;<br />
        DocumentRoot /www/default<br />
        ...<br />
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>Ʈ 80  ּҿ  û ⺻
        ȣƮ ϰ, ٸ  ּҿ Ʈ
         û   Ѵ.</p>
        
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="migrate" id="migrate"≯ ȣƮ IP
        ȣƮ ű</a></h2>
    
        <p>(<a href="#name"≯</a> ù° ) ȣƮ
        <code>www.example.org</code>  ̸ ȣƮ
        ڽ IP ּҸ  Ѵ. ̸ ȣƮ 
        IP ּҸ ijϴ Ӽ Ͻÿ  ϱ
        ű   θ ϰ ʹ.</p>
    
        <p>
          <code>VirtualHost</code> þ  IP ּҸ
        (<code>172.20.30.50</code>) ߰ϸǹǷ .</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        Listen 80<br />
        ServerName www.example.com<br />
        DocumentRoot /www/example1<br />
    		<br />
        NameVirtualHost 172.20.30.40<br />
    		<br />
        &lt;VirtualHost 172.20.30.40 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example3<br />
            ServerName www.example.net<br />
            ServerAlias *.example.net<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p> (IP ȣƮ ) ο ּҿ (̸
        ȣƮ )  ּ  ȣƮ 
         ִ.</p>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="serverpath" id="serverpath"><code>ServerPath</code>
    	þ ϱ</a></h2>
    
        <p> ̸ ȣƮ   ִ. ùٸ
        ȣƮ ϱ Ŭ̾Ʈ ùٸ
        <code>Host:</code>   Ѵ.  HTTP/1.0
        Ŭ̾Ʈ    ϸ ġ Ŭ̾Ʈ
         ȣƮ ϴ    (׷ 
        ȣƮ û Ѵ).    ȣȯ
        ϱ  ȣƮ , ⿡ ̸
        ȣƮ URL λ縦 ϴ ũ  
        д.</p>
    
        <div class="example"><h3> </h3><p><code>
        
    
        NameVirtualHost 172.20.30.40<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            # primary vhost<br />
            DocumentRoot /www/subdomain<br />
            RewriteEngine On<br />
            RewriteRule ^/.* /www/subdomain/index.html<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        DocumentRoot /www/subdomain/sub1<br />
        <span class="indent">
            ServerName www.sub1.domain.tld<br />
            ServerPath /sub1/<br />
            RewriteEngine On<br />
            RewriteRule ^(/sub1/.*) /www/subdomain$1<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/subdomain/sub2<br />
            ServerName www.sub2.domain.tld<br />
            ServerPath /sub2/<br />
            RewriteEngine On<br />
            RewriteRule ^(/sub2/.*) /www/subdomain$1<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code> þ
        URL <code>http://www.sub1.domain.tld/sub1/</code> 
        û <em>׻</em> subl-ȣƮ Ѵ.<br />
        Ŭ̾Ʈ ùٸ <code>Host:</code>  ٸ,
        URL <code>http://www.sub1.domain.tld/</code>  û
        subl-ȣƮ Ѵ.  <code>Host:</code> 
         Ŭ̾Ʈ  ȣƮ ִ 
        Եȴ.</p>
    
        <p>⿡   ϶: Ŭ̾Ʈ
        <code>Host:</code>  
        <code>http://www.sub2.domain.tld/sub1/</code>  û
        subl-ȣƮ Ѵ.</p>
    
        <p><code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
        þ Ͽ ùٸ <code>Host:</code>  
        Ŭ̾Ʈ (<em> </em>, URL ġ簡 ְų )
         URL    ִ.</p>
    
    	</div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/examples.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/fd-limits.html.tr.utf8����������������������������������������������0000664�0001751�0001751�00000022511�14743132254�022452� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Dosya Tanıtıcı Sınırları - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Sanal Konaklar</a></div><div id="page-content"><div id="preamble"><h1>Dosya Tanıtıcı Sınırları</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Çok büyük sayıda sanal konak kullanıyorsanız ve bunların her biri için
          ayrı günlük kayıtları tutuyorsanız, Apache dosya tanıtıcılarını
          tüketebilir. Apache tarafından, dahili olarak 10-20 dosya tanıtıcıya ek
          olarak her hata günlüğü için bir ve her diğer günlük kaydı için bir dosya
          tanıcı kullanılır. Unix işletim sisteminde dosya tanıtıcıların sayısı
          süreç başına 64 taneyle sınırlıdır ve gerekirse donanıma bağlı olarak
          arttırılabilir.</p>
    
        <p>Apache gerektiğinde bu sınırı kendisi arttırmaya çalışırsa da bu her
          zaman mümkün olmaz. Şöyle ki:</p>
    
        <ol>
          <li>Sisteminiz <code>setrlimit()</code> sistem çağrısını
            sağlamıyordur.</li>
    
          <li>Sisteminizde <code>setrlimit(RLIMIT_NOFILE)</code> çağrısı hiçbir işe
            yaramıyordur (örneğin, Solaris 2.3).</li>
    
          <li>Dosya tanıtıcılarının sayısı donanıma bağlı olarak daha fazla
            arttırılamıyordur.</li>
    
          <li>Sisteminiz dosya tanıtıcı sayısını başka sınırlara bağlı kılmıştır:
            örneğin stdio akımları ile ilgili sınır, dosya tanıtıcı sayısının
            256’nın altında ollmasını gerektiriyordur (Solaris 2).</li>
        </ol>
    
        <p>Böyle sorunlar karşısında yapabilecekleriniz:</p>
    
        <ul><li>Ana günlük dosyaları hariç, <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümlerinde günlük dosyası
          belirtmeyerek günlük dosyası sayısını düşürürsünüz. (Bunun nasıl
          yapılacağını öğrenmek için <a href="#splitlogs">Günlük kayıtlarının
          ayrıştırılması</a> bölümüne bakınız.)</li>
    
          <li>Sisteminizde serbest dosya tanıtıcı sayısı 1-2 civarına düşerse
            Apache’yi aşağıdaki gibi bir betikle yeniden çalıştırarak dosya
            tanıtıcı sayısını arttırabilirsiniz:
    
            <div class="example"><p><code>
              <code>#!/bin/sh<br />
               ulimit -S -n 100<br />
               exec httpd</code>
            </code></p></div>
          </li>
        </ul>
    
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="splitlogs" id="splitlogs">Günlük kayıtlarının ayrıştırılması</a></h2>
    
        <p>Günlük dosyalarını çok sayıda sanal konak için ortak olarak
          kullanıyorsanız, sanal konaklar için istatistiksel çözümlemeler yapmak
          amacıyla sırası geldiğinde bunları ayrıştırabilirsiniz. Bu işlem aşağıda
          anlatıldığı gibi yapılabilir.</p>
    
        <p>İlk iş olarak, sanal konak bilgilerini günlük girdilerine eklemeniz
          gerekir. Bu işlem, <code class="directive"><a href="../mod/mod_log_config.html#logformat">LogFormat</a></code> yönergesi ve
          <code>%v</code> biçem değişkeni ile yapılabilir. Günlük girdisi biçem
          dizgesinin başına bunu ekleyiniz:</p>
    
        <pre class="prettyprint lang-config">LogFormat "%v %h %l %u %t \"%r\" %&gt;s %b" vhost
    CustomLog logs/multiple_vhost_log vhost</pre>
    
    
        <p>Bu yapılandırma ile her günlük kaydının başında sanal konağın
          <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> yönergesine belirtilen
          ismi eklenir. (Günlük dosyalarınızın kişiselleştirilmesi ile ilgili daha
          fazla bilgi için <code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code> belgesine bakınız.)</p>
    
        <p>Günlük dosyanızdaki kayıtları bileşenlere göre gruplamak isterseniz
          <code><a href="../programs/other.html">split-logfile</a></code>
          programını kullanabilirsiniz. Bu programı Apache dağıtımının
          <code>support</code> dizininde bulabilirsiniz.</p>
    
        <p>Programı aşağıdaki gibi çalıştırın:</p>
    
        <div class="example"><p><code>
        split-logfile &lt; /logs/multiple_vhost_log
        </code></p></div>
    
        <p>Bu programı sanal konaklar için tuttuğunuz günlük dosyasının ismini
          argüman olarak belirterek çalıştırdığınızda o dosyadaki kayıtlardan her
          sanal konak için ayrı bir günlük dosyası
          (<code><em>konakadı</em>.log</code>) üretilir.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/fd-limits.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html.zh-cn.utf8�����������������������������������������������0000664�0001751�0001751�00000016750�14743132254�022273� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache 虚拟主机文档 - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache 虚拟主机文档</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
    
        <p>术语<cite>虚拟主机</cite>指的是在单一机器上运行多个网站
        (例如 <code>company1.example.com</code> 和
        <code>company2.example.com</code>) 。
        虚拟主机可以“<a href="ip-based.html">基于 IP</a>”,即每个 IP 一个站点;
        或者“<a href="name-based.html">基于名称</a>”,
        即每个 IP 多个站点。这些站点运行在同一物理服务器上的事实不会明显的透漏给最终用户。</p>
    
        <p>Apache 是第一个支持基于 IP 的虚拟主机的服务器。
        Apache 版本 1.1 和更新的版本同时支持基于 IP 和基于名称的虚拟主机。
        基于名称的虚拟主机有时候称为<em>基于主机</em>或<em>非 IP</em> 的虚拟主机.</p>
    
        <p>以下解释是在 Apache 中支持虚拟主机的所有详细信息的文档页面列表。</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#support">虚拟主机支持</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#directives">配置指令</a></li>
    </ul><h3>参见</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li><li><a href="name-based.html">基于名称的虚拟主机</a></li><li><a href="ip-based.html">基于 IP 的虚拟主机</a></li><li><a href="examples.html">虚拟主机样例</a></li><li><a href="fd-limits.html">文件句柄限制</a></li><li><a href="mass.html">动态配置的大规模虚拟主机</a></li><li><a href="details.html">虚拟主机匹配的深入讨论</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">虚拟主机支持</a></h2>
    
        <ul>
          <li><a href="name-based.html">基于名称的虚拟主机</a> (每个 IP 多个站点)</li>
          <li><a href="ip-based.html">基于 IP 的虚拟主机</a> (每个 IP 一个站点)</li>
          <li><a href="examples.html">虚拟主机样例</a></li>
          <li><a href="fd-limits.html">文件句柄限制</a> (或者<em>日志文件太多</em>)</li>
          <li><a href="mass.html">动态配置的大规模虚拟主机</a></li>
          <li><a href="details.html">虚拟主机匹配的深入讨论</a></li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="directives" id="directives">配置指令</a></h2>
    
        <ul>
          <li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li>
        </ul>
    
        <p>如果你要调试虚拟主机配置,你会发现 Apache 的命令行参数 <code>-S</code>
        非常有用。即输入以下命令:</p>
    
        <div class="example"><p><code>
        /usr/local/apache2/bin/httpd -S
        </code></p></div>
    
        <p>这个命令将会显示 Apache 是如何解析配置文件的。仔细检查 IP
        地址与服务器名称可能会帮助你发现配置错误
        (参见 <code class="program"><a href="../programs/httpd.html">httpd</a></code> 程序文档,以便了解其它命令行选项)。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������httpd-2.4.64/docs/manual/vhosts/mass.html.ko.euc-kr�������������������������������������������������0000664�0001751�0001751�00000051145�14743132254�022016� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>뷮 ȣƮ  ϱ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">ȣƮ</a></div><div id="page-content"><div id="preamble"><h1>뷮 ȣƮ  ϱ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/vhosts/mass.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    
        <p>  ġ 1.3 뷮 ȣƮ ȿ
        ϴ  Ѵ. 
        </p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#motivation"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#overview"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple">  ȣƮ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#homepages"> ȣƮϴ Ȩ ý</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#combinations">   ȣƮ
        ý ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipbased"> ȿ IP ȣƮ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#oldversion">ġ   ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple.rewrite"><code>mod_rewrite</code>
           ȣƮ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#homepages.rewrite"><code>mod_rewrite</code>
         Ȩ ý</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#xtra-conf"> ȣƮ 
        ϱ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="motivation" id="motivation"></a></h2>
    
        <p> <code>httpd.conf</code>    
        <code>&lt;VirtualHost&gt;</code> ǵ  ִٸ ⼭
        ϴ    ̴:</p>
    
    <div class="example"><p><code>
    NameVirtualHost 111.22.33.44<br />
    &lt;VirtualHost 111.22.33.44&gt;<br />
    <span class="indent">
        ServerName                 www.customer-1.com<br />
        DocumentRoot        /www/hosts/www.customer-1.com/docs<br />
        ScriptAlias  /cgi-bin/  /www/hosts/www.customer-1.com/cgi-bin<br />
    </span>
    &lt;/VirtualHost&gt;<br />
    &lt;VirtualHost 111.22.33.44&gt;<br />
    <span class="indent">
        ServerName                 www.customer-2.com<br />
        DocumentRoot        /www/hosts/www.customer-2.com/docs<br />
        ScriptAlias  /cgi-bin/  /www/hosts/www.customer-2.com/cgi-bin<br />
    </span>
    &lt;/VirtualHost&gt;<br />
    # ٺ ٺ ٺ<br />
    &lt;VirtualHost 111.22.33.44&gt;<br />
    <span class="indent">
        ServerName                 www.customer-N.com<br />
        DocumentRoot        /www/hosts/www.customer-N.com/docs<br />
        ScriptAlias  /cgi-bin/  /www/hosts/www.customer-N.com/cgi-bin<br />
    </span>
    &lt;/VirtualHost&gt;
    </code></p></div>
    
        <p>⺻   <code>&lt;VirtualHost&gt;</code>
         θ  óϵ üϴ ̴.
        ׷   ִ:</p>
    
        <ol>
          <li> ۾ ġ  ϰ ޸𸮸
           Ѵ.</li>
    
          <li>ȣƮ ߰ϱ Ͻýۿ 
          丮  DNS ׸ ߰ϱ⸸ ϸȴ. ,
          ġ 缳ϰ  ʿ䰡 .</li>
        </ol>
    
        <p>  ȣƮ ٸ α   ٴ
        ̴. ׷ ſ  ȣƮ Ѵٸ ϱڸ
         ⶧  ٸ α   . 
        fifo α׸ , ޴  α׸ óϿ 
         (    ִ)  .</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview"></a></h2>
    
        <p>ȣƮ IP ּҿ HTTP û <code>Host:</code>
          Ѵ. ⺻ 뷮
         ȣƮ  ڵ ȣƮ  û
        ϰο Ѵ. ̴ κ <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>
        Ͽ  ذ  , ġ 1.3.6 ϸ Ѵٸ
        <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> ؾ Ѵ.   
         ⺻  Ե ʴ´.   Ϸ
        ġ ϰ Ҷ ؾ Ѵ.</p>
    
        <p> ȣƮ Ϲ ȣƮó ̰Ϸ
         `ӿ' Ѵ.  ߿  ġ ڱ
        URL  鶧  ̴. 
        <code>ServerName</code> þ ϸ, CGI
        <code>SERVER_NAME</code> ȯ溯 ־.   
         <code class="directive"><a href="../mod/core.html#usecanonicalname">UseCanonicalName</a></code>  ޷ȴ.
        <code>UseCanonicalName Off</code≯ û <code>Host:</code>
           ȴ. <code>UseCanonicalName DNS</code≯
        ȣƮ IP ּҸ DNS ˻Ͽ  ˾Ƴ.
        ڴ ̸  ȣƮ ϰ, ڴ IP
        ȣƮ Ѵ. <code>Host:</code>  ų
        DNS ˻ Ͽ ġ  ˾Ƴ ϸ
        <code>ServerName</code>    Ѵ.</p>
    
        <p>ٸ `'  (<code>DocumentRoot</code> ϸ,
        CGI <code>DOCUMENT_ROOT</code> ȯ溯 ־)
        Ʈ̴. Ϲ  core    Ͽ
        URI شϴ ϸ ã,   ȣ Ҷ ٸ
         (<code>mod_vhost_alias</code> <code>mod_rewrite</code>)
        ٸ  ̷ ۾ Ѵ.   
        <code>DOCUMENT_ROOT</code> ȯ溯  Ƿ
        CGI SSI    Ѵٸ ߸   
        ִ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple" id="simple">  ȣƮ</a></h2>
    
        <p> <a href="#motivation"></a>  ȣƮ
         <code>mod_vhost_alias</code> Ͽ  Ϲ
        ߴ.</p>
    
    <div class="example"><p><code>
    # Host:   ˾Ƴ<br />
    UseCanonicalName Off<br />
    <br />
    # ù° ʵ带 Ͽ  α׸ ȣƮ   ִ<br />
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon<br />
    CustomLog logs/access_log vcommon<br />
    <br />
    # û óϱ ϸ  Ѵ<br />
    VirtualDocumentRoot /www/hosts/%0/docs<br />
    VirtualScriptAlias  /www/hosts/%0/cgi-bin
    </code></p></div>
    
        <p>  <code>UseCanonicalName Off</code>
        <code>UseCanonicalName DNS</code> ϱ⸸ ϸ IP
        ȣƮ ȴ. ȣƮ IP ּҸ 
        ϸ ߰    ִ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="homepages" id="homepages"> ȣƮϴ Ȩ ý</a></h2>
    
        <p>ISP Ȩ     ߴ.  
          ϸ <code>www.user.isp.com</code> 
        <code>/home/user/</code> δ   Ϻθ 
        ϸ   ִ.  
        <code>cgi-bin</code>  ȣƮ  ʰ
         ȣƮ  Ѵ.</p>
    
    <div class="example"><p><code>
    # ⺻   . ׸<br />
    <br />
    # ϸ  Ϻθ Ѵ<br />
    VirtualDocumentRoot /www/hosts/%2/docs<br />
    <br />
    # ϳ cgi-bin 丮<br />
    ScriptAlias  /cgi-bin/  /www/std-cgi/<br />
    </code></p></div>
    
        <p><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>   
        <code>VirtualDocumentRoot</code>   ִ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="combinations" id="combinations">   ȣƮ
        ý ϱ</a></h2>
    
        <p>    ġ Ϲ
        <code>&lt;VirtualHost&gt;</code> þ Ͽ 
        ȣƮ     ִ.  , 
          Ȩ  IP ּ Ѱ, 
         ٸ IP ּ Ѱ οѴ.  ó
        <code>&lt;VirtualHost&gt;</code>  ǿ   
        ִ.</p>
    
    <div class="example"><p><code>
    UseCanonicalName Off<br />
    <br />
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon<br />
    <br />
    &lt;Directory /www/commercial&gt;<br />
    <span class="indent">
        Options FollowSymLinks<br />
        AllowOverride All<br />
    </span>
    &lt;/Directory&gt;<br />
    <br />
    &lt;Directory /www/homepages&gt;<br />
    <span class="indent">
        Options FollowSymLinks<br />
        AllowOverride None<br />
    </span>
    &lt;/Directory&gt;<br />
    <br />
    &lt;VirtualHost 111.22.33.44&gt;<br />
    <span class="indent">
        ServerName www.commercial.isp.com<br />
        <br />
        CustomLog logs/access_log.commercial vcommon<br />
        <br />
        VirtualDocumentRoot /www/commercial/%0/docs<br />
        VirtualScriptAlias  /www/commercial/%0/cgi-bin<br />
    </span>
    &lt;/VirtualHost&gt;<br />
    <br />
    &lt;VirtualHost 111.22.33.45&gt;<br />
    <span class="indent">
        ServerName www.homepages.isp.com<br />
        <br />
        CustomLog logs/access_log.homepages vcommon<br />
        <br />
        VirtualDocumentRoot /www/homepages/%0/docs<br />
        ScriptAlias         /cgi-bin/ /www/std-cgi/<br />
    </span>
    &lt;/VirtualHost&gt;
    </code></p></div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipbased" id="ipbased"> ȿ IP ȣƮ</a></h2>
    
        <p><a href="#simple">ù° </a>   
        IP ȣƮ ٲ  ִٰ ߴ. 
        ׷   û DNS ãƾϹǷ ſ ȿ̴.
        ̸ IP ּҷ Ͻý ϰ  
        α׸ ϸ  ذ  ִ. ġ 
        ٷ ʿ䰡 , DNS ˻  ʰ ȴ.</p>
    
    <div class="example"><p><code>
    # IP ּҸ DNS ˻Ͽ  ˾Ƴ<br />
    UseCanonicalName DNS<br />
    <br />
    # α׸   ֵ IP ּҸ Ѵ<br />
    LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon<br />
    CustomLog logs/access_log vcommon<br />
    <br />
    # ϸ IP ּҸ Ѵ<br />
    VirtualDocumentRootIP /www/hosts/%0/docs<br />
    VirtualScriptAliasIP  /www/hosts/%0/cgi-bin<br />
    </code></p></div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="oldversion" id="oldversion">ġ   ϱ</a></h2>
    
        <p>  ġ  1.3.6 Ŀ Ե
        <code>mod_vhost_alias</code> Ѵ.
        <code>mod_vhost_alias</code>  ġ  Ѵٸ
        ̹ ߵ <code>mod_rewrite</code> Ͽ, 
        Host:- ȣƮ,   ִ.</p>
    
        <p> α׿ Ͽ   ִ. ġ 1.3.6
        α þ <code>%V</code> ԵǾ,  1.3.0
        - 1.3.3   <code>%v</code> ɼ  ߴ. ׷
         1.3.4 ̷  .  ġ 
        <code>.htaccess</code> Ͽ <code>UseCanonicalName</code>
        þ   Ƿ α׿ ̻  ϵ  ִ.
        ׷Ƿ    <code>%{Host}i</code> þ
        Ͽ <code>Host:</code>   α׿  ̴.
        ,   <code>%V</code> ʴ <code>:port</code>
        ڿ ߰  ִ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple.rewrite" id="simple.rewrite"><code>mod_rewrite</code>
           ȣƮ</a></h2>
    
        <p> <a href="#simple">ù° </a>   ϴ
        <code>httpd.conf</code> ̴. ó  ù° 
         ,   ȣȯ <code>mod_rewrite</code>
           Ǿ.    ۾
        ϴ <code>mod_rewrite</code> Ѵ.</p>
    
        <p>Ư ؾ   ִ. ⺻
        <code>mod_rewrite</code> (<code>mod_alias</code> ) ٸ
        URI    ȴ. ׷ ٸ URI  
           Ͽ <code>mod_rewrite</code> ؾ Ѵ.
        ,  ȣƮ <code>ScriptAlias</code> 
         ؼ Ư ۾ ʿϴ.</p>
    
    <div class="example"><p><code>
    # Host:   ´<br />
    UseCanonicalName Off<br />
    <br />
    # splittable logs<br />
    LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon<br />
    CustomLog logs/access_log vcommon<br />
    <br />
    &lt;Directory /www/hosts&gt;<br />
    <span class="indent">
        # ScriptAlias  CGI    ⶧<br />
        # ⿡ ExecCGI Ѵ<br />
        Options FollowSymLinks ExecCGI<br />
    </span>
    &lt;/Directory&gt;<br />
    <br />
    #   κ̴<br />
    <br />
    RewriteEngine On<br />
    <br />
    # Host:    ҹڰ ڼ  ִ<br />
    RewriteMap  lowercase  int:tolower<br />
    <br />
    ## Ϲ   óѴ:<br />
    # Alias /icons/  ϵ - ٸ alias ؼ ݺ<br />
    RewriteCond  %{REQUEST_URI}  !^/icons/<br />
    # CGI ϵ<br />
    RewriteCond  %{REQUEST_URI}  !^/cgi-bin/<br />
    # Ư ۾<br />
    RewriteRule  ^/(.*)$  /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1<br />
    <br />
    ##  CGI óѴ - MIME type ؾ Ѵ<br />
    RewriteCond  %{REQUEST_URI}  ^/cgi-bin/<br />
    RewriteRule  ^/(.*)$  /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1  [T=application/x-httpd-cgi]<br />
    <br />
    # !
    </code></p></div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="homepages.rewrite" id="homepages.rewrite"><code>mod_rewrite</code>
         Ȩ ý</a></h2>
    
        <p> <a href="#homepages">ι° </a>  
        Ѵ.</p>
    
    <div class="example"><p><code>
    RewriteEngine on<br />
    <br />
    RewriteMap   lowercase  int:tolower<br />
    <br />
    # CGI ϵ<br />
    RewriteCond  %{REQUEST_URI}  !^/cgi-bin/<br />
    <br />
    # RewriteRule ϵ ȣƮ ùٸ ˻Ѵ<br />
    RewriteCond  ${lowercase:%{SERVER_NAME}}  ^www\.[a-z-]+\.isp\.com$<br />
    <br />
    # ȣƮ URI տ δ<br />
    # [C]     ۼ  Ѵ<br />
    RewriteRule  ^(.+)  ${lowercase:%{SERVER_NAME}}$1  [C]<br />
    <br />
    #   ϸ <br />
    RewriteRule  ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2<br />
    <br />
    # ü CGI 丮 Ѵ<br />
    ScriptAlias  /cgi-bin/  /www/std-cgi/
    </code></p></div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="xtra-conf" id="xtra-conf"> ȣƮ 
        ϱ</a></h2>
    
        <p> <code>mod_rewrite</code>   Ͽ
           ȣƮ Ʈ ˾Ƴ.
             ʿϴ.</p>
    
        <p><code>vhost.map</code>   :</p>
    
    <div class="example"><p><code>
    www.customer-1.com  /www/customers/1<br />
    www.customer-2.com  /www/customers/2<br />
    # ...<br />
    www.customer-N.com  /www/customers/N<br />
    </code></p></div>
    
        <p><code>http.conf</code>  :</p>
    
    <div class="example"><p><code>
    RewriteEngine on<br />
    <br />
    RewriteMap   lowercase  int:tolower<br />
    <br />
    #  Ѵ<br />
    RewriteMap   vhost      txt:/www/conf/vhost.map<br />
    <br />
    #   alias óѴ<br />
    RewriteCond  %{REQUEST_URI}               !^/icons/<br />
    RewriteCond  %{REQUEST_URI}               !^/cgi-bin/<br />
    RewriteCond  ${lowercase:%{SERVER_NAME}}  ^(.+)$<br />
    #    ã´<br />
    RewriteCond  ${vhost:%1}                  ^(/.*)$<br />
    RewriteRule  ^/(.*)$                      %1/docs/$1<br />
    <br />
    RewriteCond  %{REQUEST_URI}               ^/cgi-bin/<br />
    RewriteCond  ${lowercase:%{SERVER_NAME}}  ^(.+)$<br />
    RewriteCond  ${vhost:%1}                  ^(/.*)$<br />
    RewriteRule  ^/(.*)$                      %1/cgi-bin/$1
    </code></p></div>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/vhosts/mass.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/mass.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/name-based.html.tr.utf8���������������������������������������������0000664�0001751�0001751�00000043103�14743132254�022556� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>İsme Dayalı Sanal Konaklar - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Sanal Konaklar</a></div><div id="page-content"><div id="preamble"><h1>İsme Dayalı Sanal Konaklar</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu belgede isme dayalı sanal konakların ne zaman, nasıl kullanılacakları
          açıklanmıştır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#namevip">İsme dayalı ve IP’ye dayalı Sanal Konaklar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#alg">Sunucu isme dayalı sanal konaklardan uygun olanını nasıl seçer</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#using">İsme Dayalı Sanal Konakların Kullanımı</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="ip-based.html">IP Adresine Dayalı Sanal Konaklar</a></li><li><a href="details.html">Konak Eşlemenin Derinliğine İncelenmesi</a>
    </li><li><a href="mass.html">Devingen olarak Yapılandırılan Kütlesel Sanal
    Barındırma</a></li><li><a href="examples.html">Çok kullanılan sanal konak yapılandırma
    örnekleri</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="namevip" id="namevip">İsme dayalı ve IP’ye dayalı Sanal Konaklar</a></h2>
    
        <p><a href="ip-based.html">IP’ye dayalı sanal konaklar</a>da sunulacak
          sanal konağı doğru tespit edebilmek için bağlantının yapıldığı IP
          adresine bakılır. Bu bakımdan her konak için ayrı bir IP adresine
          gereksinim vardır.</p>
    
        <p>İsme dayalı sanal konaklarda ise sunucu, istemcinin HTTP başlığının bir
          parçası olarak gönderdiği konak adını kullanır. Bu teknikte aynı IP
          adresini çok sayıda farklı konak kullanabilir.</p>
    
        <p>İsme dayalı sanal barındırma nispeten daha kolaydır, çünkü her konak
          ismini doğru IP adresiyle eşlemek için DNS sunucunuzu yapılandırdıktan
          sonra Apache HTTP sunucusunu farklı konak isimlerini tanıyacak şekilde
          yapılandırmanız yeterli olur. İsme dayalı sanal barındırma ayrıca zaten
          kıt olan IP adreslerine talebi de azaltır. Bu nedenle, IP’ye dayalı sanal
          konakları kullanmanızı gerektiren donanım kullanmadıkça isme  dayalı
          sanal konaklar kullanmalısınız. İstemci uyumuna bağlı IP’ye dayalı
          sanal barındırma için eskiden varolan sebepler genel amaçlı bir HTTP
          sunucusu için artık uygulanabilir değildir.</p>
    
        <p>İsme dayalı sanal barındırma, IP'ye dayalı sanal barındırma seçim
          algoritmasını kullanmaz, yani uygun sunucu ismini arama işlemi sadece en
          iyi IP'ye dayalı adrese sahip sanal konaklar arasında gerçekleşir.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="alg" id="alg">Sunucu isme dayalı sanal konaklardan uygun olanını nasıl seçer</a></h2>
      
    
        <p>İsme dayalı sanal konak çözümlemesinin ilk adımının IP'ye dayalı
          çözümleme olduğunun anlaşılması çok önemlidir. İsme dayalı sanal konak
          çözümlemesi en uygun isme dayalı sanal konağı seçerken önce en iyi IP'ye
          dayalı eşleşme adaylarının sayısını azaltır, sonra bunlar arasından en
          uygununu seçer. Tüm <code>VirtualHost</code> yönergelerinde IP adresi
          yerine joker kullanımı bu IP'ye dayalı eşlemeyi yersiz kılar.</p>
    
        <p>Bir istek geldiğinde, sunucu, istekte kullanılan IP adresi ve portu ile
          en iyi eşleşen <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bileşenini bulur. Bu IP adresi ve port çifti ile
          eşleşen birden fazla sanal konak varsa, Apache httpd istekte kullanılan
          sunucu ismini <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> ve
          <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> yönergelerindeki
          isimlerle karşılaştırır.</p>
    
        <p>Herhangi bir isme dayalı sanal konakta <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> yönergesini kullanmazsanız, sunucu
          bu yönergeye sistem konak adından türetilmiş tam nitelenmiş alan adının
          (FQDN) tanımlandığını varsayacaktır. Bu örtük atama sezgiselliğin
          istenmediği bir sanal konak eşleşmesi ile sonuçlanabilir ve bu
          önerilmez.</p>
    
      <h3><a name="defaultvhost" id="defaultvhost">Bir IP adresi ve port çifti için öntanımlı isme dayalı sankon</a></h3>
       
        <p><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> ve
          <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> yönergelerinde bir
          eşleşme bulunamazsa, Apache httpd bu çift ile eşleşen <strong>sanal
          konaklar listesindeki ilk sanal konağı</strong> kullanır.</p>
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">İsme Dayalı Sanal Konakların Kullanımı</a></h2>
    
    <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li><li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>İlk adım sunacağınız her konak için ayrı bir <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümü oluşturmaktır. Her
          <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümü
          içinde sunulan konağı belirtmek üzere en azından bir adet <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> yönergesine ve konak içeriğinin
          dosya sisteminde bulunduğu yeri gösteren bir <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> yönergesine ihtiyacınız
          olacaktır.</p>
    
        <div class="note"><h3>Ana konağı unutmayın</h3>
          <p>Mevcut <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
            yönergelerinin hiçbiriyle eşleşmeyen bir istek için, sunucu veya konak
            ismine bakılmaksızın genel sunucu yapılandırmanız kullanılır.</p>
    
          <p>Mevcut sitenize isme dayalı bir sanal konak eklerseniz ve bu sanal
            konak ana sunucunun IP adresi ve portuna sahipse, ana sunucuya yapılan
            istekler için bu sanal konak kullanılır. Bu bakımdan, <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> yönergesi ana sunucununki ile aynı
            olan bir <a href="#defaultvhost">öntanımlı sanal konak</a> oluşturmak
            akıllıca olacaktır. Aynı arayüz ve portu kullanan fakat farklı
            yapılandırmalara sahip diğer alan isimlerinin sanal konakları (yani
            öntanımlı olmayanlar) bu öntanımlı sanal konağın sonrasına
            yerleştirilmelidir.</p>
        </div>
    
        <div class="note"><h3>ServerName miras alma</h3>
           <p>İsme dayalı her sanal konak için daima bir <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> belirtmek en iyisidir.</p>
    
           <p>Eğer bir <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> bölümü
           içinde bir <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>
           belirtilmezse, sunucu ismi olarak ana sunucu yapılandırmasındaki isim
           kullanılır. Orada da bir sunucu ismi belirtilmemişse, başlatma sırasında
           dinlenen ilk IP adresinden ters DNS araması ile elde edilen isim
           kullanılır. Her iki durumda da miras alınan isim gereksiz yere isme
           dayalı sanal konak ismi haline gelecektir; bu bakımdan isme dayalı her
           sanal konak için daima bir <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> belirtmek en iyisidir.</p>
        </div>
    
        <p>Örnek olarak, <code>site1.example.com</code> adresinden sitenizi
          sunmakta olduğunuzu ve bunun yanına aynı IP adresini kullanan
          <code>site2.example.com</code> sanal konağını eklemek istediğinizi
          varsayalım. Bunun için <code>httpd.conf</code> dosyanıza basitçe şu
          satırları ekleyebilirsiniz:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost *:80&gt;
        #İlk sanal konak aynı zamanda *:80 için de öntanımlıdır.
        ServerName site1.example.com
        ServerAlias example.com
        DocumentRoot "/siteler/site1"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
        ServerName site2.example.com
        DocumentRoot "/siteler/site2"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>İsterseniz, <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> yönergesinde argüman olarak <code>*</code>
          yerine doğrudan bir IP adresi belirtebilirsiniz. Hatta, daha sonra, isme
          dayalı sanal konakları bir IP adresinden ve IP’ye dayalı olanları veya
          isme dayalı diğer bir sanal konak grubunu diğer IP adreslerinden sunmak
          isteyebilirsiniz.</p>
    
        <p>Çoğu sunucunun birden fazla isim ile erişilebilir olması istenir. Bu,
          <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümü
          içine bir <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> yönergesi
          yerleştirmek suretiyle mümkün olur. Örneğin yukarıdaki örnekte,
          kullanıcıların aynı siteye farklı isimlerle erişmelerini mümkün kılmak
          için bölüm içine şu satırı ekleyebilirsiniz:</p>
    
        <pre class="prettyprint lang-config">ServerAlias example.com *.example.com</pre>
    
    
        <p>Böylece <code>example.com</code> alanındaki tüm konaklar için gelen
          isteklere <code>www.example.com</code> sanal konağından hizmet sunulmuş
          olur. Konak isimleriyle eşleşmek üzere dosya ismi kalıp karakterleri
          <code>*</code> ve <code>?</code> kullanılabilir. Şüphesiz bu isimleri
          sırf <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> veya
          <code>ServerAlias</code> yönergesinde belirtmiş olmakla bu isimleri
          erişilebilir kılamazsınız. Öncelikle, bu isimleri sunucunuzdaki IP
          adresleriyle eşlemek üzere yapılandıracağınız bir DNS sunucunuz
          olmalıdır.</p>
    
        <p>İsme dayalı sanal konaklardan en iyi eşleşme kümesinde olanlar
          yapılandırmada göründükleri sıraya göre işleme sokulur. Joker
          kullanımları arasında fark gözetilmeksizin <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> veya <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> yönergesi eşleşen ilk sanal konak
          kullanılır.</p>
    
        <p><code>VirtualHost</code> içindeki isimlerin sırası (jokersiz) bir
          <code>ServerAlias</code> gibi ele alınır (fakat hiçbir
          <code>ServerAlias</code> yönergesi ile geçersiz kılınmaz).</p>
    
        <p>Son olarak, sanal konak yapılandırmanıza, <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümlerinin içine başka yönergeler
          yerleştirerek ince ayar çekebilirsiniz. Çoğu yönerge bu bölümlere
          yerleştirilebilir ve sadece o sanal konakla ilgili yapılandırmayı
          değiştirmek için kullanılabilir. Belli bir yönergenin sanal konak
          bölümlerinde kullanılıp kullanılmayacağını yönergenin açıklamasında <a href="../mod/directive-dict.html#Context">Bağlam</a> satırına bakarak
          öğrenebilirsiniz. <em>Ana sunucu bağlamındaki</em> (<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümleri dışındaki)
          yapılandırma yönergelerinden sadece sanal konak bölümlerinde geçersiz
          kılınmamış olanlar kullanılacaktır.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/name-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html.fr.utf8��������������������������������������������������0000664�0001751�0001751�00000020367�14740503670�021663� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Documentation sur les serveurs virtuels Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Documentation sur les serveurs virtuels Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
        <p>Le principe des <cite>Serveurs Virtuels</cite> consiste à 
        faire fonctionner un ou plusieurs serveurs Web (comme 
        <code>www.company1.example.com</code> et <code>www.company2.example.com</code>) 
        sur une même machine. Les serveurs virtuels peuvent être soit 
        "<a href="ip-based.html">par-IP</a>" où une adresse IP est 
        attribuée pour chaque serveur Web, soit "<a href="name-based.html">par-nom</a>" où plusieurs noms de domaine se côtoient sur 
        des mêmes adresses IP. L'utilisateur final ne perçoit pas 
        qu'en fait il s'agit d'un même serveur physique.</p>
    
        <p>Apache a été le précurseur des serveurs proposant cette 
        méthode de serveurs virtuels basés sur les adresses IP. Ses 
        versions 1.1 et suivantes proposent les deux 
        méthodes de serveurs virtuels : par-IP et par-nom. Cette 
        deuxième méthode est parfois également appelée <em>host-based</em> 
        ou <em>serveur virtuel non-IP</em>.</p>
    
        <p>Vous trouverez ci-dessous une liste documentaire qui vous 
        expliquera en détails le fonctionnement du support des serveurs
        virtuels par le serveur HTTP Apache.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#support">Support des serveurs virtuels</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#directives">Directives de configuration</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li><li><a href="name-based.html">Serveurs virtuels par-nom</a></li><li><a href="ip-based.html">Serveurs virtuels par-IP</a></li><li><a href="examples.html">Exemples de serveurs virtuels</a></li><li><a href="fd-limits.html">Limites des descripteurs de fichiers</a></li><li><a href="mass.html">Hébergement virtuel en masse</a></li><li><a href="details.html">Détails sur les critères de choix du serveur</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">Support des serveurs virtuels</a></h2>
    
        <ul>
          <li><a href="name-based.html">Serveurs Virtuels par-Nom</a> 
          (Un ou plusieurs sites Web par adresse IP)</li>
          <li><a href="ip-based.html">Serveurs Virtuels par-IP</a> 
          (Une adresse IP pour chaque site Web)</li>
          <li><a href="examples.html">Exemples de configurations classiques 
          de Serveurs Virtuels </a></li>
          <li><a href="fd-limits.html">Limites des descripteurs de fichiers</a> 
          (ou, <em>trop de fichiers journaux</em>)</li>
          <li><a href="mass.html">Configuration dynamique en masse de 
          Serveurs Virtuels</a></li>
          <li><a href="details.html">Explication approfondie des critères 
          de sélection d'un Serveur Virtuel</a></li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="directives" id="directives">Directives de configuration</a></h2>
    
        <ul>
          <li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li>
        </ul>
    
        <p>Pour vérifier et analyser la configuration de vos serveurs 
        virtuels, vous pouvez utiliser l'argument <code>-S</code> sur 
        la ligne de commande.</p>
    
        <div class="example"><h3>Exemple Unix</h3><p><code>
        
        apachectl -S
        </code></p></div>
    
        <div class="example"><h3>Exemple Windows</h3><p><code>
        
        httpd.exe -S
        </code></p></div>
    
        <p>Cette commande affichera dans le détail comment Apache a 
        traité son fichier de configuration. Les erreurs de configuration 
        peuvent être corrigées par l'examen attentif des adresses IP et 
        des noms de serveurs. (Consultez la documentation du programme 
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> pour les autres arguments de la ligne de 
        commande)</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/examples.html.ja.utf8�����������������������������������������������0000664�0001751�0001751�00000076755�14743132254�022370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>バーチャルホストの例 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">バーチャルホスト</a></div><div id="page-content"><div id="preamble"><h1>バーチャルホストの例</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    
        <p>この文書は、バーチャルホストの設定の際に
        よくある質問に答えるものです。想定している対象は <a href="name-based.html">名前ベース</a> や <a href="ip-based.html">IP ベース</a> のバーチャルホストを使って
        一つのサーバで複数のウェブサイトを運用している状況です。
        </p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#purename">一つの IP アドレスでいくつかの名前ベースの
        ウェブサイトを実行する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#twoips">複数の IP アドレスのあるホストで名前ベースの
        ホスティングを行なう</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#intraextra">違う IP アドレス (例えば、内部と外部アドレス)
        で同じコンテンツを送る</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#port">違うポートで違うサイトを運営する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ip">IP ベースのバーチャルホスティング</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipport">ポートベースと IP ベースの混ざった
        バーチャルホスト</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mixed">名前ベースと IP ベースを混ぜた
        バーチャルホスト</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#proxy"><code>Virtual_host</code> と
        mod_proxy を併用する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#default"><code>_default_</code> のバーチャルホストを
        使う</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#migrate">名前ベースのバーチャルホストから IP ベースの
        バーチャルホストに移行する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#serverpath"><code>ServerPath</code> ディレクティブを
        使う</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="purename" id="purename">一つの IP アドレスでいくつかの名前ベースの
        ウェブサイトを実行する</a></h2>
    
        <p>サーバは IP アドレスを一つ割り当てられていて、DNS でマシンに
        複数の名前 (CNAME) が指定されています。このマシンで
        <code>www.example.com</code> と <code>www.example.org</code>
        のためのウェブサーバを実行させたいとします。</p>
    
        <div class="note"><h3>注</h3><p>
              Apache サーバの設定でバーチャルホストの設定をしただけで、
              知らない間にそのホスト名に対応する DNS のエントリが
              作成されたりはしません。そのサーバの IP アドレスに解決される
              ように DNS に名前を登録しなければ<em>なりません</em>。
              そうでないと誰もあなたのウェブサイトを見ることはできません。
              ローカルでのテストのために <code>hosts</code> ファイルに
              エントリを追加することもできますが、この場合はその
              hosts エントリのあるマシンからしか動作しません。</p>
        </div>
    
        <div class="example"><h3>サーバ設定</h3><p><code>
        
    
        # Ensure that Apache listens on port 80<br />
        Listen 80<br />
        <br />
        # Listen for virtual host requests on all IP addresses<br />
        NameVirtualHost *:80<br />
        <br />
        &lt;VirtualHost *:80&gt;<br />
        <span class="indent">
          DocumentRoot /www/example1<br />
          ServerName www.example.com<br />
          <br />
          # Other directives here<br />
          <br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost *:80&gt;<br />
        <span class="indent">
          DocumentRoot /www/example2<br />
          ServerName www.example.org<br />
          <br />
          # Other directives here<br />
          <br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>アスタリスクはすべてのアドレスにマッチしますので、主サーバは
        リクエストを扱いません。<code>www.example.com</code> は
        最初にあるため、優先順位は一番高くなり、<cite>default</cite> もしくは
        <cite>primary</cite>  のサーバと考えることができます。つまり、リクエストが
        どの <code>ServerName</code> ディレクティブにもマッチしない場合、
        一番最初の <code>VirtualHost</code> により扱われます。</p>
    
        <div class="note"><h3>注</h3>
    
              <p><code>*</code> をシステムの実際の IP アドレスに置き換える
              こともできます。その場合は <code>VirtualHost</code> の引数は
              <code>NameVirtualHost</code> の引数と同じに<em>しなければなりません
              </em>:</p>
    
                <div class="example"><p><code>
                NameVirtualHost 172.20.30.40<br />
                <br />
                &lt;VirtualHost 172.20.30.40&gt;<br />
                 # etc ...
                </code></p></div>
    
              <p>しかし、IP アドレスが予測不可能なシステム
              ――例えばプロバイダから動的に IP アドレスを取得して何らかの
              ダイナミック DNS を使っている場合など――においては、<code>*</code> 
              指定はさらに便利です。<code>*</code> はすべての IP アドレスに
              マッチしますので、この設定にしておけば IP アドレスが変更されても
              設定変更せずに動作します。</p>
        </div>
    
        <p>名前ベースのバーチャルホスティングではほぼすべての状況で、
        上記の設定で希望の設定になっていることでしょう。
        実際この設定が動作しないのは、IP アドレスやポートの違いによって
        違うコンテンツを送るときだけです。</p>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="twoips" id="twoips">複数の IP アドレスのあるホストで名前ベースの
        ホスティングを行なう</a></h2>
     
        <div class="note">
        <h3>注</h3><p>ここで説明されている方法は IP アドレスが
        何個あっても同様にできます。</p>
        </div>
    
        <p>サーバには二つ IP アドレスがついています。一つ目
        (<code>172.20.30.40</code>) では主サーバ 
        <code>server.domain.com</code> を扱い、もう一方
        (<code>172.20.30.50</code>) では二つかそれ以上の数の
        バーチャルホストを扱います。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        Listen 80<br />
        <br />
        # This is the "main" server running on 172.20.30.40<br />
        ServerName server.domain.com<br />
        DocumentRoot /www/mainserver<br />
        <br />
        # This is the other address<br />
        NameVirtualHost 172.20.30.50<br />
        <br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1<br />
            ServerName www.example.com<br />
            <br />
            # Other directives here ...<br />
            <br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
            <br />
            # Other directives here ...<br />
            <br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p><code>172.20.30.50</code> 以外のアドレスへのリクエストは主サーバ
        が扱います。<code>172.20.30.50</code> への、未知のホスト名または
        <code>Host:</code> ヘッダなしのリクエストは <code>www.example.com</code>
        が扱います。</p>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intraextra" id="intraextra">違う IP アドレス (例えば、内部と外部アドレス)
        で同じコンテンツを送る</a></h2>
    
        <p>サーバマシンは IP アドレスを二つ (<code>192.168.1.1</code>
        と <code>172.20.30.40</code>) 持っています。このマシンは内部
        (イントラネット) と 外部 (インターネット) のネットワークの間に
        あります。<code>server.example.com</code> はネットワークの外からは
        外部アドレス (<code>172.20.30.40</code>) として解決されますが、
        ネットワークの中からは内部アドレス (<code>192.168.1.1</code>) 
        として解決されます。</p>
    
        <p><code>VirtualHost</code> 一つだけでサーバが内部のリクエストと
        外部のリクエストの両方に同じコンテンツで応答するようにできます。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        NameVirtualHost 192.168.1.1<br />
        NameVirtualHost 172.20.30.40<br />
        <br />
        &lt;VirtualHost 192.168.1.1 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/server1<br />
            ServerName server.example.com<br />
            ServerAlias server<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>これでどちらのネットワークからのリクエストも同じ <code>VirtualHost</code>
        で扱われるようになります。</p>
    
        <div class="note"><h3>注:</h3><p>内部ネットワークでは完全なホスト名の
              <code>server.example.com</code> の代わりに、単に <code>server</code>
              を使うことができます。</p>
    
              <p>上の例では、IP アドレスのリストを、すべてのアドレスに
               同じコンテンツで応答する <code>*</code> に置き換えられます。</p>
        </div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="port" id="port">違うポートで違うサイトを運営する</a></h2>
    
        <p>同じ IP に複数のドメインがあり、さらに複数のポートを使って
        リクエストを扱いたいときがあります。"NameVirtualHost" タグの中で
        ポートを定義することで、これを動作させられます。
        NameVirtualHost name:port 無しや Listen ディレクティブで
        &lt;VirtualHost name:port&gt; を使おうとしても、その設定は動作しません。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        Listen 80<br />
        Listen 8080<br />
        <br />
        NameVirtualHost 172.20.30.40:80<br />
        NameVirtualHost 172.20.30.40:8080<br />
        <br />
        &lt;VirtualHost 172.20.30.40:80&gt;<br />
        <span class="indent">
            ServerName www.example.com<br />
            DocumentRoot /www/domain-80<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40:8080&gt;<br />
        <span class="indent">
            ServerName www.example.com<br />
            DocumentRoot /www/domain-8080<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40:80&gt;<br />
        <span class="indent">
            ServerName www.example.org<br />
            DocumentRoot /www/otherdomain-80<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40:8080&gt;<br />
        <span class="indent">
            ServerName www.example.org<br />
            DocumentRoot /www/otherdomain-8080<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ip" id="ip">IP ベースのバーチャルホスティング</a></h2>
    
        <p>サーバは <code>www.example.com</code> と <code>www.example.org</code>
        にそれぞれ解決される、二つの IP アドレス (<code>172.20.30.40</code> と
        <code>172.20.30.50</code>) があります。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        Listen 80<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1<br />
            ServerName www.example.com<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p><code>&lt;VirtualHost&gt;</code> ディレクティブのどれでも
        指定されていないアドレス (例えば <code>localhost</code>) は、
        主サーバがあればそこに行きます。</p>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipport" id="ipport">ポートベースと IP ベースの混ざった
        バーチャルホスト</a></h2>
    
        <p>サーバマシンはそれぞれ <code>www.example.com</code> と
        <code>www.example.org</code> にそれぞれ解決される、IP アドレスを二つ
        (<code>172.20.30.40</code> と <code>172.20.30.50</code>) 持っています。
        どちらもポート 80 と 8080 でホストを走らせます。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        Listen 172.20.30.40:80<br />
        Listen 172.20.30.40:8080<br />
        Listen 172.20.30.50:80<br />
        Listen 172.20.30.50:8080<br />
        <br />
        &lt;VirtualHost 172.20.30.40:80&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1-80<br />
            ServerName www.example.com<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40:8080&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1-8080<br />
            ServerName www.example.com<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.50:80&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2-80<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.50:8080&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2-8080<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mixed" id="mixed">名前ベースと IP ベースを混ぜた
        バーチャルホスト</a></h2>
    
        <p>いくつかのマシンでは名前ベースの、その他では IP ベースのバーチャル
        ホストをします。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        Listen 80<br />
        <br />
        NameVirtualHost 172.20.30.40<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example1<br />
            ServerName www.example.com<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example3<br />
            ServerName www.example3.net<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        # IP-based<br />
        &lt;VirtualHost 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example4<br />
            ServerName www.example4.edu<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.60&gt;<br />
        <span class="indent">
            DocumentRoot /www/example5<br />
            ServerName www.example5.gov<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy"><code>Virtual_host</code> と
        mod_proxy を併用する</a></h2>
    
        <p>次の例は、フロント側のバーチャルホストで他のマシンへプロクシします。
        例では <code>192.168.111.2</code> のマシンではバーチャルホスト名は
        同じ名前で設定されています。複数のホスト名を一台のマシンにプロクシする
        場合は、<code class="directive"><a href="../mod/mod_proxy.html#proxypreservehost on">ProxyPreserveHost On</a></code>
        ディレクティブを使って、希望のホスト名を渡せるようになります。
        </p>
    
        <div class="example"><p><code>
        &lt;VirtualHost *:*&gt;<br />
            ProxyPreserveHost On<br />
            ProxyPass / http://192.168.111.2/<br />
            ProxyPassReverse / http://192.168.111.2/<br />
            ServerName hostname.example.com<br />
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="default" id="default"><code>_default_</code> のバーチャルホストを
        使う</a></h2> 
    
        <h3><a name="defaultallports" id="defaultallports">すべてのポートに対する
        <code>_default_</code> バーチャルホスト</a></h3>
    
        <p>未指定の IP アドレスとポート、<em>つまり</em>他のバーチャルホストに
        使われていないアドレスとポートの組み合わせ、への<em>すべての</em>リクエストを
        受け取ります。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        &lt;VirtualHost _default_:*&gt;<br />
        <span class="indent">
            DocumentRoot /www/default<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>このようにワイルドカードのポートでデフォルトのバーチャルホストを
        指定すると、主サーバにリクエストが行くのを防げます。</p>
    
        <p>デフォルトのバーチャルホストは名前ベースのバーチャルホストに
        使われているアドレスとポートの組に送られたリクエストを扱うことは
        ありません。リクエストが不明な <code>Host:</code> ヘッダやその
        ヘッダがなかったりする場合は基本名前ベースバーチャルホスト (その
        アドレスとポートで設定ファイル中で最初のバーチャルホスト) により
        扱われます。</p>
    
        <p>どんなリクエストでも <code class="directive"><a href="../mod/mod_alias.html#aliasmatch">AliasMatch</a></code>
        や <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> を使って
        単一の情報ページ (やスクリプト) に書き換えることができます。</p>
        
    
        <h3><a name="defaultdifferentports" id="defaultdifferentports">違うポートのための
        <code>_default_</code> バーチャルホスト</a></h3>
    
        <p>一つめの設定とほぼ同じですが、サーバは複数のポートを listen しており、
        80 番ポートに対して二つめの <code>_default_</code> バーチャルホストを
        設定したい場合です。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        &lt;VirtualHost _default_:80&gt;<br />
        <span class="indent">
            DocumentRoot /www/default80<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost _default_:*&gt;<br />
        <span class="indent">
            DocumentRoot /www/default<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>80 番ポートのデフォルトバーチャルホスト (ワイルドカードポートの
        デフォルトバーチャルホストよりも前に書かれていなければ<em>なりません</em>) は
        未指定の IP アドレスに送られたすべてのリクエストを扱います。
        主サーバはリクエストを扱いません。</p>
        
    
        <h3><a name="defaultoneport" id="defaultoneport">一つのポートに対してだけの
        <code>_default_</code> バーチャルホスト</a></h3>
    
        <p>80 番ポートにはデフォルトのバーチャルホストが必要で、他の
        バーチャルホストはデフォルトが必要ない場合です。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        &lt;VirtualHost _default_:80&gt;<br />
        DocumentRoot /www/default<br />
        ...<br />
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>80 番ポートへのアドレス未指定のリクエストはデフォルトのバーチャル
        ホストから送られます。他の未指定のアドレスとポートへのリクエストは
        主サーバから送られます。</p>
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="migrate" id="migrate">名前ベースのバーチャルホストから IP ベースの
        バーチャルホストに移行する</a></h2>
    
        <p>ホスト名が名前 <code>www.example.org</code> のバーチャルホスト
        (<a href="#name">名前ベース</a>の例の 2 番目の設定) が専用の IP アドレスを
        得たとします。名前ベースのバーチャルホストの古い IP アドレスを
        キャッシュしているネームサーバやプロキシのために移行期間中は両方の
        バーチャルホストを提供したいとします。</p>
    
        <p>答は簡単です。単に新しい IP アドレス (<code>172.20.30.50</code>)
        を <code>VirtualHost</code> ディレクティブに追加することで
        できます。</p>
      
        <div class="example"><h3>サーバ設定</h3><p><code>
        
    
        Listen 80<br />
        ServerName www.example.com<br />
        DocumentRoot /www/example1<br />
        <br />
        NameVirtualHost 172.20.30.40<br />
        <br />
        &lt;VirtualHost 172.20.30.40 172.20.30.50&gt;<br />
        <span class="indent">
            DocumentRoot /www/example2<br />
            ServerName www.example.org<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/example3<br />
            ServerName www.example.net<br />
            ServerAlias *.example.net<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>このバーチャルホストは新しいアドレス (IP ベースのバーチャルホストとして)
        と古いアドレス(名前ベースのバーチャルホストとして) の両方から
        アクセスできます。</p>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="serverpath" id="serverpath"><code>ServerPath</code> ディレクティブを
        使う</a></h2>
    
        <p>名前ベースのバーチャルホストが二つあるサーバがあるとします。
        正しいバーチャルホストを得るためにはクライアントは正しい
        <code>Host:</code> ヘッダを送らなければなりません。
        古い HTTP/1.0 はそのようなヘッダを送らないので、Apache はクライアントが
        どのバーチャルホストを意図したのかさっぱりわかりません
        (なので、主バーチャルホストでリクエストを扱います)。
        可能な限りの下位互換性を得るため、名前ベースのバーチャルホストの
        URL 接頭辞へのリンクの書かれたページを返す、
        主バーチャルホストが作成されます。</p>
    
        <div class="example"><h3>サーバの設定</h3><p><code>
        
    
        NameVirtualHost 172.20.30.40<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            # primary vhost<br />
            DocumentRoot /www/subdomain<br />
            RewriteEngine On<br />
            RewriteRule ^/.* /www/subdomain/index.html<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        DocumentRoot /www/subdomain/sub1<br />
        <span class="indent">
            ServerName www.sub1.domain.tld<br />
            ServerPath /sub1/<br />
            RewriteEngine On<br />
            RewriteRule ^(/sub1/.*) /www/subdomain$1<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost 172.20.30.40&gt;<br />
        <span class="indent">
            DocumentRoot /www/subdomain/sub2<br />
            ServerName www.sub2.domain.tld<br />
            ServerPath /sub2/<br />
            RewriteEngine On<br />
            RewriteRule ^(/sub2/.*) /www/subdomain$1<br />
            # ...<br />
        </span>
        &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code> ディレクティブの設定に
        より、URL <code>http://www.sub1.domain.tld/sub1/</code> は
        <em>常に</em> sub1-vhost により扱われます。URL
        <code>http://www.sub1.domain.tld/</code> へのリクエストは
        クライアントが正しい <code>Host:</code> ヘッダを送ったときにのみ
        sub1-vhost から送られます。<code>Host:</code> ヘッダがなければ
        クライアントは主ホストの情報ページを得ます。</p>
    
        <p>一つ奇妙な動作をする点があることは覚えておいてください。
        <code>http://www.sub2.domain.tld/sub1/</code> へのリクエストも
        <code>Host:</code> ヘッダがなければ sub1-vhost により扱われます。</p>
    
        <p>正しい <code>Host:</code> ヘッダを送ったクライアントはどちらの
        URL、<em>つまり</em>接頭辞がある方も無い方も使えるように
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> ディレクティブが
        使われています。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/examples.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������httpd-2.4.64/docs/manual/vhosts/fd-limits.html.ko.euc-kr��������������������������������������������0000664�0001751�0001751�00000020660�14743132254�022741� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ϱ(file descriptor) Ѱ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">ȣƮ</a></div><div id="page-content"><div id="preamble"><h1>ϱ(file descriptor) Ѱ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    
        <p>ȣƮ  ϰ  ȣƮ  ٸ
        α ϸ, ġ 밡 ϱ(file
        descriptor,  <cite>ڵ(file handle)</cite>̶
        θ)    ִ. ġ ϴ ϱ
           αϴ Ѱ, ٸ α þ
        Ѱ, ߰ ο뵵 10-20  . н ü
        μ   ִ ϱ  Ѵ.  Ѱ
         64,  ̺ ū hard-limit ø  ִ.</p>
    
        <p>ġ  Ѱ踦 ʿѸŭ ø , ϴ
        찡 ִ:</p>
    
        <ol>
          <li>ý <code>setrlimit()</code> ýȣ
           ʴ´.</li>
    
          <li>(Solaris 2.3 ) ýۿ
          <code>setrlimit(RLIMIT_NOFILE)</code> Լ 
          ʴ´.</li>
    
          <li>ʿ ϱ  hard limit  .</li>
          
          <li>(Solaris 2) ý stdio Ʈ 256
          ϱڸ ϵ ϴ  ϱڿ
           Ѵ.</li>
        </ol>
    
        <p>  ذå:</p>
    
        <ul>
          <li>α  δ. <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> ǿ α
           ʰ  α Ѵ. ( ڼ 
          Ʒ <a href="#splitlogs">α </a> ϶.)</li>
    
          <li>
            ϴ ý () 1° 2° 쿡 شѴٸ,
              ũƮ ġ ϱ  ϱ
            Ѱ踦 ø.
    
            <div class="example"><p><code>
              <code>#!/bin/sh<br />
               ulimit -S -n 100<br />
               exec httpd</code>
            </code></p></div>
          </li>
        </ul>
    
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="splitlogs" id="splitlogs">α </a></h2>
    
    <p> ȣƮ  α Ѵٸ ߿ 
    ȣƮ м  α   ̴.
     ۾     ִ.</p>
    
    <p> α ׸ ȣƮ  ߰Ѵ. ̸ 
    <code class="directive"><a href="../mod/mod_log_config.html#logformat">LogFormat</a></code>
    þ <code>%v</code>  Ѵ.   α
    Ĺڿ տ ߰Ѵ:</p>
    
    <div class="example"><p><code>
    LogFormat "%v %h %l %u %t \"%r\" %&gt;s %b" vhost<br />
    CustomLog logs/multiple_vhost_log vhost
    </code></p></div>
    
    <p>׷ common α տ (<code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> þ ) 
    ȣƮ Ͽ α Ѵ. (α
    ǿ   <code class="directive"><a href="../mod/mod_log_config.html# α"> α</a></code>
    ϶.)</p>
    
    <p>α (ȣƮ  Ͼ)  ʹٸ <code><a href="../programs/other.html">split-logfile</a></code> α׷
    Ѵ.  α׷ ġ  <code>support</code>
    丮 ִ.</p>
    
    <p>  α׷ Ѵ:</p>
    
    <div class="example"><p><code>
    split-logfile &lt; /logs/multiple_vhost_log
    </code></p></div>
    
    <p>ȣƮ α   α׷ ϸ αϿ
      ȣƮ  ϳ .  ϸ
    <code>hostname.log</code>̴.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/fd-limits.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html.tr.utf8��������������������������������������������������0000664�0001751�0001751�00000020150�14743132254�021666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache Sanal Konak Belgeleri - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache Sanal Konak Belgeleri</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
        <p><cite>Sanal Konak</cite> (Virtual Host) terimi tek bir makine üzerinde
          birden fazla sitenin (sirket1.example.com, sirket2.example.com gibi)
          barındırılma uygulamasını betimler. Sanal konaklar,
          "<a href="ip-based.html">IP’ye dayalı</a>" veya
          "<a href="name-based.html">isme dayalı</a>" olabilir;
          birincisinde, her site ayrı bir IP adresinden sunulurken, ikincisinde her
          IP adresinde birden fazla site sunulur. Olayda aynı fiziksel sunucu
          kullanıldığı halde bu sunucu son kullanıcıya görünür değildir.</p>
    
        <p>Apache yazılımsal olarak IP’ye dayalı sanal konakları destekleyen ilk
          sunuculardan biridir. 1.1 sürümünden itibaren Apache hem IP’ye dayalı hem
          de isme dayalı sanal konakları desteklemektedir. İsme dayalı sanal
          konaklara bazen <em>konağa dayalı</em> sanal konaklar veya <em>IP’ye
          dayanmayan</em> sanal konaklar da denmektedir.</p>
    
        <p>Aşağıda, Apache HTTP Suncusundaki sanal konak desteğini bütün
          ayrıntıları ile açıklayan belgeler listelenmiştir.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#support">Sanal Konak Desteği</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#directives">Yapılandırma Yönergeleri</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li><li><a href="name-based.html">İsme Dayalı Sanal Konaklar</a></li><li><a href="ip-based.html">IP Adresine Dayalı Sanal Konaklar</a>
    </li><li><a href="examples.html">Sanal Konak Örnekleri</a></li><li><a href="fd-limits.html">Dosya Tanıtıcı Sınırları</a></li><li><a href="mass.html">Kütlesel Sanal Konaklık</a></li><li><a href="details.html">Ayrıntılı olarak Konak Eşleme</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">Sanal Konak Desteği</a></h2>
    
        <ul>
          <li><a href="name-based.html">İsme Dayalı Sanal Konaklar</a> (Her IP
            adresinde birden fazla site)</li>
          <li><a href="ip-based.html">IP Adresine Dayalı Sanal Konaklar</a> (Her
            site için ayrı IP adresi)</li>
          <li><a href="examples.html">Çok kullanılan sanal konak yapılandırma
            örnekleri</a></li>
          <li><a href="fd-limits.html">Dosya Tanıtıcı Sınırları</a> (veya,
          <em>çok fazla günlük dosyası</em>)</li>
          <li><a href="mass.html">Devingen olarak Yapılandırılan Kütlesel Sanal
            Barındırma</a></li>
          <li><a href="details.html">Konak Eşlemenin Derinliğine
            İncelenmesi</a></li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="directives" id="directives">Yapılandırma Yönergeleri</a></h2>
    
        <ul>
          <li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li>
        </ul>
    
        <p>Sanal konak yapılandırmanız üzerinde hata ayıklamaya çalışıyorsanız
          <code>-S</code> komut satırı seçeneği şu şekilde çok işinize
          yarayabilir:</p>
    
        <div class="example"><h3>Unix örneği</h3><p><code>
        apachectl -S
        </code></p></div>
    
        <div class="example"><h3>Windows örneği</h3><p><code>
        httpd.exe -S
        </code></p></div>
        
        <p>Bu komut, yapılandırma dosyasının Apache yorumunu dökümler. IP
          adreslerinin ve sunucu isimlerinin dikkatli bir incelemesi, yapılandırma
          yanlışlarınızı keşfetmenize yardımcı olabilir. (Diğer komut satırı
          seçenekleri için <code class="program"><a href="../programs/httpd.html">httpd</a></code> programının belgelerine
          bakınız.)</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/ip-based.html.tr.utf8�����������������������������������������������0000664�0001751�0001751�00000034621�14743132254�022253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>IP’ye Dayalı Sanal Konak Desteği - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Sanal Konaklar</a></div><div id="page-content"><div id="preamble"><h1>IP’ye Dayalı Sanal Konak Desteği</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#explanation">IP'ye dayalı sanal konak desteği nedir</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#requirements">Sistem gereksinimleri</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#howto">Apache nasıl ayarlanır?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multiple">Çok sayıda sürecin yapılandırılması</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#single">Sanal konaklar tek bir sürecin yapılandırılması</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li>
    <a href="name-based.html">İsme Dayalı Sanal Konak Desteği</a>
    </li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="explanation" id="explanation">IP'ye dayalı sanal konak desteği nedir</a></h2>
        <p>IP'ye dayalı sanal konak desteği, bir isteğin alındığı IP adresi ve
          porta bağlı olarak farklı yönergeleri uygulamak için bir yoldur. Özetle,
          farklı siteleri farklı portlardan ve arayüzlerden sunmakta
          kullanılır.</p>
    
         <p>Çoğu durumda, <a href="name-based.html">isme dayalı sanal konaklar</a>
           birçok sanal konağın tek bir IP adresi/port çiftini paylaşmasını
           sağladığından daha kullanışlıdır. Neyi kullanacağınıza karar vermek için
           <a href="name-based.html#namevip">İsme dayalı ve IP’ye dayalı Sanal
           Konaklar</a> bölümüne bakınız.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">Sistem gereksinimleri</a></h2>
    
        <p><cite>IP’ye dayalı</cite> deyince, sunucunun <strong>her IP’ye dayalı
          sanal konak için ayrı bir IP adresi/port çifti</strong>ne sahip olduğunu
          anlıyoruz. Bunun olması için, makine ya çok sayıda ağ bağlantısına
          sahiptir ya da makinede, günümüzde çoğu işletim sistemi tarafından
          desteklenen sanal arabirimler ve/veya çok sayıda port kullanılıyordur.
          (Sanal arabirimlerle ilgili ayrıntılar için sistem belgelerinize bakınız;
          bu konu genellikle IP rumuzları (ip aliases) olarak geçer ve ayarlamak
          için genellikle "ifconfig" komutu kullanılır.)</p>
    
        <p>Apache HTTP Sunucusu terminolojisinde, tek bir IP adresinin çok sayıda
          TCP portuyla kullanımı IP'ye dayalı sanal konak desteği olarak
          bilinir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">Apache nasıl ayarlanır?</a></h2>
    
        <p>Çok sayıda konağı desteklemek üzere Apache iki şekilde
          yapılandırılabilir. Ya her konak için ayrı bir <code class="program"><a href="../programs/httpd.html">httpd</a></code>
          süreci çalıştırırsınız ya da tüm sanal konakları destekleyen tek bir
          süreciniz olur.</p>
    
        <p>Çok sayıda süreç kullanıyorsanız:</p>
    
        <ul>
          <li>Güvenli bölgeler oluşturmanız gerekiyordur. Örneğin, şirket2’deki hiç
            kimse dosya sistemi üzerinden şirket1’e ait verileri okuyamasın, sadece
            herkes gibi tarayıcı kullanarak okuyabilsin istenebilir.  Bu durumda,
            <code class="directive"><a href="../mod/mod_unixd.html#user">User</a></code>,
            <code class="directive"><a href="../mod/mod_unixd.html#group">Group</a></code>,
            <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> ve
            <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> yönergeleri farklı
            değerlerle yapılandırılmış iki ayrı süreç çalıştırmanız gerekir.</li>
    
          <li>Makine üzerindeki her IP adresini dinlemek için gereken dosya tanıtıcı
            ve bellek miktarını makul bir seviyede tutabilirsiniz. Bu sadece belli
            adresleri dinleyerek veya çok sayıda adresle eşleşen adres kalıpları
            kullanarak mümükün olabilir. Zaten, bir sebeple belli bir adresi dinleme
            ihtiyacı duyarsanız, diğer tüm adresleri de ayrı ayrı dinlemeniz
            gerekir. (Bir <code class="program"><a href="../programs/httpd.html">httpd</a></code> programı N-1 adresi dinlerken
            diğerleri kalan adresleri dinleyebilir.)</li>
        </ul>
    
        <p>Tek bir süreç kullanıyorsanız:</p>
    
        <ul>
          <li><code class="program"><a href="../programs/httpd.html">httpd</a></code> yapılandırmasının sanal konaklar arasında
            paylaşılmasına izin veriliyor demektir.</li>
    
          <li>Makine çok büyük miktarda isteği karşılayabilir ve ayrı ayrı
            süreçlerin çalışmasından kaynaklanan önemli başarım kayıpları
            yaşanmaz.</li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multiple" id="multiple">Çok sayıda sürecin yapılandırılması</a></h2>
    
        <p>Her sanal konak için ayrı bir <code class="program"><a href="../programs/httpd.html">httpd</a></code> yapılandırması
          oluşturulur. Her yapılandırmada, o süreç tarafından sunulacak IP adresi
          (veya sanal konak) için <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>
          yönergesi kullanılır. Örnek:</p>
    
        <pre class="prettyprint lang-config">Listen 192.0.2.100:80</pre>
    
    
        <p>Burada konak ismi yerine IP adresi kullanmanız önerilir (ayrıntılar için
          <a href="../dns-caveats.html">DNS ile ilgili konular</a> belgesine
          bakınız).</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="single" id="single">Sanal konaklar tek bir sürecin yapılandırılması</a></h2>
    
        <p>Bu durum için, ana sunucu ve sanal konakların tümüne gelen istekler tek
          bir <code class="program"><a href="../programs/httpd.html">httpd</a></code> süreci tarafından karşılanır. Yapılandırma
          dosyasında, her sanal konak için, farklı değerlere sahip <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>, <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>, <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>, <code class="directive"><a href="../mod/core.html#errorlog">ErrorLog</a></code>ve<code class="directive"><a href="../mod/mod_log_config.html#transferlog">TransferLog</a></code>
          veya <code class="directive"><a href="../mod/mod_log_config.html#customlog">CustomLog</a></code> yönergeleri
          içeren ayrı birer <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> bölümü
          oluşturulur. Örnek:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 192.168.1.10:80&gt;
        ServerAdmin bilgi@example.com
        DocumentRoot "/siteler/belgeler/ecom"
        ServerName example.com
        ErrorLog "/siteler/gunlukler/ecom/hatalar.log"
        CustomLog "/siteler/gunlukler/ecom/erisim.log" combined
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 192.168.1.20:80&gt;
        ServerAdmin bilgi@example.org
        DocumentRoot "/siteler/belgeler/eorg"
        ServerName example.org
        ErrorLog "/siteler/gunlukler/eorg/hatalar.log"
        CustomLog "/siteler/gunlukler/eorg/erisim.log" combined
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>&lt;VirtualHost&gt; yönergesinde konak ismi yerine
           IP adresi kullanmanız önerilir (ayrıntılar için
           <a href="../dns-caveats.html">DNS ile ilgili konular</a>
           belgesine bakınız).</p>
    
        <p>Belli bir IP adresi veya port kullanımı bunların joker eşdeğerlerine
          göre daha yüksek öncelik sağlar ve eşleşen bir sanal konak da genel
          sunucuya göre öncelik alır.</p>
    
        <p>Süreç oluşturmayı denetleyen yönergeler ve bir kaç başka yönerge dışında
          hemen hemen tüm yapılandırma yönergeleri <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> bölümleri içinde kullanılabilir.
          Bir yönergenin <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code>
          bölümlerinde kullanılıp kullanılmayacağını öğrenmek için <a href="../mod/quickreference.html">yönerge dizinini</a> kullanarak yönergenin
          <a href="../mod/directive-dict.html#Context">Bağlam</a>’ına bakınız.</p>
    
        <p><a href="../suexec.html">suEXEC sarmalayıcısı</a> kullanıldığı takdirde
          <code class="directive"><a href="../mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> yönergesi de
          bir <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> bölümü içinde
          kullanılabilir.</p>
    
        <p><em>GÜVENLİK:</em>Günlük dosyalarının yazılacağı yeri belirlerken,
          Apache’yi başlatan kullanıcıdan başka kimsenin yazamayacağı bir yerin
          seçilmesi bazı güvenlik risklerini ortadan kaldırmak bakımından
          önemlidir. Ayrıntılar için <a href="../misc/security_tips.html">güvenlik
          ipuçları</a> belgesine bakınız.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/ip-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/name-based.html.ko.euc-kr�������������������������������������������0000664�0001751�0001751�00000043125�14743132254�023046� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title≯ ȣƮ  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">ȣƮ</a></div><div id="page-content"><div id="preamble"><h1≯ ȣƮ </h1>
    <div class="toplang">
    <p><span> : </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>  ̸ ȣƮ ϴ  
        Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#namevip"≯  IP ȣƮ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#using"≯ ȣƮ ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#compat">  ȣȯ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="ip-based.html">IP ȣƮ </a></li><li><a href="details.html">ȣƮ ã⿡  ڼ </a></li><li><a href="mass.html">뷮 ȣƮ  ϱ</a></li><li><a href="examples.html">Ϲ ȣƮ </a></li><li><a href="examples.html#serverpath">ServerPath  </a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="namevip" id="namevip"≯  IP ȣƮ</a></h2>
    
        <p>IP ȣƮ  IP ּҸ  
        ȣƮ Ѵ. ׷  ȣƮ  ٸ IP ּҸ
         Ѵ. ̸ ȣƮ   Ŭ̾Ʈ
        HTTP  ȣƮ ˷ֱ ٶ. ̷  
        IP ּҷ  ٸ ȣƮ   ִ.</p>
    
        <p≯ ȣƮ DNS   ȣƮ ùٸ
        IP ּҷ ϵ ȣƮ ϰ, ٸ ȣƮ 
         ֵ ġ  ϱ⸸ ϸǹǷ  ϴ. ̸
        ȣƮ   IP ּҰ ʿ. ׷Ƿ Ư
        IP ȣƮ   ٸ ̸ ȣƮ
        ؾ Ѵ. IP ȣƮ ؾ δ:</p>
    
    	<ul>
            <li≯ ȣƮ ʴ 
            Ŭ̾Ʈ ִ. ̸ ȣƮ Ϸ
            Ŭ̾Ʈ HTTP Host   Ѵ. ̴
            HTTP/1.1 ʼ̰, ֱ  HTTP/1.0 鵵
            Ȯ Ѵ.  ̸ ȣƮ ϸ鼭
             Ŭ̾Ʈ ؾ Ѵٸ    ִ
             .</li>
    
            <li>SSL  ݻ SSL ȼ ̸
            ȣƮ   .</li>
    
            <li> ü Ʈ ġ ٸ IP ּҸ 
             ȣƮ  ϴ Ʈ 뷮(bandwidth)
             Ѵ.</li>
    	</ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using"≯ ȣƮ ϱ</a></h2>
    
    <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code></li><li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li><li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li><li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p≯ ȣƮ Ϸ   
        IP ּҸ (Ƹ Ʈ) ؾ Ѵ. ̴ <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> þ ϴ.
        Ϲ   IP ּҸ Ѵٸ
        <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>
        ƱԸƮ <code>*</code> Ѵ.  Ʈ 
        ( , SSL ) ȹ̶ <code>*:80</code>
         ƱԸƮ Ʈ ߰ؾ Ѵ. <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> þ IP ּҸ
        ־ٰ  ڵ  IP ּҸ ٸ 
        ϶. ڼ  <a href="../bind.html">ġ
         ּҿ Ʈ ϱ</a> ϶. , ⼭
         IP ּҴ  Ʈ ̽̾ Ѵ.</p>
    
        <p> ܰ Ϸ ȣƮ <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 
         ̴. <code class="directive"><a href="../mod/core.html#virtualhost&gt;">&lt;VirtualHost&gt;&gt;</a></code> þ ƱԸƮ
        <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> þ
        ƱԸƮ( , IP ּҳ  ּҸ ϴ <code>*</code>)
        ƾ Ѵ. <code class="directive"><a href="../mod/core.html#virtualhost&gt;">&lt;VirtualHost&gt;&gt;</a></code>  ȿ
        ּ  ȣƮ ϴ <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> þ ȣƮ
         Ͻý  ִ ϴ <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> þ ʿϴ.</p>
    
        <div class="note"><h3> ȣƮ </h3>
            <p> ϴ  ȣƮ ߰Ѵٸ
             ϴ ȣƮ  <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> ϵ ߰ؾ
            Ѵ.  Ͽ ϴ <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> ü <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> ƾ Ѵ.
            Ͽ  ȣƮ    ⺻ ȣƮ
            ȴ.</p>
        </div>
    
        <p>  <code>www.domain.tld</code>  ϰ
        ־µ  IP ּҿ
        <code>www.otherdomain.tld</code> ȣƮ ߰ϰ
        ʹٰ . <code>httpd.conf</code>  
        ߰ϸ ȴ:</p>
    
        <div class="example"><p><code>
            NameVirtualHost *:80<br />
            <br />
            &lt;VirtualHost *:80&gt;<br />
            <span class="indent">
                ServerName www.domain.tld<br />
                ServerAlias domain.tld *.domain.tld<br />
                DocumentRoot /www/domain<br />
            </span>
            &lt;/VirtualHost&gt;<br />
            <br />
            &lt;VirtualHost *:80&gt;<br />
            <span class="indent">ServerName www.otherdomain.tld<br />
                DocumentRoot /www/otherdomain<br />
            </span>
            &lt;/VirtualHost&gt;<br />
        </code></p></div>
    
        <p><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        þ   <code>*</code>   IP ּҸ 
         ִ.  , ̷  IP ּҿ  ̸
        ȣƮ , ٸ ּҿ IP Ȥ ̸
        ȣƮ   ִ.</p>
    
        <p>   ̸   ֱ ٶ. ̴
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
         ȿ <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>
        þ Ͽ ϴ.    ù° <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> Ͽ
        <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> þ
        ϸ  ̸  Ʈ   ִ:</p>
    
        <div class="example"><p><code>
            ServerAlias domain.tld *.domain.tld
        </code></p></div>
    
        <p><code>domain.tld</code> ο ִ  ȣƮ 
        û <code>www.domain.tld</code> ȣƮ Ѵ.
        ̸ ٶ ϵī  <code>*</code> <code>?</code>
          ִ.  <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>̳ <code>ServerAlias</code>
        ̸ ־ٰ  ƴϴ.   ̸ 
        IP ּҷ ϵ DNS  ˸° ؾ Ѵ.</p>
    
        <p> <code class="directive"><a href="../mod/core.html#&lt;virtualhost&gt;">&lt;&lt;VirtualHost&gt;&gt;</a></code> ȿ ٸ
        þ Ͽ ȣƮ ڼ   ִ.
        κ þ   , õ ȣƮ 
        Ѵ.  þ 밡 ˷ þ <a href="../mod/directive-dict.html#Context"></a>
        Ȯ϶. (<code class="directive"><a href="../mod/core.html#&lt;virtualhost&gt;">&lt;&lt;VirtualHost&gt;&gt;</a></code>  ƴ)
        <em>ּ</em>   þ ȣƮ
          þ  쿡 ȴ.</p>
    
        <p>û    <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>  IP
        ּ ˻Ѵ. ׷ٸ  IP ּҸ  <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        ǵ鿡 û ȣƮ ġϴ <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>̳
        <code>ServerAlias</code> ã´. ã   Ѵ.
         ȣƮ ãϸ, IP ּҿ شϴ
        <strong>ȣƮ ù° </strong> Ѵ.</p>
    
        <p> ó  ȣƮ <em>⺻</em>
        ȣƮ ȴ. IP ּҰ <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> þ شϸ,
        <em>ּ</em> <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
        <strong></strong>  ʴ´. Ư ȣƮ
        شʴ û Ϸ  <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>  Ͽ
          ϸ ȴ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compat" id="compat">  ȣȯ</a></h2>
    
        <p>̹  ̸ ȣƮ ùٷ ϱ
        ʿ  ʴ Ŭ̾Ʈ ִ. ̷ Ŭ̾Ʈ
        ׻ û IP ּҿ  ù°  ȣƮ
        (<cite></cite> ̸ ȣƮ)
        Ѵ.</p>
    
        <div class="note"><h3>󸶳   ϴ°?</h3>
        <p>⼭ Ǿ     Ѵ.
        ó ̷    Ǿ. 
          ̸ ȣƮ ʿ <code>Host</code>
         .</p>
        </div>
    
        <p>  ణ 彺 <code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code> þ ذ  ִ:</p>
    
        <p> :</p>
    
        <div class="example"><p><code>
            NameVirtualHost 111.22.33.44<br />
            <br />
            &lt;VirtualHost 111.22.33.44&gt;<br />
            <span class="indent">
                ServerName www.domain.tld<br />
                ServerPath /domain<br />
                DocumentRoot /web/domain<br />
            </span>
            &lt;/VirtualHost&gt;<br />
        </code></p></div>
    
        <p>̰  ΰ? "<code>/domain</code>" ϴ
        URI  û ȣƮ <code>www.domain.tld</code>
        Ѵ.  , <code>Host:</code>   Ŭ̾Ʈ
        <code>http://www.domain.tld/</code>ε   ,
        <code>http://www.domain.tld/domain/</code>δ 
        Ŭ̾Ʈ    ִ.</p>
    
        <p≯   ȣƮ ִ 
        <code>http://www.domain.tld/domain/</code>  ũ
        ִ´. ׸ ȣƮ  븵ũ ( ,
        "<code>file.html</code>" ̳ "<code>../icons/image.gif</code>")
        Ȥ ("<code>http://www.domain.tld/domain/misc/file.html</code>"̳
        "<code>/domain/misc/file.html</code>" ) տ
        <code>/domain/</code>  ũ Ѵ.</p>
    
        <p> Ģ ʿ  Ģ  κ 
         ̳  ̳    
          ִ.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/name-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/fd-limits.html.fr.utf8����������������������������������������������0000664�0001751�0001751�00000023361�14740503670�022441� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Limites des descripteurs de fichiers - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Serveurs Virtuels</a></div><div id="page-content"><div id="preamble"><h1>Limites des descripteurs de fichiers</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Quand de nombreux serveurs virtuels sont créés, Apache peut
        dépasser les limites en descripteurs de fichiers ('file descriptors',
        également appelés <cite>gestionnaires de fichiers</cite>) si chacun
        des serveurs virtuels utilise ses propres fichiers journaux. Le
        nombre total de descripteurs de fichiers utilisés par Apache est
        d'un par fichier journal, un pour chacune des autres directives
        de fichiers journaux, plus un nombre constant compris entre 10 et 20
        pour son fonctionnement interne. Les systèmes d'exploitation Unix
        limitent le nombre de descripteurs de fichiers utilisables par
        processus&nbsp;; une valeur courante pour cette limite est de 64, et
        cette valeur peut le plus souvent être augmentée.</p>
    
        <p>Apache tente d'accroître cette valeur limite si nécessaire, mais
        sans y parvenir dans les cas suivants&nbsp;:</p>
    
        <ol>
          <li>Le système d'exploitation ne permet pas l'utilisation d'appels
          systèmes <code>setrlimit()</code>.</li>
    
          <li>L'appel <code>setrlimit(RLIMIT_NOFILE)</code> ne fonctionne pas
          sur votre système d'exploitation (c'est le cas sous Solaris 2.3).</li>
    
          <li>Le nombre de descripteurs de fichiers nécessaires à Apache
          dépasse la limite physique du matériel.</li>
    
          <li>Le système impose d'autres limites sur l'utilisation des
          descripteurs de fichiers, comme par exemple une limite sur les
          flux stdio, utilisables uniquement sur les descripteurs de
          fichiers inférieurs à 256. (sous Solaris 2).</li>
        </ol>
    
        <p>En cas de problème, Vous pouvez&nbsp;:</p>
    
        <ul>
          <li>Réduire le nombre de fichiers journaux, en ne spécifiant
          aucun fichier journal dans les sections
          <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>,
          en donc en envoyant les informations aux fichiers journaux du
          serveur principal (Voir <a href="#splitlogs">Éclatement des
          fichiers journaux</a> ci-dessous pour plus d'informations sur
          cette possibilité).</li>
    
          <li>
            Dans les cas 1 ou 2 (évoqués ci-dessus), augmentez la limite sur
            les descripteurs de fichiers avant le démarrage d'Apache, au
            moyen d'un script comme
    
            <div class="example"><p><code>
              <code>#!/bin/sh<br />
               ulimit -S -n 100<br />
               exec httpd</code>
            </code></p></div>
          </li>
        </ul>
    
    
    
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="splitlogs" id="splitlogs">Éclatement des fichiers journaux</a></h2>
    
    <p>Lorsque vous choisissez d'enregistrer les informations émanant de
    plusieurs serveurs virtuels dans un même fichier journal, vous voudrez
    ensuite pouvoir scinder ces informations à des fins de statistiques, par
    exemple, sur les différents serveurs virtuels. Il est possible de procéder
    de la manière suivante&nbsp;:</p>
    
    <p>Tout d'abord, vous devez ajouter le nom du serveur virtuel à chaque
    entrée du journal. Ceci se paramètre au moyen de la directive
    <code class="directive"><a href="../mod/mod_log_config.html#logformat"> LogFormat</a></code> et de la
    variable <code>%v</code>. Ajoutez cette variable au début de la chaîne
    de définition du format de journalisations&nbsp;:</p>
    
    <pre class="prettyprint lang-config">LogFormat "%v %h %l %u %t \"%r\" %&gt;s %b" vhost
    CustomLog logs/multiple_vhost_log vhost</pre>
    
    
    <p>Cette configuration va provoquer la création d'un fichier de
    journalisation au format standard (CLF&nbsp;: 'Common Log Format'), mais dont
    chaque ligne débutera par le nom canonique du serveur virtuel (spécifié
    par la directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>).
    (Voir <code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code> pour d'autres informations sur la
    personnalisation des fichiers journaux.)</p>
    
    <p>Au moment de séparer les informations du fichier journal en un fichier
    par serveur virtuel, le programme <code>
    <a href="../programs/other.html">split-logfile</a></code> peut être
    utilisé. Ce programme peut être trouvé dans le répertoire
    <code>support</code> de la distribution d'Apache.</p>
    
    <p>Exécutez ce programme au moyen de la commande&nbsp;:</p>
    
    <div class="example"><p><code>
    split-logfile &lt; /logs/multiple_vhost_log
    </code></p></div>
    
    <p>Une fois exécuté avec le nom du fichier contenant tous les journaux,
    ce programme va générer un fichier pour chacun des serveurs virtuels
    qui apparaît dans le fichier d'entrée. Chaque fichier en sortie est
    nommé <code>nomduserveur.log</code>.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/fd-limits.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/name-based.html.fr.utf8���������������������������������������������0000664�0001751�0001751�00000044551�14740503670�022551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Support Apache des serveurs virtuels par nom - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Serveurs virtuels</a></div><div id="page-content"><div id="preamble"><h1>Support Apache des serveurs virtuels par nom</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Ce document décrit quand et comment utiliser des serveurs
        virtuels par nom.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#namevip">Serveurs virtuels par nom vs. par IP</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#alg">Comment le serveur sélectionne-t-il le serveur
    virtuel basé sur le nom approprié</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#using">Utilisation de serveurs virtuels par nom</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="ip-based.html">Support Apache des serveurs virtuels par IP</a></li><li><a href="details.html">Détails sur le fonctionnement des serveurs virtuels</a></li><li><a href="mass.html">Configuration dynamique des hébergements virtuels de masse</a></li><li><a href="examples.html">Exemples d'utilisations de VirtualHost</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="namevip" id="namevip">Serveurs virtuels par nom vs. par IP</a></h2>
    
        <p>Les <a href="ip-based.html">serveurs virtuels</a> par IP utilisent l'adresse IP
        de la connexion afin de déterminer quel serveur virtuel doit
        répondre. Par conséquent, vous devez disposer d'adresses IP
        différentes pour chaque serveur.</p>
    
        <p>Avec un hébergement
        virtuel par nom, le serveur s'appuie sur les informations
        transmises par le client dans les en-têtes HTTP de ses requêtes.
        La technique présentée ici vous permet de disposer de serveurs
        virtuels différents partagés sur une même adresse IP.</p>
    
        <p>L'hébergement virtuel par nom est habituellement plus simple,
        car il vous suffit de configurer votre serveur DNS pour que
        chaque domaine pointe sur l'adresse IP dont vous disposez, et de
        configurer votre serveur Apache HTTP afin qu'il reconnaisse
        ces domaines. Il réduit aussi la pénurie en adresses IP. Par
        conséquent, vous devriez utiliser l'hébergement virtuel par
        nom, sauf dans le cas où vous utiliseriez des équipements qui
        nécessitent un hébergement basé sur IP. Les raisons historiques de
        l'hébergement basé sur IP dans un but de support de certains clients ne
        s'appliquent plus à un serveur web d'usage général.</p>
    
        <p>La sélection du serveur virtuel en fonction du nom s'opère en
        dehors de l'algorithme de sélection du serveur virtuel en fonction
        de l'adresse IP, ce qui signifie que les recherches du point de vue
        du nom du serveur ne s'effectuent que parmi le jeu de serveurs
        virtuels pour lesquels la correspondance avec la paire adresse
        IP/port est la plus exacte.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="alg" id="alg">Comment le serveur sélectionne-t-il le serveur
    virtuel basé sur le nom approprié</a></h2>
    
        <p>Il est important de savoir que la première étape de la résolution
        de serveur virtuel basée sur le nom est une résolution basée sur IP.
        La résolution de serveur virtuel basée sur le nom ne fait que
        choisir le serveur virtuel basé sur le nom le plus approprié, en se
        limitant aux candidats qui conviennent le mieux du point de vue IP.
        La résolution basée sur IP est sans objet si l'on
        utilise un caractère générique (*) pour l'adresse IP dans
        toutes les directives VirtualHost.</p>
    
        <p>A l'arrivée d'une requête, le serveur va rechercher l'argument de
        section <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> présentant la meilleure
        (la plus exacte) correspondance avec la paire adresse IP/port
        utilisée dans la requête. Si plusieurs serveurs virtuels possèdent
        cette même paire adresse IP/port, Apache va ensuite comparer les
        valeurs des directives <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> et <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> avec le nom de serveur
        présent dans la requête.</p>
    
        <p>Si vous ne définissez pas de directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> pour un serveur virtuel à base
        de nom, le serveur utilisera par défaut le nom de domaine
        entièrement qualifié (FQDN) déduit du nom d'hôte système. Cette
        configuration sans nom de serveur explicite peut conduire à des
        erreurs de choix du serveur virtuel à utiliser et est déconseillée.</p>
    
        <h3><a name="defaultvhost" id="defaultvhost">Le serveur virtuel à base de nom
        par défaut pour une paire adresse IP/port</a></h3>
        <p>Si aucune directive ServerName ou ServerAlias ne correspond dans
        la liste de serveurs virtuels présentant la meilleure correspondance
        du point de vue adresse IP/port, c'est <strong>le premier serveur
        virtuel de cette liste</strong> qui sera utilisé.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Utilisation de serveurs virtuels par nom</a></h2>
    
    <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li><li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
    
        <p>La première étape consiste à créer une section
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        pour chacun des serveurs à définir. Dans chaque section
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>,
        vous devez définir au minimum une directive
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> pour désigner
        le serveur concerné et une directive
        <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> pour préciser
        l'emplacement sur le système de fichiers du contenu de ce serveur.</p>
    
        <div class="note"><h3>Le serveur principal disparaît</h3>
            <p>Toute requête qui ne correspond à aucune section <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> existante
    	est traitée avec la configuration du serveur principal, sans
    	tenir compte du nom d'hôte ou de la directive ServerName.</p>
    
            <p>Lorsque vous ajoutez un serveur virtuel basé sur le nom à un
    	serveur existant, et si les caractéristiques de ce serveur
    	virtuel correspondent à des combinaisons IP/port préexistantes,
    	les requêtes seront alors traitées par un serveur virtuel
    	explicite. Dans ce cas, il est en général judicieux de créer un
    	<a href="#defaultvhost">serveur virtuel par défaut</a>
    	comportant une directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> correspondant au nom du
    	serveur principal. De nouveaux domaines sur les mêmes interface
    	et port, mais nécessitant des configurations distinctes,
    	pourront alors être ajoutés en tant que serveurs virtuels
    	spécifiques (et non par défaut).</p>
        </div>
    
        <div class="note"><h3>Héritage du nom de serveur</h3>
           <p>Il est toujours préférable de définir une directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> au niveau de chaque serveur
           virtuel à base de nom. Si un serveur virtuel ne définit pas
           de directive  <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>, le
           nom de ce serveur virtuel sera hérité du serveur principal. Si
           aucun nom de serveur n'a été explicitement défini au niveau du
           serveur principal, le serveur tentera de déterminer son nom via
           une résolution de nom DNS inverse sur la première adresse
           d'écoute. Dans tous les cas, ce nom de serveur hérité influencera
           la sélection du serveur virtuel à base de nom, c'est pourquoi il
           est toujours préférable de définir une directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> pour chaque serveur virtuel
           à base de nom.</p>
        </div>
    
        <p>Par exemple, supposez que vous hébergez le domaine
        <code>www.example.com</code> et que vous souhaitez ajouter le
        serveur virtuel <code>other.example.com</code> qui pointe sur
        la même adresse IP. Il vous suffit d'ajouter la configuration
        suivante à <code>httpd.conf</code>&nbsp;:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost *:80&gt;
        # Le premier serveur virtuel de la liste est aussi le
        # serveur par défaut pour *:80
        ServerName www.example.com
        ServerAlias example.com
        DocumentRoot "/www/domain"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
        ServerName other.example.com
        DocumentRoot "/www/otherdomain"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Autrement, vous pouvez spécifiez une adresse IP explicite
        à la place de <code>*</code> dans la directive
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.
        Par exemple, cette méthode est utile si vous souhaitez faire
        tourner quelques serveurs virtuels par nom sur une même adresse
        IP, et d'autres, soit par IP, soit basés sur un autre jeu de
        serveurs virtuels par nom sur une autre adresse IP.</p>
    
        <p>Plusieurs serveurs sont accessibles par plus d'un nom. Il
        suffit de placer la directive
        <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> dans une section
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.
        Par exemple, dans la première section
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        ci-dessus, la directive <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>
        indique aux utilisateurs les autres noms permis pour accéder au
        même site Web&nbsp;:</p>
    
        <pre class="prettyprint lang-config">ServerAlias example.com *.example.com</pre>
    
    
        <p>ainsi, toutes les requêtes portant sur un domaine
        <code>example.com</code> seront servies par le serveur virtuel
        <code>www.example.com</code>. Les caractères joker <code>*</code>
        et <code>?</code> peuvent être utilisés pour les correspondances.
        Bien entendu, vous ne pouvez pas inventer des noms et les placer
        dans une directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>
        ou <code>ServerAlias</code>. Tout d'abord, votre serveur DNS
        doit être correctement configuré pour lier ces noms à une
        adresse IP associée avec votre serveur.</p>
    
        <p>La recherche du serveur virtuel à base de nom qui correspond au
        plus près à la requête s'effectue parmi les <code class="directive"><a href="../mod/core.html#virtualhost">&lt;virtualhost&gt;</a></code> selon leur
        ordre d'apparition dans le fichier de configuration. Le premier
        serveur virtuel dont le <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> ou le <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> correspond est utilisé, sans
        priorité particulière en cas de présence de caractères génériques
        (que ce soit pour le ServerName ou le ServerAlias).</p>
    
        <p>La liste complète des noms dans la section <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> sont traités comme une
        directive <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> sans
        caractères génériques.</p>
    
        <p>Finalement, vous pouvez affiner la configuration des serveurs
        virtuels en plaçant d'autres directives à l'intérieur des sections
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.
        La plupart des directives peut être placée dans ces sections en
        y changeant seulement la configuration du serveur virtuel associé.
        Pour déterminer si une directive particulière est permise,
        consultez le <a href="../mod/directive-dict.html#Context">contexte</a> de la
        directive. Le jeu de directives configurées dans le contexte
        du <em>serveur principal</em> (en dehors de toutes sections
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>)
        sera utilisé seulement s'il n'y a pas de configuration contraire
        par un serveur virtuel.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/name-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html.en�������������������������������������������������������0000664�0001751�0001751�00000017504�14737241666�021002� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache Virtual Host documentation - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache Virtual Host documentation</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
        <p>The term <cite>Virtual Host</cite> refers to the practice of
        running more than one web site (such as
        <code>company1.example.com</code> and <code>company2.example.com</code>)
        on a single machine. Virtual hosts can be "<a href="ip-based.html">IP-based</a>", meaning that you have a
        different IP address for every web site, or "<a href="name-based.html">name-based</a>", 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.</p>
    
        <p>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 <em>host-based</em> or <em>non-IP virtual hosts</em>.</p>
    
        <p>Below is a list of documentation pages which explain all
        details of virtual host support in Apache HTTP Server:</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#support">Virtual Host Support</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#directives">Configuration directives</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li><li><a href="name-based.html">Name-based virtual
    hosts</a></li><li><a href="ip-based.html">IP-based virtual hosts</a></li><li><a href="examples.html">Virtual host examples</a></li><li><a href="fd-limits.html">File descriptor limits</a></li><li><a href="mass.html">Mass virtual hosting</a></li><li><a href="details.html">Details of host matching</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">Virtual Host Support</a></h2>
    
        <ul>
          <li><a href="name-based.html">Name-based Virtual Hosts</a> (More
          than one web site per IP address)</li>
          <li><a href="ip-based.html">IP-based Virtual Hosts</a> (An IP
          address for each web site)</li>
          <li><a href="examples.html">Virtual Host examples for common
          setups</a></li>
          <li><a href="fd-limits.html">File Descriptor Limits</a> (or,
          <em>Too many log files</em>)</li>
          <li><a href="mass.html">Dynamically Configured Mass Virtual
          Hosting</a></li>
          <li><a href="details.html">In-Depth Discussion of Virtual Host
          Matching</a></li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="directives" id="directives">Configuration directives</a></h2>
    
        <ul>
          <li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li>
        </ul>
    
        <p>If you are trying to debug your virtual host configuration, you
        may find the <code>-S</code> command line switch
        useful.</p>
    
        <div class="example"><h3>Unix example</h3><p><code>
        
        apachectl -S
        </code></p></div>
    
        <div class="example"><h3>Windows example</h3><p><code>
        
        httpd.exe -S
        </code></p></div>
    
    
        <p>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 <code class="program"><a href="../programs/httpd.html">httpd</a></code> program for
        other command line options)</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/details.html.tr.utf8������������������������������������������������0000664�0001751�0001751�00000046207�14743132254�022217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Sanal Konak Eşlemenin Derinliğine İncelenmesi - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Sanal Konaklar</a></div><div id="page-content"><div id="preamble"><h1>Sanal Konak Eşlemenin Derinliğine İncelenmesi</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/details.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Bu belgede, bir istek aldığında Apache’nin hangi sanal konak
          ile hizmet sunacağına nasıl karar verdiği açıklanmaya çalışılmıştır.</p>
    
        <p>Çoğu kullanıcı hangi türü kullanacağına karar vermek için önce <a href="name-based.html#namevip">İsme dayalı ve IP’ye dayalı Sanal
          Konak</a> bölümünü, sonra <a href="name-based.html">İsme Dayalı Sanal
          Konak Desteği</a> veya <a href="ip-based.html">IP’ye Dayalı Sanal Konak
          Desteği</a> belgesini okumalı ve <a href="examples.html">bazı
          örneklere</a> göz atmalıdır.</p>
    
        <p>Bunlardan sonra tüm ayrıntıları anlamak isterseniz tekrar bu sayfaya
          gelebilirsiniz.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configparsing">Yapılandırma Dosyası</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#hostmatching">Sanal Konağın Belirlenmesi</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#tips">İpuçları</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="ip-based.html">IP’ye Dayalı Sanal Konak Desteği</a></li><li><a href="name-based.html">İsme Dayalı Sanal Konak Desteği</a></li><li><a href="examples.html">Çok Kullanılan Sanal Konak Örnekleri</a></li><li><a href="mass.html">Devingen olarak Yapılandırılan Kitlesel Sanal Barındırma</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configparsing" id="configparsing">Yapılandırma Dosyası</a></h2>
    
        <p>Bu belgede <code>&lt;VirtualHost&gt;</code> bölümleri dışında kalan
          tanımlardan bahsederken <em>ana_sunucu</em> diyeceğiz.</p>
    
        <p><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
          bölümlerindeki tanımlamalardan bahsederken <em>sankonlar</em>
          diyeceğiz.</p>
    
        <p>Her <code>VirtualHost</code> bölümü en az bir adres ve isteğe bağlı
          portlar içerir.</p>
    
        <p>Sanal konak tanımlarının içindeki IP adreslerinin yerine konak isimleri
          kullanılabilir, fakat bunlar başlatma sırasında çözümleneceklerinden
          çözümlemedeki bir başarısızlık bu sanal konak tanımlarının yoksayılması
          ile sonuçlanacaktır. Bu bakımdan önerilmez.</p>
    
        <p><code>VirtualHost</code> yönergesinde görünen her adresin seçimlik bir
          portu olabilir. Eğer bir port belirtilmemişse, port olarak <code>*</code>
          belirtilmiş gibi bütün portlar dinlenir.</p>
    
        <p>(<code>VirtualHost</code> yönergesinde belirtilen port numaraları Apache
          httpd'nin dinleyeceği port numaraları olarak yorumlanmaz, sadece bir
          isteği işleme sokarken hangi <code>VirtualHost</code> bölümünün
          seçileceğini belirlerler. Sunucunun dinleyeceği adresleri ve portları
          belirtmek için <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>
          yönergesini kullanın.)</p>
    
        <p>Adreslerin tamamını (DNS sorgularındaki çoklu sonuçlar dahil) içeren
          kümeye <em>sankonların adres kümesi</em> denir.</p>
    
        <p>Apache httpd, bir IP adresi ve port birleşimi için en belirgin
          eşleşmelerin listelendiği çok sayıdaki sanal konak arasında ayırdedici
          olarak istemci tarafından sağlanan HTTP <code>Host</code> başlığını
          kullanır.</p>
    
        <p><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> yönergesi sunucu
          tanımının içinde herhangi bir yerde görünebilirse de her göründüğü yerde
          bir öncekini iptal eder. Hiç <code>ServerName</code> belirtilmemişse,
          Apache httpd, sunucu ismini sunucunun IP adresinden saptamaya
          çalışır.</p>
    
        <p>Belli bir IP adresi ve port çifti için yapılandırma dosyasındaki ilk
          isme dayalı sankon önemlidir, çünkü başka hiçbir sankonun ServerName veya
          ServerAlias yönergesi ile eşleşmeyen bu adres ve port çifti için alınmış
          tüm isteklerde bu sankon kullanılır. Ayrıca, sunucunun <a class="glossarylink" href="../glossary.html#servernameindication" title="sözlüğe bakınız">Sunucu İsmi Belirtimi</a>ni
          desteklemediği durumlarda tüm SSL bağlantıları için bu sankon
          kullanılır.</p>
    
        <p><code>VirtualHost</code> içindeki isimlerin sırası (jokersiz) bir
          <code>ServerAlias</code> gibi ele alınır (fakat hiçbir
          <code>ServerAlias</code> yönergesi ile geçersiz kılınmaz).</p>
    
        <p>Her sankon için bazı değerler öntanımlı olarak atanır. Bunların
          başlıcaları:</p>
    
        <ol>
          <li>Sankon bir <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>
            yönergesi içermiyorsa,
            <code class="directive"><a href="../mod/core.html#timeout">Timeout</a></code>,
            <code class="directive"><a href="../mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code>,
            <code class="directive"><a href="../mod/core.html#keepalive">KeepAlive</a></code>,
            <code class="directive"><a href="../mod/core.html#maxkeepaliverequests">MaxKeepAliveRequests</a></code>,
            <code class="directive"><a href="../mod/mpm_common.html#receivebuffersize">ReceiveBufferSize</a></code> ve
            <code class="directive"><a href="../mod/mpm_common.html#sendbuffersize">SendBufferSize</a></code> yönergeleri için
            öntanımlı değerler ana_sunucudaki eşdeğerlerinden miras alınır. (Yani,
            bu yönergeler için ana_sunucudaki son değerler miras alınır.)</li>
    
          <li>Sankon için öntanımlı dizin erişim izinlerinin tanımlandığı "arama
            öntanımlıları" ana_sunucununkilere katılır. Buna her modülün dizinlere
            özgü yapılandırma bilgileri dahildir.</li>
    
          <li>Her modülün ana_sunucudaki sunuculara özgü yapılandırmaları sankon
            sunucusununkilerle katıştırılır.</li>
        </ol>
    
        <p>Esasen, ana_sunucu, sankon sunucularını oluştururken bir öntanımlılar
          listesi veya öntanımlı değerlere dayanak noktası olarak ele alınır.
          Fakat bu ana_sunucu tanımlarının yapılandırma dosyasındaki yerlerinin
          saptanmasının konumuzla ilgisi yoktur; ana_sunucu yapılandırmasının
          tamamı son katıştırma yapılacağı zaman çözümlenir. Bu bakımdan,
          ana_sunucu tanımlarından bir kısmı sankon tanımlarından sonra yer alsa
          bile sankon tanımlarında etkili olabilir.</p>
    
        <p>Eğer, bu noktada ana_sunucu hiçbir <code>ServerName</code> satırı
          içermiyorsa <code class="program"><a href="../programs/httpd.html">httpd</a></code> programının çalıştığı makinenin
          konak ismi öntanımlıdır. Ana_sunucunun <code>ServerName</code> için
          yaptığı DNS sorgusundan dönen IP adreslerine <em>ana_sunucu adres
          kümesi</em> diyoruz.</p>
    
        <p>Tanımsız <code>ServerName</code> alanları için bir isme dayalı sankon,
          sankonu tanımlayan <code>VirtualHost</code> yönergesinde belirtilen ilk
          adresi öntanımlı değer kabul eder.</p>
    
        <p>Sihirli <code>_default_</code> sankonları için ana_sunucunun
          <code>ServerName</code> değeri kullanılır.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hostmatching" id="hostmatching">Sanal Konağın Belirlenmesi</a></h2>
    
        <p>Sunucu bir istek durumunda hangi sankonun kullanılacağını şöyle
          belirler:</p>
    
        <h3><a name="hashtable" id="hashtable">IP adresi aranır</a></h3>
    
        <p>Bir adres ve port için bağlantı ilk alındığında Apache httpd tüm
          <code>VirtualHost</code> tanımlarında bu çifti arar.</p>
    
        <p>Arama başarısız olursa <code>*</code> (herşey) eşleşmelerine
          bakılır.</p>
    
        <p>Bir eşleşme bulunamazsa hizmet ana sunucudan sunulur.</p>
    
        <p>Arama sonucunda bu IP adresi için bulunmuş <code>VirtualHost</code>
          tanımları varsa sonraki adım hizmetin bir IP’ye dayalı sankondan mı yoksa
          isme dayalı bir sankondan mı sunulacağına karar vermektir.</p>
    
        
    
        <h3><a name="ipbased" id="ipbased">IP’ye dayalı sankon</a></h3>
    
        <p>Eğer en iyi eşleşme olarak saptanmış IP adresi ve port çiftini içeren
          sadece bir <code>VirtualHost</code> yönergesi varsa artık karar vermek
          için başka bir şey yapmaya gerek yoktur ve istek bu sankondan
          sunulur.</p>
    
        
    
        <h3><a name="namebased" id="namebased">İsme dayalı sankon</a></h3>
    
        <p>Eğer en iyi eşleşme olarak saptanmış IP adresi ve port çiftini içeren
          birden fazla <code>VirtualHost</code> yönergesi varsa, sonraki
          adımlardaki "liste" eşleşen sankonların listesi olup sankonlar listede
          yapılandırma dosyasındaki yerlerine göre sıralanırlar.</p>
    
        <p>Bağlantı SSL kullanıyorsa, sunucunun <a class="glossarylink" href="../glossary.html#servernameindication" title="sözlüğe bakınız">Sunucu İsmi Belirtimi</a>ni
          desteklediği durumlarda SSL istemci uzlaşımı, istenen konak ismiyle
          birlikte TLS eklentisini de içeriyorsa, konak ismi, SSL olmayan
          bağlantılardaki <code>Host:</code> başlığı kullanımına benzer şekilde
          aşağıdaki gibi kullanılır. Aksi takdirde, SSL bağlantıları için adresin
          eşleştiği ilk isme dayalı sankon kullanılır. Sunucunun bağlantı için
          hangi sertifikayı kullanacağını sankon belirlediği için bu önemlidir.</p>
    
        <p>İstek bir <code>Host:</code> başlık alanı içeriyorsa, listede
          <code>ServerName</code> veya <code>ServerAlias</code> alanı başlık alanı
          ile eşleşen ilk sankona bakılır. <code>Host:</code> alanı bir port
          içerebilirse de Apache httpd bunu yoksayarak daima istemcinin isteği
          gönderdiği portu gerçek port kabul eder.</p>
    
        <p>Yapılandırma dosyasındaki belirtilen IP adresiyle eşleşen ilk sankon en
          yüksek önceliğe sahiptir ve sunucu ismi bilinmeyen ve (bir HTTP/1.0
          isteği gibi) <code>Host:</code> başlık alanı içermeyen istekleri de
          yakalar.</p>
    
        
    
        <h3><a name="persistent" id="persistent">Kalıcı bağlantılar</a></h3>
    
        <p>Yukarıda açıklanan <em>IP araması</em> belli bir TCP/IP oturumunda
          <em>bir</em> defaya mahsus yapıldığı halde bir kalıcı/KeepAlive bağlantı
          sırasında <em>her</em> istek için ayrı bir <em>arama</em> yapılır. Başka
          bir deyişle, bir istemci tek bir kalıcı bağlantı üzerinde farklı isme
          dayalı sankonlardan sayfa talebinde bulunabilir.</p>
    
        
    
        <h3><a name="absoluteURI" id="absoluteURI">Mutlak URI</a></h3>
    
        <p>Eğer istekte belirtilen URI bir mutlak URI ise ve istek yapılan konak
          ismi ve port ana sunucuyla veya sankonlardan biriyle eşleşiyorsa,
          şema/konakadı/port öneki ayrılır ve elde edilen göreli URI ilgili
          sankondan veya ana sunucudan sunulur. Eğer bir eşleşme sağlanamazsa
          URI’ye dokunulmaz ve istek bir vekil isteği olarak ele alınır.</p>
    
    
    <h3><a name="observations" id="observations">İzlenimler</a></h3>
    
        <ul>
          <li>İsme dayalı sanal konak işlemleri, sunucunun en iyi eşleşen IP'ye
            dayalı sanal konağı seçmesinin ardından uygulanır.</li>
    
          <li>İstemcinin hangi IP adresine bağlandığını umursamıyorsanız, sanal
            konaklarınızda adres olarak "*" kullanın, böylece yapılandırılmış
            sankonların hepsine isme dayalı sanal konak işlemleri uygulanır.</li>
    
          <li>Bir IP’ye dayalı sankon için asla <code>ServerAlias</code> ve
            <code>ServerPath</code> değerine bakılmaz.</li>
    
          <li>Sıralama sadece aynı IP adresine sahip isme dayalı sankonlar arasında
            önemlidir. Aynı adres kümesine mensup isme dayalı sankonlardan
            yapılandırma dosyasında ilk sırada yer alanı en yüksek önceliğe
            sahiptir.</li>
    
          <li>Eşleştirme işlemi sırasında <code>Host:</code>
            başlık alanında belirtilen port asla kullanılmaz. Apache httpd daima
            istemcinin isteği gönderdiği gerçek portu kullanır.</li>
    
          <li>Eğer aynı IP adresine sahip IP’ye dayalı iki sankon varsa, bunlara
            örtük olarak isme dayalı sanal konak işlemleri uygulanır. 2.3.11
            sürümünden beri yeni davranış şekli budur.</li>
    
          <li>Ana_sunucunun bir isteğe hizmet sunabilmesi için istemcinin
            bağlandığı IP adresi ve port hiçbir yerde belirtilmemiş ve
            hiçbir sankon ile eşleşme sağlanamamış olmalıdır. Başka bir deyişle,
            istemcinin bağlandığı port ile eşleşen bir <code>_default_</code>
            sankon olmadıkça adres ve port belirtmeyen bir isteğe ana_sunucu yanıt
            verecektir.</li>
    
          <li><code>VirtualHost</code> yönergelerinde asla DNS isimleri
            belirtmemelisiniz. Aksi takdirde sunucuyu başlatma sırasında DNS
            sorgusu yapmaya zorlamış olursunuz. Listelenen tüm alanlar için DNS
            üzerinde tam denetime sahip değilseniz bu ayrıca bir güvenlik
            tehdidine yol açar. Bu konuda daha ayrıntılı bilgi edinmek için <a href="../dns-caveats.html">DNS ile ilgili konular ve Apache</a>
            belgesine bakınız.</li>
    
          <li><code>ServerName</code> her sankon için ayrı ayrı belirlenmiş
            olmalıdır. Aksi takdirde her sankon için bir DNS sorgusu gerekir.</li>
          </ul>
          
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">İpuçları</a></h2>
    
        <p><a href="../dns-caveats.html#tips">DNS konuları</a> sayfasındaki
          ipuçlarına ilaveten burada da bazı ipuçları bulacaksınız:</p>
    
        <ul>
          <li>Ana sunucu tanımlarının hepsini <code>VirtualHost</code>
            tanımlarının öncesinde bitirin. Bu ayrıca yapılandırmanızın
            okunabilirliğini de arttırır; <code>VirtualHost</code> tanımlarının
            sonrasına sarkan yapılandırmaların katıştırılması işlemi tüm sanal
            konakları etkileyebilen tanımlar bakımından bir
            karışıklığa/belirsizliğe sebep olabilir.)</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/vhosts/details.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/details.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/fd-limits.html.ja.utf8����������������������������������������������0000664�0001751�0001751�00000024441�14743132254�022423� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ファイル記述子の限界 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">バーチャルホスト</a></div><div id="page-content"><div id="preamble"><h1>ファイル記述子の限界</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    
        <p>たくさんのバーチャルホストを運用する場合、もし、
        各バーチャルホストごとに異なるログファイルが指定してあると、
        Apache がファイル記述子 (<cite>ファイルハンドル</cite>とも呼ばれます)
        を使い切ってしまうことがあります。Apache が使用するファイル
        記述子の数は、各エラーログファイルにつき 1 つ、他のログファイルの
        ディレクティブにつき 1 つ、さらに内部で使用する 10 から 20、
        の合計になります。Unix オペレーティングシステムではプロセスごとに
        使用可能なファイル記述子の数を制限しています。たいていの場合は 64 で、
        普通は大きな値のハードリミットまで増やすことができます。</p>
    
        <p>Apache は必要に応じて上限を拡大しようと試みますが、
        以下のような場合にはうまくいかないかもしれません。</p>
    
        <ol>
          <li>利用しているシステムで <code>setrlimit()</code>
          システムコールが提供されていない。</li>
    
          <li>システム上で <code>setrlimit</code>(RLIMIT_NOFILE) が動作しない
          (たとえば Solaris 2.3 のように)。</li>
    
          <li>要求されるファイル記述子の数が
          ハードリミットを超えてしまう。</li>
          
          <li>システムにファイル記述子に関して別の制限が存在してしまっている。
          たとえば、stdio ストリームではファイル記述子を 256 以上使えない
          (Solaris 2)、など。</li>
        </ol>
    
        <p>問題が発生した時に取り得る対処方法は次のとおり:</p>
    
        <ul>
          <li>ログファイルの数を減らす。<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
          セクションでログファイルを指定せず、メインのログファイルにのみ記録する。
          (これに関する詳しい情報は以下の<a href="#splitlogs">ログファイルの分割</a>を読んでください。)</li>
    
          <li>
            もし、前述の 1 または 2 の場合であれば、
            Apache を起動する前にファイル記述子を増やします。
            たとえば次のようなスクリプトを使います。
    
            <div class="example"><p><code>
              <code>#!/bin/sh<br />
               ulimit -S -n 100<br />
               exec httpd</code>
            </code></p></div>
          </li>
        </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="splitlogs" id="splitlogs">ログファイルの分割</a></h2>
    
    <p>複数のバーチャルホストのログを同じログファイルに収集しようとしているときには、
    各バーチャルホストについて統計的な解析を実行するために後でログファイルを
    分割したくなるかもしれません。これは以下のようにして実現できます。</p>
    
    <p>まず、バーチャルホストの情報をログのエントリに追加する必要があります。
    これは <code class="directive"><a href="../mod/mod_log_config.html#logformat">LogFormat</a></code>
    ディレクティブの <code>%v</code> 変数を使うことでできます。
    これをログのフォーマット文字列の先頭に追加します:</p>
    
    <div class="example"><p><code>
    LogFormat "%v %h %l %u %t \"%r\" %&gt;s %b" vhost<br />
    CustomLog logs/multiple_vhost_log vhost
    </code></p></div>
    
    <p>これは common log format のログを作成しますが、それぞれの行の先頭に
    正規化されたバーチャルホストの名前
    (<code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>
    ディレクティブに書かれているもの) が付加されます。
    (ログファイルのカスタマイズの詳細については <a href="../mod/mod_log_config.html#formats">Custom Log Formats</a> を
    読んでください。)</p>
    
    <p>ログファイルを各部分 (バーチャルホスト毎に 1 ファイル) に分けたいときは、
    <code><a href="../programs/other.html">split-logfile</a></code>
    を使って行なうことができます。プログラムは Apache 配布の 
    <code>support</code> ディレクトリにあります。</p>
    
    <p>以下のようなコマンドでこのプログラムを実行します:</p>
    
    <div class="example"><p><code>
    split-logfile &lt; /logs/multiple_vhost_log
    </code></p></div>
    
    <p>このプログラムはバーチャルホストのログファイルの名前とともに実行され、
    ログファイルに現れるそれぞれのバーチャルホスト毎に一つのファイルを作成します。
    それぞれのファイルは <code>ホスト名.log</code> という名前になります。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/vhosts/fd-limits.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/fd-limits.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html.ko.euc-kr������������������������������������������������0000664�0001751�0001751�00000017037�14743132254�022164� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ ȣƮ  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ġ ȣƮ </h1>
    <div class="toplang">
    <p><span> : </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    
        <p><cite>ȣƮ (Virtual Host)</cite>  ǻͿ
         Ʈ ( , <code>www.company1.com</code>
        <code>www.company2.com</code>)  Ѵ.
        ȣƮ  Ʈ ٸ IP ּҸ ϴ
        "<a href="ip-based.html">IP (IP-based)</a>" İ 
        IP ּҴ  ̸  "<a href="name-based.html"≯ (name-based)</a>" 
        ִ.  Ʈ   ִٴ  ڴ
        ġä Ѵ.</p>
    
        <p>ġ ⺻ IP ȣƮ  â
         ϳ. ġ  1.1 ̻ IPݰ ̸
        ȣƮ  Ѵ. ̸ ȣƮ
        <em>ȣƮ (host-based)</em> Ǵ <em>IP ȣƮ
        (non-IP virtual hosts)</em> θ.</p>
    
        <p> ġ  1.3 ̻ ȣƮ  ڼ
         ̴.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#support">ȣƮ </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#directives"> þ</a></li>
    </ul><h3></h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li><li><a href="name-based.html"≯ ȣƮ</a></li><li><a href="ip-based.html">IP ȣƮ</a></li><li><a href="examples.html">ȣƮ </a></li><li><a href="fd-limits.html">ϱ Ѱ</a></li><li><a href="mass.html">뷮 ȣƮ</a></li><li><a href="details.html">ȣƮ ã⿡  ڼ </a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="support" id="support">ȣƮ </a></h2>
    
        <ul>
          <li><a href="name-based.html"≯ ȣƮ</a>
          (IP ּҴ  Ʈ)</li>
          <li><a href="ip-based.html">IP ȣƮ</a> (
          Ʈ IP ּ)</li>
          <li><a href="examples.html">Ϲ ȣƮ </a></li>
          <li><a href="fd-limits.html">ϱ(file descriptor)
          Ѱ</a> (, <em>ʹ  α</em>)</li>
          <li><a href="mass.html">뷮 ȣƮ 
          ϱ</a></li>
          <li><a href="details.html">ȣƮ ã⿡  ڼ
          </a></li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="directives" id="directives"> þ</a></h2>
    
        <ul>
          <li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li>
          <li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li>
        </ul>
    
        <p>ȣƮ  ׽ƮҶ ġ <code>-S</code>
         ɼ ϴ. ,   Ѵ:</p>
    
        <div class="example"><p><code>
        /usr/local/apache2/bin/httpd -S
        </code></p></div>
    
        <p> ɾ ġ  Ͽ 
         Ѵ. IP ּҿ  ڼ 캸 
        Ǽ ߰ϴµ   ̴. (ٸ  ɼǵ
        <a href="../programs/httpd.html">httpd α׷ </a>
        ϶.)</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../de/vhosts/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/vhosts/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/ip-based.html.ko.euc-kr���������������������������������������������0000664�0001751�0001751�00000026340�14743132254�022536� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ IP ȣƮ  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">ȣƮ</a></div><div id="page-content"><div id="preamble"><h1>ġ IP ȣƮ </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#requirements">ý 䱸</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#howto">ġ </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multiple">  ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#single"> ϳ ȣƮ ϱ</a></li>
    </ul><h3></h3><ul class="seealso"><li>
    <a href="name-based.html"≯ ȣƮ </a>
    </li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">ý 䱸</a></h2>
    
        <p><cite>IP</cite>̶  ǹϵ 
        <strong>IP ȣƮ   ٸ IP ּҸ
        Ѵ</strong>. ̴ ǻ͸   Ʈ
        ϰų, ֱ ü ϴ  ̽
        (ڼ  ý  ϶.  "ip aliases"
        ϸ,  "ifconfig" ɾ ) Ͽ ϴ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">ġ </a></h2>
    
        <p> ȣƮ ϵ ġ ϴ  ΰ.
        ϳ  ȣƮ   ϴ
        ̰, ٸ ϳ  ȣƮ ϴ  Ѱ
        ϴ ̴.</p>
    
        <p>   ϳ:</p>
    
        <ul>
          <li>ȸ2 ڰ ̿  ȸ1 ڷḦ 
            ϴ  Ȼ  ʿ .  
             ٸ <code class="directive"><a href="../mod/mpm_common.html#user">User</a></code>, <code class="directive"><a href="../mod/mpm_common.html#group">Group</a></code>, <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>, <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code>  ؾ Ѵ.</li>
    
          <li> ޸𸮰 ְ, ǻ  IP ٸ
          ϱ(file descriptor) 䱸׵ Ѵ. "ϵī"
          Ư ּҸ <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>  ִ. ׷
            Ư ּҸ ٸ ʿ䰡 ִٸ, (
            ּҸ   ּҸ ٸ ٸ 
            ּҸ ٸ  )  ּ
          θ ٷ Ѵ.</li>
        </ul>
    
        <p>  Ѱ ϳ:</p>
    
        <ul>
          <li>ȣƮ     ִ .</li>
    
          <li>ǻͰ ſ  û Ѵٸ  
          ϱ⿡ ӵ ս Ŭ  ִ.</li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multiple" id="multiple">  ϱ</a></h2>
    
        <p> ȣƮ  ġѴ. 
        <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> þ
          IP ּ(Ȥ ȣƮ) ش. 
        ,</p>
    
        <div class="example"><p><code>
        Listen www.smallco.com:80
        </code></p></div>
    
        <p>ȣƮ ٴ IP ּҸ ϱ ٶ.
        (<a href="../dns-caveats.html">DNS </a> )</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="single" id="single"> ϳ ȣƮ ϱ</a></h2>
    
        <p>   Ѱ ּ  ȣƮ 
        û Ѵ.  <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> þ ȣƮ
        ٸ <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>,
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>, <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>, <code class="directive"><a href="../mod/core.html#errorlog">ErrorLog</a></code>, <code class="directive"><a href="../mod/mod_log_config.html#transferlog">TransferLog</a></code>,
        <code class="directive"><a href="../mod/mod_log_config.html#customlog">CustomLog</a></code>
        þ  Ѵ.  ,</p>
    
        <div class="example"><p><code>
        &lt;VirtualHost www.smallco.com&gt;<br />
        ServerAdmin webmaster@mail.smallco.com<br />
        DocumentRoot /groups/smallco/www<br />
        ServerName www.smallco.com<br />
        ErrorLog /groups/smallco/logs/error_log<br />
        TransferLog /groups/smallco/logs/access_log<br />
        &lt;/VirtualHost&gt;<br />
    		<br />
        &lt;VirtualHost www.baygroup.org&gt;<br />
        ServerAdmin webmaster@mail.baygroup.org<br />
        DocumentRoot /groups/baygroup/www<br />
        ServerName www.baygroup.org<br />
        ErrorLog /groups/baygroup/logs/error_log<br />
        TransferLog /groups/baygroup/logs/access_log<br />
        &lt;/VirtualHost&gt;
    		</code></p></div>
    
        <p>ȣƮ ٴ IP ּҸ ϱ ٶ.
        (<a href="../dns-caveats.html">DNS </a> )</p>
    
        <p>VirtualHost þ ȿ μ  Ÿ  þ
        ϰ  <strong></strong> þ 
         ִ. VirtualHost þ ȿ þ   ִ
        ˷ <a href="../mod/directives.html">þ </a>
        <a href="../mod/directive-dict.html#Context"></a>
        Ȯ϶.</p>
    
        <p><a href="../suexec.html">suEXEC α׷</a>
        Ѵٸ VirtualHost þ ȿ <code class="directive"><a href="../mod/mpm_common.html#user">User</a></code> <code class="directive"><a href="../mod/mpm_common.html#group">Group</a></code>   ִ.</p>
    
        <p><em>:</em>  ϴ ڿܿ ٸ 
        α ִ 丮  ִٸ 
         ϶. ڼ  <a href="../misc/security_tips.html"> </a> ϶.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/ip-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/name-based.html.ja.utf8���������������������������������������������0000664�0001751�0001751�00000056251�14743132254�022533� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>名前ベースのバーチャルホスト - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">バーチャルホスト</a></div><div id="page-content"><div id="preamble"><h1>名前ベースのバーチャルホスト</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>この文書では名前ベースのバーチャルホストをどんなとき、
        どうやって使うかを説明します。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#namevip">名前ベースと IP ベースのバーチャルホストの比較</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#using">名前ベースのバーチャルホストを利用する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#compat">古いブラウザとの互換性</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="ip-based.html">ネームベースのバーチャルホスト</a></li><li><a href="details.html">バーチャルホストのマッチングについての詳細</a></li><li><a href="mass.html">大量のバーチャルホストの動的な設定</a></li><li><a href="examples.html">バーチャルホストの一般的な設定例</a></li><li><a href="examples.html#serverpath">ServerPath 設定例</a></li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="namevip" id="namevip">名前ベースと IP ベースのバーチャルホストの比較</a></h2>
    
        <p>IP ベースのバーチャルホストでは、応答する
        バーチャルホストへのコネクションを決定するために IP
        アドレスを使用します。ですから、それぞれのホストに個々に IP
        アドレスが必要になります。これに対して名前ベースのバーチャルホストでは、
        クライアントが HTTP ヘッダの一部としてホスト名を告げる、
        ということに依存します。この技術で同一 IP 
        アドレスを異なる多数のホストで共有しています。</p>
    
        <p>名前ベースのバーチャルホストは通常単純で、それぞれのホスト名と
        それに対応する正確な IP アドレスを DNS で設定し、異なる
        ホスト名を区別するように Apache HTTP サーバを設定するだけです。
        さらに、名前ベースのバーチャルホストは不足する IP
        アドレスの需要を緩和します。したがって、IP ベースのバーチャルホストを
        選択すべき特定の理由がなければ名前ベースのバーチャルホストを使うべきです。
        IP ベースのバーチャルホストを使用することを考慮する理由として、</p>
    
        <ul> 
          <li>名前ベースのバーチャルホストに対応していない古いクライアントがある
          名前ベースのバーチャルホストが働くためには、クライアントは
          HTTP ホストヘッダを送ってこなければなりません。
          これは HTTP/1.1 の仕様で要求されていて、すべての現代的な
          HTTP/1.0 ブラウザでも拡張として実装されています。
          とても古いクライアントをサポートしつつ、名前ベースの
          バーチャルホストを行いたい場合は、この文書の最後の方に
          書かれている解決策になるかもしれない方法を見てください。</li>
    
          <li>名前ベースのバーチャルホストは SSL プロトコルの特徴により、
          SSL セキュアサーバには使えません。</li>
    
          <li>オペレーティングシステムやネットワーク装置のなかには、
          別の IP アドレス上でない場合、複数のホストを別扱いできないような
          帯域管理の方法を実装しているものがあります。</li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">名前ベースのバーチャルホストを利用する</a></h2>
    
    <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code></li><li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li><li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code></li><li><code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code></li><li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>名前ベースのバーチャルホストを使うには、そのホストへの
        リクエストを受け付けるサーバの IP アドレス (もしかしたらポートも)
        を指定する必要があります。
        これは <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>
        ディレクティブで設定します。通常、<code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> で
        <code>*</code> の属性を使ってサーバの全ての IP アドレスを使います。
        (例えば SSL の使用などで) 複数のポートを使うことを計画しているのであれば、
        引数に <code>*:80</code> のようにポートも含めるようにしてください。
        <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> ディレクティブで
        IP アドレスを書いても、
        自動的にサーバがその IP アドレスをリッスンするということはないことに
        注意してください。詳細は「<a href="../bind.html">Apache の使うアドレスと
        ポートを設定する</a>」を読んでください。さらに、ここで指定された
        IP アドレスは全てサーバのネットワークインターフェースと関連付けられて
        いなければなりません。</p>
    
        <p>次は、扱うホストそれぞれに対して <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> ブロックを
        作成してください。<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        ディレクティブの引数は <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>
        ディレクティブの引数と同じにしてください (すなわち、IP アドレスか、全てのアドレスを意味する
        <code>*</code>)。それぞれの <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        ディレクティブの中には、最低限、どのホストが扱われるかを示す <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> ディレクティブと、
        そのホスト用のコンテンツがファイルシステム上のどこにあるかを示す
        <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> ディレクティブを
        書く必要があります。</p>
    
        <div class="note"><h3>メインホストはなくなります</h3>
            <p>既にあるウェブサーバにバーチャルホストを追加する場合、
            既存のウェブサーバに対しても <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
            ブロックを作らなければなりません。このバーチャルホストの
            <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> と
            <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
            は、グローバルな <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> と
            <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
            と同じものにします。また、このバーチャルホストを設定ファイルの中で
            先頭に置いて、デフォルトホストとして動作するようにします。</p>
        </div>
    
        <p>たとえば、<code>www.domain.tld</code> を動かしていて、
        さらにバーチャルホスト <code>www.otherdomain.tld</code>
        を追加するとしましょう。このバーチャルホストは同一 IP を指しているとします。
        そのような場合は、<code>httpd.conf</code>
        に以下のようなコードを追加するだけです</p>
    
        <div class="example"><p><code>
            NameVirtualHost *:80<br />
            <br />
            &lt;VirtualHost *:80&gt;<br />
            <span class="indent">
                ServerName www.domain.tld<br />
                ServerAlias domain.tld *.domain.tld<br />
                DocumentRoot /www/domain<br />
            </span>
            &lt;/VirtualHost&gt;<br />
            <br />
            &lt;VirtualHost *:80&gt;<br />
            <span class="indent">ServerName www.otherdomain.tld<br />
                DocumentRoot /www/otherdomain<br />
            </span>
            &lt;/VirtualHost&gt;<br />
        </code></p></div>
    
        <p><code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code> 及び
        <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> のどちらの場合も、
        * の部分には明示的に IP アドレスを指定することができます。
        例えば、ある IP アドレスでは名前ベースのバーチャルホストを使いたい一方で、
        別の IP アドレスでは、他の IP ベースのバーチャルホストや
        別組の名前ベースのバーチャルホストを使いたい場合、
        そう設定することになるでしょう。</p>
    
        <p>複数の名前でサーバアクセスができるようにしたいことも多いでしょう。
        このようなことは、<code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> ディレクティブを <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        セクションに記述することで実現できます。
        例えば上記の <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> の例であれば、
        次のように一覧に挙げられた名前が、
        ユーザが同一のウェブサイトとして目にして使用できるサーバ名である、
        と <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>
        ディレクティブで指定できます。</p> 
    
        <div class="example"><p><code>
            ServerAlias domain.tld *.domain.tld
        </code></p></div>
    
        <p><code>domain.tld</code> ドメインへの全てのホストへのリクエストは
        <code>www.domain.tld</code> のバーチャルホストが処理します。
        名前をマッチさせるために、ワイルドカード文字 * や ? 
        を使用することもできます。もちろん思いつきの名前を作って、
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> や 
        <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>
        にその名前を書くといったことはできません。まずは、
        これらの名前が サーバに付けられた IP アドレスにマップされるように
        DNS サーバを適切に設定しなければなりません。</p>
    
        <p>最後に、<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> コンテナの中に
        他のディレクティブを書くことで、バーチャルホストの設定を細かく調整
        することができます。
        ほとんどのディレクティブはこれらのコンテナに設置することができて、
        変更点はそのバーチャルホストに対してのみ有効になります。
        どのディレクティブを書くことができるかは、ディレクティブの <a href="../mod/directive-dist.html#context">コンテキスト</a> を
        調べてください。<em>主サーバコンテキスト</em>
        (<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        コンテナの外) の設定用ディレクティブはバーチャルホストでの設定で
        上書きされない場合のみ使用されます。</p>
    
        <p>リクエストが来ると、サーバはまず最初に <code class="directive"><a href="../mod/core.html#namevirtualhost">&lt;NameVirtualHost&gt;</a></code>
        にマッチする IP アドレスかどうかをチェックします。マッチすれば
        マッチした IP アドレスの <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        のそれぞれのセクションの中から 
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> か
        <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> 
        に要求されたホスト名があるか探します。
        見つかればそのサーバ用の設定を使います。マッチするバーチャルホスト
        が見つからなければ、マッチした IP アドレスの 
        <strong>リストの最初にあるバーチャルホスト</strong> が使われます。</p>
    
        <p>結果として、リストの最初のバーチャルホストが <em>デフォルト</em> の
        バーチャルホストになります。IP アドレスが <code class="directive"><a href="../mod/core.html#namevirtualhost">NameVirtualHost</a></code>
        ディレクティブにマッチした場合は、<em>メインのサーバ</em> の
        <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> 
        は<strong>決して使われません</strong>
        どのバーチャルホストにもマッチしないリクエストに対して、
        特別な設定をしたいのであれば、設定ファイル中の最初の
        <code>&lt;VirtualHost&gt;</code> コンテナにそれを記述してください。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compat" id="compat">古いブラウザとの互換性</a></h2>
    
        <p>以前述べたように、名前ベースのバーチャルホストが正しく動作する
        ために必要な情報を送ってこないクライアントが依然として存在しています。
        そのようなクライアントに対しては、該当する IP アドレスについて、
        一番最初に設定されているバーチャルホスト
        (<cite>プライマリ</cite>の名前ベースのバーチャルホスト)
        からページが送り返されます。</p>
    
        <div class="note"><h3>どのぐらい古いの ?</h3>
        <p>「古い」と表現している場合、本当に古いことを意味して使っています。
        不幸にして今現在でもこのような古いブラウザに遭遇することがあります。
        現在のブラウザは全て、名前ベースのバーチャルホストに必要な
        <code>Host</code> ヘッダを送ります。</p>
        </div>
    
        <p><a href="../mod/core.html#serverpath"><code>ServerPath</code></a>
        ディレクティブで対処が可能です。ちょっと不格好ですけれども。</p>
    
        <p>設定例</p>
    
        <div class="example"><p><code>
            NameVirtualHost 111.22.33.44<br />
            <br />
            &lt;VirtualHost 111.22.33.44&gt;<br />
            <span class="indent">
                ServerName www.domain.tld<br />
                ServerPath /domain<br />
                DocumentRoot /web/domain<br />
            </span>
            &lt;/VirtualHost&gt;<br />
        </code></p></div>
    
        <p>この例にはどういう意味があるでしょうか? これは
        "<code>/domain</code>" で始まる URI へのリクエストはすべて、
        バーチャルホスト <code>www.domain.tld</code> で処理される、
        という意味です。つまり、すべてのクライアントで
        <code>http://www.domain.tld/domain/</code> でアクセスできるページが、
        <code>Host:</code> ヘッダを送ってくるクライアントであれば
        <code>http://www.domain.tld/</code> としてもアクセスできる、
        という意味です。</p>
    
        <p>これが動作するようにするには、
        プライマリのバーチャルホストのページに
        <code>http://www.domain.tld/domain/</code> へのリンクを設置します。
        そして、バーチャルホストのページでは、純粋な相対リンク (<em>例:</em>
        "<code>file.html</code>" や "<code>../icons/image.gif</code>")、
        あるいは <code>/domain/</code> で始まるリンク (<em>例:</em>
        "<code>http://www.domain.tld/domain/misc/file.html</code>" や
        "<code>/domain/misc/file.html</code>") だけを設置します。</p>
    
        <p>これには、幾分かの規律が必要となりますが、
        このようなガイドラインを忠実に守ることにより、たいていの場合、
        すべてのブラウザで ― 新しいブラウザでも古いものでも ―
        作成したページが見えるということを保証します。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/name-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/examples.html.fr.utf8�����������������������������������������������0000664�0001751�0001751�00000064633�14740503670�022376� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Exemples d'utilisations de VirtualHost - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Serveurs virtuels</a></div><div id="page-content"><div id="preamble"><h1>Exemples d'utilisations de VirtualHost</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Le but de ce document est d'essayer de répondre aux questions 
        les plus répandues sur la configuration des <a href="index.html">serveurs virtuels</a>. 
        Les scénarios présentés ici se rencontrent quand plusieurs 
        serveurs Webs doivent tourner sur une seule et même machine au 
        moyen de serveurs virtuels <a href="name-based.html">par nom</a> 
        ou <a href="ip-based.html">par IP</a>.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#purename">Fonctionnement de plusieurs serveurs 
      virtuels par nom sur une seule adresse IP.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#twoips">Serveurs virtuels par nom sur plus 
        d'une seule adresse IP.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#intraextra">Servir le même contenu sur des 
        adresses IP différentes (telle qu'une adresse interne et une 
        externe).</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#port">Servir différents sites sur différents 
        ports.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ip">Hébergement virtuel basé sur IP</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipport">Hébergements virtuels mixtes basés sur 
        les ports et sur les IP</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mixed">Hébergements virtuels mixtes basé sur 
        les noms et sur IP</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#proxy">Utilisation simultanée de 
        <code>Virtual_host</code> et de mod_proxy</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#default">Utilisation de serveurs virtuels 
        <code>_default_</code></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#migrate">Migration d'un serveur virtuel 
    	par nom en un serveur virtuel par IP</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#serverpath">Utilisation de la directive 
        <code>ServerPath</code></a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="purename" id="purename">Fonctionnement de plusieurs serveurs 
      virtuels par nom sur une seule adresse IP.</a></h2>
    
        <p>Votre serveur possède plusieurs noms d'hôte qui correspondent à une seule
        adresse IP, et vous souhaitez des réponses différentes si on demande
        <code>www.example.com</code> ou <code>www.example.org</code>.</p>
    
        <div class="note"><h3>Note&nbsp;:</h3><p>La configuration de serveurs virtuels 
        sous Apache ne provoque pas leur apparition magique dans la 
        configuration du DNS. Il <em>faut</em> que leurs noms soient 
        définis dans le DNS, et qu'ils y soient résolus sur l'adresse IP 
        du serveur, faute de quoi personne ne pourra visiter votre site Web. 
        Il est possible d'ajouter des entrées dans le fichier 
        <code>hosts</code> pour tests locaux, mais qui ne fonctionneront 
        que sur la machine possédant ces entrées.</p>
        </div>
    
        <pre class="prettyprint lang-config"># Apache doit écouter sur le port 80
    Listen 80
    &lt;VirtualHost *:80&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
      
        # Autres directives ici
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
    
        # Autres directives ici
    &lt;/VirtualHost&gt;</pre>
    
       
    
        <p>Les astérisques correspondent à toutes les adresses, si bien que 
        le serveur principal ne répondra jamais à aucune requête. Comme le
        serveur virtuel
        <code>ServerName www.example.com</code> se trouve en premier dans le fichier 
        de configuration, il a la plus grande priorité et peut être vu 
        comme serveur <cite>par défaut</cite> ou <cite>primaire</cite>&nbsp;; 
        ce qui signifie que toute requête reçue ne correspondant à aucune 
        des directives <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> sera servie par ce premier 
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.</p>
    
        <p>La configuration ci-dessus correspond à ce que l'on souhaite pour
        la plupart des serveurs virtuels à base de nom. Il faudra cependant
        utiliser une configuration différente si vous souhaitez servir un
        contenu différent en fonction de l'adresse IP ou du port.</p>
    
        <div class="note">
                <h3>Note&nbsp;:</h3>
    
                <p>Vous pouvez remplacer <code>*</code> 
                par une adresse IP du système. Le serveur virtuel concerné
    	    ne sera alors sélectionné que pour les requêtes HTTP vers
    	    cette adresse IP.</p>
    
               <p>En général, il est commode d'utiliser <code>*</code> sur 
               les systèmes dont l'adresse IP n'est pas constante - par 
               exemple, pour des serveurs dont l'adresse IP est attribuée 
               dynamiquement par le FAI, et où le DNS est géré au moyen 
               d'un DNS dynamique quelconque. Comme <code>*</code> signifie 
               <cite>n'importe quelle adresse</cite>, cette configuration 
               fonctionne sans devoir être modifiée quand l'adresse IP du 
               système est modifiée.</p>
        </div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="twoips" id="twoips">Serveurs virtuels par nom sur plus 
        d'une seule adresse IP.</a></h2>
    
      	<div class="note">
              <h3>Note&nbsp;:</h3><p>Toutes les techniques présentées ici 
              peuvent être étendues à un plus grand nombre d'adresses IP.</p>
        </div>
    
        <p>Le serveur a deux adresses IP. Sur l'une 
        (<code>172.20.30.40</code>), le serveur "principal" 
        <code>server.example.com</code> doit répondre, et sur l'autre 
        (<code>172.20.30.50</code>), deux serveurs virtuels (ou plus) 
        répondront.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    
    # Serveur "principal" sur 172.20.30.40
    ServerName server.example.com
    DocumentRoot "/www/mainserver"
    
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
        
        # D'autres directives ici ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
        
        # D'autres directives ici ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Toute requête arrivant sur une autre adresse que 
        <code>172.20.30.50</code> sera servie par le serveur principal. 
        Les requêtes vers <code>172.20.30.50</code> avec un nom de serveur 
        inconnu, ou sans en-tête <code>Host:</code>, seront servies par 
        <code>www.example.com</code>.</p>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intraextra" id="intraextra">Servir le même contenu sur des 
        adresses IP différentes (telle qu'une adresse interne et une 
        externe).</a></h2>
    
        <p>La machine serveur dispose de deux adresses IP 
        (<code>192.168.1.1</code> et <code>172.20.30.40</code>). Cette 
        machine est placée à la fois sur le réseau interne (l'Intranet) 
        et le réseau externe (Internet). Sur Internet, le nom 
        <code>server.example.com</code> pointe vers l'adresse externe 
        (<code>172.20.30.40</code>), mais sur le réseau interne, ce même 
        nom pointe vers l'adresse interne (<code>192.168.1.1</code>).</p>
    
        <p>Le serveur peut être configuré pour répondre de la même manière 
        aux requêtes internes et externes, au moyen d'une seule section 
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 192.168.1.1 172.20.30.40&gt;
        DocumentRoot "/www/server1"
        ServerName server.example.com
        ServerAlias server
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Ainsi, les requêtes en provenance de chacun des deux réseaux 
        seront servies par le même <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.</p>
    
        <div class="note">
              <h3>Note&nbsp;:</h3><p>Sur le réseau interne, il est possible 
              d'utiliser le nom raccourci <code>server</code> au lieu du nom 
              complet <code>server.example.com</code>.</p>
    
              <p>Notez également que dans l'exemple précédent, vous pouvez 
              remplacer la liste des adresses IP par des <code>*</code> afin 
              que le serveur réponde de la même manière sur toutes ses 
              adresses.</p>
        </div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="port" id="port">Servir différents sites sur différents 
        ports.</a></h2>
    
        <p>Vous disposez de plusieurs domaines pointant sur la même adresse 
        IP et vous voulez également servir de multiples ports. L'exemple
        suivant montre que la sélection en fonction du nom intervient après
        la sélection de la meilleure correspondance du point de vue adresse
        IP/port.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    Listen 8080
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        ServerName www.example.com
        DocumentRoot "/www/domain-80"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        ServerName www.example.com
        DocumentRoot "/www/domain-8080"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        ServerName www.example.org
        DocumentRoot "/www/otherdomain-80"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        ServerName www.example.org
        DocumentRoot "/www/otherdomain-8080"
    &lt;/VirtualHost&gt;</pre>
    
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ip" id="ip">Hébergement virtuel basé sur IP</a></h2>
    
        <p>Le serveur dispose de deux adresses IP (<code>172.20.30.40</code> 
        et <code>172.20.30.50</code>) correspondant respectivement aux noms 
        <code>www.example.com</code> et <code>www.example.org</code>.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Les requêtes provenant d'adresses non spécifiées dans l'une des 
        directives <code>&lt;VirtualHost&gt;</code> (comme pour 
        <code>localhost</code> par exemple) seront dirigées vers le serveur 
        principal, s'il en existe un.</p>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipport" id="ipport">Hébergements virtuels mixtes basés sur 
        les ports et sur les IP</a></h2>
    
        <p>Le serveur dispose de deux adresses IP (<code>172.20.30.40</code> 
        et <code>172.20.30.50</code>) correspondant respectivement aux noms 
        <code>www.example.com</code> et <code>www.example.org</code>. 
        Pour chacun d'eux, nous voulons un hébergement sur les ports 80 
        et 8080.</p>
    
        <pre class="prettyprint lang-config">Listen 172.20.30.40:80
    Listen 172.20.30.40:8080
    Listen 172.20.30.50:80
    Listen 172.20.30.50:8080
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        DocumentRoot "/www/example1-80"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        DocumentRoot "/www/example1-8080"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:80&gt;
        DocumentRoot "/www/example2-80"
        ServerName www.example.org
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:8080&gt;
        DocumentRoot "/www/example2-8080"
        ServerName www.example.org
    &lt;/VirtualHost&gt;</pre>
    
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mixed" id="mixed">Hébergements virtuels mixtes basé sur 
        les noms et sur IP</a></h2>
    
        <p>Toute adresse indiquée comme argument d'une section VirtualHost
        et n'apparaissant dans aucun autre serveur virtuel, fait de cette
        section un serveur virtuel sélectionnable uniquement en fonction de
        son adresse IP.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example3"
        ServerName www.example.net
    &lt;/VirtualHost&gt;
    
    # IP-based
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example4"
        ServerName www.example.edu
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.60&gt;
        DocumentRoot "/www/example5"
        ServerName www.example.gov
    &lt;/VirtualHost&gt;</pre>
    
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Utilisation simultanée de 
        <code>Virtual_host</code> et de mod_proxy</a></h2>
    
        <p>L'exemple suivant montre comment une machine peut mandater 
        un serveur virtuel fonctionnant sur le serveur d'une autre machine. 
        Dans cet exemple, un serveur virtuel de même nom est configuré sur 
        une machine à l'adresse <code>192.168.111.2</code>. La directive 
        <code class="directive"><a href="../mod/mod_proxy.html#proxypreservehost">ProxyPreserveHost On</a></code> est
        employée pour permette au nom de domaine d'être préservé lors du 
        transfert, au cas où plusieurs noms de domaines cohabitent sur 
        une même machine.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost *:*&gt;
        ProxyPreserveHost On
        ProxyPass        "/" "http://192.168.111.2/"
        ProxyPassReverse "/" "http://192.168.111.2/"
        ServerName hostname.example.com
    &lt;/VirtualHost&gt;</pre>
    
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="default" id="default">Utilisation de serveurs virtuels 
        <code>_default_</code></a></h2>
    
        <h3><a name="defaultallports" id="defaultallports">Serveurs virtuels 
        <code>_default_</code> pour tous les ports</a></h3>
    
        <p>Exemple de capture de <em>toutes</em> les requêtes émanant 
        d'adresses IP ou de ports non connus, <em>c'est-à-dire</em>, d'un 
        couple adresse/port non traité par aucun autre serveur virtuel.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:*&gt;
        DocumentRoot "/www/default"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>L'utilisation d'un tel serveur virtuel avec un joker pour le 
        port empêche de manière efficace qu'une requête n'atteigne le 
        serveur principal.</p>
    
        <p>Un serveur virtuel par défaut ne servira jamais une requête 
        qui est envoyée vers un couple adresse/port utilisée par un 
        serveur virtuel par nom. Si la requête contient un en-tête 
        <code>Host:</code> inconnu, ou si celui-ci est absent, elle 
        sera toujours servie par le serveur virtuel primaire par nom 
        (celui correspondant à ce couple adresse/port trouvé en premier 
        dans le fichier de configuration).</p>
    
        <p>Vous pouvez utiliser une directive 
        <code class="directive"><a href="../mod/mod_alias.html#aliasmatch">AliasMatch</a></code> ou 
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> afin de 
        réécrire une requête pour une unique page d'information (ou pour 
        un script).</p>
        
    
        <h3><a name="defaultdifferentports" id="defaultdifferentports">Serveurs virtuels 
        <code>_default_</code> pour des ports différents</a></h3>
    
        <p>La configuration est similaire à l'exemple précédent, mais 
        le serveur écoute sur plusieurs ports et un second serveur virtuel 
        <code>_default_</code> pour le port 80 est ajouté.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:80&gt;
        DocumentRoot "/www/default80"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost _default_:*&gt;
        DocumentRoot "/www/default"
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Le serveur virtuel par défaut défini pour le port 80 (il doit 
        impérativement être placé avant un autre serveur virtuel par 
        défaut traitant tous les ports grâce au joker *) capture toutes 
        les requêtes envoyées sur une adresse IP non spécifiée. Le 
        serveur principal n'est jamais utilisé pour servir une requête.</p>
        
    
        <h3><a name="defaultoneport" id="defaultoneport">Serveurs virtuels 
        <code>_default_</code> pour un seul port</a></h3>
    
        <p>Nous voulons créer un serveur virtuel par défaut seulement 
        pour le port 80.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:80&gt;
        DocumentRoot "/www/default"
    ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Une requête vers une adresse non spécifiée sur le port 80 
        sera servie par le serveur virtuel par défaut, et toute autre 
        requête vers une adresse et un port non spécifiés sera servie 
        par le serveur principal.</p>
    
        <p>L'utilisation du caractère générique <code>*</code> dans la
        déclaration d'un serveur virtuel l'emporte sur
        <code>_default_</code>.</p>
        
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="migrate" id="migrate">Migration d'un serveur virtuel 
    	par nom en un serveur virtuel par IP</a></h2>
    
        <p>Le serveur virtuel par nom avec le nom de domaine 
        <code>www.example.org</code> (de notre <a href="#name">exemple 
        par nom</a>) devrait obtenir sa propre adresse IP. Pendant la 
        phase de migration, il est possible d'éviter les problèmes avec 
        les noms de serveurs et autres serveurs mandataires qui mémorisent 
        les vielles adresses IP pour les serveurs virtuels par nom.<br />
        La solution est simple, car il suffit d'ajouter la nouvelle 
        adresse IP (<code>172.20.30.50</code>) dans la directive 
        <code>VirtualHost</code>.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    ServerName www.example.com
    DocumentRoot "/www/example1"
    
    &lt;VirtualHost 172.20.30.40 172.20.30.50&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example3"
        ServerName www.example.net
        ServerAlias *.example.net
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Le serveur virtuel peut maintenant être joint par la nouvelle 
        adresse (comme un serveur virtuel par IP) et par l'ancienne 
        adresse (comme un serveur virtuel par nom).</p>
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="serverpath" id="serverpath">Utilisation de la directive 
        <code>ServerPath</code></a></h2>
    
        <p>Dans le cas où vous disposez de deux serveurs virtuels par nom, 
        le client doit transmettre un en-tête <code>Host:</code> correct 
        pour déterminer le serveur concerné. Les vieux clients HTTP/1.0 
        n'envoient pas un tel en-tête et Apache n'a aucun indice pour 
        connaître le serveur virtuel devant être joint (il sert la 
        requête à partir d'un serveur virtuel primaire). Dans un soucis 
        de préserver la compatibilité descendante, il suffit de créer 
        un serveur virtuel primaire chargé de retourner une page contenant 
        des liens dont les URLs auront un préfixe identifiant les serveurs 
        virtuels par nom.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 172.20.30.40&gt;
        # serveur virtuel primaire
        DocumentRoot "/www/subdomain"
        RewriteEngine On
        RewriteRule "." "/www/subdomain/index.html"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/subdomain/sub1"
        ServerName www.sub1.domain.tld
        ServerPath "/sub1/"
        RewriteEngine On
        RewriteRule "^(/sub1/.*)" "/www/subdomain$1
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/subdomain/sub2"
        ServerName www.sub2.domain.tld
        ServerPath "/sub2/"
        RewriteEngine On
        RewriteRule "^(/sub2/.*)" "/www/subdomain$1"
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>À cause de la directive 
        <code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code>, une requête sur 
        une URL <code>http://www.sub1.domain.tld/sub1/</code> est 
        <em>toujours</em> servie par le serveur sub1-vhost.<br />
        Une requête sur une URL <code>http://www.sub1.domain.tld/</code> n'est 
        servie par le serveur sub1-vhost que si le client envoie un en-tête 
        <code>Host:</code> correct. Si aucun en-tête <code>Host:</code> 
        n'est transmis, le serveur primaire sera utilisé.</p>
        <p>Notez qu'il y a une singularité&nbsp;: une requête sur 
        <code>http://www.sub2.domain.tld/sub1/</code> est également servie 
        par le serveur sub1-vhost si le client n'envoie pas d'en-tête 
        <code>Host:</code>.</p>
        <p>Les directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> 
        sont employées pour s'assurer que le client qui envoie un en-tête 
        <code>Host:</code> correct puisse utiliser d'autres variantes d'URLs, 
        <em>c'est-à-dire</em> avec ou sans préfixe d'URL.</p>
    
    	</div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/examples.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/examples.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/mass.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000047621�14740503670�021521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Hébergement virtuel de masse configuré dynamiquement - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Hébergement virtuel</a></div><div id="page-content"><div id="preamble"><h1>Hébergement virtuel de masse configuré dynamiquement</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/mass.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Ce document propose une méthode performante pour servir un nombre
        quelconque d'hôtes virtuels avec le serveur HTTP Apache. Un <a href="../rewrite/vhosts.html">document séparé</a> décrit comment
        utiliser <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour gérer l'hébergement
        virtuel de masse dynamique.
        </p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#motivation">A qui ce document est-il destiné ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#overview">Vue d'ensemble</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple">Hébergement virtuel
    dynamique avec mod_vhost_alias</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#homepages">Système de serveurs virtuels dynamiques
    simplifié</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#combinations">Utiliser plusieurs systèmes
    d'hébergement virtuel sur le même serveur</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipbased">Pour un hébergement virtuel par IP plus
    efficace</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Hébergement virtuel de masse avec
    mod_rewrite</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#macro">Hébergement virtuel en masse avec mod_macro</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="motivation" id="motivation">A qui ce document est-il destiné ?</a></h2>
    
        <p>Les techniques décrites ici vous concernent si votre
        <code>httpd.conf</code> contient de nombreuses sections
        <code>&lt;VirtualHost&gt;</code> très semblables,
        dans le style :</p>
    
    <pre class="prettyprint lang-config">&lt;VirtualHost 111.22.33.44&gt;
        ServerName                 customer-1.example.com
        DocumentRoot        "/www/hosts/customer-1.example.com/docs"
        ScriptAlias  "/cgi-bin/" "/www/hosts/customer-1.example.com/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName                 customer-2.example.com
        DocumentRoot        "/www/hosts/customer-2.example.com/docs"
        ScriptAlias  "/cgi-bin/" "/www/hosts/customer-2.example.com/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName                 customer-N.example.com
        DocumentRoot        "/www/hosts/customer-N.example.com/docs"
        ScriptAlias  "/cgi-bin/" "/www/hosts/customer-N.example.com/cgi-bin"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Nous voulons remplacer toutes les configurations
        <code>&lt;VirtualHost&gt;</code> par un mécanisme qui les génère
        dynamiquement. Ceci présente certains avantages :</p>
    
        <ol>
          <li>Votre fichier de configuration est plus petit, ainsi Apache
          démarre plus rapidement et consomme moins de mémoire. Et ce qui
          est peut-être le plus important, le fichier de configuration plus
          petit est plus facile à maintenir, et le risque d'erreurs en est
          diminué d'autant.
          </li>
    
          <li>Pour ajouter des serveurs virtuels, il suffit de créer les
          répertoires appropriés dans le système de fichiers et les entrées
          dans le DNS - il n'est plus nécessaire de reconfigurer ou de
          redémarrer Apache.</li>
        </ol>
    
        <p>Le principal désavantage réside dans le fait que vous ne pouvez
        pas définir un fichier journal différent pour chaque serveur
        virtuel. De toute façon, ce serait une mauvaise idée si vous avez de
        nombreux serveurs virtuels, car cela nécessiterait un <a href="fd-limits.html">nombre important de descripteurs de
        fichier</a>. Il est préférable de rediriger <a href="../logs.html#piped">les journaux via un pipe ou
        une file fifo</a> vers un
        programme, et faire en sorte que ce dernier éclate les journaux
        en un journal par serveur virtuel. L'utilitaire <a href="../programs/split-logfile.html">split-logfile</a>
        constitue un exemple de ce traitement.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Vue d'ensemble</a></h2>
    
        <p>Un serveur virtuel peut être défini par deux informations : son
        adresse IP, et le contenu de l'en-tête <code>Host:</code> de la
        requête HTTP. La technique d'hébergement virtuel dynamique de masse
        utilisée ici consiste à insérer automatiquement ces informations
        dans le chemin du fichier à utiliser pour répondre à la requête. On
        peut y parvenir assez facilement en utilisant
        <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> avec Apache httpd, mais on peut aussi
        <a href="../rewrite/vhosts.html">utiliser mod_rewrite</a>. </p>
        <p>Par défaut, ces deux modules
        sont désactivés ; vous devez activer l'un d'eux lors de la
        compilation et de la configuration d'Apache httpd si vous voulez utiliser
        cette technique.</p>
    
        <p>Certains paramètres doivent être extraits de la requête pour que le serveur
        dynamique se présente comme un serveur dynamique normal. Le plus
        important est le nom du serveur, que le serveur utilise pour générer des
        URLs d'auto-référencement, etc... Il est défini via la directive
        <code>ServerName</code>, et les CGIs peuvent s'y référer via la
        variable d'environnement <code>SERVER_NAME</code>. Sa véritable
        valeur utilisée à l'exécution est contrôlée par la définition de la
        directive
        <code class="directive"><a href="../mod/core.html#usecanonicalname">UseCanonicalName</a></code>. Avec
        <code>UseCanonicalName Off</code>, le nom du serveur correspond au
        contenu de l'en-tête <code>Host:</code> de la requête. Avec
        <code>UseCanonicalName DNS</code>, il est extrait d'une recherche
        DNS inverse sur l'adresse IP du serveur virtuel. La première
        configuration est utilisée pour l'hébergement virtuel dynamique par
        nom, et la deuxième pour l'hébergement virtuel dynamique par IP. Si
        httpd ne peut pas déterminer le nom du serveur, soit parce qu'il
        n'y a pas d'en-tête <code>Host:</code>, soit parce que la recherche
        DNS a échoué, il prend en compte la valeur définie par la directive
        <code>ServerName</code>.</p>
    
        <p>L'autre paramètre à extraire est la racine des documents (définie
        via la directive <code>DocumentRoot</code> et disponible pour les
        scripts CGI via la variable d'environnement <code>DOCUMENT_ROOT</code>).
        Dans une configuration classique, il est utilisé par le module core
        pour faire correspondre les URIs aux noms de fichiers, mais lorsque
        la configuration du serveur comporte des serveurs virtuels, ce
        traitement doit être pris en charge par un autre module (soit
        <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>, soit <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>), qui
        utilise un méthode de correspondance différente. Aucun de ces
        modules ne se chargeant de définir la variable d'environnement
        <code>DOCUMENT_ROOT</code>, si des CGIs ou des documents SSI
        doivent en faire usage, ils obtiendront une valeur erronée.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple" id="simple">Hébergement virtuel
    dynamique avec mod_vhost_alias</a></h2>
    
        <p>Cet extrait de fichier <code>httpd.conf</code> implémente
        l'hébergement virtuel décrit dans la section <a href="#motivation">À qui ce document est-il destiné ?</a> ci-dessus
        en utilisant <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>.</p>
    
    <pre class="prettyprint lang-config"># extrait le nom du serveur de l'en-tête Host:
    UseCanonicalName Off
    
    # ce format de journal peut être éclaté en journaux par serveur virtuel
    # à l'aide du premier champ via l'utilitaire split-logfile
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log" vcommon
    
    # inclut le nom du serveur dans les noms de fichiers ressources
    # nécessaires aux traitements des requêtes
    VirtualDocumentRoot "/www/hosts/%0/docs"
    VirtualScriptAlias  "/www/hosts/%0/cgi-bin"</pre>
    
    
        <p>Pour changer cette configuration en solution de serveur virtuel
        par IP, il suffit de remplacer <code>UseCanonicalName
        Off</code> par <code>UseCanonicalName DNS</code>. Le nom du serveur
        inséré dans le nom de fichier sera alors déduit de l'adresse IP du
        serveur virtuel. La variable <code>%0</code> fait référence au nom
        de serveur de la requête, tel qu'il est indiqué dans l'en-tête
        <code>Host:</code>.</p>
    
        <p>Voir la documentation du module <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>
        pour d'avantages d'exemples d'utilisation.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="homepages" id="homepages">Système de serveurs virtuels dynamiques
    simplifié</a></h2>
    
        <p>Il s'agit d'une adaptation du système ci-dessus, ajusté pour un
        serveur d'hébergement web de FAI. Grâce à la variable
        <code>%2</code>, on peut extraire des sous-chaînes de caractères du
        nom du serveur pour les utiliser dans le nom de fichier afin, par
        exemple, de définir <code>/home/user/www</code> comme emplacement des
        documents pour <code>www.user.example.com</code>. Un seul répertoire
        <code>cgi-bin</code> suffit pour l'ensemble des
        serveurs virtuels.</p>
    
    <pre class="prettyprint lang-config">UseCanonicalName Off
    
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log" vcommon
    
    # insertion d'une partie du nom du serveur dans les noms de fichiers
    VirtualDocumentRoot "/home/%2/www"
    
    # répertoire cgi-bin unique
    ScriptAlias  "/cgi-bin/"  "/www/std-cgi/"</pre>
    
    
        <p>Vous trouverez des exemples plus élaborés d'utilisation de la
        directive <code>VirtualDocumentRoot</code> dans la documentation du
        module <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="combinations" id="combinations">Utiliser plusieurs systèmes
    d'hébergement virtuel sur le même serveur</a></h2>
    
        <p>Moyennant une configuration un peu plus compliquée, vous pouvez
        contrôler la portée des différentes configurations d'hébergement
        virtuel à l'aide des directives <code>&lt;VirtualHost&gt;</code>
        normales de httpd. Par exemple, on peut associer une adresse IP pour
        les pages d'accueil des clients en général, et une autre pour les
        clients commerciaux avec la configuration suivante. Cette
        configuration peut être combinée avec les sections
        <code>&lt;VirtualHost&gt;</code> conventionnelles, comme indiqué
        plus loin.</p>
    
    <pre class="prettyprint lang-config">UseCanonicalName Off
    
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    
    &lt;Directory "/www/commercial"&gt;
        Options FollowSymLinks
        AllowOverride All
    &lt;/Directory&gt;
    
    &lt;Directory "/www/homepages"&gt;
        Options FollowSymLinks
        AllowOverride None
    &lt;/Directory&gt;
    
    &lt;VirtualHost 111.22.33.44&gt;
        ServerName www.commercial.example.com
        
        CustomLog "logs/access_log.commercial" vcommon
        
        VirtualDocumentRoot "/www/commercial/%0/docs"
        VirtualScriptAlias  "/www/commercial/%0/cgi-bin"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 111.22.33.45&gt;
        ServerName www.homepages.example.com
        
        CustomLog "logs/access_log.homepages" vcommon
        
        VirtualDocumentRoot "/www/homepages/%0/docs"
        ScriptAlias         "/cgi-bin/" "/www/std-cgi/"
    &lt;/VirtualHost&gt;</pre>
    
    
    <div class="note">
    	<h3>Note</h3>
    	<p>Si le premier bloc VirtualHost ne comporte <em>pas</em> de
    	directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>, c'est
    	le nom issu d'une recherche DNS inverse à partir de l'adresse IP
    	du serveur virtuel qui sera utilisé. Si ce nom ne correspond pas
    	à celui que vous voulez utiliser, vous pouvez ajouter une entrée
    	de remplacement (par exemple <code>ServerName
    	none.example.com</code>) pour éviter ce comportement.</p>
    </div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipbased" id="ipbased">Pour un hébergement virtuel par IP plus
    efficace</a></h2>
    
        <p>Les changements de configuration suggérés pour transformer <a href="#simple">le premier exemple</a> en hébergement virtuel par IP
        conduisent à une configuration peu efficace. Chaque requête
        nécessite une nouvelle recherche DNS. Pour éviter cette surcharge de
        travail, le système de fichiers peut être organisé pour correspondre
        aux adresses IP, plutôt qu'aux noms de serveurs, supprimant par
        la-même la nécessité d'une recherche DNS. La journalisation doit
        aussi être adaptée pour fonctionner sur un tel système.</p>
    
    <pre class="prettyprint lang-config"># obtention du nom du serveur par recherche DNS inverse
    # sur l'adresse IP
    UseCanonicalName DNS
    
    # insertion de l'adresse IP dans les journaux afin de pouvoir les
    # éclater
    LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log" vcommon
    
    # insertion de l'adresse IP dans les noms de fichiers
    VirtualDocumentRootIP "/www/hosts/%0/docs"
    VirtualScriptAliasIP  "/www/hosts/%0/cgi-bin"</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Hébergement virtuel de masse avec
    mod_rewrite</a></h2>
    
    <p>
    L'hébergement virtuel de masse peut aussi être effectué en utilisant
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>, soit à l'aide de simples directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>, soit en utilisant des
    techniques plus compliquées comme le stockage externe des définitions
    des serveurs virtuels, ces dernières étant accessibles via des
    directives <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>. Ces
    techniques sont décrites dans la <a href="../rewrite/vhosts.html">documentation sur la réécriture</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="macro" id="macro">Hébergement virtuel en masse avec mod_macro</a></h2>
    
    <p>Une autre option pour générer dynamiquement des serveurs virtuels :
    mod_macro ; ce module permet de créer un modèle de serveur virtuel que
    vous pourrez invoquer pour des noms d'hôtes multiples. La section
    <strong>Usage</strong> de la documentation du module présente un exemple qui
    illustre cette méthode.
    </p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/mass.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/mass.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/mass.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/mass.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/mass.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/fd-limits.html.en���������������������������������������������������0000664�0001751�0001751�00000021442�14737241666�021557� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>File Descriptor Limits - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Virtual Hosts</a></div><div id="page-content"><div id="preamble"><h1>File Descriptor Limits</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/vhosts/fd-limits.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>When using a large number of Virtual Hosts, Apache may run
        out of available file descriptors (sometimes called <cite>file
        handles</cite>) 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.</p>
    
        <p>Although Apache attempts to increase the limit as required,
        this may not work if:</p>
    
        <ol>
          <li>Your system does not provide the <code>setrlimit()</code>
          system call.</li>
    
          <li>The <code>setrlimit(RLIMIT_NOFILE)</code> call does not
          function on your system (such as Solaris 2.3)</li>
    
          <li>The number of file descriptors required exceeds the hard
          limit.</li>
    
          <li>Your system imposes other limits on file descriptors,
          such as a limit on stdio streams only using file descriptors
          below 256. (Solaris 2)</li>
        </ol>
    
        <p>In the event of problems you can:</p>
    
        <ul>
          <li>Reduce the number of log files; don't specify log files
          in the <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
          sections, but only log to the main log files. (See <a href="#splitlogs">Splitting up your log files</a>, below, for more
          information on doing this.)</li>
    
          <li>
            If your system falls into 1 or 2 (above), then increase the
            file descriptor limit before starting Apache, using a
            script like:
    
            <div class="example"><p><code>
              <code>#!/bin/sh<br />
               ulimit -S -n 100<br />
               exec httpd</code>
            </code></p></div>
          </li>
        </ul>
    
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="splitlogs" id="splitlogs">Splitting up your log files</a></h2>
    
    <p>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.</p>
    
    <p>First, you will need to add the virtual host information to the log
    entries. This can be done using the <code class="directive"><a href="../mod/mod_log_config.html#logformat">
    LogFormat</a></code>
    directive, and the <code>%v</code> variable. Add this to the beginning
    of your log format string:</p>
    
    <pre class="prettyprint lang-config">LogFormat "%v %h %l %u %t \"%r\" %&gt;s %b" vhost
    CustomLog logs/multiple_vhost_log vhost</pre>
    
    
    <p>This will create a log file in the common log format, but with the
    canonical virtual host (whatever appears in the
    <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> directive) prepended to
    each line. (See <code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code> for
    more about customizing your log files.)</p>
    
    <p>When you wish to split your log file into its component parts (one
    file per virtual host), you can use the program <code><a href="../programs/other.html">split-logfile</a></code> to accomplish
    this. You'll find this program in the <code>support</code> directory
    of the Apache distribution.</p>
    
    <p>Run this program with the command:</p>
    
    <div class="example"><p><code>
    split-logfile &lt; /logs/multiple_vhost_log
    </code></p></div>
    
    <p>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 <code>hostname.log</code>.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/vhosts/fd-limits.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/fd-limits.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/fd-limits.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/fd-limits.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/fd-limits.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/fd-limits.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/details.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000051664�14740503670�022205� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Détails sur le fonctionnement des serveurs virtuels - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Serveurs virtuels</a></div><div id="page-content"><div id="preamble"><h1>Détails sur le fonctionnement des serveurs virtuels</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/details.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Ce document vise à expliquer dans le détail comment le serveur
        HTTP Apache procède lors du choix de l'utilisation
        d'un serveur virtuel en fonction d'une requête reçue.</p>
    
        <p>Il est recommandé de lire la documentation<a href="name-based.html#namevip">
        Serveurs virtuels à base de nom et serveurs virtuels à base
        d'adresse IP</a> pour déterminer quel type de serveur virtuel nous
        convient le mieux, puis de lire les documentations <a href="name-based.html">serveurs virtuels à base de nom</a> ou <a href="ip-based.html">serveurs virtuels à base d'adresse IP</a>, et enfin
        d'étudier <a href="examples.html">quelques exemples</a>.</p>
    
        <p>Si vous voulez entrer dans les détails, vous pouvez revenir vers
        cette page.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#configparsing">Fichier de configuration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#hostmatching">Choix du serveur virtuel</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#tips">Trucs et astuces</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="ip-based.html">Support des serveurs virtuels à base
    d'adresse IP</a></li><li><a href="name-based.html">Support des serveurs virtuels à base
    de nom</a></li><li><a href="examples.html">Exemples de serveurs virtuels pour une
    configuration courante</a></li><li><a href="mass.html">Hébergement virtuel de masse configuré
    dynamiquement</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configparsing" id="configparsing">Fichier de configuration</a></h2>
    
        <p>Un <em>serveur  principal (main_server)</em> contient toutes
        les définitions qui apparaissent en dehors des sections
        <code>&lt;VirtualHost&gt;</code>.</p>
    
        <p>Les serveurs virtuels, aussi
        appelés <em>vhosts</em> (pour virtual hosts), sont définis par les
        sections <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.</p>
    
        <p>Chaque directive <code>VirtualHost</code> comporte une ou
        plusieurs adresses et des ports optionnels.</p>
    
        <p>Il est possible d'utiliser des noms d'hôtes dans la définition
        d'un serveur virtuel, mais ils seront résolus en adresses IP au
        démarrage du serveur, et si une résolution de nom échoue, cette
        définition de serveur virtuel sera ignorée. Cette méthode est par
        conséquent déconseillée.</p>
    
        <p>L'adresse peut
        être spécifiée sous la forme <code>*</code>, ce qui conviendra à la
        requête si aucun autre serveur virtuel ne possède l'adresse IP
        explicite correspondant à celle de la requête.</p>
    
        <p>L'adresse qui apparaît dans la directive <code>VirtualHost</code>
        peut être associée à un port optionnel. Si aucun port n'est
        spécifié, il s'agit d'un port générique qui peut aussi être spécifié
        comme <code>*</code>. Le port générique correspond à toutes les
        valeurs de port.</p>
    
        <p>(Il ne faut pas confondre les numéros de port sur lesquels Apache
        est en écoute avec les numéros de port spécifiés dans la directive
        <code>VirtualHost</code> ; ces derniers ne servent qu'à définir le
        <code>serveur virtuel</code> qui sera sélectionné pour traiter la
        requête. Pour définir les ports sur lesquels Apache est en écoute,
        utilisez la directive <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>).
        </p>
    
        <p>L'ensemble des adresses (y compris les résultats multiples
        <code>A</code> issus des requêtes DNS) est appelé <em>jeu
        d'adresses</em> du serveur virtuel.</p>
    
        <p>Apache fait automatiquement sa sélection à partir de l'en-tête
        HTTP <code>Host</code> fourni par le client, lorsque la
        correspondance la plus exacte du point de vue adresse IP/port a lieu
        pour plusieurs serveurs virtuels.</p>
    
        <p>La directive <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> peut
        apparaître en quelque endroit de la définition d'un serveur.
        Cependant, chaque occurrence écrase la précédente (pour ce serveur).
        Si aucune directive <code>ServerName</code> n'est spécifiée, le
        serveur tente de déterminer le nom du serveur à partir de l'adresse
        IP.</p>
    
        <p>Le premier serveur virtuel à base de nom apparaissant dans le
        fichier de configuration pour une paire IP:port donnée est
        significatif car c'est lui qui sera utilisé pour toutes les requêtes
        reçues sur cette adresse IP/port et pour laquelle aucun autre
        serveur virtuel ne possède un ServerName ou un ServerAlias
        correspondant. Il sera aussi utilisé pour toutes les connexions SSL
        si le serveur ne supporte pas l'<a class="glossarylink" href="../glossary.html#servernameindication" title="voir glossaire">Indication du nom du serveur</a>.</p>
    
        <p>Tous les noms spécifiés au sein d'une section
        <code>VirtualHost</code> sont traités comme un
        <code>ServerAlias</code> (sans caractères génériques), mais ne sont
        écrasés par aucune directive <code>ServerAlias</code>.</p>
    
        <p>Pour chaque serveur virtuel, diverses valeurs sont initialisées
        par défaut. En particulier&nbsp;:</p>
    
        <ol>
          <li>Dans le cas où un serveur virtuel ne contient pas de directives
          <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>,
          <code class="directive"><a href="../mod/core.html#timeout">Timeout</a></code>,
          <code class="directive"><a href="../mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code>,
          <code class="directive"><a href="../mod/core.html#keepalive">KeepAlive</a></code>,
          <code class="directive"><a href="../mod/core.html#maxkeepaliverequests">MaxKeepAliveRequests</a></code>,
          <code class="directive"><a href="../mod/mpm_common.html#receivebuffersize">ReceiveBufferSize</a></code>,
          ou <code class="directive"><a href="../mod/mpm_common.html#sendbuffersize">SendBufferSize</a></code>,
          alors la valeur de chacun de ces paramètres est héritée de celle du
          serveur principal. (C'est à dire, héritée de la valeur finale après
          lecture de la configuration du serveur principal.)</li>
    
          <li>Les permissions par défaut sur les répertoires de chaque
          serveur virtuel sont assemblées avec celles du serveur principal.
          Elles concernent également toutes les informations de configuration
          par répertoire pour tous les modules.</li>
    
          <li>Les configurations par serveur pour chaque module sont assemblées
          à partir de celles du serveur principal.</li>
        </ol>
    
        <p>L'essentiel des valeurs de configuration des serveurs virtuels
        provient de valeurs par défaut issues du serveur principal.
        Mais la position dans le fichier de configuration des directives
        du serveur principal n'a pas d'importance -- l'ensemble de la
        configuration du serveur principal est lu avant que ces valeurs par
        défaut soient appliquées aux serveur virtuels. Ainsi, même si la
        définition d'une valeur apparaît après celle d'un serveur virtuel,
        cette valeur peut affecter la definition du serveur virtuel.</p>
    
        <p>Dans le cas où le serveur principal n'a pas de <code>ServerName</code>
        à ce stade, le nom de la machine sur laquelle tourne le programme
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> est utilisé à sa place. Nous appellerons
        <em>jeu d'adresses du serveur principal</em> les adresses IP
        renvoyées par une résolution DNS sur le <code>ServerName</code>
        du serveur principal.</p>
    
        <p>Pour tous les champs <code>ServerName</code> non définis, dans
        le cas d'une configuration en serveur virtuel par nom, la valeur
        adoptée par défaut est la première adresse donnée dans la section
        <code>VirtualHost</code> qui définit le serveur virtuel.</p>
    
        <p>Si un serveur virtuel contient la valeur magique
        <code>_default_</code>, il fonctionne sur le même <code>ServerName</code>
        que le serveur principal.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hostmatching" id="hostmatching">Choix du serveur virtuel</a></h2>
    
        <p>À la réception d'une requête, le serveur procède comme suit pour
        déterminer quel serveur virtuel utiliser&nbsp;:</p>
    
        <h3><a name="hashtable" id="hashtable">Recherche de l'adresse IP</a></h3>
    
        <p>Lors d'une première connexion sur une adresse/port, le serveur
        recherche toutes les directives <code>VirtualHost</code> qui
        possèdent la même adresse IP/port.</p>
    
        <p>S'il n'y a aucune correspondance exacte pour cette adresse/port,
        la recherche s'effectue sur la valeur générique (<code>*</code>).</p>
    
        <p>Si aucune correspondance n'est enfin trouvée, la requête sera
        servie par le serveur principal.</p>
    
        <p>S'il existe des définitions <code>VirtualHost</code> pour
        l'adresse IP, l'étape suivante consiste à déterminer si nous avons à
        faire à un serveur virtuel à base de nom ou d'adresse IP.</p>
    
        
    
        <h3><a name="ipbased" id="ipbased">Serveur virtuel par IP</a></h3>
    
        <p>Si une seule section <code>VirtualHost</code> présente la
        meilleure correspondance avec la paire adresse IP/port, aucune
        action n'est entreprise et la requête est
        traitée par le serveur virtuel qui correspond.</p>
    
        
    
        <h3><a name="namebased" id="namebased">Serveur virtuel par nom</a></h3>
    
        <p>Si plusieurs sections <code>VirtualHost</code> présentent la
        meilleure correspondance avec la paire adresse IP/port, le terme
        "liste" dans les étapes suivantes fait référence à la liste des
        serveurs virtuels qui correspondent, selon l'ordre dans lequel ils
        apparaissent dans le fichier de configuration.</p>
    
        <p>Si la connexion utilise SSL, si le serveur supporte l'<a class="glossarylink" href="../glossary.html#servernameindication" title="voir glossaire">Indication de nom de serveur</a>,
        et si la négociation du client SSL inclut l'extension TLS dans le
        nom d'hôte requis, alors ce nom d'hôte sera utilisé par la suite, tout
        comme un en-tête <code>Host:</code> aurait été utilisé dans le cas
        d'une connexion non-SSL. Si ces conditions ne sont pas réunies, le
        premier serveur virtuel à base de nom dont l'adresse correspond sera
        utilisé pour les connexions SSL. Ceci est important car c'est le
        serveur virtuel qui détermine quel certificat le serveur va utiliser
        pour la connexion.</p>
    
        <p>Si la requête contient un en-tête <code>Host:</code>, on
        recherche dans la liste le premier serveur virtuel dont le
        <code>ServerName</code> ou le <code>ServerAlias</code> correspond,
        et c'est celui-ci qui va traiter la requête. Un en-tête
        <code>Host:</code> peut comporter un numéro de port mais Apache
        l'ignore systématiquement et utilise toujours le
        port sur lequel il a effectivement reçu la requête.</p>
    
        <p>Le premier serveur virtuel du fichier de configuration qui
        possède l'adresse spécifiée est prioritaire et intercepte toutes les
        requêtes à destination d'un nom de serveur inconnu, ou toute requête
        sans en-tête <code>Host:</code> (comme les requêtes HTTP/1.0).</p>
    
        
    
        <h3><a name="persistent" id="persistent">Connexions persistantes</a></h3>
    
        <p>La <em>recherche par adresse IP</em> décrite ci-avant n'est faite
        qu'<em>une fois</em> pour chaque session TCP/IP, alors que la
        <em>recherche par nom</em> est réalisée pour <em>chaque</em> requête au
        cours d'une connexion persistante (KeepAlive). En d'autres termes,
        il est possible pour un client de faire des requêtes sur
        différents serveurs virtuels par nom, au cours d'une unique
        connexion persistante.</p>
    
        
    
        <h3><a name="absoluteURI" id="absoluteURI">URI absolu</a></h3>
    
        <p>Au cas où l'URI de la requête est absolu, et que son nom de
        serveur et son port correspondent au serveur principal (ou l'un
        des serveurs virtuels configurés), <em>et</em> qu'ils correspondent
        à l'adresse et au port de la requête, alors l'URI est amputé
        de son préfixe protocole/nom de serveur/port et traité par le
        serveur correspondant (principal ou virtuel). Si cette correspondance
        n'existe pas, l'URI reste inchangé et la requête est considérée
        comme une requête d'un serveur mandataire (proxy).</p>
    
    
    <h3><a name="observations" id="observations">Observations</a></h3>
    
        <ul>
          <li>La sélection d'un serveur virtuel en fonction de son nom est
          un processus qui intervient après la sélection par le serveur du
          serveur virtuel qui correspond le mieux du point de vue adresse
          IP/port.</li>
    
          <li>Si vous ne tenez pas compte de l'adresse IP à laquelle le
          client s'est connecté, indiquez un caractère "*" comme adresse
          pour tous les serveurs virtuels, et la sélection du serveur
          virtuel en fonction du nom s'appliquera alors à tous les serveurs
          virtuels définis.</li>
    
          <li>Les vérifications sur <code>ServerName</code> et
          <code>ServerAlias</code> ne sont jamais
          réalisées pour les serveurs virtuels par IP.</li>
    
          <li>Seul l'ordre des serveurs virtuels par nom
          pour une adresse donnée a une importance. Le serveur virtuel
          par nom qui est présent en premier dans la configuration se
          voit attribué la priorité la plus haute pour les requêtes
          arrivant sur son jeu d'adresses IP.</li>
    
          <li>Le numéro de port contenu dans l'en-tête <code>Host:</code> n'est jamais utilisé
          pour les tests de correspondances. Apache ne prend en compte
          que le numéro de port sur lequel le client a envoyé la requête.</li>
    
          <li>Si deux serveurs virtuels partagent la même adresse, la
          sélection se fera implicitement sur le nom. Il s'agit d'une
          nouvelle fonctionnalité de la version 2.3.11.</li>
    
          <li>Le serveur principal ne sert les requêtes que
          lorsque l'adresse IP et le port demandés par le client ne
          correspondent à aucun serveur virtuel (y compris un serveur
          virtuel <code>*</code>). En d'autres termes, le serveur
          principal n'est utile que pour les combinaisons adresse/port
          non spécifiées (sauf quand un serveur virtuel <code>_default_</code>
          correspond au port).</li>
    
          <li>Il ne faut jamais employer de noms DNS dans des directives
          <code>VirtualHost</code>, car cela oblige le serveur a s'appuyer
          sur le DNS au moment du démarrage. De plus, vous vous exposez
          à des problèmes de sécurité si vous n'avez pas la maîtrise du
          DNS pour la totalité de vos domaines. Voir la documentation
          <a href="../dns-caveats.html">disponible ici</a>, ainsi que
          les deux points précisés ci-après.</li>
    
          <li>Un nom de serveur <code>ServerName</code> devrait toujours
          être indiqué pour chaque serveur virtuel. Sans cela, une
          résolution DNS est nécessaire pour chaque serveur virtuel.</li>
          </ul>
          
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">Trucs et astuces</a></h2>
    
        <p>En plus des points évoqués sur la page des
        <a href="../dns-caveats.html#tips">problèmes liés au DNS</a>,
        voici quelques points intéressants&nbsp;:</p>
    
        <ul>
          <li>Toujours positionner les définitions relatives au serveur
          principal avant toute définition <code>VirtualHost</code>.
          (Ceci améliore grandement la lisibilité de la configuration
          -- la manière dont la configuration est interprétée après la
          lecture des fichiers ne met pas en évidence le fait que les
          définitions positionnées avant et surtout après les serveurs
          virtuels peuvent impacter le fonctionnement de tous les
          serveurs virtuels.)</li>
    
       </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/details.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/details.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/vhosts/details.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/details.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/details.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/ip-based.html.fr.utf8�����������������������������������������������0000664�0001751�0001751�00000032253�14740503670�022235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Support Apache des serveurs virtuels par IP - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Serveurs virtuels</a></div><div id="page-content"><div id="preamble"><h1>Support Apache des serveurs virtuels par IP</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#requirements">Système requis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#howto">Comment configurer Apache</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multiple">Configuration de processus multiples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#single">Configuration d'un unique processus
    résident pour des serveurs virtuels</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li>
    <a href="name-based.html">Support Apache des serveurs virtuels par nom</a>
    </li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">Système requis</a></h2>
    
        <p>Comme l'indique le terme <cite>par IP</cite>, le serveur
        <strong>doit disposer de différentes paires adresses IP/port pour chaque
        serveur virtuel par IP</strong>. La machine peut posséder
        plusieurs connexions physiques au réseau, ou utiliser des
        interfaces virtuelles qui sont supportées par la plupart des
        systèmes d'exploitation modernes (Consultez la documentation des
        systèmes d'exploitation pour plus de détails, notamment les "alias
        IP" et la commande "ifconfig" pour les activer), et/ou utiliser
        plusieurs numéros de port.</p>
    
        <p>Selon la terminologie du serveur HTTP Apache, l'utilisation d'une
        seule adresse IP avec plusieurs ports TCP s'apparente aussi à de
        l'hébergement virtuel basé sur IP.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">Comment configurer Apache</a></h2>
    
        <p>Il y a deux manières de configurer Apache pour le support de
        multiples serveurs virtuels. Il suffit soit de faire tourner un
        processus résident <code class="program"><a href="../programs/httpd.html">httpd</a></code> pour chaque nom de
        domaine, soit de faire tourner un unique processus résident qui
        gère tous les serveurs virtuels.</p>
    
        <p>Utilisez des processus résidents multiples lorsque&nbsp;:</p>
    
        <ul>
          <li>il y a des problèmes de répartition de sécurité, tels
          qu'une entreprise1 ne souhaite que personne d'une entreprise2
          ne puisse lire ses données excepté via le Web. Dans ce cas,
          vous aurez besoin de deux processus résidents, chacun fonctionnant
          avec des paramètres <code class="directive"><a href="../mod/mod_unixd.html#user">User</a></code>,
          <code class="directive"><a href="../mod/mod_unixd.html#group">Group</a></code>,
          <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>, et
          <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> différents.</li>
    
          <li>vous disposez suffisamment de mémoire et de
          <a href="../misc/descriptors.html">descripteurs de fichiers</a>
          pour l'écoute de chaque alias IP de la machine. Il est seulement
          possible d'appliquer la directive
          <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code>, soit sur toutes
          les adresses avec le joker "*", soit uniquement sur des adresses
          spécifiques. Donc, si vous avez besoin d'écouter une adresse
          en particulier, vous devrez le faire pour l'ensemble des
          autres adresses (Bien qu'il soit plus simple de lancer un
          processus <code class="program"><a href="../programs/httpd.html">httpd</a></code> pour écouter N-1 adresses,
          et un autre pour l'adresse restante).</li>
        </ul>
    
        <p>Utilisez un unique processus résident lorsque&nbsp;:</p>
    
        <ul>
          <li>le partage de la configuration httpd entre les serveurs
          virtuels est acceptable.</li>
    
          <li>la machine assume déjà une grande quantité de requêtes, et
          que l'ajout de processus résidents supplémentaires en affecterait
          les performances.</li>
        </ul>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multiple" id="multiple">Configuration de processus multiples</a></h2>
    
        <p>Créez une installation indépendante du programme
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> pour chaque serveur virtuel. Pour
        chacune d'elle, utilisez la directive
        <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> dans le fichier
        de configuration pour définir l'adresse IP (ou serveur virtuel)
        que le processus résident doit gérer. Par exemple&nbsp;:</p>
    
        <pre class="prettyprint lang-config">Listen 192.0.2.100:80</pre>
    
    
        <p>Il est recommandé d'utiliser une adresse IP plutôt qu'un nom
        de domaine (consultez <a href="../dns-caveats.html">Problèmes DNS
        avec Apache</a>).</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="single" id="single">Configuration d'un unique processus
    résident pour des serveurs virtuels</a></h2>
    
        <p>Dans ce cas, un unique processus httpd va gérer les requêtes
        pour le serveur principal et tous les serveurs virtuels. Dans le
        fichier de configuration, la directive
        <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> va servir à
        définir les autres directives
        <code class="directive"><a href="../mod/core.html#serveradmin">ServerAdmin</a></code>,
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>,
        <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>,
        <code class="directive"><a href="../mod/core.html#errorlog">ErrorLog</a></code> et
        <code class="directive"><a href="../mod/mod_log_config.html#transferlog">TransferLog</a></code> ou
        <code class="directive"><a href="../mod/mod_log_config.html#customlog">CustomLog</a></code> avec des
        valeurs différentes pour chaque serveur virtuel. Par exemple&nbsp;:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 172.20.30.40:80&gt;
        ServerAdmin webmaster@www1.example.com
        DocumentRoot "/www/vhosts/www1"
        ServerName www1.example.com
        ErrorLog "/www/logs/www1/error_log"
        CustomLog "/www/logs/www1/access_log" combined
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:80&gt;
        ServerAdmin webmaster@www2.example.org
        DocumentRoot "/www/vhosts/www2"
        ServerName www2.example.org
        ErrorLog "/www/logs/www2/error_log"
        CustomLog "/www/logs/www2/access_log" combined
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Il est recommandé d'utiliser une adresse IP plutôt qu'un nom
        de domaine comme argument à la directive &lt;VirtualHost&gt;
         (consultez <a href="../dns-caveats.html">Problèmes DNS
        avec Apache</a>).</p>
    
        <p>Presque <strong>toutes</strong> les directives de configuration
        peuvent être employées dans une directive VirtualHost, à l'exception
        des directives qui contrôlent la création du processus et de
        quelques autres. Pour connaître celles utilisables dans une
        directive VirtualHost, vérifiez leur
        <a href="../mod/directive-dict.html#Context">Contexte</a> en utilisant
        l'<a href="../mod/quickreference.html">directive index</a>.</p>
    
    
        <p><code class="directive"><a href="../mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> peut être
        utilisées à l'intérieur d'une directive VirtualHost si l'exécution se fait
        sous suEXEC. (Voir <a href="../suexec.html">suEXEC</a>).</p>
    
        <p><em>SÉCURITÉ&nbsp;:</em> lorsque vous spécifiez où écrire les
        fichiers journaux, soyez attentif aux risques si quelqu'un d'autre
        que celui qui a démarré Apache dispose des droits d'écriture
        sur l'emplacement de ces fichiers. Consultez les
        <a href="../misc/security_tips.html">Conseils sur la sécurité</a>
        pour plus de détails.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/vhosts/ip-based.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/ip-based.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/ip-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/ip-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/ip-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/ip-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/examples.html.en����������������������������������������������������0000664�0001751�0001751�00000060551�14737241666�021511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>VirtualHost Examples - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Virtual Hosts</a></div><div id="page-content"><div id="preamble"><h1>VirtualHost Examples</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/vhosts/examples.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>This document attempts to answer the commonly-asked questions about
        setting up <a href="index.html">virtual hosts</a>. These scenarios are those involving multiple
        web sites running on a single server, via <a href="name-based.html">name-based</a> or <a href="ip-based.html">IP-based</a> virtual hosts.
        </p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#purename">Running several name-based web
        sites on a single IP address.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#twoips">Name-based hosts on more than one
        IP address.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#intraextra">Serving the same content on
        different IP addresses (such as an internal and external
        address).</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#port">Running different sites on different
        ports.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ip">IP-based virtual hosting</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ipport">Mixed port-based and ip-based virtual
      hosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mixed">Mixed name-based and IP-based
        vhosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#proxy">Using <code>Virtual_host</code> and
        mod_proxy together</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#default">Using <code>_default_</code>
        vhosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#migrate">Migrating a name-based vhost to an
        IP-based vhost</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#serverpath">Using the <code>ServerPath</code>
      directive</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="purename" id="purename">Running several name-based web
        sites on a single IP address.</a></h2>
    
        <p>Your server has multiple hostnames that resolve to a single address,
        and you want to respond differently for <code>www.example.com</code>
        and <code>www.example.org</code>.</p>
    
        <div class="note"><h3>Note</h3><p>Creating virtual
              host configurations on your Apache server does not magically
              cause DNS entries to be created for those host names. You
              <em>must</em> 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 <code>hosts</code> file for local
              testing, but that will work only from the machine with those
              <code>hosts</code> entries.</p>
        </div>
    
        <pre class="prettyprint lang-config"># Ensure that Apache listens on port 80
    Listen 80
    &lt;VirtualHost *:80&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
    
        # Other directives here
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
    
        # Other directives here
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>The asterisks match all addresses, so the main server serves no
        requests. Due to the fact that the virtual host with
        <code>ServerName www.example.com</code> is first
        in the configuration file, it has the highest priority and can be seen
        as the <cite>default</cite> or <cite>primary</cite> server. That means
        that if a request is received that does not match one of the specified
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> directives, it will be served by this first
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.</p>
    
        <p>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.</p>
    
        <div class="note">
                <h3>Note</h3>
    
               <p>You may replace <code>*</code> with a specific IP address
               on the system.  Such virtual hosts will only be used for
               HTTP requests received on connection to the specified IP
               address.</p>
    
               <p>However, it is additionally useful to use <code>*</code>
               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
               <code>*</code> matches any IP address, this configuration
               would work without changes whenever your IP address
               changes.</p>
        </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="twoips" id="twoips">Name-based hosts on more than one
        IP address.</a></h2>
    
        <div class="note">
          <h3>Note</h3>
          <p>Any of the techniques discussed here can be extended to any
          number of IP addresses.</p>
        </div>
    
        <p>The server has two IP addresses. On one (<code>172.20.30.40</code>), we
        will serve the "main" server, <code>server.example.com</code> and on the
        other (<code>172.20.30.50</code>), we will serve two or more virtual hosts.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    
    # This is the "main" server running on 172.20.30.40
    ServerName server.example.com
    DocumentRoot "/www/mainserver"
    
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
    
        # Other directives here ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
    
        # Other directives here ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Any request to an address other than <code>172.20.30.50</code> will be
        served from the main server. A request to <code>172.20.30.50</code> with an
        unknown hostname, or no <code>Host:</code> header, will be served from
        <code>www.example.com</code>.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intraextra" id="intraextra">Serving the same content on
        different IP addresses (such as an internal and external
        address).</a></h2>
    
        <p>The server machine has two IP addresses (<code>192.168.1.1</code>
        and <code>172.20.30.40</code>). The machine is sitting between an
        internal (intranet) network and an external (internet) network. Outside
        of the network, the name <code>server.example.com</code> resolves to
        the external address (<code>172.20.30.40</code>), but inside the
        network, that same name resolves to the internal address
        (<code>192.168.1.1</code>).</p>
    
        <p>The server can be made to respond to internal and external requests
        with the same content, with just one <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> section.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 192.168.1.1 172.20.30.40&gt;
        DocumentRoot "/www/server1"
        ServerName server.example.com
        ServerAlias server
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Now requests from both networks will be served from the same
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>.</p>
    
        <div class="note">
              <h3>Note:</h3><p>On the internal
              network, one can just use the name <code>server</code> rather
              than the fully qualified host name
              <code>server.example.com</code>.</p>
    
              <p>Note also that, in the above example, you can replace the list
              of IP addresses with <code>*</code>, which will cause the server to
              respond the same on all addresses.</p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="port" id="port">Running different sites on different
        ports.</a></h2>
    
        <p>You have multiple domains going to the same IP and also want to
        serve multiple ports.  The example below illustrates that the name-matching
        takes place after the best matching IP address and port combination
        is determined.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    Listen 8080
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        ServerName www.example.com
        DocumentRoot "/www/domain-80"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        ServerName www.example.com
        DocumentRoot "/www/domain-8080"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        ServerName www.example.org
        DocumentRoot "/www/otherdomain-80"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        ServerName www.example.org
        DocumentRoot "/www/otherdomain-8080"
    &lt;/VirtualHost&gt;</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ip" id="ip">IP-based virtual hosting</a></h2>
    
        <p>The server has two IP addresses (<code>172.20.30.40</code> and
        <code>172.20.30.50</code>) which resolve to the names
        <code>www.example.com</code> and <code>www.example.org</code>
        respectively.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Requests for any address not specified in one of the
        <code>&lt;VirtualHost&gt;</code> directives (such as
        <code>localhost</code>, for example) will go to the main server, if
        there is one.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipport" id="ipport">Mixed port-based and ip-based virtual
      hosts</a></h2>
    
        <p>The server machine has two IP addresses (<code>172.20.30.40</code> and
        <code>172.20.30.50</code>) which resolve to the names
        <code>www.example.com</code> and <code>www.example.org</code>
        respectively. In each case, we want to run hosts on ports 80 and
        8080.</p>
    
        <pre class="prettyprint lang-config">Listen 172.20.30.40:80
    Listen 172.20.30.40:8080
    Listen 172.20.30.50:80
    Listen 172.20.30.50:8080
    
    &lt;VirtualHost 172.20.30.40:80&gt;
        DocumentRoot "/www/example1-80"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40:8080&gt;
        DocumentRoot "/www/example1-8080"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:80&gt;
        DocumentRoot "/www/example2-80"
        ServerName www.example.org
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.50:8080&gt;
        DocumentRoot "/www/example2-8080"
        ServerName www.example.org
    &lt;/VirtualHost&gt;</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mixed" id="mixed">Mixed name-based and IP-based
        vhosts</a></h2>
    
        <p>Any address mentioned in the argument to a virtualhost that never
        appears in another virtual host is a strictly IP-based virtual host.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example1"
        ServerName www.example.com
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example3"
        ServerName www.example.net
    &lt;/VirtualHost&gt;
    
    # IP-based
    &lt;VirtualHost 172.20.30.50&gt;
        DocumentRoot "/www/example4"
        ServerName www.example.edu
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.60&gt;
        DocumentRoot "/www/example5"
        ServerName www.example.gov
    &lt;/VirtualHost&gt;</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Using <code>Virtual_host</code> and
        mod_proxy together</a></h2>
    
        <p>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 <code>192.168.111.2</code>. The <code class="directive"><a href="../mod/mod_proxy.html#proxypreservehost">ProxyPreserveHost
        On</a></code> directive is used so that the desired hostname is
        passed through, in case we are proxying multiple hostnames to a
        single machine.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost *:*&gt;
        ProxyPreserveHost On
        ProxyPass        "/" "http://192.168.111.2/"
        ProxyPassReverse "/" "http://192.168.111.2/"
        ServerName hostname.example.com
    &lt;/VirtualHost&gt;</pre>
    
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="default" id="default">Using <code>_default_</code>
        vhosts</a></h2>
    
        <h3><a name="defaultallports" id="defaultallports"><code>_default_</code> vhosts
        for all ports</a></h3>
    
        <p>Catching <em>every</em> request to any unspecified IP address and
        port, <em>i.e.</em>, an address/port combination that is not used for
        any other virtual host.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:*&gt;
        DocumentRoot "/www/default"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Using such a default vhost with a wildcard port effectively prevents
        any request going to the main server.</p>
    
        <p>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 <code>Host:</code> header it is always
        served from the primary name-based vhost (the vhost for that
        address/port appearing first in the configuration file).</p>
    
        <p>You can use <code class="directive"><a href="../mod/mod_alias.html#aliasmatch">AliasMatch</a></code> or
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to rewrite any
        request to a single information page (or script).</p>
        
    
        <h3><a name="defaultdifferentports" id="defaultdifferentports"><code>_default_</code> vhosts
        for different ports</a></h3>
    
        <p>Same as setup 1, but the server listens on several ports and we want
        to use a second <code>_default_</code> vhost for port 80.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:80&gt;
        DocumentRoot "/www/default80"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost _default_:*&gt;
        DocumentRoot "/www/default"
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>The default vhost for port 80 (which <em>must</em> 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.</p>
        
    
        <h3><a name="defaultoneport" id="defaultoneport"><code>_default_</code> vhosts
        for one port</a></h3>
    
        <p>We want to have a default vhost for port 80, but no other default
        vhosts.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost _default_:80&gt;
        DocumentRoot "/www/default"
    ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>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.</p>
    
        <p>Any use of <code>*</code> in a virtual host declaration will have
        higher precedence than <code>_default_</code>.</p>
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="migrate" id="migrate">Migrating a name-based vhost to an
        IP-based vhost</a></h2>
    
        <p>The name-based vhost with the hostname
        <code>www.example.org</code> (from our <a href="#name">name-based</a> 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.</p>
    
        <p>
         The solution is easy, because we can simply add the new IP address
        (<code>172.20.30.50</code>) to the <code>VirtualHost</code>
        directive.</p>
    
        <pre class="prettyprint lang-config">Listen 80
    ServerName www.example.com
    DocumentRoot "/www/example1"
    
    &lt;VirtualHost 172.20.30.40 172.20.30.50&gt;
        DocumentRoot "/www/example2"
        ServerName www.example.org
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/example3"
        ServerName www.example.net
        ServerAlias *.example.net
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>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).</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="serverpath" id="serverpath">Using the <code>ServerPath</code>
      directive</a></h2>
    
        <p>We have a server with two name-based vhosts. In order to match the
        correct virtual host a client must send the correct <code>Host:</code>
        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.</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 172.20.30.40&gt;
        # primary vhost
        DocumentRoot "/www/subdomain"
        RewriteEngine On
        RewriteRule "." "/www/subdomain/index.html"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/subdomain/sub1"
        ServerName www.sub1.domain.tld
        ServerPath "/sub1/"
        RewriteEngine On
        RewriteRule "^(/sub1/.*)" "/www/subdomain$1"
        # ...
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost 172.20.30.40&gt;
        DocumentRoot "/www/subdomain/sub2"
        ServerName www.sub2.domain.tld
        ServerPath "/sub2/"
        RewriteEngine On
        RewriteRule "^(/sub2/.*)" "/www/subdomain$1"
        # ...
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Due to the <code class="directive"><a href="../mod/core.html#serverpath">ServerPath</a></code>
        directive a request to the URL
        <code>http://www.sub1.domain.tld/sub1/</code> is <em>always</em> served
        from the sub1-vhost.<br /> A request to the URL
        <code>http://www.sub1.domain.tld/</code> is only
        served from the sub1-vhost if the client sent a correct
        <code>Host:</code> header. If no <code>Host:</code> header is sent the
        client gets the information page from the primary host.</p>
    
        <p>Please note that there is one oddity: A request to
        <code>http://www.sub2.domain.tld/sub1/</code> is also served from the
        sub1-vhost if the client sent no <code>Host:</code> header.</p>
    
        <p>The <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives
        are used to make sure that a client which sent a correct
        <code>Host:</code> header can use both URL variants, <em>i.e.</em>,
        with or without URL prefix.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/vhosts/examples.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/examples.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/examples.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/examples.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/examples.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/examples.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/ip-based.html�������������������������������������������������������0000664�0001751�0001751�00000000732�13710016232�020724� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: ip-based.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: ip-based.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: ip-based.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: ip-based.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: ip-based.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������httpd-2.4.64/docs/manual/vhosts/name-based.html.en��������������������������������������������������0000664�0001751�0001751�00000041427�14737241666�021670� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Name-based Virtual Host Support - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Virtual Hosts</a></div><div id="page-content"><div id="preamble"><h1>Name-based Virtual Host Support</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>This document describes when and how to use name-based virtual hosts.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#namevip">Name-based vs. IP-based Virtual Hosts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#alg">How the server selects the proper name-based virtual host</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#using">Using Name-based Virtual Hosts</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="ip-based.html">IP-based Virtual Host Support</a></li><li><a href="details.html">An In-Depth Discussion of Virtual Host Matching</a></li><li><a href="mass.html">Dynamically configured mass virtual hosting</a></li><li><a href="examples.html">Virtual Host examples for common setups</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="namevip" id="namevip">Name-based vs. IP-based Virtual Hosts</a></h2>
    
        <p><a href="ip-based.html">IP-based virtual hosts</a> 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.</p>
    
        <p>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.</p>
    
        <p>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 you are using equipment
        that explicitly demands IP-based hosting.  Historical reasons for
        IP-based virtual hosting based on client support are no longer
        applicable to a general-purpose web server.</p>
    
        <p> Name-based virtual hosting builds off of the IP-based virtual host
        selection algorithm, meaning that searches for the proper server name
        occur only between virtual hosts that have the best IP-based address.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="alg" id="alg">How the server selects the proper name-based virtual host</a></h2>
    
        <p>It is important to recognize that the first step in name-based virtual
        host resolution is IP-based resolution.  Name-based virtual host
        resolution only chooses the most appropriate name-based virtual host
        after narrowing down the candidates to the best IP-based match.  Using a wildcard (*)
        for the IP address in all of the VirtualHost directives makes this
        IP-based mapping irrelevant.</p>
    
        <p>When a request arrives, the server will find the best (most specific) matching
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> argument based on
        the IP address and port used by the request.  If there is more than one virtual host
        containing this best-match address and port combination, Apache will further
        compare the <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> and <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> directives to the server name
        present in the request.</p>
    
        <p>If you omit the <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> 
        directive from any name-based virtual host, the server will default
        to a fully qualified domain name (FQDN) derived from the system hostname.
        This implicitly set server name can lead to counter-intuitive virtual host
        matching and is discouraged.</p>
     
        <h3><a name="defaultvhost" id="defaultvhost">The default name-based vhost for an IP and port combination </a></h3>
        <p> If no matching ServerName or ServerAlias is found in the set of
        virtual hosts containing the most specific matching IP address and port
        combination, then <strong>the first listed virtual host</strong> that
        matches that will be used.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Using Name-based Virtual Hosts</a></h2>
    
    <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code></li><li><code class="directive"><a href="../mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>The first step is to create a <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> block for
        each different host that you would like to serve.  Inside each <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> block, you will need at minimum a
        <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> directive to designate
        which host is served and a <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
        directive to show where in the filesystem the content for that host
        lives.</p>
    
        <div class="note"><h3>Main host goes away</h3>
            <p> Any request that doesn't match an existing <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> is handled by the global
            server configuration, regardless of the hostname or ServerName.</p>
    
            <p> When you add a name-based virtual host to an existing server, and
            the virtual host arguments match preexisting IP and port combinations,
            requests will now be handled by an explicit virtual host.  In this case,
            it's usually wise to create a <a href="#defaultvhost">default virtual host</a>
            with a <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> matching that of
            the base server.  New domains on the same interface and port, but
            requiring separate configurations,  can then be added as subsequent (non-default)
            virtual hosts.</p>
        </div>
    
        <div class="note"><h3>ServerName inheritance</h3>
           <p> It is best to always explicitly list a  <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> in every name-based virtual host.</p>
           <p>If a <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code> doesn't specify 
           a <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code>, a server name will be 
           inherited from the base server configuration.  If no server name was 
           specified globally, one is detected at startup through reverse DNS resolution
           of the first listening address.  In either case, this inherited server name
           will influence name-based virtual host resolution, so it is best to always
           explicitly list a  <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> in every
           name-based virtual host.</p>
        </div>
    
        <p>For example, suppose that you are serving the domain
        <code>www.example.com</code> and you wish to add the virtual host
        <code>other.example.com</code>, which points at the same IP address.
        Then you simply add the following to <code>httpd.conf</code>:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost *:80&gt;
        # This first-listed virtual host is also the default for *:80
        ServerName www.example.com
        ServerAlias example.com 
        DocumentRoot "/www/domain"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
        ServerName other.example.com
        DocumentRoot "/www/otherdomain"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>You can alternatively specify an explicit IP address in place of the
        <code>*</code> in <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 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.</p>
    
        <p>Many servers want to be accessible by more than one name. This is
        possible with the <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>
        directive, placed inside the <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> section. For example in the first <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> block above, the
        <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> directive indicates that
        the listed names are other names which people can use to see that same
        web site:</p>
    
        <pre class="prettyprint lang-config">ServerAlias example.com *.example.com</pre>
    
    
        <p>then requests for all hosts in the <code>example.com</code> domain will
        be served by the <code>www.example.com</code> virtual host. The wildcard
        characters <code>*</code> and <code>?</code> can be used to match names.
        Of course, you can't just make up names and place them in <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> or <code>ServerAlias</code>. You must
        first have your DNS server properly configured to map those names to an IP
        address associated with your server.</p>
    
        <p>Name-based virtual hosts for the best-matching set of  <code class="directive"><a href="../mod/core.html#virtualhost">&lt;virtualhost&gt;</a></code>s are processed 
        in the order they appear in the configuration.  The first matching <code class="directive"><a href="../mod/core.html#servername">ServerName</a></code> or <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code> is used, with no different precedence for wildcards
        (nor for ServerName vs. ServerAlias).  </p>
    
        <p>The complete list of names in the <code class="directive"><a href="../mod/core.html#virtualhost">VirtualHost</a></code>
        directive are treated just like a (non wildcard) 
        <code class="directive"><a href="../mod/core.html#serveralias">ServerAlias</a></code>.</p>
    
        <p>Finally, you can fine-tune the configuration of the virtual hosts
        by placing other directives inside the <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 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 <a href="../mod/directive-dict.html#Context">Context</a> of the
        directive. Configuration directives set in the <em>main server context</em>
        (outside any <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        container) will be used only if they are not overridden by the virtual host
        settings.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../de/vhosts/name-based.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="../en/vhosts/name-based.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/vhosts/name-based.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/vhosts/name-based.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/vhosts/name-based.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/vhosts/name-based.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/vhosts/name-based.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/index.html����������������������������������������������������������0000664�0001751�0001751�00000001173�13710016232�020347� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: index.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: index.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/vhosts/fd-limits.html������������������������������������������������������0000664�0001751�0001751�00000000737�13710016232�021135� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: fd-limits.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: fd-limits.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: fd-limits.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: fd-limits.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: fd-limits.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ���������������������������������httpd-2.4.64/docs/manual/vhosts/name-based.html�����������������������������������������������������0000664�0001751�0001751�00000001076�13710016232�021236� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: name-based.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: name-based.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: name-based.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: name-based.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/filter.html.ko.euc-kr������������������������������������������������������0000664�0001751�0001751�00000020567�14743132254�021016� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title> - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1></h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>  ġ ͸ ϴ  Ѵ.</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="filters" id="filters"></a></h2>
        
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilteroptions">ExtFilterOptions</a></code></li><li><code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code></li><li><code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code></li></ul></td></tr></table>
    
        <p><em>(filter)</em>  ų ޴ ڷῡ
        Ǵ ۾̴. Ŭ̾Ʈ   ڷ
        <em>Է(input filter)</em> óϰ, 
        Ŭ̾Ʈ  ڷ <em>(output filter)</em>
        óѴ. ڷῡ  ͸   ְ,  
           ִ.</p>
    
        <p>ġ ̾ޱ(byte-range) û  óϱ
         ͸ Ѵ. ,  þ
        Ͽ ð ͸ ϴ ⵵ ִ.
        <code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code>,
        <code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code>
        þ ڷḦ óϴ ͸ Ѵ.</p>
    
        <p> ġ   ڰ   ִ 
         ͸ Ѵ.</p>
    
        <dl>
          <dt>INCLUDES</dt>
          <dd><code class="module"><a href="./mod/mod_include.html">mod_include</a></code> óϴ Server-Side Includes</dd>
          <dt>DEFLATE</dt>
          <dd><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> Ͽ 
              Ŭ̾Ʈ   
          </dd>
        </dl>
    
        <p>, <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>  Ͽ
        ܺ α׷ ͷ   ִ.</p>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/filter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html�����������������������������������������������������������������0000664�0001751�0001751�00000001725�13741307256�017041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: index.html.da
    Content-Language: da
    Content-type: text/html; charset=ISO-8859-1
    
    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=UTF-8
    
    URI: index.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: index.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    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
    
    URI: index.html.ru.utf8
    Content-Language: ru
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    �������������������������������������������httpd-2.4.64/docs/manual/filter.html.tr.utf8��������������������������������������������������������0000664�0001751�0001751�00000037776�14743132254�020544� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Süzgeçler - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Süzgeçler</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu belge, Apache’de süzgeç kullanımı hakkındadır.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#intro">Apache 2’de Süzme İşlemi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#smart">Akıllı Süzme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#service">Süzgeçleri bir HTTP Hizmeti gibi göstermek </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Süzgeçlerin Kullanımı</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">Apache 2’de Süzme İşlemi</a></h2> 
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code></li><li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></li><li><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code></li><li><code class="module"><a href="./mod/mod_buffer.html">mod_buffer</a></code></li><li><code class="module"><a href="./mod/mod_data.html">mod_data</a></code></li><li><code class="module"><a href="./mod/mod_ratelimit.html">mod_ratelimit</a></code></li><li><code class="module"><a href="./mod/mod_reqtimeout.html">mod_reqtimeout</a></code></li><li><code class="module"><a href="./mod/mod_request.html">mod_request</a></code></li><li><code class="module"><a href="./mod/mod_sed.html">mod_sed</a></code></li><li><code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code></li><li><code class="module"><a href="./mod/mod_xml2enc.html">mod_xml2enc</a></code></li><li><code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_filter.html#filterchain">FilterChain</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterdeclare">FilterDeclare</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprotocol">FilterProtocol</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_reflector.html#reflectorheader">ReflectorHeader</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilteroptions">ExtFilterOptions</a></code></li><li><code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code></li><li><code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code></li></ul></td></tr></table>
    
        <p>Apache 2.0 ve sonrasında mevcut olan Süzgeç Zinciri, uygulamaların
          nereden geldiğine bakmaksızın gelen ve giden verileri oldukça esnek ve
          yapılandırılabilir tarzda işlemesini mümkün kılar. Böylece, gelen veriyi
          bir takım ön işlemlerden geçirebilir, giden veriyi de son bir defa bazı
          işlemlere sokabiliriz. Bu işlem temel olarak geleneksel istek işleme
          aşamalarından bağımsızdır.</p>
    
        <p class="figure">
          <img src="images/filter_arch.tr.png" width="569" height="392" alt="Süzgeçler, İstek işleme eksenine dik bir veri eksenine peş peşe  yerleştirilebilir." />
        </p>
    
        <p>Standard Apache dağıtımıyla gelen süzgeç uygulamalarından bazıları:</p>
    
        <ul>
          <li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code>, sunucu taraflı içerik yerleştirmeyi
          gerçekler.</li>
          <li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>, SSL şifrelemesini gerçekler (https).</li>
          <li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code>, veri sıkıştırma/açma işlemlerini
          çalışma anında gerçekleştirir.</li>
          <li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code>, karakter kümeleri arasında
          dönüşümü gerçekleştirir.</li>
          <li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>, harici bir yazılımı bir süzgeç
          olarak çalıştırır.</li>
        </ul>
    
        <p>Apache, bunlardan başka, bayt dizilerinin elde edilmesi ve içeriğin
          bölünmesi gibi işlemleri gerçekleştirmek için bir takım dahili süzgeçler
          de  kullanabilir.</p>
    
        <p>Üçüncü parti süzgeç modülleri tarafından gerçeklenmiş
          modüllerden bazılarının uygulama alanları:</p>
    
        <ul>
          <li>HTML ve XML belgelerin işlenmesi ve yazılması</li>
          <li>XSLT dönüşümleri ve XInclude’lar</li>
          <li>XML İsim-alanı desteği</li>
          <li>HTML Formlarının çözümlenmesi ve sunucuya dosya yükleme</li>
          <li>Resim işleme</li>
          <li>PHP betikleri gibi zararlı olabilecek uygulamalardan korunma</li>
          <li>Metin düzenleme ve arama işlemleri</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="smart" id="smart">Akıllı Süzme</a></h2>
        <p class="figure">
          <img src="images/mod_filter_new.tr.png" width="423" height="331" alt="Farklı süzgeç üreticilerinin uygulamaları istek işlemenin durumuna  bağlı olarak akıllıca uygulanabilir." />
        </p>
    
        <p><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>, Apache 2.1 ve sonrasında mevcut olup,
          süzgeç zincirinin çalışma anında devingen olarak yapılandırılabilmesini
          mümkün kılar. Böylece, örneğin, bir vekili, özgün sunucunun ne
          göndereceğini bilmeden HTML’yi bir HTML süzgeciyle yazmaya ve JPEG
          resimleri tamamen farklı bir süzgeçten geçirmeye ayarlayabilirsiniz. Bu,
          asıl içeriğe bağlı olarak çalışma anında içeriği farklı içerik
          sağlayıcılara dağıtan bir süzgeç düzeneği kullanılarak çalışır. Bir
          süzgeç, doğrudan zincire yerleştirilip koşulsuz olarak
          çalıştırılabileceği gibi bir içerik sağlayıcı gibi kullanılarak zincire
          devingen olarak yerleştirilebilir. Örneğin:</p>
    
        <ul>
          <li>Bir HTML işleme süzgeci sadece içerik text/html veya
          application/xhtml+xml olduğu takdirde çalışır.</li>
          <li>Bir sıkıştırma süzgeci sadece girdi sıkıştırılabilir nitelikteyse ve
          sıkıştırılmamışsa çalışır.</li>
          <li>Bir karakter kümesi dönüşüm süzgeci, bir metin belgesi istenen
          karakter kümesine sahip değilse zincire yerleştirilir.</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="service" id="service">Süzgeçleri bir HTTP Hizmeti gibi göstermek </a></h2>
        
        <p>Süzgeçler, istemciden kaynaklanan içeriği işlemekte kullanılabileceği
          gibi <code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code> modülü kullanılarak sunucudan
          kaynaklanan içeriği işlemekte de kullanılabilir.</p>
    
        <p><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code> istemcilerden gelen POST isteklerini
          kabul eder ve çıktı süzgeç yığıtı yoluyla istemciye aktararak, POST
          isteği içinde alınan içerik istek gövdesini yanıt içinde geri
          gönderir.</p>
    
        <p>Bu teknik, bir çıktı süzgeciyle istek gövdesinde gerekli dönüşümün
          sağlandığı durumda, bir uygulama sunucusu yığıtı içinde çalışan bir http
          hizmetinin yerine de kullanılabilir. Örneğin,
          <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> modülü genel bir sıkıştırma hizmeti
          sağlamakta kullanılabilir veya bir resim dönüştürme süzgeci bir resim
          dönüşüm hizmeti haline getirilebilir.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Süzgeçlerin Kullanımı</a></h2>
        <p>Süzgeçler iki şekilde kullanılır: Basit ve Devingen.
          Genelde ikisinden biri kullanılır; karışık kullanılırsa istenmeyen
          sonuçlara yol açabilir (ise de, basit girdi süzme ile çıktı süzme işlemi
          basit olsun olmasın karışık kullanılabilir).</p>
    
        <p>Basit yol, girdi süzgeçlerini yapılandırmanın tek yoludur ve bir
          durağan süzgeç zincirinin gerektiği yerlerde çıktı süzgeçleri için
          yeterlidir. İlgili yönergeler:
          <code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code>,
          <code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code>,
          <code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code>,
          <code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code>,
          <code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code> ve
          <code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code>.</p>
    
        <p>Devingen yol, <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> belgesinde açıklandığı gibi,
          çıktı süzgeçlerinin hem durağan hem de esnek ve devingen olarak
          yapılandırılabilmesini mümkün kılar. İlgili yönergeler:
          <code class="directive"><a href="./mod/mod_filter.html#filterchain">FilterChain</a></code>,
          <code class="directive"><a href="./mod/mod_filter.html#filterdeclare">FilterDeclare</a></code> ve
          <code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code>.</p>
    
        <p><code class="directive"><a href="./mod/core.html#addoutputfilterbytype">AddOutputFilterByType</a></code> yönergesi
          hala desteklenmekteyse de kullanımı artık
          önerilmemektedir. Onun yerine devingen yapılandırma kullanınız.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/filter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��httpd-2.4.64/docs/manual/glossary.html.ja.utf8������������������������������������������������������0000664�0001751�0001751�00000100035�14743132254�021042� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>用語 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>用語</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>この用語集では Apacheに特化した用語と、
        ウェブサーバ全般で一般的な用語をいくつか定義しています。
        それぞれの概念の、より詳細な情報はリンク先にあります。</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definitions" id="definitions">定義</a></h2>
    
      <dl>
        <dt><a name="accesscontrol" id="accesscontrol">アクセス制御</a></dt>
        <dd>ネットワーク認可領域へのアクセスを制限します。Apache においては、
        普通はアクセスの制限は <em>URL</em> に対するものとなります。<br />
        参照: <a href="howto/auth.html">認証、承認、アクセス制御</a>
        </dd>
        
        <dt><a name="algorithm" id="algorithm">アルゴリズム</a></dt>
        <dd>有限回のステップで問題を解くためのあいまいでない式もしくは規則の
        集合。暗号のためのアルゴリズムは通常 <dfn>Cipher</dfn> と呼ばれます。
        </dd>
        
        <dt><a name="apacheextensiontool" id="apacheextensiontool">APache
            eXtension Tool</a> <a name="apxs" id="apxs">(apxs)</a></dt>
        <dd><a class="glossarylink" href="./glossary.html#module" title="用語集を参照">モジュール</a> ソースを
        動的共有オブジェクト (<a class="glossarylink" href="./glossary.html#dso" title="用語集を参照">DSO</a>) にコンパイルし、
        Apache Web サーバにインストールする手助けをする perl スクリプト。<br />
          参照: マニュアルページ: <code class="program"><a href="./programs/apxs.html">apxs</a></code>
        </dd>
    
        <dt><a name="apacheportableruntime" id="apacheportableruntime">Apache Portable Runtime</a> <a name="apr" id="apr">(APR)</a></dt>
        <dd>サーバ<span class="transnote">(<em>訳注:</em> Apache HTTP Server)</span>と OS の
          間の基本的なインターフェースの多くを提供する<span class="transnote">(<em>訳注:</em> 
          OS の差を吸収する)</span>ライブラリのセット。 APR は 独立した
          プロジェクトとして Apache HTTP Server と平行して開発が行われています。<br />
          参照: <a href="http://apr.apache.org/">Apache Portable Runtime
          プロジェクト</a>
        </dd>
    
        <dt><a name="authentication" id="authentication">認証</a></dt>
        <dd>サーバ、クライアント、ユーザといったネットワークエンティティの
        身元の特定。<br />
          参照: <a href="howto/auth.html">認証、承認、アクセス制御</a>
        </dd>
    
        <dt><a name="certificate" id="certificate">証明書</a></dt>
        <dd>サーバやクライアントといったネットワークエンティティを認証するのに
        使用されるデータレコード。証明書には (subject と呼ばれる) 所有者と、
        (issuer と呼ばれる) <a class="glossarylink" href="./glossary.html#certificationauthority" title="用語集を参照">認証局</a> の署名、所有者の
        <a class="glossarylink" href="./glossary.html#publickey" title="用語集を参照">公開鍵</a> と、CA による署名という
        X.509 の情報が含まれます。ネットワークエンティティはそれらの署名を
        CA 証明書を使って検証します。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="certificatsigningrequest" id="certificatsigningrequest">証明書署名リクエスト</a>
          <span class="transnote">(<em>訳注:</em> Certificate Signing Request)</span>
          <a name="csr" id="csr">(CSR)</a></dt>
        <dd><a class="glossarylink" href="./glossary.html#certificationauthority" title="用語集を参照">認証局</a> に提出
        する未署名の <a class="glossarylink" href="./glossary.html#certificate" title="用語集を参照">証明書</a>。
        認証局は CA <em>証明書</em> の <a class="glossarylink" href="./glossary.html#privatekey" title="用語集を参照">秘密鍵</a> で署名します。
        一旦 CSR に署名がなされると、それは本物の証明書になります。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="certificationauthority" id="certificationauthority">証明局</a>
          <span class="transnote">(<em>訳注:</em> Certification Authority)</span>
          <a name="ca" id="ca">(CA)</a></dt>
        <dd>安全な方法で認証を行なったネットワークエンティティの証明書を
        署名するための信頼できる第三者機関。他のネットワークエンティティは
        証明書の保持者が CA に認証されたかを署名を検証することで調べることが
        できます。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="cipher" id="cipher">Cipher</a></dt>
        <dd>データ暗号化のためのアルゴリズム。例えば DES, IDEA, RC4 など。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="ciphertext" id="ciphertext">暗号文</a></dt>
        <dd><a class="glossarylink" href="./glossary.html#plaintext" title="用語集を参照">平文</a> が
        <a class="glossarylink" href="./glossary.html#cipher" title="用語集を参照">Cipher</a> をかけられた結果。<br />
        参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="commongatewayinterface" id="commongatewayinterface">Common
            Gateway Interface</a> <a name="cgi" id="cgi">(CGI)</a></dt>
        <dd>外部プログラムがリクエストを扱うことができるようにするための
        ウェブサーバと外部プログラム間のインタフェースの標準仕様。
        インタフェースは元々 <a href="http://hoohoo.ncsa.uiuc.edu/cgi/overview.html">NCSA</a> により定義
        されていましたが
        <a href="http://cgi-spec.golux.com/">RFC プロジェクト</a> も存在します。<br />
          参照: <a href="howto/cgi.html">CGI による動的コンテンツ</a>
        </dd>
    
        <dt><a name="configurationdirective" id="configurationdirective">設定ディレクティブ</a></dt>
        <dd>参照: <a class="glossarylink" href="./glossary.html#directive" title="用語集を参照">ディレクティブ</a></dd>
    
        <dt><a name="configurationfile" id="configurationfile">設定ファイル</a></dt>
        <dd>Apache の設定を制御する <a class="glossarylink" href="./glossary.html#directive" title="用語集を参照">ディレクティブ</a>
        の書かれたテキストファイル。<br />
          参照: <a href="configuring.html">設定ファイル</a>
        </dd>
    
        <dt><a name="connect" id="connect">CONNECT</a></dt>
        <dd>データチャネルをそのまま HTTP 上でプロキシするための HTTP
        <a class="glossarylink" href="./glossary.html#method" title="用語集を参照">メソッド</a>。SSL のような他の
        プロトコルをくるむために使うことができます。
        </dd>
        
        <dt><a name="context" id="context">コンテキスト</a></dt>
        <dd><a class="glossarylink" href="./glossary.html#configurationfile" title="用語集を参照">設定ファイル</a> 中で、
        特定の種類の <a class="glossarylink" href="./glossary.html#directive" title="用語集を参照">ディレクティブ</a> が許可されている場所。<br />
          参照: <a href="mod/directive-dict.html#Context">Apache のディレクティブの
        説明に使われている用語</a>
        </dd>
    
        <dt><a name="digitalsignature" id="digitalsignature">デジタル署名</a></dt>
        <dd>証明書や他のファイルを検証するための暗号化されたテキストブロック。
        <a class="glossarylink" href="./glossary.html#certificationauthority" title="用語集を参照">認証局</a> は
        <em>証明書</em> に埋め込まれた <em>公開鍵</em> のハッシュを作成し、
        それを自身の <em>秘密鍵</em> で暗号化することで署名を作成します。
        CA の公開鍵でのみその署名を復号することができますので、それにより
        <em>証明書</em> を保有するネットワークエンティティを CA が認証した
        ことを検証できます。<br />
        参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
        
        <dt><a name="directive" id="directive">ディレクティブ</a></dt>
        <dd>Apache のいろいろな振る舞いを制御する設定コマンド。ディレクティブは
        <a class="glossarylink" href="./glossary.html#configurationfile" title="用語集を参照">設定ファイル</a> に
        書かれます。<br />
        参照: <a href="mod/directives.html">ディレクティブ索引</a>
        </dd>
    
        <dt><a name="dynamicsharedobject" id="dynamicsharedobject">動的
        共有オブジェクト</a> <span class="transnote">(<em>訳注:</em> Dynamic
            Shared Object)</span> <a name="dso" id="dso">(DSO)</a></dt>
        <dd>必要に応じて読み込むことが可能な、Apache <code class="program"><a href="./programs/httpd.html">httpd</a></code> とは
          別にコンパイルされた <a class="glossarylink" href="./glossary.html#module" title="用語集を参照">モジュール</a><br />
          参照: <a href="dso.html">動的共有オブジェクトサポート</a>
        </dd>
    
        <dt><a name="environmentvariable" id="environmentvariable">環境変数</a>
        <a name="env-variable" id="env-variable">(env-variable)</a></dt>
        <dd>情報を保管したり、プログラム間の通信をするために使われる、
        オペレーティングシステムのシェルにより管理されている名前付きの変数。
        Apache も環境変数と呼ばれる内部変数を持っていますが、こちらは
        シェル環境ではなく、Apache の内部構造体に保持されています。<br />
          参照: <a href="env.html">Apache の環境変数</a>
        </dd>
    
        <dt><a name="export-crippled" id="export-crippled">輸出強度削減</a>
        <span class="transnote">(<em>訳注:</em> Export-Crippled)</span></dt>
        <dd>アメリカの Export Administration Regulations (EAR)
        <span class="transnote">(<em>訳注:</em> 輸出管理規則)</span> に従うために暗号の強度 (とセキュリティ)
        を削減すること。輸出強度削減された暗号ソフトウェアは小さいキーに
        制限され、通常総当たり攻撃で復号できてしまう <em>暗号文</em> を生成する
        ことになります。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="filter" id="filter">フィルタ</a></dt>
        <dd>サーバから送られるデータとサーバが受け取るデータに適用される処理。
        入力フィルタはクライアントからサーバに送られたデータを処理し、
        出力フィルタはサーバにある文書をクライアントに送る前に処理します。
        例えば、<code>INCLUDES</code> 出力フィルタは
        <a class="glossarylink" href="./glossary.html#ssi" title="用語集を参照">Server Side Includes</a> の文書を
        処理します。<br />
          参照: <a href="filter.html">フィルタ</a>
        </dd>
    
        <dt><a name="fully-qualifieddomain-name" id="fully-qualifieddomain-name">完全修飾ドメイン名</a>
          <span class="transnote">(<em>訳注:</em> Fully-Qualified Domain-Name)</span>
          <a name="fqdn" id="fqdn">(FQDN)</a></dt>
        <dd>IP アドレスに解決できるホスト名と、ドメイン名からなるネットワーク
        エンティティの一意な名前。例えば、<code>www</code> はホスト名で、
        <code>example.com</code> はドメイン名なので、
        <code>www.example.com</code> は完全修飾ドメイン名になります。</dd> 
        
        <dt><a name="handler" id="handler">ハンドラ</a></dt>
        <dd>ファイルが呼ばれたときに行なわれる動作の Apache の内部での表現。
        一般にファイルにはファイルの種類に応じて暗黙のハンドラが設定されて
        います。普通はすべてのファイルがサーバにより送られますが、別に
        扱われる <span class="transnote">(<em>訳注:</em> handle)</span> ファイルの種類も存在します。
        例えば <code>cgi-script</code> はファイルが
        <a class="glossarylink" href="./glossary.html#cgi" title="用語集を参照">CGI</a> として処理されるように指定します。<br />
          参照: <a href="handler.html">Apache のハンドラの使用</a>
        </dd>
    
        <dt><a name="hash" id="hash">ハッシュ</a></dt>
        <dd>任意の文字列から固定長の文字列を生成する、数学的な一方向で不可逆な
        アルゴリズム。異なった入力文字列からは普通は違うハッシュが生成されます
        (ハッシュ関数に依存します)。</dd>
    
        <dt><a name="header" id="header">ヘッダ</a></dt>
        <dd>実際のコンテンツの前に送られ、コンテンツを説明するメタ情報の
        入った <a class="glossarylink" href="./glossary.html#http" title="用語集を参照">HTTP</a> リクエストと応答の一部分。</dd> 
        
        <dt><a name="htaccess" id="htaccess">.htaccess</a></dt> 
        <dd>ウェブツリーに置かれて、そのディレクトリとサブディレクトリに
        <a class="glossarylink" href="./glossary.html#directive" title="用語集を参照">ディレクティブ</a> を適用する
        <a class="glossarylink" href="./glossary.html#configurationfile" title="用語集を参照">設定ファイル</a>。
        名前とは裏腹に、このファイルにはアクセス制御ディレクティブだけでなく、
        ほとんどどんな種類のディレクティブでも書くことができます。<br />
          参照: <a href="configuring.html">設定ファイル</a>
        </dd>
    
        <dt><a name="httpd.conf" id="httpd.conf">httpd.conf</a></dt>
        <dd>メインの Apache <a class="glossarylink" href="./glossary.html#configurationfile" title="用語集を参照">設定
        ファイル</a>。デフォルトの場所は
        <code>/usr/local/apache2/conf/httpd.conf</code>
        ですが、実行時やコンパイル時の設定により違う場所に移動されて
        いるかもしれません。<br />
          参照: <a href="configuring.html">設定ファイル</a>
        </dd>
    
        <dt><a name="hypertexttransferprotocol" id="hypertexttransferprotocol">HyperText Transfer Protocol</a>
          <a name="http" id="hhtp">(HTTP)</a></dt>
        <dd>World Wide Web で使われる標準の転送プロトコル。Apache
        は HTTP/1.1 と呼ばれ、<a href="http://ietf.org/rfc/rfc2616.txt">RFC 2616</a>
        で定義されているプロトコルのバージョン 1.1 を実装しています。</dd>
    
        <dt><a name="https" id="https">HTTPS</a></dt>
        <dd>The HyperText Transfer Protocol (Secure),
        World Wide Web での暗号化された標準の通信機構。これは実際は
        単に <a class="glossarylink" href="./glossary.html#ssl" title="用語集を参照">SSL</a> 上での HTTP です。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd> 
    
        <dt><a name="method" id="method">メソッド</a></dt>
        <dd><a class="glossarylink" href="./glossary.html#http" title="用語集を参照">HTTP</a> の文脈では、
        クライアントから指定されたリクエスト行に対応するリソース
        に対して行なう動作。HTTP では <code>GET</code>, <code>POST</code>,
        <code>PUT</code> といったようなメソッドがあります。</dd> 
        
        <dt><a name="messagedigest" id="messagedigest">メッセージダイジェスト</a></dt>
        <dd>メッセージのハッシュで、メッセージの内容が転送時に変更されていないことの検証に
        使える。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="mime-type" id="mime-type">MIME タイプ</a></dt>
        <dd>送信されているドキュメントの種類を表すための方法。
        この名前はフォーマットが Multipurpose Internet Mail Extensions から
        借りてこられたことによります。これはスラッシュで分離された、
        主タイプと副タイプからなります。例えば、<code>text/html</code>,
        <code>image/gif</code>,  <code>application/octet-stream</code> など
        があります。HTTP では、MIME タイプは <code>Content-Type</code>
        <a class="glossarylink" href="./glossary.html#header" title="用語集を参照">ヘッダ</a> で送信されます。<br />
        参照: <a href="mod/mod_mime.html">mod_mime</a>
        </dd>
    
        <dt><a name="module" id="module">モジュール</a></dt>
        <dd>プログラムの独立した一部分。Apache の機能の多くは使用するかしないかを
        選択できるモジュールの中にあります。Apache <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        に組み込まれているモジュールは<dfn>静的モジュール</dfn>と呼ばれ、
        別に保存され、実行時に読み込むことのできるモジュールは
        <dfn>動的モジュール</dfn> もしくは <a class="glossarylink" href="./glossary.html#dso" title="用語集を参照">DSO</a> と
        呼ばれます。デフォルトで含まれているモジュールは<dfn>base モジュール</dfn>
        と呼ばれます。Apache HTTP サーバの <a class="glossarylink" href="./glossary.html#tarball" title="用語集を参照">tarball</a>
        の一部としては配られていない Apache 用のモジュールがあります。
        それらは <dfn>サードパーティモジュール</dfn> と呼ばれます。<br />
          参照: <a href="mod/">モジュール索引</a>
        </dd>
    
        <dt><a name="modulemagicnumber" id="modulemagicnumber">Module Magic
          Number</a> (<a name="mmn" id="mmn">MMN</a>)</dt>
        <dd>Apache ソースコードで定義されている、モジュールのバイナリ互換性に
        関する定数。バイナリ互換性が保てなくなるような Apache 内部の構造体や、
        関数呼び出し、その他の API の重要な部分の変更があったときに変更されます。
        MMN が変わると、すべてのサードパーティモジュールは少なくとも再コンパイルを
        する必要があり、場合によっては新しいバージョンの Apache で動作するために
        少し変更する必要さえあるかもしれません。</dd>
    
        <dt><a name="openssl" id="openssl">OpenSSL</a></dt>
        <dd>SSL/TLS 用のオープンソースツールキット<br />
          参照 <a href="http://www.openssl.org/">http://www.openssl.org/</a>#
        </dd>
    
        <dt><a name="passphrase" id="passphrase">パスフレーズ</a></dt>
        <dd>秘密鍵のファイルを保護するための語句。権限の無いユーザが
        暗号化するのを防ぎます。通常は単に <a class="glossarylink" href="./glossary.html#cipher" title="用語集を参照">Cipher</a> の秘密の暗号用と復号用のキーです。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="plaintext" id="plaintext">平文</a></dt>
        <dd>暗号化されていないテキスト。</dd>
    
        <dt><a name="privatekey" id="privatekey">秘密鍵</a></dt>
        <dd>受け取るメッセージの復号と送出するメッセージの署名に使われる、
        <a class="glossarylink" href="./glossary.html#publickeycryptography" title="用語集を参照">公開鍵暗号</a> の
        秘密鍵。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
        
        <dt><a name="proxy" id="proxy">プロキシ</a></dt>
        <dd>クライアントと <em>オリジンのサーバ</em> の間に存在する中間サーバ。
        クライアントからのリクエストを受け取り、オリジンのサーバに送信して、オリジンの
        サーバからの応答をクライアントに返します。複数のクライアントが同じ
        コンテンツを要求する場合は、毎回元のサーバにリクエストを送る代わり
        プロキシはキャッシュからコンテンツを送り、応答時間を短縮することが
        できます。<br />
          参照: <a href="mod/mod_proxy.html">mod_proxy</a>
        </dd>
    
        <dt><a name="publickey" id="publickey">公開鍵</a></dt>
        <dd>所有者に向けられたメッセージの暗号化と所有者による署名の復号に使われる、
        <a class="glossarylink" href="./glossary.html#publickeycryptography" title="用語集を参照">公開鍵暗号</a>システムに
        おける公けにされている鍵。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="publickeycryptography" id="publickeycryptography">公開鍵暗号</a></dt>
        <dd>ある鍵を暗号に使い、別の鍵を復号に使う非対称暗号システムについての研究や
        その応用を指す。対応する鍵はキーペアと呼ばれます。非対称暗号とも呼ばれます。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd> 
    
        <dt><a name="regularexpresion" id="regularexpresion">正規表現</a>
          <a name="regex" id="regex">(Regex)</a></dt>
        <dd>テキストのパターンを表現する方式の一つ。例えば、
        「A で始まるすべての単語」や「すべての 10 桁の電話番号」や、
        「コンマが二つあり、大文字の Q がないすべての文」というのでさえ表現
        できます。
        正規表現は Apache においても便利なもので、ファイルやリソースの集まりに対して
        何らかの属性を適用することがとても柔軟にできます。例えば、
        すべての "images" ディレクトリの下の、すべての .gif と .jpg ファイル
        は <code>/images/.*(jpg|gif)$</code> と書くことができます。
        Apache では <a href="http://www.pcre.org/">PCRE</a> ライブラリが提供する
        Perl 互換正規表現 <span class="transnote">(<em>訳注:</em> Perl Compatible Regular Expressions)</span>
        を使います。</dd> 
    
        <dt><a name="reverseproxy" id="reverseproxy">リバースプロキシ</a></dt>
        <dd>クライアントには <em>オリジンのサーバ</em> のように見える
        <a class="glossarylink" href="./glossary.html#proxy" title="用語集を参照">プロキシ</a> サーバ。セキュリティの
        ためや、負荷分散のためにクライアントからオリジンのサーバを隠したいときに
        便利です。</dd>
      
        <dt><a name="securesocketslayer" id="securesocketslayer">Secure Sockets
          Layer</a> <a name="ssl" id="ssl">(SSL)</a></dt>
        <dd>Netscape Communications Corporation により
        TCP/IP ネットワーク上で一般の通信の認証と暗号用に作られたプロトコル。
        最もよく使われているものは <em>HTTPS</em> つまり SSL 上での
        HyperText Transfer Protocol (HTTP) です。<br />
        参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd> 
    
        <dt><a name="serversideincludes" id="serversideincludes">Server Side
          Includes</a> <a name="ssi" id="ssi">(SSI)</a></dt>
        <dd>HTML ファイル中に処理ディレクティブを埋め込む技術の一つ。<br />
        参照: <a href="howto/ssi.html">Server Side Includes 入門</a>
        </dd>
      
        <dt><a name="session" id="session">セッション</a></dt>
        <dd>一般的な通信における文脈情報。</dd>
    
        <dt><a name="ssleay" id="ssleay">SSLeay</a></dt>
        <dd>Eric A. Young 氏による SSL/TLS を実装した元々のライブラリ。</dd>
    
        <dt><a name="symmetriccryptophraphy" id="symmetriccryptophraphy">対称暗号</a>
        </dt>
        <dd>一つの秘密鍵を暗号化と復号の両方に使う <em>Cipher</em> の
        研究や応用を指す。</dd>
    
        <dt><a name="tarball" id="tarball">Tarball</a></dt>
        <dd><code>tar</code> ユーティリティを使ってまとめられたファイルのパッケージ。
          Apache 配布は圧縮された tar アーカイブか pkzip で保管されています。</dd> 
    
        <dt><a name="transportlayersecurity" id="transportlayersecurity">Transport
            Layer Security</a> <a name="tls" id="tls">(TLS)</a></dt>
        <dd>TCP/IP ネットワーク上での一般通信の認証と暗号化用に
          Internet Engineering Task Force (IETF) により作成された SSL の
          後継プロトコル。TLS バージョン 1 は SSL バージョン 3 とほぼ同じです。<br />
            参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
    
        <dt><a name="uniformresourcelocator" id="uniformresourcelocator">Uniform
            Resource Locator</a> <a name="url" id="url">(URL)</a></dt>
        <dd>Internet のリソースの名前、もしくはアドレス。これは正式には
          <a class="glossarylink" href="./glossary.html#uniformresourceidentifier" title="用語集を参照">Uniform Resource Identifier</a>
          と呼ばれるもののよく使われる非公式な名前です。URL は普通は、
          <code>http</code> や <code>https</code> といったスキームとホスト名、
          パスからなります。このページの URL はおそらく
          <code>http://httpd.apache.org/docs/2.4/glossary.html</code>
          と思われます。
        </dd> 
    
        <dt><a name="uniformresourceidentifier" id="uniformresourceidentifier">Uniform Resource Identifier</a>
          <a name="URI" id="URI">(URI)</a></dt>
        <dd>抽象的なリソースや物理リソースを同定するためのコンパクトな文字列。
          正式には <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a> で
          定義されています。WWW で使われている URI  は通常
          <a class="glossarylink" href="./glossary.html#url" title="用語集を参照">URL</a> と呼ばれます。
        </dd> 
    
        <dt><a name="virtualhosting" id="virtualhosting">バーチャルホスト</a></dt>
        <dd>一つの Apache を使って複数のウェブサイトを扱うこと。
          <em>IP バーチャルホスト</em> は IP アドレスを使ってウェブサイトを
          区別します。また <em>名前ベースのバーチャルホスト</em> は
          ホストの名前だけを使って区別するので、同じ IP アドレス上での多くのサイトを
          ホストできます。<br />
          参照: <a href="vhosts/">Apache バーチャルホストの文書</a>
        </dd>
    
        <dt><a name="x.509" id="x.509">X.509</a></dt>
        <dd>SSL/TLS 認証に使われている International
          Telecommunication Union (ITU-T) により推奨されている認証証明書の形式。<br />
          参照: <a href="ssl/">SSL/TLS 暗号化</a>
        </dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/glossary.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html.es������������������������������������������������������������0000664�0001751�0001751�00000031337�14743132254�017754� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Uso de los Handlers en Apache - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="./">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>Uso de los Handlers en Apache</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>Este documento describe el uso de los Handlers en Apache.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#definition">&#191;Qu&#233; es un Handler?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Ejemplos</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programmer">Nota para programadores</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definition" id="definition">&#191;Qu&#233; es un Handler?</a></h2>
        
        <table class="related"><tr><th>M&#243;dulos Relacionados</th><th>Directivas Relacionadas</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></li><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removehandler">RemoveHandler</a></code></li><li><code class="directive"><a href="./mod/core.html#sethandler">SetHandler</a></code></li></ul></td></tr></table>
    
    
        <p>Un "handler" es una representaci&#243;n interna de Apache de
        una acci&#243;n que se va a ejecutar cuando hay una llamada a un
        fichero. Generalmente, los ficheros tienen handlers
        impl&#237;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.</p>
    
        <p>Handlers pueden ser usados de manera explicita,
         bas&#225;ndose en la extensi&#243;n del fichero o en
        la ubicaci&#243;n en la que est&#233;, se pueden especificar handlers
        sin tener en cuenta el tipo de fichero que se trate. Esto es
        una ventaja por dos razones. Primero, es una soluci&#243;n
        m&#225;s elegante. Segundo, porque a un fichero se le pueden
        asignar tanto un tipo <strong>como</strong> un handler. (Consulte
        tambi&#233;n la secci&#243;n <a href="mod/mod_mime.html#multipleext">Ficheros y extensiones
        m&#250;ltiples</a>.)</p>
    
        <p>Los Handlers pueden tanto ser compilados con el servidor
        como incluidos en un m&#243;dulo, o a&#241;adidos con la
        directiva <code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code>. Los
        handlers que vienen incluidos en el core con el servidor de la distribuci&#243;n
        est&#225;ndar de Apache son:</p>
    
        <ul>
          <li><strong>default-handler</strong>: Env&#237;a el fichero
          usando el <code>default_handler()</code>, que es el handler
          usado por defecto para tratar contenido
          est&#225;tico. (core)</li>
    
          <li><strong>send-as-is</strong>: Env&#237;a el fichero con
          cabeceras HTTP tal y como es. (<code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code>)</li>
    
          <li><strong>cgi-script</strong>: Trata el fichero como un sript
          CGI. (<code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>)</li>
    
          <li><strong>imap-file</strong>: Trata el fichero como un mapa de
          im&#225;genes. (<code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code>)</li>
    
          <li><strong>server-info</strong>: Extrae la informaci&#243;n de
          configuraci&#243;n del
          servidor. (<code class="module"><a href="./mod/mod_info.html">mod_info</a></code>)</li>
    
          <li><strong>server-status</strong>: Extrae el informe del estado
          del servidor. (<code class="module"><a href="./mod/mod_status.html">mod_status</a></code>)</li>
    
          <li><strong>type-map</strong>: Trata el fichero como una
          correspondencia de tipos para la negociaci&#243;n de contenidos.
          (<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>)</li> 
        </ul> 
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Ejemplos</a></h2> 
          
    
          <h3><a name="example1" id="example1">Modificar contenido est&#225;tico usando un script
          CGI</a></h3>
          
    
          <p>Las siguientes directivas hacen que cuando haya una
          petici&#243;n de ficheros con la extensi&#243;n
          <code>html</code> se lance el script CGI
          <code>footer.pl</code>.</p>
    
          <div class="example"><p><code>
            Action add-footer /cgi-bin/footer.pl<br />
            AddHandler add-footer .html
          </code></p></div>
    
          <p>En este caso, el script CGI es el responsable de enviar el
          documento originalmente solicitado (contenido en la variable de
          entorno <code>PATH_TRANSLATED</code>) y de hacer cualquier
          modificaci&#243;n o a&#241;adido deseado.</p>
    
        
        <h3><a name="example2" id="example2">Archivos con cabeceras HTTP</a></h3>
          
    
          <p>Las siguientes directivas activan el handler
          <code>send-as-is</code>, que se usa para ficheros que contienen
          sus propias cabeceras HTTP. Todos los archivos en el directorio
          <code>/web/htdocs/asis/</code> ser&#225;n procesados por el
          handler <code>send-as-is</code>, sin tener en cuenta su
          extension.</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/web/htdocs/asis"&gt;
        SetHandler send-as-is
    &lt;/Directory&gt;</pre>
    
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programmer" id="programmer">Nota para programadores</a></h2>
        
    
        <p>Para implementar las funcionalidades de los handlers, se ha
        hecho un a&#241;adido a la <a href="developer/API.html">API de
        Apache</a> que puede que quiera usar. Para ser m&#225;s
        espec&#237;ficos, se ha a&#241;adido un nuevo registro a la
        estructura <code>request_rec</code>:</p>
    
        <pre class="prettyprint lang-c">char *handler</pre>
    
    
        <p>Si quiere que su m&#243;dulo llame a un handler , solo tiene
        que a&#241;adir <code>r-&gt;handler</code> al nombre del handler
        en cualquier momento antes de la fase <code>invoke_handler</code>
        de la petici&#243;n. Los handlers se implementan siempre como se
        hac&#237;a antes, aunque usando el nombre del handler en vez de un
        tipo de contenido. Aunque no es de obligado cumplimiento, la
        convenci&#243;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.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/handler.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/install.html.es������������������������������������������������������������0000664�0001751�0001751�00000072601�14743132254�020004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Compilar e Instalar - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="./">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>Compilar e Instalar</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta traducci&#243;n podr&#237;a estar
                obsoleta. Consulte la versi&#243;n en ingl&#233;s de la
                documentaci&#243;n para comprobar si se han producido cambios
                recientemente.</div>
    
    
        <p>&#201;ste documento hace referencia a la compilaci&#243;n y la instalaci&#243;n del Apache 
        HTTP Server s&#243;lo para los sistemas Unix y  tipo Unix. Para la compilaci&#243;n e instalaci&#243;n en Windows  ir a  <a href="platform/windows.html">Usando Apache HTTP Server con Microsoft
        Windows</a> y <a href="platform/win_compiling.html">Compilando Apache para Microsoft Windows</a>.
        Para otras plataformas visite la documentaci&#243;n sobre <a href="platform/">plataformas</a>.</p>
    
        <p>Apache httpd usa <code>libtool</code> y <code>autoconf</code>
        para crear un entorno de compilaci&#243;n que se parece a muchos otros proyectos de c&#243;digo abierto</p>
    
        <p>Si est&#225; actualizando desde una versi&#243;n menor a la siguiente (por
        ejemplo, 2.4.8 a 2.4.9), pasa a la secci&#243;n de  <a href="#upgrading">actualizaci&#243;n</a>.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Descripci&#243;n general para los impacientes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#requirements">Requisitos</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#download">Descargar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extract">Descomprimir</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configure">Configuraci&#243;n de la estructura de
    directorios</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compile">Build</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">Instalar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#customize">Personalizar APACHE</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#test">Comprobar que la instalaci&#243;n
    funciona</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#upgrading">Actualizar una instalaci&#243;n previa</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#thirdp">Paquetes de terceros</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="programs/configure.html">Configuraci&#243;n del &#225;rbol de las fuentes de c&#243;digo</a></li><li><a href="invoking.html">Arrancando Apache httpd</a></li><li><a href="stopping.html">Parada y Reinicio</a></li><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Descripci&#243;n general para los impacientes</a></h2>
    
        <table>
          
          <tr>
            <td><a href="#download">Descarga</a></td>
    
            <td>Descarga la &#250;ltima versi&#243;n 
              desde <a href="http://httpd.apache.org/download.cgi#apache24">
              http://httpd.apache.org/download.cgi</a>
            </td>
          </tr>
    
          <tr>
            <td><a href="#extract">Extraer</a></td>
    
            <td><code>$ gzip -d httpd-<em>NN</em>.tar.gz<br />
             $ tar xvf httpd-<em>NN</em>.tar<br />
             $ cd httpd-<em>NN</em></code></td>
          </tr>
    
          <tr>
            <td><a href="#configure">Configura</a></td>
    
            <td><code>$ ./configure --prefix=<em>PREFIX</em></code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#compile">Compila</a></td>
    
            <td><code>$ make</code> </td>
          </tr>
    
          <tr>
            <td><a href="#install">Instala</a></td>
    
            <td><code>$ make install</code> </td>
          </tr>
    
          <tr>
            <td><a href="#customize">Personalizalo</a></td>
    
            <td><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code> </td>
          </tr>
    
          <tr>
            <td><a href="#test">Prueba</a></td>
    
            <td><code>$ <em>PREFIX</em>/bin/apachectl -k start</code>
            </td>
          </tr>
        </table>
    
        <p><em>NN</em> hay que reemplazarlo por el n&#250;mero de la versi&#243;n menor, y <em>PREFIX</em> hay que reemplazarlo por la ruta en la que se va a instalar Apache. Si no especifica ning&#250;n valor en <em>PREFIX</em>, el valor por defecto que se toma es /usr/local/apache2.</p>
    
        <p>Cada parte del proceso de configuraci&#243;n e instalaci&#243;n se describe detalladamente m&#225;s abajo, empezando por los requisitos para compilar e instalar Apache.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">Requisitos</a></h2>
    
        <p>Estos son los requisitos necesarios para compilar Apache:</p>
    
        <dl>
          <dt>APR y APR-Util</dt>
          <dd>Aseg&#250;rate de que tiene instalado ya en su sistema APR y APR-Util. Si no es as&#237;, o no quiere utilizar la versi&#243;n que le proporciona el sistema, puede descargar la &#250;ltima versi&#243;n de ambos APR y APR-Util de
          <a href="http://apr.apache.org/">Apache APR</a>, descomprimelo en
           <code>/httpd_source_tree_root/srclib/apr</code> y /httpd_source_tree_root<code>/srclib/apr-util</code>
          (cerci&#243;rate de que no existen directorios con n&#250;meros de versiones; por ejemplo,
          la distribuci&#243;n de APR debe estar en /httpd_source_tree_root/srclib/apr/) y usa el comando
          <code>./configure</code> <code>--con-las-opciones-incluidas-en-apr</code>.
          En algunas plataformas deber&#225;s instalar la parte correspondiente a los paquetes 
          <code>-dev</code> para permitir que httpd se genere contra la instalaci&#243;n de la copia de APR y APR-Util.</dd>
    
          <dt>Librer&#237;a Compatible de expresiones regulares de Perl (PCRE)</dt>
          <dd>Esta librer&#237;a es requerida, pero ya no incluido con httpd.
          Descarga el c&#243;digo fuente de <a href="http://www.pcre.org/">http://www.pcre.org</a>,
          o instala un Port o un  Paquete. Si la distrubuci&#243;n de su sistema no puede encontrar el escript pcre-config instalado por PCRE, seleccione utilizando el par&#225;metro<code>--with-pcre</code>.En algunas plataformas,
          deber&#225;s instalar la correspondiente versi&#243;n <code>-dev</code>
          del paquete para permitir a httpd que se genere contra la instalaci&#243;n de la copia del PCRE que se ha instalado.</dd>
    
          <dt>Espacio en disco</dt> 
          <dd>Compruebe que tiene disponibles al
          menos 50 MB de espacio libre en disco. Despu&#233;s de la
          instalaci&#243;n, Apache ocupa aproximadamente 10 MB. No
          obstante, la necesidad real de espacio en disco var&#237;a
          considerablemente en funci&#243;n de las opciones de
          configuraci&#243;n que elija y de los m&#243;dulos externos que
          use, y como no del tama&#241;o de la p&#225;gina web</dd>
    
          <dt>Systema de compilaci&#243;n ANSI-C</dt>
          <dd>Compruebe que tiene instalado un compilador de ANSI-C. Se recomienda el <a href="http://gcc.gnu.org/">Compilador GNU C
          (GCC)</a> de la <a href="http://www.gnu.org/">Free Software
          Foundation (FSF)</a> es el recomendado. Si no tiene instalado el GCC, entonces compruebe que
          el compilador que va a utilizar cumple con los est&#225;ndares
          ANSI. Adem&#225;s, su <code>PATH</code> debe contener la
          ubicaci&#243;n donde de encuentran las herramientas b&#225;sicas
          para compilar tales como <code>make</code>.</dd>
    
          <dt>Ajuste exacto del reloj del sistema</dt> 
          <dd>Los elementos
          del protocolo HTTP est&#225;n expresados seg&#250;n la hora del
          d&#237;a. Por eso, si quiere puede investigar como instalar alguna
          utilidad para sincronizar la hora de su sistema. Para esto,
          normalmente, se usan los programas <code>ntpdate</code> o
          <code>xntpd</code>, que est&#225;n basados en el protocolo
          "Network Time Protocol" (NTP). Consulte el<a href="http://www.ntp.org">sitio web de NTP
          </a> para obtener m&#225;s informaci&#243;n sobre NTP y los
          servidores p&#250;blicos de tiempo.</dd>
    
          <dt><a href="http://www.perl.org/">Perl 5</a>[OPCIONAL]</dt>
          <dd>Para algunos de los scripts de soporte como<code class="program"><a href="./programs/apxs.html">apxs</a></code> o <code class="program"><a href="./programs/dbmmanage.html">dbmmanage</a></code> (que est&#225;n
          escritos en Perl) es necesario el int&#233;rprete de Perl 5 (las
          versiones 5.003 o posteriores son suficientes). Si el escript
          <code class="program"><a href="./programs/configure.html">configure</a></code> no se encuentra, no podr&#225; usar los
    	  escripts correspondientes que lo necesiten. Pero por supuesto
    	  podr&#225;s compilar y usar Apache httpd.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="download" id="download">Descargar</a></h2>
    
        <p>Puede descargar Apache desde <a href="http://httpd.apache.org/download.cgi">la secci&#243;n de
        descargas del sitio web de Apache</a> el cual tiene varios
        mirrors. Para la mayor&#237;a de los usuarios de Apache que tienen
        sistemas tipo Unix, se recomienda que se descarguen y compilen el
        c&#243;digo fuente. El proceso de compilaci&#243;n (descrito
        m&#225;s abajo) es f&#225;cil, y permite adaptar el servidor
        Apache a sus necesidades. Adem&#225;s, las versiones de
        disponibles en archivos binarios no est&#225;n siempre actualizadas
        con las &#250;ltimas modificaciones en el c&#243;digo fuente. Si se
        descarga un binario, siga las instrucciones contenidas en el
        archivo <code>INSTALL.bindist</code> incluido en la
        distribuci&#243;n</p>
    
        <p>Despu&#233;s de la descarga, es importante que verifique que el
        archivo descargado del servidor HTTP Apache est&#225; completo y
        sin modificaciones.  Esto puede hacerlo comparando el archivo
        descargado (.tgz) con su firma PGP. Instrucciones detalladas de
        c&#243;mo hacer esto est&#225;n disponibles en <a href="http://httpd.apache.org/download.cgi#verify"> la
        secci&#243;n de descargas</a> junto con un ejemplo de c&#243;mo <a href="http://httpd.apache.org/dev/verification.html">usar
        PGP</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extract" id="extract">Descomprimir</a></h2>
    
        <p>Extraer el c&#243;digo fuente del archivo .tgz del Servidor Apache HTTP que acabada 
          de descargar es muy f&#225;cil. Ejecute los siguientes comandos:</p>
    
    <div class="example"><p><code>
    $ gzip -d httpd-<em>NN</em>.tar.gz<br />
    $ tar xvf httpd-<em>NN</em>.tar
    </code></p></div>
    
        <p>Estos comandos crear&#225;n un nuevo directorio dentro del
        directorio en el que se encuentra y que contendr&#225; el
        c&#243;digo fuente de distribuci&#243;n. Debe cambiarse a ese
        directorio con <code>cd</code> para proceder a compilar el
        servidor Apache.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">Configuraci&#243;n de la estructura de
    directorios</a></h2>
    
        <p>El siguiente paso es configurar la estructura de directorios
        para su plataforma y sus necesidades personales. Esto se hace
        usando el script <code class="program"><a href="./programs/configure.html">configure</a></code> incluido en el directorio
        ra&#237;z de la distribuci&#243;n que acaba de descargar. (Los
        desarrolladores que se descarguen la versi&#243;n del CVS de la
        estructura de directorios necesitar&#225;n tener instalados
        <code>autoconf</code> y <code>libtool</code>, y necesitar&#225;n
        ejecutar <code>buildconf</code> antes de continuar con los
        siguientes pasos. Esto no es preciso para las versiones
        oficiales.)</p>
    
        <p>Para configurar la estructura de directorios a partir del
        c&#243;digo fuente usando las opciones por defecto, solo tiene que
        ejecutar <code>./configure</code>.Para cambiar las opciones por
        defecto, <code class="program"><a href="./programs/configure.html">configure</a></code> acepta una serie de variables y
        opciones por la l&#237;nea de comandos.</p>
    
        <p>La opci&#243;n m&#225;s importante es <code>--prefix</code>
        que es el directorio en el que Apache va a ser instalado despu&#233;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 <a href="programs/configure.html#installationdirectories">opciones de
        configuraci&#243;n</a>.</p>
    
        <p>Llegados a este punto, puede especificar que <a href="programs/configure.html#optionalfeatures">caracter&#237;sticas
        o funcionalidades</a> quiere incluir en Apache activando o
        desactivando <a href="mod/">modules</a>.Apache vine con una amplia
        selecci&#243;n de m&#243;dulos incluidos por defecto. Que ser&#225;n compilados como .
        <a href="dso.html">Objetos Compartidos (DSOs)</a> Que pueden ser activados
        o desactivados en tiempo de ejecuci&#243;n.
        Tambi&#233;n puede elegir por compilar m&#243;dulos de forma est&#225;tica usando las opciones
        <code>--enable-<var>module</var>=static</code>.</p>
    
    
    
        <p>Se pueden activar otros m&#243;dulos usando la opci&#243;n 
        <code>--enable-<var>module</var></code>, where
        <var>module</var> es el nombre del m&#243;dulo sin el
        <code>mod_</code> y convirtiendo los guiones bajos que tenga en
        guiones normales.  Del mismo modo, puede desactivar los m&#243;dulos con la
        opci&#243;n <code>--disable-<var>module</var></code>. Tenga cuidado al utilizar esta opci&#243;n, ya que
        <code class="program"><a href="./programs/configure.html">configure</a></code> no le avisar&#225; si el m&#243;dulo que especifica no existe;
        simplemente ignorar&#225; esa opci&#243;n.</p>
    
        <p>Adem&#225;s, a veces es necesario pasarle al script
        <code class="program"><a href="./programs/configure.html">configure</a></code> informaci&#243;n adicional sobre donde esta
        su compilador, librer&#237;as o ficheros de cabecera.  Esto se puede
        hacer, tanto pasando variables de entorno, como pasandole opciones
        a <code class="program"><a href="./programs/configure.html">configure</a></code>.  Para m&#225;s informaci&#243;n, consulte el manual de
        <code class="program"><a href="./programs/configure.html">configure</a></code>. O use <code class="program"><a href="./programs/configure.html">configure</a></code> con la 
        opci&#243;n <code>--help</code>.</p>
    
         <p>Para que se haga una idea sobre las posibilidades que tiene,
        aqu&#237; tiene un ejemplo t&#237;pico que configura Apache para
        la ruta <code>/sw/pkg/apache</code> con un compilador y unos flags
        determinados, y adem&#225;s, con dos m&#243;dulos adicionales
        <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> y <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> para
        cargarlos despu&#233;s a trav&#233;s del mecanismo DSO:</p>
    
    <div class="example"><p><code>
          $ CC="pgcc" CFLAGS="-O2" \<br />
           ./configure --prefix=/sw/pkg/apache \<br />
           --enable-ldap=shared \<br />
           --enable-lua=shared
    </code></p></div>
    
        <p>Cuando se ejecuta <code class="program"><a href="./programs/configure.html">configure</a></code> se comprueban que
        caracter&#237;sticas o funcionalidades est&#225;n disponibles en
        su sistema y se crean los Makefiles que ser&#225;n usados a continuaci&#243;n
        para compilar el servidor. Esto tardar&#225; algunos minutos.</p>
    
        <p>Los detalles de todas las opciones de <code class="program"><a href="./programs/configure.html">configure</a></code> est&#225;n disponibles
        en el manual de <code class="program"><a href="./programs/configure.html">configure</a></code> .</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile" id="compile">Build</a></h2>
    
        <p>Ahora puede compilar las diferentes partes que forman Apache
        simplemente ejecutando el siguiente comando:</p>
    
    <div class="example"><p><code>$ make</code></p></div>
    
        <p>Por favor sea paciente llegado a este punto, ya que una configuraci&#243;n b&#225;sica lleva unos minutos
          para su compilaci&#243;n, y el tiempo puede variar mucho dependiendo de su hardware 
          y del n&#250;mero de m&#243;dulos que haya habilitado para la compilaci&#243;n.(Se recomienda a&#241;adir al make el
          par&#225;metro -j3 como m&#237;nimo para que vaya m&#225;s r&#225;pido)</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">Instalar</a></h2>
    
        <p>Ahora es el momento de instalar el paquete en el diretorio
        elegido en <em>PREFIX</em> (consulte m&#225;s arriba la opci&#243;n
        <code>--prefix</code>) ejecutando:</p>
    
    <div class="example"><p><code>$ make install</code></p></div>
    
        <p>Este paso requiere de forma t&#237;pica privilegios de root, ya que 
          el directorio de <em>PREFIX</em> es normalmente un directorio con 
          restricciones de permisos escritura.</p>
    
        <p>Si lo que esta es s&#243;lo actualizando, la instalaci&#243;n no sobreescribir&#225; los
          archivos de configuraci&#243;n.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customize" id="customize">Personalizar APACHE</a></h2>
    
        <p>Tras la instalaci&#243;n puede personalizarla, editando los 
        <a href="configuring.html">archivos de configuracion </a> en el directorio de
        <code><em>PREFIX</em>/conf/</code>.</p>
    
    <div class="example"><p><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code></p></div>
    
        <p>&#201;chele un vistazo al Manual de Apache que est&#225; en
        <code><em>PREFIX</em>/docs/manual/</code> o consulta <a href="http://httpd.apache.org/docs/2.4/">http://httpd.apache.org/docs/2.4/</a> para la versi&#243;n m&#225;s
        reciente de este manual y su completa
        referencia de las <a href="mod/directives.html">directivas de configuracion</a> disponibles.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="test" id="test">Comprobar que la instalaci&#243;n
    funciona</a></h2>
    
        <p>Ahora puedes  <a href="invoking.html">ejecutar</a> tu Apache
        HTTP server ejecutando directamente:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k start</code></p></div>
    
        <p>Ahora debe poder acceder a su primer documento
        bajo la URL <code>http://localhost/</code>. La p&#225;gina o documento que ve se encuentra en
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>,
        que por norma general casi siempre ser&#225; <code><em>PREFIX</em>/htdocs/</code>.
        Si quiere  <a href="stopping.html">parar</a> el servidor, puede hacerlo ejecutando:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k stop</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">Actualizar una instalaci&#243;n previa</a></h2>
    
        <p>El primer paso para actualizar una instalaci&#243;n anterior es
        leer las especificaciones de la versi&#243;n y el fichero
        <code>CHANGES</code> en la distribuci&#243;n de c&#243;digo fuente
        que ha descargado para encontrar los cambios que puedan afectar a
        su instalaci&#243;n actual. Cuando el cambio sea entre versiones
        mayores(por ejemplo, de la 2.0 a 2.2 o de la 2.2 a la 2.4),
        entonces es m&#225;s probable que haya diferencias importantes en
        la compilaci&#243;n y en la ejecuci&#243;n que necesitar&#225;n
        ajustes manuales. Todos los m&#243;dulos necesitar&#225;n
        tambi&#233;n ser actualizados para adaptarse a los cambios en el
        interfaz de programaci&#243;n (API) de m&#243;dulos.</p>
    
        <p>Actualizando de una versi&#243;n menor a la siguiente
          (por ejemplo, de la 2.2.55 a la  2.2.57) es mas f&#225;cil. El prodeso de realizar el <code>make install</code>
        no sobreescribir&#225; ninguno de tus documentos existentes,archivos
        log, o archivos de configuraci&#243;n. De hecho, los desarrolladores est&#225;n haciendo los esfuerzos
        necerarios para evitar cambios que generen incompatibilidades en las opciones de
        <code class="program"><a href="./programs/configure.html">configure</a></code>, la configuraci&#243;n al ser ejecutado, o el m&#243;dulo de la API
        entre versiones menores. En la mayor parte de los casos debe poder usar un
        comando <code class="program"><a href="./programs/configure.html">configure</a></code> id&#233;ntico, un fichero de
        configuraci&#243;n id&#233;ntico, y todos sus m&#243;dulos deben
        seguir funcionando.</p>
    
        <p>Para actualizar entre versiones menores, empecemos encontrando el archivo de configuraci&#243;n
        <code>config.nice</code> el directorio <code>de instalaci&#243;n</code> del servidor
        o en el directorio raiz del c&#243;digo fuente de tu antigua instalaci&#243;n. Este archivo contendr&#225;
        los par&#225;metros exactos para pasarle al 
        <code class="program"><a href="./programs/configure.html">configure</a></code> que usaste anteriormente para configurar tus directorios.
        Entonces, para actualizar su instalaci&#243;n de una versi&#243;n a la
        siguinete, solo tiene que copiar el archivo
        <code>config.nice</code> a la estructura de directorios del
        c&#243;digo fuente de la nueva versi&#243;n, editarlo, hacer
        cualquier cambio que desee, y ejecutarlo :</p>
    
        <div class="example"><p><code>
        $ ./config.nice<br />
        $ make<br />
        $ make install<br />
        $ <em>PREFIX</em>/bin/apachectl -k graceful-stop<br />
        $ <em>PREFIX</em>/bin/apachectl -k start<br />
        </code></p></div>
    
        <div class="warning">Tenga en cuenta que antes de poner una nueva
        versi&#243;n de Apache en producci&#243;n, debe siempre probarla
        antes en un entorno de pruebas. Por ejemplo, puede instalar y ejecutar la
        nueva versi&#243;n junto con la antigua usando un
        <code>--prefix</code> diferente y un puerto diferente (modificando
        la directiva <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>)
        para comprobar que no existe ninguna incompatibilidad antes de
        hacer la actualizaci&#243;n definitiva.</div>
    
        <p>Puede pasarle argumentos adicionales a <code>config.nice</code>,
        que se agregar&#225;n a susopciones originales de <code class="program"><a href="./programs/configure.html">configure</a></code>:</p>
    
        <div class="example"><p><code>
        $ ./config.nice --prefix=/home/test/apache --with-port=90
        </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="thirdp" id="thirdp">Paquetes de terceros</a></h2>
    
        <p>Un gran n&#250;mero de terceros proporcionan sus propias 
        distribuciones empaquetadas del Apache HTTP Server para su
        instalaci&#243;n en plataformas espec&#237;ficas. Esto incluye las distintas
        distribuciones de Linux, varios paquetes de Windows de terceros,
        Mac OS X, Solaris, y muchos m&#225;s.</p>
    
        <p>Nuestra licencia de software no s&#243;lo permite, sino que anima, 
        este tipo de redistribuci&#243;n. Sin embargo, se da lugar a una situaci&#243;n
        en la que el dise&#241;o y la configuraci&#243;n de los valores predeterminados
        de la instalaci&#243;n del servidor pueden diferir de lo que se indica
        en la documentaci&#243;n. Mientras lamentablemente, esta situaci&#243;n no es probable que cambie a corto plazo.</p>
    
        <p>Una <a href="http://wiki.apache.org/httpd/DistrosDefaultLayout">descripci&#243;n
        de estas distribuciones de terceros </a> est&#225; siendo actualizada en el servidor de la WIKI de HTTP
        Server, y deber&#237;a reflejar el actual estado de &#233;stas distribuciones de terceros. 
        Sin embargo, tendr&#225; que familiarizarse con los procedimientos de gesti&#243;n
        e instalaci&#243;n de paquetes de su plataforma (SO) en particular.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/install.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html.es�����������������������������������������������������������0000664�0001751�0001751�00000033634�14743132254�020165� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Iniciar Apache - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="./">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>Iniciar Apache</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>En Windows, Apache se ejecuta normalmente como un servicio. 
            Para obtener m&#225;s informaci&#243;n, consulte
        <a href="platform/windows.html#winsvc">Ejecutar Apache como un
        servicio</a>.</p>
    
        <p>En Unix, el programa <code class="program"><a href="./programs/httpd.html">httpd</a></code> se
        ejecuta como un demonio (daemon) de forma cont&#237;niua y en segundo plano
        y atiende las peticiones que le lleguen.  Este documento describe c&#243;mo
        invocar el programa <code class="program"><a href="./programs/httpd.html">httpd</a></code>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#startup">C&#243;mo iniciar Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errors">Errores Durante el Arranque</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#boot">Iniciar Apache al Iniciar el Sistema</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#info">Informaci&#243;n Adicional</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="stopping.html">Parar y reiniciar Apache</a></li><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="startup" id="startup">C&#243;mo iniciar Apache</a></h2>
    
        <p>Si el puerto especificado en la directiva <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> del fichero de
        configuraci&#243;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&#243;n a
        trav&#233;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&#225; varios procesos,
        procesos <em>hijo</em>, que hacen el trabajo de escuchar y atender
        las peticiones de los clientes.  El proceso principal,
        <code>httpd</code> contin&#250;a ejecut&#225;ndose con el usuario root, pero los
        procesos hijo se ejecutan con menores privilegios de usuario.
        Esto lo controla el <a href="mpm.html">M&#243;dulo de
        MultiProcesamiento (MPM)</a> seleccionado.</p>
    
        <p>La forma recomendada para invocar el ejecutable
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> es usando el script de control 
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>.  Este script fija
        determinadas variables de entorno que son necesarias para que
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> funcione correctamente en el sistema operativo,
        y despu&#233;s invoca el binario <code class="program"><a href="./programs/httpd.html">httpd</a></code>.
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> pasa a <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        cualquier argumento que se le pase a trav&#233;s de la l&#237;nea de comandos, 
        de forma que cualquier opci&#243;n de <code>httpd</code> puede ser usada
        tambi&#233;n con <code>apachectl</code>.  Puede editar
        directamente el script <code>apachectl</code> y cambiar la
        variable <code>HTTPD</code> variable que est&#225; al principio y
        que especifica la ubicaci&#243;n exacta en la que est&#225; el
        binario <code class="program"><a href="./programs/httpd.html">httpd</a></code> y cualquier argumento de l&#237;nea de
        comandos que quiera que est&#233; <em>siempre</em> presente.</p>
    
        <p>La primera cosa que hace <code class="program"><a href="./programs/httpd.html">httpd</a></code> cuando es invocado
        es localizar y leer el <a href="configuring.html">fichero de
        configuraci&#243;n</a> <code>httpd.conf</code>. El lugar en el que
        est&#225; ese fichero se determina al compilar, pero tambi&#233;n
        es posible especificar la ubicaci&#243;n en la que se encuentra al
        iniciar el servidor Apache usando la opci&#243;n de l&#237;nea de
        comandos <code>-f</code></p>
    
    <div class="example"><p><code>/usr/local/apache2/bin/apachectl -f
          /usr/local/apache2/conf/httpd.conf</code></p></div>
    
        <p>Si todo va bien durante el arranque, la sesi&#243;n de terminal
        se suspender&#225; un momento y volver&#225; a estar activa casi
        inmediatamente. Esto quiere decir que el servidor est&#225; activo
        y funcionando. Puede usar su navegador para conectarse al
        servidor y ver la p&#225;gina de prueba que hay en el directorio de
        la directiva
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errors" id="errors">Errores Durante el Arranque</a></h2>
    
        <p>Si Apache encuentra una error irrecuperable durante el
        arranque, escribir&#225; un mensaje describiendo el problema en la
        consola o en el archivo <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> antes de abortar la
        ejecuci&#243;n. Uno de los mensajes de error m&#225;s comunes es
        "<code>Unable to bind to Port ...</code>". Cuando se recibe este
        mensaje es normalmente por alguna de las siguientes razones:</p>
    
        <ul>
          <li>Est&#225; intentando iniciar el servidor Apache en un puerto
          privilegiado (del 0 al 1024) sin haber hecho login como usuario
          root; &#243; bien</li>
    
          <li>Est&#225; intentando iniciar el servidor Apache mientras
          est&#225; ya ejecutando Apache o alg&#250;n otro servidor web en
          el mismo puerto.</li>
        </ul>
    
        <p>Puede encontrar m&#225;s informaci&#243;n sobre c&#243;mo
        solucionar problemas, en la secci&#243;n de <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> de Apache.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="boot" id="boot">Iniciar Apache al Iniciar el Sistema</a></h2>
    
        <p>Si quiere que el servidor Apache contin&#250;e su ejecuci&#243;n
        despu&#233;s de reiniciar el sistema, debe a&#241;adir una llamada
        a <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> en sus archivos de arranque (normalmente
        <code>rc.local</code> o un fichero en ese directorio del tipo
        <code>rc.N</code>). Esto iniciar&#225; Apache como usuario
        root. Antes de hacer esto, aseg&#250;rese de que la
        configuraci&#243;n de seguridad y las restricciones de acceso de
        su servidor Apache est&#225;n correctamente configuradas.</p>
    
        <p>El script <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> est&#225; dise&#241;ado para
        actuar como un script est&#225;ndar de tipo <code>SysV init</code>; puede tomar los
        argumentos <code>start</code>, <code>restart</code>, y
        <code>stop</code> y traducirlos en las se&#241;ales apropiadas
        para <code class="program"><a href="./programs/httpd.html">httpd</a></code>.  De esta manera, casi siempre puede
        simplemente enlazar <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>con el directorio init
        adecuado. Pero aseg&#250;rese de comprobar los requisitos exactos
        de su sistema.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="info" id="info">Informaci&#243;n Adicional</a></h2>
    
        <p>En la secci&#243;n <a href="programs/">El Servidor y Programas
        de Soporte </a> puede encontrar m&#225;s informaci&#243;n sobre
        las opciones de l&#237;nea de comandos que puede pasar a <code class="program"><a href="./programs/httpd.html">httpd</a></code> y <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> as&#237; como sobre otros
        programas de soporte incluidos con el servidor Apache.
        Tambi&#233;n hay documentaci&#243;n sobre todos los <a href="mod/">m&#243;dulos</a> incluidos con la distribuci&#243;n de
        Apache y sus correspondientes <a href="mod/directives.html">directivas</a> asociadas.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/invoking.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.zh-cn.utf8������������������������������������������������������0000664�0001751�0001751�00000021544�14743132254�020742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP 服务器 2.4 文档 - Apache HTTP 服务器 版本 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a></div>
    <div id="page-content"><h1>Apache HTTP 服务器 2.4 文档</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Google 搜索" type="submit" /><input value="10" name="num" type="hidden" /><input value="zh-cn" name="hl" type="hidden" /><input value="UTF-8" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="版本 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">发行说明</a></h2>
    <ul><li><a href="new_features_2_4.html">Apache 2.3/2.4 的新特性</a></li>
    <li><a href="new_features_2_2.html">Apache 2.1/2.2 的新特性</a></li>
    <li><a href="new_features_2_0.html">Apache 2.0 的新特性</a></li>
    <li><a href="upgrading.html">从 2.2 升级到 2.4</a></li>
    <li><a href="license.html">Apache 许可证</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">参考手册</a></h2>
    <ul><li><a href="install.html">编译与安装</a></li>
    <li><a href="invoking.html">启动</a></li>
    <li><a href="stopping.html">停止与重启</a></li>
    <li><a href="mod/quickreference.html">指令快速参考</a></li>
    <li><a href="mod/">模块</a></li>
    <li><a href="mpm.html">多处理模块(MPM)</a></li>
    <li><a href="filter.html">过滤器</a></li>
    <li><a href="handler.html">处理器</a></li>
    <li><a href="expr.html">表达式解析器</a></li>
    <li><a href="programs/">服务器与支持程序</a></li>
    <li><a href="glossary.html">术语</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">用户指南</a></h2>
    <ul><li><a href="getting-started.html">入门指南</a></li>
    <li><a href="bind.html">绑定指定地址与端口</a></li>
    <li><a href="configuring.html">配置文件</a></li>
    <li><a href="sections.html">配置片段</a></li>
    <li><a href="caching.html">缓存指南</a></li>
    <li><a href="content-negotiation.html">内容协商</a></li>
    <li><a href="dso.html">动态共享对象(DSO)</a></li>
    <li><a href="env.html">环境变量</a></li>
    <li><a href="logs.html">日志文件</a></li>
    <li><a href="urlmapping.html">从 URL 映射到文件系统</a></li>
    <li><a href="misc/perf-tuning.html">性能调谐</a></li>
    <li><a href="misc/security_tips.html">安全技巧</a></li>
    <li><a href="server-wide.html">服务器全局配置</a></li>
    <li><a href="ssl/">SSL/TLS 加密</a></li>
    <li><a href="suexec.html">执行 CGI 前的用户切换(suEXEC)</a></li>
    <li><a href="rewrite/">URL 改写与 mod_rewrite</a></li>
    <li><a href="vhosts/">虚拟主机</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">指引/教程</a></h2>
    <ul><li><a href="howto/auth.html">认证,授权与访问控制</a></li>
    <li><a href="howto/access.html">访问控制</a></li>
    <li><a href="howto/cgi.html">CGI 与动态内容</a></li>
    <li><a href="howto/htaccess.html">.htaccess 文件</a></li>
    <li><a href="howto/ssi.html">服务器端插入(SSI)</a></li>
    <li><a href="howto/public_html.html">用户私人网站目录(public_html)</a></li>
    <li><a href="howto/reverse_proxy.html">反向代理设置指南</a></li>
    <li><a href="howto/http2.html">HTTP/2 指南</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">平台相关说明</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">基于RPM安装包的系统 (Redhat / CentOS / Fedora)</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC 系统</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">其它主题</a></h2>
    <ul><li><a href="http://wiki.apache.org/httpd/FAQ">常见问题</a></li>
    <li><a href="sitemap.html">网站导航</a></li>
    <li><a href="developer/">开发文档</a></li>
    <li><a href="http://httpd.apache.org/docs-project/">帮助改进文档</a></li>
    <li><a href="misc/">其它说明</a></li>
    <li><a href="http://wiki.apache.org/httpd/">维基</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/install.html.ko.euc-kr�����������������������������������������������������0000664�0001751�0001751�00000047522�14743132254�021177� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ϰ ġ - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ϰ ġ</h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    
        <p>  н н ýۿ ġ ϰ
        ġϴ ͸ ٷ.  ϰ ġϴ 
        <a href="platform/windows.html">ũμƮ 
        ġ </a> ϶. ٸ ÷ ؼ <a href="platform/">÷</a>  ϶.</p>
    
        <p>ġ 2.0  ġ ȯ 1.3 ſ ٸ.
        ġ 1.3  ġ  ü ũƮ ߴ.
        ġ 2.0  ٸ  ¼ҽ Ʈ  ȯ
         <code>libtool</code> <code>autoconf</code>
        Ѵ.</p>
    
        <p>   Ѵܰ ׷̵Ѵٸ ( ,
        2.0.50 2.0.51), <a href="#upgrading">׷̵</a>
         ٷ  ٶ.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">    </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#requirements">䱸</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#download">ٿε</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extract"> Ǯ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configure">ҽ Ʈ ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compile"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">ġ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#customize"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#test">˻</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#upgrading">׷̵</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="programs/configure.html">ҽ Ʈ </a></li><li><a href="invoking.html">ġ </a></li><li><a href="stopping.html">ġ ߴܰ </a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">    </a></h2>
    
        <table>
          
          <tr>
            <td><a href="#download">ٿε</a></td>
    
            <td><code>$ lynx http://httpd.apache.org/download.cgi</code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#extract"> Ǯ</a></td>
    
            <td><code>$ gzip -d httpd-2_1_<em>NN</em>.tar.gz<br />
             $ tar xvf httpd-2_1_<em>NN</em>.tar</code> </td>
          </tr>
    
          <tr>
            <td><a href="#configure"></a></td>
    
            <td><code>$ ./configure --prefix=<em>PREFIX</em></code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#compile"></a></td>
    
            <td><code>$ make</code> </td>
          </tr>
    
          <tr>
            <td><a href="#install">ġ</a></td>
    
            <td><code>$ make install</code> </td>
          </tr>
    
          <tr>
            <td><a href="#customize"></a></td>
    
            <td><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code> </td>
          </tr>
    
          <tr>
            <td><a href="#test">˻</a></td>
    
            <td><code>$ <em>PREFIX</em>/bin/apachectl start</code>
            </td>
          </tr>
        </table>
    
        <p><em>NN</em>    ڷ, <em>PREFIX</em>
         ġ Ͻý η üؾ Ѵ. <em>PREFIX</em>
          ⺻ <code>/usr/local/apache2</code>
        Ѵ.</p>
    
        <p>Ʒ ġ  ϰ ġϱ 䱸׺
        ϰ ġ   ڼ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">䱸</a></h2>
    
        <p>ġ ϱ   ͵ ʿϴ:</p>
    
        <dl>
          <dt>ũ </dt>
          <dd>ũ  ּ 50 MB ̻ Ȯ϶.
          ġ ġ  10 MB ũ  Ѵ.
           ʿ ũ    ɼǰ ߰ ⿡
            ̰ .</dd>
    
          <dt>ANSI-C Ϸ  ý</dt>
          <dd>ANSI-C Ϸ ġִ Ȯ϶. <a href="http://www.gnu.org/">Free Software Foundation (FSF)</a>
          <a href="http://www.gnu.org/software/gcc/gcc.html">GNU C
          compiler (GCC)</a> õѴ. ( 2.7.2 ȴ.) GCC
          ٸ ּ ϴ Ϸ ANSI ȣȯ Ȯ϶.
          ߰ <code>PATH</code> ȯ溯 <code>make</code>
           ⺻   ؾ Ѵ.</dd>
    
          <dt>Ȯ ð</dt>
          <dd>HTTP ݿ Ϸ ð ǥϴ κ ִ. ׷
           ý ð ȭ  캼 ð̴. 
          ̸  Network Time Protocol (NTP) 
          <code>ntpdate</code> <code>xntpd</code> Ѵ.
          NTP Ʈ  ð    ׷
          <a href="news:comp.protocols.time.ntp">comp.protocols.time.ntp</a>
          <a href="http://www.ntp.org">NTP Ȩ</a>
          ϶.</dd>
    
          <dt><a href="http://www.perl.org/">Perl 5</a>
          [û]</dt>
          <dd>(Perl ) <a href="programs/apxs.html">apxs</a>
          <a href="programs/dbmmanage.html">dbmmanage</a> 
           ũƮ  Perl 5 Ͱ ʿϴ. (
          5.003 ̸̻ ȴ.) `<code>configure</code>' ũƮ
           ͸ ã ص  ġ 2.0
          ϰ ġ  ִ. ٸ  ũƮ 
           ̴.  Perl Ͱ ġִٸ (Ƹ
          춧 Ե Perl 4   Perl 5)
          <code>./configure</code> ùٸ  ã
          <code>--with-perl</code> ɼ (Ʒ ) ϱ ٶ.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="download" id="download">ٿε</a></h2>
    
        <p>ġ  ̷  ִ <a href="http://httpd.apache.org/download.cgi">ġ 
        ٿε Ʈ</a> ٿε  ִ. н ý
        Ѵٸ ҽڵ带 ٿ޾Ƽ ϴ  . 
        (Ʒ )   ְ, ڽ 뵵 ˸° 
          ִ. , ֽ  ̳ʸ   쵵
        . ̳ʸ ٿ޴´ٸ  ִ
        <code>INSTALL.bindist</code>  ø .</p>
    
        <p>ٿε ٿ  ϰ
         ġ  Ȯϴ  ߿ϴ.
        PGP   ٿε Ÿ(tarball) ˻Ͽ ȮѴ.
        ڼ  <a href="http://httpd.apache.org/download.cgi#verify">ٿε
        </a> ְ, <a href="http://httpd.apache.org/dev/verification.html">PGP
        </a> ϴ   ִ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extract" id="extract"> Ǯ</a></h2>
    
        <p>ġ  Ÿ ҽ Ǫ ۾ ܼ 
        tar Ǫ ̴:</p>
    
    <div class="example"><p><code>
    $ gzip -d httpd-2_1_<em>NN</em>.tar.gz<br />
    $ tar xvf httpd-2_1_<em>NN</em>.tar
    </code></p></div>
    
        <p>׷  丮 Ʒ  ҽڵ带 
        ο 丮 .  ϱ  
        丮 <code>cd</code>ؾ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">ҽ Ʈ ϱ</a></h2>
    
        <p>  Ư ÷  ʿ信  ġ
        ҽ Ʈ ϴ ̴. ̸   ֻ 丮
        ִ <code><a href="programs/configure.html">configure</a></code>
        ũƮ Ѵ. (ġ
        ҽ Ʈ CVS  ٿε ڴ ̹
        <code>autoconf</code> <code>libtool</code> ġְ,
          Ѿ  <code>buildconf</code> ؾ
        Ѵ. ̴   ʿ.)</p>
    
        <p> ⺻ ɼ Ͽ ҽ Ʈ Ϸ 
        <code>./configure</code> Էϸȴ. ⺻ ɼ Ϸ
        <code>./configure</code>    ɼ Ѵ.</p>
    
        <p> ߿ ɼ ġ  ۵ϱ ġ
        ϰ ġ  <code>--prefix</code>. ٸ <a href="programs/configure.html#installationdirectories">configure
        ɼǵ</a> Ͽ  ġ  ڼ  
        ִ.</p>
    
        <p><a href="mod/"></a> ϰų  ġ 
        <a href="programs/configure.html#optionalfeatures"></a>
        Ѵ. <a href="mod/module-dict.html#Status">Base</a>
          ⺻ ġ Եȴ. ٸ 
         <code>--enable-<var>module</var></code> ɼ Ͽ
        Ѵ. ⼭ <em>module</em>  ̸
        <code>mod_</code>   ȣ  .
        <code>--enable-<var>module</var>=shared</code> ɼ ϸ
         ߿ ϰų   ִ <a href="dso.html">ü(shared object, DSO)</a> Ѵ.
        , <code>--disable-<var>module</var></code> ɼ Ͽ
        Base    ִ.   
        <code>configure</code> ʰ ׳ ϱ⶧
         ̸ Ȯ Է϶.</p>
    
        <p> <code>configure</code> ũƮ Ϸ,
        ̺귯,   ġ ˷  찡 ִ.
          ȯ溯 <code>configure</code>  ɼ
        Ͽ Ѵ. ڼ  <a href="programs/configure.html">configure manpage</a>
        ϶.</p>
    
        <p>   ִ ɼ ֱ 
        Ư Ϸ ÷׸ ϰ ߿ DSO о
          <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
        <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> ߰Ͽ
        <code>/sw/pkg/apache</code> ġ ġ ϴ
         ̴:</p>
    
    <div class="example"><p><code>
          $ CC="pgcc" CFLAGS="-O2" \<br />
           ./configure --prefix=/sw/pkg/apache \<br />
           --enable-rewrite=shared \<br />
           --enable-speling=shared
    </code></p></div>
    
        <p><code>configure</code> ϸ а ý 
        ˻Ͽ ߿  Ҷ  Makefile
        .</p>
    
        <p><code>configure</code> ɼǵ鿡  ڼ  <a href="programs/configure.html">configure manpage</a> ִ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile" id="compile"></a></h2>
    
        <p>  ɾ ϳ ġ  κ 
         ִ:</p>
    
    <div class="example"><p><code>$ make</code></p></div>
    
        <p>⼭  ٷ. Ƽ III/ 2.2 ýۿ
        ⺻  ϴµ  3  ɸ.  ð
        ϵ    ũ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">ġ</a></h2>
    
        <p>  ɾ Ű ( <code>--prefix</code>
        ɼ )  ġ ġ <em>PREFIX</em> ġѴ:</p>
    
    <div class="example"><p><code>$ make install</code></p></div>
    
        <p>׷̵Ѵٸ  ġ   ̳ 
         ʴ´.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customize" id="customize"></a></h2>
    
        <p> <code><em>PREFIX</em>/conf/</code> ִ
        <a href="configuring.html"></a> Ͽ ġ
         Ѵ.</p>
    
    <div class="example"><p><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code></p></div>
    
        <p>밡 <a href="mod/directives.html"> þ</a>
              ֱ  <a href="./">docs/manual/</a>̳ <a href="http://httpd.apache.org/docs/2.4/">http://httpd.apache.org/docs/2.4/</a> ִ ġ 
        ϶.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="test" id="test">˻</a></h2>
    
        <p>   ġ  <a href="invoking.html"></a>  ִ:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl start</code></p></div>
    
        <p>׸ URL <code>http://localhost/</code> ù 
        ûѴ. Ե  Ƹ
        <code><em>PREFIX</em>/htdocs/</code> <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> Ʒ ִ. ׸
         ɾ ٽ  <a href="stopping.html">ߴ</a>Ѵ:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl stop</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">׷̵</a></h2>
    
        <p>׷̵Ѵٸ  Ʈ    ִ ȭ
        ִ ˾ƺ ǥ ҽ  <code>CHANGES</code>
         д´. ( , 1.3 2.0̳ 2.0 2.2
        ) ū     ɼǰ   ؾ
         ū ȭ  ̴.  ⵵  API ȭ
        ˸° ׷̵ؾ Ѵ.</p>
    
        <p>  Ѵܰ ׷̵ϴ  ( ,
        2.0.55 2.0.57) . <code>make install</code> ۾
         , α,   ʴ´. ,
        ڴ   <code>configure</code> ɼ, ,
         API ȣȯ ȭ ִ ´. κ 
         <code>configure</code> ,  
          ְ, 鵵    ̴. ( 
        2.0.41  شѴ.  鿡 ȣȯ
        ȭ ִ.)</p>
    
        <p> ġߴ ҽ  ִٸ, ׷̵尡 
        .  ҽ ֻ ִ <code>config.nice</code>
        Ͽ ҽ   ߴ <code>configure</code>
         ɼ ״ ִ. ׷   ׷̵Ѵٸ
        ο  ҽ <code>config.nice</code>  ϰ,
        Ѵٸ    ,   Ѵ:</p>
    
        <div class="example"><p><code>
        $ ./config.nice<br />
        $ make<br />
        $ make install<br />
        $ <em>PREFIX</em>/bin/apachectl stop<br />
        $ <em>PREFIX</em>/bin/apachectl start<br />
        </code></p></div>
    
        <div class="warning">ο  ϱ  ׻ ˻غ
        Ѵ.  , ׷̵带 ġ  ȣȯ 
        ִ ˾ƺ ٸ <code>--prefix</code> (<code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> þ) ٸ Ʈ
        Ͽ ο  ġ    غ
         ִ.</div>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/install.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/bind.html.ko.euc-kr��������������������������������������������������������0000664�0001751�0001751�00000025710�14743132254�020440� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ּҿ Ʈ  (Binding) - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ּҿ Ʈ  (Binding)</h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>ġ Ư ּҿ Ʈ ϵ ϱ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ipv6">IPv6 Ư  </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">ȣƮ  dz</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="vhosts/">ȣƮ</a></li><li><a href="dns-caveats.html">DNS </a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview"></a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mpm_common.html">mpm_common</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code></li></ul></td></tr></table>
    
    
        <p>ġ ϸ ġ ǻ  Ʈ ּҿ
        Ͽ,  û ٸ. ⺻ ġ
        ǻ  ּҿ ٸ. ׷ ġ Ư Ʈ
         ּҸ ٸ ؾ 찡 ִ.   
        ġ  ٸ IP ּ, ȣƮ, Ʈ 
        ϴ ȣƮ ɰ õִ.</p>
    
        <p><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> þ
         Ư Ʈ ּҿ Ʈ տ û ް
        Ѵ. <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        þ Ʈ ȣ ϸ,   ̽
         Ʈ ٸ.  <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> þ ٸ 
        ּҿ Ʈ   ִ.   ּҿ Ʈ
        û  Ѵ.</p>
    
        <p> ,  80 8000 Ʈ ο 
        ޵ Ϸ:</p>
    
        <div class="example"><p><code>
          Listen 80<br />
          Listen 8000
        </code></p></div>
    
        <p>   ̽ Ʈ  ٸ
        Ϸ,</p>
    
        <div class="example"><p><code>
          Listen 192.0.2.1:80<br />
          Listen 192.0.2.5:8000
        </code></p></div>
    
        <p>IPv6 ּҴ   ȣ  Ѵ:</p>
    
        <div class="example"><p><code>
          Listen [2001:db8::a00:20ff:fea7:ccea]:80
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipv6" id="ipv6">IPv6 Ư  </a></h2>
        
    
        <p>IPv6  ÷ ð ְ APR ̵ ÷ κп
    	IPv6 ϱ⶧, ġ IPv6  ҴϿ IPv6
    	 û ó  ִ.</p>
    
        <p>ġ ڿ  κ IPv6  IPv4 
    	IPv6   ó  ִĴ ̴. κ ÷
        IPv4-(mapped) IPv6 ּҸ Ͽ IPv6 Ͽ IPv4
    	 , FreeBSD NetBSD OpenBSD ýü å
    	⺻  ʴ´. ׷ ⺻ ʴ
    	ý̶ ġ  Ư  Ķͷ 
    	 ִ.</p>
    
        <p>ݸ  Tru64  Ϻ ÷ IPv4 IPv6
         óϷ  ּҸ <strong>ؾ߸</strong>
        Ѵ. ġ ּ  Ͽ IPv4  IPv6
          ޵Ϸ, IPv4- IPv6 ּҸ ϰ
    	<a href="programs/configure.html">configure</a> ɼ
        <code>--enable-v4-mapped</code> Ѵ.</p>
    
        <p><code>--enable-v4-mapped</code> FreeBSD, NetBSD, OpenBSD
    	  ÷ ⺻̰, Ƹ  ġ
    	 ̴.</p>
    
        <p>÷ APR ο  ġ IPv4 Ḹ
    	޵Ϸ,     <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> þ IPv4 ּҸ
    	Ѵ:</p>
    
        <div class="example"><p><code>
          Listen 0.0.0.0:80<br />
          Listen 192.0.2.1:80
        </code></p></div>
    
        <p>÷ ϸ ġ  ٸ  IPv4
         IPv6  ޵Ϸ ( IPv4- ּҸ 
        ), <a href="programs/configure.html">configure</a>
        ɼ <code>--disable-v4-mapped</code>
        Ѵ. <code>--disable-v4-mapped</code> FreeBSD, NetBSD,
        OpenBSD ⺻̴.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">ȣƮ  dz</a></h2>
        
    
        <p><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        ȣƮ  ʴ´. ̴  ּ
         ּҿ Ʈ ٸ ˷ش. <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> þ
         ,    û Ȱ óѴ.
        ׷ <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>  ּҿ Ʈ
         ٸ ൿ   ִ. ȣƮ 
           ּҿ Ʈ ˷ Ѵ. ׸
        Ư ּҿ Ʈ  ȣƮ ൿ 
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
         ʿϴ. ּ ٸʴ ּҿ Ʈ ϴ
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
           ϶.</p>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/bind.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������httpd-2.4.64/docs/manual/configuring.html.ko.euc-kr�������������������������������������������������0000664�0001751�0001751�00000033325�14743132254�022037� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title> - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1></h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p>  ġ  ϴ ϵ Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#main">ּ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#syntax"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#scope">þ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#htaccess">.htaccess </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">ּ</a></h2>
        
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#include">Include</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code></li></ul></td></tr></table>
    
        <p>Ϲ   Ͽ <a href="mod/directives.html">þ</a> Ͽ ġ
        Ѵ. ּ  <code>httpd.conf</code>
        θ.   ġ Ͻ , <code>-f</code>
         ɼ   ִ.  ٸ  <code class="directive"><a href="./mod/core.html#include">Include</a></code> þ Ͽ 
         ְ, ϵī带 Ͽ    
        ִ.   þ  Ͽ ص ȴ.
        ּ ϸ ġ ϰų  Ŀ
        ݿȴ.</p>
    
        <p> mime Ÿ  ϵ д´. ϸ
        <code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code> þ
        ϰ, ⺻ <code>mime.types</code>̴.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="syntax" id="syntax"> </a></h2>
        
    
        <p>ġ  ٿ  þ Ѵ.  
        ڰ 齽 "\"̸ þ  ٿ ӵ Ѵ.
          齽 ڿ  ڳ 鵵  ȵȴ.</p>
    
        <p> þ ҹڸ  , þ
        ƱԸƮ ҹڸ ϴ 찡 ִ. ؽ "#"
        ϴ  ּ Ѵ. ּ  þ 
        ٿ   <strong></strong>. ٰ þ տ 
         ϹǷ, ϰ ̵ þ ٵ(indent)
         ִ.</p>
    
        <p><code>apachectl configtest</code> <code>-t</code> 
        ɼ Ͽ ġ  ʰ  
         ˻  ִ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="modules" id="modules"></a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>ġ ȭ . ̴ ſ ⺻ ɸ
         ٽɿ Ե Ѵ. ġ <a href="mod/"></a> о鿩 
        ȮѴ. ⺻ ϸ  <a href="mod/module-dict.html#Status">base</a>  Եȴ.
         <a href="dso.html"> о̴</a> 
          ְ Ͽٸ   Ͽ ƹ
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> þ
        ߰  ִ. ׷   ߰ϰų 
        ġ ٽ ؾ Ѵ.  þ <code class="directive"><a href="./mod/core.html#ifmodule">IfModule</a></code>  μ Ư
         ִ 쿡  ó  ִ.</p>
    
        <p>    ϵִ  <code>-l</code>
         ɼ Ѵ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="scope" id="scope">þ </a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>ּϿ ִ þ  ü ȴ. þ
         Ϻο ǰ Ϸ þ <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>  ȿ ξѴ.
         ǵ ׵ δ þ  Ͻý̳
        URL Ư ġ Ѵ. ,  ļ   ֱ⶧
        ſ   ϴ.</p>
    
        <p>ġ  ٸ Ʈ ÿ ϴ
        ɷ ִ. ̸ <a href="vhosts/">ȣƮ</a> Ѵ.
        þ
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
         ȿ ξ Ư Ʈ þ   ִ.</p>
    
        <p>þ κ  ǿ ͵ ,  þ
        Ư ҿ ǹ̰ .   μ  ϴ
        þ ּ ҿ   ִ. þ
         ǿ ġ  ִ ˷ þ <a href="mod/directive-dict.html#Context"></a> Ȯ϶.
         ڼ  <a href="sections.html"> Directory,
        Location, Files  ϳ</a> ϶.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">.htaccess </a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
    
        <p>ġ Ư  Ͽ 
        (б)   ִ.  Ư  
        <code>.htaccess</code> θ, ̸ <code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code> þ
          ִ. <code>.htaccess</code> Ͽ ִ þ
         ִ 丮  丮 ȴ.
        <code>.htaccess</code>  ּϰ  
        . <code>.htaccess</code>   û б⶧
         ϸ  ȿ   ִ.</p>
    
        <p> þ <code>.htaccess</code> Ͽ  
        ִ ˷ þ <a href="mod/directive-dict.html#Context"></a>
        Ȯ϶.  ڴ ּ <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> þ
        <code>.htaccess</code> Ͽ  þ   ִ
          ִ.</p>
    
        <p><code>.htaccess</code> Ͽ   ڼ 
        <a href="howto/htaccess.html">.htaccess 丮</a>
        ϶.</p>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/configuring.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/�����������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�017032� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/modules.html�����������������������������������������������������0000664�0001751�0001751�00000000315�13710016232�021344� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: modules.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: modules.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/thread_safety.html�����������������������������������������������0000664�0001751�0001751�00000000174�13710016232�022521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: thread_safety.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/documenting.html�������������������������������������������������0000664�0001751�0001751�00000000333�13710016232�022210� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: documenting.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: documenting.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/modguide.html����������������������������������������������������0000664�0001751�0001751�00000000167�13710016232�021476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: modguide.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/request.html�����������������������������������������������������0000664�0001751�0001751�00000000166�13710016232�021370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: request.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/index.html.zh-cn.utf8��������������������������������������������0000664�0001751�0001751�00000013733�14743132254�022730� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache 2.0 开发者文档 - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache 2.0 开发者文档</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../en/developer/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
        <p>开发者页面的许多文档都来自于 Apache 1.3。当更新到 Apache 2
        时,它们可能位于不同的阶段。请耐心等待,或者直接向
        <a href="http://httpd.apache.org/lists.html#http-dev">dev@httpd.apache.org</a> 邮件列表报告开发者页面的差异或错误。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#topics">主题</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#external">外部资源</a></li>
    </ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="topics" id="topics">主题</a></h2>
        <ul>
          <li><a href="API.html">Apache 1.3 API 说明</a></li>
          <li><a href="new_api_2_4.html">在 Apache 2.3/2.4 中的 API 改变</a></li>
          <li><a href="hooks.html">Apache 2.x 钩子函数</a></li>
          <li><a href="request.html">Apache 2.x 中的请求处理</a></li>
          <li><a href="filters.html">Apache 2.x 中的过滤器</a></li>
          <li><a href="output-filters.html">Apache 2.x 中的输出过滤器指南</a></li>
          <li><a href="modules.html">将模块从 Apache 1.3 移植到 Apache 2.x</a></li>
          <li><a href="debugging.html">在 APR 中调试内存分配</a></li>
          <li><a href="documenting.html">Apache 2.x 文档</a></li>
          <li><a href="thread_safety.html">Apache 2.x 的线程安全问题</a></li>
        </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="external" id="external">外部资源</a></h2>
        <ul>
            <li><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/">自动生成的 Apache HTTP 服务器 (trunk) 代码文档</a></li>
    
          <li>Kevin O'Donnell 的模块开发教程
          <ul>
            <li><a href="http://threebit.net/tutorials/apache2_modules/tut1/tutorial1.html">集成模块到 Apache 构建系统</a></li>
    
            <li><a href="http://threebit.net/tutorials/apache2_modules/tut2/tutorial2.html">处理配置指令</a></li>
          </ul></li>
    
          <li><a href="http://www.onlamp.com/pub/ct/38">Ryan Bloom 对 Apache 模块开发的说明</a></li>
    
          <li>位于 <a href="http://www.apachetutor.org/">apachetutor</a> 的开发者文章:
          <ul>
            <li><a href="http://www.apachetutor.org/dev/request">Apache 中的请求处理</a></li>
            <li><a href="http://www.apachetutor.org/dev/config">模块的配置</a></li>
            <li><a href="http://www.apachetutor.org/dev/pools">Apache 中的资源管理</a></li>
            <li><a href="http://www.apachetutor.org/dev/reslist">Apache 中的连接池</a></li>
            <li><a href="http://www.apachetutor.org/dev/brigades">桶与队列简介</a></li>
          </ul></li>
        </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../en/developer/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������httpd-2.4.64/docs/manual/developer/documenting.html.en����������������������������������������������0000664�0001751�0001751�00000015456�14737241666�022652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Documenting code in Apache 2.4 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Documenting code in Apache 2.4</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/documenting.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/documenting.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>Apache 2.4 uses <a href="http://www.doxygen.org/">Doxygen</a> to
        document the APIs and global variables in the code. This will explain
        the basics of how to document using Doxygen.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="brief" id="brief">Brief Description</a></h2>
        <p>To start a documentation block, use <code>/**</code><br />
        To end a documentation block, use <code>*/</code></p>
    
        <p>In the middle of the block, there are multiple tags we can
        use:</p>
    
        <div class="example"><p><code>
          Description of this functions purpose<br />
          @param parameter_name description<br />
          @return description<br />
          @deffunc signature of the function<br />
        </code></p></div>
    
        <p>The <code>deffunc</code> 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 <code>deffunc</code>. An example (using &amp;gt; rather
        than &gt;):</p>
    
        <div class="example"><p><code>
          /**<br />
     &nbsp;* return the final element of the pathname<br />
     &nbsp;* @param pathname The path to get the final element of<br />
     &nbsp;* @return the final element of the path<br />
     &nbsp;* @tip Examples:<br />
     &nbsp;* &lt;pre&gt;<br />
     &nbsp;*                 "/foo/bar/gum"   -&amp;gt; "gum"<br />
     &nbsp;*                 "/foo/bar/gum/"  -&amp;gt; ""<br />
     &nbsp;*                 "gum"            -&amp;gt; "gum"<br />
     &nbsp;*                 "wi\\n32\\stuff" -&amp;gt; "stuff"<br />
     &nbsp;* &lt;/pre&gt;<br />
     &nbsp;* @deffunc const char * ap_filename_of_pathname(const char *pathname)<br />
     &nbsp;*/
        </code></p></div>
    
        <p>At the top of the header file, always include:</p>
        <div class="example"><p><code>
          /**<br />
     &nbsp;* @package Name of library header<br />
     &nbsp;*/
        </code></p></div>
    
        <p>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.</p>
    
        <p>For a further discussion of the possibilities please refer to
        <a href="http://www.doxygen.org/">the Doxygen site</a>.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/documenting.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/documenting.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/documenting.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/documenting.html.zh-cn.utf8��������������������������������������0000664�0001751�0001751�00000015305�14743132254�024132� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache 2.0 文档 - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a> &gt; <a href="./">开发者文档</a></div><div id="page-content"><div id="preamble"><h1>Apache 2.0 文档</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../en/developer/documenting.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/documenting.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
        <p>Apache 2.0 使用 <a href="http://www.doxygen.org/">Doxygen</a> 从代码中
        生成 API 和全局变量的文档。下面是对使用 Doxygen 生成文档的简介。</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="brief" id="brief">简要说明</a></h2>
        <p>使用 <code>/**</code> 开始文档块<br />
        使用 <code>*/</code> 结束文档块</p>
    
        <p>在文档块中,我们可以使用多个标签:</p>
    
        <div class="example"><p><code>
          Description of this functions purpose<br />
          @param parameter_name description<br />
          @return description<br />
          @deffunc signature of the function<br />
        </code></p></div>
          
        <p>一般不需要 <code>deffunc</code> 。DoxyGen 没有完整的解析器,所以任何
        在返回类型声明中使用宏的原型,都是太复杂了。这些函数就需要使用 <code>deffunc</code>。
        例如 (使用 &amp;gt; 而不是 &gt;):</p>
    
        <div class="example"><p><code>
          /**<br />
     &nbsp;* return the final element of the pathname<br />
     &nbsp;* @param pathname The path to get the final element of<br />
     &nbsp;* @return the final element of the path<br />
     &nbsp;* @tip Examples:<br />
     &nbsp;* &lt;pre&gt;<br />
     &nbsp;*                 "/foo/bar/gum"   -&amp;gt; "gum"<br />
     &nbsp;*                 "/foo/bar/gum/"  -&amp;gt; ""<br />
     &nbsp;*                 "gum"            -&amp;gt; "gum"<br />
     &nbsp;*                 "wi\\n32\\stuff" -&amp;gt; "stuff"<br />
     &nbsp;* &lt;/pre&gt;<br />
     &nbsp;* @deffunc const char * ap_filename_of_pathname(const char *pathname)<br />
     &nbsp;*/
        </code></p></div>
    
        <p>总是在头文件开始包含:</p>
        <div class="example"><p><code>
          /**<br />
     &nbsp;* @package Name of library header<br />
     &nbsp;*/
        </code></p></div>
    
        <p>Doxygen 为每个包生成一个新的 HTML 文件,名字是
        {Name_of_library_header}.html,所以请简化名称。</p>
    
        <p>更深入的讨论,请参见
        <a href="http://www.doxygen.org/">Doxygen 站点</a>。</p>
    </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../en/developer/documenting.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/documenting.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">评论</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/documenting.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/debugging.html.en������������������������������������������������0000664�0001751�0001751�00000010563�14737241666�022263� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Debugging Memory Allocation in APR - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Debugging Memory Allocation in APR</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/debugging.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <p>
        This document has been removed.
        </p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/debugging.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/debugging.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/index.html.en����������������������������������������������������0000664�0001751�0001751�00000014044�14737241666�021435� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Developer Documentation for the Apache HTTP Server 2.4 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Developer Documentation for the Apache HTTP Server 2.4</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <div class="warning"><h3>Warning</h3>
        <p>Many of the documents listed here are in need of update.
        They are in different stages of progress.
        Please be patient and follow <a href="https://httpd.apache.org/docs-project/">this link</a>
        to propose a fix or point out any error/discrepancy.</p>
        </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#developing">2.4 development documents</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#upgrading">Upgrading to 2.4</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#external">Other Resources</a></li>
    </ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developing" id="developing">2.4 development documents</a></h2>
        <ul>
          <li><a href="modguide.html">Developing modules for the Apache HTTP Server 2.4</a></li>
          <li><a href="hooks.html">Hook Functions in 2.4</a></li>
          <li><a href="request.html">Request Processing in 2.4</a></li>
          <li><a href="filters.html">How filters work in 2.4</a></li>
          <li><a href="output-filters.html">Guidelines for output filters in 2.4</a></li>
          <li><a href="documenting.html">Documenting code in 2.4</a></li>
          <li><a href="thread_safety.html">Thread Safety Issues in 2.4</a></li>
        </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">Upgrading to 2.4</a></h2>
        <ul>
          <li><a href="new_api_2_4.html">API changes in 2.3/2.4</a></li>
          <li><a href="modules.html">Converting Modules from 1.3 to 2.x</a></li>
        </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="external" id="external">Other Resources</a></h2>
        <ul>
          <li><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/">Autogenerated Apache HTTP Server (trunk) code documentation</a> (the link is built by
            this <a href="https://ci.apache.org/builders/httpd-doxygen-nightly">job</a>).
          </li>
    
          <li>Developer articles at <a href="http://www.apachetutor.org/">apachetutor</a> include:
          <ul>
            <li><a href="http://www.apachetutor.org/dev/request">Request Processing</a></li>
            <li><a href="http://www.apachetutor.org/dev/config">Configuration for Modules</a></li>
            <li><a href="http://www.apachetutor.org/dev/pools">Resource Management</a></li>
            <li><a href="http://www.apachetutor.org/dev/reslist">Connection Pooling</a></li>
            <li><a href="http://www.apachetutor.org/dev/brigades">Introduction to Buckets and Brigades</a></li>
          </ul></li>
          <li><a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug or feature request</a></li>
        </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../zh-cn/developer/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/modguide.html.en�������������������������������������������������0000664�0001751�0001751�00000214422�14737241666�022125� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Developing modules for the Apache HTTP Server 2.4 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer</a></div><div id="page-content"><div id="preamble"><h1>Developing modules for the Apache HTTP Server 2.4</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/modguide.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
    <p>This document explains how you can develop modules for the Apache HTTP 
    Server 2.4</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basics">Defining a module</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#hooking">Getting started: Hooking into the server</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#handling">Building a handler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuration">Adding configuration options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#context">Context aware configurations</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#summary">Summing up</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#snippets">Some useful snippets of code</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="request.html">Request Processing in Apache 2.4</a></li><li><a href="hooks.html">Apache 2.x Hook Functions</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    <h3><a name="what" id="what">What we will be discussing in this document</a></h3>
    <p>
    This document will discuss how you can create modules for the Apache 
    HTTP Server 2.4, by exploring an example module called 
    <code>mod_example</code>. In the first part of this document, the purpose 
    of this module will be to calculate and print out various digest values for 
    existing files on your web server, whenever we access the URL <code>
    http://hostname/filename.sum</code>. For instance, if we want to know the 
    MD5 digest value of the file located at <code>
    http://www.example.com/index.html</code>, we would visit <code>
    http://www.example.com/index.html.sum</code>. 
    </p>
    
    <p>
    In the second part of this document, which deals with configuration 
    directive and context awareness, we will be looking at a module that simply 
    writes out its own configuration to the client.
    </p>
    
    
    <h3><a name="prerequisites" id="prerequisites">Prerequisites</a></h3>
    <p>
    First and foremost, you are expected to have a basic knowledge of how the C 
    programming language works. In most cases, we will try to be as pedagogical 
    as possible and link to documents describing the functions used in the 
    examples, but there are also many cases where it is necessary to either 
    just assume that "it works" or do some digging yourself into what the hows 
    and whys of various function calls. 
    </p>
    <p>
    Lastly, you will need to have a basic understanding of how modules are 
    loaded and configured in the Apache HTTP Server, as well as how to get the headers for 
    Apache if you do not have them already, as these are needed for compiling 
    new modules.
    </p>
    
    <h3><a name="compiling" id="compiling">Compiling your module</a></h3>
    <p>
    To compile the source code we are building in this document, we will be 
    using <a href="../programs/apxs.html">APXS</a>. Assuming your source file 
    is called mod_example.c, compiling, installing and activating the module is 
    as simple as: 
    </p>
    <div class="example"><pre>apxs -i -a -c mod_example.c</pre></div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basics" id="basics">Defining a module</a></h2>
    <p>
    <img src="../images/build_a_mod_3.png" alt="Module name tags" /><br />
    Every module starts with the same declaration, or name tag if you will, 
    that defines a module as <em>a separate entity within Apache</em>:</p>
    
    
    
    <pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
    { 
        STANDARD20_MODULE_STUFF,
        create_dir_conf, /* Per-directory configuration handler */
        merge_dir_conf,  /* Merge handler for per-directory configurations */
        create_svr_conf, /* Per-server configuration handler */
        merge_svr_conf,  /* Merge handler for per-server configurations */
        directives,      /* Any directives we may have for httpd */
        register_hooks   /* Our hook registering function */
    };</pre>
    
    
    
    <p>
    This bit of code lets the server know that we have now registered a new module 
    in the system, and that its name is <code>example_module</code>. The name 
    of the module is used primarily for two things:<br />
    </p>
    <ul>
    <li>Letting the server know how to load the module using the LoadModule</li>
    <li>Setting up a namespace for the module to use in configurations</li>
    </ul>
    <p>
    For now, we're only concerned with the first purpose of the module name, 
    which comes into play when we need to load the module:
    </p>
    <pre class="prettyprint lang-config">LoadModule example_module modules/mod_example.so</pre>
    
    <p>
    In essence, this tells the server to open up <code>mod_example.so</code> and look for a module 
    called <code>example_module</code>.
    </p>
    <p>
    Within this name tag of ours is also a bunch of references to how we would 
    like to handle things: Which directives do we respond to in a configuration 
    file or .htaccess, how do we operate within specific contexts, and what 
    handlers are we interested in registering with the Apache HTTP service. We'll 
    return to all these elements later in this document.
    </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hooking" id="hooking">Getting started: Hooking into the server</a></h2>
    <h3><a name="hook_intro" id="hook_intro">An introduction to hooks</a></h3>
    <p>
    When handling requests in Apache HTTP Server 2.4, the first thing you will need to do is 
    create a hook into the request handling process. A hook is essentially a 
    message telling the server that you are willing to either serve or at least 
    take a glance at certain requests given by clients. All handlers, whether 
    it's mod_rewrite, mod_authn_*, mod_proxy and so on, are hooked into 
    specific parts of the request process. As you are probably aware, modules 
    serve different purposes; Some are authentication/authorization handlers, 
    others are file or script handlers while some third modules rewrite URIs or 
    proxies content. Furthermore, in the end, it is up to the user of the server 
    how and when each module will come into place. Thus, the server itself does not 
    presume to know which module is responsible for handling a specific 
    request, and will ask each module whether they have an interest in a given 
    request or not. It is then up to each module to either gently decline 
    serving a request, accept serving it or flat out deny the request from 
    being served, as authentication/authorization modules do: <br />
    <img src="../images/build_a_mod_2.png" alt="Hook handling in httpd" /><br />
    To make it a bit easier for handlers such as our mod_example to know 
    whether the client is requesting content we should handle or not, the server 
    has directives for hinting to modules whether their assistance is needed or 
    not. Two of these are <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> 
    and <code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code>. Let's take a look at 
    an example using <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code>. In 
    our example case, we want every request ending with .sum to be served by 
    <code>mod_example</code>, so we'll add a configuration directive that tells 
    the server to do just that:
    </p>
    <pre class="prettyprint lang-config">AddHandler example-handler .sum</pre>
    
    <p>
    What this tells the server is the following: <em>Whenever we receive a request 
    for a URI ending in .sum, we are to let all modules know that we are 
    looking for whoever goes by the name of "example-handler" </em>. 
    Thus, when a request is being served that ends in .sum, the server will let all 
    modules know, that this request should be served by "example-handler
    ". As you will see later, when we start building mod_example, we will 
    check for this handler tag relayed by <code>AddHandler</code> and reply to 
    the server based on the value of this tag.
    </p>
    
    <h3><a name="hook_declaration" id="hook_declaration">Hooking into httpd</a></h3>
    <p>
    To begin with, we only want to create a simple handler that replies to the 
    client browser when a specific URL is requested, so we won't bother setting 
    up configuration handlers and directives just yet. Our initial module 
    definition will look like this:</p>
    
    
    
    <pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
    {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        register_hooks   /* Our hook registering function */
    };</pre>
    
    
    
    
    <p>This lets the server know that we are not interested in anything fancy, we 
    just want to hook onto the requests and possibly handle some of them. </p> 
    
    <p> The reference in our example declaration, <code>register_hooks</code> 
    is the name of a function we will create to manage how we hook onto the 
    request process. In this example module, the function has just one purpose; 
    To create a simple hook that gets called after all the rewrites, access 
    control etc has been handled. Thus, we will let the server know that we want 
    to hook into its process as one of the last modules: 
    </p>
    
    
    <pre class="prettyprint lang-c">static void register_hooks(apr_pool_t *pool)
    {
        /* Create a hook in the request handler, so we get called when a request arrives */
        ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
    }</pre>
    
    
    
    <p>
    The <code>example_handler</code> reference is the function that will handle 
    the request. We will discuss how to create a handler in the next chapter.
    </p>
    
    <h3><a name="hook_others" id="hook_others">Other useful hooks</a></h3>
    <p>
    Hooking into the request handling phase is but one of many hooks that you 
    can create. Some other ways of hooking are:
    </p>
    <ul>
    <li><code>ap_hook_child_init</code>: Place a hook that executes when a child process is spawned (commonly used for initializing modules after the server has forked)</li>
    <li><code>ap_hook_pre_config</code>: Place a hook that executes before any configuration data has been read (very early hook)</li>
    <li><code>ap_hook_post_config</code>: Place a hook that executes after configuration has been parsed, but before the server has forked</li>
    <li><code>ap_hook_pre_translate_name</code>: Place a hook that executes when a URI needs to be translated into a filename on the server, before decoding</li>
    <li><code>ap_hook_translate_name</code>: Place a hook that executes when a URI needs to be translated into a filename on the server (think <code>mod_rewrite</code>)</li>
    <li><code>ap_hook_quick_handler</code>: Similar to <code>ap_hook_handler</code>, except it is run before any other request hooks (translation, auth, fixups etc)</li>
    <li><code>ap_hook_log_transaction</code>: Place a hook that executes when the server is about to add a log entry of the current request</li>
    </ul>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="handling" id="handling">Building a handler</a></h2>
    <p>
    A handler is essentially a function that receives a callback when a request 
    to the server is made. It is passed a record of the current request (how it was 
    made, which headers and requests were passed along, who's giving the 
    request and so on), and is put in charge of either telling the server that it's 
    not interested in the request or handle the request with the tools provided.
    </p>
    <h3><a name="simple_handler" id="simple_handler">A simple "Hello, world!" 
    handler</a></h3> 
    <p>Let's start off by making a very simple request handler 
    that does the following:
    </p>
    <ol>
    <li>Check that this is a request that should be served by "example-handler"</li>
    <li>Set the content type of our output to <code>text/html</code></li>
    <li>Write "Hello, world!" back to the client browser</li>
    <li>Let the server know that we took care of this request and everything went fine</li>
    </ol>
    <p>
    In C code, our example handler will now look like this:
    </p>
    
    
    <pre class="prettyprint lang-c">static int example_handler(request_rec *r)
    {
        /* First off, we need to check if this is a call for the "example-handler" handler.
         * If it is, we accept it and do our things, if not, we simply return DECLINED,
         * and the server will try somewhere else.
         */
        if (!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return (DECLINED);
        
        /* Now that we are handling this request, we'll write out "Hello, world!" to the client.
         * To do so, we must first set the appropriate content type, followed by our output.
         */
        ap_set_content_type(r, "text/html");
        ap_rprintf(r, "Hello, world!");
        
        /* Lastly, we must tell the server that we took care of this request and everything went fine.
         * We do so by simply returning the value OK to the server.
         */
        return OK;
    }</pre>
    
    
    
    <p>
    Now, we put all we have learned together and end up with a program that 
    looks like 
    <a href="http://people.apache.org/~humbedooh/mods/examples/mod_example_1.c">mod_example_1.c</a>
    . The functions used in this example will be explained later in the section 
    <a href="#functions">"Some useful functions you should know"</a>. 
    </p>
     
    <h3><a name="request_rec" id="request_rec">The request_rec structure</a></h3> 
    <p>The most essential part of any request is the <em>request record
    </em>. In a call to a handler function, this is represented by the <code>
    request_rec* </code> structure passed along with every call that is made. 
    This struct, typically just referred to as <code>r</code> in modules, 
    contains all the information you need for your module to fully process any 
    HTTP request and respond accordingly.</p> <p>Some key elements of the <code>
    request_rec </code> structure are:
    </p>
    <ul>
    <li><code>r-&gt;handler (char*):</code> Contains the name of the handler the server is currently asking to do the handling of this request</li>
    <li><code>r-&gt;method (char*):</code> Contains the HTTP method being used, f.x. GET or POST</li>
    <li><code>r-&gt;filename (char*):</code> Contains the translated filename the client is requesting</li>
    <li><code>r-&gt;args (char*):</code> Contains the query string of the request, if any</li>
    <li><code>r-&gt;headers_in (apr_table_t*):</code> Contains all the headers sent by the client</li>
    <li><code>r-&gt;connection (conn_rec*):</code> A record containing information about the current connection</li>
    <li><code>r-&gt;user (char*):</code> If the URI requires authentication, this is set to the username provided</li>
    <li><code>r-&gt;useragent_ip (char*):</code> The IP address of the client connecting to us</li>
    <li><code>r-&gt;pool (apr_pool_t*)</code>: The memory pool of this request. We'll discuss this in the 
    "<a href="#memory">Memory management</a>" chapter.</li>
    </ul>
    <p>
    A complete list of all the values contained within the <code>request_rec</code> structure can be found in 
    the <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/include/httpd.h"><code>httpd.h</code></a> header 
    file or at <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/structrequest__rec.html">http://ci.apache.org/projects/httpd/trunk/doxygen/structrequest__rec.html</a>.
    </p>
    
    
    <p>
    Let's try out some of these variables in another example handler:<br />
    </p>
    
    
    <pre class="prettyprint lang-c">static int example_handler(request_rec *r)
    {
        /* Set the appropriate content type */
        ap_set_content_type(r, "text/html");
    
        /* Print out the IP address of the client connecting to us: */
        ap_rprintf(r, "&lt;h2&gt;Hello, %s!&lt;/h2&gt;", r-&gt;useragent_ip);
        
        /* If we were reached through a GET or a POST request, be happy, else sad. */
        if ( !strcmp(r-&gt;method, "POST") || !strcmp(r-&gt;method, "GET") ) {
            ap_rputs("You used a GET or a POST method, that makes us happy!&lt;br/&gt;", r);
        }
        else {
            ap_rputs("You did not use POST or GET, that makes us sad :(&lt;br/&gt;", r);
        }
    
        /* Lastly, if there was a query string, let's print that too! */
        if (r-&gt;args) {
            ap_rprintf(r, "Your query string was: %s", r-&gt;args);
        }
        return OK;
    }</pre>
    
    
    
    
    
    <h3><a name="return_value" id="return_value">Return values</a></h3>
    <p>
    Apache relies on return values from handlers to signify whether a request 
    was handled or not, and if so, whether the request went well or not. If a 
    module is not interested in handling a specific request, it should always 
    return the value <code>DECLINED</code>. If it is handling a request, it 
    should either return the generic value <code>OK</code>, or a specific HTTP 
    status code, for example:
    </p>
    
    
    <pre class="prettyprint lang-c">static int example_handler(request_rec *r)
    {
        /* Return 404: Not found */
        return HTTP_NOT_FOUND;
    }</pre>
    
    
    
    <p>
    Returning <code>OK</code> or a HTTP status code does not necessarily mean 
    that the request will end. The server may still have other handlers that are 
    interested in this request, for instance the logging modules which, upon a 
    successful request, will write down a summary of what was requested and how 
    it went. To do a full stop and prevent any further processing after your 
    module is done, you can return the value <code>DONE</code> to let the server 
    know that it should cease all activity on this request and carry on with 
    the next, without informing other handlers.
    <br />
    <strong>General response codes:</strong>
    </p>
    <ul>
    <li><code>DECLINED</code>: We are not handling this request</li>
    <li><code>OK</code>: We handled this request and it went well</li>
    <li><code>DONE</code>: We handled this request and the server should just close this thread without further processing</li>
    </ul>
    <p>
    <strong>HTTP specific return codes (excerpt):</strong>
    </p>
    <ul>
    <li><code>HTTP_OK (200)</code>: Request was okay</li>
    <li><code>HTTP_MOVED_PERMANENTLY (301)</code>: The resource has moved to a new URL</li>
    <li><code>HTTP_UNAUTHORIZED (401)</code>: Client is not authorized to visit this page</li>
    <li><code>HTTP_FORBIDDEN (403)</code>: Permission denied</li>
    <li><code>HTTP_NOT_FOUND (404)</code>: File not found</li>
    <li><code>HTTP_INTERNAL_SERVER_ERROR (500)</code>: Internal server error (self explanatory)</li>
    </ul>
    
    
    <h3><a name="functions" id="functions">Some useful functions you should know</a></h3>
    
    <ul>
    <li>
        <code>ap_rputs(const char *string, request_rec *r)</code>: <br />
        Sends a string of text to the client. This is a shorthand version of <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gac827cd0537d2b6213a7c06d7c26cc36e">
        ap_rwrite</a>.
        
    
    
    <pre class="prettyprint lang-c">ap_rputs("Hello, world!", r);</pre>
    
    
    
    
    </li>
    <li>
        <code>
        <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a></code>: <br />
        This function works just like <code>printf</code>, except it sends the result to the client. 
        
    
    
    <pre class="prettyprint lang-c">ap_rprintf(r, "Hello, %s!", r-&gt;useragent_ip);</pre>
    
    
    
    </li>
    <li>
        <code>
        <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gaa2f8412c400197338ec509f4a45e4579">ap_set_content_type</a>(request_rec *r, const char *type)</code>: <br />
        Sets the content type of the output you are sending.
        
    
    
    <pre class="prettyprint lang-c">ap_set_content_type(r, "text/plain"); /* force a raw text output */</pre>
    
    
    
    </li>
    
    
    </ul>
    
    
    <h3><a name="memory" id="memory">Memory management</a></h3>
    <p>
    Managing your resources in Apache HTTP Server 2.4 is quite easy, thanks to the memory pool 
    system. In essence, each server, connection and request have their own 
    memory pool that gets cleaned up when its scope ends, e.g. when a request 
    is done or when a server process shuts down. All your module needs to do is 
    latch onto this memory pool, and you won't have to worry about having to 
    clean up after yourself - pretty neat, huh?
    </p>
    
    <p>
    In our module, we will primarily be allocating memory for each request, so 
    it's appropriate to use the <code>r-&gt;pool</code> 
    reference when creating new objects. A few of the functions for allocating 
    memory within a pool are:
    </p>
    <ul>
    <li><code>void* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__pools.html#ga85f1e193c31d109affda72f9a92c6915">apr_palloc</a>(
    apr_pool_t *p, apr_size_t size)</code>: Allocates <code>size</code> number of bytes in the pool for you</li>
    <li><code>void* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__pools.html#gaf61c098ad258069d64cdf8c0a9369f9e">apr_pcalloc</a>(
    apr_pool_t *p, apr_size_t size)</code>: Allocates <code>size</code> number of bytes in the pool for you and sets all bytes to 0</li>
    <li><code>char* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__strings.html#gabc79e99ff19abbd7cfd18308c5f85d47">apr_pstrdup</a>(
    apr_pool_t *p, const char *s)</code>: Creates a duplicate of the string <code>s</code>. This is useful for copying constant values so you can edit them</li>
    <li><code>char* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__strings.html#ga3eca76b8d293c5c3f8021e45eda813d8">apr_psprintf</a>(
    apr_pool_t *p, const char *fmt, ...)</code>: Similar to <code>sprintf</code>, except the server supplies you with an appropriately allocated target variable</li>
    </ul>
    
    <p>Let's put these functions into an example handler:</p>
    
    
    
    <pre class="prettyprint lang-c">static int example_handler(request_rec *r)
    {
        const char *original = "You can't edit this!";
        char *copy;
        int *integers;
        
        /* Allocate space for 10 integer values and set them all to zero. */
        integers = apr_pcalloc(r-&gt;pool, sizeof(int)*10); 
        
        /* Create a copy of the 'original' variable that we can edit. */
        copy = apr_pstrdup(r-&gt;pool, original);
        return OK;
    }</pre>
    
    
    
    <p>
    This is all well and good for our module, which won't need any 
    pre-initialized variables or structures. However, if we wanted to 
    initialize something early on, before the requests come rolling in, we 
    could simply add a call to a function in our <code>register_hooks</code> 
    function to sort it out:
    </p>
    
    
    <pre class="prettyprint lang-c">static void register_hooks(apr_pool_t *pool)
    {
        /* Call a function that initializes some stuff */
        example_init_function(pool);
        /* Create a hook in the request handler, so we get called when a request arrives */
        ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
    }</pre>
    
    
    
    <p>
    In this pre-request initialization function we would not be using the 
    same pool as we did when allocating resources for request-based functions. 
    Instead, we would use the pool given to us by the server for allocating memory 
    on a per-process based level.
    </p>
    
    
    <h3><a name="parsing" id="parsing">Parsing request data</a></h3>
    <p>
    In our example module, we would like to add a feature, that checks which 
    type of digest, MD5 or SHA1 the client would like to see. This could be 
    solved by adding a query string to the request. A query string is typically 
    comprised of several keys and values put together in a string, for instance 
    <code>valueA=yes&amp;valueB=no&amp;valueC=maybe</code>. It is up to the 
    module itself to parse these and get the data it requires. In our example, 
    we'll be looking for a key called <code>digest</code>, and if set to <code>
    md5</code>, we'll produce an MD5 digest, otherwise we'll produce a SHA1 
    digest.
    </p>
    <p>
    Since the introduction of Apache HTTP Server 2.4, parsing request data from GET and 
    POST requests have never been easier. All we require to parse both GET and 
    POST data is four simple lines:
    </p> 
    
    
    
    <pre class="prettyprint lang-c">
    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__apr__tables.html#gad7ea82d6608a4a633fc3775694ab71e4">apr_table_t</a> *GET; <em>
    </em><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/structapr__array__header__t.html">apr_array_header_t</a>*POST; 
    <em>
    </em>
    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__SCRIPT.html#gaed25877b529623a4d8f99f819ba1b7bd">
    ap_args_to_table</a>(r, &amp;GET); <em>
    </em><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__DAEMON.html#ga9d426b6382b49754d4f87c55f65af202">
    ap_parse_form_data</a>(r, NULL, &amp;POST, -1, 8192);</pre>
    
    
    
    <p>
    In our specific example module, we're looking for the <code>digest</code> 
    value from the query string, which now resides inside a table called <code>
    GET</code>. To extract this value, we need only perform a simple operation:
    </p>
    
    
    
    <pre class="prettyprint lang-c">/* Get the "digest" key from the query string, if any. */
    const char *digestType = apr_table_get(GET, "digest");
    
    /* If no key was returned, we will set a default value instead. */
    if (!digestType) digestType = "sha1";</pre>
    
    
    
    <p>
    The structures used for the POST and GET data are not exactly the same, so 
    if we were to fetch a value from POST data instead of the query string, we 
    would have to resort to a few more lines, as outlined in <a href="#get_post">this example</a> in the last chapter of this document.
    </p>
    
    
    <h3><a name="advanced_handler" id="advanced_handler">Making an advanced handler</a></h3>
    <p>
    Now that we have learned how to parse form data and manage our resources, 
    we can move on to creating an advanced version of our module, that spits 
    out the MD5 or SHA1 digest of files:
    </p>
    
    
    
    <pre class="prettyprint lang-c">static int example_handler(request_rec *r)
    {
        int rc, exists;
        apr_finfo_t finfo;
        apr_file_t *file;
        char *filename;
        char buffer[256];
        apr_size_t readBytes;
        int n;
        apr_table_t *GET;
        apr_array_header_t *POST;
        const char *digestType;
        
        
        /* Check that the "example-handler" handler is being called. */
        if (!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return (DECLINED);
        
        /* Figure out which file is being requested by removing the .sum from it */
        filename = apr_pstrdup(r-&gt;pool, r-&gt;filename);
        filename[strlen(filename)-4] = 0; /* Cut off the last 4 characters. */
        
        /* Figure out if the file we request a sum on exists and isn't a directory */
        rc = apr_stat(&amp;finfo, filename, APR_FINFO_MIN, r-&gt;pool);
        if (rc == APR_SUCCESS) {
            exists =
            (
                (finfo.filetype != APR_NOFILE)
            &amp;&amp;  !(finfo.filetype &amp; APR_DIR)
            );
            if (!exists) return HTTP_NOT_FOUND; /* Return a 404 if not found. */
        }
        /* If apr_stat failed, we're probably not allowed to check this file. */
        else return HTTP_FORBIDDEN;
        
        /* Parse the GET and, optionally, the POST data sent to us */
        
        ap_args_to_table(r, &amp;GET);
        ap_parse_form_data(r, NULL, &amp;POST, -1, 8192);
        
        /* Set the appropriate content type */
        ap_set_content_type(r, "text/html");
        
        /* Print a title and some general information */
        ap_rprintf(r, "&lt;h2&gt;Information on %s:&lt;/h2&gt;", filename);
        ap_rprintf(r, "&lt;b&gt;Size:&lt;/b&gt; %u bytes&lt;br/&gt;", finfo.size);
        
        /* Get the digest type the client wants to see */
        digestType = apr_table_get(GET, "digest");
        if (!digestType) digestType = "MD5";
        
        
        rc = apr_file_open(&amp;file, filename, APR_READ, APR_OS_DEFAULT, r-&gt;pool);
        if (rc == APR_SUCCESS) {
            
            /* Are we trying to calculate the MD5 or the SHA1 digest? */
            if (!strcasecmp(digestType, "md5")) {
                /* Calculate the MD5 sum of the file */
                union {
                    char      chr[16];
                    uint32_t  num[4];
                } digest;
                apr_md5_ctx_t md5;
                apr_md5_init(&amp;md5);
                readBytes = 256;
                while ( apr_file_read(file, buffer, &amp;readBytes) == APR_SUCCESS ) {
                    apr_md5_update(&amp;md5, buffer, readBytes);
                }
                apr_md5_final(digest.chr, &amp;md5);
                
                /* Print out the MD5 digest */
                ap_rputs("&lt;b&gt;MD5: &lt;/b&gt;&lt;code&gt;", r);
                for (n = 0; n &lt; APR_MD5_DIGESTSIZE/4; n++) {
                    ap_rprintf(r, "%08x", digest.num[n]);
                }
                ap_rputs("&lt;/code&gt;", r);
                /* Print a link to the SHA1 version */
                ap_rputs("&lt;br/&gt;&lt;a href='?digest=sha1'&gt;View the SHA1 hash instead&lt;/a&gt;", r);
            }
            else {
                /* Calculate the SHA1 sum of the file */
                union {
                    char      chr[20];
                    uint32_t  num[5];
                } digest;
                apr_sha1_ctx_t sha1;
                apr_sha1_init(&amp;sha1);
                readBytes = 256;
                while ( apr_file_read(file, buffer, &amp;readBytes) == APR_SUCCESS ) {
                    apr_sha1_update(&amp;sha1, buffer, readBytes);
                }
                apr_sha1_final(digest.chr, &amp;sha1);
                
                /* Print out the SHA1 digest */
                ap_rputs("&lt;b&gt;SHA1: &lt;/b&gt;&lt;code&gt;", r);
                for (n = 0; n &lt; APR_SHA1_DIGESTSIZE/4; n++) {
                    ap_rprintf(r, "%08x", digest.num[n]);
                }
                ap_rputs("&lt;/code&gt;", r);
                
                /* Print a link to the MD5 version */
                ap_rputs("&lt;br/&gt;&lt;a href='?digest=md5'&gt;View the MD5 hash instead&lt;/a&gt;", r);
            }
            apr_file_close(file);
            
        }    
        /* Let the server know that we responded to this request. */
        return OK;
    }</pre>
    
    
    
    <p>
    This version in its entirety can be found here: 
    <a href="http://people.apache.org/~humbedooh/mods/examples/mod_example_2.c">mod_example_2.c</a>.
    </p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Adding configuration options</a></h2>
    <p>
    In this next segment of this document, we will turn our eyes away from the 
    digest module and create a new example module, whose only function is to 
    write out its own configuration. The purpose of this is to examine how 
    the server works with configuration, and what happens when you start writing 
    advanced configurations 
    for your modules.
    </p>
    <h3><a name="config_intro" id="config_intro">An introduction to configuration 
    directives</a></h3>
    <p>
    If you are reading this, then you probably already know 
    what a configuration directive is. Simply put, a directive is a way of 
    telling an individual module (or a set of modules) how to behave, such as 
    these directives control how <code>mod_rewrite</code> works:
    </p>
    <pre class="prettyprint lang-config">RewriteEngine On
    RewriteCond "%{REQUEST_URI}" "^/foo/bar"
    RewriteRule "^/foo/bar/(.*)$" "/foobar?page=$1"</pre>
    
    <p>
    Each of these configuration directives are handled by a separate function, 
    that parses the parameters given and sets up a configuration accordingly.
    </p>
    
    <h3><a name="config_simple" id="config_simple">Making an example configuration</a></h3>
    <p>To begin with, we'll create a basic configuration in C-space:</p>
    
    
    
    <pre class="prettyprint lang-c">typedef struct {
        int         enabled;      /* Enable or disable our module */
        const char *path;         /* Some path to...something */
        int         typeOfAction; /* 1 means action A, 2 means action B and so on */
    } example_config;</pre>
    
    
    
    <p>
    Now, let's put this into perspective by creating a very small module that 
    just prints out a hard-coded configuration. You'll notice that we use the 
    <code>register_hooks</code> function for initializing the configuration 
    values to their defaults:
    </p>
    
    
    <pre class="prettyprint lang-c">typedef struct {
        int         enabled;      /* Enable or disable our module */
        const char *path;         /* Some path to...something */
        int         typeOfAction; /* 1 means action A, 2 means action B and so on */
    } example_config;
    
    static example_config config;
    
    static int example_handler(request_rec *r)
    {
        if (!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
        ap_set_content_type(r, "text/plain");
        ap_rprintf(r, "Enabled: %u\n", config.enabled);
        ap_rprintf(r, "Path: %s\n", config.path);
        ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
        return OK;
    }
    
    static void register_hooks(apr_pool_t *pool) 
    {
        config.enabled = 1;
        config.path = "/foo/bar";
        config.typeOfAction = 0x00;
        ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
    }
    
    /* Define our module as an entity and assign a function for registering hooks  */
    
    module AP_MODULE_DECLARE_DATA   example_module =
    {
        STANDARD20_MODULE_STUFF,
        NULL,            /* Per-directory configuration handler */
        NULL,            /* Merge handler for per-directory configurations */
        NULL,            /* Per-server configuration handler */
        NULL,            /* Merge handler for per-server configurations */
        NULL,            /* Any directives we may have for httpd */
        register_hooks   /* Our hook registering function */
    };</pre>
    
    
    
    <p>
    So far so good. To access our new handler, we could add the following to 
    our configuration:
    </p>
    <pre class="prettyprint lang-config">&lt;Location "/example"&gt;
        SetHandler example-handler
    &lt;/Location&gt;</pre>
    
    <p>
    When we visit, we'll see our current configuration being spit out by our 
    module. 
    </p>
    
    
    <h3><a name="register_directive" id="register_directive">Registering directives with the server</a></h3>
    <p>
    What if we want to change our configuration, not by hard-coding new values 
    into the module, but by using either the httpd.conf file or possibly a 
    .htaccess file? It's time to let the server know that we want this to be 
    possible. To do so, we must first change our <em>name tag</em> to include a 
    reference to the configuration directives we want to register with the server:
    </p>
    
    
    <pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
    {
        STANDARD20_MODULE_STUFF,
        NULL,               /* Per-directory configuration handler */
        NULL,               /* Merge handler for per-directory configurations */
        NULL,               /* Per-server configuration handler */
        NULL,               /* Merge handler for per-server configurations */
        example_directives, /* Any directives we may have for httpd */
        register_hooks      /* Our hook registering function */
    };</pre>
    
    
    
    <p>
    This will tell the server that we are now accepting directives from the 
    configuration files, and that the structure called <code>example_directives
    </code> holds information on what our directives are and how they work. 
    Since we have three different variables in our module configuration, we 
    will add a structure with three directives and a NULL at the end:
    </p>
    
    
    <pre class="prettyprint lang-c">static const command_rec        example_directives[] =
    {
        AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
        AP_INIT_TAKE1("examplePath", example_set_path, NULL, RSRC_CONF, "The path to whatever"),
        AP_INIT_TAKE2("exampleAction", example_set_action, NULL, RSRC_CONF, "Special action value!"),
        { NULL }
    };</pre>
    
    
    
    <p>
    <img src="../images/build_a_mod_4.png" alt="Directives structure" /><br />
    As you can see, each directive needs at least 5 parameters set:
    </p>
    <ol>
    <li><code><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#ga07c7d22ae17805e61204463326cf9c34">AP_INIT_TAKE1</a></code>: This is a macro that tells the server that this directive takes one and only one argument. 
    If we required two arguments, we could use the macro <code><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#gafaec43534fcf200f37d9fecbf9247c21">AP_INIT_TAKE2</a></code> and so on (refer to httpd_conf.h 
    for more macros).</li>
    <li><code>exampleEnabled</code>: This is the name of our directive. More precisely, it is what the user must put in his/her 
    configuration in order to invoke a configuration change in our module.</li>
    <li><code>example_set_enabled</code>: This is a reference to a C function that parses the directive and sets the configuration 
    accordingly. We will discuss how to make this in the following paragraph.</li>
    <li><code>RSRC_CONF</code>: This tells the server where the directive is permitted. We'll go into details on this value in the 
    later chapters, but for now, <code>RSRC_CONF</code> means that the server will only accept these directives in a server context.</li>
    <li><code>"Enable or disable...."</code>: This is simply a brief description of what the directive does.</li>
    </ol>
    <p>
    (<em>The "missing" parameter in our definition, which is usually set to 
    <code>NULL</code>, is an optional function that can be run after the 
    initial function to parse the arguments have been run. This is usually 
    omitted, as the function for verifying arguments might as well be used to 
    set them.</em>)
    </p>
    
    <h3><a name="directive_handler" id="directive_handler">The directive handler function</a></h3>
    <p>
    Now that we have told the server to expect some directives for our module, it's 
    time to make a few functions for handling these. What the server reads in the 
    configuration file(s) is text, and so naturally, what it passes along to 
    our directive handler is one or more strings, that we ourselves need to 
    recognize and act upon. You'll notice, that since we set our <code>
    exampleAction</code> directive to accept two arguments, its C function also 
    has an additional parameter defined:</p> 
    
    
    <pre class="prettyprint lang-c">/* Handler for the "exampleEnabled" directive */
    const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
    {
        if(!strcasecmp(arg, "on")) config.enabled = 1;
        else config.enabled = 0;
        return NULL;
    }
    
    /* Handler for the "examplePath" directive */
    const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
    {
        config.path = arg;
        return NULL;
    }
    
    /* Handler for the "exampleAction" directive */
    /* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */
    /* and we store it in a bit-wise manner. */
    const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2)
    {
        if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
        else config.typeOfAction = 0x02;
        
        if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
        else config.typeOfAction += 0x20;
        return NULL;
    }</pre>
    
    
    
    
    
    <h3><a name="directive_complete" id="directive_complete">Putting it all together</a></h3>
    <p>
    Now that we have our directives set up, and handlers configured for them, 
    we can assemble our module into one big file:
    </p>
    
    
    <pre class="prettyprint lang-c">/* mod_example_config_simple.c: */
    #include &lt;stdio.h&gt;
    #include "apr_hash.h"
    #include "ap_config.h"
    #include "ap_provider.h"
    #include "httpd.h"
    #include "http_core.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_request.h"
    
    /*
     ==============================================================================
     Our configuration prototype and declaration:
     ==============================================================================
     */
    typedef struct {
        int         enabled;      /* Enable or disable our module */
        const char *path;         /* Some path to...something */
        int         typeOfAction; /* 1 means action A, 2 means action B and so on */
    } example_config;
    
    static example_config config;
    
    /*
     ==============================================================================
     Our directive handlers:
     ==============================================================================
     */
    /* Handler for the "exampleEnabled" directive */
    const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
    {
        if(!strcasecmp(arg, "on")) config.enabled = 1;
        else config.enabled = 0;
        return NULL;
    }
    
    /* Handler for the "examplePath" directive */
    const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
    {
        config.path = arg;
        return NULL;
    }
    
    /* Handler for the "exampleAction" directive */
    /* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */
    /* and we store it in a bit-wise manner. */
    const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2)
    {
        if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
        else config.typeOfAction = 0x02;
        
        if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
        else config.typeOfAction += 0x20;
        return NULL;
    }
    
    /*
     ==============================================================================
     The directive structure for our name tag:
     ==============================================================================
     */
    static const command_rec        example_directives[] =
    {
        AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
        AP_INIT_TAKE1("examplePath", example_set_path, NULL, RSRC_CONF, "The path to whatever"),
        AP_INIT_TAKE2("exampleAction", example_set_action, NULL, RSRC_CONF, "Special action value!"),
        { NULL }
    };
    /*
     ==============================================================================
     Our module handler:
     ==============================================================================
     */
    static int example_handler(request_rec *r)
    {
        if(!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
        ap_set_content_type(r, "text/plain");
        ap_rprintf(r, "Enabled: %u\n", config.enabled);
        ap_rprintf(r, "Path: %s\n", config.path);
        ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
        return OK;
    }
    
    /*
     ==============================================================================
     The hook registration function (also initializes the default config values):
     ==============================================================================
     */
    static void register_hooks(apr_pool_t *pool) 
    {
        config.enabled = 1;
        config.path = "/foo/bar";
        config.typeOfAction = 3;
        ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
    }
    /*
     ==============================================================================
     Our module name tag:
     ==============================================================================
     */
    module AP_MODULE_DECLARE_DATA   example_module =
    {
        STANDARD20_MODULE_STUFF,
        NULL,               /* Per-directory configuration handler */
        NULL,               /* Merge handler for per-directory configurations */
        NULL,               /* Per-server configuration handler */
        NULL,               /* Merge handler for per-server configurations */
        example_directives, /* Any directives we may have for httpd */
        register_hooks      /* Our hook registering function */
    };</pre>
    
    
    
    
    <p>
    In our httpd.conf file, we can now change the hard-coded configuration by 
    adding a few lines:
    </p>
    <pre class="prettyprint lang-config">ExampleEnabled On
    ExamplePath "/usr/bin/foo"
    ExampleAction file allow</pre>
    
    <p>
    And thus we apply the configuration, visit <code>/example</code> on our 
    web site, and we see the configuration has adapted to what we wrote in our 
    configuration file.
    </p>
    
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="context" id="context">Context aware configurations</a></h2>
    <h3><a name="context_intro" id="context_intro">Introduction to context aware configurations</a></h3>
    <p>
    In Apache HTTP Server 2.4, different URLs, virtual hosts, directories etc can have very 
    different meanings to the user of the server, and thus different contexts 
    within which modules must operate. For example, let's assume you have this 
    configuration set up for mod_rewrite:
    </p>
    <pre class="prettyprint lang-config">&lt;Directory "/var/www"&gt;
        RewriteCond "%{HTTP_HOST}" "^example.com$"
        RewriteRule "(.*)" "http://www.example.com/$1"
    &lt;/Directory&gt;
    &lt;Directory "/var/www/sub"&gt;
        RewriteRule "^foobar$" "index.php?foobar=true"
    &lt;/Directory&gt;</pre>
    
    <p>
    In this example, you will have set up two different contexts for 
    mod_rewrite:</p>
    <ol>
    <li>Inside <code>/var/www</code>, all requests for <code>http://example.com</code> must go to <code>http://www.example.com</code></li>
    <li>Inside <code>/var/www/sub</code>, all requests for <code>foobar</code> must go to <code>index.php?foobar=true</code></li>
    </ol>
    <p>
    If mod_rewrite (or the entire server for that matter) wasn't context aware, then 
    these rewrite rules would just apply to every and any request made, 
    regardless of where and how they were made, but since the module can pull 
    the context specific configuration straight from the server, it does not need 
    to know itself, which of the directives are valid in this context, since 
    the server takes care of this.</p>
    
    <p>
    So how does a module get the specific configuration for the server, 
    directory or location in question? It does so by making one simple call:
    </p>
    
    
    <pre class="prettyprint lang-c">example_config *config = (example_config*) <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#ga1093a5908a384eacc929b028c79f2a02">ap_get_module_config</a>(r-&gt;per_dir_config, &amp;example_module);</pre>
    
    
    
    <p>
    That's it! Of course, a whole lot goes on behind the scenes, which we will 
    discuss in this chapter, starting with how the server came to know what our 
    configuration looks like, and how it came to be set up as it is in the 
    specific context.
    </p>
    
    
    <h3><a name="context_base" id="context_base">Our basic configuration setup</a></h3>
    <p>In this chapter, we will be working with a slightly modified version of 
    our previous context structure. We will set a <code>context</code> 
    variable that we can use to track which context configuration is being 
    used by the server in various places:
    </p>
    
    <pre class="prettyprint lang-c">typedef struct {
        char        context[256];
        char        path[256];
        int         typeOfAction;
        int         enabled;
    } example_config;</pre>
    
    
    
    <p>Our handler for requests will also be modified, yet still very simple:</p>
    
    
    
    <pre class="prettyprint lang-c">static int example_handler(request_rec *r)
    {
        if(!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
        example_config *config = (example_config*) ap_get_module_config(r-&gt;per_dir_config, &amp;example_module);
        ap_set_content_type(r, "text/plain");
        ap_rprintf("Enabled: %u\n", config-&gt;enabled);
        ap_rprintf("Path: %s\n", config-&gt;path);
        ap_rprintf("TypeOfAction: %x\n", config-&gt;typeOfAction);
        ap_rprintf("Context: %s\n", config-&gt;context);
        return OK;
    }</pre>
    
    
    
    
    
    <h3><a name="context_which" id="context_which">Choosing a context</a></h3>
    <p>
    Before we can start making our module context aware, we must first define, 
    which contexts we will accept. As we saw in the previous chapter, defining 
    a directive required five elements be set:</p>
    
    
    
    <pre class="prettyprint lang-c">AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),</pre>
    
    
    
    
    <p>The <code>RSRC_CONF</code> definition told the server that we would only allow 
    this directive in a global server context, but since we are now trying out 
    a context aware version of our module, we should set this to something 
    more lenient, namely the value <code>ACCESS_CONF</code>, which lets us use 
    the directive inside &lt;Directory&gt; and &lt;Location&gt; blocks. For more 
    control over the placement of your directives, you can combine the following 
    restrictions together to form a specific rule:
    </p>
    <ul>
    <li><code>RSRC_CONF</code>: Allow in .conf files (not .htaccess) outside &lt;Directory&gt; or &lt;Location&gt;</li>
    <li><code>ACCESS_CONF</code>: Allow in .conf files (not .htaccess) inside &lt;Directory&gt; or &lt;Location&gt;</li>
    <li><code>OR_OPTIONS</code>: Allow in .conf files and .htaccess when <code>AllowOverride Options</code> is set</li>
    <li><code>OR_FILEINFO</code>: Allow in .conf files and .htaccess when <code>AllowOverride FileInfo</code> is set</li>
    <li><code>OR_AUTHCFG</code>: Allow in .conf files and .htaccess when <code>AllowOverride AuthConfig</code> is set</li>
    <li><code>OR_INDEXES</code>: Allow in .conf files and .htaccess when <code>AllowOverride Indexes</code> is set</li>
    <li><code>OR_ALL</code>: Allow anywhere in .conf files and .htaccess</li>
    </ul>
    
    
    <h3><a name="context_pool" id="context_pool">Using the server to allocate configuration slots</a></h3>
    <p> A much smarter way to manage your configurations is by letting the server 
    help you create them. To do so, we must first start off by changing our 
    <em>name tag</em> to let the server know, that it should assist us in creating 
    and managing our configurations. Since we have chosen the per-directory 
    (or per-location) context for our module configurations, we'll add a 
    per-directory creator and merger function reference in our tag:</p>
    
    
    <pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
    {
        STANDARD20_MODULE_STUFF,
        create_dir_conf, /* Per-directory configuration handler */
        merge_dir_conf,  /* Merge handler for per-directory configurations */
        NULL,            /* Per-server configuration handler */
        NULL,            /* Merge handler for per-server configurations */
        directives,      /* Any directives we may have for httpd */
        register_hooks   /* Our hook registering function */
    };</pre>
    
    
    
    
    
    
    
    <h3><a name="context_new" id="context_new">Creating new context configurations</a></h3>
    <p>
    Now that we have told the server to help us create and manage configurations, 
    our first step is to make a function for creating new, blank 
    configurations. We do so by creating the function we just referenced in 
    our name tag as the Per-directory configuration handler:</p>
    
    <pre class="prettyprint lang-c">void *create_dir_conf(apr_pool_t *pool, char *context) {
        context = context ? context : "(undefined context)";
        example_config *cfg = apr_pcalloc(pool, sizeof(example_config));
        if(cfg) {
            /* Set some default values */
            strcpy(cfg-&gt;context, context);
            cfg-&gt;enabled = 0;
            cfg-&gt;path = "/foo/bar";
            cfg-&gt;typeOfAction = 0x11;
        }
        return cfg;
    }</pre>
    
    
    
    
    
    
    <h3><a name="context_merge" id="context_merge">Merging configurations</a></h3>
    <p>
    Our next step in creating a context aware configuration is merging 
    configurations. This part of the process particularly applies to scenarios 
    where you have a parent configuration and a child, such as the following: 
    </p>
    <pre class="prettyprint lang-config">&lt;Directory "/var/www"&gt;
        ExampleEnabled On
        ExamplePath "/foo/bar"
        ExampleAction file allow
    &lt;/Directory&gt;
    &lt;Directory "/var/www/subdir"&gt;
        ExampleAction file deny
    &lt;/Directory&gt;</pre>
    
    <p>
    In this example, it is natural to assume that the directory <code>
    /var/www/subdir</code> should inherit the values set for the <code>/var/www
    </code> directory, as we did not specify an <code>ExampleEnabled</code> nor 
    an <code>ExamplePath</code> for this directory. The server does not presume to 
    know if this is true, but cleverly does the following:
    </p>
    <ol>
    <li>Creates a new configuration for <code>/var/www</code></li>
    <li>Sets the configuration values according to the directives given for <code>/var/www</code></li>
    <li>Creates a new configuration for <code>/var/www/subdir</code></li>
    <li>Sets the configuration values according to the directives given for <code>/var/www/subdir</code></li>
    <li><strong>Proposes a merge</strong> of the two configurations into a new configuration for <code>/var/www/subdir</code></li>
    </ol>
    <p>
    This proposal is handled by the <code>merge_dir_conf</code> function we 
    referenced in our name tag. The purpose of this function is to assess the 
    two configurations and decide how they are to be merged:</p>
    
    
    
    <pre class="prettyprint lang-c">void *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD) {
        example_config *base = (example_config *) BASE ; /* This is what was set in the parent context */
        example_config *add = (example_config *) ADD ;   /* This is what is set in the new context */
        example_config *conf = (example_config *) create_dir_conf(pool, "Merged configuration"); /* This will be the merged configuration */
        
        /* Merge configurations */
        conf-&gt;enabled = ( add-&gt;enabled == 0 ) ? base-&gt;enabled : add-&gt;enabled ;
        conf-&gt;typeOfAction = add-&gt;typeOfAction ? add-&gt;typeOfAction : base-&gt;typeOfAction;
        strcpy(conf-&gt;path, strlen(add-&gt;path) ? add-&gt;path : base-&gt;path);
        
        return conf ;
    }</pre>
    
    
    
    
    
    
    <h3><a name="context_example" id="context_example">Trying out our new context aware configurations</a></h3>
    <p>
    Now, let's try putting it all together to create a new module that is 
    context aware. First off, we'll create a configuration that lets us test 
    how the module works:
    </p>
    <pre class="prettyprint lang-config">&lt;Location "/a"&gt;
        SetHandler example-handler
        ExampleEnabled on
        ExamplePath "/foo/bar"
        ExampleAction file allow
    &lt;/Location&gt;
    
    &lt;Location "/a/b"&gt;
        ExampleAction file deny
        ExampleEnabled off
    &lt;/Location&gt;
    
    &lt;Location "/a/b/c"&gt;
        ExampleAction db deny
        ExamplePath "/foo/bar/baz"
        ExampleEnabled on
    &lt;/Location&gt;</pre>
    
    <p>
    Then we'll assemble our module code. Note, that since we are now using our 
    name tag as reference when fetching configurations in our handler, I have 
    added some prototypes to keep the compiler happy:
    </p>
    
    
    <pre class="prettyprint lang-c">/*$6
     +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     * mod_example_config.c
     +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */
    
    
    #include &lt;stdio.h&gt;
    #include "apr_hash.h"
    #include "ap_config.h"
    #include "ap_provider.h"
    #include "httpd.h"
    #include "http_core.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_request.h"
    
    /*$1
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Configuration structure
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */
    
    typedef struct
    {
        char    context[256];
        char    path[256];
        int     typeOfAction;
        int     enabled;
    } example_config;
    
    /*$1
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Prototypes
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */
    
    static int    example_handler(request_rec *r);
    const char    *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg);
    const char    *example_set_path(cmd_parms *cmd, void *cfg, const char *arg);
    const char    *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2);
    void          *create_dir_conf(apr_pool_t *pool, char *context);
    void          *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD);
    static void   register_hooks(apr_pool_t *pool);
    
    /*$1
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Configuration directives
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */
    
    static const command_rec    directives[] =
    {
        AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, ACCESS_CONF, "Enable or disable mod_example"),
        AP_INIT_TAKE1("examplePath", example_set_path, NULL, ACCESS_CONF, "The path to whatever"),
        AP_INIT_TAKE2("exampleAction", example_set_action, NULL, ACCESS_CONF, "Special action value!"),
        { NULL }
    };
    
    /*$1
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Our name tag
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */
    
    module AP_MODULE_DECLARE_DATA    example_module =
    {
        STANDARD20_MODULE_STUFF,
        create_dir_conf,    /* Per-directory configuration handler */
        merge_dir_conf,     /* Merge handler for per-directory configurations */
        NULL,               /* Per-server configuration handler */
        NULL,               /* Merge handler for per-server configurations */
        directives,         /* Any directives we may have for httpd */
        register_hooks      /* Our hook registering function */
    };
    
    /*
     =======================================================================================================================
        Hook registration function
     =======================================================================================================================
     */
    static void register_hooks(apr_pool_t *pool)
    {
        ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
    }
    
    /*
     =======================================================================================================================
        Our example web service handler
     =======================================================================================================================
     */
    static int example_handler(request_rec *r)
    {
        if(!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
    
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        example_config    *config = (example_config *) ap_get_module_config(r-&gt;per_dir_config, &amp;example_module);
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        ap_set_content_type(r, "text/plain");
        ap_rprintf(r, "Enabled: %u\n", config-&gt;enabled);
        ap_rprintf(r, "Path: %s\n", config-&gt;path);
        ap_rprintf(r, "TypeOfAction: %x\n", config-&gt;typeOfAction);
        ap_rprintf(r, "Context: %s\n", config-&gt;context);
        return OK;
    }
    
    /*
     =======================================================================================================================
        Handler for the "exampleEnabled" directive
     =======================================================================================================================
     */
    const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        example_config    *conf = (example_config *) cfg;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        if(conf)
        {
            if(!strcasecmp(arg, "on"))
                conf-&gt;enabled = 1;
            else
                conf-&gt;enabled = 0;
        }
    
        return NULL;
    }
    
    /*
     =======================================================================================================================
        Handler for the "examplePath" directive
     =======================================================================================================================
     */
    const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        example_config    *conf = (example_config *) cfg;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        if(conf)
        {
            strcpy(conf-&gt;path, arg);
        }
    
        return NULL;
    }
    
    /*
     =======================================================================================================================
        Handler for the "exampleAction" directive ;
        Let's pretend this one takes one argument (file or db), and a second (deny or allow), ;
        and we store it in a bit-wise manner.
     =======================================================================================================================
     */
    const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        example_config    *conf = (example_config *) cfg;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        if(conf)
        {
            {
                if(!strcasecmp(arg1, "file"))
                    conf-&gt;typeOfAction = 0x01;
                else
                    conf-&gt;typeOfAction = 0x02;
                if(!strcasecmp(arg2, "deny"))
                    conf-&gt;typeOfAction += 0x10;
                else
                    conf-&gt;typeOfAction += 0x20;
            }
        }
    
        return NULL;
    }
    
    /*
     =======================================================================================================================
        Function for creating new configurations for per-directory contexts
     =======================================================================================================================
     */
    void *create_dir_conf(apr_pool_t *pool, char *context)
    {
        context = context ? context : "Newly created configuration";
    
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        example_config    *cfg = apr_pcalloc(pool, sizeof(example_config));
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        if(cfg)
        {
            {
                /* Set some default values */
                strcpy(cfg-&gt;context, context);
                cfg-&gt;enabled = 0;
                memset(cfg-&gt;path, 0, 256);
                cfg-&gt;typeOfAction = 0x00;
            }
        }
    
        return cfg;
    }
    
    /*
     =======================================================================================================================
        Merging function for configurations
     =======================================================================================================================
     */
    void *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        example_config    *base = (example_config *) BASE;
        example_config    *add = (example_config *) ADD;
        example_config    *conf = (example_config *) create_dir_conf(pool, "Merged configuration");
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        conf-&gt;enabled = (add-&gt;enabled == 0) ? base-&gt;enabled : add-&gt;enabled;
        conf-&gt;typeOfAction = add-&gt;typeOfAction ? add-&gt;typeOfAction : base-&gt;typeOfAction;
        strcpy(conf-&gt;path, strlen(add-&gt;path) ? add-&gt;path : base-&gt;path);
        return conf;
    }</pre>
    
    
    
    
    
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="summary" id="summary">Summing up</a></h2>
    <p>
    We have now looked at how to create simple modules for Apache HTTP Server 2.4 and 
    configuring them. What you do next is entirely up to you, but it is my 
    hope that something valuable has come out of reading this documentation. 
    If you have questions on how to further develop modules, you are welcome 
    to join our <a href="http://httpd.apache.org/lists.html">mailing lists</a> 
    or check out the rest of our documentation for further tips.
    </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="snippets" id="snippets">Some useful snippets of code</a></h2>
    
    <h3><a name="get_post" id="get_post">Retrieve variables from POST form data</a></h3>
    
    
    
    <pre class="prettyprint lang-c">typedef struct {
        const char *key;
        const char *value;
    } keyValuePair;
    
    keyValuePair *readPost(request_rec *r) {
        apr_array_header_t *pairs = NULL;
        apr_off_t len;
        apr_size_t size;
        int res;
        int i = 0;
        char *buffer;
        keyValuePair *kvp;
    
        res = ap_parse_form_data(r, NULL, &amp;pairs, -1, HUGE_STRING_LEN);
        if (res != OK || !pairs) return NULL; /* Return NULL if we failed or if there are is no POST data */
        kvp = apr_pcalloc(r-&gt;pool, sizeof(keyValuePair) * (pairs-&gt;nelts + 1));
        while (pairs &amp;&amp; !apr_is_empty_array(pairs)) {
            ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
            apr_brigade_length(pair-&gt;value, 1, &amp;len);
            size = (apr_size_t) len;
            buffer = apr_palloc(r-&gt;pool, size + 1);
            apr_brigade_flatten(pair-&gt;value, buffer, &amp;size);
            buffer[len] = 0;
            kvp[i].key = apr_pstrdup(r-&gt;pool, pair-&gt;name);
            kvp[i].value = buffer;
            i++;
        }
        return kvp;
    }
    
    static int example_handler(request_rec *r)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~*/
        keyValuePair *formData;
        /*~~~~~~~~~~~~~~~~~~~~~~*/
    
        formData = readPost(r);
        if (formData) {
            int i;
            for (i = 0; &amp;formData[i]; i++) {
                if (formData[i].key &amp;&amp; formData[i].value) {
                    ap_rprintf(r, "%s = %s\n", formData[i].key, formData[i].value);
                } else if (formData[i].key) {
                    ap_rprintf(r, "%s\n", formData[i].key);
                } else if (formData[i].value) {
                    ap_rprintf(r, "= %s\n", formData[i].value);
                } else {
                    break;
                }
            }
        }
        return OK;
    }</pre>
    
    
    
    
        
    
        <h3><a name="headers_out" id="headers_out">Printing out every HTTP header received</a></h3>
    
    
    
    <pre class="prettyprint lang-c">static int example_handler(request_rec *r)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        const apr_array_header_t    *fields;
        int                         i;
        apr_table_entry_t           *e = 0;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        fields = apr_table_elts(r-&gt;headers_in);
        e = (apr_table_entry_t *) fields-&gt;elts;
        for(i = 0; i &lt; fields-&gt;nelts; i++) {
            ap_rprintf(r, "%s: %s\n", e[i].key, e[i].val);
        }
        return OK;
    }</pre>
    
    
    
    
        
    
        <h3><a name="request_body" id="request_body">Reading the request body into memory</a></h3>
    
    
    
    <pre class="prettyprint lang-c">static int util_read(request_rec *r, const char **rbuf, apr_off_t *size)
    {
        /*~~~~~~~~*/
        int rc = OK;
        /*~~~~~~~~*/
    
        if((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
            return(rc);
        }
    
        if(ap_should_client_block(r)) {
    
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            char         argsbuffer[HUGE_STRING_LEN];
            apr_off_t    rsize, len_read, rpos = 0;
            apr_off_t length = r-&gt;remaining;
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
            *rbuf = (const char *) apr_pcalloc(r-&gt;pool, (apr_size_t) (length + 1));
            *size = length;
            while((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) &gt; 0) {
                if((rpos + len_read) &gt; length) {
                    rsize = length - rpos;
                }
                else {
                    rsize = len_read;
                }
    
                memcpy((char *) *rbuf + rpos, argsbuffer, (size_t) rsize);
                rpos += rsize;
            }
        }
        return(rc);
    }
    
    static int example_handler(request_rec *r) 
    {
        /*~~~~~~~~~~~~~~~~*/
        apr_off_t   size;
        const char  *buffer;
        /*~~~~~~~~~~~~~~~~*/
    
        if(util_read(r, &amp;buffer, &amp;size) == OK) {
            ap_rprintf(r, "We read a request body that was %" APR_OFF_T_FMT " bytes long", size);
        }
        return OK;
    }</pre>
    
    
    
    
    
        
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/modguide.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/modguide.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/request.html.en��������������������������������������������������0000664�0001751�0001751�00000036157�14737241666�022027� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Request Processing in the Apache HTTP Server 2.x - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Request Processing in the Apache HTTP Server 2.x</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/request.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <div class="warning"><h3>Warning</h3>
          <p>Warning - this is a first (fast) draft that needs further
          revision!</p>
        </div>
    
        <p>Several changes in 2.0 and above 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.</p>
    
        <p>The first major change is to the subrequest and redirect
        mechanisms. There were a number of different code paths in
        the Apache HTTP Server 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 <code>ap_process_request_internal()</code> to prevent
        the code from falling out of sync again.</p>
    
        <p>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 1.3) without introducing fragile or
        insecure code.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#processing">The Request Processing Cycle</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#parsing">The Request Parsing Phase</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">The Security Phase</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#preparation">The Preparation Phase</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#handler">The Handler Phase</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="processing" id="processing">The Request Processing Cycle</a></h2>
        <p>All requests pass through <code>ap_process_request_internal()</code>
        in <code>server/request.c</code>, 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.</p>
    
        <p>To streamline requests, the module author can take advantage
        of the <a href="./modguide.html#hooking">hooks offered</a> to drop 
        out of the request cycle early, or to bypass core hooks which are 
        irrelevant (and costly in terms of CPU.)</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="parsing" id="parsing">The Request Parsing Phase</a></h2>
        <h3><a name="unescape" id="unescape">Unescapes the URL</a></h3>
          <p>The request's <code>parsed_uri</code> path is unescaped, once and only
          once, at the beginning of internal request processing.</p>
    
          <p>This step is bypassed if the proxyreq flag is set, or the
          <code>parsed_uri.path</code> 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
          repercussions.</p>
        
    
        <h3><a name="strip" id="strip">Strips Parent and This Elements from the
        URI</a></h3>
          <p>All <code>/../</code> and <code>/./</code> elements are
          removed by <code>ap_getparents()</code>, as well as any trailing 
          <code>/.</code> or <code>/..</code> element. This helps to ensure
          the path is (nearly) absolute before the request processing
          continues. (See RFC 1808 section 4 for further discussion.)</p>
    
          <p>This step cannot be bypassed.</p>
        
    
        <h3><a name="inital-location-walk" id="inital-location-walk">Initial URI Location Walk</a></h3>
          <p>Every request is subject to an
          <code>ap_location_walk()</code> call. This ensures that
          <code class="directive"><a href="../mod/core.html#location">&lt;Location&gt;</a></code> 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.</p>
        
    
        <h3><a name="translate_name" id="translate_name">translate_name</a></h3>
          <p>Modules can determine the file name, or alter the given URI
          in this step. For example, <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> will
          translate the URI's path into the configured virtual host,
          <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> will translate the path to an alias path,
          and if the request falls back on the core, the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> is prepended to the request resource.</p>
    
          <p>If all modules <code>DECLINE</code> this phase, an error 500 is
          returned to the browser, and a "couldn't translate name" error is logged
          automatically.</p>
        
    
        <h3><a name="map_to_storage" id="map_to_storage">Hook: map_to_storage</a></h3>
          <p>After the file or correct URI was determined, the
          appropriate per-dir configurations are merged together. For
          example, <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> compares and merges the appropriate
          <code class="directive"><a href="../mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> sections.
          If the URI is nothing more than a local (non-proxy) <code>TRACE</code>
          request, the core handles the request and returns <code>DONE</code>.
          If no module answers this hook with <code>OK</code> or <code>DONE</code>,
          the core will run the request filename against the <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> and <code class="directive"><a href="../mod/core.html#files">&lt;Files&gt;</a></code> sections. If the request
          'filename' isn't an absolute, legal filename, a note is set for
          later termination.</p>
        
    
        <h3><a name="location-walk" id="location-walk">URI Location Walk</a></h3>
          <p>Every request is hardened by a second
          <code>ap_location_walk()</code> call. This reassures that a
          translated request is still subjected to the configured
          <code class="directive"><a href="../mod/core.html#location">&lt;Location&gt;</a></code> sections.
          The request again borrows some or all of the processing from its previous
          <code>location_walk</code> above, so this step is almost always very
          efficient unless the translated URI mapped to a substantially different
          path or Virtual Host.</p>
        
    
        <h3><a name="header_parser" id="header_parser">Hook: header_parser</a></h3>
          <p>The main request then parses the client's headers. This
          prepares the remaining request processing steps to better serve
          the client's request.</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">The Security Phase</a></h2>
        <p>Needs Documentation. Code is:</p>
    
        <pre class="prettyprint lang-c">if ((access_status = ap_run_access_checker(r)) != 0) {
        return decl_die(access_status, "check access", r);
    }
    
    if ((access_status = ap_run_check_user_id(r)) != 0) {
        return decl_die(access_status, "check user", r);
    }
    
    if ((access_status = ap_run_auth_checker(r)) != 0) {
        return decl_die(access_status, "check authorization", r);
    }</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="preparation" id="preparation">The Preparation Phase</a></h2>
        <h3><a name="type_checker" id="type_checker">Hook: type_checker</a></h3>
          <p>The modules have an opportunity to test the URI or filename
          against the target resource, and set mime information for the
          request. Both <code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code> and
          <code class="module"><a href="../mod/mod_mime_magic.html">mod_mime_magic</a></code> 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.</p>
    
          <p>If all modules <code>DECLINE</code> this phase, an error 500 is
          returned to the browser, and a "couldn't find types" error is logged
          automatically.</p>
        
    
        <h3><a name="fixups" id="fixups">Hook: fixups</a></h3>
          <p>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.</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="handler" id="handler">The Handler Phase</a></h2>
        <p>This phase is <strong>not</strong> part of the processing in
        <code>ap_process_request_internal()</code>. Many
        modules prepare one or more subrequests prior to creating any
        content at all. After the core, or a module calls
        <code>ap_process_request_internal()</code> it then calls
        <code>ap_invoke_handler()</code> to generate the request.</p>
    
        <h3><a name="insert_filter" id="insert_filter">Hook: insert_filter</a></h3>
          <p>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.</p>
        
    
        <h3><a name="hook_handler" id="hook_handler">Hook: handler</a></h3>
          <p>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 <code class="module"><a href="../mod/mod_autoindex.html">mod_autoindex</a></code>,
          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.</p>
        
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/request.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/request.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/output-filters.html.en�������������������������������������������0000664�0001751�0001751�00000073170�14737241666�023341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Guide to writing output filters - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Guide to writing output filters</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/output-filters.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <p>There are a number of common pitfalls encountered when writing
        output filters; this page aims to document best practice for
        authors of new or existing filters.</p>
    
        <p>This document is applicable to both version 2.0 and version 2.2
        of the Apache HTTP Server; it specifically targets
        <code>RESOURCE</code>-level or <code>CONTENT_SET</code>-level
        filters though some advice is generic to all types of filter.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#basics">Filters and bucket brigades</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#invocation">Filter invocation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#brigade">Brigade structure</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#buckets">Processing buckets</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#filtering">Filtering brigades</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#state">Maintaining state</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#buffer">Buffering buckets</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#nonblock">Non-blocking bucket reads</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rules">Ten rules for output filters</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#usecase1">Use case: buffering in mod_ratelimit</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basics" id="basics">Filters and bucket brigades</a></h2>
        
    
        <p>Each time a filter is invoked, it is passed a <em>bucket
        brigade</em>, containing a sequence of <em>buckets</em> which
        represent both data content and metadata.  Every bucket has a
        <em>bucket type</em>; a number of bucket types are defined and
        used by the <code>httpd</code> core modules (and the
        <code>apr-util</code> library which provides the bucket brigade
        interface), but modules are free to define their own types.</p>
    
        <div class="note">Output filters must be prepared to process
        buckets of non-standard types; with a few exceptions, a filter
        need not care about the types of buckets being filtered.</div>
    
        <p>A filter can tell whether a bucket represents either data or
        metadata using the <code>APR_BUCKET_IS_METADATA</code> macro.
        Generally, all metadata buckets should be passed down the filter
        chain by an output filter.  Filters may transform, delete, and
        insert data buckets as appropriate.</p>
    
        <p>There are two metadata bucket types which all filters must pay
        attention to: the <code>EOS</code> bucket type, and the
        <code>FLUSH</code> bucket type.  An <code>EOS</code> bucket
        indicates that the end of the response has been reached and no
        further buckets need be processed.  A <code>FLUSH</code> bucket
        indicates that the filter should flush any buffered buckets (if
        applicable) down the filter chain immediately.</p>
    
        <div class="note"><code>FLUSH</code> buckets are sent when the
        content generator (or an upstream filter) knows that there may be
        a delay before more content can be sent.  By passing
        <code>FLUSH</code> buckets down the filter chain immediately,
        filters ensure that the client is not kept waiting for pending
        data longer than necessary.</div>
    
        <p>Filters can create <code>FLUSH</code> buckets and pass these
        down the filter chain if desired.  Generating <code>FLUSH</code>
        buckets unnecessarily, or too frequently, can harm network
        utilisation since it may force large numbers of small packets to
        be sent, rather than a small number of larger packets.  The
        section on <a href="#nonblock">Non-blocking bucket reads</a>
        covers a case where filters are encouraged to generate
        <code>FLUSH</code> buckets.</p>
    
        <div class="example"><h3>Example bucket brigade</h3><p><code>
        HEAP FLUSH FILE EOS</code></p></div>
    
        <p>This shows a bucket brigade which may be passed to a filter; it
        contains two metadata buckets (<code>FLUSH</code> and
        <code>EOS</code>), and two data buckets (<code>HEAP</code> and
        <code>FILE</code>).</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="invocation" id="invocation">Filter invocation</a></h2>
        
    
        <p>For any given request, an output filter might be invoked only
        once and be given a single brigade representing the entire response.
        It is also possible that the number of times a filter is invoked
        for a single response is proportional to the size of the content
        being filtered, with the filter being passed a brigade containing
        a single bucket each time.  Filters must operate correctly in
        either case.</p>
    
        <div class="warning">An output filter which allocates long-lived
        memory every time it is invoked may consume memory proportional to
        response size.  Output filters which need to allocate memory
        should do so once per response; see <a href="#state">Maintaining
        state</a> below.</div>
    
        <p>An output filter can distinguish the final invocation for a
        given response by the presence of an <code>EOS</code> bucket in
        the brigade.  Any buckets in the brigade after an EOS should be
        ignored.</p>
    
        <p>An output filter should never pass an empty brigade down the
        filter chain.  To be defensive, filters should be prepared to
        accept an empty brigade, and should return success without passing
        this brigade on down the filter chain.  The handling of an empty
        brigade should have no side effects (such as changing any state
        private to the filter).</p>
    
        <div class="example"><h3>How to handle an empty brigade</h3><pre class="prettyprint lang-c">apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        if (APR_BRIGADE_EMPTY(bb)) {
            return APR_SUCCESS;
        }
        ...</pre>
    </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="brigade" id="brigade">Brigade structure</a></h2>
        
    
        <p>A bucket brigade is a doubly-linked list of buckets.  The list
        is terminated (at both ends) by a <em>sentinel</em> which can be
        distinguished from a normal bucket by comparing it with the
        pointer returned by <code>APR_BRIGADE_SENTINEL</code>.  The list
        sentinel is in fact not a valid bucket structure; any attempt to
        call normal bucket functions (such as
        <code>apr_bucket_read</code>) on the sentinel will have undefined
        behaviour (i.e. will crash the process).</p>
    
        <p>There are a variety of functions and macros for traversing and
        manipulating bucket brigades; see the <a href="http://apr.apache.org/docs/apr-util/trunk/group___a_p_r___util___bucket___brigades.html">apr_buckets.h</a>
        header for complete coverage.  Commonly used macros include:</p>
    
        <dl>
          <dt><code>APR_BRIGADE_FIRST(bb)</code></dt>
          <dd>returns the first bucket in brigade bb</dd>
    
          <dt><code>APR_BRIGADE_LAST(bb)</code></dt>
          <dd>returns the last bucket in brigade bb</dd>
    
          <dt><code>APR_BUCKET_NEXT(e)</code></dt>
          <dd>gives the next bucket after bucket e</dd>
    
          <dt><code>APR_BUCKET_PREV(e)</code></dt>
          <dd>gives the bucket before bucket e</dd>
    
        </dl>
    
        <p>The <code>apr_bucket_brigade</code> structure itself is
        allocated out of a pool, so if a filter creates a new brigade, it
        must ensure that memory use is correctly bounded.  A filter which
        allocates a new brigade out of the request pool
        (<code>r-&gt;pool</code>) on every invocation, for example, will fall
        foul of the <a href="#invocation">warning above</a> concerning
        memory use.  Such a filter should instead create a brigade on the
        first invocation per request, and store that brigade in its <a href="#state">state structure</a>.</p>
    
        <div class="warning"><p>It is generally never advisable to use
        <code>apr_brigade_destroy</code> to "destroy" a brigade unless
        you know for certain that the brigade will never be used
        again, even then, it should be used rarely.  The
        memory used by the brigade structure will not be released by
        calling this function (since it comes from a pool), but the
        associated pool cleanup is unregistered.  Using
        <code>apr_brigade_destroy</code> can in fact cause memory leaks;
        if a "destroyed" brigade contains buckets when its
        containing pool is destroyed, those buckets will <em>not</em> be
        immediately destroyed.</p>
    
        <p>In general, filters should use <code>apr_brigade_cleanup</code>
        in preference to <code>apr_brigade_destroy</code>.</p></div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="buckets" id="buckets">Processing buckets</a></h2>
    
        
    
        <p>When dealing with non-metadata buckets, it is important to
        understand that the "<code>apr_bucket *</code>" object is an
        abstract <em>representation</em> of data:</p>
    
        <ol>
          <li>The amount of data represented by the bucket may or may not
          have a determinate length; for a bucket which represents data of
          indeterminate length, the <code>-&gt;length</code> field is set to
          the value <code>(apr_size_t)-1</code>.  For example, buckets of
          the <code>PIPE</code> bucket type have an indeterminate length;
          they represent the output from a pipe.</li>
    
          <li>The data represented by a bucket may or may not be mapped
          into memory.  The <code>FILE</code> bucket type, for example,
          represents data stored in a file on disk.</li>
        </ol>
    
        <p>Filters read the data from a bucket using the
        <code>apr_bucket_read</code> function.  When this function is
        invoked, the bucket may <em>morph</em> into a different bucket
        type, and may also insert a new bucket into the bucket brigade.
        This must happen for buckets which represent data not mapped into
        memory.</p>
    
        <p>To give an example; consider a bucket brigade containing a
        single <code>FILE</code> bucket representing an entire file, 24
        kilobytes in size:</p>
    
        <div class="example"><p><code>FILE(0K-24K)</code></p></div>
    
        <p>When this bucket is read, it will read a block of data from the
        file, morph into a <code>HEAP</code> bucket to represent that
        data, and return the data to the caller.  It also inserts a new
        <code>FILE</code> bucket representing the remainder of the file;
        after the <code>apr_bucket_read</code> call, the brigade looks
        like:</p>
    
        <div class="example"><p><code>HEAP(8K) FILE(8K-24K)</code></p></div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="filtering" id="filtering">Filtering brigades</a></h2>
        
    
        <p>The basic function of any output filter will be to iterate
        through the passed-in brigade and transform (or simply examine)
        the content in some manner.  The implementation of the iteration
        loop is critical to producing a well-behaved output filter.</p>
    
        <p>Taking an example which loops through the entire brigade as
        follows:</p>
    
        <div class="example"><h3>Bad output filter -- do not imitate!</h3><pre class="prettyprint lang-c">apr_bucket *e = APR_BRIGADE_FIRST(bb);
    const char *data;
    apr_size_t length;
    
    while (e != APR_BRIGADE_SENTINEL(bb)) {
        apr_bucket_read(e, &amp;data, &amp;length, APR_BLOCK_READ);
        e = APR_BUCKET_NEXT(e);
    }
    
    return ap_pass_brigade(bb);</pre>
    </div>
    
        <p>The above implementation would consume memory proportional to
        content size.  If passed a <code>FILE</code> bucket, for example,
        the entire file contents would be read into memory as each
        <code>apr_bucket_read</code> call morphed a <code>FILE</code>
        bucket into a <code>HEAP</code> bucket.</p>
    
        <p>In contrast, the implementation below will consume a fixed
        amount of memory to filter any brigade; a temporary brigade is
        needed and must be allocated only once per response, see the <a href="#state">Maintaining state</a> section.</p>
    
        <div class="example"><h3>Better output filter</h3><pre class="prettyprint lang-c">apr_bucket *e;
    const char *data;
    apr_size_t length;
    
    while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
        rv = apr_bucket_read(e, &amp;data, &amp;length, APR_BLOCK_READ);
        if (rv) ...;
        /* Remove bucket e from bb. */
        APR_BUCKET_REMOVE(e);
        /* Insert it into  temporary brigade. */
        APR_BRIGADE_INSERT_HEAD(tmpbb, e);
        /* Pass brigade downstream. */
        rv = ap_pass_brigade(f-&gt;next, tmpbb);
        if (rv) ...;
        apr_brigade_cleanup(tmpbb);
    }</pre>
    </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="state" id="state">Maintaining state</a></h2>
    
        
    
        <p>A filter which needs to maintain state over multiple
        invocations per response can use the <code>-&gt;ctx</code> field of
        its <code>ap_filter_t</code> structure.  It is typical to store a
        temporary brigade in such a structure, to avoid having to allocate
        a new brigade per invocation as described in the <a href="#brigade">Brigade structure</a> section.</p>
    
        <div class="example"><h3>Example code to maintain filter state</h3><pre class="prettyprint lang-c">struct dummy_state {
        apr_bucket_brigade *tmpbb;
        int filter_state;
        ...
    };
    
    apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        struct dummy_state *state;
    
        state = f-&gt;ctx;
        if (state == NULL) {
    
            /* First invocation for this response: initialise state structure.
             */
            f-&gt;ctx = state = apr_palloc(f-&gt;r-&gt;pool, sizeof *state);
    
            state-&gt;tmpbb = apr_brigade_create(f-&gt;r-&gt;pool, f-&gt;c-&gt;bucket_alloc);
            state-&gt;filter_state = ...;
        }
        ...</pre>
    </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="buffer" id="buffer">Buffering buckets</a></h2>
        
    
        <p>If a filter decides to store buckets beyond the duration of a
        single filter function invocation (for example storing them in its
        <code>-&gt;ctx</code> state structure), those buckets must be <em>set
        aside</em>.  This is necessary because some bucket types provide
        buckets which represent temporary resources (such as stack memory)
        which will fall out of scope as soon as the filter chain completes
        processing the brigade.</p>
    
        <p>To setaside a bucket, the <code>apr_bucket_setaside</code>
        function can be called.  Not all bucket types can be setaside, but
        if successful, the bucket will have morphed to ensure it has a
        lifetime at least as long as the pool given as an argument to the
        <code>apr_bucket_setaside</code> function.</p>
    
        <p>Alternatively, the <code>ap_save_brigade</code> function can be
        used, which will move all the buckets into a separate brigade
        containing buckets with a lifetime as long as the given pool
        argument.  This function must be used with care, taking into
        account the following points:</p>
    
        <ol>
          <li>On return, <code>ap_save_brigade</code> guarantees that all
          the buckets in the returned brigade will represent data mapped
          into memory.  If given an input brigade containing, for example,
          a <code>PIPE</code> bucket, <code>ap_save_brigade</code> will
          consume an arbitrary amount of memory to store the entire output
          of the pipe.</li>
    
          <li>When <code>ap_save_brigade</code> reads from buckets which
          cannot be setaside, it will always perform blocking reads,
          removing the opportunity to use <a href="#nonblock">Non-blocking
          bucket reads</a>.</li>
    
          <li>If <code>ap_save_brigade</code> is used without passing a
          non-NULL "<code>saveto</code>" (destination) brigade parameter,
          the function will create a new brigade, which may cause memory
          use to be proportional to content size as described in the <a href="#brigade">Brigade structure</a> section.</li>
        </ol>
    
        <div class="warning">Filters must ensure that any buffered data is
        processed and passed down the filter chain during the last
        invocation for a given response (a brigade containing an EOS
        bucket).  Otherwise such data will be lost.</div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="nonblock" id="nonblock">Non-blocking bucket reads</a></h2>
        
    
        <p>The <code>apr_bucket_read</code> function takes an
        <code>apr_read_type_e</code> argument which determines whether a
        <em>blocking</em> or <em>non-blocking</em> read will be performed
        from the data source.  A good filter will first attempt to read
        from every data bucket using a non-blocking read; if that fails
        with <code>APR_EAGAIN</code>, then send a <code>FLUSH</code>
        bucket down the filter chain, and retry using a blocking read.</p>
    
        <p>This mode of operation ensures that any filters further down the
        filter chain will flush any buffered buckets if a slow content
        source is being used.</p>
    
        <p>A CGI script is an example of a slow content source which is
        implemented as a bucket type. <code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code> will send
        <code>PIPE</code> buckets which represent the output from a CGI
        script; reading from such a bucket will block when waiting for the
        CGI script to produce more output.</p>
    
        <div class="example"><h3>Example code using non-blocking bucket reads</h3><pre class="prettyprint lang-c">apr_bucket *e;
    apr_read_type_e mode = APR_NONBLOCK_READ;
    
    while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
        apr_status_t rv;
    
        rv = apr_bucket_read(e, &amp;data, &amp;length, mode);
        if (rv == APR_EAGAIN &amp;&amp; mode == APR_NONBLOCK_READ) {
    
            /* Pass down a brigade containing a flush bucket: */
            APR_BRIGADE_INSERT_TAIL(tmpbb, apr_bucket_flush_create(...));
            rv = ap_pass_brigade(f-&gt;next, tmpbb);
            apr_brigade_cleanup(tmpbb);
            if (rv != APR_SUCCESS) return rv;
    
            /* Retry, using a blocking read. */
            mode = APR_BLOCK_READ;
            continue;
        }
        else if (rv != APR_SUCCESS) {
            /* handle errors */
        }
    
        /* Next time, try a non-blocking read first. */
        mode = APR_NONBLOCK_READ;
        ...
    }</pre>
    </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rules" id="rules">Ten rules for output filters</a></h2>
        
    
        <p>In summary, here is a set of rules for all output filters to
        follow:</p>
    
        <ol>
          <li>Output filters should not pass empty brigades down the filter
          chain, but should be tolerant of being passed empty
          brigades.</li>
    
          <li>Output filters must pass all metadata buckets down the filter
          chain; <code>FLUSH</code> buckets should be respected by passing
          any pending or buffered buckets down the filter chain.</li>
    
          <li>Output filters should ignore any buckets following an
          <code>EOS</code> bucket.</li>
    
          <li>Output filters must process a fixed amount of data at a
          time, to ensure that memory consumption is not proportional to
          the size of the content being filtered.</li>
    
          <li>Output filters should be agnostic with respect to bucket
          types, and must be able to process buckets of unfamiliar
          type.</li>
    
          <li>After calling <code>ap_pass_brigade</code> to pass a brigade
          down the filter chain, output filters should call
          <code>apr_brigade_cleanup</code> to ensure the brigade is empty
          before reusing that brigade structure; output filters should
          never use <code>apr_brigade_destroy</code> to "destroy"
          brigades.</li>
    
          <li>Output filters must <em>setaside</em> any buckets which are
          preserved beyond the duration of the filter function.</li>
    
          <li>Output filters must not ignore the return value of
          <code>ap_pass_brigade</code>, and must return appropriate errors
          back up the filter chain.</li>
    
          <li>Output filters must only create a fixed number of bucket
          brigades for each response, rather than one per invocation.</li>
    
          <li>Output filters should first attempt non-blocking reads from
          each data bucket, and send a <code>FLUSH</code> bucket down the
          filter chain if the read blocks, before retrying with a blocking
          read.</li>
    
        </ol>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usecase1" id="usecase1">Use case: buffering in mod_ratelimit</a></h2>
        
        <p>The <a href="http://svn.apache.org/r1833875">r1833875</a> change is a good
        example to show what buffering and keeping state means in the context of an
        output filter. In this use case, a user asked on the users' mailing list a
        interesting question about why <code class="module"><a href="../mod/mod_ratelimit.html">mod_ratelimit</a></code> seemed not to
        honor its setting with proxied content (either rate limiting at a different
        speed or simply not doing it at all). Before diving deep into the solution,
        it is better to explain on a high level how <code class="module"><a href="../mod/mod_ratelimit.html">mod_ratelimit</a></code> works.
        The trick is really simple: take the rate limit settings and calculate a
        chunk size of data to flush every 200ms to the client. For example, let's imagine
        that to set <code>rate-limit 60</code> in our config, these are the high level
        steps to find the chunk size:</p>
        <pre class="prettyprint lang-c">/* milliseconds to wait between each flush of data */
    RATE_INTERVAL_MS = 200;
    /* rate limit speed in b/s */
    speed = 60 * 1024;
    /* final chunk size is 12228 bytes */
    chunk_size = (speed / (1000 / RATE_INTERVAL_MS));</pre>
    
        <p>If we apply this calculation to a bucket brigade carrying 38400 bytes, it means
        that the filter will try to do the following:</p>
        <ol>
            <li>Split the 38400 bytes in chunks of maximum 12228 bytes each.</li>
            <li>Flush the first 12228 chunk of bytes and sleep 200ms.</li>
            <li>Flush the second 12228 chunk of bytes and sleep 200ms.</li>
            <li>Flush the third 12228 chunk of bytes and sleep 200ms.</li>
            <li>Flush the remaining 1716 bytes.</li>
        </ol>
        <p>The above pseudo code works fine if the output filter handles only one brigade
        for each response, but it might happen that it needs to be called multiple times
        with different brigade sizes as well. The former use case is for example when
        httpd directly serves some content, like a static file: the bucket brigade
        abstraction takes care of handling the whole content, and rate limiting
        works nicely. But if the same static content is served via mod_proxy_http (for
        example a backend is serving it rather than httpd) then the content generator
        (in this case mod_proxy_http) may use a maximum buffer size and then send data
        as bucket brigades to the output filters chain regularly, triggering of course
        multiple calls to <code class="module"><a href="../mod/mod_ratelimit.html">mod_ratelimit</a></code>. If the reader tries to execute the pseudo code
        assuming multiple calls to the output filter, each one requiring to process
        a bucket brigade of 38400 bytes, then it is easy to spot some
        anomalies:</p>
        <ol>
            <li>Between the last flush of a brigade and the first one of the next,
                there is no sleep.</li>
            <li>Even if the sleep was forced after the last flush, then that chunk size
                would not be the ideal size (1716 bytes instead of 12228) and the final client's speed
                would quickly become different than what set in the httpd's config.</li>
        </ol>
        <p>In this case, two things might help:</p>
        <ol>
            <li>Use the ctx internal data structure, initialized by <code class="module"><a href="../mod/mod_ratelimit.html">mod_ratelimit</a></code>
            for each response handling cycle, to "remember" when the last sleep was
            performed across multiple invocations, and act accordingly.</li>
            <li>If a bucket brigade is not splittable into a finite number of chunk_size
            blocks, store the remaining bytes (located in the tail of the bucket brigade) 
            in a temporary holding area (namely another bucket brigade) and then use
            <code>ap_save_brigade</code> to set them aside.
            These bytes will be prepended to the next bucket brigade that will be handled
            in the subsequent invocation.</li>
            <li>Avoid the previous logic if the bucket brigade that is currently being
            processed contains the end of stream bucket (EOS). There is no need to sleep
            or buffering data if the end of stream is reached.</li>
        </ol>
        <p>The commit linked in the beginning of the section contains also a bit of code
        refactoring so it is not trivial to read during the first pass, but the overall
        idea is basically what written up to now. The goal of this section is not to
        cause a headache to the reader trying to read C code, but to put him/her into
        the right mindset needed to use efficiently the tools offered by the httpd's
        filter chain toolset.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/output-filters.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/output-filters.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/API.html���������������������������������������������������������0000664�0001751�0001751�00000000162�13710016232�020305� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: API.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/hooks.html�������������������������������������������������������0000664�0001751�0001751�00000000164�13710016232�021021� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: hooks.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/new_api_2_4.html�������������������������������������������������0000664�0001751�0001751�00000000172�13710016232�021763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: new_api_2_4.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/API.html.en������������������������������������������������������0000664�0001751�0001751�00000177540�14737241666�020752� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache 1.3 API notes - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Apache 1.3 API notes</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/API.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <div class="warning"><h3>Warning</h3>
          <p>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.</p>
        </div>
    
        <p>These are some notes on the Apache API and the data structures you have
        to deal with, <em>etc.</em> 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 <em>might</em> 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).</p>
    
        <p>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.</p>
    
        <p>Finally, here's an outline, to give you some bare idea of what's coming
        up, and in what order:</p>
    
        <ul>
          <li>
            <a href="#basics">Basic concepts.</a>
    
            <ul>
              <li><a href="#HMR">Handlers, Modules, and
              Requests</a></li>
    
              <li><a href="#moduletour">A brief tour of a
              module</a></li>
            </ul>
          </li>
    
          <li>
            <a href="#handlers">How handlers work</a>
    
            <ul>
              <li><a href="#req_tour">A brief tour of the
              <code>request_rec</code></a></li>
    
              <li><a href="#req_orig">Where request_rec structures come
              from</a></li>
    
              <li><a href="#req_return">Handling requests, declining,
              and returning error codes</a></li>
    
              <li><a href="#resp_handlers">Special considerations for
              response handlers</a></li>
    
              <li><a href="#auth_handlers">Special considerations for
              authentication handlers</a></li>
    
              <li><a href="#log_handlers">Special considerations for
              logging handlers</a></li>
            </ul>
          </li>
    
          <li><a href="#pools">Resource allocation and resource
          pools</a></li>
    
          <li>
            <a href="#config">Configuration, commands and the like</a>
    
            <ul>
              <li><a href="#per-dir">Per-directory configuration
              structures</a></li>
    
              <li><a href="#commands">Command handling</a></li>
    
              <li><a href="#servconf">Side notes --- per-server
              configuration, virtual servers, <em>etc</em>.</a></li>
            </ul>
          </li>
        </ul>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#basics">Basic concepts</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#handlers">How handlers work</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#pools">Resource allocation and resource pools</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">Configuration, commands and the like</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basics" id="basics">Basic concepts</a></h2>
        <p>We begin with an overview of the basic concepts behind the API, and how
        they are manifested in the code.</p>
    
        <h3><a name="HMR" id="HMR">Handlers, Modules, and Requests</a></h3>
          <p>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:</p>
    
          <ul>
          <li>URI -&gt; Filename translation</li>
          <li>Auth ID checking [is the user who they say they are?]</li>
          <li>Auth access checking [is the user authorized <em>here</em>?]</li>
          <li>Access checking other than auth</li>
          <li>Determining MIME type of the object requested</li>
          <li>`Fixups' -- there aren't any of these yet, but the phase is intended
          as a hook for possible extensions like <code class="directive"><a href="../mod/mod_env.html#setenv">SetEnv</a></code>, which don't really fit well elsewhere.</li>
          <li>Actually sending a response back to the client.</li>
          <li>Logging the request</li>
          </ul>
    
          <p>These phases are handled by looking at each of a succession of
          <em>modules</em>, 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:</p>
    
          <ul>
          <li><em>Handle</em> the request, and indicate that it has done so by
          returning the magic constant <code>OK</code>.</li>
    
          <li><em>Decline</em> to handle the request, by returning the magic integer
          constant <code>DECLINED</code>. In this case, the server behaves in all
          respects as if the handler simply hadn't been there.</li>
    
          <li>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.</li>
          </ul>
    
          <p>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 <em>any</em> request,
          by giving it the key <code>*/*</code> (<em>i.e.</em>, 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).</p>
    
          <p>The handlers themselves are functions of one argument (a
          <code>request_rec</code> structure. vide infra), which returns an integer,
          as above.</p>
        
    
        <h3><a name="moduletour" id="moduletour">A brief tour of a module</a></h3>
          <p>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 <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> 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.</p>
    
          <p>Let's begin with handlers. In order to handle the CGI scripts, the
          module declares a response handler for them. Because of <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>, it also has handlers for the
          name translation phase (to recognize <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>ed URIs), the type-checking phase (any
          <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>ed request is typed
          as a CGI script).</p>
    
          <p>The module needs to maintain some per (virtual) server information,
          namely, the <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>es 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 <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>es declared).</p>
    
          <p>Finally, this module contains code to handle the <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> command itself. This particular
          module only declares one command, but there could be more, so modules have
          <em>command tables</em> which declare their commands, and describe where
          they are permitted, and how they are to be invoked.</p>
    
          <p>A final note on the declared types of the arguments of some of these
          commands: a <code>pool</code> is a pointer to a <em>resource pool</em>
          structure; these are used by the server to keep track of the memory which
          has been allocated, files opened, <em>etc.</em>, 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,
          <em>en masse</em>, without anyone having to write explicit code to track
          them all down and dispose of them. Also, a <code>cmd_parms</code>
          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 <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>). With no further ado, the
          module itself:</p>
    
          <div class="example"><p><code>
            /* Declarations of handlers. */<br />
            <br />
            int translate_scriptalias (request_rec *);<br />
            int type_scriptalias (request_rec *);<br />
            int cgi_handler (request_rec *);<br />
            <br />
            /* Subsidiary dispatch table for response-phase <br />
            &nbsp;* handlers, by MIME type */<br />
            <br />
            handler_rec cgi_handlers[] = {<br />
            <span class="indent">
              { "application/x-httpd-cgi", cgi_handler },<br />
              { NULL }<br />
            </span>
            };<br />
            <br />
            /* Declarations of routines to manipulate the <br />
            &nbsp;* module's configuration info.  Note that these are<br />
            &nbsp;* returned, and passed in, as void *'s; the server<br />
            &nbsp;* core keeps track of them, but it doesn't, and can't,<br />
            &nbsp;* know their internal structure.<br />
            &nbsp;*/<br />
            <br />
            void *make_cgi_server_config (pool *);<br />
            void *merge_cgi_server_config (pool *, void *, void *);<br />
            <br />
            /* Declarations of routines to handle config-file commands */<br />
            <br />
            extern char *script_alias(cmd_parms *, void *per_dir_config, char *fake,
                                      char *real);<br />
            <br />
            command_rec cgi_cmds[] = {<br />
            <span class="indent">
              { "ScriptAlias", script_alias, NULL, RSRC_CONF, TAKE2,<br />
              <span class="indent">"a fakename and a realname"},<br /></span>
              { NULL }<br />
            </span>
            };<br />
            <br />
            module cgi_module = {
    </code></p><pre>  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 */
    };</pre></div>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="handlers" id="handlers">How handlers work</a></h2>
        <p>The sole argument to handlers is a <code>request_rec</code> 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 <code>request_rec</code> structure.</p>
    
        <h3><a name="req_tour" id="req_tour">A brief tour of the request_rec</a></h3>
          <p>The <code>request_rec</code> 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.</p>
    
          <p>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).</p>
    
          <p>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 <code>ap_table_get</code>
          and <code>ap_table_set</code> routines.</p>
    
          <div class="note">
            <p>Note that the <code>Content-type</code> header value <em>cannot</em>
            be set by module content-handlers using the <code>ap_table_*()</code>
            routines. Rather, it is set by pointing the <code>content_type</code>
            field in the <code>request_rec</code> structure to an appropriate
            string. <em>e.g.</em>,</p>
            <div class="example"><p><code>
              r-&gt;content_type = "text/html";
            </code></p></div>
          </div>
    
          <p>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
          <code>.htaccess</code> files or <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> 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 <code>server_rec</code> data structure pointed
          to by the <code>request_rec</code>, which contains per (virtual) server
          configuration data.</p>
    
          <p>Here is an abridged declaration, giving the fields most commonly
          used:</p>
    
          <div class="example"><p><code>
            struct request_rec {<br />
            <br />
            pool *pool;<br />
            conn_rec *connection;<br />
            server_rec *server;<br />
            <br />
            /* What object is being requested */<br />
            <br />
            char *uri;<br />
            char *filename;<br />
            char *path_info;
    </code></p><pre>char *args;           /* QUERY_ARGS, if any */
    struct stat finfo;    /* Set by server core;
                           * st_mode set to zero if no such file */</pre><p><code>
            char *content_type;<br />
            char *content_encoding;<br />
            <br />
            /* MIME header environments, in and out. Also, <br />
            &nbsp;* an array containing environment variables to<br />
            &nbsp;* be passed to subprocesses, so people can write<br />
            &nbsp;* modules to add to that environment.<br />
            &nbsp;*<br />
            &nbsp;* The difference between headers_out and <br />
            &nbsp;* err_headers_out is that the latter are printed <br />
            &nbsp;* even on error, and persist across internal<br />
            &nbsp;* redirects (so the headers printed for <br />
            &nbsp;* <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code> handlers will have
             them).<br />
            &nbsp;*/<br />
             <br />
            table *headers_in;<br />
            table *headers_out;<br />
            table *err_headers_out;<br />
            table *subprocess_env;<br />
            <br />
            /* Info about the request itself... */<br />
            <br />
    </code></p><pre>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, <em>etc.</em> */
    int method_number;   /* M_GET, M_POST, <em>etc.</em> */</pre><p><code>
            /* Info for logging */<br />
            <br />
            char *the_request;<br />
            int bytes_sent;<br />
            <br />
            /* A flag which modules can set, to indicate that<br />
            &nbsp;* the data being returned is volatile, and clients<br />
            &nbsp;* should be told not to cache it.<br />
            &nbsp;*/<br />
            <br />
            int no_cache;<br />
            <br />
            /* Various other config info which may change<br />
            &nbsp;* with .htaccess files<br />
            &nbsp;* These are config vectors, with one void*<br />
            &nbsp;* pointer for each module (the thing pointed<br />
            &nbsp;* to being the module's business).<br />
            &nbsp;*/<br />
            <br />
    </code></p><pre>void *per_dir_config;   /* Options set in config files, <em>etc.</em> */
    void *request_config;   /* Notes on *this* request */</pre><p><code>
            };
          </code></p></div>
        
    
        <h3><a name="req_orig" id="req_orig">Where request_rec structures come from</a></h3>
          <p>Most <code>request_rec</code> structures are built by reading an HTTP
          request from a client, and filling in the fields. However, there are a
          few exceptions:</p>
    
          <ul>
          <li>If the request is to an imagemap, a type map (<em>i.e.</em>, a
          <code>*.var</code> 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 <em>internal redirect</em>,
          constructing a new <code>request_rec</code> for the new URI, and
          processing it almost exactly as if the client had requested the new URI
          directly.</li>
    
          <li>If some handler signaled an error, and an <code>ErrorDocument</code>
          is in scope, the same internal redirect machinery comes into play.</li>
    
          <li><p>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.</p>
    
          <p>Such handlers can construct a <em>sub-request</em>, using the
          functions <code>ap_sub_req_lookup_file</code>,
          <code>ap_sub_req_lookup_uri</code>, and <code>ap_sub_req_method_uri</code>;
          these construct a new <code>request_rec</code> structure and processes it
          as you would expect, up to but not including the point of actually sending
          a response. (These functions skip over the access checks if the
          sub-request is for a file in the same directory as the original
          request).</p>
    
          <p>(Server-side includes work by building sub-requests and then actually
          invoking the response handler for them, via the function
          <code>ap_run_sub_req</code>).</p>
          </li>
          </ul>
        
    
        <h3><a name="req_return" id="req_return">Handling requests, declining, and returning
        error codes</a></h3>
          <p>As discussed above, each handler, when invoked to handle a particular
          <code>request_rec</code>, has to return an <code>int</code> to indicate
          what happened. That can either be</p>
    
          <ul>
          <li><code>OK</code> -- the request was handled successfully. This may or
          may not terminate the phase.</li>
    
          <li><code>DECLINED</code> -- no erroneous condition exists, but the module
          declines to handle the phase; the server tries to find another.</li>
    
          <li>an HTTP error code, which aborts handling of the request.</li>
          </ul>
    
          <p>Note that if the error code returned is <code>REDIRECT</code>, then
          the module should put a <code>Location</code> in the request's
          <code>headers_out</code>, to indicate where the client should be
          redirected <em>to</em>.</p>
        
    
        <h3><a name="resp_handlers" id="resp_handlers">Special considerations for response
        handlers</a></h3>
          <p>Handlers for most phases do their work by simply setting a few fields
          in the <code>request_rec</code> 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.</p>
    
          <p>They should begin by sending an HTTP response header, using the
          function <code>ap_send_http_header</code>. (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 <code>header_only</code>, that's all they should do; they should
          return after that, without attempting any further output.</p>
    
          <p>Otherwise, they should produce a request body which responds to the
          client as appropriate. The primitives for this are <code>ap_rputc</code>
          and <code>ap_rprintf</code>, for internally generated output, and
          <code>ap_send_fd</code>, to copy the contents of some <code>FILE *</code>
          straight to the client.</p>
    
          <p>At this point, you should more or less understand the following piece
          of code, which is the handler which handles <code>GET</code> requests
          which have no more specific handler; it also shows how conditional
          <code>GET</code>s can be handled, if it's desirable to do so in a
          particular response handler -- <code>ap_set_last_modified</code> checks
          against the <code>If-modified-since</code> 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
          <code>ap_set_content_length</code>, but it returns an error code for
          symmetry.</p>
    
          <div class="example"><p><code>
            int default_handler (request_rec *r)<br />
            {<br />
            <span class="indent">
              int errstatus;<br />
              FILE *f;<br />
              <br />
              if (r-&gt;method_number != M_GET) return DECLINED;<br />
              if (r-&gt;finfo.st_mode == 0) return NOT_FOUND;<br />
              <br />
              if ((errstatus = ap_set_content_length (r, r-&gt;finfo.st_size))<br />
              &nbsp;&nbsp;&nbsp;&nbsp;||
                 (errstatus = ap_set_last_modified (r, r-&gt;finfo.st_mtime)))<br />
              return errstatus;<br />
              <br />
              f = fopen (r-&gt;filename, "r");<br />
              <br />
              if (f == NULL) {<br />
              <span class="indent">
                log_reason("file permissions deny server access", r-&gt;filename, r);<br />
                return FORBIDDEN;<br />
              </span>
              }<br />
              <br />
              register_timeout ("send", r);<br />
              ap_send_http_header (r);<br />
              <br />
              if (!r-&gt;header_only) send_fd (f, r);<br />
              ap_pfclose (r-&gt;pool, f);<br />
              return OK;<br />
            </span>
            }
          </code></p></div>
    
          <p>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
          <code>ap_internal_redirect</code>, which is how the internal redirection
          machinery discussed above is invoked. A response handler which has
          internally redirected should always return <code>OK</code>.</p>
    
          <p>(Invoking <code>ap_internal_redirect</code> from handlers which are
          <em>not</em> response handlers will lead to serious confusion).</p>
        
    
        <h3><a name="auth_handlers" id="auth_handlers">Special considerations for authentication
        handlers</a></h3>
          <p>Stuff that should be discussed here in detail:</p>
    
          <ul>
          <li>Authentication-phase handlers not invoked unless auth is
          configured for the directory.</li>
    
          <li>Common auth configuration stored in the core per-dir
          configuration; it has accessors <code>ap_auth_type</code>,
          <code>ap_auth_name</code>, and <code>ap_requires</code>.</li>
    
          <li>Common routines, to handle the protocol end of things, at
          least for HTTP basic authentication
          (<code>ap_get_basic_auth_pw</code>, which sets the
          <code>connection-&gt;user</code> structure field
          automatically, and <code>ap_note_basic_auth_failure</code>,
          which arranges for the proper <code>WWW-Authenticate:</code>
          header to be sent back).</li>
          </ul>
        
    
        <h3><a name="log_handlers" id="log_handlers">Special considerations for logging
        handlers</a></h3>
          <p>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 <code>request_rec</code> structures which are threaded
          through the <code>r-&gt;prev</code> and <code>r-&gt;next</code> pointers.
          The <code>request_rec</code> 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 <code>bytes_sent</code> field will only be
          correct in the last request in the chain (the one for which a response was
          actually sent).</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="pools" id="pools">Resource allocation and resource pools</a></h2>
        <p>One of the problems of writing and designing a server-pool server is
        that of preventing leakage, that is, allocating resources (memory, open
        files, <em>etc.</em>), 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
        <em>automatically</em> released when the server is done with them.</p>
    
        <p>The way this works is as follows: the memory which is allocated, file
        opened, <em>etc.</em>, to deal with a particular request are tied to a
        <em>resource pool</em> which is allocated for the request. The pool is a
        data structure which itself tracks the resources in question.</p>
    
        <p>When the request has been processed, the pool is <em>cleared</em>. 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.</p>
    
        <p>Server restarts, and allocation of memory and resources for per-server
        configuration, are handled in a similar way. There is a <em>configuration
        pool</em>, 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.</p>
    
        <p>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 <code><a href="#pool-files">ap_pfopen</a></code>, which also arranges for the
        underlying file descriptor to be closed before any child processes, such as
        for CGI scripts, are <code>exec</code>ed), 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, <code>ap_palloc</code> is generally faster than
        <code>malloc</code>.</p>
    
        <p>We begin here by describing how memory is allocated to pools, and then
        discuss how other resources are tracked by the resource pool machinery.</p>
    
        <h3>Allocation of memory in pools</h3>
          <p>Memory is allocated to pools by calling the function
          <code>ap_palloc</code>, which takes two arguments, one being a pointer to
          a resource pool structure, and the other being the amount of memory to
          allocate (in <code>char</code>s). Within handlers for handling requests,
          the most common way of getting a resource pool structure is by looking at
          the <code>pool</code> slot of the relevant <code>request_rec</code>; hence
          the repeated appearance of the following idiom in module code:</p>
    
          <div class="example"><p><code>
            int my_handler(request_rec *r)<br />
            {<br />
            <span class="indent">
              struct my_structure *foo;<br />
              ...<br />
              <br />
              foo = (foo *)ap_palloc (r-&gt;pool, sizeof(my_structure));<br />
            </span>
            }
          </code></p></div>
    
          <p>Note that <em>there is no <code>ap_pfree</code></em> --
          <code>ap_palloc</code>ed memory is freed only when the associated resource
          pool is cleared. This means that <code>ap_palloc</code> does not have to
          do as much accounting as <code>malloc()</code>; all it does in the typical
          case is to round up the size, bump a pointer, and do a range check.</p>
    
          <p>(It also raises the possibility that heavy use of
          <code>ap_palloc</code> 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 <code>malloc</code>, and try to be sure that all of
          the memory gets explicitly <code>free</code>d, 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).</p>
        
    
        <h3>Allocating initialized memory</h3>
          <p>There are functions which allocate initialized memory, and are
          frequently useful. The function <code>ap_pcalloc</code> has the same
          interface as <code>ap_palloc</code>, but clears out the memory it
          allocates before it returns it. The function <code>ap_pstrdup</code>
          takes a resource pool and a <code>char *</code> as arguments, and
          allocates memory for a copy of the string the pointer points to, returning
          a pointer to the copy. Finally <code>ap_pstrcat</code> is a varargs-style
          function, which takes a pointer to a resource pool, and at least two
          <code>char *</code> arguments, the last of which must be
          <code>NULL</code>. It allocates enough memory to fit copies of each of
          the strings, as a unit; for instance:</p>
    
          <div class="example"><p><code>
            ap_pstrcat (r-&gt;pool, "foo", "/", "bar", NULL);
          </code></p></div>
    
          <p>returns a pointer to 8 bytes worth of memory, initialized to
          <code>"foo/bar"</code>.</p>
        
    
        <h3><a name="pools-used" id="pools-used">Commonly-used pools in the Apache Web
        server</a></h3>
          <p>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:</p>
    
          <dl>
          <dt><code>permanent_pool</code></dt>
          <dd>never passed to anything else, this is the ancestor of all pools</dd>
    
          <dt><code>pconf</code></dt>
          <dd>
            <ul>
              <li>subpool of permanent_pool</li>
    
              <li>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-&gt;pool, or as the
              "pool *p" argument on those which don't take pools</li>
    
              <li>passed to the module init() functions</li>
            </ul>
          </dd>
    
          <dt><code>ptemp</code></dt>
          <dd>
            <ul>
              <li>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.</li>
    
              <li>subpool of permanent_pool</li>
    
              <li>created at the beginning of a config "cycle"; exists
              until the end of config parsing; passed to config-time
              routines <em>via</em> cmd-&gt;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.</li>
            </ul>
          </dd>
    
          <dt><code>pchild</code></dt>
          <dd>
            <ul>
              <li>subpool of permanent_pool</li>
    
              <li>created when a child is spawned (or a thread is
              created); lives until that child (thread) is
              destroyed</li>
    
              <li>passed to the module child_init functions</li>
    
              <li>destruction happens right after the child_exit
              functions are called... (which may explain why I think
              child_exit is redundant and unneeded)</li>
            </ul>
          </dd>
    
          <dt><code>ptrans</code></dt>
          <dd>
            <ul>
              <li>should be a subpool of pchild, but currently is a
              subpool of permanent_pool, see above</li>
    
              <li>cleared by the child before going into the accept()
              loop to receive a connection</li>
    
              <li>used as connection-&gt;pool</li>
            </ul>
          </dd>
    
          <dt><code>r-&gt;pool</code></dt>
          <dd>
            <ul>
              <li>for the main request this is a subpool of
              connection-&gt;pool; for subrequests it is a subpool of
              the parent request's pool.</li>
    
              <li>exists until the end of the request (<em>i.e.</em>,
              ap_destroy_sub_req, or in child_main after
              process_request has finished)</li>
    
              <li>note that r itself is allocated from r-&gt;pool;
              <em>i.e.</em>, r-&gt;pool is first created and then r is
              the first thing palloc()d from it</li>
            </ul>
          </dd>
          </dl>
    
          <p>For almost everything folks do, <code>r-&gt;pool</code> 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.</p>
    
          <p>You can also see how some bugs have manifested themself, such as
          setting <code>connection-&gt;user</code> to a value from
          <code>r-&gt;pool</code> -- in this case connection exists for the
          lifetime of <code>ptrans</code>, which is longer than
          <code>r-&gt;pool</code> (especially if <code>r-&gt;pool</code> is a
          subrequest!). So the correct thing to do is to allocate from
          <code>connection-&gt;pool</code>.</p>
    
          <p>And there was another interesting bug in <code class="module"><a href="../mod/mod_include.html">mod_include</a></code>
          / <code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code>. You'll see in those that they do this test
          to decide if they should use <code>r-&gt;pool</code> or
          <code>r-&gt;main-&gt;pool</code>. In this case the resource that they are
          registering for cleanup is a child process. If it were registered in
          <code>r-&gt;pool</code>, then the code would <code>wait()</code> for the
          child when the subrequest finishes. With <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> this
          could be any old <code>#include</code>, and the delay can be up to 3
          seconds... and happened quite frequently. Instead the subprocess is
          registered in <code>r-&gt;main-&gt;pool</code> which causes it to be
          cleaned up when the entire request is done -- <em>i.e.</em>, after the
          output has been sent to the client and logging has happened.</p>
        
    
        <h3><a name="pool-files" id="pool-files">Tracking open files, etc.</a></h3>
          <p>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 <code>ap_pfopen</code>, which takes a
          resource pool and two strings as arguments; the strings are the same as
          the typical arguments to <code>fopen</code>, <em>e.g.</em>,</p>
    
          <div class="example"><p><code>
            ...<br />
            FILE *f = ap_pfopen (r-&gt;pool, r-&gt;filename, "r");<br />
            <br />
            if (f == NULL) { ... } else { ... }<br />
          </code></p></div>
    
          <p>There is also a <code>ap_popenf</code> routine, which parallels the
          lower-level <code>open</code> system call. Both of these routines arrange
          for the file to be closed when the resource pool in question is
          cleared.</p>
    
          <p>Unlike the case for memory, there <em>are</em> functions to close files
          allocated with <code>ap_pfopen</code>, and <code>ap_popenf</code>, namely
          <code>ap_pfclose</code> and <code>ap_pclosef</code>. (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 <code>ap_pfopen</code> and <code>ap_popenf</code>, since to
          do otherwise could cause fatal errors on systems such as Linux, which
          react badly if the same <code>FILE*</code> is closed more than once.</p>
    
          <p>(Using the <code>close</code> 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).</p>
        
    
        <h3>Other sorts of resources -- cleanup functions</h3>
          <p>More text goes here. Describe the cleanup primitives in terms of
          which the file stuff is implemented; also, <code>spawn_process</code>.</p>
    
          <p>Pool cleanups live until <code>clear_pool()</code> is called:
          <code>clear_pool(a)</code> recursively calls <code>destroy_pool()</code>
          on all subpools of <code>a</code>; then calls all the cleanups for
          <code>a</code>; then releases all the memory for <code>a</code>.
          <code>destroy_pool(a)</code> calls <code>clear_pool(a)</code> and then
          releases the pool structure itself. <em>i.e.</em>,
          <code>clear_pool(a)</code> doesn't delete <code>a</code>, it just frees
          up all the resources and you can start using it again immediately.</p>
        
    
        <h3>Fine control -- creating and dealing with sub-pools, with
        a note on sub-requests</h3>
          <p>On rare occasions, too-free use of <code>ap_palloc()</code> and the
          associated primitives may result in undesirably profligate resource
          allocation. You can deal with such a case by creating a <em>sub-pool</em>,
          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 <em>is</em> 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 <em>very</em> large directories.
          Unnecessary use of the primitives discussed here can hair up your code
          quite a bit, with very little gain).</p>
    
          <p>The primitive for creating a sub-pool is <code>ap_make_sub_pool</code>,
          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
          <code>ap_clear_pool</code> and <code>ap_destroy_pool</code>, respectively.
          (The difference is that <code>ap_clear_pool</code> frees resources
          associated with the pool, while <code>ap_destroy_pool</code> 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).</p>
    
          <p>One final note -- sub-requests have their own resource pools, which are
          sub-pools of the resource pool for the main request. The polite way to
          reclaim the resources associated with a sub request which you have
          allocated (using the <code>ap_sub_req_...</code> functions) is
          <code>ap_destroy_sub_req</code>, which frees the resource pool. Before
          calling this function, be sure to copy anything that you care about which
          might be allocated in the sub-request's resource pool into someplace a
          little less volatile (for instance, the filename in its
          <code>request_rec</code> structure).</p>
    
          <p>(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
          <code>ap_destroy_...</code> functions).</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">Configuration, commands and the like</a></h2>
        <p>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.</p>
    
        <p>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
        <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code> and <code class="directive"><a href="../mod/core.html#forcetype">ForceType</a></code> directives, and so forth. In general,
        the governing philosophy is that anything which <em>can</em> be made
        configurable by directory should be; per-server information is generally
        used in the standard set of modules for information like
        <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>es and <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code>s which come into play before the
        request is tied to a particular place in the underlying file system.</p>
    
        <p>Another requirement for emulating the NCSA server is being able to handle
        the per-directory configuration files, generally called
        <code>.htaccess</code> files, though even in the NCSA server they can
        contain directives which have nothing at all to do with access control.
        Accordingly, after URI -&gt; 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
        <code>.htaccess</code> files which might be present. The information which
        is read in then has to be <em>merged</em> with the applicable information
        from the server's own config files (either from the <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> sections in
        <code>access.conf</code>, or from defaults in <code>srm.conf</code>, which
        actually behaves for most purposes almost exactly like <code>&lt;Directory
        /&gt;</code>).</p>
    
        <p>Finally, after having served a request which involved reading
        <code>.htaccess</code> 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.</p>
    
        <h3><a name="per-dir" id="per-dir">Per-directory configuration structures</a></h3>
          <p>Let's look out how all of this plays out in <code>mod_mime.c</code>,
          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 <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code> and <code class="directive"><a href="../mod/mod_mime.html#addencoding">AddEncoding</a></code> commands. These commands can appear in
          <code>.htaccess</code> 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:</p>
    
          <div class="example"><pre>typedef struct {
        table *forced_types;      /* Additional AddTyped stuff */
        table *encoding_types;    /* Added with AddEncoding... */
    } mime_dir_config;</pre></div>
    
          <p>When the server is reading a configuration file, or <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> section, which includes
          one of the MIME module's commands, it needs to create a
          <code>mime_dir_config</code> 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
          <code>NULL</code> for <code>srm.conf</code>), and a pointer to a
          resource pool in which the allocation should happen.</p>
    
          <p>(If we are reading a <code>.htaccess</code> 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).</p>
    
          <p>For the MIME module, the per-dir config creation function just
          <code>ap_palloc</code>s the structure above, and a creates a couple of
          tables to fill it. That looks like this:</p>
    
          <div class="example"><p><code>
            void *create_mime_dir_config (pool *p, char *dummy)<br />
            {<br />
            <span class="indent">
              mime_dir_config *new =<br />
              <span class="indent">
               (mime_dir_config *) ap_palloc (p, sizeof(mime_dir_config));<br />
              </span>
              <br />
              new-&gt;forced_types = ap_make_table (p, 4);<br />
              new-&gt;encoding_types = ap_make_table (p, 4);<br />
              <br />
              return new;<br />
            </span>
            }
          </code></p></div>
    
          <p>Now, suppose we've just read in a <code>.htaccess</code> file. We
          already have the per-directory configuration structure for the next
          directory up in the hierarchy. If the <code>.htaccess</code> file we just
          read in didn't have any <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code>
          or <code class="directive"><a href="../mod/mod_mime.html#addencoding">AddEncoding</a></code> 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.</p>
    
          <p>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:</p>
    
          <div class="example"><p><code>
            void *merge_mime_dir_configs (pool *p, void *parent_dirv, void *subdirv)<br />
            {<br />
            <span class="indent">
              mime_dir_config *parent_dir = (mime_dir_config *)parent_dirv;<br />
              mime_dir_config *subdir = (mime_dir_config *)subdirv;<br />
              mime_dir_config *new =<br />
              <span class="indent">
                (mime_dir_config *)ap_palloc (p, sizeof(mime_dir_config));<br />
              </span>
              <br />
              new-&gt;forced_types = ap_overlay_tables (p, subdir-&gt;forced_types,<br />
              <span class="indent">
                parent_dir-&gt;forced_types);<br />
              </span>
              new-&gt;encoding_types = ap_overlay_tables (p, subdir-&gt;encoding_types,<br />
              <span class="indent">
                parent_dir-&gt;encoding_types);<br />
              </span>
              <br />
              return new;<br />
            </span>
            }
          </code></p></div>
    
          <p>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 (<em>e.g.</em>, for
          the includes module, whose per-directory configuration information
          consists solely of the state of the <code>XBITHACK</code>), and for those
          modules, you can just not declare one, and leave the corresponding
          structure slot in the module itself <code>NULL</code>.</p>
        
    
        <h3><a name="commands" id="commands">Command handling</a></h3>
          <p>Now that we have these structures, we need to be able to figure out how
          to fill them. That involves processing the actual <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code> and <code class="directive"><a href="../mod/mod_mime.html#addencoding">AddEncoding</a></code> 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 <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code>
          command handler, which looks like this (the <code class="directive"><a href="../mod/mod_mime.html#addencoding">AddEncoding</a></code> command looks basically the same, and won't be
          shown here):</p>
    
          <div class="example"><p><code>
            char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct, char *ext)<br />
            {<br />
            <span class="indent">
              if (*ext == '.') ++ext;<br />
              ap_table_set (m-&gt;forced_types, ext, ct);<br />
              return NULL;<br />
            </span>
            }
          </code></p></div>
    
          <p>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 <code>cmd_parms</code> 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.</p>
    
          <p>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 <code>NULL</code>;
          this causes an error to be printed out on the server's
          <code>stderr</code>, followed by a quick exit, if it is in the main config
          files; for a <code>.htaccess</code> 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).</p>
    
          <p>The MIME module's command table has entries for these commands, which
          look like this:</p>
    
          <div class="example"><p><code>
            command_rec mime_cmds[] = {<br />
            <span class="indent">
              { "AddType", add_type, NULL, OR_FILEINFO, TAKE2,<br />
              <span class="indent">"a mime type followed by a file extension" },<br /></span>
              { "AddEncoding", add_encoding, NULL, OR_FILEINFO, TAKE2,<br />
              <span class="indent">
              "an encoding (<em>e.g.</em>, gzip), followed by a file extension" },<br />
              </span>
              { NULL }<br />
            </span>
            };
          </code></p></div>
    
          <p>The entries in these tables are:</p>
          <ul>
          <li>The name of the command</li>
          <li>The function which handles it</li>
          <li>a <code>(void *)</code> pointer, which is passed in the
          <code>cmd_parms</code> structure to the command handler ---
          this is useful in case many similar commands are handled by
          the same function.</li>
    
          <li>A bit mask indicating where the command may appear. There
          are mask bits corresponding to each
          <code>AllowOverride</code> option, and an additional mask
          bit, <code>RSRC_CONF</code>, indicating that the command may
          appear in the server's own config files, but <em>not</em> in
          any <code>.htaccess</code> file.</li>
    
          <li>A flag indicating how many arguments the command handler
          wants pre-parsed, and how they should be passed in.
          <code>TAKE2</code> indicates two pre-parsed arguments. Other
          options are <code>TAKE1</code>, which indicates one
          pre-parsed argument, <code>FLAG</code>, which indicates that
          the argument should be <code>On</code> or <code>Off</code>,
          and is passed in as a boolean flag, <code>RAW_ARGS</code>,
          which causes the server to give the command the raw, unparsed
          arguments (everything but the command name itself). There is
          also <code>ITERATE</code>, which means that the handler looks
          the same as <code>TAKE1</code>, but that if multiple
          arguments are present, it should be called multiple times,
          and finally <code>ITERATE2</code>, which indicates that the
          command handler looks like a <code>TAKE2</code>, but if more
          arguments are present, then it should be called multiple
          times, holding the first argument constant.</li>
    
          <li>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 <code>NULL</code>).</li>
          </ul>
    
          <p>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 <code>request_rec</code>'s
          per-directory configuration vector by using the
          <code>ap_get_module_config</code> function.</p>
    
          <div class="example"><p><code>
            int find_ct(request_rec *r)<br />
            {<br />
            <span class="indent">
              int i;<br />
              char *fn = ap_pstrdup (r-&gt;pool, r-&gt;filename);<br />
              mime_dir_config *conf = (mime_dir_config *)<br />
              <span class="indent">
                ap_get_module_config(r-&gt;per_dir_config, &amp;mime_module);<br />
              </span>
              char *type;<br />
              <br />
              if (S_ISDIR(r-&gt;finfo.st_mode)) {<br />
              <span class="indent">
                r-&gt;content_type = DIR_MAGIC_TYPE;<br />
                return OK;<br />
              </span>
              }<br />
              <br />
              if((i=ap_rind(fn,'.')) &lt; 0) return DECLINED;<br />
              ++i;<br />
              <br />
              if ((type = ap_table_get (conf-&gt;encoding_types, &amp;fn[i])))<br />
              {<br />
              <span class="indent">
                r-&gt;content_encoding = type;<br />
                <br />
                /* go back to previous extension to try to use it as a type */<br />
                fn[i-1] = '\0';<br />
                if((i=ap_rind(fn,'.')) &lt; 0) return OK;<br />
                ++i;<br />
              </span>
              }<br />
              <br />
              if ((type = ap_table_get (conf-&gt;forced_types, &amp;fn[i])))<br />
              {<br />
              <span class="indent">
                r-&gt;content_type = type;<br />
              </span>
              }<br />
              <br />
              return OK;
            </span>
            }
          </code></p></div>
        
    
        <h3><a name="servconf" id="servconf">Side notes -- per-server configuration,
        virtual servers, <em>etc</em>.</a></h3>
          <p>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).</p>
    
          <p>The only substantial difference is that when a command needs to
          configure the per-server private module data, it needs to go to the
          <code>cmd_parms</code> 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):</p>
    
          <div class="example"><p><code>
            char *add_redirect(cmd_parms *cmd, void *dummy, char *f, char *url)<br />
            {<br />
            <span class="indent">
              server_rec *s = cmd-&gt;server;<br />
              alias_server_conf *conf = (alias_server_conf *)<br />
              <span class="indent">
                ap_get_module_config(s-&gt;module_config,&amp;alias_module);<br />
              </span>
              alias_entry *new = ap_push_array (conf-&gt;redirects);<br />
              <br />
              if (!ap_is_url (url)) return "Redirect to non-URL";<br />
              <br />
              new-&gt;fake = f; new-&gt;real = url;<br />
              return NULL;<br />
            </span>
            }
          </code></p></div>
        
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/API.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/API.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/hooks.html.en����������������������������������������������������0000664�0001751�0001751�00000032535�14737241666�021456� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Hook Functions in the Apache HTTP Server 2.x - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Hook Functions in the Apache HTTP Server 2.x</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/hooks.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <div class="warning"><h3>Warning</h3>
          <p>This document is still in development and may be partially out of
          date.</p>
        </div>
    
        <p>In general, a hook function is one that the Apache HTTP Server
        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.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#corehooks">Core Hooks</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#create">Creating a hook function</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#hooking">Hooking the hook</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="corehooks" id="corehooks">Core Hooks</a></h2>
        <p>The httpd's core modules offer a predefinined list of hooks
        used during the standard <a href="./request.html">request processing</a>
        phase. Creating a new hook will expose a function that 
        implements it (see sections below) but it is essential to understand that you will not 
        extend the httpd's core hooks. Their presence and order in the request processing is in fact 
        a consequence of how they are called in <code>server/request.c</code> 
        (check <a href="./modguide.html#hooking">this section</a> 
        for an overview). The core hooks are listed in the 
        <a href="https://ci.apache.org/projects/httpd/trunk/doxygen/group__hooks.html">doxygen documentation</a>.</p>
    
        <p>Reading <a href="./modguide.html">guide for developing modules</a> and 
        <a href="./request.html">request processing</a> before proceeding is 
        highly recommended.
        </p> 
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="create" id="create">Creating a hook function</a></h2>
        <p>In order to create a new hook, four things need to be
        done:</p>
    
        <h3><a name="create-declare" id="create-declare">Declare the hook function</a></h3>
          <p>Use the <code>AP_DECLARE_HOOK</code> 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 <code>int</code> and
          takes a <code>request_rec *</code> and an <code>int</code> and is
          called <code>do_something</code>, then declare it like this:</p>
          <pre class="prettyprint lang-c">AP_DECLARE_HOOK(int, do_something, (request_rec *r, int n))</pre>
    
    
          <p>This should go in a header which modules will include if
          they want to use the hook.</p>
        
    
        <h3><a name="create-create" id="create-create">Create the hook structure</a></h3>
          <p>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:</p>
    
          <pre class="prettyprint lang-c">APR_HOOK_STRUCT(
      APR_HOOK_LINK(do_something)
      ...
    )</pre>
    
        
    
        <h3><a name="create-implement" id="create-implement">Implement the hook caller</a></h3>
          <p>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 <code>ap_run_<var>hookname</var>()</code>.</p>
    
          <h4>Void hooks</h4>
            <p>If the return value of a hook is <code>void</code>, then all the
            hooks are called, and the caller is implemented like this:</p>
    
            <pre class="prettyprint lang-c">AP_IMPLEMENT_HOOK_VOID(do_something, (request_rec *r, int n), (r, n))</pre>
    
    
            <p>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:</p>
    
            <pre class="prettyprint lang-c">void ap_run_do_something(request_rec *r, int n)
    {
        ...
        do_something(r, n);
    }</pre>
    
          
    
          <h4>Hooks that return a value</h4>
            <p>If the hook returns a value, then it can either be run until
            the first hook that does something interesting, like so:</p>
    
            <pre class="prettyprint lang-c">AP_IMPLEMENT_HOOK_RUN_FIRST(int, do_something, (request_rec *r, int n), (r, n), DECLINED)</pre>
    
    
            <p>The first hook that does <em>not</em> return <code>DECLINED</code>
            stops the loop and its return value is returned from the hook
            caller. Note that <code>DECLINED</code> is the traditional
            hook return value meaning "I didn't do anything", but it can be
            whatever suits you.</p>
    
            <p>Alternatively, all hooks can be run until an error occurs.
            This boils down to permitting <em>two</em> 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:</p>
    
            <pre class="prettyprint lang-c">AP_IMPLEMENT_HOOK_RUN_ALL(int, do_something, (request_rec *r, int n), (r, n), OK, DECLINED)</pre>
    
    
            <p>Again, <code>OK</code> and <code>DECLINED</code> are the traditional
            values. You can use what you want.</p>
          
        
    
        <h3><a name="create-call" id="create-call">Call the hook callers</a></h3>
          <p>At appropriate moments in the code, call the hook caller,
          like so:</p>
    
          <pre class="prettyprint lang-c">int n, ret;
    request_rec *r;
    
    ret=ap_run_do_something(r, n);</pre>
    
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hooking" id="hooking">Hooking the hook</a></h2>
        <p>A module that wants a hook to be called needs to do two
        things.</p>
    
        <h3><a name="hooking-implement" id="hooking-implement">Implement the hook function</a></h3>
          <p>Include the appropriate header, and define a static function
          of the correct type:</p>
    
          <pre class="prettyprint lang-c">static int my_something_doer(request_rec *r, int n)
    {
        ...
        return OK;
    }</pre>
    
        
    
        <h3><a name="hooking-add" id="hooking-add">Add a hook registering function</a></h3>
          <p>During initialisation, the server will call each modules hook
          registering function, which is included in the module
          structure:</p>
    
          <pre class="prettyprint lang-c">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 */
    };</pre>
    
        
    
        <h3><a name="hooking-order" id="hooking-order">Controlling hook calling order</a></h3>
          <p>In the example above, we didn't use the three arguments in
          the hook registration function that control calling order of 
          all the functions registered within the hook.
          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: <code>APR_HOOK_FIRST</code>,
          <code>APR_HOOK_MIDDLE</code> and <code>APR_HOOK_LAST</code>.</p>
    
          <p>All modules using any particular value may be run in any
          order relative to each other, but, of course, all modules using
          <code>APR_HOOK_FIRST</code> will be run before <code>APR_HOOK_MIDDLE</code>
          which are before <code>APR_HOOK_LAST</code>. Modules that don't care
          when they are run should use <code>APR_HOOK_MIDDLE</code>. <em>These
          values are spaced out, so that positions like <code>APR_HOOK_FIRST-2</code>
          are possible to hook slightly earlier than other functions.</em></p>
    
          <p>Note that there are two more values,
          <code>APR_HOOK_REALLY_FIRST</code> and <code>APR_HOOK_REALLY_LAST</code>. These
          should only be used by the hook exporter.</p>
    
          <p>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:</p>
    
          <pre class="prettyprint lang-c">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);
    }</pre>
    
    
          <p>Note that the sort used to achieve this is stable, so
          ordering set by <code>APR_HOOK_<var>ORDER</var></code> is preserved, as far
          as is possible.</p>
    
        
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/hooks.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/hooks.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/new_api_2_4.html.en����������������������������������������������0000664�0001751�0001751�00000072253�14737241666�022422� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>API Changes in Apache HTTP Server 2.4 since 2.2 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>API Changes in Apache HTTP Server 2.4 since 2.2</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/new_api_2_4.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
      <p>This document describes changes to the Apache HTTPD API from
         version 2.2 to 2.4, that may be of interest to module/application
         developers and core hacks.  As of the first GA release of the
         2.4 branch API compatibility is preserved for the life of the
         2.4 branch.  (The
         <a href="http://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x/VERSIONING">VERSIONING</a>
         description for the 2.4 release provides more information about API
         compatibility.)</p>
    
      <p>API changes fall into two categories: APIs that are altogether new,
         and existing APIs that are expanded or changed.  The latter are
         further divided into those where all changes are backwards-compatible
         (so existing modules can ignore them), and those that might
         require attention by maintainers.  As with the transition from
         HTTPD 2.0 to 2.2, existing modules and applications will require
         recompiling and may call for some attention, but most should not
         require any substantial updating (although some may be able to
         take advantage of API changes to offer significant improvements).</p>
      <p>For the purpose of this document, the API is split according
         to the public header files.  These headers are themselves the
         reference documentation, and can be used to generate a browsable
         HTML reference with <code>make docs</code>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#api_changes">Changed APIs</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#upgrading">Specific information on upgrading modules from 2.2</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="api_changes" id="api_changes">Changed APIs</a></h2>
      
    
      <h3><a name="ap_expr" id="ap_expr">ap_expr (NEW!)</a></h3>
        
        <p>Introduces a new API to parse and evaluate boolean and algebraic
           expressions, including provision for a standard syntax and
           customised variants.</p>
      
    
      <h3><a name="ap_listen" id="ap_listen">ap_listen (changed; backwards-compatible)</a></h3>
        
        <p>Introduces a new API to enable httpd child processes to serve
           different purposes.</p>
      
    
      <h3><a name="ap_mpm" id="ap_mpm">ap_mpm (changed)</a></h3>
        
      <p><code>ap_mpm_run</code> is replaced by a new <code>mpm</code> hook.
      Also <code>ap_graceful_stop_signalled</code> is lost, and
      <code>ap_mpm_register_timed_callback</code> is new.</p>
      
    
      <h3><a name="ap_regex" id="ap_regex">ap_regex (changed)</a></h3>
        
      <p>In addition to the existing regexp wrapper, a new higher-level API
      <code>ap_rxplus</code> is now provided.  This provides the capability to
      compile Perl-style expressions like <code>s/regexp/replacement/flags</code>
      and to execute them against arbitrary strings. Support for regexp
      backreferences is also added.</p>
      
    
      <h3><a name="ap_slotmem" id="ap_slotmem">ap_slotmem (NEW!)</a></h3>
        
        <p>Introduces an API for modules to allocate and manage memory slots,
        most commonly for shared memory.</p>
      
    
      <h3><a name="ap_socache" id="ap_socache">ap_socache (NEW!)</a></h3>
        
        <p>API to manage a shared object cache.</p>
      
    
      <h3><a name="heartbeat" id="heartbeat">heartbeat (NEW!)</a></h3>
        
        <p>common structures for heartbeat modules</p>
      
    
      <h3><a name="ap_parse_htaccess" id="ap_parse_htaccess">ap_parse_htaccess (changed)</a></h3>
        
        <p>The function signature for <code>ap_parse_htaccess</code> has been
        changed. A <code>apr_table_t</code> of individual directives allowed
        for override must now be passed (override remains).</p>
      
    
      <h3><a name="http_config" id="http_config">http_config (changed)</a></h3>
        
        <ul>
          <li>Introduces per-module, per-directory loglevels, including macro wrappers.</li>
          <li>New <code>AP_DECLARE_MODULE</code> macro to declare all modules.</li>
          <li>New <code>APLOG_USE_MODULE</code> macro necessary for per-module loglevels in
              multi-file modules.</li>
          <li>New API to retain data across module unload/load</li>
          <li>New <code>check_config</code> hook</li>
          <li>New <code>ap_process_fnmatch_configs()</code> function to process wildcards</li>
          <li>Change <code>ap_configfile_t</code>, <code>ap_cfg_getline()</code>,
              <code>ap_cfg_getc()</code> to return error codes, and add
              <code>ap_pcfg_strerror()</code> for retrieving an error description.</li>
          <li>Any config directive permitted in ACCESS_CONF context must now
              correctly handle being called from an .htaccess file via the new
              <code class="directive"><a href="../mod/core.html#allowoverridelist">AllowOverrideList</a></code> directive.
              ap_check_cmd_context() accepts a new flag NOT_IN_HTACCESS to detect
              this case.</li>
        </ul>
      
    
      <h3><a name="http_core" id="http_core">http_core (changed)</a></h3>
        
        <ul>
          <li>REMOVED <code>ap_default_type</code>, <code>ap_requires</code>, all
              2.2 authnz API</li>
          <li>Introduces Optional Functions for logio and authnz</li>
          <li>New function <code>ap_get_server_name_for_url</code> to support IPv6
              literals.</li>
          <li>New function <code>ap_register_errorlog_handler</code> to register error log
              format string handlers.</li>
          <li>Arguments of <code>error_log</code> hook have changed. Declaration has moved to
              <code>http_core.h</code>.</li>
          <li>New function <code>ap_state_query</code> to determine if the server is in the
              initial configuration preflight phase or not. This is both easier to
              use and more correct than the old method of creating a pool userdata
              entry in the process pool.</li>
          <li>New function <code>ap_get_conn_socket</code> to get the socket descriptor for a
              connection. This should be used instead of accessing the core
              connection config directly.</li>
        </ul>
      
    
      <h3><a name="httpd" id="httpd">httpd (changed)</a></h3>
        
        <ul>
          <li>Introduce per-directory, per-module loglevel</li>
          <li>New loglevels <code>APLOG_TRACEn</code></li>
          <li>Introduce errorlog ids for requests and connections</li>
          <li>Support for mod_request kept_body</li>
          <li>Support buffering filter data for async requests</li>
          <li>New <code>CONN_STATE</code> values</li>
          <li>Function changes: <code>ap_escape_html</code> updated;
              <code>ap_unescape_all</code>, <code>ap_escape_path_segment_buffer</code></li>
          <li>Modules that load other modules later than the <code>EXEC_ON_READ</code> config
              reading stage need to call <code>ap_reserve_module_slots()</code> or
              <code>ap_reserve_module_slots_directive()</code> in their
              <code>pre_config hook</code>.</li>
          <li>The useragent IP address per request can now be tracked
              independently of the client IP address of the connection, for
              support of deployments with load balancers.</li>
        </ul>
      
    
      <h3><a name="http_log" id="http_log">http_log (changed)</a></h3>
        
        <ul>
          <li>Introduce per-directory, per-module loglevel</li>
          <li>New loglevels <code>APLOG_TRACEn</code></li>
          <li><code>ap_log_*error</code> become macro wrappers (backwards-compatible if
              <code>APLOG_MARK</code> macro is used, except that is no longer possible to
              use <code>#ifdef</code> inside the argument list)</li>
          <li>piped logging revamped</li>
          <li><code>module_index</code> added to error_log hook</li>
          <li>new function: <code>ap_log_command_line</code></li>
        </ul>
      
    
      <h3><a name="http_request" id="http_request">http_request (changed)</a></h3>
        
        <ul>
          <li>New auth_internal API and auth_provider API</li>
          <li>New <code>EOR</code> bucket type</li>
          <li>New function <code>ap_process_async_request</code></li>
          <li>New flags <code>AP_AUTH_INTERNAL_PER_CONF</code> and
              <code>AP_AUTH_INTERNAL_PER_URI</code></li>
          <li>New <code>access_checker_ex</code> hook to apply additional access control
              and/or bypass authentication.</li>
          <li>New functions <code>ap_hook_check_access_ex</code>,
              <code>ap_hook_check_access</code>, <code>ap_hook_check_authn</code>,
              <code>ap_hook_check_authz</code> which accept
              <code>AP_AUTH_INTERNAL_PER_*</code> flags</li>
          <li>DEPRECATED direct use of <code>ap_hook_access_checker</code>,
              <code>access_checker_ex</code>, <code>ap_hook_check_user_id</code>,
              <code>ap_hook_auth_checker</code></li>
        </ul>
        <p>When possible, registering all access control hooks (including
           authentication and authorization hooks) using <code>AP_AUTH_INTERNAL_PER_CONF</code>
           is recommended.  If all modules' access control hooks are registered
           with this flag, then whenever the server handles an internal
           sub-request that matches the same set of access control configuration
           directives as the initial request (which is the common case), it can
           avoid invoking the access control hooks another time.</p>
        <p>If your module requires the old behavior and must perform access
           control checks on every sub-request with a different URI from the
           initial request, even if that URI matches the same set of access
           control configuration directives, then use
           <code>AP_AUTH_INTERNAL_PER_URI</code>.</p>
      
    
      <h3><a name="mod_auth" id="mod_auth">mod_auth (NEW!)</a></h3>
        
        <p>Introduces the new provider framework for authn and authz</p>
      
    
      <h3><a name="mod_cache" id="mod_cache">mod_cache (changed)</a></h3>
        
        <p>Introduces a <code>commit_entity()</code> function to the cache provider
        interface, allowing atomic writes to cache. Add a <code>cache_status()</code>
        hook to report the cache decision. All private structures and functions were
        removed.</p>
      
    
      <h3><a name="mod_core" id="mod_core">mod_core (NEW!)</a></h3>
        
        <p>This introduces low-level APIs to send arbitrary headers,
        and exposes functions to handle HTTP OPTIONS and TRACE.</p>
      
    
      <h3><a name="mod_cache_disk" id="mod_cache_disk">mod_cache_disk (changed)</a></h3>
        
        <p>Changes the disk format of the disk cache to support atomic cache
        updates without locking. The device/inode pair of the body file is
        embedded in the header file, allowing confirmation that the header
        and body belong to one another.</p>
      
    
      <h3><a name="mod_disk_cache" id="mod_disk_cache">mod_disk_cache (renamed)</a></h3>
        
        <p>The mod_disk_cache module has been renamed to mod_cache_disk in
        order to be consistent with the naming of other modules within the
        server.</p>
      
    
      <h3><a name="mod_request" id="mod_request">mod_request (NEW!)</a></h3>
        
        <p>The API for <code class="module"><a href="../mod/mod_request.html">mod_request</a></code>, to make input data
        available to multiple application/handler modules where required,
        and to parse HTML form data.</p>
      
    
      <h3><a name="mpm_common" id="mpm_common">mpm_common (changed)</a></h3>
        
        <ul>
          <li>REMOVES: <code>accept</code>, <code>lockfile</code>, <code>lock_mech</code>,
              <code>set_scoreboard</code> (locking uses the new ap_mutex API)</li>
          <li>NEW API to drop privileges (delegates this platform-dependent
              function to modules)</li>
          <li>NEW Hooks: <code>mpm_query</code>, <code>timed_callback</code>, and
              <code>get_name</code></li>
          <li>CHANGED interfaces: <code>monitor</code> hook,
              <code>ap_reclaim_child_processes</code>,
              <code>ap_relieve_child_processes</code></li>
        </ul>
      
    
      <h3><a name="scoreboard" id="scoreboard">scoreboard (changed)</a></h3>
        
        <p><code>ap_get_scoreboard_worker</code> is made non-backwards-compatible
        as an alternative version is introduced.  Additional proxy_balancer
        support.  Child status stuff revamped.</p>
      
    
      <h3><a name="util_cookies" id="util_cookies">util_cookies (NEW!)</a></h3>
        
        <p>Introduces a new API for managing HTTP Cookies.</p>
      
    
      <h3><a name="util_ldap" id="util_ldap">util_ldap (changed)</a></h3>
        
        <p><em>no description available</em></p>
      
    
      <h3><a name="util_mutex" id="util_mutex">util_mutex (NEW!)</a></h3>
        
        <p>A wrapper for APR proc and global mutexes in httpd, providing
           common configuration for the underlying mechanism and location
           of lock files.</p>
      
    
      <h3><a name="util_script" id="util_script">util_script (changed)</a></h3>
        
        <p>NEW: <code>ap_args_to_table</code></p>
      
    
      <h3><a name="util_time" id="util_time">util_time (changed)</a></h3>
        
        <p>NEW: <code>ap_recent_ctime_ex</code></p>
      
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">Specific information on upgrading modules from 2.2</a></h2>
      
    
      <h3><a name="upgrading_logging" id="upgrading_logging">Logging</a></h3>
        
        <p>In order to take advantage of per-module loglevel configuration, any
           source file that calls the <code>ap_log_*</code> functions should declare
           which module it belongs to. If the module's module_struct is called
           <code>foo_module</code>, the following code can be used to remain
           backward compatible with HTTPD 2.0 and 2.2:</p>
        <div class="example"><p><code>
            #include &lt;http_log.h&gt;<br />
            <br />
            #ifdef APLOG_USE_MODULE<br />
            APLOG_USE_MODULE(foo);<br />
            #endif
        </code></p></div>
        <p>Note: This is absolutely required for C++-language modules.  It
        can be skipped for C-language modules, though that breaks
        module-specific log level support for files without it.</p>
        <p>The number of parameters of the <code>ap_log_*</code> functions and the
           definition of <code>APLOG_MARK</code> has changed. Normally, the change
           is completely transparent. However, changes are required if a
           module uses <code>APLOG_MARK</code> as a parameter to its own functions
           or if a module calls <code>ap_log_*</code> without passing
           <code>APLOG_MARK</code>.  A module which uses wrappers
           around <code>ap_log_*</code> typically uses both of these constructs.</p>
    
        <p>The easiest way to change code which passes <code>APLOG_MARK</code> to
           its own functions is to define and use a different macro that expands to
           the parameters required by those functions, as <code>APLOG_MARK</code>
           should only be used when calling <code>ap_log_*</code>
           directly.  In this way, the code will remain compatible with HTTPD 2.0
           and 2.2.</p>
    
        <p>Code which calls <code>ap_log_*</code> without passing
           <code>APLOG_MARK</code> will necessarily differ between 2.4 and earlier
           releases, as 2.4 requires a new third argument,
           <code>APLOG_MODULE_INDEX</code>.</p>
    
        <div class="example"><p><code>
           /* code for httpd 2.0/2.2 */<br />
           ap_log_perror(file, line, APLOG_ERR, 0, p, "Failed to allocate dynamic lock structure");<br />
           <br />
           /* code for httpd 2.4 */<br />
           ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, 0, p, "Failed to allocate dynamic lock structure");<br />
           <br />
        </code></p></div>
    
        <p><code>ap_log_*error</code> are now implemented as macros. This means
           that it is no longer possible to use <code>#ifdef</code> inside the
           argument list of <code>ap_log_*error</code>, as this would cause
           undefined behavior according to C99.</p>
    
        <p>A <code>server_rec</code> pointer must be passed to
           <code>ap_log_error()</code> when called after startup.  This
           was always appropriate, but there are even more limitations with
           a <code>NULL</code> <code>server_rec</code> in 2.4 than in
           previous releases.  Beginning with 2.3.12, the global variable
           <code>ap_server_conf</code> can always be used as
           the <code>server_rec</code> parameter, as it will be
           <code>NULL</code> only when it is valid to pass <code>NULL</code>
           to <code>ap_log_error()</code>.  <code>ap_server_conf</code>
           should be used only when a more appropriate <code>server_rec</code>
           is not available.</p>
    
        <p>Consider the following changes to take advantage of the new
           <code>APLOG_TRACE1..8</code> log levels:</p>
           <ul>
             <li>Check current use of <code>APLOG_DEBUG</code> and
             consider if one of the <code>APLOG_TRACEn</code> levels is
             more appropriate.</li>
             <li>If your module currently has a mechanism for configuring
             the amount of debug logging which is performed, consider
             eliminating that mechanism and relying on the use of
             different <code>APLOG_TRACEn</code> levels.  If expensive
             trace processing needs to be bypassed depending on the
             configured log level, use the <code>APLOGtrace<em>n</em></code>
             and <code>APLOGrtrace<em>n</em></code> macros to first check
             if tracing is enabled.</li>
           </ul>
    
        <p>Modules sometimes add process id and/or thread id to their log
           messages.  These ids are now logged by default, so it may not
           be necessary for the module to log them explicitly.  (Users may
           remove them from the error log format, but they can be
           instructed to add it back if necessary for problem diagnosis.)</p>
      
    
      <h3><a name="upgrading_byfunction" id="upgrading_byfunction">If your module uses these existing APIs...</a></h3>
        
    
        <dl>
          <dt><code>ap_default_type()</code></dt>
          <dd>This is no longer available; Content-Type must be configured
              explicitly or added by the application.</dd>
    
          <dt><code>ap_get_server_name()</code></dt>
          <dd>If the returned server name is used in a URL,
          use <code>ap_get_server_name_for_url()</code> instead.  This new
          function handles the odd case where the server name is an IPv6
          literal address.</dd>
    
          <dt><code>ap_get_server_version()</code></dt>
          <dd>For logging purposes, where detailed information is
              appropriate, use <code>ap_get_server_description()</code>.
              When generating output, where the amount of information
              should be configurable by ServerTokens, use
              <code>ap_get_server_banner()</code>.</dd>
    
          <dt><code>ap_graceful_stop_signalled()</code></dt>
          <dd>Replace with a call
          to <code>ap_mpm_query(AP_MPMQ_MPM_STATE)</code> and checking for
          state <code>AP_MPMQ_STOPPING</code>.</dd>
    
          <dt><code>ap_max_daemons_limit</code>, <code>ap_my_generation</code>,
              and <code>ap_threads_per_child</code></dt>
          <dd>Use <code>ap_mpm_query()</code> query codes
              <code>AP_MPMQ_MAX_DAEMON_USED</code>, <code>AP_MPMQ_GENERATION</code>,
              and <code>AP_MPMQ_MAX_THREADS</code>, respectively.</dd>
    
          <dt><code>ap_mpm_query()</code></dt>
          <dd>Ensure that it is not used until after the register-hooks
              hook has completed.  Otherwise, an MPM built as a DSO
              would not have had a chance to enable support for this
              function.</dd>
    
          <dt><code>ap_requires()</code></dt>
          <dd>The core server now provides better infrastructure for handling
              <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> configuration.
              Register an auth provider function for each supported entity using
              <code>ap_register_auth_provider()</code>.  The function will be
              called as necessary during <code class="directive">Require</code>
              processing.  (Consult bundled modules for detailed examples.)</dd>
    
          <dt><code>ap_server_conf-&gt;process-&gt;pool</code>
          userdata</dt>
          <dd>
            Optional:
            <ul>
              <li>If your module uses this to determine which pass of the
    	  startup hooks is being run,
    	  use <code>ap_state_query(AP_SQ_MAIN_STATE)</code>.</li>
              <li>If your module uses this to maintain data across the
              unloading and reloading of your module, use
              <code>ap_retained_data_create()</code> and
              <code>ap_retained_data_get()</code>.</li>
            </ul>
          </dd>
    
          <dt><code>apr_global_mutex_create()</code>,
              <code>apr_proc_mutex_create()</code></dt>
          <dd>Optional: See <code>ap_mutex_register()</code>,
              <code>ap_global_mutex_create()</code>, and
              <code>ap_proc_mutex_create()</code>; these allow your
              mutexes to be configurable with
              the <code class="directive"><a href="../mod/core.html#mutex">Mutex</a></code> directive;
              you can also remove any configuration mechanisms in your
              module for such mutexes
          </dd>
    
          <dt><code>CORE_PRIVATE</code></dt>
          <dd>This is now unnecessary and ignored.</dd>
    
          <dt><code>dav_new_error()</code>
          and <code>dav_new_error_tag()</code></dt>
          <dd>Previously, these assumed that <code>errno</code> contained
          information describing the failure.  Now,
          an <code>apr_status_t</code> parameter must be provided.  Pass
          0/APR_SUCCESS if there is no such error information, or a valid
          <code>apr_status_t</code> value otherwise.</dd>
    
          <dt><code>mpm_default.h</code>, <code>DEFAULT_LOCKFILE</code>,
          <code>DEFAULT_THREAD_LIMIT</code>, <code>DEFAULT_PIDLOG</code>,
          etc.</dt>
          <dd>The header file and most of the default configuration
          values set in it are no longer visible to modules.  (Most can
          still be overridden at build time.)  <code>DEFAULT_PIDLOG</code>
          and <code>DEFAULT_REL_RUNTIMEDIR</code> are now universally
          available via <code>ap_config.h</code>.</dd>
    
          <dt><code>unixd_config</code></dt>
          <dd>This has been renamed to ap_unixd_config.</dd>
    
          <dt><code>unixd_setup_child()</code></dt>
          <dd>This has been renamed to ap_unixd_setup_child(), but most callers
              should call the added ap_run_drop_privileges() hook.</dd>
    
          <dt><code>conn_rec-&gt;remote_ip</code> and
              <code>conn_rec-&gt;remote_addr</code></dt>
          <dd>These fields have been renamed in order to distinguish between
          the client IP address of the connection and the useragent IP address
          of the request (potentially overridden by a load balancer or proxy).
          References to either of these fields must be updated with one of the
          following options, as appropriate for the module:
          <ul>
            <li>When you require the IP address of the user agent, which
            might be connected directly to the server, or might optionally be
            separated from the server by a transparent load balancer or
            proxy, use <code>request_rec-&gt;useragent_ip</code> and
            <code>request_rec-&gt;useragent_addr</code>.</li>
            <li>When you require the IP address of the client that is
            connected directly to the server, which might be the useragent or
            might be the load balancer or proxy itself, use
            <code>conn_rec-&gt;client_ip</code> and
            <code>conn_rec-&gt;client_addr</code>.</li>
          </ul>
          </dd>
        </dl>
      
    
      <h3><a name="upgrading_byfeature" id="upgrading_byfeature">If your module interfaces with this feature...</a></h3>
        
        <dl>
          <dt>suEXEC</dt>
          <dd>Optional: If your module logs an error
              when <code>ap_unixd_config.suexec_enabled</code> is 0,
              also log the value of the new
              field <code>suexec_disabled_reason</code>, which contains an
              explanation of why it is not available.</dd>
    
          <dt>Extended status data in the scoreboard</dt>
          <dd>In previous releases, <code>ExtendedStatus</code> had to be
              set to <code>On</code>, which in turn required that
              mod_status was loaded.  In 2.4, just
              set <code>ap_extended_status</code> to <code>1</code> in a
              pre-config hook and the extended status data will be
              available.</dd>
        </dl>
      
    
      <h3><a name="upgrading_newfeatures" id="upgrading_newfeatures">Does your module...</a></h3>
        
        <dl>
        <dt>Parse query args</dt>
        <dd>Consider if <code>ap_args_to_table()</code> would be
        helpful.</dd>
    
        <dt>Parse form data...</dt>
        <dd>Use <code>ap_parse_form_data()</code>.</dd>
    
        <dt>Check for request header fields <code>Content-Length</code>
        and <code>Transfer-Encoding</code> to see if a body was
        specified</dt>
        <dd>Use <code>ap_request_has_body()</code>.</dd>
    
        <dt>Implement cleanups which clear pointer variables</dt>
        <dd>Use <code>ap_pool_cleanup_set_null()</code>.</dd>
    
        <dt>Create run-time files such as shared memory files, pid files,
        etc.</dt>
        <dd>Use <code>ap_runtime_dir_relative()</code> so that the global
        configuration for the location of such files, either by the
        <code>DEFAULT_REL_RUNTIMEDIR</code> compile setting or the
        <code class="directive"><a href="../mod/core.html#defaultruntimedir">DefaultRuntimeDir</a></code> directive,
        will be respected.  <em>Apache httpd 2.4.2 and above.</em></dd>
    
        </dl>
      
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/new_api_2_4.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/new_api_2_4.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/modules.html.ja.utf8���������������������������������������������0000664�0001751�0001751�00000037445�14743132254�022652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>モジュールの Apache 1.3 から Apache 2.0 への移植 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>モジュールの Apache 1.3 から Apache 2.0 への移植</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/developer/modules.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../ja/developer/modules.html" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>この文書は <code>mod_mmap_static</code> モジュールを Apache 2.0 用に移植した時に
        学んだ経験をもとに書いた、最初の手引き書です。まだまだ完全じゃないし、
        ひょっとすると間違っている部分もあるかもしれませんが、
        取っ掛りにはなるでしょう。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#easy">簡単な変更点</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#messy">もっと厄介な変更点…</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="easy" id="easy">簡単な変更点</a></h2>
    
        <h3><a name="cleanup" id="cleanup">クリーンナップ ルーチン</a></h3>
          <p>クリーンナップルーチンは <code>apr_status_t</code> 型である必要があります。
          そして、apr_status_t 型の値を返さなくてはなりません。
          クリーンナップ中のエラーを通知する必要がなければ、返り値は普通、
          <code>ARP_SUCCESS</code> です。たとえエラーを通知したとしても、
          すべてのコードがその通知をチェックしたり、
          エラーに応じた動作をするわけではないことに気をつけてください。</p>
        
    
    
        <h3><a name="init" id="init">初期化ルーチン</a></h3>
    
        <p>初期化ルーチンは処理全体から見てしっくりくるような意味を表すように、
        名前が変更されました。ですから、<code>mmap_init</code> から <code>mmap_post_config</code>
        のようにちょっと変更されました。
        渡される引数は大幅に変更され、次のようになりました。</p>
    
          <ul>
            <li><code>apr_pool_t *p</code></li>
            <li><code>apr_pool_t *plog</code></li>
            <li><code>apr_pool_t *ptemp</code></li>
            <li><code>server_rec *s</code></li>
          </ul>
        
    
        <h3><a name="datatypes" id="datatypes">データ型</a></h3>
          <p>データ型のほとんどは <a href="http://apr.apache.org/">APR</a> に移されました。つまり、
          いくつかの名前が前述のように変更されています。
          施すべき変更点の簡単な一覧を以下に示します。</p>
    
          <ul>
            <li><code>pool</code> becomes <code>apr_pool_t</code></li>
            <li><code>table</code> becomes <code>apr_table_t</code></li>
          </ul>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="messy" id="messy">もっと厄介な変更点…</a></h2>
    
        <h3><a name="register-hooks" id="register-hooks">フックの登録</a></h3>
          <p>新しいアーキテクチャでは作成した関数を呼び出すのに
          一連のフックを使用します。このフックは、新しい関数
          <code>static void register_hooks(void)</code> を使って登録するよう、
          モジュールに書き足さなくてはなりません。
          この関数は、なにをすべきか一旦理解してしまえば、
          十分にわかりやすいものです。
          リクエストの処理のあるステージで呼び出さなくてはならない
          関数は登録する必要があります。ハンドラは登録する必要はありません。
          関数を登録できるフェーズはたくさんあります。
          それぞれのフェーズで、関数を呼び出す相対的な順番は、
          かなりの程度制御できます。</p>
    
        <p>以下は、<code>mod_mmap_static</code> に追加したコードです:</p>
    
          <div class="example"><pre>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);
    };</pre></div>
    
        <p>ここでは呼びだすべき二つの関数を登録しています。一つは
        <code>post_config</code> ステージ用 (ほとんどすべてのモジュール
        はこれが必要です) で、もう一つは <code>translate_name</code> フェーズ用です。
        それぞれの関数は名前は違うけれども形式は同じであることに注意してください。
        それでは、形式はどのようになっているでしょうか?</p>
    
          <div class="example"><p><code>
            ap_hook_<var>phase_name</var>(<var>function_name</var>,
            <var>predecessors</var>, <var>successors</var>, <var>position</var>);
          </code></p></div>
    
        <p>三つの位置が定義されています…</p>
    
          <ul>
            <li><code>HOOK_FIRST</code></li>
            <li><code>HOOK_MIDDLE</code></li>
            <li><code>HOOK_LAST</code></li>
          </ul>
    
        <p>位置を定義するには、上記の「位置」を指定し、
        修飾子である「先行」と「後行」で手を加えます。
       「先行」「後行」は、呼ばれるべき関数のリストです。
       「先行」は関数の実行前に呼ばれるもので、
       「後行」は実行後に呼ばれるものです。</p>
    
        <p><code>mod_mmap_static</code> の場合、<code>post_config</code>
        ステージでは必要ありませんが、
        <code>mmap_static_xlat</code> が core モジュールが名前の変換を実行した後に
        <strong>呼ばれなければなりません</strong>。
        そこで aszPre を使って <code>HOOK_LAST</code> の修飾子を定義しています。</p>
      
    
        <h3><a name="moddef" id="moddef">モジュールの定義</a></h3>
          <p>モジュールの定義を作成する際に注意しなければならない
          ステージの数は激減しています。古い定義は次のようになっていました。</p>
    
          <div class="example"><pre>module MODULE_VAR_EXPORT <var>module_name</var>_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 */
    };</pre></div>
    
        <p>新しい構造体はとってもシンプルです…</p>
          <div class="example"><pre>module MODULE_VAR_EXPORT <var>module_name</var>_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 */
    };</pre></div>
    
        <p>このうちのいくつかは古いものから新しいものに直接読み替えられるもので、
        いくつかはそうではありません。どうすればいいのかを要約してみます。</p>
    
        <p>直接読み替えられるステージ:</p>
    
        <dl>
          <dt><code>/* ディレクトリ設定作成関数 */</code></dt>
          <dd><code>/* ディレクトリ毎設定構造体作成 */</code></dd>
    
          <dt><code>/* サーバ設定作成関数 */</code></dt>
          <dd><code>/* サーバ毎設定構造体作成 */</code></dd>
    
          <dt><code>/* ディレクトリ設定マージ関数 */</code></dt>
          <dd><code>/* ディレクトリ毎設定構造体マージ */</code></dd>
    
          <dt><code>/* サーバ設定マージ関数 */</code></dt>
          <dd><code>/* サーバ毎設定構造体作成マージ */</code></dd>
    
          <dt><code>/* コマンド・テーブル */</code></dt>
          <dd><code>/* コマンド apr_table_t */</code></dd>
    
          <dt><code>/* ハンドラ */</code></dt>
          <dd><code>/* ハンドラ */</code></dd>
        </dl>
    
        <p>古い関数の残りのものはフックとして登録されるべきです。
        現時点で次のようなフック・ステージが定義されています…</p>
    
        <dl>
          <dt><code>ap_hook_post_config</code></dt>
          <dd>(以前の <code>_init</code> ルーチンが登録されるべき場所です)</dd>
    
          <dt><code>ap_hook_http_method</code></dt>
          <dd>(リクエストから HTTP メソッドを取得します (互換用))</dd>
    
          <dt><code>ap_hook_open_logs</code></dt>
          <dd>(特定のログのオープン)</dd>
    
          <dt><code>ap_hook_auth_checker</code></dt>
          <dd>(リソースが権限を必要とするかどうかの確認)</dd>
    
          <dt><code>ap_hook_access_checker</code></dt>
          <dd>(モジュール固有の制約の確認)</dd>
    
          <dt><code>ap_hook_check_user_id</code></dt>
          <dd>(ユーザ ID とパスワードの確認)</dd>
    
          <dt><code>ap_hook_default_port</code></dt>
          <dd>(サーバのデフォルト・ポートの取得)</dd>
    
          <dt><code>ap_hook_pre_connection</code></dt>
          <dd>(処理の直前に必要なことを実行。ただし accept 直後に呼ばれる)</dd>
    
          <dt><code>ap_hook_process_connection</code></dt>
          <dd>(プロトコルの処理)</dd>
    
          <dt><code>ap_hook_child_init</code></dt>
          <dd>(子プロセル起動直後)</dd>
    
          <dt><code>ap_hook_create_request</code></dt>
          <dd>(??)</dd>
    
          <dt><code>ap_hook_fixups</code></dt>
          <dd>(応答内容の生成を変更するラスト・チャンス)</dd>
    
          <dt><code>ap_hook_handler</code></dt>
          <dd>(応答内容の生成)</dd>
    
          <dt><code>ap_hook_header_parser</code></dt>
          <dd>(モジュールにヘッダの照会をさせる。ほとんどのモジュールでは使われません。post_read_request を使います)</dd>
    
          <dt><code>ap_hook_insert_filter</code></dt>
          <dd>(フィルタ・チェインにフィルタを挿入)</dd>
    
          <dt><code>ap_hook_log_transaction</code></dt>
          <dd>(リクエストについての情報を記録する)</dd>
    
          <dt><code>ap_hook_optional_fn_retrieve</code></dt>
          <dd>(オプションとして登録された関数の取得)</dd>
    
          <dt><code>ap_hook_post_read_request</code></dt>
          <dd>(リクエストを読みこんだ後、他のフェーズの前に呼ばれる)</dd>
    
          <dt><code>ap_hook_quick_handler</code></dt>
          <dd>リクエストの処理が始まる前に呼ばれる。キャッシュモジュールが
          使用している</dd>
    
          <dt><code>ap_hook_translate_name</code></dt>
          <dd>(URI をファイル名に変換する)</dd>
    
          <dt><code>ap_hook_type_checker</code></dt>
          <dd>(文書型の決定と設定。あるいはその片方)</dd>
        </dl>
      
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/developer/modules.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../ja/developer/modules.html" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/modules.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/filters.html.en��������������������������������������������������0000664�0001751�0001751�00000035104�14737241666�021776� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>How filters work in Apache 2.0 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>How filters work in Apache 2.0</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/filters.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <div class="warning"><h3>Warning</h3>
          <p>This is a cut 'n paste job from an email
          (&lt;022501c1c529$f63a9550$7f00000a@KOJ&gt;) and only reformatted for
          better readability. It's not up to date but may be a good start for
          further research.</p>
        </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#types">Filter Types</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#howinserted">How are filters inserted?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#asis">Asis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#conclusion">Explanations</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="types" id="types">Filter Types</a></h2>
        <p>There are three basic filter types (each of these is actually broken
        down into two categories, but that comes later).</p>
    
        <dl>
        <dt><code>CONNECTION</code></dt>
        <dd>Filters of this type are valid for the lifetime of this connection.
        (<code>AP_FTYPE_CONNECTION</code>, <code>AP_FTYPE_NETWORK</code>)</dd>
    
        <dt><code>PROTOCOL</code></dt>
        <dd>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. (<code>AP_FTYPE_PROTOCOL</code>,
        <code>AP_FTYPE_TRANSCODE</code>)</dd>
    
        <dt><code>RESOURCE</code></dt>
        <dd>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
        <code>PROTOCOL</code>, but internal redirects and sub-requests can change
        the content without ending the request. (<code>AP_FTYPE_RESOURCE</code>,
        <code>AP_FTYPE_CONTENT_SET</code>)</dd>
        </dl>
    
        <p>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:</p>
    
        <dl>
        <dt>Byterange</dt>
        <dd>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.</dd>
    
        <dt>http_header</dt>
        <dd>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.</dd>
    
        <dt>Deflate</dt>
        <dd>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.</dd>
        </dl>
    
        <p>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 <code>RESOURCE</code> filters
        only have one filter type, but that should change.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howinserted" id="howinserted">How are filters inserted?</a></h2>
        <p>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:</p>
        <ul>
            <li><code>r-&gt;output_filters</code> (corresponds to RESOURCE)</li>
            <li><code>r-&gt;proto_output_filters</code> (corresponds to PROTOCOL)</li>
            <li><code>r-&gt;connection-&gt;output_filters</code> (corresponds to CONNECTION)</li>
        </ul> 
        
        <p>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
        <code>RESOURCE</code> filter on the stack, and I added a
        <code>CONNECTION</code> filter, the <code>CONNECTION</code> filter would
        be ignored. This should make sense, because we would insert the connection
        filter at the top of the <code>c-&gt;output_filters</code> list, but the end
        of <code>r-&gt;output_filters</code> pointed to the filter that used to be
        at the front of <code>c-&gt;output_filters</code>. 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.</p>
    
        <p>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.</p>
    
        <p>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
        <code>make_sub_request</code> 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:</p>
    
    <div class="example"><pre>Default_handler --&gt; includes_filter --&gt; byterange --&gt; ...</pre></div>
    
        <p>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:</p>
    
    <div class="example"><pre>Default_handler --&gt; includes_filter -/-&gt; byterange --&gt; ...
                                        /
    Default_handler --&gt; sub_request_core</pre></div>
    
        <p>What happens if the subrequest is SSI data?  Well, that's easy, the
        <code>includes_filter</code> is a resource filter, so it will be added to
        the sub request in between the <code>Default_handler</code> and the
        <code>sub_request_core</code> filter.</p>
    
        <p>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 <code>make_sub_request</code> function.</p>
    
        <p>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.</p>
    
        <p>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.</p>
    
        <p>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.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="asis" id="asis">Asis</a></h2>
        <p>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 <code class="module"><a href="../mod/mod_asis.html">mod_asis</a></code>, all other
        bets are off.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="conclusion" id="conclusion">Explanations</a></h2>
        <p>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 <code>reset_filters</code>
        and <code>add_required_filters</code> 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 <code>HTTP_HEADER</code>, <code>Content-length</code>, and
        <code>Byterange</code> filters are all added in the
        <code>insert_filters</code> phase, because if they were added earlier, we
        had some interesting interactions.  Now, those could all be moved to be
        inserted with the <code>HTTP_IN</code>, <code>CORE</code>, and
        <code>CORE_IN</code> filters.  That would make the code easier to
        follow.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/filters.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/filters.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/modules.html.en��������������������������������������������������0000664�0001751�0001751�00000034714�14737241666�022004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Converting Modules from Apache 1.3 to Apache 2.0 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Converting Modules from Apache 1.3 to Apache 2.0</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/modules.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../ja/developer/modules.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div>
    
        <p>This is a first attempt at writing the lessons I learned
        when trying to convert the <code>mod_mmap_static</code> 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.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#easy">The easier changes ...</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#messy">The messier changes...</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="easy" id="easy">The easier changes ...</a></h2>
    
        <h3><a name="cleanup" id="cleanup">Cleanup Routines</a></h3>
          <p>These now need to be of type <code>apr_status_t</code> and return a
          value of that type. Normally the return value will be
          <code>APR_SUCCESS</code> 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.</p>
        
    
        <h3><a name="init" id="init">Initialisation Routines</a></h3>
          <p>These should now be renamed to better signify where they sit
          in the overall process. So the name gets a small change from
          <code>mmap_init</code> to <code>mmap_post_config</code>. The arguments
          passed have undergone a radical change and now look like</p>
    
          <ul>
            <li><code>apr_pool_t *p</code></li>
            <li><code>apr_pool_t *plog</code></li>
            <li><code>apr_pool_t *ptemp</code></li>
            <li><code>server_rec *s</code></li>
          </ul>
        
    
        <h3><a name="datatypes" id="datatypes">Data Types</a></h3>
          <p>A lot of the data types have been moved into the <a href="http://apr.apache.org/">APR</a>. 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.</p>
    
          <ul>
            <li><code>pool</code> becomes <code>apr_pool_t</code></li>
            <li><code>table</code> becomes <code>apr_table_t</code></li>
          </ul>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="messy" id="messy">The messier changes...</a></h2>
    
        <h3><a name="register-hooks" id="register-hooks">Register Hooks</a></h3>
          <p>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, <code>static void register_hooks(void)</code>.
          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.</p>
    
          <p>This is the code that was added to <code>mod_mmap_static</code>:</p>
          <div class="example"><pre>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);
    };</pre></div>
    
          <p>This registers 2 functions that need to be called, one in
          the <code>post_config</code> stage (virtually every module will need this
          one) and one for the <code>translate_name</code> phase. note that while
          there are different function names the format of each is
          identical. So what is the format?</p>
    
          <div class="example"><p><code>
            ap_hook_<var>phase_name</var>(<var>function_name</var>,
            <var>predecessors</var>, <var>successors</var>, <var>position</var>);
          </code></p></div>
    
          <p>There are 3 hook positions defined...</p>
    
          <ul>
            <li><code>HOOK_FIRST</code></li>
            <li><code>HOOK_MIDDLE</code></li>
            <li><code>HOOK_LAST</code></li>
          </ul>
    
          <p>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).</p>
    
          <p>In the <code>mod_mmap_static</code> case I didn't care about the
          <code>post_config</code> stage, but the <code>mmap_static_xlat</code>
          <strong>must</strong> be called after the core module had done its name
          translation, hence the use of the aszPre to define a modifier to the
          position <code>HOOK_LAST</code>.</p>
        
    
        <h3><a name="moddef" id="moddef">Module Definition</a></h3>
          <p>There are now a lot fewer stages to worry about when
          creating your module definition. The old definition looked
          like</p>
    
          <div class="example"><pre>module MODULE_VAR_EXPORT <var>module_name</var>_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 */
    };</pre></div>
    
          <p>The new structure is a great deal simpler...</p>
          <div class="example"><pre>module MODULE_VAR_EXPORT <var>module_name</var>_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 */
    };</pre></div>
    
          <p>Some of these read directly across, some don't. I'll try to
          summarise what should be done below.</p>
    
          <p>The stages that read directly across :</p>
    
          <dl>
            <dt><code>/* dir config creater */</code></dt>
            <dd><code>/* create per-directory config structures */</code></dd>
    
            <dt><code>/* server config */</code></dt>
            <dd><code>/* create per-server config structures */</code></dd>
    
            <dt><code>/* dir merger */</code></dt>
            <dd><code>/* merge per-directory config structures */</code></dd>
    
            <dt><code>/* merge server config */</code></dt>
            <dd><code>/* merge per-server config structures */</code></dd>
    
            <dt><code>/* command table */</code></dt>
            <dd><code>/* command apr_table_t */</code></dd>
    
            <dt><code>/* handlers */</code></dt>
            <dd><code>/* handlers */</code></dd>
          </dl>
    
          <p>The remainder of the old functions should be registered as
          hooks. There are the following hook stages defined so
          far...</p>
    
          <dl>
            <dt><code>ap_hook_pre_config</code></dt>
            <dd>do any setup required prior to processing configuration
            directives</dd>
    
            <dt><code>ap_hook_check_config</code></dt>
            <dd>review configuration directive interdependencies</dd>
    
            <dt><code>ap_hook_test_config</code></dt>
            <dd>executes only with <code>-t</code> option</dd>
    
            <dt><code>ap_hook_open_logs</code></dt>
            <dd>open any specified logs</dd>
    
            <dt><code>ap_hook_post_config</code></dt>
            <dd>this is where the old <code>_init</code> routines get
            registered</dd>
    
            <dt><code>ap_hook_http_method</code></dt>
            <dd>retrieve the http method from a request. (legacy)</dd>
    
            <dt><code>ap_hook_auth_checker</code></dt>
            <dd>check if the resource requires authorization</dd>
    
            <dt><code>ap_hook_access_checker</code></dt>
            <dd>check for module-specific restrictions</dd>
    
            <dt><code>ap_hook_check_user_id</code></dt>
            <dd>check the user-id and password</dd>
    
            <dt><code>ap_hook_default_port</code></dt>
            <dd>retrieve the default port for the server</dd>
    
            <dt><code>ap_hook_pre_connection</code></dt>
            <dd>do any setup required just before processing, but after
            accepting</dd>
    
            <dt><code>ap_hook_process_connection</code></dt>
            <dd>run the correct protocol</dd>
    
            <dt><code>ap_hook_child_init</code></dt>
            <dd>call as soon as the child is started</dd>
    
            <dt><code>ap_hook_create_request</code></dt>
            <dd>??</dd>
    
            <dt><code>ap_hook_fixups</code></dt>
            <dd>last chance to modify things before generating content</dd>
    
            <dt><code>ap_hook_handler</code></dt>
            <dd>generate the content</dd>
    
            <dt><code>ap_hook_header_parser</code></dt>
            <dd>lets modules look at the headers, not used by most modules, because
            they use <code>post_read_request</code> for this</dd>
    
            <dt><code>ap_hook_insert_filter</code></dt>
            <dd>to insert filters into the filter chain</dd>
    
            <dt><code>ap_hook_log_transaction</code></dt>
            <dd>log information about the request</dd>
    
            <dt><code>ap_hook_optional_fn_retrieve</code></dt>
            <dd>retrieve any functions registered as optional</dd>
    
            <dt><code>ap_hook_post_read_request</code></dt>
            <dd>called after reading the request, before any other phase</dd>
    
            <dt><code>ap_hook_quick_handler</code></dt>
            <dd>called before any request processing, used by cache modules.</dd>
    
            <dt><code>ap_hook_translate_name</code></dt>
            <dd>translate the URI into a filename</dd>
    
            <dt><code>ap_hook_type_checker</code></dt>
            <dd>determine and/or set the doc type</dd>
          </dl>
        
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/modules.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../ja/developer/modules.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/modules.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������httpd-2.4.64/docs/manual/developer/thread_safety.html.en��������������������������������������������0000664�0001751�0001751�00000043201�14737241666�023145� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server 2.x Thread Safety Issues - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Server 2.x Thread Safety Issues</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/developer/thread_safety.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <p>When using any of the threaded mpms in the Apache HTTP Server 2.x 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 conditions that
        may only show up in certain conditions under heavy load.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#variables">Global and static variables</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#errno">errno</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#functions">Common standard troublesome functions</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#commonlibs">Common 3rd Party Libraries</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#liblist">Library List</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="variables" id="variables">Global and static variables</a></h2>
        <p>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.</p>
    
        <p>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.</p>
    
        <p>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.</p>
    
        <p>If you are using <a href="http://apr.apache.org/">APR</a>, have a look
        at the <code>apr_atomic_<var>*</var></code> functions and the
        <code>apr_thread_mutex_<var>*</var></code> functions.</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errno" id="errno">errno</a></h2>
        <p>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 <code>_REENTRANT</code> or is compiled with
        <code>-D_REENTRANT</code>. This will make errno a per-thread variable
        and should hopefully be transparent to the code. It does this by doing
        something like this:</p>
    
        <div class="example"><p><code>
          #define errno (*(__errno_location()))
        </code></p></div>
    
        <p>which means that accessing errno will call
        <code>__errno_location()</code> which is provided by the libc. Setting
        <code>_REENTRANT</code> also forces redefinition of some other functions
        to their <code><var>*</var>_r</code> equivalents and sometimes changes
        the common <code>getc</code>/<code>putc</code> macros into safer function
        calls.  Check your libc documentation for specifics.  Instead of, or in
        addition to <code>_REENTRANT</code> the symbols that may affect this are
        <code>_POSIX_C_SOURCE</code>, <code>_THREAD_SAFE</code>,
        <code>_SVID_SOURCE</code>, and <code>_BSD_SOURCE</code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="functions" id="functions">Common standard troublesome functions</a></h2>
        <p>Not only do things have to be thread safe, but they also have to be
        reentrant. <code>strtok()</code> 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 the function called <code>strtok_r()</code> where you pass in an
        extra argument which contains an allocated <code>char *</code> which the
        function will use instead of its own static storage for maintaining
        the tokenizing state. If you are using <a href="http://apr.apache.org/">APR</a> you can use <code>apr_strtok()</code>.</p>
    
        <p><code>crypt()</code> 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 <code>crypt_r()</code> chances are you should be using
        that, or if possible simply avoid the whole mess by using md5 instead.</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="commonlibs" id="commonlibs">Common 3rd Party Libraries</a></h2>
        <p>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 <code>ldd(1)</code> and
        <code>nm(1)</code>. For <a href="http://www.php.net/">PHP</a>, for example,
        try this:</p>
    
        <div class="example"><p><code>
          % ldd libphp4.so<br />
          libsablot.so.0 =&gt; /usr/local/lib/libsablot.so.0 (0x401f6000)<br />
          libexpat.so.0 =&gt; /usr/lib/libexpat.so.0 (0x402da000)<br />
          libsnmp.so.0 =&gt; /usr/lib/libsnmp.so.0 (0x402f9000)<br />
          libpdf.so.1 =&gt; /usr/local/lib/libpdf.so.1 (0x40353000)<br />
          libz.so.1 =&gt; /usr/lib/libz.so.1 (0x403e2000)<br />
          libpng.so.2 =&gt; /usr/lib/libpng.so.2 (0x403f0000)<br />
          libmysqlclient.so.11 =&gt; /usr/lib/libmysqlclient.so.11 (0x40411000)<br />
          libming.so =&gt; /usr/lib/libming.so (0x40449000)<br />
          libm.so.6 =&gt; /lib/libm.so.6 (0x40487000)<br />
          libfreetype.so.6 =&gt; /usr/lib/libfreetype.so.6 (0x404a8000)<br />
          libjpeg.so.62 =&gt; /usr/lib/libjpeg.so.62 (0x404e7000)<br />
          libcrypt.so.1 =&gt; /lib/libcrypt.so.1 (0x40505000)<br />
          libssl.so.2 =&gt; /lib/libssl.so.2 (0x40532000)<br />
          libcrypto.so.2 =&gt; /lib/libcrypto.so.2 (0x40560000)<br />
          libresolv.so.2 =&gt; /lib/libresolv.so.2 (0x40624000)<br />
          libdl.so.2 =&gt; /lib/libdl.so.2 (0x40634000)<br />
          libnsl.so.1 =&gt; /lib/libnsl.so.1 (0x40637000)<br />
          libc.so.6 =&gt; /lib/libc.so.6 (0x4064b000)<br />
          /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x80000000)
        </code></p></div>
    
        <p>In addition to these libraries you will need to have a look at any
        libraries linked statically into the module. You can use <code>nm(1)</code>
        to look for individual symbols in the module.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="liblist" id="liblist">Library List</a></h2>
        <p>Please drop a note to <a href="http://httpd.apache.org/lists.html#http-dev">dev@httpd.apache.org</a>
        if you have additions or corrections to this list.</p>
    
        <table class="bordered"><tr class="header"><th>Library</th><th>Version</th><th>Thread Safe?</th><th>Notes</th></tr>
    <tr><td><a href="http://aspell.sourceforge.net/">ASpell/PSpell</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr class="odd"><td><a href="http://www.sleepycat.com/">Berkeley DB</a></td>
            <td>3.x, 4.x</td>
            <td>Yes</td>
            <td>Be careful about sharing a connection across threads.</td></tr>
    <tr><td><a href="http://sources.redhat.com/bzip2/index.html">bzip2</a></td>
            <td> </td>
            <td>Yes</td>
            <td>Both low-level and high-level APIs are thread-safe. However,
            high-level API requires thread-safe access to errno.</td></tr>
    <tr class="odd"><td><a href="http://cr.yp.to/cdb.html">cdb</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr><td><a href="http://www.washington.edu/imap/">C-Client</a></td>
            <td> </td>
            <td>Perhaps</td>
            <td>c-client uses <code>strtok()</code> and
            <code>gethostbyname()</code> which are not thread-safe on most C
            library implementations.  c-client's static data is meant to be shared
            across threads. If <code>strtok()</code> and
            <code>gethostbyname()</code> are thread-safe on your OS, c-client
            <em>may</em> be thread-safe.</td></tr>
    <tr class="odd"><td><a href="http://www.ijg.org/files/">libcrypt</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr><td><a href="http://expat.sourceforge.net/">Expat</a></td>
            <td> </td>
            <td>Yes</td>
            <td>Need a separate parser instance per thread</td></tr>
    <tr class="odd"><td><a href="http://www.freetds.org/">FreeTDS</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr><td><a href="http://www.freetype.org/">FreeType</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr class="odd"><td><a href="http://www.boutell.com/gd/">GD 1.8.x</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr><td><a href="http://www.boutell.com/gd/">GD 2.0.x</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr class="odd"><td><a href="http://www.gnu.org/software/gdbm/gdbm.html">gdbm</a></td>
            <td> </td>
            <td>No</td>
            <td>Errors returned via a static <code>gdbm_error</code>
            variable</td></tr>
    <tr><td><a href="http://www.imagemagick.org/">ImageMagick</a></td>
            <td>5.2.2</td>
            <td>Yes</td>
            <td>ImageMagick docs claim it is thread safe since version 5.2.2 (see <a href="http://www.imagemagick.com/www/changelog.html">Change log</a>).
            </td></tr>
    <tr class="odd"><td><a href="http://www.enlightenment.org/p.php?p=about/efl&amp;l=en">Imlib2</a></td>
            <td> </td>
            <td>?</td>
            <td> </td></tr>
    <tr><td><a href="http://www.ijg.org/files/">libjpeg</a></td>
            <td>v6b</td>
            <td>?</td>
            <td> </td></tr>
    <tr class="odd"><td><a href="http://mysql.com">libmysqlclient</a></td>
            <td> </td>
            <td>Yes</td>
            <td>Use mysqlclient_r library variant to ensure thread-safety.  For
                more information, please read <a href="http://dev.mysql.com/doc/mysql/en/Threaded_clients.html">http://dev.mysql.com/doc/mysql/en/Threaded_clients.html</a>.</td></tr>
    <tr><td><a href="http://www.opaque.net/ming/">Ming</a></td>
            <td>0.2a</td>
            <td>?</td>
            <td> </td></tr>
    <tr class="odd"><td><a href="http://net-snmp.sourceforge.net/">Net-SNMP</a></td>
            <td>5.0.x</td>
            <td>?</td>
            <td> </td></tr>
    <tr><td><a href="http://www.openldap.org/">OpenLDAP</a></td>
            <td>2.1.x</td>
            <td>Yes</td>
            <td>Use <code>ldap_r</code> library variant to ensure
            thread-safety.</td></tr>
    <tr class="odd"><td><a href="http://www.openssl.org/">OpenSSL</a></td>
            <td>0.9.6g</td>
            <td>Yes</td>
            <td>Requires proper usage of <code>CRYPTO_num_locks</code>,
            <code>CRYPTO_set_locking_callback</code>,
            <code>CRYPTO_set_id_callback</code></td></tr>
    <tr><td><a href="http://www.oracle.com/">liboci8 (Oracle 8+)</a></td>
            <td>8.x,9.x</td>
            <td>?</td>
            <td> </td></tr>
    <tr class="odd"><td><a href="http://pdflib.com/">pdflib</a></td>
            <td>5.0.x</td>
            <td>Yes</td>
            <td>PDFLib docs claim it is thread safe; changes.txt indicates it
                has been partially thread-safe since V1.91: <a href="http://www.pdflib.com/products/pdflib-family/pdflib/">http://www.pdflib.com/products/pdflib-family/pdflib/</a>.</td></tr>
    <tr><td><a href="http://www.libpng.org/pub/png/libpng.html">libpng</a></td>
            <td>1.0.x</td>
            <td>?</td>
            <td> </td></tr>
    <tr class="odd"><td><a href="http://www.libpng.org/pub/png/libpng.html">libpng</a></td>
            <td>1.2.x</td>
            <td>?</td>
            <td> </td></tr>
    <tr><td><a href="http://www.postgresql.org/docs/8.4/static/libpq-threading.html">libpq (PostgreSQL)</a></td>
            <td>8.x</td>
            <td>Yes</td>
            <td>Don't share connections across threads and watch out for
            <code>crypt()</code> calls</td></tr>
    <tr class="odd"><td><a href="http://www.gingerall.com/charlie/ga/xml/p_sab.xml">Sablotron</a></td>
            <td>0.95</td>
            <td>?</td>
            <td /></tr>
    <tr><td><a href="http://www.gzip.org/zlib/">zlib</a></td>
            <td>1.1.4</td>
            <td>Yes</td>
            <td>Relies upon thread-safe zalloc and zfree functions  Default is to
            use libc's calloc/free which are thread-safe.</td></tr>
    </table>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/developer/thread_safety.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/thread_safety.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/debugging.html���������������������������������������������������0000664�0001751�0001751�00000000170�13710016232�021626� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: debugging.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/index.html�������������������������������������������������������0000664�0001751�0001751�00000000317�13710016232�021005� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: index.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/output-filters.html����������������������������������������������0000664�0001751�0001751�00000000175�13710016232�022706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: output-filters.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/developer/filters.html�����������������������������������������������������0000664�0001751�0001751�00000000166�13710016232�021350� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: filters.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/caching.html.tr.utf8�������������������������������������������������������0000664�0001751�0001751�00000155302�14743132254�020635� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Önbellek Kullanım Kılavuzu - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Önbellek Kullanım Kılavuzu</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/caching.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/caching.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/caching.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu belge <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>,
          <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>, <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code>
          modülleri ve <a href="programs/htcacheclean.html">htcacheclean</a>
          için bir başvuru kılavuzu niteliğindedir. HTTP sunucusu ve vekil
          olarak çalışmada işlemleri hızlandırmak için bilinen sorunlar ve
          yanlış yapılandırmalardan kaçınarak Apache HTTPD sunucusunun önbellekleme
          özelliklerinin nasıl kullanılacağı açıklanmıştır.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Giriş</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#http-caching">Üç durumlu RFC2616 HTTP önbelleklemesi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Önbellek Ayarlama Örnekleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#socache-caching">Genel İki durumlu Anahtar/Değer Paylaşımlı Nesne Önbellekleme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-caching">Uzmanlaşmış Dosya Önbellekleme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#security">Güvenlik Kaygıları</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Giriş</a></h2>
        
    
        <p>Apache HTTP sunucusu, sunucunun başarımını çeşitli yollarla arttırmak
          üzere tasarlanmış bir dizi önbellekleme özelliğine sahiptir.</p>
    
        <dl>
            <dt>Üç durumlu RFC2616 HTTP önbelleklemesi</dt>
            <dd>
                <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> ve destek modülü
                <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> akılcı ve HTTP'ye uygun
                önbellekleme sağlar. İçeriğin kendisi önbellekte saklanır ve
                <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">RFC2616'nın 13. bölümü</a>nde açıklandığı gibi, içeriğin
                önbelleklenebilirliğini denetleyen çeşitli HTTP başlıklarının ve
                seçeneklerinin tümünü onurlandırmayı hedefler.
                Devingen yerel içerik veya vekalet edilen içerik ile ilgilendiğiniz
                durumda veya muhtemel bir yavaş disk üzerinde yerel dosyalara
                erişimi hızlandırmak ihtiyacında olduğunuz durumda
                <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> hem basit hem de karmaşık önbellekleme
                yapılandırmalarını hedefler.
            </dd>
            <dt>İki durumlu anahtar/değer paylaşımlı nesne önbellekleme</dt>
            <dd>
                <a href="socache.html">Paylaşımlı nesne önbellek API'si</a>
                (socache) ve destek modülleri sunucu taraflı bir anahtar/değer
                paylaşımlı nesne önbelleklemesi sağlar. Bu modüller SSL oturumları
                ve kimlik doğrulama bilgileri gibi düşük seviyeli verileri
                önbelleklemek için tasarlanmıştır. Destek modülleri verinin sunucu
                tarafı bir paylaşımlı bellekte veya veri merkezi tarafı memcache
                veya distcache gibi bir önbellekte saklanmasını mümkün kılar.
            </dd>
            <dt>Uzmanlaşmış dosya önbellekleme</dt>
            <dd>
                <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> dosyaların sunucunun başlatılması
                sırasında  belleğe yüklenmesi ile ilgilenir. Böylece dosyalara
                erişim zamanını kısaltabilir, sıkça erişilen dosyaların dosya
                tanıtıcılarını kaydedebilir, her istekte diske gitme ihtiyacını
                ortadan kaldırır.
            </dd>
        </dl>
    
        <p>Bu belgeden azami yararı sağlayabilmek için temel bir HTTP bilginizin
          olması ve <a href="urlmapping.html">URL’lerin Dosya Sistemine
          Eşlenmesi</a> ile <a href="content-negotiation.html">İçerik Uzlaşımı</a>
          belgelerini okumuş olmanız gerekir.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="http-caching" id="http-caching">Üç durumlu RFC2616 HTTP önbelleklemesi</a></h2>
    
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code></li><li><code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li><li><code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code></li></ul></td></tr></table>
    
        <p>HTTP protokolü
          <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">RFC2616'nın 13. bölümü</a>nde açıklanan satıriçi önbellekleme
          mekanizması için yerleşik bir destek içerir ve bunun getirilerinden
          yararlanmak için <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü kullanılabilir.</p>
    
        <p>İçeriğin taze olmadığı durumda içeriğin kaybolmasına sebep olan basit
          iki durumlu anahtar/değer önbelleklemesinin tersine, HTTP önbelleği
          eskimiş içeriği tutan ve bu eski içeriğin değişip değişmediğini özgün
          sunucuya soran ve duruma göre onu tekrar taze duruma getiren bir
          mekanizma içerir.</p>
    
        <p>HTTP önbelleğinde bulunan bir girdi şu üç durumdan birinde olabilir:</p>
    
        <dl>
        <dt>Taze</dt>
        <dd>
            İçerik yeteri kadar yeni (<strong>tazelik ömrü</strong>nden daha genç)
            ise <strong>taze</strong> sayılır. Bir HTTP önbelleği böyle bir içeriği
            özgün sunucuya birşey sormadan sunabilir.
        </dd>
        <dt>Bayat</dt>
        <dd>
            <p>İçerik çok eski (<strong>tazelik ömrü</strong>nden daha yaşlı)
            ise <strong>bayat</strong> sayılır. Bir HTTP önbelleği böyle bir
            içeriği istemciye sunmadan önce özgün sunucuya bağlanıp bayat içeriğin
            hala yeterince taze olup olmadığına bakmalıdır. Özgün sunucu, içerik
            geçersizse yenisini gönderecektir, aksi takdirde, (ideal olanı budur)
            içeriğin hala geçerli olduğunu belirten bir kod ile yanıt verecektir.
            İçerik tekrar taze hale gelince süreç kaldığı yerden devam eder.</p>
    
            <p>HTTP protokolü belli koşullar altında önbelleğin bayat içeriği
            sunmasına izin vermez. Örneğin, bir içeriği özgün sunucuda tazeleme
            çabasının bir 5xx hatasıyla başarısız olması veya başka bir tazeleme
            isteğinin henüz sonuçlanmamış olması bu çeşit koşullardandır. Bu
            durumlarda yanıta bir <code>Warning</code> başlığı eklenir.</p>
        </dd>
        <dt>Yok</dt>
        <dd>
            Önbellekte yer kalmazsa yer açmak için içeriğin silinmesi seçenek
            dahilindedir. İçerik taze olsun olmasın her zaman silinebilir. Önlem
            olarak <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code> elle veya bir artalan süreci
            olarak çalıştırılabilir. Böylece önbelleğin boyutunun belirtilen
            boyutta veya belirtilen dosya düğümü sayısında kalması sağlanabilir.
            Araç içeriği silerken bayat içeriğe öncelik verir.
        </dd>
        </dl>
    
        <p>HTTP önbelleklemesinin çalışması ile ilgili bütün ayrıntılar
        <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">RFC2616'nın 13. bölümünde</a> bulunabilir.</p>
    
        <h3>Sunucu ile etkileşim</h3>
          
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü
          <code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code> yönergesinin
          değerine bağlı olarak iki olası yerde sunucuya bağlanır:
          </p>
    
          <dl>
          <dt>Çabuk eylem aşaması</dt>
          <dd>
              <p>Bu aşama çok erken gerçekleşen bir aşama olup isteğin işlenmesi
              sırasında isteğin çözümlenmesinin hemen sonrasıdır. İçerik
              önbellekte mevcutsa hemen sunulur ve geri kalan istek işleme işlemi
              iptal edilir.</p>
    
              <p>Bu senaryoda önbellek sunucunun önüne vidalanmış gibi
              davranır.</p>
    
              <p>Sunucuda gerçekleşecek bir dizi işlemin büyük çoğunluğunun
              yapılmadan geçilmesi nedeniyle bu en yüksek başarımlı kiptir.
              Bu kip ayrıca, sunucu işlemlerinin kimlik doğrulama ve yetkilendirme
              aşamalarının da yapılmadan geçilmesini sağlar. Bu bakımdan bu kip
              seçilirken bu durum dikkate alınmalıdır.</p>
    
              <p>"Authorization" başlığı içeren istekler (örneğin, HTTP Temel
              Kimlik Kanıtlaması gibi) <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> bu kipte
              çalışırken önbelleğe alınmadıkları gibi önbellekten bir işleme de
              sokulmazlar.</p>
          </dd>
          <dt>Normal eylem aşaması</dt>
          <dd>
              <p>Bu aşama geç bir aşama olup, isteğin tamamen işlenmesinin
              sonrasıdır.</p>
    
              <p>Bu senaryoda önbellek sunucunun arkasına vidalanmış gibi
              davranır.</p>
    
              <p>Bu kip en esneğidir. Önbelleğin, süzme zincirinin hassas olarak
              denetlenen bir noktasında oluşması sağlanabilir ve önbelleklenen
              içerik istemciye gönderilmeden önce süzülüp
              kişiselleştirilebilir.</p>
              </dd>
            </dl>
    
            <p>URL önbellekte yoksa <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü yanıtı
              önbelleğe kaydetme aşamasında süzgeç yığıtına bir
              <a href="filter.html">süzgeç</a> ekler ve geri çekilerek normal istek
              işlemlerinin devam etmesine izin verir. İçeriğin önbelleklenebilir
              olduğu saptanırsa içerik gelecekte sunulmak üzere önbelleğe
              kaydedilir, aksi takdirde içerik yok sayılır.</p>
    
            <p>Önbellekteki içerik bayatsa, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü
              isteği bir <strong>koşullu istek</strong> haline getirir. Özgün
              sunucu normal bir yanıt verirse bu yanıt mevcut içeriğin yerine
              önbelleklenir. Özgün sunucu bir <code>304 Not Modified</code> yanıtı
              verirse içerik tekrar taze olarak imlenir ve önbellekteki içerik
              süzgeç tarafından kaydedilmeden sunulur.</p>
        
    
        <h3>Önbelleğin Hızlandırılması</h3>
          
    
          <p>Bir sanal konak birçok farklı sunucu takma adından biri olarak
            bilindiği takdirde <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code> yönergesine <code>On</code>
            değeri atanmışsa önbellekten sunulan sayfa sayısında büyük bir artış
            olduğu görülür. Bunun sebebi içeriği sunan sanal konağın isminin
            önbellek anahtarının içinde kullanılmasıdır. Yönergeye
            <code>On</code> değerini atamak suretiyle çok isimli ve rumuzlu sanal
            konaklar için farklı önbellek girdileri oluşturulmaz, bunun yerine her
            meşru sanal konak için ayrı bir önbellek tutulur.</p>
        
    
        <h3>Tazelik Ömrü</h3>
          
    
          <p>Önbelleklenmek üzere tasarlanmış iyi biçimli bir içerik tazelik ömrünü
            <code>Cache-Control</code> başlığının  <code>max-age</code> veya
            <code>s-maxage</code> alanlarıyla ya da bir <code>Expires</code>
            başlığını içererek bildirmelidir.</p>
    
          <p>Aynı zamanda, özgün sunucunun tanımladığı tazelik ömrü, bir istemci
            tarafından istekte bir <code>Cache-Control</code> başlığı kullanılarak
            geçersiz kılınmak istenebilir. Bu durumda hangi tazelik ömrü daha
            kısaysa o geçerli olur.</p>
    
          <p>Tazelik ömrü istekte veya yanıtta mevcut değilse öntanımlı bir tazelik
            ömrü kullanılır. Öntanımlı tazelik ömrü önbellekli içerik için bir saat
            olmakla birlikte <code class="directive"><a href="./mod/mod_cache.html#cachedefaultexpire">CacheDefaultExpire</a></code> yönergesi
            kullanılarak kolayca değiştirilebilir.</p>
    
          <p>Bir yanıt <code>Expires</code> başlığını değil de
            <code>Last-Modified</code> başlığını içeriyorsa
            <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> tazelik ömrünü <code class="directive"><a href="./mod/mod_cache.html#cachelastmodifiedfactor">CacheLastModifiedFactor</a></code> yönergesine
            bakarak saptar.</p>
    
          <p>Yerel içerik için, ya da kendi <code>Expires</code> başlığını
            tanımlamayan uzak içerik için tazelik ömrünü <code>max-age</code> ve
            <code>Expires</code> ekleyerek hassas olarak ayarlamak
            için <code class="module"><a href="./mod/mod_expires.html">mod_expires</a></code> kullanılabilir.</p>
    
          <p>Tazelik ömrünün üst sınırı <code class="directive"><a href="./mod/mod_cache.html#cachemaxexpire">CacheMaxExpire</a></code> yönergesi ile
            belirlenebilir.</p>
        
    
        <h3>Şartlı İstekler için Özlü Kılavuz</h3>
          
    
          <p>Önbellekteki içeriğin zaman aşımına uğrayıp bayat hale gelmesi,
            httpd’nin özgün isteği aktarmak yerine isteği değişikliğe uğratarak
            şartlı bir istek yapması sonucunu doğurur.</p>
    
          <p>Özgün önbellekli yanıtta bir <code>ETag</code> başlığı mevcutsa,
            <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü özgün sunucuya yapılan isteğe
            bir <code>If-None-Match</code> başlığı ekler.
            Özgün önbellekli yanıtta bir <code>Last-Modified</code> başlığı
            mevcutsa, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü özgün sunucuya yapılan
            isteğe bir <code>If-Modified-Since</code> başlığı ekler. Bunlardan
            birinin varlığı isteği <strong>koşullu</strong> yapar.</p>
    
          <p>Bir koşullu istek özgün sunucu tarafından alındığında, özgün sunucu
            <code>ETag</code> veya <code>Last-Modified</code> başlığının isteğe
            uygun olarak değişip değişmediğine bakmalıdır. Değişmemişse, özgün
            sunucu kısa ve öz bir "304 Not Modified" yanıtı ile yanıt vermelidir.
            Bunun önbellekteki anlamı şudur: Eskimiş içerik hala tazedir ve içerik
            yeni tazelik ömrüne ulaşıncaya kadar sonraki isteklerde
            kullanılmalıdır.</p>
    
          <p>İçerik değişmişse, bir şartlı istek yapılmamış gibi içeriğin kendisi
            sunulur.</p>
    
          <p>Şartlı istekler çifte yarar sağlar. Birinci olarak, böyle bir istek
            özgün sunucuya yapılıyorsa ve iki içerik de aynıysa bunu saptamak kolay
            olur ve özkaynağın tamamını aktarma külfetinden kurtulunur.</p>
    
          <p>İkinci olarak, iyi tasarlanmış bir özgün sunucu, koşullu istekler tam
            bir yanıt üretmekten önemli ölçüde ucuz olacak şekilde tasarlanmış
            olacaktır. Durağan dosyalar için bu genellikle
            <code>stat()</code> veya  benzeri bir sistem çağrısıyla dosya
            boyutları ve değişiklik zamanına bakmak şeklinde gerçekleşir.
            Böylelikle, yerel içeriği bir değişiklik olmadığı takdirde önbellekten
            sunmak daha hızlı olacaktır.</p>
    
          <p>Özgün sunucular koşullu istekleri desteklemek için her türlü çabayı
            göstermelidir. Ancak, koşullu istekler desteklenmiyorsa, özgün sunucu
            istek koşullu değilmiş gibi yanıt vermeli, önbellek ise, içerik
            değişmiş ve yani içerik önbelleğe kaydedilmiş gibi yanıt vermelidir. Bu
            durumda, önbellek basit bir iki durumlu (içerik ya tazedir ya da
            silinmiş) önbellek gibi davranacaktır.</p>
        
    
        <h3>Neler Önbelleklenebilir?</h3>
          
    
          <p>HTTP önbelleğin tarafından önbelleklenebilecek içerik
    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4">
           RFC2616 Section 13.4 Response Cacheability</a> belgesinde tanımlanmış
           olup, bunlar şöyle özetlenebilir:</p>
    
          <ol>
            <li>Önbellekleme bu URL ile etkin kılınabilmelidir. <code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code> ve <code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code> yönergelerine bakınız.</li>
    
            <li>Yanıtın HTTP durum kodu 200, 203, 300, 301 veya 410 olmalıdır.</li>
            
            <li>Yanıtın HTTP durum kodu 200, 203, 300, 301 veya 410 değilse 
              yanıtın ayrıca, "Expires" veya "Cache-Control" başlığı da içermesi 
              gerekir.</li>
    
            <li>İstek bir HTTP GET isteği olmalıdır.</li>
    
            <li>Eğer yanıt bir "Authorization:" başlığı içeriyorsa ayrıca
              "Cache-Control:" başlığında da "s-maxage", "must-revalidate" veya
              "public" değerlerinden birini içermelidir, aksi takdirde
              önbelleklenmez.</li>
    
            <li>Eğer URL (GET yöntemi kullanan bir HTML formunun yaptığı gibi) bir
              sorgu dizgesi içeriyorsa  yanıt, RFC2616’nın 13.9. bölümünde
              açıklandığı gibi bir "Expires:" başlığı içermedikçe veya
              "Cache-Control:" başlığının max-age veya max-age yönergesini
              içermedikçe yanıt içeriği önbelleğe alınmayacaktır.</li>
    
            <li><code class="directive"><a href="./mod/mod_cache.html#cacheignorenolastmod">CacheIgnoreNoLastMod</a></code>
              yönergesinin kullanımını gerektiren bir durum olmadıkça 200 durum
              koduna sahip bir yanıtın "Etag", "Last-Modified" ve "Expires"
              başlıklarından birini veya "Cache-Control:" başlığının "max-age" veya
              "s-maxage" yönergelerinden birini (en azından) içermesi gerekir.</li>
    
            <li><code class="directive"><a href="./mod/mod_cache.html#cachestoreprivate">CacheStorePrivate</a></code>
              yönergesinin kullanımını gerektiren bir durum olmadıkça yanıt
              "private" değerli bir "Cache-Control:" başlığı içerdiği takdirde
              yanıtın içeriği önbelleğe alınmayacaktır.</li>
    
            <li>Benzer şekilde, <code class="directive"><a href="./mod/mod_cache.html#cachestorenostore">CacheStoreNoStore</a></code> yönergesi kullanılmamışsa yanıt
              "no-store" değerli bir "Cache-Control:" başlığı içeriyorsa yanıt
              içeriği önbelleğe alınmayacaktır.</li>
    
            <li>Herşeyle eşleşen "*" değerli bir "Vary:" başlığı içeren bir
              yanıtın içeriği önbelleğe alınmaz.</li>
          </ol>
        
    
        <h3>Neler Önbelleklenmemeli?</h3>
          
    
          <p>İçerik zamana bağımlıysa ya da istek kısmen bile olsa HTTP uzlaşımıyla
            bağdaşmıyorsa önbelleğe alınmamalıdır. Bu içerik önbelleklenemeyeceğini
            <code>Cache-Control</code> başlığını kullanarak sunucuya
            bildirmelidir.</p>
    
          <p>İçerik sıkça değişiyorsa, tazelik ömrü dakikalar veya saniyelerle
            ifade ediliyorsa, içerik yine de önbelleklenebilir. Ancak, tam
            yanıtların düzenli olarak üretilmemesinin temini için  özgün sunucunun
            <strong>koşullu istekleri</strong> doğru olarak desteklemesi
            sağlanmalıdır.</p>
    
          <p>İstemcinin sağladığı istek başlıklarına dayanarak değişen içerik,
            <code>Vary</code> yanıt başlığının akıllıca kullanımıyla
            önbelleklenebilir.</p>
        
    
        <h3>Değişken/Uzlaşımlı İçerik</h3>
          
    
          <p>Özgün sunucu, istekteki başlık değerlerine dayanarak farklı
            içeriklerle yanıt vermeye ayarlandığı takdirde, örneğin aynı URL'de
            farklı dillerde içerik sunmak gibi, HTTP'nin önbellekleme mekanizması
            aynı URL'de aynı sayfanın değişik sürümlerini önbelleklemeyi mümkün
            kılar.</p>
    
          <p>Bu özgün sunucu tarafından bir <code>Vary</code> başlığı eklenerek
            yapılır. Bir sayfanın farklı sürümleri arasındaki farkları saptarken
            önbellek tarafından hangi başlıkların hesaba katılacağını
            <code>Vary</code> başlığı belirler.</p>
    
          <p>Örneğin, bir yanıt şöyle bir başlık ile alınmışsa,</p>
    
          <div class="example"><p><code>
            Vary: negotiate,accept-language,accept-charset
          </code></p></div>
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> sadece accept-language ve accept-charset
            başlıkları özgün istekle eşleşen önbellekli içeriği sunacaktır.</p>
    
          <p>İçeriğin farklı sürümleri yan yana önbelleklenebilir.
            <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü <code>Vary</code> başlığını
            kullanarak başlıkta listelenmiş istek başlıklarının uygun değerlerini
            saptar ve istemciye hangi sürümle yanıt verileceğine karar verir.</p>
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Önbellek Ayarlama Örnekleri</a></h2>
    
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code></li><li><code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code></li><li><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cacheroot">CacheRoot</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code></li><li><code class="directive"><a href="./mod/mod_cache_socache.html#cachesocache">CacheSocache</a></code></li></ul></td></tr></table>
    
        <h3><a name="disk" id="disk">Disk Üzerinde Önbellekleme</a></h3>
          
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü önbelleği yönetmek için çeşitli
          depolama ortamlarına özgü gerçeklenimleri kullanır. Diske önbellekleme
          desteğini <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> sağlar.</p>
    
          <p>Tipik olarak modül şöyle yapılandırılır:</p>
    
          <pre class="prettyprint lang-config">CacheRoot   "/var/cache/apache/"
    CacheEnable disk /
    CacheDirLevels 2
    CacheDirLength 1</pre>
    
    
          <p>En önemlisi önbelleklenen dosyaların yerel olarak saklanması olup
            işletim sisteminin sağladığı bellekiçi önbelleklemeden de ayrıca
            faydalanılmış olur. Bu bakımdan, dosyalar disk üzerinde saklansa bile
            sıkça erişilen dosyalar işletim sistemi sayesinde aslında bellekten
            sunulmuş olacaklardır.</p>
        
    
        <h3>Önbellekte Saklamanın Anlamı</h3>
          
    
          <p><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> öğeleri önbellekte saklamak için
            istek yapılan URL’nin 22 karakterlik özetini oluşturur. Bu özet, çok
            sayıda URL’nin aynı özeti oluşturmaması için konak ismi, protokol,
            port ve varsa CGI argümanlarından başka <code>Vary</code> başlığında
            tanımlı elemanlardan oluşur.</p>
    
          <p>Özeti oluşturan karakterler 64 karakterlik bir karakter kümesinden
            seçildiğinden oluşturulması olası farklı özet sayısı 64^22’dir.
            Örneğin, bir URL’nin <code>xyTGxSMO2b68mBCykqkp1w</code> gibi bir
            özeti olabilir. Bu özet, bu URL ile erişilen dosyalar önbellek içinde
            saklanırken dosya ismi öneki olarak kullanılır. Ancak bununla
            yetinilmez ve içerik <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code> ve <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code> yönergelerinin
            değerlerine göre önce dizinlere ayrılır.</p>
    
          <p><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code>
            yönergesi kaç alt seviye dizin olacağını ve <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code> her dizinde kaç
            karakter olacağını belirler. Örneğin, yukarıdaki
            özete sahip bir dosyanın isminin başına yukarıdaki yapılandırma
            örneğine uygun olarak
            <code>/var/cache/apache/x/y/TGxSMO2b68mBCykqkp1w</code> gibi bir önek
            getirilebilirdi.</p>
    
          <p>Bu tekniğin asıl amacı belli bir dizin içinde bulunabilecek
            dosyaların ve alt dizinlerin sayısını düşük tutmaktır. Bu sayının
            büyük olması çoğu işletim sisteminde başarımın düşmesine sebep olur.
            <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>
            yönergesi "1" değeriyle kullanıldığında her dizin altında en fazla 64
            alt dizin veya dosya açılabilir. "2" değeriyle kullanıldığında ise bu
            sayı 64^2’ye yükselir ve böyle artarak gider. İyi bir sebebiniz
            olmadıkça <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code> için değer olarak
            "1" belirtmenizi öneririz.</p>
    
          <p><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code>
            yönergesine atanacak değer önbellekte saklamayı düşündüğünüz olası
            dosya sayısı ile ilgilidir. Yukarıdaki örnekte olduğu gibi "2"
            değerini belirtirseniz, toplamda en fazla 4096 dizin oluşturulabilir.
            1 milyon dosyanın önbelleklendiği bir durumda bu, her dizinde yaklaşık
            olarak 245 önbelleklenmiş URL demektir.</p>
    
          <p>Her URL için önbellekte en az iki dosya saklanır. Biri genellikle URL
            hakkındaki temel verilerden oluşan ".header" dosyasıdır, diğeri ise
            sunulacak içeriğin bire bir kopyası olan ".data" dosyasıdır.</p>
    
          <p>"Vary" başlığı üzerinden içeriğin uzlaşıldığı durumda URL için bir
            ".vary" dizini oluşturulur. Bu dizin her biri farklı bir uzlaşıma ait
            çok sayıda ".data" dosyası içerebilir.</p>
        
    
        <h3>Disk Önbelleğinin Bakımı</h3>
          
    
          <p><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> zaman aşımına uğrayan önbellekli
            içeriği silse de önbelleğin toplam boyu ve ne kadar boş bellek kaldığı
            hakkında bilgi vermez.</p>
    
          <p>Bunun yerine httpd önbellek içeriğini düzenli aralıklarla
            temizleyebilmeniz için <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code> adında bir araç
            içerir.  Önbellek için azami ne kadar yer kullanılacağının ve bunun
            üzerinde <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code>’i hangi sıklıkta
            çalıştırılacağının tespiti biraz karmaşık bir işlem olup uygun değerler
            genellikle deneme yanılma yoluyla bulunur.</p>
    
          <p><code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code> iki işlem kipine sahiptir. Kalıcı bir
            artalan süreci olarak çalışabileceği gibi cron üzerinden belli
            aralıklarla da çalıştırılabilir. Çok büyük (onlarca GB) önbelleklerde
            <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code>’in işini bitirmesi 1 saatten fazla
            sürebileceğinden, cron ile çalıştırma durumunda aynı anda birden fazla
            kopyanın çalışıyor durumda olmaması için
            <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code>’in çalıştırılma aralığını iyi
            belirlemek gerekir.</p>
    
          <p>Ayrıca, <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code> için uygun bir "nice" seviyesi
            seçilmesi önerilr. Böylece, sunucu çalışırken aracın ölçüsüz disk g/ç
            yapmasına sebebiyet verilmemiş olur.</p>
    
          <p class="figure">
          <img src="images/caching_fig1.tr.png" alt="" width="600" height="406" /><br />
          <a id="figure1" name="figure1"><dfn>Şekil 1</dfn></a>:
     Önbelleğin büyümesi ve düzenli aralıklarla temizlenmesi.</p>
    
          <p><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> ne kadar bellek kullanıldığı hakkında
            bilgi vermediğinden, <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code>'in bir temizliğin
            ardından yeterli bir büyüme alanı kalacak şekilde yapılandırılması
            temin edilmelidir.</p>
        
        
        <h3><a name="memcache" id="memcache">memcached ile önbellekleme</a></h3>
          
    
          <p><code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code> modülünü kullanarak, 
            <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> çeşitli gerçeklenimlerden (diğer adıyla: 
            "sağlayıcılar"dan) gelen veriyi önbellekleyebilir.   
            <code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code> modülü kullanılarak, örneğin, 
            artalan saklama mekanizması olarak 
            <a href="http://memcached.org">memcached</a> kullanıldığı 
            söylenebilir.</p>
    
          <p>Genelde modül şöyle yapılandırılır:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache memcache:memcd.example.com:11211</pre>
    
    
          <p>İlave <code>memcached</code> sunucular 
            <code>CacheSocache memcache:</code> satırının ardına virgüllerle 
            ayrılarak eklenebilir:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache memcache:mem1.example.com:11211,mem2.example.com:11212</pre>
    
    
          <p>Bu biçim diğer <code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code> sağlayıcıları için de kullanılabilir:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache shmcb:/path/to/datafile(512000)</pre>
    
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache dbm:/path/to/datafile</pre>
    
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="socache-caching" id="socache-caching">Genel İki durumlu Anahtar/Değer Paylaşımlı Nesne Önbellekleme</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code></li><li><code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code></li><li><code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code></li><li><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></li><li><code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code></li><li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code></li></ul></td></tr></table>
    
        <p>Apache HTTP sunucusu, SSL oturumları, kimlik doğrulama bilgileri gibi
          önbelleklenebilen özel bilgiler için <a href="socache.html">socache</a>
          arayüzü içinde düşük seviyeli bir paylaşımlı nesne önbelleğine
          sahiptir.</p>
    
        <p>Her gerçeklenime uygun ek modüller de sağlanmıştır:</p>
    
        <dl>
        <dt><code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code></dt>
        <dd>DBM tabanlı paylaşımlı nesne önbelleklemesi.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code></dt>
        <dd>Distcache tabanlı paylaşımlı nesne önbelleklemesi.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></dt>
        <dd>Memcache tabanlı paylaşımlı nesne önbelleklemesi.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code></dt>
        <dd>Paylaşımlı belleğe dayalı paylaşımlı nesne önbelleklemesi.</dd>
        </dl>
    
        <h3><a name="mod_authn_socache-caching" id="mod_authn_socache-caching">Kimlik Doğrulama Bilgilerinin Önbelleklenmesi</a></h3>
          
    
          <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code></li></ul></td></tr></table>
    
          <p><code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code> modülü kimlik doğrulama araçlarının
            yükünün hafifletilmesini, kimlik doğrulama sonucunun önbelleklenmesini
            sağlar.</p>
        
    
        <h3><a name="mod_ssl-caching" id="mod_ssl-caching">SSL Oturumlarının Önbelleklenmesi</a></h3>
          
    
          <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code></li></ul></td></tr></table>
    
          <p><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> modülü, oturum önbelleği ve önbellek
           zımbalaması sağlamak için <code>socache</code> arayüzünü kullanır.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-caching" id="file-caching">Uzmanlaşmış Dosya Önbellekleme</a></h2>
        
    
         <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code></li><li><code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code></li></ul></td></tr></table>
    
        <p>Dosya sisteminin yavaş olabildiği veya dosya tanıtıcılarının
          kullanımının pahalıya mal olduğu sistemlerde, sunucunun başlatılması
          sırasında dosyaların belleğe yüklenmesi seçeneği vardır.</p>
    
        <p>Dosyaların açılmasının yavaş olduğu sistemlerde, dosyaların sunucunun
          başlatılması sırasında açılması ve dosya tanıtıcısını önbelleklenmesi
          seçeneği vardır. Bu seçeneklerin duruk dosyalara erişimin yavaş olduğu
          sistemlere de bir yardımı olabilir.</p>
    
        <h3><a name="filehandle" id="filehandle">Dosya Tanıtıcı Önbelleklemesi</a></h3>
          
    
          <p>Bir dosyanın açılması işlemi, özellikle de ağ dosya sistemlerinde
            bulunan dosyalar için önemli bir gecikme kaynağı olabilir. Önbellekte,
            çok sunulan dosyaların kendilerinin değil, açık dosya tanıtıcılarının
            saklanması httpd’yi bu tür gecikmelerden koruyabilir. httpd’de tek
            türde dosya tanıtıcı önbelleklemesi yapılabilmektedir.</p>
    
          <h4><code>CacheFile</code> yönergesi ile</h4>
            
    
            <p>httpd’de mevcut önbelleklemenin en temel şekli
              <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> tarafından sağlanan dosya tanıtıcı
              önbelleklemesidir. Bu önbellek türü dosyaların kendilerini değil açık
              dosya tanıtıcılarının bir listesini saklar. Dosyaların bu anlamda
              önbelleklenmesi, <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code> yönergesi yapılandırma dosyasında belirtilerek
              sağlanabilir.</p>
    
            <p><code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code> yönergesi
              belirtilen dosyanın httpd başlatıldığında açılmasını ve dosya için
              yapılan sonraki her istekte bu dosya tanıtıcısının kullanılmasını
              sağlar.</p>
    
            <pre class="prettyprint lang-config">CacheFile /usr/local/apache2/htdocs/index.html</pre>
    
    
            <p>Büyük miktarda dosyayı bu anlamda önbelleklemeyi tasarlıyorsanız
              işletim sisteminizin açık dosya tanıtıcılarının sayısı ile ilgili
              sınırlamasını uygun bir değere ayarlamanız gerekebilir.</p>
    
            <p><code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code> yönergesini
              kullandığınız takdirde dosya içeriğindeki değişiklikleri anında
              isteğe yansıtamazsınız. httpd dosyayı ilk başlatıldığındaki haliyle
              sunar.</p>
    
            <p>Eğer httpd çalışırken dosya silinmişse httpd ilk başlatıldığındaki
              haline ilişkin dosya tanıtıcıyı sağlamaya ve dolayısıyla dosya
              içeriğini sunmaya devam edecektir. Yani, dosya silinmiş ve artık
              dosya sisteminde görünmüyor olsa bile httpd durdurulup dosya
              tanıtıcıları kapanmadıkça dosyaların silinmesiyle açılan yer serbest
              kalmayacaktır.</p>
          
    
        
    
        <h3><a name="inmemory" id="inmemory">Sistem Belleğinde Önbellekleme</a></h3>
          
    
          <p>İçeriğin sistem belleğinden sunulması içerik sunmanın evrensel olarak
          en hızlı yoludur. Dosyaların bir disk denetleyiciden okunması ya da daha
          kötüsü uzak bir ağdan okunması bellekten okumayla karşılaştırılamayacak
          ölçüde yavaş işlemlerdir. Disk denetleyiciler genellikle fiziksel
          süreçleri denetlerler. Ağ erişimi ise band genişliği sınırlamalarından
          etkilenir. Halbuki bellek erişimi sadece nano saniyeler mertebesinde
          gerçekleşir.</p>
    
          <p>Sistem belleği en pahalı saklama ortamı olması sebebiyle en verimli
          şekilde kullanımı önemlidir. Dosyaları sistem belleğinde saklamakla
          sistemin kullanabileceği bellek miktarını azaltmış olursunuz. İşletim
          sistemi önbelleklemesinde göreceğiniz gibi bu öyle basit bir konu
          değildir. httpd’nin kendi kullandığı belleğin bir kısmını önbellek
          olarak ayırırken çok fazla bellek kullanmamak önemlidir. Aksi takdirde
          işletim sistemi belleğin yetmediği noktada belleği diske
          takaslayacağından istenen başarım artışı sağlanamayacaktır.</p>
    
          <h4>İşletim Sistemi Önbelleklemesi</h4>
            
    
            <p>Günümüz iştetim sistemlerinin hemen hemen tamamında bellek içi
            dosya/veri saklama işlemlerini çekirdek yönetir. Bu güçlü bir
            özelliktir ve işletim sistemlerinin büyük çoğunluğu bunu böyle yapar.
            Örneğin, Linux’ta bir dosyanın ilk defa okunduğunda ve ikinci kez
            okunduğunda işlemcinin ne kadar meşgul edildiğine bakalım:</p>
    
            <div class="example"><p><code>
              colm@coroebus:~$ time cat testfile &gt; /dev/null<br />
              real    0m0.065s<br />
              user    0m0.000s<br />
              sys     0m0.001s<br />
              colm@coroebus:~$ time cat testfile &gt; /dev/null<br />
              real    0m0.003s<br />
              user    0m0.003s<br />
              sys     0m0.000s
            </code></p></div>
    
            <p>Küçük bir dosya için bile okuma süresi bakımından büyük fark ortaya
              çıkmaktadır. Bunun sebebi çekirdeğin dosya içeriğini bellek daha
              güncel amaçlar için lazım olana dek bellek içinde saklamasıdır.</p>
    
            <p>Sisteminizde yeterince yedek bellek olduğundan eminseniz, bu
              önbellekte daha fazla dosya saklanacağından emin olabilirsiniz.
              Bundan, önbelleğin sistem belleğinde verimli biçimde tutulması için
              httpd’de ek bir yapılandırmaya gidilmesinin gerekmediği sonucu
              çıkarılabilir.</p>
    
            <p>Bundan başka, işletim sistemi dosyaların değiştiği ve silindiği
              zamanları bildiğinden bu tür dosyaların içerikleri gerektiğinde
              önbellekten kendiliğinden silinmiş olur. Bellek içinde dosya
              saklarken dosyaların değiştirilme zamanlarını bilme olanağı
              olmadığından bu durum httpd’ye büyük yarar sağlar.</p>
          
    
          <p>İşletim sisteminin dosyaların önbelleklenmesi için sağladığı bunca
            yarara ve başarım artışına karşın bellek içinde dosya önbelleklemenin
            httpd tarafından yerine getirilmesinin daha iyi olacağı bazı durumlar
            vardır.</p>
    
          <h4><code>MMapFile</code> yönergesi ile</h4>
            
    
            <p><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> modülü, bir durağan dosyanın
              içeriğini sunucunun başlatılması sırasında (mmap sistem çağrısıyla)
              belleğe eşlenmesini mümkün kılmak için <code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code> yönergesini sağlar.
              httpd bu dosyaya gelecek sonraki istekler için dosyanın bellekiçi
              içeriğini kullanacaktır.</p>
    
            <pre class="prettyprint lang-config">MMapFile /usr/local/apache2/htdocs/index.html</pre>
    
    
            <p><code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code>
              yönergesinde olduğu gibi bu dosyalarda httpd başlatıldıktan sonra
              yapılacak bir değişiklikten httpd’nin haberi olmayacaktır.</p>
    
            <p><code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code> yönergesi
              ayırdığı belleğin toplam miktarı ile ilgilenmez, dolayısıyla
              yönergenin aşırı kullanımından kaçınmalısınız. httpd’nin çocuk
              süreçlerinin her biri bu belleğin kendilerine ait birer kopyasını
              yapacağından belleğe eşlenen dosyaların çok yer kaplamaması büyük
              önem taşımaktadır; aksi takdirde işletim sistemi belleği diske
              takaslayacağından beklenen fayda sağlanamayacaktır.</p>
          
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Güvenlik Kaygıları</a></h2>
        
    
        <h3>Erişim Denetimi ve Yetkilendirme</h3>
          
    
          <p><code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code>
            yönergesine <code>On</code> değerinin atandığı öntanımlı durumda
            <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> kullanımı, daha çok sunucunun önüne
            vidalanmış önbelleklemeli bir karşı vekile sahip olmak gibidir. Özgün
            sunucunun bir harici önbellekmiş gibi sorgulanmasını gerektirmeyen tüm
            istekler önbellekleme modülü tarafından karşılanacaktır. Bu durum
            httpd'nin güvenlik modelini büyük ölçüde değiştirir.</p>
    
          <p>Olası <code>.htaccess</code> dosyalarının dosya sisteminin tamamında
            taranması çok pahalı bir işlem olduğundan <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>,
            (işlemi hızlandırmak için) önbelleğe almanın temel amacını kısmen
            gözardı ederek, önbellekteki içeriğin sunumu için gerekli
            yetkilendirmenin olup olmadığı konusunda bir karar üretmez. Başka bir
            deyişle, eğer <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> bir kısım içeriği önbelleğe
            almışsa içerik zaman aşımına uğramadığı sürece bu içerik önbellekten
            sunulacaktır.</p>
    
          <p>Örneğin, yapılandırmanız bir özkaynağa IP adresine göre erişime izin
            veriyorsa bu içeriğin önbelleğe alınmayacağından emin olmalısınız.
            Bunu <code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code>
            yönergesini veya <code class="module"><a href="./mod/mod_expires.html">mod_expires</a></code> modülünü kullanarak
            yapabilirsiniz. Bunu yapmaz, olayı kendi haline bırakırsanız
            <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> bir karşı vekil gibi çalışarak sunulan her
            içeriği önbelleğe alacak ve hangi IP adresinden gelirse gelsin her
            istemciye bunu sunacaktır.</p>
    
          <p><code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code>
            yönergesine <code>Off</code> atandığı takdirde, istek işleme
            aşamalarının tamamı yerine getirilir ve güvenlik modeli değişmeden
            kalır.</p>
        
    
        <h3>Yerel İstismarcılar</h3>
          
    
          <p>Son kullanıcılarıın isteklerine önbellekten hizmet sunulduğundan
            önbelleğin kendisi içerikle etkileşime geçmek isteyenlerin veya
            içeriği tahrif etmek isteyenlerin hedefi haline gelebilir. httpd’yi
            çalıştıran kullanıcı tarafından her zaman önbelleğe yazılabileceğini
            akıldan çıkarmamak önemlidir. Bu durumda alışılmışın tersine tüm
            içeriğin Apache kullanıcısı tarafından yazılamamasının sağlanması
            önerilir.</p>
    
          <p>Eğer Apache kullanıcısı, örneğin bir CGI sürecindeki açık nedeniyle
            tehlikeye atılırsa, önbellek hedef alınabilir.
            <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> kullanılırken önbellekteki bir öğeyi
            değiştirmek veya önbelleğe yeni bir öğe eklemek görece daha
            kolaydır.</p>
    
          <p>Bu risk, Apache kullanıcısını kullanan diğer saldırı türleriyle
            karşılaştırıldığında daha yüksektir. <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>
            kullanıyorsanız şunları aklınızdan çıkarmayın: (1) httpd güvenlik
            güncellemelerini takip edin ve sunucunuzu buna göre güncelleyin. (2)
            Mümkünse <a href="suexec.html">suEXEC</a> kullanarak CGI süreçlerini
            Apache kullanıcısı olmayan bir kullanıcının aidiyetinde çalıştırın.</p>
        
    
        <h3>Önbellek Zehirlenmeleri</h3>
          
    
          <p>httpd bir önbellekli vekil sunucu olarak çalıştığında önbellek
            zehirlenmesi adı verilen sorunla karşılaşılma olasılığı vardır.
            Önbellek zehirlenmesi, vekil sunucunun özgün sunucudan yanlış (ve
            genellikle istenmeyen) içerik almasına sebep olan bir saldırı türünü
            betimlemek için yaygın olarak kullanılan bir terimdir.</p>
    
          <p>Örneğin httpd’nin çalıştığı sistemin kullandığı DNS sunucuları DNS
            önbellek zehirlenmesinden etkilenebilecek durumdaysa, bir saldırgan
            httpd’nin istekleri almak için başvuracağı kaynak sunucunun yerini
            değiştirebilir. Diğer bir örnek, HTTP istek kaçakçılığı adı verilen
            bir saldırı türüdür.</p>
    
          <p>Bu belge HTTP istek kaçakçılığını derinliğine incelenmesi için uygun
            yer değildir (böyle kaynaklara arama motorunuzla erişebilirsiniz).
            Bununla birlikte, vekil tarafından kaynak sunucudan alınan içeriği
            tamamen denetim altına almak amacıyla kaynak sunucudaki bir açığı
            istismar etmeye yönelik bir dizi istek yapılabileceğinin olasılık
            dahilinde olduğunu bilmenizde yarar vardır.</p>
        
    
        <h3>Hizmet Reddi / Önbelleğin Engellenmesi</h3>
          
    
          <p>Vary mekanizması aynı URL'nin çok sayıda sürümünün yan yana
            önbelleklenmesini mümkün kılar. İstemci tarafından sağlanan başlık
            değerlerine bağlı olarak, önbellek istemciye gönderilecek doğru yanıtı
            bulacaktır. Normal kullanımda olası değerlerin çok geniş olduğunun
            bilindiği durumda bir başlığı (örn, <code>User-Agent</code>)
            değişikliğe uğratma çabası bu mekanizmayı bir sorun haline getirebilir.
            Sitenin tanınırlığına bağlı olarak aynı URL'nin binlerce hatta
            milyonlarca önbellek girdisi oluşabilir ve bunlar önbellekteki diğer
            girdilerin yerini alabilir.</p>
    
          <p>Diğer yandan, belli bir özkaynağın URL'sinin her istekte
          değiştirilmesi ihtiyacı ortaya çıkabilir. Bu normalde URL dizgesine bir
          "cachebuster" dizgesi eklenerek yapılır. Bu içerik sunucu tarafından
          anlamlı bir tazelik ömrüyle önbelleklenebilir olarak imlenmişse bu
          girdiler kısa zamanda önbellekteki meşru girdilerin yerini alabilir.
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü bunun önlenmesi için <code class="directive"><a href="./mod/mod_cache.html#cacheignoreurlsessionidentifiers">CacheIgnoreURLSessionIdentifiers</a></code>
          yönergesine sahipse de bu yönerge, yoldaki vekillerin veya tarayıcı
          önbelleklerinin aynı hizmet reddi saldırısına maruz kalmamaları için
          dikkatle kullanılmalıdır.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/caching.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/caching.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/caching.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/caching.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/env.html.en����������������������������������������������������������������0000664�0001751�0001751�00000075764�14737241666�017151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Environment Variables in Apache - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Environment Variables in Apache</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/env.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>There are two kinds of environment variables that affect
        the Apache HTTP Server.</p>
    
        <p>First, there are the environment variables controlled by
        the underlying operating system.  These are set before the
        server starts.  They can be used in expansions in configuration
        files, and can optionally be passed to CGI scripts and SSI
        using the PassEnv directive.</p>
    
        <p>Second, the Apache HTTP Server provides a mechanism for storing
        information in named variables that are also called <em>environment
        variables</em>. 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.</p>
    
        <p>Although these variables are referred to as <em>environment
        variables</em>, 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.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#setting">Setting Environment Variables</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Using Environment Variables</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#special">Special Purpose Environment Variables</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Examples</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setting" id="setting">Setting Environment Variables</a></h2>
        
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_env.html">mod_env</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li><li><code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifnocase">SetEnvIfNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#unsetenv">UnsetEnv</a></code></li></ul></td></tr></table>
    
        <h3><a name="basic-manipulation" id="basic-manipulation">Basic Environment Manipulation</a></h3>
            
    
            <p>The most basic way to set an environment variable in Apache
            is using the unconditional <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> directive. Variables may also be passed from
            the environment of the shell which started the server using the
            <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> directive.</p>
    
        
        <h3><a name="conditional" id="conditional">Conditional Per-Request Settings</a></h3>
            
    
            <p>For additional flexibility, the directives provided by
            <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> 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 <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>'s <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> which uses the
            <code>[E=...]</code> option to set environment variables.</p>
    
        
        <h3><a name="unique-identifiers" id="unique-identifiers">Unique Identifiers</a></h3>
            
    
            <p>Finally, <code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code> sets the environment
            variable <code>UNIQUE_ID</code> for each request to a value which is
            guaranteed to be unique across "all" requests under very
            specific conditions.</p>
    
        
        <h3><a name="standard-cgi" id="standard-cgi">Standard CGI Variables</a></h3>
            
    
            <p>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 <a href="http://www.ietf.org/rfc/rfc3875">CGI
            specification</a>.</p>
    
        
        <h3><a name="caveats" id="caveats">Some Caveats</a></h3>
            
    
            <ul>
              <li>It is not possible to override or change the standard CGI
              variables using the environment manipulation directives.</li>
    
              <li>When <code class="program"><a href="./programs/suexec.html">suexec</a></code> is used to launch
              CGI scripts, the environment will be cleaned down to a set of
              <em>safe</em> variables before CGI scripts are launched. The
              list of <em>safe</em> variables is defined at compile-time in
              <code>suexec.c</code>.</li>
    
              <li>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.</li>
    
              <li>A special case are HTTP headers which are passed to CGI
              scripts and the like via environment variables (see below).
              They are converted to uppercase and only dashes are replaced with
              underscores; if the header contains any other (invalid) character,
              the whole header is silently dropped. See <a href="#fixheader">
              below</a> for a workaround.</li>
    
              <li>The <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> directive runs
              late during request processing meaning that directives such as
              <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> and <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> will not see the
              variables set with it.</li>
    
              <li>When the server looks up a path via an internal
              <a class="glossarylink" href="./glossary.html#subrequest" title="see glossary">subrequest</a> such as looking
              for a <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>
              or generating a directory listing with <code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code>,
              per-request environment variables are <em>not</em> inherited in the 
              subrequest. Additionally, 
              <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> directives
              are not separately evaluated in the subrequest due to the API phases
               <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> takes action in.</li>
            </ul>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Using Environment Variables</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_access_compat.html#allow">Allow</a></code></li><li><code class="directive"><a href="./mod/mod_access_compat.html#deny">Deny</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li></ul></td></tr></table>
    
        <h3><a name="cgi-scripts" id="cgi-scripts">CGI Scripts</a></h3>
            
    
            <p>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
            <a href="howto/cgi.html">CGI tutorial</a>.</p>
    
        
        <h3><a name="ssi-pages" id="ssi-pages">SSI Pages</a></h3>
            
    
            <p>Server-parsed (SSI) documents processed by
            <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>'s
            <code>INCLUDES</code> filter can print environment variables
            using the <code>echo</code> 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 <a href="howto/ssi.html">SSI tutorial</a>.</p>
    
        
        <h3><a name="access-control" id="access-control">Access Control</a></h3>
            
    
            <p>Access to the server can be controlled based on
            environment variables using the <code>Require env</code>
            and <code>Require not env</code> directives. In combination with
            <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>, 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).
            </p>
    
        
        <h3><a name="logging" id="logging">Conditional Logging</a></h3>
            
    
            <p>Environment variables can be logged in the access log using
            the <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>
            option <code>%e</code>. 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
            <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
            directive. In combination with <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> this allows for flexible control of which
            requests are logged. For example, you can choose not to log
            requests for filenames ending in <code>gif</code>, or you can
            choose to only log requests from clients which are outside your
            subnet.</p>
    
        
        <h3><a name="response-headers" id="response-headers">Conditional Response Headers</a></h3>
            
    
            <p>The <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code>
            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.</p>
    
        
    
        <h3><a name="external-filter" id="external-filter">External Filter Activation</a></h3>
            
    
            <p>External filters configured by <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>
            using the <code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code> directive can
            by activated conditional on an environment variable using the
            <code>disableenv=</code> and <code>enableenv=</code> options.</p>
        
    
        <h3><a name="url-rewriting" id="url-rewriting">URL Rewriting</a></h3>
            
    
            <p>The <code>%{ENV:<em>variable</em>}</code> form of
            <em>TestString</em> in the <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> allows <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>'s rewrite
            engine to make decisions conditional on environment variables.
            Note that the variables accessible in <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
            without the <code>ENV:</code> prefix are not actually environment
            variables. Rather, they are variables special to
            <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> which cannot be accessed from other
            modules.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="special" id="special">Special Purpose Environment Variables</a></h2>
        
    
            <p>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 <code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code>, though <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> and  <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> could also be used, for example.</p>
    
        <h3><a name="downgrade" id="downgrade">downgrade-1.0</a></h3>
            
    
            <p>This forces the request to be treated as a HTTP/1.0 request
            even if it was in a later dialect.</p>
    
        
        <h3><a name="force-gzip" id="force-gzip">force-gzip</a></h3>
            
              <p>If you have the <code>DEFLATE</code> filter activated, this
              environment variable will ignore the accept-encoding setting of
              your browser and will send compressed output unconditionally.</p>
        
        <h3><a name="force-no-vary" id="force-no-vary">force-no-vary</a></h3>
            
    
            <p>This causes any <code>Vary</code> 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 <strong>force-response-1.0</strong>.</p>
    
        
        <h3><a name="force-response" id="force-response">force-response-1.0</a></h3>
            
    
          <p>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.</p>
    
        
    
        <h3><a name="gzip-only-text-html" id="gzip-only-text-html">gzip-only-text/html</a></h3>
            
    
            <p>When set to a value of "1", this variable disables the
            <code>DEFLATE</code> output filter provided by
            <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> for content-types other than
            <code>text/html</code>. If you'd rather
            use statically compressed files, <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>
            evaluates the variable as well (not only for gzip, but for all
            encodings that differ from "identity").</p>
        
    
        <h3><a name="no-gzip" id="no-gzip">no-gzip</a></h3>
    
            <p>When set, the <code>DEFLATE</code> filter of
            <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> will be turned off and
            <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> will refuse to deliver encoded
            resources.</p>
    
        
    
        <h3><a name="no-cache" id="no-cache">no-cache</a></h3>
            <p><em>Available in versions 2.2.12 and later</em></p>
    
            <p>When set, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> will not save an otherwise
            cacheable response.  This environment variable does not influence
            whether a response already in the cache will be served for the current
            request.</p>
    
        
    
        <h3><a name="nokeepalive" id="nokeepalive">nokeepalive</a></h3>
            
    
            <p>This disables <code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code>
            when set.</p>
    
        
    
        <h3><a name="prefer-language" id="prefer-language">prefer-language</a></h3>
    
            <p>This influences <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>'s behaviour. If
            it contains a language tag (such as <code>en</code>, <code>ja</code>
            or <code>x-klingon</code>), <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> tries
            to deliver a variant with that language. If there's no such variant,
            the normal <a href="content-negotiation.html">negotiation</a> process
            applies.</p>
    
        
    
        <h3><a name="redirect-carefully" id="redirect-carefully">redirect-carefully</a></h3>
            
    
            <p>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.</p>
    
        
    
       <h3><a name="suppress-error-charset" id="suppress-error-charset">suppress-error-charset</a></h3>
           
    
        <p><em>Available in versions after 2.0.54</em></p>
    
        <p>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.</p>
    
        <p> 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.</p>
    
        <p>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.</p>
    
        <div class="warning">
          <h3>Security note</h3>
    
          <p>Sending error pages without a specified character set may
          allow a cross-site-scripting attack for existing browsers (MSIE)
          which do not follow the HTTP/1.1 specification and attempt to
          "guess" the character set from the content.  Such browsers can
          be easily fooled into using the UTF-7 character set, and UTF-7
          content from input data (such as the request-URI) will not be
          escaped by the usual escaping mechanisms designed to prevent
          cross-site-scripting attacks.</p>
        </div>
    
       
    
       <h3><a name="proxy" id="proxy">force-proxy-request-1.0, proxy-nokeepalive, proxy-sendchunked,
       proxy-sendcl, proxy-chain-auth, proxy-interim-response, proxy-initial-not-pooled</a></h3>
    
       <p>These directives alter the protocol behavior of
       <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.  See the <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> and <code class="module"><a href="./mod/mod_proxy_http.html">mod_proxy_http</a></code>
       documentation for more details.</p>
       
    
       <h3><a name="cgilike" id="cgilike">ap_trust_cgilike_cl</a></h3>
       <p><em>Available in 2.4.59 and later</em></p>
         <p> This variable allows a script running in CGI-like module to supply it's
             own Content-Length HTTP response header. It should
             only be set on configuration sections that contain trusted scripts.
         </p>
       
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Examples</a></h2>
        
    
        <h3><a name="fixheader" id="fixheader">Passing broken headers to CGI scripts</a></h3>
          
    
          <p>Starting with version 2.4, Apache is more strict about how HTTP
          headers are converted to environment variables in <code class="module"><a href="./mod/mod_cgi.html">mod_cgi
          </a></code> and other modules:  Previously any invalid characters
          in header names were simply translated to underscores.  This allowed
          for some potential cross-site-scripting attacks via header injection
          (see <a href="http://events.ccc.de/congress/2007/Fahrplan/events/2212.en.html">
          Unusual Web Bugs</a>, slide 19/20).</p>
    
          <p>If you have to support a client which sends broken headers and
          which can't be fixed, a simple workaround involving <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif
          </a></code> and <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> allows you to still accept
          these headers:</p>
    
    <pre class="prettyprint lang-config">#
    # The following works around a client sending a broken Accept_Encoding
    # header.
    #
    SetEnvIfNoCase ^Accept.Encoding$ ^(.*)$ fix_accept_encoding=$1
    RequestHeader set Accept-Encoding %{fix_accept_encoding}e env=fix_accept_encoding</pre>
    
    
        
    
        <h3><a name="misbehaving" id="misbehaving">Changing protocol behavior with misbehaving clients</a></h3>
            
    
            <p>Earlier versions recommended that the following lines be included in
            httpd.conf to deal with known client problems.  Since the affected clients
            are no longer seen in the wild, this configuration is likely no-longer
            necessary.</p>
    <pre class="prettyprint lang-config">#
    # 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 understand 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</pre>
    
    
        
        <h3><a name="no-img-log" id="no-img-log">Do not log requests for images in the access log</a></h3>
            
    
            <p>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.</p>
    
            <pre class="prettyprint lang-config">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</pre>
    
    
        
        <h3><a name="image-theft" id="image-theft">Prevent "Image Theft"</a></h3>
            
    
            <p>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 <code>/web/images</code>.</p>
    
            <pre class="prettyprint lang-config">SetEnvIf Referer "^http://www\.example\.com/" local_referal
    # Allow browsers that do not send Referer info
    SetEnvIf Referer "^$" local_referal
    &lt;Directory "/web/images"&gt;
        Require env local_referal
    &lt;/Directory&gt;</pre>
    
    
            <p>For more information about this technique, see the
            "<a href="https://www.serverwatch.com/guides/keeping-your-images-from-adorning-other-sites/">Keeping Your Images from Adorning Other Sites</a>"
            tutorial on ServerWatch.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/env.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/env.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������httpd-2.4.64/docs/manual/content-negotiation.html.ja.utf8�������������������������������������������0000664�0001751�0001751�00000121736�14743132254�023202� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>コンテントネゴシエーション - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>コンテントネゴシエーション</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    
        <p>Apache は HTTP/1.1 の規格に記述されているコンテントネゴシエーションを
        サポートしています。
        ブラウザにより提供されたメディアタイプ、
        言語、文字セット、エンコーディングの優先傾向に基づいて、
        最適なリソースの表現を選択できます。
        また、不完全なネゴシエーション情報を送ってくるブラウザからのリクエストを
        もっと賢く取り扱えるよう、いくつか機能も実装してあります。</p>
    
        <p>コンテントネゴシエーションは
        <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>
        モジュールによって提供されていて、デフォルトで組み込まれています。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#about">コンテントネゴシエーションについて</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#negotiation">Apache におけるネゴシエーション</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#methods">ネゴシエーション方法</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#better">品質の値を変える</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extensions">Transparent Content Negotiation
    の拡張</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#naming">リンクと名前の変換に関する注意点</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#caching">キャッシュに関する注意事項</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="about" id="about">コンテントネゴシエーションについて</a></h2>
    
        <p>リソースは、幾つか異なった表現で利用できる場合があります。
        例えば、異なる言語や異なるメディアタイプ、
        またはそれらの組み合わせで利用できるかも知れません。
        もっとも適した選択をする方法の一つには、インデックスページを
        ユーザに見せて、ユーザに選んでもらう方法があります。
        しかし、サーバが自動的に選ぶことができる場合が多くあります。
        これは、ブラウザがリクエスト毎に、
        どの表現を嗜好するかという情報を送ることで動作しています。
        例えばブラウザは、可能ならフランス語で情報を見たい、
        不可能ならその代わりに英語でもよいと、
        自分の嗜好を知らせることができます。
        ブラウザはリクエストのヘッダで自分の優先傾向を知らせます。
        フランス語のみの表現を要求する場合は、ブラウザは次を送ります。</p>
    
    <div class="example"><p><code>Accept-Language: fr</code></p></div>
    
        <p>この優先傾向は、選択可能な表現が存在して、
        言語によって様々な表現がある場合にのみ適用される
        ということに注意してください。</p>
    
        <p>もっと複雑なリクエストの例を挙げましょう。
        このブラウザはフランス語と英語を受け付ける、しかしフランス語を好む、
        そして様々なメディアタイプを受け付けるが、
        プレインテキストや他のタイプよりは HTML を好む、
        他のメディアタイプよりは GIF や JPEG を好む、しかし最終手段として
        他のメディアタイプも受け付ける、と設定されています。</p>
    
    <div class="example"><p><code>
      Accept-Language: fr; q=1.0, en; q=0.5<br />
      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
    </code></p></div>
    
        <p>Apache は HTTP/1.1 規格で定義されている 'server
        driven' コンテントネゴシエーションをサポートしています。
        <code>Accept</code>, <code>Accept-Language</code>, 
        <code>Accept-Charset</code>, <code>Accept-Encoding</code>
        リクエストヘッダを完全にサポートしています。Apache は
        'transparent' コンテントネゴシエーションもサポートしていますが、
        これは RFC 2295 と RFC 2296 で定義されている試験的な
        ネゴシエーションプロトコルです。
        これらの RFCで定義されている 'feature negotiation'
        はサポートしていません。</p>
    
        <p><strong>リソース</strong>とは URI
        で特定される概念上のもののことです (RFC 2396)。 Apache
        のような HTTP サーバは、その名前空間の中での
        リソースの<strong>表現</strong>へのアクセスを提供します。
        それぞれの表現は
        定義されたメディアタイプ、文字セット、エンコーディング等の
        付属した、バイト列の形式です。
        それぞれのリソースはある時点で 0 個、1 個、それ以上の表現と
        関連付けられる可能性があります。複数の表現が利用できる場合は、
        リソースは<strong>ネゴシエーション可能である</strong>とされ、
        個々の表現は <strong>variant</strong> と呼ばれます。
        ネゴシエーション可能なリソースの variant が異なる、
        その状態を指して、
        ネゴシエーションの<strong>次元</strong>と呼びます。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="negotiation" id="negotiation">Apache におけるネゴシエーション</a></h2>
    
        <p>リソースをネゴシエーションするためには、
        サーバは variant それぞれについての情報を知っておく必要があります。
        これは以下の二つの方法のどちらかで行われます。</p>
    
        <ul>
          <li>タイプマップ
          (<em>すなわち</em> <code>*.var</code> ファイル)
          を使う方法。 これは variant
          を明示的に挙げているファイルを指定します。</li>
    
          <li>'Multiviews'
          を使って、サーバが暗黙の内にファイル名にパターン照合を
          行なってその結果から選択する方法。</li>
        </ul>
    
       <h3><a name="type-map" id="type-map">type-map ファイルを使う</a></h3>
    
        <p>タイプマップは <code>type-map</code> ハンドラ
        (もしくは、古い Apache
        の設定と下位互換である <a class="glossarylink" href="./glossary.html#mime-type" title="用語集を参照">MIME タイプ</a>
        <code>application/x-type-map</code>)
        に関連付けられたドキュメントです。
        この機能を使うためには、あるファイルの拡張子を
        <code>type-map</code>
        として定義するようなハンドラを、
        設定ファイル中に置く必要があることに注意してください。
        これは</p>
    
    <div class="example"><p><code>AddHandler type-map .var</code></p></div>
    
        <p>をサーバ設定ファイル中に書くことが一番良い方法です。</p>
    
        <p>タイプマップファイルは記述するリソースと同じ名前を持っていて、
        利用可能な variant それぞれのエントリを持っている必要があります。
        そして、このエントリは連続した HTTP のヘッダ行で構成されます。
        異なる variant のためのエントリは空行で区切られています。
        エントリ中に空行が複数あってはいけません。
        習慣的には、マップファイルは全体を結合したもののエントリから始まります
        (しかしこれは必須ではなく、あったとしても無視されるものです)。
        次に例を示します。このファイルはリソース <code>foo</code> 
        を記述しているので、<code>foo.var</code> という名前になります。</p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.en.html<br />
      Content-type: text/html<br />
      Content-language: en<br />
    <br />
      URI: foo.fr.de.html<br />
      Content-type: text/html;charset=iso-8859-2<br />
      Content-language: fr, de<br />
    </code></p></div>
        <p>たとえ MultiViews を使用するようになっていたとしても、
        ファイル名の拡張子よりタイプマップの方が優先権を持つということにも
        注意してください。
        variant の品質が違うときは、この画像のように (JPEG, GIF, ASCII
        アートがあります) メディアタイプの "qs"
        パラメータで指定されます。</p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.jpeg<br />
      Content-type: image/jpeg; qs=0.8<br />
    <br />
      URI: foo.gif<br />
      Content-type: image/gif; qs=0.5<br />
    <br />
      URI: foo.txt<br />
      Content-type: text/plain; qs=0.01<br />
    </code></p></div>
    
        <p>qs 値の範囲は 0.000 から 1.000 です。qs 値が
        0.000 の variant は決して
        選択されないことに注意してください。'qs' 値のない variant
        は qs 値 1.0 を 与えられます。qs
        パラメータはクライアントの能力に関係無く、他の variant と
        比較したときの variant
        の相対的な「品質」を示します。
        例えば、写真を表現しようとしているときは JPEG
        ファイルの方が普通は ASCII
        ファイルよりも高い品質になります。しかし、リソースが元々
        ASCII アートで表現されているときは、ASCII ファイルの
        方が JPEG ファイルよりも高い品質になります。このように、qs
        は 表現されるリソースの性質によって variant
        毎に特有の値を取ります。</p>
    
        <p>認識されるヘッダの一覧は
        <a href="mod/mod_negotiation.html#typemaps">mod_negotiation</a>
        ドキュメントにあります。</p>
    
    
    <h3><a name="multiviews" id="multiviews">Multiviews</a></h3>
    
        <p><code>MultiViews</code> はディレクトリ毎のオプションで、
        <code>httpd.conf</code>ファイルの
        <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, 
        <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, 
        <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
        セクション中や、(<code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>
        が適切な値に 設定されていると) <code>.htaccess</code>
        ファイルで <code class="directive"><a href="./mod/core.html#options">Options</a></code>
        ディレクティブによって設定することができます。
        <code>Options All</code> は
        <code>MultiViews</code>
        をセットしないことに注意してください。明示的に
        その名前を書く必要があります。</p>
    
        <p><code>MultiViews</code> の効果は以下のようになります:
        サーバが <code>/some/dir/foo</code>
        へのリクエストを受け取り、<code>/some/dir</code> で
        <code>MultiViews</code> が有効であって、
        <code>/some/dir/foo</code> が存在<em>しない</em>場合、
        サーバはディレクトリを読んで <code>foo.*</code>
        にあてはまる全てのファイルを探し、
        事実上それらのファイルをマップするタイプマップを作ります。
        そのとき、メディアタイプとコンテントエンコーディングは、そのファイル名を
        直接指定したときと同じものが割り当てられます。
        それからクライアントの要求に一番合うものを選びます。</p>
    
        <p>サーバがディレクトリの索引を作ろうとしている場合、
        <code>MultiViews</code>
        は <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>
        ディレクティブで指定されたファイルを探す過程にも
        適用されます。設定ファイルに</p>
    <div class="example"><p><code>DirectoryIndex index</code></p></div>
        <p>が書かれていて、<code>index.html</code> と
        <code>index.html3</code> が
        両方存在していると、サーバはその中からどちらかを適当に選びます。
        もしその両方が存在せずに <code>index.cgi</code>
        が存在していると、 サーバはそれを実行します。</p>
    
        <p>もしディレクトリを読んでいる際に、
        文字セット、コンテントタイプ、言語、エンコーディングを
        指定するための <code>mod_mime</code> 
        で認識できる拡張子を持たないファイルが見つかると、結果は
        <code class="directive"><a href="./mod/mod_mime.html#multiviewsmatch">MultiViewsMatch</a></code>
        ディレクティブの設定に依存します。このディレクティブは
        ハンドラ、フィルタ、他のファイル拡張子タイプのどれが
        MultiViews ネゴシエーションで使用できるかを決定します。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="methods" id="methods">ネゴシエーション方法</a></h2>
    
        <p>Apache はリソースの variant の一覧を、タイプマップファイルか
        ディレクトリ内のファイル名からかで取得した後、
        「最適な」 variant を決定するために二つの方法の
        どちらかを起動します。
        Apache のコンテントネゴシエーションの機能を使うために、
        どのようにしてこの調停が行われるか詳細を知る必要はありません。
        しかしながら、この文書の残りでは関心のある人のために、
        使用されている方法について説明しています。</p>
    
        <p>ネゴシエーション方法は二つあります。</p>
    
        <ol>
          <li>通常は <strong>Apache のアルゴリズムを用いた Server
          driven negotiation</strong> が使用されます。Apache
          のアルゴリズムは後に詳細に説明されています。
          このアルゴリズムが使用された場合、Apache
          はより良い結果になるように、特定の次元において品質の値を
          「変える」ことができます。Apache
          が品質の値を変える方法は後で詳細に説明されています。</li>
    
          <li>RFC 2295
          で定義されている機構を用いてブラウザが特に指定した場合、
          <strong>transparent content negotiation</strong>
          が使用されます。このネゴシエーション方法では、「最適な」
          variant の決定をブラウザが完全に制御することができます。
          ですから、結果はブラウザが使用しているアルゴリズムに依存します。
          Transparent negotiation の処理の過程で、ブラウザは RFC 2296
          で 定義されている 'remote variant selection algorithm'
          を実行するように頼むことができます。</li>
        </ol>
    
    <h3><a name="dimensions" id="dimensions">ネゴシエーションの次元</a></h3>
    
        <table>
          
          <tr valign="top">
            <th>次元</th>
    
            <th>説明</th>
          </tr>
    
          <tr valign="top">
            <td>メディアタイプ</td>
    
            <td>ブラウザは <code>Accept</code>
    	ヘッダフィールドで優先傾向を指定します。
    	アイテムそれぞれは、関連した品質数値を持つことができます。
    	variant の説明も品質数値を持つことができます
    	("qs" パラメータをご覧下さい)。</td>
          </tr>
    
          <tr valign="top">
            <td>言語</td>
    
    	<td>ブラウザは <code>Accept-Language</code>
    	ヘッダフィールドで優先傾向を指定します。
    	要素それぞれに品質数値を持たせることができます。
    	variants は 0 か 1 つかそれ以上の言語と
    	関連づけることができます。</td>
          </tr>
    
          <tr valign="top">
            <td>エンコーディング</td>
    
    	<td>ブラウザは <code>Accept-Encoding</code>
    	ヘッダフィールドで優先傾向を指定します。
    	要素それぞれに品質数値を持たせることができます。</td>
          </tr>
    
          <tr valign="top">
            <td>文字セット</td>
    
    	<td>ブラウザは <code>Accept-Charset</code>
    	ヘッダフィールドで優先傾向を指定します。
    	要素それぞれに品質数値を持たせることができます。
    	variant はメディアタイプのパラメータとして文字セットを
    	指定することもできます。</td>
          </tr>
        </table>
    
    
    <h3><a name="algorithm" id="algorithm">Apache ネゴシエーションアルゴリズム</a></h3>
    
        <p>ブラウザに返す「最適な」variant を (もしあれば) 選択するように
        Apache は次のアルゴリズムを使うことができます。
        このアルゴリズムを設定により変更することはできません。
        次のように動作します:</p>
    
        <ol>
          <li>まずはじめに、ネゴシエーションの次元それぞれについて適切な
          <em>Accept*</em> ヘッダフィールドを調べ、
          variant それぞれに品質を割り当てます。
          もしある次元の <em>Accept*</em> ヘッダでその variant
          が許容できないことが示されていれば、それを削除します。
          variant が一つも残っていなければ、ステップ 4 に行きます。</li>
    
          <li>
    	消去法で「最適な」 variant を選びます。
    	次のテストが順番に適用されます。
    	テストで選択されなかった variant は削除されていきます。
    	テスト後 variant が一つだけ残っていれば、それを最適なものとして
    	ステップ 3 に進みます。
    	複数 variant が残っていれば、次のテストに進みます。
    
            <ol>
    	  <li>variant のメディアタイプの品質数値と <code>Accept</code>
    	  ヘッダの品質数値との積を計算して、最高値の variant
    	  を選びます。</li>
    
    	  <li>言語品質数値が最高の variant を選びます。</li>
    
    	  <li>(もしあれば) <code>Accept-Language</code> ヘッダの言語順か、
    	  (もしあれば)
    	  <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code> 
    	  ディレクティブの言語順で最適な言語の variant を選びます。</li>
    
    	  <li>最高「レベル」のメディアパラメータ
    	  (text/html メディアタイプのバージョンを与えるために使われます)
    	  を持つ variant を選びます。</li>
    
    	  <li><code>Accept-Charset</code> ヘッダ行で与えられている最高の文字セット
    	  メディアパラメータを持つ variant を選びます。
    	  明示的に除外されていない限り、ISO-8859-1
    	  が許容されるようになっています。
    	  <code>text/*</code> メディアタイプであるけれども
    	  特定の文字セットに明示的に関連づけられているわけではない
    	  variant は ISO-8859-1 であると仮定されます。</li>
    
    	  <li>ISO-8859-1 <em>ではない</em>文字セットメディアパラメータと
    	  関連づけられている variant を選びます。
    	  そのような variant がない場合は、代わりに全ての
    	  variant を選びます。</li>
    
    	  <li>最適なエンコーディングの variant を選びます。
    	  もし user-agent が許容するエンコーディングがあれば、
    	  その variant のみを選びます。
    	  そうではなく、もしエンコードされたものとそうでない
    	  variant が混ざって存在していたらエンコードされていない
    	  variant のみを選びます。
    	  variant が全部エンコードされているか
    	  variant が全部エンコードされていないという場合は、
    	  全ての variant を選びます。</li>
    
    	  <li>内容の最も短い variant を選びます。</li>
    
    	  <li>残っている variant の最初のものを選びます。
    	  タイプマップファイルの最初にリストされているか、
    	  variant がディレクトリから最初に読み込まれる時に
    	  ASCII順でソートしてファイル名が先頭になったか、のどちらかです。</li>
            </ol>
          </li>
    
          <li>アルゴリズムを使って一つの「最適な」variant を選びましたので、
          それを応答として返します。ネゴシエーションの次元を指定するために
          HTTP レスポンスヘッダ <code>Vary</code> が設定されます
          (リソースのキャッシュをする時に、
          ブラウザやキャッシュはこの情報を使うことができます)。
          以上で終わり。</li>
    
          <li>ここに来たということは、variant が一つも選択されなかった
          (ブラウザが許容するものがなかったため) ということです。
          406 ステータス ("No Acceptable representation" を意味する)
          が、利用可能な variant のリストのついた HTML 
          ドキュメントとともに返されます。
          相違の次元を示す HTTP <code>Vary</code> ヘッダも設定されます。</li>
        </ol>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="better" id="better">品質の値を変える</a></h2>
    
        <p>上記の Apache ネゴシエーションアルゴリズムの厳格な解釈で
        得られるであろう値から、Apache は品質数値を時々変えます。
        これは、このアルゴリズムで完全ではない、あるいは正確でない情報を送る
        ブラウザ向けによりよい結果を得るために行われます。
        かなりポピュラーなブラウザで、もしないと間違った variant
        を選択する結果になってしまうような <code>Accept</code>
        ヘッダ情報を送るものもあります。
        ブラウザが完全で正しい情報を送っていれば、
        この数値変化は適用されません。</p>
    
    <h3><a name="wildcards" id="wildcards">メディアタイプとワイルドカード</a></h3>
    
        <p><code>Accept:</code> リクエストヘッダはメディアタイプの優先傾向を指定します。
        これはまた、"image/*" や "*/*"
        といった「ワイルドカード」メディアタイプを含むことができます。
        ここで * は任意の文字列にマッチします。
        ですから、次の:</p>
    
    <div class="example"><p><code>Accept: image/*, */*</code></p></div>
    
        <p>を含むリクエストは、"image/" ではじまるタイプ全てが許容できる、
        そして他のどんなタイプも許容できる
        (この場合はじめの "image/*" は冗長になります)
        ことを示します。
        扱うことのできる明示的なタイプに加えて、機械的に
        ワイルドカードを送るブラウザもあります。例えば:</p>
    
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*
    </code></p></div>
        <p>こうすることの狙いは、明示的にリストしているタイプが優先されるけれども、
        異なる表現が利用可能であればそれでも良い、ということです。
        しかしながら、上の基本的なアルゴリズムでは、
        */* ワイルドカードは他の全てのタイプと全く同等なので優先されません。
        ブラウザは */* にもっと低い品質 (優先) 
        値を付けてリクエストを送るべきなのです。例えば:</p>
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
    </code></p></div>
        <p>明示的なタイプには品質数値が付けられていませんので、
        デフォルトの 1.0 (最高値) の優先になります。
        ワイルドカード */* は低い優先度 0.01 を与えられているので、
        明示的にリストされているタイプに合致する variant がない場合にのみ、
        他のタイプが返されます。</p>
    
        <p>もし <code>Accept:</code> ヘッダが q 値を全く含んで<em>いなければ</em>、
        望みの挙動をするために、
        Apache は "*/*" があれば 0.01 の q 値を設定します。
        また、"type/*" の形のワイルドカードには 0.02 の q 値を設定します
        (ですからこれらは "*/*" のマッチよりも優先されます)。
        もし <code>Accept:</code> ヘッダ中のメディアタイプのどれかが q
        値を含んでいれば、これらの特殊な値は適応<em>されず</em>、
        正しい情報を送るブラウザからのリクエストは期待通りに
        動作するようになります。</p>
    
    
    <h3><a name="exceptions" id="exceptions">言語ネゴシエーションの例外処理</a></h3>
    
        <p>Apache 2.0 では新たに、言語ネゴシエーションが適合するものを
        見つけるのに失敗した時に、優雅にフォールバックできるような
        ネゴシエーションアルゴリズムが幾つか追加されました。</p>
    
        <p>サーバのページをクライアントがリクエストしたけれども、
        ブラウザの送ってきた <code>Accept-Language</code> に合致するページが一つも
        見つからなかった場合に、サーバは "No Acceptable Variant"
        か "Multiple Choices" レスポンスをクライアントに返します。
        これらのエラーメッセージを返さないように、
        このような場合には Apache が <code>Accept-Language</code> を無視して、
        クライアントのリクエストに明示的には合致しないドキュメントを
        提供するように設定できます。
        <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>
        ディレクティブは、これらのエラーの一つか両方をオーバーライドするために
        使用できて、
        <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>
        ディレクティブの内容を使ってサーバの判断を代行するようにできます。</p>
    
        <p>サーバは他に適合するものが見つからなければ、
        言語サブセットで適合するものを試そうともします。
        例えばクライアントが英国英語である <code>en-GB</code> 言語で
        ドキュメントをリクエストした場合、サーバは HTTP/1.1
        規格では、単に <code>en</code> とマークされているドキュメントを
        マッチするものとすることは通常は許されていません。
        (英国英語は理解できるけど一般的な英語は理解できないという読み手は
        考えられないので、Accept-Language ヘッダで <code>en-GB</code> 
        を含んで <code>en</code> を含まないのはほぼ確実に設定の間違いである、
        ということに注意してください。
        ですが不幸なことに、多くのクライアントではデフォルトで
        このような設定になっています。)
        しかしながら、他の言語にはマッチせず、"No Acceptable Variants"
        エラーを返したり、
        <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>
        にフォールバックしようとしているときは、
        サブセット指定を無視して、<code>en-GB</code> を <code>en</code>
        にマッチします。
        Apache はクライアントの許容言語リストに暗黙に
        非常に低い品質値の親言語を加えることになります。
        しかし、クライアントが "en-GB; q=0.9, fr; q=0.8" とリクエストして、
        サーバが "en" と "fr" と設計されたドキュメントを持っている場合は、
        "fr" ドキュメントが返されることに注意してください。
        このような処理は、HTTP 1.1 規格との整合性を維持して、
        適切に設定されたクライアントともきちんと動作するために
        必要です。</p>
    
        <p>より高度なテクニック (Cookie や特殊な URL パス等)
        においてもユーザの言語選択をサポートするため、
        Apache 2.0.47 からは、<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>
        が<a href="env.html">環境変数</a> <code>prefer-language</code>
        を認識するようになりました。
        この変数が存在して、適切な言語タグが代入されているのであれば、
        <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> は合致する variant
        を選択しようとします。合致するものが無ければ、
        通常のネゴシエーション手順が適用されます。</p>
    
        <div class="example"><h3>Example</h3><p><code>
          SetEnvIf Cookie "language=(.+)" prefer-language=$1<br />
          Header append Vary cookie 
        </code></p></div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extensions" id="extensions">Transparent Content Negotiation
    の拡張</a></h2> 
    
    <p>Apache は transparent content negotiation プロトコル
    (RFC 2295) を次のように拡張しています。
    特定のコンテントエンコーディングのみが利用可能である variant 
    に印を付けるために、新たに <code>{encoding ..}</code> 
    要素を variant リスト中に使っています。
    リスト中のエンコードされた variant を認識し、
    <code>Accept-Encoding</code> リクエストヘッダに従って許容される
    エンコードをもった variant は、どれでも候補 variant
    として使用するように、
    RVSA/1.0 アルゴリズム (RFC 2296) の実装が拡張されました。
    RVSA/1.0 の実装では、最適な variant が見つかるまで、
    計算した品質数値は小数点以下 5 桁まで丸めません。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="naming" id="naming">リンクと名前の変換に関する注意点</a></h2>
    
        <p>言語ネゴシエーションを使っている場合は、
        ファイルが一つ以上の拡張子を持てて、
        拡張子の順番は通常は考慮されない
        (詳細は <a href="mod/mod_mime.html#multipleext">mod_mime</a> 
        を参照) ので、
        幾つかの異なる名前の変換を選べることになります。</p>
    
        <p>典型的なファイルでは、MIME タイプ拡張子 (<em>例えば</em>
        <code>html</code>) を持っていて、エンコーディング拡張子
        (<em>例えば</em> <code>gz</code>) を持っているかもしれなくて、
        このファイルに異なる言語 variant を用意していれば、
        もちろん言語拡張子 (<em>例えば</em> <code>en</code>)
        を持っているでしょう。</p>
    
        <p>例:</p>
    
        <ul>
          <li>foo.en.html</li>
    
          <li>foo.html.en</li>
    
          <li>foo.en.html.gz</li>
        </ul>
    
        <p>ファイル名と、それに対して使えるリンクと使えないリンクの例です:</p>
    
        <table class="bordered">
          
          <tr>
            <th>ファイル名</th>
    
            <th>使えるリンク</th>
    
            <th>使えないリンク</th>
          </tr>
    
          <tr>
            <td><em>foo.html.en</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>-</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html</em></td>
    
            <td>foo</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.en.gz</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>foo.gz<br />
             foo.html.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html.gz</em></td>
    
            <td>foo</td>
    
            <td>foo.html<br />
             foo.html.gz<br />
             foo.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.gz.html.en</em></td>
    
            <td>foo<br />
             foo.gz<br />
             foo.gz.html</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.gz.en</em></td>
    
            <td>foo<br />
             foo.html<br />
             foo.html.gz</td>
    
            <td>foo.gz</td>
          </tr>
        </table>
    
        <p>上の表を見て、拡張子なしのリンク (<em>例えば</em> <code>foo</code>) 
        がいつでも使えることに気が付くでしょう。
        この利点は、ドキュメントとして応答するファイルの
        実際のファイルタイプを隠蔽して、リンクの参照を変更することなく
        後からファイルを変更できる、
        <em>例えば</em> <code>html</code> から <code>shtml</code>
        に、あるいは <code>cgi</code> に変更できる点です。</p>
    
        <p>リンクに MIME タイプを使い続けたい (<em>例えば</em>
        <code>foo.html</code>)時は、言語拡張子は
        (エンコーディング拡張子もあればそれも含めて)
        MIME タイプ拡張子の右側になければなりません
        (<em>例えば</em> <code>foo.html.en</code>)。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="caching" id="caching">キャッシュに関する注意事項</a></h2>
    
        <p>キャッシュが一つの表現を保存しているときは、
        リクエスト URL と関連づけられています。
        次にその URL がリクエストされた時に、キャッシュは
        保存されている表現を使用できます。しかし、
        リソースがサーバでネゴシエーション可能であれば、
        最初のリクエストでキャッシュされて続くキャッシュヒットでは
        間違った応答を返してしまうということになりかねません。
        これを防ぐために、Apache はコンテントネゴシエーションの
        後に返された応答全てに、HTTP/1.0 クライアントでは
        キャッシュ不可能の印をつけます。
        また、ネゴシエーションされた応答のキャッシュを可能にする
        HTTP/1.1 プロトコルの機能も Apache はサポートします。</p>
    
        <p>HTTP/1.0 準拠のクライアントからのリクエストに対しては、
        (ブラウザであろうとキャッシュであろうと)
        ネゴシエーションを受けた応答のキャッシュを許すために、
        <code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code>
        ディレクティブを使用できます。
        このディレクティブは、サーバ設定ファイルやバーチャルホストに書くことができ、
        引数をとりません。
        HTTP/1.1 クライアントからのリクエストには効力を持ちません。</p>
    
        <p>HTTP/1.1 クライアントに対しては、レスポンスのネゴシエーション次元
        を示すために <code>Vary</code> HTTP レスポンスヘッダを送ります。
        キャッシュは、これを使って後続のリクエストに対してローカルコピーで応答できるか
        どうかを決定できます。
        ネゴシエーション次元とは関係なしにローカルコピーの使用を優先するようにするには、
        <code>force-no-vary</code> <a href="env.html#special">環境変数</a>を
        設定します。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/content-negotiation.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������httpd-2.4.64/docs/manual/custom-error.html.ja.utf8��������������������������������������������������0000664�0001751�0001751�00000032332�14743132254�021644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>カスタムエラーレスポンス - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>カスタムエラーレスポンス</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>ウェブマスターが何らかのエラーや問題に対する
        Apache の反応を設定できるようにする追加機能を提供します。</p>
    
        <p>サーバがエラーや問題を発見した場合の反応を、
        カスタマイズして定義することができます。</p>
    
        <p>スクリプトの実行が失敗して "500 Server Error"
        を発生させたとします。この場合の反応を、より好ましいテキストや、別の
        URL (内部及び外部) へのリダイレクションに置き換えることができます。
        </p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#behavior">動作</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configuration">設定</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#custom">カスタムエラーレスポンスとリダイレクト</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behavior" id="behavior">動作</a></h2>
        
    
        <h3>古い動作</h3>
          
    
          <p>NCSA httpd 1.3 は、古くて退屈なエラー/問題メッセージを
          返していました。それはしばしばユーザには無意味であり、
          またそれを発生させた原因を記録する方法も提供していませんでした。</p>
        
    
        <h3>新しい動作</h3>
          
    
            <ol>
              <li>NCSA のハードコードされたメッセージの代わりに
              他のテキストを表示</li>
    
              <li>ローカルの URL にリダイレクト</li>
    
              <li>外部の URL にリダイレクト</li>
            </ol>
    
            <p>するようにサーバを設定できます。</p>
    
            <p>別の URL にリダイレクトすることは役に立ちますが、
            それは説明をしたり、より明確に誤り/問題を記録したりするために
            何か情報を伝えられるときに限ります。</p>
    
            <p>これを実現するために、 Apache は新しく CGI のような環境変数を
            定義します:</p>
    
            <div class="example"><p><code>
              REDIRECT_HTTP_ACCEPT=*/*, image/gif,
              image/x-xbitmap, image/jpeg<br />
               REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX
              A.09.05 9000/712)<br />
               REDIRECT_PATH=.:/bin:/usr/local/bin:/etc<br />
               REDIRECT_QUERY_STRING=<br />
               REDIRECT_REMOTE_ADDR=121.345.78.123<br />
               REDIRECT_REMOTE_HOST=ooh.ahhh.com<br />
               REDIRECT_SERVER_NAME=crash.bang.edu<br />
               REDIRECT_SERVER_PORT=80<br />
               REDIRECT_SERVER_SOFTWARE=Apache/0.8.15<br />
               REDIRECT_URL=/cgi-bin/buggy.pl
            </code></p></div>
    
            <p>頭に付く <code>REDIRECT_</code> に注目してください。</p>
    
            <p>少なくとも <code>REDIRECT_URL</code> と
            <code>REDIRECT_QUERY_STRING</code> は新しい URL (CGI スクリプトか
            CGI インクルードであると仮定されます) に渡されます。
            他の変数は、エラーや問題が起きる前に存在した場合にだけ存在します。
            もしあなたの設定した <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> が <em>外部</em>リダイレクト
            (<em>すなわち</em>、<code>http:</code> 
            のような体系名から始まるすべてのもの。たとえ同じホストを指していても)
            ならば、これらは<strong>まったく</strong>設定されません。</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">設定</a></h2>
        
    
        <p><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> が適切に設定されていれば、
        .htaccess ファイルで <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code>
        を使用することができます。</p>
    
            <p>ここに、いくつかの例を挙げます。</p>
    
        <div class="example"><p><code>
          ErrorDocument 500 /cgi-bin/crash-recover <br />
          ErrorDocument 500 "Sorry, our script crashed. Oh dear" <br />
          ErrorDocument 500 http://xxx/ <br />
          ErrorDocument 404 /Lame_excuses/not_found.html <br />
          ErrorDocument 401 /Subscription/how_to_subscribe.html
        </code></p></div>
    
        <p>構文</p>
    
        <div class="example"><p><code>
          ErrorDocument &lt;3-digit-code&gt; &lt;action&gt;
        </code></p></div>
    
            <p>action (動作) は、下記のいずれかです</p>
    
            <ol>
              <li>表示するテキスト。テキストは引用符 (") で囲んで指定します。</li>
    
              <li>リダイレクト先の外部 URL </li>
    
              <li>リダイレクト先のローカル URL </li>
            </ol>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="custom" id="custom">カスタムエラーレスポンスとリダイレクト</a></h2>
        
    
          <p>スクリプト/SSI に追加の環境変数が利用可能になるように、
          リダイレクトされた URL に対する Apache の動作が変更されました。</p>
    
        <h3>古い動作</h3>
          
    
          <p>リダイレクトされたスクリプトは標準の CGI
          環境変数を利用可能でした。しかし、どこからリダイレクト
          されたかの情報は提供されていませんでした。</p>
        
    
        <h3>新しい動作</h3>
          
    
          <p>リダイレクトされた先のスクリプトが使用可能なように、
          新しいたくさんの環境変数が初期化されます。新しい変数は、それぞれ
          <code>REDIRECT_</code> で始まります。
          <code>REDIRECT_</code> で始まる環境変数はリダイレクトされる前に存在していた
          CGI 環境変数の頭に <code>REDIRECT_</code> を付けて作成されます。
          <em>すなわち</em>、<code>HTTP_USER_AGENT</code> は 
          <code>REDIRECT_HTTP_USER_AGENT</code> になります。
          これらの新しい変数に加えて、Apache は、
          スクリプトがリダイレクト元のトレースを助けるために
          <code>REDIRECT_URL</code> と <code>REDIRECT_STATUS</code>
          を定義します。アクセスログには元の URL とリダイレクトされた URL
          の両方が記録されます。</p>
    
        <p>ErrorDocument が CGI スクリプトへのローカルリダイレクトを
        指定している場合は、それを起動することになったエラーの状態を
        クライアントまで確実に伝えるために <code>"Status:" </code>
        ヘッダを含むべきです。例えば、ErrorDocument 用の Perl
        スクリプトは以下のようなものを含むかもしれません。
        </p>
    
          <div class="example"><p><code>
            ... <br />
            print  "Content-type: text/html\n"; <br />
            printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"}; <br />
            ...
          </code></p></div>
    
        <p>スクリプトが <code>404 Not Found</code> のような
        特定のエラーコンディションを扱うためだけに使われる場合は、
        代わりに特定のコードとエラーテキストを使用することができます。</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/custom-error.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/license.html���������������������������������������������������������������0000664�0001751�0001751�00000000166�13710016232�017335� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: license.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/bind.html.tr.utf8����������������������������������������������������������0000664�0001751�0001751�00000040334�14743132254�020153� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Adresleri ve Portları Dinleme - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Adresleri ve Portları Dinleme</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Apache HTTPD sunucusunun belli adresleri ve portları dinlemek üzere
        yapılandırılması.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Genel Bakış</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#reload">Dinleme yapılandırmasının yeniden başlatırken değiştirilmesi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ipv6">IPv6 Adreslerin Durumu</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#protocol">Protokolü Listen ile Belirtme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Sanal Konaklarla Nasıl Çalışır?</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="vhosts/">Sanal Konaklar</a></li><li><a href="dns-caveats.html">DNS Konuları</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Genel Bakış</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mpm_common.html">mpm_common</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code></li></ul></td></tr></table>
    
    
        <p>httpd başlatıldığında yerel makinedeki bazı adres ve portları kendine
          bağlar ve gelecek istekleri bekler. Öntanımlı olarak makine üzerindeki
          tüm adresleri dinler. Bununla birlikte, belli portları veya sadece
          seçilmiş bazı adresleri ya da her ikisini de dinlemesi için bunun
          belirtilmesi gerekebilir. Bu çoğunlukla, httpd’nin farklı IP
          adreslerine, konak isimlerine ve portlarına nasıl yanıt vereceğinin
          belirlendiği <a href="vhosts/">sanal konak</a> özelliği ile birlikte
          yürür.</p>
    
        <p><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesi sunucuya
          gelen istekleri sadece belli port(lar)dan veya belli adres ve port
          birleşimlerinden kabul etmesini söyler. <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesinde sadece port
          numarası belirtilmişse sunucu tüm arabirimlerin belirtilen portunu
          dinleyecektir. Portla birlikte bir IP adresi de belirtilmişse sunucu
          belirtilen portu ve arabirimi dinleyecektir. Çok sayıda adres ve portu
          dinlemek için çok sayıda <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesi kullanılabilir. Sunucu
          böyle bir durumda belirtilen bütün adres ve portlardan gelen isteklere
          yanıt verecektir.</p>
    
        <p>Örneğin, sunucunun hem 80 portundan hem de 8000 portundan gelen
          bağlantıları kabul etmesini sağlamak için,</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 80
    Listen 8000</pre>
    </div>
    
        <p>yapılandırmasını kullanabilirsiniz. Sunucunun 80 portuna gelen
          bağlantıları bir arabirimden 8000 portuna gelenleri ise başka bir
          arabirimden kabul etmesini sağlamak için ise,</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 192.0.2.1:80
    Listen 192.0.2.5:8000</pre>
    </div>
    
        <p>yapılandırmasını kullanabilirsiniz. IPv6 adresleri aşağıdaki örnekteki
          gibi köşeli ayraçlar içine alınarak belirtilmelidir:</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen [2001:db8::a00:20ff:fea7:ccea]:80</pre>
    </div>
    
        <div class="warning">
          <p>Bir <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesinin
          aynısının tekrarı sunucunun başlatılmasını engelleyen ölümcül bir hatayla
          sonuçlanacaktır.</p>
    
          <div class="example"><p><code>
          (48)Address already in use: make_sock: could not bind to address [::]:80
          </code></p></div>
    
          <p>Sorun giderme ile ilgili ipuçları için
          <a href="http://wiki.apache.org/httpd/CouldNotBindToAddress">wiki
          belgesine</a> bakınız.</p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="reload" id="reload">Dinleme yapılandırmasının yeniden başlatırken değiştirilmesi</a></h2>
        
    
        <p>httpd yeniden başlatılırken, 
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergelerindeki 
        değişiklikler için özel değerlendirmeler yapılmalıdır. Yeniden başlatma 
        sırasında, httpd, yeni bağlanma çabalarında "Connection refused" (bağlantı 
        reddedildi) hatasından kaçınmak için [özgün yapılandırmadaki gibi] portları 
        bağlı tutar. Bu bakımdan, <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        yönergelerinden yapılan değişiklikler yenden başlatılrken yapılandırmanın 
        başarısız olmasına ve sunucunun sonlanmasına sebep olur.</p>
    
        <p>Örneğin:</p>
        
        <div class="example"><pre class="prettyprint lang-config">Listen 127.0.0.1:80</pre>
    </div>
    
        <p>yapılandırmasını aşağıdakiyle değiştirmek yenden başlatma sırasında 
        sucunun hta verip sonlanmasına sebep olur. Çünkü, tüm adreslerden 80 porta 
        bağlanmak sadece 127.0.0.1 adresine bağlanmakla çelişir.</p>
        
        <div class="example"><pre class="prettyprint lang-config">Listen 80</pre>
    </div>
    
        <p>Böyle değişikliklerin etkili olabilmesi için sunucu önce durdurulmalı 
        sonra başlatımalıdır (restart yerine stop ve start kullanılmalıdır).</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipv6" id="ipv6">IPv6 Adreslerin Durumu</a></h2>
        
    
        <p>IPv6’yı gerçekleyen platformların sayısı giderek artmaktadır. Bu
          platformların çoğunda <a class="glossarylink" href="./glossary.html#apr" title="sözlüğe bakınız">APR</a>, httpd’nin IPv6
          soketleri ayırmasını mümkün kılarak IPv6’yı desteklemekte ve IPv6
          üzerinden gönderilmiş istekleri elde etmektedir.</p>
    
        <p>httpd yöneticilerinin kafasını karıştırıran tek şey IPv6 soketlerin
          hem IPv4 hem de IPv6 bağlantılarını kabul edip etmeyeceğidir. IPv4
          bağlantılarını kabul eden IPv6 soketleri IPv4 eşlemli IPv6 adresleri
          kullanırlar. Bu çoğu sistemde öntanımlı olarak böyleyken, FreeBSD,
          NetBSD ve OpenBSD’de sistem geneline uygulanan kurallar gereğince
          öntanımlı olarak buna izin verilmez; bu sistemlerde özel bir
          <code class="program"><a href="./programs/configure.html">configure</a></code> parametresi ile <code>httpd</code>’nin
          davranışı değiştirilebilir.</p>
    
        <p>Diğer taraftan, Linux ve Tru64 gibi bazı platformlarda hem IPv4 hem de
          IPv6 adresleri kabul etmenin <strong>tek yolu</strong> eşlemli adresler
          kullanmaktır. <code>httpd</code>’nin IPv4 ve IPv6 adresleri, IPv4 eşlemli
          IPv6 adreslerin kullanımını gerektiren en az sayıda soketle kabul etmesini
          istiyorsanız, <code class="program"><a href="./programs/configure.html">configure</a></code> betiğine
          <code>--enable-v4-mapped</code> seçeneğini belirtiniz.</p>
    
        <p><code>--enable-v4-mapped</code> seçeneği, FreeBSD, NetBSD ve OpenBSD
          hariç tüm platformlarda öntanımlıdır. Muhtemelen siz de
          <code>httpd</code>’nin böyle derlenmesini isterdiniz.</p>
    
        <p>Platformunuzun ve APR’nin neyi desteklediğine bakmaksızın
          <code>httpd</code>’nin sadece IPv4 adresleri kabul etmesini istiyorsanız,
          tüm <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergelerinde
          örnekteki gibi IPv4 adresleri belirtiniz:</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 0.0.0.0:80
    Listen 192.0.2.1:80</pre>
    </div>
    
        <p>Platformunuz IPv4 ve IPv6 adresleri ayrı soketlerden kabul ediyorsa ve
          <code>httpd</code>’nin de buna uygun davranmasını (yani IPv4 eşlemli IPv6
          adreslerin iptalini)  istiyorsanız <code class="program"><a href="./programs/configure.html">configure</a></code>
          betiğine <code>--disable-v4-mapped</code> seçeneğini belirtiniz. Bu
          seçenek FreeBSD, NetBSD ve OpenBSD’de öntanımlıdır.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="protocol" id="protocol">Protokolü Listen ile Belirtme</a></h2>
        
        <p><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesinin isteğe
          bağlı ikinci değiştirgesi <var>protokol</var> çoğu yapılandırmada gerekli
          olmaz. Belirtilmediği takdirde, <code>https</code> için 443,
          <code>http</code> için ise diğer bütün portlar öntanımlıdır. Protokol,
          isteğin hangi modül tarafından işleneceğini ve <code class="directive"><a href="./mod/core.html#acceptfilter">AcceptFilter</a></code> yönergesi ile uygulanacak
          protokole özgü en iyilemeleri belirlemekte kullanılır.</p>
    
        <p>Sadece standartdışı bir port kullanmak isterseniz protokolü belirtmeniz
          gerekir. Örneğin, bir<code>https</code> sitesini port 8443 üzerinde
          çalıştırmak isterseniz:</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 192.170.2.1:8443 https</pre>
    </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Sanal Konaklarla Nasıl Çalışır?</a></h2>
        
    
        <p><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesi sanal
          konaklar için gerçeklenmemiştir; sadece ana sunucuya hangi adresleri ve
          portları dinleyeceğini söyler. Hiç <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> yönergesi kullanılmamışsa sunucu
          kabul edilen tüm isteklere aynı şekilde davranacaktır. Eğer bir veya
          daha fazla adres ve port için farklı bir davranış belirtmek
          istiyorsanız <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> kullanabilirsiniz. Bir sanal
          konağı gerçeklemek için önce sunucunun sanal konak için kullanacağı
          adres ve portu dinleyeceğini belirtmek gerekir. Bundan sonra bu sanal
          konağın davranışını ayarlamak üzere belirtilen adres ve port için bir
          <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümü
          oluşturulmalıdır. Yalnız dikkat edin, eğer <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> için belirtilen adres ve port
          sunucu tarafından dinlenmiyorsa ona erişemezsiniz.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/bind.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dso.html�������������������������������������������������������������������0000664�0001751�0001751�00000000701�13710016232�016473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: dso.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: dso.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: dso.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: dso.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: dso.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������httpd-2.4.64/docs/manual/configuring.html.tr.utf8���������������������������������������������������0000664�0001751�0001751�00000045103�14743132254�021550� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Yapılandırma Dosyaları - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Yapılandırma Dosyaları</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    <p>Bu belgede Apache HTTP Sunucusunu yapılandırmakta kullanılan dosyalar
    açıklanmıştır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#main">Ana Yapılandırma Dosyaları</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#syntax">Yapılandırma Dosyalarının Sözdizimi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Modüller</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#scope">Yönergelerin Etki Alanı</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#htaccess">.htaccess Dosyaları</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">Ana Yapılandırma Dosyaları</a></h2>
        
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#include">Include</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code></li></ul></td></tr></table>
    
        <p>Apache HTTP Sunucusu düz metin yapılandırma dosyalarına <a href="mod/directives.html">yönergeler</a> yerleştirilerek yapılandırılır.
        Ana yapılandırma dosyasının ismi normalde <code>httpd.conf</code>’tur.
        Bu dosyanın yeri derleme sırasında belirlenir, ancak çalıştırma
        sırasında <code>-f</code> komut satırı seçeneği ile başka bir yer
        belirtilebilir. Ayrıca, <code class="directive"><a href="./mod/core.html#include">Include</a></code>
        yönergesi kullanılarak başka yapılandırma dosyaları da eklenebilir
        ve bu dosyaların isimleri belirtilirken dosya ismi şablonları
        kullanılabilir. Bu dosyaların içine de ana yapılandırma dosyasında
        olduğu gibi her türlü yönerge yerleştirilebilir. Ana yapılandırma
        dosyalarındaki değişiklikler httpd tarafından sadece başlatma veya
        yeniden başlatma sırasında etkin kılınır.</p>
    
        <p>Sunucu ayrıca MIME belge türlerini içeren bir dosya daha okur;
        dosya ismi öntanımlı olarak <code>mime.types</code> olup <code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code> yönergesi ile başka bir dosya
        belirtilebilir.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="syntax" id="syntax">Yapılandırma Dosyalarının Sözdizimi</a></h2>
        
    
        <p>httpd yapılandırma dosyalarının her satırında sadece bir yönerge
        bulunur ve bir yönergenin birden fazla satıra yayılması daha iyi
        olacaksa satır katlanabilir; devamı bir alt satırda olan her satırın
        son karakteri “\” (tersbölü) olmalı, satırsonu karakteri ile bu tersbölü
        karakteri arasında başka karakter bulunmamalıdır.</p>
    
        <p>Yönergelerdeki değiştirgeler boşluklarla ayrılır. Eğer bir değiştirge
        kendi içinde boşluklar içeriyorsa tırnak içine alınır.</p>
    
        <p>Yapılandırma dosyalarındaki yönergelerin isimleri harf büyüklüğüne
        duyarlı olduğu halde argümanları genellikle harf büyüklüğüne duyarlı
        değildir. Diyez (“#”) karakteri ile başlayan satırlar açıklama olarak
        ele alınır ve yok sayılırlar. Yapılandırma yönergesi içeren satırlara
        açıklama yerleştirilemez. Yönerge isminden önce yer alan boşluklar
        yoksayılır; bu özellik, okunabilirliği sağlamak için yönergelerin
        girintilenebilmesi olanağını verir. Ayrıca, boş satırlar da
        yoksayılır.</p>
    
    
        <p><code class="directive"><a href="./mod/core.html#define">Define</a></code> ile veya kabuğun ortam
        değişkenleri ile tanımlanmış değişkenlerin değerleri, yapılandırma
        dosyasının satırlarında <code>${VAR}</code> sözdizimi ile kullanılabilir.
        "VAR" geçerli bir değişkenin adı olduğu takdirde, bu değişkenin değeri
        yapılandırma dosyasının bu noktasında yerine konacak ve orada zaten
        değişken yerine değeri varmış gibi işlem kaldığı yerden devam edecektir.
        <code class="directive"><a href="./mod/core.html#define">Define</a></code> ile tanımlanmış değişkenler
        kabuğun ortam değişkenlerinden önceliklidir. "VAR" diye bir değişken yoksa
        <code>${VAR}</code> içindeki karakterler değişmeden kalır ve günlüğe bir
        uyarı çıktılanır. <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
        sözdizimi ile olası bir karışıklığı önlemek için, değişken isimleri iki
        nokta imini (":") içeremez.</p>
    
        <p>Kabuğun ortam değişkenlerinin, sadece, sunucu başlatılmadan önce
        tanımlanmış değerleri kullanılabilir.  Yapılandırma dosyasının kendisinde
        tanımlanmış ortam değişkenleri (örneğin,
        <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> ile), yapılandırma
        dosyasındaki işlemlerde çok daha sonra yer alır.</p>
    
        <p>Yapılandırma dosyasındaki bir satırın uzunluğu, değişken ikamesi
        yapıldıkta, devam satırları eklenditen sonra en fazla 16MiB olabilir. <a href="configuring.html#htaccess">.htaccess dosyalarında</a> azami uzunluk
        8190 karakterdir.</p>
    
        <p>Sunucuyu başlatmadan önce <code>apachectl configtest</code> ile veya
        <code>-t</code> komut satırı seçeneği ile yapılandırma dosyalarınızı
        sözdizimi hatalarına karşı sınayabilirsiniz.</p>
    
        <p>Eşleşmeyen <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>
        ve <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> bölümleri
        kaldırılmış, tüm açıklamalar, çözümlenmiş ortam değişkenleri ve içerilmiş
        tüm dosyalar dahil yapılandırmanın bir dökümünü almak için
        <code class="module"><a href="./mod/mod_info.html">mod_info</a></code>'nun <code>-DDUMP_CONFIG</code> seçeneğini
        kullanabilirsiniz. Ancak, çıktı yinelenen yönergeler için katıştırılan veya
        geçersiz kılınanları yansıtmayacaktır.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="modules" id="modules">Modüller</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>httpd modüler yapıda bir sunucudur. Bu, çekirdek sunucunun sadece en
        temel işlevselliği içermesi demektir. Ek özellikler, httpd’ye <a href="mod/">modüller</a> halinde yüklenebilir. Öntanımlı olarak, derleme
        sırasında sunucunun <a href="mod/module-dict.html#Status">temel</a> bir
        modül kümesi içermesi sağlanır. Eğer sunucu  <a href="dso.html">devingen
        yüklenen</a> modülleri kullanmak üzere yapılandırılarak derlenirse modüller
        ayrı olarak derlenip gerektiği zaman <code class="directive"><a href="./mod/mod_so.html#loadmodule">
        LoadModule</a></code> yönergesi kullanılarak yüklenebilir. Aksi takdirde,
        ek modülleri yükleyebilmek veya kaldırabilmek için httpd’nin yeniden
        derlenmesi gerekir. Yapılandırma yönergeleri belli bir modülün varlığına
        dayalı olarak bir <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>
        bloku içine alınmak suretiyle sunucuya koşullu olarak eklenebilir. Ancak,
        <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> yönergeleri
        gerekli değildir, önemli bir modülün yokluğu gibi durumlarda
        maskelenebilir.</p>
    
        <p>Sunucunun içinde derlenmiş modüllerin listesini görmek için
        <code>-l</code> komut satırı seçeneğini kullanabilirsiniz. Ayrıca,
        <code>-M</code> komut satırı seçeneği ile hangi modüllerin devingen olarak
        yüklendiğini görebilirsiniz.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="scope" id="scope">Yönergelerin Etki Alanı</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>Ana yapılandırma dosyasına yerleştirilen yönergeler sunucunun tamamına
        uygulanır. Yapılandırmanızı sunucunun belli bir parçası için değiştirmek
        isterseniz yönergelerinizi <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> ve <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> bölümleri içine yerleştirerek etki
        alanlarını değiştirebilirsiniz. Bu bölümler yönergelerin etkilediği
        alanları dosya sistemininin belli yerleri veya belli URL’lerle sınırlar.
        Yerine göre daha hassas ayarlamalar yapmak için bu bölgeler iç içe de
        kullanılabilir.</p>
    
        <p>httpd, çok sayıda farklı siteyi aynı anda sunabilecek yetenektedir.
        Buna <a href="vhosts/">Sanal Konaklık</a> adı verilir. Yönergelerin etki
        alanları ayrıca <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        bölümleri içine konarak da değiştirilebilir. Böylece belli bir siteye gelen
        isteklere farklı bir uygulama yapılabilir.</p>
    
        <p>Yönergelerin çoğu bu bölümlere yerleştirilebilirse de bazı yönergelerin
        bazı bağlamlarda bir etkisi olmaz. Örneğin, süreç oluşturmayı denetleyen
        yönergeler sadece ana sunucu bağlamına yerleştirilebilir. Hangi yönergenin
        hangi bağlama yerleştirilebileceğini bulmak için yönergenin <a href="mod/directive-dict.html#Context">bağlamına</a> bakınız. Bu konuda daha
        ayrıntılı bilgi edinmek için: <a href="sections.html">Directory, Location ve
        Files Bölümleri Nasıl Çalışır</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">.htaccess Dosyaları</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
    
        <p>httpd yapılandırma sorumluluğunu dağıtmak için site ağaçları içine özel
        dosyalar yerleştirilmesine izin verir. Bu özel dosyalar normalde
        <code>.htaccess</code> dosyaları olmakla birlikte <code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code> yönergesi kullanılarak rasgele bir isim
        belirtilebilir. <code>.htaccess</code> dosyalarına yerleştirilen yönergeler
        sadece dosyanın bulunduğu dizine ve alt dizinlerine uygulanır.
        <code>.htaccess</code> dosyalarında da ana yapılandırma dosyalarında geçerli
        sözdizimi kullanılır. <code>.htaccess</code> dosyaları her istek gelişinde
        yeniden okunduğundan bu dosyalarda yapılan değişiklikler hemen etkisini
        gösterir.</p>
    
        <p><code>.htaccess</code> dosyalarına hangi yönergelerin
        yerleştirilebileceğini bulmak için yönerge <a href="mod/directive-dict.html#Context">bağlamına</a> bakınız.
        Sunucunun yöneticisi <code>.htaccess</code> dosyalarına hangi yönergelerin
        yerleştirilebileceğini ana yapılandırma dosyalarında
        <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> yönergesini kullanarak
        belirleyebilir.</p>
    
        <p><code>.htaccess</code> dosyaları hakkında daha ayrıntılı bilgi edinmek
        için <a href="howto/htaccess.html">.htaccess öğreticisi</a>ne bakabilirsiniz.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/configuring.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/custom-error.html.es�������������������������������������������������������0000664�0001751�0001751�00000032462�14743132254�021000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Respuestas de error personalizadas - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="./">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>Respuestas de error personalizadas</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Apache ofrece la posibilidad de que los webmasters puedan
        configurar las respuestas que muestra el servidor Apache cuando se
        producen algunos errores o problemas.</p>
    
        <p>Las respuestas personalizadas pueden definirse para activarse
        en caso de que el servidor detecte un error o problema.</p>
    
        <p>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&#243;n o por una redirecci&#243;n a otra URL
        (local o externa).</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#behavior">Comportamiento</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configuration">Configuraci&#243;n</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#custom">Mesajes de error personalizados y redirecciones</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behavior" id="behavior">Comportamiento</a></h2>
        
    
        <h3>Comportamiento anterior</h3>
          
    
          <p>NCSA httpd 1.3 devolv&#237;a mensajes antiguos del error o
          problema encontrado que con frecuencia no ten&#237;an
          significado alguno para el usuario, y que no inclu&#237;an en
          los logs informaci&#243;n que diera pistas sobre las causas de
          lo sucedido.</p>
        
    
        <h3>Comportamiento actual</h3>
          
    
          <p>Se puede hacer que el servidor siga uno de los siguientes
          comportamientos:</p>
    
          <ol>
            <li>Desplegar un texto diferente, en lugar de los mensajes de
            la NCSA, o</li>
    
            <li>redireccionar la petici&#243;n a una URL local, o</li>
    
            <li>redireccionar la petici&#243;n a una URL externa.</li>
          </ol>
    
          <p>Redireccionar a otra URL puede resultar de utilidad, pero
          solo si con ello se puede tambi&#233;n pasar alguna
          informaci&#243;n que pueda explicar el error o problema y/o
          registrarlo en el log correspondiente m&#225;s claramente.</p>
    
          <p>Para conseguir esto, Apache define ahora variables de entorno
          similares a las de los CGI:</p>
    
          <div class="example"><p><code>
            REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, 
                image/jpeg<br />
            REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 
                9000/712)<br />
            REDIRECT_PATH=.:/bin:/usr/local/bin:/etc<br />
            REDIRECT_QUERY_STRING=<br />
            REDIRECT_REMOTE_ADDR=121.345.78.123<br />
            REDIRECT_REMOTE_HOST=ooh.ahhh.com<br />
            REDIRECT_SERVER_NAME=crash.bang.edu<br />
            REDIRECT_SERVER_PORT=80<br />
            REDIRECT_SERVER_SOFTWARE=Apache/0.8.15<br />
            REDIRECT_URL=/cgi-bin/buggy.pl
          </code></p></div>
    
          <p>Tenga en cuenta el prefijo <code>REDIRECT_</code>.</p>
    
          <p>Al menos <code>REDIRECT_URL</code> y
          <code>REDIRECT_QUERY_STRING</code> se pasar&#225;n a la nueva
          URL (asumiendo que es un cgi-script o un cgi-include). Las otras
          variables existir&#225;n solo si exist&#237;an antes de aparecer
          el error o problema. <strong>Ninguna</strong> de estas variables
          se crear&#225; si en la directiva <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> ha especificado una
          redirecci&#243;n <em>externa</em> (cualquier cosa que empiece
          por un nombre de esquema del tipo <code>http:</code>, incluso si
          se refiere al mismo servidor).</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Configuraci&#243;n</a></h2>
        
    
        <p>El uso de <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code>
        est&#225; activado para los ficheros .htaccess cuando <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> tiene el valor
        adecuado.</p>
    
        <p>Aqu&#237; hay algunos ejemplos m&#225;s...</p>
    
        <div class="example"><p><code>
          ErrorDocument 500 /cgi-bin/crash-recover <br />
          ErrorDocument 500 "Sorry, our script crashed. Oh dear" <br />
          ErrorDocument 500 http://xxx/ <br />
          ErrorDocument 404 /Lame_excuses/not_found.html <br />
          ErrorDocument 401 /Subscription/how_to_subscribe.html
        </code></p></div>
    
        <p>La sintaxis es,</p>
    
        <div class="example"><p><code>
          ErrorDocument &lt;3-digit-code&gt; &lt;action&gt;
        </code></p></div>
    
        <p>donde action puede ser,</p>
    
        <ol>
          <li>Texto a mostrar. Ponga antes del texto que quiere que se
          muestre unas comillas ("). Lo que sea que siga a las comillas se
          mostrar&#225;. <em>Nota: las comillas (") no se
          muestran.</em></li>
    
          <li>Una URL local a la que se redireccionar&#225; la
          petici&#243;n.</li>
    
          <li>Una URL externa a la que se redireccionar&#225; la
          petici&#243;n.</li>
        </ol>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="custom" id="custom">Mesajes de error personalizados y redirecciones</a></h2>
        
    
        <p>El comportamiento de Apache en cuanto a las redirecciones ha
        cambiado para que puedan usarse m&#225;s variables de entorno con
        los script/server-include.</p>
    
        <h3>Antiguo comportamiento</h3>
          
    
          <p>Las variables CGI est&#225;ndar estaban disponibles para el
          script al que se hac&#237;a la redirecci&#243;n. No se inclu&#237;a
          ninguna indicaci&#243;n sobre la precedencia de la
          redirecci&#243;n.</p>
        
    
        <h3>Nuevo comportamiento</h3>
          
    
          <p>Un nuevo grupo de variables de entorno se inicializa para que
          las use el script al que ha sido redireccionado. Cada
          nueva variable tendr&#225; el prefijo <code>REDIRECT_</code>.
          Las variables de entorno <code>REDIRECT_</code> se crean a
          partir de de las variables de entorno CGI que existen antes de
          la redirecci&#243;n, se les cambia el nombre
          a&#241;adi&#233;ndoles el prefijo <code>REDIRECT_</code>, por
          ejemplo, <code>HTTP_USER_AGENT</code> pasa a ser
          <code>REDIRECT_HTTP_USER_AGENT</code>. Adem&#225;s, para esas
          nuevas variables, Apache definir&#225; <code>REDIRECT_URL</code>
          y <code>REDIRECT_STATUS</code> para ayudar al script a seguir su
          origen. Tanto la URL original como la URL a la que es redirigida
          la petici&#243;n pueden almacenarse en los logs de acceso.</p>
    
          <p>Si ErrorDocument especifica una redirecci&#243;n local a un
          script CGI, el script debe incluir una campo de cabeceraa
          "<code>Status:</code>" en el resultado final para asegurar que
          es posible hacer llegar al cliente de vuelta la condici&#243;n
          de error que lo provoc&#243;. Por ejemplo, un script en Perl
          para usar con ErrorDocument podr&#237;a incluir lo
          siguiente:</p>
    
          <div class="example"><p><code>
            ... <br />
            print  "Content-type: text/html\n"; <br />
            printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"}; <br />
            ...
          </code></p></div>
    
          <p>Si el script tiene como fin tratar una determinada
          condici&#243;n de error, por ejemplo
          <code>404 Not Found</code>, se pueden usar los
          c&#243;digos de error y textos espec&#237;ficos en su lugar.</p>
    
          <p>Tenga en cuenta que el script <em>debe</em> incluir un campo
          de cabecera <code>Status:</code> apropiado (como
          <code>302 Found</code>), si la respuesta contiene un campo de
          cabecera <code>Location:</code> (para poder enviar una
          redirecci&#243;n que se interprete en el cliente). De otra
          manera, la cabecera
          <code>Location:</code> puede que no tenga efecto.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/custom-error.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/bind.html.ja.utf8����������������������������������������������������������0000664�0001751�0001751�00000034530�14743132254�020121� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>バインド - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>バインド</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>Apache が使用するアドレスとポートの設定をします。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">概要</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ipv6">IPv6 の特記事項</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">バーチャルホストに対してどう働くのか</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="vhosts/">バーチャルホスト</a></li><li><a href="dns-caveats.html">DNS の問題</a></li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">概要</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mpm_common.html">mpm_common</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code></li></ul></td></tr></table>
    
    
        <p>Apache は起動時に、ローカルマシンのあるポートおよびアドレス
        に対して接続し、リクエストが来るのを待ちます。
        デフォルトではマシンのすべてのアドレスに対して Listen します。
        特定のポートか、特定のアドレスのみか、
        またはそれらの組み合わせで Listen するように指定したい場合もあります。
        異なる IP アドレス、ホスト名、ポートに対して Apache がどのように
        応答するかを制御するバーチャルホスト機能と組み合わせてよく使われます。</p>
    
        <p><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        ディレクティブで、特定のポートやアドレス・ポートの組から入ってくる
        リクエストのみを受け付けるようにできます。
        もしポート番号だけが <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        ディレクティブで指定された場合は、
        すべてのインターフェースの与えられたポート番号に対して
        Listen します。 IP アドレスとポート番号とが同時に与えられた場合は、
        サーバは与えられたインターフェースのポートを Listen します。
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> ディレクティブを複数使って
        Listen するアドレスとポートをいくつも指定できます。
        サーバは指定されたアドレスやポートからのリクエストすべてに
        対して応答します。</p>
    
        <p>たとえば、全てのインターフェースのポート 80 と 8000 の両方において
        接続を受け付けるには</p>
    
        <div class="example"><p><code>
          Listen 80<br />
          Listen 8000
        </code></p></div>
    
        <p>とします。
        あるインターフェースでは 80 番で、また、同時に他のインターフェースの
        8000 番ポートで接続を受け付けるには、
        </p>
    
        <div class="example"><p><code>
          Listen 192.0.2.1:80<br />
          Listen 192.0.2.5:8000
        </code></p></div>
    
        <p>とします。
        IPv6 アドレスは、角括弧で次の例のように囲まなければいけません。</p>
    
        <div class="example"><p><code>
          Listen [2001:db8::a00:20ff:fea7:ccea]:80
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipv6" id="ipv6">IPv6 の特記事項</a></h2>
        
    
        <p>多くのプラットホームで IPv6 がサポートされてきていて、
        <a class="glossarylink" href="./glossary.html#apr" title="用語集を参照">APR</a> はこれらのほとんどで IPv6 をサポートしているので、
        Apache は IPv6 ソケットを割り当てて IPv6
        経由で送られてきたリクエストを扱うことができます。</p>
    
        <p>IPv6 ソケットが IPv4 と IPv6 コネクションの両方を扱うことができるか
        どうかは、Apache 管理者にとって厄介な問題です。
        IPv4 コネクションを IPv6 ソケットで扱う場合は、
        IPv4 マップされた IPv6 アドレスを使用していて、
        ほとんどのプラットホームではデフォルトで使用可能ですが、
        FreeBSD, NetBSD, OpenBSD では、システム全体としてのポリシーとの整合性から、
        デフォルトでは使用不可に設定されています。
        これらのデフォルトで使用不可のプラットホームであっても、
        特別な <code class="program"><a href="./programs/configure.html">configure</a></code> の
        設定パラメータで Apache の挙動を変化させることができます。</p>
    
        <p>一方で、Linux や Tru64 といったプラットホームで IPv4 と IPv6
        の両方を扱うには、マップドアドレスを使用する<strong>以外の方法はありません</strong>。
        IPv4 と IPv6 のコネクションを最小限のソケットで扱いたいのであれば、
        IPv4 マップの IPv6 アドレスを使用する必要があり、
        <code>--enable-v4-mapped</code> <code class="program"><a href="./programs/configure.html">configure</a></code>
        オプションを指定します。</p>
    
        <p><code>--enable-v4-mapped</code> は、
        FreeBSD, NetBSD, OpenBSD 以外の全てのプラットホームでのデフォルトです。
        ですから、おそらくお手元の Apache はこの設定でビルドされているでしょう。</p>
    
        <p>プラットフォームや APR が何をサポートするかに関わらず、
        IPv4 コネクションのみを扱うようにしたい場合は、
        次の例のように全ての
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> ディレクティブで
        IPv4 アドレスを指定してください。</p>
    
        <div class="example"><p><code>
          Listen 0.0.0.0:80<br />
          Listen 192.0.2.1:80
        </code></p></div>
    
        <p>条件を満たすプラットホームで、Apache が
        IPv4 と IPv6 のコネクションを別々のソケットで扱うようにしたい場合
        (つまり IPv4 マップのアドレスを無効にしたい場合)
        は、<code>--disable-v4-mapped</code>
        <code class="program"><a href="./programs/configure.html">configure</a></code>
        オプションを指定して、次のように個別指定の
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        ディレクティブを使用してください。
        <code>--disable-v4-mapped</code> は、
        FreeBSD, NetBSD, OpenBSD プラットホームでのデフォルトです。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">バーチャルホストに対してどう働くのか</a></h2>
        
    
        <p><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> ディレクティブ
        でバーチャルホストが実装されるわけではありません。
        Listen は単にメインサーバにどのアドレスとポートを Listen すべきかを
        教えるだけです。
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        ディレクティブが使われない場合は、
        受け入れたリクエストすべてに対して全く同じ挙動をします。
        しかしながら
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        を使って、
        一つ以上のアドレスやポートに対して異なる挙動をするように
        指定することができます。
        VirtualHost を実装するには、まず初めに使用したいアドレスとポートに対して
        サーバが Listen していなければなりません。
        そして、その指定したアドレスとポートでの
        このバーチャルホストの挙動を設定するために、
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        セクションを作ります。もし
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        が Listen していないアドレスとポートに対して
        設定されてしまうと、
        それにはアクセスできないということに注意してください。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/bind.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/configuring.html.ja.utf8���������������������������������������������������0000664�0001751�0001751�00000041756�14743132254�021527� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>設定ファイル - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>設定ファイル</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <p>この文書では、Apache HTTP サーバを設定するのに使用するファイルについて
    記述しています。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#main">メインの設定ファイル</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#syntax">設定ファイルの構文</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">モジュール</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#scope">ディレクティブの適用範囲</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#htaccess">.htaccess ファイル</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">メインの設定ファイル</a></h2>
        
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#include">Include</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code></li></ul></td></tr></table>
    
        <p>Apache は <a href="mod/directives.html">ディレクティブ</a> を設定ファイルに平文で書くことにより設定します。
        メインの設定ファイルは普通は <code>httpd.conf</code> という名前です。
        このファイルの位置はコンパイル時に設定されますが、コマンドラインの
        <code>-f</code> フラグにより上書きできます。
        また、他の設定ファイルを <code class="directive"><a href="./mod/core.html#include">Include</a></code>
        ディレクティブによって追加でき、ワイルドカードを使用して多数の
        設定ファイルを追加することができます。
        どんなディレクティブも、これらの設定ファイルどれにでも入れることができます。
        Apache は起動時か再起動時のみメイン設定ファイルの変更を認識します。</p>
    
        <p>サーバは MIME
        ドキュメントタイプを含んでいるファイルも読み込みます。ファイル名は
        <code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code>
        で設定され、デフォルトでは <code>mime.types</code>
        になっています。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="syntax" id="syntax">設定ファイルの構文</a></h2>
        
    
        <p>Apache の設定ファイルは 1 行に 1 つのディレクティブからなります。
        バックスラッシュ "\" はディレクティブが次の行に継続していることを
        示すために行の最後の文字として使われているかもしれません。
        行の最後とバックスラッシュの間に他の文字や空白があってはいけません。
        </p>
    
        <p>設定ファイルのディレクティブは大文字小文字を区別しませんが、
        引数にはしばしば区別するものがあります。ハッシュ文字 "#"
        で始まる行はコメントと見なされて無視されます。
        設定ディレクティブと同一行の末尾にコメントが含まれていては<strong>いけません</strong>。ディレクティブの前の空行と空白は無視されますので、
        わかりやすくするためにディレクティブをインデントしても構いません。
        </p>
    
        <p>設定ファイルの構文エラーは、
        <code>apachectl configtest</code>
        かコマンドラインオプション
        <code>-t</code> を使って調べられます。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="modules" id="modules">モジュール</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>Apache はモジュール化されたサーバです。
        コアサーバには最も基本的な機能だけが含まれています。拡張機能は
        Apache にロードされる<a href="mod/">モジュール</a>として利用可能です。デフォルトでは、コンパイル時にモジュールの
        <a href="mod/module-dict.html#Status">Base</a> セット (基本セット) が
        サーバに含まれます。サーバが<a href="dso.html">動的ロード</a>モジュールを使うようにコンパイルされている場合は、
        モジュールを別にコンパイルして、いつでも
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        ディレクティブを使って追加できます。
        そうでない場合は、モジュールの追加や削除をするためには Apache
        を再コンパイルする必要があります。設定ディレクティブは <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>
        ブロックに入れることで特定のモジュールが存在するときだけ
        設定ファイルに含まれるようにすることができます。</p>
    
        <p>コマンドラインオプション <code>-l</code> を使って現時点で
        どのモジュールがサーバにコンパイルされているかを知ることができます。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="scope" id="scope">ディレクティブの適用範囲</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>メイン設定ファイルにあるディレクティブはサーバ全体に適用されます。
        サーバの一部分の設定だけを変更したい場合は <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>
        セクションの中に置くことで適用範囲を決められます。
        これらのセクションはその中にあるディレクティブの適用範囲を
        特定のファイルシステムの位置や URL に限定します。
        非常に細粒度の設定を可能にするために、
        セクションを入れ子にすることもできます。</p>
    
        <p>Apache は同時に多くの違うウェブサイトを扱う能力があります。
        これは <a href="vhosts/">バーチャルホスト</a> と呼ばれています。
        特定のウェブサイトにのみ適用されるようにするために、
        ディレクティブは
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        セクションの中に置くことでも適用範囲を変えることができます。</p>
    
        <p>ほとんどのディレクティブはどのセクションにでも書けますが、
        中にはコンテキストによっては意味をなさないものもあります。
        例えば、プロセスの作成を制御しているディレクティブはメインサーバの
        コンテキストにのみ書くことができます。
        どのディレクティブをどのセクションに書くことができるかを知るためには
        ディレクティブの <a href="mod/directive-dict.html#Context">コンテキスト</a> を調べてください。詳しい情報は、
        <a href="sections.html">Directory, Location, Files
        セクションの動作法</a>にあります。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">.htaccess ファイル</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
    
        <p>Apache ではウェブツリーの中に置かれた特別なファイルを使って
        非中央集権的な設定管理をできます。その特別なファイルは普通は
        <code>.htaccess</code> という名前で、
        <code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code>
        ディレクティブでどんな名前にでも指定できます。
        <code>.htaccess</code>
        ファイルに書かれたディレクティブはファイルを置いた
        ディレクトリとその全てのサブディレクトリに適用されます。
        <code>.htaccess</code> ファイルは、メインの設定ファイルと同じ
        構文を使います。
        <code>.htaccess</code>
        ファイルはすべてのリクエストで読み込まれるため、
        変更はすぐに反映されます。</p>
    
        <p>どのディレクティブが <code>.htaccess</code>
        ファイルに書けるかを調べるには、ディレクティブの<a href="mod/directive-dict.html#Context">コンテキスト</a>
        を調べてください。サーバ管理者はさらにメイン設定ファイルの
        <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>
        を設定することでどのディレクティブを <code>.htaccess</code>
        ファイルに書けるようにするかを制御することができます。</p>
    
        <p><code>.htaccess</code> ファイルに関する詳しい情報は
        <a href="howto/htaccess.html">.htaccess チュートリアル</a>
        を参照してください。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/configuring.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������httpd-2.4.64/docs/manual/content-negotiation.html.ko.euc-kr�����������������������������������������0000664�0001751�0001751�00000070750�14743132254�023520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title> (Content Negotiation) - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1> (Content Negotiation)</h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    
        <p>ġ HTTP/1.1 Ծ࿡  (content
        negotiation) Ѵ.  media type, , ,
        ڵ     ȣ  ڿ
          ǥ Ѵ.  ҿ   
         û  óϴ ɵ ִ.</p>
    
        <p>⺻ ϵǴ <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>
           Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#about"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#negotiation">ġ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#methods"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#better">ǰ ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extensions">ڿ(transparent)  Ȯ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#naming">۸ũ ̸Ģ Ͽ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#caching">ij Ͽ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="about" id="about"> </a></h2>
    
        <p>ڿ  ٸ ǥ   ִ.  , ٸ
         ٸ media type Ȥ  ΰ ٸ ǥ 
         ִ.   ǥ ϴ Ѱ  ڿ
          ְ ϰ ϴ ̴. ׷ 
        ڵ ϴ ͵ ϴ. ̴  û
        Ϻη ׵ ȣϴ ǥ   ⶧
        ϴ.  ,   Ҿ, ׷
        ٸ   ʹٰ ˷  ִ. 
        û  ׵ ȣ Ÿ.  Ҿε ǥ
        ûѴٸ    .</p>
    
    <div class="example"><p><code>Accept-Language: fr</code></p></div>
    
        <p>̷ ȣ ǥ  ٸ 쿡 ȴ.</p>
    
        <p>   û   Ҿ 
          , Ҿ  ȣϰ,  media type 
         , Ϲ ؽƮ ٴ HTML, ٸ media type ٴ
        GIF JPEG ȣѴٰ ˷ش.</p>
    
    <div class="example"><p><code>
      Accept-Language: fr; q=1.0, en; q=0.5<br />
      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
    </code></p></div>
    
        <p>ġ HTTP/1.1 Ծ࿡ ǵ ' ֵ(server driven)'
         Ѵ. ġ <code>Accept</code>,
        <code>Accept-Language</code>, <code>Accept-Charset</code>,
        <code>Accept-Encoding</code> û   Ѵ.
        , ġ RFC 2295 RFC 2296 ǵ  
        'ڿ(transparent)' û  Ѵ. ׷ 
        RFC ǵ ' (feature negotiation)' 
        ʴ´.</p>
    
        <p><strong>ڿ(resource)</strong> (RFC 2396) URI ϴ
         . ġ   ڿ
        <strong>ǥ(representations)</strong> Ѵ. ǥ
         media type, , ڵ   Ʈ
        ִ. ڿ  ǥ (δ   ִ) ȴ.
        ڿ  ǥ ִٸ ڿ
        <strong>󰡴ϴٰ(negotiable)</strong> θ, ̶
         ǥ <strong>(variant)</strong>̶ Ѵ.
        󰡴 ڿ   
        <strong>(dimension)</strong> Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="negotiation" id="negotiation">ġ </a></h2>
    
        <p>ڿ ϱ      ʿϴ.
         ΰ  ϳ  ´:</p>
    
        <ul>
          <li>  ϵ   type map (<em>
          </em>, <code>*.var</code> ) ϰų,</li>
    
          <li> ʾƵ  ϸ Ģ ãƼ
           ϴ 'MultiViews' Ѵ.</li>
        </ul>
    
       <h3><a name="type-map" id="type-map">type-map  ϱ</a></h3>
    
        <p>type map <code>type-map</code>̶ ڵ鷯 
        (Ȥ  ġ  ȣȯ  MIME type
        <code>application/x-type-map</code>) .  
        Ϸ  <code>type-map</code> ڵ鷯 
         Ȯڸ ؾ Ѵ.  Ͽ  
        ϴ  .</p>
    
    <div class="example"><p><code>AddHandler type-map .var</code></p></div>
    
        <p>Type map  شϴ ڿ ̸ ƾ ϰ,
           ׸ ־ Ѵ. ׸  HTTP
         ٷ ȴ.    ׸ ٷ
        Ѵ. ׸ȿ    . (̷ 
        ʿ䰡 , ־ )  ׸  
        ִ  map  ϴ  ̴. 
        map  .   ̸ <code>foo.var</code>,
        <code>foo</code> ڿ Ѵ.</p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.en.html<br />
      Content-type: text/html<br />
      Content-language: en<br />
    <br />
      URI: foo.fr.de.html<br />
      Content-type: text/html;charset=iso-8859-2<br />
      Content-language: fr, de<br />
    </code></p></div>
        <p>typemap  ϸ Ȯ ,  Multiviews
        Ͽ, 켱  ϶.   ٸ ǰ
        ٸ,   (JPEG, GIF, ASCII-art شϴ)
        media type "qs" Ķͷ ǰ(source quality) ǥ
         ִ:</p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.jpeg<br />
      Content-type: image/jpeg; qs=0.8<br />
    <br />
      URI: foo.gif<br />
      Content-type: image/gif; qs=0.5<br />
    <br />
      URI: foo.txt<br />
      Content-type: text/plain; qs=0.01<br />
    </code></p></div>
    
        <p>qs  0.000 1.000 ̴. qs  0.000 
         õ  ϶. 'qs'    1.0
        ޵ȴ. qs  Ŭ̾Ʈ ɷ°  ٸ 
        Ͽ    'ǰ' Ÿ.  ,
         Ÿ  JPEG  ASCII Ϻٴ ׻
         ǰ . ׷ ڿ  ASCII artٸ
        ASCII ǥ JPEG ǥ   ǰ   ִ.
        ׷Ƿ   qs  ǥϷ ڿ 
         ٸ.</p>
    
        <p>ϴ    <a href="mod/mod_negotiation.html#typemaps">mod_negotation
        typemap</a>  ϶.</p>
    
    
    <h3><a name="multiviews" id="multiviews">Multiviews</a></h3>
    
        <p><code>MultiViews</code> 丮 ɼ̹Ƿ,
        <code>httpd.conf</code>
        <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
        <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>,
        <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
         Ȥ (<code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>
         Ǿٸ) <code>.htaccess</code> 
        <code class="directive"><a href="./mod/core.html#options">Options</a></code> þ 
         ִ. <code>Options All</code> <code>MultiViews</code>
         ϶.    Ѵ.</p>
    
        <p><code>MultiViews</code> ϸ    Ͼ:
         <code>/some/dir/foo</code>  û ް
        <code>/some/dir/foo</code> <code>MultiViews</code> ϸ
        <code>/some/dir/foo</code>  <em></em> ,
         丮 ̸ foo.* ϵ  ϴ
         type map . Ŭ̾Ʈ û media type
        content-encoding  ߿    Ѵ.</p>
    
        <p><code>MultiViews</code>  丮 Ҷ
         ã <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code> þ
        ȴ.   ٸ,</p>
    <div class="example"><p><code>DirectoryIndex index</code></p></div>
        <p><code>index.html</code> <code>index.html3</code>
         ִٸ  ̵ ߿ ϳ Ѵ.   
        <code>index.cgi</code> ִٸ,  װ Ѵ.</p>
    
        <p>丮   ϳ Charset, Content-Type,
        Language, Encoding Ǵϴ <code>mod_mime</code> 𸣴
        Ȯڸ ٸ,  <code class="directive"><a href="./mod/mod_mime.html#multiviewsmatch">MultiViewsMatch</a></code> þ 
        ޷Ǵ.  þ ڵ鷯, , ٸ Ȯ MultiViews
          θ Ѵ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="methods" id="methods"></a></h2>
    
        <p>ġ type-map ̳ 丮 ִ ϸ
        ־ ڿ    ԵǸ '' 
        ϱ   ϳ Ѵ. ġ 
         ϱ Ȯ   Ͼ ڼ
         ʿ . ׷ ñ     Ѵ.</p>
    
        <p>ΰ  ִ:</p>
    
        <ol>
          <li><strong>ġ ˰ Ͽ  ֵϴ
          </strong> Ϲ 쿡 Ѵ. ġ ˰
          Ʒ ڼ Ѵ.  ˰ ϸ ġ
               Ư 
          ǰ(quality factor) 'Ѵ'. ġ ǰ
          ϴ  Ʒ ڼ Ѵ.</li>
    
          <li><strong>ڿ(Transparent) </strong>
           RFC 2295 ǵ  û 쿡
          Ѵ.   ''   
           οѴ. ׷   ˰
          ޷ȴ. ڿ ߿  ġ
          RFC 2296 ǵ '  ˰(remote variant
          selection algorithm)' û  ִ.</li>
        </ol>
    
    <h3><a name="dimensions" id="dimensions"> </a></h3>
    
        <table>
          
          <tr valign="top">
            <th></th>
    
            <th></th>
          </tr>
    
          <tr valign="top">
            <td>Media Type</td>
    
            <td> <code>Accept</code>  ȣ Ÿ.
             ׸ ǰ   ִ.   ǰ
            ("qs" Ķ)   ִ.</td>
          </tr>
    
          <tr valign="top">
            <td>Language</td>
    
            <td> <code>Accept-Language</code>  ȣ
            Ÿ.  ׸ ǰ   ִ. 
               (Ȥ ƹ  )  ִ.</td>
          </tr>
    
          <tr valign="top">
            <td>Encoding</td>
    
            <td> <code>Accept-Encoding</code>  ȣ
            Ÿ.  ׸ ǰ   ִ.</td>
          </tr>
    
          <tr valign="top">
            <td>Charset</td>
    
            <td> <code>Accept-Charset</code>  ȣ
            Ÿ.  ׸ ǰ   ִ. 
            media type Ķͷ  Ÿ  ִ.</td>
          </tr>
        </table>
    
    
    <h3><a name="algorithm" id="algorithm">ġ  ˰</a></h3>
    
        <p>ġ   ''  (ִٸ)
        ϱ Ʒ ˰ Ѵ.  ˰ 
         .   Ѵ:</p>
    
        <ol>
          <li>,     شϴ <em>Accept*</em>
           ˻ϰ,   ǰ ű.  
          <em>Accept*</em>  ޾Ƶ ʴ  ĺ
          Ѵ.    4 ܰ .</li>
    
          <li>
            ĺ ϳ Ͽ ''  ã´. 
             ˻  Ͼ.  ˻翡 õ
             ܵȴ.  ˻    ̸ 
             ϰ 3 ܰ .   
             ˻縦 Ѵ.
    
            <ol>
              <li><code>Accept</code>  ǰ 
              media type  ǰ Ͽ   
                Ѵ.</li>
    
              <li>  (language) ǰ  
              Ѵ.</li>
    
              <li><code>Accept-Language</code>  (ִٸ)
                 Ȥ <code>LanguagePriority</code>
              þ (ִٸ)     
                  Ѵ.</li>
    
              <li>  (text/html media type  Ÿ)
              'level' media Ķ͸   Ѵ.</li>
    
              <li><code>Accept-Charset</code>   
               charset media Ķ͸   ã´.
               ٸ ISO-8859-1   ȣѴ.
              <code>text/*</code> media type  
              Ư հ   ISO-8859-1
              Ѵ.</li>
    
              <li>ISO-8859-1 <em>ƴ</em> charset media Ķ͸
                Ѵ. ׷  ٸ,  
               Ѵ.</li>
    
              <li>  ڵ   Ѵ.
              user-agent  ڵ   ִٸ 
               Ѵ. ׷ʰ ڵ  ڵȵ
                ִٸ ڵȵ  Ѵ. 
               ڵǾų  ڵȵ   
              Ѵ.</li>
    
              <li>content length    Ѵ.</li>
    
              <li>  ù  Ѵ. ̴ type-map
               տ ԰ų, 丮   
              ϸ ASCII ڵ  Ͽ տ  ̴.</li>
            </ol>
          </li>
    
          <li> ˰ ''  ߴ. ̰ 
          . HTTP   <code>Vary</code>  
          Ÿ ȴ. ( ij ڿ ijҶ  
            ִ.) .</li>
    
          <li> ܰ迡 ߴٸ (  ϱ )
             ȵ . ("No acceptable
          representation" ϴ)  406  밡
             HTML   . , HTML
          <code>Vary</code>    Ÿ.</li>
        </ol>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="better" id="better">ǰ ϱ</a></h2>
    
        <p>ġ   ġ  ˰  Űʰ
        ǰ Ѵ.  ϰ Ȯ  ʴ
         (˰)     ؼ.
        θ ̴  Ϻδ  ߸  ϵ
        <code>Accept</code>  .  ϰ ùٸ
         ٸ,  ʴ´.</p>
    
    <h3><a name="wildcards" id="wildcards">Media Type ϵī</a></h3>
    
        <p><code>Accept:</code> û  media type  ȣ
        Ÿ. , *  ڿ̶ ϱ⶧ "image/*"
        "*/*"  'ϵī' media type   ִ. ׷
          û:</p>
    
    <div class="example"><p><code>Accept: image/*, */*</code></p></div>
    
        <p>"image/" ϴ  type ٸ  type 
        ǹѴ.  
        ڽ  ٷ  ִ type ߰ ϵī带 .
         :</p>
    
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*
    </code></p></div>
        <p>   type ȣ ٸ ǥ ִٸ
        װ͵  Ÿ ؼ.   
    	    ǰ  ̴.</p>
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
    </code></p></div>
        <p>  type ǰ  ⺻ ( )
        1.0 . ϵī */*  ȣ 0.01 Ƿ
          type ´   쿡 ٸ type
        ȴ.</p>
    
        <p><code>Accept:</code>  q   <em></em>
        "*/*" ִٸ, ġ ٶ ൿ  q  0.01
        Ѵ. , "type/*"  ϵī忡 ("*/*"ٴ
         ȣϵ) 0.02 Ѵ. <code>Accept:</code> 
        q   media type ִٸ ̷ Ư  ߰
        <em>ʴ´</em>. ׷    
        û ûѵ óѴ.</p>
    
    
    <h3><a name="exceptions" id="exceptions">(language)  </a></h3>
    
        <p>ġ 2.0     ε巴 ϱ
         ˰  ܸ  ߰ߴ.</p>
    
        <p>Ŭ̾Ʈ   û  
         <code>Accept-language</code> ´   Ѱ
        ã  , ׷    Ŭ̾Ʈ
        "No Acceptable Variant" "Multiple Choices"  .
        ̷  ϱ   <code>Accept-language</code>
        ϰ Ŭ̾Ʈ û Ȯ   
         ġ   ִ. <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>
        þ  ̷  ϳ Ȥ Ѵٸ ϰ
        <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>
        þ Ǵϵ Ѵ.</p>
    
        <p>,  ´  ã  θ ã 
        ִ.   Ŭ̾Ʈ  ϴ
        <code>en-GB</code>   û , HTTP/1.1 ǥؿ
          <code>en</code>θ ǥõ  Ϲ
         Ѵ. (׷  ϴ ڰ Ϲ
           Ƿ <code>Accept-Language</code> 
        <code>en-GB</code> ϰ <code>en</code> 
         Ȯ ߸  ϶.   
        Ŭ̾Ʈ ̷  ⺻ִ.) ٸ 
        ã Ͽ  "No Acceptable Variants"  ų
        <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>
        ư Ѵٸ,   Ծ ϰ
        <code>en-GB</code> <code>en</code>  Ѵ.
        Ϲ ġ θ ſ  ǰ
        Ŭ̾Ʈ  Ͽ ߰Ѵ. ׷ Ŭ̾Ʈ
        "en-GB; q=0.9, fr; q=0.8" ûϰ  "en" "fr"
         ִٸ, "fr"  õ ϶. ̴ HTTP/1.1
        ǥ Ű, ùٷ  Ŭ̾Ʈ ȿ
        ϱ̴.</p>
    
        <p>ڰ ȣϴ  ˾Ƴ (Ű Ư
        URL- )   ϱ ġ 2.0.47
        <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> <code>prefer-language</code>
        <a href="env.html">ȯ溯</a> νѴ.  ȯ溯
        ϰ  ±׸ Ѵٸ,
        <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> شϴ  Ϸ
        õѴ. ׷  ٸ Ϲ  Ѵ.</p>
    
        <div class="example"><h3></h3><p><code>
          SetEnvIf Cookie "language=(.+)" prefer-language=$1
        </code></p></div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extensions" id="extensions">ڿ(transparent)  Ȯ</a></h2> 
    
    <p>ġ   ڿ Ȯ  (RFC 2295)
    ȮѴ.   ο <code>{encoding ..}</code> Ư
    content-encoding   ĪѴ. RVSA/1.0 ˰
    (RFC 2296) Ͽ ڵ  ν  ְ, ڵ
    <code>Accept-Encoding</code> û  ´  ڵ
    鵵 ĺ ϵ ȮǾ. RVSA/1.0  
     ã   ǰ Ҽ 5ڸ ݿø
    ʴ´.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="naming" id="naming">۸ũ ̸Ģ Ͽ</a></h2>
    
        <p>(language)  Ѵٸ   Ȯڸ
         Ȯ   Ƿ ϸ  ٸ
        ̸Ģ   ִ. (ڼ  <a href="mod/mod_mime.html#multipleext">mod_mime</a> 
        ϶.)</p>
    
        <p>  MIME-type Ȯ (<em> </em>,
        <code>html</code>), 쿡  encoding Ȯ (<em>
        </em>, <code>gz</code>), Ͽ    ִ
           Ȯڸ (<em> </em>, <code>en</code>)
        .</p>
    
        <p>:</p>
    
        <ul>
          <li>foo.en.html</li>
    
          <li>foo.html.en</li>
    
          <li>foo.en.html.gz</li>
        </ul>
    
        <p>  ϸ  Ͽ  ȿϰ ȿ
        ۸ũ δ:</p>
    
        <table class="bordered">
          
          <tr>
            <th>ϸ</th>
    
            <th>ȿ ۸ũ</th>
    
            <th>ȿ ۸ũ</th>
          </tr>
    
          <tr>
            <td><em>foo.html.en</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>-</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html</em></td>
    
            <td>foo</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.en.gz</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>foo.gz<br />
             foo.html.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html.gz</em></td>
    
            <td>foo</td>
    
            <td>foo.html<br />
             foo.html.gz<br />
             foo.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.gz.html.en</em></td>
    
            <td>foo<br />
             foo.gz<br />
             foo.gz.html</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.gz.en</em></td>
    
            <td>foo<br />
             foo.html<br />
             foo.html.gz</td>
    
            <td>foo.gz</td>
          </tr>
        </table>
    
        <p> ǥ  ۸ũ  Ȯڵ  ̸
        (<em> </em>, <code>foo</code>) ׻   
          ִ.         ־,
        <em> </em> ̷ũ  Ͼʰ
        <code>html</code>  <code>shtml</code>̳
        <code>cgi</code>   ִٴ ̴.</p>
    
        <p> ۸ũ MIME-type (<em> </em>,
        <code>foo.html</code>) ϰ ʹٸ (encoding Ȯڰ
        ִٸ ̰͵ Ͽ)  Ȯڸ MIME-type Ȯں
        ʿ (<em> </em>, <code>foo.html.en</code>)
        ξѴ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="caching" id="caching">ij Ͽ</a></h2>
    
        <p>ij ǥ ϸ ǥ û URL Ų.
          URL ûϸ ij  ǥ Ѵ.
        ׷    ڿ  ù° û 
        ijǾ  û ij ߸    ִ.
        ̸  ġ   ȯǴ  û
        HTTP/1.0 Ŭ̾Ʈ ij ϵ ǥø Ѵ. , ġ
          ij ϴ HTTP/1.1  
        Ѵ.</p>
    
        <p><code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code>
        þ HTTP/1.0 ȣȯ Ŭ̾Ʈ( Ȥ ij)
         û    ij  ְ Ѵ.  þ
         ȣƮ  ϸ, ƱԸƮ ʴ´.
         þ HTTP/1.1 Ŭ̾Ʈ û 谡 .</p>
    
        <p>HTTP/1.1 Ŭ̾Ʈ ġ   
        ˷ִ <code>Vary</code> HTTP  .  
        Ͽ  û ij 纻 ü  ִ
        Ǵ  ִ.    ij 纻
        Ѵٸ <code>force-no-vary</code> <a href="env.html#special">ȯ溯</a> Ѵ.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/content-negotiation.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������httpd-2.4.64/docs/manual/bind.html������������������������������������������������������������������0000664�0001751�0001751�00000001032�13710016232�016620� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: bind.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: bind.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: bind.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: bind.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/custom-error.html.ko.euc-kr������������������������������������������������0000664�0001751�0001751�00000027022�14743132254�022163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>   - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>  </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>ʹ   ߻ ġ 
          ִ.</p>
    
        <p>   ߰   
          ִ.</p>
    
        <p>ũƮ   "500 Server Error"   ڿ
         ģ  ϰų ٸ ( Ʈ ܺ Ʈ)
        URL ̷   ִ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#behavior">ൿ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configuration"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#custom">   ̷</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behavior" id="behavior">ൿ</a></h2>
        
    
        <h3> ൿ</h3>
          
    
          <p>NCSA httpd 1.3 ڿ ǹϰ  
          ´.  ߻  α׿   .</p>
        
    
        <h3>ο ൿ</h3>
          
    
          <p>      ִ:</p>
    
          <ol>
            <li>NCSA    ٸ  ְų</li>
    
            <li> Ʈ URL ̷ϰų</li>
    
            <li>ܺ Ʈ URL ̷Ѵ.</li>
          </ol>
    
          <p>ٸ Ʈ URL ̷ϴ    ,
             ϰų αϴµ ʿ  Ϻθ
          ޵ȴ.</p>
    
          <p>   ϱ ġ CGI ο
          ȯ溯 Ѵ:</p>
    
          <div class="example"><p><code>
            REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, 
                image/jpeg<br />
            REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 
                9000/712)<br />
            REDIRECT_PATH=.:/bin:/usr/local/bin:/etc<br />
            REDIRECT_QUERY_STRING=<br />
            REDIRECT_REMOTE_ADDR=121.345.78.123<br />
            REDIRECT_REMOTE_HOST=ooh.ahhh.com<br />
            REDIRECT_SERVER_NAME=crash.bang.edu<br />
            REDIRECT_SERVER_PORT=80<br />
            REDIRECT_SERVER_SOFTWARE=Apache/0.8.15<br />
            REDIRECT_URL=/cgi-bin/buggy.pl
          </code></p></div>
    
          <p><code>REDIRECT_</code> λ翡 ָ϶.</p>
    
          <p>ּ <code>REDIRECT_URL</code>
          <code>REDIRECT_QUERY_STRING</code> (cgi-script
          cgi-include)  URL Ѱ. ٸ  
          ߻ϱ  <span class="transnote">(<em>;</em> ̸ <code>REDIRECT_</code>
           ȯ溯)</span>  쿡 ִ.
          <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code>
          <em>ܺη</em> (  <code>http:</code>
           Ŵ(scheme) Ѵٸ) ̷Ѵٸ
            ͵  <strong>ʴ´</strong>.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration"></a></h2>
        
    
        <p><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>
         Ǿٸ .htaccess Ͽ
        <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> 
         ִ.</p>
    
        <p> ̴...</p>
    
        <div class="example"><p><code>
          ErrorDocument 500 /cgi-bin/crash-recover <br />
          ErrorDocument 500 "Sorry, our script crashed. Oh dear" <br />
          ErrorDocument 500 http://xxx/ <br />
          ErrorDocument 404 /Lame_excuses/not_found.html <br />
          ErrorDocument 401 /Subscription/how_to_subscribe.html
        </code></p></div>
    
        <p>,</p>
    
        <div class="example"><p><code>
          ErrorDocument &lt;3-digit-code&gt; &lt;action&gt;
        </code></p></div>
    
        <p> action,</p>
    
        <ol>
          <li> . ǥ (")  տ δ. ڿ 
          ǥ µȴ. <em>: տ  ǥ (") µ
          ʴ´.</em></li>
    
          <li>̷ ܺ URL.</li>
    
          <li>̷  URL.</li>
        </ol>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="custom" id="custom">   ̷</a></h2>
        
    
        <p>URL ̷ϴ ġ ൿ
        ũƮ/server-include ȯ溯  Ѱֵ Ǿ.</p>
    
        <h3> ൿ</h3>
          
    
          <p>̷ǵǴ ũƮ ǥ CGI  Ѿ.
          𿡼 ̷ Ͼ   .</p>
        
    
        <h3>ο ൿ</h3>
          
    
          <p>̷ǵ ũƮ ο ȯ溯 
           ִ.  տ <code>REDIRECT_</code> پִ.
          <code>REDIRECT_</code> ȯ溯  CGI ȯ溯
          տ <code>REDIRECT_</code> ٿ . <em>
          </em>, <code>HTTP_USER_AGENT</code>
          <code>REDIRECT_HTTP_USER_AGENT</code> Ǿ. ̷ 
          ߰ ũƮ  URL ˵ ġ
          <code>REDIRECT_URL</code> <code>REDIRECT_STATUS</code>
          Ѵ.  URL ̷ǵ URL   α׿
            ִ.</p>
    
          <p>ErrorDocument   ִ CGI ũƮ
          ̷Ѵٸ, ũƮ Ŭ̾Ʈ  Ȳ
          Ȯ ϱ ¿ "<code>Status:</code>" 
          ʵ带 ؾ Ѵ.  , Perl ۼ ErrorDocument
          ũƮ  :</p>
    
          <div class="example"><p><code>
            ... <br />
            print  "Content-type: text/html\n"; <br />
            printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"}; <br />
            ...
          </code></p></div>
    
          <p><code>404&nbsp;Not&nbsp;Found</code>  Ư 
          Ȳ  ũƮ,  <span class="transnote">(<em>;</em> )</span>
          Ư ڵ    ִ.</p>
    
          <p>(Ŭ̾Ʈ ̷ ûϱ) 信
          <code>Location:</code>  Ѵٸ, ũƮ
          <em>ݵ</em> (<code>302&nbsp;Found</code> ) 
          <code>Status:</code>  ؾ  ϶. ׷
          <code>Location:</code>  ƹ ҿ   ִ.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/custom-error.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/caching.html���������������������������������������������������������������0000664�0001751�0001751�00000000444�13710016232�017306� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: caching.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: caching.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: caching.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/content-negotiation.html.tr.utf8�������������������������������������������0000664�0001751�0001751�00000112126�14743132254�023226� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>İçerik Uzlaşımı - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>İçerik Uzlaşımı</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Apache HTTPD, içerik uzlaşımını HTTP/1.1 belirtiminde bahsedildiği şekliyle
          destekler. Bir özkaynağın en iyi gösterimini, tarayıcının sağladığı
          karakter kodlaması, karakter kümesi, dil, ortam türü gibi kullanıcı
          tercihlerine bağlı olarak seçebilir. Ayrıca, tarayıcının kullanıcı
          tercihlerini tam yansıtamadığı durumlarda istekleri daha akıllıca ele
          alabilmeyi sağlayacak bir takım özelliklere de sahiptir.</p>
    
        <p>İçerik uzlaşımı öntanımlı olarak derlenen
          <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> modülü tarafından sağlanır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#about">İçerik Uzlaşımı Hakkında</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#negotiation">httpd’de İçerik Uzlaşımı</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#methods">Uzlaşım Yöntemleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#better">Üstünlük Değerleriyle Oynamak</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extensions">Şeffaf İçerik Uzlaşımının Genişletilmesi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#naming">Hiperbağlar ve İsimlendirme Uzlaşımları</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#caching">Arabellekler Hakkında</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="about" id="about">İçerik Uzlaşımı Hakkında</a></h2>
    
        <p>Bir özkaynağın bir çok farklı gösterimi olabilir. Örneğin, bir belgenin
          farklı ortam türleri ve/veya farklı diller için gösterimleri olabilir.
          En uygun seçimi yapmanın tek yolu kullanıcıya bir liste verip seçmesini
          istemektir. Bununla birlikte sunucunun bu seçimi kendiliğinden yapması
          da mümkündür. Tarayıcılar isteğin bir parçası olarak kullanıcı
          tercihlerini de gönderdiğinden bu istendiği gibi çalışır. Örneğin bir
          tarayıcı, kullanıcısınının mümkünse Fransızca içerik tercih ettiğini
          yoksa İngilizce içeriğe de razı olabileceğini belirtebilirdi.
          Tarayıcılar bu tercihleri başlıkta belirtirler. Tarayıcı sadece Türkçe
          içerik istendiğini şöyle belirtebilirdi:</p>
    
        <div class="example"><p><code>Accept-Language: tr</code></p></div>
    
        <p>Bu tercihin yerine getirilebilmesininin sadece, desteklenen diller
          arasında bu dilin varlığına ve istenen belgenin bu dilde bir
          gösteriminin bulunmasına bağlı oluşuna dikkat ediniz.</p>
    
        <p>Daha karmaşık bir istek örneği olarak, tarayıcının Fransızca ve
          İngilizce içerik kabul etmeye ayarlandığını fakat Fransızcayı tercih
          ettiğini ve çeşitli ortam türlerini kabul etmekle birlikte salt metin ve
          diğer metin türlerinden ziyade HTML tercih ettiğini, ayrıca, diğer ortam
          türleri üzerinde GIF veya JPEG tercih ettiğini fakat başka çare yoksa
          her ortam türüne de izin verdiğini belirtiyor olsun:</p>
    
        <div class="example"><p><code>
          Accept-Language: fr; q=1.0, en; q=0.5<br />
          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
        </code></p></div>
    
        <p>httpd, HTTP/1.1 belirtiminde tanımlanan şekliyle ‘sunucu yönetiminde’
          içerik uzlaşımını destekler. <code>Accept</code>,
          <code>Accept-Language</code>, <code>Accept-Charset</code> ve
          <code>Accept-Encoding</code> istek başlıklarını tamamen destekler.
          httpd ayrıca, RFC 2295 ve RFC 2296’da tanımlanan bir deneysel uzlaşım
          olarak ‘şeffaf’ içerik uzlaşımını da destekler. Fakat ‘özellik
          uzlaşımını’ bu RFC’lerde tanımlandığı gibi desteklemez.</p>
    
        <p>Bir <strong>özkaynak</strong> bir URI (RFC 2396) tarafından betimlenen
          kavramsal bir öğedir. Apache gibi bir HTTP sunucusu, ortam türü,
          karakter kümesi, kodlama ve saire ile tanımlanmış bir bayt dizisi
          şeklindeki her gösterimiyle, özkaynaklara kendi isim alanları dahilinde
          erişim sağlar. Her özkaynağın aynı anda bir veya daha fazla gösterimi
          mevcut olabileceği gibi hiç mevcut olmayabilir de. Eğer çok sayıda
          gösterim mevcutsa, bu özkaynağın <strong>uzlaşılabilir</strong>
          olduğundan ve her gösteriminin  bir <strong>çeşitlilik</strong>
          oluşturduğundan bunun da uzlaşımın <strong>boyutlar</strong>ından
          kaynaklandığından bahsedilebilir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="negotiation" id="negotiation">httpd’de İçerik Uzlaşımı</a></h2>
    
        <p>Bir özkaynak üzerinde uzlaşılırken gösterim çeşitlerinin her biri
          hakkında sunucuya bilgi verilmesi gerekir. Bu iki yolla yapılabilir:</p>
    
        <ul>
          <li>Ya gösterim çeşitlerini içeren dosyaların isimleriyle eşleşmeyi
            sağlayan bir tür eşlemi kullanılır (bir <code>*.var</code> dosyası
            gibi).</li>
    
          <li>Ya da sunucu örtük bir dosya ismi kalıbı eşleşmesinin ardından
            sonuçlar arasından seçim yapar; buna ‘Çoklu Görünüm’ araması adı
            verilir.</li>
        </ul>
    
       <h3><a name="type-map" id="type-map">Bir türeşlem dosyası kullanmak</a></h3>
    
        <p>Bir türeşlem dosyası, <code>type-map</code> eylemcisi ile ilişkili bir
          belgedir (ya da eski httpd yapılandırmaları ile geriye uyumluluk için,
          <code>application/x-type-map</code> <a class="glossarylink" href="./glossary.html#mime türü" title="sözlüğe bakınız">MIME türü</a>nde
          bir belgedir). Bu özelliği kullanmak için, yapılandırmada bir tür
          eşleyici olarak her dosya ismi uzantısı için bir <code>type-map</code>
          eylemcisi tanımlamalısınız. Bu, sunucu yapılandırma dosyasında en iyi
          şöyle yapılabilir:</p>
    
        <pre class="prettyprint lang-config">AddHandler type-map .var</pre>
    
    
        <p>Türeşlem dosyaları kendilerini tanımlayan özkaynak ile aynı isimde
          olmalı ve isim bir <code>.var</code> uzantısı içermelidir. Aşağıdaki
          örneklerde özkaynak ismi <code>foo</code> olduğundan türeşlem dosyasının
          ismi <code>foo.var</code>'dır.</p>
    
        <p>Bu dosya her gösterim çeşidi için bir girdi içermelidir; bu girdiler
          ardarda belirtilen HTTP biçem başlık satırlarından oluşur. Farklı
          gösterimlerin girdileri bir boş satırla diğerlerinden ayrılır. Aynı
          girdi içinde boş satır kullanılamaz. Bir eşlem dosyasını bir birleşik
          öğenin tamamı için bir girdi ile başlatmak adet olmuştur (ise de, bu
          gerekli değildir, hele yoksayılacaksa hiç gerekli değildir). Eşlem
          dosyası için aşağıda bir örnek verilmiştir.</p>
    
       <p>Bu dosyadaki URI'ler türeşlem dosyasının yerine görelidir. Dolayısıyla,
         bu dosyaların aynı dizinde bulunması beklenirse de bu gerekli değildir.
         Aynı sunucuda bulunan tüm dosyalar için türeşlem dosyasındaki gibi mutlak
         veya göreli URI'ler belirtebilirsiniz.</p>
    
        <div class="example"><p><code>
          URI: misal<br />
        <br />
          URI: misal.en.html<br />
          Content-type: text/html<br />
          Content-language: en<br />
        <br />
          URI: misal.fr.de.html<br />
          Content-type: text/html;charset=iso-8859-2<br />
          Content-language: fr, de<br />
        </code></p></div>
    
        <p>Ayrıca, <code>MultiViews</code> etkin olsa bile bir türeşlem dosyasının
          dosya ismi uzantılarının taranmasına göre öncelik alacağına dikkat
          ediniz. Eğer gösterimler bu örnekteki resim dosyasında olduğu gibi
          farklı kaynak üstünlüklerine sahipseler, ortam türünün <code>qs</code>
          parametresi kullanılarak kaynak üstünlükleri belirtilebilir: </p>
    
        <div class="example"><p><code>
          URI: misal<br />
        <br />
          URI: misal.jpeg<br />
          Content-type: image/jpeg; <strong>qs=0.8</strong><br />
        <br />
          URI: misal.gif<br />
          Content-type: image/gif; <strong>qs=0.5</strong><br />
        <br />
          URI: misal.txt<br />
          Content-type: text/plain; <strong>qs=0.01</strong><br />
        </code></p></div>
    
        <p><code>qs</code> değerleri 0.000-1.000 değer aralığı içinde
          belirtilebilir. 0.000 <code>qs</code> değerine sahip gösterimin asla
          seçilmeyeceğine dikkat ediniz. Bir <code>qs</code> değeri belirtilmeyen
          gösterimlerin kaynak üstünlüğü 1.000 kabul edilir. <code>qs</code>
          parametresinin belirttiği değer istemcinin yeteneklerinden bağımsız
          olarak olası gösterimler arasında göreli bir üstünlük ifade eder.
          Örneğin bir fotoğraf sözkonusu olduğunda bir JPEG dosyasının kaynak
          üstünlüğü bir ASCII çiziminkinden yüksek olacaktır. Diğer taraftan özgün
          resim bir ASCII çizim olduğu takdirde, ASCII çizim, bir JPEG gösterimine
          göre öncelikli olacaktır. Bu nedenle <code>qs</code> değeri özkaynağın
          doğasına bakarak belirlenir.</p>
    
        <p>Tanınan başlıkların tam listesini <a href="mod/mod_negotiation.html#typemaps">mod_negotiation</a> modülünün
          belgesinde bulabilirsiniz.</p>
      
    
      <h3><a name="multiviews" id="multiviews">Çoklu Görünümler</a></h3>
    
        <p><code>MultiViews</code>, <code>httpd.conf</code> dosyasındaki veya
          (<code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> yönergesinin
          değerine bağlı olarak) <code>.htaccess</code> dosyalarındaki <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> veya <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> bölümleri içinde
          <code class="directive"><a href="./mod/core.html#options">Options</a></code> yönergeleri ile
          belirtilebilen, dizine özgü bir seçenektir. Yalnız, dikkatli olun,
          <code>Options All</code> yaparak <code>MultiViews</code> seçeneğini
          etkin kılamazsınız; seçeneği ismiyle açıkça belirtmelisiniz.</p>
    
        <p><code>MultiViews</code> şöyle etki eder: Sunucudan,
          <code>MultiViews</code> seçeneğinin etkin olduğu <code>/bir/dizin</code>
          dizininden <code>filanca</code> dosyası için bir istekte bulunulmuşsa
          fakat dizinde bu dosya yoksa, sunucu dizin içeriğini
          <code>filanca.*</code> dosyaları için tarar ve bu dosyalar için
          istemcinin ismiyle talep ettiği ortam türlerini ve kodlamaları
          kullanarak bir türeşlem dosyası uydurup bu gösterimler arasından
          istemcinin gereksinimlerine en uygun gösterimi seçer.</p>
    
        <p><code>MultiViews</code> ayrıca, sunucunun bir dizin içeriğini
          listelemeye çalıştığı durumda <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code> yönergesi ile belirtilen dosya için de bir
          arama tertipleyebilir. Eğer yapılandırma dosyalarında</p>
    
        <pre class="prettyprint lang-config">DirectoryIndex index</pre>
    
    
        <p>şeklinde bir atama varsa ve dizinde <code>index.html</code> ve
          <code>index.html3</code> dosyaları varsa sunucu bunlar arasından hakem
          sıfatıyla bir seçim yapacaktır; ama bu ikisi yerine dizinde sadece
          <code>index.cgi</code> mevcutsa sunucu sadece bu dosyayı
          çalıştıracaktır.</p>
    
        <p>Okunan dizinde bulunan dosyalar arasında <code>mod_mime</code>
          tarafından tanınan karakter kümesi, içerik türü, dil ve kodlama
          başlıklarına uygun gösterim uzantılarından birine sahip bir dosya yoksa
          sonuç <code class="directive"><a href="./mod/mod_mime.html#multiviewsmatch">MultiViewsMatch</a></code>
          yönergesiyle yapılan tanıma bağlı olur. Bu yönerge hangi diğer dosya
          uzantılarının, eylemcilerin veya süzgeçlerin çok gösterimli uzlaşımla
          ilintileneceğini belirler.</p>
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="methods" id="methods">Uzlaşım Yöntemleri</a></h2>
    
        <p>httpd’nin, bir türeşlem dosyası veya dizin içindeki bir dosya
          sayesinde belli bir özkaynağın gösterim çeşitlerinin bir listesini elde
          ettikten sonra ‘en uygun’ gösterime karar vermek için kullanabileceği
          iki yöntem vardır. httpd’nin içerik uzlaşım özelliklerinin kullanımı
          sırasında uzlaşımın nasıl yerine getirileceği ile ilgili ayrıntıları
          bilmek aslında gerekli değildir. Bununla birlikte belgenin kalanında bu
          konu açıklanmaya çalışılmıştır.</p>
    
        <p>İki uzlaşım yöntemi vardır:</p>
    
        <ol>
          <li>Normal durumda <strong>sunucu yönetiminde httpd uzlaşım
            algoritması</strong> kullanılır. Bu algoritma aşağıda ayrıntılı olarak
            açıklanmıştır. Bu algoritma kullanıldığı zaman, httpd, en iyi sonuca
            ulaşmak için bazen belli boyutların üstünlük katsayılarıyla ‘oynar’.
            httpd’nin bu katsayılarla oynama işini nasıl yaptığı aşağıda daha
            ayrıntılı açıklanmıştır.</li>
    
          <li>İstemci bu işlem için özellikle RFC 2295’te tanımlanan mekanizmanın
            kullanılmasını isterse <strong>şeffaf içerik uzlaşımı</strong>
            kullanılır. Bu uzlaşım yöntemi, en uygun gösterimin seçilmesi
            konusunda tarayıcıya tam denetim imkanı verir; dolayısıyla sonuç
            tarayıcının bu işlem için kullandığı algoritmanın başarısına bağlıdır.
            Şeffaf uzlaşım sürecinin bir parçası olarak, tarayıcı, RFC 2296’da
            tanımlanan ‘gösterim çeşidini uzaktan seçme algoritması’nın
            çalıştırılmasını httpd’den isteyebilir.</li>
        </ol>
    
      <h3><a name="dimensions" id="dimensions">Uzlaşımın Boyutları</a></h3>
    
        <table>
          
          <tr valign="top">
            <th>Boyut</th>
    
            <th>Açıklama</th>
          </tr>
    
          <tr valign="top">
            <td>Ortam Türü</td>
    
            <td>Tarayıcı ortam türü tercihlerini <code>Accept</code> başlık alanı
              ile belirtir. Her öğenin kendine özgü bir üstünlük katsayısı
              olabilir. Gösterimin açıklaması da ayrıca bir kaynak üstünlüğüne
              (<code>qs</code> parametresi) sahip olabilir.</td>
          </tr>
    
          <tr valign="top">
            <td>Dil</td>
    
            <td>Tarayıcı dil tercihlerini <code>Accept-Language</code> başlık
              alanı ile belirtir. Her öğenin kendine özgü bir üstünlük katsayısı
              olabilir. Gösterimler bir kaç dilde olabileceği gibi hiç bir dille
              ilişkilendirimemiş de olabilir.</td>
          </tr>
    
          <tr valign="top">
            <td>Kodlama</td>
    
            <td>Tarayıcı kodlama tercihlerini <code>Accept-Encoding</code> başlık
              alanı ile belirtir. Her öğenin kendine özgü bir üstünlük katsayısı
              olabilir.</td>
          </tr>
    
          <tr valign="top">
            <td>Karakter Kümesi</td>
    
            <td>Tarayıcı karakter kümesi tercihlerini <code>Accept-Charset</code>
              başlık alanı ile belirtir. Her öğenin kendine özgü bir üstünlük
              katsayısı olabilir. Gösterim çeşitleri karakter kümesini ortam
              türünün bir parametresi olarak belirtebilirler.</td>
          </tr>
        </table>
      
    
      <h3><a name="algorithm" id="algorithm">httpd Uzlaşım Algoritması</a></h3>
    
        <p>httpd, tarayıcıya döndürülecek en uygun gösterim çeşidini (varsa)
          seçmek için aşağıdaki algoritmayı kullanabilir. Bu algoritma pek de
          yapılandırılabilir değildir. Şöyle çalışır:</p>
    
        <ol>
          <li>Önce her uzlaşım boyutu için ilgili <em>Accept*</em> başlık alanına
            bakılıp her gösterim çeşidine bir üstünlük katsayısı atanır. Eğer
            boyutlardan bazıları için ilgili <em>Accept*</em> başlığı
            uygulanabilir değilse bu boyut elenir ve sonuçta hiçbir gösterim
            çeşidi kalmasza 4. adıma atlanır.</li>
    
          <li>‘En uygun’ gösterim çeşidi bir eleme süreciyle seçilir. Bu süreç
            sırasında aşağıdaki sınamalar sırayla uygulanır. Sınamalardan
            geçemeyen bir gösterim çeşidi elenir.  Sınamaların bir aşamasında tek
            bir gösterim çeşidi kalırsa bu en uygun eşleşme olarak seçilmiş olur
            ve 3. adıma atlanır. Eğer birden fazla gösterim çeşidi kalırsa sonraki
            sınamaya geçilir.
    
            <ol>
              <li><code>Accept</code> başlığındaki üstünlük katsayısı ile
                gösterimin ortam türünde belirtilen kaynak üstünlüğünün çarpımı en
                büyük olan gösterim çeşidi seçilir.</li>
    
              <li>En yüksek dil üstünlük katsayısına sahip gösterim çeşidi seçilir.
              </li>
    
              <li>En uygun dil eşleşmesine sahip gösterim çeşidini seçmek için
                önce varsa <code>Accept-Language</code> başlığındaki dil
                sıralamasına bakılır, aksi takdirde <code>LanguagePriority</code>
                yönergesi ile atanmışsa oradaki dil sıralamasına bakılır.</li>
    
              <li>En yüksek ‘seviyeden’ ortam parametresine (text/html ortam türü
                sürümünü belirtmekte kullanılır) sahip gösterim çeşitleri
                seçilir.</li>
    
              <li><code>Accept-Charset</code> başlık satırında belirtilene bakarak
                en uygun karakter kümesine sahip gösterim çeşitleri seçilir.
                Alenen dışlanmadıkça ISO-8859-1 kabul edilebilir karakter
                kümesidir. <code>text/*</code> ortam türüne sahip gösterim
                çeşitlerinden belli bir karakter kümesi ile ilişkilendirilmemiş
                olanların karakter kümesinin ISO-8859-1 olduğu varsayılır.</li>
    
              <li>ISO-8859-1 karakter kümesi ile ilişkilendirilmemiş gösterim
                çeşitleri seçilir. Böyle hiçbir gösterim yoksa bütün gösterimler
                seçilir.</li>
    
              <li>En uygun kodlamaya sahip gösterim çeşitleri seçilir. Tarayıcı
                tarafından kabul edilebilir kodlamaya sahip gösterim çeşitleri
                varsa bunlar seçilir. Yoksa kodlanmış ve kodlanmamış gösterim
                çeşitleri karışık olarak mevcutsa sadece kodlanmamış olanlar
                seçilir. Eğer bütün gösterim çeşitlerinin sadece kodlanmış ya da
                sadece kodlanmamış gösterimleri mevcutsa hepsi seçilir.</li>
    
              <li>En küçük içerik uzunluğuna sahip gösterim çeşitleri seçilir.</li>
    
              <li>Kalan gösterim çeşitlerinin ilki seçilir. Bu ilk, ya türeşlem
                dosyasında listelenen ilk çeşittir ya da gösterimler bir dizinden
                okunuyorsa ASCII kod sıralamasına göre ilk sıradaki dosya ismine
                sahip gösterimdir.</li>
            </ol>
          </li>
    
          <li>Algoritma, artık seçilmiş en uygun gösterim çeşidine sahipse bu
            artık yanıt olarak döndürülebilir. HTTP yanıt başlığı
            <code>Vary</code>’ye uzlaşım boyutları atanır (tarayıcı ve
            arabellekler özkaynağı kaydederken bu bilgiyi kullanırlar)
            ve algoritma sonlandırılır.</li>
    
          <li>Buraya gelinmişse hiçbir gösterim seçilmemiş demektir (hiçbiri
            tarayıcı tarafından kabul edilebilir bulunmadığından dolayı).
            Gövdesinde mevcut gösterim çeşitlerini listeleyen bir HTML belgesi 406
            durum koduyla döndürülür (406: ‘kabul edilebilir bir gösterim yok’).
            Ayrıca HTTP <code>Vary</code> başlığında gösterim çeşitliliğinin
            boyutları belirtilir.</li>
        </ol>
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="better" id="better">Üstünlük Değerleriyle Oynamak</a></h2>
    
        <p>httpd bazen yukarıdaki httpd uzlaşım algoritmasının kesin sonucunun
          beklenenden farklı olması için üstünlük değerleriyle oynar. Bunu tam ve
          doğru bilgi göndermeyen tarayıcılar için algoritmadan en iyi sonucu elde
          etmek amacıyla yapar. Bazen günümüzün en tanınmış tarayıcıları bile çoğu
          durumda yanlış bir seçimle sonuçlanmayacaksa <code>Accept</code> başlık
          bilgilerini göndermemektedir. Eğer tarayıcı eksiksiz ve doğru bilgi
          gönderirse httpd bu değerlerle oynamayacaktır.</p>
    
      <h3><a name="wildcards" id="wildcards">Ortam Türleri ve Dosyaismi Kalıpları</a></h3>
    
        <p><code>Accept:</code> istek başlığı ortam türü tercihlerini yansıtır.
          Ayrıca, * bir dizge ile eşleşmek üzere "image/*" veya  "*/*" gibi ortam
          türü kalıpları da içerebilir. Dolayısıyla şöyle bir istek,</p>
    
        <div class="example"><p><code>Accept: image/*, */*</code></p></div>
    
        <p>diğer türler gibi "image/" ile başlayan ortam türlerini kabul
          edilebilir kılacaktır. Bazı tarayıcılar ortam türlerini örtük olarak
          elde etmek amacıyla hep bu tür kalıplar gönderirler. Örnek:</p>
    
        <div class="example"><p><code>
          Accept: text/html, text/plain, image/gif, image/jpeg, */*
        </code></p></div>
    
        <p>Bunun amacı, açıkça listelenmiş türlerin tercih edildiğini, fakat
          farklı gösterimler varsa onların da kabul edilebileceğini belirtmektir.
          Üstünlük değerlerini doğrudan kullanarak tarayıcılar gerçekte ne
          istediklerini şuna benzer şekilde belirtebilirler:</p>
    
        <div class="example"><p><code>
          Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
        </code></p></div>
    
        <p>Açıkça belirtilen türler için üstünlük katsayısı belirtilmemiştir,
          dolayısıyla üstünlük katsayılarının 1.0 (en yüksek) olduğu
          varsayılmaktadır. */* kalıbı 0.01 gibi çok daha düşük bir öncelik
          belirtmektedir. Bu bakımdan, ancak, açıkça belirtilen türlerden
          hiçbirinin bulunmaması halinde diğer türler eşleşecektir.</p>
    
        <p>Eğer <code>Accept:</code> başlığı <em>hiçbir</em> <code>q</code>
          katsayısı içermiyorsa ve başlıkta "*/*" belirtilmişse, httpd istenen
          davranışı taklit etmek için bu kalıba 0.01 katsayısını atar. Keza
          "type/*" kalıbına da 0.02 katsayısını atar (yani, */* kalıbına göre
          tercihli olur). Eğer  <code>Accept:</code> alanındaki her ortam türü bir
          <code>q</code> katsayısı içeriyorsa bu özel değerler uygulanmaz.
          Dolayısıyla gerekli bilgiyi açıkça bildiren tarayıcılardan gelen
          istekler umulduğu gibi işlem görecektir.</p>
      
    
      <h3><a name="exceptions" id="exceptions">Dil Uzlaşımında İstisnalar</a></h3>
    
        <p>httpd 2.0’dan itibaren, uzlaşım algoritmasına, bir eşleşme bulmak
          konusunda algoritma başarılı olamadığı takdirde hoş bir son çareye izin
          vermek için bazı istisnalar eklenmiştir.</p>
    
        <p>İstemci sunucudan bir sayfa istediğinde, sunucu, tarayıcı tarafından
          gönderilen <code>Accept-language</code> başlığıyla eşleşen tek bir sayfa
          bulamadığı takdirde istemciye ya “Kabul edilebilir bir gösterim çeşidi
          yok” ya da “Çok sayıda seçim belirtilmiş” yanıtını döndürür. Bu hata
          iletilerinden kaçınmak için bu gibi durumlarda httpd
          <code>Accept-language</code> başlığını yoksaymaya ayarlanabilir. Böylece
          istemcinin isteğine tam olarak uymasa da bir belge sağlanır. Bu hata
          iletilerinin birini veya her ikisini de geçersiz kılmak için <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code> yönergesi
          kullanılabilir ve sunucunun kararını <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code> yönergesine
          dayanarak vermesi sağlanabilir.</p>
    
        <p>Sunucu ayrıca, tam bir eşleşme bulunmadığı zaman lehçelerle de eşleşme
          arayabilir. Örneğin, bir istemci Britanya İngilizcesi
          (<code>en-GB</code>) ile yazılmış belgeler için istekte bulunursa,
          sunucu normalde HTTP/1.1 standardına göre bir belgenin basitçe
          <code>en</code> olarak imlenmesine izin vermez. (Bir okuyucu Britanya
          İngilizcesini anlıyor ama genel İngilizceyi anlamıyor diye
          <code>Accept-Language</code> başlığında <code>en</code>  değil de
          <code>en-GB</code>’yi belirtmesinin hemen hemen daima bir yapılandırma
          hatasına yol açacağına dikkat ediniz. Maalesef, mevcut istemcilerin çoğu
          öntanımlı yapılandırmalarında buna benzer şeyler yapmaktadır.) Bununla
          birlikte, başka bir dille eşleşme mümkün değilse ve sunucu “Kabul
          edilebilir bir gösterim çeşidi yok” hatasını döndürmeye hazırsa veya
          <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code> son
          çaresine ayarlanmışsa alt küme belirtimini yok sayacak ve
          <code>en</code> belge isteklerine <code>en-GB</code> belgelerle yanıt
          verecektir. httpd, lehçenin üyesi olduğu anadili, istemcinin kabul
          edilebilir diller listesine örtük olarak düşük bir üstünlük değeri ile
          ekler. Yalnız şuna dikkat edin, eğer istemci tercihini "en-GB; q=0.9,
          fr; q=0.8" olarak belirtirse ve sunucuda sadece "en" ve "fr" belgeleri
          varsa sunucu "fr" belge ile yanıt verecektir. HTTP/1.1 belirtimi ile
          uyumluluğu sağlamak ve düzgün yapılandırılmış istemcilerle gerektiği
          gibi çalışabilmek için bu gereklidir.</p>
    
        <p>Gelişmiş tekniklerin (çerezler, özel URL yolları gibi) desteklenmesi
          sırasında, kullanıcının tercih ettiği dili saptamak için httpd 2.0.47
          sürümünden beri <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> modülü
          <code>prefer-language</code> <a href="env.html">ortam değişkenini</a>
          tanımaktadır. Değişken mevcutsa ve uygun bir dil yaftası içeriyorsa
          <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> uygun gösterimi seçmeyi deneyecektir.
          Böyle bir gösterim çeşidi mevcut değilse normal uzlaşım işlemi
          uygulanacaktır.</p>
    
        <div class="example"><h3>Örnek</h3><pre class="prettyprint lang-config">SetEnvIf Cookie "language=(.+)" prefer-language=$1
    Header append Vary cookie</pre>
    </div>
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extensions" id="extensions">Şeffaf İçerik Uzlaşımının Genişletilmesi</a></h2>
      
    
      <p>httpd, şeffaf içerik uzlaşımı protokolünü (RFC 2295) şöyle genişletir:
        Sadece içerik kodlamasına özgü olmak üzere gösterim çeşidi listelerinde
        gösterim çeşitlerini imlemek için yeni bir <code>{encoding ..}</code>
        elemanı kullanılır. RVSA/1.0 algoritmasının (RFC 2296) gerçeklenimi,
        listedeki kodlanmış gösterim çeşitlerini tanımak ve onları
        <code>Accept-Encoding</code> başlık alanıyla ilgili olarak kabul
        edilebilir kodlamalara aday gösterim çeşitleri olarak kullanmak üzere
        genişletilmiştir. RVSA/1.0 gerçeklenimi, en uygun gösterim çeşidi
        seçiminin öncesinde hesaplanmış üstünlük katsayısını virgülden sonra beş
        haneye yuvarlamaz.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="naming" id="naming">Hiperbağlar ve İsimlendirme Uzlaşımları</a></h2>
    
        <p>Eğer dil uzlaşımı kullanıyorsanız ve birden fazla dosya ismi uzantısına
          sahip dosyalarınız varsa uzantıların sıralamasının normalde uygunsuz
          düştüğü farklı isimlendirme yaklaşımlarında bulunabilirsiniz (ayrıntılar
          için <a href="mod/mod_mime.html#multipleext">mod_mime</a> belgesine
          bakınız).</p>
    
        <p>Bir MIME türü uzantısına sahip bir dosyanın (<code>html</code> gibi),
          kodlanmış bir gösterimi (<code>gz</code> gibi) mevcut olabilir. Bu
          dosyanın ayrıca farklı dillerdeki gösterimleri için de bir uzantısı
          (<code>en</code> gibi) olabilir.</p>
    
        <p>Örnekler:</p>
    
        <ul>
          <li>misal.en.html</li>
    
          <li>misal.html.en</li>
    
          <li>misal.en.html.gz</li>
        </ul>
    
        <p>Hiperbağ olarak geçerli ve geçersiz bazı dosya ismi örnekleri:</p>
    
        <table class="bordered">
          
          <tr>
            <th>Dosya ismi</th>
    
            <th>Geçerli Hiperbağ</th>
    
            <th>Geçersiz Hiperbağ</th>
          </tr>
    
          <tr>
            <td><em>misal.html.en</em></td>
    
            <td>misal<br />
             misal.html</td>
    
            <td>-</td>
          </tr>
    
          <tr>
            <td><em>misal.en.html</em></td>
    
            <td>misal</td>
    
            <td>misal.html</td>
          </tr>
    
          <tr>
            <td><em>misal.html.en.gz</em></td>
    
            <td>misal<br />
             misal.html</td>
    
            <td>misal.gz<br />
             misal.html.gz</td>
          </tr>
    
          <tr>
            <td><em>misal.en.html.gz</em></td>
    
            <td>misal</td>
    
            <td>misal.html<br />
             misal.html.gz<br />
             misal.gz</td>
          </tr>
    
          <tr>
            <td><em>misal.gz.html.en</em></td>
    
            <td>misal<br />
             misal.gz<br />
             misal.gz.html</td>
    
            <td>misal.html</td>
          </tr>
    
          <tr>
            <td><em>misal.html.gz.en</em></td>
    
            <td>misal<br />
             misal.html<br />
             misal.html.gz</td>
    
            <td>misal.gz</td>
          </tr>
        </table>
    
        <p>Yukarıdaki tabloya bakarak hiperbağlarda bir dosya ismini uzantısız
          olarak (<code>misal</code> gibi) kullanmanın daima mümkün olduğunu
          farkedeceksiniz. Böylece bir belgenin asıl türünü gizleyebilir ve
          sonradan bir hiperbağ değişikliği yapmaksızın örneğin
          <code>html</code>’den <code>shtml</code> veya <code>cgi</code>’ye
          geçebilirsiniz.</p>
    
        <p>Hiperbağlarda MIME türlerini (<code>misal.html</code> gibi) kullanmaya
          devam etmek istiyorsanız dil uzantısı MIME türü uzantısının sağında
          kalmalıdır (<code>misal.html.en</code> gibi).</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="caching" id="caching">Arabellekler Hakkında</a></h2>
    
        <p>Bir arabellek, bir gösterimi istek URL’si ile ilişkilendirerek saklar.
          Böylece, sonradan aynı URL için bir istek yapıldığında kaydettiği
          gösterimi kullanabilir. Fakat özkaynak sunucuyla uzlaşılan türdeyse
          arabelleğe ilk istenen çeşit saklanmış olacağından isteğe yanlış
          gösterimle yanıt verilmiş olacaktır. Bunun olmaması için httpd, normal
          olarak içerik uzlaşımının sonucu olarak döndürülen tüm yanıtları
          HTTP/1.0 istemciler tarafından arabelleklenemez olarak imler. httpd
          ayrıca, uzlaşımlı yanıtların arabelleklenmesini mümkün kılan HTTP/1.1
          protokolünü de destekler.</p>
    
        <p>HTTP/1.0 uyumlu istemcilerden (bir tarayıcı veya arabellek) gelen
          istekler için, uzlaşıma konu yanıtların arabelleklenmesini mümkün kılmak
          üzere <code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code> yönergesi kullanılabilir. Bu yönerge
          argümansızdır ve sunucu genelinde veya sanal konakların
          yapılandırılmasında kullanılabilir. Bunun HTTP/1.1 istemcilerinden gelen
          isteklere bir etkisi yoktur.</p>
    
        <p>HTTP/1.1 istemciler için, httpd, yanıtın uzlaşım boyutlarını göstermek
          üzere bir <code>Vary</code> HTTP yanıt başlığı gönderir. Arabellekler bu
          bilgiyi sonraki istekleri yerel kopyadan sunarken kullanabilirler. Bir
          arabelleğin uzlaşım boyutlarına bakmaksızın yerel kopyasını kullanmaya
          teşvik etmek için <code>force-no-vary</code> <a href="env.html#special">ortam değişkenini</a> etkin kılabilirsiniz.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/content-negotiation.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/mpm.html�������������������������������������������������������������������0000664�0001751�0001751�00000001300�13710016232�016473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: mpm.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: mpm.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: mpm.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: mpm.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: mpm.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: mpm.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/custom-error.html.tr.utf8��������������������������������������������������0000664�0001751�0001751�00000034256�14743132254�021706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Hata Yanıtlarının Kişiselleştirilmesi - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Hata Yanıtlarının Kişiselleştirilmesi</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Apache HTTP Sunucusu 4xx veya 5xx HTTP durum kodları ile ilgili
          olaylarda soysal hata yanıtları üretse de bu yanıtlar site
          kullanıcılarına aşırı sade, bilgi vermez ve hatta korkutucu gelebilir.
          Daha dostça yazılmış, İngilizce değil de kendi dilinizde ve belki
          sayfalarınızın yerleşimine uygun daha hoş satırlarda özel hata yanıtları
          üretmek isteyebilirsiniz.</p>
    
        <p>Kişiselleştirilmiş hata yanıtları, bir hata durumuna göre tasarlanmış
          herhangi bir HTTP durum kodu (yani 4xx ve 5xx kodlarından biri) için
          tanımlanabilir.</p>
    
        <p>Ek olarak bir değer kümesi de sağlanmıştır. Böylece hata belgeleri, <a href="howto/ssi.html">Sunucu taraflı İçerik Yerleştirme</a> kullanılarak
          bu değişkenlerin değerlerine göre özelleştirilebilir. İsterseniz bunun
          yerine bir CGI programı veya devingen bir eylemci (PHP, mod_perl, vs.)
          kullanarak da bu değişkenlerin değerlerine göre hata sayfalarınızı
          üretebilirsiniz.</p>
    
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#configuration">Yapılandırma</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#variables">Kullanılabilen Değişkenler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#custom">Özel Hata Yanıtları</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#multi-lang">Çok Dilli Özel Hata Belgeleri</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Yapılandırma</a></h2>
    
        <p>Kişiselleştirilmiş hata belgeleri <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> yönergesi kullanılarak yapılandırılabilir. Bu
          yönerge küresel bağlamda olabileceği gibi sanal konak ve dizin
          bağlamlarında da kullanılabilir. <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> yönergesine <code>FileInfo</code>
          atanarak <code>.htaccess</code> dosyalarında da kullanılabilir.</p>
    
        <pre class="prettyprint lang-config">ErrorDocument 500 "Pardon, galiba bizim betik hata verdi."
    ErrorDocument 500 /cgi-bin/hata-kurtarma
    ErrorDocument 500 http://error.example.com/server_error.html
    ErrorDocument 404 /ozuru_kabahatinden_buyuk/yok.html
    ErrorDocument 401 /Uyeler/NASIL_uye_olunur.html</pre>
    
    
        <p><code>ErrorDocument</code> yönergesinin sözdizimi:</p>
    
        <pre class="prettyprint lang-config">ErrorDocument &lt;3-rakamlı-kod&gt; &lt;eylem&gt;</pre>
    
    
        <p><var>eylem</var> şunlardan biri olabilir:</p>
    
        <ol>
          <li>Yönlendirmenin yapılacağı dahili adres (<var>eylem</var> bir "/" ile
            başlıyorsa).</li>
          <li>Yönlendirmenin yapılacağı harici adres (<var>eylem</var> geçerli bir
            URL ise).</li>
          <li>Gösterilecek metin (yukardakilerin hiçbiri yoksa). Birden fazla
            sözcük içeriyorsa tırnak (") içine alınmalıdır.</li>
        </ol>
    
        <p>Yerel bir adrese yönlendirme yapılırken ek ortam değişkenleri de
          atanarak yanıt daha da özelleştirilebilir. Bunlar harici URL'lere
          gönderilmez.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="variables" id="variables">Kullanılabilen Değişkenler</a></h2>
    
          <p>Hata durumunu açıklayacak veya hata günlüğüne daha açıkça
            kaydedilebilecek bazı bilgilerin aktarılması koşuluyla, başka bir
            adrese yönlendirme kullanışlı olabilir</p>
    
          <p>Hata yönlendirmesi yapılırken bunu sağlamak için ek ortam değişkenleri
            tanımlanır. Bu değişkenlerin isimleri, özgün istekle sağlanan
            başlık isimlerinin  önüne 'REDIRECT_' dizgesi getirilerek üretilir.
            Böylece özgün istek bağlamından hata belgesi üretilebilir.</p>
    
          <p>Örneğin, aşağıdaki gibi, daha yararlı olacak ek ortam değişkenleri
            alabilirsiniz.</p>
    
          <div class="example"><p><code>
            REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/jpeg, image/png<br />
            REDIRECT_HTTP_USER_AGENT=Mozilla/5.0 Fedora/3.5.8-1.fc12 Firefox/3.5.8<br />
            REDIRECT_PATH=.:/bin:/usr/local/bin:/sbin<br />
            REDIRECT_QUERY_STRING=<br />
            REDIRECT_REMOTE_ADDR=121.345.78.123<br />
            REDIRECT_REMOTE_HOST=client.example.com<br />
            REDIRECT_SERVER_NAME=www.example.edu<br />
            REDIRECT_SERVER_PORT=80<br />
            REDIRECT_SERVER_SOFTWARE=Apache/2.2.15<br />
            REDIRECT_URL=/cgi-bin/buggy.pl
          </code></p></div>
    
          <p><code>REDIRECT_</code> ortam değişkenleri, yönlendirme öncesi varolan
            ortam değişkenlerinden üretilir. Bunlar önlerine <code>REDIRECT_</code>
            getirilerek yeniden isimlendirilir. Örneğin,
            <code>HTTP_USER_AGENT</code> değişkeni
            <code>REDIRECT_HTTP_USER_AGENT</code> haline gelir.</p>
    
          <p><code>REDIRECT_URL</code>, <code>REDIRECT_STATUS</code> ve
            <code>REDIRECT_QUERY_STRING</code> mutlaka atanır. Diğer başlıklarla
            ilgili olanlar ise hata durumu öncesinde mevcut oldukları takdirde
            üretilirler.</p>
    
          <p>Eğer <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> hedefi bir
            <em>harici</em> yönlendirme ise bunların <strong>hiçbiri</strong>
            üretilmez (sunucunun bulunduğu konağı hedeflese bile <code>http:</code>
            ile başlayan herşey harici yönlendirme sayılır).</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="custom" id="custom">Özel Hata Yanıtları</a></h2>
    
          <p>Hata yanıtınızı üretmek için sunucu taraflı içerik yerleştirme, bir
            CGI betiği veya başka bir eylemciyi devingen eylemci olarak
            kullanıyorsanız, bu yanıtı özelleştirmek için bu kullanıma özel
            üretilmiş ortam değişkenlerini kullanmak isteyebilirsiniz.</p>
    
          <p><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> yönergesi bir CGI
            betiğine bir yerel yönlendirme belirtiyorsa, hatanın kaynağı hakkında
            istemciye bilgi vermek amacıyla betiğin çıktısında bir
            "<code>Status:</code>" başlık alanına yer verilmelidir. Örneğin, bir
            Perl betiği şunları içerebilirdi:</p>
    
          <pre class="prettyprint lang-perl">...
    print  "Content-type: text/html\n";
    printf "Status: %s durumu saptandı.\n", $ENV{"REDIRECT_STATUS"};
    ...</pre>
    
    
          <p>Eğer betik, <code>404&nbsp;Not&nbsp;Found</code> gibi, belli bir hata
            durumunu ele almaya adanmışsa duruma özel kod ve hata metni
            kullanılabilir.</p>
    
          <p>Eğer yanıt, (istemci taraflı yönlendirme yapılırken) bir
            <code>Location:</code> başlığı da içeriyorsa betiğin çıktıya uygun bir
            <code>Status:</code> başlığı (<code>302&nbsp;Found</code>) eklemesinin
            gerekli oluşuna dikkat ediniz. Aksi takdirde, <code>Location:</code>
            başlığı etkisiz olabilir.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multi-lang" id="multi-lang">Çok Dilli Özel Hata Belgeleri</a></h2>
    
        <p>Apache HTTP Sunucusunun kurulumunda, 16 dile çevrilmiş özel hata
          iletileri belgeleri içeren bir dizin bulunmaktadır. Ayrıca,
          <code>conf/extra</code> yaplandırma dizininde bu özelliği etkin kılmak
          için yapılandırmaya dahil edilebilecek bir yapılandırma dosyası
          vardır.</p>
    
        <p>Sunucu yapılandırma dosyanızda şöyle satırlar görebilirsiniz:</p>
    
        <pre class="prettyprint lang-config"># Multi-language error messages
    #Include conf/extra/httpd-multilang-errordoc.conf</pre>
    
    
        <p>Bu <code>Include</code> satırını açıklama olmaktan çıkarırsanız
          bu özelliği etkinleştirmiş olursunuz. Böylece, istemcinin tarayıcısında
          belirtilmiş dil tercihine uygun dil uzlaşımlı hata iletileri
          sağlanır.</p>
    
        <p>Ek olarak, bu belgeler çeşitli <code>REDIRECT_</code> değişkenleri
          içerir. Böylece, son kullanıcıya neler olduğu ve şimdi ne yapması
          beklendiği hakkında ek bilgiler sağlanabilir.</p>
    
        <p>Bu belgeleri istediğiniz kadar özelleştirebilir, kullanıcıya siteniz
          hakkında ve orada bulabilecekleri şeylere dair faydalı bilgiler de
          sağlayabilirsiniz.</p>
    
        <p>Bu özelliği kullanmak için <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> ve
          <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> etkin kılınmalıdır.</p>
    
     </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/custom-error.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html.zh-cn.utf8����������������������������������������������������0000664�0001751�0001751�00000026533�14743132254�021253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache 的处理器 - Apache HTTP 服务器 版本 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="./">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache 的处理器</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
        <p>本页描述 Apache 处理器的用法。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#definition">什么是处理器</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">例子</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programmer">对程序员的说明</a></li>
    </ul><h3>参见</h3><ul class="seealso"><li><a href="#comments_section">评论</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definition" id="definition">什么是处理器</a></h2>
        
        <table class="related"><tr><th>相关模块</th><th>相关指令</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></li><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removehandler">RemoveHandler</a></code></li><li><code class="directive"><a href="./mod/core.html#sethandler">SetHandler</a></code></li></ul></td></tr></table>
    
    
        <p>“处理器”是当文件被调用时,Apache 要执行的动作的内部表示形式。
        一般来说,每个文件都有基于其文件类型的隐式处理器。通常的文件会被
        服务器简单处理,但是某些文件类型会被分别“处理”。</p>
    
        <p>处理器也可以被基于扩展名或位置来明确配置。它们都很有用,这不仅
        因为它是优雅的方案,而且还允许类型<strong>与</strong>处理器关联到文件
        (参见<a href="mod/mod_mime.html#multipleext">文件与多个扩展名</a>)。</p>
    
        <p>处理器可以编译到服务器中,或者包含在模块中,它们还可以被 <code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code> 指令增加。标准发行版中内置的处理器有:</p>
    
        <ul>
          <li><strong>default-handler</strong>: 使用
          <code>default_handler()</code> 发送文件,它是用来处理静态内容的处理器(核心)。</li>
    
          <li><strong>send-as-is</strong>: 直接发送,不增加 HTTP 头(<code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code>)。</li>
    
          <li><strong>cgi-script</strong>: 按 CGI 脚本处理(<code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>)。</li>
    
          <li><strong>imap-file</strong>: 按 imagemap 规则处理(<code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code>)。</li>
    
          <li><strong>server-info</strong>: 取得服务器配置信息(<code class="module"><a href="./mod/mod_info.html">mod_info</a></code>)。</li>
    
          <li><strong>server-status</strong>: 取得服务器状态报告(<code class="module"><a href="./mod/mod_status.html">mod_status</a></code>)。</li>
    
          <li><strong>type-map</strong>: 用于内容协商,按类型映射文件处理(<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>)。</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">例子</a></h2>
        
    
        <h3><a name="example1" id="example1">使用 CGI 脚本修改静态内容</a></h3>
          
    
          <p>下面的指令将会使具有<code>html</code>扩展名的文件,触发 CGI 脚本<code>footer.pl</code>的执行。</p>
    
          <div class="example"><p><code>
            Action add-footer /cgi-bin/footer.pl<br />
            AddHandler add-footer .html
          </code></p></div>
    
          <p>于是 CGI 负责发送请求的文档(<code>PATH_TRANSLATED</code> 环境变量指向它),按照需要作出  and making
          whatever modifications or additions are desired.</p>
    
        
        <h3><a name="example2" id="example2">含有 HTTP 头的文件</a></h3>
          
    
          <p>下面的指令会启用
          <code>send-as-is</code> 处理器,用于包含自己的 HTTP 的文件。不管什么扩展名,
          所有位于 <code>/web/htdocs/asis/</code> 目录的文件会被
          <code>send-as-is</code> 处理器处理。</p>
    
          <div class="example"><p><code>
            &lt;Directory /web/htdocs/asis&gt;<br />
            SetHandler send-as-is<br />
            &lt;/Directory&gt;
          </code></p></div>
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programmer" id="programmer">对程序员的说明</a></h2>
        
    
        <p>为了实现处理器特性,增加了需要使用的 <a href="developer/API.html">Apache API</a>。
        特别的,结构 <code>request_rec</code> 增加了新成员:</p>
    
        <div class="example"><p><code>
          char *handler
        </code></p></div>
    
        <p>如果你想要模块实现处理器,只需要在在处理请求,调用 <code>invoke_handler</code>
        之前,将 <code>r-&gt;handler</code> 指向处理器名称。处理器的实现与以前一样,只是用处理器名称取代了内容类型。
        虽然不是必要,处理器的命名约定是使用破折号分割的单词,没有斜杠,从而不侵入媒体类型名称空间。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">评论</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/handler.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html.tr.utf8�������������������������������������������������������0000664�0001751�0001751�00000030622�14743132254�020653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache Eylemcilerinin Kullanımı - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache Eylemcilerinin Kullanımı</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>Bu belgede Apache Eylemcilerinin kullanımı açıklanmıştır.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#definition">Eylemci Nedir?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Örnekler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programmer">Yazılım Geliştirenler İçin</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definition" id="definition">Eylemci Nedir?</a></h2>
        
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></li><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removehandler">RemoveHandler</a></code></li><li><code class="directive"><a href="./mod/core.html#sethandler">SetHandler</a></code></li></ul></td></tr></table>
    
    
        <p>Bir <em>eylemci</em> bir dosya çağrıldığında uygulanacak eylemin Apache
          dahilindeki gösterimidir. Genellikle dosyaların kendi türüne bağlı
          olarak örtük eylemcileri vardır. Normalde tüm dosyalar basitçe sunucu
          tarafından sunulurlar, fakat bazı dosya türleri normalden farklı şekilde
          ele alınırlar.</p>
    
        <p>Eylemciler, dosya türünden bağımsız olarak dosyanın bulunduğu yere veya
          dosya ismi uzantısına göre de yapılandırılabilirler. Gerek, zarif bir
          çözüm oluşuyla gerekse, hem dosya türünü hem de bir dosya ile ilişkili
          bir eylemciyi mümkün kılması sebebiyle bunun getirisi daha yüksektir.
          (Ayrıca, <a href="mod/mod_mime.html#multipleext">çok uzantılı
          dosyalara</a> da bakınız.)</p>
    
        <p>Eylemciler sunucu içinde derlenebileceği gibi bir modül olarak ya da
          <code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code> yönergesi ile de
          sunucuya dahil edilebilirler. Standart dağıtımda bulunan yerleşik
          eylemciler şunlardır:</p>
    
        <ul>
          <li><strong>default-handler</strong>: Dosyayı, öntanımlı olarak durağan
            içeriği işlemekte kullanılan <code>default_handler()</code> işlevini
            kullanarak gönderir. (<code class="module"><a href="./mod/core.html">core</a></code>)</li>
    
          <li><strong>send-as-is</strong>: Dosyayı HTTP başlıklarıyla olduğu gibi
            gönderir. (<code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code>)</li>
    
          <li><strong>cgi-script</strong>: Dosyayı bir CGI betiği olarak ele alır.
            (<code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>)</li>
    
          <li><strong>imap-file</strong>: Dosyayı bir resim eşleme kuralları
            dosyası olarak çözümler. (<code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code>)</li>
    
          <li><strong>server-info</strong>: Sunucunun yapılandırma bilgisini
            döndürür. (<code class="module"><a href="./mod/mod_info.html">mod_info</a></code>)</li>
    
          <li><strong>server-status</strong>: Sunucunun durum raporunu döndürür.
            (<code class="module"><a href="./mod/mod_status.html">mod_status</a></code>)</li>
    
          <li><strong>type-map</strong>: Dosyayı içerik uzlaşımı için bir tür
            eşlem dosyası olarak çözümler. (<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>)</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Örnekler</a></h2>
        
    
        <h3><a name="example1" id="example1">Bir CGI betiği kullanarak durağan içeriğin değiştirilmesi</a></h3>
          
    
          <p>Aşağıdaki yönergeler sayesinde, <code>html</code> uzantılı dosyalar
            için yapılan istekler <code>footer.pl</code> CGI betiğininin
            çalıştırılmasına sebep olacaktır.</p>
    
          <pre class="prettyprint lang-config">Action add-footer /cgi-bin/footer.pl
    AddHandler add-footer .html</pre>
    
    
          <p>Bu yapılandırmayla, istenen belgenin özgün haliyle mi (yeri
            <code>PATH_TRANSLATED</code> ortam değişkenindedir) yoksa istenen
            değişiklikler veya eklemeler yapıldıktan sonra mı gönderileceğinden
            CGI betiği sorumlu olacaktır.</p>
    
        
        <h3><a name="example2" id="example2">HTTP başlıklı dosyalar</a></h3>
          
    
          <p>Aşağıdaki yönergeler kendi HTTP başlıklarını içeren dosyalar için
            kullanılan <code>send-as-is</code> eylemcisini etkinleştirmek amacıyla
            kullanılmıştır. <code>/siteler/htdocs/asis/</code> dizinindeki tüm
            dosyalar dosya ismi uzantılarına bakılmaksızın <code>send-as-is</code>
            eylemcisi tarafından işleme sokulacaktır.</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/web/htdocs/asis"&gt;
        SetHandler send-as-is
    &lt;/Directory&gt;</pre>
    
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programmer" id="programmer">Yazılım Geliştirenler İçin</a></h2>
        
    
        <p>Eylemci özellikleri gerçeklenirken kullanılmak üzere <a href="developer/API.html">Apache API</a>’ye bir ekleme yapılmıştır.
          Özellikle de, <code>request_rec</code> yapısına yeni bir kayıt
          eklenmiştir:</p>
    
        <pre class="prettyprint lang-c">char *handler</pre>
    
    
        <p>Modülünüzün bir eylemciyi devreye sokmasını isterseniz, tek yapacağınız
          isteğin <code>invoke_handler</code> aşamasının hemen öncesinde
          <code>r-&gt;handler</code> alanına eylemcinin ismini atamak olacaktır.
          Eylemciler daha önce de bahsedildiği gibi bir içerik türü yerine bir
          eylemci ismi kullanılarak gerçeklenirler. Çok gerekli olmamakla
          birlikte, eylemciler için kullanılan adlandırma uzlaşımları gereğince,
          ismi oluşturan sözcükler, ortam türü isim alanını ihlal etmemek amacıyla
          bölü imleri ile değil tire imleri ile ayrılırlar.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/handler.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/mpm.html.ja.utf8�����������������������������������������������������������0000664�0001751�0001751�00000027320�14743132254�017775� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>マルチプロセッシングモジュール (MPM) - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>マルチプロセッシングモジュール (MPM)</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <p>この文書ではマルチプロセッシングモジュールがどのようなもので、
    Apache HTTP サーバでどのように使用されるかについて解説しています。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">はじめに</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#choosing">MPM を選ぶ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#defaults">MPM デフォルト値</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">はじめに</a></h2>
    
        <p>Apache HTTP サーバは異なる幅広い環境、多種多様なプラットホームで
        動作するように、パワフルで柔軟性に富んだ設計になっています。
        異なるプラットホーム・異なる環境ではしばしば、
        異なる機能が必要になったり、
        同じ機能でも効率のために異なる実装が必要になったりします。
        Apache ではモジュール化された設計により幅広い環境に適応してきました。
        この設計のおかげで、管理者は
        コンパイル時または実行時にどのモジュールをロードするか選ぶことによって、
        どの機能をサーバに取り込むか選択することができます。</p>
    
        <p>Apache 2.0 では、
        このモジュール化された設計をサーバの基本機能にまで拡張しました。
        サーバには精選されたマルチプロセッシングモジュール (MPM) 
        が付いてきて、これらはマシンのネットワークポートをバインドしたり、
        リクエストを受け付けたり、リクエストを扱うよう子プロセスに割り当てたり、
        といった役割を持ちます。</p>
    
        <p>モジュール化された設計をサーバのこのレベルまで拡張することで
        二つの重要な利点が生まれます:</p>
    
        <ul>
          <li>Apache は幅広いオペレーティングシステムを
          より美しく効率的にサポートできます。
          特に Windows 版の Apache は随分効率的になりました。
          なぜなら <code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code>
          によって、Apache 1.3 で用いられていた POSIX 
          レイヤの代わりにネイティブのネットワーク機能を
          利用できるからです。
          特別化された MPM 
          を実装した他のオペレーティングシステムでも、
          同様にこの利点は生まれます。</li>
    
          <li>サーバは特定のサイト向けに、より上手にカスタマイズできます。
          例えば、非常に大きなスケーラビリティを必要とするサイトでは、
          <code class="module"><a href="./mod/worker.html">worker</a></code> や <code class="module"><a href="./mod/event.html">event</a></code> といったスレッド化された
          MPM を利用できる一方で、安定性や古いソフトウェアとの互換性を
          必要とするサイトでは <code class="module"><a href="./mod/prefork.html">prefork</a></code>
          が利用できます。</li>
        </ul>
    
        <p>ユーザレベルでは、MPM は他の Apache 
        モジュールと同等に見えます。
        主な違いは、いつでも唯一の MPM 
        がロードされなければならないという点です。
        利用可能な MPM は 
        <a href="mod/">module インデックス</a>にあります。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="choosing" id="choosing">MPM を選ぶ</a></h2>
    
        <p>MPM は設定中に選択して、サーバ内部にコンパイルされなければ
        なりません。
        コンパイラは、スレッドが使用されている場合に様々な機能を最適化できますが、
        そのためにはそもそもスレッドが使われているということを知る必要があります。</p>
    
        <p>望みの MPM を実際に選ぶためには、<code class="program"><a href="./programs/configure.html">configure</a></code> スクリプトで
        <code>--with-mpm=<em>NAME</em></code> 引数を用いてください。
        <em>NAME</em> は望みの MPM の名前です。</p>
    
        <p>サーバコンパイル後は、どの MPM が選択されたかを
        <code>./httpd -l</code> で確かめることができます。
        このコマンドは、MPM
        を含め、サーバにコンパイルで組み込まれたモジュール全てを
        列挙します。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="defaults" id="defaults">MPM デフォルト値</a></h2>
    
    <p>次表に様々な OS 向けのデフォルトの MPM 一覧を掲載しています。
    コンパイル時に意図的に他を選択しなければ、自動的にこれらの MPM
    が選択されます。</p>
    
    <table>
    
    <tr><td>BeOS</td><td><code class="module"><a href="./mod/beos.html">beos</a></code></td></tr>
    <tr><td>Netware</td><td><code class="module"><a href="./mod/mpm_netware.html">mpm_netware</a></code></td></tr>
    <tr><td>OS/2</td><td><code class="module"><a href="./mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
    <tr><td>Unix</td><td><code class="module"><a href="./mod/prefork.html">prefork</a></code></td></tr>
    <tr><td>Windows</td><td><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code></td></tr>
    </table>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/mpm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.ko.euc-kr�������������������������������������������������������0000664�0001751�0001751�00000020350�14743132254�020626� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server Version 2.4  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a></div>
    <div id="page-content"><h1>Apache HTTP Server Version 2.4 </h1>
    <div class="toplang">
    <p><span> : </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Google ˻" type="submit" /><input value="10" name="num" type="hidden" /><input value="ko" name="hl" type="hidden" /><input value="EUC-KR" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Version 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">ǥ</a></h2>
    <ul><li><a href="new_features_2_0.html"> 2.0 ο </a></li>
    <li><a href="upgrading.html">1.3 2.0  ׷̵</a></li>
    <li><a href="license.html">ġ ̼</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual"> </a></h2>
    <ul><li><a href="install.html">ϰ ġ</a></li>
    <li><a href="invoking.html"></a></li>
    <li><a href="stopping.html">ߴܰ </a></li>
    <li><a href="mod/directives.html"> þ</a></li>
    <li><a href="mod/quickreference.html">þ </a></li>
    <li><a href="mod/"></a></li>
    <li><a href="mpm.html">ó (MPM)</a></li>
    <li><a href="filter.html"></a></li>
    <li><a href="handler.html">ڵ鷯</a></li>
    <li><a href="programs/">  α׷</a></li>
    <li><a href="glossary.html"></a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide"> ħ</a></h2>
    <ul><li><a href="bind.html">ּҿ Ʈ </a></li>
    <li><a href="configuring.html"></a></li>
    <li><a href="sections.html"> </a></li>
    <li><a href="content-negotiation.html"> (content negotiation)</a></li>
    <li><a href="dso.html">ü (DSO)</a></li>
    <li><a href="env.html">ȯ溯</a></li>
    <li><a href="logs.html">α</a></li>
    <li><a href="urlmapping.html">URL Ͻýۿ </a></li>
    <li><a href="misc/perf-tuning.html"></a></li>
    <li><a href="misc/security_tips.html"> </a></li>
    <li><a href="server-wide.html">  </a></li>
    <li><a href="ssl/">SSL/TLS ȣȭ</a></li>
    <li><a href="suexec.html">CGI Suexec </a></li>
    <li><a href="rewrite/">URL ۼ(rewriting) ħ</a></li>
    <li><a href="vhosts/">ȣƮ</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">How-To / 丮</a></h2>
    <ul><li><a href="howto/auth.html">, Ѻο,
        </a></li>
    <li><a href="howto/cgi.html">CGI:   </a></li>
    <li><a href="howto/htaccess.html">.htaccess </a></li>
    <li><a href="howto/ssi.html">Server Side Includes (SSI)</a></li>
    <li><a href="howto/public_html.html">ں 丮
        (public_html)</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">÷ </a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC </a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">ٸ </a></h2>
    <ul><li><a href="faq/">   (FAQ)</a></li>
    <li><a href="sitemap.html">Ʈ</a></li>
    <li><a href="developer/">ڸ  </a></li>
    <li><a href="misc/">Ÿ</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html.ko.euc-kr����������������������������������������������������0000664�0001751�0001751�00000025571�14743132254�021355� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ġ </h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p> ġ Windows NT, 2000, XP 񽺷,
        Windows 95 ME ܼ α׷ ȴ. ڼ
         <a href="platform/windows.html#winsvc">񽺷
        ġ ϱ</a> <a href="platform/windows.html#wincons">ܼ α׷
        ġ ϱ</a>.</p>
    
        <p>н <a href="programs/httpd.html">httpd</a>
        α׷ ׶忡  û óϴ 
        ȴ.   <code>httpd</code> ϴ 
        Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#startup"> ġ ϳ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errors"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#boot">Ҷ ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#info">߰ </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="stopping.html">ġ ߴܰ </a></li><li><a href="programs/httpd.html">httpd</a></li><li><a href="programs/apachectl.html">apachectl</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="startup" id="startup"> ġ ϳ</a></h2>
    
        <p>Ͽ <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> ⺻ 80(Ȥ
        1024 ٸ Ʈ)̶  Ư Ʈ ϱ
        root  ʿϴ.  Ͽ α  
          ۾ ģ, Ŭ̾Ʈ û ٸ
        ϴ <em>ڽ(child)</em> μ  .
         <code>httpd</code> μ  root ڷ ,
        ڽ μ    ڷ ȴ. ̴
         <a href="mpm.html">ó </a> Ѵ.</p>
    
        <p><a href="programs/apachectl.html">apachectl</a>
        ũƮ Ͽ <code>httpd</code>  ϱ
        Ѵ.  ũƮ <code>httpd</code> 
        ü  ϱ ʿ ȯ溯
        ϰ <code>httpd</code>  Ѵ.
        <code>apachectl</code>  ƱԸƮ ״ ѱ⶧,
        <code>httpd</code>  ɼ̶ <code>apachectl</code>
        밡ϴ. , <code>apachectl</code> ũƮ պκп
         <code>HTTPD</code>  <code>httpd</code> 
        ִ ġ <em>׻</em>   ƱԸƮ 
          ִ.</p>
    
        <p><code>httpd</code> ϸ  <a href="configuring.html"></a> <code>httpd.conf</code>
        ãƼ д´.   ġ  ߿ ϳ, 
          <code>-f</code>  ɼ   ִ.</p>
    
    <div class="example"><p><code>/usr/local/apache2/bin/apachectl -f
          /usr/local/apache2/conf/httpd.conf</code></p></div>
    
        <p>ϴ   ٸ,  ͹̳ο
          Ʈ   Եȴ. ̴ 
         ǹѴ.   Ͽ <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> 丮 ִ
        ׽Ʈ    ũ (ī)  
         ִ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errors" id="errors"> </a></h2>
    
        <p>ġ ϴ ߿ ɰ  ߻ϸ,
        ϱ   ˸  ܼ̳ <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> .    
        ϳ "<code>Unable to bind to Port ...</code>"̴.
         ޼    쿡 ߻Ѵ:</p>
    
        <ul>
          <li>root ڷ α ʰ Ư Ʈ 
          Ϸ  . Ȥ</li>
    
          <li>̹ ġ ٸ   Ʈ
           Ϸ  .</li>
        </ul>
    
        <p>Ÿ ذ  ġ <a href="faq/">FAQ</a>
        ϶.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="boot" id="boot">Ҷ ϱ</a></h2>
    
        <p>ý  Ŀ   DZ ٶٸ,
        ý ( <code>rc.local</code>̳ <code>rc.N</code>
        丮 ִ ) <code>apachectl</code> ߰ؾ
        Ѵ.   ġ root ۵ȴ.   ̳
         (ϱ) ùٷ Ǿ Ȯ϶.</p>
    
        <p><code>apachectl</code> ǥ SysV init ũƮ ϰ
        ϵ . ũƮ ƱԸƮ <code>start</code>,
        <code>restart</code>, <code>stop</code>   
        ñ׳ <code>httpd</code> . ׷ 
        <code>apachectl</code>  init 丮 ũ ɸȴ.
        ׷ ϴ ý Ȯ 䱸 Ȯ϶.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="info" id="info">߰ </a></h2>
    
        <p><a href="programs/httpd.html">httpd</a> <a href="programs/apachectl.html">apachectl</a>, Ÿ 
        Ե  α׷  ɼ
        <a href="programs/">  α׷</a> 
        ϶.  ġ   <a href="mod/"></a>
        ׵ ϴ <a href="mod/directives.html">þ</a>
          ִ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/invoking.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/faq/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�015614� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/faq/index.html.zh-cn.utf8��������������������������������������������������0000664�0001751�0001751�00000007104�14743132254�021505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>常见问题 - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>常见问题</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>常见问题已经移到 <a href="http://wiki.apache.org/httpd/FAQ">HTTP 服务器维基</a>。</p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/faq/index.html.tr.utf8�����������������������������������������������������0000664�0001751�0001751�00000007155�14743132254�021121� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Sıkça Sorulan Sorular - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Sıkça Sorulan Sorular</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>SSS belgesi <a href="http://wiki.apache.org/httpd/FAQ">HTTP Server
          Wiki</a>'ye taşındı.</p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/faq/index.html�������������������������������������������������������������0000664�0001751�0001751�00000000716�13710016232�017572� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: index.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: index.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������httpd-2.4.64/docs/manual/faq/index.html.es����������������������������������������������������������0000664�0001751�0001751�00000007431�14743132254�020213� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Preguntas Frecuentes - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>Preguntas Frecuentes</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
        <p>Las preguntas frecuentes se han movido a la  <a href="http://wiki.apache.org/httpd/FAQ">Wiki  de HTTP Server (en Ingl&#233;s)</a>.</p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/faq/index.html.en����������������������������������������������������������0000664�0001751�0001751�00000007144�14737241666�020222� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Frequently Asked Questions - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Frequently Asked Questions</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/faq/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
        <p>The FAQ has been moved to the <a href="http://wiki.apache.org/httpd/FAQ">HTTP Server Wiki</a>.</p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/faq/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/faq/index.html.fr.utf8�����������������������������������������������������0000664�0001751�0001751�00000007153�14740503670�021102� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Foire aux questions - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Foire aux questions</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
        <p>La FAQ a été transférée vers le <a href="http://wiki.apache.org/httpd/FAQ">Wiki du serveur HTTP</a>.</p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/faq/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/faq/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/faq/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/faq/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/faq/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/glossary.html.ko.euc-kr����������������������������������������������������0000664�0001751�0001751�00000051604�14743132254�021370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title> - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1></h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p>    Ϲݿ , Ư ġ õ, 
    Ѵ.  信  ڼ  ũ ϶.
    <span class="transnote">(<em>;</em>  ܾ  ѱ  ƴ϶, 
    Դϴ. ǥ <a href="http://www.whiterabbitpress.com/osp/apache/"></a>
    ϱ ٶϴ.)</span></p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definitions" id="definitions"></a></h2>
    
    <dl>
    <dt><a name="accesscontrol"> (Access Control)</a></dt>
    <dd>Ʈ    . ġ  Ư
    <em>URL</em>  ϱ Ѵ.<br /> : <a href="howto/auth.html">, Ѻο, </a></dd>
    
    <dt><a name="algorithm">˰ (Algorithm)</a></dt>
    <dd> ܰ踦   Ǫ Ȯ  Ȥ Ģ.
    ȣȭ  ˰  <dfn>ȣ(Ciphers)</dfn>
    θ.</dd>
    
    <dt><a name="apacheextensiontool">APache eXtension Tool</a>
    <a name="apxs">(apxs)</a></dt> <dd><a href="#module">
    (module)</a> ҽ ü (<a href="#dso">DSO</a>)
    ϰ ġ  ġϴ ۾  perl
    ũƮ.<br /> : <a href="programs/apxs.html">Manpage:
    apxs</a></dd>
    
    <dt><a name="authentication"> (Authentication)</a></dt>
    <dd>, Ŭ̾Ʈ,   Ʈ ü 
    Ȯ.<br /> : <a href="howto/auth.html">, Ѻο,
    </a></dd>
    
    <dt><a name="certificate"> (Certificate)</a></dt>
    <dd> Ŭ̾Ʈ  Ʈ ü ϴ ڷ.
          (subject ),  <a href="#certificationauthority"> (Certificate
        Authority)</a> (issuer ),  <a href="#publickey">Ű</a>, CA    
        X.509  ִ. Ʈ ü CA  Ͽ
         ˻Ѵ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="certificatsigningrequest">  û (Certificate
    Signing Request</a>, <a name="csr">CSR)</a></dt> <dd><a href="#certificationauthority"> (Certification
    Authority)</a> Ͽ CA <em> (Certificate)</em>
    <a href="#privatekey">Ű (Private Key)</a>  
     <a href="#certificate"></a>. CSR Ǹ
      ȴ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="certificationauthority"> (Certification
    Authority</a>, <a name="ca">CA)</a></dt> <dd> 
    Ʈ ü   ϴ ŷϴ . ٸ Ʈ
    ü  CA  ڸ ߴ Ȯ 
    ִ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="cipher">ȣ (Cipher)</a></dt> <dd>ڷḦ
    ȣȭϴ ˰̳ ý.  , DES, IDEA, RC4  ִ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="ciphertext">ȣ (Ciphertext)</a></dt> <dd><a href="#plaintext"> (Plaintext)</a> <a href="#cipher">ȣ
    (Cipher)</a> ó .<br /> : <a href="ssl/">SSL/TLS
    ȣȭ</a></dd>
    
    <dt><a name="commongatewayinterface"> Ʈ ̽
    (Common Gateway Interface</a>, <a name="cgi">CGI)</a></dt>
    <dd>ܺ α׷ û   ֵ   ܺ
    α׷  ̽ ǥ. ̽  <a href="http://hoohoo.ncsa.uiuc.edu/cgi/overview.html">NCSA</a>
    , <a href="http://cgi-spec.golux.com/">RFC
    Ʈ</a>̱⵵ ϴ.<br />
    : <a href="howto/cgi.html">CGI   </a></dd>
    
    
    <dt><a name="configurationdirective"> þ (Configuration
    Directive)</a></dt>
    <dd>: <a href="#directive">þ</a></dd>
    
    <dt><a name="configurationfile"> (Configuration File)</a></dt>
    <dd>ġ ϴ <a href="#directive">þ (directive)</a>
     ؽƮ.<br />
    : <a href="configuring.html"></a></dd>
    
    <dt><a name="connect">CONNECT</a></dt>
    <dd>HTTP  ڷ帧 Ͻϴ HTTP <a href="#method">޽
    (method)</a>. SSL   ٸ  α Ѵ.</dd>
    
    <dt><a name="context"> (Context)</a></dt> <dd><a href="#configurationfile"> (configuration file)</a>
    Ư <a href="#directive">þ (directive)</a>  
    ִ .<br /> : <a href="mod/directive-dict.html#Context">ġ þ ϴµ
     </a></dd>
    
    <dt><a name="digitalsignature">ڼ (Digital Signature)</a></dt>
    <dd> ٸ  ˻ϴ ȣȭ ڵ. <a href="#certificationauthority"> (Certification
        Authority)</a> <em> (Certificate)</em> Ե
        <em>Ű (Public Key)</em> ؽ  ڽ
        <em>Ű (Private Key)</em> ȣȭϿ  .
         CA Ű  Ǯ  ֱ⶧, CA <em>
        (Certificate)</em>  Ʈ ü  
         ִ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="directive">þ (Directive)</a></dt> <dd>ġ
      ϴ  ɾ. þ <a href="#configurationfile"> (Configuration File)</a>
    Ѵ.<br /> : <a href="mod/directives.html">þ </a></dd>
    
    <dt><a name="dynamicsharedobject">ü (Dynamic Shared
    Object)</a> <a name="dso">(DSO)</a></dt> <dd> ġ httpd
    ϰ  Ͽ ʿҶ о  ִ <a href="#module"> (Module)</a>.<br />
    : <a href="dso.html">ü </a></dd>
    
    <dt><a name="environmentvariable">ȯ溯 (Environment Variable)</a>
    <a name="env-variable">(env-variable)</a></dt>
    <dd> ϰ α׷   ü  ϴ
    . ġ ȯ溯   ,  ȯ
    ƴ϶ ġ ο ȴ.<br />
    : <a href="env.html">ġ ȯ溯</a></dd>
    
    <dt><a name="export-crippled"> (Export-Crippled)</a></dt>
    <dd>̱ (Export Administration Regulations, EAR)
        ؼϱ ȣ( )  .  ȣȭ
        Ʈ Ű ũⰡ ۰ ѵǾ, <em>ȣ
        (Ciphertext)</em>  (brute force) Ǯ  ִ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ (SSL/TLS Encryption)</a></dd>
    
    <dt><a name="filter"> (Filter)</a></dt>
    <dd> ų ޴ ڷḦ óϴ . Էʹ
    Ŭ̾Ʈ   ڷḦ óϰ, ʹ 
    Ŭ̾Ʈ   óѴ.  ,
    <code>INCLUDES</code> ʹ  <a href="#ssi">Server
    Side Includes</a> óѴ.<br />
    : <a href="filter.html"></a></dd>
    
    <dt><a name="fully-qualifieddomain-name"> θ
    (Fully-Qualified Domain-Name)</a> <a name="fqdn">(FQDN)</a></dt>
    <dd>IP ּҿ ϴ, ȣƮ θ  Ʈ
    ü  ̸.  , <code>www</code> ȣƮ̰
    <code>example.com</code> θ϶,
    <code>www.example.com</code>  θ̴.</dd>
    
    <dt><a name="handler">ڵ鷯 (Handler)</a></dt>
    <dd> ûҶ ϴ ۾  ġ  ǥ.
    Ϲ     Ϲ ڵ鷯 .
         ,   
     "óȴ(handled)".  , <code>cgi-script</code>
    ڵ鷯 <a href="#cgi">CGI</a> ó  Ѵ.<br />
    : <a href="handler.html">ġ ڵ鷯 </a></dd>
    
    <dt><a name="header"> (Header)</a></dt>
    <dd><a href="#http">HTTP</a> û 信   
     κ  ϴ  ִ.</dd>
    
    <dt><a name="htaccess">.htaccess</a></dt> <dd> ȿ ִ
    <a href="#configurationfile"> (configuration file)</a>,
     <a href="#directive">þ (directive)</a> ڽ ġ
    丮  丮 Ѵ. ̸ ޸ 
    Ͽ ܼ  þܿ    þ
      ִ.<br />
    : <a href="configuring.html"></a></dd>
    
    <dt><a name="httpd.conf">httpd.conf</a></dt>
    <dd>ġ  <a href="#configurationfile"> (configuration
    file)</a>. ⺻ ġ
    <code>/usr/local/apache2/conf/httpd.conf</code>, Ҷ
    Ȥ ϶    ִ.<br />
    : <a href="configuring.html"></a></dd>
    
    <dt><a name="hypertexttransferprotocol">HyperText Transfer
    Protocol</a> <a name="http">(HTTP)</a></dt>
    <dd>̵ ϴ ǥ  . ġ
    <a href="http://ietf.org/rfc/rfc2616.txt">RFC 2616</a>
     HTTP/1.1̶  1.1  Ѵ.</dd>
    
    <dt><a name="https">HTTPS</a></dt>
    <dd>ȭ̵ ǥ ȣ , HyperText Transfer
        Protocol (Secure).  شܿ <a href="#ssl">SSL</a>
         HTTP̴.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="method">޽ (Method)</a></dt> <dd>Ŭ̾Ʈ
     <a href="#http">HTTP</a> û
    ڿ ϵ  ൿ. HTTP ޽忡 <code>GET</code>,
    <code>POST</code>, <code>PUT</code>  ִ.</dd>
    
    <dt><a name="messagedigest">޽  (Message Digest)</a></dt>
    <dd>޽    ʾ ϱ
        ޽ ؽ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="mime-type">MIME-type</a></dt> <dd> 
     ϴ . Multipurpose Internet Mail Extensions
     Ա⶧ ̷ ̸ .  ̿
     major type minor type ̷.  ,
    <code>text/html</code>, <code>image/gif</code>,
    <code>application/octet-stream</code> ̴. MIME-type HTTP
    <code>Content-Type</code> <a href="#header"> (header)</a>
    Ѵ.<br /> : <a href="mod/mod_mime.html">mod_mime</a></dd>
    
    <dt><a name="module"> (Module)</a></dt> <dd>α׷ 
    κ.  ġ   Կθ   ִ ⿡
    ִ. ġ httpd ϰ    <em>
    </em>̶ ϸ,  иǾ   о
     ִ  <em> </em> Ȥ <a href="#dso">DSO</a>
    Ѵ. ⺻ ϴ  <em>base </em>̶ Ѵ.
    ġ  <a href="#tarball">Ÿ (tarball)</a> 
      ġ   ִ. ̵
    <em>ڰ (third-party) </em>̶ Ѵ.<br />
    : <a href="mod/"> </a></dd>
    
    <dt><a name="modulemagicnumber">  (Module Magic Number)</a>
    (<a name="mmn">MMN</a>)</dt>
    <dd>  ġ ҽڵ尡  , 
    ȣȯ  ִ.   ȣȯ  ̻ 
      ġ   Լ ȣ, ٸ API Ϻΰ 
    쿡 ٲ. MMN ϸ ڰ    ּ ٽ
    ϵǾ Ѵ.  ġ  µ  ؾ 쵵
    ִ.
    </dd>
    
    <dt><a name="openssl">OpenSSL</a></dt>
    <dd>SSL/TLS  ¼ҽ <br />
         <a href="http://www.openssl.org/">http://www.openssl.org/</a></dd>
    
    <dt><a name="passphrase">Pass Phrase</a></dt>
    <dd>Ű  ȣϴ .  ڰ  Ű
     Ͽ ȣȭ ϵ Ѵ.  <a name="cipher">ȣ
    (Ciphers)</a> ϴ н ȣ/ص Ű̴.<br /> : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="plaintext"> (Plaintext)</a></dt>
    <dd>ȣȭ  .</dd>
    
    <dt><a name="privatekey">Ű (Private Key)</a></dt> <dd>
    ڷḦ صϰ  ڷḦ ϱ <a href="#publickeycryptography">Ű ȣȭ (Public Key
    Cryptography)</a> ý ȣŰ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="proxy">Ͻ (Proxy)</a></dt> <dd>Ŭ̾Ʈ
    <em> </em> ̿ ִ ߰ . Ŭ̾Ʈ û
    ޾   ,  Լ   ٽ
    Ŭ̾Ʈ .  Ŭ̾Ʈ   ûϸ
    Ͻô Ź  ûʰ ij   Ͽ
    ð   ִ.<br />
    : <a href="mod/mod_proxy.html">mod_proxy</a></dd>
    
    <dt><a name="publickey">Ű (Public Key)</a></dt> <dd><a href="#publickeycryptography">Ű ȣȭ (Public Key
    Cryptography)</a> ýۿ Ű ڿ   ȣȭϰų
    ڰ   Ǯ  Ű.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="publickeycryptography">Ű ȣȭ (Public Key
    Cryptography)</a></dt>
    <dd>ȣ ص  ٸ Ű ϴ Ī(asymmetric)
    ȣȭ ý   Ȱ. ȣ ص ϴ ΰ Ű
    Ű(key pair) ̷. Ī ȣȭ θ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="regularexpresion">ǥ (Regular Expression)</a> <a name="regex">(Regex)</a></dt> <dd>  ϴ .
     , " A ϴ  ܾ", " 10ε ȭȣ",
     "ǥ ΰְ 빮 Q  "  ǥ  ִ.
    ǥ ϸ ſ ϰ ̳ ڿ   
     ִ.  , "images" 丮 Ʒ ִ  .gif
    .jpg  "<code>/images/.*(jpg|gif)$</code>" Ī 
    ִ. ġ <a href="http://www.pcre.org/">PCRE</a> ̺귯
    Ͽ Perlȣȯ ǥ Ѵ.</dd>
    
    <dt><a name="reverseproxy">Ͻ (Reverse Proxy)</a></dt>
    <dd>Ŭ̾Ʈ <em> </em>ó ̴ <a href="#proxy">Ͻ (proxy)</a> . Ȼ  Ȥ ϸ
    лϱ Ŭ̾Ʈ   涧 ϴ.</dd>
    
    <dt><a name="securesocketslayer">Secure Sockets Layer</a> <a name="ssl">(SSL)</a></dt> <dd>Netscape Communications簡 TCP/IP
    Ʈ Ϲ   ȣȭ   .
     Ϲ 뵵 <em>HTTPS</em> (HyperText Transfer Protocol
    (HTTP) over SSL)̴.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="serversideincludes">Server Side Includes</a> <a name="ssi">(SSI)</a></dt> <dd>HTML  ȿ óþ ϴ
    .<br /> : <a href="howto/ssi.html">Server Side Includes Ұ</a></dd>
    
    <dt><a name="session"> (Session)</a></dt>
    <dd>Ϲ  Ȳ(context) .</dd>
    
    <dt><a name="ssleay">SSLeay</a></dt>
    <dd>Eric A. Young   SSL/TLS  ̺귯</dd>
    
    <dt><a name="symmetriccryptophraphy">Ī ȣ (Symmetric
    Cryptography)</a></dt>
    <dd>ȣ ص ۾  ȣŰ ϴ <em>ȣ
        (Ciphers)</em>   Ȱ.<br />
    : <a href="ssl/">SSL/TLS Encryption</a></dd>
    
    <dt><a name="tarball">Ÿ (Tarball)</a></dt>
    <dd><code>tar</code>  Ͽ ϵ  . ġ
    tar  ϰų pkzip Ͽ ȴ.</dd>
    
    <dt><a name="transportlayersecurity">Transport Layer Security</a> <a name="tls">(TLS)</a></dt>
    <dd>ͳݱ  ǥȭⱸ(Internet Engineering Task
    Force, IETF) TCP/IP Ʈ Ϲ   ȣȭ
      SSL ļ . TLS  1 SSL  3 
    ϴ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    
    <dt><a name="uniformresourcelocator">Uniform Resource Locator</a>
    <a name="url">(URL)</a></dt>
    <dd>ͳݿ ִ ڿ ̸/ּ. δ <a href="#uniformresourceidentifier">Uniform Resource
    Identifier</a> ϴ  ϻ  Ī̴.  URL
    <code>http</code> <code>https</code> Ŵ(scheme), ȣƮ,
    η ȴ.   URL
    <code>http://httpd.apache.org/docs/2.4/glossary.html</code>̴.</dd>
    
    <dt><a name="uniformresourceidentifier">Uniform Resource Identifier</a>
    <a name="URI">(URI)</a></dt>
    <dd>߻ ڿ̳  ڿ Īϱ  ڿ.
     <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC
    2396</a> Ѵ. ̵ ϴ URI 
    <a href="#url">URL</a>̶ θ.</dd>
    
    <dt><a name="virtualhosting">ȣƮ (Virtual Hosting)</a></dt>
    <dd>ġ ϳ  Ʈ ϱ. <em>IP ȣƮ</em>
    Ʈ IP ּҰ ٸ. <em≯(name-based)
    ȣƮ</em> ȣƮ ϹǷ  IP ּҿ 
    Ʈ   ִ.<br />
    : <a href="vhosts/">ġ ȣƮ </a></dd>
    
    <dt><a name="x.509">X.509</a></dt>
    <dd>ſ(International Telecommunication Union,
    ITU-T) ϴ  . SSL/TLS  Ѵ.<br />
    : <a href="ssl/">SSL/TLS ȣȭ</a></dd>
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/glossary.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/socache.html���������������������������������������������������������������0000664�0001751�0001751�00000000315�13710016232�017314� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: socache.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: socache.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html.ko.euc-kr�����������������������������������������������������0000664�0001751�0001751�00000026546�14743132254�021151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ ڵ鷯  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ġ ڵ鷯 </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>  ġ ڵ鷯 ϴ  Ѵ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#definition">ڵ鷯 ΰ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programmer">α׷Ӹ  </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definition" id="definition">ڵ鷯 ΰ</a></h2>
        
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></li><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removehandler">RemoveHandler</a></code></li><li><code class="directive"><a href="./mod/core.html#sethandler">SetHandler</a></code></li></ul></td></tr></table>
    
    
        <p> ûҶ ġ   ۾
        "ڵ鷯(handler)" Ѵ. Ϲ   
         Ϲ ڵ鷯  ִ.    
         ,     "óȴ(handled)".</p>
    
        <p>Apache 1.1 ڵ鷯    ְ Ǿ.
           ڵ鷯  Ȯڳ ġ 
          ִ. ̴  Ǹ ̰   ڵ鷯
         ο   ֱ⶧ . (<a href="mod/mod_mime.html#multipleext"> Ȯڸ  </a>
        )</p>
    
        <p>ڵ鷯   Ͽ, <code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code> þ ߰
         ִ. ǥ  ִ ⺻ ڵ鷯  :</p>
    
        <ul>
          <li><strong>default-handler</strong>:  
          óϱ ⺻ ϴ ڵ鷯
          <code>default_handler()</code> Ͽ  .
          (core)</li>
    
          <li><strong>send-as-is</strong>: HTTP  ִ 
          ״ . (<code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code>)</li>
    
          <li><strong>cgi-script</strong>:  CGI óѴ.
          (<code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>)</li>
    
          <li><strong>imap-file</strong>: imagemap Ģ Ϸ
          óѴ. (<code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code>)</li>
    
          <li><strong>server-info</strong>:   
          ˷ش. (<code class="module"><a href="./mod/mod_info.html">mod_info</a></code>)</li>
    
          <li><strong>server-status</strong>:  ¸ Ѵ.
          (<code class="module"><a href="./mod/mod_status.html">mod_status</a></code>)</li>
    
          <li><strong>type-map</strong>:  
          type map óѴ.
          (<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>)</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples"></a></h2>
        
    
        <h3><a name="example1" id="example1">CGI ũƮ Ͽ   ϱ</a></h3>
          
    
          <p> þ Ȯڰ <code>html</code> 
          û  <code>footer.pl</code> CGI ũƮ .</p>
    
          <div class="example"><p><code>
            Action add-footer /cgi-bin/footer.pl<br />
            AddHandler add-footer .html
          </code></p></div>
    
          <p>CGI ũƮ
          (<code>PATH_TRANSLATED</code> ȯ溯 Īϴ) 
          û     .</p>
     
        
        <h3><a name="example2" id="example2">HTTP  ϴ </a></h3>
          
    
          <p> þ HTTP  ϴ Ͽ
          <code>send-as-is</code> ڵ鷯 Ѵ.
          <code>/web/htdocs/asis/</code> 丮 ȿ ִ 
           Ȯڿ  <code>send-as-is</code> ڵ鷯
          óѴ.</p>
    
          <div class="example"><p><code>
            &lt;Directory /web/htdocs/asis&gt;<br />
            SetHandler send-as-is<br />
            &lt;/Directory&gt;
          </code></p></div>
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programmer" id="programmer">α׷Ӹ  </a></h2>
        
    
        <p>ڵ鷯  ϱ 
        <a href="developer/API.html">Apache API</a> ߰Ǿ.
        Ư <code>request_rec</code> ü ο ʵ尡
        ߰Ǿ:</p>
    
        <div class="example"><p><code>
          char *handler
        </code></p></div>
    
        <p> ڵ鷯 Ϸ, û
        <code>invoke_handler</code> ܰ 
        <code>r-&gt;handler</code> ڵ鷯 ̸ ֱ⸸
        ϸ ȴ. ڵ鷯 content type  ڵ鷯 ̸ 
         ϰ   Ǿ.  ų ʿ 
        ڵ鷯 ̸   ʰ, ܾ ̿ 
        ȣ ϴ  Ϲ̴. ׷ ڵ鷯 ̸
        media type ġ ʴ´.</p>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/handler.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.ru.utf8���������������������������������������������������������0000664�0001751�0001751�00000024640�14743132254�020351� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ru" xml:lang="ru"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server версия 2.4
    Документация - HTTP сервер Apache Версия 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Модули</a> | <a href="./mod/directives.html">Директивы</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Глоссарий</a> | <a href="./sitemap.html">Карта сайта</a></p>
    <p class="apache">HTTP сервер Apache Версия 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP сервер</a> &gt; <a href="http://httpd.apache.org/docs/">Документация</a></div>
    <div id="page-content"><h1>Apache HTTP Server версия 2.4
    Документация</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Google Search" type="submit" /><input value="10" name="num" type="hidden" /><input value="ru" name="hl" type="hidden" /><input value="UTF-8" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Версия 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">Примечания к выпуску</a></h2>
    <ul><li><a href="new_features_2_4.html">Новые возможности Apache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Новые возможности Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">Новые возможности Apache 2.0</a></li>
    <li><a href="upgrading.html">Обновление до 2.4 с 2.2</a></li>
    <li><a href="license.html">Лицензия Apache</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">Справочное руководство</a></h2>
    <ul><li><a href="install.html">Компиляция и установка</a></li>
    <li><a href="invoking.html">Запуск</a></li>
    <li><a href="stopping.html">Остановка или перезапуск</a></li>
    <li><a href="mod/quickreference.html">Директивы конфигурации среды выполнения</a></li>
    <li><a href="mod/">Модули</a></li>
    <li><a href="mpm.html">Модули многопроцессорной обработки (MPMs)</a></li>
    <li><a href="filter.html">Фильтры</a></li>
    <li><a href="handler.html">Обработчики</a></li>
    <li><a href="expr.html">Парсер выражений</a></li>
    <li><a href="mod/overrides.html">Индекс классов переопределения для .htaccess</a></li>
    <li><a href="programs/">Сервер и вспомогательные программы</a></li>
    <li><a href="glossary.html">Глоссарий</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">Руководство пользователя</a></h2>
    <ul><li><a href="getting-started.html">Начало работы</a></li>
    <li><a href="bind.html">Привязка к адресам и портам</a></li>
    <li><a href="configuring.html">Файлы конфигурации</a></li>
    <li><a href="sections.html">Разделы конфигурации</a></li>
    <li><a href="caching.html">Кэширование контента</a></li>
    <li><a href="content-negotiation.html">Согласование контента</a></li>
    <li><a href="dso.html">Динамические общие объекты (DSO)</a></li>
    <li><a href="env.html">Переменные среды</a></li>
    <li><a href="logs.html">Лог-файлы</a></li>
    <li><a href="urlmapping.html">Сопоставление URL-адресов с файловой системой</a></li>
    <li><a href="misc/perf-tuning.html">Настройка производительности</a></li>
    <li><a href="misc/security_tips.html">Советы по безопасности</a></li>
    <li><a href="server-wide.html">Общесерверная конфигурация</a></li>
    <li><a href="ssl/">SSL/TLS шифрование</a></li>
    <li><a href="suexec.html">Выполнение SuExec для CGI</a></li>
    <li><a href="rewrite/">Перезапись URL с помощью mod_rewrite</a></li>
    <li><a href="vhosts/">Виртуальные хосты</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">Инструкции / Учебники</a></h2>
    <ul><li><a href="howto/auth.html">Аутентификация и авторизация</a></li>
    <li><a href="howto/access.html">Контроль доступа</a></li>
    <li><a href="howto/cgi.html">CGI: динамический контент</a></li>
    <li><a href="howto/htaccess.html">Файлы .htaccess</a></li>
    <li><a href="howto/ssi.html">Включения на стороне сервера (SSI)</a></li>
    <li><a href="howto/public_html.html">Веб-каталоги для каждого пользователя (public_html)</a></li>
    <li><a href="howto/reverse_proxy.html">Руководство по настройке обратного прокси</a></li>
    <li><a href="howto/http2.html">Руководство HTTP/2</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">Специфические примечания к платформе</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">RPM-based системы (Redhat / CentOS / Fedora)</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC Port</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">Другие темы</a></h2>
    <ul><li><a href="http://wiki.apache.org/httpd/FAQ">Часто задаваемые вопросы</a></li>
    <li><a href="sitemap.html">Карта сайта</a></li>
    <li><a href="developer/">Документация для разработчиков</a></li>
    <li><a href="http://httpd.apache.org/docs-project/">Помощь с документацией</a></li>
    <li><a href="misc/">Прочие примечания</a></li>
    <li><a href="http://wiki.apache.org/httpd/">Вики</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Модули</a> | <a href="./mod/directives.html">Директивы</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Глоссарий</a> | <a href="./sitemap.html">Карта сайта</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/install.html���������������������������������������������������������������0000664�0001751�0001751�00000001203�13710016232�017352� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: install.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: install.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: install.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: install.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: install.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/logs.html.ja.utf8����������������������������������������������������������0000664�0001751�0001751�00000120205�14743132254�020144� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ログファイル - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>ログファイル</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>ウェブサーバを効果的に管理するためには、サーバの活動やパフォーマンス、
        今発生しているかもしれない問題に関するフィードバックを得ることが必要です。
        Apache HTTP サーバには非常に包括的で柔軟なロギング機能があります。
        この文書はロギング機能の設定の仕方と、ログに何が書かれているかを
        理解するための方法を説明します。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#security">
        セキュリティに関する警告</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errorlog">エラーログ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#accesslog">アクセスログ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rotation">ログの交替</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#piped">パイプ経由のログ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhosts">バーチャルホスト</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">他のログファイル</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">
        セキュリティに関する警告</a></h2>
    
        <p>Apache がログファイルを書いているディレクトリに書き込める人は、
        ほぼ確実にサーバが起動された uid へのアクセスを手に入れることができます。
        そして、それは通常は root ユーザです。
        ちゃんと結果を考えることなく、そのディレクトリへの
        書き込み権限を与え<em>ない</em>でください。詳しくは
        <a href="misc/security_tips.html">セキュリティのこつ</a>の文書を
        読んでください。</p>
    
        <p>加えて、ログファイルにはクライアントからの情報がそのまま、
        エスケープされることなく書かれています。ですから、悪意のある
        クライアントがログファイルに制御文字を挿入することができます。
        生のログを扱うときは注意してください。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errorlog" id="errorlog">エラーログ</a></h2>
        
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code></li></ul></td></tr></table>
    
        <p><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> ディレクティブにより
        名前と場所が決まるサーバのエラーログは、一番重要なログファイルです。
        Apache の診断情報はここに送られ、リクエストを処理しているときに
        発生したエラーはすべてここに記録されます。サーバを起動したときや、
        サーバの動作に問題が起こったときは、一番最初に調べるべき
        ところです。間違いの詳細や修正方法がそこに書かれていることが
        よくあります。</p>
    
        <p>エラーログは普通はファイルに書かれます (通常 Unix システムでは
        <code>error_log</code>、Windows と OS/2 では <code>error.log</code>)。
        Unix システムではエラーを <code>syslog</code> や
        <a href="#piped">パイプでプログラムに送る</a> ことができます。</p>
    
        <p>エラーログの書式は比較的自由度の高いもので、説明的に書かれています。
        ただし、いくつかの情報はほとんどのエラーログのエントリにあります。
        例えば、代表的なものに次のようなメッセージがあります。</p>
    
        <div class="example"><p><code>
          [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1]
          client denied by server configuration:
          /export/home/live/ap/htdocs/test
        </code></p></div>
    
        <p>ログエントリの最初の項目はメッセージの日付と時刻です。
        二つめの項目は報告されているエラーの重要度です。
        <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> で重要度のレベルを
        制限することによりエラーログに送られるエラーの種類を制御することが
        できます。三つ目の項目はエラーを発生させたクライアントの IP アドレス
        です。残りはメッセージで、この場合はサーバがクライアントのアクセスを
        拒否するように設定されている、ということを示しています。
        サーバはリクエストされた文書の (ウェブのパスではなく) ファイルシステムの
        パスを報告します。</p>
    
        <p>非常に広範囲のメッセージがエラーログに現れます。たいていのものは
        上の例のような感じです。エラーログには CGI スクリプトのデバッグ
        出力も書かれます。CGI スクリプトが <code>stderr</code> に書いた
        すべての情報は直接エラーログにコピーされます。</p>
    
        <p>情報を追加したり削除したりしてエラーログをカスタマイズすることは
        できません。しかし、リクエストに対するエラーログのエントリは、
        対応するエントリが<a href="#accesslog">アクセスログ</a>にあります。
        例えば、上の例のエントリはアクセスログのステータスコード 403 の
        エントリに対応します。アクセスログはカスタマイズ可能ですので、
        そちらを使うことによりエラーの状況に関する情報をより多く
        手に入れることができます。</p>
    
        <p>テストの最中は、問題が発生しているかどうかを見るために、
        常にエラーログを監視するのが役に立つ場合がよくあります。
        Unix システムでは、次のものを使うことができます。</p>
    
        <div class="example"><p><code>
          tail -f error_log
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="accesslog" id="accesslog">アクセスログ</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li></ul></td></tr></table>
    
        <p>サーバアクセスログはサーバが処理をしたすべてのリクエストを
        記録します。アクセスログの場所と内容は <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
        ディレクティブにより決まります。ログの内容の選択を簡潔にするために
        <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>
        ディレクティブを使用することができます。このセクションはアクセスログに
        情報を記録するためのサーバの設定方法を説明します。</p>
    
        <p>もちろん、アクセスログに情報を蓄積することはログ管理の
        始まりに過ぎません。次の段階は有用な統計を取るためにこの情報を
        解析することです。一般的なログ解析はこの文書の範囲外で、
        ウェブサーバ自身の仕事というわけでもありません。この話や、
        ログ解析を行なうアプリケーションの情報を得るには、<a href="http://dmoz.org/Computers/Software/Internet/Site_Management/Log_Analysis/">
        Open Directory</a> を調べてください。</p>
    
        <p>いろんなバージョンの Apache httpd が mod_log_config,
        mod_log_agent, <code>TransferLog</code> ディレクティブといった、
        他のモジュールやディレクティブを使ってアクセスのロギングを
        制御してきました。今では、<code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> がすべての古い
        ディレクティブの機能を含むようになっています。</p>
    
        <p>アクセスログの書式は非常に柔軟な設定が可能です。
        書式は C の printf(1) フォーマット文字列に非常に似た
        <code class="directive"><a href="./mod/mod_log_config.html#フォーマット文字列">フォーマット文字列</a></code>
        により指定されます。いくつか次の節で例を示します。
        フォーマット文字列に使用できる内容の一覧は <a href="mod/mod_log_config.html">mod_log_config の文書</a>
        を見てください。</p>
    
        <h3><a name="common" id="common">Common Log Format</a></h3>
          
    
          <p>アクセスログのよくある設定に以下のものがあります。</p>
    
          <div class="example"><p><code>
            LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common<br />
             CustomLog logs/access_log common
          </code></p></div>
    
          <p>これは、<em>ニックネーム</em> <code>common</code> を定義し、
          ログのフォーマット文字列の一つと関連付けます。フォーマット文字列は
          パーセントディレクティブからなり、それぞれのパーセントディレクティブは
          サーバにどの情報をロギングするかを指示します。フォーマット文字列に
          文字をそのまま入れることもでき、それらはログの出力に直接コピーされます。
          そこに引用文字 (<code>"</code>) を書くときは、
          フォーマット文字列の最後として解釈
          されることを防ぐためにバックスラッシュでエスケープする必要があります。
          フォーマット文字列には改行用の "<code>\n</code>"、タブ用の
          "<code>\t</code>" という特別な制御文字も含めることができます。</p>
    
          <p><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> ディレクティブは
          既に定義された
          <em>ニックネーム</em> を使って新しいログファイルを設定します。
          アクセスログのファイル名はスラッシュで始まらない限り、
          <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> からの相対パスとして
          扱われます。</p>
    
          <p>上の設定は Common Log Format (CLF) と呼ばれる形式で
          ログエントリを書きます。この標準の形式は異なるウェブサーバの多くが
          生成することができ、多くのログ解析プログラムが読みこむことができます。
          CLF により生成されたログファイルのエントリは以下のようになります:</p>
    
          <div class="example"><p><code>
            127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET
            /apache_pb.gif HTTP/1.0" 200 2326
          </code></p></div>
    
          <p>このログエントリのそれぞれの部分の意味は以下で説明します。</p>
    
          <dl>
    	<dt><code>127.0.0.1</code> (<code>%h</code>)</dt>
    
    	<dd>これはサーバへリクエストをしたクライアント (リモートホスト)
    	の IP アドレスです。<code class="directive"><a href="./mod/core.html#hostnamelookups">HostnameLookups</a></code> が
    	<code>On</code> の場合は、サーバはホスト名を調べて、
    	IP アドレスが書かれているところに記録します。しかし、この設定は
    	サーバをかなり遅くするので、あまりお勧めできません。
    	そうではなく、<code class="program"><a href="./programs/logresolve.html">logresolve</a></code> の
    	ようなログの後処理を行なうプログラムでホスト名を調べるのが良いでしょう。
    	ここに報告される IP アドレスは必ずしもユーザが使っているマシンの
    	ものであるとは限りません。ユーザとサーバの間にプロキシサーバが
    	あれば、このアドレスは元のマシンのものではなく、プロキシの
    	アドレスになります。</dd>
    
    	<dt><code>-</code> (<code>%l</code>)</dt>
    
    	<dd>出力中の「ハイフン」は要求された情報が手に入らなかったということを
    	意味します。この場合、取得できなかった情報はクライアントのマシンの
    	<code>identd</code> により決まる RFC 1413 のクライアントの
    	アイデンティティです。この情報はあまり信用することができず、
    	しっかりと管理された内部ネットワークを除いては使うべきではありません。
    	Apache は <code class="directive"><a href="./mod/core.html#identitycheck">IdentityCheck</a></code> が
    	<code>On</code> になっていない限り、この情報を得ようとすらしません。</dd>
    
    	<dt><code>frank</code> (<code>%u</code>)</dt>
    
    	<dd>これは HTTP 認証による、ドキュメントをリクエストした人の
    	ユーザ ID です。CGI スクリプトには通常同じ値が <code>REMOTE_USER</code>
    	環境変数として与えられます。リクエストのステータスコード
    	(以下を参照) が 401 であった場合は、ユーザは認証に失敗しているので、
    	この値は信用できません。ドキュメントがパスワードで保護されていない
    	場合は、この部分は前のものと同じように "<code>-</code>" に
    	なります。</dd>
    
    	<dt><code>[10/Oct/2000:13:55:36 -0700]</code>
    	(<code>%t</code>)</dt>
    
    	<dd>
    	  サーバがリクエストを受け取った時刻です。書式は:
    
    	    <p class="indent">
    	      <code>[day/month/year:hour:minute:second zone]<br />
    	       day = 2*digit<br />
    	       month = 3*letter<br />
    	       year = 4*digit<br />
    	       hour = 2*digit<br />
    	       minute = 2*digit<br />
    	       second = 2*digit<br />
    	       zone = (`+' | `-') 4*digit</code>
    	    </p>
    	  ログのフォーマット文字列に <code>%{format}t</code> を
    	  指定することで、別の形式で時刻を表示させることもできます。
    	  このとき、<code>format</code> は C の標準ライブラリの
    	  <code>strftime(3)</code> の形式になります。
    	</dd>
    
    	<dt><code>"GET /apache_pb.gif HTTP/1.0"</code>
    	(<code>\"%r\"</code>)</dt>
    
    	<dd>クライアントからのリクエストが二重引用符の中に示されています。
    	リクエストには多くの有用な情報があります。まず、この場合クライアントが
    	使ったメソッドは <code>GET</code> です。次に、クライアントは
    	リソース <code>/apache_pb.gif</code> を要求しました。そして、
    	クライアントはプロトコル <code>HTTP/1.0</code> を使用しました。
    	リクエストの各部分を独立にログ収集することもできます。例えば、
    	フォーマット文字列 "<code>%m %U%q %H</code>" は
    	メソッド、パス、クエリ文字列、プロトコルをログ収集し、
    	結局 "<code>%r</code>" とまったく同じ出力になります。</dd>
    
    	<dt><code>200</code> (<code>%&gt;s</code>)</dt>
    
    	<dd>サーバがクライアントに送り返すステータスコードです。
    	この情報は、リクエストが成功応答 (2 で始まるコード) であったか、
    	リダイレクション (3 で始まるコード) であったか、クライアントによる
    	エラー (4 で始まるコード) であったか、サーバのエラー (5 で始まるコード)
    	であったか、を表すので、非常に大切です。ステータスコードの
    	完全なリストは <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">HTTP
    	規格</a> (RFC2616 第 10 節) にあります。</dd>
    
    	<dt><code>2326</code> (<code>%b</code>)</dt>
    
    	<dd>この最後の部分はクライアントに送信されたオブジェクトの、
    	応答ヘッダを除いたサイズを表します。コンテントがクライアントに送られなかった
    	場合は、この値は "<code>-</code>" になります。コンテントが無い場合に
    	"<code>0</code>" をログ収集するには、<code>%b</code> ではなく
    	<code>%B</code> を使ってください。</dd>
    
          </dl>
        
    
        <h3><a name="combined" id="combined">Combined Log Format</a></h3>
          
    
          <p>もう一つのよく使われる書式は Combined Log Format と呼ばれています。
          以下のようにして使うことができます。</p>
    
          <div class="example"><p><code>
            LogFormat "%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\"
            \"%{User-agent}i\"" combined<br />
             CustomLog log/access_log combined
          </code></p></div>
    
          <p>この書式の最初の方は Common Log Format とまったく同じで、最後に
          二つ追加のエントリがあります。追加のエントリはパーセントディレクティブ
          <code>%{<em>header</em>}i</code> を使っています。ここで
          <em>header</em> は HTTP のリクエストヘッダのどれかです。この書式による
          アクセスログは以下のような感じになります:</p>
    
          <div class="example"><p><code>
            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)"
          </code></p></div>
    
          <p>追加のエントリは:</p>
    
          <dl>
    	<dt><code>"http://www.example.com/start.html"</code>
    	(<code>\"%{Referer}i\"</code>)</dt>
    
    	<dd>"Referer" (意図的な綴り間違い) HTTP リクエストヘッダです。
    	これはクライアントが報告してくる参照元のサイトを表します。
    	(この場合は、<code>/apache_pb.gif</code> にリンクしているか、
    	それを含んでいるページです)。</dd>
    
    	<dt><code>"Mozilla/4.08 [en] (Win98; I ;Nav)"</code>
    	(<code>\"%{User-agent}i\"</code>)</dt>
    
    	<dd>User-Agent HTTP リクエストヘッダです。これはクライアントのブラウザが
    	自分自身のことを報告してくる情報です。</dd>
          </dl>
        
    
        <h3><a name="multiple" id="multiple">複数のアクセスログ</a></h3>
          
    
        <p>複数のアクセスログは単に設定ファイルに複数の <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
        ディレクティブを書くことで作成されます。例えば、以下のディレクティブは
        三つのアクセスログを作ります。最初のものは基本的な CLF の情報で、
        二つ目と三つ目は referer とブラウザの情報です。最後二つの
        <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> は
        <code>ReferLog</code> ディレクティブと
        <code>AgentLog</code> ディレクティブの効果をまねる方法を示しています。</p>
    
          <div class="example"><p><code>
            LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common<br />
            CustomLog logs/access_log common<br />
            CustomLog logs/referer_log "%{Referer}i -&gt; %U"<br />
            CustomLog logs/agent_log "%{User-agent}i"
          </code></p></div>
    
        <p>この例は <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> で
        ニックネームを定義する必要がない、
        ということも示しています。ニックネームの代わりに、
        <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> ディレクティブに
        直接ログの書式を指定することができます。</p>
        
    
        <h3><a name="conditional" id="conditional">条件付きログ</a></h3>
          
    
        <p>クライアントのリクエストの特徴に基づいてアクセスログにエントリの
        一部をロギングしない方が便利なことがあります。これは <a href="env.html">環境変数</a> の補助により簡単に実現できます。まず、
        リクエストが何らかの条件に合うということを表すために環境変数が
        設定される必要があります。これは通常は <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> により
        行なわれます。そして、<code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> ディレクティブの
        <code>env=</code> 節を使って環境変数が設定されているリクエストを
        含めたり排除したりすることができます。いくつか例を挙げます:</p>
    
          <div class="example"><p><code>
            # Mark requests from the loop-back interface<br />
            SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog<br />
            # Mark requests for the robots.txt file<br />
            SetEnvIf Request_URI "^/robots\.txt$" dontlog<br />
            # Log what remains<br />
            CustomLog logs/access_log common env=!dontlog
          </code></p></div>
    
        <p>他の例として、英語を話す人からのリクエストとそれ以外の人からのリクエストを
        分けたい、という場合を考えてみてください。</p>
    
          <div class="example"><p><code>
            SetEnvIf Accept-Language "en" english<br />
            CustomLog logs/english_log common env=english<br />
            CustomLog logs/non_english_log common env=!english
          </code></p></div>
    
        <p>ここまででは条件付きロギングが非常に強力で柔軟であることを示してきましたが、
        それがログの内容を制御する唯一の方法というわけではありません。ログファイルは
        サーバの活動の完全な記録である方がより役に立ちます。単純にログファイルを
        後処理して、考慮したくないログを削除する方が簡単であることがよくあります。</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rotation" id="rotation">ログの交替</a></h2>
        
    
        <p>普通の負荷のサーバでさえ、ログファイルに保存される情報の量は
        膨大になります。アクセスログのファイルは普通 10,000 リクエスト毎に
        1 MB 以上増えます。ですから、既存のログを移動したり、削除したりして、
        定期的にログを交替させることが必要になります。これはサーバの実行中には
        行なえません。というのは、Apache はファイルが open されている間は
        ずっと古いログファイルに書き続けるからです。
        新しいログファイルを open できるように、ログファイルが移動されたり
        削除された後に、サーバを<a href="stopping.html">再起動</a>する
        必要があります。</p>
    
        <p><em>優雅な</em> 再起動を行なうことで、サーバは既存のコネクションや
        処理待ちのコネクションを失うことなく新しいログファイルを open させる
        ことができます。しかし、これを実現するために、サーバは古いリクエストを
        扱っている間は古いログファイルに書き続ける必要があります。
        ですから、再起動の後ではログファイルの処理を始める前に、しばらく待たなければ
        なりません。単にログを交替させて、ディスクの節約のために古いログを
        圧縮する普通のシナリオは:</p>
    
        <div class="example"><p><code>
          mv access_log access_log.old<br />
          mv error_log error_log.old<br />
          apachectl graceful<br />
          sleep 600<br />
          gzip access_log.old error_log.old
        </code></p></div>
    
        <p>ログの交替をするもう一つの方法は<a href="#piped">パイプ経由のログ</a>を使うもので、次の節で説明されています。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="piped" id="piped">パイプ経由のログ</a></h2>
        
    
        <p>Apache httpd はエラーログとアクセスログをファイルに直接書く代わりに、
        パイプを通して別のプログラムに書き出すことができます。
        この機能により、主サーバにコードを追加することなく
        ロギングの柔軟性が非常に高まっています。パイプにログを書くためには、
        単にファイル名をパイプ文字 "<code>|</code>" に置き換え、その続きに
        標準入力からログのエントリを受けとる実行プログラムの名前を書くだけです。
        Apache はパイプ経由のログ用のプロセスをサーバの起動時に実行し、
        サーバの実行中にそのプログラムがクラッシュしたときはそれを再び
        実行します。(この最後の機能がこの技術が「信頼性のあるパイプ経由のロギング」
        と呼ばれている理由です。)</p>
    
        <p>パイプ経由のログ用のプロセスは Apache httpd の親プロセスから起動され、
        そのプロセスのユーザ ID を継承します。これは、パイプ経由のログ用の
        プログラムは普通 root として実行されることを意味します。
        ですから、プログラムを簡単で安全に保つことが非常に重要です。</p>
    
        <p>パイプ経由のログの重要な利用法は、サーバの再起動なしでログの交替を
        することです。Apache HTTP サーバにはこのための  <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> と呼ばれる簡単な
        プログラムが付属しています。たとえば、24 時間毎にログを交替させるには、
        以下のものを使うことができます:</p>
    
        <div class="example"><p><code>
          CustomLog "|/usr/local/apache/bin/rotatelogs
          /var/log/access_log 86400" common
        </code></p></div>
    
        <p>パイプの先で呼ばれるコマンド全体が引用符で囲まれていることに注目して
        ください。この例はアクセスログを使っていますが、エラーログにも同じ技術を
        使うことができます。</p>
    
        <p>似ているけれど、よりずっと柔軟な
        <a href="http://www.cronolog.org/">cronolog</a> というログ交替用の
        プログラムが外部のサイトにあります。</p>
    
        <p>条件付きロギングと同様、パイプ経由のログは非常に強力な
        道具ですが、オフラインの後処理のような、より簡単な解決方法があるときは
        使わない方が良いでしょう。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhosts" id="virtualhosts">バーチャルホスト</a></h2>
        
    
        <p>多くの <a href="vhosts/">バーチャルホスト</a> のあるサーバを実行している
        ときは、ログファイルの扱い方にいくつかの方法があります。
        まず、単独のホストのみのサーバとまったく同じようにログを使うことができます。
        ロギングディレクティブを主サーバのコンテキストの
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> セクションの外に置くことで、
        すべてのログを同じアクセスログとエラーログにログ収集することができます。
        この手法では個々のバーチャルホストの統計を簡単にとることはできません。</p>
    
        <p><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> や
        <code class="directive"><a href="./mod/mod_log_config.html#errorlog">ErrorLog</a></code> ディレクティブが
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> の中に
        置かれた場合は、そのバーチャル
        ホストへのすべてのリクエストやエラーがそこで指定されたファイルにのみ
        ログ収集されます。ロギングディレクティブのないバーチャルホストは
        依然としてリクエストが主サーバのログに送られます。この手法は少ない
        バーチャルホストに対しては非常に有用ですが、ホストの数が非常に多くなると
        管理が大変になります。さらに、<a href="vhosts/fd-limits.html">ファイル記述子の限界</a>の問題を起こすことが
        あります。</p>
    
        <p>アクセスログには、非常に良い妥協案があります。バーチャルホストの
        情報をログのフォーマット文字列に加えることで、すべてのホストへの
        リクエストを同じログにログ収集して、後でログを個々のファイルに分割することが
        できます。たとえば、以下のディレクティブを見てください。</p>
    
        <div class="example"><p><code>
          LogFormat "%v %l %u %t \"%r\" %&gt;s %b"
          comonvhost<br />
          CustomLog logs/access_log comonvhost
        </code></p></div>
    
        <p><code>%v</code> がリクエストを扱っているバーチャルホストの名前を
        ログ収集するために使われています。そして、<a href="programs/other.html">split-logfile</a> のようなプログラムを
        使ってアクセスログを後処理することで、
        バーチャルホスト毎のファイルにログを分割することができます。</p>
    
        <p>残念ながら、エラーログには同様の手法はありません。ですから、
        すべてのバーチャルホストを同じエラーログの中に混ぜるか、
        バーチャルホスト毎にエラーログを使うかを選ばなければなりません。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">他のログファイル</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code></li><li><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_log_forensic.html#forensiclog">ForensicLog</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritelog">RewriteLog</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriteloglevel">RewriteLogLevel</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlogbuffer">ScriptLogBuffer</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptloglength">ScriptLogLength</a></code></li></ul></td></tr></table>
    
        <h3>実際に送受信したバイト数のログ</h3>
          
    
          <p><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code> は、
             ネットワーク上で実際に送受信した数をログする
             二つのフィールド (%I と %O) を
             <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> 
             ディレクティブに追加します。</p>
        
    
        <h3>Forensic ログ</h3>
          
    
          <p><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code> はクライアントリクエストの
             forensic ログを取ります。ログはリクエスト処理前と処理後に
             行われますので、1 リクエストに対して 2 行のログが出力されます。
             forensic ロガーはとても厳密でカスタマイズできません。
             デバッグやセキュリティ用のツールとして有効かもしれません。</p>
        
    
        <h3><a name="pidfile" id="pidfile">PID ファイル</a></h3>
          
    
          <p>起動時に、Apache は親 httpd プロセスのプロセス ID を
          <code>logs/httpd.pid</code> に保存します。この
          ファイル名は <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> ディレクティブを使って
          変更することができます。プロセス ID は管理者が親プロセスに
          シグナルを送ることでデーモンを再起動したり終了させたりするときに
          使用します。Windows では、代わりに -k コマンドオプションを
          使ってください。詳しい情報は <a href="stopping.html">終了と
          再起動</a> のページを見てください。</p>
        
    
        <h3><a name="scriptlog" id="scriptlog">スクリプトログ</a></h3>
          
    
          <p>デバッグの補助のために、<code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code> ディレクティブは
          CGI スクリプトの入力と出力を記録するようにできます。
          これはテスト用にのみ使用して、通常のサーバでは使用しないでください。
          詳しい情報は <a href="mod/mod_cgi.html">mod_cgi の文書</a> にあります。</p>
        
    
        <h3><a name="rewritelog" id="rewritelog">リライトログ</a></h3>
          
    
          <p><code class="directive"><a href="./mod/mod_rewrite.html#mod_rewrite">mod_rewrite</a></code> の強力で
          複雑な機能を
          使っているときは、ほぼいつもデバッグを簡単にするために
          <code class="directive"><a href="./mod/mod_rewrite.html#rewritelog">RewriteLog</a></code> の使用が
          必要でしょう。このログファイルにはリライトエンジンがリクエストを
          書き換える方法の詳細な解析が出力されます。詳しさの度合は <code class="directive"><a href="./mod/mod_rewrite.html#rewriteloglevel">RewriteLogLevel</a></code>
          で制御できます。</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/logs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.es��������������������������������������������������������������0000664�0001751�0001751�00000023401�14743132254�017437� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server Versi&#243;n 2.4
    Documentaci&#243;n - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a></div>
    <div id="page-content"><h1>Apache HTTP Server Versi&#243;n 2.4
    Documentaci&#243;n</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Buscar en Google" type="submit" /><input value="10" name="num" type="hidden" /><input value="es" name="hl" type="hidden" /><input value="ISO-8859-1" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Versi&#243;n 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">Notas de la versi&#243;n</a></h2>
    <ul><li><a href="new_features_2_4.html">Nuevas funcionalidades en Apache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Nuevas funcionalidades en Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">Nuevas funcionalidades en Apache 2.0</a></li>
    <li><a href="upgrading.html">Actualizar a la versi&#243;n 2.4 desde la 2.2</a></li>
    <li><a href="license.html">Licencia Apache </a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">Manual de Referencia</a></h2>
    <ul><li><a href="install.html">Compilar e Instalar</a></li>
    <li><a href="invoking.html">Ejecutando Apache</a></li>
    <li><a href="stopping.html">Parada y Reinicio de Apache</a></li>
    <li><a href="mod/quickreference.html">Directivas de configuraci&#243;n en tiempo de ejecuci&#243;n</a></li>
    <li><a href="mod/">M&#243;dulos</a></li>
    <li><a href="mpm.html">M&#243;dulos de Procesamiento M&#250;ltiple (MPM)</a></li>
    <li><a href="filter.html">Filtros</a></li>
    <li><a href="handler.html">Handlers</a></li>
    <li><a href="expr.html">Analizador de Expresiones</a></li>
    <li><a href="mod/overrides.html">Sobreescritura de la clase &#237;ndice .htaccess</a></li>
    <li><a href="programs/">Programas de Soporte y Servidor</a></li>
    <li><a href="glossary.html">Glosario</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">Gu&#237;a de Usuario</a></h2>
    <ul><li><a href="getting-started.html">Empezando</a></li>
    <li><a href="bind.html">Enlazando Direcciones y Puertos</a></li>
    <li><a href="configuring.html">Ficheros de Configuraci&#243;n</a></li>
    <li><a href="sections.html">Secciones de Configuraci&#243;n</a></li>
    <li><a href="caching.html">Almacenamiento de Contenido en Cach&#233;</a></li>
    <li><a href="content-negotiation.html">Negociaci&#243;n de Contenido</a></li>
    <li><a href="dso.html">Objetos Compartidos Din&#225;micamente (DSO)</a></li>
    <li><a href="env.html">Variables de Entorno</a></li>
    <li><a href="logs.html">Ficheros de Log</a></li>
    <li><a href="compliance.html">Cumplimiento del Protocolo HTTP</a></li>
    <li><a href="urlmapping.html">Mapeo de URLs al Sistema de Ficheros</a></li>
    <li><a href="misc/perf-tuning.html">Optimizaci&#243;n del Rendimiento</a></li>
    <li><a href="misc/security_tips.html">Consejos de seguridad</a></li>
    <li><a href="server-wide.html">Configuraci&#243;n b&#225;sica del Servidor</a></li>
    <li><a href="ssl/">Cifrado SSL/TLS</a></li>
    <li><a href="suexec.html">Ejecuci&#243;n de Suexec para CGI</a></li>
    <li><a href="rewrite/">Reescritura de URL con mod_rewrite</a></li>
    <li><a href="vhosts/">Servidores Virtuales</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">How-To / Tutoriales</a></h2>
    <ul><li><a href="howto">&#205;ndice de Tutoriales </a></li>
    <li><a href="howto/auth.html">Autenticaci&#243;n y Autorizaci&#243;n</a></li>
    <li><a href="howto/access.html">Control de Acceso</a></li>
    <li><a href="howto/cgi.html">CGI: Contenido Din&#225;mico</a></li>
    <li><a href="howto/htaccess.html">Ficheros .htaccess</a></li>
    <li><a href="howto/ssi.html">Inclusiones del Lado del Servidor (SSI)</a></li>
    <li><a href="howto/public_html.html">Directorios Web por Usuario
        (public_html)</a></li>
    <li><a href="howto/reverse_proxy.html">Gu&#237;a de configuraci&#243;n de Proxy Inverso</a></li>
    <li><a href="howto/http2.html">Gu&#237;a HTTP/2 </a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">Notas Sobre Plataformas Espec&#237;ficas</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">Sistemas Basados en RPM (Redhat / CentOS / Fedora)</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">Otros Temas</a></h2>
    <ul><li><a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a></li>
    <li><a href="sitemap.html">Mapa del Sitio</a></li>
    <li><a href="developer/">Documentaci&#243;n para Desarrolladores</a></li>
    <li><a href="http://httpd.apache.org/docs-project/">Contribuir en la Documentaci&#243;n</a></li>
    <li><a href="misc/">Otras Notas</a></li>
    <li><a href="http://wiki.apache.org/httpd/">Wiki</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/mpm.html.tr.utf8�����������������������������������������������������������0000664�0001751�0001751�00000034301�14743132254�020025� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Çok Süreçlilik Modülleri (MPM’ler) - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Çok Süreçlilik Modülleri (MPM’ler)</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
      <p>Bu belgede Çok Süreçlilik Modülü denince ne anlaşıldığı ve bunların
        Apache HTTP Sunucusu tarafından nasıl kullanıldıkları açıklanmıştır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Giriş</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#defaults">Öntanımlı MPM’ler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#static">Bir MPM'i bir duruk modül olarak derlemek</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#dynamic">Bir MPM'i bir DSO modülü olarak derlemek</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Giriş</a></h2>
    
        <p>Apache HTTP Sunucusu çok çeşitli platformlar üstünde farklı ortamlarda
          çalışabilen güçlü ve esnek bir HTTP sunucusu olarak tasarlanmıştır.
          Farklı platformlar ve farklı ortamlar çoğunlukla farklı özellikler veya
          aynı özelliğin en yüksek verimlilikle gerçeklenmesi için farklı yöntemler
          gerektirir. Apache httpd, geniş ortam çeşitliliğini daima modüler
          tasarımı sayesinde uzlaştırmıştır.  Bu tasarım, site yöneticilerine,
          sunucularında bulunmasını istedikleri özellikleri derleme sırasında veya
          çalışma anında gerekli modülleri yüklemek suretiyle seçebilme imkanı
          verir.</p>
    
        <p>Apache HTTP Sunucusu 2.0, bu modüler tasarımı sunucunun en temel
          işlevlerine kadar indirmiştir. Sunucu, Çok Süreçlilik Modülleri adı
          verilen ve makine üzerindeki ağ portlarının bağlanmasından, isteklerin
          kabul edilmesinden ve bu istekleri yanıtlayacak çocuklara dağıtmaktan
          sorumlu olan modüllerin seçimine imkan verecek bir yapılanma ile
          gelir.</p>
    
        <p>Sunucunun modüler tasarımının bu seviyede genişletilmesi iki önemli
          yarar sağlar:</p>
    
        <ul>
          <li>Apache httpd geniş çeşitlilikteki işletim sistemlerini daha temiz ve
            daha verimli bir şekilde destekleyebilmektedir. Özellikle,
            <code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code> modülü, Apache httpd 1.3’te kullanılan POSIX
            katmanının yerine işletim sistemine özgü özellikleri
            kullanabildiğinden, Apache HTTP Sunucusunun Windows sürümü artık çok
            daha verimli bir duruma gelmiştir. Aynı fayda özelleştirilmiş MPM’lerle
            diğer işletim sistemlerine de sağlanmıştır.</li>
    
          <li>Sunucu, belli bir sitenin ihtiyaçlarına uygun olarak daha iyi
            kişiselleştirilebilmektedir. Örneğin, eski yazılım ile uyumluluk ve
            kararlılığa önem veren siteler <code class="module"><a href="./mod/prefork.html">prefork</a></code> modülünü
            kullanabilirken, daha geniş ölçeklenebilirlik gerektiren siteler
            <code class="module"><a href="./mod/worker.html">worker</a></code> veya <code class="module"><a href="./mod/event.html">event</a></code> gibi evreli MPM
            modüllerinden birini seçebilmektedir.</li>
        </ul>
    
        <p>Kullanıcı açısından MPM’lerin diğer Apache httpd modüllerinden görünüşte
          bir farkı yoktur. Asıl fark sunucuya yüklenebilecek azami MPM modülü
          sayısının bir ve yalnız bir olarak sınırlanmış olmasıdır. Mevcut MPM
          modülleri <a href="mod/">modül dizini</a> sayfasında listelenmiştir.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="defaults" id="defaults">Öntanımlı MPM’ler</a></h2>
    
        <p>Aşağıdaki tabloda çeşitli işletim sistemlerinde öntanımlı olan MPM’ler
          listelenmiştir. Derleme sırasında başka bir seçim yapmadığınız takdirde
          bu işletim sistemlerinde bu MPM’ler seçilmiş olacaktır.</p>
    
        <table class="bordered"><tr><td>Netware</td><td><code class="module"><a href="./mod/mpm_netware.html">mpm_netware</a></code></td></tr>
    <tr class="odd"><td>OS/2</td><td><code class="module"><a href="./mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
    <tr><td>Unix</td><td>Platformun yapabildiklerine bağlı olarak,
            <code class="module"><a href="./mod/prefork.html">prefork</a></code>, <code class="module"><a href="./mod/worker.html">worker</a></code> veya
            <code class="module"><a href="./mod/event.html">event</a></code></td></tr>
    <tr class="odd"><td>Windows</td><td><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code></td></tr>
    </table>
    
        <div class="note"><p>'Unix' burada Unix benzeri işletim sistemleri anlamında
          kullanılmıştır (örn, Linux, BSD, Solaris, Mac OS X, vb.</p></div>
    
        <p>Unix durumunda, hangi MPM'nin kurulacağı kararı şu 2 soruya verilecek
          yanıta bağlıdır:</p>
        <p>1. Sistem evreleri destekliyor mu?</p>
        <p>2. Sistem evreleri "thread-safe polling" anlamında destekliyor mu
          (özellikle kqueue ve epoll işlevlerini)?</p>
    
        <p>Her iki soruya da verilen yanıt 'evet' ise, öntanımlı MPM'niz
          <code class="module"><a href="./mod/event.html">event</a></code> modülüdür.</p>
    
        <p>Birincinin yanıtı 'evet' ikincinin 'hayır' ise öntanımlı MPM'niz
          <code class="module"><a href="./mod/worker.html">worker</a></code> modülüdür.</p>
    
        <p>Yanıtların her ikisi de 'hayır' ise öntanımlı MPM'niz
          <code class="module"><a href="./mod/prefork.html">prefork</a></code> modülüdür.</p>
    
        <p>Uygulamada, günümüzdeki işletim sistemlerinin tümü bu iki özelliği
          desteklediğinden öntanımlı MPM'niz hemen hemen daima
          <code class="module"><a href="./mod/event.html">event</a></code> modülü olacaktır.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="static" id="static">Bir MPM'i bir duruk modül olarak derlemek</a></h2>
    
        <p>MPM'ler tüm platformlarda duruk (static) modüller olarak derlenebilir.
          Derleme sırasında tek bir modül seçilir ve sunucu ile ilintilenir. MPM
          değiştirilmek istenirse sunucunun yeniden derlenmesi gerekir.</p>
    
        <p>Öntanımlı MPM seçimin değiştirmek için <code class="program"><a href="./programs/configure.html">configure</a></code>
          betiğinin <code>--with-mpm=<em>AD</em></code> seçeneği kullanılır.
          Buradaki <em>AD</em> istenen MPM'in ismidir.</p>
    
        <p>Sunucu bir kere derlendi mi, hangi MPM'in seçilmiş olduğunu
          <code>./httpd -l</code> komutuyla öğrenebilirsiniz. Bu komut, içerilen
          MPM dahil, sunucu içinde derlenmiş bütüm modülleri listeler.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dynamic" id="dynamic">Bir MPM'i bir DSO modülü olarak derlemek</a></h2>
    
        <p>Unix ve benzeri platformlarda, MPM'ler DSO modülleri olarak derlenebilir
          ve diğer DSO modülleri gibi sunucuya devingen olarak yüklenebilir. DSO
          modülü olarak derlenen MPM'ler, sunucunun yeniden derlenmesini
          gerektirmeden <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesi
          güncellenerek değiştirilebilir.</p>
    
        <pre class="prettyprint lang-config">LoadModule mpm_prefork_module modules/mod_mpm_prefork.so</pre>
    
    
        <p><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesini birden
          fazla MPM için kullanmak sunucunun başlatılması sırasında aşağıdaki
          hatanın oluşmasına sebep olur.</p>
    
        <div class="example"><p><code>AH00534: httpd: Configuration error: More than one MPM
        loaded.</code></p></div>
    
        <p>Bu özellik <code class="program"><a href="./programs/configure.html">configure</a></code> betiğinin
          <code>--enable-mpms-shared</code> seçeneği ile etkinleştirilebilir.
          <code><em>all</em></code> değeri belirtilerek platform için
          kullanılabilen tüm modüller kurulur. İstenirse, değer olarak bir MPM
          listesi de belirtilebilir.</p>
    
        <p>Özdevinimli olarak seçilerek veya  <code class="program"><a href="./programs/configure.html">configure</a></code> betiğine
          <code>--with-mpm</code> seçeneğiyle belirtilerek seçilen öntanımlı MPM
          üretilen sunucu yapılandırma dosyasıyla yüklenir. Farklı bir MPM seçmek
          için MPM'i <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesinde
          belirtin.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/mpm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.ja.utf8���������������������������������������������������������0000664�0001751�0001751�00000023070�14743132254�020311� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP サーバ バージョン 2.4
    ドキュメント - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a></div>
    <div id="page-content"><h1>Apache HTTP サーバ バージョン 2.4
    ドキュメント</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Google 検索" type="submit" /><input value="10" name="num" type="hidden" /><input value="ja" name="hl" type="hidden" /><input value="UTF-8" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="バージョン 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">リリースノート</a></h2>
    <ul><li><a href="new_features_2_4.html">Apache 2.3/2.4 の新機能</a></li>
    <li><a href="new_features_2_2.html">Apache 2.1/2.2 の新機能</a></li>
    <li><a href="new_features_2_0.html">Apache 2.0 の新機能</a></li>
    <li><a href="upgrading.html">2.2 から 2.4 へのアップグレード</a></li>
    <li><a href="license.html">Apache ライセンス</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">リファレンスマニュアル</a></h2>
    <ul><li><a href="install.html">コンパイルとインストール</a></li>
    <li><a href="invoking.html">起動</a></li>
    <li><a href="stopping.html">終了と再起動</a></li>
    <li><a href="mod/quickreference.html">実行の設定用ディレクティブ</a></li>
    <li><a href="mod/">モジュール</a></li>
    <li><a href="mpm.html">マルチプロセッシングモジュール (MPM)</a></li>
    <li><a href="filter.html">フィルタ</a></li>
    <li><a href="handler.html">ハンドラ</a></li>
    <li><a href="expr.html">Expression parser</a></li>
    <li><a href="programs/">サーバとサポートプログラム</a></li>
    <li><a href="glossary.html">用語集</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">ユーザの手引</a></h2>
    <ul><li><a href="getting-started.html">Getting Started</a></li>
    <li><a href="bind.html">アドレスとポートのバインド</a></li>
    <li><a href="configuring.html">設定ファイル</a></li>
    <li><a href="sections.html">セクションの設定</a></li>
    <li><a href="caching.html">キャッシュ機能</a></li>
    <li><a href="content-negotiation.html">コンテントネゴシエーション</a></li>
    <li><a href="dso.html">動的共有オブジェクト (DSO)</a></li>
    <li><a href="env.html">環境変数</a></li>
    <li><a href="logs.html">ログファイル</a></li>
    <li><a href="urlmapping.html">URL をファイルシステムにマップする</a></li>
    <li><a href="misc/perf-tuning.html">性能に関する調整</a></li>
    <li><a href="misc/security_tips.html">セキュリティ情報</a></li>
    <li><a href="server-wide.html">サーバ全体の設定</a></li>
    <li><a href="ssl/">SSL/TLS による暗号化</a></li>
    <li><a href="suexec.html">CGI の Suexec 実行</a></li>
    <li><a href="rewrite/">mod_rewriteによる URL Rewriting</a></li>
    <li><a href="vhosts/">バーチャルホスト</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">How-To / チュートリアル</a></h2>
    <ul><li><a href="howto/auth.html">認証、承認、アクセス制御
        </a></li>
    <li><a href="howto/cgi.html">CGI: 動的コンテンツ</a></li>
    <li><a href="howto/htaccess.html">.htaccess ファイル</a></li>
    <li><a href="howto/ssi.html">Server Side Includes (SSI)</a></li>
    <li><a href="howto/public_html.html">ユーザ専用ディレクトリ
        (public_html)</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">プラットフォーム固有の情報</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">RPMベースのシステム (Redhat / CentOS / Fedora)</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC 版</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">その他</a></h2>
    <ul><li><a href="http://wiki.apache.org/httpd/FAQ">よくある質問 (FAQ)</a></li>
    <li><a href="sitemap.html">サイトマップ</a></li>
    <li><a href="developer/">開発者のためのドキュメント</a></li>
    <li><a href="http://httpd.apache.org/docs-project/">ドキュメンテーションプロジェクトへの協力</a></li>
    <li><a href="misc/">その他</a></li>
    <li><a href="http://wiki.apache.org/httpd/">ウィキ</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.pt-br�����������������������������������������������������������0000664�0001751�0001751�00000022406�14743132254�020060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="pt-br" xml:lang="pt-br"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Documenta&#231;&#227;o do Servidor HTTP Apache Vers&#227;o
    2.4 - Servidor HTTP Apache Vers&#227;o 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Gloss&#225;rio</a> | <a href="./sitemap.html">Mapa do site</a></p>
    <p class="apache">Servidor HTTP Apache Vers&#227;o 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documenta&#231;&#227;o</a></div>
    <div id="page-content"><h1>Documenta&#231;&#227;o do Servidor HTTP Apache Vers&#227;o
    2.4</h1>
    <div class="toplang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta tradu&#231;&#227;o pode estar desatualizada.
            Confira a vers&#227;o em Ingl&#234;s para mudan&#231;as recentes.</div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Busca Google" type="submit" /><input value="10" name="num" type="hidden" /><input value="pt-br" name="hl" type="hidden" /><input value="ISO-8859-1" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Vers&#227;o 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">Notas da Vers&#227;o</a></h2>
    <ul><li><a href="new_features_2_4.html">Novas funcionalidades no Apache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Novas funcionalidades no Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">Novas funcionalidades no Apache 2.0</a></li>
    <li><a href="upgrading.html">Atualizando da vers&#227;o 2.2 para 2.4</a></li>
    <li><a href="license.html">Licen&#231;a Apache</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">Manual de Refer&#234;ncia</a></h2>
    <ul><li><a href="install.html">Compilando e Instalando</a></li>
    <li><a href="invoking.html">Iniciando</a></li>
    <li><a href="stopping.html">Parando ou Reiniciando</a></li>
    <li><a href="mod/directives.html">Diretrizes de Configura&#231;&#227;o para execu&#231;&#227;o</a></li>
    <li><a href="mod/quickreference.html">Refer&#234;ncia R&#225;pida de Diretrizes</a></li>
    <li><a href="mod/">M&#243;dulos</a></li>
    <li><a href="mpm.html">M&#243;dulos Multi-Processos (MPMs)</a></li>
    <li><a href="filter.html">Filtros</a></li>
    <li><a href="handler.html">Handlers</a></li>
    <li><a href="programs/">Servidor e Programas Suportados</a></li>
    <li><a href="glossary.html">Gloss&#225;rio</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">Guia do Usu&#225;rio</a></h2>
    <ul><li><a href="bind.html">Portas de escuta</a></li>
    <li><a href="configuring.html">Arquivos de Configura&#231;&#227;o</a></li>
    <li><a href="sections.html">Se&#231;&#245;es de Configura&#231;&#227;o</a></li>
    <li><a href="caching.html">Cach&#234; de Conte&#250;do</a></li>
    <li><a href="content-negotiation.html">Negocia&#231;&#227;o de Conte&#250;do</a></li>
    <li><a href="dso.html">Objetos Din&#226;micos Compartilhados (DSO)</a></li>
    <li><a href="env.html">Vari&#225;veis de Ambiente</a></li>
    <li><a href="logs.html">Arquivos de Registro</a></li>
    <li><a href="urlmapping.html">Mapeando URLs para o Sistema de Arquivos</a></li>
    <li><a href="misc/perf-tuning.html">Ajustes de Performance</a></li>
    <li><a href="misc/security_tips.html">Dicas de Seguran&#231;a</a></li>
    <li><a href="server-wide.html">Configura&#231;&#245;es Globais do Servidor</a></li>
    <li><a href="ssl/">Encriptamento SSL/TLS</a></li>
    <li><a href="suexec.html">Execu&#231;&#227;o Suexec para CGI</a></li>
    <li><a href="rewrite/">Guia para Reescrever URL</a></li>
    <li><a href="vhosts/">Hosting Virtuais</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">How-To / Tutoriais</a></h2>
    <ul><li><a href="howto/auth.html">Autentica&#231;&#227;o, Autoriza&#231;&#227;o, e 
        Controle de Acesso</a></li>
    <li><a href="howto/cgi.html">CGI: Conte&#250;do Din&#226;mico</a></li>
    <li><a href="howto/htaccess.html">Arquivos .htaccess</a></li>
    <li><a href="howto/ssi.html">Server Side Includes (SSI)</a></li>
    <li><a href="howto/public_html.html">Diret&#243;rios Web para usu&#225;rios individuais
        (public_html)</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">Notas Espec&#237;ficas para diferentes Platformas</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC Port</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">Outros T&#243;picos</a></h2>
    <ul><li><a href="faq/">Perguntas Mais Frequentes</a></li>
    <li><a href="sitemap.html">Mapa do Site</a></li>
    <li><a href="developer/">Documenta&#231;&#227;o para Desenvolvedores</a></li>
    <li><a href="misc/">Outras Notas</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licenciado sob a <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Gloss&#225;rio</a> | <a href="./sitemap.html">Mapa do site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�016205� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/ssi.html.fr.utf8�����������������������������������������������������0000664�0001751�0001751�00000067264�14740503670�021173� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Tutoriel Apache httpd : Introduction aux "Inclusions Côté Serveur"
    (Server Side Includes - SSI) - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Recettes et tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Tutoriel Apache httpd : Introduction aux "Inclusions Côté Serveur"
    (Server Side Includes - SSI)</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    
    <p>Les SSI permettent d'ajouter du contenu dynamique à des documents
    HTML préexistants.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">Qu'est-ce que SSI ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">Configurer votre serveur pour permettre les SSI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic">Directives SSI de base</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#additionalexamples">Exemples additionnels</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">Que puis-je configurer d'autre ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exec">Exécution de commandes</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#advanced">Techniques SSI avancées</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#conclusion">Conclusion</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Introduction</a></h2>
     <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code></li><li><code class="directive"><a href="../mod/core.html#setoutputfilter">SetOutputFilter</a></code></li><li><code class="directive"><a href="../mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li></ul></td></tr></table>
    
        <p>Cet article traite des Inclusions Côté Serveur (Server Side
        Includes), plus communément appelés SSI. Vous trouverez ici la
        manière de configurer votre serveur pour permettre les SSI, ainsi
        qu'une introduction à quelques techniques SSI de base permettant
        d'ajouter du contenu dynamique à vos pages HTML préexistantes.</p>
    
        <p>La dernière partie de cet article sera consacrée aux
        configurations SSI plus avancées, telles que les expressions
        conditionnelles dans les directives SSI.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">Qu'est-ce que SSI ?</a></h2>
    
        <p>SSI (Server Side Includes) est constitué de directives placées dans
        des pages HTML, et évaluées par le serveur au moment où les pages
        sont servies. Elles vous permettent d'ajouter du contenu généré
        dynamiquement à une page HTML préexistante, sans avoir à servir la
        page entière via un programme CGI, ou toute autre technologie de
        contenu dynamique.</p>
    
        <p>Par exemple, vous pouvez insérer la directive suivante dans une
        page HTML existante :</p>
    
        <div class="example"><p><code>
        &lt;!--#echo var="DATE_LOCAL" --&gt;
        </code></p></div>
    
        <p>Ainsi, lorsque la page sera servie, la directive sera évaluée et
        remplacée par sa valeur :</p>
    
        <div class="example"><p><code>
        Tuesday, 15-Jan-2013 19:28:54 EST
        </code></p></div>
    
        <p>Le choix entre l'utilisation des SSI et la génération entière de
        la page par un programme quelconque, est en général dicté par la
        proportion de contenu statique et de contenu devant être généré
        chaque fois que la page est servie. SSI est idéal pour ajouter de
        petites quantités d'information, comme l'heure courante dans
        l'exemple précédent. Mais si la
        plus grande partie de votre page est générée au moment où elle est
        servie, vous devez vous tourner vers une autre solution.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">Configurer votre serveur pour permettre les SSI</a></h2>
    
    
        <p>Pour permettre l'utilisation des SSI sur votre serveur, vous
        devez ajouter la directive suivante dans votre fichier
        <code>httpd.conf</code>, ou dans un fichier <code>.htaccess</code>
        :</p>
    <pre class="prettyprint lang-config">Options +Includes</pre>
    
    
        <p>Cette directive indique à Apache que vous désirez permettre la
        recherche de directives SSI lors de l'interprétation des fichiers.
        Notez cependant que la plupart des configurations contiennent de
        nombreuses directives <code class="directive"><a href="../mod/core.html#options">Options</a></code>
        qui peuvent s'écraser les unes les autres. Vous devrez probablement
        appliquer ces directives <code>Options</code> au répertoire
        spécifique pour lequel vous voulez activer les SSI, afin d'être sûr
        qu'elles y seront bien activées.</p>
    
        <p>Tout fichier ne fera cependant pas l'objet de recherche de
        directives SSI. Vous devez indiquer à Apache quels fichiers seront
        concernés. Vous pouvez y parvenir en indiquant une extension, comme
        <code>.shtml</code>, à l'aide des directives suivantes :</p>
    <pre class="prettyprint lang-config">AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml</pre>
    
    
        <p>Un des désavantages de cette approche réside dans le fait que si
        vous voulez ajouter des directives SSI à une page préexistante, vous
        devrez changer le nom de cette page, et donc tout lien qui la
        contient, de façon à ce qu'elle possède l'extension
        <code>.shtml</code>, condition nécessaire pour que les directives
        SSI qu'elle contient soient traitées.</p>
    
        <p>Une autre méthode consiste à utiliser la directive <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code> :</p>
    <pre class="prettyprint lang-config">XBitHack on</pre>
    
    
        <p>La directive <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>
        indique à Apache qu'il doit rechercher des directivves SSI dans les
        fichiers si leur bit d'exécution est positionné. Il n'est ainsi plus
        nécessaire de changer le nom du fichier pour ajouter des directives
        SSI à une page préexistante ; vous devez simplement attribuer les
        droits d'exécution au fichier à l'aide de <code>chmod</code>.</p>
    <div class="example"><p><code>
            chmod +x pagename.html
    </code></p></div>
    
        <p>Un bref commentaire sur ce qu'il ne faut pas faire. Certaines
        personnes peuvent vous conseiller de tout simplement indiquer à
        Apache de rechercher des directives SSI dans tous les fichiers
        <code>.html</code>, ce qui vous évite d'avoir à gérer les noms de
        fichiers avec extension <code>.shtml</code>. Ils n'ont probablement
        pas entendu parler de la directive <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>. En effet, vous devez
        garder à l'esprit qu'en faisant ceci, Apache va devoir rechercher
        des directives SSI dans chaque fichier qu'il sert, même s'il n'en
        contient aucune. Ce n'est donc pas une bonne idée car les
        performances peuvent en être sensiblement affectées.</p>
    
        <p>Bien entendu, sous Windows, il n'y a pas de bit d'exécution à
        positionner, ce qui limite un peu vos choix.</p>
    
        <p>Dans sa configuration par défaut, Apache n'envoie pas la date de
        dernière modification ou les en-têtes HTTP relatifs à la taille des
        contenus dans les pages SSI, car ses valeurs sont difficiles à
        calculer pour les contenus dynamiques. Ceci peut induire une
        impression de diminution des performances côté client, en empêchant
        la mise en cache de votre document. Il existe deux méthodes pour
        résoudre ce problème :</p>
    
        <ol>
          <li>Utilisez la configuration <code>XBitHack Full</code>. Elle
          indique à Apache de déterminer la date de dernière modification en
          ne regardant que la date du fichier à l'origine de la requête,
          tout en ignorant la date de modification de tout fichier inclus.</li>
    
          <li>Utilisez les directives fournies par le module
          <code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> pour définir de manière explicite la
          date d'expiration de vos fichiers, laissant par la-même
          aux navigateurs et aux mandataires le soin de déterminer s'il est
          opportun ou non de les mettre en cache.</li>
        </ol>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic" id="basic">Directives SSI de base</a></h2>
    
        <p>Les directives SSI adoptent la syntaxe suivante :</p>
    <div class="example"><p><code>
            &lt;!--#fonction attribut=valeur attribut=valeur ... --&gt;
    </code></p></div>
    
        <p>Le format d'une directive SSI étant similaire à celui d'un
        commentaire HTML, si vous n'avez pas activé correctement SSI, le
        navigateur l'ignorera, mais elle sera encore visible dans le source
        HTML. Si SSI est correctement configuré, la directive sera remplacée
        par ses résultats.</p>
    
        <p>"fonction" peut prendre de nombreuses formes, et nous décrirons
        plus précisément la plupart d'entre eux dans la prochaine version de
        ce document. Pour le moment, voici quelques exemples de ce que vous
        pouvez faire avec SSI.</p>
    
    <h3><a name="todaysdate" id="todaysdate">La date courante</a></h3>
    
    <div class="example"><p><code>
            &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
        <p>La fonction <code>echo</code> permet d'afficher la valeur d'une
        variable. Il existe un grand nombre de variables standards, y
        compris l'ensemble des variables d'environnement disponibles pour
        les programmes CGI. De plus, vous pouvez définir vos propres
        variables à l'aide de la fonction <code>set</code>.</p>
    
        <p>Si vous n'aimez pas le format sous lequel la date s'affiche, vous
        pouvez utiliser la fonction <code>config</code> avec un attribut
        <code>timefmt</code>, pour le modifier.</p>
    
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            Today is &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
    
    <h3><a name="lastmodified" id="lastmodified">Date de modification du fichier</a></h3>
    
    <div class="example"><p><code>
            Dernière modification du document &lt;!--#flastmod file="index.html" --&gt;
    </code></p></div>
    
        <p>Le format peut là aussi être modifié à l'aide de l'attribut
        <code>timefmt</code>.</p>
    
    
    <h3><a name="cgi" id="cgi">Inclusion des résultats d'un programme CGI</a></h3>
    
        <p>C'est le cas le plus courant d'utilisation des SSI - afficher les
        résultats d'un programme CGI, comme l'universellement adoré
        "compteur d'accès".</p>
    
    <div class="example"><p><code>
            &lt;!--#include virtual="/cgi-bin/counter.pl" --&gt;
    </code></p></div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="additionalexamples" id="additionalexamples">Exemples additionnels</a></h2>
    
    
        <p>Vous trouverez dans ce qui suit quelques exemples spécifiques de
        ce que vous pouvez faire de vos documents HTML avec SSI.</p>
    
    <h3><a name="docmodified" id="docmodified">Quand ce document a-t-il été modifié ?</a></h3>
    
        <p>Nous avons mentionné plus haut que vous pouviez utiliser SSI pour
        informer l'utilisateur de la date de dernière modification du
        document. Cependant, la méthode pour y parvenir n'a pas été vraiment
        abordée. Placé dans votre document HTML, le code suivant va insérer
        un repère de temps dans votre page. Bien entendu, SSI devra avoir
        été correctement activé, comme décrit plus haut.</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            Dernière modification du fichier &lt;!--#flastmod file="ssi.shtml" --&gt;
    </code></p></div>
    
        <p>Bien entendu, vous devez remplacer <code>ssi.shtml</code> par le
        nom du fichier auquel vous faites référence. Ceci ne conviendra pas
        si vous recherchez un morceau de code générique que vous pourrez
        insérer dans tout fichier ; dans ce cas, il est préférable
        d'utiliser la variable <code>LAST_MODIFIED</code> :</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%D" --&gt;<br />
            This file last modified &lt;!--#echo var="LAST_MODIFIED" --&gt;
    </code></p></div>
    
        <p>Pour plus de détails sur le format <code>timefmt</code>, tapez
        <code>strftime</code> dans votre moteur de recherche préferé. La
        syntaxe est identique.</p>
    
    
    <h3><a name="standard-footer" id="standard-footer">Inclusion d'un pied de page standard</a></h3>
    
    
        <p>Si le site que vous gérez comporte plus que quelques pages, vous
        allez vite vous apercevoir qu'effectuer des modifications sur toutes
        ces pages peut devenir très contraignant, en particulier si vous
        voulez qu'elles conservent un aspect homogène.</p>
    
        <p>Inclure un fichier pour un en-tête et/ou un pied de page peut
        simplifier cette corvée de mises à jour. Il vous suffit de
        confectionner un fichier de pied de page, et de l'inclure dans
        chaque page à l'aide de l'élément SSI <code>include</code>. Pour
        définir le fichier à inclure, la fonction <code>include</code> peut
        utiliser soit l'attribut <code>file</code>, soit l'attribut
        <code>virtual</code>. L'attribut <code>file</code> est un chemin de
        fichier <em>relatif au répertoire courant</em>. C'est à dire qu'il
        ne peut ni avoir pour valeur un chemin absolu (commençant par /), ni
        comporter "../" dans son chemin. L'attribut <code>virtual</code> est
        probablement plus commode, et peut spécifier une URL relative au
        document servi. Elle peut commencer par un /, mais le fichier inclus
        et le fichier servi doivent résider sur le même serveur.</p>
    <div class="example"><p><code>
            &lt;!--#include virtual="/footer.html" --&gt;
    </code></p></div>
    
        <p>Je combinerai souvent ces deux derniers points, en ajoutant une
        directive <code>LAST_MODIFIED</code> dans un fichier de pied de page
        destiné à être inclus. Le fichier inclus peut contenir des
        directives SSI, et les inclusions peuvent être imbriquées - à
        savoir, le fichier inclus peut inclure un autre fichier, etc...</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">Que puis-je configurer d'autre ?</a></h2>
    
    
        <p>En plus du format de date, vous pouvez utiliser l'élément
        <code>config</code> pour configurer deux autres choses.</p>
    
        <p>En général, lorsque quelque chose se passe mal avec votre
        directive SSI, vous recevez le message :</p>
    <div class="example"><p><code>
            [an error occurred while processing this directive]
    </code></p></div>
    
        <p>Pour modifier ce message, vous pouvez utiliser l'attribut
        <code>errmsg</code> avec la fonction <code>config</code> :</p>
    <div class="example"><p><code>
            &lt;!--#config errmsg="[Il semblerait que vous ne sachiez pas
    	utiliser les SSI]" --&gt;
    </code></p></div>
    
        <p>Il est cependant probable que les utilisateurs finaux ne voient
        jamais ce message, car vous aurez résolu tous les problèmes issus de
        vos directives SSI avant que votre site ne soit mis en production.
        (N'est-ce pas ?)</p>
    
        <p>Vous pouvez aussi modifier le format sous lequel les tailles de
        fichiers sont affichées à l'aide de l'attribut <code>sizefmt</code>.
        Vous pouvez spécifier <code>bytes</code> pour un affichage en
        octets, ou <code>abbrev</code> pour un affichage plus concis en Ko
        ou Mo, selon le cas.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exec" id="exec">Exécution de commandes</a></h2>
        
    
        <p>Voici autre chose que vous pouvez faire avec la fonction
        <code>exec</code>. Vous pouvez vraiment faire exécuter une commande
        par SSI en utilisant le shell (<code>/bin/sh</code>, pour être plus
        précis - ou le shell DOS, si vous êtes sous Win32). Par exemple, ce
        qui suit vous permet d'afficher le contenu d'un répertoire.</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="ls" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>ou, sous Windows</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="dir" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>Vous noterez probablement l'étrange formatage provoqué par cette
        directive sous Windows, car la sortie de <code>dir</code> contient
        la chaîne  de caractères "&lt;<code>dir</code>&gt;", ce qui trompe le
        navigateur.</p>
    
        <p>Notez que cette fonctionnalité est très dangereuse, car elle va
        permettre d'exécuter tout code associé à l'élément
        <code>exec</code>. Si vous êtes dans la situation où les
        utilisateurs peuvent éditer le contenu de vos pages web, dans le cas
        d'un "livre d'or" par exemple, assurez-vous de désactiver cette
        fonctionnalité. Vous pouvez, tout en permettant les SSI, désactiver
        la fonctionnalité <code>exec</code> à l'aide de l'argument
        <code>IncludesNOEXEC</code> de la directive
        <code>Options</code>.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advanced" id="advanced">Techniques SSI avancées</a></h2>
    
    
        <p>Outre l'affichage de contenu, les SSI d'Apache vous permettent de
        définir des variables, et de les utiliser dans des comparaisons et
        des conditions.</p>
    
    <h3><a name="variables" id="variables">Définition de variables</a></h3>
    
        <p>Avec l'élément <code>set</code>, vous pouvez définir des
        variables pour un usage ultérieur. Comme nous en aurons besoin plus
        loin, nous allons en parler tout de suite. La syntaxe se présente
        comme suit :</p>
    <div class="example"><p><code>
            &lt;!--#set var="name" value="Rich" --&gt;
    </code></p></div>
    
        <p>Pour affecter une valeur à vos variables, en plus de la
        définition littérale de l'exemple ci-dessus, vous pouvez utiliser
        une autre variable, y compris les <a href="../env.html">variables d'environnement</a>, ou les variables
        décrites plus haut (comme <code>LAST_MODIFIED</code> par exemple).
        Pour indiquer qu'il s'agit d'une variable et non d'une chaîne, vous
        devez utiliser le symbole dollar ($) devant le nom de la
        variable.</p>
    
        <div class="example"><p><code> &lt;!--#set var="modified" value="$LAST_MODIFIED" --&gt;
        </code></p></div>
    
        <p>Pour insérer un caractère $ dans la valeur de votre variable,
        vous devez l'échapper à l'aide d'un backslash.</p>
    <div class="example"><p><code>
            &lt;!--#set var="cost" value="\$100" --&gt;
    </code></p></div>
    
        <p>Enfin, si vous voulez insérer une variable dans une chaîne, et
        s'il y a une chance pour que le nom de la variable se confonde avec
        le reste de la chaîne, vous pouvez l'entourer d'accolades pour
        eviter toute confusion (Il est difficile de trouver un bon exemple
        pour illustrer ceci, mais j'espère que vous comprendrez).</p>
    <div class="example"><p><code>
            &lt;!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --&gt;
    </code></p></div>
    
    
    <h3><a name="conditional" id="conditional">Expressions conditionnelles</a></h3>
    
    
        <p>Maintenent que nous avons des variables, et que nous pouvons
        définir et comparer leurs valeurs, nous sommes à même de les
        utiliser dans des expressions conditionnelles. Ceci confère à SSI le
        statut de petit langage de programmation.
        <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> fournit une structure <code>if</code>,
        <code>elif</code>, <code>else</code>, <code>endif</code> pour la
        construction d'expressions conditionnelles, ce qui vous permet de
        générer plusieurs pages logiques à partir d'une seule vraie
        page.</p>
    
        <p>La structure de l'expression conditionnelle est :</p>
    <div class="example"><p><code>
        &lt;!--#if expr="condition" --&gt;<br />
        &lt;!--#elif expr="condition" --&gt;<br />
        &lt;!--#else --&gt;<br />
        &lt;!--#endif --&gt;
    </code></p></div>
    
        <p>Une <em>condition</em> peut revêtir la forme de toute comparaison
        logique - soit une comparaison de valeurs avec une autre, soit une
        vérification de la "vérité" d'une valeur particulière (Une chaîne
        donnée est vraie si elle n'est pas vide). Pour une liste exhaustive
        des opérateurs de comparaison disponibles, voir la documentation du
        module <code class="module"><a href="../mod/mod_include.html">mod_include</a></code>.</p>
    
        <p>Par exemple, spour insérer l'heure du jour dans votre page web,
        vous pouvez ajouter ces lignes dans la page HTML :</p>
    
        <div class="example"><p><code>
        Good
        &lt;!--#if expr="%{TIME_HOUR} &lt;12" --&gt;<br />
        morning!<br />
        &lt;!--#else --&gt;<br />
        afternoon!<br />
        &lt;!--#endif --&gt;<br />
        </code></p></div>    
    
        <p>Toute autre variable (que vous avez définie, ou une variable
        d'environnement normale) peut être utilisée dans les expressions
        conditionnelles. Voir le document <a href="../expr.html">Expressions
        rationnelles dans le serveur HTTP Apache</a> pour plus de détails à
        propos du fonctionnement du moteur d'évaluation des expressions
        rationnelles.</p>
        
        <p>Associée à la possibilité avec Apache de définir
        des variables d'environnement à l'aide de directives
        <code>SetEnvIf</code>, ainsi que d'autres directives en rapport,
        cette fonctionnalité vous permet d'ajouter une grande variété
        de contenus dynamiques côté serveur sans avoir à concevoir une
        application web de A à Z.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="conclusion" id="conclusion">Conclusion</a></h2>
    
        <p>SSI ne remplace certainement pas CGI, ou d'autres technologies
        utilisées pour la génération de pages web dynamiques. Mais c'est une
        bonne méthode pour ajouter des petits contenus dynamiques à vos
        pages, sans devoir fournir un gros effort supplémentaire.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/ssi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/ssi.html.es����������������������������������������������������������0000664�0001751�0001751�00000067022�14743132254�020275� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Tutorial de Apache httpd: Introducci&#243;n a los Server Side Includes
     - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a> &gt; <a href="./">How-To / Tutoriales</a></div><div id="page-content"><div id="preamble"><h1>Tutorial de Apache httpd: Introducci&#243;n a los Server Side Includes
    </h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    
    <p>Los Server Side Includes (Inclusiones en la parte Servidor) facilitan un m&#233;todo para a&#241;adir contenido din&#225;mico a documentos HTML existentes.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Introducci&#243;n</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">&#191;Qu&#233; son los SSI?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">Configurar su servidor para permitir SSI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic">Directivas SSI b&#225;sicas</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#additionalexamples">M&#225;s ejemplos</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">&#191;Qu&#233; m&#225;s puedo configurar?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exec">Ejecutando comandos</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#advanced">T&#233;cnicas avanzadas de SSI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#conclusion">Conclusi&#243;n</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Introducci&#243;n</a></h2>
     <table class="related"><tr><th>M&#243;dulos Relacionados</th><th>Directivas Relacionadas</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code></li><li><code class="directive"><a href="../mod/core.html#setoutputfilter">SetOutputFilter</a></code></li><li><code class="directive"><a href="../mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li></ul></td></tr></table>
    
        <p>Este art&#237;culo trata sobre los Server Side Includes, generalmente llamados SSI.
         En este art&#237;culo, hablaremos sobre c&#243;mo configurar su servidor para permitir SSI,
          y de t&#233;cnicas b&#225;sicas de SSI para a&#241;adir contenido din&#225;mico a sus p&#225;ginas 
          HTML existentes.</p>
    
        <p>M&#225;s adelante tambi&#233;n hablaremos de algunas t&#233;cnicas m&#225;s avanzadas que 
        pueden usarse con SSI, tales como declaraciones condicionales en sus directivas SSI.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">&#191;Qu&#233; son los SSI?</a></h2>
    
        <p>SSI (Server Side Includes) son directivas que se introducen en p&#225;ginas HTML y son 
            evaluadas por el servidor mientras &#233;ste las sirve. Le permiten a&#241;adir 
            contenido generado de manera din&#225;mica a sus p&#225;ginas HTML existentes sin tener 
            que servir una p&#225;gina entera a trav&#233;s de un programa CGI, u otra tecnolog&#237;a 
            para generar contenido din&#225;mico.</p>
    
        <p>Por ejemplo, podr&#237;a colocar una directiva en una p&#225;gina existente de HTML 
            de esta manera:</p>
    
        <div class="example"><p><code>
        &lt;!--#echo var="DATE_LOCAL" --&gt;
        </code></p></div>
    
        <p>Y, cuando se sirve la p&#225;gina, este fragmento ser&#225; evaluado y sustituido con su resultado:</p>
    
        <div class="example"><p><code>
        Tuesday, 15-Jan-2013 19:28:54 EST
        </code></p></div>
    
        <p>La decisi&#243;n sobre cu&#225;ndo usar SSI, o de cu&#225;ndo generar una p&#225;gina al completo con alg&#250;n programa, suele depender generalmente de la cantidad de contenido est&#225;tico que contiene, y cu&#225;nto de esa p&#225;gina tiene que ser recalculado cada vez que &#233;sta se sirve. SSI es un buen m&#233;todo para a&#241;adir peque&#241;as partes de informaci&#243;n, tales como la hora actual - como se ha mostrado m&#225;s arriba. Pero si la mayor&#237;a de su p&#225;gina se tiene que generar en el momento en el que se est&#225; sirviendo, necesita buscar otra opci&#243;n m&#225;s adecuada que no sea SSI.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">Configurar su servidor para permitir SSI</a></h2>
    
    
        <p>Para permitir SSI en su servidor, debe tener la siguiente directiva en su fichero <code>httpd.conf</code> , o en un fichero 
        <code>.htaccess</code>:</p>
    <pre class="prettyprint lang-config">Options +Includes</pre>
    
    
        <p>Esto le dice a Apache que quiere permitir que se examinen los ficheros buscando directivas SSI. Tenga en cuenta que la mayor&#237;a de las configuraciones contienen m&#250;ltiples directivas <code class="directive"><a href="../mod/core.html#options">Options</a></code> que pueden sobreescribirse las unas a las otras. Probablemente necesitar&#225; aplicar <code>Options</code> al directorio espec&#237;fico donde quiere SSI activado para asegurarse de que se eval&#250;a en &#250;ltimo lugar y por tanto se acabar&#225; aplicando.</p>
    
        <p>No todos los ficheros se examinan buscando directivas SSI. Usted Le tiene que indicar a Apache qu&#233; ficheros se tienen que examinar. Hay dos formas de hacer esto. Puede decirle a Apache que examine cualquier fichero con una extensi&#243;n determinada, como por ejemplo <code>.shtml</code>, con las siguientes directivas:</p>
    <pre class="prettyprint lang-config">AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml</pre>
    
    
        <p>Una desventaja de este m&#233;todo es que si quisiera a&#241;adir directivas SSI a una p&#225;gina ya existente, tendr&#237;a que cambiar el nombre de la p&#225;gina, y todos los enlaces que apuntasen a esa p&#225;gina, todo para poder darle la extensi&#243;n <code>.shtml</code> y que esas directivas sean interpretadas.</p>
    
        <p>El otro m&#233;todo es usar la directiva <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code> :</p>
    <pre class="prettyprint lang-config">XBitHack on</pre>
    
    
        <p><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code> le dice a Apache que examine ficheros buscando directivas SSI si los ficheros tienen el bit de ejecuci&#243;n configurado. Asi que para a&#241;adir directivas SSI a una p&#225;gina existente, en lugar de tener que cambiarle el nombre, solo tendr&#237;a que convertirla en ejecutable usando <code>chmod</code>.</p>
    <div class="example"><p><code>
            chmod +x pagename.html
    </code></p></div>
    
        <p>Una breve recomendaci&#243;n de qu&#233; no hay que hacer. Ocasionalmente vemos gente recomendar que le diga a Apache que examine todos los ficheros 
        <code>.html</code> para activar SSI, para no tener que lidiar renombrando los ficheros a <code>.shtml</code>. Quiz&#225;s estas personas no hayan oido hablar de <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>. Lo que hay que tener en cuenta, es que haciendo eso, est&#225; pidiendo al Apache que lea cada uno de los ficheros que manda al cliente, incluso si no contenien directivas SSI. Esto puede ralentizar bastante el servidor, y no es una buena idea.</p>
    
        <p>Por supuesto, en Windows, no hay tal cosa como la configuraci&#243;n del bit de ejecuci&#243;n, as&#237; que esto limita las opciones un poco.</p>
    
        <p>En su configuraci&#243;n por defecto, Apache no env&#237;a la fecha de &#250;ltima modificaci&#243;n o la longitud de contenido de p&#225;ginas SSI porque es dificil calcular estos valores para contenido din&#225;mico. Esto puede impedir que se cachee un documento, y dar como resultado en apareciencia un rendimiento m&#225;s lento del cliente. Hay dos maneras de solucionar esto:</p>
    
        <ol>
          <li>Usando la configuraci&#243;n <code>XBitHack Full</code>. Esto le indica a apache que determine la fecha de &#250;ltima modificaci&#243;n mirando s&#243;lo la fecha del fichero que se ha solicitado originalmente, obviando la modificaci&#243;n de cualquier otro fichero al que se hace referencia mediante SSI.</li>
    
          <li>Use las directivas facilitadas por <code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> para configurar una expiraci&#243;n espec&#237;fica de tiempo en sus ficheros, y as&#237; hacer saber a proxies o navegadores web que es aceptable cachearlos.</li>
        </ol>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic" id="basic">Directivas SSI b&#225;sicas</a></h2>
    
        <p>Las directivas SSI tienen la sintaxis siguiente:</p>
    <div class="example"><p><code>
            &lt;!--#function attribute=value attribute=value ... --&gt;
    </code></p></div>
    
        <p>Se formatean como comentarios HTML, as&#237; si no tiene SSI habilitado correctamente, el navegador las obviar&#225;, pero todav&#237;a ser&#225;n visibles en el fichero HTML. Si tiene SSI configurado correctamente, la directiva ser&#225; reemplazada con su propio resultado.</p>
    
        <p>Esta funci&#243;n es una de tantas, y hablaremos de algunas de ellas m&#225;s adelante. Por ahora, aqu&#237; mostramos unos ejemplos de lo que puede hacer con SSI.</p>
    
    <h3><a name="todaysdate" id="todaysdate">La fecha de hoy</a></h3>
    
    <div class="example"><p><code>
            &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
        <p>La funci&#243;n <code>echo</code> sencillamente muestra el valor de una variable. Hay muchas variables est&#225;ndar que incluyen un conjunto de variables de entorno disponibles para programas CGI. Tambi&#233;n puede definir sus propias variables con la funci&#243;n <code>set</code>.</p>
    
        <p>Si no le gusta el formato en el que se imprime la fecha, puede usar la funci&#243;n <code>config</code>, con un atributo
        <code>timefmt</code> para modificar ese formato.</p>
    
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            Today is &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
    
    <h3><a name="lastmodified" id="lastmodified">Fecha de modificaci&#243;n del fichero</a></h3>
    
    <div class="example"><p><code>
            La &#250;ltima modificaci&#243;n de este documento &lt;!--#flastmod file="index.html" --&gt;
    </code></p></div>
    
        <p>Esta funci&#243;n tambi&#233;n est&#225; sujeta a configuraciones de formato de 
            <code>timefmt</code>.</p>
    
    
    <h3><a name="cgi" id="cgi">Incluyendo los resultados de un programa CGI</a></h3>
    
        <p>Este es uno de los usos m&#225;s comunes de SSI - para sacar el resultado de un programa CGI, tal y como ocurre con el que fuera el programa favorito de todos, un ``contador de visitas.''</p>
    
    <div class="example"><p><code>
            &lt;!--#include virtual="/cgi-bin/counter.pl" --&gt;
    </code></p></div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="additionalexamples" id="additionalexamples">M&#225;s ejemplos</a></h2>
    
    
        <p>A continuaci&#243;n hay algunos ejemplos espec&#237;ficos de cosas que puede hacer con SSI en sus documentos HTML.</p>
    
    <h3><a name="docmodified" id="docmodified">&#191;Cu&#225;ndo fue modificado este documento?</a></h3>
    
        <p>Antes mencionamos que puede usar SSI para informar al usuario cuando el documento ha sido modificado por &#250;ltima vez. Aun as&#237;, el m&#233;todo actual para hacerlo se dej&#243; en cuesti&#243;n. El c&#243;digo que se muestra a continuaci&#243;n, puesto en un documento HTML, pondr&#225; ese sello de tiempo en su p&#225;gina. Por descontado, tendr&#225; que tener SSI habilitado correctamente, como se indic&#243; m&#225;s arriba.</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            Ultima modificaci&#243;n de este fichero &lt;!--#flastmod file="ssi.shtml" --&gt;
    </code></p></div>
    
        <p>Obviamente, necesitar&#225; sustituir el nombre de fichero
        <code>ssi.shtml</code> con el nombre real del fichero al que usted hace referencia. Esto puede ser inconveniente si solo est&#225; buscando un trozo gen&#233;rico de c&#243;digo que pueda copiar y pegar en cualquier fichero, asi que probablemente necesite usar la variable <code>LAST_MODIFIED</code> en su lugar:</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%D" --&gt;<br />
            &#218;ltima modificaci&#243;n de este fichero &lt;!--#echo var="LAST_MODIFIED" --&gt;
    </code></p></div>
    
        <p>Para m&#225;s detalles sobre el formato <code>timefmt</code>, vaya a su buscador favorito y busque <code>strftime</code>. La sintaxis es la misma.</p>
    
    
    <h3><a name="standard-footer" id="standard-footer">Incluyendo un pie de p&#225;gina est&#225;ndar</a></h3>
    
    
        <p>Si gestiona un sitio que tiene m&#225;s de unas cuantas p&#225;ginas, probablemente se de cuenta de que modificar todas esa p&#225;ginas es un aut&#233;ntico engorro, especialmente si trata de mantener una apareciencia homog&#233;nea en todas ellas.</p>
    
        <p>Si usa un Include de fichero para la cabecera y/o pie de p&#225;gina puede reducir la carga de trabajo de estas actualizaciones. Solo tiene que hacer un s&#243;lo pie de p&#225;gina, y despu&#233;s incluirlo en cada p&#225;gina con el comando SSI <code>include</code>. La funci&#243;n <code>include</code>
        puede determinar qu&#233; fichero incluir cuando usa el atributo
        <code>file</code>, o el atributo <code>virtual</code>. El atributo <code>file</code> es una ruta de fichero, <em>relativa al directorio actual</em>. Eso significa que no puede ser una ruta de fichero absoluta (que comienza con /), ni tampoco puede contener ../ como parte de la ruta. El atributo <code>virtual</code> es probablemente m&#225;s &#250;til, y deber&#237;a especificar una URL relativa al documento que se est&#225; sirviendo. Puede empezar con una /, pero debe estar en el mismo servidor que el fichero que se est&#225; sirviendo.</p>
    <div class="example"><p><code>
            &lt;!--#include virtual="/footer.html" --&gt;
    </code></p></div>
    
        <p>Frecuentemente combinaremos las dos &#250;ltimas, poniendo una directiva
        <code>LAST_MODIFIED</code> dentro de un fichero de pie de p&#225;gina que va a ser incluido. Se pueden encontrar directivas SSI en el fichero que se incluye, las inclusiones pueden anidarse - lo que quiere decir, que el fichero incluido puede incluir otro fichero, y as&#237; sucesivamente.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">&#191;Qu&#233; m&#225;s puedo configurar?</a></h2>
    
    
        <p>Adem&#225;s de poder configurar el formato de la hora, tambi&#233;n puede configurar dos cosas m&#225;s.</p> 
    
        <p>Generalmente, cuando algo sale mal con sus directivas SSI, obtiene el mensaje (ha ocurrido un error procesando esta directiva)</p>
    <div class="example"><p><code>
            [an error occurred while processing this directive]
    </code></p></div>
    
        <p>Si quiere cambiar ese mensaje por otra cosa, puede hacerlo con el atributo <code>errmsg</code> para la funci&#243;n
        <code>config</code>:</p>
    <div class="example"><p><code>
            &lt;!--#config errmsg="[Parece que no sabe c&#243;mo usar SSI]" --&gt;
    </code></p></div>
    
        <p>Afortunadamente, los usuarios finales nunca ver&#225;n este mensaje, porque habr&#225; resuelto todos los problemas con sus directivas SSI antes de publicar su p&#225;gina web. (&#191;Verdad?)</p>
    
        <p>Y puede configurar el formato en el que los tama&#241;os de fichero se muestran con el formato <code>sizefmt</code>. Puede especificar
        <code>bytes</code> para un recuento total en bytes, o
        <code>abbrev</code> para un n&#250;mero abreviado en Kb o Mb, seg&#250;n sea necesario.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exec" id="exec">Ejecutando comandos</a></h2>
        
    
        <p> Puede usar la funci&#243;n <code>exec</code> para ejecutar comandos. Y SSI puede ejecutar un comando usando la shell (<code>/bin/sh</code>, para ser m&#225;s precisos - o la shell de DOS , si est&#225; en Win32). Lo siguiente, por ejemplo, le dar&#225; un listado de ficheros en un directorio.</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="ls" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>o, en Windows</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="dir" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>Notar&#225; un formato estra&#241;o con esta directiva en Windows, porque el resultado de <code>dir</code> contiene la cadena de caracterers ``&lt;<code>dir</code>&gt;'' ,que confunde a los navegadores.</p>
    
        <p>Tenga en cuenta de que esta caracter&#237;stica es muy peligrosa, puesto que ejecutar&#225; cualquier c&#243;digo que est&#233; especificado con la etiqueta 
        <code>exec</code>. Si tiene una situaci&#243;n en la que los usuarios pueden editar contenido en sus p&#225;ginas web, tales como por ejemplo un ``registro de visitas'', aseg&#250;rese de tener esta caracter&#237;stica deshabilitada. Puede permitir SSI, pero no la caracter&#237;stica <code>exec</code>, con el argumento <code>IncludesNOEXEC</code> en la directiva <code>Options</code>.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advanced" id="advanced">T&#233;cnicas avanzadas de SSI</a></h2>
    
    
        <p>Adem&#225;s de mostrar contenido, SSI en Apache da la opci&#243;n de configurar variables y usar esas variables en comparaciones y condicionales.</p>
    
    <h3><a name="variables" id="variables">Configurando Variables</a></h3>
    
        <p>Usando la directiva <code>set</code>, puede configurar variables para su uso posterior. La sintaxis es como sigue:</p>
    <div class="example"><p><code>
            &lt;!--#set var="name" value="Rich" --&gt;
    </code></p></div>
    
        <p>Adem&#225;s de configurar valores literales como esto, puede usar cualquier otra variable, incluyendo <a href="../env.html">variables de entorno</a> o las variables que se han mencionado antes (como por ejemplo <code>LAST_MODIFIED</code>) para dar valores a sus variables. Podr&#225; especificar que algo es una vaiable, en lugar de una cadena de caracters literal, usando el s&#237;mbolo del dolar ($) antes del nombre de la variable.</p>
    
        <div class="example"><p><code> &lt;!--#set var="modified" value="$LAST_MODIFIED" --&gt;
        </code></p></div>
    
        <p>Para poner el s&#237;mbolo del dolar de manera literal en un valor de su variable tendr&#225; que escapar el s&#237;mbolo del dolar con una barra "\".</p>
    <div class="example"><p><code>
            &lt;!--#set var="cost" value="\$100" --&gt;
    </code></p></div>
    
        <p>Por &#250;ltimo, si quiere poner una variable entre medias de una cadena de caracteres m&#225;s larga, y se da la coincidencia de que el nombre de la variable se encontrar&#225; con otros caracteres, y de esta manera se confundir&#225; con otros caracteres, puedes poner el nombre de la variable entre llaves, y as&#237; eliminar la confusi&#243;n. (Es dificil encontrar un buen ejemplo para esto, pero con &#233;ste a lo mejor entiende lo que tratamos de transmitir.)</p>
    <div class="example"><p><code>
            &lt;!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --&gt;
    </code></p></div>
    
    
    <h3><a name="conditional" id="conditional">Expresiones condicionales</a></h3>
    
    
        <p>Ahora que tenemos variables, y somos capaces de comparar sus valores, podemos usarlas para expresar condicionales. Esto permite a SSI ser un cierto tipo de lenguaje de programaci&#243;n diminuto.
        <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> provee una estrucura <code>if</code>,
        <code>elif</code>, <code>else</code>, <code>endif</code>
        para construir declaraciones condicionales. Esto le permite generar de manera efectiva multitud de p&#225;ginas l&#243;gicas desde tan solo una p&#225;gina.</p>
    
        <p>La estructura de este sistema condicional es:</p>
    <div class="example"><p><code>
        &lt;!--#if expr="test_condition" --&gt;<br />
        &lt;!--#elif expr="test_condition" --&gt;<br />
        &lt;!--#else --&gt;<br />
        &lt;!--#endif --&gt;
    </code></p></div>
    
        <p>Una <em>test_condition</em> puede ser cualquier tipo de comparaci&#243;n l&#243;gica - o bien comparando valores entre ellos, o probando la ``verdad'' (o falsedad) de un valor en particular. (Una cadena de caracteres cualquiera es verdadera si no est&#225; vac&#237;a.) Para una lista completa de operadores de comparaci&#243;n, vea la documentaci&#243;n de <code class="module"><a href="../mod/mod_include.html">mod_include</a></code>.</p>
    
        <p>Por ejemplo, si quiere personalizar el texto en su p&#225;gina web basado en la hora actual, puede usar la siguiente receta, colocada en su p&#225;gina HTML:</p>
    
        <div class="example"><p><code>
        Good
        &lt;!--#if expr="%{TIME_HOUR} &lt;12" --&gt;<br />
        morning!<br />
        &lt;!--#else --&gt;<br />
        afternoon!<br />
        &lt;!--#endif --&gt;<br />
        </code></p></div>
    
        <p>Cualquier otra variable (o bien las que defina usted, o variables de entorno normales) puede usarse en declaraciones condicionales.
        Vea <a href="../expr.html">Expresiones en el Servidor Apache HTTP</a> para m&#225;s informaci&#243;n sobre el motor de evaluaci&#243;n de expresiones.</p>
    
        <p>Con la habilidad de Apache de configurar variables de entorno con directivas <code>SetEnvIf</code>, y otras directivas relacionadas,
        esta funcionalidad puede llevarle a hacer una gran variedad de contenido din&#225;mico en la parte de servidor sin tener que depender de una aplicaci&#243;n web al completo.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="conclusion" id="conclusion">Conclusi&#243;n</a></h2>
    
        <p>Desde luego SSI no es un reemplazo para CGI u otras tecnolog&#237;as que se usen para generar p&#225;ginas web din&#225;micas. Pero es un gran m&#233;todo para a&#241;adir peque&#241;as cantidaddes de contenido din&#225;mico a p&#225;ginas web, sin hacer mucho m&#225;s trabajo extra.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/ssi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/auth.html.fr.utf8����������������������������������������������������0000664�0001751�0001751�00000117470�14740503670�021331� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Authentification et autorisation - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Recettes / Tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Authentification et autorisation</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>L'authentification est un processus qui vous permet de vérifier
        qu'une personne est bien celle qu'elle prétend être. L'autorisation
        est un processus qui permet à une personne d'aller là où elle veut
        aller, ou d'obtenir les informations qu'elle désire.</p>
    
        <p>Pour le contrôle d'accès en général, voir le How-To <a href="access.html">Contrôle d'accès</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Modules et directives concernés</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#theprerequisites">Les prérequis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#gettingitworking">Mise en oeuvre</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#lettingmorethanonepersonin">Autorisation d'accès à
    plusieurs personnes</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#possibleproblems">Problèmes possibles</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbmdbd">Autre méthode de stockage des mots de
    passe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multprovider">Utilisation de plusieurs fournisseurs
    d'authentification</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#beyond">Pour aller plus loin qu'une simple
    autorisation</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#socache">Mise en cache de l'authentification</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">Pour aller plus loin . . .</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Modules et directives concernés</a></h2>
    
    <p>Trois groupes de modules sont concernés par le processus
    d'authentification et d'autorisation. Vous devrez utiliser au moins un
    module de chaque groupe.</p>
    
    <ul>
      <li>Type d'authentification (voir la directive <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code>)
        <ul>
          <li><code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code></li>
          <li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li>
        </ul>
      </li>
      <li>Fournisseur d'authentification (voir les directives <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> et <code class="directive"><a href="../mod/mod_auth_digest.html#authdigestprovider">AuthDigestProvider</a></code>)
    
        <ul>
          <li><code class="module"><a href="../mod/mod_authn_anon.html">mod_authn_anon</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code></li>
        </ul>
      </li>
      <li>Autorisation (voir la directive <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>)
        <ul>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbd.html">mod_authz_dbd</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li>
         <li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_owner.html">mod_authz_owner</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_user.html">mod_authz_user</a></code></li>
        </ul>
      </li>
    </ul>
    
      <p>On peut aussi ajouter <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> et
      <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>. Ces modules implémentent des
      directives générales qui opèrent au dessus de tous les modules
      d'authentification.</p>
    
      <p>Le module <code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> est un fournisseur
      d'authentification et d'autorisation. Le module
      <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code> fournit une autorisation et un
      contrôle d'accès basés sur le nom du serveur, l'adresse IP ou
      certaines caractéristiques de la requête, mais ne fait pas partie du
      système fournisseur d'authentification. Le module
      <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> a été créé à des fins de
      compatibilité ascendante avec mod_access.</p>
    
      <p>Vous devriez aussi jeter un coup d'oeil au manuel de recettes de <a href="access.html">Contrôle d'accès</a>, qui décrit les différentes
      méthodes de contrôle d'accès à votre serveur.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
        <p>Si votre site web contient des informations sensibles ou
        destinées seulement à un groupe de personnes restreint, les
        techniques exposées dans cet article vont vous aider à vous assurer
        que les personnes qui ont accès à ces pages sont bien celles
        auxquelles vous avez donné l'autorisation d'accès.</p>
    
        <p>Cet article décrit les méthodes "standards" de protection de
        parties de votre site web que la plupart d'entre vous sont appelés à
        utiliser.</p>
    
        <div class="note"><h3>Note :</h3>
        <p>Si vos données ont un réel besoin de sécurisation, prévoyez
        l'utilisation de <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> en plus de toute méthode
        d'authentification.</p>
        </div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="theprerequisites" id="theprerequisites">Les prérequis</a></h2>
        <p>Les directives décrites dans cet article devront être insérées
        soit au niveau de la configuration de votre serveur principal (en
        général dans une section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>), soit au niveau de la
        configuration des répertoires (fichiers <code>.htaccess</code>)</p>
    
        <p>Si vous envisagez l'utilisation de fichiers
        <code>.htaccess</code>, la configuration de votre serveur devra
        permettre l'ajout de directives d'authentification dans ces
        fichiers. Pour ce faire, on utilise la directive <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>, qui spécifie quelles
        directives pourront éventuellement contenir les fichiers de
        configuration de niveau répertoire.</p>
    
        <p>Comme il est ici question d'authentification, vous aurez besoin
        d'une directive <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        du style :</p>
    
        <pre class="prettyprint lang-config">AllowOverride AuthConfig</pre>
    
    
        <p>Si vous avez l'intention d'ajouter les directives directement
        dans le fichier de configuration principal, vous devrez bien entendu
        posséder les droits en écriture sur ce fichier.</p>
    
        <p>Vous devrez aussi connaître un tant soit peu la structure des
        répertoires de votre serveur, ne serait-ce que pour savoir où se
        trouvent certains fichiers. Cela ne devrait pas présenter de grandes
        difficultés, et nous essaierons de clarifier tout ça lorsque le besoin
        s'en fera sentir.</p>
    
        <p>Enfin, vous devrez vous assurer que les modules
        <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> et <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>
        ont été soit compilés avec le binaire httpd, soit chargés par le
        fichier de configuration httpd.conf. Ces deux modules fournissent
        des directives générales et des fonctionnalités qui sont critiques
        quant à la configuration et l'utilisation de l'authentification et
        de l'autorisation au sein du serveur web.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gettingitworking" id="gettingitworking">Mise en oeuvre</a></h2>
        <p>Nous décrivons ici les bases de la protection par mot de passe
        d'un répertoire de votre serveur.</p>
    
        <p>Vous devez en premier lieu créer un fichier de mots de passe. La
        méthode exacte selon laquelle vous allez créer ce fichier va varier
        en fonction du fournisseur d'authentification choisi. Mais nous
        entrerons dans les détails plus loin, et pour le moment, nous nous
        contenterons d'un fichier de mots de passe en mode texte.</p>
    
        <p>Ce fichier doit être enregistré à un endroit non accessible
        depuis le web, de façon à ce que les clients ne puissent pas le
        télécharger. Par exemple, si vos documents sont servis à partir de
        <code>/usr/local/apache/htdocs</code>, vous pouvez enregistrer le
        fichier des mots de passe dans
        <code>/usr/local/apache/passwd</code>.</p>
    
        <p>L'utilitaire <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> fourni avec Apache
        permet de créer ce fichier. Vous le trouverez dans le répertoire
        <code>bin</code> de votre installation d'Apache. Si vous avez
        installé Apache à partir d'un paquetage tiers, il sera probablement
        dans le chemin par défaut de vos exécutables.</p>
    
        <p>Pour créer le fichier, tapez :</p>
    
        <div class="example"><p><code>
          htpasswd -c /usr/local/apache/passwd/passwords rbowen
        </code></p></div>
    
        <p><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> vous demandera d'entrer le mot de
        passe, et de le retaper pour confirmation :</p>
    
        <div class="example"><p><code>
          # htpasswd -c /usr/local/apache/passwd/passwords rbowen<br />
          New password: mot-de-passe<br />
          Re-type new password: mot-de-passe<br />
          Adding password for user rbowen
        </code></p></div>
    
        <p>Si <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> n'est pas dans le chemin par
        défaut de vos exécutables, vous devrez bien entendu entrer le chemin
        complet du fichier. Dans le cas d'une installation par défaut, il se
        trouve à <code>/usr/local/apache2/bin/htpasswd</code>.</p>
    
        <p>Ensuite, vous allez devoir configurer le serveur de façon à ce
        qu'il demande un mot de passe et lui préciser quels utilisateurs ont
        l'autorisation d'accès. Pour ce faire, vous pouvez soit éditer le
        fichier <code>httpd.conf</code>, soit utiliser un fichier
        <code>.htaccess</code>. Par exemple, si vous voulez protéger le
        répertoire <code>/usr/local/apache/htdocs/secret</code>, vous pouvez
        utiliser les directives suivantes, soit dans le fichier
        <code>/usr/local/apache/htdocs/secret/.htaccess</code>, soit dans le
        fichier <code>httpd.conf</code> à l'intérieur d'une section &lt;Directory
        "/usr/local/apache/htdocs/secret"&gt; :</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "Restricted Files"
    # (Following line optional)
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require user rbowen</pre>
    
    
        <p>Examinons ces directives une à une. La directive <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code> définit la méthode
        utilisée pour authentifier l'utilisateur. La méthode la plus
        courante est <code>Basic</code>, et elle est implémentée par
        <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code>. Il faut cependant garder à l'esprit
        que l'authentification Basic transmet le mot de passe depuis le
        client vers le serveur en clair. Cette méthode ne devra donc pas
        être utilisée pour la transmission de données hautement sensibles si
        elle n'est pas associée au module <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>. Apache
        supporte une autre méthode d'authentification : <code>AuthType
        Digest</code>. Cette méthode est implémentée par le module <code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code> et a été conçue pour
        améliorer la sécurité. Ce but n'a cependant pas été atteint et il est préférable
        de chiffrer la connexion avec <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.</p>
    
        <p>La directive <code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code> définit
        l'<dfn>Identificateur</dfn> (Realm) à utiliser avec
        l'authentification. L'identificateur possède deux fonctions. Tout
        d'abord, le client présente en général cette information à
        l'utilisateur dans le cadre de la boîte de dialogue de mot de passe.
        Ensuite, le client l'utilise pour déterminer quel mot de passe
        envoyer pour une zone authentifiée donnée.</p>
    
        <p>Ainsi par exemple, une fois un client authentifié dans la zone
        <code>"Fichiers réservés"</code>, il soumettra à nouveau
        automatiquement le même mot de passe pour toute zone du même serveur
        marquée de l'identificateur <code>"Fichiers réservés"</code>. De
        cette façon, vous pouvez éviter à un utilisateur d'avoir à saisir
        plusieurs fois le même mot de passe en faisant partager le même
        identificateur entre plusieurs zones réservées. Bien entendu et pour
        des raisons de sécurité, le client devra redemander le mot
        de passe chaque fois que le nom d'hôte du serveur sera modifié.</p>
    
        <p>La directive <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> est, dans ce
        cas, facultative, car <code>file</code> est la valeur par défaut
        pour cette directive. Par contre, cette directive sera obligatoire
        si vous utilisez une autre source d'authentification comme
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> ou
        <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>.</p>
    
        <p>La directive <code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code> définit le chemin
        du fichier de mots de passe que nous venons de créer avec
        <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>. Si vous possédez un grand nombre
        d'utilisateurs, la durée de la recherche dans un fichier texte pour
        authentifier un utilisateur à chaque requête va augmenter
        rapidement, et pour pallier cet inconvénient, Apache peut aussi
        stocker les données relatives aux
        utilisateurs dans des bases de données rapides. Le module
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> fournit la directive <code class="directive"><a href="../mod/mod_authn_dbm.html#authdbmuserfile">AuthDBMUserFile</a></code>. Les programmes <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> et <code class="program"><a href="../programs/htdbm.html">htdbm</a></code> permettent de
        créer et manipuler ces fichiers. Enfin, de nombreux modules tiers
        fournissent d'autres types d'authentification.</p>
    
        <p>Enfin, la directive <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> implémente la partie
        autorisation du processus en définissant l'utilisateur autorisé à
        accéder à cette zone du serveur. Dans la section suivante, nous
        décrirons les différentes méthodes d'utilisation de la directive
        <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="lettingmorethanonepersonin" id="lettingmorethanonepersonin">Autorisation d'accès à
    plusieurs personnes</a></h2>
        <p>Les directives ci-dessus n'autorisent qu'une personne (quelqu'un
        possédant le nom d'utilisateur <code>rbowen</code>) à accéder au
        répertoire. Dans la plupart des cas, vous devrez autoriser
        l'accès à plusieurs personnes. C'est ici
        qu'intervient la directive <code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code>.</p>
    
        <p>Si vous voulez autoriser l'accès à plusieurs personnes, vous
        devez créer un fichier de groupes qui associe des noms de groupes
        avec une liste d'utilisateurs de ce groupe. Le format de ce fichier
        est très simple, et vous pouvez le créer avec votre éditeur favori.
        Son contenu se présente comme suit :</p>
    
       <div class="example"><p><code>
         Nom-de-groupe: rbowen dpitts sungo rshersey
       </code></p></div>
    
        <p>Il s'agit simplement une liste des membres du groupe sous la
        forme d'une ligne séparée par des espaces.</p>
    
        <p>Pour ajouter un utilisateur à votre fichier de mots de passe
        préexistant, entrez :</p>
    
        <div class="example"><p><code>
          htpasswd /usr/local/apache/passwd/passwords dpitts
        </code></p></div>
    
        <p>Vous obtiendrez le même effet qu'auparavant, mais le mot de passe
        sera ajouté au fichier, plutôt que d'en créer un nouveau (C'est le
        drapeau <code>-c</code> qui permet de créer un nouveau fichier de
        mots de passe)..</p>
    
        <p>Maintenant, vous devez modifier votre fichier
        <code>.htaccess</code> ou la section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> comme suit :</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "By Invitation Only"
    # Optional line:
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    AuthGroupFile "/usr/local/apache/passwd/groups"
    Require group GroupName</pre>
    
    
        <p>Maintenant, quiconque appartient au groupe
        <code>Nom-de-groupe</code>, et possède une entrée dans le fichier
        <code>password</code> pourra accéder au répertoire s'il tape le bon
        mot de passe.</p>
    
        <p>Il existe une autre méthode moins contraignante pour autoriser
        l'accès à plusieurs personnes. Plutôt que de créer un fichier de
        groupes, il vous suffit d'ajouter la directive suivante :</p>
    
        <pre class="prettyprint lang-config">Require valid-user</pre>
    
    
        <p>Le remplacement de la ligne <code>Require user rbowen</code> par
        la ligne <code>Require valid-user</code> autorisera l'accès à
        quiconque possédant une entrée dans le fichier password, et ayant
        tapé le bon mot de passe.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="possibleproblems" id="possibleproblems">Problèmes possibles</a></h2>
        <p>L'authentification Basic est spécifiée d'une telle manière que
        vos nom d'utilisateur et mot de passe doivent être vérifiés chaque
        fois que vous demandez un document au serveur, et ceci même si vous
        rechargez la même page, et pour chaque image contenue dans la page
        (si elles sont situées dans un répertoire protégé). Comme vous
        pouvez l'imaginer, ceci ralentit un peu le fonctionnement. La mesure
        dans laquelle le fonctionnement est ralenti est proportionnelle à la
        taille du fichier des mots de passe, car ce dernier doit être ouvert
        et la liste des utilisateurs parcourue jusqu'à ce que votre nom soit
        trouvé, et ceci chaque fois qu'une page est chargée.</p>
    
        <p>En conséquence, ce ralentissement impose une limite pratique au
        nombre d'utilisateurs que vous pouvez enregistrer dans un fichier de
        mots de passe. Cette limite va varier en fonction des performances
        de votre serveur, mais vous commencerez à remarquer un
        ralentissement lorsque vous atteindrez quelques centaines
        d'utilisateurs, et serez alors appelés à utiliser une méthode
        d'authentification différente.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbmdbd" id="dbmdbd">Autre méthode de stockage des mots de
    passe</a></h2>
    
        <p>Suite au problème évoqué précédemment et induit par le stockage
        des mots de passe dans un fichier texte, vous pouvez être appelé à
        stocker vos mots de passe d'une autre manière, par exemple dans une
        base de données.</p>
    
        <p>Pour y parvenir, on peut utiliser les modules
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> ou <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>.
        Vous pouvez choisir comme format de stockage <code>dbm</code> ou
        <code>dbd</code> à la place de <code>file</code> pour la directive
        <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code>.</p>
    
        <p>Par exemple, pour sélectionner un fichier dbm à la place d'un
        fichier texte :</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
    
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider dbm
        AuthDBMUserFile "/www/passwords/passwd.dbm"
        Require valid-user
    
    &lt;/Directory&gt;</pre>
    
    
        <p>D'autres options sont disponibles. Consultez la documentation de
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> pour plus de détails.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multprovider" id="multprovider">Utilisation de plusieurs fournisseurs
    d'authentification</a></h2>
    
        <p>Depuis l'arrivée des nouvelles architecture d'autorisation et
        d'authentification basées sur les fournisseurs, vous n'êtes plus
        limité à une méthode d'authentification et d'autorisation
        unique. En fait, on peut panacher autant de fournisseurs que l'on
        veut, ce qui vous permet d'élaborer l'architecture qui correspond
        exactement à vos besoins. Dans l'exemple suivant, on utilise
        conjointement les fournisseurs d'authentification
        file et LDAP :</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
    
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file ldap
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        Require valid-user
    
    &lt;/Directory&gt;</pre>
    
    
        <p>Dans cet exemple, le fournisseur file va tenter d'authentifier
        l'utilisateur en premier. S'il n'y parvient pas, le fournisseur LDAP
        sera sollicité. Ceci permet l'élargissement des possibilités
        d'authentification si votre organisation implémente plusieurs types
        de bases d'authentification. D'autres scénarios d'authentification
        et d'autorisation peuvent associer un type d'authentification avec
        un autre type d'autorisation. Par exemple, une authentification
        basée sur un fichier de mots de passe peut permettre l'attribution
        d'autorisations basée sur un annuaire LDAP.</p>
    
        <p>Tout comme plusieurs fournisseurs d'authentification peuvent être
        implémentés, on peut aussi utiliser plusieurs méthodes
        d'autorisation. Dans l'exemple suivant, on utilise à la fois une
        autorisation à base de fichier de groupes et une autorisation à base
        de groupes LDAP.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
    
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        AuthGroupFile "/usr/local/apache/passwd/groups"
        Require group GroupName
        Require ldap-group cn=mygroup,o=yourorg
    
    &lt;/Directory&gt;</pre>
    
    
        <p>Pour un scénario d'autorisation un peu plus avancé, des
        directives de conteneur d'autorisation comme <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code> et
        <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code> permettent d'appliquer une
        logique telle que l'ordre dans lequel les autorisations sont
        appliquées peut être entièrement contrôlé au niveau de la
        configuration. Voir <a href="../mod/mod_authz_core.html#logic">Conteneurs
        d'autorisations</a> pour un exemple de ce contrôle.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="beyond" id="beyond">Pour aller plus loin qu'une simple
    autorisation</a></h2>
    
        <p>La manière dont les autorisations sont accordées est désormais
        beaucoup plus souple qu'une simple vérification auprès d'une seule
        base de données. Il est maintenant possible de choisir l'ordre, la
        logique et la manière selon lesquels une autorisation est
        accordée.</p>
    
        <h3><a name="authandororder" id="authandororder">Appliquer logique et
        ordonnancement</a></h3>
            <p>Le contrôle de la manière et de l'ordre selon lesquels le
    	processus d'autorisation était appliqué
    	constituait une sorte de mystère par
    	le passé. Dans Apache 2.2, un mécanisme d'authentification basé
    	sur les fournisseurs a été développé afin de séparer le
    	véritable processus d'authentification de l'autorisation et ses
    	différentes fonctionnalités. Un des avantages colatéraux
    	résidait dans le fait que les fournisseurs d'authentification
    	pouvaient être configurés et appelés selon un ordre particulier
    	indépendant de l'ordre de chargement du module auth proprement
    	dit. Ce mécanisme basé sur les fournisseurs a été étendu au
    	processus d'autorisation. Ceci signifie que la directive
    	<code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> définit
    	non seulement quelles méthodes d'autorisation doivent être
    	utilisées, mais aussi l'ordre dans lequel elles sont appelées.
    	Les méthodes d'autorisation sont appelées selon l'ordre dans
    	lequel les directives <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> apparaissent dans la
    	configuration.</p>
    
            <p>Avec l'introduction des directives de conteneur
    	d'autorisations <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
     	et <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>, la
    	configuration contrôle aussi le moment où les méthodes
    	d'autorisation sont appelées, et quels critères déterminent
    	l'autorisation d'accès. Voir <a href="../mod/mod_authz_core.html#logic">Conteneurs
    	d'autorisations</a> pour un exemple de la manière de les
    	utiliser pour exprimer des logiques d'autorisation
    	complexes.</p>
    
            <p>Par défaut, toutes les directives <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> sont
    	traitées comme si elles étaient contenues dans une directive
    	<code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>. En d'autres termes, il
    	suffit
    	qu'une méthode d'autorisation s'applique avec succès pour que
    	l'autorisation soit accordée.</p>
    
        
    
        <h3><a name="reqaccessctrl" id="reqaccessctrl">Utilisation de fournisseurs
        d'autorisation pour le contrôle d'accès</a></h3>
            <p>La vérification du nom d'utilisateur et du mot de passe ne
    	constituent qu'un aspect des méthodes d'authentification.
    	Souvent, le contrôle d'accès à certaines personnes n'est pas
    	basé sur leur identité ; il peut dépendre, par exemple de leur
    	provenance.</p>
    
            <p>Les fournisseurs d'autorisation <code>all</code>,
    	<code>env</code>, <code>host</code> et <code>ip</code> vous
    	permettent d'accorder ou refuser l'accès en
    	fonction de critères tels que le nom d'hôte ou l'adresse
    	IP de la machine qui effectue la requête.</p>
    
            <p>L'utilisation de ces fournisseurs est spécifiée à l'aide de
    	la directive <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>. Cette directive
    	permet d'enregistrer quels fournisseurs d'autorisation
    	seront appelés dans le processus d'autorisation au cours du
    	traitement de la requête. Par exemple :</p>
    
            <pre class="prettyprint lang-config">Require ip <var>address</var></pre>
    
    
            <p>où <var>adresse</var> est une adresse IP (ou une adresse IP
    	partielle) ou :</p>
    
            <pre class="prettyprint lang-config">Require host <var>domain_name</var></pre>
    
    
            <p>où <var>nom_domaine</var> est un nom de domaine entièrement
    	qualifé (ou un nom de domaine partiel) ; vous pouvez indiquer
    	plusieurs adresses ou noms de domaines, si vous le désirez.</p>
    
            <p>Par exemple, si vous voulez rejeter les spams dont une
    	machine vous inonde, vous pouvez utiliser ceci :</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 10.252.46.165
    &lt;/RequireAll&gt;</pre>
    
    
            <p>Ainsi, les visiteurs en provenance de cette adresse ne
    	pourront pas voir le contenu concerné par cette directive. Si,
    	par contre, vous connaissez le nom de la machine, vous pouvez
    	utiliser ceci :</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not host host.example.com
    &lt;/RequireAll&gt;</pre>
    
    
            <p>Et si vous voulez interdire l'accès à toutes les machines
    	d'un domaine, vous pouvez spécifier une partie seulement de
    	l'adresse ou du nom de domaine :</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 192.168.205
        Require not host phishers.example.com moreidiots.example
        Require not host ke
    &lt;/RequireAll&gt;</pre>
    
    
            <p>L'utilisation de la directive <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
    	avec de multiples directives <code class="directive"><a href="../mod/mod_authz_core.html#require">&lt;Require&gt;</a></code>, toutes avec la négation
    	<code>not</code>, n'accordera l'accès que si toutes les
    	conditions négatives sont vérifiées. En d'autres termes, l'accès
    	sera refusé si au moins une des conditions négatives n'est pas
    	vérifiée.</p>
    
        
    
        <h3><a name="filesystem" id="filesystem">Compatibilité ascendante du contrôle
        d'accès</a></h3>
            <p>L'adoption d'un mécanisme à base de fournisseurs pour
    	l'authentification, a pour effet colatéral de rendre inutiles
    	les directives <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>, <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> et <code class="directive"><a href="../mod/mod_access_compat.html#satisfy">Satisfy</a></code>. Cependant, et à
    	des fins de compatibilité ascendante vers les anciennes
    	configurations, ces directives ont été déplacées vers le module
    	<code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code>.</p>
    
        <div class="warning"><h3>Note</h3>
          <p>Les directives fournies par le module
          <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> sont devenues obsolètes depuis
          la refonte du module <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>. Mélanger d'anciennes
          directives comme <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code> ou <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> avec des nouvelles comme
          <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> est techniquement
          possible mais déconseillé. En effet, <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> a
          été conçu pour supporter des configurations ne contenant que des anciennes
          directives afin de faciliter le passage à la version 2.4. Voir le document
          <a href="../upgrading.html">upgrading</a> pour plus de détails.
          </p>
        </div>	
        
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="socache" id="socache">Mise en cache de l'authentification</a></h2>
        <p>Dans certains cas, l'authentification constitue une charge
        inacceptable pour un fournisseur d'authentification ou votre réseau.
        Ceci est susceptible d'affecter les utilisateurs du module
        <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code> (ou les fournisseurs
        tiers/personnalisés). Pour résoudre ce problème, HTTPD 2.3/2.4
        propose un nouveau fournisseur de mise en cache,
        <code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code>, qui permet de mettre en cache
        les données d'authentification, et ainsi réduire la charge du/des
        fournisseurs(s) originels.</p>
        <p>Cette mise en cache apportera un gain en performance substantiel
        à certains utilisateurs.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">Pour aller plus loin . . .</a></h2>
        <p>Vous pouvez aussi lire la documentation de
        <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> et <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>
        qui contient des informations supplémentaires à propos du
        fonctionnement de tout ceci.
        Certaines configurations d'authentification peuvent aussi être
        simplifiées à l'aide de la directive <code class="directive"><a href="../mod/mod_authn_core.html#authnprovideralias">&lt;AuthnProviderAlias&gt;</a></code>.</p>
    
        <p>Les différents algorithmes de chiffrement supportés par Apache
        pour authentifier les données sont expliqués dans <a href="../misc/password_encryptions.html">PasswordEncryptions</a>.</p>
    
        <p>Enfin vous pouvez consulter la recette <a href="access.html">Contrôle
        d'accès</a>, qui décrit un certain nombre de situations en relation
        avec le sujet.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/auth.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/index.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000021607�14740503670�021473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>How-To / Tutoriels - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>How-To / Tutoriels</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">How-To / Tutoriels</a></h2>
    
        
    
        <dl>
          <dt>Authentification et autorisation</dt>
          <dd>
            <p>L'authentification représente tout processus par lequel vous
    	vérifiez si quelqu'un correspond bien à la personne qu'il
    	prétend être. L'autorisation représente tout processus
    	permettant de savoir si une personne est autorisée à aller là où
    	elle veut aller, ou à obtenir les informations qu'elle demande.</p>
    
            <p>Voir <a href="auth.html">Authentification, Autorisation</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Contrôle d'accès</dt>
          <dd>
            <p>Le contrôle d'accès se réfère au processus permettant
    	d'interdire ou d'accorder l'accès à une ressource en fonction de
    	certains critères, et il existe de nombreuses façons d'y
    	parvenir.</p>
    
            <p>Voir <a href="access.html">Contrôle d'accès</a></p>
          </dd>
        </dl>
    
       <dl>
          <dt>Contenu dynamique avec CGI</dt>
          <dd>
            <p>L'interface CGI (Common Gateway Interface)
    	fournit au serveur web une méthode d'interaction avec des
    	programmes externes générateurs de contenu, souvent nommés
    	programmes CGI ou scripts CGI. Il s'agit d'une méthode
    	simple permettant d'ajouter du contenu
    	dynamique à votre site web. Ce document se veut une introduction
    	à la configuration de CGI sur votre serveur web Apache et à
    	l'écriture de programmes CGI.</p>
    
            <p>Voir <a href="cgi.html">CGI : contenu dynamique</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Fichiers <code>.htaccess</code></dt>
          <dd>
            <p>Les fichiers <code>.htaccess</code> permettent de modifier la
    	configuration du serveur au niveau de chaque répertoire. À cet
    	effet, un fichier est placé dans un répertoire particulier du site
    	web, et les directives de configuration qu'il contient s'appliquent à ce
    	répertoire et à tous ses sous-répertoires.</p>
    
            <p>Voir <a href="htaccess.html">Fichiers <code>.htaccess</code></a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>HTTP/2 avec httpd</dt>
          <dd>
          <p>HTTP/2 est une évolution du protocole de la couche application le plus
          connu au monde, HTTP. Les efforts se sont concentrés sur une amélioration
          de l'efficacité de l'utilisation des ressources réseau sans modifier la
          sémantique de HTTP. Ce guide explique la manière dont HTTP/2 est
          implémenté dans httpd, donne des conseils pour une configuration de base
          ainsi qu'une liste de recommandations.
          </p>
    
            <p>Voir le <a href="http2.html">guide HTTP/2</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Introduction au Inclusions côté Serveur (Server Side Includes
          ou SSI)</dt>
          <dd>
            <p>Les SSI sont des directives que l'on place dans des pages
    	HTML, et qui sont évaluées par le serveur lorsque ces pages sont
    	servies. Elles vous permettent d'ajouter du contenu généré
    	dynamiquement à une page HTML existante, sans avoir à servir
    	l'intégralité de la page via un programme CGI, ou toute autre
    	technologie dynamique.</p>
    
            <p>Voir <a href="ssi.html">Server Side Includes (SSI)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Répertoires web de l'utilisateur</dt>
          <dd>
            <p>Sur les systèmes multi-utilisateurs, vous pouvez permettre à
    	chaque utilisateur d'avoir un site web dans son répertoire home
    	via la directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>. Les visiteurs de l'URL
    	<code>http://example.com/~nom-utilisateur/</code> vont recevoir
    	du contenu situé dans le répertoire home de l'utilisateur
    	"<code>nom-utilisateur</code>", et dans le sous-répertoire
    	spécifié par la directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>.</p>
    
            <p>Voir <a href="public_html.html">Répertoires web des utilisateurs (<code>public_html</code>)</a></p>
          </dd>
        </dl>
        <dl>
          <dt>Mandataires inverses</dt>
          <dd>
            <p>Apache httpd possède des fonctionnalités évoluées de serveur
    	mandataire inverse via ses directives <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> et <code class="directive"><a href="../mod/mod_proxy.html#balancermember">BalancerMember</a></code> qui permettent
    	d'implémenter un système de mandataire inverse sophistiqué garantissant
    	une haute disponibilité, une répartition et une réattribution de charge,
    	un regroupement de serveurs en grappe (clustering) basé sur le cloud et
    	une reconfiguration dynamique à la volée.</p>
    
            <p>Voir le <a href="reverse_proxy.html" />Guide de configuration des
    	mandataires inverses</p>
          </dd>
        </dl>
    
        <dl>
          <dt>Réécriture d'URLs avec mod_rewrite</dt>
          <dd>
            <p>La réécriture d'URLs avec (ou sans) <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> devient
    	l'une des questions les plus fréquentes posées dans nos listes de
    	diffusion et nos canaux IRC. C'est pourquoi nous avons dédié une <a href="../rewrite/">section entière de notre documentation</a> à des
    	howtos et recettes sur ce sujet.</p>
          </dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/htaccess.html.en�����������������������������������������������������0000664�0001751�0001751�00000066634�14737241666�021312� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server Tutorial: .htaccess files - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Server Tutorial: .htaccess files</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/htaccess.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div>
    
    <p><code>.htaccess</code> files provide a way to make configuration
    changes on a per-directory basis.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">.htaccess files</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">What they are/How to use them</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#when">When (not) to use .htaccess files</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#how">How directives are applied</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#auth">Authentication example</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssi">Server Side Includes example</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Rewrite Rules in .htaccess files</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">CGI example</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">Troubleshooting</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">.htaccess files</a></h2>
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li><li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li><li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code></li></ul></td></tr></table>
    
        <div class="note">You should avoid using <code>.htaccess</code> files completely if you have access to
        httpd main server config file. Using <code>.htaccess</code> files slows down your Apache http server.
        Any directive that you can include in a <code>.htaccess</code> file is better set in a <code class="directive"><a href="../mod/core.html#directory">Directory</a></code> block, as it will have the same effect with better performance.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">What they are/How to use them</a></h2>
    
    
        <p><code>.htaccess</code> 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.</p>
    
        <div class="note"><h3>Note:</h3>
          <p>If you want to call your <code>.htaccess</code> file something
          else, you can change the name of the file using the <code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code> directive. For example,
          if you would rather call the file <code>.config</code> then you
          can put the following in your server configuration file:</p>
    
          <pre class="prettyprint lang-config">AccessFileName ".config"</pre>
    
        </div>
    
        <p>In general, <code>.htaccess</code> files use the same syntax as
        the <a href="../configuring.html#syntax">main configuration
        files</a>. What you can put in these files is determined by the
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> directive. This
        directive specifies, in categories, what directives will be
        honored if they are found in a <code>.htaccess</code> file. If a
        directive is permitted in a <code>.htaccess</code> file, the
        documentation for that directive will contain an Override section,
        specifying what value must be in <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> in order for that
        directive to be permitted.</p>
    
        <p>For example, if you look at the documentation for the <code class="directive"><a href="../mod/core.html#adddefaultcharset">AddDefaultCharset</a></code>
        directive, you will find that it is permitted in <code>.htaccess</code>
        files. (See the Context line in the directive summary.) The <a href="../mod/directive-dict.html#Context">Override</a> line reads
        <code>FileInfo</code>. Thus, you must have at least
        <code>AllowOverride FileInfo</code> in order for this directive to be
        honored in <code>.htaccess</code> files.</p>
    
        <div class="example"><h3>Example:</h3><table>
            <tr>
              <td><a href="../mod/directive-dict.html#Context">Context:</a></td>
              <td>server config, virtual host, directory, .htaccess</td>
            </tr>
    
            <tr>
              <td><a href="../mod/directive-dict.html#Override">Override:</a></td>
              <td>FileInfo</td>
            </tr>
          </table></div>
    
        <p>If you are unsure whether a particular directive is permitted in a
        <code>.htaccess</code> file, look at the documentation for that
        directive, and check the Context line for ".htaccess".</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="when" id="when">When (not) to use .htaccess files</a></h2>
    
        <p>In general, you should only use <code>.htaccess</code> files when
        you don't have access to the main server configuration file. There is,
        for example, a common misconception that user authentication should
        always be done in <code>.htaccess</code> files, and, in more recent years,
        another misconception that <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> directives
        must go in <code>.htaccess</code> 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. Likewise, <code>mod_rewrite</code> directives work better,
        in many respects, in the main server configuration.</p>
    
        <p><code>.htaccess</code> 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 <code>.htaccess</code> 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.</p>
    
        <p>However, in general, use of <code>.htaccess</code> files should be
        avoided when possible. Any configuration that you would consider
        putting in a <code>.htaccess</code> file, can just as effectively be
        made in a <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> section in your main server
        configuration file.</p>
    
        <p>There are two main reasons to avoid the use of
        <code>.htaccess</code> files.</p>
    
        <p>The first of these is performance. When <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        is set to allow the use of <code>.htaccess</code> files, httpd will
        look in every directory for <code>.htaccess</code> files. Thus,
        permitting <code>.htaccess</code> files causes a performance hit,
        whether or not you actually even use them! Also, the
        <code>.htaccess</code> file is loaded every time a document is
        requested.</p>
    
        <p>Further note that httpd must look for <code>.htaccess</code> files
        in all higher-level directories, in order to have a full complement of
        directives that it must apply. (See section on <a href="#how">how
        directives are applied</a>.) Thus, if a file is requested out of a
        directory <code>/www/htdocs/example</code>, httpd must look for the
        following files:</p>
    
        <div class="example"><p><code>
          /.htaccess<br />
          /www/.htaccess<br />
          /www/htdocs/.htaccess<br />
          /www/htdocs/example/.htaccess
        </code></p></div>
    
        <p>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
        <code>.htaccess</code> files were enabled for <code>/</code>, which
        is not usually the case.)</p>
    
        <p>In the case of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives, in
        <code>.htaccess</code> context these regular expressions must be
        re-compiled with every request to the directory, whereas in main
        server configuration context they are compiled once and cached.
        Additionally, the rules themselves are more complicated, as one must
        work around the restrictions that come with per-directory context
        and <code>mod_rewrite</code>. Consult the <a href="../rewrite/intro.html#htaccess">Rewrite Guide</a> for more
        detail on this subject.</p>
    
        <p>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
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> to, and pointing them
        to the relevant documentation, will save yourself a lot of confusion
        later.</p>
    
        <p>Note that it is completely equivalent to put a <code>.htaccess</code>
        file in a directory <code>/www/htdocs/example</code> containing a
        directive, and to put that same directive in a Directory section
        <code>&lt;Directory "/www/htdocs/example"&gt;</code> in your main server
        configuration:</p>
    
        <p><code>.htaccess</code> file in <code>/www/htdocs/example</code>:</p>
    
        <div class="example"><h3>Contents of .htaccess file in
        <code>/www/htdocs/example</code></h3><pre class="prettyprint lang-config">AddType text/example ".exm"</pre>
    </div>
    
        <div class="example"><h3>Section from your <code>httpd.conf</code>
        file</h3><pre class="prettyprint lang-config">&lt;Directory "/www/htdocs/example"&gt;
        AddType text/example ".exm"
    &lt;/Directory&gt;</pre>
    </div>
    
        <p>However, putting this configuration in your server configuration
        file will result in less of a performance hit, as the configuration is
        loaded once when httpd starts, rather than every time a file is
        requested.</p>
    
        <p>The use of <code>.htaccess</code> files can be disabled completely
        by setting the <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        directive to <code>none</code>:</p>
    
        <pre class="prettyprint lang-config">AllowOverride None</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="how" id="how">How directives are applied</a></h2>
    
        <p>The configuration directives found in a <code>.htaccess</code> file
        are applied to the directory in which the <code>.htaccess</code> file
        is found, and to all subdirectories thereof. However, it is important
        to also remember that there may have been <code>.htaccess</code> files
        in directories higher up. Directives are applied in the order that they
        are found. Therefore, a <code>.htaccess</code> file in a particular
        directory may override directives found in <code>.htaccess</code> 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.</p>
    
        <p>Example:</p>
    
        <p>In the directory <code>/www/htdocs/example1</code> we have a
        <code>.htaccess</code> file containing the following:</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI</pre>
    
    
        <p>(Note: you must have "<code>AllowOverride Options</code>" in effect
        to permit the use of the "<code class="directive"><a href="../mod/core.html#options">Options</a></code>" directive in
        <code>.htaccess</code> files.)</p>
    
        <p>In the directory <code>/www/htdocs/example1/example2</code> we have
        a <code>.htaccess</code> file containing:</p>
    
        <pre class="prettyprint lang-config">Options Includes</pre>
    
    
        <p>Because of this second <code>.htaccess</code> file, in the directory
        <code>/www/htdocs/example1/example2</code>, CGI execution is not
        permitted, as only <code>Options Includes</code> is in effect, which
        completely overrides any earlier setting that may have been in
        place.</p>
    
        <h3><a name="merge" id="merge">Merging of .htaccess with the main
        configuration files</a></h3>
    
        <p>As discussed in the documentation on <a href="../sections.html">Configuration Sections</a>,
        <code>.htaccess</code> files can override the <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> sections for
        the corresponding directory, but will be overridden 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 <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> setting. For example, to
        prevent script execution while allowing anything else to be set in
        <code>.htaccess</code> you can use:</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/htdocs"&gt;
        AllowOverride All
    &lt;/Directory&gt;
    
    &lt;Location "/"&gt;
        Options +IncludesNoExec -ExecCGI
    &lt;/Location&gt;</pre>
    
    
        <div class="note">This example assumes that your <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> is <code>/www/htdocs</code>.</div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="auth" id="auth">Authentication example</a></h2>
    
        <p>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
        <code>.htaccess</code> files in order to implement password
        authentication. This is not the case. Putting authentication directives
        in a <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
        section, in your main server configuration file, is the preferred way
        to implement this, and <code>.htaccess</code> files should be used only
        if you don't have access to the main server configuration file. See <a href="#when">above</a> for a discussion of when you should and should
        not use <code>.htaccess</code> files.</p>
    
        <p>Having said that, if you still think you need to use a
        <code>.htaccess</code> file, you may find that a configuration such as
        what follows may work for you.</p>
    
        <p><code>.htaccess</code> file contents:</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "Password Required"
    AuthUserFile "/www/passwords/password.file"
    AuthGroupFile "/www/passwords/group.file"
    Require group admins</pre>
    
    
        <p>Note that <code>AllowOverride AuthConfig</code> must be in effect
        for these directives to have any effect.</p>
    
        <p>Please see the <a href="auth.html">authentication tutorial</a> for a
        more complete discussion of authentication and authorization.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssi" id="ssi">Server Side Includes example</a></h2>
    
        <p>Another common use of <code>.htaccess</code> files is to enable
        Server Side Includes for a particular directory. This may be done with
        the following configuration directives, placed in a
        <code>.htaccess</code> file in the desired directory:</p>
    
        <pre class="prettyprint lang-config">Options +Includes
    AddType text/html shtml
    AddHandler server-parsed shtml</pre>
    
    
        <p>Note that <code>AllowOverride Options</code> and <code>AllowOverride
        FileInfo</code> must both be in effect for these directives to have any
        effect.</p>
    
        <p>Please see the <a href="ssi.html">SSI tutorial</a> for a more
        complete discussion of server-side includes.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Rewrite Rules in .htaccess files</a></h2>
    <p>When using <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> in
    <code>.htaccess</code> files, be aware that the per-directory context
    changes things a bit. In particular, rules are taken to be relative to
    the current directory, rather than being the original requested URI.
    Consider the following examples:</p>
    
    <pre class="prettyprint lang-config"># In httpd.conf
    RewriteRule "^/images/(.+)\.jpg" "/images/$1.png"
    
    # In .htaccess in root dir
    RewriteRule "^images/(.+)\.jpg" "images/$1.png"
    
    # In .htaccess in images/
    RewriteRule "^(.+)\.jpg" "$1.png"</pre>
    
    
    <p>In a <code>.htaccess</code> in your document directory, the leading
    slash is removed from the value supplied to <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>, and in the
    <code>images</code> subdirectory, <code>/images/</code> is removed from
    it. Thus, your regular expression needs to omit that portion as
    well.</p>
    
    <p>Consult the <a href="../rewrite/">mod_rewrite documentation</a> for
    further details on using <code>mod_rewrite</code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">CGI example</a></h2>
    
        <p>Finally, you may wish to use a <code>.htaccess</code> file to permit
        the execution of CGI programs in a particular directory. This may be
        implemented with the following configuration:</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI
    AddHandler cgi-script cgi pl</pre>
    
    
        <p>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:</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI
    SetHandler cgi-script</pre>
    
    
        <p>Note that <code>AllowOverride Options</code> and <code>AllowOverride
        FileInfo</code> must both be in effect for these directives to have any
        effect.</p>
    
        <p>Please see the <a href="cgi.html">CGI tutorial</a> for a more
        complete discussion of CGI programming and configuration.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">Troubleshooting</a></h2>
    
        <p>When you put configuration directives in a <code>.htaccess</code>
        file, and you don't get the desired effect, there are a number of
        things that may be going wrong.</p>
    
        <p>Most commonly, the problem is that <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> is not
        set such that your configuration directives are being honored. Make
        sure that you don't have a <code>AllowOverride None</code> in effect
        for the file scope in question. A good test for this is to put garbage
        in your <code>.htaccess</code> file and reload the page. If a server error is
        not generated, then you almost certainly have <code>AllowOverride
        None</code> in effect.</p>
    
        <p>If, on the other hand, you are getting server errors when trying to
        access documents, check your httpd error log. It will likely tell you
        that the directive used in your <code>.htaccess</code> file is not
        permitted.</p>
    
        <div class="example"><p><code>
        [Fri Sep 17 18:43:16 2010] [alert] [client 192.168.200.51] /var/www/html/.htaccess: DirectoryIndex not allowed here
        </code></p></div>
    
        <p>This will indicate either that you've used a directive that is
        never permitted in <code>.htaccess</code> files, or that you simply
        don't have <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> set to
        a level sufficient for the directive you've used. Consult the
        documentation for that particular directive to determine which is
        the case.</p>
    
        <p>Alternately, it may tell you that you had a syntax error in your
        usage of the directive itself.</p>
    
        <div class="example"><p><code>
        [Sat Aug 09 16:22:34 2008] [alert] [client 192.168.200.51] /var/www/html/.htaccess: RewriteCond: bad flag delimiters
        </code></p></div>
    
        <p>In this case, the error message should be specific to the
        particular syntax error that you have committed.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/htaccess.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/reverse_proxy.html.en������������������������������������������������0000664�0001751�0001751�00000050140�14737241666�022412� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Reverse Proxy Guide - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Reverse Proxy Guide</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/reverse_proxy.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/howto/reverse_proxy.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>In addition to being a "basic" web server, and providing static and
        dynamic content to end-users, Apache httpd (as well as most other web
        servers) can also act as a reverse proxy server, also-known-as a
        "gateway" server.</p>
    
        <p>In such scenarios, httpd itself does not generate or host the data,
        but rather the content is obtained by one or several backend servers,
        which normally have no direct connection to the external network. As
        httpd receives a request from a client, the request itself is <em>proxied</em>
        to one of these backend servers, which then handles the request, generates
        the content and then sends this content back to httpd, which then
        generates the actual HTTP response back to the client.</p>
    
        <p>There are numerous reasons for such an implementation, but generally
        the typical rationales are due to security, high-availability, load-balancing
        and centralized authentication/authorization. It is critical in these
        implementations that the layout, design and architecture of the backend
        infrastructure (those servers which actually handle the requests) are
        insulated and protected from the outside; as far as the client is concerned,
        the reverse proxy server <em>is</em> the sole source of all content.</p>
    
        <p>A typical implementation is below:</p>
        <p class="centered"><img src="../images/reverse-proxy-arch.png" alt="reverse-proxy-arch" /></p>
    
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Reverse Proxy</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple">Simple reverse proxying</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cluster">Clusters and Balancers</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">Balancer and BalancerMember configuration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#failover">Failover</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#manager">Balancer Manager</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#health-check">Dynamic Health Checks</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#status">BalancerMember status flags</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Reverse Proxy</a></h2>
      
      <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="../mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code></li><li><code class="module"><a href="../mod/mod_proxy_hcheck.html">mod_proxy_hcheck</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="../mod/mod_proxy.html#balancermember">BalancerMember</a></code></li></ul></td></tr></table>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple" id="simple">Simple reverse proxying</a></h2>
        
    
        <p>
          The <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>
          directive specifies the mapping of incoming requests to the backend
          server (or a cluster of servers known as a <code>Balancer</code>
          group). The simplest example proxies all requests (<code>"/"</code>)
          to a single backend:
        </p>
    
        <pre class="prettyprint lang-config">ProxyPass "/"  "http://www.example.com/"</pre>
    
    
        <p>
          To ensure that and <code>Location:</code> headers generated from
          the backend are modified to point to the reverse proxy, instead of
          back to itself, the <code class="directive"><a href="../mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code>
          directive is most often required:
        </p>
    
        <pre class="prettyprint lang-config">ProxyPass "/"  "http://www.example.com/"
    ProxyPassReverse "/"  "http://www.example.com/"</pre>
    
    
        <p>Only specific URIs can be proxied, as shown in this example:</p>
    
        <pre class="prettyprint lang-config">ProxyPass "/images"  "http://www.example.com/"
    ProxyPassReverse "/images"  "http://www.example.com/"</pre>
    
    
        <p>In the above, any requests which start with the <code>/images</code>
          path with be proxied to the specified backend, otherwise it will be handled
          locally.
        </p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cluster" id="cluster">Clusters and Balancers</a></h2>
        
    
        <p>
          As useful as the above is, it still has the deficiencies that should
          the (single) backend node go down, or become heavily loaded, that proxying
          those requests provides no real advantage. What is needed is the ability
          to define a set or group of backend servers which can handle such
          requests and for the reverse proxy to load balance and failover among
          them. This group is sometimes called a <em>cluster</em> but Apache httpd's
          term is a <em>balancer</em>. One defines a balancer by leveraging the
          <code class="directive"><a href="../mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> and
          <code class="directive"><a href="../mod/mod_proxy.html#balancermember">BalancerMember</a></code> directives as
          shown:
        </p>
    
        <pre class="prettyprint lang-config">&lt;Proxy balancer://myset&gt;
        BalancerMember http://www2.example.com:8080
        BalancerMember http://www3.example.com:8080
        ProxySet lbmethod=bytraffic
    &lt;/Proxy&gt;
    
    ProxyPass "/images/"  "balancer://myset/"
    ProxyPassReverse "/images/"  "balancer://myset/"</pre>
    
    
        <p>
          The <code>balancer://</code> scheme is what tells httpd that we are creating
          a balancer set, with the name <em>myset</em>. It includes 2 backend servers,
          which httpd calls <em>BalancerMembers</em>. In this case, any requests for
          <code>/images</code> will be proxied to <em>one</em> of the 2 backends.
          The <code class="directive"><a href="../mod/mod_proxy.html#proxyset">ProxySet</a></code> directive
          specifies that the <em>myset</em> Balancer use a load balancing algorithm
          that balances based on I/O bytes.
        </p>
    
        <div class="note"><h3>Hint</h3>
          <p>
          	<em>BalancerMembers</em> are also sometimes referred to as <em>workers</em>.
          </p>
       </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">Balancer and BalancerMember configuration</a></h2>
        
    
        <p>
          You can adjust numerous configuration details of the <em>balancers</em>
          and the <em>workers</em> via the various parameters defined in
          <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>. For example,
          assuming we would want <code>http://www3.example.com:8080</code> to
          handle 3x the traffic with a timeout of 1 second, we would adjust the
          configuration as follows:
        </p>
    
        <pre class="prettyprint lang-config">&lt;Proxy balancer://myset&gt;
        BalancerMember http://www2.example.com:8080
        BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
        ProxySet lbmethod=bytraffic
    &lt;/Proxy&gt;
    
    ProxyPass "/images"  "balancer://myset/"
    ProxyPassReverse "/images"  "balancer://myset/"</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="failover" id="failover">Failover</a></h2>
        
    
        <p>
          You can also fine-tune various failover scenarios, detailing which workers
          and even which balancers should be accessed in such cases. For example, the
          below setup implements three failover cases:
        </p>
        <ol>
          <li>
            <code>http://spare1.example.com:8080</code> and
            <code>http://spare2.example.com:8080</code> are only sent traffic if one
            or both of <code>http://www2.example.com:8080</code> or
            <code>http://www3.example.com:8080</code> is unavailable. (One spare
            will be used to replace one unusable member of the same balancer set.)
          </li>
          <li>
            <code>http://hstandby.example.com:8080</code> is only sent traffic if
            all other workers in balancer set <code>0</code> are not available.
          </li>
          <li>
            If all load balancer set <code>0</code> workers, spares, and the standby
            are unavailable, only then will the
            <code>http://bkup1.example.com:8080</code> and
            <code>http://bkup2.example.com:8080</code> workers from balancer set
            <code>1</code> be brought into rotation.
          </li>
        </ol>
        <p>
          Thus, it is possible to have one or more hot spares and hot standbys for
          each load balancer set.
        </p>
    
        <pre class="prettyprint lang-config">&lt;Proxy balancer://myset&gt;
        BalancerMember http://www2.example.com:8080
        BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
        BalancerMember http://spare1.example.com:8080 status=+R
        BalancerMember http://spare2.example.com:8080 status=+R
        BalancerMember http://hstandby.example.com:8080 status=+H
        BalancerMember http://bkup1.example.com:8080 lbset=1
        BalancerMember http://bkup2.example.com:8080 lbset=1
        ProxySet lbmethod=byrequests
    &lt;/Proxy&gt;
    
    ProxyPass "/images/"  "balancer://myset/"
    ProxyPassReverse "/images/"  "balancer://myset/"</pre>
    
    
        <p>
          For failover, hot spares are used as replacements for unusable workers in
          the same load balancer set. A worker is considered unusable if it is
          draining, stopped, or otherwise in an error/failed state. Hot standbys are
          used if all workers and spares in the load balancer set are
          unavailable. Load balancer sets (with their respective hot spares and
          standbys) are always tried in order from lowest to highest.
        </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="manager" id="manager">Balancer Manager</a></h2>
        
    
        <p>
          One of the most unique and useful features of Apache httpd's reverse proxy is
    	  the embedded <em>balancer-manager</em> application. Similar to
    	  <code class="module"><a href="../mod/mod_status.html">mod_status</a></code>, <em>balancer-manager</em> displays
    	  the current working configuration and status of the enabled
    	  balancers and workers currently in use. However, not only does it
    	  display these parameters, it also allows for dynamic, runtime, on-the-fly
    	  reconfiguration of almost all of them, including adding new <em>BalancerMembers</em>
    	  (workers) to an existing balancer. To enable these capability, the following
    	  needs to be added to your configuration:
        </p>
    
        <pre class="prettyprint lang-config">&lt;Location "/balancer-manager"&gt;
        SetHandler balancer-manager
        Require host localhost
    &lt;/Location&gt;</pre>
    
    
        <div class="warning"><h3>Warning</h3>
          <p>Do not enable the <em>balancer-manager</em> until you have <a href="../mod/mod_proxy.html#access">secured your server</a>. In
          particular, ensure that access to the URL is tightly
          restricted.</p>
        </div>
    
        <p>
          When the reverse proxy server is accessed at that url
          (eg: <code>http://rproxy.example.com/balancer-manager/</code>, you will see a
          page similar to the below:
        </p>
        <p class="centered"><img src="../images/bal-man.png" alt="balancer-manager page" /></p>
    
        <p>
          This form allows the devops admin to adjust various parameters, take
          workers offline, change load balancing methods and add new works. For
          example, clicking on the balancer itself, you will get the following page:
        </p>
        <p class="centered"><img src="../images/bal-man-b.png" alt="balancer-manager page" /></p>
    
        <p>
          Whereas clicking on a worker, displays this page:
        </p>
        <p class="centered"><img src="../images/bal-man-w.png" alt="balancer-manager page" /></p>
    
        <p>
          To have these changes persist restarts of the reverse proxy, ensure that
          <code class="directive"><a href="../mod/mod_proxy.html#balancerpersist">BalancerPersist</a></code> is enabled.
        </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="health-check" id="health-check">Dynamic Health Checks</a></h2>
        
    
        <p>
          Before httpd proxies a request to a worker, it can <em>"test"</em> if that worker
          is available via setting the <code>ping</code> parameter for that worker using
          <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>. Oftentimes it is
          more useful to check the health of the workers <em>out of band</em>, in a
          dynamic fashion. This is achieved in Apache httpd by the
          <code class="module"><a href="../mod/mod_proxy_hcheck.html">mod_proxy_hcheck</a></code> module.
        </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="status" id="status">BalancerMember status flags</a></h2>
        
    
        <p>
          In the <em>balancer-manager</em> the current state, or <em>status</em>, of a worker
          is displayed and can be set/reset. The meanings of these statuses are as follows:
        </p>
          <table class="bordered">
          	<tr><th>Flag</th><th>String</th><th>Description</th></tr>
          	<tr><td>&nbsp;</td><td><em>Ok</em></td><td>Worker is available</td></tr>
          	<tr><td>&nbsp;</td><td><em>Init</em></td><td>Worker has been initialized</td></tr>
            <tr><td><code>D</code></td><td><em>Dis</em></td><td>Worker is disabled and will not accept any requests; will be
                        automatically retried.</td></tr>
            <tr><td><code>S</code></td><td><em>Stop</em></td><td>Worker is administratively stopped; will not accept requests
                        and will not be automatically retried</td></tr>
            <tr><td><code>I</code></td><td><em>Ign</em></td><td>Worker is in ignore-errors mode and will always be considered available.</td></tr>
            <tr><td><code>R</code></td><td><em>Spar</em></td><td>Worker is a hot spare. For each worker in a given lbset that is unusable
                        (draining, stopped, in error, etc.), a usable hot spare with the same lbset will be used in
                        its place. Hot spares can help ensure that a specific number of workers are always available
                        for use by a balancer.</td></tr>
            <tr><td><code>H</code></td><td><em>Stby</em></td><td>Worker is in hot-standby mode and will only be used if no other
                        viable workers or spares are available in the balancer set.</td></tr>
            <tr><td><code>E</code></td><td><em>Err</em></td><td>Worker is in an error state, usually due to failing pre-request check;
                        requests will not be proxied to this worker, but it will be retried depending on
                        the <code>retry</code> setting of the worker.</td></tr>
            <tr><td><code>N</code></td><td><em>Drn</em></td><td>Worker is in drain mode and will only accept existing sticky sessions
                        destined for itself and ignore all other requests.</td></tr>
            <tr><td><code>C</code></td><td><em>HcFl</em></td><td>Worker has failed dynamic health check and will not be used until it
                        passes subsequent health checks.</td></tr>
          </table>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/reverse_proxy.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/howto/reverse_proxy.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/reverse_proxy.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/cgi.html.en����������������������������������������������������������0000664�0001751�0001751�00000074463�14737241666�020256� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache Tutorial: Dynamic Content with CGI - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Apache Tutorial: Dynamic Content with CGI</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/cgi.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#intro">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">Configuring Apache to permit CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#writing">Writing a CGI program</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">But it's still not working!</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#behindscenes">What's going on behind the scenes?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#libraries">CGI modules/libraries</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinfo">For more information</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">Introduction</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_cgid.html">mod_cgid</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li></ul></td></tr></table>
    
        <p>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 a simple way to put dynamic content on
        your web site, using whatever programming language you're most
        familiar with. This document will be an introduction to setting
        up CGI on your Apache web server, and getting started writing
        CGI programs.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">Configuring Apache to permit CGI</a></h2>
        
    
        <p>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.</p>
    
        <div class="warning">Note: If Apache has been built with shared module
        support you need to ensure that the module is loaded; in your
        <code>httpd.conf</code> you need to make sure the
        <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>
        directive has not been commented out.  A correctly configured directive
        may look like this:
    
        <pre class="prettyprint lang-config">LoadModule cgid_module modules/mod_cgid.so</pre>
    
    
    
         On Windows, or using a non-threaded MPM like prefork,  A correctly 
         configured directive may look like this:
    
        <pre class="prettyprint lang-config">LoadModule cgi_module modules/mod_cgi.so</pre>
    </div>
    
    
        <h3><a name="scriptalias" id="scriptalias">ScriptAlias</a></h3>
          
    
          <p>The
          <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
    
          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.</p>
    
          <p>The <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          directive looks like:</p>
    
          <pre class="prettyprint lang-config">ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"</pre>
    
    
          <p>The example shown is from your default <code>httpd.conf</code>
          configuration file, if you installed Apache in the default
          location. The <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          directive is much like the <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> directive, which defines a URL prefix that
          is to mapped to a particular directory. <code class="directive">Alias</code>
          and <code class="directive">ScriptAlias</code> are usually used for
          directories that are outside of the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> directory. The difference between
          <code class="directive">Alias</code> and <code class="directive">ScriptAlias</code>
          is that <code class="directive">ScriptAlias</code> 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 <code>/cgi-bin/</code> should be served from
          the directory  <code>/usr/local/apache2/cgi-bin/</code>, and should be
          treated as a CGI program.</p>
    
          <p>For example, if the URL
          <code>http://www.example.com/cgi-bin/test.pl</code>
          is requested, Apache will attempt to execute the file
          <code>/usr/local/apache2/cgi-bin/test.pl</code>
          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.</p>
        
    
        <h3><a name="nonscriptalias" id="nonscriptalias">CGI outside of ScriptAlias directories</a></h3>
          
    
          <p>CGI programs are often restricted to <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>'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
          <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> directive.
          If they want to have their own CGI programs, but don't have access to
          the main <code>cgi-bin</code> directory, they will need to be able to
          run CGI programs elsewhere.</p>
    
          <p>There are two steps to allowing CGI execution in an arbitrary
          directory.  First, the <code>cgi-script</code> handler must be
          activated using the <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> or <code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code> directive.  Second,
          <code>ExecCGI</code> must be specified in the <code class="directive"><a href="../mod/core.html#options">Options</a></code> directive.</p>
        
    
        <h3><a name="options" id="options">Explicitly using Options to permit CGI execution</a></h3>
          
    
          <p>You could explicitly use the <code class="directive"><a href="../mod/core.html#options">Options</a></code> directive, inside your main server configuration
          file, to specify that CGI execution was permitted in a particular
          directory:</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/usr/local/apache2/htdocs/somedir"&gt;
        Options +ExecCGI
    &lt;/Directory&gt;</pre>
    
    
          <p>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 <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> directive tells the server to treat all
          files with the <code>cgi</code> or <code>pl</code> extension as CGI
          programs:</p>
    
          <pre class="prettyprint lang-config">AddHandler cgi-script .cgi .pl</pre>
    
        
    
        <h3><a name="htaccess" id="htaccess">.htaccess files</a></h3>
          
    
          <p>The <a href="htaccess.html"><code>.htaccess</code> tutorial</a>
          shows how to activate CGI programs if you do not have
          access to <code>httpd.conf</code>.</p>
        
    
        <h3><a name="userdir" id="userdir">User Directories</a></h3>
          
    
          <p>To allow CGI program execution for any file ending in
          <code>.cgi</code> in users' directories, you can use the
          following configuration.</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html"&gt;
        Options +ExecCGI
        AddHandler cgi-script .cgi
    &lt;/Directory&gt;</pre>
    
    
          <p>If you wish designate a <code>cgi-bin</code> subdirectory of
          a user's directory where everything will be treated as a CGI
          program, you can use the following.</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html/cgi-bin"&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="writing" id="writing">Writing a CGI program</a></h2>
        
    
        <p>There are two main differences between ``regular''
        programming, and CGI programming.</p>
    
        <p>First, all output from your CGI program must be preceded by
        a <a class="glossarylink" href="../glossary.html#mime-type" title="see glossary">MIME-type</a> header. This is HTTP header that tells the client
        what sort of content it is receiving. Most of the time, this
        will look like:</p>
    
        <div class="example"><p><code>
          Content-type: text/html
        </code></p></div>
    
        <p>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.</p>
    
        <p>Apart from those two things, writing a CGI program will look
        a lot like any other program that you might write.</p>
    
        <h3><a name="firstcgi" id="firstcgi">Your first CGI program</a></h3>
          
    
          <p>The following is an example CGI program that prints one
          line to your browser. Type in the following, save it to a
          file called <code>first.pl</code>, and put it in your
          <code>cgi-bin</code> directory.</p>
    
          <pre class="prettyprint lang-perl">#!/usr/bin/perl
    print "Content-type: text/html\n\n";
    print "Hello, World.";</pre>
    
    
          <p>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 <code>/usr/bin/perl</code>.
          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.</p>
    
          <p>If you open your favorite browser and tell it to get the
          address</p>
    
          <div class="example"><p><code>
            http://www.example.com/cgi-bin/first.pl
          </code></p></div>
    
          <p>or wherever you put your file, you will see the one line
          <code>Hello, World.</code> 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.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">But it's still not working!</a></h2>
        
    
        <p>There are four basic things that you may see in your browser
        when you try to access your CGI program from the web:</p>
    
        <dl>
          <dt>The output of your CGI program</dt>
          <dd>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 <code>Content-Type</code> set in your CGI program.</dd>
    
          <dt>The source code of your CGI program or a "POST Method Not
          Allowed" message</dt>
          <dd>That means that you have not properly configured Apache
          to process your CGI program. Reread the section on
          <a href="#configuring">configuring
          Apache</a> and try to find what you missed.</dd>
    
          <dt>A message starting with "Forbidden"</dt>
          <dd>That means that there is a permissions problem. Check the
          <a href="#errorlogs">Apache error log</a> and the section below on
          <a href="#permissions">file permissions</a>.</dd>
    
          <dt>A message saying "Internal Server Error"</dt>
          <dd>If you check the
          <a href="#errorlogs">Apache error log</a>, 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.</dd>
        </dl>
    
        <h3><a name="permissions" id="permissions">File permissions</a></h3>
          
    
          <p>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 <code>nobody</code>, or
          <code>www</code> - 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 <code>nobody</code>
          is to give everyone execute permission on the file:</p>
    
          <div class="example"><p><code>
            chmod a+x first.pl
          </code></p></div>
    
          <p>Also, if your program reads from, or writes to, any other
          files, those files will need to have the correct permissions
          to permit this.</p>
    
        
    
        <h3><a name="pathinformation" id="pathinformation">Path information and environment</a></h3>
          
    
          <p>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 <code>PATH</code>,
          which tells the shell where it can look for files that you
          reference.</p>
    
          <p>When a program runs through the web server as a CGI program,
          it may not have the same <code>PATH</code>. Any programs that you
          invoke in your CGI program (like <code>sendmail</code>, 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.</p>
    
          <p>A common manifestation of this is the path to the script
          interpreter (often <code>perl</code>) indicated in the first
          line of your CGI program, which will look something like:</p>
    
          <pre class="prettyprint lang-perl">#!/usr/bin/perl</pre>
    
    
          <p>Make sure that this is in fact the path to the
          interpreter.</p>
          <div class="warning">
          When editing CGI scripts on Windows, end-of-line characters may be
          appended to the interpreter path. Ensure that files are then
          transferred to the server in ASCII mode. Failure to do so may
          result in "Command not found" warnings from the OS, due to the
          unrecognized end-of-line character being interpreted as a part of
          the interpreter filename.
          </div>
        
    
        <h3><a name="missingenv" id="missingenv">Missing environment variables</a></h3>
          
    
          <p>If your CGI program depends on non-standard <a href="#env">environment variables</a>, you will need to
          assure that those variables are passed by Apache.</p>
    
          <p>When you miss HTTP headers from the environment, make
          sure they are formatted according to
          <a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>,
          section 4.2: Header names must start with a letter,
          followed only by letters, numbers or hyphen. Any header
          violating this rule will be dropped silently.</p>
    
        
    
        <h3><a name="syntaxerrors" id="syntaxerrors">Program errors</a></h3>
          
    
          <p>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:</p>
    
          <div class="example"><p><code>
          cd /usr/local/apache2/cgi-bin<br />
          ./first.pl
          </code></p></div>
    
          <p>(Do not call the <code>perl</code> interpreter.  The shell
          and Apache should find the interpreter using the <a href="#pathinformation">path information</a> on the first line of
          the script.)</p>
    
          <p>The first thing you see written by your program should be
          a set of HTTP headers, including the <code>Content-Type</code>,
          followed by a blank line.  If you see anything else, Apache will
          return the <code>Premature end of script headers</code> error if
          you try to run it through the server. See <a href="#writing">Writing a CGI program</a> above for more
          details.</p>
        
    
        <h3><a name="errorlogs" id="errorlogs">Error logs</a></h3>
          
    
          <p>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.</p>
        
    
        <h3><a name="suexec" id="suexec">Suexec</a></h3>
          
    
          <p>The <a href="../suexec.html">suexec</a> 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 <code>Premature end of script headers</code>.</p>
    
          <p>To check if you are using suexec, run <code>apachectl
          -V</code> and check for the location of <code>SUEXEC_BIN</code>.
          If Apache finds an <code class="program"><a href="../programs/suexec.html">suexec</a></code> binary there on startup,
          suexec will be activated.</p>
    
          <p>Unless you fully understand suexec, you should not be using it.
          To disable suexec, simply remove (or rename) the <code class="program"><a href="../programs/suexec.html">suexec</a></code>
          binary pointed to by <code>SUEXEC_BIN</code> and then restart the
          server.  If, after reading about <a href="../suexec.html">suexec</a>,
          you still wish to use it, then run <code>suexec -V</code> to find
          the location of the suexec log file, and use that log file to
          find what policy you are violating.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behindscenes" id="behindscenes">What's going on behind the scenes?</a></h2>
        
    
        <p>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.</p>
    
        <h3><a name="env" id="env">Environment variables</a></h3>
          
    
          <p>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
          <code>env</code> at a command prompt.</p>
    
          <p>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.</p>
    
          <p>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
          <a href="http://www.ietf.org/rfc/rfc3875">Common Gateway
          Interface RFC</a>.</p>
    
          <p>This simple Perl CGI program will display all of the
          environment variables that are being passed around. Two
          similar programs are included in the
          <code>cgi-bin</code>
    
          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
          <a href="../env.html">add your own environment variables</a>
          to the basic ones provided by default.</p>
    
          <pre class="prettyprint lang-perl">#!/usr/bin/perl
    use strict;
    use warnings;
    
    print "Content-type: text/html\n\n";
    foreach my $key (keys %ENV) {
        print "$key --&gt; $ENV{$key}&lt;br&gt;";
    }</pre>
    
        
    
        <h3><a name="stdin" id="stdin">STDIN and STDOUT</a></h3>
          
    
          <p>Other communication between the server and the client
          happens over standard input (<code>STDIN</code>) and standard
          output (<code>STDOUT</code>). In normal everyday context,
          <code>STDIN</code> means the keyboard, or a file that a
          program is given to act on, and <code>STDOUT</code>
          usually means the console or screen.</p>
    
          <p>When you <code>POST</code> 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 <code>STDIN</code>.
          The program then can process that data as though it was
          coming in from the keyboard, or from a file</p>
    
          <p>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
          (&amp;). 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:</p>
    
          <div class="example"><p><code>
            name=Rich%20Bowen&amp;city=Lexington&amp;state=KY&amp;sidekick=Squirrel%20Monkey
          </code></p></div>
    
          <p>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
          <code>QUERY_STRING</code>. That's called a <code>GET</code>
          request. Your HTML form specifies whether a <code>GET</code>
          or a <code>POST</code> is used to deliver the data, by setting the
          <code>METHOD</code> attribute in the <code>FORM</code> tag.</p>
    
          <p>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.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="libraries" id="libraries">CGI modules/libraries</a></h2>
        
    
        <p>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.</p>
    
        <p>If you're writing CGI programs in Perl, modules are
        available on <a href="http://www.cpan.org/">CPAN</a>. The most
        popular module for this purpose is <code>CGI.pm</code>. You might
        also consider <code>CGI::Lite</code>, which implements a minimal
        set of functionality, which is all you need in most programs.</p>
    
        <p>If you're writing CGI programs in C, there are a variety of
        options. One of these is the <code>CGIC</code> library, from
        <a href="https://web.mit.edu/wwwdev/www/cgic.html">https://web.mit.edu/wwwdev/www/cgic.html</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinfo" id="moreinfo">For more information</a></h2>
        
    
        <p>The current CGI specification is available in the
        <a href="http://www.ietf.org/rfc/rfc3875">Common Gateway
        Interface RFC</a>.</p>
    
        <p>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.</p>
    
        <p>Note that questions about CGI problems should <strong>never</strong>
        be posted to the Apache bug database unless you are sure you
        have found a problem in the Apache source code.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/cgi.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/cgi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/public_html.html.en��������������������������������������������������0000664�0001751�0001751�00000032541�14737241666�022005� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Per-user web directories - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Per-user web directories</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/public_html.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    <p>On systems with multiple users, each user can be permitted to have a
        web site in their home directory using the <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> directive. Visitors
        to a URL <code>http://example.com/~username/</code> will get content
        out of the home directory of the user "<code>username</code>", out of
        the subdirectory specified by the <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> directive.</p>
    <p>Note that, by default, access to these directories is <strong>not</strong>
        enabled. You can enable access when using <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> by uncommenting the line:</p>
        <pre class="prettyprint lang-config">#Include conf/extra/httpd-userdir.conf</pre>
    
        <p>in the default config file <code>conf/httpd.conf</code>, and adapting the <code>httpd-userdir.conf</code>
        file as necessary, or by including the appropriate directives in a
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> block
        within the main config file.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Per-user web directories</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#userdir">Setting the file path with UserDir</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#redirect">Redirecting to external URLs</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#enable">Restricting what users are permitted to use this
        feature</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">Enabling a cgi directory for each user</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">Allowing users to alter configuration</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../urlmapping.html">Mapping URLs to the Filesystem</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Per-user web directories</a></h2>
        
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code></li><li><code class="directive"><a href="../mod/core.html#directorymatch">DirectoryMatch</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="userdir" id="userdir">Setting the file path with UserDir</a></h2>
        
    
        <p>The <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
        directive specifies a directory out of which per-user
        content is loaded. This directive may take several different forms.</p>
    
        <p>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:</p>
    
        <pre class="prettyprint lang-config">UserDir public_html</pre>
    
    
        <p>the URL <code>http://example.com/~rbowen/file.html</code> will be
        translated to the file path
        <code>/home/rbowen/public_html/file.html</code></p>
    
        <p>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:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/html</pre>
    
    
        <p>the URL <code>http://example.com/~rbowen/file.html</code> will be
        translated to the file path <code>/var/html/rbowen/file.html</code></p>
    
        <p>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:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/www/*/docs</pre>
    
    
        <p>the URL <code>http://example.com/~rbowen/file.html</code> will be
        translated to the file path
        <code>/var/www/rbowen/docs/file.html</code></p>
    
        <p>Multiple directories or directory paths can also be set.</p>
    
        <pre class="prettyprint lang-config">UserDir public_html /var/html</pre>
    
    
        <p>For the URL <code>http://example.com/~rbowen/file.html</code>,
        Apache will search for <code>~rbowen</code>. If it isn't found,
        Apache will search for <code>rbowen</code> in <code>/var/html</code>. If
        found, the above URL will then be translated to the file path
        <code>/var/html/rbowen/file.html</code></p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">Redirecting to external URLs</a></h2>
        
        <p>The <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> directive can be
          used to redirect user directory requests to external URLs.</p>
    
        <pre class="prettyprint lang-config">UserDir http://example.org/users/*/</pre>
    
    
        <p>The above example will redirect a request for
        <code>http://example.com/~bob/abc.html</code> to
        <code>http://example.org/users/bob/abc.html</code>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">Restricting what users are permitted to use this
        feature</a></h2>
        
    
        <p>Using the syntax shown in the UserDir documentation, you can restrict
        what users are permitted to use this functionality:</p>
    
        <pre class="prettyprint lang-config">UserDir disabled root jro fish</pre>
    
    
        <p>The configuration above will enable the feature for all users
        except for those listed in the <code>disabled</code> statement.
        You can, likewise, disable the feature for all but a few users by
        using a configuration like the following:</p>
    
        <pre class="prettyprint lang-config">UserDir disabled
    UserDir enabled rbowen krietz</pre>
    
    
        <p>See <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
        documentation for additional examples.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">Enabling a cgi directory for each user</a></h2>
      
    
       <p>In order to give each user their own cgi-bin directory, you can use
        a <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
        directive to make a particular subdirectory of a user's home directory
        cgi-enabled.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html/cgi-bin/"&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
    
        <p>Then, presuming that <code>UserDir</code> is set to
        <code>public_html</code>, a cgi program <code>example.cgi</code>
        could be loaded from that directory as:</p>
    
        <div class="example"><p><code>
        http://example.com/~rbowen/cgi-bin/example.cgi
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">Allowing users to alter configuration</a></h2>
        
    
        <p>If you want to allows users to modify the server configuration in
        their web space, they will need to use <code>.htaccess</code> files to
        make these changes. Ensure that you have set <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> to a
        value sufficient for the directives that you want to permit the users
        to modify. See the <a href="htaccess.html">.htaccess tutorial</a> for
        additional details on how this works.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/public_html.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/public_html.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/access.html.es�������������������������������������������������������0000664�0001751�0001751�00000035257�14743132254�020745� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Control de Acceso - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a> &gt; <a href="./">How-To / Tutoriales</a></div><div id="page-content"><div id="preamble"><h1>Control de Acceso</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/access.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/access.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/access.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>El control de acceso, hace referencia a todos los medios que proporcionan
            una forma de controlar el acceso a cualquier recurso. Esta parte est&#225;
            separada de <a href="auth.html">autenticaci&#243;n y autorizaci&#243;n</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">M&#243;dulos y Directivas relacionados</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#host">Control de Acceso por host</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#env">Control de acceso por variables arbitrarias.</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Control de acceso con mod_rewrite</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">M&#225;s informaci&#243;n</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">M&#243;dulos y Directivas relacionados</a></h2>
    
        <p>El control de acceso puede efectuarse mediante diferentes m&#243;dulos. Los 
        m&#225;s importantes de &#233;stos son <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> y
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>. Tambi&#233;n se habla en este documento de
        el control de acceso usando el m&#243;dulo <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="host" id="host">Control de Acceso por host</a></h2>
        <p>
        Si lo que se quiere es restringir algunas zonas del sitio web, bas&#225;ndonos
        en la direcci&#243;n del visitante, esto puede ser realizado de manera 
        f&#225;cil con el m&#243;dulo <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>.
        </p>
    
        <p>La directiva <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
        proporciona una variedad de diferentes maneras de permitir o denegar el acceso a los recursos. Adem&#225;s puede ser usada junto con las directivas:<code class="directive"><a href="../mod/mod_authz_core.html#requireall">RequireAll</a></code>, <code class="directive"><a href="../mod/mod_authz_core.html#requireany">RequireAny</a></code>, y <code class="directive"><a href="../mod/mod_authz_core.html#requirenone">RequireNone</a></code>, estos requerimientos pueden
        ser combinados de forma compleja y arbitraria, para cumplir cualquiera que
        sean tus pol&#237;ticas de acceso.</p>
    
        <div class="warning"><p>
        Las directivas <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>,
        <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code>, y
        <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>,
        proporcionadas por <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code>, est&#225;n obsoletas y
        ser&#225;n quitadas en futuras versiones. Deber&#225; evitar su uso, y tambi&#233;n
        los tutoriales desactualizaos que recomienden su uso.
        </p></div>
    
        <p>El uso de estas directivas es:</p>
    
     
        <pre class="prettyprint lang-config">Require host <var>address</var> <br />
    Require ip <var>ip.address</var>
        </pre>
    
    
        <p>En la primera l&#237;nea, <var>address</var> es el FQDN de un nombre de 
        dominio (o un nombre parcial del dominio); puede proporcionar m&#250;ltiples
        direcciones o nombres de dominio, si se desea.
        </p>
    
        <p>En la segunda l&#237;nea, <var>ip.address</var> es la direcci&#243;n IP, una
        direcci&#243;n IP parcial, una red con su m&#225;scara, o una especificaci&#243;n red/nnn 
        CIDR. Pueden usarse tanto IPV4 como IPV6.</p>
    
        <p>Consulte tambi&#233;n <a href="../mod/mod_authz_host.html#requiredirectives">la 
        documentaci&#243;n de mod_authz_host </a> para otros ejemplos de esta sintaxis.
        </p>
    
        <p>Puede ser insertado <code>not</code> para negar un requisito en particular.
        Note que, ya que <code>not</code> es una negaci&#243;n de un valor, no puede ser 
        usado por si solo para permitir o denegar una petici&#243;n, como <em>not true</em>
        que no contituye ser <em>false</em>. En consecuencia, para denegar una 
        visita usando una negaci&#243;n, el bloque debe tener un elemento que se eval&#250;a como
        verdadero o falso. Por ejemplo, si tienes a alguien espameandote tu tabl&#243;n de 
        mensajes, y tu quieres evitar que entren o dejarlos fuera, puedes realizar
        lo siguiente:
        </p>
    
        <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 10.252.46.165
    &lt;/RequireAll&gt;</pre>
    
    
        <p>Los visitantes que vengan desde la IP que se configura (<code>10.252.46.165</code>)
        no tendr&#225;n acceso al contenido que cubre esta directiva. Si en cambio, lo que se 
        tiene es el nombre de la m&#225;quina, en vez de la IP, podr&#225;s usar:</p>
    
        <pre class="prettyprint lang-config">Require not host <var>host.example.com</var>
        </pre>
    
    
        <p>Y, Si lo que se quiere es bloquear el acceso desde dominio especifico, 
            podr&#225;s especificar parte de una direcci&#243;n o nombre de dominio:</p>
    
        <pre class="prettyprint lang-config">Require not ip 192.168.205
    Require not host phishers.example.com moreidiots.example
    Require not host gov</pre>
    
    
        <p>Uso de las directivas <code class="directive"><a href="../mod/mod_authz_core.html#requireall">RequireAll</a></code>, <code class="directive"><a href="../mod/mod_authz_core.html#requireany">RequireAny</a></code>, y <code class="directive"><a href="../mod/mod_authz_core.html#requirenone">RequireNone</a></code> pueden ser usadas
        para forzar requisitos m&#225;s complejos.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="env" id="env">Control de acceso por variables arbitrarias.</a></h2>
    
        <p>Haciendo el uso de <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>,
        puedes permitir o denegar el acceso basado en variables de entrono arbitrarias
        o en los valores de las cabeceras de las peticiones. Por ejemplo para denegar 
        el acceso bas&#225;ndonos en el "user-agent" (tipo de navegador as&#237; como Sistema Operativo)
        puede que hagamos lo siguiente:
        </p>
    
        <pre class="prettyprint lang-config">&lt;If "%{HTTP_USER_AGENT} == 'BadBot'"&gt;
        Require all denied
    &lt;/If&gt;</pre>
    
    
        <p>Usando la sintaxis de <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
        <code>expr</code> , esto tambi&#233;n puede ser escrito de la siguiente forma:
        </p>
    
    
        <pre class="prettyprint lang-config">Require expr %{HTTP_USER_AGENT} != 'BadBot'</pre>
    
    
        <div class="note"><h3>Advertencia:</h3>
        <p>El control de acceso por <code>User-Agent</code> es una t&#233;cnica poco fiable,
        ya que la cabecera de <code>User-Agent</code> puede ser modificada y establecerse 
        al antojo del usuario.</p>
        </div>
    
        <p>Vea tambi&#233;n la p&#225;gina de  <a href="../expr.html">expresiones</a>
        para una mayor aclaraci&#243;n de que sintaxis tienen las expresiones y que
        variables est&#225;n disponibles.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Control de acceso con mod_rewrite</a></h2>
    
        <p>El flag <code>[F]</code> de <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> causa una respuesta 403 Forbidden
        para ser enviada. USando esto, podr&#225; denegar el acceso a recursos bas&#225;ndose
        en criterio arbitrario.</p>
    
        <p>Por ejemplo, si lo que desea es bloquear un recurso entre las 8pm y las 
            7am, podr&#225; hacerlo usando <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>:</p>
    
        <pre class="prettyprint lang-config">RewriteEngine On
    RewriteCond "%{TIME_HOUR}" "&gt;=20" [OR]
    RewriteCond "%{TIME_HOUR}" "&lt;07"
    RewriteRule "^/fridge"     "-"       [F]</pre>
    
    
        <p>Esto devolver&#225; una respuesta de error 403 Forbidden para cualquier  petici&#243;n 
        despu&#233;s de las 8pm y antes de las 7am. Esta t&#233;cnica puede ser usada para cualquier 
        criterio que desee usar. Tambi&#233;n puede redireccionar, o incluso reescribir estas 
        peticiones, si se prefiere ese enfoque.
        </p>
    
        <p>La directiva <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>,
         a&#241;adida en la 2.4, sustituye muchas cosas que <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
         tradicionalmente sol&#237;a hacer, y deber&#225; comprobar estas antes de recurrir a 
        </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">M&#225;s informaci&#243;n</a></h2>
    
        <p>El <a href="../expr.html">motor de expresiones</a> le da una gran
        capacidad de poder para hacer una gran variedad de cosas basadas en 
        las variables arbitrarias del servidor, y debe consultar este 
        documento para m&#225;s detalles.</p>
    
        <p>Tambi&#233;n, deber&#225; leer la documentaci&#243;n de <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>
        para ejemplos de combinaciones de m&#250;ltiples requisitos de acceso y especificar
        c&#243;mo interact&#250;an.
        </p>
    
        <p>Vea tambi&#233;n los howtos de <a href="auth.html">Authenticaci&#243;n y Autorizaci&#243;n</a>
        </p>
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/access.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/access.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/access.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/access.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/auth.html.ko.euc-kr��������������������������������������������������0000664�0001751�0001751�00000051073�14743132254�021626� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>(Authentication), Ѻο(Authorization),
    (Access Control) - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>(Authentication), Ѻο(Authorization),
    (Access Control)</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>(authentication) ڽ  ϴ 
        Ȯϴ ̴. Ѻο(authorization)   
         Ȥ ϴ  򵵷 ϴ ̴.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">  þ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#introduction">Ұ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#theprerequisites">⺻ </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#gettingitworking">⺻ ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#lettingmorethanonepersonin"> 鿩</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#possibleproblems">߻  ִ </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#whatotherneatstuffcanido">ٸ  Ѱ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">  </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">  þ</a></h2>
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code></li><li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li><li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li><li><code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_authz_host.html#allow">Allow</a></code></li><li><code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code></li><li><code class="directive"><a href="../mod/core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="../mod/core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_host.html#deny">Deny</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/core.html#require">Require</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Ұ</a></h2>
        <p> Ʈ ִ  Ҽ 鸸 ̰ų
        ̵鸸  ,  ۿ ϴ  Ͽ
          ϴ      ִ.</p>
    
        <p>  Ʈ Ϻθ ȣϱ  
        ϴ "ǥ"  ٷ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="theprerequisites" id="theprerequisites">⺻ </a></h2>
        <p> ۿ ٷ þ  ּ(Ϲ
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
        )̳ 丮 (<code>.htaccess</code> )
        Ѵ.</p>
    
        <p><code>.htaccess</code>  Ϸ  Ͽ ִ
         þ ϵ  ؾ Ѵ. ̸ 
        丮 Ͽ  þ   ִ ϴ
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> þ
        Ѵ.</p>
    
        <p>⼭  ٷ ,  
        <code>AllowOverride</code> þ ʿϴ.</p>
    
        <div class="example"><p><code>
          AllowOverride AuthConfig
        </code></p></div>
    
        <p>Ȥ þ   ּϿ ´ٸ,  Ͽ
           ־ Ѵ.</p>
    
        <p>׸ ȣ  ִ ˱  丮
           ˾ƾѴ.   ʰ, 
         ڼ  ̴.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gettingitworking" id="gettingitworking">⺻ ϱ</a></h2>
        <p>  丮 ȣ ȣϴ ⺻ 
        Ѵ.</p>
    
        <p> ȣ  Ѵ.    
           ־ Ѵ. ٸ ȣ ٿε
        ϰϱ ؼ.  , 
        <code>/usr/local/apache/htdocs</code> ִٸ ȣ()
        <code>/usr/local/apache/passwd</code> д.</p>
    
        <p>ġ Ե <a href="../programs/htpasswd.html">htpasswd</a>  Ͽ
        ȣ .  α׷ ġ ġ 
        <code>bin</code> 丮 ִ.   
         ԷѴ.</p>
    
        <div class="example"><p><code>
          htpasswd -c /usr/local/apache/passwd/passwords rbowen
        </code></p></div>
    
        <p><code>htpasswd</code> ȣ , Ȯ 
        ȣ ٽ Է϶ ûѴ.</p>
    
        <div class="example"><p><code>
          # htpasswd -c /usr/local/apache/passwd/passwords rbowen<br />
          New password: mypassword<br />
          Re-type new password: mypassword<br />
          Adding password for user rbowen
        </code></p></div>
    
        <p> <code>htpasswd</code>  ο ٸ
         ü θ Էؾ Ѵ.  ϴ 
        <code>/usr/local/apache/bin/htpasswd</code> 
        ִ.</p>
    
        <p>  ȣ ûϵ ϰ, 
            ˷ Ѵ.
        <code>httpd.conf</code> ϰų <code>.htaccess</code>
         Ͽ Ѵ.  ,
        <code>/usr/local/apache/htdocs/secret</code> 丮
        ȣϷ, Ʒ þ
        <code>/usr/local/apache/htdocs/secret/.htaccess</code> ̳
        <code>httpd.conf</code> &lt;Directory
        /usr/local/apache/apache/htdocs/secret&gt; ǿ 
        Ѵ.</p>
    
        <div class="example"><p><code>
          AuthType Basic<br />
          AuthName "Restricted Files"<br />
          AuthUserFile /usr/local/apache/passwd/passwords<br />
          Require user rbowen
        </code></p></div>
    
        <p>þ ϳ 캸. <code class="directive"><a href="../mod/core.html#authtype">AuthType</a></code> þ ڸ 
         Ѵ.  Ϲ  <code>Basic</code>,
        <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> Ѵ. ׷ Basic
           ȣ ȣȭ ʰ .
        ׷Ƿ  ڷḦ ȣϱ   ϸ ȵȴ.
        ġ <code>AuthType Digest</code>   Ѵ.
          <code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code> ϸ, ſ
        ϴ.  ֱ Ŭ̾Ʈ鸸 Digest  Ѵٰ
        Ѵ.</p>
    
        <p><code class="directive"><a href="../mod/core.html#authname">AuthName</a></code> þ
          <dfn>(realm)</dfn> Ѵ. 
        ΰ  Ѵ. ù° Ŭ̾Ʈ   
        ȣ ȭâ ش. ι°   Ͽ
        Ŭ̾Ʈ Ư   ȣ  Ѵ.</p>
    
        <p> , ϴ Ŭ̾Ʈ <code>"Restricted Files"</code>
          Ͽٸ, Ŭ̾Ʈ ڵ  
        <code>"Restricted Files"</code>  ǥõ  
         ȣ õѴ. ׷     
        ϸ ڰ  ȣ Է ʾƵ ȴ. 
        Ȼ  Ŭ̾Ʈ  ȣƮ ٸ ׻
         ȣ .</p>
    
        <p><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code>
        þ 츮  <code>htpasswd</code>  ȣ
        θ Ѵ. ڰ ٸ û Ź ڸ
        ϱ Ϲ  ˻ϴµ ð  
        ɸ  ִ. ġ  Ÿ̽ Ͽ  
          ִ. <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code>  <code class="directive"><a href="../mod/mod_authn_dbm.html#authdbmuserfile">AuthDBMUserFile</a></code> þ
        Ѵ. <a href="../programs/dbmmanage.html">dbmmanage</a>
        α׷ Ͽ ȣ  ٷ. <a href="http://modules.apache.org/">ġ 
        Ÿ̽</a>  ٸ   ϴ ڰ
          ִ.</p>
    
        <p> <code class="directive"><a href="../mod/core.html#require">Require</a></code>
        þ  Ư    ִ ڸ Ͽ
        Ѻο Ѵ.   <code>require</code> þ
        ϴ پ  Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="lettingmorethanonepersonin" id="lettingmorethanonepersonin"> 鿩</a></h2>
        <p> þ 丮 (ڸ <code>rbowen</code>)
          鿩. κ    鿩
         ̴.  <code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code>
         .</p>
    
        <p>  鿩 ʹٸ ׷  ׷쿡 
        ڵ ִ ˷ִ ׷ ʿϴ.  
         ſ Ͽ, ƹ γ   ִ. ϳ
         .</p>
    
       <div class="example"><p><code>
         GroupName: rbowen dpitts sungo rshersey
       </code></p></div>
    
        <p>׳    ׷   ̴.</p>
    
        <p> ȣϿ ڸ ߰Ϸ   ԷѴ</p>
    
        <div class="example"><p><code>
          htpasswd /usr/local/apache/passwd/passwords dpitts
        </code></p></div>
    
        <p> ,    ʰ  Ͽ ڸ
        ߰Ѵ. (<code>-c</code> ɼ  ȣ ).</p>
    
        <p> <code>.htaccess</code>    Ѵ.</p>
    
        <div class="example"><p><code>
          AuthType Basic<br />
          AuthName "By Invitation Only"<br />
          AuthUserFile /usr/local/apache/passwd/passwords<br />
          AuthGroupFile /usr/local/apache/passwd/groups<br />
          Require group GroupName
        </code></p></div>
    
        <p>׷ <code>GroupName</code> ׷쿡 ϸ
        <code>password</code> Ͽ ׸ ִ ڰ ùٸ
        ȣ Էϸ  Ѵ.</p>
    
        <p> Ϲ ڸ 鿩 ٸ  ִ. ׷
         ʿ  þ ϱ⸸ ϸ ȴ.</p>
    
        <div class="example"><p><code>
          Require valid-user
        </code></p></div>
    
        <p><code>Require user rbowen</code>   þ ϸ
        ȣϿ ִ  ùٸ ȣ Էϱ⸸ ϸ 
        Ѵ. ׷캰 ٸ ȣ Ͽ ׷ 
        ȿ   ִ.   ġ  ΰ(ȣϰ
        ׷) ƴ  Ѱ(ȣ) ˻ϸ ȴٴ 
        ̴. ׷  ȣ ؾ ϰ, <code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code> þ
        Ȯ ȣ ؾ ϴ  ̴.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="possibleproblems" id="possibleproblems">߻  ִ </a></h2>
        <p>Basic     û  ڸ
        ȣ ȮѴ.     ħ  
        (׸ ȣ ȣϴ 丮 ִ )  ִ
         ׸  ٽ ȮѴ. ϵ ӵ  .
        ȣ  ڸ ã    
        ϱ⶧ ȣ ũⰡ Ŀ   . ׸
         ۾  û  Ѵ.</p>
    
        <p>׷   ȣϿ   ִ ڼ
        Ѱ谡 ִ.  Ѱ ϴ  ɿ  ٸ,
        ׸ 鰳 Ѵ´ٸ ٰ ϰ ٸ  
        ؾ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="whatotherneatstuffcanido" id="whatotherneatstuffcanido">ٸ  Ѱ?</a></h2>
        <p>ڸ ȣ   ٰ ƴϴ.  
        ҿ  ٸ   ڸ 鿩 
         ִ.</p>
    
        <p><code class="directive"><a href="../mod/mod_authz_host.html#allow">Allow</a></code>
        <code class="directive"><a href="../mod/mod_authz_host.html#deny">Deny</a></code> þ
         û ǻ ȣƮ Ȥ ȣƮ ּҸ 
         ϰų źѴ. <code class="directive"><a href="../mod/mod_authz_host.html#order">Order</a></code> þ  
        þ  Ͽ, ġ   Ģ 
        ˸.</p>
    
        <p>̵ þ   .</p>
    
        <div class="example"><p><code>
          Allow from <var>address</var>
        </code></p></div>
    
        <p>⼭ <var>address</var> IP ּ(Ȥ IP ּ Ϻ)
         θ(Ȥ θ Ϻ)̴. Ѵٸ  ּҳ
        θ   ִ.</p>
    
        <p> ,  Խǿ  ø ִٸ 
            ִ.</p>
    
        <div class="example"><p><code>
          Deny from 205.252.46.165
        </code></p></div>
    
        <p> ּҿ  湮ڴ  þ ȣϴ 
          . IP ּ    ǻ͸  
        ִ.</p>
    
        <div class="example"><p><code>
          Deny from <var>host.example.com</var>
        </code></p></div>
    
        <p>, ü    ּҳ θ Ϻθ
        Ѵ.</p>
    
        <div class="example"><p><code>
          Deny from <var>192.101.205</var><br />
          Deny from <var>cyberthugs.com</var> <var>moreidiots.com</var><br />
          Deny from ke
        </code></p></div>
    
        <p><code class="directive"><a href="../mod/mod_authz_host.html#order">Order</a></code>
        <code class="directive"><a href="../mod/mod_authz_host.html#deny">Deny</a></code> <code class="directive"><a href="../mod/mod_authz_host.html#allow">Allow</a></code> þ 
        Ͽ  ϴ    ִ.</p>
    
        <div class="example"><p><code>
          Order deny,allow<br />
          Deny from all<br />
          Allow from <var>dev.example.com</var>
        </code></p></div>
    
        <p><code class="directive"><a href="../mod/mod_authz_host.html#allow">Allow</a></code>
        þ ϸ, ش ȣƮ ڸ ϰ ű⿡
        ߰   ϹǷ ϴ   Ѵ.
         Ư <em></em> ϱ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">  </a></h2>
        <p><code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code>
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>   ϴ
             ִ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/auth.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/cgi.html.ko.euc-kr���������������������������������������������������0000664�0001751�0001751�00000063473�14743132254�021436� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ 丮: CGI     - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>ġ 丮: CGI    </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#intro">Ұ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">CGI ϵ ġ ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#writing">CGI α׷ ۼϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">׷   ʾƿ!</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#behindscenes">ڿ   °?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#libraries">CGI /̺귯</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinfo">  ...</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">Ұ</a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li></ul></td></tr></table>
    
        <p>CGI (Common Gateway Interface)   CGI α׷
        Ȥ CGI ũƮ θ, (  ) ܺ
        α׷ ϴ  Ѵ. Ʈ 
           ϰ  ̴.   ġ
         CGI ϴ  Ұϰ, CGI α׷
        ۼغ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">CGI ϵ ġ ϱ</a></h2>
        
    
        <p>CGI α׷ ùٷ Ϸ CGI  ϵ
        ġ ؾ Ѵ. ϴ  .</p>
    
        <h3><a name="scriptalias" id="scriptalias">ScriptAlias</a></h3>
          
    
          <p><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          þ ϸ ġ Ư 丮 CGI α׷
          д. ġ  丮 ִ   CGI
          α׷̶ Ͽ Ŭ̾Ʈ ڿ ûϸ ڿ
          Ϸ õѴ.</p>
    
          <p><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          þ   Ѵ.</p>
    
          <div class="example"><p><code>
            ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/
          </code></p></div>
    
          <p>  ġ ⺻ ҿ ġ 
          <code>httpd.conf</code> Ͽ ִ ̴. <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> þ <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> þ  URL
          պκ Ư 丮 Ѵ.
          <code class="directive">Alias</code>
          <code class="directive">ScriptAlias</code>  <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> 丮 ۿ ִ
          丮 Ѵ. <code class="directive">Alias</code>
          <code class="directive">ScriptAlias</code> 
          <code class="directive">ScriptAlias</code> ߰ URL պκ
          ϴ   CGI α׷ ϴ ̴.
          ׷   ġ <code>/cgi-bin/</code>
          ϴ ڿ ûϸ
          <code>/usr/local/apache2/cgi-bin/</code> 丮
          ãƼ CGI α׷ ó϶ ˸.</p>
    
          <p> , URL
          <code>http://www.example.com/cgi-bin/test.pl</code>
          ûϸ ġ
          <code>/usr/local/apache2/cgi-bin/test.pl</code> 
          Ͽ  ȯѴ.   ϰ డϸ
           ε  ؾ Ѵ. ׷  ġ
           .</p>
        
    
        <h3><a name="nonscriptalias" id="nonscriptalias">ScriptAlias 丮 ۿ ִ CGI</a></h3>
          
    
          <p> Ȼ  CGI α׷ <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> 丮
          Ѵ. ׷ ڴ  CGI α׷  
          ִ    ִ. ׷  ġ
          ߴٸ ƹ 丮 CGI α׷  
           .  , <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> þ Ͽ
          ڰ ڽ Ȩ丮   츦
          . ڰ ڽ CGI α׷ ϰ 
          <code>cgi-bin</code> 丮 ٱ ٸ, ٸ
           CGI α׷ ϰ  ̴.</p>
    
          <p>ƹ 丮 CGI  Ϸ  
          ʿϴ. , <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> <code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code> þ Ͽ
          <code>cgi-script</code> ڵ鷯 ۵ؾ Ѵ. ι°,
          <code class="directive"><a href="../mod/core.html#options">Options</a></code> þ
          <code>ExecCGI</code> ؾ Ѵ.</p>
        
    
        <h3><a name="options" id="options">Options Ͽ  CGI  ϱ</a></h3>
          
    
          <p> ּϿ  <code class="directive"><a href="../mod/core.html#options">Options</a></code> þ Ͽ Ư
          丮 CGI    ִ.</p>
    
          <div class="example"><p><code>
            &lt;Directory /usr/local/apache2/htdocs/somedir&gt;<br />
            <span class="indent">
              Options +ExecCGI<br />
            </span>
            &lt;/Directory&gt;
          </code></p></div>
    
          <p> þ ġ CGI   Ѵ. 
           CGI   ˷ Ѵ.  <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> þ 
          Ȯڰ <code>cgi</code> <code>pl</code>  
          CGI α׷̶ ˸.</p>
    
          <div class="example"><p><code>
            AddHandler cgi-script .cgi .pl
          </code></p></div>
        
    
        <h3><a name="htaccess" id="htaccess">.htaccess </a></h3>
          
    
          <p><a href="htaccess.html"><code>.htaccess</code> 丮</a>
          <code>httpd.conf</code> ٱ  쿡 CGI α׷
            ִ  ˷ش.</p>
        
    
        <h3><a name="userdir" id="userdir"> 丮</a></h3>
          
    
          <p>Ʒ  ϸ  丮 <code>.cgi</code>
            CGI α׷ Ѵ.</p>
    
          <div class="example"><p><code>
          &lt;Directory /home/*/public_html&gt;<br />
          <span class="indent">
            Options +ExecCGI<br />
            AddHandler cgi-script .cgi<br />
          </span>
          &lt;/Directory&gt;
          </code></p></div>
    
          <p> ϸ  丮 <code>cgi-bin</code>
          丮 ִ   CGI α׷ νѴ.</p>
    
          <div class="example"><p><code>
          &lt;Directory /home/*/public_html/cgi-bin&gt;<br />
          <span class="indent">
            Options ExecCGI<br />
            SetHandler cgi-script<br />
          </span>
          &lt;/Directory&gt;
          </code></p></div>
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="writing" id="writing">CGI α׷ ۼϱ</a></h2>
        
    
        <p>``Ϲ'' α׷ְ CGI α׷ ̿ ΰ
        ֵ  ִ.</p>
    
        <p>ù° ̴ CGI α׷ ٸ  ϱ 
        MIME-type  ؾ Ѵٴ ̴. HTTP 
        Ŭ̾Ʈ Ŭ̾Ʈ   ްԵ ̸ ˸.
          .</p>
    
        <div class="example"><p><code>
          Content-type: text/html
        </code></p></div>
    
        <p>ι° ̴ HTML Ȥ    ִ 
        ؾ Ѵٴ ̴. κ  HTML ,
         gif ׸  HTML ƴ  ϴ CGI
        α׷ ۼϴ 쵵 ִ.</p>
    
        <p>ΰ ϰ CGI α׷ ۼ ̹  
        ٸ α׷ ſ ϴ.</p>
    
        <h3><a name="firstcgi" id="firstcgi">ó  CGI α׷</a></h3>
          
    
          <p>     CGI α׷ .
          ״ <code>first.pl</code>̶ Ͽ ϰ,
          <code>cgi-bin</code> 丮 Ѵ.</p>
    
          <div class="example"><p><code>
            #!/usr/bin/perl<br />
            print "Content-type: text/html\n\n";<br />
            print "Hello, World.";
          </code></p></div>
    
          <p>Perl ͼ ʴ   Ͼ  
          ִ. ù°  ġ(Ȥ ϴ )
          <code>/usr/bin/perl</code> ġ ִ  Ͽ
           α׷  ϶ ˸. ι°  
           content-type  ϰ carriage-return ٹٲ
          ι Ѵ. ׷  ڿ HTTP   ϴ
           ,  Ѵ. °  "Hello, World."
          ڿ Ѵ. ̰ ̴.</p>
    
          <p> ϰ ּҸ ԷѴ</p>
    
          <div class="example"><p><code>
            http://www.example.com/cgi-bin/first.pl
          </code></p></div>
    
          <p> Ҹ Էϸ, â <code>Hello, World.</code>
            δ. е , ѹ ϴ 
            ٸ  õ   ִ.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">׷   ʾƿ!</a></h2>
        
    
        <p> CGI α׷ Ҷ    ִ
         ⺻ װ.</p>
    
        <dl>
          <dt>CGI α׷ </dt>
          <dd>!    Ѵٴ ̴.  Ȯ
           ùٷ ó Ѵٸ, CGI α׷
          ùٸ <code>Content-Type</code> Ͽ ȮѴ.</dd>
    
          <dt>CGI α׷ ҽڵ Ȥ "POST Method Not Allowed"
          </dt>
          <dd>CGI α׷ ϵ ġ  
          ʾҴٴ ̴. <a href="#configuring">ġ ϱ</a>
           ٽ а  κ ִ ãƺ.</dd>
    
          <dt>"Forbidden" ϴ </dt>
          <dd>  ִٴ ̴. <a href="#errorlogs">ġ
           α</a> Ʒ <a href="#permissions">ϱ</a>
           Ȯ϶.</dd>
    
          <dt>"Internal Server Error" </dt>
          <dd><a href="#errorlogs">ġ  α</a>  Ƹ
          CGI α׷   Բ "Premature end of
          script headers"  ̴.   Ʒ  ϳ
          ȮϿ   CGI α׷  HTTP 
           ߴ ˾ƺ.</dd>
        </dl>
    
        <h3><a name="permissions" id="permissions">ϱ</a></h3>
          
    
          <p> Ű     ϶.
          ,  ϸ  Ư  (
          <code>nobody</code> <code>www</code>) Ѵ.
          ׷    Ϸ  ʿϴ.
          Ͽ <code>nobody</code> ϱ⿡  
          ֱ  ο    ش.</p>
    
          <div class="example"><p><code>
            chmod a+x first.pl
          </code></p></div>
    
          <p>, α׷ ٸ  аų ٸ  Ͽ
            ʿϴ.</p>
    
        
    
        <h3><a name="pathinformation" id="pathinformation">  ȯ</a></h3>
          
    
          <p>࿡ α׷ ϸ ڵ  
           ޵ȴ.  , <code>PATH</code>  
            ã Ҹ ˷ش.</p>
    
          <p> α׷ CGI α׷ Ҷ
          <code>PATH</code> ٸ  ִ. ( ,
          <code>sendmail</code> ) CGI α׷ ȿ ϴ
          ɾ  η ؾ  ɾ ã 
          ִ.</p>
    
          <p>    CGI α׷ ù° ٿ 
          ũƮ  ( <code>perl</code>) ο
           ߻Ѵ.</p>
    
          <div class="example"><p><code>
            #!/usr/bin/perl
          </code></p></div>
    
          <p>   ȮѴ.</p>
    
          <p>, CGI α׷ ٸ <a href="#env">ȯ溯</a>
          Ѵٸ ġ   α׷ ؾ
          Ѵ.</p>
    
        
    
        <h3><a name="syntaxerrors" id="syntaxerrors">α׷ </a></h3>
          
    
          <p>CGI α׷ ϴ  κ α׷ ü
          ̴. Ư  ΰ Ǽ  ʾҰ  
            ִٸ  ׷.   ϱ
           ࿡ α׷ غ.  , 
           Ѵ.</p>
    
          <div class="example"><p><code>
          cd /usr/local/apache2/cgi-bin<br />
          ./first.pl
          </code></p></div>
    
          <p>(<code>perl</code> ͸  . 
          ġ ũƮ ù° ٿ ִ <a href="#pathinformation"> </a> Ͽ ͸
          ãƾ Ѵ.)</p>
    
          <p>α׷   <code>Content-Type</code> 
          HTTP  ϰ   ؾ Ѵ. ٸ 
          Ѵٸ    ġ <code>Premature
          end of script headers</code> ȯѴ. ڼ 
           <a href="#writing">CGI α׷ ۼϱ</a> ϶.</p>
        
    
        <h3><a name="errorlogs" id="errorlogs"> α</a></h3>
          
    
          <p> α״  ̴.  ߸Ǹ  α׿
           .  α׸    Ѵ. Ʈ
          ȣϴ   α׸  ϰ Ѵٸ, Ƹ
          ٸ ü ˾ƺ Ѵ.  α׸   ,
          κ   ľϿ ذ  ִ.</p>
        
    
        <h3><a name="suexec" id="suexec">Suexec</a></h3>
          
    
          <p><a href="../suexec.html">suexec</a>  α׷
          ϸ  ȣƮ Ȥ   丮 ִ
           CGI α׷ ٸ     ִ.
          Suexec ſ ϰ  ˻ϸ, ˻縦 ϳ
           ϸ CGI α׷  ʰ <code>Premature
          end of script headers</code> ȯѴ.</p>
    
          <p>suexec ϰ ִ ˷ <code>apachectl -V</code>
          Ͽ <code>SUEXEC_BIN</code> ġ ȮѴ. ġ
          Ҷ  ҿ suexec  ߰ϸ, suexec
            ִ.</p>
    
          <p>suexec   ߴٸ ؼ ȵȴ.
          suexec   <code>SUEXEC_BIN</code> ġ
          ִ <code>suexec</code>   (Ȥ ϸ
          ٲٰ)  ϸ ȴ. <a href="../suexec.html">suexec</a>    ׷
          ϰ ʹٸ, <code>suexec -V</code> Ͽ suexec
          α ġ ˾Ƴ αϿ   Ģ
           ִ ã´.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behindscenes" id="behindscenes">ڿ   °?</a></h2>
        
    
        <p>CGI α׷ֿ ͼ ڿ   ϸ
         ȴ. ü    ϴ
         ϴ ̴.  "Hello, World." ϴ
        α׷ ۼ   ̷ α׷  
        ⶧̴.</p>
    
        <h3><a name="env" id="env">ȯ溯</a></h3>
          
    
          <p>ȯ溯  ǻ͸ ϴ   
          ٴϴ ̴. ȯ溯 path (ǻͰ  Է
          ɾ شϴ   ã ), ڸ, ͹̳
             . Ϲ ȯ溯  
           Ʈ <code>env</code> ԷѴ.</p>
    
          <p>CGI Ҷ    ȯ溯
           ȯѴ.     (Netscape, IE,
          Lynx),   (ġ, IIS, WebSite), ϴ CGI
          α׷  ִ.</p>
    
          <p>CGI α׷Ӵ ̷    ְ,
          ȯ溯 Ŭ̾Ʈ- ſ Ϻκ Ѵ.
          ü ʼ   <a href="http://hoohoo.ncsa.uiuc.edu/cgi/env.html">http://hoohoo.ncsa.uiuc.edu/cgi/env.html</a> ִ.</p>
    
          <p>Ʒ  Perl CGI α׷ ڽſ ޵ 
          ȯ溯 ش. ġ  <code>cgi-bin</code>
          丮 ̿  α׷ ΰ ִ.  
          ʼ̰  ̴. ׷  Ͽ 
           δ. , ġ ⺻ ϴ ȯ溯
          ܿ   <a href="../env.html"> ȯ溯
          ߰  ִ</a>.</p>
    
          <div class="example"><p><code>
            #!/usr/bin/perl<br />
            print "Content-type: text/html\n\n";<br />
            foreach $key (keys %ENV) {<br />
            <span class="indent">
              print "$key --&gt; $ENV{$key}&lt;br&gt;";<br />
            </span>
            }
          </code></p></div>
        
    
        <h3><a name="stdin" id="stdin">STDIN STDOUT</a></h3>
          
    
          <p>,  Ŭ̾Ʈ ǥԷ(<code>STDIN</code>)
          ǥ(<code>STDOUT</code>) Ѵ. ϻ 
          <code>STDIN</code> Ű峪 α׷ óϴ 
          Ÿ, <code>STDOUT</code>  ܼ̳ ȭ Ѵ.</p>
    
          <p>CGI α׷  (form) <code>POST</code>ϸ
          Ŀ Է ڷḦ Ư   CGI α׷
          <code>STDIN</code> Ѵ. ׷ α׷ Ű峪
          Ͽ  ڷḦ óϵ ڷḦ ó  ִ.</p>
    
          <p>"Ư " ſ ϴ. ׸ ̸  ȣ(=)
          ϰ, ׸ ̸  ֵ  ۻ(&amp;)
          Ѵ. , ۻ, ȣ  ڿ ڴ
          ȥ ʵ 16 ȯѴ.  ڷ ڿ
            .</p>
    
          <div class="example"><p><code>
            name=Rich%20Bowen&amp;city=Lexington&amp;state=KY&amp;sidekick=Squirrel%20Monkey
          </code></p></div>
    
          <p> URL ڿ ̷ ڿ  ȴ.   
          ڿ <code>QUERY_STRING</code>̶ ȯ溯 Ѵ.
          ̸ <code>GET</code> û̶ Ѵ. <code>FORM</code>
          ± <code>METHOD</code> Ӽ Ͽ HTML (form)
          ڷḦ <code>GET</code> <code>POST</code> Ѵ.</p>
    
          <p> α׷ ̷ ڿ   ɰ
          Ѵ.   ̷ ڷ ó  CGI α׷ ٸ
            Ǵ ̺귯  ִ.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="libraries" id="libraries">CGI /̺귯</a></h2>
        
    
        <p>CGI α׷ ۼҶ  ۾ ִ ڵ
        ̺귯 Ȥ   غ Ѵ. ̷ 
        ϸ װ ٰ   α׷   ִ.</p>
    
        <p>Perl CGI α׷ ۼѴٸ <a href="http://www.cpan.org/">CPAN</a>   ã
         ִ. CGI ߿  θ Ǵ 
        <code>CGI.pm</code>̴. κ α׷  ּ
          <code>CGI::Lite</code>    ִ.</p>
    
        <p>C CGI α׷ ۼѴٸ   . 
        ϳ <a href="http://www.boutell.com/cgic/">http://www.boutell.com/cgic/</a>
        ִ <code>CGIC</code> ̺귯.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinfo" id="moreinfo">  ...</a></h2>
        
    
        <p> ſ  CGI  ִ. ׷ <a href="news:comp.infosystems.www.authoring.cgi">comp.infosystems.www.authoring.cgi</a>  
        CGI    ִ. HTML Writers Guild -servers
        ϸƮ    ã⿡ Ǹ Ҵ. <a href="http://www.hwg.org/lists/hwg-servers/">http://www.hwg.org/lists/hwg-servers/</a>   
          ִ.</p>
    
        <p>׸  CGI α׷ ۿ    
        CGI Ծ о  𸥴. <a href="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html">NCSA</a>
          ְ,  ʾ <a href="http://web.golux.com/coar/cgi/">Common Gateway Interface
        RFC Ʈ</a> ִ.</p>
    
        <p>ϸƮ ׷쿡  ݰ ִ CGI  
        Ҷ ߻    ,  ߻
          ٸ, ϴ , CGI α׷ ۼ
        , ϸ ش ڵ带 ڼ . ׷ ذå
        ã .</p>
    
        <p>ġ ҽڵ尡 ߸Ǿٰ Ȯ ʴ  CGI 
        ġ  ͺ̽ ø <strong></strong>
        ȵȴ.</p>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/cgi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/auth.html.es���������������������������������������������������������0000664�0001751�0001751�00000126127�14743132254�020442� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Autenticaci&#243;n y Autorizaci&#243;n - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a> &gt; <a href="./">How-To / Tutoriales</a></div><div id="page-content"><div id="preamble"><h1>Autenticaci&#243;n y Autorizaci&#243;n</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta traducci&#243;n podr&#237;a estar
                obsoleta. Consulte la versi&#243;n en ingl&#233;s de la
                documentaci&#243;n para comprobar si se han producido cambios
                recientemente.</div>
    
        <p>Autenticaci&#243;n es cualquier proceso por el cu&#225;l se verifica que uno es 
        quien dice ser. Autorizaci&#243;n es cualquier proceso en el cu&#225;l cualquiera
        est&#225; permitido a estar donde se quiera, o tener informaci&#243;n la cu&#225;l se
        quiera tener.
        </p>
    
        <p>Para informaci&#243;n de control de acceso de forma gen&#233;rica visite<a href="access.html">How to de Control de Acceso</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">M&#243;dulos y Directivas Relacionados</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introducci&#243;n</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#theprerequisites">Los Prerequisitos</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#gettingitworking">Conseguir que funcione</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#lettingmorethanonepersonin">Dejar que m&#225;s de una persona 
    	entre</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#possibleproblems">Posibles Problemas</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbmdbd">M&#233;todo alternativo de almacenamiento de las 
    	contrase&#241;as</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multprovider">Uso de m&#250;ltiples proveedores</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#beyond">M&#225;s all&#225; de la Autorizaci&#243;n</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#socache">Cache de Autenticaci&#243;n</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">M&#225;s informaci&#243;n</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">M&#243;dulos y Directivas Relacionados</a></h2>
    
    <p>Hay tres tipos de m&#243;dulos involucrados en los procesos de la autenticaci&#243;n 
    	y autorizaci&#243;n. Normalmente deber&#225;s escoger al menos un m&#243;dulo de cada grupo.</p>
    
    <ul>
      <li>Modos de Autenticaci&#243;n (consulte la directiva
          <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code> )
        <ul>
          <li><code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code></li>
          <li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li>
        </ul>
      </li>
      <li>Proveedor de Autenticaci&#243;n (consulte la directiva
      <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> y
      <code class="directive"><a href="../mod/mod_auth_digest.html#authdigestprovider">AuthDigestProvider</a></code>)
    
        <ul>
          <li><code class="module"><a href="../mod/mod_authn_anon.html">mod_authn_anon</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code></li>
        </ul>
      </li>
      <li>Autorizaci&#243;n (consulte la directiva
          <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>)
        <ul>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbd.html">mod_authz_dbd</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_owner.html">mod_authz_owner</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_user.html">mod_authz_user</a></code></li>
        </ul>
      </li>
    </ul>
    
      <p>A parte de &#233;stos m&#243;dulos, tambi&#233;n est&#225;n
      <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> y
      <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>. &#201;stos m&#243;dulos implementan las directivas 
      esenciales que son el centro de todos los m&#243;dulos de autenticaci&#243;n.</p>
    
      <p>El m&#243;dulo <code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> es tanto un proveedor de 
      autenticaci&#243;n como de autorizaci&#243;n. El m&#243;dulo
      <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code> proporciona autorizaci&#243;n y control de acceso
      basado en el nombre del Host, la direcci&#243;n IP o caracter&#237;sticas de la propia
      petici&#243;n, pero no es parte del sistema proveedor de 
      autenticaci&#243;n. Para tener compatibilidad inversa con el mod_access, 
      hay un nuevo modulo llamado <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code>.</p>
    
      <p>Tambi&#233;n puedes mirar el how-to de <a href="access.html">Control de Acceso </a>, donde se plantean varias formas del control de acceso al servidor.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introducci&#243;n</a></h2>
        <p>Si se tiene informaci&#243;n en nuestra p&#225;gina web que sea informaci&#243;n 
        	sensible o pensada para un grupo reducido de usuarios/personas,
        	las t&#233;cnicas que se describen en este manual, le servir&#225;n  
        	de ayuda para asegurarse de que las personas que ven esas p&#225;ginas sean 
        	las personas que uno quiere.</p>
    
        <p>Este art&#237;culo cubre la parte "est&#225;ndar" de c&#243;mo proteger partes de un 
        	sitio web que muchos usar&#225;n.</p>
    
        <div class="note"><h3>Nota:</h3>
        <p>Si de verdad es necesario que tus datos est&#233;n en un sitio seguro, 
        	considera usar <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>  como m&#233;todo de autenticaci&#243;n adicional a cualquier forma de autenticaci&#243;n.</p>
        </div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="theprerequisites" id="theprerequisites">Los Prerequisitos</a></h2>
        <p>Las directivas que se usan en este art&#237;culo necesitaran ponerse ya sea 
        	en el fichero de configuraci&#243;n principal del servidor ( t&#237;picamente en 
        	la secci&#243;n 
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> de httpd.conf ), o
        en cada uno de los ficheros de configuraciones del propio directorio
        (los archivos <code>.htaccess</code>).</p>
    
        <p>Si planea usar los ficheros <code>.htaccess</code> , necesitar&#225;s
        tener en la configuraci&#243;n global del servidor, una configuraci&#243;n que permita
        poner directivas de autenticaci&#243;n en estos ficheros. Esto se hace con la
        directiva <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>, la cual especifica
        que directivas, en su caso, pueden ser puestas en cada fichero de configuraci&#243;n
        por directorio.</p>
    
        <p>Ya que estamos hablando aqu&#237; de autenticaci&#243;n, necesitar&#225;s una directiva 
        	<code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> como la siguiente:
        	</p>
    
        <pre class="prettyprint lang-config">AllowOverride AuthConfig</pre>
    
    
        <p>O, si solo se van a poner las directivas directamente en la configuraci&#243;n
        	principal del servidor, deber&#225;s tener, claro est&#225;, permisos de escritura
        	en el archivo. </p>
    
        <p>Y necesitar&#225;s saber un poco de como est&#225; estructurado el &#225;rbol de 
        	directorios de tu servidor, para poder saber donde se encuentran algunos 
        	archivos. Esto no deber&#237;a ser una tarea dif&#237;cil, a&#250;n as&#237; intentaremos 
        	dejarlo claro llegado el momento de comentar dicho aspecto.</p>
    
        <p>Tambi&#233;n deber&#225;s de asegurarte de que los m&#243;dulos 
        <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> y <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>
        han sido incorporados, o a&#241;adidos a la hora de compilar en tu binario httpd o
        cargados mediante el archivo de configuraci&#243;n <code>httpd.conf</code>. Estos 
        dos m&#243;dulos proporcionan directivas b&#225;sicas y funcionalidades que son cr&#237;ticas
        para la configuraci&#243;n y uso de autenticaci&#243;n y autorizaci&#243;n en el servidor web.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gettingitworking" id="gettingitworking">Conseguir que funcione</a></h2>
        <p>Aqu&#237; est&#225; lo b&#225;sico de c&#243;mo proteger con contrase&#241;a un directorio en tu
         servidor.</p>
    
        <p>Primero, necesitar&#225;s crear un fichero de contrase&#241;a. Dependiendo de que 
        	proveedor de autenticaci&#243;n se haya elegido, se har&#225; de una forma u otra. Para empezar, 
        	usaremos un fichero de contrase&#241;a de tipo texto.</p>
    
        <p>Este fichero deber&#225; estar en un sitio que no se pueda tener acceso desde
         la web. Esto tambi&#233;n implica que nadie pueda descargarse el fichero de 
         contrase&#241;as. Por ejemplo, si tus documentos est&#225;n guardados fuera de
         <code>/usr/local/apache/htdocs</code>, querr&#225;s poner tu archivo de contrase&#241;as en 
         <code>/usr/local/apache/passwd</code>.</p>
    
        <p>Para crear el fichero de contrase&#241;as, usa la utilidad 
        	<code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> que viene con Apache. Esta herramienta se 
        	encuentra en el directorio <code>/bin</code> en donde sea que se ha 
        	instalado el Apache. Si ha instalado Apache desde un paquete de terceros, 
        	puede ser que se encuentre en su ruta de ejecuci&#243;n.</p>
    
        <p>Para crear el fichero, escribiremos:</p>
    
        <div class="example"><p><code>
          htpasswd -c /usr/local/apache/passwd/passwords rbowen
        </code></p></div>
    
        <p><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> te preguntar&#225; por una contrase&#241;a, y despu&#233;s 
        te pedir&#225; que la vuelvas a escribir para confirmarla:</p>
    
        <div class="example"><p><code>
          $ htpasswd -c /usr/local/apache/passwd/passwords rbowen<br />
          New password: mypassword<br />
          Re-type new password: mypassword<br />
          Adding password for user rbowen
        </code></p></div>
    
        <p>Si <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> no est&#225; en tu variable de entorno "path" del 
        sistema, por supuesto deber&#225;s escribir la ruta absoluta del ejecutable para 
        poder hacer que se ejecute. En una instalaci&#243;n por defecto, est&#225; en:
        <code>/usr/local/apache2/bin/htpasswd</code></p>
    
        <p>Lo pr&#243;ximo que necesitas, ser&#225; configurar el servidor para que pida una 
        	contrase&#241;a y as&#237; decirle al servidor que usuarios est&#225;n autorizados a acceder.
        	Puedes hacer esto ya sea editando el fichero <code>httpd.conf</code>
        de configuraci&#243;n  o usando in fichero <code>.htaccess</code>. Por ejemplo, 
        si quieres proteger el directorio
        <code>/usr/local/apache/htdocs/secret</code>, puedes usar las siguientes 
        directivas, ya sea en el fichero <code>.htaccess</code> localizado en
        following directives, either placed in the file
        <code>/usr/local/apache/htdocs/secret/.htaccess</code>, o
        en la configuraci&#243;n global del servidor <code>httpd.conf</code> dentro de la
        secci&#243;n &lt;Directory  
        "/usr/local/apache/htdocs/secret"&gt; , como se muestra a continuaci&#243;n:</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/usr/local/apache/htdocs/secret"&gt;
    AuthType Basic
    AuthName "Restricted Files"
    # (Following line optional)
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require user rbowen
    &lt;/Directory&gt;</pre>
    
    
        <p>Vamos a explicar cada una de las directivas individualmente.
        	La directiva <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code> selecciona el m&#233;todo
        que se usa para autenticar al usuario. El m&#233;todo m&#225;s com&#250;n es 
        <code>Basic</code>, y &#233;ste es el m&#233;todo que implementa 
        <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code>. Es muy importante ser consciente,
        de que la autenticaci&#243;n b&#225;sica, env&#237;a las contrase&#241;as desde el cliente 
        al servidor sin cifrar.
        Este m&#233;todo por tanto, no debe ser utilizado para proteger datos muy sensibles,
        a no ser que, este m&#233;todo de autenticaci&#243;n b&#225;sica, sea acompa&#241;ado del m&#243;dulo
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.
        Apache soporta otro m&#233;todo m&#225;s de autenticaci&#243;n  que es del tipo 
        <code>AuthType Digest</code>. Este m&#233;todo, es implementado por el m&#243;dulo <code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code> y con el se pretend&#237;a crear una autenticaci&#243;n m&#225;s
        segura. Este ya no es el caso, ya que la conexi&#243;n deber&#225; realizarse con  <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> en su lugar.
        </p>
    
        <p>La directiva <code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code> 
        establece el <dfn>Realm</dfn> para ser usado en la autenticaci&#243;n. El 
        <dfn>Realm</dfn> tiene dos funciones principales.
        La primera, el cliente presenta a menudo esta informaci&#243;n al usuario como 
        parte del cuadro de di&#225;logo de contrase&#241;a. La segunda, que es utilizado por 
        el cliente para determinar qu&#233; contrase&#241;a enviar a para una determinada zona 
        de autenticaci&#243;n.</p>
    
        <p>As&#237; que, por ejemple, una vez que el cliente se ha autenticado en el &#225;rea de
        los <code>"Ficheros Restringidos"</code>, entonces re-intentar&#225; autom&#225;ticamente
        la misma contrase&#241;a para cualquier &#225;rea en el mismo servidor que es marcado 
        con el Realm de <code>"Ficheros Restringidos"</code>
        Por lo tanto, puedes prevenir que a un usuario se le pida mas de una vez por su
        contrase&#241;a, compartiendo as&#237; varias &#225;reas restringidas el mismo Realm
        Por supuesto, por razones de seguridad, el cliente pedir&#225; siempre por una contrase&#241;a, 
        siempre y cuando el nombre del servidor cambie.
        </p>
    
        <p>La directiva <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> es,
        en este caso, opcional, ya que <code>file</code> es el valor por defecto
        para esta directiva. Deber&#225;s usar esta directiva si estas usando otro medio
        diferente para la autenticaci&#243;n, como por ejemplo
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> o <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>.</p>
    
        <p>La directiva <code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code>
        establece el path al fichero de contrase&#241;as que acabamos de crear con el 
        comando <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>. Si tiene un n&#250;mero muy grande de usuarios, 
        puede ser realmente lento el buscar el usuario en ese fichero de texto plano 
        para autenticar a los usuarios en cada petici&#243;n.
        Apache tambi&#233;n tiene la habilidad de almacenar informaci&#243;n de usuarios en 
        unos ficheros de r&#225;pido acceso a modo de base de datos.
        El m&#243;dulo <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> proporciona la directiva <code class="directive"><a href="../mod/mod_authn_dbm.html#authdbmuserfile">AuthDBMUserFile</a></code>. Estos ficheros pueden ser creados y
        manipulados con el programa <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> y <code class="program"><a href="../programs/htdbm.html">htdbm</a></code>. 
        Muchos otros m&#233;todos de autenticaci&#243;n as&#237; como otras opciones, est&#225;n disponibles en 
        m&#243;dulos de terceros 
        <a href="http://modules.apache.org/">Base de datos de M&#243;dulos disponibles</a>.</p>
    
        <p>Finalmente, la directiva <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
        proporciona la parte del proceso de autorizaci&#243;n estableciendo el o los
        usuarios que se les est&#225; permitido acceder a una regi&#243;n del servidor.
        En la pr&#243;xima secci&#243;n, discutiremos las diferentes v&#237;as de utilizar la 
        directiva <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="lettingmorethanonepersonin" id="lettingmorethanonepersonin">Dejar que m&#225;s de una persona 
    	entre</a></h2>
        <p>Las directivas mencionadas arriba s&#243;lo permiten a una persona 
        (especialmente con un usuario que en ej ejemplo es <code>rbowen</code>) 
        en el directorio. En la mayor&#237;a de los casos, se querr&#225; permitir el acceso
        a m&#225;s de una persona. Aqu&#237; es donde la directiva 
        <code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code> entra en juego.</p>
    
        <p>Si lo que se desea es permitir a m&#225;s de una persona el acceso, necesitar&#225;s
         crear un archivo de grupo que asocie los nombres de grupos con el de personas
         para permitirles el acceso. El formato de este fichero es bastante sencillo, 
         y puedes crearlo con tu editor de texto favorito. El contenido del fichero 
         se parecer&#225; a:</p>
    
       <div class="example"><p><code>
         GroupName: rbowen dpitts sungo rshersey
       </code></p></div>
    
        <p>B&#225;sicamente eso es la lista de miembros los cuales est&#225;n en un mismo fichero
         de grupo en una sola linea separados por espacios.</p>
    
        <p>Para a&#241;adir un usuario a tu fichero de contrase&#241;as existente teclee:</p>
    
        <div class="example"><p><code>
          htpasswd /usr/local/apache/passwd/passwords dpitts
        </code></p></div>
    
        <p>Te responder&#225; lo mismo que anteriormente, pero se a&#241;adir&#225; al fichero 
        	existente en vez de crear uno nuevo. (Es decir el flag <code>-c</code> ser&#225; 
        	el que haga que se genere un nuevo 
        fichero de contrase&#241;as).</p>
    
        <p>Ahora, tendr&#225; que modificar su fichero <code>.htaccess</code> para que sea 
        parecido a lo siguiente:</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "By Invitation Only"
    # Optional line:
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    AuthGroupFile "/usr/local/apache/passwd/groups"
    Require group GroupName</pre>
    
    
        <p>Ahora, cualquiera que est&#233; listado en el grupo <code>GroupName</code>,
        y tiene una entrada en el fichero de <code>contrase&#241;as</code>, se les 
        permitir&#225; el acceso, si introducen su contrase&#241;a correctamente.</p>
    
        <p>Hay otra manera de dejar entrar a varios usuarios, que es menos espec&#237;fica.
        En lugar de crear un archivo de grupo, s&#243;lo puede utilizar la siguiente 
        directiva:</p>
    
        <pre class="prettyprint lang-config">Require valid-user</pre>
    
    
        <p>Usando &#233;sto en vez de la l&#237;nea <code>Require user rbowen</code>
         permitir&#225; a cualquier persona acceder, la cu&#225;l aparece en el archivo de 
         contrase&#241;as, y que introduzca correctamente su contrase&#241;a. Incluso puede 
         emular el comportamiento del grupo aqu&#237;, s&#243;lo manteniendo un fichero de 
         contrase&#241;as independiente para cada grupo. La ventaja de este enfoque es 
         que Apache s&#243;lo tiene que comprobar un archivo, en lugar de dos. La desventaja 
         es que se tiene que mantener un mont&#243;n de ficheros de contrase&#241;a de grupo, y 
         recuerde hacer referencia al fichero correcto en la directiva
        <code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="possibleproblems" id="possibleproblems">Posibles Problemas</a></h2>
        <p>Debido a la forma en que se especifica la autenticaci&#243;n b&#225;sica,
        su nombre de usuario y la contrase&#241;a deben ser verificados cada vez 
        que se solicita un documento desde el servidor. Esto es, incluso si&nbsp;
        se&nbsp; vuelve a cargar la misma p&#225;gina, y para cada imagen de la p&#225;gina (si
    &nbsp;&nbsp;&nbsp;&nbsp;provienen de un directorio protegido). Como se puede imaginar, esto
    &nbsp;&nbsp;&nbsp;&nbsp;ralentiza las cosas un poco. La cantidad que ralentiza las cosas es 
        proporcional al tama&#241;o del archivo de contrase&#241;as, porque tiene que 
        abrir ese archivo, recorrer&nbsp;lista de usuarios hasta que llega a su nombre.
        Y tiene que hacer esto cada vez que se carga una p&#225;gina.</p>
    
        <p>Una consecuencia de esto, es que hay un limite pr&#225;ctico de cuantos 
        usuarios puedes introducir en el fichero de contrase&#241;as. Este l&#237;mite
        variar&#225; dependiendo de la m&#225;quina en la que tengas el servidor,
        pero puedes notar ralentizaciones en cuanto se metan cientos de entradas,
        y por lo tanto consideraremos entonces otro m&#233;todo de autenticaci&#243;n
        en ese momento.
    	</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbmdbd" id="dbmdbd">M&#233;todo alternativo de almacenamiento de las 
    	contrase&#241;as</a></h2>
    
        <p>Debido a que el almacenamiento de las contrase&#241;as en texto plano tiene 
        	el problema mencionado anteriormente, puede que se prefiera guardar 
        	las contrase&#241;as en otro lugar como por ejemplo una base de datos.
        	</p>
    
        <p>Los m&#243;dulos <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> y <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code> son
        dos m&#243;dulos que hacen esto posible. En vez de seleccionar la directiva de fichero
        <code><code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> </code>, en su lugar
        se puede elegir <code>dbm</code> o <code>dbd</code> como formato de almacenamiento.</p>
    
        <p>Para seleccionar los ficheros de tipo dbm en vez de texto plano, podremos hacer algo parecido a lo siguiente:</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider dbm
        AuthDBMUserFile "/www/passwords/passwd.dbm"
        Require valid-user
    &lt;/Directory&gt;</pre>
    
    
        <p>Hay otras opciones disponibles. Consulta la documentaci&#243;n de
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> para m&#225;s detalles.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multprovider" id="multprovider">Uso de m&#250;ltiples proveedores</a></h2>
    
        <p>Con la introducci&#243;n de la nueva autenticaci&#243;n basada en un proveedor y
         una arquitectura de autorizaci&#243;n, ya no estaremos restringidos a un &#250;nico
         m&#233;todo de autenticaci&#243;n o autorizaci&#243;n. De hecho, cualquier n&#250;mero de 
         los proveedores pueden ser mezclados y emparejados para ofrecerle 
         exactamente el esquema que se adapte a sus necesidades. 
         En el siguiente ejemplo, veremos como ambos proveedores tanto el fichero 
         como el LDAP son usados en la autenticaci&#243;n:
         </p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file ldap
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        Require valid-user
    &lt;/Directory&gt;</pre>
    
    
        <p>En este ejemplo el fichero, que act&#250;a como proveedor, intentar&#225; autenticar 
        	primero al usuario. Si no puede autenticar al usuario, el proveedor del LDAP
        	ser&#225; llamado para que realice la autenticaci&#243;n.
        	Esto permite al &#225;mbito de autenticaci&#243;n ser amplio, si su organizaci&#243;n 
        	implementa m&#225;s de un tipo de almac&#233;n de autenticaci&#243;n. 
        	Otros escenarios de autenticaci&#243;n y autorizaci&#243;n pueden incluir la 
        	mezcla de un tipo de autenticaci&#243;n con un tipo diferente de autorizaci&#243;n.
        	Por ejemplo, autenticar contra un fichero de contrase&#241;as pero autorizando
        	dicho acceso mediante el directorio del LDAP.</p>
    
        <p>As&#237; como m&#250;ltiples m&#233;todos y proveedores de autenticaci&#243;n pueden 
        	ser implementados, tambi&#233;n pueden usarse m&#250;ltiples formas de 
        	autorizaci&#243;n.
        	En este ejemplo ambos ficheros de autorizaci&#243;n de grupo as&#237; como 
        	autorizaci&#243;n de grupo mediante LDAP va a ser usado:
        </p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        AuthGroupFile "/usr/local/apache/passwd/groups"
        Require group GroupName
        Require ldap-group cn=mygroup,o=yourorg
    &lt;/Directory&gt;</pre>
    
    
        <p>Para llevar la autorizaci&#243;n un poco m&#225;s lejos, las directivas 
        	de autorizaci&#243;n de contenedores tales como
        <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
        and
        <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>
        nos permiten aplicar una l&#243;gica de en qu&#233; orden se manejar&#225; la autorizaci&#243;n dependiendo
        de la configuraci&#243;n y controlada a trav&#233;s de ella.
        Mire tambi&#233;n <a href="../mod/mod_authz_core.html#logic">Contenedores de
        Autorizaci&#243;n</a> para ejemplos de c&#243;mo pueden ser aplicados.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="beyond" id="beyond">M&#225;s all&#225; de la Autorizaci&#243;n</a></h2>
    
        <p>El modo en que la autorizaci&#243;n puede ser aplicada es ahora mucho m&#225;s flexible
        	que us solo chequeo contra un almac&#233;n de datos (contrase&#241;as). Ordenando la 
        	l&#243;gica y escoger la forma en que la autorizaci&#243;n es realizada, ahora es posible 
        </p>
    
        <h3><a name="authandororder" id="authandororder">Aplicando la l&#243;gica y ordenaci&#243;n</a></h3>
            <p>Controlar el c&#243;mo y en qu&#233; orden se va a aplicar la autorizaci&#243;n ha 
            	sido un misterio en el pasado. En Apache 2.2 un proveedor del 
            	mecanismo de autenticaci&#243;n fue introducido para disociar el proceso actual
            	de autenticaci&#243;n y soportar funcionalidad.
            	Uno de los beneficios secundarios fue que los proveedores de autenticaci&#243;n
            	pod&#237;an ser configurados y llamados en un orden especifico que no dependieran
            	en el orden de carga del propio modulo. 
            	Este proveedor de dicho mecanismo, ha sido introducido en la autorizaci&#243;n
            	tambi&#233;n. Lo que esto significa es que la directiva 
            	<code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> 
            	no s&#243;lo especifica que m&#233;todo de autorizaci&#243;n deber&#225; ser usado, si no
            	tambi&#233;n especifica el orden en que van a ser llamados. M&#250;ltiples
            	m&#233;todos de autorizaci&#243;n son llamados en el mismo orden en que la directiva
                <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> aparece en la
                configuraci&#243;n.
            </p>
    
            <p>
            	Con la Introducci&#243;n del contenedor de directivas de autorizaci&#243;n tales como
    	        <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
    	        y
    	        <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>,
    	        La configuraci&#243;n tambi&#233;n tiene control sobre cu&#225;ndo se llaman a los m&#233;todos
    	        de autorizaci&#243;n y qu&#233; criterios determinan cu&#225;ndo se concede el acceso.
    	        Vease
    	        <a href="../mod/mod_authz_core.html#logic">Contenedores de autorizaci&#243;n</a>
    	        Para un ejemplo de c&#243;mo pueden ser utilizados para expresar una l&#243;gica 
    	        m&#225;s compleja de autorizaci&#243;n.
    	    </p>
    
            <p>
            	Por defecto todas las directivas 
            	<code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
           		son manejadas como si estuvieran contenidas en una directiva
           		<code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>.
           		En otras palabras, Si alguno de los m&#233;todos de autorizaci&#243;n 
           		especificados tiene &#233;xito, se concede la autorizaci&#243;n.
           	</p>
    
        
    
        <h3><a name="reqaccessctrl" id="reqaccessctrl">Uso de los proveedores de autorizaci&#243;n para 
        	el control de acceso</a></h3>
    
        	<p>
        		La autenticaci&#243;n de nombre de usuario y contrase&#241;a es s&#243;lo parte
        		de toda la historia que conlleva el proceso. Frecuentemente quiere
        		dar acceso a la gente en base a algo m&#225;s que lo que son.
        		Algo como de donde vienen.
        	</p>
    
            <p>
            	Los proveedores de autorizaci&#243;n <code>all</code>,
            	<code>env</code>, <code>host</code> y <code>ip</code>
            	te permiten denegar o permitir el acceso bas&#225;ndose en otros
            	criterios como el nombre de la m&#225;quina o la IP de la m&#225;quina que
            	realiza la consulta para un documento.
            </p>
    
            <p>
            	El uso de estos proveedores se especifica a trav&#233;s de la directiva
            	<code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>.
            	La directiva registra los proveedores de autorizaci&#243;n que ser&#225;n llamados
            	durante la solicitud de la fase del proceso de autorizaci&#243;n. Por ejemplo:
            </p>
    
            <pre class="prettyprint lang-config">Require ip <var>address</var>
            </pre>
    
    
            <p>
            	Donde <var>address</var> es una direcci&#243;n IP (o una direcci&#243;n IP parcial) 
            	o bien:
            </p>
    
            <pre class="prettyprint lang-config">Require host <var>domain_name</var>
            </pre>
    
    
            <p>
            	Donde <var>domain_name</var> es el nombre completamente cualificado de un nombre 
    	        de dominio (FQDN) (o un nombre parcial del dominio);
    	        puede proporcionar m&#250;ltiples direcciones o nombres de dominio, si se desea.
            </p>
    
            <p>
            	Por ejemplo, si alguien env&#237;a spam a su tabl&#243;n de mensajes y desea
            	mantenerlos alejados, podr&#237;a hacer lo siguiente:</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 10.252.46.165
    &lt;/RequireAll&gt;</pre>
    
    
            <p>
            	Visitantes que vengan desde esa IP no ser&#225;n capaces de ver el contenido
            	que cubre esta directiva. Si, en cambio, lo que se tiene es el nombre de
            	la m&#225;quina, en vez de la direcci&#243;n IP, podr&#237;a usar:
            </p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not host host.example.com
    &lt;/RequireAll&gt;</pre>
    
    
            <p>
            	Y, si lo que se quiere es bloquear el acceso desde un determinado dominio
            	(bloquear el acceso desde el dominio entero), puede especificar parte 
            	de la direcci&#243;n o del propio dominio a bloquear:
            </p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 192.168.205
        Require not host phishers.example.com moreidiots.example
        Require not host ke
    &lt;/RequireAll&gt;</pre>
    
    
            <p>
            	Usando <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
    	        con m&#250;ltiples directivas <code class="directive"><a href="../mod/mod_authz_core.html#require">&lt;Require&gt;</a></code>, cada una negada con un <code>not</code>,
    	        S&#243;lo permitir&#225; el acceso, si todas las condiciones negadas son verdaderas.
    	        En otras palabras, el acceso ser&#225; bloqueado, si cualquiera de las condiciones
    	        negadas fallara.
            </p>
    
        
    
        <h3><a name="filesystem" id="filesystem">Compatibilidad de Control de Acceso con versiones 
        	anteriores </a></h3>
    
            <p>
            	Uno de los efectos secundarios de adoptar proveedores basados en 
            	mecanismos de autenticaci&#243;n es que las directivas anteriores
    	        <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>,
    	        <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>,
    	        <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> y
            	<code class="directive"><a href="../mod/mod_access_compat.html#satisfy">Satisfy</a></code> ya no son necesarias.
            	Sin embargo, para proporcionar compatibilidad con configuraciones antiguas,
            	estas directivas se han movido al m&#243;dulo <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code>.
            </p>
    
            <div class="warning"><h3>Nota:</h3>
    	        <p>
    	        	Las directivas proporcionadas por <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> 
    	        	han quedado obsoletas por <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>. Mezclar 
    	        	directivas antiguas como
    	        	<code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>, 
    	            <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code> &#243; 
    	            <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> con las nuevas 
    	            como 
    	            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> 
    	            es t&#233;cnicamente posible pero desaconsejable. El m&#243;dulo 
    	            <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> se cre&#243; para soportar configuraciones
    	            que contuvieran s&#243;lo directivas antiguas para facilitar la actualizaci&#243;n
    	            a la versi&#243;n 2.4.
    	            Por favor revise la documentaci&#243;n de 
    	            <a href="../upgrading.html">actualizaci&#243;n</a> para m&#225;s informaci&#243;n al
    	            respecto.
    	        </p>
    	    </div>
    	
    
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="socache" id="socache">Cache de Autenticaci&#243;n</a></h2>
    	<p>
    		Puede haber momentos en que la autenticaci&#243;n ponga una carga 
    		inaceptable en el proveedor (de autenticaci&#243;n) o en tu red.
    		Esto suele afectar a los usuarios de <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code> 
    		(u otros proveedores de terceros/personalizados).
    		Para lidiar con este problema, HTTPD 2.3/2.4 introduce un nuevo proveedor
    		de cach&#233;  <code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code> para cachear las credenciales 
    		y reducir la carga en el proveedor(es) original.
    	</p>
        <p>
        	Esto puede ofrecer un aumento de rendimiento sustancial para algunos usuarios.
        </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">M&#225;s informaci&#243;n</a></h2>
    
        <p>
        	Tambi&#233;n deber&#237;a leer la documentaci&#243;n para
        	<code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> y <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>
        	la cu&#225;l contiene m&#225;s informaci&#243;n de como funciona todo esto.
        	La directiva <code class="directive"><a href="../mod/mod_authn_core.html#authnprovideralias">&lt;AuthnProviderAlias&gt;</a></code> puede tambi&#233;n ayudar 
    	    a la hora de simplificar ciertas configuraciones de autenticaci&#243;n.
    	</p>
    
        <p>
        	Los diferentes algoritmos de cifrado que est&#225;n soportados por Apache
        	para la autenticaci&#243;n se explican en
        	<a href="../misc/password_encryptions.html">Cifrado de Contrase&#241;as</a>.
        </p>
    
        <p>
        	Y tal vez quiera ojear la documentaci&#243;n de "how to"  
        	<a href="access.html">Control de Acceso</a>  donde se mencionan temas 
        	relacionados.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/auth.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/cgi.html.es����������������������������������������������������������0000664�0001751�0001751�00000107276�14743132254�020247� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Tutorial de Apache: Contenido Din&#225;mico con CGI - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a> &gt; <a href="./">How-To / Tutoriales</a></div><div id="page-content"><div id="preamble"><h1>Tutorial de Apache: Contenido Din&#225;mico con CGI</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta traducci&#243;n podr&#237;a estar
                obsoleta. Consulte la versi&#243;n en ingl&#233;s de la
                documentaci&#243;n para comprobar si se han producido cambios
                recientemente.</div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#intro">Introducci&#243;n</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">Configurando Apache para permitir CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#writing">Escribiendo un programa CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">&#161;Pero todav&#237;a no funciona!</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#behindscenes">&#191;Qu&#233; ocurre entre bastidores?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#libraries">M&#243;dulos/librer&#237;as CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinfo">Para m&#225;s informaci&#243;n</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">Introducci&#243;n</a></h2>
    	    
    		<table class="related"><tr><th>M&#243;dulos Relacionados</th><th>Directivas Relacionadas</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_cgid.html">mod_cgid</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li></ul></td></tr></table>
    
        	<p>CGI (Common Gateway Interface) es un m&#233;todo por el cual
    		un servidor web puede interactuar con programas externos de 
    		generaci&#243;n de contenido, a ellos nos referimos com&#250;nmente como 
    		programas CGI o scripts CGI. Es el m&#233;todo m&#225;s com&#250;n y sencillo de
            mostrar contenido din&#225;mico en su sitio web. Este documento es una 
    		introducci&#243;n para configurar CGI en su servidor web Apache, y de
    		iniciaci&#243;n para escribir programas CGI.</p>
    	</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">Configurando Apache para permitir CGI</a></h2>
    		
    
            <p>Para conseguir que sus programas CGI funcionen correctamente,
    	    deber&#225; configurar Apache para que permita la ejecuci&#243;n de CGI. Hay
    	    distintas formas de hacerlo.</p>
    
            <div class="warning">Nota: Si Apache ha sido compilado con soporte
            de m&#243;dulos compartidos, necesitar&#225; que el m&#243;dulo de CGI est&#233; cargado;
            en su <code>httpd.conf</code> tiene que asegurarse de que la directiva
            <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>
            no ha sido comentada. Una directiva configurada correctamente ser&#237;a as&#237;:
                
                <pre class="prettyprint lang-config">LoadModule cgid_module modules/mod_cgid.so</pre>
    
    
            En Windows, o si usa un mpm que no es multihilo, como prefork, una 
            directiva configurada correctamente podr&#237;a definirse as&#237;: 
    
            <pre class="prettyprint lang-config">LoadModule cgi_module modules/mod_cgi.so</pre>
    </div>
    
            <h3><a name="scriptalias" id="scriptalias">ScriptAlias</a></h3>
                
    
                <p>La directiva
                <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
                indica a Apache que un directorio se ha configurado espec&#237;ficamente
                para programas CGI. Apache asumir&#225; que cada fichero en este 
                directorio es un programa CGI, e intentar&#225; ejecutarlos cuando un
                cliente solicita este recurso.</p>
            
                <p>La directiva 
                <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> se puede 
                definir as&#237;:</p>
    
                <pre class="prettyprint lang-config">ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"</pre>
    
            
                <p>El ejemplo que se muestra es de un archivo de configuraci&#243;n
                <code>httpd.conf</code> por defecto si usted instal&#243; Apache
                en la ubicaci&#243;n por defecto. La directiva
                <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> es muy 
                parecida a la directiva <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>,
                &#233;sta define un prefijo de URL que se enlaza a un directorio 
                en particular. <code class="directive">Alias</code> y
                <code class="directive">ScriptAlias</code> se usan generalmente para 
                directorios que se encuentran fuera del directorio 
                <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>. La diferencia
                entre <code class="directive">Alias</code> y <code class="directive">ScriptAlias</code>
                es que en <code class="directive">ScriptAlias</code> cualquier elemento
                debajo de ese prefijo de URL ser&#225; considerado un programa CGI. As&#237;, 
                el ejemplo de m&#225;s arriba le indica a Apache que
                cualquier solicitud para un recurso que comience con 
                <code>/cgi-bin/</code> deber&#237;a servirse desde el directorio
                <code>/usr/local/apache2/cgi-bin/</code>, y deber&#237;a tratarse como un
                programa CGI.</p>
    
                <p>Por ejemplo, si se solicita la URL
                <code>http://www.example.com/cgi-bin/test.pl</code>,
                Apache intentar&#225; ejecutar el archivo
                <code>/usr/local/apache2/cgi-bin/test.pl</code> y dar
                el resultado. Por supuesto el archivo debe existir y ser ejecutable, 
                y dar el resultado de una manera espec&#237;fica o Apache devolver&#225;
                un mensaje de error.</p>
            
    
            <h3><a name="nonscriptalias" id="nonscriptalias">CGI fuera de directorios ScriptAlias</a></h3>
                
    
                <p>Los programas CGI habitualmente se restringen a los directorios de
                <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> por razones de
                seguridad. De esta manera, los administradores pueden controlar de una
                manera m&#225;s segura quien puede ejecutar programas CGI. Aun as&#237;, si no
                se toman suficientes precauciones, no hay ninguna raz&#243;n por la que
                programas CGI no se puedan ejecutar desde directorios seleccionados de 
                manera arbitraria. Por ejemplo, quiz&#225;s quiera permitir que usuarios del
                sistema tengan contenido web en sus directorios home con la directiva
                <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>. Si quieren 
                tener sus propios programas CGI, pero no tienen acceso al directorio 
                principal <code>cgi-bin</code>, necesitar&#225;n ser capaces de 
                ejecutar sus scripts CGI en alg&#250;n otro sitio.</p>
          
                <p>Hay dos pasos a seguir para permitir la ejecuci&#243;n CGI en directorios
                seleccionados de manera arbitraria. Primero, el handler 
                <code>cgi-script</code> debe estar activado usando la directiva 
                <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> o la directiva 
                <code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code>. Segundo, el par&#225;metro
                <code>ExecCGI</code> debe estar definido en la directiva
                <code class="directive"><a href="../mod/core.html#options">Options</a></code>.</p>
            
    
            <h3><a name="options" id="options">Usando Options de manera expl&#237;cita para permitir ejecuci&#243;n de 
                CGI</a></h3>
                
    
                <p>Puede usar la directiva 
                <code class="directive"><a href="../mod/core.html#options">Options</a></code>, en el archivo de 
                configuraci&#243;n principal para especificar que se permite la ejecuci&#243;n 
                de CGI en un directorio en particular:</p>
    
                <pre class="prettyprint lang-config">&lt;Directory "/usr/local/apache2/htdocs/somedir"&gt;
        Options +ExecCGI
    &lt;/Directory&gt;</pre>
    
                
                <p>Esta directiva de aqu&#237; arriba le indica a Apache que debe 
                permitir la ejecuci&#243;n de archivos CGI. Tambi&#233;n necesitar&#225; indicarle 
                al servidor que los archivos son archivos CGI. La directiva 
                <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> le indica al 
                servidor que debe tratar a todos los archivos con la extensi&#243;n 
                <code>cgi</code> o <code>pl</code> como programas CGI:</p>
    
                <pre class="prettyprint lang-config">AddHandler cgi-script .cgi .pl</pre>
    
            
    
            <h3><a name="htaccess" id="htaccess">Ficheros .htaccess</a></h3>
                
    
                <p>El <a href="htaccess.html">tutorial <code>.htaccess</code></a>
                ense&#241;a como activar programas CGI si no tienes acceso a 
                <code>httpd.conf</code>.</p>
            
    
            <h3><a name="userdir" id="userdir">Directorios de Usuario</a></h3>
                
    
                <p>Para permitir la ejecuci&#243;n de programas CGI para cualquier 
                archivo que acabe en <code>.cgi</code> en directorios de usuario, 
                puedes usar la siguiente configuraci&#243;n:</p>
    
                <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html"&gt;
        Options +ExecCGI
        AddHandler cgi-script .cgi
    &lt;/Directory&gt;</pre>
    
    
                <p>Si quiere designar un subdirectorio <code>cgi-bin</code> dentro 
                de un directorio de usuario en el que todos los ficheros ser&#225;n 
                tratados como un programa CGI, puede usar lo siguiente:</p>
    
                <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html/cgi-bin"&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
            
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="writing" id="writing">Escribiendo un programa CGI</a></h2>
            
    
            <p>Hay dos diferencias principales entre programaci&#243;n ``regular'' y 
            programaci&#243;n en CGI.</p>
    
            <p>Primera, el resultado al completo de tu programa CGI debe estar 
            precedido de una cabecera <a class="glossarylink" href="../glossary.html#mime-type" title="ver glosario">MIME-type</a>. Esta
            cabecera HTTP le indica al cliente que tipo de contenido est&#225;
            recibiendo. La mayor parte de las veces, &#233;sto ser&#225; algo como:</p>
    
            <div class="example"><p><code>
                Content-type: text/html
            </code></p></div>
    
            <p>Segunda, el resultado debe estar en formato HTML, o cualquier 
            otro formato que su navegador sea capaz de mostrar. La mayor
            parte de las veces, ser&#225; HTML, pero otras escribir&#225; un programa
            CGI que devuelve una imagen gif, u otro contenido no-HTML.</p>
    
            <p>Aparte de estas dos cosas, escribir un programa en CGI se 
            parecer&#225; bastante a cualquier otro programa que vaya a escribir.
            </p>
    
    
            <h3><a name="firstcgi" id="firstcgi">Su primer programa CGI</a></h3>
                
    
                <p>A continuaci&#243;n podr&#225; ver un ejemplo de programa CGI que muestra
                una l&#237;nea de texto en su navegador. Escriba lo siguiente, 
                gu&#225;rdelo en un archivo con el nombre <code>first.pl</code>, y 
                p&#243;ngalo en su directorio <code>cgi-bin</code>.</p>
    
                <pre class="prettyprint lang-perl">#!/usr/bin/perl
    print "Content-type: text/html\n\n";
    print "Hola, Mundo.";</pre>
    
    
                <p>Incluso si Perl no le resulta familiar, podr&#225; ver lo que est&#225;
                ocurriendo aqu&#237;. La primera l&#237;nea le dice a Apache (o a
                cualquier shell en la que se est&#233; ejecutando) que este programa
                puede ejecutarse con el int&#233;rprete en la ubicaci&#243;n
                <code>/usr/bin/perl</code>. La segunda l&#237;nea imprime la
                declaraci&#243;n de Content-Type que mencionamos antes, seguida de 
                dos pares de retornos de carro. Esto pone una l&#237;nea en blanco 
                despu&#233;s de la cabecera para indicar el final de las cabeceras
                HTTP, y el comienzo del cuerpo del contenido. La tercera 
                imprime la cadena de caracteres "Hola, Mundo.". Y ese es el 
                final del programa.</p>
    
                <p>Si lo abre con su navegador favorito y le dice que solicite la 
                direcci&#243;n</p>
    
                <div class="example"><p><code>
                    http://www.example.com/cgi-bin/first.pl
                </code></p></div>
    
                <p>o donde quiera que pusiera el archivo, ver&#225; una l&#237;nea
                <code>Hola, Mundo.</code> aparecer&#225;n la ventana del navegador. No es 
                muy emocionante, pero una vez que consiga que funcione podr&#225; hacer 
                lo mismo con casi cualquier programa.</p>
            
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">&#161;Pero todav&#237;a no funciona!</a></h2>
            
    
            <p>Hay 4 cosas b&#225;sicas que puede llegar a ver en su navegador cuando
            intenta acceder a un programa CGI desde la web:</p>
    
            <dl>
                <dt>El resultado del programa CGI</dt>
                <dd>&#161;Genial! Esto indica que todo funcion&#243; correctamente. Si el
                resultado es correcto, pero el navegador no lo procesa
                correctamente, aseg&#250;rese de que tiene especificado 
                correctamente el <code>Content-Type</code> en su programa 
                CGI.</dd>
    
                <dt>El c&#243;digo fuente de su programa CGI o un mensaje del tipo 
                "POST Method Not Allowed".</dt>
    
                <dd>Eso significa que no ha configurado Apache de manera
                apropiada para interpretar su programa CGI. Relea la secci&#243;n
                de <a href="#configuring">Configurando Apache</a> e intente
                encontrar qu&#233; le falta.</dd>
    
                <dt>Un mensaje que empieza con "Forbidden"</dt>
                <dd>Eso significa que hay un problema de permisos. Compruebe el
                <a href="#errorlogs">Log de Errores de Apache</a> y la
                secci&#243;n de m&#225;s abajo de <a href="#permissions">Permisos de
                Fichero</a>.</dd>
    
                <dt>Un mensaje indicando "Internal Server Error"</dt>
                <dd>Si comprueba el <a href="#errorlogs">Log de errores de
                Apache</a>, probablemente encontrar&#225; que indica "Premature 
                end of script headers", posiblemente acompa&#241;ado de otro 
                mensaje de error generado por su programa CGI. En este caso, 
                querr&#225; comprobar cada una de las secciones de m&#225;s adelante 
                para ver qu&#233; impide que su programa CGI genere las cabeceras 
                HTTP adecuadas.</dd>
                </dl>
    
            <h3><a name="permissions" id="permissions">Permisos de Fichero</a></h3>
                
    
                <p>Recuerde que el servidor no se ejecuta con su usuario. Es decir,
                cuando el servidor arranca, est&#225; funcionando con un usuario sin
                privilegios, generalmente el usuario <code>nobody</code>, o
                <code>www-data</code>, as&#237; que necesitar&#225; permisos extra para
                ejecutar los archivos de los que usted es due&#241;o. Generalmente, 
                el m&#233;todo para dar permisos suficientes para que se pueda 
                ejecutar con <code>nobody</code> es dar permisos de ejecuci&#243;n a 
                todo el mundo en el fichero:</p>
    
                <div class="example"><p><code>
                    chmod a+x first.pl
                </code></p></div>
    
                <p>Adem&#225;s, si su programa lee desde o escribe a cualquier otro/s
                archivo/s, esos archivos necesitar&#225;n tener los permisos correctos
                para permitir esas acciones.</p>
    
            
    
            <h3><a name="pathinformation" id="pathinformation">Informaci&#243;n de Ruta y Entorno</a></h3>
                
    
                <p>Cuando ejecuta un programa desde la l&#237;nea de comandos, usted tiene
                cierta informaci&#243;n que se le pasa a la shell sin que usted se
                percate de ello. Por ejemplo, usted tiene un <code>PATH</code>,
                que le indica a la shell d&#243;nde debe buscar archivos a los que usted
                hace referencia.</p>
    
                <p>Cuando un programa se ejecuta a trav&#233;s del servidor web como un
                programa CGI, puede que no tenga el mismo <code>PATH</code>. 
                Cualquier programa que invoque desde su programa CGI (como por
                ejemplo <code>sendmail</code>) necesitar&#225; que se le indique la
                ruta absoluta, as&#237; la shell puede encontrarlos cuando intenta 
                ejecutar su programa CGI.</p>
    
                <p>Una manifestaci&#243;n com&#250;n de esto es la ruta del int&#233;rprete del 
                script (a menudo <code>perl</code>) indicado en la primera l&#237;nea
                de su programa CGI, que parecer&#225; algo como:</p>
    
                <pre class="prettyprint lang-perl">#!/usr/bin/perl</pre>
    
    
                <p>Aseg&#250;rese de que &#233;ste es de hecho el path de su int&#233;rprete.</p>
                <div class="warning">
                Cuando edita scripts CGI en Windows, los caracteres de retorno de
                carro podr&#237;an a&#241;adirse a la l&#237;nea donde se especifica el int&#233;rprete. 
                Aseg&#250;rese de que los archivos se transfieren al servidor en modo 
                ASCII. Fallar en esto puede acabar con avisos del tipo "Command not 
                found" del Sistema Operativo, debido a que &#233;ste no reconoce los 
                caracteres de final de l&#237;nea interpretados como parte del nombre
                de fichero del int&#233;rprete.
                </div>
            
    
            <h3><a name="missingenv" id="missingenv">Faltan Variables de Entorno</a></h3>
                
    
                <p>Si su programa CGI depende de <a href="#env">variables de entorno</a> no est&#225;ndar, necesitar&#225;
                asegurarse de que Apache pasa esas variables.</p>
    
                <p>Cuando no encuentra ciertas cabeceras HTTP del entorno, aseg&#250;rese 
                de que est&#225;n formateadas seg&#250;n el 
                <a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>, 
                secci&#243;n 4.2: Nombres de Cabeceras deben empezar con una letra, 
                seguida solo de letras, n&#250;meros o gui&#243;n. Cualquier cabecera 
                que no cumpla esta regla ser&#225; ignorada de manera silenciosa.</p>
    
            
    
            <h3><a name="syntaxerrors" id="syntaxerrors">Errores de Programa</a></h3>
                
    
                <p>La mayor parte de las veces cuando un programa CGI falla, es por un 
                problema en el programa mismo. Esto ocurre generalmente cuando se 
                maneja bien con "esto del CGI", y ya no comete los dos errores
                mencionados m&#225;s arriba. Lo primero que hay que hacer es asegurarse
                de que su programa se ejecuta correctamente en l&#237;nea de comandos 
                antes de probarlo a trav&#233;s del servidor web.  Por ejemplo, 
                intente:</p>
    
                <div class="example"><p><code>
                    cd /usr/local/apache2/cgi-bin<br />
                    ./first.pl
                </code></p></div>
    
                <p>(No llame al int&#233;rprete de <code>perl</code>. La consola y Apache 
                tienen que poder encontrar el int&#233;rprete usando l&#237;nea 
                <a href="#pathinformation">l&#237;nea de informaci&#243;n</a> en la primera 
                l&#237;nea del script.)</p>
    
                <p>Lo primero que debe ver escrito por su programa es un conjunto de 
                cabeceras HTTP, incluyendo el <code>Content-Type</code>,
                seguido de una l&#237;nea en blanco.  Si ve alguna otra cosa, Apache
                devolver&#225; el error <code>Premature end of script headers</code> si
                intenta lanzar el script en el servidor web. Vea 
                <a href="#writing">Escribiendo un programa CGI</a> m&#225;s arriba para
                m&#225;s detalle.</p>
            
    
            <h3><a name="errorlogs" id="errorlogs">Log de Errores</a></h3>
                
    
                <p>El log de errores es su amigo. Cualquier cosa que vaya mal generar&#225; 
                un mensaje en el log de errores. Deber&#237;a mirar siempre ah&#237; primero. 
                Si el lugar donde est&#225; alojando su sitio web no permite que acceda
                al log de errores, probablemente deber&#237;a alojarlo en otro sitio.
                Aprenda a leer el log de errores y se dar&#225; cuenta de que enseguida
                averiguar&#225; el motivo del error y lo solucionar&#225; r&#225;pidamente.</p>
            
    
            <h3><a name="suexec" id="suexec">Suexec</a></h3>
                
    
                <p>El programa de soporte <a href="../suexec.html">suexec</a> permite
                que programas CGI se ejecuten con permisos de usuario distintos,
                dependiendo del virtualhost o el directorio home donde se 
                encuentren. Suexec tiene una comprobaci&#243;n de permisos muy estricta, 
                y cualquier fallo en esa comprobaci&#243;n dar&#225; como resultado un error
                con el mensaje <code>Premature end of script headers</code>.</p>
    
                <p>Para comprobar si est&#225; usando Suexec, ejecute 
                <code>apachectl -V</code> y compruebe la ubicaci&#243;n de 
                <code>SUEXEC_BIN</code>. Si Apache encuentra un binario 
                <code class="program"><a href="../programs/suexec.html">suexec</a></code> al arrancar, suexec se activar&#225;.</p>
    
                <p>A menos que comprenda suxec perfectamente, no deber&#237;a usarlo.
                Para desactivar suexec, basta con eliminar el binario 
                <code class="program"><a href="../programs/suexec.html">suexec</a></code> al que apunta <code>SUEXEC_BIN</code> y 
                reiniciar el servidor. Si despu&#233;s de leer sobre 
                <a href="../suexec.html">suexec</a> todav&#237;a quiere usarlo, entonces
                ejecute <code>suexec -V</code> para encontrar la ubicaci&#243;n del 
                fichero log de suexec, y use ese log para encontrar que pol&#237;tica no
                est&#225; cumpliendo.</p>
            
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behindscenes" id="behindscenes">&#191;Qu&#233; ocurre entre bastidores?</a></h2>
            
    
            <p>En cuanto tenga conocimiento avanzado de programaci&#243;n CGI, le ser&#225; 
            &#250;til comprender m&#225;s de lo que ocurre entre bastidores. 
            Espec&#237;ficamente, c&#243;mo el navegador y el servidor se comunican el uno
            con el otro. Porque aunque est&#233; muy bien escribir un programa que 
            diga "Hola, Mundo.", no tiene una gran utilidad.</p>
    
            <h3><a name="env" id="env">Variables de Entorno</a></h3>
                
    
                <p>Las variables de entorno son valores que est&#225;n ah&#237; cuando 
                usa el ordenador. Son cosas &#250;tiles como el path (donde su ordenador
                busca el archivo espec&#237;fico que se lanza cuando usted escribe un 
                comando), su nombre de usuario, el tipo de terminal que usa, etc. 
                Para una lista completa de la variables de entorno normales que se 
                se usan en su d&#237;a a d&#237;a escriba <code>env</code> en la l&#237;nea de 
                comandos.</p>
    
                <p>Durante la transacci&#243;n CGI, el servidor y el navegador tambi&#233;n 
                configuran variables de entorno, y as&#237; pueden comunicarse entre 
                ellos. Cosas como el tipo de navegador (Netscape, IE, Lynx), el tipo
                de servidor (Apache, IIS, WebSite), el nombre del programa CGI que
                se est&#225; ejecutando, etc.</p>
    
                <p>Estas variables est&#225;n disponibles para el programador de CGI, y son 
                la mitad de la historia de la comunicaci&#243;n cliente-servidor. La 
                lista completa de las variables necesarias se encuentra en 
                <a href="http://www.ietf.org/rfc/rfc3875">el RFC de Common Gateway
                Interface</a>.</p>
    
                <p>Este sencillo programa CGI en Perl mostrar&#225; todas las variables 
                de entorno que se est&#225;n pasando entre el cliente y el navegador. Dos
                programas similares est&#225;n incluidos en el directorio 
                <code>cgi-bin</code> de la distribuci&#243;n de Apache. Tenga en cuenta
                que algunas variables son necesarias mientras que otras son 
                opcionales, as&#237; que es posible que vea algunas variables que no 
                est&#225;n en la lista oficial. Adicionalmente, Apache aporta distintas
                maneras diferentes para que pueda
                <a href="../env.html">a&#241;adir sus variables de entorno</a> a las 
                b&#225;sicas que se proveen por defecto.</p>
    
                <pre class="prettyprint lang-perl">#!/usr/bin/perl
    use strict;
    use warnings;
    
    print "Content-type: text/html\n\n";
              
    foreach my $key (keys %ENV) {
        print "$key --&gt; $ENV{$key}&lt;br&gt;";
    }</pre>
    
            
    
            <h3><a name="stdin" id="stdin">STDIN y STDOUT</a></h3>
                
    
                <p>Otra comunicaci&#243;n entre el servidor y el cliente ocurre en la 
                entrada est&#225;ndar (<code>STDIN</code>) y la salida est&#225;ndar 
                (<code>STDOUT</code>). En el contexto normal de cada d&#237;a, 
                <code>STDIN</code> es la entrada con el teclado, o un fichero que se 
                le da a un programa para que act&#250;e sobre &#233;l, y <code>STDOUT</code>
                generalmente es la consola o la pantalla.</p>
    
                <p>Cuando hace <code>POST</code> con un formulario de web a un programa 
                CGI, los datos en ese formulario se empaquetan en un formato especial
                que se entrega a su programa CGI en el <code>STDIN</code>.
                Entonces el programa puede procesar la informaci&#243;n como si le llegara
                desde el teclado, o desde un fichero.</p>
    
                <p>El "formato especial" es muy sencillo. Un nombre de campo y su 
                valor se asocian juntos con el signo igual (=), y pares de valores 
                se asocian juntos con el ampersand &#243; et en espa&#241;ol (&amp;). 
                Caracteres inconvenientes como los espacios, ampersands y signos de 
                igual, se convierten en su equivalente hexadecimal para no impidan 
                el funcionamiento correcto del programa. La cadena de datos al 
                completo ser&#225; algo como:</p>
    
      <div class="example"><p><code>
            name=Rich%20Bowen&amp;city=Lexington&amp;state=KY&amp;sidekick=Squirrel%20Monkey
      </code></p></div>
    
                <p>A veces tendr&#225; este tipo de cadena de caracteres al final de una 
                URL. Cuando esto ocurre, el servidor pone esa cadena en una variable 
                de entorno que se llama <code>QUERY_STRING</code>. Esto se llama 
                solicitud <code>GET</code>. Su formulario HTML especifica si se usa 
                un <code>GET</code> o un <code>POST</code> para entregar la 
                informaci&#243;n, configurando el atributo <code>METHOD</code> en la 
                etiqueta <code>FORM</code>.</p>
    
                <p>Su programa es el responsable de convertir esa cadena de 
                caracteres en informaci&#243;n &#250;til. Afortunadamente, hay librer&#237;as y 
                m&#243;dulos disponibles que ayudan a procesar la informaci&#243;n, as&#237; como a 
                gestionar los distintos aspectos de su programa CGI.</p>
            
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="libraries" id="libraries">M&#243;dulos/librer&#237;as CGI</a></h2>
            
    
            <p>Cuando escribe programas CGI, deber&#237;a considerar usar una librer&#237;a de
            c&#243;digo, o m&#243;dulo, para hacer todo el trabajo m&#225;s arduo por usted.
            Esto lleva a tener menos errores y un desarrollo de c&#243;digo m&#225;s 
            r&#225;pido.</p>
    
            <p>Si est&#225; escribiendo un programa CGI en Perl, existen m&#243;dulos 
            disponibles en <a href="http://www.cpan.org/">CPAN</a>. El m&#243;dulo m&#225;s
            conocido para este prop&#243;sito es <code>CGI.pm</code>. Quiz&#225;s quiera
            considerar <code>CGI::Lite</code>, que implementa una funcionalidad 
            m&#237;nima, que es todo lo que se necesita en la mayor&#237;a de los programas.</p>
    
            <p>Si est&#225; escribiendo programas CGI en C, hay varidad de opciones. Una
            de estas es la librer&#237;a <code>CGIC</code>, de
            <a href="http://www.boutell.com/cgic/">http://www.boutell.com/cgic/</a>.
            </p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinfo" id="moreinfo">Para m&#225;s informaci&#243;n</a></h2>
            
    
            <p>La especificaci&#243;n actual de CGI est&#225; disponible en el
            <a href="http://www.ietf.org/rfc/rfc3875">RFC de Common Gateway
            Interface</a>.</p>
    
            <p>Cuando env&#237;e una pregunta sobre un problema de CGI, o bien a una 
            lista de correo, o a un grupo de noticias, aseg&#250;rese de que facilita suficiente
            informaci&#243;n de lo que ha ocurrido, de lo que espera que ocurra, y de 
            lo que est&#225; ocurriendo en su lugar que es diferente, el servidor que 
            est&#225; ejecutando, en qu&#233; lenguaje CGI est&#225; hecho su programa, y si es
            posible, el c&#243;digo que falla. Esto har&#225; encontrar el problema mucho m&#225;s 
            f&#225;cil.</p>
    
            <p>Tenga en cuenta que las preguntas sobre problemas CGI 
            <strong>nunca</strong> deber&#237;an enviarse a la base de datos de bugs de
            bugs de Apache a menos que est&#233; seguro de haber encontrado un 
            problema en el c&#243;digo fuente de Apache.</p>
        </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/cgi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/htaccess.html.ja.utf8������������������������������������������������0000664�0001751�0001751�00000070341�14743132254�022142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache チュートリアル: .htaccess ファイル - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">How-To / チュートリアル</a></div><div id="page-content"><div id="preamble"><h1>Apache チュートリアル: .htaccess ファイル</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <p><code>.htaccess</code> ファイルはディレクトリ毎に設定を変更する方法を
    提供します。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">.htaccess ファイル</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">.htaccess ファイルとは何か/その使い方</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#when">いつ .htaccess ファイルを使う(使わない)か。</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#how">ディレクティブの適用のされ方</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#auth">認証の例</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssi">SSI の例</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">CGI の例</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">問題解決</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">.htaccess ファイル</a></h2>
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li><li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li><li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">.htaccess ファイルとは何か/その使い方</a></h2>
    
    
        <p><code>.htaccess</code> ファイル (「分散設定ファイル」) は
        ディレクトリ毎に設定を変更する方法を提供します。ディレクティブの
        書かれたファイルをディレクトリに置くことで、そのディレクトリとその
        サブディレクトリすべてにディレクティブを適用させることができます。</p>
    
        <div class="note"><h3>注:</h3>
          <p><code>.htaccess</code> ファイルを別の名前にしたい場合は、
          <code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code> ディレクティブを
          使って変更することができます。例えば、そのファイルを <code>.config</code> 
          という名前にしたい場合は、以下の設定をサーバ設定ファイルに入れることが
          できます:</p>
    
          <div class="example"><p><code>
            AccessFileName .config
          </code></p></div>
        </div>
    
        <p>一般に、<code>.htaccess</code> ファイルの構文は
        <a href="../configuring.html#syntax">主設定ファイル</a>
        と同じです。これらのファイルに書くことのできるディレクティブは <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> ディレクティブにより決まります。
        このディレクティブは、<code>.htaccess</code> ファイルに
        書かれたディレクティブの中で、、
        どのディレクティブが適用されるかをカテゴリー単位で指定します。
        <code>.htaccess</code> に書くことのできるディレクティブであれば、
        説明文書には「上書き」という項目があり、.htaccess に書くことができるように
        なるための <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> の値が指定されています。</p>
    
        <p>例えば、<code class="directive"><a href="../mod/core.html#adddefaultcharset">AddDefaultCharset</a></code> ディレクティブの説明を
        見ると、<code>.htaccess</code> ファイルでの使用が許可されていることが
        わかります。 (ディレクティブの概要の所にある「コンテキスト」と書かれている
        行を見てください。) <a href="../mod/directive-dict.html#Context">上書き</a>と書かれている行には
        <code>FileInfo</code> とあります。ですから、<code>.htaccess</code> 中の
        このディレクティブが有効になるためには、少なくとも
        <code>AllowOverride FileInfo</code> が設定されている必要があります。</p>
    
        <div class="example"><h3>例:</h3><table>
            <tr>
              <td><a href="../mod/directive-dict.html#Context">コンテキスト:</a></td>
              <td>サーバ設定ファイル,バーチャルホスト,ディレクトリ,.htaccess</td>
            </tr>
    
            <tr>
              <td><a href="../mod/directive-dict.html#Override">上書き:</a></td>
              <td>FileInfo</td>
            </tr>
          </table></div>
    
        <p>あるディレクティブを <code>.htaccess</code> ファイルに書くことができるか
        どうかわからないときは、そのディレクティブの説明を探して、".htaccess"
        のための「コンテキスト」の行を調べてください。</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="when" id="when">いつ .htaccess ファイルを使う(使わない)か。</a></h2>
    
        <p>一般的に、サーバの主設定ファイルにアクセスできない場合を除いて、
        <code>.htaccess</code> ファイルの使用は極力避けてください。
        世の中には、例えば、ユーザ認証は常に <code>.htaccess</code> ファイルで
        行なわなければならない、という誤解が広まっていますが、まったくそんなことは
        ありません。ユーザ認証の設定はサーバ主設定ファイルに書くことができ、
        実際、その方がより良い設定方法です。</p>
    
        <p><code>.htaccess</code> ファイルはコンテンツ提供者がディレクトリ毎の
        設定を行ないたいけれど、サーバシステムの root アクセス権限を持っていない
        という場合にのみ使うべきものです。サーバ管理者が頻繁に設定変更を行ないたくは
        ない、というときには個々のユーザが <code>.htaccess</code> ファイルを使って
        自分で設定の変更を行なうことを許可した方が良いときもあるでしょう。
        これは特に、ISP が複数のユーザのサイトを一つのマシンでホストしていて、
        各ユーザが設定の変更をできるようにしたいようなときにあてはまります。</p>
    
        <p>しかし、普通は可能であれば <code>.htaccess</code> ファイルの使用は
        避けてください。<code>.htaccess</code> ファイルに書こうと考えるような
        すべての設定は、サーバの主設定ファイルの <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> セクションで同じように行なうことが
        できます。</p>
    
        <p><code>.htaccess</code> ファイルの使用を避ける理由は主に二つあります。</p>
    
        <p>一つ目はサーバの性能の問題です。<code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> ディレクティブが
        <code>.htaccess</code> ファイルの設定を許可している場合は、Apache は
        各ディレクトリで <code>.htaccess</code> ファイルを探します。
        ですから、<code>.htaccess</code> ファイルを許可すると、実際に使用しているか
        どうかに関わらず、性能の低下を招くことになります! また、<code>.htaccess</code>
        ファイルは文書がリクエストされる度に読み込まれます。</p>
    
        <p>さらに、Apache は適用すべきディレクティブを集めるために、すべての
        上位のディレクトリの <code>.htaccess</code> ファイルを探す必要があることにも
        注意してください。(<a href="#how">ディレクティブが適用される方法</a>を
        参照してください。)ですから、<code>/www/htdocs/example</code> にある
        ファイルがリクエストされたときは、Apache は以下のファイルを調べます。</p>
    
        <div class="example"><p><code>
          /.htaccess<br />
          /www/.htaccess<br />
          /www/htdocs/.htaccess<br />
          /www/htdocs/example/.htaccess
        </code></p></div>
    
        <p>ですから、そのディレクトリのそれぞれのファイルへのアクセスに対して、
        上の例のファイルがまったく存在しないときでも、追加のファイルシステムの
        アクセスが行なわれることになります。(これは、<code>.htaccess</code> が
        <code>/</code> に対して有効になっているときの場合で、普通はそうなって
        いないことに注意してください。)</p>
    
        <p>二つ目はセキュリティです。ユーザにサーバの設定を変更することを
        許可することになりますので、あなた自身が管理できない変更をされる
        恐れがあります。ユーザにこの特権を与えるのが良いのかどうか、十分
        検討してください。また、ユーザに与える権限が必要なものよりも少なすぎると、
        余分な技術サポート報告を受け取るようになる可能性が高いことにも
        注意してください。確実に、ユーザにどの程度の権限を与えたか明確に告げるように
        してください。<code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> に
        何を設定したかということと、関連する文書を示すことで、
        後々の混乱をぐっと減らすことが
        できます。</p>
    
        <p>ところで、ディレクティブの書かれた <code>.htaccess</code> を
        <code>/www/htdocs/example</code> に置くことと、同じディレクティブを
        主サーバ設定の Directory セクション
        <code>&lt;Directory /www/htdocs/example&gt;</code> に書くことは
        完全に等価です:</p>
    
        <p><code>/www/htdocs/example</code> の <code>.htaccess</code> ファイル:</p>
    
        <div class="example"><h3><code>/www/htdocs/example</code> の .htaccess ファイルの
        内容</h3><p><code>
            AddType text/example .exm
        </code></p></div>
    
        <div class="example"><h3><code>httpd.conf のセクション</code>
        file</h3><p><code>
          &lt;Directory /www/htdocs/example&gt;<br />
          <span class="indent">
            AddType text/example .exm<br />
          </span>
          &lt;/Directory&gt;
        </code></p></div>
    
        <p>しかし、この設定はサーバ設定ファイルに書いた方がパフォーマンスの
        低下が少なくなります。ファイルがリクエストされる度に
        読み込まれる代わりに、Apache の起動時に 1 回だけ読み込めば
        よくなるからです。</p>
    
        <p><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> ディレクティブの
        値を <code>none</code> に設定することで <code>.htaccess</code> ファイル
        の使用を完全に無効にすることができます。</p>
    
        <div class="example"><p><code>
          AllowOverride None
        </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="how" id="how">ディレクティブの適用のされ方</a></h2>
    
        <p><code>.htaccess</code> ファイルの設定ディレクティブは <code>.htaccess</code>
        ファイルの存在するディレクトリと、そのサブディレクトリすべてに適用されます。
        しかし、上の階層のディレクトリにも <code>.htaccess</code> ファイルが
        存在するかもしれないことを覚えておくことは大切です。ディレクティブは現れる
        順番に適用されます。ですから、あるディレクトリの <code>.htaccess</code> は
        ディレクトリツリーのより上の階層の <code>.htaccess</code> ファイルの
        設定を上書きするかもしれません。そして、その <code>.htaccess</code> も
        より上の階層で書かれたディレクティブを上書きしたり、主サーバ設定ファイル
        そのものの設定を上書きしたりしているかもしれません。</p>
    
        <p>例:</p>
    
        <p>ディレクトリ <code>/www/htdocs/example1</code> に以下の内容の
        <code>.htaccess</code> ファイルがあります:</p>
    
        <div class="example"><p><code>
           Options +ExecCGI
        </code></p></div>
    
        <p>(注: <code>.htaccess</code>
        ファイルで "<code class="directive"><a href="../mod/core.html#options">Options</a></code>" ディレクティブが有効になるためには、
        "<code>AllowOverride Options</code>" を有効にする必要があります。)</p>
    
        <p>ディレクトリ <code>/www/htdocs/example1/example2</code> には
        以下のような <code>.htaccess</code> ファイルがあります:</p>
    
        <div class="example"><p><code>
           Options Includes
        </code></p></div>
    
        <p>二つめの <code>.htaccess</code> により、ディレクトリ
        <code>/www/htdocs/example1/example2</code> では CGI の実行は
        許可されません。これは、<code>Options Includes</code> のみが
        効力を持ち、それがすべての以前の設定を上書きするからです。</p>
    
        <h3><a name="merge" id="merge">メイン設定ファイルに対する
        .htaccess のマージ</a></h3>
    
        <p>As discussed in the documentation on <a href="../sections.html">Configuration Sections</a>,
        <code>.htaccess</code> files can override the <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> 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 <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> setting.  For example, to
        prevent script execution while allowing anything else to be set in
        <code>.htaccess</code> you can use:</p>
        <p><a href="../sections.html">セクションの設定</a>
        に記載されているように、<code>.htaccess</code> ファイルを使って
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
        セクションの設定をディレクトリ毎に上書きできますが、
        メイン設定ファイル中にある、他の種類の設定セクションによって
        さらに上書きされることもあります。
        この特徴を使って、
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        で自由度の高い設定があったとしても、ある特定の設定が確実に
        反映されるようにできます。例えば、CGI スクリプトの実行は
        不許可に、かつ、<code>.htaccess</code> でその他の項目は
        設定できるように、という場合は次のようにできます :</p>
        
        <div class="example"><p><code>
    &lt;Directory /&gt;<br />
    <span class="indent">
    Allowoverride All<br />
    </span>
    &lt;/Directory&gt;<br />
    <br />
    &lt;Location /&gt;<br />
    <span class="indent">
    Options +IncludesNoExec -ExecCGI<br />
    </span>
    &lt;/Location&gt;
        </code></p></div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="auth" id="auth">認証の例</a></h2>
    
        <p>もし認証の方法を知るためにこの部分に直接来たのであれば、次のことを
        知っておくことが重要です。よくある誤解に、パスワード認証を行なうためには
        <code>.htaccess</code> ファイルを使う必要がある、というものがあります。
        これは正しくありません。主サーバ設定ファイルの <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> セクションに
        認証用のディレクティブを書く方が推奨される方法で、<code>.htaccess</code>
        ファイルは主サーバ設定ファイルを変更できないときにのみ使用すべきです。
        いつ <code>.htaccess</code> ファイルを使うべきで、いつ使うべきではないかに
        ついては <a href="#when">上</a>を参照してください。</p>
    
        <p>以上のことをふまえた上で、もし <code>.htaccess</code> の使用が
        まだ必要だと思う場合は、次のようなものが望みのことをしてくれるかも
        しれません。</p>
    
        <p><code>.htaccess</code> ファイルの内容:</p>
    
        <div class="example"><p><code>
          AuthType Basic<br />
          AuthName "Password Required"<br />
          AuthUserFile /www/passwords/password.file<br />
          AuthGroupFile /www/passwords/group.file<br />
          Require Group admins
        </code></p></div>
    
        <p>これらのディレクティブが有効になるためには、
        <code>AllowOverride AuthConfig</code> が有効でなくてはならないことに
        注意してください。</p>
    
        <p>認証と承認については <a href="auth.html">認証チュートリアル</a>を
        参照してください。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssi" id="ssi">SSI の例</a></h2>
    
        <p>もう一つの <code>.htaccess</code> ファイルのよくある利用法は
        特定のディレクトリで SSI を有効にすることです。これは、望みのディレクトリの
        <code>.htaccess</code> ファイルに以下の設定ディレクティブを書くことで
        達成できます:</p>
    
        <div class="example"><p><code>
           Options +Includes<br />
           AddType text/html shtml<br />
           AddHandler server-parsed shtml
        </code></p></div>
    
        <p>これらのディレクティブが有効になるためには、
        <code>AllowOverride Options</code> と <code>AllowOverride
        FileInfo</code> が有効になっている必要があることに注意してください。</p>
    
        <p>よりまとまった SSI の説明は <a href="ssi.html">SSI チュートリアル</a>を
        参照してください。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">CGI の例</a></h2>
    
        <p>最後に、特定のディレクトリで CGI プログラムの実行を許可したいことが
        あるでしょう。これは以下の設定で行なうことができます:</p>
    
        <div class="example"><p><code>
           Options +ExecCGI<br />
           AddHandler cgi-script cgi pl
        </code></p></div>
    
        <p>もしくは、あるディレクトリのすべてのファイルが CGI プログラムと
        みなされるようにしたいなら、以下の設定で実現することができます:</p>
    
        <div class="example"><p><code>
           Options +ExecCGI<br />
           SetHandler cgi-script
        </code></p></div>
    
        <p>これらのディレクティブが有効になるためには、
        <code>AllowOverride Options</code> と <code>AllowOverride
        FileInfo</code> が有効である必要があることに注意してください。</p>
    
        <p>CGI プログラムと設定のよりまとまった説明は <a href="cgi.html">CGI チュートリアル</a>を参照してください。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">問題解決</a></h2>
    
        <p>設定ディレクティブを <code>.htaccess</code> ファイルに書いたけれども、
        期待した効果が得られないときには、いくつかの原因が考えられます。</p>
    
        <p>一番よくあることは、設定ディレクティブが考慮されるようには
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> が設定されていない
        というものです。該当のファイルのスコープに <code>AllowOverride None</code>
        が設定されていないことを確認してください。これを調べるための良い方法は、
        <code>.htaccess</code> ファイルにごみを書いて、リロードすることです。
        サーバのエラーが生成されないときは、ほぼ確実に <code>AllowOverride
        None</code> が設定されている状態になっています。</p>
    
        <p>そうではなく、文書をアクセスしようとしたときにエラーが発生している
        ときは、Apache のエラーログを調べてください。<code>.htaccess</code> ファイルで
        使用されたディレクティブが許可されていない、ということを知らせている
        可能性が高いです。または、構文の間違いがあることを述べているかもしれません。
        その場合にはまずそれを修正する必要があります。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/index.html.es��������������������������������������������������������0000664�0001751�0001751�00000020220�14743132254�020573� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>How-To / Tutoriales - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>How-To / Tutoriales</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">How-To / Tutoriales</a></h2>
    
        
    
        <dl>
          <dt>Autenticaci&#243;n y Autorizaci&#243;n</dt>
          <dd>
            <p>Autenticaci&#243;n es un proceso en el cual se verifica 
    		que alguien es quien afirma ser. Autorizaci&#243;n es cualquier
    		proceso en el que se permite a alguien acceder donde quiere ir,
            o a obtener la informaci&#243;n que desea tener.</p>
    
            <p>Ver: <a href="auth.html">Autenticaci&#243;n, Autorizaci&#243;n</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Control de Acceso</dt>
          <dd>
            <p>Control de acceso hace referencia al proceso de restringir, o 
    		garantizar el acceso a un recurso en base a un criterio arbitrario.
    		Esto se puede conseguir de distintas formas.</p>
    
            <p>Ver: <a href="access.html">Control de Acceso</a></p>
          </dd>
        </dl>
    
       <dl>
          <dt>Contenido Din&#225;mico con CGI</dt>
          <dd>
            <p>El CGI (Common Gateway Interface) es un m&#233;todo por el cual
    		un servidor web puede interactuar con programas externos de 
    		generaci&#243;n de contenido, a ellos nos referimos com&#250;nmente como 
    		programas CGI o scripts CGI. Es un m&#233;todo sencillo para mostrar
    		contenido din&#225;mico en tu sitio web. Este documento es una 
    		introducci&#243;n para configurar CGI en tu servidor web Apache, y de
    		inicio para escribir programas CGI.</p>
    
            <p>Ver: <a href="cgi.html">CGI: Contenido Din&#225;mico</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Ficheros <code>.htaccess</code></dt>
          <dd>
            <p>Los ficheros <code>.htaccess</code> facilitan una forma de 
    		hacer configuraciones por-directorio. Un archivo, que 
    		contiene una o m&#225;s directivas de configuraci&#243;n, se coloca en un
    		directorio espec&#237;fico y las directivas especificadas solo aplican
    		sobre ese directorio y los subdirectorios del mismo.</p>
    
            <p>Ver: <a href="htaccess.html"><code>.htaccess</code> files</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>HTTP/2 con httpd</dt>
          <dd>
          <p>HTTP/2 es la evoluci&#243;n del protocolo de capa de aplicaci&#243;n m&#225;s conocido, HTTP. 
            Se centra en hacer un uso m&#225;s eficiente de los recursos de red sin cambiar la
    		sem&#225;ntica de HTTP. Esta gu&#237;a explica como se implementa HTTP/2 en httpd,
    		mostrando buenas pr&#225;cticas y consejos de configuraci&#243;n b&#225;sica.
          </p>
    
            <p>Ver: <a href="http2.html">Gu&#237;a HTTP/2</a></p>
          </dd>
        </dl>
    
    
        <dl>
          <dt>Introducci&#243;n a los SSI</dt>
          <dd>
            <p>Los SSI (Server Side Includes) son directivas que se colocan
    		en las p&#225;ginas HTML, y son evaluadas por el servidor mientras 
    		&#233;ste las sirve. Le permiten a&#241;adir contenido generado 
    		din&#225;micamente a una p&#225;gina HTML existente, sin tener que servir
    		la p&#225;gina entera a trav&#233;s de un programa CGI u otro m&#233;todo 
    		din&#225;mico.</p>
    
            <p>Ver: <a href="ssi.html">Server Side Includes (SSI)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Directorios web Por-usuario</dt>
          <dd>
            <p>En sistemas con m&#250;ltiples usuarios, cada usuario puede tener
    		su directorio "home" compartido usando la directiva
    		<code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>. Aquellos
    		que visiten la URL <code>http://example.com/~username/</code>
    		obtendr&#225;n contenido del directorio del usuario "<code>username</code>"
    		que se encuentra en el directorio "home" del sistema.</p>
    
            <p>Ver: <a href="public_html.html">
    		Directorios Web de Usuario (<code>public_html</code>)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Gu&#237;a de Proxy Inverso</dt>
          <dd>
            <p>Apache httpd ofrece muchas posibilidades como proxy inverso. Usando la
    		directiva <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> as&#237; como
    		<code class="directive"><a href="../mod/mod_proxy.html#balancermember">BalancerMember</a></code> puede crear
    		sofisticadas configuraciones de proxy inverso que proveen de alta 
    		disponibilidad, balanceo de carga, clustering basado en la nube y 
    		reconfiguraci&#243;n din&#225;mica en caliente.</p>
    
            <p>Ver: <a href="reverse_proxy.html">Gu&#237;a de Proxy Inverso</a></p>
          </dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/public_html.html.es��������������������������������������������������0000664�0001751�0001751�00000034241�14743132254�021776� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Directorios web por usuario - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Directorios web por usuario</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    
    	<p>En sistemas con m&#250;ltiples usuarios, cada usuario puede tener un website 
        en su directorio home usando la directiva <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>. Los visitantes de una URL 
        <code>http://example.com/~username/</code> recibir&#225;n el contenido del 
        directorio home del usuario "<code>username</code>", en el subdirectorio 
        especificado por la directiva <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>.</p>
    
    	<p>Tenga en cuenta que, por defecto, el acceso a estos directorios 
        <strong>NO</strong> est&#225; activado. Puede permitir acceso cuando usa 
        <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> quitando el comentario de la l&#237;nea:</p>
    
        <pre class="prettyprint lang-config">#Include conf/extra/httpd-userdir.conf</pre>
    
    
        <p>En el fichero por defecto de configuraci&#243;n <code>conf/httpd.conf</code>, 
        y adaptando el fichero <code>httpd-userdir.conf</code> seg&#250;n sea necesario, 
        o incluyendo las directivas apropiadas en un bloque 
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> dentro del fichero 
        principal de configuraci&#243;n.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Directorios web por usuario</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#userdir">Configurando la ruta del fichero con UserDir</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#redirect">Redirigiendo a URLs externas</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#enable">Restringiendo qu&#233; usuarios pueden usar esta caracter&#237;stica</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">Activando un directorio cgi para cada usuario</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">Permitiendo a usuarios cambiar la configuraci&#243;n</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="../urlmapping.html">Mapeando URLs al sistema de ficheros</a></li><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Directorios web por usuario</a></h2>
        
        <table class="related"><tr><th>M&#243;dulos Relacionados</th><th>Directivas Relacionadas</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code></li><li><code class="directive"><a href="../mod/core.html#directorymatch">DirectoryMatch</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="userdir" id="userdir">Configurando la ruta del fichero con UserDir</a></h2>
        
    
        <p>La directiva <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
        especifica un directorio del que cargar contenido por usuario. Esta directiva 
        puede tener muchas formas distintas.</p>
    
        <p>Si se especifica una ruta que no empieza con una barra ("/"), se asume que 
          va a ser una ruta de directorio relativa al directorio home del usuario 
          especificado. Dada &#233;sta configuraci&#243;n:</p>
    
        <pre class="prettyprint lang-config">UserDir public_html</pre>
    
    
        <p>La URL <code>http://example.com/~rbowen/file.html</code> se traducir&#225; en 
        la ruta del fichero <code>/home/rbowen/public_html/file.html</code></p>
    
        <p>Si la ruta que se especifica comienza con una barra ("/"), la ruta del 
          directorio se construir&#225; usando esa ruta, m&#225;s el usuario especificado en la 
          configuraci&#243;n:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/html</pre>
    
    
        <p>La URL <code>http://example.com/~rbowen/file.html</code> se traducir&#225; en 
        la ruta del fichero <code>/var/html/rbowen/file.html</code></p>
    
        <p>Si se especifica una ruta que contiene un asterisco (*), se usar&#225; una ruta 
          en la que el asterisco se reemplaza con el nombre de usuario. Dada &#233;sta configuraci&#243;n:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/www/*/docs</pre>
    
    
        <p>La URL <code>http://example.com/~rbowen/file.html</code> se traducir&#225; en 
        la ruta del fichero <code>/var/www/rbowen/docs/file.html</code></p>
    
        <p>Tambi&#233;n se pueden configurar m&#250;ltiples directorios o rutas de directorios.</p>
    
        <pre class="prettyprint lang-config">UserDir public_html /var/html</pre>
    
    
        <p>Para la URL <code>http://example.com/~rbowen/file.html</code>,
        Apache buscar&#225; <code>~rbowen</code>. Si no lo encuentra, Apache buscar&#225;
        <code>rbowen</code> en <code>/var/html</code>. Si lo encuentra, la URL de m&#225;s 
        arriba se traducir&#225; en la ruta del fichero 
        <code>/var/html/rbowen/file.html</code></p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">Redirigiendo a URLs externas</a></h2>
        
        <p>La directiva <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> puede 
        usarse para redirigir solcitudes de directorios de usuario a URLs externas.</p>
    
        <pre class="prettyprint lang-config">UserDir http://example.org/users/*/</pre>
    
    
        <p>El ejemplo de aqu&#237; arriba redirigir&#225; una solicitud para
        <code>http://example.com/~bob/abc.html</code> hacia
        <code>http://example.org/users/bob/abc.html</code>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">Restringiendo qu&#233; usuarios pueden usar esta caracter&#237;stica</a></h2>
        
    
        <p>Usando la sintaxis que se muestra en la documentaci&#243;n de UserDir, usted 
          puede restringir a qu&#233; usuarios se les permite usar esta funcionalidad:</p>
    
        <pre class="prettyprint lang-config">UserDir disabled root jro fish</pre>
    
    
        <p>La configuraci&#243;n de aqu&#237; arriba permitir&#225; a todos los usuarios excepto a 
          los que se listan con la declaraci&#243;n <code>disabled</code>. Usted puede, 
          del mismo modo, deshabilitar esta caracter&#237;stica para todos excepto algunos 
          usuarios usando una configuraci&#243;n como la siguiente:</p>
    
        <pre class="prettyprint lang-config">UserDir disabled
    UserDir enabled rbowen krietz</pre>
    
    
        <p>Vea la documentaci&#243;n de <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> para m&#225;s 
        ejemplos.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">Activando un directorio cgi para cada usuario</a></h2>
      
    
       <p>Para dar a cada usuario su propio directorio cgi-bin, puede usar una directiva 
       	<code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
       para activar cgi en un subdirectorio en particular del directorio home del usuario.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html/cgi-bin/"&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
    
        <p>Entonces, asumiendo que <code>UserDir</code> est&#225; configurado con la 
        declaraci&#243;n <code>public_html</code>, un programa cgi <code>example.cgi</code> 
        podr&#237;a cargarse de ese directorio as&#237;:</p>
    
        <div class="example"><p><code>
        http://example.com/~rbowen/cgi-bin/example.cgi
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">Permitiendo a usuarios cambiar la configuraci&#243;n</a></h2>
        
    
        <p>Si quiere permitir que usuarios modifiquen la configuraci&#243;n del servidor en 
        	su espacio web, necesitar&#225;n usar ficheros <code>.htaccess</code> para hacer 
        	estos cambios. Aseg&#250;rese de tener configurado <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> con un valor suficiente que permita a 
        los usuarios modificar las directivas que quiera permitir. 
        Vea el <a href="htaccess.html">tutorial de .htaccess</a> para obtener detalles adicionales sobre c&#243;mo funciona.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/public_html.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/auth.html.en���������������������������������������������������������0000664�0001751�0001751�00000111445�14737241666�020445� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Authentication and Authorization - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Authentication and Authorization</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/auth.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>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.</p>
    
        <p>For general access control, see the <a href="access.html">Access
        Control How-To</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Related Modules and Directives</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#theprerequisites">The Prerequisites</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#gettingitworking">Getting it working</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#lettingmorethanonepersonin">Letting more than one
    person in</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#possibleproblems">Possible problems</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbmdbd">Alternate password storage</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multprovider">Using multiple providers</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#beyond">Beyond just authorization</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#socache">Authentication Caching</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">More information</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Related Modules and Directives</a></h2>
    
    <p>There are three types of modules involved in the authentication and
    authorization process.  You will usually need to choose at least one
    module from each group.</p>
    
    <ul>
      <li>Authentication type (see the
          <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code> directive)
        <ul>
          <li><code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code></li>
          <li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li>
        </ul>
      </li>
      <li>Authentication provider (see the
      <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> and
      <code class="directive"><a href="../mod/mod_auth_digest.html#authdigestprovider">AuthDigestProvider</a></code> directives)
    
        <ul>
          <li><code class="module"><a href="../mod/mod_authn_anon.html">mod_authn_anon</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code></li>
        </ul>
      </li>
      <li>Authorization (see the
          <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> directive)
        <ul>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbd.html">mod_authz_dbd</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_owner.html">mod_authz_owner</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_user.html">mod_authz_user</a></code></li>
        </ul>
      </li>
    </ul>
    
      <p>In addition to these modules, there are also
      <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> and
      <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>.  These modules implement core
      directives that are core to all auth modules.</p>
    
      <p>The module <code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> is both an
      authentication and authorization provider.  The module
      <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code> provides authorization
      and access control based on hostname, IP address or characteristics
      of the request, but is not part of the authentication provider
      system. For backwards compatibility with the mod_access, there is
      a new module <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code>.</p>
    
      <p>You probably also want to take a look at the <a href="access.html">Access Control</a> howto, which discusses the
      various ways to control access to your server.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
        <p>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.</p>
    
        <p>This article covers the "standard" way of protecting parts
        of your web site that most of you are going to use.</p>
    
        <div class="note"><h3>Note:</h3>
        <p>If your data really needs to be secure, consider using
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> in addition to any authentication.</p>
        </div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="theprerequisites" id="theprerequisites">The Prerequisites</a></h2>
        <p>The directives discussed in this article will need to go
        either in your main server configuration file (typically in a
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> section), or
        in per-directory configuration files (<code>.htaccess</code> files).</p>
    
        <p>If you plan to use <code>.htaccess</code> files, you will
        need to have a server configuration that permits putting
        authentication directives in these files. This is done with the
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> directive, which
        specifies which directives, if any, may be put in per-directory
        configuration files.</p>
    
        <p>Since we're talking here about authentication, you will need
        an <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> directive like the
        following:</p>
    
        <pre class="prettyprint lang-config">AllowOverride AuthConfig</pre>
    
    
        <p>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.</p>
    
        <p>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.</p>
    
        <p>You will also need to make sure that the modules
        <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> and <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>
        have either been built into the httpd binary or loaded by the
        httpd.conf configuration file. Both of these modules provide core
        directives and functionality that are critical to the configuration
        and use of authentication and authorization in the web server.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gettingitworking" id="gettingitworking">Getting it working</a></h2>
        <p>Here's the basics of password protecting a directory on your
        server.</p>
    
        <p>First, you need to create a password file. Exactly how you do
        this will vary depending on what authentication provider you have
        chosen. More on that later. To start with, we'll use a text password
        file.</p>
    
        <p>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 <code>/usr/local/apache/htdocs</code>, you
        might want to put the password file(s) in
        <code>/usr/local/apache/passwd</code>.</p>
    
        <p>To create the file, use the <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> utility that
        came with Apache. This will be located in the <code>bin</code> directory
        of wherever you installed Apache. If you have installed Apache from
        a third-party package, it may be in your execution path.</p>
    
        <p>To create the file, type:</p>
    
        <div class="example"><p><code>
          htpasswd -c /usr/local/apache/passwd/passwords rbowen
        </code></p></div>
    
        <p><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> will ask you for the password, and
        then ask you to type it again to confirm it:</p>
    
        <div class="example"><p><code>
          # htpasswd -c /usr/local/apache/passwd/passwords rbowen<br />
          New password: mypassword<br />
          Re-type new password: mypassword<br />
          Adding password for user rbowen
        </code></p></div>
    
        <p>If <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> is not in your path, of course
        you'll have to type the full path to the file to get it to run.
        With a default installation, it's located at
        <code>/usr/local/apache2/bin/htpasswd</code></p>
    
        <p>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 <code>httpd.conf</code>
        file or using an <code>.htaccess</code> file. For example, if
        you wish to protect the directory
        <code>/usr/local/apache/htdocs/secret</code>, you can use the
        following directives, either placed in the file
        <code>/usr/local/apache/htdocs/secret/.htaccess</code>, or
        placed in <code>httpd.conf</code> inside a &lt;Directory
        "/usr/local/apache/htdocs/secret"&gt; section.</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "Restricted Files"
    # (Following line optional)
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require user rbowen</pre>
    
    
        <p>Let's examine each of those directives individually. The <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code> directive selects
        the method that is used to authenticate the user. The most
        common method is <code>Basic</code>, and this is the method
        implemented by <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code>. It is important to be aware,
        however, that Basic authentication sends the password from the client to
        the server unencrypted. This method should therefore not be used for
        highly sensitive data, unless accompanied by <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.
        Apache supports one other authentication method:
        <code>AuthType Digest</code>. This method is implemented by <code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code> and was intended to be more secure. This is no
        longer the case and the connection should be encrypted with <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> instead.</p>
    
        <p>The <code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code> directive sets
        the <dfn>Realm</dfn> 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.</p>
    
        <p>So, for example, once a client has authenticated in the
        <code>"Restricted Files"</code> area, it will automatically
        retry the same password for any area on the same server that is
        marked with the <code>"Restricted Files"</code> 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.</p>
    
        <p>The <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> is,
        in this case, optional, since <code>file</code> is the default value
        for this directive. You'll need to use this directive if you are
        choosing a different source for authentication, such as
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> or <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>.</p>
    
        <p>The <code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code>
        directive sets the path to the password file that we just
        created with <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>. 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 <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> module provides the <code class="directive"><a href="../mod/mod_authn_dbm.html#authdbmuserfile">AuthDBMUserFile</a></code> directive. These
        files can be created and manipulated with the <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> and <code class="program"><a href="../programs/htdbm.html">htdbm</a></code> programs. Many
        other types of authentication options are available from third
        party modules.</p>
    
        <p>Finally, the <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
        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
        <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> directive.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="lettingmorethanonepersonin" id="lettingmorethanonepersonin">Letting more than one
    person in</a></h2>
        <p>The directives above only let one person (specifically
        someone with a username of <code>rbowen</code>) into the
        directory. In most cases, you'll want to let more than one
        person in. This is where the <code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code> comes in.</p>
    
        <p>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:</p>
    
       <div class="example"><p><code>
         GroupName: rbowen dpitts sungo rshersey
       </code></p></div>
    
        <p>That's just a list of the members of the group in a long
        line separated by spaces.</p>
    
        <p>To add a user to your already existing password file,
        type:</p>
    
        <div class="example"><p><code>
          htpasswd /usr/local/apache/passwd/passwords dpitts
        </code></p></div>
    
        <p>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 <code>-c</code> that makes it create a new password
        file).</p>
    
        <p>Now, you need to modify your <code>.htaccess</code> file or
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> block
        to look like the following:</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "By Invitation Only"
    # Optional line:
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    AuthGroupFile "/usr/local/apache/passwd/groups"
    Require group GroupName</pre>
    
    
        <p>Now, anyone that is listed in the group <code>GroupName</code>,
        and has an entry in the <code>password</code> file, will be let in, if
        they type the correct password.</p>
    
        <p>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:</p>
    
        <pre class="prettyprint lang-config">Require valid-user</pre>
    
    
        <p>Using that rather than the <code>Require user rbowen</code>
        line will allow anyone in that is listed in the password file,
        and who correctly enters their password.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="possibleproblems" id="possibleproblems">Possible problems</a></h2>
        <p>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.</p>
    
        <p>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.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbmdbd" id="dbmdbd">Alternate password storage</a></h2>
    
        <p>Because storing passwords in plain text files has the above
        problems, you may wish to store your passwords somewhere else, such
        as in a database.</p>
    
        <p><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> and <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code> are two
        modules which make this possible. Rather than selecting <code><code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> file</code>, instead
        you can choose <code>dbm</code> or <code>dbd</code> as your storage
        format.</p>
    
        <p>To select a dbm file rather than a text file, for example:</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider dbm
        AuthDBMUserFile "/www/passwords/passwd.dbm"
        Require valid-user
    &lt;/Directory&gt;</pre>
    
    
        <p>Other options are available. Consult the
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> documentation for more details.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multprovider" id="multprovider">Using multiple providers</a></h2>
    
        <p>With the introduction of the new provider based authentication and
        authorization architecture, you are no longer locked into a single
        authentication or authorization method. In fact any number of the
        providers can be mixed and matched to provide you with exactly the
        scheme that meets your needs. In the following example, both the
        file and LDAP based authentication providers are being used.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file ldap
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        Require valid-user
    &lt;/Directory&gt;</pre>
    
    
        <p>In this example the file provider will attempt to authenticate
        the user first. If it is unable to authenticate the user, the LDAP
        provider will be called. This allows the scope of authentication
        to be broadened if your organization implements more than
        one type of authentication store. Other authentication and authorization
        scenarios may include mixing one type of authentication with a
        different type of authorization. For example, authenticating against
        a password file yet authorizing against an LDAP directory.</p>
    
        <p>Just as multiple authentication providers can be implemented, multiple
        authorization methods can also be used. In this example both file group
        authorization as well as LDAP group authorization is being used.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        AuthGroupFile "/usr/local/apache/passwd/groups"
        Require group GroupName
        Require ldap-group cn=mygroup,o=yourorg
    &lt;/Directory&gt;</pre>
    
    
        <p>To take authorization a little further, authorization container
        directives such as
        <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
        and
        <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>
        allow logic to be applied so that the order in which authorization
        is handled can be completely controlled through the configuration.
        See <a href="../mod/mod_authz_core.html#logic">Authorization
        Containers</a> for an example of how they may be applied.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="beyond" id="beyond">Beyond just authorization</a></h2>
    
        <p>The way that authorization can be applied is now much more flexible
        than just a single check against a single data store. Ordering, logic
        and choosing how authorization will be done is now possible.</p>
    
        <h3><a name="authandororder" id="authandororder">Applying logic and ordering</a></h3>
            <p>Controlling how and in what order authorization will be applied
            has been a bit of a mystery in the past. In Apache 2.2 a provider-based
            authentication mechanism was introduced to decouple the actual
            authentication process from authorization and supporting functionality.
            One of the side benefits was that authentication providers could be
            configured and called in a specific order which didn't depend on the
            load order of the auth module itself. This same provider based mechanism
            has been brought forward into authorization as well. What this means is
            that the <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> directive
            not only specifies which authorization methods should be used, it also
            specifies the order in which they are called. Multiple authorization
            methods are called in the same order in which the
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> directives
            appear in the configuration.</p>
    
            <p>With the introduction of authorization container directives
            such as
            <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
            and
            <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>,
            the configuration also has control over when the
            authorization methods are called and what criteria determines when
            access is granted.  See
            <a href="../mod/mod_authz_core.html#logic">Authorization Containers</a>
            for an example of how they may be used to express complex
            authorization logic.</p>
    
            <p>By default all
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
            directives are handled as though contained within a
            <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>
            container directive.  In other words, if
            any of the specified authorization methods succeed, then authorization
            is granted.</p>
    
        
    
        <h3><a name="reqaccessctrl" id="reqaccessctrl">Using authorization providers for access control</a></h3>
            <p>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.</p>
    
            <p>The authorization providers <code>all</code>,
            <code>env</code>, <code>host</code> and <code>ip</code> let you
            allow or deny access based on other host based criteria such as
            host name or ip address of the machine requesting a
            document.</p>
    
            <p>The usage of these providers is specified through the
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> directive.
            This directive registers the authorization providers
            that will be called during the authorization stage of the request
            processing. For example:</p>
    
            <pre class="prettyprint lang-config">Require ip <var>address</var>
            </pre>
    
    
            <p>where <var>address</var> is an IP address (or a partial IP
            address) or:</p>
    
            <pre class="prettyprint lang-config">Require host <var>domain_name</var>
            </pre>
    
    
            <p>where <var>domain_name</var> is a fully qualified domain name
            (or a partial domain name); you may provide multiple addresses or
            domain names, if desired.</p>
    
            <p>For example, if you have someone spamming your message
            board, and you want to keep them out, you could do the
            following:</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 10.252.46.165
    &lt;/RequireAll&gt;</pre>
    
    
            <p>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.</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not host host.example.com
    &lt;/RequireAll&gt;</pre>
    
    
            <p>And, if you'd like to block access from an entire domain,
            you can specify just part of an address or domain name:</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 192.168.205
        Require not host phishers.example.com moreidiots.example
        Require not host ke
    &lt;/RequireAll&gt;</pre>
    
    
            <p>Using <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>
            with multiple <code class="directive"><a href="../mod/mod_authz_core.html#require">&lt;Require&gt;</a></code> directives, each negated with <code>not</code>,
            will only allow access, if all of negated conditions are true. In other words,
            access will be blocked, if any of the negated conditions fails.</p>
    
        
    
        <h3><a name="filesystem" id="filesystem">Access Control backwards compatibility</a></h3>
            <p>One of the side effects of adopting a provider based mechanism for
            authentication is that the previous access control directives
            <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>,
            <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>,
            <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> and
            <code class="directive"><a href="../mod/mod_access_compat.html#satisfy">Satisfy</a></code> are no longer needed.
            However to provide backwards compatibility for older configurations, these
            directives have been moved to the <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> module.</p>
    
            <div class="warning"><h3>Note</h3>
            <p>The directives provided by <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> have
            been deprecated by <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>.
            Mixing old directives like <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code> or <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> with new ones like
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> is technically possible
            but discouraged. The <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> module was created to support
            configurations containing only old directives to facilitate the 2.4 upgrade.
            Please check the <a href="../upgrading.html">upgrading</a> guide for more
            information.
            </p>
            </div>
        
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="socache" id="socache">Authentication Caching</a></h2>
        <p>There may be times when authentication puts an unacceptable load
        on a provider or on your network.  This is most likely to affect users
        of <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code> (or third-party/custom providers).
        To deal with this, HTTPD 2.3/2.4 introduces a new caching provider
        <code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code> to cache credentials and reduce
        the load on the origin provider(s).</p>
        <p>This may offer a substantial performance boost to some users.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">More information</a></h2>
        <p>You should also read the documentation for
        <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> and <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>
        which contain some more information about how this all works.  The
        directive <code class="directive"><a href="../mod/mod_authn_core.html#authnprovideralias">&lt;AuthnProviderAlias&gt;</a></code> can also help
        in simplifying certain authentication configurations.</p>
    
        <p>The various ciphers supported by Apache for authentication data are
        explained in <a href="../misc/password_encryptions.html">Password
        Encryptions</a>.</p>
    
        <p>And you may want to look at the <a href="access.html">Access
        Control</a> howto, which discusses a number of related topics.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/auth.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/auth.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/index.html.en��������������������������������������������������������0000664�0001751�0001751�00000020662�14737241666�020613� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>How-To / Tutorials - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>How-To / Tutorials</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">How-To / Tutorials</a></h2>
    
        
    
        <dl>
          <dt>Authentication and Authorization</dt>
          <dd>
            <p>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.</p>
    
            <p>See: <a href="auth.html">Authentication, Authorization</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Access Control</dt>
          <dd>
            <p>Access control refers to the process of restricting, or
            granting access to a resource based on arbitrary criteria. There
            are a variety of different ways that this can be
            accomplished.</p>
    
            <p>See: <a href="access.html">Access Control</a></p>
          </dd>
        </dl>
    
       <dl>
          <dt>Dynamic Content with CGI</dt>
          <dd>
            <p>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 a simple 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.</p>
    
            <p>See: <a href="cgi.html">CGI: Dynamic Content</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt><code>.htaccess</code> files</dt>
          <dd>
            <p><code>.htaccess</code> 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.</p>
    
            <p>See: <a href="htaccess.html"><code>.htaccess</code> files</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>HTTP/2 with httpd</dt>
          <dd>
          <p>HTTP/2 is the evolution of the world's most successful application layer protocol, HTTP. 
            It focuses on making more efficient use of network resources without changing the semantics of HTTP.
            This guide explains how HTTP/2 is implemented in httpd, showing basic configurations tips and 
            best practices.
          </p>
    
            <p>See: <a href="http2.html">HTTP/2 guide</a></p>
          </dd>
        </dl>
    
    
        <dl>
          <dt>Introduction to Server Side Includes</dt>
          <dd>
            <p>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.</p>
    
            <p>See: <a href="ssi.html">Server Side Includes (SSI)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Per-user web directories</dt>
          <dd>
            <p>On systems with multiple users, each user can be permitted to have a
            web site in their home directory using the <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> directive. Visitors
            to a URL <code>http://example.com/~username/</code> will get content
            out of the home directory of the user "<code>username</code>", out of
            the subdirectory specified by the <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> directive.</p>
    
            <p>See: <a href="public_html.html">User web directories (<code>public_html</code>)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Reverse Proxy guide</dt>
          <dd>
            <p>Apache httpd has extensive capabilities as a reverse proxy server using the
            <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> directive as well as
            <code class="directive"><a href="../mod/mod_proxy.html#balancermember">BalancerMember</a></code> to create sophisticated
            reverse proxying implementations which provide for high-availability, load
            balancing and failover, cloud-based clustering and dynamic on-the-fly reconfiguration.</p>
    
            <p>See: <a href="reverse_proxy.html">Reverse proxy guide</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Rewriting URLs with mod_rewrite</dt>
          <dd>
            <p>Rewriting URLs with (and without)
            <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> tends to be one of the most
            frequently asked topics on our mailing lists and IRC channels.
            We have devoted <a href="../rewrite/">and entire section of our
            documentation</a> to howtos and recipes around this topic.</p>
          </dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/auth.html.tr.utf8����������������������������������������������������0000664�0001751�0001751�00000114550�14743132254�021342� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Kimlik Doğrulama ve Yetkilendirme - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Nasıllar ve Öğreticiler</a></div><div id="page-content"><div id="preamble"><h1>Kimlik Doğrulama ve Yetkilendirme</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Kimlik Doğrulama istediğiniz kişileri teyid etme işlemidir.
          Yetkilendirme ise kişilerin nereye gireceklerine ve hangi bilgiye
          ulaşacaklarına müsaade edilmesi işlemidir.</p>
    
        <p>Genel erişim denetimi için <a href="access.html">Erişim Denetimi
          Nasıl</a> belgesine bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">İlgili modüller ve Yönergeler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#introduction">Giriş</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#theprerequisites">Ön gereksinimler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#gettingitworking">Çalışmaya Başlama</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#lettingmorethanonepersonin">Birden çok kişiye izin vermek</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#possibleproblems">Olası Sorunlar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbmdbd">Diğer parola depolama yöntemleri</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multprovider">Birden çok tedarikçi kullanmak</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#beyond">Yetkilendirmenin biraz ötesi</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#socache">Kimlik Doğrulama Arabelleği</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">Daha fazla bilgi</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">İlgili modüller ve Yönergeler</a></h2>
    
        <p>Kimlik Doğrulama ve yetkilendirme işlemi ile ilgili üç tür modül
        vardır. Genellikle her bir gruptan en az bir modül seçeceksiniz.</p>
    
        <ul>
          <li>Kimlik Doğrulama türü (bkz. <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code> yönergesi)
            <ul>
              <li><code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code></li>
              <li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li>
            </ul>
          </li>
    
          <li>Kimlik Doğrulayıcı (bkz.
          <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code>
          ve <code class="directive"><a href="../mod/mod_auth_digest.html#authdigestprovider">AuthDigestProvider</a></code> yönergeleri)
            <ul>
              <li><code class="module"><a href="../mod/mod_authn_anon.html">mod_authn_anon</a></code></li>
              <li><code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code></li>
              <li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li>
              <li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li>
              <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
              <li><code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code></li>
            </ul>
          </li>
          <li>Yetkilendirme (bkz.
              <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> yönergesi)
            <ul>
              <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
              <li><code class="module"><a href="../mod/mod_authz_dbd.html">mod_authz_dbd</a></code></li>
              <li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li>
              <li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li>
              <li><code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code></li>
              <li><code class="module"><a href="../mod/mod_authz_owner.html">mod_authz_owner</a></code></li>
              <li><code class="module"><a href="../mod/mod_authz_user.html">mod_authz_user</a></code></li>
            </ul>
          </li>
        </ul>
    
        <p>Bu modüllere ek olarak, <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> ve
        <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> modülleri bulunur. Bu modüller
        yetkilendirme modüllerinin çekirdeğini oluşturan temel yönergeleri
        gerçekler.</p>
    
        <p><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> modülü kimlik doğrulama ve
        yetkilendirme işlemlerinin ikisini birden gerçekleştirir.
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code> modülü bu işlemleri sunucu adına, IP
        adresine ve isteğin karekteristiğine bağlı olarak gerçekleştirir.
        Ancak kimlik doğrulama sisteminin bir parçası değildir.
        <code>mod_access</code> ile geriye uyumluluk için
        <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> diye bir modül daha vardır.</p>
    
        <p>Muhtemelen göz atmak isteyeceğiniz <a href="access.html">Erişim
        Denetimi</a> nasıl belgesi, sunucuya erişimlerin çeşitli yollarından
        bahsetmektedir.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Giriş</a></h2>
        <p>Sitenizde sadece küçük bir grup insana hitap eden ya da hassas
        bilgileriniz varsa, bu makaledeki teknikleri kullanarak dilediğiniz
        kişilerin sadece dilediğiniz sayfaları görüntülemesini
        sağlayabilirsiniz.</p>
    
        <p>Bu makale sitenizin bazı parçalarını korumak için kullanacağınız
        "standart" yolları içermektedir.</p>
    
        <div class="note"><h3>Bilginize:</h3>
          <p>Eğer bilgileriniz gerçekten gizliliğe ihtiyaç duyuyorsa kimlik
          doğrulamasına ilaveten <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> modülünü de
          kullanabilirsiniz.</p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="theprerequisites" id="theprerequisites">Ön gereksinimler</a></h2>
        
        <p>Bu makalede bahsi geçen yönergeler ya ana sunucu yapılandırma
        dosyasında (genellikle <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> bölümünde) ya da dizin içi
        yapılandırma dosyalarında (<code>.htaccess</code> dosyaları)
        bulunmak zorundadır.</p>
    
        <p>Eğer <code>.htaccess</code> dosyalarını kullanmayı
        tasarlıyorsanız, kimlik doğrulama yönergelerine bu dosyaların içine
        koymaya izin veren sunucu yapılandırmasına ihtiyacınız olacaktır.
        Bunun için, dizin içi yapılandırma dosyalarının içine hangi
        yönergelerin konacağını belirleyen <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> yönergesi kullanılır.</p>
    
        <p>Kimlik doğrulamadan sözettiğimize göre, aşağıda gösterilen
        şekilde bir <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> yönergesine ihtiyacınız olacaktır:</p>
    
        <pre class="prettyprint lang-config">AllowOverride AuthConfig</pre>
    
    
        <p>Yönergeleri doğrudan ana sunucunun yapılandırma dosyasına
        koyacaksanız bu dosyaya yazma izniniz olmalıdır.</p>
    
        <p>Bazı dosyaların nerede saklandığını bilmek için sunucunun dizin
        yapısı hakkında biraz bilgi sahibi olmanız gerekmektedir. Bu çok da
        zor olmamakla birlikte bu noktaya gelindiğinde konuyu
        netleştireceğiz.</p>
    
        <p>Ayrıca <code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> ve
        <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> modülleri ya <code>httpd</code>
        çalıştırılabilirinin içinde derlenmiş olmalı ya da
        <code>httpd.conf</code> yapılandırma dosyası ile yüklenmelidir. Bu
        iki modül HTTP sunucusunda kimlik doğrulama ve yetkilendirme
        kullanımı ve yapılandırması için büyük öneme sahip temel yönergeleri
        ve işlevselliği sağlar.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gettingitworking" id="gettingitworking">Çalışmaya Başlama</a></h2>
        <p>Burada, sunucu üzerindeki bir dizini parolayla korumak için
        gereken temel bilgiler verilecektir.</p>
    
        <p>İlk olarak bir parola dosyası oluşturmalısınız. Bunu nasıl
        yapacağınız, özellikle, seçtiğiniz kimlik doğrulayıcıya göre
        değişiklik gösterir. Bunun üzerinde ileride daha fazla duracağız.
        Başlangıç için parolaları bir metin dosyasında tutacağız.</p>
    
        <p>Bu dosya belge kök dizini altında olmamalıdır. Böylece başkaları
        parola dosyasını indiremezler. Örneğin belgeleriniz
        <code>/usr/local/apache/htdocs</code> üzerinden sunuluyorsa parola
        dosyanızı <code>/usr/local/apache/passwd</code> dizininde
        tutabilirsiniz.</p>
    
        <p>Dosyayı oluşturmak için Apache ile gelen
        <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> uygulamasını kullanacağız. Bu uygulama
        Apache'nin kurulumunda belirtilen  <code>bin</code> dizininde
        bulunur. Eğer Apache'yi üçüncü parti paketlerden  kurduysanız,
        çalıştırılabilir dosyaların bulunduğu yollar üzerinde olmalıdır.</p>
    
        <p>Bir dosya oluşturmak için şunları yazın:</p>
    
        <div class="example"><p><code>
          htpasswd -c /usr/local/apache/passwd/passwords umut
        </code></p></div>
    
        <p><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> size parola soracaktır arkasından da
        teyit etmek için parolayı tekrar girmenizi isteyecektir:</p>
    
        <div class="example"><p><code>
          # htpasswd -c /usr/local/apache/passwd/passwords umut<br />
          New password: parolam<br />
          Re-type new password: parolam<br />
          Adding password for user umut
        </code></p></div>
    
        <p>Eğer <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> normal yollar üzerinde değilse
        çalıştırmak için dosyanın bulunduğu tam yeri belirtmeniz
        gerekecektir. Dosyanın öntanımlı kurulum yeri:
        <code>/usr/local/apache2/bin/htpasswd</code></p>
    
        <p>Bundan sonra, sunucuyu, parola sorması için ve kimlerin erişim
        izni olacağını belirlemek için yapılandıracaksınız. Bu işlemi
        <code>httpd.conf</code>dosyasını düzenleyerek ya da bir
        <code>.htaccess</code> dosyası kullanarak yapabilirsiniz. Örneğin,
        <code>/usr/local/apache/htdocs/secret</code> dizinini korumayı
        amaçlıyorsanız, şu yönergeleri kullanabilirsiniz. Bu yönergeleri
        <code>/usr/local/apache/htdocs/secret/.htaccess</code> dosyası içine
        veya <code>httpd.conf</code> içindeki &lt;Directory
        "/usr/local/apache/htdocs/secret"&gt; bölümüne koyabilirsiniz.</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "Gizli Dosyalar"
    # (Aşağıdaki satırın kullanımı isteğe bağlıdır)
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require user umut</pre>
    
    
        <p>Bu yönergeleri tek tek inceleyelim.
        <code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code> yönergesi
        kullanıcının kimliğini doğrulamakta kullanılacak yöntemi seçer. En
        çok kullanılan yöntem <code>Basic</code>'tir ve bu yöntem
        <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> modülüyle gerçeklenmiştir. Temel
        (<code>Basic</code>) kimlik doğrulamasıyla gönderilen parolanın
        şifrelenmeyeceğini unutmayın. Bu yöntem, bu sebepten dolayı
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> eşliğinde kullanılmadığı sürece yüksek
        hassasiyete sahip bilgiler için kullanılmamalıdır. Apache bir başka
        kimlik doğrulama yöntemini daha destekler: <code>AuthType
        Digest</code>. Bu yöntem <code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code> tarafından
        gerçeklenmişti ve çok daha güvenli olacağı düşünülmüştü. Bu artık
        geçerliliğini yitirdiğinden bağlantının bundan böyle
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> ile şifrelenmesi gerekmektedir.</p>
    
        <p><code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code> yönergesi
        ile kimlik doğrulamada kullanılacak <dfn>Saha</dfn> da
        belirtilebilir. Saha kullanımının, başlıca iki işlevi vardır.
        Birincisi, istemci sıklıkla bu bilgiyi kullanıcıya parola diyalog
        kutusunun bir parçası olarak sunar. İkincisi, belirtilen kimlik
        doğrulamalı alan için gönderilecek parolayı belirlerken istemci
        tarafından kullanılır.</p>
    
        <p>Örneğin, bir istemcinin <code>"Gizli Dosyalar"</code> alanında
        kimliği doğrulanmış olsun. Aynı sunucu üzerinde <code>"Gizli
        Dosyalar"</code> Sahası olarak belirlenmiş alanlarda aynı parola
        özdevinimli olarak yinelenecektir. Böylece parola bir kere girilerek
        aynı Sahayı paylaşan çok sayıda kısıtlanmış alana ulaşırken oluşacak
        gecikmeden kullanıcı korunmuş olur. Güvenlik gerekçelerinden dolayı,
        her sunucu adı değiştirilişinde istemcinin parolayı yeniden sorması
        gerekir.</p>
    
        <p><code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code>
        yönergesinin öntanımlı değeri <code>file</code> olduğundan, bu
        durumda, bu yönergenin kullanımı isteğe bağlıdır. Ancak, eğer kimlik
        doğrulaması için  <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> ya da
        <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code> gibi farklı bir kaynak seçecekseniz
        bu yönergeyi kullanmanız gerekecektir.</p>
    
        <p><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code>
        yönergesi <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> ile oluşturduğumuz parola
        dosyasının yerini belirtmek için kullanılır. Eğer çok sayıda
        kullanıcınız varsa her bir kullanıcıyı her kimlik doğrulama isteği
        için kimlik bilgilerini bir metin dosyasında aramak gayet yavaş
        olacaktır. Apache, kullanıcı bilgilerini hızlı bir veritabanı
        dosyasında depolama özelliğine de sahiptir. Bu amaçla,
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> modülünün
        <code class="directive"><a href="../mod/mod_authn_dbm.html#authdbmuserfile">AuthDBMUserFile</a></code>
        yönergesi kullanılabilir. Bu dosyalar <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> ve
        <code class="program"><a href="../programs/htdbm.html">htdbm</a></code> programı ile oluşturulabilir ve değiştirilebilir.
        Üçüncü parti modüllerinde çok sayıda
        başka kimlik doğrulama türü de vardır.</p>
    
        <p>Son olarak <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
        yönergesi, sunucunun bu bölgesine erişimine izin verilen
        kullanıcıları ayarlama işleminin kimlik doğrulamasıyla ilgili
        kısmını sağlar. Bir sonraki bölümde <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> yönergesini kullanmanın
        çeşitli yoları üzerinde duracağız.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="lettingmorethanonepersonin" id="lettingmorethanonepersonin">Birden çok kişiye izin vermek</a></h2>
        
        <p>Yukarıdaki yönergelerle bir dizinde sadece bir kişiye
        (<code>umut</code> adlı kullanıcıya) izin verir. Çoğunlukla birden
        çok kişiye izin verilmesi istenir. Bu durumda <code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code> yönergesi
        devreye girer.</p>
    
        <p>Eğer birden çok kişiye izin vermek istiyorsanız içinde kullanıcı
        isimlerinin olduğu bir grup dosyası oluşturmalısınız. Bu dosyanın
        biçemi gayet basittir ve bunu herhangi bir metin düzenleyici ile
        oluşturabilirsiniz. Bu dosyanın içeriği aşağıdaki gibi
        görünecektir:</p>
    
        <div class="example"><p><code>
         GroupName: umut samet engin kubilay
        </code></p></div>
    
        <p>Dosya, sadece, boşluklarla birbirinden ayrılmış gurup üyelerinin
        isimlerinden oluşan uzun bir liste içerir.</p>
    
        <p>Varolan parola dosyasına bir kullanıcı eklemek için şunu
        yazın:</p>
    
        <div class="example"><p><code>
          htpasswd /usr/local/apache/passwd/passwords birey
        </code></p></div>
    
        <p>Evvelce almış olduğunuz yanıtı yine alacaksınız ama bu sefer yeni
        bir dosya oluşturulmak yerine var olan bir dosyaya eklenecektir.
        (Yeni bir parola dosyası oluşturmak için <code>-c</code> seçeneği
        kullanılır).</p>
    
        <p>Şimdi, <code>.htaccess</code> dosyanızı veya
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> bölümünüzü
        aşağıda görüldüğü şekilde değiştirebilirsiniz:</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "Davete Binaen"
    # Satır isteğe bağlıdır:
    AuthBasicProvider file
    AuthUserFile "/usr/local/apache/passwd/passwords"
    AuthGroupFile "/usr/local/apache/passwd/groups"
    Require group Grupismi</pre>
    
    
        <p>Artık, <code>Grupismi</code> gurubunda listelenmiş ve
        <code>password</code> dosyasında kaydı olan kişiye, parolayı doğru
        yazdığı takdirde izin verilecektir.</p>
    
        <p>Çoklu kullanıcıya izin veren biraz daha az kullanılan başka bir
        yol daha mevcuttur. Bir gurup dosyası oluşturmaktansa, şu yönergeyi
        kullanabilirsiniz:</p>
    
        <pre class="prettyprint lang-config">Require valid-user</pre>
    
    
        <p><code>Require user umut</code> satırı ile parola dosyasında
        listelenmiş ve parolayı doğru olarak giren herhangi bir kişiye izin
        vermektense, her grup için ayrı bir parola dosyası tutarak grup
        davranışını taklit edebilirsiniz.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="possibleproblems" id="possibleproblems">Olası Sorunlar</a></h2>
        <p>Temel kimlik doğrulama yolu belirtildiği için, sunucuya
        yaptığınız her belge istediğinde kullanıcı adınızın ve parolanızın
        doğrulanması gerekir. Hatta aynı sayfayı yeniden yüklerken ya da
        sayfadaki her bir resim için bu yapılmalıdır (şayet korunmakta olan
        bir dizinden geliyorsa). Bu işlem hızı azaltacaktır. Yavaşlama
        miktarı parola dosyanızın büyüklüğü ile orantılı olacaktır, çünkü bu
        işlem sırasında dosya açılacak ve kullanıcıların arasında isminiz
        bulunana kadar liste aşağı doğru taranacaktır. Bu işlem sayfa her
        yüklenişinde tekrar edilecektir.</p>
    
        <p>Buradan çıkacak sonuç, bir parola dosyasına konulan kullanıcı
        sayısında bir üst sınır olması gerekliliğidir. Bu sınır sunucunuzun
        başarımına bağlı olarak değişiklik gösterir. Bir kaç yüz kayıtın
        üstünde giriş yaptığınızda hız düşüşünü gözlemlebilirsiniz İşte bu
        anda kimlik doğrulama için başka bir yöntem aramaya başlarsınız.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbmdbd" id="dbmdbd">Diğer parola depolama yöntemleri</a></h2>
        
        <p>Parolaları basit bir metin dosyasında depolamak yukarıda
        bahsedilen sorunlara yol açtığından parolaları başka bir yerde
        depolamayı düşünebilirsiniz; örneğin bir veritabanında.</p>
    
        <p><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> ve <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>
        modülleri bunu mümkün kılan iki modüldür. Depolama yönemi olarak
        <code><code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code> file</code> yerine, <code>dbm</code>
        veya <code>dbd</code> kullanabilirsiniz.</p>
    
        <p>Bir metin dosyası yerine bir dbm dosyası kullanım örneği:</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider dbm
        AuthDBMUserFile "/www/passwords/passwd.dbm"
        Require valid-user
    &lt;/Directory&gt;</pre>
    
    
        <p>Başka seçenekler de mümkündür. Ayrınılar için
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> belgesine başvurun.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multprovider" id="multprovider">Birden çok tedarikçi kullanmak</a></h2>
        
        <p>Kimlik doğrulama ve yetkilendirme mimarisine dayalı yeni
        tedarikçiyi kullanarak tek bir yetkilendirme ya da kimlik doğrulama
        yöntemine kilitlenip kalmayacaksınız. Aslında birden çok tedarikçi
        ihtiyacınıza cevap vermek için bir arada kullanılabilir. Aşağıdaki
        örnekte dosya ve LDAP tabanlı kimlik doğrulama tedarikçileri bir
        arada kullanılmıştır.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file ldap
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        Require valid-user
    &lt;/Directory&gt;</pre>
    
    
        <p>Bu örnekte dosya tedarikçisi, ilk olarak kullanıcının kimliğini
        doğrulamaya teşebbüs edecektir. Kullanıcının kimliği
        doğrulanamıyorsa LDAP tedarikçisi çağırılır. Eğer kurumunuz birden
        çok kimlik doğrulama tedarikçisini yürürlüğe koyuyorsa bu, kimlik
        doğrulama faaliyet alanının genişletilmesini sağlar. Diğer kimlik
        kanıtlama ve yetkilendirme senaryoları tek bir kimlik doğrulaması
        ile birden fazla yetkilendirme türüne izin verebilir.</p>
    
        <p>Çok sayıda kimlik doğrulama tedarikçisi uygulamaya konulabileceği
        gibi, çok sayıda yetkilendirme yöntemi de kullanılabilir. Bu örnekte
        dosya için hem dosyalı hem de LDAP grup kimlik doğrulaması
        kullanılmıştır.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/docs/private"&gt;
        AuthName "Private"
        AuthType Basic
        AuthBasicProvider file
        AuthUserFile "/usr/local/apache/passwd/passwords"
        AuthLDAPURL ldap://ldaphost/o=yourorg
        AuthGroupFile "/usr/local/apache/passwd/groups"
        Require group GroupName
        Require ldap-group cn=mygroup,o=yourorg
    &lt;/Directory&gt;</pre>
    
    
        <p>Kimlik doğrulama konusunu biraz daha genişletirsek, <code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code> ve
        <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code> gibi yetkilendirme taşıyıcısı
        yönergelerle hangi iznin hangi sırayla uygulanacağını
        belirlenebilir. <a href="../mod/mod_authz_core.html#logic">Yetkilendirme Taşıyıcıları</a> bölümünde bunun bir uygulama
        örneğini görebilirsiniz.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="beyond" id="beyond">Yetkilendirmenin biraz ötesi</a></h2>
        <p>Tek bir veri deposundan yapılacak tek bir sınamadan çok daha
        esnek kimlik doğrulaması yapılabilir. Sıralama, mantık ve hangi
        kimlik doğrulamasının kullanılacağını seçmek mümkündür.</p>
    
        <h3><a name="authandororder" id="authandororder">Mantık ve sıralamanın uygulanması</a></h3>
          
          <p>Yetkilendirmenin hangi sırayla uygulanacağı ve nasıl
          denetleneceği geçmişte biraz gizemli bir konuydu. Apache 2.2'de,
          tedarikçi tabanlı kimlik doğrulamasının devreye girmesiyle asıl
          kimlik doğrulama işlemini yetkilendirme ve destek işlevselliğinden
          ayırmak mümkün oldu. Bunun faydalarından birisi de kimlik
          doğrulama tedarikçilerinin yapılandırılabilmesi ve auth modülünün
          kendi yükleme sırasından bağımsız olarak özel bir sırayla
          çağrılabilmesidir. Bu tedarikçi tabanlı mekanizmanın aynısı
          yetkilendirmeye de getirilmiştir. Bunun anlamı <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> yönergesinde hangi
          izin yönteminin kullanılması gerektiğinin belirtmesinin yanında
          hangi sırayla çağırılacaklarının da belirlenebildiğidir. Çok
          sayıda yetkilendirme yöntemi kullanıldığında, bunlar, <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> yönergelerinin
          yapılandırma dosyasında göründükleri sıra ile çağırılır.</p>
    
          <p><code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code> ve <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code> gibi yetkilendirme
          taşıyıcısı yönergelerin devreye girmesiyle yetkilendirme
          yöntemlerinin ne zaman çağırılacağı ve çağırıldığında ve erişime
          izin verirken hangi kuralların uygulanacağı konusunda denetim
          yapılandırmanın eline geçmektedir. Karmaşık yetkilendime mantığını
          ifade etmek için kullanılan bir örneği görmek için
          <a href="../mod/mod_authz_core.html#logic">Yetkilendirme
          Taşıyıcıları</a> bölümüne bakınız.</p>
    
          <p>Öntanımlı olarak tüm <code class="directive"><a href="../mod/mod_authz_core.html#require">
          Require</a></code> yönergeleri, <code class="directive"><a href="../mod/mod_authz_core.html#requireany">&lt;RequireAny&gt;</a></code>
          taşıyıcı yönergesinin içine konur. Başka bir deyişle eğer
          belirtilen kimlik doğrulama yöntemlerinden herhangi biri başarılı
          olursa yetkilendirme de sağlanmış olur.</p>
    
        
    
        <h3><a name="reqaccessctrl" id="reqaccessctrl">Erişim denetimi için yetkilendirme tedarikçilerinin
          kullanımı</a></h3>
          
          <p>Kullanıcı adı ve parolasına göre kimlik doğrulama hikayenin
          sadece bir bölümüdür. Sıklıkla insanlara kim olduklarına göre
          değil birşeylere dayanarak izin vermek istersiniz. Örneğin nereden
          geldikleri gibi.</p>
    
          <p><code>all</code>, <code>env</code>, <code>host</code> ve
          <code>ip</code> gibi yetkilendirme tedarikçileri ile, bir belgenin
          istendiği makinenin IP adresi veya konak ismi gibi bazı özelliklerine
          dayalı olarak erişime izin verip vermeyeceğinizi belirtebilirsiniz.</p>
    
          <p>Bu tedarikçilerin kullanımı <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> yönergesinde açıklanmıştır. Bu yönergeler,
          isteklerin işlenmesi sırasında yetkilendirme aşamasında
          çağırılacak yetkilendirme tedarikçilerini kayda geçirir. Örneğin:
          </p>
    
          <pre class="prettyprint lang-config">Require ip <var>adres</var>
          </pre>
    
    
          <p>Burada, <var>adres</var> bir IP adresidir (veya kısmi bir IP
            addresidir)</p>
    
          <pre class="prettyprint lang-config">Require host <var>alan_adı</var>
          </pre>
    
    
          <p>Burada, <var>alan_adı</var> bir tam nitelikli alan adıdır
          (ya da kısmi alan adıdır); gerekirse çok sayıda alan adı veya IP
          adresi de belirtilebilir.</p>
    
          <p>Örneğin, yorum alanını gereksiz iletilerle dolduran birini uzak
          tutmak istediğinizi varsayalım. Bu kişiyi uzak tutmak için şunları
          yapabilirsiniz:</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 10.252.46.165
    &lt;/RequireAll&gt;</pre>
    
    
          <p>Bu adresden gelen ziyaretçiler bu yönergedeki içeriği
          göremeyeceklerdir. Bunun yerine, elinizde IP adresi değil de
          makine adı varsa şunu kullanabilirsiniz:</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not host host.example.com
    &lt;/RequireAll&gt;</pre>
    
    
          <p>Eğer alan adının tamanıdan gelecek olan bütün erişimleri
          engellemek isterseniz adresin ya da alan adının bir parçasını
          belirtin:</p>
    
            <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 192.168.205
        Require not host phishers.example.com moreidiots.example
        Require not host ke
    &lt;/RequireAll&gt;</pre>
    
    
            <p><code class="directive"><a href="../mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code> yönergesini çok sayıda
            <code class="directive"><a href="../mod/mod_authz_core.html#require">&lt;Require&gt;</a></code> yönergesi ile birlikte kullanarak,
            sadece <code>not</code> ile olumsuzlanan tüm koşulları gerçekleyen
            bağlantılara erişim verilir. Başka bir deyişle, olumsuzlanan koşulları
            gerçeklemeyen bağlantıların erişimi engellenir.</p>
    
        
    
        <h3><a name="filesystem" id="filesystem">Erişim denetimi ve geriye uyumluluk</a></h3>
          
          <p>Kimlik doğrulama için tedarik tabanlı mekanizma kullanımının
          yan etkilerinden birisi,
          <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>,
          <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>,
          <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> ve
          <code class="directive"><a href="../mod/mod_access_compat.html#satisfy">Satisfy</a></code> erişim
          denetim yönergelerine artık ihtiyaç duyulmamasıdır. Ancak eski
          yapılandırmalarla uyumluluğu sağlamak için bu yönergeler
          <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> modülüne taşınmıştır.</p>
    
          <div class="warning"><h3>Note</h3>
            <p><code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> ile sağlanan yönergelerin
            kullanımı artık önerilmemekte, <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>
            modülündeki yönergeler önerilmektedir. <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code> veya <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> ile
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> gibi daha yeni
            olanlarının yenilerle karışık kullanımı teknik olarak mümkünse de
            önerilmemektedir. <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> modülü, 2.4
            yükseltmesini kolaylaştırmak için sadece eski yönergeleri içeren
            yapılandırmaları desteklemek üzere oluşturulmuştur.  Daha ayrıntılı
            bilgi için <a href="../upgrading.html">yükseltme</a> belgesine bakınız.
            </p>
          </div>
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="socache" id="socache">Kimlik Doğrulama Arabelleği</a></h2>
        <p>Zaman zaman kimlik doğrulama ağınızda veya sağlayıcı(ları)nızda kabul
        edilemez yükler oluşturur. Bu çoğunlukla <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>
        (veya üçüncü parti/özel sağlayıcıların) kullanıcılarını etkiler. Bununla
        ilgilenmek için httpd 2.3/2.4, kimlik bilgilerini arabelleklemek ve özgün
        sağlayıcıların yüklerini azaltmak için yeni bir arabellekleme sağlayıcısı
        olarak <code class="module"><a href="../mod/mod_authn_socache.html">mod_authn_socache</a></code> modülü ile gelmektedir.</p>
        <p>Bu, bazı kullanıcılar için önemli bir başarım artışı sağlayabilir.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">Daha fazla bilgi</a></h2>
        <p>Daha fazla bilgi için <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> ve
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code> modüllerinin belgelerine bakınız.
        <code class="directive"><a href="../mod/mod_authn_core.html#authnprovideralias">AuthnProviderAlias</a></code>
        yönergesi ile bazı yapılandırmalarınızı basitleştirebilirsiniz.</p>
    
        <p>Apache tarafından desteklenen şifrelerle ilgili bilgi için <a href="../misc/password_encryptions.html">Parola Biçemleri</a>
        belgesine bakınız.</p>
    
        <p><a href="access.html">Erişim Denetimi</a> nasıl belgesinden de
        bazı bilgiler edinebilirsiniz.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/auth.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/htaccess.html.es�����������������������������������������������������0000664�0001751�0001751�00000073135�14743132254�021276� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Tutorial del Servidor Apache HTTP: Ficheros .htaccess - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a> &gt; <a href="./">How-To / Tutoriales</a></div><div id="page-content"><div id="preamble"><h1>Tutorial del Servidor Apache HTTP: Ficheros .htaccess</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div>
    
        <p>Los ficheros <code>.htaccess</code> facilitan una forma de realizar 
        cambios en la configuraci&#243;n en contexto directorio.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Ficheros .htaccess</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">Qu&#233; son/C&#243;mo usarlos</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#when">Cuando (no) usar ficheros .htaccess</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#how">How directives are applied</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#auth">Ejemplo de Autenticaci&#243;n</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssi">Ejemplo de Server Side Includes</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Reglas de Rewrite en ficheros .htaccess</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">Ejemplo de CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">Resoluci&#243;n de problemas</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Ficheros .htaccess</a></h2>
        <table class="related"><tr><th>M&#243;dulos Relacionados</th><th>Directivas Relacionadas</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li><li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li><li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code></li></ul></td></tr></table>
    
        <div class="note">Deber&#237;a evitar usar ficheros <code>.htaccess</code> completamente si
        tiene acceso al fichero de configuraci&#243;n principal de httpd. Usar ficheros 
        <code>.htaccess</code> ralentiza su servidor Apache http. Cualquier 
        directiva que pueda incluir en un fichero <code>.htaccess</code> 
        estar&#225; mejor configurada dentro de una secci&#243;n 
        <code class="directive"><a href="../mod/core.html#directory">Directory</a></code>, tendr&#225; el mismo efecto y
        mejor rendimiento.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">Qu&#233; son/C&#243;mo usarlos</a></h2>
    
    
        <p>Los ficheros <code>.htaccess</code> (o "ficheros de configuraci&#243;n
        distribuida") facilitan una forma de realizar cambios en la configuraci&#243;n
        en contexto directorio. Un fichero, que contiene una o m&#225;s directivas, se 
        coloca en un documento espec&#237;fico de un directorio, y estas directivas 
        aplican a ese directorio y todos sus subdirectorios.</p>
    
        <div class="note"><h3>Nota:</h3>
          <p>Si quiere llamar a su fichero <code>.htaccess</code> de otra manera, 
          puede cambiar el nombre del fichero usando la directiva <code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code>. Por ejemplo, si usted prefiere
          llamar al fichero <code>.config</code>, entonces puede poner lo siguiente
          en el fichero de configuraci&#243;n de su servidor:</p>
    
          <pre class="prettyprint lang-config">AccessFileName ".config"</pre>
    
        </div>
    
        <p>Generalmente, los ficheros <code>.htaccess</code> usan la misma sint&#225;xis 
        que los <a href="../configuring.html#syntax">ficheros de la configuraci&#243;n
        principal</a>. Lo que puede utilizar en estos ficheros lo determina la 
        directiva <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>. Esta directiva
        especifica, en categor&#237;as, qu&#233; directivas tendr&#225;n efecto si se encuentran en 
        un fichero <code>.htaccess</code>. Si se permite una directiva en un fichero 
        <code>.htaccess</code>, la documentaci&#243;n para esa directiva contendr&#225; una 
        secci&#243;n Override, especificando qu&#233; valor debe ir en 
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> para que se permita esa
        directiva.</p>
    
        <p>Por ejemplo, si busca en la documentaci&#243;n la directiva <code class="directive"><a href="../mod/core.html#adddefaultcharset">AddDefaultCharset</a></code>, encontrar&#225; que se permite en
        ficheros <code>.htaccess</code>. (Vea la l&#237;nea de Contexto en el sumario de
        la directiva.) La l&#237;nea <a href="../mod/directive-dict.html#Context">Override</a> muestra
        <code>FileInfo</code>. De este modo, debe tener al menos
        <code>AllowOverride FileInfo</code> para que esta directiva se aplique en
        ficheros <code>.htaccess</code>.</p>
    
        <div class="example"><h3>Ejemplo:</h3><table>
            <tr>
              <td><a href="../mod/directive-dict.html#Context">Context:</a></td>
              <td>server config, virtual host, directory, .htaccess</td>
            </tr>
    
            <tr>
              <td><a href="../mod/directive-dict.html#Override">Override:</a></td>
              <td>FileInfo</td>
            </tr>
          </table></div>
    
        <p>Si no est&#225; seguro de cu&#225;ndo, una directiva en concreto, se puede usar en un 
        fichero <code>.htaccess</code>, consulte la documentaci&#243;n para esa directiva, 
        y compruebe la l&#237;nea Context buscando ".htaccess".</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="when" id="when">Cuando (no) usar ficheros .htaccess</a></h2>
    
        <p>Generalmente, solo deber&#237;a usar ficheros <code>.htaccess</code> cuando no
        tiene acceso al fichero principal de configuraci&#243;n del servidor. Hay, por
        ejemplo, una creencia err&#243;nea de que la autenticaci&#243;n de usuario deber&#237;a 
        hacerse siempre dentro de ficheros <code>.htaccess</code>, y, m&#225;s recientemente, otra creencia err&#243;nea de que las directivas de 
        <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> deben ir en ficheros <code>.htaccess</code>. 
        Esto sencillamente no es el caso. Puede poner las configuraciones de 
        autenticaci&#243;n de usuario en la configuraci&#243;n principal del servidor, y esto 
        es de hecho, el m&#233;todo preferido de configurar Apache. Del mismo modo, las 
        directivas <code>mod_rewrite</code> funcionan mejor, en muchos sentidos, en 
        el fichero de configuraci&#243;n principal del servidor.</p>
    
        <p>Los ficheros <code>.htaccess</code> deber&#237;an usarse cuando su proveedor 
        de contenidos le permite hacer modificaciones de configuraci&#243;n 
        en contexto directorio, pero usted no tiene acceso de root en el servidor.
        En el caso de que el administrador no est&#233; dispuesto a hacer cambios 
        frecuentes en la configuraci&#243;n, puede que sea necesario permitir a usuarios
        individuales realizar estos cambios de configuraci&#243;n en ficheros 
        <code>.htaccess</code> por ellos mismos. Lo cual ocurre a menudo, por 
        ejemplo, en casos donde los ISP est&#225;n albergando m&#250;ltiples sitios web de 
        usuario en una sola m&#225;quina, y quieren que sus usuarios tengan la 
        posibilidad de modificar sus configuraciones.</p>
    
        <p>Aun as&#237;, generalmente, el uso de ficheros <code>.htaccess</code> deber&#237;a
        evitarse cuando sea posible. Cualquier configuraci&#243;n que considerar&#237;a poner
        en un fichero <code>.htaccess</code>, puede usarse con la misma efectividad
        en una secci&#243;n <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> en el fichero de configuraci&#243;n 
        del servidor.</p>
    
        <p>Hay dos razones para evitar el uso de ficheros <code>.htaccess</code>.</p>
    
        <p>La primera es el rendimiento. Cuando <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        est&#225; configurado para permitir el uso de ficheros <code>.htaccess</code>, 
        httpd buscar&#225; ficheros <code>.htaccess</code> en cada directorio. As&#237;,
        permitiendo ficheros <code>.htaccess</code> provoca una p&#233;rdida de 
        rendimiento, &#161;incluso aunque no los use! Adem&#225;s, los ficheros 
        <code>.htaccess</code> se cargan cada vez que se solicita un documento.</p>
    
        <p>Adem&#225;s tenga en cuenta que httpd debe buscar ficheros 
        <code>.htaccess</code> en todos los directorios de mayor jerarqu&#237;a, 
        para poder terner la lista completa de directivas que debe aplicar. (Vea
        la secci&#243;n sobre <a href="#how">C&#243;mo se aplican las directivas</a>.) As&#237;, si
        se solicita un fichero de un directorio <code>/www/htdocs/example</code>, 
        httpd debe buscar los siguientes ficheros:</p>
    
        <div class="example"><p><code>
          /.htaccess<br />
          /www/.htaccess<br />
          /www/htdocs/.htaccess<br />
          /www/htdocs/example/.htaccess
        </code></p></div>
    
        <p>De esta manera, por cada acceso a un fichero de ese directorio, hay 4 
        accesos adicionales al sistema de ficheros, incluso si ninguno de esos 
        ficheros est&#225; presente. (Tenga en cuenta que este caso solo se dar&#237;a si los 
        ficheros <code>.htaccess</code> est&#225;n activados en <code>/</code>, que 
        generalmente no es el caso.).</p>
    
        <p>En el caso de las directivas <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>, en el contexto de
        <code>.htaccess</code> estas expresiones regulares deben recompilarse con 
        cada solicitud a ese directorio, cuando en el contexto de configuraci&#243;n del
        servidor solo se compilan una vez y se cachean. Adicionalmente, las reglas
        en s&#237; mismas son m&#225;s complicadas, puesto que uno debe sortear las 
        restricciones que vienen acompa&#241;adas del contexto directorio y 
        <code>mod_rewrite</code>. Consulte la  <a href="../rewrite/intro.html#htaccess">Gu&#237;a de Rewrite</a> para un mayor 
        detalle sobre este tema.</p>
    
        <p>La segunda consideraci&#243;n es de seguridad. Estar&#225; permitiendo que usuarios
        modifiquen la configuraci&#243;n del servidor, lo cual puede dar lugar a cambios sobre los que usted no tendr&#225; ning&#250;n control. Medite profundamente si debe 
        dar a sus usuarios ese privilegio. Adem&#225;s tenga en cuenta que dar a los usuarios menos privilegios de los que necesitan dar&#225; lugar a m&#225;s peticiones 
        de soporte. Aseg&#250;rese de que le indica a sus usuarios claramente el nivel de privilegios que les est&#225; dando. Especificando exactamente c&#243;mo ha 
        configurado <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>, e inv&#237;teles 
        a revisar la documentaci&#243;n relacionada, lo cual le ahorrar&#225; 
        bastantes confusiones m&#225;s adelante.</p>
    
        <p>Tenga en cuenta que esto es equivalente por completo a poner un fichero
        <code>.htaccess</code> en un directorio <code>/www/htdocs/example</code> 
        con una directiva, y poner la misma directiva en una secci&#243;n 
        Directory <code>&lt;Directory "/www/htdocs/example"&gt;</code> en su 
        configuraci&#243;n principal del servidor:</p>
    
        <p>Fichero <code>.htaccess</code> en <code>/www/htdocs/example</code>:</p>
    
        <div class="example"><h3>Contenido de fichero .htaccess en
        <code>/www/htdocs/example</code></h3><pre class="prettyprint lang-config">AddType text/example ".exm"</pre>
    </div>
    
        <div class="example"><h3>Secci&#243;n de su fichero <code>httpd.conf</code></h3><pre class="prettyprint lang-config">&lt;Directory "/www/htdocs/example"&gt;
        AddType text/example ".exm"
    &lt;/Directory&gt;</pre>
    </div>
    
        <p>Aun as&#237;, poniendo &#233;sta en el fichero de configuraci&#243;n dar&#225; como resultado
        una menor p&#233;rdida de rendimiento, y como la configuraci&#243;n se carga una vez
        cuando el httpd arranca, en lugar de cada vez que se solicita un fichero.</p>
    
        <p>El uso de ficheros <code>.htaccess</code> puede desactivarse por completo
        configurando la directiva <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        a <code>none</code>:</p>
    
        <pre class="prettyprint lang-config">AllowOverride None</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="how" id="how">How directives are applied</a></h2>
    
        <p>Las directivas de configuraci&#243;n que se encuentran en el fichero
        <code>.htaccess</code> se aplican al directorio en el que el fichero
        <code>.htaccess</code> se encuentra, y a todos sus subdirectorios. Sin 
        embargo, es importante recordar que puede haber otros ficheros 
        <code>.htaccess</code> en directorios previos. Las directivas se aplican en
        el orden en el que se encuentran. Por lo tanto, un fichero 
        <code>.htaccess</code> puede sobrescribir directivas que se encuentran
        en ficheros <code>.htaccess</code> que se encuentran en directorios previos 
        del &#225;rbol de directorios. Y estos, en cambio, pueden haber sobrescrito 
        directivas que se encontraban m&#225;s arriba, o en el fichero principal de 
        configuraci&#243;n del servidor mismo.</p>
    
        <p>Ejemplo:</p>
    
        <p>En el directorio <code>/www/htdocs/example1</code> tenemos un fichero
        <code>.htaccess</code> que contiene lo siguiente:</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI</pre>
    
    
        <p>(Nota: debe terner "<code>AllowOverride Options</code>" configurado para
        permitir el uso de la directiva "<code class="directive"><a href="../mod/core.html#options">Options</a></code>" en ficheros 
        <code>.htaccess</code> files.)</p>
    
        <p>En el directorio <code>/www/htdocs/example1/example2</code> tenemos un
        fichero <code>.htaccess</code> que contiene:</p>
    
        <pre class="prettyprint lang-config">Options Includes</pre>
    
    
        <p>Por este segundo fichero <code>.htaccess</code>, en el directorio
        <code>/www/htdocs/example1/example2</code>, la ejecuci&#243;n de CGI execution no
        est&#225; permitida, porque solo se ha definido <code>Options Includes</code>, 
        que sobrescribe completamente una configuraci&#243;n previa que se pudiera haber
        definido.</p>
    
        <h3><a name="merge" id="merge">Incorporando el .htaccess en los ficheros de 
        configuraci&#243;n principal</a></h3>
    
        <p>Como se ha comentado en la documentaci&#243;n en las <a href="../sections.html">Secciones de Configuraci&#243;n</a>, los ficheros
        <code>.htaccess</code> pueden sobrescribir las secciones <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> por el directorio
        correspondiente, pero se sobrescribir&#225;n por otros tipos de secciones de 
        configuraci&#243;n de los ficheros de configuraci&#243;n principal. Este hecho se
        puede usar para forzar ciertas configuraciones, incluso en presencia
        de una configuraci&#243;n laxa de 
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>. Por ejemplo, para 
        prevenir la ejecuci&#243;n de un script mientras se permite cualquier otra cosa 
        en <code>.htaccess</code> puede usar:</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/htdocs"&gt;
        AllowOverride All
    &lt;/Directory&gt;
    
    &lt;Location "/"&gt;
        Options +IncludesNoExec -ExecCGI
    &lt;/Location&gt;</pre>
    
    
        <div class="note">Este ejemplo asume que su <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> es <code>/www/htdocs</code>.</div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="auth" id="auth">Ejemplo de Autenticaci&#243;n</a></h2>
    
        <p>Si salt&#243; directamente a esta parte del documento para averiguar como 
        hacer la autenticaci&#243;n, es important que tenga en cuenta una cosa. Hay una 
        creencia err&#243;nea de que necesita usar ficheros <code>.htaccess</code> para
        configurar autenticaci&#243;n con contrase&#241;a. Este no es el caso. Colocar las
        directivas de autenticaci&#243;n en una secci&#243;n 
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>, en su fichero
        de configuraci&#243;n principal, es el m&#233;todo recomendado para configurar esto, 
        y los ficheros <code>.htaccess</code> deber&#237;an usarse solamente si no tiene 
        acceso al fichero de configuraci&#243;n principal del servidor. Vea <a href="#when">m&#225;s arriba</a> una explicaci&#243;n de cuando deber&#237;a y cuando no
        deber&#237;a usar ficheros <code>.htaccess</code>.</p>
    
        <p>Dicho esto, si todav&#237;a cree que debe usar el fichero
        <code>.htaccess</code>, podr&#225; ver que una configuraci&#243;n como la que sigue 
        podr&#237;a servirle.</p>
    
        <p>Contenido del fichero <code>.htaccess</code>:</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "Password Required"
    AuthUserFile "/www/passwords/password.file"
    AuthGroupFile "/www/passwords/group.file"
    Require group admins</pre>
    
    
        <p>Tenga en cuenta que <code>AllowOverride AuthConfig</code> debe estar
        habilitado para que estas directivas tengan alg&#250;n efecto.</p>
    
        <p>Por favor vea el <a href="auth.html">tutorial de autenticaci&#243;n</a> para
        una explicaci&#243;n m&#225;s completa de la autenticaci&#243;n y la autorizaci&#243;n.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssi" id="ssi">Ejemplo de Server Side Includes</a></h2>
    
        <p>Otro uso com&#250;n de ficheros <code>.htaccess</code> es activar Server Side 
        Includes para un directorio en particular. Esto puede hacerse 
        con las siguientes directivas de configuraci&#243;n, colocadas en un fichero
        <code>.htaccess</code> y el directorio deseado:</p>
    
        <pre class="prettyprint lang-config">Options +Includes
    AddType text/html "shtml"
    AddHandler server-parsed shtml</pre>
    
    
        <p>Tenga en cuenta que <code>AllowOverride Options</code> y 
        <code>AllowOverride FileInfo</code> deben estar activadas para que estas 
        directivas tengan efecto.</p>
    
        <p>Por favor vea el <a href="ssi.html">tutorial de SSI</a> para una
        explicaci&#243;n m&#225;s completa de server-side includes.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Reglas de Rewrite en ficheros .htaccess</a></h2>
        <p>Cuando use <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> en
        ficheros <code>.htaccess</code>, tenga en cuenta que el contexto 
        directorio cambia las cosas un poco. En concreto, las reglas son 
        relativas al directorio actual, en lugar de serlo de la petici&#243;n de URI 
        solicitada originalmente.
        Considere los siguientes ejemplos:</p>
    
    <pre class="prettyprint lang-config"># En httpd.conf
    RewriteRule "^/images/(.+)\.jpg" "/images/$1.png"
    
    # En .htaccess en el directorio ra&#237;z
    RewriteRule "^images/(.+)\.jpg" "images/$1.png"
    
    # En .htaccess en images/
    RewriteRule "^(.+)\.jpg" "$1.png"</pre>
    
    
        <p>En un <code>.htaccess</code> en cualquier directorio del DocumentRoot, la 
        barra ("/") inicial se elimina del valor facilitado a <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>, y en el subdirectorio 
        <code>images</code>, se elimina <code>/images/</code> tambi&#233;n de este valor. 
        As&#237;, su expresi&#243;n regular necesita omitir tambi&#233;n esa parte.</p>
    
        <p>Consulte la <a href="../rewrite/">documentaci&#243;n de mod_rewrite</a> para 
        m&#225;s detalles al usar <code>mod_rewrite</code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">Ejemplo de CGI</a></h2>
    
        <p>Finalmente, puede que quiera usar un fichero <code>.htaccess</code> para
        permitir la ejecuci&#243;n de programas CGI en un directorio en particular. Esto
        se puede implementar con la siguiente configuraci&#243;n:</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI
    AddHandler cgi-script "cgi" "pl"</pre>
    
    
        <p>Alternativamente, si quiere considerar como programas CGI todos los 
        ficheros de un directorio concreto, esto se puede conseguir con la siguiente 
        configuraci&#243;n:</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI
    SetHandler cgi-script</pre>
    
    
        <p>Tenga en cuenta que <code>AllowOverride Options</code> y 
        <code>AllowOverride FileInfo</code> deben estar ambas activadas para que 
        estas directivas tengan efecto.</p>
    
        <p>Por favor vea el <a href="cgi.html">tutorial CGI</a> para mayor detalle
        sobre programaci&#243;n y configuraci&#243;n de CGI.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">Resoluci&#243;n de problemas</a></h2>
    
        <p>Cuando pone directivas en un fichero <code>.htaccess</code> y no obtiene 
        el efecto deseado hay una serie de cosas que pueden haber ido mal.</p>
    
        <p>El problema m&#225;s com&#250;n es que <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride
        </a></code> no est&#225; configurada para que sus directivas puedan surtir
        efecto. Aseg&#250;rese de que no tiene <code>AllowOverride None</code> 
        configurado para el directorio en cuesti&#243;n. Una buena forma de probar esto
        es poner "basura" en su fichero <code>.htaccess</code> y recargar la p&#225;gina. 
        Si no se genera un error en el servidor, casi seguro que tiene configurado 
        <code>AllowOverride None</code>.</p>
    
        <p>Si, por otro lado, obtiene errores de servidor al intentar acceder a 
        documentos, compruebe el log de errores de httpd. Seguramente le indiquen 
        que la directiva en uso en su fichero <code>.htaccess</code> no est&#225; 
        permitida.</p>
    
        <div class="example"><p><code>
        [Fri Sep 17 18:43:16 2010] [alert] [client 192.168.200.51] /var/www/html/.htaccess: DirectoryIndex not allowed here
        </code></p></div>
    
        <p>Esto indicar&#225; que o bien ha usado una directiva que no se permite nunca 
        en ficheros <code>.htaccess</code>, o que simplementa no tiene
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> configurado
        a un nivel suficiente para la directiva que ha usado. Consulte la
        documentaci&#243;n para esa directiva en particular para determinar cual es el 
        caso.</p>
    
        <p>Alternativamente, puede que le indique que hay un error de sintaxis en 
        el uso de la propia directiva.</p>
    
        <div class="example"><p><code>
        [Sat Aug 09 16:22:34 2008] [alert] [client 192.168.200.51] /var/www/html/.htaccess: RewriteCond: bad flag delimiters
        </code></p></div>
    
        <p>En este caso, el mensaje de error deber&#237;a ser espec&#237;fico para el error de
        sintaxis concreto que ha cometido.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/http2.html.es��������������������������������������������������������0000664�0001751�0001751�00000071241�14743132254�020536� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Gu&#237;a HTTP/2 - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a> &gt; <a href="./">How-To / Tutoriales</a></div><div id="page-content"><div id="preamble"><h1>Gu&#237;a HTTP/2</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/http2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/http2.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/http2.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta traducci&#243;n podr&#237;a estar
                obsoleta. Consulte la versi&#243;n en ingl&#233;s de la
                documentaci&#243;n para comprobar si se han producido cambios
                recientemente.</div>
    
        <p>
            Esta es la gu&#237;a para configurar HTTP/2 en Apache httpd. &#201;sta caracter&#237;stica
            est&#225; <em>lista en produci&#243;n</em> as&#237; que es de esperar que las interfaces
            y las directivas se mantengan consistentes en cada veri&#243;n.
        </p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#protocol">El protocolo HTTP/2</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#implementation">HTTP/2 en Apache httpd</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#building">Compilar httpd con soporte HTTP/2</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic-config">Configuraci&#243;n b&#225;sica</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mpm-config">Configuraci&#243;n MPM</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#clients">Clientes</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#tools">Herramientas &#250;tiles para depurar HTTP/2</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#push">Server Push</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#earlyhints">"Early Hints"</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code></li><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="protocol" id="protocol">El protocolo HTTP/2</a></h2>
        
    
        <p>HTTP/2 es la evoluci&#243;n del protocolo de la capa de aplicaci&#243;n con m&#225;s
        &#233;xito, HTTP. Se centra en hacer un uso m&#225;s eficiente de los recursos de red. 
        No cambia la caracter&#237;stica fundamental de HTTP, la sem&#225;ntica. Todav&#237;a hay 
        olicitudes, respuestas, cabeceras y todo los elementos t&#237;picos de HTTP/1. As&#237; 
        que, si ya conoce HTTP/1, tambi&#233;n conoce el 95% de HTTP/2.</p>
        
        <p>Se ha escrito mucho sobre HTTP/2 y de c&#243;mo funciona. La norma m&#225;s
        est&#225;ndar es, por supuesto, su 
        <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a> 
        (<a href="http://httpwg.org/specs/rfc7540.html"> tambi&#233;n disponible en un
        formato m&#225;s legible, YMMV</a>). As&#237; que, ah&#237; encontrar&#225; toda la especificaci&#243;n 
        del protocolo.</p>
    
        <p>Pero, como con todos los RFC, no es ideal como primera lectura. Es mejor
        entender primero <em>qu&#233;</em> se quiere hacer y despu&#233;s leer el RFC sobre 
        <em>c&#243;mo</em> hacerlo. Un documento mucho mejor con el que empezar es
        <a href="https://daniel.haxx.se/http2/">http2 explicado</a>
        por Daniel Stenberg, el autor de <a href="https://curl.haxx.se">curl</a>. 
        &#161;Tambi&#233;n est&#225; disponible cada vez en un mayor n&#250;mero lenguajes!</p>
        
        <p>Si le parece demasiado largo, o no lo ha leido, hay algunos t&#233;rminos
        y elementos a tener en cuenta cuando lea este documento:</p>
        <ul>
            <li>HTTP/2 es un <strong>protocolo binario</strong>, al contrario que 
            HTTP 1.1 que es texto plano. La intenci&#243;n para HTTP 1.1 es que sea 
            legible (por ejemplo capturando el tr&#225;fico de red) mientras que para 
            HTTP/2 no. M&#225;s informaci&#243;n en el FAQ oficial 
            <a href="https://http2.github.io/faq/#why-is-http2-binary">&#191;Por qu&#233; es 
                binario HTTP/2?</a></li>
    
            <li><strong>h2</strong> es HTTP/2 sobre TLS (negociaci&#243;n de protocolo a 
            trav&#233;s de ALPN).</li>
    
            <li><strong>h2c</strong> es HTTP/2 sobre TCP.</li>
    
            <li>Un <strong>frame</strong> es la unidad m&#225;s peque&#241;a de comunicaci&#243;n 
            dentro de una conexi&#243;n HTTP/2, que consiste en una cabecera y una secuencia 
            de octetos de longitud variable estructurada de acuerdo con el tipo de 
            frame. M&#225;s informaci&#243;n en la documentaci&#243;n oficial 
            <a href="http://httpwg.org/specs/rfc7540.html#FramingLayer">Secci&#243;n de 
                Capa de Frame</a>.</li>
    
            <li>Un <strong>stream</strong> es un flujo bidireccional de frames dentro 
            de una conexi&#243;n HTTP/2. El concepto correspondiente en HTTP 1.1 es un 
            intercambio de mensajes de solicitud/respuesta. M&#225;s informaci&#243;n en la 
            documentaci&#243;n oficial 
            <a href="http://httpwg.org/specs/rfc7540.html#StreamsLayer">Secci&#243;n Capa 
                de Stream</a>.</li>
    
            <li>
                HTTP/2 es capaz de llevar <strong>m&#250;ltiples streams</strong> de datos
                sobre la misma conexi&#243;n TCP, evitando la cl&#225;sica solicitud lenta 
                "head-of-line blocking" de HTTP 1.1 y evitando generar m&#250;ltiples conexiones
                TCP para cada solicitud/respuesta (KeepAlive parche&#243; el problema en 
                HTTP 1.1 pero no lo resolvi&#243; completamente).
          </li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">HTTP/2 en Apache httpd</a></h2>
        
    
        <p>
            El protocolo HTTP/2 se implementa con su propio m&#243;dulo httpd, llamado 
            acertadamente <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code>. Incluye el set completo de 
            caracter&#237;sticas descritas por el RFC 7540 y soporta HTTP/2 sobre texto 
            plano (http:), as&#237; como conexiones seguras (https:). La variante de texto
            plano se llama '<code>h2c</code>', la segura '<code>h2</code>'. Para 
            <code>h2c</code> permite el modo <em>direct</em>
            y el <code>Upgrade:</code> a trav&#233;s de una solicitud inicial HTTP/1.
        </p>
        
        <p>
            Una caracter&#237;stica de HTTP/2 que ofrece capacidades nuevas para 
            desarrolladores de web es <a href="#push">Server Push</a>. Vea esa secci&#243;n
             para saber como su aplicaci&#243;n web puede hacer uso de ella.
         </p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="building" id="building">Compilar httpd con soporte HTTP/2</a></h2>
        
    
        <p>
            <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> usa la librer&#237;a <a href="https://nghttp2.org">
            nghttp2</a>como su implementaci&#243;n base. Para compilar 
            <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> necesita al menos la versi&#243;n 1.2.1 de 
            <code>libnghttp2</code> instalada en su sistema.
        </p>
    
        <p>
            Cuando usted ejecuta <code>./configure</code> en el c&#243;digo fuente de 
            Apache HTTPD, necesita indicarle '<code>--enable-http2</code>' como una 
            opci&#243;n adicional para activar la compilaci&#243;n de este m&#243;dulo. Si su 
            <code>libnghttp2</code> est&#225; ubicado en una ruta no habitual (cualquiera que 
            sea en su sistema operativo), puede indicar su ubicaci&#243;n con 
            '<code>--with-nghttp2=&lt;path&gt;</code>' para <code>./configure</code>.
        </p>
    
        <p>Aunque puede que eso sirva para la mayor&#237;a, habr&#225; quien prefiera un <code>nghttp2</code> compilado est&#225;ticamente para este m&#243;dulo. Para ellos existe la opci&#243;n <code>--enable-nghttp2-staticlib-deps</code>. Funciona de manera muy similar a como uno debe enlazar openssl est&#225;ticamente para <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.</p>
    
        <p>Hablando de SSL, necesita estar al tanto de que la mayor&#237;a de los navegadores hablan HTTP/2 solo con URLs <code>https:</code>. As&#237; que necesita un servidor con soporte SSL. Pero no solo eso, necesitar&#225; una librer&#237;a SSL que de soporte a la extensi&#243;n <code>ALPN</code>. Si usa OpenSSL, necesita al menos la versi&#243;n 1.0.2.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic-config" id="basic-config">Configuraci&#243;n b&#225;sica</a></h2>
        
    
        <p>Cuando tiene un <code>httpd</code> compilado con <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> necesita una configuraci&#243;n b&#225;sica para activarlo. Lo primero, como con cualquier otro m&#243;dulo de Apache, es que necesita cargarlo:</p>
        
        <pre class="prettyprint lang-config">LoadModule http2_module modules/mod_http2.so</pre>
    
        
        <p>La segunda directiva que necesita a&#241;adir a la configuraci&#243;n de su servidor es:</p>
    
        <pre class="prettyprint lang-config">Protocols h2 http/1.1</pre>
    
        
        <p>Esto permite h2, la variante segura, para ser el protocolo preferido de las conexiones en su servidor. Cuando quiera habilitar todas las variantes de HTTP/2, entonces simplemente configure:</p>
    
        <pre class="prettyprint lang-config">Protocols h2 h2c http/1.1</pre>
    
    
        <p>Dependiendo de d&#243;nde pone esta directiva, afecta a todas las conexiones o solo a las de ciertos host virtuales. La puede anidar, como en:</p>
    
        <pre class="prettyprint lang-config">Protocols http/1.1
    &lt;VirtualHost ...&gt;
        ServerName test.example.org
        Protocols h2 http/1.1
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Esto solo permite HTTP/1, excepto conexiones SSL hacia <code>test.example.org</code> que ofrecen HTTP/2.</p>
    
        <div class="note"><h3>Escoger un SSLCipherSuite seguro</h3>
         <p>Es necesario configurar <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code> con una suite segura de cifrado TLS. La versi&#243;n actual de mod_http2 no fuerza ning&#250;n cifrado pero la mayor&#237;a de los clientes si lo hacen. Encaminar un navegador hacia un servidor con <code>h2</code> activado con una suite inapropiada de cifrados forzar&#225; al navegador a rehusar e intentar conectar por HTTP 1.1. Esto es un error com&#250;n cuando se configura httpd con HTTP/2 por primera vez, &#161;as&#237; que por favor tenga en cuenta que debe evitar largas sesiones de depuraci&#243;n! Si quiere estar seguro de la suite de cifrados que escoja, por favor evite los listados en la <a href="http://httpwg.org/specs/rfc7540.html#BadCipherSuites">Lista Negra de TLS para HTTP/2</a>.</p>
        </div>
    
        <p>El orden de los protocolos mencionados tambi&#233;n es relevante. Por defecto, el primero es el protocolo preferido. Cuando un cliente ofrece m&#250;ltiples opciones, la que est&#233; m&#225;s a la izquierda ser&#225; la escogida. En</p>
        <pre class="prettyprint lang-config">Protocols http/1.1 h2</pre>
    
        
        <p>el protocolo preferido es HTTP/1 y siempre ser&#225; seleccionado a menos que el cliente <em>s&#243;lo</em> soporte h2. Puesto que queremos hablar HTTP/2 con clientes que lo soporten, el orden correcto es:</p>
        
        <pre class="prettyprint lang-config">Protocols h2 h2c http/1.1</pre>
    
    
        <p>Hay algo m&#225;s respecto al orden: el cliente tambi&#233;n tiene sus propias preferencias. Si quiere, puede configurar su servidor para seleccionar el protocolo preferido por el cliente:</p>
    
        <pre class="prettyprint lang-config">ProtocolsHonorOrder Off</pre>
    
    
        <p>Hace que el orden en que <em>usted</em> escribi&#243; los Protocols sea irrelevante y s&#243;lo el orden de preferencia del cliente ser&#225; decisorio.</p>
    
        <p>Una &#250;ltima cosa: cuando usted configura los protocolos no se comprueba si son correctos o est&#225;n bien escritos. Puede mencionar protocolos que no existen, as&#237; que no hay necesidad de proteger <code class="directive"><a href="../mod/core.html#protocols">Protocols</a></code> con ning&#250;n <code class="directive"><a href="../mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> de comprobaci&#243;n.</p>
    
        <p>Para m&#225;s consejos avanzados de configuraci&#243;n, vea la <a href="../mod/mod_http2.html#dimensioning">
        secci&#243;n de m&#243;dulos sobre dimensionamiento</a> y <a href="../mod/mod_http2.html#misdirected">
        como gestionar multiples hosts con el mismo certificado</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mpm-config" id="mpm-config">Configuraci&#243;n MPM</a></h2>
        
        
        <p>HTTP/2 est&#225; soportado en todos los m&#243;dulos de multi-proceso que se ofrecen con httpd. Aun as&#237;, si usa el mpm <code class="module"><a href="../mod/prefork.html">prefork</a></code>, habr&#225;  restricciones severas.</p>
    
        <p>En <code class="module"><a href="../mod/prefork.html">prefork</a></code>, <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> solo procesar&#225; una solicitud cada vez por conexi&#243;n. Pero los clientes, como los navegadores, enviar&#225;n muchas solicitudes al mismo tiempo. Si una de ellas tarda mucho en procesarse (o hace un sondeo que dura m&#225;s de la cuenta), las otras solicitudes se quedar&#225;n atascadas.</p>
    
        <p><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> no evitar&#225; este l&#237;mite por defecto. El motivo es que <code class="module"><a href="../mod/prefork.html">prefork</a></code> hoy en d&#237;a solo se escoge si ejecuta motores de proceso que no est&#225;n preparados para multi-hilo, p.ej. fallar&#225; con m&#225;s de una solicitud.</p>
    
        <p>Si su configuraci&#243;n lo soporta, hoy en d&#237;a <code class="module"><a href="../mod/event.html">event</a></code> es el mejor mpm que puede usar.</p>
        
        <p>Si realmente est&#225; obligado a usar <code class="module"><a href="../mod/prefork.html">prefork</a></code> y quiere multiples solicitudes, puede configurar la directiva <code class="directive"><a href="../mod/mod_http2.html#h2minworkers">H2MinWorkers</a></code> para hacerlo posible. Sin embargo, si esto falla, es bajo su cuenta y riesgo.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="clients" id="clients">Clientes</a></h2>
        
        
        <p>Casi todos los navegadores modernos dan soporte a HTTP/2, pero solo en conexiones SSL: Firefox (v43), Chrome (v45), Safari (since v9), iOS Safari (v9), Opera (v35), Chrome para Android (v49) e Internet Explorer (v11 en Windows10) (<a href="http://caniuse.com/#search=http2">Fuente</a>).</p>
    
        <p>Otros clientes, as&#237; c&#243;mo otros servidores, est&#225;n listados en la 
        <a href="https://github.com/http2/http2-spec/wiki/Implementations">wiki de Implementaciones</a>, entre ellos, implementaciones para c, c++, common lisp, dart, erlang, haskell, java, nodejs, php, python, perl, ruby, rust, scala y swift.</p>
    
        <p>Muchos de las implementaciones de clientes que no son navegadores soportan HTTP/2 sobre texto plano, h2c. La m&#225;s vers&#225;til es <a href="https://curl.haxx.se">curl</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tools" id="tools">Herramientas &#250;tiles para depurar HTTP/2</a></h2>
        
    
        <p>La primera herramienta a mencionar es por supuesto <a href="https://curl.haxx.se">curl</a>. Por favor aseg&#250;rese de que su versi&#243;n soporta HTTP/2 comprobando sus <code>Caracter&#237;sticas</code>:</p>
        <pre class="prettyprint lang-config">    $ curl -V
        curl 7.45.0 (x86_64-apple-darwin15.0.0) libcurl/7.45.0 OpenSSL/1.0.2d zlib/1.2.8 nghttp2/1.3.4
        Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 [...] 
        Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP <strong>HTTP2</strong>
        </pre>
    
        <div class="note"><h3>Notas sobre Mac OS homebrew</h3>
        brew install curl --with-openssl --with-nghttp2 
        </div>
        <p>Y para una inspecci&#243;n en gran profundidad <a href="https://wiki.wireshark.org/HTTP2">wireshark</a>.</p>
        <p>El paquete <a href="https://nghttp2.org">nghttp2</a> tambi&#233;n incluye clientes, tales como:</p>
        <ul>
            <li><a href="https://nghttp2.org/documentation/nghttp.1.html">nghttp
            </a> - util para visualizar la frames de HTTP/2 y tener una mejor idea de como funciona el protocolo.</li>
            <li><a href="https://nghttp2.org/documentation/h2load-howto.html">h2load</a> - &#250;til para hacer un stress-test de su servidor.</li>
        </ul>
    
        <p>Chrome ofrece logs detallados de HTTP/2 en sus conexiones a trav&#233;s de la <a href="chrome://net-internals/#http2">p&#225;gina especial de net-internals</a>. Tambi&#233;n hay una extensi&#243;n interesante para <a href="https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=en">Chrome</a> y <a href="https://addons.mozilla.org/en-us/firefox/addon/spdy-indicator/">Firefox</a> con la que visualizar cuando su navegador usa HTTP/2.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="push" id="push">Server Push</a></h2>
        
        
        <p>El protocolo HTTP/2 permite al servidor hacer PUSH de respuestas a un cliente que nunca las solicit&#243;. El tono de la conversaci&#243;n es: "Aqu&#237; tiene una solicitud que nunca envi&#243; y la respuesta llegar&#225; pronto..."</p>
    
        <p>Pero hay restricciones: el cliente puede deshabilitar esta caracter&#237;stica y el servidor entonces solo podr&#225; hacer PUSH en una solicitud que hizo previamente del cliente.</p>
    
        <p>La intenci&#243;n es permitir al servidor enviar recursos que el cliente seguramente vaya a necesitar, p. ej. un recurso css o javascript que pertenece a una p&#225;gina html que el cliente solicit&#243;, un grupo de im&#225;genes a las que se hace referencia en un css, etc.</p>
    
        <p>La ventaja para el cliente es que ahorra tiempo para solicitudes que pueden tardar desde unos pocos milisegundos a medio segundo, dependiendo de la distancia entre el cliente y el servidor. La desventaja es que el cliente puede recibir cosas que ya tiene en su cache. Por supuesto que HTTP/2 soporta cancelaci&#243;n previa de tales solicitudes, pero aun as&#237; se malgastan recursos.</p>
    
        <p>Resumiendo: no hay una estrategia mejor sobre c&#243;mo usar esta caracter&#237;stica de HTTP/2 y todo el mundo est&#225; experimentando con ella. As&#237; que, &#191;c&#243;mo experimenta usted con ella en Apache httpd?</p>
    
        <p><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> busca e inspecciona las cabeceras de respuesta 
        <code>Link</code> con cierto formato:</p>
    
        <pre class="prettyprint lang-config">Link &lt;/xxx.css&gt;;rel=preload, &lt;/xxx.js&gt;; rel=preload</pre>
    
    
        <p>
            Si la conexi&#243;n soporta PUSH, estos dos recursos se enviar&#225;n al cliente. 
            Como desarrollador web, puede configurar estas cabeceras o bien 
            directamente en la respuesta de su aplicaci&#243;n o configurar su servidor con:
        </p>
    
        <pre class="prettyprint lang-config">&lt;Location /xxx.html&gt;
        Header add Link "&lt;/xxx.css&gt;;rel=preload"
        Header add Link "&lt;/xxx.js&gt;;rel=preload"
    &lt;/Location&gt;</pre>
    
    
        <p>Si quiere usar enlaces con <code>preload</code> sin activar un PUSH, puede
        usar el par&#225;metro <code>nopush</code>, como en:</p>
    
        <pre class="prettyprint lang-config">Link &lt;/xxx.css&gt;;rel=preload;nopush</pre>
    
    
        <p>o puede desactivar PUSH para su servidor por completo con la directiva </p>
    
        <pre class="prettyprint lang-config">H2Push Off</pre>
    
    
        <p>Y hay m&#225;s:</p>
    
        <p>
            El m&#243;dulo mantiene un registro de lo que se ha enviado con PUSH para cada
            conexi&#243;n (hashes de URLs, b&#225;sicamente) y no har&#225; PUSH del mismo recurso dos
            veces. Cuando la conexi&#243;n se cierra, la informaci&#243;n es descartada.
        </p>
    
        <p>
            Hay gente pensando c&#243;mo un cliente puede decirle al servidor lo que ya
            tiene, para evitar los PUSH de esos elementos, pero eso algo muy
            experimental ahora mismo.
        </p>
    
        <p>Otro borrador experimental que ha sido implementado en 
        <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> es el <a href="https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00"> Campo de Cabecera
        Accept-Push-Policy</a> en la que un cliente puede, para cada solicitud, definir 
        qu&#233; tipo de PUSH acepta.</p>
    
        <p>
            Puede que PUSH no siempre lance la peticion/respuesta/funcionamiento que
            uno espera. Hay varios estudios sobre este tema en internet, que explican
            el beneficio y las debilidades de como diferentes funcionalidades del
            cliente y de la red influyen en el resultado.
            Por Ejemplo, que un servidor haga "PUSH" de recursos, no significa que el 
            navegador vaya a usar dichos datos.
        </p>
        <p>
            Lo m&#225;s importante que influye en la respuesta que se env&#237;a, es la solicitud
            que se simul&#243;. La url de solicitud de un PUSH es dada por la aplicaci&#243;n,
            pero &#191;de donde vienen las cabeceras de la petici&#243;n? por ejemplo si el PUSH
            pide una cabecera <code>accept-language</code> y si es as&#237;, &#191;con qu&#233; valor?
        </p>
        <p>Httpd mirar&#225; la petici&#243;n original (la que origin&#243; el PUSH) y copiar&#225; las
            siguientes cabeceras a las peticiones PUSH:
            <code>user-agent</code>, <code>accept</code>, <code>accept-encoding</code>,
            <code>accept-language</code>, <code>cache-control</code>.
        </p>
        <p>
            Todas las otras cabeceras son ignorados. Las cookies tampoco ser&#225;n copiadas.
            Impulsar los recursos que requieren una cookie para estar presente no
            funcionar&#225;. Esto puede ser una cuesti&#243;n de debate. Pero a menos que esto se
            discuta m&#225;s claramente con el navegador, evitemos el exceso de precauci&#243;n y
            no expongamos las cookies donde podr&#237;an o no ser visibles.
        </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="earlyhints" id="earlyhints">"Early Hints"</a></h2>
        
    
        <p>Una alternativa de "Pushear" recursos es mandar una cabecera 
            <code>Link</code> al cliente antes que la respuesta est&#233; lista. Esto usa
            una caracteristica de HTTP que se llama  "Early Hints" y est&#225; descrita en
            la <a href="https://tools.ietf.org/html/rfc8297">RFC 8297</a>.</p>
        <p>Para poder usar esto, necesita habilitarlo explicitamente en el servidor 
        via</p>
        
        <pre class="prettyprint lang-config">H2EarlyHints on</pre>
    
        
        <p>(No est&#225; habilitado por defecto ya q ue algunos navegadores m&#225;s antiguos 
            se caen con dichas  respuestas.)
        </p>
    
        <p>si esta funcionalidad esta activada, puede usar la directiva 
            <code class="directive"><a href="../mod/mod_http2.html#h2pushresource">H2PushResource</a></code> para que lance 
            "Early hints" y recursos mediante push:
        </p>
        <pre class="prettyprint lang-config">&lt;Location /xxx.html&gt;
        H2PushResource /xxx.css
        H2PushResource /xxx.js
    &lt;/Location&gt;</pre>
    
        <p>
            Esto lanzar&#225; una respuesta <code>"103 Early Hints"</code> a un cliente 
            tan pronto como el servidor <em>comience</em> a procesar la solicitud. 
            Esto puede ser mucho antes que en el momento en que se determinaron los 
            primeros encabezados de respuesta, dependiendo de su aplicaci&#243;n web.
        </p>
    
        <p>
            Si la directiva <code class="directive"><a href="../mod/mod_http2.html#h2push">H2Push</a></code> est&#225; 
            habilitada, esto comenzar&#225; el PUSH justo despu&#233;s de la respuesta 103.
            Sin embargo, si la directiva <code class="directive"><a href="../mod/mod_http2.html#h2push">H2Push</a></code> est&#225; dehabilitada, la respuesta 103 se le enviar&#225; al cliente.
        </p>
      </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/howto/http2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/http2.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/http2.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/http2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/index.html.zh-cn.utf8������������������������������������������������0000664�0001751�0001751�00000014736�14743132254�022107� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>常见操作/教程 - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>常见操作/教程</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">常见操作/教程</a></h2>
    
        
    
        <dl>
          <dt>认证与授权</dt>
          <dd>
            <p>认证是你验证某人是所声称的人。
            授权是允许某人执行他想要的操作,或者获得想要的信息。</p>
    
            <p>参见: <a href="auth.html">认证,授权与访问控制</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>访问控制</dt>
          <dd>
            <p>访问控制是操作限制,或基于任意条件访问资源。这可以通过多种方法完成。</p>
    
            
          </dd>
        </dl>
    
       <dl>
          <dt>CGI 与动态内容</dt>
          <dd>
            <p>CGI (通用网管接口) 为 web 服务器定义了与外部的内容生成程序的操作接口,
            通常称为 CGI 程序或 CGI 脚本。它是在 web 站点放入动态内容的最简单,
            也最常用的方法。 本文简单介绍了在 Apache 服务器中配置 CGI 的方法,
            以及如何编写 CGI 程序。</p>
    
            <p>参见: <a href="cgi.html">CGI 与动态内容</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt><code>.htaccess</code> 文件</dt>
          <dd>
            <p><code>.htaccess</code> 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.</p>
    
            <p>See: <a href="htaccess.html"><code>.htaccess</code> files</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>服务器端插入简介</dt>
          <dd>
            <p>SSI (服务器端插入) 是在 HTML 页面中放入的指令,在页面被访问的时候执行。
            它允许你在现有的 HTML 页面增加动态生成的内容,不需要通过 CGI
            程序或其它动态计数来生成整个页面。</p>
    
            <p>参见: <a href="ssi.html">服务器端插入 (SSI)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>用户私人网站目录</dt>
          <dd>
            <p>在有多个用户的系统中,使用 <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> 指令,可以允许每个用户在他们的根目录中都有一个
            web 站点。 访问 URL <code>http://example.com/~username/</code> 会得到位于用户
            "<code>username</code>" 根目录中由 <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> 指定的子目录中的内容。</p>
    
            <p>参见: <a href="public_html.html">用户私人网站目录 (<code>public_html</code>)</a></p>
          </dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������httpd-2.4.64/docs/manual/howto/public_html.html.tr.utf8���������������������������������������������0000664�0001751�0001751�00000034454�14743132254�022707� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Kullanıcı Dizinleri (public_html) - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Nasıllar ve Öğreticiler</a></div><div id="page-content"><div id="preamble"><h1>Kullanıcı Dizinleri (public_html)</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>Çok kullanıcılı sistemlerde, <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesi ile her kullanıcının kendi ev dizininde
        bir sitesi olması sağlanabilir.
        <code>http://example.com/~kullanıcı/</code> adresinin ziyaretçileri
        "kullanıcı" isimli kullanıcının ev dizininin içeriğini değil, <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesinde belirtilen alt
        dizinin içeriğini görürler.</p>
    
      <p>Öntanımlı olarak bu dizinlere erişimin etkin olmadığını unutmayınız.
        <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesini
        kullanırken <code>conf/httpd.conf</code> öntanımlı yapılandırma
        dosyasındaki</p>
    
        <pre class="prettyprint lang-config">#Include conf/extra/httpd-userdir.conf</pre>
    
    
      <p>satırını etkin hale getirip, gerekiyorsa <code>httpd-userdir.conf</code>
        dosyasını da düzenleyerek veya ana yapılandırma dosyasında bir
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> bloğu içine 
        uygun yönergeleri yerleştirerek bu dizinlere erişimi etkin hale 
        getirebilirsiniz.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Kullanıcı sayfaları dizinleri</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#userdir"><code>UserDir</code> ile dosya yolunun belirtilmesi</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#redirect">Harici adreslere yönlendirme</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#enable">Bu özelliği kullanacak kullanıcıların sınırlandırılması</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">Her kullanıcıya bir CGI dizini tahsis etmek</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">Kullanıcıların yapılandırmayı değiştirmesine izin vermek</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="../urlmapping.html">URL’lerin Dosya Sistemi ile
      Eşleştirilmesi</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Kullanıcı sayfaları dizinleri</a></h2>
        
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code></li><li><code class="directive"><a href="../mod/core.html#directorymatch">DirectoryMatch</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="userdir" id="userdir"><code>UserDir</code> ile dosya yolunun belirtilmesi</a></h2>
        
    
        <p><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesinde
         kullanıcı sayfalarının yükleneceği dizin belirtilir. Bu yönergeye değeri
         çeşitli biçimlerde atanabilir.</p>
    
        <p>Başında bölü çizgisi bulunmayan bir dosya yolu belirtilmişse,
         kullanıcının ev dizinine göreli bir dizin belirtildiği varsayılır.
         Yapılandırmada şöyle bir satır varsa:</p>
    
        <pre class="prettyprint lang-config">UserDir public_html</pre>
    
    
        <p><code>http://example.com/~orhan/dosya.html</code> adresine karşılık
          gelen dosya yolu <code>/home/orhan/public_html/dosya.html</code> olarak
          çözümlenir.</p>
    
        <p>Eğer başında bölü çizgisi bulunan bir dosya yolu belirtilirse,
          kullanıcı sayfalarının bu dizinin altında kullanıcı ismini taşıyan
          dizinlerde bulunacağı varsayılır. Yapılandırmada şöyle bir satır
          varsa:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/html</pre>
    
    
        <p><code>http://example.com/~orhan/dosya.html</code> adresine karşılık
          gelen dosya yolu <code>/var/html/orhan/dosya.html</code> olarak
          çözümlenir.</p>
    
        <p>Eğer belirtilen dosya yolu bir yıldız imi (*) içeriyorsa yıldız iminin
          yerine kullanıcı ismi yerleştirilerek elde edilen dosya yolu
          kullanılır. Yapılandırmada şöyle bir satır varsa:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/html/*/sayfam</pre>
    
    
        <p><code>http://example.com/~orhan/dosya.html</code> adresine karşılık
          gelen dosya yolu <code>/var/html/orhan/sayfam/dosya.html</code>
          olarak çözümlenir.</p>
    
        <p>Çok sayıda dizin veya dizin yolu belirtmek de mümkündür.</p>
    
        <pre class="prettyprint lang-config">UserDir public_html /var/html</pre>
    
    
        <p><code>http://example.com/~orhan/dosya.html</code> adresini Apache önce
          <code>/home/orhan/public_html/dosya.html</code> olarak arayacak,
          bulamazsa <code>/var/siteler/orhan/sayfam/dosya.html</code> olarak
          arayacak, bulduğunda istenen dosyayı sunacaktır.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">Harici adreslere yönlendirme</a></h2>
        
        <p><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesi
          kullanıcı dizini isteklerini harici adreslere yönlendirmek için de
          kullanılabilir.</p>
    
        <pre class="prettyprint lang-config">UserDir http://example.org/users/*/</pre>
    
    
        <p>Bu yapılandırmaya göre <code>http://example.com/~bob/abc.html</code>
        için yapılan bir istek <code>http://example.org/users/bob/abc.html</code>
        adresine yönlendirilecektir.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">Bu özelliği kullanacak kullanıcıların sınırlandırılması</a></h2>
        
    
        <p><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesinin
          açıklamasında belirtilen sözdizimini kullanarak bu işlevselliği bazı
          kullanıcılara yasaklayabilirsiniz:</p>
    
        <pre class="prettyprint lang-config">UserDir disabled root ahmet veli</pre>
    
    
        <p>Bu yapılandırma ile <code>disabled</code> deyiminin bulunduğu
          satırdaki kullanıcılar dışında kalan bütün kullanıcılar için bu özellik
          etkin olacaktır. Benzer şekilde, aşağıdaki yapılandırma ile
          işlevselliğin belli kullanıcılar dışında kullanılmamasını da
          sağlayabilirsiniz:</p>
    
        <pre class="prettyprint lang-config">UserDir disabled
    UserDir enabled orhan yasar</pre>
    
    
        <p>Daha fazla örnek için <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesinin açıklamasına bakabilirsiniz.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">Her kullanıcıya bir CGI dizini tahsis etmek</a></h2>
      
    
       <p>Her kullanıcıya kendine ait bir CGI dizini vermek isterseniz, bir
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> yönergesi
        ile kullanıcının ev dizinindeki belli bir dizini CGI-etkin duruma
        getirebilirsiniz.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html/cgi-bin/"&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
    
        <p> <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> yönergesinde
          <code>public_html</code> belirtildiği varsayımıyla
          <code>mesela.cgi</code> betiği bu dizinden şöyle bir adresle
          yüklenebilir:</p>
    
        <div class="example"><p><code>
          http://example.com/~orhan/cgi-bin/mesela.cgi
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">Kullanıcıların yapılandırmayı değiştirmesine izin vermek</a></h2>
        
    
        <p>Kullanıcıların kendilerine ayrılan bölge içinde sunucu
          yapılandırmasını değiştirebilmelerine izin vermek isterseniz,
          <code>.htaccess</code> dosyalarını kullanmalarına izin vermeniz
          gerekir. Kullanıcının değiştirmesine izin vereceğiniz yönerge türlerini
          <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> yönergesinde
          belirtmeyi ihmal etmeyin. <code>.htaccess</code> dosyalarının kullanımı
          ile ilgili daha ayrıntılı bilgi için <a href="htaccess.html">.htaccess
          öğreticisi</a>ne bakınız.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/public_html.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/access.html.fr.utf8��������������������������������������������������0000664�0001751�0001751�00000035263�14740503670�021630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Contrôle d'accès - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Contrôle d'accès</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/access.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/access.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/access.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Le contrôle d'accès fait référence à tout concept de contrôle
        d'accès à une ressource quelconque. Il est distinct du processus d'<a href="auth.html">authentification et d'autorisation</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Modules et directives concernés</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#host">Contrôle d'accès en fonction de l'hôte du
    client</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#env">Contrôle d'accès en fonction de variables
    arbitraires</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Utilisation de mod_rewrite pour le contrôle
    d'accès</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">Informations complémentaires</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Modules et directives concernés</a></h2>
    
        <p>Plusieurs modules peuvent intervenir dans le contrôle d'accès.
        Les plus importants sont <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> et
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>. Ce document illustre aussi comment
        utiliser <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour le contrôle
        d'accès.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="host" id="host">Contrôle d'accès en fonction de l'hôte du
    client</a></h2>
        <p>
        Si vous souhaitez restreindre l'accès à certaines parties de votre
        site web en fonction de l'addresse de l'hôte de vos visiteurs, le
        plus simple pour y parvenir consiste à utiliser le module
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>.
        </p>
    
        <p>La directive <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> permet d'accorder ou
        d'interdire l'accès à certaines ressources de différentes manières.
        Ces critères d'accès, en conjonction avec les directives <code class="directive"><a href="../mod/mod_authz_core.html#requireall">RequireAll</a></code>, <code class="directive"><a href="../mod/mod_authz_core.html#requireany">RequireAny</a></code>, et <code class="directive"><a href="../mod/mod_authz_core.html#requirenone">RequireNone</a></code>, peuvent être
        combinés d'une manière suffisamment complexe pour
        satisfaire votre politique de contrôle d'accès.</p>
    
        <div class="warning"><p>
        Les directives <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>, <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code>, et <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code> fournies par le module
        <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> sont obsolètes, et sont appelées à
        disparaître dans les versions futures. Il est donc déconseillé de
        les utiliser, et de se fier aux tutoriels qui recommandent leur
        utilisation.
        </p></div>
    
        <p>Les directives Require s'utilisent comme suit :</p>
    
        <pre class="prettyprint lang-config">Require host address
    Require ip ip.address</pre>
    
    
        <p>Dans la première forme, <var>nom-hôte</var> est un nom de domaine
        pleinement qualifié (fqdn), ou un nom de domaine partiel ; vous
        pouvez spécifier plusieurs noms de domaines, si vous le désirez.</p>
    
        <p>Dans la seconde forme, <var>adresse-ip</var> est une adresse IP
        complète, une adresse IP partielle, une paire réseau/masque de
        sous-réseau ou une spécification CIDR de la forme réseau/nnn. Il est
        possible de spécifier des adresses IPv4 ou IPv6.</p>
    
        <p>Voir <a href="../mod/mod_authz_host.html#requiredirectives">la
        documentation de mod_authz_host</a> pour d'autres exemples de cette
        syntaxe.</p>
    
        <p>Vous pouvez insérer le mot-clé <code>not</code> pour inverser un
        critère particulier. Notez que le mot <code>not</code> étant la
        négation d'une valeur, il ne peut pas être utilisé pour autoriser
        ou interdire une requête, car <em>non vrai</em> ne
        sera pas interpreté par httpd comme <em>faux</em>. Ainsi, pour interdire la
        visite d'une page à l'aide d'une négation, le bloc doit contenir un
        élément évalué à vrai ou faux.
        Par exemple, si quelqu'un est en train d'inonder
        votre forum de messages indésirables, vous pouvez ajouter cette ligne pour lui refuser
        l'accès :</p>
    
        <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 10.252.46.165
    &lt;/RequireAll&gt;</pre>
    
    
        <p>Les visiteurs possédant cette adresse (<code>10.252.46.165</code>) ne pourront pas voir le
        contenu concerné par cette directive. Si vous voulez interdire
        l'accès à une machine en fonction de son nom, vous pouvez ajouter
        ceci :</p>
    
        <pre class="prettyprint lang-config">Require not host <var>host.example.com</var>
        </pre>
    
    
        <p>Et si vous voulez interdire l'accès à un domaine particulier,
        vous pouvez spécifier des adresses IP partielles ou des noms de
        domaine, comme ceci :</p>
    
        <pre class="prettyprint lang-config">Require not ip 192.168.205
    Require not host phishers.example.com moreidiots.example
    Require not host gov</pre>
    
    
        <p>Les directives <code class="directive"><a href="../mod/mod_authz_core.html#requireall">RequireAll</a></code>, <code class="directive"><a href="../mod/mod_authz_core.html#requireany">RequireAny</a></code>, et <code class="directive"><a href="../mod/mod_authz_core.html#requirenone">RequireNone</a></code> permettent également de préciser des
        critères d'accès plus complexes.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="env" id="env">Contrôle d'accès en fonction de variables
    arbitraires</a></h2>
    
        <p>Vous pouvez accorder ou refuser l'accès en fonction de variables
        d'environnement arbitraires ou de valeurs d'en-têtes de la requête
        en utilisant la directive <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>. Par exemple, pour interdire l'accès en
        fonction du user-agent (le type de navigateur), vous pouvez
        spécifier ceci :</p>
    
        <pre class="prettyprint lang-config">&lt;If "%{HTTP_USER_AGENT} == 'BadBot'"&gt;
        Require all denied
    &lt;/If&gt;</pre>
    
    
        <p>La syntaxe <code>expr</code> de la directive <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> permet de réécrire
        l'exemple précédent de la manière suivante :</p>
    
    
        <pre class="prettyprint lang-config">Require expr %{HTTP_USER_AGENT} != 'BadBot'</pre>
    
    
        <div class="note"><h3>Avertissement :</h3>
        <p>Contrôler l'accès en fonction de l'en-tête
        <code>User-Agent</code> n'est pas une technique fiable, car cet
        en-tête peut être défini à une valeur quelconque, selon le bon
        vouloir de l'utilisateur.</p>
        </div>
    
        <p>Voir le document à propos des <a href="../expr.html">expressions</a> pour une description plus
        approfondie des syntaxes d'expressions et des variables disponibles.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Utilisation de mod_rewrite pour le contrôle
    d'accès</a></h2>
    
        <p>Le drapeau <code>[F]</code> de la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> permet d'envoyer une
        réponse de type 403 Forbidden. Il vous permet donc d'interdire
        l'accès à une ressource en fonction d'un critère arbitraire.</p>
    
        <p>Par exemple, pour bloquer l'accès à une ressources entre 20h et
        7h du matin, vous pouvez utiliser <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> :</p>
    
        <pre class="prettyprint lang-config">RewriteEngine On
    RewriteCond "%{TIME_HOUR}" "&gt;=20" [OR]
    RewriteCond "%{TIME_HOUR}" "&lt;07"
    RewriteRule "^/fridge"     "-" [F]</pre>
    
    
        <p>Toute requête arrivant après 20h ou avant 7h du matin provoquera
        l'envoi d'une réponse de type 403 Forbidden. Vous pouvez utiliser
        cette technique pour vérifier toutes sortes de critères. En outre,
        si vous le préférez, vous pouvez rediriger ou réécrire la requête.</p>
    
        <p>Notez que la directive <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>, introduite à partir de la version 2.4,
        permet de remplacer le module <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> dans de
        nombreuses situations où il était traditionnellement utilisé, et
        il sera probablement préférable pour vous de tenter de l'utiliser
        avant de vous tourner vers mod_rewrite.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">Informations complémentaires</a></h2>
    
        <p>Le <a href="../expr.html">moteur d'expressions</a> vous fournit
        une grande puissance d'action en fonction de variables du serveur
        arbitraires, et il vous est conseillé de consulter le document
        correspondant pour plus de détails.</p>
    
        <p>De même, vous devez lire la documentation du module
        <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> pour des exemples de combinaison de
        critères d'accès multiples, et en particulier la manière dont ces
        derniers interagissent.</p>
    
        <p>Voir aussi le How-To <a href="auth.html">Authentification and
        autorisation</a>.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/access.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/access.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/access.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/access.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/http2.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000072626�14740503670�021434� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Guide HTTP/2 - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Guide HTTP/2</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/http2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/http2.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/http2.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Ce document est le guide de l'utilisateur de l'implémentation de HTTP/2
        dans Apache httpd. Cette fonctionnalité en est au stade
        <em>de production</em>, et les interfaces et directives devraient donc être
        dorénavant relativement stables.
        </p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#protocol">Le protocole HTTP/2</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#implementation">HTTP/2 dans Apache httpd</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#building">Compilation de httpd avec le support de HTTP/2</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic-config">Configuration de base</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mpm-config">Configuration du MPM</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#clients">Clients</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#tools">Outils efficaces pour déboguer HTTP/2</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#push">Push serveur</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#earlyhints">Suggestions précoces</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="protocol" id="protocol">Le protocole HTTP/2</a></h2>
        
        <p>HTTP/2 est une évolution du protocole de la couche application le plus
        utilisé au monde, HTTP. Cette évolution permet en particulier une utilisation
        plus efficace des ressources réseau. Il ne modifie pas les aspects
        fondamentaux de HTTP (sa sémantique). Entre autres, il y a toujours des
        requêtes, des réponses et des en-têtes. Par conséquent, si vous connaissez
        HTTP/1, vous connaissez déjà 95% de HTTP/2.</p>
        <p>Beaucoup a déjà été écrit à propos de HTTP/2 et de son fonctionnement. La
        documentation la plus officielle est bien entendu sa <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a> (ou <a href="http://httpwg.org/specs/rfc7540.html">cette version au format plus
        lisible</a>). Vous trouverez ici une description des rouages de HTTP/2 dans
        leurs moindres détails.</p>
        <p>Le premier document à lire lorsqu'on ne connaît pas un mécanisme n'est
        cependant pas sa RFC. Il est préférable de comprendre tout d'abord <em>ce
        que</em> ce mécanisme est censé faire, et seulement ensuite de lire sa RFC
        pour comprendre <em>comment</em> il fonctionne. <a href="https://daniel.haxx.se/http2/">http2  explained</a> de Daniel Stenberg
        (l'auteur de <a href="https://curl.haxx.se">curl</a>)
        est un bien meilleur document pour démarrer l'étude de HTTP/2. En outre, de
        nouveaux langages s'ajoutent régulièrement à sa liste de traductions
        disponibles !</p>
        <p>Si vous n'avez pas envie de le lire parce que vous le trouvez trop long,
        voici certains pièges à éviter et nouveaux termes à connaître avant de lire
        ce document :</p>
        <ul>
            <li>A la différence de HTTP/1 qui est en texte pur, HTTP/2 est un
    	<strong>protocole binaire</strong>, et alors que le premier est lisible par
    	un humain (par exemple pour sniffer le trafic réseau), le second ne
    	l'est pas. Voir la <a href="https://http2.github.io/faq/#why-is-http2-binary">FAQ
    	officielle</a> pour plus de détails.</li>
            <li><strong>h2</strong> correspond à HTTP/2 sur TLS (négociation de
    	protocole via ALPN).</li>
            <li><strong>h2c</strong> correspond à HTTP/2 sur TCP.</li>
    	<li>Une <strong>frame</strong> ou trame est la plus petite unité de
    	communication au sein d'une connexion HTTP/2 et comporte une en-tête et
    	une séquence d'octets de longueur variable dont la structure correspond
    	au type de trame. Voir la <a href="http://httpwg.org/specs/rfc7540.html#FramingLayer">section
    	correspondante</a> de la documentation officielle pour plus de
    	détails.</li>
            <li>Un <strong>stream</strong> est un flux bidirectionnel de frames au
    	sein d'une connexion HTTP/2. La notion correspondante dans HTTP/1 est un
    	échange de messages de type requête et réponse. Voir la <a href="http://httpwg.org/specs/rfc7540.html#StreamsLayer">section
    	correspondante</a> de la documentation officielle pour plus de détails.</li>
            <li>HTTP/2 peut gérer <strong>plusieurs streams</strong> de données sur
    	la même connexion TCP, ce qui permet d'éviter le point de blocage
    	classique de HTTP/1 pour les requêtes lentes, et de ne pas avoir à
    	ouvrir de nouvelles connexions TCP pour chaque requête/réponse (les
    	connexions persistantes ou KeepAlive avaient contourné le problème dans
    	HTTP/1 mais ne l'avaient pas entièrement résolu)</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">HTTP/2 dans Apache httpd</a></h2>
        
        <p>Le protocole HTTP/2 est implémenté dans Apache httpd via un module
        propre, pertinemment nommé <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code>. Ce
        module implémente toutes les fonctionnalités décrites par la RFC 7540 et
        supporte les connexions en texte pur (http:), ou sécurisées (https:).
        La variante texte pur se nomme '<code>h2c</code>', et la variante sécurisée
        '<code>h2</code>'. <code>h2c</code> peut être en mode <em>direct</em> ou
        <code>Upgrade:</code> via une requête initiale en HTTP/1.</p>
        <p><a href="#push">Server Push</a> est une nouvelle fonctionnalité offerte
        aux développeurs web par HTTP/2. La section correspondante de ce document
        vous indiquera comment votre application peut en tirer parti.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="building" id="building">Compilation de httpd avec le support de HTTP/2</a></h2>
        
        <p><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> se base sur la bibliothèque
        de <a href="https://nghttp2.org">nghttp2</a> pour son implémentation. Pour
        pouvoir compiler <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code>, <code>libnghttp2</code> version
        1.2.1. ou supérieure doit être installée dans votre système.</p>
        <p>Pour déclencher la compilation de <code>mod_http2</code>, vous devez
        ajouter l'argument '<code>--enable-http2</code>' au script
        <code>./configure</code> que vous exécutez à la racine de l'arborescence des
        sources de httpd. Si <code>libnghttp2</code> est installée dans un
        répertoire non connu du chemin de vos bibliothèques, vous devez indiquer ce
        répertoire au script <code>./configure</code> via l'argument
        '<code>--with-nghttp2=&lt;path&gt;</code>'.</p>
        <p>Alors que cette méthode de compilation conviendra à la plupart, certains
        préféreront lier statiquement <code>nghttp2</code> à ce module. Pour ce
        faire, utilisez l'argument <code>--enable-nghttp2-staticlib-deps</code>.
        Cette méthode est pratiquement la même que celle utilisée pour lier
        statiquement openssl à <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.</p>
        <p>En parlant de SSL, vous devez savoir que la plupart des navigateurs ne
        communiqueront en HTTP/2 que sur des URLs sécurisées de type
        <code>https:</code> ; votre serveur doit donc supporter SSL. Mais de plus,
        votre bibliothèque SSL devra supporter l'extension <code>ALPN</code>. Enfin,
        si la bibliothèque que vous utilisez est OpenSSL, sa version devra être
        1.0.2. ou supérieure.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic-config" id="basic-config">Configuration de base</a></h2>
        
    
        <p>Maintenant que vous disposez d'un binaire <code>httpd</code> compilé avec le
        module <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code>, l'activation de ce dernier nécessite un
        minimum de configuration supplémentaire. En premier lieu, comme pour tout
        module Apache, vous devez le charger :</p>
        <pre class="prettyprint lang-config">LoadModule http2_module modules/mod_http2.so</pre>
    
    
        <p>La seconde directive que vous devez ajouter à votre fichier de
        configuration est</p>
        <pre class="prettyprint lang-config">Protocols h2 http/1.1</pre>
    
        <p>Ceci permet de définir h2, la variante sécurisée, comme le protocole
        préféré pour les connexions à votre serveur. Si vous souhaitez que toutes les
        variantes soient disponibles, utilisez la directive suivante :</p>
        <pre class="prettyprint lang-config">Protocols h2 h2c http/1.1</pre>
    
        <p>Selon l'endroit où vous placez cette directive, elle affectera l'ensemble
        de votre serveur, ou seulement un ou plusieurs serveurs virtuels. Vous
        pouvez aussi l'imbriquer comme dans l'exemple suivant :</p>
        <pre class="prettyprint lang-config">Protocols http/1.1
    &lt;VirtualHost ...&gt;
        ServerName test.example.org
        Protocols h2 http/1.1
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Seules les connexions en HTTP/1 seront alors permises, sauf pour le serveur
        virtuel <code>test.example.org</code> qui acceptera aussi les connexions SSL
        en HTTP/2.</p>
        <div class="note"><h3>Utilisez une chaîne d'algorithmes de chiffrement forte</h3>
        <p>La directive <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code> doit
        être définie avec une chaîne d'algorithmes de chiffrement TLS forte. Même si
        la version actuelle de <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> n'impose pas d'algorithmes
        de chiffrement particuliers, la plupart des clients le font. Faire pointer
        un navigateur vers un serveur où <code>h2</code> est activé avec une chaîne
        d'algorithmes de chiffrement inappropriée entraînera un rejet et une
        retrogradation vers HTTP 1.1. C'est une erreur que l'on fait couramment
        lorsqu'on configure httpd pour HTTP/2 pour la première fois ; donc gardez la
        à l'esprit si vous voulez éviter de longues sessions de débogage ! Si vous
        voulez être sûr de définir une chaîne d'algorithmes de chiffrement
        appropriée, évitez ceux qui sont listés dans la <a href="http://httpwg.org/specs/rfc7540.html#BadCipherSuites"> </a>liste des
        algorithmes de chiffrement TLS HTTP/2 à proscrire.</p>
        </div>
        <p>L'ordre des protocoles indiqués est aussi important. Par défaut, le
        premier sera le protocole préféré. Lorsqu'un client offre plusieurs choix,
        c'est le plus à gauche qui sera sélectionné. Dans</p>
        <pre class="prettyprint lang-config">Protocols http/1.1 h2</pre>
    
        <p>le protocole préféré sera HTTP/1 et il sera toujours sélectionné sauf si
        un client ne supporte <em>que</em> h2. Comme nous souhaitons communiquer en
        HTTP/2 avec les clients qui le supportent, la meilleure définition de la
        directive est</p>
        <pre class="prettyprint lang-config">Protocols h2 h2c http/1.1</pre>
    
    
        <p>Toujours à propos de l'ordre des protocoles, le client a lui aussi ses
        propres préférences en la matière. À ce titre, si vous le souhaitez, vous
        pouvez configurer votre serveur pour qu'il sélectionne non plus son
        protocole préféré, mais au contraire le protocole préféré
        du client :</p>
        <pre class="prettyprint lang-config">ProtocolsHonorOrder Off</pre>
    
        <p>Avec cette directive, l'ordre des protocoles que <em>vous</em> avez
        défini devient caduque et seul l'ordre défini par le client sera pris en
        compte.</p>
        <p>Une dernière chose : les protocoles que vous définissez ne sont pas
        vérifiés quant à leurs validité ou orthographe. Vous pouvez très bien
        définir des protocoles qui n'existent pas, et il n'est donc pas nécessaire
        de filtrer le contenu de la directive <code class="directive"><a href="../mod/core.html#protocols">Protocols</a></code> avec des vérifications de type
        <code class="directive"><a href="../mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>.</p>
        <p>Pour des conseils plus avancés à propos de la configuration, voir la <a href="../mod/mod_http2.html">Documentation de mod_http2</a>, et en particulier
        la section à propos de la <a href="../mod/mod_http2.html#dimensioning">consommation supplémentaire de
        ressources</a>, ainsi que la section expliquant comment gérer les <a href="../mod/mod_http2.html#misdirected">serveurs multiples avec certificat
        commun</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mpm-config" id="mpm-config">Configuration du MPM</a></h2>
        
    
        <p>Tous les modules multiprocessus (MPM) fournis avec httpd supportent
        HTTP/2. Cependant, si vous utilisez le MPM <code class="module"><a href="../mod/prefork.html">prefork</a></code>, vous allez
        faire face à de sévères restrictions.</p>
        <p>Avec le MPM <code class="module"><a href="../mod/prefork.html">prefork</a></code>, <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> ne traitera
        qu'une requête à la fois par connexion alors que les clients tels que les
        navigateurs internet envoient de nombreuses requêtes au même moment. Si
        l'une d'entre elles est longue à traiter (ou implique une longue
        interrogation), les autres requêtes seront mises en attente.</p>
        <p>Par défaut, <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> ne passe pas outre cette limitation pour
        la simple et bonne raison que le MPM <code class="module"><a href="../mod/prefork.html">prefork</a></code> n'est aujourd'hui
        choisi que si vous exécutez des moteurs de traitement qui ne sont pas préparés
        pour le multithreading (par exemple qui se crashent lorsque plusieurs
        requêtes arrivent).</p>
        <p>Si votre plateforme et votre installation de httpd le supportent, la
        meilleur solution consiste actuellement à utiliser le MPM
        <code class="module"><a href="../mod/event.html">event</a></code>.
        </p>
        <p>Si vous n'avez pas d'autre choix que d'utiliser le MPM
        <code class="module"><a href="../mod/prefork.html">prefork</a></code>, mais souhaitez tout de même traiter plusieurs requêtes
        simultanément, vous pouvez jouer avec la directive <code class="directive"><a href="../mod/mod_http2.html#h2minworkers">H2MinWorkers</a></code>, sans garantie que cela
        fonctionne.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="clients" id="clients">Clients</a></h2>
        
        <p>La plupart des navigateurs modernes supportent HTTP/2, mais seulement sur
        des connexions SSL : Firefox v43, Chrome v45, Safari v9, iOS Safari v9,
        Opera v35, Chrome pour Android v49 et
        Internet Explorer v11 sous Windows10 (selon cette <a href="http://caniuse.com/#search=http2">source</a>).</p>
        <p>D'autres clients et serveurs sont listés dans le <a href="https://github.com/http2/http2-spec/wiki/Implementations">wiki des
        implémentations</a> ; entre autres des implémentations pour c, c++, common
        lisp, dart, erlang, haskell, java, nodejs, php, python, perl, ruby, rust,
        scala et swift.</p>
        <p>De nombreuses implémentations clientes autres que les navigateurs
        supportent HTTP/2 en texte pur, h2c. L'une des plus efficaces d'entre elles
        est <a href="https://curl.haxx.se">curl</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tools" id="tools">Outils efficaces pour déboguer HTTP/2</a></h2>
        
        <p>Le premier d'entre eux est bien entendu <a href="https://curl.haxx.se">curl</a>. Assurez-vous au préalable que votre
        version supporte HTTP/2 en vérifiant ses <code>Fonctionnalités</code> :</p>
        <pre class="prettyprint lang-config">    $ curl -V
        curl 7.45.0 (x86_64-apple-darwin15.0.0) libcurl/7.45.0 OpenSSL/1.0.2d zlib/1.2.8 nghttp2/1.3.4
        Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 [...]
        Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP <strong>HTTP2</strong>
        </pre>
    
        <div class="note"><h3>homebrew sous Mac OS :</h3>
        brew install curl --with-openssl --with-nghttp2
        </div>
        <p>Pour une inspection en profondeur : <a href="https://wiki.wireshark.org/HTTP2">wireshark</a>.</p>
        <p>Le paquet <a href="https://nghttp2.org">nghttp2</a> inclut aussi des
        outils comme :</p>
        <ul>
            <li><a href="https://nghttp2.org/documentation/nghttp.1.html">nghttp</a>
    	- permet de visualiser les trames HTTP/2 et ainsi de se faire une meilleure
    	  idée du protocole.</li>
            <li><a href="https://nghttp2.org/documentation/h2load-howto.html">h2load</a> -
    	permet de tester votre serveur dans des conditions extremes.</li>
        </ul>
        <p>Chrome fournit des journaux détaillés des connexions HTTP/2 via la page
        <a href="chrome://net-internals/#http2">special net-internals page</a>. Il y
        a aussi cette extension intéressante pour <a href="https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=en">Chrome</a>
        et <a href="https://addons.mozilla.org/en-us/firefox/addon/spdy-indicator/">Firefox</a>
        qui permet d'indiquer que votre navigateur utilise HTTP/2.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="push" id="push">Push serveur</a></h2>
        
        <p>Le protocole HTTP/2 permet au serveur de proposer (PUSH) des réponses
        pour lesquelles le client n'a rien demandé. La communication autour de ces
        réponses est du style : "voici une requête que vous n'avez jamais
        envoyée, et la réponse vous parviendra bientôt tout de même ..."</p>
        <p>Il y a cependant des conditions : le client peut désactiver cette
        fonctionnalité et le serveur ne pourra alors lui proposer des réponses que
        pour les requêtes qu'il a effectivement envoyées.</p>
        <p>Cette fonctionnalité a pour but de permettre au serveur d'envoyer au
        client des ressources dont il va probablement avoir besoin : par exemple une
        ressource css ou javascript appartenant à une page html que le client a
        demandée, un jeu d'images référencé par un css, etc...</p>
        <p>Cette anticipation a pour avantage de permettre au client d'économiser le
        temps qu'il lui aurait fallu pour envoyer une requête, quelques
        millisecondes à une demi-seconde en fonction de l'éloignement du serveur.
        Elle a cependant pour inconvénient d'imposer au client le téléchargement de
        ressources qu'il possède peut-être déjà dans son cache. Bien entendu, HTTP/2
        permet d'annuler prématurément de telles requêtes, mais des ressources sont
        tout de même gaspillées.</p>
        <p>En résumé : il n'existe pas encore de stratégie efficace pour faire le
        meilleur usage de cette fonctionnalité de HTTP/2 et tout le monde en est
        encore au stade de l'expérimentation. À ce titre, voici des conseils pour
        procéder vous-même à ces expérimentations :</p>
        <p><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> inspecte l'en-tête de la réponse et recherche les
        en-têtes <code>Link</code> sous un certain format :</p>
        <pre class="prettyprint lang-config">Link &lt;/xxx.css&gt;;rel=preload, &lt;/xxx.js&gt;; rel=preload</pre>
    
        <p>Si la connexion supporte PUSH, ces deux ressources seront envoyées au
        client. En tant que développeur web vous pouvez définir ces en-têtes soit
        directement au niveau de la réponse de votre application, soit en
        configurant votre serveur via</p>
        <pre class="prettyprint lang-config">&lt;Location /xxx.html&gt;
        Header add Link "&lt;/xxx.css&gt;;rel=preload"
        Header add Link "&lt;/xxx.js&gt;;rel=preload"
    &lt;/Location&gt;</pre>
    
        <p>Si vous souhaitez utiliser des liens <code>preload</code> sans déclencher
        de PUSH, vous pouvez utiliser le paramètre <code>nopush</code> comme suit :</p>
        <pre class="prettyprint lang-config">Link &lt;/xxx.css&gt;;rel=preload;nopush</pre>
    
        <p>Vous pouvez aussi désactiver les PUSHes pour l'ensemble de votre
        serveur via la directive</p>
        <pre class="prettyprint lang-config">H2Push Off</pre>
    
        <p>À savoir aussi :</p>
        <p>Le module maintient un journal des ressources ayant fait l'objet d'un
        PUSH pour chaque connexion (en général des condensés hash des URLs), et
        n'effectuera pas deux fois un PUSH pour la même ressource. Cependant,
        lorsque la connexion est fermée, le journal de ses PUSHes est supprimé.</p>
        <p>Certains développeurs planchent sur la manière de permettre au client
        d'informer le serveur des ressources qu'il possède déjà dans son cache afin
        d'éviter les PUSHes pour ces dernières, mais ceci n'en est actuellement qu'à
        un stade très expérimental.</p>
        <p>L'<a href="https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00">
        en-tête Accept-Push-Policy</a> est un autre dispositif expérimental
        implémenté dans <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> ; il permet au client de définir pour
        chaque requête quels genres de PUSHes il accepte.</p>
      
    
        <p>
        La fonctionnalité PUSH n'apportera pas toujours le gain de performances dans
        l'obtention de réponses aux requêtes. Vous trouverez plusieurs études sur ce
        sujet sur internet qui en expliquent les avantages et inconvénients et
        comment les particularités des clients et du réseau en influencent le
        fonctionnement. Par exemple, le seul fait que le serveur PUSHes une
        ressource n'implique pas forcément que le navigateur l'utilisera.</p>
        <p>Ce qui influence le plus la réponse PUSHed, c'est la requête qui a été
        simulée. En effet, l'URL de la requête pour un PUSH est fournie par
        l'application, mais d'où viennent les en-têtes ? Par exemple, La requête
        PUSH requiert-elle un en-tête <code>accept-language</code> et si oui, quelle
        sera sa valeur ?</p>
        <p>httpd va consulter la requête originale (celle qui a déclenché le PUSH)
        et copier les en-têtes suivants vers la requête PUSH :
        <code>user-agent</code>, <code>accept</code>, <code>accept-encoding</code>,
        <code>accept-language</code> et <code>cache-control</code>.</p>
        <p>Tous les autres en-têtes sont ignorés. Les cookies eux non plus ne seront
        pas copiés. PUSHer des ressources qui requièrent la présence d'un cookie ne
        fonctionnera pas. Ceci peut être sujet à débat, mais tant que ce ne sera pas
        clairement discuté avec les navigateurs, restons prudents et évitons
        d'exposer les cookies là où ils ne sont pas censés être visibles.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="earlyhints" id="earlyhints">Suggestions précoces</a></h2>
        
        <p>A l'instar des ressources PUSHées, une autre méthode consiste à envoyer
        des en-têtes <code>Link</code> au client avant même que la réponse ne soit
        prête. Cette méthode utilise la fonctionnalité appelée "Suggestions
        précoces" (Early Hints) décrite dans la <a href="https://tools.ietf.org/html/rfc8297">RFC 8297</a>.</p>
        <p>Pour utiliser cette fonctionnalité, vous devez l'activer explicitement
        sur le serveur via :</p>
        <pre class="prettyprint lang-config">H2EarlyHints on</pre>
    
        <p>Elle n'est en effet pas activée par défaut car certains navigateurs
        anciens perdent pied avec de telles réponses.</p>
        <p>Une fois cette fonctionnalité activée, vous pouvez utiliser la directive
        <code class="directive"><a href="../mod/mod_http2.html#h2pushresource">H2PushResource</a></code> pour déclencher les
        suggestions précoces et les PUSHes de ressources :</p>
        <pre class="prettyprint lang-config">&lt;Location /xxx.html&gt;
        H2PushResource /xxx.css
        H2PushResource /xxx.js
    &lt;/Location&gt;</pre>
    
        <p>Le serveur enverra alors au client une réponse <code>"103 Early
        Hints"</code> dès qu'il <em>commencera</em> à traiter la requête. Selon
        votre application web, cet envoi peut intervenir beaucoup plus tôt que le
        moment où les premiers en-têtes de réponse auront été déterminés.</p>
        <p>Si <code class="directive"><a href="../mod/mod_http2.html#h2push">H2Push</a></code> est activé, ceci
        déclenchera aussi le PUSH juste après la réponse 103. Mais si <code class="directive"><a href="../mod/mod_http2.html#h2push">H2Push</a></code> n'est pas activé, la réponse 103 sera
        quand-même envoyée au client.</p>
        </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/http2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/http2.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/http2.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/http2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/htaccess.html.pt-br��������������������������������������������������0000664�0001751�0001751�00000062761�14743132254�021716� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="pt-br" xml:lang="pt-br"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Tutorial do Apache: arquivos .htaccess - Servidor HTTP Apache Vers&#227;o 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Gloss&#225;rio</a> | <a href="../sitemap.html">Mapa do site</a></p>
    <p class="apache">Servidor HTTP Apache Vers&#227;o 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documenta&#231;&#227;o</a> &gt; <a href="../">Vers&#227;o 2.4</a> &gt; <a href="./">How-To / Tutoriais</a></div><div id="page-content"><div id="preamble"><h1>Tutorial do Apache: arquivos .htaccess</h1>
    <div class="toplang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta tradu&#231;&#227;o pode estar desatualizada.
            Confira a vers&#227;o em Ingl&#234;s para mudan&#231;as recentes.</div>
    
    <p>Arquivos <code>.htaccess</code> oferecem um meio de fazer mudan&#231;as
     nas configura&#231;&#245;es por-diret&#243;rio.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Arquivos .htaccess </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">O que eles s&#227;o/Como us&#225;-los</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#when">Quando (n&#227;o) usar arquivos .htaccess</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#how">Como as diretrizes s&#227;o aplicadas</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#auth">Exemplo de Autentica&#231;&#227;o</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssi">Exemplo de Server Side Includes</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">Exemplo de CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">Resolvendo Problemas</a></li>
    </ul><h3>Veja tamb&#233;m</h3><ul class="seealso"><li><a href="#comments_section">Coment&#225;rios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Arquivos .htaccess </a></h2>
        <table class="related"><tr><th>M&#243;dulos Relacionados</th><th>Diretrizes Relacionadas</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li><li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li><li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">O que eles s&#227;o/Como us&#225;-los</a></h2>
    
    
        <p>Os arquivos <code>.htaccess</code> (ou "arquivos de
        configura&#231;&#227;o distribu&#237;da") oferecem um meio de fazer mudan&#231;as nas
        configura&#231;&#245;es por-diret&#243;rio. Um arquivo, contendo uma ou mais
        diretrizes de configura&#231;&#245;es, &#233; colocado em um diret&#243;rio 
        em particular, e as diretrizes se aplicam para aquele diret&#243;rio e todos 
        os seu subdiret&#243;rios subseq&#252;entes.</p>
    
        <div class="note"><h3>Nota:</h3>
          <p>Se voc&#234; quiser renomear o seu arquivo <code>.htaccess</code>
          para outro nome, voc&#234; deve usar a diretriz <code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code>. Por exemplo, se voc&#234;
          prefere que o arquivo se chame <code>.config</code>, ent&#227;o voc&#234; 
          pode adicionar a seguinte linha ao seu arquivo de configura&#231;&#227;o
          do servidor:</p>
    
          <div class="example"><p><code>
            AccessFileName .config
          </code></p></div>
        </div>
    
        <p>No geral, arquivos <code>.htaccess</code> usam a mesma sintaxe
        que os <a href="../configuring.html#syntax">arquivos de
        configura&#231;&#227;o principal</a>. O que voc&#234; pode colocar nesses
        arquivos &#233; determinado pele diretriz <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>. Essa diretriz especifica,
        em categorias, quais diretrizes ser&#227;o aceitas caso sejam
        encontradas em um arquivo <code>.htaccess</code>.  Se uma diretriz
        for permitida em um arquivo <code>.htaccess</code>, a documenta&#231;&#227;o
        para essa diretriz ir&#225; conter uma se&#231;&#227;o <em>Override</em>,
        especificando que valor precisa estar em <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> para que esta diretriz
        seja permitida.</p>
    
        <p>Por exemplo, se voc&#234; procurar na documenta&#231;&#227;o pela diretriz
        <code class="directive"><a href="../mod/core.html#adddefaultcharset">AddDefaultCharset</a></code>, voc&#234;
        achar&#225; que ela &#233; permitida nos arquivos <code>.htaccess</code>.
        (Veja a linha Contexto no sum&#225;rio das diretivas.) A
        linha <a href="../mod/directive-dict.html#Context">Override</a> l&#234;
        <code>FileInfo</code>. Ent&#227;o, voc&#234; deve ao menos ter
        <code>AllowOverride FileInfo</code> para que essa diretriz seja
        aceita nos arquivos <code>.htaccess</code>.</p>
    
        <div class="example"><h3>Exemplo:</h3><table>
            <tr>
              <td><a href="../mod/directive-dict.html#Context">Contexto:</a></td>
              <td>configura&#231;&#227;o do servidor, hospedeiros virtuais, diret&#243;rio, .htaccess</td>
            </tr>
    
            <tr>
              <td><a href="../mod/directive-dict.html#Override">Override:</a></td>
              <td>FileInfo</td>
            </tr>
          </table></div>
    
        <p>Se voc&#234; estiver incerto se uma diretriz em particular &#233;
        aceita em um arquivo <code>.htaccess</code>, procure na
        documenta&#231;&#227;o por essa diretriz, e verifique a linha de
        Contexto por ".htaccess".</p> </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="when" id="when">Quando (n&#227;o) usar arquivos .htaccess</a></h2>
    
        <p>No geral, voc&#234; nunca deve usar arquivos <code>.htaccess</code>
        a n&#227;o ser que voc&#234; n&#227;o tenha acesso ao arquivo de configura&#231;&#227;o
        principal do servidor. Existe, por exemplo, um erro de concep&#231;&#227;o
        que dita que a autentica&#231;&#227;o de usu&#225;rios sempre deve
        ser feita usando os arquivos <code>.htaccess</code>. Esse
        simplesmente n&#227;o &#233; o caso. Voc&#234; pode usar as configura&#231;&#245;es de
        autentica&#231;&#227;o de usu&#225;rio no arquivo de configura&#231;&#227;o principal do
        servidor, e isso &#233;, de fato, a maneira mais adequada de se fazer
        as coisas.</p>
    
        <p>Arquivos <code>.htaccess</code> devem ser usados em casos onde
        os provedores de conte&#250;do do site precisem fazer mudan&#231;as na
        configura&#231;&#227;o do servidor por-diret&#243;rio, mas n&#227;o tem
        acesso <em>root</em> ao sistema do servidor. Caso o administrador do 
        servidor n&#227;o esteja disposto a fazer mudan&#231;as freq&#252;entes nas
        configura&#231;&#245;es do servidor, &#233; desej&#225;vel permitir que os 
        usu&#225;rios possam fazer essas mudan&#231;as atrav&#233;s de arquivos
        <code>.htaccess</code> eles mesmos. Isso &#233; particularmente
        verdade, por exemplo, em casos onde provedores est&#227;o fornecendo
        m&#250;ltiplos sites para usu&#225;rios em apenas uma m&#225;quina, e querem que
        seus usu&#225;rios possam alterar suas configura&#231;&#245;es.</p>
    
        <p>No entanto, de modo geral, o uso de arquivos <code>.htaccess</code>
        deve ser evitado quando poss&#237;vel. Quaisquer configura&#231;&#245;es 
        que voc&#234; considerar acrescentar em um arquivo <code>.htaccess</code>, podem
        ser efetivamente colocadas em uma se&#231;&#227;o <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> no arquivo principal de
        configura&#231;&#227;o de seu servidor.</p>
    
        <p>Existem duas raz&#245;es principais para evitar o uso de arquivos
        <code>.htaccess</code>.</p>
    
        <p>A primeira delas &#233; a performance. Quando <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> &#233; configurado para
        permitir o uso de arquivos <code>.htaccess</code>, o Apache procura
        em todos diret&#243;rios por arquivos <code>.htaccess</code>.  
        Logo, permitir arquivos <code>.htaccess</code> causa um impacto na 
        performance, mesmo sem voc&#234; us&#225;-los de fato! Al&#233;m disso, 
        o arquivo <code>.htaccess</code> &#233; carregado toda vez que um documento 
        &#233; requerido.</p>
    
        <p>Al&#233;m disso, note que o Apache precisa procurar pelos arquivos
        <code>.htaccess</code> em todos os diret&#243;rios superiores, para ter
        o complemento total de todas as diretivas que devem ser
        aplicadas. (Veja a se&#231;&#227;o <a href="#how">como as diretrizes s&#227;o
        aplicadas</a>.) Ent&#227;o, se um arquivo de um diret&#243;rio
        <code>/www/htdocs/example</code> &#233; requerido, o Apache precisa
        procurar pelos seguintes arquivos:</p>
    
        <div class="example"><p><code>
          /.htaccess<br />
          /www/.htaccess<br />
          /www/htdocs/.htaccess<br />
          /www/htdocs/example/.htaccess
        </code></p></div>
    
        <p>Assim, para cada acesso de arquivo fora desse diret&#243;rio,
        existem 4 acessos ao sistema de arquivos adicionais, mesmo
        que nenhum desses arquivos estejam presentes. (Note que esse
        s&#243; ser&#225; o caso se os arquivos <code>.htaccess</code>
        estiverem habilitados para <code>/</code>, o que
        normalmente n&#227;o &#233; o verdade.)</p>
    
        <p>A segunda considera&#231;&#227;o &#233; relativa &#224; seguran&#231;a. 
        Voc&#234; est&#225; permitindo que os usu&#225;rios modifiquem as 
        configura&#231;&#245;es do servidor, o que pode resultar em mudan&#231;as 
        que podem fugir ao seu controle. Considere com cuidado se voc&#234; quer 
        ou n&#227;o dar aos seus usu&#225;rios esses privil&#233;gios. Note tamb&#233;m 
        que dar aos usu&#225;rios menos privil&#233;gios que eles precisam, acarreta em 
        pedidos de suporte t&#233;cnico adicionais. Tenha certeza que voc&#234; comunicou
        aos usu&#225;rios que n&#237;vel de privil&#233;gios voc&#234; os deu. 
        Especificar exatamente o que voc&#234; configurou na diretriz <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>, e direcion&#225;-los para a
        documenta&#231;&#227;o relevante, ir&#225; poup&#225;-lo de muita confus&#227;o 
        depois.</p>
    
        <p>Perceba que &#233; exatamente equivalente colocar o arquivo
        <code>.htaccess</code> em um diret&#243;rio
        <code>/www/htdocs/example</code> contendo uma diretriz, e
        adicionar a mesma diretriz em uma se&#231;&#227;o <em>Directory</em>
        <code>&lt;Directory /www/htdocs/example&gt;</code> na configura&#231;&#227;o
        principal do seu servidor:</p>
    
        <p>Arquivo <code>.htaccess</code> em <code>/www/htdocs/example</code>:</p>
    
        <div class="example"><h3>Conte&#250;do de um arquivo .htaccess em
        <code>/www/htdocs/example</code></h3><p><code>
            AddType text/example .exm
        </code></p></div>
    
        <div class="example"><h3>Se&#231;&#227;o do seu arquivo <code>httpd.conf</code></h3><p><code>
          &lt;Directory /www/htdocs/example&gt;<br />
          <span class="indent">
            AddType text/example .exm<br />
          </span>
          &lt;/Directory&gt;
        </code></p></div>
    
        <p>No entanto, adicionando isso ao seu arquivo de configura&#231;&#227;o do
        servidor resultar&#225; em uma menor perda de performance, na medida que
        a configura&#231;&#227;o &#233; carregada no momento da inicializa&#231;&#227;o do
        servidor, ao inv&#233;s de toda que que um arquivo &#233; requerido.</p>
    
        <p>O uso de arquivos <code>.htaccess</code> pode ser totalmente
        desabilitado, ajustando a diretriz <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> para <code>none</code>:</p>
    
        <div class="example"><p><code>
          AllowOverride None
        </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="how" id="how">Como as diretrizes s&#227;o aplicadas</a></h2>
    
        <p>As diretrizes de configura&#231;&#227;o que se encontram em um arquivo
        <code>.htaccess</code> s&#227;o aplicadas para o diret&#243;rio no qual o
        arquivo <code>.htaccess</code> se encontra, e para todos os
        subdiret&#243;rios ali presentes. Mas, &#233; importante lembrar tamb&#233;m que
        podem existir arquivos <code>.htaccess</code> no diret&#243;rios
        superiores. As diretrizes s&#227;o aplicadas na ordem que s&#227;o
        achadas. Logo, um arquivo <code>.htaccess</code> em um diret&#243;rio
        em particular, pode sobrescrever as diretrizes encontradas em um
        diret&#243;rio acima deste em sua respectiva &#225;rvore. Estes, por sua vez,
        podem ter suas diretrizes sobrescritas por diretrizes ainda mais
        acima, ou no pr&#243;prio arquivo de configura&#231;&#227;o principal do
        servidor.</p>
    
        <p>Exemplo:</p>
    
        <p>No diret&#243;rio <code>/www/htdocs/example1</code> n&#243;s temos
        um arquivo <code>.htaccess</code> contendo o seguinte:</p>
    
        <div class="example"><p><code>
           Options +ExecCGI
        </code></p></div>
    
        <p>(Nota: voc&#234; deve ter "<code>AllowOverride Options</code>" para
        permitir o uso da diretriz "<code class="directive"><a href="../mod/core.html#options">Options</a></code>" nos arquivos
        <code>.htaccess</code> .)</p>
    
        <p>No diret&#243;rio <code>/www/htdocs/example1/example2</code> n&#243;s temos
        um arquivo <code>.htaccess</code> contendo:</p>
    
        <div class="example"><p><code>
           Options Includes
        </code></p></div>
    
        <p>Devido a esse segundo arquivo <code>.htaccess</code>, no
        diret&#243;rio <code>/www/htdocs/example1/example2</code>, a execu&#231;&#227;o
        de scripts CGI n&#227;o &#233; permitida, pois somente <code>Options
        Includes</code> est&#225; em efeito, o que sobrescreve completamente
        quaisquer outros ajustes previamente configurados.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="auth" id="auth">Exemplo de Autentica&#231;&#227;o</a></h2>
    
        <p>Se voc&#234; veio diretamente &#224; esta parte do documento para
        aprender como fazer autentica&#231;&#227;o, &#233; importante notar uma
        coisa. Existe uma concep&#231;&#227;o errada, mas muito comum, de que &#233;
        necess&#225;rio o uso de arquivos <code>.htaccess</code> para implementar 
        a autentica&#231;&#227;o por senha. Este n&#227;o &#233; o caso. Colocar 
        diretrizes de senha em uma se&#231;&#227;o <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>, no seu arquivo principal de
        configura&#231;&#227;o do servidor, &#233; a melhor maneira de se implementar
        isto, e os arquivos <code>.htaccess</code> devem ser usados apenas
        se voc&#234; n&#227;o tem acesso ao arquivo principal de configura&#231;&#227;o do
        servidor. Veja <a href="#when">acima</a> a discuss&#227;o sobre quando
        voc&#234; deve e quando n&#227;o deve usar os arquivos
        <code>.htaccess</code>.</p>
    
        <p>Dito isso, se voc&#234; ainda acredita que precisa usar um arquivo
        <code>.htaccess</code>, a configura&#231;&#227;o a seguir provavelmente
        funcionar&#225; para voc&#234;.</p>
    
        <p>Conte&#250;do de um arquivo <code>.htaccess</code>:</p>
    
        <div class="example"><p><code>
          AuthType Basic<br />
          AuthName "Password Required"<br />
          AuthUserFile /www/passwords/password.file<br />
          AuthGroupFile /www/passwords/group.file<br />
          Require Group admins
        </code></p></div>
    
        <p>Note que <code>AllowOverride AuthConfig</code> precisa estar
        habilitado para que estas diretrizes tenham efeito.</p>
    
        <p>Por favor veja o <a href="auth.html">tutorial de
        autentica&#231;&#227;o</a> para uma discuss&#227;o mais completa sobre
        autentica&#231;&#227;o e autoriza&#231;&#227;o.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssi" id="ssi">Exemplo de Server Side Includes</a></h2>
    
        <p>Outro uso comum de arquivos <code>.htaccess</code> &#233; ativar o
        Server Side Includes para um diret&#243;rio em particular. Isto pode
        ser feito com as seguintes diretrizes de configura&#231;&#227;o, colocadas em
        um arquivo <code>.htaccess</code> no diret&#243;rio desejado:</p>
    
        <div class="example"><p><code>
           Options +Includes<br />
           AddType text/html shtml<br />
           AddHandler server-parsed shtml
        </code></p></div>
    
        <p>Note que ambos <code>AllowOverride Options</code> e
        <code>AllowOverride FileInfo</code> precisam estar habilitados
        para essas diretrizes terem efeito.</p>
    
        <p>Por favor veja o <a href="ssi.html">tutorial de SSI</a> para
        uma discuss&#227;o mais completa sobre server-side includes.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">Exemplo de CGI</a></h2>
    
        <p>Finalmente, voc&#234; pode querer que um arquivo
        <code>.htaccess</code> permita a execu&#231;&#227;o de programas CGI em um
        diret&#243;rio em particular. Isto pode ser implementado com as
        seguintes configura&#231;&#245;es:</p>
    
        <div class="example"><p><code>
           Options +ExecCGI<br />
           AddHandler cgi-script cgi pl
        </code></p></div>
    
        <p>Alternativamente, se voc&#234; desejar que todos os arquivos de um
        dado diret&#243;rio, sejam considerados programas CGI, isso pode ser
        feito com a seguinte configura&#231;&#227;o:</p>
    
        <div class="example"><p><code>
           Options +ExecCGI<br />
           SetHandler cgi-script
        </code></p></div>
    
        <p>Note que ambos <code>AllowOverride Options</code> e
        <code>AllowOverride FileInfo</code> precisam estar habilitados
        para que essas diretrizes tenham quaisquer efeito.</p>
    
        <p>Por favor veja o <a href="cgi.html">tutorial de CGI
        tutorial</a> para uma discuss&#227;o mais completa sobre programa&#231;&#227;o
        e configura&#231;&#227;o CGI.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">Resolvendo Problemas</a></h2>
    
        <p>Quando voc&#234; adiciona diretrizes de configura&#231;&#227;o em um arquivo
        <code>.htaccess</code>, e n&#227;o obt&#233;m o efeito desejado, existe uma
        s&#233;rie de pontos que podem estar errados.</p>
    
        <p>Mais comumente, o problema &#233; que a diretriz <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> n&#227;o est&#225; habilitada
        corretamente para que as suas diretrizes de configura&#231;&#245;es sejam
        honradas. Verifique se voc&#234; n&#227;o possui <code>AllowOverride
        None</code> ajustado para o escopo do arquivo em quest&#227;o. Um bom
        meio de testar isso &#233; colocar "lixo" em seu arquivo
        <code>.htaccess</code> e recarreg&#225;-lo. Se n&#227;o for gerado nenhum
        erro do servidor, certamente voc&#234; tem <code>AllowOverride
        None</code> habilitado.</p>
    
        <p>Se, por outro lado, voc&#234; est&#225; obtendo erros do servidor ao
        tentar acessar documentos, verifique o registro de erros do
        Apache. Ele provavelmente ir&#225; indicar que a diretriz usada em
        seu arquivo <code>.htaccess</code> n&#227;o &#233; permitida.
        Alternativamente, ele pode acusar erros de sintaxe que voc&#234; ter&#225;
        que corrigir.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Coment&#225;rios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licenciado sob a <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Gloss&#225;rio</a> | <a href="../sitemap.html">Mapa do site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������httpd-2.4.64/docs/manual/howto/index.html.ko.euc-kr�������������������������������������������������0000664�0001751�0001751�00000014446�14743132254�021777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>How-To / 丮 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>How-To / 丮</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">How-To / 丮</a></h2>
    
        
    
        <dl>
          <dt></dt>
          <dd>
            <p>(authentication) ڽ  ϴ 
            Ȯϴ ̴. Ѻο(authorization)  
              Ȥ ϴ  򵵷 ϴ ̴.</p>
    
            <p>: <a href="auth.html">, Ѻο, </a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>CGI    </dt>
          <dd>
            <p>CGI (Common Gateway Interface)   CGI
            α׷ Ȥ CGI ũƮϰ θ, ( 
            ) ܺ α׷ ȣۿϴ  Ѵ.
            Ʈ     ϰ 
            ̴.   ġ  CGI ϴ 
            Ұϰ, CGI α׷ ۼغ.</p>
    
            <p>: <a href="cgi.html">CGI:   </a></p>
          </dd>
        </dl>
    
        <dl>
          <dt><code>.htaccess</code> </dt>
          <dd>
            <p><code>.htaccess</code>  Ͽ 丮
               ִ.   þ ִ 
            Ư  丮 θ,  丮  丮
            þ Ѵ.</p>
    
            <p>: <a href="htaccess.html"><code>.htaccess</code>
            </a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Server Side Includes Ұ</dt>
          <dd>
            <p>SSI (Server Side Includes) HTML  ϴ
            þ,  Ҷ  óѴ. SSI
            ϸ CGI α׷̳ ٸ   
            ü   ʰ HTML  
              ߰  ִ.</p>
    
            <p>: <a href="ssi.html">Server Side Includes (SSI)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>ں 丮</dt>
          <dd>
            <p> ڰ ִ ýۿ <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> þ ϸ
             ڴ ڽ Ȩ丮 ȿ Ʈ  
            ִ. URL <code>http://example.com/~username/</code>
            ϸ  "<code>username</code>" Ȩ丮
            <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
            þ  丮 ִ  
            ȴ.</p>
    
            <p>: <a href="public_html.html"> 丮
            (<code>public_html</code>)</a></p>
          </dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/public_html.html.ko.euc-kr�������������������������������������������0000664�0001751�0001751�00000026310�14743132254�023163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ں 丮 - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>ں 丮</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p> ڰ ִ ýۿ <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> þ ϸ
         ڴ ڽ Ȩ丮 ȿ Ʈ   ִ.
        URL <code>http://example.com/~username/</code> ϸ
         "<code>username</code>" Ȩ丮 <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> þ 
        丮 ִ   ȴ.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">ں 丮</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#userdir">UserDir ϰ ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#enable"> ̿  ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi"> ں cgi 丮 ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">ڰ    ֵ </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="../urlmapping.html">URL Ͻýۿ </a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">ں 丮</a></h2>
        
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code></li><li><code class="directive"><a href="../mod/core.html#directorymatch">DirectoryMatch</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="userdir" id="userdir">UserDir ϰ ϱ</a></h2>
        
    
        <p><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
        þ ں   丮 Ѵ. 
        þ  .</p>
    
        <p> ʴ θ ϸ  
        Ȩ丮  丮 η óѴ.  ,
        Ʒ  :</p>
    
        <div class="example"><p><code>
          UserDir public_html
        </code></p></div>
    
        <p>URL <code>http://example.com/~rbowen/file.html</code>
          <code>/home/rbowen/public_html/file.html</code>
        Ѵ.</p>
    
        <p> ϴ θ ϸ  丮
        ڸ  丮 θ Ѵ.  , Ʒ
         :</p>
    
        <div class="example"><p><code>
          UserDir /var/html
        </code></p></div>
    
        <p>URL <code>http://example.com/~rbowen/file.html</code>
          <code>/var/html/rbowen/file.html</code> Ѵ.</p>
    
        <p>ǥ (*)  θ ϸ ǥ ڸ
        ü θ Ѵ.  , Ʒ  :</p>
    
        <div class="example"><p><code>
          UserDir /var/www/*/docs
        </code></p></div>
    
        <p>URL <code>http://example.com/~rbowen/file.html</code>
          <code>/var/www/rbowen/docs/file.html</code>
        Ѵ.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable"> ̿  ϱ</a></h2>
        
    
        <p>UserDir  ִ  Ͽ ں 丮
         ̿  ִ ڸ   ִ:</p>
    
        <div class="example"><p><code>
          UserDir enabled<br />
          UserDir disabled root jro fish
        </code></p></div>
    
        <p>  <code>disabled</code> 忡  
        ϰ  ڿ 丮  Ѵ. ,
           ڸ ϰ   
         ִ:</p>
    
        <div class="example"><p><code>
          UserDir disabled<br />
          UserDir enabled rbowen krietz
        </code></p></div>
    
        <p><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
         ִ ٸ 鵵 ϶.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi"> ں cgi 丮 ϱ</a></h2>
      
    
       <p>ڸ cgi-bin 丮 οϷ <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> þ
       Ͽ  Ȩ丮 Ư 丮 cgi ϰ
       .</p>
    
        <div class="example"><p><code>
          &lt;Directory /home/*/public_html/cgi-bin/&gt;<br />
           Options ExecCGI<br />
           SetHandler cgi-script<br />
           &lt;/Directory&gt;
        </code></p></div>
    
        <p><code>UserDir</code> <code>public_html</code>̶
        ϸ,    ȿ ִ cgi α׷
        <code>example.cgi</code>   ִ.</p>
    
        <div class="example"><p><code>
        http://example.com/~rbowen/cgi-bin/example.cgi
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">ڰ    ֵ </a></h2>
        
    
        <p>ڰ ڽ     Ϸ,
        <code>.htaccess</code>    ־ Ѵ. <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> ڰ 
         ִ þ   ϶.  ϴ
         ڼ  <a href="htaccess.html">.htaccess
        丮</a> ϶.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/public_html.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/ssi.html.ko.euc-kr���������������������������������������������������0000664�0001751�0001751�00000054452�14743132254�021467� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ 丮: Server Side Includes Ұ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>ġ 丮: Server Side Includes Ұ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p>Server-side includes Ͽ HTML   
    ߰  ִ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Ұ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">SSI ΰ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">SSI ϵ  ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic">⺻ SSI þ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#additionalexamples">߰ </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">̿ܿ   ִ ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exec">ɾ ϱ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#advanced"> SSI </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#conclusion"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Ұ</a></h2>
     <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code></li><li><code class="directive"><a href="../mod/core.html#setoutputfilter">SetOutputFilter</a></code></li><li><code class="directive"><a href="../mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li></ul></td></tr></table>
    
        <p>   SSI θ Server Side Includes Ѵ.
        SSI ϵ  ϴ  HTML  
         ߰ϴ ⺻ SSI  ҰѴ.</p>
    
        <p>  ޺κ SSI þ ǹ  ޱ
        Ѵ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">SSI ΰ?</a></h2>
    
        <p>SSI (Server Side Includes) HTML  ϴ þ,
         Ҷ  óѴ. SSI ϸ CGI
        α׷̳ ٸ    ü 
         ʰ HTML     ߰
         ִ.</p>
    
        <p>SSI  ƴϸ α׷  ü 
           κ   
          ٽ ؾ ޷ȴ. SSI 
        ð    ߰ϴµ . ׷ 
        Ҷ  κ ؾ Ѵٸ ٸ 
        ãƺ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">SSI ϵ  ϱ</a></h2>
    
    
        <p> SSI óϷ <code>httpd.conf</code> ̳
        <code>.htaccess</code> Ͽ  þ ؾ Ѵ.</p>
    <div class="example"><p><code>
            Options +Includes
    </code></p></div>
    
        <p>׷ ġ Ͽ SSI þ óѴ. 
          <code class="directive"><a href="../mod/core.html#options">Options</a></code> þ
        ְ,  þ  Ἥ ȿ . ׷
        þ Ǹ óϱ  SSI ϴ Ư
        丮 <code>Options</code> Ѵ.</p>
    
        <p> Ͽ SSI þ óϴ  ƴϴ. ġ
          ó ˷ Ѵ. ΰ  ִ.
        ϳ   þ <code>.shtml</code>  Ư
         Ȯڸ   óϴ ̴.</p>
    <div class="example"><p><code>
            AddType text/html .shtml<br />
            AddOutputFilter INCLUDES .shtml
    </code></p></div>
    
        <p>   ̹ ִ  SSI þ ߰ϴ
         SSI þ óϱ <code>.shtml</code> Ȯڸ
        οϱ⶧ ϸ    ũ ؾ
        ϴ ̴.</p>
    
        <p>ٸ  <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>
        þ ϴ ̴.</p>
    <div class="example"><p><code>
            XBitHack on
    </code></p></div>
    
        <p><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>
         ִ Ͽ SSI þ óѴ. ׷ ̹
        ִ  SSI þ ߰Ѵٸ ϸ 
        ʰ <code>chmod</code> Ͽ  ָ ȴ.</p>
    <div class="example"><p><code>
            chmod +x pagename.html
    </code></p></div>
    
        <p> ƾ   ϳ.  <code>.shtml</code> ϸ
        ġ   <code>.html</code>  SSI ó϶
        ϴ  ִ.   Ƹ <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>  𸣴
         .   ̷ ϸ ġ Ͽ SSI þ
         Ŭ̾Ʈ     Ѵٴ
        ̴.  ſ   ,   ƴϴ.</p>
    
        <p>  ̶  ⶧ ڸ
          .</p>
    
        <p> ̿ ϱ Ʊ⶧ ġ ⺻ 
        SSI  ֱټϰ content length HTTP  
        ʴ´. ׷  ij ϰ Ŭ̾Ʈ 
         . ΰ ذ ִ.</p>
    
        <ol>
          <li><code>XBitHack Full</code>  Ѵ. ׷
          ġ ϴ(include) ϵ  ü
           û  ¥  ֱټ ˾Ƴ.</li>
    
          <li><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> ִ þ Ͽ
          Ͽ   ϸ  Ͻð 
          ij  ִ.</li>
        </ol>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic" id="basic">⺻ SSI þ</a></h2>
    
        <p>SSI þ   .</p>
    <div class="example"><p><code>
            &lt;!--#element attribute=value attribute=value ... --&gt;
    </code></p></div>
    
        <p>HTML ּ ⶧ SSI   ʾƵ
        HTML ҽ   Ѵ. SSI ùٷ
        ϸ þ  ٲ۴.</p>
    
        <p>element  ϳ.  ȸ  ڼ  ̴.
         SSI   ִ   δ</p>
    
    <h3><a name="todaysdate" id="todaysdate"> ¥</a></h3>
    
    <div class="example"><p><code>
            &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
        <p><code>echo</code> element  ״ Ѵ.
        CGI α׷ ϴ ȯ溯 ܿ  ǥ 
        ִ. , <code>set</code> element Ͽ  
          ִ.</p>
    
        <p>¥     ʴ´ٸ,  
        <code>config</code> element <code>timefmt</code> attribute
        Ѵ.</p>
    
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            Today is &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
    
    <h3><a name="lastmodified" id="lastmodified"> </a></h3>
    
    <div class="example"><p><code>
              &lt;!--#flastmod file="index.html" --&gt;  Ǿ
    </code></p></div>
    
        <p> element <code>timefmt</code>   ޷ȴ.</p>
    
    
    <h3><a name="cgi" id="cgi">CGI α׷  ϱ</a></h3>
    
        <p>Ϲ SSI  ϳ, ̵ ֿϴ ``湮
        ī''  CGI α׷  Ѵ.</p>
    
    <div class="example"><p><code>
            &lt;!--#include virtual="/cgi-bin/counter.pl" --&gt;
    </code></p></div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="additionalexamples" id="additionalexamples">߰ </a></h2>
    
    
        <p> HTML    ִ  SSI .</p>
    
    <h3><a name="docmodified" id="docmodified">   
    Ǿ?</a></h3>
    
        <p>տ SSI Ͽ ڿ  ֱټ
        ˸  ִٰ ߴ. ׷   ˷ ʾҴ.
         ڵ带 HTML  ϸ  ð  .
          Ѵ SSI ùٷ ۵ؾ Ѵ.</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
              &lt;!--#flastmod file="ssi.shtml" --&gt;  Ǿ;
    </code></p></div>
    
        <p> <code>ssi.shtml</code> ϴ  ϸ
        Ѵ. ƹ  ٿ  ִ ڵ带
        Ѵٸ, ϸ  <code>LAST_MODIFIED</code> 
        Ѵ.</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%D" --&gt;<br />
            This file last modified &lt;!--#echo var="LAST_MODIFIED" --&gt;
    </code></p></div>
    
        <p><code>timefmt</code> Ŀ  ڼ  ˻
        <code>strftime</code> ãƺ.  .</p>
    
    
    <h3><a name="standard-footer" id="standard-footer">ǥ  ϴ ϱ</a></h3>
    
    
        <p>  ִ Ʈ Ѵٸ  ü
        ϴ , Ư  ǥ ܰ  ϴ
          Ӵ.</p>
    
        <p> (header) ϴ(footer) Ϸ Ͽ
        ̷  δ   ִ.  
        <code>include</code> SSI ɾ Ͽ  ϴ 
        ϳ ϸ ȴ. <code>include</code> element
        <code>file</code> attribute <code>virtual</code> attribute
          Ѵ. <code>file</code> attribute <em>
        丮 </em> ϰδ. , (/ ϴ)
        ϰγ  ȿ ../   . Ƹ ϴ
          URL   ִ <code>virtual</code> attribute
          ̴. θ /   , Ϸ
         ϴ ϰ   ־ Ѵ.</p>
    <div class="example"><p><code>
            &lt;!--#include virtual="/footer.html" --&gt;
    </code></p></div>
    
        <p>   ΰ ļ   ϴ Ͽ
        <code>LAST_MODIFIED</code> þ ִ´. Ϸ Ͽ
        SSI þ   , ̷   ٸ 
        ϴ      ִ.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">̿ܿ   ִ ?</a></h2>
    
    
        <p>ð  <code>config</code>() ܿ ΰ 
        <code>config</code>()  ִ.</p>
    
        <p> SSI þ ߸Ǹ    ´</p>
    <div class="example"><p><code>
            [an error occurred while processing this directive]
    </code></p></div>
    
        <p>  ϰ ʹٸ <code>config</code> element
        <code>errmsg</code> attribute Ͽ Ѵ.</p>
    <div class="example"><p><code>
            &lt;!--#config errmsg="[It appears that you don't know how to use SSI]" --&gt;
    </code></p></div>
    
        <p>Ʈ ϱ   SSI þ  ذϿ
        ڰ ̷   ʱ ٶ. (׷?)</p>
    
        <p>׸ <code>sizefmt</code> attribute ȯϴ ũ
         <code>config</code>()  ִ. Ʈ ũ⸦
        ַ <code>bytes</code>,  Kb Mb ũ⸦
        ַ <code>abbrev</code> Ѵ.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exec" id="exec">ɾ ϱ</a></h2>
        
    
        <p>  ޿  CGI α׷ SSI  ϴ
          ̴.  <code>exec</code> element 
         ִ ٸ ͵  ̴. SSI   (Ȯ
        <code>/bin/sh</code> Win32 Ѵٸ DOS ) Ͽ
        ɾ Ѵ.  ,  丮  ش.</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="ls" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>or, on Windows</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="dir" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p><code>dir</code> ¿  ȥ
        ``&lt;<code>dir</code>&gt;'' ڿ Եֱ⶧,
          þ ϸ   ̻ ̴.</p>
    
        <p>  <code>exec</code> ±׿   ɾ
          ֱ⶧ ſ ϴ. ``''  ڰ
            ִ ȯ̶,   
        ؼ ȵȴ. <code>Options</code> þ
        <code>IncludesNOEXEC</code> ƱԸƮ Ͽ SSI 
        <code>exec</code>    ִ.</p> 
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advanced" id="advanced"> SSI </a></h2>
    
    
        <p> ϴ  ܿ ġ SSI   ϰ,
        񱳹 ǹ     ִ.</p>
    
    <h3><a name="caveat" id="caveat"></a></h3>
    
        <p> ۿ ϴ κ  ġ 1.2 ĺ
          ִ. , ġ 1.2 ̻  ʴ´ٸ
        Ƹ  ׷̵ؾ Ѵ. ض.  ض. ٸ
        ̴.</p>
    
    
    <h3><a name="variables" id="variables"> </a></h3>
    
        <p><code>set</code> þ Ͽ ߿  
          ִ.   ʿϱ⶧  Ѵ.
          .</p>
    <div class="example"><p><code>
            &lt;!--#set var="name" value="Rich" --&gt;
    </code></p></div>
    
        <p>   ڱ״  ʰ <a href="../env.html">ȯ溯</a>   (
        , <code>LAST_MODIFIED</code>)  ٸ  Ͽ
           ִ. ̶  տ ޷ ǥ($)
        ٿ ڿ ƴ  ǥѴ.</p>
    
        <div class="example"><p><code> &lt;!--#set var="modified" value="$LAST_MODIFIED" --&gt;
        </code></p></div>
    
        <p> ޷ ڸ ״ ԷϷ ޷ ǥ տ
        齽 Ѵ.</p>
    <div class="example"><p><code>
            &lt;!--#set var="cost" value="\$100" --&gt;
    </code></p></div>
    
        <p>  ڿ ߰  ϴµ ڿ ִ
        ڵ  Ͽ ȥǴ ,  ȣ
         Ȯ Ѵ. (  ã ,  
        ϱ ٶ.)</p>
    <div class="example"><p><code>
            &lt;!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --&gt;
    </code></p></div>
    
    
    <h3><a name="conditional" id="conditional"> ǥ</a></h3>
    
    
        <p> ϰ    ǹ ϴ. 
        SSI   α׷־ ȴ.
        <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> ǹ  <code>if</code>,
        <code>elif</code>, <code>else</code>, <code>endif</code>
         Ѵ.      
          ִ.</p>
    
        <p>ǹ   .</p>
    <div class="example"><p><code>
        &lt;!--#if expr="test_condition" --&gt;<br />
        &lt;!--#elif expr="test_condition" --&gt;<br />
        &lt;!--#else --&gt;<br />
        &lt;!--#endif --&gt;
    </code></p></div>
    
        <p><em>test_condition</em>  񱳶 
         ִ.  ٸ  ϰų, Ư  ``''
        ˻Ѵ. (ڿ   ̴.) 밡
         ڸ  , <code class="module"><a href="../mod/mod_include.html">mod_include</a></code>
         ϶.  ǹ   .</p>
    
        <p>Ͽ   ߰Ѵ.</p>
    <div class="example"><p><code>
            BrowserMatchNoCase macintosh Mac<br />
            BrowserMatchNoCase MSIE InternetExplorer
    </code></p></div>
    
        <p>Ŭ̾Ʈ Ųÿ ϴ Internet Explorer
        ȯ溯 ``Mac'' ``InternetExplorer''   Ѵ.</p>
    
        <p>׸ SSI    ´.</p>
    <div class="example"><p><code>
            &lt;!--#if expr="${Mac} &amp;&amp; ${InternetExplorer}" --&gt;<br />
            ⿡  ´<br />
            &lt;!--#else --&gt;<br />
            ⿡  JavaScript ڵ尡 ´<br />
            &lt;!--#endif --&gt;
    </code></p></div>
    
        <p> Ų IE ݰ ִ  ƴϴ.  
        ֿ ٸ    JavaScript ڵ尡 Ų
        IE  ʾƼ ð ߴ.  ӽ
        ذå̴.</p>
    
        <p>( Ͽ Ϲ ȯ溯̰)   ǹ
          ִ. ƶġ <code>SetEnvIf</code> ٸ 
        þ ȯ溯   ֱ⶧ CGI ̵ 
            ִ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="conclusion" id="conclusion"></a></h2>
    
        <p>SSI Ȯ CGI   ϴ ٸ 
        ü  . ׷  ߰ ۾  
          ߰ϱ⿡ Ǹ ̴.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/ssi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/htaccess.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000074462�14740503670�022170� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Tutoriel du serveur HTTP Apache : fichiers .htaccess - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Recettes / Tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Tutoriel du serveur HTTP Apache : fichiers .htaccess</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div>
    
    <p>Les fichiers <code>.htaccess</code> fournissent une méthode pour
    modifier la configuration du serveur au niveau de chaque répertoire.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Fichiers .htaccess</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">Que sont ce fichiers, comment les utiliser ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#when">Quand doit-on (ne doit-on pas) utiliser
        les fichiers .htaccess ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#how">Comment sont appliquées les directives ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#auth">Exemple d'authentification</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssi">Exemple d'Inclusion Côté Serveur (Server Side
    Includes - SSI)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Les règles de réécriture dans les fichiers .htaccess</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">Exemple de CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">Résolution des problèmes</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Fichiers .htaccess</a></h2>
        
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li><li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li><li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="../mod/mod_authn_core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code></li></ul></td></tr></table>
        <div class="note">Les fichiers <code>.htaccess</code> ne doivent être utilisés
        que si vous n'avez pas accès au fichier de configuration du serveur
        principal. L'utilisation des fichiers <code>.htaccess</code>
        ralentit le fonctionnement de votre serveur HTTP Apache. Il est toujours
        préférable de définir les directives que vous pouvez inclure dans un
        fichier <code>.htaccess</code> dans une section <code class="directive"><a href="../mod/core.html#directory">Directory</a></code>, car elles produiront le
        même effet avec de meilleures performances.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">Que sont ce fichiers, comment les utiliser ?</a></h2>
    
    
        <p>Les fichiers <code>.htaccess</code> (ou "fichiers de
        configuration distribués") fournissent une méthode pour modifier la
        configuration du serveur au niveau d'un répertoire. Un fichier,
        contenant une ou plusieurs directives de configuration, est placé
        dans un répertoire de documents particulier, et ses directives
        s'appliquent à ce répertoire et à tous ses sous-répertoires.</p>
    
        <div class="note"><h3>Note :</h3>
          <p>Si vous voulez donner un autre nom à votre fichier
          <code>.htaccess</code>, vous pouvez le faire en utilisant la
          directive <code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code>. Par
          exemple, si vous préférez nommer votre fichier
          <code>.config</code>, vous pouvez mettre ceci dans le fichier de
          configuration de votre serveur :</p>
    
          <pre class="prettyprint lang-config">AccessFileName ".config"</pre>
    
        </div>
    
        <p>En général, les fichiers <code>.htaccess</code> utilisent la même
        syntaxe que les <a href="../configuring.html#syntax">fichiers de
        configuration principaux</a>. Ce que vous pouvez mettre dans ces
        fichier est déterminé par la directive <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>. Cette directive spécifie,
        sous forme de catégories, quelles directives seront traitées si
        elles se trouvent dans un fichier <code>.htaccess</code>. Si une
        directive est permise dans un fichier <code>.htaccess</code> file,
        la documentation de cette directive contiendra une section Override,
        spécifiant quelle valeur doit prendre <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> pour que cette directive
        soit traitée.</p>
    
        <p>Par exemple, si vous regardez la documentation de la directive
        <code class="directive"><a href="../mod/core.html#adddefaultcharset">AddDefaultCharset</a></code>, vous verrez
        que cette dernière est permise dans les fichiers
        <code>.htaccess</code> (Voir la ligne de contexte dans le résumé de
        la directive). La ligne <a href="../mod/directive-dict.html#Context">Override</a> indique
        <code>FileInfo</code>. Vous devez donc avoir au moins
        <code>AllowOverride FileInfo</code> pour que cette directive soit
        traitée dans les fichiers <code>.htaccess</code>.</p>
    
        <div class="example"><h3>Exemple :</h3><table>
            <tr>
              <td><a href="../mod/directive-dict.html#Context">Contexte :</a></td>
              <td>configuration du serveur, serveur virtuel, directory, .htaccess</td>
            </tr>
    
            <tr>
              <td><a href="../mod/directive-dict.html#Override">Override:</a></td>
              <td>FileInfo</td>
            </tr>
          </table></div>
    
        <p>Si vous n'êtes pas sûr qu'une directive particulière soit permise
        dans un fichier <code>.htaccess</code>, lisez la documentation de
        cette directive, et consultez la ligne de contexte pour
        ".htaccess".</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="when" id="when">Quand doit-on (ne doit-on pas) utiliser
        les fichiers .htaccess ?</a></h2>
    
        <p>En principe, vous ne devriez utiliser les fichiers
        <code>.htaccess</code> que lorsque vous n'avez pas accès au fichier de
        configuration du serveur principal. Par exemple, la fausse
        idée
        selon laquelle l'authentification de l'utilisateur devrait toujours
        être faite dans les fichiers <code>.htaccess</code> est très
        répandue. Il est aussi souvent avancé, ces dernières
        années, que les directives de <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> doivent
        être définies dans les fichiers <code>.htaccess</code>. Ceci est
        tout simplement faux. Vous pouvez configurer
        l'authentification des utilisateurs au niveau de la configuration du
        serveur principal, et c'est en fait cette méthode qui doit être
        privilégiée. De même, les directives de
        <code>mod_rewrite</code> fonctionneront mieux, à de nombreux égards,
        dans le contexte du serveur principal.</p>
    
        <p>Les fichiers <code>.htaccess</code> ne devraient être utilisés
        que dans le cas où les fournisseurs de contenu ont besoin de
        modifier la configuration du serveur au niveau d'un répertoire, mais
        ne possèdent pas l'accès root sur le système du serveur. Si
        l'administrateur du serveur ne souhaite pas effectuer des
        modifications de configuration incessantes, il peut être intéressant
        de permettre aux utilisateurs isolés d'effectuer eux-mêmes ces
        modifications par le biais de fichiers <code>.htaccess</code>. Ceci
        est particulièrement vrai dans le cas où le fournisseur d'accès à
        Internet héberge de nombreux sites d'utilisateurs sur un seul
        serveur, et souhaite que ces utilisateurs puissent modifier
        eux-mêmes leurs configurations.</p>
    
        <p>Cependant et d'une manière générale, il vaut mieux éviter
        d'utiliser les fichiers <code>.htaccess</code>. Tout élément de
        configuration que vous pourriez vouloir mettre dans un fichier
        <code>.htaccess</code>, peut aussi être mis, et avec la même
        efficacité, dans une section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> du fichier de configuration de
        votre serveur principal.</p>
    
        <p>Il y a deux raisons principales d'éviter l'utilisation des
        fichiers <code>.htaccess</code>.</p>
    
        <p>La première est liée aux performances. Lorsque la directive
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> est définie de
        façon à autoriser l'utilisation des fichiers <code>.htaccess</code>,
        httpd va rechercher leur présence dans chaque répertoire. Ainsi,
        permettre l'utilisation des fichiers <code>.htaccess</code> est déjà
        en soi une cause de dégradation des performances, que vous utilisiez
        effectivement ces fichiers ou non ! De plus, le fichier
        <code>.htaccess</code> est chargé en mémoire chaque fois qu'un
        document fait l'objet d'une requête.</p>
    
        <p>Notez aussi que httpd doit rechercher les fichiers
        <code>.htaccess</code> dans tous les répertoires de niveau
        supérieur, afin de rassembler toutes les directives qui s'appliquent
        au répertoire courant (Voir la section <a href="#how">comment sont
        appliquées les directives</a>). Ainsi, si un fichier fait l'objet
        d'une requête à partir d'un répertoire
        <code>/www/htdocs/exemple</code>, httpd doit rechercher les
        fichiers suivants :</p>
    
        <div class="example"><p><code>
          /.htaccess<br />
          /www/.htaccess<br />
          /www/htdocs/.htaccess<br />
          /www/htdocs/exemple/.htaccess
        </code></p></div>
    
        <p>En conséquence, chaque accès à un fichier de ce répertoire
        nécessite 4 accès au système de fichiers supplémentaires pour
        rechercher des fichiers <code>.htaccess</code>, même si
        aucun de ces fichiers n'est présent. Notez que cet exemple ne peut
        se produire que si les fichiers <code>.htaccess</code> ont été
        autorisés pour le répertoire <code>/</code>, ce qui est rarement le
        cas.</p>
    
        <p>La seconde raison d'éviter l'utilisation des fichiers
        <code>.htaccess</code> est liée à la sécurité. Si vous permettez aux
        utilisateurs de modifier la configuration du serveur, il peut en
        résulter des conséquences sur lesquelles vous n'aurez aucun
        contrôle. Réfléchissez bien avant de donner ce privilège à vos
        utilisateurs. Notez aussi que ne pas donner aux utilisateurs les
        privilèges dont ils ont besoin va entraîner une augmentation des
        demandes de support technique. Assurez-vous d'avoir informé
        clairement vos utilisateurs du niveau de privilèges que vous leur
        avez attribué. Indiquer exactement comment vous avez défini la
        directive <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> et
        diriger les utilisateurs vers la documentation correspondante vous
        évitera bien des confusions ultérieures.</p>
    
        <p>Notez que mettre un fichier <code>.htaccess</code> contenant une
        directive dans un répertoire <code>/www/htdocs/exemple</code>
        revient exactement au même que mettre la même directive dans une
        section Directory <code>&lt;Directory "/www/htdocs/exemple"&gt;</code>
        du fichier de configuration de votre serveur principal :</p>
    
        <p>Fichier <code>.htaccess</code> dans
        <code>/www/htdocs/exemple</code> :</p>
    
        <div class="example"><h3>Contenu du fichier .htaccess dans
        <code>/www/htdocs/exemple</code></h3><pre class="prettyprint lang-config">AddType text/example ".exm"</pre>
    </div>
    
        <div class="example"><h3>Section de votre fichier
        <code>httpd.conf</code></h3><pre class="prettyprint lang-config">&lt;Directory "/www/htdocs/example"&gt;
        AddType text/example .exm
    &lt;/Directory&gt;</pre>
    </div>
    
        <p>Cependant, la perte de performances sera moindre si vous
        définissez cette directive dans la configuration de
        votre serveur principal, car cette dernière ne sera chargée qu'une
        seule fois au moment du démarrage du serveur, alors qu'elle le sera
        à chaque accès dans le cas d'un fichier <code>.htaccess</code>.</p>
    
        <p>L'utilisation des fichiers <code>.htaccess</code> peut être
        entièrement désactivée en définissant la directive <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> à <code>none</code> :</p>
    
        <pre class="prettyprint lang-config">AllowOverride None</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="how" id="how">Comment sont appliquées les directives ?</a></h2>
    
        <p>Les directives de configuration situées dans un fichier
        <code>.htaccess</code> s'appliquent au répertoire dans lequel ce
        fichier <code>.htaccess</code> se trouve, ainsi qu'à tous ses
        sous-répertoires. Cependant, il est important de garder à l'esprit
        qu'il peut y avoir des fichiers <code>.htaccess</code> dans les
        répertoires de niveau supérieur. Les directives sont appliquées
        selon l'ordre dans lequel elles sont rencontrées. Ainsi, les
        directives d'un fichier <code>.htaccess</code> situé dans un
        répertoire particulier peuvent écraser les directives se trouvant
        dans des fichiers <code>.htaccess</code> situés à un niveau
        supérieur dans l'arborescence des répertoires. Et ces dernières
        peuvent elles-mêmes avoir écrasé des directives d'un fichier
        <code>.htaccess</code> situé à un niveau encore plus haut, ou dans
        le fichier de configuration du serveur principal.</p>
    
        <p>Exemple :</p>
    
        <p>Dans le répertoire <code>/www/htdocs/exemple1</code> se trouve un
        fichier <code>.htaccess</code> contenant ce qui suit :</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI</pre>
    
    
        <p>Note : "<code>AllowOverride Options</code>" doit être présent
        pour permettre l'utilisation de la directive "<code class="directive"><a href="../mod/core.html#options">Options</a></code>"  dans les fichiers
        <code>.htaccess</code>.</p>
    
        <p>Dans le répertoire <code>/www/htdocs/exemple1/exemple2</code> se
        trouve un fichier <code>.htaccess</code> contenant ce qui suit
        :</p>
    
        <pre class="prettyprint lang-config">Options Includes</pre>
    
    
        <p>Ainsi, à cause de ce second fichier <code>.htaccess</code> du
        répertoire <code>/www/htdocs/exemple1/exemple2</code>, l'exécution
        des CGI est interdite, car la dernière définition d'options
        <code>Options Includes</code> écrase toute autre définition
        d'options d'un fichier <code>.htaccess</code> situé dans un
        répertoire de niveau supérieur.</p>
    
        <h3><a name="merge" id="merge">Interactions entre les fichiers .htaccess
        et les fichiers de configuration du serveur principal</a></h3>
    
        <p>Comme indiqué dans la documentation sur les <a href="../sections.html">Sections de configuration</a>, les fichiers
        <code>.htaccess</code> peuvent écraser les directives des sections
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> pour
        le répertoire correspondant, mais peuvent eux-mêmes être écrasés
        par d'autres types de sections des fichiers de la
        configuration principale. Cette possibilité peut s'avérer utile pour
        forcer certaines configurations, même en cas de présence de l'option
        libérale <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>. Par
        exemple, pour interdire l'exécution de scripts en autorisant la
        définition de toute autre option dans les fichiers
        <code>.htaccess</code>, vous pouvez utiliser :</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/www/htdocs"&gt;
        AllowOverride All
    &lt;/Directory&gt;
    
    &lt;Location "/"&gt;
        Options +IncludesNoExec -ExecCGI
    &lt;/Location&gt;</pre>
    
    
        <div class="note">Dans cet exemple, on considère que le chemin défini par la
        directive <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> est
        <code>/www/htdocs</code>.</div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="auth" id="auth">Exemple d'authentification</a></h2>
    
        <p>Si vous accédez directement à ce point du document pour apprendre
        à effectuer une authentification, il est important de noter ceci. Il
        existe une fausse idée selon laquelle il serait nécessaire
        d'utiliser les fichiers <code>.htaccess</code> pour implémenter
        l'authentification par mot de passe. Ceci est tout simplement faux.
        Pour y parvenir, il est préférable de mettre les directives
        d'authentification dans une section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> du fichier de configuration de
        votre serveur principal, et les fichiers <code>.htaccess</code> ne
        devraient être utilisés que dans le cas où vous n'avez pas accès au
        fichier de configuration du serveur principal. Voir <a href="#when">ci-dessus</a> pour savoir dans quels cas vous devez ou
        ne devez pas utiliser les fichiers <code>.htaccess</code>.</p>
    
        <p>Ceci étant dit, si vous pensez que vous devez quand-même utiliser
        un fichier <code>.htaccess</code>, vous pouvez utiliser la
        configuration suivante :</p>
    
        <p>Contenu du fichier <code>.htaccess</code> :</p>
    
        <pre class="prettyprint lang-config">AuthType Basic
    AuthName "Password Required"
    AuthUserFile "/www/passwords/password.file"
    AuthGroupFile "/www/passwords/group.file"
    Require group admins</pre>
    
    
        <p>Notez que <code>AllowOverride AuthConfig</code> doit être présent
        pour que ces directives produisent leur effet.</p>
    
        <p>Vous pouvez vous référer au <a href="auth.html">tutoriel sur
        l'authentification</a> pour une description plus détaillée de
        l'authentification et de l'autorisation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssi" id="ssi">Exemple d'Inclusion Côté Serveur (Server Side
    Includes - SSI)</a></h2>
    
        <p>Les fichiers <code>.htaccess</code> sont aussi couramment
        utilisés pour activer les SSI pour un répertoire particulier. Pour y
        parvenir, on utilise les directives de configuration suivantes,
        placées dans un fichier <code>.htaccess</code> enregistré dans le
        répertoire considéré :</p>
    
        <pre class="prettyprint lang-config">Options +Includes
    AddType text/html shtml
    AddHandler server-parsed shtml</pre>
    
    
        <p>Notez que <code>AllowOverride Options</code> et <code>AllowOverride
        FileInfo</code> doivent être tous les deux présents pour que ces
        directives puissent produire leur effet.</p>
    
        <p>Vous pouvez vous référer au <a href="ssi.html">tutoriel SSI</a>
        pour une description plus détaillée des SSI.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Les règles de réécriture dans les fichiers .htaccess</a></h2>
    <p>Sivous utilisez des directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> dans un fichier
    <code>.htaccess</code>, gardez à l'esprit que les choses sont légèrement
    différentes dans un contexte de répertoire. En particulier, les règles
    sont relatives au répertoire courant, et non à l'URI original. Considérez
    les exemples suivants :</p>
    
    <pre class="prettyprint lang-config"># Dans httpd.conf
    RewriteRule "^/images/(.+)\.jpg" "/images/$1.png"
    
    # Dans un fichier .htaccess situé dans le répertoire racine de vos
    # documents
    RewriteRule "^images/(.+)\.jpg" "images/$1.png"
    
    # Dans un fichier .htaccess situé dans le répertoire images/
    RewriteRule "^(.+)\.jpg" "$1.png"</pre>
    
    
    <p>On voit que si le fichier <code>.htaccess</code> se situe à la racine
    de vos documents, le slash de tête est supprimé de la valeur de
    remplacement spécifiée pour la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>, et que si le fichier
    <code>.htaccess</code> se situe dans le répertoire <code>images</code>,
    la chaîne <code>/images/</code> disparaît de cette même valeur de
    remplacement. Il doit donc en être de même dans votre expression
    rationnelle.</p>
    
    <p>Veuillez vous référer à cette <a href="../rewrite/">documentation</a>
    pour une étude détaillée de l'utilisation du module
    <code>mod_rewrite</code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">Exemple de CGI</a></h2>
    
        <p>En fin de compte, vous avez décidé d'utiliser un fichier
        <code>.htaccess</code> pour permettre l'exécution des programmes CGI
        dans un répertoire particulier. Pour y parvenir, vous pouvez
        utiliser la configuration suivante :</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI
    AddHandler cgi-script cgi pl</pre>
    
    
        <p>Alternativement, si vous souhaitez que tous les fichiers d'un
        répertoire donné soient considérés comme des programmes CGI, vous
        pouvez utiliser la configuration suivante :</p>
    
        <pre class="prettyprint lang-config">Options +ExecCGI
    SetHandler cgi-script</pre>
    
    
        <p>Notez que <code>AllowOverride Options</code> et <code>AllowOverride
        FileInfo</code> doivent être tous les deux présents pour que ces
        directives puissent produire leur effet.</p>
    
        <p>Vous pouvez vous référer au <a href="cgi.html">tutoriel CGI</a>
        pour une description plus détaillée de la configuration et de la
        proprammation CGI.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">Résolution des problèmes</a></h2>
    
        <p>De nombreuses raisons peuvent être à l'origine du fait que
        les directives que vous avez mises dans un fichier
        <code>.htaccess</code> ne produisent pas l'effet désiré.</p>
    
        <p>Le plus souvent, le problème vient du fait que la définition de
        la directive <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        ne permet pas l'activation des directives de votre fichier
        <code>.htaccess</code>. Vérifiez si une directive
        <code>AllowOverride None</code> n'affecte pas le répertoire où se
        trouve votre fichier. Un bon test consiste à mettre des directives
        dont la syntaxe est erronée dans votre ficher <code>.htaccess</code>
        et de recharger la page. Si aucune erreur n'est générée par le
        serveur, il est pratiquement certain qu'une directive
        <code>AllowOverride None</code> affecte votre répertoire.</p>
    
        <p>Par contre, si vous obtenez des erreurs de serveur lorsque vous
        tentez d'accéder à des documents, consultez votre journal des
        erreurs de httpd. Il vous indiquera probablement que la directive
        utilisée dans votre fichier <code>.htaccess</code> n'est pas
        permise.</p>
    
    <div class="example"><p><code>
    	[Fri Sep 17 18:43:16 2010] [alert] [client 192.168.200.51] /var/www/html/.htaccess: DirectoryIndex not allowed here
    </code></p></div>
    	<p>Cela signifie soit que vous utilisez une directive qui n'est
    	jamais permise dans les fichiers <code>.htaccess</code>, soit
    	que vous n'avez tout simplement pas défini la directive
    	<code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> à un niveau
    	suffisant pour la directive que vous utilisez. Consultez la
    	documentation de cette directive pour déterminer quel cas
    	s'applique.</p>
    
    	<p>Le journal des erreurs peut aussi vous signaler une erreur de
    	syntaxe dans l'usage de la directive elle-même.</p>
    
        <div class="example"><p><code>
        [Sat Aug 09 16:22:34 2008] [alert] [client 192.168.200.51] /var/www/html/.htaccess: RewriteCond: bad flag delimiters
        </code></p></div>
    
    	<p>Dans ce cas, le message d'erreur sera spécifique à l'erreur
    	de syntaxe que vous avez commise.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/reverse_proxy.html.fr.utf8�������������������������������������������0000664�0001751�0001751�00000053647�14740503670�023311� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Guide de configuration d'un mandataire inverse - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Recettes / Tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Guide de configuration d'un mandataire inverse</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/reverse_proxy.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/howto/reverse_proxy.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>En plus de ses fonctions de serveur web "basique", à savoir fournir du
        contenu statique et dynamique à l'utilisateur, Apache httpd (comme la
        plupart des autres serveurs web) peut aussi assurer les fonctions de serveur
        mandataire inverse, connu aussi sous le nom de serveur "passerelle".</p>
    
        <p>Dans un tel scénario, httpd ne génère et n'héberge pas lui-même les
        données, le contenu étant en général obtenu à partir d'un ou plusieurs serveurs
        d'arrière-plan qui n'ont normalement aucune connexion directe avec le réseau
        externe. Lorsque httpd reçoit une requête en provenance d'un client, la
        requête proprement dite est <em>mandatée</em> vers un de ces serveurs
        d'arrière-plan qui traite la requête, génère le contenu et l'envoie à httpd,
        ce dernier générant la véritable réponse HTTP à destination du client.</p>
    
        <p>De nombreuses raisons peuvent vous motiver à utiliser cette
        fonctionnalité, mais elles sont souvent du domaine de la sécurité, de
        la haute disponibilité, de la répartition de charge et de
        l'authentification/autorisation centralisée. Il est alors indispensable que
        l'organisation, la conception et l'architecture de l'infrastructure
        d'arrière-plan (les serveurs qui traitent au sens propre les requêtes) soient
        isolées et protégées de l'extérieur ; vu du client, le serveur mandataire
        inverse <em>est</em> le seul serveur accessible pouvant lui fournir du
        contenu.</p>
    
        <p>Voici un exemple typique d'implémentation de cette fonctionnalité :</p>
        <p class="centered"><img src="../images/reverse-proxy-arch.png" alt="reverse-proxy-arch" /></p>
    
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Mandataire inverse</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple">Mandatement inverse simple</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cluster">Clusters et Balancers</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">Configuration du Balancer et des BalancerMembers</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#failover">Gestion des indisponibilités (Failover)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#manager">Gestion du répartiteur de charge</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#health-check">Vérification dynamique du bon fonctionnement d'un serveur
        d'arrière-plan</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#status">Drapeaux d'état d'un membre du groupe de répartition de charge</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Mandataire inverse</a></h2>
      
      <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="../mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code></li><li><code class="module"><a href="../mod/mod_proxy_hcheck.html">mod_proxy_hcheck</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="../mod/mod_proxy.html#balancermember">BalancerMember</a></code></li></ul></td></tr></table>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple" id="simple">Mandatement inverse simple</a></h2>
        
    
        <p>
          La directive <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> permet de
          rediriger les requêtes entrantes vers un serveur d'arrière-plan (ou un
          cluster de serveurs plus connu sous le nom de groupe
          <code>Balancer</code>). Dans cet exemple le plus simple, toutes les
          requêtes (<code>"/"</code>) sont redirigées vers un serveur d'arrière-plan
          unique :
        </p>
    
        <pre class="prettyprint lang-config">ProxyPass "/"  "http://www.example.com/"</pre>
    
    
        <p>
          Pour être sur que cette redirection soit effectuée et que les en-têtes
          <code>Location:</code> générés par le serveur d'arrière-plan soient
          modifiés pour pointer vers le mandataire inverse, et non vers le serveur
          d'arrière-plan, la directive <code class="directive"><a href="../mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> est souvent requise :
        </p>
    
        <pre class="prettyprint lang-config">ProxyPass "/"  "http://www.example.com/"
    ProxyPassReverse "/"  "http://www.example.com/"</pre>
    
    
        <p>Seules des URIs spécifiques peuvent être mandatées, comme le montre
        l'exemple suivant :</p>
    
        <pre class="prettyprint lang-config">ProxyPass "/images"  "http://www.example.com/"
    ProxyPassReverse "/images"  "http://www.example.com/"</pre>
    
    
        <p>Dans l'exemple précédent, si le chemin d'une requête commence par
        <code>/images</code>, elle sera redirigée vers le serveur d'arrière-plan
        spécifié ; dans le cas contraire, elle sera traitée localement.
        </p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cluster" id="cluster">Clusters et Balancers</a></h2>
        
    
        <p>
          Utiliser un serveur d'arrière-plan unique n'est cependant pas une solution
          idéale car ce dernier peut devenir indisponible ou surchargé, et le
          mandatement inverse vers ce serveur ne présente alors plus aucun avantage.
          La solution réside dans la définition d'un groupe de serveurs
          d'arrière-plan qui vont se partager le traitement des requêtes via un
          mécanisme de répartition de charge et de gestion des indisponibilités pris
          en charge par le mandataire. Ce groupe de répartition est plus connu sous le nom de
          <em>cluster</em>, mais dans la terminologie d'Apache httpd, on utilise
          plutôt le terme de <em>balancer</em>. Un balancer se définit en
          utilisant les directives <code class="directive"><a href="../mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> et <code class="directive"><a href="../mod/mod_proxy.html#balancermember">BalancerMember</a></code> comme suit :
        </p>
    
        <pre class="prettyprint lang-config">&lt;Proxy balancer://myset&gt;
        BalancerMember http://www2.example.com:8080
        BalancerMember http://www3.example.com:8080
        ProxySet lbmethod=bytraffic
    &lt;/Proxy&gt;
    
    ProxyPass "/images/"  "balancer://myset/"
    ProxyPassReverse "/images/"  "balancer://myset/"</pre>
    
    
        <p>
          Le protocole <code>balancer://</code> indique à httpd que l'on souhaite
          créer un balancer nommé <em>myset</em>. Ce balancer comporte deux serveurs
          d'arrière-plan référencés dans la terminologie httpd sous le nom de
          <em>BalancerMembers</em>. Avec cet exemple, toute requête dont le chemin
          commence par <code>/images</code> sera mandatée vers <em>un</em> des deux
          serveurs d'arrière-plan. La directive <code class="directive"><a href="../mod/mod_proxy.html#proxyset">ProxySet</a></code> définit ici pour le balancer
          <em>myset</em> un algorithme de
          répartition de charge basé sur le trafic entrées/sorties.
        </p>
    
        <div class="note"><h3>Remarque</h3>
          <p>
          	Les <em>BalancerMembers</em> sont aussi souvent référencés sous le terme
    	<em>workers</em>.
          </p>
       </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">Configuration du Balancer et des BalancerMembers</a></h2>
        
    
        <p>
          Vous pouvez configurer de manière détaillée les <em>balancers</em> et
          <em>workers</em> via les nombreux paramètres de la directive <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>. Par exemple, si vous souhaitez
          que <code>http://www3.example.com:8080</code> traite avec un facteur 3 le
          trafic avec un timeout d'une seconde, utilisez la configuration suivante :
        </p>
    
        <pre class="prettyprint lang-config">&lt;Proxy balancer://myset&gt;
        BalancerMember http://www2.example.com:8080
        BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
        ProxySet lbmethod=bytraffic
    &lt;/Proxy&gt;
    
    ProxyPass "/images"  "balancer://myset/"
    ProxyPassReverse "/images"  "balancer://myset/"</pre>
    
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="failover" id="failover">Gestion des indisponibilités (Failover)</a></h2>
        
    
        <p>
          Vous pouvez aussi définir finement des scénarios pour les cas
          d'indisponibilité d'un ou plusieurs serveurs d'arrière-plan en spécifiant
          quels serveurs doivent alors prendre le relai. Dans l'exemple suivant,
          trois scénarios sont envisagés :
        </p>
        <ol>
          <li>
            <code>http://spare1.example.com:8080</code> et
            <code>http://spare2.example.com:8080</code> ne sont sollicités que si
    	<code>http://www2.example.com:8080</code> ou
    	<code>http://www3.example.com:8080</code> est indisponible (un serveur
    	de remplacement sera utilisé à la place d'un membre indisponible du même
    	jeu de serveurs cibles).
          </li>
          <li>
            <code>http://hstandby.example.com:8080</code> n'est sollicité que si
    	tous les autres serveurs cibles du jeu de serveurs <code>0</code> sont
    	indisponibles.
          </li>
          <li>
            Les serveurs <code>http://bkup1.example.com:8080</code> et
    	<code>http://bkup2.example.com:8080</code> du jeu <code>1</code> ne seront sollicités que si
    	tous les serveurs du jeu <code>0</code>, tous les serveurs de
    	remplacement et tous les serveurs de standby sont indisponibles.
          </li>
        </ol>
        <p>
          Il est ainsi possible de définir un ou plusieurs serveurs de remplacement
          ou de standby pour chaque jeu de serveurs du répartiteur de charge.
        </p>
    
        <pre class="prettyprint lang-config">&lt;Proxy balancer://myset&gt;
        BalancerMember http://www2.example.com:8080
        BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
        BalancerMember http://spare1.example.com:8080 status=+R
        BalancerMember http://spare2.example.com:8080 status=+R
        BalancerMember http://hstandby.example.com:8080 status=+H
        BalancerMember http://bkup1.example.com:8080 lbset=1
        BalancerMember http://bkup2.example.com:8080 lbset=1
        ProxySet lbmethod=byrequests
    &lt;/Proxy&gt;
    
    ProxyPass "/images/"  "balancer://myset/"
    ProxyPassReverse "/images/"  "balancer://myset/"</pre>
    
    
        <p>
          Les serveurs de remplacement à chaud remplacent les serveurs indisponibles
          du même jeu de serveurs du répartiteur de charge. Un serveur est
          considéré comme indisponible s'il est en maintenance, arrêté ou en erreur.
          Les serveurs de standby à chaud sont utilisés si tous les serveurs et
          serveurs de remplacement du jeu de serveurs du répartiteur de charge sont
          indisponibles. Les jeux de serveurs du répartiteur de charge (avec leurs
          serveurs de standby et de remplacement à chaud respectifs) sont toujours
          sollicités dans l'ordre du plus bas lbset vers le plus haut.
        </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="manager" id="manager">Gestion du répartiteur de charge</a></h2>
        
    
        <p>
         L'application <em>balancer-manager</em> fournie avec le mandataire inverse
         d'Apache httpd en est un des outils les plus utiles. Comme
         <code class="module"><a href="../mod/mod_status.html">mod_status</a></code>, <em>balancer-manager</em> affiche la
         configuration et l'activité actuelles des balancers actifs. L'affichage de
         ces informations n'est cependant pas sa seule fonction ; il permet aussi de
         modifier la plupart d'entre elles et même d'ajouter des membres au groupe
         de répartition de charge en temps réel. Pour activer ces fonctionnalités,
         vous devez ajouter les lignes suivantes à votre fichier de configuration : 
        </p>
    
        <pre class="prettyprint lang-config">&lt;Location "/balancer-manager"&gt;
        SetHandler balancer-manager
        Require host localhost
    &lt;/Location&gt;</pre>
    
    
        <div class="warning"><h3>Avertissement</h3>
          <p>N'activez le <em>balancer-manager</em> que si vous avez déjà <a href="../mod/mod_proxy.html#access">sécurisé votre serveur</a>.
          Assurez-vous en particulier que l'accès à l'URL soit fortement restreint.</p>
        </div>
    
        <p>
          Lorsque vous accédez au serveur mandataire avec une adresse du style
          <code>http://rproxy.example.com/balancer-manager/</code>, la page suivante
          s'affiche :
        </p>
        <p class="centered"><img src="../images/bal-man.png" alt="balancer-manager page" /></p>
    
        <p>
          Ce formulaire permet à l'administrateur de modifier certains paramètres,
          de désactiver ou d'ajouter certains serveurs d'arrière-plan, et de
          modifier les règles de répartition de charge. Par exemple, si on clique
          sur le répartiteur, la page suivante s'affiche : 
        </p>
        <p class="centered"><img src="../images/bal-man-b.png" alt="balancer-manager page" /></p>
    
        <p>
          Si on clique sur un membre du groupe de répartition de charge, la page
          suivante s'affiche :
        </p>
        <p class="centered"><img src="../images/bal-man-w.png" alt="balancer-manager page" /></p>
    
        <p>
          Si vous souhaitez que ces modifications soient conservées après un
          redémarrage du serveur, assurez-vous que la directive <code class="directive"><a href="../mod/mod_proxy.html#balancerpersist">BalancerPersist</a></code> soit définie à On.
        </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="health-check" id="health-check">Vérification dynamique du bon fonctionnement d'un serveur
        d'arrière-plan</a></h2>
        
    
        <p>
          Avant que le mandataire httpd ne fasse appel à un serveur d'arrière-plan, il
          peut <em>"tester"</em> si ce dernier est disponible en définissant le
          paramètre <code>ping</code> de ce serveur via la directive <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>. Cependant, il est souvent plus
          judicieux de vérifier le bon fonctionnement d'un serveur <em>hors
          bande</em> et de manière dynamique via le module
          <code class="module"><a href="../mod/mod_proxy_hcheck.html">mod_proxy_hcheck</a></code> d'Apache httpd.
        </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="status" id="status">Drapeaux d'état d'un membre du groupe de répartition de charge</a></h2>
        
    
        <p>
          <em>balancer-manager</em> permet d'afficher et de modifier l'état d'un
          membre du groupe de répartition de charge. Les différents états et leurs
          significations sont les suivants :
        </p>
          <table class="bordered">
          	<tr><th>Drapeau</th><th>Sigle</th><th>Description</th></tr>
          	<tr><td>&nbsp;</td><td><em>Ok</em></td><td>Le serveur est disponible</td></tr>
          	<tr><td>&nbsp;</td><td><em>Init</em></td><td>Le serveur a été initialisé</td></tr>
            <tr><td><code>D</code></td><td><em>Dis</em></td><td>Le serveur est
    	désactivé et n'accepte aucune requête ; il sera retesté automatiquement.</td></tr>
            <tr><td><code>S</code></td><td><em>Stop</em></td><td>Le serveur a été
    	arrêté par l'administrateur ; il n'accepte aucune requête et il ne sera
    	pas retesté automatiquement.</td></tr>
            <tr><td><code>I</code></td><td><em>Ign</em></td><td>Les erreurs
    	concernant ce serveur sont ignorées et il sera donc toujours considéré
    	comme disponible.</td></tr>
    	<tr><td><code>R</code></td><td><em>Spar</em></td><td>Le serveur cible sert de remplaçant à
    	 chaud. Lorsqu'un serveur cible avec un lbset donné est inutilisable
    	 (maintenance, arrêt, en erreur, etc...), un serveur de remplacement à
    	 chaud libre de même lbset sera utilisé à sa place. Les remplaçants à
    	 chaud permettent de s'assurer qu'un nombre déterminé de serveurs cibles
    	 sera toujours disponible pour un répartiteur de charge.</td></tr>
            <tr><td><code>H</code></td><td><em>Stby</em></td><td>Le serveur est en
    	mode hot-standby et ne sera donc utilisé que si aucun autre serveur ou
    	serveur de remplacement	n'est disponible dans le jeu de serveurs du
    	répartiteur de charge.</td></tr>
            <tr><td><code>E</code></td><td><em>Err</em></td><td>Le serveur est en
    	erreur, en général suite à un test préalable à une requête ; aucune
    	requête ne lui sera soumise, mais il sera retesté en fonction de la
    	valeur de son paramètre <code>retry</code>.</td></tr>
            <tr><td><code>N</code></td><td><em>Drn</em></td><td>Le serveur est en
    	mode drain ; il n'acceptera de requêtes que dans le cadre des sessions
    	persistantes qui lui sont réservées et ignorera toutes les autres.</td></tr>
            <tr><td><code>C</code></td><td><em>HcFl</em></td><td>Le serveur a échoué
    	au test dynamique de bon fonctionnement et ne sera utilisé que lorsqu'il
    	aura réussi un test ultérieur.</td></tr>
          </table>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/reverse_proxy.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/howto/reverse_proxy.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/reverse_proxy.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/auth.html.ja.utf8����������������������������������������������������0000664�0001751�0001751�00000130177�14743132254�021312� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>認証、承認、アクセス制御 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">How-To / チュートリアル</a></div><div id="page-content"><div id="preamble"><h1>認証、承認、アクセス制御</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>「認証」とは、誰かが自分は誰であるかを主張した場合に、
        それを確認するための全過程を指します。「承認」とは、
        誰かが行きたい場所に行けるように、あるいは欲しい情報を
        得ることができるようにするための全過程を指します。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">関連するモジュールとディレクティブ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#introduction">はじめに</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#theprerequisites">準備</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#gettingitworking">動作させる</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#lettingmorethanonepersonin">
    複数の人が入れるようにする</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#possibleproblems">起こりえる問題</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbmdbd">パスワードの保存形式を変える</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multprovider">複数のプロバイダを使用する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#beyond">単純な承認のその先</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">追加情報</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">関連するモジュールとディレクティブ</a></h2>
    <p>認証と承認の処理に関連する 3 種類のモジュールがあります。
    それぞれ少なくともひとつずつ必要です。</p>
    
    <ul>
      <li>認証のタイプ (
          <code class="directive"><a href="../mod/core.html#authtype">AuthType</a></code> ディレクティブ参照)
        <ul>
          <li><code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code></li>
          <li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li>
        </ul>
      </li>
      <li>認証プロバイダ (
      <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code>,
      <code class="directive"><a href="../mod/mod_auth_digest.html#authdigestprovider">AuthDigestProvider</a></code> ディレクティブ参照)
    
        <ul>
          <li><code class="module"><a href="../mod/mod_authn_anon.html">mod_authn_anon</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_default.html">mod_authn_default</a></code></li>
          <li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
        </ul>
      </li>
      <li>承認 (
          <code class="directive"><a href="../mod/core.html#require">Require</a></code> ディレクティブ参照)
        <ul>
          <li><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_default.html">mod_authz_default</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_owner.html">mod_authz_owner</a></code></li>
          <li><code class="module"><a href="../mod/mod_authz_user.html">mod_authz_user</a></code></li>
        </ul>
      </li>
    </ul>
    
      <p>これらのモジュールに加えて、<code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code>
      と <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> があります。
      この 2 つのモジュールは認証モジュールに共通なコアディレクティブを
      実装しています。</p>
    
      <p><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> は認証プロバイダと承認プロバイダの
      両方の機能を持っています。
      <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code> はホスト名、IP アドレスや
      リクエストの特徴に基づいたアクセス制御を行いますが、
      認証プロバイダのシステムの一部ではありません。
      mod_access との後方互換性のため、
      新しいモジュールの <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> があります。</p>
    
      <p>様々なアクセス制御の行ない方については、
      <a href="access.html">アクセス制御</a>の方法をご覧ください。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">はじめに</a></h2>
        <p>もし機密の情報や、ごくごく少数グループの人向けの情報を
        ウェブサイトに置くのであれば、この文書に書かれている
        テクニックを使うことで、そのページを見ている人たちが
        望みの人たちであることを確実にできるでしょう。</p>
    
        <p>この文書では、多くの人が採用するであろう、
        ウェブサイトの一部分を保護する「一般的な」
        方法についてカバーしています。</p>
    
        <div class="note"><h3>注意</h3>
        <p>データが本当に機密なのであれば、認証に加えてさらに
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> を使うと良いでしょう。</p>
        </div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="theprerequisites" id="theprerequisites">準備</a></h2>
        <p>この文書で取り扱われるディレクティブは、
        メインサーバ設定ファイル (普通は 
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
        セクション中) か、あるいはディレクトリ毎の設定ファイル 
        (<code>.htaccess</code> ファイル) かで用います。</p>
    
        <p><code>.htaccess</code> ファイルを用いるのであれば、
        これらのファイルに認証用のディレクティブを置けるように
        サーバの設定をしないといけないでしょう。これは
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        ディレクティブで可能になります。
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        ディレクティブでは、ディレクトリ毎の設定ファイル中に置くことのできる
        ディレクティブを、もしあれば、指定します。</p>
    
        <p>認証について話を進めているので、次のような
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        ディレクティブが必要になるでしょう。</p>
    
        <div class="example"><p><code>
          AllowOverride AuthConfig
        </code></p></div>
    
        <p>そうでなく、メインサーバ設定ファイルの中に
        直接置くのであれば、当然ながらそのファイルへの書き込み
        権限を持っていなければならないでしょう。</p>
    
        <p>また、どのファイルがどこに保存されているか知るために、
        サーバのディレクトリ構造について少し知っておく
        必要があるでしょう。
        これはそんなに難しくないので、この文書中で
        ディレクトリ構造について知っておく必要がある場面では、
        明らかになるようにします。</p>
    
        <p><code class="module"><a href="../mod/mod_authn_core.html">mod_authn_core</a></code> と <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> 
        の両方が httpd バイナリに静的に組み込み済みであるか、httpd.conf 
        設定ファイルで動的にロードされるかして、httpd に組み込まれていなければ
        なりません。これらの二つのモジュールは、設定ファイルのなかで非常に
        重要でウェブサーバの認証と承認で使用されるコアディレクティブと
        その機能を提供しています。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gettingitworking" id="gettingitworking">動作させる</a></h2>
        <p>では、サーバ上のあるディレクトリをパスワードで保護する
        基本手順を示します。</p>
    
        <p>まずはじめに、パスワードファイルを作ります。
        どの認証プロバイダを使うかによって、パスワードファイル生成の手順は
        大きく異なります。ここでの例では、手始めにテキストパスワードファイルを
        使います。</p>
    
        <p>このパスワードファイルは、ウェブからアクセスできる場所に
        置くべきではありません。他の人がパスワードファイルを
        ダウンロードできないようにするためです。例えば、
        <code>/usr/local/apache/htdocs</code> でドキュメントを
        提供しているのであれば、パスワードファイルは
        <code>/usr/local/apache/passwd</code>
        などに置いた方が良いでしょう。</p>
    
        <p>ファイルを作るためには、Apache 付属の <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> 
        を使います。このコマンドは Apache をどこにインストールしようとも、
        インストールディレクトリの <code>bin</code> 
        ディレクトリ以下に置かれます。サードバーティ製のパッケージで
        インストールした場合は、実行パスの中で見つかるでしょう。</p>
        
        <p>ファイルを作るには、次のようにタイプしてください。</p>
    
        <div class="example"><p><code>
          htpasswd -c /usr/local/apache/passwd/passwords rbowen
        </code></p></div>
    
        <p><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> は、パスワードを要求し、その後
        確認のためにもう一度入力するように要求してきます。</p>
    
        <div class="example"><p><code>
          # htpasswd -c /usr/local/apache/passwd/passwords rbowen<br />
          New password: mypassword<br />
          Re-type new password: mypassword<br />
          Adding password for user rbowen
        </code></p></div>
    
        <p>もし <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> がパスの中に入っていない場合は、
        もちろん、実行するためにプログラムまでのフルパスを
        タイプする必要があります。デフォルトのインストール状態であれば、
        <code>/usr/local/apache/bin/htpasswd</code>
        にプログラムが置かれています。</p>
    
        <p>次に、サーバがパスワードを要求するように設定して、
        どのユーザがアクセスを許されているかをサーバに知らせなければ
        なりません。 <code>httpd.conf</code> を編集するか
        <code>.htaccess</code> ファイルを使用するかで
        設定します。例えば、ディレクトリ
        <code>/usr/local/apache/htdocs/secret</code>
        を保護したい場合は、
        <code>/usr/local/apache/htdocs/secret/.htaccess</code>
        か httpd.conf 中の &lt;Directory
        /usr/local/apache/htdocs/secret&gt; セクションに
        配置して、次のディレクティブを使うことができます。</p>
    
        <div class="example"><p><code>
          AuthType Basic<br />
          AuthName "Restricted Files"<br />
          # (Following line optional)<br />
          AuthBasicProvider file<br />
          AuthUserFile /usr/local/apache/passwd/passwords<br />
          Require user rbowen
        </code></p></div>
    
        <p>個々のディレクティブについて見てみましょう。
        <code class="directive"><a href="../mod/core.html#authtype">AuthType</a></code>
        ディレクティブはどういう認証方法でユーザの認証を行うかを
        選択します。最も一般的な方法は <code>Basic</code>
        で、これは <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code>
        で実装されています。しかしながら、
        これは気を付けるべき重要なポイントなのですが、
        Basic 認証はクライアントからサーバへ、
        パスワードを暗号化せずに送ります。ですからこの方法は、
        <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> と組み合わせない状態では、
        特に機密性の高いデータに対しては用いるべきでは
        ありません。 Apache ではもう一つ別の認証方法:
        <code>AuthType Digest</code> をサポートしています。
        この方法は <code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code>
        で実装されていて、もっと安全です。
        最近のクライアントは Digest
        認証をサポートしているようです。</p>
    
        <p><code class="directive"><a href="../mod/core.html#authname">AuthName</a></code>
        ディレクティブでは、認証に使う <dfn>Realm</dfn> (訳注: 領域)
        を設定します。Realm は大きく分けて二つの機能を提供します。
        一つ目は、クライアントがパスワードダイアログボックスの
        一部としてユーザにこの情報をよく提示する、というものです。
        二つ目には、クライアントが与えられた認証領域に対してどのパスワードを
        送信すれば良いのかを決定するために使われる、という機能です。</p>
    
        <p>例えば、<code>"Restricted Files"</code> 領域中で
        一度認証されれば、同一サーバ上で <code>"Restricted Files"</code>
        Realm としてマークされたどんな領域でも、クライアントは
        自動的に同じパスワードを使おうと試みます。
        このおかげで、複数の制限領域に同じ realm を共有させて、
        ユーザがパスワードを何度も要求される事態を
        防ぐことができます。もちろん、セキュリティ上の理由から、
        サーバのホスト名が変わればいつでも必ず、
        クライアントは再びパスワードを尋ねる必要があります。</p>
    
        <p><code class="directive"><a href="../mod/mod_auth_basic.html#authbasicprovider">AuthBasicProvider</a></code>
        はデフォルト値が <code>file</code> なので、今回の場合は無くても構いません。
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> や <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>
        といった他のモジュールを使う場合には必要になります。
        </p>
    
        <p><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code>
        ディレクティブは <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> で作った
        パスワードファイルへのパスを設定します。
        ユーザ数が多い場合は、リクエスト毎のユーザの認証のための
        プレーンテキストの探索が非常に遅くなることがあります。
        Apache ではユーザ情報を高速なデータベースファイルに
        保管することもできます。
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> モジュールが
        <code class="directive"><a href="../mod/mod_authn_dbm.html#authdbmuserfile">AuthDBMUserFile</a></code>
        ディレクティブを提供します。これらのファイルは <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code>
        プログラムで作成したり操作したりできます。
        <a href="http://modules.apache.org/">Apache 
        モジュールデータベース</a>中にあるサードパーティー製の
        モジュールで、その他多くのタイプの認証オプションが
        利用可能です。</p>
    
        <p>最後に、<code class="directive"><a href="../mod/core.html#require">Require</a></code>
        ディレクティブが、サーバのこの領域にアクセスできるユーザを
        指定することによって、プロセスの承認部分を提供します。
        次のセクションでは、<code class="directive"><a href="../mod/core.html#require">Require</a></code>
        ディレクティブの様々な用法について述べます。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="lettingmorethanonepersonin" id="lettingmorethanonepersonin">
    複数の人が入れるようにする</a></h2>
        <p>上記のディレクティブは、ただ一人 (具体的にはユーザ名
        <code>rbowen</code> の誰か) がディレクトリに
        入れるようにします。多くの場合は、複数の人が
        入れるようにしたいでしょう。ここで
        <code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code>
        の登場です。</p>
    
        <p>もし複数の人が入れるようにしたいのであれば、
        グループに属するユーザの一覧の入っている、グループ名のついた
        グループファイルを作る必要があります。このファイルの
        書式はきわめて単純で、お好みのエディタで生成できます。
        ファイルの中身は次のようなものです。</p>
    
       <div class="example"><p><code>
         GroupName: rbowen dpitts sungo rshersey
       </code></p></div>
    
        <p>一行にスペース区切りで、グループに所属するメンバーの
        一覧をならべるだけです。</p>
    
        <p>既に存在するパスワードファイルにユーザを加える場合は、
        次のようにタイプしてください。</p>
    
        <div class="example"><p><code>
          htpasswd /usr/local/apache/passwd/passwords dpitts
        </code></p></div>
    
        <p>以前と同じ応答が返されますが、新しいファイルを
        作るのではなく、既にあるファイルに追加されています。
        (新しいパスワードファイルを作るには <code>-c</code>
        を使います。)</p>
    
        <p>ここで次のようにして <code>.htaccess</code> ファイルを
        修正する必要があります。</p>
    
        <div class="example"><p><code>
          AuthType Basic<br />
          AuthName "By Invitation Only"<br />
          # Optional line:<br />
          AuthBasicProvider file<br />
          AuthUserFile /usr/local/apache/passwd/passwords<br />
          AuthGroupFile /usr/local/apache/passwd/groups<br />
          Require group GroupName
        </code></p></div>
    
        <p>これで、グループ <code>GroupName</code> にリストされていて、
        <code>password</code> ファイルにエントリがある人は、
        正しいパスワードをタイプすれば入ることができるでしょう。</p>
    
        <p>もっと特定せずに複数のユーザが入れるようにする、
        もう一つの方法があります。グループファイルを作るのではなく、
        次のディレクティブを使えばできます。</p>
    
        <div class="example"><p><code>
          Require valid-user
        </code></p></div>
    
        <p><code>require user rbowen</code> 行でなく、上記を使うと、
        パスワードファイルにリストされている人であれば誰でも
        許可されます。
        単にパスワードファイルをグループ毎に分けておくことで、
        グループのような振る舞いをさせることもできます。
        このアプローチの利点は、Apache は二つではなく、
        ただ一つのファイルだけを検査すればよいという点です。
        欠点は、たくさんのパスワードファイルを管理して、その中から
        <code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code>
        ディレクティブに正しいファイルを参照させなければならない点です。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="possibleproblems" id="possibleproblems">起こりえる問題</a></h2>
        <p>Basic 認証が指定されている場合は、
        サーバにドキュメントをリクエストする度に
        ユーザ名とパスワードを検査しなければなりません。
        これは同じページ、ページにある全ての画像を
        リロードする場合であっても該当します
         (もし画像も保護されたディレクトリから来るのであれば) 。
        予想される通り、これは動作を多少遅くします。
        遅くなる程度はパスワードファイルの大きさと比例しますが、
        これは、ファイルを開いてあなたの名前を発見するまで
        ユーザ名のリストを読まなければならないからです。
        そして、ページがロードされる度にこれを行わなければ
        なりません。</p>
    
        <p>結論としては、一つのパスワードファイルに置くことのできる
        ユーザ数には実質的な限界があります。
        この限界はサーバマシンの性能に依存して変わりますが、
        数百のエントリを越えたあたりから速度低下が見られると予期されています。
        その時は他の認証方法を考慮に入れた方が良いでしょう。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbmdbd" id="dbmdbd">パスワードの保存形式を変える</a></h2>
    
        <p>プレーンテキストでパスワードを保存する方法には上記の問題があり、
        データベースのような別の場所にパスワードを保存したいと思う
        かもしれません。</p>
    
        <p><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> と <code class="module"><a href="../mod/mod_authn_dbd.html">mod_authn_dbd</a></code>
        を使うと、それができるようになります。
        <code class="directive"><a href="../mod/mod_auth_basic.html#authbasicsource">AuthBasicSource</a></code>
        で file の代わりに、<code>dbm</code> あるいは <code>dbd</code>
        を格納形式として選べます。</p>
    
        <p>テキストファイルの代わりに dbm ファイルを選択する場合は、たとえば次のようにします。</p>
    
        <div class="example"><p><code>
        &lt;Directory /www/docs/private&gt;<br />
        AuthName "Private"<br />
        AuthType Basic<br />
        AuthBasicProvider dbm<br />
        AuthDBMUserFile /www/passwords/passwd.dbm<br />
        Require valid-user<br />
        &lt;/Directory&gt;
        </code></p></div>
    
        <p>この他のオプションも存在します。詳細に関しては
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> のドキュメントをご覧ください。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multprovider" id="multprovider">複数のプロバイダを使用する</a></h2>
    
        <p>認証承認アーキテクチャに基づいている新しいプロバイダを使うと、
        認証承認の方法をひとつに縛る必要がなくなります。
        いくつものプロバイダを組み合わせて、自分の望みの挙動にできます。
        次の例では file 認証プロバイダと ldap 認証プロバイダを
        組み合わせています。</p>
    
        <div class="example"><p><code>
        &lt;Directory /www/docs/private&gt;<br />
        AuthName "Private"<br />
        AuthType Basic<br />
        AuthBasicProvider file ldap<br />
        AuthUserFile /usr/local/apache/passwd/passwords<br />
        AuthLDAPURL ldap://ldaphost/o=yourorg<br />
        Require valid-user
        </code></p></div>
    
        <p>この例では、まず file プロバイダがユーザ認証を試みます。
        認証できなかった場合には、ldap プロバイダが呼び出されます。
        組織で複数の認証格納方法を使っている際などに、
        この方法を使って認証のスコープを拡大できます。
        もうひとつのシナリオは、ひとつの認証タイプと異なる承認を
        組み合わせる方法でしょう。たとえば、パスワードファイルで認証して、
        ldap ディレクトリで承認を行うといった場合です。</p>
    
        <p>認証プロバイダを複数実装できるように、承認方法も複数使用できます。
        この例では file グループ承認と ldap グループ承認を使っています。</p>
    
        <div class="example"><p><code>
        &lt;Directory /www/docs/private&gt;<br />
        AuthName "Private"<br />
        AuthType Basic<br />
        AuthBasicProvider file<br />
        AuthUserFile /usr/local/apache/passwd/passwords<br />
        AuthLDAPURL ldap://ldaphost/o=yourorg
        AuthGroupFile /usr/local/apache/passwd/groups<br />
        Require group GroupName<br />
        Require ldap-group cn=mygroup,o=yourorg
        </code></p></div>
    
        <p>承認をより細かく制御したい場合は、
        <code class="directive"><a href="../mod/mod_authz_core.html#&lt;satisfyall&gt;">&lt;SatisfyAll&gt;</a></code> と
        <code class="directive"><a href="../mod/mod_authz_core.html#&lt;satisfyone&gt;">&lt;SatisfyOne&gt;</a></code> 
        ディレクティブを使って AND/OR ロジックで指定し、設定ファイルで
        承認の処理順番の制御ができるようになっています。
        これらのディレクティブをどのように使えるか、網羅した例をご覧ください。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="beyond" id="beyond">単純な承認のその先</a></h2>
    
        <p>承認の方法は、ひとつのデータソースを見て一回だけチェックするのと比べて、
        ずっと多彩な適用方法ができます。
        承認処理の適用順序や制御、選択ができるようになりました。</p>
    
        <h3><a name="authandororder" id="authandororder">AND/OR ロジックの適用と順序付け</a></h3>
            <p>承認がどのような順序で適用されているか、また、それをどのように制御するかは、
            これまで混乱を招いていました。
            Apache 2.2 ではプロバイダベースの認証メカニズムが導入され、
            承認処理から認証処理とサポート機能とが切り分けられました。
            これによるひとつの効果として、
            認証モジュールのロード順やモジュール自体の順序に依存することなく、
            指定した順番で認証プロバイダが呼び出せるよう、
    	設定できるようになりました。
            このプロバイダメカニズムは承認処理でも導入されています。
            つまり、<code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
            ディレクティブは単にどの承認手法が使われるかを指定するだけではなく、
            それらの呼び出し順序も指定できるようになりました。
            複数の承認手法があるとき、その呼び出し順は、設定ファイルの
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> ディレクティブ中で
            現れた順序と同じになります。</p>
    
            <p>追加で導入された
            <code class="directive"><a href="../mod/mod_authz_core.html#&lt;satisfyall&gt;">&lt;SatisfyAll&gt;</a></code>,
            <code class="directive"><a href="../mod/mod_authz_core.html#&lt;satisfyone&gt;">&lt;SatisfyOne&gt;</a></code>
            ディレクティブを使って、承認手法がいつ呼び出され、アクセスが許可された際に
            どの手続きが適用されるか指定することができます。
            たとえば、次の承認ブロックのロジックを見てみましょう:</p>
    
            <div class="example"><p><code>
              # if ((user == "John") ||<br />
              # &nbsp;&nbsp; ((Group == "admin")<br />
              # &nbsp; &nbsp; &amp;&amp; (ldap-group &lt;ldap-object&gt; contains auth'ed_user)<br />
              # &nbsp; &nbsp; &amp;&amp; ((ldap-attribute dept == "sales")<br />
              # &nbsp; &nbsp; &nbsp; &nbsp; || (file-group contains auth'ed_user))))<br />
              # then<br />
              # &nbsp; auth_granted<br />
              # else<br />
              # &nbsp; auth_denied<br />
              #<br />
              &lt;Directory /www/mydocs&gt;<br />
              <span class="indent">
                Authname ...<br />
                AuthBasicProvider ...<br />
                ...<br />
                Require user John<br />
                &lt;SatisfyAll&gt;<br />
                <span class="indent">
                  Require Group admins<br />
                  Require ldap-group cn=mygroup,o=foo<br />
                  &lt;SatisfyOne&gt;<br />
                  <span class="indent">
                    Require ldap-attribute dept="sales"<br />
                    Require file-group<br />
                  </span>
                  &lt;/SatisfyOne&gt;<br />
                </span>
                &lt;/SatisfyAll&gt;<br />
              </span>
              &lt;/Directory&gt;
            </code></p></div>
    
            <p>デフォルトでは <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
            ディレクティブは OR 操作として扱われます。つまり、もし指定した承認手法の
            ひとつでも合格すれば、承認されます。
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> ディレクティブのセットを
            ひとつの <code class="directive"><a href="../mod/mod_authz_core.html#&lt;satisfyall&gt;">&lt;SatisfyAll&gt;</a></code>
            ブロックで囲むとAND 操作となり、全ての承認手法で合格しなければ許可されません。</p>
    
        
    
        <h3><a name="reqaccessctrl" id="reqaccessctrl">アクセス制御における Require と Reject の使い方</a></h3>
            <p>ユーザ名とパスワードによる認証は全体の一部分でしかありません。
            誰がアクセスしてきたかといった情報以外の条件を使いたい、
    	とよく思うことでしょう。
            たとえば、どこからアクセスしてきているか、といった具合です。</p>
        
            <p>承認プロバイダ <code class="directive"><a href="../mod/mod_authz_host.html#all">all</a></code>,
            <code class="directive"><a href="../mod/mod_authz_host.html#env">env</a></code>, 
            <code class="directive"><a href="../mod/mod_authz_host.html#host">host</a></code>,
            <code class="directive"><a href="../mod/mod_authz_host.html#ip">ip</a></code>
            を使うと、リクエストを送信してきているマシンのホスト名や IP アドレス
            といった、ホストベースでのアクセス制御ができます。</p>
        
            <p>これらプロバイダの扱いは
            <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code> や
            <code class="directive"><a href="../mod/mod_authz_core.html#reject">Reject</a></code> で
            指定されます。これらのディレクティブは承認プロバイダを登録し、
            リクエスト処理の承認段階で呼び出されます。たとえば:</p>
        
            <div class="example"><p><code>
              Require ip <var>address</var>
            </code></p></div>
        
            <p>ここで、<var>address</var> は IP アドレス (あるいは IP アドレスの
            一部) か : </p>
        
            <div class="example"><p><code>
              Require host <var>domain_name</var>
            </code></p></div>
        
            <p>ここで <var>domain_name</var> は FQDN (あるいはドメイン名の一部)
            で、必要であれば複数のアドレスやドメイン名を書くことができます。</p>
        
            <p>たとえば、スパムメッセージを送信してくる誰かを拒否したい場合、
            次のようになります : </p>
        
            <div class="example"><p><code>
              Reject ip 10.252.46.165
            </code></p></div>
        
            <p>このディレクティブが有効な範囲のコンテンツに対しては、
            そのアドレスからアクセスしてきても見ることができません。
            もしマシン名がわかっていて IP アドレスよりもそちらで
            指定したいのであれば、そのマシン名が使えます。</p>
        
            <div class="example"><p><code>
              Reject host <var>host.example.com</var>
            </code></p></div>
        
            <p>また、特定のドメインからのアクセス全てをブロックしたい場合は、
            IP アドレスの一部や、ドメイン名が指定できます :</p>
        
            <div class="example"><p><code>
              &lt;SatisfyAll&gt;<br />
              <span class="indent">
                Reject ip <var>192.168.205</var><br />
                Reject host <var>phishers.example.com</var> <var>moreidiots.example</var><br />           Reject host ke<br />
              </span>
              &lt;/SatisfyAll&gt;
            </code></p></div>
        
            <p><code class="directive"><a href="../mod/mod_authz_host.html#reject">Reject</a></code> ディレクティブを
            <code class="directive"><a href="../mod/mod_authz_core.html#&lt;satisfyall&gt;">&lt;SatisfyAll&gt;</a></code> ブロックの中で使うと、
            許可したいグループにのみアクセスができるように確認できます。</p>
        
            <p>上記の例では <code class="directive"><a href="../mod/mod_authz_core.html#&lt;satisfyall&gt;">&lt;SatisfyAll&gt;</a></code>
            を使って、アクセスに合格する前段階で、全ての 
            <code class="directive"><a href="../mod/mod_authz_host.html#reject">Reject</a></code> ディレクティブが
            満たされていることを確認しています。</p>
        
        
    
        <h3><a name="filesystem" id="filesystem">アクセス制御の後方互換性</a></h3>
            <p>認証プロバイダベースの機構があるため、以前使用されていたディレクティブ
            <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code>,
            <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>,
            <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code>,
            <code class="directive"><a href="../mod/mod_access_compat.html#satisfy">Satisfy</a></code>
            は必要なくなりました。
            とはいうものの、古い設定ファイルでの後方互換性を提供するため、
            これらのディレクティブは <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> モジュールに移されました。</p>
    
            <p>これらのディレクティブの抱えていた問題のひとつに、承認の設定行とアクセス制御の設定行の
            関係がとてもあいまいだったことが挙げられます。
            <code class="directive"><a href="../mod/mod_access_compat.html#satisfy">Satisfy</a></code> ディレクティブは
            リクエスト処理中でそれ自身を呼び出すことによって、これらの 2 つの処理段階を結びつけようとします。
            現在は、これらのディレクティブは <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code> に移動し、
            新しい認証ディレクティブと古いアクセス制御ディレクティブを混ぜて使うことは
            難しくなっています。この問題のため、<code class="module"><a href="../mod/mod_authz_default.html">mod_authz_default</a></code> モジュールを
            ロードすることがとても重要で、必須になっています。
            <code class="module"><a href="../mod/mod_authz_default.html">mod_authz_default</a></code> モジュールの主な目的は、どの承認プロバイダで
            処理されなかった承認リクエストを受けることにあります。
            しかし、古いアクセス制御ディレクティブが用いられた場合には、
            アクセス制御と承認を結びつけて、すべての処理段階の出力結果を見てアクセスに合格するかを決めています。
            ですから、古いディレクティブがうまく動作しない場合は、
            <code class="module"><a href="../mod/mod_authz_default.html">mod_authz_default</a></code> がロードされていないからかもしれない、
            と疑ってみてください。</p>
    
        
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">追加情報</a></h2>
        <p>これら全てがどのように動作するかについて
        もっと多くの情報が書かれている <code class="module"><a href="../mod/mod_auth_basic.html">mod_auth_basic</a></code> と
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>
        の文書も読むとよいでしょう。
        <code class="directive"><a href="../mod/mod_authn_core.html#&lt;authnprovideralias&gt;">&lt;AuthnProviderAlias&gt;</a></code>
        ディレクティブを使うと、特定の認証設定が簡単に書けるようになります。</p>
    
        <p><a href="access.html">アクセス制御</a>の方法も、
        関連するトピックがたくさん記載されていますので、ご覧ください。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/auth.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/auth.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/auth.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/auth.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/auth.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/auth.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/auth.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/cgi.html.ja.utf8�����������������������������������������������������0000664�0001751�0001751�00000107713�14743132254�021113� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache Tutorial: CGI による動的コンテンツ - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">How-To / チュートリアル</a></div><div id="page-content"><div id="preamble"><h1>Apache Tutorial: CGI による動的コンテンツ</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#intro">はじめに</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">CGI を許可するように Apache を設定する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#writing">CGI プログラムを書く</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">しかし、まだ動かない !</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#behindscenes">裏で何が起こっているのか?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#libraries">CGI モジュール/ライブラリ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinfo">更なる情報</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">はじめに</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li></ul></td></tr></table>
    
        <p>CGI (Common Gateway Interface) は、ウェブサーバが
        コンテンツ生成をする外部プログラムと協調して動作するための方法を
        定義しています。そのプログラムはしばしば CGI プログラムや
        CGI スクリプトと呼ばれます。CGI は、ウェブサイトに動的な
        コンテンツを置くための最も簡単で一般的な方法です。このドキュメントは、
        Apache ウェブサーバで CGI を設定し、
        CGI プログラムを書き始めるための入門書となるでしょう。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">CGI を許可するように Apache を設定する</a></h2>
        
    
        <p>CGI プログラムを正しく動作させるには、CGI を許可するように
        Apache の設定を行う必要があります。
        これを行なうための方法がいくつかあります。</p>
    
        <div class="warning">
        注: Apache が共有モジュール機能着きでビルドされている場合、
        モジュールがロードされていることを確認してください。
        つまり <code>httpd.conf</code> で 
        <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>
        がコメントアウトされていないことを確認してください。
        正常に設定されていれば次のようになるはずです:
    
        <div class="example"><p><code>
          LoadModule cgi_module modules/mod_cgi.so
        </code></p></div></div>
    
        <h3><a name="scriptalias" id="scriptalias">ScriptAlias</a></h3>
          
    
          <p><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          ディレクティブを使用して、
          CGI プログラム用の特別な別ディレクトリを Apache に設定します。
          Apache は、このディレクトリ中の全てのファイルを CGI
          プログラムであると仮定します。
          そして、この特別なリソースがクライアントから要求されると、
          そのプログラムの実行を試みます。</p>
    
          <p><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          ディレクティブは以下のように使用します:</p>
    
          <div class="example"><p><code>
            ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/
          </code></p></div>
    
          <p>デフォルト位置に Apache をインストールしたならば、
          この例はデフォルト状態の <code>httpd.conf</code>
          設定ファイルに含まれています。
          <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          ディレクティブは、URL の前に付加するディレクトリを定義する
          <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>
          ディレクティブとかなり似ています。
          <code class="directive">Alias</code> と <code class="directive">ScriptAlias</code>
          は通常、<code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
          ディレクトリ外のディレクトリのために使用されます。
          <code class="directive">Alias</code> と <code class="directive">ScriptAlias</code>
          との差は、<code class="directive">ScriptAlias</code> が接頭辞で始まるすべての
          URL は CGI プログラムとみなされるという追加の意味を含んでいることです。
          従って、上記の例では、<code>/cgi-bin/</code>
          で始まるリソースへのあらゆるリクエストに対して、ディレクトリ
          <code>/usr/local/apache2/cgi-bin/</code> から提供し、それらを
          CGI プログラムとして扱うよう Apache に示します。</p>
    
          <p>例えば、URL <code>http://www.example.com/cgi-bin/test.pl</code>
          が要求された場合、Apache は ファイル
          <code>/usr/local/apache2/cgi-bin/test.pl</code>
          を実行し、その出力を返すことを試みます。
          もちろん、ファイルが存在し、実行可能であり、決められた方法で出力を返します。
          そうでなければ、Apache はエラーメッセージを返します。</p>
        
    
        <h3><a name="nonscriptalias" id="nonscriptalias">ScriptAlias ディレクトリ外の CGI</a></h3>
          
    
          <p>CGI プログラムは、セキュリティ上の理由から 
          <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
          されたディレクトリに制限されることがしばしばあります。この方法により、
          CGI プログラムを使用できるユーザを管理者が厳しく制御することができます。
          しかしながら、適切なセキュリティ事前対策がとられるならば、CGI
          プログラムを任意のディレクトリで実行できないようにする理由はありません。
          例えば、ユーザに <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
          ディレクティブで彼らのホームディレクトリ配下にウェブコンテンツを持たせたいとします。
          もし、彼らが CGI プログラムを持つことを望んでいても、メインの
          <code>cgi-bin</code> ディレクトリへのアクセスができない場合、
          CGI プログラムを実行することができる他の場所が必要になります。</p>
    
          <p>任意のディレクトリで CGI の実行を許可するには二段階の設定が必要です。
          まず、<code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> や <code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code> ディレクティブによって
          <code>cgi-script</code> ハンドラが可能になっている必要があります。
          次に、<code class="directive"><a href="../mod/core.html#options">Options</a></code> ディレクティブで
          <code>ExecCGI</code> が指定されていなければなりません。</p>
        
    
        <h3><a name="options" id="options">CGI の実行を可能にするために Options を明示的に使用する</a></h3>
          
    
          <p>サーバのメインの設定ファイル中で <code class="directive"><a href="../mod/core.html#options">Options</a></code>
          ディレクティブを明示的に使用することで、特定のディレクトリ配下で
          CGI の実行を許可するように指定することができます:</p>
    
          <div class="example"><p><code>
            &lt;Directory /usr/local/apache2/htdocs/somedir&gt;<br />
            <span class="indent">
              Options +ExecCGI<br />
            </span>
            &lt;/Directory&gt;
          </code></p></div>
    
          <p>上記ディレクティブは、CGI ファイルの実行を可能にするよう
          Apache に伝えます。また、どのファイルが CGI ファイルかを
          サーバに伝える必要があります。次の
          <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code>
          ディレクティブの例では、<code>cgi</code> または <code>pl</code>
          を拡張子に持つすべてのファイルを CGI
          プログラムとしてみなすことをサーバに伝えます:</p>
    
          <div class="example"><p><code>
            AddHandler cgi-script .cgi .pl
          </code></p></div>
        
    
        <h3><a name="htaccess" id="htaccess">.htaccess ファイル</a></h3>
          
    
          <p><a href="htaccess.html"><code>.htaccess</code> チュートリアル</a>
          は <code>httpd.conf</code> を変更できない場合にどうやって CGI プログラムを
          使えるようにするかを説明しています。</p>
        
    
        <h3><a name="userdir" id="userdir">User ディレクトリ</a></h3>
          
    
          <p><code>.cgi</code> で終わるすべてのファイルに対して CGI プログラムの
          実行を許可するには、以下の設定を使用できます。</p>
    
          <div class="example"><p><code>
          &lt;Directory /home/*/public_html&gt;<br />
          <span class="indent">
            Options +ExecCGI<br />
            AddHandler cgi-script .cgi<br />
          </span>
          &lt;/Directory&gt;
          </code></p></div>
    
          <p>ユーザディレクトリの <code>cgi-bin</code> サブディレクトリの
          すべてのファイルを CGI プログラムとして指定したい場合には
          以下のようなものを使います。</p>
    
          <div class="example"><p><code>
          &lt;Directory /home/*/public_html/cgi-bin&gt;<br />
          <span class="indent">
            Options ExecCGI<br />
            SetHandler cgi-script<br />
          </span>
          &lt;/Directory&gt;
          </code></p></div>
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="writing" id="writing">CGI プログラムを書く</a></h2>
        
    
        <p>「通常の」プログラミングと CGI
        プログラミングの間には主に二つの違いがあります。</p>
    
        <p>一つは、CGI プログラムのすべての出力には<a class="glossarylink" href="../glossary.html#mime-type" title="用語集を参照">MIME タイプ</a>
        ヘッダを付けなければなりません。
        これはどのような種類のコンテンツを受け取っているかをクライアントに示す
        HTTP ヘッダです。ほとんどの場合では、次のように出力します:</p>
    
        <div class="example"><p><code>
          Content-type: text/html
        </code></p></div>
    
        <p>もう一つは、出力を HTML
        か、ブラウザが表示することができる何か他の形式にする必要があります。
        大抵の場合は HTML でしょうが、GIF イメージや他の非 HTML
        コンテンツを出力する CGI プログラムを書くこともあるでしょう。</p>
    
        <p>これら二点以外では、CGI プログラムを書くことは、
        あなたが書いている他のプログラムとよく似ているでしょう。</p>
    
        <h3><a name="firstcgi" id="firstcgi">最初の CGI プログラム</a></h3>
          
    
          <p>次に示すのは、ブラウザに 1 行印字する CGI
          プログラムの例です。以下を入力し、<code>first.pl</code>
          というファイルに保存し、それを <code>cgi-bin</code>
          ディレクトリに置いてください。</p>
    
          <div class="example"><p><code>
            #!/usr/bin/perl<br />
            print "Content-type: text/html\n\n";<br />
            print "Hello, World.";
          </code></p></div>
    
          <p>Perl に精通していなくても、
          何が起こるかを理解することはできるでしょう。1 行目は、
          <code>/usr/bin/perl</code> で見つけられるインタプリタに
          このファイルを供給することでこのプログラムが実行されることを
          Apache に (シェル上で実行しようとしているならば、そのシェルに ) 
          示します。2 行目は、前述したとおり content-type の定義を印字します。
          これには復帰改行の二つの組を後に付加します。
          これにより、ヘッダの終りに空行が置かれ、HTTP
          ヘッダの終りとボディの始まりを示します。3 行目は、"Hello, World."
          という文字列を印字し、これで終りとなります。</p>
    
          <p>好みのブラウザを開き、アドレス</p>
    
          <div class="example"><p><code>
            http://www.example.com/cgi-bin/first.pl
          </code></p></div>
    
          <p>あるいはファイルを置いたロケーションを指定すると、
          <code>Hello, World.</code>
          という 1 行がブラウザウィンドに現れるでしょう。
          それはあまりエキサイティングなことではありません。
          しかし、これがうまく動けば、
          他のどのようなものでも動かすことができるようになります。</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">しかし、まだ動かない !</a></h2>
        
    
        <p>ウェブから CGI プログラムへのアクセスを行なったとき、
        ブラウザで見る可能性がある四つの基本的なことがあります:</p>
    
        <dl>
          <dt>CGI プログラムの出力</dt>
          <dd>素晴らしい ! それはすべてがうまく動いたことを意味します。
          出力が正常だけれども、ブラウザが正常に処理してくれない場合は、
          正しい <code>Content-Type</code> を CGI プログラム内で
          セットしたかを確認してください。</dd>
    
          <dt>CGI プログラムのソースコード、または "POST Method Not Allowed"
          というメッセージ</dt> 
          <dd>これは、CGI プログラムを処理できるよう Apache
          を適切に設定していなかったことを意味します。<a href="#configuring">「CGI を許可するように
          Apache を設定する」</a>の章を読み直し、
          あなたが何を間違えたかを探してみてください。
          </dd>
    
          <dt>メッセージが "Forbidden" で始まっている</dt>
          <dd>これはパーミッションの問題ということを意味します。
          <a href="#errorlogs">Apache のエラーログ</a>と、後述の<a href="#permissions">「ファイルのパーミッション」</a>
          の章をチェックしてください。
          </dd>
    
          <dt>"Internal Server Error" というメッセージ</dt>
          <dd><a href="#errorlogs">Apache
          のエラーログ</a>をチェックすると、"Premature end of script headers"
          というログが記録されていると思います。そして、おそらく CGI
          プログラムによって生成されたエラーメッセージも記録されているでしょう。
          この場合、CGI プログラムが適切な
          HTTP ヘッダを出力できない原因を知るために、
          以下の各章でチェックしてみてください。</dd>
        </dl>
    
        <h3><a name="permissions" id="permissions">ファイルのパーミッション</a></h3>
          
    
          <p>サーバはあなたの権限で実行されていないのを忘れないように。
          つまり、起動するとき、サーバは特権をもたないユーザ - 通常 <code>nobody</code>
          や <code>www</code> の権限で実行されます。したがって、あなたが所有する
          ファイルを実行するには別のパーミッションが必要となります。
          通常、<code>nobody</code> が実行するのに十分なパーミッションを与える方法は、
          ファイルに誰でも実行可能とするパーミッションを与えることです:</p>
    
          <div class="example"><p><code>
            chmod a+x first.pl
          </code></p></div>
    
          <p>また、もしあなたのプログラムが他のファイルを読み書きするならば、
          それらのファイルは、これが可能となる正しいパーミッション
          を持っている必要があります。</p>
    
        
    
        <h3><a name="pathinformation" id="pathinformation">パス情報と環境</a></h3>
          
    
          <p>コマンドラインからプログラムを実行するとき、
          意識しなくてもシェルに渡される情報があります。
          例えば、参照するファイルのためにどこを検索したらよいかを
          シェルに伝える <code>PATH</code> があります。</p>
    
          <p>プログラムが CGI プログラムとしてウェブサーバによって実行されるとき、
          それは同じ <code>PATH</code> ではないかもしれません。
          CGI プログラム内で呼び出すあらゆるプログラム
          (例えば、<code>sendmail</code> のようなもの) は、
          フルパスで指定する必要があるでしょう。それにより、CGI
          プログラムを実行しようとしたとき、
          シェルはそのようなプログラムを見つけることができます。</p>
    
          <p>同様なことは、スクリプトのインタプリタ (しばしば <code>perl</code>)
          へのパスで、CGI プログラムの 1 行目に次のように示されます:</p>
    
          <div class="example"><p><code>
            #!/usr/bin/perl
          </code></p></div>
    
          <p>これがインタープリタへの実際のパスであることを確認しておきます。</p>
        
    
          <p>また、CGI プログラムが他の<a href="#env">環境変数</a>に依存している場合は、その環境変数が
          Apache から渡されるようにする必要があります。</p>
    
        <h3><a name="syntaxerrors" id="syntaxerrors">プログラムエラー</a></h3>
          
    
          <p>CGI
          プログラムが失敗するのは大抵、プログラム自身に問題がある場合です。
          一度 CGI の使い方を理解し、前述の二つの誤りを犯していないならば、
          まず間違いなくそうでしょう。ブラウザを使ってテストする前に
          まず確認することは、コマンドラインからプログラムが実行できることです。
          例えば、以下を実行してみてください:</p>
    
          <div class="example"><p><code>
          cd /usr/local/apache2/cgi-bin<br />
          ./first.pl
          </code></p></div>
    
          <p>(<code>perl</code> インタプリタは呼ばないでください。
          シェルと Apache がスクリプトの最初の行の <a href="#pathinformation">パス情報</a> を使って見つけます。)</p>
    
          <p>最初にプログラムから出力されるのは <code>Content-Type</code> を含み、
          後に空行の続く HTTP ヘッダでなければなりません。他のものが出力されている
          場合は、Apache はこのプログラムをサーバ経由で実行しようとしたときには
          <code>Premature end of script headers</code> エラーを出力します。詳細は
          上記の <a href="#writing">CGI プログラムを書く</a> を読んでください。</p>
        
    
        <h3><a name="errorlogs" id="errorlogs">エラーログ</a></h3>
          
    
          <p>エラーログは友達です。
          全てのうまくいかないことは、エラーログにメッセージを生成します。
          必ずそれを最初に見るべきです。
          もし、あなたがウェブサイトを主催している場所が
          エラーログの参照を許していないならば、きっと他のサイトで主催するべきです。
          エラーログの読み方を学ぶことで、ほとんど全ての問題が迅速に確認され、
          迅速に解決されるということが分かるでしょう。</p>
        
    
        <h3><a name="suexec" id="suexec">Suexec</a></h3>
          
    
          <p><a href="../suexec.html">suexec</a> サポートプログラムは
          バーチャルホストやユーザのホームディレクトリの場所に依って
          CGI プログラムを違うユーザ権限の下で走らせることを可能にします。
          Suexec の権限のチェックは非常に厳しく、それを満たさない場合は
          CGI プログラムが <code>Premature end of script headers</code> エラーで
          実行されません。</p>
    
          <p>suexec を使っているかどうかを調べためには <code>apachectl
          -V</code> を実行して、<code>SUEXEC_BIN</code> の場所を調べてください。
          Apache がそこに <code class="program"><a href="../programs/suexec.html">suexec</a></code> のバイナリを発見した場合は、suexec が
          使用されます。</p>
    
          <p>suexec を完全に理解していない限り、使うべきではありません。
          suexec を無効にするには、<code>SUEXEC_BIN</code> から指されている
          <code class="program"><a href="../programs/suexec.html">suexec</a></code> バイナリを削除 (か名前を変更) するだけです。
          <a href="../suexec.html">suexec</a> を読んだ後で、まだそれを
          使いたいのであれば、<code>suexec -V</code> を実行して suexec の
          ログファイルの位置を調べ、そのログファイルを使ってポリシー違反を
          見つけてください。</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behindscenes" id="behindscenes">裏で何が起こっているのか?</a></h2>
        
    
        <p>CGI プログラミングに習熟すると、
        裏で起こっていることについて更に理解することの役に立ちます。
        ブラウザとサーバがどのように相互通信するかについては特にそうです。
        なぜなら、"Hello, World."
        を印字するプログラムを書くことはおおいに結構ですが、
        それは特に有益ではありません。</p>
    
        <h3><a name="env" id="env">環境変数</a></h3>
          
    
          <p>環境変数は、
          あなたがコンピュータを使うときに辺りに存在している値です。
          それらは、パス
          (コマンドをタイプしたときに実行する実際のファイルを探し出すところ)、
          ユーザ名、端末型などのような便利なものです。
          通常、普段使用している環境変数の完全なリストを調べるには、
          コマンドプロンプトで <code>env</code> を入力します。</p>
    
          <p>CGI の処理中、サーバとブラウザも環境変数を設定し、
          それにより相互に通信することができるようになります。
          その環境変数は、ブラウザタイプ (Netscape, IE, Lynx)、サーバタイプ
          (Apache, IIS, WebSite)、実行されている CGI
          プログラムの名前などです。</p>
    
          <p>これらの変数は CGI プログラマが使用できます。
          そして、それはクライアントとサーバの通信の話の半分です。
          必要な変数の完全なリストは <a href="http://hoohoo.ncsa.uiuc.edu/cgi/env.html">http://hoohoo.ncsa.uiuc.edu/cgi/env.html</a> にあります。</p>
    
          <p>以下の単純な Perl CGI
          プログラムは、渡される全ての環境変数を表示します。同様のプログラムは、
          Apache ディストリビューションの <code>cgi-bin</code>
          ディレクトリに二つ含まれています。
          いくつかの変数が必須であり、いくつかは任意であることに注意してください。
          そして、公式のリストにはないいくつかの変数が表示されているかもしれません。
          さらに、Apache はデフォルトで用意されている基本的なものに
          <a href="../env.html">あなた自身の環境変数を加える</a>ための、
          多くの異なる方法を用意してします。</p>
    
          <div class="example"><p><code>
            #!/usr/bin/perl<br />
            print "Content-type: text/html\n\n";<br />
            foreach $key (keys %ENV) {<br />
            <span class="indent">
              print "$key --&gt; $ENV{$key}&lt;br&gt;";<br />
            </span>
            }
          </code></p></div>
        
    
        <h3><a name="stdin" id="stdin">STDIN と STDOUT</a></h3>
          
    
          <p>サーバとクライアント間のもう一つの通信は、標準入力
          (<code>STDIN</code>)と標準出力 (<code>STDOUT</code>)
          を通じて行なわれます。通常の文脈において、<code>STDIN</code>
          はキーボードやプログラムが動作するために与えられるファイルを意味し、
          <code>STDOUT</code> は通常コンソールまたはスクリーンを意味します。</p>
    
          <p>ウェブフォームから CGI プログラムへ<code>POST</code>
          したとき、フォームのデータは特別なフォーマットで束ねられ、
          <code>STDIN</code> を通して、CGI プログラムに引き渡されます。
          プログラムはデータがキーボード
          もしくはファイルから来ていたかのように処理することができます。</p>
    
          <p>「特別なフォーマット」はとても単純です。フィールド名と値はイコール
          (=) で結ばれます。そして値の組はアンパサンド (&amp;) で結ばれます。
          スペース、アンパサンド、イコールのような面倒な文字は、
          それらが動作を駄目にしないようにその文字に相当する 16 進に変換されます。
          全データ文字列は、以下のようになります:
          </p>
    
          <div class="example"><p><code>
            name=Rich%20Bowen&amp;city=Lexington&amp;state=KY&amp;sidekick=Squirrel%20Monkey
          </code></p></div>
    
          <p>時々、このような文字列が URL
          に付加されるのを見るでしょう。その場合、サーバは
          <code>QUERY_STRING</code> という環境変数にその文字列を入れます。それは
          <code>GET</code> リクエストと呼ばれます。
          HTML フォームでは、データを渡すために <code>GET</code> と
          <code>POST</code> のどちらを使用するかを、<code>FORM</code> タグの
          <code>METHOD</code> 属性の設定で指定します。</p>
    
          <p>CGI プログラムは、その文字列を役に立つ情報に分割する責任があります。
          幸いにも、そのデータ処理を助けるライブラリやモジュールが存在します。
          これらは、CGI プログラムの他の面でも同様に役に立ちます。</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="libraries" id="libraries">CGI モジュール/ライブラリ</a></h2>
        
    
        <p>CGI プログラムを書くとき、面倒な仕事の大部分をしてくれる
        コードライブラリまたはモジュールを使うことを検討すべきです。
        これはエラーを減らし、早い開発につながります。</p>
    
        <p>Perl で CGI プログラムを書いているなら、モジュールは <a href="http://www.cpan.org/">CPAN</a> で提供されています。
        この目的のための最も普及しているモジュールは <code>CGI.pm</code> です。
        <code>CGI::Lite</code> も検討しましょう。これは、ほとんどのプログラム
        において必要とするすべての機能の最小セットの実装です。</p>
    
        <p>C で CGI プログラムを書いているなら、いろいろな
        オプションがあります。これらの内の一つは <a href="http://www.boutell.com/cgic/">http://www.boutell.com/cgic/</a>
        で提供されている <code>CGIC</code> ライブラリです。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinfo" id="moreinfo">更なる情報</a></h2>
        
    
        <p>CGI に関する情報はウェブで数多く提供されています。CGI
        の問題については Usenet の <a href="news:comp.infosystems.www.authoring.cgi">comp.infosystems.www.authoring.cgi</a> で、
        他のユーザと論議することができます。HTML Writers Guide の
        -servers メーリングリストは、あなたの質問に回答してくれる偉大なリソースです。
        <a href="http://www.hwg.org/lists/hwg-servers/">http://www.hwg.org/lists/hwg-servers/</a>
        で更に多くを探し出すことができます。</p>
    
        <p>そしてもちろん、おそらく CGI
        プログラムの動作に関する詳細の全てが記述されている
        CGI の仕様を読むべきです。オリジナルバージョンを
        <a href="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html">NCSA</a>
        で、アップデートされたドラフトを
        <a href="http://web.golux.com/coar/cgi/">Common Gateway Interface RFC
        プロジェクト</a>で参照することができます。</p>
    
        <p>CGI の問題について、加わっているメーリングリストまたはニュース
        グループに質問を送るとき、起こったもの、起こってほしいこと、
        実際に起こったことがどう違うか、使用しているサーバ、
        CGI プログラムを記述している言語に関する十分な情報と、
        可能であれば問題のコードを提供するようにしてください。
        そうすることで、問題がより間単に見つかるようになります。</p>
    
        <p>Apache のソースコードにおいて問題を発見したことを確信していない限り、
        CGI の問題に関する質問を Apache
        バグデータベースに<strong>送るべきでない</strong>
        ことに注目してください。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/cgi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������httpd-2.4.64/docs/manual/howto/htaccess.html.ko.euc-kr����������������������������������������������0000664�0001751�0001751�00000050261�14743132254�022460� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ 丮: .htaccess  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>ġ 丮: .htaccess </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p><code>.htaccess</code>  Ͽ 丮 
      ִ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">.htaccess </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what"≯/ ϴ°</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#when"> .htaccess  ϳ
        (Ȥ  ʳ)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#how"> þ ϳ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#auth"> </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#ssi">Server Side Includes </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">CGI </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">ذ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">.htaccess </a></h2>
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/core.html">core</a></code></li><li><code class="module"><a href="../mod/mod_authn_file.html">mod_authn_file</a></code></li><li><code class="module"><a href="../mod/mod_authz_groupfile.html">mod_authz_groupfile</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="../mod/core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="../mod/mod_authn_file.html#authuserfile">AuthUserFile</a></code></li><li><code class="directive"><a href="../mod/mod_authz_groupfile.html#authgroupfile">AuthGroupFile</a></code></li><li><code class="directive"><a href="../mod/core.html#require">Require</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what"≯/ ϴ°</a></h2>
    
    
        <p><code>.htaccess</code> (Ȥ "л ")
        ϸ 丮    ִ.   þ
        ִ  Ư  丮 θ,  丮 
        丮 þ Ѵ.</p>
    
        <div class="note"><h3>:</h3>
          <p><code>.htaccess</code> ϸ ٸ ϰ ʹٸ,
          <code class="directive"><a href="../mod/core.html#accessfilename">AccessFileName</a></code> þ
          Ͽ   ִ.  , <code>.config</code>
          ϸ Ϸ  Ͽ   ߰Ѵ.</p>
    
          <div class="example"><p><code>
            AccessFileName .config
          </code></p></div>
        </div>
    
        <p>Ϲ <code>.htaccess</code>  <a href="../configuring.html#syntax">ּ</a> 
        . <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>
        þ  Ͽ   ִ  Ѵ.  þ
        <code>.htaccess</code> Ͽ ϴ þ з Ѵ.
        þ <code>.htaccess</code> Ͽ   ִٸ,
        ش þ  Override ׸ þ ϱ
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> 
         ˷ش.</p>
    
        <p> , <code class="directive"><a href="../mod/core.html#adddefaultcharset">AddDefaultCharset</a></code>
        þ    þ <code>.htaccess</code> Ͽ
          ִ. (þ ࿡  ׸ .)
        <a href="../mod/directive-dict.html#Context">Override</a>
        ٿ <code>FileInfo</code> ִ. ׷  þ
        <code>.htaccess</code> Ͽ ϱؼ ּ
        <code>AllowOverride FileInfo</code> ʿϴ.</p>
    
        <div class="example"><h3>:</h3><table>
            <tr>
              <td><a href="../mod/directive-dict.html#Context">:</a></td>
              <td>ּ, ȣƮ, directory, .htaccess</td>
            </tr>
    
            <tr>
              <td><a href="../mod/directive-dict.html#Override">Override:</a></td>
              <td>FileInfo</td>
            </tr>
          </table></div>
    
        <p>Ư þ <code>.htaccess</code> Ͽ 
         ִ ñϸ þ   ׸ ".htaccess"
        ִ ȮѴ.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="when" id="when"> .htaccess  ϳ
        (Ȥ  ʳ)</a></h2>
    
        <p>Ϲ ּϿ    찡 ƴ϶
        <code>.htaccess</code>  ϸ ȵȴ.  ,
          ׻ <code>.htaccess</code> Ͽ ־
        Ѵٴ  ߸ ˷ ش. ̴  ƴϴ. ּ
             ְ,  ̷ Ѵ.</p>
    
        <p><code>.htaccess</code>   ڰ 丮
          ٸϰ   ýۿ root 
         쿡 Ѵ.  ڰ   ϰ
           Ϲ ڰ  <code>.htaccess</code>
         ϵ ϴ  ٶϴ.  , 
        ǻͿ   Ʈ ϴ ISP ڰ
        ڽ  ϰ  찡 ׷ϴ.</p>
    
        <p>׷ Ϲ <code>.htaccess</code>  
        ؾ Ѵ. <code>.htaccess</code> Ͽ ϴ þ
        ּ <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> ǰ  ȿ
        ִ.</p>
    
        <p> ΰ ū  <code>.htaccess</code> 
         ؾ Ѵ.</p>
    
        <p>ù° ̴. <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> <code>.htaccess</code>
         ϵ ϸ, ġ 丮
        <code>.htaccess</code>  ã´. ׷
        <code>.htaccess</code>  ϸ   
        ʴ 쿡  ! , <code>.htaccess</code>
          ûҶ оδ.</p>
    
        <p>Դٰ ؾ ϴ ü þ  ġ
          丮 <code>.htaccess</code>  ã´.
        (<a href="#how"> þ ϳ</a>  .)
        ׷ <code>/www/htdocs/example</code> 丮 ִ
         ûϸ, ġ  ϵ ãƾ Ѵ.</p>
    
        <div class="example"><p><code>
          /.htaccess<br />
          /www/.htaccess<br />
          /www/htdocs/.htaccess<br />
          /www/htdocs/example/.htaccess
        </code></p></div>
    
        <p>׷  丮 ִ    
          Ͻý 4  ؾ Ѵ.
        (<code>/</code> <code>.htaccess</code>  
        츦 Ѵ.   ʴ´.)</p>
    
        <p>ι°  ̴. ڿ   
        ָ     ȭ Ͼ  ִ. ڿ
        ̷    ϶. , ڰ ϴ ͺ
          ָ û ´. ڿ 
          Ȯ ˷. ڿ <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>  Ͽ
        Ȯ ˸   ϸ  ȥ  
        ִ.</p>
    
        <p>þ <code>/www/htdocs/example</code> 丮
        <code>.htaccess</code>  δ Ͱ ּ
        <code>&lt;Directory /www/htdocs/example&gt;</code> Directory
         δ   .</p>
    
        <p><code>/www/htdocs/example</code> ִ
        <code>.htaccess</code> :</p>
    
        <div class="example"><h3><code>/www/htdocs/example</code> ִ
        .htaccess  </h3><p><code>
            AddType text/example .exm
        </code></p></div>
    
        <div class="example"><h3><code>httpd.conf</code> Ͽ ִ </h3><p><code>
          &lt;Directory /www/htdocs/example&gt;<br />
          <span class="indent">
            AddType text/example .exm<br />
          </span>
          &lt;/Directory&gt;
        </code></p></div>
    
        <p>׷  û   ʰ ġ
        Ҷ ѹ  б⶧   Ͽ
        ϸ   .</p>
    
        <p><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> þ
        <code>none</code> ϸ <code>.htaccess</code> 
           .</p>
    
        <div class="example"><p><code>
          AllowOverride None
        </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="how" id="how"> þ ϳ</a></h2>
    
        <p><code>.htaccess</code>  ߰ 丮  丮
         丮 <code>.htaccess</code> Ͽ ִ 
        þ Ѵ. ׷ 丮 <code>.htaccess</code>
         ؾ Ѵ. ߰  þ Ѵ. Ư
        丮 ִ <code>.htaccess</code>  丮
        ִ <code>.htaccess</code>  þ ȿ 
         ְ, 丮 ִ þ  丮 Ȥ
        ּϿ ִ þ ȿ   ִ.</p>
    
        <p>:</p>
    
        <p><code>/www/htdocs/example1</code> 丮  
        <code>.htaccess</code>  ִ.</p>
    
        <div class="example"><p><code>
           Options +ExecCGI
        </code></p></div>
    
        <p>(: <code>.htaccess</code> Ͽ "<code class="directive"><a href="../mod/core.html#options">Options</a></code>" þ Ϸ
        "<code>AllowOverride Options</code>" ʿϴ.)</p>
    
        <p><code>/www/htdocs/example1/example2</code> 丮
          <code>.htaccess</code>  ִ.</p>
    
        <div class="example"><p><code>
           Options Includes
        </code></p></div>
    
        <p> ι° <code>.htaccess</code> 
        <code>Options Includes</code>    ȿ
        ⶧ <code>/www/htdocs/example1/example2</code>
        丮 CGI   ʴ´.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="auth" id="auth"> </a></h2>
    
        <p>  ˱ ٷ ̰ д´ٸ  
        ִ. ȣ  Ϸ <code>.htaccess</code> 
        ʿϴٴ ذ θ ִ. ̴  ƴϴ.
        ּ <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> ǿ  þ
        δ   ϴ ̰,  ּ 
          쿡 <code>.htaccess</code>  ؾ
        Ѵ.  <code>.htaccess</code>  ؾ ϴ
         ƾ ϴ <a href="#when"></a>
        Ͽ.</p>
    
        <p>տ   <code>.htaccess</code> 
        ʿϴٰ Ǹ Ʒ    ̴.</p>
    
        <p><code>.htaccess</code>  .</p>
    
        <div class="example"><p><code>
          AuthType Basic<br />
          AuthName "Password Required"<br />
          AuthUserFile /www/passwords/password.file<br />
          AuthGroupFile /www/passwords/group.file<br />
          Require Group admins
        </code></p></div>
    
        <p> þ ϱؼ
        <code>AllowOverride AuthConfig</code> þ ʿ
        ϶.</p>
    
        <p> Ѻο  ڼ  <a href="auth.html">
        丮</a>  ٶ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ssi" id="ssi">Server Side Includes </a></h2>
    
        <p>Ǵٸ Ϲ <code>.htaccess</code>  뵵
        Ư 丮 Server Side Includes ϰ 
        ̴. ϴ 丮 <code>.htaccess</code> Ͽ
           þ ϸ ȴ.</p>
    
        <div class="example"><p><code>
           Options +Includes<br />
           AddType text/html shtml<br />
           AddHandler server-parsed shtml
        </code></p></div>
    
        <p> þ Ϸ <code>AllowOverride Options</code>
        <code>AllowOverride FileInfo</code>  ʿ ϶.</p>
    
        <p>server-side includes  ڼ  <a href="ssi.html">SSI 丮</a>  ٶ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">CGI </a></h2>
    
        <p> <code>.htaccess</code>  Ͽ Ư
        丮 CGI α׷  ϰ ʹٸ, 
          Ѵ.</p>
    
        <div class="example"><p><code>
           Options +ExecCGI<br />
           AddHandler cgi-script cgi pl
        </code></p></div>
    
        <p>Ȥ  丮 ִ   CGI α׷
        óϰ ʹٸ    ϴ.</p>
    
        <div class="example"><p><code>
           Options +ExecCGI<br />
           SetHandler cgi-script
        </code></p></div>
    
        <p> þ Ϸ <code>AllowOverride Options</code>
        <code>AllowOverride FileInfo</code>  ʿ ϶.</p>
    
        <p>CGI α׷ְ   ڼ  <a href="cgi.html">CGI 丮</a>  ٶ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">ذ</a></h2>
    
        <p><code>.htaccess</code> Ͽ   þ ϴ
          ʴ      ִ.</p>
    
        <p> Ϲ   þ ϰ  <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code>  
        .  Ǵ   <code>AllowOverride None</code>
         ȮѴ. <code>.htaccess</code>  ƹԳ 
           ٽ Ͽ  ˻غ  ִ.
             Ȯ
        <code>AllowOverride None</code>  .</p>
    
        <p>ݴ  Ҷ   ߻ϸ ġ α׸
        . Ƹ <code>.htaccess</code> Ͽ ִ þ
         ʴ´ٰ  ̴. ƴϰ   ִٸ 
        ģ.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/howto/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/htaccess.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/htaccess.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/htaccess.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/htaccess.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../pt-br/howto/htaccess.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/index.html.ja.utf8���������������������������������������������������0000664�0001751�0001751�00000017472�14743132254�021462� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>How-To / チュートリアル - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>How-To / チュートリアル</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="howto" id="howto">How-To / チュートリアル</a></h2>
    
        
    
        <dl>
          <dt>認証と承認</dt>
          <dd>
            <p>認証とは、誰かが自分は誰であるかを名乗っているものを検証する
            処理のことです。承認とは、誰かが望みの場所に辿り着けたり、
            望みの情報を手に入れたりすることを許可する処理のことです。</p>
    
            <p>参照: <a href="auth.html">認証と承認</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>アクセス制御</dt>
          <dd>
            <p>アクセス制御は、さまざまな条件でリソースに対するアクセスを
            許可したり制限したりすることを指します。
            実現方法には様々な異なる手法があります。</p>
    
            <p>参照: <a href="access.html">アクセス制御</a></p>
          </dd>
        </dl>
    
       <dl>
          <dt>CGI による動的コンテンツ</dt>
          <dd>
            <p>CGI (Common Gateway Interface) はウェブサーバが外部のコンテンツ
            生成プログラムとどのように相互動作をするかを定義します。
            その外部プログラムは通常 CGI プログラムや CGI スクリプトと呼ばれます。
            CGI はウェブサイトに動的なコンテンツを追加するための、
            単純な方法です。この文書は Apache ウェブサーバに
            CGI を設定し、CGI プログラムを書き始めるためのイントロダクションです。</p>
    
            <p>参照: <a href="cgi.html">CGI: 動的コンテンツ</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt><code>.htaccess</code> ファイル</dt>
          <dd>
            <p><code>.htaccess</code> ファイルはディレクトリ毎に設定を変更するための
            方法を提供します。設定ディレクティブが書かれたファイルが、あるドキュメント
            ディレクトリに置かれると、ディレクティブはそのディレクトリと
            すべてのサブディレクトリに適用されます。</p>
    
            <p>参照: <a href="htaccess.html"><code>.htaccess</code> ファイル</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>Server Side Includes イントロダクション</dt>
          <dd>
            <p>SSI (Server Side Includes) は HTML ページ中に書かれるディレクティブで、
            ページが送られる時にサーバにより評価されます。これにより、ページ全体を
            CGI プログラムで生成したり、他の動的な技術を使うことなく、既存の HTML
            ページに動的に生成された内容を付加することができます。</p>
    
            <p>参照: <a href="ssi.html">Server Side Includes (SSI)</a></p>
          </dd>
        </dl>
    
        <dl>
          <dt>ユーザ毎のウェブディレクトリ</dt>
          <dd>
            <p>複数ユーザの存在するシステムでは、それぞれのユーザは <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> ディレクティブを使うことによって
            ホームディレクトリ上にウェブサイトを作成することができます。
            URL <code>http://example.com/~username/</code> を訪れた人は
            ユーザ "<code>username</code>" のホームディレクトリの、<code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> ディレクティブで指定された
           サブディレクトリからコンテンツを得ることになります。</p>
    
            <p>参照: <a href="public_html.html">ユーザウェブディレクトリ (<code>public_html</code>)</a></p>
          </dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../zh-cn/howto/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/public_html.html.ja.utf8���������������������������������������������0000664�0001751�0001751�00000036037�14743132254�022653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ユーザ毎のウェブディレクトリ - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">How-To / チュートリアル</a></div><div id="page-content"><div id="preamble"><h1>ユーザ毎のウェブディレクトリ</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <p>複数のユーザのいるシステムでは、<code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> ディレクティブを使って
        各ユーザがホームディレクトリにウェブサイトを構築できるように設定することが
        可能です。URL <code>http://example.com/~username/</code> を訪れた人は
        "<code>username</code>" というユーザの <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> ディレクティブで指定された
        サブディレクトリからコンテンツを得ることになります。</p>
    
        <p>in the default config file, and adapting the <code>httpd-userdir.conf</code>
        file as necessary, or by including the appropriate directives in a
        <code>Directory</code> block within the main config file.</p>
        <p>デフォルトではこれらのディレクトリへのアクセスは<strong>許可されていません</strong>。
        <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> を使って有効にできます。
        有効にするには、デフォルトの設定ファイルで付随する
        <code>httpd-userdir.conf</code> ファイルが必要で、
        その中の次の行のコメントアウトを外して有効にするか、
        </p>
        <div class="example"><p><code>
          #Include conf/extra/httpd-userdir.conf
        </code></p></div>
        <p>あるいは、メインの設定ファイル中の <code>Directory</code> 
        ブロックの中に適切にディレクティブを記述しておきます。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">ユーザ毎のウェブディレクトリ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#userdir">UserDir を使ってファイルのパスを設定する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#redirect">外部 URL にリダイレクトする</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#enable">この機能を使用できるユーザを制限する</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">ユーザ毎の CGI ディレクトリ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">ユーザによる設定変更を許可</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="../urlmapping.html">URL からファイルシステムへのマッピング</a></li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">ユーザ毎のウェブディレクトリ</a></h2>
        
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code></li><li><code class="directive"><a href="../mod/core.html#directorymatch">DirectoryMatch</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="userdir" id="userdir">UserDir を使ってファイルのパスを設定する</a></h2>
        
    
        <p><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> ディレクティブは
        ユーザ毎のコンテンツが読み込まれるディレクトリを指定します。
        このディレクティブはいろいろ違った形式を取ることができます。</p>
    
        <p>スラッシュで始まらないパスが与えられたときは、ユーザのホームディレクトリ
        からの相対パスとみなされます。次の設定があったときに:</p>
    
        <pre class="prettyprint lang-config">UserDir public_html</pre>
    
    
        <p>URL <code>http://example.com/~rbowen/file.html</code> は
        パス <code>/home/rbowen/public_html/file.html</code> へ
        変換されます。</p>
    
        <p>パスがスラッシュで始まるときは、ディレクトリパスはそのパスに
        ユーザ名を加えたものからなります。次の設定のとき:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/html</pre>
    
    
        <p>URL <code>http://example.com/~rbowen/file.html</code> は
        パス <code>/var/html/rbowen/file.html</code> へ変換されます。</p>
    
        <p>アスタリスク (*) を含むパスが指定されたときは、アスタリスクを
        ユーザ名で置換したものが使用されます。このような設定だと:</p>
    
        <pre class="prettyprint lang-config">UserDir /var/www/*/docs</pre>
    
    
        <p>URL <code>http://example.com/~rbowen/file.html</code> は
        パス <code>/var/www/rbowen/docs/file.html</code> へ変換されます。</p>
    
        <p>ディレクトリやディレクトリパスを複数設定することもできます。</p>
    
        <pre class="prettyprint lang-config">UserDir public_html /var/html</pre>
    
    
    
        <p><code>http://example.com/~rbowen/file.html</code> という
        URL に対しては <code>~rbowen</code> を探します。見つからなければ、
        <code>/var/html</code> の下にある <code>rbowen</code> を探します。
        もし見つかれば上記の URL は <code>/var/html/rbowen/file.html</code>
        というファイルパスに変換されます。</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">外部 URL にリダイレクトする</a></h2>
        
        <p><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
        ディレクティブを使って外部 URL にリダイレクトすることもできます。</p>
    
        <pre class="prettyprint lang-config">UserDir http://example.org/users/*/</pre>
    
    
        
        <p>上記例では <code>http://example.com/~bob/abc.html</code>
        へのリクエストは <code>http://example.org/users/bob/abc.html</code>
        にリダイレクトされます。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">この機能を使用できるユーザを制限する</a></h2>
        
    
        <p>UserDir のドキュメントに示されている構文を使うことで、
        どのユーザがこの機能を使うことができるかを制限することができます:</p>
    
        <div class="example"><p><code>
          UserDir enabled<br />
          UserDir disabled root jro fish
        </code></p></div>
    
        <p>上の設定は <code>dissabled</code> 文のユーザ以外のすべてのユーザに
        対して UserDir の機能を有効にします。同様にして、以下のように
        数名のユーザ以外に対してこの機能を無効にすることもできます:</p>
    
        <pre class="prettyprint lang-config">      UserDir disabled<br />
          UserDir enabled rbowen krietz</pre>
    
    
        <p>他の例は <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
        の説明を参照してください。</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">ユーザ毎の CGI ディレクトリ</a></h2>
      
    
       <p>それぞれのユーザに専用の cgi-bin ディレクトリを与えるために、
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
        を使ってユーザのホームディレクトリの指定された領域に対して CGI を有効に
        することができます。</p>
    
        <pre class="prettyprint lang-config">&lt;Directory /home/*/public_html/cgi-bin/&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
    
        <p>そして、<code>UserDir</code> が
        <code>public_html</code> に設定されていると仮定すると、
        そのディレクトリの CGI プログラム <code>example.cgi</code>
        は以下の様に呼び出されることができます:</p>
    
        <div class="example"><p><code>
        http://example.com/~rbowen/cgi-bin/example.cgi
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">ユーザによる設定変更を許可</a></h2>
        
    
        <p>ユーザに彼らのウェブ空間でのサーバの設定の変更を許可する場合、
        ユーザは <code>.htaccess</code> ファイルを使って設定を変更する必要があります。
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> の値を
        ユーザが変更することを許可したいディレクティブに対して十分なものに
        設定していることを確認してください。この機能がどのようにして動作しているか
        の詳細は <a href="htaccess.html">.htaccess チュートリアル</a> を読んで
        ください。</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/public_html.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/ssi.html.ja.utf8�����������������������������������������������������0000664�0001751�0001751�00000075130�14743132254�021144� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache チュートリアル: Server Side Includes 入門 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="../">バージョン 2.4</a> &gt; <a href="./">How-To / チュートリアル</a></div><div id="page-content"><div id="preamble"><h1>Apache チュートリアル: Server Side Includes 入門</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <p>サーバサイドインクルードによって、既存の HTML
    ドキュメントに動的なコンテンツを追加することができます。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">はじめに</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">SSI とは ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">SSI を許可するためのサーバの設定</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic">基本的な SSI ディレクティブ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#additionalexamples">追加の例</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">他に何が設定できるのか ?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exec">コマンドの実行</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#advanced">高度な SSI テクニック</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#conclusion">終わりに</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">はじめに</a></h2>
     <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code></li><li><code class="directive"><a href="../mod/core.html#setoutputfilter">SetOutputFilter</a></code></li><li><code class="directive"><a href="../mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li></ul></td></tr></table>
    
        <p>この記事は、通常は単に SSI と呼ばれる Server Side Includes
        を扱います。この記事においては、サーバでの SSI を許可するための設定と、
        現在の HTML ページに動的なコンテンツを加えるためのいくつかの基本的な
        SSI 技術を紹介します。</p>
    
        <p>記事の後半では、SSI ディレクティブで SSI
        と共に実行することができる条件文のような
        幾分高度な事柄について述べています。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">SSI とは ?</a></h2>
    
        <p>SSI (Server Side Includes) は、HTML
        ページ中に配置されるディレクティブであり、
        サーバでページを提供する時に評価されます。SSI は、CGI
        プログラムやその他の動的な技術で全てのページを提供せずに、
        動的に生成されたコンテンツを現在の HTML ページに加えます。</p>
    
        <p>どういう場合に SSI を使い、どういう場合にプログラムで
        ページを完全に生成するかは、ページのうちどの程度が静的であり、
        ページが提供されるたびに再計算する必要がどの程度あるかで通常は決定します。
        SSI は現在時刻のような小さい情報を加えるにはうってつけの方法です。
        しかし、そのページのほとんどの部分が提供時に生成される場合は、
        他の方法を探す必要があります。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">SSI を許可するためのサーバの設定</a></h2>
    
    
        <p>サーバで SSI を許可するには、<code>httpd.conf</code>
        ファイルまたは <code>.htaccess</code>
        ファイルに次のディレクティブを指定する必要があります:</p>
    <div class="example"><p><code>
            Options +Includes
    </code></p></div>
    
        <p>この指定は、ファイルを SSI
        ディレクティブで解析させることを許可するということを Apache
        に伝えます。ほとんどの設定ではお互いを上書きできる、複数の
        <code class="directive"><a href="../mod/core.html#options">Options</a></code> があることに
        注意してください。おそらく、設定が最後に評価されることを
        保証されるために、SSI を使用したいディレクトリに <code>Options</code>
        ディレクティブを適用する必要があるでしょう。</p>
    
        <p>全てのファイルが SSI
        ディレクティブで解析されるというわけではありません。
        どのファイルが解析されるかを Apache に伝える必要があります。
        これを行なうには二つ方法があります。
        次のディレクティブを使うことで、例えば <code>.shtml</code>
        のような特別なファイル拡張子を持つファイルを解析するよう
        Apache に伝えることができます:</p>
    <div class="example"><p><code>
            AddType text/html .shtml<br />
            AddOutputFilter INCLUDES .shtml
    </code></p></div>
    
        <p>この方法の欠点は、もし現在のページに SSI ディレクティブを加えたい場合、
        それらのディレクティブが実行されるように 
        <code>.shtml</code> 拡張子にするため、そのページの名前と、
        そのページへの全てのリンクを変更しなければならないことです。</p>
    
        <p>もう一つの方法は、<code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>
        ディレクティブを使用することです:</p>
    <div class="example"><p><code>
            XBitHack on
    </code></p></div>
    
        <p><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code> 
        は、ファイルの実行ビットが立っている場合、
        SSI ディレクティブにより解析することを Apache に伝えます。
        従って、SSI ディレクティブを現在のページに加えるためには、
        ファイル名を変更しなくてもよく、単に <code>chmod</code>
        を使用してファイルを実行可能にするだけで済みます。</p>
    <div class="example"><p><code>
            chmod +x pagename.html
    </code></p></div>
    
        <p>行なうべきではないことに関する短いコメント。時々誰かが、全ての
        <code>.html</code> ファイルを SSI で解析するよう Apache に伝えれば、
        わざわざ <code>.shtml</code> というファイル名にする必要がないといって
        薦めるのを見ることでしょう。こういう人たちは、おそらく
        <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>
        について聞いたことがないのでしょう。
        この方法について注意することは、たとえ SSI
        ディレクティブを全く含まない場合でも、Apache がクライアントに
        送る全てのファイルを最後まで読み込ませることになります。
        この方法はかなり処理を遅くするものであり、良くないアイデアです。</p>
    
        <p>もちろん、Windows ではそのような実行ビットをセット
        するようなものはありませんのでオプションが少し制限されています。</p>
    
        <p>デフォルトの設定では、Apache は SSI ページについて最終変更時刻や
        コンテンツの長さを HTTP ヘッダに送りません。
        動的なコンテンツであるため、それらの値を計算するのが難しいからです。
        このためドキュメントがキャッシュされなくなり、
        結果としてクライアントの性能が遅くなったように感じさせることになります。
        これを解決する方法が二つあります:</p>
    
        <ol>
          <li><code>XBitHack Full</code> 設定を使用する。
          この設定により、もともと要求されたファイルの時刻を参照し、
          読み込まれるファイルの変更時刻を無視して最終変更時刻を決定するよう
          Apache に伝えます。</li>
    
          <li><a href="../mod/mod_expires.html">mod_expires</a>
          で提供されているディレクティブを使用して、
          ファイルが無効になる時刻を明示します。これにより、
          ブラウザとプロキシにキャッシュが有効であることを通知します。</li>
        </ol>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic" id="basic">基本的な SSI ディレクティブ</a></h2>
    
        <p>SSI ディレクティブは以下の文法で記述します:</p>
    <div class="example"><p><code>
            &lt;!--#element attribute=value attribute=value ... --&gt;
    </code></p></div>
    
        <p>HTML のコメントのような書式をしているので、もし SSI
        を正しく動作可能にしなければ、ブラウザはそれを無視するでしょう。
        しかし、HTML ソース中では見えます。もし SSI を正しく設定したなら、
        ディレクティブはその結果と置き換えられます。</p>
    
        <p>element はたくさんあるものから一つ指定することができます。
        指定できるものの大多数については、次回もう少し詳しく説明します。
        ここでは、SSI で行なうことができる例をいくつか示します。</p>
    
    <h3><a name="todaysdate" id="todaysdate">今日の日付</a></h3>
    
    <div class="example"><p><code>
            &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
        <p><code>echo</code> 要素は単に変数の値を出力します。
        CGI プログラムに利用可能な環境変数の全ての
        セットを含む多くの標準変数があります。また、<code>set</code>
        要素を用いることで、独自の変数を定義することができます。
        </p>
    
        <p>出力される日付の書式が好きではない場合、その書式を修正するために、
        <code>config</code> 要素に <code>timefmt</code>
        属性を使用することができます。</p>
    
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            Today is &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
    
    <h3><a name="lastmodified" id="lastmodified">ファイルの変更日</a></h3>
    
    <div class="example"><p><code>
            This document last modified &lt;!--#flastmod file="index.html" --&gt;
    </code></p></div>
    
        <p>この要素も <code>timefmt</code>
        フォーマットの設定に従います。</p>
    
    
    <h3><a name="cgi" id="cgi">CGI プログラムの結果を取り込む</a></h3>
    
        <p>これは、全ての人のお気に入りである ``ヒットカウンタ'' のような
        CGI プログラムの結果を出力する SSI
        のより一般的な使用のうちの一つです。</p>
    
    <div class="example"><p><code>
            &lt;!--#include virtual="/cgi-bin/counter.pl" --&gt;
    </code></p></div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="additionalexamples" id="additionalexamples">追加の例</a></h2>
    
    
        <p>以下は、SSI を使用して HTML
        ドキュメントにおいてできることのいくつかの特別な例です。</p>
    
    <h3><a name="docmodified" id="docmodified">いつこのドキュメントは修正されたのか
    ?</a></h3>
    
        <p>先に、ドキュメントが最後に変更されたのはいつかを
        ユーザに通知するために SSI を使用することができることを述べました。
        しかしながら、実際の方法は、いくぶん問題のままにしておきました。
        HTML ドキュメントに配置された次のコードは、ページにそのような
        タイムスタンプを入れるでしょう。もちろん、上述のように、
        SSI を正しく動作可能にしておく必要があります。</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            This file last modified &lt;!--#flastmod file="ssi.shtml" --&gt;
    </code></p></div>
    
        <p>もちろん、<code>ssi.shtml</code>
        の部分を実際の当該ファイル名と置き換える必要があります。
        もし、あらゆるファイルに張ることができる一般的なコードを探しているなら、
        これは不便であるかもしれません。おそらくその場合は、
        そうする代わりに変数 <code>LAST_MODIFIED</code>
        を使用したいと考えるでしょう:</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%D" --&gt;<br />
            This file last modified &lt;!--#echo var="LAST_MODIFIED" --&gt;
    </code></p></div>
    
        <p><code>timefmt</code>
        書式についてのより詳細については、お好みの検索サイトに行き、
        <code>strftime</code> で検索してみてください。文法は同じです。</p>
    
    
    <h3><a name="standard-footer" id="standard-footer">標準のフッタを挿入する</a></h3>
    
    
        <p>もし数ページを超えるページを持つサイトを管理しているならば、
        全ページに対して変項を行なうことが本当に苦痛となり得ることが
        分かるでしょう。全てのページに渡ってある種の標準的な外観を
        維持しようとしているならば特にそうでしょう。</p>
    
        <p>ヘッダやフッタ用の挿入用ファイルを使用することで、
        このような更新にかかる負担を減らすことができます。
        一つのフッタファイルを作成し、それを <code>include</code>
        SSI コマンドで各ページに入れるだけで済みます。<code>include</code>
        要素は、<code>file</code> 属性または <code>virtual</code>
        属性のいずれかを使用してどのファイルを挿入するかを決めることができます。
        <code>file</code> 属性は、<em>カレントディレクトリからの相対パスで示された
        </em>ファイルパスです。
        それは / で始まる絶対ファイルパスにはできず、また、そのパスの一部に ../
        を含むことができないことを意味します。<code>virtual</code>
        属性は、おそらくより便利だと思いますが、提供するドキュメントからの相対
        URL で指定すべきです。それは / で始めることができますが、
        提供するファイルと同じサーバ上に存在しなくてはなりません。</p>
    <div class="example"><p><code>
            &lt;!--#include virtual="/footer.html" --&gt;
    </code></p></div>
    
        <p>私は最後の二つを組み合わせて、<code>LAST_MODIFIED</code>
        ディレクティブをフッタファイルの中に置くことがよくあります。
        SSI ディレクティブは、挿入用のファイルに含ませたり、
        挿入ファイルのネストをしたりすることができます。すなわち、
        挿入用のファイルは他のファイルを再帰的に挿入することができます。</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">他に何が設定できるのか ?</a></h2>
    
    
        <p>時刻書式を <code>config</code> で設定できることに加えて、
        更に二つ <code>config</code> で設定することができます。</p>
    
        <p>通常、SSI ディレクティブで何かがうまくいかないときは、
        次のメッセージが出力されます。</p>
    <div class="example"><p><code>
            [an error occurred while processing this directive]
    </code></p></div>
    
        <p>このメッセージを他のものにしたい場合、<code>config</code>
        要素の <code>errmsg</code> 属性で変更することができます:</p>
    <div class="example"><p><code>
            &lt;!--#config errmsg="[It appears that you don't know how to use SSI]" --&gt;
    </code></p></div>
    
        <p>おそらく、エンドユーザはこのメッセージを決して見ることはありません。
        なぜなら、そのサイトが生きた状態になる前に SSI ディレクティブに関する
        全ての問題を解決しているはずだからです。(そうですよね?)</p>
    
        <p>そして、<code>config</code> において <code>sizefmt</code>
        属性を使用することで、
        返されるファイルサイズの書式を設定することができます。
        バイト数には <code>bytes</code> を、適当に Kb や Mb
        に短縮させるには <code>abbrev</code> を指定することができます。</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exec" id="exec">コマンドの実行</a></h2>
        
    
        <p>今後数ヶ月のうちに、小さな CGI プログラムと SSI
        を使用する記事を出したいと考えています。ここではそれとは別に、
        <code>exec</code> 要素によって行なうことができることを示します。
        SSI にシェル (正確には <code>/bin/sh</code>。Win32 ならば DOS シェル)
        を使用してコマンドを実行させることができます。
        下記の例では、ディレクトリリスト出力を行ないます。</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="ls" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>Windows 上では、</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="dir" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>Windows 上では、このディレクティブによっていくつかの奇妙な
        書式に気づくでしょう。なぜなら <code>dir</code> の出力が文字列
        ``&lt;<code>dir</code>&gt;'' を含み、ブラウザを混乱させるからです。</p>
    
        <p>この機能は非常に危険であり、どんなコードでも <code>exec</code>
        タグに埋め込まれてしまえば実行することに注意してください。例えば 
        `` ゲストブック '' のように、もし、
        ユーザがページの内容を編集できる状況にあるならば、
        この機能を確実に抑制してください。<code>Options</code>
        ディレクティブの <code>IncludesNOEXEC</code> 引数を指定することで、
        SSI は許可するけれど <code>exec</code>
        機能は許可しないようにすることができます。</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advanced" id="advanced">高度な SSI テクニック</a></h2>
    
    
        <p>コンテンツを出力することに加え、Apache SSI は変数を設定し、
        そして比較と条件分岐にその変数を使用できる機能を提供しています。
        </p>
    
    <h3><a name="caveat" id="caveat">警告</a></h3>
    
        <p>この記事で述べた大部分の機能は、Apache 1.2
        以降を使用している場合のみ利用可能です。もちろん、もし Apache 1.2
        以降を使用してない場合、直ちにアップグレードする必要があります。
        さぁ、今それを行ないなさい。それまで待っています。</p>
    
    
    <h3><a name="variables" id="variables">変数を設定する</a></h3>
    
        <p><code>set</code> ディレクティブを使用して、
        後で使用するために変数を設定することができます。
        これは後の説明で必要になるので、ここでそれについて述べています。
        文法は以下のとおりです:</p>
    <div class="example"><p><code>
            &lt;!--#set var="name" value="Rich" --&gt;
    </code></p></div>
    
        <p>このように単純に文字どおりに設定することに加え、
        <a href="../env.html">環境変数</a>や上記の変数
        (例えば <code>LAST_MODIFIED</code> のような)
        を含む他のあらゆる変数を値を設定するのに使用することができます。
        変数名の前にドル記号 ($) を使用することで、
        それがリテラル文字列ではなくて変数であることを示します。</p>
    <div class="example"><p><code>
            &lt;!--#set var="modified" value="$LAST_MODIFIED" --&gt;
    </code></p></div>
    
        <p>ドル記号 ($) を文字として変数の値に入れるには、
        バックスラッシュによってドル記号をエスケープする必要があります。</p>
    <div class="example"><p><code>
            &lt;!--#set var="cost" value="\$100" --&gt;
    </code></p></div>
    
        <p>最後になりますが、長い文字列の中に変数を置きたい場合で、
        変数名が他の文字とぶつかる可能性があり、
        それらの文字について混乱してしまう場合、この混乱を取り除くため、
        変数名を中括弧で囲むことができます
        (これについての良い例を示すのは難しいのですが、
        おそらく分かっていただけるでしょう)。
        </p>
    <div class="example"><p><code>
            &lt;!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --&gt;
    </code></p></div>
    
    
    <h3><a name="conditional" id="conditional">条件式</a></h3>
    
    
        <p>さて、変数を持っていて、
        それらの値を設定して比較することができるのですから、
        条件を表すためにそれらを使用することができます。これにより
        SSI はある種の小さなプログラミング言語になっています。
        <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> は条件を表現するために <code>if</code>,
        <code>elif</code>, <code>else</code>, <code>endif</code>
        構造を提供しています。これによって、
        一つの実際のページから複数の論理ページを効果的に生成することができます。</p>
    
        <p>条件構造は以下のとおりです:</p>
    <div class="example"><p><code>
        &lt;!--#if expr="test_condition" --&gt;<br />
        &lt;!--#elif expr="test_condition" --&gt;<br />
        &lt;!--#else --&gt;<br />
        &lt;!--#endif --&gt;
    </code></p></div>
    
        <p><em>test_condition</em>
        はあらゆる種類の論理的比較をすることができます。
        値を比較したり、その値が ``真'' かどうかを評価します
        (空でないなら与えられた文字列は真です)。
        利用可能な比較演算子の全てのリストについては、
        <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> ドキュメンテーションを参照してください。
        ここでは、この構造をどう使用するかの例をいくつか示します。</p>
    
        <p>設定ファイルで次の行を記述します:</p>
    <div class="example"><p><code>
            BrowserMatchNoCase macintosh Mac<br />
            BrowserMatchNoCase MSIE InternetExplorer
    </code></p></div>
    
        <p>これはクライアントが Macintosh
        上でインターネットエクスプローラが動いている場合、環境変数
        ``Mac'' と ``InternetExplorer'' を真と設定します。</p>
    
        <p>次に、SSI が可能になったドキュメントで以下を行ないます:
        </p>
    <div class="example"><p><code>
            &lt;!--#if expr="${Mac} &amp;&amp; ${InternetExplorer}" --&gt;<br />
            Apologetic text goes here<br />
            &lt;!--#else --&gt;<br />
            Cool JavaScript code goes here<br />
            &lt;!--#endif --&gt;
    </code></p></div>
    
        <p>Mac 上の IE に対して何か思うところがあるわけでありません。
        他では実行できているいくつかの JavaScript を Mac 上の IE
        で実行させるのに、先週数時間苦労したというだけのことです。
        上の例はその暫定的な対処方法です。</p>
    
        <p>他のどんな変数 (あなたが定義するもの、
        または普通の環境変数のいずれか) も、条件文に使用することができます。
        Apache は <code>SetEnvIf</code> ディレクティブや他の関連
        ディレクティブを使用して環境変数を設定することができます。
        この機能により、CGI
        に頼ることなくかなり複雑な動的なことをさせることができます。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="conclusion" id="conclusion">終わりに</a></h2>
    
        <p>SSI は確かに CGI
        や動的なウェブページを生成する他の技術に代わるものではありません。
        しかし、たくさんの余分な作業をせずに、
        少量の動的なコンテンツを加えるにはすぐれた方法です。</p>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="../en/howto/ssi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/ssi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="../mod/">モジュール</a> | <a href="../mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">用語</a> | <a href="../sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/cgi.html.fr.utf8�����������������������������������������������������0000664�0001751�0001751�00000104340�14740503670�021122� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Tutoriel Apache : Contenu dynamique basé sur CGI - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Recettes et tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Tutoriel Apache : Contenu dynamique basé sur CGI</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#intro">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">Configurer Apache pour autoriser CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#writing">Ecrire un programme CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#troubleshoot">Mais ça ne marche toujours pas !</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#behindscenes">Que se passe-t-il en coulisse</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#libraries">Bibliothèques et modules CGI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinfo">Pour plus d'informations</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">Introduction</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_cgid.html">mod_cgid</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li></ul></td></tr></table>
    
        <p>CGI (Common Gateway Interface) définit une méthode d'interaction
        entre un serveur web et des programmes générateurs de contenu
        externes, plus souvent appelés programmes CGI ou scripts CGI.
        Il s'agit d'une méthode simple pour ajouter du contenu dynamique à votre site
        web en utilisant votre langage de programmation préféré.
        Ce document est une introduction à la configuration de CGI sur votre
        serveur web Apache, et une initiation à l'écriture de programmes
        CGI.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">Configurer Apache pour autoriser CGI</a></h2>
        
    
        <p>Apache doit être configuré pour permettre l'exécution des
        programmes CGI, pour que vos programmes CGI puissent fonctionner
        correctement. Il existe plusieurs méthodes pour y parvenir.</p>
    
        <div class="warning">Note: si Apache a été compilé avec le support
        des modules partagés (DSO), vous devez vous assurer que le module CGI est
        chargé ; vous devez pour cela vérifier que la directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> correspondante n'a pas été
        commentée dans votre <code>httpd.conf</code>. Une directive correcte
        doit ressembler à ceci :
    
        <pre class="prettyprint lang-config">LoadModule cgid_module modules/mod_cgid.so</pre>
    
    
    
         Sous Windows, ou si l'on utilise un module MPM non-threadé comme prefork,
         une directive correctement configurée sera du style :
    
        <pre class="prettyprint lang-config">LoadModule cgi_module modules/mod_cgi.so</pre>
    </div>
    
    
        <h3><a name="scriptalias" id="scriptalias">ScriptAlias</a></h3>
          
    
          <p>La directive <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> indique à Apache qu'un
          répertoire particulier est dédié aux programmes CGI. Apache
          considérera que tout fichier situé dans ce répertoire est un
          programme CGI, et tentera de l'exécuter lorsque cette ressource
          fera l'objet d'une requête client.</p>
    
          <p>La directive <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> se présente comme suit
          :</p>
    
          <pre class="prettyprint lang-config">ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"</pre>
    
    
          <p>Cet exemple est tiré de votre fichier de configuration
          <code>httpd.conf</code> par défaut, si vous avez installé Apache
          dans son répertoire par défaut. La directive <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code> est similaire à la
          directive <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>, qui
          définit à quel répertoire particulier doit correspondre un préfixe
          d'URL. <code class="directive">Alias</code> et
          <code class="directive">ScriptAlias</code> sont généralement utilisés pour
          accéder à des répertoires situés en dehors du répertoire défini
          par la directive <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>. La différence entre
          <code class="directive">Alias</code> et <code class="directive">ScriptAlias</code>
          réside dans le fait que <code class="directive">ScriptAlias</code> indique
          en plus que tout ce qui se trouve sous le préfixe d'URL doit être
          considéré comme un programme CGI. Ainsi, l'exemple ci-dessus
          indique à Apache que toute requête pour une ressource commençant
          par <code>/cgi-bin/</code> doit être servie depuis le répertoire
          <code>/usr/local/apache2/cgi-bin/</code>, et doit être traitée en
          tant que programme CGI.</p>
    
          <p>Par exemple, si une requête pour l'URL
          <code>http://www.example.com/cgi-bin/test.pl</code> est
          effectuée, Apache tentera d'exécuter le fichier
          <code>/usr/local/apache2/cgi-bin/test.pl</code> et en renverra la
          sortie. Bien entendu, le fichier doit exister, être exécutable, et
          retourner sa sortie d'une manière particulière, sinon Apache
          renverra un message d'erreur.</p>
        
    
        <h3><a name="nonscriptalias" id="nonscriptalias">CGI en dehors des répertoires ScripAlias</a></h3>
          
    
          <p>Pour des raisons de sécurité, la localisation des programmes
          CGI est souvent restreinte aux
          répertoires définis par <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>. De cette manière, les administrateurs
          peuvent contrôler précisément qui est autorisé à utiliser les
          programmes CGI. Cependant, si les précautions adéquates quant à
          la sécurité sont prises, il n'y a aucune raison pour que les
          programmes CGI ne puissent pas être exécutés depuis d'autres
          répertoires. Par exemple, vous pouvez autoriser les utilisateurs à
          enregistrer des contenus web dans leurs répertoires home à l'aide
          de la directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>. S'ils veulent mettre en
          oeuvre leurs propres programmes CGI, mais n'ont pas l'autorisation
          d'accès au répertoire <code>cgi-bin</code> principal, ils devront
          être en mesure d'exécuter ces programmes depuis un autre
          répertoire.</p>
    
          <p>L'autorisation d'exécution des programmes CGI dans un
          répertoire arbitraire se fait en deux étapes. En premier lieu, le
          gestionnaire <code>cgi-script</code> doit être activé à l'aide
          d'une directive <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> ou <code class="directive"><a href="../mod/core.html#sethandler">SetHandler</a></code>. En second lieu,
          <code>ExecCGI</code> doit être spécifié dans la directive <code class="directive"><a href="../mod/core.html#options">Options</a></code>.</p>
        
    
        <h3><a name="options" id="options">Utilisation d'options explicites pour permettre l'exécution
          des programmes CGI</a></h3>
          
    
          <p>Vous pouvez utiliser de manière explicite la directive
          <code class="directive"><a href="../mod/core.html#options">Options</a></code> dans le fichier de
          configuration de votre serveur principal, pour indiquer que
          l'exécution des programmes CGI est permise depuis un répertoire
          particulier :</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/usr/local/apache2/htdocs/somedir"&gt;
        Options +ExecCGI
    &lt;/Directory&gt;</pre>
    
    
          <p>La directive ci-dessus indique à Apache qu'il doit permettre
          l'exécution des fichiers CGI. Vous devez aussi indiquer au serveur
          quels fichiers sont des fichiers CGI. La directive <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> suivante indique au
          serveur qu'il doit traiter tous les fichiers possédant une
          extension <code>cgi</code> ou <code>pl</code> en tant que
          programmes CGI :</p>
    
          <pre class="prettyprint lang-config">AddHandler cgi-script .cgi .pl</pre>
    
        
    
        <h3><a name="htaccess" id="htaccess">Fichiers .htaccess</a></h3>
          
    
          <p>Le <a href="htaccess.html"><code>tutoriel
          .htaccess</code></a> montre comment activer les programmes
          CGI si vous n'avez pas accès au
          fichier <code>httpd.conf</code>.</p>
        
    
        <h3><a name="userdir" id="userdir">Répertoires utilisateurs</a></h3>
          
    
          <p>Pour permettre l'exécution en tant que programme CGI de tout
          fichier possédant l'extension <code>.cgi</code> et situé dans un
          répertoire utilisateur, vous pouvez utiliser la configuration
          suivante :</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html"&gt;
        Options +ExecCGI
        AddHandler cgi-script .cgi
    &lt;/Directory&gt;</pre>
    
    
          <p>Pour indiquer un sous-répertoire <code>cgi-bin</code> d'un
          répertoire utilisateur où tout fichier sera traité en tant que
          programme CGI, vous pouvez utiliser ceci :</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html/cgi-bin"&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="writing" id="writing">Ecrire un programme CGI</a></h2>
        
    
        <p>Il y a deux différences principales entre la programmation
        "standard" et la programmation CGI.</p>
    
        <p>En premier lieu, toute sortie de votre programme CGI doit être
        précédée d'un en-tête <a class="glossarylink" href="../glossary.html#mime-type" title="voir glossaire">MIME-type</a>. Il s'agit d'un
        en-tête HTTP qui indique au client quel type de contenu il reçoit.
        La plupart du temps, il se présente comme suit :</p>
    
        <div class="example"><p><code>
          Content-type: text/html
        </code></p></div>
    
        <p>En second lieu, votre sortie doit être en HTML, ou tout autre
        format qu'un navigateur est en mesure d'afficher. La plupart du
        temps, il s'agira de HTML, mais occasionnellement, vous pouvez être
        amené à écrire un programme CGI qui renvoie une image gif, ou un
        autre type de contenu non-HTML.</p>
    
        <p>A part ces deux différences, un programme CGI ressemblera à tout
        autre programme que vous pourriez être amené à écrire.</p>
    
        <h3><a name="firstcgi" id="firstcgi">Votre premier programme CGI</a></h3>
          
    
          <p>L'exemple suivant est un exemple de programme CGI qui permet
          d'afficher une ligne de caractères dans votre navigateur. Ecrivez
          ce qui suit, enregistrez le dans un fichier nommé
          <code>premier.pl</code>, et placez le dans votre répertoire
          <code>cgi-bin</code>.</p>
    
          <pre class="prettyprint lang-perl">#!/usr/bin/perl
    print "Content-type: text/html\n\n";
    print "Hello, World.";</pre>
    
    
          <p>Même si Perl ne vous est pas familier, vous devriez être
          capable de comprendre le fonctionnement de ce programme. La
          première ligne indique à Apache (ou à toute interface à partir de
          laquelle le programme s'exécute) que ce programme peut être
          exécuté en fournissant son fichier à l'interpréteur
          <code>/usr/bin/perl</code>. La seconde ligne affiche la
          déclaration du type de contenu considéré, suivie de deux paires
          "Retour chariot - Nouvelle ligne". Ceci a pour effet d'insérer une
          ligne vide après l'en-tête pour marquer la fin des en-têtes HTTP,
          et le début du corps du document. La troisième ligne affiche la
          chaîne de caractères "Bonjour tout le monde . . .". Et c'est tout
          ce dont vous avez besoin.</p>
    
          <p>Si vous ouvrez votre navigateur favori et lui indiquez
          l'adresse</p>
    
          <div class="example"><p><code>
            http://www.example.com/cgi-bin/premier.pl
          </code></p></div>
    
          <p>ou toute autre URL correspondant à votre programme CGI, Vous
          verrez la ligne <code>Bonjour tout le monde . . .</code>
          s'afficher dans la fenêtre de votre navigateur. Ce n'est pas
          extraordinaire, mais si vous y êtes parvenu, vous avez de bonnes
          chances d'y parvenir pour tout autre programme plus
          sophistiqué.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="troubleshoot" id="troubleshoot">Mais ça ne marche toujours pas !</a></h2>
        
    
        <p>Vous devriez voir au moins une des quatre sorties suivantes dans
        votre navigateur lorsque vous essayez d'accéder à votre programme
        CGI depuis le web :</p>
    
        <dl>
          <dt>Le flux de sortie de votre programme CGI</dt>
          <dd>Impeccable ! Cela signifie que tout fonctionne correctement.
          Si la sortie est correcte mais n'est pas traitée correctement par
          le navigateur, assurez-vous d'avoir défini
          <code>Content-Type</code> de manière appropriée dans votre
          programme CGI.</dd>
    
          <dt>Le code source de votre programme CGI ou un message "POST
          Method Not Allowed"</dt>
          <dd>Cela signifie que vous n'avez pas configuré Apache de manière
          à ce qu'il puisse traiter votre programme CGI. Relisez la section
          sur la <a href="#configuring">configuration d'Apache</a>, et
          essayez de trouver votre erreur.</dd>
    
          <dt>Un message commençant par "Forbidden"</dt>
          <dd>Ce type de message est révélateur d'un problème de
          droits. Consultez le <a href="#errorlogs">journal des erreurs
          d'Apache</a> et la section ci-dessous sur les <a href="#permissions">droits des fichiers</a>.</dd>
    
          <dt>Un message contenant "Internal Server Error"</dt>
          <dd>Si vous consultez le <a href="#errorlogs">journal des erreurs
          d'Apache</a>, vous y trouverez probablement des messages du type
          "Premature end of script headers" (Fin prématurée des en-têtes de
          script), éventuellement accompagnés d'un message d'erreur généré
          par votre programme CGI. Dans ce cas, il va vous falloir lire
          chacune des sections ci-dessous pour déterminer ce qui empêche
          votre programme CGI de générer les en-têtes appropriés.</dd>
        </dl>
    
        <h3><a name="permissions" id="permissions">Droits des fichiers</a></h3>
          
    
          <p>Souvenez-vous que le serveur ne s'exécute pas sous votre nom.
          En d'autres termes, lorsque le serveur a démarré, il s'exécute
          avec les droits d'un utilisateur non privilégié - en général
          <code>nobody</code>, ou <code>www</code> - et en conséquence, il
          aura besoin de droits supplémentaires pour pouvoir exécuter des
          fichiers dont vous êtes le propriétaire. En général, pour qu'un
          fichier ait des droits suffisants pour être exécutable par
          <code>nobody</code>, il suffit de lui attribuer des droits
          d'exécution pour tout le monde :</p>
    
          <div class="example"><p><code>
            chmod a+x premier.pl
          </code></p></div>
    
          <p>En outre, si votre programme doit pouvoir accéder en lecture
          et/ou écriture à d'autres fichiers, ces derniers devront avoir les
          droits appropriés.</p>
    
        
    
        <h3><a name="pathinformation" id="pathinformation">Chemin des exécutables (PATH) et variables
          d'environnement</a></h3>
          
    
          <p>Lorsque vous lancez un programme depuis la ligne de commande,
          certaines informations sont passées au shell sans que vous vous en
          doutiez. Par exemple, la variable <code>PATH</code> indique au
          shell où il doit rechercher les exécutables auxquels vous faites
          référence.</p>
    
          <p>Lorsqu'un programme s'exécute depuis le serveur web en tant que
          programme CGI, sa variable <code>PATH</code> n'aura peut-être pas
          la même valeur. Tout programme que vous invoquez dans votre
          programme CGI ( comme par exemple <code>sendmail</code>) devra
          être spécifié par son chemin complet, de façon à ce que le shell
          puisse le trouver lorsqu'il tentera d'exécuter votre programme
          CGI.</p>
    
          <p>Un exemple typique de spécification de programme est le chemin
          vers l'interpréteur de script (souvent <code>perl</code>) que l'on
          trouve à la première ligne de votre programme CGI et qui va
          ressembler à ceci :</p>
    
          <pre class="prettyprint lang-perl">#!/usr/bin/perl</pre>
    
    
          <p>Assurez-vous qu'il s'agit bien du chemin correct vers
          l'interpréteur.</p>
    
          <div class="warning">
          Lors de l'édition de scripts CGI sous Windows, il se peut que des
          caractères de fin de ligne soient ajoutés au chemin de
          l'interpréteur. Assurez-vous donc que les fichiers sont bien
          transmis au serveur en mode ASCII. Dans le cas contraire, l'OS
          pourra envoyer des avertissements "Command not found" à cause des
          caractères de fin de ligne non reconnus car considérés comme
          faisant partie du nom de fichier de l'interpréteur.
          </div>
    
          
    
        <h3><a name="missingenv" id="missingenv">Variables d'environnement manquantes</a></h3>
          
    
          <p>Si votre programme CGI dépend de <a href="#env">variables
          d'environnement</a> non standards, vous devrez vous assurez que
          ces variables lui sont bien transmises par Apache.</p>
    
          <p>Lorsque des en-têtes HTTP ne sont pas transmis à
          l'environnement, assurez-vous qu'ils sont bien formatés selon la
          <a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>, section
          4.2 : les noms d'en-têtes doivent commencer par une lettre,
          elle-même suivie de lettres, chiffres ou traits d'union. Tout
          en-tête dont le nom viole cette règle sera ignoré.</p>
    
        
    
        <h3><a name="syntaxerrors" id="syntaxerrors">Erreurs inhérentes au programme</a></h3>
          
    
          <p>La plupart des échecs dans l'exécution d'un programme CGI
          proviennent du programme lui-même. Ceci est particulièrement vrai
          lorsque ce satané programme CGI se bloque, alors que vous avez
          appris à ne plus commettre les deux erreurs précédentes. La
          première chose à faire est de vous assurer que votre programme
          s'exécute depuis la ligne de commande, avant de le tester à partir
          du serveur web. Par exemple, essayez :</p>
    
          <div class="example"><p><code>
          cd /usr/local/apache2/cgi-bin<br />
          ./premier.pl
          </code></p></div>
    
          <p>(N'invoquez pas l'interpréteur <code>perl</code>. Le shell et
          Apache doivent être capable de le déterminer à partir de <a href="#pathinformation">l'information sur le chemin</a> située sur
          la première ligne du script.)</p>
    
          <p>La première chose que vous devriez voir affichée par votre
          programme est un ensemble d'en-têtes HTTP, comprenant entre autres
          le <code>Content-Type</code>, et suivi d'une ligne vide. Si vous
          voyez quoi que ce soit d'autre, Apache renverra l'erreur
          <code>Premature end of script headers</code> si vous tentez
          d'exécuter le programme depuis le serveur. Voir <a href="#writing">Ecriture d'un programme CGI</a> ci-dessus pour
          plus de détails.</p>
        
    
        <h3><a name="errorlogs" id="errorlogs">Journalisation des erreurs</a></h3>
          
    
          <p>Les journaux d'erreurs sont vos amis. Toute anomalie de
          fonctionnement est consignée dans le journal des erreurs et c'est
          ici que vous devez regarder en premier en cas de problème. Si
          l'hébergeur de votre site ne vous donne pas accès au journal des
          erreurs, vous avez tout intérêt à vous tourner vers quelqu'un
          d'autre. Apprenez à déchiffrer les journaux d'erreurs, et vous
          vous apercevrez que la plupart des problèmes seront rapidement
          identifiés . . . et résolus.</p>
        
    
        <h3><a name="suexec" id="suexec">Suexec</a></h3>
          
    
          <p>Le programme <a href="../suexec.html">suexec</a> permet
          d'exécuter les programmes CGI avec des droits différents selon le
          serveur virtuel ou le répertoire utilisateur dans lequel ils
          se situent. Suexec effectue une vérification des droits très
          stricte, et toute anomalie détectée au cours de cette vérification
          entraînera un echec d'exécution de votre programme CGI avec
          affichage de l'erreur <code>Premature end of script
          headers</code>.</p>
    
          <p>Pour savoir si vous pouvez utiliser suexec, tapez la commande
          <code>apachectl -V</code>, et regardez le chemin indiqué par
          <code>SUEXEC_BIN</code>. Si au démarrage d'Apache, ce dernier
          trouve un exécutable <code class="program"><a href="../programs/suexec.html">suexec</a></code> dans ce chemin,
          suexec sera activé.</p>
    
          <p>Si vous ne maîtrisez pas le fonctionnement de suexec, il vous
          est déconseillé de l'utiliser. Pour désactiver suexec, supprimer
          simplement (ou renommez) l'exécutable <code class="program"><a href="../programs/suexec.html">suexec</a></code>
          pointé par <code>SUEXEC_BIN</code> et redémarrez le serveur. Si
          après une lecture de <a href="../suexec.html">suexec</a>, vous
          décidez quand-même de l'utiliser, tapez la commande <code>suexec
          -V</code> pour voir où se situe le journal de suexec, et utilisez
          ce dernier pour déterminer quelles règles vous violez
          éventuellement.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="behindscenes" id="behindscenes">Que se passe-t-il en coulisse</a></h2>
        
    
        <p>Lorsque vos compétences en programmation CGI seront plus
        poussées, il s'avérera intéressant pour vous de mieux comprendre ce
        qui se passe en coulisse, et en particulier la manière dont le
        navigateur et le serveur dialoguent entre eux. En effet, bien qu'il
        soit tout à fait louable d'écrire un programme qui affiche "Bonjour
        tout le monde . . .", cela ne sert pas à grand chose.</p>
    
        <h3><a name="env" id="env">Variables d'environnement</a></h3>
          
    
          <p>Les variables d'environnement sont des valeurs qui gravitent
          autour de vous lorsque vous utilisez votre ordinateur. Elles sont
          très utiles, à l'instar de votre chemin par défaut (où votre
          ordinateur va rechercher le fichier physique correspondant à la
          commande que vous avez tapée), votre nom d'utilisateur, le type de
          votre terminal, etc... Pour obtenir une liste complète des
          variables d'environnement standards que vous utilisez tous les
          jours, tapez <code>env</code> dans votre interpréteur
          de commandes.</p>
    
          <p>Au cours de la transaction CGI, le serveur et le navigateur
          définissent aussi des variables d'environnement, de façon à ce
          qu'ils puissent communiquer entre eux. Ces variables définissent
          entre autre le type de navigateur (Netscape, IE, Lynx), le type de
          serveur (Apache, IIS, WebSite), le nom du programme CGI en cours
          d'exécution, etc...</p>
    
          <p>Ces variables sont à la disposition du programmeur CGI, et
          elles constituent 50% de la communication client-serveur. La liste
          complète des variables requises se trouve à
          <a href="http://www.ietf.org/rfc/rfc3875">Common Gateway
          Interface RFC</a>.</p>
    
          <p>Ce programme CGI basique en Perl permet d'afficher toutes les
          variables d'environnement qui sont échangées. Deux programmes
          similaires sont fournis avec la distribution d'Apache et situés
          dans le répertoire <code>cgi-bin</code>.
          Notez que certaines variables sont
          obligatoires, alors que d'autres sont optionnelles, si bien que
          vous verrez s'afficher certaines variables qui ne font pas partie
          de la liste officielle. De plus, Apache vous propose de nombreuses
          méthodes pour <a href="../env.html">ajouter vos propres
          variables d'environnement</a> aux variables de base fournies par
          défaut.</p>
    
          <pre class="prettyprint lang-perl">#!/usr/bin/perl
    use strict;
    use warnings;
    
    print "Content-type: text/html\n\n";
    foreach my $key (keys %ENV) {
        print "$key --&gt; $ENV{$key}&lt;br&gt;";
    }</pre>
    
        
    
        <h3><a name="stdin" id="stdin">STDIN et STDOUT</a></h3>
          
    
          <p>L'entrée standard (<code>STDIN</code>) et la sortie standard
          (<code>STDOUT</code>) constituent d'autres voies de communication
          entre le client et le serveur. Dans un contexte normal,
          <code>STDIN</code> correspond au clavier, ou à un fichier fourni
          au programme à des fins de traitement, et <code>STDOUT</code> à la
          console ou à l'écran.</p>
    
          <p>Lorsque vous transmettez un formulaire web à un programme CGI
          par la méthode <code>POST</code>, les données de ce formulaire
          sont transcrites dans un format spécial et transmises à votre
          programme CGI via <code>STDIN</code>. Le programme peut alors les
          traiter comme si elles provenaient du clavier ou d'un
          fichier.</p>
    
          <p>Ce "format spécial" est très simple. Un nom de champ et sa
          valeur sont reliés entre eux par un signe "égal" (=), et chacune
          de ces paires nom champ/valeur est séparée de la suivante par un
          "et" commercial (&amp;). Les caractères
          spéciaux comme les espaces, les "et" commerciaux, et les signes
          "égal" sont convertis en leur équivalent hexadécimal pour éviter
          qu'ils ne gâchent le travail. La chaîne contenant les données doit
          ressembler à ceci :</p>
    
          <div class="example"><p><code>
            name=Rich%20Bowen&amp;city=Lexington&amp;state=KY&amp;sidekick=Squirrel%20Monkey
          </code></p></div>
    
          <p>Vous verrez aussi parfois une chaîne de ce type accolée à une
          URL. Dans ce cas, le serveur enregistre cette chaîne dans la
          variable d'environnement appelée <code>QUERY_STRING</code>. On a
          alors affaire à une requête de type <code>GET</code>. Votre
          formulaire HTML indique laquelle des méthodes <code>GET</code> ou
          <code>POST</code> est utilisée pour transmettre les données, en
          définissant l'attribut <code>METHOD</code> au niveau de la balise
          <code>FORM</code>.</p>
    
          <p>Votre programme est ensuite chargé d'extraire les informations
          utiles de cette chaîne. Heureusement, des bibliothèques et des
          modules sont à votre disposition pour vous aider à traiter ces
          données, et à gérer les différents aspects de votre programme
          CGI.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="libraries" id="libraries">Bibliothèques et modules CGI</a></h2>
        
    
        <p>Pour écrire un programme CGI, il vous est conseillé d'utiliser
        une bibliothèque de code, ou un module, qui effectueront une grande
        partie du travail de base pour vous. Ceci vous permettra de diminuer
        le nombre d'erreurs et d'accélérer le développement.</p>
    
        <p>Si vous écrivez des programmes CGI en Perl, des modules sont à
        votre disposition à <a href="http://www.cpan.org/">CPAN</a>. A ce
        sujet, le module le plus populaire est <code>CGI.pm</code>. Vous
        pouvez aussi essayer <code>CGI::Lite</code>, qui implémente les
        fonctionnalités strictement nécessaires, mais suffisantes pour
        la majorité des programmes.</p>
    
        <p>Si vous écrivez des programmes CGI en C, vous disposez de nombreuses
        options. L'une d'elles est la bibliothèque <code>CGIC</code> de  <a href="https://web.mit.edu/wwwdev/www/cgic.html">https://web.mit.edu/wwwdev/www/cgic.html</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinfo" id="moreinfo">Pour plus d'informations</a></h2>
        
    
        <p>La spécification CGI actuelle est disponible dans la <a href="http://www.ietf.org/rfc/rfc3875">Common Gateway
        Interface RFC</a>.</p>
    
        <p>Lorsque vous postez une question à propos d'un problème CGI que
        vous rencontrez, que ce soit dans une liste de diffusion ou dans un
        newsgroup, faites en sorte de fournir suffisamment d'informations
        sur le problème rencontré, ce que vous attendiez exactement, et en
        quoi ce qui se produit est réellement différent de ce que vous
        attendiez, quel serveur vous utilisez, en quel langage votre
        programme CGI a été écrit, et, si possible, son code source. Ceci
        permettra une résolution plus aisée de votre problème.</p>
    
        <p>Notez que les questions à propos de problèmes CGI ne doivent
        <strong>jamais</strong> être postées dans la base de données de
        bogues d'Apache, à moins que vous ne soyez sûr d'avoir trouvé un
        problème dans le code source d'Apache.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/cgi.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/cgi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/cgi.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/cgi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/cgi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/cgi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/public_html.html.fr.utf8���������������������������������������������0000664�0001751�0001751�00000034456�14740503670�022674� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Répertoires web utilisateurs - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Recettes et tutoriels</a></div><div id="page-content"><div id="preamble"><h1>Répertoires web utilisateurs</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    <p>Sur les systèmes multi-utilisateurs, on peut permettre à chaque
    utilisateur d'avoir un site web dans son répertoire home à l'aide de la
    directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>. Les
    visiteurs de l'URL <code>http://example.com/~nom_utilisateur/</code>
    recevront un contenu situé dans le répertoire home de l'utilisateur
    "<code>nom_utilisateur</code>", et dans le sous-répertoire spécifié par
    la directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>.</p>
    <p>Notez que par défaut, l'accès à ces répertoires n'est
    <strong>pas</strong> permis. Vous pouvez en permettre l'accès à l'aide
    de la directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> en
    décommentant la ligne :</p>
        <pre class="prettyprint lang-config">#Include conf/extra/httpd-userdir.conf</pre>
    
        <p>dans le fichier de configuration par défaut
        <code>conf/httpd.conf</code>, et en adaptant le
        fichier <code>httpd-userdir.conf</code> selon vos besoins, ou en
        incluant les directives appropriées dans une section
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> du fichier de
        configuration principal.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Répertoires web utilisateurs</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#userdir">Définition du chemin des fichiers avec UserDir</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#redirect">Redirection vers des URLs externes</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#enable">Définition de la liste des utilisateurs autorisés à utiliser
        cette fonctionnalité</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#cgi">Définition d'un répertoire CGI pour chaque utilisateur</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">Permettre aux utilisateurs de modifier la
        configuration</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../urlmapping.html">Mise en correspondance des URLs
    avec le système de fichiers</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Répertoires web utilisateurs</a></h2>
        
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code></li><li><code class="directive"><a href="../mod/core.html#directorymatch">DirectoryMatch</a></code></li><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="userdir" id="userdir">Définition du chemin des fichiers avec UserDir</a></h2>
        
    
        <p>La directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>
        permet de spécifier un répertoire à partir duquel le contenu de
        l'utilisateur pourra être chargé. Elle peut revêtir plusieurs
        formes.</p>
    
        <p>Si le chemin spécifié ne commence pas par un slash, il sera
        interprété comme chemin relatif au répertoire home de l'utilisateur
        considéré. Par exemple, avec cette configuration :</p>
    
        <pre class="prettyprint lang-config">UserDir public_html</pre>
    
    
        <p>l'URL <code>http://example.com/~rbowen/fichier.html</code>
        correspondra au chemin fichier
        <code>/home/rbowen/public_html/fichier.html</code></p>
    
        <p>Si le chemin spécifié commence par un slash, le chemin du fichier
        sera construit en utilisant ce chemin, suivi du nom de l'utilisateur
        considéré. Par exemple, avec cette configuration :</p>
    
        <pre class="prettyprint lang-config">UserDir /var/html</pre>
    
    
        <p>l'URL <code>http://example.com/~rbowen/fichier.html</code>
        correspondra au chemin fichier
        <code>/var/html/rbowen/fichier.html</code></p>
    
        <p>Si le chemin spécifié contient un astérisque (*), ce dernier sera
        remplacé par le nom de l'utilisateur dans le chemin du fichier
        correspondant. Par exemple, avec cette configuration :</p>
    
        <pre class="prettyprint lang-config">UserDir /var/www/*/docs</pre>
    
    
        <p>l'URL <code>http://example.com/~rbowen/fichier.html</code>
        correspondra au chemin fichier
        <code>/var/www/rbowen/docs/fichier.html</code></p>
    
        <p>On peut aussi définir plusieurs répertoires ou chemins de
        répertoires.</p>
    
        <pre class="prettyprint lang-config">UserDir public_html /var/html</pre>
    
    
        <p>Avec l'URL <code>http://example.com/~rbowen/fichier.html</code>,
        Apache va rechercher <code>~rbowen</code>. S'il ne le trouve pas,
        Apache va rechercher <code>rbowen</code> dans
        <code>/var/html</code>. S'il le trouve, l'URL ci-dessus correspondra
        au chemin fichier <code>/var/html/rbowen/file.html</code></p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">Redirection vers des URLs externes</a></h2>
        
        <p>On peut utiliser la directive <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code> pour rediriger les requêtes
        relatives aux répertoires utilisateurs vers des URLs externes.</p>
    
        <pre class="prettyprint lang-config">UserDir http://example.org/users/*/</pre>
    
    
        <p>L'exemple ci-dessus va rediriger une requête pour
        <code>http://example.com/~bob/abc.html</code> vers
        <code>http://exemple.org/users/bob/abc.html</code>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">Définition de la liste des utilisateurs autorisés à utiliser
        cette fonctionnalité</a></h2>
        
    
        <p>En suivant la syntaxe décrite dans la documentation de UserDir,
        vous pouvez définir quels utilisateurs sont autorisés à utiliser
        cette fonctionnalité :</p>
    
        <pre class="prettyprint lang-config">UserDir disabled root jro fish</pre>
    
    
        <p>La configuration ci-dessus va autoriser l'utilisation de la
        fonctionnalité pour tous les utilisateurs, à l'exception de ceux
        listés à la suite de l'argument <code>disabled</code>. De même, vous
        pouvez interdire l'utilisation de la fonctionnalité à tous les
        utilisateurs sauf certains d'entre eux en utilisant une
        configuration du style :</p>
    
        <pre class="prettyprint lang-config">UserDir disabled
    UserDir enabled rbowen krietz</pre>
    
    
        <p>Vous trouverez d'autres exemples dans la documentation de
        <code class="directive"><a href="../mod/mod_userdir.html#userdir">UserDir</a></code>.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="cgi" id="cgi">Définition d'un répertoire CGI pour chaque utilisateur</a></h2>
      
    
       <p>Afin de réserver un répertoire cgi-bin pour chaque utilisateur,
       vous pouvez utiliser une section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> pour activer CGI dans un
       sous-répertoire particulier d'un répertoire home utilisateur.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html/cgi-bin/"&gt;
        Options ExecCGI
        SetHandler cgi-script
    &lt;/Directory&gt;</pre>
    
    
        <p>Avec la configuration ci-dessus, et en supposant que
        <code>UserDir</code> est défini à <code>public_html</code>, un
        programme CGI <code>exemple.cgi</code> pourra être chargé depuis ce
        répertoire en passant par l'URL :</p>
    
        <div class="example"><p><code>
        http://example.com/~rbowen/cgi-bin/exemple.cgi
        </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">Permettre aux utilisateurs de modifier la
        configuration</a></h2>
        
    
        <p>Si vous voulez que vos utilisateurs puissent modifier la
        configuration du serveur pour ce qui concerne leur espace web, ils
        devront utiliser des fichiers <code>.htaccess</code> pour effectuer
        ces modifications. Assurez-vous d'avoir défini la directive
        <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> à une valeur
        appropriée pour les directives dont vous voulez permettre la
        modification aux utilisateurs. Voir le <a href="htaccess.html">tutoriel .htaccess</a> pour plus de détails sur
        la manière dont tout ceci fonctionne.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/howto/public_html.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/public_html.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/public_html.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/public_html.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/public_html.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/howto/public_html.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/public_html.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/public_html.html�����������������������������������������������������0000664�0001751�0001751�00000001104�13710016232�021346� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: public_html.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: public_html.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: public_html.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: public_html.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: public_html.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: public_html.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/cgi.html�������������������������������������������������������������0000664�0001751�0001751�00000000701�13710016232�017610� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: cgi.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: cgi.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: cgi.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: cgi.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: cgi.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    ���������������������������������������������������������������httpd-2.4.64/docs/manual/howto/auth.html������������������������������������������������������������0000664�0001751�0001751�00000001032�13710016232�020005� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: auth.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: auth.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: auth.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: auth.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: auth.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: auth.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/index.html�����������������������������������������������������������0000664�0001751�0001751�00000001046�13710016232�020160� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: index.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: index.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/access.html.en�������������������������������������������������������0000664�0001751�0001751�00000032751�14737241666�020747� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Access Control - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Access Control</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/access.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/access.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/access.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Access control refers to any means of controlling access to any
        resource. This is separate from <a href="auth.html">authentication and authorization</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Related Modules and Directives</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#host">Access control by host</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#env">Access control by arbitrary variables</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite">Access control with mod_rewrite</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moreinformation">More information</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Related Modules and Directives</a></h2>
    
        <p>Access control can be done by several different modules. The most
        important of these are <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code> and
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>. Also discussed in this document
        is access control using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="host" id="host">Access control by host</a></h2>
        <p>
        If you wish to restrict access to portions of your site based on the
        host address of your visitors, this is most easily done using
        <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code>.
        </p>
    
        <p>The <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
        provides a variety of different ways to allow or deny access to
        resources. In conjunction with the <code class="directive"><a href="../mod/mod_authz_core.html#requireall">RequireAll</a></code>, <code class="directive"><a href="../mod/mod_authz_core.html#requireany">RequireAny</a></code>, and <code class="directive"><a href="../mod/mod_authz_core.html#requirenone">RequireNone</a></code> directives, these
        requirements may be combined in arbitrarily complex ways, to enforce
        whatever your access policy happens to be.</p>
    
        <div class="warning"><p>
        The <code class="directive"><a href="../mod/mod_access_compat.html#allow">Allow</a></code>,
        <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code>, and
        <code class="directive"><a href="../mod/mod_access_compat.html#order">Order</a></code> directives,
        provided by <code class="module"><a href="../mod/mod_access_compat.html">mod_access_compat</a></code>, are deprecated and
        will go away in a future version. You should avoid using them, and
        avoid outdated tutorials recommending their use.
        </p></div>
    
        <p>The usage of these directives is:</p>
    
        <pre class="prettyprint lang-config">Require host address
    Require ip ip.address</pre>
    
    
        <p>In the first form, <var>address</var> is a fully qualified
        domain name (or a partial domain name); you may provide multiple
        addresses or domain names, if desired.</p>
    
        <p>In the second form, <var>ip.address</var> is an IP address, a
        partial IP address, a network/netmask pair, or a network/nnn CIDR
        specification. Either IPv4 or IPv6 addresses may be used.</p>
    
        <p>See <a href="../mod/mod_authz_host.html#requiredirectives">the
        mod_authz_host documentation</a> for further examples of this
        syntax.</p>
    
        <p>You can insert <code>not</code> to negate a particular requirement.
        Note, that since a <code>not</code> is a negation of a value, it cannot 
        be used by itself to allow or deny a request, as <em>not true</em>
        does not constitute <em>false</em>. Thus, to deny a visit using a negation,
        the block must have one element that evaluates as true or false.
        For example, if you have someone spamming your message
        board, and you want to keep them out, you could do the
        following:</p>
    
        <pre class="prettyprint lang-config">&lt;RequireAll&gt;
        Require all granted
        Require not ip 10.252.46.165
    &lt;/RequireAll&gt;</pre>
    
    
        <p>Visitors coming from that address (<code>10.252.46.165</code>)
        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.</p>
    
        <pre class="prettyprint lang-config">Require not host <var>host.example.com</var>
        </pre>
    
    
        <p>And, if you'd like to block access from an entire domain,
        you can specify just part of an address or domain name:</p>
    
        <pre class="prettyprint lang-config">Require not ip 192.168.205
    Require not host phishers.example.com moreidiots.example
    Require not host gov</pre>
    
    
        <p>Use of the <code class="directive"><a href="../mod/mod_authz_core.html#requireall">RequireAll</a></code>, <code class="directive"><a href="../mod/mod_authz_core.html#requireany">RequireAny</a></code>, and <code class="directive"><a href="../mod/mod_authz_core.html#requirenone">RequireNone</a></code> directives may be
        used to enforce more complex sets of requirements.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="env" id="env">Access control by arbitrary variables</a></h2>
    
        <p>Using the <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>,
        you can allow or deny access based on arbitrary environment
        variables or request header values. For example, to deny access
        based on user-agent (the browser type) you might do the
        following:</p>
    
        <pre class="prettyprint lang-config">&lt;If "%{HTTP_USER_AGENT} == 'BadBot'"&gt;
        Require all denied
    &lt;/If&gt;</pre>
    
    
        <p>Using the <code class="directive"><a href="../mod/mod_authz_core.html#require">Require</a></code>
        <code>expr</code> syntax, this could also be written as:</p>
    
    
        <pre class="prettyprint lang-config">Require expr %{HTTP_USER_AGENT} != 'BadBot'</pre>
    
    
        <div class="note"><h3>Warning:</h3>
        <p>Access control by <code>User-Agent</code> is an unreliable technique,
        since the <code>User-Agent</code> header can be set to anything at all,
        at the whim of the end user.</p>
        </div>
    
        <p>See <a href="../expr.html">the expressions document</a> for a
        further discussion of what expression syntaxes and variables are
        available to you.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Access control with mod_rewrite</a></h2>
    
        <p>The <code>[F]</code> <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> flag causes a 403 Forbidden
        response to be sent. Using this, you can deny access to a resource based
        on arbitrary criteria.</p>
    
        <p>For example, if you wish to block access to a resource between 8pm
        and 7am, you can do this using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
        <pre class="prettyprint lang-config">RewriteEngine On
    RewriteCond "%{TIME_HOUR}" "&gt;=20" [OR]
    RewriteCond "%{TIME_HOUR}" "&lt;07"
    RewriteRule "^/fridge"     "-" [F]</pre>
    
    
        <p>This will return a 403 Forbidden response for any request after 8pm
        or before 7am. This technique can be used for any criteria that you wish
        to check. You can also redirect, or otherwise rewrite these requests, if
        that approach is preferred.</p>
    
        <p>The <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code> directive,
        added in 2.4, replaces many things that <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> has
        traditionally been used to do, and you should probably look there first
        before resorting to mod_rewrite.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moreinformation" id="moreinformation">More information</a></h2>
    
        <p>The <a href="../expr.html">expression engine</a> gives you a
        great deal of power to do a variety of things based on arbitrary
        server variables, and you should consult that document for more
        detail.</p>
    
        <p>Also, you should read the <code class="module"><a href="../mod/mod_authz_core.html">mod_authz_core</a></code>
        documentation for examples of combining multiple access requirements
        and specifying how they interact.</p>
    
        <p>See also the <a href="auth.html">Authentication and Authorization</a>
        howto.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/access.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/access.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/access.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/access.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������httpd-2.4.64/docs/manual/howto/http2.html.en��������������������������������������������������������0000664�0001751�0001751�00000063234�14737241666�020547� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>HTTP/2 guide - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>HTTP/2 guide</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/http2.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/http2.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/http2.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>This is the howto guide for the HTTP/2 implementation in Apache httpd. This
        feature is <em>production-ready</em> and you may expect interfaces and directives to
        remain consistent releases.
        </p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#protocol">The HTTP/2 protocol</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#implementation">HTTP/2 in Apache httpd</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#building">Build httpd with HTTP/2 support</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic-config">Basic Configuration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#mpm-config">MPM Configuration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#clients">Clients</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#tools">Useful tools to debug HTTP/2</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#push">Server Push</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#earlyhints">Early Hints</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="protocol" id="protocol">The HTTP/2 protocol</a></h2>
        
        <p>HTTP/2 is the evolution of the world's most successful application layer protocol, HTTP.
        It focuses on making more efficient use of network resources. It does not change the fundamentals
        of HTTP, the semantics. There are still request and responses and headers and all that. So, if
        you already know HTTP/1, you know 95% about HTTP/2 as well.</p>
        <p>There has been a lot written about HTTP/2 and how it works. The most normative is, of course,
        its <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a> 
        (<a href="http://httpwg.org/specs/rfc7540.html">also available in more readable formatting, YMMV</a>).
        So, there you'll find the nuts and bolts.</p>
        <p>But, as RFC do, it's not really a good thing to read first. It's better to first understand
        <em>what</em> a thing wants to do and then read the RFC about <em>how</em> it is done. A much
        better document to start with is <a href="https://daniel.haxx.se/http2/">http2  explained</a>
        by Daniel Stenberg, the author of <a href="https://curl.haxx.se">curl</a>. It is available in
        an ever growing list of languages, too!</p>
        <p>Too Long, Didn't read: there are some new terms and gotchas that need to be kept in mind while reading this document:</p>
        <ul>
            <li>HTTP/2 is a <strong>binary protocol</strong>, as opposed to HTTP 1.1 that is plain text. The latter is meant to be human readable (for example sniffing network traffic) meanwhile the former is not. More info in the official FAQ <a href="https://http2.github.io/faq/#why-is-http2-binary">question</a>.</li>
            <li><strong>h2</strong> is HTTP/2 over TLS (protocol negotiation via ALPN).</li>
            <li><strong>h2c</strong> is HTTP/2 over TCP.</li>
            <li>A <strong>frame</strong> is the smallest unit of communication within an HTTP/2 connection, consisting of a header and a variable-length sequence of octets structured according to the frame type. More info in the official documentation <a href="http://httpwg.org/specs/rfc7540.html#FramingLayer"> section</a>.</li>
            <li>A <strong>stream</strong> is a bidirectional flow of frames within the HTTP/2 connection. The correspondent concept in HTTP 1.1 is a request/response message exchange. More info in the official documentation <a href="http://httpwg.org/specs/rfc7540.html#StreamsLayer"> section</a>.</li>
            <li>HTTP/2 is able to run <strong>multiple streams</strong> of data over the same TCP connection, avoiding the classic HTTP 1.1 head of blocking slow request and avoiding to re-instantiate TCP connections for each request/response (KeepAlive patched the problem in HTTP 1.1 but did not fully solve it).</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">HTTP/2 in Apache httpd</a></h2>
        
        <p>The HTTP/2 protocol is implemented by its own httpd module, aptly named
        <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code>. It implements the complete set
        of features described by RFC 7540 and supports HTTP/2 over cleartext (http:), as
        well as secure (https:) connections. The cleartext variant is named '<code>h2c</code>', 
        the secure one '<code>h2</code>'. For <code>h2c</code> it allows the <em>direct</em>
        mode and the <code>Upgrade:</code> via an initial HTTP/1 request.</p>
        <p>One feature of HTTP/2 that offers new capabilities for web developers is
        <a href="#push">Server Push</a>. See that section on how your web application
        can make use of it.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="building" id="building">Build httpd with HTTP/2 support</a></h2>
        
        <p><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> uses the library of <a href="https://nghttp2.org">nghttp2</a>
        as its implementation base. In order to build <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> you need at least version 1.2.1 of
        <code>libnghttp2</code> installed on your system.</p>
        <p>When you <code>./configure</code> your Apache httpd source tree, you need to give it 
        '<code>--enable-http2</code>' as additional argument to trigger the build of the module.
        Should your <code>libnghttp2</code> reside in an unusual place (whatever that is on your
        operating system), you may announce its location with '<code>--with-nghttp2=&lt;path&gt;</code>'
        to <code>configure</code>.</p>
        <p>While that should do the trick for most, they are people who might prefer a statically
        linked <code>nghttp2</code> in this module. For those, the option <code>--enable-nghttp2-staticlib-deps</code>
        exists. It works quite similar to how one statically links openssl to <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code>.</p>
        <p>Speaking of SSL, you need to be aware that most browsers will speak HTTP/2 only on <code>https:</code>
        URLs, so you need a server with SSL support. But not only that, you will need a SSL library
        that supports the <code>ALPN</code> extension. If OpenSSL is the library you use, you need
        at least version 1.0.2.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic-config" id="basic-config">Basic Configuration</a></h2>
        
    
        <p>When you have a <code>httpd</code> built with <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> you need some
        basic configuration for it becoming active. The first thing, as with every Apache module,
        is that you need to load it:</p>
        <pre class="prettyprint lang-config">LoadModule http2_module modules/mod_http2.so</pre>
    
        
        <p>The second directive you need to add to your server configuration is</p>
        <pre class="prettyprint lang-config">Protocols h2 http/1.1</pre>
    
        <p>This allows h2, the secure variant, to be the preferred protocol on your server
        connections. When you want to enable all HTTP/2 variants, you simply write:</p>
        <pre class="prettyprint lang-config">Protocols h2 h2c http/1.1</pre>
    
        <p>Depending on where you put this directive, it affects all connections or just
        the ones to a certain virtual host. You can nest it, as in:</p>
        <pre class="prettyprint lang-config">Protocols http/1.1
    &lt;VirtualHost ...&gt;
        ServerName test.example.org
        Protocols h2 http/1.1
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>This allows only HTTP/1 on connections, except SSL connections to <code>test.example.org</code>
        which offer HTTP/2.</p>
        <div class="note"><h3>Choose a strong SSLCipherSuite</h3>
        <p>The <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code> needs to be configured with
        a strong TLS cipher suite. The current version of <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> does not enforce any cipher but most
        clients do so. Pointing a browser to a <code>h2</code> enabled server with a inappropriate
        cipher suite will force it to simply refuse and fall back to HTTP 1.1. This is a common mistake
        that is done while configuring httpd for HTTP/2 the first time, so please keep it in mind to avoid
        long debugging sessions! If you want to be sure about the cipher suite to choose please avoid
        the ones listed in the <a href="http://httpwg.org/specs/rfc7540.html#BadCipherSuites">HTTP/2 TLS reject list</a>.</p>
        </div>
        <p>The order of protocols mentioned is also relevant. By default, the first one is the 
        most preferred protocol. When a client offers multiple choices, the one most to the 
        left is selected. In</p>
        <pre class="prettyprint lang-config">Protocols http/1.1 h2</pre>
    
        <p>the most preferred protocol is HTTP/1 and it will always be selected unless a 
        client <em>only</em> supports h2. Since we want to talk HTTP/2 to clients that
        support it, the better order is</p>
        <pre class="prettyprint lang-config">Protocols h2 h2c http/1.1</pre>
    
    
        <p>There is one more thing to ordering: the client has its own preferences, too. If
        you want, you can configure your server to select the protocol most preferred by
        the client:</p>
        <pre class="prettyprint lang-config">ProtocolsHonorOrder Off</pre>
    
        <p>makes the order <em>you</em> wrote the Protocols irrelevant and only the client's
        ordering will decide.</p>
        <p>A last thing: the protocols you configure are not checked for correctness
        or spelling. You can mention protocols that do not exist, so there is no need
        to guard <code class="directive"><a href="../mod/core.html#protocols">Protocols</a></code> with any
        <code class="directive"><a href="../mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> checks.</p>
        <p>For more advanced tips on configuration, see the <a href="../mod/mod_http2.html#dimensioning">
        modules section about dimensioning</a> and <a href="../mod/mod_http2.html#misdirected">
        how to manage multiple hosts with the same certificate</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mpm-config" id="mpm-config">MPM Configuration</a></h2>
        
        
        <p>HTTP/2 is supported in all multi-processing modules that come with httpd. However, if
        you use the <code class="module"><a href="../mod/prefork.html">prefork</a></code> mpm, there will be severe restrictions.</p>
        <p>In <code class="module"><a href="../mod/prefork.html">prefork</a></code>, <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> will only process one request at at time
        per connection. But clients, such as browsers, will send many requests at the same time.
        If one of these takes long to process (or is a long polling one), the other requests will
        stall.</p>
        <p><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> will not work around this limit by default. The reason is that
        <code class="module"><a href="../mod/prefork.html">prefork</a></code> is today only chosen, if you run processing engines that are not
        prepared for multi-threading, e.g. will crash with more than one request.</p>
        <p>If your setup can handle it, configuring <code class="module"><a href="../mod/event.html">event</a></code> mpm is nowadays
        the best one (if supported on your platform).</p>
        <p>If you are really stuck with <code class="module"><a href="../mod/prefork.html">prefork</a></code> and want multiple requests,
        you can tweak the <code class="directive"><a href="../mod/mod_http2.html#h2minworkers">H2MinWorkers</a></code> to make
        that possible. If it breaks, however, you own both parts.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="clients" id="clients">Clients</a></h2>
        
        <p>Almost all modern browsers support HTTP/2, but only over SSL connections: Firefox (v43),
        Chrome (v45), Safari (since v9), iOS Safari (v9), Opera (v35), Chrome for Android (v49)
        and Internet Explorer (v11 on Windows10) (<a href="http://caniuse.com/#search=http2">source</a>).</p>
        <p>Other clients, as well as servers, are listed 
        <a href="https://github.com/http2/http2-spec/wiki/Implementations">on the Implementations wiki</a>,
        among them implementations for c, c++, common lisp, dart, erlang, haskell, java, nodejs,  php, 
        python, perl, ruby, rust, scala and swift.</p>
        <p>Several of the non-browser client implementations support HTTP/2 over cleartext, h2c. The
        most versatile being <a href="https://curl.haxx.se">curl</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tools" id="tools">Useful tools to debug HTTP/2</a></h2>
        
        <p>The first tool to mention is of course <a href="https://curl.haxx.se">curl</a>. Please make sure that
        your version supports HTTP/2 checking its <code>Features</code>:</p>
        <pre class="prettyprint lang-config">    $ curl -V
        curl 7.45.0 (x86_64-apple-darwin15.0.0) libcurl/7.45.0 OpenSSL/1.0.2d zlib/1.2.8 nghttp2/1.3.4
        Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 [...] 
        Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP <strong>HTTP2</strong>
        </pre>
    
        <div class="note"><h3>Mac OS homebrew notes</h3>
        brew install curl --with-openssl --with-nghttp2 
        </div>
        <p>And for really deep inspection <a href="https://wiki.wireshark.org/HTTP2">wireshark</a>.</p>
        <p>The <a href="https://nghttp2.org">nghttp2</a> package also includes clients, such as:</p>
        <ul>
            <li><a href="https://nghttp2.org/documentation/nghttp.1.html">nghttp</a> - useful to visualize the HTTP/2 frames and get a better idea of the protocol.</li>
            <li><a href="https://nghttp2.org/documentation/h2load-howto.html">h2load</a> - useful to stress-test your server.</li>
        </ul>
        <p>Chrome offers detailed HTTP/2 logs on its connections via the 
        <a href="chrome://net-internals/#http2">special net-internals page</a>. There is also an
        interesting extension for <a href="https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=en">Chrome</a>
        and <a href="https://addons.mozilla.org/en-us/firefox/addon/spdy-indicator/">Firefox</a>
        to visualize when your browser is using HTTP/2.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="push" id="push">Server Push</a></h2>
        
        <p>The HTTP/2 protocol allows the server to PUSH responses to a client it never
        asked for. The tone of the conversation is: "here is a request that you
        never sent and the response to it will arrive soon..."</p>
        <p>But there are restrictions: the client can disable this feature and the
        server may only ever PUSH on a request that came from the client.</p>
        <p>The intention is to allow the server to send resources to the client that
        it will most likely need: a css or javascript resource that belongs to a html
        page the client requested. A set of images that is referenced by a css, etc.</p>
        <p>The advantage for the client is that it saves the time to send the request which
        may range from a few milliseconds to half a second, depending on where on the 
        globe both are located. The disadvantage is that the client may get sent
        things it already has in its cache. Sure, HTTP/2 allows for the early cancellation
        of such requests, but still there are resources wasted.</p>
        <p>To summarize: there is no one good strategy on how to make best use of this 
        feature of HTTP/2 and everyone is still experimenting. So, how do you experiment
        with it in Apache httpd?</p>
        <p><code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code> inspect response header for <code>Link</code> headers
        in a certain format:</p>
        <pre class="prettyprint lang-config">Link &lt;/xxx.css&gt;;rel=preload, &lt;/xxx.js&gt;; rel=preload</pre>
    
        <p>If the connection supports PUSH, these two resources will be sent to the
        client. As a web developer, you may set these headers either directly in
        your application response or you configure the server via</p>
        <pre class="prettyprint lang-config">&lt;Location /xxx.html&gt;
        Header add Link "&lt;/xxx.css&gt;;rel=preload"
        Header add Link "&lt;/xxx.js&gt;;rel=preload"
    &lt;/Location&gt;</pre>
    
        <p>If you want to use <code>preload</code> links without triggering a PUSH, you
        can use the <code>nopush</code> parameter, as in</p>
        <pre class="prettyprint lang-config">Link &lt;/xxx.css&gt;;rel=preload;nopush</pre>
    
        <p>or you may disable PUSHes for your server entirely with the directive</p>
        <pre class="prettyprint lang-config">H2Push Off</pre>
    
        <p>And there is more:</p>
        <p>The module will keep a diary of what has been PUSHed for each connection
        (hashes of URLs, basically) and will not PUSH the same resource twice. When
        the connection closes, this information is discarded.</p>
        <p>There are people thinking about how a client can tell a server what it
        already has, so PUSHes for those things can be avoided, but this is all
        highly experimental right now.</p>
        <p>Another experimental draft that has been implemented in <code class="module"><a href="../mod/mod_http2.html">mod_http2</a></code>
        is the <a href="https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00">
        Accept-Push-Policy Header Field</a> where a client can, for each request, define
        what kind of PUSHes it accepts.</p>
        <p>
        PUSH might not always trigger the request/response/performance that one expects or 
        hopes for. There are various studies on this topic to be found on the web that explain
        benefits and weaknesses and how different features of client and network influence
        the outcome. For example: just because the server PUSHes a resource does not mean
        a browser will actually use the data.</p>
        <p>The major thing that influences the response being PUSHed is the request that was
        simulated. The request URL for a PUSH is given by the application, but where do the
        request headers come from? For example, will the PUSH request a <code>accept-language</code>
        header and if yes with what value?</p>
        <p>Apache will look at the original request (the one that triggered the PUSH) and copy the 
        following headers over to PUSH requests: <code>user-agent</code>, <code>accept</code>, 
        <code>accept-encoding</code>, <code>accept-language</code>, <code>cache-control</code>.</p>
        <p>All other headers are ignored. Cookies will also not be copied over. PUSHing resources
        that require a cookie to be present will not work. This can be a matter of debate. But 
        unless this is more clearly discussed with browser, let's err on the side of caution and
        not expose cookie where they might ordinarily not be visible.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="earlyhints" id="earlyhints">Early Hints</a></h2>
        
        <p>An alternative to PUSHing resources is to send <code>Link</code> headers to the
        client before the response is even ready. This uses the HTTP feature called "Early Hints" and
        is described in <a href="https://tools.ietf.org/html/rfc8297">RFC 8297</a>.</p>
        <p>In order to use this, you need to explicitly enable it on the server via</p>
        <pre class="prettyprint lang-config">H2EarlyHints on</pre>
    
        <p>(It is not enabled by default since some older browser tripped on such responses.)</p>
        <p>If this feature is on, you can use the directive <code class="directive"><a href="../mod/mod_http2.html#h2pushresource">H2PushResource</a></code> to 
        trigger early hints and resource PUSHes:</p>
        <pre class="prettyprint lang-config">&lt;Location /xxx.html&gt;
        H2PushResource /xxx.css
        H2PushResource /xxx.js
    &lt;/Location&gt;</pre>
    
        <p>This will send out a <code>"103 Early Hints"</code> response to a client as soon
        as the server <em>starts</em> processing the request. This may be much early than
        the time the first response headers have been determined, depending on your web
        application.</p>
        <p>If <code class="directive"><a href="../mod/mod_http2.html#h2push">H2Push</a></code> is enabled, this will also start the PUSH right after the
        103 response. If <code class="directive"><a href="../mod/mod_http2.html#h2push">H2Push</a></code> is disabled however, the 103 response will be send
        nevertheless to the client.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/http2.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/http2.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/http2.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/http2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/ssi.html.en����������������������������������������������������������0000664�0001751�0001751�00000063107�14737241666�020303� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache httpd Tutorial: Introduction to Server Side Includes - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Apache httpd Tutorial: Introduction to Server Side Includes</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/howto/ssi.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div>
    
    <p>Server-side includes provide a means to add dynamic content to
    existing HTML documents.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#what">What are SSI?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#configuring">Configuring your server to permit SSI</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#basic">Basic SSI directives</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#additionalexamples">Additional examples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#config">What else can I config?</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exec">Executing commands</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#advanced">Advanced SSI techniques</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#conclusion">Conclusion</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Introduction</a></h2>
     <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code></li><li><code class="directive"><a href="../mod/core.html#setoutputfilter">SetOutputFilter</a></code></li><li><code class="directive"><a href="../mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li></ul></td></tr></table>
    
        <p>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.</p>
    
        <p>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.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="what" id="what">What are SSI?</a></h2>
    
        <p>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.</p>
    
        <p>For example, you might place a directive into an existing HTML
        page, such as:</p>
    
        <div class="example"><p><code>
        &lt;!--#echo var="DATE_LOCAL" --&gt;
        </code></p></div>
    
        <p>And, when the page is served, this fragment will be evaluated and replaced with its value:</p>
    
        <div class="example"><p><code>
        Tuesday, 15-Jan-2013 19:28:54 EST
        </code></p></div>
    
        <p>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 - shown
        above.  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.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuring" id="configuring">Configuring your server to permit SSI</a></h2>
    
    
        <p>To permit SSI on your server, you must have the following
        directive either in your <code>httpd.conf</code> file, or in a
        <code>.htaccess</code> file:</p>
    <pre class="prettyprint lang-config">Options +Includes</pre>
    
    
        <p>This tells Apache that you want to permit files to be parsed
        for SSI directives.  Note that most configurations contain
        multiple <code class="directive"><a href="../mod/core.html#options">Options</a></code> directives
        that can override each other.  You will probably need to apply the
        <code>Options</code> to the specific directory where you want SSI
        enabled in order to assure that it gets evaluated last.</p>
    
        <p>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 <code>.shtml</code>, with
        the following directives:</p>
    <pre class="prettyprint lang-config">AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml</pre>
    
    
        <p>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 <code>.shtml</code> extension, so that those
        directives would be executed.</p>
    
        <p>The other method is to use the <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code> directive:</p>
    <pre class="prettyprint lang-config">XBitHack on</pre>
    
    
        <p><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>
        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 <code>chmod</code>.</p>
    <div class="example"><p><code>
            chmod +x pagename.html
    </code></p></div>
    
        <p>A brief comment about what not to do. You'll occasionally
        see people recommending that you just tell Apache to parse all
        <code>.html</code> files for SSI, so that you don't have to
        mess with <code>.shtml</code> file names. These folks have
        perhaps not heard about <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>. 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.</p>
    
        <p>Of course, on Windows, there is no such thing as an execute
        bit to set, so that limits your options a little.</p>
    
        <p>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:</p>
    
        <ol>
          <li>Use the <code>XBitHack Full</code> 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.</li>
    
          <li>Use the directives provided by
          <code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> to set an explicit expiration
          time on your files, thereby letting browsers and proxies
          know that it is acceptable to cache them.</li>
        </ol>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="basic" id="basic">Basic SSI directives</a></h2>
    
        <p>SSI directives have the following syntax:</p>
    <div class="example"><p><code>
            &lt;!--#function attribute=value attribute=value ... --&gt;
    </code></p></div>
    
        <p>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.</p>
    
        <p>The function 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</p>
    
    <h3><a name="todaysdate" id="todaysdate">Today's date</a></h3>
    
    <div class="example"><p><code>
            &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
        <p>The <code>echo</code> function 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 <code>set</code> function.</p>
    
        <p>If you don't like the format in which the date gets printed,
        you can use the <code>config</code> function, with a
        <code>timefmt</code> attribute, to modify that formatting.</p>
    
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            Today is &lt;!--#echo var="DATE_LOCAL" --&gt;
    </code></p></div>
    
    
    <h3><a name="lastmodified" id="lastmodified">Modification date of the file</a></h3>
    
    <div class="example"><p><code>
            This document last modified &lt;!--#flastmod file="index.html" --&gt;
    </code></p></div>
    
        <p>This function is also subject to <code>timefmt</code> format
        configurations.</p>
    
    
    <h3><a name="cgi" id="cgi">Including the results of a CGI program</a></h3>
    
        <p>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.''</p>
    
    <div class="example"><p><code>
            &lt;!--#include virtual="/cgi-bin/counter.pl" --&gt;
    </code></p></div>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="additionalexamples" id="additionalexamples">Additional examples</a></h2>
    
    
        <p>Following are some specific examples of things you can do in
        your HTML documents with SSI.</p>
    
    <h3><a name="docmodified" id="docmodified">When was this document
    modified?</a></h3>
    
        <p>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.</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%A %B %d, %Y" --&gt;<br />
            This file last modified &lt;!--#flastmod file="ssi.shtml" --&gt;
    </code></p></div>
    
        <p>Of course, you will need to replace the
        <code>ssi.shtml</code> 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
        <code>LAST_MODIFIED</code> variable instead:</p>
    <div class="example"><p><code>
            &lt;!--#config timefmt="%D" --&gt;<br />
            This file last modified &lt;!--#echo var="LAST_MODIFIED" --&gt;
    </code></p></div>
    
        <p>For more details on the <code>timefmt</code> format, go to
        your favorite search site and look for <code>strftime</code>. The
        syntax is the same.</p>
    
    
    <h3><a name="standard-footer" id="standard-footer">Including a standard footer</a></h3>
    
    
        <p>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.</p>
    
        <p>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
        <code>include</code> SSI command. The <code>include</code>
        function can determine what file to include with either the
        <code>file</code> attribute, or the <code>virtual</code>
        attribute. The <code>file</code> attribute is a file path,
        <em>relative to the current directory</em>. That means that it
        cannot be an absolute file path (starting with /), nor can it
        contain ../ as part of that path. The <code>virtual</code>
        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.</p>
    <div class="example"><p><code>
            &lt;!--#include virtual="/footer.html" --&gt;
    </code></p></div>
    
        <p>I'll frequently combine the last two things, putting a
        <code>LAST_MODIFIED</code> 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.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="config" id="config">What else can I config?</a></h2>
    
    
        <p>In addition to being able to <code>config</code> the time
        format, you can also <code>config</code> two other things.</p>
    
        <p>Usually, when something goes wrong with your SSI directive,
        you get the message</p>
    <div class="example"><p><code>
            [an error occurred while processing this directive]
    </code></p></div>
    
        <p>If you want to change that message to something else, you
        can do so with the <code>errmsg</code> attribute to the
        <code>config</code> function:</p>
    <div class="example"><p><code>
            &lt;!--#config errmsg="[It appears that you don't know how to use SSI]" --&gt;
    </code></p></div>
    
        <p>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?)</p>
    
        <p>And you can <code>config</code> the format in which file
        sizes are returned with the <code>sizefmt</code> attribute. You
        can specify <code>bytes</code> for a full count in bytes, or
        <code>abbrev</code> for an abbreviated number in Kb or Mb, as
        appropriate.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exec" id="exec">Executing commands</a></h2>
        
    
        <p>Here's something else that you can do with the <code>exec</code>
        function. You can actually have SSI execute a command using the
        shell (<code>/bin/sh</code>, to be precise - or the DOS shell,
        if you're on Win32). The following, for example, will give you
        a directory listing.</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="ls" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>or, on Windows</p>
    <div class="example"><p><code>
            &lt;pre&gt;<br />
            &lt;!--#exec cmd="dir" --&gt;<br />
            &lt;/pre&gt;
    </code></p></div>
    
        <p>You might notice some strange formatting with this directive
        on Windows, because the output from <code>dir</code> contains
        the string ``&lt;<code>dir</code>&gt;'' in it, which confuses
        browsers.</p>
    
        <p>Note that this feature is exceedingly dangerous, as it will
        execute whatever code happens to be embedded in the
        <code>exec</code> 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
        <code>exec</code> feature, with the <code>IncludesNOEXEC</code>
        argument to the <code>Options</code> directive.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advanced" id="advanced">Advanced SSI techniques</a></h2>
    
    
        <p>In addition to spitting out content, Apache SSI gives you
        the option of setting variables, and using those variables in
        comparisons and conditionals.</p>
    
    <h3><a name="variables" id="variables">Setting variables</a></h3>
    
        <p>Using the <code>set</code> 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:</p>
    <div class="example"><p><code>
            &lt;!--#set var="name" value="Rich" --&gt;
    </code></p></div>
    
        <p>In addition to merely setting values literally like that, you
        can use any other variable, including <a href="../env.html">environment variables</a> or the variables
        discussed above (like <code>LAST_MODIFIED</code>, 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.</p>
    
        <div class="example"><p><code> &lt;!--#set var="modified" value="$LAST_MODIFIED" --&gt;
        </code></p></div>
    
        <p>To put a literal dollar sign into the value of your
        variable, you need to escape the dollar sign with a
        backslash.</p>
    <div class="example"><p><code>
            &lt;!--#set var="cost" value="\$100" --&gt;
    </code></p></div>
    
        <p>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.)</p>
    <div class="example"><p><code>
            &lt;!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --&gt;
    </code></p></div>
    
    
    <h3><a name="conditional" id="conditional">Conditional expressions</a></h3>
    
    
        <p>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.
        <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> provides an <code>if</code>,
        <code>elif</code>, <code>else</code>, <code>endif</code>
        structure for building conditional statements. This allows you
        to effectively generate multiple logical pages out of one
        actual page.</p>
    
        <p>The structure of this conditional construct is:</p>
    <div class="example"><p><code>
        &lt;!--#if expr="test_condition" --&gt;<br />
        &lt;!--#elif expr="test_condition" --&gt;<br />
        &lt;!--#else --&gt;<br />
        &lt;!--#endif --&gt;
    </code></p></div>
    
        <p>A <em>test_condition</em> 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 <code class="module"><a href="../mod/mod_include.html">mod_include</a></code>
        documentation.</p>
       
        <p>For example, if you wish to customize the text on your web page
        based on the time of day, you could use the following recipe, placed
        in the HTML page:</p>
    
        <div class="example"><p><code>
        Good
        &lt;!--#if expr="%{TIME_HOUR} &lt;12" --&gt;<br />
        morning!<br />
        &lt;!--#else --&gt;<br />
        afternoon!<br />
        &lt;!--#endif --&gt;<br />
        </code></p></div>
    
        <p>Any other variable (either ones that you define, or normal
        environment variables) can be used in conditional statements.
        See <a href="../expr.html">Expressions in Apache HTTP Server</a> for
        more information on the expression evaluation engine.</p>
    
        <p>With Apache's ability to set environment variables with the
        <code>SetEnvIf</code> directives, and other related directives,
        this functionality can let you do a wide variety of dynamic content
        on the server side without resorting a full web application.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="conclusion" id="conclusion">Conclusion</a></h2>
    
        <p>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.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/howto/ssi.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/howto/ssi.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/howto/ssi.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ja/howto/ssi.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="../ko/howto/ssi.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/howto/ssi.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/access.html����������������������������������������������������������0000664�0001751�0001751�00000000441�13710016232�020310� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: access.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: access.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: access.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/http2.html�����������������������������������������������������������0000664�0001751�0001751�00000000436�13710016232�020114� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: http2.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: http2.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: http2.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/ssi.html�������������������������������������������������������������0000664�0001751�0001751�00000000701�13710016232�017644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: ssi.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: ssi.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: ssi.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: ssi.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: ssi.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    ���������������������������������������������������������������httpd-2.4.64/docs/manual/howto/htaccess.html��������������������������������������������������������0000664�0001751�0001751�00000001070�13710016232�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: htaccess.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: htaccess.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: htaccess.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: htaccess.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    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
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/howto/reverse_proxy.html���������������������������������������������������0000664�0001751�0001751�00000000331�13710016232�021761� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: reverse_proxy.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: reverse_proxy.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/expr.html������������������������������������������������������������������0000664�0001751�0001751�00000000307�13710016232�016666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: expr.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: expr.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dso.html.ja.utf8�����������������������������������������������������������0000664�0001751�0001751�00000056436�14743132254�020003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>動的共有オブジェクト (DSO) サポート - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>動的共有オブジェクト (DSO) サポート</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>Apache HTTP サーバはモジュール化されたプログラムで、
        管理者がモジュールを選択することでサーバに組み込む機能を選ぶことができます。
        モジュールはサーバがビルドされるときに <code class="program"><a href="./programs/httpd.html">httpd</a></code> バイナリに
        静的に組み込むことができます。もしくは、<code class="program"><a href="./programs/httpd.html">httpd</a></code> バイナリとは
        別に存在する動的共有オブジェクト (訳注: Dynamic Shared Object)
        (DSO) としてコンパイルすることも
        できます。DSO モジュールはサーバがビルドされるときにコンパイルしたり、
        Apache 拡張ツール (<code class="program"><a href="./programs/apxs.html">apxs</a></code>) を
        使って後でコンパイルして追加したりできます。</p>
    
        <p>この文書は DSO モジュールの使い方と、仕組みについて
        説明します。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#implementation">実装</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">使用法の概要</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#background">背景</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#advantages">利点と欠点</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">実装</a></h2>
    
    <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>個々の Apache モジュールをロードするための DSO サポートは
        <code class="module"><a href="./mod/mod_so.c.html">mod_so.c</a></code> というモジュールの機能に基づいています。
        このモジュール は Apache のコアに静的に組み込まれている必要があります。
        それは <code class="module"><a href="./mod/core.c.html">core.c</a></code> 以外では DSO にできない唯一の
        モジュールです。事実上、他のすべての Apache のモジュールは、
        <a href="install.html">インストールの文書</a>で説明されているように、
        <code class="program"><a href="./programs/configure.html">configure</a></code> の
        <code>--enable-<em>module</em>=shared</code> オプションでそれぞれを
        DSO ビルドにすることにより、DSO モジュールにすることができます。
        <code>mod_foo.so</code> のような DSO にモジュールがコンパイルされれば、
        <code>httpd.conf</code> ファイル中で <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> の
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        ディレクティブを使うことでサーバの起動や再起動時にこのモジュールを
        ロードするようにできます。</p>
    
        <p>Apache モジュール用の (特にサードパーティモジュールの) DSO ファイルの
        作成を簡単にするために、<code class="program"><a href="./programs/apxs.html">apxs</a></code>
        (<dfn>APache eXtenSion</dfn>) という新しいサポートプログラムがあります。
        Apache のソースツリーの<em>外で</em> DSO モジュールをビルドするために
        使うことができます。発想は単純です: Apache のインストール時の
        <code class="program"><a href="./programs/configure.html">configure</a></code>、<code>make install</code> のときに Apache の
        C ヘッダをインストールし、DSO ビルド用のプラットフォーム依存の
        コンパイラとリンカのフラグを <code class="program"><a href="./programs/apxs.html">apxs</a></code> プログラムに追加します。
        これにより、ユーザが Apache の配布ソースツリーなしで、さらに
        DSO サポートのためのプラットフォーム依存のコンパイラやリンカの
        フラグをいじることなく Apache のモジュールのソースをコンパイル
        できるようになります。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">使用法の概要</a></h2>
    
        <p>Apache 2.x の DSO 機能の概略を知ることができるための、
        短く簡潔な概要です:</p>
    
        <ol>
          <li>
            <em>配布されている</em> Apache モジュール、仮に <code>mod_foo.c</code>
            として、それを DSO <code>mod_foo.so</code> にビルド、インストール: 
    
    <div class="example"><p><code>
    $ ./configure --prefix=/path/to/install --enable-foo=shared<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
            <em>サードパーティ</em> Apache モジュール、仮に <code>mod_foo.c</code>
            として、それを DSO <code>mod_foo.so</code> にビルド、インストール:
    
    <div class="example"><p><code>
    $ ./configure --add-module=<var>module_type</var>:/path/to/3rdparty/mod_foo.c \<br />
    <span class="indent">
      --enable-foo=shared<br />
    </span>
    $ make install
    </code></p></div>
          </li>
    
          <li>
            共有モジュールの <em>後々のインストール</em> のために
            Apache を設定:
    
    <div class="example"><p><code>
    $ ./configure --enable-so<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
            <em>サードパーティ</em> Apache モジュール、仮に <code>mod_foo.c</code>
            として、それを <code class="program"><a href="./programs/apxs.html">apxs</a></code> を使って
            Apache ソースツリーの<em>外で</em> DSO にビルド、インストール:
    
    <div class="example"><p><code>
    $ cd /path/to/3rdparty<br />
    $ apxs -c mod_foo.c<br />
    $ apxs -i -a -n foo mod_foo.la
    </code></p></div>
          </li>
        </ol>
    
        <p>どの場合においても、共有モジュールをコンパイルした後で、
        <code>httpd.conf</code> で 
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        ディレクティブを使って Apache がモジュールを使用するように
        しなければなりません。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="background" id="background">背景</a></h2>
    
        <p>最近の Unix 系の OS には <em>動的共有オブジェクト</em> (DSO)
        の動的リンク/ロードという気のきいた機構が
        存在します。これは、実行時にプログラムのアドレス空間に
        ロードできるような特別な形式でプログラムをビルドすることを
        可能にします。</p>
    
        <p>このロードは二つの方法で行なうことができます: 実行プログラムが
        起動されたときに <code>ld.so</code> というシステムプログラム
        により自動的に行なわれる方法と、実行プログラム中から、システムコール
        <code>dlopen()/dlsym()</code> による Unix ローダへの
        プログラムシステムのインタフェースを使って手動で行なう方法とが
        あります。</p>
    
        <p>最初の方法では DSO は普通は<em>共有ライブラリ</em>や <em>DSO
        ライブラリ</em> と呼ばれていて、DSO の名前は
        <code>libfoo.so</code> や <code>libfoo.so.1.2</code> のようになっています。
        これらはシステムディレクトリ (通常 <code>/usr/lib</code>) に存在し、
        実行プログラムへのリンクはビルド時に <code>-lfoo</code> をリンカに
        指定することで確立されます。これによりライブラリへの参照が実行プログラムの
        ファイルに書き込まれて、起動時に Unix のローダが <code>/usr/lib</code> や、
        リンカの <code>-R</code> のようなオプションによりハードコードされたパス、
        環境変数 <code>LD_LIBRARY_PATH</code> により設定されたパス、の中から
        <code>libfoo.so</code> の場所を見つけることができます。それから、
        実行プログラム中の (まだ未解決の) シンボルを DSO にあるシンボルで
        解決します。</p>
    
        <p>普通は実行プログラム中のシンボルは DSO からは参照されません
        (DSO は一般的なコードによる再利用可能なライブラリですので)。
        ですから、さらなるシンボルの解決は必要ありません。
        シンボルは Unix ローダにより完全な解決が行なわれますので、実行ファイル自身は
        何もする必要がありません。(実際のところ、静的でない方法でリンクされている
        すべての実行プログラムに組み込まれている開始用のコードの一部に
        <code>ld.so</code> を起動するコードが含まれています)。よく使われる
        ライブラリの動的ロードの利点は明らかです。ライブラリのコードは
        システムライブラリに <code>libc.so</code> のようにして一度保存するだけでよく、
        プログラムのために必要なディスクの領域を節約することができます。</p>
    
        <p>二つめの方法では DSO は普通は<em>共有オブジェクト</em>や
        <em>DSO ファイル</em>と呼ばれていて、任意の拡張子を付けることができます
        (ただし、標準的な名前は <code>foo.so</code> です)。
        これらのファイルは通常はプログラム専用のディレクトリに置かれ、
        これらを使う実行プログラムへのリンクは自動的にはされません。
        ですので、実行プログラムは <code>dlopen()</code> を使って
        実行時に手動で DSO をプログラムのアドレス空間にロードする必要があります。
        この時点では実行プログラムに対して DSO のシンボルの解決は行なわれません。
        しかし、その代わりに Unix のローダが DSO の (まだ未解決の) シンボルを
        実行プログラムによりエクスポートされたシンボルと既にロードされた
        DSO ライブラリによりエクスポートされたシンボル (特に、どこにでもある
        <code>libc.so</code> のすべてのシンボル) で自動的に解決します。
        こうすることで、DSO は最初から静的にリンクされていたかのように、
        実行プログラムのシンボルを知ることができます。</p>
    
        <p>最後に、DSO の API を利点を生かすために、プログラムは
        後でディスパッチテーブル<em>など</em>でシンボルを使うことができるように、
        <code>dlsym()</code> を使っていくつかのシンボルを解決します。
        すなわち: 実行プログラムは必要なすべてのシンボルを手動で解決しなければ
        なりません。この機構の利点はプログラムのオプショナルな部分は
        必要になるまでロードする必要がない (だからメモリも消費しない)
        ことです。必要ならば、基本プログラムの機能を拡張するために
        これらの部分を動的にロードすることができます。</p>
    
        <p>この DSO 機構は簡単なように見えますが、少なくとも一つ難しい点が
        あります: プログラムを拡張するために DSO を使っているときに、
        DSO が実行プログラムからシンボルを解決する点です (二番目の方法)。
        これはなぜでしょうか。それは、DSO のシンボルを実行プログラムの
        シンボルから「逆解決」するというのはライブラリの設計
        (ライブラリはそれを使用するプログラムのことは何も
        知らない) に反していて、この機能はすべてのプラットフォームに
        あるわけではなく、標準化もされていないからです。
        実際には実行プログラムのグローバルなシンボルは再エクスポートされることは
        あまりなく、DSO から使うことができません。リンカにグローバルシンボルすべてを
        エクスポートするようにさせる方法を見つけることが、実行時にプログラムを
        拡張するために DSO を使うときの一番の問題です。</p>
    
        <p>共有ライブラリのアプローチが普通の方法です。DSO 機構はそのために
        設計されたものですから。したがって、その方法はオペレーティングシステムが
        提供するほとんどすべての種類のライブラリで使われています。
        一方、プログラムの拡張のために共有オブジェクトを使用する、という方は
        あまり使われていません。</p>
    
        <p>1998 年の時点で、実行時に実際に機能拡張のために DSO 機構を使っている
        ソフトウェアパッケージは少しだけでした: Perl 5 (XS 機構と DnaLoader モジュール
        によるもの)、Netscape サーバ<em>など</em>です。Apache はすでに
        モジュールの概念を使って機能拡張をしていて、内部的にディスパッチリストに
        基づいた外部モジュールの Apache コア機能へのリンクを行なっていましたので、
        バージョン 1.3 から、Apache も DSO 機構を使う仲間になりました。
        Apache は実行時に DSO を使ってモジュールをロードするようにすでに
        運命付けられていたのです。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advantages" id="advantages">利点と欠点</a></h2>
    
        <p>上記の DSO に基づいた機能は以下の利点があります:</p>
    
        <ul>
          <li>実際のサーバプロセスを組み立てるために、
          ビルド時に <code>configure</code> のオプションを使う代わりに
          実行時に <code>httpd.conf</code> の設定用コマンド
          <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
          を使うことができますので、サーバパッケージの柔軟性が高まりました。
          たとえば、一つの Apache のインストールから
          違う構成のサーバ (標準版と SSL 版、最小構成と拡張版 [mod_perl, PHP3]
          <em>など</em>) を実行することができます。</li>
    
          <li>インストールの後であっても、サーバのパッケージをサードパーティ
          モジュールで簡単に拡張できるようになりました。これは、Apache コア
          パッケージと、PHP3, mod_perl, mod_fastcgi <em>など</em> の追加の
          パッケージを作成できるので、少なくともベンダのパッケージ管理者にとって
          大きな利点があります。</li>
    
          <li>Apache モジュールの開発が簡単になります。
          これは DSO と <code class="program"><a href="./programs/apxs.html">apxs</a></code> の組み合わせにより、Apache ソースツリーの
          外で作業でき、開発中のモジュールの新しいバージョンを
          実行中の Apache サーバに組み込むために <code>apxs -i</code> と
          <code>apachectl restart</code> を行なうだけで良くなるからです。</li>
        </ul>
    
        <p>DSO には以下の欠点があります:</p>
    
        <ul>
          <li>すべてのオペレーティングシステムがプログラムのアドレス空間に
          コードを動的ロードすることをサポートしているわではないので、
          プラットフォームによっては DSO 機構は使えません。</li>
    
          <li>Unix のローダがシンボルの解決をする必要ができたので、
          そのオーバヘッドによりサーバの起動時間が約 20% 遅くなっています。</li>
    
          <li>位置非依存コード (PIC) (訳注 position independent code) は
          相対アドレスのために複雑なアセンブラのトリックが必要なことがあり、
          それは必ずしも絶対アドレスと同じくらいの速度がでるわけではありませんので、
          プラットフォームによってはサーバの実行速度が約 5% 遅くなります。</li>
    
          <li>DSO モジュールはすべてのプラットフォームで他の DSO に基づいた
          ライブラリに対してリンクできる (<code>ld -lfoo</code>)
          というわけではありませんので (たとえば、a.out のプラットフォームでは
          この機能はありませんが、ELF のプラットフォームにはあります)、
          すべての種類のモジュールに DSO 機構を使えるわけではありません。
          言い換えると、DSO ファイルとしてコンパイルされたモジュールの
          使えるシンボルは、
          Apache のコアのシンボル、C ライブラリ (<code>libc</code>) と
          Apache コアが使っている他のすべての静的なライブラリと動的ライブラリの
          シンボル、PIC による静的なライブラリ (<code>libfoo.a</code>) の
          シンボルのみに制限されます。その他のコードを使う方法は、
          Apache コア自身がすでにそのコードへの参照があるようにするか、
          <code>dlopen ()</code> を使ってコードを自分自身でロードするかの
         どちらかしかありません。</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dso.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dns-caveats.html.tr.utf8���������������������������������������������������0000664�0001751�0001751�00000031454�14743132254�021452� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Sunucusu ve DNS ile ilgili Konular - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Sunucusu ve DNS ile ilgili Konular</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu sayfanın konusu şöyle özetlenebilirdi: Yapılandırma dosyalarınızda
          DNS sorguları yapılmasını gerektirecek ayarlamalardan kaçınınız. Eğer
          yapılandırma dosyalarınızda DNS sorgusu yapılarak çözümlenebilecek
          adresler bulunursa sunucunuz beklenmedik davranışlar (hiç
          başlamayabilir) gösterebileceği gibi hizmet reddi veya hizmet
          hırsızlığı (bazı sanal konakların diğerlerine giden sayfaları çalma
          olasılığı dahil) saldırılarına açık hale gelebilir.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#example">Basit Bir Örnek</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#denial">Hizmet Reddi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#main">"Ana Sunucu" Adresi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#tips">Bu Sorunlardan Kaçınmak için İpuçları</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="example" id="example">Basit Bir Örnek</a></h2>
        
    
        <pre class="prettyprint lang-config"># Bu yetersiz bir yapılandırma örneğidir, sunucunuzda kullanmayın.
    &lt;VirtualHost falan.fesmekan.dom&gt;
      ServerAdmin filanca@fesmekan.dom
      DocumentRoot "/siteler/fesmekan"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>httpd’nin beklendiği gibi işlemesi için her sanal konak için iki
          veriye mutlaka ihtiyacı vardır: <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> ve sunucunun bağlantı kabul edip hizmet
          sunacağı en az bir IP adresi. Yukarıdaki örnekte IP adresi
          bulunmamaktadır, dolayısıyla Apache, <code>falan.fesmekan.dom</code>
          adresi için bir DNS sorgusu yapmak zorundadır. Eğer sunucu,
          yapılandırma dosyasını çözümlediği sırada bir sebeple DNS sunucusuna
          erişemezse bu sanal konak <em>yapılandırılmayacak</em> ve bu sanal konağa
          yapılan isteklere yanıt verilemeyecektir.</p>
    
        <p><code>falan.fesmekan.dom</code>’un 192.168.2.1 IP adresine sahip
          olduğunu varsayarsak yapılandırma şöyle olurdu:</p>
    
        <pre class="prettyprint lang-config"># Bu yetersiz bir yapılandırma örneğidir, sunucunuzda kullanmayın.
    &lt;VirtualHost 192.168.2.1&gt;
      ServerAdmin filanca@fesmekan.dom
      DocumentRoot "/siteler/fesmekan"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Ancak, bu sefer de bu sanal konağın sunucu ismini öğrenmek için
          httpd’nin bir ters DNS sorgusu yapması gerekecektir. Eğer bu sorgu
          başarısız olursa kısmi bir yapılandırmaya gidilir.
          Eğer sanal konak isme dayalı ise sanal konak
          kısmen bile yapılandırılmaz. IP’ye dayalı sanal konaklar büyük oranda
          çalışır, fakat (örneğin, bir Redirect varlığında olduğu gibi) sunucu ismini
          içeren tam bir adres üretilmesini gerektiren bir durumda, sunucu geçerli
          bir adres üretemez.</p>
    
        <p>Her iki sorunu da çözen yapılandırma şöyle olurdu:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 192.168.2.1&gt;
      ServerName falan.fesmekan.dom
      ServerAdmin filanca@fesmekan.dom
      DocumentRoot "/siteler/fesmekan"
    &lt;/VirtualHost&gt;</pre>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="denial" id="denial">Hizmet Reddi</a></h2>
        
    
        <p>Şöyle bir yapılandırmanız olsun:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost falan.fesmekan.dom&gt;
      ServerAdmin filanca@fesmekan.dom
      DocumentRoot "/siteler/fesmekan"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost misal.mesela.dom&gt;
      ServerAdmin falanca@mesela.dom
      DocumentRoot "/siteler/mesela"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p><code>falan.fesmekan.dom</code>’a 192.168.2.1,
          <code>misal.mesela.dom</code>’a 192.168.2.2 atadığınızı fakat,
          <code>mesela.dom</code>’un DNS kaydının sizin denetiminizde olmadığını
          varsayalım. Bu yapılandırmayla, <code>mesela.dom</code>’u
          <code>fesmekan.dom</code>’a giden tüm trafiği çalabilecek duruma
          getirirsiniz. Bunu gerçekleştirmek için DNS kaydında
          <code>misal.mesela.dom</code>’a 192.168.2.1 adresinin atanması
          yeterlidir. Kendi DNS’lerine sahip olduklarından dolayı
          <code>misal.mesela.dom</code>’a istedikleri IP adresini atamaktan
          onları alıkoyamazsınız.</p>
    
        <p>192.168.2.1’e gelen isteklerin hepsine
          (<code>http://falan.fesmekan.dom/biryer</code> şeklinde yazılan
          adresler dahil) <code>mesela.dom</code> sanal konağınca hizmet
          sunulacaktır. Apache’nin gelen istekleri sunduğu sanal konaklarla nasıl
          eşleştirdiğini bilirseniz bunun sebebini kolayca anlarsınız. Bunu
          kabataslak açıklayan  <a href="vhosts/details.html">bir belgemiz
          mevcuttur</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">"Ana Sunucu" Adresi</a></h2>
        
    
        <p><a href="vhosts/name-based.html">İsme dayalı sanal konak
          desteği</a>, httpd’nin çalıştığı makinenin IP adres(ler)ini de bilmesini
          gerektirir. Bu adresi elde etmek için sunucu, ya sunucu genelinde geçerli
          <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> yönergesine bakar ya da bir
          C işlevi olan <code>gethostname</code>’i kullanır (işlev, komut
          isteminden <code>hostname</code> komutuna dönen yanıtın aynısını
          döndürür) ve ardından bu adresle ilgili olarak bir DNS sorgusu yapar.
          Bu sorgudan kaçınmanın henüz bir yolu yoktur.</p>
    
        <p>Eğer bu sorgunun (DNS sunucusunun çökmüş olması gibi bir nedenle)
          başarısız olabileceğinden korkuyorsanız, makine ismini ve IP adresini
          <code>/etc/hosts</code> dosyanıza yazabilirsiniz (Makinenizin düzgün
          olarak açılabilmesi için zaten bu kaydı yapmış olmanız gerekir).
          Kullandığınız işletim sistemine bağlı olarak bu kaydın
          <code>/etc/resolv.conf</code> veya <code>/etc/nsswitch.conf</code>
          dosyasında bulunması gerekebilir.</p>
    
        <p>Herhangi bir nedenle sunucunuz bir DNS sorgusu yapmıyorsa veya
          yapmamalıysa, httpd’yi <code>HOSTRESORDER</code> ortam değişkenine
          "<code>local</code>" değerini atadıktan sonra çalıştırabilirsiniz. Bu
          tamamen işletim sistemine ve kullandığınız çözümleyici kütüphanelere
          bağlıdır. Ayrıca, ortamı denetlemek için <code class="module"><a href="./mod/mod_env.html">mod_env</a></code>
          kullanmıyorsanız, CGI’ler de bundan etkilenir. En iyisi işletim
          sisteminizin SSS belgelerini ve kılavuz sayfalarını okumaktır.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">Bu Sorunlardan Kaçınmak için İpuçları</a></h2>
        
    
        <ul>
          <li><code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> yönergelerinizde
            IP adresleri kullanınız.</li>
    
          <li><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergelerinizde
            IP adresleri kullanınız.</li>
    
          <li>Tüm sanal konakların ayrı birer <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> yönergesi olsun.</li>
    
          <li>Hiçbir sayfa sunulmayan bir <code>&lt;VirtualHost
            _default_:*&gt;</code> sanal konağınız olsun.</li>
        </ul>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dns-caveats.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/env.html.ko.euc-kr���������������������������������������������������������0000664�0001751�0001751�00000054221�14743132254�020313� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ ȯ溯 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ġ ȯ溯</h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>ġ  <em>ȯ溯(environment variable)</em>
            ִ.   Ͽ α׳
           ۾ Ѵ. , ȯ溯 CGI ũƮ
         ܺ α׷ ϴ  ȴ.   ȯ溯
        ٷ ϴ پ  Ѵ.</p>
    
        <p>  <em>ȯ溯</em> θ, ü
        ϴ ȯ溯 ٸ.   ġ ο ǰ
        ȴ. ȯ溯 CGI ũƮ Server Side Include
        ũƮ Ѱ  ü ȯ溯 ȴ. 
        ϴ ü ȯ ϰ ʹٸ ü 
        ȯ ؾ Ѵ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#setting">ȯ溯 ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">ȯ溯 ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#special">Ư  ȯ溯</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setting" id="setting">ȯ溯 ϱ</a></h2>
        
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_env.html">mod_env</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li><li><code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifnocase">SetEnvIfNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#unsetenv">UnsetEnv</a></code></li></ul></td></tr></table>
    
        <h3><a name="basic-manipulation" id="basic-manipulation">⺻ ȯ漳</a></h3>
            
    
            <p>ġ ȯ溯 ϴ  ⺻ 
             <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> þ ϴ ̴. <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> þ Ͽ
               ȯ溯   ִ.</p>
    
        
        <h3><a name="conditional" id="conditional">û  Ǻ </a></h3>
            
    
            <p> ϰ, mod_setenvif ϴ þ û
            û Ư¡  ȯ溯 Ѵ.  , Ư
             (User-Agent) ûϰų Ư Referer (
            Ʋ ʾҴ)  ִ 쿡   
            ִ.  mod_rewrite ִ <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
            <code>[E=...]</code> ɼ Ͽ  ϰ ȯ溯
              ִ.</p>
    
        
        <h3><a name="unique-identifiers" id="unique-identifiers"> ĺ</a></h3>
            
    
            <p> mod_unique_id  û   쿡
            "" û߿ Ȯ (ġ) 
            <code>UNIQUE_ID</code> ȯ溯 Ѵ.</p>
    
        
        <h3><a name="standard-cgi" id="standard-cgi">ǥ CGI </a></h3>
            
    
            <p>CGI ũƮ SSI  ġ  Ͽų
              ȯ溯 ܿ ߰ <a href="http://cgi-spec.golux.com/">CGI Ծ</a> 
            û   ˷ִ ȯ溯 ޴´.</p>
    
        
        <h3><a name="caveats" id="caveats"> </a></h3>
            
    
            <ul>
              <li>ȯ漳 þ Ͽ ǥ CGI  ϰų
                .</li>
    
              <li><a href="suexec.html">suexec</a> CGI ũƮ
              ϴ , ϱ CGI ũƮ ȯ
              <em></em> 鸸  ûҵȴ.
              <em></em>   Ͻ
              <code>suexec.c</code> ǵȴ.</li>
    
              <li>  ȯ溯 ̸  , ,
              ٹڸ ϴ  . , ù° ڷ
              ڸ ʴ  . CGI ũƮ SSI
               Ѿ ̿ ڴ ٷ üȴ.</li>
            </ul>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">ȯ溯 ϱ</a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authz_host.html#allow">Allow</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_authz_host.html#deny">Deny</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li></ul></td></tr></table>
    
        <h3><a name="cgi-scripts" id="cgi-scripts">CGI ũƮ</a></h3>
            
    
            <p>ȯ溯 ֵ 뵵 ϳ CGI ũƮ 
            ȯϴ ̴. տ ߵ ġ  
            ܿ û  ǥ    CGI ũƮ
            Ѿ.  ڼ  <a href="howto/cgi.html">CGI
            丮</a> ϶.</p>
    
        
        <h3><a name="ssi-pages" id="ssi-pages">SSI </a></h3>
            
    
            <p>mod_include <code>INCLUDES</code> Ͱ óϴ
            Ľ (SSI)  <code>echo</code> Ҹ Ͽ
            ȯ溯   ְ, ȯ溯 Ͽ û
            Ư¡  帧 ҷ  Ϻθ  
            ִ. ġ  SSI    ǥ CGI
            ȯ溯 Ѵ.  ڼ  <a href="howto/ssi.html">SSI 丮</a> ϶.</p>
    
        
        <h3><a name="access-control" id="access-control"></a></h3>
            
    
            <p><code>allow from env=</code> <code>deny from env=</code>
            þ Ͽ ȯ溯    
              ִ. <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>  ϸ
            Ŭ̾Ʈ Ư¡  Ӱ   
             ִ.  , Ư  (User-Agent) 
            ź  ִ.</p>
    
        
        <h3><a name="logging" id="logging">Ǻ α</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>
            <code>%e</code> ɼ Ͽ ȯ溯  α׿
              ִ. , <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> þ
            Ǻ  ϸ ȯ溯 Ȳ  û
            α θ   ִ. <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>  Ͽ
             û α Ӱ   ִ.  ,
            ϸ <code>gif</code>  û α ʰų,
            ܺ Ʈ ִ Ŭ̾Ʈ û α  ִ.</p>
    
        
        <h3><a name="response-headers" id="response-headers">Ǻ  </a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code>
            þ Ŭ̾Ʈ   ȯ溯 
              HTTP     ִ. 
            , Ŭ̾Ʈ û Ư  ִ 쿡
                 ִ.</p>
    
        
    
        <h3><a name="external-filter" id="external-filter">ܺ  ϱ</a></h3>
            
    
            <p><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> <code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code>
            þ  ܺ ͸ <code>disableenv=</code>
            <code>enableenv=</code> ɼ Ͽ ȯ溯 
               ִ.</p>
        
    
        <h3><a name="url-rewriting" id="url-rewriting">URL ۼ(Rewriting)</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
            <em>TestString</em> <code>%{ENV:...}</code> 
            ϸ mod_rewrite ۼ  ȯ溯 
            ٸ ൿѴ. mod_rewrite տ <code>ENV:</code>
            ʰ ϴ   ȯ溯 ƴ ϶.
            ׵ ٸ ⿡    mod_rewrite 
            .</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="special" id="special">Ư  ȯ溯</a></h2>
        
    
            <p>Ŭ̾Ʈ Ȱ ϱ ġ Ư
            Ŭ̾Ʈ  ڽ ൿ Ѵ.  <code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code>
            ȯ溯 Ͽ ̷  ذѴ. ׷ <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code>ε ϴ.</p>
    
        <h3><a name="downgrade" id="downgrade">downgrade-1.0</a></h3>
            
    
            <p>û   ϴ HTTP/1.0 û
            óѴ.</p>
    
        
        <h3><a name="force-gzip" id="force-gzip">force-gzip</a></h3>
            
              <p><code>DEFLATE</code> ͸ Ҷ  ȯ溯
               accept-encoding  ϰ 
                .</p>
        
        <h3><a name="force-no-vary" id="force-no-vary">force-no-vary</a></h3>
            
    
            <p> Ŭ̾Ʈ    
            <code>Vary</code> ʵ带 .  Ŭ̾Ʈ 
            ʵ带  ؼ Ѵ.   ̷ 
            ذѴ. ,  
            <strong>force-response-1.0</strong> Ѵ.</p>
    
        
        <h3><a name="force-response" id="force-response">force-response-1.0</a></h3>
            
    
            <p>HTTP/1.0 û ϴ Ŭ̾Ʈ HTTP/1.0 
            Ѵ.  AOL Ͻÿ  ־ .
             HTTP/1.0 Ŭ̾Ʈ HTTP/1.1   
             Ƿ,   ذϱ Ѵ.</p>
        
    
        <h3><a name="gzip-only-text-html" id="gzip-only-text-html">gzip-only-text/html</a></h3>
            
    
          <p> "1"̸ <code>text/html</code> ƴ content-type
           <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> DEFLATE ͸
           ʴ´. (gzip Ӹ ƴ϶ "identity" ƴ 
          ڵ)    쿡
          <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>   Ѵ.</p>
        
    
        <h3><a name="no-gzip" id="no-gzip">no-gzip</a></h3>
    
            <p> ɼ ϸ <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code>
            <code>DEFLATE</code> ͸  ʰ,
            <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> ڵ ڿ
             ʴ´.</p>
    
        
    
        <h3><a name="nokeepalive" id="nokeepalive">nokeepalive</a></h3>
            
    
            <p><code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code>
            Ѵ.</p>
    
        
    
        <h3><a name="prefer-language" id="prefer-language">prefer-language</a></h3>
    
            <p>  <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> ൿ
             ģ.  (<code>en</code>, <code>ja</code>,
            <code>x-klingon</code> ) ±׸ ִٸ,
            <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>    
             õѴ. ׷  ٸ Ϲ <a href="content-negotiation.html"></a>  Ѵ.</p>
    
        
    
        <h3><a name="redirect-carefully" id="redirect-carefully">redirect-carefully</a></h3>
            
    
            <p>   Ŭ̾Ʈ ̷ .
             ̷ óϴµ  ִ Ŭ̾Ʈ
             Ѵ.  Microsoft WebFolders Ʈ
            DAV ޽带  丮 ڿ ̷ óϴµ
             ־ .</p>
    
        
    
       <h3><a name="suppress-error-charset" id="suppress-error-charset">suppress-error-charset</a></h3>
           
    
        <p><em>2.0.40   ִ</em></p>
    
        <p>ġ Ŭ̾Ʈ û   ̷
         Ŭ̾Ʈ ڵ ̷  ϴ(Ȥ
        ʴ) 쿡 Ͽ 信 ڿ   Ѵ.
        ġ    ġ ϴ  ISO-8859-1
        ǥѴ.</p>
        <p>׷ ̷ǵ  ٸ   
         ̻     ƴ϶ ̷
          Ϸ Ѵ.  , ׸
        ̻ϰ   ִ.</p>
        <p> ȯ溯 ġ ̷  
        ʵ Ͽ, ̷    
        ùٷ ϰ .</p>
    
       
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples"></a></h2>
        
    
        <h3><a name="misbehaving" id="misbehaving">߸ ϴ Ŭ̾Ʈ   ൿ
            ϱ</a></h3>
            
    
            <p>Ŭ̾Ʈ ̹ ˷  ذϱ
            httpd.conf   ϱ ٶ.</p>
    <div class="example"><pre>#
    #  þ Ϲ 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</pre></div>
    
        
        <h3><a name="no-img-log" id="no-img-log"> α׿ ̹  û α ʱ</a></h3>
            
    
            <p>  ̹  û  α׿ 
            ʴ´. Ư 丮  Ȥ Ư ȣƮ 
            û α ʵ    ִ.</p>
        <div class="example"><pre>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</pre></div>
    
        
        <h3><a name="image-theft" id="image-theft">"̹ " </a></h3>
            
    
            <p>    ڰ   ִ
            ̹  ϵ ϴ  Ѵ. 
              , ѵ 쿡 Ѵ.
            츮  ̹ /web/images 丮 ȿ ִٰ
            Ѵ.</p>
        <div class="example"><pre>SetEnvIf Referer "^http://www.example.com/" local_referal
    # Referer   ʴ  Ѵ
    SetEnvIf Referer "^$" local_referal
    &lt;Directory /web/images&gt;
       Order Deny,Allow
       Deny from all
       Allow from env=local_referal
    &lt;/Directory&gt;</pre></div>
    
            <p>   ڼ  ApacheToday 丮 "<a href="http://apachetoday.com/news_story.php3?ltsn=2000-06-14-002-01-PS">
        Keeping Your Images from Adorning Other Sites</a>" ϶.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/env.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/env.html�������������������������������������������������������������������0000664�0001751�0001751�00000000701�13710016232�016476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: env.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: env.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: env.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: env.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: env.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������httpd-2.4.64/docs/manual/dns-caveats.html.ko.euc-kr�������������������������������������������������0000664�0001751�0001751�00000032741�14743132254�021736� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>DNS ġ õ  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>DNS ġ õ </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>      ִ. ġ 
         DNS ʵ ϶. ġ  дµ
        DNS ʿϴٸ  ŷڼ  ( ȵ  ִ)
        Ȥ 񽺰ź ݰ (ڰ ٸ ڿ  
        ä  Ͽ) 񽺵(theft of service) ݿ
        ô޸  ִ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#example"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#denial">񽺰ź (Denial of Service)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#main">"ּ" ּ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#tips">  ϱ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#appendix">η: δ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="example" id="example"> </a></h2>
        
    
        <div class="example"><p><code>
          &lt;VirtualHost www.abc.dom&gt; <br />
          ServerAdmin webgirl@abc.dom <br />
          DocumentRoot /www/abc <br />
          &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>ġ  ϱؼ  ȣƮ
         ΰ   ʿϴ.  
        <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> 
        ٸ  ּ Ѱ IP ̴ּ.   IP ּҰ
        ⶧, ġ DNS Ͽ <code>www.abc.dom</code>
        ּҸ ãƾ Ѵ.     
        DNS   ٸ ȣƮ <strong>  </strong>.
         ȣƮ û   . (ġ 1.2 
           õ Ѵ.)</p>
    
        <p><code>www.abc.dom</code> ּҰ 192.0.2.1̶ .
        ׸   :</p>
    
        <div class="example"><p><code>
          &lt;VirtualHost 192.0.2.1&gt; <br />
          ServerAdmin webgirl@abc.dom <br />
          DocumentRoot /www/abc <br />
          &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p> ġ  ȣƮ <code>ServerName</code>
        ã DNS ؾ Ѵ. ãⰡ ϸ ġ
        ȣƮ κ . (ġ 1.2  
          õ Ѵ.) ,   ̸
        ȣƮ ȣƮ  ʰ, ip̶
        κ Ѵ. ׷ ġ  Ͽ 
        ü URL  Ѵٸ  URL  Ѵ.</p>
    
        <p>Ʒ   ΰ  .</p>
    
        <div class="example"><p><code>
          &lt;VirtualHost 192.0.2.1&gt; <br />
          ServerName www.abc.dom <br />
          ServerAdmin webgirl@abc.dom <br />
          DocumentRoot /www/abc <br />
          &lt;/VirtualHost&gt;
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="denial" id="denial">񽺰ź (Denial of Service)</a></h2>
        
    
        <p>(ּ) ΰ  񽺰źΰ ߻  ִ.
        ġ 1.2     ȣƮ
           DNS ˻ ϸ   ʴ´.
        DNS      ִ.  ,
        <code>abc.dom</code>  Ʈ̰  ڽ DNS
        Ѵٸ, <code>www.abc.dom</code> ڵ带 ⸸ ص
        (1.2 )   Ѵ.</p>
    
        <p>ξ  Ȱ  ִ.   캸:</p>
    
        <div class="example"><p><code>
          &lt;VirtualHost www.abc.dom&gt; <br />
          &nbsp;&nbsp;ServerAdmin webgirl@abc.dom <br />
          &nbsp;&nbsp;DocumentRoot /www/abc <br />
          &lt;/VirtualHost&gt; <br />
          <br />
          &lt;VirtualHost www.def.dom&gt; <br />
          &nbsp;&nbsp;ServerAdmin webguy@def.dom <br />
          &nbsp;&nbsp;DocumentRoot /www/def <br />
          &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p> <code>www.abc.dom</code> 192.0.2.1,
        <code>www.def.dom</code> 192.0.2.2 Ҵߴٰ .
        , <code>def.dom</code> ü DNS Ѵٰ .
          Բ <code>def.dom</code> <code>abc.dom</code>
           ç  ִ ҿ ξ. ׷ٸ ׵
        <code>www.def.dom</code> 192.0.2.1 ϱ⸸ ϸ ȴ.
        ׵ ü DNS ϱ⶧  ׵ ϴµ
        <code>www.def.dom</code> ڵ带 ϴ   
        .</p>
    
        <p>(ڰ <code>http://www.abc.dom/whatever</code> 
        URL Էϴ 츦 Ͽ) 192.0.2.1   û
        <code>def.dom</code> ȣƮ ϰ ȴ.  ̷
         Ͼ Ϸ ġ  ȣƮ
         û óϴ   ʿϴ.
        <a href="vhosts/details.html"></a> 밭 ִ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">"ּ" ּ</a></h2>
        
    
        <p>ġ 1.1 <a href="vhosts/name-based.html"≯
        ȣƮ </a> ԵǾ⶧ ġ 
        ϴ ȣƮ IP ּ()  ʿ䰡 .  ּҴ
        (ִٸ)  <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
        Ȥ C Լ <code>gethostname</code> (Ʈ
        "hostname" Է  ) ´. ׷  ּҷ
        DNS ˻ Ѵ.   ˻   .</p>
    
        <p>DNS  ׾  ˻   ٸ
        <code>/etc/hosts</code> ȣƮ   ִ.
        (ǻͰ  õǾٸ Ƹ ̹  ̴.)
        ׸ DNS ϸ  <code>/etc/hosts</code>
        ϴ Ȯ϶. ϴ ü 
        <code>/etc/resolv.conf</code> Ȥ <code>/etc/nsswitch.conf</code>
        ϸ  ̴.</p>
    
        <p>   DNS ˻ϸ ȵȴٸ
        <code>HOSTRESORDER</code> ȯ溯 "local" ϰ
        ġ   ִ. <code class="module"><a href="./mod/mod_env.html">mod_env</a></code>
        Ͽ ȯ  ʴ´ٸ  ȯ溯
        CGI  ش. ü manpage FAQ ϴ
         .</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">  ϱ </a></h2>
        
    
        <ul>
          <li>
            <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> IP
            ּҸ ϶
          </li>
    
          <li>
            <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
            IP ּҸ ϶
          </li>
    
          <li>
             ȣƮ 
            <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
             ϶
          </li>
    
          <li>  ʴ
          <code>&lt;VirtualHost _default_:*&gt;</code> 
          </li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="appendix" id="appendix">η: δ</a></h2>
        
    
        <p>DNS õ Ȳ ſ ٶ ϴ. ġ 1.2
        츮 DNS  쿡 ּ   
         . · Ͽ  IP ּҸ 䱸ϴ
         ȣ ٽ ؾ  ͳݿ ſ ٶ
        ϴ.</p>
    
        <p>  񽺵   Ѱ  ˻
        IP ּҿ ٽ DNS ˻ Ͽ  ̸ ϴ ̴.
         ٸ  ȣƮ    ִ.  
        DNS ùٷ Ǿ Ѵ. (FTP  TCP wrapper
        "ߺ-" DNS ˻  ϱ⶧ κ ڿ
        ͼ ̴.)</p>
    
        <p>· IP ּҸ  DNS   ȣƮ
           ְ   .  Ϻθ ϴ
        Ͱ  κ ذå  ü ʴ ͺ
           ִ.</p>
    
        <p>HTTP/1.1 ԰  Ͻð <code>Host</code>
          Ƿ IP ȣƮ 
        ʴ   ̴. ׷  ߿
        DNS ˻  ʿ䰡 . ׷ 1997 3 ߿
           ̸ ȣƮ θ 
        ʾҴ.</p>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dns-caveats.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������httpd-2.4.64/docs/manual/expr.html.en���������������������������������������������������������������0000664�0001751�0001751�00000110155�14737241666�017317� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Expressions in Apache HTTP Server - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Expressions in Apache HTTP Server</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/expr.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/expr.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Historically, there are several syntax variants for expressions
        used to express a condition in the different modules of the Apache
        HTTP Server.  There is some ongoing effort to only use a single
        variant, called <em>ap_expr</em>, for all configuration directives.
        This document describes the <em>ap_expr</em> expression parser.
        </p>
        <p>The <em>ap_expr</em> expression is intended to replace most other
        expression variants in HTTPD. For example, the deprecated <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code> expressions can be replaced
        by <a href="mod/mod_authz_core.html#reqexpr">Require expr</a>.  </p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#grammar">Grammar in Backus-Naur Form notation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vars">Variables</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#binop">Binary operators</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#unnop">Unary operators</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#functions">Functions</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Example expressions</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Other</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#sslrequire">Comparison with SSLRequire</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compatibility">Version History</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#elseif">&lt;ElseIf&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="./mod/mod_auth_basic.html#authbasicfake">AuthBasicFake</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginrequiredlocation">AuthFormLoginRequiredLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginsuccesslocation">AuthFormLoginSuccessLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformlogoutlocation">AuthFormLogoutLocation</a></code></li><li><code class="directive"><a href="./mod/mod_authn_core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="./mod/mod_authn_core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifexpr">SetEnvIfExpr</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#requestheader">RequestHeader</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code></li><li><a href="mod/mod_authz_core.html#reqexpr">Require expr</a></li><li><a href="mod/mod_authnz_ldap.html#requser">Require ldap-user</a></li><li><a href="mod/mod_authnz_ldap.html#reqgroup">Require ldap-group</a></li><li><a href="mod/mod_authnz_ldap.html#reqdn">Require ldap-dn</a></li><li><a href="mod/mod_authnz_ldap.html#reqattribute">Require ldap-attribute</a></li><li><a href="mod/mod_authnz_ldap.html#reqfilter">Require ldap-filter</a></li><li><a href="mod/mod_authnz_ldap.html#reqsearch">Require ldap-search</a></li><li><a href="mod/mod_authz_dbd.html#reqgroup">Require dbd-group</a></li><li><a href="mod/mod_authz_dbm.html#reqgroup">Require dbm-group</a></li><li><a href="mod/mod_authz_groupfile.html#reqgroup">Require group</a></li><li><a href="mod/mod_authz_host.html#reqhost">Require host</a></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code></li><li><code class="directive"><a href="./mod/mod_log_debug.html#logmessage">LogMessage</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="grammar" id="grammar">Grammar in Backus-Naur Form notation</a></h2>
        
          <p><a href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form">Backus-Naur
          Form</a> (BNF) is a notation technique for context-free grammars,
          often used to describe the syntax of languages used in computing.
          In most cases, expressions are used to express boolean values.
          For these, the starting point in the BNF is <code>expr</code>.
          However, a few directives like <code class="directive"><a href="./mod/mod_log_debug.html#logmessage">LogMessage</a></code> accept expressions
          that evaluate to a string value. For those, the starting point in
          the BNF is <code>string</code>.
          </p>
    <blockquote>
    <pre>expr        ::= "<strong>true</strong>" | "<strong>false</strong>"
                  | "<strong>!</strong>" expr
                  | expr "<strong>&amp;&amp;</strong>" expr
                  | expr "<strong>||</strong>" expr
                  | "<strong>(</strong>" expr "<strong>)</strong>"
                  | comp
    
    comp        ::= stringcomp
                  | integercomp
                  | unaryop word
                  | word binaryop word
                  | word "<strong>in</strong>" "<strong>{</strong>" wordlist "<strong>}</strong>"
                  | word "<strong>in</strong>" listfunction
                  | word "<strong>=~</strong>" regex
                  | word "<strong>!~</strong>" regex
    
    
    stringcomp  ::= word "<strong>==</strong>" word
                  | word "<strong>!=</strong>" word
                  | word "<strong>&lt;</strong>"  word
                  | word "<strong>&lt;=</strong>" word
                  | word "<strong>&gt;</strong>"  word
                  | word "<strong>&gt;=</strong>" word
    
    integercomp ::= word "<strong>-eq</strong>" word | word "<strong>eq</strong>" word
                  | word "<strong>-ne</strong>" word | word "<strong>ne</strong>" word
                  | word "<strong>-lt</strong>" word | word "<strong>lt</strong>" word
                  | word "<strong>-le</strong>" word | word "<strong>le</strong>" word
                  | word "<strong>-gt</strong>" word | word "<strong>gt</strong>" word
                  | word "<strong>-ge</strong>" word | word "<strong>ge</strong>" word
    
    wordlist    ::= word
                  | wordlist "<strong>,</strong>" word
    
    word        ::= word "<strong>.</strong>" word
                  | digit
                  | "<strong>'</strong>" string "<strong>'</strong>"
                  | "<strong>"</strong>" string "<strong>"</strong>"
                  | variable
                  | rebackref
                  | function
    
    string      ::= stringpart
                  | string stringpart
    
    stringpart  ::= cstring
                  | variable
                  | rebackref
    
    cstring     ::= ...
    digit       ::= [0-9]+
    
    variable    ::= "<strong>%{</strong>" varname "<strong>}</strong>"
                  | "<strong>%{</strong>" funcname "<strong>:</strong>" funcargs "<strong>}</strong>"
    
    rebackref   ::= "<strong>$</strong>" [0-9]
    
    function     ::= funcname "<strong>(</strong>" word "<strong>)</strong>"
    
    listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"</pre>
    </blockquote>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="vars" id="vars">Variables</a></h2>
        
    
        <p>The expression parser provides a number of variables of the form
        <code>%{HTTP_HOST}</code>. Note that the value of a variable may depend
        on the phase of the request processing in which it is evaluated.  For
        example, an expression used in an <code class="directive">&lt;If &gt;</code>
        directive is evaluated before authentication is done. Therefore,
        <code>%{REMOTE_USER}</code> will not be set in this case.</p>
    
        <p>The following variables provide the values of the named HTTP request
        headers. The values of other headers can be obtained with the
        <code>req</code> <a href="#functions">function</a>. Using these
        variables may cause the header name to be added to the Vary
        header of the HTTP response, except where otherwise noted for the
        directive accepting the expression. The <code>req_novary</code>
        <a href="#functions">function</a> may be used to circumvent this
        behavior.</p>
    
        <table class="bordered"><tr class="header"><th>Name</th></tr>
    <tr><td><code>HTTP_ACCEPT</code></td></tr>
    <tr class="odd"><td><code>HTTP_COOKIE</code></td></tr>
    <tr><td><code>HTTP_FORWARDED</code></td></tr>
    <tr class="odd"><td><code>HTTP_HOST</code></td></tr>
    <tr><td><code>HTTP_PROXY_CONNECTION</code></td></tr>
    <tr class="odd"><td><code>HTTP_REFERER</code></td></tr>
    <tr><td><code>HTTP_USER_AGENT</code></td></tr>
    </table>
    
        <p>Other request related variables</p>
    
        <table class="bordered"><tr class="header"><th>Name</th><th>Description</th></tr>
    <tr><td><code>REQUEST_METHOD</code></td>
            <td>The HTTP method of the incoming request (e.g.
                <code>GET</code>)</td></tr>
    <tr class="odd"><td><code>REQUEST_SCHEME</code></td>
            <td>The scheme part of the request's URI</td></tr>
    <tr><td><code>REQUEST_URI</code></td>
            <td>The path part of the request's URI</td></tr>
    <tr class="odd"><td><code>DOCUMENT_URI</code></td>
            <td>Same as <code>REQUEST_URI</code></td></tr>
    <tr><td><code>REQUEST_FILENAME</code></td>
            <td>The full local filesystem path to the file or script matching the
                request, if this has already been determined by the server at the
                time <code>REQUEST_FILENAME</code> is referenced. Otherwise, such
                as when used in virtual host context, the same value as
                <code>REQUEST_URI</code> </td></tr>
    <tr class="odd"><td><code>SCRIPT_FILENAME</code></td>
            <td>Same as <code>REQUEST_FILENAME</code></td></tr>
    <tr><td><code>LAST_MODIFIED</code></td>
            <td>The date and time of last modification of the file in the format
                <code>20101231235959</code>, if this has already been determined by
                the server at the time <code>LAST_MODIFIED</code> is referenced.
                </td></tr>
    <tr class="odd"><td><code>SCRIPT_USER</code></td>
            <td>The user name of the owner of the script.</td></tr>
    <tr><td><code>SCRIPT_GROUP</code></td>
            <td>The group name of the group of the script.</td></tr>
    <tr class="odd"><td><code>PATH_INFO</code></td>
            <td>The trailing path name information, see
                <code class="directive"><a href="./mod/core.html#acceptpathinfo">AcceptPathInfo</a></code></td></tr>
    <tr><td><code>QUERY_STRING</code></td>
            <td>The query string of the current request</td></tr>
    <tr class="odd"><td><code>IS_SUBREQ</code></td>
            <td>"<code>true</code>" if the current request is a subrequest,
                "<code>false</code>" otherwise</td></tr>
    <tr><td><code>THE_REQUEST</code></td>
            <td>The complete request line (e.g.,
                "<code>GET /index.html HTTP/1.1</code>")</td></tr>
    <tr class="odd"><td><code>REMOTE_ADDR</code></td>
            <td>The IP address of the remote host</td></tr>
    <tr><td><code>REMOTE_PORT</code></td>
            <td>The port of the remote host (2.4.26 and later)</td></tr>
    <tr class="odd"><td><code>REMOTE_HOST</code></td>
            <td>The host name of the remote host</td></tr>
    <tr><td><code>REMOTE_USER</code></td>
            <td>The name of the authenticated user, if any (not available during <code class="directive">&lt;If&gt;</code>)</td></tr>
    <tr class="odd"><td><code>REMOTE_IDENT</code></td>
            <td>The user name set by <code class="module"><a href="./mod/mod_ident.html">mod_ident</a></code></td></tr>
    <tr><td><code>SERVER_NAME</code></td>
            <td>The <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> of
                the current vhost</td></tr>
    <tr class="odd"><td><code>SERVER_PORT</code></td>
            <td>The server port of the current vhost, see
                <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code></td></tr>
    <tr><td><code>SERVER_ADMIN</code></td>
            <td>The <code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code> of
                the current vhost</td></tr>
    <tr class="odd"><td><code>SERVER_PROTOCOL</code></td>
            <td>The protocol used by the request</td></tr>
    <tr><td><code>DOCUMENT_ROOT</code></td>
            <td>The <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> of
                the current vhost</td></tr>
    <tr class="odd"><td><code>AUTH_TYPE</code></td>
            <td>The configured <code class="directive"><a href="./mod/mod_authn_core.html#authtype">AuthType</a></code> (e.g.
            "<code>basic</code>")</td></tr>
    <tr><td><code>CONTENT_TYPE</code></td>
            <td>The content type of the response (not available during <code class="directive">&lt;If&gt;</code>)</td></tr>
    <tr class="odd"><td><code>HANDLER</code></td>
            <td>The name of the <a href="handler.html">handler</a> creating
                the response</td></tr>
    <tr><td><code>HTTP2</code></td>
            <td>"<code>on</code>" if the request uses http/2,
                "<code>off</code>" otherwise</td></tr>
    <tr class="odd"><td><code>HTTPS</code></td>
            <td>"<code>on</code>" if the request uses https,
                "<code>off</code>" otherwise</td></tr>
    <tr><td><code>IPV6</code></td>
            <td>"<code>on</code>" if the connection uses IPv6,
                "<code>off</code>" otherwise</td></tr>
    <tr class="odd"><td><code>REQUEST_STATUS</code></td>
            <td>The HTTP error status of the request (not available during <code class="directive">&lt;If&gt;</code>)</td></tr>
    <tr><td><code>REQUEST_LOG_ID</code></td>
            <td>The error log id of the request (see
                <code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code>)</td></tr>
    <tr class="odd"><td><code>CONN_LOG_ID</code></td>
            <td>The error log id of the connection (see
                <code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code>)</td></tr>
    <tr><td><code>CONN_REMOTE_ADDR</code></td>
            <td>The peer IP address of the connection (see the
                <code class="module"><a href="./mod/mod_remoteip.html">mod_remoteip</a></code> module)</td></tr>
    <tr class="odd"><td><code>CONTEXT_PREFIX</code></td>
            <td /></tr>
    <tr><td><code>CONTEXT_DOCUMENT_ROOT</code></td>
            <td /></tr>
    </table>
    
        <p>Misc variables</p>
    
        <table class="bordered"><tr class="header"><th>Name</th><th>Description</th></tr>
    <tr><td><code>TIME_YEAR</code></td>
            <td>The current year (e.g. <code>2010</code>)</td></tr>
    <tr class="odd"><td><code>TIME_MON</code></td>
            <td>The current month (<code>01</code>, ..., <code>12</code>)</td></tr>
    <tr><td><code>TIME_DAY</code></td>
            <td>The current day of the month (<code>01</code>, ...)</td></tr>
    <tr class="odd"><td><code>TIME_HOUR</code></td>
            <td>The hour part of the current time
                (<code>00</code>, ..., <code>23</code>)</td></tr>
    <tr><td><code>TIME_MIN</code></td>
            <td>The minute part of the current time </td></tr>
    <tr class="odd"><td><code>TIME_SEC</code></td>
            <td>The second part of the current time </td></tr>
    <tr><td><code>TIME_WDAY</code></td>
            <td>The day of the week (starting with <code>0</code>
                for Sunday)</td></tr>
    <tr class="odd"><td><code>TIME</code></td>
            <td>The date and time in the format
            <code>20101231235959</code></td></tr>
    <tr><td><code>SERVER_SOFTWARE</code></td>
            <td>The server version string</td></tr>
    <tr class="odd"><td><code>API_VERSION</code></td>
            <td>The date of the API version (module magic number)</td></tr>
    </table>
    
        <p>Some modules register additional variables, see e.g.
        <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="binop" id="binop">Binary operators</a></h2>
        
    
        <p>With the exception of some built-in comparison operators, binary
        operators have the form "<code>-[a-zA-Z][a-zA-Z0-9_]+</code>", i.e. a
        minus and at least two characters. The name is not case sensitive.
        Modules may register additional binary operators.</p>
    
        <h3><a name="comp" id="comp">Comparison operators</a></h3>
        
    
        <table class="bordered"><tr class="header"><th>Name</th><th>Alternative</th> <th>Description</th></tr>
    <tr><td><code>==</code></td>
            <td><code>=</code></td>
            <td>String equality</td></tr>
    <tr class="odd"><td><code>!=</code></td>
            <td />
            <td>String inequality</td></tr>
    <tr><td><code>&lt;</code></td>
            <td />
            <td>String less than</td></tr>
    <tr class="odd"><td><code>&lt;=</code></td>
            <td />
            <td>String less than or equal</td></tr>
    <tr><td><code>&gt;</code></td>
            <td />
            <td>String greater than</td></tr>
    <tr class="odd"><td><code>&gt;=</code></td>
            <td />
            <td>String greater than or equal</td></tr>
    <tr><td><code>=~</code></td>
            <td />
            <td>String matches the regular expression</td></tr>
    <tr class="odd"><td><code>!~</code></td>
            <td />
            <td>String does not match the regular expression</td></tr>
    <tr><td><code>-eq</code></td>
            <td><code>eq</code></td>
            <td>Integer equality</td></tr>
    <tr class="odd"><td><code>-ne</code></td>
            <td><code>ne</code></td>
            <td>Integer inequality</td></tr>
    <tr><td><code>-lt</code></td>
            <td><code>lt</code></td>
            <td>Integer less than</td></tr>
    <tr class="odd"><td><code>-le</code></td>
            <td><code>le</code></td>
            <td>Integer less than or equal</td></tr>
    <tr><td><code>-gt</code></td>
            <td><code>gt</code></td>
            <td>Integer greater than</td></tr>
    <tr class="odd"><td><code>-ge</code></td>
            <td><code>ge</code></td>
            <td>Integer greater than or equal</td></tr>
    </table>
        
    
        <h3><a name="binaryother" id="binaryother">Other binary operators</a></h3>
        
    
        <table class="bordered"><tr class="header"><th>Name</th><th>Description</th></tr>
    <tr><td><code>-ipmatch</code></td>
            <td>IP address matches address/netmask</td></tr>
    <tr class="odd"><td><code>-strmatch</code></td>
            <td>left string matches pattern given by right string (containing
                wildcards *, ?, [])</td></tr>
    <tr><td><code>-strcmatch</code></td>
            <td>same as <code>-strmatch</code>, but case insensitive</td></tr>
    <tr class="odd"><td><code>-fnmatch</code></td>
            <td>same as <code>-strmatch</code>, but slashes are not matched by
                wildcards</td></tr>
    </table>
        
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="unnop" id="unnop">Unary operators</a></h2>
        
    
        <p>Unary operators take one argument and have the form
        "<code>-[a-zA-Z]</code>", i.e. a minus and one character.
        The name <em>is</em> case sensitive.
        Modules may register additional unary operators.</p>
    
        <table class="bordered"><tr class="header"><th>Name</th><th>Description</th><th>Restricted</th></tr>
    <tr><td><code>-d</code></td>
            <td>The argument is treated as a filename.
                True if the file exists and is a directory</td><td>yes</td></tr>
    <tr class="odd"><td><code>-e</code></td>
            <td>The argument is treated as a filename.
                True if the file (or dir or special) exists</td><td>yes</td></tr>
    <tr><td><code>-f</code></td>
            <td>The argument is treated as a filename.
                True if the file exists and is regular file</td><td>yes</td></tr>
    <tr class="odd"><td><code>-s</code></td>
            <td>The argument is treated as a filename.
                True if the file exists and is not empty</td><td>yes</td></tr>
    <tr><td><code>-L</code></td>
            <td>The argument is treated as a filename.
                True if the file exists and is symlink</td><td>yes</td></tr>
    <tr class="odd"><td><code>-h</code></td>
            <td>The argument is treated as a filename.
                True if the file exists and is symlink
                (same as <code>-L</code>)</td><td>yes</td></tr>
    <tr><td><code>-F</code></td>
            <td>True if string is a valid file, accessible via all the server's
                currently-configured access controls for that path. This uses an
                internal subrequest to do the check, so use it with care - it can
                impact your server's performance!</td><td /></tr>
    <tr class="odd"><td><code>-U</code></td>
            <td>True if string is a valid URL, accessible via all the server's
                currently-configured access controls for that path. This uses an
                internal subrequest to do the check, so use it with care - it can
                impact your server's performance!</td><td /></tr>
    <tr><td><code>-A</code></td>
            <td>Alias for <code>-U</code></td><td /></tr>
    <tr class="odd"><td><code>-n</code></td>
            <td>True if string is not empty</td><td /></tr>
    <tr><td><code>-z</code></td>
            <td>True if string is empty</td><td /></tr>
    <tr class="odd"><td><code>-T</code></td>
            <td>False if string is empty, "<code>0</code>", "<code>off</code>",
                "<code>false</code>", or "<code>no</code>" (case insensitive).
                True otherwise.</td><td /></tr>
    <tr><td><code>-R</code></td>
            <td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more
            efficient
            </td><td /></tr>
    </table>
    
        <p>The operators marked as "restricted" are not available in some modules
        like <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="functions" id="functions">Functions</a></h2>
        
    
        <p>Normal string-valued functions take one string as argument and return
        a string. Functions names are not case sensitive.
        Modules may register additional functions.</p>
    
        <table class="bordered"><tr class="header"><th>Name</th><th>Description</th><th>Special notes</th></tr>
    <tr><td><code>req</code>, <code>http</code></td>
            <td>Get HTTP request header; header names may be added to the Vary
                header, see below</td><td /></tr>
    <tr class="odd"><td><code>req_novary</code></td>
            <td>Same as <code>req</code>, but header names will not be added to the
                Vary header</td><td /></tr>
    <tr><td><code>resp</code></td>
            <td>Get HTTP response header (most response headers will not yet be set
                during <code class="directive">&lt;If&gt;</code>)</td><td /></tr>
    <tr class="odd"><td><code>reqenv</code></td>
            <td>Lookup request environment variable (as a shortcut,
            <code>v</code> can also be used to access variables). 
            </td>
            <td>ordering</td></tr>
    <tr><td><code>osenv</code></td>
            <td>Lookup operating system environment variable</td><td /></tr>
    <tr class="odd"><td><code>note</code></td>
            <td>Lookup request note</td><td>ordering</td></tr>
    <tr><td><code>env</code></td>
            <td>Return first match of <code>note</code>, <code>reqenv</code>,
                <code>osenv</code></td><td>ordering</td></tr>
    <tr class="odd"><td><code>tolower</code></td>
            <td>Convert string to lower case</td><td /></tr>
    <tr><td><code>toupper</code></td>
            <td>Convert string to upper case</td><td /></tr>
    <tr class="odd"><td><code>escape</code></td>
            <td>Escape special characters in %hex encoding</td><td /></tr>
    <tr><td><code>unescape</code></td>
            <td>Unescape %hex encoded string, leaving encoded slashes alone;
                return empty string if %00 is found</td><td /></tr>
    <tr class="odd"><td><code>base64</code></td>
            <td>Encode the string using base64 encoding</td><td /></tr>
    <tr><td><code>unbase64</code></td>
            <td>Decode base64 encoded string, return truncated string if 0x00 is
                found</td><td /></tr>
    <tr class="odd"><td><code>md5</code></td>
            <td>Hash the string using MD5, then encode the hash with hexadecimal
                encoding</td><td /></tr>
    <tr><td><code>sha1</code></td>
            <td>Hash the string using SHA1, then encode the hash with hexadecimal
                encoding</td><td /></tr>
    <tr class="odd"><td><code>file</code></td>
            <td>Read contents from a file (including line endings, when present)
            </td><td>restricted</td></tr>
    <tr><td><code>filesize</code></td>
            <td>Return size of a file (or 0 if file does not exist or is not
                regular file)</td><td>restricted</td></tr>
    <tr class="odd"><td><code>ldap</code></td>
            <td>Escape characters as required by LDAP distinguished name escaping
                (RFC4514) and LDAP filter escaping (RFC4515).<br />
                (Available in httpd 2.4.53 and later)</td><td /></tr>
    </table>
    
        <p>The functions marked as "restricted" in the final column are not 
        available in some modules like <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>.</p>
    
        <p>The functions marked as "ordering" in the final column require some
        consideration for the ordering of different components of the server,
        especially when the function is used within the 
        &lt;<code class="directive"><a href="./mod/core.html#if">If</a></code>&gt; directive which is
        evaluated relatively early.</p>
        <div class="note">
        <h3>Environment variable ordering</h3>
        When environment variables are looked up within an 
        &lt;<code class="directive"><a href="./mod/core.html#if">If</a></code>&gt; condition, it's important 
        to consider how extremely early in request processing that this 
        resolution occurs. As a guideline, any directive defined outside of virtual host 
        context (directory, location, htaccess) is not likely to have yet had a 
        chance to execute. <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>
        in virtual host scope is one directive that runs prior to this resolution
        <br />
        <br />
        When <code>reqenv</code> is used outside of &lt;<code class="directive"><a href="./mod/core.html#if">If</a></code>&gt;, the resolution will generally occur later, but the 
        exact timing depends on the directive the expression has been used within.
        </div>
    
        <p>When the functions <code>req</code> or <code>http</code> are used,
        the header name will automatically be added to the Vary header of the
        HTTP response, except where otherwise noted for the directive accepting
        the expression. The <code>req_novary</code> function can be used to
        prevent names from being added to the Vary header.</p>
    
        <p>In addition to string-valued functions, there are also
        list-valued functions which take one string as argument and return a
        wordlist, i.e. a list of strings. The wordlist can be used with the
        special <code>-in</code> operator.  Functions names are not case
        sensitive.  Modules may register additional functions.</p>
    
        <p>There are no built-in list-valued functions. <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>
        provides <code>PeerExtList</code>.  See the description of
        <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code> for details
        (but <code>PeerExtList</code> is also usable outside
        of <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code>).</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Example expressions</a></h2>
    
        
        <p>The following examples show how expressions might be used to
        evaluate requests:</p>
    
        
        <pre class="prettyprint lang-config"># Compare the host name to example.com and redirect to www.example.com if it matches
    &lt;If "%{HTTP_HOST} == 'example.com'"&gt;
        Redirect permanent "/" "http://www.example.com/"
    &lt;/If&gt;
    
    # Force text/plain if requesting a file with the query string contains 'forcetext'
    &lt;If "%{QUERY_STRING} =~ /forcetext/"&gt;
        ForceType text/plain
    &lt;/If&gt;
    
    # Only allow access to this content during business hours
    &lt;Directory "/foo/bar/business"&gt;
        Require expr %{TIME_HOUR} -gt 9 &amp;&amp; %{TIME_HOUR} -lt 17
    &lt;/Directory&gt;
    
    # Check a HTTP header for a list of values
    &lt;If "%{HTTP:X-example-header} in { 'foo', 'bar', 'baz' }"&gt;
        Header set matched true
    &lt;/If&gt;
    
    # Check an environment variable for a regular expression, negated.
    &lt;If "! reqenv('REDIRECT_FOO') =~ /bar/"&gt;
        Header set matched true
    &lt;/If&gt;
    
    # Check result of URI mapping by running in Directory context with -f
    &lt;Directory "/var/www"&gt;
        AddEncoding x-gzip gz
    &lt;If "-f '%{REQUEST_FILENAME}.unzipme' &amp;&amp; ! %{HTTP:Accept-Encoding} =~ /gzip/"&gt;
          SetOutputFilter INFLATE
    &lt;/If&gt;
    &lt;/Directory&gt;
    
    # Check against the client IP
    &lt;If "-R '192.168.1.0/24'"&gt;
        Header set matched true
    &lt;/If&gt;
    
    # Function example in boolean context
    &lt;If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'"&gt;
      Header set checksum-matched true
    &lt;/If&gt;
    
    # Function example in string context
    Header set foo-checksum "expr=%{md5:foo}"
    
    # This delays the evaluation of the condition clause compared to &lt;If&gt;
    Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path\.php$#"
    
    # Conditional logging
    CustomLog logs/access-errors.log common "expr=%{REQUEST_STATUS} &gt;= 400"
    CustomLog logs/access-errors-specific.log common "expr=%{REQUEST_STATUS} -in {'405','410'}"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Other</a></h2>
        
    
        <table class="bordered"><tr class="header"><th>Name</th><th>Alternative</th> <th>Description</th></tr>
    <tr><td><code>-in</code></td>
            <td><code>in</code></td>
            <td>string contained in wordlist</td></tr>
    <tr class="odd"><td><code>/regexp/</code></td>
            <td><code>m#regexp#</code></td>
            <td>Regular expression (the second form allows different
            delimiters than /)</td></tr>
    <tr><td><code>/regexp/i</code></td>
            <td><code>m#regexp#i</code></td>
            <td>Case insensitive regular expression</td></tr>
    <tr class="odd"><td><code>$0 ... $9</code></td>
            <td />
            <td>Regular expression backreferences</td></tr>
    </table>
    
        <h3><a name="rebackref" id="rebackref">Regular expression backreferences</a></h3>
            
            <p>The strings <code>$0</code> ... <code>$9</code> allow to reference
            the capture groups from a previously executed, successfully
            matching regular expressions. They can normally only be used in the
            same expression as the matching regex, but some modules allow special
            uses.</p>
        
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="sslrequire" id="sslrequire">Comparison with SSLRequire</a></h2>
        
        <p>The <em>ap_expr</em> syntax is mostly a superset of the syntax of the
        deprecated <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code> directive.
        The differences are described in <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code>'s documentation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compatibility" id="compatibility">Version History</a></h2>
        
        <p>The <code>req_novary</code> <a href="#functions">function</a>
        is available for versions 2.4.4 and later.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/expr.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/expr.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/expr.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/env.html.ja.utf8�����������������������������������������������������������0000664�0001751�0001751�00000075073�14743132254�020004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache の環境変数 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache の環境変数</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>Apache HTTP サーバは<em>環境変数</em>と呼ばれる、名前のついた
        変数に情報を記憶する仕組みを提供しています。この情報はログ収集や
        アクセス制御などのいろいろな操作を制御するために使うことができます。
        これらの変数は CGI スクリプトなどの外部プログラムと通信するためにも
        使われます。この文書はそれらの変数の操作方法と使用方法をいくつか
        紹介します。</p>
    
        <p>これらの変数は<em>環境変数</em>と呼ばれていますが、オペレーティング
        システムによって制御されている環境変数と同じではありません。
        実際は、これらの変数は Apache の内部構造の中に記憶され、操作されています。
        それらは、CGI や SSI スクリプトに渡されたときだけ、実際の
        オペレーティングシステムの環境変数になります。サーバ自身が
        実行されているオペレーティングシステムの環境を操作したい場合は、
        オペレーティングシステムのシェルが提供している標準の環境変数の
        操作方法を使わなければなりません。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#setting">環境変数の設定</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">環境変数の使用</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#special">特別な目的の環境変数</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">例</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setting" id="setting">環境変数の設定</a></h2>
        
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_env.html">mod_env</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li><li><code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifnocase">SetEnvIfNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#unsetenv">UnsetEnv</a></code></li></ul></td></tr></table>
    
        <h3><a name="basic-manipulation" id="basic-manipulation">基本的な環境の操作</a></h3>
            
    
            <p>Apache において環境変数を設定する一番基本的な方法は、
            無条件に環境変数を設定する <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> ディレクティブを使用することです。
    	<code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> 
            ディレクティブにより、Apache が起動されたシェルの
            環境変数を渡すこともできます。</p>
    
        
        <h3><a name="conditional" id="conditional">リクエスト毎に条件に基づいて設定する</a></h3>
            
    
            <p>より柔軟性を高めるために、mod_setenvif
            で提供されているディレクティブを使用することで、リクエストの
            特性に基づいて環境変数を設定することができます。例えば、特定のブラウザ
            (User-Agent) のリクエストや特定の Referer [意図的な綴りです]
            <span class="transnote">(<em>訳注:</em> 正しい綴りは referrer ですが、HTTP の仕様では Referer
            となっています)</span>ヘッダが見つかったときのみ変数を設定することができます。
            mod_rewrite の <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
    	ディレクティブにおいて環境変数を設定する <code>[E=...]</code>
    	オプションを使用することで、
            より柔軟な設定を行なうことができます。</p>
    
        
        <h3><a name="unique-identifiers" id="unique-identifiers">一意な識別子</a></h3>
            
    
            <p>mod_unique_id は、非常に限られた条件の下で
            「すべて」のリクエストについて、一意であることが保証されている値を環境変数
            <code>UNIQUE_ID</code> に設定します。</p>
    
        
        <h3><a name="standard-cgi" id="standard-cgi">標準 CGI 変数</a></h3>
            
    
            <p>Apache の設定ファイルで設定された環境変数とシェルから渡される
            環境変数に加えて、CGI スクリプトと SSI ページには <a href="http://cgi-spec.golux.com">CGI の仕様</a>で要求されている、
            リクエストのメタ情報を持った環境変数の組が提供されます。</p>
    
        
        <h3><a name="caveats" id="caveats">いくつかの注意</a></h3>
            
    
            <ul>
              <li>環境を操作するディレクティブを使って標準 CGI
              変数を上書きしたり変更したりすることはできません。</li>
    
              <li>CGI スクリプトを起動するために <code class="program"><a href="./programs/suexec.html">suexec</a></code>
              が使用されている場合、CGI スクリプトが起動するために、環境変数は<em>安全</em>な環境変数の組に整理されます。
              この安全な環境変数の集合は、コンパイル時に <code>suexec.c</code>
              で定義されます。</li>
    
              <li>移植性のために、環境変数の名前はアルファベット、
              数字とアンダースコア <span class="transnote">(<em>訳注:</em> '_')</span> だけから成ります。
              さらに、最初の文字は数字であってはいけません。
              この制限に合わない文字は CGI スクリプトと SSI
              ページに渡されるときにアンダースコアに置換されます。</li>
              
              <li><code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> はリクエスト処理の
              段階の中でも遅くに実行されます。つまり
              <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> や
              <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
              などからは、変数がそこで設定されていることがわかりません。</li>
            </ul>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">環境変数の使用</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authz_host.html#allow">Allow</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_authz_host.html#deny">Deny</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li></ul></td></tr></table>
    
        <h3><a name="cgi-scripts" id="cgi-scripts">CGI スクリプト</a></h3>
            
    
            <p>環境変数の主な利用法の一つは、CGI スクリプトに情報を伝えることです。
            上で説明されているように、CGI スクリプトに渡される環境変数は Apache
            の設定により設定される変数に加えて、リクエストの標準のメタ情報を含んでいます。
            詳細は <a href="howto/cgi.html">CGI チュートリアル</a>
    	を参照してください。</p>
    
        
        <h3><a name="ssi-pages" id="ssi-pages">SSI ページ</a></h3>
            
    
            <p>mod_include の <code>INCLUDES</code> フィルタで処理される
            server-parsed (SSI) ドキュメントでは、<code>echo</code>
            要素を使用すると環境変数が出力されます。
            また、ページのある部分がリクエストの性質に応じて変更されるように、
            環境変数をフロー制御要素で使うことができます。詳細は
            <a href="howto/ssi.html">SSI チュートリアル</a> を参照してください。</p>
    
        
        <h3><a name="access-control" id="access-control">アクセス制御</a></h3>
            
    
            <p><code>allow from env=</code> ディレクティブと <code>deny from env=</code>
            ディレクティブを使用して、サーバへのアクセスを環境変数の値で制御することができます。
            <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>
    	ディレクティブと組み合わせることで、クライアントの特性に基づいて
            サーバへのアクセス制御を柔軟に行なうことができるようになります。
            たとえば、これらのディレクティブを使用して、特定のブラウザ (User-Agent)
            からのアクセスを拒否することができます。</p>
    
        
        <h3><a name="logging" id="logging">条件付きログ記録</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>
            ディレクティブのオプション <code>%e</code>
            を使用することで、環境変数をアクセスログに記録することができます。さらに、
            <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
    	ディレクティブの条件分岐式を使用することで、
            環境変数の値によってリクエストをログに記録するかどうかを決めることができます。
            <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>
    	ディレクティブと組み合わせることで、
            どのリクエストをログに記録するかを柔軟に制御することが可能になります。たとえば、
            <code>gif</code> で終わるファイル名へのリクエストはログに記録しない、
            違うサブネットのクライアントからのリクエストだけをログに記録する、
    	という選択が可能です。</p>
    
        
        <h3><a name="response-headers" id="response-headers">条件付き応答ヘッダ</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code>
    	ディレクティブは環境変数の存在や不在によってクライアントへの応答に特定の
    	HTTP ヘッダを付けるかどうかを決めることができます。
    	これにより、たとえば、クライアントからのリクエスト
            にあるヘッダがある場合にのみ特定の応答ヘッダを送る、というようなことが
            できます。</p>
    
        
    
        <h3><a name="external-filter" id="external-filter">外部フィルタの適用</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code>
            ディレクティブを使用して
            <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> で設定される外部フィルタは、
    	<code>disableenv=</code> と <code>enableenv=</code>
    	オプションを使って、環境変数による条件付き適用ができます。</p>
        
    
        <h3><a name="url-rewriting" id="url-rewriting">URL の書き換え</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
    	ディレクティブで<em>評価文字列</em>として
            <code>%{ENV:...}</code> 式を指定することで、mod_rewrite
            の書き換えエンジンが環境変数に基いて条件分岐を行なうことができます。
            mod_rewrite が使用可能な変数で <code>ENV:</code> が前についていない変数は、
            実際は環境変数ではないということに注意してください。
            それらは他のモジュールからは使用できない mod_rewrite 用の特別な変数です。
            </p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="special" id="special">特別な目的の環境変数</a></h2>
        
    
            <p>互換性の問題を解決するために、特定のクライアントと通信しているときは
            Apache の動作を変更できる機構が導入されました。できるだけ柔軟にするために、
            これらの機構は環境変数を定義することで呼び出されます。普通は、
            <code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code>
            ディレクティブを使いますが、たとえば <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> ディレクティブや <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> ディレクティブも使用することができます。</p>
    
        <h3><a name="downgrade" id="downgrade">downgrade-1.0</a></h3>
            
    
            <p>これを指定することで、リクエストが HTTP/1.0
            より新しいプロトコルの場合でも、HTTP/1.0 として扱われます。</p>
    
        
        <h3><a name="force-gzip" id="force-gzip">force-gzip</a></h3>
            
              <p><code>DEFLATE</code> フィルタが使用するように設定されているときに、
              この環境変数はブラウザの accept-encoding の設定を無視して常に
              圧縮された出力を送るようにします。</p>
        
        <h3><a name="force-no-vary" id="force-no-vary">force-no-vary</a></h3>
            
    
            <p>応答ヘッダがクライアントに送られる前に <code>Vary</code>
            フィールドを取り除きます。
            クライアントの中にはこのフィールドを正しく解釈しないものがあります。
            この変数を設定することでその問題を回避することができます。
            この変数を設定すると、<strong>force-response-1.0</strong>
            が設定されたことになります。</p>
    
        
        <h3><a name="force-response" id="force-response">force-response-1.0</a></h3>
            
    
            <p>これが設定されていると、HTTP/1.0 リクエストを発行するクライアントに対しては
    	常に HTTP/1.0 で応答するようになります。この機能は、
            元々は AOL のプロキシの問題のために実装されました。HTTP/1.0 クライアントの中には、
            HTTP/1.1 の応答を返されると正しく動作しないものがあるかもしれません。
            この機能を使用することで、そのようなクライアントとの間の互換性問題を解決できます。</p>
        
    
        <h3><a name="gzip-only-text-html" id="gzip-only-text-html">gzip-only-text/html</a></h3>
            
    
    	<p>これが 1 に設定されると、この変数は <code>text/html</code>
    	以外のコンテントタイプに対する、<code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code>
    	提供の <code>DEFLATE</code> 出力フィルタを無効にします。
            また、静的に、既に圧縮されたファイルを使用したい場合、
            (gzip だけでなく、"identity" と異なる全てのエンコードに対して)
            <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> も変数を評価します。</p>
        
    
        <h3><a name="no-gzip" id="no-gzip">no-gzip</a></h3>
            <p>セットされると、<code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> の
    	<code>DEFLATE</code> フィルタがオフになります。
            そして <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>
            はエンコードされたリソースを送らないようにします。</p>
        
    
        <h3><a name="nokeepalive" id="nokeepalive">nokeepalive</a></h3>
            
    
            <p>これが設定されている場合は、<code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code> を使用しないようにします。</p>
    
        <h4><a name="prefer-language" id="prefer-language">prefer-language</a></h4>
    
            <p><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> の挙動に影響を与えます。
            (<code>en</code>, <code>ja</code>, <code>x-klingon</code>といった)
            言語タグが格納されていれば、その言語の variant を送信しようとします。
            そのような variant がない場合は、
            通常の<a href="content-negotiation.html">ネゴシエーション</a>処理が
            適用されます。</p>
    
        
    
        
        <h3><a name="redirect-carefully" id="redirect-carefully">redirect-carefully</a></h3>
            
    
            <p>これはクライアントへのリダイレクトの送信をサーバがより注意深く
            行なうようにします。
            これは通常、リダイレクトに際してクライアントに
            問題があることが分かっている場合に使われます。この機能は元々は
            マイクロソフトのウェブフォルダのソフトが DAV
            メソッドによるディレクトリのリソースへのリダイレクトの扱いに
            問題がり、それを回避するために実装されました。</p>
    
        
    
       <h3><a name="suppress-error-charset" id="suppress-error-charset">suppress-error-charset</a></h3>
           
    
        <p><em>Apache 2.2 以降で利用可能</em></p>
    
        <p>クライアントのリクエストに対する応答としてリダイレクトを送信する際、
        レスポンスにはリダイレクトが自動的に行なえない (行なわれない)
        場合に表示するテキストが含まれます。
        通常、このテキストに合致したキャラクタセット、ISO-8859-1
        でラベル付けをします。</p>
        <p>しかし、リダイレクト先が別の文字セットを使っている場合、
        ある問題のあるブラウザのバージョンでは、
        リダイレクト先の実際の文字セットの代わりに、
        リダイレクト元の文字セットを使ってしまうことがあります。
        その結果、例えば変な描画が行なわれたりして、読めなくなったりします。</p>
        <p>この環境変数を設定することで、リダイレクションテキストに対する
        キャラクタセットの指定を除去しますので、それら問題のあるブラウザでも
        リダイレクト先の文字セットを正しく使うようにできます。</p>
    
        <div class="warning">
          <h3>セキュリティ</h3> 
    
          <p>文字セットを指定せずにエラーページを送信すると、
          クロスサイトスクリプティング <span class="transnote">(<em>訳注:</em> XSS)</span>
          攻撃の危険性がでてきます。
          HTTP/1.1 仕様に準拠していなくて、コンテンツの中身から文字セットを
          "推測" しようとするブラウザ (MSIE) が実際にあるからです。
          そのようなブラウザは UTF-7 文字セットを使って簡単に騙すことができます。
          クロスサイトスクリプティング攻撃を防ぐために実装されている
          通常のエスケープ機構が、入力データ中にある UTF-7 で
          エンコードされたコンテンツ (リクエスト URI など) には
          うまく動作しないからです。</p>
        </div>
    
       
    
       <h3><a name="proxy" id="proxy">force-proxy-request-1.0, proxy-nokeepalive, proxy-sendchunked, proxy-sendcl</a></h3>
    
       <p>これらの指示子は <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> の挙動を変更します。
       詳細は <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> のドキュメントをご参照ください。</p>
       
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">例</a></h2>
        
    
        <h3><a name="misbehaving" id="misbehaving">おかしな挙動をするクライアントに対してプロトコルの動作を変更する</a></h3>
            
    
            <p>クライアントに関する既知の問題に対処するために、以下の行を
            httpd.conf に入れることを推奨しています。</p>
            <p>古いバージョンの Apache では、クライアントの問題に対応するために
            httpd.conf に次の行を加えるよう推奨されていましたが、
            今となっては、問題としていたクライアントは実際には見かけることは
            なくなってきたので、この設定はもはや必要ないかもしれません。</p>
    <div class="example"><pre>#
    # 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</pre></div>
    
        
        <h3><a name="no-img-log" id="no-img-log">画像へのリクエストをアクセスログに記録しない</a></h3>
            
    
            <p>この例では、画像へのリクエストがアクセスログに現れないようにします。
            これを変更することで、特定のディレクトリのログ収集をやめたり、
            特定のホストからのリクエストのログ収集をやめたりすることが簡単にできます。
            </p>
        <div class="example"><pre>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</pre></div>
    
        
        <h3><a name="image-theft" id="image-theft">「画像の盗用」を防ぐ</a></h3>
            
    
            <p>この例は、別のサーバにいる人が、あなたのサーバにある画像を
            inline 画像として使用することを防ぎます。
            これは推奨されている設定ではありませんが、ある限定された状況では有効です。
            ここでは、すべての画像は <code>/web/images</code>
    	というディレクトリにあると仮定します。</p>
        <div class="example"><pre>SetEnvIf Referer "^http://www\.example\.com/" local_referal
    # Allow browsers that do not send Referer info
    SetEnvIf Referer "^$" local_referal
    &lt;Directory /web/images&gt;
       Order Deny,Allow
       Deny from all
       Allow from env=local_referal
    &lt;/Directory&gt;</pre></div>
    
            <p>この手法に関する詳しい情報は ServerWatch にあるチュートリアル
            「<a href="http://www.serverwatch.com/tutorials/article.php/1132731">Keeping Your Images from Adorning Other Sites</a>
            」を参照してください。</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/env.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dso.html.tr.utf8�����������������������������������������������������������0000664�0001751�0001751�00000052756�14743132254�020037� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Devingen Paylaşımlı Nesne Desteği - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Devingen Paylaşımlı Nesne Desteği</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Apache HTTP Sunucusu modüler bir program olup, yönetici sadece bir
          grup modül seçerek sunucuya işlevsellik ekleyebilir. Modüller, Devingen
          Paylaşımlı Nesneler (DSO - Dynamic Shared Object) halinde
          <code class="program"><a href="./programs/httpd.html">httpd</a></code> programından ayrı olarak derlenir. DSO modülleri
          sunucunun derlenmesi sırasında derlenebileceği gibi ayrı olarak derlenip
          daha sonra Apache Eklenti Aracı (Apache Extension Tool)
          <code class="program"><a href="./programs/apxs.html">apxs</a></code> programı kullanılarak da sunucuya eklenebilir.</p>
    
        <p>Bu belgede DSO modüllerinin kullanımının yanında teorisine de
          değinilecektir.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#implementation">Gerçeklenim</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">Kullanım Özeti</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#background">Artalan Bilgisi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#advantages">Getiriler ve Götürüler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">Gerçeklenim</a></h2>
    
    <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>Apache httpd modüllerini yüklemek için DSO desteği, Apache httpd
          çekirdeğine durağan olarak ilintilenerek derlenmiş olan
          <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> adında bir modül tarafından sağlanır.
          <code class="module"><a href="./mod/core.html">core</a></code> modülünden  başka, bir DSO modülü olamayan tek modül
          <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> modülüdür. Apache ile dağıtılan hemen hemen tüm
          diğer Apache modülleri bir DSO modülüne yerleştirilebilir. Derlenmiş
          modüller <code>mod_filanca.so</code> biçeminde birer DSO ismi alırlar ve
          her biri istenirse <code>httpd.conf</code> dosyasında
          <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> modülünün <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesiyle belirtilerek sunucu başlatılırken
          veya yeniden başlatılırken sunucuya yüklenebilir.</p>
    
        <p><a href="install.html">Kurulum belgesinde</a> açıklandığı gibi, her DSO
          modülü <code class="program"><a href="./programs/configure.html">configure</a></code> programının
          <code>--enable-mods-static</code> seçeneği ile devredışı bırakılabilir.</p>
    
        <p>Apache httpd modülleri için (özellikle üçüncü parti modüller için) DSO
          dosyası üretimini kolaylaştırmak amacıyla <code class="program"><a href="./programs/apxs.html">apxs</a></code>
          (<dfn>APache eXtenSion</dfn>) adında yeni bir destek programı
          kullanılmaktadır. Bu program Apache httpd modüllerini Apache httpd kaynak
          ağacından ayrı olarak derlemek için kullanılabilir. Fikir basittir: Apache
          HTTP Sunucusu derlenirken DSO dosyalarını derlemek için platforma bağımlı
          derleyici ve ilintileyici seçenekleri <code class="program"><a href="./programs/apxs.html">apxs</a></code>
          programının içine konur ve <code>make install</code> ile kurulum sırasında
          Apache httpd C başlık dosyaları da kurulur. Böylece
          kullanıcı Apache httpd dağıtımının kaynak ağacına ihtiyaç duymadan ve
          platforma bağımlı derleyici ve ilintileyici seçeneklerini bilmek zorunda
          kalmadan istediği Apache httpd modülünü <code class="program"><a href="./programs/apxs.html">apxs</a></code>
          programını kullanarak derleyebilir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">Kullanım Özeti</a></h2>
    
        <p>Apache HTTP Sunucusu 2.x’in DSO özelliklerine bir giriş olarak burada
          kısaca bir bilgi vermekle yetinilecektir:</p>
    
        <ol>
          <li><p>Kaynak dosyası <code>mod_filanca.c</code> dosyasında dağıtılan bir
            <em>özgün</em> Apache htpd modülünü <code>mod_filanca.so</code> isminde
            bir  DSO modülü olarak derlemek ve kurmak için şöyle yapılır:</p>
    
    <div class="example"><p><code>
      $ ./configure --prefix=/kurulum/yeri --enable-filanca<br />
      $ make install
    </code></p></div>
          </li>
    
          <li><p>Apache HTTP Sunucusunu tüm modüller etkin olarak
            derleyebilirsiniz. Fakat sunucunun başlatılması sırasında sadece temel
            modüller yüklenir.  Daha sonra <code>httpd.conf</code> içindeki
            <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> yönergelerini etkin
            veya etkisiz hale getirerek yüklenecek modülleri
            değiştirebilirsiniz.</p>
    
    <div class="example"><p><code>
    $ ./configure --enable-mods-shared=all<br />
    $ make install
    </code></p></div>
          </li>
    
          <li><p>Bazı modüller sadece geliştiriciler içindir ve bunlar tüm
            modüllerin derlenmesini (<em>all</em>) seçseniz bile derlenmeyecektir.
            Geliştirici modülleri dehil tüm modülleri derlemek isterseniz
            <em>reallyall</em> kullanınız. Ek olarak, derlenmiş modüller için
            kullanılan <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
            yönergelerinin tamamını <code>--enable-load-all-modules</code> derleme
            seçeneği ile etkin kılabilirsiniz.</p>
    
    <div class="example"><p><code>
    $ ./configure --enable-mods-shared=reallyall --enable-load-all-modules<br />
    $ make install
    </code></p></div>
          </li>
    
          <li><p>Kaynak dosyası <code>mod_filanca.c</code> dosyasında dağıtılan bir
            <em>üçüncü parti</em> Apache httpd modülü <code>mod_filanca.so</code>
            isminde bir DSO modülü olarak Apache httpd kaynak ağacının dışında
            <code class="program"><a href="./programs/apxs.html">apxs</a></code> kullanarak derlemek ve kurmak için şöyle
            yapılır:</p>
    
    <div class="example"><p><code>
    $ cd /bir/kurulum/yeri<br />
    $ apxs -c mod_filanca.c<br />
    $ apxs -aci filanca mod_filanca.la
    </code></p></div>
          </li>
        </ol>
    
        <p>Tüm durumlarda derlenen paylaşımlı modülü Apache httpd’nin etkin
          kılabilmesi  için <code>httpd.conf</code> dosyasında o modül için bir
          <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesi
          bulunmalıdır.</p>
    
        <p>Ayrıntılı bilgi için <a href="programs/apxs.html">apxs belgelerine</a>
          bakınız.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="background" id="background">Artalan Bilgisi</a></h2>
    
        <p>Günümüzün Unix türevlerinde var olan bir mekanizma sayesinde
          çalıştırılabilir bir programın adres uzayına çalışma anında yüklenmek
          veya ilintilenmek üzere <em>Devingen Paylaşımlı Nesneler</em> (DSO -
          Dynamic Shared Object) adı verilen, özel bir biçem kullanarak kodlanmış
          program parçaları oluşturulabilir.</p>
    
        <p>Bu yükleme normalde iki yolla yapılabilir: Ya çalıştırılabilir
          programın başlatılması sırasında yüklenen <code>ld.so</code> adlı bir
          sistem programınının devingen olarak yüklenmesi ile ya da
          çalıştırılabilir programın içinden Unix yükleyicisine programsal sistem
          arayüzü sağlayan <code>dlopen()/dlsym()</code> sistem çağrılarının elle
          yapılması suretiyle.</p>
    
        <p>İlk yöntemde kullanılan DSO’lara genelde <em>paylaşımlı
          kütüphaneler</em> veya <em>DSO kütüphaneleri</em> adı verilir ve
          bunların dosyaları <code>libfilanca.so</code> veya
          <code>libfilanca.so.1.2</code> biçiminde isimlendirilir. Belli bir
          sistem dizininde (normalde <code>/usr/lib</code>) bulunurlar ve derleme
          sırasında ilintileyici komutuna <code>-lfilanca</code> şeklinde
          belirtilerek çalıştırılabilir programla ilintilenirler. Doğrudan
          çalıştırılabilir koda eklenen bu kodlar Unix yükleyicisinin programın
          başlatılması sırasında kütüphaneyi <code>/usr/lib</code> altında
          <code>libfilanca.so</code> adıyla bulabilmesini sağlar. Kütüphanelerin
          aranacağı yerler ya <code>-R</code> gibi bir ilintileyici seçeneği ile
          koda eklenir ya da arama yolları <code>LD_LIBRARY_PATH</code> ortam
          değişkeni aracılığıyla yapılandırılır. Böylece çalıştırılabilir
          programda henüz çözümlenmemiş simgeler DSO içinde bulunarak
          çözümlenebilir.</p>
    
        <p>Çalıştırılabilir program içindeki simgelere normalde DSO içinden
          atıfta bulunulmaz (genel kod kütüphanesinin başka programlarca da
          kullanılması nedeniyle). Bu bakımdan DSO tarafında böyle bir çözümleme
          yapılmaz. Çalıştırılabilir program da DSO’daki simgeleri kendisi
          çözümlemeye uğraşmaz, bu işlemlerden tamamen Unix yükleyicisi
          (<code>ld.so</code>) sorumludur. (Aslında, <code>ld.so</code>’yu
          çağıracak kod, her çalıştırılabilir programın içine ilintilenmiş
          (durağan değil) başlatma kodunun bir parçasıdır.) Programlar tarafından
          ortaklaşa kullanılan kütüphanelerin devingen olarak yüklenmesinin sebebi
          basittir: Kütüphane kodu <code>libc.so</code> gibi bir sistem
          kütüphanesine bir kere kaydedilip disk alanından yer kazanılmış
          olur.</p>
    
        <p>İkinci yöntemde kullanılan DSO’lara yine <em>paylaşımlı
          kütüphaneler</em> veya <em>DSO kütüphaneleri</em> adı verilir fakat
          bunların dosyaları geçerli kabule göre <code>filanca.so</code> gibi
          isimlendirilse de genelde keyfi olarak seçilen bir dosya uzantısı
          kullanılarak isimlendirilirler. Bu dosyalar genellikle programa özel bir
          dizinde dururlar ve bu dosyaları kullanacak olan çalıştırılabilir
          programla aralarında özdevimli olarak bağ kurulmamıştır. Bunun yerine,
          çalıştırılabilir program DSO’yu çalışma anında <code>dlopen()</code>
          sayesinde kendi adres uzayına ekler. Çalıştırılabilir program için
          DSO’daki simgeler bu sırada çözümlenmez. Özdevimli olarak devreye
          giren Unix yükleyicisi, (varsa) artakalan simgeleri, çalıştırılabilir
          ihraç edilen simge kümelerini (ve özellikle her yerde hazır ve nazır
          <code>libc.so</code> içindeki tüm simgeleri) kullanarak çözümler. Bu
          yolla DSO, çalıştırılabilir programın simge kümesi bilgilerini sanki
          kendisine baştan durağan olarak ilintilenmiş gibi ulaşabilir.</p>
    
        <p>Son olarak, DSO’nun programlama arayüzünün getirilerinden yararlanmak
          amacıyla çalıştırılabilir program, daha sonra dağıtım tabloları vb.
          yerlerde kullanmak üzere <code>dlsym()</code> üzerinden DSO’daki belli
          simgeleri çözümlemek zorundadır. Başka bir deyişle: Çalıştırılabilir
          program ihtiyaç duyduğu her simgeyi kullanmak için kendisi çözümleme
          yapmak zorundadır. Böyle bir mekanizmanın getirisi, programın isteğe
          bağlı parçalarının gerekli olana kadar yüklenmemesidir (böylece daha az
          bellek alanı kullanılır). Gerektiği zaman programın işlevselliğini
          arttırmak amacıyla bu parçalar devingen olarak programa
          yüklenebilir.</p>
    
        <p>DSO mekanizmasının bu basit gibi görünen işleyişinde zorluk içeren bir
          adım şudur (başkaları da olabilir): Bir programın işlevselliğini
          genişletmek için DSO kullanılırken (ikinci yöntem) çalıştırılabilir
          programdan DSO için simgelerin çözümlenmesi.  Zorluğun sebebi,
          "tersine çözümleme" yapılmasıdır; çalıştırılabilir programın simge
          kümesindeki DSO simgeleri kütüphane tasarımına aykırı bir şekilde
          çözümlenir ve bu uygulama tüm platformlarda hazır olarak
          desteklenmediği gibi standartlaşmış da değildir. Geçer uygulamada
          çalıştırılabilir programın evrensel simgeleri çoğunlukla yeniden dışa
          verilmez ve bu bakımdan bir DSO içinde kullanılmaları uygun değildir.
          Esas sorun, çalıştırılabilir bir programın işlevselliğini çalışma
          anında genişletmek için DSO kullanımı sırasında ilintileyicinin tüm
          evrensel simgeleri dışa vermesini zorlamanın bir yolunu bulmaktır.</p>
    
        <p>Paylaşımlı kütüphane yaklaşımı bu bakımdan türünün tek örneğidir,
          çünkü DSO mekanizması özellikle bunun için tasarlanmıştır, dolayısıyla
          işletim sisteminin sağladığı hemen hemen tüm kütüphaneler için
          kullanılabilir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advantages" id="advantages">Getiriler ve Götürüler</a></h2>
    
        <p>Yukarıda bahsedilen DSO’ya dayalı özelliklerin getirileri
          şunlardır:</p>
    
        <ul>
          <li>Sunucu paketi çalışma anında daha esnektir çünkü, sunucuyu
            oluşturan parçalar derleme sırasında <code class="program"><a href="./programs/configure.html">configure</a></code>
            seçenekleriyle birleştirilmek yerine <code>httpd.conf</code> içinde
            <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> yönergeleri
            sayesinde çalışma anında birleştirilebilmektedir. Bu yolla, örneğin
            tek bir Apache kurulumuyla birbirinden farklı yapılandırmalara sahip
            çok sayıda sunucu çalıştırmak mümkündür. (standart veya SSL sürümü;
            basitleştirilmiş veya devingen sürümü [mod_perl, PHP3], vs.)</li>
    
          <li>Sunucu paketi kurulumdan sonra bile üçüncü parti modüllerle kolayca
            genişletilebilir. Bu özellikle, bir Apache temel paketinin yanında
            PHP, mod_perl, mod_security gibi ek paketler oluşturan paket
            dağıtıcılarına büyük yarar sağlar.</li>
    
          <li>Yeni Apache httpd modülleri için daha kolay prototip
            geliştirilebilir: Modül kaynak kodunu DSO/<code class="program"><a href="./programs/apxs.html">apxs</a></code> çifti
            sayesinde Apache httpd kaynak ağacının dışında derleyip modülün yeni
            bir sürümünü bir <code>apxs -i</code> komutunun ardından
            <code>apachectl restart</code> yaparak çalışan bir Apache HTTP
            Sunucusunda denemek daha kolay hale getirilmiştir.</li>
        </ul>
    
        <p>DSO kullanımının götürüleri ise şunlardır:</p>
    
        <ul>
          <li>İlk yüklemede %20 yavaşlama: Unix yükleyicisi simgeleri çözümlemek
            zorunda olduğundan sunucu ilk başlatılırken yaklaşık %20 daha yavaş
            faaliyete geçer.</li>
    
          <li>Çalışma sırasında % 5 yavaşlama: Konumdan bağımsız kodun (PIC -
            Position Independent Code) göreli adresleme için karmaşık oyunlara
            girmesi ve bunun mutlak adresleme kadar hızlı olmaması nedeniyle
            sunucu bazı platformlarda çalışma anında yaklaşık %5 daha yavaş
            çalışabilir.</li>
    
          <li>DSO'nun tüm modüller için uygun olmaması: DSO modülleri bazı
            platformlarda diğer DSO temelli kütüphanelerle ilintilenemediğinden
            (<code>ld -lfilanca</code>) DSO mekanizmasını tüm modül türleri için
            kullanamazsınız (örneğin a.out temelli platformlar bu işlevselliği
            ELF temelli platformlar kadar iyi sağlamaz). Başka bir deyişle, DSO
            dosyaları olarak derlenmiş modüllerin kullanabileceği simgeler ya
            Apache httpd temel kodunda vardır ya Apache httpd temel kodunun
            kullandığı C kütüphanesinde (<code>libc</code>) ve diğer durağan ve
            devingen kütüphanelerde vardır ya da konumdan bağımsız kodu içeren
            durağan kütüphane arşivlerinde (<code>libfilanca.a</code>)
            vardır. Diğer modülleri kullanmak için tek şansınız ya Apache httpd
            çekirdeğinin modüle bir atıf içermesini sağlamak ya da modül kodunu
            <code>dlopen()</code> vasıtasıyla yüklemektir.</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dso.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������httpd-2.4.64/docs/manual/dns-caveats.html.ja.utf8���������������������������������������������������0000664�0001751�0001751�00000042576�14743132254�021426� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>DNS と Apache にまつわる注意事項 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>DNS と Apache にまつわる注意事項</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>本文書の内容は次の一言に尽きます。「Apache が設定ファイルを読み込むときに
        DNS を使用する必要がないようにして下さい」。Apache が設定ファイルを
        読み込むときに DNS を使用する必要がある場合、信頼性の問題
        (起動しないかもしれません) やサービス拒否や盗用アタック
        (他のユーザからヒットを盗むことを含みます)
        の問題に直面するかもしれません。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#example">簡単な例</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#denial">サービス拒否</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#main">「主サーバ」アドレス</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#tips">以上の問題を解決する方法</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#appendix">付録: 将来的な方向性</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="example" id="example">簡単な例</a></h2>
        
    
        <div class="example"><p><code>
          &lt;VirtualHost www.abc.dom&gt; <br />
          ServerAdmin webgirl@abc.dom <br />
          DocumentRoot /www/abc <br />
          &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>Apache が正常に機能するには、バーチャルホスト毎に必ず二つの
        情報が必要になります。それは、
        <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
        と、そのサーバが応答するための IP (最低一つ) です。
        上記例では IP アドレスを含んでいませんので、Apache は DNS
        を使用して <code>www.abc.dom</code> を見つけなければなりません。
        何らかの理由で設定ファイルを読み込んでいるときに DNS 
        が利用できなかった場合、
        バーチャルホストは<strong>設定されません</strong>。
        そして、そのバーチャルホストに対するヒットには応答がなされません
        (Apache 1.2 以前では起動すらしません)。</p>
    
        <p><code>www.abc.dom</code> のアドレスが 192.0.2.1
        だとします。では、次の設定について考えてみましょう。</p>
    
        <div class="example"><p><code>
          &lt;VirtualHost 192.0.2.1&gt; <br />
          ServerAdmin webgirl@abc.dom <br />
          DocumentRoot /www/abc <br />
          &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>現在のリリースでは Apache は DNS 逆引きを使用して
        このバーチャルホストの <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
        を見つけます。
        その逆引きが失敗した場合は部分的にバーチャルホストを無効にします
        (Apache 1.2 より前では起動すらしません)。
        バーチャルホストが名前ベースであれば完全に無効になりますが、
        IP ベースであれば概ね動作します。しかしながら、サーバ名を
        含む完全な URL を生成しなければならない場合は、正しい URL
        の生成ができません。</p>
    
        <p>次の例は上記の問題を解決しています。</p>
    
        <div class="example"><p><code>
          &lt;VirtualHost 192.0.2.1&gt; <br />
          ServerName www.abc.dom <br />
          ServerAdmin webgirl@abc.dom <br />
          DocumentRoot /www/abc <br />
          &lt;/VirtualHost&gt;
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="denial" id="denial">サービス拒否</a></h2>
        
    
        <p>サービス拒否が起こる場合、(少なくとも) 二つのケースがあります。
        Apache 1.2 より前を実行している場合、バーチャルホストのための
        上記の二つの DNS 検索のうち一つ失敗すれば起動すらしません。
        そしてこの DNS 検索が自分の制御下にすらない場合もありえます。
        例えば、<code>abc.dom</code> が顧客のサーバの一つで、
        DNS は顧客自身で管理している場合、単に
        <code>www.abc.dom</code> レコードを削除するだけで、
        (1.2 より前の) サーバを起動不能にすることができます。</p>
    
        <p>もう一つのケースは、より気付きにくいものです。
        次の設定について考えてみましょう。</p>
    
        <div class="example"><p><code>
          &lt;VirtualHost www.abc.dom&gt; <br />
          <span class="indent">
            ServerAdmin webgirl@abc.dom <br />
            DocumentRoot /www/abc <br />
          </span>
          &lt;/VirtualHost&gt; <br />
          <br />
          &lt;VirtualHost www.def.dom&gt; <br />
          <span class="indent">
            ServerAdmin webguy@def.dom <br />
            DocumentRoot /www/def <br />
          </span>
          &lt;/VirtualHost&gt;
        </code></p></div>
    
        <p>192.0.2.1 を <code>www.abc.dom</code> に、
        192.0.2.2 を <code>www.def.dom</code> に割り当てているとします。
        また、<code>def.dom</code> は顧客自身の DNS
        の制御下にあるとします。この設定で、<code>abc.dom</code>
        に向けられたトラフィック全てを奪うことができる位置に
        <code>def.dom</code> を設置できています。後は単に 
        <code>www.def.dom</code> が 192.0.2.1 を参照するように
        設定するだけです。DNS は顧客側の DNS でコントロールされているので、
        <code>www.def.dom</code> レコードが好きな場所を指すように
        設定できてしまうのを止めさせることができません。</p>
    
        <p>192.0.2.1 に対するリクエスト
        (<code>http://www.abc.dom/whatever</code> 形式の URL 
        を入力したユーザからのもの全てを含みます) 
        は、<code>def.dom</code> バーチャルホストで応答されます。
        このようなことが何故起こるかもっと良く知るためには、
        応答の必要なバーチャルホストへのリクエストに対して、
        Apache がどのように整合性を確保するかについて、
        深い議論が必要になります。おおざっぱな説明は<a href="vhosts/details.html">こちら</a>に記述されています。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">「主サーバ」アドレス</a></h2>
        
    
        <p>Apache 1.1 での <a href="vhost/name-based.html">名前ベースのバーチャルホストのサポート</a> 追加の際に、
        Apache は <code class="program"><a href="./programs/httpd.html">httpd</a></code> の実行されているホストの IP
        アドレスを知る必要が出てきました。このアドレスを得るために、
        (もしあれば) グローバルな
        <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> を使用するか、
        C 言語の関数 <code>gethostname</code> (コマンドプロンプトで
        <code>hostname</code> とタイプしたときと同じものを返します)
        を呼び出すかをします。
        その後、得られたアドレスで DNS 検索を行ないます。
        現在のところ、この DNS 検索を回避する方法はありません。</p>
    
        <p>DNS サーバがダウンして、この検索ができない事態が起こることを
        恐れているのであれば、<code>/etc/hosts</code>
        にホスト名を記述しておくことができます
        (マシンが正常に起動するように既に設定されているかもしれません)。
        その場合、DNS 参照が失敗した場合にマシンが <code>/etc/hosts</code>
        を使用するように設定していることを確認してください。
        その方法は、どの OS を使用しているかに依存しますが、
        <code>/etc/resolv.conf</code> か <code>/etc/nsswitch.conf</code>
        を編集することで設定できます。</p>
    
        <p>もし他の理由で DNS を利用する必要がない場合は、
        <code>HOSTRESORDER</code> 環境変数を「 <code>local</code>
        」に設定することでそのようにできます。以上これらの事柄は、どんな
        OS 、レゾルバライブラリを使用しているかに依存します。また、
        <code class="module"><a href="./mod/mod_env.html">mod_env</a></code> を使用して環境変数を制御しない限り、
        CGI にも影響を与えます。man ページや使用している OS
        の FAQ で調べると良いでしょう。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">以上の問題を解決する方法</a></h2>
        
    
        <ul>
          <li>
            <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code>
            で IP アドレスを使用する。
          </li>
    
          <li>
            <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
            で IP アドレスを使用する。
          </li>
    
          <li>
            全てのバーチャルホストが明示的に
            <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
            を持つようにする。
          </li>
    
          <li>何も応答しない
          <code>&lt;VirtualHost _default_:*&gt;</code>
          サーバを作る。</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="appendix" id="appendix">付録: 将来的な方向性</a></h2>
        
    
        <p>DNS に関して、現状は全く宜しくありません。Apache 1.2 で、
        DNS のイベントが失敗しても少なくとも起動プロセスが続くようにしましたが、
        これが最高の解決方法ではないでしょう。アドレスの再割り当てが必要不可避
        となっている今日のインターネットにおいては、
        設定ファイルの中で明示的な IP アドレスを要求する仕様は、
        全く宜しくありません。</p>
    
        <p>盗用のサービスアタックに関して行なうべき事は、
        DNS 順引きを行なって得られたアドレスに対する DNS 
        逆引きを行なって、二つの名前を比較することです。
        この二つが一致しなければバーチャルホストは無効になるようにします。
        こうするためには逆引き DNS が適切に設定されている必要があります
        (FTP サーバや TCP ラッパーのおかげで「二重逆引き」DNS は一般的に
        なっていますので、管理者にはお馴染みものでしょう)。</p>
    
        <p>IP アドレスが使用されていなくて DNS が失敗した場合は、
        どうしてもバーチャルホストウェブサーバを信頼性を確保して
        起動させることは不可能のようです。
        設定の一部を無効にするというような部分的な解決では、
        サーバが何をするようにするかにもよりますが、
        そのサーバが起動しないより確実に悪い状況になるでしょう。</p>
    
        <p>HTTP/1.1 が開発され、ブラウザやプロキシが <code>Host</code>
        ヘッダを発行するようになったので、IP ベースのバーチャルホストを
        全く使用しなくても済むようになるかもしれません。
        この場合、ウェブサーバは設定中に DNS 参照をしなくても済みます。
        しかし 1997 年 3 月時点の状況では、
        商用レベルのウェブサーバで使用できるほどには、
        これらの機能は広く開発が進んでいません。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dns-caveats.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dso.html.ko.euc-kr���������������������������������������������������������0000664�0001751�0001751�00000041136�14743132254�020311� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ü (DSO)  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ü (DSO) </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>ġ  ڰ  Ͽ  
           ִ ȭ α׷̴.  Ҷ
        <code>httpd</code> Ͽ   
         ִ. ƴϸ  <code>httpd</code> ϰ
        иϿ ü(Dynamic Shared Objects, DSO) 
         ִ. DSO   Ҷ ϰų, Apache
        Extension Tool (<a href="programs/apxs.html">apxs</a>)
        Ͽ ߿ Ͽ ߰  ִ.</p>
    
        <p>  DSO    ̷ Ѵ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#implementation"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#background"></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#advantages"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation"></a></h2>
    
    <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>ġ ٽɿ  ؾ
        <code class="module"><a href="./mod/mod_so.c.html">mod_so.c</a></code>  ġ 
        о̱ DSO Ѵ.
          <code class="module"><a href="./mod/core.html">core</a></code> ϰ DSO
            ̴.  ٸ  ġ 
        <a href="install.html">ġ </a> 
        <code>configure</code> <code>--enable-<em>module</em>=shared</code>
        ɼ Ͽ DSO   ִ. 
        <code>mod_foo.so</code>  DSO  <code>httpd.conf</code>
        Ͽ <code class="module"><a href="./mod/mod_so.html">mod_so</a></code>
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> ɾ
        Ͽ  ۽ Ȥ ۽   о 
        ִ.</p>
    
        <p>ġ (Ư ڰ  )  DSO  
         <a href="programs/apxs.html">apxs</a> (<em>APache
        eXtenSion</em>) ο  α׷ ִ.  α׷
        ġ ҽ Ʈ <em>ۿ</em> DSO  
        Ҷ Ѵ.  . ġ ġҶ
        <code>configure</code> <code>make install</code>
        ġ C  ġϰ, DSO  ϱ
        ÷ Ư Ϸ ɼǰ Ŀ ɼ <code>apxs</code>
        α׷ Ѵ. ׷ <code>apxs</code> ϴ ڴ
        ġ  ҽ Ʈ,  DSO   ÷ Ư
        Ϸ ɼǿ Ŀ ɼǿ Ű ʰ ڽ ġ
         ҽ   ִ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage"> </a></h2>
    
        <p>Apache 2.2 DSO ɿ  ª  ̴:</p>
    
        <ol>
          <li>
            <em> ִ</em> ġ  ϰ ġϴ
            .   <code>mod_foo.c</code> DSO
            <code>mod_foo.so</code>:
    
    <div class="example"><p><code>
    $ ./configure --prefix=/path/to/install --enable-foo=shared<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
            <em>ڰ </em> ġ  ϰ ġϴ
            .   <code>mod_foo.c</code> DSO
            <code>mod_foo.so</code>:
    
    <div class="example"><p><code>
    $ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c --enable-foo=shared<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
              <em>߿ ϱ</em> ġ ϴ
            :
    
    <div class="example"><p><code>
    $ ./configure --enable-so<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
            <em>ڰ </em> ġ  ϰ ġϴ
            . <a href="programs/apxs.html">apxs</a> Ͽ
            ġ ҽ Ʈ <em>ۿ</em> <code>mod_foo.c</code>
            DSO <code>mod_foo.so</code>:
    
    <div class="example"><p><code>
    $ cd /path/to/3rdparty<br />
    $ apxs -c mod_foo.c<br />
    $ apxs -i -a -n foo mod_foo.la
    </code></p></div>
          </li>
        </ol>
    
        <p>  ϴ   ϵǸ, <code>httpd.conf</code>
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> þ
        Ͽ ġ   о̰ .</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="background" id="background"></a></h2>
    
        <p> н <em>ü</em> (DSO)
         ŷ/ε(dynamic linking/loading)̶ Ͽ, Ư
         ڵ    α׷
        ּҰ о̴   ִ.</p>
    
        <p> ΰ  о  ִ. ϳ α׷
        Ҷ <code>ld.so</code> ý α׷ ڵ
        о̴ , ٸ ϳ  α׷
        <code>dlopen()/dlsym()</code> ýȣ н δ(loader)
        ý ̽ Ͽ  о̴ .</p>
    
        <p>ù°  DSO  <em>̺귯(shared libraries)</em>
        Ȥ <em>DSO ̺귯</em> θ, 
        <code>libfoo.so</code> <code>libfoo.so.1.2</code> 
        ̸ . ̵ ý 丮( <code>/usr/lib</code>)
        ְ, Ͻ Ŀ ɾ <code>-lfoo</code> ־
        ϰ Ѵ. ̷   ̺귯 Ͽ
        ǿ, α׷ Ҷ Ŀ ɼ <code>-R</code>
          , ȯ溯 <code>LD_LIBRARY_PATH</code>
          Ȥ <code>/usr/lib</code> н δ
        <code>libfoo.so</code> ã  ִ. ׷ α׷
        ( ã(unresolved)) ɺ(symbol) DSO ãԵȴ.</p>
    
        <p>DSO  α׷ ɺ ãʱ  (DSO
        밡 Ϲ ڵ ̺귯̹Ƿ) ã ⼭
        . н δ ɺ ã⸦  ϹǷ α׷
         DSO ɺ ã ʿ䰡 . ( <code>ld.so</code>
        θ ڵ  ƴ  α׷ ũǴ 
        ڵ Ϻδ.)  ̺귯 ڵ带  о̴
         Ȯϴ. ̺귯 ڵ尡  α׷ ߺؼ
        Ǵ  <code>libc.so</code>  ý ̺귯
        ѹ DZ  ũ  ȴ.</p>
    
        <p>ι°  DSO  <em>ü(shared objects)</em>
        Ȥ <em>DSO </em>̶ θ, (Ģ ̸
        <code>foo.so</code>)  Ȯڴ Ӵ. 
        ϵ  α׷ ü 丮 ġϰ α׷
        ڵ  ʴ´.  α׷ 
        <code>dlopen()</code> Ͽ DSO ּҰ
         о鿩 Ѵ. ̶ α׷ DSO ɺ
        ã ʴ´.  տ  н δ ڵ ϰ
         ̹ о DSO ̺귯(Ư ׻ ϴ
        <code>libc.so</code>  ɺ) DSO ( ã)
        ɺ ã´. ׷ DSO ġ ó α׷
         ũȰͰ   ɺ ˰Եȴ.</p>
    
        <p>DSO API ̿ϱؼ  α׷
        <code>dlsym()</code> DSO Ư ɺ ãƼ, 
        ϱ ġ(dispatch) ǥ <em></em> Ѵ.
        ٸ  α׷   Ǻ  ãƾѴ.
        ̷   α׷ Ϻθ α׷
        ʿҶ о ʾƵ (׷ ޸𸮸 
        ʰ) ȴٴ ̴. ⺻ α׷  Ȯϱ
        ʿ   κ  о  ִ.</p>
    
        <p>̷ DSO  ڿ , ּ  
        Ѱִ. α׷ Ȯϱ DSO Ҷ DSO
        α׷ ɺ ã ̴. ? DSO α׷
        ɺ " ã " (̺귯 ڽ ϴ α׷
         𸥴ٴ) ̺귯 迡 ϸ,  ÷
        ʰ ǥȭ ʾұ ̴.  
        ɺ(global symbol)  ͽƮ(export) ʱ⶧
        DSO   . DSO Ͽ  α׷ ȮϷ
        Ŀ  ɺ ͽƮϵ ϴ  ֵ
        ذå̴.</p>
    
        <p>̺귯 DSO  Ģ ̱⶧
        ü ϴ    ̺귯 Ѵ.
        ݴ  α׷ α׷ Ȯϱ ü
         ʴ´.</p>
    
        <p>1998    Ȯϱ DSO  
        Ʈ Ű (XS  DynaLoader  )
        Perl 5, Netscape Server <em></em> 幰. ġ
        ̹  Ȯϱ   ߰ ܺ 
        ġ ٽɱɿ ϱ  ġ
        ̿ ٹ ߱⶧ 1.3   뿭 շߴ.
        ׷ ġ   о̴µ DSO ϵ
        .</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advantages" id="advantages"></a></h2>
    
        <p>տ  DSO ϸ    ִ:</p>
    
        <ul>
          <li>  μ Ͻ <code>configure</code>
          ɼǴ <code>httpd.conf</code> <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> Ͽ ߿
          յǹǷ  Ű   ϴ.   ѹ
          ġ ġ ٸ (ǥ  SSL , ּȭ
           ߰  [mod_perl, PHP3] <em></em>) 
           ִ.</li>
    
          <li> ġĿ ڰ   Ͽ 
          Ȯ  ִ. ּ  Ű ڴ ġ ٽ
          Ű  PHP3, mod_perl, mod_fastcgi <em></em>
          ߰ Ű   ־ ū ̵̴.</li>
    
          <li>DSO <code>apxs</code>  ġ ҽ Ʈ ۿ
          ۾ϰ <code>apxs -i</code> <code>apachectl restart</code>
          ɾ       ġ
           ݿ  ־   ġ   
          ִ.</li>
        </ul>
    
        <p>DSO    ִ:</p>
    
        <ul>
          <li>α׷ ּҰ ڵ带  о̴ 
          ʴ ü ֱ   ÷ DSO
            .</li>
    
          <li>н δ ɺ ãƾϱ   
           20%  ʾ.</li>
    
          <li> ġڵ(position independent code, PIC)
           ּ(absolute addressing) 
          ּ(relative addressing)   
          ʿϹǷ  ÷   5%  ʴ.</li>
    
          <li>DSO  ٸ DSO ̺귯(<code>ld -lfoo</code>)
          ũ   ÷ ֱ⶧ (  ELF
          ÷  a.out ÷   
           ʴ´)   ⿡ DSO   .
          ٸ  DSO Ϸ ϴ  ġ ٽɰ ġ
          ٽ ϴ C ̺귯(<code>libc</code>) ٸ
          / ̺귯, ġڵ带  ִ  ̺귯
          ī̺(<code>libfoo.a</code>) ɺ   ִ.
          ٸ ڵ带 Ϸ ġ ٽ װ ϴ,
          <code>dlopen()</code>  ڵ带 о鿩 Ѵ.</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dso.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/suexec.html����������������������������������������������������������������0000664�0001751�0001751�00000000720�13710016232�017203� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: suexec.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: suexec.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: suexec.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: suexec.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: suexec.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������httpd-2.4.64/docs/manual/filter.html.ja.utf8��������������������������������������������������������0000664�0001751�0001751�00000022354�14743132254�020473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>フィルタ - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>フィルタ</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>Apache でのフィルタの使い方について記述しています。</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="filters" id="filters">フィルタ</a></h2>
        
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilteroptions">ExtFilterOptions</a></code></li><li><code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code></li><li><code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code></li></ul></td></tr></table>
    
        <p><em>フィルタ</em> とは、サーバが送受信したデータに
        適用される処理プロセスのことをいいます。クライアントからサーバに
        送られたデータは <em>入力フィルタ</em> によって、サーバから
        クライアントに送られるデータは<em>出力フィルタ</em>によって
        処理されます。複数のフィルタを適用することができ、
        その順番を厳密に指定することもできます。</p>
    
        <p>Apache 内部では、チャンク (データのぶつ切り) を行ったり、
        バイト範囲の指定されたリクエストを扱ったりといった機能を
        行う際に、フィルタが使われています。それに加えて、
        実行時の設定ディレクティブで選択が可能なフィルタを
        モジュールが提供できます。
        データに適応されるフィルタのセットは、
        <code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code>,
        <code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code>,
        <code class="directive"><a href="./mod/core.html#addinputfilter">AddInputFilter</a></code>,
        <code class="directive"><a href="./mod/core.html#addoutputfilter">AddOutputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code>
        ディレクティブで制御できます。</p>
    
        <p>現行の Apache HTTP サーバの配布では、
        次のユーザ選択可能なフィルタが提供されています。</p>
    
        <dl>
          <dt>INCLUDES</dt>
          <dd><code class="module"><a href="./mod/mod_include.html">mod_include</a></code> で Server-Side Include をします。</dd>
          <dt>DEFLATE</dt>
          <dd><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code>
          を使って、クライアントに送信する前に出力を圧縮します。</dd>
        </dl>
    
        <p>また、<code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> モジュールで
        外部プログラムをフィルタとして指定することができます。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/filter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/env.html.tr.utf8�����������������������������������������������������������0000664�0001751�0001751�00000101513�14743132254�020024� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache’de Ortam Değişkenleri - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache’de Ortam Değişkenleri</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.</div>
    
        <p>Apache HTTP Sunucusunu etkileyen ortam değişkenleri iki çeşittir.</p>
    
        <p>İlki, işletim sisteminin denetimindeki ortam değişkenleridir. Bu
          değişkenlere değer atama işlemi sunucu başlatılmadan önce yapılır.
          Bunlar yapılandırma dosyalarının içinde kullanılabilir. Ayrıca,
          istenirse PassEnv yönergesi kullanılarak bunlar CGI betiklerine ve
          SSI sayfalarına da aktarılabilir.</p>
    
        <p>İkincisi ise, Apache HTTP Sunucusunun kendi ortam değişkenleridir.
          Bu değişkenlerde saklanan bilgi erişim denetimi, günlük kaydı gibi
          çeşitli işlemleri denetlemekte kullanılabilir. Değişkenler ayrıca, CGI
          betikleri gibi harici uygulamalarla iletişim mekanizması olarak da
          kullanılabilir. Bu belgede bu değişkenler üzerindeki işlemlere ve
          kullanım şekillerine değinilmiştir.</p>
    
        <p>Bu değişkenlere <em>ortam değişkenleri</em> dense de işletim sisteminin
          ortam değişkenleri gibi değillerdir. Bunlar sadece Apache ortamında
          geçerli değişkenler olup işletim sisteminin bu değişkenlerden haberi
          olmaz. Sadece CGI betikleri ve SSI sayfaları gibi harici uygulamalar
          tarafından üretilen ortam değişkenleri sistem ortamının değişkenleri
          haline gelirler. İşletim sistemi ortamına çalışmakta olan sunucudan
          müdahale etmek isterseniz işletim sisteminizin kabuğu tarafından sağlanan
          standart ortam müdahale mekanizmalarını kullanmalısınız.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#setting">Ortam Değişkenlerinin Atanması</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Ortam Değişkenlerinin Kullanımı</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#special">Özel Amaçlı Ortam Değişkenleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Örnekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setting" id="setting">Ortam Değişkenlerinin Atanması</a></h2>
        
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_env.html">mod_env</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li><li><code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifnocase">SetEnvIfNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#unsetenv">UnsetEnv</a></code></li></ul></td></tr></table>
    
        <h3><a name="basic-manipulation" id="basic-manipulation">Temel Ortamda Değişiklik</a></h3>
            
    
            <p>Apache ortamında bir ortam değişkenine müdahale etmenin en temel
              yolu hiçbir koşula tabi olmayan <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> yönergesini kullanmaktır. Bu değişkenleri Apache
              başlatılırken sistem ortam değişkenleri haline getirmek için
              <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> yönergesi
              kullanılabilir.</p>
    
        
        <h3><a name="conditional" id="conditional">İsteğe Bağlı Şartlı Atamalar</a></h3>
            
    
            <p>Esnekliği arttırmak için, <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> modülü ile
              isteğin özelliklerine uygun olarak her isteğe özel değişkenler
              atayabilmek mümkün kılınmıştır. Örneğin, bir değişken sadece isteği
              yapan tarayıcıya özgü bir değerle veya sadece belli bir başlık
              alanınına bağlı olarak atanabilir. Daha da esnek bir mekanizma,
              ortam değişkeni atamak için <code>[E=...]</code> seçeneğinin
              kullanıldığı <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> modülünün <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> yönergesi ile
              sağlanmıştır.</p>
    
        
        <h3><a name="unique-identifiers" id="unique-identifiers">Eşsiz Betimleyiciler</a></h3>
            
    
            <p>Son olarak, <code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code> <code>UNIQUE_ID</code>
              ortam değişkenine her istek için o isteğin çok özel koşullar altında
              tüm diğer istekler arasında eşsizliğini garanti edecek bir değer
              atar.</p>
    
        
        <h3><a name="standard-cgi" id="standard-cgi">Standart CGI Değişkenleri</a></h3>
            
    
            <p>Apache yapılandırmasıyla atanan ve kabuğa aktarılan ortam
              değişkenlerinden başka <a href="http://www.ietf.org/rfc/rfc3875">CGI
              Belirtimi</a>nin gerektirdiği istekler hakkında temel bilgileri
              içeren ortam değişkenlerinin CGI betikleri ve SSI sayfalarınca
              atanabilmesi sağlanmıştır.</p>
    
        
        <h3><a name="caveats" id="caveats">Bazı Yetersizlikler</a></h3>
            
    
            <ul>
              <li>Standart CGI değişkenlerini ortam değişkenlerine müdahale
                yönergelerini kullanarak değiştirmek veya geçersiz kılmak mümkün
                değildir.</li>
    
              <li>CGI betiklerini çalıştırmak için <code class="program"><a href="./programs/suexec.html">suexec</a></code>
                kullanıldığında ortam, CGI betikleri çalıştırılmadan önce
                <em>güvenilir</em> değişkenler kalacak şekilde temizlenir.
                <em>Güvenilir</em> değişken listesi <code>suexec.c</code> içinde
                derleme sırasında tanımlanır.</li>
    
              <li>Taşınabilirlik adına, ortam değişkenlerinin isimleri sadece
                harfler, rakamlar ve alt çizgi imlerini içerebilir. Bunlara ek
                olarak ismin ilk karakteri bir rakam olmamalıdır. Değişkenler CGI
                betiklerine ve SSI sayfalarına aktarılırken bu sınırlamalara uygun
                olmayan karakterlerin yerlerine alt çizgi imleri konur.</li>
    
              <li>Bir özel durum, CGI betiklerine ve benzerlerine ortam
                değişkenleri üzerinden aktarılan HTTP başlıklarıdır (aşağıya
                bakın). Bunlar büyük harfe dönüştürülür ve sadece tireler
                altçizgilere dönüştürülür. Eğer HTTP başlığı geçersiz karakter
                içeriyorsa başlığın tamamı yoksayılır. Böyle bir durumda ne
                yapılacağı öğrenmek için <a href="#fixheader">aşağıya</a>
                bakın.</li>
    
              <li>İsteklerin işleme konması sırasında <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> yönergesi geç çalıştırılır,
                yani <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> ve
                <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> gibi
                yönergeler <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> ile
                atanan değişken değerlerini görmezler.</li>
    
              <li><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code> ile dizin listesi oluşturulması
                veya bir <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>
                için yol aranması gibi bir dahili <a class="glossarylink" href="./glossary.html#subrequest" title="sözlüğe bakınız">alt
                istek</a> için sunucu yol araması yaparken isteklere özgü
                ortam değişkenleri alt istekler tarafından miras alınMAZ. Buna ek
                olarak, <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> modülünün devreye girdiği API
                fazlarından dolayı yapılan alt isteklerde
                <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> yönergeleri
                ayrı ayrı değerlendirilMEZ.</li>
          </ul>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Ortam Değişkenlerinin Kullanımı</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_access_compat.html#allow">Allow</a></code></li><li><code class="directive"><a href="./mod/mod_access_compat.html#deny">Deny</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li></ul></td></tr></table>
    
        <h3><a name="cgi-scripts" id="cgi-scripts">CGI Betikleri</a></h3>
            
    
            <p>Ortam değişkenlerinin başlıca amaçlarından biri CGI betikleriyle
              iletişim kurmaktır. Yukarıda bahsedildiği gibi CGI betiklerine
              aktarılan ortam Apache yapılandırmasında atanan değişkenlere ek
              olarak istek hakkında standart temel bilgileri de içerir. Bu konuda
              ayrıntılı bilgi edinmek için <a href="howto/cgi.html">CGI
              Öğreticisi</a>ne bakabilirsiniz.</p>
    
        
        <h3><a name="ssi-pages" id="ssi-pages">SSI Sayfaları</a></h3>
            
    
            <p>Sunucu tarafında <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> modülünün
              <code>INCLUDES</code> süzgeci ile yorumlanan SSI sayfalarında ortam
              değişkenleri <code>echo</code> elemanı ile basılabilir ve sayfayı
              isteğin özelliklerine uygun olarak oluşturmak için ortam
              değişkenleri akış denetim elemanları içinde kullanılabilir. Apache
              ayrıca, yukarıda bahsedildiği gibi standart CGI ortam değişkenli SSI
              sayfalarını da sağlayabilmektedir. Daha ayrıntılı bilgi edinmek için
              <a href="howto/ssi.html">SSI Öğreticisi</a>ne bakabilirsiniz.</p>
    
        
        <h3><a name="access-control" id="access-control">Erişim Denetimi</a></h3>
            
    
            <p><code>Require env</code> ve <code>Require not env</code>
              yönergeleri sayesinde ortam değişkenlerine dayalı olarak sunucuya
              erişim denetim altında tutulabilir. Bunlar <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> yönergesi ile birlikte
              kullanılmak suretiyle sunucuya erişim isteğin özelliklerine bağlı
              olarak daha esnek bir tarzda denetlenebilir. Örneğin, belli bir
              tarayıcının sunucuya erişimi bu yönergelerle engellenebilir.</p>
    
        
        <h3><a name="logging" id="logging">Şartlı Günlük Kaydı</a></h3>
            
    
            <p>Ortam değişkenleri <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> yönergesinin <code>%e</code> seçeneği
              kullanılarak erişim günlüğüne kaydedilebilir. Bundan başka,
              <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> yönergesi
              sayesinde isteklerin günlüğe kaydedilip kaydedilmeyeceğine ortam
              değişkenlerine dayalı olarak karar verilmesi sağlanabilir. Bunlar
              <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> yönergesi ile
              birlikte kullanılmak suretiyle günlük kayıtları isteğin
              özelliklerine bağlı olarak daha esnek bir tarzda denetlenebilir.
              Örneğin, <code>gif</code> uzantılı dosyalar için yapılan isteklerin
              günlüğe kaydedilmemesi veya sadece alt ağınızın dışından gelen
              isteklerin günlüğe kaydedilmesini isteyebilirsiniz.</p>
    
        
        <h3><a name="response-headers" id="response-headers">Şartlı Yanıt Başlıkları</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> yönergesi belli
              bir yanıt başlığının istemciye gönderilip gönderilmeyeceğine belli
              bir ortam değişkeninin varlığına bakarak karar vermek için
              kullanılabilir. Böylece örneğin, belli bir başlığın istemciye
              gönderilmesine istemciden belli bir başlığın alınıp alınmadığına
              bağlı olarak karar verilebilir.</p>
    
        
    
        <h3><a name="external-filter" id="external-filter">Harici Süzgeçlerin Etkinleştirilmesi</a></h3>
            
    
            <p><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> tarafından yapılandırılan harici
              süzgeçler <code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code> yönergesinin <code>disableenv=</code> ve
              <code>enableenv=</code> seçenekleri kullanılarak bir ortam
              değişkenine bağlı olarak etkinleştirilebilir.</p>
        
    
        <h3><a name="url-rewriting" id="url-rewriting">URL Kurgulaması</a></h3>
            
    
            <p><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
              yönergesinin <em>SınamaDizgesi</em> olarak kullanılan
              <code>%{ENV:<em>değişken</em>}</code> biçemi
              <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> yeniden yazma motorunun ortam
              değişkenlerine bağlı kararlar almasını mümkün kılar. Yalnız şuna
              dikkat ediniz: <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>’ta <code>ENV:</code>
              öneki kullanılmadan belirtilen değişkenler ortam değişkenleri
              değillerdir. Onlar <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>’a özgü diğer
              modüllerden erişilemeyen özel değişkenlerdir.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="special" id="special">Özel Amaçlı Ortam Değişkenleri</a></h2>
        
    
            <p>Birlikte çalışabilirlik sorunları Apache’nin belli istemcilerle
              veri alışverişi sırasında davranışını değiştirmesini gerektirebilir.
              Genellikle <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> ve
              <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> yönergelerinden
              başka <code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code>
              gibi yönergelerle ortam değişkenleri atanarak bunu sağlayan
              mekanizmaların olabildiğince esnek davranabilmesi sağlanabilir.</p>
    
        <h3><a name="downgrade" id="downgrade"><code>downgrade-1.0</code></a></h3>
            
    
            <p>İstek, daha yüksek bir HTTP protokolüyle yapılmış olsa bile
              HTTP/1.0 isteği olarak ele alınır.</p>
    
        
        <h3><a name="force-gzip" id="force-gzip"><code>force-gzip</code></a></h3>
            
              <p><code>DEFLATE</code> süzgeci etkinse tarayıcının tercih ettiği
                kodlama koşulsuz olarak yoksayılarak sıkıştırılmış çıktı
                gönderilir.</p>
        
        <h3><a name="force-no-vary" id="force-no-vary"><code>force-no-vary</code></a></h3>
            
    
            <p>İstemciye gönderilmeden önce yanıttan <code>Vary</code> alanının
              çıkarılmasına sebep olur. Bazı istemciler bu alanı gerektiği gibi
              yorumlayamazlar, bu değişken atanarak bu sorunla karşılaşılmamaya
              çalışılır. Bu değişkenin atanması ayrıca
              <strong>force-response-1.0</strong> değişkeninin de atanmasına sebep
              olur.</p>
    
        
        <h3><a name="force-response" id="force-response"><code>force-response-1.0</code></a></h3>
            
    
          <p>HTTP/1.0 isteği yapan istemcilere HTTP/1.0 yanıtı verilmesini zorunlu
            kılar. AOL vekillerindeki bir sorun nedeniyle gerçeklenmiştir. Bazı
            HTTP/1.0 istemciler HTTP/1.1 yanıtlarında doğru davranmayabilirler; bu
            değişken atanarak bunların sorunları giderilebilir.</p>
    
        
    
        <h3><a name="gzip-only-text-html" id="gzip-only-text-html"><code>gzip-only-text/html</code></a></h3>
            
    
            <p>Bu değişkene "1" değeri atandığında <code>text/html</code>’den
              farklı içerik türleri için <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> modülü
              tarafından sağlanan <code>DEFLATE</code>  çıktı süzgeci iptal
              edilir. Sıkıştırılmış olarak saklanan dosyalar kullanıyorsanız bu
              değişkeni <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> modülü de dikkate alır
              (kimliğine bakarak sadece gzip için değil, tüm kodlamalar için bunu
              yapar).</p>
        
    
        <h3><a name="no-gzip" id="no-gzip"><code>no-gzip</code></a></h3>
    
            <p>Bu değişken atandığında, <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> modülünün
              <code>DEFLATE</code> süzgeci kapatılır ve
              <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> modülü kodlanmış kaynak teslimatını
              reddeder.</p>
    
        
    
        <h3><a name="no-cache" id="no-cache">no-cache</a></h3>
            <p><em>2.2.12 sürümünden beri kullanılabilmektedir.</em></p>
    
            <p>Atandığı takdirde, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> artık
            önbelleklenebilecek yanıtları kaydetmeyecektir. Bu ortam değişkeni bir
            yanıtın halihazırda mevcut bir isteğe sunulmak üzere önbellekte olup
            olmadığından etkilenmez.</p>
    
        
    
        <h3><a name="nokeepalive" id="nokeepalive"><code>nokeepalive</code></a></h3>
            
    
            <p>Bu değişken atandığında, <code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code> yönergesi iptal edilir.</p>
    
        
    
        <h3><a name="prefer-language" id="prefer-language"><code>prefer-language</code></a></h3>
            
    
            <p>Değer olarak <code>en</code>, <code>ja</code> veya
              <code>x-klingon</code> gibi bir dil kısaltması verilerek atanmışsa
              <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> modülünün normal davranışını
              değiştirerek belirtilen dilde bir teslimat yapılmaya çalışılır.
              Böyle bir belge yoksa normal <a href="content-negotiation.html">uzlaşım</a> süreci uygulanır.</p>
    
        
    
        <h3><a name="redirect-carefully" id="redirect-carefully"><code>redirect-carefully</code></a></h3>
            
    
            <p>İstemciye bir yönlendirme gönderirken sunucuyu daha dikkatli olmaya
              zorlar. Bu genellikle istemcinin yönlendirmeler konusunda sorunlu
              olduğu bilindiği takdirde yararlı olur. Bu değişkenin gerçeklenme
              sebebi, dizin kaynaklarına yönlendirmeler için DAV yöntemlerini
              kullanan Microsoft'un WebFolders yazılımındaki bir sorundur.</p>
    
        
    
       <h3><a name="suppress-error-charset" id="suppress-error-charset"><code>suppress-error-charset</code></a></h3>
           
    
        <p><em>2.0.54 sürümünden beri mevcuttur.</em></p>
    
        <p>Apache bir isteğe bir yönlendirme ile yanıt verdiğinde istemci
          yönlendirmeyi kendiliğinden yapmaz veya yapamazsa kullanıcıya yanıtla
          birlikte gönderilen metin gösterilir. Apache normal olarak bu metni
          ISO-8859-1 ile kodlar.</p>
    
        <p>Ancak, yönlendirmenin yapıldığı sayfa farklı bir karakter kümesine
          sahipse bazı tarayıcı sürümleri asıl sayfanın karakter kodlaması yerine
          yönlendirmenin kodlamasını kullanmaya çalışırlar. Bu özellikle Yunanca
          gibi dillerde hedef sayfanın hatalı yorumlanmasına yol açar.</p>
    
        <p>Bu ortam değişkeninin atanması Apache’nin yönlendirme için karakter
          kümesi belirtmemesini sağlamak suretiyle hatalı tarayıcıların hedef
          sayfayı yanlış karakter kodlamasıyla yorumlamasını önler.</p>
    
        <div class="warning">
          <h3>Güvenlik Uyarısı</h3>
    
          <p>Hata sayfalarının bir karakter kümesi belirtilmeksizin yollanması,
            HTTP/1.1 belirtimine uymayan ve karakter kümesini içeriğe bakarak
            tahmin etmeye çalışan tarayıcılarda (MSIE) karşı siteden betik
            saldırısı yorumuna sebep olabilir.  Girdi verisindeki UTF-7 içerik
            (istek betimleyici gibi) karşı siteden betik saldırılarını engellemek
            için tasarlanmış normal önceleme mekanizmalarıyla öncelenmeyeceği için
            böyle tarayıcılar UTF-7 karakter kodlaması kullanılarak kolayca
            aldatılabilir.</p>
        </div>
    
       
    
       <h3><a name="proxy" id="proxy"><code>force-proxy-request-1.0</code>,
        <code>proxy-nokeepalive</code>, <code>proxy-sendchunked</code> ve
        <code>proxy-sendcl</code>, <code>proxy-chain-auth</code>,
        <code>proxy-interim-response</code>, <code>proxy-initial-not-pooled</code>
        </a></h3>
    
       <p>Bu yönergeler <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> modülünün normal protokol
        davranışını değiştirirler. Daha ayrıntılı bilgi için
        <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> ve <code class="module"><a href="./mod/mod_proxy_http.html">mod_proxy_http</a></code>
        belgelerine bakınız.</p>
       
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Örnekler</a></h2>
        
    
        <h3><a name="fixheader" id="fixheader">Bozuk başlıkların CGI betiklerine aktarılması</a></h3>
          
    
          <p>2.4 sürümünden itibaren, <code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code> modülü ve diğer
            modüllerde HTTP başlıklarının ortam değişkenlerine dönüştürülmesi
            bağlamında Apache daha seçici davranmaktadır. Önce HTTP başlığındaki
            geçersiz karakterlerin tamamı altçizgilere dönüştürülür. Bu, başlık
            zerki yoluyla yapılan karşı-site-betiklerini-çalıştırma saldırısını
            önlemeye yöneliktir. (Bakınız: <a href="http://events.ccc.de/congress/2007/Fahrplan/events/2212.en.html">Unusual Web Bugs</a>, slide 19/20).</p>
    
          <p>Bozuk başlıklar gönderdiği halde bunlara dokunulmamasını gerektiren
            bir istemciniz varsa, <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> ve
            <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> modüllerinin sunduğu yapıyı örnekteki gibi
            kullanarak bu sorunun üstesinden gelebilirsiniz:</p>
    
          <pre class="prettyprint lang-config">#
    # Aşağıdaki satırlarla bir istemcinin gönderdiği bozuk
    # Accept_Encoding başlıklarının istenildiği gibi işlenmesi
    # sağlanabilir.
    #
    SetEnvIfNoCase ^Accept.Encoding$ ^(.*)$ fix_accept_encoding=$1
    RequestHeader set Accept-Encoding %{fix_accept_encoding}e env=fix_accept_encoding</pre>
    
    
        
    
        <h3><a name="misbehaving" id="misbehaving">Protokolü yanlış yorumlayan tarayıcıların davranışlarının
            değiştirilmesi</a></h3>
            
    
            <p>Önceki sürümlerde bilinen istemci davranışlarına karşı önlem olarak
              aşağıdaki satırların <code>httpd.conf</code> içinde bulunması
              önerilirdi. Fakat, böyle tarayıcılar artık ortalıkta görünmediğinden
              bu yapılandırmaya da artık gerek kalmamıştır.</p>
    
            <pre class="prettyprint lang-config">#
    # Aşağıdaki yönergeler normal HTTP yanıt davranışını değiştirirler.
    # İlk yönerge Netscape 2.x ve kendini öyle gösteren tarayıcılar için
    # kalıcı bağlantıyı (keepalive) iptal eder. İkinci yönerge ise HTTP/1.1
    # protokolü bozuk olan ve 301/302 durum kodlu yönlendirme yanıtları
    # kullanıldığında kalıcı bağlantıları gerektiği gibi desteklemeyen
    # Microsoft Internet Explorer 4.0b2 içindir.
    #
    BrowserMatch "Mozilla/2" nokeepalive
    BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    
    #
    # Aşağıdaki yönergeler HTTP/1.0 yanıtlarından başkasına yabancı olan
    # tarayıcılara HTTP/1.1 yanıtlarının gönderilmesini iptal eder.
    #
    BrowserMatch "RealPlayer 4\.0" force-response-1.0
    BrowserMatch "Java/1\.0" force-response-1.0
    BrowserMatch "JDK/1\.0" force-response-1.0</pre>
    
    
        
        <h3><a name="no-img-log" id="no-img-log">Resim isteklerinin erişim günlüğüne kaydedilmemesi</a></h3>
            
    
            <p>Bu örnek resim isteklerinin erişim günlüğüne yazılmasını engeller.
              Bu örnek değiştirilerek belli dizinlerin veya belli konaklardan
              gelen isteklerin günlüğe kaydedilmesini engellemek amacıyla da
              kullanılabilir.</p>
    
            <pre class="prettyprint lang-config">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</pre>
    
    
    
        
        <h3><a name="image-theft" id="image-theft">“Resim Hırsızlığı” için önlem alınması</a></h3>
            
    
            <p>Bu örnekte sunucunuzda bulunmayan sayfalarda sunucunuzdaki
              resimlerin kullanılmasının nasıl önleneceği gösterilmiştir. Bu
              yapılandırma önerilmemekle birlikte nadir durumlarda işe yarar. Tüm
              resimlerin <code>/siteler/resimler</code> dizini altında tutulduğu
              varsayılmıştır.</p>
    
            <pre class="prettyprint lang-config">SetEnvIf Referer "^http://www\.example\.com/" local_referal
    # Referrer bilgisi göndermeyen tarayıcılara izin verelim
    SetEnvIf Referer "^$" local_referal
    &lt;Directory "/siteler/resimler"&gt;
      Require env local_referal
    &lt;/Directory&gt;</pre>
    
    
            <p>Bu teknik hakkında daha ayrıntılı bilgi edinmek için ServerWatch
              üzerindeki  "<a href="http://www.serverwatch.com/tutorials/article.php/1132731">Diğer sitelerin sizin resimlerinizle donatılmasını engellemek</a>"
              belgesine bakınız.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/env.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html���������������������������������������������������������������0000664�0001751�0001751�00000001340�13710016232�017350� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: sitemap.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: sitemap.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: sitemap.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: sitemap.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: sitemap.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: sitemap.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html.ja.utf8�������������������������������������������������������0000664�0001751�0001751�00000032562�14743132254�020625� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache のハンドラの使用 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache のハンドラの使用</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>Apache のハンドラの使用に関して記述しています。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#definition">ハンドラとは</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">例</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programmer">プログラマ向けのメモ</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definition" id="definition">ハンドラとは</a></h2>
        
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></li><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removehandler">RemoveHandler</a></code></li><li><code class="directive"><a href="./mod/core.html#sethandler">SetHandler</a></code></li></ul></td></tr></table>
    
    
        <p>「ハンドラ」とは、ファイルが呼ばれたときに実行される動作の
        Apache における内部表現です。
        通常、ファイルはファイルタイプ<span class="transnote">(<em>訳注:</em> MIME-type)</span>に基づいた暗黙のハンドラがあります。
        普通はすべてのファイルは単にサーバに扱われますが、
        ファイルタイプの中には別に「ハンドル」<span class="transnote">(<em>訳注:</em> 扱う)</span>
        されるものもあります。</p>
    
        <p>ファイルの拡張子や置いている場所に基づいてファイルタイプと関係なく、
        ハンドラを明示的に設定することもできます。
        これはより優雅な解決法という点と、ファイルにタイプ<strong>と</strong>ハンドラの両方を関連付けることができるという点で優れています。
        (<a href="mod/mod_mime.html#multipleext">複数の拡張子のあるファイル</a>も参照してください)。</p>
    
        <p>ハンドラはサーバに組み込んだり、モジュールとして含めたり、
        <code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code>
        ディレクティブとして追加したりすることができます。
        以下は標準配布に組み込まれているハンドラです。
        </p>
    
        <ul>
          <li><strong>default-handler</strong>:<code>default_handelr()</code>
          を使ってファイルを送ります。
          静的なコンテンツを扱うときにデフォルトで使用されるハンドラです。
          (<code class="module"><a href="./mod/core.html">core</a></code>)</li>
    
          <li><strong>send-as-is</strong>:
          HTTP ヘッダのあるファイルをそのまま送ります。
          (<code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code>)</li>
    
          <li><strong>cgi-script</strong>: ファイルを CGI
          スクリプトとして扱います。
          (<code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>)</li>
    
          <li><strong>imap-file</strong>:
          イメージマップのルールファイルとして解析します。
          (<code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code>)</li>
    
          <li><strong>server-info</strong>: サーバの設定情報を取得します。
          (<code class="module"><a href="./mod/mod_info.html">mod_info</a></code>)</li>
    
          <li><strong>server-status</strong>: サーバの状態報告を取得します。
          (<code class="module"><a href="./mod/mod_status.html">mod_status</a></code>)</li>
    
          <li><strong>type-map</strong>:
          コンテントネゴシエーションのためのタイプマップとして解析します。
          (<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>)</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">例</a></h2>
        
    
        <h3><a name="example1" id="example1">CGI スクリプトを用いて静的なコンテンツを変更する</a></h3>
          
    
          <p>以下のディレクティブによって、拡張子が <code>html</code>
          であるファイルは <code>footer.pl</code>
          CGI スクリプトを起動するようになります。</p>
    
          <pre class="prettyprint lang-config">Action add-footer /cgi-bin/footer.pl
    AddHandler add-footer .html</pre>
    
    
          <p>CGI スクリプトは希望の修正や追加を行なって、元々要求された文書
          (環境変数 <code>PATH_TRANSLATED</code>
          で指されています) を送る責任があります。
          </p>
    
        
        <h3><a name="example2" id="example2">HTTP ヘッダのあるファイル</a></h3>
          
    
          <p>以下のディレクティブは <code>send-as-is</code>
          ハンドラを使用するように指示します。このハンドラは自分自身の HTTP
          ヘッダを持っているファイルに使用されます。ここでは、拡張子に関わらず、
          <code>/web/htdocs/asis</code> ディレクトリにある全てのファイルは
          <code>send-as-is</code> ハンドラによって扱われます。</p>
    
          <pre class="prettyprint lang-config">&lt;Directory /web/htdocs/asis&gt;
        SetHandler send-as-is
    &lt;/Directory&gt;</pre>
    
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programmer" id="programmer">プログラマ向けのメモ</a></h2>
        
    
        <p>ハンドラの機能を実装するために、利用すると便利かもしれないものが
        <a href="developer/API.html">Apache API</a>
        に追加されました。詳しく言うと、<code>request_rec</code>
        構造体に新しいレコードが追加されたということです。</p>
    
        <pre class="prettyprint lang-c">char *handler</pre>
    
    
        <p>もしモジュールがハンドラに関わりたい場合、
        やらなければならないことは、リクエストが <code>invoke_handler</code>
        ステージに達する以前に <code>r-&gt;handler</code>
        を設定することだけです。ハンドラはコンテントタイプの代わりに
        ハンドラ名を使うようになっていること以外は、以前と同じように実装されています。
        必ず要求されているわけではありませんが、メディアタイプ
        の名前空間を侵さないように、ハンドラの名前にはスラッシュを含まない、
        ダッシュ<span class="transnote">(<em>訳注:</em> "-")</span>で分離された名前を付ける習慣になっています。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/handler.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/glossary.html.es�����������������������������������������������������������0000664�0001751�0001751�00000077737�14743132254�020220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Glosario - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="./">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>Glosario</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    
    	<p>&#201;ste glosario define las terminolog&#237;as m&#225;s comunes
    	relacionada con Apache en particular, y con los servidores web en
    	general. En los enlaces que hay asociados a cada t&#233;rmino se puede
    	encontrar informaci&#243;n m&#225;s detallada de cada uno.</p>
    	</div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definitions" id="definitions">Definiciones</a></h2>
    		<dl>
    		<dt><a name="algorithm" id="algorithm">Algoritmo</a></dt>
    		<dd>Un proceso definido sin ambig&#252;edades o un conjunto de reglas 
    		para solucionar un problema en un n&#250;mero finito de pasos.
    		Los algoritmos para encriptar se llaman
    		normalmente <dfn>algoritmos de cifrado</dfn>.
    		</dd>
    
    
    		<dt><a name="cipher" id="cipher">Algoritmo de cifrado, (Cipher). </a></dt>
    		<dd>Es un algoritmo o sistema de encriptado de informaci&#243;n. 
    		Ejemplos de estos algoritmos son DES, IDEA, RC4, etc.<br />
    		Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    		<dt><a name="authentication" id="authentication">Autenticaci&#243;n.</a></dt>
    		<dd>La identificaci&#243;n positiva de una entidad de red tal como un
    		servidor, un cliente, o un usuario.<br /> 
    		Consulte: <a href="howto/auth.html">Autentificaci&#243;n, Autorizaci&#243;n, 
    		y Control de Acceso</a></dd>
    
    
    		<dt><a name="certificationauthority" id="certificationauthority">Autoridad Certificadora.</a> <a name="ca">(CA)</a></dt> <dd>Es 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.<br /> Consulte: <a href="ssl/">Encriptado
    		SSL/TLS</a></dd>
    
    
    		<dt><a name="header" id="header">Cabecera.</a></dt> <dd>Es la parte de la
    		petici&#243;n y la respuesta <a class="glossarylink" href="./glossary.html#http" title="ver glosario">HTTP</a> que se
    		env&#237;a antes del contenido propiamente dicho, y que contiene
    		meta-informaci&#243;n describiendo el contenido.</dd>
    
    		<dt><a name="certificate" id="certificate">Certificado.</a></dt>
    		<dd>Una informaci&#243;n que se almacena para autenticar entidades
    		de red tales como un servidor o un cliente. Un certificado
    		contiene piezas de informaci&#243;n X.509 sobre su poseedor
    		(llamado sujeto) y sobre la <a class="glossarylink" href="./glossary.html#certificationauthority" title="ver glosario">Autoridad Certificadora</a>
    		(llamada el emisor) que lo firma, m&#225;s la <a class="glossarylink" href="./glossary.html#publickey" title="ver glosario">clave p&#250;blica</a> del propietario y la firma de
    		la AC(Autoridad Certificadora). Las entidades de red verifican las firmas usando
    		certificados de las AC.<br />
    		Consulte: <a href="ssl/">Encriptado SSL/TLS</a>
    		</dd>
    
    
    
    		<dt><a name="publickey" id="publickey">Clave P&#250;blica.</a></dt> 
    		<dd>La clave disponible
    		p&#250;blicamente en un <a class="glossarylink" href="./glossary.html#publickeycryptography" title="ver glosario">sistema
    		criptogr&#225;fico de Clave P&#250;blica</a>, usado para encriptar
    		mensajes destinados a su propietario y para desencriptar firmas hechas
    		por su propietario.<br /> Consulte: <a href="ssl/">Encriptado
    		SSL/TLS</a></dd>
    
    
    
    		<dt><a name="privatekey" id="privatekey">Clave Privada.</a></dt>
    		<dd>La clave secreta
    		de un <a class="glossarylink" href="./glossary.html#publickeycryptography" title="ver glosario">Sistema criptogr&#225;fico de
    		Clave P&#250;blica</a>, usada para desencriptar los mensajes entrantes
    		y firmar los salientes.<br /> Consulte: <a href="ssl/">Encriptado
    		SSL/TLS</a></dd>
    
    
    		<dt><a name="connect" id="connect">CONNECT</a></dt> <dd>Un <a class="glossarylink" href="./glossary.html#method" title="ver glosario">m&#233;todo</a> de HTTP para hacer proxy a canales de
    		datos sin usar HTTP. Puede usarse para encapsular otros protocolos,
    		tales como el protocolo SSL.</dd>
    
    
    
    		<dt><a name="context" id="context">Contexto</a></dt> <dd>Un &#225;rea en los
    		<a class="glossarylink" href="./glossary.html#configurationfile" title="ver glosario">ficheros de configuraci&#243;n</a>
    		donde est&#225;n permitidos ciertos tipos de <a class="glossarylink" href="./glossary.html#directive" title="ver glosario">directivas</a>.<br />
    		Consulte: <a href="mod/directive-dict.html#Context">T&#233;rminos 
    		usados para describir las directivas de Apache</a></dd>
    
    
    		<dt><a name="accesscontrol" id="accesscontrol">Control de Acceso.</a></dt> 
    		<dd>La
    		restricci&#243;n en el acceso al entorno de una red. En el contexto de
    		Apache significa normalmente la restricci&#243;n en el acceso a
    		ciertas <em>URLs</em>.<br /> 
    		Consulte: <a href="howto/auth.html">Autentificaci&#243;n, Autorizaci&#243;n, y
    		Control de Acceso</a></dd>
    
    
    		<dt><a name="symmetriccryptophraphy">Criptograf&#237;a
    		Sim&#233;trica</a></dt> <dd>El estudio y aplicaci&#243;n de
    		<em>Algoritmos de Cifrado</em> que usan una sola clave secreta tanto
    		para cifrar como para descifrar.<br /> Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    
    		<dt><a name="directive" id="directive">Directiva</a></dt>
    		<dd>Un comando de
    		configuraci&#243;n que controla uno o m&#225;s aspectos del
    		comportamiento de Apache.  Las directivas se ponen en el <a class="glossarylink" href="./glossary.html#configurationfile" title="ver glosario">Fichero de Configuraci&#243;n</a><br />
    		Consulte: <a href="mod/directives.html">&#205;ndice de
    		Directivas</a></dd>
    
    		<dt><a name="configurationdirective" id="configurationdirective">Directivas de
    		configuraci&#243;n.</a></dt> <dd>Consulte: <a class="glossarylink" href="./glossary.html#directive" title="ver glosario">Directivas</a></dd>
    
    		<dt><a name="apacheportableruntime" id="apacheportableruntime">Entorno Portable de tiempo de ejecuci&#243;n de Apache, </a> <a name="apr" id="apr">(APR, Apache Portable Runtime)</a></dt>
    		<dd>Es un conjunto de librer&#237;as que proveen las interfaces b&#225;sicas 
    		entre el servidor y el sistema operativo. El desarrollo de APR es 
    		paralelo al del Servidor HTTP Apache, como un proyecto independiente. 
    		Puedes visitar el proyecto en:<br />
    		<a href="http://apr.apache.org/">Apache Portable Runtime
    		Project</a>
    		</dd>
    
    		<dt><a name="export-crippled" id="export-crippled">Export-Crippled</a></dt>
    		<dd>Disminuci&#243;n de la fortaleza criptogr&#225;fica (y seguridad)
    		para cumplir con las Regulaciones sobre Exportaci&#243;n de la
    		Administraci&#243;n de los Estados Unidos (EAR). El software
    		criptogr&#225;fico Export-crippled est&#225; limitado a una clave de
    		peque&#241;o tama&#241;o, de tal manera que el <em>texto cifrado</em>
    		que se consigue con &#233;l, puede descifrarse por medio de fuerza bruta.<br /> Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    
    		<dt><a name="regularexpresion" id="regularexpresion">Expresiones Regulares</a> 
    		<a name="regex">(Regex)</a></dt> <dd>Una forma de describir un patr&#243;n en un 
    		texto - por ejemplo, "todas las palabras que empiezan con la letra "A"
    		o "todos los n&#250;meros de tel&#233;fono que contienen 10
    		d&#237;gitos" o incluso "Todas las frases entre comas, y que no
    		contengan ninguna letra Q". Las Expresiones Regulares son &#250;tiles 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&#233;n en el directorio "im&#225;genes"
    		podr&#237;an ser escritos como "<code>/images/.*(jpg|gif)$</code>".
    		En los lugares donde expresiones regulares se utilizan para reemplazar
    		cadenas, las variables especiales $ 1 ... $ 9 contienen 
    		referencias inversa las partes agrupadas (entre par&#233;ntesis) 
    		de la expresi&#243;n coincidente. La variable especial $ 0 contiene 
    		una referencia inversa a todo el ejemplar de la expresi&#243;n.
    		Para escribir un s&#237;mbolo de dolar literal en una sustituci&#243;n de
    		una cadena, se puede escapar usando "\". Hist&#243;ricamente, la variable &amp;
    		se pod&#237;a usar como un alias a $0 en algunos sitios. 
    		Esto ya no esta soportado desde la versi&#243;n 2.3.6.
    		Apache usa Expresiones Regulares compatibles con Perl gracias a la
    		librer&#237;a <a href="http://www.pcre.org/">PCRE</a>.
    		Puedes encontrar m&#225;s documentaci&#243;n sobre las expresiones regulares 
    		de PCRE y su sintaxis en esa p&#225;gina o en la
    		<a href="http://en.wikipedia.org/wiki/PCRE">Wikipedia</a>.</dd>
    
    
    
    		<dt><a name="configurationfile" id="configurationfile">Fichero de Configuraci&#243;n.</a></dt>
    		<dd>Un fichero de texto que contiene <a class="glossarylink" href="./glossary.html#directive" title="ver glosario">Directivas</a> que controlan la configuraci&#243;n
    		de Apache.<br /> Consulte: <a href="configuring.html">Ficheros de
    		Configuraci&#243;n</a></dd>
    
    
    		<dt><a name="htaccess" id="htaccess">.htaccess</a></dt> 
    		<dd>Un <a class="glossarylink" href="./glossary.html#configurationfile" title="ver glosario">fichero de configuraci&#243;n</a> que se
    		pone dentro de la estructura de directorios del sitio web y aplica <a class="glossarylink" href="./glossary.html#directive" title="ver glosario">directivas</a> de configuraci&#243;n al directorio
    		en el que est&#225; y a sus subdirectorios. A pesar de su nombre, este
    		fichero puede contener cualquier tipo de directivas, no solo
    		directivas de control de acceso.<br /> Consulte: <a href="configuring.html">Ficheros de Configuraci&#243;n</a> para m&#225;s informaci&#243;n.</dd>
    
    		<dt><a name="httpd.conf" id="httpd.conf">httpd.conf</a></dt>
    		<dd>Es el <a class="glossarylink" href="./glossary.html#configurationfile" title="ver glosario">fichero de configuraci&#243;n</a> principal
    		de Apache. Su ubicaci&#243;n por defecto es
    		<code>/usr/local/apache2/conf/httpd.conf</code>, pero puede moverse
    		usando opciones de configuraci&#243;n al compilar o al iniciar
    		Apache.<br /> Consulte: <a href="configuring.html">Ficheros de
    		Configuraci&#243;n</a></dd>
    
    		<dt><a name="filter" id="filter">Filtro</a></dt>
    		<dd>Un proceso que se aplica a la
    		informaci&#243;n que es enviada o recibida por el servidor. Los
    		ficheros de entrada procesan la informaci&#243;n enviada por un
    		cliente al servidor, mientras que los filtros de salida procesan la
    		informaci&#243;n en el servidor antes de envi&#225;rsela al
    		cliente. Por ejemplo, el filtro de salida <code>INCLUDES</code>
    		procesa documentos para <a class="glossarylink" href="./glossary.html#ssi" title="ver glosario">Server Side Includes</a>.<br />
    		Consulte: <a href="filter.html">Filtros</a></dd>
    
    
    
    		<dt><a name="digitalsignature" id="digitalsignature">Firma Digital</a></dt>
    		<dd>Un bloque de
    		texto encriptado que verifica la validez de un certificado o de otro
    		fichero. Una <a class="glossarylink" href="./glossary.html#certificationauthority" title="ver glosario">Autoridad
    		Certificadora</a> crea una firma generando un hash a partir de la
    		<em>Clave P&#250;blica</em> que lleva incorporada en un
    		<em>Certificado</em>, despu&#233;s encriptando el hash con su propia
    		<em>Clave Privada</em>. Solo las claves p&#250;blicas de las CAs
    		pueden desencriptar la firma, verificando que la CA ha autentificado a
    		la entidad de red propietaria del <em>Certificado</em>.<br />
    		Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    		<dt><a name="handler" id="handler">Handler</a></dt> 
    		<dd>Es una representaci&#243;n
    		interna de Apache de una acci&#243;n a ser ejecutada cuando se llama a
    		un fichero. Generalmente, los ficheros tienen un handler (manejador)
    		impl&#237;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 <code>cgi-script</code> designa los ficheros a ser
    		procesados como <a class="glossarylink" href="./glossary.html#cgi" title="ver glosario">CGIs</a>.<br /> Consulte: <a href="handler.html">Uso de Handlers en Apache</a></dd>
    
    		<dt><a name="apacheextensiontool" id="apacheextensiontool">Herramienta de extensi&#243;n de
    		Apache.</a> <a name="apxs" id="apxs">(apxs)</a></dt>
    		<dd>Es un script escrito en Perl que ayuda a compilar el c&#243;digo
    		fuente de algunos <a class="glossarylink" href="./glossary.html#module" title="ver glosario">m&#243;dulos</a> para 
    		convertirlos en Objetos Din&#225;micos Compartidos (<a class="glossarylink" href="./glossary.html#dso.html" title="ver glosario">DSO</a>s)
    		y ayuda a instalarlos en el Servidor Web de Apache.<br /> 
    		Consulte: Manual de: <code class="program"><a href="./programs/apxs.html">apxs</a></code></dd>
    
    
    
    		<dt><a name="hash" id="hash">Hash</a></dt>
    		<dd>Algoritmo matem&#225;tico de un solo sentido e irreversible, que genera
    		una cadena de una determinada longitud de otra cadena de 
    		cualquier tama&#241;o. Diferentes entradas dar&#225;n diferentes hashes 
    		(dependiendo de la funci&#243;n hash.) 
    		</dd>
    
    
    
    
    
    		<dt><a name="virtualhosting">Hosting Virtual</a></dt> <dd>Se trata de
    		servir diferentes sitios web con una sola entidad de Apache.  <em>El
    		hosting virtual de IPs</em> diferencia los sitios web bas&#225;ndose en sus
    		direcciones IP, mientras que el <em>hosting virtual basado en
    		nombres</em> usa solo el nombre del host y de esta manera puede alojar
    		muchos sitios web con la misma direcci&#243;n IP.<br /> Consulte: <a href="vhosts/">Documentaci&#243;n sobre Hosting Virtual en
    		Apache</a></dd>
    
    
    		<dt><a name="uniformresourceidentifier">Identificador de Recursos
    		Uniforme</a> <a name="URI">(URI)</a></dt> <dd>Una cadena de caracteres
    		compacta para identificar un recurso f&#237;sico o abstracto.  Se
    		define formalmente en la <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>.  Los URIs que
    		se usan en world-wide web se refieren normalmente como <a href="#url">URLs</a>.</dd>
    
    
    
    
    		<dt><a name="servernameindication" id="servernameindication">Indicador del Nombre del servidor</a>
    		<a name="sni" id="sni"> Server Name Indication (SNI) </a></dt>
    		<dd>Una funci&#243;n SSL que permite pasar el nombre de host del servidor deseado 
    		en el mensaje inicial del protocolo de enlace SSL, para que el servidor web 
    		pueda seleccionar la configuraci&#243;n correcta del host virtual para usar en el 
    		procesamiento del protocolo de enlace SSL. Se a&#241;adi&#243; a SSL 
    		con las extensiones TLS en el RFC 3546.  <br />
    		See: <a href="ssl/ssl_faq.html">the SSL FAQ</a>
    		and <a href="http://www.ietf.org/rfc/rfc3546.txt">RFC 3546</a>
    		</dd>
    
    
    
    
    		<dt><a name="commongatewayinterface" id="commongatewayinterface">Interfaz de Pasarela Com&#250;n.</a> <a name="cgi"> Common Gateway Interface (CGI)</a></dt>
    		<dd>Una definici&#243;n est&#225;ndar para
    		un interfaz entre un servidor web y un programa externo que permite
    		hacer peticiones de servicio a los programas externos.  Este interfaz
    		esta definido en el  <a href="http://www.ietf.org/rfc/rfc3875">RFC-3875</a>.<br />
    		Consulte: <a href="howto/cgi.html">Contenido Din&#225;mico con CGI</a>
    		</dd>
    
    		<dt><a name="uniformresourcelocator">Localizador de Recursos
    		Uniforme</a> <a name="url">(URL)</a></dt>
    		<dd>El nombre de un recurso
    		en Internet.  Es la manera informal de decir lo que formalmente se
    		llama un <a href="#uniformresourceidentifier">Identificador de
    		Recursos Uniforme</a>.  Las URLs est&#225;n compuestas normalmente por
    		un esquema, tal como <code>http</code> o <code>https</code>, un nombre
    		de host, y una ruta.  Una URL para esta p&#225;gina es
    		<code>http://httpd.apache.org/docs/2.4/glossary.html</code>.</dd>
    
    
    		<dt><a name="module" id="module">M&#243;dulo</a></dt>
    		<dd>Una parte independiente
    		de un programa. La mayor parte de la funcionalidad de Apache
    		est&#225; contenida en m&#243;dulos que pueden incluirse o excluirse.
    		Los m&#243;dulos que se compilan con el binario <code class="program"><a href="./programs/httpd.html">httpd</a></code>de Apache se
    		llaman <em>m&#243;dulos est&#225;ticos</em>, mientras que los que se
    		almacenan de forma separada y pueden ser cargados de forma opcional,
    		se llaman <em>m&#243;dulos din&#225;micos</em> o <a class="glossarylink" href="./glossary.html#dso" title="ver glosario">DSOs</a>.
    		Los m&#243;dulos que est&#225;n incluidos por defecto de llaman
    		<em>m&#243;dulos base</em>.  Hay muchos m&#243;dulos disponibles para
    		Apache que no se distribuyen con la <a class="glossarylink" href="./glossary.html#tarball" title="ver glosario">tarball</a> del
    		Servidor HTTP Apache.  Estos m&#243;dulos son llamados
    		<em>m&#243;dulos de terceros</em>.<br /> Consulte: <a href="mod/">&#205;ndice de M&#243;dulos</a></dd>
    
    
    		<dt><a name="method" id="method">M&#233;todo</a></dt> 
    		<dd>En el contexto de <a class="glossarylink" href="./glossary.html#http" title="ver glosario">HTTP</a>, es una acci&#243;n a ejecutar sobre un recurso,
    		especificado en la l&#237;neas de petici&#243;n por el cliente.
    		Algunos de los m&#233;todos disponibles en HTTP son <code>GET</code>,
    		<code>POST</code>, y <code>PUT</code>.</dd>
    
    		<dt><a name="messagedigest" id="messagedigest">Mensaje Resumen (Message Digest)</a></dt> 
    		<dd>Un hash de un
    		mensaje, el cual pude ser usado para verificar que el contenido del
    		mensaje no ha sido alterado durante la transmisi&#243;n.<br />
    		Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    		<dt><a name="mime-type" id="mime-type">MIME-type</a></dt> 
    		<dd>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 <code>text/html</code>,
    		<code>image/gif</code>, y <code>application/octet-stream</code>.  En
    		HTTP, el tipo MIME se transmite en la <a class="glossarylink" href="./glossary.html#header" title="ver glosario">cabecera</a>
    		del <code>Tipo Contenido</code>.<br /> Consulte: <a href="mod/mod_mime.html">mod_mime</a></dd>
    
    		<dt><a name="modulemagicnumber" id="modulemagicnumber">M&#243;dulo del N&#250;mero M&#225;gico</a>
    		(<a name="mmn">MMN Module Magic
    		Number</a>)</dt> <dd> El m&#243;dulo del n&#250;mero
    		m&#225;gico es una constante definida en el c&#243;digo
    		fuente de Apache que est&#225; asociado con la compatibilidad binaria
    		de los m&#243;dulos. Ese n&#250;mero cambia cuando cambian las
    		estructuras internas de Apache, las llamadas a funciones y otras
    		partes significativas de la interfaz de programaci&#243;n de manera
    		que la compatibilidad binaria no puede garantizarse sin cambiarlo.  Si
    		cambia el n&#250;mero m&#225;gico de m&#243;dulo, todos los
    		m&#243;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&#243;n de Apache </dd>
    
    
    		<dt><a name="fully-qualifieddomain-name" id="fully-qualifieddomain-name">Nombre de dominio
    		completamente qualificado</a> <a name="fqdn">(FQDN)</a></dt> 
    		<dd>El
    		nombre &#250;nico de una entidad de red, que consiste en un nombre de
    		host y un nombre de dominio que puede traducirse a una direcci&#243;n
    		IP. Por ejemplo, <code>www</code> es un nombre de host,
    		<code>example.com</code> es un nombre de dominio, y
    		<code>www.example.com</code> es un nombre de dominio completamente
    		qualificado.</dd>
    
    		<dt><a name="dynamicsharedobject" id="dynamicsharedobject">Objetos Din&#225;micos
    		Compartidos</a> <a name="dso">(DSO, dinamic shared objects)</a></dt>
    		<dd>Los <a class="glossarylink" href="./glossary.html#module" title="ver glosario">M&#243;dulos</a> compilados de forma separada al
    		binario httpd de Apache se pueden cargar seg&#250;n se necesiten.<br /> Consulte: <a href="dso.html">Soporte de Objetos Din&#225;micos
    		Compartidos</a></dd>
    
    
    		<dt><a name="openssl" id="openssl">OpenSSL</a></dt>
    		<dd>El toolkit Open Source para SSL/TLS<br />
    		Ver: <a href="http://www.openssl.org/">http://www.openssl.org/</a></dd>
    
    
    		<dt><a name="passphrase">Pass Phrase o frase de contrase&#241;a</a></dt> 
    		<dd>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 <a class="glossarylink" href="./glossary.html#cipher" title="ver glosario">Algoritmos de
    		Cifrado</a>.<br /> Consulte: <a href="ssl/">Encriptado
    		SSL/TLS</a></dd>
    
    		<dt><a name="certificatsigningrequest" id="certificatsigningrequest">Petici&#243;n de firma de
    		Certificado.</a> <a name="csr">(CSR)</a></dt> 
    		<dd>Es la petici&#243;n a
    		una <a class="glossarylink" href="./glossary.html#certificationauthority" title="ver glosario">Autoridad Certificadora</a> para
    		que firme un <a class="glossarylink" href="./glossary.html#certificate" title="ver glosario">certificado</a> a&#250;n sin
    		firmar. La Autoridad Certificadora firma el <em>Certificado</em> con
    		la <a class="glossarylink" href="./glossary.html#privatekey" title="ver glosario">Clave Privada</a> de su 
    		<em>certificado</em>. Una vez que el CSR est&#225; firmado, se 
    		convierte en un aut&#233;ntico certificado.<br /> 
    		Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    
    
    		<dt><a name="hypertexttransferprotocol" id="hypertexttransferprotocol">Protocolo de Transferencia de
    		Hipertexto</a> <a name="http">(HTTP)</a></dt> 
    		<dd>Es el protocolo de
    		transmisi&#243;n est&#225;dar usado en la World Wide Web.  Apache
    		implementa la versi&#243;n 1.1 de este protocolo, al que se hace
    		referencia como HTTP/1.1 y definido por el <a href="http://ietf.org/rfc/rfc2616.txt">RFC 2616</a>.</dd>
    
    		<dt><a name="https" id="https">HTTPS</a></dt>
    		<dd>Protocolo de transferencia de
    		Hipertexto (Seguro), es el mecanismo de comunicaci&#243;n encriptado
    		est&#225;ndar en World Wide Web. En realidad es HTTP sobre <a class="glossarylink" href="./glossary.html#ssl" title="ver glosario">SSL</a>.<br /> Consulte: <a href="ssl/">Encriptado
    		SSL/TLS</a></dd>
    
    		<dt><a name="proxy" id="proxy">Proxy</a></dt> <dd>Un servidor intermedio que se
    		pone entre el cliente y el <em>servidor de origen</em>.  Acepta las
    		peticiones de los clientes, las transmite al servidor de origen, y
    		despu&#233;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&#233;, en lugar de pedirlo cada vez que lo
    		necesita al servidor de origen, reduciendo con esto el tiempo de
    		respuesta.<br /> Consulte: <a href="mod/mod_proxy.html">mod_proxy</a></dd>
    
    
    		<dt><a name="reverseproxy" id="reverseproxy">Proxy Inverso</a></dt>
    		<dd>Es un servidor
    		<a href="proxy">proxy</a> que se presenta al cliente como si fuera un
    		<em>servidor de origen</em>.  Es &#250;til para esconder el
    		aut&#233;ntico servidor de origen a los clientes por cuestiones de
    		seguridad, o para equilibrar la carga.</dd>
    
    
    		<dt><a name="securesocketslayer" id="securesocketslayer">SSL, Capa de Conexi&#243;n Segura </a> <a name="ssl">Secure Sockets Layer(SSL)</a></dt> <dd>Es un protocolo creado por Netscape
    		Communications Corporation para la autenticaci&#243;n en
    		comunicaciones en general y encriptado sobre redes TCP/IP. Su
    		aplicaci&#243;n m&#225;s popular es en <em>HTTPS</em>, ejemplo.: el Protocolo de
    		Transferencia de Hipertexto (HTTP) sobre SSL.<br /> Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    
    		<dt><a name="ssleay" id="ssleay">SSLeay</a></dt> <dd>La implementaci&#243;n
    		original de la librer&#237;a SSL/TLS desarrollada por Eric
    		A. Young</dd>
    
    
    
    		<dt><a name="serversideincludes" id="serversideincludes">Server Side Includes</a> <a name="ssi">(SSI)</a></dt> <dd>Una t&#233;cnica para incluir directivas de
    		proceso en archivos HTML.<br /> Consulte: <a href="howto/ssi.html">Introducci&#243;n a Server Side
    		Includes</a></dd>
    
    
    
    		<dt><a name="session" id="session">Sesi&#243;n</a></dt> <dd>Informaci&#243;n del
    		contexto de una comunicaci&#243;n en general.</dd>
    
    
    		<dt><a name="publickeycryptography" id="publickeycryptography">Sistema Criptogr&#225;fico de Clave
    		P&#250;blica</a></dt> <dd>El estudio y aplicaci&#243;n de sistemas de
    		encriptado asim&#233;tricos, que usa una clave para encriptar y otra
    		para desencriptar. Una clave de cada uno de estos tipos constituye un
    		par de claves. Tambi&#233;n se llama Criptograf&#237;a Asim&#233;trica.<br />
    		Consulte: <a href="ssl/"> Encriptado SSL/TLS</a></dd>
    
    
    		<dt><a name="subrequest" id="subrequest">Subconsulta</a></dt>
    		<dd>Apache proporciona una API de subconsultasd a los m&#243;dulos,
    		que permiten a otros sistemas de ficheros o paths de URL ser parcial o totalmente evaluados
    		por el servidor. Un ejemplo de los que usan esta API ser&#237;a
    		<code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>,
    		<code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code>, y <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>.
    		</dd>
    
    		<dt><a name="tarball" id="tarball">Tarball</a></dt> <dd>Un grupo de ficheros
    		puestos en un solo paquete usando la utilidad <code>tar</code>.  Las
    		distribuciones Apache se almacenan en ficheros comprimidos con tar o
    		con pkzip.</dd>
    
    		<dt><a name="ciphertext" id="ciphertext">Texto cifrado.</a></dt> 
    		<dd>El resultado de
    		haber aplicado a un <a class="glossarylink" href="./glossary.html#plaintext" title="ver glosario">texto plano</a> un <a class="glossarylink" href="./glossary.html#cipher" title="ver glosario">algoritmo de cifrado</a>.<br /> Consultar: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    
    
    		<dt><a name="plaintext" id="plaintext">Texto plano</a></dt>
    		<dd>Un texto no encriptado.</dd>
    
    
    		<dt><a name="transportlayersecurity" id="transportlayersecurity">Transport 
    			Layer Security</a> <a name="tls">(TLS)</a></dt> <dd>Es el sucesor del protocolo SSL, creado
    		por el "Internet Engineering Task Force" (IETF) para la
    		autentificaci&#243;n en comunicaciones en general y encriptado sobre
    		redes TCP/IP. La versi&#243;n 1 de TLS es casi id&#233;ntica a la
    		versi&#243;n 3 de SSL.<br /> Consulte: <a href="ssl/">Encriptado
    		SSL/TLS</a></dd>
    
    
    		<dt><a name="environmentvariable" id="environmentvariable">Variable de Entorno</a> <a name="env-variable">(env-variable)</a></dt> 
    		<dd>Variables que
    		gestionan el shell del sistema operativo y que se usan para guardar
    		informaci&#243;n y para la comunicaci&#243;n entre programas.  Apache
    		tambi&#233;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.<br />
    		Consulte: <a href="env.html">Variables de entorno de Apache</a></dd>
    
    
    		<dt><a name="x.509" id="x.509">X.509</a></dt> <dd>Un esquema de certificado de
    		autentificaci&#243;n recomendado por la International
    		Telecommunication Union (ITU-T) que se usa en la autentificaci&#243;n
    		SSL/TLS.<br /> Consulte: <a href="ssl/">Encriptado SSL/TLS</a></dd>
    
    		</dl>
    	</div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/glossary.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������httpd-2.4.64/docs/manual/getting-started.html.ru.utf8�����������������������������������������������0000664�0001751�0001751�00000052426�14743132254�022352� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ru" xml:lang="ru"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Начало работы - HTTP сервер Apache Версия 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Модули</a> | <a href="./mod/directives.html">Директивы</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Глоссарий</a> | <a href="./sitemap.html">Карта сайта</a></p>
    <p class="apache">HTTP сервер Apache Версия 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP сервер</a> &gt; <a href="http://httpd.apache.org/docs/">Документация</a> &gt; <a href="./">Версия 2.4</a></div><div id="page-content"><div id="preamble"><h1>Начало работы</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/getting-started.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/getting-started.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ru/getting-started.html" title="Russian">&nbsp;ru&nbsp;</a></p>
    </div>
    
    <p>Если вы абсолютный новичок в работе с HTTP-сервером Apache или 
    в запуске веб-сайтов вообще, вы можете не знать с чего начать или какие
    вопросы задавать. Этот документ познакомит вас с основами.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#clientserver">Клиенты, серверы и URL-адреса</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#dns">Имена хостов и DNS</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configuration">Файлы конфигурации и директивы</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#content">Контент веб-сайта</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#logs">Файлы журналов и устранение неполадок</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Что дальше?</a></li>
    </ul><h3>См. также</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="clientserver" id="clientserver">Клиенты, серверы и URL-адреса</a></h2>
    
    
    <p>Адреса в Интернете записываются с помощью URL — Uniform Resource
    Locator (унифицированный указатель ресурса), который указывает на
    используемый протокол (например, <code>http</code>), имя сервера
    (например, <code>www.apache.org</code>), URL-путь (например,
    <code>/docs/current/getting-started.html</code>) и, возможно,
    строку запроса (например, <code>?arg=value</code>), используемую для
    передачи серверу дополнительных аргументов.</p>
    
    <p>Клиент (например, веб-браузер) подключается к серверу
    (например, вашему HTTP-серверу Apache), используя определённый протокол,
    и отправляет <strong>запрос</strong> на ресурс, используя URL-путь.</p>
    
    <p>URL-путь может обозначать множество вещей на сервере. Это может быть
    файл (как <code>getting-started.html</code>), обработчик
    (как <a href="mod/mod_status.html">server-status</a>) или файл какой-то
    программы (как <code>index.php</code>). Мы рассмотрим это подробней ниже,
    в разделе <a href="#content">Контент веб-сайта</a>.</p>
    
    <p>Сервер отправляет <strong>ответ</strong>, содержащий код состояния и,
    опционально, тело ответа. Код состояния указывает, был ли запрос успешно
    обработан, а если нет, то какая ошибка произошла.
    Это говорит клиенту, что он должен делать с ответом.
    Вы можете прочитать о возможных кодах ответа на 
    <a href="http://wiki.apache.org/httpd/CommonHTTPStatusCodes">
    Вики HTTP-сервера Apache</a>.</p>
    
    <p>Детали транзакции и условия возникновения ошибки записываются
    в файлы журналов. Это описывается более подробно ниже, в разделе
    <a href="#logs">Файлы журналов и устранение неполадок</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dns" id="dns">Имена хостов и DNS</a></h2>
    
    
    <p>Для того чтобы соединиться с сервером, клиент сначала должен преобразовать
    имя сервера в IP-адрес — место в Интернете, где находится сервер.
    Таким образом, чтобы ваш веб-сервер был доступен, необходимо,
    чтобы имя сервера было в DNS.</p>
    
    <p>Если вы не знаете как это сделать, вам нужно обратиться к сетевому
    администратору или поставщику услуг Интернета (провайдеру).
    Они могут сделать это для вас.</p>
    
    <p>Несколько хостов могут указывать на один и тот же IP-адрес,
    а один физический сервер может иметь больше одного IP-адреса.
    Таким образом на одном физическом сервере вы можете запустить больше одного
    сайта с помощью особенности: <a href="vhosts/">виртуальные хосты</a>.</p>
    
    <p>Если вы тестируете сервер, не имеющий выхода в Интернет, можете поместить
    имена хостов в файл hosts для того что бы имя разрешалось локально.
    Например, вы можете добавить запись для отправки запросов к
    <code>www.example.com</code> на локальный компьютер, для тестирования.
    Эта запись будет выглядеть так:</p>
    
    <div class="example"><p><code>
    127.0.0.1 www.example.com
    </code></p></div>
    
    <p>Файл hosts, скорее всего, расположен в <code>/etc/hosts</code> или 
    <code>C:\Windows\system32\drivers\etc\hosts</code>.</p>
    
    <p>Вы можете узнать больше о файле 
    <a href="http://en.wikipedia.org/wiki/Hosts_(file)">hosts</a> и больше о
    <a href="http://en.wikipedia.org/wiki/Domain_Name_System">DNS</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Файлы конфигурации и директивы</a></h2>
    
    
    <p>HTTP-сервер Apache настроен с помощью простых текстовых файлов.
    Эти файлы могут располагаться в разных местах, в зависимости от того как вы 
    установили сервер. Общие места расположения файлов можно найти в 
    <a href="http://wiki.apache.org/httpd/DistrosDefaultLayout">Вики
    HTTP-сервера Apache</a>. Если вы установили httpd из исходного кода,
    то расположение файлов конфигурации по умолчанию следующее:
    <code>/usr/local/apache2/conf</code>.
    По умолчанию файл конфигурации называется <code>httpd.conf</code>.
    Это тоже может варьироваться в сторонних дистрибутивах сервера.</p>
    
    <p>Конфигурация часто разбивается на несколько небольших файлов, для
    удобства управления. Эти файлы загружаются через директиву
    <code class="directive"><a href="./mod/core.html#include">Include</a></code>.
    Имена или расположения этих файлов конфигурации
    могут сильно отличаться от одной установки к другой.
    Расположите и разделите эти файлы наиболее подходящим для
    <strong>вас</strong> образом. Если расположение файлов по умолчанию,
    не имеет смысла для вас, не стесняйтесь изменить его.</p>
    
    <p>Сервер настраивается путём размещения <a href="mod/quickreference.html">
    директив конфигурации</a> в этих файлах конфигурации.
    Директива — это ключевое слово с одним или несколькими аргументами,
    устанавливающими её значение.</p>
    
    <p>На вопрос: «<em>Где я должен прописать эту директиву?</em>» – обычно
    отвечают, там где ты хочешь использовать её. Если это глобальная настройка,
    она должна располагаться в конфигурационном файле вне разделов
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> или других
    разделов. Если настройка относится только к конкретному каталогу,
    значит она должна быть внутри секции
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
    которая описывает этот каталог, и так далее.
    Смотри документ <a href="sections.html">Разделы конфигурации</a>
    с подробным описанием вышеуказанных разделов.</p>
    
    <p>В дополнение к основному файлу конфигурации, некоторые директивы могут
    располагаться в файлах <code>.htaccess</code>, расположенных в папках с
    контентом. Файлы <code>.htaccess</code> в первую очередь предназначены для
    людей у которых нет доступа к главному конфигурационному файлу сервера.
    Вы можете узнать больше о файлах <code>.htaccess</code> в инструкции
    <a href="howto/htaccess.html"><code>.htaccess</code></a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="content" id="content">Контент веб-сайта</a></h2>
    
    
    <p>Содержимое сайта может принимать различные формы, но в широком смысле
    разделяется на статический и динамический контент.</p>
    
    <p>Статический контент — это, например, HTML-файлы, файлы изображений,
    CSS-файлы и другие файлы, которые просто лежат на диске.
    Директива <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> указывает
    где в вашей файловой системе, вы должны разместить эти файлы.
    Эта директива устанавливается глобально или отдельно для каждого
    виртуального хоста. Посмотрите в своём файле(ах) конфигурации,
    чтобы узнать, как именно эта директива используется на вашем сервере.</p>
    
    <p>Обычно, когда запрашивается каталог, без указания имени файла, то будет
    отдан документ с именем <code>index.html</code>. Например, если для директивы
    <code>DocumentRoot</code> установлено значение <code>/var/www/html</code> 
    и приходит запрос на адрес
    <code>http://www.example.com/work/</code>,
    то файл расположенный по пути
    <code>/var/www/html/work/index.html</code>
    будет отдан клиенту.</p>
    
    <p>Динамический контент — это всё что генерируется во время запроса и может 
    изменяться от запроса к запросу. Существует множество способов создания
    динамического контента. Различные <a href="handler.html">обработчики</a>
    доступны для генерации содержимого. Могут быть написаны специальные
    <a href="howto/cgi.html">CGI программы</a> для генерации контента на сайте.</p>
    
    <p>Для написания кода с разнообразным функционалом
    могут использоваться сторонние модули, такие как mod_php.
    Множество сторонних приложений, написанных на различных языках
    программирования, и утилит доступны для скачивания и установки
    на ваш HTTP-сервер Apache.
    Поддержка сторонних продуктов выходит за рамки этой документации.
    При необходимости вы должны самостоятельно найти их документацию
    или форумы поддержки, где вы сможете получить ответы на свои вопросы.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="logs" id="logs">Файлы журналов и устранение неполадок</a></h2>
    
    <p>Для вас, как администратора HTTP-сервера Apache,
    самые ценные активы — это файлы журналов (лог-файлы),
    в частности, журнал ошибок. Исправление любой проблемы без журнала ошибок
    можно сравнить с вождением автомобиля с закрытыми глазами.</p>
    
    <p>Расположение журнала ошибок задаётся директивой
    <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code>,
    которая может быть установлена глобально или для каждого виртуального хоста.
    Записи в журнале ошибок расскажут вам, что и когда пошло не так.
    Зачастую они также смогут подсказать, как что-то исправить.
    Каждая запись в журнале ошибок содержит код ошибки,
    по которому вы можете поискать в Интернете более подробное
    описание того, как решить проблему.
    Вы также можете настроить журнал ошибок так, чтобы в него записывался
    идентификатор журнала, который можно сопоставить с записями в журнале
    доступа — это поможет определить, какой запрос какую ошибку вызвал.</p>
    
    <p>Больше о логирование вы можете узнать в
    <a href="logs.html">документации о журналах</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Что дальше?</a></h2>
    
    
    <p>Теперь, когда вы знакомы с основами, пора двигаться дальше.</p>
    
    <p>Этот документ содержит только базовую информацию.
    Мы надеемся, что она поможет вам начать работу,
    но есть множество других вещей, о которых вам, возможно, нужно узнать.</p>
    
    <ul>
    <li><a href="http://httpd.apache.org/download.cgi">Загрузки</a></li>
    <li><a href="install.html">Установка</a></li>
    <li><a href="configuring.html">Настройка</a></li>
    <li><a href="invoking.html">Старт</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">Часто задаваемые вопросы</a></li>
    </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/getting-started.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/getting-started.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ru/getting-started.html" title="Russian">&nbsp;ru&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/getting-started.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Модули</a> | <a href="./mod/directives.html">Директивы</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Глоссарий</a> | <a href="./sitemap.html">Карта сайта</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/install.html.tr.utf8�������������������������������������������������������0000664�0001751�0001751�00000072076�14743132254�020715� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Derleme ve Kurulum - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Derleme ve Kurulum</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Bu belge Apache HTTP Sunucusunun sadece Unix ve Unix benzeri
          sistemlerde derlenmesini ve kurulmasını kapsar. Windows üzerinde
          derleme ve kurulum için <a href="platform/windows.html">Apache HTTP
          Sunucusunun Microsoft Windows ile kullanımı</a> ve <a href="platform/win_compiling.html">Apache HTTP
          Sunucusunun Microsoft Windows için Derlenmesi</a> bölümüne bakınız.
          Diğer platformlar için ise <a href="platform/">platform</a>
          belgelerine bakınız.</p>
    
        <p>Apache HTTP Sunucusunun, derleme ortamını oluşturmak için çoğu Açık
          Kaynak Kodlu projenin yaptığı gibi <code>libtool</code> ve
          <code>autoconf</code> kullanır.</p>
    
        <p>Eğer sadece sürüm yükseltiyorsanız (2.4.8’dwn 2.4.9’a yükseltmek
          gibi) lütfen doğrudan <a href="#upgrading">Yükseltme</a> bölümüne
          atlayınız.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Tez canlılar için genel bir bakış</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#requirements">Gereksinimler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#download">İndirme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extract">Paketi açma</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configure">Kaynak ağacının yapılandırılması</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compile">Derleme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">Kurulum</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#customize">Kişiselleştirme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#test">Deneme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#upgrading">Yükseltme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#thirdp">Üçüncü parti paketler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="programs/configure.html">Kaynak ağacının yapılandırılması</a></li><li><a href="invoking.html">Apache httpd’nin başlatılması</a></li><li><a href="stopping.html">Durdurma ve yeniden başlatma</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Tez canlılar için genel bir bakış</a></h2>
        <dl>
        <dt>Fedora/CentOS/Red Hat Enterprise Linux üzerinde kurulum</dt>
        <dd>
        <pre class="prettyprint lang-">sudo yum install httpd
    sudo systemctl enable httpd
    sudo systemctl start httpd</pre>
    
    
        <div class="warning">Bu dağıtımların yeni sürümlerinde <code>yum</code> 
        yerine <code>dnf</code> kullanılmaktadır.<code>yum</code>. Daha ayrıntılı 
        bilgi için <a href="https://fedoraproject.org/wiki/Apache_HTTP_Server">Fedora projesinin 
        belgelerine</a> bakınız.</div>
        </dd>
    
        <dt>Ubuntu/Debian üzerinde kurulum</dt>
        <dd>
    <pre class="prettyprint lang-">sudo apt install apache2
    sudo service apache2 start</pre>
    
    
        <div class="warning">Daha ayrıntılı bilgi için <a href="https://help.ubuntu.com/lts/serverguide/httpd.html">Ubuntu 
        belgelerine</a> bakınız.</div>
    
        </dd>
    
        <dt>Kaynak koddan kurulum</dt>
        <dd>
        <table>
          
          <tr>
            <td><a href="#download">İndirme</a></td>
    
            <td><a href="http://httpd.apache.org/download.cgi#apache24">http://httpd.apache.org/download.cgi</a> adresinden en son 
              dağıtımı indirin.
    
            </td>
          </tr>
    
          <tr>
            <td><a href="#extract">Paketi açma</a></td>
    
            <td><code>$ gzip -d httpd-<em>NN</em>.tar.gz<br />
             $ tar xvf httpd-<em>NN</em>.tar<br />
             $ cd httpd-<em>NN</em></code></td>
          </tr>
    
          <tr>
            <td><a href="#configure">Yapılandırma</a></td>
    
            <td><code>$ ./configure --prefix=<em>ÖNEK</em></code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#compile">Derleme</a></td>
    
            <td><code>$ make</code> </td>
          </tr>
    
          <tr>
            <td><a href="#install">Kurulum</a></td>
    
            <td><code>$ make install</code> </td>
          </tr>
    
          <tr>
            <td><a href="#customize">Kişiselleştirme</a></td>
    
            <td><code>$ vi <em>ÖNEK</em>/conf/httpd.conf</code> </td>
          </tr>
    
          <tr>
            <td><a href="#test">Deneme</a></td>
    
            <td><code>$ <em>ÖNEK</em>/bin/apachectl -k start</code>
            </td>
          </tr>
        </table>
    
        <p><em>NN</em> yerine kuracağınız sürümü, <code><em>ÖNEK</em></code>
          yerine de dosya sisteminde sunucunun altına kurulacağı dizin yolunu
          yazınız. <code><em>ÖNEK</em></code> belirtilmezse
          <code>/usr/local/apache2</code> öntanımlıdır.</p>
    
        <p>Derleme ve kurulum işleminin her aşaması, Apache HTTPd Sunucusunun
          derlenmesi ve kurulması için gerekenler başta olmak üzere aşağıda
          ayrıntılı olarak açıklanmıştır.</p>
        </dd>
        </dl>
    
        <div class="warning">Kullandığınız platformu burada göremiyor musunuz?
        <a href="http://httpd.apache.org/docs-project/">Bu belgeleri geliştirmek 
         için gelin bize yardımcı olun.</a></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">Gereksinimler</a></h2>
    
        <p>Apache httpd’yi derleyebilmek için şunlar mevcut olmalıdır:</p>
    
        <dl>
          <dt>APR ve APR-Util</dt>
          <dd>APR ve APR-Util'in sisteminizde kurulu olduğundan emin olun. Kurulu
            değilse veya sisteminizce sağlanmış sürümlerini kullanmak
            istemiyorsanız APR ve APR-Util'in ikisini birden <a href="http://apr.apache.org/">Apache APR</a>'den indirin ve onları
            Apache httpd dağıtımını açtığınız dizinin altında
            <code>/httpd_kaynakkod_kök_dizini/srclib/apr</code> ve
            <code>/httpd_kaynakkod_kök_dizini/srclib/apr-util</code> dizinlerine
            açın (Dizin isimlerinin sürüm numarası içermemesine dikkat edin,
            örneğin, APR dağıtımı
            <code>/httpd_kaynakkod_kök_dizini/srclib/apr/</code> altında olsun.)
            ve <code>./configure</code> betiğinin <code>--with-included-apr</code>
            seçeneğini kullanın. Bazı platformlarda, httpd'nin, kurulu APR ve
            APR-Util kopyanıza karşın derlenmesini sağlamak için ilgili
            <code>-dev</code> paketlerini kurmanız gerekebilir.</dd>
    
          <dt>Perl-Uyumlu Düzenli İfade Kütüphanesi (PCRE)</dt>
          <dd>Bu kütüphane gereklidir, ancak artık httpd ile birlikte
            dağıtılmamaktadır. Kaynak kodunu <a href="http://www.pcre.org/">http://www.pcre.org</a> sitesinden indirin ve bir port veya paket
            olarak kurun. Eğer derleme sisteminiz PCRE kurulumunuz tarafından
            kurulan <code>pcre-config</code> betiğini bulamazsa
            <code>--with-pcre</code> seçeneğini kullanarak yerini belirtin. Bazı
            platformlarda, httpd'nin, kurulu PCRE kopyanıza karşın derlenmesini
            sağlamak için ilgili <code>-dev</code> paketlerini kurmanız
            gerekebilir.</dd>
    
          <dt>Disk Alanı</dt>
          <dd>Geçici olarak en azından 50 MB boş disk alanınız olduğundan emin
            olunuz. Kurulumdan sonra sunucu yaklaşık 10 MB disk alanı kaplıyor
            olacaktır. Asıl disk alanı gereksinimi seçtiğiniz yapılandırma
            seçeneklerine, üçüncü parti modüllere ve şüphesiz sitenizin veya sunucu
            üzerindeki sitelerin boyutlarına göre değişiklik
            gösterecektir.</dd>
    
          <dt>ANSI-C Derleyici ve Derleme Sistemi</dt>
          <dd>Bir ANSI-C derleyicinin kurulu olduğundan emin olunuz. <a href="http://www.gnu.org/">Free Software Foundation (FSF)</a>
            tarafından dağıtılan <a href="http://gcc.gnu.org/">GNU C derleyicisini
            (GCC)</a> kullanmanız önerilir. GCC yoksa en azından satıcınızın
            derleyicisinin ANSI uyumlu olduğundan emin olunuz. Ayrıca,
            <code>PATH</code> ortam değişkeninizin içerdiği yollarda
            <code>make</code> gibi temel derleme araçları da bulunmalıdır.</dd>
    
          <dt>Zamanın doğru belirlenmesi</dt>
          <dd>HTTP protokolünün elemanları sunuldukları tarih ve saate göre ifade
            edilirler. Bu bakımdan sisteminizdeki zaman ayarlama oluşumunun
            ayarlarını gözden geçirmenizin tam sırasıdır. Bu amaçla, Ağ Zaman
            Protokolüne (NTP) göre çalışan <code>ntpdate</code> veya
            <code>xntpd</code> programları kullanılır. NTP yazılımları ve halka
            açık zaman sunucuları hakkında daha ayrıntılı bilgi için <a href="http://www.ntp.org">NTP sitesine bakınız</a>.</dd>
    
          <dt><a href="http://www.perl.org/">Perl 5</a> [SEÇİMLİK]</dt>
          <dd>Perl ile yazılmış <code class="program"><a href="./programs/apxs.html">apxs</a></code> veya
            <code class="program"><a href="./programs/dbmmanage.html">dbmmanage</a></code> gibi bazı betikleri desteklemek için
            Perl 5 yorumlayıcısı gerekir (5.003 veya daha yeni sürümleri
            yeterlidir). Eğer <code class="program"><a href="./programs/configure.html">configure</a></code> betiği sisteminizde
            Perl 5 yorumlayıcısı
            bulamazsa bu betikleri kullanamazsınız. Ancak, bu durum Apache
            HTTPd’nin derlenip kurulmasına engel değildir.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="download" id="download">İndirme</a></h2>
    
        <p>Apache HTTP Sunucusunu, çeşitli yansıların da listelendiği <a href="http://httpd.apache.org/download.cgi">Apache HTTP Sunucusu
          indirme sayfasından</a> indirebilirsiniz. Unix benzeri sistemler
          kullanan Apache HTTPd kullanıcılarının kaynak paketlerinden birini
          indirip derlemeleri daha iyi olacaktır. Derleme işlemi (aşağıda
          açıklanmıştır) kolaydır ve sunucunuzu ihtiyaçlarınıza uygun olarak
          kişiselleştirmenize imkan tanır. Ayrıca, hazır derlenmiş paketler
          çoğunlukla en son kaynak sürüm kadar güncel değildirler. Eğer böyle bir
          paket indirmişseniz, kurarken paketin içinde bulunan
          <code>INSTALL.bindist</code> dosyasındaki talimatlara uyunuz.</p>
    
        <p>İndirme işleminin ardından Apache HTTP Sunucusunun eksiksiz ve
          değişikliğe uğramamış olduğunun doğrulanması önemlidir. Bu indirilen
          tar paketinin PGP imzasına göre sınanması ile sağlanabilir. Bunun nasıl
          yapılacağı <a href="http://httpd.apache.org/download.cgi#verify">indirme
          sayfasında</a> anlatıldığı gibi <a href="http://httpd.apache.org/dev/verification.html">PGP
          kullanımının</a> anlatıldığı daha geniş bir örnek de vardır.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extract" id="extract">Paketi açma</a></h2>
    
        <p>Apache HTTP Sunucusu tar paketinden sıkıştırmayı kaldırdıktan sonra tar
          arşivinden dosyaları çıkarmak basit bir işlemdir:</p>
    
        <div class="example"><p><code>
          $ gzip -d httpd-<em>NN</em>.tar.gz<br />
          $ tar xvf httpd-<em>NN</em>.tar
        </code></p></div>
    
        <p>Bu işlem bulunduğunuz dizinin içinde dağıtımın kaynak dosyalarını
          içeren yeni bir dizin oluşturacaktır. Sunucuyu derleme işlmine
          başlayabilmek için önce <code>cd</code> ile bu dizine geçmelisiniz.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">Kaynak ağacının yapılandırılması</a></h2>
    
        <p>Sonraki adım, Apache HTTPd kaynak ağacının platformunuza ve kişisel
          gereksinimlerinize uygun olarak yapılandırılmasıdır. Bu işlem dağıtımın
          kök dizininde bulunan <code class="program"><a href="./programs/configure.html">configure</a></code> betiği kullanılarak
          yapılır. (Apache HTTPd kaynak ağacının resmen dağıtıma girmemiş bir
          sürümünü indiren geliştiricilerin sistemlerinde <code>autoconf</code> ve
          <code>libtool</code> kurulu olması ve sonraki adıma geçmek için
          <code>buildconf</code> çalıştırmaları gerekir. Bu işlem resmi
          dağıtımlar için gerekli değildir.)</p>
    
        <p>Kaynak ağacını tamamen öntanımlı seçenekler kullanılarak derlemek için
          <code>./configure</code> komutunu vermek yeterlidir. Öntanımlı
          seçenekleri değiştirmek için <code class="program"><a href="./programs/configure.html">configure</a></code> betiği
          çeşitli değişkenler ve komut satırı seçenekleri kabul eder.</p>
    
        <p>En önemli seçenek, Apache HTTP Sunucusunun kurulacağı yerin
          belirlenmesini, dolayısıyla Apache’nin bu konumda doğru olarak
          çalışması için yapılandırılmasını sağlayan <code>--prefix</code>’tir.
          Kurulacak dosyaların yerleri ile ilgili daha ayrıntılı denetim ek <a href="programs/configure.html#installationdirectories">yapılandırma
          seçenekleri</a> ile mümkün kılınmıştır.</p>
    
        <p>Bu noktada ayrıca, Apache HTTPd’de hangi özelliklerin bulunmasını
          istediğinizi <a href="mod/">modülleri</a> etkin kılarak veya iptal
          ederek belirtebilirsiniz. Apache, öntanımlı olarak içerilmiş pek çok
          modülle gelir. Bunlar çalışma anında devereye sokulup çıkarılabilen <a href="dso.html">paylaşımlaı nesneler (DSO'lar)</a> olarak derlenebilir.
          Ayrıca, istediğiniz modülleri derleme sırasında
          <code>--enable-<var>module</var>=static</code> seçeneğini kullanarak
          durağan olarak derleyebilirsiniz. Ek modüller <code>--enable-
          <var>modül</var></code> seçenekleri kullanılarak etkinleştirilir.
          Buradaki <code><var>modül</var></code>, önünden <code>mod_</code> dizgesi
          kaldırılmış ve içindeki altçizgi imleri tire imleri ile değiştirilmiş
          modül ismidir. Temel modülleri de benzer şekilde
          <code>--disable-<var>modül</var></code> seçenekleriyle iptal
          edebilirsiniz. <code class="program"><a href="./programs/configure.html">configure</a></code> betiği mevcut olmayan
          modüller için sizi uyarmayıp, seçeneği yok saymakla yetineceğinden, bu
          seçenekleri kullanırken dikkatli olmalısınız.</p>
    
        <p>Ek olarak, bazen kullandığınız derleyici, kütüphaneler veya başlık
          dosyalarının yerleri hakkında <code class="program"><a href="./programs/configure.html">configure</a></code> betiğine
          ilave bilgiler sağlamanız gerekir. Bu işlem
          <code class="program"><a href="./programs/configure.html">configure</a></code> betiğine ya ortam değişkenleriyle ya da
          komut satırı seçenekleriyle bilgi aktarılarak yapılır. Daha fazla bilgi
          için <code class="program"><a href="./programs/configure.html">configure</a></code> kılavuz sayfasına bakınız.</p>
    
        <p>Apache’yi derlerken ne gibi olasılıklara sahip olduğunuz hakkında bir
          izlenim edinmeniz için aşağıda tipik bir örneğe yer verilmiştir. Bu
          örnekte, Apache’nin <code>/sw/pkg/apache</code> önekiyle başlayan
          dizinlere kurulması, belli bir derleyici ve derleyici seçenekleriyle
          derlenmesi ve <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> ve
          <code class="module"><a href="./mod/mod_lua.html">mod_lua</a></code>modüllerinin de DSO mekanizması üzerinden
          daha sonra yüklenmek üzere derlenmesi istenmektedir:</p>
    
        <div class="example"><p><code>
          $ CC="pgcc" CFLAGS="-O2" \<br />
           ./configure --prefix=/sw/pkg/apache \<br />
           --enable-ldap=shared \<br />
           --enable-lua=shared
        </code></p></div>
    
        <p><code class="program"><a href="./programs/configure.html">configure</a></code> betiği başlatıldığında sisteminizde
          mevcut özelliklerin işe yararlığını sınamak ve sonradan sunucuyu
          derlemek için kullanılacak Makefile dosyalarını oluşturmak için bir kaç
          dakika çalışacaktır.</p>
    
        <p><code class="program"><a href="./programs/configure.html">configure</a></code> seçeneklerinin tamamı ayrıtılı olarak
          <code class="program"><a href="./programs/configure.html">configure</a></code> kılavuz sayfasında açıklanmıştır.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile" id="compile">Derleme</a></h2>
    
        <p>Artık, Apache HTTPd paketini şekillendiren çeşitli parçaları derlemek
          için basitçe aşağıdaki komutu verebilirsiniz:</p>
    
        <div class="example"><p><code>$ make</code></p></div>
    
        <p>Bu komutu verdikten sonra lütfen sabırlı olunuz. Temel yapılandırmanın
          derlenmesi bir kaç dakika alsa da modüllerin derlenmesi donanımınıza ve
          seçtiğiniz modüllerin sayısına bağlı olarak daha uzun süre
          gerektirecektir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">Kurulum</a></h2>
    
        <p>Şimdi sıra <code><em>ÖNEK</em></code> dizini altına kurulmak üzere
          yapılandırdığınız (yukarı <code>--prefix</code> seçeneğine bakınız)
          paketi kurmaya geldi. Basitçe şu komutu veriniz:</p>
    
    <div class="example"><p><code># make install</code></p></div>
    
        <p><code><em>ÖNEK</em></code> dizininde genellikle yazma izinlerinin
          sınırlı oluşu nedeniyle bu adım genellikle root yetkilerini
          gerektirir.</p>
    
        <p>Eğer sürüm yükseltiyorsanız, kurulum sırasında mevcut yapılandırma
          dosyalarının ve belgelerin üzerine yazılmayacaktır.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customize" id="customize">Kişiselleştirme</a></h2>
    
        <p>Bu adımda, Apache HTTP Sunucunuzu <code><em>ÖNEK</em>/conf/</code>
          dizini altındaki <a href="configuring.html">yapılandırma
          dosyalarını</a> düzenleyerek kişiselleştirebilirsiniz.</p>
    
        <div class="example"><p><code>$ vi <em>ÖNEK</em>/conf/httpd.conf</code></p></div>
    
        <p>Bu kılavuz ve kullanılabilecek <a href="mod/directives.html">yapılandırma yönergelerinin</a> kılavuzlarını
          <code><em>ÖNEK</em>/<a href="./">docs/manual/</a></code> altında
          bulabileceğiniz gibi en son sürümünü daima <a href="http://httpd.apache.org/docs/2.4/">http://httpd.apache.org/docs/2.4/</a> adresinde
          bulabilirsiniz.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="test" id="test">Deneme</a></h2>
    
        <p>Artık Apache HTTP Sunucunuzu <a href="invoking.html">başlatmaya</a>
          hazırsınız. Hemen şu komutu verin:</p>
    
        <div class="example"><p><code>$ <em>ÖNEK</em>/bin/apachectl -k start</code></p></div>
    
        <p><code>http://localhost/</code> üzerinden ilk belgeniz için bir istek
          yapmalısınız. Genellikle <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> olarak bilinen
          <code><em>ÖNEK</em>/htdocs/</code> altındaki sayfayı görürsünüz.
          Çalışmakta olan sunucuyu <a href="stopping.html">durdurmak</a> için şu
          komutu verebilirsiniz:</p>
    
        <div class="example"><p><code>$ <em>ÖNEK</em>/bin/apachectl -k stop</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">Yükseltme</a></h2>
    
        <p>Sürüm yükseltme işleminin ilk adımı, sitenizi etkileyen değişiklikleri
          öğrenmek için dağıtım duyurusunu ve kaynak paketindeki
          <code>CHANGES</code> dosyasını okumaktır. Ana sürümlerden yükseltme
          yapıyorsanız (2.0’ten 2.2’ye veya 2.2’den 2.4’e gibi), derleme anı ve
          çalışma anı yapılandırmalarındaki ana farklılıklar elle ayarlamalar
          yapmanızı gerektirecektir. Ayrıca, tüm modüllerin de modül API’sindeki
          değişikliklere uyum sağlaması için yükseltilmesi gerekecektir.</p>
    
        <p>Aynı ana sürüm içinde yükseltme yapmak (2.2.55’ten 2.2.57’ye
          yükseltmek gibi) daha kolaydır. <code>make install</code> işlemi,
          mevcut yapılandırma ve günlük dosyalarınızın ve belgelerin üzerine
          yazmayacaktır. Ek olarak, geliştiriciler alt sürüm değişikliklerinde
          <code class="program"><a href="./programs/configure.html">configure</a></code> seçenekleri, çalışma anı yapılandırması
          veya modül API’sinde uyumsuz değişiklikler yapmamaya özen
          göstereceklerdir. Çoğu durumda, aynı <code class="program"><a href="./programs/configure.html">configure</a></code> komut
          satırını, aynı yapılandırma dosyasını kullanabileceksiniz ve tüm
          modülleriniz de çalışmaya devam edebilecektir.</p>
    
        <p>Aynı ana sürüm içinde yükseltme işlemine, eski kaynak ağacının kök
          dizininde veya kurulu sunucunuzun <code>build</code> dizininde
          bulacağınız <code>config.nice</code> dosyasını yeni kaynak ağacının kök
          dizinine kopyalamak suretiyle başlayabilirsiniz. Bu dosya evvelce
          kaynak ağacını yapılandırmakta kullandığınız
          <code class="program"><a href="./programs/configure.html">configure</a></code> komut satırını içerir.
          <code>config.nice</code> dosyasında yapmak istediğiniz değişiklikler
          varsa yaptıktan sonra şu komutları veriniz:</p>
    
        <div class="example"><p><code>
        $ ./config.nice<br />
        $ make<br />
        $ make install<br />
        $ <em>ÖNEK</em>/bin/apachectl -k graceful-stop<br />
        $ <em>ÖNEK</em>/bin/apachectl -k start<br />
        </code></p></div>
    
        <div class="warning">Her yeni sürümü hizmete sokmadan önce daima çalışma
          ortamınızda denemeniz gerekir. Örneğin, yükseltme işlemini
          sonuçlandırmadan önce eski sürümün çalışmasını durdurmadan yenisini
          farklı bir <code>--prefix</code> ile kurabilir ve farklı bir port ile
          (<code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesini
          ayarlamak suretiyle) çalıştırabilirsiniz.</div>
    
        <p>Özgün <code class="program"><a href="./programs/configure.html">configure</a></code> seçeneklerinizi değiştirmek veya
          yeni seçenekler eklemek isterseniz bunları <code>config.nice</code>
          betiğine komut satırı argümanları olarak belirtebilirsiniz:</p>
    
        <div class="example"><p><code>
        $ ./config.nice --prefix=/home/dnm/apache --with-port=90
        </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="thirdp" id="thirdp">Üçüncü parti paketler</a></h2>
    
        <p>Üçüncü partilerin çoğunun, Apache HTTP Sunucusunun belli bir platforma
          kurulumu için paketlenmiş kendi dağıtımları vardır. Çeşitli Linux
          dağıtımları, üçüncü parti Windows paketleri, Mac OS X, Solaris ve daha
          pek çokları bunlar arasında sayılabilir.r</p>
    
        <p>Yazılım lisansımız bu çeşit yeniden dağıtımlara izin verdiği gibi
          bunları cesaretlendirir de. Ancak, sunucunun kurulum ve yapılandırmasının
          belgelerimizde belittiğimizden farklı olması gibi bir durum ortaya
          çıkabilir. Ne yazık ki, bu durum yakın zamanda değişecekmiş gibi
          görünmüyor.</p>
    
        <p>Bu <a href="http://wiki.apache.org/httpd/DistrosDefaultLayout">üçüncü parti
          dağıtımlarla ilgili bir açıklamaya</a> HTTP
          Sunucu wikisinde yer verilmiş olup bunların şu anki durumunu
          yansıtmaktadır. Ancak, yine de, dağıtımınızın belli platformlarla ilgili
          paket yönetimi ve kurulum işlemleri hakkında bilgi sahibi olmanız
          gerekmektir.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/install.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html.tr.utf8������������������������������������������������������0000664�0001751�0001751�00000032614�14743132254�021065� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTPd’nin başlatılması - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTPd’nin başlatılması</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Apache normal olarak, Windows'ta bir hizmet olarak çalışır. Ayrıntılı
          bilgi için <a href="platform/windows.html#winsvc">Apache HTTPD’nin bir
          hizmet olarak çalıştırılması</a> bölümüne bakınız.</p>
    
        <p>Unix’te ise artalanda isteklere yanıt vermek için sürekli çalışan bir
          artalan sürecidir. Bu belgede <code class="program"><a href="./programs/httpd.html">httpd</a></code>’nin nasıl
          çalıştırılacağı açıklanmaktadır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#startup">Apache Nasıl Başlatılır?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errors">Başlatma Sırasındaki Hatalar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#boot">Sistem Açılışında Başlatma</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#info">Ek Bilgiler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="stopping.html">Durdurma ve Yeniden Başlatma</a></li><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="startup" id="startup">Apache Nasıl Başlatılır?</a></h2>
    
        <p>Yapılandırma dosyasında <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesi ile öntanımlı olan port
          80 (veya 1024’ten küçük herhangi bir port) belirtilmişse Apache HTTP
          Sunucusunu başlatmak için root yetkileri gerekecektir. Sunucu başlatılıp
          günlük dosyalarını açmak gibi bazı ön hazırlık etkinliklerinde
          bulunduktan sonra istemcilerden gelen istekleri dinlemek ve yanıt vermek
          için çeşitli <em>çocuk</em> süreçler başlatır. Ana
          <code class="program"><a href="./programs/httpd.html">httpd</a></code> süreci root kullanıcısının aidiyetinde
          çalışmasını sürdürürken çocuk süreçler daha az yetkili bir kullanıcının
          aidiyetinde çalışır. Bu işlem seçilen <a href="mpm.html">Çok Süreçlilik
          Modülü</a> tarafından denetlenir.</p>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code>’yi çalıştırmak için önerilen yöntem
          <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> betiğini kullanmaktır. Bu betik,
          <code class="program"><a href="./programs/httpd.html">httpd</a></code>’nin bazı işletim sistemlerinde işlevini
          gerektiği gibi yerine getirebilmesi için gereken belli ortam
          değişkenlerini ayarlar ve <code class="program"><a href="./programs/httpd.html">httpd</a></code>’yi çalıştırır.
          <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>, komut satırı argümanlarını
          <code class="program"><a href="./programs/httpd.html">httpd</a></code>’ye aktarabildiğinden gerekli
          <code class="program"><a href="./programs/httpd.html">httpd</a></code> seçenekleri <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>
          betiğine komut satırı seçenekleri olarak belirtilebilir. Ayrıca,
          <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> betiğinin içeriğini doğrudan düzenlemek
          suretiyle betiğin başlangıç satırlarındaki <code>HTTPD</code>
          değişkenine <code class="program"><a href="./programs/httpd.html">httpd</a></code> çalıştırılabilir dosyasının doğru
          yerini ve <em>daima</em> mevcut olmasını istediğiniz komut satırı
          seçeneklerini belirtebilirsiniz.</p>
    
        <p><code>httpd</code> çalıştırıldığında yaptığı ilk şey <a href="configuring.html">yapılandırma dosyası</a>
          <code>httpd.conf</code>’u bulup okumaktır. Bu dosyanın yeri derleme
          sırasında belirtilmekteyse de <code>-f</code> komut satırı seçeneği
          kullanılarak çalıştırma sırasında belirtmek de mümkündür:</p>
    
        <div class="example"><p><code>/usr/local/apache2/bin/apachectl -f
          /usr/local/apache2/conf/httpd.conf</code></p></div>
    
        <p>Başlatma sırasında herşey yolunda giderse sunucu kendini uçbirimden
          ayıracak ve hemen ardından uçbirim, komut istemine düşecektir. Bu,
          sunucunun etkin ve çalışmakta olduğunu gösterir. Artık tarayıcınızı
          kullanarak sunucuya bağlanabilir ve <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> dizinindeki deneme sayfasını
          görebilirsiniz.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errors" id="errors">Başlatma Sırasındaki Hatalar</a></h2>
    
        <p>Apache başlatma sırasında ölümcül bir sorunla karşılaşacak olursa
          çıkmadan önce sorunu açıklayan bir iletiyi konsola veya <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> yönergesi ile belirtilen hata
          günlüğüne yazacaktır. En çok karşılaşılan hata iletilerinden biri
          "<code>Unable to bind to Port ...</code>" dizgesidir. Bu iletiye
          genellikle şu iki durumdan biri sebep olur:</p>
    
        <ul>
          <li>Sunucunun, root yetkileri gerektiren bir portu kullanmak üzere root
            kullanıcısı tarafından çalıştırılmamış olması.</li>
    
          <li>Aynı portu kullanan başka bir Apache Sunucusunun veya başka bir HTTP
            sunucusunun zaten çalışmakta oluşu.</li>
        </ul>
    
        <p>Bu ve diğer sorun çözme talimatları için Apache <a href="http://wiki.apache.org/httpd/FAQ">SSS</a>’sini inceleyiniz.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="boot" id="boot">Sistem Açılışında Başlatma</a></h2>
    
        <p>Sunucunuzun sistem yeniden başlatıldıktan sonra çalışmasına devam
          etmesini istiyorsanız sistem başlatma betiklerinize (genellikle ya
          <code>rc.local</code> dosyasıdır ya da bir <code>rc.N</code> dizininde
          bir dosyadır) <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> betiği için bir çağrı
          eklemelisiniz. Bu, Apache sunucunuzu root yetkileriyle başlatacaktır.
          Bunu yapmadan önce sunucunuzun güvenlik ve erişim kısıtlamaları
          bakımından gerektiği gibi yapılandırıldığından emin olunuz.</p>
    
        <p><code class="program"><a href="./programs/apachectl.html">apachectl</a></code> betiği, bir standart SysV init betiği gibi
          davranacak şekilde tasarlanmıştır. <code>start</code>,
          <code>restart</code> ve <code>stop</code> argümanlarını kabul edebilir
          ve bunları <code class="program"><a href="./programs/httpd.html">httpd</a></code>’ye uygun sinyallere dönüştürebilir.
          Bu bakımdan, çoğunlukla uygun init dizinlerinden birine
          <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> betiği için basitçe bir bağ
          yerleştirebilirsiniz. Fakat bunu yapmadan önce betiğin sisteminizin
          gereklerini yerine getirdiğinden emin olunuz.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="info" id="info">Ek Bilgiler</a></h2>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code>, <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> ve sunucuyla
          gelen diğer destek programlarının komut satırı seçenekleri hakkında ek
          bilgi  <a href="programs/">Sunucu ve Destek Programları</a> sayfasında
          bulunabilir. Ayrıca, Apache dağıtımında bulunan tüm <a href="mod/">modüller</a> ve bunlarla sağlanan <a href="mod/directives.html">yönergeler</a> hakkında da belgeler
          vardır.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/invoking.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/logs.html.tr.utf8����������������������������������������������������������0000664�0001751�0001751�00000125163�14743132254�020207� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Günlük Dosyaları - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Günlük Dosyaları</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bir HTTP sunucusunu verimli şekilde yönetebilmek için oluşabilecek
          sorunlardan başka sunucunun başarımı ve etkinliği hakkında da bazı geri
          bildirimler almak gerekir. Apache HTTP Sunucusu çok kapsamlı ve esnek
          bir günlükleme yeteneğine sahiptir. Bu belgede sunucunun günlükleme
          yeteneğini nasıl yapılandıracağınızdan ve günlük kayıtlarını nasıl
          yorumlayacağınızdan bahsedilecektir.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Giriş</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#security">Güvenlik Uyarısı</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errorlog">Hata Günlüğü</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#permodule">Modüllere göre günlükleme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#accesslog">Erişim Günlüğü</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rotation">Günlük Çevrimi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#piped">Borulu Günlükler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Sanal Konaklar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Diğer Günlük Dosyaları</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Giriş</a></h2>
        
    
      <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code></li><li><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td /></tr></table>
    
      <p>Apache HTTP Sunucusu, isteğin ilk alınışından itibaren, URL eşleme
        işlemleri, bağlantının son çözümlemesi ve bu işlemler sırasına ortaya çıkan
        hatalar da dahil olmak üzere sunucunuzda meydana gelen herşeyi günlüklemek
        için çok çeşitli mekanizmalar içerir. Buna ek olarak, günlükleme
        yetenekleri sağlayan üçüncü parti modüller de kullanılabilir veya mevcut
        günlük dosyalarına girdiler enjekte edilebilir. Ayrıca, CGI programları,
        PHP betikleri ve benzerleri sunucu hata günlüğüne kendi iletilerini
        gönderebilirler.</p>
    
      <p>Bu belgede Apache HTTP Sunucusunun standart parçası olan günlükleme
        modülleri hakkında bilgi verilecektir.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Güvenlik Uyarısı</a></h2>
        
    
        <p>Apache httpd’nin günlük dosyalarını yazdığı dizine yazabilen birinin sunucuyu
          başlatan kullanıcı kimliğine (bu genellikle root olur) erişim
          kazanabileceğine hemen hemen kesin gözüyle bakılabilir. Sonuçlarının
          neler olacağını kestiremiyorsanız günlüklerin yazıldığı dizinde <em>hiç
          kimseye</em> yazma erişimi vermeyin; ayrıntılı bilgi için <a href="misc/security_tips.html">güvenlik ipuçları</a> belgesine
          bakınız.</p>
    
        <p>Buna ilaveten, günlük dosyaları istemci tarafından sağlanmış bilgiler
          de içerebilir. Bu nedenle, kötü niyetli istemcilerin günlük dosyalarına
          denetim karakterleri girmeleri olasılığına karşı ham günlükler ele
          alınırken dikkatli olunmalıdır.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errorlog" id="errorlog">Hata Günlüğü</a></h2>
        
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code></li><li><code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code></li></ul></td></tr></table>
    
        <p>İsmi ve yeri <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> yönergesi
          ile belirtilen sunucu hata günlüğü, en önemli günlük dosyasıdır. Apache
          httpd tarafından istekler işlenirken saptanan hatalar ve tanı bilgileri
          bu dosyaya gönderilir. Sunucuyu başlatırken veya sunucu çalışırken bir
          sorunla karşılaşıldığında, neyin yanlış gittiğini öğrenmek için
          bakılacak ilk yer burasıdır. Günlük kaydı çoğunlukla sorunun nasıl
          düzeltileceği ile ilgili ayrıntıları da içerir.</p>
    
        <p>Hata günlüğü normal olarak bir dosyaya yazılır (genellikle, dosyanın
          ismi Unix sistemlerinde <code>error_log</code>, OS/2 ve Windows’ta ise
          <code>error.log</code>’dur). Ayrıca, Unix sistemlerinde sunucunun
          hataları <code>syslog</code>’a veya <a href="#piped">borulamak suretiyle
          bir programa</a> aktarması da mümkündür.</p>
    
        <p>Hata günlüğünün biçemi <code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code> yönergesi ile belirlenir. Bu yönergeyi
          kullanarak günlüklenen değerleri özelleştirebilirsiniz. Bir biçem
          belirtmezseniz öntanımlı biçem kullanılır. Örnek tipik bir hata iletisi
          içermektedir:</p>
    
        <div class="example"><p><code>
        [Fri Sep 09 10:42:29.902022 2011] [core:error] [pid 35708:tid 4328636416]
        [client 72.15.99.187] Dosya yok: /usr/local/apache2/htdocs/favicon.ico
        </code></p></div>
    
        <p>Günlük girdisinin ilk öğesi iletinin yazıldığı tarih ve saatten oluşur.
          İkincisi iletiyi üreten modülün ismi (bu durumda: core) ile raporlanan
          bilginin önem derecesini belirtir. Bunu varsa sürecin kimliği ve yine
          varsa evre kimliği izler. Sonraki öğe hatanın üretilmesine sebep olan
          istemcinin IP adresini içerir. Kalanı iletinin kendisidir (duruma
          bakılırsa bir dosyaya yapılan istek yerine getirilememiş).</p>
    
        <p>Hata günlüğünde görünebilecek ileti çeşitliliği oldukça fazladır. Çoğu
          yukarıdaki örneğin benzeridir. Hata günlüğü ayrıca, CGI betiklerinin
          hata ayıklama çıktılarını da içerir. Bir CGI betiği tarafından standart
          hataya (<code>stderr</code>) yazılan her türlü bilgi doğrudan hata
          günlüğüne kopyalanır.</p>
    
        <p>Hata günlüğüne ve erişim günlüğüne  <code>%L</code> dizgeciği konularak
          erişim günlüğündeki girdi ile hata günlüğündeki girdiyi ilişkilendirecek
          bir günlük girdisi kimliği oluşturulabilir.
          <code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code> yüklüyse günlük girdisi kimliği olarak
          onun eşsiz istek kimliği de kullanılır.</p>
    
        <p>Sunucuyu denerken olası sorunlara karşı hata günlüğünü sürekli
          izlemelisiniz. Unix sistemlerinde bunu şöyle bir komutla
          sağlayabilirsiniz:</p>
    
        <div class="example"><p><code>
          tail -f error_log
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="permodule" id="permodule">Modüllere göre günlükleme</a></h2>
        
    
        <p><code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> yönergesi, günlük
          iletisinin üretilmesine sebep olan modüle bağlı bir önem seviyesi
          belirleyebilmenizi sağlar. Bu yolla sorun yaşadığınız modülle ilgili
          günlük musluklarını sonuna kadar açabiliri ek olarak ilgilendiğiniz diğer
          modüllerle ilgili ayrıntıları da edinebilirsiniz. Özellikle
          <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> veya <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> gibi
          modüllerde yapılmak isteneni denerken neler olup bittiğini ayrıntılarıyla
          bilmek istediğiniz durumlarda kullanışlıdır.</p>
    
        <p>Bunu <code class="directive">LogLevel</code> yönergesinde modülün ismini
          belirterek yapabilirsiniz:</p>
    
        <pre class="prettyprint lang-config">LogLevel info rewrite:trace5</pre>
    
    
        <p>Bu satırla ana <code class="directive">LogLevel</code> info'ya ayarlanırken
          <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> için musluk <code>trace5</code> seviyesine
          kadar açılmaktadır.</p>
    
        <div class="note">Bu yönerge, Apache HTTP Sunucusunun evvelki sürümlerinde mevcut olan
          <code>RewriteLog</code> gibi günlükleme modüllerinin yerini almıştır.
        </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="accesslog" id="accesslog">Erişim Günlüğü</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li></ul></td></tr></table>
    
        <p>Sunucu erişim günlüğü sunucu tarafından işleme alınan tüm istekleri
          kaydeder. Erişim günlüğünün yeri ve içeriği  <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> yönergesi ile belirlenir.
          <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> yönergesi ile
          günlük içeriğini kişiselleştirmek mümkündür. Bu bölümde sunucunun
          bilgileri erişim günlüğüne kaydetmesi için nasıl yapılandırılacağından
          bahsedilecektir.</p>
    
        <p>Bilginin erişim günlüğünde saklanması günlük yönetiminde ilk
          adımı oluşturur.  Sonraki adım yararlı istatistikleri üretmek için bu
          bilgiyi incelemektir. Günlük incelemesi bu belgenin kapsamına dahil
          değildir ve aslında bu işlem sunucunun yaptığı işlerden biri
          değildir.</p>
    
        <p>Apache httpd’nin çeşitli sürümlerinde erişim günlüklerini denetlemek
          için kullanılan diğer modüller ve yönergeler arasında mod_log_referer,
          mod_log_agent modülleri ve <code>TransferLog</code> yönergesi
          sayılabilir. Artık, daha eski tüm diğer yönergelerin işlevselliklerini
          bir araya toplayan <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> yönergesi kullanılmaktadır.</p>
    
        <p>Erişim günlüğünün girdi biçemi kolayca isteğe göre
          düzenlenebilmektedir. Biçemi belirtmekte kullanılan biçem dizgesi, C
          tarzı printf(1) biçem dizgesini andırır. Sonraki bölümlerde bazı
          örneklere yer verilmiştir. Biçem dizgesini oluşturan belirteçlerin tam
          listesi için <code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code> belgesinin <a href="mod/mod_log_config.html#formats">Günlük Girdilerinin
          Kişiselleştirilmesi</a> bölümüne bakınız.</p>
    
        <h3><a name="common" id="common">Ortak Günlük Biçemi (OGB)</a></h3>
          
    
          <p>Erişim günlüğü için sıklıkla kullanılan bir yapılandırma:</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common
    CustomLog logs/access_log common</pre>
    
    
          <p>İlk satırda belli bir biçem dizgesi için <code>common</code> diye bir
            <em>takma ad</em> tanımlanmaktadır. Biçem dizgesi, sunucuya hangi
            belli bir bilgi parçalarını günlükleyeceğini söyleyen % imli biçem
            belirteçlerinden oluşur. Biçem dizgesine ayrıca dizgesel sabitler de
            yerleştirilebilir ve bunlar erişim günlüğüne oldukları gibi
            kopyalanırlar. Biçem dizgesi içinde çift tırnak karakteri (") biçem
            dizgesini vaktinden önce sonlandırmaması için ters bölü çizgisi ile
            öncelenmelidir. Biçem dizgesi ayrıca, satır sonlarını belirtmek için
            "<code>\n</code>" ve sekmeleri belirtmek için "<code>\t</code>"
            denetim karakterlerini de içerebilir.</p>
    
          <p><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> yönergesi
            evvelce tanımlanmış bir <em>takma adı</em> kullanarak yeni bir günlük
            dosyası tanımlar. Erişim günlüğünün dosya ismi bölü çizgisi ile
            başlamadıkça dosya yolunun <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> değerine göreli olduğu varsayılır.</p>
    
          <p>Yukarıdaki yapılandırma günlük dosyasına girdileri Ortak Günlük
            Biçemi (Common Log Format) adı verilen standart biçemde yazar.
            Bu standart biçem başka HTTP sunucuları tarafından da kullanılır ve
            çoğu günlük inceleme yazılımı tarafından tanınır. Ortak Günlük
            Biçeminde üretilen günlük girdileri şöyle görünür:</p>
    
          <div class="example"><p><code>
            127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET
            /apache_pb.gif HTTP/1.0" 200 2326
          </code></p></div>
    
          <p>Bu günlük girdisini parça parça açıklayalım:</p>
    
          <dl>
            <dt><code>127.0.0.1</code> (<code>%h</code>)</dt>
    
            <dd>Bu, sunucuya istek yapan istemcinin (uzak konağın) IP adresidir.
              Eğer <code class="directive"><a href="./mod/core.html#hostnamelookups">HostnameLookups</a></code>
              yönergesine <code>On</code> değeri atanmışsa sunucu bu IP adresi
              için DNS sorgusu yapacak ve IP adresi yerine bulduğu konak ismini
              yazmaya çalışacaktır. Bununla birlikte, bu işlem sunucuyu epeyce
              yavaşlattığından önerilmemektedir. Konak isimlerini saptamak için en
              iyisi günlük girdilerini <code class="program"><a href="./programs/logresolve.html">logresolve</a></code> gibi bir
              günlük işlemcisinden geçirmektir. Burada raporlanan IP adresi
              doğrudan istemcinin IP adresi olmayabilir. Eğer sunucu ile istemci
              arasında bir vekil sunucu varsa bu IP adresi, vekil sunucunun IP
              adresi olacaktır.</dd>
    
            <dt><code>-</code> (<code>%l</code>)</dt>
    
            <dd>Çıktıdaki bir "tire" imi istenen bilgi parçasının mevcut olmadığı
              anlamına gelir. Bu durumda, mevcut olmayan bilgi istemci makine
              üzerinde <code>identd</code> tarafından belirlenen istemcinin RFC
              1413 kimliğidir. Bu bilgi oldukça güvenilmezdir ve sıkıca denetlenen
              iç ağlar haricinde hemen hemen asla kullanılmamalıdır. Apache,
              <code class="directive"><a href="./mod/mod_ident.html#identitycheck">IdentityCheck</a></code> yönergesine
              <code>On</code> değeri atanmış olmadıkça bu bilgiyi saptamaya
              uğraşmaz.</dd>
    
            <dt><code>frank</code> (<code>%u</code>)</dt>
    
            <dd>Bu, belge isteğinde bulunan kişinin HTTP kimlik doğrulamasıyla
              saptanan kullanıcı kimliğidir. Bu değer CGI betiklerine
              <code>REMOTE_USER</code> ortam değişkeni ile sağlanır. Eğer istek
              için durum kodu 401 ise (aşağıya bakınız) henüz kullanıcının kimliği
              doğrulanmamış olacağından bu değere güvenilmemelidir. Eğer belge
              parola korumalı değilse günlüğün bu kısmı da yukarıdaki gibi
              "<code>-</code>" olacaktır.</dd>
    
            <dt><code>[10/Oct/2000:13:55:36 -0700]</code>
            (<code>%t</code>)</dt>
    
            <dd>İsteğin alındığı tarih ve saat. Biçemi şöyledir:
    
              <p class="indent">
                <code>[gün/ay/yıl:saat:dakika:saniye dilim]<br />
                 gün&nbsp;&nbsp;&nbsp;&nbsp;= 2 hane<br />
                 ay&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 3 harf<br />
                 yıl&nbsp;&nbsp;&nbsp;&nbsp;= 4 hane<br />
                 saat&nbsp;&nbsp;&nbsp;= 2 hane<br />
                 dakika = 2 hane<br />
                 saniye = 2 hane<br />
                 dilim&nbsp; = (`+' | `-') 4 hane</code>
              </p>
              <p>Günlük biçem dizgesinde zaman gösterim biçemini
              <code>%{<em>biçem</em>}t</code> şeklinde belirtmek de mümkündür.
              Buradaki <code><em>biçem</em></code> dizgesi, stardart C
              kütüphanesindeki <code>strftime(3)</code> işlevi için tanımlanmış
              biçem belirteçleriyle veya desteklenen özel belirteçlerle
              oluşturulabilir. Ayrıntılı bilgi için <code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code>
              <a href="mod/mod_log_config.html#formats">biçem dizgelerine</a>
              bakın.</p>
            </dd>
    
            <dt><code>"GET /apache_pb.gif HTTP/1.0"</code>
            (<code>\"%r\"</code>)</dt>
    
            <dd>İstemciden alınan istek satırının çift tırnaklar arasında
              gösterilmesi istenmiştir. İstek satırı en yararlı bilgi parçalarını
              içerir. Birincisi, istemci tarafından kullanılan yöntem
              <code>GET</code>’miş. İkinci olarak istemci
              <code>/apache_pb.gif</code> dosyasını istemiş ve üçüncü olarak
              istemci <code>HTTP/1.0</code> protokolünü kullanmış. İstek satırının
              bazı parçalarını bağımsız olarak da günlüklemek mümkündür. Örneğin,
              "<code>%m %U%q %H</code>" dizgesi, yöntem, yol, sorgu dizgesi ve
              protokolü kaydedecektir; bu dizge "<code>%r</code>" biçem
              belirtecinin tek başına yaptığı işi yapar.</dd>
    
            <dt><code>200</code> (<code>%&gt;s</code>)</dt>
    
            <dd>Bu, sunucunun istemciye gönderdiği durum kodudur. İsteğin
              başarıyla yerine getirilip getirilmediğini gösterdiği için bu bilgi
              çok değerlidir. Durum kodu 2 ile başlıyorsa istek başarıyla yerine
              getirilmiştir, 3 ile başlıyorsa yönlendirilmiştir, 4 ile başlıyorsa
              istemci tarafında bir hata oluşmuştur, 5 ile başlıyorsa sunucuda bir
              hata oluşmuştur. Olası hata kodlarının tam listesi <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">RFC2616 Hiper
              Metin Aktarım Protokolü</a>nün 10. bölümünde bulunabilir.</dd>
    
            <dt><code>2326</code> (<code>%b</code>)</dt>
    
            <dd>Son parça istemciye döndürülen nesnenin yanıt başlığı hariç
              uzunluğudur. Eğer istemciye bir içerik döndürülmemişse bu değer
              "<code>-</code>" olacaktır. Bunun yerine günlüğe "<code>0</code>"
              yazdırmak için <code>%B</code> belirtecini kullanınız.</dd>
          </dl>
        
    
        <h3><a name="combined" id="combined">Birleşik Günlük Biçemi</a></h3>
          
    
          <p>Sıklıkla kullanılan diğer bir biçem dizgesi Birleşik Günlük Biçemi
            (Combined Log Format) olup şöyle kullanılabilir:</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
    CustomLog log/access_log combined</pre>
    
    
          <p>Bu biçem ilaveten 2 alan içermesi dışında Ortak Günlük Biçemi ile
            aynıdır. İlave alanların ikisi de <code>%{<em>başlık</em>}i</code>
            biçeminde olup buradaki <code><em>başlık</em></code>, HTTP isteğindeki
            başlık alanlarından biridir. Bu biçemin kullanıldığı bir erişim
            günlüğü girdisi şöyle olurdu:</p>
    
          <div class="example"><p><code>
            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)"
          </code></p></div>
    
          <p>Ek alanlar:</p>
    
          <dl>
            <dt><code>"http://www.example.com/start.html"</code>
            (<code>\"%{Referer}i\"</code>)</dt>
    
            <dd>HTTP istek başlığı "Referer". İstemcinin raporladığı isteğin
              kaynaklandığı URI. (Bu isteğin yapılmasını sağlayan bağlantıyı
              içeren URL veya istek bir sayfanın bileşenleri ile ilgiliyse istenen
              sayfanın URL’si olabilir.)</dd>
    
            <dt><code>"Mozilla/4.08 [en] (Win98; I ;Nav)"</code>
            (<code>\"%{User-agent}i\"</code>)</dt>
    
            <dd>Tarayıcı kimliğini içeren HTTP istek başlığı. Bu istemcinin
              tarayıcısının raporladığı kendi tanıtım bilgisidir.</dd>
          </dl>
        
    
        <h3><a name="multiple" id="multiple">Çok Sayıda Erişim Günlüğü</a></h3>
          
    
          <p>Yapılandırma dosyasında çok sayıda <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> yönergesi kullanarak çok
            sayıda erişim günlüğü kolayca oluşturulabilir. Örneğin aşağıdaki
            yönergelerle 3 tane erişim günlüğü oluşturulacaktır. İlki temel OGB
            bilgisini içerirken diğer ikisi isteğin kaynaklandığı yeri ve tarayıcı
            kimliğini içerir. Son iki <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> satırı ayrıca, <code>ReferLog</code> ve
            <code>AgentLog</code> yönergelerinin etkilerinin nasıl taklit
            edileceğini de göstermektedir.</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common
    CustomLog logs/access_log common
    CustomLog logs/referer_log "%{Referer}i -&gt; %U"
    CustomLog logs/agent_log "%{User-agent}i"</pre>
    
    
          <p>Bu örnek ayrıca, <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> yönergesi ile bir takma ad tanımlamanın şart
            olmadığını da göstermektedir. Günlük biçemi doğrudan <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> yönergesinde
            belirtilebilir.</p>
        
    
        <h3><a name="conditional" id="conditional">Şarta Bağlı Günlükler</a></h3>
          
    
          <p>Bazı durumlarda istemcinin yaptığı isteğe bağlı olarak erişim
            günlüğünde belli girdilerin dışlanması gerekebilir. Bu, <a href="env.html">ortam değişkenleri</a> sayesinde kolayca yerine
            getirilebilir. Önce isteğin belli koşulları sağladığını belirten bir
            ortam değişkeni ataması yapılır. Bu işlem <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> yönergesi ile yapılır.
            Sonra da, ortam değişkenine bağlı olarak isteklerin günlüğe dahil
            edilip edilmeyeceği <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> yönergesinin
            <code>env=</code> deyimi kullanılarak belirtilir. Bazı örnekler:</p>
    
          <pre class="prettyprint lang-config"># yerel konaktan kaynaklanan istekleri imleyelim
    SetEnvIf Remote_Addr "127\.0\.0\.1" kaydetme
    # robots.txt dosyası isteklerini imleyelim
    SetEnvIf Request_URI "^/robots\.txt$" kaydetme
    # Kalanları günlüğe kaydedelim
    CustomLog logs/access_log common env=!kaydetme</pre>
    
    
          <p>Başka bir örnek olarak, Türkçe belge isteklerini bir dosyaya diğer
            dillerdeki istekleri başka bir dosyaya kaydedelim.</p>
    
          <pre class="prettyprint lang-config">SetEnvIf Accept-Language "tr" turkce
    CustomLog logs/turkce_log common env=turkce
    CustomLog logs/diger_diller_log common env=!turkce</pre>
    
    
          <p>Bir arabellekleme senaryosuna arabelleğin verimli kullanılıp
            kullanılmadığını bilmek isteyelim. Bu basitçe şöyle yapılabilir:</p>
    
          <pre class="prettyprint lang-config">SetEnv CACHE_MISS 1
    LogFormat "%h %l %u %t "%r " %&gt;s %b %{CACHE_MISS}e" common-cache
    CustomLog logs/access_log common-cache</pre>
    
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> önce <code class="module"><a href="./mod/mod_env.html">mod_env</a></code> modülünü
            çalıştıracak ve başarılı olunduğu takdirde içeriği onsuz teslim
            edecektir. Bu durumda arabellek kaybı <code>1</code> olarak
            günlüklenirken arabellek sunumu <code>-</code> olarak
            günlüklenecektir.</p>
    
          <p><code>env=</code> sözdizimine ek olarak, <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> HTTP yanıt kodudaki koşul
            değerlerini günlüklemeyi de destekler:</p>
    
          <pre class="prettyprint lang-config">LogFormat "%400,501{User-agent}i" browserlog
    LogFormat "%!200,304,302{Referer}i" refererlog</pre>
    
    
          <p>Bu örnekte, HTTP durum kodu 400 veya 501 ise <code>User-agent</code>
            başlığı günlüklenecektir. Aksi takdirde, günlüğe bir "-" yazılacaktır.
            Benzer şekilde ikinci örnekte, HTTP durum kodu 200, 304 veya 302
            <strong>değilse</strong> (durum kodlarının öncesindeki "!" imine
            dikkat) <code>Referer</code> başlığı günlüklenecektir.</p>
    
          <p>Koşula bağlı günlük kaydının çok esnek ve güçlü olabileceğini
            göstermiş olsak da günlük içeriğini denetlemenin tek yolu bu değildir.
            Günlük dosyaları sunucu etkinliğini eksiksiz olarak kaydedebildikleri
            takdirde daha yararlı olurlar. Günlük dosyalarını sonradan işleme tabi
            tutarak istenmeyen girdileri kaldırılmış bir kopya almak hem kolay hem
            de daha yararlıdır.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rotation" id="rotation">Günlük Çevrimi</a></h2>
        
    
        <p>Yükü ağır sunucularda günlük dosyalarına kaydedilen bilginin miktarı
          çok büyük boyutlara ulaşabilir. 10.000 istek içeren bir erişim günlüğü
          yaklaşık 1MB yer kaplar. Etkin günlük dosyasını belirli aralıklarla
          değiştirmek veya silmek gerekebilir. Apache httpd çalışırken dosyayı sürekli
          açık tuttuğu ve yazdığı için bu işlem sunucu çalışırken yapılamaz. Bu
          bakımdan, günlük dosyası değiştirildikten veya silindikten sonra yeni
          dosyanın açılması için <a href="stopping.html">sunucunun yeniden
          başlatılması</a> gerekir.</p>
    
        <p><a href="stopping.html#graceful">Nazikçe yeniden başlatmak</a>
          suretiyle sunucunun, mevcut ve bekleyen bağlantıları kaybetmeden yeni
          günlük dosyalarını açması sağlanabilir. Bununla birlikte, bu işlem
          sırasında sunucunun eski isteklere sunumu bitirene kadar eski günlük
          dosyalarına yazmaya devam edebilmesi gerekir. Bu bakımdan, yeniden
          başlatmanın ardından eski günlük dosyaları üzerinde bir işlem yapmadan
          önce biraz beklemek gerekir. Günlük dosyalarını döndürürken kullanılan
          senaryolarda genellikle eski günlük dosyaları yer kazanmak için
          sıkıştırılırlar:</p>
    
        <div class="example"><p><code>
          mv access_log access_log.old<br />
          mv error_log error_log.old<br />
          apachectl graceful<br />
          sleep 600<br />
          gzip access_log.old error_log.old
        </code></p></div>
    
        <p>Günlük çevrimi yapmanın başka bir yolu da sonraki bölümde açıklandığı
          gibi <a href="#piped">borulu günlükler</a> kullanmaktır.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="piped" id="piped">Borulu Günlükler</a></h2>
        
    
        <p>Apache httpd hata ve erişim günlüklerini doğrudan bir dosyaya yazmak
          yerine bir boru üzerinden başka bir sürece yazabilir. Bu yetenek ana
          sunucuya herhangi bir kod eklemeksizin günlükleme esnekliğini şaşırtıcı
          derecede arttırır. Günlükler boruya yazılmak istenirse dosya ismini boru
          karakteriyle ("<code>|</code>") değiştirip ardına günlük girdilerini
          standart girdisinden kabul edecek programın ismini eklemek yeterlidir.
          Apache httpd başlatıldığı zaman borulu günlük işlemini de
          başlatacaktır. Eğer sunucu çalışırken günlükleri kabul eden süreç
          çökerse Apache httpd bu programı yeniden başlatır. (Bu son özelliği
          sebebiyle bu tekniğe “güvenilir borulu günlükleme” adını veriyoruz.)</p>
    
        <p>Borulu günlük süreçleri ana Apache httpd süreci tarafından başlatılır
          ve bu süreçler ana Apache httpd sürecinin kullanıcı kimliğini miras
          alırlar. Yani borulu günlükleme programları aslında root tarafından
          çalıştırılmış gibi olur. Bu bakımdan, bu programları basit ve güvenilir
          kılmak çok önemlidir.</p>
    
        <p>Borulu günlüklerin önemli kullanım alanlarından biri de sunucuyu
          yeniden başlatmak gerekmeksizin günlük çevrimini mümkün kılmaktır.
          Apache HTTP sunucusu bu amaçla kullanılmak üzere
          <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> diye bir program içerir. Örneğin,
          günlükleri 24 saatte bir döndürmek isterseniz bunu şöyle
          yapabilirsiniz:</p>
    
        <pre class="prettyprint lang-config">CustomLog "|/usr/local/apache/bin/rotatelogs /var/log/access_log 86400" common</pre>
    
    
        <p>Borunun diğer ucundaki süreci başlatacak komutun tırnak içine
          alındığına dikkat ediniz. Bu örnekler erişim günlüğü için verilmişse de
          aynı teknik hata günlüğü için de kullanılabilir.</p>
    
        <p>Hariçten bir uygulama olarak <a href="http://www.cronolog.org/">cronolog</a> isminde buna benzer ancak
          çok daha esnek bir program daha vardır.</p>
    
        <p>Borulu günlükler de şarta bağlı günlükleme kadar güçlü olmakla beraber
          çevrimdışı ardıl işlemler gibi daha basit çözümler için
          kullanılmamalıdır.</p>
    
        <p>Öntanımlı olarak borulu günlük süreci bir kabuk kullanmadan
          çalıştırılır. Kabuk kullanarak (genelde <code>/bin/sh -c</code> ile)
          yapılmak istenirse "<code>|</code>" yerine "<code>|$</code>"
          kullanılır:</p>
    
        <pre class="prettyprint lang-config"># Kabuk kullanarak "rotatelogs" çalıştırmak
    CustomLog "|$/usr/local/apache/bin/rotatelogs /var/log/access_log 86400" common</pre>
    
    
        <p>Bu, Apache 2.2 için öntanımlı davranıştı. Kabuk özelliklerine bağlı
          olarak, yeniden başlatma sırasındaki sinyal işleme sorunları ve günlük
          borulama uygulamasının yaşam süresi için ek bir kabuk süreci ile
          sonuçlanabilir. Apache 2.2 ile uyumluluk açısından "<code>||</code>"
          gösterimi de desteklenmekte olup "<code>|</code>" kullanımına
          eşdeğerdir.</p>
    
        <div class="note"><h3>Windows'ta yığın alanı</h3>
        <p>Windows'ta çok sayıda borulu günlükleme süreci çalışırken ve özellikle
          HTTPD bir hizmet olarak çalışıyorsa sorunlar baş gösterebilir. Bunun
          başlıca sebebi masaüstü yığın alanının (heap) dışına taşılmasıdır. Her
          hizmete ayrılan masüstü yığın alanı, kayıt defterindeki
          HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\SubSystems\Windows
          kaydındaki üçüncü değiştirge olan <code>SharedSection</code>
          değeridir. <strong>Bu değeri değiştirirken çok dikkatli olun</strong>;
          bu, Windows kayıt defterini değiştirirken verilen normal
          uyarılardandır, fakat eğer bu değer çok yüksek olursa masaüstü yığın
          alanının tükenebileceği dikkate alınmalıdır.</p>
        </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Sanal Konaklar</a></h2>
        
    
        <p>Bir sunucu çok sayıda <a href="vhosts/">sanal konak</a> ile hizmet
          sunarken bunların günlük kayıtları için çeşitli seçenekler mevcuttur.
          İlk seçenekte, sanki sunucu tek bir konakla hizmet sunuyormuş gibi
          günlük kaydı yapılır. Günlükleme yönergelerini <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümlerinin dışına, ana sunucu
          bağlamına yerleştirerek tüm isteklerin aynı erişim ve hata günlüğüne
          yazılmasını sağlamak olasıdır. Bu teknik, tek tek sanal konaklar için
          kolayca istatistik toplamaya izin vermez.</p>
    
        <p>Eğer  <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
          veya <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> yönergesi bir
          <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümüne
          yerleştirilirse bu sanal konağa bütün erişimler veya hatalar belirtilen
          dosyaya günlüklenecektir. Böyle günlükleme yönergeleri içermeyen sanal
          konakların günlükleri hala ana sunucunun hata ve erişim günlüklerine
          yazılmaya devam edecektir. Bu teknik az sayıda sanal konak barındıran
          sunucular için çok kullanışlıdır. Fakat sanal konak sayısı çok fazlaysa
          bu teknikle günlük dosyalarını yönetmek çok karmaşık bir hal alabilir.
          Ayrıca, <a href="vhosts/fd-limits.html">yetersiz dosya tanıtıcısı</a>
          sorunlarıyla çok sık karşılaşılabilir.</p>
    
        <p>Erişim günlükleri için çok az bir fedakarlıkla çok iyi bir çözüm vardır.
          Günlük biçemine sanal konaklarla ilgili bilgi eklemek suretiyle tüm
          konakların aynı günlük dosyasını kullanmaları olasıdır. Böylece günlük
          dosyası sonradan her sanal konak için ayrı bir dosya oluşturmak üzere
          ayrıştırılabilir. Örneğin, bu işlem için şu yönergeler kullanılıyor
          olsun:</p>
    
        <pre class="prettyprint lang-config">LogFormat "%v %l %u %t \"%r\" %&gt;s %b" ortaksankon
    CustomLog logs/access_log ortaksankon</pre>
    
    
        <p><code>%v</code> belirteci isteği sunan sanal konağın ismini günlüğe
          yazmak için kullanılır. Daha sonra <a href="programs/split-logfile.html">split-logfile</a> gibi bir program
          kullanarak, bu dosyadan her sanal konak için ayrı birer dosya elde
          edilebilir.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Diğer Günlük Dosyaları</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#bufferedlogs">BufferedLogs</a></code></li><li><code class="directive"><a href="./mod/mod_log_forensic.html#forensiclog">ForensicLog</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlogbuffer">ScriptLogBuffer</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptloglength">ScriptLogLength</a></code></li></ul></td></tr></table>
    
        <h3>Gönderilen ve alınan bayt sayısının günlüklenmesi</h3>
          
    
          <p><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code> modülü <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> yönergesinde kullanılan
            biçem belirteçlerine alınan ve gönderilen bayt sayıları için iki
            belirteç (%I ve %O) ekler.</p>
        
    
        <h3>Adli Günlük</h3>
          
    
          <p><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code> modülü istemci isteklerinin kanıt
            olarak kullanılmak amacıyla günlüklenmesini sağlar. Günlükleme her
            istek için isteğe hizmet sunmadan önce ve sonra olmak üzere iki defa
            yapılır. Böylece günlük dosyasında başarılı her istek için iki satır
            bulunur. Adli günlükleme çok sıkı kurallara tabi olup
            kişiselleştirilemez. Güvenlik ve hata ayıklama aracı olarak yararlı
            değildir.</p>
        
    
        <h3><a name="pidfile" id="pidfile">PID Dosyası</a></h3>
          
    
          <p>Apache httpd başlatıldığında, ana httpd sürecinin kimliği (PID)
            <code>logs/httpd.pid</code> dosyasına kaydedilir. Bu dosyanın ismi
            <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> yönergesi ile
            değiştirilebilir. Bu süreç kimliği sistem yöneticisi tarafından ana
            sürece sinyal göndererek artalan sürecini sonlandırmak veya yeniden
            başlatmak için kullanılır. Windows üzerinde bu işlem için
            <code>-k</code> komut satırı seçeneği kullanılır. Bu konuda daha
            ayrıntılı bilgi edinmek için <a href="stopping.html">Durdurma ve
            Yeniden Başlatma</a> belgesine bakınız.</p>
        
    
        <h3><a name="scriptlog" id="scriptlog">Betik Günlüğü</a></h3>
          
    
          <p><code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code> yönergesi CGI
            betiklerinin girdi ve çıktılarını kaydetmenizi mümkün kılmak suretiyle
            hata ayıklamaya yardımcı olur. Bu sadece deneysel amaçla kullanılmalı,
            asıl sunucuya uygulanmamalıdır. <a href="mod/mod_cgi.html">mod_cgi</a>
            belgesinde daha fazla bilgi bulunabilir.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/logs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/install.html.ja.utf8�������������������������������������������������������0000664�0001751�0001751�00000067115�14743132254�020660� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>コンパイルとインストール - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>コンパイルとインストール</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    
        <p>この文書で扱う範囲は、Unix や Unix に類似したシステムでの
        Apache のコンパイルとインストールです。 Windows における
        コンパイルとインストールに関しては「<a href="platform/windows.html">Microsoft
        Windows で Apache を使う</a>」をご覧下さい。
        その他のプラットホームに関しては「<a href="platform/">プラットホーム</a>」をご覧下さい。</p>
    
        <p>Apache 2.0 では他の Open Source プロジェクトと同様、
        ビルド環境構築に <code>libtool</code> と <code>autoconf</code>
        を使うようになっています。</p>
    
        <p>マイナーバージョンからその次のバージョンにアップグレードする
        (2.2.50 から 2.2.51 へ等) 場合は、まず <a href="#upgrading">
        アップグレード</a>をご覧下さい。</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">概要 (せっかちな人向け)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#requirements">必要なもの</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#download">ダウンロード</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extract">展開</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configure">ソースツリーを設定する</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compile">ビルド</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">インストール</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#customize">カスタマイズ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#test">テスト</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#upgrading">アップグレード</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="programs/configure.html">ソースツリーの設定</a></li><li><a href="invoking.html">Apacheの起動</a></li><li><a href="stopping.html">Apacheの停止と再起動</a></li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">概要 (せっかちな人向け)</a></h2>
    
        <table>
          
          <tr>
            <td><a href="#download">ダウンロード</a></td>
    
            <td><code>$ lynx http://httpd.apache.org/download.cgi</code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#extract">展開</a></td>
    
            <td><code>$ gzip -d httpd-<em>NN</em>.tar.gz<br />
             $ tar xvf httpd-<em>NN</em>.tar<br />
             $ cd httpd-<em>NN</em></code></td>
          </tr>
    
          <tr>
            <td><a href="#configure">設定</a></td>
    
            <td><code>$ ./configure --prefix=<em>PREFIX</em></code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#compile">コンパイル</a></td>
    
            <td><code>$ make</code> </td>
          </tr>
    
          <tr>
            <td><a href="#install">インストール</a></td>
    
            <td><code>$ make install</code> </td>
          </tr>
    
          <tr>
            <td><a href="#customize">カスタマイズ</a></td>
    
            <td><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code> </td>
          </tr>
    
          <tr>
            <td><a href="#test">テスト</a></td>
    
            <td><code>$ <em>PREFIX</em>/bin/apachectl -k start</code>
            </td>
          </tr>
        </table>
    
        <p><em>NN</em> は最新のバージョンナンバーに、
        <em>PREFIX</em> はインストールするサーバでのファイルシステムのパスに、
        置き換えてください。<em>PREFIX</em> を指定しなかった場合は、
        デフォルトの <code>/usr/local/apache2</code> になります。</p>
    
        <p>Apache httpd のコンパイルとインストールに必要なものをはじめとして、
        コンパイルとインストールについては、次に詳しく記述されています。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">必要なもの</a></h2>
    
        <p>Apache のビルドには次のものが必要です:</p>
    
        <dl>
          <dt>ディスクスペース</dt>
          <dd>ディスクに少なくとも 50 MB の一時的な空き容量があるように
          気を付けてください。インストール後は Apache は 10 MB 程度の
          ディスクスペースを占めます。実際に必要になるディスクスペースは、
          設定オプションやサードパーティー製モジュールをどう選択するかによって
          大きく変わるでしょう。</dd>
    
          <dt>ANSI-C コンパイラとビルドシステム</dt>
          <dd>ANSI-C コンパイラをインストールしておいて下さい。お薦めは <a href="http://www.gnu.org/">Free Software Foundation (FSF)</a>
          による <a href="http://www.gnu.org/software/gcc/gcc.html">GNU C
          compiler (GCC)</a> です。GCC がない場合は、
          少なくとも提供されているコンパイラが ANSI 準拠であることを確認しておいて下さい。
          それから、変数 <code>PATH</code> には <code>make</code>
          といった基本的なビルドツールが含まれている必要があります。</dd>
    
          <dt>時刻を正確にする</dt>
          <dd>HTTP プロトコルの要素は日時の時刻で表現されています。ですから、
          正確な時刻にシンクロさせる機能をシステムに設定することを吟味してみて下さい。
          Network Time Protocol (NTP) をベースとした ntpdate や xntpd プログラムが
          この目的によく用いられます。NTP ソフトウェアや公開 NTP 
          サーバに関する詳細は、<a href="http://www.ntp.org">NTP ホームページ</a> をご覧下さい。</dd>
    
          <dt><a href="http://www.perl.org/">Perl 5</a>
          [オプション]</dt>
          <dd>提供されているスクリプト幾つか、例えば <code class="program"><a href="./programs/apxs.html">apxs</a></code> や
          <code class="program"><a href="./programs/dbmmanage.html">dbmmanage</a></code> は
          Perl で書かれているので、Perl 
          5 インタプリタが必要になります (5.003 以降)。
          Perl インタプリタを複数インストールしている (たとえば全体のシステムの一部
          としてインストールされている Perl 4 と、自分で追加でインストールした
          Perl 5 があるなどの) 場合、<code>--with-perl</code> オプション (下記参照)
          を使って <code class="program"><a href="./programs/configure.html">configure</a></code> が意図したものを使うように
          明示的に指定すると良いでしょう。
          <code class="program"><a href="./programs/configure.html">configure</a></code> スクリプトで Perl 5 インタプリタが
          見つからない場合は、この影響を受けるサポートスクリプトが使えなくなります。
          もちろん、Apache httpd のコンパイルとインストールは問題なく行えます。</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="download" id="download">ダウンロード</a></h2>
    
        <p>Apache HTTP サーバは <a href="http://httpd.apache.org/download.cgi">Apache HTTP
        サーバダウンロードサイト</a>からダウンロードできますし、
        同じ場所に幾つかのミラーサイトもリストしています。
        UNIX に類似するシステムで Apache を使うユーザは、ソースを
        ダウンロードしてビルドしたほうが良いでしょう。
        ビルドの手順(下記)は簡単ですし、そのおかげでニーズに
        見合ったカスタマイズを簡単にできます。
        さらに、バイナリのリリースはソースリリースよりも
        遅れていることがよくあります。
        それでもバイナリをダウンロードしたのであれば、
        ディストリビューションの中にある <code>INSSTALL.bindist</code> 
        ファイルの説明に従ってください。</p>
    
        <p>ダウンロード後、ダウンロードしたものが Apache HTTP 
        サーバの完全で改竄されていないバージョンであることを
        検証することが重要です。これはダウンロードした tarball の PGP 署名を
        テストすることによって検証します。
        この手順の詳細は <a href="http://httpd.apache.org/download.cgi#verify">ダウンロード
        ページ</a> にあり、さらに詳しい例は <a href="http://httpd.apache.org/dev/verification.html">PGP の使用
        </a> に記載されています。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extract" id="extract">展開</a></h2>
    
        <p>Apache HTTPD の tarball
        からソースファイルを展開して取り出すとは、
        単なる圧縮の解除と tar の展開です:</p>
    
    <div class="example"><p><code>
    $ gzip -d httpd-<em>NN</em>.tar.gz<br />
    $ tar xvf httpd-<em>NN</em>.tar
    </code></p></div>
    
        <p>配布用のソースコードがある現在いるディレクトリの下に、
        新しいディレクトリが作られます。
        サーバをコンパイルする段階に進む前に、そのディレクトリに
        <code>cd</code> で移動してください。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">ソースツリーを設定する</a></h2>
    
        <p>次のステップは、あなたのプラットホームと
        個人的な要求に合うように Apache
        ソースツリーを設定することです。
        これは配布ディレクトリのルートディレクトリにある、
        <code class="program"><a href="./programs/configure.html">configure</a></code>
        スクリプトで行ないます。
         (Apache ソースツリーの未リリース
        版をダウンロードした開発者は、次のステップに進む前に
        <code>autoconf</code> と<code>libtool</code>
        をインストールして <code>buildconf</code>
        を実行する必要があります。
        公式リリースではこの作業は必要ありません。) </p>
    
        <p>デフォルトオプションを使ってソースツリーを全て設定する
        のであれば、単純に <code>./configure</code> とタイプしてください。
        デフォルトオプションを変更できるように、<code class="program"><a href="./programs/configure.html">configure</a></code>
        には様々な変数やコマンドラインオプションが用意されています。</p>
    
        <p>最も重要なオプションは、Apache がこの後でインストールされる位置
        <code>--prefix</code> です。Apache は、このインストール位置に
        おいて正常に動作するように設定しなければならないからです。
        さらに詳細なファイル位置の制御は追加の <a href="programs/configure.html#installationdirectories">設定オプション
        </a> でできます。</p>
    
        <p>この時点で、<a href="mod/">モジュール</a> を有効にしたり
        無効にしたりすることで Apache 本体に含まれる <a href="programs/configure.html#optionalfeatures">機能</a>
        を指定できます。Apache 本体にはデフォルトで、モジュールの <a href="mod/module-dict.html#Status">Base</a> セットが
        含まれます。その他のモジュールは 
        <code>--enable-<var>module</var></code> オプションで
        有効になります。ここで <var>module</var> はモジュールの名前で、
        つまりそれはモジュールの名前から <code>mod_</code> 文字列を取り除いた後に
        アンダースコアをダッシュで置換した文字列です。
        これとは別の方法で <code>--enable-<var>module</var>=shared</code>
        オプションを使って、モジュールを<a href="dso.html">
        シェアードオブジェクト (DSO)</a> -- 実行時にロードしたり
        アンロードしたりできる形式 -- としてコンパイルすることもできます。
        同様に、<code>--disable-<var>module</var></code> オプションで
        Base モジュールを無効化することもできます。
        これらのオプションを使っているときに、もし指定したモジュールが存在しなくても
        <code class="program"><a href="./programs/configure.html">configure</a></code> は警告を上げることなく、単純にオプションを
        無視することに気をつけてください。</p>
    
        <p>上記に加えて、<code class="program"><a href="./programs/configure.html">configure</a></code> スクリプトに、
        コンパイラ、ライブラリ、ヘッダファイルの位置を追加情報として渡す
        必要がある場合があります。このような場合には、環境変数あるいは
        コマンドラインオプションで <code class="program"><a href="./programs/configure.html">configure</a></code> に渡します。
        詳細に関しては <code class="program"><a href="./programs/configure.html">configure</a></code> マニュアルページ
        をご覧ください。あるいは <code>--help</code> オプションつきで
        <code class="program"><a href="./programs/configure.html">configure</a></code> を呼び出してください。</p>
    
        <p>ちょっとどんなことができるかを見せましょう。
        ここで典型的な例として、<code>/sw/pkg/apache</code> 
        というインストールツリーでコンパイラとフラグを指定して、
        さらに二つの追加モジュール <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> と
        <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> を後で DSO 
        メカニズムでロードするようにコンパイルしてみます:</p>
    
    <div class="example"><p><code>
          $ CC="pgcc" CFLAGS="-O2" \<br />
           ./configure --prefix=/sw/pkg/apache \<br />
           --enable-rewrite=shared \<br />
           --enable-speling=shared
    </code></p></div>
    
        <p><code class="program"><a href="./programs/configure.html">configure</a></code> を実行したら、システムの機能を
        テストしたり、後でサーバをコンパイルするために必要な Makefile
        を生成したりするのに数分間かかるでしょう。</p>
    
        <p>個々の <code class="program"><a href="./programs/configure.html">configure</a></code> オプションの詳細に関しては
        <code class="program"><a href="./programs/configure.html">configure</a></code> マニュアルページ
        をご覧ください。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile" id="compile">ビルド</a></h2>
    
        <p>これで Apache の様々なパーツをビルドすることができます。
        次のコマンドを単純に実行するだけです:</p>
    
    <div class="example"><p><code>$ make</code></p></div>
    
        <p>基本的な設定をするのに数分かかりますが、
        あらかじめご了承ください。
        また、時間はハードウェアや有効にしたモジュールの数に
        大きく依存するでしょう。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">インストール</a></h2>
    
        <p>さて、設定したインストール <em>PREFIX</em> 
         (前述の <code>--prefix</code> オプションを参照) 
        以下にパッケージをインストールする段階になりました。
        次のコマンドを実行してください:</p>
    
    <div class="example"><p><code>$ make install</code></p></div>
    
        <p>通常 <em>PREFIX</em> は書き込みパーミッションが制限されている
        ディレクトリになっているので、このステップは通常は
        ルート権限が必要です。</p>
    
        <p>アップグレードする場合は、インストールでは設定ファイルや
        ドキュメントファイルの上書きは行いません。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customize" id="customize">カスタマイズ</a></h2>
    
        <p>次に <code><em>PREFIX</em>/conf/</code> 以下にある <a href="configuring.html">設定ファイル</a>を編集して、
        Apache HTTP サーバをカスタマイズします。</p>
    
    <div class="example"><p><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code></p></div>
    
        <p><code><em>PREFIX</em>/docs/manual/</code> や
        <a href="./">docs/manual/</a> にある Apache マニュアルをざっと見てください。
        または、<a href="http://httpd.apache.org/docs/2.4/">http://httpd.apache.org/docs/2.4/</a>
        にあるマニュアル最新版、<a href="mod/directives.html">設定ディレクティブ</a>に当たってみてください。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="test" id="test">テスト</a></h2>
    
        <p>次のコマンドを実行して Apache HTTP サーバを<a href="invoking.html">開始</a>できます:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k start</code></p></div>
    
        <p>URL <code>http://localhost/</code> を通して最初のドキュメントに対する
        リクエストを発行する事ができるはずです。これで見える
        ウェブページは <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        以下に置かれたもので、通常は
        <code><em>PREFIX</em>/htdocs/</code> でしょう。
        サーバを再び<a href="stopping.html">停止</a>するには、
        次のコマンドを実行します:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k stop</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">アップグレード</a></h2>
    
        <p>アップグレードでまず行なうべきことは、リリースアナウンスと
        ソースディストリビューションに入っている <code>CHANGES</code> を読んで、
        自身のサイトに対して影響を及ぼす変更点を探すことです。
        メジャーリリース間の変更をする場合 (例えば 1.3 から 2.0 へ、2.0 から 2.2 へ)
        は、コンパイル時や実行時の設定に大きな差異があるでしょうから、
        手動の調整が必要になるでしょう。モジュールも全て、API
        の変更に合わせるためにアップグレードが必要になるでしょう。</p>
    
        <p>マイナーバージョンから次のバージョンにアップグレードする場合
        (例えば 2.2.55 から 2.2.57 へ) は、もっと簡単です。
        <code>make install</code> を実行しても今あるドキュメント、
        ログファイル、設定ファイルは上書きされません。
        さらに、マイナーバージョン間では <code class="program"><a href="./programs/configure.html">configure</a></code> オプション、
        実行時の設定、モジュール API に不整合が起こらないように、
        開発者は最大限の努力をしています。
        大抵の場合、同一の <code class="program"><a href="./programs/configure.html">configure</a></code> コマンドライン、
        同一の設定ファイル、モジュール全てが正常に動作するはずです。</p>
    
        <p>マイナーバージョンでアップグレードする場合は、
        既にインストールされているサーバの <code>build</code> ディレクトリ内か、
        以前インストールに使ったソースコードツリーの最上位ディレクトリ内にある、
        <code>config.nice</code> ファイルを探してください。
        このファイルにはソースツリーを設定した時に使った
        <code class="program"><a href="./programs/configure.html">configure</a></code> コマンドラインが、そのまま入っています。
        次のバージョンにアップグレードする場合は <code>config.nice</code>
        ファイルを新しいバージョンのソースツリーにコピーし、
        必要であればそれを編集した後に、次のように実行します。</p>
    
        <div class="example"><p><code>
        $ ./config.nice<br />
        $ make<br />
        $ make install<br />
        $ <em>PREFIX</em>/bin/apachectl -k graceful-stop<br />
        $ <em>PREFIX</em>/bin/apachectl -k start<br />
        </code></p></div>
    
        <div class="warning">新しいバージョンを使用する場合は、
        実際に運用を始める前に、必ず自分用の環境でテストすべきです。
        最終的にアップグレードする前に、非互換性がないかをテストするために、
        例えば、異なる <code>--prefix</code> と異なるポート (<code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> ディレクティブで設定します) 
        を使用することで、古いバージョンに影響を与えずに新しいバージョンを
        インストールし、実行できます。</div>
    
        <p>もとの <code class="program"><a href="./programs/configure.html">configure</a></code> に追加する形で、
        追加の引数を <code>config.nice</code> に渡すこともできます:</p>
    
        <div class="example"><p><code>
        $ ./config.nice --prefix=/home/test/apache --with-port=90
        </code></p></div>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/install.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html.ja.utf8������������������������������������������������������0000664�0001751�0001751�00000034056�14743132254�021034� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache の起動 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache の起動</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Windows 上では、Apache は通常はサービスとして実行されます。
        詳細に関しては、「<a href="platform/windows.html#winsvc">
        サービスとして実行する</a>」をご覧下さい。</p>
    
        <p>Unixでは、<code class="program"><a href="./programs/httpd.html">httpd</a></code> 
        プログラムが、バックグラウンドで常にリクエスト処理を行う
        デーモンとして実行されます。この文書ではどのように
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> を起動するかについて記述しています。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#startup">Apache の起動方法</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errors">起動時のエラー</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#boot">ブート時の起動</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#info">追加情報</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="stopping.html">停止と再起動</a></li><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="startup" id="startup">Apache の起動方法</a></h2>
    
        <p>もし、設定ファイル中で指定されている
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        がデフォルトの 80 (もしくは 1024 以下の他のポート)
        である場合は、Apache を起動するためには root
        権限が必要になりますが、
        これはこの特権ポートにバインドするためです。
        起動して、一度ログファイルを開くといった準備のための
        動作を幾つか実行した後は、クライアントからのリクエストに対する
        listen と応答を実際に行う<em>子</em>プロセスを起動します。
        メインの <code class="program"><a href="./programs/httpd.html">httpd</a></code> プロセスは root 権限で走り続けますが、
        子プロセスはもっと低い権限で走ります。
        これは選択した<a href="mpm.html">マルチプロセッシングモジュール</a>で制御されます。</p>
    
        <p>推奨の <code class="program"><a href="./programs/httpd.html">httpd</a></code> 実行プログラムの起動方法は、
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>
        制御スクリプトを使用する方法です。このスクリプトは、<code class="program"><a href="./programs/httpd.html">httpd</a></code> 
        がオペレーティングシステム上で正常に動作するように必要な環境変数を
        適切に設定して、<code class="program"><a href="./programs/httpd.html">httpd</a></code> バイナリを起動します。
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> はどんなコマンドライン引数も通過させますので、
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> のどのコマンドラインオプションも
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> のオプションとして使用できます。
        また、<code class="program"><a href="./programs/apachectl.html">apachectl</a></code> スクリプトを直接編集し、
        スクリプト先頭付近の <code>HTTPD</code> 変数を変更することで、
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> バイナリの正しい位置を指定したり、<em>常に</em>
        付加させるコマンドライン引数を指定したりすることができます。</p>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code> が起動されてまず最初にすることは、
        <a href="configuring.html">設定ファイル</a>
        <code>httpd.conf</code> の位置を特定して読み込むことです。
        このファイルの位置はコンパイル時に設定されますが、実行時に
        <code>-f</code> コマンドラインオプションを使って
        位置を指定することもできます。例えば次のようにです。</p>
    
    <div class="example"><p><code>/usr/local/apache2/bin/apachectl -f
          /usr/local/apache2/conf/httpd.conf</code></p></div>
    
        <p>スタートアップが万事上手くいったら、サーバはターミナルから
        切り離されて、コマンドプロンプトが即座に戻ってくるでしょう。
        これはサーバが起動している状態を示しています。
        その後はブラウザでサーバに接続して、
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        ディレクトリのテストページを見ることができるでしょう。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errors" id="errors">起動時のエラー</a></h2>
    
        <p>Apache は、起動時に致命的な問題に遭遇すると、
        終了する前に、コンソールか
        <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code>
        のどちらかに問題を記述したメッセージを出力します。
        最もよくあるエラーメッセージは
        「<code>Unable to bind to Port ...</code>」
        です。このメッセージは普通は次のどちらかが原因です。</p>
    
        <ul>
          <li>root でログインしていない時に、
          特権ポートでサーバを起動しようとした。</li>
    
          <li>同じポートに既にバインドされている Apache
          がもう一つあるときや他のウェブサーバが存在している時に、
          サーバを開始しようとした。</li>
        </ul>
    
        <p>より多くの問題解決の方策の説明は、
    	Apache <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> をご覧下さい。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="boot" id="boot">ブート時の起動</a></h2>
    
        <p>システムがリブートした後でも
        サーバが実行され続けるようにしたい場合は、
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>
        を呼び出すものをシステムスタートアップファイル
        (通常 <code>rc.local</code> や <code>rc.N</code>
        内のファイル) に追加しなければなりません。
        この方法では Apache を root 権限で起動します。
        これをする前に、セキュリティやアクセス制限が
        適切に設定されていていることを確認してください。</p>
    
        <p><code class="program"><a href="./programs/apachectl.html">apachectl</a></code> スクリプトは通常は、標準的な SysV init 
        スクリプトとして動作するように設計されています。
        <code>start</code>, <code>restart</code>, <code>stop</code>
        といった引数をとって、<code class="program"><a href="./programs/httpd.html">httpd</a></code> 
        への適切なシグナルに変換します。
        ですから、通常は単に適切な init ディレクトリ内から
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> へリンクすることができます。しかし、
        念のためシステムの要求に合致していることを確認してください。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="info" id="info">追加情報</a></h2>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code> や
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>、サーバに含まれていたその他補助プログラムの、
        コマンドラインオプションに関する追加情報は、
        <a href="programs/">サーバと補助プログラム</a>ページに
        記載されています。
        Apache 配布に含まれている全<a href="mod/">モジュール</a>、
        それによって提供される<a href="mod/directives.html">ディレクティブ</a>
        のドキュメントもあります。</p>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/invoking.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/logs.html.ko.euc-kr��������������������������������������������������������0000664�0001751�0001751�00000072035�14743132254�020472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>α - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>α</h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>ȿ  Ϸ ߻ϴ  Բ 
        Ȱ ɿ  ˾ƾ Ѵ. ġ  ſ ̰
         α  Ѵ.   α  ϴ
         α׿   Ѵ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#security"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errorlog"> α (Error Log)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#accesslog"> α (Access Log)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rotation">α ȯ (Log Rotation)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#piped">α׸  </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">ȣƮ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">ٸ α</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security"> </a></h2>
        
    
        <p> ġ α ִ 丮 
        ִٸ ( root)  ϴ uid  Ȯ 
         ִ. ̸ ʰ αװ  丮 
         <em></em>. ڼ  <a href="misc/security_tips.html"> </a>  ϶.</p>
    
        <p>, Ŭ̾Ʈ   αϿ  ״
        ϵȴ. ׷ ǰ ִ Ŭ̾Ʈ αϿ ڸ
          Ƿ, α׸ ٷ궧 ؾ Ѵ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errorlog" id="errorlog"> α (Error Log)</a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code></li></ul></td></tr></table>
    
        <p><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> þ
         ߿ α   α ̸ ġ Ѵ.
        ġ   Ͽ  û óϴ 
        ߻  Ѵ.  ϰų ϴµ 
        ִٸ  ߸Ǿ   ġ ˷ִ
        ̰    Ѵ.</p>
    
        <p> α״  ( н ýۿ
        <code>error_log</code>,  OS/2
        <code>error.log</code>) Ͽ ϵȴ. н ýۿ
          <code>syslog</code> <a href="#piped">
        Ͽ ٸ α׷</a>   ִ.</p>
    
        <p> α   Ӱ ڼϴ. ׷
        κ  α ׸    ִ.
         , ׸   .</p>
    
        <div class="example"><p><code>
          [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1]
          client denied by server configuration:
          /export/home/live/ap/htdocs/test
        </code></p></div>
    
        <p>α ׸񿡼 ù° ׸ ¥ ð̴. ι°
        ׸ ϴ  ɰ Ÿ. <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> þ  α׿
        ϵǴ  ɰ   ִ. ° ׸
         ߻ Ŭ̾Ʈ IP ̴ּ.   
        ,    Ŭ̾Ʈ  źϵ
        Ǿٰ ִ. û  ( ΰ ƴ)
        Ͻý ε δ.</p>
    
        <p> α׿ ſ پ     ִ.
        κ  ϴ. CGI ũƮ  µ 
        α׿ ϵȴ. CGI ũƮ <code>stderr</code> 
         ״  α׷ ȴ.</p>
    
        <p> α׿  ߰ϰ   . ׷
        û   α  <a href="#accesslog">
        α</a> ϴ ׸ .  ,  
        ڵ尡 403  α ׸ .  α״
          Ƿ   Ͽ  Ȳ
         ߰   ִ.</p>
    
        <p>˻Ҷ     α׸  캸
         . н ýۿ   Ѵ:</p>
    
        <div class="example"><p><code>
          tail -f error_log
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="accesslog" id="accesslog"> α (Access Log)</a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li></ul></td></tr></table>
    
        <p>  α״  óϴ  û Ѵ.
        <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
        þ  α ġ  Ѵ. <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> þ
        Ͽ α׿      ִ.  
          α׿   ϴ  Ѵ.</p>
    
        <p>  α׿  ϴ  α  
        ̴.  ܰ   мϿ  踦 
        ̴.   Ϲ α м ؼ ٷ ,
        α м     ƴϴ. α м 
         α׸ мϴ Ʈ ؼ <a href="http://dmoz.org/Computers/Software/Internet/Site_Management/Log_Analysis/">Open Directory</a>
        ϶.</p>
    
        <p>ġ   mod_log_referer, mod_log_agent,
        <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
          þ Ͽ  α׸ ٷ. 
        <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
        þ  þ   ̾޾Ҵ.</p>
    
        <p> α  ſ  ϴ.  C
        printf(1) Ĺڿ ſ  Ĺڿ Ͽ
        Ѵ.    . Ĺڿ 밡
          ˷ <code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code> <a href="mod/mod_log_config.html#formats">Ĺڿ</a>
        ϶.</p>
    
        <h3><a name="common" id="common">Common α </a></h3>
          
    
          <p> α    .</p>
    
          <div class="example"><p><code>
            LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common<br />
             CustomLog logs/access_log common
          </code></p></div>
    
          <p>׷  α Ĺڿ <em></em>
          <code>common</code> Ѵ. Ĺڿ ۼƮ
          þ Ǹ,     ˸.
          Ĺڿ Ϲ ڸ  ״ α׿ µȴ.
          ǥ (<code>"</code>) ϰ ʹٸ 齽
          տ ٿ Ĺڿ  ƴ ǥѴ. Ĺڿ
          ٹٲ "<code>\n</code>",  "<code>\t</code>" 
          Ư ڸ   ִ.</p>
    
          <p><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
          þ  <em></em> ϴ ο α
          .  α ϸ  
          <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> ̴.</p>
    
          <p>  α(Common Log Format, CLF)̶
           α ׸ Ѵ.  ٸ 鵵 ̷
          ǥ  α׸ ,  α м α׷
            ִ.  CLF  α ׸  :</p>
    
          <div class="example"><p><code>
            127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET
            /apache_pb.gif HTTP/1.0" 200 2326
          </code></p></div>
    
          <p> α ׸  κ Ѵ.</p>
    
          <dl>
            <dt><code>127.0.0.1</code> (<code>%h</code>)</dt>
    
            <dd> û  Ŭ̾Ʈ( ȣƮ) IP
            ̴ּ. <code class="directive"><a href="./mod/core.html#hostnamelookups">HostnameLookups</a></code>
            <code>On</code>̶ ȣƮ ãƼ IP ּ ڸ
             . ׷    ſ   
            Ƿ õ ʴ´. ȣƮ ˷  ߿
            <a href="programs/logresolve.html">logresolve</a>
             α׸ óϴ α׷ ϴ  .
            ⿡  IP ּҴ ڰ ϴ ǻ ּҰ
            ƴ  ִ. Ͻ  ڿ ̿ Ѵٸ,
             ǻ ּҰ ƴ϶ Ͻ ּҰ ϵ ̴.</dd>
    
            <dt><code>-</code> (<code>%l</code>)</dt>
    
            <dd>¿ "ȣ" û   Ÿ.
              ⿡   Ŭ̾Ʈ ǻ
            <code>identd</code>  Ŭ̾Ʈ RFC 1413
            ſ̴.   ſ   ⶧, 
            Ǵ  Ʈ ƴ϶    ϸ
            ȵȴ. <code class="directive"><a href="./mod/core.html#identitycheck">IdentityCheck</a></code>
            <code>On</code> ƴ϶ ġ   
            ˾ƺ õ ʴ´.</dd>
    
            <dt><code>frank</code> (<code>%u</code>)</dt>
    
            <dd>̴ HTTP  ˾Ƴ  û 
            userid̴.    CGI ũƮ
            <code>REMOTE_USER</code> ȯ溯 Ѱ. û
            ڵ尡 401̶ (Ʒ ) ڰ  
            ġ ʾǷ    ȵȴ.  ȣ
            ȣ ʴ´ٸ  ׸  ׸ 
            "<code>-</code>"̴.</dd>
    
            <dt><code>[10/Oct/2000:13:55:36 -0700]</code>
            (<code>%t</code>)</dt>
    
            <dd>
               ûó ģ ð.
              :
    
              <p class="indent">
                <code>[day/month/year:hour:minute:second zone]<br />
                 day =  2<br />
                 month =  3<br />
                 year =  4<br />
                 hour =  2<br />
                 minute =  2<br />
                 second =  2<br />
                 zone = (`+' | `-')  4</code>
              </p>
              α Ĺڿ <code>%{format}t</code> Ͽ
              ٸ  ð   ִ. <code>format</code>
              C ǥ ̺귯 <code>strftime(3)</code> .
            </dd>
    
            <dt><code>"GET /apache_pb.gif HTTP/1.0"</code>
            (<code>\"%r\"</code>)</dt>
    
            <dd>Ŭ̾Ʈ û ֵǥ ִ. û
            ſ    ִ. ù°, Ŭ̾Ʈ 
            ޽ <code>GET</code>̴. °, Ŭ̾Ʈ ڿ
            <code>/apache_pb.gif</code> ûѴ. °, Ŭ̾Ʈ
            <code>HTTP/1.0</code>  Ѵ. û
             κ  α  ִ.  , Ĺڿ
            "<code>%m %U%q %H</code>" "<code>%r</code>" Ȱ
            ޽, , ǹڿ,  αѴ.</dd>
    
            <dt><code>200</code> (<code>%&gt;s</code>)</dt>
    
            <dd>̴  Ŭ̾Ʈ  ڵ̴. 
             (2 ϴ ڵ) û Ͽ, (4
            ϴ ڵ) Ŭ̾Ʈ  ִ, (5 ϴ
            ڵ)   ִ ˷ֹǷ ſ ߿ϴ.
            ڵ ü  <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">HTTP
            Ծ</a> (RFC2616 section 10) ã  ִ.</dd>
    
            <dt><code>2326</code> (<code>%b</code>)</dt>
    
            <dd> ׸   ϰ Ŭ̾Ʈ
              ũ⸦ Ÿ. Ŭ̾Ʈ 
             ٸ   "<code>-</code>"̴. 
              "<code>0</code>" αϷ 
            <code>%B</code> Ѵ.</dd>
          </dl>
        
    
        <h3><a name="combined" id="combined">Combined α </a></h3>
          
    
          <p> Ǵ ٸ Ĺڿ յȷα(Combined
          Log Format)̴.   Ѵ.</p>
    
          <div class="example"><p><code>
            LogFormat "%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\"
            \"%{User-agent}i\"" combined<br />
             CustomLog log/access_log combined
          </code></p></div>
    
          <p>   ׸  ߰  ϰ Common
          α İ  . ߰ ׸ ۼƮ þ
          <code>%{<em>header</em>}i</code> Ѵ. ⼭
          <em>header</em> ڸ  HTTP û  ̸  
          ִ.    α״  :</p>
    
          <div class="example"><p><code>
            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)"
          </code></p></div>
    
          <p>߰ ׸:</p>
    
          <dl>
            <dt><code>"http://www.example.com/start.html"</code>
            (<code>\"%{Referer}i\"</code>)</dt>
    
            <dd>"Referer" ( Ʋʾ) HTTP û .
            Ŭ̾Ʈ ߴٰ  ˸ Ʈ̴.
            (, <code>/apache_pb.gif</code> ũϿų 
            Ʈ̴.)</dd>
    
            <dt><code>"Mozilla/4.08 [en] (Win98; I ;Nav)"</code>
            (<code>\"%{User-agent}i\"</code>)</dt>
    
            <dd>User-Agent HTTP û . Ŭ̾Ʈ 
            ڽſ  ˸ ĺ̴.</dd>
          </dl>
        
    
        <h3><a name="multiple" id="multiple">  α</a></h3>
          
    
          <p>Ͽ  <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> þ
          ϸ  αװ  .  , 
             α׸ . ù° ⺻ CLF 
          ϰ, ι° ° referer  
          Ѵ.   <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>  
           <code>ReferLog</code> <code>AgentLog</code> þ
           䳻  ִ ش.</p>
    
          <div class="example"><p><code>
            LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common<br />
            CustomLog logs/access_log common<br />
            CustomLog logs/referer_log "%{Referer}i -&gt; %U"<br />
            CustomLog logs/agent_log "%{User-agent}i"
          </code></p></div>
    
          <p>,   <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> ݵ
            ʿ  ش.  <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> þ
           α    ִ.</p>
        
    
        <h3><a name="conditional" id="conditional">Ǻ α</a></h3>
          
    
          <p>Ŭ̾Ʈ û ݿ  ش ׸  α׿
          ʰ   ִ. <a href="env.html">ȯ溯</a>
          ϸ  ذȴ. , Ŭ̾Ʈ Ư 
          ϸ ȯ溯 Ѵ.  ۾  <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> Ѵ.
          ׸ <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
          þ <code>env=</code> Ͽ ȯ溯 
           û ְų .  :</p>
    
          <div class="example"><p><code>
            # loop-back ̽ û ǥѴ<br />
            SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog<br />
            # robots.txt Ͽ  û ǥѴ<br />
            SetEnvIf Request_URI "^/robots\.txt$" dontlog<br />
            #  α׿ <br />
            CustomLog logs/access_log common env=!dontlog
          </code></p></div>
    
          <p>ٸ    û  αϿ ϰ,
          񿵾  û ٸ αϿ ϴ 츦
          غ.</p>
    
          <div class="example"><p><code>
            SetEnvIf Accept-Language "en" english<br />
            CustomLog logs/english_log common env=english<br />
            CustomLog logs/non_english_log common env=!english
          </code></p></div>
    
          <p>Ǻ α״ ſ ϰ , ̰ α
           ϴ   ƴϴ. α 
           ൿ Ҷ  ϴ. ߿ ʴ û
          ϰ α мϴ   .</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rotation" id="rotation">α ȯ (Log Rotation)</a></h2>
        
    
        <p> ٻ  αϿ Ǵ  ſ
        .  α״   û 1MB ̻ Ѵ. 
         α׸ űų   α׸ ֱ
        Ȱ ʿ䰡 ִ. ġ  ִ ȿ 
         αϿ ⶧  ϶ α׸ ȯ
         .  α űų   <a href="stopping.html"></a>Ͽ, α  
        Ѵ.</p>
    
        <p><em></em>  ϸ  Ŭ̾Ʈ
         Ȥ   ʰ  α   ִ.
        ׷ ̸    û 񽺸  
         α  ؾ Ѵ. ׷Ƿ 
        α óϱ  󸶰 ٸ ʿ䰡 ִ. Ϲ
          α׸ ȯϰ, ũ ϱ 
        α׸ Ѵ:</p>
    
        <div class="example"><p><code>
          mv access_log access_log.old<br />
          mv error_log error_log.old<br />
          apachectl graceful<br />
          sleep 600<br />
          gzip access_log.old error_log.old
        </code></p></div>
    
        <p>α׸ ȯϴ ٸ     <a href="#piped"> α</a> ϴ ̴.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="piped" id="piped">α׸  </a></h2>
        
    
        <p>ġ   α׿  α׸ Ͽ 
        ʰ   ٸ μ   ִ. 
         ϸ  ڵ带 ߰ʰ ſ ϰ
        α׸ ó  ִ. α׸   ϸ
        ڸ  "<code>|</code>" ڿ ǥԷ
        α ׸  ϸ  ȴ. ġ 
        Ҷ   α μ ϰ, 
        Ǵ  μ  ٽ Ѵ. ( 
        ɶ 츮   "  ִ  α"
        θ.)</p>
    
        <p>  α μ θ ġ httpd μ
        , μ userid . ,   α
        α׷  root ȴ. ׷Ƿ α׷ ϰ
        ϰ   ſ ߿ϴ.</p>
    
        <p> θ ü ɾ ǥ  ϶.
           α׿  ,  α׵ .</p>
    
        <p> ʰ α׸ ȯ  ִ  
        α׸ ϴ ߿ . ġ  ̸ 
        <a href="programs/rotatelogs.html">rotatelogs</a> 
        α׷ Ѵ.   24ð α׸ ȯѴٸ:</p>
    
        <div class="example"><p><code>
          CustomLog "|/usr/local/apache/bin/rotatelogs
          /var/log/access_log 86400" common
        </code></p></div>
    
        <p>ٸ Ʈ <a href="http://www.cronolog.org/">cronolog</a> 
        ξ   α ȯ α׷ ִ.</p>
    
        <p>Ǻ α׿   α״ ſ  ,
        ߿ óϴ       ؼ
        ȵȴ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">ȣƮ</a></h2>
        
    
        <p> <a href="vhosts/">ȣƮ</a> ִ 
        Ҷ   α ٷ  ִ. ,
        ȣƮ Ѱ   α׸   ִ. <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 
        ƴ ּ  α þ θ  û  
        α׿  α׷ ϵȴ.   ȣƮ 
        ó   .</p>
    
        <p><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
         ȿ <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
        <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> þ
        ϸ ش ȣƮ  û  
        Ͽ ϵȴ. α þ  ٸ ȣƮ 
        ּ α׿ α׸ Ѵ.   ȣƮ 
          ſ , ȣƮ  ٸ ϱ
        . , <a href="vhosts/fd-limits.html">ϱڰ
        </a>   ߻Ѵ.</p>
    
        <p> α  ſ  ذå ִ. α Ĺڿ
        ȣƮ   ߰ϸ  ȣƮ  α׸
        ϰ, ߿ α׸ ȣƮ   ִ. 
        ,  þ .</p>
    
        <div class="example"><p><code>
          LogFormat "%v %l %u %t \"%r\" %&gt;s %b"
          comonvhost<br />
          CustomLog logs/access_log comonvhost
        </code></p></div>
    
        <p><code>%v</code> û ϴ ȣƮ ̸
        Ѵ. ߿ <a href="programs/other.html">split-logfile</a>
         α׷  α׸ ȣ   ִ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">ٸ α</a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritelog">RewriteLog</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriteloglevel">RewriteLogLevel</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlogbuffer">ScriptLogBuffer</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptloglength">ScriptLogLength</a></code></li></ul></td></tr></table>
    
        <h3><a name="pidfile" id="pidfile">PID </a></h3>
          
    
          <p>ġ  Ҷ <code>logs/httpd.pid</code>
          Ͽ θ httpd μ process id Ѵ. 
          ϸ <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>
          þ   ִ. process-id ڰ θ μ
          ñ׳   ϰų ϶ Ѵ.
            -k ɼ Ѵ.  ڼ
           <a href="stopping.html">ߴܰ </a> 
          ϶.</p>
        
    
        <h3><a name="scriptlog" id="scriptlog">ũƮ α</a></h3>
          
    
          <p>  <code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code> þ Ͽ
          CGI ũƮ Է°    ִ.  þ
           ׽Ʈθ ؾ Ѵ.  ϴ 
          ϸ ȵȴ.  ڼ  <a href="mod/mod_cgi.html">mod_cgi</a>  ϶.</p>
        
    
        <h3><a name="rewritelog" id="rewritelog">ۼ α</a></h3>
          
    
          <p><a href="mod/mod_rewrite.html">mod_rewrite</a> ϰ
            Ѵٸ    ׻ <code class="directive"><a href="./mod/mod_rewrite.html#rewritelog">RewriteLog</a></code>  ʿ䰡
          ִ.  α ۼ   û ȯϴ
           ڼ ˷ش. ڼ  <code class="directive"><a href="./mod/mod_rewrite.html#rewriteloglevel">RewriteLogLevel</a></code> þ
          Ѵ.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/logs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_4.html.tr.utf8����������������������������������������������0000664�0001751�0001751�00000075243�14743132254�022401� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Sunucusu 2.4'te Yeni olan Özellikler - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Sunucusu 2.4'te Yeni olan Özellikler</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/new_features_2_4.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_4.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/new_features_2_4.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>Bu belgede Apache HTTP Sunucusunun 2.2 ve 2.4 sürümleri arasındaki
        başlıca farklara değinilmiştir. 2.0 sürümüne göre yeni özellikler için <a href="new_features_2_2.html">Apache 2.2’de Yeni olan Özellikler</a>
        belgesine bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Çekirdekteki Gelişmeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#newmods">Yeni Modüller</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Modüllerdeki Gelişmeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Programlardaki Gelişmeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentation">Belgelendirme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Modül Geliştirici Değişiklikleri</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Çekirdekteki Gelişmeler</a></h2>
        
        <dl>
          <dt>Çalışma anında yüklenebilen MPM'ler</dt>
          <dd>Çok sayıda MPM artık <a href="mpm.html#dynamic">yüklenebilir
            modül</a> olarak derlenebilmektedir. Kullanılacak MPM'in seçimi
            çalışma anında <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
            yönergesi üzerinden yapılabilmektedir.</dd>
    
          <dt>Event MPM</dt>
          <dd><a href="mod/event.html">Event MPM</a> artık deneysel değil, ancak
            tam olarak desteklenmiyor.</dd>
    
          <dt>Eşzamansıza destek</dt>
          <dd>MPM'leri ve platformları desteklemek için eşzamansız okuma/yazmaya
            destek iyileştirildi.</dd>
    
          <dt>Modul bazında ve dizin bazına LogLevel yapılandırması</dt>
          <dd><code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> artık her modül ve her
              dizin için yapılandırılabilmektedir. <code>debug</code> log
              seviyesinin üstüne <code>trace1</code>'den <code>trace8</code>'e
              kadar yeni log seviyeleri eklendi.</dd>
    
          <dt>İstek bazında yapılandırma bölümleri</dt>
          <dd><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>,
              <code class="directive"><a href="./mod/core.html#elseif">&lt;ElseIf&gt;</a></code>,
              ve <code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code> bölümleri
              artık HTTP isteklerine dayalı olarak yapılandırılabilmektedir.</dd>
    
          <dt>Genel amaçlı ifade çözümleyici</dt>
          <dd>Yeni ifade çözümleyici
              <code class="directive"><a href="./mod/mod_setenvif.html#setenvifexpr">SetEnvIfExpr</a></code>,
              <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>,
              <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code>,
              <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> ve
              benzeri yönergelerde ortak bir sözdizimi kullanarak <a href="expr.html">karmaşık durumlar</a> belirtmeyi mümkün kılmaktadır.
          </dd>
    
          <dt>Milisaniye cinsinden KeepAliveTimeout</dt>
          <dd><code class="directive"><a href="./mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code> milisaniye
            cinsinden belirtmek artık mümkündür.</dd>
    
          <dt>NameVirtualHost yönergesi</dt>
          <dd>Artık gerekmemekte ve kullanımı önerilmemektedir.</dd>
    
          <dt>Yapılandırma geçersizleştirme</dt>
          <dd>Yeni <code class="directive"><a href="./mod/core.html#allowoverridelist">AllowOverrideList</a></code>
              yönergesi <code>.htaccess</code> dosyalarında kullanılabilen
              yönergelerde daha ince ayarlara izin vermektedir.</dd>
    
          <dt>Yapılandırma dosyası değişkenleri</dt>
          <dd>Yapılandırmada değişkenler <code class="directive"><a href="./mod/core.html#define">Define</a></code> yönergesi ile tanımlanabilmekte, böylece aynı
              değer yapılandırmada bir çok yerde kullanılıyorsa daha temiz bir
              görünüm elde edilebilmektedir.</dd>
    
          <dt>Azaltılmış bellek kullanımı</dt>
          <dd>Bir çok yeni özelliğe karşın, 2.4.x'te 2.2.x'e nazaran bellek
            kullanımı azaltılmıştır.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="newmods" id="newmods">Yeni Modüller</a></h2>
        
        <dl>
          <dt><code class="module"><a href="./mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> için FastCGI Protokolü sağlayıcısı</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_scgi.html">mod_proxy_scgi</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> için SCGI Protokolü sağlayıcısı</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_express.html">mod_proxy_express</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> için devingen olarak yapılandırılmış tam
            tersinir vekiller sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_remoteip.html">mod_remoteip</a></code></dt>
          <dd>İstek başlıklarında bir yük dengeleyici veya bir vekil tarafından
            sunulan IP adres listeli bir istek için görünen istemci IP adresi ve
            konak adını değiştirir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_heartmonitor.html">mod_heartmonitor</a></code>,
              <code class="module"><a href="./mod/mod_lbmethod_heartbeat.html">mod_lbmethod_heartbeat</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> modülünün arka sunuculardaki
            etkin bağlantı sayısı üzerindeki yük dengeleme kararlarına dayalı işlem
            yapmasını sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code></dt>
          <dd>Başta bir üçüncü parti modüldü. Arka plandaki sağlayıcının vekil
            istemcileri için geçersiz URL'ler ürettiği tersinir vekil durumlarında
            HTML bağlarının düzeltilmesini sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_sed.html">mod_sed</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code> modülünün geliştirilmiş hali olup
            yanıt gövdesinin sed'in tüm gücü ile yeniden düzenlenebilmesini
            sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_form.html">mod_auth_form</a></code></dt>
          <dd>Formlara dayalı kimlik kanıtlamayı etkinleştirir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_session.html">mod_session</a></code></dt>
          <dd>Çerezleri ve veritabanı deposunu kullanarak istemciler için oturum
            durumunun saklanmasını etkinleştirir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_allowmethods.html">mod_allowmethods</a></code></dt>
          <dd>Kimlik Doğrulama ve Yetkilendirme ile etkileşmeyen belli HTTP
            yöntemlerine sınır koymak için yeni bir modül.</dd>
    
          <dt><code class="module"><a href="./mod/mod_lua.html">mod_lua</a></code></dt>
          <dd>Küçük iş mantıksal işlevleri ve yapılandırması için httpd içine <a href="http://www.lua.org/">Lua</a> dilini gömer.</dd>
    
          <dt><code class="module"><a href="./mod/mod_log_debug.html">mod_log_debug</a></code></dt>
          <dd>İstek işlemlerinin farklı aşamalarına özelleştirilebilir hata
            ayıklama günlüğü eklenmesini sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_buffer.html">mod_buffer</a></code></dt>
          <dd>Girdi ve çıktı süzgeç yığıtlarına tampon bellek sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_data.html">mod_data</a></code></dt>
          <dd>Yanıt gövdesini bir RFC2397 veri URL'sine dönüştürür.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ratelimit.html">mod_ratelimit</a></code></dt>
          <dd>İstemciler için band genişliği oranında sınırlama sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_request.html">mod_request</a></code></dt>
          <dd>Kullanılabilir HTTP istek gövdelerini yapmak ve elde etmek için
            Süzgeçleri sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code></dt>
          <dd>Çıktı süzgeci yığıtı üzerinden bir yanıt olarak bir istek gövdesinin
            yansısını sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_slotmem_shm.html">mod_slotmem_shm</a></code></dt>
          <dd>Yuva temelli bir paylaşımlı bellek sağlayıcı sağlar (scoreboard
            olarak da bilinir).</dd>
    
          <dt><code class="module"><a href="./mod/mod_xml2enc.html">mod_xml2enc</a></code></dt>
          <dd>Başta bir üçüncü parti modüldü. libxml2 temelli süzgeç modüllerinde
            i18n'i destekler.</dd>
    
          <dt><code class="module"><a href="./mod/mod_macro.html">mod_macro</a></code> (2.4.5'den itibaren kullanılabilir)</dt>
          <dd>Yapılandırma dosyalarında makro kullanımını sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_wstunnel.html">mod_proxy_wstunnel</a></code> (2.4.5'den itibaren
            kullanılabilir)</dt>
          <dd>Web-socket tünelleri için destek.</dd>
    
          <dt><code class="module"><a href="./mod/mod_authnz_fcgi.html">mod_authnz_fcgi</a></code> (2.4.10'dan itibaren
            kullanılabilir)</dt>
          <dd>Kimlik kanıtlama ve/veya istemcileri yetkilendirmek için FastCGI
            yetkilendirme uygulamalarını etkinleştirir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_http2.html">mod_http2</a></code> (2.4.17'den itibaren kullanılabilir)</dt>
          <dd>HTTP/2 aktarım katmanı desteği.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_http2.html">mod_proxy_http2</a></code> (2.4.19'dan itibaren
            kullanılabilir)</dt>
          <dd><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> için HTTP/2 Protokol arayüzü</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_hcheck.html">mod_proxy_hcheck</a></code> (2.4.21'den itibaren
            kullanılabilir)</dt>
          <dd>Uzak vekil artuç sunucuları için bağımsız özdevinimli sağlık
            sınamalarını destekler.</dd>
    
          <dt><code class="module"><a href="./mod/mod_brotli.html">mod_brotli</a></code> (2.4.26'dan itibaren kullanılabilir)</dt>
          <dd>Brotli sıkıştırma algoritması desteği.</dd>
    
          <dt><code class="module"><a href="./mod/mod_md.html">mod_md</a></code> (2.4.30'dan itibaren kullanılabilir)</dt>
          <dd>Sertifika sağlama işlemi için ACME protokolü desteği.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_uwsgi.html">mod_proxy_uwsgi</a></code> (2.4.30'dan itibaren
            kullanılabilir)</dt>
          <dd><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> UWSGI ağ geçidi modülü.</dd>
    
          <dt><code class="module"><a href="./mod/mod_socache_redis.html">mod_socache_redis</a></code> (2.4.39'dan itibaren
            kullanılabilir)</dt>
          <dd><a href="http://redis.io/">Redis</a> tabanlı paylaşımlı nesne
            arabelleği sağlayıcı için destek.</dd>
    
          <dt><code class="module"><a href="./mod/mod_systemd.html">mod_systemd</a></code> (2.4.42'den itibaren
            kullanılabilir)</dt>
          <dd>systemd bütünleştirmesi. Httpd'nin systemd <code>Type=notify</code>
            ile bir hizmette kullanılmasına izin verir.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Modüllerdeki Gelişmeler</a></h2>
        
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> bir istemci sertifikasının doğrulama
            durumunu sınamak için bir OCSP sunucusunu kullanmak üzere
            yapılandırılabilir. Öntanımlı yanıtlayıcı, istemci sertifikasının
            kendisinde tasarlanmış yanıtlayıcının tercih edilip edilmeyeceği
            kararına bağlı olarak yapılandırılabilir.</dd>
    
          <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>, ayrıca, sunucunun istemciyle anlaşma
            sırasında kendi sertifikasının OCSP doğrulamasını umursamazca sağlayıp
            aktardığı durumda OCSP zımbalamasını da destekler.</dd>
    
          <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>, sunucular arasında SSL Oturumu verisini
            memcached üzerinden paylaşmak üzere yapılandırılabilir.</dd>
    
          <dd>RSA ve DSA'ya ek olarak EC anahtarları da artık desteklenmektedir.
          </dd>
    
          <dd>TLS-SRP için destek (2.4.4 itibariyle kullanılabilir).</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> yönergesi bir
            <code class="directive"><a href="./mod/core.html#location">Location</a></code> veya
            <code class="directive"><a href="./mod/core.html#locationmatch">LocationMatch</a></code> bloku içinde en
            verimli şekilde yapılandırılabilir ve büyük sayıların varlığı durumunda
            geleneksel iki değiştirgeli sözdiziminin de üzerinde belirgin bir
            başarım artışı sağlar.</dd>
    
          <dd>Vekil istekleri için kullanılan kaynak adresi artık
            yapılandırılabilmektedir.</dd>
    
          <dd>Artalanda Unix alan soketleri için destek (2.4.7 itibariyle
            kullanılabilir).</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code></dt>
    
          <dd>Dengeleme yöneticisi üzerinden BalancerMembers için daha fazla
            çalışma anı yapılandırması</dd>
    
          <dd>Çalışma anında dengeleme yöneticisi üzerinden başka BalancerMembers
            eklenebilir.</dd>
    
          <dd>Çalışma anı yapılandırmasına yönelik dengeleyici değiştirgeleri</dd>
    
          <dd>BalancerMembers için 'Drain' değeri belirtilebilir; böylece sadece
            mevcut yapışık oturumlara yanıt verirler ve bunların güzellikle hattan
            alınması mümkün olur.</dd>
    
          <dd>Balancer ayarları sunucu yeniden başlatılssa bile kalıcı olabilir.
            </dd>
    
          <dt><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></dt>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> CACHE süzgeci, arabellekleme üzerinde daha
            hassas denetim sağlamak için istenirse süzgeç zincirinin belli bir
            noktasına yerleştirilebilmektedir.</dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> artık HEAD isteklerini
            arabellekleyebiliyor.</dd>
    
          <dd>Mümkün olduğunda, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> yönergeleri sunucu
            bazında değil, dizin bazında belirtilebiliyor.</dd>
    
          <dd>Arabellekli URL'lerin temel URL'si özelleştirilebiliyor; böylece
             arabelleğin bir bölümü aynı uç URL önekini paylaşabiliyor.</dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, ardalanda bir sağlayıcının olmadığı
            durumda (5xx hatası), arabelleklenmiş bayat içeriği sunabiliyor.</dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> artık bir X-Cache başlığına bir
            HIT/MISS/REVALIDATE yerleştirebiliyor.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
          <dd>Bir hata durumunda öntanımlı hata dizgisi yerine bir hata sayfası
            sunmayı sağlayan 'onerror' özniteliği için 'include' elemanı içinde
            destek.</dd>
    
          <dt><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>, <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>,
              <code class="module"><a href="./mod/mod_isapi.html">mod_isapi</a></code>, ...</dt>
          <dd>Başlıkların ortam değişkenlerine dönüşümü, başlık zerki yoluyla bazı
            olası karşı-site-betik saldırılarının hafifletilmesinden önce daha
            hızlı ve doğru yapılmaktadır. Geçersiz karakterler (altçizgiler dahil)
            içeren başlık isimleri artık sessizce bırakılmaktadır.<a href="env.html">Apache'deki Ortam değişkenleri</a>, böyle başlıkları
            gerektiren bozulmuş meşru istemcilerin çevresinden dolanabilen
            göstericilere sahiptir. (Bu durum, bu değişkenleri kullanan tüm
            modülleri etkiler.)</dd>
    
          <dt><code class="module"><a href="./mod/mod_authz_core.html">mod_authz_core</a></code> Yetkilendirme Kuralları
            Taşıyıcıları</dt>
    
          <dd>Gelişkin yetkilendirme kuralları artık <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code> yönergesi ve <code class="directive"><a href="./mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code> gibi
            ilgili taşıyıcı yönergeler kullanılarak belirtilebilmektedir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> bildik yeniden yazma senaryolarını
            basitleştirmek için <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> yönergesine
            <code>[QSD]</code> (Query String Discard=sorgu dizgisini iptal) ve
            <code>[END]</code> seçeneklerini sağlamaktadır.</dd>
          <dd><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> içinde
            karmaşık mantıksal ifadeler kullanımını mümkün kılmaktadır.</dd>
          <dd>SQL sorgularının <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> işlevleri olarak
            kullanılması sağlanmıştır.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>, <code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> kümelenmiş gruplara destek sağlar.
          </dd>
          <dd><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> zaman aşımlarını işleme sokabilmek için
              <code class="directive"><a href="./mod/mod_ldap.html#ldapconnectionpoolttl">LDAPConnectionPoolTTL</a></code>,
              <code class="directive"><a href="./mod/mod_ldap.html#ldaptimeout">LDAPTimeout</a></code> ve birtakım
              başka geliştirmeler sahiptir. Özellikle, bir LDAP sunucusunun boşta
              kalmış bağlantılarını bıraktıran bir durumsal güvenlik duvarı
              varlığında gerekli ayarlamaları yapmak için kullanışlıdır.</dd>
          <dd><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>, artık, LDAP araç kiti kullanarak sağlanan
            hata ayıklama bilgisini günlüklemek için <code class="directive"><a href="./mod/mod_ldap.html#ldaplibrarydebug">LDAPLibraryDebug</a></code> yönergesini
            içermektedir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_info.html">mod_info</a></code> önceden çözümlenmiş yapılandırmayı artık
            sunucunun başlatılması sırasında standart çıktıya
            dökümleyebilmektedir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_basic.html">mod_auth_basic</a></code></dt>
          <dd>Temel kimlik kanıtlamayı taklit eden yeni temel mekanizma
            (2.4.5 itibariyle kullanılabilmektedir).</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programs" id="programs">Programlardaki Gelişmeler</a></h2>
        
        <dl>
            <dt><code class="program"><a href="./programs/fcgistarter.html">fcgistarter</a></code></dt>
            <dd>Yeni FastCGI artalan sunucusu başlatma aracı</dd>
    
            <dt><code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code></dt>
            <dd>Arabellekli URL'ler, istenirse metadata'yı da dahil ederek
              listelenebilmektedir.</dd>
            <dd>Bazı URL'ler arabellekten tek tek silinebilmektedir.</dd>
            <dd>Dosya boyutları belirtilen blok boyutuna yukarı doğru
              yuvarlanabilmekte, böylece dosya boyutu sınırları diskteki gerçek
              boyutlarla daha iyi eşlenebilmektedir.</dd>
            <dd>Arabellek boyutu artık, diskteki dosyaların boyutuna göre bir
              sınıra ek olarak veya bunun yerine dosya düğümü sayısı ile
              sınırlanabilmektedir.</dd>
    
            <dt><code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code></dt>
            <dd>Artık geçerli günlük dosyasına bir bağ oluşturulabiliyor.</dd>
            <dd>Artık özel bir döndürme sonrası betiği çalıştırılabiliyor.</dd>
    
          <dt><code class="program"><a href="./programs/htpasswd.html">htpasswd</a></code>, <code class="program"><a href="./programs/htdbm.html">htdbm</a></code></dt>
          <dd>Bcrypt algoritması için destek (2.4.4 itibariyle
            kullanılabilmektedir).</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">Belgelendirme</a></h2>
        
        <dl>
            <dt>mod_rewrite</dt>
            <dd><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> belgeleri, yeniden düzenlenerek,
              genel kullanıma ve örneklere odaklı olarak ve diğer çözümlerin hangi
              durumlarda daha uygun olduğu da gösterilerek hemen hemen tamamen
              yeniden yazıldı. <a href="rewrite/">Yeniden Yazma Kılavuzu</a> artık
              bir sayfa olmaktan çıkıp, çok daha ayrıntılı ve daha iyi düzenlenmiş
              bir bölüm haline geldi.</dd>
    
            <dt>mod_ssl</dt>
            <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> belgeleri, evvelki teknik ayrıntılara ek
              olarak başlarken seviyesinde daha fazla örnekle büyük oranda
              genişletildi.</dd>
    
            <dt>Önbellek Kullanım Kılavuzu</dt>
            <dd><a href="caching.html">Önbellek Kullanım Kılavuzu</a>
              <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> tarafından sağlanan RFC2616 HTTP/1.1
              önbellekleme özellikleri arasıda daha iyi ayrım yapılabilmesi için ve
              <a href="socache.html">socache</a> arayüzü ile sağlanan soysal
              anahtar/değer önbelleklemesi yanında <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code>
              gibi mekanizmalarla sağlanan özelleştirilebilir arabelleklemeyi de
              kapsamak üzere yeniden yazıldı.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer">Modül Geliştirici Değişiklikleri</a></h2>
        
        <dl>
          <dt>Yapılandırma Denetleme Kancası Eklendi</dt>
    
          <dd>Yeni bir kanca, <code>check_config</code> kancası,
            <code>pre_config</code> ve <code>open_logs</code> kancaları arasında
            çalışmak üzere eklendi. Ayrıca, <code class="program"><a href="./programs/httpd.html">httpd</a></code>'ye
            <code>-t</code> seçeneği verildiğinde <code>test_config</code>
            kancasından önce çalışır. <code>check_config</code> kancası, modüllerin
            karşılıklı bağımlı yapılandırma yönergesi değerlerini yeniden
            yoklamasını ve iletiler konsola hala günlüklenebiliyorken bunların
            ayarlanabilmesini sağlar. Temel <code>open_logs</code> kanca işlevi
            konsol çıktısını hata günlüğüne yönlendirmeden önce hatalı yapılandırma
            sorunlarına karşı kullanıcı uyarılabilir.</dd>
    
          <dt>İfade Çözümleyici Eklendi</dt>
    
          <dd>Artık genel amaçlı bir ifade çözümleyicimiz var. API
            <var>ap_expr.h</var> içinde incelenebilir. Evvelce
            <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> içinde gerçeklenmiş olan ifade çözümleyiciden
            esinlenildi.</dd>
    
          <dt>Yetkilendirme Kuralları Taşıyıcıları</dt>
    
          <dd>Yetkilendirme modülleri, <code class="directive"><a href="./mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code> gibi gelişmiş yetkilendirme
            kuralı taşıyıcılarını desteklemek için ap_register_auth_provider()
            üzerinden artık bir sağlayıcı olarak çalıştırılabilmektedir.</dd>
    
          <dt>Küçük Nesne Arabellekleme Arayüzü</dt>
    
          <dd><var>ap_socache.h</var>, evvelki <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> oturum
            arabelleği gerçeklenimine dayalı olarak küçük veri nesnelerini
            arabelleklemek için sağlayıcı temelli bir arayüz ortaya koyar.
            Paylaşımlı bellek çevrimsel tamponu kullanan sağlayıcılar, disk bazlı
            dbm dosyaları ve memcache ile dağıtılan arabellekler şu an
            desteklenmektedir.</dd>
    
          <dt>Arabellek Durum Kancası Eklendi</dt>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> modülü artık, arabellekleme kararı bilinir
            olduğunda çağrılan yeni bir <code>cache_status</code> kancası içeriyor.
            Öntanımlı gerçeklenim, yanıta istemlik bir <code>X-Cache</code> ve
            <code>X-Cache-Detail</code> ekleyebilmektedir.</dd>
        </dl>
    
        <p>Geliştirici belgeleri <a href="developer/new_api_2_4.html">API
          değişikliklerinin ayrıntılı bir listesini</a> içermektedir.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/new_features_2_4.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_4.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/new_features_2_4.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_4.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html.ko.euc-kr��������������������������������������������0000664�0001751�0001751�00000035031�14743132254�022650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache 2.0 ο   - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache 2.0 ο  </h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
      <p>  ġ  1.3  2.0  ֵ 
         Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">ٽ κп  </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">⿡  </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="upgrading.html">1.3 2.0 ׷̵</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">ٽ κп  </a></h2>
        
    
        <dl>
          <dt>н </dt>
    
          <dd>POSIX 带 ϴ н ýۿ ġ
           μ   ȥؼ   ִ.
          δ ƴ   Ȯ尡ɼ(scalability) δ.</dd>
    
          <dt>ο  ý</dt>
    
          <dd> ý <code>autoconf</code> <code>libtool</code>
          ϵ ۼǾ. ׷ ġ  ý ٸ
          Ű  .</dd>
    
          <dt>  </dt>
    
          <dd> ġ     ִ 
          . <code class="module"><a href="./mod/mod_echo.html">mod_echo</a></code>   ۼǾ.</dd>
    
          <dt>н ÷    </dt>
    
          <dd>Apache 2.0 BeOS, OS/2,   н
          ÷   ȭǾ.  ġ ̵
          ÷ װ   ȴ POSIX ȣȯ 
          ü API  ÷ Ư <a href="mpm.html">ó </a>
          (MPM) Apache Portable Runtime (APR) Ͽ ȴ.</dd>
    
          <dt>ο ġ API</dt>
    
          <dd> API 2.0  ߴ. 1.3  
           켱  . 2.0 ̸ κ ڵ
          óϸ,      (hook)  Ѵ.
          , ġ  ٽ κ  ʰ ο  
          ϴ Լ ߰Ǿ.</dd>
    
          <dt>IPv6 </dt>
    
          <dd> Apache Portable Runtine ̺귯 IPv6 ϴ
          ýۿ ġ ⺻ IPv6  ٸ. ,
          <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>,
          <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code>,
          <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> þ
          IPv6  ּҸ Ѵ. (,
          "<code>Listen [2001:db8::1]:8080</code>").</dd>
    
          <dt>͸</dt>
    
          <dd> ġ    帧 
          ͷ   ִ.   <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>
          <code>INCLUDES</code> ͸ Ͽ CGI ũƮ ¿
          Server Side Include þ ó  ִ.
          <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>  CGI α׷
          ڵ鷯 ϴ Ͱ  ܺ α׷ ͷ
            ְ Ѵ.</dd>
    
          <dt>ٱ  </dt>
    
          <dd>   乮  SSI 
          Ͽ ٱ ȴ. ڴ ϵ ܰ 
              ִ.</dd>
    
          <dt> </dt>
    
          <dd>ȥ ִ  þ .  ȥ
          ִ <code>Port</code> <code>BindAddress</code> þ
           IP ּ ῡ
          <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> þ
          Ѵ. <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
          þ ̷ǰ ȣƮ νĿ  
          Ʈ Ѵ.</dd>
    
          <dt>Windows NT ڵ ü </dt>
    
          <dd>Windows NT Apache 2.0   ϸ ڵ
          utf-8 Ѵ. ϸ  ڵ Ͻý 
          Ǿ, Windows 2000 Windows XP   Windows NT
          ýۿ ٱ  Ѵ. <em>  Windows 95,
          98, ME ʰ, Ͻý ٿ   ý
           ڵ Ѵ.</em></dd>
    
          <dt>ǥ ̺귯 Updated</dt>
    
          <dd>Apache 2.0 <a href="http://www.pcre.org/">Perlȣȯ
          ǥ ̺귯 (Perl Compatible Regular Expression
          Library)</a> (PCRE) Ѵ.   ǥĿ
            Perl 5    ִ.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">⿡  </a></h2>
        
    
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd>Apache 2.0  ߰Ǿ.   OpenSSL
          ϴ SSL/TLS ȣȭ  ̽.</dd>
    
          <dt><code class="module"><a href="./mod/mod_dav.html">mod_dav</a></code></dt>
    
          <dd>Apache 2.0  ߰Ǿ.   
          ø ϱ HTTP Distributed Authoring and Versioning
          (DAV) ǥ Ѵ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></dt>
    
          <dd>Apache 2.0  ߰Ǿ. Ʈ 뷮
          ̱   ؼ  û
           ִ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_ldap.html">mod_auth_ldap</a></code></dt>
    
          <dd>Apache 2.0.41  ߰Ǿ.   HTTP
          Basic Authentication ϴ  LDAP ͺ̽
          Ѵ. õ <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> 
          Ǯ(connection pool) ϰ,  ijѴ.</dd> 
    
          <dt><code class="module"><a href="./mod/mod_auth_digest.html">mod_auth_digest</a></code></dt>
    
          <dd>޸𸮸 Ͽ μ  ij Ѵ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></dt>
    
          <dd>Apache 2.0  ߰Ǿ.   
           ȯ  ۼ  Ѵ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></dt>
    
          <dd>Apache 2.0  ߰Ǿ.   Apache 1.3
          <code>mod_mmap_static</code> ɿ   ij 
          ߰ߴ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></dt>
    
          <dd>  Apache 2.0  . 
          <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> ϴ û  
           ְ, 쿡      ִ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd> Ͻ  ο   ̿ϰ  
          HTTP/1.1 Ͻø ϱ  ۼǾ. ߰
          ο <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
            Ͻ    (׸  
          ) .  <code>&lt;Directory "proxy:..."&gt;</code>
             ʴ´.  <code>proxy_connect</code>,
          <code>proxy_ftp</code>, <code>proxy_http</code> 
          ϴ   .</dd>
    
          <dt><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></dt>
    
          <dd>ο <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>
          þ Ŭ̾Ʈ NOT ACCEPTABLE̳ MULTIPLE CHOICES
                 Ѵ. ߰
           ˰ MultiViews ˰  ϰ 
           Ǿ,     ִ ο 
          type map ߰Ǿ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></dt>
    
          <dd>ڵ  丮     
           HTML ǥ   ְ Ǿ,   Ͽ
          ļ ڼ   , 丮  ϵī
          ɷ  ִ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
    
          <dd>ο þ Ͽ SSI  ⺻  ±׿
          ħ ±׸   ְ,  ð SSI ܿ
           Ͽ   ְ Ǿ. mod_include (
          Perl ǥ ) ǥ Ľ̰ ׷
           <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> <code>$0</code>
          ... <code>$9</code>    ִ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_dbm.html">mod_auth_dbm</a></code></dt>
    
          <dd> <code class="directive"><a href="./mod/mod_auth_dbm.html#authdbmtype">AuthDBMType</a></code>
          þ Ͽ  DBM ͺ̽ Ѵ.</dd>
    
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_0.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_2.html.ko.euc-kr��������������������������������������������0000664�0001751�0001751�00000022731�14743132254�022655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ġ 2.2 ο   - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ġ 2.2 ο  </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
      <p>  ġ  2.0  2.2  ֵ 
         Ѵ. 1.3   ο  <a href="new_features_2_0.html">2.0 ο </a> 
         ϶.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">ٽ κп  </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">⿡  </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer"> ڿ ޶ </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">ٽ κп  </a></h2>
        
        <dl>
    
          <dt>Authn/Authz</dt>
          <dd>...</dd>
    
          <dt>ij</dt>
          <dd>...</dd>
    
          <dt>Ͻ</dt>
          <dd>ο <code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> 
          <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>  Ϻл 񽺸 Ѵ.
          ο <code class="module"><a href="./mod/mod_proxy_ajp.html">mod_proxy_ajp</a></code>  <a href="http://tomcat.apache.org/">ġ Ĺ</a>
          ϴ <code>Apache JServ Protocol 1.3 </code>
          Ѵ.</dd>
    
          <dt>ȶ </dt>
          <dd><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> ͼ 
            ִ. ׷ û ,  , ȯ溯
            ͸   ְ, 2.0  ǽɽ
             ش.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">⿡  </a></h2>
        
        <dl>
          <dt><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd>  2.0 <code>mod_auth_ldap</code> 
          2.2 <code>Authn/Authz</code>  ű ̴. <code class="directive"><a href="./mod/core.html#require">Require</a></code> þ LDAP
          Ӽ(attribute)   ˻ ͸   ִ
           ߰Ǿ.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd>ġ о þ ϸ ٹȣ 
          ִ <code>?config</code> ƱԸƮ ߰Ǿ. 
           û (hook)  <code>httpd -V</code> 
            ش.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer"> ڿ ޶ </a></h2>
        
        <dl>
          <dt>APR 1.0 API</dt>
    
          <dd>ġ 2.2 APR 1.0 API Ѵ. <code>APR</code>
          <code>APR-Util</code>  Ǿ Լ
          ɺ  . ڼ  <a href="http://apr.apache.org/">APR Ʈ</a> ϶.</dd>
    
          <dt>  α </dt>
    
          <dd>Ŭ̾Ʈ ῡ ߻  α׿ ϱ
          Լ <code>ap_log_cerror</code>  ߰ߴ. α׿
          ϸ  Ŭ̾Ʈ IP ּҰ ´.</dd>
    
          <dt> ׽Ʈ  ߰</dt>
    
          <dd>ڰ httpd <code>-t</code> ɼ  쿡
           Ư ڵ带 ϵ  <code>test_config</code>
           ߰ߴ.</dd>
    
          <dt> MPM ũ </dt>
    
          <dd>  MPM ũ⸦ ϱ
          <code>ThreadStackSize</code> þ  ߰ߴ. 
          ũ ⺻  ÷ Ϻ ڰ  
           쿡 ʿϴ.</dd>
    
          <dt>͸   ó</dt>
    
          <dd>  Ϳ ڽ ó 信 ùٸ 
           ϴ Ȯ å ־.  ʹ
          <code>ap_register_output_filter_protocol</code> Ȥ
          <code>ap_filter_protocol</code> ȣ Ͽ ϻ
            <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> ѱ
           ִ.</dd>
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������httpd-2.4.64/docs/manual/new_features_2_2.html.pt-br������������������������������������������������0000664�0001751�0001751�00000025471�14743132254�022107� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="pt-br" xml:lang="pt-br"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Descri&#231;&#227;o das novas funcionalidades do Apache 2.2 - Servidor HTTP Apache Vers&#227;o 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Gloss&#225;rio</a> | <a href="./sitemap.html">Mapa do site</a></p>
    <p class="apache">Servidor HTTP Apache Vers&#227;o 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documenta&#231;&#227;o</a> &gt; <a href="./">Vers&#227;o 2.4</a></div><div id="page-content"><div id="preamble"><h1>Descri&#231;&#227;o das novas funcionalidades do Apache 2.2</h1>
    <div class="toplang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta tradu&#231;&#227;o pode estar desatualizada.
            Confira a vers&#227;o em Ingl&#234;s para mudan&#231;as recentes.</div>
    
      <p>Esse documento descreve algumas das principais mudan&#231;as
         entre as vers&#245;es 2.0 e 2.2 do Servidor HTTP Apache.
         Para a lista de mudan&#231;as desde a vers&#227;o 1.3, veja a p&#225;gina
         de documenta&#231;&#227;o <a href="new_features_2_0.html">novas funcionalidades
         do Apache 2.0</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Principais Melhorias</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Melhorias nos M&#243;dulos</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Mudan&#231;as ao Desenvolvedor de M&#243;dulos</a></li>
    </ul><h3>Veja tamb&#233;m</h3><ul class="seealso"><li><a href="#comments_section">Coment&#225;rios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Principais Melhorias</a></h2>
        
        <dl>
    
          <dt>Authn/Authz</dt>
          <dd>...</dd>
    
          <dt>Caching</dt>
          <dd>...</dd>
    
          <dt>Proxying</dt>
          <dd>O novo m&#243;dulo <code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> fornece
              servi&#231;os de carregamento de balenceamento para <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>. O novo m&#243;dulo <code class="module"><a href="./mod/mod_proxy_ajp.html">mod_proxy_ajp</a></code> oferece suporte para o <code>Protocolo Apache JServ
              vers&#227;o 1.3</code>, usado pelo <a href="http://tomcat.apache.org/">Apache Tomcat</a>.</dd>
    
          <dt>Filtragem Inteligente (Smart Filtering)</dt>
          <dd>O <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> introduz configura&#231;&#227;o din&#226;mica para
              o filtro de sa&#237;da de dados. Permitindo que os filtros sejam
    	  condicionalmente inseridos, baseando-se nos cabe&#231;alhos <em>Request</em> ou <em>Response</em> ou em vari&#225;veis do
    	  ambiente, ele acaba com os problemas de depend&#234;ncias e pedidos
              da arquitetura 2.0.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Melhorias nos M&#243;dulos</a></h2>
        
        <dl>
          <dt><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd>Este m&#243;dulo &#233; uma migra&#231;&#227;o do <code>mod_auth_ldap</code>,
              da vers&#227;o 2.0 para a estrutura 2.2 de <code>Authn/Authz</code>.
    	  As novas funcionalidades incluem o uso de atributos LDAP e
    	  filtros de procura complexos na diretriz <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd>Adicionado um novo argumento <code>?config</code> que
              mostra a configura&#231;&#227;o das diretrizes analisadas pelo
    	  Apache, incluindo o nome do arquivo e o n&#250;mero da linha.
    	  Esse m&#243;dulo tamb&#233;m mostra a ordem de todos os ganchos de
              pedidos (request hooks) e informa&#231;&#245;es adicionais sobre
              a compila&#231;&#227;o, similar ao comando <code>httpd -V</code>.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer">Mudan&#231;as ao Desenvolvedor de M&#243;dulos</a></h2>
        
        <dl>
          <dt>API do APR 1.0</dt>
    
          <dd>O Apache 2.2 utiliza a API do APR 1.0. Todas as fun&#231;&#245;es e
              s&#237;mbolos antigos foram removidos do <code>APR</code> e
    	  <code>APR-Util</code>. Para mais detalhes, visite o
              <a href="http://apr.apache.org/">Website do APR</a>.</dd>
    
          <dt>Registros de Erros de Conex&#227;o (logs)</dt>
    
          <dd>Uma nova fun&#231;&#227;o <code>ap_log_cerror</code>, foi adicionada
              para registrar erros que ocorrem na conex&#227;o do cliente.
    	  Quando documentado no di&#225;rio de log, a mensagem inclui o
    	  endere&#231;o IP do cliente.</dd>
    
          <dt>Adicionado Gancho de Teste de Configura&#231;&#227;o</dt>
    
          <dd>Um novo gancho (hook), <code>test_config</code> foi
              adicionado para auxiliar m&#243;dulos que querem executar
    	  c&#243;digos especiais apenas quando o usu&#225;rio passa o
    	  par&#226;metro <code>-t</code> para o httpd.</dd>
    
          <dt>Ajustar o Stacksize dos "Threaded MPM's"</dt>
    
          <dd>Uma nova diretriz chamada <code>ThreadStackSize</code>,
              foi adicionada para ajustar o tamanho das stacks em todos
              os threadeds MPMs. Essa &#233; uma pr&#225;tica necess&#225;rio para alguns
    	  m&#243;dulos de terceiros em plataformas com tamanhos de stacks
    	  pequenos por padr&#227;o.</dd>
    
          <dt>Negocia&#231;&#227;o de Protocolo para filtros de sa&#237;da</dt>
    
          <dd>No passado, todo filtro era respons&#225;vel por garantir
              a gera&#231;&#227;o de cabe&#231;alhos de resposta correto que os afetava.
    	  Os filtros agora podem delegar o gerenciamento de protocolos
    	  comuns para <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>, usando chamadas
    	  de <code>ap_register_output_filter_protocol</code> ou
              <code>ap_filter_protocol</code>.</dd>
    
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Coment&#225;rios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licenciado sob a <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Gloss&#225;rio</a> | <a href="./sitemap.html">Mapa do site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�016677� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/rotatelogs.html.ko.euc-kr�����������������������������������������0000664�0001751�0001751�00000023626�14743132254�023545� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>rotatelogs - ġ α׸ ȯϱ  
      α α׷ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>rotatelogs - ġ α׸ ȯϱ  
      α α׷</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/rotatelogs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
         <p><code>rotatelogs</code> ġ  α 
           α׷̴.  :</p>
    
    <div class="example"><p><code>
         CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common
    </code></p></div>
    	 
         <p>׷ /var/logs/logfile.nnnn  . nnnn
         α׸  ý۽ð̴ ( ð ׻ ȯⰣ
         ̴. ׷ cron ũƮ óϱ ). ȯⰣ
         (⼭ 24 ð)  ο α׸ Ѵ.</p>
    
    <div class="example"><p><code>
         CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common
    </code></p></div>
    
         <p>  α ũⰡ 5 ްƮ ɶ
         ȯѴ.</p>
    	 
    <div class="example"><p><code>
         ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M"
    </code></p></div>
         <p>  α  ũⰡ 5 ްƮ ɶ
         <code>errorlog.YYYY-mm-dd-HH_MM_SS</code>  
          α  ȯѴ.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#portability">ðɼ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
    
         <p><code><strong>rotatelogs</strong>
         [ -<strong>l</strong> ]
         <var>logfile</var>
         [ <var>rotationtime</var> [ <var>offset</var> ]] |
         [ <var>filesize</var>M ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
    
    <dl>
    
    <dt><code>-l</code></dt>
    <dd>ȯֱ GMT  ð Ѵ. (BST DST )
    GMT ð ϴ ȯ濡 <code>-l</code> ϸ ġ
      ߻  ִ!</dd>
    
    <dt><code><var>logfile</var></code></dt>
    
    <dd>α ο ̸. <var>logfile</var> '%' ڰ
    ִٸ <code>strftime(3)</code> Ĺڿ  óѴ.
    '%' ڰ ٸ ڿ ʴ ð <var>.nnnnnnnnnn</var>
    ڵ δ.     Ⱓ ۽ð Ѵ.</dd>
    
    <dt><code><var>rotationtime</var></code></dt>
    
    <dd>α ȯ ʴ ð.</dd>
    
    <dt><code><var>offset</var></code></dt>
    
    <dd>UTC д ð. ϸ 0 Ͽ UTC
    Ѵ.  , UTC -5 ð ð Ѵٸ
    ƱԸƮ <code>-300</code> Ѵ.</dd>
    
    <dt><code><var>filesize</var>M</code></dt>
    
    <dd>ð ƴ ũ⸦ Ҷ ްƮ ִ ũ
    ڿ <code>M</code> δ. rotationtime offset  
    Ķ͸ Ѵ.</dd>
    </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="portability" id="portability">ðɼ</a></h2>
    
    <p> α Ĺڿ ǥ  <code>strftime(3)</code>
     ؾ Ѵ. ̺귯 Ư Ȯ
    <code>strftime(3)</code> manpage ϶.</p>
    
    <table class="bordered"><tr><td><code>%A</code></td><td>(ȭ)   ̸</td></tr>
    <tr class="odd"><td><code>%a</code></td><td>(ȭ) 3-  ̸</td></tr>
    <tr><td><code>%B</code></td><td>(ȭ)   ̸</td></tr>
    <tr class="odd"><td><code>%b</code></td><td>(ȭ) 3-  ̸</td></tr>
    <tr><td><code>%c</code></td><td>(ȭ) ¥ ð</td></tr>
    <tr class="odd"><td><code>%d</code></td><td>2-ڸ </td></tr>
    <tr><td><code>%H</code></td><td>2-ڸ ð (24 ð ð)</td></tr>
    <tr class="odd"><td><code>%I</code></td><td>2-ڸ ð (12 ð ð)</td></tr>
    <tr><td><code>%j</code></td><td>3-ڸ ¥</td></tr>
    <tr class="odd"><td><code>%M</code></td><td>2-ڸ </td></tr>
    <tr><td><code>%m</code></td><td>2-ڸ </td></tr>
    <tr class="odd"><td><code>%p</code></td><td>(ȭ) 12 ð ð am/pm</td></tr>
    <tr><td><code>%S</code></td><td>2-ڸ </td></tr>
    <tr class="odd"><td><code>%U</code></td><td>2-ڸ ϼ ( ù 
    Ͽ)</td></tr>
    <tr><td><code>%W</code></td><td>2-ڸ ϼ ( ù 
    )</td></tr>
    <tr class="odd"><td><code>%w</code></td><td>1-ڸ ϼ ( ù° 
    Ͽ)</td></tr>
    <tr><td><code>%X</code></td><td>(ȭ) ð</td></tr>
    <tr class="odd"><td><code>%x</code></td><td>(ȭ) ¥</td></tr>
    <tr><td><code>%Y</code></td><td>4-ڸ </td></tr>
    <tr class="odd"><td><code>%y</code></td><td>2-ڸ </td></tr>
    <tr><td><code>%Z</code></td><td>ð ̸</td></tr>
    <tr class="odd"><td><code>%%</code></td><td>ڱ״ `%'</td></tr>
    </table>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/rotatelogs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/rotatelogs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apxs.html���������������������������������������������������������0000664�0001751�0001751�00000000562�13710016232�020520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: apxs.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: apxs.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: apxs.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: apxs.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/httpd.html.tr.utf8������������������������������������������������0000664�0001751�0001751�00000033517�14743132254�022221� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>httpd - Apache Hiper Metin Aktarım Protokolü Sunucusu - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>httpd - Apache Hiper Metin Aktarım Protokolü Sunucusu</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/httpd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><strong><code>httpd</code></strong>, Apache Hiper Metin Aktarım
          Protokolü (HTTP) sunucusu programıdır. Tek başına çalışan bir artalan
          süreci olarak tasarlanmıştır. Bu tarz kullanıldığında istekleri işleme
          sokmak için çocuk süreçlerden ve evrelerden oluşan bir havuz
          oluşturur.</p>
    
         <p>Genelde, <strong><code>httpd</code></strong>'nin doğrudan çağrılmaması
          gerekir. Unix ve benzerlerinde <code class="program"><a href="../programs/apachectl.html">apachectl</a></code>
          aracılığıyla, <a href="../platform/windows.html#winsvc">Windows NT, 2000
          ve XP</a>'de bir hizmet olarak,  <a href="../platform/windows.html#wincons">Windows 9x ve ME</a>'de ise bir
          konsol uygulaması olarak çalıştırılır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="../invoking.html">Apache httpd'nin Başlatılması</a></li><li><a href="../stopping.html">Apache httpd'nin Durdurulması</a></li><li><a href="../configuring.html">Yapılandırma Dosyaları</a></li><li><a href="../platform/">Platforma Özgü Belgeler</a></li><li><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
         <p><code><strong>httpd</strong> [ -<strong>d</strong>
         <var>sunucu-kök-dizini</var> ] [ -<strong>f</strong>
         <var>yapılandırma-dosyası</var> ]
         [ -<strong>C</strong> <var>yönerge</var> ] [ -<strong>c</strong>
         <var>yönerge</var> ] [ -<strong>D</strong> <var>parametre</var> ]
         [ -<strong>e</strong> <var>seviye</var> ] [ -<strong>E</strong>
         <var>dosya</var> ]
         [ <strong>-k</strong> start | restart | graceful | stop | graceful-stop ]
         [ -<strong>h</strong> ]
         [ -<strong>l</strong> ] [ -<strong>L</strong> ] [ -<strong>S</strong> ]
         [ -<strong>t</strong> ] [ -<strong>v</strong> ] [ -<strong>V</strong> ]
         [ -<strong>X</strong> ] [ -<strong>M</strong> ] [ -<strong>T</strong> ]
         </code></p>
    
         <p><a href="../platform/windows.html">Windows sistemlerinde</a>, ek
          olarak şunlar vardır:</p>
    
         <p><code><strong>httpd</strong> [ -<strong>k</strong> install | config |
          uninstall ] [ -<strong>n</strong> <var>isim</var> ]
         [ -<strong>w</strong> ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
    
      <dl>
        <dt><code><strong>-d</strong> <var>sunucu-kök-dizini</var></code></dt>
          <dd><var>sunucu-kök-dizini</var>'ni <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> yönergesine ilk değer olarak atar. Yapılandırma
          dosyasındaki bir <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code>
          yönergesiyle bu atama geçersiz kılınabilir. Bu seçenek belirtilmediği
          takdirde <code>/usr/local/apache2</code> dizini öntanımlıdır.</dd>
    
        <dt><code><strong>-f</strong> <var>yapılandırma-dosyası</var></code></dt>
          <dd>Başlatma sırasında <var>yapılandırma-dosyası</var>'ndaki yönergeler
          kullanılır. Eğer <var>yapılandırma-dosyası</var> bir / ile başlamıyorsa
          dosyanın <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> yönergesinin
          değerine göreli olduğu varsayılır. Seçenek belirtilmediği takdirde
          <code>conf/httpd.conf</code> öntanımlı değerdir.</dd>
    
        <dt><code><strong>-k</strong> <code>start | restart | graceful | stop |
          graceful-stop</code></code></dt>
        <dd><strong><code>httpd</code></strong>'yi başlatmak, durdurmak ve yeniden
          başlatmak için sinyal gönderir. Daha ayrıntılı bilgi edinmek için <a href="../stopping.html">Apache httpd'nin Durdurulması</a> belgesine
          bakınız.</dd>
    
        <dt><code><strong>-C</strong> <var>yönerge</var></code></dt>
        <dd>Yapılandırma <var>yönerge</var>'sini yapılandırma dosyalarını okumadan
          önce işleme sokar.</dd>
    
        <dt><code><strong>-c</strong> <var>yönerge</var></code></dt>
        <dd>Yapılandırma <var>yönerge</var>'sini yapılandırma dosyalarını
          okuduktan sonra işleme sokar.</dd>
    
        <dt><code><strong>-D</strong> <var>parametre</var></code></dt>
        <dd>Sunucu başlatılırken veya yeniden başlatılırken komutları şarta bağlı
          olarak işleme sokmak veya atlamak için yapılandırma dosyalarında
          kullanılan <code class="directive"><a href="../mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>
          bölümlerinde kullanılmak üzere bir yapılandırma <var>parametre</var>'si
          tanımlar. Ayrıca, <code>-DNO_DETACH</code> (ana sürecin çatallanmasını
          engellemek için), <code>-DFOREGROUND</code> (ana sürecin
          <code>setsid()</code> ve benzerlerinden çağrılmasını engellemek için)
          gibi daha az bilinen bazı başlatma parametrelerini atamakta da
          kullanılabilir.</dd>
    
        <dt><code><strong>-e</strong> <var>seviye</var></code></dt>
        <dd>Hata günlüğü seviyesi olarak <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> yönergesine sunucu başlatılırken <var>seviye</var>
          değerini atar. Bu seçenek, başlatma sırasındaki sorunları saptamak
          amacıyla hata iletilerinin ayrıntı seviyesini geçici olarak arttırmak
          için kullanılır.</dd>
    
        <dt><code><strong>-E</strong> <var>dosya</var></code></dt>
        <dd>Sunucunun başlatılması sırasında hata iletilerinin belirtilen
          <var>dosya</var>'ya gönderilmesini sağlar.</dd>
    
        <dt><code><strong>-h</strong></code></dt>
        <dd>Mevcut komut satırı seçeneklerinin kısa bir özetini çıktılar.</dd>
    
        <dt><code><strong>-l</strong></code></dt>
        <dd>Sunucunun içinde derlenmiş modüllerin listesini çıktılar. Bu liste
          <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesi kullanılarak
          devingen olarak yüklenen modülleri içermez.</dd>
    
        <dt><code><strong>-L</strong></code></dt>
        <dd>Durağan modüllerce sağlanmış yönergeleri olası değerleriyle geçerli
          konumlarına yerleştirerek listeler. Paylaşımlı modüllerce sağlanan
          yönergeleri listelemez.</dd>
    
        <dt><code><strong>-M</strong></code></dt>
        <dd>Yüklü durağan ve paylaşımlı modülleri listeler.</dd>
    
        <dt><code><strong>-S</strong></code></dt>
        <dd>Yapılandırma dosyasından çözümlenmiş haliyle ayarları gösterir (şu an
          sadece sanal konak ayarları gösterilmektedir).</dd>
    
        <dt><code><strong>-T</strong></code> (2.3.8 ve sonrasında
        kullanılabilmektedir)</dt>
        <dd>Başlatma ve yeniden başlatma sırasında belge kökü sınanmadan
          geçilir.</dd>
    
        <dt><code><strong>-t</strong></code></dt>
        <dd>Yapılandırma dosyasını sözdizimi hatalarına karşı denetler. Program
          sözdizimini denetledikten sonra sözdizimi geçerliyse 0 ile, değilse
          sıfırdan farklı bir değerle çıkar.
          <code><strong>-D</strong>DUMP_VHOSTS</code> seçeneği ile birlikte
          kullanılmışsa ek olarak sanal konak ayrıntıları da basılır.
          <code><strong>-D</strong>DUMP_MODULES</code> seçeneği ile ise ek olarak
          tüm modüller listelenir.</dd>
    
        <dt><code><strong>-v</strong></code></dt>
        <dd><strong><code>httpd</code></strong> sürümünü basar ve çıkar.</dd>
    
        <dt><code><strong>-V</strong></code></dt>
        <dd>Sürümü ve <strong><code>httpd</code></strong> kurulum parametrelerini
          basar ve çıkar.</dd>
    
        <dt><code><strong>-X</strong></code></dt>
        <dd><strong><code>httpd</code></strong> hata ayıklama kipinde çalışır. Tek
          çocuk süreç başlatılır ve sunucu konsolu terketmez.</dd>
      </dl>
    
      <p>Aşağıdaki seçenekler sadece <a href="../platform/windows.html">Windows
        platformunda geçerlidir</a>:</p>
    
      <dl>
        <dt><code><strong>-k</strong> install | config | uninstall</code></dt>
        <dd>Parametreler bakımından sırasıyla: Apache httpd bir Windows NT hizmeti
          haline getirilir; başlatma seçenekleri Apache httpd hizmeti için
          değiştirilir; ve Apache httpd hizmeti sistemden kaldırılır.</dd>
    
        <dt><code><strong>-n</strong> <var>isim</var></code></dt>
        <dd>Sinyal gönderilecek Apache httpd hizmetinin <var>ismi</var>.</dd>
    
        <dt><code><strong>-w</strong></code></dt>
        <dd>Hata durumunda konsol penceresi açık tutularak hata iletilerinin
          okunması sağlanır.</dd>
      </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/httpd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/httpd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/index.html.tr.utf8������������������������������������������������0000664�0001751�0001751�00000016124�14743132254�022200� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Sunucu ve Destek Programları - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Sunucu ve Destek Programları</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>Bu sayfada Apache HTTP Sunucusuna dahil tüm çalıştırılabilir programlar
          tanıtılmıştır.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="index" id="index">Dizin</a></h2>
    
        <dl>
          <dt><code class="program"><a href="../programs/httpd.html">httpd</a></code></dt>
          <dd>Apache hiper metin aktarım protokolü sunucusu.</dd>
    
          <dt><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></dt>
          <dd>Apache HTTP Sunucusu denetim arayüzü.</dd>
    
          <dt><code class="program"><a href="../programs/ab.html">ab</a></code></dt>
          <dd>Apache HTTP Sunucusu  başarım ölçme aracı.</dd>
    
          <dt><code class="program"><a href="../programs/apxs.html">apxs</a></code></dt>
          <dd>Apache HTTP Sunucusu eklenti aracı (APache eXtenSion tool).</dd>
    
          <dt><code class="program"><a href="../programs/configure.html">configure</a></code></dt>
          <dd>Kaynak ağacını yapılandırır.</dd>
    
          <dt><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></dt>
          <dd>Kullanıcı kimlik doğrulama dosyalarını temel kimlik doğrulaması için
            DBM biçeminde oluşturur ve günceller.</dd>
    
          <dt><code class="program"><a href="../programs/fcgistarter.html">fcgistarter</a></code></dt>
          <dd>Bir FastCGI programını çalıştırır.</dd>
    
          <dt><code class="program"><a href="../programs/htcacheclean.html">htcacheclean</a></code></dt>
          <dd>Disk arabelleğini temizler.</dd>
    
          <dt><code class="program"><a href="../programs/htdigest.html">htdigest</a></code></dt>
    
          <dd>Kullanıcı kimlik doğrulama dosyalarını özet kimlik doğrulaması için
            oluşturur ve günceller.</dd>
    
          <dt><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></dt>
          <dd>DBM parola veritabanlarını idare eder.</dd>
    
          <dt><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code></dt>
          <dd>Kullanıcı kimlik doğrulama dosyalarını temel kimlik doğrulaması için
            oluşturur ve günceller.</dd>
    
          <dt><code class="program"><a href="../programs/httxt2dbm.html">httxt2dbm</a></code></dt>
          <dd><code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> ile kullanmak
            üzere DBM dosyaları oluşturur.</dd>
    
          <dt><code class="program"><a href="../programs/logresolve.html">logresolve</a></code></dt>
          <dd>Apache günlük dosyalarındaki IP adreslerini konak isimlerine
            dönüştürür.</dd>
    
          <dt><code class="program"><a href="../programs/log_server_status.html">log_server_status</a></code></dt>
          <dd>Sunucunun durumunu düzenli aralıklarla günlüğe kaydeder.</dd>
    
          <dt><code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code></dt>
          <dd>Sunucuyu öldürmek gerekmeksizin günlük dosyalarının döndürülmesini
            sağlar.</dd>
    
          <dt><code class="program"><a href="../programs/split-logfile.html">split-logfile</a></code></dt>
          <dd>Bir çok konaklı günlük dosyasını konak başına bir günlük dosyası düşecek şekilde böler.</dd>
    
          <dt><code class="program"><a href="../programs/suexec.html">suexec</a></code></dt>
          <dd>Bir dosyayı belli bir kullanıcı adına çalıştırır.</dd>
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdbm.html��������������������������������������������������������0000664�0001751�0001751�00000000436�13710016232�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: htdbm.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: htdbm.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: htdbm.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/logresolve.html.tr.utf8�������������������������������������������0000664�0001751�0001751�00000016040�14743132254�023247� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>logresolve - Apache günlük dosyalarındaki IP adreslerini konak
      isimlerine dönüştürür - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>logresolve - Apache günlük dosyalarındaki IP adreslerini konak
      isimlerine dönüştürür</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/logresolve.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code><strong>logresolve</strong></code>, Apache'nin erişim
         günlüklerindeki IP adreslerini çözümlemek için bir ardıl işlem
         uygulamasıdır. İsim sunucunuza bindirdiği yükü en aza indirmek için
         <code><strong>logresolve</strong></code> kendi arabelleğinde oluşturduğu
         eşleme tablosunu kullanır.</p>
    
         <p>Apache günlük dosyasını standart girdisinden okur. IP adresleri günlük
         dosyası satırlarında ilk bileşen olmalı ve sonraki bileşenlerden bir
         boşluk ile ayrılmalıdır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
    
         <p><code><strong>logresolve</strong> [ -<strong>s</strong>
         <var>dosyaismi</var> ] [ -<strong>c</strong> ] &lt;
         <var>günlük_dosyası</var> &gt; <var>yeni_günlük_dosyası</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
    
    <dl>
        <dt><code>-s <var>dosyaismi</var></code></dt>
        <dd>İstatistiklerin kaydedileceği dosyanın ismi belirtilir.</dd>
    
        <dt><code>-c</code></dt>
        <dd><code><strong>logresolve</strong></code> uygulamasının bazı DNS
        sorguları yapmasına sebep olur: IP adresine karşılık olan konak ismini
        bulduktan sonra özgün adresle karşılaştırmak için bu konak ismine karşılık
        gelen IP adresini sorgular.</dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/logresolve.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/logresolve.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/rotatelogs.html.tr.utf8�������������������������������������������0000664�0001751�0001751�00000045705�14743132254�023263� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>rotatelogs - Apache günlüklerini döndürmek için borulu günlük kayıt
      programı - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>rotatelogs - Apache günlüklerini döndürmek için borulu günlük kayıt
      programı</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/rotatelogs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code><strong>rotatelogs</strong></code>, Apache'nin borulu günlük
         dosyaları özelliği ile birlikte kullanmak için tasarlanmış basit bir
         programdır. Günlük dosyasının azami boyutuna göre veya belli aralıklarla
         günlük dosyalarını döndürür.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Örnekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#portability">Taşınabilirlik</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
    
         <p><code><strong>rotatelogs</strong>
         [ -<strong>l</strong> ]
         [ -<strong>L</strong> <var>isim</var> ]
         [ -<strong>p</strong> <var>program</var> ]
         [ -<strong>f</strong> ]
         [ -<strong>D</strong> ]
         [ -<strong>t</strong> ]
         [ -<strong>v</strong> ]
         [ -<strong>e</strong> ]
         [ -<strong>c</strong> ]
         [ -<strong>n</strong> <var>dosya_sayısı</var> ]
         <var>dosyaismi</var>
         <var>süre</var>|<var>boyut</var>(B|K|M|G)
         [ <var>saat_farkı</var> ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
    
    <dl>
        <dt><code><strong>-l</strong></code></dt>
        <dd>GMT yerine yerel zamanın kullanılmasını sağlar.</dd>
    
        <dt><code><strong>-L</strong></code> <var>bagismi</var></dt>
        <dd><p>Belirtilen bağ dosyası ismine geçerli günlük dosyasından kalıcı bir bağ
        oluşturulur. <code>tail -F bagismi</code> gibi bir komut kullanılarak
        günlüğün sürekli izlenmesi için kullanılabilir.</p>
        <p>Bağ ismi mutlak bir yol içermiyorsa, <code>rotatelogs</code>'un çalışma
        dizinine, <code>rotatelogs</code> sunucu tarafından çalıştırılıyorsa
        <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> dizinine görelidir.</p>
        </dd>
    
        <dt><code><strong>-p</strong></code> <var>program</var></dt>
    
        <dd>Belirtildiği takdirde, <code><strong>rotatelogs</strong></code> yeni
        bir günlük dosyasının her açılışında belirtilen programı çalıştırır. Yeni
        açılan dosyanın ismi programa ilk argüman olarak aktarılır. Bu işlem bir
        döndürme sonrası yapılırsa eski günlük dosyası ikinci argüman olarak
        aktarılır. <code><strong>rotatelogs</strong></code> işlemini sürdürmek için
        belirtilen programın sonlanmasını beklemez, dolayısıyla sonlanma soucunda
        döndürülen hata kodunu günlüğe kaydetmez. Çalıştırılan program
        <code><strong>rotatelogs</strong></code> ile aynı stdin, stdout ve stderr'i
        kullanır ve ortamı da miras alır.</dd>
    
        <dt><code><strong>-f</strong></code></dt>
        <dd>İlk günlük giridisinin okunmasını beklemeden
        <code><strong>rotatelogs</strong></code> başlar başlamaz günlük
        dosyasının açılmasını sağlar. Çok meşgul sitelerde, sunucu başlatılıp ilk
        istek sunuluncaya kadar geçen zamanda günlük dosyasının yokluğu
        özdevinimli işlemler yapan bazı günlükleme araçlarında sorunlara yol
        açabilir. Bu seçenek bu gibi durumlarda yararlıdır.</dd>
    
        <dt><code><strong>-D</strong></code></dt>
        <dd>Günlük dosyasının yerleştirileceği dizini (eğer yoksa) üst dizinleri ile
        birlikte yapılandırır. Bu, <code>strftime(3)</code> işlevinin sırf dosya için
        değil yol için de kullanılmasını sağlar.</dd>
    
        <dt><code><strong>-t</strong></code></dt>
        <dd>Günlük dosyasının döndürülmek yerine tepeden kırpılmasına sebep olur.
        Günlüğün <code><strong>tail</strong></code> gibi bir araç tarafından gerçek
        zamanda işlendiği ve veriyi saklamanın gerekmediği durumda kullanışlıdır.
        Dosya ismine bir sonek eklenmez, ancak biçem dizgesi '%' karakteri
        içeriyorsa buna uyulur.</dd>
    
        <dt><code>-T</code></dt>
        <dd>Açıldığında ilk günlük dosyası dışındaki tüm dosyaların kırpılmasına
        neden olur. Bu, biçem dizgesi ayın günü gibi döngüsel bir şey içerdiğinde
        kullanışlıdır. 2.4.56 ve sonrasında mevcuttur.
        </dd>
    
    
        <dt><code><strong>-v</strong></code></dt>
        <dd>Standart hataya verilen çıktı daha ayrıntılı olur. Çıktı,
        yapılandırma çözümlemesinin sonuçlarını ve tüm dosya açma/kapama
        işlemlerini içerir.</dd>
    
        <dt><code><strong>-e</strong></code></dt>
        <dd>Günlüğü standart çıktıya basar. Günlüğün zincirdeki ilgili araç
        tarafından gerçek zamanda işlenmesi gerektiğinde kullanışlıdır.</dd>
    
        <dt><code><strong>-c</strong></code></dt>
        <dd>Boş olsa bile her döngüde günlük dosyası oluşturur.</dd>
    
        <dt><code><strong>-n</strong> <var>dosya_sayısı</var></code></dt>
        <dd>Zaman damgalarına bakılmaksızın bir dosya serisi açılır. Bu seçenek
          döndürme ve başlatma sırasında günlük dosyalarının üzerine yazar.
          Örneğin -n3 belirtilirse <var>dosyaismi</var>, <var>dosyaismi.1</var>,
          <var>dosyaismi.2</var> serisi açılır ve <var>dosyaismi</var>'nin üzerine
          yazılır.<br />
          Bu uygulama <var>dosyaismi</var> dosyasını ilk açtığında, dosya yalnızca
          <code>-t</code> seçeneği de belirtilmişse kırpılır. Sonraki her döngü,
          daima hedef dosya kırpılarak başlar. <code>-t</code> ve mevcut günlük
          dosyaları olmadan boyuta dayalı döndürme için bu seçenek, ilk günlük
          girişlerinin <var>dosyaismi.1</var>'e gönderilmesine ve
          <var>dosyaismi.n</var> henüz kullanılmamış olsa bile
          <var>dosyaismi.1</var>'deki girdilerin korunmaması gibi sezgisel
          olmayan davranışlara neden olabilir.<br />
          2.4.5 ve sonraki sürümler içindir.</dd>
    
        <dt><code><var>dosyaismi</var></code></dt>
        <dd><p>Günlük dosyasının ismi yoluyla birlikte belirtilir.
          <var>dosyaismi</var> '%' karakterleri içeriyorsa bunlar
          <code>strftime(3)</code> biçem belirteçleri olarak ele alınır. Aksi
          takdirde, özdevinimli olarak <var>.nnnnnnnnnn</var> uzantısı üretilir.
          (<code><strong>-t</strong></code> seçeneği kullanılmadıkça) Uzantı saniye
          cinsindendir  ve her iki durumda da bu değer, mevcut döngü
          diliminin başlangıcına göre hesaplanır. Örneğin, döndürmenin 86400
          saniyede bir yapılacağı belirtilmişse, <code>strftime(3)</code> biçeminde
          oluşturulan saat, dakika ve saniye alanları, 24 saatlik sürenin
          başlangıcını (geceyarısı) göstermek üzere sıfırlarla doldurulur.</p>
    
          <p><code>strftime(3)</code> dosyaismi biçemlemesi kullanılırken, günlük
          dosyası biçeminin günlük dosyası döndürülürken her zaman farklı bir dosya
          ismi üretecek yeterlilikte parçacıklı yapıya sahip olduğundan emin
          olmalısınız. Aks takdirde döndürme işlemi yeni bir dosya başlatmak yerine
          hep aynı dosyanın üzerine yazar. Örneğin, <var>logfile</var> için
          <code>/var/log/errorlog.%Y-%m-%d</code> belirtilmişse 5 mega baytta bir
          yeni bir günlük dosyasına başlanacaktır. Fakat 5 megabayta gün içinde iki
          kez ulaşılırsa aynı günlük dosyası üretilir ve günlük hep aynı dosyanın
          üzerine yazılır.</p>
          <p>Günlük dosyası mutlak bir yol içermiyorsa, <code>rotatelogs</code>'un
          çalışma dizinine, <code>rotatelogs</code> sunucu tarafından
          çalıştırılıyorsa <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code>
          dizinine görelidir.</p>
        </dd>
    
        <dt><code><var>süre</var></code></dt>
        <dd>Günlük dosyasının yenisinin kaç saniyede bir açılacağı belirtilir.
        Örneğin, bu süre 3600 saniye ise günlük dosyası her saat başında
        yenilenir; 86400 saniye ise her geceyarısı yenilenir. (Bu süre zarfında
        günlüğe kaydedilecek bir olay gerçekleşmemişse dosya oluşturulmaz.)</dd>
    
        <dt><code><var>boyut</var>(B|K|M|G)</code></dt>
        <dd>Boyuta göre döndürme için azami dosya boyutu. Belirtilenin bir süre
        değil de bir boyut değeri olarak ele alınması için değerin sonuna şu
        karakterlerden biri eklenmelidir: <code>B</code> (Bayt), <code>K</code>
        (kilobayt), <code>M</code> (megabayt), <code>G</code> (gigabayt).
    
        <p>Süre ve boyut birlikte belirtilmişse boyut süreden sonra
        belirtilmelidir. Dosya yenilemesi, bunlardan hangisi daha önce aşılırsa o
        zaman gerçekleşir.</p></dd>
    
        <dt><code><var>saat_farkı</var></code></dt>
        <dd>Koordinatlı evrensel zamana göre "dakika" farkı. Belirtilmezse, sıfır
        öntanımlıdır. Örneğin, -5 saatlik bir zaman diliminde bulunuyorsanız bu
        değer <code>-300</code> olmalıdır. Çoğu durumda, bunun yerine
        <code><strong>-l</strong></code> seçeneğini kullanmak gerekir.</dd>
    </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Örnekler</a></h2>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/logfile 86400" common</pre>
    </div>
    
         <p>nnnn, günlük kaydının başladığı sistem zamanı olmak üzere
         /var/log/logfile.nnnn dosyası oluşturulur. Bu zaman, daima döngü
         süresinin katları olacağından bunu cron betiklerinizi eşzamanlamakta
         kullanabilirsiniz. Her döngü süresinin sonunda (burada 24 saat sonra)
         yeni bir günlük dosyası açılır.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -l /var/log/logfile.%Y.%m.%d 86400" common</pre>
    </div>
    
         <p>yyyy, yıl; mm, ay; dd, ayın gününü belirtmek üzere
         /var/log/logfile.yyyy.mm.dd dosyası oluşturulur. Her gün yerel zamanla
         geceyarısı yeni bir günlük dosyasına geçilecektir.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/logfile 5M" common</pre>
    </div>
    
         <p>Günlük dosyası 5 megabaytlık olunca yenisinin oluşturulmasını sağlar.
         </p>
    
    <div class="example"><pre class="prettyprint lang-config">ErrorLog "|bin/rotatelogs /var/log/errorlog.%Y-%m-%d-%H_%M_%S 5M"</pre>
    </div>
         <p>Hata günlüğünün 5 megabaytta bir
         <code>errorlog.YYYY-mm-dd-HH_MM_SS</code> biçemli bir isimle
         oluşturulmasını sağlar.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -t /var/log/logfile 86400" common</pre>
    </div>
    
         <p><code>/var/log/logfile</code> dosyasını oluşturur, sunucu başlatılırken ve günde
           bir kere dosyanın tepesi kırpılır. Bu senaryoda ayrı bir sürecin (tail
           gibi) dosyayı gerçek zamanlı işleyeceği umulur.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -T /var/log/logfile.%d 86400" common</pre>
    </div>
    
         <p>Sunucu ayın birinde başlatılırsa (veya yeniden başlatılırsa), bu,
         <code>/var/log/logfile.01</code> dosyasının sonuna eklenir. Ayın ikinci
         günü bir günlük girişi yazıldığında, <code>/var/log/logfile.02</code>
         kırpılır ve en üste yeni girdiler eklenir. Bu örnek, özel bir bakım
         gerektirmeden yaklaşık 1 aylık günlük tutar.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="portability" id="portability">Taşınabilirlik</a></h2>
    
        <p>Aşağıdaki günlük dosyası biçem belirteçlerinin tüm
        <code>strftime(3)</code> gerçeklenimlerince desteklenmesi gerekir.
        Kullandığınız kütüphaneye özgü belirteçler için sisteminizdeki
        <code>strftime(3)</code> kılavuz sayfasına bakınız.</p>
    
    <table class="bordered"><tr><td><code>%A</code></td><td>tam gün ismi (yerelleştirilmiş)</td></tr>
    <tr class="odd"><td><code>%a</code></td><td>3 harflik gün ismi
    (yerelleştirilmiş)</td></tr>
    <tr><td><code>%B</code></td><td>tam ay ismi (yerelleştirilmiş)</td></tr>
    <tr class="odd"><td><code>%b</code></td><td>3 harflik ay ismi (yerelleştirilmiş)</td></tr>
    <tr><td><code>%c</code></td><td>tarih ve saat (yerelleştirilmiş)</td></tr>
    <tr class="odd"><td><code>%d</code></td><td>2 haneli ay günü numarası</td></tr>
    <tr><td><code>%H</code></td><td>2 haneli saat (24 saatlik)</td></tr>
    <tr class="odd"><td><code>%I</code></td><td>2 haneli saat (12 saatlik)</td></tr>
    <tr><td><code>%j</code></td><td>3 hanelik yıl günü numarası</td></tr>
    <tr class="odd"><td><code>%M</code></td><td>2 haneli dakika</td></tr>
    <tr><td><code>%m</code></td><td>2 haneli ay</td></tr>
    <tr class="odd"><td><code>%p</code></td><td>12 saatlik kip için öö/ös
    (yerelleştirilmiş)</td></tr>
    <tr><td><code>%S</code></td><td>2 haneli saniye</td></tr>
    <tr class="odd"><td><code>%U</code></td><td>2 haneli yılın hafta numarası
    (Haftanın ilk gününün Pazar olduğu varsayımıyla)</td></tr>
    <tr><td><code>%W</code></td><td>2 haneli yılın hafta numarası
    (Haftanın ilk gününün Pazartesi olduğu varsayımıyla)</td></tr>
    <tr class="odd"><td><code>%w</code></td><td>1 hanelik haftanın gün numarası
    (Haftanın ilk gününün Pazar olduğu varsayımıyla)</td></tr>
    <tr><td><code>%X</code></td><td>saat (yerelleştirilmiş)</td></tr>
    <tr class="odd"><td><code>%x</code></td><td>tarih (yerelleştirilmiş)</td></tr>
    <tr><td><code>%Y</code></td><td>4 hanelik yıl</td></tr>
    <tr class="odd"><td><code>%y</code></td><td>2 hanelik yıl</td></tr>
    <tr><td><code>%Z</code></td><td>zaman dilimi ismi</td></tr>
    <tr class="odd"><td><code>%%</code></td><td>`%' iminin kendisi</td></tr>
    </table>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/rotatelogs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/rotatelogs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������httpd-2.4.64/docs/manual/programs/index.html��������������������������������������������������������0000664�0001751�0001751�00000001046�13710016232�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: index.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: index.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: index.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/dbmmanage.html����������������������������������������������������0000664�0001751�0001751�00000000606�13710016232�021457� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: dbmmanage.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: dbmmanage.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: dbmmanage.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: dbmmanage.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdigest.html.fr.utf8���������������������������������������������0000664�0001751�0001751�00000021046�14740503670�022666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htdigest - Gestion des fichiers d'utilisateurs pour
    l'authentification à base de condensés - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>htdigest - Gestion des fichiers d'utilisateurs pour
    l'authentification à base de condensés</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htdigest.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htdigest</code> permet de créer et maintenir les fichiers
        textes dans lesquels sont stockés des noms d'utilisateurs, des
        domaines de protection (realms) et des mots de passe pour
        l'authentification à base de condensés des utilisateurs HTTP.
        L'accès aux ressources du serveur HTTP Apache peut être limité aux
        seuls utilisateurs enregistrés dans les fichiers créés par
        <code>htdigest</code>.</p>
    
        <p>Cette page de manuel ne décrit que les arguments de la ligne de
        commande. Pour plus de détails à propos des directives nécessaires à
        la configuration de l'authentification à base de condensés dans
        <code class="program"><a href="../programs/httpd.html">httpd</a></code>, voir le manuel Apache qui est fourni avec
        la distribution et peut être consulté à <a href="http://httpd.apache.org/">http://httpd.apache.org/</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Considérations à propos de sécurité</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>htdigest</strong> [ -<strong>c</strong> ]
        <var>fichier-mots-de-passe</var> <var>realm</var>
        <var>nom-utilisateur</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">options</a></h2>
        <dl>
        <dt><code>-c</code></dt>
        <dd>Crée le fichier <var>fichier-mots-de-passe</var>. Si
        <var>fichier-mots-de-passe</var> existe déjà, il est tout d'abord
        supprimé.</dd>
    
        <dt><code><var>fichier-mots-de-passe</var></code></dt>
        <dd>Nom du fichier contenant les noms utilisateurs, realms et mots
        de passe. Si l'option <code>-c</code> est spécifiée, le fichier est
        créé s'il n'existe pas, ou supprimé et recréé s'il existe
        déjà.</dd>
    
        <dt><code><var>realm</var></code></dt>
        <dd>Le nom du domaine de protection auquel le nom d'utilisateur
        appartient. Voir <a href="http://tools.ietf.org/html/rfc2617#section-3.2.1">http://tools.ietf.org/html/rfc2617#section-3.2.1</a>
        pour plus de détails.</dd>
    
        <dt><code><var>nom-utilisateur</var></code></dt>
        <dd>Le nom d'utilisateur à créer ou mettre à jour dans le
        <var>fichier-mots-de-passe</var>. Si <var>nom-utilisateur</var> est
        absent de ce fichier, une nouvelle entrée est ajoutée. Si
        l'utilisateur existe déjà, le mot de passe est modifié.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Considérations à propos de sécurité</a></h2>
        <p>En tant qu'exécutable setuid, ce programme n'est pas sûr. En
        conséquence, évitez de lui attribuer des permissions setuid.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htdigest.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htdigest.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/httxt2dbm.html.fr.utf8��������������������������������������������0000664�0001751�0001751�00000020050�14740503670�022765� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>httxt2dbm - Génère des fichiers dbm à utiliser avec
    RewriteMap - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>httxt2dbm - Génère des fichiers dbm à utiliser avec
    RewriteMap</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/httxt2dbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httxt2dbm.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/httxt2dbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>httxt2dbm</code> permet, à partir d'une entrée au format
        texte, de générer des fichiers dbm à utiliser dans les directives
        <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> avec le type
        de table <code>dbm</code>.
        </p>
    
        <p>Si le fichier de sortie existe déjà, il ne sera pas tronqué. Les
        nouvelles clés seront ajoutées et les clés préexistantes mises à
        jour.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Exemples</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>httxt2dbm</strong>
        [ -<strong>v</strong> ]
        [ -<strong>f</strong> <var>TYPE_DBM</var> ]
        -<strong>i</strong> <var>TEXTE_SOURCE</var>
        -<strong>o</strong> <var>SORTIE_DBM</var>
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-v</code></dt>
        <dd>Sortie plus verbeuse</dd>
    
        <dt><code>-f <var>TYPE_DBM</var></code></dt>
        <dd>Spécifie le type DBM à utiliser pour le fichier de sortie.
        S'il n'est pas spécifié, c'est la valeur par défaut de
        l'<a class="glossarylink" href="../glossary.html#apr" title="voir glossaire">APR</a> qui sera utilisée. Les types disponibles
        sont :
        <code>GDBM</code> pour les fichiers GDBM,
        <code>SDBM</code> pour les fichiers SDBM,
        <code>DB</code> pour les fichiers DB,
        <code>NDBM</code> pour les fichiers NDBM,
        <code>default</code> pour le type DBM par défaut
        </dd>
    
        <dt><code>-i <var>TEXTE_SOURCE</var></code></dt>
        <dd>Le fichier d'entrée à partir duquel le fichier dbm sera créé. Le
        fichier doit être formaté de façon à ne contenir qu'un seul
        enregistrement par ligne, de la forme : <code>clé valeur</code>.
        Voir la documentation de la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> pour plus de détails à
        propos du format de ce fichier et de sa signification.
        </dd>
    
        <dt><code>-o <var>SORTIE_DBM</var></code></dt>
        <dd>Nom du fichier dbm de sortie.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples</a></h2>
        <div class="example"><p><code>
          httxt2dbm -i rewritemap.txt -o rewritemap.dbm<br />
          httxt2dbm -f SDBM -i rewritemap.txt -o rewritemap.dbm<br />
        </code></p></div>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/httxt2dbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httxt2dbm.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/httxt2dbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/httxt2dbm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/ab.html.ko.euc-kr�������������������������������������������������0000664�0001751�0001751�00000030614�14743132254�021737� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ab - ġ  ɰ˻  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>ab - ġ  ɰ˻ </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/ab.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><code>ab</code> ġ ؽƮ   (HTTP)
          ˻ϴ(benchmarking) ̴.  ġ
         ϴ ˷ش. Ư ġ  ʴ 
        û ϴ ˷ش.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="httpd.html">httpd</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
        <p><code><strong>ab</strong>
        [ -<strong>A</strong> <var>auth-username</var>:<var>password</var> ]
        [ -<strong>c</strong> <var>concurrency</var> ]
        [ -<strong>C</strong> <var>cookie-name</var>=<var>value</var> ]
        [ -<strong>d</strong> ]
        [ -<strong>e</strong> <var>csv-file</var> ]
        [ -<strong>g</strong> <var>gnuplot-file</var> ]
        [ -<strong>h</strong> ]
        [ -<strong>H</strong> <var>custom-header</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>k</strong> ]
        [ -<strong>n</strong> <var>requests</var> ]
        [ -<strong>p</strong> <var>POST-file</var> ]
        [ -<strong>P</strong> <var>proxy-auth-username</var>:<var>password</var> ]
        [ -<strong>q</strong> ]
        [ -<strong>s</strong> ]
        [ -<strong>S</strong> ]
        [ -<strong>t</strong> <var>timelimit</var> ]
        [ -<strong>T</strong> <var>content-type</var> ]
        [ -<strong>v</strong> <var>verbosity</var>]
        [ -<strong>V</strong> ]
        [ -<strong>w</strong> ]
        [ -<strong>x</strong> <var>&lt;table&gt;-attributes</var> ]
        [ -<strong>X</strong> <var>proxy</var>[:<var>port</var>] ]
        [ -<strong>y</strong> <var>&lt;tr&gt;-attributes</var> ]
        [ -<strong>z</strong> <var>&lt;td&gt;-attributes</var> ]
        [http://]<var>hostname</var>[:<var>port</var>]/<var>path</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
        <dl>
        <dt><code>-A <var>auth-username</var>:<var>password</var></code></dt>
        <dd> BASIC Authentication  Ѵ.
        <code>:</code>  ڸ ȣ base64 ڵϿ
        Ѵ.   䱸ϴ (<em> </em>,
        401  ʿ並 )  ڿ Ѵ.</dd>
    
        <dt><code>-c <var>concurrency</var></code></dt>
        <dd>ÿ ûϴ û. ⺻ ѹ  û
        .</dd>
    
        <dt><code>-C <var>cookie-name</var>=<var>value</var></code></dt>
        <dd>û <code>Cookie:</code>  ߰Ѵ. ƱԸƮ
         <code><var>name</var>=<var>value</var></code> 
        ̴.  ɼ    ִ.</dd>
    
        <dt><code>-d</code></dt>
        <dd>"percentage served within XX [ms] table" 
        ʴ´. (ȣȯ ).</dd>
    
        <dt><code>-e <var>csv-file</var></code></dt>
        <dd>û óϴµ ɸ (и ) ð (1%
        100%)  ǥ  (CSV) Ѵ.
         ̹ ''Ͽ⶧ 'gnuplot' Ϻ  
        ϴ.</dd>
    
        <dt><code>-g <var>gnuplot-file</var></code></dt>
        <dd>   'gnuplot' Ȥ TSV (Tab separate values,
          ) Ͽ Ѵ. Gnuplot, IDL, Mathematica,
        Igor,  Excel  α׷ ̷  
          ִ.  ù° ٿ ׸̸ ´. </dd>
    
        <dt><code>-h</code></dt>
        <dd> Ѵ.</dd>
    
        <dt><code>-H <var>custom-header</var></code></dt>
        <dd>û  ߰Ѵ. ƱԸƮ  ݷ 
         (<em> </em>,
        <code>"Accept-Encoding: zip/zop;8bit"</code>) ȿ
        ̴.</dd>
    
        <dt><code>-i</code></dt>
        <dd><code>GET</code>  <code>HEAD</code> û Ѵ.</dd>
    
        <dt><code>-k</code></dt>
        <dd>HTTP KeepAlive  Ѵ. <em> </em>,
         HTTP ǿ  û Ѵ. ⺻ KeepAlive
         ʴ´.</dd>
    
        <dt><code>-n <var>requests</var></code></dt>
        <dd> ˻ϱ  û. ⺻ û
        ѹ ⶧ Ϲ ɰ˻    .</dd>
    
        <dt><code>-p <var>POST-file</var></code></dt>
        <dd>POST ڷ .</dd>
    
        <dt><code>-P <var>proxy-auth-username</var>:<var>password</var></code></dt>
        <dd>Ͻø  BASIC Authentication  Ѵ.
        <code>:</code>  ڸ ȣ base64 ڵϿ
        Ѵ. Ͻð  䱸ϴ (<em> </em>,
        401  ʿ並 )  ڿ Ѵ.</dd>
    
        <dt><code>-q</code></dt>
        <dd>150 ̻ û  <code>ab</code> 10% Ȥ
         100 û <code>ǥؿ</code> Ȳ Ѵ.
        <code>-q</code> ɼ    ʴ´.</dd>
    
        <dt><code>-s</code></dt>
        <dd> ߰Ͽ Ͽٸ (<code>ab -h</code>
        Ȯ  ִ) <code>http</code>   SSL 
        <code>https</code>  Ѵ.   ̰
        <em>ſ</em> ̴. Ƹ   ̴.</dd>
    
        <dt><code>-S</code></dt>
        <dd>߰ ǥ  ʰ, հ ߰ ̰
        ǥ ũ /  ʴ´.
        ּ//ִ  Ѵ. (ȣȯ ).</dd>
    
        <dt><code>-t <var>timelimit</var></code></dt>
        <dd> ˻ϴ ִ ʴ ð. 
        <code>-n 50000</code> Ѵ.  ð  
        ˻Ҷ Ѵ. ⺻ ð  ˻Ѵ.</dd>
    
        <dt><code>-T <var>content-type</var></code></dt>
        <dd>POST ڷ Content-type .</dd>
    
        <dt><code>-v <var>verbosity</var></code></dt>
        <dd> ڼ  Ѵ. <code>4</code> ̸̻
          , <code>3</code> ̸̻ (404, 202, )
        ڵ带, <code>2</code> ̸̻ (warning)
        (info) Ѵ.</dd>
    
        <dt><code>-V</code></dt>
        <dd> ϰ Ѵ.</dd>
    
        <dt><code>-w</code></dt>
        <dd> HTML ǥ Ѵ. ⺻ ǥ  濡
          ۼѴ.</dd>
    
        <dt><code>-x <var>&lt;table&gt;-attributes</var></code></dt>
        <dd><code>&lt;table&gt;</code> Ӽ  ڿ.
        Ӽ <code>&lt;table <var>⿡</var> &gt;</code>
        ߰Ѵ.</dd>
    
        <dt><code>-X <var>proxy</var>[:<var>port</var>]</code></dt>
        <dd>Ͻ  Ͽ ûѴ.</dd>
    
        <dt><code>-y <var>&lt;tr&gt;-attributes</var></code></dt>
        <dd><code>&lt;tr&gt;</code> Ӽ  ڿ.</dd>
    
        <dt><code>-z <var>&lt;td&gt;-attributes</var></code></dt>
        <dd><code>&lt;td&gt;</code> Ӽ  ڿ.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs"></a></h2>
        <p> ̰  ۸  Ѵ. 
        ƱԸƮ,   , ٸ ܺ Էµ 
        о̸鼭  ߻  ִ.</p>
    
        <p> α׷ HTTP/1.x   ʴ´; 
        'ϴ'  丸 ޴´. <code>strstr(3)</code>
        ſ  ⶧ ӵ    ִ; <em></em>,
         ɺٴ <code>ab</code>  ϰ  
        ִ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/ab.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/ab.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apachectl.html.tr.utf8��������������������������������������������0000664�0001751�0001751�00000032413�14743132254�023014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apachectl - Apache HTTP Sunucusu Denetim Arayüzü - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>apachectl - Apache HTTP Sunucusu Denetim Arayüzü</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/apachectl.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code><strong>apachectl</strong></code> Apache Hiper Metin Aktarım
          Protokolü (HTTP) sunucusu için bir denetim aracıdır. Sistem
          yöneticisinin Apache <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> artalan
          sürecini denetimi altında tutabilmesine yardımcı olmak amacıyla
          tasarlanmıştır.</p>
    
        <p><code><strong>apachectl</strong></code> iki kipte işleyebilir.
          İlkinde, <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> komutu için basit
          bir önyüz gibi davranarak, gerekli ortam değişkenlerini atar ve
          belirtilen komut satırı seçenekleriyle
          <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> sürecini başlatır. İkinci
          kipte ise, <code><strong>apachectl</strong></code> bir SysV başlatma
          betiği olarak <code><strong>start</strong></code>,
          <code><strong>restart</strong></code>,
          <code><strong>stop</strong></code> gibi tek sözcüklük basit argümanlar
          alır ve bunları uygun sinyallere dönüştürerek
          <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong>'ye gönderir.</p>
    
        <p>Eğer Apache kurulumunuzda standart dışı dosya yolları kullanmışsanız,
          <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> programına uygun yolları
          atamak için <code><strong>apachectl</strong></code> betiğini elden
          geçirmelisiniz. Bu arada gerek gördüğünüz
          <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> komut satırı argümanlarını da
          belirtebilirsiniz. Ayrıntılar için betik içindeki açıklamalara
          bakınız.</p>
    
        <p><code><strong>apachectl</strong></code> betiği başarı durumunda 0
          çıkış değeri ile döner. Bir hata durumunda ise sıfırdan farklı bir
          değerle döner. Daha fazla bilgi için betik içindeki açıklamalara
          bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="../invoking.html">Apache'nin Başlatılması</a></li><li><a href="../stopping.html">Apache'nin Durdurulması</a></li><li><a href="../configuring.html">Yapılandırma Dosyaları</a></li><li><a href="../platform/">Platform Belgeleri</a></li><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
    
        <p><code><strong>apachectl</strong></code> önyüz kipinde çalıştığında
          <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> programının bütün komut
          satırı argümanlarını kabul edebilir.</p>
    
        <p><code><strong>apachectl</strong> [ <var>httpd-argümanları</var> ]
        </code></p>
    
        <p>SysV başlatma betiği kipinde ise,
          <code><strong>apachectl</strong></code> aşağıda tanımlanan basit, tek
          sözcüklük komutları kabul eder.</p>
    
        <p><code><strong>apachectl</strong> <var>komut</var></code></p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
    
        <p>Burada sadece SysV başlatma betiğine özgü seçeneklere yer verilmiştir.
          Diğer argümanlar için <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> kılavuz
          sayfasına bakınız.</p>
    
        <dl>
          <dt><code><strong>start</strong></code></dt>
          <dd>Apache <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> artalan sürecini
            başlatır. Zaten çalışmaktaysa bir hata verir. <code><strong>apachectl
            -k start</strong></code> komutuna eşdeğerdir.</dd>
    
          <dt><code><strong>stop</strong></code></dt>
          <dd>Apache <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> artalan sürecini
            durdurur. <code><strong>apachectl -k stop</strong></code> komutuna
            eşdeğerdir.</dd>
    
          <dt><code><strong>restart</strong></code></dt>
          <dd>Apache <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> artalan sürecini
            yeniden başlatır; çalışmıyorsa çalıştırılır. Artalan sürecinin ölü
            olmadığından emin olmak için yeniden başlatmadan önce
            <code><strong>configtest</strong></code> seçeneği verilmiş gibi
            yapılandırma dosyaları sınanır. <code><strong>apachectl -k
            restart</strong></code> komutuna eşdeğerdir.</dd>
    
          <dt><code><strong>fullstatus</strong></code></dt>
          <dd><strong><code class="module"><a href="../mod/mod_status.html">mod_status</a></code></strong> üzerinden tam bir
            durum raporu gösterir. Bunun çalışması için sunucuda
            <strong><code class="module"><a href="../mod/mod_status.html">mod_status</a></code></strong> etkinleştirilmiş olmalı
            ve sisteminizde <code><strong>lynx</strong></code> gibi bir metin
            kipi HTTP tarayıcı kurulu olmalıdır. Durum raporuna erişmek için
            kullanılacak adres betik içinde <code>STATUSURL</code> değişkenine
            atanabilir.</dd>
    
          <dt><code><strong>status</strong></code></dt>
          <dd>Özet halinde bir durum raporu gösterir. O an sunulmakta olan
            isteklerin gösterilmemesi dışında
            <code><strong>fullstatus</strong></code> seçeneği gibidir.</dd>
    
          <dt><code><strong>graceful</strong></code></dt>
          <dd>Apache <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> artalan sürecini
            <em>nazikçe</em> yeniden başlatır; çalışmıyorsa çalıştırılır. O an
            hizmet sunmakta olan çocuk süreçleri hemen durdurmaması dışında
            normal yeniden başlatma gibidir. Bir yan etki olarak eski günlük
            dosyaları hemen kapatılmaz. Yani, günlük dosyalarını döndüren bir
            betik kullanıyorsanız yenilerini başlatmadan önce eski dosyaların
            tamamen kapandığından emin olmak için belli bir süre beklemeniz
            gerekecektir. Artalan sürecinin ölü olmadığından emin olmak için
            yeniden başlatmadan önce  <code><strong>configtest</strong></code>
            seçeneği verilmiş gibi yapılandırma dosyaları sınanır.
            <code><strong>apachectl -k graceful</strong></code> komutuna
            eşdeğerdir.</dd>
    
          <dt><code><strong>graceful-stop</strong></code></dt>
          <dd>Apache <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> artalan sürecini
            <em>nazikçe</em> durdurur. O an hizmet sunmakta olan çocuk süreçleri
            hemen durdurmaması dışında normal durdurma gibidir. Bir yan etki
            olarak eski günlük dosyaları hemen kapatılmaz.
            <code><strong>apachectl -k graceful-stop</strong></code> komutuna
            eşdeğerdir.</dd>
    
          <dt><code><strong>configtest</strong></code></dt>
          <dd>Yapılandırma dosyasında sözdizimi denetimi yapılmasını sağlar.
            Yapılandırma dosyaları çözümlenir ve bir sorun yoksa bir <code>Syntax
            Ok</code> raporu verilir fakat, bir hata varsa o hataya ilişkin
            ayrıntılı bilgi verilir. <code><strong>apachectl -t</strong></code>
            komutuna eşdeğerdir.</dd>
    
        </dl>
    
        <p>Aşağıdaki seçenek eski sürümlerde kullanılmaktaydı, fakat artık
          kullanılmamaktadır.</p>
    
        <dl>
          <dt><code>startssl</code></dt>
          <dd><strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> programını SSL destekli
            başlatmak için, yapılandırma dosyanızı ilgili yönergeleri içermesi
            için elden geçirmeli ve normal <code><strong>apachectl
            start</strong></code> komutunu kullanmalısınız.</dd>
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/apachectl.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apachectl.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apachectl.html.fr.utf8��������������������������������������������0000664�0001751�0001751�00000030211�14740503670�022771� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apachectl - L'interface de contrôle du serveur HTTP
      Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>apachectl - L'interface de contrôle du serveur HTTP
      Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/apachectl.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>apachectl</code> est un frontal pour le serveur HTTP
         Apache. Il a été conçu pour aider l'administrateur à contrôler le
         fonctionnement du démon Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code>.</p>
    
         <p>Le script <code>apachectl</code> possède deux modes de
         fonctionnement. Il peut fonctionner en tant que simple frontal
         de la commande <code class="program"><a href="../programs/httpd.html">httpd</a></code> et ne fait alors que
         définir toute variable d'environnement nécessaire, puis invoque
         <code class="program"><a href="../programs/httpd.html">httpd</a></code> en lui passant tout argument de ligne de
         commande souhaité. Il peut aussi fonctionner en tant que script
         d'initialisation SysV n'acceptant qu'un seul argument tel que
         <code>start</code>, <code>restart</code> et <code>stop</code>, et
         traduisant ce dernier en signaux appropriés pour le démon
         <code class="program"><a href="../programs/httpd.html">httpd</a></code>.</p>
    
         <p>Si votre installation d'Apache utilise des chemins non
         standards, vous devrez éditer le script <code>apachectl</code> afin
         de définir les chemins appropriés pour le binaire
         <code class="program"><a href="../programs/httpd.html">httpd</a></code>. Vous pouvez aussi spécifier tout argument
         de ligne de commande de <code class="program"><a href="../programs/httpd.html">httpd</a></code> nécessaire. Voir
         les commentaires dans le script pour plus de détails.</p>
    
         <p>Le script <code>apachectl</code> renvoie une valeur égale à 0 en
         cas de succès, et une valeur supérieure à 0 en cas de problème.
         Voir les commentaires dans le script pour plus de détails.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Résumé</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../invoking.html">Démarrer Apache</a></li><li><a href="../stopping.html">Arrêter Apache</a></li><li><a href="../configuring.html">Fichiers de
    configuration</a></li><li><a href="../platform/">Documentation spécifique aux
    plates-formes</a></li><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Résumé</a></h2>
    
    <p>En mode frontal (pass-through), <code>apachectl</code> peut spécifier
    tous les arguments qu'accepte le binaire <code class="program"><a href="../programs/httpd.html">httpd</a></code>.</p>
    
    <p><code><strong>apachectl</strong> [ <var>argument-httpd</var> ]</code></p>
    
    <p>En mode script d'initialisation SysV, <code>apachectl</code>
    n'accepte qu'un seul des arguments définis ci-dessous.</p>
    
    <p><code><strong>apachectl</strong> <var>commande</var></code></p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <p>Seules les options du style initialisation SysV sont décrites ici.
    Les autres arguments sont décrits dans la page de manuel de
    <code class="program"><a href="../programs/httpd.html">httpd</a></code>.</p>
    
    <dl>
    
    <dt><code>start</code></dt>
    
    <dd>Démarre le démon Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code>. Renvoie une erreur
    s'il est déjà en cours d'exécution. Équivalent à <code>apachectl -k
    start</code>.</dd>
    
    <dt><code>stop</code></dt>
    
    <dd>Arrête le démon Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code>. Équivalent à
    <code>apachectl -k stop</code>.</dd>
    
    <dt><code>restart</code></dt>
    
    <dd>Redémarre le démon Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code>. Si le démon
    n'est pas en cours d'exécution, il est démarré. Cette option vérifie
    automatiquement les fichiers de configuration (de la même manière que
    l'option <code>configtest</code> ) avant de lancer le redémarrage, afin
    d'être sûr que le fonctionnement du démon ne sera pas compromis.
    Equivalent à <code>apachectl -k restart</code>.</dd>
    
    <dt><code>fullstatus</code></dt>
    
    <dd>Affiche le rapport d'état complet du module
    <code class="module"><a href="../mod/mod_status.html">mod_status</a></code>. Pour que ceci fonctionne,
    <code class="module"><a href="../mod/mod_status.html">mod_status</a></code> doit être activé dans votre serveur et vous
    devez disposer d'un navigateur en mode texte tel que <code>lynx</code>
    sur votre système. L'URL utilisée pour accéder au rapport d'état peut
    être modifiée en définissant la variable <code>STATUSURL</code> dans le
    script.</dd>
    
    <dt><code>status</code></dt>
    
    <dd>Affiche un rapport d'état succinct. Similaire à l'option
    <code>fullstatus</code>, excepté que la liste des requêtes en cours de
    traitement est omise.</dd>
    
    <dt><code>graceful</code></dt>
    
    <dd>Redémarre le démon Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> en douceur. Si le
    démon n'est pas en cours d'exécution, il est démarré. À la différence
    d'un redémarrage normal, les connexions en cours ne sont pas fermées.
    Comme effet de bord, les anciens fichiers journaux ne seront pas fermés
    immédiatement. Cela signifie que si l'on utilise un script de rotation
    des journaux, un délai suffisant sera nécessaire afin d'être sûr que les
    fichiers journaux seront bien fermés avant leur traitement par le script
    de rotation. Cette option vérifie
    automatiquement les fichiers de configuration (de la même manière que
    l'option <code>configtest</code> ) avant de lancer le redémarrage, afin
    d'être sûr que le fonctionnement du démon ne sera pas compromis.
    Équivalent à <code>apachectl -k graceful</code>.</dd>
    
    <dt><code>graceful-stop</code></dt>
    
    <dd>Arrête le démon Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> en douceur. À la
    différence d'un arrêt normal, les connexions en cours ne sont pas
    fermées. Comme effet de bord, les anciens fichiers journaux ne seront
    pas fermés immédiatement. Équivalent à <code>apachectl -k
    graceful-stop</code>.</dd>
    
    <dt><code>configtest</code></dt>
    
    <dd>Effectue une vérification de la syntaxe du fichier de configuration.
    Avec cette option, le script parcourt le fichier de configuration et
    renvoie soit <code>Syntax Ok</code>, soit des informations détaillées à
    propos des éventuelles erreurs de syntaxe. Equivalent à <code>apachectl
    -t</code>.</dd>
    
    </dl>
    
    <p>Les options suivantes étaient disponibles dans les anciennes versions
    et ont été supprimées.</p>
    
    <dl>
    
    <dt><code>startssl</code></dt>
    
    <dd>Pour démarrer <code class="program"><a href="../programs/httpd.html">httpd</a></code> avec le support SSL, vous
    devez éditer votre fichier de configuration et y inclure les
    directives appropriées, puis utiliser la commande de démarrage normale
    <code>apachectl start</code>.</dd>
    
    </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/apachectl.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apachectl.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/suexec.html�������������������������������������������������������0000664�0001751�0001751�00000000572�13710016232�021042� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: suexec.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: suexec.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: suexec.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: suexec.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/ab.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000051201�14740503670�021431� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ab - L'outil de test des performances du serveur HTTP
    Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>ab - L'outil de test des performances du serveur HTTP
    Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/ab.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>ab</code> est un utilitaire qui vous permet de tester les
        performances de votre serveur HTTP Apache. Il a été conçu pour vous
        donner une idée du degré de performances de votre installation
        d'Apache. Il vous permet en particulier de déterminer le nombre de
        réquêtes que votre installation d'Apache est capable de servir par
        seconde.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#output">Sortie</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Bogues</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>ab</strong>
        [ -<strong>A</strong> <var>nom-utilisateur</var>:<var>mot-de-passe</var> ]
        [ -<strong>b</strong> <var>taille-tampon</var> ]
        [ -<strong>B</strong> <var>adresse-locale</var> ]
        [ -<strong>c</strong> <var>simultanéité</var> ]
        [ -<strong>C</strong> <var>nom-cookie</var>=<var>valeur</var> ]
        [ -<strong>d</strong> ]
        [ -<strong>e</strong> <var>fichier-csv</var> ]
        [ -<strong>E</strong> <var>fichier du certificat client</var> ]
        [ -<strong>f</strong> <var>protocole</var> ]
        [ -<strong>g</strong> <var>fichier-gnuplot</var> ]
        [ -<strong>h</strong> ]
        [ -<strong>H</strong> <var>en-tête-personnalisé</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>k</strong> ]
        [ -<strong>l</strong> ]
        [ -<strong>m</strong> <var>HTTP-method</var> ]
        [ -<strong>n</strong> <var>requêtes</var> ]
        [ -<strong>p</strong> <var>fichier-POST</var> ]
        [ -<strong>P</strong>
        <var>nom-utilisateur-mandataire</var>:<var>mot-de-passe</var> ]
        [ -<strong>q</strong> ]
        [ -<strong>r</strong> ]
        [ -<strong>s</strong> <var>timeout</var> ]
        [ -<strong>S</strong> ]
        [ -<strong>t</strong> <var>limite-de-durée</var> ]
        [ -<strong>T</strong> <var>type-de-contenu</var> ]
        [ -<strong>u</strong> <var>fichier PUT</var> ]
        [ -<strong>v</strong> <var>verbosité</var>]
        [ -<strong>V</strong> ]
        [ -<strong>w</strong> ]
        [ -<strong>x</strong> <var>&lt;table&gt;-attributs</var> ]
        [ -<strong>X</strong> <var>mandataire</var>[:<var>port</var>] ]
        [ -<strong>y</strong> <var>&lt;tr&gt;-attributs</var> ]
        [ -<strong>z</strong> <var>&lt;td&gt;-attributs</var> ]
        [ -<strong>Z</strong> <var>algorithme-chiffrement</var> ]
        [http[s]://]<var>nom-serveur</var>[:<var>port</var>]/<var>chemin</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-A <var>nom-utilisateur</var>:<var>mot-de-passe</var></code></dt>
        <dd>Fournit le support d'une authentification de base vers le
        serveur. Les nom-utilisateur et mot-de-passe sont séparés par un
        seul caractère <code>:</code> et transmis sous forme codée base64.
        La chaîne est envoyée que le serveur en ait besoin ou non (qu'il ait
        renvoyé un code "401 authentication needed" ou non).</dd>
    
        <dt><code>-b <var>taille-tampon</var></code></dt>
        <dd>Taille du tampon d'émission/réception TCP, en octets.</dd>
    
        <dt><code>-B <var>adresse-locale</var></code></dt>
        <dd>Adresse à laquelle se rattacher lors des connexions sortantes.</dd>
    
        <dt><code>-c <var>simultanéité</var></code></dt>
        <dd>Nombre de requêtes à effectuer simultanément. Par défaut, une
        seule requête est effectuée à la fois.</dd>
    
        <dt><code>-C <var>nom-cookie</var>=<var>valeur</var></code></dt>
        <dd>Ajoute une ligne <code>Cookie:</code> à la requête. L'argument
        se présente en général sous la forme d'une
        paire <code><var>nom</var>=<var>valeur</var></code>. Ce champ peut
        être répété.</dd>
    
        <dt><code>-d</code></dt>
        
        <dd>N'affiche pas le "pourcentage servi dans la table XX [ms]".
        (support de l'héritage).</dd>
    
        <dt><code>-e <var>fichier-csv</var></code></dt>
        <dd>Enregistre des valeurs séparées par des virgules (CSV) dans un
        fichier, indiquant pour chaque pourcentage (de 1% à 100 %), le temps
        (en millisecondes) mis pour servir ce pourcentage de requêtes. Ce
        fichier est en général plus utile qu'un fichier 'gnuplot', car les
        résultats sont déjà sous forme binaire.</dd>
    
        <dt><code>-E <var>fichier du certificat client</var></code></dt>
        <dd>Utilise le certificat client au format PEM qu'il contient pour
        s'authentifier auprès du serveur lors d'une connexion à un site web sous
        SSL. Ce fichier doit contenir le certificat client suivi des certificats
        intermédiaires et de la clé privé. Disponible à partir de la version 2.4.36
        du serveur HTTP Apache.</dd>
    
        <dt><code>-f <var>protocole</var></code></dt>
        <dd>Spécifie le protocole SSL/TLS (SSL2, SSL3, TLS1, TLS1.1, TLS1.2, or ALL).
        TLS1.1 et TLS1.2 sont supportés à partir de la version 2.4.4 du
        serveur HTTP Apache.</dd>
    
        <dt><code>-g <var>fichier-gnuplot</var></code></dt>
        <dd>Enregistre toutes les valeurs mesurées dans un fichier 'gnuplot'
        ou TSV (valeurs séparées par des tabulations). Ce fichier peut être
        facilement importé dans des programmes comme Gnuplot, IDL,
        Mathematica, Igor ou même Excel. La première ligne du fichier
        contient les noms des valeurs.</dd>
    
        <dt><code>-h</code></dt>
        <dd>Affiche une aide à propos de l'utilisation du programme.</dd>
    
        <dt><code>-H <var>en-tête-personnalisé</var></code></dt>
        <dd>Ajoute des en-têtes supplémentaires à la requête. L'argument se
        présente sous la forme d'une ligne d'en-tête valide, autrement dit
        une paire champ/valeur séparés par un caractère ':' (par exemple
        <code>"Accept-Encoding: zip/zop;8bit"</code>).</dd>
    
        <dt><code>-i</code></dt>
        <dd>Effectue des requêtes <code>HEAD</code> plutôt que
        <code>GET</code>.</dd>
    
        <dt><code>-k</code></dt>
        <dd>Active la fonctionnalité des connexions HTTP persistantes
        (KeepAlive), c'est à dire effectue plusieurs requêtes au cours d'une
        seule session HTTP. Cette fonctionnalité est désactivée par
        défaut.</dd>
    
        <dt><code>-l</code></dt>
        <dd>Ne signale pas les erreurs si la taille de la réponse n'est pas
        constante. Cette option peut s'avérer utile pour les pages
        dynamiques. Disponible à partir de la version 2.4.7 du serveur HTTP
        Apache.
        </dd>
    
        <dt><code>-m <var>HTTP-method</var></code></dt>
        <dd>Méthode HTTP personnalisée à utiliser pour les requêtes.
        Disponible à partir de la version 2.4.10 du serveur HTTP
        Apache.</dd>
    
        <dt><code>-n <var>requêtes</var></code></dt>
        <dd>Nombre de requêtes à effectuer au cours du test de performances.
        Par défaut, une seule requête est effectuée, ce qui ne permet pas
        d'obtenir des résultats représentatifs.</dd>
    
        <dt><code>-p <var>fichier-POST</var></code></dt>
        <dd>Fichier contenant les données pour les requêtes POST.
        Assurez-vous de spécifier aussi le paramètre <code>-T</code>.</dd>
    
        <dt><code>-P <var>nom-utilisateur-mandataire</var>:<var>mot-de-passe</var></code></dt>
        <dd>Fournit les informations d'authentification basique pour un
        mandataire en-route. Les nom d'utilisateur et mot de passe sont
        séparés par un simple caractère <code>:</code> et envoyés sur le
        réseau codés en base64. La chaîne est envoyée, que le mandataire en
        ait besoin ou non (qu'il ait renvoyé un code "407 proxy
        authentication needed" ou non).</dd>
    
        <dt><code>-q</code></dt>
        <dd>Lorsque plus de 150 requêtes sont traitées, <code>ab</code>
        affiche la progression du traitement sur <code>stderr</code> tous
        les 10% du nombre total ou toutes les 100 requêtes. Le drapeau
        <code>-q</code> permet de supprimer ces messages.</dd>
    
        <dt><code>-r</code></dt>
        <dd>Ne s'arrête pas en cas d'erreur de réception du socket.</dd>
    
        <dt><code>-s <var>timeout</var></code></dt>
        <dd>Temps maximum d'attente en secondes du socket avant de considérer
        le délai comme dépassé. La valeur par défaut est de 30 secondes.
        Disponible à partir de la version 2.4.4 du serveur HTTP
        Apache.</dd>
    
        <dt><code>-S</code></dt>
        <dd>N'affiche ni les valeurs de déviation standards et médianes, ni
        les messages d'erreur et d'avertissement lorsque les valeurs
        médianes et moyennes sont égales à une ou deux fois la valeur de
        déviation standard. Par défaut les valeurs mini/moyenne/maxi sont
        affichées (support de l'héritage).</dd>
        
    
        <dt><code>-t <var>limite-durée</var></code></dt>
        <dd>Durée maximale en secondes du test de performances. Ceci
        implique un <code>-n 50000</code> en interne. Utilisez cette option
        si vous souhaitez tester les performances du serveur pendant une
        durée fixée à l'avance. Par défaut, il n'y a pas de limite de
        durée.</dd>
    
        <dt><code>-T <var>type-contenu</var></code></dt>
        <dd>Valeur de l'en-tête Content-type à utiliser pour les données
        POST/PUT, par exemple
        <code>application/x-www-form-urlencoded</code>.
        La valeur par défaut est <code>text/plain</code>.</dd>
    
        <dt><code>-u <var>fichier PUT</var></code></dt>
        <dd>Fichier contenant des données PUT.  Ne pas oublier de spécifier
        aussi <code>-T</code>.</dd>
    
        <dt><code>-v <var>verbosité</var></code></dt>
        <dd>Définit le niveau de verbosité - les niveaux <code>4</code> et
        supérieurs permettent d'afficher des informations à propos des
        en-têtes, les niveaux <code>3</code> et supérieurs les codes de
        réponse (404, 200, etc...), et les niveaux <code>2</code> et
        supérieurs les messages d'avertissement et d'information.</dd>
    
        <dt><code>-V</code></dt>
        <dd>Affiche le numéro de version et s'arrête.</dd>
    
        <dt><code>-w</code></dt>
        <dd>Affiche les résultats dans des tables HTML. La table par défaut
        comporte deux colonnes sur fond blanc.</dd>
    
        <dt><code>-x <var>&lt;table&gt;-attributs</var></code></dt>
        <dd>La chaîne à utiliser comme attributs pour
        <code>&lt;table&gt;</code>. Les attributs sont insérés
        <code>&lt;table <var>ici</var> &gt;</code>.</dd>
    
        <dt><code>-X <var>mandataire</var>[:<var>port</var>]</code></dt>
        <dd>Utilise un serveur mandataire pour les requêtes.</dd>
    
        <dt><code>-y <var>&lt;tr&gt;-attributs</var></code></dt>
        <dd>La chaîne à utiliser comme attributs pour
        <code>&lt;tr&gt;</code>.</dd>
    
        <dt><code>-z <var>&lt;td&gt;-attributs</var></code></dt>
        <dd>La chaîne à utiliser comme attributs pour
        <code>&lt;td&gt;</code>.</dd>
    
        <dt><code>-Z <var>algorithme-chiffrement</var></code></dt>
        <dd>Spécifie l'algorithme de chiffrement SSL/TLS (Voir les
        algorithme de chiffrement openssl).</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="output" id="output">Sortie</a></h2>
        <p>Vous touverez dans ce qui suit la liste des valeurs retournées
        par <code>ab</code> :
        </p>
    
        <dl>
            <dt>Server Software</dt>
            <dd>La valeur, si elle existe, de l'en-tête HTTP
    	<var>server</var> renvoyée dans la première réponse réussie.
    	Elle comporte tous les caractères de l'en-tête jusqu'à ce qu'un
    	caractère de valeur décimale 32 soit rencontré (le plus souvent
    	un espace ou une fin de ligne).</dd>
    
            <dt>Server Hostname</dt>
            <dd>Le nom DNS ou l'adresse IP fourni dans la ligne de commande.</dd>
    
            <dt>Server Port</dt>
            <dd>Le port auquel ab est connecté. Si la ligne de commande ne
    	spécifie aucun port, le port par défaut sera 80 pour http et 443
    	pour https.</dd>
    
            <dt>SSL/TLS Protocol</dt>
            <dd>Les paramètres de protocole négociés entre le client et le
    	serveur. Uniquement si SSL est utilisé.</dd>
    
            <dt>Document Path</dt>
            <dd>L'URI de la requête interprété à partir de la chaîne de la
    	ligne de commande.</dd>
    
            <dt>Document Length</dt>
            <dd>Il s'agit de la taille en octets du premier document renvoyé
    	avec succès. Si la taille du document est modifiée au cours
    	du test, la réponse est considérée comme une erreur.</dd>
    
            <dt>Concurrency Level</dt>
            <dd>Le nombre de clients simultanés utilisés au cours du test.</dd>
    
            <dt>Time taken for tests</dt>
            <dd>Il s'agit du temps écoulé entre le moment de la première
    	connexion au socket et la réception de la dernière
    	réponse.</dd>
    
            <dt>Complete requests</dt>
            <dd>Le nombre de réponses reçues avec succès.</dd>
    
            <dt>Failed requests</dt>
            <dd>Le nombre de requêtes considérées comme erronées. Si ce
    	nombre est différent de 0, une ligne supplémentaire indiquera le
    	nombre de requêtes ayant échoué suite à un problème de
    	connexion, de lecture, de taille de contenu erronée ou
    	d'exceptions.</dd>
    
            <dt>Write errors</dt>
            <dd>Le nombre d'erreurs rencontrées en cours d'écriture (broken pipe).</dd>
    
            <dt>Non-2xx responses</dt>
            <dd>Le nombre de réponses dont le code était en dehors de la
    	série 200. Si toutes les réponses appartiennent à la série 200,
    	cette ligne est absente.</dd>
    
            <dt>Keep-Alive requests</dt>
            <dd>Le nombre de connexions promues à l'état de connexions
    	persistantes.</dd>
    
            <dt>Total body sent</dt>
            <dd>Si le test a été configuré dans ce sens, il s'agit du nombre
    	total d'octets envoyés au cours du test. Ce champ est omis si le
    	test ne prévoyait pas d'envoi de corps.</dd>
    
            <dt>Total transferred</dt>
            <dd>Le nombre total d'octets reçus du serveur. Ce nombre
    	correspond à peu près au nombre d'octets envoyés sur la ligne.</dd>
    
            <dt>HTML transferred</dt>
            <dd>Le nombre total d'octets utiles (contenus) reçus du serveur.
    	Ce nombre n'inclut pas les octets correspondant aux en-têtes
    	HTTP.</dd>
    
            <dt>Requests per second</dt>
            <dd>Il s'agit du nombre de requêtes par seconde. Il correspond
    	au nombre de requêtes divisé par la durée totale du traitement.</dd>
    
            <dt>Time per request</dt>
            <dd>La durée moyenne du traitement d'une requête. La première
    	valeur est calculée selon la formule <code>concurrency *
    	timetaken * 1000 / done</code>, alors que la seconde valeur est
    	calculée selon la formule <code>timetaken * 1000 / done</code>.</dd>
    
            <dt>Transfer rate</dt>
            <dd>Le taux de transfert calculé selon la formule
    	<code>totalread / 1024 / timetaken</code>.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Bogues</a></h2>
        <p>De nombreux tampons de taille fixe sont déclarés statiquement.
        Combiné avec l'interprétation poussive des arguments de la ligne de
        commande, les en-têtes de réponse du serveur et autres entrées
        externes, ceci peut vous affecter.</p>
    
        <p>HTTP/1.x n'est pas complètement implémenté ; seules certaines
        formes de réponses 'attendues' sont acceptées. L'utilisation
        relativement intense de <code>strstr(3)</code> provoque un affichage
        en tête de profil, ce qui peut faire croire à un problème de
        performances ; en d'autres termes, vous mesurez les performances de
        <code>ab</code> plutôt que celles du serveur.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/ab.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/ab.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/index.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000015665�14740503670�022174� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Le serveur et ses utilitaires - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Le serveur et ses utilitaires</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>Cette page documente tous les utilitaires inclus
        dans le serveur HTTP Apache.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="index" id="index">Index</a></h2>
    
        <dl>
          <dt><code class="program"><a href="../programs/httpd.html">httpd</a></code></dt>
    
          <dd>Le serveur de protocole de transfert hypertexte Apache</dd>
    
          <dt><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></dt>
    
          <dd>L'interface de contrôle du serveur HTTP Apache</dd>
    
          <dt><code class="program"><a href="../programs/ab.html">ab</a></code></dt>
    
          <dd>L'outil de test de performances du serveur HTTP Apache</dd>
    
          <dt><code class="program"><a href="../programs/apxs.html">apxs</a></code></dt>
    
          <dd>L'outil de gestion des extensions Apache</dd>
    
          <dt><code class="program"><a href="../programs/configure.html">configure</a></code></dt>
    
          <dd>Configuration de l'arborescence des sources</dd>
    
          <dt><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></dt>
    
          <dd>Crée et met à jour les fichiers d'authentification utilisateurs au
          format DBM pour une authentification basique</dd>
    
          <dt><code class="program"><a href="../programs/fcgistarter.html">fcgistarter</a></code></dt>
    
          <dd>Lance un programme fastcgi</dd>
    
          <dt><code class="program"><a href="../programs/htcacheclean.html">htcacheclean</a></code></dt>
    
          <dd>Nettoie le cache sur disque</dd>
    
          <dt><code class="program"><a href="../programs/htdigest.html">htdigest</a></code></dt>
    
          <dd>Crée et met à jour les fichiers d'authentification pour une
          authentification sommaire</dd>
    
          <dt><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></dt>
    
          <dd>Manipulation des bases de données DBM des mots de passe.</dd>
    
          <dt><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code></dt>
    
          <dd>Crée et met à jour les fichiers d'authentification pour une
          authentification basique</dd>
    
          <dt><code class="program"><a href="../programs/httxt2dbm.html">httxt2dbm</a></code></dt>
    
          <dd>Crée des fichiers dbm destinés à être utilisés avec
          RewriteMap</dd>
    
          <dt><code class="program"><a href="../programs/logresolve.html">logresolve</a></code></dt>
    
          <dd>Résolution des noms d'hôtes en adresses IP dans les fichiers
          de traces d'Apache</dd>
    
          <dt><code class="program"><a href="../programs/log_server_status.html">log_server_status</a></code></dt>
    
           <dd>Journalisation périodique du statut du serveur</dd>
    
          <dt><code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code></dt>
    
          <dd>Rotation des traces d'Apache sans devoir arrêter le serveur</dd>
    
          <dt><code class="program"><a href="../programs/split-logfile.html">split-logfile</a></code></dt>
    
           <dd>Divise un journal pour plusieurs hôtes virtuels en journaux
           spécifiques à chaque hôte</dd>
    
          <dt><code class="program"><a href="../programs/suexec.html">suexec</a></code></dt>
    
          <dd>Change d'utilisateur pour l'exécution de certains programmes</dd>
    
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdbm.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000050402�14740503670�022147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htdbm - Manipuler des bases de données DBM de mots de
    passe - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>htdbm - Manipuler des bases de données DBM de mots de
    passe</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htdbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdbm.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/htdbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htdbm</code> permet de manipuler des fichiers au format DBM
        ou sont stockés des nom d'utilisateurs et mots de passe à des fins
        d'authentification de base des utilisateurs HTTP via le module
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code>. Voir la documentation de
        <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> pour plus de détails à propos de ces
        fichiers DBM.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Bugs</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Valeur renvoyée</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Exemples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Considérations à propos de sécurité</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#restrictions">Restrictions</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></li><li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>htdbm</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>nom-fichier</var> <var>nom-utilisateur</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>b</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
        -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>nom-fichier</var> <var>nom-utilisateur</var> <var>mot-de-passe</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>n</strong>
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>nom-utilisateur</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>nb</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>nom-utilisateur</var> <var>mot-de-passe</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>v</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>nom-fichier</var> <var>nom-utilisateur</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>vb</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>nom-fichier</var> <var>nom-utilisateur</var> <var>mot-de-passe</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>x</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        <var>nom-fichier</var> <var>nom-utilisateur</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>l</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-b</code></dt>
        <dd>Utilise le mode batch ; en d'autres termes, le mot de passe est
        extrait de la ligne de commande au lieu d'être demandé à
        l'opérateur. Cette option doit être utilisée avec la plus grande
        prudence, car <strong>le mot de passe est visible en clair</strong>
        dans la ligne de commande. Pour utiliser un script, voir l'option
        <code>-i</code>.</dd>
    
        <dt><code>-i</code></dt>
        <dd>Lit le mot de passe depuis stdin sans vérification (à utiliser
        dans le cadre d'un script).</dd>
    
        <dt><code>-c</code></dt>
        <dd>Crée le <var>fichier-mots-de-passe</var>. Si
        <var>fichier-mots-de-passe</var> existe déjà, il est réécrit et
        tronqué. Cette option ne peut pas être combinée avec l'option
        <code>-n</code>.</dd>
    
        <dt><code>-n</code></dt>
        <dd>Affiche les résultats sur la sortie standard et ne met pas à
        jour la base de données. Cette option modifie la syntaxe de la ligne
        de commande, car l'argument <var>fichier-mots-de-passe</var> (en
        général le premier) est omis. Elle ne peut pas être combinée avec
        l'option <code>-c</code>.</dd>
    
        <dt><code>-m</code></dt>
        <dd>Utilise un hachage MD5 pour les mots de passe. Sous Windows
        et Netware, c'est l'option par défaut..</dd>
    
        <dt><code>-B</code></dt>
        <dd>Utilise l'algorythme de hachage bcrypt pour les mots de
        passe. C'est un algorythme actuellement considéré comme sûr.</dd>
    
        <dt><code>-C</code></dt>
        <dd>Ce drapeau n'est autorisé qu'en conjonction avec le drapeau
        <code>-B</code> (hachage bcrypt). Il permet de définir la durée
        de traitement pour l'algorythme de chiffrement bcrypt (plus elle est
        longue, plus la sécurité est élevée, mais la rapidité est diminuée
        d'autant) ; la valeur par défaut est 5, les valeurs valides vont de
        4 à 31.</dd>
    
    
        <dt><code>-d</code></dt>
        <dd>Utilise un hachage <code>crypt()</code> pour les mots de
        passe. C'est l'option par défaut sur toutes les plates-formes, sauf
        Windows et Netware. Bien que <code>htdbm</code> supporte ce
        chiffrement sur toutes les plates-formes, il n'est pas supporté par
        le serveur <code class="program"><a href="../programs/httpd.html">httpd</a></code> sous Windows et Netware. Cet
        algorythme est considéré comme <strong>non sûr</strong> selon les
        standards actuels.</dd>
    
        <dt><code>-s</code></dt>
        <dd>Utilise le hachage SHA pour les mots de passe. Facilite la
        migration vers/depuis les serveurs Netscape qui utilisent le format
        LDAP Directory Interchange (ldif). Cet
        algorythme est considéré comme <strong>non sûr</strong> selon les
        standards actuels.</dd>
    
        <dt><code>-p</code></dt>
        <dd>Utilise des mots de passe au format texte en clair. Bien que
        <code>htdbm</code> supporte ce format sur toutes les plates-formes,
        le démon <code class="program"><a href="../programs/httpd.html">httpd</a></code> n'accepte les mots de passe au
        format texte en clair que sous Windows et Netware.</dd>
    
        <dt><code>-l</code></dt>
        <dd>Affiche chaque nom d'utilisateur de la base de données
        accompagné de son commentaire sur la sortie standard.</dd>
    
        <dt><code>-v</code></dt>
        <dd>Vérifie une association nom d'utilisateur/mot de passe. Le
        programme affichera un message indiquant si le mot de passe fourni
        est valide. Si le mot de passe n'est pas valide, le programme
        s'arrête et renvoie un code d'erreur 3.</dd>
    
        <dt><code>-x</code></dt>
        <dd>Supprime l'utilisateur. Si le nom d'utilisateur existe dans le
        fichier DBM spécifié, il sera supprimé.</dd>
    
        <dt><code>-t</code></dt>
        <dd>Interprète le dernier paramètre en tant que commentaire. Avec
        cette option, il est possible d'ajouter une chaîne supplémentaire à
        la fin de la ligne de commande ; le contenu de cette chaîne sera
        stocké dans la base de données dans le champ "Comment" associé au
        nom d'utilisateur spécifié.</dd>
    
        <dt><code><var>nom-fichier</var></code></dt>
        <dd>Le nom du fichier au format DBM en général sans l'extension
        <code>.db</code>, <code>.pag</code>, ou <code>.dir</code>. Avec
        l'option <code>-c</code>, le fichier DBM est mis à jour s'il existe
        ou créé dans le cas contraire.</dd>
    
        <dt><code><var>nom-utilisateur</var></code></dt>
        <dd>Le nom d'utilisateur à créer ou mettre à jour dans le
        <var>fichier-mots-de-passe</var>. Si <var>nom-utilisateur</var>
        n'existe pas dans ce fichier, une entrée est ajoutée. S'il existe,
        son mot de passe est modifié.</dd>
    
        <dt><code><var>mot-de-passe</var></code></dt>
        <dd>Le mot de passe en clair destiné à être haché et stocké dans
        le fichier DBM. Ne s'utilise qu'avec l'option <code>-b</code>.</dd>
    
        <dt><code>-T<var>DBTYPE</var></code></dt>
        <dd>Type de fichier DBM (SDBM, GDBM, DB, ou "default").</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Bugs</a></h2>
        <p>Vous devez garder à l'esprit qu'il existe de nombreux formats de
        fichiers DBM différents, et que selon toute vraisemblance, des
        bibliothèques pour plus d'un format sont présentes sur votre
        système. Les trois exemples de base sont SDBM, NDBM, le projet GNU
        GDBM, et Berkeley/Sleepycat DB 2/3/4. Malheureusement, toutes ces
        bibliothèques
        utilisent des formats de fichiers différents, et vous devez vous
        assurer que le format de fichier utilisé par <var>nom-fichier</var>
        correspond au format attendu par <code>htdbm</code>.
        Actuellement, <code>htdbm</code> n'a aucun moyen de savoir à
        quel type de fichier DBM il a à faire. S'il est utilisé avec un
        format inapproprié, il ne renverra rien, ou pourra créer un fichier
        DBM différent avec un nom différent, ou au pire, va corrompre le
        fichier DBM si vous avez tenté de le modifier.</p>
    
        <p>Vous pouvez utiliser le programme <code>file</code> fourni par la
        plupart des systèmes Unix pour déterminer le format d'un fichier
        DBM.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Valeur renvoyée</a></h2>
        <p><code>htdbm</code> renvoie 0 ("true") si les nom d'utilisateur et
        mot de passe ont été créés ou mis à jour avec succès dans le fichier
        DBM. <code>htdbm</code> renvoie <code>1</code> s'il a rencontré un
        problème d'accès aux fichiers, <code>2</code> si la ligne de
        commande comportait une erreur de syntaxe, <code>3</code> si le mot
        de passe a été fourni interactivement et s'il est invalide pour
        l'entrée considérée, <code>4</code> si l'opération a été
        interrompue, <code>5</code> si une valeur est trop longue (nom
        utilisateur, nom fichier, mot de passe, ou l'enregistrement après
        son élaboration), <code>6</code> si le nom d'utilisateur contient
        des caractères illégaux (voir la section <a href="#restrictions">Restrictions</a>), et <code>7</code> si le
        fichier n'est pas un fichier de mots de passe DBM valide.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples</a></h2>
        <div class="example"><p><code>
          htdbm /usr/local/etc/apache/.utilisateurs-htdbm jsmith
        </code></p></div>
    
        <p>Ajoute ou modifie le mot de passe de l'utilisateur
        <code>jsmith</code>. Le mot de passe est demandé à l'opérateur. Sous
        Windows, le mot de passe sera haché en utilisant l'algorithme MD5
        Apache modifié ; dans les autres cas, c'est la routine
        <code>crypt()</code> du système qui sera utilisée. Si le fichier
        n'existe pas, <code>htdbm</code> s'arrêtera et renverra une
        erreur.</p>
    
        <div class="example"><p><code>
          htdbm -c /home/doe/public_html/.htdbm jane
        </code></p></div>
    
        <p>Crée un nouveau fichier et y enregistre une entrée pour
        l'utilisateur <code>jane</code>. Le mot de passe est demandé à
        l'opérateur. Si le fichier existe et ne peut pas être lu, ou ne peut
        pas être écrit, il ne sera pas modifié et
        <code>htdbm</code> affichera un message et renverra un code
        d'erreur.</p>
    
        <div class="example"><p><code>
          htdbm -mb /usr/web/.htdbm-tous jones Pwd4Steve
        </code></p></div>
    
        <p>Chiffre le mot de passe entré avec la ligne de commande
        (<code>Pwd4Steve</code>) à l'aide de l'algorithme MD5, et
        l'enregistre dans le fichier spécifié.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Considérations à propos de sécurité</a></h2>
        <p>Les fichiers de mots de passe Web tels que ceux que gère
        <code>htdbm</code> ne doivent <em>pas</em> être stockés dans
        l'espace d'URI du serveur Web -- en d'autres termes, il ne doit pas
        être possible d'y accéder à l'aide d'un navigateur.</p>
    
        <p>L'utilisation de l'option <code>-b</code> est déconseillée, car
        lorsqu'il est utilisé, le mot de passe apparaît en clair sur la
        ligne de commande.</p>
    
        <p>Notez que lorsque vous utilisez l'algorythme
        <code>crypt()</code>, seuls les 8 premiers caractères du mot de
        passe sont pris en compte. Si le mot de passe fourni est plus long,
        les caractères supplémentaires seront ignorés sans avertissement.</p>
    
        <p>L'algorythme de hachage SHA ne permet pas de spécifier une valeur
        d'initialisation pour la génération de nombres aléatoires (salting)
        : un mot de passe donné ne possède ainsi qu'une seule représentation
        hachée. Les algorythmes <code>crypt()</code> et MD5 permettent quant à
        eux des représentations hachées multiples en acceptant comme
        paramètre une chaîne d'initialisation (salt), rendant les attaques à
        base de dictionnaires contre les mots de passe plus difficiles.</p>
    
        <p>Les algorythmes SHA et <code>crypt()</code> sont considérés comme
        non sûrs selon les standards actuels.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="restrictions" id="restrictions">Restrictions</a></h2>
        <p>Sur la plate-forme Windows, les mots de passe hachés avec
        <code>htdbm</code> ont une taille limitée à <code>255</code>
        caractères. Si le mot de passe fourni est plus long, il sera tronqué
        à 255 caractères.</p>
    
        <p>L'algorithme MD5 utilisé par <code>htdbm</code> est spécifique à
        Apache ; les mots de passe hachés en utilisant cet algorithme
        seront inutilisables sur d'autres serveurs Web.</p>
    
        <p>Les noms d'utilisateurs ont une taille limitée à <code>255</code>
        octets et ne doivent pas contenir de caractère <code>:</code>.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htdbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdbm.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/htdbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htdbm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apachectl.html.en�������������������������������������������������0000664�0001751�0001751�00000026554�14737241666�022130� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apachectl - Apache HTTP Server Control Interface - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>apachectl - Apache HTTP Server Control Interface</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/apachectl.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>apachectl</code> 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
         <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon.</p>
    
         <p>The <code>apachectl</code> script can operate in two modes.
         First, it can act as a simple front-end to the <code class="program"><a href="../programs/httpd.html">httpd</a></code>
         command that simply sets any necessary environment variables and
         then invokes <code class="program"><a href="../programs/httpd.html">httpd</a></code>, passing through any command line
         arguments.  Second, <code>apachectl</code> can act as a SysV init
         script, taking simple one-word arguments like <code>start</code>,
         <code>restart</code>, and <code>stop</code>, and translating them
         into appropriate signals to <code class="program"><a href="../programs/httpd.html">httpd</a></code>.</p>
    
         <p>If your Apache installation uses non-standard paths, you will
         need to edit the <code>apachectl</code> script to set the
         appropriate paths to the <code class="program"><a href="../programs/httpd.html">httpd</a></code> binary.  You can also
         specify any necessary <code class="program"><a href="../programs/httpd.html">httpd</a></code> command line arguments.
         See the comments in the script for details.</p>
    
         <p>The <code>apachectl</code> script returns a 0 exit value on
         success, and &gt;0 if an error occurs.  For more details, view
         the comments in the script.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../invoking.html">Starting Apache</a></li><li><a href="../stopping.html">Stopping Apache</a></li><li><a href="../configuring.html">Configuration Files</a></li><li><a href="../platform/">Platform Docs</a></li><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
    
    <p>When acting in pass-through mode, <code>apachectl</code> can take
    all the arguments available for the <code class="program"><a href="../programs/httpd.html">httpd</a></code>
    binary.</p>
    
    <p><code><strong>apachectl</strong> [ <var>httpd-argument</var> ]</code></p>
    
    <p>When acting in SysV init mode, <code>apachectl</code> takes simple,
    one-word commands, defined below.</p>
    
    <p><code><strong>apachectl</strong> <var>command</var></code></p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <p>Only the SysV init-style options are defined here.  Other arguments
    are defined on the <code class="program"><a href="../programs/httpd.html">httpd</a></code> manual page.</p>
    
    <dl>
    
    <dt><code>start</code></dt>
    
    <dd>Start the Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon.  Gives an error if it
    is already running.  This is equivalent to <code>apachectl -k
    start</code>.</dd>
    
    <dt><code>stop</code></dt>
    
    <dd>Stops the Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon.  This is equivalent to
    <code>apachectl -k stop</code>.</dd>
    
    <dt><code>restart</code></dt>
    
    <dd>Restarts the Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon.  If the daemon is
    not running, it is started.  This command automatically checks the
    configuration files as in <code>configtest</code> before initiating
    the restart to make sure the daemon doesn't die.  This is equivalent
    to <code>apachectl -k restart</code>.</dd>
    
    <dt><code>fullstatus</code></dt>
    
    <dd>Displays a full status report from <code class="module"><a href="../mod/mod_status.html">mod_status</a></code>.
    For this to work, you need to have <code class="module"><a href="../mod/mod_status.html">mod_status</a></code> enabled
    on your server and a text-based browser such as <code>lynx</code>
    available on your system.  The URL used to access the status report
    can be set by editing the <code>STATUSURL</code> variable in the
    script.</dd>
    
    <dt><code>status</code></dt>
    
    <dd>Displays a brief status report.  Similar to the
    <code>fullstatus</code> option, except that the list of requests
    currently being served is omitted.</dd>
    
    <dt><code>graceful</code></dt>
    
    <dd>Gracefully restarts the Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> 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 <code>configtest</code> before initiating the
    restart to make sure Apache doesn't die.  This is equivalent to
    <code>apachectl -k graceful</code>.</dd>
    
    <dt><code>graceful-stop</code></dt>
    
    <dd>Gracefully stops the Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon.
    This differs from a normal stop in that currently open connections are not
    aborted.  A side effect is that old log files will not be closed immediately.
    This is equivalent to <code>apachectl -k graceful-stop</code>.</dd>
    
    <dt><code>configtest</code></dt>
    
    <dd>Run a configuration file syntax test. It parses the configuration
    files and either reports <code>Syntax Ok</code>
    or detailed information about the particular syntax error.  This is
    equivalent to <code>apachectl -t</code>.</dd>
    
    </dl>
    
    <p>The following option was available in earlier versions but has been removed.</p>
    
    <dl>
    
    <dt><code>startssl</code></dt>
    
    <dd>To start <code class="program"><a href="../programs/httpd.html">httpd</a></code> with SSL support, you should edit
    your configuration file to include the relevant directives and then
    use the normal <code>apachectl start</code>.</dd>
    
    </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/apachectl.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apachectl.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htcacheclean.html.en����������������������������������������������0000664�0001751�0001751�00000034344�14737241666�022602� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htcacheclean - Clean up the disk cache - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>htcacheclean - Clean up the disk cache</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/htcacheclean.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htcacheclean</code> is used to keep the size of
        <code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code>'s storage within a given size limit, or
        limit on inodes in use. This tool can run either manually or in daemon mode.
        When running in daemon mode, it sleeps in the background and checks the cache
        directory at regular intervals for cached content to be removed. You can stop
        the daemon cleanly by sending it a TERM or INT signal. When run manually, a
        once off check of the cache directory is made for cached content to be
        removed. If one or more URLs are specified, each URL will be deleted from
        the cache, if present.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#delete">Deleting a specific URL</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#list">Listing URLs in the Cache</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Exit Status</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>htcacheclean</strong>
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>r</strong> ]
        [ -<strong>n</strong> ]
        [ -<strong>R</strong><var>round</var> ]
        -<strong>p</strong><var>path</var>
        [ -<strong>l</strong><var>limit</var> ]
        [ -<strong>L</strong><var>limit</var> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>n</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>i</strong> ]
        [ -<strong>P</strong><var>pidfile</var> ]
        [ -<strong>R</strong><var>round</var> ]
        -<strong>d</strong><var>interval</var>
        -<strong>p</strong><var>path</var>
        [ -<strong>l</strong><var>limit</var> ]
        [ -<strong>L</strong><var>limit</var> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>v</strong> ]
        [ -<strong>R</strong><var>round</var> ]
        -<strong>p</strong><var>path</var>
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>R</strong><var>round</var> ]
        -<strong>p</strong><var>path</var>
        <var>url</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-d<var>interval</var></code></dt>
        <dd>Daemonize and repeat cache cleaning every <var>interval</var> minutes.
        This option is mutually exclusive with the <code>-D</code>, <code>-v</code>
        and <code>-r</code> options. To shutdown the daemon cleanly, just send it
        a <code>SIGTERM</code> or <code>SIGINT</code>.</dd>
    
        <dt><code>-D</code></dt>
        <dd>Do a dry run and don't delete anything. This option is mutually
            exclusive with the <code>-d</code> option. When doing a dry run and
            deleting directories with <code>-t</code>, the inodes reported deleted
            in the stats cannot take into account the directories deleted, and will
            be marked as an estimate.</dd>
    
        <dt><code>-v</code></dt>
        <dd>Be verbose and print statistics. This option is mutually exclusive
        with the <code>-d</code> option.</dd>
    
        <dt><code>-r</code></dt>
        <dd>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 <code>-d</code> option and implies
        the <code>-t</code> option.</dd>
    
        <dt><code>-n</code></dt>
        <dd>Be nice. This causes slower processing in favour of other
        processes. <code>htcacheclean</code> 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.</dd>
    
        <dt><code>-t</code></dt>
        <dd>Delete all empty directories. By default only cache files are
        removed, however with some configurations the large number of
        directories created may require attention. If your configuration
        requires a very large number of directories, to the point that
        inode or file allocation table exhaustion may become an issue, use
        of this option is advised.</dd>
    
        <dt><code>-p<var>path</var></code></dt>
        <dd>Specify <var>path</var> as the root directory of the disk cache. This
        should be the same value as specified with the <code class="directive"><a href="../mod/mod_cache_disk.html#cacheroot">CacheRoot</a></code> directive.</dd>
    
        <dt><code>-P<var>pidfile</var></code></dt>
        <dd>Specify <var>pidfile</var> as the name of the file to write the
        process ID to when daemonized.</dd>
    
        <dt><code>-R<var>round</var></code></dt>
        <dd>Specify <var>round</var> as the amount to round sizes up to, to
        compensate for disk block sizes. Set to the block size of the cache
        partition.</dd>
    
        <dt><code>-l<var>limit</var></code></dt>
        <dd>Specify <var>limit</var> as the total disk cache size limit. The value
        is expressed in bytes by default (or attaching <code>B</code> to the
        number). Attach <code>K</code> for Kbytes, <code>M</code> for
        MBytes or <code>G</code> for Gbytes.</dd>
    
        <dt><code>-L<var>limit</var></code></dt>
        <dd>Specify <var>limit</var> as the total disk cache inode limit.
        <code>K</code>, <code>M</code> or <code>G</code> suffix can also be
        used.</dd>
    
        <dt><code>-i</code></dt>
        <dd>Be intelligent and run only when there was a modification of the disk
        cache. This option is only possible together with the <code>-d</code>
        option.</dd>
    
        <dt><code>-a</code></dt>
        <dd>List the URLs currently stored in the cache. Variants of the same URL
        will be listed once for each variant.</dd>
    
        <dt><code>-A</code></dt>
        <dd>List the URLs currently stored in the cache, along with their
        attributes in the following order: url, header size, body size, status,
        entity version, date, expiry, request time, response time, body present,
        head request.</dd>
        </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="delete" id="delete">Deleting a specific URL</a></h2>
        <p>If <code>htcacheclean</code> is passed one or more URLs, each URL will
        be deleted from the cache. If multiple variants of an URL exists, all
        variants would be deleted.</p>
    
        <p>When a reverse proxied URL is to be deleted, the effective URL is
        constructed from the <strong>Host</strong> header, the
        <strong>port</strong>, the <strong>path</strong> and the
        <strong>query</strong>. Note the '?' in the URL must always be specified
        explicitly, whether a query string is present or not. For example, an
        attempt to delete the path <strong>/</strong> from the server
        <strong>localhost</strong>, the URL to delete would be
        <strong>http://localhost:80/?</strong>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="list" id="list">Listing URLs in the Cache</a></h2>
        <p>By passing the <code>-a</code> or <code>-A</code> options to
        <code>htcacheclean</code>, the URLs within the cache will be listed
        as they are found, one URL per line. The <code>-A</code> option
        dumps the full cache entry after the URL, with fields in the
        following order:</p>
    
        <dl>
            <dt>url</dt><dd>The URL of the entry.</dd>
            <dt>header size</dt><dd>The size of the header in bytes.</dd>
            <dt>body size</dt><dd>The size of the body in bytes.</dd>
            <dt>status</dt><dd>Status of the cached response.</dd>
            <dt>entity version</dt><dd>The number of times this entry has been
            revalidated without being deleted.</dd>
            <dt>date</dt><dd>Date of the response.</dd>
            <dt>expiry</dt><dd>Expiry date of the response.</dd>
            <dt>request time</dt><dd>Time of the start of the request.</dd>
            <dt>response time</dt><dd>Time of the end of the request.</dd>
            <dt>body present</dt><dd>If 0, no body is stored with this request,
            1 otherwise.</dd>
            <dt>head request</dt><dd>If 1, the entry contains a cached HEAD
            request with no body, 0 otherwise.</dd>
        </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Exit Status</a></h2>
        <p><code>htcacheclean</code> returns a zero status ("true") if all
        operations were successful, <code>1</code> otherwise. If an URL is
        specified, and the URL was cached and successfully removed,
        <code>0</code> is returned, <code>2</code> otherwise. If an error
        occurred during URL removal, <code>1</code> is returned.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/htcacheclean.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htcacheclean.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/ab.html�����������������������������������������������������������0000664�0001751�0001751�00000000552�13710016232�020126� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: ab.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: ab.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: ab.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: ab.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/fcgistarter.html.en�����������������������������������������������0000664�0001751�0001751�00000015024�14737241666�022507� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>fcgistarter - Start a FastCGI program - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>fcgistarter - Start a FastCGI program</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/fcgistarter.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/fcgistarter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/fcgistarter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p />
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#note">Note</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="note" id="note">Note</a></h2>
          <p>Currently only works on Unix systems.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>fcgistarter</strong>
        -<strong>c</strong> <var>command</var>
        -<strong>p</strong> <var>port</var>
        [ -<strong>i</strong> <var>interface</var> ]
        -<strong>N</strong> <var>num</var>
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-c <var>command</var></code></dt>
        <dd>Absolute path of the FastCGI program</dd>
    
        <dt><code>-p <var>port</var></code></dt>
        <dd>Port which the program will listen on</dd>
    
        <dt><code>-i <var>interface</var></code></dt>
        <dd>Interface which the program will listen on</dd>
    
        <dt><code>-N <var>num</var></code></dt>
        <dd>Number of instances of the program</dd>
    
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/fcgistarter.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/fcgistarter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/fcgistarter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/fcgistarter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/suexec.html.tr.utf8�����������������������������������������������0000664�0001751�0001751�00000015722�14743132254�022370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>suexec - harici programları çalıştırmadan önce kullanıcıyı değiştirir - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>suexec - harici programları çalıştırmadan önce kullanıcıyı değiştirir</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code><strong>suexec</strong></code>, CGI programlarını çalıştırmadan
        önce Apache HTTP Sunucusu tarafından kullanıcı değiştirmek için kullanılır.
        Bunu yapabilmek için sunucunun <code>root</code> tarafından çalıştırılmış
        olması gerekir. HTTP artalan süreci normalde <code>root</code> aidiyetinde
        çalışmadığından <code><strong>suexec</strong></code>'in çalıştırılabilir
        dosyasının sahibi <code>root</code> olmalı, setuid biti etkin
        (<code>u+s</code>) olmalı ve dosyaya <code>root</code> dışında hiç kimse
        yazamamalıdır.</p>
    
        <p><code><strong>suexec</strong></code> güvenlik modeli ve kavramlar
        hakkında bilgi edinmek için suexec belgesine (<a href="../suexec.html">http://httpd.apache.org/docs/2.4/suexec.html</a>) bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>suexec</strong> -<strong>V</strong></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
      <dl>
        <dt><code><strong>-V</strong></code></dt>
        <dd><code>root</code> iseniz, bu seçenek
          <code><strong>suexec</strong></code>
        derleme seçeneklerini gösterir. Güvenlik sebebiyle tüm yapılandırma
        seçenekleri sadece derleme sırasında değiştirilebilir.</dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������httpd-2.4.64/docs/manual/programs/ab.html.tr.utf8���������������������������������������������������0000664�0001751�0001751�00000050723�14743132254�021456� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ab - Apache HTTP sunucusu başarım ölçme aracı - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>ab - Apache HTTP sunucusu başarım ölçme aracı</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/ab.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code><strong>ab</strong></code> Apache Hiper Metin Aktarım Protokolü
          (HTTP) sunucunuzun başarımını ölçmek amacıyla kullanabileceğiniz bir
          kıyaslama aracıdır. Mevcut Apache kurulumunuzun görevini nasıl yerine
          getirdiği hakkında bir izlenim edinmeniz için tasarlanmıştır.
          Özellikle, Apache kurulumunuzun saniyede kaç isteği sunma yeteneğinde
          olduğunu gösterir.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#output">Çıktı</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Börtü böcek</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>ab</strong>
        [ -<strong>A</strong> <var>yetkili-kullanıcı:parola</var> ]
        [ -<strong>b</strong> <var>tampon-boyu</var> ]
        [ -<strong>B</strong> <var>yerel-adres</var> ]
        [ -<strong>c</strong> <var>bağlantı-sayısı</var> ]
        [ -<strong>C</strong> <var>çerez-ismi=değer</var> ]
        [ -<strong>d</strong> ]
        [ -<strong>e</strong> <var>csv-dosyası</var> ]
        [ -<strong>E</strong> <var>istemci-sertifikası-dosyası</var> ]
        [ -<strong>f</strong> <var>protokol</var> ]
        [ -<strong>g</strong> <var>gnuplot-dosyası</var> ]
        [ -<strong>h</strong> ]
        [ -<strong>H</strong> <var>özel-başlık</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>k</strong> ]
        [ -<strong>l</strong> ]
        [ -<strong>m</strong> <var>HTTP-yöntemi</var> ]
        [ -<strong>n</strong> <var>istek-sayısı</var> ]
        [ -<strong>p</strong> <var>POST-dosyası</var> ]
        [ -<strong>P</strong> <var>vekil-yetkilisi:parola</var> ]
        [ -<strong>q</strong> ]
        [ -<strong>r</strong> ]
        [ -<strong>s</strong> <var>zamanasimi</var> ]
        [ -<strong>S</strong> ]
        [ -<strong>t</strong> <var>saniye</var> ]
        [ -<strong>T</strong> <var>içerik-türü</var> ]
        [ -<strong>u</strong> <var>PUT-dosyası</var> ]
        [ -<strong>v</strong> <var>ayrıntı-düzeyi</var>]
        [ -<strong>V</strong> ]
        [ -<strong>w</strong> ]
        [ -<strong>x</strong> <var>&lt;table&gt;-öznitelikleri</var> ]
        [ -<strong>X</strong> <var>vekil</var>[:<var>port</var>] ]
        [ -<strong>y</strong> <var>&lt;tr&gt;-öznitelikleri</var> ]
        [ -<strong>z</strong> <var>&lt;td&gt;-öznitelikleri</var> ]
        [ -<strong>Z</strong> <var>şifre-kümesi</var> ]
        [http[s]://]<var>konakadı</var>[:<var>port</var>]/<var>dizin</var>
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><strong>-A</strong>
          <var>yetkili-kullanıcı</var>:<var>parola</var></code></dt>
        <dd>Sunucuya TEMEL Kimlik Doğrulamada kullanılmak üzere kanıt sağlar.
          Kullanıcı adı ile parola arasına sadece <code>:</code> konur ve
          sunucunun buna ihtiyacı olup olmadığına bakılmaksızın (yani, bir "401
          kimlik doğrulaması gerekli" yanıtı beklenmeden) bağlantı üzerinden
          base64 kodlu olarak sunucuya gönderilir.</dd>
    
        <dt><code><strong>-b</strong> <var>tampon-boyu</var></code></dt>
        <dd>TCP gönderme/alma tamponlarının bayt cinsinden uzunluğu.</dd>
    
        <dt><code><strong>-B</strong> <var>yerel-adres</var></code></dt>
        <dd>Uzak bağlantılar yaparken dinlenecek adres.</dd>
    
        <dt><code><strong>-c</strong> <var>bağlantı-sayısı</var></code></dt>
        <dd>Aynı anda işleme sokulacak bağlantı sayısı. Aynı anda bir bağlantı
          öntanımlı değerdir.</dd>
    
        <dt><code><strong>-C</strong>
          <var>çerez-ismi</var>=<var>değer</var></code></dt>
        <dd>İsteğe bir <code>Cookie:</code> satırı ekler. Argüman olarak
          genellikle bir <code><var>isim=değer</var></code> çifti kullanılır. Bu
          çiftler birden fazla olabilir.</dd>
    
        <dt><code><strong>-d</strong></code></dt>
        <dd>"percentage served within XX [ms] table" iletisi gösterilmez. (Geriye
          uyumluluk için vardır).</dd>
    
        <dt><code><strong>-e</strong> <var>csv-dosyası</var></code></dt>
        <dd>Sunulan isteğin birim zamanda (milisaniye) ne kadarının (yüzde
          cinsinden) sunulduğunu gösteren virgül ayraçlı değerler (CSV) dosyası.
          Sonuçlar 'bobin haline' getirilmiş olduğundan doğal olarak 'gnuplot'
          dosyasından daha yararlıdır.</dd>
    
        <dt><code>-E <var>istemci-sertifikası-dosyası</var></code></dt>
        <dd>Bir SSL sitesine bağlanırken, sunucu ile kimlik doğrulaması için
          PEM biçeminde sağlanan sertifika kullanılır. Dosyanın sırayla istemci 
          sertifikasını, ara sertifikaları ve özel anahtarı içermesi beklenir. 
          2.4.36 ve sonrasında kullanılabilir.</dd>
    
        <dt><code><strong>-f</strong> <var>protokol</var></code></dt>
        <dd>SSL/TLS protokolü belirtilir (SSL2, SSL3, TLS1, TLS1.1, TLS1.2 veya
          ALL). TLS1.1 ve TLS1.2 desteği 2.4.4 ve sonraki sürümler
          içindir.</dd>
    
        <dt><code><strong>-g</strong> <var>gnuplot-dosyası</var></code></dt>
        <dd>Ölçülen değerler bir 'gnuplot' veya TSV (sekme ayraçlı değerler)
          dosyasına yazılır. Bu dosya, Gnuplot, IDL, Mathematica, Igor hatta
          Excel tarafından veri dosyası olarak kabul edilir. Veri sütunlarının
          başlıkları dosyanın ilk satırında bulunur. </dd>
    
        <dt><code><strong>-h</strong></code></dt>
        <dd>Kullanım bilgisi gösterir.</dd>
    
        <dt><code><strong>-H</strong> <var>özel-başlık</var></code></dt>
        <dd>İsteğe fazladan başlık ekler. <var>özel-başlık</var>, aralarında iki
          nokta imi bulunan bir isim-değer çifti olarak belirtilir. Örnek:
          <code>"Accept-Encoding: zip/zop;8bit"</code></dd>
    
        <dt><code><strong>-i</strong></code></dt>
        <dd><code>GET</code> istekleri yerine <code>HEAD</code> istekleri
          yapılır.</dd>
    
        <dt><code><strong>-k</strong></code></dt>
        <dd>HTTP KeepAlive (kalıcı bağlantı) özelliğini etkinleştirir, yani tek
          bir oturum içinde çok sayıda isteğe hizmet sunulabilir. Özellik
          öntanımlı olarak kapalıdır.</dd>
    
        <dt><code><strong>-l</strong></code></dt>
        <dd>Yanıtarın uzunluğu sabit değilse hataları raporlamaz. Özdevinimli
          sayfalarda kullanışlı olabilir. 2.4.7 ve sonraki sürümler
          içindir.</dd>
    
        <dt><code><strong>-m</strong> <var>HTTP-yöntemi</var></code></dt>
        <dd>İstekler için özel HTTP yöntemi, belirtilir.
        2.4.10 ve sonraki sürümler içindir.</dd>
    
        <dt><code><strong>-n</strong> <var>istek-sayısı</var></code></dt>
        <dd>Kıyaslama oturumu sırasında sunucuya uygulanacak istek sayısı.
          Öntanımlı olarak hiçbir başarım ölçütü sağlamayan tek bir istek
          yapılır.</dd>
    
        <dt><code><strong>-p</strong> <var>POST-dosyası</var></code></dt>
        <dd>POST isteği ile ilgili verileri içeren dosya. Ayrıca
          <code><strong>-T</strong></code> seçeneğini de belirtmeyi
          unutmayın..</dd>
    
        <dt><code><strong>-P</strong>
          <var>vekil-yetkilisi</var>:<var>parola</var></code></dt>
        <dd>Vekil sunucuya TEMEL Kimlik Doğrulamasında kullanılacak kanıtları
          sağlar. Kullanıcı adı ile parola arasına sadece <code>:</code> konur ve
          vekilin buna ihtiyacı olup olmadığına bakılmaksızın (yani, bir "407
          vekilde kimlik doğrulaması gerekiyor" yanıtı beklenmeden) bağlantı
          üzerinden base64 kodlu olarak sunucuya gönderilir.</dd>
    
        <dt><code><strong>-q</strong></code></dt>
        <dd>İstek sayısı 150'den fazla olduğunda,
          <code><strong>ab</strong></code> her 100 veya %10 istekte bir, standart
          hataya bir işlenen istek sayacı çıktılar.
          <code><strong>-q</strong></code> seçeneği bu çıktının üretilmemesini
          sağlar.</dd>
    
        <dt><code><strong>-r</strong></code></dt>
        <dd>Soket hata alsa bile program çıkmaz.</dd>
    
        <dt><code><strong>-s</strong> <var>zamanasimi</var></code></dt>
        <dd>Soket zaman aşımına uğramadan önce beklenecek azami saniye sayısı.
          30 saniye öntanımlı süredir.
          2.4.4 ve sonraki sürümler içindir.</dd>
    
        <dt><code><strong>-S</strong></code></dt>
        <dd>Ortalama ve ortanca değerler arasında bir veya iki standart sapmadan
          fazlası varsa ne ortalama değer ne standart sapma değeri ne de
          uyarı/hata iletileri gösterilir. Öntanımlı olarak,
          asgari/ortalama/azami değerler gösterilir. (Geriye uyumluluk).</dd>
    
        <dt><code><strong>-t</strong> <var>saniye</var></code></dt>
        <dd>Ölçümleme işleminin ne kadar süreyle uygulanacağı belirtilir. Dahili
          olarak <code><strong>-n 50000</strong></code> seçeneği uygulanır. Bunu
          belli bir süreye göre kıyaslama yapmak amacıyla kullanabilirsiniz.
          Öntanımlı olarak bir süre kısıtlaması yoktur.</dd>
    
        <dt><code><strong>-T</strong> <var>içerik-türü</var></code></dt>
        <dd>POST/PUT verisi için kullanılacak içerik türü belirtilir. Örnek:
          <code>application/x-www-form-urlencoded</code>.
          Öntanımlı değer: <code>text/plain</code>.</dd>
    
        <dt><code><strong>-v</strong> <var>ayrıntı-düzeyi</var></code></dt>
        <dd>Çıktının ayrıntı düzeyi belirtilir.  <code>4</code> ve üstü ile
          başlıklar hakkında bilgi, <code>3</code> ve üstü ile yanıt kodları
          (404, 200, vb.), <code>2</code> ve üstü ile ise uyarı ve bilgi
          iletileri gösterilir.</dd>
    
        <dt><code>-u <var>PUT-dosyası</var></code></dt>
        <dd>PUT verisini içeren dosya.  Ayrıca, <code>-T</code> seçeneğini
          belirtmeyi de unutmayın.</dd>
    
        <dt><code><strong>-V</strong></code></dt>
        <dd>Sürüm bilgilerini gösterir ve çıkar.</dd>
    
        <dt><code><strong>-w</strong></code></dt>
        <dd>Sonuçları HTML tabloları olarak basar. Öntanımlı tablo, beyaz
          artalanlı ve iki sütunludur.</dd>
    
        <dt><code><strong>-x</strong>
          <var>&lt;table&gt;-öznitelikleri</var></code></dt>
        <dd><code>&lt;table&gt;</code> etiketinde kullanılacak öznitelikler
          belirtilir. Belirtilen öznitelikler etiket içine <code>&lt;table
          <var>buraya</var> &gt;</code> biçeminde yerleştirilir.</dd>
    
        <dt><code><strong>-X</strong>
          <var>vekil</var>[:<var>port</var>]</code></dt>
        <dd>İstekler için bir vekil sunucu kullanılır.</dd>
    
        <dt><code><strong>-y</strong>
          <var>&lt;tr&gt;-öznitelikleri</var></code></dt>
        <dd><code>&lt;tr&gt;</code> etiketinde kullanılacak öznitelikler
          belirtilir.</dd>
    
        <dt><code><strong>-z</strong>
          <var>&lt;td&gt;-öznitelikleri</var></code></dt>
        <dd><code>&lt;td&gt;</code> etiketinde kullanılacak öznitelikler
          belirtilir.</dd>
    
        <dt><code>-Z <var>şifre-kümesi</var></code></dt>
        <dd>SSL/TLS şifre kümesi belirtilir
          (<code><strong>openssl</strong></code>(1) şifrelerine bakınız).</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="output" id="output">Çıktı</a></h2>
        <p>Aşağıda <code><strong>ab</strong></code> tarafından döndürülen değerler
          açıklanmıştır:</p>
    
        <dl>
            <dt>Server Software</dt>
            <dd>İlk başarılı yanıtın, varsa, <var>server</var> HTTP başlığında
              döndürülen değer. Bu başlıktaki başlangıçtan 32 ondalık değerli
              karaktere (genellikle boşluk veya CR/LF karakteri) kadar tüm
              karakterleri içerir.</dd>
    
            <dt>Server Hostname</dt>
            <dd>Komut satırında belirtilen DNS veya IP adresi.</dd>
    
            <dt>Server Port</dt>
            <dd><code><strong>ab</strong></code>'nin bağlandığı port. Komut
              satırında port belirtilmemişse, öntanımlı olarak http için 80, https
              için 443'tür.</dd>
    
            <dt>SSL/TLS Protocol</dt>
            <dd>İstemci le sunucu arasında uzlaşılmış protokol değerleri. Bu sadece
              SSL kullanılıyorsa çıktılanır.</dd>
    
            <dt>Document Path</dt>
            <dd>Komut satırı dizgesinden çözümlenen isteğin URI'si.</dd>
    
            <dt>Document Length</dt>
            <dd>Başarıyla döndürülen ilk belgenin bayt cinsinden uzunluğu. Eğer
              belge uzunluğu sınama sırasında değişirse yanıt bir hata
              içerecektir.</dd>
    
            <dt>Concurrency Level</dt>
            <dd>Sınama sırasında kullanılan eşzamanlı istemcilerin sayısı.</dd>
    
            <dt>Time taken for tests</dt>
            <dd>İlk soket bağlantısının alındığı andan son yanıtın alındığı ana
              kadar geçen süre.</dd>
    
            <dt>Complete requests</dt>
            <dd>Alınan başarılı yanıtların sayısı.</dd>
    
            <dt>Failed requests</dt>
            <dd>Başarısızlık olarak addedilen isteklerin sayısı. Sayı sıfırdan
              büyükse, diğer satırda,  bağlanma, okuma, yanlış içerik uzunluğu,
              istisnalar gibi sebeplerle başarısız olmuş istekler gösterilir.</dd>
    
            <dt>Write errors</dt>
            <dd>Başarısız yazma hatalarının (kırık boru) sayısı.</dd>
    
            <dt>Non-2xx responses</dt>
            <dd>200 serisi yanıt kodları ile açıklanamayan yanıtların sayısı. Tüm
              yanıtlar 200 olursa bu alan çıktılanmaz.</dd>
    
            <dt>Keep-Alive requests</dt>
            <dd>Keep-Alive isteklerinde sonuçlanan bağlantı sayısı.</dd>
    
            <dt>Total body sent</dt>
            <dd>Sınamanın parçası olarak veri gönderimi yapılandırılmışsa, bu
              sınama sırasında gönderilen toplam bayt sayısıdır. Sınama sırasında
              gövde gönderilmiyorsa bu alan çıktılanmaz.</dd>
    
            <dt>Total transferred</dt>
            <dd>Sunucudan alınan toplam bayt sayısı. Bu sayı aslında hattan
              gönderilen bayt sayısıdır.</dd>
    
            <dt>HTML transferred</dt>
            <dd>Sunucudan alınan belge baytlarının sayısı. Bu sayı HTTP
              başlıklarının bayt sayısını içermez.</dd>
    
            <dt>Requests per second</dt>
            <dd>Saniyedeki istek sayısı. İstek sayısının toplam süreye
              oranıdır.</dd>
    
            <dt>Time per request</dt>
            <dd>İstek başına harcanan süre. İlk değer <code>eşzamanlılık * süre *
              1000 / biten</code> formülüyle hesaplanırken ikincisi için
              <code>süre * 1000 / biten</code> formülü kullanılır.</dd>
    
            <dt>Transfer rate</dt>
            <dd><code>okunantoplam / 1024 / süre</code> formülüyle hesaplanan
              aktarım hızı.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Börtü böcek</a></h2>
        <p>Duruk bildirimli sabit uzunlukta çeşitli tamponlar vardır.
          Sunucudan gelen yanıt başlıkları ve diğer harici girdiler, komut satırı
          argümanları ile birlikte basitçe çözümlenir, bu size can sıkıcı
          gelebilir.</p>
    
        <p>HTTP/1.x protokolünü tamamen gerçeklemez; sadece yanıtların 'belli
          başlı' bazı biçimlerini kabul eder. Aksi takdirde,
          <code><strong>strstr</strong></code>(3) işlevinin yoğun kullanımı
          nedeniyle sunucu yerine <code><strong>ab</strong></code>'nin başarımını
          ölçerdiniz.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/ab.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/ab.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������httpd-2.4.64/docs/manual/programs/apxs.html.tr.utf8�������������������������������������������������0000664�0001751�0001751�00000053524�14743132254�022051� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apxs - Apache Eklenti Aracı - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>apxs - Apache Eklenti Aracı</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/apxs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code><strong>apxs</strong></code>, Apache Hiper Metin Aktarım
         Protokolü (HTTP) sunucusu için ek modül derleme ve kurulum aracıdır. Bu
         araç sayesinde, bir veya daha fazla kaynak veya nesne
         <var>dosya</var>sından bir devingen paylaşımlı nesne (DSO - "Dynamic
         Shared Object" kısaltması) derlemek ve bu nesneyi (modülü) Apache
         sunucusuna çalışma anında <strong><code class="module"><a href="../mod/mod_so.html">mod_so</a></code></strong>
         modülünün <strong><code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code></strong> yönergesi üzerinden yüklemek mümkün
         olmaktadır.</p>
    
        <p>Bu eklenti mekanizmasını platformunuzda kullanmak için DSO desteğinin
         olması ve <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong> programının
         <strong><code class="module"><a href="../mod/mod_so.html">mod_so</a></code></strong> modülünü içerecek şekilde
         derlenmiş olması gerekir. Eğer bunlar mevcut değilse
         <strong><code>apxs</code></strong> aracı durumu size bildirecektir. Bunu
         aşağıdaki komutla kendiniz de sınayabilirsiniz:</p>
    
        <div class="example"><p><code>
          $ httpd -l
        </code></p></div>
    
        <p><strong><code class="module"><a href="../mod/mod_so.html">mod_so</a></code></strong> modülü gösterilen listede yer
         almalıdır. Bu gereksinimler sağlandığı takdirde
         <strong><code>apxs</code></strong> aracı sayesinde DSO mekanizması
         üzerinden kendi modüllerinizi kurmak suretiyle Apache sunucunuzun
         işlevselliğini kolayca arttırabilirsiniz. Örnek bir uygulama:</p>
    
        <div class="example"><p><code>
          $ apxs -i -a -c mod_foo.c<br />
          gcc -fpic -DSHARED_MODULE -I/dosya/yolu/apache/include -c mod_foo.c<br />
          ld -Bshareable -o mod_foo.so mod_foo.o<br />
          cp mod_foo.so /dosya/yolu/apache/modules/mod_foo.so<br />
          chmod 755 /dosya/yolu/apache/modules/mod_foo.so<br />
          [`foo' modülü /dosya/yolu/apache/etc/httpd.conf'ta etkinleştiriliyor]<br />
          $ apachectl restart<br />
          /dosya/yolu/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /dosya/yolu/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
        <p><var>dosya</var> olarak bir C kaynak dosyası (.c), bir nesne dosyası
         (.o) ve hatta bir kütüphane arşivi archive (.a) belirtebilirsiniz.
         <strong><code>apxs</code></strong> aracı bu dosya uzantılarını
         tanıdığından C dosyalarını derleme işleminden, arşiv ve nesne
         dosyalarını ise doğrudan ilintileme işleminden geçirir. Fakat böyle
         önceden derlenmiş nesne dosyalarını kullanırken, devingen paylaşımlı
         nesne olarak kullanılmalarını sağlamak üzere konumdan bağımsız kod (PIC)
         üretecek şekilde derlenmiş olduklarından emin olmalısınız. Örneğin
         GCC'yi bunun için daima <strong><code>-fpic</code></strong> seçeneği ile
         kullanmalısınız. Diğer C derleyiciler için,
         <strong><code>apxs</code></strong>'in nesne dosyalarını derlerken
         kullanacağı seçenekleri öğrenmek için o derleyicilerin kılavuz
         sayfalarına bakınız.</p>
    
        <p>Apache'deki DSO desteği ile ilgili daha ayrıntılı bilgi edinmek için
         <strong><code class="module"><a href="../mod/mod_so.html">mod_so</a></code></strong> belgesini okumakla yetinmeyip
         <code>src/modules/standard/mod_so.c</code> kaynak dosyasını da
         okuyunuz.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Örnekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></li><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>apxs</strong> -<strong>g</strong>
        [ -<strong>S</strong> <var>isim=değer</var> ]
        -<strong>n</strong> <var>modüladı</var></code></p>
    
        <p><code><strong>apxs</strong> -<strong>q</strong>
        [ -<strong>v</strong> ]
        [ -<strong>S</strong> <var>isim=değer</var> ]
        <var>sorgu</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>c</strong>
        [ -<strong>S</strong> <var>isim=değer</var> ]
        [ -<strong>o</strong> <var>dso-dosyası</var> ]
        [ -<strong>I</strong> <var>include-dizini</var> ]
        [ -<strong>D</strong> <var>isim=değer</var> ]
        [ -<strong>L</strong> <var>lib-dizini</var> ]
        [ -<strong>l</strong> <var>kütüphane-adı</var> ]
        [ -<strong>Wc,</strong><var>derleyici-seçenekleri</var> ]
        [ -<strong>Wl,</strong><var>ilintileyici-seçenekleri</var> ]
        [ -<strong>p</strong> ]
        <var>dosya</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>i</strong>
        [ -<strong>S</strong> <var>isim=değer</var> ]
        [ -<strong>n</strong> <var>modüladı</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>dso-dosyası</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>e</strong>
        [ -<strong>S</strong> <var>isim=değer</var> ]
        [ -<strong>n</strong> <var>modüladı</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>dso-dosyası</var> ...</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <h3><a name="options.common" id="options.common">Ortak Seçenekler</a></h3>
          <dl>
            <dt><code><strong>-n</strong> <var>modüladı</var></code></dt>
            <dd><code><strong>-i</strong></code> (kurulum) ve
             <code><strong>-g</strong></code> (şablon üretimi)
             seçenekleri için modül ismi belirtmek amacıyla kullanılır. Bir modül
             ismi belirtmek için bu seçeneği kullanın.
             <code><strong>-g</strong></code> seçeneği için bu gereklidir.
             <code><strong>-i</strong></code> seçeneği için ise araç, modül
             ismini kaynağın ismine bakarak veya (son çare olarak) dosya isminden
             tahmin etmeye çalışarak saptamaya çalışır.</dd>
          </dl>
        
    
        <h3><a name="options.query" id="options.query">Sorgu Seçenekleri</a></h3>
          <dl>
            <dt><code><strong>-q</strong> <var>sorgu</var></code></dt>
            <dd><code>httpd</code>'yi derlemekte kullanılacak değişkenler ve
             ortam ayarları için bir sorgu gerçekleştirir.  When invoked without
             <code><var>sorgu</var></code> belirtilmeksizin çağrıldığında, bilinen
             değişkenleri değerleriyle birlikte basar. İsteğe bağlı
             <code><strong>-v</strong></code> seçeneği liste çıktısını biçemler.
    
             <p>Modülünüzü yükleyecek <code><strong>httpd</strong></code>'yi
              derlemek için kullanılacak ayarları elle belirtmek için kullanılır.
              Örneğin, Apache'nin C başlık dosyalarının yerini kendi Makefile
              dosyalarınızın içinde şöyle belirtebilirsiniz:</p>
            <div class="example"><p><code>
              INC=-I`apxs -q INCLUDEDIR`
            </code></p></div></dd>
          </dl>
        
    
        <h3><a name="options.conf" id="options.conf">Yapılandırma Seçenekleri</a></h3>
          <dl>
          <dt><code><strong>-S</strong> <var>isim=değer</var></code></dt>
          <dd>Bu seçenek yukarıda açıklanan <code><strong>apxs</strong></code>
            ayarlarını değiştirir.</dd>
          </dl>
        
    
        <h3><a name="options.template" id="options.template">Şablon Üretme Seçenekleri</a></h3>
          <dl>
          <dt><code><strong>-g</strong></code></dt>
          <dd><code><var>modüladı</var></code> (<strong><code>-n</code></strong>
           seçeneğine bakınız) adında bir alt dizin oluşturur ve içine iki dosya
           yerleştirir: Kendi modülünüzü oluşturabilmeniz için veya
           <code><strong>apxs</strong></code> mekanizmaları ile hemen oynamaya
           başlayabilmeniz için <code>mod_<var>modüladı</var>.c</code> adında bir
           modül kaynak dosyası örneği ve bu modülü derleyip kurmayı
           kolaylaştırmak için bir <code>Makefile</code> dosyası.</dd>
          </dl>
        
    
        <h3><a name="options.dso" id="options.dso">DSO Derleme Seçenekleri</a></h3>
          <dl>
          <dt><code><strong>-c</strong></code></dt>
          <dd>Bu seçenek derleme yapılacağını belirtir. Önce belirtilen C kaynak
           <var>dosyalar</var>ını (.c), nesne dosyalarını (.o) elde etmek için
           derler. Sonra bunları kalan nesne dosyaları (.o ve .a) ile
           ilintileyerek <var>dso-dosyası</var> adında bir devingen paylaşımlı
           nesne oluşturur. Eğer <strong><code>-o</code></strong> seçeneği ile
           modül ismi belirtilmemişse <var>dosyalar</var> arasındaki ilk dosyanın
           ismine bakarak dosya ismi tahmin edilmeye çalışılır ve
           <code>mod_<var>isim</var>.so</code> dosya adı bu isimden elde
           edilir.</dd>
    
          <dt><code><strong>-o</strong> <var>dso-dosyası</var></code></dt>
          <dd>Oluşturulacak devingen paylaşımlı nesnenin ismini belirtmek için
           kullanılır. Modül ismi bu seçenekle belirtilmez ve <var>dosya</var>
           listesinden bir isim tahmini de yapılamazsa son çare olarak
           <code>mod_unknown.so</code> ismi kullanılır.</dd>
    
          <dt><code><strong>-D</strong> <var>isim=değer</var></code></dt>
          <dd>Bu seçenek doğrudan derleme komutlarına aktarılır. Bu seçeneği
           derleme işlemine kendi tanımlarınızı belirtmek için kullanın.</dd>
    
          <dt><code><strong>-I</strong> <var>include-dizini</var></code></dt>
          <dd>Bu seçenek doğrudan derleme komutlarına aktarılır. Bu seçeneği
           derleme işleminde kullanılmak üzere kendi başlık dosyalarınızı içeren
           dizinleri arama yollarına eklemek için kullanın.</dd>
    
          <dt><code><strong>-L</strong> <var>lib-dizini</var></code></dt>
          <dd>Bu seçenek doğrudan derleme komutlarına aktarılır. Bu seçeneği
           derleme işleminde kullanılmak üzere kendi kütüphane dizinlerinizi
           arama yollarına eklemek için kullanın.</dd>
    
          <dt><code><strong>-l</strong> <var>kütüphane-adı</var></code></dt>
          <dd>Bu seçenek doğrudan derleme komutlarına aktarılır. Bu seçeneği
           derleme işleminde kullanılmak üzere kendi kütüphanelerinizi arama
           yollarına eklemek için kullanın.</dd>
    
          <dt><code><strong>-Wc</strong>,<var>derleyici-seçenekleri</var></code></dt>
          <dd>Bu seçenek <code>libtool --mode=compile</code> komutuna doğrudan
           seçenek aktarmak için kullanılır. Bu seçeneği yerel derleyiciniz için
           gereken ek seçenekleri belirtmek için kullanın.</dd>
    
          <dt><code><strong>-Wl</strong>,<var>ilintileyici-seçenekleri</var></code></dt>
          <dd>Bu seçenek <code>libtool --mode=link</code> komutuna doğrudan
           seçenek aktarmak için kullanılır. Bu seçeneği yerel ilintileyiciniz
           için gereken ek seçenekleri belirtmek için kullanın.</dd>
    
         <dt><code><strong>-p</strong></code></dt>
         <dd>Bu seçenek apxs'in apr/apr-util kütüphaneleriyle ilintilenmesini
           sağlar. apr/apr-util kütüphanelerini kullanan yardımcı uygulamaları
           derlerken yararlıdır.</dd>
          </dl>
        
    
        <h3><a name="options.dsoinstall" id="options.dsoinstall">DSO Kurulum ve Yapılandırma Seçenekleri</a></h3>
        
          <dl>
          <dt><code><strong>-i</strong></code></dt>
          <dd>Kurulum işlemini belirtir ve devingen olarak paylaşımlı nesneleri
           sunucunun <var>modules</var> dizinine kurar.</dd>
    
          <dt><code><strong>-a</strong></code></dt>
          <dd>İlgili <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> satırını
           Apache'nin <code>httpd.conf</code> yapılandırma dosyasına özdevinimli
           olarak ekleyerek veya böyle bir satır varsa bunu etkin kılarak modülü
           etkinleştirir.</dd>
    
          <dt><code><strong>-A</strong></code></dt>
          <dd><strong><code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code></strong>
           yönergesini daha sonra etkinleştirmek üzere satırın başına bir diyez
           imi (<code>#</code>) yerleştirmesi dışında
           <strong><code>-a</code></strong> seçeneği ile aynıdır.</dd>
    
          <dt><code><strong>-e</strong></code></dt>
          <dd>Modülü kurmaya çalışmaksızın Apache'nin <code>httpd.conf</code>
           yapılandırma dosyasını <strong><code>-i</code></strong> işlemine
           benzer şekilde <strong><code>-a</code></strong> ve
           <strong><code>-A</code></strong> seçenekleri ile düzenleme işlemini
           belirtir.</dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Örnekler</a></h2>
        <p>Apache'nin sunucu işlevselliğini genişletmek amacıyla kullanacağınız
         <code>mod_foo.c</code> adında bir Apache modülünüz olduğunu varsayalım.
         Öncelikle, C kaynak dosyasını, Apache sunucusuna çalışma anında
         yüklenmeye uygun bir paylaşımlı nesne olarak derlemeniz gerekir. Bunu
         sağlamak için şu komutları vermelisiniz:</p>
    
        <div class="example"><p><code>
          $ apxs -c mod_foo.c<br />
          /dosya/yolu/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /dosya/yolu/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          $ _
        </code></p></div>
    
        <p>Bundan sonra, Apache yapılandırmanızın bu paylaşımlı nesneyi yüklemek
         için bir <strong><code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code></strong> yönergesi içermesini
         sağlamalısınız. <strong><code>apxs</code></strong> bu adımı
         basitleştirmek amacıyla, paylaşımlı nesneyi sunucunun <var>modules</var>
         dizinine özdevinimli olarak kurmak ve <code>httpd.conf</code> dosyasını
         buna uygun olarak güncellemek için bir yol sağlar. Bu sonuç şöyle elde
         edilebilir:</p>
    
        <div class="example"><p><code>
          $ apxs -i -a mod_foo.la<br />
          /dosya/yolu/instdso.sh mod_foo.la /path/to/apache/modules<br />
          /dosya/yolu/libtool --mode=install cp mod_foo.la /dosya/yolu/apache/modules
          ...
          chmod 755 /dosya/yolu/apache/modules/mod_foo.so<br />
          [`foo' modülü /dosya/yolu/apache/conf/httpd.conf'da etkinleştiriliyor] <br />
          $ _
        </code></p></div>
    
        <p>Yapılandıma dosyasına (eğer yoksa) şu satır eklenir:</p>
    
        <div class="example"><p><code>
          LoadModule foo_module modules/mod_foo.so
        </code></p></div>
    
        <p>Bunu öntanımlı olarak iptal etmek isterseniz
         <strong><code>-A</code></strong> seçeneğini kullanmanız gerekir:</p>
    
        <div class="example"><p><code>
          $ apxs -i -A mod_foo.c
        </code></p></div>
    
        <p><strong><code>apxs</code></strong> mekanizmalarını hızlıca denemek
         için örnek bir Apache modül şablonunu ve bir Makefile dosyasını şöyle
         oluşturabilirsiniz:</p>
    
        <div class="example"><p><code>
          $ apxs -g -n foo<br />
          Creating [DIR]  foo<br />
          Creating [FILE] foo/Makefile<br />
          Creating [FILE] foo/modules.mk<br />
          Creating [FILE] foo/mod_foo.c<br />
          Creating [FILE] foo/.deps<br />
          $ _
        </code></p></div>
    
        <p>Ardından bu örnek modülü bir paylaşımlı nesne olarak derleyip Apache
         sunucusuna yükleyebilirsiniz:</p>
    
        <div class="example"><p><code>
          $ cd foo<br />
          $ make all reload<br />
          apxs -c mod_foo.c<br />
          /dosya/yolu/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /dosya/yolu/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          apxs -i -a -n "foo" mod_foo.la<br />
          /dosya/yolu/instdso.sh mod_foo.la /dosya/yolu/apache/modules<br />
          /dosya/yolu/libtool --mode=install cp mod_foo.la /dosya/yolu/apache/modules
          ...
           chmod 755 /dosya/yolu/apache/modules/mod_foo.so<br />
          [`foo' modülü /dosya/yolu/apache/conf/httpd.conf'ta etkinleştiriliyor]<br />
           apachectl restart<br />
           /dosya/yolu/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          chmod 755 /dosya/yolu/apache/modules/mod_foo.so<br />
          [`foo' modülü /dosya/yolu/apache/etc/httpd.conf'ta etkinleştiriliyor]<br />
          apachectl restart<br />
          /dosya/yolu/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /dosya/yolu/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/apxs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apxs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apxs.html.ko.euc-kr�����������������������������������������������0000664�0001751�0001751�00000043043�14743132254�022330� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apxs - APache eXtenSion  - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>apxs - APache eXtenSion </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/apxs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><code>apxs</code> ġ ؽƮ  
        (HTTP)  Ȯ ϰ ġϴ ̴. 
          ҽ Ʈ<var></var> ,
        <code class="module"><a href="../mod/mod_so.html">mod_so</a></code> <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> þ ߿
        ġ  о  ִ ü(DSO) .</p>
    
        <p>׷ ̷ Ȯ Ϸ ÷ DSO 
        ϰ ġ <code>httpd</code> 
        <code class="module"><a href="../mod/mod_so.html">mod_so</a></code>   ؾ Ѵ.
        <code>apxs</code>     
        ʴ´.  ɾ Ͽ  ϴ ˾ƺ
         ִ</p>
    
        <div class="example"><p><code>
          $ httpd -l
        </code></p></div>
    
        <p>Ͽ <code class="module"><a href="../mod/mod_so.html">mod_so</a></code>  ; Ѵ. 
        ϸ <code>apxs</code>  DSO  ġϿ
        ġ   Ȯ  ִ:</p>
    
        <div class="example"><p><code>
          $ apxs -i -a -c mod_foo.c<br />
          gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c<br />
          ld -Bshareable -o mod_foo.so mod_foo.o<br />
          cp mod_foo.so /path/to/apache/modules/mod_foo.so<br />
          chmod 755 /path/to/apache/modules/mod_foo.so<br />
          [activating module `foo' in /path/to/apache/etc/httpd.conf]<br />
          $ apachectl restart<br />
          /path/to/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /path/to/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
        <p>ƱԸƮ <var>files</var> C ҽ (.c) ̳
        Ʈ (.o), ̺귯 (.a)   ִ.
        <code>apxs</code>  Ȯڸ  ڵ C ҽ
        ϰ, Ʈ  ũ Ѵ. ׷
         Ʈ Ϸ  о  ִ
        ü ϱ ݵ Ʈ ġڵ(PIC,
        position independent code) ؾ Ѵ. GCC 
        <code>-fpic</code> ϸ ȴ. ٸ C Ϸ 
        ϰų <code>apxs</code> Ʈ Ҷ
        ϴ ɼ ϶.</p>
    
        <p>ġ DSO    ڼ 
        <code class="module"><a href="../mod/mod_so.html">mod_so</a></code>  ϰų
        <code>src/modules/standard/mod_so.c</code> ҽ о.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="apachectl.html">apachectl</a></li><li><a href="httpd.html">httpd</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
        <p><code><strong>apxs</strong> -<strong>g</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        -<strong>n</strong> <var>modname</var></code></p>
    
        <p><code><strong>apxs</strong> -<strong>q</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        <var>query</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>c</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>o</strong> <var>dsofile</var> ]
        [ -<strong>I</strong> <var>incdir</var> ]
        [ -<strong>D</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>L</strong> <var>libdir</var> ]
        [ -<strong>l</strong> <var>libname</var> ]
        [ -<strong>Wc,</strong><var>compiler-flags</var> ]
        [ -<strong>Wl,</strong><var>linker-flags</var> ]
        <var>files</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>i</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>n</strong> <var>modname</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>dso-file</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>e</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>n</strong> <var>modname</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>dso-file</var> ...</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
        <h3><a name="options.common" id="options.common"> ɼ</a></h3>
          <dl>
          <dt><code>-n <var>modname</var></code></dt>
          <dd><code>-i</code> (install) <code>-g</code> (template
          generation) ɼ Ҷ   Ѵ. 
          ɼ Ͽ   Ѵ. <code>-g</code>
          ɼ Ѵٸ  ɼ ݵ ؾϰ,
          <code>-i</code> ɼ Ѵٸ <code>apxs</code> 
          ҽ ( õ) ϸ  ̸ Ѵ.</dd>
          </dl>
        
    
        <h3><a name="options.query" id="options.query"> ɼ</a></h3>
          <dl>
          <dt><code>-q</code></dt>
          <dd><code>apxs</code>  ˾Ƴ. <var>query</var>
             ִ: <code>CC</code>, <code>CFLAGS</code>,
          <code>CFLAGS_SHLIB</code>, <code>INCLUDEDIR</code>,
          <code>LD_SHLIB</code>, <code>LDFLAGS_SHLIB</code>,
          <code>LIBEXECDIR</code>, <code>LIBS_SHLIB</code>,
          <code>SBINDIR</code>, <code>SYSCONFDIR</code>, <code>TARGET</code>.
    
          <p>  ˾Ƴ Ѵ.</p>
          <div class="example"><p><code>
            INC=-I`apxs -q INCLUDEDIR`
          </code></p></div>
    
          <p> , ġ C   Ѵٸ
          Makefile   Ѵ.</p></dd>
          </dl>
        
    
        <h3><a name="options.conf" id="options.conf"> ɼ</a></h3>
          <dl>
          <dt><code>-S <var>name</var>=<var>value</var></code></dt>
          <dd> ɼ   apxs  Ѵ.</dd>
          </dl>
        
    
        <h3><a name="options.template" id="options.template">ߺ(template)  ɼ</a></h3>
          <dl>
          <dt><code>-g</code></dt>
          <dd>丮 <var>name</var>  (<code>-n</code>
          ɼ ) װ  ΰ :  
          <code>mod_<var>name</var>.c</code> ߺ ҽϷ,
          ڽ  鶧 ߺ ϰų apxs 
          غ Ѵ. ٸ     ϰ
          ġϱ <code>Makefile</code>̴.</dd>
          </dl>
        
    
        <h3><a name="options.dso" id="options.dso">DSO  ɼ</a></h3>
          <dl>
          <dt><code>-c</code></dt>
          <dd> Ѵ.  <var>files</var> C
          ҽϵ(.c) Ʈ(.o) ϰ,
          <var>files</var>  Ʈϵ(.o .a)
          ũϿ ü <var>dsofile</var> .
          <code>-o</code> ɼ  <var>files</var>
          ù° ϸ ̸ Ͽ 
          <code>mod_<var>name</var>.so</code> Ѵ.</dd>
    
          <dt><code>-o <var>dsofile</var></code></dt>
          <dd> ü ϸ  Ѵ. ̸
          ʰ <var>files</var> Ͽ ̸ 
          ϸ  <code>mod_unknown.so</code> ̸
          Ѵ.</dd>
    
          <dt><code>-D <var>name</var>=<var>value</var></code></dt>
          <dd> ɼ  ɾ  Ѵ.
          ϶ ڽ define ߰Ѵ.</dd>
    
          <dt><code>-I <var>incdir</var></code></dt>
          <dd> ɼ  ɾ  Ѵ.
          ϶ include ã 丮 ߰Ѵ.</dd>
    
          <dt><code>-L <var>libdir</var></code></dt>
          <dd> ɼ Ŀ ɾ  Ѵ.
          ϶ ̺귯 ã 丮 ߰Ѵ.</dd>
    
          <dt><code>-l <var>libname</var></code></dt>
          <dd> ɼ Ŀ ɾ  Ѵ.
          ϶  ̺귯 ߰Ѵ.</dd>
    
          <dt><code>-Wc,<var>compiler-flags</var></code></dt>
          <dd> ɼ ߰ ɼ <var>compiler-flags</var>
          <code>libtool --mode=compile</code> ɾ Ѵ.
          Ϸ Ư ɼ ߰Ҷ Ѵ.</dd>
    
          <dt><code>-Wl,<var>linker-flags</var></code></dt>
          <dd> ɼ ߰ ɼ <var>linker-flags</var>
          <code>libtool --mode=link</code> ɾ Ѵ. Ŀ
          Ư ɼ ߰Ҷ Ѵ.</dd>
          </dl>
        
    
        <h3><a name="options.dsoinstall" id="options.dsoinstall">DSO ġ  ɼ</a></h3>
        
          <dl>
          <dt><code>-i</code></dt>
          <dd>ġ Ѵ.  ü 
          <var>modules</var> 丮 ġѴ.</dd>
    
          <dt><code>-a</code></dt>
          <dd>ġ <code>httpd.conf</code> Ͽ 
          <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> 
          ߰ϰų ̹ ִٸ ȰȭϿ  ϵ
          .</dd>
    
          <dt><code>-A</code></dt>
          <dd><code>-a</code> , <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> þ տ
          칰(<code>#</code>) δ. <em></em>, 
           ߿   ֵ  غѴ.</dd>
    
          <dt><code>-e</code></dt>
          <dd> Ѵ. <code>-a</code> Ȥ <code>-A</code>
          ɼǰ    , <code>-i</code> ɰ
            ġʰ ġ
          <code>httpd.conf</code> ϸ Ѵ.</dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples"></a></h2>
        <p>ġ  Ȯϴ <code>mod_foo.c</code>
        ġ  ִٰ .   ɾ Ͽ
        C ҽ ġ  о ü Ѵ:</p>
    
        <div class="example"><p><code>
          $ apxs -c mod_foo.c<br />
          /path/to/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          $ _
        </code></p></div>
    
        <p>׸  ü о̴ <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> þ ġ
         ߰Ѵ. <code>apxs</code> ڵ ü
        "modules" 丮 ġϰ <code>httpd.conf</code> 
        ˸° Ͽ  ۾ ģ.   Ѵ:</p>
    
        <div class="example"><p><code>
          $ apxs -i -a mod_foo.la<br />
          /path/to/instdso.sh mod_foo.la /path/to/apache/modules<br />
          /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules
          ...
          chmod 755 /path/to/apache/modules/mod_foo.so<br />
          [/path/to/apache/conf/httpd.conf `foo'  ȰȭѴ]<br />
          $ _
        </code></p></div>
    
        <p>׷   </p>
    
        <div class="example"><p><code>
          LoadModule foo_module modules/mod_foo.so
        </code></p></div>
    
        <p>Ͽ ٸ ߰Ѵ.   ⺻ 
        ʴ´ٸ <code>-A</code> ɼ Ѵ. <em></em></p>
    
        <div class="example"><p><code>
          $ apxs -i -A mod_foo.c
        </code></p></div>
    
        <p>apxs  Ϸ   ġ  ߺ
        Makefile   ִ:</p>
    
        <div class="example"><p><code>
          $ apxs -g -n foo<br />
          Creating [DIR]  foo<br />
          Creating [FILE] foo/Makefile<br />
          Creating [FILE] foo/modules.mk<br />
          Creating [FILE] foo/mod_foo.c<br />
          Creating [FILE] foo/.deps<br />
          $ _
        </code></p></div>
    
        <p>׷ ٷ ߺ  ü Ͽ ġ
         еѴ:</p>
    
        <div class="example"><p><code>
          $ cd foo<br />
          $ make all reload<br />
          apxs -c mod_foo.c<br />
          /path/to/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          apxs -i -a -n "foo" mod_foo.la<br />
          /path/to/instdso.sh mod_foo.la /path/to/apache/modules<br />
          /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules
          ...
          chmod 755 /path/to/apache/modules/mod_foo.so<br />
          [/path/to/apache/conf/httpd.conf `foo'  ȰȭѴ]<br />
          apachectl restart<br />
          /path/to/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /path/to/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/apxs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apxs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/httpd.html��������������������������������������������������������0000664�0001751�0001751�00000000566�13710016232�020674� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: httpd.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: httpd.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: httpd.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: httpd.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apachectl.html.ko.euc-kr������������������������������������������0000664�0001751�0001751�00000023430�14743132254�023277� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apachectl - ġ   ̽ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>apachectl - ġ   ̽</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/apachectl.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
         <p><code>apachectl</code> ġ ؽƮ 
          (HTTP)  մ̴.  α׷ ڰ
         ġ <a href="httpd.html">httpd</a>  ϵ
         ´.</p>
    
         <p><code>apachectl</code> ũƮ ΰ  Ѵ.
         ù°  <code>httpd</code> θ  ũƮ
          Ͽ, ʿ ȯ溯 ϰ   ƱԸƮ
          <code>httpd</code> Ѵ. ι° 
         <code>apachectl</code> SysV init ũƮ Ͽ,
         <code>start</code>, <code>restart</code>, <code>stop</code>
          Ѵܾ ƱԸƮ ޾Ƽ <code>httpd</code>
          ȣ .</p>
    
         <p>ġ Ϲ ο ġ ʾҴٸ, 
         <code>httpd</code> η <code>apachectl</code> ũƮ
         ؾ Ѵ. , <code>httpd</code>  ƱԸƮ
         ߰   ִ. ڼ  ũƮ ּ
         ϶.</p>
    
         <p><code>apachectl</code> ũƮ  ڵ 0,
          &gt;0 ȯѴ. ڼ  ũƮ ּ
         ϶.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="../invoking.html">ġ </a></li><li><a href="../stopping.html">ġ ߴ</a></li><li><a href="../configuring.html"></a></li><li><a href="../platform/">÷ </a></li><li><a href="httpd.html">httpd</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
    
    <p>  ũƮ ϸ, <code>apachectl</code>
    <a href="httpd.html">httpd</a>   ƱԸƮ ޴´.</p>
    
    <p><code><strong>apachectl</strong> [ <var>httpd-argument</var> ]</code></p>
    
    <p>SysV init  ϸ, <code>apachectl</code> Ʒ
      Ѵܾ ɾ ޴´.</p>
    
    <p><code><strong>apachectl</strong> <var>command</var></code></p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
    
    <p>⼭ SysV init- ɼǸ Ѵ. ٸ ɼ <a href="httpd.html">httpd</a> manpage Ѵ.</p>
    
    <dl>
    
    <dt><code>start</code></dt>
    
    <dd>ġ <code>httpd</code>  Ѵ. ̹ ̶
     . <code>apachectl -k start</code> .</dd>
    
    <dt><code>stop</code></dt>
    
    <dd>ġ <code>httpd</code>  ߴѴ. <code>apachectl
    -k stop</code> .</dd>
    
    <dt><code>restart</code></dt>
    
    <dd>ġ <code>httpd</code>  Ѵ.  
    ƴ϶, Ѵ.  ۽   Ȯϱ
      ڵ <code>configtest</code> ɰ  
    ˻Ѵ. <code>apachectl -k restart</code> .</dd>
    
    <dt><code>fullstatus</code></dt>
    
    <dd><code class="module"><a href="../mod/mod_status.html">mod_status</a></code>    Ѵ.
      ϱؼ  <code class="module"><a href="../mod/mod_status.html">mod_status</a></code>
    ϰ, ýۿ <code>lynx</code>  ڱ 
    ʿϴ.   ϴ URL ũƮ
    <code>STATUSURL</code>  Ͽ   ִ.</dd>
    
    <dt><code>status</code></dt>
    
    <dd>   Ѵ. <code>fullstatus</code> ɼǰ
    ,   û   ʴ´.</dd>
    
    <dt><code>graceful</code></dt>
    
    <dd>ġ <code>httpd</code>  ݰ(gracefully) Ѵ.
      ƴ϶, Ѵ. Ϲ ۰ ޸ 
    ִ  ʴ´. ,  α   ʴ´.
    , α׼ȯ ũƮ   Ѵٸ,  α
    óϱ α  ϱ  ٷ
    Ѵ. ġ ۽   Ȯϱ 
     ڵ <code>configtest</code> ɰ  
    ˻Ѵ. <code>apachectl -k graceful</code> .</dd>
    
    <dt><code>configtest</code></dt>
    
    <dd>  ˻Ѵ.  а <code>Syntax
    Ok</code> Ȥ Ư   ڼ  ˷ش.
    <code>apachectl -t</code> .</dd>
    
    </dl>
    
    <p>Ʒ ɼ   ,   ̴.</p>
    
    <dl>
    
    <dt><code>startssl</code></dt>
    
    <dd><code>apachectl -k start -DSSL</code> . 츮 
     ɾ ϰų ׻ SSL ϵ
    <code>httpd.conf</code> <code class="directive"><a href="../mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>  ϱ Ѵ.</dd>
    
    </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/apachectl.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apachectl.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apachectl.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apachectl.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apachectl.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/configure.html.ko.euc-kr������������������������������������������0000664�0001751�0001751�00000132673�14743132254�023346� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>configure - ҽ Ʈ Ѵ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>configure - ҽ Ʈ Ѵ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/configure.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><code>configure</code> ũƮ Ư ÷ ġ
         ϰ ġϱ ҽ Ʈ Ѵ. 
        ɼ Ͽ ϴ 䱸ǿ °   
        ִ.</p>
    
        <p>ҽ  ֻ 丮 ִ  ũƮ н
        н ýۿ Ѵ. ٸ ÷ Ѵٸ
        <a href="../platform/">÷</a>  ϶.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#env">ȯ溯</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="../install.html">ϰ ġ</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
        <p><code>configure</code> ũƮ  ֻ
        丮 ؾ Ѵ.</p>
    
        <p><code><strong>./configure</strong> [<var>OPTION</var>]...
        [<var>VAR</var>=<var>VALUE</var>]...</code></p>
    
        <p>ȯ溯 ( , <code>CC</code>, <code>CFLAGS</code>,
        ...) Ϸ, <code><var>VAR</var>=<var>VALUE</var></code>
         Ѵ. <a href="#env">Ʒ</a>  ȯ溯
        Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
      <ul>
        <li><a href="#configurationoptions"> ɼ</a></li>
        <li><a href="#installationdirectories">ġ 丮</a></li>
        <li><a href="#systemtypes">ý </a></li>
        <li><a href="#optionalfeatures"> </a></li>
        <li><a href="#supportopt"> α׷  ɼ</a></li>
      </ul>
    
      <h3><a name="configurationoptions" id="configurationoptions"> ɼ</a></h3>
    
        <p> ɼǵ <code>configure</code> ü ൿ 
        ش.</p>
    
        <dl>
          <dt><code>-C</code></dt>
          <dt><code>--config-cache</code></dt>
          <dd><code>--cache-file=config.cache</code> .</dd>
    
          <dt><code>--cache-file=<var>FILE</var></code></dt>
          <dd>˻  <var>FILE</var> Ͽ ijѴ.
            ⺻ ˻   ʴ´.</dd>
    
          <dt><code>-h</code></dt>
          <dt><code>--help [short|recursive]</code></dt>
          <dd> ϰ Ѵ. <code>short</code> ƱԸƮ
             Ű Ư ɼǸ Ѵ. <code>recursive</code>
            ƱԸƮ Ե  Ű  ª 
            ش.</dd>
    
          <dt><code>-n</code></dt>
          <dt><code>--no-create</code></dt>
          <dd><code>configure</code> ũƮ  ,
              ʴ´.  ɼ   makefile
              ˻  Ȯغ ϴ.</dd>
    
          <dt><code>-q</code></dt>
          <dt><code>--quiet</code></dt>
          <dd>߿ <code>checking ...</code>  
            ʴ´.</dd>
    
          <dt><code>--srcdir=<var>DIR</var></code></dt>
          <dd><var>DIR</var> 丮 ҽ 丮 Ѵ.
            ⺻ configure ִ 丮 Ȥ 丮
            <code>..</code>̴.</dd>
    
          <dt><code>--silent</code></dt>
          <dd><code>--quiet</code> .</dd>
    
          <dt>-V</dt>
          <dt>--version</dt>
          <dd>۱  ϰ Ѵ.</dd>
        </dl>
      
    
      <h3><a name="installationdirectories" id="installationdirectories">ġ 丮</a></h3>
    
        <p> ɼǵ ġ 丮 Ѵ. ġ ġ
           (layout)  ٸ.</p>
    
        <dl>
          <dt><code>--prefix=<var>PREFIX</var></code></dt>
          <dd>ŰĿ   <var>PREFIX</var> ġѴ.
            ⺻ <code>/usr/local/apache2</code>̴.</dd>
    
          <dt><code>--exec-prefix=<var>EPREFIX</var></code></dt>
          <dd>ŰĿ   <var>EPREFIX</var> ġѴ.
            ⺻ <var>PREFIX</var> 丮̴.</dd>
        </dl>
    
        <p>⺻ <code>make install</code>
          <code>/usr/local/apache2/bin</code>,
          <code>/usr/local/apache2/lib</code>  ġ 
           ġѴ. <code>--prefix=$HOME</code> 
          <code>--prefix</code> ɼ Ͽ
          <code>/usr/local/apache2</code> ̿ ġ 丮
            ִ.</p>
    
        <h4><a name="layout" id="layout">丮  </a></h4>
          <dl>
            <dt><code>--enable-layout=<var>LAYOUT</var></code></dt>
            <dd>ġ ġ <var>LAYOUT</var>  
              ҽڵ  ũƮ Ѵ.  ϸ
                 ġ ġ    ִ.
              <code>config.layout</code> Ͽ    ְ,
              ̸ Ͽ     ִ. Ͽ
                <code>&lt;Layout
                FOO&gt;...&lt;/Layout&gt;</code> еǸ, 
              κ <code>FOO</code> ̸  Ÿ.
               ⺻ <code>Apache</code>̴.</dd>
          </dl>
        
    
        <h4><a name="directoryfinetuning" id="directoryfinetuning">ġ 丮
          ڼ </a></h4>
        
          <p>ġ 丮  Ѵٸ Ʒ ɼ Ѵ.
             丮 ⺻ <code>autoconf</code> ϸ,
               ٸ ϶.</p>
    
          <dl>
            
            <dt><code>--bindir=<var>DIR</var></code></dt>
            <dd>  <var>DIR</var> ġѴ. 
              Ͽ Ʈ ڿ 
              <code>htpasswd</code> <code>dbmmanage</code> 
               α׷ Եȴ. <var>DIR</var> ⺻
              <code><var>EPREFIX</var>/bin</code>̴.</dd>
    
            <dt><code>--datadir=<var>DIR</var></code></dt>
            <dd>Ű  б ڷḦ <var>DIR</var>
              ġѴ. <code>datadir</code> ⺻
              <code><var>PREFIX</var>/share</code>̴.
              <code>autoconf</code>  ɼ   
              ʴ´.</dd>
    
            <dt><code>--includedir=<var>DIR</var></code></dt>
            <dd>C  <var>DIR</var> ġѴ.
              <code>includedir</code> ⺻
              <code><var>EPREFIX</var>/include</code>̴.</dd>
    
            <dt><code>--infodir=<var>DIR</var></code></dt>
            <dd>info  <var>DIR</var> ġѴ.
              <code>infodir</code> ⺻
              <code><var>PREFIX</var>/info</code>̴.   ɼ
               ʴ´.</dd>
            
            <dt><code>--libdir=<var>DIR</var></code></dt>
            <dd>Ʈڵ ̺귯 <var>DIR</var> ġѴ.
              <code>libdir</code> ⺻
              <code><var>EPREFIX</var>/lib</code>̴.</dd>
    
            <dt><code>--libexecdir=<var>DIR</var></code></dt>
            <dd>α׷  (, ) <var>DIR</var>
              ġѴ. <code>libexecdir</code> ⺻
              <code><var>EPREFIX</var>/libexec</code>̴.</dd>
    
            <dt><code>--localstatedir=<var>DIR</var></code></dt>
            <dd>Ǵ ӽ  <var>DIR</var> ġѴ.
              <code>localstatedir</code> ⺻
              <code><var>PREFIX</var>/var</code>̴.
              <code>autoconf</code>  ɼ   
              ʴ´.</dd>
    
            <dt><code>--mandir=<var>DIR</var></code></dt>
            <dd>man  <var>DIR</var> ġѴ.
              <code>mandir</code> ⺻
              <code><var>EPREFIX</var>/man</code>̴.</dd>
          
            <dt><code>--oldincludedir=<var>DIR</var></code></dt>
            <dd>gcc ƴ Ϸ  C  <var>DIR</var>
              ġѴ. <code>oldincludedir</code> ⺻
              <code>/usr/include</code>̴. <code>autoconf</code>
               ɼ    ʴ´.</dd>
            
            <dt><code>--sbindir=<var>DIR</var></code></dt>
            <dd>ý ڿ  <var>DIR</var> ġѴ.
              ý ڿ ̶ ġ  ϴµ
              ʿ <code>httpd</code>, <code>apachectl</code>,
              <code>suexec</code>   α׷ Ѵ.
              <code>sbindir</code> ⺻
              <code><var>EPREFIX</var>/sbin</code>̴.</dd>
    
            <dt><code>--sharedstatedir=<var>DIR</var></code></dt>
            <dd>Ǵ Ű  ڷḦ <var>DIR</var>
              ġѴ. <code>sharedstatedir</code> ⺻
              <code><var>PREFIX</var>/com</code>̴.
              <code>autoconf</code>  ɼ   
              ʴ´.</dd>
    
            <dt><code>--sysconfdir=<var>DIR</var></code></dt>
            <dd>  <code>httpd.conf</code>,
              <code>mime.types</code>  б ӽ ڷḦ
              <var>DIR</var> ġѴ. <code>sysconfdir</code>
              ⺻ <code><var>PREFIX</var>/etc</code>̴.</dd>
          </dl>        
        
      
      
      <h3><a name="systemtypes" id="systemtypes">ý </a></h3>
    
        <p>ٸ ýۿ  ġ 
          ϱ(cross-compile)ϱ  ɼǵ̴. 
           ýۿ  ϴ Ϲ , 
          ɼ  ʴ´.</p>
    
        <dl>
          <dt><code>--build=<var>BUILD</var></code></dt>
          <dd> ϴ ý  Ѵ. ⺻
            <code>config.guess</code> ũƮ ̴.</dd>
    
          <dt><code>--host=<var>HOST</var></code></dt>
          <dd>  ý  Ѵ. <var>HOST</var>
            ⺻ <var>BUILD</var>̴.</dd>
    
          <dt><code>--target=<var>TARGET</var></code></dt>
          <dd><var>TARGET</var> ý   Ϸ 鶧
            Ѵ. ⺻ <var>HOST</var>̴.
            <code>autoconf</code>  ɼ  ġ ʹ
             .</dd>
        </dl>
      
    
      <h3><a name="optionalfeatures" id="optionalfeatures"> </a></h3>
    
        <p> ɼ    Ѵ.</p>
    
        <h4><a name="generaloptfeat" id="generaloptfeat">Ϲ </a></h4>
          <p>Ϲ   Ͽ  ϰ :</p>
    
          <dl>
            <dt><code>--disable-<var>FEATURE</var></code></dt>
            <dd><var>FEATURE</var>  .
              <code>--enable-<var>FEATURE</var>=no</code> .</dd>
    
            <dt><code>--enable-<var>FEATURE</var>[=<var>ARG</var>]</code></dt>
            <dd><var>FEATURE</var>  Ѵ. <var>ARG</var>
              ⺻ <code>yes</code>̴.</dd>
    
            <dt><code>--enable-<var>MODULE</var>=shared</code></dt>
            <dd>ش  DSO  Ѵ.</dd>
    
            <dt><code>--enable-<var>MODULE</var>=static</code></dt>
            <dd>ϴ  ⺻  ũȴ. 
              ɼ   ũ Ѵ.</dd>
          </dl>
    
          <div class="note"><h3></h3>
            <code>configure</code> <var>foo</var>  
            <code>--enable-<var>foo</var></code> ص  
            ˷ Ƿ ؼ Էؾ Ѵ.
          </div>
        
    
        
        <h4><a name="enabledmodules" id="enabledmodules">⺻ ϴ </a></h4>
          <p>  ⺻ ϵDZ⶧  ʴ´ٸ
              Ѵ.  ɼ Ư  
             Ѵ.</p>
    
          <dl>
            <dt><code>--disable-actions</code></dt>
            <dd><code class="module"><a href="../mod/mod_actions.html">mod_actions</a></code> ϴ û 
              ൿ   ʴ´.</dd>
    
            <dt><code>--disable-alias</code></dt>
            <dd><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> ϴ û
              Ͻý ٸ κ ϴ  
              ʴ´.</dd>
    
            <dt><code>--disable-asis</code></dt>
            <dd><code class="module"><a href="../mod/mod_asis.html">mod_asis</a></code> ϴ as-is 
               ʴ´.</dd>
    
            <dt><code>--disable-auth</code></dt>
            <dd><code class="module"><a href="../mod/mod_auth.html">mod_auth</a></code> ϴ ں 
                ʴ´.   ڸ ȣ
              Ϲ Ͽ ϴ HTTP Basic Authentication
              Ѵ.</dd>
    
            <dt><code>--disable-autoindex</code></dt>
            <dd><code class="module"><a href="../mod/mod_autoindex.html">mod_autoindex</a></code> ϴ 丮
                 ʴ´.</dd>
    
            <dt><code>--disable-access</code></dt>
            <dd><code class="module"><a href="../mod/mod_access.html">mod_access</a></code> ϴ ȣƮ
                 ʴ´.</dd>
    
            <dt><code>--disable-cgi</code></dt>
            <dd>񾲷 MPM ϴ  CGI ũƮ ϴ
              <code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code> ⺻ Ѵ. 
              ɼ ϸ CGI  ʴ´.</dd>
    
            <dt><code>--disable-cgid</code></dt>
            <dd> MPM <code class="module"><a href="../mod/worker.html">worker</a></code>
              <code class="module"><a href="../mod/perchild.html">perchild</a></code> ϴ  ⺻
              <code class="module"><a href="../mod/mod_cgid.html">mod_cgid</a></code> CGI ũƮ Ѵ.
               ɼ ϸ CGI  ʴ´.</dd>
    
            <dt><code>--disable-charset-lite</code></dt>
            <dd><code class="module"><a href="../mod/mod_charset_lite.html">mod_charset_lite</a></code> ϴ 
              ȯ   ʴ´.   EBCDIC ýۿ
              ⺻ Ѵ.</dd>
    
            <dt><code>--disable-dir</code></dt>
            <dd><code class="module"><a href="../mod/mod_dir.html">mod_dir</a></code> ϴ 丮 û
              ó   ʴ´.</dd>
    
            <dt><code>--disable-env</code></dt>
            <dd><code class="module"><a href="../mod/mod_env.html">mod_env</a></code> ϴ ȯ溯 /
                ʴ´.</dd>
    
            
            <dt><code>--disable-http</code></dt>
              <dd>HTTP  ó ʴ´. <code>http</code>
                   ϴµ ⺻ ̴.
                 ٸ    쿡  
                ϴ. <strong>ڽ  ϴ Ȯ 
                Ѵٸ  ɼ  </strong>
                <br />
                :   ׻  ũȴ.</dd>
    
            <dt><code>--disable-imagemap</code></dt>
            <dd><code class="module"><a href="../mod/mod_imagemap.html">mod_imagemap</a></code> ϴ  imagemap
                ʴ´.</dd>
    
            <dt><code>--disable-include</code></dt>
            <dd><code class="module"><a href="../mod/mod_include.html">mod_include</a></code> ϴ Server Side
              Includes   ʴ´.</dd>
    
            <dt><code>--disable-log-config</code></dt>
            <dd><code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code> ϴ α
                ʴ´.     û
              α׿   .</dd>
    
            <dt><code>--disable-mime</code></dt>
            <dd><code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code> û ϸ Ȯڿ
                ൿ (mime-type, , ,
              ڵ) Ѵ. (  Ͽ)  Ȯڸ
              MIME  ʴ  Ϲ õ ʴ´.</dd>
    
            <dt><code>--disable-negotiation</code></dt>
            <dd><code class="module"><a href="../mod/mod_negotiation.html">mod_negotiation</a></code> ϴ 
                ʴ´.</dd>
    
            <dt><code>--disable-setenvif</code></dt>
            <dd><code class="module"><a href="../mod/mod_setenvif.html">mod_setenvif</a></code> ϴ 
               ȯ溯 ϴ   ʴ´.</dd>
    
            <dt><code>--disable-status</code></dt>
            <dd><code class="module"><a href="../mod/mod_status.html">mod_status</a></code> ϴ μ/
                 ʴ´.</dd>
    
            <dt><code>--disable-userdir</code></dt>
            <dd><code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code> ϴ û ں
              丮 ϴ   ʴ´.</dd>
          </dl>
        
    
        <h4><a name="disabledmodules" id="disabledmodules">⺻  ʴ </a></h4>
          <p>⺻ ϵǴ ⵵ ,  Ϸ
             Ȥ <code>most</code> <code>all</code> Ű带
            Ͽ  ؾ ϴ  ִ. ׷
            Ʒ ɼǵ Ѵ.</p>
    
          <dl>
            <dt><code>--enable-auth-anon</code></dt>
            <dd><code class="module"><a href="../mod/mod_auth_anon.html">mod_auth_anon</a></code> ϴ ͸
                Ѵ.</dd>
    
            <dt><code>--enable-auth-dbm</code></dt>
            <dd><code class="module"><a href="../mod/mod_auth_dbm.html">mod_auth_dbm</a></code> ڸ ȣ
              DBM ͺ̽ Ͽ ϴ HTTP Basic
              Authentication Ѵ.  Ϸ 
              ɼ Ѵ.</dd>
    
            <dt><code>--enable-auth-digest</code></dt>
            <dd><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code> ϴ RFC2617
              Digest authentication Ѵ.   
              Ϲ Ͽ Ѵ.</dd>
    
            <dt><code>--enable-authnz-ldap</code></dt>
            <dd><code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> ϴ LDAP
                Ѵ.</dd>
              
            <dt><code>--enable-cache</code></dt>
            <dd><code class="module"><a href="../mod/mod_cache.html">mod_cache</a></code> ϴ  ϴ
               ij  Ѵ. ſ ϰ ų Ͻ
               ijϴ     
               ִ. ּ Ѱ (storage management
              module) ( , <code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code>
              <code class="module"><a href="../mod/mod_mem_cache.html">mod_mem_cache</a></code>)  ؾ Ѵ.</dd>
    
            <dt><code>--enable-cern-meta</code></dt>
            <dd><code class="module"><a href="../mod/mod_cern_meta.html">mod_cern_meta</a></code> ϴ CERN Ÿ
                Ѵ.</dd>
    
            <dt><code>--enable-charset-lite</code></dt>
            <dd><code class="module"><a href="../mod/mod_charset_lite.html">mod_charset_lite</a></code> ϴ 
              ȯ  Ѵ.   EBCDIC ýۿ
              ⺻ Եȴ. ٸ ýۿ  Խ
              Ѵ.</dd>
    
            <dt><code>--enable-dav</code></dt>
            <dd><code class="module"><a href="../mod/mod_dav.html">mod_dav</a></code> ϴ WebDAV 
              ó  Ѵ.  <code class="module"><a href="../mod/mod_dav_fs.html">mod_dav_fs</a></code>
               Ͻý ڿ Ѵ.  
              <code>--enable-dav</code> ϸ ڵ Ѵ.<br />
              : <code class="module"><a href="../mod/mod_dav.html">mod_dav</a></code> <code>http</code>
                 ؾ Ѵ.</dd>
    
            <dt><code>--enable-dav-fs</code></dt>
            <dd><code class="module"><a href="../mod/mod_dav_fs.html">mod_dav_fs</a></code> ϴ DAV Ͻý
              ڿ   Ѵ.  
              <code class="module"><a href="../mod/mod_dav.html">mod_dav</a></code>   ̱ 
              <code>--enable-dav</code> ؾ Ѵ.</dd>
    
            <dt><code>--enable-deflate</code></dt>
            <dd><code class="module"><a href="../mod/mod_deflate.html">mod_deflate</a></code> ϴ 
              ڵ  Ѵ.</dd>
    
            <dt><code>--enable-disk-cache</code></dt>
            <dd><code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code> ϴ ũ
              ij  Ѵ.</dd>
    
            <dt><code>--enable-expires</code></dt>
            <dd><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> ϴ Expires
                 Ѵ.</dd>
    
            <dt><code>--enable-ext-filter</code></dt>
            <dd><code class="module"><a href="../mod/mod_ext_filter.html">mod_ext_filter</a></code> ϴ ܺ
                 Ѵ.</dd>
    
            <dt><code>--enable-file-cache</code></dt>
            <dd><code class="module"><a href="../mod/mod_file_cache.html">mod_file_cache</a></code> ϴ 
              ij  Ѵ.</dd>
    
            <dt><code>--enable-headers</code></dt>
            <dd><code class="module"><a href="../mod/mod_headers.html">mod_headers</a></code> ϴ HTTP 
                Ѵ.</dd>
    
            <dt><code>--enable-info</code></dt>
            <dd><code class="module"><a href="../mod/mod_info.html">mod_info</a></code> ϴ  
              Ѵ.</dd>
    
            <dt><code>--enable-ldap</code></dt>
            <dd><code class="module"><a href="../mod/mod_ldap.html">mod_ldap</a></code> ϴ LDAP ij̰
              Ǯ  Ѵ.</dd>
    
            <dt><code>--enable-logio</code></dt>
            <dd><code class="module"><a href="../mod/mod_logio.html">mod_logio</a></code> ϴ α׿ 
               Ʈ ϴ  Ѵ.</dd>
    
            <dt><code>--enable-mem-cache</code></dt>
            <dd><code class="module"><a href="../mod/mod_mem_cache.html">mod_mem_cache</a></code> ϴ ޸
              ij  Ѵ.</dd>
    
            <dt><code>--enable-mime-magic</code></dt>
            <dd><code class="module"><a href="../mod/mod_mime_magic.html">mod_mime_magic</a></code> ϴ MIME
              type ڵ ν  Ѵ.</dd>
    
            <dt><code>--enable-isapi</code></dt>
            <dd><code class="module"><a href="../mod/mod_isapi.html">mod_isapi</a></code> ϴ isapi Ȯ
              Ѵ.</dd>
    
            <dt><code>--enable-proxy</code></dt>
            <dd><code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> ϴ Ͻ/Ʈ
               Ѵ. <code>CONNECT</code>, <code>FTP</code>,
              <code>HTTP</code>  Ͻ  
              <code class="module"><a href="../mod/mod_proxy_connect.html">mod_proxy_connect</a></code>,
              <code class="module"><a href="../mod/mod_proxy_ftp.html">mod_proxy_ftp</a></code>,
              <code class="module"><a href="../mod/mod_proxy_http.html">mod_proxy_http</a></code>
               Ѵ. <code>--enable-proxy</code> ϸ
                 ڵ Ѵ.</dd>
    
            <dt><code>--enable-proxy-connect</code></dt>
            <dd><code class="module"><a href="../mod/mod_proxy_connect.html">mod_proxy_connect</a></code> ϴ
              <code>CONNECT</code> û  Ͻ  
              Ѵ.   <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> 
              Ȯ̹Ƿ, <code>--enable-proxy</code>  ؾ
              Ѵ.</dd>
    
            <dt><code>--enable-proxy-ftp</code></dt>
            <dd><code class="module"><a href="../mod/mod_proxy_ftp.html">mod_proxy_ftp</a></code> ϴ
              <code>FTP</code> û  Ͻ   Ѵ.
                <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>  Ȯ̹Ƿ,
              <code>--enable-proxy</code>  ؾ Ѵ.</dd>
    
            <dt><code>--enable-proxy-http</code></dt>
            <dd><code class="module"><a href="../mod/mod_proxy_http.html">mod_proxy_http</a></code> ϴ
              <code>HTTP</code> û  Ͻ   Ѵ.
                <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>  Ȯ̹Ƿ,
              <code>--enable-proxy</code>  ؾ Ѵ.</dd>
    
            <dt><code>--enable-rewrite</code></dt>
            <dd><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> ϴ Ģ
              URL   Ѵ.</dd>
    
            <dt><code>--enable-so</code></dt>
            <dd><code class="module"><a href="../mod/mod_so.html">mod_so</a></code> ϴ DSO  Ѵ.
              <code>--enable-mods-shared</code> ɼ ϸ
              ڵ   Ѵ.</dd>
    
            <dt><code>--enable-speling</code></dt>
            <dd><code class="module"><a href="../mod/mod_spelling.html">mod_spelling</a></code> ϴ URL
              Ϲ  Ǽ ġ  Ѵ.</dd>
    
            <dt><code>--enable-ssl</code></dt>
            <dd><code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> ϴ SSL/TLS 
              Ѵ.</dd>
    
            <dt><code>--enable-unique-id</code></dt>
            <dd><code class="module"><a href="../mod/mod_unique_id.html">mod_unique_id</a></code> ϴ û
               ĺڸ   Ѵ.</dd>
    
            <dt><code>--enable-usertrack</code></dt>
            <dd><code class="module"><a href="../mod/mod_usertrack.html">mod_usertrack</a></code> ϴ ڼ
                Ѵ.</dd>
    
            <dt><code>--enable-vhost-alias</code></dt>
            <dd><code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> ϴ 뷮
              ȣƮ  Ѵ.</dd>
          </dl>
        
    
        <h4><a name="developermodules" id="developermodules">ڸ  </a></h4>
          <p>  ׽Ʈ ڿԸ ϸ, ⺻
             ʴ´.   Ϸ  ɼ Ѵ.
              ʿ Ȯġʴٸ  .</p>
    
          <dl>
            
            <dt><code>--enable-bucketeer</code></dt>
            <dd><code>mod_bucketeer</code> ϴ Ŷ(bucket)
               ͸ Ѵ.</dd>
    
            
            <dt><code>--enable-case-filter</code></dt>
            <dd><code>mod_case_filter</code> 빮ںȯ 
              ߺ Ѵ.</dd>
    
            
            <dt><code>--enable-case-filter-in</code></dt>
            <dd><code>mod_case_filter_in</code> 빮ںȯ Է
              ߺ Ѵ.</dd>
    
            <dt><code>--enable-echo</code></dt>
            <dd><code class="module"><a href="../mod/mod_echo.html">mod_echo</a></code> ϴ ECHO 
              Ѵ.</dd>
    
            <dt><code>--enable-example</code></dt>
            <dd>ߺ  <code class="module"><a href="../mod/mod_example.html">mod_example</a></code>
              Ѵ.</dd>
    
            
            <dt><code>--enable-optional-fn-export</code></dt>
            <dd><code>mod_optional_fn_export</code> ϴ 
              Լ Ʈ(exporter)  Ѵ.</dd>
    
            
            <dt><code>--enable-optional-fn-import</code></dt>
            <dd><code>mod_optional_fn_import</code> ϴ 
              Լ Ʈ(importer)  Ѵ.</dd>
    
            
            <dt><code>--enable-optional-hook-export</code></dt>
            <dd><code>mod_optional_hook_export</code> ϴ
               (hook) Ʈ  Ѵ.</dd>
    
            
            <dt><code>--enable-optional-hook-import</code></dt>
            <dd><code>mod_optional_hook_import</code> ϴ
                Ʈ  Ѵ.</dd>
          </dl>
        
    
        <h4><a name="modules" id="modules">MPM ڰ  </a></h4>
          <p> ɼ Ͽ ʿ ó ڰ
              ߰Ѵ:</p>
    
          <dl>
            <dt><code>--with-module=<var>module-type</var>:<var>module-file</var>
              </code></dt>
            <dd><p>ڰ    ũ  Ͽ
                ߰Ѵ. ġ  ҽ Ʈ
                <code>modules/<var>module-type</var></code> 
                ҽ <code><var>module-file</var></code> ã⶧
                װ ҽ ־ Ѵ. װ  ٸ
                <code>configure</code> <var>module-file</var>
                ϰζ ϰ ҽ
                <var>module-type</var> 丮 Ϸ
                õѴ.</p>
              <p> ɼ ҽ Ѱ  ܺ  ߰ϴµ
                ϴ.    ߻簡  
                ؾ Ѵ.</p>
              <div class="note"><h3></h3>
                 ũ  ƴ DSO  Ѵٸ
                <a href="apxs.html">apxs</a> ϶.</div>
            </dd>
    
            <dt><code>--with-mpm=MPM</code></dt>
            <dd> ۹ Ѵ. Ȯ Ѱ <a href="../mpm.html">ó</a> ؾ Ѵ.
                ϴ ü <a href="../mpm.html#defaults">⺻ MPM</a> Ѵ.
                ִ MPM <code class="module"><a href="../mod/beos.html">beos</a></code>,
              <code class="module"><a href="../mod/leader.html">leader</a></code>, <code class="module"><a href="../mod/mpmt_os2.html">mpmt_os2</a></code>,
              <code class="module"><a href="../mod/perchild.html">perchild</a></code>, <code class="module"><a href="../mod/prefork.html">prefork</a></code>,
              <code class="module"><a href="../mod/threadpool.html">threadpool</a></code>, <code class="module"><a href="../mod/worker.html">worker</a></code>
              ִ.</dd>
          </dl>
        
    
        <h4><a name="otheroptfeat" id="otheroptfeat">Ÿ ɼ</a></h4>
          <dl>
            <dt><code>--enable-maintainer-mode</code></dt>
            <dd>  Ͻ  ۵Ѵ.</dd>
    
            <dt><code>--enable-mods-shared=<var>MODULE-LIST</var></code></dt>
            <dd>
              <p>    Ѵ. ,
                  <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> þ
                Ͽ  о鿩 Ѵ.</p>
              <p><var>MODULE-LIST</var>   
                ǥ  ̴.  տ
                <code>mod_</code> .  :</p>
              <div class="example"><p><code>
                --enable-mods-shared='headers rewrite dav'
              </code></p></div>
              <p>, Ư Ű <code>all</code> <code>most</code>
                  ִ.  ,</p>
              <div class="example"><p><code>
                --enable-mods-shared=most
              </code></p></div>
              <p> κ  DSO  Ѵ.
                </p>
            </dd>
                        
            <dt><code>--enable-modules=<var>MODULE-LIST</var></code></dt>
            <dd><code>--enable-mods-shared</code> ,
               ɼ    ũѴ. , 
               <code>httpd</code> ϸ  
               ִ. <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> о
              ʿ䰡 .</dd>
    
            <dt><code>--enable-v4-mapped</code></dt>
            <dd>IPv6  IPv4  ó  ֵ Ѵ.</dd>
    
            <dt><code>--with-port=<var>PORT</var></code></dt>
            <dd><code>httpd</code> ٸ Ʈ Ѵ. 
              Ʈȣ  <code>httpd.conf</code> 鶧
              δ. ⺻ 80̴.</dd>
    
            <dt><code>--with-program-name</code></dt>
            <dd>ٸ ϸ Ѵ. ⺻
              <code>httpd</code>̴.</dd>
          </dl>
        
      
    
      <h3><a name="packages" id="packages">߰ Ű </a></h3>
        <p> ɼ ߰ Ű Ѵ.</p>
    
        <h4><a name="generalpackages" id="generalpackages">Ϲ </a></h4>
          <p>Ϲ    Ͽ ߰ Ű
            ٷ:</p>
    
          <dl>
            <dt><code>--with-<var>PACKAGE</var>[=<var>ARG</var>]</code></dt>
            <dd>Ű <var>PACKAGE</var> Ѵ.
              <var>ARG</var> ⺻ <code>yes</code>̴.</dd>
    
            <dt><code>--without-<var>PACKAGE</var></code></dt>
            <dd>Ű <var>PACKAGE</var>  ʴ´.
              <code>--with-<var>PACKAGE</var>=no</code> .
              <code>autoconf</code>  ɼ  ġ ʹ
              谡 .</dd>
          </dl>
        
    
        
    
        <h4><a name="packageopt" id="packageopt">Ư Ű</a></h4>
          <dl>
            <dt><code>--with-apr=<var>DIR</var>|<var>FILE</var></code></dt>
            <dd><code>httpd</code> ҽ  Ե Apache Portable
              Runtime (APR) ڵ   ϵȴ.
               ̹ ġ APR  ϰ ʹٸ
              <code>configure</code> <code>apr-config</code>
              ũƮ θ ˷־ Ѵ. APR ġ ,
              ϸ, 丮   ִ.  丮
               丮 丮 <code>bin</code>
              <code>apr-config</code> ־ Ѵ.</dd>
            
            <dt><code>--with-apr-util=<var>DIR</var>|<var>FILE</var></code></dt>
            <dd><code>httpd</code> ҽ  Ե Apache Portable
              Runtime Utilities (APU) ڵ  
              ϵȴ.  ̹ ġ APU  ϰ ʹٸ
              <code>configure</code> <code>apu-config</code>
              ũƮ θ ˷־ Ѵ. APU ġ ,
              ϸ, 丮   ִ.  丮
               丮 丮 <code>bin</code>
              <code>apu-config</code> ־ Ѵ.</dd>
    
            <dt><code>--with-ssl=<var>DIR</var></code></dt>
            <dd><code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> ϴ 
              <code>configure</code> ġ OpenSSL ã´.
                ɼ Ͽ SSL/TLS  丮θ
              ˷  ִ.</dd>
    
            <dt><code>--with-z=<var>DIR</var></code></dt>
            <dd>(<code class="module"><a href="../mod/mod_deflate.html">mod_deflate</a></code> ϴ 
              )  ʿϴٸ ڵ <code>configure</code>
              ġ <code>zlib</code> ̺귯 ã´. 
               ɼ Ͽ  ̺귯 丮θ
              ˷  ִ.</dd>
          </dl>
    
          <p><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code>
            <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> DBM <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>  ġ
             Ϻ    ã  Ű/
            ͺ̽ Ѵ. APU SDBM ־ 
            ּ  ͺ̽   ִ. ٸ 
            ͺ̽ ϰ ʹٸ Ʒ ɼ Ѵ:</p>
    
          <dl>
            <dt><code>--with-gdbm[=<var>path</var>]</code></dt>
            <dd><var>path</var>  ,
              <code>configure</code> Ϲ ˻ο ġ
              GNU DBM ϰ ̺귯 ã´. 
              <var>path</var> ϸ <code>configure</code>
              <code><var>path</var>/lib</code>
              <code><var>path</var>/include</code> ʿ 
              ã´.  <var>path</var>  ο
              ̺귯 θ ݷ ̿ ΰ   
              ִ.</dd>
    
            <dt><code>--with-ndbm[=<var>path</var>]</code></dt>
            <dd><code>--with-gdbm</code>  ġ New DBM
              ã´.</dd>
    
            <dt><code>--with-berkeley-db[=<var>path</var>]</code></dt>
            <dd><code>--with-gdbm</code>  ġ Berkeley
              DB ã´.</dd>
          </dl>
    
          <div class="note"><h3></h3>
            <p>DBM ɼ APU ϸ APU ũƮ 
              ޵ȴ. ׷ <code>--with-apr-util</code> Ͽ
              ̹ ġ APU Ѵٸ DBM ɼ ҿ .</p>
            <p>  DBM     ִ. 
               DBM    ִ.</p>
          </div>
        
      
      
      <h3><a name="supportopt" id="supportopt"> α׷  ɼ</a></h3>
        <dl>
          <dt><code>--enable-static-support</code></dt>
          <dd> α׷  ũ Ϸ .
            , ʿ ̺귯  ϵ 
            Ѵ.  ɼ   ⺻ 
            α׷  ũѴ.</dd>
    
          <dt><code>--enable-suexec</code></dt>
          <dd> ϴ μ uid gid ϴ
            <code><a href="suexec.html">suexec</a></code> Ϸ
             ɼ Ѵ. <strong>suid  Ȼ 
              Ѵٸ  ɼ  .</strong>
            <code>suexec</code> ϴ ɼ
            <a href="#suexec">Ʒ</a> Ѵ.</dd>
        </dl>
    
        <p> ɼ Ͽ  α׷  ũ
             ִ:</p>
    
        <dl>
          <dt><code>--enable-static-ab</code></dt>
          <dd><code><a href="ab.html">ab</a></code>  ũ
            Ϸ Ѵ.</dd>
    
          
          <dt><code>--enable-static-checkgid</code></dt>
          <dd><code>checkgid</code>  ũ Ϸ
            Ѵ.</dd>
    
          
          <dt><code>--enable-static-htdbm</code></dt>
          <dd><code>htdbm</code>  ũ Ϸ
            Ѵ.</dd>
    
          <dt><code>--enable-static-htdigest</code></dt>
          <dd><code><a href="htdigest.html">htdigest</a></code>
             ũ Ϸ Ѵ.</dd>
            
          <dt><code>--enable-static-htpasswd</code></dt>
          <dd><code><a href="htpasswd.html">htpasswd</a></code>
             ũ Ϸ Ѵ.</dd>
    
          <dt><code>--enable-static-logresolve</code></dt>
          <dd><code><a href="logresolve.html">logresolve</a></code>
             ũ Ϸ Ѵ.</dd>
    
          <dt><code>--enable-static-rotatelogs</code></dt>
          <dd><code><a href="rotatelogs.html">rotatelogs</a></code>
             ũ Ϸ Ѵ.</dd>
        </dl>
    
        <h4><a name="suexec" id="suexec">suexec  ɼ</a></h4>
          <p>Ʒ ɼ <code><a href="../suexec.html">suexec</a></code> ڼ Ѵ.
             ڼ  <a href="../suexec.html#install">suEXEC
             ġ</a> ϶.</p>
    
          <dl>
            <dt><code>--with-suexec-bin</code></dt>
            <dd>suexec  θ Ѵ. ⺻
              <code>--sbindir</code>̴ (<a href="#directoryfinetuning">ġ 丮 ڼ
              </a> ).</dd>
    
            <dt><code>--with-suexec-caller</code></dt>
            <dd><code>suexec</code>  ڸ Ѵ.
               ڴ  <code>httpd</code> ϴ ڿ
              ƾ Ѵ.</dd>
    
            <dt><code>--with-suexec-docroot</code></dt>
            <dd><code>suexec</code>  ɼ  丮
              Ʒ ִ ϸ   ִ. ⺻
              <code>--datadir/htdocs</code>.</dd>
    
            <dt><code>--with-suexec-gidmin</code></dt>
            <dd><code>suexec</code>  ּ GID Ѵ.
              ⺻ 100̴.</dd>
    
            <dt><code>--with-suexec-logfile</code></dt>
            <dd><code>suexec</code> αϸ Ѵ. αϸ
              ⺻ <code>suexec_log</code>̰,
              <code>--logfiledir</code> ġѴ.</dd>
    
            <dt><code>--with-suexec-safepath</code></dt>
            <dd><code>suexec</code> ϴ μ
              <code>PATH</code> ȯ溯 Ѵ. ⺻
              <code>/usr/local/bin:/usr/bin:/bin</code>̴.</dd>
    
            <dt><code>--with-suexec-userdir</code></dt>
            <dd> 丮 <code>suexec</code> 
               ִ ( ִ) 丮 Ѵ.
                <code>suexec</code>
              (<code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code> ϴ) ں
              丮  Ҷ ʿϴ. ⺻
              <code>public_html</code>̴.</dd>
    
            <dt><code>--with-suexec-uidmin</code></dt>
            <dd><code>suexec</code>  ּ UID Ѵ.
              ⺻ 100̴.</dd>
    
            <dt><code>--with-suexec-umask</code></dt>
            <dd><code>suexec</code> ϴ μ
              <code>umask</code> Ѵ. ⺻ ϴ ý
              ⺻  .</dd>
          </dl>
        
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="env" id="env">ȯ溯</a></h2>
      <p><code>configure</code>  ϰų ʿ ٸ
        ̸̳ ġ ִ ̺귯 α׷ ã ִ
         ȯ溯 ִ.</p>
    
      
      <dl>
        <dt><code>CC</code></dt>
        <dd>Ͽ  C Ϸ ɾ Ѵ.</dd>
    
        <dt><code>CFLAGS</code></dt>
        <dd>϶ ϱ ٶ C Ϸ ɼ Ѵ.</dd>
    
        <dt><code>CPP</code></dt>
        <dd> C ó ɾ Ѵ.</dd>
    
        <dt><code>CPPFLAGS</code></dt>
        <dd>C/C++ ó ɼ.  ,  ʿ ޸
          <var>includedir</var> 丮 ִٸ
          <code>-I<var>includedir</var></code> Ѵ.</dd>
    
        <dt><code>LDFLAGS</code></dt>
        <dd>Ŀ ɼ.  , ̺귯 ʿ ޸
          <var>libdir</var> 丮 ִٸ
          <code>-L<var>libdir</var></code> Ѵ.</dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/configure.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/configure.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/log_server_status.html.fr.utf8������������������������������������0000664�0001751�0001751�00000014354�14740503670�024631� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>log_server_status - Enregistrement périodique de l'état du serveur - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>log_server_status - Enregistrement périodique de l'état du serveur</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/log_server_status.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/log_server_status.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Ce script perl a été conçu pour être exécuté à intervalles
        réguliers via un déclencheur de type cron. Il se connecte au serveur
        pour en extraire des informations quant à son état. Il formate ces
        informations sous la forme d'une seule ligne qu'il enregistre dans
        un fichier. Vous devez éditer la valeur des variables en tête de
        script afin de définir le chemin du fichier de sortie. Pour que ce
        script puisse fonctionner, <code class="module"><a href="../mod/mod_status.html">mod_status</a></code> doit au
        préalable être chargé et configuré.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">Mode d'emploi</a></h2>
    
    <p>Le script contient les sections suivantes :</p>
    
    <pre class="prettyprint lang-perl">my $wherelog = "/usr/local/apache2/logs/";  # Le fichier de sortie sera
    					# du style "/usr/local/apache2/logs/19960312"
    my $server   = "localhost";        # Nom du serveur, par exemple "www.foo.com"
    my $port     = "80";               # Port d'écoute du serveur
    my $request = "/server-status/?auto";    # Requête à soumettre</pre>
    
    
    <p>Ces variables doivent contenir des valeurs correctes, et le
    gestionnaire <code>/server-status</code> doit être configuré pour le
    répertoire considéré. En outre, l'utilisateur qui exécute le script doit
    avoir les droits d'écriture sur le chemin du fichier de sortie.</p>
    
    <p>L'exécution périodique du script via cron permet d'obtenir un jeu de
    rapports d'état qui pourra être utilisé à des fins d'analyse
    statistique.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/log_server_status.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/log_server_status.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/log_server_status.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/split-logfile.html.fr.utf8����������������������������������������0000664�0001751�0001751�00000014150�14740503670�023623� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>split-logfile - Eclatement des journaux en fonction des serveurs
    virtuels - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>split-logfile - Eclatement des journaux en fonction des serveurs
    virtuels</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/split-logfile.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/split-logfile.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Ce script perl permet d'extraire un journal pour chaque serveur
        virtuel à partir d'un journal d'accès global du serveur web. Pour
        que ce script fonctionne, le premier champ de chaque ligne du
        journal global doit contenir l'identité du serveur virtuel ; ce
        champ aura été ajouté à la directive <code class="directive"><a href="../mod/mod_log_config.html#logformat">LogFormat</a></code> via la variable
        "<code>%v</code>".
        </p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="split-logfile" id="split-logfile">Mode d'emploi</a></h2>
    
        <p>Création d'un fichier journal comportant l'identité du serveur
        virtuel considéré :</p>
    
        <pre class="prettyprint lang-config">LogFormat "%v %h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-agent}i\"" combined_plus_vhost
    CustomLog logs/access_log combined_plus_vhost</pre>
    
    
        <p>Un fichier journal sera créé dans le répertoire à partir duquel
        vous exécutez le script pour chaque serveur virtuel qui apparaît
        dans le journal global. Ces fichiers journaux seront nommés à partir
        du nom du serveur virtuel considéré, avec l'extension
        <code>.log</code>.</p>
    
        <p>Le fichier journal global est lu depuis l'entrée standard stdin.
        Les entrées de ce journal sont alors ajoutées au journal du serveur
        virtuel correspondant.</p>
    
        <div class="example"><p><code>split-logfile &lt; access_log</code></p></div>
    
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/split-logfile.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/split-logfile.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/split-logfile.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/dbmmanage.html.tr.utf8��������������������������������������������0000664�0001751�0001751�00000035535�14743132254�023013� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>dbmmanage - DBM biçemli kullanıcı kimlik doğrulama dosyalarını yönetir - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>dbmmanage - DBM biçemli kullanıcı kimlik doğrulama dosyalarını yönetir</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/dbmmanage.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.</div>
    
        <p><code><strong>dbmmanage</strong></code>,
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> üzerinden HTTP kullanıcılarının temel
        kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının
        saklanmasında kullanılacak DBM dosyalarını oluşturmak ve güncellemek için
        kullanılır. Apache HTTP sunucusunun mevcut özkaynaklarının kullanımı
        sadece <code><strong>dbmmanage</strong></code> tarafından oluşturulan
        dosyalarda listelenmiş kullanıcılara tahsis edilebilir. Bu program
        sadece, kullanıcı isimleri bir DBM dosyasında saklanmak istenirse işe
        yarar. Düz metin bir veritabanı kullanmak isterseniz
        <strong><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code></strong> sayfasına bakınız.</p>
    
        <p>DBM parola veritabanı sağlayan diğer bir araç da
          <strong><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></strong>'dir.</p>
    
        <p>Bu kılavuz sayfası sadece komut satırı değiştirgelerini listeler.
        Kullanıcı kimlik doğrulamasını
        <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong>'de yapılandırmak için gerekli
        yönergelerle ilgili ayrıntılar için Apache dağıtımının bir parçası olan
        ve <a href="http://httpd.apache.org/"> http://httpd.apache.org/</a>
        adresinde de bulunan Apache HTTP Sunucusu Belgelerine bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Hatalar</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></li><li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li><li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>dbmmanage</strong> [ <var>kodlama</var> ]
        <var>dosyaismi</var> add|adduser|check|delete|update
        <var>kullanıcı</var>
        [ <var>şifreli_parola</var>
          [ <var>grup</var>[,<var>grup</var>...]
            [ <var>açıklama</var> ] ] ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>dosyaismi</var>
        view [ <var>kullanıcı</var> ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>dosyaismi</var> import</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><var>dosyaismi</var></code></dt>
        <dd>DBM dosyasının ismi. Genellikle, <code>.db</code>, <code>.pag</code>
        veya <code>.dir</code> eklentisi olmaksızın belirtilir.</dd>
    
        <dt><code><var>kullanıcı</var></code></dt>
        <dd>İşlemleri gerçekleştirecek kullanıcı ismi.
        <code><var>kullanıcı</var></code> ismi ikinokta imi (<code>:</code>)
        içeremez.</dd>
    
        <dt><code><var>şifreli_parola</var></code></dt>
        <dd><code><strong>update</strong></code> ve
        <code><strong>add</strong></code> komutları için kullanılacak şifreli
        paroladır. Parolanın istenmesini sağlamak, fakat hemen ardından alanları
        doldurmak için bir tire imi (<code>-</code>) kullanabilirsiniz. Buna ek
        olarak, <code><strong>update</strong></code> komutunu kullanırken özgün
        parolaya dokunulmaması için bir nokta imi (<code>.</code>)
        kullanabilirsiniz.</dd>
    
        <dt><code><var>grup</var></code></dt>
        <dd>Kullanıcının üyesi olduğu grup. Grup ismi ikinokta imi
        (<code>:</code>) içeremez.Kullanıcıyı bir gruba atamadan açıklama alanını
        doldurmak istiyorsanız bir tire imi (<code>-</code>) kullanabilirsiniz.
        Buna ek olarak, <code><strong>update</strong></code> komutunu kullanırken
        özgün gruba dokunulmaması için bir nokta imi (<code>.</code>)
        kullanabilirsiniz.</dd>
    
        <dt><code><var>açıklama</var></code></dt>
        <dd>Adı ve soyadı, eposta adresi gibi kullanıcıyla ilgili bir takım
        bilgiler buraya yazılır. Sunucu bu alanı gözardı eder.</dd>
        </dl>
    
        <h3><a name="options.encodings" id="options.encodings">Kodlamalar</a></h3>
          <dl>
          <dt><code><strong>-d</strong></code></dt>
          <dd>CRYPT şifrelemesi (Win32 ve Netware hariç, öntanımlı)</dd>
    
          <dt><code><strong>-m</strong></code></dt>
          <dd>MD5 şifrelemesi (Win32 ve Netware için öntanımlı)</dd>
    
          <dt><code><strong>-s</strong></code></dt>
          <dd>SHA1 şifrelemesi</dd>
    
          <dt><code><strong>-p</strong></code></dt>
          <dd>düz metin (<em>önerilmez</em>)</dd>
          </dl>
        
    
        <h3><a name="options.commands" id="options.commands">Komutlar</a></h3>
          <dl>
          <dt><code><strong>add</strong></code></dt>
          <dd><code><var>şifreli_parola</var></code>'yı kullanarak
            <code><var>dosyaismi</var></code> dosyasına
            <code><var>kullanıcı</var></code> için bir girdi ekler.
    
          <div class="example"><p><code>dbmmanage passwords.dat add rbowen foKntnEF3KSXA</code></p></div>
          </dd>
    
          <dt><code><strong>adduser</strong></code></dt>
          <dd>Parola sorduktan sonra <code><var>dosyaismi</var></code>
            dosyasına <code><var>kullanıcı</var></code> için bir girdi ekler.
    
          <div class="example"><p><code>dbmmanage passwords.dat adduser krietz</code></p></div>
          </dd>
    
          <dt><code><strong>check</strong></code></dt>
          <dd>Parola sorduktan sonra belirtilen <code><var>kullanıcı</var></code>,
            <code><var>dosyaismi</var></code> dosyasında var mı diye bakar; varsa
            belirtilen parolayı kullanıcınınkiyle eşleştirmeye çalışır.
    
          <div class="example"><p><code>dbmmanage passwords.dat check rbowen</code></p></div>
          </dd>
    
          <dt><code><strong>delete</strong></code></dt>
          <dd><code><var>dosyaismi</var></code> dosyasından
            <code><var>kullanıcı</var></code> girdisini siler.
    
          <div class="example"><p><code>dbmmanage passwords.dat delete rbowen</code></p></div>
          </dd>
    
          <dt><code><strong>import</strong></code></dt>
          <dd>Standart girdiden
            <code><var>kullanıcı</var>:<var>parola</var></code> satırlarını (her
            satırda bir tane) okur ve bunları <code><var>dosyaismi</var></code>
            dosyasına ekler. Parola şifrelenmiş olmalıdır.</dd>
    
          <dt><code><strong>update</strong></code></dt>
          <dd>Belirtilen <code><var>kullanıcı</var></code>'nın
            <code><var>dosyaismi</var></code> dosyasında mevcut olması dışında
            <code><strong>adduser</strong></code> komutu gibidir.
    
          <div class="example"><p><code>dbmmanage passwords.dat update rbowen</code></p></div>
          </dd>
    
          <dt><code><strong>view</strong></code></dt>
          <dd>Sadece, DBM dosyasının içeriğini gösterir. Bir
            <code><var>kullanıcı</var></code> belirtirseniz sadece o kaydı
            gösterir.
    
          <div class="example"><p><code>dbmmanage passwords.dat view</code></p></div>
          </dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Hatalar</a></h2>
        <p>Birden fazla DBM dosya biçemi vardır ve büyük bir olasılıkla da
        sisteminizde bu birden fazla biçemle ilgili kütüphaneler vardır. SDBM,
        NDBM, GNU'nun GDBM projesi ve Berkeley DB 2 bunların başlıcalarıdır. Ne
        yazık ki, bu kütüphanelerin her birinin dosya biçimleri farklıdır. Bu
        bakımdan, <code><var>dosyaismi</var></code> dosyasında kullanılan dosya
        biçeminin <code><strong>dbmmanage</strong></code> tarafından kullanılanla
        aynı biçemde olduğundan emin olmalısınız.
        <code><strong>dbmmanage</strong></code> hangi tür DBM dosyasına baktığını
        saptayacak yeterliliğe sahip değildir. Yanlış biçemli bir dosya
        belirtirseniz hiçbir şey dönmeyebileceği gibi, başka isimde bir DBM
        dosyasının oluşturulması veya daha da kötüsü üzerine yazmaya
        çalışıyorsanız DBM dosyasının bozulması bile olasıdır.</p>
    
        <p><code><strong>dbmmanage</strong></code> programının başlangıcında
        <code>@AnyDBM::ISA</code> dizisi olarak tanımlanmış DBM biçem
        tercihlerinin bir listesi vardır. Berkeley DB 2 biçemini tercih
        ettiğimizden <code><strong>dbmmanage</strong></code> sistem
        kütüphanelerini şu sıraya göre arar: Berkeley DB 2, NDBM, GDBM ve SDBM.
        <code><strong>dbmmanage</strong></code> DBM dosyası hareketleri için  bu
        sıralamaya göre bulduğu ilk kütüphaneyi kullanacaktır. Sıralama Perl'deki
        <code>dbmopen()</code> çağrısının kullandığından faklı olduğu gibi
        Perl'deki standart <code>@AnyDBM::ISA</code> sıralamasından da oldukça
        farklıdır. Bu bakımdan, DBM dosyalarınızı yönetmek için Perl ile yazılmış
        başka araçlar kullanıyorsanız, onların da bu tercih sırasını izlemesini
        sağlamalısınız. Benzer şekilde, bu dosyalara erişmek için diğer dillerde
        (C gibi) yazılmış programlar kullanıyorsanız bunlar için de aynı durum
        geçerlidir.</p>
    
        <p>Unix sistemlerinde, kullanılan DBM dosyasının biçemini öğrenmek için
        <code><strong>file</strong></code> programı kullanılabilir.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/dbmmanage.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/dbmmanage.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/dbmmanage.html.ko.euc-kr������������������������������������������0000664�0001751�0001751�00000026616�14743132254�023277� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>dbmmanage - DBM    Ѵ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>dbmmanage - DBM    Ѵ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/dbmmanage.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><code>dbmmanage</code> HTTP basic authentication
         ڸ ȣ ϴ DBM  
        Ѵ. ġ  ڿ <code>dbmmanage</code>
         Ͽ  ڿԸ   ִ. ڸ
        DBM Ͽ ϵ  α׷   ִ.
        Ϲ ͺ̽ Ϸ <a href="htpasswd.html">htpasswd</a> ϶.</p>
    
        <p> manpage  ɼǸ Ѵ. <a href="httpd.html">httpd</a>  ϴ þ
          ġ  Եְ <a href="http://httpd.apache.org">http://httpd.apache.org/</a>
          ִ ġ  ϶.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="httpd.html">httpd</a></li><li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li><li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
        <p><code><strong>dbmmanage</strong> [ <var>encoding</var> ]
        <var>filename</var> add|adduser|check|delete|update
        <var>username</var>
        [ <var>encpasswd</var>
          [ <var>group</var>[,<var>group</var>...]
            [ <var>comment</var> ] ] ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>filename</var>
        view [ <var>username</var> ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>filename</var> import</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
        <dl>
        <dt><code><var>filename</var></code></dt>
        <dd>DBM  ϸ.  <code>.db</code>,
        <code>.pag</code>, <code>.dir</code> Ȯڸ .</dd>
    
        <dt><code><var>username</var></code></dt>
        <dd>۾ ڸ. <var>username</var> ݷ(<code>:</code>)
          .</dd>
    
        <dt><code><var>encpasswd</var></code></dt>
        <dd><code>update</code> <code>add</code> ɿ 
        ̹ ȣȭ ȣ̴. ȣ ߿ ϰ  
        ȣ(<code>-</code>) Ѵ. , <code>update</code>
         Ҷ ħǥ(<code>.</code>) ϸ 
        ȣ ״ д.</dd>
    
        <dt><code><var>group</var></code></dt>
        <dd>ڰ  ׷. ׷ ݷ(<code>:</code>)
          . ڸ ׷쿡 ߰  
        ä ʹٸ ȣ(<code>-</code>) Ѵ. ,
        <code>update</code>  Ҷ ħǥ(<code>.</code>)
        Ѵٸ  ׷ ״ д.</dd>
    
        <dt><code><var>comment</var></code></dt>
        <dd> ̸,  ּ  ڿ    ̴.
          ׸ Ѵ.</dd>
        </dl>
    
        <h3><a name="options.encodings" id="options.encodings">ڵ</a></h3>
          <dl>
          <dt><code>-d</code></dt>
          <dd>crypt ȣȭ (Win32 Netware ƴ϶ ⺻)</dd>
    
          <dt><code>-m</code></dt>
          <dd>MD5 ȣȭ (Win32 Netware ⺻)</dd>
    
          <dt><code>-s</code></dt>
          <dd>SHA1 ȣȭ</dd>
    
          <dt><code>-p</code></dt>
          <dd>ȣ ״  (<em>õ </em>)</dd>
          </dl>
        
    
        <h3><a name="options.commands" id="options.commands"></a></h3>
          <dl>
          <dt><code>add</code></dt>
          <dd>ȣȭ ȣ <var>encpasswd</var> Ͽ
          <var>filename</var> <var>username</var> ׸ ߰Ѵ.</dd>
    
          <dt><code>adduser</code></dt>
          <dd>ȣ  <var>filename</var>
          <var>username</var> ׸ ߰Ѵ.</dd>
    
          <dt><code>check</code></dt>
          <dd>ȣ  <var>filename</var>
          <var>username</var> ְ ȣ ġϴ ˻Ѵ.</dd>
    
          <dt><code>delete</code></dt>
          <dd><var>filename</var> <var>username</var> ׸
          Ѵ.</dd>
    
          <dt><code>import</code></dt>
          <dd><code>STDIN</code>
          <code><var>username</var>:<var>password</var></code> ׸
          (ٿ ϳ) о <var>filename</var> ߰Ѵ.
          ȣ ̹ ȣȭ־ Ѵ.</dd>
    
          <dt><code>update</code></dt>
          <dd><code>adduser</code> ɰ ,
          <var>filename</var> ̹ <var>username</var> ִ
          ȮѴ.</dd>
    
          <dt><code>view</code></dt>
          <dd>DBM   Ѵ. <var>username</var>
          ϸ Ư ׸ Ѵ.</dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs"></a></h2>
        <p> ٸ DBM ĵ ְ  ýۿ 
        Ŀ   ̺귯  ؾ Ѵ.
         ǥ װ SDBM, NDBM, GNU Ʈ GDBM,
        Berkeley DB 2̴.   ̺귯  ٸ
         Ѵ. ׷ <var>filename</var> ϴ
         <code>dbmmanage</code> ϴ İ 
        Ȯؾ Ѵ. <code>dbmmanage</code> DBM  
        ˾Ƴ Ѵ. ٸ  ϸ ƹϵ  ʰų,
        ٸ ̸ DBM  ų, ־   Ͽ
        DBM  ĥ  ִ.</p>
    
        <p><code>dbmmanage</code> α׷ պκп ִ
        <code>@AnyDBM::ISA</code> 迭 DBM ȣ̴.
        츮 Berkeley DB 2  ȣϹǷ
        <code>dbmmanage</code> ý ̺귯 ã 
        Berkeley DB 2, NDBM, GDBM, SDBM ̴. <code>dbmmanage</code>
          ã ̺귯 Ͽ  DBM  ۾
        Ѵ.   Perl  <code>dbmopen()</code> ȣ
        ϴ  Perl ǥ <code>@AnyDBM::ISA</code> 
         ٸ. ׷ ٸ  Ͽ DBM  Ѵٸ
           Ѵ. C  ٸ  ۼ α׷
        Ͽ  ٷ 쿡 .</p>
    
        <p>κ н ýۿ <code>file</code> α׷
        DBM  Ȯ  ִ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/dbmmanage.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/dbmmanage.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdbm.html.tr.utf8������������������������������������������������0000664�0001751�0001751�00000047430�14743132254�022173� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htdbm - DBM parola veritabanlarını yönetir - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>htdbm - DBM parola veritabanlarını yönetir</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htdbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/htdbm.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.</div>
    
        <p><code><strong>htdbm</strong></code>,
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> üzerinden HTTP kullanıcılarının temel
        kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının
        saklanmasında kullanılacak DBM dosyalarını yönetmek için kullanılır. DBM
        dosyaları hakkında daha ayrıntılı bilgi edinmek için
        <strong><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></strong> sayfasına bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Hatalar</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Çıkış Durumu</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Örnekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Güvenlik Değerlendirmeleri</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#restrictions">Kısıtlamalar</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></li><li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>htdbm</strong>
        [ -<strong>T</strong><var>VTtürü</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>parola-dosyası</var> <var>kullanıcı</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>b</strong>
        [ -<strong>T</strong><var>VTtürü</var> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>parola-dosyası</var> <var>kullanıcı</var> <var>parola</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>n</strong>
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>kullanıcı</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>nb</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>kullanıcı</var> <var>parola</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>v</strong>
        [ -<strong>T</strong><var>VTtürü</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>parola-dosyası</var> <var>kullanıcı</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>vb</strong>
        [ -<strong>T</strong><var>VTtürü</var> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong>
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>parola-dosyası</var> <var>kullanıcı</var> <var>parola</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>x</strong>
        [ -<strong>T</strong><var>VTtürü</var> ]
        <var>parola-dosyası</var> <var>kullanıcı</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>l</strong>
        [ -<strong>T</strong><var>VTtürü</var> ]
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><strong>-b</strong></code></dt>
        <dd>Betik kipi; parola için istek yapmak yerine parola komut satırından
        verilir. <strong>Parola komut satırında görünür</strong> olacağından çok
        dikkatli kullanmak gerekir. Betik kullanımı için
        <code><strong>-i</strong></code> seçeneğine bakınız.</dd>
    
        <dt><code><strong>-i</strong></code></dt>
        <dd>Parolayı doğrulamaksızın standart girdiden okur (betik kullanımı
        için).</dd>
    
        <dt><code><strong>-c</strong></code></dt>
        <dd><code><var>parola-dosyası</var></code> oluşturur. Dosya mevcutsa,
        dosya silinip yeniden yazılır. Bu seçenek
        <code><strong>-n</strong></code> seçeneği ile birlikte kullanılamaz.</dd>
    
        <dt><code><strong>-n</strong></code></dt>
        <dd>Sonuçları veritabanında güncellemek yerine standart çıktıya gönderir.
        <code><var>parola-dosyası</var></code> belirtilmediğinden, bu seçenek
        komut satırı sözdizimini değiştirir. Bu seçenek
        <code><strong>-c</strong></code> seçeneği ile birlikte kullanılamaz.</dd>
    
        <dt><code><strong>-m</strong></code></dt>
        <dd>Parolalar için MD5 şifrelemesi kullanılır. Windows ve Netware
        için bu öntanımlıdır.</dd>
    
        <dt><code><strong>-B</strong></code></dt>
        <dd>Parolalar için bcrypt şifrelemesi kullanılır. Şu an için çok güvenli
        kabul edilmektedir.</dd>
    
        <dt><code><strong>-C</strong>  <var>bedel</var></code></dt>
        <dd>Bu seçenek sadece <code><strong>-B</strong></code> (bcrypt şifrelemesi)
        seçeneği ile birlikte kullanılabilir. Bcrypt algoritmasına hesaplama
        süresini belirtir (daha yüksek değerler daha güvenlidir, öntanımlı 5,
        geçerli değerler: 4 - 31).</dd>
    
        <dt><code><strong>-d</strong></code></dt>
        <dd>Parolaları şifrelemek için <code>crypt()</code> kullanılır. Windows,
        ve Netware dışında öntanımlıdır.
        <code><strong>htdbm</strong></code> tarafından tüm platformlarda
        destekleniyor olsa da Windows ve Netware üzerinde
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> sunucusu tarafından desteklenmez. Bu algoritma
        günümüz standartlarında <strong>güvenilmez</strong> kabul
        edilmektedir.</dd>
    
        <dt><code><strong>-s</strong></code></dt>
        <dd>Parolalar için SHA şifrelemesi kullanılır. LDAP Dizin değişim
        biçemini (ldif) kullanarak Netscape sunucularına/sunucularından göçü
        kolaylaştırır. Bu algoritma günümüz standartlarında
        <strong>güvenilmez</strong> kabul edilmektedir.</dd>
    
        <dt><code><strong>-p</strong></code></dt>
        <dd>Düz metin parolalar kullanılır. <code><strong>htdbm</strong></code>
        tarafından tüm platformlarda destekleniyor olsa da Windows, Netware ve
        TPF üzerinde <code class="program"><a href="../programs/httpd.html">httpd</a></code> sunucusu tarafından sadece düz
        metin parolalar kabul edilir.</dd>
    
        <dt><code><strong>-l</strong></code></dt>
        <dd>Veritabanındaki kullanıcıları açıklamalarıyla birlikte standart
        çıktıya gönderir.</dd>
    
        <dt><code><strong>-v</strong></code></dt>
        <dd>Kullanıcı adını ve parolasını doğrular. Program belirtilen parolanın
        geçerli olup olmadığını belirten bir ileti basar. Eğer parola geçersizse
        program hata kodu 3 ile çıkar.</dd>
    
        <dt><code><strong>-x</strong></code></dt>
        <dd>Kullanıcıyı siler. Kullanıcı belirtilen DBM dosyasında mevcutsa
        silinir.</dd>
    
        <dt><code><strong>-t</strong></code></dt>
        <dd>Son değiştirgenin bir açıklama olarak yorumlanmasını sağlar. Bu
        seçenek kullanıldığında komut satırının sonuna fazladan bir dizge
        eklenebilir. Bu dizge, veritabanında belirtilen kullanıcının "Comment"
        alanında saklanır.</dd>
    
        <dt><code><var>parola-dosyası</var></code></dt>
        <dd>DBM dosyasının ismi. Genellikle, <code>.db</code>, <code>.pag</code>
        veya <code>.dir</code> eklentisi olmaksızın belirtilir.
        <code><strong>-c</strong></code> seçeneği ile birlikte verilmişse ve DBM
        dosyası mevcut değilse dosya oluşturulur, mevcutsa dosya güncellenir.</dd>
    
        <dt><code><var>kullanıcı</var></code></dt>
        <dd><code><var>parola-dosyası</var></code>'nda oluşturulacak veya
        güncellenecek kullanıcı ismi. <code><var>kullanıcı</var></code> bu
        dosyada mevcut değilse yeni bir girdi eklenir. Girdi mevcutsa parolası
        değiştirilir.</dd>
    
        <dt><code><var>parola</var></code></dt>
        <dd>Şifrelenip DBM dosyasında saklanacak düz metin parola. Sadece
        <code><strong>-b</strong></code> seçeneği ile kullanılır.</dd>
    
        <dt><code><strong>-T</strong> <var>VTtürü</var></code></dt>
        <dd>DBM dosyasının türü; SDBM, GDBM, DB, veya "default" olabilir.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Hatalar</a></h2>
        <p>Birden fazla DBM dosya biçemi vardır ve büyük bir olasılıkla da
        sisteminizde bu birden fazla biçemle ilgili kütüphaneler vardır. SDBM,
        NDBM, GNU'nun GDBM projesi ve Berkeley/Sleepycat DB 2/3/4 bunların
        başlıcalarıdır. Ne yazık ki, bu kütüphanelerin her birinin dosya
        biçimleri farklıdır. Bu bakımdan, <code><var>dosyaismi</var></code>
        dosyasında kullanılan dosya biçeminin <code><strong>htdbm</strong></code>
        tarafından kullanılanla aynı biçemde olduğundan emin olmalısınız.
        <code><strong>htdbm</strong></code> hangi tür DBM dosyasına baktığını
        saptayacak yeterliliğe sahip değildir. Yanlış biçemli bir dosya
        belirtirseniz hiçbir şey dönmeyebileceği gibi, başka isimde bir DBM
        dosyasının oluşturulması veya daha da kötüsü üzerine yazmaya
        çalışıyorsanız DBM dosyasının bozulması bile olasıdır.</p>
    
        <p>Unix sistemlerinde, kullanılan DBM dosyasının biçemini öğrenmek için
        <code><strong>file</strong></code> programı kullanılabilir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Çıkış Durumu</a></h2>
        <p><code><strong>htdbm</strong></code>, kullanıcı ismi ve parolasını DBM
        dosyasına başarıyla eklemiş veya güncellemişse <code>0</code>, dosyalara
        erişirken bir sorun çıkmışsa <code>1</code>, komut satırında bir
        sözdizimi hatası varsa <code>2</code>, parola etkileşimli alınmış fakat
        girdi ile eşleşme sağlanamamışsa <code>3</code>, işlem kesintiye
        uğramışsa <code>4</code>, bir değer çok uzunsa <code>5</code> (kullanıcı,
        parola, dosya ismi veya açıklama), kullanıcı ismi kuraldışı karakter
        içeriyorsa (<a href="#restrictions">Kısıtlamalar</a> bölümüne bakınız)
        <code>6</code> ve dosya geçerli bir DBM parola dosyası değilse
        <code>7</code> değeriyle döner.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Örnekler</a></h2>
        <div class="example"><p><code>
          htdbm /usr/local/etc/apache/.htdbm-users jsmith
        </code></p></div>
    
        <p><code>jsmith</code> kullanıcısı için parolayı ekler veya değiştirir.
        Parolayı vermesi için kullanıcıya parola isteği yapılır. Windows üzerinde
        çalıştırılırsa parola Apache MD5 algoritması ile şifrelenir, aksi
        takdirde sistemin <code>crypt()</code> yordamı kullanılır. Dosya mevcut
        değilse <code><strong>htdbm</strong></code> beklenen hiçbir işlemi
        yapmadan bir hata vererek çıkar.</p>
    
        <div class="example"><p><code>
          htdbm -c /home/doe/public_html/.htdbm jane
        </code></p></div>
    
        <p>Yeni bir dosya oluşturur ve kullanıcı <code>jane</code> için kaydı bir
        girdi olarak bu dosyaya yazar. Dosya mevcutsa fakat okunamıyor veya
        yazılamıyorsa dosyada bir değişiklik yapılmaz ve
        <code><strong>htdbm</strong></code> bir ileti gösterip bir hata durumu
        ile çıkar.</p>
    
        <div class="example"><p><code>
          htdbm -mb /usr/web/.htdbm-all jones Pwd4Steve
        </code></p></div>
    
        <p>Komut satırından verilen parolayı (<code>Pwd4Steve</code>) MD5
        algoritmasıyla şifreler ve bunu belirtilen dosyada saklar.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Güvenlik Değerlendirmeleri</a></h2>
        <p><code><strong>htdbm</strong></code> tarafından yönetilen parola
        dosyalarına sunucunun URI uzayından erişilememelidir; yani dosya bir
        tarayıcı ile okunabilecek bir yerde bulunmamalıdır.</p>
    
        <p>Komut satırında parolanın şifrelenmemiş olarak görünmesi sebebiyle
        <code><strong>-b</strong></code> seçeneğinin kullanımından kaçınılmasını
        öneriyoruz.</p>
    
        <p><code>crypt()</code> algoritması kullanılırken, parolayı
        şekillendirmek için parolanın ilk 8 baytının kullanılacağına dikkat
        ediniz. Eğer parola 8 bayttan uzunsa kalanlar bir uyarı verilmeksizin
        iptal edilir.</p>
    
        <p>SHA şifreleme biçeminde tuz kullanılmaz; yani, bir parolanın
        sadece bir şifreli gösterimi olabilir. <code>crypt()</code> ve
        MD5 biçemleri parolanın önüne rasgele üretilmiş bir tuz dizgesi
        eklediklerinden sözlük saldırılarına karşı daha dayanıklıdır.</p>
    
        <p>SHA ve <code>crypt()</code> biçimleri günümüz standartlarında
        <strong>güvenilmez</strong> kabul edilmektedir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="restrictions" id="restrictions">Kısıtlamalar</a></h2>
        <p>Windows platformunda, <code><strong>htdbm</strong></code>
        ile şifrelenen parolalar <code>255</code> karakterden daha uzun olamaz.
        255 karakterden sonrası kırpılır.</p>
    
        <p><code><strong>htdbm</strong></code> tarafından kullanılan MD5
        algoritması Apache yazılımına özeldir; bu algoritma ile şifrelenen
        parolalar başka HTTP sunucularında kullanılamayabilir.</p>
    
        <p>Kullanıcı isimleri <code>255</code> bayttan uzun olamaz ve iki nokta
        imi (<code>:</code>) içeremez.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htdbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/htdbm.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htdbm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apxs.html.en������������������������������������������������������0000664�0001751�0001751�00000046542�14737241666�021156� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apxs - APache eXtenSion tool - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>apxs - APache eXtenSion tool</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/apxs.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>apxs</code> 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 <var>files</var> which then can be loaded into the Apache server
        under runtime via the <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>
        directive from <code class="module"><a href="../mod/mod_so.html">mod_so</a></code>.</p>
    
        <p>So to use this extension mechanism your platform has to support the DSO
        feature and your Apache <code class="program"><a href="../programs/httpd.html">httpd</a></code> binary has to be built with the
        <code class="module"><a href="../mod/mod_so.html">mod_so</a></code> module. The <code>apxs</code> tool automatically
        complains if this is not the case. You can check this yourself by manually
        running the command</p>
    
        <div class="example"><p><code>
          $ httpd -l
        </code></p></div>
    
        <p>The module <code class="module"><a href="../mod/mod_so.html">mod_so</a></code> 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 <code>apxs</code> tool:</p>
    
        <div class="example"><p><code>
          $ apxs -i -a -c mod_foo.c<br />
          gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c<br />
          ld -Bshareable -o mod_foo.so mod_foo.o<br />
          cp mod_foo.so /path/to/apache/modules/mod_foo.so<br />
          chmod 755 /path/to/apache/modules/mod_foo.so<br />
          [activating module `foo' in /path/to/apache/etc/httpd.conf]<br />
          $ apachectl restart<br />
          /path/to/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /path/to/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
        <p>The arguments <var>files</var> can be any C source file (.c), a object
        file (.o) or even a library archive (.a). The <code>apxs</code> 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 <code>-fpic</code>. For other C compilers consult its
        manual page or at watch for the flags <code>apxs</code> uses to compile the
        object files.</p>
    
        <p>For more details about DSO support in Apache read the documentation of
        <code class="module"><a href="../mod/mod_so.html">mod_so</a></code> or perhaps even read the
        <code>src/modules/standard/mod_so.c</code> source file.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Examples</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></li><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>apxs</strong> -<strong>g</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        -<strong>n</strong> <var>modname</var></code></p>
    
        <p><code><strong>apxs</strong> -<strong>q</strong>
        [ -<strong>v</strong> ]
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        <var>query</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>c</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>o</strong> <var>dsofile</var> ]
        [ -<strong>I</strong> <var>incdir</var> ]
        [ -<strong>D</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>L</strong> <var>libdir</var> ]
        [ -<strong>l</strong> <var>libname</var> ]
        [ -<strong>Wc,</strong><var>compiler-flags</var> ]
        [ -<strong>Wl,</strong><var>linker-flags</var> ]
        <var>files</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>i</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>n</strong> <var>modname</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>dso-file</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>e</strong>
        [ -<strong>S</strong> <var>name</var>=<var>value</var> ]
        [ -<strong>n</strong> <var>modname</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>dso-file</var> ...</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <h3><a name="options.common" id="options.common">Common Options</a></h3>
          <dl>
          <dt><code>-n <var>modname</var></code></dt>
          <dd>This explicitly sets the module name for the <code>-i</code> (install)
          and <code>-g</code> (template generation) option. Use this to explicitly
          specify the module name. For option <code>-g</code> this is required, for
          option <code>-i</code> the <code>apxs</code> tool tries to determine the
          name from the source or (as a fallback) at least by guessing it from the
          filename.</dd>
          </dl>
        
    
        <h3><a name="options.query" id="options.query">Query Options</a></h3>
          <dl>
          <dt><code>-q</code></dt>
          <dd>Performs a query for variables and environment settings used to
          build <code>httpd</code>.  When invoked without <var>query</var> parameters,
          it prints all known variables and their values.  The optional <code>-v</code>
          parameter formats the list output.
    
          <p>Use this to manually determine settings used to build the
          <code>httpd</code> that will load your module.  For instance use</p>
          <div class="example"><p><code>
            INC=-I`apxs -q INCLUDEDIR`
          </code></p></div>
    
          <p>inside your own Makefiles if you need manual access to Apache's C
          header files.</p></dd>
          </dl>
        
    
        <h3><a name="options.conf" id="options.conf">Configuration Options</a></h3>
          <dl>
          <dt><code>-S <var>name</var>=<var>value</var></code></dt>
          <dd>This option changes the apxs settings described above.</dd>
          </dl>
        
    
        <h3><a name="options.template" id="options.template">Template Generation Options</a></h3>
          <dl>
          <dt><code>-g</code></dt>
          <dd>This generates a subdirectory <var>name</var> (see option
          <code>-n</code>) and there two files: A sample module source file named
          <code>mod_<var>name</var>.c</code> 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 <code>Makefile</code> for even easier
          build and installing of this module.</dd>
          </dl>
        
    
        <h3><a name="options.dso" id="options.dso">DSO Compilation Options</a></h3>
          <dl>
          <dt><code>-c</code></dt>
          <dd>This indicates the compilation operation. It first compiles the C
          source files (.c) of <var>files</var> into corresponding object files (.o)
          and then builds a dynamically shared object in <var>dsofile</var> by
          linking these object files plus the remaining object files (.o and .a) of
          <var>files</var>. If no <code>-o</code> option is specified the output
          file is guessed from the first filename in <var>files</var> and thus
          usually defaults to <code>mod_<var>name</var>.so</code>.</dd>
    
          <dt><code>-o <var>dsofile</var></code></dt>
          <dd>Explicitly specifies the filename of the created dynamically shared
          object. If not specified and the name cannot be guessed from the
          <var>files</var> list, the fallback name <code>mod_unknown.so</code> is
          used.</dd>
    
          <dt><code>-D <var>name</var>=<var>value</var></code></dt>
          <dd>This option is directly passed through to the compilation command(s).
          Use this to add your own defines to the build process.</dd>
    
          <dt><code>-I <var>incdir</var></code></dt>
          <dd>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.</dd>
    
          <dt><code>-L <var>libdir</var></code></dt>
          <dd>This option is directly passed through to the linker command. Use this
          to add your own library directories to search to the build  process.</dd>
    
          <dt><code>-l <var>libname</var></code></dt>
          <dd>This option is directly passed through to the linker command. Use this
          to add your own libraries to search to the build process.</dd>
    
          <dt><code>-Wc,<var>compiler-flags</var></code></dt>
          <dd>This option passes <var>compiler-flags</var> as additional flags to
          the <code>libtool --mode=compile</code> command. Use this to add local
          compiler-specific options.</dd>
    
          <dt><code>-Wl,<var>linker-flags</var></code></dt>
          <dd>This option passes <var>linker-flags</var> as additional
          flags to the <code>libtool --mode=link</code> command. Use this
          to add local linker-specific options.</dd>
    
          <dt><code>-p</code></dt>
          <dd>This option causes apxs to link against the apr/apr-util libraries.
          This is useful when compiling helper programs that use the apr/apr-util
          libraries.</dd>
          </dl>
        
    
        <h3><a name="options.dsoinstall" id="options.dsoinstall">DSO Installation and Configuration Options</a></h3>
        
          <dl>
          <dt><code>-i</code></dt>
          <dd>This indicates the installation operation and installs one or more
          dynamically shared objects into the server's <var>modules</var>
          directory.</dd>
    
          <dt><code>-a</code></dt>
          <dd>This activates the module by automatically adding a corresponding
          <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> line to Apache's
          <code>httpd.conf</code> configuration file, or by enabling it if it
          already exists.</dd>
    
          <dt><code>-A</code></dt>
          <dd>Same as option <code>-a</code> but the created <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directive is prefixed with a hash
          sign (<code>#</code>), <em>i.e.</em>, the module is just prepared for
          later activation but initially disabled.</dd>
    
          <dt><code>-e</code></dt>
          <dd>This indicates the editing operation, which can be used with the
          <code>-a</code> and <code>-A</code> options similarly to the
          <code>-i</code> operation to edit Apache's <code>httpd.conf</code>
          configuration file without attempting to install the module.</dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Examples</a></h2>
        <p>Assume you have an Apache module named <code>mod_foo.c</code> 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:</p>
    
        <div class="example"><p><code>
          $ apxs -c mod_foo.c<br />
          /path/to/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          $ _
        </code></p></div>
    
        <p>Then you have to update the Apache configuration by making sure a
        <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directive is present to
        load this shared object. To simplify this step <code>apxs</code> provides
        an automatic way to install the shared object in its "modules" directory
        and updating the <code>httpd.conf</code> file accordingly. This can be
        achieved by running:</p>
    
        <div class="example"><p><code>
          $ apxs -i -a mod_foo.la<br />
          /path/to/instdso.sh mod_foo.la /path/to/apache/modules<br />
          /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules
          ...
          chmod 755 /path/to/apache/modules/mod_foo.so<br />
          [activating module `foo' in /path/to/apache/conf/httpd.conf]<br />
          $ _
        </code></p></div>
    
        <p>This way a line named</p>
    
        <div class="example"><p><code>
          LoadModule foo_module modules/mod_foo.so
        </code></p></div>
    
        <p>is added to the configuration file if still not present. If you want to
        have this disabled per default use the <code>-A</code> option,
        <em>i.e.</em></p>
    
        <div class="example"><p><code>
          $ apxs -i -A mod_foo.c
        </code></p></div>
    
        <p>For a quick test of the apxs mechanism you can create a sample Apache
        module template plus a corresponding Makefile via:</p>
    
        <div class="example"><p><code>
          $ apxs -g -n foo<br />
          Creating [DIR]  foo<br />
          Creating [FILE] foo/Makefile<br />
          Creating [FILE] foo/modules.mk<br />
          Creating [FILE] foo/mod_foo.c<br />
          Creating [FILE] foo/.deps<br />
          $ _
        </code></p></div>
    
        <p>Then you can immediately compile this sample module into a shared object
        and load it into the Apache server:</p>
    
        <div class="example"><p><code>
          $ cd foo<br />
          $ make all reload<br />
          apxs -c mod_foo.c<br />
          /path/to/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          apxs -i -a -n "foo" mod_foo.la<br />
          /path/to/instdso.sh mod_foo.la /path/to/apache/modules<br />
          /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules
          ...
          chmod 755 /path/to/apache/modules/mod_foo.so<br />
          [activating module `foo' in /path/to/apache/conf/httpd.conf]<br />
          apachectl restart<br />
          /path/to/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /path/to/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/apxs.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apxs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/configure.html.fr.utf8��������������������������������������������0000664�0001751�0001751�00000117140�14740503670�023035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>configure - Configure l'arborescence des sources - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>configure - Configure l'arborescence des sources</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/configure.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Le script <code>configure</code> permet de configurer
        l'arborescence des sources afin de compiler et installer le serveur
        HTTP Apache sur votre plate-forme spécifique. De nombreuses options
        vous permettent de compiler un serveur correspondant à vos propres
        besoins.</p>
    
        <p>Ce script, situé dans le répertoire racine de la distribution des
        sources, ne concerne que la compilation sur les systèmes Unix et
        apparentés. Pour les autres plates-formes, voir la <a href="../platform/">documentation spécifique</a> de ces
        dernières.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Résumé</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#env">Variables d'environnement</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../install.html">Compilation et installation</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Résumé</a></h2>
        <p>Vous devez appeler le script <code>configure</code> depuis le
        répertoire racine de la distribution.</p>
    
        <p><code><strong>./configure</strong> [<var>OPTION</var>]...
        [<var>VARIABLE</var>=<var>VALEUR</var>]...</code></p>
    
        <p>Pour définir des variables d'environnement (par exemple
        <code>CC</code>,<code>CFLAGS</code>, etc...), utilisez la clause
        <code><var>VARIABLE</var>=<var>VALEUR</var></code>. Voir <a href="#env">ci-dessous</a> pour la description de quelques variables
        usuelles.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
      <ul>
        <li><a href="#configurationoptions">Options de Configuration</a></li>
        <li><a href="#installationdirectories">Répertoires d'installation</a></li>
        <li><a href="#systemtypes">Types de Systèmes</a></li>
        <li><a href="#optionalfeatures">Fonctionnalités optionnelles</a></li>
        <li><a href="#supportopt">Options pour les programmes support</a></li>
      </ul>
    
      <h3><a name="configurationoptions" id="configurationoptions">Options de Configuration</a></h3>
    
        <p>Les options suivantes affectent le comportement du script
        <code>configure</code>.</p>
    
        <dl>
          <dt><code>-C</code></dt>
          <dt><code>--config-cache</code></dt>
          <dd>C'est un alias pour <code>--cache-file=config.cache</code></dd>
    
          <dt><code>--cache-file=<var>FICHIER</var></code></dt>
          <dd>Les résultats des tests seront mis en cache dans le fichier
          <var>FICHIER</var>. Cette option est désactivée par défaut.</dd>
    
          <dt><code>-h</code></dt>
          <dt><code>--help [short|recursive]</code></dt>
          <dd>Affichage de l'aide et sortie du script. Avec l'argument
          <code>short</code>, seules les options spécifiques à ce paquet
          seront affichées. L'argument <code>recursive</code> permet
          d'afficher l'aide de tous les paquets inclus.</dd>
    
          <dt><code>-n</code></dt>
          <dt><code>--no-create</code></dt>
          <dd>Le script <code>configure</code> s'exécute normalement, mais
          ne crée pas les fichiers résultants. Ceci permet de vérifier les
          résultats des tests avant de générer les fichiers makefile pour la
          compilation.</dd>
    
          <dt><code>-q</code></dt>
          <dt><code>--quiet</code></dt>
          <dd>Les messages <code>checking ...</code> ne sont pas affichés au
          cours du processus de configuration.</dd>
    
          <dt><code>--srcdir=<var>DIR</var></code></dt>
          <dd>Définit le répertoire <var>DIR</var> comme répertoire des
          fichiers sources. Par défaut, c'est le répertoire où se situe le
          script <code>configure</code>, ou le répertoire parent.</dd>
    
          <dt><code>--silent</code></dt>
          <dd>Identique à <code>--quiet</code></dd>
    
          <dt>-V</dt>
          <dt>--version</dt>
          <dd>Affichage des informations de copyright et sortie du
          script.</dd>
        </dl>
      
    
      <h3><a name="installationdirectories" id="installationdirectories">Répertoires
      d'installation</a></h3>
    
        <p>Ces options permettent de spécifier le répertoire d'installation.
        L'arborescence de l'installation dépend de l'organisation (layout)
        sélectionnée.</p>
    
        <dl>
          <dt><code>--prefix=<var>PREFIX</var></code></dt>
          <dd>Installe les fichiers indépendants de l'architecture dans
          <var>PREFIX</var>. Par défaut, le répertoire d'installation est
          <code>/usr/local/apache2</code>.</dd>
    
          <dt><code>--exec-prefix=<var>EPREFIX</var></code></dt>
          <dd>Installe les fichiers dépendants de l'architecture dans
          <var>EPREFIX</var>. La valeur par défaut de cette option
          correspond à la valeur de la variable
          <var>PREFIX</var>.</dd>
        </dl>
    
        <p>Par défaut, <code>make install</code> va installer tous les
        fichiers dans <code>/usr/local/apache2/bin</code>,
        <code>/usr/local/apache2/lib</code>, etc... Vous pouvez cependant
        spécifier un préfixe d'installation autre que
        <code>/usr/local/apache2</code> en utilisant l'option
        <code>--prefix</code> (par exemple <code>--prefix=$HOME</code>).</p>
    
        <h4><a name="layout" id="layout">Spécifier une organisation (layout) des
        répertoires</a></h4>
          <dl>
            <dt><code>--enable-layout=<var>LAYOUT</var></code></dt>
            <dd>Configure le code source et les scripts de compilation de
    	façon à ce que l'arborescence d'installation adopte
    	l'organisation <var>LAYOUT</var>. Ceci vous permet de spécifier
    	des chemins séparés pour chaque type de fichier de
    	l'installation du serveur HTTP Apache. Le fichier
    	<code>config.layout</code> contient de nombreux exemples de
    	configurations, et vous pouvez créer vos propres configurations
    	personnalisées en vous basant sur ces exemples. Les différentes
    	organisations contenues dans ce fichier sont enregistrées sous
    	forme de sections <code>&lt;Layout
    	FOO&gt;...&lt;/Layout&gt;</code> et référencées dans ce cas par
    	le nom <code>FOO</code>. L'organisation par défaut
    	est <code>Apache</code>.</dd>
          </dl>
        
    
        <h4><a name="directoryfinetuning" id="directoryfinetuning">Configuration avancée des
        répertoires d'installation</a></h4>
    
          <p>Pour une définition plus précise des répertoires
          d'installation, utilisez les options ci-dessous. Notez que les
          répertoires par défaut sont définis par <code>autoconf</code>, et
          que leurs valeurs sont écrasées par les valeurs correspondantes
          définies lors du choix de l'organisation des répertoires
          (layout).</p>
    
          <dl>
            <dt><code>--bindir=<var>DIR</var></code></dt>
            <dd>Installe les exécutables utilisateur dans <var>DIR</var>.
    	Les exécutables utilisateur sont des programmes support comme
    	<code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>, <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code>,
    	etc..., et destinés aux administrateurs du site. Par défaut,
    	<var>DIR</var> est défini à
    	<code><var>EPREFIX</var>/bin</code>.</dd>
    
            <dt><code>--datadir=<var>DIR</var></code></dt>
            <dd>Installe les données non modifiables indépendantes de
    	l'architecture dans <var>DIR</var>. Par défaut,
    	<code>datadir</code> est défini à
    	<code><var>PREFIX</var>/share</code>. Cette option est fournie
    	par autoconf et actuellement inutilisée.</dd>
    
            <dt><code>--includedir=<var>DIR</var></code></dt>
            <dd>Installe les fichiers d'en-têtes C dans <var>DIR</var>. Par
    	défaut, <code>includedir</code> est défini à
    	<code><var>EPREFIX</var>/include</code>.</dd>
    
            <dt><code>--infodir=<var>DIR</var></code></dt>
            <dd>Installe la documentation info dans <var>DIR</var>. Par
    	défaut, <code>infodir</code> est défini à
    	<code><var>PREFIX</var>/info</code>. Cette option est
    	actuellement inutilisée.</dd>
    
            <dt><code>--libdir=<var>DIR</var></code></dt>
            <dd>Installe les fichiers objet des bibliothèques dans
    	<var>DIR</var>. Par défaut, <code>libdir</code> est défini à
    	<code><var>EPREFIX</var>/lib</code>.</dd>
    
            <dt><code>--libexecdir=<var>DIR</var></code></dt>
            <dd>Installe les exécutables du programme (autrement dit les
    	modules partagés) dans <var>DIR</var>. Par défaut,
    	<code>libexecdir</code> est défini à
    	<code><var>EPREFIX</var>/modules</code>.</dd>
    
            <dt><code>--localstatedir=<var>DIR</var></code></dt>
            <dd>Installe les données temporaires modifiables spécifiques à
    	la machine dans
    	<var>DIR</var>. Par défaut, <code>localstatedir</code> est
    	défini à <code><var>PREFIX</var>/var</code>. Cette option est
    	fournie par <code>autoconf</code> et est actuellement
    	inutilisée.</dd>
    
            <dt><code>--mandir=<var>DIR</var></code></dt>
            <dd>Installe les pages de manuel dans  <var>DIR</var>. Par
    	défaut, <code>mandir</code> est défini à
    	<code><var>EPREFIX</var>/man</code>.</dd>
    
            <dt><code>--oldincludedir=<var>DIR</var></code></dt>
            <dd>Installe les fichiers d'en-têtes C pour les programmes
    	autres que gcc dans <var>DIR</var>. Par défaut,
    	<code>oldincludedir</code> est défini à
    	<code>/usr/include</code>. Cette option est fournie par
    	<code>autoconf</code> et est actuellement inutilisée.</dd>
    
            <dt><code>--sbindir=<var>DIR</var></code></dt>
            <dd>Installe les exécutables de l'administrateur système dans
    	<var>DIR</var>. Ce sont les programmes du serveur comme
    	<code class="program"><a href="../programs/httpd.html">httpd</a></code>, <code class="program"><a href="../programs/apachectl.html">apachectl</a></code>,
    	<code class="program"><a href="../programs/suexec.html">suexec</a></code>, etc..., qui sont nécessaires à
    	l'exécution du serveur HTTP Apache. Par défaut,
    	<code>sbindir</code> est défini à
    	<code><var>EPREFIX</var>/sbin</code>.</dd>
    
            <dt><code>--sharedstatedir=<var>DIR</var></code></dt>
            <dd>Installe les données modifiables indépendantes de
    	l'architecture dans <var>DIR</var>. Par défaut,
    	<code>sharedstatedir</code> est défini à
    	<code><var>PREFIX</var>/com</code>. Cette option est fournie par
    	<code>autoconf</code> et est actuellement inutilisée.</dd>
    
            <dt><code>--sysconfdir=<var>DIR</var></code></dt>
            <dd>Installe les données non modifiables spécifiques à la
    	machine comme les fichiers de configuration du serveur
    	<code>httpd.conf</code>, <code>mime.types</code>, etc... dans
    	<var>DIR</var>. Par défaut, <code>sysconfdir</code> est défini à
    	<code><var>PREFIX</var>/conf</code>.</dd>
          </dl>
        
      
    
      <h3><a name="systemtypes" id="systemtypes">Types de systèmes</a></h3>
    
        <p>Ces options sont utilisées pour la cross-compilation du serveur
        HTTP Apache afin de pouvoir l'utiliser sur un autre système. Dans le
        cas général où la compilation et l'exécution du serveur ont lieu sur
        le même système, ces options ne sont pas utilisées.</p>
    
        <dl>
          <dt><code>--build=<var>BUILD</var></code></dt>
          <dd>Définit le type du système sur lequel les outils sont
          compilés. Par défaut, il s'agit de la chaîne renvoyée par le
          script <code>config.guess</code>.</dd>
    
          <dt><code>--host=<var>HOST</var></code></dt>
          <dd>Définit le type du système sur lequel le serveur s'exécutera.
          Par défaut, <var>HOST</var> est identique à <var>BUILD</var>.</dd>
    
          <dt><code>--target=<var>TARGET</var></code></dt>
          <dd>Configure pour construire des compilateurs pour le type de
          système <var>TARGET</var>. Par défaut, <var>TARGET</var> est
          identique à <var>HOST</var>. Cette option est fournie par
    	<code>autoconf</code> et n'est pas requise par le serveur HTTP
    	Apache.</dd>
        </dl>
      
    
      <h3><a name="optionalfeatures" id="optionalfeatures">Fonctionnalités
      optionnelles</a></h3>
    
        <p>Ces options vous permettent de configurer avec précision les
        fonctionnalités de votre futur serveur HTTP.</p>
    
        <h4><a name="generaloptfeat" id="generaloptfeat">Syntaxe générale</a></h4>
          <p>D'une manière générale, vous pouvez utiliser la syntaxe
          suivante pour activer ou désactiver une fonctionnalité :</p>
    
          <dl>
            <dt><code>--disable-<var>FONCTIONNALITE</var></code></dt>
            <dd>Désactive la fonctionnalité <var>FONCTIONNALITE</var>.
    	Identique à
    	<code>--enable-<var>FONCTIONNALITE</var>=no</code>.</dd>
    
            <dt><code>--enable-<var>FONCTIONNALITE</var>[=<var>ARG</var>]</code></dt>
            <dd>Active la fonctionnalité <var>FONCTIONNALITE</var>. La
    	valeur par défaut de <var>ARG</var> est <code>yes</code>.</dd>
    
            <dt><code>--enable-<var>MODULE</var>=shared</code></dt>
            <dd>Le module spécifié sera compilé en tant que module DSO. Par
    	défaut, les modules activés sont liés dynamiquement.</dd>
    
            <dt><code>--enable-<var>MODULE</var>=static</code></dt>
            <dd>Le module correspondant sera lié statiquement.</dd>
          </dl>
    
          <div class="note"><h3>Note</h3>
            Si vous spécifiez <code>--enable-<var>foo</var></code>, et si
    	<var>foo</var> n'existe pas, <code>configure</code> ne le
    	signalera pas ; vous devez donc prendre soin de taper les
    	options correctement.
          </div>
        
    
        <h4><a name="choosemodules" id="choosemodules">Choix des modules à compiler</a></h4>
          <p>La plupart des modules sont compilés par défaut et ils doivent être
          désactivés de manière explicite ou via le mots-clé <code>few</code> (voir
          ci-dessous <code>--enable-modules</code>,
          <code>--enable-mods-shared</code> et <code>--enable-mods-static</code>
          pour une explication plus détaillée), ou
          <code>--enable-modules=none</code> pour les désactiver tous.</p>
    
          <p>Par défaut, les autres modules ne sont pas compilés et doivent
          être activés explicitement, ou en utilisant les mots-clés
          <code>all</code> ou <code>reallyall</code> pour être disponibles.</p>
    
          <p>Pour déterminer quels modules sont compilés par défaut,
          exécutez la commande <code>./configure -h</code> ou
          <code>./configure --help</code>, et consultez les <code>Optional
          Features</code>. Par exemple, supposons que vous soyez intéressé
          par les modules <code>mod_example1</code> et
          <code>mod_example2</code>, et que vous voyiez ceci :</p>
    
            <div class="example"><pre>Optional Features:
      ...
      --disable-example1     example module 1
      --enable-example2      example module 2
      ...</pre></div>
    
            <p>Le module <code>mod_example1</code> est ici activé par
    	défaut, et vous devez spécifier <code>--disable-example1</code>
    	si vous ne voulez pas le compiler. Par contre, le module
    	<code>mod_example2</code> est désactivé par défaut, et vous
    	devez spécifier <code>--enable-example2</code> si vous voulez le
    	compiler.</p>
    
        
    
        <h4><a name="mpms" id="mpms">Modules Multi-Processus</a></h4>
          <p>Les <a href="../mpm.html">Modules Multi-Processus</a>, ou MPMs,
          constituent le coeur du serveur. Un seul MPM doit être actif pour
          que le serveur puisse fonctionner. Vous trouverez la liste des
          MPMs disponibles à <a href="../mod/">module index page</a>.</p>
    
          <p>Les MPMs peuvent être compilés en tant que modules DSO pour un
          chargement dynamique, ou liés statiquement avec le serveur, et
          sont activés via les options suivantes :</p>
    
          <dl>
            <dt><code>--with-mpm=MPM</code></dt>
            <dd>
              <p>Sélectionne le MPM par défaut pour votre serveur. Si les
    	  MPMs sont compilés en tant que modules DSO (voir
    	  <code>--enable-mpms-shared</code>), cette option spécifie le
    	  MPM qui sera chargé par défaut selon le fichier de
    	  configuration. Dans le cas contraire, cette option spécifie le
    	  seul MPM disponible qui sera lié statiquement avec le
    	  serveur.</p>
              <p>Si cette option est omise, c'est le <a href="../mpm.html#defaults">MPM par défaut</a> pour votre
    	  système d'exploitation qui sera utilisé.</p>
            </dd>
    
            <dt><code>--enable-mpms-shared=<var>Liste de MPM</var></code></dt>
            <dd>
              <p>Définit une liste de MPMs à compiler en tant que modules
    	  dynamiquement partagés (DSO). Un de ces modules doit être
    	  chargé dynamiquement via la directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>.</p>
              <p><var>Liste de MPM</var> est une liste, entourée
    	  d'apostrophes,  de noms de MPM séparés par des espaces. Par
    	  exemple :</p>
              <div class="example"><p><code>
                --enable-mpms-shared='prefork worker'
              </code></p></div>
              <p>Vous pouvez aussi utiliser le mot-clé <code>all</code>, ce
    	  qui aura pour effet de spécifier tous les MPMs qui supportent
    	  le chargement dynamique sur la plate-forme considérée, et de
    	  les compiler en tant que modules DSO. Par exemple :</p>
              <div class="example"><p><code>
                --enable-mpms-shared=all
              </code></p></div>
    	</dd>
          </dl>
        
    
        <h4><a name="modules" id="modules">Modules tiers</a></h4>
          <p>Pour ajouter des modules tiers, utilisez les options suivantes
          :</p>
    
          <dl>
            <dt><code>--with-module=<var>type-module</var>:<var>fichier-module</var>[,
              <var>type-module</var>:<var>fichier-module</var>]</code></dt>
            <dd><p>Ajoute un ou plusieurs modules tiers à la liste des
    	modules liés statiquement. Le fichier source du module
    	<var>fichier-module</var> sera recherché dans le sous-répertoire
    	<var>type-module</var> de l'arborescence des sources de votre
    	serveur HTTP Apache. S'il ne l'y trouve pas,
    	<code>configure</code> considèrera <var>fichier-module</var>
    	comme un chemin de fichier absolu et essaiera de copier le
    	fichier source dans le sous-répertoire <var>type-module</var>.
    	Si ce sous-répertoire n'existe pas, il sera créé et un fichier
    	<code>Makefile.in</code> standard y sera enregistré.</p>
              <p>Cette option est conçue pour ajouter de petits modules
    	  externes ne comportant qu'un seul fichier source. Pour des
    	  modules plus complexes, vous devrez lire la documentation du
    	  fournisseur du module.</p>
              <div class="note"><h3>Note</h3>
                Si vous voulez compiler un module DSO (lié de manière
    	    dynamique au lieu de statique), utilisez le programme
    	    <code class="program"><a href="../programs/apxs.html">apxs</a></code>.</div>
            </dd>
    
          </dl>
        
    
        <h4><a name="otheroptfeat" id="otheroptfeat">Options cumulatives et autres
        options</a></h4>
          <dl>
            <dt><code>--enable-maintainer-mode</code></dt>
            <dd>Active les avertissements de débogage et de compilation et
    	charge tous les modules compilés.</dd>
    
            <dt><code>--enable-mods-shared=<var>LISTE-MODULES</var></code></dt>
            <dd>
              <p>Définit une liste de modules à activer et à compiler en
    	  tant que modules dynamiques partagés. Cela signifie que ces
    	  modules doivent être chargés dynamiquement en utilisant la
    	  directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>.</p>
              <p><var>LISTE-MODULES</var> est une liste, entourée
    	  d'apostrophes, de noms de modules
    	  séparés par des espaces. Les noms
    	  des modules sont spécifiés sans le préfixe <code>mod_</code>.
    	  Par exemple :</p>
              <div class="example"><p><code>
                --enable-mods-shared='headers rewrite dav'
              </code></p></div>
              <p>Vous pouvez aussi utiliser les mots-clés <code>reallyall</code>,
    	  <code>all</code>, <code>most</code> et <code>few</code>. Par
    	  exemple,</p>
              <div class="example"><p><code>
                --enable-mods-shared=most
              </code></p></div>
              <p>va compiler la plupart des modules en tant que modules DSO,</p>
    	  <div class="example"><p><code>
                --enable-mods-shared=few
              </code></p></div>
              <p>ne compilera qu'un jeu de modules de base.</p>
              <p>Le jeu par défaut correspond au mot-clé <code>most</code>.</p>
                
    	  <p>Les directives <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> correspondant aux
    	  différents modules choisis sont automatiquement générées dans
    	  le fichier de configuration principal. Par défaut, toutes ces
    	  directives sont mises en commentaire, sauf pour les modules
    	  requis ou ceux explicitement sélectionnés par un argument
    	  <code>--enable-nom-module</code> du script configure. Vous
    	  pouvez modifier le jeu de modules chargé en activant ou
    	  désactivant les directives <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> dans le fichier
    	  <code>httpd.conf</code>. En outre, les directives <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> peuvent être activées
    	  pour tous les modules compilés via l'option
    	  <code>--enable-load-all-modules</code> du script configure.</p>
              
            </dd>
    
            <dt><code>--enable-mods-static=<var>MODULE-LIST</var></code></dt>
            <dd>Cette option produit le même effet que l'option
    	<code>--enable-mods-shared</code>, à l'exception que les modules
    	seront liés statiquement. Cela signifie que les modules
    	spécifiés seront toujours disponibles au cours du fonctionnement
    	de <code class="program"><a href="../programs/httpd.html">httpd</a></code>. Ils n'ont pas besoin d'être chargés
    	via la directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>.</dd>
    
    	<dt><code>--enable-modules=<var>MODULE-LIST</var></code></dt>
            <dd>Cette option se comporte comme
    	<code>--enable-mods-shared</code>, et va aussi lier les modules
    	concernés dynamiquement. Le mot-clé spécial <code>none</code>
    	désactive la compilation de tous les modules.</dd>
    
            <dt><code>--enable-v4-mapped</code></dt>
            <dd>Permet aux sockets IPv6 de traiter les connexions IPv4.</dd>
    
            <dt><code>--with-port=<var>PORT</var></code></dt>
            <dd>Permet de définir le port que le programme
    	<code class="program"><a href="../programs/httpd.html">httpd</a></code> va écouter. Ce numéro de port est
    	utilisé lors de la génération du fichier de configuration
    	<code>httpd.conf</code>. Sa valeur par défaut est 80.</dd>
    
            <dt><code>--with-program-name</code></dt>
            <dd>Permet de définir un nom d'exécutable alternatif. Le nom par
    	défaut est <code>httpd</code>.</dd>
          </dl>
        
      
    
      <h3><a name="packages" id="packages">Paquets optionnels</a></h3>
        <p>Ces options permettent de définir des paquets optionnels.</p>
    
        <h4><a name="generalpackages" id="generalpackages">Syntaxe générale</a></h4>
          <p>D'une manière générale, vous pouvez utiliser la syntaxe
          suivante pour définir un paquet optionnel :</p>
    
          <dl>
            <dt><code>--with-<var>PAQUET</var>[=<var>ARG</var>]</code></dt>
            <dd>Utilise le paquet <var>PAQUET</var>. La valeur par défaut de
    	<var>ARG</var> est <code>yes</code>.</dd>
    
            <dt><code>--without-<var>PAQUET</var></code></dt>
            <dd>N'utilise pas le paquet <var>PAQUET</var>. Cette option est
    	identique à <code>--with-<var>PAQUET</var>=no</code>. Elle est
    	fournie par <code>autoconf</code> mais n'est pas très utile pour
    	le serveur HTTP Apache.</dd>
          </dl>
        
    
        
    
        <h4><a name="packageopt" id="packageopt">Paquets spécifiques</a></h4>
          <dl>
            <dt><code>--with-apr=<var>REP</var>|<var>FICHIER</var></code></dt>
            <dd>La <a class="glossarylink" href="../glossary.html#apr" title="voir glossaire">Bibliothèque pour la portabilité
    	d'Apache ou
    	Apache Portable Runtime</a> (APR) fait partie de la
    	distribution des sources de httpd et est compilée
    	automatiquement avec le serveur HTTP. Si vous voulez utiliser
    	une APR déjà installée à la place, vous devez indiquer à
    	<code>configure</code> le chemin du script
    	<code>apr-config</code>. Vous pouvez spécifier le chemin absolu
    	et le nom ou le répertoire d'installation de l'APR.
    	<code>apr-config</code> doit se trouver dans ce répertoire ou
    	dans le sous-repertoire <code>bin</code>.</dd>
    
            <dt><code>--with-apr-util=<var>REP</var>|<var>FICHIER</var></code></dt>
            <dd>Les utilitaires pour la Bibliothèque pour la portabilité
    	d'Apache ou Apache Portable Runtime Utilities (APU) font partie de la
    	distribution des sources de httpd et sont compilés
    	automatiquement avec le serveur HTTP. Si vous voulez utiliser
    	des APU déjà installés à la place, vous devez indiquer à
    	<code>configure</code> le chemin du script
    	<code>apu-config</code>. Vous pouvez spécifier le chemin absolu
    	et le nom ou le répertoire d'installation des APU.
    	<code>apu-config</code> doit se trouver dans ce répertoire ou
    	dans le sous-repertoire <code>bin</code>.</dd>
    
            <dt><code>--with-ssl=<var>REP</var></code></dt>
            <dd>Si <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> a été activé,
    	<code>configure</code> recherche une installation d'OpenSSL.
    	Vous pouvez définir le répertoire de la boîte à outils SSL/TLS à
    	la place.</dd>
    
            <dt><code>--with-z=<var>REP</var></code></dt>
            <dd><code>configure</code> recherche automatiquement une
    	bibliothèque <code>zlib</code> installée si la configuration de
    	vos sources en nécessite une (par exemple lorsque
    	<code class="module"><a href="../mod/mod_deflate.html">mod_deflate</a></code> est activé). Vous pouvez définir le
    	répertoire de la bibliothèque de compression à la place.</dd>
          </dl>
    
          <p>De nombreuses fonctionnalités du serveur HTTP Apache, y compris
          les directives <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> DBM de
          <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> et <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code>
          utilisent une base de données simple
          de la forme clé/valeur pour une recherche rapide d'informations.
          SDBM, inclus dans les APU, est donc toujours disponible. Si vous
          souhaitez utiliser d'autres types de bases de données, utilisez
          les options suivantes afin de les activer :</p>
    
          <dl>
            <dt><code>--with-gdbm[=<var>chemin</var>]</code></dt>
            <dd>Si aucun <var>chemin</var> n'est spécifié,
    	<code>configure</code> va rechercher les fichiers d'en-têtes et
    	les bibliothèques d'une installation DBM GNU dans les chemins
    	standards. Avec un <var>chemin</var> explicite,
    	<code>configure</code> recherchera les fichiers concernés dans
    	<code><var>chemin</var>/lib</code> et
    	<code><var>chemin</var>/include</code>. En fait,
    	<var>chemin</var> permet de spécifier plusieurs chemins
    	d'en-têtes et bibliothèques spécifiques en les séparant par des
    	caractères ':'.</dd>
    
            <dt><code>--with-ndbm[=<var>chemin</var>]</code></dt>
            <dd>Identique à <code>--with-gdbm</code>, mais recherche une
    	installation de New DBM.</dd>
    
            <dt><code>--with-berkeley-db[=<var>chemin</var>]</code></dt>
            <dd>Identique à <code>--with-gdbm</code>, mais recherche une
    	installation de Berkeley DB.</dd>
          </dl>
    
          <div class="note"><h3>Note</h3>
            <p>Les options DBM sont fournies par les APU et passées en
    	paramètres à son script de configuration. Elles sont inutiles
    	lorsqu'on utilise des APU déjà installés définis par
    	<code>--with-apr-util</code>.</p>
            <p>Vous pouvez utiliser plusieurs implémentations DBM avec votre
    	serveur HTTP. Le type DBM approprié sera choisi au cours de la
    	configuration de l'exécution à chaque démarrage.</p>
          </div>
        
      
    
      <h3><a name="supportopt" id="supportopt">Options pour les programmes de
      support</a></h3>
        <dl>
          <dt><code>--enable-static-support</code></dt>
          <dd>Permet de compiler une version des binaires de support liés
          statiquement. En d'autres termes, la compilation produira un
          exécutable indépendant comportant toutes les bibliothèques
          nécessaires. Sans cette option, les binaires de supports sont liés
          dynamiquement.</dd>
    
          <dt><code>--enable-suexec</code></dt>
          <dd>Utilisez cette option pour activer la programme
          <code class="program"><a href="../programs/suexec.html">suexec</a></code>, qui vous permet de définir un uid et un
          gid pour les processus lancés. <strong>N'utilisez cette option que
          si vous maîtrisez toutes les implications en matière de sécurité
          de l'exécution d'un binaire suid sur votre serveur.</strong>
          D'autres options permettent de configurer
          <code class="program"><a href="../programs/suexec.html">suexec</a></code> comme décrit <a href="#suexec">ci-dessous</a>.</dd>
        </dl>
    
        <p>Il est possible de lier statiquement le binaire d'un programme
        support particulier en utilisant les options suivantes :</p>
    
        <dl>
          <dt><code>--enable-static-ab</code></dt>
          <dd>Compile une version liée statiquement du programme
          <code class="program"><a href="../programs/ab.html">ab</a></code>.</dd>
    
          
          <dt><code>--enable-static-checkgid</code></dt>
          <dd>&gt;Compile une version liée statiquement du programme
          <code>checkgid</code>.</dd>
    
          <dt><code>--enable-static-htdbm</code></dt>
          <dd>Compile une version liée statiquement du programme <code class="program"><a href="../programs/htdbm.html">htdbm</a></code>.</dd>
    
          <dt><code>--enable-static-htdigest</code></dt>
          <dd>Compile une version liée statiquement du programme <code class="program"><a href="../programs/htdigest.html">htdigest</a></code>.</dd>
    
          <dt><code>--enable-static-htpasswd</code></dt>
          <dd>Compile une version liée statiquement du programme <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>.</dd>
    
          <dt><code>--enable-static-logresolve</code></dt>
          <dd>Compile une version liée statiquement du programme <code class="program"><a href="../programs/logresolve.html">logresolve</a></code>.</dd>
    
          <dt><code>--enable-static-rotatelogs</code></dt>
          <dd>Compile une version liée statiquement du programme <code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code>.</dd>
        </dl>
    
        <h4><a name="suexec" id="suexec">Options de configuration de <code>suexec</code></a></h4>
          
          <p>Les options suivantes permettent de définir avec précision le
          comportement du programme <code class="program"><a href="../programs/suexec.html">suexec</a></code>. Voir <a href="suexec.html#install">Configurer et installer suEXEC</a>
    	pour plus de détails.</p>
    
          <dl>
            <dt><code>--with-suexec-bin</code></dt>
            <dd>Définit le chemin du binaire <code class="program"><a href="../programs/suexec.html">suexec</a></code>. La
    	valeur par défaut est <code>--sbindir</code> (voir <a href="#directoryfinetuning">Définition précise des répertoires
    	d'installation</a>).</dd>
    
            <dt><code>--with-suexec-caller</code></dt>
            <dd>Définit l'utilisateur qui a l'autorisation d'appeler
    	<code class="program"><a href="../programs/suexec.html">suexec</a></code>. Il est en général souhaitable que ce
    	soit le même que celui sous lequel <code class="program"><a href="../programs/httpd.html">httpd</a></code>
    	s'exécute.</dd>
    
            <dt><code>--with-suexec-docroot</code></dt>
            <dd>Définit l'arborescence des répertoires dans laquelle le
    	lancement des exécutables via <code class="program"><a href="../programs/suexec.html">suexec</a></code> est
    	autorisé. La valeur par défaut est
    	<code>--datadir/htdocs</code>.</dd>
    
            <dt><code>--with-suexec-gidmin</code></dt>
            <dd>Définit la valeur de GID la plus basse autorisée comme
    	valeur cible pour <code class="program"><a href="../programs/suexec.html">suexec</a></code>. La valeur par
    	défaut est 100.</dd>
    
            <dt><code>--with-suexec-logfile</code></dt>
            <dd>Définit le nom du fichier journal de
    	<code class="program"><a href="../programs/suexec.html">suexec</a></code>. La valeur par défaut est
    	<code>--logfiledir/suexec_log</code>.</dd>
    
            <dt><code>--with-suexec-safepath</code></dt>
            <dd>Définit la valeur de la variable d'environnement
    	<code>PATH</code> pour les processus lancés par
    	<code class="program"><a href="../programs/suexec.html">suexec</a></code>. La valeur par défaut est
    	<code>/usr/local/bin:/usr/bin:/bin</code>.</dd>
    
            <dt><code>--with-suexec-userdir</code></dt>
            <dd>Définit le sous-répertoire du répertoire utilisateur qui
    	contient tous les exécutables pouvant être lancés par
    	<code class="program"><a href="../programs/suexec.html">suexec</a></code>. Cette option est nécessaire si vous
    	souhaitez utiliser <code class="program"><a href="../programs/suexec.html">suexec</a></code> avec des
    	répertoires utilisateurs (définis via
    	<code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code>). La valeur par défaut est
    	<code>public_html</code>.</dd>
    
            <dt><code>--with-suexec-uidmin</code></dt>
            <dd>Définit la valeur d'UID la plus basse autorisée comme
    	valeur cible pour <code class="program"><a href="../programs/suexec.html">suexec</a></code>. La valeur par
    	défaut est 100.</dd>
    
            <dt><code>--with-suexec-umask</code></dt>
            <dd>Définit le masque de permissions <code>umask</code> pour les
    	processus lancés par <code class="program"><a href="../programs/suexec.html">suexec</a></code>. Il correspond
    	par défaut au masque défini par la configuration de votre
    	système.</dd>
          </dl>
        
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="env" id="env">Variables d'environnement</a></h2>
      <p>Certaines variables d'environnement permettent de modifier les
      choix effectués par <code>configure</code>, ou d'aider ce dernier à
      trouver les bibliothèques et programmes possédant des noms et chemins
      non standards.</p>
    
      
      <dl>
        <dt><code>CC</code></dt>
        <dd>Définit la commande du compilateur C à utiliser pour la
        compilation.</dd>
    
        <dt><code>CFLAGS</code></dt>
        <dd>Définit les paramètres du compilateur C que vous voulez utiliser
        pour la compilation.</dd>
    
        <dt><code>CPP</code></dt>
        <dd>Définit la commande du préprocesseur C à utiliser.</dd>
    
        <dt><code>CPPFLAGS</code></dt>
        <dd>Définit les paramètres du préprocesseur C/C++, par exemple
        <code>-I<var>répertoire-include</var></code>, si certains de vos
        fichiers d'en-têtes se trouvent dans le répertoire non standard
        <var>répertoire-include</var>.</dd>
    
        <dt><code>LDFLAGS</code></dt>
        <dd>Définit les paramètres de l'éditeur de liens, par exemple
        <code>-L<var>répertoire-lib</var></code>, si certaines de vos
        bibliothèques se trouvent dans le répertoire non standard
        <var>répertoire-lib</var>.</dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/configure.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/configure.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htpasswd.html.tr.utf8���������������������������������������������0000664�0001751�0001751�00000045045�14743132254�022732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htpasswd - Temel kimlik doğrulama dosyalarını yönetir - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>htpasswd - Temel kimlik doğrulama dosyalarını yönetir</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htpasswd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.</div>
    
        <p><code><strong>htpasswd</strong></code>, HTTP kullanıcılarının temel
        kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının
        saklanmasında kullanılacak düz metin dosyalarını oluşturmak ve güncellemek
        için kullanılır. <code><strong>htpasswd</strong></code>, güncelleme
        sırasında yazmak veya okumak için bir dosyaya erişemezse beklenen hiçbir
        işlemi yapmaz ve hata vererek çıkar.</p>
    
        <p>Apache HTTP sunucusunun mevcut özkaynaklarının kullanımı
        sadece <code><strong>htpasswd</strong></code> tarafından oluşturulan
        dosyalarda listelenmiş kullanıcılara tahsis edilebilir.
        <code><strong>htpasswd</strong></code> sadece düz metin dosyalarda
        saklanmış kullanıcı isimlerini ve parolalarını yönetirse de, diğer veri
        saklama türleri için parolayı şifreleyip gösterebilir. Bir DBM veritabanı
        kullanmak isterseniz <strong><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></strong> ve
        <strong><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></strong> sayfasına bakınız.</p>
    
        <p><code><strong>htpasswd</strong></code>, parolaları şifrelemek için
        bcrypt, Apache'nin kendine özgü MD5 algoritması, SHA1 ya da sistemin
        <code>crypt()</code> yordamını kullanır. Bu bakımdan
        <code><strong>htpasswd</strong></code> tarafından yönetilen dosyalar farklı
        algoritmalarla şifrelenmiş parolalar içerebilir.</p>
    
        <p>Bu kılavuz sayfası sadece komut satırı değiştirgelerini listeler.
        Kullanıcı kimlik doğrulamasını
        <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong>'de yapılandırmak için gerekli
        yönergelerle ilgili ayrıntılar için Apache dağıtımının bir parçası olan
        ve <a href="http://httpd.apache.org/"> http://httpd.apache.org/</a>
        adresinde de bulunan Apache HTTP Sunucusu Belgelerine bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Çıkış Durumu</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Örnekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Güvenlik Değerlendirmeleri</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#restrictions">Kısıtlamalar</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></li><li>Kaynak paketinin support/SHA1 dizinindeki betikler.</li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>htpasswd</strong>
        [ -<strong>c</strong> ]
        [ -<strong>i</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ] <var>parola-dosyası</var> <var>kullanıcı</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>b</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ]
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ] <var>parola-dosyası</var> <var>kullanıcı</var>
        <var>parola</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>n</strong>
        [ -<strong>i</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ] <var>kullanıcı</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>nb</strong>
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>bedel</var> ] <var>kullanıcı</var>
        <var>parola</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><strong>-b</strong></code></dt>
        <dd>Betik kipi; parola için istek yapmak yerine parola komut satırından
        verilir. <strong>Parola komut satırında görünür</strong> olacağından çok
        dikkatli kullanmak gerekir. Betik kullanımı için
        <code><strong>-i</strong></code> seçeneğine bakınız.
        2.4.4 ve sonraki sürümler içindir.</dd>
    
        <dt><code><strong>-i</strong></code></dt>
        <dd>Parolayı doğrulamaksızın standart girdiden okur (betik kullanımı
        için).</dd>
    
        <dt><code><strong>-c</strong></code></dt>
        <dd><code><var>parola-dosyası</var></code> oluşturur. Dosya mevcutsa,
        dosya silinip yeniden yazılır. Bu seçenek
        <code><strong>-n</strong></code> seçeneği ile birlikte kullanılamaz.</dd>
    
        <dt><code><strong>-n</strong></code></dt>
        <dd>Sonuçları veritabanında güncellemek yerine standart çıktıya gönderir.
        Bu seçenek, Apache'nin metin veriler içermeyen veri depolarına dahil
        edilebilecek parolaları üretmekte yararlıdır.
        <code><var>parola-dosyası</var></code> belirtilmediğinden, bu seçenek
        komut satırı sözdizimini değiştirir. Bu seçenek
        <code><strong>-c</strong></code> seçeneği ile birlikte kullanılamaz.</dd>
    
        <dt><code><strong>-m</strong></code></dt>
        <dd>Parolalar için MD5 şifrelemesi kullanılır.
        Bu 2.2.18 sürümünden beri öntanımlıdır.</dd>
    
        <dt><code><strong>-B</strong></code></dt>
        <dd>Parolalar için bcrypt şifrelemesi kullanılır. Şu an için çok güvenli
        kabul edilmektedir.</dd>
    
        <dt><code><strong>-C</strong>  <var>bedel</var></code></dt>
        <dd>Bu seçenek sadece <code><strong>-B</strong></code> (bcrypt şifrelemesi)
        seçeneği ile birlikte kullanılabilir. Bcrypt algoritmasına hesaplama
        süresini belirtir (daha yüksek değerler daha güvenlidir, öntanımlı 5,
        geçerli değerler: 4 - 17).</dd>
    
        <dt><code><strong>-d</strong></code></dt>
        <dd>Parolaları şifrelemek için <code>crypt()</code> kullanılır.
        <code><strong>htpasswd</strong></code> tarafından tüm platformlarda
        destekleniyor olsa da Windows, Netware ve TPF üzerinde
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> sunucusu tarafından desteklenmez. Bu algoritma
        günümüz standartlarında <strong>güvenilmez</strong> kabul
        edilmektedir. 2.2.17 sürümüne kadar öntanımlı algoritma olarak
        kullanılmıştı.</dd>
    
        <dt><code><strong>-s</strong></code></dt>
        <dd>Parolalar için SHA şifrelemesi kullanılır. LDAP Dizin değişim
        biçemini (ldif) kullanarak Netscape sunucularına/sunucularından göçü
        kolaylaştırır.Bu algoritma günümüz standartlarında
        <strong>güvenilmez</strong> kabul edilmektedir.</dd>
    
        <dt><code><strong>-p</strong></code></dt>
        <dd>Düz metin parolalar kullanılır. <code><strong>htpasswd</strong></code>
        tarafından tüm platformlarda destekleniyor olsa da Windows, Netware ve
        TPF üzerinde <code class="program"><a href="../programs/httpd.html">httpd</a></code> sunucusu tarafından sadece düz
        metin parolalar kabul edilir.</dd>
    
        <dt><code><strong>-D</strong></code></dt>
        <dd>Kullanıcıyı siler. Kullanıcı belirtilen dosyada mevcutsa
        silinir.</dd>
    
        <dt><code>-v</code></dt>
        <dd>Parolayı doğrular. Verilen parolayı belitilen htpasswd dosyasında
          saklanan kullanıcı parolası ile karşılaştırarak doğrulama yapar.
          2.4.5 ve sonraki sürümler içindir.</dd>
    
        <dt><code><var>parola-dosyası</var></code></dt>
        <dd>Kullanıcı ismini ve parolasını içeren dosyanın ismi.
        <code><strong>-c</strong></code> seçeneği verilmişse ve dosya mevcut
        değilse oluşturulur, dosya mevcutsa silinip yeniden oluşturulur.</dd>
    
        <dt><code><var>kullanıcı</var></code></dt>
        <dd><code><var>parola-dosyası</var></code>'nda oluşturulacak veya
        güncellenecek kullanıcı ismi. <code><var>kullanıcı</var></code> bu
        dosyada mevcut değilse yeni bir girdi eklenir. Girdi mevcutsa parolası
        değiştirilir.</dd>
    
        <dt><code><var>parola</var></code></dt>
        <dd>Şifrelenip dosyada saklanacak düz metin parola. Sadece
        <code><strong>-b</strong></code> seçeneği ile kullanılır.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Çıkış Durumu</a></h2>
        <p><code><strong>htpasswd</strong></code>, kullanıcı ismi ve parolasını DBM
        dosyasına başarıyla eklemiş veya güncellemişse <code>0</code>, dosyalara
        erişirken bir sorun çıkmışsa <code>1</code>, komut satırında bir
        sözdizimi hatası varsa <code>2</code>, parola etkileşimli alınmış fakat
        girdi ile eşleşme sağlanamamışsa <code>3</code>, işlem kesintiye
        uğramışsa <code>4</code>, bir değer çok uzunsa <code>5</code> (kullanıcı,
        parola, dosya ismi veya açıklama), kullanıcı ismi kuraldışı karakter
        içeriyorsa (<a href="#restrictions">Kısıtlamalar</a> bölümüne bakınız)
        <code>6</code> ve dosya geçerli bir DBM parola dosyası değilse
        <code>7</code> değeriyle döner.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Örnekler</a></h2>
        <div class="example"><p><code>
          htpasswd /usr/local/etc/apache/.htpasswd-users jsmith
        </code></p></div>
    
        <p><code>jsmith</code> kullanıcısı için parolayı ekler veya değiştirir.
        Parolayı vermesi için kullanıcıya parola isteği yapılır.
        Parola takviyeli Apache MD5 algoritması ile şifrelenir. Dosya mevcut
        değilse <code><strong>htpasswd</strong></code> beklenen hiçbir işlemi
        yapmadan bir hata vererek çıkar.</p>
    
        <div class="example"><p><code>
          htpasswd -c /home/doe/public_html/.htpasswd jane
        </code></p></div>
    
        <p>Yeni bir dosya oluşturur ve kullanıcı <code>jane</code> için kaydı bir
        girdi olarak bu dosyaya yazar. Dosya mevcutsa fakat okunamıyor veya
        yazılamıyorsa dosyada bir değişiklik yapılmaz ve
        <code><strong>htpasswd</strong></code> bir ileti gösterip bir hata durumu
        ile çıkar.</p>
    
        <div class="example"><p><code>
          htpasswd -db /usr/web/.htpasswd-all jones Pwd4Steve
        </code></p></div>
    
        <p>Komut satırından verilen parolayı (<code>Pwd4Steve</code>) <code>crypt()</code>
        algoritmasıyla şifreler ve bunu belirtilen dosyada saklar.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Güvenlik Değerlendirmeleri</a></h2>
        <p><code><strong>htpasswd</strong></code> tarafından yönetilen parola
        dosyalarına sunucunun URI uzayından erişilememelidir; yani dosya bir
        tarayıcı ile okunabilecek bir yerde bulunmamalıdır.</p>
    
        <p>Bu program bir setuid çalıştırılabiliri olarak güvenilir olmadığından
        <em>setuid yapılmamalıdır</em>.</p>
    
        <p>Komut satırında parolanın şifrelenmemiş olarak görünmesi sebebiyle
        <code><strong>-b</strong></code> seçeneğinin kullanımından kaçınılmasını
        öneriyoruz.</p>
    
        <p><code>crypt()</code> algoritması kullanılırken, parolayı
        şekillendirmek için parolanın ilk 8 baytının kullanılacağına dikkat
        ediniz. Eğer parola 8 bayttan uzunsa kalanlar bir uyarı verilmeksizin
        iptal edilir.</p>
    
        <p>SHA şifreleme biçeminde tuz kullanılmaz; yani, bir parolanın
        sadece bir şifreli gösterimi olabilir. <code>crypt()</code> ve
        MD5 biçemleri parolanın önüne rasgele üretilmiş bir tuz dizgesi
        eklediklerinden sözlük saldırılarına karşı daha dayanıklıdırlar.</p>
    
        <p>SHA ve <code>crypt()</code> biçimleri günümüz standartlarında
        <strong>güvenilmez</strong> kabul edilmektedir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="restrictions" id="restrictions">Kısıtlamalar</a></h2>
        <p>Windows platformuda, <code><strong>htpasswd</strong></code>
        ile şifrelenen parolalar <code>255</code> karakterden daha uzun olamaz.
        255 karakterden sonrası kırpılır.</p>
    
        <p><code><strong>htpasswd</strong></code> tarafından kullanılan MD5
        algoritması Apache yazılımına özeldir; bu algoritma ile şifrelenen
        parolalar başka HTTP sunucularında kullanılamayabilir.</p>
    
        <p>Kullanıcı isimleri <code>255</code> bayttan uzun olamaz ve iki nokta
        imi (<code>:</code>) içeremez.</p>
        
        <p>Bir bcrypt parolasının karma değerini hesaplamanın maliyeti, 
        <code>-C</code> seçeneğinde belirtilen tur sayısı ile artar.
        <code>apr-util</code> kitaplığının <code>1.6.0</code> ve sonraki 
        sürümleri için azami tur sayısı 17 ile sınırlıdır.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htpasswd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htpasswd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htcacheclean.html.tr.utf8�����������������������������������������0000664�0001751�0001751�00000036145�14743132254�023500� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htcacheclean - Disk arabelleğini temizler - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>htcacheclean - Disk arabelleğini temizler</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htcacheclean.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code><strong>htcacheclean</strong></code>,
        <code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code> deposunun boyutlarını belli sınırlar
        içinde veya kullanımdaki dosya düğümlerinin sınırları içinde tutmak için
        kullanılır. Bu araç ya elle ya da bir artalan süreci
        olarak çalıştırılır. Artalan süreci olarak çalıştırıldığında, silinecek
        arabellek içeriğini tespit etmek için arabellek dizinlerine belli
        aralıklarla bakmak dışında uykuda olur. Artalan sürecini temiz olarak
        durdurmak için TERM veya INT sinyali göndermeniz yeterlidir. Elle
        çalıştırıldığında, silinecek arabellek içeriğini tespit etmek için
        arabellek dizinlerine bir kereliğine bakar. Bir veya daha fazla URL
        belirtilmesi durumunda arabellekte olanlar arabellekten silinir.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#delete">Belli bir URL'nin silinmesi</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#list">Arabellekteki URL'lerin listelenmesi</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Çıkış Durumu</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>htcacheclean</strong>
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>r</strong> ]
        [ -<strong>n</strong> ]
        [ -<strong>R</strong><var>boyut</var> ]
        -<strong>p</strong><var>yol</var>
        [ -<strong>l</strong><var>sınır</var> |
        [ -<strong>L</strong><var>sınır</var> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>n</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>i</strong> ]
        [ -<strong>P</strong><var>piddosyası</var> ]
        [ -<strong>R</strong><var>boyut</var> ]
        -<strong>d</strong><var>süre</var>
        -<strong>p</strong><var>yol</var>
        [ -<strong>l</strong><var>sınır</var> |
        [ -<strong>L</strong><var>sınır</var> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>v</strong> ]
        [ -<strong>R</strong><var>boyut</var> ]
        -<strong>p</strong><var>yol</var>
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>R</strong><var>boyut</var> ]
        -<strong>p</strong><var>yol</var>
        <var>url</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><strong>-d</strong><var> süre</var></code></dt>
        <dd>Artalanda çalışarak <code><var>süre</var></code> dakikada bir
        arabelleği temizler. Bu seçenek <code><strong>-D</strong></code>,
        <code><strong>-v</strong></code> ve <code><strong>-r</strong></code>
        seçenekleri ile birlikte kullanılamaz. Artalan sürecini temiz olarak
        sonlandırmak için <code>SIGTERM</code> veya <code>SIGINT</code> göndermek
        yeterlidir.</dd>
    
        <dt><code><strong>-D</strong></code></dt>
        <dd>Kuru kuruya çalışıp, hiçbir şeyi silmez.
        <code><strong>-d</strong></code> seçeneği ile birlikte kullanılamaz. Kuru
        çalıştırma sırasında <code><strong>-t</strong></code> seçeneği ile dizinler
        silinmek istenirse, statlarda silinmiş görünen dosya düğümleri silinmiş
        dizinler olarak hesaba katılmaz ve tahmini olarak imlenir.</dd>
    
        <dt><code><strong>-v</strong></code></dt>
        <dd>Çıktı daha ayrıntılı olur. <code><strong>-d</strong></code> seçeneği
        ile birlikte kullanılamaz.</dd>
    
        <dt><code><strong>-r</strong></code></dt>
        <dd>İyice temizlik yapılır. Bunun için Apache HTTP sunucusunun
        çalışmadığı varsayılır (aksi takdirde arabellek içeriği bozulabilir).
        <code><strong>-t</strong></code> seçeneğinin de uygulanmasını sağlar.
        <code><strong>-d</strong></code> seçeneği ile birlikte kullanılamaz.</dd>
    
        <dt><code><strong>-n</strong></code></dt>
        <dd>Nazik olur. Diğer süreçlerin yararına daha yavaş çalışır. (a) disk
        G/Ç işlemlerinde gecikmeler olursa ve (b) çekirdek bu arada başka bir
        süreci öne çekmişse <code><strong>htcacheclean</strong></code> uyumayı
        tercih edecektir.</dd>
    
        <dt><code><strong>-t</strong></code></dt>
        <dd>Tüm boş dizinleri siler. Öntanımlı olarak, sadece arabellek dosyaları
        silinirse de bazı yapılandırmalarda büyük miktarda dizin oluşturulması bu
        seçeneğin kullanılmasını gerektirebilir. Yapılandırmanız çok sayıda dizin
        gerektiriyorsa ve dosya düğümlerinin veya dosya ayırma tablolarının
        tükenmesi sözkonusu ise bu seçeneğin kullanılması önerilir.</dd>
    
        <dt><code><strong>-p</strong><var> yol</var></code></dt>
        <dd><code><var>yol</var></code>, disk arabelleğinin kök dizini olarak
        belirtilir. <code class="directive"><a href="../mod/mod_cache_disk.html#cacheroot">CacheRoot</a></code>
        yönergesinde belirtilen dizin olmalıdır.</dd>
    
        <dt><code><strong>-P</strong><var>piddosyası</var></code></dt>
        <dd>Artalan süreci olarak çalışmada süreç kimliğinin yazılacağı dosyanın
        adını belirtmek için kullanılır.</dd>
    
        <dt><code><strong>-R</strong><var>boyut</var></code></dt>
        <dd>Disk bloklarının boyunu denkleştirmek için yuvarlanacak üst boyutu
        belirtmekte kullanılır. Arabellek bölümünün blok boyutunu belirler.</dd>
    
        <dt><code><strong>-l</strong><var> sınır</var></code></dt>
        <dd><code><var>sınır</var></code>, disk arabelleğinin toplam boyutu
        olarak belirtilir. Değerin öntanımlı olarak bayt cinsinden belirtileceği
        varsayılır. Değerin sonuna kilobayt için <code>K</code>, megabayt
        <code>M</code>, Gbayt için <code>G</code>  harfi konulabilir.</dd>
    
        <dt><code><strong>-L</strong><var>limit</var></code></dt>
        <dd>Disk arabellek dosyası düğümü toplamının sınırını belirlemekte
        kullanılır. Değerin sonuna kilobayt için <code>K</code>, megabayt
        <code>M</code>, Gbayt için <code>G</code>  harfi konulabilir.</dd>
    
        <dt><code><strong>-i</strong></code></dt>
        <dd>Akıllı olup sadece disk arabelleği değiştiği zaman çalışır. Bu
        seçenek <code><strong>-d</strong></code> seçeneği ile birlikte
        belirtilmek zorundadır.</dd>
    
        <dt><code><strong>-a</strong></code></dt>
        <dd>O an arabellekte saklanmakta olan URL'leri listeler. Birden fazla aynı
        URL varsa yalnız biri listelenir.</dd>
    
        <dt><code><strong>-A</strong></code></dt>
        <dd>O an arabellekte saklanmakta olan URL'leri öznitelikleri ile listeler.
        Öznitelikler şu sırayla verilir: url, header size, body size, status,
        entity version, date, expiry, request time, response time, body present,
        head request</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="delete" id="delete">Belli bir URL'nin silinmesi</a></h2>
        <p><code><strong>htcacheclean</strong></code> tarafından aktarılan URL'ler
        arabellekten silinir. Bir URL birden fazla mevcutsa hepsi silinir.</p>
    
        <p>Ters vekilli bir URL silinmişse, etkin URL <strong>Host</strong> başlığı
        <strong>port</strong>, <strong>yol</strong> ve <strong>sorgu</strong> ile
        oluşturulur. Bir sorgu dizgesi olsun olmasın, URL içinde '?' daima açıkça
        belirtilmelidir. Örneğin, <strong>localhost</strong> sunucusundaki
        <strong>/</strong> yolu silinmek istenirse silinecek URL
        <strong>http://localhost:80/?</strong> olurdu.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="list" id="list">Arabellekteki URL'lerin listelenmesi</a></h2>
        <p><code><strong>htcacheclean</strong></code>'e
        <code><strong>-a</strong></code> veya <code><strong>-A</strong></code>
        seçeneğinin aktarılmasıyla, arabellekteki URL'ler bulundukça her satıra bir
        URL gelecek biçemde listelenir. <code><strong>-A</strong></code> seçeneği
        URL'nin ardından arabellek içeriğini tamamını şu sırayla dökümler:</p>
    
        <dl>
            <dt>url</dt><dd>Öğenin URL'si.</dd>
            <dt>header size</dt><dd>Bayt cinsinden başlık uzunluğu.</dd>
            <dt>body size</dt><dd>Bayt cinsinden gövde uzunluğu.</dd>
            <dt>status</dt><dd>Arabellekteki yanıtın durumu.</dd>
            <dt>entity version</dt><dd>Öğenin silinmeksizin kaç kere
              doğrulandığı.</dd>
            <dt>date</dt><dd>Yanıt tarihi.</dd>
            <dt>expiry</dt><dd>Yanıtın zaman aşımı tarihi.</dd>
            <dt>request time</dt><dd>İsteğin başlama zamanı.</dd>
            <dt>response time</dt><dd>İsteğin bitiş zamanı.</dd>
            <dt>body present</dt><dd>0 ise istekle birlikte gövde saklanmaz, 1 ise
              saklanır.</dd>
            <dt>head request</dt><dd>1 ise, öğe, gövde olmaksızın arabellekli bir
              HEAD isteği içerir, 0 ise içermez.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Çıkış Durumu</a></h2>
        <p><code><strong>htcacheclean</strong></code>, tüm işlemler başarıyla
        yerine getirildiğinde <code>0</code>, aksi takdirde <code>1</code>
        döndürür. Bir URL belirtildiğinde, bu URL arablleklenmi ve silinmişse
        <code>0</code>, aksi takdirde <code>2</code> döndürür. URL'nin silinmesi
        sırasında bir hata oluşursa <code>1</code> döndürür.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htcacheclean.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htcacheclean.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htpasswd.html.ko.euc-kr�������������������������������������������0000664�0001751�0001751�00000032663�14743132254�023220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htpasswd - basic authentication  
          Ѵ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>htpasswd - basic authentication  
          Ѵ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/htpasswd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><code>htpasswd</code> HTTP basic authentication 
        ڸ ȣ ϴ Ϲ ϰ Ѵ.
        <code>htpasswd</code>  ų   ٸ,
        ¸ ȯϰ ƹ͵  ʴ´.</p>
    
        <p>ġ  ڿ <code>htpasswd</code>  Ͽ
         ڿԸ   ִ.  α׷ ڸ
        ȣ ϴ Ϲ  Ѵ. ׷ ٸ ڷ
          ȣ  ȣȭϿ   ִ. DBM
        ͺ̽ Ϸ <a href="dbmmanage.html">dbmmanage</a> ϶.</p>
    
        <p><code>htpasswd</code> ġ Ư MD5 Ȥ ý
        <code>crypt()</code> Ͽ ȣ ȣȭѴ.
        <code>htpasswd</code> ϴ    ȣ
           ִ. ,  Ͽ MD5 ȣȭ ȣ
        ϴ ڿ <code>crypt()</code> ȣȭ ȣ
        ϴ      ִ.</p>
    
        <p> manpage  ɼǸ Ѵ. <a href="httpd.html">httpd</a>  ϴ þ
          ġ  Եְ <a href="http://httpd.apache.org">http://httpd.apache.org/</a>
          ִ ġ  ϶.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">ڵ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Ȼ  </a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#restrictions"></a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="httpd.html">httpd</a></li><li> SHA1 ϴ ũƮ ִ.</li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
        <p><code><strong>htpasswd</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> ]
        [ -<strong>D</strong> ] <var>passwdfile</var> <var>username</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>b</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>d</strong> |
          -<strong>p</strong> |
          -<strong>s</strong> ] 
        [ -<strong>D</strong> ]  <var>passwdfile</var> <var>username</var>
        <var>password</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>n</strong>
        [ -<strong>m</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ] <var>username</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>nb</strong>
        [ -<strong>m</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ] <var>username</var> <var>password</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
        <dl>
        <dt><code>-b</code></dt>
        <dd>ġ(batch) 带 Ѵ. <em> </em>, ȣ
        ʰ ࿡ ޴´. ࿡ <strong>ȣ
         巯Ƿ</strong>,  ɼ ſ ؼ ؾ
        Ѵ.</dd>
    
        <dt><code>-c</code></dt>
        <dd><var>passwdfile</var> . <var>passwdfile</var>
        ̹ Ѵٸ, .  ɼ <code>-n</code> ɼǰ
           .</dd>
    
        <dt><code>-n</code></dt>
        <dd> ʰ  ǥ Ѵ.
        ġ ̿   ȣ Ҷ ϴ.
        (׻ ù° ƱԸƮ) <var>passwdfile</var> ƱԸƮ
        ⶧   ٸ. <code>-c</code> ɼǰ
           .</dd>
    
        <dt><code>-m</code></dt>
        <dd>MD5 Ͽ ȣ ȣȭѴ. Windows, Netware,
        TPF ⺻̴.</dd>
    
        <dt><code>-d</code></dt>
        <dd><code>crypt()</code> Ͽ ȣ ȣȭѴ.
        Windows, Netware, TPF   ÷ ⺻̴.
         ÷ <code>htpasswd</code>    
        , Windows, Netware, TPF <a href="httpd.html">httpd</a>
            ʴ´.</dd>
    
        <dt><code>-s</code></dt>
        <dd>ȣ SHA ȣȭѴ. LDAP 丮ȯ(ldif)
        Ͽ Netscape   ų ö ϴ.</dd>
    
        <dt><code>-p</code></dt>
        <dd>ȣ ״ Ѵ.  ÷ <code>htpasswd</code>
        , Windows, Netware, TPF <a href="httpd.html">httpd</a>
         Ϲ ȣ ޴´.</dd>
    
        <dt><code>-D</code></dt>
        <dd>ڸ Ѵ. htpasswd Ͽ ڸ ִٸ
        Ѵ.</dd>
        
        <dt><code><var>passwdfile</var></code></dt>
        <dd>ڸ ȣ ϴ ϸ. <code>-c</code>
           ٸ  , ִٸ .</dd>
    
        <dt><code><var>username</var></code></dt>
        <dd><var>passwdfile</var> ų  ڸ.
        <var>username</var>  Ͽ ٸ ׸ ߰Ѵ.
        ִٸ ȣ Ѵ.</dd>
    
        <dt><code><var>password</var></code></dt>
        <dd>ȣȭϿ Ͽ  ȣ.  <code>-b</code>
        ɼǰ    ִ.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">ڵ</a></h2>
        <p><code>htpasswd</code> <var>passwdfile</var> ڸ
        ȣ  ߰ϰų   ("") ڵ
        0 ȯѴ. <code>htpasswd</code> Ͽ Ҷ 
        ߻  <code>1</code>,   ߸ 
        <code>2</code>, Է ȣ Ȯ ٽ Է 
        ġ   <code>3</code>,  ߴܵ 
        <code>4</code>, (ڸ, ϸ, ȣ,  )
         ʹ   <code>5</code>, ڸ ʴ
        ڰ Ե  <a href="#restrictions"> </a> )
        <code>6</code>,  ùٸ ȣ ƴ 
        <code>7</code> ȯѴ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples"></a></h2>
        <div class="example"><p><code>
          htpasswd /usr/local/etc/apache/.htpasswd-users jsmith
        </code></p></div>
    
        <p> <code>jsmith</code> ȣ ߰ϰų Ѵ.
        ڿ ȣ . Windows ýۿ ϸ
        ȣ ġ Ư MD5 ˰ Ͽ ȣȭϰ,
        ƴϸ ý <code>crypt()</code> Լ Ѵ. 
        ٸ <code>htpasswd</code> ƹ ϵ ʰ 
        .</p>
    
        <div class="example"><p><code>
          htpasswd -c /home/doe/public_html/.htpasswd jane
        </code></p></div>
    
        <p>    Ͽ  <code>jane</code>
        ߰Ѵ. ڿ ȣ .   аų
          ٸ, <code>htpasswd</code>  ʰ
          ¸ ȯѴ.</p>
    
        <div class="example"><p><code>
          htpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve
        </code></p></div>
    
        <p> ȣ(<code>Pwd4Steve</code>) MD5 ˰
        ȣȭϿ  Ͽ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Ȼ  </a></h2>
        <p><code>htpasswd</code>  ϴ  ȣ 
        URI   <em>ȵȴ</em>. ,   
           Ѵ.</p>
    
        <p>࿡ ȣȭ ȣ ϱ⶧ <code>-b</code>
        ɼ õ ʴ´.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="restrictions" id="restrictions"></a></h2>
        <p>Windows MPE ÷ <code>htpasswd</code> ȣȭϴ
        ȣ ̸ <code>255</code> ڷ Ѵ.   ȣ
        255ڿ ©.</p>
    
        <p><code>htpasswd</code> ϴ MD5 ˰ ġ
        Ʈ Ư ̴. ̸ Ͽ ȣȭ ȣ
        ٸ    .</p>
    
        <p>ڸ <code>255</code> Ʈ ѵǰ <code>:</code>
        ڸ   .</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/htpasswd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htpasswd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/fcgistarter.html.tr.utf8������������������������������������������0000664�0001751�0001751�00000015231�14743132254�023404� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>fcgistarter - Bir FastCGI betiğini çalıştır - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>fcgistarter - Bir FastCGI betiğini çalıştır</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/fcgistarter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/fcgistarter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/fcgistarter.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p />
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#note">Bilginize</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="note" id="note">Bilginize</a></h2>
        <p>Şimdilik sadece Unix sistemlerinde çalışmaktadır.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>fcgistarter</strong>
        -<strong>c</strong> <var>komut</var>
        -<strong>p</strong> <var>port</var>
        [ -<strong>i</strong> <var>arabirim</var> ]
        -<strong>N</strong> <var>sayı</var>
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><strong>-c</strong> <var>komut</var></code></dt>
        <dd>Çalıştırılacak FastCGI betiğinin mutlak yolu</dd>
    
        <dt><code><strong>-p</strong> <var>port</var></code></dt>
        <dd>Betiğin dinleyeceği port</dd>
    
        <dt><code><strong>-i</strong> <var>arabirim</var></code></dt>
        <dd>Betiğin dinleyeceği arabirim</dd>
    
        <dt><code><strong>-N</strong> <var>sayı</var></code></dt>
        <dd>Betik örneklerinin sayısı</dd>
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/fcgistarter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/fcgistarter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/fcgistarter.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/fcgistarter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdigest.html.ko.euc-kr�������������������������������������������0000664�0001751�0001751�00000016364�14743132254�023176� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htdigest - digest authentication  
    Ѵ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>htdigest - digest authentication  
    Ѵ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/htdigest.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><code>htdigest</code> HTTP  digest authentication
         ڸ, , ȣ ϴ Ϲ 
        Ѵ. ġ  ڿ <code>htdigest</code>
         Ͽ  ڿԸ   ִ.</p>
    
        <p> manpage  ɼǸ Ѵ. <a href="httpd.html">httpd</a> digest authentication
        ϴ þ   ġ  Եְ
        <a href="http://httpd.apache.org">http://httpd.apache.org/</a>
          ִ ġ  ϶.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="httpd.html">httpd</a></li><li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
        <p><code><strong>htdigest</strong> [ -<strong>c</strong> ]
        <var>passwdfile</var> <var>realm</var> <var>username</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
        <dl>
        <dt><code>-c</code></dt>
        <dd><var>passwdfile</var> . <var>passwdfile</var>
        ̹ ִٸ   .</dd>
    
        <dt><code><var>passwdfile</var></code></dt>
        <dd>ڸ, , ȣ  ϸ. <code>-c</code>
            ٸ , ִٸ  
        ٽ .</dd>
    
        <dt><code><var>realm</var></code></dt>
        <dd>ڸ  ̸.</dd>
    
        <dt><code><var>username</var></code></dt>
        <dd><var>passwdfile</var> ų  ڸ. Ͽ
        <var>username</var> ٸ ׸ ߰Ѵ. ִٸ ȣ
        Ѵ.</dd>
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/htdigest.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htdigest.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htpasswd.html.fr.utf8���������������������������������������������0000664�0001751�0001751�00000051576�14740503670�022723� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htpasswd - Gestion des fichiers d'utilisateurs pour
    l'authentification de base - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>htpasswd - Gestion des fichiers d'utilisateurs pour
    l'authentification de base</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htpasswd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htpasswd</code> permet de créer et de maintenir les
        fichiers textes où sont stockés les noms d'utilisateurs et mots de
        passe pour l'authentification de base des utilisateurs HTTP. Si
        <code>htpasswd</code> rencontre un problème d'accès à un fichier,
        que ce soit pour écrire dans le fichier de sortie, ou pour lire le
        fichier d'entrée dans le but de le mettre à jour, il renvoie un code
        d'erreur et n'effectue aucune modification.</p>
    
        <p>Il est possible de limiter l'accès aux ressources du serveur HTTP
        Apache aux seuls utilisateurs présents dans les fichiers créés par
        <code>htpasswd</code>. Ce programme ne sait gérer les noms
        d'utilisateurs et mots de passe que s'ils sont stockés dans des
        fichiers textes. Il peut cependant hacher et afficher les mots de
        passe à des fins d'utilisation dans d'autres types de bases de
        données. Pour utiliser une base de données DBM, voir le programme
        <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> ou <code class="program"><a href="../programs/htdbm.html">htdbm</a></code>.</p>
    
        <p><code>htpasswd</code> hache les mots de passe en utilisant bcrypt, une
        version de MD5 modifiée pour Apache, SHA-1 ou la routine système
        <code>crypt()</code>. Les hachages de type SHA-2 (SHA-256 and SHA-512) sont
        pris en charge pour <code>crypt()</code>. Les fichiers gérés par
        <code>htpasswd</code> peuvent contenir un mélange de différents types de
        codage des mots de passe&nbsp;; par exemple, certaines entrées utilisateur
        pourront comporter des mots de passe hachés avec bcrypt ou MD5, alors que
        d’autres dans le même fichier pourront comporter des mots de passe hachés
        avec <code>crypt()</code>.</p>    
    
        <p>Cette page de manuel ne décrit que les arguments de la ligne de
        commande. Pour plus de détails à propos des directives nécessaires à
        la configuration de l'authentification des utilisateurs dans
        <code class="program"><a href="../programs/httpd.html">httpd</a></code>, voir le manuel Apache qui est fourni avec
        la distribution ou peut être consulté à <a href="http://httpd.apache.org">http://httpd.apache.org/</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Valeur renvoyée</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Exemples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Considérations à propos de sécurité</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#restrictions">Restrictions</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></li><li>Les scripts fournis avec la distibution d'Apache et situés dans
    support/SHA1.</li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>htpasswd</strong>
        [ -<strong>c</strong> ]
        [ -<strong>i</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>2</strong> | 
          -<strong>5</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]  <var>fichier-mots-de-passe</var> <var>nom-utilisateur</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>b</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>2</strong> | 
          -<strong>5</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]  <var>fichier-mots-de-passe</var> <var>nom-utilisateur</var>
        <var>mot-de-passe</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>n</strong>
        [ -<strong>i</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>2</strong> | 
          -<strong>5</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ] <var>nom-utilisateur</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>nb</strong>
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>2</strong> | 
          -<strong>5</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ] <var>nom-utilisateur</var>
        <var>mot-de-passe</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-b</code></dt>
        <dd>Utilise le mode batch ; c'est à dire, extrait le mot de passe de
        la ligne de commande au lieu de le demander à l'opérateur. Cette
        option doit être utilisée avec la plus grande prudence, car
        <strong>le mot de passe est visible en clair</strong> dans la ligne
        de commande. Pour utiliser un script, voir l'option
        <code>-i</code>.
        Disponible à partir de la version 2.4.4 du serveur HTTP Apache.</dd>
    
        <dt><code>-i</code></dt>
        <dd>Lit le mot de passe depuis stdin sans vérification (à utiliser
        dans les scripts).</dd>
    
        <dt><code>-c</code></dt>
        <dd>Crée le <var>fichier-mots-de-passe</var>. Si
        <var>fichier-mots-de-passe</var> existe déjà, il est réécrit et
        tronqué. Cette option ne peut pas être combinée avec l'option
        <code>-n</code>.</dd>
    
        <dt><code>-n</code></dt>
        <dd>Affiche le résultat du traitement sur la sortie standard au lieu
        de mettre à jour le fichier. Ceci peut s'avérer utile pour générer
        des enregistrements de mots de passe qu'Apache pourra utiliser à des
        fins d'inclusion dans des fichiers de données au format autre que
        texte. Cette option modifie la syntaxe de la ligne de commande, car
        l'argument <var>fichier-mots-de-passe</var> (en général le premier)
        est omis. Elle ne peut pas être combinée avec l'option
        <code>-c</code> option.</dd>
    
        <dt><code>-m</code></dt>
        <dd>Utilise le hachage MD5 pour les mots de passe. C'est le
        comportement par défaut (depuis la version 2.2.18).</dd>
    
        <dt><code>-2</code></dt>
        <dd>Utilise les hachages SHA-256 basés sur <code>crypt()</code> pour les
        mots de passe. Pris en charge sur la plupart des plateformes de style Unix.</dd>
    
        <dt><code>-5</code></dt>
        <dd>Utilise les hachages SHA-512 basés sur <code>crypt()</code> pour les
        mots de passe. Pris en charge sur la plupart des plateformes de style Unix.</dd>
    
        <dt><code>-B</code></dt>
        <dd>Utilise bcrypt pour hacher les mots de passe. c'est un
        algorythme de chiffrement actuellement considéré comme sûr.</dd>
    
        <dt><code>-C</code></dt>
        <dd>Ce drapeau n'est autorisé qu'en conjonction avec le drapeau
        <code>-B</code> (hachage bcrypt). Il permet de définir la durée
        de traitement pour l'algorytme bcrypt (plus elle est longue,
        meilleure sera la sécurité, mais inférieure la rapidité). La valeur
        par défaut est 5 et les valeurs autorisées vont de 4 à 17.</dd>
    
        <dt><code>-r</code></dt>
        <dd>Ce drapeau n’est autorisé qu’en combinaison avec les drapeaux
        <code>-2</code> ou <code>-5</code>. Il permet de définir le nombre de passes
        de hachage utilisé pour les algorithmes SHA-2 (un nombre élevé améliore la
        sécurité mais le traitement est plus lent&nbsp;; la valeur par défaut est 5000.</dd>
    
        <dt><code>-d</code></dt>
        <dd>Utilise le hachage <code>crypt()</code> pour les mots de
        passe. Cette option n'est pas supportée par le
        serveur <code class="program"><a href="../programs/httpd.html">httpd</a></code> sous Windows ou Netware. Cet
        algorithme limite la longueur des mots de passe à 8 caractères ; il
        est considéré comme <strong>non sur</strong> du point de vue des
        standards actuels. C'était l'algorithme par défaut jusqu'à la
        version 2.2.17.</dd>
    
        <dt><code>-s</code></dt>
        <dd>Utilise le hachage SHA-1 (160-bit) pour les mots de passe. Facilite la
        migration vers/depuis les serveurs Netscape qui utilisent le format
        LDAP Directory Interchange (ldif). Cet algorithme
        est considéré comme <strong>non sûr</strong> du point de vue des
        normes actuelles.</dd>
    
        <dt><code>-p</code></dt>
        <dd>Enregistre les mots de passe en clair. Bien que
        <code>htpasswd</code> supporte la création des mots de passe en
        clair sur toutes les plates-formes, le démon
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> n'accepte les mots de passe en clair que
        sous Windows et Netware.</dd>
    
        <dt><code>-D</code></dt>
        <dd>Supprime un utilisateur, sous réserve qu'il existe dans le
        fichier spécifié par htpasswd.</dd>
    
        <dt><code>-v</code></dt>
        <dd>Vérifie si le mot de passe fourni correspond au mot de passe de
        l'utilisateur enregistré dans le fichier de mots de passe spécifié.
        Disponible à partir de la version 2.4.5 du serveur HTTP Apache.</dd>
    
        <dt><code><var>fichier-mots-de-passe</var></code></dt>
        <dd>Le nom du fichier contenant les noms d'utilisateurs et mots de
        passe. Avec l'option <code>-c</code>, le fichier est créé s'il
        n'existe pas, ou réécrit et tronqué s'il existe déjà.</dd>
    
        <dt><code><var>nom-utilisateur</var></code></dt>
        <dd>Le nom d'utilisateur à créer ou mettre à jour dans le
        <var>fichier-mots-de-passe</var>. Si <var>nom-utilisateur</var>
        n'existe pas, une nouvelle entrée est ajoutée. Dans le cas
        contraire, le mot de passe est modifié.</dd>
    
        <dt><code><var>mot-de-passe</var></code></dt>
        <dd>Le mot de passe en clair et destiné à être haché puis stocké
        dans le fichier. Cet argument ne s'utilise qu'avec l'option
        <code>-b</code>.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Valeur renvoyée</a></h2>
        <p><code>htpasswd</code> renvoie 0 ("true") si le nom d'utilisateur
        et le mot de passe ont été enregistrés ou mis à jour avec succès
        dans le <var>fichier-mots-de-passe</var>. <code>htpasswd</code>
        renvoie <code>1</code> s'il a rencontré un problème d'accès aux
        fichiers, <code>2</code> si la ligne de commande comportait une
        erreur de syntaxe, <code>3</code> si le mot de passe entré
        interactivement ne correspondait pas au nom d'utilisateur,
        <code>4</code> si l'opération a été interrompue, <code>5</code> si
        une valeur était trop longue (nom-utilisateur, nom-fichier,
        mot-de-passe, ou l'enregistrement résultant), <code>6</code> si le
        nom d'utilisateur contenait des caractères illégaux (voir la section
        <a href="#restrictions">Restrictions</a>), et <code>7</code> si le
        fichier spécifié n'était pas un fichier de mots de passe
        valide.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples</a></h2>
        <div class="example"><p><code>
          htpasswd /usr/local/etc/apache/.utilisateurs-htpasswd jsmith
        </code></p></div>
    
        <p>Ajoute ou modifie le mot de passe de l'utilisateur
        <code>jsmith</code>. Le mot de passe est demandé à l'opérateur. Le
        mot de passe sera haché en utilisant l'algorithme MD5
        modifié pour Apache. Si le fichier spécifié
        n'existe pas, <code>htpasswd</code> renverra un code d'erreur.</p>
    
        <div class="example"><p><code>
          htpasswd -c /home/doe/public_html/.htpasswd jane
        </code></p></div>
    
        <p>Crée un nouveau fichier de mots de passe et y enregistre une
        entrée pour l'utilisateur <code>jane</code>. Le mot de passe est
        demandé à l'opérateur. Si le fichier existe et ne peut être ni lu ni
        écrit, il n'est pas modifié et <code>htpasswd</code> affichera un
        message et renverra un code d'erreur.</p>
    
        <div class="example"><p><code>
          htpasswd -db /usr/web/.htpasswd-tous jones Pwd4Steve
        </code></p></div>
    
        <p>Chiffre le mot de passe spécifié dans la ligne de commande
        (<code>Pwd4Steve</code>) en utilisant l'algorithme
        <code>crypt()</code>, et le stocke dans le fichier spécifié.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Considérations à propos de sécurité</a></h2>
        <p>Les fichiers de mots de passe Web comme ceux que gère
        <code>htpasswd</code> ne doivent <em>pas</em> être situés dans
        l'espace d'URI du serveur Web -- en d'autres termes, il ne doit pas
        être possible d'y accéder à partir d'un navigateur.</p>
    
        <p>En tant qu'exécutable setuid, ce programme n'est pas sûr, et il
        ne faut par conséquent <em>pas</em> lui attribuer de permissions
        setuid.</p>
    
        <p>L'utilisation de l'option <code>-b</code> est déconseillée, car
        avec elle, les mots de passe apparaissent en clair sur la ligne de
        commande.</p>
    
        <p>Notez qu'avec l'algorithme <code>crypt()</code>, seuls les huit
        premiers caractères du mot de passe spécifié sont pris en compte. Si
        le mot de passe spécifié est plus long, les caractères
        supplémentaires sont ignorés.</p>
    
        <p>Le format de hachage SHA-1 n'utilise pas d'amorçage aléatoire
        (salting) : à un mot de passe donné correspond une seule
        représentation hachée. Les formats <code>crypt()</code> et MD5
        permutent la représentation en la préfixant par une chaîne d'amorce
        aléatoire, afin de rendre les attaques de mots de passe à base de
        dictionnaires plus difficiles.</p>
    
        <p>Les algorithmes de chiffrement SHA-1 et <code>crypt()</code> 
        sont considérés comme <strong>non surs</strong> du point de vue des
        standards actuels.</p>
    
        <p>Les formats de <code>crypt()</code> basés sur SHA-2 (SHA-256 et SHA-512)
        sont pris en charge sur la plupart des systèmes de style Unix récents et
        respectent la spécification de <a href="https://www.akkadia.org/drepper/SHA-crypt.txt">https://www.akkadia.org/drepper/SHA-crypt.txt</a>.</p>
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="restrictions" id="restrictions">Restrictions</a></h2>
        <p>Sur les plates-formes Windows, la taille des mots de passe
        hachés avec <code>htpasswd</code> est limitée à <code>255</code>
        caractères. Les mots de passe dont la taille est supérieure seront
        tronqués.</p>
    
        <p>L'algorithme MD5 utilisé par <code>htpasswd</code> est spécifique
        à Apache ; les mots de passe hachés en utilisant cet algorithme
        seront inutilisables sur d'autres serveurs Web.</p>
    
        <p>La taille des noms d'utilisateurs est limitée à <code>255</code>
        octets et ceux-ci ne doivent pas contenir de caractère
        <code>:</code>.</p>
    
        <p>Le coût en performances de la génération de la valeur de hashage d'un mot
        de passe bcrypt augmente avec le nombre de passes spécifié par l'option
        <code>-C</code>. A partir de sa version <code>1.6.0</code>, la bibliothèque
        <code>apr-util</code> limite le nombre de passes à 17.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htpasswd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htpasswd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/httpd.html.en�����������������������������������������������������0000664�0001751�0001751�00000027713�14737241666�021325� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>httpd - Apache Hypertext Transfer Protocol Server - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>httpd - Apache Hypertext Transfer Protocol Server</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/httpd.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>httpd</code> 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.</p>
    
         <p>In general, <code>httpd</code> should not be invoked directly,
         but rather should be invoked via <code class="program"><a href="../programs/apachectl.html">apachectl</a></code> on Unix-based systems or <a href="../platform/windows.html#winsvc">as a service on Windows NT,
         2000 and XP</a> and <a href="../platform/windows.html#wincons">as
         a console application on Windows 9x and ME</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../invoking.html">Starting Apache httpd</a></li><li><a href="../stopping.html">Stopping Apache httpd</a></li><li><a href="../configuring.html">Configuration Files</a></li><li><a href="../platform/">Platform-specific Documentation</a></li><li><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
         <p><code><strong>httpd</strong> [ -<strong>d</strong>
         <var>serverroot</var> ] [ -<strong>f</strong> <var>config</var> ]
         [ -<strong>C</strong> <var>directive</var> ] [ -<strong>c</strong>
         <var>directive</var> ] [ -<strong>D</strong> <var>parameter</var> ]
         [ -<strong>e</strong> <var>level</var> ] [ -<strong>E</strong>
         <var>file</var> ]
         [ <strong>-k</strong> start|restart|graceful|stop|graceful-stop ]
         [ -<strong>h</strong> ]
         [ -<strong>l</strong> ] [ -<strong>L</strong> ] [ -<strong>S</strong> ]
         [ -<strong>t</strong> ] [ -<strong>v</strong> ] [ -<strong>V</strong> ]
         [ -<strong>X</strong> ] [ -<strong>M</strong> ] [ -<strong>T</strong> ]
         </code></p>
    
         <p>On <a href="../platform/windows.html">Windows systems</a>, the
         following additional arguments are available:</p>
    
         <p><code><strong>httpd</strong> [ -<strong>k</strong>
         install|config|uninstall ] [ -<strong>n</strong> <var>name</var> ]
         [ -<strong>w</strong> ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    <dt><code>-d <var>serverroot</var></code></dt>
    
    <dd>Set the initial value for the <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> directive to
    <var>serverroot</var>.  This can be overridden by the ServerRoot
    directive in the configuration file. The default is
    <code>/usr/local/apache2</code>.</dd>
    
    <dt><code>-f <var>config</var></code></dt>
    
    <dd>Uses the directives in the file <var>config</var> on startup. If
    <var>config</var> does not begin with a /, then it is taken to be a
    path relative to the <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code>. The default is
    <code>conf/httpd.conf</code>.</dd>
    
    <dt><code>-k <code>start|restart|graceful|stop|graceful-stop</code></code></dt>
    
    <dd>Signals <code>httpd</code> to start, restart, or stop.  See <a href="../stopping.html">Stopping Apache httpd</a> for more information.</dd>
    
    <dt><code>-C <var>directive</var></code></dt>
    
    <dd>Process the configuration <var>directive</var> before reading
    config files.</dd>
    
    <dt><code>-c <var>directive</var></code></dt>
    
    <dd>Process the configuration <var>directive</var> after reading config
    files.</dd>
    
    
    <dt><code>-D <var>parameter</var></code></dt>
    
    <dd>Sets a configuration <var>parameter </var>which can be used with
    <code class="directive"><a href="../mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> sections
    in the configuration files to conditionally skip or process commands
    at server startup and restart. Also can be used to set certain
    less-common startup parameters including <code>-DNO_DETACH</code>
    (prevent the parent from forking) and <code>-DFOREGROUND</code>
    (prevent the parent from calling <code>setsid()</code> et al).</dd>
    
    <dt><code>-e <var>level</var></code></dt>
    
    <dd>Sets the <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> to
    <var>level</var> during server startup.  This is useful for
    temporarily increasing the verbosity of the error messages to find
    problems during startup.</dd>
    
    <dt><code>-E <var>file</var></code></dt>
    
    <dd>Send error messages during server startup to <var>file</var>.</dd>
    
    <dt><code>-h</code></dt>
    
    <dd>Output a short summary of available command line options.</dd>
    
    <dt><code>-l</code></dt>
    
    <dd>Output a list of modules compiled into the server.  This will
    <strong>not</strong> list dynamically loaded modules included using
    the <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directive.</dd>
    
    <dt><code>-L</code></dt>
    
    <dd>Output a list of directives provided by static modules, together with expected arguments and
    places where the directive is valid. Directives provided by shared modules are not listed.</dd>
    
    <dt><code>-M</code></dt>
    
    <dd>Dump a list of loaded Static and Shared Modules.</dd>
    
    <dt><code>-S</code></dt>
    
    <dd>Show the settings as parsed from the config file (currently only
    shows the virtualhost settings).</dd>
    
    <dt><code>-T</code> (Available in 2.3.8 and later)</dt>
    
    <dd>Skip document root check at startup/restart.</dd>
    
    <dt><code>-t</code></dt>
    
    <dd>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
    <var>DUMP</var>_<var>VHOSTS </var>is also set, details of the virtual host
    configuration will be printed. If -D <var>DUMP</var>_<var>MODULES </var> is
    set, all loaded modules will be printed.</dd>
    
    <dt><code>-v</code></dt>
    
    <dd>Print the version of <code>httpd</code>, and then exit.</dd>
    
    <dt><code>-V</code></dt>
    
    <dd>Print the version and build parameters of <code>httpd</code>, and
    then exit.</dd>
    
    <dt><code>-X</code></dt>
    
    <dd>Run httpd in debug mode.  Only one worker will be started and the
    server will not detach from the console.</dd>
    
    </dl>
    
    <p>The following arguments are available only on the <a href="../platform/windows.html">Windows platform</a>:</p>
    
    <dl>
    
    <dt><code>-k install|config|uninstall</code></dt>
    
    <dd>Install Apache httpd as a Windows NT service; change startup options for
    the Apache httpd service; and uninstall the Apache httpd service.</dd>
    
    <dt><code>-n <var>name</var></code></dt>
    
    <dd>The <var>name</var> of the Apache httpd service to signal.</dd>
    
    <dt><code>-w</code></dt>
    
    <dd>Keep the console window open on error so that the error message can
    be read.</dd>
    
    </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/httpd.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/httpd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������httpd-2.4.64/docs/manual/programs/httpd.html.ko.euc-kr����������������������������������������������0000664�0001751�0001751�00000026063�14743132254�022503� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>httpd - ġ ؽƮ    - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>httpd - ġ ؽƮ   </h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/httpd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
         <p><code>httpd</code> ġ ؽƮ  
         (HTTP)  α׷̴. ü(standalone)  μ
         ϵ Ǿ. Ѵٸ û óϱ ڽ
         μ  .</p>
    
         <p>Ϲ <code>httpd</code>  ϱ⺸ٴ
         н ýۿ <a href="apachectl.html">apachectl</a> , <a href="../platform/windows.html#winsvc">2000, XP
         񽺷</a>, <a href="../platform/windows.html#wincons">Windows
         9x ME ݼ α׷</a> ؾ Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="../invoking.html">ġ </a></li><li><a href="../stopping.html">ġ ߴ</a></li><li><a href="../configuring.html"></a></li><li><a href="../platform/">÷ </a></li><li><a href="apachectl.html">apachectl</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
         <p><code><strong>httpd</strong> [ -<strong>d</strong>
         <var>serverroot</var> ] [ -<strong>f</strong> <var>config</var> ]
         [ -<strong>C</strong> <var>directive</var> ] [ -<strong>c</strong>
         <var>directive</var> ] [ -<strong>D</strong> <var>parameter</var> ]
         [ -<strong>e</strong> <var>level</var> ] [ -<strong>E</strong>
         <var>file</var> ] [ <strong>-k</strong> start|restart|graceful|stop ]
         [ -<strong>R</strong> <var>directory</var> ] [ -<strong>h</strong> ]
         [ -<strong>l</strong> ] [ -<strong>L</strong> ] [ -<strong>S</strong> ]
         [ -<strong>t</strong> ] [ -<strong>v</strong> ] [ -<strong>V</strong> ]
         [ -<strong>X</strong> ] [ -<strong>M</strong> ]</code></p>
    
         <p><a href="../platform/windows.html">Windows ý</a>
          ƱԸƮ ߰   ִ:</p>
    
         <p><code><strong>httpd</strong> [ -<strong>k</strong>
         install|config|uninstall ] [ -<strong>n</strong> <var>name</var> ]
         [ -<strong>w</strong> ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
    
    <dl>
    <dt><code>-d <var>serverroot</var></code></dt>
    
    <dd><code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> þ
    ⺻ <var>serverroot</var> Ѵ. Ͽ ServerRoot
    þ Ͽ     ִ. ⺻
    <code>/usr/local/apache2</code>̴.</dd>
    
    <dt><code>-f <var>config</var></code></dt>
    
    <dd>Ҷ <var>config</var> Ͽ ִ þ Ѵ.
    <var>config</var> /   <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> ̴. ⺻
    <code>conf/httpd.conf</code>̴.</dd>
    
    <dt><code>-k <code>start|restart|graceful|stop</code></code></dt>
    
    <dd><code>httpd</code> , , ߴѴ.  ڼ 
    <a href="../stopping.html">ġ ߴϱ</a> ϶.</dd>
    
    <dt><code>-C <var>directive</var></code></dt>
    
    <dd> б <var>directive</var> þ óѴ.</dd>
    
    <dt><code>-c <var>directive</var></code></dt>
    
    <dd> б <var>directive</var> þ óѴ.</dd>
    
    
    <dt><code>-D <var>parameter</var></code></dt>
    
    <dd>  Ȥ ۽  ɾ óϱ
     <code class="directive"><a href="../mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>
    ǿ  <var>parameter</var> Ѵ.</dd>
    
    <dt><code>-e <var>level</var></code></dt>
    
    <dd> ϴµ <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code>
    <var>level</var> Ѵ. ̴   ã 
     ڼ   ϴ.</dd>
    
    <dt><code>-E <var>file</var></code></dt>
    
    <dd> ϴµ <var>file</var>  .</dd>
    
    <dt><code>-R <var>directory</var></code></dt>
    
    <dd> <code>SHARED_CORE</code> Ģ Ͽ 
     Ʈ <var>directory</var> Ѵ.</dd>
    
    <dt><code>-h</code></dt>
    
    <dd>  ִ  ɼǵ ª  Ѵ.</dd>
    
    <dt><code>-l</code></dt>
    
    <dd>     Ѵ. <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> þ Ͽ 
    о̴   <strong>ʴ´</strong>.</dd>
    
    <dt><code>-L</code></dt>
    
    <dd>þ  þ ޴ ƱԸƮ þ ҿ
     Ѵ.</dd>
    
    <dt><code>-M</code></dt>
    
    <dd>о      Ѵ.</dd>
    
    <dt><code>-S</code></dt>
    
    <dd>Ͽ о  ش ( ȣƮ
     ش).</dd>
    
    <dt><code>-t</code></dt>
    
    <dd> ˻縸 Ѵ. α׷  ˻
    ( ùٸ ) 0̳ (  ִ ) 0 ƴ
    ڵ  Ѵ. -D <var>DUMP</var>_<var>VHOSTS</var>
    ϸ ȣƮ  ڼ Ѵ. -D
    <var>DUMP</var>_<var>MODULES</var> ϸ о 
     Ѵ.</dd>
    
    <dt><code>-v</code></dt>
    
    <dd><code>httpd</code>  ϰ Ѵ.</dd>
    
    <dt><code>-V</code></dt>
    
    <dd><code>httpd</code>   Ķ͸ ϰ
    Ѵ.</dd>
    
    <dt><code>-X</code></dt>
    
    <dd> ·  Ѵ.   μ θ
    ϰ,  ֿܼ  ʴ´.</dd>
    
    </dl>
    
    <p> ƱԸƮ <a href="../platform/windows.html">Windows
    ÷</a>   ִ:</p>
    
    <dl>
    
    <dt><code>-k install|config|uninstall</code></dt>
    
    <dd>ġ Windows NT 񽺷 ġѴ; ġ  
    ɼ Ѵ; ġ  ġ .</dd>
    
    <dt><code>-n <var>name</var></code></dt>
    
    <dd>ġ  <var>name</var>.</dd>
    
    <dt><code>-w</code></dt>
    
    <dd> ߻ϸ ܼâ   ش.</dd>
    
    </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/httpd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/httpd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/configure.html.tr.utf8��������������������������������������������0000664�0001751�0001751�00000122776�14743132254�023065� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>configure - kaynak ağacını yapılandırır - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>configure - kaynak ağacını yapılandırır</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/configure.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>configure</code> betiği, Apache HTTP Sunucusunun kaynak kodlarını
          belli bir platform için yapılandırmakta ve derlemekte kullanılır.
          Sunucuyu kişisel gereksinimlerinize uygun şekilde derlemek için çeşitli
          seçeneklere sahiptir.</p>
    
        <p>Bu betik Apache HTTP Sunucusu kaynak paketinin kök dizininde bulunur ve
          sadece Unix ve benzeri sistemlerde kullanılabilir. Kaynak paketinin
          diğer platformalarda yapılandırılması ve derlenmesi hakkında bilgi
          edinmek için <a href="../platform/">platform</a> belgelerine bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Komut Satırı</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#env">Ortam Değişkenleri</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="../install.html">Derleme ve Kurulum</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Komut Satırı</a></h2>
        <p><code>configure</code> betiğini kaynak paketinin kök dizininden başka
          bir yere kopyalayıp çalıştırmamalısınız.</p>
    
        <p><code><strong>./configure</strong> [<var>seçenek</var>]...
          [<var>değişken=değer</var>]...</code></p>
    
        <p><code>CC</code>, <code>CFLAGS</code> gibi ortam değişkenlerini
          <code><var>değişken</var>=<var>değer</var></code> atamaları biçiminde
          kullanabilirsiniz. Kullanışlı değişkenlerin bazıları <a href="#env">aşağıda</a> açıklanmıştır.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
      <ul>
        <li><a href="#configurationoptions">Yapılandırma seçenekleri</a></li>
        <li><a href="#installationdirectories">Kurulum dizinleri</a></li>
        <li><a href="#systemtypes">Sistem türleri</a></li>
        <li><a href="#optionalfeatures">Seçimlik özellikler</a></li>
        <li><a href="#supportopt">Destek programları için seçenekler</a></li>
      </ul>
    
      <h3><a name="configurationoptions" id="configurationoptions">Yapılandırma seçenekleri</a></h3>
    
        <p>Aşağıdaki seçenekler <code>configure</code> betiğinin kendi davranışını
          belirlemekte kullanılır.</p>
    
        <dl>
          <dt><code>-C</code></dt>
          <dt><code>--config-cache</code></dt>
          <dd><code>--cache-file=config.cache</code> için bir kısaltmadır.</dd>
    
          <dt><code>--cache-file=<var>dosya</var></code></dt>
          <dd>Sınama sonuçları <code><var>dosya</var></code> dosyasında saklanır.
            Bu seçenek açıkça belirtilmedikçe işlevsizdir.</dd>
    
          <dt><code>-h</code></dt>
          <dt><code>--help [short|recursive]</code></dt>
          <dd>Yardım metnini basar ve çıkar. <code>short</code> değeriyle sadece
            bu pakete özgü seçenekler listelenir. <code>recursive</code> değeriyle
            ise paketin içindeki tüm paketler için kısa bir yardım metni
            basılır.</dd>
    
          <dt><code>-n</code></dt>
          <dt><code>--no-create</code></dt>
          <dd><code>configure</code> betiği normal olarak çalışır fakat herhangi
            bir çıktı dosyası üretmez. Derleme için <code>Makefile</code>
            dosyalarını üretmeksizin sınamaların sonuçlarını görmek için
            yararlıdır.</dd>
    
          <dt><code>-q</code></dt>
          <dt><code>--quiet</code></dt>
          <dd>Yapılandırma sürecinde <code>checking ...</code> iletilerini basmaz.
          </dd>
    
          <dt><code>--srcdir=<var>dizin</var></code></dt>
          <dd><code><em>dizin</em></code> dizinini kaynak dosyaları dizini olarak
            tanımlar. <code>configure</code> betiğinin bulunduğu dizin veya bir
            üst dizin öntanımlıdır.</dd>
    
          <dt><code>--silent</code></dt>
          <dd><code>--quiet</code> ile aynı.</dd>
    
          <dt>-V</dt>
          <dt>--version</dt>
          <dd>Telif hakkı bilgilerini gösterir ve çıkar.</dd>
        </dl>
      
    
      <h3><a name="installationdirectories" id="installationdirectories">Kurulum dizinleri</a></h3>
    
        <p>Bu seçenekler kurulum dizinlerini tanımlar. Kurulum dizinleri seçilmiş
          yerleşime bağımlıdır.</p>
    
        <dl>
          <dt><code>--prefix=<var>PREFIX</var></code></dt>
          <dd>Mimariden bağımsız dosyalar <code><em>PREFIX</em></code> dizininin
            altına kurulur. <code>/usr/local/apache2</code> öntanımlı kurulum
            dizinidir.</dd>
    
          <dt><code>--exec-prefix=<var>EPREFIX</var></code></dt>
          <dd>Mimariye bağımlı dosyalar <code><em>EPREFIX</em></code> dizininin
            altına kurulur. Bunun için <code><em>PREFIX</em></code> dizini
            öntanımlı kurulum dizinidir.</dd>
        </dl>
    
        <p>Öntanımlı olarak, <code>make install</code> tüm dosyaların
          <code>/usr/local/apache2/bin</code>, <code>/usr/local/apache2/lib</code>
          gibi dizinlere kurulmasını sağlar. Kurulum dizini önekini örneğin,
          <code>--prefix=$HOME</code> şeklinde belirterek kurulumun başka bir yere
          yapılmasını sağlayabilirsiniz.</p>
    
        <h4><a name="layout" id="layout">Bir dizin yerleşimi tanımlamak</a></h4>
          <dl>
            <dt><code>--enable-layout=<var>LAYOUT</var></code></dt>
            <dd>Kaynak kodu ve derleme betikleri kurulum ağacının
              <code><em>LAYOUT</em></code> yerleşimine dayalı olduğu varsayımıyla
              yapılandırılır. Bu seçenek sayesinde Apache HTTP Sunucusu kurulumu
              içinde her dosya türü için farklı bir yer belirleyebilirsiniz.
              <code>config.layout</code> dosyasında böyle yapılandırma örnekleri
              vardır. Örnekleri izleyerek kendi yapılandırmanızı
              oluşturabilirsiniz. Bu dosyada örneğin <code>FOO</code> isimli
              yerleşim <code>&lt;Layout FOO&gt;...&lt;/Layout&gt;</code> bölümü
              içinde düzenlenmiştir ve her yerleşim için böyle ayrı bir bölüm
              vardır. Öntanımlı yerleşim <code>Apache</code>’dir.</dd>
          </dl>
        
    
        <h4><a name="directoryfinetuning" id="directoryfinetuning">Kurulum dizinlerinde ince ayar</a></h4>
          
    
          <p>Kurulum dizinlerini daha iyi denetim altında tutmak için aşağıdaki
            seçenekler kullanılır. Lütfen, dizin öntanımlılarının
            <code>autoconf</code> tarafından tanımlandığına ve seçilen yerleşim
            ayarlarının bunları yerini aldığına dikkat ediniz.</p>
    
          <dl>
            
            <dt><code>--bindir=<var>dizin</var></code></dt>
            <dd>Kullanıcı tarafından çalıştırılabilen dosyalar
              <code><em>dizin</em></code> dizinine kurulur. Bunlar
              <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>, <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> gibi site
              yönetimi için yararlı destek programlarıdır. Öntanımlı olarak bu
              dosyalar <code><var>EPREFIX</var>/bin</code> dizinine kurulur.</dd>
    
            <dt><code>--datadir=<var>dizin</var></code></dt>
            <dd>Mimariden bağımsız salt okunur veriler <code><em>dizin</em></code>
              dizinine kurulur. Bunların öntanımlı kurulum dizini
              <code><var>PREFIX</var>/share</code> dizinidir. Bu seçenek
              <code>autoconf</code> tarafından atanır ve şimdilik
              kullanılmamıştır.</dd>
    
            <dt><code>--includedir=<var>dizin</var></code></dt>
            <dd>C başlık dosyaları <code><em>dizin</em></code> dizinine kurulur.
              Bunların öntanımlı kurulum dizini
              <code><var>PREFIX</var>/include</code> dizinidir.</dd>
    
            <dt><code>--infodir=<var>dizin</var></code></dt>
            <dd>Info belgeleri <code><em>dizin</em></code> dizinine kurulur.
              Bunların öntanımlı kurulum dizini
              <code><var>PREFIX</var>/info</code> dizinidir. Bu seçenek şimdilik
              kullanılmamıştır.</dd>
    
            <dt><code>--libdir=<var>dizin</var></code></dt>
            <dd>Nesne kod kütüphaneleri <code><em>dizin</em></code> dizinine
              kurulur. Bunların öntanımlı kurulum dizini
              <code><var>PREFIX</var>/lib</code> dizinidir.</dd>
    
            <dt><code>--libexecdir=<var>dizin</var></code></dt>
            <dd>Paylaşımlı modüller gibi program dosyaları
              <code><em>dizin</em></code> dizinine kurulur. Öntanımlı olarak
              <code>libexecdir</code> bu dizini
              <code><var>EPREFIX</var>/modules</code> olarak tanımlar.</dd>
    
            <dt><code>--localstatedir=<var>dizin</var></code></dt>
            <dd>Düzenlenebilir tek makinelik veri <code><em>dizin</em></code>
              dizinine kurulur. Öntanımlı olarak <code>localstatedir</code> bu
              dizini <code><var>PREFIX</var>/var</code> olarak tanımlar. Bu
              seçenek <code>autoconf</code> tarafından atanır ve şimdilik
              kullanılmamıştır.</dd>
    
            <dt><code>--mandir=<var>dizin</var></code></dt>
            <dd>Kılavuz sayfaları <code><em>dizin</em></code> dizinine kurulur.
              Öntanımlı olarak <code>mandir</code> bu dizini
              <code><var>EPREFIX</var>/man</code> olarak tanımlar.</dd>
    
            <dt><code>--oldincludedir=<var>dizin</var></code></dt>
            <dd>GCC harici C başlık dosyaları <code><em>dizin</em></code> dizinine
              kurulur. Öntanımlı olarak <code>oldincludedir</code> bu dizini
              <code>/usr/include</code> olarak tanımlar. Bu seçenek
              <code>autoconf</code> tarafından atanır ve şimdilik
              kullanılmamıştır.</dd>
    
            <dt><code>--sbindir=<var>dizin</var></code></dt>
            <dd>Sistem yöneticisi tarafından kullanılabilen programlar
              <code><em>dizin</em></code> dizinine kurulur. Bunlar
              <code class="program"><a href="../programs/httpd.html">httpd</a></code>, <code class="program"><a href="../programs/apachectl.html">apachectl</a></code>,
              <code class="program"><a href="../programs/suexec.html">suexec</a></code> gibi Apache HTTP Sunucusunu çalıştırmak
              için gereken programlardır. Öntanımlı olarak <code>sbindir</code> bu
              dizini <code><var>EPREFIX</var>/sbin</code> olarak tanımlar.</dd>
    
            <dt><code>--sharedstatedir=<var>dizin</var></code></dt>
            <dd>Mimariye bağımlı düzenlenebilir veriler
              <code><em>dizin</em></code> dizinine kurulur. Öntanımlı olarak
              <code>sharedstatedir</code> bu dizini
              <code><var>PREFIX</var>/com</code> olarak tanımlar. Bu seçenek
              <code>autoconf</code> tarafından atanır ve şimdilik
              kullanılmamıştır.</dd>
    
            <dt><code>--sysconfdir=<var>dizin</var></code></dt>
            <dd><code>httpd.conf</code>, <code>mime.types</code> gibi tek
              makinelik salt okunur sunucu yapılandırma dosyaları
              <code><em>dizin</em></code> dizinine kurulur. Öntanımlı olarak
              <code>sysconfdir</code> bu dizini
              <code><var>PREFIX</var>/conf</code> olarak tanımlar.</dd>
          </dl>
        
      
    
      <h3><a name="systemtypes" id="systemtypes">Sistem türleri</a></h3>
    
        <p>Bu seçenekleri Apache HTTP Sunucusunu başka bir platformda çalıştırmak
          üzere çapraz derleme yaparken kullanılır. Normal durumlarda sunucu
          derlendiği platformda çalıştırıldığından bu seçenekler kullanılmaz.</p>
    
        <dl>
          <dt><code>--build=<var>derleme-ortamı</var></code></dt>
          <dd>Derleme araçlarının derleneceği sistemin sistem türünü tanımlar.
            <code>config.guess</code> betiği ile elde edilen sonuç
            öntanımlıdır.</dd>
    
          <dt><code>--host=<var>çalışma-ortamı</var></code></dt>
          <dd>Sunucunun çalışacağı sistemin sistem türünü tanımlar. Öntanımlı
            sistem türü <code><var>derleme-ortamı</var></code>’dır.</dd>
    
          <dt><code>--target=<var>hedef-ortam</var></code></dt>
          <dd>Derleyicileri <code><var>hedef-ortam</var></code> sistem türü için
            yapılandırır. Öntanımlı sistem türü
            <code><var>çalışma-ortamı</var></code>’dır. Bu seçenek
            <code>autoconf</code> tarafından atanır ve Apache HTTP Sunucusu için
            gerekli değildir.</dd>
        </dl>
      
    
      <h3><a name="optionalfeatures" id="optionalfeatures">Seçimlik özellikler</a></h3>
    
        <p>Bu seçenekler HTTP sunucunuzun sahip olmasını istediğiniz özelliklerin
          hassas olarak ayarlanmasını sağlar.</p>
    
        <h4><a name="generaloptfeat" id="generaloptfeat">Genel sözdizimi</a></h4>
          <p>Bir özelliği etkin kılmak veya iptal etmek için genellikle şu
            sözdizimi kullanılır:</p>
    
          <dl>
            <dt><code>--disable-<var>özellik</var></code></dt>
            <dd>Sunucu <code><em>özellik</em></code> özelliğine sahip olmaz. Bu
              seçenek<code>--enable-<var>özellik</var>=no</code> seçeneğine
              eşdeğerdir.</dd>
    
            <dt><code>--enable-<var>özellik</var>[=<var>değer</var>]</code></dt>
            <dd>Sunucu <code><var>özellik</var></code> özelliğine sahip olur.
              <code><var>değer</var></code> belirtilmediği takdirde
              <code>yes</code> (evet) öntanımlıdır.</dd>
    
            <dt><code>--enable-<var>modül</var>=shared</code></dt>
            <dd>Belirtilen modül DSO modülü olarak derlenir. Öntanımlı olarak
              etkin modüller devingen ilintilenir.</dd>
    
            <dt><code>--enable-<var>modül</var>=static</code></dt>
            <dd>Belirtilen modül durağan ilintilenir.</dd>
          </dl>
    
          <div class="note"><h3>Bilginize</h3>
          <p><code>--enable-<var>filanca</var></code> seçeneğinin varlığı
            <code>configure</code> betiğinin <code><var>filanca</var></code> diye
            bir modül var olmasa bile bundan şikayetçi olmasına sebep olmaz. Bu
            bakımdan dikkatli olunuz.</p>
          </div>
        
    
        <h4><a name="choosemodules" id="choosemodules">Derlenecek modüllerin seçimi</a></h4>
          <p>Modüllerin çoğu öntanımlı olarak derlenir ve ya açıkça iptal edilmek
            ya da <code>few</code> anahtar sözcüğü
            kullanılarak kaldırılmak zorunda kalınır (ayrıntılar için
            <code>--enable-modules</code>, <code>--enable-mods-shared</code> ve
            <code>--enable-mods-static</code> seçeneklerine bakın). Bir grubu 
            tamamen kaldırmak için <code>--enable-modules=none</code> gerekir.</p>
    
            <p>Öntanımlı olarak derlenmeyenler ise ya açıkça etkin kılınmak ya da
              <code>all</code> veya <code>reallyall</code> anahtar sözcükleriyle
              kullanılabilir yapılmak zorunda kalınır.</p>
    
            <p>Hangi modüllerin öntanımlı olarak derlendiğini öğrenmek için
              <code>./configure -h</code> veya <code>./configure --help</code>
              komutunu çalıştırın ve çıktıdaki <code>Optional Features</code>
              bölümüne bakın. Örnek olarak, <code>mod_example1</code> ve
              <code>mod_example2</code> modülleriyle ilgilendiğinizi
              varsayalım:</p>
    
            <div class="example"><pre>Optional Features:
      ...
      --disable-example1     example module 1
      --enable-example2      example module 2
      ...</pre></div>
    
            <p>Burada, <code>mod_example1</code> öntanımlı olarak etkindir ve
              derlenmemesini istiyorsanız <code>--disable-example1</code>
              seçeneğini kullanmalısınız. <code>mod_example2</code> ise öntanımlı
              olarak derlenmemektedir ve derlenmesini istiyorsanız
              <code>--enable-example2</code> seçeneğini kullanmalısınız.</p>
        
    
        <h4><a name="mpms" id="mpms">Çok Süreçlilik Modülleri</a></h4>
          <p><a href="../mpm.html">Çok Süreçlilik Modülleri</a> veya MPM'ler
            sunucunun temel davranışını belirler. Sunucuya yüklenebilecek azami MPM
            sayısı birdir. Kullanılabilecek modüller <a href="../mod/">modül
            dizini</a>nde listelenmiştir.</p>
    
          <p>MPM'ler devingen yükleme için DSO olarak derlenebileceği gibi
            sunucuyla duruk olarak da ilintilenebilir ve bunlar aşağıdaki
            seçeneklerle etkin kılınır:</p>
    
          <dl>
            <dt><code>--with-mpm=MPM</code></dt>
            <dd>
              <p>Sunucu için öntanımlı MPM'i seçer. MPM'ler DSO modülleri olarak
                derleniyorsa (bak <code>--enable-mpms-shared</code>), bu seçenek
                öntanımlı yapılandırma dosyasında yüklenecek MPM'i seçer. Aksi
                takdirde, sunucuyla duruk olarak ilintilenecek, kullanılabilir tek
                MPM'i seçer.</p>
    
              <p>Bu seçenek belirtilmezse, işletim sisteminiz için
                <a href="../mpm.html#defaults">öntanımlı olan MPM</a> seçilir.</p>
            </dd>
    
           <dt><code>--enable-mpms-shared=<var>MPM-LISTESİ</var></code></dt>
            <dd>
              <p>MPM'leri devingen paylaşımlı modül olarak etkinleştirir.
                <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesi
                kullanılarak bu modüllerden biri devingen olarak yüklenmelidir.</p>
    
              <p><var>MPM-LISTESİ</var> MPM'lerin aralarına boşluk bırakılarak ve
                tamamı tek tırnaklarla sarmalanarak oluşturulmuş bir listesidir.
                Örnek:</p>
    
              <div class="example"><p><code>
                --enable-mpms-shared='prefork worker'
              </code></p></div>
    
              <p>Ek olarak, kullandığınız platformda devingen yüklemeyi destekleyen
                ve DSO modülü olarak derlenmiş tüm modülleri seçmek için
                <code>all</code> anahtar sözcüğünü de kullanabilirsiniz. Örnek:</p>
    
                <div class="example"><p><code>
                --enable-mpms-shared=all
              </code></p></div>
           </dd>
         </dl>
        
    
        <h4><a name="modules" id="modules">Üçüncü parti modüller</a></h4>
          <p>Üçüncü parti modülleri etkin kılmak için şu seçenekler kullanılır:</p>
    
          <dl>
            <dt><code>--with-module=<var>modül-türü</var>:<var>modül-dosyası</var>[,<var>modül-türü</var>:<var>modül-dosyası</var>]</code></dt>
            <dd><p>Durağan ilintili modüller listesine belirtilen modülleri ekler.
              Modül kaynak dosyası <code><var>modül-dosyası</var></code>, önce
              Apache HTTP Sunucusu kaynak ağacı altında
              <code>modules/<var>modül-türü</var></code> alt dizininde aranır.
              Modül orada değilse <code>configure</code>  betiği
              <code><var>modül-dosyası</var></code> ile bir mutlak dosya yolu
              belirtildiği varsayımıyla kaynak dosyasını
              <code><var>modül-türü</var></code> alt dizinine kopyalamaya çalışır.
              Alt dizin mevcut değilse oluşturulur ve içine standart bir
              <code>Makefile.in</code> yerleştirilir.</p>
    
            <p>Bu seçenek tek kaynak dosyasından oluşan küçük harici modülleri
              eklemek için yararlıdır. Daha karmaşık modüller için modül üreticisi
              tarafından sağlanan belgelere bakınız.</p>
    
            <div class="note"><h3>Bilginize</h3>
              <p>Durağan ilintili modüller yerine bir DSO modülü derlemek
                isterseniz <code class="program"><a href="../programs/apxs.html">apxs</a></code> programını kullanınız.</p>
            </div>
            </dd>
          </dl>
        
    
        <h4><a name="otheroptfeat" id="otheroptfeat">Kümeleme seçenekleri ve diğerleri</a></h4>
          <dl>
            <dt><code>--enable-maintainer-mode</code></dt>
            <dd>Hata ayıklama iletileri ve derleme sırasındaki uyarıların
              gösterilmesi etkin kılınır ve derlenmiş tüm modüller yüklenir.</dd>
    
            <dt><code>--enable-mods-shared=<var>modül-listesi</var></code></dt>
            <dd>
              <p>Etkinleştirilip devingen paylaşımlı modül olarak derlenecek
                modüllerin listesi belirtilir. Yani, bu modüller <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesi kullanılarak
                devingen olarak yüklenir.</p>
    
              <p><code><var>modül-listesi</var></code> tırnak içine alınmış boşluk
                ayraçlı modül isimleri listesidir. Modül isimleri önlerindeki
                <code>mod_</code> öneki olmaksızın belirtilirler. Örnek:</p>
    
              <div class="example"><p><code>
                --enable-mods-shared='headers rewrite dav'
              </code></p></div>
    
              <p><code><var>modül-listesi</var></code> yerine
                <code>reallyall</code>, <code>all</code>, <code>most</code> ve 
                <code>few</code> anahtar sözcükleri de belirtilebilir. Örneğin,</p>
    
              <div class="example"><p><code>
                --enable-mods-shared=most
              </code></p></div>
    
              <p>seçeneği ile çoğu modül DSO modülü olarak derlenir,</p>
    
              <div class="example"><p><code>
                --enable-mods-shared=few
              </code></p></div>
    
              <p>seçeneği ile sadece en temel modüller derlenir.</p>
    
              <p><code>most</code> öntanımlıdır.</p>
    
              <p>Seçilen modüller için <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> yönergeleri ana yapılandırma dosyasında
                kendiliğinden üretilir. Öntanımlı olarak, <code>--enable-foo</code>
                yapılandıma seçeneği ile açıkça seçilen modüller ve gerekli olanlar
                dışında kalan <code>LoadModule</code> yönergeleri açıklama haline
                getirilir. Yüklü modülleri <code>httpd.conf</code> dosyasındaki
                <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> yönergelerini
                etkin kılarak veya açıklama haline getirerek değiştirebilirsiniz.
                <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> yönergelerine ek
                olarak, derlenmiş tüm modüller
                <code>--enable-load-all-modules</code> yapılandırma seçeneği ile de
                etkinleştirilebilir.</p></dd>
    
            <dt><code>--enable-mods-static=<var>modül-listesi</var></code></dt>
            <dd>Bu seçenek modülleri devingen değil de durağan ilintilemek dışında
              <code>--enable-mods-shared</code> seçeneğine benzer. Yani bu
              modüller <code class="program"><a href="../programs/httpd.html">httpd</a></code> çalıştırılır çalıştırılmaz etkin
              olurlar. Yüklenmeleri için <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> yönergesine ihtiyaçları
              yoktur.</dd>
    
            <dt><code>--enable-modules=<var>MODULE-LIST</var></code></dt>
            <dd>Bu seçenek <code>--enable-mods-shared</code> gibi davranır ve ek
              olarak belirtilen modülleri devingen olarak ilintiler.Özel
              <code>none</code> anahtar sözcüğü tüm modüllerin derlenmesini iptal
              eder.</dd>
    
            <dt><code>--enable-v4-mapped</code></dt>
            <dd>IPv6 soketlierinin IPv4 bağlantılar üzerinde kullanılması mümkün
              olur.</dd>
    
            <dt><code>--with-port=<var>port</var></code></dt>
            <dd>Bu seçenek <code class="program"><a href="../programs/httpd.html">httpd</a></code>'nin dinleyeceği portu
              belirler. Bu port <code>httpd.conf</code> yapılandırma dosyası
              üretilirken kullanılır. 80. port öntanımlıdır.</dd>
    
            <dt><code>--with-program-name</code></dt>
            <dd>Öntanımlı olan <code>httpd</code> yerine başka bir çalıştırabilir
              ismi tanımlar.</dd>
          </dl>
        
      
    
      <h3><a name="packages" id="packages">Seçimlik paketler</a></h3>
        <p>Buradaki seçenekler seçimlik paketleri tanımlamak için kullanılır.</p>
    
        <h4><a name="generalpackages" id="generalpackages">Genel sözdizimi</a></h4>
          <p>Bir seçimlik paketi tanımlamak için genellikle şöyle bir sözdizimi
            kullanılır:</p>
    
          <dl>
            <dt><code>--with-<var>paket</var>[=<var>değer</var>]</code></dt>
            <dd><code><var>paket</var></code> paketi kullanılır. Öntanımlı
              <code><var>değer</var></code> <code>yes</code>’tir.</dd>
    
            <dt><code>--without-<var>paket</var></code></dt>
            <dd><code><var>paket</var></code> paketi kullanılmaz. Öntanımlı
              <code><var>değer</var></code> <code>no</code>’dur. Bu seçenek
              <code>autoconf</code> tarafından sağlanmıştır ve Apache HTTP
              Sunucusu için pek yararlı değildir.</dd>
          </dl>
        
    
        
    
        <h4><a name="packageopt" id="packageopt">Özel paketler</a></h4>
          <dl>
            <dt><code>--with-apr=<var>dizin</var>|<var>dosya</var></code></dt>
            <dd><a class="glossarylink" href="../glossary.html#apr" title="sözlüğe bakınız">Apache Taşınabilir Arayüzü</a> (APR)
              httpd kaynak paketinin bir parçası olup HTTP Sunucu ile birlikte
              derlenir. Eğer kendi kurulu APR’nizi kullanmak isterseniz bunu
              <code>configure</code> betiğine <code>apr-config</code> betiğinin
              yolunu belirterek ifade edebilirsiniz. Kurulu APR için bid dizin,
              dosya ismi veya mutlak dosya yolu belirtebilirsiniz.
              <code>apr-config</code> ya belirttiğiniz dizinde ya da
              <code>bin</code> alt dizininde bulunmalıdır.</dd>
    
            <dt><code>--with-apr-util=<var>dizin</var>|<var>dosya</var></code></dt>
            <dd>Apache Taşınabilir Arayüzü Araçları (APU) httpd kaynak paketinin
              bir parçası olup HTTP Sunucu ile birlikte derlenir. Eğer kendi
              kurulu APU’nuzu kullanmak isterseniz bunu <code>configure</code>
              betiğine <code>apu-config</code> betiğinin yolunu belirterek ifade
              edebilirsiniz. Kurulu APR için bir dizin, dosya ismi veya mutlak
              dosya yolu belirtebilirsiniz. <code>apr-config</code> ya
              belirttiğiniz dizinde ya da <code>bin</code> alt dizininde
              bulunmalıdır.</dd>
    
            <dt><code>--with-ssl=<var>dizin</var></code></dt>
            <dd><code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> modülü etkinse <code>configure</code>
              betiği kurulu bir OpenSSL arayacaktır. Kendi SSL/TLS kurulumunuzun
              yolunu bu seçenekle belirtebilirsiniz.</dd>
    
            <dt><code>--with-z=<var>dizin</var></code></dt>
            <dd>Yapılandırmanız gerektirdiği takdirde (örneğin,
              <code class="module"><a href="../mod/mod_deflate.html">mod_deflate</a></code> etkinse) <code>configure</code> betiği
              kurulu <code>zlib</code> kütüphanesinin yerini tespit etmeye
              çalışacaktır. Kendi sıkıştırma kütüphanenizin yerini bu seçenekle
              belirtebilirsiniz.</dd>
          </dl>
    
          <p>Apache HTTP Sunucusunun çeşitli bölümleri,
            <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> modülü ve <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
            modülünün <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
            yönergesi bilgilere erişimi hızlandırmak için basit anahtar/değer
            veritabanları kullanırlar. SDBM, APU içinde mevcut olduğundan bu
            veritabanı her zaman kullanılabilir durumdadır. Eğer başka veritabanı
            türleri kullanmak isterseniz aşağıdaki seçeneklerle bunları etkin
            kılabilirsiniz:</p>
    
          <dl>
            <dt><code>--with-gdbm[=<var>dizin-yolu</var>]</code></dt>
            <dd>Bir <code><var>dizin-yolu</var></code> belirtilmemişse
              <code>configure</code> betiği GNU DBM kurulumunun kütüphanelerini ve
              başlık dosyalarını bulunması olası yerlerde arar.  Bir
              <code><var>dizin-yolu</var></code> belirtilmişse
              <code>configure</code> betiği kurulumun kütüphanelerini
              <code><var>dizin-yolu</var>/lib</code> altında, başlık dosyalarını
              ise <code><var>dizin-yolu</var>/include</code> altında arayacaktır.
              Bundan başka, başlık ve kütüphane dosyalarının bulundukları yerler
              iki nokta imi ile ayrılarak <code><var>dizin-yolu</var></code>
              olarak belirtilebilir.</dd>
    
            <dt><code>--with-ndbm[=<var>dizin-yolu</var>]</code></dt>
            <dd>New DBM kurulumunu araştırması dışında <code>--with-gdbm</code>
              seçeneği gibidir.</dd>
    
            <dt><code>--with-berkeley-db[=<var>dizin-yolu</var>]</code></dt>
            <dd>Berkeley DB kurulumunu araştırması dışında
              <code>--with-gdbm</code> seçeneği gibidir.</dd>
          </dl>
    
          <div class="note"><h3>Bilginize</h3>
            <p>DBM seçenekleri APU tarafından sağlanmış olup onun yapılandırma
              betiğine aktarılır. Bu seçenekler <code>--with-apr-util</code>
              seçeneği ile tanımlanmış bir kurulu APU varsa kullanışlı olur.</p>
            <p>HTTP sunucunuz ile birlikte birden fazla DBM gerçeklenimi
              kullanabilirsiniz. Kullanılacak DBM türünü her zaman çalışma anı
              yapılandırmanızla yapılandırabilirsiniz.</p>
          </div>
        
      
    
      <h3><a name="supportopt" id="supportopt">Destek programları için seçenekler</a></h3>
        <dl>
          <dt><code>--enable-static-support</code></dt>
          <dd>Destek programlarını durağan ilintili olarak derler. Yani
            çalıştırılabilirin kullandığı bütün kütüphaneler kodla
            bütünleştirilir. Bu seçenek belirtilmedikçe destek programları daima
            devingen ilintili olarak derlenir.</dd>
    
          <dt><code>--enable-suexec</code></dt>
          <dd>Çatallanan sürecin kullanıcı ve grup kimliklerinin
            değiştirilebilmesini sağlayan <code class="program"><a href="../programs/suexec.html">suexec</a></code> programının
            kullanımını etkinleştirir. <strong>Sunucunuz üzerinde suid biti
            etkinleştirilmiş bir program çalıştırmanın sistem güvenliğinde
            yaratacağı sorunlar hakkında bir fikriniz yoksa bu seçeneği
            etkinleştirmeyin</strong>. <code class="program"><a href="../programs/suexec.html">suexec</a></code> yapılandırma
            seçenekleri <a href="#suexec">aşağıda</a> açıklanmıştır.</dd>
        </dl>
    
        <p>Tek bir destek programını aşağıdaki seçenekleri kullanarak bir durağan
          ilintili çalıştırılabilir olarak derleyebilirsiniz:</p>
    
        <dl>
          <dt><code>--enable-static-ab</code></dt>
          <dd><code class="program"><a href="../programs/ab.html">ab</a></code> programının durağan ilintili sürümü
            derlenir.</dd>
    
          
          <dt><code>--enable-static-checkgid</code></dt>
          <dd><code>checkgid</code> programının durağan ilintili sürümü
            derlenir.</dd>
    
          <dt><code>--enable-static-htdbm</code></dt>
          <dd><code class="program"><a href="../programs/htdbm.html">htdbm</a></code> programının durağan ilintili sürümü
            derlenir.</dd>
    
          <dt><code>--enable-static-htdigest</code></dt>
          <dd><code class="program"><a href="../programs/htdigest.html">htdigest</a></code> programının durağan ilintili sürümü
            derlenir.</dd>
    
          <dt><code>--enable-static-htpasswd</code></dt>
          <dd><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code> programının durağan ilintili sürümü
            derlenir.</dd>
    
          <dt><code>--enable-static-logresolve</code></dt>
          <dd><code class="program"><a href="../programs/logresolve.html">logresolve</a></code> programının durağan ilintili sürümü
            derlenir.</dd>
    
          <dt><code>--enable-static-rotatelogs</code></dt>
          <dd><code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code> programının durağan ilintili sürümü
            derlenir.</dd>
        </dl>
    
        <h4><a name="suexec" id="suexec"><code>suexec</code> yapılandırma seçenekleri</a></h4>
          
    
          <p>Aşağıdaki seçeneklerle <code class="program"><a href="../programs/suexec.html">suexec</a></code> programının
            davranışı hassas bir şekilde ayarlanabilir. Daha ayrıntılı bilgi için
            <a href="suexec.html#install">suEXEC yapılandırması ve kurulumu</a>na
            bakınız.</p>
    
          <dl>
            <dt><code>--with-suexec-bin</code></dt>
            <dd>Bu seçenek ile <code class="program"><a href="../programs/suexec.html">suexec</a></code> çalıştırılabilirinin yeri
              belirtilir. Öntanımlı olarak <code>--sbindir</code> ile belirtilen
              dizine kurulur (<a href="#directoryfinetuning">Kurulum dizinlerinde
              ince ayar</a> konusuna bakınız).</dd>
    
            <dt><code>--with-suexec-caller</code></dt>
            <dd>Bu seçenek ile <code class="program"><a href="../programs/suexec.html">suexec</a></code>’i çalıştırabilecek
              kullanıcı belirtilir. Normalde <code class="program"><a href="../programs/httpd.html">httpd</a></code> programını
              çalıştıran kullanıcı olmalıdır.</dd>
    
            <dt><code>--with-suexec-docroot</code></dt>
            <dd>Bu seçenek ile <code class="program"><a href="../programs/suexec.html">suexec</a></code>'e erişebilecek
              çalıştırılabilirlerin altında bulunacağı dizin belirtilir.
              <code>--datadir/htdocs</code> öntanımlıdır.</dd>
    
            <dt><code>--with-suexec-gidmin</code></dt>
            <dd><code class="program"><a href="../programs/suexec.html">suexec</a></code> için hedef kullanıcı olmasına izin
              verilen en küçük grup kimliğini tanımlamak için kullanılır. 100
              öntanımlıdır.</dd>
    
            <dt><code>--with-suexec-logfile</code></dt>
            <dd><code class="program"><a href="../programs/suexec.html">suexec</a></code> günlük dosyasının ismi belirtilir.
              Öntanımlı olarak bu dosyanın ismi <code>suexec_log</code> olup
              <code>--logfiledir</code> seçeneği ile belirtilen dizin altında
              bulunur.</dd>
    
            <dt><code>--with-suexec-safepath</code></dt>
            <dd><code class="program"><a href="../programs/suexec.html">suexec</a></code> tarafından çalıştırılacak süreçlerin
              çalıştırılabilirlerinin bulunabileceği dizinleri <code>PATH</code>
              ortam değişkenine tanımlamak için kullanılır.
              <code>/usr/local/bin:/usr/bin:/bin</code> öntanımlıdır.</dd>
    
            <dt><code>--with-suexec-userdir</code></dt>
            <dd>Bu seçenek, kullanıcı dizinleri altında <code class="program"><a href="../programs/suexec.html">suexec</a></code>
              tarafından çalıştırılacak süreçlerin çalıştırılabilirlerinin
              bulunabileceği alt dizini tanımlar. <code class="program"><a href="../programs/suexec.html">suexec</a></code>
              programını (<code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code> tarafından sağlanan)
              kullanıcıya özel dizinlerde  kullanmak istediğinizde bu gereklidir.
              <code>public_html</code> alt dizini öntanımlıdır.</dd>
    
            <dt><code>--with-suexec-uidmin</code></dt>
            <dd><code class="program"><a href="../programs/suexec.html">suexec</a></code> için hedef kullanıcı olmasına izin
              verilen en küçük kullanıcı kimliğini tanımlamak için kullanılır.
              100 öntanımlıdır.</dd>
    
            <dt><code>--with-suexec-umask</code></dt>
            <dd><code class="program"><a href="../programs/suexec.html">suexec</a></code> tarafından çalıştırılacak süreçler için
              <code>umask</code> tanımlar. Sisteminiz için geçerli ayarlar
              öntanımlıdır.</dd>
          </dl>
        
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="env" id="env">Ortam Değişkenleri</a></h2>
      <p><code>configure</code> betiğinin yerleri ve isimleri standartlara uygun
        olmayan kütüphaneleri ve programları bulmasını yardımcı olan veya
        <code>configure</code> betiği tarafından yapılan bazı seçimleri
        değiştirmenizi sağlayacak bazı ortam değişkenleri vardır.</p>
    
      
      <dl>
        <dt><code>CC</code></dt>
        <dd>Bu değişkenle derleme sırasında kullanılacak C derleyici komutu
          tanımlanır.</dd>
    
        <dt><code>CFLAGS</code></dt>
        <dd>Bu değişkenle derleme sırasında kullanılacak C derleyici seçenekleri
          tanımlanır.</dd>
    
        <dt><code>CPP</code></dt>
        <dd>Bu değişkenle derleme sırasında kullanılacak C önişlemci komutu
          tanımlanır.</dd>
    
        <dt><code>CPPFLAGS</code></dt>
        <dd>C/C++ önişlemci seçenekleri tanımlanır. Örneğin, eğer başlık
          dosyaları standart yerlerinde değil de
          <code><var>includedir</var></code> dizinindeyse bunu
          <code>-I<var>includedir</var></code> seçeneği olarak
          belirtebilirsiniz.</dd>
    
        <dt><code>LDFLAGS</code></dt>
        <dd>İlintileyici seçenekleri tanımlanır. Örneğin, eğer kütüphane
          dosyalarınız standart yerlerinde değil de
          <code><var>libdir</var></code> dizinindeyse bunu
          <code>-L<var>libdir</var></code> seçeneği olarak belirtebilirsiniz.</dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/configure.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/configure.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��httpd-2.4.64/docs/manual/programs/htcacheclean.html.ko.euc-kr���������������������������������������0000664�0001751�0001751�00000021656�14743132254�023765� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htcacheclean - ũ ij ûѴ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>htcacheclean - ũ ij ûѴ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/htcacheclean.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><code>htcacheclean</code> <code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code>
        ϴ  뷮  ѵ Ѵ.   
        ϰų (daemon)   ִ. α׷ 
        ϸ ׶忡 ڰ ִٰ  ֱ ij
        丮   ִ ˻Ѵ. 󿡰 TERM̳
        INT ñ׳  ϰ Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">ڵ</a></li>
    </ul><h3></h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_cache_disk.html">mod_cache_disk</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
        <p><code><strong>htcacheclean</strong>
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]
        [ -<strong>r</strong> ]
        [ -<strong>n</strong> ]
        -<strong>p</strong><var>path</var>
        -<strong>l</strong><var>limit</var></code></p>
    
        <p><code><strong>htcacheclean</strong> -<strong>b</strong>
        [ -<strong>n</strong> ]
        [ -<strong>i</strong> ]
        -<strong>d</strong><var>interval</var>
        -<strong>p</strong><var>path</var>
        -<strong>l</strong><var>limit</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
        <dl>
        <dt><code>-d<var>interval</var></code></dt>
        <dd> Ͽ <var>interval</var> и ij
        ûѴ.  ɼ <code>-D</code>, <code>-v</code>,
        <code>-r</code> ɼǰ Բ   .  ϰ
        Ϸ 󿡰 <code>SIGTERM</code> Ȥ
        <code>SIGINT</code> ñ׳  ȴ.</dd>
    
        <dt><code>-D</code></dt>
        <dd>˻縸 ϰ  ƹ͵  ʴ´.  ɼ
        <code>-d</code> ɼǰ Բ   .</dd>
    
        <dt><code>-v</code></dt>
        <dd>ڼ 踦 Ѵ.  ɼ <code>-d</code> ɼǰ
        Բ   .</dd>
    
        <dt><code>-r</code></dt>
        <dd> ûѴ. ġ   ʴ´ٰ Ѵ
        ( Ѵٸ ij ̻  ȴ).  ɼ
        <code>-d</code> ɼǰ Բ   .</dd>
    
        <dt><code>-n</code></dt>
        <dd>ģϰ(nice) Ѵ. ٸ μ  
        Ѵ. <code>htcacheclean</code>   ڰԵǿ
        (1) ũ  ǰ (2) ׵ Ŀ ٸ μ
          ִ.</dd>
    
        <dt><code>-p<var>path</var></code></dt>
        <dd><var>path</var> ũ ij ֻ 丮 Ѵ.
        <code class="directive"><a href="../mod/mod_cache_disk.html#cacheroot">CacheRoot</a></code>
        þ     ؾ Ѵ.</dd>
    
        <dt><code>-l<var>limit</var></code></dt>
        <dd>ü ũ ij 뷮  <var>limit</var> Ѵ.
         ⺻ (Ȥ ڿ <code>B</code> ̸) Ʈ
        ̴. ųιƮ <code>K</code>, ްƮ
        <code>M</code> ڿ δ.</dd>
    
        <dt><code>-i</code></dt>
        <dd> ũ ij  쿡 Ѵ. 
        ɼ <code>-d</code> ɼǰ Բ   ִ.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">ڵ</a></h2>
        <p><code>htcacheclean</code>  ۾  쿡
        ("") ڵ 0 ȯϰ,  쿡 <code>1</code>
        ȯѴ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/htcacheclean.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htcacheclean.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/index.html.es�����������������������������������������������������0000664�0001751�0001751�00000016336�14743132254�021302� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>El Servidor Apache y Programas de Soporte - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="../">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>El Servidor Apache y Programas de Soporte</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>Esta p&#225;gina contiene toda la documentaci&#243;n sobre los programas
        ejecutables incluidos en el servidor Apache.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="index" id="index">&#205;ndice</a></h2>
    
        <dl>
          <dt><code class="program"><a href="../programs/httpd.html">httpd</a></code></dt>
    
          <dd>Servidor Apache del Protocolo de Transmisi&#243;n de
          Hipertexto (HTTP)</dd>
    
          <dt><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></dt>
    
          <dd>Interfaz de control del servidor HTTP Apache </dd>
    
          <dt><code class="program"><a href="../programs/ab.html">ab</a></code></dt>
    
          <dd>Herramienta de benchmarking del Servidor HTTP Apache</dd>
    
          <dt><code class="program"><a href="../programs/apxs.html">apxs</a></code></dt>
    
          <dd>Herramienta de Extensi&#243;n de Apache</dd>
    
          <dt><code class="program"><a href="../programs/configure.html">configure</a></code></dt>
    
          <dd>Configuraci&#243;n de la estructura de directorios de Apache</dd>
    
          <dt><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></dt>
    
          <dd>Crea y actualiza los archivos de autentificaci&#243;n de usuarios
          en formato DBM para autentificaci&#243;n b&#225;sica</dd>
    
          <dt><code class="program"><a href="../programs/fcgistarter.html">fcgistarter</a></code></dt>
    
          <dd>Ejecuta un programa FastCGI.</dd>
    
          <dt><code class="program"><a href="../programs/htcacheclean.html">htcacheclean</a></code></dt>
    
          <dd>Vac&#237;a la cach&#233; del disco.</dd>
    
          <dt><code class="program"><a href="../programs/htdigest.html">htdigest</a></code></dt>
    
          <dd>Crea y actualiza los ficheros de autentificaci&#243;n de usuarios
          para autentificaci&#243;n tipo digest</dd>
    
          <dt><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></dt>
    
          <dd>Manipula la base de datos DBM de contrase&#241;as.</dd>
    
          <dt><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code></dt>
    
          <dd>Crea y actualiza los ficheros de autentificaci&#243;n de usuarios
          para autentificaci&#243;n tipo b&#225;sica</dd>
    
          <dt><code class="program"><a href="../programs/httxt2dbm.html">httxt2dbm</a></code></dt>
    
          <dd>Crea ficheros dbm para que se usen con RewriteMap</dd>
    
          <dt><code class="program"><a href="../programs/logresolve.html">logresolve</a></code></dt>
    
          <dd>Resuelve los nombres de host para direcciones IP que est&#225;n
          en los ficheros log de Apache</dd>
    
          <dt><code class="program"><a href="../programs/log_server_status.html">log_server_status</a></code></dt>
    
          <dd>Logea de forma peri&#243;dica el estado del servidor.</dd>
    
          <dt><code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code></dt>
    
          <dd>Renueva los logs de Apache sin tener que parar el servidor</dd>
    
          <dt><code class="program"><a href="../programs/split-logfile.html">split-logfile</a></code></dt>
    
          <dd>Divide un archivo de registro multi-host virtual en 
          	archivos de registro por host</dd>
    
          <dt><code class="program"><a href="../programs/suexec.html">suexec</a></code></dt>
    
          <dd>Programa para cambiar la identidad de
          	 usuario con la que se ejecuta un CGI</dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">M&#243;dulos</a> | <a href="../mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="../glossary.html">Glosario</a> | <a href="../sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/logresolve.html.ko.euc-kr�����������������������������������������0000664�0001751�0001751�00000015334�14743132254�023540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>logresolve - ġ α IP-ּҸ ȣƮ
      ȯѴ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>logresolve - ġ α IP-ּҸ ȣƮ
      ȯѴ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/logresolve.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
         <p><code>logresolve</code> ġ ٷαϿ ִ
         IP-ּҸ ã ó α׷̴. Ӽ ϸ
         ּȭϱ logresolve  ؽ̺ ij
         Ѵ. , IP ּҰ αϿ ó ö ã´.</p>
    
         <p>ǥԷ ġ α д´.   ù°
         ׸ IP ּ̰,  κа  еǾ Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
    
         <p><code><strong>logresolve</strong> [ -<strong>s</strong>
         <var>filename</var> ] [ -<strong>c</strong> ] &lt;
         <var>access_log</var> &gt; <var>access_log.new</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
    
    <dl>
    
    <dt><code>-s <var>filename</var></code></dt>
    
    <dd>踦  ϸ Ѵ.</dd>
    
    <dt><code>-c</code></dt>
    
    <dd><code>logresolve</code>  DNS ˻縦 ϵ Ѵ:
    IP ּҷ ȣƮ ã  ȣƮ ٽ IP ּҵ
    ãƼ  ϳ  ּҿ ġϴ ˻Ѵ.</dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/logresolve.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/logresolve.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdigest.html.tr.utf8���������������������������������������������0000664�0001751�0001751�00000020656�14743132254�022711� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htdigest - Özet kimlik doğrulama dosyalarını yönetir - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>htdigest - Özet kimlik doğrulama dosyalarını yönetir</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htdigest.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code><strong>htdigest</strong></code>, HTTP kullanıcılarının digest
        türü kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının
        saklanmasında kullanılacak düz metin dosyalarını oluşturmak ve güncellemek
        için kullanılır. Apache HTTP sunucusunun mevcut özkaynaklarının kullanımı
        sadece <code><strong>htdigest</strong></code> tarafından oluşturulan
        dosyalarda listelenmiş kullanıcılara tahsis edilebilir.</p>
    
        <p>Bu kılavuz sayfası sadece komut satırı değiştirgelerini listeler.
        Kullanıcı kimlik doğrulamasını
        <strong><code class="program"><a href="../programs/httpd.html">httpd</a></code></strong>'de yapılandırmak için gerekli
        yönergelerle ilgili ayrıntılar için Apache dağıtımının bir parçası olan
        ve <a href="http://httpd.apache.org/"> http://httpd.apache.org/</a>
        adresinde de bulunan Apache HTTP Sunucusu Belgelerine bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Güvenlik Değerlendirmeleri</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>htdigest</strong> [ -<strong>c</strong> ]
        <var>parola-dosyası</var> <var>bölge</var> <var>kullanıcı</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><strong>-c</strong></code></dt>
        <dd><code><var>parola-dosyası</var></code> oluşturur. Dosya mevcutsa,
        dosya silinip yeniden yazılır.</dd>
    
        <dt><code><var>parola-dosyası</var></code></dt>
        <dd>Kullanıcı ismi, parola ve bölge bilgilerini içeren dosyanın ismi.
        <code><strong>-c</strong></code> seçeneği verilmişse ve dosya mevcut
        değilse oluşturulur, dosya mevcutsa silinip yeniden oluşturulur.</dd>
    
        <dt><code><var>bölge</var></code></dt>
        <dd>Kullanıcının mensup olduğu bölge ismi. Daha fazla bilgi için:
        <a href="http://tools.ietf.org/html/rfc2617#section-3.2.1">
        http://tools.ietf.org/html/rfc2617#section-3.2.1</a></dd>
    
        <dt><code><var>kullanıcı</var></code></dt>
        <dd><code><var>parola-dosyası</var></code>'nda oluşturulacak veya
        güncellenecek kullanıcı ismi. <code><var>kullanıcı</var></code> bu
        dosyada mevcut değilse yeni bir girdi eklenir. Girdi mevcutsa parolası
        değiştirilir.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Güvenlik Değerlendirmeleri</a></h2>
        <p>Bu program bir setuid çalıştırılabiliri olarak güvenilir olmadığından
        <em>setuid yapılmamalıdır</em>.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/htdigest.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htdigest.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/httxt2dbm.html.tr.utf8��������������������������������������������0000664�0001751�0001751�00000017770�14743132254�023021� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>httxt2dbm - RewriteMap ile kullanmak için DBM dosyaları üretir - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>httxt2dbm - RewriteMap ile kullanmak için DBM dosyaları üretir</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/httxt2dbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httxt2dbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/httxt2dbm.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code><strong>httxt2dbm</strong></code>, <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> ile kullanmak için düz metin
        dosyalardan DBM dosyaları üretir.</p>
    
        <p>Çıktı dosyası mevcutsa dosya kırpılmaz. Yeni anahtarlar eklenir,
        mevcutlar da güncellenir.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Kullanım</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Seçenekler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Örnekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Kullanım</a></h2>
        <p><code><strong>httxt2dbm</strong>
        [ -<strong>v</strong> ]
        [ -<strong>f</strong> <var>DBM_türü</var> ]
        -<strong>i</strong> <var>kaynak_metin</var>
        -<strong>o</strong> <var>çıktı_DBM</var>
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Seçenekler</a></h2>
        <dl>
        <dt><code><strong>-v</strong></code></dt>
        <dd>Çıktı daha ayrıntılı olur.</dd>
    
        <dt><code><strong>-f</strong> <var>DBM_türü</var></code></dt>
        <dd>Çıktı için kullanılacak DBM türü belirtilir. Belirtilmediği takdirde
        <a class="glossarylink" href="../glossary.html#apr" title="sözlüğe bakınız">APR</a> öntanımlısı kullanılır. Belirtilebilecek DBM
        türleri:
        GDBM dosyalar için <code>GDBM</code>,
        SDBM dosyalar için <code>SDBM</code>,
        Berkeley DB dosyalar için <code>DB</code>,
        NDBM dosyalar için <code>NDBM</code>,
        öntanımlı DBM türü için <code>default</code>
        </dd>
    
        <dt><code><strong>-i</strong> <var>kaynak_metin</var></code></dt>
        <dd>DBM dosyasının üretiminde kullanılacak girdi dosyası belirtilir. Bu
        dosya, her satırda bir kayıt bulunmak üzere her satırı şöyle biçemlenmiş
        olmalıdır:
        <code>anahtar değer</code>.
        Bu dosyanın biçemi ve manası ile ilgili ayrıntılar için <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> yönergesinin açıklamasına
        bakınız.
        </dd>
    
        <dt><code><strong>-o</strong>  <var>çıktı_DBM</var></code></dt>
        <dd>Çıktılanacak DBM dosyasının ismi belirtilir.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Örnekler</a></h2>
        <div class="example"><p><code>
          httxt2dbm -i rewritemap.txt -o rewritemap.dbm<br />
          httxt2dbm -f SDBM -i rewritemap.txt -o rewritemap.dbm<br />
        </code></p></div>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/httxt2dbm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httxt2dbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/httxt2dbm.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/httxt2dbm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������httpd-2.4.64/docs/manual/programs/other.html��������������������������������������������������������0000664�0001751�0001751�00000000566�13710016232�020672� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: other.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: other.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: other.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: other.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/index.html.en�����������������������������������������������������0000664�0001751�0001751�00000015133�14737241666�021302� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Server and Supporting Programs - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Server and Supporting Programs</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>This page documents all the executable programs included
        with the Apache HTTP Server.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="index" id="index">Index</a></h2>
    
        <dl>
          <dt><code class="program"><a href="../programs/httpd.html">httpd</a></code></dt>
    
          <dd>Apache hypertext transfer protocol server</dd>
    
          <dt><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></dt>
    
          <dd>Apache HTTP server control interface</dd>
    
          <dt><code class="program"><a href="../programs/ab.html">ab</a></code></dt>
    
          <dd>Apache HTTP server benchmarking tool</dd>
    
          <dt><code class="program"><a href="../programs/apxs.html">apxs</a></code></dt>
    
          <dd>APache eXtenSion tool</dd>
    
          <dt><code class="program"><a href="../programs/configure.html">configure</a></code></dt>
    
          <dd>Configure the source tree</dd>
    
          <dt><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></dt>
    
          <dd>Create and update user authentication files in DBM format
          for basic authentication</dd>
    
          <dt><code class="program"><a href="../programs/fcgistarter.html">fcgistarter</a></code></dt>
    
          <dd>Start a FastCGI program</dd>
    
          <dt><code class="program"><a href="../programs/htcacheclean.html">htcacheclean</a></code></dt>
    
          <dd>Clean up the disk cache</dd>
    
          <dt><code class="program"><a href="../programs/htdigest.html">htdigest</a></code></dt>
    
          <dd>Create and update user authentication files for digest
          authentication</dd>
    
          <dt><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></dt>
    
          <dd>Manipulate DBM password databases.</dd>
    
          <dt><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code></dt>
    
          <dd>Create and update user authentication files for basic
          authentication</dd>
    
          <dt><code class="program"><a href="../programs/httxt2dbm.html">httxt2dbm</a></code></dt>
    
          <dd>Create dbm files for use with RewriteMap</dd>
    
          <dt><code class="program"><a href="../programs/logresolve.html">logresolve</a></code></dt>
    
          <dd>Resolve hostnames for IP-addresses in Apache
          logfiles</dd>
    
          <dt><code class="program"><a href="../programs/log_server_status.html">log_server_status</a></code></dt>
    
          <dd>Periodically log the server's status</dd>
    
          <dt><code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code></dt>
    
          <dd>Rotate Apache logs without having to kill the server</dd>
    
          <dt><code class="program"><a href="../programs/split-logfile.html">split-logfile</a></code></dt>
    
          <dd>Split a multi-vhost logfile into per-host logfiles</dd>
    
          <dt><code class="program"><a href="../programs/suexec.html">suexec</a></code></dt>
    
          <dd>Switch User For Exec</dd>
    
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/index.html.zh-cn.utf8���������������������������������������������0000664�0001751�0001751�00000015030�14743132254�022565� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP 服务器与支持程序 - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP 服务器与支持程序</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
        <p>本页描述了 Apache HTTP 服务器包含的所有可执行程序。</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="index" id="index">索引</a></h2>
    
        <dl>
          <dt><code class="program"><a href="../programs/httpd.html">httpd</a></code></dt>
    
          <dd>Apache 服务器。</dd>
    
          <dt><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></dt>
    
          <dd>Apache HTTP 服务器控制工具。</dd>
    
          <dt><code class="program"><a href="../programs/ab.html">ab</a></code></dt>
    
          <dd>Apache HTTP 服务器性能基准工具。</dd>
    
          <dt><code class="program"><a href="../programs/apxs.html">apxs</a></code></dt>
    
          <dd>Apache 扩展工具。</dd>
    
          <dt><code class="program"><a href="../programs/configure.html">configure</a></code></dt>
    
          <dd>配置源代码。</dd>
    
          <dt><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></dt>
    
          <dd>为基本认证创建和更新 DBM 格式的用户认证文件。</dd>
    
          <dt><code class="program"><a href="../programs/fcgistarter.html">fcgistarter</a></code></dt>
    
          <dd>启动 FastCGI 程序。</dd>
    
          <dt><code class="program"><a href="../programs/htcacheclean.html">htcacheclean</a></code></dt>
          <dd>清理磁盘缓存。</dd>
    
          <dt><code class="program"><a href="../programs/htdigest.html">htdigest</a></code></dt>
    
          <dd>为摘要认证创建和更新用户认证文件。</dd>
    
          <dt><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></dt>
    
          <dd>操作 DBM 密码数据库。</dd>
    
          <dt><code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code></dt>
    
          <dd>为基本认证创建和更新用户认证文件。</dd>
    
          <dt><code class="program"><a href="../programs/httxt2dbm.html">httxt2dbm</a></code></dt>
    
          <dd>为 RewriteMap 创建 dbm 文件。</dd>
    
          <dt><code class="program"><a href="../programs/logresolve.html">logresolve</a></code></dt>
    
          <dd>将 Apache 日志文件中的 IP 地址解析到主机名称。</dd>
    
          <dt><a href="other.html#log_server_status">log_server_status</a></dt>
    
          <dd>周期性的记录服务器状态。</dd>
    
          <dt><code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code></dt>
    
          <dd>不关闭 Apache 而切换日志文件。</dd>
    
          <dt><a href="other.html#split-logfile">split-logfile</a></dt>
    
          <dd>将多个虚拟主机的日志文件按照主机拆分。</dd>
    
          <dt><code class="program"><a href="../programs/suexec.html">suexec</a></code></dt>
    
          <dd>执行外部程序前切换用户。</dd>
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/other.html.tr.utf8������������������������������������������������0000664�0001751�0001751�00000012344�14743132254�022212� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Diğer Programlar - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a> &gt; <a href="./">Programlar</a></div><div id="page-content"><div id="preamble"><h1>Diğer Programlar</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/other.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu sayfada daha önce belgelenen programlar şimdi kendi belgelerine
        sahiptir. Bu sayfaya verilmiş bağlantıları lütfen güncelleyin.</p>
    
        <p><code class="program"><a href="../programs/log_server_status.html">log_server_status</a></code></p>
        <p><code class="program"><a href="../programs/split-logfile.html">split-logfile</a></code></p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/programs/other.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/other.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/other.html.ko.euc-kr����������������������������������������������0000664�0001751�0001751�00000015135�14743132254�022477� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Other Programs - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>Other Programs</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/other.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p> Ͽ manpage , ġ  Ե
         α׷̴. ڵ ̵ ġ ʴ´.
         <code>support/</code> 丮  α׷
        ã  ִ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#log_server_status">log_server_status</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#split-logfile">split-logfile</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="log_server_status" id="log_server_status">log_server_status</a></h2>
        <p> perl ũƮ cron   ϵ Ǿ.
         ũƮ  Ͽ   ٿεѴ.
        ׷   ٷ Ͽ Ͽ Ѵ. α
        ġ Ϸ ũƮ պκ  Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="split-logfile" id="split-logfile">split-logfile</a></h2>
        <p> perl ũƮ յ  ٷα 
         Ϸ .   ù° ׸ ("<code>%v</code>"
        ߰) ȣƮ ̰, αϸ  丮
        ȣƮ + "<code>.log</code>" Ѵ.</p>
    
        <p>յ α ǥԷ д´.   
        αϵ鿡 ߰Ѵ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/other.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/other.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/index.html.ko.euc-kr����������������������������������������������0000664�0001751�0001751�00000012765�14743132254�022473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>  α׷ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>  α׷</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>ġ  Ե α׷̴.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="index" id="index"></a></h2>
    
        <dl>
          <dt><a href="httpd.html">httpd</a></dt>
    
          <dd>ġ ؽƮ   </dd>
    
          <dt><a href="apachectl.html">apachectl</a></dt>
    
          <dd>ġ   ̽</dd>
    
          <dt><a href="ab.html">ab</a></dt>
    
          <dd>ġ  ɰ˻ </dd>
    
          <dt><a href="apxs.html">apxs</a></dt>
    
          <dd>ġ Ȯ  (APache eXtenSion tool)</dd>
    
          <dt><a href="configure.html">configure</a></dt>
    
          <dd>ҽ Ʈ Ѵ</dd>
    
          <dt><a href="dbmmanage.html">dbmmanage</a></dt>
    
          <dd>basic authentication  DBM  
            Ѵ</dd>
    
          <dt><a href="htcacheclean.html">htcacheclean</a></dt>
          <dd>ũ ij ûѴ</dd>
    
          <dt><a href="htdigest.html">htdigest</a></dt>
    
          <dd>digest authentication   
           Ѵ</dd>
    
          <dt><a href="htpasswd.html">htpasswd</a></dt>
    
          <dd>basic authentication    
          Ѵ</dd>
    
          <dt><a href="logresolve.html">logresolve</a></dt>
    
          <dd>ġ α IP-ּҸ ȣƮ ȯѴ</dd>
    
          <dt><a href="rotatelogs.html">rotatelogs</a></dt>
    
          <dd> ʰ ġ α׸ ȯѴ</dd>
    
          <dt><a href="suexec.html">suexec</a></dt>
    
          <dd>  ڸ Ѵ (Switch User For Exec)</dd>
    
          <dt><a href="other.html">ٸ α׷</a></dt>
          <dd>manpage   .</dd>
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../es/programs/" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="../fr/programs/" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/programs/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������httpd-2.4.64/docs/manual/programs/fcgistarter.html.fr.utf8������������������������������������������0000664�0001751�0001751�00000015166�14740503670�023376� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>fcgistarter - Démarrer un programme FastCGI - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>fcgistarter - Démarrer un programme FastCGI</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/fcgistarter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/fcgistarter.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/fcgistarter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p />
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#note">Note</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="note" id="note">Note</a></h2>
          <p>Ne fonctionne actuellement que sur les systèmes de type Unix.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>fcgistarter</strong>
        -<strong>c</strong> <var>commande</var>
        -<strong>p</strong> <var>port</var>
        [ -<strong>i</strong> <var>interface</var> ]
        -<strong>N</strong> <var>nombre</var>
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-c <var>commande</var></code></dt>
        <dd>Le chemin absolu du programme FastCGI</dd>
    
        <dt><code>-p <var>port</var></code></dt>
        <dd>Port sur lequel le programme va se mettre en écoute</dd>
    
        <dt><code>-i <var>interface</var></code></dt>
        <dd>Interface sur laquelle le programme va se mettre en écoute</dd>
    
        <dt><code>-N <var>nombre</var></code></dt>
        <dd>Nombre d'instances du programme</dd>
    
        </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/fcgistarter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/fcgistarter.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/fcgistarter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/fcgistarter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/dbmmanage.html.fr.utf8��������������������������������������������0000664�0001751�0001751�00000034471�14740503670�022774� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>dbmmanage - Gestion des fichiers d'authentification des
    utilisateurs au format DBM - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>dbmmanage - Gestion des fichiers d'authentification des
    utilisateurs au format DBM</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/dbmmanage.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>dbmmanage</code> permet de créer et de maintenir les
        fichiers au format DBM où sont stockés les noms d'utilisateurs et
        mots de passe à des fins d'authentification de base des utilisateurs
        HTTP via le module <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code>. Il est possible
        de restreindre l'accès aux ressources disponibles sur le serveur
        HTTP Apache aux seuls utilisateurs spécifiés dans les fichiers créés
        par <code>dbmmanage</code>. Ce programme ne peut être utilisé
        qu'avec des fichiers d'utilisateurs au format DBM. Pour
        l'utilisation de fichiers textes, voir le programme
        <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>.</p>
    
        <p>Le programme <code class="program"><a href="../programs/htdbm.html">htdbm</a></code> est aussi un utilitaire
        permettant de maintenir une base de données de mots de passe DBM.</p>
    
        <p>Cette page de manuel ne décrit que les arguments de la ligne de
        commande. Pour plus de détails à propos des directives nécessaires
        pour configurer l'authentification des utilisateurs dans
        <code class="program"><a href="../programs/httpd.html">httpd</a></code>, voir le manuel httpd qui est fourni avec
        la distribution d'Apache, ou peut être consulté à <a href="http://httpd.apache.org/">http://httpd.apache.org/</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Bogues</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></li><li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li><li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>dbmmanage</strong> [ <var>codage</var> ]
        <var>nom-fichier</var> add|adduser|check|delete|update
        <var>nom-utilisateur</var>
        [ <var>mot-de-passe-haché</var>
          [ <var>groupe</var>[,<var>groupe</var>...]
            [ <var>commentaire</var> ] ] ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>nom-fichier</var>
        view [ <var>nom-utilisateur</var> ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>nom-fichier</var>import</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code><var>nom-fichier</var></code></dt>
        <dd>Le nom du fichier au format DBM, en général sans l'extension
        <code>.db</code>, <code>.pag</code>, ou <code>.dir</code>.</dd>
    
        <dt><code><var>nom-utilisateur</var></code></dt>
        <dd>L'utilisateur concerné par l'opération effectuée. Le
        <var>nom-utilisateur</var> ne doit pas contenir de caractère
        <code>:</code>.</dd>
    
        <dt><code><var>mot-de-passe-haché</var></code></dt>
        <dd>C'est le mot de passe sous sa forme hachée à utiliser avec les
        commandes <code>update</code> et <code>add</code>. Vous pouvez
        utiliser un tiret (<code>-</code>) si vous voulez que le mot de
        passe vous soit demandé, mais remplissez les champs par la suite. En
        outre, avec la commande <code>update</code>, un point
        (<code>.</code>) permet de conserver le mot de passe original.</dd>
    
        <dt><code><var>groupe</var></code></dt>
        <dd>Un groupe dont l'utilisateur est membre. Un nom de groupe ne
        doit pas contenir de caractère (<code>:</code>). Vous pouvez
        utiliser un tiret (<code>-</code>) si vous ne voulez pas associer
        l'utilisateur à un groupe, mais remplissez le champ commentaire. En
        outre, avec la commande <code>update</code>, un point
        (<code>.</code>) permet de conserver le groupe original.</dd>
    
        <dt><code><var>commentaire</var></code></dt>
        <dd>C'est l'endroit où vous pouvez enregistrer diverses informations
        à propos de l'utilisateur telles que son nom réel, sont e-mail,
        etc... Le serveur ignore ce champ.</dd>
        </dl>
    
        <h3><a name="options.encodings" id="options.encodings">Codages</a></h3>
          <dl>
          <dt><code>-d</code></dt>
          <dd>hachage crypt (hachage par défaut sauf sous Win32,
          Netware)</dd>
    
          <dt><code>-m</code></dt>
          <dd>hachage MD5 (hachage par défaut sous Win32,
          Netware)</dd>
    
          <dt><code>-s</code></dt>
          <dd>hachage SHA1</dd>
    
          <dt><code>-p</code></dt>
          <dd>en clair (<em>déconseillé</em>)</dd>
          </dl>
        
    
        <h3><a name="options.commands" id="options.commands">Commandes</a></h3>
          <dl>
          <dt><code>add</code></dt>
          <dd>Ajoute une entrée pour <var>nom-utilisateur</var> à
          <var>nom-fichier</var> en utilisant le mot de passe haché
          <var>mot-de-passe-haché</var>.
    
          <div class="example"><p><code>dbmmanage passwords.dat add rbowen foKntnEF3KSXA</code></p></div>
          </dd>
    
          <dt><code>adduser</code></dt>
          <dd>Demande un mot de passe puis ajoute une entrée pour
          <var>nom-utilisateur</var> à <var>nom-fichier</var>.
    
          <div class="example"><p><code>dbmmanage passwords.dat adduser krietz</code></p></div>
          </dd>
    
          <dt><code>check</code></dt>
          <dd>Demande un mot de passe puis vérifie si
          <var>nom-utilisateur</var> est présent dans <var>nom-fichier</var>
          et si son mot de passe correspond au mot de passe fourni.
    
          <div class="example"><p><code>dbmmanage passwords.dat check rbowen</code></p></div>
          </dd>
    
          <dt><code>delete</code></dt>
          <dd>Supprime l'entrée <var>nom-utilisateur</var> de
          <var>nom-fichier</var>.
    
          <div class="example"><p><code>dbmmanage passwords.dat delete rbowen</code></p></div>
          </dd>
    
          <dt><code>import</code></dt>
          <dd>Lit les entrées
          <code><var>nom-utilisateur</var>:<var>mot-de-passe</var></code>
          (une par ligne) depuis <code>STDIN</code>, et les ajoute à
          <var>nom-fichier</var>. Les mots de passe doivent être déjà
          chiffrés.</dd>
    
          <dt><code>update</code></dt>
          <dd>Identique à la commande <code>adduser</code>, à l'exception
          que la présence de <var>nom-utilisateur</var> dans
          <var>nom-fichier</var> est vérifiée.
    
          <div class="example"><p><code>dbmmanage passwords.dat update rbowen</code></p></div>
          </dd>
    
          <dt><code>view</code></dt>
          <dd>Affiche le contenu du fichier DBM. Si vous spécifiez un
          <var>nom-utilisateur</var>, seule l'entrée correspondante est
          affichée.
    
          <div class="example"><p><code>dbmmanage passwords.dat view</code></p></div>
          </dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Bogues</a></h2>
        <p>Vous devez garder à l'esprit qu'il existe de nombreux formats de
        fichiers DBM différents, et que selon toute vraisemblance, des
        bibliothèques pour plus d'un format sont présentes sur votre
        système. Les trois exemples de base sont SDBM, NDBM, le projet GNU
        GDBM, et Berkeley DB 2. Malheureusement, toutes ces bibliothèques
        utilisent des formats de fichiers différents, et vous devez vous
        assurer que le format de fichier utilisé par <var>nom-fichier</var>
        correspond au format attendu par <code>dbmmanage</code>.
        Actuellement, <code>dbmmanage</code> n'a aucun moyen de savoir à
        quel type de fichier DBM il a à faire. S'il est utilisé avec un
        format inapproprié, il ne renverra rien, ou pourra créer un fichier
        DBM différent avec un nom différent, ou au pire, va corrompre le
        fichier DBM si vous avez tenté de le modifier.</p>
    
        <p><code>dbmmanage</code> possède une liste de préférences en
        matière de formats DBM, définies dans le tableau
        <code>@AnyDBM::ISA</code> au début du programme. Comme nous
        préférons le format de fichier Berkeley DB 2, l'ordre dans lequel
        <code>dbmmanage</code> va rechercher les bibliothèques système est
        Berkeley DB 2, puis NDBM, GDBM et enfin SDBM. La première
        bibliothèque trouvée sera celle que <code>dbmmanage</code> tentera
        d'utiliser pour toutes les opérations sur les fichiers DBM. Cette
        ordre est sensiblement différent de l'ordre standard de Perl
        <code>@AnyDBM::ISA</code>, et de l'ordre utilisé par l'appel
        <code>dbmopen()</code> de Perl ; si vous utilisez un autre
        utilitaire pour gérer vos fichiers DBM, il doit donc se conformer à
        l'ordre de préférence indiqué précédemment. Vous devez prêter la
        même attention si vous utilisez des programmes écrits dans d'autres
        langages, comme C, pour accéder à ces fichiers.</p>
    
        <p>Vous pouvez utiliser le programme <code>file</code> fourni par la
        plupart des systèmes Unix pour déterminer le format d'un fichier
        DBM.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/dbmmanage.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/dbmmanage.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/rotatelogs.html.fr.utf8�������������������������������������������0000664�0001751�0001751�00000046514�14740503670�023245� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>rotatelogs - Rotation des journaux d'Apache par redirection de
      ces derniers dans un "pipe" - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>rotatelogs - Rotation des journaux d'Apache par redirection de
      ces derniers dans un "pipe"</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/rotatelogs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>rotatelogs</code> est un programme simple à utiliser en
         conjonction avec la fonctionnalité d'Apache de redirection dans un
         "pipe" des fichiers journaux. Il supporte une rotation basée sur un
         intervalle de temps ou une taille maximale du journal.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Exemples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#portability">Portabilité</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
    
         <p><code><strong>rotatelogs</strong>
         [ -<strong>l</strong> ]
         [ -<strong>L</strong> <var>nom-lien</var> ]
         [ -<strong>p</strong> <var>programme</var> ]
         [ -<strong>f</strong> ]
         [ -<strong>D</strong> ]
         [ -<strong>t</strong> ]
         [ -<strong>v</strong> ]
         [ -<strong>e</strong> ]
         [ -<strong>c</strong> ]
         [ -<strong>n</strong> <var>nombre-de-fichiers</var> ]
         <var>fichier-journal</var>
         <var>heure-de-rotation</var>|<var>taille-fichier</var>(B|K|M|G)
         [ <var>décalage</var> ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    
    <dt><code>-l</code></dt>
    <dd>Utilise le temps local plutôt que GMT comme base pour l'intervalle
    de temps ou pour le formatage de <code>strftime(3)</code> avec une
    rotation basée sur la taille.</dd>
    
    <dt><code>-L</code> <var>nom-lien</var></dt>
    <dd><p>Etablit un lien physique entre le fichier journal courant et le lien
    spécifié. Cette option permet de consulter le journal de manière
    continue malgré les rotations via une commande du style <code>tail -F
    nom-lien</code>.</p>
    <p>Si le nom du lien spécifié n'est pas un chemin absolu, il est relatif au
    répertoire de travail de <code>rotatelogs</code> qui correspond à la valeur de
    la directive <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> lorsque la commande
    <code>rotatelogs</code> est exécutée par le serveur.  
    </p>
    </dd>
    
    <dt><code>-p</code> <var>programme</var></dt>
    <dd>Avec cette option, <code>rotatelogs</code> exécutera le programme
    <var>programme</var> chaque fois qu'un nouveau fichier journal sera
    ouvert. Le nom du fichier nouvellement ouvert est passé comme premier
    argument au programme. Si l'exécution se produit après une rotation,
    l'ancien nom du fichier journal est passé au programme comme second
    argument. <code>rotatelogs</code>
    n'attend pas la fin du <var>programme</var> pour continuer son
    exécution, et cessera tout enregistrement de codes d'erreur lorsqu'il
    aura terminé son processus. Le <var>programme</var> utilise les mêmes
    canaux stdin, stdout, et stderr que rotatelogs, et hérite de son
    environnement.</dd>
    
    <dt><code>-f</code></dt>
    <dd>Ouvre le fichier journal immédiatement, dès que
    <code>rotatelogs</code> démarre, au lieu d'attendre la lecture de la
    première entrée de journal (pour les sites peu chargés, il peut
    s'écouler un temps substantiel entre le démarrage du serveur et le
    traitement de la première requête, temps pendant lequel le fichier
    journal associé n'"existe" pas, ce qui peut causer des problèmes à
    certains utilitaires de journalisation automatiques).</dd>
    
    <dt><code>-D</code></dt>
    <dd>Crée les répertoires parents du chemin du fichier journal s'ils
    n'existent pas déjà, ce qui permet d'utiliser le format
    <code>strftime(3)</code> dans les chemins au lieu du nom de fichier seul.</dd>
    
    <dt><code>-t</code></dt>
    <dd>Provoque une troncature du fichier journal au lieu d'une rotation.
    Cela peut s'avérer utile lorsqu'un journal est élaboré en temps réel par
    une commande telle que tail, l'archivage des données n'étant ici pas
    nécessaire. Si aucun suffixe n'est ajouté au nom de fichier, les
    chaînes de format contenant des caractères '%' sont cependant
    respectées.
    </dd>
    
    <dt><code>-T</code></dt>
    <dd>Provoque la troncature de tous les fichiers journaux lors de leur ouverture,
    à l'exception du fichier journal initial. Cela s'avère utile lorsque la chaîne
    de formatage contient quelque chose qui va se répéter de manière cyclique, comme
    le jour du mois par exemple. Disponible à partir de la version 2.4.56 du serveur
    HTTP Apache.
    </dd>
    
    
    <dt><code>-v</code></dt>
    <dd>Affiche une sortie verbeuse sur STDERR. La sortie contient le
    résultat de l'interprétation de la configuration, ainsi que toutes les
    opérations d'ouverture et de fermeture de fichiers.</dd>
    
    <dt><code>-c</code></dt>
    <dd>Crée un fichier journal pour chaque intervalle, même s'il est vide.</dd>
    
    <dt><code>-e</code></dt>
    <dd>Envoie les messages de journalisation vers stdout. Ceci s'avère
    utile lorsque les journaux doivent être traités par un autre programme.</dd>
    
    <dt><code>-n <var>nombre-de-fichiers</var></code></dt>
    <dd>Utilise une liste circulaire de noms de fichiers sans repères de temps.
    Cette option permet d'écraser des fichiers journaux au démarrage et au cours de
    la rotation. Avec -n 3, la série de fichiers conservés sera "logfile",
    "logfile.1", "logfile.2" avec écrasement de "logfile".
    <br />
    Lorsque ce programme ouvre «&nbsp;logfile&nbsp;», ce dernier sera seulement tronqué si
    l'option <code>-t</code> est aussi spécifiée. Toute rotation subséquente sera
    précédée d'une troncature du fichier cible. Dans le cas d'une rotation basée sur
    la taille sans l'option <code>-t</code> et si des fichiers journaux sont déjà en
    place, cette option peut provoquer des résultats inattendus comme l'envoi des
    entrées de journal initiales vers «&nbsp;logfile.1&nbsp;», les entrées de «&nbsp;logfile.1&nbsp;»
    n'étant pas conservées, même si des fichiers «&nbsp;logfile.n&nbsp;» n'ont pas encore été
    utilisés.
    <br />
    Disponible à partir de la version 2.4.5 du serveur HTTP Apache.</dd>
    
    <dt><code><var>fichier-journal</var></code></dt>
    <dd><p>Le chemin et le nom de base du fichier journal. Si
    <var>fichier-journal</var> contient des caractères '%', il est considéré
    comme une chaîne de formatage pour <code>strftime(3)</code>. Dans le cas
    contraire, le suffixe <var>.nnnnnnnnnn</var> est automatiquement ajouté
    et correspond au temps en secondes (sauf si l'option -t est spécifiée).
    Les deux formats calculent le temps
    de démarrage depuis le début de la période courante. Par exemple, si un
    temps de rotation de 86400 est spécifié, les champs heure, minute et
    seconde créés à partir du format <code>strftime(3)</code> auront tous
    pour valeur 0, en référence au début de la période de 24 heures courante
    (minuit).</p>
    <p>Si vous utilisez le formatage de noms de fichiers
    <code>strftime(3)</code>, assurez-vous que le format du fichier journal
    possède une granularité suffisamment importante pour générer un nom de
    fichier différent à chaque rotation des journaux. Si ce n'est pas le
    cas, la rotation va écraser le fichier existant au lieu d'en générer un
    nouveau. Par exemple, si <var>fichier-journal</var> était
    <code>/var/log/errorlog.%Y-%m-%d</code> avec une rotation à 5
    mégaoctets, et si la limite de 5 mégaoctets a été atteinte deux fois
    dans la même journée, le même nom de fichier va être généré, et la
    rotation va écraser le fichier existant.</p>
    <p>Si le nom du fichier journal n'est pas un chemin absolu, il est relatif au
    répertoire de travail de <code>rotatelogs</code> qui correspond à la valeur de
    la directive <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> lorsque la commande
    <code>rotatelogs</code> est exécutée par le serveur.  
    </p>
    </dd>
    
    <dt><code><var>temps-rotation</var></code></dt>
    
    <dd>Le temps entre deux rotations des fichiers journaux en secondes. La
    rotation intervient au début de cet intervalle. Par exemple, si le temps
    de rotation est de 3600, la rotation des fichiers journaux s'effectuera
    au début de chaque heure ; si le temps de rotation est de 86400, la
    rotation des fichiers journaux s'effectuera chaque nuit à minuit. (Si
    aucune donnée n'est enregistrée au cours d'un intervalle, aucun fichier
    ne sera créé).</dd>
    
    <dt><code><var>taille-fichier</var>(B|K|M|G)</code></dt>
    
    <dd>La taille maximale du fichier suivie par une des lettres
    <code>B</code> (Octets), <code>K</code> (KOctets), <code>M</code> (MOctets)
    ou <code>G</code> (GOctets).
    <p>
    Lorsque temps et taille sont spécifiés, la taille doit l'être après le
    temps. La rotation interviendra alors aussitôt que l'une des deux limites
    (temps ou taille) sera atteinte.
    </p>
    </dd>
    
    <dt><code><var>décalage</var></code></dt>
    
    <dd>Le décalage en minutes par rapport au temps UTC. Par défaut, le
    décalage est considéré comme nul et c'est le temps UTC qui est utilisé.
    Par exemple, pour utiliser le temps local de la zone UTC -5 heures,
    spécifiez une valeur de <code>-300</code> pour cette option. Dans la
    plupart des cas, il vaut mieux utiliser l'option <code>-l</code> que
    spécifier un décalage.</dd>
    
    </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples</a></h2>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/fichier-journal 86400" common</pre>
    </div>
    
         <p>Cette directive crée les fichiers /var/log/fichier-journal.nnnn
         où nnnn correspond au temps système auquel la journalisation
         démarre effectivement (ce temps sera toujours un multiple du temps
         de rotation, si bien que vous pouvez synchroniser les scripts cron
         avec lui). A la fin de chaque temps de rotation (ici après 24
         heures), une nouvelle journalisation démarre.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -l /var/log/fichier-journal.%Y.%m.%d 86400" common</pre>
    </div>
    
         <p>Cette directive crée les fichiers
         /var/log/fichier-journal.yyyy.mm.dd où yyyy correspond à l'année,
         mm au mois et dd au jour du mois. La journalisation basculera vers
         un nouveau fichier chaque jour à minuit, temps local.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/fichier-journal 5M" common</pre>
    </div>
    
         <p>Cette directive va effectuer une rotation du fichier journal
         chaque fois que la taille de ce dernier atteindra 5 MOctets.</p>
    
    <div class="example"><pre class="prettyprint lang-config">ErrorLog "|bin/rotatelogs /var/log/journal-erreurs.%Y-%m-%d-%H_%M_%S 5M"</pre>
    </div>
         <p>Cette directive va effectuer une rotation du fichier journal des
         erreurs chaque fois que la taille de ce dernier atteindra 5
         MOctets, et le nom du fichier journal se présentera sous
         la forme <code>journal-erreurs.YYYY-mm-dd-HH_MM_SS</code>.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -t /var/log/journal 86400" common</pre>
    </div>
    
         <p>Cet exemple crée le fichier <code>/var/log/journal</code> en le
         tronquant au démarrage, puis une fois par jour. Ce scénario implique qu'un
         processus séparé (tel que tail) traite le fichier en temps réel.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -T /var/log/logfile.%d 86400" common</pre>
    </div>
    
    <p>Si le serveur est démarré ou redémarré le premier du mois, cela s'ajoute à la
    fin de <code>/var/log/logfile.01</code>. Lorsqu'une entrée de journal est écrite
    le deux du mois, <code>/var/log/logfile.02</code> est tronqué et les nouvelles
    entrées seront ajoutées à partir du début du fichier. Cet exemple conserve
    environ 1 mois de journaux sans nécessiter de maintenance externe.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="portability" id="portability">Portabilité</a></h2>
    
    <p>Les substitutions des chaînes de format du fichier journal suivantes
    doivent être supportées par toutes les implémentations de
    <code>strftime(3)</code> ; voir la page de manuel de
    <code>strftime(3)</code> pour les extensions spécifiques à une
    bibliothèque.</p>
    
    <table class="bordered"><tr><td><code>%A</code></td><td>nom du jour de la semaine en entier
    (localisé)</td></tr>
    <tr class="odd"><td><code>%a</code></td><td>nom du jour de la semaine sur 3
    caractères (localisé)</td></tr>
    <tr><td><code>%B</code></td><td>nom du mois en entier (localisé)</td></tr>
    <tr class="odd"><td><code>%b</code></td><td>nom du mois sur 3 caractères (localisé)</td></tr>
    <tr><td><code>%c</code></td><td>date et heure (localisé)</td></tr>
    <tr class="odd"><td><code>%d</code></td><td>jour du mois sur 2 chiffres</td></tr>
    <tr><td><code>%H</code></td><td>heure sur 2 chiffres (de 0 à 24h)</td></tr>
    <tr class="odd"><td><code>%I</code></td><td>heure sur 2 chiffres (de 0 à 12h)</td></tr>
    <tr><td><code>%j</code></td><td>jour de l'année sur 3 chiffres</td></tr>
    <tr class="odd"><td><code>%M</code></td><td>minutes sur 2 chiffres</td></tr>
    <tr><td><code>%m</code></td><td>mois sur 2 chiffres</td></tr>
    <tr class="odd"><td><code>%p</code></td><td>suffixe am/pm pour l'heure de 0 à 12h
    (localisé)</td></tr>
    <tr><td><code>%S</code></td><td>secondes sur 2 chiffres</td></tr>
    <tr class="odd"><td><code>%U</code></td><td>semaine de l'année sur 2 chiffres
    (Dimanche est le premier jour de la semaine)</td></tr>
    <tr><td><code>%W</code></td><td> semaine de l'année sur 2 chiffres
    (Lundi est le premier jour de la semaine)</td></tr>
    <tr class="odd"><td><code>%w</code></td><td>jour de la semaine sur 1 chiffre
    (Dimanche est le premier jour de la semaine)</td></tr>
    <tr><td><code>%X</code></td><td>heure (localisée)</td></tr>
    <tr class="odd"><td><code>%x</code></td><td>date (localisée)</td></tr>
    <tr><td><code>%Y</code></td><td>année sur 4 chiffres</td></tr>
    <tr class="odd"><td><code>%y</code></td><td>année sur 2 chiffres</td></tr>
    <tr><td><code>%Z</code></td><td>nom de la zone de temps</td></tr>
    <tr class="odd"><td><code>%%</code></td><td>caractère littéral `%'</td></tr>
    </table>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/rotatelogs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/rotatelogs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/other.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000012404�14740503670�022172� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Autres programmes - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>Autres programmes</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/other.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Cette page contenait la documentation de programmes qui possèdent
        maintenant leurs propres pages de documentation. Merci de bien
        vouloir mettre à jour vos liens.</p>
    
        <p><code class="program"><a href="../programs/log_server_status.html">log_server_status</a></code></p>
        <p><code class="program"><a href="../programs/split-logfile.html">split-logfile</a></code></p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/other.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/other.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/ab.html.en��������������������������������������������������������0000664�0001751�0001751�00000045424�14737241666�020563� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ab - Apache HTTP server benchmarking tool - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>ab - Apache HTTP server benchmarking tool</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/ab.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>ab</code> 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.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#output">Output</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Bugs</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>ab</strong>
        [ -<strong>A</strong> <var>auth-username</var>:<var>password</var> ]
        [ -<strong>b</strong> <var>windowsize</var> ]
        [ -<strong>B</strong> <var>local-address</var> ]
        [ -<strong>c</strong> <var>concurrency</var> ]
        [ -<strong>C</strong> <var>cookie-name</var>=<var>value</var> ]
        [ -<strong>d</strong> ]
        [ -<strong>e</strong> <var>csv-file</var> ]
        [ -<strong>E</strong> <var>client-certificate file</var> ]
        [ -<strong>f</strong> <var>protocol</var> ]
        [ -<strong>g</strong> <var>gnuplot-file</var> ]
        [ -<strong>h</strong> ]
        [ -<strong>H</strong> <var>custom-header</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>k</strong> ]
        [ -<strong>l</strong> ]
        [ -<strong>m</strong> <var>HTTP-method</var> ]
        [ -<strong>n</strong> <var>requests</var> ]
        [ -<strong>p</strong> <var>POST-file</var> ]
        [ -<strong>P</strong> <var>proxy-auth-username</var>:<var>password</var> ]
        [ -<strong>q</strong> ]
        [ -<strong>r</strong> ]
        [ -<strong>s</strong> <var>timeout</var> ]
        [ -<strong>S</strong> ]
        [ -<strong>t</strong> <var>timelimit</var> ]
        [ -<strong>T</strong> <var>content-type</var> ]
        [ -<strong>u</strong> <var>PUT-file</var> ]
        [ -<strong>v</strong> <var>verbosity</var>]
        [ -<strong>V</strong> ]
        [ -<strong>w</strong> ]
        [ -<strong>x</strong> <var>&lt;table&gt;-attributes</var> ]
        [ -<strong>X</strong> <var>proxy</var>[:<var>port</var>] ]
        [ -<strong>y</strong> <var>&lt;tr&gt;-attributes</var> ]
        [ -<strong>z</strong> <var>&lt;td&gt;-attributes</var> ]
        [ -<strong>Z</strong> <var>ciphersuite</var> ]
        [http[s]://]<var>hostname</var>[:<var>port</var>]/<var>path</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-A <var>auth-username</var>:<var>password</var></code></dt>
        <dd>Supply BASIC Authentication credentials to the server. The username and
        password are separated by a single <code>:</code> and sent on the wire
        base64 encoded. The string is sent regardless of whether the server needs
        it (<em>i.e.</em>, has sent an 401  authentication needed).</dd>
    
        <dt><code>-b <var>windowsize</var></code></dt>
        <dd>Size of TCP send/receive buffer, in bytes.</dd>
    
        <dt><code>-B <var>local-address</var></code></dt>
        <dd>Address to bind to when making outgoing connections.</dd>
    
        <dt><code>-c <var>concurrency</var></code></dt>
        <dd>Number of multiple requests to perform at a time. Default is one
        request at a time.</dd>
    
        <dt><code>-C <var>cookie-name</var>=<var>value</var></code></dt>
        <dd>Add a <code>Cookie:</code> line to the request. The  argument  is
        typically in the form of a <code><var>name</var>=<var>value</var></code>
        pair. This field is repeatable.</dd>
    
        <dt><code>-d</code></dt>
        <dd>Do not display the "percentage served within XX [ms] table". (legacy
        support).</dd>
    
        <dt><code>-e <var>csv-file</var></code></dt>
        <dd>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'.</dd>
    
        <dt><code>-E <var>client-certificate-file</var></code></dt>
        <dd>When connecting to an SSL website, use the provided client certificate
        in PEM format to authenticate with the server. The file is expected to
        contain the client certificate, followed by intermediate certificates,
        followed by the private key. Available in 2.4.36 and later.</dd>
    
        <dt><code>-f <var>protocol</var></code></dt>
        <dd>Specify SSL/TLS protocol (SSL2, SSL3, TLS1, TLS1.1, TLS1.2, or ALL).
        TLS1.1 and TLS1.2 support available in 2.4.4 and later.</dd>
    
        <dt><code>-g <var>gnuplot-file</var></code></dt>
        <dd>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. </dd>
    
        <dt><code>-h</code></dt>
        <dd>Display usage information.</dd>
    
        <dt><code>-H <var>custom-header</var></code></dt>
        <dd>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 (<em>i.e.</em>, <code>"Accept-Encoding: zip/zop;8bit"</code>).</dd>
    
        <dt><code>-i</code></dt>
        <dd>Do <code>HEAD</code> requests instead of <code>GET</code>.</dd>
    
        <dt><code>-k</code></dt>
        <dd>Enable the HTTP KeepAlive feature, <em>i.e.</em>, perform multiple
        requests within one HTTP session. Default is no KeepAlive.</dd>
    
        <dt><code>-l</code></dt>
        <dd>Do not report errors if the length of the responses is not constant. This 
        can be useful for dynamic pages.
        Available in 2.4.7 and later.
        </dd>
    
        <dt><code>-m <var>HTTP-method</var></code></dt>
        <dd>Custom HTTP method for the requests.
        Available in 2.4.10 and later.</dd>
    
        <dt><code>-n <var>requests</var></code></dt>
        <dd>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.</dd>
    
        <dt><code>-p <var>POST-file</var></code></dt>
        <dd>File containing data to POST.  Remember to also set <code>-T</code>.</dd>
    
        <dt><code>-P <var>proxy-auth-username</var>:<var>password</var></code></dt>
        <dd>Supply BASIC Authentication credentials to a proxy en-route. The
        username and password are separated by a single <code>:</code> and sent on
        the  wire base64 encoded. The string is sent regardless of whether the
        proxy needs it (<em>i.e.</em>, has  sent an 407 proxy authentication
        needed).</dd>
    
        <dt><code>-q</code></dt>
        <dd>When processing more than 150 requests, <code>ab</code> outputs a
        progress count on <code>stderr</code> every 10% or 100 requests or so. The
        <code>-q</code> flag will suppress these messages.</dd>
    
        <dt><code>-r</code></dt>
        <dd>Don't exit on socket receive errors.</dd>
    
        <dt><code>-s <var>timeout</var></code></dt>
        <dd>Maximum number of seconds to wait before the socket times out.
        Default is 30 seconds.
        Available in 2.4.4 and later.</dd>
    
        <dt><code>-S</code></dt>
        <dd>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).</dd>
    
        <dt><code>-t <var>timelimit</var></code></dt>
        <dd>Maximum number of seconds to  spend  for  benchmarking. This implies a
        <code>-n 50000</code> internally. Use this to benchmark the server within a
        fixed total amount of time. Per default there is no timelimit.</dd>
    
        <dt><code>-T <var>content-type</var></code></dt>
        <dd>Content-type header to use for POST/PUT data, eg.
        <code>application/x-www-form-urlencoded</code>.
        Default is <code>text/plain</code>.</dd>
    
        <dt><code>-u <var>PUT-file</var></code></dt>
        <dd>File containing data to PUT.  Remember to also set <code>-T</code>.</dd>
    
        <dt><code>-v <var>verbosity</var></code></dt>
        <dd>Set verbosity level - <code>4</code> and above prints information on
        headers, <code>3</code> and above prints response codes (404, 200, etc.),
        <code>2</code> and above prints warnings and info.</dd>
    
        <dt><code>-V</code></dt>
        <dd>Display version number and exit.</dd>
    
        <dt><code>-w</code></dt>
        <dd>Print out results in HTML tables. Default table is two columns wide,
        with a white background.</dd>
    
        <dt><code>-x <var>&lt;table&gt;-attributes</var></code></dt>
        <dd>String to use as attributes for <code>&lt;table&gt;</code>. Attributes
        are inserted <code>&lt;table <var>here</var> &gt;</code>.</dd>
    
        <dt><code>-X <var>proxy</var>[:<var>port</var>]</code></dt>
        <dd>Use a proxy server for the requests.</dd>
    
        <dt><code>-y <var>&lt;tr&gt;-attributes</var></code></dt>
        <dd>String to use as attributes for <code>&lt;tr&gt;</code>.</dd>
    
        <dt><code>-z <var>&lt;td&gt;-attributes</var></code></dt>
        <dd>String to use as attributes for <code>&lt;td&gt;</code>.</dd>
    
        <dt><code>-Z <var>ciphersuite</var></code></dt>
        <dd>Specify SSL/TLS cipher suite (See openssl ciphers)</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="output" id="output">Output</a></h2>
        <p>The following list describes the values returned by <code>ab</code>:
        </p>
    
        <dl>
            <dt>Server Software</dt>
            <dd>The value, if any, returned in the <var>server</var> HTTP header
            of the first successful response. This includes all characters in the
            header from beginning to the point a character with decimal value of 32
            (most notably: a space or CR/LF) is detected.</dd>
    
            <dt>Server Hostname</dt>
            <dd>The DNS or IP address given on the command line</dd>
    
            <dt>Server Port</dt>
            <dd>The port to which ab is connecting. If no port is given on the
            command line, this will default to 80 for http and 443 for
            https.</dd>
    
            <dt>SSL/TLS Protocol</dt>
            <dd>The protocol parameters negotiated between the client and server.
            This will only be printed if SSL is used.</dd>
    
            <dt>Document Path</dt>
            <dd>The request URI parsed from the command line string.</dd>
    
            <dt>Document Length</dt>
            <dd>This is the size in bytes of the first successfully returned document.
            If the document length changes during testing, the response is
            considered an error.</dd>
    
            <dt>Concurrency Level</dt>
            <dd>The number of concurrent clients used during the test</dd>
    
            <dt>Time taken for tests</dt>
            <dd>This is the time taken from the moment the first socket connection
            is created to the moment the last response is received</dd>
    
            <dt>Complete requests</dt>
            <dd>The number of successful responses received</dd>
    
            <dt>Failed requests</dt>
            <dd>The number of requests that were considered a failure. If the
            number is greater than zero, another line will be printed showing the
            number of requests that failed due to connecting, reading, incorrect
            content length, or exceptions.</dd>
    
            <dt>Write errors</dt>
            <dd>The number of errors that failed during write (broken pipe).</dd>
    
            <dt>Non-2xx responses</dt>
            <dd>The number of responses that were not in the 200 series of response
            codes. If all responses were 200, this field is not printed.</dd>
    
            <dt>Keep-Alive requests</dt>
            <dd>The number of connections that resulted in Keep-Alive requests</dd>
    
            <dt>Total body sent</dt>
            <dd>If configured to send data as part of the test, this is the total
            number of bytes sent during the tests. This field is omitted if the test
            did not include a body to send.</dd>
    
            <dt>Total transferred</dt>
            <dd>The total number of bytes received from the server. This number
            is essentially the number of bytes sent over the wire.</dd>
    
            <dt>HTML transferred</dt>
            <dd>The total number of document bytes received from the server. This
            number excludes bytes received in HTTP headers</dd>
    
            <dt>Requests per second</dt>
            <dd>This is the number of requests per second. This value is the result
            of dividing the number of requests by the total time taken</dd>
    
            <dt>Time per request</dt>
            <dd>The average time spent per request. The first value is calculated
            with the formula <code>concurrency * timetaken * 1000 / done</code>
            while the second value is calculated with the formula
            <code>timetaken * 1000 / done</code></dd>
    
            <dt>Transfer rate</dt>
            <dd>The rate of transfer as calculated by the formula
            <code>totalread / 1024 / timetaken</code></dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Bugs</a></h2>
        <p>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.</p>
    
        <p>It does not implement HTTP/1.x fully; only accepts some 'expected' forms
        of responses. The rather heavy use of <code>strstr(3)</code> shows up top
        in profile, which might indicate a performance problem; <em>i.e.</em>, you
        would measure the <code>ab</code> performance rather than the server's.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/ab.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/ab.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/ab.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/ab.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/ab.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/dbmmanage.html.en�������������������������������������������������0000664�0001751�0001751�00000032455�14737241666�022114� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>dbmmanage - Manage user authentication files in DBM format - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>dbmmanage - Manage user authentication files in DBM format</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/dbmmanage.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>dbmmanage</code> is used to create and update the DBM format files
        used to store usernames and password for basic authentication of HTTP users
        via <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code>.
        Resources available from the Apache HTTP server can be restricted to just
        the users listed in the files created by <code>dbmmanage</code>. This
        program can only be used when the usernames are stored in a DBM file. To
        use a flat-file database see <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>.</p>
    
        <p>Another tool to maintain a DBM password database is
        <code class="program"><a href="../programs/htdbm.html">htdbm</a></code>.</p>
    
        <p>This manual page only lists the command line arguments. For details of
        the directives necessary to configure user authentication in
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> see the httpd manual, which is part of
        the Apache distribution or can be found at <a href="http://httpd.apache.org/">http://httpd.apache.org/</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Bugs</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></li><li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li><li><code class="module"><a href="../mod/mod_authz_dbm.html">mod_authz_dbm</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>dbmmanage</strong> [ <var>encoding</var> ]
        <var>filename</var> add|adduser|check|delete|update
        <var>username</var>
        [ <var>encpasswd</var>
          [ <var>group</var>[,<var>group</var>...]
            [ <var>comment</var> ] ] ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>filename</var>
        view [ <var>username</var> ]</code></p>
    
        <p><code><strong>dbmmanage</strong> <var>filename</var> import</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code><var>filename</var></code></dt>
        <dd>The filename of the DBM format file. Usually without the extension
        <code>.db</code>, <code>.pag</code>, or <code>.dir</code>.</dd>
    
        <dt><code><var>username</var></code></dt>
        <dd>The user for which the operations are performed. The <var>username</var>
        may not contain a colon (<code>:</code>).</dd>
    
        <dt><code><var>encpasswd</var></code></dt>
        <dd>This is the already hashed password to use for the
        <code>update</code> and <code>add</code> commands. You may use a hyphen
        (<code>-</code>) if you want to get prompted for the password, but fill
        in the fields afterwards. Additionally when using the <code>update</code>
        command, a period (<code>.</code>) keeps the original password
        untouched.</dd>
    
        <dt><code><var>group</var></code></dt>
        <dd>A group, which the user is member of. A groupname may not contain a
        colon (<code>:</code>). You may use a hyphen (<code>-</code>) if you don't
        want to assign the user to a group, but fill in the comment field.
        Additionally when using the <code>update</code> command, a period
        (<code>.</code>) keeps the original groups untouched.</dd>
    
        <dt><code><var>comment</var></code></dt>
        <dd>This is the place for your opaque comments about the user, like
        realname, mailaddress or such things. The server will ignore this
        field.</dd>
        </dl>
    
        <h3><a name="options.encodings" id="options.encodings">Encodings</a></h3>
          <dl>
          <dt><code>-d</code></dt>
          <dd>crypt hashing (default, except on Win32, Netware)</dd>
    
          <dt><code>-m</code></dt>
          <dd>MD5 hashing (default on Win32, Netware)</dd>
    
          <dt><code>-s</code></dt>
          <dd>SHA1 hashing</dd>
    
          <dt><code>-p</code></dt>
          <dd>plaintext (<em>not recommended</em>)</dd>
          </dl>
        
    
        <h3><a name="options.commands" id="options.commands">Commands</a></h3>
          <dl>
          <dt><code>add</code></dt>
          <dd>Adds an entry for <var>username</var> to <var>filename</var> using the
          hashed password <var>encpasswd</var>.
    
          <div class="example"><p><code>dbmmanage passwords.dat add rbowen foKntnEF3KSXA</code></p></div>
          </dd>
    
          <dt><code>adduser</code></dt>
          <dd>Asks for a password and then adds an entry for <var>username</var> to
          <var>filename</var>.
    
          <div class="example"><p><code>dbmmanage passwords.dat adduser krietz</code></p></div>
          </dd>
    
          <dt><code>check</code></dt>
          <dd>Asks for a password and then checks if <var>username</var> is in
          <var>filename</var> and if it's password matches the specified one.
    
          <div class="example"><p><code>dbmmanage passwords.dat check rbowen</code></p></div>
          </dd>
    
          <dt><code>delete</code></dt>
          <dd>Deletes the <var>username</var> entry from <var>filename</var>.
    
          <div class="example"><p><code>dbmmanage passwords.dat delete rbowen</code></p></div>
          </dd>
    
          <dt><code>import</code></dt>
          <dd>Reads <code><var>username</var>:<var>password</var></code> entries
          (one per line) from <code>STDIN</code> and adds them to
          <var>filename</var>. The passwords already have to be crypted.</dd>
    
          <dt><code>update</code></dt>
          <dd>Same as the <code>adduser</code> command, except that it makes
          sure <var>username</var> already exists in <var>filename</var>.
    
          <div class="example"><p><code>dbmmanage passwords.dat update rbowen</code></p></div>
          </dd>
    
          <dt><code>view</code></dt>
          <dd>Just displays the contents of the DBM file. If you specify a
          <var>username</var>, it displays the particular record only.
    
          <div class="example"><p><code>dbmmanage passwords.dat view</code></p></div>
          </dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Bugs</a></h2>
        <p>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 <var>filename</var> is the same format that <code>dbmmanage</code>
        expects to see. <code>dbmmanage</code> 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.</p>
    
        <p><code>dbmmanage</code> has a list of DBM format preferences, defined by
        the <code>@AnyDBM::ISA</code> array near the beginning of the program. Since
        we prefer the Berkeley DB 2 file format, the order in which
        <code>dbmmanage</code> will look for system libraries is Berkeley DB 2,
        then NDBM, then GDBM and then SDBM. The first library found will be the
        library <code>dbmmanage</code> will attempt to use for all DBM file
        transactions. This ordering is slightly  different than the standard
        <code>@AnyDBM::ISA</code> ordering in Perl, as well as the ordering used by
        the simple <code>dbmopen()</code> 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.</p>
    
        <p>One can usually use the <code>file</code> program supplied with most
        Unix systems to see what format a DBM file is in.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/dbmmanage.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/dbmmanage.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/dbmmanage.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/dbmmanage.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/dbmmanage.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/suexec.html.ko.euc-kr���������������������������������������������0000664�0001751�0001751�00000015241�14743132254�022650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>suexec - ܺ α׷ ϱ  ڸ Ѵ - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>suexec - ܺ α׷ ϱ  ڸ Ѵ</h1>
    <div class="toplang">
    <p><span> : </span><a href="../en/programs/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
         <p>ġ  CGI α׷ ϱ  ٸ ڷ
         ȯϱ <code>suexec</code> Ѵ. ̸ Ϸ
          <code>root</code>  ؾ Ѵ.  
          <code>root</code>   ʱ⶧
         <code>suexec</code> Ͽ setuid Ʈ ϰ
         <code>root</code> ̾ Ѵ. <code>root</code>̿
         ٸ ڰ   ȵȴ.</p>
    
         <p>suexec  ȸ𵨿   suexec 
         (<a href="http://httpd.apache.org/docs/2.4/suexec.html">http://httpd.apache.org/docs/2.4/suexec.html</a>) ϶.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis"></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">ɼ</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis"></a></h2>
         <p><code><strong>suexec</strong> -<strong>V</strong></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">ɼ</a></h2>
    
    <dl>
    <dt><code>-V</code></dt>
    
    <dd><code>root</code> ϸ <code>suexec</code> 
    ɼ Ѵ. Ȼ   ɼ  
      ִ.</dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="../en/programs/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/"></a> | <a href="../mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html"></a> | <a href="../sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apxs.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000052514�14740503670�022032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>apxs - Utilitaire pour les extensions d'Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>apxs - Utilitaire pour les extensions d'Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/apxs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>apxs</code> est un utilitaire permettant de compiler et
        d'installer des modules en tant qu'extensions du serveur HTTP
        Apache. A cet effet, un objet dynamique partagé (DSO) est compilé à
        partir d'un ou plusieurs <var>fichiers</var> sources ou objets et
        peut être chargé pendant l'exécution du serveur Apache via la
        directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> du
        module <code class="module"><a href="../mod/mod_so.html">mod_so</a></code>.</p>
    
        <p>Pour pouvoir utiliser ce mécanisme d'extensions, votre
        plate-forme doit supporter la fonctionnalité DSO, et votre binaire
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> Apache doit être compilé avec le module
        <code class="module"><a href="../mod/mod_so.html">mod_so</a></code>. Si ce n'est pas le cas, l'utilitaire
        <code>apxs</code> vous le signalera. Vous pouvez aussi vérifier
        vous-même ces prérequis en exécutant manuellement la commande :</p>
    
        <div class="example"><p><code>
          $ httpd -l
        </code></p></div>
    
        <p>Le module <code class="module"><a href="../mod/mod_so.html">mod_so</a></code> doit faire partie de la liste
        des modules affichée. Si ces prérequis sont présents, vous pouvez
        facilement étendre les fonctionnalités de votre serveur Apache en
        installant vos propres modules à l'aide de l'utilitaire
        <code>apxs</code>, via le mécanisme DSO :</p>
    
        <div class="example"><p><code>
          $ apxs -i -a -c mod_foo.c<br />
          gcc -fpic -DSHARED_MODULE -I/chemin/vers/apache/include -c mod_foo.c<br />
          ld -Bshareable -o mod_foo.so mod_foo.o<br />
          cp mod_foo.so /chemin/vers/apache/modules/mod_foo.so<br />
          chmod 755 /chemin/vers/apache/modules/mod_foo.so<br />
          [activation du module `foo' dans /chemin/vers/apache/etc/httpd.conf]<br />
          $ apachectl restart<br />
          /chemin/vers/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /chemin/vers/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
        <p>Les arguments <var>fichiers</var> peuvent correspondre à un
        fichier source C (.c), un fichier objet (.o) ou même une archive de
        bibliothèques (.a). L'utilitaire <code>apxs</code> reconnaît
        automatiquement ces extensions et utilise automatiquement les
        fichiers source C pour la compilation, et les fichiers objets et
        archives pour l'édition de liens. Cependant, si vous utilisez des
        fichiers objets précompilés, assurez-vous que leur code soit
        indépendant de la position (PIC), afin de pouvoir les utiliser avec
        un objet partagé chargé dynamiquement. Avec GCC, par exemple, il
        vous suffit de toujours utiliser l'option de compilation
        <code>-fpic</code>. Pour les autres compilateurs C, consultez leur
        page de manuel, ou vérifiez les drapeaux qu'<code>apxs</code>
        utilise pour compiler les fichiers objets.</p>
    
        <p>Pour plus de détails à propos du support DSO dans Apache, lire la
        documentation du module <code class="module"><a href="../mod/mod_so.html">mod_so</a></code>, ou même, consultez
        le fichier source <code>src/modules/standard/mod_so.c</code>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Exemples</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></li><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>apxs</strong> -<strong>g</strong>
        [ -<strong>S</strong> <var>nom</var>=<var>valeur</var> ]
        -<strong>n</strong> <var>nom-module</var></code></p>
    
        <p><code><strong>apxs</strong> -<strong>q</strong>
        [ -<strong>v</strong> ]
        [ -<strong>S</strong> <var>nom</var>=<var>valeur</var> ]
        <var>requête</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>c</strong>
        [ -<strong>S</strong> <var>nom</var>=<var>valeur</var> ]
        [ -<strong>o</strong> <var>fichier-dso</var> ]
        [ -<strong>I</strong> <var>répertoire-inc</var> ]
        [ -<strong>D</strong> <var>nom</var>=<var>valeur</var> ]
        [ -<strong>L</strong> <var>répertoire-lib</var> ]
        [ -<strong>l</strong> <var>nom-bibliothèque</var> ]
        [ -<strong>Wc,</strong><var>options-compilation</var> ]
        [ -<strong>Wl,</strong><var>options-edition-liens</var> ]
        <var>fichiers</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>i</strong>
        [ -<strong>S</strong> <var>nom</var>=<var>valeur</var> ]
        [ -<strong>n</strong> <var>nom-module</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>fichier-dso</var> ...</code></p>
    
        <p><code><strong>apxs</strong> -<strong>e</strong>
        [ -<strong>S</strong> <var>nom</var>=<var>valeur</var> ]
        [ -<strong>n</strong> <var>nom-module</var> ]
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]
        <var>fichier-dso</var> ...</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <h3><a name="options.common" id="options.common">Options courantes</a></h3>
          <dl>
          <dt><code>-n <var>nom-module</var></code></dt>
          <dd>Définit explicitement le nom du module pour les options
          <code>-i</code> (install) et <code>-g</code> (génération de
          modèles). Utilisez cette option pour spécifier de manière
          explicite le nom du module. Pour l'option <code>-g</code>, cette
          option est nécessaire ; pour l'option <code>-i</code>,
          l'utilitaire <code>apxs</code> tente de déterminer le nom du
          module à partir des sources, ou (à défaut) en le déduisant du nom
          de fichier.</dd>
          </dl>
        
    
        <h3><a name="options.query" id="options.query">Options de requête</a></h3>
          <dl>
          <dt><code>-q</code></dt>
          <dd>Effectue une requête à propos des variables et de
          l'environnement utilisés pour compiler <code>httpd</code>.
          Lorsqu'elle est invoquée sans paramètre <var>requête</var>, cette
          option affiche toutes les variables connues, ainsi que leurs
          valeurs. Le paramètre optionnel <code>-v</code> formate la liste
          affichée.
    
          <p>Utilisez cette option pour déterminer manuellement les options
          utilisées pour compiler le binaire <code>httpd</code> qui chargera
          votre module. Ajoutez par exemple</p>
          <div class="example"><p><code>
            INC=-I`apxs -q INCLUDEDIR`
          </code></p></div>
    
          <p>dans vos propres Makefiles si vous devez accéder manuellement
          aux fichiers d'en-têtes C d'Apache.</p></dd>
          </dl>
        
    
        <h3><a name="options.conf" id="options.conf">Options de configuration</a></h3>
          <dl>
          <dt><code>-S <var>nom</var>=<var>valeur</var></code></dt>
          <dd>Cette option permet de modifier la configuration d'apxs
          décrite ci-dessus.</dd>
          </dl>
        
    
        <h3><a name="options.template" id="options.template">Option de génération des
        modèles</a></h3>
          <dl>
          <dt><code>-g</code></dt>
          <dd>Cette option permet de générer un sous-répertoire
          <var>nom</var> (voir option <code>-n</code>) contenant deux
          fichiers : le premier fichier est un exemple de fichier source de
          module nommé <code>mod_<var>nom</var>.c</code> que l'on peut
          utiliser comme modèle pour créer ses propres modules, ou comme
          point de départ pour se familiariser avec le mécanisme apxs ; le
          second fichier est le <code>Makefile</code> correspondant
          facilitant la compilation et l'installation de ce module.</dd>
          </dl>
        
        <h3><a name="options.dso" id="options.dso">Options de compilation DSO</a></h3>
          <dl>
          <dt><code>-c</code></dt>
          <dd>Cette option indique une opération de compilation. Tout
          d'abord, les fichiers sources (.c) spécifiés par
          <var>fichiers</var> sont compilés en fichiers objets
          correspondants (.o), puis un objet dynamiquement partagé
          <var>fichier-dso</var> est compilé via une édition de liens de ces
          fichiers objets avec les autres fichiers objets (.o and .a)
          spécifiés par <var>fichiers</var>. Si l'option <code>-o</code>
          n'est pas spécifiée, le nom du fichier résultant est déduit du
          premier nom de fichier spécifié par <var>fichiers</var>, et ainsi
          prend en général pour valeur par défaut
          <code>mod_<var>nom</var>.so</code>.</dd>
    
          <dt><code>-o <var>fichier-dso</var></code></dt>
          <dd>Spécifie de manière explicite le nom de fichier de l'objet
          partagé dynamiquement créé. Sans cette option, et si le nom ne
          peut pas être déduit de la liste <var>fichiers</var>, c'est le nom
          par défaut <code>mod_unknown.so</code> qui sera utilisé.</dd>
    
          <dt><code>-D <var>nom</var>=<var>valeur</var></code></dt>
          <dd>Cette option est transmise directement à la commande de
          compilation. Vous pouvez l'utiliser pour ajouter vos propres
          définitions au processus de compilation. </dd>
    
          <dt><code>-I <var>répertoire-inc</var></code></dt>
          <dd>Cette option est transmise directement à la commande de
          compilation. Vous pouvez l'utiliser pour ajouter vos propres
          chemins de recherche des répertoires <code>include</code> au processus de
          compilation.</dd>
    
          <dt><code>-L <var>répertoire-lib</var></code></dt>
          <dd>Cette option est transmise directement à la commande d'édition
          de liens. Vous pouvez l'utiliser pour ajouter vos propres
          chemins de recherche des répertoires de bibliothèques au processus
          de compilation.</dd>
    
          <dt><code>-l <var>nom-bibliothèque</var></code></dt>
          <dd>Cette option est transmise directement à la commande d'édition
          de liens. Vous pouvez l'utiliser pour ajouter vos propres
          bibliothèques à rechercher au processus de compilation.</dd>
    
          <dt><code>-Wc,<var>options-compilation</var></code></dt>
          <dd>Cette option transmet les <var>options-compilation</var> en
          tant qu'options supplémentaires à la commande <code>libtool
          --mode=compile</code>. Vous pouvez l'utiliser pour ajouter des
          options locales spécifiques au compilateur.</dd>
    
          <dt><code>-Wl,<var>options-edition-liens</var></code></dt>
          <dd>Cette option transmet les <var>options-edition-liens</var> en
          tant qu'options supplémentaires à la commande <code>libtool
          --mode=link</code>. Vous pouvez l'utiliser pour ajouter des
          options locales spécifiques à l'éditeur de liens.</dd>
          
          <dt><code>-p</code></dt>
          <dd>Avec cette option, apxs effectue l'édition de liens avec les
          bibliothèques apr/apr-util. Elle permet de compiler les programmes
          helper qui utilisent les bibliothèques apr/apr-util.</dd>
          </dl>
        
    
        <h3><a name="options.dsoinstall" id="options.dsoinstall">Options d'installation et de configuration DSO</a></h3>
        
          <dl>
          <dt><code>-i</code></dt>
          <dd>Cette option indique une opération d'installation et installe
          un ou plusieurs objets dynamiquement partagés dans le répertoire
          <var>modules</var> du serveur.</dd>
    
          <dt><code>-a</code></dt>
          <dd>Cette option active le module en ajoutant automatiquement une
          directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>
          correspondante au fichier de configuration d'Apache
          <code>httpd.conf</code>, ou en l'activant s'il existe déjà.</dd>
    
          <dt><code>-A</code></dt>
          <dd>Identique à l'option <code>-a</code>, à la différence que la
          directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> créée
          est préfixée par un caractère dièse (<code>#</code>) ; le module
          est ainsi préparé pour une activation ultérieure, mais est
          désactivé dans un premier temps.</dd>
    
          <dt><code>-e</code></dt>
          <dd>Cette option indique une opération d'édition de liens et peut
          être utilisée avec les options <code>-a</code> et <code>-A</code>
          de la même manière qu'au cours de l'opération d'installation pour
          éditer le fichier de configuration d'Apache
          <code>httpd.conf</code>, sans toutefois installer le module.</dd>
          </dl>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples</a></h2>
        <p>Supposons que vous disposiez d'un module Apache nommé
        <code>mod_foo.c</code> et destiné à étendre les fonctionnalités du
        serveur. Pour ce faire, vous devez tout d'abord compiler le fichier
        source C en un objet partagé pouvant être chargé dans le serveur
        Apache à l'exécution, via la commande suivante :</p>
    
        <div class="example"><p><code>
          $ apxs -c mod_foo.c<br />
          /chemin/vers/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /chemin/vers/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          $ _
        </code></p></div>
    
        <p>Vous devez ensuite vérifier la configuration d'Apache en vous
        assurant qu'une directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> est bien présente pour
        charger cet objet partagé. Pour simplifier cette étape,
        <code>apxs</code> propose une méthode automatique d'installation de
        l'objet partagé dans son répertoire "modules", et de mise à jour du
        fichier <code>httpd.conf</code> en conséquence. Pour bénéficier de
        cette automatisation, utilisez la commande suivante :</p>
    
        <div class="example"><p><code>
          $ apxs -i -a mod_foo.la<br />
          /chemin/vers/instdso.sh mod_foo.la /chemin/vers/apache/modules<br />
          /chemin/vers/libtool --mode=install cp mod_foo.la /chemin/vers/apache/modules
          ...
          chmod 755 /chemin/vers/apache/modules/mod_foo.so<br />
          [activation du module `foo' dans /chemin/vers/apache/conf/httpd.conf]<br />
          $ _
        </code></p></div>
    
        <p>Une ligne contenant</p>
    
        <div class="example"><p><code>
          LoadModule foo_module modules/mod_foo.so
        </code></p></div>
    
        <p>est alors ajoutée au fichier de configuration si ce n'est pas
        déjà fait. Si vous voulez que le module soit désactivé par défaut,
        utilisez l'option <code>-A</code> comme suit :</p>
    
        <div class="example"><p><code>
          $ apxs -i -A mod_foo.c
        </code></p></div>
    
        <p>Pour un test rapide du mécanisme apxs, vous pouvez créer un
        exemple de modèle de module Apache, ainsi que le Makefile
        correspondant via :</p>
    
        <div class="example"><p><code>
          $ apxs -g -n foo<br />
          Creating [DIR]  foo<br />
          Creating [FILE] foo/Makefile<br />
          Creating [FILE] foo/modules.mk<br />
          Creating [FILE] foo/mod_foo.c<br />
          Creating [FILE] foo/.deps<br />
          $ _
        </code></p></div>
    
        <p>Vous pouvez ensuite compiler immédiatement ce module exemple en
        objet partagé et le charger dans le serveur Apache :</p>
    
        <div class="example"><p><code>
          $ cd foo<br />
          $ make all reload<br />
          apxs -c mod_foo.c<br />
          /chemin/vers/libtool --mode=compile gcc ... -c mod_foo.c<br />
          /chemin/vers/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo<br />
          apxs -i -a -n "foo" mod_foo.la<br />
          /chemin/vers/instdso.sh mod_foo.la /chemin/vers/apache/modules<br />
          /chemin/vers/libtool --mode=install cp mod_foo.la /chemin/vers/apache/modules
          ...
          chmod 755 /chemin/vers/apache/modules/mod_foo.so<br />
          [activation du module `foo' dans /chemin/vers/apache/conf/httpd.conf]<br />
          apachectl restart<br />
          /chemin/vers/apache/sbin/apachectl restart: httpd not running, trying to start<br />
          [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module<br />
          /chemin/vers/apache/sbin/apachectl restart: httpd started<br />
          $ _
        </code></p></div>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/apxs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/apxs.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/apxs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/apxs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/apxs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htcacheclean.html.fr.utf8�����������������������������������������0000664�0001751�0001751�00000036745�14740503670�023471� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htcacheclean - Nettoyage du cache sur disque - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>htcacheclean - Nettoyage du cache sur disque</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htcacheclean.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htcacheclean</code> permet de maintenir la taille de
        l'espace de stockage réservé à <code class="module"><a href="../mod/mod_disk_cache.html">mod_disk_cache</a></code> en
        dessous d'une limite de taille donnée ou d'inodes utilisés. Cet
        utilitaire peut s'exécuter
        soit manuellement, soit en mode démon. Lorsqu'il fonctionne en mode
        démon, il se met en attente en arrière-plan et recherche à
        intervalles réguliers dans le répertoire du cache les contenus à
        supprimer. Pour arrêter proprement le démon, vous pouvez lui envoyer
        un signal TERM ou INT. Lorsqu'il est lancé manuellement, une
        recherche des contenus du cache qui peuvent être supprimés est
        effectuée une seule fois. Si une ou plusieurs URLs sont spécifiées,
        chacune d'entre elles sera supprimée du cache, si elle est présente.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#delete">Suppression d'une URL particulière</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#list">Affichage des URLs présentes dans le cache</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Valeur renvoyée</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="module"><a href="../mod/mod_disk_cache.html">mod_disk_cache</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
        <p><code><strong>htcacheclean</strong>
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>r</strong> ]
        [ -<strong>n</strong> ]
        [ -<strong>R</strong><var>arrondi</var> ]
        -<strong>p</strong><var>chemin</var>
        [ -<strong>l</strong><var>limite</var> ]
        [ -<strong>L</strong><var>limite</var> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>n</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>i</strong> ]
        [ -<strong>P</strong><var>fichier-pid</var> ]
        [ -<strong>R</strong><var>arrondi</var> ]
        -<strong>d</strong><var>intervalle</var>
        -<strong>p</strong><var>chemin</var>
        [ -<strong>l</strong><var>limite</var> ]
        [ -<strong>L</strong><var>limite</var> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>v</strong> ]
        [ -<strong>R</strong><var>arrondi</var> ]
        -<strong>p</strong><var>chemin</var>
        [ -<strong>a</strong> ]
        [ -<strong>A</strong> ]</code></p>
    
        <p><code><strong>htcacheclean</strong>
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]
        [ -<strong>t</strong> ]
        [ -<strong>R</strong><var>arrondi</var> ]
        -<strong>p</strong><var>chemin</var>
        <var>url</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-d<var>intervalle</var></code></dt>
        <dd>Configure en mode démon et planifie le nettoyage du cache toutes
        les <var>intervalle</var> minutes. Cette option et les options
        <code>-D</code>, <code>-v</code> et <code>-r</code> s'excluent
        mutuellement. Pour arrêter le démon proprement, il suffit de lui
        envoyer un signal <code>SIGTERM</code> ou <code>SIGINT</code>.</dd>
    
        <dt><code>-D</code></dt>
        <dd>Le programme s'exécute mais ne supprime aucun contenu ("dry run"). Cette
        option et l'option <code>-d</code> s'excluent mutuellement. Si ce mode
        est combiné avec la suppression des répertoires avec
        <code>-t</code>, les inodes signalés comme supprimés dans les
        statistiques ne peuvent pas prendre en compte les répertoires
        supprimés, et seront marqués en tant qu'estimation.</dd>
    
        <dt><code>-v</code></dt>
        <dd>Exécution verbeuse et affichage de statistiques. Cette
        option et l'option <code>-d</code> s'excluent mutuellement.</dd>
    
        <dt><code>-r</code></dt>
        <dd>Nettoyage en profondeur. Le serveur web Apache doit être arrêté
        (dans le cas contraire, il risque de rester des déchets dans le
        cache). Cette option implique l'option <code>-t</code> et s'exclue
        mutuellement avec l'option <code>-d</code>.</dd>
    
        <dt><code>-n</code></dt>
        <dd>Exécution en retrait. L'exécution du programme est ralentie en
        faveur des autres processus. <code>htcacheclean</code> s'interrompt
        de temps en temps de façon à ce que a) les entrées/sorties disque
        soient retardées et b) que le noyau puisse mettre ce temps
        processeur à disposition des autres processus.</dd>
    
        <dt><code>-t</code></dt>
        <dd>Supprime tous les répertoires vides. Par défaut, seuls les
        fichiers sont supprimés du cache ; avec certaines configurations,
        cependant, un grand nombre de répertoires sont créés et méritent que
        l'on y prête attention. Si votre configuration nécessite un grand
        nombre de répertoires, au point que le remplissage de la table
        d'inodes ou d'allocation de fichiers puisse poser problème,
        l'utilisation de cette option est conseillée.</dd>
    
        <dt><code>-p<var>chemin</var></code></dt>
        <dd>Définit <var>chemin</var> comme répertoire racine du cache sur
        disque. Cette valeur doit correspondre à celle spécifiée par la
        directive <code class="directive"><a href="../mod/mod_disk_cache.html#cacheroot">CacheRoot</a></code>.</dd>
    
        <dt><code>-P<var>fichier-pid</var></code></dt>
        <dd>Permet de spécifier <var>fichier-pid</var> comme nom du fichier
        dans le lequel sera enregistré l'identifiant du processus en mode
        démon.</dd>
    
        <dt><code>-R<var>round</var></code></dt>
        <dd>Permet de spécifier le plus petit commun multiple de la taille
        du cache, afin de tenir compte de la taille des blocs. Définir ce
        paramètre à la taille d'un bloc de la partition du cache.</dd>
    
        <dt><code>-l<var>limite</var></code></dt>
        <dd>Définit <var>limite</var> comme la taille maximale du cache sur
        disque. La valeur s'exprime par défaut en octets (ou en ajoutant le
        suffixe <code>B</code> à la valeur). Ajoutez le suffixe
        <code>K</code> pour Ko, <code>M</code> pour Mo ou <code>G</code> pour
        Go.</dd>
    
        <dt><code>-L<var>limite</var></code></dt>
        <dd>Spécifie <var>limite</var> comme la limite totale en inodes du cache
        disque. Là aussi, on peut ajouter le suffixe <code>K</code> pour Ko,
        <code>M</code> pour Mo ou <code>G</code> pour Go.</dd>
    
        <dt><code>-i</code></dt>
        <dd>Exécution intelligente. Le programme ne s'exécute que lorsque le
        cache sur disque a été modifié. Cette option ne peut s'utiliser
        qu'avec l'option <code>-d</code>.</dd>
    
        <dt><code>-a</code></dt>
        <dd>Affiche la liste des URLs actuellement stockées dans le cache.
        Les variantes de la même URL seront listées une seule fois par
        variante.</dd>
    
        <dt><code>-A</code></dt>
        <dd>Affiche la liste des URLs actuellement stockées dans le cache,
        ainsi que leurs attributs dans l'ordre suivant : url, header size,
        body size, status, entity version, date, expiry, request time,
        response time, body present, head request.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="delete" id="delete">Suppression d'une URL particulière</a></h2>
        <p>Si une ou plusieurs URLs sont passées en argument à
        <code>htcacheclean</code>, chacune d'entre elles sera supprimée du
        cache. S'il existe plusieurs variantes de ces URLs, elles seront
        toutes supprimées.</p>
    
        <p>Lorsqu'une URL mandatée en inverse doit être supprimée, l'URL
        effective est construite à partir de l'en-tête
        <strong>Host</strong>, du <strong>port</strong>, du
        <strong>chemin</strong> et de la <strong>requête</strong>. Notez que
        le '?' doit toujours être spécifié explicitement dans l'URL, qu'une
        chaîne de paramètres soit présente ou non. Par exemple, pour
        supprimer le chemin <strong>/</strong> du serveur
        <strong>localhost</strong>, l'URL devra être spécifiée comme suit :
        <strong>http://localhost:80/?</strong>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="list" id="list">Affichage des URLs présentes dans le cache</a></h2>
        <p>Les options <code>-a</code> ou <code>-A</code> permettent
        d'afficher les URLs présentes dans le cache telles qu'elles s'y
        trouvent, une URL par ligne. L'option <code>-A</code> affiche
        l'entrée du cache complète pour chaque URL, avec ses différents
        champs dans l'ordre suivant :</p>
    
        <dl>
            <dt>url</dt><dd>L'URL de l'entrée considérée.</dd>
            <dt>header size</dt><dd>La taille de l'en-tête en octets.</dd>
            <dt>body size</dt><dd>La taille du corps en octets.</dd>
            <dt>status</dt><dd>Etat de la réponse en cache.</dd>
            <dt>entity version</dt><dd>Le nombre de fois que cette entrée a
    	été revalidée sans être effacée.</dd>
            <dt>date</dt><dd>Date de la réponse.</dd>
            <dt>expiry</dt><dd>Date d'expiration de la réponse.</dd>
            <dt>request time</dt><dd>Date du début de la requête.</dd>
            <dt>response time</dt><dd>Date de la fin de la requête.</dd>
            <dt>body present</dt><dd>Ce champ contient la valeur 0 si aucun
    	corps n'est stocké avec cette requête, 1 dans le cas contraire.</dd>
            <dt>head request</dt><dd>Ce champ contient la valeur 1 si
    	l'entrée comporte une requête HEAD en cache sans corps, 0 dans
    	le cas contraire.</dd>
        </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Valeur renvoyée</a></h2>
        <p><code>htcacheclean</code> renvoie zéro ("true") si toutes les
        opérations se sont déroulées normalement, et <code>1</code> dans le
        cas contraire. Si une URL est spécifiée, et si cette URL était
        présente dans le cache et a été supprimée avec succès,
        <code>htcacheclean</code> renvoie <code>0</code>, et <code>2</code>
        dans le cas contraire. Si une erreur est survenue au cours de la
        suppression de l'URL, <code>htcacheclean</code> renvoie
        <code>1</code>.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/htcacheclean.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htcacheclean.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htcacheclean.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htcacheclean.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htcacheclean.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������httpd-2.4.64/docs/manual/programs/httpd.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000031377�14740503670�022206� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>httpd - Le serveur HTTP d'Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>httpd - Le serveur HTTP d'Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/httpd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>httpd</code> est le programme du serveur HTTP d'Apache. Il
         a été conçu pour fonctionner sous forme de processus démon
         indépendant. Lorsqu'il est utilisé ainsi, il va créer un jeu de
         processus enfants ou de threads qui traiteront les requêtes.</p>
    
         <p>En général, <code>httpd</code> n'est pas invoqué directement,
         mais plutôt via <code class="program"><a href="../programs/apachectl.html">apachectl</a></code> sur les systèmes de
         style Unix ou <a href="../platform/windows.html#winsvc">en tant que service sous
         Windows NT, 2000 et XP</a> et <a href="../platform/windows.html#wincons">comme application de
         console sous Windows 9x et ME</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../invoking.html">Démarrer Apache httpd</a></li><li><a href="../stopping.html">Arrêter Apache httpd</a></li><li><a href="../configuring.html">Fichiers de configuration</a></li><li><a href="../platform/">Documentations spécifiques aux
    plates-formes</a></li><li><code class="program"><a href="../programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
         <p><code><strong>httpd</strong> [ -<strong>d</strong>
         <var>racine-serveur</var> ] [ -<strong>f</strong> <var>config</var> ]
         [ -<strong>C</strong> <var>directive</var> ] [ -<strong>c</strong>
         <var>directive</var> ] [ -<strong>D</strong> <var>paramètre</var> ]
         [ -<strong>e</strong> <var>niveau</var> ] [ -<strong>E</strong>
         <var>fichier</var> ]
         [ <strong>-k</strong> start|restart|graceful|stop|graceful-stop ]
         [ -<strong>h</strong> ]
         [ -<strong>l</strong> ] [ -<strong>L</strong> ] [ -<strong>S</strong> ]
         [ -<strong>t</strong> ] [ -<strong>v</strong> ] [ -<strong>V</strong> ]
         [ -<strong>X</strong> ] [ -<strong>M</strong> ] [ -<strong>T</strong> ]
         </code></p>
    
         <p>Sur les <a href="../platform/windows.html">systèmes Windows</a>,
         les options additionnelles suivantes sont disponibles :</p>
    
         <p><code><strong>httpd</strong> [ -<strong>k</strong>
         install|config|uninstall ] [ -<strong>n</strong> <var>nom</var> ]
         [ -<strong>w</strong> ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    <dt><code>-d <var>racine-serveur</var></code></dt>
    
    <dd>Définit la valeur initiale de la directive <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> à <var>racine-serveur</var>. Cette
    valeur peut être écrasée par la directive ServerRoot du fichier de
    configuration. La valeur par défaut est
    <code>/usr/local/apache2</code>.</dd>
    
    <dt><code>-f <var>config</var></code></dt>
    
    <dd>Utilise les directives du fichier <var>config</var> au démarrage. Si
    <var>config</var> ne commence pas par un '/', il est considéré comme
    relatif au chemin défini par la directive <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code>. La valeur par défaut est
    <code>conf/httpd.conf</code>.</dd>
    
    <dt><code>-k <code>start|restart|graceful|stop|graceful-stop</code></code></dt>
    
    <dd>Permet de démarrer, redémarrer ou arrêter <code>httpd</code>. Voir <a href="../stopping.html">Arrêter Apache httpd</a> pour plus d'informations.</dd>
    
    <dt><code>-C <var>directive</var></code></dt>
    
    <dd>Exécute la directive de configuration <var>directive</var> avant de
    lire les fichiers de configurations.</dd>
    
    <dt><code>-c <var>directive</var></code></dt>
    
    <dd>Exécute la directive de configuration <var>directive</var> après
    avoir lu les fichiers de configurations.</dd>
    
    
    <dt><code>-D <var>paramètre</var></code></dt>
    
    <dd>Définit un <var>paramètre</var> de configuration à utiliser dans les
    sections <code class="directive"><a href="../mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>
    des fichiers de configuration, ces dernières permettant d'exécuter ou
    non des
    commandes au démarrage ou au redémarrage du serveur. Sert aussi à
    définir certains paramètres de démarrage moins courants comme
    <code>-DNO_DETACH</code> (empêche le processus parent de lancer des
    processus enfants) et <code>-DFOREGROUND</code> (empêche le processus
    parent d'appeler <code>setsid()</code> et autres).</dd>
    
    <dt><code>-e <var>niveau</var></code></dt>
    
    <dd>Définit la directive <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> à
    <var>niveau</var> pendant le démarrage du serveur. Ceci permet
    d'augmenter temporairement la verbosité des messages d'erreur afin de
    déterminer les problèmes de démarrage.</dd>
    
    <dt><code>-E <var>fichier</var></code></dt>
    
    <dd>Envoie les messages d'erreur de démarrage vers le fichier
    <var>fichier</var>.</dd>
    
    <dt><code>-h</code></dt>
    
    <dd>Affiche un bref résumé des options de ligne de commande
    disponibles.</dd>
    
    <dt><code>-l</code></dt>
    
    <dd>Affiche la liste des modules compilés dans le le serveur. Ce
    paramètre n'affiche <strong>pas</strong> les modules chargés
    dynamiquement via la directive <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>.</dd>
    
    <dt><code>-L</code></dt>
    
    <dd>Affiche une liste des directives fournies par les modules statiques
    avec les arguments associés, ainsi que les contextes dans lesquels elles
    sont valides. Les directives fournies par les modules partagés
    (dynamiques) ne sont pas affichées).</dd>
    
    <dt><code>-M</code></dt>
    
    <dd>Affiche une liste des modules statiques et des modules chargés
    dynamiquement.</dd>
    
    <dt><code>-S</code></dt>
    
    <dd>Affiche la configuration telle qu'elle est issue de l'interprétation
    du fichier de configuration (actuellement, seule la configuration des
    serveurs virtuels est affichée).</dd>
    
    <dt><code>-T</code> (disponible depuis la version 2.3.8)</dt>
    
    <dd>Empêche la vérification de la racine des documents (DocumentRoot) au
    démarrage/redémarrage.</dd>
    
    <dt><code>-t</code></dt>
    
    <dd>Exécute une vérification de syntaxe pour les fichiers de
    configuration seulement. Le programme se termine immédiatement après ces
    tests de vérification de syntaxe avec soit un code de retour de 0
    (syntaxe OK), soit un code de retour différent de 0 (erreur de
    syntaxe). Si -D <var>DUMP</var>_<var>VHOSTS </var> est défini, les
    détails de la configuration des serveurs virtuels seront affichés. Si -D
    <var>DUMP</var>_<var>MODULES </var> est défini, tous les modules chargés
    seront affichés.</dd>
    
    <dt><code>-v</code></dt>
    
    <dd>Print the version of <code>httpd</code>, and then exit.</dd>
    
    <dt><code>-V</code></dt>
    
    <dd>Le programme affiche la version et les paramètres de compilation de
    <code>httpd</code>, puis se termine.</dd>
    
    <dt><code>-X</code></dt>
    
    <dd>Exécute httpd en mode debug. Un seul processus sera démarré, et le
    serveur ne rendra pas la main à la console.</dd>
    
    </dl>
    
    <p>Les arguments suivants ne sont disponibles que sur la <a href="../platform/windows.html">plate-forme Windows</a> :</p>
    
    <dl>
    
    <dt><code>-k install|config|uninstall</code></dt>
    
    <dd>Respectivement : installe Apache httpd en tant que service Windows NT ;
    modifie les options de démarrage du service Apache httpd ; désinstalle le
    service Apache httpd.</dd>
    
    <dt><code>-n <var>nom</var></code></dt>
    
    <dd>Le <var>nom</var> du service Apache httpd à actionner.</dd>
    
    <dt><code>-w</code></dt>
    
    <dd>Garde la console Windows ouverte en cas de problème de façon à ce
    que le message d'erreur puisse être lu.</dd>
    
    </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/httpd.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httpd.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/httpd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/httpd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/httpd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/logresolve.html.fr.utf8�������������������������������������������0000664�0001751�0001751�00000016223�14740503670�023235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>logresolve - Résoud les adresses IP en noms d'hôtes dans les
      fichiers journaux d'Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programmes</a></div><div id="page-content"><div id="preamble"><h1>logresolve - Résoud les adresses IP en noms d'hôtes dans les
      fichiers journaux d'Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/logresolve.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>logresolve</code> est un programme agissant après
         traitement pour résoudre les adresses IP dans les journaux d'accès
         d'Apache. Pour minimiser la charge de votre serveur de noms,
         logresolve possède son propre cache interne sous forme d'une table
         de hashage. Cela implique que chaque numéro IP ne fera l'objet
         d'une requête DNS que la première fois où il est rencontré dans le
         fichier journal.</p>
    
         <p>Le programme reçoit le fichier journal sur son entrée standard.
         Les adresses IP doivent se trouver en tête de chaque ligne et
         doivent être séparées du reste de la ligne par un espace.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Syntaxe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Syntaxe</a></h2>
    
         <p><code><strong>logresolve</strong> [ -<strong>s</strong>
         <var>nom-fichier</var> ] [ -<strong>c</strong> ] &lt;
         <var>access_log</var> &gt; <var>access_log.new</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    
    <dt><code>-s <var>nom-fichier</var></code></dt>
    
    <dd>Spécifie le nom du fichier où seront enregistrées des
    statistiques.</dd>
    
    <dt><code>-c</code></dt>
    
    <dd>Avec cette option, <code>logresolve</code> effectue certaines
    vérifications DNS : après avoir trouvé le nom d'hôte correspondant à une
    adresse IP, <code>logresolve</code> effectue une recherche DNS sur ce
    nom d'hôte et vérifie si une des adresses IP trouvées correspond à
    l'adresse originale.</dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/logresolve.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/logresolve.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/suexec.html.fr.utf8�����������������������������������������������0000664�0001751�0001751�00000015545�14740503670�022356� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>suexec - Change d'utilisateur avant l'exécution d'un programme
    externe - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>suexec - Change d'utilisateur avant l'exécution d'un programme
    externe</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>suexec</code> permet au serveur HTTP Apache de changer
         d'utilisateur avant d'exécuter un programme CGI. Pour ce faire, il
         doit être exécuté par <code>root</code>. A cet effet, comme le
         démon HTTP ne s'exécute en général pas en tant que
         <code>root</code>, l'exécutable <code>suexec</code> doit posséder
         le bit setuid et avoir comme propriétaire <code>root</code>. Seul
         <code>root</code> doit en posséder les droits en écriture.</p>
    
         <p>Pour plus d'informations à propos des concepts et du modèle de
         sécurité du programme suexec, veuillez vous reporter à sa
         documentation : <a href="http://httpd.apache.org/docs/2.4/suexec.html">http://httpd.apache.org/docs/2.4/suexec.html</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
         <p><code><strong>suexec</strong> -<strong>V</strong></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    <dt><code>-V</code></dt>
    
    <dd>Si vous êtes <code>root</code>, cette option permet d'afficher les
    options de compilation du programme <code>suexec</code>. Pour des
    raisons de sécurité, toutes les options de configuration ne sont
    modifiables qu'à la compilation.</dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/programs/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/configure.html.en�������������������������������������������������0000664�0001751�0001751�00000112034�14737241666�022152� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>configure - Configure the source tree - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>configure - Configure the source tree</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/configure.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>The <code>configure</code> 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.</p>
    
        <p>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 <a href="../platform/">platform</a> documentation.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#env">Environment variables</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../install.html">Compiling and Installing</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p>You should call the <code>configure</code> script from within the
        root directory of the distribution.</p>
    
        <p><code><strong>./configure</strong> [<var>OPTION</var>]...
        [<var>VAR</var>=<var>VALUE</var>]...</code></p>
    
        <p>To assign environment variables (e.g. <code>CC</code>,
        <code>CFLAGS</code> ...), specify them as
        <code><var>VAR</var>=<var>VALUE</var></code>. See <a href="#env">below</a>
        for descriptions of some of the useful variables.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
      <ul>
        <li><a href="#configurationoptions">Configuration options</a></li>
        <li><a href="#installationdirectories">Installation directories</a></li>
        <li><a href="#systemtypes">System types</a></li>
        <li><a href="#optionalfeatures">Optional features</a></li>
        <li><a href="#supportopt">Options for support programs</a></li>
      </ul>
    
      <h3><a name="configurationoptions" id="configurationoptions">Configuration options</a></h3>
    
        <p>The following options influence the behavior of
        <code>configure</code> itself.</p>
    
        <dl>
          <dt><code>-C</code></dt>
          <dt><code>--config-cache</code></dt>
          <dd>This is an alias for <code>--cache-file=config.cache</code></dd>
    
          <dt><code>--cache-file=<var>FILE</var></code></dt>
          <dd>The test results will be cached in file <var>FILE</var>.
            This option is disabled by default.</dd>
    
          <dt><code>-h</code></dt>
          <dt><code>--help [short|recursive]</code></dt>
          <dd>Output the help and exit. With the argument <code>short</code> only
            options specific to this package will displayed. The argument
            <code>recursive</code> displays the short help of all the included
            packages.</dd>
    
          <dt><code>-n</code></dt>
          <dt><code>--no-create</code></dt>
          <dd>The <code>configure</code> script is run normally but does
            not create output files. This is useful to check the test results
            before generating makefiles for compilation.</dd>
    
          <dt><code>-q</code></dt>
          <dt><code>--quiet</code></dt>
          <dd>Do not print <code>checking ...</code> messages during the
            configure process.</dd>
    
          <dt><code>--srcdir=<var>DIR</var></code></dt>
          <dd>Defines directory <var>DIR</var> to be the source file directory.
            Default is the directory where <code>configure</code> is located, or
            the parent directory.</dd>
    
          <dt><code>--silent</code></dt>
          <dd>Same as <code>--quiet</code></dd>
    
          <dt>-V</dt>
          <dt>--version</dt>
          <dd>Display copyright information and exit.</dd>
        </dl>
      
    
      <h3><a name="installationdirectories" id="installationdirectories">Installation
        directories</a></h3>
    
        <p>These options define the installation directory. The installation
          tree depends on the selected layout.</p>
    
        <dl>
          <dt><code>--prefix=<var>PREFIX</var></code></dt>
          <dd>Install architecture-independent files in <var>PREFIX</var>.
            By default the installation directory is set to
            <code>/usr/local/apache2</code>.</dd>
    
          <dt><code>--exec-prefix=<var>EPREFIX</var></code></dt>
          <dd>Install architecture-dependent files in <var>EPREFIX</var>.
            By default the installation directory is set to the
            <var>PREFIX</var> directory.</dd>
        </dl>
    
        <p>By default, <code>make install</code> will install all the files in
          <code>/usr/local/apache2/bin</code>, <code>/usr/local/apache2/lib</code>
          etc. You can specify an installation prefix other than
          <code>/usr/local/apache2</code> using <code>--prefix</code>,
          for instance <code>--prefix=$HOME</code>.</p>
    
        <h4><a name="layout" id="layout">Define a directory layout</a></h4>
          <dl>
            <dt><code>--enable-layout=<var>LAYOUT</var></code></dt>
            <dd>Configure the source code and build scripts to assume an
              installation tree based on the layout <var>LAYOUT</var>. This allows
              you to separately specify the locations for each type of file within
              the Apache HTTP Server installation. The <code>config.layout</code>
              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 <code>&lt;Layout
                FOO&gt;...&lt;/Layout&gt;</code> sections and referred to by name as
              in <code>FOO</code>. The default layout is <code>Apache</code>.</dd>
          </dl>
        
    
        <h4><a name="directoryfinetuning" id="directoryfinetuning">Fine tuning of the installation
          directories</a></h4>
    
          <p>For better control of the installation directories, use the options
            below. Please note that the directory defaults are set by
            <code>autoconf</code> and are overwritten by the corresponding layout
            setting.</p>
    
          <dl>
            
            <dt><code>--bindir=<var>DIR</var></code></dt>
            <dd>Install user executables in <var>DIR</var>. The user executables
              are supporting programs like <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>,
              <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code>, etc. which are useful for site
              administrators. By default <var>DIR</var> is set to
              <code><var>EPREFIX</var>/bin</code>.</dd>
    
            <dt><code>--datadir=<var>DIR</var></code></dt>
            <dd>Install read-only architecture-independent data in <var>DIR</var>.
              By default <code>datadir</code> is set to
              <code><var>PREFIX</var>/share</code>. This option is offered by
              <code>autoconf</code> and currently unused.</dd>
    
            <dt><code>--includedir=<var>DIR</var></code></dt>
            <dd>Install C header files in <var>DIR</var>. By default
              <code>includedir</code> is set to
              <code><var>EPREFIX</var>/include</code>.</dd>
    
            <dt><code>--infodir=<var>DIR</var></code></dt>
            <dd>Install info documentation in <var>DIR</var>.
              By default <code>infodir</code> is set to
              <code><var>PREFIX</var>/info</code>. This option is currently
              unused.</dd>
    
            <dt><code>--libdir=<var>DIR</var></code></dt>
            <dd>Install object code libraries in <var>DIR</var>. By default
              <code>libdir</code> is set to
              <code><var>EPREFIX</var>/lib</code>.</dd>
    
            <dt><code>--libexecdir=<var>DIR</var></code></dt>
            <dd>Install the program executables (i.e., shared modules) in
              <var>DIR</var>. By default <code>libexecdir</code> is set to
              <code><var>EPREFIX</var>/modules</code>.</dd>
    
            <dt><code>--localstatedir=<var>DIR</var></code></dt>
            <dd>Install modifiable single-machine data in <var>DIR</var>.
              By default <code>localstatedir</code> is set to
              <code><var>PREFIX</var>/var</code>. This option is offered by
              <code>autoconf</code> and currently unused.</dd>
    
            <dt><code>--mandir=<var>DIR</var></code></dt>
            <dd>Install the man documentation in <var>DIR</var>. By default
              <code>mandir</code> is set to
              <code><var>EPREFIX</var>/man</code>.</dd>
    
            <dt><code>--oldincludedir=<var>DIR</var></code></dt>
            <dd>Install C header files for non-gcc in <var>DIR</var>.
              By default <code>oldincludedir</code> is set to
              <code>/usr/include</code>. This option is offered by
              <code>autoconf</code> and currently unused.</dd>
    
            <dt><code>--sbindir=<var>DIR</var></code></dt>
            <dd>Install the system administrator executables in <var>DIR</var>.
              Those are server programs like <code class="program"><a href="../programs/httpd.html">httpd</a></code>,
              <code class="program"><a href="../programs/apachectl.html">apachectl</a></code>, <code class="program"><a href="../programs/suexec.html">suexec</a></code>, etc. which
              are necessary to run the Apache HTTP Server. By default
              <code>sbindir</code> is set to
              <code><var>EPREFIX</var>/sbin</code>.</dd>
    
            <dt><code>--sharedstatedir=<var>DIR</var></code></dt>
            <dd>Install modifiable architecture-independent data in <var>DIR</var>.
              By default <code>sharedstatedir</code> is set to
              <code><var>PREFIX</var>/com</code>. This option is offered by
              <code>autoconf</code> and currently unused.</dd>
    
            <dt><code>--sysconfdir=<var>DIR</var></code></dt>
            <dd>Install read-only single-machine data like the server configuration
              files <code>httpd.conf</code>, <code>mime.types</code>, etc. in
              <var>DIR</var>. By default <code>sysconfdir</code> is set to
              <code><var>PREFIX</var>/conf</code>.</dd>
          </dl>
        
      
    
      <h3><a name="systemtypes" id="systemtypes">System types</a></h3>
    
        <p>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.</p>
    
        <dl>
          <dt><code>--build=<var>BUILD</var></code></dt>
          <dd>Defines the system type of the system on which the tools are being
            built. It defaults to the result of the script
            <code>config.guess</code>.</dd>
    
          <dt><code>--host=<var>HOST</var></code></dt>
          <dd>Defines the system type of the system on which the server will run.
            <var>HOST</var> defaults to <var>BUILD</var>.</dd>
    
          <dt><code>--target=<var>TARGET</var></code></dt>
          <dd>Configure for building compilers for the system type
            <var>TARGET</var>. It defaults to <var>HOST</var>. This option is
            offered by <code>autoconf</code> and not necessary for the Apache HTTP
            Server.</dd>
        </dl>
      
    
      <h3><a name="optionalfeatures" id="optionalfeatures">Optional Features</a></h3>
    
        <p>These options are used to fine tune the features your HTTP server will
          have.</p>
    
        <h4><a name="generaloptfeat" id="generaloptfeat">General syntax</a></h4>
          <p>Generally you can use the following syntax to enable or disable a
            feature:</p>
    
          <dl>
            <dt><code>--disable-<var>FEATURE</var></code></dt>
            <dd>Do not include <var>FEATURE</var>. This is the same as
              <code>--enable-<var>FEATURE</var>=no</code>.</dd>
    
            <dt><code>--enable-<var>FEATURE</var>[=<var>ARG</var>]</code></dt>
            <dd>Include <var>FEATURE</var>. The default value for <var>ARG</var>
              is <code>yes</code>.</dd>
    
            <dt><code>--enable-<var>MODULE</var>=shared</code></dt>
            <dd>The corresponding module will be built as a DSO module.
                By default enabled modules are linked dynamically.</dd>
    
            <dt><code>--enable-<var>MODULE</var>=static</code></dt>
            <dd>The corresponding module will be linked statically.</dd>
          </dl>
    
          <div class="note"><h3>Note</h3>
            <code>configure</code> will not complain about
            <code>--enable-<var>foo</var></code> even if <var>foo</var> doesn't
            exist, so you need to type carefully.
          </div>
        
    
        <h4><a name="choosemodules" id="choosemodules">Choosing modules to compile</a></h4>
          <p>Most modules are compiled by default and have to be disabled
            explicitly or by using the keyword <code>few</code> 
            (see <code>--enable-modules</code>, <code>--enable-mods-shared</code>
            and <code>--enable-mods-static</code> below for further explanation)
            or <code>--enable-modules=none</code> to be removed as a group.</p>
    
            <p>Other modules are not compiled by default and have to be enabled
            explicitly or by using the keywords <code>all</code> or
            <code>reallyall</code> to be available.</p>
    
            <p>To find out which modules are compiled by default, run
            <code>./configure -h</code> or <code>./configure --help</code>
            and look under <code>Optional Features</code>.  Suppose you
            are interested in <code>mod_example1</code> and
            <code>mod_example2</code>, and you
            see this:</p>
    
            <div class="example"><pre>Optional Features:
      ...
      --disable-example1     example module 1
      --enable-example2      example module 2
      ...</pre></div>
    
            <p>Then <code>mod_example1</code> is enabled by default,
            and you would use <code>--disable-example1</code> to not
            compile it.  <code>mod_example2</code> is disabled by
            default, and you would use <code>--enable-example2</code>
            to compile it.</p>
        
    
        <h4><a name="mpms" id="mpms">Multi-Processing Modules</a></h4>
          <p><a href="../mpm.html">Multi-Processing Modules</a>, or MPMs, implement
            the basic behavior of the server.  A single MPM must be active in order
            for the server to function.  The list of available MPMs appears on the
            <a href="../mod/">module index page</a>.</p>
    
          <p>MPMs can be built as DSOs for dynamic loading or statically linked with
            the server, and are enabled using the following options:</p>
    
          <dl>
            <dt><code>--with-mpm=MPM</code></dt>
            <dd>
              <p>Choose the default MPM for your server.  If MPMs are built as DSO
                modules (see <code>--enable-mpms-shared</code>), this directive
                selects the MPM which will be loaded in the default configuration
                file.  Otherwise, this directive selects the only available MPM,
                which will be statically linked into the server.</p>
              <p>If this option is omitted, the <a href="../mpm.html#defaults">default
              MPM</a> for your operating system will be used.</p>
            </dd>
    
            <dt><code>--enable-mpms-shared=<var>MPM-LIST</var></code></dt>
            <dd>
              <p>Enable a list of MPMs as dynamic shared modules.  One of these
                modules must be loaded dynamically using the
                <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directive.</p>
              <p><var>MPM-LIST</var> is a space-separated list of MPM names
                enclosed by quotation marks.  For example:</p>
              <div class="example"><p><code>
                --enable-mpms-shared='prefork worker'
              </code></p></div>
              <p>Additionally you can use the special keyword <code>all</code>,
                which will select all MPMs which support dynamic loading on the
                current platform and build them as DSO modules.  For example:</p>
              <div class="example"><p><code>
                --enable-mpms-shared=all
              </code></p></div>
    	</dd>
          </dl>
        
    
        <h4><a name="modules" id="modules">Third-party modules</a></h4>
          <p>To add additional third-party modules use the following options:</p>
    
          <dl>
            <dt><code>--with-module=<var>module-type</var>:<var>module-file</var>[,
              <var>module-type</var>:<var>module-file</var>]</code></dt>
            <dd><p>Add one or more third-party modules to the list of statically linked
                modules. The module source file <code><var>module-file</var></code>
                will be searched in the <code>modules/<var>module-type</var></code>
                subdirectory of your Apache HTTP server source tree. If it is not found
                there <code>configure</code> is considering <var>module-file</var> to be
                an absolute file path and tries to copy the source file into the
                <var>module-type</var> subdirectory. If the subdirectory doesn't
                exist it will be created and populated with a standard
                <code>Makefile.in</code>.</p>
              <p>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.</p>
              <div class="note"><h3>Note</h3>
                If you want to build a DSO module instead of a statically linked
                use <code class="program"><a href="../programs/apxs.html">apxs</a></code>.</div>
            </dd>
          </dl>
        
    
        <h4><a name="otheroptfeat" id="otheroptfeat">Cumulative and other options</a></h4>
          <dl>
            <dt><code>--enable-maintainer-mode</code></dt>
            <dd>Turn on debugging and compile time warnings
                and load all compiled modules.</dd>
    
            <dt><code>--enable-mods-shared=<var>MODULE-LIST</var></code></dt>
            <dd>
              <p>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  <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directive.</p>
              <p><var>MODULE-LIST</var> is a space separated list of modulenames
                enclosed by quotation marks. The module names are given without the
                preceding <code>mod_</code>. For example:</p>
              <div class="example"><p><code>
                --enable-mods-shared='headers rewrite dav'
              </code></p></div>
              <p>Additionally you can use the special keywords <code>reallyall</code>,
                <code>all</code>, <code>most</code> and <code>few</code>.
                For example,</p>
              <div class="example"><p><code>
                --enable-mods-shared=most
              </code></p></div>
              <p>will compile most modules and build them as DSO modules,</p>
              <div class="example"><p><code>
                --enable-mods-shared=few
              </code></p></div>
              <p>will only compile a very basic set of modules.</p>
              <p>The default set is <code>most</code>.</p>
                
              <p>The <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directives for
              the chosen modules will be automatically generated in the main
              configuration file. By default, all those directives will be commented
              out except for the modules that are either required or explicitly selected
              by a configure <code>--enable-foo</code> argument. You can change the set
              of loaded modules by activating or deactivating the <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directives in
              <code>httpd.conf</code>. In addition the
              <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directives for all
              built modules can be activated via the configure option
              <code>--enable-load-all-modules</code>.</p>
            </dd>
    
            <dt><code>--enable-mods-static=<var>MODULE-LIST</var></code></dt>
            <dd>This option behaves similar to <code>--enable-mods-shared</code>,
              but will link the given modules statically. This mean, these modules
              will always be present while running <code class="program"><a href="../programs/httpd.html">httpd</a></code>. They need
              not be loaded with <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code>.</dd>
    
            <dt><code>--enable-modules=<var>MODULE-LIST</var></code></dt>
            <dd>This option behaves like to <code>--enable-mods-shared</code>,
              and will also link the given modules dynamically. The special
              keyword <code>none</code> disables the build of all modules.</dd>
    
            <dt><code>--enable-v4-mapped</code></dt>
            <dd>Allow IPv6 sockets to handle IPv4 connections.</dd>
    
            <dt><code>--with-port=<var>PORT</var></code></dt>
            <dd>This defines the port on which <code class="program"><a href="../programs/httpd.html">httpd</a></code> will listen.
              This port number is used when generating the configuration file
              <code>httpd.conf</code>. The default is 80.</dd>
    
            <dt><code>--with-program-name</code></dt>
            <dd>Define an alternative executable name. The default is
              <code>httpd</code>.</dd>
          </dl>
        
      
    
      <h3><a name="packages" id="packages">Optional packages</a></h3>
        <p>These options are used to define optional packages.</p>
    
        <h4><a name="generalpackages" id="generalpackages">General syntax</a></h4>
          <p>Generally you can use the following syntax to define an optional
            package:</p>
    
          <dl>
            <dt><code>--with-<var>PACKAGE</var>[=<var>ARG</var>]</code></dt>
            <dd>Use the package <var>PACKAGE</var>. The default value for
              <var>ARG</var> is <code>yes</code>.</dd>
    
            <dt><code>--without-<var>PACKAGE</var></code></dt>
            <dd>Do not use the package <var>PACKAGE</var>. This is the same as
              <code>--with-<var>PACKAGE</var>=no</code>. This option is provided by
              <code>autoconf</code> but not very useful for the Apache HTTP
              Server.</dd>
          </dl>
        
    
        
    
        <h4><a name="packageopt" id="packageopt">Specific packages</a></h4>
          <dl>
            <dt><code>--with-apr=<var>DIR</var>|<var>FILE</var></code></dt>
            <dd>The <a class="glossarylink" href="../glossary.html#apr" title="see glossary">Apache Portable Runtime</a> (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 <code>configure</code> the path to the
              <code>apr-config</code> script. You may set the absolute path and name
              or the directory to the installed APR. <code>apr-config</code> must
              exist within this directory or the subdirectory
              <code>bin</code>.</dd>
    
            <dt><code>--with-apr-util=<var>DIR</var>|<var>FILE</var></code></dt>
            <dd>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 <code>configure</code> the path to the
              <code>apu-config</code> script. You may set the absolute path and name
              or the directory to the installed APU. <code>apu-config</code> must
              exist within this directory or the subdirectory
              <code>bin</code>.</dd>
    
            <dt><code>--with-ssl=<var>DIR</var></code></dt>
            <dd>If <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> has been enabled <code>configure</code>
              searches for an installed OpenSSL. You can set the directory path
              to the SSL/TLS toolkit instead.</dd>
    
            <dt><code>--with-z=<var>DIR</var></code></dt>
            <dd><code>configure</code> searches automatically for an installed
              <code>zlib</code> library if your source configuration requires one
              (e.g., when <code class="module"><a href="../mod/mod_deflate.html">mod_deflate</a></code> is enabled). You can set the
              directory path to the compression library instead.</dd>
          </dl>
    
          <p>Several features of the Apache HTTP Server, including
            <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code> and <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>'s DBM
            <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> 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:</p>
    
          <dl>
            <dt><code>--with-gdbm[=<var>path</var>]</code></dt>
            <dd>If no <var>path</var> is specified, <code>configure</code> will
              search for the include files and libraries of a GNU DBM
              installation in the usual search paths. An explicit
              <var>path</var> will cause <code>configure</code> to look in
              <code><var>path</var>/lib</code> and
              <code><var>path</var>/include</code> for the relevant files.
              Finally, the <var>path</var> may specify specific include and
              library paths separated by a colon.</dd>
    
            <dt><code>--with-ndbm[=<var>path</var>]</code></dt>
            <dd>Like <code>--with-gdbm</code>, but searches for a New DBM
              installation.</dd>
    
            <dt><code>--with-berkeley-db[=<var>path</var>]</code></dt>
            <dd>Like <code>--with-gdbm</code>, but searches for a Berkeley DB
              installation.</dd>
          </dl>
    
          <div class="note"><h3>Note</h3>
            <p>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 <code>--with-apr-util</code>.</p>
            <p>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.</p>
          </div>
        
      
    
      <h3><a name="supportopt" id="supportopt">Options for support programs</a></h3>
        <dl>
          <dt><code>--enable-static-support</code></dt>
          <dd>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.</dd>
    
          <dt><code>--enable-suexec</code></dt>
          <dd>Use this option to enable <code class="program"><a href="../programs/suexec.html">suexec</a></code>, which allows you to set
            uid and gid for spawned processes. <strong>Do not use this
            option unless you understand all the security implications of
            running a suid binary on your server.</strong> Further options
            to configure <code class="program"><a href="../programs/suexec.html">suexec</a></code> are described <a href="#suexec">below</a>.</dd>
        </dl>
    
        <p>It is possible to create a statically linked binary of a single
          support program by using the following options:</p>
    
        <dl>
          <dt><code>--enable-static-ab</code></dt>
          <dd>Build a statically linked version of <code class="program"><a href="../programs/ab.html">ab</a></code>.</dd>
    
          
          <dt><code>--enable-static-checkgid</code></dt>
          <dd>Build a statically linked version of <code>checkgid</code>.</dd>
    
          <dt><code>--enable-static-htdbm</code></dt>
          <dd>Build a statically linked version of <code class="program"><a href="../programs/htdbm.html">htdbm</a></code>.</dd>
    
          <dt><code>--enable-static-htdigest</code></dt>
          <dd>Build a statically linked version of <code class="program"><a href="../programs/htdigest.html">htdigest</a></code>.</dd>
    
          <dt><code>--enable-static-htpasswd</code></dt>
          <dd>Build a statically linked version of <code class="program"><a href="../programs/htpasswd.html">htpasswd</a></code>.</dd>
    
          <dt><code>--enable-static-logresolve</code></dt>
          <dd>Build a statically linked version of <code class="program"><a href="../programs/logresolve.html">logresolve</a></code>.</dd>
    
          <dt><code>--enable-static-rotatelogs</code></dt>
          <dd>Build a statically linked version of <code class="program"><a href="../programs/rotatelogs.html">rotatelogs</a></code>.</dd>
        </dl>
    
        <h4><a name="suexec" id="suexec"><code>suexec</code> configuration options</a></h4>
          
          <p>The following options are used to fine tune the behavior of <code class="program"><a href="../programs/suexec.html">suexec</a></code>. See <a href="suexec.html#install">Configuring and installing suEXEC</a>
            for further information.</p>
    
          <dl>
            <dt><code>--with-suexec-bin</code></dt>
            <dd>This defines the path to <code class="program"><a href="../programs/suexec.html">suexec</a></code> binary.
            Default is <code>--sbindir</code> (see <a href="#directoryfinetuning">Fine tuning of installation directories</a>).</dd>
    
            <dt><code>--with-suexec-caller</code></dt>
            <dd>This defines the user allowed to call <code class="program"><a href="../programs/suexec.html">suexec</a></code>.
              It should be the same as the user under which
              <code class="program"><a href="../programs/httpd.html">httpd</a></code> normally runs.</dd>
    
            <dt><code>--with-suexec-docroot</code></dt>
            <dd>This defines the directory tree under which <code class="program"><a href="../programs/suexec.html">suexec</a></code> access is allowed for executables. Default value is
              <code>--datadir/htdocs</code>.</dd>
    
            <dt><code>--with-suexec-gidmin</code></dt>
            <dd>Define this as the lowest GID allowed to be a target user for
              <code class="program"><a href="../programs/suexec.html">suexec</a></code>. The default value is 100.</dd>
    
            <dt><code>--with-suexec-logfile</code></dt>
            <dd>This defines the filename of the <code class="program"><a href="../programs/suexec.html">suexec</a></code> logfile.
              By default the logfile is named <code>suexec_log</code> and located in
              <code>--logfiledir</code>.</dd>
    
            <dt><code>--with-suexec-safepath</code></dt>
            <dd>Define the value of the environment variable <code>PATH</code> to
              be set for processes started by <code class="program"><a href="../programs/suexec.html">suexec</a></code>. Default
              value is <code>/usr/local/bin:/usr/bin:/bin</code>.</dd>
    
            <dt><code>--with-suexec-userdir</code></dt>
            <dd>This defines the subdirectory under the user's directory that
              contains all executables for which <code class="program"><a href="../programs/suexec.html">suexec</a></code> access
              is allowed. This setting is necessary when you want to use
              <code class="program"><a href="../programs/suexec.html">suexec</a></code> together with user-specific directories (as
              provided by <code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code>). The default is
              <code>public_html</code>.</dd>
    
            <dt><code>--with-suexec-uidmin</code></dt>
            <dd>Define this as the lowest UID allowed to be a target user for
              <code class="program"><a href="../programs/suexec.html">suexec</a></code>. The default value is 100.</dd>
    
            <dt><code>--with-suexec-umask</code></dt>
            <dd>Set <code>umask</code> for processes started by
              <code class="program"><a href="../programs/suexec.html">suexec</a></code>. It defaults to your system settings.</dd>
          </dl>
        
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="env" id="env">Environment variables</a></h2>
      <p>There are some useful environment variables to override the choices made by
        <code>configure</code> or to help it to find libraries and programs with
        nonstandard names or locations.</p>
    
      
      <dl>
        <dt><code>CC</code></dt>
        <dd>Define the C compiler command to be used for compilation.</dd>
    
        <dt><code>CFLAGS</code></dt>
        <dd>Set C compiler flags you want to use for compilation.</dd>
    
        <dt><code>CPP</code></dt>
        <dd>Define the C preprocessor command to be used.</dd>
    
        <dt><code>CPPFLAGS</code></dt>
        <dd>Set C/C++ preprocessor flags, e.g. <code>-I<var>includedir</var></code>
          if you have headers in a nonstandard directory <var>includedir</var>.</dd>
    
        <dt><code>LDFLAGS</code></dt>
        <dd>Set linker flags, e.g. <code>-L<var>libdir</var></code> if you have
          libraries in a nonstandard directory <var>libdir</var>.</dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/configure.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/configure.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/configure.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/configure.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/configure.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdbm.html.en�����������������������������������������������������0000664�0001751�0001751�00000044513�14737241666�021275� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htdbm - Manipulate DBM password databases - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>htdbm - Manipulate DBM password databases</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/htdbm.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/htdbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htdbm</code> is used to manipulate the DBM format files used to
        store usernames and password for basic authentication of HTTP users via
        <code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code>.  See the <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code>
        documentation for more information about these DBM files.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#bugs">Bugs</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Exit Status</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Examples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Security Considerations</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#restrictions">Restrictions</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code></li><li><code class="module"><a href="../mod/mod_authn_dbm.html">mod_authn_dbm</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>htdbm</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>filename</var> <var>username</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>b</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>filename</var> <var>username</var> <var>password</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>n</strong>
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>username</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>nb</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>username</var> <var>password</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>v</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>i</strong> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>filename</var> <var>username</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>vb</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>t</strong> ]
        [ -<strong>v</strong> ]
        <var>filename</var> <var>username</var> <var>password</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>x</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        <var>filename</var> <var>username</var></code></p>
    
        <p><code><strong>htdbm</strong> -<strong>l</strong>
        [ -<strong>T</strong><var>DBTYPE</var> ]
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-b</code></dt>
        <dd>Use batch mode; <em>i.e.</em>, get the password from the command line
        rather than prompting for it. This option should be used with extreme care,
        since <strong>the password is clearly visible</strong> on the command
        line. For script use see the <code>-i</code> option.</dd>
    
        <dt><code>-i</code></dt>
        <dd>Read the password from stdin without verification (for script usage).</dd>
    
        <dt><code>-c</code></dt>
        <dd>Create the <var>passwdfile</var>. If <var>passwdfile</var> already
        exists, it is rewritten and truncated. This option cannot be combined with
        the <code>-n</code> option.</dd>
    
        <dt><code>-n</code></dt>
        <dd>Display the results on standard output rather than updating a
        database.  This option changes the syntax of the command line, since the
        <var>passwdfile</var> argument (usually the first one) is omitted. It
        cannot be combined with the <code>-c</code> option.</dd>
    
        <dt><code>-m</code></dt>
        <dd>Use MD5 hashing for passwords. On Windows and Netware, this is
        the default.</dd>
    
        <dt><code>-B</code></dt>
        <dd>Use bcrypt hashing for passwords. This is currently considered to
        be very secure.</dd>
    
        <dt><code>-C</code></dt>
        <dd>This flag is only allowed in combination with <code>-B</code> (bcrypt
        hashing). It sets the computing time used for the bcrypt algorithm
        (higher is more secure but slower, default: 5, valid: 4 to 31).</dd>
    
        <dt><code>-d</code></dt>
        <dd>Use <code>crypt()</code> hashing for passwords. The default on all
        platforms but Windows and Netware. Though possibly supported by
        <code>htdbm</code> on all platforms, it is not supported by the
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> server on Windows and Netware.
        This algorithm is <strong>insecure</strong> by today's standards.</dd>
    
        <dt><code>-s</code></dt>
        <dd>Use SHA hashing for passwords. Facilitates migration from/to Netscape
        servers using the LDAP Directory Interchange Format (ldif).
        This algorithm is <strong>insecure</strong> by today's standards.</dd>
    
        <dt><code>-p</code></dt>
        <dd>Use plaintext passwords. Though <code>htdbm</code> will support
        creation on all platforms, the <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon will
        only accept plain text passwords on Windows and Netware.</dd>
    
        <dt><code>-l</code></dt>
        <dd>Print each of the usernames and comments from the database on
        stdout.</dd>
    
        <dt><code>-v</code></dt>
        <dd>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.</dd>
    
        <dt><code>-x</code></dt>
        <dd>Delete user. If the username exists in the specified DBM file, it
        will be deleted.</dd>
    
        <dt><code>-t</code></dt>
        <dd>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.</dd>
    
        <dt><code><var>filename</var></code></dt>
        <dd>The filename of the DBM format file. Usually without the extension
        <code>.db</code>, <code>.pag</code>, or <code>.dir</code>.  If
        <code>-c</code> is given, the DBM file is created if it does not already
        exist, or updated if it does exist.</dd>
    
        <dt><code><var>username</var></code></dt>
        <dd>The username to create or update in <var>passwdfile</var>. If
        <var>username</var> does not exist in this file, an entry is added. If it
        does exist, the password is changed.</dd>
    
        <dt><code><var>password</var></code></dt>
        <dd>The plaintext password to be hashed and stored in the DBM file.
        Used only with the <code>-b</code> flag.</dd>
    
        <dt><code>-T<var>DBTYPE</var></code></dt>
        <dd>Type of DBM file (SDBM, GDBM, DB, or "default").</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="bugs" id="bugs">Bugs</a></h2>
        <p>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 <var>filename</var> is the same format that
        <code>htdbm</code> expects to see. <code>htdbm</code> 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.</p>
    
        <p>One can usually use the <code>file</code> program supplied with most
        Unix systems to see what format a DBM file is in.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Exit Status</a></h2>
        <p><code>htdbm</code> returns a zero status ("true") if the username and
        password have been successfully added or updated in the DBM File.
        <code>htdbm</code> returns <code>1</code> if it encounters some problem
        accessing files, <code>2</code> if there was a syntax problem with the
        command line, <code>3</code> if the password was entered interactively and
        the verification entry didn't match, <code>4</code> if its operation was
        interrupted, <code>5</code> if a value is too long (username, filename,
        password, or final computed record), <code>6</code> if the username
        contains illegal characters (see the <a href="#restrictions">Restrictions
        section</a>), and <code>7</code> if the file is not a valid DBM password
        file.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Examples</a></h2>
        <div class="example"><p><code>
          htdbm /usr/local/etc/apache/.htdbm-users jsmith
        </code></p></div>
    
        <p>Adds or modifies the password for user <code>jsmith</code>. The user
        is prompted for the password. If executed on a Windows system, the password
        will be hashed using the  modified Apache MD5 algorithm; otherwise, the
        system's <code>crypt()</code> routine will be used. If the file does not
        exist, <code>htdbm</code> will do nothing except return an error.</p>
    
        <div class="example"><p><code>
          htdbm -c /home/doe/public_html/.htdbm jane
        </code></p></div>
    
        <p>Creates a new file and stores a record in it for user <code>jane</code>.
        The user is prompted for the password. If the file exists and cannot be
        read, or cannot be written, it is not altered and <code>htdbm</code>
        will display a message and return an error status.</p>
    
        <div class="example"><p><code>
          htdbm -mb /usr/web/.htdbm-all jones Pwd4Steve
        </code></p></div>
    
        <p>Encrypts the password from the command line (<code>Pwd4Steve</code>)
        using the MD5 algorithm, and stores it in the specified file.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Security Considerations</a></h2>
        <p>Web password files such as those managed by <code>htdbm</code> should
        <em>not</em> be within the Web server's URI space -- that is, they should
        not be fetchable with a browser.</p>
    
        <p>The use of the <code>-b</code> option is discouraged, since when it is
        used the plaintext password appears on the command line.</p>
    
        <p>When using the <code>crypt()</code> algorithm, note that only the first
        8 characters of the password are used  to form the password. If the supplied
        password is longer, the extra characters will be silently discarded.</p>
    
        <p>The SHA hashing option does not use salting: for a given password,
        there is only one hashed representation. The <code>crypt()</code> and
        MD5 formats permute the representation by prepending a random salt string,
        to make dictionary attacks against the passwords more difficult.</p>
    
        <p>The SHA and <code>crypt()</code> formats are insecure by today's
        standards.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="restrictions" id="restrictions">Restrictions</a></h2>
        <p>On the Windows platform, passwords hashed with
        <code>htdbm</code> are limited to no more than <code>255</code>
        characters in length. Longer passwords will be truncated to 255
        characters.</p>
    
        <p>The MD5 algorithm used by <code>htdbm</code> is specific to the Apache
        software; passwords hashed using it will not be usable with other Web
        servers.</p>
    
        <p>Usernames are limited to <code>255</code> bytes and may not include the
        character <code>:</code>.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/htdbm.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/htdbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htdbm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/httxt2dbm.html.en�������������������������������������������������0000664�0001751�0001751�00000017324�14737241666�022117� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>httxt2dbm - Generate dbm files for use with RewriteMap - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>httxt2dbm - Generate dbm files for use with RewriteMap</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/httxt2dbm.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httxt2dbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/httxt2dbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>httxt2dbm</code> is used to generate dbm files from text input, for
        use in <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> with the
        <code>dbm</code> map type.</p>
    
        <p>If the output file already exists, it will not be truncated. New keys will be
        added and existing keys will be updated.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Examples</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>httxt2dbm</strong>
        [ -<strong>v</strong> ]
        [ -<strong>f</strong> <var>DBM_TYPE</var> ]
        -<strong>i</strong> <var>SOURCE_TXT</var>
        -<strong>o</strong> <var>OUTPUT_DBM</var>
        </code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-v</code></dt>
        <dd>More verbose output</dd>
    
        <dt><code>-f <var>DBM_TYPE</var></code></dt>
        <dd>Specify the DBM type to be used for the output. If not specified, will
        use the <a class="glossarylink" href="../glossary.html#apr" title="see glossary">APR</a> Default. Available types are:
        <code>GDBM</code> for GDBM files,
        <code>SDBM</code> for SDBM files,
        <code>DB</code> for berkeley DB files,
        <code>NDBM</code> for NDBM files,
        <code>default</code> for the default DBM type.
        </dd>
    
        <dt><code>-i <var>SOURCE_TXT</var></code></dt>
        <dd>Input file from which the dbm is to be created. The file should be formatted
        with one record per line, of the form: <code>key value</code>.
        See the documentation for <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> for
        further details of this file's format and meaning.
        </dd>
    
        <dt><code>-o <var>OUTPUT_DBM</var></code></dt>
        <dd>Name of the output dbm files.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Examples</a></h2>
        <div class="example"><p><code>
          httxt2dbm -i rewritemap.txt -o rewritemap.dbm<br />
          httxt2dbm -f SDBM -i rewritemap.txt -o rewritemap.dbm<br />
        </code></p></div>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/httxt2dbm.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/httxt2dbm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/programs/httxt2dbm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/httxt2dbm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htpasswd.html.en��������������������������������������������������0000664�0001751�0001751�00000044752�14737241666�022041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htpasswd - Manage user files for basic authentication - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>htpasswd - Manage user files for basic authentication</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/htpasswd.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htpasswd</code> is used to create and update the flat-files used to
        store usernames and password for basic authentication of HTTP users. If
        <code>htpasswd</code> 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.</p>
    
        <p>Resources available from the Apache HTTP server can be restricted to
        just the users listed in the files created by <code>htpasswd</code>. This
        program can only manage usernames and passwords stored in a flat-file. It
        can hash and display password information for use in other types of data
        stores, though. To use a DBM database see <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> or
        <code class="program"><a href="../programs/htdbm.html">htdbm</a></code>.</p>
    
        <p><code>htpasswd</code> hashes passwords using either bcrypt, a
        version of MD5 modified for Apache, SHA-1, or the system's
        <code>crypt()</code> routine. SHA-2-based hashes (SHA-256 and
        SHA-512) are supported for <code>crypt()</code>.  Files managed by
        <code>htpasswd</code> may contain a mixture of different encoding
        types of passwords; some user records may have bcrypt or
        MD5-hashed passwords while others in the same file may have
        passwords hashed with <code>crypt()</code>.</p>
    
        <p>This manual page only lists the command line arguments. For details of
        the directives necessary to configure user authentication in
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> see the Apache manual, which is part of the
        Apache distribution or can be found at <a href="http://httpd.apache.org">http://httpd.apache.org/</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#exit">Exit Status</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Examples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Security Considerations</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#restrictions">Restrictions</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="../programs/htdbm.html">htdbm</a></code></li><li>The scripts in support/SHA1 which come with the
    distribution.</li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>htpasswd</strong>
        [ -<strong>c</strong> ]
        [ -<strong>i</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>2</strong> | 
          -<strong>5</strong> | 
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]  <var>passwdfile</var> <var>username</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>b</strong>
        [ -<strong>c</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>2</strong> | 
          -<strong>5</strong> | 
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ]
        [ -<strong>D</strong> ]
        [ -<strong>v</strong> ]  <var>passwdfile</var> <var>username</var>
        <var>password</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>n</strong>
        [ -<strong>i</strong> ]
        [ -<strong>m</strong> |
          -<strong>B</strong> |
          -<strong>2</strong> | 
          -<strong>5</strong> | 
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ] <var>username</var></code></p>
    
        <p><code><strong>htpasswd</strong> -<strong>nb</strong>
        [ -<strong>m</strong> |
          -<strong>B</strong> | 
          -<strong>2</strong> | 
          -<strong>5</strong> | 
          -<strong>d</strong> |
          -<strong>s</strong> |
          -<strong>p</strong> ]
        [ -<strong>r</strong> <var>rounds</var> ]
        [ -<strong>C</strong> <var>cost</var> ] <var>username</var>
        <var>password</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-b</code></dt>
        <dd>Use batch mode; <em>i.e.</em>, get the password from the command line
        rather than prompting for it. This option should be used with extreme care,
        since <strong>the password is clearly visible</strong> on the command
        line. For script use see the <code>-i</code> option.
        Available in 2.4.4 and later.</dd>
    
        <dt><code>-i</code></dt>
        <dd>Read the password from stdin without verification (for script usage).</dd>
    
        <dt><code>-c</code></dt>
        <dd>Create the <var>passwdfile</var>. If <var>passwdfile</var> already
        exists, it is rewritten and truncated. This option cannot be combined with
        the <code>-n</code> option.</dd>
    
        <dt><code>-n</code></dt>
        <dd>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 <var>passwdfile</var> argument (usually the first
        one) is omitted. It cannot be combined with the <code>-c</code> option.</dd>
    
        <dt><code>-m</code></dt>
        <dd>Use MD5 hashing for passwords. This is the default (since version
        2.2.18).</dd>
    
        <dt><code>-2</code></dt>
        <dd>Use SHA-256 <code>crypt()</code> based hashes for passwords.  This is
        supported on most Unix platforms.</dd>
    
        <dt><code>-5</code></dt>
        <dd>Use SHA-512 <code>crypt()</code> based hashes for passwords.  This is
        supported on most Unix platforms.</dd>
    
        <dt><code>-B</code></dt>
        <dd>Use bcrypt hashing for passwords. This is currently considered to
        be very secure.</dd>
    
        <dt><code>-C</code></dt>
        <dd>This flag is only allowed in combination with <code>-B</code> (bcrypt
        hashing). It sets the computing time used for the bcrypt algorithm
        (higher is more secure but slower, default: 5, valid: 4 to 17).</dd>
    
        <dt><code>-r</code></dt>
        <dd>This flag is only allowed in combination with <code>-2</code>
        or <code>-5</code>. It sets the number of hash rounds used for the
        SHA-2 algorithms (higher is more secure but slower; the default is
        5,000).</dd>
    
        <dt><code>-d</code></dt>
        <dd>Use <code>crypt()</code> hashing for passwords. This is not
        supported by the <code class="program"><a href="../programs/httpd.html">httpd</a></code> server on Windows and
        Netware. This algorithm limits the password length to 8 characters.
        This algorithm is <strong>insecure</strong> by today's standards.
        It used to be the default algorithm until version 2.2.17.</dd>
    
        <dt><code>-s</code></dt>
        <dd>Use SHA-1 (160-bit) hashing for passwords. Facilitates migration
        from/to Netscape servers using the LDAP Directory Interchange
        Format (ldif).  This algorithm is <strong>insecure</strong> by
        today's standards.</dd>
    
        <dt><code>-p</code></dt>
        <dd>Use plaintext passwords. Though <code>htpasswd</code> will support
        creation on all platforms, the <code class="program"><a href="../programs/httpd.html">httpd</a></code> daemon will
        only accept plain text passwords on Windows and Netware.</dd>
    
        <dt><code>-D</code></dt>
        <dd>Delete user. If the username exists in the specified htpasswd file, it
        will be deleted.</dd>
    
        <dt><code>-v</code></dt>
        <dd>Verify password. Verify that the given password matches the password
        of the user stored in the specified htpasswd file.
        Available in 2.4.5 and later.</dd>
    
        <dt><code><var>passwdfile</var></code></dt>
        <dd>Name of the file to contain the user name and password. If
        <code>-c</code> is given, this file is created if it does not already exist,
        or rewritten and truncated if it does exist.</dd>
    
        <dt><code><var>username</var></code></dt>
        <dd>The username to create or update in <var>passwdfile</var>. If
        <var>username</var> does not exist in this file, an entry is added. If it
        does exist, the password is changed.</dd>
    
        <dt><code><var>password</var></code></dt>
        <dd>The plaintext password to be hashed and stored  in the file. Only
        used with the <code>-b</code> flag.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="exit" id="exit">Exit Status</a></h2>
        <p><code>htpasswd</code> returns a zero status ("true") if the username and
        password have been successfully added or updated in the
        <var>passwdfile</var>. <code>htpasswd</code> returns <code>1</code> if it
        encounters some problem accessing files, <code>2</code> if there was a
        syntax problem with the command line, <code>3</code> if the password was
        entered interactively and the verification entry didn't match,
        <code>4</code> if its operation was interrupted, <code>5</code> if a value
        is too long (username, filename, password, or final computed record),
        <code>6</code> if the username contains illegal characters (see the
        <a href="#restrictions">Restrictions section</a>), and <code>7</code>
        if the file is not a valid password file.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Examples</a></h2>
        <div class="example"><p><code>
          htpasswd /usr/local/etc/apache/.htpasswd-users jsmith
        </code></p></div>
    
        <p>Adds or modifies the password for user <code>jsmith</code>. The user
        is prompted for the password. The password will be hashed using the
        modified Apache MD5 algorithm. If the file does not exist,
        <code>htpasswd</code> will do nothing except return an error.</p>
    
        <div class="example"><p><code>
          htpasswd -c /home/doe/public_html/.htpasswd jane
        </code></p></div>
    
        <p>Creates a new file and stores a record in it for user <code>jane</code>.
        The user is prompted for the password. If the file exists and cannot be
        read, or cannot be written, it is not altered and <code>htpasswd</code>
        will display a message and return an error status.</p>
    
        <div class="example"><p><code>
          htpasswd -db /usr/web/.htpasswd-all jones Pwd4Steve
        </code></p></div>
    
        <p>Encrypts the password from the command line (<code>Pwd4Steve</code>)
        using the <code>crypt()</code> algorithm, and stores it in the specified
        file.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Security Considerations</a></h2>
        <p>Web password files such as those managed by <code>htpasswd</code> should
        <em>not</em> be within the Web server's URI space -- that is, they should
        not be fetchable with a browser.</p>
    
        <p>This program is not safe as a setuid executable. Do <em>not</em> make it
        setuid.</p>
    
        <p>The use of the <code>-b</code> option is discouraged, since when it is
        used the plaintext password appears on the command line.</p>
    
        <p>When using the <code>crypt()</code> algorithm, note that only the first
        8 characters of the password are used  to form the password. If the supplied
        password is longer, the extra characters will be silently discarded.</p>
    
        <p>The SHA-1 hashing format does not use salting: for a given
        password, there is only one hashed representation. The
        <code>crypt()</code> and MD5 formats permute the representation by
        prepending a random salt string, to make dictionary attacks
        against the passwords more difficult.</p>
    
        <p>The SHA-1 and <code>crypt()</code> formats are insecure by
        today's standards.</p>
    
        <p>The SHA-2-based <code>crypt()</code> formats (SHA-256 and
        SHA-512) are supported on most modern Unix systems, and follow the
        specification at <a href="https://www.akkadia.org/drepper/SHA-crypt.txt">https://www.akkadia.org/drepper/SHA-crypt.txt</a>.</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="restrictions" id="restrictions">Restrictions</a></h2>
        <p>On the Windows platform, passwords hashed with
        <code>htpasswd</code> are limited to no more than <code>255</code>
        characters in length. Longer passwords will be truncated to 255
        characters.</p>
    
        <p>The MD5 algorithm used by <code>htpasswd</code> is specific to the Apache
        software; passwords hashed using it will not be usable with other Web
        servers.</p>
    
        <p>Usernames are limited to <code>255</code> bytes and may not include the
        character <code>:</code>.</p>
    
        <p>The cost of computing a bcrypt password hash value increases
        with the number of rounds specified by the <code>-C</code> option.
        The <code>apr-util</code> library enforces a maximum number of
        rounds of 17 in version <code>1.6.0</code> and later.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/htpasswd.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htpasswd.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htpasswd.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htpasswd.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htpasswd.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������httpd-2.4.64/docs/manual/programs/log_server_status.html.en�����������������������������������������0000664�0001751�0001751�00000013766�14737241666�023757� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>log_server_status - Log periodic status summaries - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>log_server_status - Log periodic status summaries</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/log_server_status.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/log_server_status.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>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. <code class="module"><a href="../mod/mod_status.html">mod_status</a></code> will
        need to be loaded and configured in order for this script to do its
        job.</p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">Usage</a></h2>
    
    <p>The script contains the following section.</p>
    
    <pre class="prettyprint lang-perl">my $wherelog = "/usr/local/apache2/logs/";  # Logs will be like "/usr/local/apache2/logs/19960312"
    my $server   = "localhost";        # Name of server, could be "www.foo.com"
    my $port     = "80";               # Port on server
    my $request = "/server-status/?auto";    # Request to send</pre>
    
    
    <p>You'll need to ensure that these variables have the correct values,
    and you'll need to have the <code>/server-status</code> handler
    configured at the location specified, and the specified log location
    needs to be writable by the user which will run the script.</p>
    
    <p>Run the script periodically via cron to produce a daily log file,
    which can then be used for statistical analysis.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/log_server_status.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/log_server_status.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/log_server_status.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������httpd-2.4.64/docs/manual/programs/split-logfile.html.en���������������������������������������������0000664�0001751�0001751�00000013413�14737241666�022744� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>split-logfile - Split up multi-vhost logfiles - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>split-logfile - Split up multi-vhost logfiles</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/split-logfile.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/split-logfile.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>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 using the "<code>%v</code>"
        variable in <code class="directive"><a href="../mod/mod_log_config.html#logformat">LogFormat</a></code>.
        </p>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="split-logfile" id="split-logfile">Usage</a></h2>
    
        <p>Create a log file with virtual host information in it:</p>
    
        <pre class="prettyprint lang-config">LogFormat "%v %h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-agent}i\"" combined_plus_vhost
    CustomLog logs/access_log combined_plus_vhost</pre>
    
    
        <p>Log files will be created, in the directory where you run the
        script, for each virtual host name that appears in the combined log file.
        These logfiles will named after the hostname, with a
        <code>.log</code> file extension.</p>
    
        <p>The combined log file is read from stdin. Records read will be appended
        to any existing log files.</p>
    
        <div class="example"><p><code>split-logfile &lt; access_log</code></p></div>
    
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/split-logfile.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/split-logfile.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/split-logfile.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdigest.html.en��������������������������������������������������0000664�0001751�0001751�00000017744�14737241666�022020� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>htdigest - manage user files for digest authentication - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>htdigest - manage user files for digest authentication</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/htdigest.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><code>htdigest</code> 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 <code>htdigest</code>.</p>
    
        <p>This manual page only lists the command line arguments. For details of
        the directives necessary to configure digest authentication in
        <code class="program"><a href="../programs/httpd.html">httpd</a></code> see the Apache manual, which is part
        of the Apache distribution or can be found at
        <a href="http://httpd.apache.org/">http://httpd.apache.org/</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#security">Security Considerations</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="../programs/httpd.html">httpd</a></code></li><li><code class="module"><a href="../mod/mod_auth_digest.html">mod_auth_digest</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
        <p><code><strong>htdigest</strong> [ -<strong>c</strong> ]
        <var>passwdfile</var> <var>realm</var> <var>username</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
        <dl>
        <dt><code>-c</code></dt>
        <dd>Create the <var>passwdfile</var>. If <var>passwdfile</var> already
        exists, it is deleted first.</dd>
    
        <dt><code><var>passwdfile</var></code></dt>
        <dd>Name of the file to contain the username, realm and password. If
        <code>-c</code> is given, this file is created if it does not already
        exist, or deleted and recreated if it does exist.</dd>
    
        <dt><code><var>realm</var></code></dt>
        <dd>The realm name to which the user name belongs. See 
        <a href="http://tools.ietf.org/html/rfc2617#section-3.2.1">
        http://tools.ietf.org/html/rfc2617#section-3.2.1</a> for more details.
        </dd>
    
        <dt><code><var>username</var></code></dt>
        <dd>The user name to create or update in <var>passwdfile</var>. If
        <var>username</var> does not exist is this file, an entry is added. If it
        does exist, the password is changed.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Security Considerations</a></h2>
        <p>This program is not safe as a setuid executable. Do <em>not</em> make it
        setuid.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/htdigest.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/htdigest.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/htdigest.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/htdigest.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/htdigest.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������httpd-2.4.64/docs/manual/programs/rotatelogs.html.en������������������������������������������������0000664�0001751�0001751�00000042333�14737241666�022360� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>rotatelogs - Piped logging program to rotate Apache logs - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>rotatelogs - Piped logging program to rotate Apache logs</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/rotatelogs.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>rotatelogs</code> is a simple program for use in
         conjunction with Apache's piped logfile feature.  It supports
         rotation based on a time interval or maximum size of the log.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#examples">Examples</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#portability">Portability</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
    
         <p><code><strong>rotatelogs</strong>
         [ -<strong>l</strong> ]
         [ -<strong>L</strong> <var>linkname</var> ]
         [ -<strong>p</strong> <var>program</var> ]
         [ -<strong>f</strong> ]
         [ -<strong>D</strong> ]
         [ -<strong>t</strong> ]
         [ -<strong>v</strong> ]
         [ -<strong>e</strong> ]
         [ -<strong>c</strong> ]
         [ -<strong>n</strong> <var>number-of-files</var> ]
         <var>logfile</var>
         <var>rotationtime</var>|<var>filesize</var>(B|K|M|G)
         [ <var>offset</var> ]</code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    
    <dt><code>-l</code></dt>
    <dd>Causes the use of local time rather than GMT as the base for the
    interval or for <code>strftime(3)</code> formatting with size-based
    rotation.</dd>
    
    <dt><code>-L</code> <var>linkname</var></dt>
    <dd><p>Causes a hard link to be made from the current logfile
    to the specified link name.  This can be used to watch
    the log continuously across rotations using a command like
    <code>tail -F linkname</code>.</p>
    <p>If the linkname is not an absolute
    path, it is relative to <code>rotatelogs</code>' working directory,
    which is the <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> when
    <code>rotatelogs</code> is run by the server.  
    </p>
    </dd>
    
    <dt><code>-p</code> <var>program</var></dt>
    
    <dd>If given, <code>rotatelogs</code> will execute the specified
    program every time a new log file is opened.  The filename of the
    newly opened file is passed as the first argument to the program.  If
    executing after a rotation, the old log file is passed as the second
    argument.  <code>rotatelogs</code> does not wait for the specified
    program to terminate before continuing to operate, and will not log
    any error code returned on termination.  The spawned program uses the
    same stdin, stdout, and stderr as rotatelogs itself, and also inherits
    the environment.</dd>
    
    <dt><code>-f</code></dt>
    <dd>Causes the logfile to be opened immediately, as soon as
    <code>rotatelogs</code> starts, instead of waiting for the
    first logfile entry to be read (for non-busy sites, there may be
    a substantial delay between when the server is started
    and when the first request is handled, meaning that the
    associated logfile does not "exist" until then, which
    causes problems from some automated logging tools)</dd>
    
    <dt><code>-D</code></dt>
    <dd>Creates the parent directories of the path that the log file will be
    placed in if they do not already exist.  This allows <code>strftime(3)</code>
    formatting to be used in the path and not just the filename.</dd>
    
    <dt><code>-t</code></dt>
    <dd>Causes the logfile to be truncated instead of rotated. This is
    useful when a log is processed in real time by a command like tail,
    and there is no need for archived data. No suffix will be added to
    the filename, however format strings containing '%' characters
    will be respected.
    </dd>
    
    <dt><code>-T</code></dt>
    <dd>Causes all but the initial logfile to be truncated when opened.
    This is useful when the format string contains something that will
    loop around, such as the day of the month. Available in 2.4.56 and later.
    </dd>
    
    
    <dt><code>-v</code></dt>
    <dd>Produce verbose output on STDERR. The output contains
    the result of the configuration parsing, and all file open and
    close actions.</dd>
    
    <dt><code>-e</code></dt>
    <dd>Echo logs through to stdout. Useful when logs need to be further
    processed in real time by a further tool in the chain.</dd>
    
    <dt><code>-c</code></dt>
    <dd>Create log file for each interval, even if empty.</dd>
    
    <dt><code>-n <var>number-of-files</var></code></dt>
    <dd>Use a circular list of filenames without timestamps. This option overwrites 
    log files at startup and during rotation.  With -n 3, the series of log 
    files opened would be "logfile", "logfile.1", "logfile.2", then overwriting 
    "logfile". 
    <br />
    When this program first opens "logfile", the file will only be truncated if <code>-t</code> is also provided. Every subsequent rotation will
    always begin with truncation of the target file.  For size based rotation without <code>-t</code> and existing log files in place,
    this option may result in unintuitive behavior such as initial log entries being sent to "logfile.1", and entries in "logfile.1" not being preserved
    even if later "logfile.n" have not yet been used.
    <br />
    Available in 2.4.5 and later.</dd>
    
    <dt><code><var>logfile</var></code></dt>
    
    <dd><p>The path plus basename of the logfile.  If <var>logfile</var>
    includes any '%' characters, it is treated as a format string for
    <code>strftime(3)</code>.  Otherwise, the suffix
    <var>.nnnnnnnnnn</var> is automatically added and is the time in
    seconds (unless the -t option is used). Both formats compute the
    start time from the beginning of the current period.  For example,
    if a rotation time of 86400 is specified, the hour, minute, and
    second fields created from the <code>strftime(3)</code> format will
    all be zero, referring to the beginning of the current 24-hour
    period (midnight).</p>
    <p>When using <code>strftime(3)</code> filename formatting,
    be sure the log file format has enough granularity to produce
    a different file name each time the logs are rotated.  Otherwise
    rotation will overwrite the same file instead of starting a new
    one.  For example, if <var>logfile</var> was
    <code>/var/log/errorlog.%Y-%m-%d</code> with log rotation at 5
    megabytes, but 5 megabytes was reached twice in the same day, the
    same log file name would be produced and log rotation would keep
    writing to the same file.</p>
    <p>If the logfile is not an absolute
    path, it is relative to <code>rotatelogs</code>' working directory,
    which is the <code class="directive"><a href="../mod/core.html#serverroot">ServerRoot</a></code> when
    <code>rotatelogs</code> is run by the server.
    </p>
    </dd>
    
    <dt><code><var>rotationtime</var></code></dt>
    
    <dd>The time between log file rotations in seconds.  The rotation
    occurs at the beginning of this interval.  For example, if the
    rotation time is 3600, the log file will be rotated at the beginning
    of every hour; if the rotation time is 86400, the log file will be
    rotated every night at midnight.  (If no data is logged during an
    interval, no file will be created.)</dd>
    
    <dt><code><var>filesize</var>(B|K|M|G)</code></dt>
    
    <dd>The maximum file size in followed by exactly one of the letters
    <code>B</code> (Bytes), <code>K</code> (KBytes), <code>M</code> (MBytes)
    or <code>G</code> (GBytes).
    <p>
    When time and size are specified, the size must be given after the time.
    Rotation will occur whenever either time or size limits are reached.
    </p>
    </dd>
    
    <dt><code><var>offset</var></code></dt>
    
    <dd>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 <code>-300</code> for this argument.
    In most cases, <code>-l</code> should be used instead of specifying
    an offset.</dd>
    
    </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Examples</a></h2>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/logfile 86400" common</pre>
    </div>
    
         <p>This creates the files /var/log/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.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -l /var/log/logfile.%Y.%m.%d 86400" common</pre>
    </div>
    
         <p>This creates the files /var/log/logfile.yyyy.mm.dd where
         yyyy is the year, mm is the month, and dd is the day of the month.
         Logging will switch to a new file every day at midnight, local time.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/logfile 5M" common</pre>
    </div>
    
         <p>This configuration will rotate the logfile whenever it reaches
         a size of 5 megabytes.</p>
    
    <div class="example"><pre class="prettyprint lang-config">ErrorLog "|bin/rotatelogs /var/log/errorlog.%Y-%m-%d-%H_%M_%S 5M"</pre>
    </div>
         <p>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
         <code>errorlog.YYYY-mm-dd-HH_MM_SS</code>.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -t /var/log/logfile 86400" common</pre>
    </div>
    
         <p>This creates the file <code>/var/log/logfile</code>, truncating the file at
         startup and then truncating the file once per day. It is expected
         in this scenario that a separate process (such as tail) would
         process the file in real time.</p>
    
    <div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -T /var/log/logfile.%d 86400" common</pre>
    </div>
    
    <p>If the server is started (or restarted) on the first of the month, this 
    appends to <code>/var/log/logfile.01</code>.  When a log entry is written on the
    second of the month, <code>/var/log/logfile.02</code> is truncated and new entries
    will be added to the top. This example keeps approximately 1 months worth of 
    logs without external maintenance.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="portability" id="portability">Portability</a></h2>
    
    <p>The following logfile format string substitutions should be
    supported by all <code>strftime(3)</code> implementations, see
    the <code>strftime(3)</code> man page for library-specific
    extensions.</p>
    
    <table class="bordered"><tr><td><code>%A</code></td><td>full weekday name (localized)</td></tr>
    <tr class="odd"><td><code>%a</code></td><td>3-character weekday name (localized)</td></tr>
    <tr><td><code>%B</code></td><td>full month name (localized)</td></tr>
    <tr class="odd"><td><code>%b</code></td><td>3-character month name (localized)</td></tr>
    <tr><td><code>%c</code></td><td>date and time (localized)</td></tr>
    <tr class="odd"><td><code>%d</code></td><td>2-digit day of month</td></tr>
    <tr><td><code>%H</code></td><td>2-digit hour (24 hour clock)</td></tr>
    <tr class="odd"><td><code>%I</code></td><td>2-digit hour (12 hour clock)</td></tr>
    <tr><td><code>%j</code></td><td>3-digit day of year</td></tr>
    <tr class="odd"><td><code>%M</code></td><td>2-digit minute</td></tr>
    <tr><td><code>%m</code></td><td>2-digit month</td></tr>
    <tr class="odd"><td><code>%p</code></td><td>am/pm of 12 hour clock (localized)</td></tr>
    <tr><td><code>%S</code></td><td>2-digit second</td></tr>
    <tr class="odd"><td><code>%U</code></td><td>2-digit week of year
    (Sunday first day of week)</td></tr>
    <tr><td><code>%W</code></td><td>2-digit week of year
    (Monday first day of week)</td></tr>
    <tr class="odd"><td><code>%w</code></td><td>1-digit weekday
    (Sunday first day of week)</td></tr>
    <tr><td><code>%X</code></td><td>time (localized)</td></tr>
    <tr class="odd"><td><code>%x</code></td><td>date (localized)</td></tr>
    <tr><td><code>%Y</code></td><td>4-digit year</td></tr>
    <tr class="odd"><td><code>%y</code></td><td>2-digit year</td></tr>
    <tr><td><code>%Z</code></td><td>time zone name</td></tr>
    <tr class="odd"><td><code>%%</code></td><td>literal `%'</td></tr>
    </table>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/rotatelogs.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/rotatelogs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/rotatelogs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/rotatelogs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/other.html.en�����������������������������������������������������0000664�0001751�0001751�00000012267�14737241666�021321� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Other Programs - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>Other Programs</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/other.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>This page used to contain documentation for programs which now
        have their own docs pages. Please update any links.</p>
    
        <p><code class="program"><a href="../programs/log_server_status.html">log_server_status</a></code></p>
        <p><code class="program"><a href="../programs/split-logfile.html">split-logfile</a></code></p>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/other.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/other.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/other.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/other.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/other.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/logresolve.html.en������������������������������������������������0000664�0001751�0001751�00000015512�14737241666�022355� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>logresolve - Resolve IP-addresses to hostnames in Apache
       log files - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>logresolve - Resolve IP-addresses to hostnames in Apache
       log files</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/logresolve.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>logresolve</code> 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.</p>
    
         <p>Takes an Apache log file on standard input.  The IP addresses
         must be the first thing on each line and must be separated from
         the remainder of the line by a space.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
    
         <p><code><strong>logresolve</strong> [ -<strong>s</strong>
         <var>filename</var> ] [ -<strong>c</strong> ] &lt;
         <var>access_log</var> &gt; <var>access_log.new</var></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    
    <dt><code>-s <var>filename</var></code></dt>
    
    <dd>Specifies a filename to record statistics.</dd>
    
    <dt><code>-c</code></dt>
    
    <dd>This causes <code>logresolve</code> 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.</dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/logresolve.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/logresolve.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/logresolve.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/logresolve.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/logresolve.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/suexec.html.en����������������������������������������������������0000664�0001751�0001751�00000015262�14737241666�021472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>suexec - Switch user before executing external programs - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Programs</a></div><div id="page-content"><div id="preamble"><h1>suexec - Switch user before executing external programs</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/programs/suexec.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p><code>suexec</code> 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 <code>root</code>. Since the HTTP daemon normally doesn't
         run as <code>root</code>, the <code>suexec</code> executable needs the
         setuid bit set and must be owned by <code>root</code>. It should never be
         writable for any other person than <code>root</code>.</p>
    
         <p>For further information about the concepts and the security model
         of suexec please refer to the suexec documentation (<a href="http://httpd.apache.org/docs/2.4/suexec.html">http://httpd.apache.org/docs/2.4/suexec.html</a>).</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#synopsis">Synopsis</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="synopsis" id="synopsis">Synopsis</a></h2>
         <p><code><strong>suexec</strong> -<strong>V</strong></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="options" id="options">Options</a></h2>
    
    <dl>
    <dt><code>-V</code></dt>
    
    <dd>If you are <code>root</code>, this option displays the compile options of
    <code>suexec</code>. For security reasons all configuration options are
    changeable only at compile time.</dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/programs/suexec.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/programs/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../ko/programs/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="../tr/programs/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/programs/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/configure.html����������������������������������������������������0000664�0001751�0001751�00000000606�13710016232�021525� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: configure.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: configure.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: configure.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: configure.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/httxt2dbm.html����������������������������������������������������0000664�0001751�0001751�00000000452�13710016232�021463� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: httxt2dbm.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: httxt2dbm.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: httxt2dbm.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htcacheclean.html�������������������������������������������������0000664�0001751�0001751�00000000622�13710016232�022144� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: htcacheclean.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: htcacheclean.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: htcacheclean.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: htcacheclean.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/logresolve.html���������������������������������������������������0000664�0001751�0001751�00000000612�13710016232�021722� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: logresolve.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: logresolve.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: logresolve.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: logresolve.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/apachectl.html����������������������������������������������������0000664�0001751�0001751�00000000606�13710016232�021470� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: apachectl.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: apachectl.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: apachectl.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: apachectl.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/fcgistarter.html��������������������������������������������������0000664�0001751�0001751�00000000460�13710016232�022057� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: fcgistarter.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: fcgistarter.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: fcgistarter.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htpasswd.html�����������������������������������������������������0000664�0001751�0001751�00000000602�13710016232�021375� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: htpasswd.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: htpasswd.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: htpasswd.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: htpasswd.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/log_server_status.html��������������������������������������������0000664�0001751�0001751�00000000341�13710016232�023312� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: log_server_status.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: log_server_status.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/split-logfile.html������������������������������������������������0000664�0001751�0001751�00000000331�13710016232�022311� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: split-logfile.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: split-logfile.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/htdigest.html�����������������������������������������������������0000664�0001751�0001751�00000000602�13710016232�021353� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: htdigest.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: htdigest.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: htdigest.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: htdigest.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/programs/rotatelogs.html���������������������������������������������������0000664�0001751�0001751�00000000612�13710016232�021724� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: rotatelogs.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: rotatelogs.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: rotatelogs.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: rotatelogs.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/�������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�016526� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/flags.html.en������������������������������������������������������0000664�0001751�0001751�00000132223�14737241666�021116� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>RewriteRule Flags - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>RewriteRule Flags</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/flags.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/flags.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <p>This document discusses the flags which are available to the
    <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directive,
    providing detailed explanations and examples.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_b">B (escape backreferences)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_bnp">BNP|backrefnoplus (don't escape space to +)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_bctls">BCTLS</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_bne">BNE</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_c">C|chain</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_co">CO|cookie</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_dpi">DPI|discardpath</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_e">E|env</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_end">END</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_f">F|forbidden</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_g">G|gone</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_h">H|handler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_l">L|last</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_n">N|next</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_nc">NC|nocase</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_ne">NE|noescape</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_ns">NS|nosubreq</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_p">P|proxy</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_pt">PT|passthrough</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_qsa">QSA|qsappend</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_qsd">QSD|qsdiscard</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_qsl">QSL|qslast</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_r">R|redirect</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_s">S|skip</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_t">T|type</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_allow_3f">UnsafeAllow3F</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_prefix_stat">UnsafePrefixStat</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_unc">UNC</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    <p>A <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> can have
    its behavior modified by one or more flags. Flags are included in
    square brackets at the end of the rule, and multiple flags are separated
    by commas.</p>
    <pre class="prettyprint lang-config">RewriteRule pattern target [Flag1,Flag2,Flag3]</pre>
    
    
    <p>Each flag (with a few exceptions) has a short form, such as
    <code>CO</code>, as well as a longer form, such as <code>cookie</code>.
    While it is most common to use
    the short form, it is recommended that you familiarize yourself with the
    long form, so that you remember what each flag is supposed to do.
    Some flags take one or more arguments. Flags are not case sensitive.</p>
    
    <p>Flags that alter metadata associated with the request (T=, H=, E=)
    have no affect in per-directory and htaccess context, when a substitution
    (other than '-') is performed during the same round of rewrite processing.
    </p>
    
    <p>Presented here are each of the available flags, along with an example
    of how you might use them.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_b" id="flag_b">B (escape backreferences)</a></h2>
    <p>The [B] flag instructs <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to escape non-alphanumeric
    characters before applying the transformation.</p>
    
    <p><code>mod_rewrite</code> has to unescape URLs before mapping them,
    so backreferences are unescaped at the time they are applied.
    Using the B flag, non-alphanumeric characters in backreferences
    will be escaped. For example, consider the rule:</p>
    
    <p>For similar escaping of server-variables, see
        the "escape" <a href="#mapfunc">mapping-function</a></p>
    
    
    <pre class="prettyprint lang-config">RewriteRule "^search/(.*)$" "/search.php?term=$1"</pre>
    
    
    <p>Given a search term of 'x &amp; y/z', a browser will encode it as
    'x%20%26%20y%2Fz', making the request 'search/x%20%26%20y%2Fz'. Without the B
    flag, this rewrite rule will map to 'search.php?term=x &amp; y/z', which
    isn't a valid URL, and so would be encoded as
    <code>search.php?term=x%20&amp;y%2Fz=</code>, which is not what was intended.</p>
    
    <p>With the B flag set on this same rule, the parameters are re-encoded
    before being passed on to the output URL, resulting in a correct mapping to
    <code>/search.php?term=x%20%26%20y%2Fz</code>.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^search/(.*)$" "/search.php?term=$1" [B,PT]</pre>
    
    
    <p>Note that you may also need to set <code class="directive"><a href="../mod/core.html#allowencodedslashes">AllowEncodedSlashes</a></code> to <code>On</code> to get this
    particular example to work, as httpd does not allow encoded slashes in URLs, and
    returns a 404 if it sees one.</p>
    
    <p>This escaping is particularly necessary in a proxy situation,
    when the backend may break if presented with an unescaped URL.</p>
    
    <p>An alternative to this flag is using a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> to capture against %{THE_REQUEST} which will capture
    strings in the encoded form.</p>
    
    <p>In 2.4.26 and later, you can limit the escaping to specific characters
    in backreferences by listing them: <code>[B=#?;]</code>. Note: The space
    character can be used in the list of characters to escape, but you must quote
    the entire third argument of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
    and the space must not be the last character in the list.</p>
    
    <pre class="prettyprint lang-config"># Escape spaces and question marks.  The quotes around the final argument 
    # are required when a space is included.
    RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"</pre>
    
    
    <p>To limit the characters escaped this way, see <a href="#flag_bne">#flag_bne</a>
            and <a href="#flag_bctls">#flag_bctls</a></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_bnp" id="flag_bnp">BNP|backrefnoplus (don't escape space to +)</a></h2>
    <p>The [BNP] flag instructs <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to escape the space character
    in a backreference to %20 rather than '+'. Useful when the backreference
    will be used in the path component rather than the query string.</p>
    
    <pre class="prettyprint lang-config"># Escape spaces to %20 in the path instead of + as used in form submission via
    # the query string
    RewriteRule "^search/(.*)$" "/search.php/$1" "[B,BNP]"</pre>
    
    
    
    <p>This flag is available in version 2.4.26 and later.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_bctls" id="flag_bctls">BCTLS</a></h2>
    <p>The [BCTLS] flag is similar to the [B] flag, but only escapes
    control characters and the space character. This is the same set of
    characters rejected when they are copied into the query string unencoded.
    </p>
    
    <pre class="prettyprint lang-config"># Escape control characters and spaces
    RewriteRule "^search/(.*)$" "/search.php/$1" "[BCTLS]"</pre>
    
    
    <p>This flag is available in version 2.4.57 and later.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_bne" id="flag_bne">BNE</a></h2>
    <p>The list of characters in [BNE=...] are treated as exclusions to the
    characters of the [B] or [BCTLS] flags. The listed characters will not be
    escaped.
    </p>
    
    <pre class="prettyprint lang-config"># Escape the default characters, but leave /
    RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B,BNE=/]"</pre>
    
    
    <p>This flag is available in version 2.4.57 and later.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_c" id="flag_c">C|chain</a></h2>
    <p>The [C] or [chain] flag indicates that the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> is chained to the next
    rule. That is, if the rule matches, then it is processed as usual and
    control moves on to the next rule. However, if it does not match, then
    the next rule, and any other rules that are chained together, are
    skipped.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_co" id="flag_co">CO|cookie</a></h2>
    <p>The [CO], or [cookie] flag, allows you to set a cookie when a
    particular <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
    matches. The argument consists of three required fields and five optional
    fields.</p>
    
    <p>The full syntax for the flag, including all attributes, is as
    follows:</p>
    
    <div class="example"><p><code>
    [CO=NAME:VALUE:DOMAIN:lifetime:path:secure:httponly:samesite]
    </code></p></div>
    
    <p>If a literal ':' character is needed in any of the cookie fields, an 
    alternate syntax is available.  To opt-in to the alternate syntax, the cookie 
    "Name" should be preceded with a ';' character, and field separators should be
    specified as ';'.</p>
    
    <div class="example"><p><code>
    [CO=;NAME;VALUE:MOREVALUE;DOMAIN;lifetime;path;secure;httponly;samesite]
    </code></p></div>
    
    <p>You must declare a name, a value, and a domain for the cookie to be set.</p>
    
    <dl>
    <dt>Domain</dt>
    <dd>The domain for which you want the cookie to be valid. This may be a
    hostname, such as <code>www.example.com</code>, or it may be a domain,
    such as <code>.example.com</code>. It must be at least two parts
    separated by a dot. That is, it may not be merely <code>.com</code> or
    <code>.net</code>. Cookies of that kind are forbidden by the cookie
    security model.</dd>
    </dl>
    
    <p>You may optionally also set the following values:</p>
    
    <dl>
    <dt>Lifetime</dt>
    <dd>The time for which the cookie will persist, in minutes.</dd>
    <dd>A value of 0 indicates that the cookie will persist only for the
    current browser session. This is the default value if none is
    specified.</dd>
    
    <dt>Path</dt>
    <dd>The path, on the current website, for which the cookie is valid,
    such as <code>/customers/</code> or <code>/files/download/</code>.</dd>
    <dd>By default, this is set to <code>/</code> - that is, the entire
    website.</dd>
    
    <dt>Secure</dt>
    <dd>If set to <code>secure</code>, <code>true</code>, or <code>1</code>,
    the cookie will only be permitted to be translated via secure (https)
    connections.</dd>
    
    <dt>httponly</dt>
    <dd>If set to <code>HttpOnly</code>, <code>true</code>, or
    <code>1</code>, the cookie will have the <code>HttpOnly</code> flag set,
    which means that the cookie is inaccessible to JavaScript code on
    browsers that support this feature.</dd>
    
    <dt>samesite</dt>
    <dd>If set to anything other than <code>false</code> or <code>0</code>, the <code>SameSite</code>
    attribute is set to the specified value.  Typical values are <code>None</code>,
    <code>Lax</code>, and <code>Strict</code>. Available in 2.4.47 and later.</dd>
    </dl>
    
    
    <p>Consider this example:</p>
    
    <pre class="prettyprint lang-config">RewriteEngine On
    RewriteRule   "^/index\.html"   "-" [CO=frontdoor:yes:.example.com:1440:/]</pre>
    
    
    <p>In the example give, the rule doesn't rewrite the request.
    The "-" rewrite target tells mod_rewrite to pass the request
    through unchanged. Instead, it sets a cookie
    called 'frontdoor' to a value of 'yes'. The cookie is valid for any host
    in the <code>.example.com</code> domain. It is set to expire in 1440
    minutes (24 hours) and is returned for all URIs.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_dpi" id="flag_dpi">DPI|discardpath</a></h2>
    <p>The DPI flag causes the PATH_INFO portion of the rewritten URI to be
    discarded.</p>
    <p>This flag is available in version 2.2.12 and later.</p>
    <p>In per-directory context, the URI each <code class="directive">RewriteRule</code>
    compares against is the concatenation of the current values of the URI
    and PATH_INFO.</p>
    
    <p>The current URI can be the initial URI as requested by the client, the
    result of a previous round of mod_rewrite processing, or the result of
    a prior rule in the current round of mod_rewrite processing.</p>
    
    <p>In contrast, the PATH_INFO that is appended to the URI before each
    rule reflects only the value of PATH_INFO before this round of
    mod_rewrite processing. As a consequence, if large portions
    of the URI are matched and copied into a substitution in multiple
    <code class="directive">RewriteRule</code> directives, without regard for
    which parts of the URI came from the current PATH_INFO, the final
    URI may have multiple copies of PATH_INFO appended to it.</p>
    
    <p>Use this flag on any substitution where the PATH_INFO that resulted
    from the previous mapping of this request to the filesystem is not of
    interest.  This flag permanently forgets the PATH_INFO established
    before this round of mod_rewrite processing began. PATH_INFO will
    not be recalculated until the current round of mod_rewrite processing
    completes.  Subsequent rules during this round of processing will see
    only the direct result of substitutions, without any PATH_INFO
    appended.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_e" id="flag_e">E|env</a></h2>
    <p>With the [E], or [env] flag, you can set the value of an environment
    variable. Note that some environment variables may be set after the rule
    is run, thus unsetting what you have set. See <a href="../env.html">the
    Environment Variables document</a> for more details on how Environment
    variables work.</p>
    
    <p>The full syntax for this flag is:</p>
    
    <pre class="prettyprint lang-config">[E=VAR:VAL]
    [E=!VAR]</pre>
    
    
    <p><code>VAL</code> may contain backreferences (<code>$N</code> or
    <code>%N</code>) which are expanded.</p>
    
    <p>Using the short form</p>
    
    <div class="example"><p><code>
    [E=VAR]
    </code></p></div>
    
    <p>you can set the environment variable named <code>VAR</code> to an
    empty value.</p>
    
    <p>The form</p>
    
    <div class="example"><p><code>
    [E=!VAR]
    </code></p></div>
    
    <p>allows to unset a previously set environment variable named
    <code>VAR</code>.</p>
    
    <p>Environment variables can then be used in a variety of
    contexts, including CGI programs, other RewriteRule directives, or
    CustomLog directives.</p>
    
    <p>The following example sets an environment variable called 'image' to a
    value of '1' if the requested URI is an image file. Then, that
    environment variable is used to exclude those requests from the access
    log.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "\.(png|gif|jpg)$"   "-" [E=image:1]
    CustomLog   "logs/access_log"    combined env=!image</pre>
    
    
    <p>Note that this same effect can be obtained using <code class="directive"><a href="../mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>. This technique is offered as
    an example, not as a recommendation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_end" id="flag_end">END</a></h2>
    <p>Using the [END] flag terminates not only the current round of rewrite
    processing (like [L]) but also prevents any subsequent rewrite
    processing from occurring in per-directory (htaccess) context.</p>
    
    <p>This does not apply to new requests resulting from external
    redirects.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_f" id="flag_f">F|forbidden</a></h2>
    <p>Using the [F] flag causes the server to return a 403 Forbidden status
    code to the client. While the same behavior can be accomplished using
    the <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code> directive, this
    allows more flexibility in assigning a Forbidden status.</p>
    
    <p>The following rule will forbid <code>.exe</code> files from being
    downloaded from your server.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "\.exe"   "-" [F]</pre>
    
    
    <p>This example uses the "-" syntax for the rewrite target, which means
    that the requested URI is not modified. There's no reason to rewrite to
    another URI, if you're going to forbid the request.</p>
    
    <p>When using [F], an [L] is implied - that is, the response is returned
    immediately, and no further rules are evaluated.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_g" id="flag_g">G|gone</a></h2>
    <p>The [G] flag forces the server to return a 410 Gone status with the
    response. This indicates that a resource used to be available, but is no
    longer available.</p>
    
    <p>As with the [F] flag, you will typically use the "-" syntax for the
    rewrite target when using the [G] flag:</p>
    
    <pre class="prettyprint lang-config">RewriteRule "oldproduct"   "-" [G,NC]</pre>
    
    
    <p>When using [G], an [L] is implied - that is, the response is returned
    immediately, and no further rules are evaluated.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_h" id="flag_h">H|handler</a></h2>
    <p>Forces the resulting request to be handled with the specified
    handler. For example, one might use this to force all files without a
    file extension to be parsed by the php handler:</p>
    
    <pre class="prettyprint lang-config">RewriteRule "!\."  "-" [H=application/x-httpd-php]</pre>
    
    
    <p>
    The regular expression above - <code>!\.</code> - will match any request
    that does not contain the literal <code>.</code> character.
    </p>
    
    <p>This can be also used to force the handler based on some conditions.
    For example, the following snippet used in per-server context allows
    <code>.php</code> files to be <em>displayed</em> by <code>mod_php</code>
    if they are requested with the <code>.phps</code> extension:</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^(/source/.+\.php)s$" "$1" [H=application/x-httpd-php-source]</pre>
    
    
    <p>The regular expression above - <code>^(/source/.+\.php)s$</code> - will
    match any request that starts with <code>/source/</code> followed by 1 or
    n characters followed by <code>.phps</code> literally. The backreference
    $1 referrers to the captured match within parenthesis of the regular
    expression.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_l" id="flag_l">L|last</a></h2>
    <p>The [L] flag causes <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> to stop processing
    the rule set. In most contexts, this means that if the rule matches, no
    further rules will be processed. This corresponds to the
    <code>last</code> command in Perl, or the <code>break</code> command in
    C. Use this flag to indicate that the current rule should be applied
    immediately without considering further rules.</p>
    
    <p>If you are using <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> in either
    <code>.htaccess</code> files or in
    <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> sections,
    it is important to have some understanding of how the rules are
    processed.  The simplified form of this is that once the rules have been
    processed, the rewritten request is handed back to the URL parsing
    engine to do what it may with it. It is possible that as the rewritten
    request is handled, the <code>.htaccess</code> file or
    <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> section
    may be encountered again, and thus the ruleset may be run again from the
    start. Most commonly this will happen if one of the rules causes a
    redirect - either internal or external - causing the request process to
    start over.</p>
    
    <p>It is therefore important, if you are using <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives in one of these
    contexts, that you take explicit steps to avoid rules looping, and not
    count solely on the [L] flag to terminate execution of a series of
    rules, as shown below.</p>
    
    <p> An alternative flag, [END], can be used to terminate not only the
    current round of rewrite processing but prevent any subsequent
    rewrite processing from occurring in per-directory (htaccess)
    context. This does not apply to new requests resulting from external
    redirects.</p>
    
    <p>The example given here will rewrite any request to
    <code>index.php</code>, giving the original request as a query string
    argument to <code>index.php</code>, however, the <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> ensures that if the request
    is already for <code>index.php</code>, the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> will be skipped.</p>
    
    <pre class="prettyprint lang-config">RewriteBase "/"
    RewriteCond "%{REQUEST_URI}" !=/index.php
    RewriteRule "^(.*)"          "/index.php?req=$1" [L,PT]</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_n" id="flag_n">N|next</a></h2>
    <p>
    The [N] flag causes the ruleset to start over again from the top, using
    the result of the ruleset so far as a starting point. Use
    with extreme caution, as it may result in loop.
    </p>
    <p>
    The [Next] flag could be used, for example, if you wished to replace a
    certain string or letter repeatedly in a request. The example shown here
    will replace A with B everywhere in a request, and will continue doing
    so until there are no more As to be replaced.
    </p>
    <pre class="prettyprint lang-config">RewriteRule "(.*)A(.*)" "$1B$2" [N]</pre>
    
    <p>You can think of this as a <code>while</code> loop: While this
    pattern still matches (i.e., while the URI still contains an
    <code>A</code>), perform this substitution (i.e., replace the
    <code>A</code> with a <code>B</code>).</p>
    
    <p>In 2.4.8 and later, this module returns an error after 10,000 iterations to
    protect against unintended looping.  An alternative maximum number of
    iterations can be specified by adding to the N flag.  </p>
    <pre class="prettyprint lang-config"># Be willing to replace 1 character in each pass of the loop
    RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=32000]
    # ... or, give up if after 10 loops
    RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=10]</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_nc" id="flag_nc">NC|nocase</a></h2>
    <p>Use of the [NC] flag causes the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to be matched in a
    case-insensitive manner. That is, it doesn't care whether letters appear
    as upper-case or lower-case in the matched URI.</p>
    
    <p>In the example below, any request for an image file will be proxied
    to your dedicated image server. The match is case-insensitive, so that
    <code>.jpg</code> and <code>.JPG</code> files are both acceptable, for
    example.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "(.*\.(jpg|gif|png))$" "http://images.example.com$1" [P,NC]</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_ne" id="flag_ne">NE|noescape</a></h2>
    <p>By default, special characters, such as <code>&amp;</code> and
    <code>?</code>, for example, will be converted to their hexcode
    equivalent for rules that result in external redirects. 
    Using the [NE] flag prevents that from happening.
    </p>
    
    <pre class="prettyprint lang-config">RewriteRule "^/anchor/(.+)" "/bigpage.html#$1" [NE,R]</pre>
    
    
    <p>
    The above example will redirect <code>/anchor/xyz</code> to
    <code>/bigpage.html#xyz</code>. Omitting the [NE] will result in the #
    being converted to its hexcode equivalent, <code>%23</code>, which will
    then result in a 404 Not Found error condition.
    </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_ns" id="flag_ns">NS|nosubreq</a></h2>
    <p>Use of the [NS] flag prevents the rule from being used on
    subrequests. For example, a page which is included using an SSI (Server
    Side Include) is a subrequest, and you may want to avoid rewrites
    happening on those subrequests. Also, when <code class="module"><a href="../mod/mod_dir.html">mod_dir</a></code>
    tries to find out information about possible directory default files
    (such as <code>index.html</code> files), this is an internal
    subrequest, and you often want to avoid rewrites on such subrequests.
    On subrequests, it is not always useful, and can even cause errors, if
    the complete set of rules are applied. Use this flag to exclude
    problematic rules.</p>
    
    <p>To decide whether or not to use this rule: if you prefix URLs with
    CGI-scripts, to force them to be processed by the CGI-script, it's
    likely that you will run into problems (or significant overhead)
    on sub-requests. In these cases, use this flag.</p>
    
    <p>
    Images, javascript files, or css files, loaded as part of an HTML page,
    are not subrequests - the browser requests them as separate HTTP
    requests.
    </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_p" id="flag_p">P|proxy</a></h2>
    <p>Use of the [P] flag causes the request to be handled by
    <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>, and handled via a proxy request. For
    example, if you wanted all image requests to be handled by a back-end
    image server, you might do something like the following:</p>
    
    <pre class="prettyprint lang-config">RewriteRule "/(.*)\.(jpg|gif|png)$" "http://images.example.com/$1.$2" [P]</pre>
    
    
    <p>Use of the [P] flag implies [L] - that is, the request is immediately
    pushed through the proxy, and any following rules will not be
    considered.</p>
    
    <p>
    You must make sure that the substitution string is a valid URI
    (typically starting with <code>http://</code><em>hostname</em>) which can be
    handled by the <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>. If not, you will get an
    error from the proxy module. Use this flag to achieve a
    more powerful implementation of the <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> directive,
    to map remote content into the namespace of the local server.</p>
    
    <div class="warning">
    <h3>Security Warning</h3>
    <p>Take care when constructing the target URL of the rule, considering
    the security impact from allowing the client influence over the set of
    URLs to which your server will act as a proxy.  Ensure that the scheme
    and hostname part of the URL is either fixed, or does not allow the
    client undue influence.</p>
    </div>
    
    <div class="warning">
    <h3>Performance warning</h3>
    <p>Using this flag triggers the use of <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>, without
    handling of persistent connections as the default worker is used in this case,
    which does not handle connection pooling/reuse.</p>
    <p>In order to use persistent connections you need to setup a
    <code class="directive"><a href="../mod/mod_proxy.html#proxy">Proxy</a></code> block at least for the scheme
    and host part of the target URL containing a
    <code class="directive"><a href="../mod/mod_proxy.html#proxyset">ProxySet</a></code> directive where you e.g. set
    a timeout.</p>
    <p>If you set it up with <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> or
    <code class="directive"><a href="../mod/mod_proxy.html#proxypassmatch">ProxyPassMatch</a></code> persistent connections
    will be used automatically.</p>
    </div>
    
    <p>Note: <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> must be enabled in order
    to use this flag.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_pt" id="flag_pt">PT|passthrough</a></h2>
    
    <p>
    The target (or substitution string) in a RewriteRule is assumed to be a
    file path, by default. The use of the [PT] flag causes it to be treated
    as a URI instead. That is to say, the
    use of the [PT] flag causes the result of the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to be passed back through
    URL mapping, so that location-based mappings, such as <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>, <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code>, or <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>, for example, might have a
    chance to take effect.
    </p>
    
    <p>
    If, for example, you have an
    <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>
    for /icons, and have a <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> pointing there, you should
    use the [PT] flag to ensure that the
    <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> is evaluated.
    </p>
    
    <pre class="prettyprint lang-config">Alias "/icons" "/usr/local/apache/icons"
    RewriteRule "/pics/(.+)\.jpg$" "/icons/$1.gif" [PT]</pre>
    
    
    <p>
    Omission of the [PT] flag in this case will cause the Alias to be
    ignored, resulting in a 'File not found' error being returned.
    </p>
    
    <p>The <code>PT</code> flag implies the <code>L</code> flag:
    rewriting will be stopped in order to pass the request to
    the next phase of processing.</p>
    
    <p>Note that the <code>PT</code> flag is implied in per-directory
    contexts such as
    <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> sections
    or in <code>.htaccess</code> files. The only way to circumvent that
    is to rewrite to <code>-</code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_qsa" id="flag_qsa">QSA|qsappend</a></h2>
    <p>
    When the replacement URI contains a query string, the default behavior
    of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> is to discard
    the existing query string, and replace it with the newly generated one.
    Using the [QSA] flag causes the query strings to be combined.
    </p>
    
    <p>Consider the following rule:</p>
    
    <pre class="prettyprint lang-config">RewriteRule "/pages/(.+)" "/page.php?page=$1" [QSA]</pre>
    
    
    <p>With the [QSA] flag, a request for <code>/pages/123?one=two</code> will be
    mapped to <code>/page.php?page=123&amp;one=two</code>. Without the [QSA]
    flag, that same request will be mapped to
    <code>/page.php?page=123</code> - that is, the existing query string
    will be discarded.
    </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_qsd" id="flag_qsd">QSD|qsdiscard</a></h2>
    <p>
    When the requested URI contains a query string, and the target URI does
    not, the default behavior of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> is to copy that query
    string to the target URI. Using the [QSD] flag causes the query string
    to be discarded.
    </p>
    
    <p>This flag is available in version 2.4.0 and later.</p>
    
    <p>
    Using [QSD] and [QSA] together will result in [QSD] taking precedence.
    </p>
    
    <p>
    If the target URI has a query string, the default behavior will be
    observed - that is, the original query string will be discarded and
    replaced with the query string in the <code>RewriteRule</code> target
    URI.
    </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_qsl" id="flag_qsl">QSL|qslast</a></h2>
    <p>
    By default, the first (left-most) question mark in the substitution
    delimits the path from the query string.  Using the [QSL] flag instructs
    <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to instead split
    the two components using the last (right-most) question mark.  </p>
    
    <p>
    This is useful when mapping to files that have literal question marks in 
    their filename.  If no query string is used in the substitution, 
    a question mark can be appended to it in combination with this flag.  </p>
    
    <p> This flag is available in version 2.4.19 and later.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_r" id="flag_r">R|redirect</a></h2>
    <p>
    Use of the [R] flag causes a HTTP redirect to be issued to the browser.
    If a fully-qualified URL is specified (that is, including
    <code>http://servername/</code>) then a redirect will be issued to that
    location. Otherwise, the current protocol, servername, and port number
    will be used to generate the URL sent with the redirect.
    </p>
    
    <p>
    <em>Any</em> valid HTTP response  status code may be specified,
    using the syntax [R=305], with a 302 status code being used by
    default if none is specified. The status code specified need not
    necessarily be a redirect (3xx) status code. However,
    if a status code is outside the redirect range (300-399) then the
    substitution string is dropped entirely, and rewriting is stopped as if
    the <code>L</code> were used.</p>
    
    <p>In addition to response status codes, you may also specify redirect
    status using their symbolic names: <code>temp</code> (default),
    <code>permanent</code>, or <code>seeother</code>.</p>
    
    <p>
    You will almost always want to use [R] in conjunction with [L] (that is,
    use [R,L]) because on its own, the [R] flag prepends
    <code>http://thishost[:thisport]</code> to the URI, but then passes this
    on to the next rule in the ruleset, which can often result in 'Invalid
    URI in request' warnings.
    </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_s" id="flag_s">S|skip</a></h2>
    <p>The [S] flag is used to skip rules that you don't want to run. The
    syntax of the skip flag is [S=<em>N</em>], where <em>N</em> signifies
    the number of rules to skip (provided the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">
    RewriteRule</a></code> and any preceding <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">
    RewriteCond</a></code> directives match). This can be thought of as a
    <code>goto</code> statement in your rewrite ruleset. In the following
    example, we only want to run the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">
    RewriteRule</a></code> if the requested URI doesn't correspond with an
    actual file.</p>
    
    <pre class="prettyprint lang-config"># Is the request for a non-existent file?
    RewriteCond "%{REQUEST_FILENAME}" !-f
    RewriteCond "%{REQUEST_FILENAME}" !-d
    # If so, skip these two RewriteRules
    RewriteRule ".?"                  "-" [S=2]
    
    RewriteRule "(.*\.gif)"           "images.php?$1"
    RewriteRule "(.*\.html)"          "docs.php?$1"</pre>
    
    
    <p>This technique is useful because a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> only applies to the
    <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> immediately
    following it. Thus, if you want to make a <code>RewriteCond</code> apply
    to several <code>RewriteRule</code>s, one possible technique is to
    negate those conditions and add a <code>RewriteRule</code> with a [Skip] flag. You can
    use this to make pseudo if-then-else constructs: The last rule of
    the then-clause becomes <code>skip=N</code>, where N is the
    number of rules in the else-clause:</p>
    <pre class="prettyprint lang-config"># Does the file exist?
    RewriteCond "%{REQUEST_FILENAME}" !-f
    RewriteCond "%{REQUEST_FILENAME}" !-d
    # Create an if-then-else construct by skipping 3 lines if we meant to go to the "else" stanza.
    RewriteRule ".?"                  "-" [S=3]
    
    # IF the file exists, then:
        RewriteRule "(.*\.gif)"  "images.php?$1"
        RewriteRule "(.*\.html)" "docs.php?$1"
        # Skip past the "else" stanza.
        RewriteRule ".?"         "-" [S=1]
    # ELSE...
        RewriteRule "(.*)"       "404.php?file=$1"
    # END</pre>
    
    
    <p>It is probably easier to accomplish this kind of configuration using
    the <code class="directive">&lt;If&gt;</code>, <code class="directive">&lt;ElseIf&gt;</code>, and <code class="directive">&lt;Else&gt;</code> directives instead.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_t" id="flag_t">T|type</a></h2>
    <p>Sets the MIME type with which the resulting response will be
    sent. This has the same effect as the <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code> directive.</p>
    
    <p>For example, you might use the following technique to serve Perl
    source code as plain text, if requested in a particular way:</p>
    
    <pre class="prettyprint lang-config"># Serve .pl files as plain text
    RewriteRule "\.pl$"  "-" [T=text/plain]</pre>
    
    
    <p>Or, perhaps, if you have a camera that produces jpeg images without
    file extensions, you could force those images to be served with the
    correct MIME type by virtue of their file names:</p>
    
    <pre class="prettyprint lang-config"># Files with 'IMG' in the name are jpg images.
    RewriteRule "IMG"  "-" [T=image/jpg]</pre>
    
    
    <p>Please note that this is a trivial example, and could be better done
    using <code class="directive"><a href="../mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>
    instead. Always consider the alternate
    solutions to a problem before resorting to rewrite, which will
    invariably be a less efficient solution than the alternatives.</p>
    
    <p>
    If used in per-directory context, use only <code>-</code> (dash)
    as the substitution <em>for the entire round of mod_rewrite processing</em>,
    otherwise the MIME-type set with this flag is lost due to an internal
    re-processing (including subsequent rounds of mod_rewrite processing).
    The <code>L</code> flag can be useful in this context to end the
    <em>current</em> round of mod_rewrite processing.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_unsafe_allow_3f" id="flag_unsafe_allow_3f">UnsafeAllow3F</a></h2>
        <p> Setting this flag is required to allow a rewrite to continue If the
        HTTP request being written has an encoded question mark, '%3f', and the
        rewritten result has a '?' in the substiution.  This protects from a malicious
        URL taking advantage of a capture and re-substitution of the encoded
        question mark.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_unsafe_prefix_stat" id="flag_unsafe_prefix_stat">UnsafePrefixStat</a></h2>
        <p> Setting this flag is required in server-scoped substitutions
        start with a variable or backreference and resolve to a filesystem path.
        These substitutions are not prefixed with the document root.
        This protects from a malicious URL causing the expanded substitution to
        map to an unexpected filesystem location.</p>
    
        <p>Available in Apache HTTP Server 2.4.60 and later.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_unc" id="flag_unc">UNC</a></h2>
        <p> Setting this flag prevents the merging of multiple leading slashes,
        as used in Windows UNC paths.  The flag is not necessary when the rules
        substitution starts with multiple literal slashes.</p>
    
        <p>Available in Apache HTTP Server 2.4.62 and later.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/flags.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/flags.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/flags.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/proxy.html.en������������������������������������������������������0000664�0001751�0001751�00000016754�14737241666�021215� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Using mod_rewrite for Proxying - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Using mod_rewrite for Proxying</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/proxy.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/proxy.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
    how to use the RewriteRule's [P] flag to proxy content to another server.
    A number of recipes are provided that describe common scenarios.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dynamic-proxy" id="dynamic-proxy">Proxying Content with mod_rewrite</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
        <p>
        mod_rewrite provides the [P] flag, which allows URLs to be passed,
        via mod_proxy, to another server. Two examples are given here. In
        one example, a URL is passed directly to another server, and served
        as though it were a local URL. In the other example, we proxy
        missing content to a back-end server.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>To simply map a URL to another server, we use the [P] flag, as
          follows:</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteBase    "/products/"
    RewriteRule    "^widget/(.*)$"  "http://product.example.com/widget/$1"  [P]
    ProxyPassReverse "/products/widget/" "http://product.example.com/widget/"</pre>
    
    
       <p>In the second example, we proxy the request only if we can't find
       the resource locally. This can be very useful when you're migrating
       from one server to another, and you're not sure if all the content
       has been migrated yet.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{REQUEST_FILENAME}"       !-f
    RewriteCond "%{REQUEST_FILENAME}"       !-d
    RewriteRule "^/(.*)" "http://old.example.com/$1" [P]
    ProxyPassReverse "/" "http://old.example.com/"</pre>
    
        </dd>
    
        <dt>Discussion:</dt>
    
        <dd><p>In each case, we add a <code class="directive"><a href="../mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> directive to ensure
        that any redirects issued by the backend are correctly passed on to
        the client.</p>
    
        <p>Consider using either <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> or <code class="directive"><a href="../mod/mod_proxy.html#proxypassmatch">ProxyPassMatch</a></code> whenever possible in
        preference to mod_rewrite.</p>
        </dd>
      </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/proxy.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/proxy.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/proxy.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������httpd-2.4.64/docs/manual/rewrite/vhosts.html.en�����������������������������������������������������0000664�0001751�0001751�00000030246�14737241666�021352� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Dynamic mass virtual hosts with mod_rewrite - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Dynamic mass virtual hosts with mod_rewrite</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/vhosts.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/vhosts.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
    how you can use <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> to create dynamically
    configured virtual hosts.</p>
    
    <div class="warning">mod_rewrite is not the best way to configure
    virtual hosts. You should first consider the <a href="../vhosts/mass.html">alternatives</a> before resorting to
    mod_rewrite. See also the "<a href="avoid.html#vhosts">how to avoid
    mod_rewrite</a> document.</div>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#per-hostname">Virtual Hosts For Arbitrary Hostnames</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple.rewrite">Dynamic
        Virtual Hosts Using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#xtra-conf">Using a Separate Virtual Host Configuration File</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="per-hostname" id="per-hostname">Virtual Hosts For Arbitrary Hostnames</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
        <p>We want to automatically create a virtual host for every hostname
        which resolves in our domain, without having to create
        new VirtualHost sections.</p>
    
        <p>In this recipe, we assume that we'll be using the hostname
        <code>www.<strong>SITE</strong>.example.com</code> for each
        user, and serve their content out of
        <code>/home/<strong>SITE</strong>/www</code>.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    
    RewriteMap    lowercase int:tolower
    
    RewriteCond   "${lowercase:%{<strong>HTTP_HOST</strong>}}"   "^www\.<strong>([^.]+)</strong>\.example\.com$"
    RewriteRule   "^(.*)" "/home/<strong>%1</strong>/www$1"</pre>
    </dd>
    
    <dt>Discussion</dt>
        <dd>
    
        <div class="warning">You will need to take care of the DNS
        resolution - Apache does
        not handle name resolution. You'll need either to create CNAME
        records for each hostname, or a DNS wildcard record. Creating DNS
        records is beyond the scope of this document.</div>
    
    <p>The internal <code>tolower</code> RewriteMap directive is used to
    ensure that the hostnames being used are all lowercase, so that there is
    no ambiguity in the directory structure which must be created.</p>
    
    <p>Parentheses used in a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> are captured into the
    backreferences <code>%1</code>, <code>%2</code>, etc, while parentheses
    used in <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> are
    captured into the backreferences <code>$1</code>, <code>$2</code>,
    etc.</p>
    
    <p>
    As with many techniques discussed in this document, mod_rewrite really
    isn't the best way to accomplish this task. You should, instead,
    consider using <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> instead, as it will much
    more gracefully handle anything beyond serving static files, such as any
    dynamic content, and Alias resolution.
    </p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple.rewrite" id="simple.rewrite">Dynamic
        Virtual Hosts Using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></a></h2>
    
        <p>This extract from <code>httpd.conf</code> does the same
        thing as <a href="#per-hostname">the first example</a>. The first
        half is very similar to the corresponding part above, except for
        some changes, required for backward compatibility and to make the
        <code>mod_rewrite</code> part work properly; the second half
        configures <code>mod_rewrite</code> to do the actual work.</p>
    
        <p>Because <code>mod_rewrite</code> runs before other URI translation
        modules (e.g., <code>mod_alias</code>), <code>mod_rewrite</code> must
        be told to explicitly ignore any URLs that would have been handled
        by those modules. And, because these rules would otherwise bypass
        any <code>ScriptAlias</code> directives, we must have
        <code>mod_rewrite</code> explicitly enact those mappings.</p>
    
    <pre class="prettyprint lang-config"># 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
    
    &lt;Directory "/www/hosts"&gt;
        # ExecCGI is needed here because we can't force
        # CGI execution in the way that ScriptAlias does
        Options FollowSymLinks ExecCGI
    &lt;/Directory&gt;
    
    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 handler
    RewriteCond  "%{REQUEST_URI}"  "^/cgi-bin/"
    RewriteRule  "^/(.*)$"  "/www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1"  [H=cgi-script]</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="xtra-conf" id="xtra-conf">Using a Separate Virtual Host Configuration File</a></h2>
    
        <p>This arrangement uses more advanced <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
        features to work out the translation from virtual host to document
        root, from a separate configuration file. This provides more
        flexibility, but requires more complicated configuration.</p>
    
        <p>The <code>vhost.map</code> file should look something like
        this:</p>
    
    <div class="example"><p><code>
    customer-1.example.com  /www/customers/1<br />
    customer-2.example.com  /www/customers/2<br />
    # ...<br />
    customer-N.example.com  /www/customers/N<br />
    </code></p></div>
    
        <p>The <code>httpd.conf</code> should contain the following:</p>
    
    <pre class="prettyprint lang-config">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  "^/cgi-bin/(.*)$"                      "%1/cgi-bin/$1" [H=cgi-script]</pre>
    
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/vhosts.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/vhosts.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/vhosts.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/remapping.html�����������������������������������������������������0000664�0001751�0001751�00000000321�13710016232�021347� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: remapping.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: remapping.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/proxy.html���������������������������������������������������������0000664�0001751�0001751�00000000311�13710016232�020545� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: proxy.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: proxy.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/avoid.html���������������������������������������������������������0000664�0001751�0001751�00000000311�13710016232�020466� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: avoid.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: avoid.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/intro.html���������������������������������������������������������0000664�0001751�0001751�00000000311�13710016232�020517� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: intro.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: intro.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/tech.html����������������������������������������������������������0000664�0001751�0001751�00000000307�13710016232�020314� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: tech.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: tech.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/index.html.zh-cn.utf8����������������������������������������������0000664�0001751�0001751�00000014344�14743132254�022423� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache mod_rewrite - Apache HTTP 服务器 版本 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="../">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache mod_rewrite</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
        <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 提供了基于<a href="intro.html#regex">正则表达式</a>规则动态修改传入的请求的 URL 的方法。
        这允许你以自己喜欢的任意方法映射任意 URL 到你的内部 URL 结构。</p>
    
        <p>它支持无限的规则,以及为每个规则附加条件,从而提供了一个真正灵活且强大的 URL
        操作机制。URL 操作可以依赖于各种测试,例如服务器变量,环境变量,HTTP
        头,时戳,甚至外部数据库查询等,以便完成 URL 单元匹配。</p>
    
        <p>这个模块在服务器上下文 (<code>httpd.conf</code>),虚拟主机上下文 (<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 指令块),目录上下文
        (<code>.htaccess</code> 文件和 <code>&lt;Directory&gt;</code>
        指令块) 对完整的 URL (包含目录信息部分和查询字符串部分) 操作。
        重写结果可以导致新的规则处理,内部的后续处理,外部请求重定向,甚至透过内部代理,
        这取决于你为规则附加的<a href="flags.html">标志</a>。</p>
    
        <p>既然 mod_rewrite 这么强大,它当然是相当复杂。这篇文档作为<a href="../mod/mod_rewrite.html">参考手册</a>的补充,试图减轻一些复杂性,
        提供你可能使用 mod_rewrite 的常见场景的有充分注释的例子。
        但是,我们也试图告诉你,在什么时候你不应当使用 mod_rewrite,
        可以使用其它标准的 Apache 特性来达到目的,以避免无谓的复杂性。</p>
    
    <ul>
    <li><a href="../mod/mod_rewrite.html">mod_rewrite 参考手册</a></li>
    <li><a href="intro.html">正则表达式与 mod_rewrite 入门</a></li>
    <li><a href="remapping.html">使用 mod_rewrite 重定向和重新映射 URL</a></li>
    <li><a href="access.html">使用 mod_rewrite 控制访问</a></li>
    <li><a href="vhosts.html">动态虚拟主机与 mod_rewrite</a></li>
    <li><a href="proxy.html">动态代理与 mod_rewrite</a></li>
    <li><a href="rewritemap.html">使用 RewriteMap</a></li>
    <li><a href="advanced.html">高级技术与诀窍</a></li>
    <li><a href="avoid.html">何时 <strong>不要</strong>使用 mod_rewrite</a></li>
    <li><a href="flags.html">RewriteRule 标志</a></li>
    <li><a href="tech.html">技术细节</a></li>
    </ul>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>参见</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">mod_rewrite 参考手册</a></li><li><a href="../urlmapping.html">从 URL 映射到文件系统</a></li><li><a href="http://wiki.apache.org/httpd/Rewrite">mod_rewrite
    wiki</a></li><li><a href="../glossary.html">术语</a></li></ul></div>
    </div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/index.html.tr.utf8�������������������������������������������������0000664�0001751�0001751�00000015543�14743132254�022033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache mod_rewrite - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="../">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache mod_rewrite</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> modülü gelen URL isteklerinde değişiklik
          yapabilmek için <a href="intro.html#regex">düzenli ifade</a> kurallarına
          dayalı, devingen bir yol sunar. Böylece, keyfi URL'leri dahili URL
          yapınızla kolayca eşleyebilirsiniz.</p>
    
        <p>Gerçekten esnek ve güçlü bir URL kurgulama mekanizması oluşturmak için
          sınısız sayıda kural ve her kural için de sınırsız sayıda koşul destekler.
          URL değişiklikleri çeşitli sınamalara dayanır; sunucu değişkenleri, HTTP
          başlıkları, ortam değişkenleri, zaman damgaları hatta çeşitli biçimlerde
          harici veritabanı sorguları bile bu amaçla kullanılabilir.</p>
    
        <p>Yeniden yazma kuralları URL’lerin tamamında (path-info kısmı ve sorgu
          dizgesi dahil) hem sunucu bağlamında (<code>httpd.conf</code>) hem sanal
          konaklar bağlamında (<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> bölümleri), hem de dizin bağlamında
          (<code>.htaccess</code> dosyaları ve <code>&lt;Directory&gt;</code>
          bölümleri) çalışır ve URL üzerinde sorgu dizgesi bölümleri bile
          oluşturabilir. Kurallara atadığınız <a href="flags.html">seçeneklere</a>
          bağlı olarak, yeniden yazılan URL sonuçta dahili işlemlerde, harici
          yönlendirmelerde ve vekalet işlemlerinde kullanılabilir.</p>
    
        <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> modülü çok güçlü olduğundan, gerçekten çok
          karmaşık olabilir. Bu belge, <a href="../mod/mod_rewrite.html">başvuru
          belgeleri</a>nin tamamlayıcısı olup karmaşıklığı biraz azaltmaya çalışır
          ve <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> ile elde edilebilen ortak senaryoların
          oldukça açıklamalı örneklerini sağlar. Fakat ayrıca,
          <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> modülünü kullanmamanız, yerine standart
          Apache özelliklerini kullanmanız gereken durumları da göstermeye,
          böylece gereksiz karmaşıklıktan kurtulmanızı sağlamaya çalıştık.</p>
    
    <ul>
    <li><a href="../mod/mod_rewrite.html">mod_rewrite başvuru belgesi</a></li>
    <li><a href="intro.html">mod_rewrite ve düzenli ifadelere giriş</a></li>
    <li><a href="remapping.html">URL yönlendirme ve yeniden eşlemede mod_rewrite kullanımı</a></li>
    <li><a href="access.html">Erişimi denetlemekte mod_rewrite kullanımı</a></li>
    <li><a href="vhosts.html">mod_rewrite ile devingen sanal konaklar</a></li>
    <li><a href="proxy.html">mod_rewrite ile devingen vekalet</a></li>
    <li><a href="rewritemap.html">RewriteMap kullanımı</a></li>
    <li><a href="advanced.html">İleri teknikler</a></li>
    <li><a href="avoid.html">mod_rewrite ne zaman kullanıl<strong>maMA</strong>lı</a></li>
    <li><a href="flags.html">RewriteRule seçenekleri</a></li>
    <li><a href="tech.html">Teknik ayrıntılar</a></li>
    </ul>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">mod_rewrite başvuru belgesi</a>
    </li><li><a href="../urlmapping.html">URL’lerin Dosya Sistemine Eşlenmesi</a></li><li><a href="http://wiki.apache.org/httpd/Rewrite">mod_rewrite wiki</a>
    </li><li><a href="../glossary.html">Terimler</a></li></ul></div>
    </div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="../mod/">Modüller</a> | <a href="../mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="../glossary.html">Terimler</a> | <a href="../sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/vhosts.html��������������������������������������������������������0000664�0001751�0001751�00000000313�13710016232�020714� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: vhosts.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: vhosts.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/access.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000035560�14740503670�022151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Utiliser mod_rewrite pour le contrôle d'accès - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Utiliser mod_rewrite pour le contrôle d'accès</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/access.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/access.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document est un complément à la <a href="../mod/mod_rewrite.html">documentation de référence</a> de
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il explique comment utiliser
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour contrôler l'accès à diverses
    ressources, ainsi que d'autres techniques en rapport. Il contient de
    nombreux exemples d'utilisation courante de mod_rewrite avec une
    description détaillée de leur fonctionnement.</p>
    
    <div class="warning">Vous devez vous attacher à comprendre le
    fonctionnement des exemples, car la plupart d'entre eux ne
    fonctionneront pas sur votre système si vous vous contentez de les
    copier/coller dans vos fichiers de configuration.</div>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#blocked-inline-images">Blocage du référencement à chaud (Hotlinking) d'images</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#blocking-of-robots">Blocage des robots</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#host-deny">Rejet des clients contenus dans une liste de proscrits</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#referer-deflector">Aiguillage basé sur l'en-tête Referer</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module mod_rewrite</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
    correspondance</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Serveurs mandataires</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="blocked-inline-images" id="blocked-inline-images">Blocage du référencement à chaud (Hotlinking) d'images</a></h2>
    
          
    
          <dl>
            <dt>Description :</dt>
    
            <dd>
              <p>Cette technique vous permet d'interdire à d'autres sites
    	  d'inclure directement vos images dans leurs pages. On fait
    	  souvent référence à cette pratique sous le nom de
    	  référencement à chaud (Hotlinking) qui entraîne l'utilisation
    	  de votre bande passante pour servir des contenus faisant
    	  partie du site de quelqu'un d'autre.</p>
            </dd>
    
            <dt>Solution :</dt>
    
            <dd>
    	<p>Cette technique repose sur la valeur de la variable
    	optionnelle <code>HTTP_REFERER</code>. Certaines personnes
    	pourront donc contourner cette limitation. Pour la plupart des
    	utilisateurs cependant, la requête échouera, en ce sens que
    	l'image ne sera pas affichée depuis le site tiers.</p>
    	<p>Il y a plusieurs manières de gérer cette situation.</p>
    
    	<p>Dans le premier exemple, nous rejetons tout simplement la
    	requête si elle ne provenait pas d'une page appartenant à notre
    	site. Pour les besoins de cet exemple, nous supposons que le nom
    	de votre site est <code>www.example.com</code>.</p>
    
    
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_REFERER}" "!^$"
    RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
    RewriteRule "\.(gif|jpg|png)$"    "-"   [F,NC]</pre>
    
    
    	<p>Dans le second exemple, plutôt que de rejeter la requête,
    	nous affichons une autre image à la place.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_REFERER}" "!^$"
    RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
    RewriteRule "\.(gif|jpg|png)$"    "/images/go-away.png"   [R,NC]</pre>
    
    
    	<p>Dans le troisième exemple, nous redirigeons la requête vers
    	une image appartenant à un autre site.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_REFERER}" "!^$"
    RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
    RewriteRule "\.(gif|jpg|png)$" "http://other.example.com/image.gif"   [R,NC]</pre>
    
    
    	<p>De tous ces exemples, les deux derniers semblent les plus
    	efficaces pour faire en sorte que les gens arrêtent de
    	référencer vos images à chaud, car il ne verront pas les images
    	qu'ils s'attendent à voir.</p>
    
            </dd>
    
            <dt>Discussion :</dt>
    
            <dd>
            <p>Si vous ne voulez pas rediriger la requête, mais
    	simplement interdire l'accès à la ressource, vous pouvez y
    	parvenir sans utiliser mod_rewrite :</p>
    
            <pre class="prettyprint lang-config">SetEnvIf Referer "example\.com" localreferer
    &lt;FilesMatch "\.(jpg|png|gif)$"&gt;
        Require env localreferer
    &lt;/FilesMatch&gt;</pre>
    
            </dd>
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="blocking-of-robots" id="blocking-of-robots">Blocage des robots</a></h2>
    
          
    
          <dl>
            <dt>Description :</dt>
    
            <dd>
            <p>
            Dans cet exemple, nous allons discuter d'une méthode permettant
    	de bloquer les requêtes persistentes en provenance d'un robot
    	particulier, ou d'un navigateur.</p>
    
            <p>La méthode classique pour exclure un robot consiste à définir
    	un fichier, <code>/robots.txt</code> qui spécifie les parties de
    	votre site web pour lesquelles vous voulez exclure les robots.
    	Malheureusement, certains robots ne tiennent pas compte de ces
    	fichiers.
            </p>
    
            <p>Notez qu'il existe des méthodes d'exclusion qui n'utilisent
    	pas mod_rewrite. Notez aussi que toute technique qui repose sur
    	le contenu de la chaîne client <code>USER_AGENT</code> peut être
    	contournée très facilement car cette chaîne peut être modifiée.</p>
            </dd>
    
            <dt>Solution :</dt>
    
            <dd>
            <p>On utilise un jeu de règles qui spécifie le répertoire à
    	protéger, ainsi que la chaîne client <code>USER_AGENT</code> qui
    	identifie le robot malin ou envahissant.</p>
    
            <p>Dans cet exemple, nous bloquons un robot nommé
    	<code>Vilain_Robot</code> pour le répertoire
    	<code>/secret/fichiers</code>. Si vous voulez bloquer ce client
    	seulement depuis une source particulière, vous pouvez aussi
    	spécifier un intervalle d'adresses IP.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_USER_AGENT}"   "^NameOfBadRobot"
    RewriteCond "%{REMOTE_ADDR}"       "=123\.45\.67\.[8-9]"
    RewriteRule "^/secret/files/"   "-"   [F]</pre>
    
            </dd>
    
          <dt>Discussion :</dt>
    
          <dd>
          <p>
            Vous pouvez cependant parvenir au même résultat sans utiliser
    	mod_rewrite via la méthode alternative suivante :
          </p>
          <pre class="prettyprint lang-config">SetEnvIfNoCase User-Agent "^NameOfBadRobot" goaway
    &lt;Location "/secret/files"&gt;
        &lt;RequireAll&gt;
            Require all granted
            Require not env goaway
        &lt;/RequireAll&gt;
    &lt;/Location&gt;</pre>
    
          <p>
          Comme indiqué plus haut, il est aisé de contourner cette
          technique, simplement en modifiant le contenu de l'en-tête
          <code>USER_AGENT</code>. Si vous subissez une attaque en règle,
          vous allez devoir réfléchir à un blocage à un niveau supérieur,
          par exemple une règle de filtrage de votre pare-feu.
          </p>
    
          </dd>
    
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="host-deny" id="host-deny">Rejet des clients contenus dans une liste de proscrits</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Nous voulons interdire l'accès à notre serveur aux clients
          contenus dans une liste de proscrits similaire à
          <code>hosts.deny</code>.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteMap    hosts-deny  "txt:/path/to/hosts.deny"
    RewriteCond   "${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}" "!=NOT-FOUND" [OR]
    RewriteCond   "${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}" "!=NOT-FOUND"
    RewriteRule   "^"  "-"  [F]</pre>
    
    
    <div class="example"><p><code>
    ##<br />
    ##  hosts.deny<br />
    ##<br />
    ##  ATTENTION! Ceci est une table de correspondances, non une liste,<br />
    ##		même si elle est traitée comme telle. mod_rewrite<br />
    ##		l'interprète comme une liste de paires clé/valeur, et<br />
    ##		chaque entrée doit au moins posséder une valeur par<br />
    ##		défaut "-".<br />
    <br />
    193.102.180.41 -<br />
    bsdti1.sdm.de  -<br />
    192.76.162.40  -<br />
    </code></p></div>
        </dd>
    
        <dt>Discussion :</dt>
        <dd>
        <p>
        La seconde condition RewriteCond présuppose que HostNameLookups est
        défini à On, de façon à ce que les adresses IP des clients puissent
        être résolues. Dans le cas contraire, vous devez supprimer la
        seconde condition, ainsi que le drapeau <code>[OR]</code> de la
        première.
        </p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="referer-deflector" id="referer-deflector">Aiguillage basé sur l'en-tête Referer</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Redirige les requêtes en fonction du Referer de provenance de
          la requête, avec des cibles différentes pour chaque Referer.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
      <p>Le jeu de règles suivant utilise un fichier de correspondances pour
      associer chaque Referer à une cible de redirection.</p>
    
    <pre class="prettyprint lang-config">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]</pre>
    
    
          <p>Le fichier de correspondances contient les cibles de
          redirection associées à chaque Referer, ou, si nous voulons
          simplement rediriger les requêtes vers leur Referer, un "-" est
          inscrit dans le fichier de correspondances :</p>
    
    <pre class="prettyprint lang-config">##
    ##  deflector.map
    ##
    
    http://badguys.example.com/bad/index.html    -
    http://badguys.example.com/bad/index2.html   -
    http://badguys.example.com/bad/index3.html   http://somewhere.example.com/</pre>
    
    
        </dd>
      </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/access.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/access.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/access.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/htaccess.html.fr.utf8����������������������������������������������0000664�0001751�0001751�00000013206�14740503670�022476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>mod_rewrite et les fichiers .htaccess - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>mod_rewrite et les fichiers .htaccess</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/htaccess.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document est un complément de la <a href="../mod/mod_rewrite.html">documentation de référence</a> du module
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il décrit les changements apportés aux règles
    lorsqu'on utilise mod_rewrite dans les fichiers .htaccess, et comment
    travailler avec ces changements.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module mod_rewrite</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
    correspondance</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Serveurs mandataires</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    </div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/htaccess.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/htaccess.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/avoid.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000042122�14740503670�022002� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Quand ne pas utiliser mod_rewrite - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Quand ne pas utiliser mod_rewrite</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/avoid.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/avoid.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document est un complément à la <a href="../mod/mod_rewrite.html">Documentation de référence</a> de
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il décrit peut-être un des concepts les
    plus importants à propos de <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> - à savoir, quand doit-on éviter
    de l'utiliser.</p>
    
    <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> doit être considéré comme un dernier recours,
    lorsqu'aucune alternative n'est possible. Utiliser mod_rewrite lorsqu'il
    existe des alternatives plus simples conduit à des configurations
    confuses, fragiles, et difficiles à maintenir. La compréhension des
    autres alternatives disponibles est une étape très importante sur le
    chemin de la maîtrise de <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    <p>Vous devez vous attacher à comprendre le
    fonctionnement des exemples, car la plupart d'entre eux ne
    fonctionneront pas sur votre système si vous vous contentez de les
    copier/coller dans vos fichiers de configuration.</p>
    
    <p>Le cas le plus courant dans lequel <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> est
    l'outil approprié est la situation où la seule solution envisageable
    nécessite l'accès aux fichiers de configuration du serveur, alors que
    cet accès ne vous est pas accordé. Certaines directives de configuration
    ne sont disponibles que dans le fichier de configuration du serveur. Si
    vous ne pouvez agir que sur les fichiers .htaccess, vous devrez donc
    vous tourner vers <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#redirect">Redirection simple</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#alias">Alias d'URL</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#vhosts">Hébergement virtuel</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#proxy">Mandat simple</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#setenv">Test de variables d'environnement</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module mod_rewrite</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
    correspondance</a></li><li><a href="access.html">Contrôle d'accès</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Serveurs mandataires</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">Redirection simple</a></h2>
    
    
    <p><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> fournit les directives <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code> et <code class="directive"><a href="../mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> qui permettent de
    rediriger une URL vers une autre. Plutôt que d'utiliser la directive
    <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> pour ce genre de
    redirection simple d'une URL ou d'une classe d'URLs vers une autre, on
    préfèrera l'utilisation de ces directives. En outre, avec
    <code>RedirectMatch</code>, vous pouvez inclure une expression
    rationnelle dans votre critère de redirection, ce qui vous permet de
    bénéficier de nombreux avantages de la directive
    <code>RewriteRule</code>.</p>
    
    <p>Une utilisation courante de la directive <code>RewriteRule</code> est
    la redirection de toute une classe d'URLs. Par exemple, toutes les URLs
    faisant référence au répertoire <code>/un</code> doivent être
    redirigées vers <code>http://un.example.com/</code>, ou toutes les
    requêtes <code>http</code> doivent être redirigées vers
    <code>https</code>.</p>
    
    <p>Pour ce faire, il est préférable d'utiliser la directive
    <code>Redirect</code>. Souvenez-vous que la directive
    <code>Redirect</code> conserve les informations relatives au chemin. En
    d'autres termes, la redirection d'une URL <code>/un</code> va aussi
    rediriger toutes les URLs de niveaux inférieurs comme
    <code>/un/deux.html</code> et <code>/un/trois/quatre.html</code>.</p>
    
    <p>Pour rediriger les URLs sous <code>/un</code> vers
    <code>http://un.example.com/</code>, utilisez cette définition :</p>
    
    <pre class="prettyprint lang-config">Redirect /one/ http://one.example.com/</pre>
    
    
    <p>Pour rediriger un nom d'hôte vers un autre nom d'hôte, par exemple
    <code>example.com</code> vers <code>www.example.com</code>, voir la
    méthode <a href="remapping.html#canonicalhost">Noms d'hôtes canoniques</a>.</p>
    
    <p>Pour rediriger les URLs <code>http</code> vers <code>https</code>,
    utilisez cette définition :</p>
    
    <pre class="prettyprint lang-config">&lt;VirtualHost *:80&gt;
    ServerName www.example.com
    Redirect "/" "https://www.example.com/"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:443&gt;
    ServerName www.example.com
    #  ... insérer ici la configuration SSL
    &lt;/VirtualHost&gt;</pre>
    
    
    <p>L'utilisation de la directive <code>RewriteRule</code> pour accomplir
    cette tâche peut se justifier s'il existe d'autres directives
    <code>RewriteRule</code> dans la même portée. En effet, lorsque des
    directives <code>Redirect</code> et <code>RewriteRule</code> se trouvent
    dans la même portée, les directives <code>RewriteRule</code> sont
    exécutées en premier, sans tenir compte de leur ordre d'apparition dans
    le fichier de configuration.</p>
    
    <p>Dans le cas de la redirection <em>http-vers-https</em>, l'utilisation
    de règles <code>RewriteRule</code> se justifie si vous n'avez pas accès
    au fichier de configuration principal, et devez donc accomplir cette
    tâche au sein d'un fichier <code>.htaccess</code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="alias" id="alias">Alias d'URL</a></h2>
    <p>La directive <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> permet
    de mettre en correspondance un URI avec un répertoire, ce dernier étant
    en général situé en dehors de l'arborescence définie par la directive
    <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>. Bien qu'il soit
    possible d'effectuer cette mise en correspondance avec
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>, il est préférable d'utiliser la directive
    <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> pour des raisons de simplicité
    et de performances.</p>
    
    <div class="example"><h3>Utilisation de la directive Alias</h3><pre class="prettyprint lang-config">Alias "/cats" "/var/www/virtualhosts/felines/htdocs"</pre>
    </div>
    
    <p>
    Pour effectuer cette mise en correspondance, <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    s'impose si vous n'avez pas accès aux fichiers de configuration du
    serveur. En effet, la directive Alias ne peut pas être utilisée dans un
    fichier <code>.htaccess</code>, mais seulement dans un contexte de
    serveur principal ou de serveur virtuel.
    </p>
    
    <p>En outre, vous pouvez arriver au même résultat avec les liens
    symboliques, pourvu que <code>Options FollowSymLinks</code> soit activé
    sur votre serveur.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="vhosts" id="vhosts">Hébergement virtuel</a></h2>
    <p>Bien qu'il soit possible de gérer les <a href="vhosts.html">serveurs
    virtuels avec mod_rewrite</a>, il s'agit rarement de la bonne méthode.
    Il est pratiquement toujours préférable de créer des blocs
    <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> individuels.
    Dans l'éventualité où vous devez gérer
    un grand nombre de serveurs virtuels, vous devez vous tourner vers
    <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> pour créer ces serveurs
    automatiquement.</p>
    
    <p>Il est aussi possible d'utiliser des modules comme <code class="module"><a href="../mod/mod_macro.html">mod_macro</a></code> pour
    créer un grand nombre de serveurs virtuels dynamiquement.</p>
    
    <p>L'utilisation de <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour la création de
    serveurs virtuels peut se révéler appropriée si votre service
    d'hébergement ne vous permet pas d'accéder aux fichiers de configuration
    du serveur, et que vous soyez par conséquent obligé de passer par les
    fichiers <code>.htaccess</code>.</p>
    
    <p>Voir le document <a href="vhosts.html">création de serveurs virtuels
    avec mod_rewrite</a> pour plus de détails sur la manière d'y parvenir si
    cela semble être tout de même la meilleure approche.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Mandat simple</a></h2>
    
    <p>La directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> fournit
    le drapeau <a href="flags.html#flag_p">[P]</a> qui permet de faire passer les URIs
    réécrits par <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^/?images(.*)" "http://serveur-images.local/images$1" [P]</pre>
    
    
    <p>Cependant, dans les nombreux cas où aucune correspondance au modèle
    n'est vraiment nécessaire, comme dans l'exemple ci-dessus, il est
    préférable d'utiliser la directive <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>. L'exemple précédent pourrait
    être remplacé par :</p>
    
    <pre class="prettyprint lang-config">ProxyPass "/images/" "http://serveur-images.local/images/"</pre>
    
    
    <p>Que vous utilisiez <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> ou <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>, vous devrez dans tous les cas
    utiliser aussi la directive <code class="directive"><a href="../mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> pour intercepter les
    redirections en provenance du serveur d'arrière-plan :</p>
    
    <pre class="prettyprint lang-config">ProxyPassReverse "/images/" "http://serveur-images.local/images/"</pre>
    
    
    <p>Vous devrez cependant tout de même utiliser <code>RewriteRule</code>
    lorsque d'autres <code>RewriteRule</code>s se trouvent dans la même portée,
    car elles agissent en général avant les directives
    <code>ProxyPass</code>, et peuvent ainsi les court-circuiter.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setenv" id="setenv">Test de variables d'environnement</a></h2>
    
    <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> est souvent utilisé pour effectuer une
    action en fonction de la présence ou de l'absence d'une variable
    d'environnement particulière ou d'un en-tête de requête, ce qui peut
    être accompli de manière plus efficace via la directive <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>.</p>
    
    <p>Considérons par exemple le scénario courant où la directive
    <code class="directive">RewriteRule</code> est utilisée pour forcer un nom
    d'hôte canonique, tel que <code>www.example.com</code> au lieu de
    <code>example.com</code>. Il est possible d'utiliser à la place la
    directive <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code> comme
    suit :</p>
    
    <pre class="prettyprint lang-config">&lt;If "req('Host') != 'www.example.com'"&gt;
        Redirect "/" "http://www.example.com"
    &lt;/If&gt;</pre>
    
    
    <p>On peut utiliser cette technique dans de nombreux scénarios courant
    pour remplacer <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour effectuer des actions
    en fonction d'en-têtes de requêtes ou de réponses, ou de variables
    d'environnement.</p>
    
    <p>Voir en particulier la <a href="../expr.html">documentation sur
    l'évaluation des expressions</a> pour une vue d'ensemble des types
    d'expressions que vous pouvez utiliser dans les sections <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>,
    ainsi que dans certaines directives.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/avoid.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/avoid.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/avoid.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/advanced.html.fr.utf8����������������������������������������������0000664�0001751�0001751�00000043172�14740503670�022453� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Advanced Techniques with mod_rewrite - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Advanced Techniques with mod_rewrite</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/advanced.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/advanced.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document complète la <a href="../mod/mod_rewrite.html">documentation de référence</a> du
        module <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il présente un certain nombre
        de techniques avancées quant à
        l'utilisation de mod_rewrite.</p>
    
    <div class="warning">Notez que la plupart des exemples ne fonctionneront
    pas en l'état dans la configuration particulière de votre serveur ; il
    est donc important de bien comprendre leur fonctionnement, plutôt que de
    simplement les copier/coller dans votre configuration.</div>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#sharding">Distribution de la charge entre plusieurs serveurs
      d'arrière-plan en fonction de l'adresse IP</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#on-the-fly-content">Régéneration de contenu à la volée</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#load-balancing">Répartition de charge</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#structuredhomedirs">Répertoires Home structurés</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#redirectanchors">Redirection des ancrages</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#time-dependent">Réécriture dépendant de l'heure</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#setenvvars">Définir des variables d'environnement en fonction de
          certaines parties de l'URL</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
    correspondance</a></li><li><a href="access.html">Contrôler l'accès</a></li><li><a href="vhosts.html">serveurs virtuels</a></li><li><a href="proxy.html">serveurs mandataires</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="sharding" id="sharding">Distribution de la charge entre plusieurs serveurs
      d'arrière-plan en fonction de l'adresse IP</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>La fragmentation ou "sharding" est une technique courante de
          distribution de la charge du serveur ou de l'espace de stockage.
          Quand on utilise cette méthode, un serveur frontal utilise l'URL
          pour répartir de manière appropriée les utilisateurs et objets
          entre différents serveurs d'arrière-plan.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>On maintient une table de correspondance entre utilisateurs et
          serveurs cibles dans des fichiers externes. Ces derniers se
          présentent comme suit :</p>
    
    <div class="example"><p><code>
    utilisateur1  serveur_physique_utilisateur1<br />
    utilisateur2  serveur_physique_utilisateur2<br />
    # etc ...
    </code></p></div>
    
      <p>Tout ceci est enregistré dans un fichier
      <code>correspondances-utilisateurs-serveurs</code>. Le but est de
      faire correspondre</p>
    
    <div class="example"><p><code>
    /u/utilisateur1/chemin
    </code></p></div>
    
      <p>avec</p>
    
    <div class="example"><p><code>
    http://serveur_physique_utilisateur1/u/utilisateur/chemin
    </code></p></div>
    
          <p>il n'est ainsi pas nécessaire que tous les chemins URL soient
          valides sur tous les serveurs physiques d'arrière-plan. Le jeu de
          règles suivant fait tout ceci pour nous, en s'appuyant sur les
          fichiers de correspondances, en supposant que serveur0 est un
          serveur par défaut qui sera utilisé lorsqu'un utilisateur ne
          possèdera pas d'entrée dans la table de correspondances :</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteMap    users-to-hosts      "txt:/path/to/map.users-to-hosts"
    RewriteRule   "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"</pre>
    
        </dd>
      </dl>
    
      <p>Voir la documentation de <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> et le <a href="./rewritemap.html">RewriteMap HowTo</a> pour une description plus
      approfondie de la syntaxe de cette directive.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="on-the-fly-content" id="on-the-fly-content">Régéneration de contenu à la volée</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Nous voulons générer du contenu de manière dynamique, mais le
          conserver de manière statique lorsqu'il a été généré. La règle
          suivante vérifie l'existence du fichier statique, et le génère
          s'il est absent. Les fichiers statiques peuvent être supprimés
          périodiquement si on le désire (par exemple via cron), et seront
          régénérés à la demande.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          A cet effet, on utilise le jeu de règles suivant :
    
    <pre class="prettyprint lang-config"># Cet exemple n'est valable que dans un contexte de répertoire
    RewriteCond "%{REQUEST_URI}"   "!-U"
    RewriteRule "^(.+)\.html$"     "/regenerate_page.cgi"   [PT,L]</pre>
    
    
          <p>L'opérateur <code>-U</code> permet de déterminer si la chaîne
          de test (dans ce cas <code>REQUEST_URI</code>) est une URL valide.
          Pour ce faire, il utilise une sous-requête. Si cette sous-requête
          échoue, ou en d'autres termes, si la ressource demandée n'existe pas,
          cette règle invoque le programme CGI
          <code>/regenerate_page.cgi</code> qui génère la ressource
          demandée et la sauvegarde dans le répertoire des documents, de
          façon à ce qu'une copie statique puisse être servie lors d'une
          demande ultérieure.</p>
    
        <p>De cette façon, les documents qui ne sont pas mis à jour
        régulièrement peuvent être servis sous une forme statique. Si ces
        documents doivent être réactualisés, on peut les supprimer du
        répertoire des documents, et ils seront ainsi régénérés à la
        prochaine demande.</p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="load-balancing" id="load-balancing">Répartition de charge</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Nous voulons répartir la charge de manière aléatoire entre
          plusieurs serveurs en utilisant mod_rewrite.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>Pour y parvenir, nous allons utiliser la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> et une liste de
          serveurs.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteMap lb        "rnd:/path/to/serverlist.txt"
    RewriteRule "^/(.*)" "http://${lb:servers}/$1"     [P,L]</pre>
    
    
    <p><code>liste-serveurs.txt</code> contiendra la liste des serveurs :</p>
    
    <div class="example"><p><code>
    ## liste-serveurs.txt<br />
    <br />
    serveurs un.example.com|deux.example.com|trois.example.com<br />
    </code></p></div>
    
    <p>Si vous voulez qu'un serveur se voit confier d'avantage de charge que
    les autres, faites le figurer plusieurs fois dans la liste.</p>
    
       </dd>
    
       <dt>Discussion</dt>
       <dd>
    <p>Apache possède un module de répartition de charge -
    <code class="module"><a href="../mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> - beaucoup plus souple et présentant
    plus de fonctionnalités dans ce domaine que mod_rewrite.</p>
       </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="structuredhomedirs" id="structuredhomedirs">Répertoires Home structurés</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Certains sites avec des milliers d'utilisateurs organisent
    	  les répertoires utilisateurs de manière structurée, c'est à
    	  dire que chaque répertoire utilisateur se trouve dans un
    	  sous-répertoire dont le nom commence (par exemple) par le
    	  premier caractère du nom de l'utilisateur. Ainsi,
    	  <code>/~larry/chemin</code> correspond à
    	  <code>/home/<strong>l</strong>/larry/public_html/chemin</code>, alors
    	  que <code>/~waldo/chemin</code> correspond à
    	  <code>/home/<strong>w</strong>/waldo/public_html/chemin</code>.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>On utilise le jeu de règles suivant pour développer les
    	  URLs avec tilde selon l'organisation structurée précédente.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/~(<strong>([a-z])</strong>[a-z0-9]+)(.*)"  "/home/<strong>$2</strong>/$1/public_html$3"</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirectanchors" id="redirectanchors">Redirection des ancrages</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
        <p>Par défaut, la redirection vers un ancrage HTML ne fonctionne
    	pas, car mod_rewrite échappe le caractère <code>#</code> en le
    	transformant en <code>%23</code>, ce qui rend la redirection
    	inopérante.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>On utilise le drapeau <code>[NE]</code> dans la règle
    	  <code>RewriteRule</code>. NE signifie "No Escape".
          </p>
        </dd>
    
        <dt>Discussion :</dt>
        <dd>Cette technique fonctionne bien entendu pour tout autre
        caractère spécial que mod_rewrite, par défaut, code pour insertion
        dans une URL.</dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="time-dependent" id="time-dependent">Réécriture dépendant de l'heure</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Nous voulons servir des contenus différents selon l'heure du
          jour en utilisant mod_rewrite.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>Il existe de nombreuses variables nommées
    	  <code>TIME_xxx</code> utilisables dans les conditions de
    	  réécriture. Utilisées en conjonction avec les modèles de
    	  comparaison lexicographique spéciaux <code>&lt;STRING</code>,
    	  <code>&gt;STRING</code> et <code>=STRING</code>, elles
    	  permettent d'effectuer des redirections dépendant de
    	  l'heure :</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" "&gt;0700"
    RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" "&lt;1900"
    RewriteRule   "^foo\.html$"             "foo.day.html" [L]
    RewriteRule   "^foo\.html$"             "foo.night.html"</pre>
    
    
          <p>Avec cet exemple, l'URL <code>foo.html</code> renvoie
    	  le contenu de <code>foo.jour.html</code> durant le
    	  créneau horaire <code>07:01-18:59</code>, et le contenu de
    	  <code>foo.nuit.html</code> le reste du temps.</p>
    
          <div class="warning"><code class="module"><a href="../mod/mod_cache.html">mod_cache</a></code>, les mandataires
    	intermédiaires et les navigateurs peuvent chacun mettre en cache
    	les réponses et ainsi afficher une des deux pages en dehors de
    	la fenêtre de temps configurée. On peut utiliser
    	<code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> pour contourner ce problème. Il est
    	cependant bien plus commode de servir un contenu dynamique, et
    	de le personnaliser en fonction de l'heure du jour.</div> </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setenvvars" id="setenvvars">Définir des variables d'environnement en fonction de
          certaines parties de l'URL</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Nous voulons parfois conserver une certaine forme de statut
          lorsqu'une réécriture a eu lieu. Par exemple, vous souhaitez
          consigner le fait que cette réécriture a eu lieu, et vous servir
          plus tard de cette information pour déterminer si une requête était
          concernée par cette réécriture. Pour ce faire, on peut utiliser
          une variable d'environnement.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>Utiliser le drapeau [E] pour définir une variable
          d'environnement.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/cheval/(.*)"   "/poney/$1" [E=<strong>rewritten:1</strong>]</pre>
    
    
        <p>Plus loin dans votre jeu de règles, vous pouvez vérifier le
        contenu de cette variable d'environnement via une directive
        RewriteCond :</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{ENV:rewritten}" "=1"</pre>
    
    
        <p>Notez que les variables d'environnement ne survivent pas à une
        redirection externe. Vous devez alors utiliser le drapeau [CO] pour définir
        un cookie. Pour les redirections de niveau répertoire et htaccess où la
        substitution finale est traitée en tant que redirection interne, les
        variables d'environnement du tour de réécriture précédent sont préfixées par
        "REDIRECT_".</p>
    
        </dd>
      </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/advanced.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/advanced.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/advanced.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/flags.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000144167�14740503670�022010� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Les drapeaux de réécriture - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Les drapeaux de réécriture</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/flags.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/flags.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <p>Ce document décrit les drapeaux disponibles dans la directive
    <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>, en fournissant
    des explications détaillées et des exemples.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_b">B (échappement dans les références arrières)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_bnp">BNP|backrefnoplus (ne pas échapper
    l'espace en +)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_c">C|chain</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_co">CO|cookie</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_dpi">DPI|discardpath</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_e">E|env</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_end">END</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_f">F|forbidden</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_g">G|gone</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_h">H|handler</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_l">L|last</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_n">N|next</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_nc">NC|nocase</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_ne">NE|noescape</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_ns">NS|nosubreq</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_p">P|proxy</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_pt">PT|passthrough</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_qsa">QSA|qsappend</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_qsd">QSD|qsdiscard</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_qsl">QSL|qslast</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_r">R|redirect</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_s">S|skip</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_t">T|type</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_allow_3f">UnsafeAllow3F</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_prefix_stat">UnsafePrefixStat</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flag_unc">UNC</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection and remise en
    correspondance</a></li><li><a href="access.html">Contrôle d'accès</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Mise en cache</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    <p>Le comportement d'une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> peut être modifié par un ou
    plusieurs drapeaux. Les drapeaux sont situés en fin de règle, entourés
    de crochets, et séparés le cas échéant par des virgules.</p>
    <pre class="prettyprint lang-config">RewriteRule pattern target [Flag1,Flag2,Flag3]</pre>
    
    
    <p>Chaque drapeau (à quelques exceptions près)
    possède une forme courte, comme <code>CO</code>, ainsi qu'une forme longue,
    comme <code>cookie</code>. Bien que
    la forme courte soit la plus couramment utilisée, nous vous recommandons
    de vous familiariser avec les drapeaux sous leur forme longue, afin de
    bien mémoriser ce que chaque drapeau est supposé faire.
    Certains drapeaux acceptent un ou plusieurs arguments. Les drapeaux ne
    sont pas sensibles à la casse.</p>
    
    <p>Les drapeaux qui modifient les métadonnées associées à la requête
    (T=, H=, E=) n'ont aucun effet dans un contexte de répertoire ou de
    fichier htaccess, lorsqu'une substitution (autre que '-') est effectuée
    au cours de la même passe du processus de réécriture.
    </p>
    
    <p>Chaque drapeau disponible est présenté ici, avec un exemple
    d'utilisation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_b" id="flag_b">B (échappement dans les références arrières)</a></h2>
    <p>Avec le drapeau [B], la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> échappe les caractères
    non-alphanumériques avant d'appliquer la transformation.</p>
    
    <p><code>mod_rewrite</code> doit supprimer les séquences d'échappement
    des URLs avant leur
    mise en correspondance avec le système de fichiers ; les séquences
    d'échappement sont donc supprimées des références arrières au moment où
    ces dernières sont appliquées. Avec le drapeau B, les caractères
    non-alphanumériques des références arrières seront échappés. Considérons
    par exemple cette règle :</p>
    
    <p>Pour un échappement similaire des variables du serveur, voir la <a href="#mapfunc">fonction de mappage</a> "escape".
    </p>
    
    <pre class="prettyprint lang-config">RewriteRule "^search/(.*)$" "/search.php?term=$1"</pre>
    
    
    <p>Soit le terme de recherche 'x &amp; y/z' ; un navigateur va le coder
    en 'x%20%26%20y%2Fz', transformant la requête en
    'search/x%20%26%20y%2Fz'. Sans le drapeau B, cette règle de réécriture
    va réécrire la requête en 'search.php?term=x &amp; y/z', ce qui ne
    correspond pas à une URL valide et cette dernière sera encodée en
    <code>search.php?term=x%20&amp;y%2Fz=</code>, ce qui ne correspond pas à
    ce que l'on souhaitait.</p>
    
    <p>Avec le drapeau B, les paramètres sont réencodés avant d'être passés
    à l'URL résultante, ce qui fournit une réécriture correcte en
    <code>/search.php?term=x%20%26%20y%2Fz</code>.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^search/(.*)$" "/search.php?term=$1" [B,PT]</pre>
    
    
    <p>Notez que vous devrez peut-être aussi définir la
    directive <code class="directive"><a href="../mod/core.html#allowencodedslashes">AllowEncodedSlashes</a></code>
    à <code>On</code> pour
    que cet exemple particulier fonctionne, car httpd ne permet pas les
    slashes encodés dans les URLs, et renvoie une erreur 404 s'il en
    rencontre un.</p>
    
    <p>Ce processus d'échappement est en particulier nécessaire dans le
    contexte d'un mandataire, où l'accès au serveur d'arrière-plan échouera
    si on présente à ce dernier une URL non échappée.</p>
    
    <p>Une alternative à ce drapeau consiste à utiliser une directive
    <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> pour capturer
    %{THE_REQUEST}, les chaînes capturées se présentant
    alors sous la forme codée.</p>
    
    <p>A partir
    de la version 2.4.26, vous pouvez limiter l'échappement dans les
    références arrières à une liste de caractères que vous pouvez spécifiez comme
    dans cet exemple : <code>[B=#?;]</code>. Notez que l'espace peut faire
    partie de la liste des caractères à échapper, mais que vous devez mettre entre
    guillemets le troisième argument de la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> et que l'espace ne doit pas
    être le dernier caractère de cette liste.
    </p>
    
    <pre class="prettyprint lang-config"># Échappement des espaces et des points d'interrogation. Les guillemets autour
    # du dernier argument sont obligatoires lorsque l'espace est inclus.
    RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"</pre>
    
    
    <p>Pour définir la liste des caractères à échapper de cette manière, voir <a href="#flag_bne">#flag_bne</a> et <a href="#flag_bctls">#flag_bctls</a></p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_bnp" id="flag_bnp">BNP|backrefnoplus (ne pas échapper
    l'espace en +)</a></h2>
    <p>Si le drapeau [BNP] est spécifié, la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> échappera le caractère
    espace en %20 au lieu de '+' dans les références arrières. Ceci s'avère
    utile lorsque la référence arrière est utilisée dans la partie chemin,
    et non dans les paramètres de la requête.</p>
    
    <pre class="prettyprint lang-config"># Échappe le caractère espace en %20 dans le chemin au lieu de + comme dans la
    # soumission de formulaire à l'aide de la chaîne de paramètres
    RewriteRule "^search/(.*)$" "/search.php/$1" "[B,BNP]"</pre>
    
    
    <p>Ce drapeau est disponible à partir de la version 2.4.26 du serveur HTTP
    Apache.</p>
    
    <h3><a name="flag_bctls" id="flag_bctls">BCTLS</a></h3>
    <p>Le drapeau [BCTLS] est similaire à [B], à la différence que seuls les espaces
    et les caractères de contrôle sont échappés. Il s'agit du même jeu de caractères
    rejetés lorsqu'ils sont copiés dans la chaîne de paramètres non codée.
    </p>
    
    <pre class="prettyprint lang-config"># Échappe les espaces et les caractères de contrôle
    RewriteRule "^search/(.*)$" "/search.php/$1" "[BCTLS]"</pre>
    
    
    <p>Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP
    Apache.</p>
    
    
    
    <h3><a name="flag_bne" id="flag_bne">BNE</a></h3>
    <p>Les caractères listés dans [BNE=...] sont exclus des listes de caractères
    correspondant aux drapeaux [B] ou [BCTLS]. Ils ne seront donc pas échappés.
    </p>
    
    <pre class="prettyprint lang-config"># Échappe les caractères par défaut, sauf /
    RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B,BNE=/]"</pre>
    
     
    <p>Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP
    Apache.</p>
    
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_c" id="flag_c">C|chain</a></h2>
    <p>Le drapeau [C] ou [chain] indique que la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> est chaînée avec la
    suivante. Autrement dit, si la règle s'applique, elle est traitée
    normalement et passe le contrôle à la règle suivante. Par contre, si
    elle ne s'applique pas, la règle suivante, ainsi que toutes les règles
    chaînées qui suivent, seront sautées.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_co" id="flag_co">CO|cookie</a></h2>
    <p>Le drapeau [CO], ou [cookie], vous permet de définir un cookie
    lorsqu'une règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
    s'applique. Il possède trois arguments obligatoires et
    cinq arguments optionnels.</p>
    
    <p>La syntaxe complète de ce drapeau, avec tous ses attributs, est la
    suivante :</p>
    
    <div class="example"><p><code>
    [CO=NAME:VALUE:DOMAIN:lifetime:path:secure:httponly:samesite]
    </code></p></div>
    
    <p>Si un caractère littéral ':' doit être insérer dans un des champs du
    cookie, une autre syntaxe est disponible. Pour utiliser cette syntaxe
    alternative, le contenu du champ "Name" doit être précédé du caractère
    ';', et les sépateurs de champs deviendront des ';'.</p>
    
    <div class="example"><p><code>
    [CO=;NAME;VALUE:MOREVALUE;DOMAIN;lifetime;path;secure;httponly;samesite]
    </code></p></div>
    
    <p>Vous devez déclarer un nom, une valeur et un domaine pour que
    le cookie puisse être défini.</p>
    
    
    <dl>
    <dt>Domain</dt>
    <dd>Le domaine pour lequel vous souhaitez que le cookie soit valide. Ce
    peut être un nom de serveur, comme <code>www.example.com</code>, ou un
    domaine, comme <code>.example.com</code>. Il doit comporter au moins
    deux parties séparées par un point. C'est à dire que vous ne pouvez pas
    utiliser les valeurs <code>.com</code> ou <code>.net</code>. En effet,
    ce style de cookie est interdit par le modèle de sécurité des cookies.</dd>
    </dl>
    
    <p>Vous pouvez aussi définir les valeurs suivantes :</p>
    
    <dl>
    <dt>Lifetime</dt>
    <dd>La durée de vie du cookie, en minutes.</dd>
    <dd>Une valeur de 0 indique une durée de vie correspondant à la session
    courante du navigateur. Il s'agit de la valeur par défaut.</dd>
    
    <dt>Path</dt>
    <dd>Le chemin, sur le site web concerné, pour lequel le cookie est
    valide, du style <code>/clients/</code> or
    <code>/fichiers/telechargement/</code>.</dd>
    <dd>La valeur par défaut est <code>/</code> - c'est à dire l'ensemble du
    site web.</dd>
    
    <dt>Secure</dt>
    <dd>Si cet argument a pour valeur <code>secure</code>,
    <code>true</code>, ou <code>1</code>, le cookie ne pourra être transmis
    que dans le cadre d'une connexion sécurisée (https).</dd>
    
    <dt>httponly</dt>
    <dd>Si cet argument a pour valeur <code>HttpOnly</code>,
    <code>true</code>, ou <code>1</code>, le cookie aura son drapeau
    <code>HttpOnly</code> activé, ce qui signifie qu'il sera inaccessible au
    code JavaScript pour les navigateurs qui supportent cette
    fonctionnalité.</dd>
    
    <dt>samesite</dt>
    <dd>S'il est différent de <code>false</code> ou <code>0</code>, l'attribut
    <code>SameSite</code> est défini à la valeur spécifiée. Les valeurs typiques
    sont <code>None</code>, <code>Lax</code> et <code>Strict</code>. Disponible à
    partir de la version 2.4.47 du serveur HTTP Apache.</dd>
    </dl>
    
    <p>Voici un exemple :</p>
    
    <pre class="prettyprint lang-config">RewriteEngine On
    RewriteRule   "^/index\.html"   "-" [CO=frontdoor:yes:.example.com:1440:/]</pre>
    
    
    <p>Dans l'exemple ci-dessus, la règle ne réécrit
    pas la requête. La cible de réécriture "-"
    indique à mod_rewrite de transmettre la requête sans
    modification. Par contre, il
    définit un cookie nommé 'frontdoor' avec une valeur 'yes'. Le cookie est
    valide pour tout hôte situé dans le domaine <code>.example.org</code>. Sa
    durée de vie est limitée à 1440 minutes (24 heures), et il sera renvoyé
    pour tous les URIs.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_dpi" id="flag_dpi">DPI|discardpath</a></h2>
    <p>Avec le drapeau DPI, la partie PATH_INFO de l'URI
    réécrit est supprimée.</p>
    <p>Ce drapeau est disponible dans les versions 2.2.12 et supérieures.</p>
    <p>Dans un contexte de répertoire, l'URI mis en comparaison par chaque
    règle <code class="directive">RewriteRule</code> est la concaténation des
    valeurs courantes de l'URI et de PATH_INFO.</p>
    
    <p>L'URI courant peut être l'URI initial tel qu'il a été fourni par le
    client, le résultat d'une passe précédente du processus de réécriture,
    ou le résultat de la règle précédente dans le processus courant de
    réécriture.</p>
    
    <p>Par contre, la partie PATH_INFO ajoutée à l'URI avant chaque règle ne
    reflète que la valeur de PATH_INFO avant la passe courante du processus
    de réécriture. En conséquence, si de larges portions de l'URI
    correspondent et sont traduites via plusieurs directives
    <code class="directive">RewriteRule</code>, sans prendre en compte
    quelles parties de l'URI provenaient du PATH_INFO courant, l'URI final
    pourra se voir ajouter plusieurs copies de PATH_INFO.</p>
    
    <p>Utilisez ce drapeau pour toute substitution où la présence du PATH_INFO qui
    résultait de la mise en correspondance précédente de cette requête avec
    le système de fichier n'est pas nécessaire. Avec ce drapeau, le
    PATH_INFO établi avant que cette passe du processus de réécriture ne
    débute est oublié. PATH_INFO ne sera pas recalculé tant que la passe
    courante du processus de réécriture ne sera pas achevée. Les règles
    suivantes de cette passe ne verront que le résultat direct des
    substitutions, sans aucun PATH_INFO ajouté.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_e" id="flag_e">E|env</a></h2>
    <p>Avec le drapeau [E], ou [env], vous pouvez définir la valeur d'une
    variable d'environnement. Notez que certaines variables d'environnement
    peuvent être définies après le traitement de la règle, annulant par
    la-même ce que vous avez défini. Voir le <a href="../env.html">document
    sur les variables d'environnement</a> pour plus de détails sur le
    fonctionnement des variables d'environnement.</p>
    
    <p>La syntaxe complète pour ce drapeau est :</p>
    
    <pre class="prettyprint lang-config">[E=!VAR]</pre>
    
    
    <p><code>VAL</code> peut comporter des références arrières
    (<code>$N</code> ou <code>%N</code>) qui seront développées.</p>
    
    <p>En utilisant la version courte</p>
    
    <div class="example"><p><code>
    [E=VAR]
    </code></p></div>
    
    <p>vous pouvez définir la variable d'environnement nommée
    <code>VAR</code> avec une valeur vide.</p>
    
    <p>La forme</p>
    
    <div class="example"><p><code>
    [E=!VAR]
    </code></p></div>
    
    <p>permet d'annuler la définition de la variable <code>VAR</code>.</p>
    
    <p>Les variables d'environnement s'emploient dans différents contextes,
    comme les programmes CGI, d'autres directives RewriteRule, ou des
    directives CustomLog.</p>
    
    <p>L'exemple suivant définit une variable d'environnement nommée 'image'
    avec une valeur de '1' si l'URI de la requête correspond à un fichier
    image. Cette variable d'environnement est ensuite utilisée pour exclure
    une telle requête du journal des accès.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "\.(png|gif|jpg)$"   "-" [E=image:1]
    CustomLog   "logs/access_log"    combined env=!image</pre>
    
    
    <p>Notez que le même effet peut être obtenu à l'aide de la directive
    <code class="directive"><a href="../mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>. Cette technique
    est présentée à titre d'exemple et non de recommandation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_end" id="flag_end">END</a></h2>
    <p>L'utilisation du drapeau [END] permet non seulement de terminer le
    processus de réécriture en cours (comme [L]), mais aussi d'empêcher tout
    processus de réécriture ultérieur dans un contexte de répertoire
    (htaccess).</p>
    
    <p>Ceci ne s'applique pas aux nouvelles requêtes résultant d'une
    redirection externe.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_f" id="flag_f">F|forbidden</a></h2>
    <p>L'utilisation du drapeau [F] permet de faire envoyer par le serveur au
    client un code de statut "403 Forbidden". Le même effet peut être obtenu à
    l'aide de la directive <code class="directive"><a href="../mod/mod_access_compat.html#deny">Deny</a></code>,
    mais ce drapeau offre plus de souplesse dans l'attribution d'un statut
    Forbidden.</p>
    
    <p>La règle suivante va interdire la téléchargement de fichiers
    <code>.exe</code> depuis votre serveur.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "\.exe"   "-" [F]</pre>
    
    
    <p>Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce
    qui signifie que l'URI de la requête n'est pas modifié. Il n'y a aucune
    raison de réécrire un URI, si vous avez l'intention d'interdire la
    requête.</p>
    
    <p>Lorsqu'on utilise [F], [L] est implicite - c'est à dire que la
    réponse est renvoyée immédiatement, et aucune autre règle n'est évaluée.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_g" id="flag_g">G|gone</a></h2>
    <p>Le drapeau [G] permet de faire envoyer par le serveur un code de statut
    "410 Gone" avec la réponse. Ce code indique qu'une ressource qui était
    disponible auparavant ne l'est plus actuellement.</p>
    
    <p>Comme dans le cas du drapeau [F], on utilise en général la syntaxe
    "-" pour la cible de réécriture lorsqu'on utilise le drapeau [G] :</p>
    
    <pre class="prettyprint lang-config">RewriteRule "oldproduct"   "-" [G,NC]</pre>
    
    
    <p>Lorsqu'on utilise [G], [L] est implicite - c'est à dire que la
    réponse est renvoyée immédiatement, et aucune autre règle n'est évaluée.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_h" id="flag_h">H|handler</a></h2>
    <p>Force le traitement de la requête résultante par le gestionnaire
    spécifié. Par exemple, on peut utiliser ce drapeau pour forcer
    l'interprétation de tous les fichiers sans extension par le gestionnaire
    php :</p>
    
    <pre class="prettyprint lang-config">RewriteRule "!\."  "-" [H=application/x-httpd-php]</pre>
    
    
    <p>
    L'expression rationnelle ci-dessus - <code>!\.</code> - correspond à
    toute requête qui ne contient pas le caractère <code>.</code>.
    </p>
    <p>On peut aussi utiliser ce drapeau pour forcer l'utilisation d'un
    certain gestionnaire en fonction de certaines conditions. Par exemple,
    l'extrait suivant utilisé dans un contexte de niveau serveur permet de
    faire en sorte que les fichiers <code>.php</code> soient
    <em>affichés</em> par <code>mod_php</code> dans le cas où ils font
    l'objet d'une requête avec l'extension <code>.phps</code> :</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^(/source/.+\.php)s$" "$1" [H=application/x-httpd-php-source]</pre>
    
    
    
    <p>L'expression rationnelle ci-dessus -
    <code>^(/source/.+\.php)s$</code> - va correspondre à toute requête qui
    débutera par <code>/source/</code>, continuera par 1 ou n caractères
    puis par <code>.phps</code>. La référence arrière $1 fait référence à la
    correspondance capturée entre parenthèses de l'expression
    rationnelle.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_l" id="flag_l">L|last</a></h2>
    <p>Lorsque le drapeau [L] est présent, <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    arrête le traitement du jeu de règles. Cela signifie dans la plupart des
    situations que si la règle s'applique, aucune autre règle ne sera
    traitée. Ce drapeau correspond à la commande Perl <code>last</code>, ou
    à la commande <code>break</code> en C. Utilisez ce drapeau pour indiquer
    que la règle courante doit être appliquée immédiatement, sans tenir
    compte des règles ultérieures.</p>
    
    <p>Si vous utilisez des règles <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> dans des fichiers
    <code>.htaccess</code> ou des sections <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>, il est important d'avoir quelques
    notions sur la manière dont les règles sont traitées. Pour simplifier,
    une fois les règles traitées, la requête réécrite est passée à nouveau
    au moteur d'interprétation des URLs afin que ce dernier puisse la
    traiter. Il est possible qu'au cours du traitement de la requête
    réécrite, le fichier <code>.htaccess</code> ou la section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> soient à nouveau
    rencontrés, entraînant un nouveau traitement du jeu de règles depuis le
    début. Cette situation se présente le plus souvent lorsqu'une des règles
    provoque une redirection - interne ou externe - ce qui réinitialise le
    traitement de la requête.</p>
    
    <p>Si vous utilisez des directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> dans un de ces contextes,
    il importe par conséquent de prévoir explicitement des étapes permettant
    d'éviter un bouclage infini sur les règles,
    et de ne pas compter seulement sur
    le drapeau [L] pour terminer l'exécution d'une série de règles, comme
    décrit ci-dessous.</p>
    
    <p>Un autre drapeau, [END], permet non seulement d'interrompre le cycle
    courant du processus de réécriture, mais aussi d'empêcher toute
    réécriture ultérieure dans le contexte de répertoire (htaccess). Ceci ne
    s'applique pas aux nouvelles requêtes résultant de redirections
    externes.</p>
    
    <p>Dans l'exemple donné ici, toute requête est réécrite en
    <code>index.php</code>, la requête originale étant ajoutée comme chaîne
    de requête en argument à <code>index.php</code> ; cependant, la
    directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> permet de s'assurer que si
    la requête concerne déjà <code>index.php</code>, la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> sera sautée.</p>
    
    <pre class="prettyprint lang-config">RewriteBase "/"
    RewriteCond "%{REQUEST_URI}" !=/index.php
    RewriteRule "^(.*)"          "/index.php?req=$1" [L,PT]</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_n" id="flag_n">N|next</a></h2>
    <p>Le drapeau [N] provoque un redémarrage du traitement des règles
    depuis le début, en utilisant le résultat du jeu de règles, sous
    réserve qu'il existe un point de démarrage ; à utiliser avec précautions
    car il peut provoquer un bouclage infini.
    </p>
    <p>
    Le drapeau [Next] peut servir, par exemple,
    à remplacer de manière répétitive
    une chaîne de caractère ou une lettre dans une requête. Dans l'exemple
    suivant, chaque occurence de A sera remplacée par B dans la requête, et
    ceci jusqu'il n'y ait plus de A à remplacer.
    </p>
    
    <pre class="prettyprint lang-config">RewriteRule "(.*)A(.*)" "$1B$2" [N]</pre>
    
    
    <p>Vous pouvez vous représenter ce traitement comme une boucle
    <code>while</code> : tant que le modèle de la règle correspond (c'est à
    dire, tant que l'URI contient un <code>A</code>),
    effectuer la substitution (c'est à dire, remplacer le <code>A</code> par
    un <code>B</code>).</p>
    
    <p>A partir de la version 2.4.8, ce module renvoie une erreur après
    10000 itérations afin d'éviter les boucles infinies. Ce nombre maximum
    d'itération peut être modifié via le drapeau N.</p>
    <pre class="prettyprint lang-config"># On veut remplacer 1 caractère à chaque itération de la boucle
    RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=32000]
    # ... ou s'arrêter après 10 itérations
    RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=10]</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_nc" id="flag_nc">NC|nocase</a></h2>
    <p>Avec le drapeau [NC], le modèle de la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> est comparé à la requête de
    manière insensible à la casse. C'est à dire que cette comparaison
    s'effectue sans tenir compte des majuscules/minuscules dans l'URI
    comparé.</p>
    
    <p>Dans l'exemple suivant, toute requête pour un fichier image sera
    transmise par Apache à votre serveur d'images dédié. La correspondance est
    insensible à la casse, si bien que par exemple, <code>.jpg</code> aussi
    bien que <code>.JPG</code> seront acceptés.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "(.*\.(jpg|gif|png))$" "http://images.example.com$1" [P,NC]</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_ne" id="flag_ne">NE|noescape</a></h2>
    <p>Par défaut, les caractères spéciaux, comme <code>&amp;</code> et
    <code>?</code>, sont convertis en leur équivalent hexadécimal pour les règles
    qui génèrent des redirections externes. Le drapeau [NE] permet d'éviter cette
    conversion.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^/anchor/(.+)" "/bigpage.html#$1" [NE,R]</pre>
    
    
    <p>
    Dans l'exemple ci-dessus, <code>/anchor/xyz</code> est réécrit en
    <code>/bigpage.html#xyz</code>. En l'absence du drapeau [NE], le #
    aurait été converti en son équivalent hexadécimal, <code>%23</code>, ce
    qui aurait provoqué un code d'erreur "404 Not Found".
    </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_ns" id="flag_ns">NS|nosubreq</a></h2>
    <p>Le drapeau [NS] empêche la règle de s'appliquer aux sous-requêtes.
    Par exemple, une page incluse au moyen d'une SSI (Server
    Side Include) est une sous-requête, et vous ne voudrez probablement pas que
    la réécriture s'applique à ces sous-requêtes. Ainsi, lorsque
    <code class="module"><a href="../mod/mod_dir.html">mod_dir</a></code> recherche des informations à propos des
    fichiers par défaut du répertoire (comme les fichiers
    <code>index.html</code>), il s'agit d'une sous-requête interne, et vous
    ne désirez en général pas que ces sous-requêtes soient réécrites. Cette
    réécriture
    n'est pas toujours utile pour les sous-requêtes, et peut même causer des
    erreurs si l'ensemble du jeu de règles est appliqué. L'utilisation de
    ce drapeau permet d'exclure les règles qui peuvent poser problème.</p>
    
    <p>Comment déterminer si vous devez utiliser cette règle ou non : si
    vous préfixez les URLs avec des scripts CGI, afin de forcer leur
    traitement par le script CGI, vous vous exposez à des problèmes (ou du
    moins à une surcharge significative) avec les sous-requêtes. Dans ces
    cas, vous devez utiliser ce drapeau.</p>
    
    <p>
    Les images, scripts java, ou fichiers css, chargés en tant que partie
    d'une page html, ne sont pas des sous-requêtes - le navigateur les
    appelle sous forme de requêtes HTTP à part entière.
    </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_p" id="flag_p">P|proxy</a></h2>
    <p>L'utilisation du drapeau [P] entraîne le traitement de la requête par
    le module <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>, et ceci via une requête de
    mandataire. Par exemple, si vous voulez que toutes les requêtes d'images
    soient traitées par un serveur d'images annexe, vous pouvez utiliser
    une règle de ce style :</p>
    
    <pre class="prettyprint lang-config">RewriteRule "/(.*)\.(jpg|gif|png)$" "http://images.example.com/$1.$2" [P]</pre>
    
    
    <p>L'utilisation du drapeau [P] provoque aussi l'effet du drapeau [L] -
    autrement dit, la requête est immédiatement envoyée au mandataire, et
    toute règle ultérieure sera ignorée.</p>
    
    <p>
    Vous devez vous assurer que la chaîne de substitution soit un URI valide
    (commençant typiquement par <code>http://</code><em>nom-serveur</em>)
    qui puisse être traitée par le module <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>. Dans
    le cas contraire, le module mandataire vous renverra une erreur.
    L'utilisation de ce drapeau implémente de manière plus puissante la
    directive <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>, pour
    faire correspondre le contenu distant à l'espace de nommage du serveur
    local.</p>
    
    <div class="warning">
          <h3>Avertissement à propos de la sécurité</h3>
          <p>Lors de la construction de l'URL cible de la règle, il convient
          de prendre en compte l'impact en matière de sécurité qu'aura le
          fait de permettre au client d'influencer le jeu d'URLs pour
          lesquelles votre serveur agira en tant que mandataire.
          Assurez-vous que la partie protocole://nom-serveur de l'URL soit
          fixe, ou ne permette pas au client de l'influencer induement.</p>
    </div>
    
    <div class="warning">
          <h3>Avertissement au sujet des performances</h3> 
          <p>Utiliser ce drapeau fait intervenir <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> sans la
          gestion des connexions persistantes car dans ce cas, c'est le worker par
          défaut qui est utilisé, et ce dernier ne gère pas la mise en commun et la
          réutilisation des connexions.</p> 
          <p>Pour utiliser les connexions persistantes, vous devez définir un bloc
          <code class="directive"><a href="../mod/mod_proxy.html#proxy">Proxy</a></code>, au moins pour les parties
          protocole et hôte de l'URL cible, et contenant une directive <code class="directive"><a href="../mod/mod_proxy.html#proxyset">ProxySet</a></code> où vous définissez par exemple un
          délai.</p> 
          <p>Si vous le définissez avec une directive <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> ou <code class="directive"><a href="../mod/mod_proxy.html#proxypassmatch">ProxyPassMatch</a></code>, les connexions persistantes
          seront automatiquement utilisées.</p>
    </div>
    
    <p>Note: <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> doit être activé pour pouvoir
    utiliser ce drapeau.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_pt" id="flag_pt">PT|passthrough</a></h2>
    
    <p>
    Par défaut, la cible (ou chaîne de substitution) d'une règle
    RewriteRule est sensée être un chemin de fichier. Avec le drapeau [PT],
    par contre, elle est traitée comme un URI. Autrement dit, avec le
    drapeau [PT], le résultat de la règle  <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> est passé à nouveau au
    système de mise en correspondance des URLs avec le système de fichiers,
    de façon à ce que les systèmes de mise en correspondance basés sur les
    chemins de fichiers, comme la directive <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>, <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code>, ou <code class="directive"><a href="../mod/mod_alias.html#scriptalias">ScriptAlias</a></code>, par exemple, puissent avoir une
    chance d'accomplir leur tâche.
    </p>
    
    <p>
    Si par exemple, vous avez un <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> pour /icons, et une règle  <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> qui renvoie vers /icons,
    vous devez utiliser le drapeau [PT] pour être sûr que l'<code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> sera bien évalué.
    </p>
    
    <pre class="prettyprint lang-config">Alias "/icons" "/usr/local/apache/icons"
    RewriteRule "/pics/(.+)\.jpg$" "/icons/$1.gif" [PT]</pre>
    
    
    <p>
    Dans l'exemple précédent, en l'absence du drapeau [PT], l'Alias aurait
    été ignoré, ce qui aurait provoqué une erreur 'File not found'.
    </p>
    
    <p>Avec le drapeau <code>PT</code>, le drapeau <code>L</code> est
    implicite : la réécriture s'arrêtera afin de transmettre la requête à la
    phase suivante du traitement.</p>
    
    <p>Notez que le drapeau <code>PT</code> est implicite dans des contextes
    de répertoire comme les sections <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> ou les fichiers
    <code>.htaccess</code>. Le seul moyen de contourner ceci consiste à
    réécrire vers <code>-</code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_qsa" id="flag_qsa">QSA|qsappend</a></h2>
    <p>
    Quand l'URI de remplacement contient une chaîne de requête, le
    comportement par défaut de la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> est de supprimer la <code>
    query string</code> (il s'agit des paramètres éventuellement passés dans l'URL après le
    caractère <code>?</code>, usuellement pour les formulaires traités par la
    méthode HTTP <code>GET</code>) existante, et de la remplacer par celle nouvellement créée.
    Avec le drapeau [QSA], les chaînes de requête peuvent être combinées.
    </p>
    
    <p>Considérons la règle suivante :</p>
    
    <pre class="prettyprint lang-config">RewriteRule "/pages/(.+)" "/page.php?page=$1" [QSA]</pre>
    
    
    <p>Avec le drapeau [QSA], une requête pour
    <code>/pages/123?one=two</code> sera réécrite en
    <code>/page.php?page=123&amp;one=two</code>. Sans le drapeau [QSA], la
    même requête sera réécrite en <code>/page.php?page=123</code> -
    autrement dit, la chaîne de requête (<code>query string</code>) existante sera supprimée.
    </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_qsd" id="flag_qsd">QSD|qsdiscard</a></h2>
    <p>
    Lorsque l'URI de la requête contient une chaîne de paramètres, et si
    l'URI cible n'en contient pas, le comportement par défaut de la
    directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> consiste à copier cette
    chaîne de paramètres dans l'URI cible. Avec le drapeau [QSD], la chaîne
    de paramètres est supprimée.
    </p>
    
    <p>Ce drapeau est disponible dans les versions 2.4.0 et supérieures.</p>
    
    <p>
    Lorsque les drapeaux [QSD] et [QSA] sont utilisés ensemble, c'est le
    drapeau [QSD] qui l'emporte.
    </p>
    
    <p>
    Si l'URI cible possède une chaîne de paramètres, le comportement par
    défaut sera respecté - c'est à dire que la chaîne de paramètres
    originale sera supprimée et remplacée par la chaîne de paramètres de
    l'URI cible.
    </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_qsl" id="flag_qsl">QSL|qslast</a></h2>
    <p>
    Par défaut, le premier (le plus à gauche) point d'interrogation de la
    substitution sépare le chemin de la requête de sa chaîne de paramètres. Avec le
    drapeau [QSL] au contraire, les deux composants seront séparés en utilisant le
    dernier (le plus à droite) point d'interrogation.</p>
    
    <p>
    Cela peut s'avérer utile lorsqu'on recherche un fichier dont le nom contient des
    points d'interrogation. Si aucune chaîne de paramètre n'est présente dans la
    substitution, il est alors possible d'ajouter un point d'interrogation à la fin
    et d'utiliser ce drapeau.</p>
    
    <p>Ce drapeau est disponible à partir de la version 2.4.19 du serveur HTTP
    Apache.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_r" id="flag_r">R|redirect</a></h2>
    <p>
    L'utilisation du drapeau [R] provoque l'envoi d'une redirection au
    navigateur. Si une URL pleinement qualifiée (FQDN - fully qualified domain name)
     est spécifiée (c'est à dire incluant <code>http://nom-du-serveur/</code>),
     une redirection sera effectuée vers cette adresse. Dans le cas contraire,
     le protocole courant, le nom du serveur et le numéro de port seront
     utilisés pour générer l'URL envoyée avec la redirection.
    </p>
    
    <p><em>Tout</em> code de statut de réponse HTTP valide peut être
    spécifié, en utilisant la syntaxe [R=305], le code de statut 302 étant
    utilisé par défaut si aucun code n'est spécifié. Le code de statut
    spécifié n'est pas nécessairement un code de statut
    de redirection (3xx). Cependant, si le code de statut est en dehors de la plage des codes de
    redirection (300-399), la chaîne de substitution est entièrement
    supprimée, et la réécriture s'arrête comme si le drapeau <code>L</code>
    était utilisé.</p>
    
    <p>En plus des codes de statut de réponse, vous pouvez spécifier les
    codes de redirection en utilisant leurs noms symboliques :
    <code>temp</code> (défaut), <code>permanent</code>, ou
    <code>seeother</code>.</p>
    
    <p>
    Vous utiliserez presque toujours [R] en conjonction avec [L] (c'est à
    dire [R,L]), car employé seul, le drapeau [R] préfixe l'URI avec
    <code>http://cet-hôte[:ce-port]</code>, mais passe ensuite cette adresse
    à la règle suivante, ce qui provoquera le plus souvent des
    avertissements 'Invalid URI in request'.
    </p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_s" id="flag_s">S|skip</a></h2>
    <p>Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir
    exécuter. La syntaxe du drapeau [S] est [S=<em>N</em>], où
    <em>N</em> correspond au nombre de règles à sauter (sous
    réserve que la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> corresponde et qu'au moins
    une condition <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
    préalable soit vérifiée). 
    Ceci peut s'interpréter comme une instruction
    <code>goto</code>  dans votre jeu de règles de réécriture. Dans
    l'exemple suivant, nous ne voulons exécuter la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> que si l'URI demandé ne
    correspond pas à un fichier existant.</p>
    <pre class="prettyprint lang-config"># La requête concerne-t-elle un fichier qui n'existe pas ?
    RewriteCond "%{REQUEST_FILENAME}" !-f
    RewriteCond "%{REQUEST_FILENAME}" !-d
    # Si c'est la cas, on saute les deux règles de réécriture suivantes
    RewriteRule ".?"                  "-" [S=2]
    
    RewriteRule "(.*\.gif)"           "images.php?$1"
    RewriteRule "(.*\.html)"          "docs.php?$1"</pre>
    
    
    
    
    <p>Cette technique trouve son utilité dans le fait qu'une directive
    <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> ne s'applique
    qu'à la règle qui la suit immédiatement. Ainsi, si vous voulez
    qu'une directive <code>RewriteCond</code> s'applique à plusieurs règles
    <code>RewriteRule</code>, une technique possible consiste à inverser ces
    conditions et ajouter une <code>RewriteRule</code> avec le drapeau [Skip]. Cette technique permet
    d'élaborer des pseudo-constructions if-then-else : la dernière règle du
    bloc then contiendra <code>skip=N</code>, où N est le nombre de règles
    contenues dans le bloc else :</p>
    <pre class="prettyprint lang-config"># Est-ce que le fichier existe ?
    RewriteCond "%{REQUEST_FILENAME}" !-f
    RewriteCond "%{REQUEST_FILENAME}" !-d
    # Créer une structure conditionnelle if-then-else en sautant 3 lignes si nous
    # avions l'intention d'aller au bloc "else".
    RewriteRule ".?"                  "-" [S=3]
    
    # Si le fichier existe, alors :
        RewriteRule "(.*\.gif)"  "images.php?$1"
        RewriteRule "(.*\.html)" "docs.php?$1"
        # Passer le bloc "else".
        RewriteRule ".?"         "-" [S=1]
    # ELSE...
        RewriteRule "(.*)"       "404.php?file=$1"
    # END</pre>
    
    
    <p>Il est probablement plus aisé de définir ce genre de configuration
    via les directives <code class="directive">&lt;If&gt;</code>, <code class="directive">&lt;ElseIf&gt;</code>, et <code class="directive">&lt;Else&gt;</code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_t" id="flag_t">T|type</a></h2>
    <p>Définit le type MIME de la réponse résultante renvoyée. L'effet est
    identique à celui de la directive <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code>.</p>
    
    <p>Par exemple, vous pouvez utiliser la technique suivante pour servir
    du code source Perl en tant que plein texte, s'il est requis d'une
    certaine manière :</p>
    
    <pre class="prettyprint lang-config"># Sert les fichier .pl en tant que plein texte
    RewriteRule "\.pl$"  "-" [T=text/plain]</pre>
    
    
    <p>Ou encore, si vous possédez une caméra qui produit des fichiers
    images jpeg sans extension, vous pouvez forcer le renvoi de ces images
    avec le type MIME correct en se basant sur le nom du fichier :</p>
    
    <pre class="prettyprint lang-config"># Les fichiers dont le nom contient 'IMG' sont des images jpg.
    RewriteRule "IMG"  "-" [T=image/jpg]</pre>
    
    
    <p>Notez cependant qu'il s'agit d'un exemple trivial, et que le problème
    aurait pu être résolu en utilisant à la place la directive <code class="directive"><a href="../mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>. Il faut toujours
    envisager la possibilité d'une solution alternative à un problème avant
    d'avoir recours à la réécriture, qui sera toujours moins efficace qu'une
    solution alternative.</p>
    
    <p>
    Dans un contexte de niveau répertoire, n'utilisez que <code>-</code>
    (tiret) comme substitution, <em>dans toute la séquence de réécriture de
    mod_rewrite</em>, sinon le type MIME défini avec ce drapeau
    sera perdu suite à un retraitement interne (y compris les séquences de
    réécriture suivantes de mod_rewrite). Dans ce contexte, vous pouvez
    utiliser le drapeau <code>L</code> pour terminer la séquence
    <em>courante</em> de réécriture de mod_rewrite.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_unsafe_allow_3f" id="flag_unsafe_allow_3f">UnsafeAllow3F</a></h2>
        <p>Il est nécessaire de définir ce drapeau pour permettre à une réécriture
        de continuer si la requête HTTP en cours d’écriture possède un point d'interrogation encodé, «&nbsp;%3f&nbsp;», et si le résultat réécrit contient un «&nbsp;?&nbsp;» dans
        la substitution. Cela protège d’une URL malveillante tirant avantage d’une
        capture et d’une resubstitution du point d'interrogation encodé.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_unsafe_prefix_stat" id="flag_unsafe_prefix_stat">UnsafePrefixStat</a></h2>
        <p>La définition de ce drapeau est requise dans les substitutions à
        l'échelle du serveur qui commencent par une variable ou une référence
        arrière et se résolvent en un chemin du système de fichiers. Ces
        substitutions ne sont pas préfixées par la racine des documents. Cela protège
        d’une URL malveillante faisant correspondre la substitution expansée à un
        emplacement non souhaité du système de fichiers.</p>
    
        <p>Disponible à partir de la version 2.4.60 du serveur HTTP Apache.</p>    
     </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flag_unc" id="flag_unc">UNC</a></h2>
        <p>Définir ce drapeau empêche la fusion des slashes de début multiples tels
        que ceux utilisés dans les chemins UNC de Windows. Ce drapeau n’est pas
        nécessaire lorsque la substitution de la règle commence par des slashes
        multiples littéraux.</p>
    
        <p>Disponible à partir de la version 2.4.62 du serveur HTTP Apache.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/flags.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/flags.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/flags.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/proxy.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000017471�14740503670�022072� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Utilisation de mod_rewrite comme mandataire - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Utilisation de mod_rewrite comme mandataire</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/proxy.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/proxy.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document est un complément de la <a href="../mod/mod_rewrite.html">documentation de référence</a> du module
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il décrit comment utiliser le drapeau [P]
    de la directive RewriteRule pour mandater un contenu vers un autre
    serveur. Plusieurs recettes décrivant des scénarios courants sont
    fournies.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
    correspondance</a></li><li><a href="access.html">Contrôle d'accès</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dynamic-proxy" id="dynamic-proxy">Mandater du contenu avec mod_rewrite</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
        <p>
        mod_rewrite implémente le drapeau [P] qui permet de passer des URLs,
        via mod_proxy, à un autre serveur. Deux exemples sont fournis ici.
        Dans le premier, une URL est passée directement à un autre serveur,
        et servie comme si c'était une URL locale. Dans le deuxième, nous
        mandatons un contenu manquant vers un serveur d'arrière-plan.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>Pour passer une URL à un autre serveur, on utilise le drapeau
          [P] comme suit :</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteBase    "/produits/"
    RewriteRule    "^widget/(.*)$"  "http://produits.example.com/widget/$1"  [P]
    ProxyPassReverse "/produits/objet/" "http://produits.example.com/objet/"</pre>
    
    
       <p>Dans le deuxième exemple, nous ne mandatons la requête que si nous
       ne trouvons pas la ressource localement. Ceci peut s'avérer très
       utile lorsque vous effectuez une migration d'un serveur vers un
       autre, et que vous n'êtes pas certain que tout le contenu a déjà été
       migré.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{REQUEST_FILENAME}"       !-f
    RewriteCond "%{REQUEST_FILENAME}"       !-d
    RewriteRule "^/(.*)" "http://ancien.exemple.com/$1" [P]
    ProxyPassReverse "/" "http://ancien.exemple.com/"</pre>
    
        </dd>
    
        <dt>Discussion :</dt>
    
        <dd><p>Dans les deux cas, on ajoute une directive <code class="directive"><a href="../mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> afin de s'assurer
        que toute redirection en provenance du serveur d'arrière-plan est
        renvoyée correctement au client.</p>
    
        <p>Chaque fois que cela est possible, préférez l'utilisation de la
        directive <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> ou
        <code class="directive"><a href="../mod/mod_proxy.html#proxypassmatch">ProxyPassMatch</a></code> à
        mod_rewrite.</p>
        </dd>
      </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/proxy.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/proxy.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/proxy.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/vhosts.html.fr.utf8������������������������������������������������0000664�0001751�0001751�00000032314�14740503670�022230� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Hébergement virtuel de masse avec mod_rewrite - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Hébergement virtuel de masse avec mod_rewrite</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/vhosts.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/vhosts.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document est un complément à la <a href="../mod/mod_rewrite.html">documentation de référence</a> du module
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il décrit comment créer des serveurs
    virtuels dynamiquement configurés en utilisant
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    <div class="warning">L'utilisation de mod_rewrite n'est pas la meilleure
    méthode pour configurer des serveurs virtuels. Vous devez dans un
    premier temps tenter de résoudre votre problème via ces  <a href="../vhosts/mass.html">d'autres méthodes</a> avant d'avoir
    recours à mod_rewrite. Voir aussi le document <a href="avoid.html#vhosts">Comment éviter l'utilisation de
    mod_rewrite</a>.</div>
    
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#per-hostname">Serveurs virtuels pour des noms d'hôtes arbitraires</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#simple.rewrite">Configuration dynamique de serveurs
    virtuels via <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#xtra-conf">Utilisation d'un fichier de configuration
    du serveur virtuel séparé</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
    correspondance</a></li><li><a href="access.html">Contrôle d'accès</a></li><li><a href="proxy.html">Serveurs mandataires</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="per-hostname" id="per-hostname">Serveurs virtuels pour des noms d'hôtes arbitraires</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
        <p>Nous voulons créer automatiquement un serveur virtuel pour tout
        nom d'hôte qui peut être résolu dans notre domaine, sans avoir à
        créer de nouvelle section VirtualHost.</p>
    
        <p>Dans cet exemple, nous supposons que nous utilisons le nom d'hôte
        <code>www.<strong>SITE</strong>.example.com</code> pour chaque
        utilisateur, et que nous servons leur contenu depuis
        <code>/home/<strong>SITE</strong>/www</code>.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    
    RewriteMap    lowercase int:tolower
    
    RewriteCond   "${lowercase:%{<strong>HTTP_HOST</strong>}}" "^www\.<strong>([^.]+)</strong>\.example\.com$"
    RewriteRule   "^(.*)" "/home/<strong>%1</strong>/www$1"</pre>
    </dd>
    
    <dt>Discussion</dt>
        <dd>
    
        <div class="warning">Vous devez vérifier le bon fonctionnement de la
        résolution DNS - Apache ne gère pas la résolution de nom. Vous
        devrez créer soit des enregistrements CNAME pour chaque nom d'hôte,
        soit un enregistrement DNS avec caractères génériques. La création
        des enregistrements DNS est en dehors du sujet de ce document.</div>
    
    <p>La directive RewriteMap interne <code>tolower</code> permet de
    s'assurer que les noms d'hôtes utilisés seront tous en minuscules, de
    façon à éviter toute ambiguité dans la structure des répertoires qui
    doit être créée.</p>
    
    <p>Les contenus des parenthèses utilisées dans une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> sont enregistrés dans les
    références arrières <code>%1</code>, <code>%2</code>, etc..., alors que
    les contenus des parenthèses utilisées dans une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> le sont dans les
    références arrières <code>$1</code>, <code>$2</code>, etc...</p>
    
    <p>
    Comme c'est le cas pour de nombreuses techniques discutées dans ce
    document, mod_rewrite n'est vraiment pas la meilleure méthode pour
    accomplir cette tâche. Vous devez plutôt vous tourner vers
    <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code>, car ce dernier sera bien plus à même
    de gérer tout ce qui est au delà du domaine des fichiers statiques,
    comme les contenus dynamiques et la résolution des alias.
    </p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="simple.rewrite" id="simple.rewrite">Configuration dynamique de serveurs
    virtuels via <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code></a></h2>
    
        <p>Cet extrait du fichier <code>httpd.conf</code> permet d'obtenir
        le même résultat que <a href="#per-hostname">le premier exemple</a>.
        La première moitié est très similaire à la partie correspondante
        ci-dessus, excepté quelques modifications requises à des fins de
        compatibilité ascendante et pour faire en sorte que la partie
        <code>mod_rewrite</code> fonctionne correctement ; la seconde moitié
        configure <code>mod_rewrite</code> pour effectuer le travail
        proprement dit.</p>
    
        <p>Comme <code>mod_rewrite</code> s'exécute avant tout autre module
        de traduction d'URI (comme <code>mod_alias</code>), il faut lui
        ordonner explicitement d'ignorer toute URL susceptible d'être
        traitée par ces autres modules. Et comme ces règles auraient sinon
        court-circuité toute directive <code>ScriptAlias</code>, nous devons
        faire en sorte que <code>mod_rewrite</code> déclare explicitement
        ces correspondances.</p>
    
    <pre class="prettyprint lang-config"># extrait le nom de serveur de l'en-tête Host:
    UseCanonicalName Off
    
    # journaux dissociables
    LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
    CustomLog "logs/access_log" vcommon
    
    &lt;Directory "/www/hosts"&gt;
        # ExecCGI est nécessaire ici car on ne peut pas forcer l'exécution
        # des CGI à la manière de ScriptAlias
        Options FollowSymLinks ExecCGI
    &lt;/Directory&gt;
    
    RewriteEngine On
    
    # un nom de serveur extrait d'un en-tête Host: peut être dans n'importe
    # quelle casse
    RewriteMap  lowercase  int:tolower
    
    ## on s'occupe tout d'abord des documents normaux :<br />
    # permet à Alias "/icons/" de fonctionner - répéter pour les autres
    RewriteCond  "%{REQUEST_URI}"  "!^/icons/"
    # permet aux CGIs de fonctionner
    RewriteCond  "%{REQUEST_URI}"  "!^/cgi-bin/"
    # le coeur du traitement
    RewriteRule  "^/(.*)$"  "/www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1"
    
    ## on s'occupe maintenant des CGIs - on doit forcer l'utilisation d'un
    # gestionnaire
    RewriteCond  "%{REQUEST_URI}"  "^/cgi-bin/"
    RewriteRule  "^/(.*)$" "/www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1"  [H=cgi-script]</pre>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="xtra-conf" id="xtra-conf">Utilisation d'un fichier de configuration
    du serveur virtuel séparé</a></h2>
    
        <p>Cette construction utilise des fonctionnalités plus avancées de
        <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour effectuer la traduction depuis le
        serveur virtuel vers la racine des documents, à partir d'un fichier
        de configuration séparé. Elle est plus souple mais nécessite une
        configuration plus compliquée.</p>
    
        <p>Le fichier <code>vhost.map</code> devrait ressembler à ceci :</p>
    
    <div class="example"><p><code>
    www.client-1.example.com  /www/clients/1<br />
    www.client-2.example.com  /www/clients/2<br />
    # ...<br />
    www.client-N.example.com  /www/clients/N<br />
    </code></p></div>
    
        <p>On doit ajouter à <code>httpd.conf</code> :</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    
    RewriteMap   lowercase  int:tolower
    
    # définit le fichier de correspondances
    RewriteMap   vhost      "txt:/www/conf/vhost.map"
    
    # on s'occupe des alias comme ci-dessus
    RewriteCond  "%{REQUEST_URI}"               "!^/icons/"
    RewriteCond  "%{REQUEST_URI}"               "!^/cgi-bin/"
    RewriteCond  "${lowercase:%{SERVER_NAME}}"  "^(.+)$"
    # on effectue ici la remise en correspondance à base de fichier
    RewriteCond  "${vhost:%1}"                  "^(/.*)$"
    RewriteRule  "^/(.*)$"                      "%1/docs/$1"
    
    RewriteCond  "%{REQUEST_URI}"               "^/cgi-bin/"
    RewriteCond  "${lowercase:%{SERVER_NAME}}"  "^(.+)$"
    RewriteCond  "${vhost:%1}"                  "^(/.*)$"
    RewriteRule  "^/cgi-bin/(.*)$"              "%1/cgi-bin/$1" [H=cgi-script]</pre>
    
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/vhosts.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/vhosts.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/vhosts.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/rewritemap.html����������������������������������������������������0000664�0001751�0001751�00000000323�13710016232�021546� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: rewritemap.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: rewritemap.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/intro.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000061066�14740503670�022043� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Introduction au module Apache mod_rewrite - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Introduction au module Apache mod_rewrite</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/intro.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/intro.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <p>Ce document est un complément à la <a href="../mod/mod_rewrite.html">documentation de référence</a> du module
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il décrit les concepts de base dont la
    connaissance est nécessaire pour l'utilisation de
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. D'autres documents entrent d'avantage dans
    les détails, mais celui-ci devrait aider le débutant à se mouiller les
    pieds.
    </p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#regex">Expressions rationnelles</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewriterule">Les bases des règles de réécriture</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flags">Drapeaux de réécriture</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewritecond">Conditions de réécriture</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewritemap">Tables de réécriture</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">Fichiers .htaccess</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du
    module mod_rewrite</a></li><li><a href="remapping.html">Redirection and remise en
    correspondance</a></li><li><a href="access.html">Contrôle d'accès</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Mise en cache</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    <p>Le module Apache <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> est un module puissant
    et sophistiqué qui permet la réécriture des URLs. Grâce à lui, vous
    pouvez effectuer quasiment tous les types de réécriture d'URLs dont vous
    avez besoin. Il est cependant assez complexe, et peut paraître
    intimidant au débutant. Certains ont aussi tendance à traiter les
    règles de réécriture comme des incantations magiques, et à les utiliser
    sans vraiment comprendre leur manière d'agir.</p>
    
    <p>Ce document a pour ambition d'être suffisamment explicite pour
    permettre la compréhension, et non la copie en aveugle, de ce qui suit.
    </p>
    
    <p>Gardez à l'esprit que de nombreuses tâches de manipulation d'URLs
    courantes n'ont pas besoin de la puissance et de la complexité de
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Pour les tâches simples, voir
    <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> et la documentation sur la <a href="../urlmapping.html">Mise en correspondance des URLs avec le
    système de fichiers</a>.</p>
    
    <p>Enfin, avant de procéder, assurez-vous d'avoir configuré le niveau de
    journalisation de <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> à un des niveaux de trace
    via la directive <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code>. Bien que
    ceci risque de vous submerger sous une énorme quantité d'informations,
    le débogage des problèmes avec la configuration de
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> est à ce prix car vous verrez alors
    exactement comment chaque règle est traitée.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="regex" id="regex">Expressions rationnelles</a></h2>
    
    <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> utilise le vocabulaire des <a href="http://pcre.org/">Expressions rationnelles compatibles Perl</a>.
    Ce document n'a pas pour prétention d'être une référence détaillée des
    expressions rationnelles. A cet effet, nous recommandons les <a href="http://pcre.org/pcre.txt">pages de manuel de PCRE</a>, la <a href="http://perldoc.perl.org/perlre.html">page de manuel des
    expressions rationnelles Perl</a>, et l'ouvrage <a href="http://shop.oreilly.com/product/9780596528126.do">Mastering
    Regular Expressions, by Jeffrey Friedl</a>.</p>
    
    <p>Dans ce document, nous avons pour but de vous fournir suffisamment de
    vocabulaire des expressions rationnelles pour vous mettre le pied à
    l'étrier, sans être dépassé, en espérant que les directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> vous apparaîtront comme des
    formules scientifiques, plutôt que comme des incantations magiques.</p>
    
    <h3><a name="regexvocab" id="regexvocab">Vocabulaire des expressions rationnelles</a></h3>
    
    <p>Vous trouverez dans ce qui suit le minimum à connaître pour être en
    mesure d'écrire des expressions rationnelles et des règles <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>. Ceci ne représente
    certainement pas un vocabulaire des expressions rationnelles complet,
    mais constitue un bon point de départ, et devrait vous aider à
    déchiffrer les expressions rationnelles simples, et à écrire vos propres
    expressions.</p>
    
    <table>
    <tr>
    <th>Motif</th>
    <th>Signification</th>
    <th>Exemple</th>
    </tr>
    
    <tr>
    	<td><code>.</code></td>
    	<td>Correspond à tout caractère unique</td>
    	<td><code>c.t</code> correspondra à <code>cat</code>,
    	<code>cot</code>, <code>cut</code>, etc.</td>
    </tr>
    <tr>
    	<td><code>+</code></td>
    	<td>Répète le caractère de correspondance précédent une ou plusieurs fois</td>
    	<td><code>a+</code> correspond à <code>a</code>, <code>aa</code>,
    	<code>aaa</code>, etc.</td>
    </tr>
    	<tr><td><code>*</code></td>
    	<td>Répète le caractère de correspondance
    	précédent zéro ou plusieurs fois</td>
    	<td><code>a*</code> correspond à tout ce à quoi correspond
    	<code>a+</code>, mais correspond aussi à la chaîne vide.</td>
    </tr>
    <tr>
    	<td><code>?</code></td>
    	<td>Rend la correspondance optionnelle.</td>
    	<td><code>colou?r</code> correspondra à <code>color</code> et <code>colour</code>.</td>
    </tr>
    <tr>
        <td><code>\</code></td>
        <td>Echappe le caractère suivant</td>
        <td><code>\.</code> correspondra à <code>.</code> (le point) et non <em>à
        tout caractère unique</em> comme expliqué plus haut</td>
    </tr>
    <tr>
    	<td><code>^</code></td>
    	<td>Appelé ancrage, correspond au début de la
    	chaîne</td>
    	<td><code>^a</code> correspond à une chaîne qui commence par
    	<code>a</code></td>
    </tr>
    <tr>
    	<td><code>$</code></td>
    	<td>L'autre ancrage, correspond à la fin de
    	la chaîne.</td>
    	<td><code>a$</code> correspond à une chaîne qui se termine par
    	<code>a</code>.</td>
    </tr>
    <tr>
    	<td><code>( )</code></td>
    	<td>Regroupe plusieurs caractères en une
    	seule entité, et conserve une correspondance à des fins d'utilisation
    	dans une référence arrière.</td>
    	<td><code>(ab)+</code>
    	correspond à <code>ababab</code> - à savoir, le <code>+</code>
    	s'applique au groupe.
    	Pour plus de détails sur les références arrières, voir <a href="#InternalBackRefs">ci-dessous</a>.</td>
    </tr>
    <tr>
    	<td><code>[ ]</code></td>
    	<td>Une classe de caractères - correspond à
    	un des caractères de la classe</td>
    	<td><code>c[uoa]t</code> correspond à <code>cut</code>,
    	<code>cot</code> ou <code>cat</code>.</td>
    </tr>
    <tr>
    	<td><code>[^ ]</code></td>
    	<td>Négation de la classe de caractères -
    	correspond à tout caractère ne faisant pas partie de la classe</td>
    	<td><code>c[^/]t</code> correspond à <code>cat</code> ou
    	<code>c=t</code> mais pas à <code>c/t</code></td>
    </tr>
    </table>
    
    <p>Avec <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>, le caractère <code>!</code> peut
    préfixer une expression rationnelle afin d'en exprimer la négation.
    Autrement dit, une chaîne ne correspondra que si elle ne correspond pas
    à l'expression située après le <code>!</code>.</p>
    
    
    
    <h3><a name="InternalBackRefs" id="InternalBackRefs">Disponibilité des références
    arrières dans les expressions rationnelles</a></h3>
    
          <p>Vous devez vous souvenir d'une chose importante : chaque fois
          que vous utilisez des parenthèses dans un <em>Modèle</em> ou dans
          un des <em>modèles de conditions</em>, des références arrières
          sont créées en interne et peuvent être rappelées via les chaînes
          <code>$N</code> et <code>%N</code> (voir ci-dessous). Ces
          références sont disponibles lors de la
          création de la chaîne de substitution d'une directive
          <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> ou de la
          chaîne de test d'une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>.</p>
          <p>Les captures dans les modèles de directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> sont paradoxalement
          disponibles dans toutes les directives <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> qui précèdent, car
          les expressions des directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> sont évaluées avant
          les conditions individuelles.</p>
          
          <p>La figure 1 montre à quels endroits les
          références arrières sont suceptibles
          d'être développées, et illustre le flux des comparaisons
          effectuées par les règles RewriteRule et
          RewriteCond. Dans les chapitres suivants, nous examinerons comment
          utiliser ces références arrières, donc ne vous affolez pas si
          elles vous paraissent un peu exotiques au premier abord.</p>
    
    <p class="figure">
          <img src="../images/rewrite_backreferences.png" alt="Flux des comparaisons effectuées par les règles RewriteRule       et RewriteCond" /><br />
          <dfn>Figure 1 :</dfn> Le cheminement d'une référence arrière à
          travers une règle.<br />
          Dans cet exemple, une requête pour <code>/test/1234</code> serait
          transformée en
          <code>/admin.foo?page=test&amp;id=1234&amp;host=admin.example.com</code>.
    </p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewriterule" id="rewriterule">Les bases des règles de réécriture</a></h2>
    <p>Une règle de réécriture <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> est constituée de trois
    arguments séparés par des espaces. Les arguments sont :</p>
    <ol>
    <li><var>Modèle</var>: le modèle des URLs auxquelles la règle doit
    s'appliquer;</li>
    <li><var>Substitution</var>: vers quoi la requête correspondante doit être
    transformée;</li>
    <li><var>[drapeaux]</var>: options affectant la requête réécrite.</li>
    </ol>
    
    <p>Le <var>Modèle</var> est une <a href="#regex">expression
    rationnelle</a>. Au sein de la première règle de réécriture, ou jusqu'à
    ce qu'une substitution survienne, elle est comparée au chemin de
    l'URL de la requête entrante (la
    partie située après le nom d'hôte mais avant tout point d'interrogation
    qui indique le début d'une chaîne de paramètres de
    requête) ou, dans un contexte de répertoire, au chemin de la
    requête relativement au répertoire pour lequel la
    règle est définie. Lorsqu'une substitution a eu lieu, les
    règles suivantes effectuent leurs comparaisons par rapport à la valeur
    substituée.</p>
    
    <p class="figure">
          <img src="../images/syntax_rewriterule.png" alt="Syntaxe de la directive RewriteRule" /><br />
          <dfn>Figure 2 :</dfn> Syntaxe de la directive RewriteRule.
    </p>
    
    <p>La chaîne de <var>Substitution</var> peut, quant à elle, être de
    trois types :</p>
    
    <dl>
    <dt>1. Un chemin complet du système de fichiers vers une ressource</dt>
    <dd>
    <pre class="prettyprint lang-config">RewriteRule "^/games" "/usr/local/games/web/puzzles.html"</pre>
    
    <p>Ceci peut faire correspondre une requête à toute localisation voulue de
    votre système de fichiers, un peu comme la directive <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code>.</p>
    </dd>
    
    <dt>2. Un chemin web vers une ressource</dt>
    <dd>
    <pre class="prettyprint lang-config">RewriteRule "^/games$" "/puzzles.html"</pre>
    
    <p>Si la directive <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> a
    pour valeur <code>/usr/local/apache2/htdocs</code>, cette règle va faire
    correspondre les requêtes pour <code>http://example.com/games</code> au
    chemin <code>/usr/local/apache2/htdocs/puzzles.html</code>.</p>
    </dd>
    
    <dt>3. Une URL absolue</dt>
    <dd>
    <pre class="prettyprint lang-config">RewriteRule "^/produits/vues$" "http://site2.example.com/voirproduits.html" [R]</pre>
    
    <p>Ceci informe le client qu'il doit effectuer une nouvelle requête vers
    l'URL spécifiée.</p>
    </dd>
    </dl>
    
    <div class="warning">Notez que <strong>1</strong> et <strong>2</strong>
    possèdent exactement la même syntaxe. Par contre, dans le cas de
    <strong>1</strong>, le niveau racine du chemin cible (par exemple
    <code>/usr/</code>) existe dans le système de fichiers, alors que ce n'est pas
    le cas avec <strong>2</strong> (par exemple, il n'y a pas de répertoire
    <code>/bar/</code> au niveau de la racine du système de fichiers).</div>
    
    <p>La chaîne de <var>Substitution</var> peut aussi contenir des
    <em>références arrières</em> vers des parties du chemin d'URL entrant
    correspondant au <var>Modèle</var>. Considérons ce qui suit :</p>
    <pre class="prettyprint lang-config">RewriteRule "^/produits/(.*)/view$" "/var/web/produitsdb/$1"</pre>
    
    <p>La variable <code>$1</code> sera remplacée par tout texte
    correspondant à l'expression située entre les parenthèses dans le
    <var>Modèle</var>. Par exemple, une requête pour
    <code>http://example.com/produits/r14df/vue</code> correspondra au
    chemin <code>/var/web/produitsdb/r14df</code>.</p>
    
    <p>S'il y a plus d'une expression entre parenthèses, elle seront
    accessibles selon leur ordre d'apparition via les variables
    <code>$1</code>, <code>$2</code>, <code>$3</code>, etc...</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flags" id="flags">Drapeaux de réécriture</a></h2>
    <p>Le comportement d'une règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> peut être modifié par la
    présence d'un ou plusieurs drapeaux en fin de règle. Par exemple, les
    conditions de correspondance d'une règle peuvent être rendues
    insensibles à la casse par la présence du drapeau <code>[NC]</code> :
    </p>
    <pre class="prettyprint lang-config">RewriteRule "^puppy.html" "petitchien.html" [NC]</pre>
    
    
    <p>Pour une liste des drapeaux disponibles, leurs significations, et des
    exemples, voir le document <a href="flags.html">Drapeaux de
    réécriture</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewritecond" id="rewritecond">Conditions de réécriture</a></h2>
    <p>Il est possible d'utiliser une ou plusieurs directives <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> pour restreindre les types
    de requêtes auxquelles devra s'appliquer la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> suivante. Le premier
    argument est une variable décrivant une caractéristique de la requête,
    le second argument est une <a href="#regex">expression rationnelle</a>
    qui doit correspondre à la variable, et un troisième argument optionnel
    est une liste de drapeaux qui modifient la manière dont la
    correspondance est évaluée.</p>
    
    <p class="figure">
          <img src="../images/syntax_rewritecond.png" alt="Syntaxe de la directive RewriteCond" /><br />
          <dfn>Figure 3 :</dfn> Syntaxe de la directive RewriteCond
    </p>
    
    
    <p>Par exemple, pour renvoyer toutes les requêtes en provenance d'une
    certaine tranche d'adresses IP vers un autre serveur, vous pouvez
    utiliser :</p>
    <pre class="prettyprint lang-config">RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
    RewriteRule "(.*)"           "http://intranet.example.com$1"</pre>
    
    
    <p>Si vous spécifiez plus d'une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>, ces directives
    doivent toutes être satisfaites pour que la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> suivante s'applique. Par exemple,
    pour interdire les requêtes qui contiennent le mot "hack" dans la chaîne
    de requête, sauf si elles contiennent aussi un cookie contenant le mot
    "go", vous pouvez utiliser :</p>
    <pre class="prettyprint lang-config">RewriteCond "%{QUERY_STRING}" "hack"
    RewriteCond "%{HTTP_COOKIE}"  !go
    RewriteRule "."               "-"   [F]</pre>
    
    <p>Notez que le point d'exclamation indique une correspondance négative
    ; ainsi, la règle n'est appliquée que si le cookie ne contient pas "go"</p>
    
    <p>Les correspondances dans les expressions rationnelles contenues dans
    les directives <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
    peuvent constituer des parties de la chaîne de <var>Substitution</var>
    de la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> via
    les variables <code>%1</code>, <code>%2</code>, etc... Par
    exemple, ce qui suit va diriger la requête vers un répertoire différent
    en fonction du nom d'hôte utilisé pour accéder au site :</p>
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}" "(.*)"
    RewriteRule "^/(.*)"       "/sites/%1/$1"</pre>
    
    <p>Si la requête concernait <code>http://example.com/foo/bar</code>,
    alors <code>%1</code> contiendrait <code>example.com</code> et
    <code>$1</code> contiendrait <code>foo/bar</code>.</p>
    
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewritemap" id="rewritemap">Tables de réécriture</a></h2>
    
    <p>La directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
    permet en quelque sorte de faire appel à une fonction externe pour
    effectuer la réécriture à votre place. Tout ceci est décrit plus en
    détails dans la <a href="rewritemap.html">Documentation
    supplémentaire sur RewriteMap</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">Fichiers .htaccess</a></h2>
    
    <p>La réécriture est en général définie au niveau de la configuration du
    serveur principal (en dehors de toute section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>) ou dans une section  <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>. Il s'agit là de la
    manière la plus simple de mettre en oeuvre la réécriture et nous la
    recommandons. Il est possible, cependant, de mettre en oeuvre la
    réécriture au sein d'une section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> ou d'un fichier <a href="../howto/htaccess.html"><code>.htaccess</code></a> ; ce type de
    configuration est cependant plus complexe. Cette technique est appelée
    réécriture par répertoire.</p>
    
    <p>La principale différence avec les réécritures au niveau du serveur réside
    dans le fait que le préfixe du chemin du répertoire contenant le fichier
    <code>.htaccess</code> est supprimé avant la mise en correspondance dans
    la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>. De
    plus, on doit utiliser la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> pour s'assurer que la
    requête est correctement mise en correspondance.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/intro.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/intro.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/intro.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/tech.html.fr.utf8��������������������������������������������������0000664�0001751�0001751�00000034315�14740503670�021630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Détails techniques sur le module Apache mod_rewrite - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Détails techniques sur le module Apache mod_rewrite</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/tech.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/tech.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <p>Ce document passe en revue certains détails techniques à propos du
    module mod_rewrite et de la mise en correspondance des URLs</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#InternalAPI">Phases de l'API</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#InternalRuleset">Traitement du jeu de règles</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module mod_rewrite</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
    correspondance</a></li><li><a href="access.html">Contrôle d'accès</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Mise en cache</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="InternalAPI" id="InternalAPI">Phases de l'API</a></h2>
    
          <p>Le traitement des requêtes par le serveur HTTP Apache se
          déroule en plusieurs phases. Au cours de chaque phase, un ou
          plusieurs modules peuvent être appelés pour traiter la partie
          concernée du cycle de vie de la requête. Les différentes phases
          peuvent consister en traduction d'URL en nom de fichier,
          authentification, autorisation, gestion de contenu ou journalisation (la
          liste n'est pas exhaustive).</p>
    
        <p>mod_rewrite agit dans deux de ces phases (ou accroches - hooks -
        comme on les nomme souvent) pour la réécriture des URLs.</p>
    
        <p>Tout d'abord, il utilise le hook traduction URL vers nom de
        fichier qui intervient après la lecture de la requête HTTP, mais
        avant le processus d'autorisation. Ensuite, il utilise le hook
        Fixup, qui intervient après les phases d'autorisation, après la
        lecture des fichiers de configuration de niveau répertoire (fichiers
        <code>.htaccess</code>), mais avant l'appel du gestionnaire de
        contenu.</p>
    
        <p>Ainsi, lorsqu'une requête arrive et une fois le serveur
        correspondant ou le serveur virtuel déterminé, le moteur de
        réécriture commence à traiter toute directive apparaissant dans la
        configuration de niveau serveur (autrement dit dans le
        fichier de configuration principal du serveur et les sections
        <code class="directive"><a href="../mod/core.html#virtualhost">&lt;Virtualhost&gt;</a></code>).
        Tout ce processus s'exécute au cours de la phase de traduction URL
        vers nom de fichier.</p>
    
        <p>Quelques étapes plus loin, une fois les répertoires de données
        finaux trouvés, les directives de configuration de niveau répertoire
        (fichiers <code>.htaccess</code> et sections <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>) sont appliquées. Ce processus
        s'exécute au cours de la phase Fixup.</p>
    
        <p>Dans tous ces cas, mod_rewrite réécrit le
        <code>REQUEST_URI</code> soit vers une nouvelle URL, soit vers un
        nom de fichier.</p>
    
        <p>Dans un contexte de niveau répertoire (autrement dit dans les
        fichiers <code>.htaccess</code> et les sections
        <code>Directory</code>), les règles de réécriture s'appliquent après
        la traduction de l'URL en nom de fichier. C'est pourquoi le chemin
        URL auquel mod_rewrite compare initialement les directives
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> est le
        chemin complet vers le nom de fichier traduit amputé de la partie
        répertoires (y compris le dernier slash).</p>
    
        <p>Un exemple : si les règles se trouvent dans
        /var/www/foo/.htaccess et si une requête pour /foo/bar/baz est
        traité, une expression comme ^bar/baz$ correspondra.</p>
    
        <p>Si une substitution intervient dans un contexte de répertoire,
        une nouvelle sous-requête interne est générée avec la nouvelle URL,
        ce qui relance le traitement des phases de la requête. Si la
        substitution est un chemin relatif, la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> détermine le chemin URL
        devant préfixer cette substitution. Dans un contexte de répertoire,
        il faut s'assurer de créer des règles qui
        n'effectueront pas de substitution au
        cours d'une passe ultérieure du processus de réécriture au niveau
        répertoire afin d'éviter les bouclages . Voir <a href="http://wiki.apache.org/httpd/RewriteLooping">Bouclage dans le
        processus de réécriture</a> pour une discussion plus détaillée à
        propos de ce problème.</p>
    
        <p>En conséquence de cette manipulation de l'URL , vous devrez
        pensez à confectionner différemment vos règles de réécriture dans un
        contexte de niveau répertoire. En particulier, rappelez-vous que le
        chemin de répertoire sera absent de l'URL que vos règles de
        réécriture verront. Voici quelques exemples qui permettront de
        clarifier les choses :</p>
    
        <table class="bordered">
    
            <tr>
                <th>Position de la règle</th>
                <th>Règle</th>
            </tr>
    
            <tr>
                <td>Section VirtualHost</td>
                <td>RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"</td>
            </tr>
    
            <tr>
                <td>Fichier .htaccess à la racine des documents</td>
                <td>RewriteRule "^images/(.+)\.jpg" "images/$1.gif"</td>
            </tr>
    
            <tr>
                <td>Fichier .htaccess dans le répertoire images</td>
                <td>RewriteRule "^(.+)\.jpg" "$1.gif"</td>
            </tr>
    
        </table>
    
        <p>Pour une étude plus approfondie de la manière dont mod_rewrite
        manipule les URLs dans les différents contextes, vous pouvez
        consulter les <a href="../mod/mod_rewrite.html#logging">entrées du
        journal</a> générées au cours du processus de réécriture.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="InternalRuleset" id="InternalRuleset">Traitement du jeu de règles</a></h2>
    
          <p>Maintenant, quand mod_rewrite se lance dans ces deux phases de
          l'API, il lit le jeu de règles configurées depuis la structure
          contenant sa configuration (qui a été elle-même créée soit au
          démarrage d'Apache pour le contexte du serveur, soit lors du
          parcours des répertoires par le noyau d'Apache pour le contexte de
          répertoire). Puis le moteur de réécriture est démarré avec le jeu
          de règles contenu (une ou plusieurs règles associées à leurs
          conditions). En lui-même, le mode opératoire du moteur de
          réécriture d'URLs est exactement le même dans les deux contextes
          de configuration. Seul le traitement du résultat final diffère.</p>
    
          <p>L'ordre dans lequel les règles sont définies est important car
          le moteur de réécriture les traite selon une chronologie
          particulière (et pas très évidente). Le principe est le suivant :
          le moteur de réécriture traite les règles (les directives <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>) les unes
          à la suite des autres, et lorsqu'une règle s'applique, il parcourt
          les éventuelles conditions (directives
          <code>RewriteCond</code>directives) associées.
          Pour des raisons historiques, les
          conditions précèdent les règles, si bien que le déroulement du
          contrôle est un peu compliqué. Voir la figure 1 pour plus de
          détails.</p>
    <p class="figure">
          <img src="../images/rewrite_process_uri.png" alt="Flux des comparaisons des directives RewriteRule et RewriteCond" /><br />
          <dfn>Figure 1:</dfn>Déroulement du contrôle à travers le jeu de
          règles de réécriture
    </p>
          <p>L'URL est tout d'abord comparée au
          <em>Modèle</em> de chaque règle. Lorsqu'une règle ne s'applique
          pas, mod_rewrite stoppe immédiatement le traitement de cette règle
          et passe à la règle suivante. Si l'URL correspond au
          <em>Modèle</em>, mod_rewrite recherche la présence de conditions
          correspondantes (les directives Rewritecond apparaissant dans la
          configuration juste
          avant les règles de réécriture). S'il n'y en a pas, mod_rewrite remplace
          l'URL par une chaîne élaborée à partir de la chaîne de
          <em>Substitution</em>, puis passe à la règle suivante. Si des
          conditions sont présentes, mod_rewrite lance un bouclage
          secondaire afin de les traiter selon l'ordre dans lequel elles
          sont définies. La logique de traitement des conditions est
          différente : on ne compare pas l'URL à un modèle. Une chaîne de
          test <em>TestString</em> est tout d'abord élaborée en développant
          des variables, des références arrières, des recherches dans des
          tables de correspondances, etc..., puis cette chaîne de test est
          comparée au modèle de condition <em>CondPattern</em>. Si le modèle
          ne correspond pas, les autres conditions du jeu ne sont pas
          examinées et la règle correspondante ne s'applique pas. Si le
          modèle correspond, la condition suivante est examinée et ainsi de
          suite jusqu'à la dernière condition. Si toutes les conditions sont
          satisfaites, le traitement de la règle en cours se poursuit avec
          le remplacement de l'URL par la chaîne de <em>Substitution</em>.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/tech.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/tech.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/tech.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/avoid.html.en������������������������������������������������������0000664�0001751�0001751�00000037457�14737241666�021141� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>When not to use mod_rewrite - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>When not to use mod_rewrite</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/avoid.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/avoid.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
    perhaps one of the most important concepts about <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> - namely,
    when to avoid using it.</p>
    
    <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> should be considered a last resort, when other
    alternatives are found wanting. Using it when there are simpler
    alternatives leads to configurations which are confusing, fragile, and
    hard to maintain. Understanding what other alternatives are available is
    a very important step towards <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> mastery.</p>
    
    <p>Note that many of these examples won't work unchanged in your
    particular server configuration, so it's important that you understand
    them, rather than merely cutting and pasting the examples into your
    configuration.</p>
    
    <p>The most common situation in which <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> is
    the right tool is when the very best solution requires access to the
    server configuration files, and you don't have that access. Some
    configuration directives are only available in the server configuration
    file. So if you are in a hosting situation where you only have .htaccess
    files to work with, you may need to resort to
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#redirect">Simple Redirection</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#alias">URL Aliasing</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#vhosts">Virtual Hosting</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#proxy">Simple Proxying</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#setenv">Environment Variable Testing</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">Simple Redirection</a></h2>
    
    
    <p><code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> provides the <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code> and <code class="directive"><a href="../mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> directives, which provide a
    means to redirect one URL to another. This kind of simple redirection of
    one URL, or a class of URLs, to somewhere else, should be accomplished
    using these directives rather than <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>. <code>RedirectMatch</code>
    allows you to include a regular expression in your redirection criteria,
    providing many of the benefits of using <code>RewriteRule</code>.</p>
    
    <p>A common use for <code>RewriteRule</code> is to redirect an entire
    class of URLs. For example, all URLs in the <code>/one</code> directory
    must be redirected to <code>http://one.example.com/</code>, or perhaps
    all <code>http</code> requests must be redirected to
    <code>https</code>.</p>
    
    <p>These situations are better handled by the <code>Redirect</code>
    directive. Remember that <code>Redirect</code> preserves path
    information. That is to say, a redirect for a URL <code>/one</code> will
    also redirect all URLs under that, such as <code>/one/two.html</code>
    and <code>/one/three/four.html</code>.</p>
    
    <p>To redirect URLs under <code>/one</code> to
    <code>http://one.example.com</code>, do the following:</p>
    
    <pre class="prettyprint lang-config">Redirect "/one/" "http://one.example.com/"</pre>
    
    
    <p>To redirect one hostname to another, for example
    <code>example.com</code> to <code>www.example.com</code>, see the
    <a href="remapping.html#canonicalhost">Canonical Hostnames</a>
    recipe.</p>
    
    <p>To redirect <code>http</code> URLs to <code>https</code>, do the
    following:</p>
    
    <pre class="prettyprint lang-config">&lt;VirtualHost *:80&gt;
        ServerName www.example.com
        Redirect "/" "https://www.example.com/"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:443&gt;
        ServerName www.example.com
        # ... SSL configuration goes here
    &lt;/VirtualHost&gt;</pre>
    
    
    <p>The use of <code>RewriteRule</code> to perform this task may be
    appropriate if there are other <code>RewriteRule</code> directives in
    the same scope. This is because, when there are <code>Redirect</code>
    and <code>RewriteRule</code> directives in the same scope, the
    <code>RewriteRule</code> directives will run first, regardless of the
    order of appearance in the configuration file.</p>
    
    <p>In the case of the <em>http-to-https</em> redirection, the use of
    <code>RewriteRule</code> would be appropriate if you don't have access
    to the main server configuration file, and are obliged to perform this
    task in a <code>.htaccess</code> file instead.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="alias" id="alias">URL Aliasing</a></h2>
    <p>The <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> directive
    provides mapping from a URI to a directory - usually a directory outside
    of your <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>. Although it
    is possible to perform this mapping with <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>,
    <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> is the preferred method, for
    reasons of simplicity and performance.</p>
    
    <div class="example"><h3>Using Alias</h3><pre class="prettyprint lang-config">Alias "/cats" "/var/www/virtualhosts/felines/htdocs"</pre>
    </div>
    
    <p>
    The use of <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> to perform this mapping may be
    appropriate when you do not have access to the server configuration
    files. Alias may only be used in server or virtualhost context, and not
    in a <code>.htaccess</code> file.
    </p>
    
    <p>Symbolic links would be another way to accomplish the same thing, if
    you have <code>Options FollowSymLinks</code> enabled on your
    server.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="vhosts" id="vhosts">Virtual Hosting</a></h2>
    <p>Although it is possible to handle <a href="vhosts.html">virtual hosts
    with mod_rewrite</a>, it is seldom the right way. Creating individual
    <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> blocks is
    almost always the right way to go. In the
    event that you have an enormous number of virtual hosts, consider using
    <code class="module"><a href="../mod/mod_vhost_alias.html">mod_vhost_alias</a></code> to create these hosts automatically.</p>
    
    <p>Modules such as <code class="module"><a href="../mod/mod_macro.html">mod_macro</a></code> are
    also useful for creating a large number of virtual hosts dynamically.</p>
    
    <p>Using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> for vitualhost creation may be
    appropriate if you are using a hosting service that does not provide
    you access to the server configuration files, and you are therefore
    restricted to configuration using <code>.htaccess</code> files.</p>
    
    <p>See the <a href="vhosts.html">virtual hosts with mod_rewrite</a>
    document for more details on how you might accomplish this if it still
    seems like the right approach.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Simple Proxying</a></h2>
    
    <p><code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> provides the <a href="flags.html#flag_p">[P]</a> flag to pass rewritten URIs through
    <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>.</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^/?images(.*)" "http://imageserver.local/images$1" [P]</pre>
    
    
    <p>However, in many cases, when there is no actual pattern matching
    needed, as in the example shown above, the <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code> directive is a better choice.
    The example here could be rendered as:</p>
    
    <pre class="prettyprint lang-config">ProxyPass "/images/" "http://imageserver.local/images/"</pre>
    
    
    <p>Note that whether you use <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> or <code class="directive"><a href="../mod/mod_proxy.html#proxypass">ProxyPass</a></code>, you'll still need to use the
    <code class="directive"><a href="../mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> directive to
    catch redirects issued from the back-end server:</p>
    
    <pre class="prettyprint lang-config">ProxyPassReverse "/images/" "http://imageserver.local/images/"</pre>
    
    
    <p>You may need to use <code>RewriteRule</code> instead when there are
    other <code>RewriteRule</code>s in effect in the same scope, as a
    <code>RewriteRule</code> will usually take effect before a
    <code>ProxyPass</code>, and so may preempt what you're trying to
    accomplish.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setenv" id="setenv">Environment Variable Testing</a></h2>
    
    <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> is frequently used to take a particular
    action based on the presence or absence of a particular environment
    variable or request header. This can be done more efficiently using the
    <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code> directive.</p>
    
    <p>Consider, for example, the common scenario where
    <code class="directive">RewriteRule</code> is used to enforce a canonical
    hostname, such as <code>www.example.com</code> instead of
    <code>example.com</code>. This can be done using the <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code> directive, as shown here:</p>
    
    <pre class="prettyprint lang-config">&lt;If "req('Host') != 'www.example.com'"&gt;
        Redirect "/" "http://www.example.com/"
    &lt;/If&gt;</pre>
    
    
    <p>This technique can be used to take actions based on any request
    header, response header, or environment variable, replacing
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> in many common scenarios.</p>
    
    <p>See especially the <a href="../expr.html">expression evaluation
    documentation</a> for a overview of what types of expressions you can
    use in <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code> sections,
    and in certain other directives.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/avoid.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/avoid.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/avoid.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/intro.html.en������������������������������������������������������0000664�0001751�0001751�00000054242�14737241666�021161� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache mod_rewrite Introduction - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Apache mod_rewrite Introduction</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/intro.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/intro.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It
    describes the basic concepts necessary for use of
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Other documents go into greater detail,
    but this doc should help the beginner get their feet wet.
    </p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#regex">Regular Expressions</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewriterule">RewriteRule Basics</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#flags">Rewrite Flags</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewritecond">Rewrite Conditions</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewritemap">Rewrite maps</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#htaccess">.htaccess files</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    <p>The Apache module <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 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.</p>
    
    <p>This document attempts to give sufficient background so that what
    follows is understood, rather than just copied blindly.
    </p>
    
    <p>Remember that many common URL-manipulation tasks don't require the
    full power and complexity of <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. For simple
    tasks, see <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> and the documentation
    on <a href="../urlmapping.html">mapping URLs to the
    filesystem</a>.</p>
    
    <p>Finally, before proceeding, be sure to configure
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>'s log level to one of the trace levels using
    the <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> directive. Although this
    can give an overwhelming amount of information, it is indispensable in
    debugging problems with <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> configuration, since
    it will tell you exactly how each rule is processed.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="regex" id="regex">Regular Expressions</a></h2>
    
    <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> uses the <a href="http://pcre.org/">Perl Compatible
    Regular Expression</a> vocabulary. In this document, we do not attempt
    to provide a detailed reference to regular expressions. For that, we
    recommend the <a href="http://pcre.org/pcre.txt">PCRE man pages</a>, the
    <a href="http://perldoc.perl.org/perlre.html">Perl regular
    expression man page</a>, and <a href="http://shop.oreilly.com/product/9780596528126.do">Mastering
    Regular Expressions, by Jeffrey Friedl</a>.</p>
    
    <p>In this document, we attempt to provide enough of a regex vocabulary
    to get you started, without being overwhelming, in the hope that
    <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>s will be scientific
    formulae, rather than magical incantations.</p>
    
    <h3><a name="regexvocab" id="regexvocab">Regex vocabulary</a></h3>
    
    <p>The following are the minimal building blocks you will need, in order
    to write regular expressions and <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>s. They certainly do not
    represent a complete regular expression vocabulary, but they are a good
    place to start, and should help you read basic regular expressions, as
    well as write your own.</p>
    
    <table>
    <tr>
    <th>Character</th>
    <th>Meaning</th>
    <th>Example</th>
    </tr>
    
    <tr>
        <td><code>.</code></td>
        <td>Matches any single character</td>
        <td><code>c.t</code> will match <code>cat</code>, <code>cot</code>,
          <code>cut</code>, etc</td>
    </tr>
    <tr>
        <td><code>+</code></td>
        <td>Repeats the previous match one or more times</td>
        <td><code>a+</code> matches <code>a</code>, <code>aa</code>,
          <code>aaa</code>, etc</td>
    </tr>
    <tr>
        <td><code>*</code></td>
        <td>Repeats the previous match zero or more times</td>
        <td><code>a*</code> matches all the same things <code>a+</code> matches,
          but will also match an empty string</td>
    </tr>
    <tr>
        <td><code>?</code></td>
        <td>Makes the match optional</td>
        <td><code>colou?r</code> will match <code>color</code> and
        <code>colour</code></td>
    </tr>
    <tr>
        <td><code>\</code></td>
        <td>Escape the next character</td>
        <td><code>\.</code> will match <code>.</code> (dot) and not <em>any single
        character</em> as explain above</td>
    </tr>
    <tr>
        <td><code>^</code></td>
        <td>Called an anchor, matches the beginning of the string</td>
        <td><code>^a</code> matches a string that begins with <code>a</code></td>
    </tr>
    <tr>
        <td><code>$</code></td>
        <td>The other anchor, this matches the end of the string</td>
        <td><code>a$</code> matches a string that ends with <code>a</code></td>
    </tr>
    <tr>
        <td><code>( )</code></td>
        <td>Groups several characters into a single unit, and captures a match
          for use in a backreference</td>
        <td><code>(ab)+</code> matches <code>ababab</code> - that is, the
          <code>+</code> applies to the group. For more on backreferences see
          <a href="#InternalBackRefs">below</a></td>
    </tr>
    <tr>
        <td><code>[ ]</code></td>
        <td>A character class - matches one of the characters</td>
        <td><code>c[uoa]t</code> matches <code>cut</code>, <code>cot</code> or
          <code>cat</code></td>
    </tr>
    <tr>
        <td><code>[^ ]</code></td>
        <td>Negative character class - matches any character not specified</td>
        <td><code>c[^/]t</code> matches <code>cat</code> or <code>c=t</code> but
          not <code>c/t</code></td></tr>
    </table>
    
    <p>In <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> the <code>!</code> character can be
    used before a regular expression to negate it. This is, a string will
    be considered to have matched only if it does not match the rest of
    the expression.</p>
    
    
    
    <h3><a name="InternalBackRefs" id="InternalBackRefs">Regex Back-Reference Availability</a></h3>
    
          <p>One important thing here has to be remembered: Whenever you
          use parentheses in <em>Pattern</em> or in one of the
          <em>CondPattern</em>, back-references are internally created
          which can be used with the strings <code>$N</code> and
          <code>%N</code> (see below). These are available for creating
          the <em>Substitution</em> parameter of a
          <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> or
          the <em>TestString</em> parameter of a
          <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>.</p>
          <p>  Captures in the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> patterns are (counterintuitively) available to
           all preceding
          <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> directives,
          because the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
          expression is evaluated before the individual conditions.</p>
    
          <p>Figure 1 shows to which
          locations the back-references are transferred for expansion as
          well as illustrating the flow of the RewriteRule, RewriteCond
          matching. In the next chapters, we will be exploring how to use
          these back-references, so do not fret if it seems a bit alien
          to you at first.
          </p>
    
    <p class="figure">
          <img src="../images/rewrite_backreferences.png" alt="Flow of RewriteRule and RewriteCond matching" /><br />
          <dfn>Figure 1:</dfn> The back-reference flow through a rule.<br />
          In this example, a request for <code>/test/1234</code> would be transformed into <code>/admin.foo?page=test&amp;id=1234&amp;host=admin.example.com</code>.
    </p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewriterule" id="rewriterule">RewriteRule Basics</a></h2>
    <p>A <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> consists
    of three arguments separated by spaces. The arguments are</p>
    <ol>
    <li><var>Pattern</var>: which incoming URLs should be affected by the rule;</li>
    <li><var>Substitution</var>: where should the matching requests be sent;</li>
    <li><var>[flags]</var>: options affecting the rewritten request.</li>
    </ol>
    
    <p>The <var>Pattern</var> is a <a href="#regex">regular expression</a>.
    It is initially (for the first rewrite rule or until a substitution occurs)
    matched against the URL-path of the incoming request (the part after the
    hostname but before any question mark indicating the beginning of a query
    string) or, in per-directory context, against the request's path relative
    to the directory for which the rule is defined. Once a substitution has
    occurred, the rules that follow are matched against the substituted
    value.
    </p>
    
    <p class="figure">
          <img src="../images/syntax_rewriterule.png" alt="Syntax of the RewriteRule directive" /><br />
          <dfn>Figure 2:</dfn> Syntax of the RewriteRule directive.
    </p>
    
    
    <p>The <var>Substitution</var> can itself be one of three things:</p>
    
    <dl>
    <dt>1. A full filesystem path to a resource</dt>
    <dd>
    <pre class="prettyprint lang-config">RewriteRule "^/games" "/usr/local/games/web/puzzles.html"</pre>
    
    <p>This maps a request to an arbitrary location on your filesystem, much
    like the <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> directive.</p>
    </dd>
    
    <dt>2. A web-path to a resource</dt>
    <dd>
    <pre class="prettyprint lang-config">RewriteRule "^/games$" "/puzzles.html"</pre>
    
    <p>If <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> is set
    to <code>/usr/local/apache2/htdocs</code>, then this directive would
    map requests for <code>http://example.com/games</code> to the
    path <code>/usr/local/apache2/htdocs/puzzles.html</code>.</p>
    
    </dd>
    
    <dt>3. An absolute URL</dt>
    <dd>
    <pre class="prettyprint lang-config">RewriteRule "^/product/view$" "http://site2.example.com/seeproduct.html" [R]</pre>
    
    <p>This tells the client to make a new request for the specified URL.</p>
    </dd>
    </dl>
    
    <div class="warning">Note that <strong>1</strong> and <strong>2</strong> have exactly the same syntax. The difference between them is that in the case of <strong>1</strong>, the top level of the target path (i.e., <code>/usr/</code>) exists on the filesystem, where as in the case of <strong>2</strong>, it does not. (i.e., there's no <code>/bar/</code> as a root-level directory in the filesystem.)</div>
    
    <p>The <var>Substitution</var> can also
    contain <em>back-references</em> to parts of the incoming URL-path
    matched by the <var>Pattern</var>. Consider the following:</p>
    <pre class="prettyprint lang-config">RewriteRule "^/product/(.*)/view$" "/var/web/productdb/$1"</pre>
    
    <p>The variable <code>$1</code> will be replaced with whatever text
    was matched by the expression inside the parenthesis in
    the <var>Pattern</var>. For example, a request
    for <code>http://example.com/product/r14df/view</code> will be mapped
    to the path <code>/var/web/productdb/r14df</code>.</p>
    
    <p>If there is more than one expression in parenthesis, they are
    available in order in the
    variables <code>$1</code>, <code>$2</code>, <code>$3</code>, and so
    on.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="flags" id="flags">Rewrite Flags</a></h2>
    <p>The behavior of a <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> can be modified by the
    application of one or more flags to the end of the rule. For example, the
    matching behavior of a rule can be made case-insensitive by the
    application of the <code>[NC]</code> flag:
    </p>
    <pre class="prettyprint lang-config">RewriteRule "^puppy.html" "smalldog.html" [NC]</pre>
    
    
    <p>For more details on the available flags, their meanings, and
    examples, see the <a href="flags.html">Rewrite Flags</a> document.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewritecond" id="rewritecond">Rewrite Conditions</a></h2>
    <p>One or more <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
    directives can be used to restrict the types of requests that will be
    subject to the
    following <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>. The
    first argument is a variable describing a characteristic of the
    request, the second argument is a <a href="#regex">regular
    expression</a> that must match the variable, and a third optional
    argument is a list of flags that modify how the match is evaluated.</p>
    
    <p class="figure">
          <img src="../images/syntax_rewritecond.png" alt="Syntax of the RewriteCond directive" /><br />
          <dfn>Figure 3:</dfn> Syntax of the RewriteCond directive
    </p>
    
    <p>For example, to send all requests from a particular IP range to a
    different server, you could use:</p>
    <pre class="prettyprint lang-config">RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
    RewriteRule "(.*)"           "http://intranet.example.com$1"</pre>
    
    
    <p>When more than
    one <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> is
    specified, they must all match for
    the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to be
    applied. For example, to deny requests that contain the word "hack" in
    their query string, unless they also contain a cookie containing
    the word "go", you could use:</p>
    <pre class="prettyprint lang-config">RewriteCond "%{QUERY_STRING}" "hack"
    RewriteCond "%{HTTP_COOKIE}"  !go
    RewriteRule "."               "-"   [F]</pre>
    
    <p>Notice that the exclamation mark specifies a negative match, so the rule is only applied if the cookie does not contain "go".</p>
    
    <p>Matches in the regular expressions contained in
    the <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>s can be
    used as part of the <var>Substitution</var> in
    the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> using the
    variables <code>%1</code>, <code>%2</code>, etc. For example, this
    will direct the request to a different directory depending on the
    hostname used to access the site:</p>
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}" "(.*)"
    RewriteRule "^/(.*)"       "/sites/%1/$1"</pre>
    
    <p>If the request was for <code>http://example.com/foo/bar</code>,
    then <code>%1</code> would contain <code>example.com</code>
    and <code>$1</code> would contain <code>foo/bar</code>.</p>
    
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewritemap" id="rewritemap">Rewrite maps</a></h2>
    
    <p>The <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive
    provides a way to call an external function, so to speak, to do your
    rewriting for you. This is discussed in greater detail in the <a href="rewritemap.html">RewriteMap supplementary documentation</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">.htaccess files</a></h2>
    
    <p>Rewriting is typically configured in the main server configuration
    setting (outside any <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> section) or
    inside <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
    containers. This is the easiest way to do rewriting and is
    recommended. It is possible, however, to do rewriting
    inside <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>
    sections or <a href="../howto/htaccess.html"><code>.htaccess</code>
    files</a> at the expense of some additional complexity. This technique
    is called per-directory rewrites.</p>
    
    <p>The main difference with per-server rewrites is that the path
    prefix of the directory containing the <code>.htaccess</code> file is
    stripped before matching in
    the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>. In addition, the <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> should be used to assure the request is properly mapped.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/intro.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/intro.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/intro.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/index.html.fr.utf8�������������������������������������������������0000664�0001751�0001751�00000016331�14740503670�022012� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Le module Apache mod_rewrite - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Le module Apache mod_rewrite</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
           <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> permet de modifier les requêtes
           entrantes dynamiquement, en fonction de règles manipulant des <a href="intro.html#regex">expressions rationnelles</a>. Vous pouvez
           ainsi relier des URLs arbitraires à votre propre structure d'URLs
           interne comme vous le souhaitez.</p>
    
          <p>Il fournit un
          mécanisme de manipulation d'URL particulièrement souple et
          puissant en supportant un nombre illimité de règles et de
          conditions attachées à chaque règle. Les manipulations d'URLs
          peuvent dépendre de tests variés : les URLs peuvent
          être finement caractérisées en fonction de variables du serveur,
          de variables d'environnement, d'en-têtes HTTP, de repères
          temporels, de recherches dans des bases de données
          externes, ou même de requêtes vers des bases de données externes
          et de différents gestionnaires ou programmes externes.</p>
    
          <p>Les règles de réécriture peuvent agir sur l'ensemble des URLs (la partie chemin
          et la chaîne de paramètres) et peuvent être utilisées dans le contexte du serveur principal
          (<code>httpd.conf</code>), mais aussi dans le contexte des
          serveurs virtuels (sections <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>), ou dans le
          contexte des
          répertoires (fichiers <code>.htaccess</code> et blocs
          <code>&lt;Directory&gt;</code>. Le résultat
          réécrit peut conduire vers d'autres règles à un
          traitement secondaire interne, une redirection vers une requête
          externe ou même l'envoi vers un serveur mandataire, en fonction
          des  <a href="flags.html">drapeaux</a> que vous attachez aux
          règles</p>
    
    	<p>mod_rewrite étant très puissant, il peut par
    	conséquent être très complexe. Ce document
    	complète la <a href="../mod/mod_rewrite.html">documentation de
          référence du module mod_rewrite</a>, et est sensé alléger un
          peu cette complexité, et présenter des exemples largement
          commentés, ainsi que des situations courantes que vous
          pourrez traiter avec mod_rewrite. Mais nous voulons aussi vous
          montrer des situations où vous ne devrez pas utiliser
          mod_rewrite, et lui préférer d'autres
          fonctionnalités standard d'Apache, évitant ainsi
          d'entrer dans une complexité inutile.</p>
    
    <ul>
    <li><a href="../mod/mod_rewrite.html">documentation de
    référence de mod_rewrite</a></li>
    <li><a href="intro.html">Introduction aux expressions rationnelles et à
    mod_rewrite</a></li>
    <li><a href="remapping.html">Utilisation de mod_rewrite pour la
    redirection et la remise en correspondance avec le système de
    fichiers des URLs</a></li>
    <li><a href="access.html">Utilisation de mod_rewrite pour le
    contrôle d'accès</a></li>
    <li><a href="vhosts.html">Les serveurs virtuels dynamiques avec mod_rewrite</a></li>
    <li><a href="proxy.html">Les serveurs mandataires dynamiques avec mod_rewrite</a></li>
    <li><a href="rewritemap.html">Utilisation de  RewriteMap</a></li>
    <li><a href="advanced.html">Techniques avancées</a></li>
    <li><a href="avoid.html">Quand <strong>NE PAS</strong> utiliser mod_rewrite</a></li>
    <li><a href="flags.html">Drapeaux de réécriture</a></li>
    <li><a href="tech.html">Détails techniques</a></li>
    </ul>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation de
    référence de mod_rewrite</a></li><li><a href="../urlmapping.html">Mise en correspondance des URLs
    avec le système de fichiers</a></li><li><a href="http://wiki.apache.org/httpd/Rewrite">wiki mod_rewrite
    </a></li><li><a href="../glossary.html">Glossaire</a></li></ul></div>
    </div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/rewritemap.html.fr.utf8��������������������������������������������0000664�0001751�0001751�00000066131�14740503670�023065� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Utilisation de RewriteMap - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Utilisation de RewriteMap</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/rewritemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/rewritemap.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
        <p>Ce document est un complément à la <a href="../mod/mod_rewrite.html">documentation de référence</a> du
        module <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il décrit l'utilisation de la
        directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>, et
        fournit des exemples pour chacun des différents types de
        <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>.</p>
    
        <div class="warning">Notez que la plupart de ces exemples ne
        fonctionneront pas en l'état dans le contexte de votre configuration
        particulière ; vous devez donc vous attacher à les
        comprendre, plutôt que de simplement les insérer dans votre
        configuration par copier/coller.</div>
    
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#int">int: Fonction interne</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#txt">txt: tables de correspondances au format texte</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rnd">rnd: Fichier texte à valeurs de substitution multiples
        choisies de manière aléatoire</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbm">dbm: Fichier condensé DBM</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#prg">prg: Programme de réécriture externe</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbd">dbd ou fastdbd: requête SQL</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#summary">Résumé</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module
      mod_rewrite</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="remapping.html">Redirection et remise en
      correspondance</a></li><li><a href="access.html">Contrôle d'accès</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Mise en cache</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
        
    
       <p>
       La directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
       définit une fonction externe qui peut être appelée depuis une
       directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> ou
       <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> pour
       accomplir une réécriture trop compliquée, ou trop spécialisée pour
       être effectuée à partir d'expressions rationnelles. Vous trouverez
       ci-dessous les différents types disponibles pour la source de
       données, ceux-ci étant par ailleurs énumérés dans la documentation de
       référence de <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>.</p>
    
       <p>La syntaxe de la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> est la suivante
       :</p>
    
    <pre class="prettyprint lang-config">RewriteMap <em>MapName</em> <em>MapType</em>:<em>MapSource</em></pre>
    
    
        <p>L'argument <a id="mapfunc" name="mapfunc"><em>MapName</em></a>
        est un nom arbitraire que vous associez à la table de
        correspondances, et que vous
        pourrez utilisez par la suite dans les directives de réécriture. Les
        recherches dans la table de correspondance s'effectuent en
        respectant cette syntaxe :</p>
    
        <p class="indent">
          <strong>
            <code>${</code> <em>nom-map</em> <code>:</code>
    	<em>clé-recherche</em>
            <code>}</code> <br /> <code>${</code> <em>nom-map</em> <code>:</code>
            <em>clé-recherche</em> <code>|</code> <em>DefaultValue</em> <code>}</code>
          </strong>
        </p>
    
        <p>Lorsque cette syntaxe est employée, la table de correspondances
        <em>nom-map</em> est consultée et la clé <em>clé-recherche</em>
        recherchée. Si la clé est trouvée, la fonction de recherche dans la
        table de correspondance est remplacée par <em>SubstValue</em>, ou
        par <em>DefaultValue</em> dans le cas contraire, ou par la chaîne
        vide si aucune <em>DefaultValue</em> n'a été spécifiée.</p>
    
        <p>Par exemple, vous pouvez définir une directive
        <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> comme suit :</p>
        <pre class="prettyprint lang-config">RewriteMap examplemap "txt:/path/to/file/map.txt"</pre>
    
        <p>Vous pourrez par la suite utiliser cette table de correspondances
        dans une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> comme suit :</p>
    <pre class="prettyprint lang-config">RewriteRule "^/ex/(.*)" "${examplemap:$1}"</pre>
    
    
    <p>Il est possible de spécifier une valeur par défaut qui sera utilisée
    si la recherche dans la table de correspondances est infructueuse :</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^/ex/(.*)" "${examplemap:$1|/not_found.html}"</pre>
    
    
    <div class="note"><h3>Contexte de répertoire et fichiers.htaccess</h3>
    <p>
    Vous ne pouvez utiliser la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> ni dans
    les sections <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>, ni dans les fichiers
    <code>.htaccess</code>. Vous devez déclarer la table de correspondances
    au niveau du serveur principal ou dans un contexte de serveur virtuel.
    En revanche, si vous ne pouvez pas déclarer la table dans une section
    &lt;Directory&gt; ou dans un fichier <code>.htaccess</code>, vous
    pourrez y faire référence dans ces contextes, une fois cette table
    créée.
    </p>
    </div>
    
    <p>Les sections suivantes décrivent les différents types de tables de
    correspondances <em>type-map</em> disponibles, et fournissent des
    exemples pour chacun d'entre eux.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="int" id="int">int: Fonction interne</a></h2>
        
    
        <p>Lorsque le type-map <code>int</code> est spécifié, la source est
        une des fonctions RewriteMap internes disponibles. Les développeurs
        de modules peuvent fournir des fonctions internes supplémentaires en
        les enregistrant via l'API <code>ap_register_rewrite_mapfunc</code>.
        Les fonctions fournies par défaut sont :
        </p>
    
        <ul>
          <li><strong>toupper</strong>:<br />
                 Met tous les caractères de la clé en majuscules.</li>
          <li><strong>tolower</strong>:<br />
                 Met tous les caractères de la clé en minuscules.</li>
          <li><strong>escape</strong>:<br />
                 Protège les caractères spéciaux de la clé en les
    	     transformant en leur code hexadécimal.</li>
          <li><strong>unescape</strong>:<br />
                 Retraduit les codes hexadécimaux de la clé en caractères
    	     spéciaux.</li>
        </ul>
    
        <p>
        Pour utiliser une de ces fonctions, créez une
        <code>RewriteMap</code> faisant référence à cette fonction int, et
        utilisez-la dans votre règle <code>RewriteRule</code> :
        </p>
    
        <p> <strong>Redirige un URI vers son équivalent en minuscules</strong></p>
        <pre class="prettyprint lang-config">RewriteMap lc int:tolower
    RewriteRule "(.*)" "${lc:$1}" [R]</pre>
    
    
        <div class="note">
        <p>Notez que cet exemple n'est fourni qu'à titre d'illustration,
        et ne constitue en aucun cas une recommandation. Si vous voulez
        rendre des URLs insensibles à la casse, vous devez plutôt vous
        tourner vers <code class="module"><a href="../mod/mod_speling.html">mod_speling</a></code>.
        </p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="txt" id="txt">txt: tables de correspondances au format texte</a></h2>
        
    
        <p>Lorsqu'un type-map <code>txt</code> est utilisé, la source-map
        est un chemin du système de fichiers vers un fichier de
        correspondances au format texte, contenant sur chaque ligne une
        paire clé/valeur séparées par un espace. Il est possible d'insérer
        des commentaires sous la forme de chaînes commençant par le caractère
        '#'.</p>
    
        <p>Voici un exemple d'entrées valides dans un fichier de
        correspondances :</p>
    
        <div class="example"><p><code>
          # Ligne de commentaires<br />
          <strong><em>clé</em> <em>valeur-substitution</em></strong><br />
          <strong><em>clé</em> <em>valeur-substitution</em></strong> # commentaire<br />
        </code></p></div>
    
        <p>Lorsque la table de correspondance fait l'objet d'une recherche,
        la valeur spécifiée est recherchée dans le premier champ, et si elle
        est trouvée, la valeur de substitution est renvoyée.</p>
    
        <p>Par exemple, nous pourrions utiliser un fichier de
        correspondances pour traduire des noms de produits en identifiants
        produits pour obtenir des URLs plus simples à mémoriser, en
        utilisant la recette suivante :</p>
    
        <p><strong>Product to ID configuration</strong></p>
        <pre class="prettyprint lang-config">RewriteMap product2id "txt:/etc/apache2/productmap.txt"
    RewriteRule "^/product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]</pre>
    
    
        <p>Nous supposons ici que le script <code>prods.php</code> sait quoi
        faire lorsqu'il reçoit un argument <code>id=NOTFOUND</code>, dans
        le cas où le produit ne se trouve pas dans la table de
        correspondances.</p>
    
        <p>Le fichier <code>/etc/apache2/map-produit.txt</code> contient ce
        qui suit :</p>
    
        <div class="example"><h3>Fichier de correspondances Produit - Identifiant</h3><p><code>
    ##<br />
    ##  map-produit.txt - Fichier de correspondances Produit - Identifiant<br />
    ##<br />
    <br />
    TELEVISION 993<br />
    STEREO     198<br />
    CANNE-A-PECHE 043<br />
    BALLON-BASKET 418<br />
    TELEPHONE  328
        </code></p></div>
    
        <p>Ainsi, lorsqu'une requête pour
        <code>http://example.com/produit/TELEVISION</code> arrive, la directive
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> s'applique, et la
        requête est transformée en interne en <code>/prods.php?id=993</code>.</p>
    
        <div class="note"><h3>Note: fichiers .htaccess</h3>
        L'exemple donné est conçu pour être utilisé dans un contexte de
        serveur principal ou de serveur virtuel. Si vous voulez l'utiliser
        dans un fichier <code>.htaccess</code>, vous devrez supprimer le
        slash de début dans le modèle de réécriture afin que ce dernier
        puisse correspondre à toute URL :
        <pre class="prettyprint lang-config">RewriteRule "^product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]</pre>
    
        </div>
    
        <div class="note"><h3>Recherches mises en cache</h3>
        <p>
        Les clés de recherche sont mises en cache par httpd jusqu'à ce que
        le <code>mtime</code> (date de modification) du fichier de
        correspondances soit modifié, ou que le serveur httpd soit
        redémarré, ce qui améliore les performances pour les tables de
        correspondances consultées par de nombreuses requêtes.
        </p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rnd" id="rnd">rnd: Fichier texte à valeurs de substitution multiples
        choisies de manière aléatoire</a></h2>
        
    
        <p>Lorsque le type-map spécifié est <code>rnd</code>, la source est
        un chemin du système de fichiers vers un fichier de correspondances
        au format texte dont chaque ligne contient une clé, et une ou
        plusieurs valeurs séparées par le caractère <code>|</code>. Si une
        clé convient, une des valeurs correspondantes sera choisie de
        manière aléatoire.</p>
    
        <p>Par exemple, vous pouvez utiliser le fichier de correspondances
        et les directives suivants pour implémenter une répartition de
        charge aléatoire entre plusieurs serveurs d'arrière-plan, par
        l'intermédiaire d'un mandataire inverse. Les images sont envoyées
        vers un des serveurs de l'ensemble 'statique', tandis que tout le
        reste est envoyé vers un des serveurs de l'ensemble 'dynamique'.</p>
    
        <div class="example"><h3>Fichier de correspondances</h3><p><code>
    ##<br />
    ##  map.txt -- table de réécriture<br />
    ##<br />
    <br />
    statique   www1|www2|www3|www4<br />
    dynamique  www5|www6
        </code></p></div>
    <p><strong>Directives de configuration</strong></p>
        <pre class="prettyprint lang-config">RewriteMap servers "rnd:/path/to/file/map.txt"
    
    RewriteRule "^/(.*\.(png|gif|jpg))" "http://${servers:static}/$1" [NC,P,L]
    RewriteRule "^/(.*)"                "http://${servers:dynamic}/$1" [P,L]</pre>
    
    
    
        <p>Ainsi, lorsqu'une image est demandée et que la première règle
        convient, <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> recherche la chaîne
        <code>statique</code> dans le fichier de correspondances qui
        renvoie un des noms de serveurs spécifiés de manière aléatoire,
        ce dernier étant utilisé dans la cible de la règle
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>.</p>
    
        <p>Si vous voulez qu'un des serveurs soit plus souvent sollicité que
        les autres (par exemple s'il possède plus de mémoire, et peut donc
        traiter d'avantage de requêtes), spécifiez-le plusieurs fois dans la
        liste des serveurs.</p>
    
        <div class="example"><p><code>
    statique   www1|www1|www2|www3|www4
        </code></p></div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbm" id="dbm">dbm: Fichier condensé DBM</a></h2>
        
    
        <p>Lorsque le type-map <code>dbm</code> est utilisé, la source est
        un chemin du système de fichiers vers un fichier de données DBM
        contenant des paires clé/valeur permettant d'effectuer la
        correspondance. Le fonctionnement est identique à celui du type-map
        <code>txt</code>, mais beaucoup plus rapide car un fichier DBM est
        indexé, alors qu'un fichier texte ne l'est pas. L'accès à la clé
        recherchée est donc plus rapide.</p>
    
        <p>Vous pouvez éventuellement spécifier un type dbm particulier :</p>
    
     <pre class="prettyprint lang-config">RewriteMap examplemap "dbm=sdbm:/etc/apache/mapfile.dbm"</pre>
    
    
        <p>Ce type peut être choisi parmi <code>sdbm</code>, <code>gdbm</code>,
        <code>ndbm</code> ou <code>db</code>. Il est
        cependant recommandé d'utiliser l'utilitaire <a href="../programs/httxt2dbm.html">httxt2dbm</a> fourni avec le
        serveur HTTP Apache, car il utilise la bibliothèque DBM appropriée,
        à savoir celle qui a été utilisée lors de la compilation de httpd.</p>
    
        <p>Pour créer un fichier dbm, créez tout d'abord un fichier de
        correspondances au format texte comme décrit dans la section <a href="#txt">txt</a>. Traitez ensuite ce fichier avec
        <code>httxt2dbm</code> :</p>
    
    <div class="example"><p><code>
    $ httxt2dbm -i fichier-map.txt -o fichier-map.map
    </code></p></div>
    
    <p>Vous pouvez alors faire référence au fichier obtenu dans votre
    directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> :</p>
    <pre class="prettyprint lang-config">RewriteMap mapname "dbm:/etc/apache/mapfile.map"</pre>
    
    
    <div class="note">
    <p>Notez qu'avec certains types dbm, plusieurs fichiers possédant le
    même nom de base sont créés. Par exemple, vous pouvez obtenir deux
    fichiers nommés <code>fichier-map.map.dir</code> et
    <code>fichier-map.map.pag</code>. Ceci est tout à fait normal, et vous
    ne devez utiliser que le nom de base <code>fichier-map.map</code> dans votre
    directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>.</p>
    </div>
    
    <div class="note"><h3>Mise en cache des recherches</h3>
    <p>
        Les clés de recherche sont mises en cache par httpd jusqu'à ce que
        le <code>mtime</code> (date de modification) du fichier de
        correspondances soit modifié, ou que le serveur httpd soit
        redémarré, ce qui améliore les performances pour les tables de
        correspondances consultées par de nombreuses requêtes.
    </p>
    </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="prg" id="prg">prg: Programme de réécriture externe</a></h2>
    
        <p>Lorque le type-map <code>prg</code> est spécifié, la source est
        un chemin du système de fichiers vers un programme exécutable
        destiné à effectuer la mise en correspondance. Il peut s'agir d'un
        fichier binaire compilé, ou d'un programme en langage interprété
        comme Perl ou Python.</p>
    
        <p>Ce programme est lancé une fois au démarrage du serveur HTTP
        Apache, puis communique avec le moteur de réécriture via
        <code>STDIN</code> et <code>STDOUT</code>. En d'autres termes, pour
        chaque recherche de correspondance, il reçoit un argument via
        <code>STDIN</code>, et doit renvoyer en guise de réponse une chaîne
        terminée par un caractère nouvelle-ligne sur <code>STDOUT</code>. Si
        la recherche de correspondance est infructueuse, le programme doit
        l'indiquer en retournant la chaîne de quatre caractères
        "<code>NULL</code>".</p>
    
        <p>Les programmes de réécriture externes ne sont pas lancés s'il
        n'ont pas été définis dans un contexte où la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriteengine">RewriteEngine</a></code> est définie à
        <code>on</code>.</p>
    
        <p>Par défaut, les programmes de réécriture externes sont lancés par
        l'utilisateur/groupe qui a démarré httpd. Pour changer ce comportement, il
        est possible sur les systèmes de style Unix de spécifier un autre couple
        utilisateur/groupe via le troisième argument de la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>, et ceci au format
        <code>utilisateur:groupe</code>.</p>
    
        <p>Cette fonctionnalité utilise le mutex <code>rewrite-map</code>
        nécessaire à la fiabilité des communications avec le programme. Le
        mécanisme de mutex et le fichier verrou peuvent être définis via la
        directive <code class="directive"><a href="../mod/core.html#mutex">Mutex</a></code>.</p>
    
        <p>Voici un exemple simple qui remplace tous les tirets par des
        caractères de soulignement dans l'URI de la requête.</p>
    
        <p><strong>Configuration de la réécriture</strong></p>
        <pre class="prettyprint lang-config">RewriteMap d2u "prg:/www/bin/dash2under.pl" apache:apache
    RewriteRule "-" "${d2u:%{REQUEST_URI}}"</pre>
    
    
        <p><strong>dash2under.pl</strong></p>
        <pre class="prettyprint lang-perl">    #!/usr/bin/perl
        $| = 1; # Turn off I/O buffering
        while (&lt;STDIN&gt;) {
            s/-/_/g; # Remplace tous les tirets par des caractères de soulignement
            print $_;
        }</pre>
    
    
    <div class="note"><h3>Mises en garde !</h3>
    <ul>
    <li>Votre programme doit être le plus
    simple possible. Si le programme se bloque, httpd va attendre
    indéfiniment une réponse de sa part, et par conséquent ne répondra plus
    aux requêtes.</li>
    <li>Assurez-vous de bien désactiver la mise en tampon dans votre
    programme. En Perl, ceci est effectué à la seconde ligne du script de
    l'exemple - <code>$| = 1;</code> - La syntaxe sera bien entendu
    différente dans
    d'autres langages. Si les entrées/sorties sont mises en tampon, httpd va
    attendre une sortie, et va par conséquent se bloquer.</li>
    <li>Rappelez-vous qu'il n'existe qu'une copie du programme lancé au
    démarrage du serveur, et que toutes les requêtes vont devoir passer par
    ce goulot d'étranglement. Ceci peut provoquer des ralentissements
    significatifs si de nombreuses requêtes doivent être traitées, ou si le
    script lui-même est très lent.</li>
    </ul>
    </div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbd" id="dbd">dbd ou fastdbd: requête SQL</a></h2>
        
    
        <p>Lorsque le type-map <code>dbd</code> ou <code>fastdbd</code> est
        spécifié, la source est une requête SQL SELECT qui reçoit un
        argument et renvoie une seule valeur.</p>
    
        <p>Pour que cette requête puisse être exécutée,
        <code class="module"><a href="../mod/mod_dbd.html">mod_dbd</a></code> doit être configuré pour attaquer la base
        de données concernée.</p>
    
        <p>Ce type-map existe sous deux formes. Avec le type-map
        <code>dbd</code>, la requête est exécutée à chaque demande, tandis
        qu'avec le type-map <code>fastdbd</code>, les recherches dans la
        base de données sont mises en cache en interne. <code>fastdbd</code>
        est donc plus efficace et donc plus rapide ; par contre, il ne
        tiendra pas compte des modifications apportées à la base de données
        jusqu'à ce que le serveur soit redémarré.</p>
    
        <p>Si une requête renvoie plusieurs enregistrements, un de ceux-ci
        sera sélectionné aléatoirement.</p>
    
        <div class="example"><h3>Exemple</h3><pre class="prettyprint lang-config">RewriteMap ma-requete "fastdbd:SELECT destination FROM rewrite WHERE source = %s"</pre>
    </div>
    
        <div class="note"><h3>Note</h3>
        <p>Le nom de la requête est transmis au pilote de base de données en tant
        que label pour une requête SQL préparée, et doit donc respecter toutes les
        règles imposées par votre base de données (comme la sensibilité à la casse).</p></div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="summary" id="summary">Résumé</a></h2>
        
    
        <p>La directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> peut apparaître
        plusieurs fois. Utilisez une directive
        <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> pour chaque fonction de mise en
        correspondance pour déclarer son fichier de correspondances.</p>
    
        <p>Bien que l'on ne puisse pas <strong>déclarer</strong> de fonction
        de mise en correspondance dans un contexte de répertoire (fichier
        <code>.htaccess</code> ou section <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code>), il est
        possible d'utiliser cette fonction dans un tel contexte.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/rewritemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/rewritemap.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/rewritemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/advanced.html.en���������������������������������������������������0000664�0001751�0001751�00000037657�14737241666�021606� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Advanced Techniques with mod_rewrite - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Advanced Techniques with mod_rewrite</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/advanced.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/advanced.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It provides
    a few advanced techniques using mod_rewrite.</p>
    
    <div class="warning">Note that many of these examples won't work unchanged in your
    particular server configuration, so it's important that you understand
    them, rather than merely cutting and pasting the examples into your
    configuration.</div>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#sharding">URL-based sharding across multiple backends</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#on-the-fly-content">On-the-fly Content-Regeneration</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#load-balancing">Load Balancing</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#structuredhomedirs">Structured Userdirs</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#redirectanchors">Redirecting Anchors</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#time-dependent">Time-Dependent Rewriting</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#setenvvars">Set Environment Variables Based On URL Parts</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="sharding" id="sharding">URL-based sharding across multiple backends</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>A common technique for distributing the burden of
          server load or storage space is called "sharding".
          When using this method, a front-end server will use the
          url to consistently "shard" users or objects to separate
          backend servers.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>A mapping is maintained, from users to target servers, in
          external map files. They look like:</p>
    
    <div class="example"><p><code>
    user1  physical_host_of_user1<br />
    user2  physical_host_of_user2<br />
    # ... and so on
    </code></p></div>
    
      <p>We put this into a <code>map.users-to-hosts</code> file. The
        aim is to map;</p>
    
    <div class="example"><p><code>
    /u/user1/anypath
    </code></p></div>
    
      <p>to</p>
    
    <div class="example"><p><code>
    http://physical_host_of_user1/u/user/anypath
    </code></p></div>
    
          <p>thus every URL path need not be valid on every backend physical
          host. The following ruleset does this for us with 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:</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteMap    users-to-hosts      "txt:/path/to/map.users-to-hosts"
    RewriteRule   "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"</pre>
    
        </dd>
      </dl>
    
      <p>See the <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
      documentation and the <a href="./rewritemap.html">RewriteMap HowTo</a>
      for more discussion of the syntax of this directive.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="on-the-fly-content" id="on-the-fly-content">On-the-fly Content-Regeneration</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>We wish to dynamically generate content, but store it
          statically once it is generated. This rule will check for the
          existence of the static file, and if it's not there, generate
          it. The static files can be removed periodically, if desired (say,
          via cron) and will be regenerated on demand.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          This is done via the following ruleset:
    
    <pre class="prettyprint lang-config"># This example is valid in per-directory context only
    RewriteCond "%{REQUEST_URI}"   "!-U"
    RewriteRule "^(.+)\.html$"     "/regenerate_page.cgi"   [PT,L]</pre>
    
    
        <p>The <code>-U</code> operator determines whether the test string
        (in this case, <code>REQUEST_URI</code>) is a valid URL. It does
        this via a subrequest. In the event that this subrequest fails -
        that is, the requested resource doesn't exist - this rule invokes
        the CGI program <code>/regenerate_page.cgi</code>, which generates
        the requested resource and saves it into the document directory, so
        that the next time it is requested, a static copy can be served.</p>
    
        <p>In this way, documents that are infrequently updated can be served in
        static form. if documents need to be refreshed, they can be deleted
        from the document directory, and they will then be regenerated the
        next time they are requested.</p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="load-balancing" id="load-balancing">Load Balancing</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>We wish to randomly distribute load across several servers
          using mod_rewrite.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We'll use <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> and a list of servers
          to accomplish this.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteMap lb        "rnd:/path/to/serverlist.txt"
    RewriteRule "^/(.*)" "http://${lb:servers}/$1"     [P,L]</pre>
    
    
    <p><code>serverlist.txt</code> will contain a list of the servers:</p>
    
    <div class="example"><p><code>
    ## serverlist.txt<br />
    <br />
    servers one.example.com|two.example.com|three.example.com<br />
    </code></p></div>
    
    <p>If you want one particular server to get more of the load than the
    others, add it more times to the list.</p>
    
       </dd>
    
       <dt>Discussion</dt>
       <dd>
    <p>Apache comes with a load-balancing module -
    <code class="module"><a href="../mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> - which is far more flexible and
    featureful than anything you can cobble together using mod_rewrite.</p>
       </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="structuredhomedirs" id="structuredhomedirs">Structured Userdirs</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>Some sites with thousands of users use a
          structured homedir layout, <em>i.e.</em> each homedir is in a
          subdirectory which begins (for instance) with the first
          character of the username. So, <code>/~larry/anypath</code>
          is <code>/home/<strong>l</strong>/larry/public_html/anypath</code>
          while <code>/~waldo/anypath</code> is
          <code>/home/<strong>w</strong>/waldo/public_html/anypath</code>.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We use the following ruleset to expand the tilde URLs
          into the above layout.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/~(<strong>([a-z])</strong>[a-z0-9]+)(.*)"  "/home/<strong>$2</strong>/$1/public_html$3"</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirectanchors" id="redirectanchors">Redirecting Anchors</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
        <p>By default, redirecting to an HTML anchor doesn't work,
        because mod_rewrite escapes the <code>#</code> character,
        turning it into <code>%23</code>. This, in turn, breaks the
        redirection.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>Use the <code>[NE]</code> flag on the
          <code>RewriteRule</code>. NE stands for No Escape.
          </p>
        </dd>
    
        <dt>Discussion:</dt>
        <dd>This technique will of course also work with other
        special characters that mod_rewrite, by default, URL-encodes.</dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="time-dependent" id="time-dependent">Time-Dependent Rewriting</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>We wish to use mod_rewrite to serve different content based on
          the time of day.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>There are a lot of variables named <code>TIME_xxx</code>
          for rewrite conditions. In conjunction with the special
          lexicographic comparison patterns <code>&lt;STRING</code>,
          <code>&gt;STRING</code> and <code>=STRING</code> we can
          do time-dependent redirects:</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" "&gt;0700"
    RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" "&lt;1900"
    RewriteRule   "^foo\.html$"             "foo.day.html" [L]
    RewriteRule   "^foo\.html$"             "foo.night.html"</pre>
    
    
          <p>This provides the content of <code>foo.day.html</code>
          under the URL <code>foo.html</code> from
          <code>07:01-18:59</code> and at the remaining time the
          contents of <code>foo.night.html</code>.</p>
    
          <div class="warning"><code class="module"><a href="../mod/mod_cache.html">mod_cache</a></code>, intermediate proxies
          and browsers may each cache responses and cause the either page to be
          shown outside of the time-window configured.
          <code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> may be used to control this
          effect. You are, of course, much better off simply serving the
          content dynamically, and customizing it based on the time of day.</div>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setenvvars" id="setenvvars">Set Environment Variables Based On URL Parts</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>At times, we want to maintain some kind of status when we
          perform a rewrite. For example, you want to make a note that
          you've done that rewrite, so that you can check later to see if a
          request came via that rewrite. One way to do this is by setting an
          environment variable.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>Use the [E] flag to set an environment variable.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/horse/(.*)"   "/pony/$1" [E=<strong>rewritten:1</strong>]</pre>
    
    
        <p>Later in your ruleset you might check for this environment
        variable using a RewriteCond:</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{ENV:rewritten}" "=1"</pre>
    
    
        <p>Note that environment variables do not survive an external
        redirect. You might consider using the [CO] flag to set a
        cookie. For per-directory and htaccess rewrites, where the final
        substitution is processed as an internal redirect, environment
        variables from the previous round of rewriting are prefixed with
        "REDIRECT_". </p>
    
        </dd>
      </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/advanced.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/advanced.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/advanced.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/index.html.en������������������������������������������������������0000664�0001751�0001751�00000015061�14737241666�021131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache mod_rewrite - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="../"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache mod_rewrite</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    
        <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> provides a way to modify incoming
        URL requests, dynamically, based on <a href="intro.html#regex">regular
        expression</a> rules. This allows you to map arbitrary URLs onto
        your internal URL structure in any way you like.</p>
    
          <p>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:
          server variables, environment variables, HTTP
          headers, time stamps, external database lookups, and various other
          external programs or handlers, can be used to achieve granular URL
          matching.</p>
    
          <p>Rewrite rules can operate on the full URLs, including the path-info
          and query string portions, and may be used in per-server context
          (<code>httpd.conf</code>), per-virtualhost context (<code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> blocks), or
          per-directory context (<code>.htaccess</code> files and <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> blocks). The
          rewritten result can lead to further rules, internal
          sub-processing, external request redirection, or proxy
          passthrough, depending on what <a href="flags.html">flags</a> you
          attach to the rules.</p>
    
          <p>Since mod_rewrite is so powerful, it can indeed be rather
          complex. This document supplements the <a href="../mod/mod_rewrite.html">reference documentation</a>, and
          attempts to allay some of that complexity, and provide highly
          annotated examples of common scenarios that you may handle with
          mod_rewrite. But we also attempt to show you when you should not
          use mod_rewrite, and use other standard Apache features instead,
          thus avoiding this unnecessary complexity.</p>
    
    
    <ul>
    <li><a href="../mod/mod_rewrite.html">mod_rewrite reference
    documentation</a></li>
    <li><a href="intro.html">Introduction to regular expressions and mod_rewrite</a></li>
    <li><a href="remapping.html">Using mod_rewrite for redirection and remapping of URLs</a></li>
    <li><a href="access.html">Using mod_rewrite to control access</a></li>
    <li><a href="vhosts.html">Dynamic virtual hosts with mod_rewrite</a></li>
    <li><a href="proxy.html">Dynamic proxying with mod_rewrite</a></li>
    <li><a href="rewritemap.html">Using RewriteMap</a></li>
    <li><a href="advanced.html">Advanced techniques</a></li>
    <li><a href="avoid.html">When <strong>NOT</strong> to use mod_rewrite</a></li>
    <li><a href="flags.html">RewriteRule Flags</a></li>
    <li><a href="tech.html">Technical details</a></li>
    </ul>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">mod_rewrite reference
    documentation</a></li><li><a href="../urlmapping.html">Mapping URLs to the Filesystem</a></li><li><a href="http://wiki.apache.org/httpd/Rewrite">mod_rewrite
    wiki</a></li><li><a href="../glossary.html">Glossary</a></li></ul></div>
    </div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="../tr/rewrite/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="../zh-cn/rewrite/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/rewritemap.html.en�������������������������������������������������0000664�0001751�0001751�00000060613�14737241666�022204� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Using RewriteMap - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Using RewriteMap</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/rewritemap.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/rewritemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
        <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
    the use of the <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive,
    and provides examples of each of the various <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> types.</p>
    
        <div class="warning">Note that many of these examples won't work unchanged in your
    particular server configuration, so it's important that you understand
    them, rather than merely cutting and pasting the examples into your
    configuration.</div>
    
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#int">int: Internal Function</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#txt">txt: Plain text maps</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rnd">rnd: Randomized Plain Text</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbm">dbm: DBM Hash File</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#prg">prg: External Rewriting Program</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#dbd">dbd or fastdbd: SQL Query</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#summary">Summary</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
        
    
       <p>
       The <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive
       defines an external function which can be called in the context of
       <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> or
       <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> directives to
       perform rewriting that is too complicated, or too specialized to be
       performed just by regular expressions. The source of this lookup can
       be any of the types listed in the sections below, and enumerated in
       the <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> reference
       documentation.</p>
    
       <p>The syntax of the <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
       directive is as follows:</p>
    
    <pre class="prettyprint lang-config">RewriteMap <em>MapName</em> <em>MapType</em>:<em>MapSource</em>
    </pre>
    
    
        <p>The <a id="mapfunc" name="mapfunc"><em>MapName</em></a> is an
        arbitrary name that you assign to the map, and which you will use in
        directives later on. Arguments are passed to the map via the
        following syntax:</p>
    
        <p class="indent">
          <strong>
            <code>${</code> <em>MapName</em> <code>:</code> <em>LookupKey</em>
            <code>}</code> <br /> <code>${</code> <em>MapName</em> <code>:</code>
            <em>LookupKey</em> <code>|</code> <em>DefaultValue</em> <code>}</code>
          </strong>
        </p>
    
        <p>When such a construct occurs, the map <em>MapName</em> is
          consulted and the key <em>LookupKey</em> is looked-up. If the
          key is found, the map-function construct is substituted by
          <em>SubstValue</em>. If the key is not found then it is
          substituted by <em>DefaultValue</em> or by the empty string
          if no <em>DefaultValue</em> was specified.</p>
    
        <p>For example, you can define a
          <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> as:</p>
        <pre class="prettyprint lang-config">RewriteMap examplemap "txt:/path/to/file/map.txt"</pre>
    
        <p>You would then be able to use this map in a
          <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> as follows:</p>
          <pre class="prettyprint lang-config">RewriteRule "^/ex/(.*)" "${examplemap:$1}"</pre>
    
    
    <p>A default value can be specified in the event that nothing is found
    in the map:</p>
    
    <pre class="prettyprint lang-config">RewriteRule "^/ex/(.*)" "${examplemap:$1|/not_found.html}"</pre>
    
    
    <div class="note"><h3>Per-directory and .htaccess context</h3>
    <p>
    The <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive may not be
    used in <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> sections or
    <code>.htaccess</code> files. You must
    declare the map in server or virtualhost context. You may use the map,
    once created, in your <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> and
    <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> directives in those
    scopes. You just can't <strong>declare</strong> it in those scopes.</p>
    </div>
    
    <p>The sections that follow describe the various <em>MapType</em>s that
    may be used, and give examples of each.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="int" id="int">int: Internal Function</a></h2>
        
    
        <p>When a MapType of <code>int</code> is used, the MapSource is one
        of the available internal <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
        functions.  Module authors can provide
        additional internal functions by registering them with the
        <code>ap_register_rewrite_mapfunc</code> API.
        The functions that are provided by default are:
        </p>
    
        <ul>
          <li><strong>toupper</strong>:<br />
                 Converts the key to all upper case.</li>
          <li><strong>tolower</strong>:<br />
                 Converts the key to all lower case.</li>
          <li><strong>escape</strong>:<br />
                 Translates special characters in the key to
                hex-encodings.</li>
          <li><strong>unescape</strong>:<br />
                 Translates hex-encodings in the key back to
                special characters.</li>
        </ul>
    
        <p>
        To use one of these functions, create a <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> referencing
        the int function, and then use that in your <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>:
        </p>
    
       <p> <strong>Redirect a URI to an all-lowercase version of itself</strong></p>
        <pre class="prettyprint lang-config">RewriteMap lc int:tolower
    RewriteRule "(.*)" "${lc:$1}" [R]</pre>
    
    
        <div class="note">
        <p>Please note that the example offered here is for
        illustration purposes only, and is not a recommendation. If you want
        to make URLs case-insensitive, consider using
        <code class="module"><a href="../mod/mod_speling.html">mod_speling</a></code> instead.
        </p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="txt" id="txt">txt: Plain text maps</a></h2>
        
    
        <p>When a MapType of <code>txt</code> is used, the MapSource is a filesystem path to a
        plain-text mapping file, containing one space-separated key/value pair
        per line. Optionally, a line may contain a comment, starting with
        a '#' character.</p>
    
        <p>A valid text rewrite map file will have the following syntax:</p>
    
        <div class="example"><p><code>
          # Comment line<br />
          <strong><em>MatchingKey</em> <em>SubstValue</em></strong><br />
          <strong><em>MatchingKey</em> <em>SubstValue</em></strong> # comment<br />
        </code></p></div>
    
        <p>When the <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> is invoked
        the argument is looked for in the
        first argument of a line, and, if found, the substitution value is
        returned.</p>
    
        <p>For example, we can use a mapfile to translate product names to
        product IDs for easier-to-remember URLs, using the following
        recipe:</p>
    <p><strong>Product to ID configuration</strong></p>
        <pre class="prettyprint lang-config">RewriteMap product2id "txt:/etc/apache2/productmap.txt"
    RewriteRule "^/product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]</pre>
    
    
        <p>We assume here that the <code>prods.php</code> script knows what
        to do when it received an argument of <code>id=NOTFOUND</code> when
        a product is not found in the lookup map.</p>
    
        <p>The file <code>/etc/apache2/productmap.txt</code> then contains
        the following:</p>
    
        <div class="example"><h3>Product to ID map</h3><p><code>
    ##<br />
    ##  productmap.txt - Product to ID map file<br />
    ##<br />
    <br />
    television 993<br />
    stereo     198<br />
    fishingrod 043<br />
    basketball 418<br />
    telephone  328
        </code></p></div>
    
        <p>Thus, when <code>http://example.com/product/television</code> is
        requested, the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> is
        applied, and the request
        is internally mapped to <code>/prods.php?id=993</code>.</p>
    
        <div class="note"><h3>Note: .htaccess files</h3>
        The example given is crafted to be used in server or virtualhost
        scope. If you're planning to use this in a <code>.htaccess</code>
        file, you'll need to remove the leading slash from the rewrite
        pattern in order for it to match anything:
        <pre class="prettyprint lang-config">RewriteRule "^product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]</pre>
    
        </div>
    
        <div class="note"><h3>Cached lookups</h3>
        <p>
        The looked-up keys are cached by httpd until the <code>mtime</code>
        (modified time) of the mapfile changes, or the httpd server is
        restarted. This ensures better performance on maps that are called
        by many requests.
        </p>
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rnd" id="rnd">rnd: Randomized Plain Text</a></h2>
        
    
        <p>When a MapType of <code>rnd</code> is used, the MapSource is a
        filesystem path to a plain-text mapping file, each line of which
        contains a key, and one or more values separated by <code>|</code>.
        One of these values will be chosen at random if the key is
        matched.</p>
    
        <p>For example, you can use the following map
        file and directives to provide a random load balancing between
        several back-end servers, via a reverse-proxy. Images are sent
        to one of the servers in the 'static' pool, while everything
        else is sent to one of the 'dynamic' pool.</p>
    
        <div class="example"><h3>Rewrite map file</h3><p><code>
    ##<br />
    ##  map.txt -- rewriting map<br />
    ##<br />
    <br />
    static   www1|www2|www3|www4<br />
    dynamic  www5|www6
        </code></p></div>
    <p><strong>Configuration directives</strong></p>
        <pre class="prettyprint lang-config">RewriteMap servers "rnd:/path/to/file/map.txt"
    
    RewriteRule "^/(.*\.(png|gif|jpg))" "http://${servers:static}/$1"  [NC,P,L]
    RewriteRule "^/(.*)"                "http://${servers:dynamic}/$1" [P,L]</pre>
    
    
        <p>So, when an image is requested and the first of these rules is
        matched, <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> looks up the string
        <code>static</code> in the map file, which returns one of the
        specified hostnames at random, which is then used in the
        <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> target.</p>
    
        <p>If you wanted to have one of the servers more likely to be chosen
        (for example, if one of the server has more memory than the others,
        and so can handle more requests) simply list it more times in the
        map file.</p>
    
        <div class="example"><p><code>
    static   www1|www1|www2|www3|www4
        </code></p></div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbm" id="dbm">dbm: DBM Hash File</a></h2>
        
    
        <p>When a MapType of <code>dbm</code> is used, the MapSource is a
        filesystem path to a DBM database file containing key/value pairs to
        be used in the mapping. This works exactly the same way as the
        <code>txt</code> map, but is much faster, because a DBM is indexed,
        whereas a text file is not. This allows more rapid access to the
        desired key.</p>
    
        <p>You may optionally specify a particular dbm type:</p>
    
     <pre class="prettyprint lang-config">RewriteMap examplemap "dbm=sdbm:/etc/apache/mapfile.dbm"</pre>
    
    
        <p>The type can be <code>sdbm</code>, <code>gdbm</code>, <code>ndbm</code> 
        or <code>db</code>.
        However, it is recommended that you just use the <a href="../programs/httxt2dbm.html">httxt2dbm</a> utility that is
        provided with Apache HTTP Server, as it will use the correct DBM library,
        matching the one that was used when httpd itself was built.</p>
    
        <p>To create a dbm file, first create a text map file as described
        in the <a href="#txt">txt</a> section. Then run
        <code>httxt2dbm</code>:</p>
    
    <div class="example"><p><code>
    $ httxt2dbm -i mapfile.txt -o mapfile.map
    </code></p></div>
    
    <p>You can then reference the resulting file in your
    <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive:</p>
    
    <pre class="prettyprint lang-config">RewriteMap mapname "dbm:/etc/apache/mapfile.map"</pre>
    
    
    <div class="note">
    <p>Note that with some dbm types, more than one file is generated, with
    a common base name. For example, you may have two files named
    <code>mapfile.map.dir</code> and <code>mapfile.map.pag</code>. This is
    normal, and you need only use the base name <code>mapfile.map</code> in
    your <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive.</p>
    </div>
    
    <div class="note"><h3>Cached lookups</h3>
    <p>
    The looked-up keys are cached by httpd until the <code>mtime</code>
    (modified time) of the mapfile changes, or the httpd server is
    restarted. This ensures better performance on maps that are called
    by many requests.
    </p>
    </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="prg" id="prg">prg: External Rewriting Program</a></h2>
    
        <p>When a MapType of <code>prg</code> is used, the MapSource is a
        filesystem path to an executable program which will providing the
        mapping behavior. This can be a compiled binary file, or a program
        in an interpreted language such as Perl or Python.</p>
    
        <p>This program is started once, when the Apache HTTP Server is
        started, and then communicates with the rewriting engine via
        <code>STDIN</code> and <code>STDOUT</code>. That is, for each map
        function lookup, it expects one argument via <code>STDIN</code>, and
        should return one new-line terminated response string on
        <code>STDOUT</code>. If there is no corresponding lookup value, the
        map program should return the four-character string
        "<code>NULL</code>" to indicate this.</p>
    
        <p>External rewriting programs are not started if they're defined in
        a context that does not have <code class="directive"><a href="../mod/mod_rewrite.html#rewriteengine">RewriteEngine</a></code> set to
        <code>on</code>.</p>
    
        <p>By default, external rewriting programs are run as the
        user:group who started httpd. This can be changed on UNIX systems
        by passing user name and group name as third argument to
        <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> in the
        <code>username:groupname</code> format.</p>
    
        <p>This feature utilizes the <code>rewrite-map</code> mutex,
        which is required for reliable communication with the program.
        The mutex mechanism and lock file can be configured with the
        <code class="directive"><a href="../mod/core.html#mutex">Mutex</a></code> directive.</p>
    
        <p>A simple example is shown here which will replace all dashes with
        underscores in a request URI.</p>
    
        <p><strong>Rewrite configuration</strong></p>
        <pre class="prettyprint lang-config">RewriteMap d2u "prg:/www/bin/dash2under.pl" apache:apache
    RewriteRule "-" "${d2u:%{REQUEST_URI}}"</pre>
    
    
        <p><strong>dash2under.pl</strong></p>
        <pre class="prettyprint lang-perl">#!/usr/bin/perl
    $| = 1; # Turn off I/O buffering
    while (&lt;STDIN&gt;) {
        s/-/_/g; # Replace dashes with underscores
        print $_;
    }</pre>
    
    
    <div class="note"><h3>Caution!</h3>
    <ul>
    <li>Keep your rewrite map program as simple as possible. If the program
    hangs, it will cause httpd to wait indefinitely for a response from the
    map, which will, in turn, cause httpd to stop responding to
    requests.</li>
    <li>Be sure to turn off buffering in your program. In Perl this is done
    by the second line in the example script: <code>$| = 1;</code> This will
    of course vary in other languages. Buffered I/O will cause httpd to wait
    for the output, and so it will hang.</li>
    <li>Remember that there is only one copy of the program, started at
    server startup. All requests will need to go through this one bottleneck.
    This can cause significant slowdowns if many requests must go through
    this process, or if the script itself is very slow.</li>
    </ul>
    </div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dbd" id="dbd">dbd or fastdbd: SQL Query</a></h2>
        
    
        <p>When a MapType of <code>dbd</code> or <code>fastdbd</code> is
        used, the MapSource is a SQL SELECT statement that takes a single
        argument and returns a single value.</p>
    
        <p><code class="module"><a href="../mod/mod_dbd.html">mod_dbd</a></code> will need to be configured to point at
        the right database for this statement to be executed.</p>
    
        <p>There are two forms of this MapType.
        Using a MapType of <code>dbd</code> causes the query to be
        executed with each map request, while using <code>fastdbd</code>
        caches the database lookups internally. So, while
        <code>fastdbd</code> is more efficient, and therefore faster, it
        won't pick up on changes to the database until the server is
        restarted.</p>
    
        <p>If a query returns more than one row, a random row from
        the result set is used.</p>
    
        <div class="example"><h3>Example</h3><pre class="prettyprint lang-config">RewriteMap myquery "fastdbd:SELECT destination FROM rewrite WHERE source = %s"</pre>
    </div>
    
        <div class="note"><h3>Note</h3>
        <p>The query name is passed to the database driver as a label for
        an SQL prepared statement, and will therefore need to follow any rules
        (such as case-sensitivity) required for your database.</p></div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="summary" id="summary">Summary</a></h2>
        
    
        <p>The <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive can
        occur more than once. For each mapping-function use one
        <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive to declare
        its rewriting mapfile.</p>
    
        <p>While you cannot <strong>declare</strong> a map in
        per-directory context (<code>.htaccess</code> files or
        <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> blocks) it is
        possible to <strong>use</strong> this map in per-directory context.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/rewritemap.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/rewritemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/rewritemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/remapping.html.fr.utf8���������������������������������������������0000664�0001751�0001751�00000074311�14740503670�022667� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Redirection et remise en correspondance avec mod_rewrite - Serveur HTTP Apache Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Redirection et remise en correspondance avec mod_rewrite</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/remapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/remapping.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>Ce document est un complément à la <a href="../mod/mod_rewrite.html">Documentation de référence</a> de
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Il montre comment utiliser
    <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour rediriger et remettre en
    correspondance une requête. Il contient de
    nombreux exemples d'utilisation courante de mod_rewrite avec une
    description détaillée de leur fonctionnement.</p>
    
    <div class="warning">Vous devez vous attacher à comprendre le
    fonctionnement des exemples, car la plupart d'entre eux ne
    fonctionneront pas sur votre système si vous vous contentez de les
    copier/coller dans vos fichiers de configuration.</div>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#old-to-new">De l'ancienne à la nouvelle URL (en interne)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#old-to-new-extern">De l'ancien au nouveau (en externe)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#movehomedirs">Ressource déplacée vers un autre serveur</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#static-to-dynamic">De statique à dynamique</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#backward-compatibility">Compatibilité ascendante dans le cadre d'une modification
          d'extension de nom de fichier</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#canonicalhost">Noms d'hôtes canoniques</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multipledirs">Recherche de pages dans plus d'un répertoire</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#archive-access-multiplexer">Redirection vers des serveurs géographiquement distribués</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#browser-dependent-content">Contenu dépendant du navigateur</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#canonicalurl">URLs canoniques</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moveddocroot">Déplacement du répertoire <code>DocumentRoot</code></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#fallback-resource">Ressource par défaut</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite-query">Rewrite query string</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Documentation du module mod_rewrite</a></li><li><a href="intro.html">Introduction à mod_rewrite</a></li><li><a href="access.html">Contrôler l'accès</a></li><li><a href="vhosts.html">Serveurs virtuels</a></li><li><a href="proxy.html">Serveurs mandataires</a></li><li><a href="rewritemap.html">Utilisation de RewriteMap</a></li><li><a href="advanced.html">Techniques avancées</a></li><li><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="old-to-new" id="old-to-new">De l'ancienne à la nouvelle URL (en interne)</a></h2>
    
          
    
          <dl>
            <dt>Description :</dt>
    
            <dd>
              <p>Supposons que nous ayons récemment renommé la page
    	  <code>foo.html</code> en <code>bar.html</code>, et voulions
    	  maintenant que l'ancienne URL soit toujours valide à des fins
    	  de compatibilité ascendante. En fait, on voudrait que le
    	  changement de nom soit transparent aux utilisateurs de
    	  l'ancienne URL.</p>
            </dd>
    
            <dt>Solution :</dt>
    
            <dd>
              <p>On réécrit l'ancienne URL en interne vers la nouvelle via
    	  la règle suivante :</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteRule    "^<strong>/foo</strong>\.html$" "<strong>/bar</strong>.html" [PT]</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="old-to-new-extern" id="old-to-new-extern">De l'ancien au nouveau (en externe)</a></h2>
    
          
    
          <dl>
            <dt>Description :</dt>
    
            <dd>
              <p>Supposons toujours que nous ayons récemment renommé la page
    	  <code>foo.html</code> en <code>bar.html</code>, et voulions
    	  maintenant que l'ancienne URL soit toujours valide à des fins
    	  de compatibilité ascendante. En revanche, nous voulons cette
    	  fois que la nouvelle URL soit suggérée aux utilisateurs de
    	  l'ancienne URL, c'est à dire que l'adresse vue depuis leur
    	  navigateur doit également être modifiée.</p>
            </dd>
    
            <dt>Solution :</dt>
    
            <dd>
              <p>On force une redirection HTTP vers la nouvelle URL, ce qui
    	  entraîne une modification de celle du navigateur et aussi de ce
    	  que voit l'utilisateur :</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteRule    "^<strong>foo</strong>\.html$"  "<strong>bar</strong>.html"  [<strong>R</strong>]</pre>
    
    </dd>
    
    <dt>Discussion</dt>
    
        <dd>
        <p>Dans l'exemple <a href="#old-to-new-intern">interne</a>, on a utilisé mod_rewrite afin
        de dissimuler la redirection au client. Dans cet exemple, en
        revanche, on aurait pu se contenter d'une directive Redirect :</p>
    
        <pre class="prettyprint lang-config">Redirect "/foo.html" "/bar.html"</pre>
    
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="movehomedirs" id="movehomedirs">Ressource déplacée vers un autre serveur</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
          <p>Si une ressource a été déplacée vers un autre serveur, vous
          pouvez faire en sorte que les URLs de l'ancien serveur continuent
          de fonctionner pendant un certain temps, afin de laisser au
          utilisateurs le temps de modifier leurs favoris.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>Vous pouvez utiliser <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> pour
          rediriger ces URLs vers le nouveau serveur, mais vous pouvez aussi
          utiliser les directives Redirect ou RedirectMatch.</p>
    
    <pre class="prettyprint lang-config">#Avec mod_rewrite
    RewriteEngine on
    RewriteRule   "^/docs/(.+)"  "http://nouveau.example.com/docs/$1"  [R,L]</pre>
    
    
    <pre class="prettyprint lang-config">#Avec RedirectMatch
    RedirectMatch "^/docs/(.*)" "http://nouveau.example.com/docs/$1"</pre>
    
    
    <pre class="prettyprint lang-config">#Avec Redirect
    Redirect "/docs/" "http://nouveau.example.com/docs/"</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="static-to-dynamic" id="static-to-dynamic">De statique à dynamique</a></h2>
    
          
    
          <dl>
            <dt>Description :</dt>
    
            <dd>
              <p>Comment transformer une page statique <code>foo.html</code>
    	  en sa variante dynamique <code>foo.cgi</code> de manière
    	  transparente, c'est à dire sans en avertir le
    	  navigateur/utilisateur.</p>
            </dd>
    
            <dt>Solution :</dt>
    
            <dd>
              <p>On réécrit simplement l'URL en script CGI et force le
    	  gestionnaire de contenu à <strong>cgi-script</strong> de façon
    	  à ce que le script s'exécute en tant que programme CGI.
    	  Ainsi, une requête vers <code>/~quux/foo.html</code> conduit
    	  en interne à l'invocation de
    	  <code>/~quux/foo.cgi</code>.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteBase    "/~quux/"
    RewriteRule    "^foo\.html$"  "foo.cgi"  [H=<strong>cgi-script</strong>]</pre>
    
            </dd>
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="backward-compatibility" id="backward-compatibility">Compatibilité ascendante dans le cadre d'une modification
          d'extension de nom de fichier</a></h2>
    
          
    
          <dl>
            <dt>Description :</dt>
    
            <dd>
              <p>Comment conférer une compatibilité ascendante aux URLs
    	  (existant encore virtuellement) après avoir migré
    	  <code>document.YYYY</code> vers <code>document.XXXX</code>,
    	  c'est à dire après avoir par exemple traduit un lot de
    	  fichiers <code>.html</code> en fichiers <code>.php</code>
    	  ?</p>
            </dd>
    
            <dt>Solution :</dt>
    
            <dd>
              <p>On réécrit simplement le nom du fichier en son nom
    	  de base et vérifie s'il existe aussi avec la nouvelle
    	  extension. Si c'est le cas, on utilise ce nom, sinon on
    	  réécrit l'URL sous sa forme originale.</p>
    
    
    <pre class="prettyprint lang-config">#   jeu de règles assurant une compatibilité ascendante en réécrivant<br />
    #   document.html en document.php si et seulement si document.php<br />
    #   existe
    &lt;Directory "/var/www/htdocs"&gt;
        RewriteEngine on
        RewriteBase "/var/www/htdocs"
    
        RewriteCond "$1.php" -f
        RewriteCond "$1.html" !-f
        RewriteRule "^(.*).html$" "$1.php"
    &lt;/Directory&gt;</pre>
    
        </dd>
    
        <dt>Discussion</dt>
        <dd>
        <p>Cet exemple utilise une fonctionnalité souvent méconnue de
        mod_rewrite, en tirant avantage de l'ordre d'exécution du jeu de
        règles. En particulier, mod_rewrite évalue la partie gauche des
        règles de réécriture avant d'évaluer les directives RewriteCond. En
        conséquence, $1 est déjà défini au moment où les directives
        RewriteCond sont évaluées. Ceci nous permet de tester l'existence du
        fichier original (<code>document.html</code>) et du fichier cible
        (<code>document.php</code>) en utilisant le même nom de base.</p>
    
        <p>Ce jeu de règles est conçu pour une utilisation dans un contexte
        de répertoire (au sein d'une section &lt;Directory&gt; ou d'un
        fichier .htaccess), de façon à ce que les vérifications
        <code>-f</code> effectuent leurs recherches dans le bon répertoire.
        Vous serez peut-être amené à définir une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> pour spécifier le
        répertoire de base à partir duquel vous travaillez.</p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="canonicalhost" id="canonicalhost">Noms d'hôtes canoniques</a></h2>
    
    
    
          <dl>
            <dt>Description :</dt>
    
            <dd>Le but de cette règle est de préférer l'utilisation d'un nom
    	d'hôte particulier à d'autres noms d'hôte utilisables
    	pour atteindre le même site. Par exemple, si vous voulez
    	utiliser <strong>www.example.com</strong> à la place de
    	<strong>example.com</strong>, vous pouvez utiliser une solution
    	du style :</dd>
    
            <dt>Solution :</dt>
    
            <dd>
    
    <p>Pour y parvenir, il vaut mieux se passer de mod_rewrite, et utiliser
    plutôt la directive <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code> dans
    une section de serveur virtuel pour le/les noms d'hôte non canoniques.</p>
    
    <pre class="prettyprint lang-config">&lt;VirtualHost *:80&gt;
      ServerName undesired.example.com
      ServerAlias example.com notthis.example.com
    
      Redirect "/" "http://www.example.com/"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
      ServerName www.example.com
    &lt;/VirtualHost&gt;</pre>
    
    
    <p>Vous pouvez aussi utiliser la directive <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code> :</p>
    
    <pre class="prettyprint lang-config">&lt;If "%{HTTP_HOST} != 'www.example.com'"&gt;
    	Redirect "/" "http://www.example.com/"
    &lt;/If&gt;</pre>
    
    
    <p>Ou, par exemple, pour rediriger une portion de votre site vers HTTPS
    :</p>
    
    <pre class="prettyprint lang-config">&lt;If "%{SERVER_PROTOCOL} != 'HTTPS'"&gt;
    	Redirect "/admin/" "https://www.example.com/admin/"
    &lt;/If&gt;</pre>
    
    
    <p>Si, pour une raison particulière, vous voulez tout de même utiliser
    <code>mod_rewrite</code> - dans le cas, par exemple, où vous avez besoin
    d'un jeu plus important de règles de réécritures - vous pouvez utiliser
    la recette suivante :</p>
    
    <p>Pour les sites écoutant sur un port autre que 80:</p>
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}"   "!^www\.example\.com" [NC]
    RewriteCond "%{HTTP_HOST}"   "!^$"
    RewriteCond "%{SERVER_PORT}" "!^80$"
    RewriteRule "^/?(.*)"         "http://www.example.com:%{SERVER_PORT}/$1" [L,R,NE]</pre>
    
    
    <p>Et pour un site écoutant sur le port 80</p>
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}"   "!^www\.example\.com" [NC]
    RewriteCond "%{HTTP_HOST}"   "!^$"
    RewriteRule "^/?(.*)"         "http://www.example.com/$1" [L,R,NE]</pre>
    
    	<p>
    	Si vous souhaitez que cette règle s'applique à tous les noms de
    	domaine - en d'autres termes, si vous voulez rediriger
    	<strong>example.com</strong> vers
    	<strong>www.example.com</strong> pour toutes les valeurs
    	possibles de <strong>example.com</strong>, vous pouvez utiliser
    	le jeu de règles suivants :</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
    RewriteCond "%{HTTP_HOST}" "!^$"
    RewriteRule "^/?(.*)" "http://www.%{HTTP_HOST}/$1" [L,R,NE]</pre>
    
    	<p>
    	Vous pouvez utiliser ce jeu de règles aussi bien dans le fichier
    	de configuration de votre serveur principal que dans un fichier
    	<code>.htaccess</code> placé dans le répertoire défini par la
    	directive <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> du serveur.</p>
            </dd>
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multipledirs" id="multipledirs">Recherche de pages dans plus d'un répertoire</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>Une ressource peut exister dans plusieurs répertoires, et nous
          voulons rechercher cette ressource dans ces répertoires
          lorsqu'elle fait l'objet d'une requête. Il est possible que nous
          ayons récemment réorganisé la structure de notre site en
          répartissant son contenu dans plusieurs répertoires.</p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>Le jeu de règles suivant recherche la ressource dans deux
          répertoires, et s'il ne la trouve dans aucun des deux, il tentera
          simplement de la servir à partir de l'adresse fournie dans la
          requête.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    
    #   on cherche tout d'abord dans dir1/...
    #   ... et si on trouve, on est content et on arrête :
    RewriteCond         "%{DOCUMENT_ROOT}/<strong>dir1</strong>/%{REQUEST_URI}"  -f
    RewriteRule  "^(.+)"  "%{DOCUMENT_ROOT}/<strong>dir1</strong>/$1"  [L]
    
    #   on cherche ensuite dans dir2/...
    #   ... et si on trouve, on est content et on arrête :
    RewriteCond         "%{DOCUMENT_ROOT}/<strong>dir2</strong>/%{REQUEST_URI}"  -f
    RewriteRule  "^(.+)"  "%{DOCUMENT_ROOT}/<strong>dir2</strong>/$1"  [L]
    
    #   sinon, on continue la recherche avec d'autres directives Alias
    #   ou ScriptAlias, etc...
    RewriteRule   "^"  "-"  [PT]</pre>
    
            </dd>
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="archive-access-multiplexer" id="archive-access-multiplexer">Redirection vers des serveurs géographiquement distribués</a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
        <p>Notre site web possède de nombreux miroirs, et nous voulons
        rediriger les utilisateurs vers celui qui se situe dans le pays où
        ils se trouvent. </p>
        </dd>
    
        <dt>Solution :</dt>
    
        <dd>
        <p>En consultant le nom d'hôte du client demandeur, on détermine le
        pays dans lequel il se trouve. S'il est impossible d'effectuer une
        recherche sur leur adresse IP, on se rabat sur un serveur par
        défaut.</p>
        <p>Nous allons utiliser une directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> afin de construire une
        liste des serveurs que nous voulons utiliser.</p>
    
    <pre class="prettyprint lang-config">HostnameLookups on
    RewriteEngine on
    RewriteMap    multiplex         "txt:/path/to/map.mirrors"
    RewriteCond  "%{REMOTE_HOST}"     "([a-z]+)$ [NC]"
    RewriteRule   "^/(.*)$"  "${multiplex:<strong>%1</strong>|http://www.example.com/}$1"  [R,L]</pre>
    
    
    <div class="example"><p><code>
    ##  liste_miroirs -- Table de correspondance pays - serveurs<br />
    <br />
    de        http://www.exemple.de/<br />
    uk        http://www.exemple.uk/<br />
    com       http://www.example.com/<br />
    ##EOF##
    </code></p></div>
        </dd>
    
        <dt>Discussion</dt>
        <dd>
        <div class="warning">Ce jeu de règles nécessite la définition à
        <code>on</code> de la directive <code class="directive"><a href="../mod/core.html#hostnamelookups">HostNameLookups</a></code>, ce qui peut induire une
        baisse de performance significative.</div>
    
        <p>La directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> extrait la dernière
        partie du nom d'hôte du client demandeur - le code du pays - et la
        règle de réécriture qui suit utilise cette valeur pour rechercher le
        serveur miroir approprié dans le fichier de correspondances.</p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="browser-dependent-content" id="browser-dependent-content">Contenu dépendant du navigateur</a></h2>
    
          
    
          <dl>
            <dt>Description :</dt>
    
            <dd>
              <p>Nous voulons fournir des contenus différents en fonction du
    	  navigateur (user-agent) qui effectue la requête.</p>
            </dd>
    
            <dt>Solution :</dt>
    
            <dd>
              <p>Nous devons déterminer quel contenu servir, en nous basant
    	  sur l'en-tête HTTP "User-Agent". La
    	  configuration suivante effectue ceci : si l'en-tête HTTP
    	  "User-Agent" commence par "Mozilla/3", le nom de la page
    	  <code>foo.html</code> est réécrit en <code>foo.NS.html</code>
    	  et la réécriture s'arrête. Si le navigateur est "Lynx" ou
    	  "Mozilla" version 1 ou 2, l'URL devient
    	  <code>foo.20.html</code>. Tous les autres navigateurs
    	  reçoivent la page <code>foo.32.html</code>. Tout ceci est
    	  effectué par le jeu de règles suivant :</p>
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_USER_AGENT}"  "^<strong>Mozilla/3</strong>.*"
    RewriteRule "^foo\.html$"         "foo.<strong>NS</strong>.html"          [<strong>L</strong>]
    
    RewriteCond "%{HTTP_USER_AGENT}"  "^Lynx/" [OR]
    RewriteCond "%{HTTP_USER_AGENT}"  "^Mozilla/[12]"
    RewriteRule "^foo\.html$"         "foo.<strong>20</strong>.html"          [<strong>L</strong>]
    
    RewriteRule "^foo\.html$"         "foo.<strong>32</strong>.html"          [<strong>L</strong>]</pre>
    
            </dd>
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="canonicalurl" id="canonicalurl">URLs canoniques</a></h2>
    
    
    
    <dl>
     <dt>Description :</dt>
    
       <dd>
         <p>Sur certains serveurs, une ressource peut posséder plusieurs
         URLs. Il y a en général les URLs canoniques (celles qui sont
         réellement distribuées et utilisées), et celles qui correspondent à
         des raccourcis, les URLs internes, etc... Quelle que soit l'adresse
         que l'utilisateur fournit dans la requête, il devrait finalement
         voir l'URL canonique dans la barre d'adresse de son navigateur.</p>
       </dd>
    
       <dt>Solution :</dt>
    
         <dd>
           <p>Nous effectuons une redirection HTTP externe pour toutes les
           URLs non canoniques afin de les corriger dans la barre d'adresse
           du navigateur, et ceci pour toutes les requêtes futures. Dans le
           jeu de règles suivant, nous remplaçons <code>/matous</code> et
           <code>/minettes</code> par le canonique <code>/chats</code>.</p>
    
    	<pre class="prettyprint lang-config">RewriteRule   "^/(matous|minettes)/(.*)"    "/chats/$2"  [R]</pre>
    
            </dd>
    
         <dt>Discussion :</dt>
         <dd>On serait mieux inspiré d'utiliser ici les directives Redirect ou
         RedirectMatch :
    
         <pre class="prettyprint lang-config">RedirectMatch "^/(matous|minettes)/(.*)" "/chats/$2"</pre>
    
         </dd>
          </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moveddocroot" id="moveddocroot">Déplacement du répertoire <code>DocumentRoot</code></a></h2>
    
      
    
      <dl>
        <dt>Description :</dt>
    
        <dd>
    <p>En général, le répertoire <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> du serveur web correspond à l'URL
    "<code>/</code>". Ce répertoire ne contient cependant pas forcément des
    ressources de première importance pour l'utilisateur. Par exemple, vous
    préférerez peut-être que le répertoire d'accueil d'un visiteur accédant
    pour la première fois à votre site soit un répertoire particulier
    <code>/a-propos-de/</code>. Pour y parvenir, utilisez le jeu de règles
    suivant :</p>
    </dd>
    
        <dt>Solution :</dt>
    
        <dd>
          <p>On redirige l'URL <code>/</code> vers
          <code>/a-propos-de/</code> :
          </p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/$"  "/a-propos-de/"  [<strong>R</strong>]</pre>
    
    
    <p>Notez que l'on peut aussi y parvenir en utilisant la directive
    <code class="directive"><a href="../mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> :</p>
    
    <pre class="prettyprint lang-config">RedirectMatch "^/$" "http://example.com/a-propos-de/"</pre>
    
    
    <p>Notez aussi que cet exemple ne réécrit que l'URL racine. En d'autres
    termes, il réécrit une requête pour <code>http://example.com/</code>,
    mais pas pour une requête <code>http://example.com/page.html</code>. Si
    vous avez effectivement modifié la racine de vos documents - c'est à dire
    si <strong>tous</strong> vos contenus se trouvent dans un
    sous-répertoire, il est largement préférable de modifier simplement
    votre directive <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>, ou de
    déplacer l'ensemble du contenu vers le répertoire supérieur, plutôt que
    de réécrire les URLs.</p>
    </dd>
    </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="fallback-resource" id="fallback-resource">Ressource par défaut</a></h2>
    
    
    <dl>
    <dt>Description :</dt>
    <dd>Vous voulez qu'une seule ressource (disons un certain fichier tel
    que index.php) soit servie pour toutes les requêtes à destination d'un
    certain répertoire, sauf pour celles qui concernent une ressource
    existant effectivement comme une image, ou un fichier css.</dd>
    
    <dt>Solution :</dt>
    <dd>
    <p>Depuis la version 2.2.16, vous pouvez y parvenir via la directive
    <code class="directive"><a href="../mod/mod_dir.html#fallbackresource">FallbackResource</a></code> :</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/www/my_blog"&gt;
      FallbackResource "index.php"
    &lt;/Directory&gt;</pre>
    
    
    <p>Cependant, si vos besoins étaient plus complexes, vous pouviez, dans
    les versions plus anciennes d'Apache, utiliser un jeu de règles du style
    :</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/www/my_blog"&gt;
      RewriteBase "/my_blog"
    
      RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-f
      RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-d
      RewriteRule "^" "index.php" [PT]
    &lt;/Directory&gt;</pre>
    
    
    <p>D'autre part, si vous voulez transmettre l'URI de la requête en tant
    que chaîne de paramètres à index.php, vous pouvez remplacer cette règle
    de réécriture par :</p>
    
    <pre class="prettyprint lang-config">RewriteRule "(.*)" "index.php?$1" [PT,QSA]</pre>
    
    
    <p>Notez que l'on peut utiliser ces jeux de règles aussi bien dans un
    fichier <code>.htaccess</code> que dans une section
    &lt;Directory&gt;.</p>
    
    </dd>
    
    </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite-query" id="rewrite-query">Rewrite query string</a></h2>
    
    
    <dl>
    <dt>Description :</dt>
    <dd>Vous voulez extraire une valeur particulière d'une chaîne de
    paramètres d'une URL, et soit la remplacer, soit l'incorporer dans un
    autre composant de l'URL.</dd>
    
    <dt>Solutions :</dt>
    <dd>
    <p>Dans la plupart des solutions de cette section, on utilise la même
    condition qui stocke la valeur recherchée dans la référence arrière %2.
    %1 est le début de la requête, et %3 ce qui reste. Cette condition est
    un peu complexe car elle introduit de la flexibilité et évite les
    doubles perluettes '&amp;&amp;' dans les substitutions.</p>
    <ul>
      <li>Cette solution supprime le couple clé/valeur recherché :
    
    <pre class="prettyprint lang-config"># Remove mykey=???
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&amp;))mykey=([^&amp;]*)&amp;?(.*)&amp;?$"
    RewriteRule "(.*)" "$1?%1%3"</pre>
    
      </li>
    
      <li>Cette solution remplace la partie de l'URL qui suit la valeur
      recherchée par un '?' :
    
    <pre class="prettyprint lang-config"># Copy from query string to PATH_INFO
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&amp;))mykey=([^&amp;]*)&amp;?(.*)&amp;?$"
    RewriteRule "(.*)" "$1/products/%2/?" [PT]</pre>
    
      </li>
    
      <li>Cette solution utilise la valeur recherchée dans une deuxième
      condition ::
    
    <pre class="prettyprint lang-config"># Capture the value of mykey in the query string
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&amp;))mykey=([^&amp;]*)&amp;?(.*)&amp;?$""
    RewriteCond "%2" !=not-so-secret-value 
    RewriteRule "(.*)" - [F]</pre>
    
      </li>
    
      <li>Cette solution produit l'effet inverse des précédentes ; elle
      copie des composantes du chemin (peut-être PATH_INFO) depuis l'URL
      vers sa chaîne de paramètres :
    <pre class="prettyprint lang-config"># The desired URL might be /products/kitchen-sink, and the script expects 
    # /path?products=kitchen-sink.
    RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]</pre>
    
      </li>
    </ul>
    
    </dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="../en/rewrite/remapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/remapping.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/remapping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossaire</a> | <a href="../sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/access.html.en�����������������������������������������������������0000664�0001751�0001751�00000034216�14737241666�021266� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Using mod_rewrite to control access - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Using mod_rewrite to control access</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/access.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/access.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
    how you can use <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> to control access to
    various resources, and other related techniques.
    This includes many examples of common uses of mod_rewrite,
    including detailed descriptions of how each works.</p>
    
    <div class="warning">Note that many of these examples won't work unchanged in your
    particular server configuration, so it's important that you understand
    them, rather than merely cutting and pasting the examples into your
    configuration.</div>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#blocked-inline-images">Forbidding Image "Hotlinking"</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#blocking-of-robots">Blocking of Robots</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#host-deny">Denying Hosts in a Reject List</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#referer-deflector">Referer-based Deflector</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="blocked-inline-images" id="blocked-inline-images">Forbidding Image "Hotlinking"</a></h2>
    
          
    
          <dl>
            <dt>Description:</dt>
    
            <dd>
              <p>The following technique forbids the practice of other sites
              including your images inline in their pages. This practice is
              often referred to as "hotlinking", and results in
              your bandwidth being used to serve content for someone else's
              site.</p>
            </dd>
    
            <dt>Solution:</dt>
    
            <dd>
              <p>This technique relies on the value of the
              <code>HTTP_REFERER</code> variable, which is optional. As
              such, it's possible for some people to circumvent this
              limitation. However, most users will experience the failed
              request, which should, over time, result in the image being
              removed from that other site.</p>
              <p>There are several ways that you can handle this
              situation.</p>
    
        <p>In this first example, we simply deny the request, if it didn't
        initiate from a page on our site. For the purpose of this example,
        we assume that our site is <code>www.example.com</code>.</p>
    
    
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_REFERER}" "!^$"
    RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
    RewriteRule "\.(gif|jpg|png)$"    "-"   [F,NC]</pre>
    
    
        <p>In this second example, instead of failing the request, we display
        an alternate image instead.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_REFERER}" "!^$"
    RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
    RewriteRule "\.(gif|jpg|png)$"    "/images/go-away.png"   [R,NC]</pre>
    
    
        <p>In the third example, we redirect the request to an image on some
        other site.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_REFERER}" "!^$"
    RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
    RewriteRule "\.(gif|jpg|png)$" "http://other.example.com/image.gif"   [R,NC]</pre>
    
    
        <p>Of these techniques, the last two tend to be the most effective
        in getting people to stop hotlinking your images, because they will
        simply not see the image that they expected to see.</p>
    
            </dd>
    
            <dt>Discussion:</dt>
    
            <dd>
            <p>If all you wish to do is deny access to the resource, rather
            than redirecting that request elsewhere, this can be
            accomplished without the use of mod_rewrite:</p>
    
            <pre class="prettyprint lang-config">SetEnvIf Referer "example\.com" localreferer
    &lt;FilesMatch "\.(jpg|png|gif)$"&gt;
        Require env localreferer
    &lt;/FilesMatch&gt;</pre>
    
            </dd>
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="blocking-of-robots" id="blocking-of-robots">Blocking of Robots</a></h2>
    
          
    
          <dl>
            <dt>Description:</dt>
    
            <dd>
            <p>
            In this recipe, we discuss how to block persistent requests from
            a particular robot, or user agent.</p>
    
            <p>The standard for robot exclusion defines a file,
            <code>/robots.txt</code> that specifies those portions of your
            website where you wish to exclude robots. However, some robots
            do not honor these files.
            </p>
    
            <p>Note that there are methods of accomplishing this which do
            not use mod_rewrite. Note also that any technique that relies on
            the clients <code>USER_AGENT</code> string can be circumvented
            very easily, since that string can be changed.</p>
            </dd>
    
            <dt>Solution:</dt>
    
            <dd>
            <p>We use a ruleset that specifies the directory to be
            protected, and the client <code>USER_AGENT</code> that
            identifies the malicious or persistent robot.</p>
    
            <p>In this example, we are blocking a robot called
            <code>NameOfBadRobot</code> from a location
            <code>/secret/files</code>. You may also specify an IP address
            range, if you are trying to block that user agent only from the
            particular source.</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_USER_AGENT}"   "^NameOfBadRobot"
    RewriteCond "%{REMOTE_ADDR}"       "=123\.45\.67\.[8-9]"
    RewriteRule "^/secret/files/"   "-"   [F]</pre>
    
            </dd>
    
          <dt>Discussion:</dt>
    
          <dd>
          <p>
            Rather than using mod_rewrite for this, you can accomplish the
            same end using alternate means, as illustrated here:
          </p>
          <pre class="prettyprint lang-config">SetEnvIfNoCase User-Agent "^NameOfBadRobot" goaway
    &lt;Location "/secret/files"&gt;
        &lt;RequireAll&gt;
            Require all granted
            Require not env goaway
        &lt;/RequireAll&gt;
    &lt;/Location&gt;</pre>
    
          <p>
          As noted above, this technique is trivial to circumvent, by simply
          modifying the <code>USER_AGENT</code> request header. If you
          are experiencing a sustained attack, you should consider blocking
          it at a higher level, such as at your firewall.
          </p>
    
          </dd>
    
          </dl>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="host-deny" id="host-deny">Denying Hosts in a Reject List</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>We wish to maintain a list of hosts, rather like
          <code>hosts.deny</code>, and have those hosts blocked from
          accessing our server.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteMap    hosts-deny  "txt:/path/to/hosts.deny"
    RewriteCond   "${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}" "!=NOT-FOUND" [OR]
    RewriteCond   "${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}" "!=NOT-FOUND"
    RewriteRule   "^"  "-"  [F]</pre>
    
    
    <div class="example"><p><code>
    ##<br />
    ##  hosts.deny<br />
    ##<br />
    ##  ATTENTION! This is a map, not a list, even when we treat it as such.<br />
    ##             mod_rewrite parses it for key/value pairs, so at least a<br />
    ##             dummy value "-" must be present for each entry.<br />
    ##<br />
    <br />
    193.102.180.41 -<br />
    bsdti1.sdm.de  -<br />
    192.76.162.40  -<br />
    </code></p></div>
        </dd>
    
        <dt>Discussion:</dt>
        <dd>
        <p>
        The second RewriteCond assumes that you have HostNameLookups turned
        on, so that client IP addresses will be resolved. If that's not the
        case, you should drop the second RewriteCond, and drop the
        <code>[OR]</code> flag from the first RewriteCond.
        </p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="referer-deflector" id="referer-deflector">Referer-based Deflector</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>Redirect requests based on the Referer from which the request
          came, with different targets per Referer.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
      <p>The following ruleset uses a map file to associate each Referer
      with a redirection target.</p>
    
    <pre class="prettyprint lang-config">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]</pre>
    
    
          <p>The map file lists redirection targets for each referer, or, if
          we just wish to redirect back to where they came from, a "-" is
          placed in the map:</p>
    
    <pre class="prettyprint lang-config">##
    ##  deflector.map
    ##
    
    http://badguys.example.com/bad/index.html    -
    http://badguys.example.com/bad/index2.html   -
    http://badguys.example.com/bad/index3.html   http://somewhere.example.com/</pre>
    
    
        </dd>
      </dl>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/access.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/access.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/access.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/htaccess.html.en���������������������������������������������������0000664�0001751�0001751�00000012763�14737241666�021625� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>mod_rewrite and .htaccess files - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>mod_rewrite and .htaccess files</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/htaccess.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
    the way that the rules change when you use mod_rewrite in .htaccess files,
    and how to deal with these changes.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    </div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/htaccess.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/htaccess.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������httpd-2.4.64/docs/manual/rewrite/remapping.html.en��������������������������������������������������0000664�0001751�0001751�00000070042�14737241666�022004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Redirecting and Remapping with mod_rewrite - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Redirecting and Remapping with mod_rewrite</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/remapping.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/remapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
    <a href="../mod/mod_rewrite.html">reference documentation</a>. It describes
    how you can use <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> to redirect and remap
    request. This includes many examples of common uses of mod_rewrite,
    including detailed descriptions of how each works.</p>
    
    <div class="warning">Note that many of these examples won't work unchanged in your
    particular server configuration, so it's important that you understand
    them, rather than merely cutting and pasting the examples into your
    configuration.</div>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#old-to-new">From Old to New (internal)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#old-to-new-extern">Rewriting From Old to New (external)</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#movehomedirs">Resource Moved to Another Server</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#static-to-dynamic">From Static to Dynamic</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#backward-compatibility">Backward Compatibility for file extension change</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#canonicalhost">Canonical Hostnames</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#multipledirs">Search for pages in more than one directory</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#archive-access-multiplexer">Redirecting to Geographically Distributed Servers</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#browser-dependent-content">Browser Dependent Content</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#canonicalurl">Canonical URLs</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#moveddocroot">Moved <code>DocumentRoot</code></a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#fallback-resource">Fallback Resource</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#rewrite-query">Rewrite query string</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="old-to-new" id="old-to-new">From Old to New (internal)</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>Assume we have recently renamed the page
          <code>foo.html</code> to <code>bar.html</code> and now want
          to provide the old URL for backward compatibility. However,
          we want that users of the old URL even not recognize that
          the pages was renamed - that is, we don't want the address to
          change in their browser.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We rewrite the old URL to the new one internally via the
          following rule:</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteRule    "^<strong>/foo</strong>\.html$"  "<strong>/bar</strong>.html" [PT]</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="old-to-new-extern" id="old-to-new-extern">Rewriting From Old to New (external)</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>Assume again that we have recently renamed the page
          <code>foo.html</code> to <code>bar.html</code> 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.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We force a HTTP redirect to the new URL which leads to a
          change of the browsers and thus the users view:</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteRule    "^<strong>/foo</strong>\.html$"  "<strong>bar</strong>.html"  [<strong>R</strong>]</pre>
    
    </dd>
    
    <dt>Discussion</dt>
    
        <dd>
        <p>In this example, as contrasted to the <a href="#old-to-new-intern">internal</a> example above, we can simply
        use the Redirect directive. mod_rewrite was used in that earlier
        example in order to hide the redirect from the client:</p>
    
        <pre class="prettyprint lang-config">Redirect "/foo.html" "/bar.html"</pre>
    
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="movehomedirs" id="movehomedirs">Resource Moved to Another Server</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>If a resource has moved to another server, you may wish to have
          URLs continue to work for a time on the old server while people
          update their bookmarks.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>You can use <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> to redirect these URLs
          to the new server, but you might also consider using the Redirect
          or RedirectMatch directive.</p>
    
    <pre class="prettyprint lang-config">#With mod_rewrite
    RewriteEngine on
    RewriteRule   "^/docs/(.+)"  "http://new.example.com/docs/$1"  [R,L]</pre>
    
    
    <pre class="prettyprint lang-config">#With RedirectMatch
    RedirectMatch "^/docs/(.*)" "http://new.example.com/docs/$1"</pre>
    
    
    <pre class="prettyprint lang-config">#With Redirect
    Redirect "/docs/" "http://new.example.com/docs/"</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="static-to-dynamic" id="static-to-dynamic">From Static to Dynamic</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>How can we transform a static page
          <code>foo.html</code> into a dynamic variant
          <code>foo.cgi</code> in a seamless way, i.e. without notice
          by the browser/user.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We just rewrite the URL to the CGI-script and force the
          handler to be <strong>cgi-script</strong> so that it is
          executed as a CGI program.
          This way a request to <code>/~quux/foo.html</code>
          internally leads to the invocation of
          <code>/~quux/foo.cgi</code>.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine  on
    RewriteBase    "/~quux/"
    RewriteRule    "^foo\.html$"  "foo.cgi"  [H=<strong>cgi-script</strong>]</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="backward-compatibility" id="backward-compatibility">Backward Compatibility for file extension change</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>How can we make URLs backward compatible (still
          existing virtually) after migrating <code>document.YYYY</code>
          to <code>document.XXXX</code>, e.g. after translating a
          bunch of <code>.html</code> files to <code>.php</code>?</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We 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.</p>
    
    <pre class="prettyprint lang-config">#   backward compatibility ruleset for
    #   rewriting document.html to document.php
    #   when and only when document.php exists
    &lt;Directory "/var/www/htdocs"&gt;
        RewriteEngine on
        RewriteBase "/var/www/htdocs"
    
        RewriteCond "$1.php" -f
        RewriteCond "$1.html" !-f
        RewriteRule "^(.*).html$" "$1.php"
    &lt;/Directory&gt;</pre>
    
        </dd>
    
        <dt>Discussion</dt>
        <dd>
        <p>This example uses an often-overlooked feature of mod_rewrite,
        by taking advantage of the order of execution of the ruleset. In
        particular, mod_rewrite evaluates the left-hand-side of the
        RewriteRule before it evaluates the RewriteCond directives.
        Consequently, $1 is already defined by the time the RewriteCond
        directives are evaluated. This allows us to test for the existence
        of the original (<code>document.html</code>) and target
        (<code>document.php</code>) files using the same base filename.</p>
    
        <p>This ruleset is designed to use in a per-directory context (In a
        &lt;Directory&gt; block or in a .htaccess file), so that the
        <code>-f</code> checks are looking at the correct directory path.
        You may need to set a <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> directive to specify the
        directory base that you're working in.</p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="canonicalhost" id="canonicalhost">Canonical Hostnames</a></h2>
    
    
    
          <dl>
            <dt>Description:</dt>
    
            <dd>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 <strong>www.example.com</strong> instead of
            <strong>example.com</strong>, you might use a variant of the
            following recipe.</dd>
    
            <dt>Solution:</dt>
    
            <dd>
    
    <p>The very best way to solve this doesn't involve mod_rewrite at all,
    but rather uses the <code class="directive"><a href="../mod/mod_alias.html#redirect">Redirect</a></code>
    directive placed in a virtual host for the non-canonical
    hostname(s).</p>
    
    <pre class="prettyprint lang-config">&lt;VirtualHost *:80&gt;
      ServerName undesired.example.com
      ServerAlias example.com notthis.example.com
    
      Redirect "/" "http://www.example.com/"
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
      ServerName www.example.com
    &lt;/VirtualHost&gt;</pre>
    
    
    <p>You can alternatively accomplish this using the
    <code class="directive"><a href="../mod/core.html#if">&lt;If&gt;</a></code>
    directive:</p>
    
    <pre class="prettyprint lang-config">&lt;If "%{HTTP_HOST} != 'www.example.com'"&gt;
        Redirect "/" "http://www.example.com/"
    &lt;/If&gt;</pre>
    
    
    <p>Or, for example, to redirect a portion of your site to HTTPS, you
    might do the following:</p>
    
    <pre class="prettyprint lang-config">&lt;If "%{SERVER_PROTOCOL} != 'HTTPS'"&gt;
        Redirect "/admin/" "https://www.example.com/admin/"
    &lt;/If&gt;</pre>
    
    
    <p>If, for whatever reason, you still want to use <code>mod_rewrite</code>
    - if, for example, you need this to work with a larger set of RewriteRules -
    you might use one of the recipes below.</p>
    
    <p>For sites running on a port other than 80:</p>
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}"   "!^www\.example\.com" [NC]
    RewriteCond "%{HTTP_HOST}"   "!^$"
    RewriteCond "%{SERVER_PORT}" "!^80$"
    RewriteRule "^/?(.*)"        "http://www.example.com:%{SERVER_PORT}/$1" [L,R,NE]</pre>
    
    
    <p>And for a site running on port 80</p>
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}"   "!^www\.example\.com" [NC]
    RewriteCond "%{HTTP_HOST}"   "!^$"
    RewriteRule "^/?(.*)"        "http://www.example.com/$1" [L,R,NE]</pre>
    
    
            <p>
            If you wanted to do this generically for all domain names - that
            is, if you want to redirect <strong>example.com</strong> to
            <strong>www.example.com</strong> for all possible values of
            <strong>example.com</strong>, you could use the following
            recipe:</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
    RewriteCond "%{HTTP_HOST}" "!^$"
    RewriteRule "^/?(.*)"      "http://www.%{HTTP_HOST}/$1" [L,R,NE]</pre>
    
    
        <p>These rulesets will work either in your main server configuration
        file, or in a <code>.htaccess</code> file placed in the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> of the server.</p>
            </dd>
          </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multipledirs" id="multipledirs">Search for pages in more than one directory</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>A particular resource might exist in one of several places, and
          we want to look in those places for the resource when it is
          requested. Perhaps we've recently rearranged our directory
          structure, dividing content into several locations.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>The following ruleset searches in two directories to find the
          resource, and, if not finding it in either place, will attempt to
          just serve it out of the location requested.</p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    
    #   first try to find it in dir1/...
    #   ...and if found stop and be happy:
    RewriteCond         "%{DOCUMENT_ROOT}/<strong>dir1</strong>/%{REQUEST_URI}"  -f
    RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/<strong>dir1</strong>/$1"  [L]
    
    #   second try to find it in dir2/...
    #   ...and if found stop and be happy:
    RewriteCond         "%{DOCUMENT_ROOT}/<strong>dir2</strong>/%{REQUEST_URI}"  -f
    RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/<strong>dir2</strong>/$1"  [L]
    
    #   else go on for other Alias or ScriptAlias directives,
    #   etc.
    RewriteRule   "^"  "-"  [PT]</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="archive-access-multiplexer" id="archive-access-multiplexer">Redirecting to Geographically Distributed Servers</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
        <p>We have numerous mirrors of our website, and want to redirect
        people to the one that is located in the country where they are
        located.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
        <p>Looking at the hostname of the requesting client, we determine
        which country they are coming from. If we can't do a lookup on their
        IP address, we fall back to a default server.</p>
        <p>We'll use a <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
        directive to build a list of servers that we wish to use.</p>
    
    <pre class="prettyprint lang-config">HostnameLookups on
    RewriteEngine on
    RewriteMap    multiplex         "txt:/path/to/map.mirrors"
    RewriteCond   "%{REMOTE_HOST}"  "([a-z]+)$" [NC]
    RewriteRule   "^/(.*)$"  "${multiplex:<strong>%1</strong>|http://www.example.com/}$1"  [R,L]</pre>
    
    
    <div class="example"><p><code>
    ##  map.mirrors -- Multiplexing Map<br />
    <br />
    de        http://www.example.de/<br />
    uk        http://www.example.uk/<br />
    com       http://www.example.com/<br />
    ##EOF##
    </code></p></div>
        </dd>
    
        <dt>Discussion</dt>
        <dd>
        <div class="warning">This ruleset relies on
        <code class="directive"><a href="../mod/core.html#hostnamelookups">HostNameLookups</a></code>
        being set <code>on</code>, which can be
        a significant performance hit.</div>
    
        <p>The <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
        directive captures the last portion of the hostname of the
        requesting client - the country code - and the following RewriteRule
        uses that value to look up the appropriate mirror host in the map
        file.</p>
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="browser-dependent-content" id="browser-dependent-content">Browser Dependent Content</a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
          <p>We wish to provide different content based on the browser, or
          user-agent, which is requesting the content.</p>
        </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We have to decide, based on the HTTP header "User-Agent",
          which content to serve. The following config
          does the following: If the HTTP header "User-Agent"
          contains "Mozilla/3", the page <code>foo.html</code>
          is rewritten to <code>foo.NS.html</code> and the
          rewriting stops. If the browser is "Lynx" or "Mozilla" of
          version 1 or 2, the URL becomes <code>foo.20.html</code>.
          All other browsers receive page <code>foo.32.html</code>.
          This is done with the following ruleset:</p>
    
    <pre class="prettyprint lang-config">RewriteCond "%{HTTP_USER_AGENT}"  "^<strong>Mozilla/3</strong>.*"
    RewriteRule "^foo\.html$"         "foo.<strong>NS</strong>.html"          [<strong>L</strong>]
    
    RewriteCond "%{HTTP_USER_AGENT}"  "^Lynx/" [OR]
    RewriteCond "%{HTTP_USER_AGENT}"  "^Mozilla/[12]"
    RewriteRule "^foo\.html$"         "foo.<strong>20</strong>.html"          [<strong>L</strong>]
    
    RewriteRule "^foo\.html$"         "foo.<strong>32</strong>.html"          [<strong>L</strong>]</pre>
    
        </dd>
      </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="canonicalurl" id="canonicalurl">Canonical URLs</a></h2>
    
    
    
    <dl>
     <dt>Description:</dt>
    
       <dd>
         <p>On some webservers there is more than one URL for a
         resource. Usually there are canonical URLs (which are be
         actually used and distributed) and those which are just
         shortcuts, internal ones, and so on. Independent of which URL the
         user supplied with the request, they should finally see the
         canonical one in their browser address bar.</p>
       </dd>
    
       <dt>Solution:</dt>
    
         <dd>
           <p>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 <code>/puppies</code> and <code>/canines</code>
           by the canonical <code>/dogs</code>.</p>
    
    <pre class="prettyprint lang-config">RewriteRule   "^/(puppies|canines)/(.*)"    "/dogs/$2"  [R]</pre>
    
            </dd>
    
         <dt>Discussion:</dt>
         <dd>
         This should really be accomplished with Redirect or RedirectMatch
         directives:
    
         <pre class="prettyprint lang-config">RedirectMatch "^/(puppies|canines)/(.*)" "/dogs/$2"</pre>
    
         </dd>
          </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="moveddocroot" id="moveddocroot">Moved <code>DocumentRoot</code></a></h2>
    
      
    
      <dl>
        <dt>Description:</dt>
    
        <dd>
    <p>Usually the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
    of the webserver directly relates to the URL "<code>/</code>".
    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 <code>/about/</code>. This may be accomplished
    using the following ruleset:</p>
    </dd>
    
        <dt>Solution:</dt>
    
        <dd>
          <p>We redirect the URL <code>/</code> to
          <code>/about/</code>:
          </p>
    
    <pre class="prettyprint lang-config">RewriteEngine on
    RewriteRule   "^/$"  "/about/"  [<strong>R</strong>]</pre>
    
    
    <p>Note that this can also be handled using the <code class="directive"><a href="../mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> directive:</p>
    
    <pre class="prettyprint lang-config">RedirectMatch "^/$" "http://example.com/about/"</pre>
    
    
    <p>Note also that the example rewrites only the root URL. That is, it
    rewrites a request for <code>http://example.com/</code>, but not a
    request for <code>http://example.com/page.html</code>. If you have in
    fact changed your document root - that is, if <strong>all</strong> of
    your content is in fact in that subdirectory, it is greatly preferable
    to simply change your <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
    directive, or move all of the content up one directory,
    rather than rewriting URLs.</p>
    </dd>
    </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="fallback-resource" id="fallback-resource">Fallback Resource</a></h2>
    
    
    <dl>
    <dt>Description:</dt>
    <dd>You want a single resource (say, a certain file, like index.php) to
    handle all requests that come to a particular directory, except those
    that should go to an existing resource such as an image, or a css file.</dd>
    
    <dt>Solution:</dt>
    <dd>
    <p>As of version 2.2.16, you should use the <code class="directive"><a href="../mod/mod_dir.html#fallbackresource">FallbackResource</a></code> directive for this:</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/www/my_blog"&gt;
      FallbackResource "index.php"
    &lt;/Directory&gt;</pre>
    
    
    <p>However, in earlier versions of Apache, or if your needs are more
    complicated than this, you can use a variation of the following rewrite
    set to accomplish the same thing:</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/www/my_blog"&gt;
      RewriteBase "/my_blog"
    
      RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-f
      RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-d
      RewriteRule "^" "index.php" [PT]
    &lt;/Directory&gt;</pre>
    
    
    <p>If, on the other hand, you wish to pass the requested URI as a query
    string argument to index.php, you can replace that RewriteRule with:</p>
    
    <pre class="prettyprint lang-config">RewriteRule "(.*)" "index.php?$1" [PT,QSA]</pre>
    
    
    <p>Note that these rulesets can be used in a <code>.htaccess</code>
    file, as well as in a &lt;Directory&gt; block.</p>
    
    </dd>
    
    </dl>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite-query" id="rewrite-query">Rewrite query string</a></h2>
    
    
    <dl>
    <dt>Description:</dt>
    <dd>You want to capture a particular value from a query string
    and either replace it or incorporate it into another component
    of the URL.</dd>
    
    <dt>Solutions:</dt>
    <dd>
    <p> Many of the solutions in this section will all use the same condition,
    which leaves the matched value in the %2 backreference.  %1 is the beginining
    of the query string (up to the key of intererest), and %3 is the remainder. This
    condition is a bit complex for flexibility and to avoid double '&amp;&amp;' in the
    substitutions.</p>
    <ul>
      <li>This solution removes the matching key and value:
    
    <pre class="prettyprint lang-config"># Remove mykey=???
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&amp;))mykey=([^&amp;]*)&amp;?(.*)&amp;?$"
    RewriteRule "(.*)" "$1?%1%3"</pre>
    
      </li>
    
      <li>This solution uses the captured value in the URL substitution,
      discarding the rest of the original query by appending a '?':
    
    <pre class="prettyprint lang-config"># Copy from query string to PATH_INFO
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&amp;))mykey=([^&amp;]*)&amp;?(.*)&amp;?$"
    RewriteRule "(.*)" "$1/products/%2/?" [PT]</pre>
    
      </li>
    
      <li>This solution checks the captured value in a subsequent condition:
    
    <pre class="prettyprint lang-config"># Capture the value of mykey in the query string
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&amp;))mykey=([^&amp;]*)&amp;?(.*)&amp;?$"
    RewriteCond "%2" !=not-so-secret-value 
    RewriteRule "(.*)" - [F]</pre>
    
      </li>
    
      <li>This solution shows the reverse of the previous ones, copying
          path components (perhaps PATH_INFO) from the URL into the query string.
    <pre class="prettyprint lang-config"># The desired URL might be /products/kitchen-sink, and the script expects
    # /path?products=kitchen-sink.
    RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]</pre>
    
      </li>
    </ul>
    
    </dd>
    
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/remapping.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/remapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/remapping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/advanced.html������������������������������������������������������0000664�0001751�0001751�00000000317�13710016232�021137� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: advanced.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: advanced.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/index.html���������������������������������������������������������0000664�0001751�0001751�00000000571�13710016232�020503� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: index.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: index.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/access.html��������������������������������������������������������0000664�0001751�0001751�00000000313�13710016232�020627� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: access.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: access.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/htaccess.html������������������������������������������������������0000664�0001751�0001751�00000000317�13710016232�021167� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: htaccess.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: htaccess.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/tech.html.en�������������������������������������������������������0000664�0001751�0001751�00000031516�14737241666�020750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache mod_rewrite Technical Details - Apache HTTP Server Version 2.4</title>
    <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
    <script src="../style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="../images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="../images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Apache mod_rewrite Technical Details</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="../en/rewrite/tech.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/tech.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
    <p>This document discusses some of the technical details of mod_rewrite
    and URL matching.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#InternalAPI">API Phases</a></li>
    <li><img alt="" src="../images/down.gif" /> <a href="#InternalRuleset">Ruleset Processing</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="InternalAPI" id="InternalAPI">API Phases</a></h2>
    
        <p>The Apache HTTP Server handles requests in several phases. At
        each of these phases, one or more modules may be called upon to
        handle that portion of the request lifecycle. Phases include things
        like URL-to-filename translation, authentication, authorization,
        content, and logging. (This is not an exhaustive list.)</p>
    
        <p>mod_rewrite acts in two of these phases (or "hooks", as they are
        often called) to influence how URLs may be rewritten.</p>
    
        <p>First, it uses the URL-to-filename translation hook, which occurs
        after the HTTP request has been read, but before any authorization
        starts. Secondly, it uses the Fixup hook, which is after the
        authorization phases, and after per-directory configuration files
        (<code>.htaccess</code> files) have been read, but before the
        content handler is called.</p>
    
        <p>So, after a request comes in and a corresponding server or
        virtual host has been determined, the rewriting engine starts
        processing any <code>mod_rewrite</code> directives appearing in the
        per-server configuration. (i.e., in the main server configuration file
        and <code class="directive"><a href="../mod/core.html#virtualhost">&lt;Virtualhost&gt;</a></code>
        sections.) This happens in the URL-to-filename phase.</p>
    
        <p>A few steps later, once the final data directories have been found,
        the per-directory configuration directives (<code>.htaccess</code>
        files and <code class="directive"><a href="../mod/core.html#directory">&lt;Directory&gt;</a></code> blocks) are applied. This
        happens in the Fixup phase.</p>
    
        <p>In each of these cases, mod_rewrite rewrites the
        <code>REQUEST_URI</code> either to a new URL, or to a filename.</p>
    
        <p>In per-directory context (i.e., within <code>.htaccess</code> files
        and <code>Directory</code> blocks), these rules are being applied
        after a URL has already been translated to a filename. Because of
        this, the URL-path that mod_rewrite initially compares <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives against
        is the full filesystem path to the translated filename with the current
        directories path (including a trailing slash) removed from the front.</p>
    
        <p> To illustrate: If rules are in /var/www/foo/.htaccess and a request
        for /foo/bar/baz is being processed, an expression like ^bar/baz$ would
        match.</p>
    
        <p> If a substitution is made in per-directory context, a new internal 
        subrequest is issued with the new URL, which restarts processing of the 
        request phases. If the substitution is a relative path, the <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> directive 
        determines the URL-path prefix prepended to the substitution.
        In per-directory context, care must be taken to 
        create rules which will eventually (in some future "round" of per-directory
        rewrite processing) not perform a substitution to avoid looping.
        (See <a href="http://wiki.apache.org/httpd/RewriteLooping">RewriteLooping</a>
        for further discussion of this problem.)</p>
    
        <p>Because of this further manipulation of the URL in per-directory
        context, you'll need to take care to craft your rewrite rules
        differently in that context. In particular, remember that the
        leading directory path will be stripped off of the URL that your
        rewrite rules will see. Consider the examples below for further
        clarification.</p>
    
        <table class="bordered">
    
            <tr>
                <th>Location of rule</th>
                <th>Rule</th>
            </tr>
    
            <tr>
                <td>VirtualHost section</td>
                <td>RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"</td>
            </tr>
    
            <tr>
                <td>.htaccess file in document root</td>
                <td>RewriteRule "^images/(.+)\.jpg" "images/$1.gif"</td>
            </tr>
    
            <tr>
                <td>.htaccess file in images directory</td>
                <td>RewriteRule "^(.+)\.jpg" "$1.gif"</td>
            </tr>
    
        </table>
    
        <p>For even more insight into how mod_rewrite manipulates URLs in
        different contexts, you should consult the <a href="../mod/mod_rewrite.html#logging">log entries</a> made during 
        rewriting.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="InternalRuleset" id="InternalRuleset">Ruleset Processing</a></h2>
    
          <p>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.</p>
    
          <p>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 (<code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> directives) and
          when a particular rule matches it optionally loops through
          existing corresponding conditions (<code>RewriteCond</code>
          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.</p>
    <p class="figure">
          <img src="../images/rewrite_process_uri.png" alt="Flow of RewriteRule and RewriteCond matching" /><br />
          <dfn>Figure 1:</dfn>The control flow through the rewriting ruleset
    </p>
          <p>First the URL is matched against the
          <em>Pattern</em> of each rule. If it fails, mod_rewrite
          immediately stops processing this rule, and continues with the
          next rule. If the <em>Pattern</em> matches, mod_rewrite looks
          for corresponding rule conditions (RewriteCond directives,
          appearing immediately above the RewriteRule in the configuration).
          If none are present, it substitutes the URL with a new value, which is
          constructed from the string <em>Substitution</em>, 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 <em>TestString</em> by expanding variables,
          back-references, map lookups, <em>etc.</em> and then we try
          to match <em>CondPattern</em> 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
          <em>Substitution</em>.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="../en/rewrite/tech.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="../fr/rewrite/tech.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/tech.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/rewrite/flags.html���������������������������������������������������������0000664�0001751�0001751�00000000311�13710016232�020460� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: flags.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: flags.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/mpm.html.ko.euc-kr���������������������������������������������������������0000664�0001751�0001751�00000023427�14743132254�020320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ó  (MPM) - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ó  (MPM)</h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p>  ó  (Multi-Processing Module) ̸,
    ġ  ̸  ϴ Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Ұ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#choosing">MPM ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#defaults">MPM ⺻</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Ұ</a></h2>
    
        <p>ġ  پ ȯ پ ÷ 
         ֵ ϰ ϰ Ǿ. ٸ ÷ ٸ
        ȯ  ٸ  䱸ϸ,    ȿ
        ϴ  ٸ  ִ. ġ ȭ  ̷
        پ ȯ濡 ׻ ؿԴ. ׷ ʹ Ͻ
        Ȥ    о Ͽ  
           ִ.</p>
    
        <p>Apache 2.0 ̷ ȭ 踦   ⺻
        κп Ȯߴ.  ý Ʈ Ʈ ϰ,
        û ޾Ƶ̸, ޾Ƶ û óϱ ڽĵ鿡
        йϴ ó  (Multi-Processing Modules, MPMs)
          ִ.</p>
    
        <p>   ȭϸ ΰ ߿ 
        ִ:</p>
    
        <ul>
          <li><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code> Apache 1.3 
          POSIX  ü Ʈ    ִ ,
          ġ  پ ü  ϰ ȿ
            ִ.   Ưȭ MPM  ٸ
          ü ȴ.</li>
    
          <li> Ư Ʈ 䱸ǿ  Ưȭ  ִ.
             Ȯ尡ɼ(scalability) ʿ Ʈ
          <code class="module"><a href="./mod/worker.html">worker</a></code>   MPM ϰ,
            Ʈ ȣȯ ʿ Ʈ
          <code class="module"><a href="./mod/prefork.html">prefork</a></code>ing MPM    ִ.
          ߰ ٸ ھ̵  ȣƮ ϴ
          (<code class="module"><a href="./mod/perchild.html">perchild</a></code>)  Ư ɵ
          ȴ.</li>
        </ul>
    
        <p>ڰ ⿡ MPM ٸ ġ   
        δ. ֵ ̴  ѹ   MPM ؾ
        Ѵٴ ̴. 밡 MPM  <a href="mod/">
         </a> ִ.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="choosing" id="choosing">MPM ϱ</a></h2>
    
        <p>MPMs ߿ Ͽ  ϵǾ Ѵ.
        带 ϴ  Ϸ ˸  Լ
        ȭ  ִ. н  MPM 带 
         ƴϹǷ, MPM ߿ õǾ ġ
        ϵɶ ġ   ӵ .</p>
    
        <p>ϴ MPM Ϸ ./configure ũƮ
        with-mpm= <em>NAME</em> ƱԸƮ ϶. <em>NAME</em>
        ϴ MPM ̸̴.</p>
    
        <p>  <code>./httpd -l</code> ɾ 
        MPM   ִ.   ɾ MPM Ͽ  ϵ
          ˷ش.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="defaults" id="defaults">MPM ⺻</a></h2>
    
    <p> ǥ  ü ⺻ MPM ش. Ͻ
    ٸ    MPM õȴ.</p>
    
    <table>
    
    <tr><td>BeOS</td><td><code class="module"><a href="./mod/beos.html">beos</a></code></td></tr>
    <tr><td>Netware</td><td><code class="module"><a href="./mod/mpm_netware.html">mpm_netware</a></code></td></tr>
    <tr><td>OS/2</td><td><code class="module"><a href="./mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
    <tr><td>н</td><td><code class="module"><a href="./mod/prefork.html">prefork</a></code></td></tr>
    <tr><td></td><td><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code></td></tr>
    </table>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/mpm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html.pt-br������������������������������������������������0000664�0001751�0001751�00000042627�14743132254�022107� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="pt-br" xml:lang="pt-br"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Descri&#231;&#227;o das novas funcionalidades do Apache 2.0 - Servidor HTTP Apache Vers&#227;o 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Gloss&#225;rio</a> | <a href="./sitemap.html">Mapa do site</a></p>
    <p class="apache">Servidor HTTP Apache Vers&#227;o 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documenta&#231;&#227;o</a> &gt; <a href="./">Vers&#227;o 2.4</a></div><div id="page-content"><div id="preamble"><h1>Descri&#231;&#227;o das novas funcionalidades do Apache 2.0</h1>
    <div class="toplang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta tradu&#231;&#227;o pode estar desatualizada.
            Confira a vers&#227;o em Ingl&#234;s para mudan&#231;as recentes.</div>
    
      <p>Esse documento descreve algumas das mudan&#231;as principais
         entre as vers&#245;es 1.3 e 2.0 do Servidor HTTP Apache.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Principais Melhorias</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Melhorias nos M&#243;dulos</a></li>
    </ul><h3>Veja tamb&#233;m</h3><ul class="seealso"><li><a href="upgrading.html">Atualizando da vers&#227;o 1.3 para 2.0</a></li><li><a href="#comments_section">Coment&#225;rios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Principais Melhorias</a></h2>
        
    
        <dl>
          <dt>Threading Unix</dt>
    
          <dd>Em sistemas Unix com suporte a threads POSIX, o Apache pode
          funcionar em modo h&#237;brido multiprocesso e multithread. N&#227;o funciona
          em todas configura&#231;&#245;es, mas melhora a escalabilidade em muitas.</dd>
    
          <dt>Novo Sistema de Compila&#231;&#227;o</dt>
    
          <dd>O sistema de compila&#231;&#227;o foi reescrito do zero para utilizar o
          <code>autoconf</code> e o <code>libtool</code>, tornando a
          configura&#231;&#227;o do sistema Apache mais similar a de outros
          pacotes.</dd>
    
          <dt>Suporte Multi-protocolo</dt>
    
          <dd>O Apache possui agora uma infraestrutura feita para suportar
          m&#250;ltiplos protocolos. O m&#243;dulo <code class="module"><a href="./mod/mod_echo.html">mod_echo</a></code> &#233;  um
          exemplo ilustrativo de sua utiliza&#231;&#227;o.</dd>
    
          <dt>Suporte Aperfei&#231;oado para Plataformas N&#227;o-Unix</dt>
    
          <dd>O Apache 2.0 est&#225;  mais r&#225;pido e mais est&#225;vel em plataformas
          N&#227;o-Unix como BeOS, OS/2 e Windows. Com a introdu&#231;&#227;o de m&#243;dulos
          <a href="mpm.html">multi-processamento</a> (MPMs) espec&#237;ficos e a
          Apache Portable Runtime (APR), essas plataformas est&#227;o implementando
          as suas APIs nativas, evitando as camadas de emula&#231;&#227;o POSIX que se
          mostravam lentas e defeituosas.</dd>
    
          <dt>Nova API Apache</dt>
    
          <dd>A API para m&#243;dulos mudou significativamente na vers&#227;o 2.0.
          Muitos dos problemas de ordenamento/prioridade da vers&#227;o
          1.3 foram resolvidos. A vers&#227;o 2.0 faz o ordenamento autom&#225;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.</dd>
    
          <dt>Suporte IPv6</dt>
    
          <dd>Em sistemas onde o IPv6 &#233; suportado pela biblioteca de base
          Apache Portable Runtime, o Apache monitora por padr&#227;o
          as interfaces IPv6. Em adi&#231;&#227;o as diretrizes  <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>, <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code> e <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code>, suportam correntes (strings) de
          endere&#231;os num&#233;ricos do tipo IPv6. (ex. "<code>Listen
          [2001:db8::1]:8080</code>").</dd>
    
          <dt>Filtrando</dt>
    
          <dd>Os m&#243;dulos do Apache agora s&#227;o feito filtros que
          agem na corrente do conte&#250;do na medida que este &#233; entregue, tanto
          na entrada quando na sa&#237;da de dados do servidor. &#201; poss&#237;vel ent&#227;o,
          por exemplo, que o retorno de dados de scripts CGI sejam analisados
          pelas diretrizes do "Server Side Include" usando o filtro <code>INCLUDES</code> do <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>. O m&#243;dulo <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>, permite que programas externos trabalhem
          como filtros do mesmo modo que aplica&#231;&#245;es CGI funcionam como
          manipuladores.</dd>
    
          <dt>Respostas de Erro Multi-linguais</dt>
    
          <dd>Mensagens de erro para o navegador agora s&#227;o fornecidas em
          diversas l&#237;nguas, usando documentos SSI. Podem ser personalizadas
          pelo administrador que desejar definir seus pr&#243;prios
          padr&#245;es.</dd>
    
          <dt>Configura&#231;&#227;o Simplificada</dt>
    
          <dd>Muitas diretrizes confusas foram simplificadas. Entre elas,
          <code>Port</code> e <code>BindAddress</code> n&#227;o existem
          mais; apenas a diretriz <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
          &#233; usada para direcionar endere&#231;os IP; a diretriz <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> especifica o nome do servidor
          e o n&#250;mero da porta apenas para redirecionamento e reconhecimento
          de hospedeiros virtuais.</dd>
    
          <dt>Suporte Nativo ao Unicode do Windows NT</dt>
    
          <dd>O Apache 2.0 para Windows NT agora usa utf-8 para codifica&#231;&#227;o
          de todos os nomes de arquivos. A tradu&#231;&#227;o para o sistema
          base Unicode, torna poss&#237;vel o suporte multi-lingual para todas
          as instala&#231;&#245;es da fam&#237;lia NT, incluindo o Windows 2000 e Windows XP.
          <em>Esse suporte n&#227;o se estende ao Windows 95, 98 ou ME, que
          continuam usando o c&#243;digo de p&#225;ginas da m&#225;quina local para o
          acesso ao sistema de arquivos.</em></dd>
    
          <dt>Biblioteca de Express&#245;es Regulares Atualizada</dt>
    
          <dd>O Apache 2.0 inclui a <a href="http://www.pcre.org/">Biblioteca
          de Express&#245;es Regulares Compat&#237;veis Perl</a> (PCRE).  Todas as
          avalia&#231;&#245;es de express&#245;es regulares usam a mais poderosa sintaxe
          do Perl 5.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Melhorias nos M&#243;dulos</a></h2>
        
    
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd>Novo m&#243;dulo no Apache 2.0. Esse m&#243;dulo &#233; uma interface
          para os protocolos de codifica&#231;&#227;o SSL/TLS fornecidos pela
          OpenSSL.</dd>
    
          <dt><code class="module"><a href="./mod/mod_dav.html">mod_dav</a></code></dt>
    
          <dd>Novo m&#243;dulo no Apache 2.0. Este m&#243;dulo implementa as
          especifica&#231;&#245;es de Autoria Distribu&#237;da e Vers&#245;es (Distributed
          Authoring and Versioning - DAV) para HTTP, para a publica&#231;&#227;o
          e a manuten&#231;&#227;o de conte&#250;do da web.</dd>
    
          <dt><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></dt>
    
          <dd>Novo m&#243;dulo no Apache 2.0.  Esse m&#243;dulo permite o suporte
          a navegadores que solicitam que o conte&#250;do seja comprimido antes
          da entrega, economizando banda da rede.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_ldap.html">mod_auth_ldap</a></code></dt>
    
          <dd>Novo m&#243;dulo no Apache 2.0.41. Este m&#243;dulo permite que 
          bancos de dados LDAP sejam usados para armazenar credenciais
          para Autentica&#231;&#227;o B&#225;sica HTTP. Um m&#243;dulo que o acompanha <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>, fornece a concilia&#231;&#227;o de conex&#245;es e armazenamento
          de resultados.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_digest.html">mod_auth_digest</a></code></dt>
    
          <dd>Inclui suporte adicional para armazenamento de sess&#245;es
          atrav&#233;s de processos que usam mem&#243;ria compartilhada.</dd>
    
          <dt><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></dt>
    
          <dd>Novo m&#243;dulo no Apache 2.0. Este modo experimental permite a
          tradu&#231;&#227;o de tabelas de caracteres ou re-codifica&#231;&#227;o.</dd>
    
          <dt><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></dt>
    
          <dd>Novo m&#243;dulo no Apache 2.0. Esse m&#243;dulo inclui a funcionalidade
          do <code>mod_mmap_static</code> do Apache 1.3, al&#233;m de disponibilizar
          outras possibilidades de armazenamento.</dd>
    
          <dt><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></dt>
    
          <dd>Este m&#243;dulo est&#225; muito mais flex&#237;vel no Apache 2.0. Pode
          modificar pedidos de cabe&#231;alhos usados pelo <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>, e incondicionalmente pode ajustar cabe&#231;alhos de respostas.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd>O m&#243;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&#227;o HTTP/1.1. Al&#233;m disso, uma nova se&#231;&#227;o
          de configura&#231;&#227;o <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> fornece controles mais leg&#237;veis (e internamente
          mais r&#225;pidos) para sites com proxies; configura&#231;&#245;es
          sobrecarregadas <code>&lt;Directory "proxy:..."&gt;</code>, n&#227;o
          s&#227;o suportadas. O m&#243;dulo agora &#233; dividido em suporte
          de protocolos espec&#237;ficos incluindo <code>proxy_connect</code>,
          <code>proxy_ftp</code> e <code>proxy_http</code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></dt>
    
          <dd>A nova diretriz <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code> pode ser usada para assegurar que
          o cliente receba um &#250;nico documento em todos os casos, ao inv&#233;s de
          respostas "NOT ACCEPTABLE" ou "MULTIPLE CHOICES". Novos algoritmos
          de negocia&#231;&#227;o e vis&#245;es m&#250;ltiplas (MultiViews) foram organizados para
          obter resultados mais consistentes e uma nova forma de tipo de mapa
          (map type) que podem incluir o conte&#250;do de documentos &#233; fornecido.</dd>
    
          <dt><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></dt>
    
          <dd>As listagens de diret&#243;rios autom&#225;ticas podem ser
          configuradas para usar tabelas HTML para formata&#231;&#245;es mais limpas
          e permitir controles mais acurados de classifica&#231;&#227;o, incluindo
          ordena&#231;&#227;o por vers&#227;o e filtro da lista de
          diret&#243;rios atrav&#233;s de caracteres-coringa.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
    
          <dd>Novas diretrizes permitem que as tags padr&#245;es <em>start</em> e
          <em>end</em> para elementos SSI, possam ser alteradas e permitir que
          as configura&#231;&#245;es de formatos de erro e hora sejam inclu&#237;dos no
          arquivo de configura&#231;&#227;o principal, ao inv&#233;s de serem adicionadas
          ao documento SSI. Resultados de an&#225;lises de express&#245;es regulares
          e agrupamento (baseadas na sintaxe de express&#245;es regulares do Perl)
          podem ser obtidas usando as vari&#225;veis do m&#243;dulo <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>, de <code>$0</code> a <code>$9</code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_dbm.html">mod_auth_dbm</a></code></dt>
    
          <dd>Agora suporta m&#250;ltiplos tipos de banco de dados similares ao DBM,
          usando a diretriz <a href="../2.0/mod/mod_auth_dbm.html#AuthDBMType">
    	  <code>AuthDBMType</code></a>
          .</dd>
    
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>L&#237;nguas Dispon&#237;veis: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" title="Portugu&#234;s (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Coment&#225;rios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_0.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licenciado sob a <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Diretrizes</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Gloss&#225;rio</a> | <a href="./sitemap.html">Mapa do site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/mpm.html.zh-cn.utf8��������������������������������������������������������0000664�0001751�0001751�00000026417�14743132254�020430� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>多处理模块(MPM) - Apache HTTP 服务器 版本 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="./">版本 2.4</a></div><div id="page-content"><div id="preamble"><h1>多处理模块(MPM)</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
    <p>本文档介绍了什么是多处理模块,以及 Apache HTTP 服务器如何使用它们。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">介绍</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#defaults">默认 MPM</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#static">构建 MPM 为静态模块</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#dynamic">构建 MPM 为动态模块</a></li>
    </ul><h3>参见</h3><ul class="seealso"><li><a href="#comments_section">评论</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">介绍</a></h2>
    
        <p>Apache HTTP 服务器被设计为一个功能强大,并且灵活的 web 服务器,
        可以在很多平台与环境中工作。不同平台和不同的环境往往需要不同
        的特性,或可能以不同的方式实现相同的特性最有效率。Apache httpd
        通过模块化的设计来适应各种环境。这种设计允许网站管理员通过在
        编译时或运行时,选择哪些模块将会加载在服务器中,来选择服务器特性。</p>
    
        <p>Apache HTTP 服务器 2.0 扩展此模块化设计到最基本的 web 服务器功能。
        它提供了可以选择的多处理模块(MPM),用来绑定到网络端口上,接受请求,
        以及调度子进程处理请求。</p>
    
        <p>扩展到这一级别的服务器模块化设计,带来两个重要的好处:</p>
    
        <ul>
          <li>Apache httpd 能更优雅,更高效率的支持不同的平台。尤其是
          Apache httpd 的 Windows 版本现在更有效率了,因为
          <code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code> 能使用原生网络特性取代在
          Apache httpd 1.3 中使用的 POSIX 层。它也可以扩展到其它平台
          来使用专用的 MPM。</li>
    
          <li>Apache httpd 能更好的为有特殊要求的站点定制。例如,要求
          更高伸缩性的站点可以选择使用线程的 MPM,即
          <code class="module"><a href="./mod/worker.html">worker</a></code> 或 <code class="module"><a href="./mod/event.html">event</a></code>;
          需要可靠性或者与旧软件兼容的站点可以使用
          <code class="module"><a href="./mod/prefork.html">prefork</a></code>。</li>
        </ul>
    
        <p>在用户看来,MPM 很像其它 Apache httpd 模块。主要是区别是,在任何时间,
        必须有一个,而且只有一个 MPM 加载到服务器中。可用的 MPM 列表位于
        <a href="mod/">模块索引页面</a>。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="defaults" id="defaults">默认 MPM</a></h2>
    
    <p>下表列出了不同系统的默认 MPM。如果你不在编译时选择,那么它就是你将要使用的 MPM。</p>
    
    <table class="bordered"><tr><td>Netware</td><td><code class="module"><a href="./mod/mpm_netware.html">mpm_netware</a></code></td></tr>
    <tr class="odd"><td>OS/2</td><td><code class="module"><a href="./mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
    <tr><td>Unix</td><td><code class="module"><a href="./mod/prefork.html">prefork</a></code>,<code class="module"><a href="./mod/worker.html">worker</a></code> 或
        <code class="module"><a href="./mod/event.html">event</a></code>,取决于平台特性</td></tr>
    <tr class="odd"><td>Windows</td><td><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code></td></tr>
    </table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="static" id="static">构建 MPM 为静态模块</a></h2>
    
        <p>在全部平台中,MPM 都可以构建为静态模块。在构建时选择一种
        MPM,链接到服务器中。如果要改变 MPM,必须重新构建。</p>
    
        <p>为了使用指定的 MPM,请在执行 <code class="program"><a href="./programs/configure.html">configure</a></code> 脚本
          时,使用参数 <code>--with-mpm=<em>NAME</em></code>。<em>NAME</em>
          是指定的 MPM 名称。</p>
    
        <p>编译完成后,可以使用 <code>./httpd -l</code> 来确定选择的 MPM。
        此命令会列出编译到服务器程序中的所有模块,包括 MPM。</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dynamic" id="dynamic">构建 MPM 为动态模块</a></h2>
    
        <p>在 Unix 或类似平台中,MPM 可以构建为动态模块,与其它动态模块一样在运行时加载。
        构建 MPM 为动态模块允许通过修改 <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        指令内容来改变 MPM,而不用重新构建服务器程序。</p>
    
        <p>在执行 <code class="program"><a href="./programs/configure.html">configure</a></code> 脚本时,使用
        <code>--enable-mpms-shared</code> 选项可以启用此特性。
        当给出的参数为 <code><em>all</em></code> 时,所有此平台支持的 MPM
        模块都会被安装。还可以在参数中给出模块列表。</p>
    
        <p>默认 MPM,可以自动选择或者在执行 <code class="program"><a href="./programs/configure.html">configure</a></code>
        脚本时通过 <code>--with-mpm</code> 选项来指定,然后出现在生成的服务器配置文件中。
        编辑 <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> 指令内容可以选择不同的 MPM。</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">评论</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/mpm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html.tr.utf8����������������������������������������������0000664�0001751�0001751�00000042573�14743132254�022375� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Sunucusu 2.0’da Yeni olan Özellikler - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Sunucusu 2.0’da Yeni olan Özellikler</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>Bu belgede Apache HTTP Sunucusunun 1.3 ve 2.0 sürümleri arasındaki
        başlıca değişikliklerin bazılarına değinilmiştir.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Çekirdekteki Gelişmeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Modüllerdeki Gelişmeler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="upgrading.html">1.3’ten 2.0’a Yükseltme</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Çekirdekteki Gelişmeler</a></h2>
        
    
        <dl>
          <dt>Unix Evreleri</dt>
    
          <dd>POSIX evreleri desteği olan Unix sistemlerinde Apache httpd, çok evreli
            kipte çok süreçlilik şeklinde melez bir yapıda çalışır. Bu bir çok
            bakımdan ölçeklenebilirliği arttırsa da bütün yapılandırmalarda
            sağlanamaz.</dd>
    
          <dt>Yeni Paket Derleme Sistemi</dt>
    
          <dd>Yeni kaynak paketi derleme sistemi <code>autoconf</code> ve
            <code>libtool</code>’a dayalı olarak sıfırdan, yeni baştan yazıldı.
            Böylece Apache httpd’nin paket yapılandırma sistemi diğer paketlerinkiyle
            benzerlik kazanmış oldu.</dd>
    
          <dt>Çok Sayıda Protokol Desteği</dt>
    
          <dd>Apache HTTP Sunucusu artık çok sayıda protokol ile hizmet sunacak bir
            alt yapıya sahiptir. Örneğin, <code class="module"><a href="./mod/mod_echo.html">mod_echo</a></code> modülü bu
            amaçla yazılmıştır.</dd>
    
          <dt>Unix dışı platformalara daha iyi destek</dt>
    
          <dd>Apache HTTP Sunucusu 2.0 sürümleri,  BeOS, OS/2, Windows gibi Unix olmayan
            platformlarda daha hızlı ve daha kararlı çalışacak duruma
            getirilmiştir. Genelde iyi geliştirilmemiş olan dolayısıyla istenen
            başarımı sağlayamayan POSIX taklit katmanlarının kullanımından
            vazgeçilmiş, platforma özgü <a href="mpm.html">çok süreçlilik
            modülleri</a> (MPM) ve Apache Taşınabilirlik Arayüzü (APR) sayesinde
            bu platformlar artık kendi doğal programlama arayüzleriyle
            gerçeklenir olmuştur.</dd>
    
          <dt>Yeni Apache httpd Programlama Arayüzü</dt>
    
          <dd>Modüller için kullanılan programlama arayüzü 2.0 sürümüyle önemli
            değişikliklere uğramıştır. 1.3 sürümünde görülen modüllerle ilgili
            sıralama/öncelik sorunlarının çoğu giderilmiştir. 2.0 sürümü bu
            işlemleri daha bir özdevimli yapar olmuştur; daha fazla esneklik
            sağlamak için artık kancalı modül sıralaması kullanılabilmektedir.
            Ayrıca, arayüze, Apache HTTP Sunucususu çekirdeğini yamamaya gerek kalmadan
            modüllerle sunucu yeteneklerinin arttırılabilmesini sağlayan yeni
            çağrılar eklenmiştir.</dd>
    
          <dt>IPv6 Desteği</dt>
    
          <dd>IPv6’nın Apache Taşınabilirlik Arayüzü kütüphanesi tarafından
            desteklendiği sistemlerde Apache httpd öntanımlı olarak IPv6 soketlerini
            dinler. Bundan başka, <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>, <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code> ve <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> yönergelerinin IPv6 sayısal adres
            dizgelerini desteklemesi sağlanmıştır.<br />Örnek: <code>Listen
            [2001:db8::1]:8080</code></dd>
    
          <dt>Süzme</dt>
    
          <dd>Apache httpd modülleri, artık, sunucuya teslim edilen veya sunucudan
            teslim alınan içerik akımları üzerinde süzgeç gibi davranacak şekilde
            yazılabilmektedir. Bu sayede, örneğin CGI betiklerinin çıktılarının
            <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> modülünün <code>INCLUDES</code> süzgeci
            kullanılarak SSI yönergeleri için çözümlenmesi mümkündür. CGI
            programlarının birer eylemci olarak davranması gibi,
            <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> modülü de harici programların birer
            süzgeç olarak davranabilmesini mümkün kılar.</dd>
    
          <dt>Çok Dilli Hata Yanıtları</dt>
    
          <dd>Hata yanıtlarının tarayıcılara yönelik iletileri artık SSI
            belgeleri kullanılarak çeşitli dillerde sağlanabilmektedir. Bunlar
            ayrıca yönetici tarafından görünüş ve kullanışlılık tutarlılığı
            bakımından kişiselleştirilebilmektedir.</dd>
    
          <dt>Basitleştirilmiş Yapılandırma</dt>
    
          <dd>Bazı yönergelerle ilgili kafa karışıklıkları giderilmiştir.
            Bilhassa belli bir IP adresini dinlemek için kullanılan
            <code>Port</code> ve <code>BindAddress</code> yönergeleri ile ilgili
            karışıklığın önüne geçmek için sadece <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> yönergesi yeterli olmaktadır. <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> yönergesi ise sadece yönlendirme
            ve sanal konak tanıma amacıyla sunucu ismi ve port belirtiminde
            kullanılmaktadır.</dd>
    
          <dt>Doğal Windows NT Unicode Desteği</dt>
    
          <dd>Apache httpd 2.0, Windows NT üzerinde artık tüm dosya sistemi
            kodlamalarında utf-8 kullanmaktadır. Bu destek, Windows 2000 ve
            Windows XP dahil tüm Windows NT temelli sistemlere çok dillilik
            desteğini sağlamak üzere mevcut Unicode dosya sistemine doğrudan
            uyarlanır. <em>Dosya sisteminde makinenin yerel karakter kodlamasını
            kullanan kullanan Windows 95, 98 ve ME için bu destek
            yoktur.</em></dd>
    
          <dt>Düzenli İfade Kütüphanesi Güncellemesi</dt>
    
          <dd>Apache httpd 2.0’da <a href="http://www.pcre.org/">Perl uyumlu düzenli
            ifade kütüphanesi</a> bulunur. Tüm düzenli ifadelerde artık çok daha
            güçlü olan Perl 5 sözdizimi kullanılmaktadır.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Modüllerdeki Gelişmeler</a></h2>
        
    
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd>Apache httpd 2.0’da yeni olan bu modül,  OpenSSL tarafından sağlanan
            SSL/TLS şifreleme protokollerine bir arayüzdür.</dd>
    
          <dt><code class="module"><a href="./mod/mod_dav.html">mod_dav</a></code></dt>
    
          <dd>Apache httpd 2.0’da yeni olan bu modül, site içeriğinin destek ve bakımı
            için HTTP dağıtık yazım ve sürüm yönetimi (DAV - Distributed
            Authoring and Versioning) belirtimini gerçekler.</dd>
    
          <dt><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></dt>
    
          <dd>Apache httpd 2.0’da yeni olan bu modül sayesinde ağ band genişliğinden
            daha verimli yararlanabilmek için içeriğin sıkıştırılarak
            gönderilmesini talep eden tarayıcıların desteklenmesi mümkün
            olmuştur.</dd>
    
          <dt><code class="module">mod_auth_ldap</code></dt>
    
          <dd>Apache httpd 2.0.41’de yeni olan bu modül, HTTP temel kimlik
            doğrulamasında kullanılan delillerin saklanması için LDAP
            veritabanının kullanılabilmesini mümkün kılar. Kardeş modülü olan
            <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> ise bağlantı havuzlaması ve sonuçların
            önbelleğe alınması ile ilgilenir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_digest.html">mod_auth_digest</a></code></dt>
    
          <dd>Paylaşımlı belleği kullanan süreçlere karşı oturum önbelleklemesi
            için ek destek içerir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></dt>
    
          <dd>Apache httpd 2.0’da yeni olan bu deneysel modül, karakter kümesi
            dönüşümleri veya kaydı için destek sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></dt>
    
          <dd>Apache httpd 2.0’da yeni olan bu modül, Apache HHP Sunucusu 1.3’teki
            <code>mod_mmap_static</code> modülünün işlevselliğini içermenin
            yanında buna önbellekleme yetenekleri de ekler.</dd>
    
          <dt><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></dt>
    
          <dd>Bu modül Apache httpd 2.0’da daha esnek hale getirilmiştir. Artık
            <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> tarafından kullanılan istek başlıkları
            değiştirilebilmekte ve bunlar yanıt başlıklarına şartlı olarak
            atanabilmektedir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd>Bu modül HTTP/1.1 uyumlu vekaleti daha güvenilir kılmak ve yeni
            süzgeç alt yapısının getirilerinden de yararlanmak amacıyla yeni
            baştan yazılmıştır. Bunun yanında, <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> bölümünün yeni hali vekil siteleri
            desteklemek bakımından daha okunabilir (ve kendi içinde daha hızlı)
            olması sağlanmıştır; <code>&lt;Directory "proxy:..."&gt;</code>
            yapılandırması artık desteklenmemektedir. Modül,
            <code>proxy_connect</code>, <code>proxy_ftp</code> ve
            <code>proxy_http</code> şeklinde her biri belli bir protokolü
            destekleyen ayrı modüllere bölünmüştür.</dd>
    
          <dt><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></dt>
    
          <dd>Yeni <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code> yönergesi sayesinde istemciye
            “Kabul edilebilir bir gösterim çeşidi yok” ya da “Çok sayıda seçim
            belirtilmiş” yanıtını döndürmek yerine tüm durumlara uyan bir
            sayfanın gönderilebilmesi sağlanmıştır. Bundan başka, uzlaşım ve
            <code>MultiViews</code> algoritmaları daha tutarlı sonuçlar elde
            etmek amacıyla elden geçirilmiş ve belge içeriği ile daha iyi eşleşen
            yeni bir tür eşlem yapısı sağlanmıştır.</dd>
    
          <dt><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></dt>
    
          <dd>Dizin içeriklerinin özdevimli listelenmesi artık HTML tabloları
            kullanılacak şekilde yapılandırılabilmektedir. Böylece sayfa daha iyi
            biçemlenebilmekte, içerik daha hassas sıralanabilmekte, sürüm
            numarasına göre sıralama yapılabilmekte ve dosya ismi kalıpları
            kullanılarak sadece istenen içerik listelenebilmektedir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
    
          <dd>Yeni yönergeler, değiştirilecek SSI elemanları için öntanımlı
            başlangıç ve bitiş etiketlerine izin vermekte, hataların ve zaman
            biçemleme yapılandırmalarının SSI belgesinde değil ana yapılandırma
            dosyasında bulunması mümkün olmaktadır. Düzenli ifadelerin gruplanmış
            sonuçları (Perl düzenli ifade sözdizimi kullanılmaktadır)
            <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> modülünün <code>$0</code> ..
            <code>$9</code> değişkenleri sayesinde kullanılabilmektedir.</dd>
    
          <dt><code class="module">mod_auth_dbm</code></dt>
    
          <dd><code class="directive">AuthDBMType</code> yönergesi
            sayesinde artık çok sayıda DBM tarzı veritabanı türü
            desteklenmektedir.</dd>
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_0.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_2.html.tr.utf8����������������������������������������������0000664�0001751�0001751�00000050661�14743132254�022374� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Sunucusu 2.2’de Yeni olan Özellikler - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Sunucusu 2.2’de Yeni olan Özellikler</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>Bu belgede Apache HTTP Sunucusunun 2.0 ve 2.2 sürümleri arasındaki
        başlıca farklara değinilmiştir. 1.3 sürümüne göre yeni özellikler için <a href="new_features_2_0.html">Apache 2.0’da Yeni olan Özellikler</a>
        belgesine bakınız.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Çekirdekteki Gelişmeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Modüllerdeki Gelişmeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Programlardaki Gelişmeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Modül Geliştirici Değişiklikleri</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Çekirdekteki Gelişmeler</a></h2>
        
        <dl>
    
          <dt>Authn/Authz</dt>
          <dd>Mevcut kimlik doğrulama ve yetkilendirme modüllerinin iç işleyişi
            yeniden düzenlendi. Yeni <code>mod_authn_alias</code> modülü
            (2.3/2.4 sürümlerinde kaldırılmıştır) belli kimlik doğrulama
            yapılandırmalarını büyük oranda basitleştirebilir. Bu değişikliklerin
            kullanıcıları ve modül yazarlarını nasıl etkilediğini öğrenmek için
            <a href="#module">modül değişikliklerine</a> ve <a href="#developer">geliştirici değişikliklerine</a> bakabilirsiniz.</dd>
    
          <dt>Önbellekleme</dt>
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> ve
            <code>mod_mem_cache</code> (2.3/2.4 sürümlerinde kaldırılmıştır)
            modüllerinde büyük oranda değişikliğe gidilerek bunlar deneysel
            olmaktan çıkarılıp üretim amaçlı modüller haline getirildiler.
            <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> tarafından kullanılan disk
            alanının  <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code> tarafından
            düzenli aralıklarla temizlenebilmesi sağlandı.</dd>
    
          <dt>Yapılandırma</dt>
          <dd>Öntanımlı yapılandırma basitleştirildi ve modüler bir yapıya
            kavuşturuldu. Sık kullanılan ortak özellikleri etkinleştirmekte
            kullanılan yapılandırmalar gruplanarak bunların Apache ile gelmesi ve
            ana sunucu yapılandırılırken yapılandırmaya kolayca eklenebilmesi
            sağlandı.</dd>
    
          <dt>Nazikçe Durdurma</dt>
          <dd><code class="module"><a href="./mod/prefork.html">prefork</a></code>, <code class="module"><a href="./mod/worker.html">worker</a></code> ve
            <code class="module"><a href="./mod/event.html">event</a></code>  MPM’leri artık <code class="program"><a href="./programs/httpd.html">httpd</a></code>’yi <a href="stopping.html#gracefulstop"><code>graceful-stop</code></a>
            sinyali sayesinde nazikçe durdurabilmektedir.
            <code class="program"><a href="./programs/httpd.html">httpd</a></code> programının sonlandırılmasındaki gecikmelere
            karşı bir önlem olarak, isteğe bağlı bir zaman aşımı belirtmeyi
            mümkün kılan <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code> yönergesi
            sayesinde sunum sürüyor olsa bile <code class="program"><a href="./programs/httpd.html">httpd</a></code>
            sonlandırılabilmektedir.</dd>
    
          <dt>Vekil Sunucu</dt>
          <dd>Yeni <code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> modülü ile
            <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> için yük dengeleme hizmetleri sağlanmış,
            yeni <code class="module"><a href="./mod/mod_proxy_ajp.html">mod_proxy_ajp</a></code> modülü ile <a href="http://tomcat.apache.org/">Apache Tomcat</a> tarafından
            kullanılan <em>Apache JServ Protokolünün 1.3 sürümü</em> için destek
            eklenmiştir.</dd>
    
          <dt>Düzenli İfade Kütüphanesi Güncellemesi</dt>
          <dd>Apache, <a href="http://www.pcre.org/">Perl uyumlu düzenli ifade
            kütüphanesinin 5.0 sürümünü</a> (PCRE) içermektedir.
            <code class="program"><a href="./programs/configure.html">configure</a></code> betiğinin <code>--with-pcre</code>
            seçeneği sayesinde <code class="program"><a href="./programs/httpd.html">httpd</a></code> programı PCRE destekli
            olarak derlenebilmektedir.</dd>
    
          <dt>Akıllı Süzme</dt>
          <dd><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> çıktı süzgeç zincirinin devingen olarak
            yapılandırılmasını sağlar. Süzgeçlerin herhangi bir istek veya yanıt
            başlığına veya bir ortam değişkenine dayanarak koşullu olarak
            yerleştirilmesini mümkün kılar ve bunu yaparken 2.0 mimarisindeki
            sorunlu bağımlılıklar ve sıralama sorunlarının da üstesinden
            gelir.</dd>
    
          <dt>Büyük Dosya (&gt;2GB) Desteği</dt>
          <dd><code class="program"><a href="./programs/httpd.html">httpd</a></code> artık günümüzün 32 bitlik Unix
            sistemlerinde bulunan 2 GB’lık büyük dosyaları destekleyecek tarzda
            derlenebilmektedir. 2 GB’lık istek gövdelerine destek de ayrıca
            eklenmiştir.</dd>
    
          <dt>Event MPM</dt>
          <dd><code class="module"><a href="./mod/event.html">event</a></code> MPM modülü sürekli bağlantı isteklerinin
            işlenmesi ve bağlantıların kabul edilmesi için ayrı bir evre
            kullanır. Sürekli bağlantı (keepalive) isteklerinin işlenmesi
            geleneksel olarak httpd’nin buna bir <code class="module"><a href="./mod/worker.html">worker</a></code>
            adamasını gerektirirdi. Bu adanmış <code class="module"><a href="./mod/worker.html">worker</a></code> bağlantı
            zaman aşımına uğrayıncaya değin tekrar kullanılamazdı.</dd>
    
          <dt>SQL Veritabanı Desteği</dt>
          <dd><code class="module"><a href="./mod/mod_dbd.html">mod_dbd</a></code> modülü <code>apr_dbd</code> arayüzü ile
            birlikte, ihtiyacı olan modüllere SQL desteği sağlar. Evreli MPM’ler
            için bağlantı havuzlamasını destekler.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Modüllerdeki Gelişmeler</a></h2>
        
        <dl>
          <dt>Authn/Authz</dt>
          <dd>Kimlik Doğrulama, Yetkilendirme ve Erişim Denetimi ile ilgili
            modüller özetli kimlik doğrulamasına daha iyi destek sağlamak
            amacıyla yeniden isimlendirildi. Örneğin, <code>mod_auth</code>
            modülü şimdi <code class="module"><a href="./mod/mod_auth_basic.html">mod_auth_basic</a></code> ve
            <code class="module"><a href="./mod/mod_authn_file.html">mod_authn_file</a></code> diye iki modüle bölünmüştür.;
            <code>mod_auth_dbm</code> modülünün ismi
            <code class="module"><a href="./mod/mod_authn_dbm.html">mod_authn_dbm</a></code> ve <code>mod_access</code>  modülünün
            ismi de <code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code> olarak değiştirilmiştir.
            Ayrıca, belli kimlik doğrulama yapılandırmalarını basitleştirmek
            üzere <code>mod_authn_alias</code> diye yeni bir modül vardır
            (2.3/2.4 sürümlerinde kaldırılmıştır).
          </dd>
    
          <dt><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd>Bu modül 2.0 sürümü <code>mod_auth_ldap</code> modülünün 2.2
            <code>Authn/Authz</code> arayüzüne bir uyarlamasıdır. <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code> yönergesine LDAP
            öznitelik değerlerinin ve karmaşık arama süzgeçlerinin kullanımı gibi
            yeni özellikler eklenmiştir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_authz_owner.html">mod_authz_owner</a></code></dt>
          <dd>Dosya sistemi üzerindeki dosyalara erişimi dosya sahibine göre
            düzenleyebilmeyi sağlayan yeni bir modüldür.</dd>
    
          <dt><code class="module"><a href="./mod/mod_version.html">mod_version</a></code></dt>
          <dd>Çalışan sunucunun sürüm numarasına göre belli yapılandırma
            bloklarını etkinleştirebilen bir modüldür.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd>Apache tarafından çözümlenen haliyle yapılandırma yönergelerinin
            gösterilmesini sağlayan yeni <code>?config</code> parametresini
            ekler. Modül ayrıca, <code>httpd -V</code>’nin yaptığı gibi ek olarak
            derleme bilgisini ve tüm istek kancalarının sırasını da gösterir.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
          
          <dd>TLS şifrelemesini HTTP/1.1 için güncelleyen <a href="http://www.ietf.org/rfc/rfc2817.txt">RFC 2817</a> için destek
            sağlar.</dd>
    
          <dt><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></dt>
          <dd><code>mod_imap</code> modülünün ismi yanlış anlamalara meydan
            vermemek için <code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code> olarak değiştirildi.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programs" id="programs">Programlardaki Gelişmeler</a></h2>
        
        <dl>
          <dt><code class="program"><a href="./programs/httpd.html">httpd</a></code></dt>
          <dd>Mevcut yapılandırmaya göre yüklenen modülleri listelemek için
            <code>-M</code> diye yeni bir komut satırı seçeneği eklendi.
            <code>-l</code> seçeneğinin aksine, bu seçenekle elde edilen liste
            <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> üzerinden yüklenen DSO’ları içerir.</dd>
    
          <dt><code class="program"><a href="./programs/httxt2dbm.html">httxt2dbm</a></code></dt>
          <dd><code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> yönergesinde
            <code>dbm</code> eşlem türü ile kullanmak üzere metin girdilerden DBM
            dosyaları üretmek için kullanılan yeni bir program.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer">Modül Geliştirici Değişiklikleri</a></h2>
        
        <dl>
          <dt><a class="glossarylink" href="./glossary.html#apr" title="sözlüğe bakınız">APR</a> 1.0 Programlama Arayüzü</dt>
    
          <dd>Apache 2.2’de APR 1.0 API kullanılmıştır.  Kullanımı önerilmeyen
            tüm işlevler ve simgeler <code>APR</code> ve
            <code>APR-Util</code>’den kaldırılmıştır. Ayrıntılar için <a href="http://apr.apache.org/">APR Sitesine bakınız</a>.</dd>
    
          <dt>Authn/Authz</dt>
          <dd>Dağıtımla gelen kimlik doğrulama ve yetkilendirme modüllerinin
              isimleri aşağıdaki gibi değiştirildi:
              <ul>
              <li><code>mod_auth_*</code>  -&gt; HTTP kimlik doğrulamasını
                gerçekleştiren modüller.</li>
              <li><code>mod_authn_*</code> -&gt; Kimlik doğrulamasının artalanına
                destek sağlayan modüller.</li>
              <li><code>mod_authz_*</code> -&gt; Yetkilendirmeyi (veya erişimi)
                gerçekleştiren modüller.</li>
              <li><code>mod_authnz_*</code> -&gt; Kimlik doğrulama ve
                yetkilendirmeyi birlikte gerçekleştiren modüller.</li>
              </ul>
              Yeni kimlik doğrulama artalanının oluşturulmasını büyük oranda
              kolaylaştıran yeni bir kimlik doğrulama artalanı sağlayıcı şeması
              vardır.</dd>
    
          <dt>Bağlantı Hatalarının Günlüklenmesi</dt>
    
          <dd>İstemci bağlantısında ortaya çıkan hataları günlüğe kaydetmek için
            <code>ap_log_cerror</code> isminde yeni bir işlev eklendi. Böyle bir
            durumda günlük kaydı istemcinin IP adresini içermektedir.</dd>
    
          <dt>Deneme Yapılandırma Kancası Eklendi</dt>
    
          <dd>Kullanıcı, <code class="program"><a href="./programs/httpd.html">httpd</a></code>’yi sadece <code>-t</code>
            seçeneği ile kullandığı takdirde özel kod icra edilmesini isteyen
            modüllere yardımcı olmak üzere <code>test_config</code> diye yeni bir
            kanca işlev eklendi.</dd>
    
          <dt>Evreli MPM’lerin Yığıt Boyutunun Ayarlanması</dt>
    
          <dd>Tüm evreli MPM’lerin yığıt boyutunu ayarlamak üzere <code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code> isminde yeni bir
            yönerge eklendi. Öntanımlı yığıt boyutunun küçük olduğu platformlarda
            bazı üçüncü parti modüller tarafından buna ihtiyaç duyulmaktadır.</dd>
    
          <dt>Çıktı süzgeçlerinde protokoller</dt>
    
          <dd>Evvelce her süzgeç etkilediğini yanıt başlıklarının doğru olarak
            üretilmesini sağlamak zorundaydı. Süzgeçler artık protokol yönetimini
            <code>ap_register_output_filter_protocol</code> veya
            <code>ap_filter_protocol</code> işlevi üzerinden
            <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> modülüne devredebilmektedir.</dd>
    
          <dt>İzleme kancası eklendi</dt>
          <dd>İzleme kancası, modüllerin ana (tepe) süreçteki sıradan/zamanlanmış
            işlerini yapacak modülleri etkinleştirir.</dd>
    
          <dt>Düzenli ifade programlama aryüzü değişti</dt>
    
          <dd><code>pcreposix.h</code> başlık dosyası artık yok; yerine
            <code>ap_regex.h</code> dosyası geçti. Eski başlık dosyasınca ifade
            olunan POSIX.2 <code>regex.h</code> gerçeklenimi şimdi
            <code>ap_</code> isim alanı altında <code>ap_regex.h</code> başlık
            dosyasındadır. <code>regcomp</code>, <code>regexec</code> gibi
            işlevlerin yerine de artık <code>ap_regcomp</code>,
            <code>ap_regexec</code> işlevleri geçerlidir.</dd>
    
          <dt>DBD Arayüzü (SQL Veritabanı API)</dt>
    
          <dd><p>Apache 1.x ve 2.0’da, modüller, SQL veritabanlarını kendileri
            yönetebilmek için sorumluluğu alacak bir SQL artalanına ihtiyaç
            duymaktadır. Her biri kendi bağlantısına sahip bir sürü modül
            olduğunda bu yöntem çok verimsiz olabilmektedir.</p>
    
          <p>Apache 2.1 ve sonrasında veritabanı bağlantılarını (evreli olsun
            olmasın MPM’lerin eniyilenmiş stratejileri dahil) yönetmek için
            <code>ap_dbd</code> arayüzü kullanılmıştır. APR 1.2 ve sonrasında ise
            veritabanı ile etkileşim <code>apr_dbd</code> arayüzüyle
            sağlanmıştır.</p>
    
          <p>Yeni modüllerin tüm SQL veritabanı işlemlerinde bu arayüzü
            kullanmaları ÖNERİlir.  Mevcut uygulamaların uygulanabildiği takdirde
            hem kullanıcılarına önerilen bir seçenek olarak hem de şeffaf olarak
            kullanmak üzere kendilerini güncellemeleri ÖNERİir.</p></dd>
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html.ja.utf8����������������������������������������������0000664�0001751�0001751�00000045071�14743132254�022336� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache 2.0 の新機能の概要 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache 2.0 の新機能の概要</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
      <p>この文書では、Apache HTTP サーババージョン 1.3 と 2.0
         の主な違いについて記述しています。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">コア機能の拡張</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">モジュールの拡張</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="upgrading.html">1.3 から 2.0 へのアップグレード</a></li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">コア機能の拡張</a></h2>
        
    
        <dl>
          <dt>Unix のスレッド</dt>
    
          <dd>POSIX スレッドをサポートしている Unix システム上では、
          Apache はマルチプロセス、マルチスレッドのハイブリッドモードで
          実行できるようになりました。これにより
          多くの設定においてスケーラビリティが向上します。</dd>
    
          <dt>新しいビルドシステム</dt>
    
          <dd>ビルドシステムは <code>autoconf</code> と <code>libtool</code>
          に基づいたものになるように、
          新しく書き直されました。これにより、Apache の configure のシステムは
          他のパッケージと似たものになりました。</dd>
    
          <dt>マルチプロトコルサポート</dt>
    
          <dd>Apache に複数のプロトコルを扱うための機構が備わりました。
          例として <code class="module"><a href="./mod/mod_echo.html">mod_echo</a></code> が書かれています。</dd>
    
          <dt>Unix 以外のプラットフォームのサポートの改善</dt>
    
          <dd>Apache 2.0 は BeOS、OS/2、Windows などの Unix 以外の
          プラットフォームで、より速く、より安定して動作するようになりました。
          プラットフォーム特有の <a href="mpm.html">マルチプロセッシングモジュール</a> (MPM) と
          Apache Portable Runtime (APR) の導入により、
          ネイティヴの API で実装されるようになり、
          バグが多く、性能の悪いことが多い POSIX エミュレーションレイヤの使用を
          回避することができました。</dd>
    
          <dt>新しい Apache API</dt>
    
          <dd>2.0 ではモジュールの API が大きく変わりました。
          1.3 にあったモジュールの順番/優先度の問題の多くは
          なくなっているはずです。2.0 は優先度の選択をほとんどを自動的に行ない、
          モジュールの順番はより柔軟性を高めるためにフック毎に行なわれるように
          なりました。また、コア Apache サーバにパッチをあてることなく
          追加のモジュール機能を提供することができるように新しい関数が
          追加されました。</dd>
    
          <dt>IPv6 サポート</dt>
    
          <dd>Apache が使用している Apache Portable Runtime library が
          IPv6 をサポートしているシステムでは Apache は デフォルトで
          IPv6 のソケットを listen します。さらに、
          <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>,
          <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code>,
          <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code>
          の各ディレクティブが IPv6 のアドレスを
          サポートするようになりました (例えば、
          "<code>Listen [2001:db8::1]:8080</code>")。</dd>
    
          <dt>フィルタ</dt>
    
          <dd>Apache のモジュールはサーバから送られてきたり、サーバへ
          送るストリームに対して動作するフィルタとして書くことができるように
          なりました。これにより、例えば CGI スクリプトの出力を
          <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> の <code>INCLUDES</code> フィルタを使って
          Server Side Include のディレクティブを解析する、
          というようなことが可能になりました。<code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>
          で外部プログラムをフィルタとして動作させることができます。
          これは CGI プログラムをハンドラとして動作させるのと
          よく似た方法でできます。</dd>
    
          <dt>多言語エラー応答</dt>
    
          <dd>ブラウザへのエラー応答のメッセージが、SSI の文書を使って
          複数の言語で提供されるようになりました。見ための一貫性を保つために
          管理者がカスタマイズすることもできます。</dd>
    
          <dt>設定の簡素化</dt>
    
          <dd>多くの混乱を招きがちなディレクティブが簡素化されました。
          よく混乱を引き起こしていた <code>Port</code> ディレクティブと 
          <code>Bind</code> ディレクティブは
          なくなりました。<code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
          ディレクティブのみが IP アドレスのバインドに使われます。
          <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> ディレクティブでは
          リダイレクトと vhost の認識のためだけにサーバの名前とポート番号を
          指定します。</dd>
    
          <dt>Windows NT のネイティヴ Unicode サポート</dt>
    
          <dd>Windows NT 上の Apache 2.0 はファイル名の文字エンコード全てに
          utf-8 を使うようになりました。これらは Unicode ファイルシステムに
          直接変換されるので、Windows 2000 と Windows XP を含む、全ての
          Windows NT 系で多言語サポートが提供されます。
          <em>このサポートは、ファイルシステムのアクセス時にローカルの
          コードページを使う Windows 95, 98, ME には適用されません。</em></dd>
    
          <dt>正規表現ライブラリのアップデート</dt>
    
          <dd>Apache 2.0 は <a href="http://www.pcre.org/">Perl
          互換正規表現ライブラリ (PCRE) </a>を含んでいます。
          正規表現の評価には、より強力になった Perl 5
          構文を使用します。</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">モジュールの拡張</a></h2>
        
    
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd>Apache 2.0 の新モジュール。このモジュールは OpenSSL が
          提供する SSL/TLS 暗号プロトコルへのインタフェースです。</dd>
    
          <dt><code class="module"><a href="./mod/mod_dav.html">mod_dav</a></code></dt>
    
          <dd>Apache 2.0 の新モジュール。このモジュールはウェブコンテンツを
          送り、維持するための規格
          HTTP Distributed Authoring and Versioning (DAV) を実装しています。</dd>
    
          <dt><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></dt>
    
          <dd>Apache 2.0 の新モジュール。送信前に送信内容を圧縮して
          ネットワーク帯域を節約する、というリクエストをブラウザが
          要求できるようにします。</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_ldap.html">mod_auth_ldap</a></code></dt>
    
          <dd>Apache 2.0.41 の新モジュール。HTTP 基本認証の証明書を保存するのに、
          LDAP データベースを使用できるようになります。
          関連モジュールの <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> で、
          コネクションのプール機能と結果のキャッシュ機能が提供されます。</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_digest.html">mod_auth_digest</a></code></dt>
    
          <dd>このモジュールは共有メモリを使うことにより、プロセスをまたいだ
          セッションのキャッシュをサポートするようになりました。</dd>
    
          <dt><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></dt>
    
          <dd>Apache 2.0 の新モジュール。この実験的なモジュールは
          キャラクタセットの変換や再符号化を可能にします。</dd>
    
          <dt><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></dt>
    
          <dd>Apache 2.0 の新モジュール。このモジュールには、
          Apache 1.3 における <code>mod_mmap_static</code> 機能が含まれ、
          また、追加のキャッシュ機能が加わっています。</dd>
    
          <dt><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></dt>
    
          <dd>このモジュールは Apache 2.0 で非常に柔軟性が
          高くなりました。<code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>
          で使われるリクエストのヘッダを変更できるようになりましたし、
          応答ヘッダを条件に応じて設定できるようになりました。</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd>proxy モジュールは新しいフィルタの機構を利用するためと、
          より信頼できる、HTTP/1.1 に準拠した proxy を実装するために
          完全に書き直されました。さらに、新しい 
          <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
          設定セクションがproxy されるサイトのより読みやすく (内部的にもより速い)
          設定を提供します。オーバーロードされた
          <code>&lt;Directory "proxy:... &gt;</code>
          設定はサポートされていません。このモジュールは <code>proxy_connect</code>,
          <code>proxy_ftp</code>, <code>proxy_http</code> 
          といった、特定のプロトコルをサポートする
          モジュールに分割されるようになりました。</dd>
    
          <dt><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></dt>
    
          <dd>クライアントが NOT ACCEPTABLE や MULTIPLE CHOICES 応答の
          代わりに常に単独の文書を受けとるようにするために、新しいディレクティブ
          <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>
          を使うことができるようになりました。
          さらに、より一貫性のある結果を提供するために
          ネゴシエーションと MultiViews のアルゴリズムが改善され、
          文書の内容を含めることのできる、新しい形式のタイプマップが
          提供されるようになりました。</dd>
    
          <dt><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></dt>
    
          <dd>Autoindex されるディレクトリの内容一覧が、
          きれいに表示されるために HTML のテーブルを使うように
          設定できるようになりました。また、バージョンによるソーティングなど、
          より細かいソーティングの制御ができるようになり、ディレクトリ
          の内容一覧をワイルドカードにより選別することができるようにもなりました。</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
    
          <dd>新しいディレクティブにより、SSI のデフォルトの開始タグと終了タグを
          変更できるようになりました。また、エラーと時刻の形式の設定が SSI の
          文書中ではなく、主設定ファイル中で行なえるようになりました。
          正規表現の解析とグループ化の結果 (Perl の正規表現の構文に
          基づいたものになりました) を <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>
          の変数 $0 .. $9 により取得できるようになりました。</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_dbm.html">mod_auth_dbm</a></code></dt>
    
          <dd><code class="directive"><a href="./mod/mod_auth_dbm.html#authdbmtype">AuthDBMType</a></code>
          ディレクティブにより、複数の DBM 型のデータベースをサポートする
          ようになりました。</dd>
    
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_0.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sections.html.ko.euc-kr����������������������������������������������������0000664�0001751�0001751�00000062175�14743132254�021361� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1> </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
     <p><a href="configuring.html"></a> ִ
    þ  ü ǰų, Ư 丮, , ȣƮ,
    URL   ִ.   ٸ þ 
    ϱ  ̳ <code>.htaccess</code> 
    ϴ  Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#types">  </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-and-web">Ͻý۰ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">ȣƮ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Ͻ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#whatwhere">ȿ  þ  
    ֳ?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#mergin">ǵ ϴ </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="types" id="types">  </a></h2>
    
    <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
    <p>ǿ ΰ  ִ. κ ſû óȴ.
    شϴ û ȿ  þ Ѵ. ݴ, <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> 
    Ҷ  óѴ. Ҷ ° ̸ ȿ ִ
    þ  û ȴ.  ƴϸ ȿ ִ þ
    Ѵ.</p>
    
    <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>
    þ <code>httpd</code> ࿡  ĶͰ ִ
    쿡 ȿ  þ Ѵ.    ,
     <code>httpd -DClosedForNow</code>  쿡
     û ٸ Ʈ ̷ǵȴ:</p>
    
    <div class="example"><p><code>
    &lt;IfDefine ClosedForNow&gt;<br />
    Redirect / http://otherserver.example.com/<br />
    &lt;/IfDefine&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>
    þ Ư   Ե 쿡 ȿ  þ
    Ѵٴ  ϰ ſ ϴ.   
    ϰų    տ <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>  ־ Ѵ. 
    þ Ư  ġ   ٸ ʿ䰡
     ؾ Ѵ.      
     ֱ   ϱ ϴ þ ȿ θ ȵȴ.</p>
    
    <p>  <code class="module"><a href="./mod/mod_mime_magic.html">mod_mime_magic</a></code>  <code class="directive"><a href="./mod/mod_mime_magic.html#mimemagicfiles">MimeMagicFiles</a></code> þ
    óѴ.</p>
    
    <div class="example"><p><code>
    &lt;IfModule mod_mime_magic.c&gt;<br />
    MimeMagicFile conf/magic<br />
    &lt;/IfModule&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>
    <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>
    ˻ տ "!" ٿ     ִ. ,  ǵ
    ļ Ͽ   ȿ   ִ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-and-web" id="file-and-web">Ͻý۰ </a></h2>
    
    <p>  Ǵ   Ͻý۰ (webspace)
    Ư ҿ   ϴ ͵̴.    ̸
    ϴ  ߿ϴ. Ͻý ü 忡 ũ
     ̴.  , ⺻ ġ ġ ϸ н
    Ͻý  <code>/usr/local/apache2</code>, 
    Ͻý  <code>"c:/Program Files/Apache
    Group/Apache2"</code> ġȴ. (ġ  
    ׻,  ƴ,   ϶.) ݴ
      ϰ Ŭ̾Ʈ Ե Ʈ ̴.
    ׷ н ⺻ ġ ġ    
    <code>/dir/</code> Ͻý 
    <code>/usr/local/apache2/htdocs/dir/</code> شѴ. 
    Ÿ̽     ֱ⶧ ݵ
    Ͻýۿ   ʿ .</p>
    
    <h3><a name="filesystem" id="filesystem">Ͻý </a></h3>
    
    <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> þ
    ǥ ϴ þ Ͻý Ư κп þ
    Ѵ. <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> þ Ե þ
     Ͻý 丮   丮 ȴ. <a href="howto/htaccess.html">.htaccess </a> ص 
    .    , 丮 (index)
    <code>/var/web/dir1</code>  丮 丮 (index)
    ϴ.</p>
    
    <div class="example"><p><code>
    &lt;Directory /var/web/dir1&gt;<br />
    Options +Indexes<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> ǿ Ե þ 
    丮 ִ   ̸  Ͽ ȴ.
     ּκп ִ    , ҿ
     <code>private.html</code>̶ ̸   
    źѴ.</p>
    
    <div class="example"><p><code>
    &lt;Files private.html&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Files&gt;
    </code></p></div>
    
    <p>Ͻý Ư κп ִ  Īϱ <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>  
    Ѵ.    ,
    <code>/var/web/dir1/private.html</code>,
    <code>/var/web/dir1/subdir2/private.html</code>,
    <code>/var/web/dir1/subdir3/private.html</code> 
    <code>/var/web/dir1/</code> 丮 Ʒ ִ ̸
    <code>private.html</code>   źѴ.</p>
    
    <div class="example"><p><code>
    &lt;Directory /var/web/dir1&gt;<br />
    &lt;Files private.html&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Files&gt;<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    
    <h3><a name="webspace" id="webspace"> </a></h3>
    
    <p><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    þ ̿ شϴ ǥ ϴ þ ݴ
    Ư   ٲ۴.    , /private
    ϴ URL-  źεȴ. ⿡
    <code>http://yoursite.example.com/private</code>,
    <code>http://yoursite.example.com/private123</code>,
    <code>http://yoursite.example.com/private/dir/file.html</code>
     <code>/private</code> ڿ ϴ û شȴ.</p>
    
    <div class="example"><p><code>
    &lt;Location /private&gt;<br />
    Order Allow,Deny<br />
    Deny from all<br />
    &lt;/Location&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    þ Ͻýۿ  ʿ䰡 .    Ư
    URL <code class="module"><a href="./mod/mod_status.html">mod_status</a></code> ϴ ġ  ڵ鷯
    Ű ش. Ͻýۿ <code>server-status</code>
     ʿ.</p>
    
    <div class="example"><p><code>
    &lt;Location /server-status&gt;<br />
    SetHandler server-status<br />
    &lt;/Location&gt;
    </code></p></div>
    
    
    <h3><a name="wildcards" id="wildcards">ϵī ǥ</a></h3>
    
    <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    þ C ǥ ̺귯 <code>fnmatch</code> 
     ϴ ϵī ڸ   ִ.
    "*" ڴ  ڿ̶ Ÿ, "?" ڴ   Ѱ
    Ÿ, "[<em>seq</em>]" <em>seq</em> ߿  ڸ Ÿ.
     ϵī嵵 "/" ڸ Ÿ Ѵ. ׷  ڴ
     ؾ Ѵ.</p>
    
    <p>   ʿϸ perlȣȯ <a href="glossary.html#regex">ǥ</a> ϴ <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> 
     ִ. ׷ Ʒ  տ   ǥ 
    ϸ þ Ǵ   ϴ .</p>
    
    <p>  丮  ϴ ǥ ϵī
      :</p>
    
    <div class="example"><p><code>
    &lt;Directory /home/*/public_html&gt;<br />
    Options Indexes<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    <p>ǥ  Ͽ ѹ   ׸Ͽ
      ź  ִ:</p>
    <div class="example"><p><code>
    &lt;FilesMatch \.(?i:gif|jpe?g|png)$&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/FilesMatch&gt;
    </code></p></div>
    
    
    
    <h3><a name="whichwhen" id="whichwhen"> ϳ</a></h3>
    
    <p>Ͻý ǰ    ϳ ϴ  
    ſ . Ͻýۿ ִ ü þ Ҷ ׻
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    Ѵ. (Ÿ̽   ) Ͻýۿ
     ʴ ü þ Ҷ <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> Ѵ.</p>
    
    <p>Ͻýۿ ִ ü  ϱ <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> ϸ
     ȵȴ.  ٸ  (URL)  Ͻý ҿ
      Ƿ, ɾ  ȸ  ֱ ̴. 
      캸:</p>
    
    <div class="example"><p><code>
    &lt;Location /dir/&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Location&gt;
    </code></p></div>
    
    <p>  <code>http://yoursite.example.com/dir/</code>
    ûѴٸ  ۵Ѵ. ׷ ҹڸ ʴ Ͻý
    Ѵٸ Եdz?
    <code>http://yoursite.example.com/DIR/</code> ûϿ 
     ȸ  ִ. ݴ <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> þ  ûϿ
      ҿ 񽺵Ǵ 뿡 ȴ. (ܴ Ͻý
    ũ ϴ . ɺũ Ͽ  丮
    Ͻý  ҿ   ִ. <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> þ ɺũ 󰣴.
    ׷Ƿ    ؼ  <code class="directive"><a href="./mod/core.html#options">Options</a></code> þ Ͽ ɺũ
    ؾ Ѵ.)</p>
    
    <p>Ƹ  ҹڸ ϴ Ͻý ϹǷ
    ̷  Ͼ ʴ´ٰ  𸥴. ׷ ٸ
    ε   ġ  Ͻý ġ  
     ϶. ׷ ϸ ׻ Ͻý  ؾ
    Ѵ. ׷  Ģ ܰ ϳ ִ.  
    <code>&lt;Location /&gt;</code> ǿ θ   Ư
    URL ƴ  û ǹǷ Ϻϰ ϴ.</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">ȣƮ</a></h2>
    
    <p><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
     Ư ȣƮ Ǵ þ Ѵ. ̴ 
    ǻͿ  ٸ    ȣƮ Ҷ
    ϴ.  ڼ  <a href="vhosts/">ȣƮ </a>
    ϶.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Ͻ</a></h2>
    
    <p><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
    <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
      URL  <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> Ͻ 
     ϴ 쿡 ȴ.    , Ͻ
      <code>cnn.com</code> Ʈ   .</p>
    
    <div class="example"><p><code>
    &lt;Proxy http://cnn.com/*&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Proxy&gt;
    </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="whatwhere" id="whatwhere">ȿ  þ  
    ֳ?</a></h2>
    
    <p>  Ǿȿ   ִ þ ˷ þ
    <a href="mod/directive-dict.html#Context"></a> Ȯ϶.
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    밡 þ <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>, <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>, <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code> ǿ 밡ϴ.
    ׷, ܰ ִ:</p>
    
    <ul>
    <li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> þ
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    ǿ   ִ.</li>
    
    <li><code>FollowSymLinks</code>, <code>SymLinksIfOwnerMatch</code>,
    <code class="directive"><a href="./mod/core.html#options">Options</a></code> <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> ̳
    <code>.htaccess</code> Ͽ   ִ.</li>
    
    <li><code class="directive"><a href="./mod/core.html#options">Options</a></code> þ
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>
    ǿ   .</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mergin" id="mergin">ǵ ϴ </a></h2>
    
    <p>  ſ Ư  ȴ.   
    þ ؼϴ  ߿  ֱ⶧  
    ϴ  ߿ϴ.</p>
    
        <p>ϴ :</p>
    
        <ol>
          <li> (ǥ ʴ) <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> <code>.htaccess</code>
          ÿ Ͼ (쿡  <code>.htaccess</code>
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
          ϵ   ִ)</li>
    
          <li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code> (׸
          <code>&lt;Directory ~&gt;</code>)</li>
    
          <li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code> ÿ Ͼ</li>
    
          <li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> ÿ Ͼ</li>
        </ol>
    
        <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> ϰ  ǵ
        Ͽ   óȴ. (  1) <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> 丮
          ª Ϳ  óȴ. ׷  ,
        <code>&lt;Directory /var/web/dir&gt;</code>
        <code>&lt;Directory /var/web/dir/subdir&gt;</code> 
        óѴ.  丮 Īϴ  <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> 
        ִٸ ̵   óѴ. <code class="directive"><a href="./mod/core.html#include">Include</a></code> þ  
        <code class="directive"><a href="./mod/core.html#include">Include</a></code> þ ġ
           ִ ó óѴ.</p>
    
        <p><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>  ȿ Ե 
        ȣƮ  ۿ ִ ش  <em>Ŀ</em> ȴ.
        ׷ ȣƮ ȿ ּ    ִ.</p>
    
        <p><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> û Ҷ, <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> 
        ó <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> ǰ .</p>
    
        <p>      Ѵ.</p>
    
    <div class="note"><h3> </h3>
          
          <code>&lt;Location&gt;</code>/<code>&lt;LocationMatch&gt;</code>
          (<code>Aliases</code> <code>DocumentRoot</code> Ͽ
          URL ϸ ȯϴ) ̸ ܰ  óȴ.
            Ŀ  Ѵ.
    </div>
    
    <h3><a name="merge-examples" id="merge-examples"></a></h3>
    
    <p> ϴ  ϴ . ̵  û
    ȴٰ ϸ þ A &gt; B &gt; C &gt; D &gt; E
     óȴ.</p>
    
    <div class="example"><p><code>
    &lt;Location /&gt;<br />
    E<br />
    &lt;/Location&gt;<br />
    <br />
    &lt;Files f.html&gt;<br />
    D<br />
    &lt;/Files&gt;<br />
    <br />
    &lt;VirtualHost *&gt;<br />
    &lt;Directory /a/b&gt;<br />
    B<br />
    &lt;/Directory&gt;<br />
    &lt;/VirtualHost&gt;<br />
    <br />
    &lt;DirectoryMatch "^.*b$"&gt;<br />
    C<br />
    &lt;/DirectoryMatch&gt;<br />
    <br />
    &lt;Directory /a/b&gt;<br />
    A<br />
    &lt;/Directory&gt;<br />
    <br />
    </code></p></div>
    
    <p>    . <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>  ߿ óϹǷ
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    ǿ ִ Ѱ     ϴ.
    , ϴ  ߿ϹǷ ϶!</p>
    
    <div class="example"><p><code>
    &lt;Location /&gt;<br />
    Order deny,allow<br />
    Allow from all<br />
    &lt;/Location&gt;<br />
    <br />
    # !   &lt;Directory&gt;  ƹ ȿ <br />
    &lt;Directory /&gt;<br />
    Order allow,deny<br />
    Allow from all<br />
    Deny from badguy.example.com<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sections.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/server-wide.html.tr.utf8���������������������������������������������������0000664�0001751�0001751�00000030636�14743132254�021477� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Sunucu Genelinde Yapılandırma - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Sunucu Genelinde Yapılandırma</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu belgede <code class="module"><a href="./mod/core.html">core</a></code> modülü ile sağlanan ve  sunucunun temel
        işlemlerini yapılandırmakta kullanılan yönergelerden bazıları
        açıklanmıştır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#identification">Sunucu Kimliği</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#locations">Dosyaların Yerleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#resource">Özkaynak Kullanımının Sınırlanması</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#implementation">Gerçeklenimle ilgili Seçimler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="identification" id="identification">Sunucu Kimliği</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code></li><li><code class="directive"><a href="./mod/core.html#serversignature">ServerSignature</a></code></li><li><code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code></li></ul></td></tr></table>
    
        <p><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code> ve <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> yönergeleri, hata iletileri gibi
          sunucu tarafından üretilen belgelerde sunucu ile ilgili hangi bilgilerin
          sunulacağını belirlerler. <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> yönergesi sunucunun HTTP yanıt başlığı
          alanının değerini belirler.</p>
    
        <p><code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>,
          <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code> ve
          <code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code>
          yönergeleri, sunucu tarafından, özüne yönelik URL’leri nasıl
          oluşturacağını saptamak için kullanılır. Örneğin bir istemci bir dizin
          isteğinde bulunurken URL’nin sonuna bölü çizgisi eklemese bile
          Apache httpd’nin istemciyi bölü çizgisi ile bitirilmiş URL yoluna
          yönlendirmesi gerekir; böylece istemci belge içindeki göreli
          bağlantıları doğru şekilde çözümleyebilir.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="locations" id="locations">Dosyaların Yerleri</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/mpm_common.html#coredumpdirectory">CoreDumpDirectory</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code></li><li><code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code></li></ul></td></tr></table>
    
        <p>Bu yönergeler Apache httpd’nin doğru işlem yapması için gereksinim
          duyduğu çeşitli dosyaların yerlerini belirlerler. Bölü çizgisi (/) ile
          başlamayan dosya yolları kullanıldığında bu dosyaların yerlerinin
          <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> yönergesinde belirtilen
          dizine göre belirtildiği varsayılır; root olmayan kullanıcılar
          tarafından yazılabilen dosya yollarına dosya yerleştirmemeye dikkat
          ediniz. Bu konuda daha ayrıntılı bilgi edinmek için <a href="misc/security_tips.html#serverroot">güvenlik ipuçları</a>
          belgesine bakınız.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="resource" id="resource">Özkaynak Kullanımının Sınırlanması</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#limitrequestbody">LimitRequestBody</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfields">LimitRequestFields</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfieldsize">LimitRequestFieldsize</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestline">LimitRequestLine</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitcpu">RLimitCPU</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitmem">RLimitMEM</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitnproc">RLimitNPROC</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code></li></ul></td></tr></table>
    
        <p><code>LimitRequest*</code> yönergeleri, Apache httpd’nin istemcilerden
          gelen istekleri okumak için kullanacağı özkaynakların miktarları ile
          ilgili sınırlamalar koymak için kullanılırlar. Bu değerleri sınırlamak
          suretiyle bazı hizmet reddi saldırılarının etkileri azaltılabilir.</p>
    
        <p><code>RLimit*</code> yönergeleri ise Apache httpd’nin çocuk süreçleri
          tarafından çatallanabilen özkaynakların miktarlarını sınırlamakta
          kullanılırlar. Özellikle de CGI betikleri ve SSI çalıştırma komutları
          tarafından kullanılan özkaynakları denetlemekte kullanılırlar.</p>
    
        <p><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code> yönergesi
          bazı platformlarda yığıt boyutunu denetim altında tutmak için
          kullanılır.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">Gerçeklenimle ilgili Seçimler</a></h2>
        
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code></li></ul></td></tr></table>
    
        <p><code class="directive">Mutex</code> yönergesi, <a class="glossarylink" href="./glossary.html#apr" title="sözlüğe bakınız">APR</a>'nin
          öntanımlı seçimi ile ilgili işlevsel ve başarımsal sorunlarına çare
          bulmada ilgili gerçeklenimi mutex'ler için değiştirmekte
          kullanılabilir.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/server-wide.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.ko.euc-kr�����������������������������������������������������0000664�0001751�0001751�00000056071�14743132254�021172� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Ʈ - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>Ʈ</h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p>  
    <a href="./">Apache HTTP Server Version 2.4 </a> 
    ش.</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">ǥ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">ġ  ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">ġ ȣƮ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#faq">ġ     </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">ġ SSL/TLS ȣȭ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">ħ, 丮, HowTo</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">÷ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">ġ   α׷</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Ÿ ġ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">ġ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index"> </a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">ǥ</a></h2>
    <ul><li><a href="upgrading.html">1.3 2.0 ׷̵</a></li>
    <li><a href="new_features_2_0.html">ġ 2.0 ο </a></li>
    <li><a href="license.html">ġ ̼</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">ġ  ϱ</a></h2>
    <ul><li><a href="install.html">ġ ϰ ġ</a></li>
    <li><a href="invoking.html">ġ </a></li>
    <li><a href="stopping.html"> ߴܰ </a></li>
    <li><a href="configuring.html"></a></li>
    <li><a href="sections.html"> Directory, Location, Files 
    ϳ</a></li>
    <li><a href="server-wide.html">  </a></li>
    <li><a href="logs.html">α</a></li>
    <li><a href="urlmapping.html">URL Ͻýۿ </a></li>
    <li><a href="misc/security_tips.html"> </a></li>
    <li><a href="dso.html">ü (DSO) </a></li>
    <li><a href="content-negotiation.html"> (content negotiation)</a></li>
    <li><a href="custom-error.html">  </a></li>
    <li><a href="bind.html">ġ  ּҿ Ʈ </a></li>
    <li><a href="mpm.html">ó (MPM)</a></li>
    <li><a href="env.html">ġ ȯ溯</a></li>
    <li><a href="handler.html">ġ ڵ鷯 </a></li>
    <li><a href="filter.html"></a></li>
    <li><a href="suexec.html">suEXEC </a></li>
    <li><a href="misc/perf-tuning.html"> Ʈ</a></li>
    <li><a href="misc/rewriteguide.html">URL ۼ(rewriting) ħ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">ġ ȣƮ </a></h2>
    <ul><li class="separate"><a href="vhosts/"></a></li>
    <li><a href="vhosts/name-based.html"≯ ȣƮ</a></li>
    <li><a href="vhosts/ip-based.html">IP ȣƮ </a></li>
    <li><a href="vhosts/mass.html">뷮 ȣƮ  ϱ</a></li>
    <li><a href="vhosts/examples.html">ȣƮ </a></li>
    <li><a href="vhosts/details.html">ȣƮ ã⿡  ڼ </a></li>
    <li><a href="vhosts/fd-limits.html">ϱ(file descriptor) Ѱ</a></li>
    <li><a href="dns-caveats.html">DNS ġ õ </a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="faq" id="faq">ġ     </a></h2>
    <ul><li><a href="faq/"></a></li>
    <li><a href="faq/support.html"></a></li>
    <li><a href="faq/error.html"></a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">ġ SSL/TLS ȣȭ</a></h2>
    <ul><li class="separate"><a href="ssl/">Ұ</a></li>
    <li><a href="ssl/ssl_intro.html">SSL/TLS ȣȭ: Ұ</a></li>
    <li><a href="ssl/ssl_compat.html">SSL/TLS ȣȭ: ȣȯ</a></li>
    <li><a href="ssl/ssl_howto.html">SSL/TLS ȣȭ: How-To</a></li>
    <li><a href="ssl/ssl_faq.html">SSL/TLS ȣȭ: FAQ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">ħ, 丮, HowTo</a></h2>
    <ul><li class="separate"><a href="howto/"></a></li>
    <li><a href="howto/auth.html"></a></li>
    <li><a href="howto/cgi.html">CGI   </a></li>
    <li><a href="howto/ssi.html">Server Side Includes Ұ</a></li>
    <li><a href="howto/htaccess.html">.htaccess </a></li>
    <li><a href="howto/public_html.html">ں 丮</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">÷ </a></h2>
    <ul><li class="separate"><a href="platform/"></a></li>
    <li><a href="platform/windows.html">Microsoft Windows ġ
    ϱ</a></li>
    <li><a href="platform/win_compiling.html">Microsoft Windows
    ġ ϱ</a></li>
    <li><a href="platform/netware.html">Novell NetWare ġ
    ϱ</a></li>
    <li><a href="platform/perf-hp.html">HPUX  
    ϱ</a></li>
    <li><a href="platform/ebcdic.html">ġ EBCDIC </a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">ġ   α׷</a></h2>
    <ul><li class="separate"><a href="programs/"></a></li>
    <li><a href="programs/httpd.html">Manpage: httpd</a></li>
    <li><a href="programs/ab.html">Manpage: ab</a></li>
    <li><a href="programs/apachectl.html">Manpage: apachectl</a></li>
    <li><a href="programs/apxs.html">Manpage: apxs</a></li>
    <li><a href="programs/configure.html">Manpage: configure</a></li>
    <li><a href="programs/dbmmanage.html">Manpage: dbmmanage</a></li>
    <li><a href="programs/htcacheclean.html">Manpage: htcacheclean</a></li>
    <li><a href="programs/htdigest.html">Manpage: htdigest</a></li>
    <li><a href="programs/htpasswd.html">Manpage: htpasswd</a></li>
    <li><a href="programs/logresolve.html">Manpage: logresolve</a></li>
    <li><a href="programs/rotatelogs.html">Manpage: rotatelogs</a></li>
    <li><a href="programs/suexec.html">Manpage: suexec</a></li>
    <li><a href="programs/other.html">ٸ α׷</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Ÿ ġ </a></h2>
    <ul><li class="separate"><a href="misc/"></a></li>
    <li><a href="misc/relevant_standards.html">õ ǥص</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">ġ </a></h2>
    <ul><li><a href="mod/module-dict.html">ġ  ϴµ 
    </a></li>
    <li><a href="mod/directive-dict.html">ġ þ ϴµ
     </a></li>
    </ul><ul><li><a href="mod/core.html">ġ ٽ </a></li>
    <li><a href="mod/mpm_common.html">ġ MPM  þ</a></li>
    <li><a href="mod/event.html">ġ MPM event</a></li>
    <li><a href="mod/mpm_netware.html">ġ MPM netware</a></li>
    <li><a href="mod/mpmt_os2.html">ġ MPM os2</a></li>
    <li><a href="mod/prefork.html">ġ MPM prefork</a></li>
    <li><a href="mod/mpm_winnt.html">ġ MPM winnt</a></li>
    <li><a href="mod/worker.html">ġ MPM worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">ġ  mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">ġ  mod_actions</a></li>
    <li><a href="mod/mod_alias.html">ġ  mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">ġ  mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">ġ  mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">ġ  mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">ġ  mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">ġ  mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">ġ  mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">ġ  mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">ġ  mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">ġ  mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">ġ  mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">ġ  mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">ġ  mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">ġ  mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">ġ  mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">ġ  mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">ġ  mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">ġ  mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">ġ  mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">ġ  mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">ġ  mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">ġ  mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">ġ  mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">ġ  mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">ġ  mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">ġ  mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">ġ  mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">ġ  mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">ġ  mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">ġ  mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">ġ  mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">ġ  mod_data</a></li>
    <li><a href="mod/mod_dav.html">ġ  mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">ġ  mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">ġ  mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">ġ  mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">ġ  mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">ġ  mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">ġ  mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">ġ  mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">ġ  mod_echo</a></li>
    <li><a href="mod/mod_env.html">ġ  mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">ġ  mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">ġ  mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">ġ  mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">ġ  mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">ġ  mod_filter</a></li>
    <li><a href="mod/mod_headers.html">ġ  mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">ġ  mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">ġ  mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">ġ  mod_http2</a></li>
    <li><a href="mod/mod_ident.html">ġ  mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">ġ  mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">ġ  mod_include</a></li>
    <li><a href="mod/mod_info.html">ġ  mod_info</a></li>
    <li><a href="mod/mod_isapi.html">ġ  mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">ġ  mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">ġ  mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">ġ  mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">ġ  mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">ġ  mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">ġ  mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">ġ  mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">ġ  mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">ġ  mod_logio</a></li>
    <li><a href="mod/mod_lua.html">ġ  mod_lua</a></li>
    <li><a href="mod/mod_macro.html">ġ  mod_macro</a></li>
    <li><a href="mod/mod_md.html">ġ  mod_md</a></li>
    <li><a href="mod/mod_mime.html">ġ  mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">ġ  mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">ġ  mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">ġ  mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">ġ  mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">ġ  mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">ġ  mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">ġ  mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">ġ  mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">ġ  mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">ġ  mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">ġ  mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">ġ  mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">ġ  mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">ġ  mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">ġ  mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">ġ  mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">ġ  mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">ġ  mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">ġ  mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">ġ  mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">ġ  mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">ġ  mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">ġ  mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">ġ  mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">ġ  mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">ġ  mod_sed</a></li>
    <li><a href="mod/mod_session.html">ġ  mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">ġ  mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">ġ  mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">ġ  mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">ġ  mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">ġ  mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">ġ  mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">ġ  mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">ġ  mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">ġ  mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">ġ  mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">ġ  mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">ġ  mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">ġ  mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">ġ  mod_ssl</a></li>
    <li><a href="mod/mod_status.html">ġ  mod_status</a></li>
    <li><a href="mod/mod_substitute.html">ġ  mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">ġ  mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">ġ  mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">ġ  mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">ġ  mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">ġ  mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">ġ  mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">ġ  mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">ġ  mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">ġ  mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">ġ  mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer"> </a></h2>
    <ul><li class="separate"><a href="developer/"></a></li>
    <li><a href="developer/API.html">Apache API </a></li>
    <li><a href="developer/debugging.html">APR ޸Ҵ </a></li>
    <li><a href="developer/documenting.html">Apache 2.0 ȭ</a></li>
    <li><a href="developer/hooks.html">Apache 2.0 (hook) Լ</a></li>
    <li><a href="developer/modules.html">Apache 1.3 Apache 2.0
     ϱ</a></li>
    <li><a href="developer/request.html">Apache 2.0 ûó</a></li>
    <li><a href="developer/filters.html">Apache 2.0  ۹</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index"> </a></h2>
    <ul><li><a href="glossary.html"></a></li>
    <li><a href="mod/"> </a></li>
    <li><a href="mod/directives.html">þ </a></li>
    <li><a href="mod/quickreference.html">þ </a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sections.html.ja.utf8������������������������������������������������������0000664�0001751�0001751�00000101471�14743132254�021033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>セクションの設定 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>セクションの設定</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
     <p><a href="configuring.html">設定ファイル</a>中のディレクティブは
    サーバ全体に適用されたり、特定のディレクトリやファイル、ホスト、URL にのみ
    適用されるように制限したりすることができます。この文書は設定用のセクションの
    コンテナや <code>.htaccess</code> ファイルを使って他の設定ディレクティブの
    スコープを変更する方法を説明します。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#types">設定用セクションコンテナの種類</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-and-web">ファイルシステムとウェブ空間</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">バーチャルホスト</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">プロクシ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#whatwhere">どのディレクティブが使えるの?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#mergin">セクションのマージ方法</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="types" id="types">設定用セクションコンテナの種類</a></h2>
    
    <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mod_version.html">mod_version</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
    <p>コンテナには二つの基本となる種類があります。ほとんどのコンテナは
    各リクエストに対して評価されます。その場合、コンテナ中のディレクティブは
    コンテナにマッチするリクエストにのみ適用されます。一方、
    <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>, 
    <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>, 
    <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
    コンテナは
    サーバの起動時と再起動時にのみ評価されます。起動時に条件が真であれば、
    コンテナ中のディレクティブはすべてのリクエストに適用されます。条件が
    偽であれば、コンテナ中のディレクティブは無視されます。</p>
    
    <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> ディレクティブは
    <code class="program"><a href="./programs/httpd.html">httpd</a></code> コマンドラインで適切なパラメータが定義されたときにのみ
    適用されるディレクティブを囲います。例えば次の設定では、サーバが
    <code>httpd -DClosedForNow</code> を使って起動されたときだけすべての
    リクエストを別のサイトにリダイレクトします:</p>
    
    <div class="example"><p><code>
    &lt;IfDefine ClosedForNow&gt;<br />
    Redirect / http://otherserver.example.com/<br />
    &lt;/IfDefine&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> は
    非常に似ていますが、代わりにサーバ上でモジュールが使用可能な場合にのみ
    適用可能なディレクティブを囲います。モジュールはサーバに
    静的に組み込まれているか、動的に組み込むようになっていて、設定ファイル中で
    <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> の行がより前の
    部分に書かれている必要があります。このディレクティブは特定のモジュールの
    存在に関わらず設定ファイルが動作する必要がある場合にのみ使ってください。
    常に動作して欲しいディレクティブを囲むために使うべきではありません。
    存在しないモジュールに関する有用なエラーメッセージの発生を抑制してしまいますので。
    </p>
    
    <p>次の例では、<code class="module"><a href="./mod/mod_mime_magic.html">mod_mime_magic</a></code> があるときにのみ <code class="directive"><a href="./mod/mod_mime_magic.html#mimemagicfiles">MimeMagicFiles</a></code> ディレクティブが
    適用されます。</p>
    
    <div class="example"><p><code>
    &lt;IfModule mod_mime_magic.c&gt;<br />
    MimeMagicFile conf/magic<br />
    &lt;/IfModule&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
    ディレクティブは
    <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> や
    <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>と、
    とてもよく似ていますが、稼働中のサーバのバージョンが特定のバージョンの時にのみ
    適用されます。様々なバージョンの httpd を様々な設定で動作させることになる場合で、
    テストスイートや巨大なネットワークでの用途を想定して、
    このモジュールは設計されています。</p>
    
    <div class="example"><p><code>
      &lt;IfVersion &gt;= 2.1&gt;<br />
      <span class="indent">
        # this happens only in versions greater or<br />
        # equal 2.1.0.<br />
      </span>
      &lt;/IfVersion&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>, 
    <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>,
    <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code> ディレクティブは
    テストの前に "!" を付けることで否定の条件を適用することができます。
    また、これらのセクションはより複雑な制限を課すために入れ子にすることができます。
    </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-and-web" id="file-and-web">ファイルシステムとウェブ空間</a></h2>
    
    <p>最もよく使われる設定のセクションコンテナはファイルシステムやウェブ空間の
    特定の場所の設定を変更するものです。まず、この二つの違いを理解することが
    大切です。ファイルシステムはオペレーティングシステムから見たディスクの内容です。
    たとえば、デフォルトのインストールでは Apache は Unix ファイルシステムでは
    <code>/usr/local/apache2</code> に、Windows ファイルシステムでは
    <code>"c:/Program Files/Apache Group/Apache2"</code> に存在します。
    (Apache では Windows でもパスセパレータとしてスラッシュを使うことに
    気をつけてください。) 対照的に、ウェブ空間はあなたのサイトを
    ウェブサーバから配信されるものとして見たもので、クライアントに見えるものです。
    デフォルトの Unix 上の Apache のインストールではウェブ空間の
    <code>/dir/</code> というパスはファイルシステムの
    <code>/usr/local/apache2/htdocs/dir/</code> というパスに対応します。
    ウェブページはデータベースや他の場所から動的に生成することもできますので、
    ウェブ空間はファイルシステムに直接マップする必要はありません。</p>
    
    <h3><a name="filesystem" id="filesystem">ファイルシステムコンテナ</a></h3>
    
    <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> ディレクティブと
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> ディレクティブ、それと
    それらの正規表現版はディレクティブをファイルシステムの一部分に対して適用します。
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> セクションの
    中のディレクティブは指定されたディレクトリとそのすべてのサブディレクトリに
    適用されます。<a href="howto/htaccess.html">.htaccess ファイル</a>を
    使うことでも同じ効果を得ることができます。例えば、次の設定では
    <code>/var/web/dir1</code> とすべてのサブディレクトリに対して
    ディレクトリインデックスを行ないます。</p>
    
    <div class="example"><p><code>
    &lt;Directory /var/web/dir1&gt;<br />
    Options +Indexes<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> セクションの
    中にあるディレクティブはどのディレクトリにあるかに関わらず、指定された名前の
    すべてのファイルに適用されます。ですから例えば以下の設定ディレクティブが
    設定ファイルの主セクションに書かれたときには、すべての場所の
    <code>private.html</code> という名前のファイルへのアクセスを拒否します。</p>
    
    <div class="example"><p><code>
    &lt;Files private.html&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Files&gt;
    </code></p></div>
    
    <p>ファイルシステムの特定の場所にあるファイルを指定するために、
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> セクションと
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> セクションを
    組み合わせることができます。例えば、次の設定では
    <code>/var/web/dir1/private.html</code>, 
    <code>/var/web/dir1/subdir2/private.html</code>, 
    <code>/var/web/dir1/subdir3/private.html</code> など、
    <code>/var/web/dir1/</code> ディレクトリの下にあるすべての
    <code>private.html</code> へのアクセスを拒否します。</p>
    
    <div class="example"><p><code>
    &lt;Directory /var/web/dir1&gt;<br />
    &lt;Files private.html&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Files&gt;<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    
    <h3><a name="webspace" id="webspace">ウェブ空間コンテナ</a></h3>
    
    <p>一方、<code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    ディレクティブとその<a class="glossarylink" href="./glossary.html#regex" title="用語集を参照">正規表現</a>版は
    ウェブ空間上の内容に対して設定を変更します。
    たとえば、次の設定では /private で始まる URL パスへのアクセスを制限します。
    具体的には、
    <code>http://yoursite.example.com/private</code>,
    <code>http://yoursite.example.com/private123</code>, 
    <code>http://yoursite.example.com/private/dir/file.html</code> 
    へのリクエストや、
    他の同様に <code>/private</code> 文字列で始まるリクエストに
    適用されます。</p>
    
    <div class="example"><p><code>
    &lt;Location /private&gt;<br />
    Order Allow,Deny<br />
    Deny from all<br />
    &lt;/Location&gt;
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    ディレクティブはファイルシステムと関係ある必要が全くありません。
    たとえば次の例では、どのようにして特定の URL を
    <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>で提供されている Apache 
    内部ハンドラにマップするかを示しています。ファイルシステムに
    <code>server-status</code> というファイルが存在する必要はありません。</p>
    
    <div class="example"><p><code>
    &lt;Location /server-status&gt;<br />
    SetHandler server-status<br />
    &lt;/Location&gt;
    </code></p></div>
    
    
    <h3><a name="wildcards" id="wildcards">ワイルドカードと正規表現</a></h3>
    
    <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, 
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, 
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> 
    ディレクティブでは、 C 標準ライブラリの <code>fnmatch</code> のように
    shell スタイルのワイルドカードキャラクタが使用できます。
    "*" 文字は任意の文字列にマッチし、"?" 文字は任意の 1 文字にマッチし、
    "[<em>seq</em>]" は <em>seq</em> の任意の文字にマッチします。
    "/" 文字はどのワイルドカードでもマッチされません。
    明示的に指定する必要があります。</p>
    
    <p>これより柔軟なマッチングが必要な場合は、これらのコンテナに正規表現
    (regex) 版である
    <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, 
    <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, 
    <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>
    があり、マッチを選択するのに perl 互換<a class="glossarylink" href="./glossary.html#regex" title="用語集を参照">正規表現</a>を使用できます。しかし、次の設定のマージに目を通して、
    regex セクションを使用することで、ディレクティブの適用がどのように
    変化するか把握しておいてください。</p>
    
    <p>全ユーザディレクトリの設定を変更する、非 regex
    ワイルドカードセクションは次のようになります。</p>
    
    <div class="example"><p><code>
    &lt;Directory /home/*/public_html&gt;<br />
    Options Indexes<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    <p>regex セクションを使用することで、画像ファイルの多くのタイプに対する
    アクセスを一度に拒否できます。</p>
    <div class="example"><p><code>
    &lt;FilesMatch \.(?i:gif|jpe?g|png)$&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/FilesMatch&gt;
    </code></p></div>
    
    
    
    <h3><a name="whichwhen" id="whichwhen">いつ何を使うか</a></h3>
    
    <p>ファイルシステムコンテナとウェブ空間コンテナを使い分けるのは、
    実際には非常に簡単です。ファイルシステムに依存する
    オブジェクトにディレクティブを適応する場合は、必ず
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> か
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    を使用します。ファイルシステムに依存しないオブジェクト
    (データベースから生成されるウェブページなど) 
    にディレクティブを適用する際には、
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    を使用します。</p>
    
    <p>ファイルシステム上のオブジェクトへのアクセスを制限するために、
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    を決して使用ないようにしましょう。
    同一のファイルシステム位置にマップしている、ウェブ空間位置 (URL)
    が多数あって、設定した制限を迂回されてしまうかもしれないからです。
    例えば次の設定を考えてみましょう。</p>
    
    <div class="example"><p><code>
    &lt;Location /dir/&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Location&gt;
    </code></p></div>
    
    <p><code>http://yoursite.example.com/dir/</code>
    へのリクエストでは上手く動作します。しかし大文字小文字を区別しない
    ファイルシステムを使っていたらどうなるでしょう?
    <code>http://yoursite.example.com/DIR/</code> 
    へのリクエストで簡単にアクセス制限を迂回されてしまいます。これに対して
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    ディレクティブを使用すると、どのように呼び出されたかに関わらず
    その場所から提供される内容に適用されます。
    (例外はファイルシステムのリンクです。シンボリックリンクを使って、
    同一のディレクトリを複数のファイルシステムに設置できます。
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    ディレクティブはパス名をリセットすることなくシンボリックリンクを
    辿ります。ですから、高度なセキュリティが要求される場合は、
    適切に <code class="directive"><a href="./mod/core.html#options">Options</a></code> 
    ディレクティブを使用してシンボリックリンクを無効にするべきです。)</p>
    
    <p>大文字小文字を区別するファイルシステムを使用しているから上記のことは
    無関係だと思われるかもしれませんが、
    同一のファイルシステム位置に複数のウェブ空間位置をマップする方法は、
    他にいくらでもあるということを覚えていてください。
    ですからできる限りファイルシステムコンテナを使用してください。
    しかしながら一つだけ例外があります。
    <code>&lt;Location /&gt;</code> セクションはどんな URL 
    にも関わらず適用されるので、完全に安全です。</p>
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">バーチャルホスト</a></h2>
    
    <p><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
    コンテナは特定のホストに適用するディレクティブを格納します。
    一台のマシンで複数のホストを異なる設定で提供したいときに有用です。
    詳細に関しては<a href="vhosts/">バーチャルホストドキュメント</a>を
    ご覧下さい。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">プロクシ</a></h2>
    
    <p><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
    と <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
    コンテナは、特定の URL にマッチする <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>
    プロクシサーバを経由してアクセスしたサイトに対してのみ適用される
    設定ディレクティブを格納します。例えば次の設定は、<code>cnn.com</code> 
    ウェブサイトにアクセスするために用いられるプロクシサーバを
    制限します。</p>
    
    <div class="example"><p><code>
    &lt;Proxy http://cnn.com/*&gt;<br />
    Order allow,deny<br />
    Deny from all<br />
    &lt;/Proxy&gt;
    </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="whatwhere" id="whatwhere">どのディレクティブが使えるの?</a></h2>
    
    <p>どのタイプの設定セクションでどのディレクティブが使用できるかは、
    ディレクティブの <a href="mod/directive-dict.html#Context">Context</a>
    を見てください。
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    で使用可能なものは全て、同様に
    <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>,
    <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
    セクションで使用可能です。しかしながら幾つか例外も存在します。</p>
    
    <ul>
    <li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> ディレクティブは
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    セクションでのみ使用可能です。</li>
    
    <li><code>FollowSymLinks</code> と <code>SymLinksIfOwnerMatch</code> の
    <code class="directive"><a href="./mod/core.html#options">Options</a></code> は、
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    セクションか <code>.htaccess</code> ファイルでのみ使用可能です。</li>
    
    <li><code class="directive"><a href="./mod/core.html#options">Options</a></code> ディレクティブは、
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    と <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>
    セクションでは使用できません。</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="mergin" id="mergin">セクションのマージ方法</a></h2>
    
        <p>マージの順番は以下のようになっています:</p>
    
        <ol>
          <li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> (正規表現無し) と
          <code>.htaccess</code> を同時に (<code>.htaccess</code> が許可されていれば、それが
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> を上書きします)
          </li>
    
          <li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>
          (と <code>&lt;Directory ~&gt;</code></li>
    
          <li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> と
          <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code> を同時に</li>
    
          <li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> と
          <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> を同時に</li>
        </ol>
    
        <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
        以外は、それぞれのグループは設定ファイルに現れた順番に処理されます。
        <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> (上のグループ 1)
        はディレクトリが短いものから長いものへと処理されます。ですから、
        例えば <code>&lt;Directory /var/web/dir1&gt;</code> は
        <code>&lt;Directory /var/web/dir/subdir&gt;</code> の前に処理されます。複数の
        <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> セクションが
        同じディレクトリに
        適用される場合は、設定ファイル中の順番に従って処理されます。
        <code class="directive"><a href="./mod/core.html#include">Include</a></code>
        によって挿入された設定は 挿入しているファイルの
        <code class="directive"><a href="./mod/core.html#include">Include</a></code>
        ディレクティブの位置にあったかのように扱われます。</p>
    
        <p><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> セクション中のセクションは
        バーチャルホストの定義の外側の対応するセクションの
        <em>後</em>に適用されます。これによりバーチャルホストが
        メインのサーバ設定を上書きできるようなります。</p>
    
        <p><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> でリクエストが処理される場合は、
        処理順番のうち、<code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> コンテナの部分が
        <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
        コンテナに取って代わられます。</p>
    
        <p>後のセクションのディレクティブが前のセクションのものを上書きします。</p>
    
    
    <div class="note"><h3>技術メモ</h3>
          実際には、名前を変換する段階 (URL
          をファイル名にマップするために <code>Alias</code> や
          <code>DocumentRoot</code> が使用されるところ) の直前に
          <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>/<code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>
          が行なわれます。
          これらを適用した結果は変換が終わった後に完全に捨てられます。
    </div>
    <h3><a name="merge-examples" id="merge-examples">例</a></h3>
    
    <p>次はマージの順番を示すための恣意的な例になっています。
    リクエスト全てに適用されるとして、本例のディレクティブは
    A &gt; B &gt; C &gt; D &gt; E の順番に適用されます。</p>
    
    <div class="example"><p><code>
    &lt;Location /&gt;<br />
    E<br />
    &lt;/Location&gt;<br />
    <br />
    &lt;Files f.html&gt;<br />
    D<br />
    &lt;/Files&gt;<br />
    <br />
    &lt;VirtualHost *&gt;<br />
    &lt;Directory /a/b&gt;<br />
    B<br />
    &lt;/Directory&gt;<br />
    &lt;/VirtualHost&gt;<br />
    <br />
    &lt;DirectoryMatch "^.*b$"&gt;<br />
    C<br />
    &lt;/DirectoryMatch&gt;<br />
    <br />
    &lt;Directory /a/b&gt;<br />
    A<br />
    &lt;/Directory&gt;<br />
    <br />
    </code></p></div>
    
    <p>もっと具体的な、次の例を考えてみましょう。
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> 
    セクションに設置されたアクセス制限に関わらず、
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    セクションが最後に評価されて、サーバへのアクセスは制限されません。
    言い換えれば、マージの順番は重要で、注意して使用してください!</p>
    
    <div class="example"><p><code>
    &lt;Location /&gt;<br />
    Order deny,allow<br />
    Allow from all<br />
    &lt;/Location&gt;<br />
    <br />
    # Woops!  This &lt;Directory&gt; section will have no effect<br />
    &lt;Directory /&gt;<br />
    Order allow,deny<br />
    Allow from all<br />
    Deny from badguy.example.com<br />
    &lt;/Directory&gt;
    </code></p></div>
    
    
    
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sections.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/server-wide.html.ko.euc-kr�������������������������������������������������0000664�0001751�0001751�00000024645�14743132254�021766� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>   - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>  </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
    <p>  <code class="module"><a href="./mod/core.html">core</a></code>   ⺻ ൿ
    ϱ ϴ þ Ϻθ Ѵ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#identification"> ĺ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#locations"> ġ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#resource">ڿ </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="identification" id="identification"> ĺ</a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code></li><li><code class="directive"><a href="./mod/core.html#serversignature">ServerSignature</a></code></li><li><code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li></ul></td></tr></table>
    
        <p><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code>
        <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> þ
           ϴ     
        Ѵ. <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code>
        þ  HTTP   Ѵ.</p>
    
        <p> <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
        <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code>
        þ Ͽ ڱ URL .  ,
        Ŭ̾Ʈ 丮 û 丮 ڿ 
          ġ ڿ   ü ̸
        Ŭ̾Ʈ ̷ƮϿ, Ŭ̾Ʈ  
        ùٷ ã Ѵ.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="locations" id="locations"> ġ</a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/mpm_common.html#coredumpdirectory">CoreDumpDirectory</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#lockfile">LockFile</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code></li><li><code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code></li></ul></td></tr></table>
    
        <p> þ ġ  ϱ ʿ
         ϵ ġ Ѵ. θ (/) 
        , <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code>
          ã´. root ƴ ڿ 
        ִ ο  ʵ ض.  ڼ 
        <a href="misc/security_tips.html#serverroot"> </a>
         ϶.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="resource" id="resource">ڿ </a></h2>
        
    
        <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#limitrequestbody">LimitRequestBody</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfields">LimitRequestFields</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfieldsize">LimitRequestFieldsize</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestline">LimitRequestLine</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitcpu">RLimitCPU</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitmem">RLimitMEM</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitnproc">RLimitNPROC</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code></li></ul></td></tr></table>
    
        <p><code class="directive">LimitRequest</code>* þ ġ
        Ŭ̾Ʈ û    ڿ Ѵ. ̷
         Ͽ 񽺰ź(denial of service) 
          ִ.</p>
    
        <p><code class="directive">RLimit</code>* þ ġ ڽ
        ϴ μ  ڿ Ѵ. Ư CGI
        ũƮ SSI exec ɾ  ڿ Ѵ.</p>
    
        <p><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code>
        þ  ũ⸦ ϱ Netware Ѵ.</p>
      </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/server-wide.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.ja.utf8�������������������������������������������������������0000664�0001751�0001751�00000064554�14743132254�020660� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Site Map - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>Site Map</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <p>このページは現時点で利用可能な
    <a href="./">Apache HTTP サーババージョン 2.4 のドキュメンテーション</a>
    の一覧です。</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">リリースのメモ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Apache HTTP サーバの使用</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">Apache バーチャルホストドキュメント</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#faq">Apache サーバのよくある質問</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">Apache の SSL/TLS 暗号化</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">ガイド、チュートリアル、ハウツー</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">プラットフォーム固有の情報</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Apache HTTP サーバとサポートプログラム</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Apache その他</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Apache モジュール</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">開発者のためのドキュメント</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index">用語集と索引</a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">リリースのメモ</a></h2>
    <ul><li><a href="upgrading.html">2.2 から 2.4 へのアップグレード</a></li>
    <li><a href="new_features_2_4.html">Apache 2.3/2.4 の新機能</a></li>
    <li><a href="new_features_2_2.html">Apache 2.1/2.2 の新機能</a></li>
    <li><a href="new_features_2_0.html">Apache 2.0 の新機能</a></li>
    <li><a href="license.html">Apache License</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">Apache HTTP サーバの使用</a></h2>
    <ul><li><a href="install.html">Apache のコンパイルとインストール</a></li>
    <li><a href="invoking.html">Apache の起動</a></li>
    <li><a href="stopping.html">サーバの停止と再起動</a></li>
    <li><a href="configuring.html">設定ファイル</a></li>
    <li><a href="sections.html">Directory, Location, Files セクションの動作方法</a></li>
    <li><a href="caching.html">Content Caching</a></li>
    <li><a href="server-wide.html">サーバ全体の設定</a></li>
    <li><a href="logs.html">ログファイル</a></li>
    <li><a href="urlmapping.html">URL からファイルシステム上の位置へのマップ</a></li>
    <li><a href="misc/security_tips.html">セキュリティのコツ</a></li>
    <li><a href="dso.html">動的共有オブジェクト (DSO) サポート</a></li>
    <li><a href="content-negotiation.html">コンテントネゴシエーション</a></li>
    <li><a href="custom-error.html">カスタムエラーレスポンス</a></li>
    <li><a href="bind.html">Apache が使用するアドレスとポートの設定</a></li>
    <li><a href="mpm.html">マルチプロセッシングモジュール (MPM)</a></li>
    <li><a href="env.html">Apache における環境変数</a></li>
    <li><a href="handler.html">Apache のハンドラの使用</a></li>
    <li><a href="filter.html">フィルタ</a></li>
    <li><a href="suexec.html">suEXEC サポート</a></li>
    <li><a href="misc/perf-tuning.html">性能に関するヒント</a></li>
    <li><a href="misc/rewriteguide.html">URL リライトガイド</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">Apache バーチャルホストドキュメント</a></h2>
    <ul><li class="separate"><a href="vhosts/">概略</a></li>
    <li><a href="vhosts/name-based.html">名前ベースのバーチャルホスト</a></li>
    <li><a href="vhosts/ip-based.html">IP ベースのバーチャルホストのサポート</a></li>
    <li><a href="vhosts/mass.html">動的に設定された大規模バーチャルホスト</a></li>
    <li><a href="vhosts/examples.html">VirtualHost の例</a></li>
    <li><a href="vhosts/details.html">バーチャルホストのマッチングの詳しい説明</a></li>
    <li><a href="vhosts/fd-limits.html">ファイル記述子の限界</a></li>
    <li><a href="dns-caveats.html">DNS と Apache とに関係する問題</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="faq" id="faq">Apache サーバのよくある質問</a></h2>
    <ul><li><a href="faq/">概略</a></li>
    <li><a href="faq/background.html">背景の説明</a></li>
    <li><a href="faq/support.html">サポート</a></li>
    <li><a href="faq/error.html">エラーメッセージ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">Apache の SSL/TLS 暗号化</a></h2>
    <ul><li class="separate"><a href="ssl/">概略</a></li>
    <li><a href="ssl/ssl_intro.html">SSL/TLS 暗号化: 入門</a></li>
    <li><a href="ssl/ssl_compat.html">SSL/TLS 暗号化: 互換性</a></li>
    <li><a href="ssl/ssl_howto.html">SSL/TLS 暗号化: ハウツー</a></li>
    <li><a href="ssl/ssl_faq.html">SSL/TLS 暗号化: FAQ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">ガイド、チュートリアル、ハウツー</a></h2>
    <ul><li class="separate"><a href="howto/">概略</a></li>
    <li><a href="howto/auth.html">認証</a></li>
    <li><a href="howto/cgi.html">CGI による動的コンテンツ</a></li>
    <li><a href="howto/ssi.html">Server Side Includes 入門</a></li>
    <li><a href="howto/htaccess.html">.htaccess ファイル</a></li>
    <li><a href="howto/public_html.html">ユーザ毎のウェブディレクトリ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">プラットフォーム固有の情報</a></h2>
    <ul><li class="separate"><a href="platform/">概略</a></li>
    <li><a href="platform/windows.html">Microsoft Windows での Apache の使用</a></li>
    <li><a href="platform/win_compiling.html">Microsoft Windows での Apache
    のコンパイル</a></li>
    <li><a href="platform/netware.html">Novell NetWare で Apache を使う</a></li>
    <li><a href="platform/perf-hp.html">HPUX で高性能ウェブサーバを実行する</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC 版 Apache</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">Apache HTTP サーバとサポートプログラム</a></h2>
    <ul><li class="separate"><a href="programs/">概略</a></li>
    <li><a href="programs/httpd.html">マニュアルページ: httpd</a></li>
    <li><a href="programs/ab.html">マニュアルページ: ab</a></li>
    <li><a href="programs/apachectl.html">マニュアルページ: apachectl</a></li>
    <li><a href="programs/apxs.html">マニュアルページ: apxs</a></li>
    <li><a href="programs/configure.html">マニュアルページ: configure</a></li>
    <li><a href="programs/dbmmanage.html">マニュアルページ: dbmmanage</a></li>
    <li><a href="programs/htcacheclean.html">マニュアルページ: htcacheclean</a></li>
    <li><a href="programs/htdbm.html">マニュアルページ: htdbm</a></li>
    <li><a href="programs/htdigest.html">マニュアルページ: htdigest</a></li>
    <li><a href="programs/htpasswd.html">マニュアルページ: htpasswd</a></li>
    <li><a href="programs/logresolve.html">マニュアルページ: logresolve</a></li>
    <li><a href="programs/rotatelogs.html">マニュアルページ: rotatelogs</a></li>
    <li><a href="programs/suexec.html">マニュアルページ: suexec</a></li>
    <li><a href="programs/other.html">他のプログラム</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Apache その他</a></h2>
    <ul><li class="separate"><a href="misc/">概略</a></li>
    <li><a href="misc/relevant_standards.html">関連する標準規格</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">Apache モジュール</a></h2>
    <ul><li><a href="mod/module-dict.html">Apache ディレクティブの説明に使われる用語</a></li>
    <li><a href="mod/directive-dict.html">Apache ディレクティブを説明に使われる用語</a></li>
    </ul><ul><li><a href="mod/core.html">Apache コア機能</a></li>
    <li><a href="mod/mpm_common.html">Apache MPM 共通ディレクティブ</a></li>
    <li><a href="mod/event.html">Apache MPM event</a></li>
    <li><a href="mod/mpm_netware.html">Apache MPM netware</a></li>
    <li><a href="mod/mpmt_os2.html">Apache MPM os2</a></li>
    <li><a href="mod/prefork.html">Apache MPM prefork</a></li>
    <li><a href="mod/mpm_winnt.html">Apache MPM winnt</a></li>
    <li><a href="mod/worker.html">Apache MPM worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">Apache モジュール mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">Apache モジュール mod_actions</a></li>
    <li><a href="mod/mod_alias.html">Apache モジュール mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">Apache モジュール mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">Apache モジュール mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">Apache モジュール mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">Apache モジュール mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">Apache モジュール mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">Apache モジュール mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">Apache モジュール mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">Apache モジュール mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">Apache モジュール mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">Apache モジュール mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">Apache モジュール mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">Apache モジュール mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">Apache モジュール mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">Apache モジュール mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">Apache モジュール mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">Apache モジュール mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">Apache モジュール mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">Apache モジュール mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">Apache モジュール mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">Apache モジュール mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">Apache モジュール mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">Apache モジュール mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">Apache モジュール mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">Apache モジュール mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">Apache モジュール mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">Apache モジュール mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">Apache モジュール mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">Apache モジュール mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">Apache モジュール mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">Apache モジュール mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">Apache モジュール mod_data</a></li>
    <li><a href="mod/mod_dav.html">Apache モジュール mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">Apache モジュール mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">Apache モジュール mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">Apache モジュール mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">Apache モジュール mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">Apache モジュール mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">Apache モジュール mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">Apache モジュール mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">Apache モジュール mod_echo</a></li>
    <li><a href="mod/mod_env.html">Apache モジュール mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">Apache モジュール mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">Apache モジュール mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">Apache モジュール mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">Apache モジュール mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">Apache モジュール mod_filter</a></li>
    <li><a href="mod/mod_headers.html">Apache モジュール mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">Apache モジュール mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">Apache モジュール mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">Apache モジュール mod_http2</a></li>
    <li><a href="mod/mod_ident.html">Apache モジュール mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">Apache モジュール mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">Apache モジュール mod_include</a></li>
    <li><a href="mod/mod_info.html">Apache モジュール mod_info</a></li>
    <li><a href="mod/mod_isapi.html">Apache モジュール mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">Apache モジュール mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">Apache モジュール mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">Apache モジュール mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">Apache モジュール mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">Apache モジュール mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">Apache モジュール mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">Apache モジュール mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">Apache モジュール mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">Apache モジュール mod_logio</a></li>
    <li><a href="mod/mod_lua.html">Apache モジュール mod_lua</a></li>
    <li><a href="mod/mod_macro.html">Apache モジュール mod_macro</a></li>
    <li><a href="mod/mod_md.html">Apache モジュール mod_md</a></li>
    <li><a href="mod/mod_mime.html">Apache モジュール mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">Apache モジュール mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">Apache モジュール mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">Apache モジュール mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">Apache モジュール mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">Apache モジュール mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">Apache モジュール mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">Apache モジュール mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">Apache モジュール mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">Apache モジュール mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">Apache モジュール mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">Apache モジュール mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">Apache モジュール mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">Apache モジュール mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">Apache モジュール mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">Apache モジュール mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">Apache モジュール mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">Apache モジュール mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">Apache モジュール mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">Apache モジュール mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">Apache モジュール mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">Apache モジュール mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">Apache モジュール mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">Apache モジュール mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">Apache モジュール mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">Apache モジュール mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">Apache モジュール mod_sed</a></li>
    <li><a href="mod/mod_session.html">Apache モジュール mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">Apache モジュール mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">Apache モジュール mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">Apache モジュール mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">Apache モジュール mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">Apache モジュール mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">Apache モジュール mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">Apache モジュール mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">Apache モジュール mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">Apache モジュール mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">Apache モジュール mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">Apache モジュール mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">Apache モジュール mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">Apache モジュール mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">Apache モジュール mod_ssl</a></li>
    <li><a href="mod/mod_status.html">Apache モジュール mod_status</a></li>
    <li><a href="mod/mod_substitute.html">Apache モジュール mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">Apache モジュール mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">Apache モジュール mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">Apache モジュール mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">Apache モジュール mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">Apache モジュール mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">Apache モジュール mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">Apache モジュール mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">Apache モジュール mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">Apache モジュール mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">Apache モジュール mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer">開発者のためのドキュメント</a></h2>
    <ul><li class="separate"><a href="developer/">概略</a></li>
    <li><a href="developer/API.html">Apache API メモ</a></li>
    <li><a href="developer/debugging.html">APR
    のメモリアロケーションのデバッグ</a></li>
    <li><a href="developer/documenting.html">Apache 2.0 の説明を書く</a></li>
    <li><a href="developer/hooks.html">Apache 2.0 フック関数</a></li>
    <li><a href="developer/modules.html">Apache 1.3 から Apache 2.0 にモジュールを
    移植する</a></li>
    <li><a href="developer/request.html">Apache 2.0 のリクエスト処理</a></li>
    <li><a href="developer/filters.html">Apache 2.0 のフィルタの動作の仕方</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index">用語集と索引</a></h2>
    <ul><li><a href="glossary.html">用語集</a></li>
    <li><a href="mod/">モジュール索引</a></li>
    <li><a href="mod/directives.html">ディレクティブ索引</a></li>
    <li><a href="mod/quickreference.html">ディレクティブ クイックリファレンス</a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/server-wide.html.ja.utf8���������������������������������������������������0000664�0001751�0001751�00000030024�14743132254�021433� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>サーバ全体の設定 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>サーバ全体の設定</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
    <p>このドキュメントでは<code class="module"><a href="./mod/core.html">core</a></code>
    サーバのディレクティブの中で、
    基本動作を設定するためのものを説明します。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#identification">サーバ ID</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#locations">ファイルの位置</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#resource">リソースの制限</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="identification" id="identification">サーバ ID</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code></li><li><code class="directive"><a href="./mod/core.html#serversignature">ServerSignature</a></code></li><li><code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code></li></ul></td></tr></table>
    
        <p><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code> ディレクティブと
        <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code>
        ディレクティブは、エラーメッセージなどのサーバが作るドキュメントに、
        どのようなサーバの情報を表示するかを制御します。
        <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> ディレクティブは、Server HTTP
        レスポンスヘッダフィールドの値を設定します。</p>
    
        <p><code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>,
        <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code>,
        <code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code>
        ディレクティブは、サーバが自分自身を参照する URL
        を作るときに使われます。
        たとえば、クライアントがディレクトリを要求して、
        そのディレクトリ名の最後にスラッシュが付いていないような場合には、
        ドキュメントの相対的な参照を正しく解決できるようにするために、
        Apache は最後のスラッシュを含んだ完全なパスにクライアントを
        リダイレクトさせる必要があります。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="locations" id="locations">ファイルの位置</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/mpm_common.html#coredumpdirectory">CoreDumpDirectory</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#lockfile">LockFile</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code></li><li><code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code></li></ul></td></tr></table>
    
        <p>これらのディレクティブは Apache
        が適切な動作をするために必要な各種ファイルの位置を制御します。
        パスがスラッシュ (/) で始まっていないときは、ファイルは
        <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> からの相対パスとして
        探されます。root
        以外のユーザが書き込み可能なパスにファイルを置く場合は注意が必要です。
        詳細は<a href="misc/security_tips.html#serverroot">「セキュリティ情報」</a>
        を参照してください。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="resource" id="resource">リソースの制限</a></h2>
        
    
        <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#limitrequestbody">LimitRequestBody</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfields">LimitRequestFields</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfieldsize">LimitRequestFieldsize</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestline">LimitRequestLine</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitcpu">RLimitCPU</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitmem">RLimitMEM</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitnproc">RLimitNPROC</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code></li></ul></td></tr></table>
    
        <p><code class="directive">LimitRequest</code>* ディレクティブは Apache
        がクライアントからのリクエスト読み込みで使う
        リソースを制限するために使われます。これらの値を制限することで、
        いくつかのサービス拒否攻撃は影響を和らげることができます。</p>
    
        <p><code class="directive">RLimit</code>* ディレクティブは、Apache の子プロセスから
        fork されたプロセスが使用するリソースを制限するために使われます。
        特に、これは CGI スクリプトと SSI exec
        コマンドで使われるリソースを制御します。</p>
    
        <p><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code> は Netware
        でのみ、スタックの大きさを制御するために使われます。</p>
      </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/server-wide.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.es������������������������������������������������������������0000664�0001751�0001751�00000063460�14743132254�020003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Mapa de este sitio web - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="./">Versi&#243;n 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>Mapa de este sitio web</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta traducci&#243;n podr&#237;a estar
                obsoleta. Consulte la versi&#243;n en ingl&#233;s de la
                documentaci&#243;n para comprobar si se han producido cambios
                recientemente.</div>
    
    <p>Esta p&#225;gina contiene la lista con los documentos actualmente
    disponibles de la <a href="./">Versi&#243;n 2.4 de la
    Documentaci&#243;n del Servidor HTTP Apache</a>.</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">Notas de la Versi&#243;n</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Funcionamiento del Servidor HTTP Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">Documentaci&#243;n sobre Hosting Virtual en Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#faq">Preguntas M&#225;s Frecuentes sobre Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">Encriptado SSL/TLS con Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">Gu&#237;as, Tutoriales, y HowTos</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">Notas espec&#237;ficas sobre plataformas</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Programas de soporte y el Servidor HTTP Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Documentaci&#243;n adicional sobre Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">M&#243;dulos de Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Documentaci&#243;n para desarrolladores</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index">Glosario e &#205;ndice</a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">Notas de la Versi&#243;n</a></h2>
    <ul><li><a href="upgrading.html">Pasar a usar Apache 2.0 desde Apache 1.3</a></li>
    <li><a href="new_features_2_0.html">Nuevas funcionalidades de Apache 2.0</a></li>
    <li><a href="license.html">Licencia Apache</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">Funcionamiento del Servidor HTTP Apache</a></h2>
    <ul><li><a href="install.html">Compilaci&#243;n e Instalaci&#243;n de Apache</a></li>
    <li><a href="invoking.html">Iniciar Apache</a></li>
    <li><a href="stopping.html">Parar y reiniciar Apache</a></li>
    <li><a href="configuring.html">Ficheros de Configuraci&#243;n</a></li>
    <li><a href="sections.html">Funcionamiento de las secciones Directory, Location y Files</a></li>
    <li><a href="server-wide.html">Configuraci&#243;n B&#225;sica de Apache</a></li>
    <li><a href="logs.html">Archivos Log</a></li>
    <li><a href="urlmapping.html">Mapear URLs a ubicaciones de un sistema de ficheros</a></li>
    <li><a href="misc/security_tips.html">Consejos de Seguridad</a></li>
    <li><a href="dso.html">Soporte de Objetos Din&#225;micos Compartidos (DSO)</a></li>
    <li><a href="content-negotiation.html">Negociaci&#243;n de Contenido</a></li>
    <li><a href="custom-error.html">Mensajes de Error Personalizados</a></li>
    <li><a href="bind.html">Fijar las direcciones y los puertos que usa Apache</a></li>
    <li><a href="mpm.html">M&#243;dulos de Multiproceso (MPMs)</a></li>
    <li><a href="env.html">Variables de entorno en Apache</a></li>
    <li><a href="handler.html">El uso de Handlers en Apache</a></li>
    <li><a href="filter.html">Filtros</a></li>
    <li><a href="suexec.html">Soporte de suEXEC</a></li>
    <li><a href="misc/perf-tuning.html">Rendimiento del servidor</a></li>
    <li><a href="misc/rewriteguide.html">Documentaci&#243;n adicional sobre mod_rewrite</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">Documentaci&#243;n sobre Hosting Virtual en Apache</a></h2>
    <ul><li class="separate"><a href="vhosts/">Visi&#243;n General</a></li>
    <li><a href="vhosts/name-based.html">Hosting Virtual basado en nombres</a></li>
    <li><a href="vhosts/ip-based.html">Soporte de Hosting Virtual Basado en IPs</a></li>
    <li><a href="vhosts/mass.html">Configurar de forma Din&#225;mica el Hosting Virtual masivo en Apache</a></li>
    <li><a href="vhosts/examples.html">Ejemplos de Hosting Virtual</a></li>
    <li><a href="vhosts/details.html">Discusi&#243;n en profundidad sobre los tipos de Hosting Virtual</a></li>
    <li><a href="vhosts/fd-limits.html">Limitaciones de los descriptores de ficheros</a></li>
    <li><a href="dns-caveats.html">Asuntos relacionados con DNS y Apache</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="faq" id="faq">Preguntas M&#225;s Frecuentes sobre Apache</a></h2>
    <ul><li><a href="faq/">Visi&#243;n General</a></li>
    <li><a href="faq/support.html">Soporte</a></li>
    <li><a href="faq/error.html">Mensajes de error</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">Encriptado SSL/TLS con Apache</a></h2>
    <ul><li class="separate"><a href="ssl/">Visi&#243;n General</a></li>
    <li><a href="ssl/ssl_intro.html">Encriptado SSL/TLS: Introducci&#243;n</a></li>
    <li><a href="ssl/ssl_compat.html">Encriptado SSL/TLS: Compatibilidad</a></li>
    <li><a href="ssl/ssl_howto.html">Encriptado SSL/TLS: How-To</a></li>
    <li><a href="ssl/ssl_faq.html">Encriptado SSL/TLS: Preguntas Frecuentes</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">Gu&#237;as, Tutoriales, y HowTos</a></h2>
    <ul><li class="separate"><a href="howto/">Visi&#243;n General</a></li>
    <li><a href="howto/auth.html">Autentificaci&#243;n</a></li>
    <li><a href="howto/cgi.html">Contenido Din&#225;mico con CGIs</a></li>
    <li><a href="howto/ssi.html">Introducci&#243;n a Server Side Includes</a></li>
    <li><a href="howto/htaccess.html">Archivos .htaccess</a></li>
    <li><a href="howto/public_html.html">Directorios web para cada usuario</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">Notas espec&#237;ficas sobre plataformas</a></h2>
    <ul><li class="separate"><a href="platform/">Visi&#243;n General</a></li>
    <li><a href="platform/windows.html">Usar Apache con Microsoft Windows</a></li>
    <li><a href="platform/win_compiling.html">Compilar Apache para
    Microsoft Windows</a></li>
    <li><a href="platform/netware.html">Usar
    Apache con Novell NetWare</a></li>
    <li><a href="platform/perf-hp.html">Servidor Web de alto rendimiento con
    HPUX</a></li>
    <li><a href="platform/ebcdic.html">La versi&#243;n EBCDIC de
    Apache</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">Programas de soporte y el Servidor HTTP Apache</a></h2>
    <ul><li class="separate"><a href="programs/">Visi&#243;n General</a></li>
    <li><a href="programs/httpd.html">P&#225;gina de Ayuda: httpd</a></li>
    <li><a href="programs/ab.html">P&#225;gina de Ayuda: ab</a></li>
    <li><a href="programs/apachectl.html">P&#225;gina de Ayuda: apachectl</a></li>
    <li><a href="programs/apxs.html">P&#225;gina de Ayuda: apxs</a></li>
    <li><a href="programs/configure.html">P&#225;gina de Ayuda: configure</a></li>
    <li><a href="programs/dbmmanage.html">P&#225;gina de Ayuda: dbmmanage</a></li>
    <li><a href="programs/htcacheclean.html">P&#225;gina de Ayuda: htcacheclean</a></li>
    <li><a href="programs/htdigest.html">P&#225;gina de Ayuda: htdigest</a></li>
    <li><a href="programs/htpasswd.html">P&#225;gina de Ayuda: htpasswd</a></li>
    <li><a href="programs/logresolve.html">P&#225;gina de Ayuda: logresolve</a></li>
    <li><a href="programs/rotatelogs.html">P&#225;gina de Ayuda: rotatelogs</a></li>
    <li><a href="programs/suexec.html">P&#225;gina de Ayuda: suexec</a></li>
    <li><a href="programs/other.html">Otros Programas</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Documentaci&#243;n adicional sobre Apache</a></h2>
    <ul><li class="separate"><a href="misc/">Visi&#243;n General</a></li>
    <li><a href="misc/relevant_standards.html">Est&#225;ndares Importantes</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">M&#243;dulos de Apache</a></h2>
    <ul><li><a href="mod/module-dict.html">Definiciones de t&#233;rminos usados
    para describir los m&#243;dulos de Apache</a></li>
    <li><a href="mod/directive-dict.html">Definiciones de t&#233;rminos
    usados para describir las directivas de Apache</a></li>
    </ul><ul><li><a href="mod/core.html">Funcionalidad B&#225;sica de Apache</a></li>
    <li><a href="mod/mpm_common.html">Directivas Comunes de los MPM de
                Apache</a></li>
    <li><a href="mod/event.html">MPM de Apache event</a></li>
    <li><a href="mod/mpm_netware.html">MPM de Apache netware</a></li>
    <li><a href="mod/mpmt_os2.html">MPM de Apache os2</a></li>
    <li><a href="mod/prefork.html">MPM de Apache prefork</a></li>
    <li><a href="mod/mpm_winnt.html">MPM de Apache winnt</a></li>
    <li><a href="mod/worker.html">MPM de Apache worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">M&#243;dulo Apache mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">M&#243;dulo Apache mod_actions</a></li>
    <li><a href="mod/mod_alias.html">M&#243;dulo Apache mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">M&#243;dulo Apache mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">M&#243;dulo Apache mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">M&#243;dulo Apache mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">M&#243;dulo Apache mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">M&#243;dulo Apache mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">M&#243;dulo Apache mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">M&#243;dulo Apache mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">M&#243;dulo Apache mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">M&#243;dulo Apache mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">M&#243;dulo Apache mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">M&#243;dulo Apache mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">M&#243;dulo Apache mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">M&#243;dulo Apache mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">M&#243;dulo Apache mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">M&#243;dulo Apache mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">M&#243;dulo Apache mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">M&#243;dulo Apache mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">M&#243;dulo Apache mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">M&#243;dulo Apache mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">M&#243;dulo Apache mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">M&#243;dulo Apache mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">M&#243;dulo Apache mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">M&#243;dulo Apache mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">M&#243;dulo Apache mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">M&#243;dulo Apache mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">M&#243;dulo Apache mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">M&#243;dulo Apache mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">M&#243;dulo Apache mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">M&#243;dulo Apache mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">M&#243;dulo Apache mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">M&#243;dulo Apache mod_data</a></li>
    <li><a href="mod/mod_dav.html">M&#243;dulo Apache mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">M&#243;dulo Apache mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">M&#243;dulo Apache mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">M&#243;dulo Apache mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">M&#243;dulo Apache mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">M&#243;dulo Apache mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">M&#243;dulo Apache mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">M&#243;dulo Apache mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">M&#243;dulo Apache mod_echo</a></li>
    <li><a href="mod/mod_env.html">M&#243;dulo Apache mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">M&#243;dulo Apache mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">M&#243;dulo Apache mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">M&#243;dulo Apache mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">M&#243;dulo Apache mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">M&#243;dulo Apache mod_filter</a></li>
    <li><a href="mod/mod_headers.html">M&#243;dulo Apache mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">M&#243;dulo Apache mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">M&#243;dulo Apache mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">M&#243;dulo Apache mod_http2</a></li>
    <li><a href="mod/mod_ident.html">M&#243;dulo Apache mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">M&#243;dulo Apache mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">M&#243;dulo Apache mod_include</a></li>
    <li><a href="mod/mod_info.html">M&#243;dulo Apache mod_info</a></li>
    <li><a href="mod/mod_isapi.html">M&#243;dulo Apache mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">M&#243;dulo Apache mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">M&#243;dulo Apache mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">M&#243;dulo Apache mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">M&#243;dulo Apache mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">M&#243;dulo Apache mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">M&#243;dulo Apache mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">M&#243;dulo Apache mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">M&#243;dulo Apache mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">M&#243;dulo Apache mod_logio</a></li>
    <li><a href="mod/mod_lua.html">M&#243;dulo Apache mod_lua</a></li>
    <li><a href="mod/mod_macro.html">M&#243;dulo Apache mod_macro</a></li>
    <li><a href="mod/mod_md.html">M&#243;dulo Apache mod_md</a></li>
    <li><a href="mod/mod_mime.html">M&#243;dulo Apache mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">M&#243;dulo Apache mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">M&#243;dulo Apache mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">M&#243;dulo Apache mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">M&#243;dulo Apache mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">M&#243;dulo Apache mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">M&#243;dulo Apache mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">M&#243;dulo Apache mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">M&#243;dulo Apache mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">M&#243;dulo Apache mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">M&#243;dulo Apache mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">M&#243;dulo Apache mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">M&#243;dulo Apache mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">M&#243;dulo Apache mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">M&#243;dulo Apache mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">M&#243;dulo Apache mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">M&#243;dulo Apache mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">M&#243;dulo Apache mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">M&#243;dulo Apache mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">M&#243;dulo Apache mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">M&#243;dulo Apache mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">M&#243;dulo Apache mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">M&#243;dulo Apache mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">M&#243;dulo Apache mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">M&#243;dulo Apache mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">M&#243;dulo Apache mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">M&#243;dulo Apache mod_sed</a></li>
    <li><a href="mod/mod_session.html">M&#243;dulo Apache mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">M&#243;dulo Apache mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">M&#243;dulo Apache mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">M&#243;dulo Apache mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">M&#243;dulo Apache mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">M&#243;dulo Apache mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">M&#243;dulo Apache mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">M&#243;dulo Apache mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">M&#243;dulo Apache mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">M&#243;dulo Apache mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">M&#243;dulo Apache mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">M&#243;dulo Apache mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">M&#243;dulo Apache mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">M&#243;dulo Apache mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">M&#243;dulo Apache mod_ssl</a></li>
    <li><a href="mod/mod_status.html">M&#243;dulo Apache mod_status</a></li>
    <li><a href="mod/mod_substitute.html">M&#243;dulo Apache mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">M&#243;dulo Apache mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">M&#243;dulo Apache mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">M&#243;dulo Apache mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">M&#243;dulo Apache mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">M&#243;dulo Apache mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">M&#243;dulo Apache mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">M&#243;dulo Apache mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">M&#243;dulo Apache mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">M&#243;dulo Apache mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">M&#243;dulo Apache mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer">Documentaci&#243;n para desarrolladores</a></h2>
    <ul><li class="separate"><a href="developer/">Visi&#243;n General</a></li>
    <li><a href="developer/API.html">Notas sobre la API de Apache</a></li>
    <li><a href="developer/debugging.html">Debugear la Reserva de Memoria en APR</a></li>
    <li><a href="developer/documenting.html">Documentando Apache 2.0</a></li>
    <li><a href="developer/hooks.html">Funciones Hook de Apache 2.0</a></li>
    <li><a href="developer/modules.html">Convertir M&#243;dulos de Apache 1.3 a Apache 2.0</a></li>
    <li><a href="developer/request.html">Procesamiento de Peticiones en Apache 2.0</a></li>
    <li><a href="developer/filters.html">Funcionamiento de los filtros en Apache 2.0</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index">Glosario e &#205;ndice</a></h2>
    <ul><li><a href="glossary.html">Glosario</a></li>
    <li><a href="mod/">&#205;ndice de M&#243;dulos</a></li>
    <li><a href="mod/directives.html">&#205;ndice de Directivas</a></li>
    <li><a href="mod/quickreference.html">Gu&#237;a R&#225;pida de
    Referencia de Directivas</a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.zh-cn.utf8����������������������������������������������������0000664�0001751�0001751�00000057652�14743132254�021306� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn" xml:lang="zh-cn"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>站点导航 - Apache HTTP 服务器 版本 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p>
    <p class="apache">Apache HTTP 服务器版本 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP 服务器</a> &gt; <a href="http://httpd.apache.org/docs/">文档</a> &gt; <a href="./">版本 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>站点导航</h1>
    <div class="toplang">
    <p><span>可用语言: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div>
    
    <p>本页列出了
    <a href="./">Apache HTTP 服务器 2.4
    的全部文档</a>。</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">发行说明</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">使用 Apache HTTP 服务器</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">Apache 虚拟主机文档</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">URL 改写指南</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">Apache SSL/TLS 加密</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">指南与教程</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">平台相关说明</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Apache HTTP 服务器与支持程序</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Apache 杂项文档</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Apache 模块</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">开发者文档</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index">术语与索引</a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">发行说明</a></h2>
    <ul><li><a href="upgrading.html">从 2.2 升级到 2.4</a></li>
    <li><a href="new_features_2_4.html">Apache 2.3/2.4 的新特性</a></li>
    <li><a href="new_features_2_2.html">Apache 2.1/2.2 的新特性</a></li>
    <li><a href="new_features_2_0.html">Apache 2.0 的新特性</a></li>
    <li><a href="license.html">Apache 许可证</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">使用 Apache HTTP 服务器</a></h2>
    <ul><li><a href="install.html">编译与安装 Apache</a></li>
    <li><a href="invoking.html">启动 Apache</a></li>
    <li><a href="stopping.html">停止与重启 Apache</a></li>
    <li><a href="configuring.html">配置文件</a></li>
    <li><a href="sections.html">配置片段</a></li>
    <li><a href="caching.html">缓存指南</a></li>
    <li><a href="server-wide.html">服务器全局配置</a></li>
    <li><a href="logs.html">日志文件</a></li>
    <li><a href="urlmapping.html">从 URL 映射到文件系统</a></li>
    <li><a href="misc/security_tips.html">安全技巧</a></li>
    <li><a href="dso.html">动态共享对象(DSO)</a></li>
    <li><a href="content-negotiation.html">内容协商</a></li>
    <li><a href="custom-error.html">定制错误响应</a></li>
    <li><a href="bind.html">绑定指定地址与端口</a></li>
    <li><a href="mpm.html">多处理模块(MPM)</a></li>
    <li><a href="env.html">环境变量</a></li>
    <li><a href="handler.html">Apache 的处理器</a></li>
    <li><a href="filter.html">过滤器</a></li>
    <li><a href="suexec.html">执行 CGI 前的用户切换(suEXEC)</a></li>
    <li><a href="misc/perf-tuning.html">性能调谐</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">常见问题</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">Apache 虚拟主机文档</a></h2>
    <ul><li class="separate"><a href="vhosts/">概述</a></li>
    <li><a href="vhosts/name-based.html">基于名称的虚拟主机</a></li>
    <li><a href="vhosts/ip-based.html">基于 IP 的虚拟主机</a></li>
    <li><a href="vhosts/mass.html">动态配置的大规模虚拟主机</a></li>
    <li><a href="vhosts/examples.html">虚拟主机样例</a></li>
    <li><a href="vhosts/details.html">虚拟主机匹配的深入讨论</a></li>
    <li><a href="vhosts/fd-limits.html">文件句柄限制</a></li>
    <li><a href="dns-caveats.html">Apache 的 DNS 相关问题</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="rewrite" id="rewrite">URL 改写指南</a></h2>
    <ul><li class="separate"><a href="rewrite/">概述</a></li>
    <li><a href="mod/mod_rewrite.html">mod_rewrite 参考文档</a></li>
    <li><a href="rewrite/intro.html">简介</a></li>
    <li><a href="rewrite/flags.html">标志</a></li>
    <li><a href="rewrite/tech.html">技术细节</a></li>
    <li><a href="rewrite/remapping.html">重新映射 URL</a></li>
    <li><a href="rewrite/access.html">访问控制</a></li>
    <li><a href="rewrite/advanced.html">高级技术</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">Apache SSL/TLS 加密</a></h2>
    <ul><li class="separate"><a href="ssl/">概述</a></li>
    <li><a href="ssl/ssl_intro.html">SSL/TLS 加密: 简介</a></li>
    <li><a href="ssl/ssl_compat.html">SSL/TLS 加密: 兼容性</a></li>
    <li><a href="ssl/ssl_howto.html">SSL/TLS 加密: 常见操作</a></li>
    <li><a href="ssl/ssl_faq.html">SSL/TLS 加密: 常见问题</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">指南与教程</a></h2>
    <ul><li class="separate"><a href="howto/">概述</a></li>
    <li><a href="howto/auth.html">认证,授权与访问控制</a></li>
    <li><a href="howto/cgi.html">CGI 与动态内容</a></li>
    <li><a href="howto/ssi.html">服务器端插入</a></li>
    <li><a href="howto/htaccess.html">.htaccess 文件</a></li>
    <li><a href="howto/public_html.html">用户私人网站目录(public_html)</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">平台相关说明</a></h2>
    <ul><li class="separate"><a href="platform/">概述</a></li>
    <li><a href="platform/windows.html">在 Microsoft Windows 中使用 Apache</a></li>
    <li><a href="platform/win_compiling.html">为 Microsoft Windows 编译 Apache</a></li>
    <li><a href="platform/netware.html">在 Novell NetWare 中使用 Apache</a></li>
    <li><a href="platform/perf-hp.html">在 HPUX 中运行高性能 web 服务器</a></li>
    <li><a href="platform/ebcdic.html">Apache 与 EBCDIC 系统</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">Apache HTTP 服务器与支持程序</a></h2>
    <ul><li class="separate"><a href="programs/">概述</a></li>
    <li><a href="programs/httpd.html">手册: httpd</a></li>
    <li><a href="programs/ab.html">手册: ab</a></li>
    <li><a href="programs/apachectl.html">手册: apachectl</a></li>
    <li><a href="programs/apxs.html">手册: apxs</a></li>
    <li><a href="programs/configure.html">手册: configure</a></li>
    <li><a href="programs/dbmmanage.html">手册: dbmmanage</a></li>
    <li><a href="programs/htcacheclean.html">手册: htcacheclean</a></li>
    <li><a href="programs/htdbm.html">手册: htdbm</a></li>
    <li><a href="programs/htdigest.html">手册: htdigest</a></li>
    <li><a href="programs/htpasswd.html">手册: htpasswd</a></li>
    <li><a href="programs/logresolve.html">手册: logresolve</a></li>
    <li><a href="programs/rotatelogs.html">手册: rotatelogs</a></li>
    <li><a href="programs/suexec.html">手册: suexec</a></li>
    <li><a href="programs/other.html">其它程序</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Apache 杂项文档</a></h2>
    <ul><li class="separate"><a href="misc/">概述</a></li>
    <li><a href="misc/relevant_standards.html">相关标准</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">Apache 模块</a></h2>
    <ul><li><a href="mod/module-dict.html">描述模块的术语</a></li>
    <li><a href="mod/directive-dict.html">描述指令的术语</a></li>
    </ul><ul><li><a href="mod/core.html">Apache 核心特性</a></li>
    <li><a href="mod/mpm_common.html">Apache MPM 通用指令</a></li>
    <li><a href="mod/event.html">Apache MPM event</a></li>
    <li><a href="mod/mpm_netware.html">Apache MPM netware</a></li>
    <li><a href="mod/mpmt_os2.html">Apache MPM os2</a></li>
    <li><a href="mod/prefork.html">Apache MPM prefork</a></li>
    <li><a href="mod/mpm_winnt.html">Apache MPM winnt</a></li>
    <li><a href="mod/worker.html">Apache MPM worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">Apache 模块 mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">Apache 模块 mod_actions</a></li>
    <li><a href="mod/mod_alias.html">Apache 模块 mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">Apache 模块 mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">Apache 模块 mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">Apache 模块 mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">Apache 模块 mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">Apache 模块 mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">Apache 模块 mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">Apache 模块 mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">Apache 模块 mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">Apache 模块 mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">Apache 模块 mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">Apache 模块 mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">Apache 模块 mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">Apache 模块 mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">Apache 模块 mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">Apache 模块 mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">Apache 模块 mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">Apache 模块 mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">Apache 模块 mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">Apache 模块 mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">Apache 模块 mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">Apache 模块 mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">Apache 模块 mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">Apache 模块 mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">Apache 模块 mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">Apache 模块 mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">Apache 模块 mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">Apache 模块 mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">Apache 模块 mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">Apache 模块 mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">Apache 模块 mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">Apache 模块 mod_data</a></li>
    <li><a href="mod/mod_dav.html">Apache 模块 mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">Apache 模块 mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">Apache 模块 mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">Apache 模块 mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">Apache 模块 mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">Apache 模块 mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">Apache 模块 mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">Apache 模块 mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">Apache 模块 mod_echo</a></li>
    <li><a href="mod/mod_env.html">Apache 模块 mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">Apache 模块 mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">Apache 模块 mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">Apache 模块 mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">Apache 模块 mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">Apache 模块 mod_filter</a></li>
    <li><a href="mod/mod_headers.html">Apache 模块 mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">Apache 模块 mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">Apache 模块 mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">Apache 模块 mod_http2</a></li>
    <li><a href="mod/mod_ident.html">Apache 模块 mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">Apache 模块 mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">Apache 模块 mod_include</a></li>
    <li><a href="mod/mod_info.html">Apache 模块 mod_info</a></li>
    <li><a href="mod/mod_isapi.html">Apache 模块 mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">Apache 模块 mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">Apache 模块 mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">Apache 模块 mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">Apache 模块 mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">Apache 模块 mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">Apache 模块 mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">Apache 模块 mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">Apache 模块 mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">Apache 模块 mod_logio</a></li>
    <li><a href="mod/mod_lua.html">Apache 模块 mod_lua</a></li>
    <li><a href="mod/mod_macro.html">Apache 模块 mod_macro</a></li>
    <li><a href="mod/mod_md.html">Apache 模块 mod_md</a></li>
    <li><a href="mod/mod_mime.html">Apache 模块 mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">Apache 模块 mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">Apache 模块 mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">Apache 模块 mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">Apache 模块 mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">Apache 模块 mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">Apache 模块 mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">Apache 模块 mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">Apache 模块 mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">Apache 模块 mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">Apache 模块 mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">Apache 模块 mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">Apache 模块 mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">Apache 模块 mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">Apache 模块 mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">Apache 模块 mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">Apache 模块 mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">Apache 模块 mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">Apache 模块 mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">Apache 模块 mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">Apache 模块 mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">Apache 模块 mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">Apache 模块 mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">Apache 模块 mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">Apache 模块 mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">Apache 模块 mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">Apache 模块 mod_sed</a></li>
    <li><a href="mod/mod_session.html">Apache 模块 mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">Apache 模块 mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">Apache 模块 mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">Apache 模块 mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">Apache 模块 mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">Apache 模块 mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">Apache 模块 mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">Apache 模块 mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">Apache 模块 mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">Apache 模块 mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">Apache 模块 mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">Apache 模块 mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">Apache 模块 mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">Apache 模块 mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">Apache 模块 mod_ssl</a></li>
    <li><a href="mod/mod_status.html">Apache 模块 mod_status</a></li>
    <li><a href="mod/mod_substitute.html">Apache 模块 mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">Apache 模块 mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">Apache 模块 mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">Apache 模块 mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">Apache 模块 mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">Apache 模块 mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">Apache 模块 mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">Apache 模块 mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">Apache 模块 mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">Apache 模块 mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">Apache 模块 mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer">开发者文档</a></h2>
    <ul><li class="separate"><a href="developer/">概述</a></li>
    <li><a href="developer/API.html">Apache API 说明</a></li>
    <li><a href="developer/debugging.html">在 APR 中调试内存分配</a></li>
    <li><a href="developer/documenting.html">Apache 2.x 文档</a></li>
    <li><a href="developer/hooks.html">Apache 2.x 钩子函数</a></li>
    <li><a href="developer/modules.html">将模块从 Apache 1.3 移植到 Apache 2.x</a></li>
    <li><a href="developer/request.html">Apache 2.x 中的请求处理</a></li>
    <li><a href="developer/filters.html">Apache 2.x 中的过滤器</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index">术语与索引</a></h2>
    <ul><li><a href="glossary.html">术语</a></li>
    <li><a href="mod/">模块索引</a></li>
    <li><a href="mod/directives.html">指令索引</a></li>
    <li><a href="mod/quickreference.html">指令快速参考</a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>可用语言: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">评论</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />基于 <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p>
    <p class="menu"><a href="./mod/">模块</a> | <a href="./mod/directives.html">指令</a> | <a href="http://wiki.apache.org/httpd/FAQ">常见问题</a> | <a href="./glossary.html">术语</a> | <a href="./sitemap.html">网站导航</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sections.html.tr.utf8������������������������������������������������������0000664�0001751�0001751�00000122636�14743132254�021074� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Yapılandırma Bölümleri - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Yapılandırma Bölümleri</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><a href="configuring.html">Yapılandırma dosyaları</a>ndaki
           yönergeler sunucunun tamamına uygulanacağı gibi sadece belli dizinler,
           dosyalar, konaklar veya URL’lere uygulanmakla sınırlanabilir. Bu
           belgede, yapılandırma bölümü taşıyıcılarınının veya
           <code>.htaccess</code> dosyalarının, yapılandırma dosyalarındaki diğer
           yönergelerin etki alanlarını değiştirtirmek için nasıl kullanılacağı
           açıklanmıştır.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#types">Yapılandırma Bölümü Taşıyıcılarının Türleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-and-web">Dosya Sistemi, Site Alanı ve Mantıksal İfadeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Sanal Konaklar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Vekil</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#whatwhere">Hangi Yönergelere İzin Veriliyor?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#merging">Bölümler Nasıl Katıştırılır?</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="types" id="types">Yapılandırma Bölümü Taşıyıcılarının Türleri</a></h2>
    
        <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mod_version.html">mod_version</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_md.html#mdomainsetsection">&lt;MDomainSet&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>İki temel taşıyıcı türü vardır. Taşıyıcıların çoğu her istek için
          değerlendirmeye alınır. Taşıyıcılardaki yönergeler ise sadece bu
          taşıyıcılarla eşleşen istekler için uygulanır. Diğer yandan,
          <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>,
          <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> ve
          <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
          taşıyıcıları sadece sunucu başlatılırken veya yeniden başlatılırken
          değerlendirmeye alınır. Başlatma sırasında gerektirdikleri koşullar
          sağlanıyorsa içerdikleri yönergeler tüm isteklere uygulanır. Aksi
          takdirde, içerdikleri yönergeler yok sayılır.</p>
    
        <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> yönergesi
          sadece <code class="program"><a href="./programs/httpd.html">httpd</a></code> komut satırında uygun parametreler
          tanımlanmışsa uygulanabilecek yönergeleri içerir. Örneğin, aşağıdaki
          yapılandırma ile tüm isteklerin diğer siteye yönlendirilebilmesi sadece
          sunucu <code>httpd -DClosedForNow</code> komut satırı ile başlatıldığı
          takdirde mümkün olur:</p>
    
        <pre class="prettyprint lang-config">&lt;IfDefine ClosedForNow&gt;
      Redirect "/" "http://otherserver.example.com/"
    &lt;/IfDefine&gt;</pre>
    
    
        <p><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> yönergesi
          sadece belli bir modülün sunucuda kullanılabilir durumda olması halinde
          uygulanabilecek yönergeleri içerir. Modülün ya sunucuyla birlikte durağan
          olarak derlenmiş olması ya da devingen olarak derlenmiş ve yapılandırma
          dosyasında yönergeden önce o modüle ilişkin bir <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> satırının bulunması gerekir. Bu
          yönergeyi sadece belli bir modülün varlığının veya yokluğunun
          yapılandırma dosyanızın çalışmasını etkilememesini istediğiniz durumlarda
          kullanmalısınız. Eksik modüllerle ilgili hata iletilerini
          engellediğinden, taşıyıcı içine, her zaman çalışması istenen yönergeler
          konulmamalıdır.</p>
    
        <p>Aşağıdaki örnekte, <code class="directive"><a href="./mod/mod_mime_magic.html#mimemagicfile">MimeMagicFile</a></code> yönergesi sadece
          <code class="module"><a href="./mod/mod_mime_magic.html">mod_mime_magic</a></code> modülü mevcutsa uygulanacaktır.</p>
    
        <pre class="prettyprint lang-config">&lt;IfModule mod_mime_magic.c&gt;
      MimeMagicFile "conf/magic"
    &lt;/IfModule&gt;</pre>
    
    
        <p><code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
          yönergesi sunucunun belli bir sürümünün çalıştırılması halinde
          uygulanabilecek yönergeleri içerebilmesi dışında <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> ve <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> yönergeleri gibidir.
          <code class="module"><a href="./mod/mod_version.html">mod_version</a></code> modülü farklı httpd sürümleri ve farklı
          yapılandırmalarla büyük ağlarda çalışmayı mümkün kılmak veya sürüm
          denemeleri yapabilmek amacıyla tasarlanmıştır.</p>
    
        <pre class="prettyprint lang-config">&lt;IfVersion &gt;= 2.4&gt;
      # burası sadece 2.4.0 veya daha üstü sürümlerde
      # iş görür.
    &lt;/IfVersion&gt;</pre>
    
    
        <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>,
          <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> ve
          <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
          yönergelerinin önüne "!" konularak olumsuz koşullar için uygulanabilir.
          Ayrıca, bu bölümler daha karmaşık sınırlamalar elde etmek amacıyla bir
          diğerinin içinde kullanılabilirler.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-and-web" id="file-and-web">Dosya Sistemi, Site Alanı ve Mantıksal İfadeler</a></h2>
        
    
        <p>En sık kullanılan yapılandırma bölümü taşıyıcıları dosya sistemindeki
          veya site alanındaki belli yerlerin yapılandırmalarını değiştirmekte
          kullanılanlardır. Öncelikle, bu ikisi arasındaki farkları bilmek
          önemlidir. Dosya sistemi disklerinizin işletim sistemi tarafından size
          gösterilen halidir. Örneğin, öntanımlı kurulumda Apache httpd, Unix
          sistemlerinde  <code>/usr/local/apache2</code> altındayken Windows
          sistemlerinde  <code>"c:/Program Files/Apache Group/Apache2"</code>
          altındadır. (Bilgi: Windows için bile, Apache httpd yapılandırma
          dosyalarında dosya yolu belirtilirken tersbölü değil normal bölü
          karakterleri kullanılır.) Site alanı ise sunucu tarafından istemciye
          sunulan dizin ağacıdır. Yani, site alanı içindeki <code>/dir/</code>
          dizini, Apache httpd’nin Unix üzerinde dosya sistemine öntanımlı olarak
          kurulduğu yer göz önüne alınarak, dosya sistemindeki
          <code>/usr/local/apache2/htdocs/dir/</code> dizinine karşılıktır. Site
          sayfaları veritabanlarından veya başka yerlerden devingen olarak
          üretilebildiğinden site alanlarının doğrudan dosya sistemine eşlenmesi
          gerekli değildir.</p>
    
      <h3><a name="filesystem" id="filesystem">Dosya Sistemi Taşıyıcıları</a></h3>
    
        <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
          ve <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
          taşıyıcıları, <a class="glossarylink" href="./glossary.html#regex" title="sözlüğe bakınız">düzenli ifade</a> karşılıkları
          ile beraber, yönergeleri dosya sisteminin parçalarına uygularlar. Bir
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümü
          içindeki yönergeler belli bir dosya sistemi dizinine ve onun alt
          dizinlerine uygulanır. Aynı etki <a href="howto/htaccess.html">.htaccess
          dosyaları</a> kullanılarak da sağlanabilir. Örneğin aşağıdaki
          yapılandırmada, <code>/var/web/dir1</code> dizini ve alt dizinlerinde
          dizin içeriğinin listelenmesi etkin kılınmaktadır.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/var/web/dir1"&gt;
      Options +Indexes
    &lt;/Directory&gt;</pre>
    
    
        <p>Bir <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> bölümü
          içindeki yönergeler, hangi dizinde bulunduğuna bakılmaksızın ismi
          belirtilen dosyalara uygulanır. Örneğin, aşağıdaki yapılandırma
          yönergeleri yapılandırma dosyasının ana bölümüne yerleştirildiği takdirde
          <code>gizli.html</code> isimli dosyalara nerede bulunursa bulunsun
          erişime izin vermeyecektir.</p>
    
        <pre class="prettyprint lang-config">&lt;Files "gizli.html"&gt;
      Require all denied
    &lt;/Files&gt;</pre>
    
    
        <p>Dosya sisteminin belli bir yerindeki belli dosyalarla ilgili yaptırımlar
          için <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> ve
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümleri
          birlikte kullanılabilir. Örneğin, aşağıdaki yapılandırma
          <code>/var/web/dir1/gizli.html</code>,
          <code>/var/web/dir1/subdir2/gizli.html</code>,
          <code>/var/web/dir1/subdir3/gizli.html</code> ve
          <code>/var/web/dir1/</code> altında bulunabilecek diğer tüm
          <code>gizli.html</code> dosyalarına erişimi yasaklar.</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/var/web/dir1"&gt;<br />
      &lt;Files "gizli.html"&gt;<br />
        Require all denied
      &lt;/Files&gt;<br />
    &lt;/Directory&gt;</pre>
    
      
    
      <h3><a name="webspace" id="webspace">Site Alanı Taşıyıcıları</a></h3>
    
        <p><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> yönergesi
          ve yönergenin <a class="glossarylink" href="./glossary.html#regex" title="sözlüğe bakınız">düzenli ifade</a> karşılığı
          site alanındaki içerik için yapılandırmayı değiştirir.  Örneğin aşağıdaki
          yapılandırma, <code>/gizli</code> ile başlayan URL yollarına erişimi
          engeller. Özellikle, <code>http://siteniz.mesela.dom/gizli</code>,
          <code>http://siteniz.mesela.dom/gizli123</code> ve
          <code>http://siteniz.mesela.dom/gizli/dir/dosya.html</code>
          istekleri yanında <code>/gizli</code> ile başlayan diğer isteklere de
          uygulanır.</p>
    
        <pre class="prettyprint lang-config">&lt;LocationMatch "^/gizli"&gt;
        Require all denied
    &lt;/LocationMatch&gt;</pre>
    
    
        <p>Dosya sistemi ile etkileşime girmeyen herşey için
          <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
          yönergesi gerekir. Aşağıdaki örnekte, belli bir URL’nin
          <code class="module"><a href="./mod/mod_status.html">mod_status</a></code> modülü tarafından sağlanan bir dahili
          Apache eylemcisine nasıl eşlenebileceği gösterilmiştir. Bu örnek
          için dosya sisteminde <code>server-status</code> adında bir dosya
          veya dizin bulunması gerekli değildir.</p>
    
        <pre class="prettyprint lang-config">&lt;Location "/server-status"&gt;
        SetHandler server-status
    &lt;/Location&gt;</pre>
    
      
    
      <h3><a name="overlapping-webspace" id="overlapping-webspace">Site Alanında Çakışma</a></h3>
        <p>Belli bölümler ve yönergeler değerlendirilirken çakışan iki URL bir URL
        olarak dikkate alınır. <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> yönergesi için bu şöyle olurdu:</p>
    
        <pre class="prettyprint lang-config">&lt;Location "/foo"&gt;
    &lt;/Location&gt;
    &lt;Location "/foo/bar"&gt;
    &lt;/Location&gt;</pre>
    
    
        <p>Diğer yandan <code class="directive"><a href="./mod/mod_alias.html#takma adlar">&lt;Takma
          adlar&gt;</a></code> tam tersi eşlenir:</p>
    
        <pre class="prettyprint lang-config">Alias "/foo/bar" "/srv/www/uncommon/bar"
    Alias "/foo"     "/srv/www/common/foo"</pre>
    
    
        <p>Aynısı <code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code>
          yönergeleri için de geçerlidir:</p>
    
        <pre class="prettyprint lang-config">ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
    ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On</pre>
    
      
    
      <h3><a name="wildcards" id="wildcards">Dosya Adı Şablonları ve Düzenli İfadeler</a></h3>
        
    
        <p><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
          <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> ve
          <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
          yönergelerinde, Standart C kütüphanesindeki <code>fnmatch</code>
          işlevindeki gibi kabuk tarzı dosya ismi kalıpları kullanılabilir. "*"
          karakteri herhangi bir karakter dizisi ile eşleşirken "?" karakteri tek
          tek karakterlerle ve "[<em>seq</em>]" kalıbı ise <em>seq</em> içindeki
          her karakterle eşleşir. "/" karakteri her hangi bir kalıp karakteri ile
          eşleşmez; açıkça belirtilmesi gerekir.</p>
    
        <p>Daha esnek bir eşleşmenin gerekli olduğu durumlar için her taşıyıcının
          bir düzenli ifade karşılığı vardır. <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code> ve <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> yönergelerinde gerekli
          eşleşmeleri seçmek için perl uyumlu <a class="glossarylink" href="./glossary.html#regex" title="sözlüğe bakınız">düzenli
          ifadelerin</a> kullanımına izin verilir. Ayrıca, yönergelerin
          uygulanışının düzenli ifade bölümleri kullanılarak nasıl
          değiştirileceğini öğrenmek için, aşağıda, yapılandırmanın
          katıştırılmasıyla ilgili bölüme de bakınız.</p>
    
        <p>Tüm kullanıcı dizinlerine ilişkin yapılandırmayı değiştirmek için dosya
          ismi kalıpları şöyle kullanılabilirdi:</p>
    
        <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html"&gt;
        Options Indexes
    &lt;/Directory&gt;</pre>
    
    
        <p>Düzenli ifade bölümleri kullanarak çeşitli türlerdeki resim dosyalarına
          erişimi bir defada yasaklayabiliriz:</p>
    
        <pre class="prettyprint lang-config">&lt;FilesMatch "\.(?i:gif|jpe?g|png)$"&gt;
        Require all denied
    &lt;/FilesMatch&gt;</pre>
    
    
        <p><strong>İsimli gruplar ve geriye başvurular</strong> içeren düzenli
          ifadeler ortama eklenirken ilgili isimler büyük harfli yapılır. Böylece,
          URL'lere ve dosya yolları elemanlarına <a href="expr.html">ifadelerin
          içinden</a> ve <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> gibi modüllerden başvurmak
          mümkün olur.</p>
    
    <pre class="prettyprint lang-config">&lt;DirectoryMatch "^/var/www/combined/(?&lt;SITENAME&gt;[^/]+)"&gt;
        Require ldap-group "cn=%{env:MATCH_SITENAME},ou=combined,o=Example"
    &lt;/DirectoryMatch&gt;</pre>
    
      
    
      <h3><a name="expressions" id="expressions">Mantıksal İfadeler</a></h3>
        <p><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> yönergesi bir
          mantıksal ifade olarak belirtilebilen bir kurala bağlı olarak
          yapılandırmayı değiştirebilir. Örneğin, aşağıdaki yapılandırmada,
          <code>HTTP Referer</code> başlığı "http://www.example.com/" ile
          başlamıyorsa erişimi yasaklar.</p>
    
        <pre class="prettyprint lang-config">&lt;If "!(%{HTTP_REFERER} -strmatch 'http://www.example.com/*')"&gt;
        Require all denied
    &lt;/If&gt;</pre>
    
      
    
      <h3><a name="whichwhen" id="whichwhen">Ne, Ne Zaman Kullanılır?</a></h3>
        <p>Dosya sistemi taşıyıcıları ile site alanı taşıyıcıları arasında seçim
          yapmak aslında oldukça kolaydır. Dosya sisteminde bulunan nesnelere
          uygulanacak yönergeler için daima <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> veya <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> kullanılır. Dosya sisteminde bulunmayan nesnelere
          (bir sayfanın bir veritabanı tarafından üretilmesi gibi) uygulanacak
          yönergeler için ise <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> kullanılır.</p>
    
        <p>Dosya sistemindeki nesnelere erişimi kısıtlarken asla
          <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
          kullanmamak önemlidir. Bunun sebebi farklı site alanı konumlarının
          (URL’ler) aynı dosya sistemi konumuna eşlenebilmesi dolayısıyla
          kısıtlamalarınızın etrafından dolaşılabilmesine izin vermesidir.
          Örneğin, aşağıdaki yapılandırmayı ele alalım:</p>
    
        <pre class="prettyprint lang-config">&lt;Location "/dir/"&gt;
        Require all denied
    &lt;/Location&gt;</pre>
    
    
        <p><code>http://siteniz.mesela.dom/dir/</code> için bir istek yapılmışsa
          bu doğru çalışacaktır. Fakat dosya sistemi harf büyüklüğüne duyarsızsa
          ne olacak? Kısıtlamanız, istek
          <code>http://siteniz.mesela.dom/DIR/</code>
          şeklinde yapılarak kolayca geçersiz kılınabilir. Halbuki <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> yönergesi isteğin
          nasıl yapıldığına bakılmaksızın bu konumdan sunulan her türlü içeriğe
          uygulanacaktı. (Dosya sistemi bağlarıyla bu da aşılabilir. Sembolik
          bağlar kullanılarak aynı dizin dosya sisteminin bir çok yerine
          yerleştirilebilir. <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> yönergesi dosya yolunu sıfırlamaksızın sembolik
          bağları izleyecektir. Bu bakımdan, en yüksek seviyede güvenlik için uygun
          <code class="directive"><a href="./mod/core.html#options">Options</a></code> yönergesi ile sembolik
          bağların izlenmesi devredışı bırakılabilir.)</p>
    
        <p>Belki de siz sırf harf büyüklüğüne duyarlı bir dosya sistemi
          kullanıyorsunuz diye böyle uygulamalara ihtiyacınız olmadığını düşünüyor
          olabilirsiniz, fakat aynı site alanını çok sayıda dosya sistemi konumuna
          eşleyecek daha bir sürü yol bulunduğunu unutmayınız. Bu bakımdan dosya
          sisteminde yapacağınız kısıtlamalarda daima dosya sistemi taşıyıcılarını
          kullanmalısınız. Bununla birlikte bu kuralın da bir istisnası vardır.
          Yapılandırma kısıtlamalarının bir <code>&lt;Location "/"&gt;</code> bölümü
          içine koyulması, bu bölüme konan yönergelerin etki alanının belli bir URL
          ile sınırlı olmaması nedeniyle mükemmelen güvenlidir.</p>
      
    
      <h3><a name="nesting" id="nesting">Bölüm iç içeliği</a></h3>
        <p>Bazı bölüm türleri başka bölüm türlerinin içinde olabilir. Bir yandan,
          <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> bölümü
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümünün
          içinde bulunabilirken diğer yandan bir <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümü <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> ve <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> bölümlerinde bulunabilir fakat
          başka bir <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümünün
          içinde bulunamaz. Bu bölümlerin düzenli ifadeli türevleri de benzer tarzda
          davranır.</p>
    
        <p>İç içe bölümler, aynı türdeki iç içe olmayan bölümlerin sonrasına
          yerleştirilir.</p>
      
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Sanal Konaklar</a></h2>
    
        <p><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
          taşıyıcısının içinde belli bir konağa uygulanan yönergeler bulunur.
          Aynı makinede çok sayıda konağı farklı yapılandırmalarla  sunuyorsanız
          bu taşıyıcı çok işinize yarar. Daha fazla bilgi için
          <a href="vhosts/">Sanal Konak Belgeleri</a> bölümüne bakınız.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Vekil</a></h2>
        <p><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
          ve <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
          taşıyıcıları, sadece belli bir URL ile eşleşen <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>
          vekil sunucusu üzerinden erişilen sitelere uygulanan yapılandırma
          yönergelerini bulundururlar. Örneğin aşağıdaki yapılandırma
          <code>example.com</code> sitesine erişim için vekil sunucunun
          sadece ağdaki bazı kullanıcılar tarafından kullanılabilmesini sağlayacaktır.</p>
    
        <pre class="prettyprint lang-config">&lt;Proxy "http://www.example.com/*"&gt;
        Require host bizimki.example.com
    &lt;/Proxy&gt;</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="whatwhere" id="whatwhere">Hangi Yönergelere İzin Veriliyor?</a></h2>
        <p>Hangi yönergelere hangi yapılandırma bölümlerinde izin verildiğini
          öğrenmek için yönerge <a href="mod/directive-dict.html#Context">bağlamına</a> bakınız. <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümlerinde
          izin verilen herşeye sözdizimsel olarak ayrıca
          <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>,
          <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>,
          <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>,
          <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>,
          <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>,
          <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
          ve <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
          bölümlerinde de izin verilir. Yine de bazı istisnai durumlar
          mevcuttur:</p>
    
        <ul>
          <li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> yönergesi sadece
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
          bölümlerinde çalışır.</li>
    
          <li><code class="directive"><a href="./mod/core.html#options">Options</a></code> yönergesinin
          <code>FollowSymLinks</code> ve <code>SymLinksIfOwnerMatch</code>
          seçenekleri sadece <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümlerinde veya <code>.htaccess</code>
          dosyalarında çalışır.</li>
    
          <li><code class="directive"><a href="./mod/core.html#options">Options</a></code> yönergesi
          <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> ve
          <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>
          bölümlerinde kullanılamaz.</li>
        </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="merging" id="merging">Bölümler Nasıl Katıştırılır?</a></h2>
    
        <p>Yapılandırma bölümleri belli bir sıra ile uygulanır. Yapılandırma
          yönergelerinin yorumlanışı üzerinde önemli etkilere sahip olabilmesi
          nedeniyle neyin ne zaman çalıştığını anlamak çok önemlidir.</p>
    
        <p>Yapılandırma bölümlerinin katıştırılma sırası şöyledir:</p>
    
        <ol>
          <li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> (düzenli ifadeler hariç)
          ve <code>.htaccess</code> aynı anda işleme sokulur
          (<code>.htaccess</code> ile eğer izin verilmişse <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> içindeki bazı
          yönergeler geçersiz kılınabileceği için).</li>
    
          <li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>
          (ve <code>&lt;Directory "~"&gt;</code>).</li>
    
          <li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> ve
          <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code> aynı anda
          işleme sokulur.</li>
    
          <li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
          ve <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>
          aynı anda işleme sokulur.</li>
    
          <li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümleri,
          önceki bağlamlardan herhangi birinin içine alınmış olsalar bile.
    
          </li>
        </ol>
    
        <p>Bazı önemli durumlar:</p>
        <ul>
            <li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
            bölümündekiler hariç, her grup, yapılandırma dosyasında bulundukları
            sıraya göre işleme sokulurlar. Örneğin, 4. grupta <em>/foo/bar</em> için yapılan
            bir istek <code>&lt;Location "/foo/bar"&gt;</code> ve <code>&lt;Location
            "/foo"&gt;</code> bölümleriyle de eşleşir ve bunlar yapılandırma
            dosyalarında bulundukları sıraya göre değerlendirilir.</li>
    
            <li>Yukarıda 1. grup olan <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümü en kısa dizin elemanından en uzun
            dizin elemanına doğru işleme sokulur. Yani, örneğin, <code>&lt;Directory
            "/var/web/dir"&gt;</code> bölümü <code>&lt;Directory
            "/var/web/dir/subdir"&gt;</code> bölümünden önce işleme sokulacaktır.</li>
    
            <li>Eğer aynı dizin için birden fazla <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümü varsa bunlar yapılandırma
            dosyasında bulundukları sıraya göre işleme sokulurlar.</li>
    
            <li><code class="directive"><a href="./mod/core.html#include">Include</a></code> yönergeleri ile
            yapılandırmaya dahil edilen dosyaların içerikleri <code class="directive"><a href="./mod/core.html#include">Include</a></code> yönergesinin bulunduğu yere konulduktan
            sonra işleme sokulurlar.</li>
    
           <li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
           bölümlerinin içindeki bölümler, sanal konak tanımı dışındaki
           karşılıklarından <em>sonra</em> uygulanırlar. Bu yöntemle ana sunucu
           yapılandırmasındaki tanımlar geçersiz kılınabilir</li>
    
           <li>İstek <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> tarafından sunulduğu takdirde,
           <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> taşıyıcısı
           işlem sırasında <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> taşıyıcısının yerini alır.</li>
    
           <li>katıştırma düzeni üzerindeki etkisi nedeniyle, ilgili yapılandırma
           yönergelerini <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>'in
           içinde ve dışında karıştırırken dikkatli olunmalıdır.  Doğrudan
           <code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code> kullanımının
           yardımı olabilir.</li>
    
           <li><code>.htaccess</code> içinde <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> kullanıldığında, üst dizindeki sarmalanmış
           yönergeler, alt dizinde sarmalanmamış yönergelerden <em>sonra</em>
           birleştirilir.</li>
        </ul>
    
        <div class="note"><h3>Bazı Teknik Bilgiler</h3>
          Aslında, isim dönüşüm aşamasından (<code>Aliases</code> ve
          <code>DocumentRoots</code>, URL’leri dosya isimlerine eşlemek için
          kullanılırken) hemen önce uygulanan bir
          <code>&lt;Location&gt;</code>/<code>&lt;LocationMatch&gt;</code> dizisi
          vardır. Bu dizinin sonuçları isim dönüşüm aşaması tamamlandıktan sonra
          tamamen elden çıkarılır.
        </div>
    
      <h3><a name="relationship-module-configuration" id="relationship-module-configuration">Modüllerle
        yapılandırma bölümleri arasındaki ilişki</a></h3>
    
        <p>Yapılandırma bölümlerini okurken örneğin <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
          gibi belli modüllerin yönergelerinin bu bölümlere nasıl katılacağı ve
          ne zaman nasıl işleneceği gibi sorular sıkça aklımızdan geçer. Bunun
          belli bir yanıtı yoktur ve biraz temel bilgi gerektirir. Her httpd
          modülü yapılandırmasını kendi yönetir ve httpd.conf içindeki
          yönergelerinin her biri belli bir bağlamdaki bir yapılandırmayı
          belirtir. httpd bir komutu okunduğu sırada çalıştırmaz.</p>
    
        <p>Çalışma anında, httpd çekirdeği geçerli isteğe hangilerinin
          uygulanacağını belirlemek için yukarıda açıklanan sırada tanımlı
          yapılandırma bölümlerini tekrar tekrar okur. Eşleşen ilk bölümün bu
          istek için geçerli yapılandırmayı içerdiği varsayılır. Eğer alt
          bölümlerden biri de eşleşmişse bu bölümlerde yönergeleri bulunan her
          modüle yapılandırmasını iki bölüm arasında katıştırma şansı verilir.
          Sonuç üçüncü bir yapılandırma olup işlem bütün yapılandırma bölümleri
          değerlendirilene kadar sürer.</p>
    
        <p>Yukarıdaki adımların ardından HTTP isteğiyle ilgili "asıl" işlem
          başlar: her modül ondan istenen görevleri gerçekleştirme şansına sahip
          olur. Nasıl davranacaklarını belirlemek için kendilerinin katıştırılmış
          son yapılandırmalarını http çekirdeğinden alabilirler.</p>
    
        <p>Sürecin tamamı bir örnekle görselleştirilebilir. Aşağıdaki örnekte
          belli bir HTTP başlığını ayarlamak için <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code>
          modülünün <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> yönergesi
          kullanılmıştır. <code>/example/index.html</code> isteği için httpd
          <code>CustomHeaderName</code> başlığına hangi değeri atayacaktır?
        </p>
        <pre class="prettyprint lang-config">&lt;Directory "/"&gt;
        Header set CustomHeaderName bir
        &lt;FilesMatch ".*"&gt;
            Header set CustomHeaderName yedi
        &lt;/FilesMatch&gt;
    &lt;/Directory&gt;
    
    &lt;Directory "/example"&gt;
        Header set CustomHeaderName iki
    &lt;/Directory&gt;</pre>
    
        <ul>
            <li><code class="directive">Directory</code> "/" eşleşir ve ilk yapılandırma
              olarak <code>CustomHeaderName</code> başlığı <code>bir</code>
              değeriyle oluşturulur.</li>
    
            <li><code class="directive">Directory</code> "/example" eşleşir ve
              <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> modülünün koduna göre bir katıştırma
              durumundan yeni değer eskiyi geçersiz kılacağından yeni bir
              yapılandırma ile <code>CustomHeaderName</code> başlığının değeri
              <code>iki</code> yapılır.</li>
    
            <li><code class="directive">FilesMatch</code> ".*" eşleşir ve başka bir
              katıştırma fırsatı doğar: <code>CustomHeaderName</code> başlığının
              değeri <code>yedi</code> yapılır.</li>
    
            <li>Neticede HHP isteğinin sonraki adımlarında
              <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> çağrılıp <code>yedi</code> değeri
              atanmış <code>CustomHeaderName</code> başlığını işleme sokması
              istenecektir. <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> normalde işini yapmak
              için bu yapılandırmayı kullanacaktır. Fakat bundan, bir yönergenin
              gerekli olmaması veya kullanımdan kaldırılması ve benzeri nedenlerle
              yapılandırmada iptal edilmesi gibi daha karmaşık bir eylemi bir
              modülün gerçekleştiremeyeceği anlamı çıkarılmamalıdır.</li>
        </ul>
    
        <p><code class="directive">Directory</code> ile aynı katıştırma sırasından dolayı
          bu durum .htaccess için de geçerlidir. Burada anlaşılması gereken husus,
          <code class="directive">Directory</code> ve <code class="directive">FilesMatch</code>
          gibi yapılandırma bölümlerinin <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> veya <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> gibi modüle özgü
          yönergelerle karşılaştırılmamasıdır, çünkü bunlar farklı seviyelerde
          işlem görür.
        </p>
      
    
      <h3><a name="merge-examples" id="merge-examples">Bazı Örnekler</a></h3>
    
        <p>Aşağıdaki yapay örnekte katıştırma sırası gösterilmiştir. Hepsinin aynı
          isteğe uygulandığı varsayımıyla, bu örnekteki yönergeler A &gt; B &gt; C
          &gt; D &gt; E sırasıyla uygulanacaktır.</p>
    
        <pre class="prettyprint lang-config">&lt;Location "/"&gt;
        E
    &lt;/Location&gt;
    
    &lt;Files "f.html"&gt;
        D
    &lt;/Files&gt;
    
    &lt;VirtualHost *&gt;
        &lt;Directory "/a/b"&gt;
            B
        &lt;/Directory&gt;
    &lt;/VirtualHost&gt;
    
    &lt;DirectoryMatch "^.*b$"&gt;
        C
    &lt;/DirectoryMatch&gt;
    
    &lt;Directory "/a/b"&gt;
        A
    &lt;/Directory&gt;</pre>
    
    
        <p>Daha somut bir örnek olarak aşağıdakini ele alalım.
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
          bölümlerindeki erişim sınırlamaları ne olursa olsun <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> bölümü son olarak
          değerlendirmeye alınacak ve sunucuya sınırsız erişim verecektir.
          Başka bir deyişle, katıştırma sırası önemlidir, bu nedenle dikkatli
          olmalısınız!</p>
    
        <pre class="prettyprint lang-config">&lt;Location "/"&gt;
        Require all granted
    &lt;/Location&gt;
    
    # Alooo!  Bu &lt;Directory&gt; bölümünün hiçbir hükmü yok.
    &lt;Directory "/"&gt;
        &lt;RequireAll&gt;
            Require all granted
            Require not host kkadam.example.com
        &lt;/RequireAll&gt;
    &lt;/Directory&gt;</pre>
    
    
      
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sections.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.de������������������������������������������������������������0000664�0001751�0001751�00000064220�14743132254�017757� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Seitenindex - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP-Server</a> &gt; <a href="http://httpd.apache.org/docs/">Dokumentation</a> &gt; <a href="./">Version 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>Seitenindex</h1>
    <div class="toplang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/sitemap.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <div class="outofdate">Diese &#220;bersetzung ist m&#246;glicherweise
                nicht mehr aktuell. Bitte pr&#252;fen Sie die englische Version auf
                die neuesten &#196;nderungen.</div>
    
    <p>Diese Seite verzeichnet die zur Zeit verf&#252;gbaren Dokumente der
    <a href="./">Dokumentation zum Apache HTTP Server Version
    2.4</a>.</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">Hinweise zur Version</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Bedienung des Apache HTTP Servers</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">Apache-Dokumentation zu virtuellen Hosts</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">Einf&#252;hrung in die URL-Manipulation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">SSL/TLS-Verschl&#252;sselung des Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">Praxis / Anleitungen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">Plattform-spezifische Anmerkungen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Apache HTTP Server und Hilfsprogramme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Weitere Apache-Dokumentationen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Apache-Module</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Dokumentation f&#252;r Entwickler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index">Glossar und Index</a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">Hinweise zur Version</a></h2>
    <ul><li><a href="upgrading.html">Upgrade von 2.2 auf 2.4</a></li>
    <li><a href="new_features_2_4.html">Neue Funktionen in Version 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Neue Funktionen in Version 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">Neue Funktionen in Version 2.0</a></li>
    <li><a href="license.html">Apache-Lizenz</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">Bedienung des Apache HTTP Servers</a></h2>
    <ul><li><a href="install.html">Kompilieren und Installieren</a></li>
    <li><a href="invoking.html">Apache starten</a></li>
    <li><a href="stopping.html">Beenden und Neustarten des Servers</a></li>
    <li><a href="configuring.html">Konfigurationsdateien</a></li>
    <li><a href="sections.html">Konfigurationsabschnitte</a></li>
    <li><a href="caching.html">Caching von Inhalten</a></li>
    <li><a href="server-wide.html">Serverweite Konfiguration</a></li>
    <li><a href="logs.html">Log-Dateien</a></li>
    <li><a href="urlmapping.html">URLs auf das Dateisystem abbilden</a></li>
    <li><a href="dso.html">Dynamic Shared Object (DSO)</a></li>
    <li><a href="content-negotiation.html">Content Negotiation</a></li>
    <li><a href="custom-error.html">Individuelle Fehlermeldungen</a></li>
    <li><a href="bind.html">Bestimmen der vom Apache verwendeten Adressen und Ports</a></li>
    <li><a href="mpm.html">Multi-Processing-Module (MPMs)</a></li>
    <li><a href="env.html">Umgebungsvariablen</a></li>
    <li><a href="expr.html">Parsen von Ausdr&#252;cken</a></li>
    <li><a href="handler.html">Handler</a></li>
    <li><a href="filter.html">Filter</a></li>
    <li><a href="socache.html">Unterst&#252;tzung f&#252;r gemeinsame Objekt-Zwischenspeicher</a></li>
    <li><a href="suexec.html">suEXEC Unterst&#252;tzung</a></li>
    <li><a href="dns-caveats.html">Probleme bez&#252;glich DNS und Apache</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">H&#228;ufig gestellte Fragen
        (FAQ)</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">Apache-Dokumentation zu virtuellen Hosts</a></h2>
    <ul><li class="separate"><a href="vhosts/">&#220;bersicht</a></li>
    <li><a href="vhosts/name-based.html">Namensbasierte virtuelle Hosts</a></li>
    <li><a href="vhosts/ip-based.html">IP-basierte virtuelle Hosts</a></li>
    <li><a href="vhosts/mass.html">Dynamisch konfiguriertes Massen-Virtual-Hosting</a></li>
    <li><a href="vhosts/examples.html">Beispiele f&#252;r virtuelle Hosts in
      typischen Installationen</a></li>
    <li><a href="vhosts/details.html">Tiefergehende Er&#246;rterung der Zuweisung
      virtueller Hosts</a></li>
    <li><a href="vhosts/fd-limits.html">Datei-Deskriptor-Begrenzungen</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="rewrite" id="rewrite">Einf&#252;hrung in die URL-Manipulation</a></h2>
    <ul><li class="separate"><a href="rewrite/">&#220;bersicht</a></li>
    <li><a href="mod/mod_rewrite.html">Referenz-Dokumentation von
    mod_rewrite</a></li>
    <li><a href="rewrite/intro.html">Einf&#252;hrung in regul&#228;re Ausdr&#252;cke und mod_rewrite</a></li>
    <li><a href="rewrite/remapping.html">Verwendung von mod_rewrite, um URLs umzuleiten oder umzuschreiben</a></li>
    <li><a href="rewrite/access.html">Zugriffskontrolle mit mod_rewrite</a></li>
    <li><a href="rewrite/vhosts.html">Dynamische virtuelle Hosts mit mod_rewrite</a></li>
    <li><a href="rewrite/proxy.html">Dynamische Proxy-Konfigurationen mit mod_rewrite</a></li>
    <li><a href="rewrite/rewritemap.html">RewriteMap einsetzen</a></li>
    <li><a href="rewrite/advanced.html">Fortgeschrittene Techniken</a></li>
    <li><a href="rewrite/avoid.html">Wann man auf mod_rewrite verzichten sollte</a></li>
    <li><a href="rewrite/flags.html">Schalter / Flags</a></li>
    <li><a href="rewrite/tech.html">Technische Details</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">SSL/TLS-Verschl&#252;sselung des Apache</a></h2>
    <ul><li class="separate"><a href="ssl/">&#220;bersicht</a></li>
    <li><a href="ssl/ssl_intro.html">SSL/TLS-Verschl&#252;sselung: Einf&#252;hrung</a></li>
    <li><a href="ssl/ssl_compat.html">SSL/TLS-Verschl&#252;sselung: Kompatibilit&#228;t</a></li>
    <li><a href="ssl/ssl_howto.html">SSL/TLS-Verschl&#252;sselung: Praxis</a></li>
    <li><a href="ssl/ssl_faq.html">SSL/TLS-Verschl&#252;sselung: FAQ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">Praxis / Anleitungen</a></h2>
    <ul><li class="separate"><a href="howto/">&#220;bersicht</a></li>
    <li><a href="howto/auth.html">Authentisierung und Autorisierung</a></li>
    <li><a href="howto/access.html">Zugriffskontrolle</a></li>
    <li><a href="howto/cgi.html">Dynamische Inhalte mit CGI</a></li>
    <li><a href="howto/ssi.html">Einf&#252;hrung in Server Side Includes</a></li>
    <li><a href="howto/htaccess.html">.htaccess-Dateien</a></li>
    <li><a href="howto/public_html.html">Web-Verzeichnisse f&#252;r Benutzer</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">Plattform-spezifische Anmerkungen</a></h2>
    <ul><li class="separate"><a href="platform/">&#220;bersicht</a></li>
    <li><a href="platform/windows.html">Apache unter Microsoft
    Windows einsetzen</a></li>
    <li><a href="platform/win_compiling.html">Kompilieren des Apache f&#252;r
    Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">Apache auf RPM-basierten Systemen einsetzen</a></li>
    <li><a href="platform/netware.html">Apache unter Novell NetWare einsetzen</a></li>
    <li><a href="platform/perf-hp.html">Einen Hochleistungs-Web-Server auf
    HPUX betreiben</a></li>
    <li><a href="platform/ebcdic.html">Die Apache EBCDIC-Portierung</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">Apache HTTP Server und Hilfsprogramme</a></h2>
    <ul><li class="separate"><a href="programs/">&#220;bersicht</a></li>
    <li><a href="programs/httpd.html">httpd</a></li>
    <li><a href="programs/ab.html">ab</a></li>
    <li><a href="programs/apachectl.html">apachectl</a></li>
    <li><a href="programs/apxs.html">apxs</a></li>
    <li><a href="programs/configure.html">configure</a></li>
    <li><a href="programs/dbmmanage.html">dbmmanage</a></li>
    <li><a href="programs/fcgistarter.html">fcgistarter</a></li>
    <li><a href="programs/htcacheclean.html">htcacheclean</a></li>
    <li><a href="programs/htdbm.html">htdbm</a></li>
    <li><a href="programs/htdigest.html">htdigest</a></li>
    <li><a href="programs/htpasswd.html">htpasswd</a></li>
    <li><a href="programs/httxt2dbm.html">httxt2dbm</a></li>
    <li><a href="programs/logresolve.html">logresolve</a></li>
    <li><a href="programs/log_server_status.html">log_server_status</a></li>
    <li><a href="programs/rotatelogs.html">rotatelogs</a></li>
    <li><a href="programs/split-logfile.html">split-logfile</a></li>
    <li><a href="programs/suexec.html">suexec</a></li>
    <li><a href="programs/other.html">Sonstige Programme</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Weitere Apache-Dokumentationen</a></h2>
    <ul><li class="separate"><a href="misc/">&#220;bersicht</a></li>
    <li><a href="misc/perf-tuning.html">Performance-Hinweise</a></li>
    <li><a href="misc/security_tips.html">Tipps zur Sicherheit</a></li>
    <li><a href="misc/relevant_standards.html">Wichtige Standards</a></li>
    <li><a href="misc/password_encryptions.html">Verschl&#252;sselungsformate f&#252;r Passworte</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">Apache-Module</a></h2>
    <ul><li><a href="mod/module-dict.html">Erkl&#228;rung der Fachbegriffe zu Apache-Modulen</a></li>
    <li><a href="mod/directive-dict.html">Erkl&#228;rung der Fachbegriffe zu Apache-Direktiven</a></li>
    </ul><ul><li><a href="mod/core.html">Apache-Kernfunktionen</a></li>
    <li><a href="mod/mpm_common.html">Allgemeine Direktiven der Apache-MPMs</a></li>
    <li><a href="mod/event.html">Apache-MPM event</a></li>
    <li><a href="mod/mpm_netware.html">Apache-MPM netware</a></li>
    <li><a href="mod/mpmt_os2.html">Apache-MPM os2</a></li>
    <li><a href="mod/prefork.html">Apache-MPM prefork</a></li>
    <li><a href="mod/mpm_winnt.html">Apache-MPM winnt</a></li>
    <li><a href="mod/worker.html">Apache-MPM worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">Apache-Modul mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">Apache-Modul mod_actions</a></li>
    <li><a href="mod/mod_alias.html">Apache-Modul mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">Apache-Modul mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">Apache-Modul mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">Apache-Modul mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">Apache-Modul mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">Apache-Modul mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">Apache-Modul mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">Apache-Modul mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">Apache-Modul mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">Apache-Modul mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">Apache-Modul mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">Apache-Modul mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">Apache-Modul mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">Apache-Modul mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">Apache-Modul mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">Apache-Modul mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">Apache-Modul mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">Apache-Modul mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">Apache-Modul mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">Apache-Modul mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">Apache-Modul mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">Apache-Modul mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">Apache-Modul mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">Apache-Modul mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">Apache-Modul mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">Apache-Modul mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">Apache-Modul mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">Apache-Modul mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">Apache-Modul mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">Apache-Modul mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">Apache-Modul mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">Apache-Modul mod_data</a></li>
    <li><a href="mod/mod_dav.html">Apache-Modul mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">Apache-Modul mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">Apache-Modul mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">Apache-Modul mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">Apache-Modul mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">Apache-Modul mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">Apache-Modul mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">Apache-Modul mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">Apache-Modul mod_echo</a></li>
    <li><a href="mod/mod_env.html">Apache-Modul mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">Apache-Modul mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">Apache-Modul mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">Apache-Modul mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">Apache-Modul mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">Apache-Modul mod_filter</a></li>
    <li><a href="mod/mod_headers.html">Apache-Modul mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">Apache-Modul mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">Apache-Modul mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">Apache-Modul mod_http2</a></li>
    <li><a href="mod/mod_ident.html">Apache-Modul mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">Apache-Modul mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">Apache-Modul mod_include</a></li>
    <li><a href="mod/mod_info.html">Apache-Modul mod_info</a></li>
    <li><a href="mod/mod_isapi.html">Apache-Modul mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">Apache-Modul mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">Apache-Modul mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">Apache-Modul mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">Apache-Modul mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">Apache-Modul mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">Apache-Modul mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">Apache-Modul mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">Apache-Modul mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">Apache-Modul mod_logio</a></li>
    <li><a href="mod/mod_lua.html">Apache-Modul mod_lua</a></li>
    <li><a href="mod/mod_macro.html">Apache-Modul mod_macro</a></li>
    <li><a href="mod/mod_md.html">Apache-Modul mod_md</a></li>
    <li><a href="mod/mod_mime.html">Apache-Modul mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">Apache-Modul mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">Apache-Modul mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">Apache-Modul mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">Apache-Modul mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">Apache-Modul mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">Apache-Modul mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">Apache-Modul mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">Apache-Modul mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">Apache-Modul mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">Apache-Modul mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">Apache-Modul mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">Apache-Modul mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">Apache-Modul mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">Apache-Modul mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">Apache-Modul mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">Apache-Modul mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">Apache-Modul mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">Apache-Modul mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">Apache-Modul mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">Apache-Modul mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">Apache-Modul mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">Apache-Modul mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">Apache-Modul mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">Apache-Modul mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">Apache-Modul mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">Apache-Modul mod_sed</a></li>
    <li><a href="mod/mod_session.html">Apache-Modul mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">Apache-Modul mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">Apache-Modul mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">Apache-Modul mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">Apache-Modul mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">Apache-Modul mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">Apache-Modul mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">Apache-Modul mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">Apache-Modul mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">Apache-Modul mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">Apache-Modul mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">Apache-Modul mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">Apache-Modul mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">Apache-Modul mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">Apache-Modul mod_ssl</a></li>
    <li><a href="mod/mod_status.html">Apache-Modul mod_status</a></li>
    <li><a href="mod/mod_substitute.html">Apache-Modul mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">Apache-Modul mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">Apache-Modul mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">Apache-Modul mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">Apache-Modul mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">Apache-Modul mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">Apache-Modul mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">Apache-Modul mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">Apache-Modul mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">Apache-Modul mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">Apache-Modul mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer">Dokumentation f&#252;r Entwickler</a></h2>
    <ul><li class="separate"><a href="developer/">&#220;bersicht</a></li>
    <li><a href="developer/API.html">Anmerkungen zur Apache-API</a></li>
    <li><a href="developer/new_api_2_4.html">API-&#196;nderungen im Apache HTTPD
    2.4</a></li>
    <li><a href="developer/modguide.html">Module f&#252;r Apache HTTPD 2.4 entwickeln</a></li>
    <li><a href="developer/documenting.html">Apache HTTPD dokumentieren</a></li>
    <li><a href="developer/hooks.html">Hook-Funktionen des Apache 2.x</a></li>
    <li><a href="developer/modules.html">Module von 1.3 nach 2.x konvertieren</a></li>
    <li><a href="developer/request.html">Verarbeitung der Anfragen in Version 2.x</a></li>
    <li><a href="developer/filters.html">Wie Filter in Version 2.x funktionieren</a></li>
    <li><a href="developer/output-filters.html">Richtlinien f&#252;r Ausgangsfilter in Version 2.x</a></li>
    <li><a href="developer/thread_safety.html">Thread-Sicherheit in Version 2.x</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index">Glossar und Index</a></h2>
    <ul><li><a href="glossary.html">Glossar</a></li>
    <li><a href="mod/">Modul-Index</a></li>
    <li><a href="mod/directives.html">Direktiven-Index</a></li>
    <li><a href="mod/quickreference.html">Kurzreferenz der Direktiven</a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>Verf&#252;gbare Sprachen: </span><a href="./de/sitemap.html" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Kommentare</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Lizenziert unter der <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Module</a> | <a href="./mod/directives.html">Direktiven</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossar</a> | <a href="./sitemap.html">Seitenindex</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.tr.utf8�������������������������������������������������������0000664�0001751�0001751�00000065504�14743132254�020707� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Site Haritası - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>Site Haritası</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>Bu sayfada <a href="./">Apache HTTP Sunucusu Sürüm 2.4
    Belgeleri</a>nin tamamı listelenmiştir.</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">Sürümlerin Dağıtım Bilgileri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Apache HTTP Sunucusunun Kullanımı</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">Apache Sanal Konak (VirtualHost) Belgeleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">URL’lerin Yeniden Yazılması</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">Apache SSL/TLS Şifrelemesi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">Kılavuzlar, Öğreticiler ve Nasıllar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">Platformlara Özgü Bilgiler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Apache HTTP Sunucusu  ve Desteklenen Programlar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Çeşitli Belgeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Apache Modülleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Geliştirici Belgeleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index">Terimler ve Dizin</a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">Sürümlerin Dağıtım Bilgileri</a></h2>
    <ul><li><a href="upgrading.html">2.4’e 2.2’den yükseltme</a></li>
    <li><a href="new_features_2_4.html">2.3/2.4’teki yeni özellikler</a></li>
    <li><a href="new_features_2_2.html">Apache 2.1/2.2’deki yeni özellikler</a></li>
    <li><a href="new_features_2_0.html">Apache 2.0’daki yeni özellikler</a></li>
    <li><a href="license.html">Apache Lisansı</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">Apache HTTP Sunucusunun Kullanımı</a></h2>
    <ul><li><a href="install.html">Derleme ve Kurulum</a></li>
    <li><a href="invoking.html">Sunucuyu Başlatma</a></li>
    <li><a href="stopping.html">Sunucuyu Durdurma ve Yeniden Başlatma</a></li>
    <li><a href="configuring.html">Yapılandırma Dosyaları</a></li>
    <li><a href="sections.html">Directory, Location ve Files Bölümleri Nasıl Çalışır</a></li>
    <li><a href="caching.html">İçerik Bellekleme</a></li>
    <li><a href="server-wide.html">Sunucu Genelinde Yapılandırma</a></li>
    <li><a href="logs.html">Günlük Dosyaları</a></li>
    <li><a href="urlmapping.html">URL’lerin Dosya Sistemi ile Eşlenmesi</a></li>
    <li><a href="dso.html">Devingen Paylaşımlı Nesne (DSO) Desteği</a></li>
    <li><a href="content-negotiation.html">İçerik Dili Uzlaşımı</a></li>
    <li><a href="custom-error.html">Özel Hata Yanıtları</a></li>
    <li><a href="bind.html">Sunucunun Kullandığı Adreslerin ve Portların Ayarlanması</a></li>
    <li><a href="mpm.html">Çok Süreçlilik Modülleri (MPM’ler)</a></li>
    <li><a href="env.html">Ortam Değişkenleri</a></li>
    <li><a href="expr.html">Apache'de İfadelerin Çözümlenmesi</a></li>
    <li><a href="handler.html">Eylemci Kullanımı</a></li>
    <li><a href="filter.html">Süzgeçler</a></li>
    <li><a href="socache.html">Paylaşımlı Nesne Arabelleği Desteği</a></li>
    <li><a href="suexec.html">CGI için Suexec Desteği</a></li>
    <li><a href="dns-caveats.html">DNS ile ilgili Konular ve Apache</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">Sıkça Sorulan Sorular</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">Apache Sanal Konak (VirtualHost) Belgeleri</a></h2>
    <ul><li class="separate"><a href="vhosts/">Genel Bakış</a></li>
    <li><a href="vhosts/name-based.html">İsme göre Sanal Konak Desteği</a></li>
    <li><a href="vhosts/ip-based.html">IP Adresine göre Sanal Konak Desteği</a></li>
    <li><a href="vhosts/mass.html">Sanal Konakların Devingen olarak Yapılandırılması</a></li>
    <li><a href="vhosts/examples.html">VirtualHost Örnekleri</a></li>
    <li><a href="vhosts/details.html">Sanal Konak Eşleştirmesinin Derinliğine İncelenmesi</a></li>
    <li><a href="vhosts/fd-limits.html">Dosya Tanıtıcı Sınırlamaları</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="rewrite" id="rewrite">URL’lerin Yeniden Yazılması</a></h2>
    <ul><li class="separate"><a href="rewrite/">Genel Bakış</a></li>
    <li><a href="mod/mod_rewrite.html">mod_rewrite Başvuru Belgesi</a></li>
    <li><a href="rewrite/intro.html">mod_rewrite ve düzenli ifadelere giriş</a></li>
    <li><a href="rewrite/remapping.html">URL'lerin yeniden eşlenmesi ve
    yönlendirilmesi içinmod_rewrite kullanımı</a></li>
    <li><a href="rewrite/access.html">Erişim denetimi için mod_rewrite
    kullanımı</a></li>
    <li><a href="rewrite/vhosts.html">mod_rewrite ile devingen sanal konaklar</a></li>
    <li><a href="rewrite/proxy.html">mod_rewrite ile devingen vekil kullanımı</a></li>
    <li><a href="rewrite/rewritemap.html">RewriteMap kullanımı</a></li>
    <li><a href="rewrite/advanced.html">İleri seviye teknikler</a></li>
    <li><a href="rewrite/avoid.html">mod_rewrite ne zaman kullanılMAZ</a></li>
    <li><a href="rewrite/flags.html">RewriteRule Seçenekleri</a></li>
    <li><a href="rewrite/tech.html">Teknik Ayrıntılar</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">Apache SSL/TLS Şifrelemesi</a></h2>
    <ul><li class="separate"><a href="ssl/">Genel Bakış</a></li>
    <li><a href="ssl/ssl_intro.html">SSL/TLS Şifrelemesi: Giriş</a></li>
    <li><a href="ssl/ssl_compat.html">SSL/TLS Şifrelemesi: Uyumluluk</a></li>
    <li><a href="ssl/ssl_howto.html">SSL/TLS Şifrelemesi: Nasıl</a></li>
    <li><a href="ssl/ssl_faq.html">SSL/TLS Şifrelemesi: SSS</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">Kılavuzlar, Öğreticiler ve Nasıllar</a></h2>
    <ul><li class="separate"><a href="howto/">Genel Bakış</a></li>
    <li><a href="howto/auth.html">Kimlik Doğrulama ve Yetkilendirme</a></li>
    <li><a href="howto/access.html">Erişim Denetimi</a></li>
    <li><a href="howto/cgi.html">CGI ile Devingen İçerik</a></li>
    <li><a href="howto/ssi.html">Sunucu Taraflı İçerik Yerleştirme (SSI)</a></li>
    <li><a href="howto/htaccess.html">.htaccess Dosyaları</a></li>
    <li><a href="howto/public_html.html">Kullanıcı Dizinleri (public_html)</a></li>
    <li><a href="howto/reverse_proxy.html">Ters Vekil Yapılandırma Rehberi</a></li>
    <li><a href="howto/http2.html">HTTP/2 rehberi</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">Platformlara Özgü Bilgiler</a></h2>
    <ul><li class="separate"><a href="platform/">Genel Bakış</a></li>
    <li><a href="platform/windows.html">Microsoft
    Windows ile Apache Kullanımı</a></li>
    <li><a href="platform/win_compiling.html">Microsoft Windows için Apache Derleme</a></li>
    <li><a href="platform/rpm.html">RPM Temelli Sistemlerde Apache Kullanımı</a></li>
    <li><a href="platform/netware.html">Novell NetWare ile Apache Kullanımı</a></li>
    <li><a href="platform/perf-hp.html">HPUX üzerinde Yüksek Başarımlı HTTP Sunucusu Çalıştırma</a></li>
    <li><a href="platform/ebcdic.html">Apache EBCDIC Portu</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">Apache HTTP Sunucusu  ve Desteklenen Programlar</a></h2>
    <ul><li class="separate"><a href="programs/">Genel Bakış</a></li>
    <li><a href="programs/httpd.html">Kılavuz Sayfası: httpd</a></li>
    <li><a href="programs/ab.html">Kılavuz Sayfası: ab</a></li>
    <li><a href="programs/apachectl.html">Kılavuz Sayfası: apachectl</a></li>
    <li><a href="programs/apxs.html">Kılavuz Sayfası: apxs</a></li>
    <li><a href="programs/configure.html">Kılavuz Sayfası: configure</a></li>
    <li><a href="programs/dbmmanage.html">Kılavuz Sayfası: dbmmanage</a></li>
    <li><a href="programs/fcgistarter.html">Kılavuz Sayfası: fcgistarter</a></li>
    <li><a href="programs/htcacheclean.html">Kılavuz Sayfası: htcacheclean</a></li>
    <li><a href="programs/htdbm.html">Kılavuz Sayfası: htdbm</a></li>
    <li><a href="programs/htdigest.html">Kılavuz Sayfası: htdigest</a></li>
    <li><a href="programs/htpasswd.html">Kılavuz Sayfası: htpasswd</a></li>
    <li><a href="programs/httxt2dbm.html">Kılavuz Sayfası: httxt2dbm</a></li>
    <li><a href="programs/logresolve.html">Kılavuz Sayfası: logresolve</a></li>
    <li><a href="programs/log_server_status.html">Kılavuz Sayfası: log_server_status</a></li>
    <li><a href="programs/rotatelogs.html">Kılavuz Sayfası: rotatelogs</a></li>
    <li><a href="programs/split-logfile.html">Kılavuz Sayfası: split-logfile</a></li>
    <li><a href="programs/suexec.html">Kılavuz Sayfası: suexec</a></li>
    <li><a href="programs/other.html">Diğer Programlar</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Çeşitli Belgeler</a></h2>
    <ul><li class="separate"><a href="misc/">Genel Bakış</a></li>
    <li><a href="misc/perf-tuning.html">Başarım Arttırma İpuçları</a></li>
    <li><a href="misc/security_tips.html">Güvenlik İpuçları</a></li>
    <li><a href="misc/relevant_standards.html">İlgili Standartlar</a></li>
    <li><a href="misc/password_encryptions.html">Parola Şifreleme Çeşitleri</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">Apache Modülleri</a></h2>
    <ul><li><a href="mod/module-dict.html">Apache modüllerini tanımlamakta kullanılan terimlerin açıklamaları</a></li>
    <li><a href="mod/directive-dict.html">Apache yönergelerini tanımlamakta kullanılan terimlerin açıklamaları</a></li>
    </ul><ul><li><a href="mod/core.html">Apache Temel Özellikleri</a></li>
    <li><a href="mod/mpm_common.html">Apache MPM Ortak Yönergeleri</a></li>
    <li><a href="mod/event.html">Apache MPM event</a></li>
    <li><a href="mod/mpm_netware.html">Apache MPM netware</a></li>
    <li><a href="mod/mpmt_os2.html">Apache MPM os2</a></li>
    <li><a href="mod/prefork.html">Apache MPM prefork</a></li>
    <li><a href="mod/mpm_winnt.html">Apache MPM winnt</a></li>
    <li><a href="mod/worker.html">Apache MPM worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">Apache Modülü mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">Apache Modülü mod_actions</a></li>
    <li><a href="mod/mod_alias.html">Apache Modülü mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">Apache Modülü mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">Apache Modülü mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">Apache Modülü mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">Apache Modülü mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">Apache Modülü mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">Apache Modülü mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">Apache Modülü mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">Apache Modülü mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">Apache Modülü mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">Apache Modülü mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">Apache Modülü mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">Apache Modülü mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">Apache Modülü mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">Apache Modülü mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">Apache Modülü mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">Apache Modülü mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">Apache Modülü mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">Apache Modülü mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">Apache Modülü mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">Apache Modülü mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">Apache Modülü mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">Apache Modülü mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">Apache Modülü mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">Apache Modülü mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">Apache Modülü mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">Apache Modülü mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">Apache Modülü mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">Apache Modülü mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">Apache Modülü mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">Apache Modülü mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">Apache Modülü mod_data</a></li>
    <li><a href="mod/mod_dav.html">Apache Modülü mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">Apache Modülü mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">Apache Modülü mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">Apache Modülü mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">Apache Modülü mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">Apache Modülü mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">Apache Modülü mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">Apache Modülü mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">Apache Modülü mod_echo</a></li>
    <li><a href="mod/mod_env.html">Apache Modülü mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">Apache Modülü mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">Apache Modülü mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">Apache Modülü mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">Apache Modülü mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">Apache Modülü mod_filter</a></li>
    <li><a href="mod/mod_headers.html">Apache Modülü mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">Apache Modülü mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">Apache Modülü mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">Apache Modülü mod_http2</a></li>
    <li><a href="mod/mod_ident.html">Apache Modülü mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">Apache Modülü mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">Apache Modülü mod_include</a></li>
    <li><a href="mod/mod_info.html">Apache Modülü mod_info</a></li>
    <li><a href="mod/mod_isapi.html">Apache Modülü mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">Apache Modülü mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">Apache Modülü mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">Apache Modülü mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">Apache Modülü mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">Apache Modülü mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">Apache Modülü mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">Apache Modülü mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">Apache Modülü mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">Apache Modülü mod_logio</a></li>
    <li><a href="mod/mod_lua.html">Apache Modülü mod_lua</a></li>
    <li><a href="mod/mod_macro.html">Apache Modülü mod_macro</a></li>
    <li><a href="mod/mod_md.html">Apache Modülü mod_md</a></li>
    <li><a href="mod/mod_mime.html">Apache Modülü mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">Apache Modülü mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">Apache Modülü mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">Apache Modülü mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">Apache Modülü mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">Apache Modülü mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">Apache Modülü mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">Apache Modülü mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">Apache Modülü mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">Apache Modülü mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">Apache Modülü mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">Apache Modülü mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">Apache Modülü mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">Apache Modülü mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">Apache Modülü mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">Apache Modülü mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">Apache Modülü mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">Apache Modülü mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">Apache Modülü mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">Apache Modülü mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">Apache Modülü mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">Apache Modülü mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">Apache Modülü mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">Apache Modülü mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">Apache Modülü mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">Apache Modülü mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">Apache Modülü mod_sed</a></li>
    <li><a href="mod/mod_session.html">Apache Modülü mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">Apache Modülü mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">Apache Modülü mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">Apache Modülü mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">Apache Modülü mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">Apache Modülü mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">Apache Modülü mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">Apache Modülü mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">Apache Modülü mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">Apache Modülü mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">Apache Modülü mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">Apache Modülü mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">Apache Modülü mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">Apache Modülü mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">Apache Modülü mod_ssl</a></li>
    <li><a href="mod/mod_status.html">Apache Modülü mod_status</a></li>
    <li><a href="mod/mod_substitute.html">Apache Modülü mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">Apache Modülü mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">Apache Modülü mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">Apache Modülü mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">Apache Modülü mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">Apache Modülü mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">Apache Modülü mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">Apache Modülü mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">Apache Modülü mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">Apache Modülü mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">Apache Modülü mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer">Geliştirici Belgeleri</a></h2>
    <ul><li class="separate"><a href="developer/">Genel Bakış</a></li>
    <li><a href="developer/API.html">Apache API Bilgileri</a></li>
    <li><a href="developer/new_api_2_4.html">Apache HTTPD 2.4'te API güncellemeleri</a></li>
    <li><a href="developer/modguide.html">Apache HTTPD 2.4 için Modül Geliştirme</a></li>
    <li><a href="developer/documenting.html">Apache HTTPD'nin Belgelendirilmesi</a></li>
    <li><a href="developer/hooks.html">Apache 2.x Kullanıcı İşlevleri</a></li>
    <li><a href="developer/modules.html">Modüllerin 1.3’ten Apache 2.x’e Dönüştürülmesi</a></li>
    <li><a href="developer/request.html">2.x’de İsteklerin İşlenmesi</a></li>
    <li><a href="developer/filters.html">2.x’de Süzgeçler Nasıl Çalışır</a></li>
    <li><a href="developer/output-filters.html">2.x'de çıktı süzgeçleri için yol göstericiler</a></li>
    <li><a href="developer/thread_safety.html">2.x'de Çok Evrelilik Konuları</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index">Terimler ve Dizin</a></h2>
    <ul><li><a href="glossary.html">Terimler</a></li>
    <li><a href="mod/">Modül Dizini</a></li>
    <li><a href="mod/directives.html">Yönerge Dizini</a></li>
    <li><a href="mod/quickreference.html">Hızlı Yönerge Kılavuzu</a></li>
    <li><a href="mod/overrides.html">.htaccess için Geçersizleştirme Sınıfları</a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/stopping.html.ja.utf8������������������������������������������������������0000664�0001751�0001751�00000047754�14743132254�021064� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server の停止と再起動 - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Server の停止と再起動</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>この文書では Unix に類似したシステムでの
        Apache HTTP Serverの停止と再起動について扱っています。
        Windows NT, 2000, XP ユーザは<a href="platform/windows.html#winsvc">サービスとして
        httpd を実行する</a>で、Windows 9x, MEユーザは<a href="platform/windows.html#wincons">コンソールアプリケーションとして
        httpd を実行する</a>で、
        これらのプラットホームでの使用方法をご覧下さい。</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">イントロダクション</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#term">急な停止</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#graceful">緩やかな再起動</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#hup">急な再起動</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#gracefulstop">緩やかな停止</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="invoking.html">Starting</a></li><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">イントロダクション</a></h2>
    
        <p>Apache HTTP Server を停止したり再起動したりするためには、実行されている
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> プロセスにシグナルを送る必要があります。
        シグナルを送るには二つの方法があります。
        一つ目はプロセスに直接シグナルを送る unix の <code>kill</code>
        コマンドを使用する方法です。
        システムを見ればたくさんの <code class="program"><a href="./programs/httpd.html">httpd</a></code> が
        実行されているのに気が付くでしょうが、シグナルを送るのは
        親プロセスだけで、それ以外の個々のプロセスには
        シグナルを送らないで下さい。その親プロセスの pid は
        <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>
        に書かれています。これはつまり、親以外のプロセスに
        シグナルを送る必要すらない、ということです。
        親プロセスに送ることができる 4 種類のシグナルがあります:
        <code><a href="#term">TERM</a></code>,
        <code><a href="#hup">HUP</a></code>, 
        <code><a href="#graceful">USR1</a></code>,
        <code><a href="#gracefulstop">WINCH</a></code>
        です。これらの説明については続きをご覧下さい。</p>
    
        <p>親プロセスにシグナルを送るには、
        次のようなコマンドを発行して下さい:</p>
    
    <div class="example"><p><code>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</code></p></div>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code> プロセスにシグナルを送る 2 番目の方法は
        <code>-k</code> というコマンドライン引数を使用することです。
        下で説明されているように、<code>stop</code>, <code>restart</code>, 
        <code>graceful</code>, <code>graceful-stop</code> を指定できます。
        これらは <code class="program"><a href="./programs/httpd.html">httpd</a></code> の引数ですが、
        制御用のスクリプト <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> はそれらの引数をそのまま
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> に渡します。</p>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code> にシグナルを送った後、
        実行状況を次のコマンドで読むことができます:</p>
    
    <div class="example"><p><code>tail -f /usr/local/apache2/logs/error_log</code></p></div>
        <p>ここに挙げた例は、各自の
        <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code>
        と
        <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>
        の設定に適合するように適宜修正して下さい。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="term" id="term">急な停止</a></h2>
    
    <dl><dt>シグナル: TERM</dt>
    <dd><code>apachectl -k stop</code></dd>
    </dl>
    
        <p><code>TERM</code> あるいは <code>stop</code> 
        シグナルを親プロセスに送ると、即座に子プロセス全てを kill しようとします。
        子プロセスを完全に kill し終わるまでに数秒かかるかもしれません。
        その後、親プロセス自身が終了します。
        処理中のリクエストは全て停止され、もはやリクエストに対する
        応答はされません。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="graceful" id="graceful">緩やかな再起動</a></h2>
    
    <dl><dt>シグナル: USR1</dt>
    <dd><code>apachectl -k graceful</code></dd>
    </dl>
    
        <p>親プロセスは <code>USR1</code> あるいは <code>graceful</code>
        シグナルを受け取ると、子プロセスに現在のリクエストの処理の後に終了する
        (あるいは何もしていなければすぐに終了する)
        ように<em>助言</em>します。
        親プロセスは設定ファイルを再読込して、ログファイルを開き直します。
        子プロセスが徐々になくなるに従って、
        新しい<em>世代</em>の設定による子プロセスに置き換えていきます。
        そして、これらが新たなリクエストに即座に応答し始めます。</p>
    
        <p>このコードは常に
        MPM のプロセス制御ディレクティブの設定を重視しますので、
        クライアントのリクエストを扱うプロセスとスレッドの数を再起動の処理中も
        適切な値に維持されます。。また、次のようにして
        <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code>
        を守ります:
        少なくとも 1 秒後に <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> 個の新しい子プロセスが
        生成されていなければ、その数になるように適宜プロセスを生成します。
        この挙動は現在の負荷に対して適切な子プロセスの数と
        <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> パラメータでの
        希望の数の両方を維持しようとしています。</p>
    
        <p><code class="module"><a href="./mod/mod_status.html">mod_status</a></code> を
        使用している場合は、<code>USR1</code> シグナルが送られた際に
        サーバ統計がゼロに<strong>設定されない</strong>ことに
        注意してください。
        サーバが新しいリクエストに応答不能な時間を最小にするように
        (リクエストは OS によってキューに追加されるので絶対に紛失はしません)、
        また同時に、希望のチューニングパラメータを守るように
        コードは書かれています。
        このようにするために、世代をまたがった全子プロセスの追跡に使われている
        <em>スコアボード</em>を維持しなければなりません。</p>
    
        <p>status モジュールは、緩やかな再起動以前から開始して
        リクエストに応答し続けている子プロセスを特定するために、
        <code>G</code> を使うこともします。</p>
    
        <p>現在、<code>USR1</code> を使うログ移動スクリプトでは、
        再起動前の子プロセスがログを書き終わったことを確証する方法が
        ありません。古いログに対して何かする前に、
        <code>USR1</code> シグナルを送った後いくらか適当な時間待つことを
        提案します。例えば、帯域の狭い通信路のユーザのリクエストのほとんどが 10 
        分以下で完了しているということが分かっていれば、
        古いログに何かする前に 15 分待つということです。</p>
    
        <div class="note"><p>再起動が発行されると設定ファイルの構文チェックがまず走り、
        設定ファイルに (構文上の) 誤りがないかチェックされます。
        誤りがあった場合エラーメッセージでその旨が示され、サーバは再起動されません。
        こうすることでサーバが終了しているけれども再起動できないという状況を
        防ぎ、サーバが機能不全な状態になるのを防いでいます。</p>
    
        <p>ただしこれでもサーバが正しく再起動することは保証されません。
        設定ファイルの意味的な内容を構文と同様に検証したい場合は、
        非 root ユーザで <code class="program"><a href="./programs/httpd.html">httpd</a></code> を起動しようとすればわかります。
        もしエラーがなければ、ソケットやログを開こうとして
        root でないため
        (もしくは実行中の <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        が既に必要なポートにバインドしているため)
        に失敗するでしょう。
        これ以外の理由で起動に失敗したのであれば、
        それは設定ファイルのエラーで、
        緩やかな再起動を行う前にその誤りを修正しなければなりません。</p>
        </div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hup" id="hup">急な再起動</a></h2>
    
    <dl><dt>シグナル: HUP</dt>
    <dd><code>apachectl -k restart</code></dd>
    </dl>
    
        <p><code>HUP</code> あるいは <code>restart</code> シグナルを親プロセスに送ると、
        <code>TERM</code> と同様に子プロセスを kill しますが、
        親プロセスは終了しません。
        設定ファイルを再読込して、ログファイル全てを開き直します。
        その後、新しい子プロセスを起動して応答を続けます。</p>
    
        <p><code class="module"><a href="./mod/mod_status.html">mod_status</a></code>
        を使っている場合は、<code>HUP</code> が送られた場合に
        サーバ統計がゼロに設定されることに注意してください。</p>
    
        <div class="note">graceful 再起動時は、再起動前に構文チェックが行われます。
        もし構文エラーがあればその旨が示され、再起動は行われません。</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gracefulstop" id="gracefulstop">緩やかな停止</a></h2>
    
    <dl><dt>Signal: WINCH</dt>
    <dd><code>apachectl -k graceful-stop</code></dd>
    </dl>
    
        <p><code>WINCH</code> や <code>graceful-stop</code> シグナルを受け取ると、
        親プロセスは子プロセスに現在処理中のリクエストの後に終了する
        (あるいは処理中のものが何もなければ直ちに終了する)
        ように<em>アドバイス</em>します。
        その後親プロセスは <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>
        を削除し、ポートでの Listen を全て停止します。
        親プロセスはどの子プロセスがリクエスト処理中かを監視し続けています。
        全ての子プロセスが終了するか
        <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code>
        で設定した時間が過ぎると、親プロセスも終了します。
        タイムアウトに達した場合、残りの子プロセスには <code>TERM</code>
        シグナルが送信され強制的に終了されます。</p>
        
        <p>"graceful" 状態の場合 <code>TERM</code> シグナルを受け取ると、
        親プロセスも子プロセスもすぐに終了します。しかしながら
        <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>
        が削除されてしまっているので、<code>apachectl</code>
        や <code>httpd</code> にこのシグナルを送ることはできません。</p>
    
        <div class="note"><p><code>graceful-stop</code> を使うとまったく同一に設定された
        複数の <code class="program"><a href="./programs/httpd.html">httpd</a></code> を同時に実行することができます。
        httpd を緩やかにアップグレードするのにはとても便利ですが、
        設定ファイルによってはデッドロックやレースコンディションを
        引き起こすこともあります。</p>
    
        <p>ディスク上のファイルを使うもの、たとえばロックファイル
        (<code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>) や Unix ソケットファイル
        (<code class="directive"><a href="./mod/mod_cgid.html#scriptsock">ScriptSock</a></code>) 
        などはサーバの PID を含めて管理されていて、
        共存できるよう注意が払われています。
        しかしその他設定ディレクティブやサードパーティ製のモジュール、
        CGI ユーティリティのパーシステント層などで
        ディスク上にロックファイルや状態管理ファイルを
        使っている場合は、実行されている複数の <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        が互いに衝突しないように気をつけなければなりません。</p>
    
        <p><code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> 形式のパイプを使ったログといった、
        その他潜在的なレースコンディションについても注意しなければなりません。
        複数の <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> が同じファイルを同時に
        rotate しようとすると、互いにログファイルを破壊してしまいます。</p>
        </div>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/stopping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������httpd-2.4.64/docs/manual/stopping.html.ko.euc-kr����������������������������������������������������0000664�0001751�0001751�00000035254�14743132254�021373� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>ߴܰ  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>ߴܰ </h1>
    <div class="toplang">
    <p><span> : </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>  н ýۿ ġ ߴϰ ϴ
         ִ.  NT, 2000, XP ڴ <a href="platform/windows.html#winsvc">񽺷 ġ
        ϱ</a>,  9x ME ڴ <a href="platform/windows.html#wincons">ݼ α׷
        ġ ϱ</a> ÷ ġ ۹   ִ.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Ұ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#term"> ߴ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#graceful"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#hup"> </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#race">η: ñ׳ΰ ̽ </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="programs/httpd.html">httpd</a></li><li><a href="programs/apachectl.html">apachectl</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Ұ</a></h2>
    
        <p>ġ ߴϰ Ϸ ϰ ִ
        <code>httpd</code> μ ñ׳  Ѵ. ñ׳
          ΰ. ϳ н <code>kill</code>
        ɾ Ͽ μ  ñ׳  ̴.
        ýۿ  <code>httpd</code> , <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> pid ϵ θܿ
        ٸ μ ñ׳(signal)  ȵȴ. , θ̿ܿ
        ٸ μ ñ׳  ʿ䰡 ٴ ̴. θ𿡰
          ִ ñ׳ ,   <code><a href="#term">TERM</a></code>, <code><a href="#hup">HUP</a></code>, <code><a href="#graceful">USR1</a></code>̴.</p>
    
        <p>  θ𿡰 ñ׳ :</p>
    
    <div class="example"><p><code>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</code></p></div>
    
        <p><code>httpd</code> μ ñ׳  ٸ 
         ɼ <code>-k</code> ϴ ̴. Ʒ 
        <code>stop</code>, <code>restart</code>, <code>graceful</code>
        <a href="programs/httpd.html">httpd</a>  ƱԸƮ̴.
        ׷  ƱԸƮ <code>httpd</code> ϴ, <a href="programs/apachectl.html">apachectl</a> ũƮ
        ϱ Ѵ.</p>
    
        <p><code>httpd</code> ñ׳ ,  ɾ
        Ȳ   ִ:</p>
    
    <div class="example"><p><code>tail -f /usr/local/apache2/logs/error_log</code></p></div>
    
        <p>   <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>  ˸° ϶.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="term" id="term"> ߴ</a></h2>
    
    <dl><dt>ñ׳: TERM</dt>
    <dd><code>apachectl -k stop</code></dd>
    </dl>
    
        <p><code>TERM</code>̳ <code>stop</code> ñ׳ θ𿡰
           ڽ δ. ڽ  ̴µ
         ʰ ɸ  ִ. ׷ θ Ѵ. ó û
        ߴܵǰ,  ̻ û ʴ´.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="graceful" id="graceful"> </a></h2>
    
    <dl><dt>ñ׳: USR1</dt>
    <dd><code>apachectl -k graceful</code></dd>
    </dl>
    
        <p><code>USR1</code>̳ <code>graceful</code> ñ׳
        θ𿡰  θ μ ڽĵ鿡  û
        ó ϶ (Ȥ  ƹ͵ ó ʴٸ
         ϶) <em>Ѵ</em>. θ 
        ٽа αϵ ٽ . ڽ  θ
         ڽĴ ο  <em></em>  ڽ
        Ͽ  û óϰ Ѵ.</p>
    
        <div class="note"> (graceful restart) <code>USR1</code>
           ÷  (<code>WINCH</code> )
        ٸ ñ׳   ִ. <code>apachectl graceful</code>
        ÷ ˸ ñ׳ .</div>
    
        <p>  ׻ MPM μ  þ 
        Ͽ, ۵ Ŭ̾Ʈ ϴ μ 尡
          ϵ Ǿ. Դٰ <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code>,  
        ּ StartServersŭ ο ڽ ȸ ڽ
        StartServers  ǵ  . , α׷ 
         Ͽ ˸ ڽ  ϸ,
        <code class="directive">StartServers</code> Ķͷ  
        븦 Ѵ.</p>
    
        <p><code class="module"><a href="./mod/mod_status.html">mod_status</a></code> ڴ <code>USR1</code>
          谡 0  <strong></strong> 
        ̴.  ο û (ü ̵ ť Ƽ
         쿡 Ҿ ʴ´) ó ϴ ð
        ּȭϰ  Ʃ Ķ͸ ϵ .
        ̸  밣  ڽ ϴ <em>scoreboard</em>
        Ѵ.</p>
    
        <p>status      Ͽ 
        û óϰ ִ ڽ <code>G</code> ˷ش.</p>
    
        <p>δ <code>USR1</code> ϴ α׼ȯ ũƮ
          ڽ αۼ ƴ   ִ
         . 츮 <code>USR1</code> ñ׳ 
         ð   α׸ ٷ絵 Ѵ. 
          뿪    κ ġµ 10
        Ȱɸٸ,  α׸ ٷ 15 ٸ.</p>
    
        <div class="note">Ͽ  ִٸ ۽ θ 
        ʰ   Ѵ. ,    Ҷ
        ڽ ǵ д. (ڽĵ ڽ  û
        óϰ "ݰ Ѵ".) ̴  Ҷ
         ȴ.  ڽ ٸ Ʈ  Ѵ.
         <code>-t</code>  ɼ(<a href="programs/httpd.html">httpd</a> ) 
         ˻  ִ. ׷ ̷ ˻絵  ùٷ
          Ѵ.   ƴ ǹ̸
        ˻Ϸ root ƴ ڷ <code>httpd</code> غ  ִ.
        root ƴϱ⶧ (ƴϸ   Ʈ ϴ
        <code>httpd</code> DZ⶧)  ٸ ϰ
        α  õϴ   ̴. ٸ
         Ѵٸ Ƹ Ͽ   ̴.
          ϱ  ľѴ.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hup" id="hup"> </a></h2>
    
    <dl><dt>ñ׳: HUP</dt>
    <dd><code>apachectl -k restart</code></dd>
    </dl>
    
        <p><code>HUP</code>̳ <code>restart</code> ñ׳
        θ𿡰  <code>TERM</code>   ڽ
         θ  ʴ´. θ  ٽа
        α ٽ . ׸ ο ڽĵ  񽺸
        Ѵ.</p>
    
        <p><code class="module"><a href="./mod/mod_status.html">mod_status</a></code> ڴ <code>HUP</code>
          谡 0    ִ.</p>
    
    <div class="note">Ͽ  ִٸ  ص θ 
    ʰ    ̴. ̸ ϴ   ϶.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="race" id="race">η: ñ׳ΰ ̽ </a></h2>
    
        <p>Apache 1.2b9  ۰  ñ׳ο 
        <em>̽ (race condition)</em> ־. (̽
          ڸ,   ߸ȶ Ͼ
        Ѵ  ʴ ð ΰ .) "ùٸ"
         ִ ŰĿ 츮 ̷  ִ ذߴ.
        ׷  ŰĿ  ̽  
        ϶.</p>
    
        <p><code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code>
        ũ ϴ ŰĴ scoreboard Ʈ ɼ
        ִ. ׷ (<code>HUP</code>) "bind: Address already in use"
        Ȥ (<code>USR1</code> ) "long lost child came home!"
        ߻  ִ. ڴ ɰ ̰, ڴ  
        scoreboard slot Ұ . ׷   ̰
          ϱ õѴ.   ذϱ ſ
        . ׷  κ ŰĴ scoreboard 
         ʴ´.  ϴ ŰĶ <code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code>  ϶.</p>
    
        <p> ŰĿ ӵǴ HTTP  (KeepAlive)
        ι°  û óϴ ڽĿ ణ ̽ 
        ִ. ڽ û   û  б  
        ִ.   ʹ ʰ ߰Ͽ 1.2  Ŀ
        Ǿ. ׷ Ʈ ̳  ðѶ KeepAlive
        Ŭ̾Ʈ ̷ 츦 ؾϱ  ̷л 
        ȵȴ.   ˻ϱ ʿ 20 ϴ 
        Ŭ̾Ʈ  ׸̳   Ʈ 
        о̱  ʴ´ٸ  ȵȴ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/stopping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/stopping.html.tr.utf8������������������������������������������������������0000664�0001751�0001751�00000047067�14743132254�021114� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Sunucusunun Durdurulması ve Yeniden Başlatılması - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Sunucusunun Durdurulması ve Yeniden Başlatılması</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu belge Apache HTTP Sunucusunun Unix benzeri sistemlerde durdurulması
          ve yeniden başlatılması konularını kapsar. Windows NT, 2000 ve XP
          kullanıcıları Apache HTTPd’yi bu platformlarda nasıl denetimlerine
          alacaklarını öğrenmek için <a href="platform/windows.html#winsvc">httpd’nin Bir Hizmet Olarak Çalıştırılması</a> sayfasına, Windows 9x ve
          ME kullanıcıları ise <a href="platform/windows.html#wincons">httpd’nin
          Bir Konsol Uygulaması Olarak Çalıştırılması</a> sayfasına
          bakabilirler.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Giriş</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#term">Hemen Durdur</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#graceful">Nazikçe Yeniden Başlat</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#hup">Hemen Yeniden Başlat</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#gracefulstop">Nazikçe Durdur</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="invoking.html">Başlatma</a></li><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Giriş</a></h2>
    
        <p>Apache HTTP Sunucusunu durdurmak ve yeniden başlatmak için çalışan
          <code class="program"><a href="./programs/httpd.html">httpd</a></code> süreçlerine bir sinyal göndermeniz gerekir.
          Sinyal göndermek için iki yol vardır. İlki, süreçlere doğrudan sinyal
          göndermek için unix <code>kill</code> komutunun kullanımıdır. Bu
          suretle, sisteminizde çalışmakta olan bir çok <code class="program"><a href="./programs/httpd.html">httpd</a></code>
          sürecini uyarabilirsiniz ama süreç kimliği <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> yönergesi ile belirtilen dosyada
          tutulan ana süreç dışında hiçbirine sinyal göndermemelisiniz. Başka
          bir deyişle, ana süreç haricinde hiçbir sürece sinyal göndermeye normal
          olarak ihtiyacınız olmaması gerekir. Ana sürece gönderebileceğiniz
          dört çeşit sinyal vardır:
          <code><a href="#term">TERM</a></code>,
          <code><a href="#graceful">USR1</a></code>,
          <code><a href="#hup">HUP</a></code> ve
          <code><a href="#gracefulstop">WINCH</a></code>. Bunlar yeri geldikçe
          açıklanacaktır.</p>
    
        <p>Ana sürece <code>kill</code> ile sinyal göndermek için şöyle bir
          komut verebilirsiniz:</p>
    
        <div class="example"><p><code>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</code></p></div>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code> süreçlerine sinyal göndermenin ikinci yolu
          <code>-k</code> komut satırı seçeneğini şu değerlerden biri ile
          kullanmaktır: <code>stop</code>, <code>restart</code>,
          <code>graceful</code> ve <code>graceful-stop</code>. Bunlar aşağıda
          açıklanacaktır. <code>-k</code> komut satırı seçeneği
          <code class="program"><a href="./programs/httpd.html">httpd</a></code>’ye ait olsa da ana sürece bu sinyalleri
          göndermek için <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> betiğini kullanmanızı
          öneririz. <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>, komut satırı seçeneklerini
          <code class="program"><a href="./programs/httpd.html">httpd</a></code>’ye aktaracaktır.</p>
    
        <p><code class="program"><a href="./programs/httpd.html">httpd</a></code>’ye sinyal gönderdikten sonra olup biteni şu
          komutla izleyebilirsiniz:</p>
    
        <div class="example"><p><code>tail -f /usr/local/apache2/logs/error_log</code></p></div>
    
        <p>Bu örnekleri, kendi <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> ve
          <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> yönergelerinizdeki
          ayarlara uygun olarak değiştirdikten sonra kullanınız.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="term" id="term">Hemen Durdur</a></h2>
    
      <dl><dt>Sinyal: TERM</dt>
        <dd><code>apachectl -k stop</code></dd>
      </dl>
    
        <p>Ana sürece <code>TERM</code> veya <code>stop</code> sinyali
          göndererek tüm çocukların bir an önce öldürülmeye çalışılmasını sağlamış
          olursunuz. Tüm çocukların öldürülmesi bir kaç saniye sürebilir. Son
          olarak ana süreç çıkacaktır. Yanıtlanmakta olan istekler hemen
          sonlandırılacak ve artık isteklere yanıt verilmeyecektir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="graceful" id="graceful">Nazikçe Yeniden Başlat</a></h2>
    
      <dl><dt>Sinyal: USR1</dt>
        <dd><code>apachectl -k graceful</code></dd>
      </dl>
    
        <p>Ana sürece <code>USR1</code> veya <code>graceful</code> sinyalinin
          gönderilmesi, çocuklara ellerindeki mevcut işleri bitirdikten sonra
          (veya sundukları bir şey yoksa hemen) çıkmalarının <em>önerilmesi</em>
          demektir. Ana süreç kendi yapılandırma dosyalarını yeniden okur ve
          kendi günlük dosyalarını yeniden açar. Ana sürecin öldürdüğü her sürecin
          yerine yeni yapılandırma <em>kuşağından</em> bir süreç başlatır ve hemen
          yeni isteklere hizmet sunulmaya başlanır.</p>
    
        <p>Bu kod MPM’lerin süreçleri denetleyen yönergelerine daima uyacak
          şekilde tasarlanmıştır. Bu suretle, istemcilere hizmet sunacak çocuk
          süreçler ve evreler, yeniden başlatma işleminde de uygun sayıda
          sağlanmış olur. Bununla birlikte, <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> yönergesinde şöyle
          davranılır: İlk saniye içinde en azından <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> sayıda yeni çocuk
          oluşturulmamışsa iş olmayan bir devreyi geçiştirecek kadarı oluşturulur.
          Ardından sunucunun mevcut yükünü karşılamak için gereken sayıda çocuk
          süreç oluşturulur. Bu suretle, kod her ikisi için de gereğini yerine
          getirmeye çalışmış olur.</p>
    
        <p><code class="module"><a href="./mod/mod_status.html">mod_status</a></code> kullanıcıları <code>USR1</code>
          gönderildiği zaman sunucu istatistiklerinin sıfırlanmadığı konusunda
          uyarılacaktır. Kod, sunucunun yeni isteklere yanıt veremediği zamanı en
          aza indirmenin yanısıra ayar parametrelerinize de uymak üzere
          tasarlanmıştır (yeni istekler işletim sistemi tarafından kuyruğa
          alınacağından bir istek kaybı olayı yaşanmaz). Bunu sağlamak için, her
          iki kuşağın çocuklarının izini sürecek bir <em>çetele</em> tutulur.</p>
    
        <p><code class="module"><a href="./mod/mod_status.html">mod_status</a></code> modülü, nazikçe yeniden başlat komutunun
          verilmesinden önce başlamış ve sunulmaya devam eden isteklere bakan
          çocukları imlemek için ayrıca bir <code>G</code> (Graceful’un baş harfi)
          kullanır.</p>
    
        <p>Günlük dosyası döndürme betiğine, yeniden başlatma öncesi günlüğe yazan
          tüm çocukların işini bitirdiğini <code>USR1</code> kullanarak
          bildirmenin bir yolu yoktur.  Önerimiz, eski günlük kaydı üzerinde bir
          işlem yapmaya başlamadan önce <code>USR1</code> sinyali gönderilmesinin
          ardından belli bir süre beklenilmesi olacaktır. Örneğin, düşük band
          genişliğine sahip istemcilere hizmet sunan çoğu sürecin işinin 10
          dakikadan önce bitmeyeceğini gözönüne alarak eski günlük üzerinde işlem
          yapmaya başlamak için 15 dakika beklenebilir.</p>
    
        <div class="note">
        <p>Bir yeniden başlatma isteğinde, yapılandırma dosyalarında bir hata
          olmadığından emin olmak için önce bir sözdizimi denetimi yapılır. Eğer
          yapılandırma dosyalarınızda bir hata varsa bu sözdizimi hatasıyla ilgili
          bir hata iletisi alırsınız ve sunucu yeniden başlamayı reddeder. Bu
          yolla, bir hata sonucu sunucunun çökerek yeniden başlamaması nedeniyle
          işlevsiz bir sunucuyla başbaşa kalmanız önlenmiştir.</p>
    
        <p>Ancak, bu hala sunucunuzun düzgünce yeniden başlatılmasını garanti
          etmeyecektir. Yapılandırma dosyalarınızı sözdizimi denetiminin yanında
          anlamlandırılması bakımından da sınamak için
          <code class="program"><a href="./programs/httpd.html">httpd</a></code>’nin root olmayan bir kullanıcı tarafından
          çalıştırılmasını deneyebilirsiniz. Eğer yapılandırma dosyalarında bir
          hata yoksa soketleri ve günlük dosyalarını açmaya çalışırken root
          aidiyetinde çalışmadığından veya çalışmakta olan asıl sunucu bu portları
          zaten dinlediğinden başarısız olacaktır. Eğer başka bir sebeple
          başarısız olursa olası sebep bir yapılandırma dosyası hatasıdır ve asıl
          sunucuya ‘nazikçe yeniden başla’ komutunu vermeden önce bu hatayı
          düzeltmeniz gerekir.</p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hup" id="hup">Hemen Yeniden Başlat</a></h2>
    
      <dl><dt>Sinyal: HUP</dt>
        <dd><code>apachectl -k restart</code></dd>
      </dl>
    
        <p>Ana sürece <code>HUP</code> veya <code>restart</code> sinyalinin
          gönderilmesi tüm çocukların <code>TERM</code> sinyali gönderilmiş gibi
          öldürülmesine sebep olur fakat ana sürecin çıkmasını sağlamaz.
          Ana süreç yapılandırma dosyalarını yeniden okur ve günlük kayıt
          dosyalarını yeniden açar. Bunların ardından isteklere yanıt verecek yeni
          kuşak çocukları oluşturmaya başlar.</p>
    
        <p><code class="module"><a href="./mod/mod_status.html">mod_status</a></code> kullanıcıları bir <code>HUP</code> sinyalı
          gönderildiğinde sunucu istatistiklerinin sıfırlandığı konusunda
          uyarılırlar.</p>
    
        <div class="note">‘Nazikçe yeniden başlat’ komutundaki gibi yeniden başlatma öncesi
          bir sözdizimi denetimi yapılır. Eğer yapılandırma dosyalarınızda
          sözdizimi hatası varsa yeniden başlatma işlemi gerçekleşmez ve sözdizimi
          hatalarıyla ilgili bildirim alırsınız.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gracefulstop" id="gracefulstop">Nazikçe Durdur</a></h2>
    
      <dl><dt>Sinyal: WINCH</dt>
        <dd><code>apachectl -k graceful-stop</code></dd>
      </dl>
    
        <p>Ana sürecin <code>WINCH</code> veya <code>graceful-stop</code>
          sinyalini alması, çocuklara ellerindeki mevcut işleri bitirdikten sonra
          (veya sundukları bir şey yoksa hemen) çıkmalarının <em>önerilmesine</em>
          sebep olur. Ana süreç bunun hemen ardından <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> dosyasını siler ve port
          dinlemeyi keser. Ana süreç  çalışmaya ve isteklere yanıt vermekte olan
          çocuk süreçleri izlemeye devam eder. Tüm çocuklar işlerini bitirip
          çıktığında veya <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code> ile belirtilen
          zaman aşımı dolduğunda ana süreç de kendini sonlandırır. Eğer zaman aşımı
          devreye girmişse o an çalışmakta olan çocuk süreçlere <code>TERM</code>
          sinyali gönderilerek hemen çıkmaları sağlanır.</p>
    
        <p>Bir <code>TERM</code> sinyali ile "graceful" durumundaki tüm çocuklar
          ve ana süreç hemen sonlandırılacaktır. Bununla birlikte, <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> dosyası da silineceğinden, artık
          <code>apachectl</code> veya <code>httpd</code>’yi bu sinyali göndermek
          için kullanamayacaksınız.</p>
    
        <div class="note"><p><code>graceful-stop</code> sinyali, aynı anda, aynı yapılandırma
          ile çok sayıda <code class="program"><a href="./programs/httpd.html">httpd</a></code> kopyasının çalıştırılabilmesine
          imkan verir.  Bu, Apache nazikçe yükseltileceği zaman güçlü bir özellik
          haline gelmekteyse de, bazı yapılandırmalarda yarış koşullarının
          oluşmasına ve kısır çekişmelere (deadlock) sebep olabilir.</p>
    
        <p>Sunucunun süreç kimliğini içeren kilit dosyaları (<code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>) ve Unix soket dosyaları
          (<code class="directive"><a href="./mod/mod_cgid.html#scriptsock">ScriptSock</a></code>) gibi dosyaların
          disk üzerindeki mevcudiyetlerinin sorunsuz olarak devam ettiğinden emin
          olunmaya çalışılmalıdır.  Ayrıca, bir yapılandırma yönergesi, üçüncü
          parti bir modül veya kalıcı CGI uygulamalarına ait disk kilit veya durum
          dosyaları olabilir; <code class="program"><a href="./programs/httpd.html">httpd</a></code>’nin birden fazla kopyasının
          çalışması nedeniyle bu dosyaların da üzerine yazılmadığından emin
          olunmaya çalışılmalıdır.</p>
    
        <p><code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> tarzı borulu günlükleme kullanımı gibi
          durumlarda yarış koşullarının oluşması olasılığına karşı uyanık
          olunmalıdır. Aynı günlük kayıt dosyalarını aynı anda döndürmeye çalışan
          birden fazla <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> kopyasının çalıştırılması
          halinde bunların her biri diğerlerinin günlük kayıt dosyalarının kaybına
          sebep olabilir.</p></div>
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/stopping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/suexec.html.tr.utf8��������������������������������������������������������0000664�0001751�0001751�00000076066�14743132254�020546� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>SuEXEC Desteği - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>SuEXEC Desteği</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p><strong>SuEXEC</strong> özelliği, Apache HTTP Sunucusu kullanıcılarına
          <strong>CGI</strong> ve <strong>SSI</strong> programlarını sunucunun
          aidiyetinde çalıştığı kullanıcıdan farklı bir kullanıcının aidiyetinde
          çalıştırma olanağı verir. Normalde, <strong>CGI</strong> ve
          <strong>SSI</strong> programlarını çalıştıranla sunucuyu çalıştıran
          aynı kullanıcıdır.</p>
    
        <p>Gerektiği gibi kullanıldığında bu özellik, kullanıcılara
          <strong>CGI</strong> ve <strong>SSI</strong> programlarını çalıştırma
          ve geliştirmeye izin vermekle ortaya çıkan güvenlik risklerini azaltır.
          Bununla birlikte, <strong>suEXEC</strong> gerektiği gibi
          yapılandırılmadığı takdirde bazı sorunlara yol açabilir ve bilgisayar
          güvenliğinizde yeni delikler ortaya çıkmasına sebep olabilir.
          Güvenlikle ilgili mevcut sorunlarla başa çıkmada ve <em>setuid
          root</em> programları yönetmekte bilgi ve deneyim sahibi değilseniz
          <strong>suEXEC</strong> kullanmayı kesinlikle düşünmemenizi
          öneririz.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#before">Başlamadan önce</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#model">SuEXEC Güvenlik Modeli</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">suEXEC’in Yapılandırılması ve Kurulumu</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#enable">suEXEC’in etkin kılınması ve iptal edilmesi</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">SuEXEC’in kullanımı</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#debug">SuEXEC ve hata ayıklama</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#jabberwock">Uyarılar ve Örnekler</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="before" id="before">Başlamadan önce</a></h2>
    
        <p>Belgeye balıklama dalmadan önce, suexec'i kullanacağınız ortam ve
          kendiniz hakkında yapılmış çeşitli kabuller hakkında bilgi sahibi
          olmalısınız.</p>
    
        <p>Öncelikle, üzerinde <strong>setuid</strong> va <strong>setgid</strong>
          işlemlerinin yapılabildiği Unix türevi bir işletim sistemi
          kullandığınızı varsayıyoruz. Tüm komut örnekleri buna dayanarak
          verilmiştir. Bu desteğe sahip başka platformlar varsa onlardaki
          yapılandırma burada anlattığımız yapılandırmadan farklı olabilir.</p>
    
        <p>İkinci olarak, bilgisayarınızın güvenliği ve yönetimi ile ilgili bazı
          temel kavramları bildiğinizi kabul ediyoruz. Buna
          <strong>setuid/setgid</strong> işlemlerinin sisteminiz ve güvenlik
          seviyesi üzerindeki etkilerini bilmek dahildir.</p>
    
        <p>Üçüncü olarak, <strong>suEXEC</strong> kodunun
          <strong>değiştirilmemiş</strong> bir sürümünü kullandığınızı
          varsayıyoruz. Tüm suEXEC kodu, geliştiricilerin yanında sayısız beta
          kullanıcısı tarafından dikkatle incelenmiş ve denenmiştir. Kodların hem
          basit hem de sağlam bir şekilde güvenli olması için gerekli tüm
          önlemler alınmıştır. Bu kodun değiştirilmesi beklenmedik sorunlara ve
          yeni güvenlik risklerine yol açabilir. Özellikle güvenlikle ilgili
          programlarda deneyimli değilseniz suEXEC kodunda kesinlikle bir
          değişiklik yapmamalısınız. Değişiklik yaparsanız kodlarınızı gözden
          geçirmek ve tartışmak üzere Apache HTTP Sunucusu geliştirme ekibi ile
          paylaşmanızı öneririz.</p>
    
        <p>Dördüncü ve son olarak, Apache HTTP Sunucusu geliştirme ekibinin
          suEXEC’i öntanımlı httpd kurulumunun bir parçası yapmama kararından
          bahsetmek gerekir. Bunun sonucu olarak, suEXEC yapılandırması sistem
          yöneticisinin ayrıntılı bir incelemesini gerektirir. Gerekli incelemeden
          sonra yönetici tarafından suEXEC yapılandırma seçeneklerine karar
          verilip, normal yollardan sisteme kurulumu yapılır. Bu seçeneklerin
          belirlenmesi, suEXEC işlevselliğinin kullanımı sırasında sistem
          güvenliğini gerektiği gibi sağlamak için yönetici tarafından dikkatle
          saptanmayı gerektirir. Bu sürecin ayrıntılarının yöneticiye bırakılma
          sebebi, suEXEC kurulumunu, suEXEC’i dikkatle kullanacak yeterliliğe sahip
          olanlarla sınırlama  beklentimizdir.</p>
    
        <p>Hala bizimle misiniz? Evet mi? Pekala, o halde devam!</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="model" id="model">SuEXEC Güvenlik Modeli</a></h2>
    
        <p>SuEXEC yapılandırması ve kurulumuna girişmeden önce biraz da
          gerçekleşmesini istediğiniz güvenlik modelinin ayrıntıları üzerinde
          duralım. Böylece, suEXEC’in içinde olup bitenleri ve sisteminizin
          güvenliği için alınacak önlemleri daha iyi anlayabilirsiniz.</p>
    
        <p><strong>suEXEC</strong> işlevselliği, Apache HTTP Sunucusu tarafından
          gerektiği takdirde artalanda çalıştırılan bir setuid programa dayanır.
          Bu program, bir CGI veya SSI betiğine bir HTTP isteği yapıldığı zaman,
          bu betiği, yöneticinin ana sunucunun aidiyetinde çalıştığı kullanıcıdan
          farklı olarak seçtiği bir kullanıcının aidiyetinde çalıştırmak için
          çağrılır. Böyle bir istek geldiğinde, Apache httpd artalandaki setuid
          programına, HTTP isteği yapılan programın ismiyle beraber aidiyetinde
          çalışacağı kullanıcı ve grup kimliklerini de aktarır.</p>
    
        <p>Artalanda çalıştırılan setuid program başarıyı ve başarısızlığı
          aşağıdaki süreci izleyerek saptar. Bunlardan herhangi biri başarısız
          olursa program başarısızlık durumunu günlüğe kaydeder ve bir hata
          vererek çıkar. Aksi takdirde çalışmaya devam eder.</p>
    
        <ol>
          <li>
            <strong>Setuid programı çalıştıran kullanıcı sistemin geçerli
            kullanıcılarından biri mi?</strong>
    
            <p class="indent">Bu, setuid programı çalıştıran kullanıcının
            sistemin gerçek bir kullanıcısı olduğunudan emin olunmasını sağlar.
            </p>
         </li>
    
         <li>
            <strong>Setuid program yeterli sayıda argümanla çağrılmış mı?
            </strong>
    
            <p class="indent">Apache HTTP Sunucusunun artalanda çağırdığı
              setuid program ancak yeterli sayıda argüman sağlandığı takdirde
              çalışacaktır. Argümanların sayısını ve sırasını Apache HTTP sunucusu
              bilir. Eğer setuid program yeterli sayıda argümanla çağrılmamışsa
              ya kendisinde bir değişiklik yapılmıştır ya da kurulu Apache httpd
              çalıştırılabilirinin suEXEC ile ilgili kısmında yanlış giden bir
              şeyler vardır.</p>
          </li>
    
          <li>
            <strong>Bu geçerli kullanıcının bu setuid programı çalıştırma
              yetkisi var mı?</strong>
    
            <p class="indent">Sadece tek bir kullanıcı (Apache’nin aidiyetinde
              çalıştığı kullanıcı) bu programı çalıştırmaya yetkilidir.</p>
          </li>
    
          <li>
            <strong>Hedef CGI veya SSI programı hiyerarşik olarak güvenliği
              bozacak bir dosya yolu üzerinde mi?</strong>
    
            <p class="indent">Hedef CGI veya SSI programının dosya yolu '/' veya
              '..' ile başlıyor  mu? Buna izin verilmez. Hedef CGI veya SSI
              programı suEXEC’in belge kök dizininde yer almalıdır (aşağıda
              <code>--with-suexec-docroot=<em>DİZİN</em></code> seçeneğine
              bakınız).</p>
          </li>
    
          <li>
            <strong>Hedef kullanıcı ismi geçerli mi?</strong>
    
            <p class="indent">Hedef kullanıcı mevcut mu?</p>
          </li>
    
          <li>
            <strong>Hedef grup ismi geçerli mi?</strong>
    
            <p class="indent">Hedef grup mevcut mu?</p>
          </li>
    
          <li>
            <strong>Hedef kullanıcı <code>root</code> değil, değil mi?</strong>
    
            <p class="indent">Mevcut durumda, <code>root</code> kullanıcısının
              CGI/SSI programlarını çalıştırmasına izin verilmemektedir.</p>
          </li>
    
          <li>
            <strong>Hedef kullanıcı kimliği asgari kullanıcı numarasından
              <em>BÜYÜK</em> mü?</strong>
    
            <p class="indent">Asgari kullanıcı numarası yapılandırma sırasında
              belirtilir. Böylece CGI/SSI programlarını çalıştırmasına izin
              verilecek olası en düşük kullanıcı numarasını belirlemeniz mümkün
              kılınmıştır. Bu bazı “sistem” hesaplarını devreden çıkarmak için
              yararlıdır.</p>
          </li>
    
          <li>
            <strong>Hedef grup <code>root</code>  değil, değil mi?</strong>
    
            <p class="indent"><code>root</code> grubunun CGI/SSI
              programlarını çalıştırmasına izin verilmemektedir.</p>
          </li>
    
          <li>
            <strong>Hedef grup numarası asgari grup numarasından
              <em>BÜYÜK</em> mü?</strong>
    
            <p class="indent">Asgari grup numarası yapılandırma sırasında
              belirtilir. Böylece CGI/SSI programlarını çalıştırmasına izin
              verilecek olası en düşük grup numarasını belirlemeniz mümkün
              kılınmıştır. Bu bazı “sistem” hesaplarını devreden çıkarmak için
              yararlıdır.</p>
          </li>
    
          <li>
            <strong>Apache’nin artalanda çağırdığı setuid program hedef
              kullanıcı ve grubun aidiyetine geçebildi mi?</strong>
    
            <p class="indent">Bu noktadan itibaren program setuid ve setgid
              çağrıları üzerinden hedef kullanıcı ve grubun aidiyetine geçer.
              Erişim grubu listesi de ayrıca kullanıcının üyesi olduğu tüm
              gruplara genişletilir.</p>
          </li>
    
          <li>
            <strong>Hedef CGI/SSI programının bulunduğu dizine geçebildik mi?
            </strong>
    
            <p class="indent">Dizin mevcut değilse dosyaları da içeremez. Hedef
              dizine geçemiyorsak bu, dizin mevcut olmadığından olabilir.</p>
          </li>
    
          <li>
            <strong>Hedef dizin Apache için izin verilen yerlerden biri mi?
            </strong>
    
            <p class="indent">İstek sunucunun normal bir bölümü için yapılmış
              olsa da istenen dizin acaba suEXEC’in belge kök dizini altında mı?
              Yani, istenen dizin, suEXEC’in aidiyetinde çalıştığı kullanıcının
              ev dizini altında bulunan, <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> ile belirtilen dizinin altında mı? (<a href="#install">suEXEC’in yapılandırma seçeneklerine</a>
              bakınız).</p>
          </li>
    
          <li>
            <strong>Hedef dizin başkaları tarafından yazılabilen bir dizin değil,
              değil mi?</strong>
    
            <p class="indent">Başkaları da yazabilsin diye bir dizin açmıyoruz;
              dizin içeriğini sadece sahibi değiştirebilmelidir.</p>
          </li>
    
          <li>
            <strong>Hedef CGI/SSI programı mevcut mu?</strong>
    
            <p class="indent">Mevcut değilse çalıştırılamaz.</p>
          </li>
    
          <li>
            <strong>Hedef CGI/SSI program dosyasına başkaları tarafından
              yazılamıyor, değil mi?</strong>
    
            <p class="indent">Hedef CGI/SSI programının dosyasına sahibinden
              başka kimsenin bir şeyler yazmasını istemeyiz.</p>
          </li>
    
          <li>
            <strong>Hedef CGI/SSI program setuid veya setgid <em>değil</em>,
              değil mi?</strong>
    
            <p class="indent">UID/GID‘i tekrar değiştirecek programlar
              çalıştırmayı istemeyiz.</p>
          </li>
    
          <li>
            <strong>Hedef kullanıcı/grup, programın kullanıcı/grubu ile aynı mı?
            </strong>
    
            <p class="indent">Hedef kullanıcı dosyanın sahibi mi?</p>
          </li>
    
          <li>
            <strong>İşlemlerin güvenle yapılabilmesi için süreç ortamını
              başarıyla temizleyebildik mi?</strong>
    
            <p class="indent">suEXEC, sürecin çalışacağı ortama güvenli bir
              program çalıştırma yolu sağlamaktan başka, yapılandırma sırasında
              oluşturulan güvenli ortam değişkenleri listesinde isimleri bulunan
              ortam değişkenlerinden başkasını aktarmayacaktır.</p>
          </li>
    
          <li>
            <strong>Hedef CGI/SSI programı haline gelip çalışabildik mi?</strong>
    
            <p class="indent">Burası suEXEC’in bitip CGI/SSI programının
              başladığı yerdir.</p>
          </li>
        </ol>
    
        <p>Bu süreç suEXEC güvenlik modelinin standart işlemlerini oluşturur.
          Biraz zorlayıcı ve CGI/SSI tasarımına yeni kurallar ve sınırlamalar
          getiriyor olsa da düşünülen güvenliği adım adım sağlayacak şekilde
          tasarlanmıştır.</p>
    
        <p>Düzgün bir suEXEC yapılandırmasının hangi güvenlik risklerinden
          kurtulmayı sağladığı ve bu güvenlik modelinin sunucu yapılandırmasıyla
          ilgili sorumluluklarınızı nasıl sınırlayabildiği hakkında daha
          ayrıntılı bilgi edinmek için bu belgenin <a href="#jabberwock">"Uyarılar ve Örnekler"</a> bölümüne bakınız.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">suEXEC’in Yapılandırılması ve Kurulumu</a></h2>
    
        <p>Eğlence başlıyor.</p>
    
        <p><strong>suEXEC yapılandırma seçenekleri</strong><br />
        </p>
    
        <dl>
          <dt><code>--enable-suexec</code></dt>
    
          <dd>Bu seçenek, hiçbir zaman öntanımlı olarak kurulmayan ve
            etkinleştirilmeyen suEXEC özelliğini etkin kılar. suEXEC özelliğini
            kullanma isteğinizi Apache’nin kabul edebilmesi için
            <code>--enable-suexec</code> seçeneğinin yanında en azından bir tane
            de <code>--with-suexec-xxxxx</code> seçeneği belirtilmiş
            olmalıdır.</dd>
    
          <dt><code>--with-suexec-bin=<em>YOL</em></code></dt>
    
          <dd>Güvenlik sebebiyle <code>suexec</code> çalıştırılabilirinin
            bulunduğu yer sunucu koduna yazılır. Bu seçenekle öntanımlı yol
            değiştirilmiş olur. Örnek:<br />
            <code>--with-suexec-bin=/usr/sbin/suexec</code></dd>
    
          <dt><code>--with-suexec-caller=<em>KULLANICI</em></code></dt>
    
          <dd>Normalde httpd’nin aidiyetinde çalıştığı <a href="mod/mpm_common.html#user">kullanıcı</a>dır. Bu, suEXEC
            çalıştırıcısını çalıştırmasına izin verilen tek kullanıcıdır.</dd>
    
          <dt><code>--with-suexec-userdir=<em>DİZİN</em></code></dt>
    
          <dd><p>Kullanıcıların ev dizinleri altında suEXEC’in erişmesine izin
            verilen alt dizinin yerini tanımlar. Bu dizin altında suEXEC
            kullanıcısı tarafından çalıştırılacak tüm programlar "güvenilir"
            olmalıdır. Eğer “basit” bir <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> yönergesi kullanıyorsanız ( içinde “*”
            bulunmayan), bunun aynı dizin olması gerekir. Eğer burada belirtilen
            dizin, <code>passwd</code> dosyasında kullanıcı için belirtilmiş
            dizinin altında <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>
            yönergesinde belirtilen dizin olmadığı takdirde suEXEC işini
            gerektiği gibi yapmayacaktır. Öntanımlı değer
            <code>public_html</code>’dir.</p>
    
          <p>Eğer, sanal konaklarınızın herbiri farklı <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> yönergeleri içeriyorsa
            burada belirtilecek dizinin üst dizininin hepsinde aynı olması
            gerekir. <strong>Aksi takdirde, "~<em><code>kullanıcı</code></em>"
            istekleri düzgün çalışmayacaktır.</strong></p></dd>
    
          <dt><code>--with-suexec-docroot=<em>DİZİN</em></code></dt>
    
          <dd>httpd için belge kök dizinini belirler. Bu, (<code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>’lardan başka) suEXEC için
            kullanılacak tek hiyerarşi olacaktır. Öntanımlı dizin sonuna
            "<code>/htdocs</code>" eklenmiş <code>--datadir</code> dizinidir.
            Yani, seçeneği "<code>--datadir=/home/apache</code>" olarak
            belirtmişseniz suEXEC çalıştırıcısı için belge kök dizini
            "<code>/home/apache/htdocs</code>" olur.</dd>
    
          <dt><code>--with-suexec-uidmin=<em>UID</em></code></dt>
    
          <dd>suEXEC kullanıcısının kullanıcı kimliği olarak izin verilen en
            düşük değeri belirler. Çoğu sistemde bu ya 500’dür ya da 100; 100
            öntanımlıdır.</dd>
    
          <dt><code>--with-suexec-gidmin=<em>GID</em></code></dt>
    
          <dd>suEXEC kullanıcısının grup kimliği olarak izin verilen en düşük
            değeri belirler. Çoğu sistemde bu 100 olup, seçeneğin de öntanımlı
            değeridir.</dd>
    
          <dt><code>--with-suexec-logfile=<em>DOSYA</em></code></dt>
    
          <dd>suEXEC hareketlerinin ve hatalarının kaydedileceği günlük
            dosyasının adını belirler (denetim ve hata ayıklama için
            kullanışlıdır). Öntanımlı günlük dosyası ismi
            "<code>suexec_log</code>" olup yeri (<code>--logfiledir</code>
            seçeneği ile belirtilen) günlük dosyaları dizinidir.</dd>
    
          <dt><code>--with-suexec-safepath=<em>YOL</em></code></dt>
    
          <dd>CGI çalıştırılabilirlerine aktarılacak güvenilir <code>PATH</code>
            ortam değişkeninin değerini tanımlar.
            "<code>/usr/local/bin:/usr/bin:/bin</code>" öntanımlıdır.</dd>
        </dl>
    
        <h3>SuEXEC çalıştırıcısının derlenmesi ve kurulumu</h3>
          
    
          <p>SuEXEC özelliğini <code>--enable-suexec</code> seçeneği ile
            etkinleştirdiyseniz <code>make</code> komutunu verdiğinizde httpd
            ile birlikte <code>suexec</code> çalıştırılabilir dosyası da
            derlenecektir.</p>
    
          <p>Tüm bileşenler derlendikten sonra <code>make install</code> komutunu
            vererek kurulumu tamamlayabilirsiniz. <code>suexec</code>
            çalıştırılabilir dosyası <code>--sbindir</code> seçeneği ile
            tanımlanan dizine kurulacaktır; öntanımlı yeri
            <code>/usr/local/apache2/bin/</code> dizinidir.</p>
    
          <p>Kurulum adımında <strong><em>root yetkisine</em></strong> sahip
            olmanız gerektiğini unutmayın. Çalıştırıcıya kullanıcı kimliğinin
            atanabilmesi ve dosyanın sahibi olan kullanıcı kimliği ile
            çalıştırılabilmesini mümkün kılan bitinin etkin kılınabilmesi için
            kurulumun <code><em>root</em></code> tarafından yapılması
            önemlidir.</p>
        
    
        <h3>Paranoyak yetkilendirme</h3>
          
    
          <p>SuEXEC çalıştırıcısı kendini çalıştıran kullanıcının
            <code class="program"><a href="./programs/configure.html">configure</a></code> betiğine
            <code>--with-suexec-caller</code> seçeneği ile belirtilen kullanıcı
            olup olmadığına bakacaksa da, bu sınamanın da bir sistem veya
            kütüphane çağrısı ile istismar edilmiş olma ihtimali gözardı
            edilmemelidir. Bunun meydana gelmesini önlemek için ve genelde
            yapıldığı gibi dosyanın izinlerini suEXEC çalıştırıcısı sadece
            httpd'nin aidiyetinde çalıştığı grup tarafından çalıştırılacak
            şekilde ayarlayınız.</p>
    
          <p>Örneğin, sunucunuz şöyle yapılandırılmışsa:</p>
    
          <pre class="prettyprint lang-config">User www
    Group webgroup</pre>
    
    
          <p>Ve <code class="program"><a href="./programs/suexec.html">suexec</a></code> çalıştırılabilir de
            <code>/usr/local/apache2/bin/</code> dizinine kurulmuşsa şu komutları
            vermelisiniz:</p>
    
          <div class="example"><p><code>
              chgrp apache-grup /usr/local/apache2/bin/suexec<br />
              chmod 4750 /usr/local/apache2/bin/suexec<br />
          </code></p></div>
    
          <p>Böylece suEXEC çalıştırıcısını httpd’yi çalıştıran grubun
            üyelerinden başkasının çalıştıramayacağından emin olabilirsiniz.</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">suEXEC’in etkin kılınması ve iptal edilmesi</a></h2>
        
    
        <p>httpd başlatıldığı sırada <code class="program"><a href="./programs/suexec.html">suexec</a></code> çalıştırıcısı için
          <code>--sbindir</code> seçeneği ile tanımlanan dizine bakar (seçeneğin
          öntanımlı değeri <code>/usr/local/apache/sbin/suexec</code>’tir). httpd
          düzgün yapılandırılmış bir suEXEC çalıştırıcısı bulduğu takdirde hata
          günlüğüne şöyle bir ileti yazacaktır:</p>
    
    <div class="example"><p><code>
        [notice] suEXEC mechanism enabled (wrapper: <var>/dosya/yolu/suexec</var>)
    </code></p></div>
    
        <p>Sunucu başlatıldığında bu ileti yazılmazsa sunucu ya çalıştırıcı
          programı umduğu yerde bulamamıştır ya da dosyanın <em>setuid</em> biti
          <em>root</em> tarafından etkin kılınmamıştır.</p>
    
         <p>SuEXEC mekanizmasını etkin kılmak istediğiniz sunucu çalışmaktaysa
          sunucuyu önce öldürmeli sonra yeniden başlatmalısınız.  Basit bir
          <code>HUP</code> veya <code>USR1</code> sinyali ile yeniden başlamasını
          sağlamak yeterli olmayacaktır.</p>
    
         <p>SuEXEC mekanizmasını iptal etmek için ise <code class="program"><a href="./programs/suexec.html">suexec</a></code>
          dosyasını sildikten sonra httpd'yi öldürüp yeniden başlamalısınız.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">SuEXEC’in kullanımı</a></h2>
    
        <p>CGI programlarına yapılan isteklerin suEXEC çalıştırıcısı tarafından
          yerine getirilebilmesi için sanal konağın bir <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> yönergesi içermesi veya
          isteğin <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> tarafından işleme konulması
          gerekir.</p>
    
        <p><strong>Sanal Konaklar:</strong><br />SuEXEC çalıştırıcısını farklı
          bir kullanıcı ile etkin kılmanın tek yolu <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> bölümleri içinde <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> yönergesini
          kullanmaktır. Bu yönergede ana sunucuyu çalıştıran kullanıcıdan farklı
          bir kullanıcı  belirterek ilgili sanal konak üzerinden CGI kaynakları
          için yapılan tüm isteklerin belirtilen <em>kullanıcı</em> ve
          <em>grup</em> tarafından çalıştırılması sağlanır. Bu yönergeyi
          içermeyen sanal konaklar için ana sunucunun kullanıcısı
          öntanımlıdır.</p>
    
        <p><strong>Kullanıcı dizinleri:</strong><br />
        <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> tarafından işleme sokulan tüm istekler için
        suEXEC çalıştırıcısı istek yapılan kullanıcı dizininin sahibinin
        aidiyetinde çalıştırılacaktır. Bu özelliğin çalışması için tek
        gereklilik, kullanıcının SuEXEC çalıştırıcısı için etkin kılınmış olması
        ve çalıştırıcının yukarıdaki <a href="#model">güvenlik sınamalarından</a>
        geçebilmesidir. Ayrıca,  <code>--with-suexec-userdir</code> <a href="#install">derleme</a> seçeneğinin açıklamasına da bakınız.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="debug" id="debug">SuEXEC ve hata ayıklama</a></h2>
    
        <p>SuEXEC çalıştırıcısı yukarıda değinildiği gibi günlük bilgilerini
          <code>--with-suexec-logfile</code> seçeneği ile belirtilen dosyaya
          yazacaktır. Çalıştırıcıyı doğru yapılandırarak kurduğunuzdan emin olmak
          istiyorsanız, yolunda gitmeyen şeyler var mı diye bu günlük dosyasına
          bakmayı ihmal etmeyin.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="jabberwock" id="jabberwock">Uyarılar ve Örnekler</a></h2>
        
    
        <p><strong>UYARI!</strong> Bu bölüm henüz bitmedi.</p>
    
        <p>SuEXEC çalıştırıcısından dolayı sunucu ayarlarına bazı sınırlamalar
          getiren bir kaç önemli nokta mevcuttur. SuEXEC ile ilgili hata
          bildiriminde bulunmadan önce bunlara bir göz atmalısınız.</p>
    
        <p><strong>suEXEC ile ilgili önemli noktalar</strong></p>  
        <ul>
          <li>Hiyerarşik sınırlamalar
    
            <p class="indent">Güvenlik ve verimlilik adına, tüm suEXEC
              isteklerinin sanal konaklar için üst düzey belge kökünün altındaki
              dosyalarla, kullanıcı dizinleri için ise üst düzey bireysel belge
              köklerinin altındaki dosyalarla sınırlı kalması gerekir. Örneğin,
              dört sanal konağınız varsa ve suEXEC çalıştırıcısının
              getirilerinden faydalanmak istiyorsanız, sanal konaklarınızın belge
              kök dizinlerini ana sunucunun belge kök dizininin altında kalacak
              şekilde yapılandırmanız gerekir (örnek yolda).</p>
          </li>
    
          <li>SuEXEC'in <code>PATH</code> ortam değişkeni
    
            <p class="indent">Bunu değiştirmek tehlikeli olabilir. Bu değişkende
              tanımladığınız her yolun <strong>güvenli</strong> bir dizini işaret
              ettiğinden emin olmalısınız. Başkalarının oralarda bir truva atı
              çalıştırmasını istemiyorsanız buna çok dikkat ediniz.</p>
          </li>
    
          <li>SuEXEC kodunda değişiklik
    
            <p class="indent">Gerçekte ne yaptığınızı bilmiyorsanız bu,
              <strong>büyük bir sorun</strong> olabilir. Böyle şeyler yapmaktan
              mümkün olduğunca uzak durmalısınız.</p>
          </li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/bind.html.fr.utf8����������������������������������������������������������0000664�0001751�0001751�00000041005�14740503670�020132� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Ecoute sélective - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Ecoute sélective</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Configuration du serveur HTTP Apache pour l'écoute
        sur un port et une adresse IP spécifiques.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Vue d'ensemble</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#reload">Changer la configuration de l'écoute au redémarrage</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ipv6">Remarques spécifiques à IPv6</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#protocol">Spécification du protocole avec Listen</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Qu'en est-il avec les serveurs virtuels</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="vhosts/">Serveurs virtuels</a></li><li><a href="dns-caveats.html">Problèmes liés au DNS</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Vue d'ensemble</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mpm_common.html">mpm_common</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code></li></ul></td></tr></table>
    
    
        <p>Au démarrage de httpd, un port et une adresse lui sont associés sur
        l'hôte local et le serveur se met en attente de l'arrivée d'une requête.
        Par défaut, le serveur écoute toutes les adresses de l'hôte local.
        Cependant, on peut lui préciser des ports et des adresses spécifiques à
        écouter, ou une combinaison des deux. Tout ceci est souvent associé avec la
        fonctionnalité des <a href="vhosts/">serveurs virtuels</a> qui détermine la
        manière dont <code>httpd</code> répond aux différents ports, noms d'hôtes et
        adresses IP.</p>
    
        <p>La directive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> permet
        d'indiquer au serveur qu'il ne doit accepter des requêtes que sur le(s)
        port(s) spécifiés ou une combinaison adresse/port. Si seul un numéro de port
        est spécifié dans la directive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>, le serveur se met à l'écoute sur ce
        port et sur toutes les interfaces réseau. Si une adresse IP est spécifiée
        en plus du port, le serveur va écouter sur ce port et uniquement sur
        l'interface réseau correspondante. On peut utiliser plusieurs directives
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> pour spécifier plusieurs
        adresses et ports à écouter. Le serveur répondra alors aux requêtes sur tous
        les ports et adresses spécifiés.</p>
    
        <p>Par exemple, pour faire en sorte que le serveur accepte des connexions
        sur les ports 80 et 8000 et sur toutes les interfaces, utilisez :</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 80
    Listen 8000</pre>
    </div>
    
        <p>Pour faire en sorte que le serveur accepte des connexions sur le port 80
        pour une interface, et sur le port 8000 pour une
        autre interface, utilisez :</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 192.0.2.1:80
    Listen 192.0.2.5:8000</pre>
    </div>
    
        <p>Les adresses IPv6 doivent être mises entre crochets, comme dans
        l'exemple suivant :</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen [2001:db8::a00:20ff:fea7:ccea]:80</pre>
    </div>
    
        <div class="warning"><p>Des directives <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        imbriquées provoqueront une erreur fatale qui
        empêchera le serveur de démarrer.</p>
    
        <div class="example"><p><code>
          (48)Address already in use: make_sock: could not bind to address [::]:80
        </code></p></div>
    
        <p>Voir <a href="http://wiki.apache.org/httpd/CouldNotBindToAddress">cette
        discussion dans le wiki</a> pour plus de détails à propos de la résolution
        de ce problème.</p>
    
        </div>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="reload" id="reload">Changer la configuration de l'écoute au redémarrage</a></h2>
        
    
        <p>Lorsque httpd est redémarré, certaines remarques sont à prendre en compte
        quant aux modifications apportées aux directives <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>. Au cours du redémarrage, httpd
        conserve la liaison avec les ports de la configuration précédente afin
        d'éviter l'obtention d'un message d'erreur "Connection refused" lors d'une
        tentative ultérieure de connexion au serveur. Si les modifications apportées au jeu de
        directives <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> utilisé entrent
        en conflit avec ce dernier, le serveur refusera de redémarrer.</p>
    
        <p>Par exemple, modifier la configuration suivante :</p>
        
        <div class="example"><pre class="prettyprint lang-config">Listen 127.0.0.1:80</pre>
    </div>
    
        <p>pour utiliser la suivante pourra échouer car écouter le port 80 sur
        toutes les adresses IP entre en conflit avec une écoute sélective du port 80
        sur la seule adresse IP 127.0.0.1.</p>
        
        <div class="example"><pre class="prettyprint lang-config">Listen 80</pre>
    </div>
    
        <p>Pour qu'une telle modification de configuration soit prise en compte avec
        succès, il est nécessaire d'arrêter, puis de démarrer le serveur.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="ipv6" id="ipv6">Remarques spécifiques à IPv6</a></h2>
        
    
        <p>Un nombre croissant de plateformes implémentent IPv6, et
        <a class="glossarylink" href="./glossary.html#apr" title="voir glossaire">APR</a> supporte IPv6 sur la plupart d'entre elles,
        ce qui permet à httpd d'allouer des points de connexion (sockets) IPv6
        et de traiter des requêtes envoyées sur IPv6.</p>
    
        <p>Les administrateurs de httpd doivent se préoccuper de la possibilité
        pour un point de connexion IPv6 de traiter à la fois des connexions IPv4
        et des connexions IPv6.
        Le traitement de connexions IPv4 avec un point de connexion IPv6 utilise
        des adresses IPv6 traduites en IPv4 qui sont autorisées par défaut sur la
        plupart des plateformes, mais sont interdites par défaut sous FreeBSD, NetBSD,
        et OpenBSD, afin de respecter la politique de sécurité du système sur ces plateformes.
        Sur les systèmes où ces adresses sont interdites par défaut, un
        paramètre spécial du script <code class="program"><a href="./programs/configure.html">configure</a></code> permet de modifier
        ce comportement pour httpd.</p>
    
        <p>En revanche, sur certaines plateformes comme Linux et Tru64, la
        <strong>seule</strong> manière de gérer à la fois IPv6 et IPv4 passe
        par l'utilisation d'adresses traduites. Si vous voulez que <code>httpd</code> gère
        des connexions IPv4 et IPv6 avec un minimum de points de connexion,
        ce qui nécessite l'utilisation d'adresses IPv6 traduites en IPv4,
        utilisez l'option <code>--enable-v4-mapped</code> du script <code class="program"><a href="./programs/configure.html">configure</a></code>.</p>
    
        <p>L'option <code>--enable-v4-mapped</code> est utilisée par défaut sur
        toutes les plateformes sauf FreeBSD, NetBSD, et OpenBSD&nbsp;;
        votre httpd a donc probablement été construit avec cette option.</p>
    
        <p>Si vous souhaitez que httpd ne gère que des connexions IPv4, sans se
        soucier de ce que votre plateforme et APR supportent, spécifiez une adresse
        IPv4 dans toutes les directives
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>, comme dans l'exemple
        suivant :</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 0.0.0.0:80
    Listen 192.0.2.1:80</pre>
    </div>
    
        <p>Si votre plateforme le supporte et si vous souhaitez que httpd gère
        des connexions IPv4 et IPv6 sur des points de connexion séparés
        (c'est à dire désactiver la traduction des adresses IPv6 au format IPv4),
        utilisez l'option <code>--disable-v4-mapped</code> du script
        <code class="program"><a href="./programs/configure.html">configure</a></code>. <code>--disable-v4-mapped</code> est
        utilisée par défaut sur FreeBSD, NetBSD, et OpenBSD.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="protocol" id="protocol">Spécification du protocole avec Listen</a></h2>
        
        <p>Dans la plupart des configurations, le second paramètre optionnel
        <var>protocol</var> de la directive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> n'est pas obligatoire. S'il
        n'est pas spécifié, les protocoles par défaut
        sont <code>https</code> pour le port 443, et <code>http</code> pour
        tous les autres ports. Le protocole sert à déterminer quel module
        doit traiter une requête, et à appliquer les optimisations
        spécifiques au protocole à l'aide de la directive <code class="directive"><a href="./mod/core.html#acceptfilter">AcceptFilter</a></code>.</p>
    
        <p>Vous ne devez définir le protocole que si vous travaillez avec
        des ports non standards. Par exemple, pour travailler en
        <code>https</code> sur le port 8443 :</p>
    
        <div class="example"><pre class="prettyprint lang-config">Listen 192.170.2.1:8443 https</pre>
    </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Qu'en est-il avec les serveurs virtuels</a></h2>
        
    
        <p> La directive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> n'implémente pas les serveurs virtuels.
        Elle indique simplement au serveur principal sur quels adresses et ports
        il doit écouter. Si aucune directive
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        n'est présente, le serveur se comportera de la même façon pour toutes
        les requêtes acceptées. En revanche, la directive
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        peut être utilisée pour provoquer une réaction différente du serveur
        pour un ou plusieurs adresses ou ports. Pour implémenter un serveur virtuel,
        on doit d'abord indiquer au serveur sur quels adresses et ports il doit écouter.
        Ensuite, une section
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        doit être créée pour le couple adresse+port spécifié afin de définir le
        comportement de cet hôte virtuel. Notez que si la directive
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        est définie pour une adresse et un port sur lesquels le serveur n'est pas censé
        écouter, cet hôte virtuel ne sera pas accessible.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/bind.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/bind.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/bind.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/bind.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/bind.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/bind.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/bind.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/custom-error.html.fr.utf8��������������������������������������������������0000664�0001751�0001751�00000035016�14740503670�021664� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Messages d'erreur personnalisés - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Messages d'erreur personnalisés</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Le serveur HTTP Apache fournit des messages d'erreur génériques
        pour les codes de statut 4xx ou 5xx ; ces messages sont cependant
        relativement austères, imprécis, et peuvent s'avérer intimidants
        pour les visiteurs du site. Si vous le souhaitez, vous pouvez
        afficher des messages d'erreur plus conviviaux, dans un langage
        autre que l'anglais, ou même sous une forme plus en adéquation avec
        le style de votre site.</p>
    
        <p>Il est possible de définir des messages d'erreur personnalisés
        pour chaque code de statut HTTP associé à une condition d'erreur -
        c'est à dire tout code de statut 4xx ou 5xx.</p>
    
        <p>De plus, il est possible de
        personnaliser le message d'erreur en fonction d'un jeu de valeurs
        fourni, en utilisant les <a href="howto/ssi.html">Inclusions Côté
        Serveur (SSI)</a>. Un programme CGI ou un autre gestionnaire
        dynamique (PHP, mod_perl, etc...) peut aussi utiliser ces variables
        pour gérer les conditions d'erreur.</p>
    
    
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#configuration">Configuration</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#variables">Variables disponibles</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#custom">Personnalisation des messages d'erreur</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#multi-lang">Messages d'erreur personnalisés
      multilingues</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Configuration</a></h2>
    
        <p>Les messages d'erreur personnalisés sont configurés via la
        directive <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code>, qui
        peut être utilisée dans un contexte global, serveur virtuel ou
        répertoire. On peut utiliser cette directive dans les fichiers
        .htaccess si <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> est
        définie à FileInfo.</p>
    
        <pre class="prettyprint lang-config">ErrorDocument 500 "Désolé, notre script s'est
    crashé ; comme c'est dommage !"
    ErrorDocument 500 /cgi-bin/crash-recover
    ErrorDocument 500 http://error.example.com/server_error.html
    ErrorDocument 404 /errors/not_found.html 
    ErrorDocument 401 /subscription/how_to_subscribe.html</pre>
    
    
    <p>La syntaxe de la directive <code>ErrorDocument</code> est :</p>
          <pre class="prettyprint lang-config">ErrorDocument &lt;code_3_chiffres&gt; &lt;action&gt;</pre>
    
          <p>où action peut être traitée comme :</p>
            <ol>
          <li>Une URL de redirection local (si l'action commence par un "/").</li>
          <li>Une URL de redirection externe (si action est une URL valide).</li>
          <li>Le texte à afficher (si l'action ne répond à aucune des
          deux conditions précédentes). Entourez le texte de guillemets (")
          s'il contient plusieurs mots.</li>
            </ol>
    
        <p>Dans le cas d'une redirection vers une URL locale, des variables
        d'environnement supplémentaires sont définies de façon à ce que la
        réponse puisse être personnalisée par la suite. Elles ne sont pas
        envoyées aux URLs externes.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="variables" id="variables">Variables disponibles</a></h2>
    
          <p>La redirection vers une autre URL peut être utile, mais
          seulement s'il est possible de transmettre certaines informations
          qui pourront être utilisées pour expliquer ou journaliser
          la condition d'erreur ou le problème plus clairement.</p>
    
    	<p>Pour y parvenir, lorsque la redirection d'erreur est envoyée,
    	des variables d'environnement supplémentaires sont définies à
    	partir des en-têtes de la requête originale en préfixant le nom
    	d'origine de l'en-tête par 'REDIRECT_', ce qui permet de fournir au
    	message d'erreur le contexte de la requête originelle.</p>
    
          <p>Par exemple, en plus des variables d'environnement habituelles,
          vous pouvez recevoir ce qui suit :</p>
    
    
          <div class="example"><p><code>
            REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/jpeg, image/png<br />
            REDIRECT_HTTP_USER_AGENT=Mozilla/5.0 Fedora/3.5.8-1.fc12 Firefox/3.5.8<br />
            REDIRECT_PATH=.:/bin:/usr/local/bin:/sbin<br />
            REDIRECT_QUERY_STRING=<br />
            REDIRECT_REMOTE_ADDR=121.345.78.123<br />
            REDIRECT_REMOTE_HOST=client.example.com<br />
            REDIRECT_SERVER_NAME=www.example.edu<br />
            REDIRECT_SERVER_PORT=80<br />
            REDIRECT_SERVER_SOFTWARE=Apache/2.2.15<br />
            REDIRECT_URL=/cgi-bin/buggy.pl
          </code></p></div>
    
          <p>Les variables d'environnement <code>REDIRECT_</code> sont
          créées à partir des variables d'environnement préexistantes à la
          redirection qui sont préfixées par la chaîne <code>REDIRECT_</code> ;
          par exemple, <code>HTTP_USER_AGENT</code> devient
          <code>REDIRECT_HTTP_USER_AGENT</code>.</p>
    
          <p><code>REDIRECT_URL</code>, <code>REDIRECT_STATUS</code>, et
          <code>REDIRECT_QUERY_STRING</code> sont systématiquement définies,
          les autres variables n'étant définies que si l'en-tête
          correspondant existait avant la condition d'erreur.</p>
    
          <p><strong>Aucune</strong> d'entre elles ne sera définie si votre
          directive <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code>
          spécifie une redirection <em>externe</em> (toute URL commençant
          par un protocole du style <code>http:</code>, même si elle fait
          référence au même hôte que le serveur).</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="custom" id="custom">Personnalisation des messages d'erreur</a></h2>
    
    
    	<p>Si vous faites pointer votre directive
    	<code>ErrorDocument</code> vers certains gestionnaires
    	dynamiques comme les inclusions côté serveur, les scripts CGI ou
    	d'autres gestionnaires, vous pouvez utiliser les variables
    	d'environnement supplémentaires disponibles pour personnaliser
    	le message.</p>
    
    
          <p>Si la directive ErrorDname-basedocument spécifie une redirection locale
          vers un script CGI, ce dernier doit ajouter un en-tête
          "<code>Status:</code>" dans sa sortie afin de s'assurer du bon
          acheminement jusqu'au client de la condition d'erreur qui a
          provoqué cette redirection. Par exemple, un script Perl spécifié
          par une directive ErrorDocument pourrait contenir ce qui suit
          :</p>
    
          <pre class="prettyprint lang-perl">...
    print  "Content-type: text/html\n"; 
    printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"}; 
    ...</pre>
    
    
          <p>Si un script est dédié à la gestion d'une condition d'erreur
          spécifique, telle que <code>404&nbsp;Not&nbsp;Found</code>, il
          peut utiliser le code et le texte de l'erreur spécifiques à la
          place.</p>
    
          <p>Notez que si la réponse contient un en-tête
          <code>Location:</code> (afin d'initier une redirection côté
          client), le script <em>doit</em> émettre un en-tête approprié
          (comme <code>302&nbsp;Found</code>). Dans le cas contraire,
          l'en-tête <code>Location:</code> ne produira aucun effet.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multi-lang" id="multi-lang">Messages d'erreur personnalisés
      multilingues</a></h2>
    
        <p>Vous trouverez dans la distribution du serveur HTTP Apache un
        répertoire contenant des messages d'erreur personnalisés traduits en
        16 langues différentes. Pour activer cette fonctionnalité, vous
        pouvez aussi inclure un fichier de configuration qui se trouve dans
        le répertoire de configuration <code>conf/extra</code>.</p>
    
        <p>Dans le fichier de configuration de votre serveur, vous trouverez
        un groupe de lignes du style :</p>
    
        <pre class="prettyprint lang-config">    # Multi-language error messages
        #Include conf/extra/httpd-multilang-errordoc.conf</pre>
    
    
        <p>Décommentez la ligne <code>Include</code> pour activer cette
        fonctionnalité, et présenter des messages d'erreur dont le langage
        sera négocié en fonction du langage préféré défini au niveau du
        navigateur du client.</p>
    
        <p>De plus, ces documents contiennent diverses variables
        <code>REDIRECT_</code>, de façon à ce que l'utilisateur final
        dispose d'informations supplémentaires à propos de ce qui a pu se
        produire, et de ce qu'il est susceptible de faire maintenant.</p>
    
        <p>Ces documents peuvent être personnalisés en fournissant autant
        d'informations utiles que vous le souhaitez aux utilisateurs à
        propos de votre site, et de ce qu'ils sont susceptibles d'y trouver.</p>
    
        <p>Pour pouvoir utiliser cette fonctionnalité, vous devez activer
        <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> et <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>.</p>
    
     </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/custom-error.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/custom-error.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/suexec.html.ko.euc-kr������������������������������������������������������0000664�0001751�0001751�00000060131�14743132254�021014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>suEXEC  - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>suEXEC </h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p><strong>suEXEC</strong>  ġ <strong>CGI</strong>
        <strong>SSI</strong> α׷    ID
        ƴ ٸ  ID ϵ Ѵ.  CGI SSI α׷
        ϸ   ڿ  ڷ Ѵ.</p>
    
        <p>   ϸ ڰ  CGI SSI α׷
        ϰ Ҷ ߻  ִ   
         ִ. ׷ suEXEC ϰ Ǹ  
        ǻͿ ο     ִ.  <em>setuid root</em>
        α׷ ̷ α׷   ϴٸ suEXEC
        ʱ  ٶ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#before">ϱ </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#model">suEXEC ȸ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">suEXEC  ġ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#enable">suEXEC Ű </a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">suEXEC ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#debug">suEXEC ϱ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#jabberwock">ٽ ѹ ϶:  </a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="before" id="before">ϱ </a></h2>
    
        <p>ϱ  켱 ġ׷    .</p>
    
        <p> <strong>setuid</strong> <strong>setgid</strong>
          н ü Ѵٰ Ѵ. 
        ɾ 鵵   Ѵ. suEXEC ϴ ٸ ÷
        ϴٸ  ٸ  ִ.</p>
    
        <p>ι°,  ǻ  ⺻   ͼϴٰ
        Ѵ. ⿡ <strong>setuid/setgid</strong> ɰ
        ̵ ý۰ ȿ ġ  ⿡  ذ Եȴ.</p>
    
        <p>°, suEXEC ڵ <strong></strong>
         Ѵٰ Ѵ. ڿ  Ÿ׽͵
        suEXEC õ  ڵ带 ɽ ϰ ˻ߴ.
        ڵ带 ϰ ϰ Ȯ  ϱ  Ǹ
        ￴.  ڵ带 ϸ ġ  ο 
         ߻  ִ.  α׷ֿ  ſ  ˰
        ڵ带 캸 ġ׷ ۾  ǻ簡 ٸ
        suEXEC ڵ带 ʱ <strong></strong> Ѵ.</p>
    
        <p>׹° , ġ׷ suEXEC ġ
        ⺻ġ  <strong>ʱ</strong> ߴ. ᱹ
        ڰ Ǹ ← suEXEC ؾ Ѵ. suEXEC
            ڴ Ϲ ġ suEXEC
        ġ  ִ. suEXEC  ϴ ý  å
        ڴ   ְ 캸 ؾ Ѵ.
        ̷   suEXEC Ҹŭ ְ ȣ 
         suEXEC ϵ ġ׷ ϱ ̴.</p>
    
        <p> ϱ ϴ°? ׷? .  !</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="model" id="model">suEXEC ȸ</a></h2>
    
        <p>suEXEC ϰ ġϱ  츮 ȸ 
        Ѵ. ̸  Ȯ suEXEC ȿ   Ͼ
        ý    ؾ     
        ִ.</p>
    
        <p><strong>suEXEC</strong> ġ  θ setuid
        "wrapper" α׷  Ѵ.  wrapper ڰ
        ּ ٸ userid ϵ  CGI SSI α׷
        HTTP û  Ҹ. ̷ û  ġ suEXEC
        wrapper α׷ α׷  ڿ ׷
        ID Ѵ.</p>
    
        <p>׷ wrapper     и Ѵ.
          ϳ ϸ α׷ з ϵǰ 
         Ѵ.    Ѵ:</p>
    
        <ol>
          <li>
            <strong>wrapper ϴ ڰ ý 
            ΰ?</strong> 
    
            <p class="indent">
              wrapper ϴ ڰ  ý 
              ȮѴ.
            </p>
         </li>
    
         <li>
            <strong>  ƱԸƮ wrapper ϴ°?</strong>
    
            <p class="indent">
              wrapper   ƱԸƮ ־߸ ȴ.
              ġ    ȴ. wrapper  
              ƱԸƮ ϸ ŷǾų ġ suEXEC
                ִ ̴.
            </p>
          </li>
    
          <li>
            <strong> ڰ wrapper ϵ Ǿ?</strong> 
    
            <p class="indent">
               ڰ wrapper ϵ Ǿ? 
               (ġ )  α׷ 
               ִ.
            </p>
          </li>
    
          <li>
            <strong> CGI SSI α׷  
            °?</strong>
    
            <p class="indent">
               CGI SSI α׷ '/' ϰų 
              '..' °? ̵   .  CGI/SSI
              α׷ suEXEC  root (Ʒ
              <code>--with-suexec-docroot=<em>DIR</em></code> )
               ־ Ѵ.
            </p>
          </li>
    
          <li>
            <strong> ڸ ȿѰ?</strong> 
    
            <p class="indent">
               ڰ ϴ°?
            </p>
          </li>
    
          <li>
            <strong> ׷ ȿѰ?</strong> 
    
            <p class="indent">
               ׷ ϴ°?
            </p>
          </li>
    
          <li>
            <strong> ڰ superuser <em>ƴѰ</em>?</strong>
            
    
            <p class="indent">
               suEXEC <code><em>root</em></code> CGI/SSI
              α׷    Ѵ.
            </p>
          </li>
    
          <li>
            <strong> userid ּ ID ں <em>ū</em>?</strong>
    
            <p class="indent">
               ּ  ID ڸ Ѵ. ׷ CGI/SSI
              α׷   ִ userid ּġ 
               ִ. "ýۿ"  Ҷ ϴ.
            </p>
          </li>
    
          <li>
            <strong> ׷ superuser ׷ <em>ƴѰ</em>?</strong> 
    
            <p class="indent">
               suEXEC <code><em>root</em></code> ׷ CGI/SSI
              α׷    Ѵ.
            </p>
          </li>
    
          <li>
            <strong> groupid ּ ID ں <em>ū</em>?</strong> 
    
            <p class="indent">
               ּ ׷ ID ڸ Ѵ. ׷ CGI/SSI
              α׷   ִ groupid ּġ 
               ִ. "ýۿ" ׷ Ҷ ϴ.
            </p>
          </li>
    
          <li>
            <strong>wrapper   ڿ ׷
              ִ°?</strong>
    
            <p class="indent">
               ܰ迡 α׷ setuid setgid ȣ Ͽ
               ڿ ׷ ȴ. , ׷ ٸ
              ڰ ش  ׷ ʱȭȴ.
            </p>
          </li>
    
          <li>
            <strong>CGI/SSI α׷ ִ 丮 丮
              ִ°?</strong>
    
            <p class="indent">
              丮  ʴٸ    . ̰
              丮   ٸ 丮  
              ̴.
            </p>
          </li>
    
          <li>
            <strong>丮 ġ  ȿ ִ°?</strong>
    
            <p class="indent">
               Ϲ κ û  ûϴ 丮
              suEXEC  root Ʒ ִ°? UserDir û 
              ûϴ 丮 suEXEC userdir  (<a href="#install">suEXEC  ɼ</a> ) 丮
              Ʒ ִ°?
            </p>
          </li>
    
          <li>
            <strong>ٸ  丮  <em>°</em>?</strong>
    
            <p class="indent">
              丮 ٸ  α ʴ´. 
              ڸ 丮    ִ.
            </p>
          </li>
    
          <li>
            <strong> CGI/SSI α׷ ϴ°?</strong> 
    
            <p class="indent">
              ʴٸ   .
            </p>
          </li>
    
          <li>
            <strong>ٸ   CGI/SSI α׷ 
            <em>°</em>?</strong>
    
            <p class="indent">
              ڿ  CGI/SSI α׷ ϱ ʴ´.
            </p>
          </li>
    
          <li>
            <strong> CGI/SSI α׷ setuid setgid
            <em>ƴѰ</em>?</strong>
    
            <p class="indent">
              츮 α׷ ٽ UID/GID ϱ ʴ´.
            </p>
          </li>
    
          <li>
            <strong> /׷ α׷ /׷ ?</strong>
    
            <p class="indent">
              ڰ  ΰ?
            </p>
          </li>
    
          <li>
            <strong>   μ ȯ溯 û
             ִ°?</strong>
    
            <p class="indent">
              suEXEC ( )   PATH ,
              (̰͵  )  ȯ溯 Ͽ ŵ
                μ ȯ溯 .
            </p>
          </li>
    
          <li>
            <strong>  CGI/SSI α׷ 
             ִ°?</strong> 
    
            <p class="indent">
              ⼭ suEXEC   CGI/SSI α׷ Ѵ.
            </p>
          </li>
        </ol>
    
        <p>̰ suEXEC wrapper ȸ ǥ ̴. ټ
        ϰ CGI/SSI 迡 ο  ,  ο
        ΰ Ѵܰ辿 ɽ .</p>
    
        <p>       ִ 
        suEXEC       ִ  
         <a href="#jabberwock">"ٽ ѹ ϶"</a> 
        ϶.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">suEXEC  ġ</a></h2>
    
        <p> ִ  Ѵ.</p>
    
        <p><strong>suEXEC  ɼ</strong><br />
        </p>
    
        <dl>
          <dt><code>--enable-suexec</code></dt>
    
          <dd> ɼ ⺻ ġǰų Ȱȭʴ suEXEC
           ȰȭѴ. APACI suEXEC ޾Ƶ̷
          <code>--enable-suexec</code> ɼǿܿ
          <code>--with-suexec-xxxxx</code> ɼ ּ Ѱ
          ʿϴ.</dd>
    
          <dt><code>--with-suexec-bin=<em>PATH</em></code></dt>
    
          <dd><code>suexec</code> ̳ʸ δ Ȼ 
           ϵǾ Ѵ.  ⺻ Ϸ  ɼ
          Ѵ. <em> </em>
          <code>--with-suexec-bin=/usr/sbin/suexec</code></dd>
    
          <dt><code>--with-suexec-caller=<em>UID</em></code></dt>
    
          <dd> ġ ϴ <a href="mod/mpm_common.html#user">ڸ</a>. α׷
            ִ  ڴ.</dd>
    
          <dt><code>--with-suexec-userdir=<em>DIR</em></code></dt>
    
          <dd>suEXEC  Ǵ  Ȩ丮 丮
          Ѵ.  丮 ִ   
          suEXEC Ƿ,  α׷ "ؾ" Ѵ. (
          ,  "*" ) "" UserDir þ Ѵٸ
            ؾ Ѵ. UserDir þ passwd Ͽ
            Ȩ丮 ٸ suEXEC 
          ۵ ʴ´. ⺻ "public_html"̴.<br />
          ȣƮ  ٸ UserDir Ѵٸ  
          θ 丮 ȿ ֵ ؾ ϰ,  θ 丮
           ´. <strong>̷  , "~userdir"
          cgi û ۵ ʴ´!</strong></dd>
    
          <dt><code>--with-suexec-docroot=<em>DIR</em></code></dt>
    
          <dd>ġ DocumentRoot Ѵ. ̴ suEXEC 
           ִ (UserDirs )  ̴. ⺻ 丮
          <code>--datadir</code>  "/htdocs"  ̴.
          <em> </em> "<code>--datadir=/home/apache</code>"
          ߴٸ suEXEC wrapper document root
          "/home/apache/htdocs" 丮 Ѵ.</dd>
    
          <dt><code>--with-suexec-uidmin=<em>UID</em></code></dt>
    
          <dd>suEXEC   ּ UID Ѵ.
          κ ýۿ 500̳ 100 ϴ. ⺻
          100̴.</dd>
    
          <dt><code>--with-suexec-gidmin=<em>GID</em></code></dt>
    
          <dd>suEXEC  ׷ ּ GID Ѵ.
          κ ýۿ 100 ϹǷ   ⺻̴.</dd>
    
          <dt><code>--with-suexec-logfile=<em>FILE</em></code></dt>
    
          <dd> suEXEC ۵  (ó   )
           αϸ Ѵ. ⺻ α ̸
          "suexec_log"̰ ǥ α 丮
          (<code>--logfiledir</code>) ġѴ.</dd>
    
          <dt><code>--with-suexec-safepath=<em>PATH</em></code></dt>
    
          <dd>CGI Ͽ Ѱ  PATH ȯ溯 Ѵ.
          ⺻ "/usr/local/bin:/usr/bin:/bin"̴.</dd>
        </dl>
    
        <p><strong>suEXEC wrapper ϰ ġϱ</strong><br />
        <code>--enable-suexec</code> ɼ suEXEC  ϰ
         <code>make</code> ɾ ϸ <code>suexec</code>
         (ġ Բ) ڵ .<br />
           <code>make install</code> ɾ
        Ͽ ġ  ִ. ̳ʸ <code>suexec</code>
        <code>--sbindir</code> ɼ  丮 ġȴ.
        ⺻ ġ "/usr/local/apache2/sbin/suexec"̴.<br />
        ġ  <strong><em>root </em></strong> ʿ
        ϶. wrapper  ID ϱؼ ڰ
        <code><em>root</em></code>̰ ϸ setuserid Ʈ
        Ǿ Ѵ.</p>
    
        <p><strong> Ѽ</strong><br />
        suEXEC wrapper ڽ  ڰ  ɼ
        <code>--with-suexec-caller</code>  ùٸ 
        Ȯ ,  ˻  suEXEC ϴ ýȣ
        Ȥ ̺귯 Լ ۵Ǿ  ִ. ̸ ϸ
        Ϲ  ̹Ƿ  ġ ϴ ׷츸
        suEXEC   ֵ Ͻý  ؾ Ѵ.</p>
    
        <p> ,    ϰ:</p>
    
    <div class="example"><p><code>
        User www<br />
        Group webgroup<br />
    </code></p></div>
    
        <p><code>suexec</code> "/usr/local/apache2/sbin/suexec"
        ġϿٸ,  ؾ Ѵ:</p>
    
    <div class="example"><p><code>
        chgrp webgroup /usr/local/apache2/bin/suexec<br />
        chmod 4750 /usr/local/apache2/bin/suexec<br />
    </code></p></div>
    
        <p>׷  ġ ϴ ׷츸 suEXEC wrapper
          ִ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">suEXEC Ű </a></h2>
    
        <p>ġ Ҷ <code>--sbindir</code> ɼ 
        丮 <code>suexec</code>  (⺻
        "/usr/local/apache2/sbin/suexec") ã´. ġ
          suEXEC wrapper ߰ϸ  α(error
        log)   Ѵ:</p>
    
    <div class="example"><p><code>
        [notice] suEXEC mechanism enabled (wrapper: <em>/path/to/suexec</em>)
    </code></p></div>
    
        <p> ߿ ̷  ٸ   ҿ
        wrapper α׷ ã ߰ų,  <em>setuid
        root</em> ġʾұ  ̴.</p>
    
         <p>ó suEXEC  ϰ Ͱ ̹ ġ 
         ̶, ġ ̰ ٽ ؾ Ѵ. 
         HUP̳ USR1 ñ׳η ϴ δ  ʴ. </p>
         <p>suEXEC ȻϷ <code>suexec</code>  
         ġ ̰ ؾ Ѵ. </p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">suEXEC ϱ</a></h2>
    
        <p>CGI α׷ û  <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> þ
         ȣƮ û Ͽų <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code>
        û óϴ 쿡 suEXEC wrapper ȣѴ.</p>
    
        <p><strong>ȣƮ:</strong><br /> suEXEC wrapper
        ϴ Ѱ  <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> ǿ <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> þ
        ϴ ̴.  þ ּ  ID ٸ
        ϸ CGI ڿ  û <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
         <em>User</em> <em>Group</em> ȴ. 
        þ <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>  ּ
        userid Ѵ.</p>
    
        <p><strong> 丮:</strong><br />
         <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> û óѴٸ suEXEC
         wrapper ȣϿ, û  丮 شϴ 
         ID CGI α׷ Ѵ.   Ϸ 
         ID CGI   ְ ũƮ  <a href="#model">
         ˻</a> ׸ ؾ Ѵ. <a href="#install">
         ɼ</a> <code>--with-suexec-userdir</code> ϶.</p> </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="debug" id="debug">suEXEC ϱ</a></h2>
    
        <p>suEXEC wrapper α   ٷ
        <code>--with-suexec-logfile</code> ɼ  Ͽ
        . wrapper ùٷ ϰ ġߴٸ  ߸Ǿ
         αϿ  error_log .</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="jabberwock" id="jabberwock">ٽ ѹ ϶:  </a></h2>
    
        <p><strong>!</strong>      ִ.
        ġ׷ <a href="http://httpd.apache.org/docs/2.4/suexec.html">¶
        </a>   ֽ ϶.</p>
    
        <p>wrapper   ϴ  ̷ο  ִ.
        suEXEC õ "" ϱ  ̵ 캸 ٶ.</p>
    
        <ul>
          <li><strong>suEXEC  </strong></li>
    
          <li>
            丮  
    
            <p class="indent">
              Ȱ ȿ   suEXEC û ȣƮ
               ֻ document root Ȥ userdir û 
              ֻ  document root ȿ ߻ؾ Ѵ. 
              , ȣƮ װ ߴٸ ȣƮ
              suEXEC ̿ϱ ȣƮ document root
               ġ   ۿ  ʿ䰡 ִ.
              ( .)
            </p>
          </li>
    
          <li>
            suEXEC PATH ȯ溯
    
            <p class="indent">
              ϸ   ִ.  ⿡ ϴ  ΰ
              <strong>  ִ</strong> 丮 Ȯ϶. 
                 װ ִ Ʈ̸񸶸 ϱ
                ̴.
            </p>
          </li>
    
          <li>
            suEXEC ڵ ϱ
    
            <p class="indent">
              ݺؼ ,   ϴ 𸣰 õѴٸ
              <strong>ū </strong> ߻  ִ.  쿡
              .
            </p>
          </li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/urlmapping.html.tr.utf8����������������������������������������������������0000664�0001751�0001751�00000067731�14743132254�021427� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr" xml:lang="tr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>URL’lerin Dosya Sistemi ile Eşleştirilmesi - Apache HTTP Sunucusu Sürüm 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p>
    <p class="apache">Apache HTTP Sunucusu Sürüm 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Sunucusu</a> &gt; <a href="http://httpd.apache.org/docs/">Belgeleme</a> &gt; <a href="./">Sürüm 2.4</a></div><div id="page-content"><div id="preamble"><h1>URL’lerin Dosya Sistemi ile Eşleştirilmesi</h1>
    <div class="toplang">
    <p><span>Mevcut Diller: </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Bu belgede, bir istekte belirtilen URL’nin sunulacak dosyanın dosya
          sistemindeki yerini bulmak için Apache HTTP Sunucusu tarafından nasıl
          kullanıldığı açıklanmaktadır.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#related">İlgili Modüller ve Yönergeler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentroot"><code>DocumentRoot</code></a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#outside">Belge Kök Dizini Dışındaki Dosyalar</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#user">Kullanıcı Dizinleri</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#redirect">URL Yönlendirme</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Karşı Vekil</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">Yeniden Yazma Motoru</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#notfound">Dosya orada yok</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Diğer URL Eşleme Modülleri</a></li>
    </ul><h3>Ayrıca bakınız:</h3><ul class="seealso"><li><a href="#comments_section">Yorumlar</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">İlgili Modüller ve Yönergeler</a></h2>
    
    <table class="related"><tr><th>İlgili Modüller</th><th>İlgili Yönergeler</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></li><li><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code></li><li><code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code></li><li><code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_speling.html#checkspelling">CheckSpelling</a></code></li><li><code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="./mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentroot" id="documentroot"><code>DocumentRoot</code></a></h2>
    
        <p>Yapılan bir isteğe hangi dosyanın sunulacağına karar verirken
          httpd’nin öntanımlı davranışı istek için URL yolunu (URL’den konak ismi
          ve port ayrıldıktan sonra kalan kısım) alıp bunu yapılandırma dosyasında
          <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> yönergesi ile
          belirtilen dizinin sonuna eklemektir. Bu nedenle, <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> altındaki dizinler ve dosyalar
          sitenin dışardan görünen temel belge ağacını oluştururlar.</p>
    
        <p>Örneğin, <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> yönergesine
          <code>/var/http/html</code> atanmış olsun.
          <code>http://example.com/balıklar/zargana.html</code> şeklindeki bir
          istek için istemciye <code>/var/http/html/balıklar/zargana.html</code>
          dosyası sunulur.</p>
    
        <p>Bir dizin istenirse (<code>/</code> ile biten bir yol belirtilmesi
          durumu), sunulacak dosya <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code> yönergesinde belirtilen dosya olacaktır.
          Örneğin, <code>DocumentRoot</code> yukarıdaki gibi belirtimiş ve siz de
          şunu belirtmişseniz:</p>
    
        <div class="example"><p><code>DirectoryIndex index.html index.php</code></p></div>
    
        <p><code>http://www.example.com/fish/</code> isteği, httpd'nin
          <code>/var/www/html/fish/index.html</code> dosyasını sunmaya, bu dosya
          bulunmuyorsa <code>/var/www/html/fish/index.php</code> dosyasını sunmaya
          çalışmasına sebep olacaktır.</p>
    
        <p>Bu dosyaların ikisi de bulunmuyorsa sonraki adım,
          <code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code> yüklü ve uygun şekilde yapılandırılmışsa
          bir dizin içeriği dosyası sağlamaya çalışmak olacaktır.</p>
    
        <p>httpd ayrıca, sunucunun birden fazla konak için istek kabul etmesini
          sağlayan <a href="vhosts/">sanal barındırmaya</a> da muktedirdir. Bu
          durumda her sanal konak için ayrı bir <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> belirtilebileceği gibi sunulacak içeriğin
          istekte bulunulan IP adresi veya konak ismine dayanarak devingen olarak
          saptanmasını sağlayabilen <code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code> modülüyle
          gelen yönergeler de kullanılabilir.</p>
    
        <p><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> yönergesi
          yapılandırma dosyanızda ana sunucu için bir tane ve muhtemelen
          oluşturduğunuz her <a href="vhosts/">sanal konak</a> için de birer
          tanedir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="outside" id="outside">Belge Kök Dizini Dışındaki Dosyalar</a></h2>
    
        <p>Bazen dosya sisteminde doğrudan <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> altında bulunmayan dosyalara da erişim izni
          vermek gerekir. httpd’de bunu sağlamanın çeşitli yolları vardır. Unix
          sistemlerinde sembolik bağlar sayesinde dosya sisteminin farklı
          yerlerindeki dosyaları ve dizinleri <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> altındaymış gibi göstermek mümkündür.
          <code class="directive"><a href="./mod/core.html#options">Options</a></code> yönergesine değer olarak
          <code>FollowSymLinks</code> veya <code>SymLinksIfOwnerMatch</code>
          atanmadıkça httpd olası güvenlik açıklarına karşı öntanımlı olarak
          sembolik bağları izlemez.</p>
    
        <p>Bundan başka, dosya sisteminin farklı parçalarını belge kök dizini
          altında göstermek için <code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code>
          yönergesi de kullanılabilir. Örneğin,</p>
    
        <pre class="prettyprint lang-config">Alias "/belgeler" "/var/http"</pre>
    
    
        <p>yapılandırması ile
          <code>http://example.com/belgeler/dizin/dosya.html</code> URL’si için
          dosya sistemindeki <code>/var/http/dizin/dosya.html</code> dosyası
          sunulacaktır. Hedef dizindeki dosyaları birer <a class="glossarylink" href="./glossary.html#cgi" title="sözlüğe bakınız">CGI</a> betiği olarak imlemesi dışında <code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code> yönergesi de aynı şekilde
          çalışır.</p>
    
        <p>Biraz daha fazla esnekliğin gerektiği durumlarda  <a class="glossarylink" href="./glossary.html#regex" title="sözlüğe bakınız">düzenli ifadelere</a> dayalı eşleşmeler sağlamak
          üzere <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code> ve <code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code> yönergelerinin gücünden
          yararlanılabilir. Örneğin,</p>
    
        <pre class="prettyprint lang-config">ScriptAliasMatch "^/~([a-zA-Z0-9]+)/cgi-bin/(.+)" "/home/$1/cgi-bin/$2"</pre>
    
    
        <p>satırı sayesinde <code>http://example.com/~user/cgi-bin/betik.cgi</code>
          URL’si <code>/home/user/cgi-bin/betik.cgi</code> dosyası ile
          eşleştirilir ve dosya bir CGI betiği olarak çalıştırılırdı.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="user" id="user">Kullanıcı Dizinleri</a></h2>
    
        <p>Geleneksel olarak Unix sistemlerinde belli bir kullanıcının (örn,
          <em>birisi</em>) ev dizinine <code>~birisi/</code> şeklinde atıfta
          bulunulabilir. <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> modülü bu özelliği site
          üzerinden kullanıcıların ev dizinlerindeki dosyaları kişisel sayfalar
          olarak sunmalarını sağlamak üzere kullanır. Örnek:</p>
    
        <div class="example"><p><code>http://example.com/~birisi/dosya.html</code></p></div>
    
        <p>Güvenlik sebebiyle kullanıcıların ev dizinlerine doğrudan HTTP erişimi
          vermek uygun olmaz. Bu bakımdan, kullanıcının ev dizini altında HTTP
          erişimi verilecek dosyaların bulunduğu dizini belirtmek için <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> yönergesi sağlanmıştır.
          Öntanımlı olan <code>Userdir public_html</code> yapılandırması ile
          yukarıdaki gibi bir URL kullanıcının ev dizini (<code>/etc/passwd</code>
          dosyasında belirtilir) <code>/home/birisi/</code> altında yer alan
          <code>/home/birisi/public_html/dosya.html</code> dosyası ile
          eşleşirdi.</p>
    
        <p>Ev dizininin yerinin <code>/etc/passwd</code> dosyasında belirtilmediği
          sistemlerde kullanılmak üzere <code>Userdir</code> yönergesinin başka
          kullanım şekilleri de vardır.</p>
    
        <p>Bazı kişiler (genellikle URL üzerinde <code>%7e</code> olarak
          kodlanması sebebiyle) "~" simgesini biçimsiz bulabilir ve kullanıcı
          dizinlerini imlemek için başka bir karakter kullanmayı tercih
          edebilirler. Bu işlevsellik <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> tarafından
          desteklenmemektedir. Ancak, kullanıcı dizinleri düzgün şekilde
          yapılandırılmışsa istenen etki <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code> yönergesi ile sağlanabilir.
          Örneğin, <code>http://example.com/sayfalar/birisi/dosya.html</code>
          URL’si ile <code>/home/birisi/public_html/dosya.html</code> dosyasını
          eşlemek için <code>AliasMatch</code> yönergesi şöyle
          kullanılabilirdi:</p>
    
        <pre class="prettyprint lang-config">AliasMatch "^/sayfalar/([a-zA-Z0-9]+)(/(.*))?$" "/home/$1/public_html/$3"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">URL Yönlendirme</a></h2>
    
        <p>Yukarıdaki bölümlerde açıklanan yapılandırma yönergeleri httpd’ye
          içeriği dosya sisteminin belli bir yerinden alıp istemciye göndermesini
          söyler. Bazen istemciye, istediği içeriğe farklı bir URL ile
          erişebileceğini ve bu URL için ayrı bir istek yapması gerektiğini
          bildirmek gerekir. Bu işleme <em>yönlendirme</em> adı verilir ve bu
          işlevsellik <code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code> yönergesi
          ile sağlanır. Örneğin, <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
          altındaki <code>/foo/</code> dizininin içeriğinin <code>/bar/</code>
          adında yeni bir dizine taşınması halinde istemciye yeni konumun
          bildirilmesi şöyle sağlanabilirdi:</p>
    
        <pre class="prettyprint lang-config">Redirect permanent "/foo/" "http://example.com/bar/"</pre>
    
    
        <p>Bu atama sayesinde <code>/foo/</code> ile başlayan URL yolları
          <code>example.com</code> sunucundaki <code>/bar/</code> dizini altındaki
          içeriğe yönlendirilmektedir. Yönlendirmeyi aynı sunucu üzerinde yapmak
          zorunda değilsiniz, bu yönerge ile başka bir sunucuya da yönlendirme
          yapabilirsiniz.</p>
    
        <p>httpd ayrıca, yeniden yazma ile ilgili daha karmaşık sorunlara çözüm
          olarak <code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> diye bir
          yönerge daha sağlar. Örneğin bir sitenin baş sayfasını diğer isteklerden
          ayrı olarak farklı bir siteye yönlendirmek için yönergeyi şöyle
          kullanabilirsiniz:</p>
    
        <pre class="prettyprint lang-config">RedirectMatch permanent "^/$" "http://example.com/ilksayfa.html"</pre>
    
    
        <p>Bundan başka, bir sitedeki tüm sayfalara yapılan istekleri başka bir
          siteye geçici olarak yönlendirmek için şöyle bir şey yapabilirsiniz:</p>
    
        <pre class="prettyprint lang-config">RedirectMatch temp ".*" "http://mesela.example.com/ilksayfa.html"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Karşı Vekil</a></h2>
    
        <p>httpd ayrıca, uzak sunuculardaki belgelerin yerel sunucunun URL
          alanına getirilmesini de mümkün kılar. Bu tekniğe HTTP sunucunun
          belgeleri uzak bir sunucudan alıp istemciye sunmasını sağlayarak bir
          vekil sunucu gibi davranması nedeniyle <em>ters vekalet</em> adı
          verilir. Belgelerin istemciye özkaynağın bulunduğu sunucudan
          geliyormuş gibi değilde doğrudan isteği yaptığı sunucudan geliyormuş
          gibi sunulması nedeniyle bu işlem normal vekaletten farklıdır.</p>
    
        <p>Aşağıdaki örnekte, istemci <code>/foo/</code> dizini altından bir belge
          istemekte, sunucu ise bu belgeyi <code>dahili.example.com</code>
          üzerindeki <code>/bar/</code> dizininden alıp istemciye yerel sunucudan
          geliyormuş gibi sunmaktadır:</p>
    
        <pre class="prettyprint lang-config">ProxyPass "/foo/" "http://dahili.example.com/bar/"
    ProxyPassReverse "/foo/" "http://dahili.example.com/bar/"
    ProxyPassReverseCookieDomain dahili.example.com harici.example.com
    ProxyPassReverseCookiePath "/foo/" "/bar/"</pre>
    
    
        <p><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> sunucuyu uygun
          belgeleri alması için yapılandırırken <code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> yönergesi <code>dahili.example.com</code>
          sunucusundan kaynaklanan yönlendirmeleri yeniden yazar, böylece bunların
          yerel sunucudaki yerleri belirlenmiş olur. Benzer şekilde,  <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code> ve
          <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code>
          yönergeleri de arka sunucu tarafından atanan çerezleri yeniden yazar.</p>
    
        <p>Yalnız, belgelerin içindeki hiperbağların yeniden yazılmayacağına
          dikkat ediniz. Dolayısıyla, belge içinde
          <code>dahili.example.com</code>’u ismiyle hedef alan mutlak hiperbağlar
          varsa bunlar istemci tarafından vekil sunucudan değil doğrudan
          <code>dahili.example.com</code>’dan istenecektir. Bir sayfanın içindeki bu
          bağları (ve diğer içeriği) <code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code> modülü
          kullanılarak istemciye sunuluyormuşçasına değiştirebilirsiniz.</p>
    
        <pre class="prettyprint lang-config">Substitute "s/dahili\.example\.com/harici.example.com/i"</pre>
    
    
         <p>HTML ve XHTML’de hiperbağları daha bilgece yeniden yazabilen
          <code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code> modülü de kullanılabilir. Yeniden
          yazılması gereken URL eşlemlerini oluşturmanızı sağlar, böylece karmaşık
          vekil senaryoları oluşturulabilir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Yeniden Yazma Motoru</a></h2>
    
        <p>Daha güçlü ikameler gerektiğinde <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> modülü
          tarafından sağlanan yeniden yazma motoru işe yarayabilir. Bu modüldeki
          yönergeler sunulacak içeriğin yerine karar vermek için kaynak IP adresi,
          tarayıcı türü gibi isteğe özgü özellikleri kullanırlar.
          <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> modülü buna ek olarak isteğin nasıl ele
          alınacağına karar vermek için harici yazılımları ve veritabanlarını
          kullanabilir. Yeniden yazma motoru yukarıda değinilen üç eşleşme türünü
          de uygulayabilecek yetenektedir: Dahili yönlendirmeler (rumuzlar),
          harici yönlendirmeler ve vekalet. <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> modülü
          tarafından sağlanan yeteneklerin ayrıntılı açıklamaları ve bunların
          kullanım örnekleri ayrıntılı olarak <a href="rewrite/">mod_rewrite
          belgeleri</a>nde bulunmaktadır.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="notfound" id="notfound">Dosya orada yok</a></h2>
    
        <p>Kaçınılmaz olarak, dosya sisteminde mevcut olmayan dosyalar için de
          istek yapılacaktır. Bunun çeşitli sebepleri olabilir.  Bazı durumlarda
          bu, belgelerin yerlerininin değiştirilmesinin bir sonucu olabilir. Bu
          durumda yapılacak en iyi şey, istemciyi belgeyi yeni yerinden istemesi
          için bilgilendirmek amacıyla  <a href="#redirect">URL yönlendirmesi</a>
          kullanmaktır. Bu şekilde, içeriğin yeri değişse bile eski yer imlerinin
          ve hiperbağların çalışmaya devam edeceklerinden emin olabilirsiniz.</p>
    
        <p>"Dosya orada yok" ("File Not Found") hatalarının diğer bir bildik
          sebebi de URL’lerin hiperbağlarda veya doğrudan tarayıcıda kasıtlı ya da
          kasıtsız, yanlış yazılmasıdır. Bu tür sorunlarda yardımcı olması için
          httpd <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> (sic) adında bir modülle gelir. Bu
          modül etkin kılındığında htpd, "Dosya orada yok" ("File Not Found")
          hatalarının önünü kesip başka bir yerde benzer isimde bir dosya var mı
          diye bakar. Böyle bir dosya varsa, <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code>
          istemciye dosyanın doğru yerini bildiren bir HTTP yönlendirmesi yollar.
          Benzer çok sayıda dosya varsa bunlar istemciye bir liste halinde
          sunulur.</p>
    
        <p><code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> modülünün en yararlı özelliklerinden biri
          de dosya isimlerini harf büyüklüğüne duyarsız olarak arayabilmesidir.
          Dosya isimlerinde harf büyüklüğünün önemli olduğu Unix benzeri sistemler
          hakkında bilgisi olmayan kullanıcılara sahip sistemlerin kullanıcılarına
          bu büyük yarar sağlar. Fakat modülün URL düzeltmekten başka şeyler için
          de kullanılması, istemcilerden gelen neredeyse her isteğin URL
          yönlendirmesine konu olmasına sebep olarak sunucunun yükünü
          arttırabilir.</p>
    
        <p><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code> modülü sanal URI'leri, onları sunan gerçek
          kaynağa eşlemekte kullanılan <code class="directive"><a href="./mod/mod_dir.html#fallbackresource">FallbackResource</a></code> yönergesini içerir. Bir 'ön denetleyici'
          gerçeklerken <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> modülünün kullanılmasını
          sağlamak için çok kullanışlıdır.</p>
    
        <p>Yerinde bulunmayan içeriğin bulunması çabalarının tümü Apache’nin 404
          (Dosya orada yok) HTTP durum kodlu bir hata sayfası döndürmesine yol
          açar. Bu sayfanın içeriği <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> yönergesi ile denetlenebilir ve <a href="custom-error.html">Hata Yanıtlarının Kişiselleştirilmesi</a>
          bölümünde anlatıldığı gibi oldukça esnek bir şekilde
          kişiselleştirilebilir.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Diğer URL Eşleme Modülleri</a></h2>
    
    
    
        <p>URL eşlemede kullanılabilecek diğer modüller:</p>
    
        <ul>
        <li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code> - Bir isteği, özkaynağın MIME türüne veya
          istek yöntemine bakarak bir CGI betiğine eşler.</li>
    
        <li><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code> - URL'yi sonlandıran bölü çizgisini
          <code>index.html</code> bir dosyaya eşler.</li>
    
        <li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code> - Bir isteği, bir HTML belge içindeki
          bir resme yapılan kullanıcı tıklamalarına dayanarak bir URL'ye
          eşler.</li>
    
        <li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> - Dil veya içerik sıkıştırması gibi
          kullanıcı tercihlerine dayanarak uygun bir belgeyi seçer.</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Mevcut Diller: </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Yorumlar</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/urlmapping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br /><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> altında lisanslıdır.</p>
    <p class="menu"><a href="./mod/">Modüller</a> | <a href="./mod/directives.html">Yönergeler</a> | <a href="http://wiki.apache.org/httpd/FAQ">SSS</a> | <a href="./glossary.html">Terimler</a> | <a href="./sitemap.html">Site Haritası</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������httpd-2.4.64/docs/manual/content-negotiation.html.fr.utf8�������������������������������������������0000664�0001751�0001751�00000116272�14740503670�023217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Négociation de contenu - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Négociation de contenu</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Apache HTTPD prend en charge la négociation de
        contenu telle qu'elle est décrite
        dans la spécification HTTP/1.1. Il peut choisir la meilleure représentation
        d'une ressource en fonction des préférences du navigateur pour ce qui
        concerne le type de media, les langages, le jeu de caractères et son
        encodage. Il implémente aussi quelques fonctionnalités pour traiter de
        manière plus intelligente les requêtes en provenance de navigateurs qui
        envoient des informations de négociation incomplètes.</p>
    
        <p>La négociation de contenu est assurée par le module
        <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> qui est compilé par défaut
        dans le serveur.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#about">À propos de la négociation de contenu</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#negotiation">La négociation avec httpd</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#methods">Les méthodes de négociation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#better">Ajustement des valeurs de qualité</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extensions">Extensions à la négociation de contenu
    transparente</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#naming">Remarques à propos des liens hypertextes et des
    conventions de nommage</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#caching">Remarque sur la mise en cache</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="about" id="about">À propos de la négociation de contenu</a></h2>
    
        <p>Une ressource peut être disponible selon différentes représentations.
        Par exemple, elle peut être disponible en différents langages ou pour
        différents types de média, ou une combinaison des deux.
        Pour faire le meilleur choix, on peut fournir à l'utilisateur une page
        d'index, et le laisser choisir. Cependant, le serveur peut souvent faire
        ce choix automatiquement. Cela est possible car les navigateurs peuvent
        envoyer des informations sur les
        représentations qu'ils préfèrent à l'intérieur de chaque requête.
        Par exemple, un navigateur peut indiquer
        qu'il préfère voir les informations en français, mais qu'en cas
        d'impossibilité l'anglais peut convenir. Les navigateurs indiquent leurs
        préférences à l'aide d'en-têtes dans la requête. Pour ne demander que des
        représentations en français, le navigateur peut utiliser l'en-tête :</p>
    
    <div class="example"><p><code>Accept-Language: fr</code></p></div>
    
        <p>Notez qu'il ne sera tenu compte de cette préférence que s'il existe un
        choix de représentations et que ces dernières varient en fonction
        du langage.</p>
    
        <p>À titre d'exemple d'une requête plus complexe, ce navigateur a été
        configuré pour accepter le français et l'anglais, avec une préférence pour
        le français, et accepter différents types de média, avec une préférence
        pour HTML par rapport à au texte plat («&nbsp;plain text&nbsp;») ou autres types de fichiers texte, et
        avec une préférence pour GIF ou JPEG par rapport à tout autre type de
        média, mais autorisant tout autre type de média en dernier ressort :</p>
    
    <div class="example"><p><code>
      Accept-Language: fr; q=1.0, en; q=0.5<br />
      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
    </code></p></div>
    
        <p>httpd prend en charge la négociation de contenu «&nbsp;server driven&nbsp;» (telle qu'elle
        est définie dans la spécification HTTP/1.1), où c'est le serveur qui
        décide quelle est la meilleure représentation à renvoyer pour la ressource
        demandée. Il prend entièrement en charge les en-têtes de requête
        <code>Accept</code>, <code>Accept-Language</code>,
        <code>Accept-Charset</code> et <code>Accept-Encoding</code>.
        httpd prend aussi en charge la négociation de contenu transparente, qui est un
        protocole de négociation expérimental défini dans les RFC 2295 et 2296.
        Il ne prend pas en charge la négociation de fonctionnalité (feature negotiation)
        telle qu'elle est définie dans ces RFCs.</p>
    
        <p>Une <strong>ressource</strong> est une entité conceptuelle identifiée
        par un URI (RFC 2396). Un serveur HTTP comme le serveur HTTP Apache
        propose l'accès à des
        <strong>représentations</strong> de la ressource à l'intérieur de son
        espace de nommage, chaque représentation étant composée d'une séquence
        d'octets avec la définition d'un type de media, d'un jeu de caractères,
        d'un encodage, etc. À un instant donné, chaque ressource peut être
        associée avec zéro, une ou plusieurs représentations. Si plusieurs
        représentations sont disponibles, la ressource est qualifiée de
        <strong>négociable</strong> et chacune de ses représentations se nomme
        <strong>variante</strong>. Les différences entre les
        variantes disponibles d'une ressource négociable constituent les
        <strong>dimensions</strong> de la négociation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="negotiation" id="negotiation">La négociation avec httpd</a></h2>
    
        <p>Pour négocier une ressource, on doit fournir au serveur des
        informations à propos de chacune des variantes. Il y a deux manières
        d'y parvenir :</p>
    
        <ul>
          <li>Utiliser une liste de correspondances de type («&nbsp;type-map&nbsp;») (<em>c'est à dire</em>
          un fichier <code>*.var</code>) qui nomme explicitement les fichiers
          contenant les variantes, ou</li>
    
          <li>Utiliser une recherche «&nbsp;multivues&nbsp;», où le serveur effectue une
          recherche de correspondance sur un motif de nom de fichier implicite et
          fait son choix parmi les différents résultats.</li>
        </ul>
    
       <h3><a name="type-map" id="type-map">Utilisation d'un fichier de
       correspondances de types (type-map)</a></h3>
    
        <p>Une liste de correspondances de types est un document associé au
        gestionnaire <code>type-map</code> (ou, dans un souci de compatibilité
        ascendante avec des configurations de httpd plus anciennes, le
        <a class="glossarylink" href="./glossary.html#type mime" title="voir glossaire">type MIME</a>
        <code>application/x-type-map</code>). Notez que pour utiliser cette
        fonctionnalité, vous devez, dans le fichier de configuration, définir un
        gestionnaire qui associe un suffixe de fichier à une <code>type-map</code>,
        ce qui se fait simplement en ajoutant</p>
    
    <pre class="prettyprint lang-config">AddHandler type-map .var</pre>
    
    
        <p>dans le fichier de configuration du serveur.</p>
    
        <p>Les fichiers de correspondances de types doivent posséder le même nom que
        la ressource qu'ils décrivent, avec pour extension
        <code>.var</code>. Dans l'exemple ci-dessous, la ressource a pour
        nom <code>foo</code>, et le fichier de correspondances se nomme donc
        <code>foo.var</code>.</p>
    
        <p>Ce fichier doit comporter une entrée pour chaque variante
        disponible ; chaque entrée consiste en une ligne contiguë d'en-têtes au
        format HTTP. Les entrées sont séparées par des lignes vides. Les lignes
        vides à l'intérieur d'une entrée sont interdites. Par convention, le
        fichier de correspondances de types débute par une entrée concernant l'entité
        considérée dans son ensemble (bien que ce ne soit pas obligatoire, et
        ignoré si présent). Un exemple de fichier de
        correspondances de types est fourni
        ci-dessous.</p>
    
        <p>Les URIs de ce fichier sont relatifs à la localisation du fichier
        de correspondances de types. En général, ces fichiers se trouveront dans le
        même répertoire que le fichier de correspondances de types, mais ce
        n'est pas obligatoire. Vous pouvez utiliser des URIs absolus ou
        relatifs pour tout fichier situé sur le même serveur que le fichier
        de correspondances.</p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.en.html<br />
      Content-type: text/html<br />
      Content-language: en<br />
    <br />
      URI: foo.fr.de.html<br />
      Content-type: text/html;charset=iso-8859-2<br />
      Content-language: fr, de<br />
    </code></p></div>
    
        <p>Notez aussi qu'un fichier de correspondances de types prend le pas sur
        les extensions de noms de fichiers, même si les Multivues sont activées.
        Si les variantes sont de qualités différentes, on doit l'indiquer
        à l'aide du paramètre «&nbsp;qs&nbsp;» à la suite du type de média, comme pour cette
        image
        (disponible aux formats JPEG, GIF, ou ASCII-art) : </p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.jpeg<br />
      Content-type: image/jpeg; qs=0.8<br />
    <br />
      URI: foo.gif<br />
      Content-type: image/gif; qs=0.5<br />
    <br />
      URI: foo.txt<br />
      Content-type: text/plain; qs=0.01<br />
    </code></p></div>
    
        <p>Les valeurs de qs peuvent varier de 0.000 à 1.000. Notez que toute
        variante possédant une valeur de qs de 0.000 ne sera jamais choisie.
        Les variantes qui n'ont pas de paramètre qs défini se voient attribuer
        une valeur de 1.0. Le paramètre qs indique la qualité relative de la
        variante comparée à celle des autres variantes disponibles, sans tenir
        compte des capacités du client. Par exemple, un fichier JPEG possède
        en général une qualité supérieure à celle d'un fichier ASCII s'il
        représente une photographie. Cependant, si la ressource représentée est
        un ASCII art original, la représentation ASCII sera de meilleure qualité
        que la représentation JPEG. Ainsi une valeur de qs est associée à une
        variante en fonction de la nature de la ressource qu'elle représente.</p>
    
        <p>La liste complète des en-têtes reconnus est disponible dans la
        documentation sur les <a href="mod/mod_negotiation.html#typemaps">correspondances de types du
        module mod_negotiation</a>.</p>
    
    
    <h3><a name="multiviews" id="multiviews">Multivues (option Multiviews)</a></h3>
    
        <p><code>MultiViews</code> est une option qui s'applique à un répertoire,
        ce qui signifie qu'elle peut être activée à l'aide d'une directive
        <code class="directive"><a href="./mod/core.html#options">Options</a></code> à l'intérieur d'une section
        <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> ou <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> dans
        <code>httpd.conf</code>, ou (si <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> est correctement positionnée) dans
        des fichiers
        <code>.htaccess</code>. Notez que <code>Options All</code>
        n'active pas <code>MultiViews</code> ; vous devez activer cette option en
        la nommant explicitement.</p>
    
        <p>L'effet de <code>MultiViews</code> est le suivant : si le serveur reçoit
        une requête pour <code>/tel/répertoire/foo</code>, si
        <code>MultiViews</code> est activée pour
        <code>/tel/répertoire</code> et si
        <code>/tel/répertoire/foo</code> n'existe <em>pas</em>, le serveur parcourt
        le répertoire à la recherche de fichiers nommés foo.*, et simule
        littéralement une correspondance de types (type map) qui liste tous ces
        fichiers, en leur associant les mêmes types de média et encodages de
        contenu qu'ils auraient eu si le client avait demandé l'accès à l'un
        d'entre eux par son nom. Il choisit ensuite ce qui correspond le mieux
        aux besoins du client.</p>
    
        <p><code>MultiViews</code> peut aussi s'appliquer à la recherche du fichier
        nommé par la directive <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>, si le serveur tente d'indexer
        un répertoire. Si les fichiers de configuration spécifient</p>
    <pre class="prettyprint lang-config">DirectoryIndex index</pre>
    
        <p>le serveur va choisir entre <code>index.html</code>
        et <code>index.html3</code> si les deux fichiers sont présents. Si aucun
        n'est présent, alors qu’<code>index.cgi</code> existe,
        le serveur l'exécutera.</p>
    
        <p>Si, parcequ'elle n'est pas reconnue par <code>mod_mime</code>,
        l'extension d'un des fichiers du répertoire ne permet pas de
        déterminer son jeu de caractères, son type de contenu, son langage, ou son
        encodage,
        le résultat dépendra de la définition de la directive <code class="directive"><a href="./mod/mod_mime.html#multiviewsmatch">MultiViewsMatch</a></code>. Cette directive détermine
        si les gestionnaires (handlers), les filtres et autres types d'extensions
        peuvent participer à la négociation MultiVues.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="methods" id="methods">Les méthodes de négociation</a></h2>
    
        <p>Une fois obtenue la liste des variantes pour une ressource donnée,
        httpd dispose de deux méthodes pour choisir la meilleure variante à
        renvoyer, s'il y a lieu, soit à partir d'un fichier de
        correspondances de types, soit en se basant sur les noms de fichier du
        répertoire. Il n'est pas nécessaire de connaître en détails comment la
        négociation fonctionne réellement pour pouvoir utiliser les fonctionnalités
        de négociation de contenu de httpd. La suite de ce document explique
        cependant les méthodes utilisées pour ceux ou celles qui sont
        intéressés(ées). </p>
    
        <p>Il existe deux méthodes de négociation :</p>
    
        <ol>
          <li><strong>La négociation effectuée par le serveur selon l'algorithme
          de httpd</strong> est utilisée par défaut. L'algorithme de
          httpd est
          expliqué plus en détails ci-dessous. Quand cet algorithme est utilisé,
          httpd peut parfois «&nbsp;bricoler&nbsp;» le facteur de qualité (qs) d'une dimension
          particulière afin d'obtenir un meilleur résultat.
          La manière dont httpd peut modifier les facteurs de qualité est
          expliquée plus en détails ci-dessous.</li>
    
          <li><strong>La négociation de contenu transparente</strong> est utilisée
          quand le navigateur le demande explicitement selon le mécanisme défini
          dans la RFC 2295. Cette méthode de négociation donne au navigateur le
          contrôle total du choix de la meilleure variante ; le résultat dépend
          cependant de la spécificité des algorithmes utilisés par le navigateur.
          Au cours du processus de négociation transparente, le navigateur peut
          demander à httpd d'exécuter l'«&nbsp;algorithme de sélection de variante à
          distance&nbsp;» défini dans la RFC 2296.</li>
        </ol>
    
    <h3><a name="dimensions" id="dimensions">Les dimensions de la négociation</a></h3>
    
        <table>
          
          <tr valign="top">
            <th>Dimension</th>
    
            <th>Notes</th>
          </tr>
    
          <tr valign="top">
            <td>Type de média</td>
    
            <td>Le navigateur affiche ses préférences à l'aide du champ d'en-tête
    	<code>Accept</code>. Chaque type de média peut se voir associé un facteur de
    	qualité. La description de la variante peut aussi avoir un facteur de
    	qualité (le paramètre «&nbsp;qs&nbsp;»).</td>
          </tr>
    
          <tr valign="top">
            <td>Langage</td>
    
            <td>Le navigateur affiche ses préférences à l'aide du champ d'en-tête
            <code>Accept-Language</code>. Chaque langue peut se voir associé un facteur de
    	qualité. Les variantes peuvent être associées avec zéro, un ou
    	plusieurs langages.</td>
          </tr>
    
          <tr valign="top">
            <td>Encodage</td>
    
            <td>Le navigateur affiche ses préférences à l'aide du champ d'en-tête
            <code>Accept-Encoding</code>. Chaque encodage peut se voir associé un facteur de
    	qualité.</td>
          </tr>
    
          <tr valign="top">
            <td>Jeu de caractères</td>
    
            <td>Le navigateur affiche ses préférences à l'aide du champ d'en-tête
            <code>Accept-Charset</code>. Chaque jeu de caractère peut se voir associé un facteur de
    	qualité. Les variantes peuvent préciser un jeu de caractères comme
    	paramètre du type de média.</td>
          </tr>
        </table>
    
    
    <h3><a name="algorithm" id="algorithm">L'algorithme de négociation de
    httpd</a></h3>
    
        <p>httpd peut utiliser l'algorithme suivant pour choisir la «&nbsp;meilleure&nbsp;»
        variante (s'il y en a une) à renvoyer au navigateur. Cet algorithme n'est pas
        configurable. Il fonctionne comme suit :</p>
    
        <ol>
          <li>En premier lieu, pour chaque dimension de la négociation, consulter
          le champ d'en-tête <em>Accept*</em> approprié et assigner une qualité à
          chaque variante. Si l'en-tête <em>Accept*</em> pour toute dimension
          implique que la variante n'est pas acceptable, éliminer cette dernière.
          S'il ne reste plus de variante, aller à l'étape 4.</li>
    
          <li>
            Choisir la «&nbsp;meilleure&nbsp;» variante par élimination. Chacun des tests
    	suivants est effectué dans cet ordre. Toute variante non sélectionnée
    	à l'issue d'un test est éliminée. Après chaque test, s'il reste une
    	seule variante, choisir cette dernière comme celle qui correspond le
    	mieux puis aller à l'étape 3. S'il reste plusieurs variantes, passer
    	au test suivant.
    
            <ol>
              <li>Multiplier le facteur de qualité de l'en-tête
    	  <code>Accept</code> par le facteur de qualité «&nbsp;qs&nbsp;» pour le type de
    	  média de ces variantes, et choisir la variante qui possède la valeur
    	  la plus importante.</li>
    
              <li>Sélectionner les variantes qui possèdent le facteur de qualité
    	  de langage le plus haut.</li>
    
              <li>Sélectionner les variantes dont le langage correspond le mieux,
              en se basant sur l'ordre des langages de l'en-tête
              <code>Accept-Language</code> (s'il existe), ou de la directive
    	  <code>LanguagePriority</code> (si elle existe).</li>
    
              <li>Sélectionner les variantes possédant le paramètre de média
    	  «&nbsp;level&nbsp;» le plus élevé (utilisé pour préciser la version des types de
    	  média text/html).</li>
    
              <li>Sélectionner les variantes possédant le paramètre de média
    	  «&nbsp;charset&nbsp;» (jeu de caractères) qui correspond le mieux, en se basant
    	  sur la ligne d'en-tête <code>Accept-Charset</code> . Le jeu de
    	  caractères ISO-8859-1 est acceptable sauf s'il est explicitement
    	  exclus. Les variantes avec un type de média <code>text/*</code>
              mais non explicitement associées avec un jeu de caractères
    	  particulier sont supposées être en ISO-8859-1.</li>
    
              <li>Sélectionner les variantes dont le paramètre de média «&nbsp;charset&nbsp;»
    	  associé n'est <em>pas</em> ISO-8859-1. S'il n'en existe pas,
    	  sélectionner toutes les variantes.</li>
    
              <li>Sélectionner les variantes avec le meilleur encodage. S'il existe
    	  des variantes avec un encodage acceptable pour le client,
    	  sélectionner celles-ci. Sinon, s'il existe des variantes encodées et
    	  des variantes non encodées, ne sélectionner que les variantes non
    	  encodées. Si toutes les variantes sont encodées ou si aucune
    	  ne l'est, sélectionner toutes les variantes.</li>
    
              <li>Sélectionner les variantes dont le contenu a la longueur
    	  la plus courte.</li>
    
              <li>Sélectionner la première des variantes restantes. Il s'agira
    	  soit de la première variante listée dans le fichier de
    	  correspondances de types, soit, quand les variantes sont lues depuis
    	  le répertoire, la première par ordre alphabétique quand elles sont
    	  triées selon le code ASCII.</li>
            </ol>
          </li>
    
          <li>L'algorithme a maintenant sélectionné une variante considérée comme
          la «&nbsp;meilleure&nbsp;», il la renvoie donc au client en guise de réponse.
          L'en-tête HTTP <code>Vary</code> de la réponse est renseigné de façon à
          indiquer les dimensions de la négociation (les navigateurs et les caches
          peuvent utiliser cette information lors de la mise en cache de la
          ressource).  Travail terminé.</li>
    
          <li>Le passage par cette étape signifie qu'aucune variante n'a été
          sélectionnée (parce qu'aucune n'est acceptable pour le navigateur).
          Envoyer une réponse avec un code de statut 406 (qui signifie «&nbsp;Aucune
          représentation acceptable&nbsp;») et un corps comportant un document HTML qui
          affiche les variantes disponibles. Renseigner aussi l'en-tête HTTP
          <code>Vary</code> de façon à indiquer les dimensions de la variante.</li>
        </ol>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="better" id="better">Ajustement des valeurs de qualité</a></h2>
    
        <p>Parfois httpd modifie les valeurs de qualité par rapport à celles qui
        découleraient d'une stricte interprétation de l'algorithme de négociation
        de httpd ci-dessus, cela afin d’améliorer les résultats de l'algorithme pour
        les navigateurs qui envoient des informations incomplètes ou inappropriées.
        Certains des navigateurs les plus populaires envoient des informations dans
        l'en-tête <code>Accept</code> qui, sans ce traitement, provoqueraient la
        sélection d'une variante inappropriée dans de nombreux cas. Quand un
        navigateur envoie des informations complètes et correctes ces ajustements
        ne sont pas effectués.</p>
    
    <h3><a name="wildcards" id="wildcards">Types de média et caractères génériques</a></h3>
    
        <p>L'en-tête de requête <code>Accept:</code> indique les types de média
        souhaités. Il peut aussi contenir des types de média avec caractères
        génériques, comme «&nbsp;image/*&nbsp;» ou «&nbsp;*/*&nbsp;» où * correspond à n'importe quelle
        chaîne de caractères. Ainsi une requête contenant :</p>
    
    <div class="example"><p><code>Accept: image/*, */*</code></p></div>
    
        <p>indiquerait que tout type de média est acceptable, avec une préférence
        pour les types commençant par «&nbsp;image/&nbsp;».
        Certains navigateurs ajoutent par défaut des types de média avec caractères
        génériques aux types explicitement nommés qu'ils peuvent gérer.
        Par exemple :</p>
    
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*
    </code></p></div>
        <p>Cela indique que les types explicitement listés sont préférés, mais
        qu'une représentation avec un type différent de ces derniers conviendra
        aussi.  Les valeurs de qualités explicites,
        afin de préciser ce que veut vraiment le navigateur, s'utilisent
        comme suit :</p>
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
    </code></p></div>
        <p>Les types explicites n'ont pas de facteur de qualité, la valeur par
        défaut de leur préférence est donc de 1.0 (la plus haute). Le type avec
        caractères génériques */* se voit attribuer une préférence basse de 0.01,
        si bien que les types autres que ceux explicitement listés ne seront
        renvoyés
        que s'il n'existe pas de variante correspondant à un type explicitement
        listé.</p>
    
        <p>Si l'en-tête <code>Accept:</code> ne contient <em>pas</em> de
        facteur de qualité, httpd positionne la valeur de qualité de
        «&nbsp;*/*&nbsp;», si présent, à 0.01 pour simuler l'effet désiré. Il positionne aussi
        la valeur de qualité des types avec caractères génériques au format
        «&nbsp;type/*&nbsp;» à 0.02 (ils sont donc préférés à ceux correspondant à «&nbsp;*/*&nbsp;»). Si
        un type de média dans l'en-tête <code>Accept:</code> contient un facteur de
        qualité, ces valeurs spéciales ne seront <em>pas</em> appliquées, de façon
        à ce que les requêtes de navigateurs qui envoient les informations
        explicites à prendre en compte fonctionnent comme souhaité.</p>
    
    
    <h3><a name="exceptions" id="exceptions">Exceptions dans la négociation du
    langage</a></h3>
    
        <p>A partir de la version 2.0 de httpd, certaines exceptions ont été
        ajoutées à l'algorithme de négociation afin de ménager une issue de secours
        quand la négociation ne trouve aucun langage correspondant.</p>
    
        <p>Quand un client demande une page sur votre serveur, si ce dernier ne
        parvient pas à trouver une page dont la langue correspond à l'en-tête
        <code>Accept-language</code> envoyé par le navigateur, il enverra au client
        une réponse «&nbsp;Aucune variante acceptable&nbsp;» ou «&nbsp;Plusieurs choix possibles&nbsp;».
        Pour éviter ces
        messages d'erreur, il est possible de configurer httpd de façon que,
        dans ces cas, il ignore l'en-tête <code>Accept-language</code> et fournisse
        tout de même un document, même s'il ne correspond pas exactement à la
        demande explicite du client. La directive <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>
        peut être utilisée pour éviter ces messages d'erreur et leur substituer une
        page dont le langage sera déterminé en fonction du contenu de la directive
        <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>.</p>
    
        <p>Le serveur va aussi essayer d'étendre sa recherche de correspondance aux
        sous-ensembles de langages quand aucune correspondance exacte ne peut être
        trouvée. Par exemple, si un client demande des documents possédant le
        langage <code>en-GB</code>, c'est à dire anglais britannique, le standard
        HTTP/1.1 n'autorise normalement pas le serveur à faire correspondre cette
        demande à un document dont le langage est simplement <code>en</code>
        (notez qu'inclure <code>en-GB</code> et non <code>en</code> dans l'en-tête
        <code>Accept-Language</code> constitue une quasi-erreur de configuration,
        car il est très peu probable qu'un lecteur qui comprend l'anglais
        britannique, ne comprenne pas l'anglais en général. Malheureusement, de
        nombreux clients ont réellement des configurations par défaut de ce type).
        Cependant, si aucune autre correspondance de langage n'est possible, et si le
        serveur est sur le point de renvoyer une erreur «&nbsp;Aucune variable
        acceptable&nbsp;» ou de choisir le langage défini par la directive <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>, le serveur ignorera
        la spécification du sous-ensemble de langage et associera la demande en
        <code>en-GB</code> à des documents en <code>en</code>.  Implicitement,
        httpd ajoute le langage parent à la liste de langages acceptés par le
        client avec une valeur de qualité très basse. Notez cependant que si le
        client demande «&nbsp;en-GB; q=0.9, fr; q=0.8&nbsp;», et si le serveur dispose de
        documents estampillés «&nbsp;en&nbsp;» et «&nbsp;fr&nbsp;», c'est le document «&nbsp;fr&nbsp;» qui sera
        renvoyé, tout cela dans un souci de compatibilité avec la spécification
        HTTP/1.1 et afin de fonctionner efficacement avec les clients
        correctement configurés.</p>
    
        <p>Pour prendre en charge les techniques avancées (comme les cookies ou les chemins
        d'URL spéciaux) afin de déterminer le langage préféré de l'utilisateur, le
        module <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> reconnaît la
        <a href="env.html">variable d'environnement</a>
        <code>prefer-language</code>
        depuis la version 2.0.47 de httpd. Si elle est définie et contient un
        symbole de langage approprié, <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> va essayer
        de sélectionner une variante correspondante. S'il n'existe pas de telle
        variante, le processus normal de négociation sera lancé.</p>
    
        <div class="example"><h3>Exemple</h3><pre class="prettyprint lang-config">SetEnvIf Cookie "language=(.+)" prefer-language=$1
    Header append Vary cookie</pre>
    </div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extensions" id="extensions">Extensions à la négociation de contenu
    transparente</a></h2>
    
    <p>httpd étend le protocole de négociation de contenu transparente (RFC
    2295) comme suit. Un nouvel élément <code>{encodage ..}</code> est utilisé dans
    les listes de variantes pour marquer celles qui ne sont disponibles qu'avec un
    encodage de contenu spécifique. L'implémentation de l'algorithme
    RVSA/1.0 (RFC 2296) est étendue à la reconnaissance de variantes encodées dans
    la liste, et à leur utilisation en tant que variantes candidates à partir du
    moment où leur encodage satisfait au contenu de l'en-tête de requête
    <code>Accept-Encoding</code>. L'implémentation RVSA/1.0 n'arrondit pas les
    facteurs de qualité calculés à 5 décimales avant d'avoir choisi la meilleure
    variante.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="naming" id="naming">Remarques à propos des liens hypertextes et des
    conventions de nommage</a></h2>
    
        <p>Si vous utilisez la négociation de langage, vous avez le choix entre
        différentes conventions de nommage, car les fichiers peuvent posséder
        plusieurs extensions, et l'ordre dans lequel ces dernières apparaissent
        est en général sans rapport (voir la documentation sur le module <a href="mod/mod_mime.html#multipleext">mod_mime</a>
        pour plus de détails).</p>
    
        <p>Un fichier type possède une extension liée au type MIME
        (<em>par exemple</em>, <code>html</code>), mais parfois aussi une
        extension liée à l'encodage (<em>par exemple</em>, <code>gz</code>),
        et bien sûr une extension liée au langage
        (<em>par exemple</em>, <code>en</code>) quand plusieurs variantes de
        langage sont disponibles pour ce fichier.</p>
    
        <p>Exemples :</p>
    
        <ul>
          <li>foo.en.html</li>
    
          <li>foo.html.en</li>
    
          <li>foo.en.html.gz</li>
        </ul>
    
        <p>Ci-dessous d'autres exemples de noms de fichiers avec des liens
        hypertextes valables et non valables :</p>
    
        <table class="bordered">
          
          <tr>
            <th>Nom fichier</th>
    
            <th>lien valide</th>
    
            <th>Lien invalide</th>
          </tr>
    
          <tr>
            <td><em>foo.html.en</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>-</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html</em></td>
    
            <td>foo</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.en.gz</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>foo.gz<br />
             foo.html.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html.gz</em></td>
    
            <td>foo</td>
    
            <td>foo.html<br />
             foo.html.gz<br />
             foo.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.gz.html.en</em></td>
    
            <td>foo<br />
             foo.gz<br />
             foo.gz.html</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.gz.en</em></td>
    
            <td>foo<br />
             foo.html<br />
             foo.html.gz</td>
    
            <td>foo.gz</td>
          </tr>
        </table>
    
        <p>En regardant la table ci-dessus, vous remarquerez qu'il est toujours
        possible d'utiliser le nom de fichier sans extension dans un lien
        (<em>par exemple</em>, <code>foo</code>). L'avantage est de pouvoir
        dissimuler le type réel du fichier associé à un document et de pouvoir
        le modifier
        ultérieurement, <em>par exemple</em>, de <code>html</code> à
        <code>shtml</code> ou <code>cgi</code> sans avoir à
        mettre à jour aucun lien.</p>
    
        <p>Si vous souhaitez continuer à utiliser un type MIME dans vos liens
        (<em>par exemple </em> <code>foo.html</code>), l'extension liée au langage
        (y compris une extension liée à l'encodage s'il en existe une)
        doit se trouver à droite de l'extension liée au type MIME
        (<em>par exemple</em>, <code>foo.html.en</code>).</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="caching" id="caching">Remarque sur la mise en cache</a></h2>
    
        <p>Quand un cache stocke une représentation, il l'associe avec l'URL de la
        requête. Lorsque cette URL est à nouveau demandée, le cache peut utiliser
        la représentation stockée. Cependant, si la ressource est négociable au
        niveau du serveur, il se peut que seule la première variante demandée soit
        mise en cache et de ce fait, la correspondance positive du cache peut
        entraîner une réponse inappropriée. Pour
        éviter cela, httpd marque par
        défaut toutes les réponses qui sont renvoyées après une négociation de
        contenu comme «&nbsp;non-cachables&nbsp;» par les clients HTTP/1.0. httpd prend
        aussi en charge les fonctionnalités du protocole HTTP/1.1 afin de permettre la mise
        en cache des réponses négociées.</p>
    
        <p>Pour les requêtes en provenance d'un client compatible HTTP/1.0
        (un navigateur ou un cache), la directive <code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code> peut être utilisée
        pour permettre la mise en cache des réponses qui ont fait l'objet d'une
        négociation. Cette directive peut intervenir dans la configuration au
        niveau du serveur ou de l'hôte virtuel, et n'accepte aucun argument. Elle
        n'a aucun effet sur les requêtes en provenance de clients HTTP/1.1.</p>
    
        <p>Pour les clients HTTP/1.1, httpd envoie un en-tête de réponse HTTP
        <code>Vary</code> afin d'indiquer les dimensions de la négociation pour
        cette réponse. Les caches peuvent
        utiliser cette information afin de déterminer
        si une requête peut être servie à partir de la copie locale. Pour inciter
        un cache à utiliser la copie locale sans tenir compte des dimensions de la
        négociation, définissez la
        <a href="env.html#special">variable d'environnement</a>
        <code>force-no-vary</code>.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/content-negotiation.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/content-negotiation.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/env.html.fr.utf8�����������������������������������������������������������0000664�0001751�0001751�00000103340�14740503670�020007� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache httpd et les variables d'environnement - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache httpd et les variables d'environnement</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
         <p>Deux types de variables d'environnement affectent le serveur
         HTTP Apache.</p>
    
        <p>Le premier type correspond aux variables d'environnement
        contrôlées par le système d'exploitation sous-jacent et définies
        avant le démarrage du serveur. Leurs valeurs peuvent être utilisées
        directement dans les fichiers de configuration, et peuvent
        éventuellement être transmises aux scripts CGI et SSI à l’aide de la
        directive PassEnv.</p>
    
        <p>Le second type correspond aux variables nommées appelées aussi
        <em>variables d'environnement</em> dans lesquelles le serveur HTTP
        Apache stocke des informations via un mécanisme spécial. Ces
        informations peuvent servir à contrôler diverses opérations comme
        l'enregistrement des traces ou le contrôle d'accès. On utilise aussi ces
        variables dans le mécanisme de communication avec les programmes externes
        comme les scripts CGI. Ce document présente différentes méthodes pour
        manipuler et utiliser ces variables.</p>
    
        <p>Bien que ces variables soient référencées comme <em>variables
        d'environnement</em>, il ne faut pas les confondre avec les variables
        d'environnement contrôlées par le système d'exploitation sous-jacent.
        En fait, ces variables sont stockées et manipulées dans une structure
        interne à Apache httpd. Elles ne deviennent de véritables variables
        d'environnement du système d'exploitation que lorsqu'elles sont mises à la
        disposition de scripts CGI et de scripts inclus côté serveur (SSI). Si vous
        souhaitez manipuler l'environnement du système d'exploitation sous lequel
        le serveur s'exécute, vous devez utiliser les mécanismes standards de
        manipulation de l'environnement fournis par l'interpréteur de commandes
        (shell) de votre système d'exploitation.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#setting">Définition des variables d'environnement</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Utilisation des variables d'environnement</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#special">Variables d'environnement à usage spécial</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Exemples</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="setting" id="setting">Définition des variables d'environnement</a></h2>
        
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_env.html">mod_env</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li><li><code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifnocase">SetEnvIfNoCase</a></code></li><li><code class="directive"><a href="./mod/mod_env.html#unsetenv">UnsetEnv</a></code></li></ul></td></tr></table>
    
        <h3><a name="basic-manipulation" id="basic-manipulation">Manipulations de base de l'environnement</a></h3>
            
    
            <p>La méthode la plus élémentaire pour définir une variable
    	d'environnement au niveau d'Apache httpd consiste à utiliser la directive
    	inconditionnelle <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code>. Les variables peuvent aussi être transmises depuis
    	l'environnement du shell à partir duquel le serveur a été démarré en
    	utilisant la directive
            <code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code>.</p>
    
        
        <h3><a name="conditional" id="conditional">Définitions conditionnelles en fonction des requêtes</a></h3>
            
    
            <p>Pour plus de souplesse, les directives fournies par le module
            <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> permettent de définir les
    	variables d'environnement en tenant compte des caractéristiques
    	de chaque requête. Par exemple, une
    	variable pourrait n'être définie que lorsqu'un navigateur spécifique
    	(User-Agent) a généré la requête, ou seulement quand un en-tête
    	Referer particulier est présent. La directive
    	<code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> du module
    	<code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> qui utilise l'option
    	<code>[E=...]</code> pour définir
    	les variables d'environnement apporte encore plus de souplesse.</p>
    
        
        <h3><a name="unique-identifiers" id="unique-identifiers">Identifiants uniques</a></h3>
            
    
            <p>Finalement, le module <code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code> définit la variable
    	d'environnement <code>UNIQUE_ID</code> pour chaque requête à une valeur
    	qui est garantie unique parmi «&nbsp;toutes&nbsp;» les requêtes sous des
    	conditions très spécifiques.</p>
    
        
        <h3><a name="standard-cgi" id="standard-cgi">Variables CGI standards</a></h3>
            
    
            <p>En plus de l'ensemble des variables d'environnement internes à la
    	configuration d'Apache httpd et de celles transmises depuis le shell,
    	les scripts CGI	et les pages SSI
    	se voient affectés un ensemble de variables
    	d'environnement contenant des méta-informations à propos de la requête
    	comme préconisé dans la
    	<a href="http://www.ietf.org/rfc/rfc3875">spécification
    	sur les CGIs</a>.</p>
    
        
        <h3><a name="caveats" id="caveats">Quelques mises en garde</a></h3>
            
    
            <ul>
              <li>Les directives de manipulation de l'environnement ne permettent
    	  pas de supplanter ou modifier les variables CGI standards.</li>
    
              <li>Lorsqu'on utilise <code class="program"><a href="./programs/suexec.html">suexec</a></code> pour exécuter des
    	  scripts CGI, l'environnement est nettoyé et réduit à un ensemble de
    	  variables <em>sûres</em> avant l'exécution du script. La liste des
    	  variables <em>sûres</em> est définie à la compilation dans
              <code>suexec.c</code>.</li>
    
              <li>Pour des raisons de portabilité, les noms des variables
    	  d'environnement ne peuvent contenir que des lettres, des chiffres et
    	  le caractère «&nbsp;souligné&nbsp;». En outre, le premier caractère ne doit pas
    	  être un chiffre. Les caractères qui ne satisfont pas à ces conditions
    	  seront remplacés par un caractère «&nbsp;souligné&nbsp;» quand ils seront
    	  transmis aux scripts CGI et aux pages SSI.</li>
    
    	  <li>Les contenus d'en-têtes HTTP transmis aux scripts de type
    	  CGI ou autre à l’aide de variables d'environnement constituent un
    	  cas particulier (voir plus loin). Leur nom est converti en
    	  majuscules et seuls les tirets sont remplacés par des
    	  caractères '_' («&nbsp;souligné&nbsp;») ; si le format du nom de l'en-tête
    	  n'est pas valide, celui-ci est ignoré. Voir <a href="#fixheader">plus loin</a> pour une solution de
    	  contournement du problème.</li>
    
              <li>La directive <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> s'exécute assez tard au
    	  cours du traitement de la requête, ce qui signifie que des
    	  directives telles que <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> et <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> ne verront pas
    	  les variables qu'elle aura définies.</li>
    
    	  <li>Lorsque le serveur cherche un chemin via une <a class="glossarylink" href="./glossary.html#subrequest" title="voir glossaire">sous-requête</a> interne (par exemple la
       recherche d'un <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>), ou lorsqu'il génère un
       listing du contenu d'un répertoire à l’aide du module
       <code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code>, la sous-requête n'hérite pas des
       variables d'environnement spécifiques à la requête. En outre, à cause
       des phases de l'API auxquelles <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> prend
       part, les directives <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> ne sont pas évaluées
       séparément dans la sous-requête.</li>
            </ul>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Utilisation des variables d'environnement</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_access_compat.html#allow">Allow</a></code></li><li><code class="directive"><a href="./mod/mod_access_compat.html#deny">Deny</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li></ul></td></tr></table>
    
        <h3><a name="cgi-scripts" id="cgi-scripts">Scripts CGI</a></h3>
            
    
            <p>La communication d'informations aux scripts CGI constitue une des
    	principales utilisations des variables d'environnement. Comme indiqué
    	plus haut, l'environnement transmis aux scripts CGI comprend des
    	méta-informations standards à propos de la requête, en plus des
    	variables définies dans la configuration d'Apache httpd. Pour plus de
    	détails, se référer au
            <a href="howto/cgi.html">tutoriel CGI</a>.</p>
    
        
        <h3><a name="ssi-pages" id="ssi-pages">Pages SSI</a></h3>
            
    
            <p>Les documents inclus côté serveur (SSI) traités par le filtre
            <code>INCLUDES</code> du module <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>,
    	peuvent afficher les
    	variables d'environnement à l'aide de l'élément <code>echo</code>,
    	et peuvent utiliser des variables d'environnement dans les éléments
    	de contrôle de flux pour rendre certaines parties d'une page
            conditionnelles en fonction des caractéristiques de la requête.
    	Apache httpd fournit aussi les variables d'environnement CGI standards
    	aux pages SSI
    	comme indiqué plus haut. Pour plus de détails, se référer au
    	<a href="howto/ssi.html">tutoriel SSI</a>.</p>
    
        
        <h3><a name="access-control" id="access-control">Contrôle d'accès</a></h3>
            
    
            <p>L'accès au serveur peut être contrôlé en fonction de la valeur de
    	variables d'environnement à l'aide des directives
    	<code>Require env</code> et <code>Require not env</code>.
    	En association avec la directive
            <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>, cela confère une
    	grande souplesse au contrôle d'accès au serveur en fonction des
    	caractéristiques du client. Par exemple, vous pouvez utiliser ces
            directives pour interdire l'accès depuis un navigateur particulier
    	(User-Agent).
            </p>
    
        
        <h3><a name="logging" id="logging">Enregistrement conditionnel des traces</a></h3>
            
    
            <p>Les variables d'environnement peuvent être enregistrées dans le
    	fichier de log des accès à l'aide de l'option <code>%e</code> de la
    	directive <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>.
    	En outre, la décision de tracer ou non les requêtes peut être prise
    	en fonction de l'état de variables d'environnement en utilisant la
    	forme conditionnelle de la directive
            <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>. En
    	association avec la directive <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>, cela confère une grande souplesse au contrôle
    	du traçage des requêtes. Par exemple, vous pouvez choisir de ne pas
    	tracer les requêtes pour des noms de fichiers se terminant par
    	<code>gif</code>, ou encore de ne tracer que les requêtes des clients
    	n'appartenant pas à votre sous-réseau.</p>
    
        
        <h3><a name="response-headers" id="response-headers">En-têtes de réponse conditionnels</a></h3>
            
    
            <p>La directive <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code>
            peut se baser sur la présence ou l'absence d'une variable
    	d'environnement pour décider si un certain en-tête HTTP sera placé
    	dans la réponse au client. Cela permet, par exemple, de n'envoyer un
    	certain en-tête de réponse que si un en-tête correspondant est présent
    	dans la requête du client.</p>
    
        
    
        <h3><a name="external-filter" id="external-filter">Activation de filtres externes</a></h3>
            
    
            <p>Les filtres externes configurés par le module
    	<code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> à l'aide de la directive <code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code> peuvent être
    	activés de manière conditionnelle en fonction d'une variable
    	d'environnement à l'aide des options
            <code>disableenv=</code> et <code>enableenv=</code>.</p>
        
    
        <h3><a name="url-rewriting" id="url-rewriting">Réécriture d'URL</a></h3>
            
    
            <p>La forme <code>%{ENV:<em>variable</em>}</code> de
    	<em>TestString</em> dans la
    	directive <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
            permet au moteur de réécriture du module
    	<code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> de prendre des
    	décisions conditionnées par des variables d'environnement.
            Notez que les variables accessibles dans
    	<code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> sans le préfixe
            <code>ENV:</code> ne sont pas de véritables variables
    	d'environnement. Ce sont plutôt des variables spécifiques à
    	<code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
            qui ne sont pas accessibles pour les autres modules.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="special" id="special">Variables d'environnement à usage spécial</a></h2>
        
    
            <p>Des problèmes d'interopérabilité ont conduit à l'introduction de
    	mécanismes permettant de modifier le comportement d'Apache httpd lorsqu'il
    	dialogue avec certains clients. Afin de rendre ces mécanismes aussi
    	souples que possible, ils sont invoqués en définissant des variables
    	d'environnement, en général à l'aide de la directive
    	<code class="directive"><a href="./mod/mod_setenvif.html#browsermatch">BrowserMatch</a></code>, bien que les
    	directives <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code> et
    	<code class="directive"><a href="./mod/mod_env.html#passenv">PassEnv</a></code> puissent aussi être
    	utilisées, par exemple.</p>
    
        <h3><a name="downgrade" id="downgrade">downgrade-1.0</a></h3>
            
    
            <p>Cela force le traitement d'une requête comme une requête HTTP/1.0
            même si elle a été rédigée dans un langage plus récent.</p>
    
        
        <h3><a name="force-gzip" id="force-gzip">force-gzip</a></h3>
            
              <p>Si le filtre <code>DEFLATE</code> est activé, cette variable
    	  d'environnement ignorera les réglages accept-encoding de votre
    	  navigateur et enverra une sortie compressée inconditionnellement.</p>
        
        <h3><a name="force-no-vary" id="force-no-vary">force-no-vary</a></h3>
            
    
            <p>Cette variable entraîne la suppression de tout champ
    	<code>Vary</code> des en-têtes de la réponse avant que cette dernière
    	soit renvoyée au client. Certains clients n'interprètent pas ce champ
    	correctement, et la définition de cette variable permet de contourner
    	ce problème, mais implique aussi la définition de
    	<strong>force-response-1.0</strong>.</p>
    
        
        <h3><a name="force-response" id="force-response">force-response-1.0</a></h3>
            
    
          <p>Cette variable force une réponse en langage HTTP/1.0 aux clients
          qui envoient des requêtes dans le même langage. Elle fut implémentée à
          l'origine suite à des problèmes avec les mandataires d'AOL. Certains
          clients en langage HTTP/1.0 ne réagissent pas correctement face à une
          réponse en langage HTTP/1.1, et cette variable peut être utilisée pour
          assurer l'interopérabilité avec eux.</p>
    
        
    
        <h3><a name="gzip-only-text-html" id="gzip-only-text-html">gzip-only-text/html</a></h3>
            
    
            <p>Positionnée à «&nbsp;1&nbsp;», cette variable désactive le filtre en sortie
    	<code>DEFLATE</code> fourni par le module <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> pour les
    	types de contenu autres que <code>text/html</code>. Si vous préférez
    	utiliser des fichiers compressés statiquement,
    	<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> évalue aussi la variable (non
    	seulement pour gzip, mais aussi pour tous les encodages autres que
    	«&nbsp;identity&nbsp;»).</p>
        
    
        <h3><a name="no-gzip" id="no-gzip">no-gzip</a></h3>
    
            <p>Quand cette variable est définie, le filtre <code>DEFLATE</code> du
    	module <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> est désactivé, et
            <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> refusera de délivrer des ressources
    	encodées.</p>
    
        
    
        <h3><a name="no-cache" id="no-cache">no-cache</a></h3>
        	<p><em>Disponible dans les versions 2.2.12 et ultérieures d'Apache httpd</em></p>
    
            <p>Lorsque cette variable est définie,
    	<code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> ne sauvegardera pas de réponse
    	susceptible d'être mise en cache. Cette variable d'environnement
    	n'a aucune incidence sur le fait qu'une réponse déjà enregistrée
    	dans le cache soit utilisée ou non pour la requête courante.</p>
    
        
    
        <h3><a name="nokeepalive" id="nokeepalive">nokeepalive</a></h3>
            
    
            <p>Quand cette variable est définie, la directive
    	<code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code> est désactivée.</p>
    
        
    
        <h3><a name="prefer-language" id="prefer-language">prefer-language</a></h3>
    
            <p>Cette variable modifie le comportement du module
    	<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>. Si elle contient un symbole de
    	langage (tel que <code>en</code>, <code>ja</code>
            ou <code>x-klingon</code>), <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> essaie de
    	délivrer une variante dans ce langage. S'il n'existe pas de telle
    	variante, le processus normal de
    	<a href="content-negotiation.html">négociation</a> s'applique.</p>
    
        
    
        <h3><a name="redirect-carefully" id="redirect-carefully">redirect-carefully</a></h3>
            
    
            <p>Cette variable force le serveur à être plus prudent lors de l'envoi
    	d'une redirection au client. Elle est en général utilisée quand un
    	client présente un problème connu avec les redirections. Elle fut
    	implémentée à l'origine suite a un problème rencontré avec le logiciel
    	WebFolders de Microsoft qui ne gère pas correctement les redirections
    	vers des ressources de type répertoire via des méthodes DAV.</p>
    
        
    
       <h3><a name="suppress-error-charset" id="suppress-error-charset">suppress-error-charset</a></h3>
           
    
        <p><em>Disponible dans les versions postérieures à 2.0.54</em></p>
    
        <p>Quand Apache httpd génère une redirection en réponse à une requête client,
        la réponse inclut un texte destiné à être affiché au cas où le client ne
        suivrait pas, ou ne pourrait pas suivre automatiquement la redirection.
        Habituellement, Apache httpd marque ce texte en accord avec le jeu de caractères
        qu'il utilise, à savoir ISO-8859-1.</p>
        <p> Cependant, si la redirection fait référence à une page qui utilise un
        jeu de caractères différent, certaines versions de navigateurs obsolètes
        essaieront d'utiliser le jeu de caractères du texte de la redirection
        plutôt que celui de la page réelle.
        Cela peut entraîner, par exemple, un rendu incorrect du Grec.</p>
        <p>Si cette variable d'environnement est définie, Apache httpd omettra le jeu de
        caractères pour le texte de la redirection, et les navigateurs obsolètes
        précités utiliseront correctement celui de la page de destination.</p>
    
        <div class="warning">
          <h3>Note concernant la sécurité</h3>
    
          <p>L'envoi de pages d'erreur sans spécifier un jeu de caractères peut
          conduire à des attaques de type "cross-site-scripting" pour les
          navigateurs qui ne respectent pas la spécification HTTP/1.1 (MSIE) et
          tentent de déduire le jeu de caractères à partir du contenu. De tels
          navigateurs peuvent être facilement trompés et utiliser le jeu de
          caractères UTF-7 ; les contenus des données en entrée de type UTF-7
          (comme les URI de requête) ne seront alors plus protégés par les
          mécanismes d'échappement usuels conçus pour prévenir les attaques
          de type "cross-site-scripting".</p>
        </div>
    
       
    
       <h3><a name="proxy" id="proxy">force-proxy-request-1.0, proxy-nokeepalive, proxy-sendchunked,
       proxy-sendcl, proxy-chain-auth, proxy-interim-response, proxy-initial-not-pooled</a></h3>
    
       <p>Ces directives modifient le comportement protocolaire du module
       <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.  Voir la documentation sur
       <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> et <code class="module"><a href="./mod/mod_proxy_http.html">mod_proxy_http</a></code> pour plus de détails.</p>
       
    
       <h3><a name="cgilike" id="cgilike">ap_trust_cgilike_cl</a></h3>
       <p><em>Disponible à partir de la version 2.4.59 du serveur HTTP Apache</em></p>
         <p>Cette variable permet à un script qui s’exécute dans un module de type CGI
         de fournir son propre en-tête de réponse HTTP Content-Length. Elle ne doit
         être définie que dans les sections de configuration qui contiennent des
         scripts de confiance.</p>
       
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples</a></h2>
        
    
        <h3><a name="fixheader" id="fixheader">Transmission du contenu d'en-têtes non valides aux scripts
          CGI</a></h3>
          
    
          <p>Avec la version 2.4, Apache httpd est plus strict avec la conversion
          des en-têtes HTTP en variables d'environnement dans
          <code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code> et d'autres modules : dans les versions
          précédentes, tout caractère non valable dans les noms d'en-têtes
          était tout simplement remplacé par un caractère '_', ce qui
          pouvait exposer à des attaques de type cross-site-scripting via
          injection d'en-têtes (voir <a href="http://events.ccc.de/congress/2007/Fahrplan/events/2212.en.html">Bogues
          du Web inhabituelles</a>, planche 19/20).</p>
    
          <p>Si vous devez prendre en charge un client qui envoie des en-têtes non
          conformes et si ceux-ci ne peuvent pas être corrigés, il existe
          une solution de contournement simple mettant en jeu les modules
          <code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code> et <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code>,
          et permettant de prendre en compte ces en-têtes :</p>
    
    <pre class="prettyprint lang-config"># L'exemple suivant montre comment prendre en compte un en-tête<br />
    # Accept_Encoding non conforme envoyé par un client.
    #
    SetEnvIfNoCase ^Accept.Encoding$ ^(.*)$ fix_accept_encoding=$1
    RequestHeader set Accept-Encoding %{fix_accept_encoding}e env=fix_accept_encoding</pre>
    
    
        
    
        <h3><a name="misbehaving" id="misbehaving">Modification du comportement protocolaire face à des clients
    	réagissant de manière non conforme</a></h3>
            
    
            <p>Les versions antérieures recommandaient l'ajout de ces lignes dans
            httpd.conf pour tenir compte de problèmes connus avec certains clients.
    	Comme les clients concernés sont maintenant très peu utilisés, cet
    	ajout n'est pratiquement plus nécessaire.</p>
    <pre class="prettyprint lang-config">#
    # 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</pre>
    
    
        
        <h3><a name="no-img-log" id="no-img-log">Ne pas tracer les requêtes pour des images dans le fichier de
    	trace des accès</a></h3>
            
    
            <p>Dans cet exemple, les requêtes pour des images n'apparaissent pas
    	dans le fichier de trace des accès. Il peut être facilement adapté pour
    	empêcher le traçage de répertoires particuliers, ou de requêtes
            en provenance de certains hôtes.</p>
             <pre class="prettyprint lang-config">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</pre>
    
    
        
        <h3><a name="image-theft" id="image-theft">Prévention du «&nbsp;Vol d'image&nbsp;»</a></h3>
            
    
            <p>Cet exemple montre comment empêcher les utilisateurs ne faisant pas
    	partie de votre serveur d'utiliser des images de votre serveur comme
    	images en ligne dans leurs pages. Cette configuration n'est pas
    	recommandée, mais elle peut fonctionner dans des circonstances bien
    	définies. Nous supposons que toutes vos images sont enregistrées dans
    	un répertoire nommé <code>/web/images</code>.</p>
        	<pre class="prettyprint lang-config">SetEnvIf Referer "^http://www\.example\.com/" local_referal
    # Autorise les navigateurs qui n'envoient aucune information de Referer
    SetEnvIf Referer "^$" local_referal
    &lt;Directory "/web/images"&gt;
        Require env local_referal
    &lt;/Directory&gt;</pre>
    
    
            <p>Pour plus d'informations sur cette technique, voir le tutoriel sur
    	ServerWatch
    	"<a href="https://www.serverwatch.com/guides/keeping-your-images-from-adorning-other-sites/">Keeping Your Images from Adorning Other Sites</a>".</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/env.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/env.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/env.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/env.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/env.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/env.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/getting-started.html.fr.utf8�����������������������������������������������0000664�0001751�0001751�00000042322�14740503670�022326� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Pour démarrer - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Pour démarrer</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/getting-started.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/getting-started.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ru/getting-started.html" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a></p>
    </div>
    
    <p>Si vous ne connaissez rien au serveur HTTP Apache, ou même au
    fonctionnement d'un site web, vous vous demandez probablement par où
    commencer et quelles questions poser. Ce document vous permettra de
    parcourir les bases du sujet.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#clientserver">Clients, serveurs et URLs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#dns">Noms d'hôte et DNS</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configuration">Fichiers de configuration et directives</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#content">Contenu du site web</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#logs">Fichiers journaux et résolution des problèmes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Et maintenant, comment faire pour aller plus loin ?</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="clientserver" id="clientserver">Clients, serveurs et URLs</a></h2>
    
    
    <p>
    Les adresses des pages web sur la Toile se présentent sous forme d'URLs
    - Uniform Resource Locators - qui comportent un protocole (par
      exemple <code>http</code>), un nom de serveur (par exemple
      <code>www.apache.org</code>), un chemin (par exemple
      <code>/docs/current/getting-started.html</code>), et le cas échéant
      une chaîne de paramètres (query string) (par exemple <code>?arg=value</code>)
      permettant de transmettre des informations supplémentaires au serveur.
    </p>
    
    <p>Un client (par exemple un navigateur web) se connecte à un serveur
    (par exemple votre serveur HTTP Apache) avec un protocole spécifique, et
    effectue une <strong>requête</strong> pour une ressource en spécifiant
    son chemin.</p>
    
    <p>Un chemin peut représenter plusieurs types de ressources sur le
    serveur. Il peut s'agir d'un fichier (comme
    <code>getting-started.html</code>), d'un gestionnaire (comme <a href="mod/mod_status.html">server-status</a>) ou d'une sorte quelconque de
    programme (comme <code>index.php</code>). Nous décrirons tout cela plus
    en détails ci-dessous dans la section <a href="#content">Contenu d'un
    site web</a>.</p>
    
    <p>
    Le serveur envoie alors une <strong>réponse</strong> comportant un code
    d'état, et éventuellement un corps de réponse. Le code d'état indique si
    la requête a été traitée avec succès, ou dans la négative, quel type
    d'erreur a été rencontré. Le client est alors censé savoir quoi faire de
    la réponse. Vous pouvez vous familiariser avec les différents codes
    d'état en consultant le <a href="http://wiki.apache.org/httpd/CommonHTTPStatusCodes">Wiki du
    serveur HTTP Apache</a>.</p>
    
    <p>Les détails de la transaction, ainsi que les erreurs rencontrées,
    sont enregistrés dans des fichiers journaux. Tout cela est décrit en
    détails ci-dessous dans la section <a href="#logs">Débogage et fichiers
    journaux</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dns" id="dns">Noms d'hôte et DNS</a></h2>
    
    
    <p>Pour se connecter à un serveur, le client doit tout d'abord traduire
    le nom du serveur en adresse IP, cette dernière permettant de localiser
    le serveur sur Internet. Ainsi, pour que votre serveur web soit
    accessible, son nom doit être enregistré dans le DNS.</p>
    
    <p>Si vous ne savez pas comment effectuer cet enregistrement, vous
    devez contacter votre administrateur réseau ou votre fournisseur
    d'accès à Internet afin qu'il effectue cette opération pour vous.</p>
    
    <p>Plusieurs noms d'hôte peuvent pointer vers la même adresse IP, et
    plusieurs adresses IP peuvent être attachées au même serveur physique.
    Vous pouvez ainsi héberger plusieurs serveurs web sur le même serveur
    physique grâce au mécanisme des <a href="vhosts/">serveurs virtuels</a>.</p>
    
    <p>Pour tester un serveur non encore accessible sur Internet, vous
    pouvez renseigner son nom d'hôte dans votre fichier hosts afin
    d'effectuer une résolution de nom locale. Par exemple, pour tester le
    serveur web <code>www.example.com</code> depuis le serveur physique qui
    l'héberge, vous pouvez ajouter la ligne suivante au fichier hosts de ce
    dernier : </p>
    
    <div class="example"><p><code>
    127.0.0.1 www.example.com
    </code></p></div>
    
    <p>En général, le fichier hosts se trouve dans le répertoire
    <code>/etc</code> sur les systèmes de style Unix, ou
    <code>C:\Windows\system32\drivers\etc</code> sous Windows.</p>
    
    <p>Vous trouverez plus de détails à propos du fichier hosts à <a href="http://en.wikipedia.org/wiki/Hosts_(file)">Wikipedia.org/wiki/Hosts_(file)</a>,
    et à propos du DNS à <a href="http://en.wikipedia.org/wiki/Domain_Name_System">Wikipedia.org/wiki/Domain_Name_System</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Fichiers de configuration et directives</a></h2>
    
    
    <p>La configuration du serveur HTTP Apache s'effectue via de simples
    fichiers texte. Ces fichiers peuvent se trouver dans de nombreux
    endroits différents en fonction du mode d'installation du serveur. Vous
    trouverez les positions courantes de ces fichiers dans le <a href="http://wiki.apache.org/httpd/DistrosDefaultLayout">wiki httpd</a>.
    Si vous installez httpd depuis le code source, le répertoire par défaut
    des fichiers de configuration est <code>/usr/local/apache2/conf</code>.
    Le nom du fichier de configuration par défaut est en général
    <code>httpd.conf</code>, mais peut aussi varier en fonction des
    distributions tierces du serveur.</p>
    
    <p>L'ensemble de la configuration est en général divisé en plusieurs
    fichiers afin d'en faciliter la gestion. Ces fichiers sont inclus dans
    le fichier de configuration principal via la directive <code class="directive"><a href="./mod/core.html#include">Include</a></code>. Les noms ou positions de ces fichiers
    ne sont pas figés et peuvent varier considérablement d'une distribution
    à l'autre. N'hésitez pas à les arranger et subdiviser selon
    <strong>vos</strong> goûts et besoins, quitte à en modifier
    l'organisation par défaut.</p>
    
    <p>La configuration du serveur s'effectue via des <a href="mod/quickreference.html">directives de configuration</a> que l'on
    insère dans les fichiers de configuration. Une directive se compose d'un
    mot-clé suivi d'un ou plusieurs arguments qui définissent sa valeur.</p>
    
    <p>La réponse à la question "<em>Où dois-je placer cette directive ?</em>"
    dépend en général du niveau auquel cette directive doit être prise en compte.
    S'il s'agit du niveau global, elle doit être placée dans le fichier de
    configuration principal, et en dehors de toute section  <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> ou de toute autre section.  Sinon, si par
    exemple elle ne doit s'appliquer qu'à un répertoire particulier, elle doit être
    placée dans la section <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> qui fait référence à ce répertoire.  Voir la
    documentation sur les <a href="sections.html">Sections de configuration</a> pour
    plus de détails.</p>
    
    <p>En complément des fichiers de configuration principaux, certaines directives
    peuvent être insérées dans des fichiers <code>.htaccess</code> que l'on place
    directement dans le répertoire concerné. Les fichiers <code>.htaccess</code>
    sont essentiellement destinés aux personnes qui n'ont pas accès aux fichiers de
    configuration du serveur. Vous trouverez plus de détails à propos des fichiers
    <code>.htaccess</code> dans ce <a href="howto/htaccess.html"><code>.htaccess</code>howto</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="content" id="content">Contenu du site web</a></h2>
    
    
    <p>Si le contenu du site web peut se présenter sous de nombreuses
    formes, il en existe deux principales : les
    contenus statiques et les contenus dynamiques.</p>
    
    <p>Les contenus statiques sont par exemple les fichiers HTML, les
    images, les fichiers CSS et tout autre fichier résidant dans le système
    de fichiers. La directive <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> permet de définir la position
    dans l'arborescence du site où vous devez placer ces fichiers. Cette
    directive peut être définie au niveau global, ou au niveau de chaque
    serveur virtuel. Vous pouvez consulter vos fichiers de configuration
    pour vérifier la manière dont cette directive est définie pour votre
    serveur.</p>
    
    <p>En général, et si aucun nom de fichier n'est spécifié dans la
    requête, c'est une page de nom <code>index.html</code> qui sera
    renvoyée. Par exemple, si la directive <code>DocumentRoot</code> est
    définie à <code>/var/www/html</code>, et si une requête est effectuée
    pour l'adresse <code>http://www.example.com/work/</code>, c'est le
    fichier <code>/var/www/html/work/index.html</code> qui sera envoyé au
    client par le serveur.</p>
    
    <p>Un contenu dynamique est un contenu qui est généré au moment du
    traitement de la requête, et qui peut différer d'une requête à l'autre.
    Ces contenus dynamiques peuvent être générés de nombreuses manières par
    l'intermédiaire de <a href="handler.html">gestionnaires de contenu</a>
    ou "handlers". Il est aussi possible de créer des <a href="howto/cgi.html">programmes CGI</a> pour générer le contenu de
    votre site.</p>
    
    <p>Enfin, on peut utiliser des modules tiers comme mod_php pour écrire
    du code permettant d'effectuer de nombreuses choses. De nombreuses
    applications tierces écrites à partir de divers langages ou outils sont
    disponibles en téléchargement et peuvent être installées sur votre
    serveur HTTP Apache. Le support de ces applications est en dehors du sujet de
    ce document, et nous vous invitons à consulter le site de leur éditeur
    pour accéder à leur documentation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="logs" id="logs">Fichiers journaux et résolution des problèmes</a></h2>
    
    <p>En tant qu'administrateur d'un serveur HTTP Apache, vos sources
    d'informations principales sont les fichiers journaux, et en particulier
    le journal des erreurs. Toute tentative de résolution d'un problème sans
    consulter le journal des erreurs revient à essayer de conduire les yeux
    fermés.</p>
    
    <p>La position dans le système de fichiers du journal des erreurs est
    spécifiée par la directive <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code>
    qui peut être définie au niveau global, ou au niveau de chaque serveur
    virtuel. Chaque entrée du journal des erreurs vous informe sur la nature
    des problèmes et le moment de leur survenue. En outre, elle vous indique
    souvent comment résoudre le problème. Chaque message d'erreur contient
    un code d'erreur que vous pouvez utiliser pour effectuer une recherche
    en ligne afin d'obtenir une description plus détaillée de la manière de
    résoudre le problème. Vous pouvez aussi configurer votre journal des
    erreurs de manière à ce qu'il enregistre un identifiant d'erreur que
    vous pourrez ensuite utiliser pour effectuer une corrélation avec le
    journal des accès afin de déterminer quelle requête est à l'origine de
    l'erreur.</p>
    
    <p>Vous trouverez plus de détails à ce sujet dans la <a href="logs.html">Documentation sur la journalisation</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Et maintenant, comment faire pour aller plus loin ?</a></h2>
    
    
    <p>La question des prérequis étant réglée, il est temps de passer aux
    choses sérieuses.</p>
    
    <p>Ce document ne couvre que les notions de base. Nous espérons qu'il
    vous permettra de mettre le pied à l'étrier, mais il y a encore de
    nombreuses choses que vous devez savoir.</p>
    
    <ul>
    <li><a href="http://httpd.apache.org/download.cgi">Téléchargement</a></li>
    <li><a href="install.html">Installation</a></li>
    <li><a href="configuring.html">Configuration</a></li>
    <li><a href="invoking.html">Démarrage du serveur</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">Foire aux questions</a></li>
    </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/getting-started.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/getting-started.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ru/getting-started.html" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/getting-started.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/urlmapping.html.ja.utf8����������������������������������������������������0000664�0001751�0001751�00000063316�14743132254�021367� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>URL からファイルシステム上の位置へのマップ - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>URL からファイルシステム上の位置へのマップ</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p>この文書は Apache がリクエストの URL から送信するファイルの
        ファイルシステム上の位置を決定する方法を説明します。</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#related">関連するモジュールとディレクティブ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentroot">DocumentRoot</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#outside">DocumentRoot 外のファイル</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#user">ユーザディレクトリ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#redirect">URL リダイレクション</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">リバースプロキシ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">リライトエンジン</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#notfound">File Not Found</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">関連するモジュールとディレクティブ</a></h2>
    
    <table class="related"><tr><th>関連モジュール</th><th>関連ディレクティブ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code></li><li><code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code></li><li><code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_speling.html#checkspelling">CheckSpelling</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="./mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritematch">RewriteMatch</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentroot" id="documentroot">DocumentRoot</a></h2>
    
        <p>リクエストに対してどのファイルを送信するかを決定するときの
        Apache のデフォルトの動作は、リクエストの URL-Path (URL のホスト名と
        ポート番号の後に続く部分) を取り出して設定ファイルで指定されている
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> 
        の最後に追加する、というものです。ですから、
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> 
        の下のディレクトリやファイルがウェブから見える基本のドキュメントの木構造を
        なします。</p>
    
        <p>Apache にはサーバが複数のホストへのリクエストを受け取る
        <a href="vhosts/">バーチャルホスト</a> の機能もあります。
        この場合、それぞれのバーチャルホストに対して違う
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        を指定することができます。また、<code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code>
        モジュールにより提供されるディレクティブを使って、
        送信するためのコンテンツの場所をリクエストされた IP
        アドレスやホスト名から動的に決めることもできます。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="outside" id="outside">DocumentRoot 外のファイル</a></h2>
    
        <p>ファイルシステム上の、
        厳密には <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        の下にはない部分へのウェブアクセスを許可する必要がある
        場合がよくあります。Apache はこのために複数の方法を用意しています。
        Unix システムでは、ファイルシステムの他の部分をシンボリックリンクを
        使って <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        の下に持ってくることができます。セキュリティ上の理由により、
        Apache は該当するディレクトリの
        <code class="directive"><a href="./mod/core.html#options">Options</a></code> の設定に
        <code>FollowSymLinks</code> か <code>SymLinksIfOwnerMatch</code> が
        ある場合にのみシンボリックリンクをたどります。</p>
    
        <p>代わりの方法として、<code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code>
        ディレクティブを使ってファイルシステムの任意の部分をウェブの空間に
        マップできます。たとえば、</p>
    
    <div class="example"><p><code>Alias /docs /var/web</code></p></div>
    
        <p>という設定のときは、URL
        <code>http://www.example.com/docs/dir/file.html</code> には
        <code>/var/web/dir/file.html</code> が送信されます。
        <code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code> も、
        対象となっているパスが CGI スクリプトとして扱われるという追加の
        効果以外は同じように動作します。</p>
    
        <p>もっと柔軟な設定が必要な状況では、
        <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code> ディレクティブや
        <code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code> ディレクティブ
        を使って強力な正規表現に基づいたマッチと置換を行なうことができます。
        たとえば、</p>
    
    <div class="example"><p><code>ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+)
          /home/$1/cgi-bin/$2</code></p></div>
    
        <p>は <code>http://example.com/~user/cgi-bin/script.cgi</code> への
        リクエストを <code>/home/user/cgi-bin/script.cgi</code> というパスへ
        マップし、このマップの結果としてのファイルを CGI スクリプトとして
        扱います。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="user" id="user">ユーザディレクトリ</a></h2>
    
        <p>伝統的に Unix システムではユーザ <em>user</em> のホームディレクトリを
        <code>~user/</code> として参照できます。<code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> 
        モジュールはこの概念をウェブに拡張して、
        それぞれのユーザのホームディレクトリのファイルを
        以下のような URL を使ってアクセスできるようにします。</p>
    
    <div class="example"><p><code>http://www.example.com/~user/file.html</code></p></div>
    
        <p>セキュリティの観点から、ウェブからユーザのホームディレクトリへ
        直接アクセスできるようにすることは適切ではありません。ですから、
        <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> ディレクティブには
        ユーザのホームディレクトリの下の、ウェブファイルの
        置かれているディレクトリを指定します。デフォルトの設定の
        <code>Userdir public_html</code> を使うと、上の URL は
        <code>/home/user/public_html/file.html</code> というようなファイルに
        マップされます。ここで、<code>/home/user/</code> は
        <code>/etc/passwd</code> で指定されているユーザのホームディレクトリです。</p>
    
        <p><code class="directive"><a href="./mod/mod_userdir.html#userdir">Userdir</a></code> には、
        <code>/etc/passwd</code> にホームディレクトリの位置が書かれていない
        システムでも使うことのできる他の形式もあります。</p>
    
        <p>中にはシンボル "~" (<code>%7e</code> のように符号化されることが多い)
        を格好が悪いと思って、ユーザのディレクトリを表すために別の文字列の
        使用を好む人がいます。mod_userdir はこの機能をサポートしていません。
        しかし、ユーザのホームディレクトリが規則的な構成のときは、
        <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code> を使って望みの
        効果を達成することができます。たとえば、
        <code>http://www.example.com/upages/user/file.html</code> が
        <code>/home/user/public_html/file.html</code> にマップされるようにするには、
        以下のように <code>AliasMatch</code> ディレクティブを使います:</p>
    
    <div class="example"><p><code>AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*)
          /home/$1/public_html/$2</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">URL リダイレクション</a></h2>
    
        <p>上の節で説明した設定用のディレクティブは Apache に
        ファイルシステムの特定の場所からコンテンツを取ってきて
        クライアントに送り返すようにします。ときには、その代わりに
        クライアントにリクエストされたコンテンツは別の URL にあることを
        知らせて、クライアントが新しい URL へ新しいリクエストを行なうように
        する方が望ましいことがあります。これは<em>リダイレクション</em>と
        呼ばれていて、<code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code>
        ディレクティブにより実装されています。たとえば、
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> の下のディレクトリ
        <code>/foo/</code> が新しいディレクトリ <code>/bar/</code> に移動したときは、
        以下のようにしてクライアントが新しい場所のコンテンツをリクエストするように
        指示することができます:</p>
    
    <div class="example"><p><code>Redirect permanent /foo/
          http://www.example.com/bar/</code></p></div>
    
        <p>これは、<code>/foo/</code> で始まるすべての URL-Path を、
        <code>www.example.com</code> サーバの <code>/bar/</code> が
        <code>/foo/</code> に置換されたものにリダイレクトします。
        サーバは自分自身のサーバだけでなく、どのサーバにでもクライアントを
        リダイレクトすることができます。</p>
    
        <p>Apache はより複雑な書き換えの問題のために、
        <code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> ディレクティブを
        提供しています。たとえば、サイトのホームページを違うサイトにリダイレクト
        するけれど、他のリクエストはそのまま扱う、というときは以下の設定を
        使います:</p>
    
    <div class="example"><p><code>RedirectMatch permanent ^/$
          http://www.example.com/startpage.html</code></p></div>
    
        <p>あるいは、一時的にサイトのすべてのページを他のサイトの特定の
        ページへリダイレクトするときは、以下を使います:</p>
    
    <div class="example"><p><code>RedirectMatch temp .*
          http://othersite.example.com/startpage.html</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">リバースプロキシ</a></h2>
    
    <p>Apache は遠隔地にあるドキュメントをローカルのサーバの URL 空間に
    持ってくることもできます。この手法は<em>リバースプロキシ</em>と呼ばれています。
    ウェブサーバが遠隔地のドキュメントを取得してクライアントに送り返すのが
    プロキシサーバの動作のように見えるからです。クライアントにはドキュメントが
    リバースプロキシサーバから送られてきているように見える点が通常の
    プロキシとは異なります。</p>
    
    <p>次の例では、クライアントが <code>/foo/</code> ディレクトリの下にある
    ドキュメントをリクエストすると、サーバが <code>internal.example.com</code> の
    <code>/bar/</code> ディレクトリから取得して、さもローカルサーバからの
    ドキュメントのようにしてクライアントに返します。</p>
    
    <div class="example"><p><code>
    ProxyPass /foo/ http://internal.example.com/bar/<br />
    ProxyPassReverse /foo/ http://internal.example.com/bar/<br />
    ProxyPassReverseCookieDomain internal.example.com public.example.com<br />
    ProxyPassReverseCookiePath /foo/ /bar/
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> ディレクティブは
    サーバが適切なドキュメントを取得するように設定し、
    <code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> ディレクティブは
    <code>internal.example.com</code> からのリダイレクトがローカルサーバの
    適切なディレクトリを指すように書き換えます。
    同様に <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code>
    と <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code>
    でバックエンド側サーバの発行した Cookie を書き換えることができます。</p>
    <p>ただし、ドキュメントの中のリンクは書き換えられない、
    ということは知っておいてください。
    ですから、<code>internal.example.com</code> への絶対パスによるリンクでは、
    クライアントがプロキシサーバを抜け出して <code>internal.example.com</code> に
    直接リクエストを送る、ということになります。
    サードパーティ製モジュールの <a href="http://apache.webthing.com/mod_proxy_html/">mod_proxy_html</a>
    は、HTML と XHTML 中のリンクを書き換えることができます。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">リライトエンジン</a></h2>
    
        <p>より一層強力な置換が必要なときは、<code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
        が提供するリライトエンジンが役に立つでしょう。
        このモジュールにより提供されるディレクティブは
        ブラウザの種類、リクエスト元の IP アドレスなどのリクエストの特徴を
        使って送り返すコンテンツの場所を決めます。さらに、<code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
        は外部のデータベースファイルやプログラムを使ってリクエストの扱い方を
        決めることもできます。リライトエンジンは上で挙げられている三つのマッピング
        すべてを行なうことができます: 内部のリダイレクト (エイリアス)、
        外部のリダイレクト、プロキシです。mod_rewrite を使う多くの実用的な例は
        <a href="misc/rewriteguide.html">URL リライトガイド</a>
        で説明されています。</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="notfound" id="notfound">File Not Found</a></h2>
    
        <p>必ず、リクエストされた URL に対応するファイルがファイルシステムに
        無いという場合が発生します。これが起こるのにはいくつかの理由があります。
        場合によっては、ドキュメントを別の場所に移動した結果であることがあります。
        この場合は、クライアントにリソースの新しい位置を知らせるために
        <a href="#redirect">URL リダイレクション</a>を使うのが最善の方法です。
        そうすることによって、リソースは新しい位置に移動しているけれども、
        古いブックマークやリンクが動作し続けるようにすることができます。</p>
    
        <p>"File Not Found" エラーのもう一つのよくある理由は、
        ブラウザへの直接入力や HTML リンクからの偶発的な URL の入力間違いです。
        Apache はこの問題を改善するために、<code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code>
        モジュール (意図的な綴り間違い)
        (訳注: 正しくは spelling) を提供しています。このモジュールが
        使用されているときは、"File Not Found" エラーを横取りして、
        似たファイル名のリソースを探します。もし一つだけ見つかった場合は
        mod_speling はクライアントに正しい位置を知らせるために HTTP リダイレクトを
        送ります。もし複数の「近い」ファイルが見つかった場合は、それら
        代替となりえるもののリストがクライアントに表示されます。</p>
    
        <p>mod_speling の非常に有用な機能は、大文字小文字を区別せずに
        ファイル名を比較するものです。これは URL と unix の
        ファイルシステムが両方とも大文字小文字を区別するものである、
        ということをユーザが知らないシステムで役に立ちます。ただし、
        時折の URL 訂正程度で済まず、mod_speling をより多く使用すると、サーバに
        さらなる負荷がかかります。すべての「正しくない」リクエストの後に
        URL のリダイレクトとクライアントからの新しいリクエストがくることに
        なりますから。</p>
    
        <p>コンテンツの位置を決めようとするすべての試みが失敗すると、
        Apache は、HTTP ステータスコード 404 (file not found) と共に
        エラーページを返します。このエラーページの外観は
        <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> 
        ディレクティブで制御され、
        <a href="custom-error.html">カスタムエラーレスポンス</a> で
        説明されているように、柔軟な設定を行なうことができます。</p>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/urlmapping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/caching.html.fr.utf8�������������������������������������������������������0000664�0001751�0001751�00000160764�14740503670�020630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Guide de la mise en cache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Guide de la mise en cache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/caching.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/caching.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/caching.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Ce document complète la documentation de référence des modules
        <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>,
        <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> et du programme <a href="programs/htcacheclean.html">htcacheclean</a>.
        Il décrit l'utilisation des fonctionnalités de mise en
        cache du serveur HTTP Apache
        pour accélérer les services web et mandataire, tout en évitant les problèmes
        courants et les erreurs de configuration.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#http-caching">Mise en cache HTTP à trois états RFC2616</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Exemples de configuration du cache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#socache-caching">Mise en cache générale d'objets partagés à deux états de forme
        clé/valeur</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-caching">Mise en cache à base de fichiers spécialisés</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#security">Considérations sur la sécurité</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
        
    
        <p>Le serveur HTTP Apache offre tout un ensemble de fonctionnalités
        de mise en cache qui ont été conçues pour améliorer les performances
        du serveur de différentes manières.</p>
    
        <dl>
            <dt>Mise en cache HTTP à trois états RFC2616</dt>
            <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> et son module de fournisseur
    	<code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> proposent une mise en cache
    	intelligente de niveau HTTP. Le contenu proprement dit est
    	stocké dans le cache, et mod_cache vise à respecter tous les
    	en-têtes HTTP, ainsi que les options qui contrôlent la mise en
    	cache du contenu comme décrit dans la <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">Section
    	13 de la RFC2616</a>. <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> peut gérer des
    	configurations de mise en cache simples, mais aussi complexes
    	comme dans les cas où vous avez à faire à des contenus mandatés,
    	à des contenus locaux dynamiques, ou lorsque vous avez besoin
    	d'accélérer l'accès aux fichiers locaux situés sur disque
    	supposé lent.
            </dd>
    
            <dt>Mise en cache d'objets partagés de forme clé/valeur à deux
    	états</dt>
            <dd>
                L'<a href="socache.html">API du cache d'objets partagés</a> (socache)
    	    et ses modules de fournisseurs
    	    proposent une mise en cache d'objets partagés à base de
    	    couples clé/valeur de niveau serveur. Ces modules sont
    	    conçus pour la mise en cache de données de bas niveau comme
    	    les sessions SSL et les données d'authentification. les
    	    serveurs d'arrière-plan permettent le stockage des données
    	    au niveau serveur en mémoire partagée, ou au niveau
    	    datacenter dans un cache comme memcache ou distcache.
            </dd>
    
            <dt>Mise en cache de fichiers spécialisée</dt>
            <dd>
                <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> offre la possibilité de
    	    précharger des fichiers en mémoire au démarrage du serveur,
    	    et peut améliorer les temps d'accès et sauvegarder les
    	    gestionnaires de fichiers pour les fichiers qui font l'objet
    	    d'accès fréquents, évitant ainsi d'avoir à accéder au disque
    	    à chaque requête.
            </dd>
        </dl>
    
        <p>Pour tirer parti efficacement de ce document, les bases de HTTP doivent
        vous être familières, et vous devez avoir lu les sections
        <a href="urlmapping.html">Mise en correspondance des
        URLs avec le système de fichiers</a> et
        <a href="content-negotiation.html">Négociation sur le contenu</a>
        du guide de l'utilisateur.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="http-caching" id="http-caching">Mise en cache HTTP à trois états RFC2616</a></h2>
    
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code></li><li><code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li><li><code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code></li></ul></td></tr></table>
    
        <p>Le module <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> permet de tirer avantage du
        mécanisme de mise en cache en ligne faisant partie
        intégrante du protocole HTTP, et décrit dans la <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">section
        13 de la RFC2616</a>.</p>
    
        <p>A la différence d'un cache simple clé/valeur à deux états où le
        contenu est supprimé lorsqu'il est périmé, un cache HTTP comporte un
        mécanisme permettant de conserver temporairement un contenu périmé,
        de demander au serveur original si ce contenu périmé a été modifié,
        et dans le cas contraire de le rendre à nouveau valable.</p>
    
        <p>Une entrée d'un cache HTTP peut se présenter sous un de ces trois
        états :</p>
    
        <dl>
        <dt>Frais</dt>
        <dd>
            Si un contenu est suffisamment récent (plus jeune que sa
    	<strong>durée de fraîcheur</strong>), il est considéré comme
    	<strong>frais</strong>. Un cache HTTP peut servir un contenu
    	frais sans avoir à demander quoi que ce soit au serveur
    	d'origine.
        </dd>
        <dt>Périmé</dt>
        <dd>
            <p>Si le contenu est trop ancien (plus vieux que sa
    	<strong>durée de fraîcheur</strong>), il est considéré comme
    	<strong>périmé</strong>. Un cache HTTP doit contacter le serveur
    	original pour vérifier si le contenu, même s'il est périmé, est
    	encore à jour avant de le servir au client. Soit le serveur
    	original va répondre en envoyant un contenu de remplacement si
    	le contenu périmé n'est plus à jour, soit dans le cas idéal il
    	renverra un code pour signaler au cache que le contenu est
    	encore à jour, et qu'il est inutile de le générer ou de
    	l'envoyer à nouveau. Le contenu repasse à l'état "frais" et le
    	cycle continue.</p>
    
            <p>Le protocole HTTP permet au cache de servir des données
    	périmées dans certaines circonstances, comme lorsqu'une
    	tentative de rafraîchir une entrée depuis un serveur original
    	se solde par un échec avec un code d'erreur 5xx, ou lorsqu'une
    	autre requête est déjà en train d'essayer de rafraîchir la même
    	entrée. Dans ces cas, un en-tête <code>Warning</code> est ajouté
    	à la réponse.</p>
        </dd>
        <dt>Non Existent</dt>
        <dd>
            Si le cache est plein, il se réserve la possibilité de supprimer
    	des entrées pour faire de la place. Une entrée peut être
    	supprimée à tout moment, qu'elle soit fraîche ou périmée.
    	L'outil <a href="programs/htcacheclean.html">htcacheclean</a>
    	peut être utilisé à la demande, ou lancé en tant que démon afin
    	de conserver la taille du cache ou le nombre d'inodes en deçà de
    	valeurs spécifiées. Cet outil essaie cependant de
    	supprimer les entrées périmées avant les entrées fraîches.
        </dd>
        </dl>
    
        <p>Le fonctionnement détaillé d'un cache HTTP est décrit dans la <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">Section
        13 de la RFC2616</a>.</p>
    
        <h3>Interaction avec le serveur</h3>
          
    
          <p>Le module <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> interagit avec le serveur
          à deux niveaux possibles en fonction de la directive <code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code> :
          </p>
    
          <dl>
            <dt>Phase de gestion rapide</dt>
            <dd>
              <p>Cette phase se déroule très tôt au cours du traitement de
    	  la requête, juste après l'interprétation de cette dernière. Si
    	  le contenu se trouve dans le cache, il est servi immédiatement
    	  et pratiquement tout le reste du traitement de la requête est
    	  court-circuité.</p>
    
                  <p>Dans ce scénario, le cache se comporte comme s'il avait
    	      été "boulonné" à l'entrée du serveur.</p>
                  
                  <p>Ce mode possède les meilleures performances car la
    	      majorité des traitements au niveau du serveur sont
    	      court-circuités. Cependant, il court-circuite aussi les
    	      phases d'authentification et d'autorisation du traitement
    	      au niveau du serveur, et il doit donc être utilisé avec
    	      prudence lorsque que ces phases sont importantes.</p>
    
    	      <p>Les requêtes comportant un en-tête "Authorization"
    	      (comme par exemple l'authentification HTTP basique) ne
    	      peuvent être ni mises en cache, ni servies depuis ce
    	      dernier lorsque <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> s'exécute dans
    	      cette phase.</p>
              </dd>
              <dt>Phase de gestion normale</dt>
              <dd>
                  <p>Cette phase se déroule très tard au cours du traitement
    	      de la requête, en fait après toutes les phases de ce
    	      traitement.</p>
    
                  <p>Dans ce scénario, le cache se comporte comme s'il avait
    	      été "boulonné" à la sortie du serveur.</p>
    
                  <p>Ce mode offre la plus grande souplesse, car il permet
    	      de faire intervenir la mise en cache en un point
    	      précisément spécifié de la chaîne de filtrage, et le
    	      contenu issu du cache peut être filtré ou personnalisé
    	      avant d'être servi au client.</p>
              </dd>
            </dl>
    
            <p>Si l'URL ne se trouve pas dans le cache,
    	<code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> ajoutera un <a href="filter.html">filtre</a> à la chaîne de filtrage afin
    	d'enregistrer la réponse dans le cache, puis passera la main
    	pour permettre le déroulement normal de la suite du traitement
    	de la requête. Si la mise en cache du contenu est autorisée, il
    	sera enregistré dans le cache pour pouvoir être servi à nouveau
    	; dans le cas contraire, le contenu sera ignoré.</p>
    
            <p>Si le contenu trouvé dans le cache est périmé, le module
    	<code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> convertit la requête en
    	<strong>requête conditionnelle</strong>. Si le serveur original
    	renvoie une réponse normale, elle est enregistrée dans le cache
    	en lieu et place du contenu périmé. Si le serveur original
    	renvoie une réponse "304 Not Modified", le contenu repasse à
    	l'état "frais" et est servi par le filtre au lieu d'être
    	sauvegardé.</p>
        
    
        <h3>Amélioration du taux de présence dans le cache</h3>
          
    
          <p>Lorsqu'un serveur virtuel est connu sous la forme d'un des
          nombreux alias du serveur, la définition de la directive
          <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code> à
          <code>On</code> peut augmenter de manière significative le nombre
          de correspondances positives dans le cache. Cela est dû au fait
          que la clé du cache contient le nom d'hôte du serveur virtuel.     
          Avec <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code> positionnée
          à <code>On</code>,
          les hôtes virtuels possédant plusieurs noms de serveur ou alias ne
          généreront pas d'entités de cache différentes, et le contenu sera mis en
          cache en faisant référence au nom d'hôte canonique.</p>
    
        
    
        <h3>Durée de fraîcheur</h3>
          
    
           <p>Un contenu bien formé destiné à être mis en cache doit déclarer
           explicitement une durée de fraîcheur à l'aide des champs
           <code>max-age</code> ou <code>s-maxage</code> de l'en-tête
           <code>Cache-Control</code>, ou en incluant un en-tête
           <code>Expires</code>.</p>
          
          <p>De plus, un client peut passer outre la durée de fraîcheur
          définie pour le serveur d'origine en ajoutant son propre en-tête
          <code>Cache-Control</code> à la requête. Dans ce cas, c'est la
          durée de fraîcheur la plus basse entre la requête et la réponse
          qui l'emporte.</p>
    
          <p>Lorsque cette durée de fraîcheur est absente de la requête ou
          de la réponse, une durée de fraîcheur par défaut s'applique. La
          durée de fraîcheur par défaut des entrées du cache est d'une heure
          ; elle peut cependant être facilement modifiée à l'aide de
          la directive <code class="directive"><a href="./mod/mod_cache.html#cachedefaultexpire">CacheDefaultExpire</a></code>.</p>
    
          <p>Si une réponse ne contient pas d'en-tête <code>Expires</code> mais
          inclut un en-tête <code>Last-Modified</code>, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>
          peut déduire une durée de fraîcheur en se basant sur une
          heuristique, qui peut être contrôlée à l'aide de la directive <code class="directive"><a href="./mod/mod_cache.html#cachelastmodifiedfactor">CacheLastModifiedFactor</a></code>.</p>
    
          <p>Pour les contenus locaux, ou les contenus distants qui ne
          spécifient pas leur propre en-tête <code>Expires</code>,
          <code class="module"><a href="./mod/mod_expires.html">mod_expires</a></code> permet de régler finement la durée de
          fraîcheur à l'aide des paramètres <code>max-age</code> et
          <code>Expires</code>.</p>
    
          <p>On peut aussi contrôler la durée de fraîcheur maximale en utilisant
          la directive <code class="directive"><a href="./mod/mod_cache.html#cachemaxexpire">CacheMaxExpire</a></code>.</p>
    
        
    
        <h3>Guide succinct des requêtes conditionnelles</h3>
          
    
         <p>Lorsqu'un contenu du cache est périmé, httpd modifie la requête
         pour en faire une requête conditionnelle</p>
    
          <p>Lorsque la réponse originale du cache contient un en-tête
          <code>ETag</code>, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> ajoute un en-tête
          <code>If-None-Match</code> à la requête envoyée au serveur
          d'origine. Lorsque la réponse originale du cache contient un en-tête
          <code>Last-Modified</code>, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> ajoute un en-tête
          <code>If-Modified-Since</code> à la requête envoyée au serveur
          d'origine. Dans ces deux cas, la requête devient une requête
          <strong>conditionnelle</strong>.</p>
    
          <p>Lorsqu'un serveur d'origine reçoit une requête conditionnelle,
          il vérifie si le paramètre Etag ou Last-Modified a été modifié en
          fonction des paramètres de la requête. Si ce n'est pas le cas, il
          répondra avec le message lapidaire "304 Not Modified". Cela
          informe le cache que le contenu est périmé mais encore à jour, et
          peut être utilisé tel quel pour les prochaines requêtes jusqu'à ce
          qu'il atteigne à nouveau sa date de péremption.</p>
    
          <p>Si le contenu a été modifié, il est servi comme s'il s'agissait
          d'une requête normale et non conditionnelle.</p>
    
          <p>Les requêtes conditionnelles offrent deux avantages. D'une
          part, il est facile de déterminer si le contenu du serveur
          d'origine correspond à celui situé
          dans le cache, et ainsi d'économiser la consommation de ressources
          nécessaire au transfert du contenu dans son ensemble.</p>
    
          <p>D'autre part, un serveur d'origine bien conçu sera configuré de
          telle manière que les requêtes conditionnelles nécessitent pour
          leur production bien moins de ressources qu'une réponse complète.
          Dans le cas des fichiers statiques, il suffit en général d'un
          appel système de type <code>stat()</code> ou similaire pour
          déterminer si la taille ou la date de modification du fichier a
          été modifiée. Ainsi, même un contenu local pourra être servi plus
          rapidement depuis le cache s'il n'a pas été modifié.</p>
          
          <p>Il serait souhaitable que tous les serveurs d'origine
          supportent les requêtes conditionnelles, car dans le cas
          contraire, ils répondent comme s'il s'agissait d'une requête
          normale, et le cache répond comme si le contenu avait été
          modifié et enregistre ce dernier. Le cache se comporte alors
          comme un simple cache à deux état, où le contenu est servi s'il
          est à jour, ou supprimé dans le cas contraire.</p>
        
    
        <h3>Que peut-on mettre en cache ?</h3>
          
    
          <p>La liste complète des conditions nécessaires pour qu'une
          réponse puisse être enregistrée dans un cache HTTP est fournie
          dans la <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4">section
          13.4 Response Cacheability de la RFC2616</a>, et peut se résumer
          ainsi&nbsp;:</p>
    
          <ol>
            <li>La mise en cache doit être activée pour cette URL. Voir les
    	directives <code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code> et <code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code>.</li>
    
            <li>Si la reponse possède un code de statut HTTP autre que 200, 203, 300, 301
    	ou 410, elle doit aussi comporter un en-tête "Expires" ou
    	"Cache-Control".</li>
    
            <li>La requête doit être de type HTTP GET.</li>
    
    	<li>Si la réponse contient un en-tête "Authorization:", elle doit aussi
    	contenir une option "s-maxage", "must-revalidate" ou "public" dans l'en-tête
    	"Cache-Control:".</li>
    
            <li>Si l'URL contient une chaîne de requête
    	(provenant par exemple d'une méthode GET de formulaire HTML), elle ne
    	sera pas mise en cache, à moins que la réponse ne
    	spécifie explicitement un délai d'expiration à l'aide d'un
    	en-tête "Expires:" ou une directive max-age ou s-maxage de
    	l'en-tête "Cache-Control:" comme indiqué dans les
    	sections 13.2.1. et 13.9 de la RFC2616.</li>
    
            <li>Si la réponse a un statut de 200 (OK), elle doit aussi contenir
    	au moins un des en-têtes "Etag", "Last-Modified" ou
            "Expires", ou une directive max-age ou s-maxage de
    	l'en-tête "Cache-Control:", à moins que la directive
            <code class="directive"><a href="./mod/mod_cache.html#cacheignorenolastmod">CacheIgnoreNoLastMod</a></code>
            ne précise d'autres contraintes.</li>
    
            <li>Si la réponse contient l'option "private" dans un en-tête
    	"Cache-Control:", elle ne sera pas mise en cache à moins que la
    	directive
            <code class="directive"><a href="./mod/mod_cache.html#cachestoreprivate">CacheStorePrivate</a></code>
    	ne précise d'autres contraintes.</li>
    
            <li>De même, si la réponse contient l'option "no-store" dans un en-tête
            "Cache-Control:", elle ne sera pas mise en cache à moins que la
    	directive
            <code class="directive"><a href="./mod/mod_cache.html#cachestorenostore">CacheStoreNoStore</a></code>
    	n'ait été utilisée.</li>
    
            <li>Une réponse ne sera pas mise en cache si elle comporte un en-tête
    	"Vary:" contenant le caractère "*" qui correspond à toute
    	chaîne de caractères.</li>
          </ol>
        
    
        <h3>Qu'est ce qui ne doit pas être mis en cache ?</h3>
          
    
          <p>Le client qui crée la requête ou le serveur d'origine qui
          génère la réponse doit être à même de déterminer si le contenu
          doit pouvoir être mis en cache ou non en définissant correctement
          l'en-tête <code>Cache-Control</code>, et
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> sera alors en mesure de satisfaire les
          souhaits du client ou du serveur de manière appropriée.
          </p>
    
          <p>Les contenus qui varient au cours du temps, ou en fonction de
          particularités de la requête non prises en compte par la
          négociation HTTP ne doivent pas être mis en cache. Ce type de
          contenu doit se déclarer lui-même "à ne pas mettre en cache" à l'aide de
          l'en-tête <code>Cache-Control</code>.</p>
          
          <p>Si le contenu change souvent, suite par exemple à une durée de
          fraîcheur de l'ordre de la minute ou de la seconde, il peut tout
          de même être mis en cache, mais il est alors fortement souhaitable
          que le serveur d'origine supporte correctement les
          <strong>requêtes conditionnelles</strong> afin que des réponses
          complètes ne soient pas systématiquement générées.</p>
    
          <p>Un contenu qui varie en fonction d'en-têtes de requête fournis
          par le client peut être mis en cache, sous réserve d'une
          utilisation appropriée de l'en-tête de réponse <code>Vary</code>.</p>
        
    
        <h3>Contenu variable et/ou négocié</h3>
          
    
          <p>Lorsque le serveur d'origine est configuré pour servir des
          contenus différents en fonction de la valeur de certains en-têtes
          de la requête, par exemple pour servir une ressource en plusieurs
          langages à partir d'une seule URL, le mécanisme de mise en cache
          d'HTTP permet de mettre en cache plusieurs variantes de la même
          page à partir d'une seule URL.</p>
          
          <p>Pour y parvenir, le serveur d'origine ajoute un en-tête
          <code>Vary</code> pour indiquer quels en-têtes doivent être pris
          en compte par un cache pour déterminer si deux variantes sont
          différentes l'une de l'autre.</p>
    
          <p>Si par exemple, une réponse est reçue avec l'en-tête Vary suivant,</p>
    
          <div class="example"><p><code>
    Vary: negotiate,accept-language,accept-charset
          </code></p></div>
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> ne servira aux demandeurs que le contenu
          mis en cache qui correspond au contenu des en-têtes accept-language et
          accept-charset de la requête originale.</p>
    
          <p>Plusieurs variantes d'un contenu peuvent être mises en cache
          simultanément ; <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> utilise l'en-tête
          <code>Vary</code> et les valeurs correspondantes des en-têtes de
          la requête spécifiés dans ce dernier pour
          déterminer quelle variante doit être servie au client.</p>
              
        
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples de configuration du cache</a></h2>
    
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code></li><li><code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code></li><li><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cacheroot">CacheRoot</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code></li><li><code class="directive"><a href="./mod/mod_cache_socache.html#cachesocache">CacheSocache</a></code></li></ul></td></tr></table>
    
        <h3><a name="disk" id="disk">Mise en cache sur disque</a></h3>
          
    
          <p>Le module <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> s'appuie sur des
          implémentations de stockage sous-jacentes spécifiques pour gérer
          le cache ; à ce titre, <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> fournit la
          prise en charge de la mise en cache sur disque.</p>
    
          <p>En général, le module se configure comme suit :</p>
    
          <pre class="prettyprint lang-config">CacheRoot   "/var/cache/apache/"
    CacheEnable disk /
    CacheDirLevels 2
    CacheDirLength 1</pre>
    
    
        <p>Il est important de savoir que, les fichiers mis en cache étant stockés
        localement, la mise en cache par l'intermédiaire du système d'exploitation
        sera en général aussi appliquée à leurs accès. Si bien que même si les
        fichiers sont stockés sur disque, s'il font l'objet d'accès fréquents,
        il est probable que le système d'exploitation s'appliquera à ce qu'ils
        soient servis à partir de la mémoire.</p>
    
        
    
        <h3>Comprendre le stockage dans le cache</h3>
          
    
          <p>Pour stocker des entités dans le cache,
          le module <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> crée une empreinte (hash) de 22
          caractères de l'URL qui a fait l'objet d'une requête. Cette empreinte
          comprend le nom d'hôte, le protocole, le port, le chemin et tout argument
          de type CGI associé à l'URL, ainsi que les éléments
          spécifiés dans l'en-tête Vary afin d'être sûr que plusieurs URLs
          n'interfèrent pas entre elles.</p>
    
          <p>Chaque position de l'empreinte peut contenir un caractère
          choisi parmi 64 caractères différents, il y a donc
          64^22 possibilités pour une empreinte. Par exemple, une URL peut posséder
          l'empreinte <code>xyTGxSMO2b68mBCykqkp1w</code>. Cette empreinte est
          utilisée pour préfixer les noms de fichiers spécifiques à cette URL à
          l'intérieur du cache&nbsp;; cependant, elle est tout d'abord placée dans les
          répertoires du cache selon les directives
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code> et
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>.</p>
    
          <p>La directive
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code>
          définit le nombre de niveaux de sous-répertoires, et
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>
          le nombre de caractères composant le nom des sous-répertoires. Dans
          l'exemple donné plus haut, l'empreinte se trouvera à :
          <code>/var/cache/apache/x/y/TGxSMO2b68mBCykqkp1w</code>.</p>
    
          <p>Cette technique a pour but principal de réduire le nombre de
          sous-répertoires ou de fichiers contenus dans un répertoire particulier,
          car le fonctionnement de la plupart des systèmes de fichiers est ralenti
          quand ce nombre augmente. Avec la valeur "1" pour la directive
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>,
          il peut y avoir au plus 64 sous-répertoires à un niveau quelconque.
          Avec la valeur "2", il peut y en avoir 64 * 64, etc...
          A moins d'avoir une bonne raison pour ne pas le faire, l'utilisation de
          la valeur "1" pour la directive
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>
          est recommandée.</p>
    
          <p>Le paramétrage de la directive
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code>
          dépend du nombre de fichiers que vous pensez stocker dans le cache.
          Avec une valeur de "2" comme dans l'exemple donné plus haut,
          4096 sous-répertoires peuvent être créés au total. Avec 1 million de
          fichiers dans le cache, cela équivaut à environ 245 URLs mises en cache
          dans chaque répertoire.</p>
    
          <p>Chaque URL nécessite au moins deux fichiers dans le cache. Ce sont en
          général un fichier ".header", qui contient des meta-informations à propos
          de l'URL, comme la date de son arrivée à expiration,
          et un fichier ".data" qui est la copie exacte du contenu à servir.</p>
    
          <p>Dans le cas d'un contenu négocié via l'en-tête "Vary", un répertoire
          ".vary" sera créé pour l'URL en question. Ce répertoire contiendra de
          multiples fichiers ".data" correspondant aux différents contenus
          négociés.</p>
        
    
        <h3>Maintenance du cache sur disque</h3>
          
    
          <p>Le module <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> n'effectue aucune
          régulation de l'espace disque utilisé par le cache, bien qu'il
          s'arrête en douceur en cas d'erreur disque et se comporte alors
          comme si le cache n'avait jamais existé.</p>
    
          <p>Par contre, l'utilitaire
          <a href="programs/htcacheclean.html">htcacheclean</a> fourni avec
          httpd
          vous permet de nettoyer le cache périodiquement.
          Déterminer la fréquence à laquelle lancer <a href="programs/htcacheclean.html">htcacheclean</a> et la taille souhaitée
          pour le cache est une tâche relativement complexe et il vous faudra de
          nombreux essais et erreurs pour arriver à sélectionner des valeurs
          optimales.</p>
    
          <p><a href="programs/htcacheclean.html">htcacheclean</a> opère selon deux
          modes. Il peut s'exécuter comme démon résident, ou être lancé
          périodiquement par cron. <a href="programs/htcacheclean.html">htcacheclean</a> peut mettre une heure
          ou plus pour traiter de très grands caches (plusieurs dizaines de
          Gigaoctets) et si vous l'exécutez à partir de cron, il vous est
          conseillé de déterminer la durée typique d'un traitement, afin d'éviter
          d'exécuter plusieurs instances à la fois.</p>
    
          <p>Il est aussi conseillé d'attribuer un niveau de priorité "nice"
          approprié à htcacheclean de façon à ce qu'il n'effectue pas trop
          d'accès disque pendant le fonctionnement du serveur.</p>
    
          <p class="figure">
          <img src="images/caching_fig1.gif" alt="" width="600" height="406" /><br />
          <a id="figure1" name="figure1"><dfn>Figure 1</dfn></a>: Croissance
          typique du cache / séquence de nettoyage.</p>
    
          <p>Comme <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> ne tient pas compte de l'espace
          utilisé, vous devez vous assurer que
          <a href="programs/htcacheclean.html">htcacheclean</a> est configuré de
          façon à laisser suffisamment d'"espace de croissance"
          à la suite d'un nettoyage.</p>
        
    
        <h3><a name="memcache" id="memcache">Cache en mémoire</a></h3>
          
    
          <p>En utilisant le module <code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code>,
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> peut mettre en cache des données à partir de
          diverses implémentations aussi nommées "fournisseurs". Par exemple, en
          utilisant le module <code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code>, on peut
          spécifier que c'est <a href="http://memcached.org">memcached</a> qui doit
          être utilisé comme mécanisme de stockage sous-jacent.</p>
    
          <p>Typiquement, le module sera configuré comme suit :</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache memcache:memcd.example.com:11211</pre>
    
    
          <p>En outre, il est possible de spécifier plusieurs serveurs
          <code>memcached</code> en les ajoutant à la fin de la ligne
          <code>CacheSocache memcache:</code> et en les séparant par des virgules&nbsp;:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache memcache:mem1.example.com:11211,mem2.example.com:11212</pre>
    
    
          <p>Divers autres fournisseurs <code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code> utilisent
          aussi ce format. Par exemple&nbsp;:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache shmcb:/path/to/datafile(512000)</pre>
    
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache dbm:/path/to/datafile</pre>
    
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="socache-caching" id="socache-caching">Mise en cache générale d'objets partagés à deux états de forme
        clé/valeur</a></h2>
    
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code></li><li><code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code></li><li><code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code></li><li><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></li><li><code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code></li><li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code></li></ul></td></tr></table>
        
        <p>Le serveur HTTP Apache fournit un cache d'objets partagés de bas
        niveau pour la mise en cache d'informations comme les sessions SSL
        ou les données d'authentification dans l'interface <a href="socache.html">socache</a>.</p>
    
        <p>Pour chaque implémentation, un module supplémentaire est fourni
        qui offre les services d'arrière-plan suivants&nbsp;:</p>
    
        <dl>
        <dt><code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code></dt>
        <dd>Cache d'objets partagés basé sur DBM.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code></dt>
        <dd>Cache d'objets partagés basé sur Distcache.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></dt>
        <dd>Cache d'objets partagés basé sur Memcache.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code></dt>
        <dd>Cache d'objets partagés basé sur la mémoire partagée.</dd>
        </dl>
    
        <h3><a name="mod_authn_socache-caching" id="mod_authn_socache-caching">Mise en cache des données d'authentification</a></h3>
          
    
          <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code></li></ul></td></tr></table>
    
          <p>Le module <code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code> permet la mise en
          cache des données issues d'une authentification, diminuant ainsi
          la charge des serveurs d'authentification d'arrière-plan.</p>
    
        
    
        <h3><a name="mod_ssl-caching" id="mod_ssl-caching">Mise en cache des sessions SSL</a></h3>
          
    
          <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code></li></ul></td></tr></table>
    
          <p>Le module <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> utilise l'interface
          <code>socache</code> pour fournir un cache de session et un cache
          de base.</p>
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-caching" id="file-caching">Mise en cache à base de fichiers spécialisés</a></h2>
    
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code></li><li><code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code></li></ul></td></tr></table>
    
        <p>Sur les plateformes où le système de fichiers peut être lent, ou
        lorsque les descripteurs de fichiers sont gourmands en ressources,
        il est possible de précharger des fichiers en mémoire au démarrage
        du serveur.</p>
    
        <p>Sur les systèmes où l'ouverture des fichiers est lente, il est
        possible d'ouvrir le fichier au démarrage du serveur et de mettre en
        cache le descripteur de fichier. Ces options peuvent vous aider sur
        les systèmes où l'accès aux fichiers statiques est lent.</p>
    
        <h3><a name="filehandle" id="filehandle">Mise en cache des descripteurs de fichier</a></h3>
          
    
          <p>Le processus d'ouverture d'un fichier peut être en soi une
          source de ralentissement, en particulier sur les systèmes de
          fichiers sur le réseau. httpd permet d'éviter ce ralentissement en
          maintenant un cache des descripteurs de fichiers ouverts pour les
          fichiers souvent servis. Actuellement, httpd fournit une seule
          implémentation de mise en cache des descripteurs de fichiers.</p>
    
          <h4>CacheFile</h4>
            
    
            <p>La forme la plus basique de mise en cache que propose httpd
    	est la mise en cache des descripteurs de fichiers fournie par le
    	module <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code>. Plutôt que de mettre en
    	cache le contenu des fichiers, ce cache maintient une table des
    	descripteurs de fichiers ouverts. Les fichiers devant faire
    	l'objet d'une mise en cache de ce type sont spécifiés dans le
    	fichier de configuration via la directive <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code>.</p>
    
            <p>La directive <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code> informe httpd
    	qu'il doit ouvrir le fichier lors de son démarrage et qu'il doit
    	réutiliser le descripteur de fichier mis en cache pour tous les
    	accès futurs à ce fichier.</p>
    
            <pre class="prettyprint lang-config">CacheFile /usr/local/apache2/htdocs/index.html</pre>
    
    
            <p>Si vous désirez mettre en cache un grand nombre de fichiers
    	de cette manière, vous devez vous assurer que le nombre maximal
    	de fichiers ouverts pour votre système d'exploitation est défini
    	à une valeur suffisante.</p>
    
            <p>Bien que l'utilisation de la directive <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code> n'entraîne pas de
    	mise en cache du contenu du fichier proprement dit, elle
    	implique que si le fichier est modifié pendant l'exécution du
    	serveur, ces modifications ne seront pas prises en compte. Le
    	fichier sera toujours servi dans l'état où il se trouvait au
    	moment du démarrage du serveur.</p>
    
            <p>Si le fichier est supprimé pendant l'exécution du serveur, ce
    	dernier conservera le descripteur de fichier ouvert associé et
    	servira le fichier dans l'état où il se trouvait au
    	moment du démarrage du serveur. Cela signifie aussi que même si
    	le fichier a été supprimé, et n'apparaît donc plus dans le
    	système de fichiers, l'espace disque libéré ne sera disponible
    	qu'une fois le serveur httpd arrêté et donc le descripteur de
    	fichier fermé.</p>
          
    
        
    
        <h3><a name="inmemory" id="inmemory">In-Memory Caching</a></h3>
          
    
        <p>Servir un contenu directement depuis la mémoire système est
        universellement reconnu comme la méthode la plus rapide. Lire des fichiers
        depuis un contrôleur de disque ou pire, depuis un réseau distant est plus
        lent de plusieurs ordres de grandeur. Les contrôleurs de disque réalisent
        en général des opérations mécaniques, et l'accès au réseau est limité par la
        bande passante dont vous disposez. Par contre, les temps d'accès à la
        mémoire sont de l'ordre de la nano-seconde.</p>
    
        <p>Cependant la mémoire système n'est pas bon marché&nbsp;; à capacité égale,
        c'est de loin le type de stockage le plus coûteux et il est important de
        s'assurer qu'elle est utilisée efficacement. Le fait de mettre en cache
        des fichiers en mémoire diminue d'autant la quantité de mémoire système
        disponible. Comme nous le verrons plus loin, ce n'est pas un problème en
        soi dans le cas de la mise en cache par l'intermédiaire du système
        d'exploitation, mais si l'on utilise la mise en cache en mémoire propre à
        httpd, il faut prendre garde à ne pas allouer trop de mémoire au cache.
        Sinon le système sera contraint d'utiliser le swap, ce qui dégradera
        sensiblement les performances.</p>
    
          <h4>Mise en cache par l'intermédiaire du système d'exploitation</h4>
          
    
          <p>Dans la plupart des systèmes d'exploitation modernes, c'est le noyau
          qui gère directement la mise en cache en mémoire des données relatives
          aux fichiers. C'est une fonctionnalité puissante, et les systèmes
          d'exploitation s'en acquittent fort bien pour la plus grande partie.
          Considérons par exemple, dans le cas de Linux, la différence entre le
          temps nécessaire à la première lecture d'un fichier et le temps
          nécessaire à sa deuxième lecture;</p>
    
            <div class="example"><pre>colm@coroebus:~$ time cat testfile &gt; /dev/null
    real    0m0.065s
    user    0m0.000s
    sys     0m0.001s
    colm@coroebus:~$ time cat testfile &gt; /dev/null
    real    0m0.003s
    user    0m0.003s
    sys     0m0.000s</pre></div>
    
          <p>Même pour ce petit fichier, il y a une grande différence entre les
          temps nécessaires pour lire le fichier. Cela est dû au fait que le
          noyau a mis en cache le contenu du fichier en mémoire.</p>
    
          <p>En s'assurant de toujours pouvoir disposer de mémoire système, vous
          pouvez être assuré qu'il y aura de plus en plus de contenus de fichiers
          stockés dans ce cache. Cela peut s'avérer une méthode de mise en cache en
          mémoire très efficace, et ne nécessite aucune configuration supplémentaire
          de httpd.</p>
    
          <p>De plus, comme le système d'exploitation sait si des fichiers ont été
          supprimés ou modifiés, il peut effacer automatiquement des contenus de
          fichiers du cache lorsque cela s'avère nécessaire. Cela constitue un gros
          avantage par rapport à la mise en cache en mémoire de httpd qui n'a aucune
          possibilité de savoir si un fichier a été modifié.</p>
          
    
        <p>En dépit des performances et des avantages de la mise en cache
        automatique par le système d'exploitation, la mise en cache en mémoire
        peut être effectuée plus efficacement par httpd dans certaines
        circonstances.</p>
    
        <h4>Mise en cache à l'aide de la directive MMapFile</h4>
          
    
          <p>La directive <code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code>
          fournie par le module <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> vous permet de
          demander à httpd de charger un contenu de fichier statique en mémoire lors
          de son démarrage (à l'aide de l'appel système mmap). httpd utilisera le
          contenu chargé en mémoire pour satisfaire ultérieurement toutes les
          demandes d'accès à ce fichier.</p>
    
            <pre class="prettyprint lang-config">MMapFile /usr/local/apache2/htdocs/index.html</pre>
    
    
          <p>Comme dans le cas de la directive
          <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code>, toute
          modification du fichier ne sera plus prise en compte par httpd une fois
          ce dernier démarré.</p>
    
          <p> La directive
          <code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code> ne gardant
          pas la trace de la quantité de mémoire qu'elle alloue, vous devez prendre
          garde de ne pas en abuser. Chaque processus enfant de httpd utilisant
          sa propre réplique de la mémoire allouée, il est donc d'une importance
          critique de s'assurer que les fichiers chargés ne sont pas d'une taille
          trop importante afin d'épargner au système l'utilisation du swap.</p>
          
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Considérations sur la sécurité</a></h2>
        
    
        <h3>Autorisation et contrôle d'accès</h3>
          
    
          <p>Utiliser <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> revient sensiblement à la même
          chose qu'avoir un mandataire inverse intégré (reverse-proxy). Les requêtes
          seront servies par le module de mise en cache sauf si ce dernier
          détermine qu'un processus d'arrière-plan doit être appelé. La mise en
          cache de ressources locales modifie considérablement le modèle de
          sécurité de httpd.</p>
    
          <p>Comme le parcours de la hiérarchie d'un système de fichiers pour
          examiner le contenu d'éventuels fichiers
          <code>.htaccess</code> serait une opération très coûteuse en ressources,
          annulant partiellement de ce fait l'intérêt de la mise en cache
          (accélérer le traitement des requêtes),
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> ne se préoccupe pas de savoir s'il a
          l'autorisation de servir une entité mise en cache. En d'autres termes,
          si <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> a mis en cache un certain contenu, ce
          dernier sera servi à partir du cache tant qu'il ne sera pas arrivé à
          expiration.</p>
    
          <p>Si par exemple, votre configuration autorise l'accès à une ressource
          en fonction de l'adresse IP, vous devez vous assurer que ce contenu n'est
          pas mis en cache. Ceci est possible en utilisant la directive
          <code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code>, ou le module
          <code class="module"><a href="./mod/mod_expires.html">mod_expires</a></code>. Livré à lui-même,
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> - pratiquement comme un mandataire inverse -
          mettrait en cache le contenu lors de sa mise à dispisotion, et le servirait ensuite
          à tout client, vers n'importe quelle adresse IP.</p>
    
          <p>Lorsque la directive <code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code> est définie à
          <code>Off</code>, toutes les phases du traitement de la requête
          sont exécutées et le modèle de sécurité reste le même.</p>
    
        
    
        <h3>Piratages locaux</h3>
          
    
          <p>Etant donné que les réponses vers les utilisateurs finaux peuvent être
          servies depuis le cache, ce dernier est une cible potentielle pour ceux
          qui veulent défigurer un contenu ou interférer avec lui. Il est important
          de garder à l'esprit que l'utilisateur sous lequel tourne
          httpd doit
          toujours avoir l'accès en écriture dans le cache. Ceci est en contraste
          total avec la recommandation usuelle d'interdire à l'utilisateur sous
          lequel tourne Apache
          l'accès en écriture à tout contenu.</p>
    
          <p>Si l'utilisateur sous lequel tourne Apache est compromis,
          par exemple à cause d'une
          faille de sécurité dans un processus CGI, il est possible que le cache
          fasse l'objet d'une attaque. Il est relativement aisé d'insérer ou de
          modifier une entité dans le cache en utilisant le module
          <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>.</p>
    
          <p>Cela représente un risque relativement élevé par rapport aux autres
          types d'attaques qu'il est possible de mener sous l'utilisateur apache.
          Si vous utilisez <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>, vous devez garder ceci à
          l'esprit&nbsp;: effectuez toujours les mises à jour de httpd quand des
          correctifs de sécurité sont annoncés et exécutez les processus CGI sous un
          utilisateur autre qu'apache en utilisant <a href="suexec.html">suEXEC</a>
          dans la mesure du possible.</p>
    
        
    
        <h3>Empoisonnement du cache (Cache Poisoning)</h3>
          
    
          <p>Si vous utilisez httpd comme serveur mandataire avec mise en cache,
          vous vous exposez aussi à un éventuel "Empoisonnement du
          cache" (Cache poisoning). L'empoisonnement du cache est un terme général
          pour désigner les attaques au cours desquelles l'attaquant fait en sorte
          que le serveur mandataire renvoie à un contenu incorrect (et souvent
          indésirable) en provenance du serveur d'origine.
          </p>
    
          <p>Par exemple, si les serveur DNS qu'utilise votre système où tourne
          httpd sont vulnérables à l'empoisonnement du cache des DNS, un attaquant
          pourra contrôler vers où httpd se connecte lorsqu'il demande un contenu
          depuis le serveur d'origine.
          Un autre exemple est constitué par les attaques ainsi nommées
          "Dissimulation de requêtes HTTP" (HTTP request-smuggling).</p>
    
          <p>Ce document n'est pas le bon endroit pour une discussion approfondie
          à propos de la Dissimulation de requêtes HTTP (utilisez plutôt votre
          moteur de recherche favori)&nbsp;; il est cependant important de savoir qu'il
          est possible d'élaborer une série de requêtes, et d'exploiter une
          vulnérabilité d'un serveur web d'origine de façon que l'attaquant
          puisse contrôler entièrement le contenu renvoyé par le mandataire.</p>
        
    
        <h3>Déni de Service / Cachebusting</h3>
          
    
          <p>Le mécanisme utilisé via l'en-tête Vary permet de mettre en
          cache simultanément plusieurs variantes d'une ressource avec la
          même URL. Le cache sélectionne la variante correcte à envoyer au
          client en fonction des valeurs d'en-tête fournies par ce dernier.
          Ce mécanisme peut devenir un problème lorsqu'on tente d'appliquer
          le mécanisme des variantes à un en-tête connu pour pouvoir
          posséder un grand nombre de valeurs
          possibles en utilisation normal, comme par exemple l'en-tête
          <code>User-Agent</code>. En fonction de la popularité du site web,
          des milliers ou même des millions d'entrées de cache dupliquées
          peuvent être créées pour la même URL, submergeant les autres
          entrées du cache.</p>
          
          <p>Dans d'autres cas, il peut être nécessaire de modifier l'URL
          d'une ressource particulière à chaque requête, en général en lui
          ajoutant une chaîne "cachebuster". Si ce contenu est déclaré comme
          pouvant être mis en cache par un serveur avec une durée de
          fraîcheur significative, ces entrées peuvent submerger les entrées
          légitimes du cache. Alors que <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> fournit
          une directive <code class="directive"><a href="./mod/mod_cache.html#cacheignoreurlsessionidentifiers">CacheIgnoreURLSessionIdentifiers</a></code>,
          cette dernière doit être utilisée avec prudence pour s'assurer que
          les caches du navigateur ou du mandataire le plus proche
          (downstream proxy) ne sont pas victimes du même problème de Déni de
          service.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/caching.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/caching.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/caching.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/caching.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������httpd-2.4.64/docs/manual/dns-caveats.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000032615�14740503670�021435� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Problèmes liés au DNS avec le serveur HTTP Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Problèmes liés au DNS avec le serveur HTTP Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Cette page pourrait se résumer ainsi : configurez le
        serveur HTTP Apache de façon
        à ce qu'il n'ait pas besoin de résolution DNS pour interpréter les
        fichiers de configuration. Si httpd doit effectuer des résolutions
        DNS pour interpréter les fichiers de configuration, votre serveur
        pourra présenter des problèmes de fiabilité (en d'autres termes,
        il est possible qu'il refuse de démarrer), ou d'attaques par déni ou
        usurpation de service (y compris l'attribution de requêtes à un
        serveur virtuel autre que le serveur virtuel voulu).</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#example">Un exemple simple</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#denial">Déni de service</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#main">L'adresse du "serveur principal"</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#tips">Conseils pour éviter ce genre de problème</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="example" id="example">Un exemple simple</a></h2>
        
    
        <pre class="prettyprint lang-config"># Ceci est un exemple de mauvaise configuration ; ne l'utilisez pas comme base
    # de configuration
    &lt;VirtualHost www.example.dom&gt;
      ServerAdmin webgirl@example.dom
      DocumentRoot "/www/example"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Pour fonctionner correctement, le serveur a absolument besoin de deux
        informations à propos de chaque serveur virtuel : le nom du serveur
        défini par la directive <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>, et au moins une adresse IP à
        laquelle le serveur va se rattacher et répondre. L'exemple ci-dessus
        ne comporte pas d'adresse IP, si bien que httpd devra utiliser le
        DNS pour trouver l'adresse IP de <code>www.example.dom</code>. Si pour
        une raison quelconque, le DNS n'est pas disponible au moment où
        votre serveur interprète son fichier de configuration, ce serveur
        virtuel <strong>ne sera pas pris en compte dans la
        configuration</strong>. Il sera incapable de
        répondre à toute requête pour ce serveur virtuel.</p>
    
        <p>Supposons que l'adresse de <code>www.example.dom</code> soit
        192.0.2.1, et examinons cet extrait de configuration :</p>
    
        <pre class="prettyprint lang-config"># Ceci est un exemple de mauvaise configuration ; ne l'utilisez pas comme base
    # de configuration
    &lt;VirtualHost 192.0.2.1&gt;
      ServerAdmin webgirl@example.dom
      DocumentRoot "/www/example"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Cette fois, httpd doit effectuer une recherche DNS inverse pour
        trouver le nom <code>ServerName</code> de ce serveur virtuel. Si
        cette recherche inverse échoue, le serveur virtuel sera
        partiellement désactivé. Si le serveur
        virtuel est à base de nom, il sera en fait totalement désactivé,
        mais s'il est à base d'adresse IP, il fonctionnera probablement.
        Cependant, httpd échouera s'il doit générer une URL complète pour
        le serveur qui inclut ce nom de serveur (comme dans le cas d'une
        redirection).</p>
    
        <p>Voici un extrait de configuration qui permet d'éviter ces deux
        types de problèmes :</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 192.0.2.1&gt;
      ServerName www.example.dom
      ServerAdmin webgirl@example.dom
      DocumentRoot "/www/example"
    &lt;/VirtualHost&gt;</pre>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="denial" id="denial">Déni de service</a></h2>
        
    
        <p>Considérons cet extrait de configuration :</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost www.example1.dom&gt;
      ServerAdmin webgirl@example1.dom
      DocumentRoot "/www/example1"
    &lt;/VirtualHost&gt;
    &lt;VirtualHost www.example2.dom&gt;
      ServerAdmin webguy@example2.dom
      DocumentRoot "/www/example2"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Supposons que vous ayez assigné 192.0.2.1 à
        <code>www.example1.dom</code> et 192.0.2.2 à <code>www.example2.dom</code>. En
        outre, supposons que <code>example1.dom</code> gère son propre DNS. Avec
        cette configuration, <code>example1.dom</code> sera en mesure de
        détourner tout trafic destiné à <code>example2.dom</code>. Pour y
        parvenir, tout ce qu'ils ont à faire consiste à
        assigner 192.0.2.2 à
        <code>www.example1.dom</code>. Comme ils gèrent leur propre DNS, vous ne
        pouvez pas les empêcher de faire pointer l'enregistrement
        <code>www.example1.dom</code> vers l'adresse qu'ils veulent.</p>
    
        <p>Les requêtes à destination de 192.0.2.2 (y compris toutes celles
        où l'utilisateur à tapé une URL de la forme
        <code>http://www.example2.dom/quelquepart</code>), seront toutes servies
        par le serveur virtuel <code>example1.dom</code>. Une meilleur
        compréhension de la raison pour laquelle ceci peut se produire
        nécessite une discussion plus approfondie à propos de la manière
        dont httpd associe les requêtes entrantes aux différents serveurs
        virtuels qui vont les servir. Un document de base décrivant ceci <a href="vhosts/details.html">est disponible</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">L'adresse du "serveur principal"</a></h2>
        
    
        <p><a href="vhosts/name-based.html">Le support des
        serveurs virtuels à base de nom</a> oblige httpd à
        connaître la/les adresse(s) IP de l'hôte sur
        lequel <code class="program"><a href="./programs/httpd.html">httpd</a></code> s'exécute. Pour obtenir cette
        adresse, soit il utilise la directive <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> globale (si elle est présente),
        soit il fait appel à la fonction C <code>gethostname</code> (qui
        doit renvoyer le même nom que la commande shell "hostname"). Il
        effectue ensuite une recherche DNS sur cette adresse. Pour le
        moment, il n'existe aucun moyen d'éviter cette recherche DNS.</p>
    
        <p>Si vous craignez que cette recherche DNS échoue parce que votre
        serveur DNS est arrêté, vous pouvez insérer le nom d'hôte dans le
        fichier <code>/etc/hosts</code> (où il est probablement déjà
        enregistré afin que la machine démarre correctement). Assurez-vous
        ensuite que la machine est configurée pour utiliser
        <code>/etc/hosts</code> dans le cas où la recherche DNS échoue.
        Suivant le système d'exploitation que vous utilisez, vous y
        parviendrez en éditant <code>/etc/resolv.conf</code>, ou
        <code>/etc/nsswitch.conf</code>.</p>
    
        <p>Si votre serveur n'a aucune autre raison d'effectuer des
        recherches DNS, vous pouvez définir la variable d'environnement
        <code>HOSTRESORDER</code> à "local", et vous serez alors en mesure
        d'exécuter httpd. Tout dépend du système d'exploitation et des
        bibliothèques de résolution de noms que vous utilisez. Elle affecte
        aussi les programmes CGI, à moins que vous n'utilisiez
        <code class="module"><a href="./mod/mod_env.html">mod_env</a></code> pour contrôler l'environnement. Il est
        conseillé de consulter les pages de manuel ou les FAQs de votre
        système d'exploitation.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">Conseils pour éviter ce genre de problème</a></h2>
        
    
        <ul>
          <li>
            utilisez des adresses IP au sein des <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code>
          </li>
    
          <li>
            utilisez des adresses IP avec la directive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
          </li>
    
          <li>
            vérifiez que tous les serveurs virtuels possèdent un nom
    	<code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>	explicite
          </li>
    
          <li>créez un serveur virtuel <code>&lt;VirtualHost
          _default_:*&gt;</code> qui n'a aucune page à servir</li>
        </ul>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/dns-caveats.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dns-caveats.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html.fr.utf8�������������������������������������������������������0000664�0001751�0001751�00000031143�14740503670�020635� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Utilisation des gestionnaires d'Apache (handlers) - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Utilisation des gestionnaires d'Apache (handlers)</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>Ce document décrit l'utilisation des gestionnaires d'Apache (handlers).</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#definition">Qu'est-ce qu'un gestionnaire ?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Exemples</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programmer">Note du développeur</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definition" id="definition">Qu'est-ce qu'un gestionnaire ?</a></h2>
        
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></li><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removehandler">RemoveHandler</a></code></li><li><code class="directive"><a href="./mod/core.html#sethandler">SetHandler</a></code></li></ul></td></tr></table>
    
    
        <p>Un "gestionnaire" est une représentation interne à Apache de l'action
        qui doit être entreprise quand un fichier est appelé. En général, les
        fichiers ont des gestionnaires implicites, basés sur le type du fichier.
        Normalement, tous les fichiers sont traités simplement par le serveur,
        mais certains types de fichiers sont "gérés" séparément.</p>
    
        <p>Les gestionnaires peuvent aussi être configurés explicitement,
        soit en fonction des extensions des noms de fichier, soit en fonction
        du chemin du fichier,
        sans faire référence au type de fichier. Ceci a le double avantage d'être
        une solution plus élégante, et aussi d'autoriser à associer à la fois
        un type <strong>et</strong> un gestionnaire avec un fichier. (Voir aussi <a href="mod/mod_mime.html#multipleext">Fichiers avec extensions
        multiples</a>.)</p>
    
        <p>Les gestionnaires peuvent être soit partie intégrante
        du serveur ou inclus dans un module, soit ajoutés à l'aide de la directive
        <code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code>. Les gestionnaires
        intégrés dans la distribution standard se présentent comme suit :</p>
    
        <ul>
          <li><strong>default-handler</strong>: envoie le fichier en utilisant
          le <code>default_handler()</code>, qui est le gestionnaire utilisé par
          défaut pour traiter les contenus statiques. (core)</li>
    
          <li><strong>send-as-is</strong>: envoie les fichiers avec en-têtes HTTP
          tels quels. (<code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code>)</li>
    
          <li><strong>cgi-script</strong>: traite le fichier comme un
          script CGI. (<code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>)</li>
    
          <li><strong>imap-file</strong>: Traite le fichier comme un ensemble
          de règles de descriptions d'images (imagemap).
          (<code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code>)</li>
    
          <li><strong>server-info</strong>: Extrait des informations sur la
          configuration du serveur. (<code class="module"><a href="./mod/mod_info.html">mod_info</a></code>)</li>
    
          <li><strong>server-status</strong>: Rédige un rapport sur le statut
          du serveur. (<code class="module"><a href="./mod/mod_status.html">mod_status</a></code>)</li>
    
          <li><strong>type-map</strong>: Traite le fichier comme une description
          de type pour la négociation du contenu.
          (<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>)</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples</a></h2>
        
    
        <h3><a name="example1" id="example1">Modification d'un contenu statique à l'aide d'un script CGI</a></h3>
          
    
          <p>Les directives suivantes vont faire en sorte que les requêtes pour
          des fichiers possédant une extension <code>html</code> déclenchent
          l'exécution du script CGI <code>footer.pl</code>.</p>
    
          <pre class="prettyprint lang-config">Action add-footer /cgi-bin/footer.pl
    AddHandler add-footer .html</pre>
    
    
          <p>À ce moment-là, le script CGI se charge d'envoyer le document
          initialement demandé (référencé par la variable d'environnement
          <code>PATH_TRANSLATED</code>) et d'effectuer tous ajout ou modification
          voulus.</p>
    
        
        <h3><a name="example2" id="example2">Fichiers avec en-têtes HTTP</a></h3>
          
    
          <p>Les directives suivantes vont activer le gestionnaire
          <code>send-as-is</code>, qui est utilisé pour les fichiers qui possèdent
          leurs propres en-têtes HTTP. Tous les fichiers situés dans le répertoire
          <code>/web/htdocs/asis/</code> seront traités par le gestionnaire
          <code>send-as-is</code>, sans tenir compte de l'extension
          de leur nom de fichier.</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/web/htdocs/asis"&gt;
        SetHandler send-as-is
    &lt;/Directory&gt;</pre>
    
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programmer" id="programmer">Note du développeur</a></h2>
        
    
        <p>Pour implémenter la fonctionnalité des gestionnaires, l'
        <a href="developer/API.html">API Apache</a> a fait l'objet d'un ajout
        que vous pourriez être amené à utiliser.
    
        Plus précisément, un nouvel enregistrement a été ajouté à la structure
        <code>request_rec</code> :</p>
    
        <pre class="prettyprint lang-c">char *handler</pre>
    
    
        <p>Si vous voulez que votre module déclenche l'utilisation d'un
        gestionnaire, il vous suffit de définir <code>r-&gt;handler</code> avec
        le nom du gestionnaire à n'importe quel moment avant l'étape
        <code>invoke_handler</code>
        de la requête. Les gestionnaires sont implémentés comme auparavant,
        quoique l'on utilise le nom du gestionnaire à la place d'un type
        de contenu. Bien que ce ne soit pas obligatoire, la convention de nommage
        des gestionnaires stipule l'utilisation d'un mot composé séparé par des
        tirets, sans slashes, afin de ne pas interférer avec l'espace de nommage
        des types de média.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/handler.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/handler.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/logs.html.fr.utf8����������������������������������������������������������0000664�0001751�0001751�00000130357�14740503670�020173� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Fichiers journaux - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Fichiers journaux</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Pour véritablement gérer un serveur web,
        il est nécessaire de disposer d'un
        retour d'informations à propos de l'activité et des performances du
        serveur, ainsi que de tout problème qui pourrait survenir. Le serveur HTTP
        Apache propose des fonctionnalités de journalisation souples et très
        complètes. Ce document décrit comment configurer ces fonctionnalités de
        journalisation et interpréter le contenu des journaux.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Vue d'ensemble</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#security">Avertissement à propos de la sécurité</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errorlog">Journal des erreurs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#permodule">Journalisation par module</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#accesslog">Journal des accès</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rotation">Rotation des journaux</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#piped">Journaux redirigés</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Hôtes virtuels</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Autres fichiers journaux</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Vue d'ensemble</a></h2>
        
    
      <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code></li><li><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td /></tr></table>
    
      <p>
      Le serveur HTTP Apache fournit toute une variété de mécanismes
      différents pour la journalisation de tout ce qui peut se passer au
      sein de votre serveur, depuis la requête initiale, en passant par le
      processus de mise en correspondance des URLs, et jusqu'à la fermeture
      de la connexion, y compris toute erreur pouvant survenir au cours du
      traitement. De plus, certains modules tiers fournissent des
      fonctionnalités de journalisation ou insèrent des entrées dans les
      fichiers journaux existants, et les applications comme les programmes
      CGI, les scripts PHP ou autres gestionnaires peuvent envoyer des
      messages vers le journal des erreurs du serveur.
      </p>
    
      <p>
      Ce document décrit le fonctionnement des modules de journalisation
      fournis en standard avec le serveur httpd.
      </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Avertissement à propos de la sécurité</a></h2>
        
    
        <p>Tout utilisateur qui a les droits en écriture sur le répertoire dans
        lequel Apache httpd écrit ses journaux pourra quasi
        certainement avoir accès à l'uid sous lequel le serveur est démarré, en
        l'occurrence habituellement root. N'accordez <em>PAS</em> aux utilisateurs
        l'accès en écriture au répertoire dans lequel les journaux sont stockés
        sans savoir exactement quelles en seraient les conséquences ; voir le
        document <a href="misc/security_tips.html">conseils sur la sécurité</a>
        pour plus de détails.</p>
    
        <p>En outre, les journaux peuvent contenir des informations fournies
        directement par un client, sans caractères d'échappement. Des clients mal
        intentionnés peuvent donc insérer des caractères de contrôle dans les
        journaux, et il convient par conséquent d'être très prudent lors de la
        manipulation des journaux bruts.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errorlog" id="errorlog">Journal des erreurs</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code></li></ul></td></tr></table>
    
        <p>Le journal des erreurs du serveur, dont le nom et la localisation sont
        définis par la directive <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code>,
        est le journal le plus important. C'est dans celui-ci
        que le démon Apache httpd va envoyer les informations de diagnostic et
        enregistrer toutes les erreurs qui surviennent lors du traitement des
        requêtes. Lorsqu'un problème survient au démarrage du serveur ou pendant
        son fonctionnement, la première chose à faire est de regarder dans ce
        journal, car il vous renseignera souvent sur le problème rencontré et
        la manière d'y remédier.</p>
    
        <p>Le journal des erreurs est habituellement enregistré dans un fichier
        (en général <code>error_log</code> sur les systèmes de type Unix et
        <code>error.log</code> sur Windows et OS/2). Sur les systèmes de type Unix,
        le serveur peut aussi enregistrer ses erreurs dans
        <code>syslog</code> ou les
        <a href="#piped">rediriger vers un programme</a> par l'intermédiaire d'un
        tube de communication (pipe).</p>
    
        <p>Le format par défaut du journal des erreurs est descriptif et de forme
        relativement libre. Certaines informations apparaissent cependant dans la
        plupart des entrées du journal. Voici un message typique
        à titre d'exemple : </p>
    
        <div class="example"><p><code>
          [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1]
          client denied by server configuration:
          /export/home/live/ap/htdocs/test
        </code></p></div>
    
        <p>Le premier champ de l'entrée du journal est la date et l'heure du
        message. Le second champ indique la sévérité de l'erreur rapportée. La
        directive <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> permet de
        restreindre le type des erreurs qui doivent être enregistrées
        dans le journal des erreurs en définissant leur niveau de sévérité. Le
        troisième champ contient l'adresse IP du client qui a généré l'erreur.
        Vient ensuite le message proprement dit, qui indique dans ce cas que le
        serveur a été configuré pour interdire l'accès au client. Le serveur
        indique le chemin système du document requis (et non
        son chemin web).</p>
    
        <p>Une grande variété de messages différents peuvent apparaître dans le
        journal des erreurs. La plupart d'entre eux sont similaires à l'exemple
        ci-dessus. Le journal des erreurs peut aussi contenir des informations de
        débogage en provenance de scripts CGI. Toute information qu'un script CGI
        écrit sur la sortie d'erreurs standard <code>stderr</code> sera recopiée
        telle quelle dans le journal des erreurs.</p>
    
        <p>La directive <code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code>
        vous permet de personnaliser le format du journal des erreurs, et de
        définir les informations à journaliser. Si
        <code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code> est présent, vous pouvez utiliser le
        drapeau <code>%L</code> à la fois dans le journal des erreurs et
        dans le
        journal des accès, ce qui aura pour effet de générer un identifiant
        d'entrée qui vous permettra de corréler les entrées du journal des
        erreurs avec celles du journal des accès.</p>
    
        <p>Pendant la phase de test, il est souvent utile de visualiser en continu
        le journal des erreurs afin de détecter tout problème éventuel. Sur les
        systèmes de type Unix, ceci s'effectue à l'aide de la commande :</p>
    
        <div class="example"><p><code>
          tail -f error_log
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="permodule" id="permodule">Journalisation par module</a></h2>
        
    
        <p>La directive <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> permet
        de spécifier un niveau de sévérité de journalisation pour chaque
        module. Vous pouvez ainsi résoudre un problème propre à un module particulier
        en augmentant son volume de journalisation sans augmenter ce volume
        pour les autres modules. Ceci est particulièrement utile lorsque
        vous voulez obtenir des détails sur le fonctionnement de modules
        comme <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> ou <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
        <p>Pour ce faire, vous devez spécifier le nom du module dans votre
        directive <code class="directive">LogLevel</code> :</p>
    
        <pre class="prettyprint lang-config">LogLevel info rewrite:trace5</pre>
    
    
        <p>Dans cet exemple, le niveau de journalisation général est défini
        à info, et à <code>trace5</code> pour <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
        <div class="note">Cette directive remplace les directives de journalisation par
        module des versions précédentes du serveur, comme
        <code>RewriteLog</code>.</div>
     </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="accesslog" id="accesslog">Journal des accès</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li></ul></td></tr></table>
    
        <p>Le journal des accès au serveur
        enregistre toutes les requêtes que traite
        ce dernier. La localisation et le contenu du journal des accès sont définis
        par la directive <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>.
        La directive <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>
        permet de simplifier la sélection du contenu du journal. Cette section
        décrit comment configurer le serveur pour l'enregistrement des informations
        dans le journal des accès.</p>
    
        <p>Le stockage d'informations dans le journal des accès
        n'est que le point de départ de la gestion de la journalisation. L'étape
        suivante consiste à analyser ces informations de façon à pouvoir en
        extraire des statistiques utiles. L'analyse de journaux en général est en
        dehors du sujet de ce document et ne fait pas vraiment partie intégrante
        du travail du serveur web lui-même.</p>
    
        <p>Différentes versions du démon Apache httpd utilisaient d'autres modules
        et directives pour contrôler la journalisation des accès, à l'instar de
        mod_log_referer, mod_log_agent, et de la directive
        <code>TransferLog</code>. La directive
        <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> rassemble
        désormais les fonctionnalités de toutes les anciennes directives.</p>
    
        <p>Le format du journal des accès est hautement configurable. Il est
        défini à l'aide d'une chaîne de format qui ressemble sensiblement à la
        chaîne de format de style langage C de printf(1). Vous trouverez quelques
        exemples dans les sections suivantes. Pour une liste exhaustive de ce que
        peut contenir une chaîne de format, vous pouvez vous référer au chapitre
        <a href="mod/mod_log_config.html#formats">chaînes de format</a> de la
        documentation du module <code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code>.</p>
    
        <h3><a name="common" id="common">Format habituel du journal</a></h3>
          
    
          <p>Voici une configuration typique pour le journal des accès :</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common
    CustomLog logs/access_log common</pre>
    
    
          <p>Ici est définie l'<em>identité</em> <code>common</code> qui est
          ensuite associée à une chaîne de format de journalisation particulière.
          La chaîne de format est constituée de directives débutant par le
          caractère %, chacune d'entre elles indiquant au serveur d'enregistrer
          un élément particulier d'information. Des caractères littéraux peuvent
          aussi être insérés dans la chaîne de format ; il seront copiés tels
          quels dans le flux de sortie destiné à la journalisation.
          Les guillemets (<code>"</code>) doivent être échappées en les faisant
          précéder d'un anti-slash (<code>\</code>) afin qu'elles ne soient pas
          interprétées comme la fin de la chaîne de format. La chaîne de format
          peut aussi contenir les caractères de contrôle spéciaux
          "<code>\n</code>" et "<code>\t</code>" pour insérer respectivement
          un passage à la ligne et une tabulation.</p>
    
          <p>La directive <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
          définit un nouveau fichier journal en l'associant à l'identité
          précédemment définie. Le chemin du nom de fichier associé au journal
          des accès est relatif au chemin défini par la directive
          <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code>, sauf s'il
          débute par un slash.</p>
    
          <p>La configuration ci-dessus va enregistrer les entrées de
          journalisation selon un format connu sous le nom de
          Common Log Format (CLF) pour "Format de journalisation standard".
          Ce format standard peut être produit par de nombreux serveurs web
          différents et lu par de nombreux programmes d'analyse de journaux.
          Les entrées de fichier journal générées selon le format CLF
          ressemblent à ceci :</p>
    
          <div class="example"><p><code>
            127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET
            /apache_pb.gif HTTP/1.0" 200 2326
          </code></p></div>
    
          <p>Chaque partie de cette entrée de journal est décrite
          dans ce qui suit.</p>
    
          <dl>
            <dt><code>127.0.0.1</code> (<code>%h</code>)</dt>
    
            <dd>Il s'agit de l'adresse IP du client (l'hôte distant) qui a envoyé
    	la requête au serveur. Si la directive
    	<code class="directive"><a href="./mod/core.html#hostnamelookups">HostnameLookups</a></code> est positionnée à
    	<code>On</code>, le serveur va essayer de déterminer le nom de l'hôte
    	et de l'enregistrer à la place de l'adresse IP. Cette configuration
    	n'est cependant pas recommandée car elle peut ralentir le serveur de
    	manière significative. Il est par conséquent préférable d'utiliser un
    	processeur d'analyse de journaux a posteriori
    	tel que <code class="program"><a href="./programs/logresolve.html">logresolve</a></code>
    	pour déterminer les noms d'hôte. L'adresse IP indiquée ici n'est pas
    	nécessairement l'adresse IP de la machine devant laquelle se trouve
    	l'utilisateur. Si un serveur mandataire s'intercale entre le serveur
    	et l'utilisateur, l'adresse indiquée sera celle du mandataire et non
    	celle de la machine à l'origine de la requête.</dd>
    
            <dt><code>-</code> (<code>%l</code>)</dt>
    
            <dd>Le "trait d'union" indique que la portion d'information
    	correspondante n'est pas disponible. Dans le cas présent, l'information
    	non disponible est l'identité (RFC 1413) du client telle que déterminée
    	par <code>identd</code> sur la machine cliente. Cette information est
    	très peu fiable et ne devrait jamais être utilisée, sauf dans le cas
    	de réseaux internes étroitement contrôlés. Le démon httpd ne cherchera
    	d'ailleurs à obtenir cette information que si la directive
    	<code class="directive"><a href="./mod/mod_ident.html#identitycheck">IdentityCheck</a></code> est positionnée
    	à <code>On</code>.</dd>
    
            <dt><code>frank</code> (<code>%u</code>)</dt>
    
            <dd>Il s'agit de l'identifiant utilisateur de la personne qui a
    	demandé le document, issu d'une authentification HTTP.
    	Ce même identifiant est en général fourni aux scripts CGI par
    	l'intermédiaire de la valeur de la variable d'environnement
    	<code>REMOTE_USER</code>. Si le statut de la requête (voir plus loin)
    	est 401, cette identifiant n'est pas fiable car l'utilisateur n'est
    	pas encore authentifié. Si le document n'est pas protégé par
    	mot de passe, cette partie d'information sera représentée par
    	"<code>-</code>", comme la partie précédente.</dd>
    
            <dt><code>[10/Oct/2000:13:55:36 -0700]</code>
            (<code>%t</code>)</dt>
    
            <dd>
              L'heure à laquelle la requête a été reçue.
              Le format est le suivant :
    
              <p class="indent">
                <code>[jour/mois/année:heure:minutes:secondes zone]<br />
                 jour = 2*chiffre<br />
                 mois = 3*lettre<br />
                 année = 4*chiffre<br />
                 heure = 2*chiffre<br />
                 minutes = 2*chiffre<br />
                 secondes = 2*chiffre<br />
                 zone = (`+' | `-') 4*chiffre</code>
              </p>Il est possible de modifier le format d'affichage de l'heure
    	  en spécifiant <code>%{format}t</code> dans la chaîne de format du
    	  journal, où <code>format</code> est une chaîne de format
    	  de la forme de celle de la fonction <code>strftime(3)</code>
    	  de la bibliothèque C standard, ou choisie parmi les
    	  formats spéciaux supportés. Pour plus de détails,
    	  reportez-vous aux. <a href="mod/mod_log_config.html#formats">chaînes de format</a>
    	  de <code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code>.
            </dd>
    
            <dt><code>"GET /apache_pb.gif HTTP/1.0"</code>
            (<code>\"%r\"</code>)</dt>
    
            <dd>La ligne de la requête du client est placée entre guillemets.
    	Elle contient de nombreuses informations utiles. Tout d'abord, la
    	méthode utilisée par le client est <code>GET</code>. Ensuite, le
    	client a demandé la ressource <code>/apache_pb.gif</code>, et enfin,
    	le client a utilisé le protocole <code>HTTP/1.0</code>. Il est aussi
    	possible d'enregistrer séparément une ou plusieurs parties de la
    	requête. Par exemple, la chaîne de format "<code>%m %U %q %H</code>"
    	va enregistrer la méthode, le chemin, la chaîne de la requête et le
    	protocole, ce qui donnera le même résultat que
    	"<code>%r</code>".</dd>
    
            <dt><code>200</code> (<code>%&gt;s</code>)</dt>
    
            <dd>C'est le code de statut que le serveur retourne au client. Cette
    	information est très importante car elle indique si la requête a fait
    	l'objet d'une réponse positive (codes commençant par 2), une
    	redirection (codes commençant par 3), une erreur due au client (codes
    	commençant par 4), ou une erreur due au serveur (codes commençant
    	par 5). Vous trouverez la liste complète des codes de statut possibles
    	dans la <a href="http://www.w3.org/Protocols/rfc2616/  rfc2616.txt">specification HTTP</a> (RFC2616 section 10).</dd>
    
            <dt><code>2326</code> (<code>%b</code>)</dt>
    
            <dd>La dernière partie indique la taille de l'objet retourné au client,
    	en-têtes non compris. Si aucun contenu n'a été retourné au client, cette
    	partie contiendra "<code>-</code>". Pour indiquer l'absence de contenu
    	par "<code>0</code>", utilisez <code>%B</code> au lieu de
    	<code>%b</code>.</dd>
          </dl>
        
    
        <h3><a name="combined" id="combined">Combined Log Format (Format de journalisation combiné)</a></h3>
          
    
          <p>Une autre chaîne de format couramment utilisée est le
          "Combined Log Format" (Format de journalisation combiné). Il s'utilise
          comme suit :</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
    CustomLog log/access_log combined</pre>
    
    
          <p>Ce format est identique au Common Log Format, avec deux champs
          supplémentaires. Chacun de ces deux champs utilise la directive
          commençant par le caractère "%" <code>%{<em>header</em>}i</code>,
          où <em>header</em> peut être n'importe quel en-tête de requête HTTP.
          Avec ce format, le journal des accès se présentera comme suit :</p>
    
          <div class="example"><p><code>
            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)"
          </code></p></div>
    
          <p>Les champs supplémentaires sont :</p>
    
          <dl>
            <dt><code>"http://www.example.com/start.html"</code>
            (<code>\"%{Referer}i\"</code>)</dt>
    
            <dd>L'en-tête "Referer" (sic) de la requête HTTP. Il indique le site
    	depuis lequel le client prétend avoir lancé sa requête. (Ce doit être
    	la page qui contient un lien vers <code>/apache_pb.gif</code> ou
    	inclut ce dernier fichier).</dd>
    
            <dt><code>"Mozilla/4.08 [en] (Win98; I ;Nav)"</code>
            (<code>\"%{User-agent}i\"</code>)</dt>
    
            <dd>L'en-tête User-Agent de la requête HTTP. C'est une information
    	d'identification que le navigateur du client envoie à propos
    	de lui-même.</dd>
          </dl>
        
    
        <h3><a name="multiple" id="multiple">Journaux d'accès multiples</a></h3>
          
    
          <p>Plusieurs journaux d'accès peuvent être créés en spécifiant tout
          simplement plusieurs directives
          <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> dans le
          fichier de configuration. Par exemple, les directives suivantes vont
          créer trois journaux d'accès. Le premier contiendra les informations
          de base CLF, le second les informations du Referer, et le troisième
          les informations sur le navigateur. Les deux dernières directives
          <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> montrent
          comment simuler les effets des directives <code>ReferLog</code> et
          <code>AgentLog</code>.</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common
    CustomLog logs/access_log common
    CustomLog logs/referer_log "%{Referer}i -&gt; %U"
    CustomLog logs/agent_log "%{User-agent}i"</pre>
    
    
          <p>Cet exemple montre aussi qu'il n'est pas obligatoire d'associer
          une chaîne de format à un alias au moyen de la directive
          <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>. Elle peut
          être définie directement dans la ligne de la directive
          <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>.</p>
        
    
        <h3><a name="conditional" id="conditional">Journalisation conditionnelle</a></h3>
          
    
          <p>Il est parfois souhaitable d'exclure certaines entrées des journaux
          d'accès en fonction des caractéristiques de la requête du client. On
          peut aisément accomplir ceci à l'aide des
          <a href="env.html">variables d'environnement</a>. Tout d'abord, une
          variable d'environnement doit être définie pour indiquer que la
          requête remplit certaines conditions. Pour ceci, on utilise en général
          la directive <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>,
          puis la clause <code>env=</code> de la directive
          <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> pour inclure
          ou exclure les requêtes pour lesquelles
          la variable d'environnement est définie.
          Quelques exemples :</p>
    
          <pre class="prettyprint lang-config"># Marque les requêtes en provenance de l'interface loop-back
    SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
    # Marque les requêtes pour le fichier robots.txt
    SetEnvIf Request_URI "^/robots\.txt$" dontlog
    # Journalise toutes les autres requêtes
    CustomLog logs/access_log common env=!dontlog</pre>
    
    
          <p>Autre exemple, imaginons l'enregistrement des requêtes en provenance
          d'utilisateurs de langue anglaise dans un journal, et celles des autres
          utilisateurs dans un autre journal.</p>
    
          <pre class="prettyprint lang-config">        SetEnvIf Accept-Language "en" english
            CustomLog logs/english_log common env=english
            CustomLog logs/non_english_log common env=!english</pre>
    
    
    	<p>Dans le contexte d'une mise en cache, il peut être
    	intéressant de connaître l'efficacité du cache. Pour y parvenir,
    	on pourrait utiliser cette méthode simple :</p>
    
          <pre class="prettyprint lang-config">SetEnv CACHE_MISS 1
    LogFormat "%h %l %u %t "%r " %&gt;s %b %{CACHE_MISS}e" common-cache
    CustomLog logs/access_log common-cache</pre>
    
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> va s'exécuter avant
          <code class="module"><a href="./mod/mod_env.html">mod_env</a></code>, et si son action est couronnée de
          succès, il délivrera le contenu sans faire appel à ce dernier. Si
          l'URL se trouve dans le cache, la valeur journalisée sera alors
          <code>-</code>, tandis que dans le cas contraire elle sera
          <code>1</code>.</p>
    
          <p>En plus de la syntaxe <code>env=</code>, la directive <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> supporte les
          valeurs de journalisation conditionnelles basées sur le code de la
          réponse HTTP :</p>
    
          <pre class="prettyprint lang-config">LogFormat "%400,501{User-agent}i" browserlog
    LogFormat "%!200,304,302{Referer}i" refererlog</pre>
    
    
          <p>Dans le premier exemple, le <code>User-agent</code> sera
          enregistré si le code d'état HTTP est 400 ou 501. Dans le cas
          contraire, c'est un caractère "-" qui sera enregistré à la place.
          Dans le second exemple, le <code>Referer</code> sera enregistré si
          le code d'état HTTP n'est <strong>pas</strong> 200, 304, ou 302
          (remarquez le caractère "!" avant les codes d'état).</p>
    
          <p>Bien que nous venions de montrer que la journalisation conditionnelle
          est souple et très puissante, cette méthode de contrôle du contenu des
          journaux n'est pas la seule. Les fichiers journaux sont plus utiles
          quand ils contiennent un enregistrement complet de l'activité du serveur,
          et il est souvent plus aisé de simplement traiter à posteriori les fichiers
          journaux pour supprimer les requêtes que vous ne voulez pas y voir
          apparaître.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rotation" id="rotation">Rotation des journaux</a></h2>
        
    
        <p>Même dans le cas d'un serveur modérément sollicité, la quantité
        d'informations stockées dans les fichiers journaux est très importante.
        Le fichier journal des accès grossit en général d'1 Mo ou plus toutes
        les 10000 requêtes. Il est par conséquent nécessaire d'effectuer
        périodiquement la rotation des journaux en déplaçant ou supprimant les
        fichiers correspondants. On ne peut pas le faire pendant que le serveur
        est en cours d'exécution, car Apache httpd va continuer à écrire dans l'ancien
        fichier journal aussi longtemps qu'il le maintiendra ouvert.
        C'est pourquoi le serveur doit être
        <a href="stopping.html">redémarré</a> après le déplacement ou la
        suppression des fichiers journaux de façon à ce qu'il en ouvre
        de nouveaux.</p>
    
        <p>Avec un redémarrage <em>graceful</em>, on peut faire en sorte que le
        serveur ouvre de nouveaux fichiers journaux sans perdre de connexions
        existantes ou en cours avec les clients. Cependant, pour que ceci soit
        possible, le serveur doit continuer à écrire dans les anciens fichiers
        journaux pendant qu'il termine le traitement des requêtes en cours.
        Il est donc nécessaire d'attendre un certain temps après le rédémarrage
        avant d'effectuer tout traitement sur les fichiers journaux. Voici un
        scénario typique dans lequel on effectue une simple rotation des
        journaux en compressant les anciens fichiers correspondants afin
        de gagner de l'espace disque :</p>
    
        <div class="example"><p><code>
          mv access_log access_log.old<br />
          mv error_log error_log.old<br />
          apachectl graceful<br />
          sleep 600<br />
          gzip access_log.old error_log.old
        </code></p></div>
    
        <p>La section suivante présente une autre méthode de rotation des journaux
        qui consiste à utiliser les
        <a href="#piped">journaux redirigés</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="piped" id="piped">Journaux redirigés</a></h2>
        
    
        <p>Nous avons vu que le démon httpd écrivait les informations de
        journalisation des erreurs et des accès dans un fichier journal ;
        il peut aussi
        rediriger ces informations vers un autre processus par l'intermédiaire d'un
        tube de communication (pipe). Cette fonctionnalité améliore
        considérablement la souplesse de la journalisation, sans ajouter de code
        au serveur principal. Pour rediriger les informations de journalisation
        vers un tube de communication, remplacez simplement le nom de fichier
        journal par
        le caractère pipe "<code>|</code>", suivi du nom de l'exécutable qui va
        recueillir les entrées de journal sur son entrée
        standard. Le serveur va
        lancer le processus de redirection des journaux au moment du démarrage du
        serveur, et le relancera s'il cesse de fonctionner
        pendant l'exécution du serveur.
        (Nous dénommons cette technique "journalisation
        redirigée fiable" grâce à cette dernière fonctionnalité.)</p>
    
        <p>Les processus de journalisation redirigée sont lancés par le processus
        httpd parent, et héritent de l'UID de ce dernier. Cela signifie que les
        programmes de journalisation dirigée s'exécutent généralement en tant que
        root. Il est donc très important que ces programmes soient simples et
        sécurisés.</p>
    
        <p>Un des grands avantages de la journalisation redirigée est la possibilité
        d'effectuer la rotation des journaux sans avoir à redémarrer le serveur. Pour
        accomplir cette tâche, le serveur HTTP Apache fournit un programme simple
        appelé <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code>. Par exemple, pour une rotation des
        journaux toutes les 24 heures, ajoutez ces lignes :</p>
    
        <pre class="prettyprint lang-config">CustomLog "|/usr/local/apache/bin/rotatelogs /var/log/access_log 86400" common</pre>
    
    
        <p>Notez que l'ensemble de la commande qui sera appelée par le tube de
        communication a été placée entre guillemets. Bien que cet exemple
        concerne le journal des accès, la même technique peut être utilisée
        pour le journal des erreurs.</p>
    
        <p>Comme la journalisation conditionnelle, la journalisation redirigée est
        un outil très puissant, mais si elle existe, il est préférable d'utiliser
        une solution plus simple comme le traitement à posteriori hors ligne.</p>
    
    
      <p>Par défaut, le processus de redirection du journal est lancé sans
      invoquer un shell. Pour invoquer un shell, utilisez "<code>|$</code>"
      au lieu de "<code>|</code>" (en général avec <code>/bin/sh -c</code>)
      :</p>
    
        <pre class="prettyprint lang-config"># Invocation de "rotatelogs" en utilisant un shell
    CustomLog "|$/usr/local/apache/bin/rotatelogs   /var/log/access_log 86400" common</pre>
    
    
    
        <p>Il s'agissait du comportement par défaut sous Apache 2.2. Selon
        les spécificités du shell, ceci peut générer un processus shell
        supplémentaire pour toute la durée du programme de redirection du
        journal, et induire des problèmes de gestion de signaux au cours du
        redémarrage. La notation "<code>||</code>" est aussi supportée pour
        des raisons de compatibilité avec Apache 2.2 et est équivalente à
        "<code>|</code>".</p>
    
        <div class="note"><h3>Note à propos de la plateforme Windows</h3>
        <p>Notez que sous Windows, la mémoire allouée au bureau (desktop
        heap) peut devenir insuffisante si vous utilisez de nombreux
        processus vers lesquels sont redirigés des journaux via un pipe, et
        ceci particulièrement si httpd s'exécute en tant que service. La
        quantité de mémoire du bureau allouée à chaque service est spécifiée
        dans le troisième argument du paramètre <code>SharedSection</code>
        de la clé de registre
        HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\SubSystems\Windows.
        <strong>Modifiez cette valeur avec prudence</strong> ; les
        précautions d'usage s'imposent lorsqu'on modifie la base de registre,
        mais vous pouvez aussi saturer la mémoire du bureau si vous
        spécifiez une valeur trop élevée.</p>
        </div>
        </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Hôtes virtuels</a></h2>
        
    
        <p>Lorsqu'un serveur possède plusieurs <a href="vhosts/">hôtes virtuels</a>, il existe de nombreuses solutions pour gérer
        les fichiers journaux. Par exemple, on peut utiliser les journaux comme
        s'il s'agissait d'un serveur avec un seul hôte. Il suffit pour cela de
        placer les directives de journalisation en dehors des sections
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> au niveau
        du serveur principal, ce qui a pour effet de journaliser toutes les
        requêtes dans le même journal des accès et des erreurs. Cette technique
        est cependant inappropriée pour recueillir des statistiques sur chaque
        hôte virtuel individuellement.</p>
    
        <p>Si des directives <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> ou
        <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> sont placées dans une section
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>, toutes les
        requêtes ou erreurs pour cet hôte virtuel ne seront enregistrées que dans
        le fichier spécifié. Tout hôte virtuel qui ne possède pas de directives de
        journalisation verra ses requêtes enregistrées dans le journal du serveur
        principal. Cette technique est appropriée pour un petit nombre d'hôtes
        virtuels, mais si ce nombre est important, elle peut devenir compliquée à
        gérer. En outre, des problèmes de <a href="vhosts/fd-limits.html">nombre de descripteurs
        de fichiers insuffisant</a> peuvent rapidement apparaître.</p>
    
        <p>Il existe un très bon compromis pour le journal des accès. En intégrant
        les informations à propos de l'hôte virtuel à la chaîne de format du
        journal, il est possible de journaliser tous les hôtes dans le même
        journal, puis de séparer ultérieurement le journal en plusieurs journaux
        individuels. Considérons par exemple les directives suivantes :</p>
    
        <pre class="prettyprint lang-config">LogFormat "%v %l %u %t \"%r\" %&gt;s %b" comonvhost
    CustomLog logs/access_log comonvhost</pre>
    
    
        <p>Le champ <code>%v</code> sert à enregistrer le nom de l'hôte virtuel qui
        traite la requête. Un programme tel que <a href="programs/split-logfile.html">split-logfile</a> peut ensuite être utilisé
        pour générer "à froid" autant de journaux que d'hôtes virtuels.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Autres fichiers journaux</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#bufferedlogs">BufferedLogs</a></code></li><li><code class="directive"><a href="./mod/mod_log_forensic.html#forensiclog">ForensicLog</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlogbuffer">ScriptLogBuffer</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptloglength">ScriptLogLength</a></code></li></ul></td></tr></table>
    
        <h3>Enregistrement du nombre réel d'octets envoyés et reçus</h3>
          
    
          <p>Le module <code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code> fournit deux champs
          <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> supplémentaires
          (%I et %O) qui permettent d'enregistrer le nombre réel d'octets reçus et
          envoyés sur le réseau.</p>
        
    
        <h3>Journalisation de style investigation judiciaire (forensic logging)</h3>
          
    
          <p>Le module <code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code> permet la journalisation
          à des fins d'investigation judiciaire des requêtes des clients. La
          journalisation est effectuée avant et après le traitement de la requête,
          qui fait donc l'objet de deux entrées dans le journal. Le générateur de
          journaux d'investigation est très strict et ne permet aucune
          personnalisation. C'est un inestimable outil de débogage et de sécurité.</p>
        
    
        <h3><a name="pidfile" id="pidfile">Fichier PID</a></h3>
          
    
          <p>Au démarrage, le démon httpd Apache enregistre l'identifiant du
          processus httpd parent dans le fichier <code>logs/httpd.pid</code>.
          Le nom de ce fichier peut être modifié à l'aide de la directive
          <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>. Cet identifiant
          permet à l'administrateur de redémarrer et arrêter le démon en
          envoyant des signaux au processus parent ; sous Windows, vous devez
          utiliser l'option de ligne de commande -k. Pour plus de détails,
          consulter la page <a href="stopping.html">Arrêt et redémarrage</a>.</p>
        
    
        <h3><a name="scriptlog" id="scriptlog">Journal des scripts</a></h3>
          
    
          <p>Afin de faciliter le débogage, la directive
          <code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code> vous permet
          d'enregistrer les entrées et sorties des scripts CGI. Elle ne doit être
          utilisée que pendant la phase de test, et en aucun cas sur un
          serveur en production. Vous trouverez plus d'informations dans la
          documentation du module <a href="mod/mod_cgi.html">mod_cgi</a>.</p>
        
        
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/logs.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/logs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/expr.html.fr.utf8����������������������������������������������������������0000664�0001751�0001751�00000115070�14740503670�020200� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Les expressions dans le serveur HTTP Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Les expressions dans le serveur HTTP Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/expr.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/expr.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Historiquement, il existe de nombreuses variantes dans la syntaxe
        des expressions permettant d'exprimer une condition dans les
        différents modules du serveur HTTP Apache. À ce titre, des travaux sont
        en cours pour n'utiliser qu'une seule variante nommée
        <em>ap_expr</em>, pour toutes les directives de configuration. Ce
        document décrit l'interpréteur d'expressions <em>ap_expr</em>.
        </p>
        <p>Le type d'expression <em>ap_expr</em> est appelé à remplacer la
        plupart des autres types d'expressions dans HTTPD. Par exemple, la
        directive obsolète <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code> peut être remplacée par la
        directive <a href="mod/mod_authz_core.html#reqexpr">Require
        expr</a>.
        </p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#grammar">Syntaxe en Forme de Backus-Naur</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vars">Variables</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#binop">Opérateurs binaires</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#unnop">Opérateurs unaires</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#functions">Fonctions</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Exemples d'expressions</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Autres</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#sslrequire">Comparaison avec SSLRequire</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compatibility">Historique de version</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="directive"><a href="./mod/core.html#if">If</a></code></li><li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#elseif">&lt;ElseIf&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="./mod/mod_auth_basic.html#authbasicfake">AuthBasicFake</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginrequiredlocation">AuthFormLoginRequiredLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginsuccesslocation">AuthFormLoginSuccessLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformlogoutlocation">AuthFormLogoutLocation</a></code></li><li><code class="directive"><a href="./mod/mod_authn_core.html#authname">AuthName</a></code></li><li><code class="directive"><a href="./mod/mod_authn_core.html#authtype">AuthType</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifexpr">SetEnvIfExpr</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#requestheader">RequestHeader</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code></li><li><a href="mod/mod_authz_core.html#reqexpr">Require expr</a></li><li><a href="mod/mod_authnz_ldap.html#requser">Require ldap-user</a></li><li><a href="mod/mod_authnz_ldap.html#reqgroup">Require ldap-group</a></li><li><a href="mod/mod_authnz_ldap.html#reqdn">Require ldap-dn</a></li><li><a href="mod/mod_authnz_ldap.html#reqattribute">Require ldap-attribute</a></li><li><a href="mod/mod_authnz_ldap.html#reqfilter">Require ldap-filter</a></li><li><a href="mod/mod_authnz_ldap.html#reqsearch">Require ldap-search</a></li><li><a href="mod/mod_authz_dbd.html#reqgroup">Require dbd-group</a></li><li><a href="mod/mod_authz_dbm.html#reqgroup">Require dbm-group</a></li><li><a href="mod/mod_authz_groupfile.html#reqgroup">Require group</a></li><li><a href="mod/mod_authz_host.html#reqhost">Require host</a></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code></li><li><code class="directive"><a href="./mod/mod_log_debug.html#logmessage">LogMessage</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="grammar" id="grammar">Syntaxe en Forme de Backus-Naur</a></h2>
        
          <p>La <a href="http://fr.wikipedia.org/wiki/Forme_de_Backus-Naur">Forme de Backus-Naur</a>
          (souvent abrégée en BNF, de l'anglais Backus-Naur Form) est une notation permettant de décrire
          les règles syntaxiques des langages de programmation. En
          général, les expressions représentent des valeurs booléennes. Dans
          ce cas, le point de départ de la BNF est <code>expr</code>.
          Cependant, certaines directives comme <code class="directive"><a href="./mod/mod_log_debug.html#logmessage">LogMessage</a></code> utilisent comme
          paramètres des expressions qui représentent des chaînes de
          caractères. Dans ce cas, le point de départ de la BNF est
          <code>string</code>.
          </p>
    <blockquote>
    <pre>expr        ::= "<strong>true</strong>" | "<strong>false</strong>"
                  | "<strong>!</strong>" expr
                  | expr "<strong>&amp;&amp;</strong>" expr
                  | expr "<strong>||</strong>" expr
                  | "<strong>(</strong>" expr "<strong>)</strong>"
                  | comp
    
    comp        ::= stringcomp
                  | integercomp
                  | unaryop word
                  | word binaryop word
                  | word "<strong>in</strong>" "<strong>{</strong>" wordlist "<strong>}</strong>"
                  | word "<strong>in</strong>" listfunction
                  | word "<strong>=~</strong>" regex
                  | word "<strong>!~</strong>" regex
    
    
    stringcomp  ::= word "<strong>==</strong>" word
                  | word "<strong>!=</strong>" word
                  | word "<strong>&lt;</strong>"  word
                  | word "<strong>&lt;=</strong>" word
                  | word "<strong>&gt;</strong>"  word
                  | word "<strong>&gt;=</strong>" word
    
    integercomp ::= word "<strong>-eq</strong>" word | word "<strong>eq</strong>" word
                  | word "<strong>-ne</strong>" word | word "<strong>ne</strong>" word
                  | word "<strong>-lt</strong>" word | word "<strong>lt</strong>" word
                  | word "<strong>-le</strong>" word | word "<strong>le</strong>" word
                  | word "<strong>-gt</strong>" word | word "<strong>gt</strong>" word
                  | word "<strong>-ge</strong>" word | word "<strong>ge</strong>" word
    
    wordlist    ::= word
                  | wordlist "<strong>,</strong>" word
    
    word        ::= word "<strong>.</strong>" word
                  | digit
                  | "<strong>'</strong>" string "<strong>'</strong>"
                  | "<strong>"</strong>" string "<strong>"</strong>"
                  | variable
    	      | rebackref
                  | function
    
    string      ::= stringpart
                  | string stringpart
    
    stringpart  ::= cstring
                  | variable
    	      | rebackref
    
    cstring     ::= ...
    digit       ::= [0-9]+
    
    variable    ::= "<strong>%{</strong>" varname "<strong>}</strong>"
                  | "<strong>%{</strong>" funcname "<strong>:</strong>" funcargs "<strong>}</strong>"
    
    rebackref   ::= "<strong>$</strong>" [0-9]
    
    function     ::= funcname "<strong>(</strong>" word "<strong>)</strong>"
    
    listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>"</pre>
    </blockquote>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="vars" id="vars">Variables</a></h2>
        
    
        <p>L'interpréteur d'expressions fournit plusieurs variables de la
        forme <code>%{HTTP_HOST}</code>. Notez que la valeur d'une variable
        peut dépendre de la phase du traitement de la requête au cours de
        laquelle elle est évaluée. Par exemple, une expression utilisée dans
        une directive <code class="directive">&lt;If &gt;</code> sera évaluée avant
        la phase d'authentification. Par conséquent, la variable
        <code>%{REMOTE_USER}</code> ne sera pas encore définie à ce stade.</p>
    
        <p>Les variables suivantes contiennent la valeur de l'en-tête de
        requête HTTP correspondant. La <a href="#functions">fonction</a>
        <code>req</code> permet d'extraire les valeurs des autres
        en-têtes. L'utilisation de ces variables peut provoquer
        l'ajout du nom d'en-tête correspondant à l'en-tête Vary de la
        réponse HTTP, sauf spécification contraire pour la directive
        qui accepte l'expression comme paramètre. La <a href="#functions">function</a> <code>req_novary</code> permet de
        modifier ce comportement.</p>
    
        <table class="bordered"><tr class="header"><th>Nom</th></tr>
    <tr><td><code>HTTP_ACCEPT</code></td></tr>
    <tr class="odd"><td><code>HTTP_COOKIE</code></td></tr>
    <tr><td><code>HTTP_FORWARDED</code></td></tr>
    <tr class="odd"><td><code>HTTP_HOST</code></td></tr>
    <tr><td><code>HTTP_PROXY_CONNECTION</code></td></tr>
    <tr class="odd"><td><code>HTTP_REFERER</code></td></tr>
    <tr><td><code>HTTP_USER_AGENT</code></td></tr>
    </table>
    
        <p>Autres variables liées aux requêtes</p>
    
        <table class="bordered"><tr class="header"><th>Nom</th><th>Description</th></tr>
    <tr><td><code>REQUEST_METHOD</code></td>
            <td>La méthode HTTP de la requête entrante (par exemple
    	<code>GET</code>)</td></tr>
    <tr class="odd"><td><code>REQUEST_SCHEME</code></td>
            <td>Le protocole associé à l'URI de la requête</td></tr>
    <tr><td><code>REQUEST_URI</code></td>
            <td>La partie chemin de l'URI de la requête</td></tr>
    <tr class="odd"><td><code>DOCUMENT_URI</code></td>
            <td>Idem <code>REQUEST_URI</code></td></tr>
    <tr><td><code>REQUEST_FILENAME</code></td>
            <td>Le chemin complet dans le système de fichiers local du
    	fichier ou du script correspondant à la requête, si le serveur
    	l'a dèjà déterminé à l'instant où <code>REQUEST_FILENAME</code>
    	est référencée. Dans le cas contraire, comme dans un
    	contexte de serveur virtuel, même valeur que <code>REQUEST_URI</code> </td></tr>
    <tr class="odd"><td><code>SCRIPT_FILENAME</code></td>
            <td>Identique à <code>REQUEST_FILENAME</code></td></tr>
    <tr><td><code>LAST_MODIFIED</code></td>
            <td>La date et heure de dernière modification du fichier au
    	format <code>20101231235959</code>, si elle est déjà connue du
    	serveur au moment où <code>LAST_MODIFIED</code> est référencé.
            </td></tr>
    <tr class="odd"><td><code>SCRIPT_USER</code></td>
            <td>Le nom d'utilisateur du propriétaire du script.</td></tr>
    <tr><td><code>SCRIPT_GROUP</code></td>
            <td>Le nom du groupe auquel appartient le script.</td></tr>
    <tr class="odd"><td><code>PATH_INFO</code></td>
            <td>L'information relative au nom de chemin située en fin, voir
    	la directive <code class="directive"><a href="./mod/core.html#acceptpathinfo">AcceptPathInfo</a></code></td></tr>
    <tr><td><code>QUERY_STRING</code></td>
            <td>La chaîne de paramètres de la requête courante</td></tr>
    <tr class="odd"><td><code>IS_SUBREQ</code></td>
            <td>"<code>true</code>" si la requête courante est une
    	sous-requête, "<code>false</code>" dans le cas contraire</td></tr>
    <tr><td><code>THE_REQUEST</code></td>
            <td>La requête complète (par exemple "<code>GET /index.html
    	HTTP/1.1</code>")</td></tr>
    <tr class="odd"><td><code>REMOTE_ADDR</code></td>
            <td>L'adresse IP de l'hôte distant</td></tr>
    <tr><td><code>REMOTE_PORT</code></td>
            <td>Le port de l'hôte distant (versions 2.4.26 et supérieures)</td></tr>
    <tr class="odd"><td><code>REMOTE_HOST</code></td>
            <td>Le nom d'hôte de l'hôte distant</td></tr>
    <tr><td><code>REMOTE_USER</code></td>
            <td>Le nom de l'utilisateur authentifié, s'il existe (non
    	disponible à l'intérieur d'un bloc <code class="directive">&lt;If&gt;</code>)</td></tr>
    <tr class="odd"><td><code>REMOTE_IDENT</code></td>
            <td>Le nom de l'utilisateur défini par <code class="module"><a href="./mod/mod_ident.html">mod_ident</a></code></td></tr>
    <tr><td><code>SERVER_NAME</code></td>
            <td>La valeur de la directive <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> du serveur virtuel courant</td></tr>
    <tr class="odd"><td><code>SERVER_PORT</code></td>
            <td>Le port associé au serveur virtuel courant ; voir la
    	directive <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code></td></tr>
    <tr><td><code>SERVER_ADMIN</code></td>
            <td>La valeur de la directive <code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code> du serveur virtuel courant</td></tr>
    <tr class="odd"><td><code>SERVER_PROTOCOL</code></td>
            <td>Le protocole utilisé par la requête</td></tr>
    <tr><td><code>DOCUMENT_ROOT</code></td>
            <td>La valeur de la directive <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> du serveur virtuel
    	courant</td></tr>
    <tr class="odd"><td><code>AUTH_TYPE</code></td>
            <td>La valeur de la directive <code class="directive"><a href="./mod/mod_authn_core.html#authtype">AuthType</a></code> (par exemple
    	"<code>basic</code>")</td></tr>
    <tr><td><code>CONTENT_TYPE</code></td>
            <td>Le type de contenu de la réponse (non
    	disponible à l'intérieur d'un bloc <code class="directive">&lt;If&gt;</code>)</td></tr>
    <tr class="odd"><td><code>HANDLER</code></td>
            <td>Le nom du <a href="handler.html">gestionnaire</a> qui a
    	généré la réponse</td></tr>
    <tr><td><code>HTTP2</code></td>
            <td>"<code>on</code>" si la requête utilise http/2,
                "<code>off</code>" dans le cas contraire</td></tr>
    <tr class="odd"><td><code>HTTPS</code></td>
            <td>"<code>on</code>" si la requête utilise https,
    	"<code>off</code>" dans le cas contraire</td></tr>
    <tr><td><code>IPV6</code></td>
            <td>"<code>on</code>" si la connexion utilise IPv6,
    	"<code>off</code>" dans le cas contraire</td></tr>
    <tr class="odd"><td><code>REQUEST_STATUS</code></td>
            <td>Le code d'erreur HTTP de la requête (non
    	disponible à l'intérieur d'un bloc <code class="directive">&lt;If&gt;</code>)</td></tr>
    <tr><td><code>REQUEST_LOG_ID</code></td>
            <td>L'identifiant du message d'erreur associé à la requête (voir
    	la directive <code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code>)</td></tr>
    <tr class="odd"><td><code>CONN_LOG_ID</code></td>
            <td>L'identifiant du message d'erreur associé à la connexion
    	(voir la directive <code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code>)</td></tr>
    <tr><td><code>CONN_REMOTE_ADDR</code></td>
            <td>L'adresse IP du correspondant pour la connexion (voir le module
    	<code class="module"><a href="./mod/mod_remoteip.html">mod_remoteip</a></code>)</td></tr>
    <tr class="odd"><td><code>CONTEXT_PREFIX</code></td>
            <td /></tr>
    <tr><td><code>CONTEXT_DOCUMENT_ROOT</code></td>
            <td /></tr>
    </table>
    
        <p>Variables diverses</p>
    
        <table class="bordered"><tr class="header"><th>Nom</th><th>Description</th></tr>
    <tr><td><code>TIME_YEAR</code></td>
            <td>L'année courante (par exemple <code>2010</code>)</td></tr>
    <tr class="odd"><td><code>TIME_MON</code></td>
            <td>Le mois courant (<code>01</code>, ..., <code>12</code>)</td></tr>
    <tr><td><code>TIME_DAY</code></td>
            <td>Le jour courant dans le mois (<code>01</code>, ...)</td></tr>
    <tr class="odd"><td><code>TIME_HOUR</code></td>
            <td>Les heures de la date courante (<code>00</code>, ...,
    	<code>23</code>)</td></tr>
    <tr><td><code>TIME_MIN</code></td>
            <td>Les minutes de la date courante</td></tr>
    <tr class="odd"><td><code>TIME_SEC</code></td>
            <td>Les secondes de la date courante</td></tr>
    <tr><td><code>TIME_WDAY</code></td>
            <td>Le jour de la semaine (à partir de <code>0</code> pour
    	dimanche)</td></tr>
    <tr class="odd"><td><code>TIME</code></td>
            <td>La date et heure au format <code>20101231235959</code></td></tr>
    <tr><td><code>SERVER_SOFTWARE</code></td>
            <td>La chaîne contenant la version du serveur</td></tr>
    <tr class="odd"><td><code>API_VERSION</code></td>
            <td>La date de la version de l'API (module magic number)</td></tr>
    </table>
    
        <p>Certains modules, comme <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>, définissent des
        variables supplémentaires.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="binop" id="binop">Opérateurs binaires</a></h2>
        
    
        <p>À l'exception de quelques opérateurs de comparaison internes, les
        opérateurs binaires sont de la forme
        "<code>-[a-zA-Z][a-zA-Z0-9_]+</code>", autrement dit un signe moins
        et au moins deux caractères. Le nom est insensible à la casse. Les
        modules peuvent fournir des opérateurs binaires supplémentaires.</p>
    
        <h3><a name="comp" id="comp">Opérateurs de comparaison</a></h3>
        
    
        <table class="bordered"><tr class="header"><th>Nom</th><th>Alternative</th> <th>Description</th></tr>
    <tr><td><code>==</code></td>
            <td><code>=</code></td>
            <td>Egalité de chaînes</td></tr>
    <tr class="odd"><td><code>!=</code></td>
            <td />
            <td>Inégalité de chaînes</td></tr>
    <tr><td><code>&lt;</code></td>
            <td />
            <td>Chaîne inférieure à</td></tr>
    <tr class="odd"><td><code>&lt;=</code></td>
            <td />
            <td>Chaîne inférieure ou égale à</td></tr>
    <tr><td><code>&gt;</code></td>
            <td />
            <td>Chaîne supérieure à</td></tr>
    <tr class="odd"><td><code>&gt;=</code></td>
            <td />
            <td>Chaîne supérieure ou égale à</td></tr>
    <tr><td><code>=~</code></td>
            <td />
            <td>La chaîne correspond à l'expression rationnelle</td></tr>
    <tr class="odd"><td><code>!~</code></td>
            <td />
            <td>La chaîne ne correspond pas à l'expression rationnelle</td></tr>
    <tr><td><code>-eq</code></td>
            <td><code>eq</code></td>
            <td>Egalité d'entiers</td></tr>
    <tr class="odd"><td><code>-ne</code></td>
            <td><code>ne</code></td>
            <td>Inégalité d'entiers</td></tr>
    <tr><td><code>-lt</code></td>
            <td><code>lt</code></td>
            <td>Entier inférieur à</td></tr>
    <tr class="odd"><td><code>-le</code></td>
            <td><code>le</code></td>
            <td>Entier inférieur ou égal à</td></tr>
    <tr><td><code>-gt</code></td>
            <td><code>gt</code></td>
            <td>Entier supérieur à</td></tr>
    <tr class="odd"><td><code>-ge</code></td>
            <td><code>ge</code></td>
            <td>Entier supérieur ou égal à</td></tr>
    </table>
        
    
        <h3><a name="binaryother" id="binaryother">Autres opérateurs binaires</a></h3>
        
    
        <table class="bordered"><tr class="header"><th>Nom</th><th>Description</th></tr>
    <tr><td><code>-ipmatch</code></td>
            <td>L'adresse IP correspond à adresse/masque</td></tr>
    <tr class="odd"><td><code>-strmatch</code></td>
            <td>la chaîne de gauche correspond au modèle constitué par la
    	chaîne de droite (contenant des caractères génériques *, ?, [])</td></tr>
    <tr><td><code>-strcmatch</code></td>
            <td>idem <code>-strmatch</code>, mais insensible à la casse</td></tr>
    <tr class="odd"><td><code>-fnmatch</code></td>
            <td>idem <code>-strmatch</code>, mais les slashes ne sont pas
    	pris en compte par les caractères génériques</td></tr>
    </table>
        
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="unnop" id="unnop">Opérateurs unaires</a></h2>
        
    
        <p>Les opérateurs unaires acceptent un seul argument et sont
        de la forme "<code>-[a-zA-Z]</code>",
        autrement dit le signe moins et un caractère. Le nom <em>est</em>
        sensible à la casse. Les modules peuvent fournir des opérateurs
        unaires supplémentaires.</p>
    
        <table class="bordered"><tr class="header"><th>Nom</th><th>Description</th><th>Remarques particulières</th></tr>
    <tr><td><code>-d</code></td>
            <td>L'argument est traité comme un nom de fichier. 
    	Vrai si le fichier existe et correspond à un
    	répertoire</td><td>oui</td></tr>
    <tr class="odd"><td><code>-e</code></td>
            <td>L'argument est traité comme un nom de fichier. Vrai si le
    	fichier (ou dir ou special) existe</td><td>oui</td></tr>
    <tr><td><code>-f</code></td>
            <td>L'argument est traité comme un nom de fichier. Vrai si le
    	fichier existe et correspond à un fichier
    	régulier</td><td>oui</td></tr>
    <tr class="odd"><td><code>-s</code></td>
            <td>L'argument est traité comme un nom de fichier. Vrai si le
    	fichier existe et n'est pas vide</td><td>oui</td></tr>
    <tr><td><code>-L</code></td>
            <td>L'argument est traité comme un nom de fichier. Vrai si le
    	fichier existe et correspond à un lien
    	symbolique</td><td>oui</td></tr>
    <tr class="odd"><td><code>-h</code></td>
            <td>L'argument est traité comme un nom de fichier. Vrai si le
    	fichier existe et correspond à un lien symbolique
    	(identique à <code>-L</code>)</td><td>oui</td></tr>
    <tr><td><code>-F</code></td>
            <td>Vrai si la chaîne correspond a un fichier valide, accessible
    	avec tous les contrôles d'accès configurés pour ce chemin. A
    	cette fin, une sous-requête effectue la vérification, et vous
    	devez utiliser ce drapeau avec soin car il peut impacter les
    	performances de votre serveur !</td><td /></tr>
    <tr class="odd"><td><code>-U</code></td>
            <td>Vrai si la chaîne correspond a une URL valide, accessible
    	avec tous les contrôles d'accès configurés pour ce chemin. A
    	cette fin, une sous-requête effectue la vérification, et vous
    	devez utiliser ce drapeau avec soin car il peut impacter les
    	performances de votre serveur !</td><td /></tr>
    <tr><td><code>-A</code></td>
            <td>Alias pour <code>-U</code></td><td /></tr>
    <tr class="odd"><td><code>-n</code></td>
            <td>Vrai si la chaîne n'est pas vide</td><td /></tr>
    <tr><td><code>-z</code></td>
            <td>Vrai si la chaîne est vide</td><td /></tr>
    <tr class="odd"><td><code>-T</code></td>
            <td>Faux si la chaîne est vide, "<code>0</code>",
    	"<code>off</code>", "<code>false</code>", ou "<code>no</code>"
    	(insensibilité à la casse). Vrai dans le cas contraire.</td><td /></tr>
    <tr><td><code>-R</code></td>
            <td>Idem "<code>%{REMOTE_ADDR} -ipmatch ...</code>", en plus
    	efficace
            </td><td /></tr>
    </table>
    
        <p>Les opérateurs marqués comme "restreints" ne sont pas disponibles
        avec certains modules comme <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="functions" id="functions">Fonctions</a></h2>
        
    
        <p>Normalement, les fonctions dont la valeur est une chaîne acceptent une chaîne
        comme argument et renvoient une chaîne. Les noms de fonctions sont
        insensibles à la casse. Les modules peuvent fournir des fonctions
        supplémentaires.</p>
    
        <table class="bordered"><tr class="header"><th>Nom</th><th>Description</th><th>Notes particulières</th></tr>
    <tr><td><code>req</code>, <code>http</code></td>
            <td>Lit l'en-tête de requête HTTP ; les noms
    	d'en-tête correspondants peuvent être ajoutés
    	à l'en-tête Vary,
    	voir ci-dessous</td><td /></tr>
    <tr class="odd"><td><code>req_novary</code></td>
            <td>Identique à <code>req</code>, mais aucun nom d'en-tête n'est
    	ajouté à l'en-tête Vary</td><td /></tr>
    <tr><td><code>resp</code></td>
            <td>Lit l'en-tête de réponse HTTP (La plupart des en-têtes de la réponse
    	ne seront pas encore définis pendant le traitement de la directive
    	<code class="directive">&lt;If&gt;</code>)</td><td /></tr>
    <tr class="odd"><td><code>reqenv</code></td>
            <td>Recherche une variable d'environnement de requête (on
    	peut aussi utiliser le raccourci <code>v</code>).
    	</td>
    	<td>ordonnancement</td></tr>
    <tr><td><code>osenv</code></td>
            <td>Recherche une variable d'environnement du système
    	d'exploitation</td><td /></tr>
    <tr class="odd"><td><code>note</code></td>
            <td>Recherche une note de requête</td><td>ordonnancement</td></tr>
    <tr><td><code>env</code></td>
            <td>Renvoie le premier résultat positif de <code>note</code>,
    	<code>reqenv</code>, <code>osenv</code></td><td>ordonnancement</td></tr>
    <tr class="odd"><td><code>tolower</code></td>
            <td>Convertit une chaîne en minuscules</td><td /></tr>
    <tr><td><code>toupper</code></td>
            <td>Convertit une chaîne en majuscules</td><td /></tr>
    <tr class="odd"><td><code>escape</code></td>
            <td>Echappe les caractères spéciaux en codage hexadécimal</td><td /></tr>
    <tr><td><code>unescape</code></td>
            <td>"Déséchappe" les chaînes codées
    	en hexadécimal, en ne gardant encodés que les slashes; renvoie la chaîne vide
    	si la séquence %00 est rencontrée</td><td /></tr>
    <tr class="odd"><td><code>base64</code></td>
            <td>Encode la chaîne en base64</td><td /></tr>
    <tr><td><code>unbase64</code></td>
            <td>Décode les chaînes codées en base64, renvoie une chaîne
    	tronquée si le caractère 0x00 est rencontré</td><td /></tr>
    <tr class="odd"><td><code>md5</code></td>
            <td>Génère un hash de la chaîne en utilisant MD5, puis code le
    	hash obtenu en hexadécimal</td><td /></tr>
    <tr><td><code>sha1</code></td>
            <td>Génère un hash de la chaîne en utilisant SHA1, puis encode
    	le hash obtenu en hexadécimal</td><td /></tr>
    <tr class="odd"><td><code>file</code></td>
            <td>Lit le contenu d'un fichier(fins de lignes incluses, si
    	elles existent)</td><td>limité</td></tr>
    <tr><td><code>filesize</code></td>
            <td>Renvoie la taille d'un fichier (ou 0 si le fichier n'existe
    	pas ou ne correspond pas à un fichier régulier)</td><td>limité</td></tr>
    <tr class="odd"><td><code>ldap</code></td>
            <td>Echappe les caractères selon la RFC4514 (Echappement des
    	noms distinctifs LDAP - DN) et la RFC4515 (Echappement des
    	filtres LDAP).<br />
    	Disponible à partir de la version 2.4.53 du serveur HTTP
    	Apache.</td><td /></tr>
    </table>
    
        <p>Les fonctions marquées comme "limité" dans la dernière colonne ne sont
        pas disponibles avec certains modules comme
        <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>.</p>
    
        <p>Les fonctions marquées comme "ordonnancement" dans la dernière colonne
        nécessitent une attention particulière pour l'ordonnancement des différents
        composants du serveur, spécialement lorsque la fonction est utilisée au sein
        d'une directive &lt;<code class="directive"><a href="./mod/core.html#if">If</a></code>&gt; qui est
        évaluée relativement tôt.</p>
        <div class="note">
        <h3>Ordonnancement des variables d'environnement</h3>
        Lorsque des variables d'environnement sont évaluées au sein d'une directive
        &lt;<code class="directive"><a href="./mod/core.html#if">If</a></code>&gt;, il est important de tenir
        compte du moment où cette évaluation intervient dans le traitement de la
        requête. Par exemple, toute directive définie en dehors d'un contexte de
        serveur virtuel (directory, location, htaccess) aura peu de chance d'être
        déjà exécutée. Ainsi la directive <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code> est une directive qui s'exécute
        avant cette évaluation.
        <br />
        <br />
        Lorsque <code>reqenv</code> est utilisé en dehors de la directive
        &lt;<code class="directive"><a href="./mod/core.html#if">If</a></code>&gt;, l'évaluation survient en
        général plus tard, mais le moment exact dépend de la directive dans laquelle
        l'expression a été utilisée.
        </div>
    
        <p>Lorsque les fonctions <code>req</code> ou <code>http</code> sont
        utilisées, le nom d'en-tête sera automatiquement ajouté à l'en-tête
        Vary de la réponse HTTP, sauf spécification contraire pour la
        directive qui accepte l'expression comme paramètre. La
        fonction <code>req_novary</code> permet d'empêcher l'ajout de noms
        d'en-têtes à l'en-tête Vary.</p>
    
        <p>En plus des fonctions dont la valeur est une chaîne, il existe
        aussi des fonctions dont la valeur est une liste, qui acceptent une
        chaîne comme argument, et renvoient une liste de mots, autrement dit
        une liste de chaînes. La liste de mot peut être utilisée avec
        l'opérateur spécial <code>-in</code>. Les noms de fonctions sont
        insensibles à la casse. Les modules peuvent fournir des fonctions
        supplémentaires.</p>
    
        <p>Il n'existe pas de fonctions internes dont la valeur est une
        liste. Le module <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> fournit la fonction
        <code>PeerExtList</code>. Voir la description de la directive
        <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code> pour plus de
        détails (notez que la fonction <code>PeerExtList</code> peut aussi
        être utilisée en dehors de la directive <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code>).</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Exemples d'expressions</a></h2>
        
    	
    	<p>Les exemples suivants montent comment utiliser les
    	expressions pour évaluer les requêtes :</p>
    	
    	<pre class="prettyprint lang-config"># Comparer le nom d'hôte avec example.com et rediriger vers
    # www.example.com si le nom d'hôte correspond
    &lt;If "%{HTTP_HOST} == 'example.com'"&gt;
        Redirect permanent "/" "http://www.example.com/"
    &lt;/If&gt;
    
    # Forcer le type text/plain si un fichier fait l'objet d'une
    # requête dont la chaîne de paramètres contient 'forcetext'
    &lt;If "%{QUERY_STRING} =~ /forcetext/"&gt;
        ForceType text/plain
    &lt;/If&gt;
    
    # N'autoriser l'accès à ce contenu que pendant les heures de
    # travail
    &lt;Directory "/foo/bar/business"&gt;
         Require expr %{TIME_HOUR} -gt 9 &amp;&amp; %{TIME_HOUR} -lt 17
    &lt;/Directory&gt;
    
    # Vérifie si un en-tête HTTP correspond à une des valeurs d'une liste
    &lt;If "%{HTTP:X-example-header} in { 'foo', 'bar', 'baz' }"&gt;
        La définition de l'en-tête correspond à une des valeurs recherchées
    &lt;/If&gt;
    
    # Recherche la valeur d'une expression rationnelle dans une variable
    # d'environnement, et renvoie la négation du résultat.
    &lt;If "! reqenv('REDIRECT_FOO') =~ /bar/"&gt;
        La condition est vérifiée
    &lt;/If&gt;
    
    # Vérifie le résultat de la recherche d'une correspondance d'URI dans un
    # contexte de répertoire avec l'option -f
    &lt;Directory "/var/www"&gt;
        AddEncoding x-gzip gz
    &lt;If "-f '%{REQUEST_FILENAME}.unzipme' &amp;&amp; ! %{HTTP:Accept-Encoding} =~ /gzip/"&gt;
          SetOutputFilter INFLATE
    &lt;/If&gt;
    &lt;/Directory&gt;
    
    # Vérifie l'adresse IP du client
    &lt;If "-R '192.168.1.0/24'"&gt;
        Header set matched true
    &lt;/If&gt;
    
    # Exemple de fonction dans un contexte booléen
    &lt;If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'"&gt;
      Header set checksum-matched true
    &lt;/If&gt;
    
    # Function example in string context
    Header set foo-checksum "expr=%{md5:foo}"
    
    # L'exemple suivant retarde l'évaluation de la clause de condition par rapport à
    # &lt;If&gt;
    Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path\.php$#"
    
    # Journalisation conditionnelle
    CustomLog logs/access-errors.log common "expr=%{REQUEST_STATUS} &gt;= 400"
    CustomLog logs/access-errors-specific.log common "expr=%{REQUEST_STATUS} -in {'405','410'}"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Autres</a></h2>
        
    
        <table class="bordered"><tr class="header"><th>Nom</th><th>Alternative</th> <th>Description</th></tr>
    <tr><td><code>-in</code></td>
            <td><code>in</code></td>
            <td>chaîne contenue dans une liste de mots</td></tr>
    <tr class="odd"><td><code>/regexp/</code></td>
            <td><code>m#regexp#</code></td>
            <td>Expression rationnelle (la seconde forme permet de spécifier
    	des délimiteurs autres que /)</td></tr>
    <tr><td><code>/regexp/i</code></td>
            <td><code>m#regexp#i</code></td>
            <td>Expression rationnelle insensible à la casse</td></tr>
    <tr class="odd"><td><code>$0 ... $9</code></td>
            <td />
            <td>Références arrières dans les expressions rationnelles</td></tr>
    </table>
    
        <h3><a name="rebackref" id="rebackref">Références arrières dans les expressions rationnelles</a></h3>
            
            <p>Les chaînes <code>$0</code> ... <code>$9</code> permettent de
    	référencer les groupes de capture en provenance d'expressions
    	rationnelles précédemment exécutées et mises en correspondance avec
    	succès. Elles ne peuvent normalement être utilisées que dans la
    	même expression que celle mise en correspondance, mais certains
    	modules permettent de les utiliser de manière spéciale.</p>
        
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="sslrequire" id="sslrequire">Comparaison avec SSLRequire</a></h2>
        
        <p>La syntaxe <em>ap_expr</em> consiste principalement en une
        surcouche de la syntaxe de la directive obsolète <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code>. Vous pouvez consulter la
        liste de leur différences dans la documentation de la directive
        <code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compatibility" id="compatibility">Historique de version</a></h2>
        
        <p>La <a href="#functions">fonction</a> <code>req_novary</code> est
        disponible à partir de la version 2.4.4 du serveur HTTP Apache.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/expr.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/expr.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/expr.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/glossary.html.fr.utf8������������������������������������������������������0000664�0001751�0001751�00000104011�14740503670�021056� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Glossaire - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Glossaire</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Ce glossaire définit la terminologie courante relative à Apache en
        particulier, et aux serveurs web en général. Vous trouverez plus
        d'informations sur chaque concept dans les liens fournis.</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definitions" id="definitions">Définitions</a></h2>
    <dl>
    <dt><a name="algorithm" id="algorithm">Algorithme</a></dt>
    
        <dd>Une formule sans ambiguité ou un jeu de règles destinées à
        résoudre un problème en un nombre fini d'étapes. Les algorithmes de
        chiffrement sont en général appelés
          <dfn>Ciphers</dfn>.
        </dd>
    
        <dt><a name="cipher" id="cipher">Algorithme de chiffrement
        (Cipher)</a></dt>
        <dd>Un algorithme ou un système de chiffrement des données.
        Quelques exemples : DES, IDEA, RC4, etc.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="apr" id="APR">APR</a></dt>
        <dd>Voir "Bibliothèques pour la portabilité d'Apache"
        </dd>
    
        <dt><a name="tarball" id="tarball">Archive Tar (Tarball)</a></dt>
      <dd>Un paquetage de fichiers rassemblés dans une archive
      à l'aide de l'utilitaire <code>tar</code>.
        Les distributions d'Apache sont stockées dans des Archives Tar compressées
        ou en utilisant pkzip.
      </dd>
    
        <dt><a name="authentication" id="authentication">Authentification </a></dt>
        <dd>L'identification formelle d'une entité du réseau comme un serveur, un
        client, ou un utilisateur.<br />
          Voir : <a href="howto/auth.html">Authentification, Autorisation, et
          contrôle d'accès</a>
        </dd>
    
        <dt><a name="certificationauthority" id="certificationauthority">Autorité de Certification
    	(Certification Authority)</a>
          <a name="ca" id="ca">(CA)</a></dt>
        <dd>Un tiers de confiance habilité à signer des certificats pour des entités
        du réseau qu'il a authentifiées selon des critères basés sur la sécurité.
        Les autres entités du réseau peuvent alors utiliser la signature pour
        vérifier qu'une CA a authentifié le porteur du certificat.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="apacheportableruntime" id="apacheportableruntime">Bibliothèques pour la portabilité d'Apache
           (Apache Portable Runtime)</a> <a name="apr" id="apr">(APR)</a></dt>
        <dd>Un jeu de bibliothèques qui fournit la plupart des interfaces de base
          entre le serveur et le système d'exploitation.  APR est développé
          parallèlement au serveur HTTP Apache comme projet indépendant.<br />
          Voir : <a href="http://apr.apache.org/">Apache Portable Runtime
          Project</a>
        </dd>
    
    
    <dt><a name="certificate" id="certificate">Certificat (Certificate)</a></dt>
        <dd>Un ensemble de données servant à authentifier des entités du
        réseau comme un serveur ou un client. Un certificat contient des ensembles
        d'informations X509 à propos de son propriétaire (appelé sujet/subject)
        et de l'<a class="glossarylink" href="./glossary.html#certificationauthority" title="voir glossaire">Autorité de Certification
          (Certification Authority) ou CA</a> signataire (appelée
          le fournisseur/issuer), ainsi que la
          <a class="glossarylink" href="./glossary.html#publickey" title="voir glossaire">clé publique (public
          key)</a> du propriétaire et la
          signature de la CA. Les entités du réseau vérifient ces signatures
          en utilisant les certificats des Autorités de Certification.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="publickeycryptography" id="publickeycryptography">Chiffrement à Clé Publique
          (Public Key Cryptography)</a></dt>
        <dd>L'étude et l'application des systèmes de chiffrement asymétriques,
        qui utilisent une clé pour le chiffrement et une autre pour le
        déchiffrement. Les deux clés correspondantes constituent une paire de clés.
        Appelé aussi chiffrement asymétrique.
          <br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="privatekey" id="privatekey">Clé Privée (Private Key)</a></dt>
        <dd>La clé secrète dans un système de
        <a class="glossarylink" href="./glossary.html#publickeycryptography" title="voir glossaire">chiffrement à clé publique</a>,
        utilisée pour déchiffrer les messages entrants et signer
        les messages sortants.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
    <dt><a name="publickey" id="publickey">Clé Publique (Public Key)</a></dt>
        <dd>La clé accessible au public dans un système de <a class="glossarylink" href="./glossary.html#publickeycryptography" title="voir glossaire">Chiffrement à clé publique</a>,
          utilisée pour chiffrer les messages destinés uniquement à son
          propriétaire et déchiffrer les signatures
          faites par son propriétaire.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
    <dt><a name="connect" id="connect">CONNECT</a></dt>
        <dd>Une <a class="glossarylink" href="./glossary.html#method" title="voir glossaire">méthode</a> HTTP pour encapsuler
        des données brutes dans HTTP. Elle peut aussi être utilisée pour encapsuler
        d'autres protocoles, comme le protocole SSL.
        </dd>
    
        <dt><a name="context" id="context">Contexte (Context)</a></dt>
        <dd>Une portion des <a class="glossarylink" href="./glossary.html#configurationfile" title="voir glossaire">
        fichiers de configuration</a> dans laquelle certains types de
        <a class="glossarylink" href="./glossary.html#directive" title="voir glossaire">directives</a> sont autorisés.<br />
          Voir : <a href="mod/directive-dict.html#Context">Termes utilisés
          pour décrire les directives d'Apache</a>
        </dd>
    
        <dt><a name="accesscontrol" id="accesscontrol">Contrôle d'accès
        (Access Control)</a></dt>
        <dd>La restriction d'accès à des zones du réseau. Habituellement
        dans un contexte Apache,
          la restriction d'accès à certaines <em>URLs</em>.<br />
          Voir :  <a href="howto/auth.html">Authentification, Autorisation et
          Contrôle d'accès</a>
        </dd>
    
        <dt><a name="securesocketslayer" id="securesocketslayer">
        Couche des Points de connexion Sécurisés
        (Secure Sockets Layer)
          </a> <a name="ssl" id="ssl">(SSL)</a></dt>
      <dd>Un protocole créé par Netscape Communications Corporation pour
      l'authentification et le chiffrement généraux des communications dans les
      réseaux TCP/IP.  L'utilisation la plus connue est <em>HTTPS</em>, autrement dit
      le Protocole de Transfert Hypertexte (HTTP) au dessus de SSL.<br />
        Voir : <a href="ssl/">chiffrement SSL/TLS</a>
      </dd>
    
      <dt><a name="subrequest" id="subrequest">Sous-requête</a></dt>
        <dd>Apache possède une API des sous-requêtes pour les modules qui
        permettent l'évaluation complète ou partielle par le serveur de
        chemins d'autres systèmes de fichiers ou d'URL. Par exemple, la
        directive <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>,
        les modules <code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code> et
        <code class="module"><a href="./mod/mod_include.html">mod_include</a></code> utilisent cette API.
        </dd>
    
      <dt><a name="symmetriccryptophraphy" id="symmetriccryptophraphy">
      Cryptographie Symétrique (Symmetric Cryptography)</a></dt>
      <dd>L'étude et l'application des <em>Algorithmes de chiffrement</em> qui
      utilisent une clé secrète unique pour les opérations de chiffrement et de
      déchiffrement.<br />
        Voir : <a href="ssl/">chiffrement SSL/TLS</a>
      </dd>
    
    
        <dt><a name="export-crippled" id="export-crippled">
        Dégradé pour l'exportation
        (Export-Crippled)</a></dt>
        <dd>Diminué en terme de puissance cryptographique (et de sécurité)
        afin de respecter les Règles de l'Administration des Exportations
         des Etats-Unis (Export Administration Regulations ou EAR).
          Les logiciels de cryptographie dégradés pour l'exportation sont limités
          à une clé de petite taille, et produisent un
          <em>Texte crypté</em> qui peut en général être décrypté
          par force brute.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
    
        <dt><a name="certificatsigningrequest" id="certificatsigningrequest">Demande de signature de certificat
          (Certificate Signing Request)</a>
          <a name="csr" id="csr">(CSR)</a></dt>
        <dd>La soumission d'un <a class="glossarylink" href="./glossary.html#certificate" title="voir glossaire">certificat</a>
        non signé à une <a class="glossarylink" href="./glossary.html#certificationauthority" title="voir glossaire">Autorité de
        certification</a>, qui le signe avec la <a class="glossarylink" href="./glossary.html#privatekey" title="voir glossaire">Clé privée</a> de leur
          <em>Certificat</em> de CA. Une fois le CSR signé, il devient un vrai
          certificat.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="directive" id="directive">Directive</a></dt>
        <dd>Une commande de configuration qui contrôle un ou plusieurs aspects du
        comportement d'Apache.  Les directives sont placées dans le <a class="glossarylink" href="./glossary.html#configurationfile" title="voir glossaire">Fichier de configuration</a><br />
        Voir : <a href="mod/directives.html">Index des directives</a>
        </dd>
    
    <dt><a name="configurationdirective" id="configurationdirective">Directive de configuration
    	(Configuration Directive)</a></dt>
        <dd>Voir : <a class="glossarylink" href="./glossary.html#directive" title="voir glossaire">Directive</a></dd>
    
        <dt><a name="header" id="header">En-tête (Header)</a></dt>
        <dd>La partie de la requête et de la réponse
        <a class="glossarylink" href="./glossary.html#http" title="voir glossaire">HTTP</a> qui est envoyée avant le contenu
        proprement dit, et contient des méta-informations décrivant le contenu.
        </dd>
    
        <dt><a name="regularexpression" id="regularexpression">Expression Rationnelle
        (Regular Expression)</a>
          <a name="regex" id="regex">(Regex)</a></dt>
        <dd>Une méthode pour décrire un modèle sous forme de texte - par exemple,
        "tous les mots qui commencent par la lettre A" ou "tous les numéros de
        téléphone à 10 chiffres" ou encore "Toutes les phrases contenant 2 virgules,
        et aucun Q majuscule". Les expressions rationnelles sont très utiles dans
        Apache car elles vous permettent d'appliquer certains attributs à des
        ensembles de fichiers ou ressources avec une grande flexibilité
          - par exemple, tous les fichiers .gif et .jpg situés dans tout répertoire
          nommé "images", pourraient être enregistrés comme
          "<code>/images/.*(jpg|gif)$</code>".  Lorsque l'on utilise des
          expressions rationnelles pour la substitution de chaînes, les
          variables spéciales $1 ... $9 contiennent des références arrières
          vers les parties regroupées (entre parenthèses) de l'expression
          qui correspond. La variable spéciale $0 contient une référence
          arrière vers l'ensemble de l'expression qui correspond. Pour
          insérer un caractère littéral "dollar" dans la chaîne de
          remplacement, il faut l'échapper avec un anti-slash. Pour des
          raisons historiques, la variable &amp; peut être utilisée en tant
          qu'alias de $0 dans certains cas, mais ceci n'est plus possible
          depuis la version 2.3.6. Apache utilise les Expressions
          Rationnelles Compatibles avec Perl fournies par la librairie <a href="http://www.pcre.org/">PCRE</a>. Vous trouverez plus
          d'information à propos de la syntaxe des expressions rationnelles
          PCRE sur ce site, ou dans le <a href="http://en.wikipedia.org/wiki/PCRE">Wikipedia de la PCRE</a>.
      </dd>
    
        <dt><a name="configurationfile" id="configurationfile">
        Fichier de configuration
        (Configuration File)</a></dt>
        <dd>Un fichier texte contenant des
        <a class="glossarylink" href="./glossary.html#directive" title="voir glossaire">Directives</a>
          qui contrôlent la configuration d'Apache.<br />
          Voir : <a href="configuring.html">Fichiers de configuration</a>
        </dd>
    
        <dt><a name="filter" id="filter">Filtre (Filter)</a></dt>
        <dd>Un traitement appliqué aux données envoyées ou reçues par le serveur.
          Les filtres en entrée traitent les données envoyées au serveur par le
          client, alors que les filtres en sortie traitent les documents sur le
          serveur avant qu'ils soient envoyés au client.
          Par exemple, le filtre en sortie
          <code>INCLUDES</code>
          traite les documents pour les
          <a class="glossarylink" href="./glossary.html#ssi" title="voir glossaire">Server Side Includes (Inclusions côté Serveur)
          </a>.<br />
          Voir : <a href="filter.html">Filtres</a>
        </dd>
    
    <dt><a name="handler" id="handler">Gestionnaire (Handler)</a></dt>
        <dd>Une représentation interne à Apache de l'action à entreprendre
        quand un fichier est appelé. En général, les fichiers ont des gestionnaires
        implicites, basés sur le type de fichier. Normalement, tous les
        fichiers sont directement servis par le serveur, mais certains
        types de fichiers sont "gérés" séparément.  Par exemple, le gestionnaire
          <code>cgi-script</code> désigne les fichiers qui doivent être traités
          comme <a class="glossarylink" href="./glossary.html#cgi" title="voir glossaire">CGIs</a>.<br />
          Voir : <a href="handler.html">Utilisation des gestionnaires d'Apache</a>
        </dd>
    
        <dt><a name="hash" id="hash">Hachage (Hash)</a></dt>
        <dd>Un algorithme mathématique à sens unique, irréversible, générant une
        chaîne de longueur fixe à partir d'une autre chaîne de longueur quelconque.
        Des chaînes différentes en entrée vont normalement produire des chaînes
        différentes en sortie (selon la fonction de hachage).
        </dd>
    
        <dt><a name="virtualhosting" id="virtualhosting">Hébergement Virtuel
        (Virtual Hosting)</a></dt>
      <dd>Servir des sites web multiples en utilisant une seule instance d'Apache.
      Les <em>Hôtes virtuels basés sur IP</em> différencient les sites web en se
      basant sur leur adresse IP, alors que les
      <em>Hôtes virtuels basés sur le nom</em> utilisent uniquement le nom d'hôte
      et peuvent en conséquence héberger de nombreux sites avec la même
      adresse IP.<br />
        Voir la <a href="vhosts/">Documentation des Hôtes Virtuels d'Apache</a>
      </dd>
    
    
        <dt><a name="htaccess" id="htaccess">.htaccess</a></dt>
        <dd>Un <a class="glossarylink" href="./glossary.html#configurationfile" title="voir glossaire">fichier de configuration</a>
        placé à un certain niveau de l'arborescence du site web, et appliquant des
        <a class="glossarylink" href="./glossary.html#directive" title="voir glossaire">directives</a> de configuration au
        répertoire dans lequel il est placé, ainsi qu'à tous ses sous-répertoires.
        En dépit de son nom, ce fichier peut contenir pratiquement tout type de
        directive, et pas seulement des directives de contrôle d'accès.<br />
          Voir : <a href="configuring.html">Fichiers de configuration</a>
        </dd>
    
    <dt><a name="httpd.conf" id="httpd.conf">httpd.conf</a></dt>
        <dd>Le <a class="glossarylink" href="./glossary.html#configurationfile" title="voir glossaire">fichier de configuration
        </a> principal d'Apache.  Sa localisation par défaut est
          <code>/usr/local/apache2/conf/httpd.conf</code>, mais ceci peut être
          changé en utilisant des options de compilation ou d'exécution.<br />
          Voir : <a href="configuring.html">Fichiers de configuration</a>
        </dd>
    
         <dt><a name="https" id="https">HTTPS</a></dt>
        <dd>Le Protocole de Transfert Hypertexte (Sécurisé), le mécanisme de
        communication cryptée standard sur le World Wide Web.
        Il s'agit en fait de HTTP au dessus de
        <a class="glossarylink" href="./glossary.html#ssl" title="voir glossaire">SSL</a>.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="uniformresourceidentifier" id="uniformresourceidentifier">Identificateur de Ressource Uniformisé
        (Uniform Resource Identifier)</a>
        <a name="URI" id="URI">(URI)</a></dt>
      <dd>Une chaîne de caractères compacte servant à identifier une ressource
      abstraite ou physique.  Elle est formellement définie par la <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>.  Les URIs
          utilisées sur le world-wide web sont souvent appelées <a class="glossarylink" href="./glossary.html#url" title="voir glossaire">URLs</a>.
      </dd>
    
        <dt><a name="serversideincludes" id="serversideincludes">
        Inclusions Côté Serveur
        (Server Side Includes)</a> <a name="ssi" id="ssi">(SSI)
          </a></dt>
      <dd>Une technique permettant d'englober des directives de traitement dans
      des fichiers HTML.<br />
        Voir : <a href="howto/ssi.html">Introduction aux Inclusions Côté Serveur</a>
      </dd>
    
      <dt><a name="servernameindication" id="servernameindication">Indication du nom du serveur</a> <a name="sni" id="sni">(SNI)</a></dt>
        <dd>Une fonctionnalité SSL permettant de spécifier le
        nom du serveur désiré dans le message initial de la
        négociation SSL, de façon à ce que le serveur web
        puisse choisir la bonne configuration de serveur virtuel à
        utiliser pendant le déroulement de la négociation SSL.
        Cette fonctionnalité a été ajoutée
        à SSL lorsque sont apparues les extensions TLS, RFC 3546.<br />
          Voir <a href="ssl/ssl_faq.html">la FAQ SSL</a>
          et <a href="http://www.ietf.org/rfc/rfc3546.txt">la RFC 3546</a>
        </dd>
    
    
    
    <dt><a name="commongatewayinterface" id="commongatewayinterface">
    Interface commune avec les programmes externes
    (Common Gateway Interface)</a>
    	 <a name="cgi" id="cgi">(CGI)</a></dt>
        <dd>La définition standard d'une interface entre un serveur web et un
        programme externe pour permettre à ce dernier de traiter des requêtes.
         Il existe une <a href="http://www.ietf.org/rfc/rfc3875">RFC
         informationnelle</a> qui en couvre les spécificités.<br />
          Voir : <a href="howto/cgi.html">Contenu dynamique avec CGI</a>
        </dd>
    
    
    
    <dt><a name="uniformresourcelocator" id="uniformresourcelocator">
    Localisation de Ressource Uniformisée
    (Uniform Resource Locator)
          </a> <a name="url" id="url">(URL)</a></dt>
      <dd>Le nom/adresse d'une ressource sur l'Internet.  Il s'agit du terme
      informel commun pour ce qui est formellement défini comme <a class="glossarylink" href="./glossary.html#uniformresourceidentifier" title="voir glossaire">
          Identificateur de Ressource Uniformisé</a>.
        Les URLs sont généralement construites selon un schéma, comme
        <code>http</code> ou
        <code>https</code>, un nom d'hôte, et un chemin.  Une URL pour cette page
        pourrait être
        <code>http://httpd.apache.org/docs/2.4/glossary.html</code>.
      </dd>
    
    
        <dt><a name="proxy" id="proxy">Mandataire (Proxy)</a></dt>
        <dd>Un serveur intermédiaire qui se situe entre le client et le
        <em>serveur d'origine</em>.
        Il prend en compte les requêtes des clients, les transmet au serveur
        d'origine, puis renvoie la réponse du serveur d'origine au client.
        Si plusieurs clients demandent le même contenu, le mandataire peut l'extraire
        de son cache, plutôt que le demander au serveur d'origine
        à chaque fois, ce qui réduit le temps de réponse.<br />
          Voir : <a href="mod/mod_proxy.html">mod_proxy</a>
        </dd>
    
        <dt><a name="reverseproxy" id="reverseproxy">Mandataire inverse
        (Reverse Proxy)</a></dt>
      <dd>Un serveur <a class="glossarylink" href="./glossary.html#proxy" title="voir glossaire">mandataire</a> qui est vu du client
        comme un <em>serveur d'origine</em>.  Ceci peut s'avérer utile pour
        dissimuler le serveur d'origine réel au client pour des raisons de sécurité,
        ou pour répartir la charge.
      </dd>
    
        <dt><a name="method" id="method">Méthode (Method)</a></dt>
        <dd>Dans le contexte <a class="glossarylink" href="./glossary.html#http" title="voir glossaire">HTTP</a>, une action à
          effectuer sur une ressource spécifiée dans la ligne de requête
          par le client.  Parmi les méthodes disponibles dans HTTP, on trouve
          <code>GET</code>, <code>POST</code>,
          et <code>PUT</code>.
        </dd>
    
        <dt><a name="module" id="module">Module</a></dt>
        <dd>Une partie indépendante d'un programme.  De nombreuses fonctionnalités
        d'Apache sont fournies par des modules que vous pouvez choisir d'inclure
        ou d'exclure.  Les modules qui sont compilés dans le binaire
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> sont appelés <dfn>modules statiques</dfn>, alors
        que les modules qui existent séparément et peuvent être chargés
        optionnellement à l'exécution sont appelés
          <dfn>modules dynamiques</dfn> ou <a class="glossarylink" href="./glossary.html#dso" title="voir glossaire">DSOs</a>.
          Les modules qui sont inclus par défaut sont appelés
          <dfn>modules de base</dfn>. De nombreux modules disponibles pour Apache
          ne se trouvent pas dans l'<a class="glossarylink" href="./glossary.html#tarball" title="voir glossaire">archive</a>
          du Serveur HTTP Apache .  Il sont appelés
          <dfn>modules tiers</dfn>.<br />
          Voir : <a href="mod/">Index des modules</a>
        </dd>
    
    <dt><a name="passphrase" id="passphrase">Mot de Passe (Pass Phrase)</a></dt>
        <dd>Le mot ou la phrase qui protège les fichiers de clés privées.
        Il empêche les utilisateurs non autorisés de les déchiffrer. En général,
        il s'agit simplement de la clé secrète de chiffrement/déchiffrement
          utilisée pour les <a class="glossarylink" href="./glossary.html#cipher" title="voir glossaire">Algorithmes de chiffrement</a>.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="fully-qualifieddomain-name" id="fully-qualifieddomain-name">Nom de domaine entièrement qualifié
    	(Fully-Qualified Domain-Name)</a>
          <a name="fqdn" id="fqdn">(FQDN)</a></dt>
        <dd>Le nom unique d'une entité du réseau, comprenant un nom d'hôte et un
        nom de domaine qui peuvent être résolus en une adresse IP. Par exemple,
          <code>www</code> est un nom d'hôte, <code>example.com</code> est un nom
          de domaine, et <code>www.example.com</code> est un nom de domaine
          entièrement qualifié.
        </dd>
    
        <dt><a name="modulemagicnumber" id="modulemagicnumber">
        Nombre Magique des Modules
        (Module Magic Number)</a>
          (<a name="mmn" id="mmn">MMN</a>)</dt>
        <dd>Le Nombre Magique des Modules est une constante définie dans le code
        source d'Apache et associée à la compatibilité binaire des modules.
        Sa valeur est modifiée quand des structures internes d'Apache, des appels
        de fonctions et d'autres parties significatives de l'API sont modifiées
        de telle façon que la compatibilité binaire ne peut plus être garantie.
        En cas de changement de MMN, tous les modules tiers doivent être au
        moins recompilés, et parfois même légèrement modifiés afin de pouvoir
        fonctionner avec la nouvelle version d'Apache.
        </dd>
    
        <dt><a name="dynamicsharedobject" id="dynamicsharedobject">
        Objet Dynamique Partagé (Dynamic Shared Object)
    	</a> <a name="dso" id="dso">(DSO)</a></dt>
        <dd><a class="glossarylink" href="./glossary.html#module" title="voir glossaire">Modules</a> compilés en dehors du binaire
          Apache <code class="program"><a href="./programs/httpd.html">httpd</a></code> et qui peuvent être
          chargés à la demande.<br />
          Voir : <a href="dso.html">Support des objets dynamiques partagés</a>
        </dd>
    
    <dt><a name="openssl" id="openssl">OpenSSL</a></dt>
        <dd>L'ensemble d'outils Open Source pour SSL/TLS<br />
          Voir <a href="http://www.openssl.org/">http://www.openssl.org/</a>#
        </dd>
    
    <dt><a name="apacheextensiontool" id="apacheextensiontool">
        Outil de gestion des extensions Apache
        (APache eXtension Tool)</a>
        <a name="apxs" id="apxs">(apxs)</a></dt>
        <dd>Un script Perl qui aide à la compilation des sources de <a class="glossarylink" href="./glossary.html#module" title="voir glossaire">module</a> sous forme d'Objets Dynamiques Partagés
          (Dynamic Shared Objects ou
          <a class="glossarylink" href="./glossary.html#dso" title="voir glossaire">DSO</a>s) et facilite leur installation
          dans le serveur Web Apache.<br />
          Voir : Page de manuel : <code class="program"><a href="./programs/apxs.html">apxs</a></code>
        </dd>
    
    <dt><a name="plaintext" id="plaintext">Plein Texte (Plaintext)</a></dt>
        <dd>Le texte non chiffré.</dd>
    
    
    
        <dt><a name="hypertexttransferprotocol" id="hypertexttransferprotocol">Protocole de Transfert Hypertexte
          (HyperText Transfer Protocol)</a>
          <a name="http" id="hhtp">(HTTP)</a></dt>
        <dd>Le protocole de transmission standard utilisé sur le World Wide Web.
        Apache implémente la version 1.1 du protocole, référencée comme HTTP/1.1 et
          définie par la
          <a href="http://ietf.org/rfc/rfc2616.txt">RFC 2616</a>.
        </dd>
    
        <dt><a name="messagedigest" id="messagedigest">Résumé de message
        (Message Digest)</a></dt>
        <dd>Un hachage du message, qui peut être utilisé pour vérifier
        que son contenu n'a pas été altéré durant le transfert.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="transportlayersecurity" id="transportlayersecurity">
        Sécurité de la couche Transport
        (Transport Layer Security)
          </a> <a name="tls" id="tls">(TLS)</a></dt>
      <dd>Le protocole successeur de SSL, créé par l'Internet Engineering Task
        Force (IETF) pour l'authentification et le chiffrement généraux des
        communications dans les réseaux TCP/IP. TLS version 1 est pratiquement
        identique à SSL version 3.<br />
        Voir : <a href="ssl/">chiffrement SSL/TLS</a>
      </dd>
    
        <dt><a name="session" id="session">Session</a></dt>
      <dd>Les informations sur le contexte d'une communication en général.</dd>
    
        <dt><a name="digitalsignature" id="digitalsignature">Signature numérique
        (Digital Signature)</a></dt>
        <dd>Un bloc de texte crypté qui valide un certificat ou un autre fichier.
        Une <a class="glossarylink" href="./glossary.html#certificationauthority" title="voir glossaire">Autorité de certification</a>
          crée une signature en générant une empreinte de la <em>Clé publique</em>
          fournie avec le <em>Certificat</em>; la CA chiffre ensuite l'empreinte
          avec sa propre <em>Clé privée</em>. Seule la clé publique de la CA
          peut décrypter la signature, ce qui permet de vérifier que la CA a bien
          authentifié l'entité du réseau qui possède le
          <em>Certificat</em>.<br />
          Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
    <dt><a name="ssleay" id="ssleay">SSLeay</a></dt>
      <dd>La bibliothèque originelle d'implémentation de SSL/TLS développée par
      Eric A. Young
      </dd>
    
    <dt><a name="ciphertext" id="ciphertext">Texte crypté
    (Ciphertext)</a></dt>
        <dd>Le résultat du passage d'un document
        <a class="glossarylink" href="./glossary.html#plaintext" title="voir glossaire">Plaintext</a> (Plein texte) par un
        <a class="glossarylink" href="./glossary.html#cipher" title="voir glossaire">Cipher</a>.<br />
        Voir : <a href="ssl/">chiffrement SSL/TLS</a>
        </dd>
    
        <dt><a name="mime-type" id="mime-type">Type MIME (MIME-type)</a></dt>
        <dd>Une méthode pour décrire le type de document transmis.  Son nom
        vient du fait que son format est issu des Multipurpose
          Internet Mail Extensions (Extensions Multi-usages de la
          Messagerie par Internet) .  Il comprend un type majeur et un type
          mineur, séparés par un slash (barre oblique).  On trouve
          entre autres types <code>text/html</code>,
          <code>image/gif</code>, et <code>application/octet-stream</code>. Dans
          HTTP, le type MIME est transmis dans l'
          <a class="glossarylink" href="./glossary.html#header" title="voir glossaire">en-tête</a> <code>Content-Type</code>.<br />
          Voir : <a href="mod/mod_mime.html">mod_mime</a>
        </dd>
    
    
        <dt><a name="environmentvariable" id="environmentvariable">
        Variable d'environnement
        (Environment Variable)</a> <a name="env-variable" id="env-variable">(env-variable)</a></dt>
        <dd>Ce sont des variables nommées gérées par le shell du système
        d'exploitation, et servant au stockage d'informations et à la
        communication entre les programmes. Apache possède aussi des variables
        internes considérées comme variables d'environnement, mais stockées dans
        des structures internes à Apache, et non dans l'environnement
        du shell.<br />
          Voir : <a href="env.html">Les variables d'environnement dans Apache</a>
        </dd>
    
         <dt><a name="x.509" id="x.509">X.509</a></dt>
      <dd>Une norme de certificat d'authentification recommandée par l'International
        Telecommunication Union (ITU-T) et utilisée pour
        l'authentification SSL/TLS.<br /> Voir : <a href="ssl/">chiffrement SSL/TLS</a>
      </dd>
    </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/glossary.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html.fr.utf8������������������������������������������������������0000664�0001751�0001751�00000032653�14740503670�021053� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Démarrage d'Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Démarrage d'Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Sous Windows, Apache est habituellement lancé en tant que
        service. Pour plus de détails, voir <a href="platform/windows.html#winsvc">Démarrer Apache en tant
        que service</a>.</p>
    
        <p>Sous Unix, le programme <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        est lancé en mode démon et s'exécute de manière permanente en
        arrière-plan pour gérer les requêtes.  Ce document décrit comment invoquer
         <code class="program"><a href="./programs/httpd.html">httpd</a></code>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#startup">Comment Apache démarre</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errors">Erreurs en cours de démarrage</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#boot">Lancement au démarrage du système</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#info">Informations supplémentaires</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="stopping.html">Arrêt et redémarrage</a></li><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="startup" id="startup">Comment Apache démarre</a></h2>
    
        <p>Si la directive <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        spécifiée dans le fichier de configuration est à sa valeur par défaut
        de 80 (ou tout autre port inférieur à 1024), il est nécessaire de
        posséder les privilèges root pour pouvoir démarrer apache, et lui
        permettre d'être associé à ce port privilégié. Lorsque le serveur est
        démarré, il effectue quelques opérations préliminaires
        comme ouvrir ses fichiers de log, puis il lance plusieurs processus
        <em>enfants</em> qui ont pour rôle d'écouter et de répondre aux
        requêtes des clients. Le processus <code>httpd</code> principal
        continue à s'exécuter sous l'utilisateur root, tandis que les processus
        enfants s'exécutent sous un utilisateur aux privilèges restreints.
        Ceci s'effectue par la voie du
        <a href="mpm.html">Module Multi-Processus (MPM)</a>.</p>
    
        <p>Il est recommandé d'utiliser le script de contrôle
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> pour invoquer l'exécutable
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>. A cet effet, ce script définit certaines variables
        d'environnement nécessaires pour permettre à
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> de fonctionner correctement sous certains systèmes
        d'exploitation.
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> accepte des arguments de ligne de
        commande ;
        ainsi toute option de <code class="program"><a href="./programs/httpd.html">httpd</a></code> peut aussi être utilisée avec
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>.  Vous pouvez aussi éditer directement le
        script <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> en modifiant la variable
        <code>HTTPD</code> située en début de script pour spécifier la
        localisation du binaire <code class="program"><a href="./programs/httpd.html">httpd</a></code> et tout argument de ligne
        de commande que vous souhaitez voir <em>systématiquement</em> présent.</p>
    
        <p>La première chose qu'effectue <code class="program"><a href="./programs/httpd.html">httpd</a></code> quand il est
        invoqué est de localiser et lire le <a href="configuring.html">fichier de configuration</a>
        <code>httpd.conf</code>. La localisation de ce fichier est définie à la
        compilation, mais il est possible d'en spécifier une autre à
        l'exécution en utilisant l'option de ligne de commande <code>-f</code> comme suit:</p>
    
    <div class="example"><p><code>/usr/local/apache2/bin/apachectl -f
          /usr/local/apache2/conf/httpd.conf</code></p></div>
    
        <p>Si tout se passe bien pendant le démarrage, le serveur va se dissocier
        du terminal et l'invite de commande réapparaîtra presque immédiatement.
        Ceci indique que le serveur a démarré et est en cours d'exécution.
        À partir de ce moment, vous pouvez utiliser votre navigateur pour vous connecter
        au serveur et afficher la page de test située dans le répertoire défini
        par la directive <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errors" id="errors">Erreurs en cours de démarrage</a></h2>
    
        <p>Si un problème fatal survient pendant le démarrage
        d'Apache, ce dernier va
        afficher un message décrivant le problème sur la console ou
        enregistrer ces informations dans le fichier défini par la directive
        <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> avant de quitter.
        Un des messages d'erreur les plus courants est "<code>Unable
        to bind to Port ...</code>". Ce message d'erreur est habituellement
        provoqué par :</p>
    
        <ul>
          <li>Une tentative de démarrage du serveur avec un port privilégié sans
          être connecté root</li>
    
          <li>Une tentative de démarrage du serveur alors qu'une autre instance
          d'Apache ou un autre serveur web est déjà associé au même port.</li>
        </ul>
    
        <p>Pour plus d'instructions de dépannage, consultez la
        <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> Apache.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="boot" id="boot">Lancement au démarrage du système</a></h2>
    
        <p>Si vous souhaitez que votre serveur web soit automatiquement
        disponible après
        un redémarrage du système, vous devez ajouter un appel à
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> à vos
        fichiers de démarrage système (en général <code>rc.local</code> ou un
        fichier dans un répertoire <code>rc.N</code>), ce qui démarrera Apache sous
        l'utilisateur root. Avant de faire ceci, assurez-vous que votre serveur
        soit correctement configuré en ce qui concerne la sécurité et les
        restrictions d'accès.</p>
    
        <p>Le script <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> est conçu pour fonctionner
        comme un script d'initialisation SysV standard ; il accepte les arguments
        <code>start</code>, <code>restart</code>, et <code>stop</code>
        et les traduit en signaux appropriés pour
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>, et il suffit en général d'installer
        un lien vers
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> dans le répertoire d'initialisation approprié.
        Mais prenez soin de vérifier les besoins exacts de votre système
        en la matière.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="info" id="info">Informations supplémentaires</a></h2>
    
        <p>Des informations supplémentaires à propos des options en ligne de
        commande de <code class="program"><a href="./programs/httpd.html">httpd</a></code> et <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>
        ainsi que d'autres programmes support inclus dans la distribution
        sont disponibles sur la page
        <a href="programs/">Le serveur et ses programmes support</a>.
        Il existe aussi une documentation sur tous les <a href="mod/">modules</a> inclus dans la distribution Apache
        et les <a href="mod/directives.html">directives</a>
        qu'ils supportent.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/invoking.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/install.html.fr.utf8�������������������������������������������������������0000664�0001751�0001751�00000072653�14740503670�020701� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Compilation et installation - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Compilation et installation</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Ce document couvre l'installation et la compilation du serveur
        HTTP Apache
        sur les systèmes Unix et similaires seulement. Pour la compilation et
        l'installation sous Windows, voir <a href="platform/windows.html">Utiliser le serveur HTTP Apache avec Microsoft
        Windows</a> et <a href="platform/win_compiling.html">Compilation
        d'Apache sous Microsoft Windows</a>. Pour les autres plateformes, se
        référer à la documentation par
         <a href="platform/">plateforme</a>.</p>
    
        <p>Apache httpd utilise <code>libtool</code> et <code>autoconf</code>
        afin de créer un environnement de construction similaire à la plupart
        des projets Open Source .</p>
    
        <p>Si vous effectuez une mise à jour depuis une version mineure vers
        la suivante (par exemple, 2.4.8 à 2.4.9), veuillez passer à la section
        <a href="#upgrading">mise à jour</a>.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Aperçu pour les plus pressés</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#requirements">Prérequis</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#download">Téléchargement</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extract">Extraction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configure">Configuration de l'arborescence des sources</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compile">Construction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">Installation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#customize">Personnalisation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#test">Test</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#upgrading">Mise à jour</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#thirdp">Paquets tiers</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="programs/configure.html">Configuration de l'arborescence
    	des sources</a></li><li><a href="invoking.html">Démarrer Apache httpd</a></li><li><a href="stopping.html">Arrêt et redémarrage</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Aperçu pour les plus pressés</a></h2>
    
        <dl>
        <dt>Installation sous Fedora/CentOS/Red Hat Enterprise Linux</dt>
        <dd>
        <pre class="prettyprint lang-">sudo yum install httpd
    sudo service httpd start</pre>
    
    
        <div class="warning">Les dernières versions de ces distributions préfèrent
        <code>dnf</code> à <code>yum</code>. Voir la <a href="https://fedoraproject.org/wiki/Apache_HTTP_Server">documentation du
        projet Fedora</a> pour des informations spécifiques à cette plateforme.</div>
        </dd>
    
        <dt>Installation sous Ubuntu/Debian</dt>
        <dd>
    <pre class="prettyprint lang-">sudo apt install apache2
    sudo service apache2 start</pre>
    
    
        <div class="warning">Voir la <a href="https://help.ubuntu.com/lts/serverguide/httpd.html">documentation
        Ubuntu</a> pour des informations spécifiques à cette plateforme.</div>
    
        </dd>
    
        <dt>Installation à partir des sources</dt>
        <dd>
    
        <table>
          
          <tr>
            <td><a href="#download">Téléchargement</a></td>
    
            <td>Téléchargez la dernière version depuis <a href="http://httpd.apache.org/download.cgi#apache24">http://httpd.apache.org/download.cgi</a>
            </td>
          </tr>
    
          <tr>
            <td><a href="#extract">Extraction</a></td>
    
            <td><code>$ gzip -d httpd-<em>NN</em>.tar.gz<br />
             $ tar xvf httpd-<em>NN</em>.tar<br />
             $ cd httpd-<em>NN</em></code></td>
          </tr>
    
          <tr>
            <td><a href="#configure">Configuration</a></td>
    
            <td><code>$ ./configure --prefix=<em>PREFIX</em></code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#compile">Compilation</a></td>
    
            <td><code>$ make</code> </td>
          </tr>
    
          <tr>
            <td><a href="#install">Installation</a></td>
    
            <td><code>$ make install</code> </td>
          </tr>
    
          <tr>
            <td><a href="#customize">Personnalisation</a></td>
    
            <td><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code> </td>
          </tr>
    
          <tr>
            <td><a href="#test">Test</a></td>
    
            <td><code>$ <em>PREFIX</em>/bin/apachectl -k start</code>
            </td>
          </tr>
        </table>
    
        <p><em>NN</em> doit être remplacé par le numéro de version courant,
        et <em>PREFIX</em> par le
        chemin du répertoire d'installation. Si
        <em>PREFIX</em> n'est pas spécifié, le chemin du répertoire
        d'installation prendra sa valeur par défaut, à savoir
        <code>/usr/local/apache2</code>.</p>
    
        <p>Chaque étape du processus de compilation et d'installation est
        décrite plus en détails ci-dessous, à commencer par les prérequis
        pour compiler et installer Apache httpd.</p>
    
        </dd>
        </dl>
    
        <div class="warning">L'installation sous votre plateforme favorite n'est pas
        traitée ici ? N'hésitez pas à nous <a href="http://httpd.apache.org/docs-project/">aider à compléter cette
        documentation</a> en nous faisant profiter de votre expérience.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">Prérequis</a></h2>
    
        <p>Les prérequis pour la construction d'Apache httpd sont les suivants:</p>
    
        <dl>
          <dt>APR et APR-Util</dt>
          <dd>APR et APR-Util doivent être déjà installés sur votre système.
          Si ce n'est pas le cas, ou si vous préférez ne pas utiliser les
          versions fournies par le système, téléchargez les dernières
          versions d'APR et APR-Util depuis <a href="http://apr.apache.org/">Apache APR</a>, décompressez-les
          respectivement dans <code>/racine_sources_httpd/srclib/apr</code> et
          <code>/racine_sources_httpd/srclib/apr-util</code> (les noms des répertoires ne
          doivent pas comporter de numéros de versions ; par exemple, la
          distribution d'APR doit se trouver dans /racine_sources_httpd/srclib/apr/), et
          utilisez l'option <code>--with-included-apr</code> du script
          <code>./configure</code>. Sur certaines plateformes, vous devrez
          peut-être installer les paquets <code>-dev</code> correspondants
          pour permettre la compilation de httpd avec les versions
          installées d'APR et APR-Util.</dd>
    
          <dt>Bibliothèque d'expressions rationnelles compatibles Perl
          (PCRE)</dt>
          <dd>Cette bibliothèque est nécessaire mais n'est plus fournie avec la
          distribution de httpd. Téléchargez le code source depuis <a href="http://www.pcre.org/">http://www.pcre.org</a> ou installez
          un portage du paquet. Si votre suite de compilation ne trouve pas
          le script pcre-config installé au cours du processus de
          construction de PCRE, indiquez son chemin via l'option
          <code>--with-pcre</code> du script <code>./configure</code>. Sur
          certaines plateformes, vous devrez
          peut-être installer les paquets <code>-dev</code> correspondants
          pour permettre la compilation de httpd avec la version
          installée de PCRE.</dd>
    
          <dt>Espace disque</dt>
          <dd>Assurez-vous d'avoir au moins 50 Mo d'espace disque disponible
          temporaire. Après l'installation le serveur occupe
          approximativement 10 Mo d'espace disque. L'espace disque réellement
          nécessaire va varier considérablement en fonction de vos options
          de configuration, de la présence éventuelle de
          modules tiers, et bien entendu de la taille de votre site web et
          des sites que vous hébergez sur votre serveur.</dd>
    
          <dt>Compilateur ANSI-C et système de construction</dt>
          <dd>Vous devez disposer d'un compilateur ANSI-C. Le compilateur <a href="http://gcc.gnu.org/">GNU C (GCC)</a> de la <a href="http://www.gnu.org/">Free Software Foundation (FSF)</a>
          est recommandé. Si vous ne possédez pas GCC,
          assurez-vous au moins que votre compilateur soit compatible ANSI.
          En outre, votre <code>PATH</code> doit contenir
          les outils de construction de base tels que <code>make</code>.</dd>
    
          <dt>Connaissance de l'heure exacte</dt>
          <dd>Les éléments du protocole HTTP font référence à l'heure du jour.
          Par conséquent, il est nécessaire d'équiper votre système d'un
          dispositif de synchronisation du temps. Les programmes
          <code>ntpdate</code> ou <code>xntpd</code>, basés sur le protocole NTP,
          sont couramment utilisés à cet effet.
          Voir la <a href="http://www.ntp.org">page d'accueil de NTP</a>
          pour plus de détails à propos du logiciel NTP et des serveurs
          de temps publics.</dd>
    
          <dt><a href="http://www.perl.org/">Perl 5</a>
          [OPTIONNEL]</dt>
          <dd>L'interpréteur Perl 5 (les versions 5.003 ou supérieures conviennent)
          est nécessaire pour l'exécution de certains scripts comme
          <code class="program"><a href="./programs/apxs.html">apxs</a></code> ou <code class="program"><a href="./programs/dbmmanage.html">dbmmanage</a></code>
          (qui sont écrits en Perl).
          Si le script <code class="program"><a href="./programs/configure.html">configure</a></code> ne trouve pas d'interpréteur
          Perl 5, vous ne pourrez pas utiliser les scripts qui en ont besoin.
          Bien entendu, vous pourrez tout de même construire et utiliser
          Apache httpd.</dd>
    
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="download" id="download">Téléchargement</a></h2>
    
        <p>Le serveur HTTP Apache peut être téléchargé à partir du
        <a href="http://httpd.apache.org/download.cgi">site de téléchargement
        du serveur HTTP Apache</a>, qui fournit la liste de nombreux miroirs.
        Il sera plus commode à la plupart des utilisateurs d'Apache sur les
        systèmes UNIX ou similaires de télécharger et de compiler
        la version sources.  Le processus de construction (décrit ci-dessous) est
        simple, et vous permet de personnaliser votre serveur selon vos besoins.
        En outre, les versions binaires sont souvent plus anciennes que les
        dernières versions sources. Si vous téléchargez une version binaire,
        suivez les instructions décrites dans le fichier
        <code>INSTALL.bindist</code> inclus dans la distribution.</p>
    
        <p>Après le téléchargement, il est important de vérifier que vous
        disposez d'une version complète et non modifiée du serveur HTTP Apache.
        Vous pouvez le faire en testant l'archive téléchargée à l'aide de
        la signature PGP. Vous trouverez les détails de cette opération sur la <a href="http://httpd.apache.org/download.cgi#verify">page de téléchargement</a> ainsi qu'un exemple précis décrivant <a href="http://httpd.apache.org/dev/verification.html">l'utilisation de
        PGP</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extract" id="extract">Extraction</a></h2>
    
        <p>L'extraction des sources depuis l'archive du serveur HTTP Apache consiste
        simplement à décompresser et à désarchiver cette dernière :</p>
    
    <div class="example"><p><code>
    $ gzip -d httpd-<em>NN</em>.tar.gz<br />
    $ tar xvf httpd-<em>NN</em>.tar
    </code></p></div>
    
        <p>Ceci créera, dans le répertoire courant, un nouveau répertoire
        contenant le code source de la distribution. Vous devrez vous positionner
        dans ce répertoire avant de procéder à la compilation du serveur.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">Configuration de l'arborescence des sources</a></h2>
    
        <p>L'étape suivante consiste à configurer l'arborescence des sources
        d'Apache en fonction de votre plateforme et de vos besoins personnels.
        Le script  <code class="program"><a href="./programs/configure.html">configure</a></code>, situé à la racine du
        répertoire de la distribution, a été conçu à cet effet
        (Les développeurs qui téléchargent
        une version non officielle de l'arborescence des sources d'Apache
        devront disposer de
        <code>autoconf</code> et <code>libtool</code> et
        exécuter <code>buildconf</code> avant de passer à l'étape suivante,
        ce qui n'est pas nécessaire pour les versions officielles).</p>
    
        <p>Pour configurer l'arborescence des sources avec les valeurs par défaut
        pour toutes les options, entrez simplement <code>./configure</code>.
        Pour modifier les valeurs des options, <code class="program"><a href="./programs/configure.html">configure</a></code>
        accepte toute une variété de variables et
        d'options de ligne de commande.</p>
    
        <p>L'option la plus importante <code>--prefix</code> est le chemin
        du répertoire d'installation d'Apache, car Apache doit être configuré
        en fonction de ce chemin pour pouvoir fonctionner correctement.
        Il est possible de définir plus finement le chemin d'installation des fichiers
        à l'aide d'<a href="programs/configure.html#installationdirectories">options
        supplémentaires de configure</a>.</p>
    
        <p>À ce niveau, vous pouvez aussi spécifier de quelles <a href="programs/configure.html#optionalfeatures">fonctionnalités</a> vous
        voulez disposer dans Apache en activant ou désactivant des <a href="mod/">modules</a>.  Apache est fourni avec un grand nombre de
        modules inclus par défaut. Ils seront compilés en tant qu'<a href="dso.html">objets partagés (DSOs)</a> qui pourront être chargés
        ou déchargés à l'exécution. Vous pouvez aussi choisir de compiler
        les modules statiquement via l'option
        <code>--enable-<var>module</var>=static</code>.</p>
        <p>Des modules supplémentaires peuvent être activés à l'aide de l'option
        <code>--enable-<var>module</var></code>, où
        <var>module</var> est le nom du module sans la chaîne
        <code>mod_</code> et où tout caractère de soulignement est converti
        en tiret. D'une manière similaire,
        vous pouvez désactiver des modules à l'aide de l'option
        <code>--disable-<var>module</var></code>.  Faites très attention
        en utilisant ces options, car <code class="program"><a href="./programs/configure.html">configure</a></code> n'est pas en
        mesure de vous avertir si le module que vous avez spécifié n'existe pas;
        il ignorera tout simplement l'option.</p>
    
        <p>En outre, vous devrez peut-être fournir au script
        <code class="program"><a href="./programs/configure.html">configure</a></code> des informations supplémentaires sur
        le chemin de votre compilateur, de vos bibliothèques, ou de vos fichiers
        d'en-têtes.  A cet effet, vous pouvez passer des options de ligne de
        commande ou des variables d'environnement au script
        <code class="program"><a href="./programs/configure.html">configure</a></code>. Pour plus d'informations, voir la
        page de manuel de <code class="program"><a href="./programs/configure.html">configure</a></code>, ou lancez le script
        <code class="program"><a href="./programs/configure.html">configure</a></code> avec l'option <code>--help</code>.
        </p>
    
        <p>Pour vous faire une idée des possibilités qui s'offrent à vous, voici
        un exemple typique de compilation d'Apache avec le répertoire
        d'installation <code>/sw/pkg/apache</code>, un compilateur et des drapeaux
        particuliers et les deux modules additionnels <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>
        et <code class="module"><a href="./mod/mod_lua.html">mod_lua</a></code> :</p>
    
    <div class="example"><p><code>
          $ CC="pgcc" CFLAGS="-O2" \<br />
           ./configure --prefix=/sw/pkg/apache \<br />
           --enable-ldap=shared \<br />
           --enable-lua=shared
    </code></p></div>
    
        <p>Plusieurs minutes peuvent être nécessaires à
        <code class="program"><a href="./programs/configure.html">configure</a></code> pour tester la disponibilité des
        fonctionnalités
        au sein de votre système, et construire les Makefiles qui seront utilisés
        par la suite pour compiler le serveur.</p>
    
        <p>Vous trouverez une description détaillée des options de
        <code class="program"><a href="./programs/configure.html">configure</a></code> dans sa page de manuel.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile" id="compile">Construction</a></h2>
    
        <p>Vous pouvez maintenant construire les différents éléments qui
        composent le paquet Apache en lançant tout simplement la commande :</p>
    
    <div class="example"><p><code>$ make</code></p></div>
    
        <p>Vous devez être patient, car il faut plusieurs minutes pour compiler
        une configuration de base, et cette durée peut varier considérablement
        en fonction de votre matériel et du nombre de modules que vous avez activés.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">Installation</a></h2>
    
        <p>Il est temps maintenant d'installer le paquet dans le répertoire
        d'installation défini par <em>PREFIX</em> (voir plus haut l'option
        <code>--prefix</code>) en lançant:</p>
    
    <div class="example"><p><code>$ make install</code></p></div>
    
        <p>Cette étape nécessite habituellement les privilèges
        de root, car <em>PREFIX</em> est en général un
        répertoire possèdant des droits en écriture
        restreints.</p>
    
        <p>Si vous effectuez une mise à jour, l'installation n'écrasera pas
        vos fichiers de configuration ou autres documents.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customize" id="customize">Personnalisation</a></h2>
    
        <p>Ensuite, vous pourrez personnaliser votre Serveur HTTP Apache en
        éditant les <a href="configuring.html">fichiers de configuration</a>
        situés dans <code><em>PREFIX</em>/conf/</code>.</p>
    
    <div class="example"><p><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code></p></div>
    
        <p>Consultez le manuel d'Apache situé dans
        <code><em>PREFIX</em>/docs/manual/</code> ou
        <a href="http://httpd.apache.org/docs/2.4/">http://httpd.apache.org/docs/2.4/</a> pour la version la plus
        récente de ce manuel et la liste complète des <a href="mod/directives.html">directives de configuration</a> disponibles.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="test" id="test">Test</a></h2>
    
        <p>Vous pouvez maintenant <a href="invoking.html">démarrer</a> votre
        serveur HTTP Apache en lançant:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k start</code></p></div>
    
        <p>Vous devriez alors pouvoir requérir votre premier document
        à l'aide de l'URL <code>http://localhost/</code>. La page web que vous
        voyez est située dans le répertoire défini par la directive
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>,
        qui est généralement <code><em>PREFIX</em>/htdocs/</code>.
        Pour <a href="stopping.html">arrêter</a> le serveur, lancez:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k stop</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">Mise à jour</a></h2>
    
        <p>La première étape d'une mise à jour consiste à lire l'annonce de la
        sortie de la nouvelle version et le fichier <code>CHANGES</code>
        dans la distribution des sources afin de déceler toutes les modifications
        qui pourraient affecter votre site. Lors d'un changement majeur de version
        (par exemple de 2.0 à 2.2 ou de 2.2 à 2.4),
        il y aura certainement des différences importantes quant à la
        configuration de la compilation et de l'exécution qui nécessiteront des
        ajustements manuels.  Tous les
        modules devront aussi être mis à jour pour qu'ils s'adaptent aux
        changements de l'API des modules.</p>
    
        <p>La mise à jour d'une version mineure à la suivante (par exemple, de
        2.2.55 à 2.2.57) est plus aisée.  Le processus <code>make install</code>
        n'écrasera aucun de vos documents existants, fichiers de log,
        ou fichiers de configuration.  De plus, les développeurs font tout
        leur possible pour éviter les changements entraînant une
        incompatibilité dans les options de
        <code class="program"><a href="./programs/configure.html">configure</a></code>, la configuration de l'exécution, ou l'API
        des modules d'une version mineure à l'autre.  Dans la plupart des cas,
        vous pourrez utiliser une ligne de commande
        <code class="program"><a href="./programs/configure.html">configure</a></code> identique, le même fichier de configuration,
        et tous vos modules continueront de fonctionner.</p>
    
        <p>Pour effectuer une mise à jour entre deux versions mineures,
        commencez par trouver le fichier
        <code>config.nice</code> dans le répertoire de <code>construction</code>
        de votre serveur installé ou à la racine de l'arborescence des sources
        de votre ancienne installation.  Il contient la reproduction exacte de la
        ligne de commande <code class="program"><a href="./programs/configure.html">configure</a></code> que vous avez utilisée pour
        configurer l'arborescence des sources.  Ensuite, pour mettre à jour
        l'ancienne version vers la nouvelle,
        il vous suffit de copier le fichier <code>config.nice</code> dans
        l'arborescence des sources de la nouvelle version, de l'éditer pour
        effectuer toute modification souhaitée, et de lancer :</p>
    
        <div class="example"><p><code>
        $ ./config.nice<br />
        $ make<br />
        $ make install<br />
        $ <em>PREFIX</em>/bin/apachectl -k graceful-stop<br />
        $ <em>PREFIX</em>/bin/apachectl -k start<br />
        </code></p></div>
    
        <div class="warning">Vous devez toujours effectuer un test de la nouvelle
        version dans votre environnement avant de la mettre en production.
        Par exemple, vous pouvez installer et exécuter la nouvelle version
        en parallèle avec l'ancienne en utilisant une option
        <code>--prefix</code> et un port différents (en ajustant la directive
        <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>) afin de déceler toute
        incompatibilité avant d'effectuer la mise à jour définitive.</div>
    
        <p>Vous pouvez ajouter des arguments supplémentaires à
        <code>config.nice</code> ; ils seront alors ajoutés aux options de
        votre script <code class="program"><a href="./programs/configure.html">configure</a></code> original :</p>
    
         <div class="example"><p><code>
         $ ./config.nice --prefix=/home/test/apache --with-port=90
         </code></p></div>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="thirdp" id="thirdp">Paquets tiers</a></h2>
    
        <p>De nombreux tiers fournissent leur propre distribution du
        serveur HTTP Apache à installer sur une plate-forme particulière. On
        peut citer les différentes distributions Linux, divers
        paquets tiers Windows, Mac OS X, Solaris et de nombreux autres.</p>
    
        <p>Notre license logicielle non seulement permet, mais aussi
        encourage ce genre de redistribution. Cependant, ceci conduit à une
        situation ou l'organisation de la configuration et les valeurs par
        défaut de votre installation du serveur peuvent ne pas correspondre
        à ce qui est écrit dans la documentation. Bien que fâcheuse, cette
        situation n'est pas appelée à évoluer de sitôt.</p>
    
        <p>Une  <a href="http://wiki.apache.org/httpd/DistrosDefaultLayout">description
        de ces distributions tierces</a> est maintenue dans le wiki du
        serveur HTTP, et doit en refléter l'état actuel. Vous devrez
        cependant vous familiariser par vous-même avec la gestion du paquet
        de votre plate-forme particulière et les procédures d'installation.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/install.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html.fr.utf8����������������������������������������������0000664�0001751�0001751�00000044427�14740503670�022360� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Vue d'ensemble des nouvelles fonctionnalités de la
        version 2.0 du serveur HTTP Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Vue d'ensemble des nouvelles fonctionnalités de la
        version 2.0 du serveur HTTP Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
            <p>Ce document décrit les changements majeurs apportés entre les 
            versions 1.3 et 2.0 du serveur HTTP Apache.</p>
        </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Améliorations du Système de Base</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Amélioration des Modules</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="upgrading.html">Migrer à 2.0 depuis la version 1.3</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Améliorations du Système de Base</a></h2>
            
    
            <dl>
                <dt>Threading Unix</dt>
    
                <dd>Sur les systèmes Unix qui supportent les threads
    	    POSIX, Apache httpd
                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.</dd>
    
                <dt>Nouveau Système de Compilation</dt>
    
                <dd>Le processus de compilation a été refait de A à Z; 
                il utilise à présent <code>autoconf</code> et <code>libtool</code>, 
                ce qui rend la compilation d'Apache httpd plus familière aux utilisateurs 
                d'autre logiciels de mème type.</dd>
    
                <dt>Support Multiprotocole</dt>
    
                <dd>Le serveur HTTP Apache dispose désormais de
    	    l'infrastructure nécessaire pour supporter
                d'autres protocoles. Le module <code class="module"><a href="./mod/mod_echo.html">mod_echo</a></code> illustre ces 
                possibilités.</dd>
    
                <dt>Support amélioré des Plate-formes non-Unix</dt>
            
                <dd>Le serveur HTTP 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 
                <a href="mpm.html">Modules Multi-Processus</a> (MPMs), ainsi que de 
                la bibliothèque "Apache Portable Runtime" (APR) permet à 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.</dd>
    
                <dt>Nouvelle API d'Apache httpd</dt>
    
                <dd>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 HTTP Apache.</dd>
    
                <dt>Support IPv6</dt>
    
                <dd>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 <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>, 
                <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code> et 
                <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> supportent également 
                les adresses IPv6 (comme par exemple, dans "<code>Listen[2001:db8::1]:8080</code>").</dd>
    
                <dt>Filtering</dt>
    
                <dd>Il est maintenant possible d'écrire des modules
    	    pour Apache  httpd 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 <code>INCLUDES</code> fourni
                par le module <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>. Le module
                <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> 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.</dd>
    
                <dt>Réponses d'Erreurs Multilangues</dt>
    
                <dd>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.</dd>
    
                <dt>Simplification de la Configuration</dt>
    
                <dd>Beaucoup de directives, auparavant peu claires, ont été simplifiées.
                Les directives <code>Port</code> et <code>BindAddress</code>, souvent
                sources d'incompréhension, ont disparus. Désormais seule la directive 
                <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> sert de liaison pour les 
                adresses IP; la directive <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> ne 
                précise le nom du serveur et son port que pour les redirections et la
                gestion des hôtes virtuels.</dd>
    
                <dt>Support natif de l'Unicode sous Windows NT</dt>
    
                <dd>Apache httpd 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.<em>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.</em></dd>
    
                <dt>Mise à jour de la Bibliothèque d'Expressions Rationnelles</dt>
    
                <dd>Apache httpd 2.0 contient la <a href="http://www.pcre.org/">bibliothèque 
                d'expressions rationnelles compatible Perl </a>(Perl Compatible Regular 
                Expression Library - PCRE). Toutes les expressions rationnelles sont dont
                gérées avec la syntaxe de Perl 5, plus puissante.</dd>
    
            </dl>
        </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Amélioration des Modules</a></h2>
            
    
            <dl>
                <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
                <dd>Apparu dans Apache httpd 2.0, ce module est une interface aux protocoles de 
                chiffrement SSL/TLS fournis par OpenSSL.</dd>
    
                <dt><code class="module"><a href="./mod/mod_dav.html">mod_dav</a></code></dt>
    
                <dd>Apparu dans Apache httpd 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.</dd>
    
                <dt><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></dt>
    
                <dd>Module apparu dans Apache httpd 2.0, mod_deflate permet aux navigateurs qui 
                le supportent de demander la compression des contenus envoyés par le serveur. 
                Cela a l'avantage de réduite l'occupation de la bande passante.</dd>
    
                <dt><code class="module">mod_auth_ldap</code></dt>
    
                <dd>Apparu dans Apache httpd 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,
                <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>, permet de globaliser les connexions à l'arbre LDAP
                et de garder en mémoire cache ces accès.</dd>
        
                <dt><code class="module"><a href="./mod/mod_auth_digest.html">mod_auth_digest</a></code></dt>
    
                <dd>Améliore les fonctions de cache sur une session entre les différents
                processus, en utilisant de la mémoire partagée.</dd>
    
                <dt><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></dt>
    
                <dd>Apparu dans Apache httpd 2.0, ce module expérimental permet la conversion 
                et l'enregistrement entre jeux de caractères.</dd>
    
                <dt><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></dt>
    
                <dd>Apparu dans Apache httpd 2.0, ce module implémente les fonctionnalités du 
                module <code>mod_mmap_static</code> présent du serveur
    	    HTTP Apache 1.3, et offre des 
                fonctions plus avancées pour la gestion du cache.</dd>
    
                <dt><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></dt>
    
                <dd>Ce module gagne beaucoup de flexibilité avec Apache
    	    httpd 2.0 : on peut 
                désormais l'utiliser pour modifier les en-têtes des requêtes 
                utilisés par <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>, et pour positionner les 
                en-têtes des réponses de manière conditionnelle.</dd>
    
                <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
                <dd>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 à 
                <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> 
                donnent un contrôle plus lisible et un traitement plus rapide des requêtes 
                mandatées ; les configurations surchargées <code>&lt;Directory 
                "proxy:..."&gt;</code> ne sont pas supportées. Le module a aussi été 
                fragmenté en plusieurs modules qui gèrent chacun leur protocole : 
                <code>proxy_connect</code>, <code>proxy_ftp</code> et 
                <code>proxy_http</code>.</dd>
    
                <dt><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></dt>
    
                <dd>Une nouvelle directive, <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code> 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 gérer le contenu de documents a 
                aussi été ajouté.</dd>
        
                <dt><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></dt>
    
                <dd>Les listes auto-générées 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.</dd>
    
                <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
    
                <dd>De nouvelles directives permettent de modifier la valeur par défaut 
                des drapeaux <em>start</em> et <em>end</em> 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ées au moyen des variables <code>$0</code> à <code>$9</code>.</dd>
    
                <dt><code class="module">mod_auth_dbm</code></dt>
    
                <dd>Plusieurs bases de données DBM sont supportées, et sélectionnables 
                via la directive <code class="directive">AuthDBMType</code>.</dd>
            </dl>
        </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_0.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/stopping.html.es�����������������������������������������������������������0000664�0001751�0001751�00000046513�14743132254�020204� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"><head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Iniciar y Parar el servidor Apache - Servidor HTTP Apache Versi&#243;n 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p>
    <p class="apache">Versi&#243;n 2.4 del Servidor HTTP Apache</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Servidor HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentaci&#243;n</a> &gt; <a href="./">Versi&#243;n 2.4</a></div><div id="page-content"><div id="preamble"><h1>Iniciar y Parar el servidor Apache</h1>
    <div class="toplang">
    <p><span>Idiomas disponibles: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">Esta traducci&#243;n podr&#237;a estar
                obsoleta. Consulte la versi&#243;n en ingl&#233;s de la
                documentaci&#243;n para comprobar si se han producido cambios
                recientemente.</div>
    
        <p>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&#243;n <a href="platform/windows.html#winsvc">Ejecutar Apache como un
         servicio</a> y los usuario de Windows 9x y ME deben consultar <a href="platform/windows.html#wincons">Ejecutar Apache como una
         Aplicaci&#243;n de Consola</a> para obtener informaci&#243;n
         sobre como controlar Apache en esas plataformas.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Introducci&#243;n</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#term">Parar Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#graceful">Reinicio Graceful</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#hup">Reiniciar Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#race">Ap&#233;ndice: se&#241;ales y race conditions</a></li>
    </ul><h3>Consulte tambi&#233;n</h3><ul class="seealso"><li><a href="programs/httpd.html">httpd</a></li><li><a href="programs/apachectl.html">apachectl</a></li><li><a href="#comments_section">Comentarios</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introducci&#243;n</a></h2>
    
        <p>Para parar y reiniciar Apache, hay que enviar la se&#241;al
        apropiada al proceso padre <code>httpd</code> que se est&#233;
        ejecutando.  Hay dos maneras de enviar estas se&#241;ales.  En
        primer lugar, puede usar el comando de Unix <code>kill</code> que
        env&#237;a se&#241;ales directamente a los procesos. Puede que
        tenga varios procesos <code>httpd</code> ejecutandose en su
        sistema, pero las se&#241;ales deben enviarse solamente al proceso
        padre, cuyo pid est&#225; especificado en la directiva <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>. Esto quiere decir que no
        debe necesitar enviar se&#241;ales a ning&#250;n proceso excepto
        al proceso padre. Hay tres se&#241;ales que puede enviar al
        proceso padre: <code><a href="#term">TERM</a></code>, <code><a href="#hup">HUP</a></code>, y <code><a href="#graceful">USR1</a></code>, que van a ser descritas a
        continuaci&#243;n.</p>
    
        <p>Para enviar una se&#241;al al proceso padre debe escribir un
        comando como el que se muestra en el ejemplo:</p>
    
    <div class="example"><p><code>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</code></p></div>
    
        <p>La segunda manera de enviar se&#241;ales a los procesos
        <code>httpd</code> es usando las opciones de l&#237;nea de
        comandos <code>-k</code>: <code>stop</code>, <code>restart</code>,
        y <code>graceful</code>, como se muestra m&#225;s abajo.  Estas
        opciones se le pueden pasar al binario <a href="programs/httpd.html">httpd</a>, pero se recomienda que se
        pasen al script de control <a href="programs/apachectl.html">apachectl</a>, que a su vez los
        pasar&#225; a <code>httpd</code>.</p>
    
        <p>Despu&#233;s de haber enviado las se&#241;ales que desee a
        <code>httpd</code>, puede ver como progresa el proceso
        escribiendo:</p>
    
    <div class="example"><p><code>tail -f /usr/local/apache2/logs/error_log</code></p></div>
    
        <p>Modifique estos ejemplos para que coincidan con la
        configuraci&#243;n que tenga especificada en las directivas
        <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> y <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> en su fichero principal de
        configuraci&#243;n.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="term" id="term">Parar Apache</a></h2>
    
    <dl><dt>Se&#241;al: TERM</dt>
    <dd><code>apachectl -k stop</code></dd>
    </dl>
    
        <p>Enviar las se&#241;ales <code>TERM</code> o <code>stop</code>
        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&#225; el
        proceso padre. Cualquier petici&#243;n en proceso terminar&#225;
        inmediatanmente, y ninguna petici&#243;n posterior ser&#225;
        atendida.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="graceful" id="graceful">Reinicio Graceful</a></h2>
    
    <dl><dt>Se&#241;al: USR1</dt>
    <dd><code>apachectl -k graceful</code></dd>
    </dl>
    
        <p>Las se&#241;ales <code>USR1</code> o <code>graceful</code>
        hacen que el proceso padre <em>indique</em> a sus hijos que
        terminen despu&#233;s de servir la petici&#243;n que est&#233;n
        atendiendo en ese momento (o de inmediato si no est&#225;n
        sirviendo ninguna petici&#243;n). El proceso padre lee de nuevo
        sus ficheros de configuraci&#243;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 <em>generaci&#243;n</em> con
        la nueva configuraci&#243;n, que empeciezan a servir peticiones
        inmediatamente.</p>
    
        <div class="note">En algunas plataformas que no permiten usar
        <code>USR1</code> para reinicios graceful, puede usarse una
        se&#241;al alternativa (como <code>WINCH</code>). Tambien puede
        usar <code>apachectl graceful</code> y el script de control
        enviar&#225; la se&#241;al adecuada para su plataforma.</div>
    
        <p>Apache est&#225; dise&#241;ado para respetar en todo momento la
        directiva de control de procesos de los MPM, as&#237; como para
        que el n&#250;mero de procesos y hebras disponibles para servir a
        los clientes se mantenga en los valores adecuados durante el
        proceso de reinicio.  A&#250;n m&#225;s, est&#225; dise&#241;ado
        para respetar la directiva <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> de la siguiente
        manera: si despu&#233;s de al menos un segundo el nuevo hijo de la
        directiva <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code>
        no ha sido creado, entonces crea los suficientes para se atienda
        el trabajo que queda por hacer. As&#237;, se intenta mantener
        tanto el n&#250;mero de hijos adecuado para el trabajo que el
        servidor tenga en ese momento, como respetar la configuraci&#243;n
        determinada por los par&#225;metros de la directiva
        <code class="directive">StartServers</code>.</p>
    
        <p>Los usuarios del m&#243;dulo <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>
        notar&#225;n que las estad&#237;sticas del servidor
        <strong>no</strong> se ponen a cero cuando se usa la se&#241;al
        <code>USR1</code>. Apache fue escrito tanto para minimizar el
        tiempo en el que el servidor no puede servir nuevas peticiones
        (que se pondr&#225;n en cola por el sistema operativo, de modo que
        se no se pierda ning&#250;n evento), como para respetar sus
        par&#225;metros de ajuste. Para hacer esto, tiene que guardar el
        <em>scoreboard</em> usado para llevar el registro de los procesos
        hijo a trav&#233;s de las distintas generaciones.</p>
    
        <p>El mod_status tambi&#233;n usa una <code>G</code> para indicar
        que esos hijos est&#225;n todav&#237;a sirviendo peticiones
        previas al reinicio graceful.</p>
    
        <p>Actualmente no existe ninguna manera de que un script con un
        log de rotaci&#243;n usando <code>USR1</code> 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&#233;s de enviar la se&#241;al <code>USR1</code>
        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.</p>
    
        <div class="note">Si su fichero de configuraci&#243;n tiene errores cuando
        haga el reinicio, entonces el proceso padre no se reinciciar&#225;
        y terminar&#225; con un error. En caso de un reinicio graceful,
        tambi&#233;n dejar&#225; a los procesos hijo ejecutandose mientras
        existan.  (Estos son los hijos de los que se est&#225; saliendo de
        forma graceful y que est&#225;n sirviendo sus &#250;ltimas
        peticiones.) Esto provocar&#225; problemas si intenta reiniciar el
        servidor -- no ser&#225; 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&#243;n de
        l&#237;nea de comandos <code>-t</code> (consulte <a href="programs/httpd.html">httpd</a>). No obstante, esto no
        garantiza que el servidor se reinicie correctamente. Para
        comprobar que no hay errores en los ficheros de
        configuraci&#243;n, puede intentar iniciar <code>httpd</code> con
        un usuario diferente a root. Si no hay errores, intentar&#225;
        abrir sus sockets y logs y fallar&#225; porque el usuario no es
        root (o porque el <code>httpd</code> que se est&#225; ejecutando
        en ese momento ya est&#225; conectado a esos puertos). Si falla
        por cualquier otra raz&#243;n, entonces casi seguro que hay
        alg&#250;n error en alguno de los ficheros de configuraci&#243;n y
        debe corregir ese o esos errores antes de hacer un reinicio
        graceful.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hup" id="hup">Reiniciar Apache</a></h2>
    
    <dl><dt>Se&#241;al: HUP</dt>
    <dd><code>apachectl -k restart</code></dd>
    </dl>
    
        <p>El env&#237;o de las se&#241;ales <code>HUP</code> o
        <code>restart</code> al proceso padre hace que los procesos hijo
        terminen como si le envi&#225; ramos la se&#241;al
        <code>TERM</code>, para eliminar el proceso padre. La diferencia
        est&#225; en que estas se&#241;ales vuelven a leer los archivos de
        configuraci&#243;n y vuelven a abrir los ficheros log. Se genera
        un nuevo conjunto de hijos y se contin&#250;a sirviendo
        peticiones.</p>
    
        <p>Los usuarios del m&#243;dulo <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>
        notar&#225;n que las estad&#237;sticas del servidor se ponen a
        cero cuando se env&#237;a la se&#241;al <code>HUP</code>.</p>
    
    <div class="note">Si su fichero de configuraci&#243;n contiene errores, cuando
    intente reiniciar, el proceso padre del servidor no se
    reiniciar&#225;, sino que terminar&#225; con un error. Consulte
    m&#225;s arriba c&#243;mo puede solucionar este problema.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="race" id="race">Ap&#233;ndice: se&#241;ales y race conditions</a></h2>
    
        <p>Con anterioridad a la versi&#243;n de Apache 1.2b9 hab&#237;a
        varias <em>race conditions</em> implicadas en las se&#241;ales
        para parar y reiniciar procesos (una descripci&#243;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&#237;sticas "adecuadas", se han eliminado tantas race
        conditions como ha sido posible. Pero hay que tener en cuenta que
        todav&#237;a existen race conditions en algunas arquitecturas.</p>
    
        <p>En las arquitecturas que usan un <code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code> 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&#233;s de usar<code>HUP</code>) o el error "long lost child
        came home!"  (despu&#233;s de usar <code>USR1</code>). 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&#237;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&#243;n de la directiva
        <code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code> para ver
        las arquitecturas que la usan.</p>
    
        <p>Todas las arquitecturas tienen una peque&#241;a race condition
        en cada proceso hijo implicada en la segunda y subsiguientes
        peticiones en una conexi&#243;n HTTP persistente
        (KeepAlive). Puede ser que el servidor termine despu&#233;s de
        leer la l&#237;nea de petici&#243;n pero antes de leer cualquiera
        de las cebeceras de petici&#243;n. Hay una soluci&#243;n que fue
        descubierta demasiado tarde para la incluirla en versi&#243;n
        1.2. En teoria esto no debe suponer ning&#250;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&#225;s
        -- en una sesi&#243;n de pruebas, un servidor se reinici&#243;
        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. </p>
    </div></div>
    <div class="bottomlang">
    <p><span>Idiomas disponibles: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" title="Espa&#241;ol">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comentarios</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/stopping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licencia bajo los t&#233;rminos de la <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">M&#243;dulos</a> | <a href="./mod/directives.html">Directivas</a> | <a href="http://wiki.apache.org/httpd/FAQ">Preguntas Frecuentes</a> | <a href="./glossary.html">Glosario</a> | <a href="./sitemap.html">Mapa del sitio web</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/suexec.html.ja.utf8��������������������������������������������������������0000664�0001751�0001751�00000102324�14743132254�020476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>suEXEC サポート - Apache HTTP サーバ バージョン 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p>
    <p class="apache">Apache HTTP サーバ バージョン 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP サーバ</a> &gt; <a href="http://httpd.apache.org/docs/">ドキュメンテーション</a> &gt; <a href="./">バージョン 2.4</a></div><div id="page-content"><div id="preamble"><h1>suEXEC サポート</h1>
    <div class="toplang">
    <p><span>翻訳済み言語: </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">この日本語訳はすでに古くなっている
                可能性があります。
                最近更新された内容を見るには英語版をご覧下さい。
            </div>
    
        <p><strong>suEXEC</strong>
        機能により、Apache ユーザは Web サーバを実行しているユーザ ID とは
        異なるユーザ ID で <strong>CGI</strong> プログラムや <strong>SSI</strong> 
        プログラムを実行することができます。CGI プログラムまたは SSI
        プログラムを実行する場合、通常は web サーバと同じユーザで実行されます。
        </p>
    
        <p>適切に使用すると、この機能によりユーザが個別の CGI
        や SSI プログラムを開発し実行することで生じるセキュリティ上の危険を、
        かなり減らすことができます。しかし、suEXEC の設定が不適切だと、
        多くの問題が生じ、あなたのコンピュータに新しいセキュリティホールを
        作ってしまう可能性があります。あなたが <em>setuid root</em>
        されたプログラムと、それらから生じるセキュリティ上の問題の管理に
        詳しくないようなら、suEXEC の使用を検討しないように強く推奨します。
        </p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#before">始める前に</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#model">suEXEC セキュリティモデル</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">suEXEC
        の設定とインストール</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#enable">suEXEC
        の有効化と無効化</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">suEXEC の使用</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#debug">suEXEC のデバッグ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#jabberwock">とかげに注意: 警告と事例</a></li>
    </ul><h3>参照</h3><ul class="seealso"><li><a href="#comments_section">コメント</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="before" id="before">始める前に</a></h2>
    
        <p>この文書の先頭に飛ぶ前に、Apache
        グループとこの文書での仮定を知っておくべきでしょう。
        </p>
    
        <p>第 1 に、あなたが <strong>setuid</strong> と
        <strong>setgid</strong> 操作が可能な UNIX
        由来のオペレーティングシステムを使っていることを想定しています。
        これは、すべてのコマンド例にあてはまります。
        その他のプラットホームでは、もし suEXEC
        がサポートされていたとしても設定は異なるかもしれません。</p>
    
        <p>第 2 に、あなたが使用中のコンピュータの
        セキュリティに関する基本的な概念と、それらの管理について詳しいことを
        想定しています。これは、<strong>setuid/setgid</strong>
        操作、あなたのシステム上でのその操作による様々な効果、
        セキュリティレベルについてあなたが理解しているということを含みます。
        </p>
    
        <p>第 3 に、<strong>改造されていない</strong> suEXEC
        コードの使用を想定しています。suEXEC のコードは、
        多くのベータテスタだけでなく、開発者によっても注意深く精査され
        テストされています。それらの注意により、簡潔で信頼できる安全な
        コードの基盤が保証されます。このコードを改変することで、
        予期されない問題や新しいセキュリティ上の危険が生じることがあります。
        セキュリティプログラミングの詳細に通じていて、
        今後の検討のために成果を Apache
        グループと共有しようと思うのでなければ、suEXEC
        コードは変えないことを <strong>強く</strong>推奨します。</p>
    
        <p>第 4 に、これが最後ですが、suEXEC を Apache
        のデフォルトインストールには<strong>含めない</strong>ことが
        Apache グループで決定されています。これは、suEXEC
        の設定には管理者の詳細にわたる慎重な注意が必要だからです。
        suEXEC の様々な設定について検討が終われば、管理者は suEXEC
        を通常のインストール方法でインストールすることができます。
        これらの設定値は、suEXEC
        機能の使用中にシステムセキュリティを適切に保つために、
        管理者によって慎重に決定され指定されることが必要です。
        この詳細な手順により、Apache グループは、suEXEC
        のインストールについて、注意深く十分に検討してそれを使用することを
        決定した場合に限っていただきたいと考えています。
        </p>
    
        <p>それでも進みますか? よろしい。では、先へ進みましょう!</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="model" id="model">suEXEC セキュリティモデル</a></h2>
    
        <p>suEXEC の設定とインストールを始める前に、
        まず実装しようとしているセキュリティモデルについて論じておきます。
        それには、suEXEC の内部で行なわれていること、
        システムのセキュリティを保証するために警告されることを
        よく理解しておいた方がよいでしょう。</p>
    
        <p><strong>suEXEC</strong> は、Apache web
        サーバから呼び出される setuid された "wrapper"
        プログラムが基本となっています。設計した CGI、または SSI
        プログラムへの HTTP リクエストがあると、この wrapper
        が呼び出されます。このようなリクエストがあると、Apache
        はそのプログラムが実行される際のプログラム名とユーザ ID とグループ
        ID を指定して suEXEC wrapper を実行します。
        </p>
    
        <p>それから、wrapper は成功または失敗を決定するため
        以下の処理を行ないます。これらの状態のうち一つでも失敗した場合、
        プログラムは失敗をログに記録してエラーで終了します。
        そうでなければ、後の処理が続けられます。</p>
    
        <ol>
          <li>
            <strong>wrapper
            を実行しているユーザはこのシステムの正当なユーザか?</strong>
    
            <p class="indent">
              これは、wrapper を実行しているユーザが
              本当にシステムの利用者であることを保証するためです。
            </p>
          </li>
    
    
         <li>
            <strong>wrapper が適切な数の引数で呼び出されたか?</strong>
    
    
            <p class="indent">
              wrapper は適切な数の引数が与えられた場合にのみ実行されます。
              適切な引数のフォーマットは Apache Web サーバに解釈されます。
              適切な数の引数を受け取らなければ、攻撃をされたか
              あなたの Apache バイナリの suEXEC の部分が
              どこかおかしい可能性があります。
            </p>
          </li>
    
          <li>
            <strong>この正当なユーザは wrapper
            の実行を許可されているか?</strong>
    
            <p class="indent">
              このユーザは wrapper 実行を許可されたユーザですか?
              ただ一人のユーザ (Apache ユーザ) だけが、
              このプログラムの実行を許可されます。
            </p>
          </li>
    
          <li>
            <strong>対象の CGI, SSI プログラムが安全でない階層の参照をしているか?
            </strong>
    
            <p class="indent">
              対象の CGI, SSI プログラムが '/' から始まる、または
              '..' による参照を行なっていますか? これらは許可されません。
              対象のプログラムは suEXEC のドキュメントルート
              (下記の <code>--with-suexec-docroot=<em>DIR</em></code> を参照)
              内に存在しなければなりません。
            </p>
          </li>
    
          <li>
            <strong>対象となるユーザ名は正当なものか?</strong>
    
            <p class="indent">
              対象となるユーザ名は存在していますか?
            </p>
          </li>
    
          <li>
            <strong>対象となるグループ名は正当なものか?</strong>
    
            <p class="indent">
              対象となるグループ名は存在していますか?
            </p>
          </li>
    
          <li>
            <strong>目的のユーザはスーパーユーザでは<em>ない</em>か?
            </strong>
    
            <p class="indent">
              今のところ、suEXEC は <code><em>root</em></code> による CGI/SSI
              プログラムの実行を許可していません。
            </p>
          </li>
    
          <li>
            <strong>対象となるユーザ ID は、最小の ID
            番号よりも<em>大きい</em>か?  </strong>
    
            <p class="indent">
              最小ユーザ ID 番号は設定時に指定されます。これは、
              CGI/SSI プログラム実行を許可されるユーザ ID
              のとりうる最小値です。これは
              "system" 用のアカウントを閉め出すのに有効です。
            </p>
          </li>
    
          <li>
            <strong>対象となるグループはスーパーユーザのグループでは
            <em>ない</em>か?</strong>
    
            <p class="indent">
             今のところ、suEXEC は 'root' グループによる CGI/SSI
             プログラムの実行を許可していません。
            </p>
          </li>
    
          <li>
            <strong>対象となるグループ ID は最小の ID
              番号よりも<em>大きい</em>か?</strong>
    
            <p class="indent">
              最小グループ ID 番号は設定時に指定されます。これは、
              CGI/SSI プログラム実行を許可されるグループ
              ID のとりうる最小値です。
              これは "system" 用のグループを閉め出すのに有効です。
            </p>
          </li>
    
          <li>
            <strong>wrapper が正常に対象となるユーザとグループになれるか?
            </strong>
    
            <p class="indent">
              ここで、setuid と setgid
              の起動によりプログラムは対象となるユーザとグループになります。
              グループアクセスリストは、
              ユーザが属しているすべてのグループで初期化されます。
            </p>
          </li>
    
          <li>
            <strong>CGI/SSI プログラムが置かれているディレクトリに移動
            (change directory) できるか?</strong>
    
            <p class="indent">
              ディレクトリが存在しないなら、そのファイルも存在しないかもしれません。
              ディレクトリに移動できないのであれば、おそらく存在もしないでしょう。
            </p>
          </li>
    
          <li>
            <strong>ディレクトリが Apache のドキュメントツリー内にあるか?
            </strong>
    
            <p class="indent">
              リクエストがサーバ内のものであれば、
              要求されたディレクトリが suEXEC のドキュメントルート配下にありますか?
              リクエストが UserDir のものであれば、要求されたディレクトリが suEXEC 
              のユーザのドキュメントルート配下にありますか?
              (<a href="#install">suEXEC 設定オプション</a> 参照)
            </p>
          </li>
    
          <li>
            <strong>ディレクトリを他のユーザが書き込めるようになって
            <em>いない</em>か?</strong>
    
            <p class="indent">
              ディレクトリを他ユーザに開放しないようにします。
              所有ユーザだけがこのディレクトリの内容を改変できるようにします。
            </p>
          </li>
    
    
          <li>
            <strong>対象となる CGI/SSI プログラムは存在するか?</strong>
    
            <p class="indent">
              存在しなければ実行できません。
            </p>
          </li>
    
          <li>
            <strong>対象となる CGI/SSI プログラムファイルが他アカウントから
            書き込めるようになって<em>いない</em>か?</strong>
    
            <p class="indent">
              所有者以外には CGI/SSI プログラムを変更する権限は与えられません。
            </p>
          </li>
    
    
          <li>
            <strong>対象となる CGI/SSI プログラムが setuid または setgid 
            されて<em>いない</em>か?</strong>
    
            <p class="indent">
              UID/GID を再度変更してのプログラム実行はしません
            </p>
          </li>
    
    
          <li>
            <strong>対象となるユーザ/グループがプログラムの
            ユーザ/グループと同じか?</strong>
    
            <p class="indent">
              ユーザがそのファイルの所有者ですか?
            </p>
          </li>
    
          <li>
            <strong>安全な動作を保証するための環境変数クリアが可能か?
            </strong>
    
            <p class="indent">
              suEXEC は、安全な環境変数のリスト
              (これらは設定時に作成されます) 内の変数として渡される安全な
              PATH 変数 (設定時に指定されます) を設定することで、
              プロセスの環境変数をクリアします。
            </p>
          </li>
    
    
          <li>
            <strong>対象となる CGI/SSI プログラムを exec して実行できるか?</strong>
    
    
            <p class="indent">
              ここで suEXEC が終了し、対象となるプログラムが開始されます。
            </p>
          </li>
        </ol>
    
        <p>ここまでが suEXEC の wrapper
        におけるセキュリティモデルの標準的な動作です。もう少し厳重に
        CGI/SSI 設計についての新しい制限や規定を取り入れることもできますが、
        suEXEC はセキュリティに注意して慎重に少しずつ開発されてきました。
        </p>
    
        <p>このセキュリティモデルを用いて
        サーバ設定時にどのように許すことを制限するか、また、suEXEC
        を適切に設定するとどのようなセキュリティ上の危険を避けられるかに
        関するより詳しい情報については、<a href="#jabberwock">"とかげに注意"
        (Beware the Jabberwock)</a> の章を参照してください。
        </p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">suEXEC
        の設定とインストール</a></h2>
    
        <p>ここから楽しくなります。</p>
    
        <p><strong>suEXEC
        設定オプション</strong><br />
        </p>
    
        <dl>
          <dt><code>--enable-suexec</code></dt>
    
          <dd>このオプションは、デフォルトではインストールされず、
          有効にはならない suEXEC 機能を有効にします。
          suEXEC を使うように APACI に要求するには、<code>--enable-suexec</code>
          オプションにあわせて少なくとも一つは <code>--with-suexec-xxxxx</code>
          オプションが指定されなければなりません。</dd>
    
          <dt><code>--with-suexec-bin=<em>PATH</em></code></dt>
    
          <dd>セキュリティ上の理由により、<code>suexec</code> バイナリのパスはサーバに
          ハードコードされている必要があります。デフォルトのパスを
          変えたいときはこのオプションを使ってください。<em>例えば</em>、
          <code>--with-suexec-bin=/usr/sbin/suexec</code> のように。</dd>
    
          <dt><code>--with-suexec-caller=<em>UID</em></code></dt>
    
          <dd>Apache を通常動作させる<a href="mod/mpm_common.html#user">ユーザ名</a>を指定します。
          このユーザだけが suexec の実行を許可されたユーザになります。</dd>
    
          <dt><code>--with-suexec-userdir=<em>DIR</em></code></dt>
    
          <dd>suEXEC がアクセスを許されるユーザホームディレクトリ配下の
          サブディレクトリを指定します。
          このディレクトリ以下の全実行ファイルは、"安全な"プログラムになるよう、
          suEXEC がそのユーザとして実行できるようにします。
          "単純な" UserDir ディレクティブを使っている場合 
          (すなわち "*" を含まないもの)、これと同じ値を設定すべきです。
          Userdir ディレクティブがそのユーザのパスワードファイル内の
          ホームディレクトリと同じ場所を指していなければ、
          suEXEC は適切に動作しません。デフォルトは "public_html" です。
          <br />
          各 UserDir が異なった仮想ホストを設定している場合、
          それらを全て一つの親ディレクトリに含めて、
          その親ディレクトリの名前をここで指定する必要があります。
          <strong>このように指定されなければ "~userdir" cgi
          へのリクエストが動作しません。</strong></dd>
    
          <dt><code>--with-suexec-docroot=<em>DIR</em></code></dt>
    
          <dd>Apache のドキュメントルートを設定します。これが suEXEC
          の動作で使用する唯一のディレクトリ階層になります (UserDir
          の指定は別)。デフォルトでは <code>--datedir</code> に "/htdocs"
          というサフィックスをつけたものです。
          "<code>--datadir=/home/apache</code>" として設定すると、
          suEXEC wrapper にとって "/home/apache/htdocs"
          がドキュメントルートとして使われます。</dd>
    
          <dt><code>--with-suexec-uidmin=<em>UID</em></code></dt>
    
          <dd>suEXEC の対象ユーザとして許される UID の最小値を指定します。
          大抵のシステムでは 500 か 100 が一般的です。
          デフォルト値は 100 です。</dd>
    
          <dt><code>--with-suexec-gidmin=<em>GID</em></code></dt>
    
          <dd>suEXEC の対象グループとして許される GID
          の最小値を指定します。大抵のシステムでは 100 が一般的なので、
          デフォルト値としても 100 が使われています。</dd>
    
          <dt><code>--with-suexec-logfile=<em>FILE</em></code></dt>
    
          <dd>suEXEC の処理とエラーが記録されるファイル名を指定します。
          (監査やデバッグ目的に有用)
          デフォルトではログファイルは "suexec_log" という名前で、
          標準のログファイルディレクトリ (<code>--logfiledir</code>) に置かれます。
          </dd>
    
          <dt><code>--with-suexec-safepath=<em>PATH</em></code></dt>
    
          <dd>CGI 実行ファイルに渡される安全な PATH 環境変数です。
          デフォルト値は "/usr/local/bin:/usr/bin:/bin" です。
          </dd>
        </dl>
    
        <p><strong>suEXEC wrapper
        のコンパイルとインストール</strong><br />
        <code>--enable-suexec</code> オプションで suEXEC 機能を有効にすると、
        "make" コマンドを実行した時に <code>suexec</code> のバイナリ (Apache 自体も)
        が自動的に作成されます。
        <br />
        すべての構成要素が作成されると、それらのインストールには
        <code>make install</code> コマンドが実行できます。バイナリイメージの <code>suexec</code>
        は <code>--sbindir</code> オプションで指定されたディレクトリにインストールされます。
        デフォルトの場所は "/usr/local/apache/bin/suexec" です。<br />
        インストール時には <strong><em>root</em></strong>
        権限が必要なので注意してください。wrapper がユーザ ID
        を設定するために、所有者 <code><em>root</em></code>
        でのセットユーザ ID
        ビットをそのファイルのモードに設定しなければなりません。
        </p>
    
        <p><strong>安全なパーミッションを設定する</strong><br />
        suEXEC ラッパーは、<code>--with-suexec-caller</code> <code class="program"><a href="./programs/configure.html">configure</a></code> 
        オプションで指定した正しいユーザで起動されていることを確認しますが、
        システム上でこのチェックが行なわれる前に、
        suEXEC が呼ぶシステムやライブラリが脆弱である可能性は残ります。対抗策として、
        一般に良い習慣ともされいますが、
        ファイルシステムパーミッションを使って
        Apache の実行時のグループのみが suEXEC を実行できるように
        するのが良いでしょう。</p>
    
        <p>たとえば、次のようにサーバが設定されていたとします。</p>
    
    <div class="example"><p><code>
        User www<br />
        Group webgroup<br />
    </code></p></div>
    
        <p><code class="program"><a href="./programs/suexec.html">suexec</a></code> が "/usr/local/apache2/bin/suexec" 
        にインストールされていた場合、次のように設定する必要があります。</p>
    
    <div class="example"><p><code>
        chgrp webgroup /usr/local/apache2/bin/suexec<br />
        chmod 4750 /usr/local/apache2/bin/suexec<br />
    </code></p></div>
    
        <p>これで Apache が実行されるグループのみが 
        suEXEC ラッパーを実行できるということを
        確証します。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">suEXEC
        の有効化と無効化</a></h2>
    
        <p>起動時に、Apache は <code>--sbindir</code>
        オプションで設定されたディレクトリで
        <code>suexec</code> を探します
        (デフォルトは "/usr/local/apache/sbin/suexec") 。
        適切に設定された suEXEC がみつかると、
        エラーログに以下のメッセージが出力されます。</p>
    
    <div class="example"><p><code>
        [notice] suEXEC mechanism enabled (wrapper: <var>/path/to/suexec</var>)
    </code></p></div>
    
        <p>サーバ起動時にこのメッセージが出ない場合、
        大抵はサーバが想定した場所で wrapper プログラムが見つからなかったか、
        <em>setuid root</em> としてインストールされていないかです。</p>
    
        <p>suEXEC の仕組みを使用するのが初めてで、Apache が既に動作中であれば、
        Apache を kill して、再起動しなければなりません。HUP シグナルや
        USR1 シグナルによる単純な再起動では不十分です。</p>
        <p>suEXEC を無効にする場合は、<code>suexec</code> ファイルを削除してから
        Apache を kill して再起動します。
        </p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">suEXEC の使用</a></h2>
    
        <p>CGI プログラムへのリクエストが suEXEC ラッパーを呼ぶのは、
        <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> ディレクティブを
        含むバーチャルホストへのリクエストか、<code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> により
        処理されたリクエストの場合に限ります。</p>
    
        <p><strong>仮想ホスト:</strong><br />
        suEXEC wrapper の使い方として、
        <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> 設定での
        <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code>
        ディレクティブを通したものがあります。
        このディレクティブをメインサーバのユーザ ID
        と異なるものにすると、CGI リソースへのすべてのリクエストは、その
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> で指定された <em>User</em> と
        <em>Group</em> として実行されます。<code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        でこのディレクティブが指定されていない場合、
        メインサーバのユーザ ID が想定されます。</p>
    
        <p><strong>ユーザディレクトリ:</strong><br />
        <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> により処理されたリクエストは
        リクエストされたユーザディレクトリのユーザ ID で CGI プログラムを
        実行するために suEXEC ラッパーを呼びます。
        この機能を動作させるために必要なことは、CGI
        をそのユーザで実行できること、そのスクリプトが上記の<a href="#model">セキュリティ検査</a>をパスできることです。
        <a href="#install">コンパイル
         時のオプション</a> <code>--with-suexec-userdir</code> も参照してください。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="debug" id="debug">suEXEC のデバッグ</a></h2>
    
        <p>suEXEC wrapper は、上記で述べた <code>--with-suexec-logfile</code>
        オプションで指定されたファイルにログ情報を記録します。
        wrapper を適切に設定、インストールできていると思う場合、
        どこで迷っているか見ようとするならこのログとサーバの
        エラーログを見るとよいでしょう。</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="jabberwock" id="jabberwock">とかげに注意: 警告と事例</a></h2>
    
        <p><strong>注意!</strong>
        この章は完全ではありません。この章の最新改訂版については、
        Apache グループの<a href="http://httpd.apache.org/docs/2.4/suexec.html">
        オンラインドキュメント</a>版を参照してください。
        </p>
    
        <p>サーバの設定に制限をもうける wrapper について、
        いくつか興味深い点があります。suEXEC に関する "バグ"
        を報告する前にこれらを確認してください。</p>
    
        <ul>
          <li><strong>suEXEC の興味深い点</strong></li>
    
          <li>階層構造の制限
    
    
            <p class="indent">
              セキュリティと効率の理由から、<code>suEXEC</code> の全てのリクエストは
              仮想ホストへのリクエストにおける最上位のドキュメントルート内か、
              ユーザディレクトリへのリクエストにおける個々のユーザの最上位の
              ドキュメントルート内に残らなければなりません。
              例えば、四つの仮想ホストを設定している場合、
              仮想ホストの suEXEC に有利なように、メインの Apache
              ドキュメント階層の外側に全ての仮想ホストのドキュメントルートを
              構築する必要があります。(例は後日記載)
            </p>
          </li>
    
          <li>suEXEC の PATH 環境変数
    
    
            <p class="indent">
              これを変更するのは危険です。この指定に含まれる各パスが
              <strong>信頼できる</strong>
              ディレクトリであることを確認してください。
              世界からのアクセスにより、誰かがホスト上でトロイの木馬
              を実行できるようにはしたくないでしょう。
            </p>
          </li>
    
          <li>suEXEC コードの改造
    
    
            <p class="indent">
              繰り返しますが、何をやろうとしているか把握せずにこれをやると
              <strong>大きな問題</strong>を引き起こしかねません。
              可能な限り避けてください。
            </p>
          </li>
        </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>翻訳済み言語: </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">コメント</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />この文書は <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> のライセンスで提供されています。.</p>
    <p class="menu"><a href="./mod/">モジュール</a> | <a href="./mod/directives.html">ディレクティブ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">用語</a> | <a href="./sitemap.html">サイトマップ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/urlmapping.html.ko.euc-kr��������������������������������������������������0000664�0001751�0001751�00000046516�14743132254�021711� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko"><head>
    <meta content="text/html; charset=EUC-KR" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>URL Ͻý ġ ϱ - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>URL Ͻý ġ ϱ</h1>
    <div class="toplang">
    <p><span> : </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div>
    <div class="outofdate">  ֽ  ƴմϴ.
                ֱٿ     ϼ.</div>
    
        <p>  û URL  ġ   
         Ͻýۻ ġ ã Ѵ.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#related">õ  þ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentroot">DocumentRoot</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#outside">DocumentRoot ۿ ִ ϵ</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#user"> 丮</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#redirect">URL ̷(Redirection)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Ͻ(Reverse Proxy)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">ۼ  (Rewriting Engine)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#notfound">File Not Found</a></li>
    </ul><h3></h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">õ  þ</a></h2>
    
    <table class="related"><tr><th>õ </th><th>õ þ</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code></li><li><code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code></li><li><code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_speling.html#checkspelling">CheckSpelling</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="./mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritematch">RewriteMatch</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentroot" id="documentroot">DocumentRoot</a></h2>
    
        <p>û  ġ    ϱ
        ⺻ û URL-(URL ȣƮ Ʈ ڿ
         κ) Ͽ  <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> ڿ δ. ׷
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> Ʒִ
        ϰ 丮  Ե ⺻ ̴.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="outside" id="outside">DocumentRoot ۿ ִ ϵ</a></h2>
    
        <p> Ͻýۿ <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> Ʒ  κ
          ʿ䰡 ִ. ġ    
          ִ. н ýۿ ɺũ Ͽ
        Ͻý ٸ κ <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> Ʒ   ִ.
          ġ ش 丮 <code class="directive"><a href="./mod/core.html#options">Options</a></code> 
        <code>FollowSymLinks</code>
        <code>SymLinksIfOwnerMatch</code> ִ 쿡 ɺũ
        󰣴.</p>
    
        <p>, <code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code>
        þ Ͻý Ư κ  Ѵ. 
          ٸ</p>
    
    <div class="example"><p><code>Alias /docs /var/web</code></p></div>
    
        <p>URL <code>http://www.example.com/docs/dir/file.html</code>
        <code>/var/web/dir/file.html</code>  Ѵ.
         ο ִ   CGI ũƮ ϴ 
        ϰ <code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
        þ   Ѵ.</p>
    
        <p><code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code>
        <code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code>
        þ  ǥı  ġ Ͽ 
          ϴ.  ,</p>
    
    <div class="example"><p><code>ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+)
          /home/$1/cgi-bin/$2</code></p></div>
    
        <p> <code>http://example.com/~user/cgi-bin/script.cgi</code>
        û  <code>/home/user/cgi-bin/script.cgi</code>
        ϰ, ش  CGI ũƮ Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="user" id="user"> 丮</a></h2>
    
        <p>н ý  Ư  <em>user</em>
        Ȩ丮 <code>~user/</code> ĪѴ.
        <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code>    
        ȮϿ,   URL    Ȩ丮
        ȿ ִ  Ѵ.</p>
    
    <div class="example"><p><code>http://www.example.com/~user/file.html</code></p></div>
    
        <p>Ȼ   Ȩ丮    
        ȵȴ. ׷ <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>
        þ  Ȩ丮  ϵ  丮
        Ѵ. ⺻  <code>Userdir public_html</code> ϰ
        <code>/home/user/</code> <code>/etc/passwd</code> 
         Ȩ丮,  URL 
        <code>/home/user/public_html/file.html</code> Ѵ.</p>
    
        <p>, <code>Userdir</code> þ <code>/etc/passwd</code>
        Ȩ丮 ġ ʴ ý   ٸ
        ¸   ִ.</p>
    
        <p>  (  <code>%7e</code> ڵǴ)
        "~" ȣ ̻Ͽ ٸ   丮 Ÿ
        ;Ѵ.   mod_userdir ʴ´. ׷
         Ȩ丮 Ģ  ִٸ, <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code> þ Ͽ
        ϴ ȿ   ִ.  , 
        <code>AliasMatch</code> þ ϸ
        <code>http://www.example.com/upages/user/file.html</code>
        <code>/home/user/public_html/file.html</code> Ѵ:</p>
    
    <div class="example"><p><code>AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*)
          /home/$1/public_html/$2</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">URL ̷(Redirection)</a></h2>
    
        <p>տ   þ ġ Ͻý Ư
        ҿ ִ  Ŭ̾Ʈ  . ׷
         û  ٸ URL ִٰ Ŭ̾Ʈ ˷־,
        Ŭ̾Ʈ   URL ûϵ    
        ִ. ̸ <em>̷(redirection)</em>̶ ϸ,
        <code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code> þ
        Ѵ.  , <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> Ʒ <code>/foo/</code>
        丮   <code>/bar/</code> 丮 Űٸ
          Ŭ̾Ʈ ο ġ ûϵ Ѵ:</p>
    
    <div class="example"><p><code>Redirect permanent /foo/
          http://www.example.com/bar/</code></p></div>
    
        <p>׷ <code>www.example.com</code>  <code>/foo/</code>
        ϴ URL-δ <code>/foo/</code> <code>/bar/</code>
        ٲ URL ̷ǵȴ. Ŭ̾Ʈ  ܿ 
        ٸ ε ̷  ִ.</p>
    
        <p>, ġ   ۼ  
        <code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code>
        þ Ѵ.  , ٸ û ״ ΰ Ʈ
        Ȩ  û ٸ Ʈ ̷Ϸ:</p>
    
    <div class="example"><p><code>RedirectMatch permanent ^/$
          http://www.example.com/startpage.html</code></p></div>
    
        <p>ӽ÷ Ʈ   ٸ Ʈ Ư 
        ̷Ϸ:</p>
    
    <div class="example"><p><code>RedirectMatch temp .*
          http://othersite.example.com/startpage.html</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Ͻ(Reverse Proxy)</a></h2>
    
    <p>ġ ٸ  ִ   URL  
     ִ.       ͼ
    Ŭ̾Ʈ ϴ Ͻ   ϱ⶧ ̷
     <em>Ͻ(reverse proxying)</em> Ѵ. Ŭ̾Ʈ
    忡 Ͻ   ִ ó ̹Ƿ Ϲ
    Ͻÿʹ ٸ.</p>
    
    <p>Ʒ  Ŭ̾Ʈ <code>/foo/</code> ִ 
    ûϸ,  <code>internal.example.com</code>
    <code>/bar/</code> 丮  ͼ  ġ
     ־ ó Ŭ̾Ʈ .</p>
    
    <div class="example"><p><code>
    ProxyPass /foo/ http://internal.example.com/bar/<br />
    ProxyPassReverse /foo/ http://internal.example.com/bar/
    </code></p></div>
    
    <p><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> 
       ϸ, <code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code> þ
    <code>internal.example.com</code>  ̷ ۼϿ
    ̷    丮 Ű Ѵ.
    , <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code>
    <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code>
         Ű ۼѴ.</p>
    <p>׷  ȿ ִ ũ ۼ  ϶.
    <code>internal.example.com</code>  븵ũ Ŭ̾Ʈ
    Ͻü ƴ϶ <code>internal.example.com</code> 
    ûϰ Ѵ. ڰ  <a href="http://apache.webthing.com/mod_proxy_html/">mod_proxy_html</a>
     Ͽ HTML XHTML ִ ũ ۼ  ִ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">ۼ  (Rewriting Engine)</a></h2>
    
        <p>  ġȯ ʿҶ <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
        ۼ   ȴ.   þ  
        Ŭ̾Ʈ IP ּ  û Ư¡   ִ
            ִ. , mod_rewrite û
         ó ϱ ܺ ͺ̽ ̳
        α׷   ִ. ۼ   ٷ 
         , ,  ̷ (alias), ܺ ̷,
        Ͻ, θ Ѵ. mod_rewrite ϴ  
        <a href="misc/rewriteguide.html">URL ۼ ħ</a>
        Ѵ.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="notfound" id="notfound">File Not Found</a></h2>
    
        <p>ᱹ û URL ϴ  Ͻýۿ ã
         ̴.    ִ.   
        ٸ  Ű   ִ.   Ŭ̾Ʈ
        <a href="#redirect">URL ̷</a> ڿ ο
        ġ ˷ִ   . ׷ ڿ Űܵ
         ϸũ ũ  ȿϴ.</p>
    
        <p>"File Not Found"  ٸ Ϲ  
         Ȥ HTML ũ URL ߸ Էµ ̴. ġ
        <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> ( Ʋ ʾ) 
        ̿   ´.   ϸ "File Not Found"
         ߻ϴ   ϸ  ڿ ã´.
         ߰ϸ mod_speling Ŭ̾Ʈ ùٸ ġ
        HTTP ̷Ѵ. ""   ִٸ
        Ŭ̾Ʈ  .</p>
    
        <p>mod_speling Ư   ҹڸ ʰ
        ϸ ϴ ̴. ׷ н Ͻý۰ URL
        ҹ  ϴ ڰ ִ ýۿ 
        ȴ. ׷ mod_speling  URL ľѴٸ, "߸"
        û URL ̷ǰ Ŭ̾Ʈ ο û
        ϾǷ  δ ȴ.</p>
    
        <p>ã õ  ϸ ġ HTTP status code 404
        (file not found)  .   
        <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> þ
        ϸ, <a href="custom-error.html">  </a>
         Ͽ   ִ.</p>
    </div></div>
    <div class="bottomlang">
    <p><span> : </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Fran&#231;ais">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="T&#252;rk&#231;e">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/urlmapping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/"></a> | <a href="./mod/directives.html">þ</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html"></a> | <a href="./sitemap.html">Ʈ</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/configuring.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000045611�14740503670�021537� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Fichiers de configuration - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Fichiers de configuration</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    <p>Ce document décrit les fichiers utilisés pour configurer
    le Serveur HTTP Apache.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#main">Fichiers de configuration principaux</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#syntax">Syntaxe des fichiers de configuration</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#scope">Portée des directives</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#htaccess">Fichiers .htaccess</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">Fichiers de configuration principaux</a></h2>
        
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#include">Include</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code></li></ul></td></tr></table>
    
        <p>La configuration du serveur HTTP Apache est effectuée en plaçant des <a href="mod/directives.html">directives</a> dans des fichiers de
        configuration au format texte. Le fichier de configuration principal se nomme
        en général
        <code>httpd.conf</code>. La localisation de ce fichier est définie
        à la compilation, mais peut être redéfinie à l'aide de l'option
        de ligne de commande <code>-f</code>. En outre, d'autres fichiers de
        configuration peuvent être ajoutés à l'aide de la directive
        <code class="directive"><a href="./mod/core.html#include">Include</a></code>, et des caractères de
        remplacement
        peuvent être utilisés pour inclure de nombreux fichiers de configuration.
        Des directives de tous types peuvent être placées dans chacun de ces fichiers
        de configuration. Les modifications dans les fichiers de configuration
        principaux ne sont prises en compte par httpd que lorsque le serveur
        est démarré ou redémarré.</p>
    
        <p>Le serveur lit aussi un fichier contenant les types de document mime&nbsp;;
        ce fichier est défini par la directive <code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code>,
        et se nomme <code>mime.types</code> par défaut.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="syntax" id="syntax">Syntaxe des fichiers de configuration</a></h2>
        
    
        <p>Les fichiers de configuration de httpd contiennent une directive
        par ligne.
        On peut utiliser l'anti-slash "\" comme dernier caractère d'une ligne
        pour indiquer que la directive continue à la ligne suivante.
        Il ne doit y avoir aucun caractère ni espace entre l'anti-slash et
        la fin de la ligne.</p>
    
        <p>Les arguments des directives sont séparés les uns des autres par
        des espaces. Si un argument contient des espaces, il doit être
        entouré de guillemets.</p>
    
        <p>Les directives dans les fichiers de configuration ne sont pas
        sensibles à la casse, mais leurs arguments le sont souvent. Les lignes
        qui débutent par le caractère "#" sont interprétées comme des
        commentaires, et sont ignorées. Les commentaires ne doivent
        <strong>pas</strong> apparaître sur la même ligne qu'une directive
        de configuration. Les espaces précédant une directive
        sont ignorés&nbsp;; vous pouvez par conséquent indenter les directives
        afin d'améliorer la lisibilité. Les lignes vides sont
        aussi ignorées.</p>
    
        <p>Les valeurs des variables d'environnement ou des variables définies via
        la directive <code class="directive"><a href="./mod/core.html#define">Define</a></code> peuvent être
        utilisées dans le fichier de configuration en utilisant la syntaxe
        <code>${VAR}</code>. Si "VAR" est le nom d'une variable valable, la valeur
        de la variable est alors substituée à la chaîne <code>${VAR}</code>, et le
        processus de lecture du fichier de configuration continue comme si la
        chaîne correspondant à la valeur de la variable s'y était trouvée
        littéralement. Les variables définies via la directive <code class="directive"><a href="./mod/core.html#define">Define</a></code> l'emportent sur les autres variables
        d'environnement de l'interpréteur de commande. Si la variable "VAR" n'est
        pas trouvée, la chaîne <code>${VAR}</code> n'est pas modifiée, et un
        avertissement est enregistré dans le journal. Le caractère ":" est interdit
        dans les noms de variables afin d'éviter tout conflit avec la syntaxe de la
        directive <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>.</p>
    
        <p>Seules les variables d'environnement de l'interpréteur de commande
        définies avant le démarrage du serveur peuvent être utilisées en extension.
        Les variables d'environnement définies dans le fichier de configuration
        lui-même, par exemple avec <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code>,
        prennent effet trop tard pour pouvoir être utilisées en extension au sein
        du fichier de configuration.</p>
    
        <p>La longueur maximale d'une ligne dans un fichier de configuration
        normal, après substitution des variables et fusion des lignes
        interrompues, est approximativement de 16 Mo. Dans les <a href="configuring.html#htaccess">fichiers .htaccess</a>, la longueur
        maximale est de 8190 caractères.</p>
    
        <p>Vous pouvez vérifier l'absence d'erreurs de syntaxe dans vos fichiers
        de configuration sans démarrer le serveur à l'aide de la commande
        <code>apachectl configtest</code> ou de l'option de ligne de commande
        <code>-t</code>.</p>
    
        <p>Vous pouvez utiliser la définition <code>-DDUMP_CONFIG</code> de
        <code class="module"><a href="./mod/mod_info.html">mod_info</a></code> pour afficher la configuration avec tous
        les fichiers inclus et les variables d'environnement évaluées, tous
        les commentaires et les sections <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> et <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> non actives ayant
        été supprimés. Cependant, la sortie ne reflète
        pas les fusions ou écrasements pouvant intervenir en cas de
        définitions multiples de directives.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="modules" id="modules">Modules</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>httpd est un serveur modulaire. Ceci implique que seules les
        fonctionnalités les plus courantes sont incluses dans le serveur de base.
        Les fonctionnalités étendues sont fournies à l'aide de <a href="mod/">modules</a> qui peuvent être chargés dans httpd.
        Par défaut, un jeu de <a href="mod/module-dict.html#Status">modules de base</a> est inclus dans le
        serveur à la compilation. Si le serveur est compilé de façon à utiliser
        les <a href="dso.html">modules chargés dynamiquement</a>,
        alors les modules peuvent être compilés séparément et chargés à
        n'importe quel moment à l'aide de la directive
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>.
        Dans le cas contraire, httpd doit être recompilé pour ajouter ou
        supprimer des modules.
        Les directives de configuration peuvent être incluses de manière
        conditionnelle selon la présence ou l'absence d'un module particulier
        en les plaçant dans un bloc <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>.</p>
    
        <p>Pour voir quels modules ont été compilés avec le serveur,
        vous pouvez utiliser l'option de ligne de commande <code>-l</code>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="scope" id="scope">Portée des directives</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>Les directives placées dans les fichiers de configuration principaux
        s'appliquent au serveur dans son ensemble. Si vous souhaitez modifier la
        configuration d'une partie du serveur seulement, vous pouvez limiter la
        portée de vos directives en les plaçant dans une section
        <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> ou <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>.
        Ces sections limitent le champ d'application des directives qu'elles
        contiennent à des URls ou des portions du système de fichiers particulières.
        Elles peuvent aussi être imbriquées, ce qui permet
        une configuration très fine.</p>
    
        <p>httpd peut servir simultanément de nombreux sites web au travers des <a href="vhosts/">Serveurs Virtuels</a>. La portée des directives peut ainsi
        être limitée en les plaçant dans des sections <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>, afin qu'elles ne s'appliquent
        qu'aux requêtes pour un site web particulier.</p>
    
        <p>Bien que la plupart des directives puissent être placées dans
        chacune de ces sections, certaines d'entre elles n'ont aucun sens
        dans certains contextes.
        Par exemple, les directives qui contrôlent la création des processus
        n'ont de sens que dans le contexte du serveur global. Pour déterminer
        quelles directives peuvent être placées dans quelles sections, consultez
        le <a href="mod/directive-dict.html#Context">Contexte</a> de la
        directive. Pour plus d'informations, nous fournissons des détails dans
        <a href="sections.html">Comment fonctionnent les sections Directory,
        Location et Files</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">Fichiers .htaccess</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
    
        <p>httpd permet la gestion décentralisée de la configuration
        à l'aide de fichiers spéciaux placés dans l'arborescence du site web.
        Ces fichiers spéciaux se nomment en général <code>.htaccess</code>,
        mais tout autre nom peut être spécifié à l'aide de la directive
        <code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code>.
        Les directives placées dans les fichiers <code>.htaccess</code>
        s'appliquent au répertoire dans lequel vous avez placé le fichier,
        ainsi qu'à tous ses sous-répertoires.
        La syntaxe des fichiers <code>.htaccess</code> est la même que celle
        des fichiers de configuration principaux. Comme les fichiers
        <code>.htaccess</code> sont lus à chaque requête, les modifications de
        ces fichiers prennent effet immédiatement.</p>
    
        <p>Pour déterminer quelles directives peuvent être placées
        dans les fichiers <code>.htaccess</code>, consultez le
        <a href="mod/directive-dict.html#Context">Contexte</a> de la
        directive. L'administrateur du serveur peut contrôler quelles
        directives peuvent être placées dans les fichiers
        <code>.htaccess</code> en définissant la directive
        <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>
        dans les fichiers de configuration principaux.</p>
    
        <p>Pour plus d'informations sur les fichiers <code>.htaccess</code>,
        se référer au <a href="howto/htaccess.html">tutoriel .htaccess</a>.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/configuring.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dso.html.fr.utf8�����������������������������������������������������������0000664�0001751�0001751�00000054422�14740503670�020012� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Prise en charge des objets dynamiques partagés (DSO) - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Prise en charge des objets dynamiques partagés (DSO)</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>La conception modulaire du serveur HTTP Apache permet à l'administrateur
        de choisir les fonctionnalités à inclure dans le serveur en sélectionnant
        un certain nombre de modules. Les modules seront compilés en tant
        qu'Objets Dynamiques Partagés (Dynamic Shared Objects ou DSOs)
        qui mènent une existence séparée du fichier binaire principal
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>. Les modules DSO peuvent être compilés en
        même temps que le serveur, ou compilés et ajoutés ultérieurement via
        l'Outil des Extensions à Apache (Apache Extension Tool ou
        <code class="program"><a href="./programs/apxs.html">apxs</a></code>).</p>
        <p>Les modules peuvent aussi être intégrés statiquement dans le
        binaire <code class="program"><a href="./programs/httpd.html">httpd</a></code> lors de la compilation de ce
        dernier.</p>
    
        <p>Ce document décrit l'utilisation des modules DSO ainsi que les dessous
        de leur fonctionnement.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#implementation">Implémentation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">Mode d'emploi succinct</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#background">Les dessous du fonctionnement des DSO</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#advantages">Avantages et inconvénients</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">Implémentation</a></h2>
    
    <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>La prise en charge de DSO pour le chargement de modules individuels d'Apache
        httpd est
        assuré par un module nommé <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> qui doit être compilé
        statiquement dans le coeur d'Apache httpd. Il s'agit du seul module avec le
        module <code class="module"><a href="./mod/core.html">core</a></code> à ne pas pouvoir être compilé en tant que
        module DSO lui-même. Pratiquement tous les autres modules d'Apache httpd
        distribués seront alors compilés en tant que modules DSO. Une fois
        compilé en tant que module DSO nommé <code>mod_foo.so</code>, un
        module peut être chargé en mémoire au
        démarrage ou redémarrage du serveur à l'aide de
        la directive <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> du module
        <code class="module"><a href="./mod/mod_so.html">mod_so</a></code> placée
        dans votre fichier <code>httpd.conf</code>.</p>
        <p>La compilation en mode DSO peut être désactivée pour certains
        modules via l'option <code>--enable-mods-static</code> du script
        <code class="program"><a href="./programs/configure.html">configure</a></code>, comme expliqué dans la <a href="install.html">Documentation sur l'installation</a>.</p>
    
        <p>Un utilitaire permet de simplifier la création de
        fichiers DSO pour les modules d'Apache httpd
        (particulièrement pour les modules tiers) ; il s'agit du programme nommé
        <code class="program"><a href="./programs/apxs.html">apxs</a></code> (<dfn>APache
        eXtenSion</dfn>). On peut l'utiliser pour construire des modules de type
        DSO <em>en dehors</em> de l'arborescence des sources d'Apache httpd. L'idée est
        simple : à l'installation du serveur HTTP Apache, la procédure <code>make install</code>
        du script <code class="program"><a href="./programs/configure.html">configure</a></code> installe les fichiers d'en-têtes
        d'Apache httpd et positionne, pour la plateforme de compilation,  les drapeaux du compilateur et de
        l'éditeur de liens à l'intérieur du programme
        <code class="program"><a href="./programs/apxs.html">apxs</a></code> qui sera utilisé pour la construction de fichiers DSO.
        Il est ainsi possible d'utiliser le programme <code class="program"><a href="./programs/apxs.html">apxs</a></code>
        pour compiler ses sources de modules Apache httpd sans avoir besoin de
        l'arborescence des sources de la distribution d'Apache, et sans avoir à
        régler les drapeaux du compilateur et de l'éditeur de liens pour la prise en charge de DSO.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">Mode d'emploi succinct</a></h2>
    
        <p>Afin que vous puissiez vous faire une idée des fonctionnalités DSO
        du serveur HTTP Apache 2.x, en voici un résumé court et concis :</p>
    
        <ol>
          <li>
            <p>Construire et installer un module Apache httpd <em>faisant partie de la
    	distribution</em>, par exemple <code>mod_foo.c</code>,
    	en tant que module DSO <code>mod_foo.so</code> :</p>
    
    <div class="example"><p><code>
    $ ./configure --prefix=/chemin/vers/installation --enable-foo<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
            <p>Configurer le serveur HTTP Apache avec tous les modules
    	activés. Seul un jeu de modules de base sera chargé au
    	démarrage du serveur. Vous pouvez modifier ce jeu de modules
    	chargés au démarrage en activant ou désactivant les directives <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> correspondantes dans le
          fichier <code>httpd.conf</code>.</p>
    
    <div class="example"><p><code>
    $ ./configure --enable-mods-shared=all<br />
    $ make install
    </code></p></div>
    
            <p>L'argument <code>most</code> de l'option
    	<code>--enable-modules</code> indique que tous les modules
    	non-expérimentaux ou qui ne sont pas là à titre d'exemple seront
    	compilés.</p>
          </li>
    
          <li>
          <p>Certains modules ne sont utilisés que par les développeurs et
          ne seront pas compilés. Si vous voulez les utiliser, spécifiez
          l'option <em>all</em>. Pour compiler tous les modules disponibles,
          y compris les modules de développeurs, spécifiez l'option
          <em>reallyall</em>. En outre, la directive <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> peut être activée pour tous
          les modules compilés via l'option du script configure
          <code>--enable-load-all-modules</code>.</p>
    
    <div class="example"><p><code>
    $ ./configure --enable-mods-shared=reallyall --enable-load-all-modules<br />
    $ make install
    </code></p></div>
          </li>
    
          <li>
            Construire et installer un module Apache httpd <em>tiers</em>, par exemple
            <code>mod_foo.c</code>, en tant que module DSO
            <code>mod_foo.so</code> <em>en dehors</em> de l'arborescence des sources
    	d'Apache httpd à l'aide du programme <code class="program"><a href="./programs/apxs.html">apxs</a></code> :
    
    <div class="example"><p><code>
    $ cd /chemin/vers/module_tiers<br />
    $ apxs -cia mod_foo.c
    </code></p></div>
          </li>
        </ol>
    
        <p>Dans tous les cas, une fois le module partagé compilé, vous devez
        ajouter une directive <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        dans le fichier <code>httpd.conf</code> pour qu'Apache httpd active le module.</p>
    
        <p>Voir la <a href="programs/apxs.html">documentation sur apxs</a>
        pour plus de détails.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="background" id="background">Les dessous du fonctionnement des DSO</a></h2>
    
        <p>Les clones modernes d'UNIX proposent un mécanisme
        appelé édition de liens et chargement dynamiques d'
        <em>Objets Dynamiques Partagés</em> (DSO), qui permet de construire un
        morceau de programme dans un format spécial pour le rendre chargeable
        à l'exécution dans l'espace d'adressage d'un programme exécutable.</p>
    
        <p>Ce chargement peut s'effectuer de deux manières : automatiquement par
        un programme système appelé <code>ld.so</code> quand un programme
        exécutable est démarré, ou manuellement à partir du programme en cours
        d'exécution à l’aide de sa propre interface système vers le chargeur Unix à l'aide
        des appels système <code>dlopen()/dlsym()</code>.</p>
    
        <p>Dans la première méthode, les DSO sont en général appelés
        <em>bibliothèques partagées</em> ou encore <em>bibliothèques DSO</em>, et
        possèdent des noms du style
        <code>libfoo.so</code> ou <code>libfoo.so.1.2</code>. Ils résident dans un
        répertoire système (en général <code>/usr/lib</code>)
        et le lien avec le programme exécutable est établi à la compilation en
        ajoutant <code>-lfoo</code> à la commande de l'éditeur de liens. Les
        références à la bibliothèque sont ainsi codées en dur dans le fichier du
        programme exécutable de façon qu'au démarrage du programme, le
        chargeur Unix soit capable de localiser <code>libfoo.so</code> dans
        <code>/usr/lib</code>, dans des chemins codés en dur à l'aide d'options de
        l'éditeur de liens comme <code>-R</code> ou dans des chemins définis par la
        variable d'environnement
        <code>LD_LIBRARY_PATH</code>. Le chargeur peut dès lors résoudre tous les symboles
        (jusque là non encore résolus) du DSO dans le programme exécutable.</p>
    
        <p>Les symboles du programme exécutable ne sont en général pas
        référencés par le DSO (car c'est une bibliothèque de code à usage général
        et réutilisable),
        et ainsi aucune résolution supplémentaire n'est nécessaire. De son côté,
        le programme exécutable ne doit accomplir aucune action particulière
        pour utiliser les
        symboles du DSO car toutes les résolutions sont effectuées par le chargeur
        Unix. En fait, le code permettant d'invoquer
        <code>ld.so</code> fait partie du code de démarrage pour l'exécution qui
        est lié dans tout programme exécutable non statiquement lié.
        L'avantage du chargement dynamique du code d'une bibliothèque partagée est
        évident : le code de la bibliothèque ne doit être stocké qu'une seule fois
        dans une bibliothèque système telle que <code>libc.so</code>, ce qui permet
        d'économiser de l'espace disque pour les autres programmes.</p>
    
        <p>Dans la seconde méthode, les DSO sont en général appelés <em>objets
        partagés</em> ou <em>fichiers DSO</em>, et peuvent être nommés avec
        l'extension de son choix (bien que le nom conseillé soit du style
        <code>foo.so</code>). Ces fichiers résident en général dans un répertoire
        spécifique à un programme, et aucun lien n'est automatiquement établi avec
        le programme exécutable dans lequel ils sont utilisés.
        Le programme exécutable charge manuellement le DSO à l'exécution dans son
        espace d'adressage à l'aide de l'appel système <code>dlopen()</code>.
        A ce moment, aucune résolution de symboles du DSO n'est effectuée pour le
        programme exécutable. Par contre le chargeur Unix
        résoud automatiquement tout symbole du DSO (non encore résolu)
        faisant partie de l'ensemble de symboles exporté par le programme
        exécutable et ses bibliothèques DSO déjà chargées (et en particulier tous
        les symboles de la bibliothèque à tout faire <code>libc.so</code>).
        De cette façon, le DSO prend connaissance de l'ensemble de symboles du
        programme exécutable comme s'il avait été lié statiquement avec lui
        auparavant.</p>
    
        <p>Finalement, pour tirer profit de l'API des DSO, le programme exécutable
        doit résoudre certains symboles du DSO à l'aide de l'appel système
        <code>dlsym()</code> pour une utilisation ultérieure dans les tables de
        distribution, <em>etc.</em> En d'autres termes, le programme exécutable doit
        résoudre manuellement tous les symboles dont il a besoin pour pouvoir les
        utiliser.
        Avantage d'un tel mécanisme : les modules optionnels du programme n'ont pas
        besoin d'être chargés (et ne gaspillent donc pas de ressources mémoire)
        tant qu'il ne sont pas nécessaires au programme en question. Si nécessaire,
        ces modules peuvent être chargés dynamiquement afin d'étendre les
        fonctionnalités de base du programme.</p>
    
        <p>Bien que ce mécanisme DSO paraisse évident, il comporte au moins une
        étape difficile : la résolution des symboles depuis le programme exécutable
        pour le DSO lorsqu'on utilise un DSO pour étendre les fonctionnalités d'un
        programme (la seconde méthode). Pourquoi ? Parce que la «&nbsp;résolution
        inverse&nbsp;» des symboles DSO à partir du jeu de symboles du programme
        exécutable dépend de la conception de la bibliothèque (la bibliothèque n'a
        aucune information sur le programme qui l'utilise) et n'est ni standardisée
        ni disponible sur toutes les plateformes. En pratique, les symboles globaux
        du programme exécutable ne sont en général pas réexportés et donc
        indisponibles pour l'utilisation dans un DSO. Trouver une méthode pour
        forcer l'éditeur de liens à exporter tous les symboles globaux est le
        principal problème que l'on doit résoudre lorsqu'on utilise un DSO pour
        étendre les fonctionnalités d'un programme au moment de son exécution.</p>
    
        <p>L'approche des bibliothèques partagées est la plus courante, parce que
        c'est dans cette optique que le mécanisme DSO a été conçu ; c'est cette
        approche qui est ainsi
        utilisée par pratiquement tous les types de bibliothèques que fournit le
        système d'exploitation.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="advantages" id="advantages">Avantages et inconvénients</a></h2>
    
        <p>Les fonctionnalités ci-dessus basées sur les DSO présentent les
        avantages suivants :</p>
    
        <ul>
          <li>Le paquetage du serveur est plus flexible à l'exécution car le
          processus serveur peut être assemblé à l'exécution via la
          directive <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> du fichier de
          configuration <code>httpd.conf</code> plutôt que par des options du script
          <code class="program"><a href="./programs/configure.html">configure</a></code> à la compilation. Par exemple,
          on peut ainsi exécuter différentes instances du serveur
          (standard et version SSL, version minimale et version dynamique
          [mod_perl, mod_php], <em>etc.</em>) à partir d'une seule installation
          d'Apache httpd.</li>
    
          <li>Le paquetage du serveur peut être facilement étendu avec des modules
          tiers, même après l'installation. Ceci présente un gros
          avantage pour les mainteneurs de paquetages destinés aux distributions,
          car ils peuvent créer un paquetage Apache httpd de base, et des paquetages
          additionnels contenant des extensions telles que PHP, mod_perl, mod_fastcgi,
          <em>etc.</em></li>
    
          <li>Une facilité de prototypage des modules Apache httpd, car la paire
          DSO/<code class="program"><a href="./programs/apxs.html">apxs</a></code> vous permet d'une part de travailler en
          dehors de l'arborescence des sources d'Apache httpd, et d'autre part de n'avoir
          besoin que de la commande <code>apxs -i</code>
          suivie d'un <code>apachectl restart</code> pour introduire une nouvelle
          version de votre module fraîchement développé dans le serveur HTTP Apache
          en cours d'exécution.</li>
        </ul>
    
        <p>Inconvénients des DSO :</p>
    
        <ul>
          <li>Le serveur est environ 20 % plus lent au démarrage
          à cause des résolutions de symboles supplémentaires que le chargeur
          Unix doit effectuer.</li>
    
          <li>Le serveur est environ 5 % plus lent à l'exécution
          sur certaines plates-formes, car le code indépendant de la position (PIC)
          nécessite parfois des manipulations compliquées en assembleur pour
          l'adressage relatif qui ne sont pas toujours aussi rapides que celles
          que permet l'adressage absolu.</li>
    
          <li>Comme les modules DSO ne peuvent pas être liés avec d'autres
          bibliothèques basées sur DSO (<code>ld -lfoo</code>) sur toutes les
          plates-formes
          (par exemple, les plates-formes basées sur a.out ne fournissent en
          général pas cette fonctionnalité alors que les plates-formes basées sur
          ELF le font), vous ne pouvez pas utiliser le mécanisme DSO pour tous les
          types de modules. Ou en d'autres termes, les modules compilés comme
          fichiers DSO sont contraints de n'utiliser que les symboles du coeur
          d'Apache httpd, de la bibliothèque C
          (<code>libc</code>) et toutes autres bibliothèques statiques ou
          dynamiques utilisées par le coeur d'Apache httpd, ou d'archives statiques
          (<code>libfoo.a</code>) contenant du code indépendant de la
          position (PIC).
          Il y a deux solutions pour utiliser un autre type de code : soit le
          coeur d'Apache httpd contient déjà lui-même une référence au code, soit vous
          chargez le code vous-même à l’aide de <code>dlopen()</code>.</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/dso.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dso.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dso.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dso.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dso.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dso.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/filter.html.fr.utf8��������������������������������������������������������0000664�0001751�0001751�00000040014�14740503670�020502� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Filtres - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Filtres</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Ce document décrit l'utilisation des filtres avec Apache.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#intro">Le filtrage avec Apache 2</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#smart">Filtrage intelligent</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#service">Présentation des filtres en tant que service HTTP</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Utilisation des filtres</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">Le filtrage avec Apache 2</a></h2>
        
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code></li><li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></li><li><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code></li><li><code class="module"><a href="./mod/mod_buffer.html">mod_buffer</a></code></li><li><code class="module"><a href="./mod/mod_data.html">mod_data</a></code></li><li><code class="module"><a href="./mod/mod_ratelimit.html">mod_ratelimit</a></code></li><li><code class="module"><a href="./mod/mod_reqtimeout.html">mod_reqtimeout</a></code></li><li><code class="module"><a href="./mod/mod_request.html">mod_request</a></code></li><li><code class="module"><a href="./mod/mod_sed.html">mod_sed</a></code></li><li><code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code></li><li><code class="module"><a href="./mod/mod_xml2enc.html">mod_xml2enc</a></code></li><li><code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_filter.html#filterchain">FilterChain</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterdeclare">FilterDeclare</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprotocol">FilterProtocol</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_reflector.html#reflectorheader">ReflectorHeader</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilteroptions">ExtFilterOptions</a></code></li><li><code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code></li><li><code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code></li></ul></td></tr></table>
    
    <p>La chaîne de filtrage est disponible depuis la version 2.0 d'Apache,
    et permet aux applications de traiter les données en entrée et en sortie
    d'une manière hautement flexible et configurable, quelle que soit la
    provenance de ces données.  Il est possible de pré-traiter les données
    en entrée, et post-traiter les données en sortie, selon
    vos souhaits.
    Ces traitements sont tout à fait indépendants des traditionnelles phases
    de traitement des requêtes.</p>
    <p class="figure">
    <img src="images/filter_arch.png" width="569" height="392" alt="les filtres peuvent s'enchaîner, perpendiculairement au traitement des requêtes" />
    </p>
    <p>Voici quelques exemples de filtrage avec la distribution standard d'Apache:</p>
    <ul>
    <li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code>, implémente les inclusions côté serveur.</li>
    <li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>, implémente le cryptage SSL (https).</li>
    <li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code>, implémente la compression/décompression
    à la volée.</li>
    <li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code>, transcodage entre différents
    jeux de caractères.</li>
    <li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>, utilisation d'un programme externe
    comme filtre.</li>
    </ul>
    <p>Apache utilise aussi plusieurs filtres en interne pour accomplir des tâches
    comme le découpage des grosses requêtes (chunking) et la gestion des
    requêtes portant sur une partie d'un fichier (byte-range).</p>
    
    <p>Un grand choix d'applications sont implémentées par des modules de filtrage
    tiers. En voici quelques exemples :</p>
    
    <ul>
    <li>Traitement et réécriture HTML et XML</li>
    <li>Transformations XSLT et inclusions XML (XIncludes)</li>
    <li>Support de l'espace de nommage XML</li>
    <li>Gestion du chargement de fichier et décodage des formulaires HTML</li>
    <li>Traitement d'image</li>
    <li>Protection des applications vulnérables comme les scripts PHP</li>
    <li>Edition de texte par Chercher/Remplacer</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="smart" id="smart">Filtrage intelligent</a></h2>
    
    <p class="figure">
    <img src="images/mod_filter_new.png" width="423" height="331" alt="Le filtrage intelligent applique différents fournisseurs de filtrage en fonction de l'état du traitement de la requête" />
    </p>
    <p><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>, inclus dans les version 2.1 et supérieures
    d'Apache, permet de configurer la chaîne de filtrage dynamiquement
    à l'exécution.
    Ainsi par exemple, vous pouvez définir un proxy pour réécrire du code HTML
    avec un filtre HTML et traiter des images JPEG avec un filtre totalement
    séparé, bien que le proxy ne possède aucune information préliminaire
    sur ce que le serveur à l'origine des données à filtrer va envoyer.
    Ceci fonctionne grâce à l'utilisation d'un gestionnaire de filtre,
    qui distribue les tâches à différents fournisseurs de filtrage en fonction
    du contenu réel à filtrer à l'exécution.  Tout filtre peut se voir soit
    inséré directement dans la chaîne et lancé inconditionnellement, soit
    utilisé comme un fournisseur de filtrage et inséré dynamiquement.
    Par exemple,</p>
    <ul>
    <li>un filtre de traitement HTML sera lancé uniquement si le contenu est
    de type text/html ou application/xhtml+xml</li>
    <li>Un filtre de compression sera lancé uniquement si les données en entrée
    sont de type compressible et non déjà compressées</li>
    <li>Un filtre de conversion de jeux de caractères ne sera inséré que si
    le document texte n'est pas déjà dans le jeu de caractères voulu</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="service" id="service">Présentation des filtres en tant que service HTTP</a></h2>
    
    
    <p>Les filtres permettent de traiter les requêtes des clients avant
    traitement par le serveur, ainsi que les contenus issus du serveur avant de les renvoyer
    au client. Le module <code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code> permet aussi
    d'utiliser les filtres pour traiter les requêtes des clients avant de
    les renvoyer directement à ces derniers.</p>
    
    <p>Le module <code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code> reçoit les requêtes POST des
    clients, et en répercute le corps dans la requête POST constituant la
    réponse, lors de l'envoi de cette dernière au client en passant à travers la
    pile de filtres en sortie.</p>
    
    <p>Cette technique peut être utilisée comme alternative à un service web
    s'exécutant à l'intérieur de la pile d'un serveur d'applications, où un
    filtre en sortie effectue la transformation requise sur le corps de la
    requête. Par exemple, on peut utiliser le module
    <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> pour fournir un service général de
    compression ; un filtre de transformation d'images peut aussi se voir
    mué en service de transformation d'images.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Utilisation des filtres</a></h2>
    
    <p>Il y a deux manières d'utiliser le filtrage : Simple et Dynamique.
    En général, vous utiliserez l'une ou l'autre méthode; le mélange des deux
    peut avoir des conséquences inattendues (bien que le filtrage simple en entrée
    puisse être associé sans problème avec le filtrage simple ou dynamique
    en sortie).</p>
    <p>La méthode Simple est la seule permettant de configurer les filtres
    en entrée, et suffit pour les filtres en sortie pour lesquels vous avez besoin
    d'une chaîne de filtres statique.
    Les directives correspondantes sont
        <code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code>,
        <code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code>, et
        <code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code>.</p>
    
    <p>La méthode Dynamique permet une configuration dynamique des filtres en
    sortie à la fois statique et flexible, comme discuté dans la page
    <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>.
    Les directives correspondantes sont
        <code class="directive"><a href="./mod/mod_filter.html#filterchain">FilterChain</a></code>,
        <code class="directive"><a href="./mod/mod_filter.html#filterdeclare">FilterDeclare</a></code>, et
        <code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code>.</p>
    
    <p>Une autre directive <code class="directive"><a href="./mod/mod_filter.html#addoutputfilterbytype">AddOutputFilterByType</a></code> est encore supportée,
    mais obsolète. Utilisez la
    configuration dynamique à la place.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/filter.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/filter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.fr.utf8���������������������������������������������������������0000664�0001751�0001751�00000022735�14740503670�020336� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Documentation du Serveur HTTP Apache Version 2.4
     - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a></div>
    <div id="page-content"><h1>Documentation du Serveur HTTP Apache Version 2.4
    </h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Recherche Google" type="submit" /><input value="10" name="num" type="hidden" /><input value="fr" name="hl" type="hidden" /><input value="UTF-8" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Version 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">Notes de version</a></h2>
    <ul><li><a href="new_features_2_4.html">Nouvelles fonctionnalités dApache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Nouvelles fonctionnalités d'Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html.fr">Nouvelles fonctionnalités d'Apache 2.0</a></li>
    <li><a href="upgrading.html">Mise à jour de la version 2.2 vers la version 2.4</a></li>
    <li><a href="license.html">Licence Apache</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">Manuel de référence</a></h2>
    <ul><li><a href="install.html">Compilation et installation</a></li>
    <li><a href="invoking.html">Démarrage</a></li>
    <li><a href="stopping.html">Arrêt ou redémarrage</a></li>
    <li><a href="mod/quickreference.html">Directives de configuration à l'exécution</a></li>
    <li><a href="mod/">Modules</a></li>
    <li><a href="mpm.html">Modules multi-processus (MPMs)</a></li>
    <li><a href="filter.html">Filtres</a></li>
    <li><a href="handler.html">Gestionnaires</a></li>
    <li><a href="expr.html">Interpréteur d'expressions</a></li>
    <li><a href="mod/overrides.html">Index des directives disponibles dans les
        fichiers .htaccess</a></li>
    <li><a href="programs/">Le serveur et ses utilitaires</a></li>
    <li><a href="glossary.html">Glossaire</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">Guide de l'utilisateur</a></h2>
    <ul><li><a href="getting-started.html">Bien démarrer</a></li>
    <li><a href="bind.html">Ecoute sélective</a></li>
    <li><a href="configuring.html">Fichiers de configuration</a></li>
    <li><a href="sections.html">Sections de configuration</a></li>
    <li><a href="caching.html">Mise en cache du contenu</a></li>
    <li><a href="content-negotiation.html">Négociation sur le contenu</a></li>
    <li><a href="dso.html">Objets Dynamiques Partagés (DSO)</a></li>
    <li><a href="env.html">Variables d'environnement</a></li>
    <li><a href="logs.html">Fichiers de traces</a></li>
    <li><a href="urlmapping.html">Mise en correspondance des URLs avec le système de fichiers</a></li>
    <li><a href="misc/perf-tuning.html">Optimisation des performances</a></li>
    <li><a href="misc/security_tips.html">Conseils sur la sécurité</a></li>
    <li><a href="server-wide.html">Configuration à l'échelle du serveur</a></li>
    <li><a href="ssl/">Chiffrement SSL/TLS</a></li>
    <li><a href="suexec.html">Exécution des CGI avec suexec</a></li>
    <li><a href="rewrite/">Réécriture des URLs avec mod_rewrite</a></li>
    <li><a href="vhosts/">Hôtes virtuels</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">Recettes / Tutoriels</a></h2>
    <ul><li><a href="howto/auth.html">Authentification et autorisation</a></li>
    <li><a href="howto/access.html">Contrôle d'accès</a></li>
    <li><a href="howto/cgi.html">CGI: Contenu dynamique</a></li>
    <li><a href="howto/htaccess.html">Fichiers .htaccess</a></li>
    <li><a href="howto/ssi.html">Server Side Includes (SSI)</a></li>
    <li><a href="howto/public_html.html">Répertoires Web des utilisateurs (public_html)</a></li>
    <li><a href="howto/reverse_proxy.html">Guide de configuration des mandataires
        inverses</a></li>
    <li><a href="howto/http2.html">Guide HTTP/2</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">Notes spécifiques aux différentes plateformes</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">Systèmes basés sur les paquet RPM (Redhat / CentOS / Fedora)</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">Portage EBCDIC</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">Autres sujets</a></h2>
    <ul><li><a href="http://wiki.apache.org/httpd/FAQ">Foire Aux Questions</a></li>
    <li><a href="sitemap.html">Plan du site</a></li>
    <li><a href="developer/">Documentation du développeur</a></li>
    <li><a href="http://httpd.apache.org/docs-project/">Aide pour la
        documentation</a></li>
    <li><a href="misc/">Autres notes</a></li>
    <li><a href="http://wiki.apache.org/httpd/">Wiki</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������httpd-2.4.64/docs/manual/mpm.html.fr.utf8�����������������������������������������������������������0000664�0001751�0001751�00000034576�14740503670�020026� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Modules multi-processus (MPMs) - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Modules multi-processus (MPMs)</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>Ce document décrit ce qu'est un Module Multi-Processus, ainsi
    que la manière dont ces modules sont utilisés par le serveur HTTP Apache.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#defaults">MPM par défaut</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#static">Compiler un module MPM en tant que module
    statique</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#dynamic">Compiler un module MPM en tant que module
    DSO (Dynamic Shared Object)</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    
        <p>La conception du serveur HTTP Apache en fait un serveur web puissant et
        flexible pouvant fonctionner sur une très grande variété de
        plateformes et toute une gamme d'environnements différents. Plateformes
        différentes et environnements différents signifient souvent fonctionnalités
        différentes, ou utilisation de différentes méthodes pour
        implémenter la même fonctionnalité le plus efficacement possible.
        Apache httpd s'est toujours accomodé d'une grande variété d'environnements
        grâce à sa conception modulaire. Cette conception autorise le webmaster
        à choisir quelles fonctionnalités seront incluses
        dans le serveur en sélectionnant les modules à charger soit à la
        compilation, soit à l'exécution.</p>
    
        <p>Le serveur HTTP Apache 2.0 a étendu cette conception modulaire aux
        fonctions les plus
        élémentaires d'un serveur web. Le serveur est fourni avec une variété de
        Modules Multi-Processus (MPMs) qui
        sont responsables de l'association aux ports réseau de la machine,
        acceptent les requêtes, et se chargent de répartir ces dernières
        entre les différents processus enfants.</p>
    
        <p>L'extension de la conception modulaire à ce niveau du serveur
        comporte deux avantages importants :</p>
    
        <ul>
          <li>Apache httpd peut supporter plus proprement et efficacement une grande
          variété de systèmes d'exploitation. En particulier, la version Windows
          du serveur est maintenant beaucoup plus efficace, depuis que
          <code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code> peut utiliser les fonctionnalités réseau
          natives à la place de la couche POSIX utilisée par
          Apache httpd 1.3. Cet avantage s'étend aussi aux systèmes d'exploitation
          qui implémentent des MPMs spécialisés.</li>
    
          <li>le serveur est plus à même de répondre aux besoins d'un site
          particulier. Par exemple, les sites qui sont très sollicités peuvent
          utiliser un MPM threadé comme
          <code class="module"><a href="./mod/worker.html">worker</a></code> ou <code class="module"><a href="./mod/event.html">event</a></code>, tandis que les sites
          qui privilégient la stabilité ou la compatibilité avec des logiciels
          plus anciens peuvent utiliser un module comme
          <code class="module"><a href="./mod/prefork.html">prefork</a></code>.</li>
        </ul>
    
        <p>Du point de vue de l'utilisateur, les MPMs ne sont pas différents des
        autres modules Apache httpd. La principale différence réside dans le fait qu'un
        et un seul MPM à la fois doit être chargé
        lorsque le serveur s'exécute. La liste des
        MPMs disponibles est fournie dans <a href="mod/">l'index des
        modules</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="defaults" id="defaults">MPM par défaut</a></h2>
    
    <p>La table suivante fournit la liste des MPMs par défaut pour divers
    systèmes d'exploitation.  Il s'agit du MPM qui sera utilisé si
    vous n'en spécifiez pas un autre à la compilation.</p>
    
    <table class="bordered"><tr><td>Netware</td><td><code class="module"><a href="./mod/mpm_netware.html">mpm_netware</a></code></td></tr>
    <tr class="odd"><td>OS/2</td><td><code class="module"><a href="./mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
    <tr><td>Unix</td><td><code class="module"><a href="./mod/prefork.html">prefork</a></code>, <code class="module"><a href="./mod/worker.html">worker</a></code>,
    ou <code class="module"><a href="./mod/event.html">event</a></code>, selon les possibilités de la plate-forme</td></tr>
    <tr class="odd"><td>Windows</td><td><code class="module"><a href="./mod/mpm_winnt.html">mpm_winnt</a></code></td></tr>
    </table>
    
    <div class="note"><p>Ici, 'Unix' sous-entend les systèmes d'exploitation de type
    Unix, comme Linux, BSD, Solaris, Mac OS X, etc...</p></div>
    
    <p>Dans le cas des systèmes d'exploitation de type Unix, le choix du MPM
    à installer est orienté par deux questions :</p>
    <p>1. Est-ce que le système supporte les threads ?</p>
    <p>2. Est-ce que le système supporte le polling thread-safe (et en
    particulier les fonctions kqueue et epoll) ?</p>
    
    <p>Si la réponse aux deux questions est 'oui', le MPM par défaut sera
    <code class="module"><a href="./mod/event.html">event</a></code>.</p>
    
    <p>Si la réponse à la première question est 'oui', et la réponse à la
    deuxième 'non', le MPM par défaut sera <code class="module"><a href="./mod/worker.html">worker</a></code>.</p>
    
    <p>Si la réponse aux deux questions est 'non', le MPM par défaut sera
    <code class="module"><a href="./mod/prefork.html">prefork</a></code>.</p>
    
    <p>En pratique, cela signifie que le MPM par défaut sera presque
    toujours <code class="module"><a href="./mod/event.html">event</a></code> car tous les systèmes d'exploitation
    modernes satisfont aux deux conditions.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="static" id="static">Compiler un module MPM en tant que module
    statique</a></h2>
    
        <p>Les modules MPM peuvent être compilés en tant que modules
    statiques sur toutes les plates-formes. A la compilation d'Apache, un
    seul module MPM doit être choisi pour être compilé et lié avec le
    serveur. La recompilation du serveur sera donc nécessaire si vous
    souhaitez changer de module MPM.</p>
    
        <p>Pour choisir un module MPM autre que le MPM par défaut,
        utiliser l'argument
          <code>--with-mpm=<em>NOM</em></code> du script
          <code class="program"><a href="./programs/configure.html">configure</a></code>. <em>NOM</em> est le nom
          du MPM désiré.</p>
    
        <p>Une fois le serveur compilé, il est possible de savoir quel MPM
        a été choisi à l'aide de la commande <code>./httpd -l</code>.
        Cette commande fournit la liste de tous les modules compilés
        avec le serveur, y compris le MPM.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dynamic" id="dynamic">Compiler un module MPM en tant que module
    DSO (Dynamic Shared Object)</a></h2>
    
        <p>Sous Unix et les plates-formes similaires, les modules MPM
        peuvent être compilés en tant que modules DSO et chargés
        dynamiquement dans le serveur comme tout module DSO. Compiler les
        modules MPM en tant que modules DSO permet de changer de MPM en
        modifiant la directive <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> concernée, sans avoir à
        recompiler le serveur.</p>
    
        <pre class="prettyprint lang-config">LoadModule mpm_prefork_module modules/mod_mpm_prefork.so</pre>
    
    
        <p>Toute tentative de charger plusieurs modules MPM via la directive
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> empêchera le
        serveur de démarrer et affichera l'erreur suivante :</p>
    
        <div class="example"><p><code>AH00534: httpd: Configuration error: More than one MPM
        loaded.</code></p></div>
    
        <p>Cette fonctionnalité est activée via l'option
        <code>--enable-mpms-shared</code> du script
        <code class="program"><a href="./programs/configure.html">configure</a></code>. Si on ajoute l'argument
        <code><em>all</em></code>, tous les modules MPM disponibles sur la
        plate-forme considérée seront installés. Cet argument peut aussi
        contenir une liste de modules MPM à installer.</p>
    
        <p>Le module MPM par défaut, sélectionné automatiquement ou spécifié
        via l'option <code>--with-mpm</code> du script
        <code class="program"><a href="./programs/configure.html">configure</a></code>, sera chargé via une directive
        <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> du fichier de
        configuration du serveur généré. Pour choisir un autre module MPM,
        vous devrez donc modifier cette directive</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/mpm.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/mpm.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/mpm.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/mpm.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/mpm.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/mpm.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/mpm.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/mpm.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/mpm.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sections.html.fr.utf8������������������������������������������������������0000664�0001751�0001751�00000123453�14740503670�021055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Sections de configuration - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Sections de configuration</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
     <p>Les directives des <a href="configuring.html">fichiers de configuration</a> peuvent s'appliquer
    au serveur dans son ensemble, ou seulement à des répertoires, fichiers, hôtes,
    ou URLs particuliers.  Ce document décrit comment utiliser les conteneurs de
    sections de configuration ou les fichiers <code>.htaccess</code> pour
    modifier la portée des directives de configuration.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#types">Types de conteneurs de sections de
    configuration</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-and-web">Système de fichiers,
    arborescence du site web et expressions booléennes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Serveurs virtuels</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Mandataire</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#whatwhere">Quelles sont les directives autorisées&nbsp;?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#merging">Comment les sections sont combinées entre elles</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="types" id="types">Types de conteneurs de sections de
    configuration</a></h2>
    
    <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mod_version.html">mod_version</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_md.html#mdomainsetsection">&lt;MDomainSet&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
    <p>Il existe deux grands types de conteneurs. La plupart des conteneurs sont
    évalués pour chaque requête. Les directives qu'ils contiennent s'appliquent
    seulement aux requêtes qui sont concernées par le conteneur. En revanche,
    les conteneurs
    <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>, <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> et
    <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code> sont
    évalués seulement au démarrage et au redémarrage du serveur.
    Si leurs conditions sont vérifiées au démarrage, les directives qu'ils contiennent
    s'appliqueront à toutes les requêtes. Si leurs conditions ne sont pas vérifiées, les
    directives qu'ils contiennent seront ignorées.</p>
    
    <p>Le conteneur <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>
    contient des directives qui ne seront appliquées que si un paramètre
    approprié a été défini dans la ligne de commande de <code class="program"><a href="./programs/httpd.html">httpd</a></code>.
    Par exemple,
    avec la configuration suivante, toutes les requêtes seront redirigées vers
    un autre site si le serveur est démarré en utilisant la ligne de commande&nbsp;:
    <code>httpd -DClosedForNow</code>&nbsp;:</p>
    
    <pre class="prettyprint lang-config">&lt;IfDefine ClosedForNow&gt;
        Redirect "/" "http://otherserver.example.com/"
    &lt;/IfDefine&gt;</pre>
    
    
    <p>Le conteneur <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>
    est similaire&nbsp;; les directives qu'il contient ne s'appliqueront que si
    un module particulier est disponible au niveau du serveur.
    Le module doit être soit compilé statiquement dans le serveur, soit
    dynamiquement et dans ce cas, la ligne <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> correspondante doit apparaître
    plus haut dans le fichier de configuration. Ce conteneur ne doit être
    utilisé que dans le cas où votre fichier de configuration doit être valable
    indépendamment de la présence ou de l'absence de certains modules.
    Il ne doit pas contenir de directives que vous souhaitez voir s'appliquer
    systématiquement, car vous pouvez perdre ainsi de précieux messages d'erreur
    à propos de modules manquants.</p>
    
    <p>Dans l'exemple suivant, la directive <code class="directive"><a href="./mod/mod_mime_magic.html#mimemagicfile">MimeMagicFile</a></code> ne s'appliquera que si le
    module <code class="module"><a href="./mod/mod_mime_magic.html">mod_mime_magic</a></code> est disponible.</p>
    
    <pre class="prettyprint lang-config">&lt;IfModule mod_mime_magic.c&gt;
        MimeMagicFile "conf/magic"
    &lt;/IfModule&gt;</pre>
    
    
    <p>Le conteneur
    <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
    est similaire aux conteneurs <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> et <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>&nbsp;; les directives qu'il contient ne
    s'appliqueront que si une version particulière du serveur s'exécute. Ce
    conteneur a été conçu pour une utilisation dans les suites de tests
    et les grands réseaux qui doivent prendre en compte différentes versions
    et configurations de httpd.</p>
    
    <pre class="prettyprint lang-config">&lt;IfVersion &gt;= 2.4&gt;
        # les directives situées ici ne s'appliquent que si la version <br />
        # est supérieure ou égale à 2.4.0.
    &lt;/IfVersion&gt;</pre>
    
    
    <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> et
    <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
    peuvent inverser leur test conditionnel en le faisant précéder d'un &nbsp;«&nbsp;!&nbsp;».
    De plus, ces sections peuvent être imbriquées afin de définir des restrictions
    plus complexes.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-and-web" id="file-and-web">Système de fichiers,
    arborescence du site web et expressions booléennes</a></h2>
    
    <p>Les conteneurs de sections de configuration les plus couramment utilisés
    sont ceux qui modifient la configuration de points particuliers du système de
    fichiers ou de l'arborescence du site web. Tout d'abord, il est important de
    comprendre la différence entre les deux. Le système de fichiers est une vue de
    vos disques tels qu'ils sont perçus par votre système d'exploitation.  Par
    exemple, avec une installation par défaut, Apache httpd est situé dans
    <code>/usr/local/apache2</code> pour le système de fichiers UNIX, ou
    <code>"c:/Program Files/Apache Group/Apache2"</code> pour le système de
    fichiers Windows (notez que des slashes directs doivent toujours être utilisés
    comme séparateur de chemin dans les fichiers de configuration d'Apache httpd,
    même sous Windows). Quant à l'arborescence du site web, il s'agit d'une vue de
    votre site telle que présentée par le serveur web et perçue par le client.
    Ainsi le chemin <code>/dir/</code> dans l'arborescence du site web correspond
    au chemin <code>/usr/local/apache2/htdocs/dir/</code> dans le système de
    fichiers pour une installation d'Apache httpd par défaut sous UNIX.  En outre,
    l'arborescence du site web n'a pas besoin de correspondre en permanence au
    système de fichiers, car les pages web peuvent être générées dynamiquement à
    partir de bases de données ou d'autres emplacements.</p>
    
    <h3><a name="filesystem" id="filesystem">Conteneurs de système de fichiers</a></h3>
    
    <p>Les conteneurs <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    et <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>,
    ainsi que leurs équivalents acceptant les
    <a class="glossarylink" href="./glossary.html#regex" title="voir glossaire">expressions rationnelles</a>,
    appliquent des directives à certaines parties du système de fichiers.
    Les directives contenues dans une section <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> s'appliquent au répertoire
    précisé, ainsi qu'à tous ses sous-répertoires et aux fichiers que ces
    derniers contiennent.
    Le même effet peut être obtenu en utilisant les <a href="howto/htaccess.html">fichiers .htaccess</a>. Par exemple, avec la
    configuration suivante, l'indexation sera activée pour le répertoire
    <code>/var/web/dir1</code> et tous ses sous-répertoires.</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/web/dir1"&gt;
        Options +Indexes
    &lt;/Directory&gt;</pre>
    
    
    <p>Les directives contenues dans une section <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> s'appliquent à tout fichier
    avec le nom spécifié, quel que soit le répertoire dans lequel il se trouve.
    Ainsi par exemple, les directives de configuration suivantes, si elles sont
    placées dans la section principale du fichier de configuration, vont interdire
    l'accès à tout fichier nommé <code>private.html</code> quel que soit
    l'endroit où il se trouve.</p>
    
    <pre class="prettyprint lang-config">&lt;Files "private.html"&gt;
        Require all denied
    &lt;/Files&gt;</pre>
    
    
    <p>Pour faire référence à des fichiers qui se trouvent en des points
    particuliers du système de fichiers, les sections
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> et
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    peuvent être combinées. Par exemple, la configuration suivante va interdire
    l'accès à <code>/var/web/dir1/private.html</code>,
    <code>/var/web/dir1/subdir2/private.html</code>,
    <code>/var/web/dir1/subdir3/private.html</code>, ainsi que toute instance de
    <code>private.html</code> qui se trouve dans l'arborescence
    <code>/var/web/dir1/</code>.</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/web/dir1"&gt;
        &lt;Files "private.html"&gt;
            Require all denied
        &lt;/Files&gt;
    &lt;/Directory&gt;</pre>
    
    
    
    <h3><a name="webspace" id="webspace">Conteneurs de l'arborescence du site web</a></h3>
    
    <p>le conteneur <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    et son équivalent acceptant les
    <a class="glossarylink" href="./glossary.html#regex" title="voir glossaire">expressions rationnelles</a> modifient quant à eux la
    configuration de parties de l'arborescence du site web. Par exemple, la
    configuration suivante interdit l'accès à toute URL dont la partie chemin
    commence par /private.
    En particulier, l'interdiction s'appliquera aux requêtes pour :
    <code>http://yoursite.example.com/private</code>,
    <code>http://yoursite.example.com/private123</code>, et
    <code>http://yoursite.example.com/private/dir/file.html</code> ainsi qu'à
    toute requête commençant par la chaîne de caractères <code>/private</code>.</p>
    
    <pre class="prettyprint lang-config">&lt;LocationMatch "^/private"&gt;
        Require all denied
    &lt;/LocationMatch&gt;</pre>
    
    
    <p>Le conteneur <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    n'a pas besoin de faire référence à un élément du système de fichiers.
    À ce titre, l'exemple suivant montre comment faire correspondre une URL
    particulière à un gestionnaire interne du serveur HTTP Apache fourni par le module
    <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>.
    Il n'est pas nécessaire de trouver un fichier nommé <code>server-status</code>
    dans le système de fichiers.</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/server-status"&gt;
        SetHandler server-status
    &lt;/Location&gt;</pre>
    
    
    
    <h3><a name="overlapping-webspace" id="overlapping-webspace">Espace web imbriqué</a></h3>
    <p>Pour contrôler deux URLs imbriquées, on doit tenir compte de l'ordre
    dans lequel certaines sections ou directives sont évaluées. Pour
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, on doit
    avoir&nbsp;:</p>
    <pre class="prettyprint lang-config">&lt;Location "/foo"&gt;
    &lt;/Location&gt;
    &lt;Location "/foo/bar"&gt;
    &lt;/Location&gt;</pre>
    
    <p>Les directives <code class="directive"><a href="./mod/mod_alias.html#alias">&lt;Alias&gt;</a></code>, quant à elles, sont évaluées vice-versa&nbsp;:</p>
    <pre class="prettyprint lang-config">Alias "/foo/bar" "/srv/www/uncommon/bar"
    Alias "/foo" "/srv/www/common/foo"</pre>
    
    <p>Ceci est aussi vrai pour les directives <code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code>&nbsp;:</p>
    <pre class="prettyprint lang-config">ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
    ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On</pre>
    
    
    
    
    <h3><a name="wildcards" id="wildcards">Caractères de remplacement
    et expressions rationnelles</a></h3>
    
    <p>Les conteneurs <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> et <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> peuvent utiliser des caractères de
    remplacement de style shell comme dans la fonction <code>fnmatch</code> de la
    bibliothèque C standard.  Le caractère «&nbsp;*&nbsp;» correspond à toute séquence de
    caractères, «&nbsp;?&nbsp;» à un caractère seul, et «&nbsp;[<em>seq</em>]&nbsp;» à tout caractère
    contenu dans <em>seq</em>.  Le caractère «&nbsp;/&nbsp;» ne peut pas faire l'objet d'un
    remplacement&nbsp;; il doit être spécifié explicitement.</p>
    
    <p>Si une définition des critères de correspondance encore plus souple est
    nécessaire, chaque conteneur possède son équivalent acceptant les expressions
    rationnelles&nbsp;: <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code> et <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> acceptent les <a class="glossarylink" href="./glossary.html#regex" title="voir glossaire">expressions rationnelles</a> compatibles Perl pour définir
    les critères de correspondance. Mais voyez plus loin la section à propos de la
    combinaison des sections de configuration pour comprendre comment l'utilisation
    de conteneurs avec des expressions rationnelles va modifier la manière dont les
    directives sont appliquées.</p>
    
    <p>Un conteneur qui modifie la configuration de tous les répertoires
    utilisateurs à l'aide de caractères de remplacement mais sans utiliser les
    expressions rationnelles pourrait ressembler à ceci&nbsp;:</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html"&gt;
        Options Indexes
    &lt;/Directory&gt;</pre>
    
    
    <p>Avec les conteneurs utilisant les expressions rationnelles,
    on peut interdire l'accès à de nombreux types de fichiers d'images
    simultanément&nbsp;:</p>
    <pre class="prettyprint lang-config">+&lt;FilesMatch "\.(?i:gif|jpe?g|png)$"&gt;
        Require all denied
    &lt;/FilesMatch&gt;</pre>
    
    
    <p>Les expressions rationnelles contenant des <strong>groupes nommés et
    des références arrières</strong> sont ajoutées à l'environnement avec
    leur nom en majuscules. Cela permet de référencer des éléments de
    chemins de fichiers et d'URLs depuis une <a href="expr.html">expression</a> et au sein de modules comme
    <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    <pre class="prettyprint lang-config">&lt;DirectoryMatch "^/var/www/combined/(?&lt;SITENAME&gt;[^/]+)"&gt;
        Require ldap-group "cn=%{env:MATCH_SITENAME},ou=combined,o=Example"
    &lt;/DirectoryMatch&gt;</pre>
    
    
    
    
    <h3><a name="expressions" id="expressions">Expressions booléennes</a></h3>
    <p>La directive <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>
    permet de modifier la configuration en fonction d'une condition qui peut
    être définie sous la forme d'une expression booléenne. Dans l'exemple
    suivant, l'accès est interdit si l'en-tête HTTP Referer ne commence pas
    par «&nbsp;http://www.example.com/&nbsp;».</p>
    <pre class="prettyprint lang-config">&lt;If "!(%{HTTP_REFERER} -strmatch 'http://www.example.com/*')"&gt;
        Require all denied
    &lt;/If&gt;</pre>
    
    
    
    
    <h3><a name="whichwhen" id="whichwhen">Que faut-il utiliser et quand ?</a></h3>
    
    <p>Choisir entre des conteneurs de système de fichiers et des conteneurs
    d'arborescence du site web est vraiment très simple.
    Pour appliquer des directives à des objets qui résident dans le système de
    fichiers, utilisez toujours un conteneur <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> ou <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>. Pour appliquer des directives à des objets
    qui ne résident pas dans le système de fichiers (comme une page web générée
    par une base de données), utilisez un conteneur <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>.</p>
    
    <p>Il ne faut jamais utiliser un conteneur <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> pour restreindre l'accès à des
    objets du système de fichiers, car plusieurs emplacements de
    l'arborescence du site web (URLs) peuvent correspondre au même emplacement
    du système de fichier, ce qui peut permettre de contourner vos restrictions.
    Par exemple, imaginez la configuration suivante :</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/dir/"&gt;
        Require all denied
    &lt;/Location&gt;</pre>
    
    
    <p>Elle fonctionne correctement si la requête appelle
    <code>http://yoursite.example.com/dir/</code>. Mais que va-t-il se passer si
    votre système de fichiers est insensible à la casse&nbsp;?  Votre restriction va
    pouvoir être tout simplement contournée en envoyant une requête sur
    <code>http://yoursite.example.com/DIR/</code>. Le conteneur <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, quant à lui, s'appliquera à
    tout contenu servi à partir de cet emplacement, sans tenir compte de la manière
    dont il est appelé.  Les liens du système de fichiers constituent une exception.
    Le même répertoire peut être placé dans plusieurs parties du système de fichiers
    en utilisant des liens symboliques. Le conteneur <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> va suivre le lien symbolique sans modifier
    le nom du chemin. Par conséquent, pour plus de sécurité, les liens symboliques
    doivent être désactivés à l'aide de la directive <code class="directive"><a href="./mod/core.html#options">Options</a></code> appropriée.</p>
    
    <p>Si vous pensez que vous n'êtes pas concerné par ce problème
    parce que vous utilisez un système de fichiers sensible à la casse,
    gardez à l'esprit qu'il y a de nombreuses autres manières pour faire
    correspondre plusieurs emplacements de l'arborescence du site web au même
    emplacement du système de fichiers. C'est pourquoi vous devez autant que
    possible toujours utiliser les conteneurs de système de fichiers.
    Il y a cependant une exception à cette règle. Placer des restrictions de
    configuration dans un conteneur <code>&lt;Location
    "/"&gt;</code> est absolument sans rique car ce conteneur va s'appliquer à
    toutes les requêtes sans tenir compte de l'URL spécifique.</p>
    
    
    <h3><a name="nesting" id="nesting">Imbrication des sections</a></h3>
    
    <p>Certains types de sections peuvent être imbriqués&nbsp;: d'une part, on peut
    utiliser les sections <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    à l'intérieur des sections <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, d'autre part, on peut utiliser les
    directives <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> à l'intérieur
    des sections <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> et <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> (mais pas à l'intérieur d'une
    autre section <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>). Les
    valeurs des expressions rationnelles correspondant aux sections citées se
    comportent de manière identique.</p>
    
    <p>Les sections imbriquées sont fusionnées après les sections
    non-imbriquées de même type.</p>
    
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Serveurs virtuels</a></h2>
    
    <p>Le conteneur <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
    contient des directives qui s'appliquent à des serveurs virtuels spécifiques.
    Cela s'avère utile pour servir les contenus de plusieurs serveurs virtuels à
    partir de la même machine, chacun d'entre eux possédant une configuration
    différente. Pour de plus amples informations, voir la <a href="vhosts/">Documentation sur les serveurs virtuels</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Mandataire</a></h2>
    
    <p>Les conteneurs
    <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
    et <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
    appliquent les directives de configuration qu'ils contiennent uniquement aux
    sites qui correspondent à l'URL spécifiée et auxquels on a
    accédé à l'aide du serveur mandataire du module <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.
    Par exemple, la configuration suivante n'autorisera qu'un sous-ensemble de
    clients à accéder au site <code>www.example.com</code> en passant par le serveur
    mandataire&nbsp;:</p>
    
    <pre class="prettyprint lang-config">&lt;Proxy "http://www.example.com/*"&gt;
        Require host yournetwork.example.com
    &lt;/Proxy&gt;</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="whatwhere" id="whatwhere">Quelles sont les directives autorisées&nbsp;?</a></h2>
    
    <p>Pour déterminer quelles sont les directives autorisées pour tel type de
    section de configuration, vérifiez le <a href="mod/directive-dict.html#Context">Contexte</a> de la directive.
    Tout ce qui est autorisé dans les sections
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    l'est aussi d'un point de vue syntaxique dans les sections
    <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
    et <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>.
    Il y a cependant quelques exceptions&nbsp;:</p>
    
    <ul>
    <li>La directive <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>
    ne fonctionne que dans les sections
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>.</li>
    
    <li>Les <code class="directive"><a href="./mod/core.html#options">Options</a></code> <code>FollowSymLinks</code> et
    <code>SymLinksIfOwnerMatch</code> ne fonctionnent que dans les sections
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> ou les fichiers
    <code>.htaccess</code>.</li>
    
    <li>La directive <code class="directive"><a href="./mod/core.html#options">Options</a></code> ne peut pas être
    utilisée dans les sections
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    et <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>.</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="merging" id="merging">Comment les sections sont combinées entre elles</a></h2>
    
    <p>Les sections de configuration sont appliquées dans un ordre très particulier.
    Il est important de savoir comment cet ordre est défini car il peut avoir
    des effets importants sur la manière dont les directives de configuration
    sont interprétées.</p>
    
        <p>L'ordre dans lequel les sections sont appliquées est&nbsp;:</p>
    
        <ol>
          <li> Les sections <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> (à l'exception des expressions
          rationnelles) et les fichiers <code>.htaccess</code> sont appliquées
          simultanément (avec la possibilité pour <code>.htaccess</code>, s'il y est
          autorisé, de prévaloir sur <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>)</li>
    
          <li>Les sections <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code> (et <code>&lt;Directory
          "~"&gt;</code>)</li>
    
          <li>Les sections <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
          et <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code> sont
          appliquées simultanément</li>
    
          <li>Les sections <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> et <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> sont appliquées simultanément</li>
    
          <li>Les sections <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>,
          même si elles sont incluses dans un des contextes précédents.  </li>
        </ol>
    
        <p>Quelques remarques importantes :</p>
        <ul>
        <li>Mises à part les sections <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, dans chaque groupe, les sections sont
        traitées selon
        l'ordre dans lequel elles apparaissent dans les fichiers de configuration.
        Par exemple, une requête pour <em>/foo/bar</em> correspondra à
        <code>&lt;Location "/foo/bar"&gt;</code> et <code>&lt;Location
        "/foo"&gt;</code> (dans ce cas le groupe 4)&nbsp;: les deux sections seront
        évaluées mais selon l'ordre dans lequel elles apparaissent dans le fichier
        de configuration.</li>
        <li>Les sections <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> (groupe 1 ci-dessus)
        sont traitées dans l'ordre du répertoire le plus court vers le plus long.
        Par exemple, <code>&lt;Directory "/var/web/dir"&gt;</code> sera
        traitée avant <code>&lt;Directory
        "/var/web/dir/subdir"&gt;</code>.</li>
        <li>Si plusieurs sections <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> s'appliquent au même
        répertoire, elles sont traitées selon l'ordre dans lequel elles
        apparaissent dans le fichier de configuration.</li>
        <li>Les sections de configuration incluses à l'aide de la directive <code class="directive"><a href="./mod/core.html#include">Include</a></code> sont traitées comme si elles se
        trouvaient réellement dans le fichier qui les inclut à la position de la
        directive
        <code class="directive"><a href="./mod/core.html#include">Include</a></code>.</li>
        <li>Les sections situées à l'intérieur de sections <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        sont appliquées <em>après</em> les sections correspondantes situées en
        dehors de la définition du serveur virtuel, ce qui permet au serveur virtuel
        de prévaloir sur la configuration du serveur global.</li>
        <li>Quand la requête est servie par le module <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>,
        le conteneur <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
        prend la place du conteneur <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> dans l'ordre de traitement.</li>
        <li>Il faut être très prudent lorsqu'on mélange des directives de
        configuration similaires à l'intérieur et à l'extérieur d'une section
        <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> car leur ordre
        d'apparition a de l'importance. A cet effet, l'utilisation explicite de la
        directive <code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code>
        peut vous y aider.
            </li>
            <li>Lorsqu'une section <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> est utilisée dans un fichier <code>.htaccess</code>, les
    	directives incluses dans un répertoire parent seront fusionnées
    	<em>après</em> les directives non-incluses dans un sous-répertoire.
    	</li>
        </ul>
    
    	<div class="note"><h3>Note technique</h3>
    	Une séquence <code>&lt;Location&gt;</code>/<code>&lt;LocationMatch&gt;</code>
    	est réellement traitée juste avant la phase de traduction du nom
    	(où <code>Aliases</code> et <code>DocumentRoots</code>
          sont utilisés pour faire correspondre les URLs aux noms de fichiers).
          Les effets de cette séquence disparaissent totalement lorsque
          la traduction est terminée.
    	</div>
    
    <h3><a name="relationship-module-configuration" id="relationship-module-configuration">Interactions entre
    modules et sections de configuration</a></h3>
        <p>Une question se pose souvent après avoir lu comment les sections de
        configuration sont fusionnées&nbsp;: comment et quand les directives de modules
        particuliers comme <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> sont-elles interprétées&nbsp;? La
        réponse n'est pas triviale et nécessite un approfondissement. Chaque module
        httpd gère sa propre configuration, et chacune de ses directives dans
        httpd.conf définit un élément de configuration dans un contexte particulier.
        httpd n'exécute pas une commande au moment où elle est lue.</p>
        <p>A l'exécution, le noyau de httpd parcourt les sections de configuration
        dans l'ordre décrit ci-dessus afin de déterminer lesquelles s'appliquent à
        la requête actuelle. Lorsqu'une première section s'applique, elle est
        considérée comme la configuration actuelle pour cette requête. Si une
        section suivante s'applique aussi, chaque module qui possède des directives
        dans chacune de ces sections a la possibilité de fusionner sa configuration
        entre ces deux sections. Il en résulte une troisième configuration et le
        processus de fusion se poursuit jusqu'à ce que toutes les sections de
        configuration aient été évaluées.</p>
        <p>Après l'étape précédente, le traitement proprement dit de la requête HTTP
        peut commencer&nbsp;: chaque module peut effectuer toute tâche qui lui incombe,
        et pour déterminer de quelle manière il doit agir, il peut s'appuyer
        sur le noyau de httpd pour retrouver sa configuration globale issue de la
        fusion précédente.</p>
        <p>Un exemple permet de mieux visualiser l'ensemble du processus. La
        configuration suivante utilise la directive <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> du module
        <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> pour définir un en-tête HTTP spécifique. Quelle
        valeur httpd va-t-il affecter à l'en-tête <code>CustomHeaderName</code> pour
        une requête vers <code>/example/index.html</code>&nbsp;?
        </p>
        <pre class="prettyprint lang-config">&lt;Directory "/"&gt;
        Header set CustomHeaderName one
        &lt;FilesMatch ".*"&gt;
            Header set CustomHeaderName three
        &lt;/FilesMatch&gt;
    &lt;/Directory&gt;
    
    &lt;Directory "/example"&gt;
        Header set CustomHeaderName two
    &lt;/Directory&gt;</pre>
    
        <ul>
            <li><code class="directive">Directory</code> "/" s'applique, et une configuration
    	initiale est créée qui définit l'en-tête <code>CustomHeaderName</code>
    	avec la valeur <code>one</code>.</li>
            <li><code class="directive">Directory</code> "/example" s'applique, et comme
    	<code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> spécifie dans son code que
    	la valeur d'un en-tête doit être écrasée si ce dernier est défini à
    	nouveau, une nouvelle configuration est créée qui définit l'en-tête
    	<code>CustomHeaderName</code> avec la valeur <code>two</code>.</li>
            <li><code class="directive">FilesMatch</code> ".*" s'applique, une nouvelle
    	opportunité de fusion survient, et l'en-tête <code>CustomHeaderName</code>
    	est défini à la valeur <code>three</code>.</li>
            <li>Finalement, au cours des étapes suivantes du traitement de la
    	requête HTTP, <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> sera sollicité, et il se
    	basera sur la configuration qui a défini l'en-tête
    	<code>CustomHeaderName</code> à la valeur <code>three</code>.
    	<code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> utilise normalement cette configuration pour
    	accomplir sa tâche, à savoir définir des en-têtes HTTP. Cela ne veut
    	cependant pas dire qu'un module ne peut pas effectuer des actions plus
    	complexes comme désactiver des directives car elle ne sont pas
    	nécessaires ou obsolètes, etc.</li>
        </ul>
    
        <p>Ceci est aussi vrai pour les fichiers .htaccess car ils possèdent la même
        priorité que les sections <code class="directive">Directory</code> dans l'ordre de
        fusion. Il faut bien comprendre que les sections de configuration comme
        <code class="directive">Directory</code> et <code class="directive">FilesMatch</code> ne
        sont pas comparables avec les directives spécifiques de modules comme
        <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> ou <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> car elles agissent à des
        niveaux différents.
        </p>
    
    
    <h3><a name="merge-examples" id="merge-examples">Quelques exemples utiles</a></h3>
    
    <p>Voici un exemple imaginaire qui montre l'ordre de combinaison des sections.
    En supposant qu'elles s'appliquent toutes à la requête, les directives de
    cet exemple seront appliquées dans l'ordre suivant : A &gt; B &gt; C &gt; D &gt;
    E.</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/"&gt;
        E
    &lt;/Location&gt;
    
    &lt;Files "f.html"&gt;
        D
    &lt;/Files&gt;
    
    &lt;VirtualHost *&gt;
       &lt;Directory "/a/b"&gt;
            B
       &lt;/Directory&gt;
    &lt;/VirtualHost&gt;
    
    &lt;DirectoryMatch "^.*b$"&gt;
        C
    &lt;/DirectoryMatch&gt;
    
    &lt;Directory "/a/b"&gt;
        A
    &lt;/Directory&gt;</pre>
    
    
    <p>Pour un exemple plus concret, considérez ce qui suit. Sans tenir compte
    d'une quelconque restriction d'accès placée dans les sections <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, la section <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> sera
    évaluée en dernier et permettra un accès au serveur sans aucune restriction.
    En d'autres termes, l'ordre de la combinaison des sections est important&nbsp;;
    soyez donc prudent&nbsp;!</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/"&gt;
        Require all granted
    &lt;/Location&gt;
    
    # Grrrr !  Cette section &lt;Directory&gt; n'aura aucun effet
    &lt;Directory "/"&gt;
        &lt;RequireAll&gt;
            Require all granted
            Require not host badguy.example.com
        &lt;/RequireAll&gt;
    &lt;/Directory&gt;</pre>
    
    
    
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/sections.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sections.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_4.html.fr.utf8����������������������������������������������0000664�0001751�0001751�00000077162�14740503670�022366� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Vue d'ensemble des nouvelles fonctionnalités de la version 2.4 du
    serveur HTTP Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Vue d'ensemble des nouvelles fonctionnalités de la version 2.4 du
    serveur HTTP Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/new_features_2_4.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_4.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/new_features_2_4.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>Ce document décrit les modifications majeures apportées par
      la version 2.4 du serveur HTTP Apache. Pour les nouvelles fonctionnalités
      ajoutées par la version 2.2, se référer au document
      <a href="new_features_2_2.html">Nouvelles fonctionnalités
      de la version 2.2</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Améliorations du noyau</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#newmods">Nouveau modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Améliorations des modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Améliorations des programmes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentation">Documentation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Modifications concernant les développeur de modules</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Améliorations du noyau</a></h2>
        
        <dl>
          <dt>Modules multiprocessus (MPMs) chargeables à l'exécution</dt>
          <dd>Plusieurs MPMs peuvent maintenant être <a href="mpm.html#dynamic">compilés en tant que modules
          chargeables</a>. Le choix du MPM à utiliser s'effectue
          à l'exécution via la directive <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>.</dd>
    
          <dt>MPM Event</dt>
          <dd>Le <a href="mod/event.html">MPM Event</a> n'en est plus au stade expérimental et est
          maintenant pleinement supporté.</dd>
    
          <dt>Support du mode asynchrone</dt>
          <dd>Le support des lectures/écritures asynchrones pour les MPMs et
          les plateformes qui l'implémentent a été amélioré.</dd>
    
          <dt>Configuration du niveau de journalisation (LogLevel) par
          module et par répertoire</dt>
          <dd>La directive <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code>
          peut maintenant être définie par module et par répertoire. Les
          nouveaux niveaux <code>trace1</code> à <code>trace8</code> ont été
          ajoutés au dessus du niveau de journalisation <code>debug</code>.</dd>
    
          <dt>Sections de configuration au niveau requête</dt>
          <dd>Les sections <code class="directive"><a href="./mod/core.html#if">If</a></code>,
          <code class="directive"><a href="./mod/core.html#elseif">&lt;ElseIf&gt;</a></code> et
          <code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code>
          permettent de définir une configuration en fonction de critères
          liés à la requête.</dd>
    
          <dt>Interpréteur d'expressions à usage général</dt>
          <dd>Un nouvel interpréteur d'expressions permet de spécifier des
          <a href="expr.html">conditions complexes</a> via des directives à
          syntaxe commune comme <code class="directive"><a href="./mod/mod_setenvif.html#setenvifexpr">SetEnvIfExpr</a></code>, <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>, <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code>,
          <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>, etc...
          </dd>
    
          <dt>KeepAliveTimeout en millisecondes</dt>
          <dd>Il est maintenant possible de définir la directive <code class="directive"><a href="./mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code> en millisecondes.
          </dd>
    
          <dt>Directive NameVirtualHost</dt>
          <dd>Cette directive n'est plus nécessaire et est maintenant obsolète.</dd>
    
          <dt>Directives autorisées dans les fichiers <code>.htaccess</code></dt>
          <dd>La nouvelle directive <code class="directive"><a href="./mod/core.html#allowoverridelist">AllowOverrideList</a></code> permet de contrôler de
          manière plus précise la liste des directives autorisées dans les
          fichiers <code>.htaccess</code>.</dd>
    
          <dt>Variables dans les fichiers de configuration</dt>
          <dd>La directive <code class="directive"><a href="./mod/core.html#define">Define</a></code>
          permet de définir des variables dans les fichiers de
          configuration, améliorant ainsi la clareté de la présentation si
          la même valeur est utilisée en plusieurs points de la
          configuration.
          </dd>
    
          <dt>Diminution de la mémoire utilisée</dt>
          <dd>Bien qu'elle propose de nombreuses nouvelles fonctionnalités,
          la version 2.4.x tend à utiliser moins de mémoire que la version
          2.2.x.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="newmods" id="newmods">Nouveau modules</a></h2>
        
        <dl>      
    
          <dt><code class="module"><a href="./mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code></dt>
          <dd>Mise à disposition du protocole FastCGI pour
          <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_scgi.html">mod_proxy_scgi</a></code></dt>
          <dd>Mise à disposition du protocole SCGI pour
          <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_express.html">mod_proxy_express</a></code></dt>
          <dd>Ajoute à <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> la configuration dynamique
          de mandataires inverses en masse.</dd>
    
          <dt><code class="module"><a href="./mod/mod_remoteip.html">mod_remoteip</a></code></dt>
          <dd>Remplace l'adresse IP distante et le nom d'hôte apparents du
          client pour la requête courante par la liste d'adresses IP
          présentée par un mandataire ou un répartiteur de charge via les
          en-têtes de la requête.</dd>
    
          <dt><code class="module"><a href="./mod/mod_heartmonitor.html">mod_heartmonitor</a></code>,
              <code class="module"><a href="./mod/mod_lbmethod_heartbeat.html">mod_lbmethod_heartbeat</a></code></dt>
          <dd>Permet à <code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> de répartir la
          charge en fonction du nombre de connexions actives sur les
          serveurs d'arrière-plan.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code></dt>
          <dd>Anciennement module tiers, il supporte la correction des liens
          HTML dans une situation de mandat inverse, où le serveur
          d'arrière-plan génère des URLs qui ne sont pas valides du point de
          vue des clients du mandataire.</dd>
    
          <dt><code class="module"><a href="./mod/mod_sed.html">mod_sed</a></code></dt>
          <dd>Une amélioration de <code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code> qui permet
          d'éditer le corps de la réponse avec toute la puissance de la
          commande sed.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_form.html">mod_auth_form</a></code></dt>
          <dd>Implémente une authentification à base de formulaire.</dd>
    
          <dt><code class="module"><a href="./mod/mod_session.html">mod_session</a></code></dt>
          <dd>Permet de conserver les données de sessions des clients sous
          forme de cookies ou dans une base de données.</dd>
    
          <dt><code class="module"><a href="./mod/mod_allowmethods.html">mod_allowmethods</a></code></dt>
          <dd>Permet de restreindre l'utilisation de
          certaines méthodes HTTP sans interférer avec l'authentification et
          l'autorisation.</dd>      
    
          <dt><code class="module"><a href="./mod/mod_lua.html">mod_lua</a></code></dt>
          <dd>Embarque le langage <a href="http://www.lua.org/">Lua</a> dans
          httpd pour la configuration et les fonctions logiques courantes
          (Expérimental).</dd>
    
          <dt><code class="module"><a href="./mod/mod_log_debug.html">mod_log_debug</a></code></dt>
          <dd>Permet d'introduire une journalisation personnalisée à
          différentes phases du traitement de la requête.</dd>
    
          <dt><code class="module"><a href="./mod/mod_buffer.html">mod_buffer</a></code></dt>
          <dd>Fournit un tampon pour les piles des filtres en entrée et en
          sortie.</dd>
    
          <dt><code class="module"><a href="./mod/mod_data.html">mod_data</a></code></dt>
          <dd>Convertit un corps de réponse en URL de type données RFC2397.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ratelimit.html">mod_ratelimit</a></code></dt>
          <dd>Permet de limiter la bande passante pour certains
          clients.</dd>
    
          <dt><code class="module"><a href="./mod/mod_request.html">mod_request</a></code></dt>
          <dd>Fournit des filtres permettant de gérer et de mettre à
          disposition les corps des requêtes HTTP.</dd>
    
          <dt><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code></dt>
          <dd>Permet de renvoyer comme réponse le corps de la requête via la
          pile du filtre de sortie.</dd>
          
          <dt><code class="module"><a href="./mod/mod_slotmem_shm.html">mod_slotmem_shm</a></code></dt>
          <dd>Met à disposition un fournisseur de mémoire partagée à base de
          slots (du style tableau de bord).</dd>
    
          <dt><code class="module"><a href="./mod/mod_xml2enc.html">mod_xml2enc</a></code></dt>
          <dd>Anciennement module tiers, il supporte l'internationalisation
          dans les modules de filtrage basés sur libxml2 (support du
          markup)</dd>
    
          <dt><code class="module"><a href="./mod/mod_macro.html">mod_macro</a></code> (disponible à partir de la version 2.4.5)</dt>
          <dd>Permet d'utiliser des macros au sein des fichiers de
          configuration.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_wstunnel.html">mod_proxy_wstunnel</a></code> (disponible à partir de la version 2.4.5)</dt>
          <dd>Support des tunnels web-socket.</dd>
    
          <dt><code class="module"><a href="./mod/mod_authnz_fcgi.html">mod_authnz_fcgi</a></code> (disponible à partir de la version 2.4.10)</dt>
          <dd>Permet aux applications d'autorisation FastCGI d'authentifier
          et/ou autoriser les clients.</dd>
    
          <dt><code class="module"><a href="./mod/mod_http2.html">mod_http2</a></code> (disponible à partir de la version 2.4.17)</dt>
          <dd>Support de la couche transport HTTP/2.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_http2.html">mod_proxy_http2</a></code> (disponible à partir de la version 2.4.19)</dt>
          <dd>Support du protocole HTTP/2 pour <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_hcheck.html">mod_proxy_hcheck</a></code> (disponible à partir de la version 2.4.21)</dt>
          <dd>Support d'un bilan de santé dynamique indépendant pour les serveurs
          d'arrière-plan mandatés distants.</dd>
    
          <dt><code class="module"><a href="./mod/mod_brotli.html">mod_brotli</a></code> (disponible à partir de la version 2.4.26)</dt>
          <dd>Support de l'algorithme de compression Brotli.</dd>
    
          <dt><code class="module"><a href="./mod/mod_md.html">mod_md</a></code> (disponible à partir de la version 2.4.30)</dt>
          <dd>Automatisation de l'obtention de certificats via le protocole ACME.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_uwsgi.html">mod_proxy_uwsgi</a></code> (disponible à partir de la version 2.4.30)</dt>
          <dd>module passerelle UWSGI pour <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_socache_redis.html">mod_socache_redis</a></code> (disponible à partir de la version 2.4.39)</dt>
          <dd>Supporte le fournisseur de cache d'objets partagés basé sur <a href="http://redis.io/">Redis</a>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_systemd.html">mod_systemd</a></code> (disponible à partir de la version 2.4.42)</dt>
          <dd>intégration de systemd. Permet d'utiliser httpd en tant que service avec
          le paramètre systemd <code>Type=notify</code>.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Améliorations des modules</a></h2>
        
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> peut maintenant vérifier la
          validité des certificats clients en se connectant à
          un serveur OCSP. Il est possible de définir un
          répondeur par défaut, et de choisir si l'on
          préfère le répondeur désigné
          dans le certificat client.</dd>
    
    	<dd>En outre, <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> supporte maintenant
    	l'estampillage OCSP (OCSP stapling), qui permet au serveur
    	d'attester la validité de son certificat auprès du client au
    	cours de la phase de négociation de la connexion.</dd>
    
          <dd>Enfin, <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> peut maintenant être configuré pour
          que celui-ci partage les données de session SSL entre les serveurs
          via memcached.</dd>
    
          <dd>Le support des clés EC a été ajouté à celui des clés RSA et
          DSA.</dd>
    
          <dd>Support de TLS-SRP (disponible à partir de la version 2.4.4).</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd>La directive <code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> est maintenant configurée
          de manière optimale dans les sections <code class="directive"><a href="./mod/core.html#location">Location</a></code> ou <code class="directive"><a href="./mod/core.html#locationmatch">LocationMatch</a></code>, et offre un gain de
          performances important par rapport à la syntaxe traditionnelle à
          deux paramètres lorsqu'elle est présente en grand nombre.</dd>
    
          <dd>Il est maintenant possible de configurer l'adresse source dans
          les requêtes mandatées.</dd>
    
          <dd>Support des sockets de type Unix vers le serveur
          d'arrière-plan (disponible à partir de la version 2.4.7).</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code></dt>
    
          <dd>Le gestionnaire de répartition de charge propose de nouvelles
          fonctionnalités. Ainsi, les possibilités de configuration des
          membres du groupe de répartition de charge pendant l'exécution ont
          été améliorées (possibilité d'ajout d'un membre supplémentaire).</dd>
    
          <dd>Configuration à l'exécution d'un sous-ensemble de paramètres
          de répartition de charge.</dd>
    
          <dd>Les membres du groupe de répartition peuvent être définis à
          'Drain' de façon à ce qu'ils ne répondent qu'aux sessions
          persistantes existantes, ce qui permet de les mettre hors ligne en
          douceur.</dd>
    
          <dd>Les règlages du répartiteur de charge peuvent être rendus
          persistants après redémarrage.</dd>
    
          <dt><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></dt>
    
          <dd>Le filtre CACHE du module <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> peut être
          inséré à un certain point de la chaîne de filtrage pour contrôler
          plus finement la mise en cache.
          </dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> peut maintenant mettre en cache des
          requêtes HEAD.</dd>
    
          <dd>Chaque fois que cela est possible, les directives de
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> peuvent maintenant être définies au
          niveau du répertoire, et non plus seulement au niveau du serveur
          principal.</dd>
    
          <dd>L'URL de base des URLs en cache peut être personnalisée de
          façon à ce qu'un cluster de caches puisse partager le même préfixe
          d'URL.</dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> peut maintenant servir du contenu
          non mis à jour lorsqu'un serveur d'arrière-plan n'est pas
          disponible (erreur 5xx).</dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> peut maintenant insérer
          HIT/MISS/REVALIDATE dans un en-tête X-Cache.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
          <dd>Support de l'attribut 'onerror' dans un élément 'include',
          permettant de renvoyer un message d'erreur personnalisé à la place
          du message d'erreur par défaut.</dd>
    
          <dt><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>, <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>,
              <code class="module"><a href="./mod/mod_isapi.html">mod_isapi</a></code>, ...</dt>
          <dd>La traduction des en-têtes en variables d'environnement est
          plus stricte qu'avant, ce qui permet de diminuer l'exposition aux attaques
          de type cross-site-scripting via injection d'en-têtes. Les noms
          d'en-têtes contenant des caractères invalides (comme les caractères
          de soulignement) ne sont plus convertis en variables d'environnement. Le document <a href="env.html">Les variables d'environnement dans Apache</a>
          présente quelques pistes pour contourner ce problème avec les
          clients anciens qui nécessitent de tels en-têtes (Ceci affecte
          tous les modules qui utilisent ces variables d'environnement).</dd>
    
          <dt><code class="module"><a href="./mod/mod_authz_core.html">mod_authz_core</a></code> Conteneurs de logique d'autorisation</dt>
    
          <dd>La directive <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code> et les directives de
          conteneurs associées, comme <code class="directive"><a href="./mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>, permettent de définir une
          logique d'autorisation avancée.</dd>
    
          
    
          <dt><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></dt>
          <dd>La directive <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> dispose maintenant
          des drapeaux <code>[QSD]</code> (Query String Discard) et
          <code>[END]</code> qui permettent de simplifier les scénarios de
          réécriture courants.</dd>
          <dd>Possibilité d'utiliser des expressions booléennes complexes
          dans la directive <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>.</dd>
          <dd>Possibilité d'utiliser des requêtes SQL en tant que fonctions
          dans la directive <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>, <code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> ajoute le support des
          groupes imbriqués.</dd>
          <dd><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> apporte les directives <code class="directive"><a href="./mod/mod_ldap.html#ldapconnectionpoolttl">LDAPConnectionPoolTTL</a></code> et <code class="directive"><a href="./mod/mod_ldap.html#ldaptimeout">LDAPTimeout</a></code>, ainsi que d'autres
          améliorations dans le traitement des délais. Ceci s'avère utile
          pour les configurations où un pare-feu à mémoire d'état (stateful)
          rejète les connexions inactives vers le serveur LDAP.</dd>
          <dd><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> propose la directive <code class="directive"><a href="./mod/mod_ldap.html#ldaplibrarydebug">LDAPLibraryDebug</a></code> qui permet de
          journaliser les informations de débogage fournies par la boîte à
          outils LDAP utilisée.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_info.html">mod_info</a></code> est maintenant capable d'afficher la
          configuration préinterprétée sur stdout au cours du démarrage du
          serveur.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_basic.html">mod_auth_basic</a></code></dt>
          <dd>Nouveau mécanisme générique permettant d'effectuer une
          authentification basique (disponible à partir de la version 2.4.5).</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programs" id="programs">Améliorations des programmes</a></h2>
        
        <dl>
            <dt><code class="program"><a href="./programs/fcgistarter.html">fcgistarter</a></code></dt>
            <dd>Nouvel utilitaire pour le démarrage des démons
    	FastCGI.</dd>
    	<dt><code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code></dt>
            <dd>Les URLs présentes dans le cache peuvent maintenant être
    	affichées, accompagnées éventuellement de leurs métadonnées.</dd>
            <dd>Possibilité de supprimer explicitement des URLs individuelles
    	présentes dans le cache.</dd>
            <dd>Les tailles de fichiers peuvent maintenant être arrondies au
    	multiple de la taille de bloc donnée, les limites de taille
    	collant de ce fait d'avantage à la taille réelle sur disque.</dd>
            <dd>La taille du cache peut maintenant être limitée par le
    	nombre d'inodes, en plus de la possibilité de limitation par la
    	taille des fichiers.</dd>
    
    	<dt><code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code></dt>
            <dd>Possibilité de créer un lien vers le fichier journal
    	courant.</dd>
            <dd>Possibilité d'invoquer un script personnalisé après la
    	rotation.</dd>
    
    	<dt><code class="program"><a href="./programs/htpasswd.html">htpasswd</a></code>, <code class="program"><a href="./programs/htdbm.html">htdbm</a></code></dt>
            <dd>Support de l'algorithme bcrypt (disponible à partir de la
    	version 2.4.4).
            </dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">Documentation</a></h2>
        
        <dl>
            <dt>mod_rewrite</dt>
            <dd>La documentation du module <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> a
    	été réorganisée et presque entièrement réécrite en mettant
    	l'accent sur les exemples et l'utilisation courante, ainsi que
    	sur l'incitation à utiliser d'autres solutions lorsque cela
    	s'avère plus approprié. Le document <a href="rewrite/">Rewrite
    	Guide</a> constitue maintenant une section de premier niveau ;
    	il est mieux organisé et contient beaucoup plus de détails.</dd>
    
            <dt>mod_ssl</dt>
            <dd>La documentation du module <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> a été
    	grandement améliorée, avec plus d'exemples et un niveau "Bien
    	démarrer" qui s'ajoutent aux détails techniques déjà présents
    	dans la précédente documentation.</dd>
    
            <dt>Caching Guide</dt>
            <dd>Le <a href="caching.html">Guide de la mise en cache</a> a
    	été réécrit afin de bien faire la différence entre les
    	fonctionnalités de mise en cache de la RFC2616 HTTP/1.1 fournies
    	par le module <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, et la mise en cache
    	générique de type clé/valeur fournie par l'interface <a href="socache.html">socache</a>, mais aussi pour couvrir la mise
    	en cache spécialisée fournie par des mécanismes tels que ceux du
    	module <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code>.</dd>
        </dl>
        </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer">Modifications concernant les développeur de modules</a></h2>
        
        <dl>
          <dt>Ajout de code pour la vérification de la configuration</dt>
    
          <dd>Une nouvelle fonction, <code>check_config</code>, a été ajoutée et
          s'exécute entre les fonctions <code>pre_config</code> et
          <code>open_logs</code>. Elle s'exécute aussi avant la fonction
          <code>test_config</code> si l'option <code>-t</code> est passée au
          démon <code class="program"><a href="./programs/httpd.html">httpd</a></code>. La fonction <code>check_config</code>
          permet aux modules de vérifier l'interdépendance des valeurs des
          directives de configuration et d'ajuster ces valeurs, alors que les
          messages du serveur peuvent encore être affichés sur la console.
          L'utilisateur est ainsi averti des erreurs de configuration avant que la
          fonction du noyau <code>open_logs</code> ne redirige les sorties de la
          console vers le journal des erreurs.</dd>
    
          <dt>Ajout d'un analyseur syntaxique d'expressions</dt>
          <dd>Nous disposons à présent d'un analyseur générique d'expressions, dont l'API
          est décrite dans <var>ap_expr.h</var>. Il s'agit d'une adaptation de
          l'analyseur qu'on trouvait auparavant dans <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>.</dd>
    
          <dt>Conteneurs de logique d'autorisation</dt>
    
          <dd>Afin de fournir une logique d'autorisation avancée via des
          directives telles que <code class="directive"><a href="./mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>, les modules d'autorisation
          s'enregistrent maintenant en tant
          que fournisseur par le biais de ap_register_auth_provider().</dd>
    
          <dt>Interface de mise en cache des petits objets</dt>
    
          <dd>Le fichier d'en-têtes <var>ap_socache.h</var> fournit une
          interface à base de fournisseur pour la mise en cache des petits
          objets de données, en s'inspirant de
          l'implémentation précédente
          du cache de session par <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>. Sont supportés
          actuellement : les fournisseurs utilisant un tampon cyclique en
          mémoire partagée, les fichiers dbm sur disque, et les caches
          distribués de type memcache.</dd>
    
          <dt>Ajout du point d'ancrage Cache Status</dt>
    
          <dd>Le module <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> inclut maintenant un
          nouveau point d'ancrage, <code>cache_status</code>, qui est appelé
          lorsque la décision à propos de la mise en cache est connue. Il en
          existe une implémentation par défaut qui ajoute les en-têtes
          optionnels <code>X-Cache</code> et <code>X-Cache-Detail</code> à
          la réponse.</dd>
    
    
        </dl>
        <p>La documentation du développeur contient une <a href="developer/new_api_2_4.html">liste détaillée des modifications
        de l'API</a>.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/new_features_2_4.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_4.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/new_features_2_4.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_4.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/socache.html.fr.utf8�������������������������������������������������������0000664�0001751�0001751�00000024357�14740503670�020636� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Le cache des objets partagés du serveur HTTP Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Le cache des objets partagés du serveur HTTP Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/socache.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/socache.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>Le cache des objets partagés est un concept de partage de données
        de base entre tous les processus d'un serveur, sans se préoccuper du
        <a href="mpm.html">modèle de threads et de processus</a>. On
        l'utilise lorsque les avantages apportés par le partage de données
        entre processus contrebalance la perte de performances consécutive à
        la communication interprocessus.</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="providers" id="providers">Fournisseurs du cache d'objets partagés</a></h2>
        
        <p>Le cache d'objets partagés en tant que tel est une abstraction.
        Il est implémenté par cinq modules différents. Pour pouvoir
        utiliser le cache, un ou plusieurs de ces modules doivent être
        présents et configurés.</p>
        <p>Le seul élément de configuration consiste à définir le
        fournisseur de cache à utiliser. Ceci est de la responsabilité des
        modules qui utilisent le cache, et pour cela, ils activent la
        sélection via des directives telles que <code class="directive"><a href="./mod/mod_cache_socache.html#cachesocache">CacheSocache</a></code>, <code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code>, <code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code>, et <code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code>.</p>
        <p>Les fournisseurs actuellement disponibles sont :</p>
        <dl>
        <dt>"dbm" (<code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code>)</dt>
        <dd>Celui-ci utilise un fichier de hashage DBM. Le choix de la
        DBM sous-jacente peut être configurable si la version
        d'APR installée supporte de multiples implémentations de DBM.</dd>
        <dt>"dc" (<code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code>)</dt>
        <dd>Celui-ci utilise les bibliothèques de mise en cache de sessions
        distribuées <a href="http://distcache.sourceforge.net/">distcache</a>.</dd>
        <dt>"memcache" (<code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code>)</dt>
        <dd>Celui-ci utilise le système à hautes performances de mise en
        cache d'objets de mémoire distribuée <a href="http://memcached.org/">memcached</a>.</dd>
        <dt>"redis" (<code class="module"><a href="./mod/mod_socache_redis.html">mod_socache_redis</a></code>)</dt>
        <dd>Celui-ci utilise le système de mise en cache d'objets de mémoire
        distribuée à hautes performances <a href="http://redis.io/">Redis</a>.</dd>
        <dt>"shmcb" (<code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code>)</dt>
        <dd>Celui-ci utilise un tampon cyclique à hautes performances au
        sein d'un segment de mémoire partagée.</dd>
        </dl>
    
        <p>L'API fournit les fonctions suivantes :</p>
    
        <dl>
          <dt>const char *create(ap_socache_instance_t **instance, const char *arg,
                              apr_pool_t *tmp, apr_pool_t *p);</dt>
          <dd>Cette fonction permet de créer un cache de session basé sur
          la chaîne de configuration spécifiée. Le pointeur d'instance
          renvoyé dans le paramètre instance sera passé comme premier
          argument des invocations subséquentes.</dd>
    
          <dt>apr_status_t init(ap_socache_instance_t *instance, const char *cname,
                             const struct ap_socache_hints *hints,
                             server_rec *s, apr_pool_t *pool)</dt>
          <dd>Cette fonction permet d'initialiser le cache. L'argument cname
          doit avoir une longueur maximale de 16 caractères et permet
          d'identifier de manière unique l'utilisateur du cache au sein du
          serveur ; il est recommandé d'utiliser le nom du module, par
          exemple "mod_ssl-sess". Comme cette chaîne peut être utilisée au
          sein d'un système de fichiers, il est conseillé de n'utiliser que
          des caractères alphanumériques [a-z0-9_-]. Si l'argument hints
          n'est pas égal à NULL, il fournit un ensemble d'indications au
          fournisseur. La valeur retournée est le code d'erreur APR.</dd>
    
          <dt>void destroy(ap_socache_instance_t *instance, server_rec *s)</dt>
          <dd>Cette fonction permet de détruire l'instance de cache
          spécifiée.</dd>
    
          <dt>apr_status_t store(ap_socache_instance_t *instance, server_rec *s,
                              const unsigned char *id, unsigned int idlen,
                              apr_time_t expiry,
                              unsigned char *data, unsigned int datalen,
                              apr_pool_t *pool)</dt>
          <dd>Cette fonction permet de stocker un objet dans une instance de
          cache.</dd>
    
          <dt>apr_status_t retrieve(ap_socache_instance_t *instance, server_rec *s,
                                 const unsigned char *id, unsigned int idlen,
                                 unsigned char *data, unsigned int *datalen,
                                 apr_pool_t *pool)</dt>
          <dd>Cette fonction permet d'extraire un objet du cache.</dd>
    
          <dt>apr_status_t remove(ap_socache_instance_t *instance, server_rec *s,
                               const unsigned char *id, unsigned int idlen,
                               apr_pool_t *pool)</dt>
          <dd>Supprime un objet du cache.</dd>
    
          <dt>void status(ap_socache_instance_t *instance, request_rec *r, int flags)</dt>
          <dd>Renvoie le statut d'une instance de cache à destination de mod_status.</dd>
    
          <dt>apr_status_t iterate(ap_socache_instance_t *instance, server_rec *s,
                                void *userctx, ap_socache_iterator_t *iterator,
                                apr_pool_t *pool)</dt>
          <dd>Envoie tous les objets gardés en cache à une fonction pour traitement itératif.</dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/socache.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/socache.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/socache.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/urlmapping.html.fr.utf8����������������������������������������������������0000664�0001751�0001751�00000070620�14740503670�021401� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title> Mise en correspondance des URLs avec le système de fichiers - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1> Mise en correspondance des URLs avec le système de fichiers</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Ce document explique comment le serveur HTTP Apache utilise l'URL contenue dans une
        requête pour déterminer le noeud du système de fichier à partir duquel le
        fichier devra être servi.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#related">Modules et directives concernés</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentroot">Racine des documents (DocumentRoot)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#outside">Fichiers situés en dehors de
    l'arborescence DocumentRoot</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#user">Répertoires des utilisateurs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#redirect">Redirection d'URL</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Mandataire inverse (Reverse Proxy)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">Moteur de réécriture</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#notfound">Fichier non trouvé (File Not Found)</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Autres modules de mise en correspondance des
    URLs</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Modules et directives concernés</a></h2>
    
    <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></li><li><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code></li><li><code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code></li><li><code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_speling.html#checkspelling">CheckSpelling</a></code></li><li><code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="./mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentroot" id="documentroot">Racine des documents (DocumentRoot)</a></h2>
    
        <p>La méthode par défaut de httpd pour déterminer quel fichier servir pour
        une requête donnée, consiste à extraire le chemin du fichier de la requête
        (la partie de l'URL qui suit le nom d'hôte et le port), puis de l'ajouter
        à la fin de la valeur de la directive
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> définie dans vos fichiers
        de configuration.
        Ainsi, les fichiers et répertoires
        situés en dessous de <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        constituent l'arborescence de base des documents qui seront visibles
        depuis le web.</p>
    
        <p>Par exemple, si la directive
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> contient
        <code>/var/www/html</code>, une requête pour
        <code>http://www.example.com/fish/guppies.html</code> retournera le
        fichier <code>/var/www/html/fish/guppies.html</code> au client.</p>
    
        <p>Si la requête concerne un répertoire (autrement dit un chemin se
        terminant par un slash <code>/</code>), le nom du fichier qui sera
        recherché et servi depuis ce répertoire est défini via la directive
        <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>. Par exemple,
        supposons que <code>DocumentRoot</code> ait été définie comme
        précédemment, et que vous ayez défini <code>DirectoryIndex</code>
        comme suit :</p>
    
        <div class="example"><p><code>DirectoryIndex index.html index.php</code></p></div>
    
        <p>Si httpd reçoit alors une requête pour
        <code>http://www.example.com/fish/</code>, il tentera de servir le
        fichier <code>/var/www/html/fish/index.html</code>. Si ce fichier
        n'existe pas, il tentera de servir le fichier
        <code>/var/www/html/fish/index.php</code>.</p>
    
        <p>Si aucun de ces fichiers existe, httpd tentera de générer et
        d'afficher un index du répertoire, à condition que
        <code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code> ait été chargé et configuré pour le
        permettre.</p>
    
        <p>httpd supporte aussi les <a href="vhosts/">Hôtes virtuels</a>,
        ce qui lui permet de traiter des requêtes pour plusieurs hôtes.
        Dans ce cas, un <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        différent peut être défini pour chaque hôte virtuel;
        les directives fournies par le module
        <code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code> peuvent aussi être utilisées afin de
        déterminer dynamiquement le noeud approprié du système de fichiers
        à partir duquel servir un contenu en fonction de l'adresse IP
        ou du nom d'hôte.</p>
    
        <p>La directive <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>  est
        définie dans le fichier de configuration de votre serveur principal
        (<code>httpd.conf</code>), mais peut aussi être redéfinie pour chaque
        <a href="vhosts/">Hôte virtuel</a> supplémentaire que vous avez créé.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="outside" id="outside">Fichiers situés en dehors de
    l'arborescence DocumentRoot</a></h2>
    
        <p>Il existe de nombreuses circonstances pour lesquelles il est nécessaire
        d'autoriser l'accès web à des portions du système de fichiers qui ne se
        trouvent pas dans l'arborescence <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>.  httpd propose de nombreuses
        solutions pour réaliser cela. Sur les systèmes Unix, les liens
        symboliques permettent de rattacher d'autres portions du système de
        fichiers au <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>. Pour des raisons de sécurité,
        httpd ne suivra les liens symboliques que si les <code class="directive"><a href="./mod/core.html#options">Options</a></code> pour le répertoire concerné contiennent
        <code>FollowSymLinks</code> ou <code>SymLinksIfOwnerMatch</code>.</p>
    
        <p>Une autre méthode consiste à utiliser la directive <code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code> pour rattacher toute portion
        du système de fichiers à l'arborescence du site web. Par exemple, avec</p>
    
    <pre class="prettyprint lang-config">Alias "/docs" "/var/web"</pre>
    
    
        <p>l'URL <code>http://www.example.com/docs/dir/file.html</code>
        correspondra au fichier <code>/var/web/dir/file.html</code>. La
        directive
        <code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code>
        fonctionne de la même manière, excepté que tout contenu localisé dans le
        chemin cible sera traité comme un script <a class="glossarylink" href="./glossary.html#cgi" title="voir glossaire">CGI</a>.</p>
    
        <p>Pour les situations qui nécessitent plus de flexibilité, vous disposez
        des directives <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code>
        et <code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code>
        qui permettent des substitutions et comparaisons puissantes basées
        sur les <a class="glossarylink" href="./glossary.html#regex" title="voir glossaire">expressions rationnelles</a>.
        Par exemple,</p>
    
    <pre class="prettyprint lang-config">ScriptAliasMatch "^/~([a-zA-Z0-9]+)/cgi-bin/(.+)" "/home/$1/cgi-bin/$2"</pre>
    
    
        <p>fera correspondre une requête du style
        <code>http://example.com/~user/cgi-bin/script.cgi</code> au chemin
        <code>/home/user/cgi-bin/script.cgi</code>, et traitera le fichier résultant
        comme un script CGI.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="user" id="user">Répertoires des utilisateurs</a></h2>
    
        <p>Sur les systèmes Unix, on peut traditionnellement faire référence
        au répertoire personnel d'un <em>utilisateur</em> particulier à l'aide de
        l'expression <code>~user/</code>.
        Le module <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code>
        étend cette idée au web en autorisant l'accès aux fichiers situés dans les
        répertoires home des utilisateurs à l'aide d'URLs
        comme dans ce qui suit :</p>
    
    <div class="example"><p><code>http://www.example.com/~user/file.html</code></p></div>
    
        <p>Pour des raisons de sécurité, il est déconseillé de permettre un accès
        direct à un répertoire home d'utilisateur depuis le web. A cet effet, la
        directive <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>
        spécifie un répertoire où sont situés les fichiers accessibles depuis le web
        dans le répertoire home de l'utilisateur.
        Avec la configuration par défaut
        <code>Userdir public_html</code>, l'URL ci-dessus correspondra à un fichier
        dont le chemin sera du style
        <code>/home/user/public_html/file.html</code> où
        <code>/home/user/</code> est le répertoire home de l'utilisateur tel qu'il
        est défini dans <code>/etc/passwd</code>.</p>
    
        <p>La directive <code>Userdir</code> met à votre disposition de nombreuses
        formes différentes pour les systèmes où <code>/etc/passwd</code> ne
        spécifie pas la localisation du répertoire home.</p>
    
        <p>Certains jugent le symbole "~" (dont le code sur le web est souvent
        <code>%7e</code>) inapproprié et préfèrent utiliser une chaîne de
        caractères différente pour représenter les répertoires utilisateurs.
        mod_userdir ne supporte pas cette fonctionnalité. Cependant, si les
        répertoires home des utilisateurs sont structurés de manière rationnelle,
        il est possible d'utiliser la directive
        <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code>
        pour obtenir l'effet désiré. Par exemple, pour faire correspondre
        <code>http://www.example.com/upages/user/file.html</code> à
        <code>/home/user/public_html/file.html</code>, utilisez la directive
        <code>AliasMatch</code> suivante :</p>
    
    <pre class="prettyprint lang-config">AliasMatch "^/upages/([a-zA-Z0-9]+)(/(.*))?$"   "/home/$1/public_html/$3"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">Redirection d'URL</a></h2>
    
        <p>Les directives de configuration décrites dans les sections précédentes
        demandent à httpd d'extraire un contenu depuis un emplacement spécifique
        du système de fichiers
        et de la retourner au client. Il est cependant parfois
        souhaitable d'informer le
        client que le contenu demandé est localisé à une URL différente, et de
        demander au client d'élaborer une nouvelle requête avec la nouvelle URL.
        Ce processus se nomme <em>redirection</em> et est implémenté par la
        directive <code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code>.
        Par exemple, si le contenu du répertoire <code>/foo/</code> sous
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> est déplacé vers le
        nouveau répertoire <code>/bar/</code>, vous pouvez demander aux clients
        de le requérir à sa nouvelle localisation comme suit :</p>
    
    <pre class="prettyprint lang-config">Redirect permanent "/foo/"   "http://www.example.com/bar/"</pre>
    
    
        <p>Ceci aura pour effet de rediriger tout chemin d'URL commençant par
        <code>/foo/</code> vers le même chemin d'URL sur le serveur
        <code>www.example.com</code> en remplaçant <code>/foo/</code> par
        <code>/bar/</code>. Vous pouvez rediriger les clients non seulement sur le
        serveur d'origine, mais aussi vers n'importe quel autre serveur.</p>
    
        <p>httpd propose aussi la directive <code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> pour traiter les problèmes
        de réécriture d'une plus grande complexité. Par exemple, afin de rediriger
        les requêtes pour la page d'accueil du site vers un site différent, mais
        laisser toutes les autres requêtes inchangées, utilisez la
        configuration suivante :</p>
    
    <pre class="prettyprint lang-config">RedirectMatch permanent "^/$"    "http://www.example.com/startpage.html"</pre>
    
    
        <p>De même, pour rediriger temporairement toutes les pages d'un site
        vers une page particulière d'un autre site, utilisez ce qui suit :</p>
    
    <pre class="prettyprint lang-config">RedirectMatch temp ".*"  "http://othersite.example.com/startpage.html"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Mandataire inverse (Reverse Proxy)</a></h2>
    
    <p>httpd vous permet aussi de rapatrier des documents distants
    dans l'espace des URL du serveur local.
    Cette technique est appelée <em>mandataire inverse ou reverse
    proxying</em> car le serveur web agit comme un serveur mandataire en
    rapatriant les documents depuis un serveur distant puis les renvoyant
    au client. Ceci diffère d'un service de mandataire usuel (direct) car, pour le client,
    les documents semblent appartenir au serveur mandataire inverse.</p>
    
    <p>Dans l'exemple suivant, quand les clients demandent des documents situés
    dans le répertoire
    <code>/foo/</code>, le serveur rapatrie ces documents depuis le répertoire
    <code>/bar/</code> sur <code>internal.example.com</code>
    et les renvoie au client comme s'ils appartenaient au serveur local.</p>
    
    <pre class="prettyprint lang-config">ProxyPass "/foo/" "http://internal.example.com/bar/"
    ProxyPassReverse "/foo/" "http://internal.example.com/bar/"
    ProxyPassReverseCookieDomain internal.example.com public.example.com
    ProxyPassReverseCookiePath "/foo/" "/bar/"</pre>
    
    
    <p>La directive <code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> configure
    le serveur pour rapatrier les documents appropriés, alors que la directive
    <code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code>
    réécrit les redirections provenant de
    <code>internal.example.com</code> de telle manière qu'elles ciblent le
    répertoire approprié sur le serveur local. De manière similaire, les directives
    <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code>
    et <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code>
    réécrivent les cookies élaborés par le serveur d'arrière-plan.</p>
    <p>Il est important de noter cependant, que les liens situés dans les documents
    ne seront pas réécrits.  Ainsi, tout lien absolu sur
    <code>internal.example.com</code> fera décrocher le client
    du serveur mandataire et effectuer sa requête directement sur
    <code>internal.example.com</code>. Vous pouvez modifier ces liens (et
    d'utres contenus) situés dans la page au moment où elle est envoyée au
    client en utilisant le module <code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code>.</p>
    
    <pre class="prettyprint lang-config">Substitute "s/internal\.example\.com/www.example.com/i"</pre>
    
    
    <p>Le module <code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code> rend possible une réécriture plus
    élaborée des liens en HTML et XHTML. Il permet de créer des listes
    d'URLs et de leurs réécritures, de façon à pouvoir gérer des scénarios
    de réécriture complexes.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Moteur de réécriture</a></h2>
    
        <p>Le moteur de réécriture <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> peut s'avérer
        utile lorsqu'une substitution plus puissante est nécessaire.
        Les directives fournies par ce module peuvent utiliser des caractéristiques de la
        requête comme le type de navigateur ou l'adresse IP source afin de décider
        depuis où servir le contenu. En outre, mod_rewrite peut utiliser des
        fichiers ou programmes de bases de données externes pour déterminer comment
        traiter une requête. Le moteur de réécriture peut effectuer les trois types
        de mise en correspondance discutés plus haut :
        redirections internes (aliases), redirections externes, et services mandataires.
        De nombreux exemples pratiques utilisant mod_rewrite sont discutés dans la
        <a href="rewrite/">documentation détaillée de mod_rewrite</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="notfound" id="notfound">Fichier non trouvé (File Not Found)</a></h2>
    
        <p>Inévitablement, apparaîtront des URLs qui ne correspondront à aucun
        fichier du système de fichiers.
        Ceci peut arriver pour de nombreuses raisons.
        Il peut s'agir du déplacement de documents d'une
        localisation vers une autre. Dans ce cas, le mieux est d'utiliser la
        <a href="#redirect">redirection d'URL</a> pour informer les clients de la
        nouvelle localisation de la ressource. De cette façon, vous êtes sur que
        les anciens signets et liens continueront de fonctionner, même si la
        ressource est déplacée.</p>
    
        <p>Une autre cause fréquente d'erreurs "File Not Found" est l'erreur de
        frappe accidentelle dans les URLs, soit directement dans le navigateur,
        soit dans les liens HTML. httpd propose le module
        <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> (sic) pour tenter de résoudre ce problème.
        Lorsque ce module est activé, il intercepte les erreurs
        "File Not Found" et recherche une ressource possédant un nom de fichier
        similaire. Si un tel fichier est trouvé, mod_speling va envoyer une
        redirection HTTP au client pour lui communiquer l'URL correcte.
        Si plusieurs fichiers proches sont trouvés, une liste des alternatives
        possibles sera présentée au client.</p>
    
        <p>mod_speling possède une fonctionnalité particulièrement utile :
        il compare les noms de fichiers sans tenir compte de la casse.
        Ceci peut aider les systèmes où les utilisateurs ne connaissent pas la
        sensibilité des URLs à la casse et bien sûr les systèmes de fichiers unix.
        Mais l'utilisation de mod_speling pour toute autre chose que la correction
        occasionnelle d'URLs peut augmenter la charge du serveur, car chaque
        requête "incorrecte" entraîne une redirection d'URL et une nouvelle requête
        de la part du client.</p>
    
        <p><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code> fournit la directive <code class="directive"><a href="./mod/mod_dir.html#fallbackresource">FallbackResource</a></code> qui permet d'associer
        des URIs virtuels à une ressource réelle qui peut ainsi les servir.
        Cette directive remplace avantageusement
        <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> lors de l'implémentation d'un
        "contrôleur frontal".</p>
    
        <p>Si toutes les tentatives pour localiser le contenu
        échouent, httpd
        retourne une page d'erreur avec le code de statut HTTP 404
        (file not found). L'apparence de cette page est contrôlée à l'aide de la
        directive <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code>
        et peut être personnalisée de manière très flexible comme discuté dans le
        document
        <a href="custom-error.html">Réponses personnalisées aux erreurs</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Autres modules de mise en correspondance des
    URLs</a></h2>
    
    
    
        <p>Les autres modules disponibles pour la mise en correspondance des
        URLs sont :</p>
        <ul>
        <li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code> - Met une URL en correspondance
        avec un script CGI en fonction de la méthode de la requête, ou du
        type MIME de la ressource.</li>
        <li><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code> - Permet une mise en correspondance
        basique d'un slash terminal dans un fichier index comme
        <code>index.html</code>.</li>
        <li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code> - Met en correspondance une
        requête avec une URL en fonction de la zone d'une image intégrée à
        un document HTML dans laquelle un utilisateur clique.</li>
        <li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> - Sélectionne le document
        approprié en fonction de préférences du client telles que la langue
        ou la compression du contenu.</li>
        </ul>
        
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/urlmapping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/urlmapping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_2.html.fr.utf8����������������������������������������������0000664�0001751�0001751�00000051360�14740503670�022354� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Aperçu des nouvelles fonctionnalités de la version
    2.2 du serveur HTTP Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Aperçu des nouvelles fonctionnalités de la version
    2.2 du serveur HTTP Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>Ce document décrit quelques uns des changements principaux entre
         les versions 2.0 et 2.2 du serveur HTTP Apache. Pour les
         nouvelles fonctionnalités ajoutées depuis la version 1.3, se
         référer au document
         <a href="new_features_2_0.html">2.0 new features</a>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Améliorations du système de base</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Améliorations des modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Améliorations des programmes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Changements pour le développeur de module</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Améliorations du système de base</a></h2>
        
        <dl>
    
          <dt>Authn/Authz</dt>
          <dd>Les modules d'authentification et d'autorisation intégrés
    	ont été refondus. Le nouveau module
    	mod_authn_alias (supprimé dans la version 2.3/2.4) permet de
    	simplifier considérablement certaines configurations d'authentification.
              Voir <a href="#module">modification des noms de modules</a>,
    	  et
    	  <a href="#developer">les changements pour le développeur</a>
    	  pour plus d'informations sur les conséquences de ces
    	  changements pour les utilisateurs et les développeurs de
    	  modules.</dd>
    
          <dt>Mise en cache</dt>
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>, et
              mod_mem_cache (supprimés dans la version 2.3/2.4) ont subi de nombreuses
    	  modifications, et l'on considère qu'ils ont maintenant atteint
    	  un degré de qualité suffisant pour leur mise en production. Le programme
    	  <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code> a été ajouté afin de rendre
    	  plus propre la configuration du module
    	  <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>.</dd>
    
          <dt>Configuration</dt>
          <dd>L'agencement de la configuration par défaut a été simplifié
          	et modularisé. Les portions de configuration qui peuvent être
    	utilisées pour activer des fonctionnalités courantes sont
    	maintenant intégrées à Apache, et peuvent être facilement
    	ajoutées à la configuration principale du serveur.</dd>
    
          <dt>Arrêt en douceur</dt>
          <dd>Les modules MPM <code class="module"><a href="./mod/prefork.html">prefork</a></code>,
            <code class="module"><a href="./mod/worker.html">worker</a></code> et <code class="module"><a href="./mod/event.html">event</a></code> permettent
    	maintenant l'arrêt en douceur de <code class="program"><a href="./programs/httpd.html">httpd</a></code>
              au moyen du signal
              <a href="stopping.html#gracefulstop"><code>graceful-stop</code></a>.
    	  La directive <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code> a été ajoutée dans le but
    	  de spécifier un délai optionnel, après lequel
              <code class="program"><a href="./programs/httpd.html">httpd</a></code> s'arrêtera quel que soit le statut
              des requêtes en cours.</dd>
    
          <dt>Mise en oeuvre du proxy</dt>
          <dd>Le nouveau module <code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> fournit
              des services de répartition de charge (load balancing) pour le
    	  module <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.
              Le nouveau module <code class="module"><a href="./mod/mod_proxy_ajp.html">mod_proxy_ajp</a></code> ajoute le
    	  support pour le
              <code>Protocole JServ de Apache version 1.3</code> qu'utilise
              <a href="http://tomcat.apache.org/">Apache Tomcat</a>.</dd>
    
          <dt>Mise à jour de la bibliothèque des expressions rationnelles</dt>
          <dd>La version 5.0 de la
              <a href="http://www.pcre.org/">Perl Compatible Regular Expression
              Library</a> (PCRE) est maintenant disponible.
    	  <code class="program"><a href="./programs/httpd.html">httpd</a></code> peut être configuré pour utiliser une
    	  PCRE choisie en passant l'option <code>--with-pcre</code> au
    	  script configure.</dd>
    
          <dt>Filtrage intelligent</dt>
          <dd>Le module <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> permet la configuration
              dynamique de la chaîne de filtrage en sortie. Il permet
    	  d'insérer des filtres conditionnels basés sur toute
    	  requête, en-tête de réponse ou variable
    	  d'environnement, et fait table rase des problèmes de dépendances
    	  et d'ordonnancement rencontrés avec l'architecture 2.0.</dd>
    
          <dt>Support des gros fichiers</dt>
          <dd><code class="program"><a href="./programs/httpd.html">httpd</a></code> supporte maintenant les fichiers d'une taille supérieure
          à 2GB sur les systèmes 32 bits UNIX modernes.  Le support des
          corps de requête d'une taille supérieure à 2GB a aussi été
          ajouté.</dd>
    
          <dt>Module MPM Event</dt>
          <dd>Le module MPM <code class="module"><a href="./mod/event.html">event</a></code> utilise un thread séparé
          	pour gérer les requêtes "Keep alive" et accepter des connexions.
    	Les requêtes "Keep alive" requéraient traditionnellement un
    	processus httpd dédié pour leur gestion. Ce processus dédié
    	ne pouvait plus être réutilisé jusqu'à ce que le délai "Keep Alive"
              soit écoulé.</dd>
    
          <dt>Support des bases de données SQL</dt>
          <dd>Le module <code class="module"><a href="./mod/mod_dbd.html">mod_dbd</a></code>, associé à l'environnement
          	<code>apr_dbd</code>, fournit le support SQL direct aux modules
    	qui en ont besoin.  Supporte la mise en commun des connexions
              dans les modules MPM threadés.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Améliorations des modules</a></h2>
        
        <dl>
          <dt>Authn/Authz</dt>
          <dd>Les modules du répertoire aaa ont été renommés et fournissent
              un support amélioré pour la méthode d'authentification <strong>digest</strong>.  Par exemple, <code>mod_auth</code>
              est maintenant scindé en deux modules : <code class="module"><a href="./mod/mod_auth_basic.html">mod_auth_basic</a></code> et
              <code class="module"><a href="./mod/mod_authn_file.html">mod_authn_file</a></code>; <code>mod_auth_dbm</code> s'appelle maintenant
              <code class="module"><a href="./mod/mod_authn_dbm.html">mod_authn_dbm</a></code>; <code>mod_access</code> a été renommé en
              <code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code>.  Est également apparu le nouveau module
              mod_authn_alias (supprimé dans la version 2.3/2.4) qui simplifie
              certaines configurations d'authentification.
          </dd>
    
          <dt><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd>Ce module est un portage de la version 2.0 du module
              <code>mod_auth_ldap</code> vers la version 2.2 du framework
    	  <code>Authn/Authz</code>.
    	  Les nouvelles fonctionnalités comprennent l'utilisation des valeurs
    	  d'attributs LDAP et des filtres de recherche avancés dans la
              directive <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_authz_owner.html">mod_authz_owner</a></code></dt>
    	<dd>Un nouveau module qui autorise l'accès à un fichier
    	en fonction de son propriétaire dans le système de
    	fichiers</dd>
    
    	<dt><code class="module"><a href="./mod/mod_version.html">mod_version</a></code></dt>
    	<dd>Un nouveau module qui permet d'activer des blocs de
    	configuration en fonction de la version du serveur en cours
    	d'exécution.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd>Un nouvel argument <code>?config</code> a été ajouté, qui permettra d'afficher
              les directives de configuration telles qu'elles sont interprétées
    	  par Apache, y compris le nom de fichier et le numéro de ligne.
    	  Le module montre aussi l'ordre des points d'entrée de traitement d'une
    	  requête (request hooks) ainsi que des informations de construction
    	  supplémentaires, d'une manière similaire à <code>httpd -V</code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
          
          <dd>Le support de la <a href="http://www.ietf.org/rfc/rfc2817.txt">RFC 2817</a> a été ajouté, ce qui permet de passer d'une
    	connexion en clair au chiffrement TLS.</dd>
    
          <dt><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></dt>
          <dd><code>mod_imap</code> a été renommé en <code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code> afin
          d'éviter une confusion pour les utilisateurs.</dd>
        </dl>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programs" id="programs">Améliorations des programmes</a></h2>
        
        <dl>
          <dt><code class="program"><a href="./programs/httpd.html">httpd</a></code></dt>
          <dd>Une nouvelle option de ligne de commande <code>-M</code>
         a été ajoutée, qui fournit la liste de tous les modules chargés
         en fonction de la configuration réelle. À la différence de l'option
         <code>-l</code>, cette liste inclut les Objets Dynamiques Partagés
         (DSOs) chargés par l'intermédiaire du module
         <code class="module"><a href="./mod/mod_so.html">mod_so</a></code>.</dd>
          <dt><code class="program"><a href="./programs/httxt2dbm.html">httxt2dbm</a></code></dt>
          <dd>Un nouveau programme servant à générer des fichiers dbm à partir
          d'une source au format texte, à utiliser avec la directive
          <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
              et le type de mise en correspondance <code>dbm</code>.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer">Changements pour le développeur de module</a></h2>
        
        <dl>
          <dt><a class="glossarylink" href="./glossary.html#apr" title="voir glossaire">APR</a> 1.0 API</dt>
    
          <dd>Apache 2.2 utilise l'API APR 1.0.  Toutes les fonctions et
          symboles obsolètes ont été supprimés du code de <code>APR</code> et
              <code>APR-Util</code>. Pour plus de détails, consultez le
              <a href="http://apr.apache.org/">site web d'APR</a>.</dd>
    
          <dt>Authn/Authz</dt>
          <dd>Les modules d'authentification et d'autorisation intégrés ont
              été renommés de la manière suivante:
              <ul>
              <li><code>mod_auth_*</code>  -&gt; Modules qui implémentent un mécanisme
    	  	d'authentification HTTP</li>
              <li><code>mod_authn_*</code> -&gt; Modules qui fournissent un dispositif
    	  	d'authentification en arrière-plan</li>
              <li><code>mod_authz_*</code> -&gt; Modules qui implémentent l'autorisation (ou l'accès)</li>
              <li><code>mod_authnz_*</code> -&gt; Modules qui implémentent à la fois
    	  l'authentification &amp; l'autorisation</li>
              </ul>
    	  L'organisation des méthodes d'authentification a également été revue, ce qui va simplifier
    	  grandement l'ajout de nouvelles méthodes d'authentification.</dd>
    
          <dt>Journalisation des erreurs de connexion</dt>
    
          <dd>Une nouvelle fonction a été ajoutée, <code>ap_log_cerror</code>,
          afin de pouvoir enregistrer les erreurs qui surviennent au cours de
          la connexion du client.  Une fois enregistré, le message inclut l'adresse IP du client.</dd>
    
          <dt>Ajout d'une portion de code pour la vérification de la configuration</dt>
    
          <dd>Un nouvel élément de traitement a été ajouté, <code>test_config</code>,
          afin d'aider les modules qui ne veulent exécuter un code spécial
          que si l'utilisateur passe le paramètre <code>-t</code> à
          <code class="program"><a href="./programs/httpd.html">httpd</a></code>.</dd>
    
          <dt>Définition de la taille de la pile pour les modules MPM en processus légers</dt>
    
          <dd>Une nouvelle directive a été ajoutée, <code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code>
         afin de définir la taille de la pile pour tous les modules MPM en processus légers (modules threadés).
         Ceci s'avère nécessaire pour certains modules tiers sur des plateformes
         dont la taille de la pile des threads par défaut est
         trop petite.</dd>
    
          <dt>Gestion de protocole pour les filtres en sortie</dt>
    
          <dd>Par le passé, chaque filtre devait s'assurer que les en-têtes de
          réponse corrects étaient générés dans la mesure où il les affectait.
          Les filtres peuvent maintenant déléguer la gestion courante du
          protocole au module
              <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>, à l'aide des appels
              <code>ap_register_output_filter_protocol</code> ou
              <code>ap_filter_protocol</code>.</dd>
    
          <dt>Ajout d'un élément de traitement pour le processus père (monitor hook)</dt>
          <dd>Ce nouvel élément de traitement permet aux modules de lancer
          des jobs réguliers/planifiés au niveau du processus père
          (root).</dd>
    
          <dt>Modifications de l'API de traitement des expressions rationnelles</dt>
    
          <dd>Le fichier d'en-tête <code>pcreposix.h</code> n'est plus disponible ;
          il a été remplacé par le nouveau fichier
          d'en-tête <code>ap_regex.h</code>.  L'implémentation
          POSIX.2 <code>regex.h</code> exposée dans l'ancien fichier d'en-tête
          est maintenant disponible dans l'espace de nommage <code>ap_</code>
          depuis <code>ap_regex.h</code>.  Les appels à <code>regcomp</code>,
          <code>regexec</code>, etc... peuvent être remplacés par des appels à
          <code>ap_regcomp</code>, <code>ap_regexec</code>.</dd>
    
          <dt>Cadre d'application DBD (API pour base de données SQL)</dt>
    
          <dd><p>Avec Apache 1.x et 2.0, les modules nécessitant un processus
          SQL d'arrière-plan devaient s'en charger eux-mêmes.  En dehors du fait
          de réinventer la roue, ceci peut s'avérer très inefficace, par
          exemple lorsque plusieurs modules maintiennent chacun leurs
          propres connexions.</p>
          <p>Apache 2.1 et supérieur fournissent l'API <code>ap_dbd</code> qui
          permet la gestion des connexions à la base de données (y compris
          les stratégies optimisées pour les modules MPM threadés
          et non threadés), tandis que APR 1.2 et supérieur fournissent
          l'API <code>apr_dbd</code> qui permet l'interaction avec la
          base de données.</p>
          <p>Les nouveaux modules DEVRAIENT désormais utiliser ces APIs pour
          toutes les opérations liées aux bases de données SQL.
          De même, les applications existantes DEVRAIENT être mises à jour
          lorsque c'est possible, que ce soit de manière transparente ou sous forme
          d'une option recommandée à leurs utilisateurs.</p></dd>
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/new_features_2_2.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.fr.utf8�������������������������������������������������������0000664�0001751�0001751�00000065715�14740503670�020676� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Plan du site - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>Plan du site</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>Cette page contient la liste des éléments actuellement disponibles de
    la <a href="./">Documentation du serveur HTTP Apache Version
    2.4</a>.</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">Notes de version</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Utilisation du serveur HTTP Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">Documentation des serveurs virtuels Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">Guide de réécriture d'URLs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">Chiffrement SSL/TLS avec Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">Guides, Tutoriels, and Recettes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">Notes spécifiques à certains systèmes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Le serveur HTTP Apache et ses programmes associés</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Documentations diverses sur Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Modules Apache</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Documentation du développeur</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index">Glossaire et Index</a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">Notes de version</a></h2>
    <ul><li><a href="upgrading.html">Mise à jour vers 2.4 depuis 2.2</a></li>
    <li><a href="new_features_2_4.html">Nouvelles fonctionnalités d'Apache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">Nouvelles fonctionnalités d'Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">Nouvelles fonctionnalités d'Apache 2.0</a></li>
    <li><a href="license.html">License Apache</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">Utilisation du serveur HTTP Apache</a></h2>
    <ul><li><a href="install.html">Compilation et installation</a></li>
    <li><a href="invoking.html">Démarrage</a></li>
    <li><a href="stopping.html">Arrêt ou redémarrage</a></li>
    <li><a href="configuring.html">Fichiers de configuration</a></li>
    <li><a href="sections.html">Comment fonctionnent les sections Directory,
    Location et Files</a></li>
    <li><a href="caching.html">Mise en cache du contenu</a></li>
    <li><a href="server-wide.html">Configuration niveau serveur</a></li>
    <li><a href="logs.html">Fichiers de traces</a></li>
    <li><a href="urlmapping.html">Mise en correspondance des URLs avec le système de fichiers</a></li>
    <li><a href="dso.html">Objets Dynamiques Partagés (DSO)</a></li>
    <li><a href="content-negotiation.html">Négociation sur le contenu</a></li>
    <li><a href="custom-error.html">Messages d'erreur personnalisés</a></li>
    <li><a href="bind.html">Définition des adresses et ports qu'utilise
    Apache</a></li>
    <li><a href="mpm.html">Modules multi-processus (MPMs)</a></li>
    <li><a href="env.html">Les variables d'environnement d'Apache</a></li>
    <li><a href="expr.html">L'interprétation des expressions dans Apache</a></li>
    <li><a href="handler.html">Utilisation des gestionnaires d'Apache</a></li>
    <li><a href="filter.html">Filtres</a></li>
    <li><a href="socache.html">Support du cache des objets partagés</a></li>
    <li><a href="suexec.html">Support de suEXEC</a></li>
    <li><a href="dns-caveats.html">Considérations à propos de DNS et Apache</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">Foire aux Questions</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">Documentation des serveurs virtuels Apache</a></h2>
    <ul><li class="separate"><a href="vhosts/">Aperçu</a></li>
    <li><a href="vhosts/name-based.html">Serveurs virtuels basés sur le nom</a></li>
    <li><a href="vhosts/ip-based.html">Support des serveurs virtuels basés
    sur l'adresse IP</a></li>
    <li><a href="vhosts/mass.html">Configuration dynamique de l'hébergement
    virtuel de masse</a></li>
    <li><a href="vhosts/examples.html">Exemples de serveurs virtuels</a></li>
    <li><a href="vhosts/details.html">Discussion approfondie à propos de la
    sélection d'un serveur virtuel</a></li>
    <li><a href="vhosts/fd-limits.html">Limitations inhérentes aux
    descripteurs de fichiers</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="rewrite" id="rewrite">Guide de réécriture d'URLs</a></h2>
    <ul><li class="separate"><a href="rewrite/">Survol</a></li>
    <li><a href="mod/mod_rewrite.html">Documentation de référence de mod_rewrite</a></li>
    <li><a href="rewrite/intro.html">Introduction à l'utilisation des expressions
    rationnelles avec mod_rewrite</a></li>
    <li><a href="rewrite/remapping.html">Utilisation de mod_rewrite pour les
    redirections et la traduction des URLs</a></li>
    <li><a href="rewrite/access.html">Utilisation de mod_rewrite pour le contrôle d'accès</a></li>
    <li><a href="rewrite/vhosts.html">Les serveurs virtuels dynamique avec mod_rewrite</a></li>
    <li><a href="rewrite/proxy.html">Le mandat dynamique avec mod_rewrite</a></li>
    <li><a href="rewrite/rewritemap.html">Utilisation d'une table de
    réécriture</a></li>
    <li><a href="rewrite/advanced.html">Techniques avancées</a></li>
    <li><a href="rewrite/avoid.html">Quand ne pas utiliser mod_rewrite</a></li>
    <li><a href="rewrite/flags.html">Drapeaux de réécriture</a></li>
    <li><a href="rewrite/tech.html">Détails techniques</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">Chiffrement SSL/TLS avec Apache</a></h2>
    <ul><li class="separate"><a href="ssl/">Aperçu</a></li>
    <li><a href="ssl/ssl_intro.html">Chiffrement SSL/TLS :
    Introduction</a></li>
    <li><a href="ssl/ssl_compat.html">Chiffrement SSL/TLS :
    Compatibilité</a></li>
    <li><a href="ssl/ssl_howto.html">Chiffrement SSL/TLS : Recettes</a></li>
    <li><a href="ssl/ssl_faq.html">Chiffrement SSL/TLS : FAQ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">Guides, Tutoriels, and Recettes</a></h2>
    <ul><li class="separate"><a href="howto/">Aperçu</a></li>
    <li><a href="howto/auth.html">Authentification et autorisation</a></li>
    <li><a href="howto/access.html">Contrôle d'accès</a></li>
    <li><a href="howto/cgi.html">Contenu dynamique avec CGI</a></li>
    <li><a href="howto/ssi.html">Introduction aux Inclusions côté serveur
    (Server Side Includes - SSI)</a></li>
    <li><a href="howto/htaccess.html">Fichiers .htaccess</a></li>
    <li><a href="howto/public_html.html">Répertoires web des
    utilisateurs</a></li>
    <li><a href="howto/reverse_proxy.html">Guide de configuration des mandataires
    inverses</a></li>
    <li><a href="howto/http2.html">Guide HTTP/2</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">Notes spécifiques à certains systèmes</a></h2>
    <ul><li class="separate"><a href="platform/">Aperçu</a></li>
    <li><a href="platform/windows.html">Utiliser Apache avec Microsoft
    Windows</a></li>
    <li><a href="platform/win_compiling.html">Compiler Apache pour
    Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">Utilisation d'Apache avec les systèmes à
    base de paquets RPM</a></li>
    <li><a href="platform/netware.html">Utiliser Apache avec Novell
    NetWare</a></li>
    <li><a href="platform/perf-hp.html">Mise en oeuvre d'un serveur web
    hautes performances sous HPUX</a></li>
    <li><a href="platform/ebcdic.html">Le portage d'Apache sous EBCDIC</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">Le serveur HTTP Apache et ses programmes associés</a></h2>
    <ul><li class="separate"><a href="programs/">Aperçu</a></li>
    <li><a href="programs/httpd.html">Page de manuel : httpd</a></li>
    <li><a href="programs/ab.html">Page de manuel : ab</a></li>
    <li><a href="programs/apachectl.html">Page de manuel : apachectl</a></li>
    <li><a href="programs/apxs.html">Page de manuel : apxs</a></li>
    <li><a href="programs/configure.html">Page de manuel : configure</a></li>
    <li><a href="programs/dbmmanage.html">Page de manuel : dbmmanage</a></li>
    <li><a href="programs/fcgistarter.html">Page de manuel : fcgistarter</a></li>
    <li><a href="programs/htcacheclean.html">Page de manuel : htcacheclean</a></li>
    <li><a href="programs/htdbm.html">Page de manuel : htdbm</a></li>
    <li><a href="programs/htdigest.html">Page de manuel : htdigest</a></li>
    <li><a href="programs/htpasswd.html">Page de manuel : htpasswd</a></li>
    <li><a href="programs/httxt2dbm.html">Page de manuel : httxt2dbm</a></li>
    <li><a href="programs/logresolve.html">Page de manuel : logresolve</a></li>
    <li><a href="programs/log_server_status.html">Page de manuel : log_server_status</a></li>
    <li><a href="programs/rotatelogs.html">Page de manuel : rotatelogs</a></li>
    <li><a href="programs/split-logfile.html">Page de manuel : split-logfile</a></li>
    <li><a href="programs/suexec.html">Page de manuel : suexec</a></li>
    <li><a href="programs/other.html">Autres programmes</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Documentations diverses sur Apache</a></h2>
    <ul><li class="separate"><a href="misc/">Aperçu</a></li>
    <li><a href="misc/perf-tuning.html">Considérations à propos des
    performances - Configuration fine d'Apache</a></li>
    <li><a href="misc/security_tips.html">Conseils en matière de sécurité</a></li>
    <li><a href="misc/relevant_standards.html">Standards concernés</a></li>
    <li><a href="misc/password_encryptions.html">Formats de chiffrement des
    mots de passe</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">Modules Apache</a></h2>
    <ul><li><a href="mod/module-dict.html">Définitions des termes utilisés pour
    décrire les modules Apache</a></li>
    <li><a href="mod/directive-dict.html">Définitions des termes utilisés
    pour décrire les directives Apache</a></li>
    </ul><ul><li><a href="mod/core.html">Fonctionalités de Base Apache</a></li>
    <li><a href="mod/mpm_common.html">Apache MPM : Directives Communes</a></li>
    <li><a href="mod/event.html">Apache MPM event</a></li>
    <li><a href="mod/mpm_netware.html">Apache MPM netware</a></li>
    <li><a href="mod/mpmt_os2.html">Apache MPM os2</a></li>
    <li><a href="mod/prefork.html">Apache MPM prefork</a></li>
    <li><a href="mod/mpm_winnt.html">Apache MPM winnt</a></li>
    <li><a href="mod/worker.html">Apache MPM worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">Module Apache mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">Module Apache mod_actions</a></li>
    <li><a href="mod/mod_alias.html">Module Apache mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">Module Apache mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">Module Apache mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">Module Apache mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">Module Apache mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">Module Apache mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">Module Apache mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">Module Apache mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">Module Apache mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">Module Apache mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">Module Apache mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">Module Apache mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">Module Apache mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">Module Apache mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">Module Apache mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">Module Apache mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">Module Apache mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">Module Apache mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">Module Apache mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">Module Apache mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">Module Apache mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">Module Apache mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">Module Apache mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">Module Apache mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">Module Apache mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">Module Apache mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">Module Apache mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">Module Apache mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">Module Apache mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">Module Apache mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">Module Apache mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">Module Apache mod_data</a></li>
    <li><a href="mod/mod_dav.html">Module Apache mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">Module Apache mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">Module Apache mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">Module Apache mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">Module Apache mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">Module Apache mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">Module Apache mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">Module Apache mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">Module Apache mod_echo</a></li>
    <li><a href="mod/mod_env.html">Module Apache mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">Module Apache mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">Module Apache mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">Module Apache mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">Module Apache mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">Module Apache mod_filter</a></li>
    <li><a href="mod/mod_headers.html">Module Apache mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">Module Apache mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">Module Apache mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">Module Apache mod_http2</a></li>
    <li><a href="mod/mod_ident.html">Module Apache mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">Module Apache mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">Module Apache mod_include</a></li>
    <li><a href="mod/mod_info.html">Module Apache mod_info</a></li>
    <li><a href="mod/mod_isapi.html">Module Apache mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">Module Apache mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">Module Apache mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">Module Apache mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">Module Apache mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">Module Apache mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">Module Apache mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">Module Apache mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">Module Apache mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">Module Apache mod_logio</a></li>
    <li><a href="mod/mod_lua.html">Module Apache mod_lua</a></li>
    <li><a href="mod/mod_macro.html">Module Apache mod_macro</a></li>
    <li><a href="mod/mod_md.html">Module Apache mod_md</a></li>
    <li><a href="mod/mod_mime.html">Module Apache mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">Module Apache mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">Module Apache mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">Module Apache mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">Module Apache mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">Module Apache mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">Module Apache mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">Module Apache mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">Module Apache mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">Module Apache mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">Module Apache mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">Module Apache mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">Module Apache mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">Module Apache mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">Module Apache mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">Module Apache mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">Module Apache mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">Module Apache mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">Module Apache mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">Module Apache mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">Module Apache mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">Module Apache mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">Module Apache mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">Module Apache mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">Module Apache mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">Module Apache mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">Module Apache mod_sed</a></li>
    <li><a href="mod/mod_session.html">Module Apache mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">Module Apache mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">Module Apache mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">Module Apache mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">Module Apache mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">Module Apache mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">Module Apache mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">Module Apache mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">Module Apache mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">Module Apache mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">Module Apache mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">Module Apache mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">Module Apache mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">Module Apache mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">Module Apache mod_ssl</a></li>
    <li><a href="mod/mod_status.html">Module Apache mod_status</a></li>
    <li><a href="mod/mod_substitute.html">Module Apache mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">Module Apache mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">Module Apache mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">Module Apache mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">Module Apache mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">Module Apache mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">Module Apache mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">Module Apache mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">Module Apache mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">Module Apache mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">Module Apache mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer">Documentation du développeur</a></h2>
    <ul><li class="separate"><a href="developer/">Aperçu</a></li>
    <li><a href="developer/API.html">Notes sur l'API Apache</a></li>
    <li><a href="developer/new_api_2_4.html">Mises à jour de l'API dans Apache HTTPD 2.4</a></li>
    <li><a href="developer/modguide.html">Développement de modules pour Apache HTTPD 2.4</a></li>
    <li><a href="developer/documenting.html">Documentation d'Apache HTTPD</a></li>
    <li><a href="developer/hooks.html">Fonctions d'accroche (Hook Functions)
    d'Apache 2.x</a></li>
    <li><a href="developer/modules.html">Convertir un module depuis la
    version 1.3 vers la version 2.x</a></li>
    <li><a href="developer/request.html">Traitement des requêtes avec
    la version 2.x</a></li>
    <li><a href="developer/filters.html">Fonctionnement des filtres dans la
    version 2.x</a></li>
    <li><a href="developer/output-filters.html">Guide des filtres en sortie
    dans la version 2.x</a></li>
    <li><a href="developer/thread_safety.html">Sécurité des
    threads dans la version 2.x</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index">Glossaire et Index</a></h2>
    <ul><li><a href="glossary.html">Glossaire</a></li>
    <li><a href="mod/">Index des modules</a></li>
    <li><a href="mod/directives.html">Index des directives</a></li>
    <li><a href="mod/quickreference.html">Référence rapide des directives</a></li>
    <li><a href="mod/overrides.html">Index des directives disponibles dans les
    fichiers .htaccess</a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������httpd-2.4.64/docs/manual/upgrading.html.fr.utf8�����������������������������������������������������0000664�0001751�0001751�00000102635�14740503670�021205� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Mise à jour de la version 2.2 vers la version 2.4 - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Mise à jour de la version 2.2 vers la version 2.4</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/upgrading.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/upgrading.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
      <p>Afin d'assister les utilisateurs lors de leurs opérations de mise à
      jour, nous maintenons un document
      qui comporte des informations critiques à l'attention des personnes qui
      utilisent déjà le serveur HTTP Apache. Ces informations
      ne sont que de brèves notes, et vous
      trouverez plus d'informations dans le document <a href="new_features_2_4.html">Nouvelles fonctionnalités</a>, ou dans
      le fichier <code>src/CHANGES</code>. Les développeurs d'applications
      et de modules trouveront un résumé des modifications de l'API dans la
      vue d'ensemble <a href="developer/new_api_2_4.html">Mises à jour de
      l'API</a>.</p>
    
      <p>Ce document présente les changements de comportement du serveur qui
      peuvent nécessiter une modification de la configuration, et une
      méthode pour utiliser la version 2.4 du serveur en parallèle avec la
      version 2.2. Pour tirer parti des nouvelles fonctionnalités de la
      version 2.4, reportez-vous au document "Nouvelles fonctionnalités".</p>
    
      <p>Ce document ne décrit que les modifications intervenues entre les versions
      2.2 et 2.4. Si vous effectuez une mise à jour depuis la version 2.0, vous
      devez aussi consulter le
      <a href="http://httpd.apache.org/docs/2.2/upgrading.html">document de mise
      à jour de 2.0 vers 2.2.</a></p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#compile-time">Modifications des paramètres de compilation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#run-time">Modifications de la configuration à l'exécution</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Changements divers</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#third-party">Modules tiers</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#commonproblems">Problèmes de mise à jour courants</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="new_features_2_4.html">Vue d'ensemble des nouvelles
    fonctionnalités du serveur HTTP Apache 2.4</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile-time" id="compile-time">Modifications des paramètres de compilation</a></h2>
        
         <p>Le processus de compilation est très similaire à celui de la
         version 2.2. Dans la plupart des cas, vous pourrez utiliser votre
         ancienne ligne de commande <code>configure</code> (telle qu'elle
         est enregistrée dans le fichier <code>build/config.nice</code>
         situé dans le répertoire de compilation du serveur). Voici certains
         changements intervenus dans la configuration par défaut :</p>
    
        <ul>
          <li>Les modules suivants ont été supprimés : mod_authn_default,
          mod_authz_default et mod_mem_cache. Si vous utilisiez
          mod_mem_cache sous la version 2.2, vous devez maintenant utiliser
          <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> dans la version 2.4.</li>
    
          <li>Toutes les implémentations de répartition de charge ont été
          déplacées vers des sous-modules spécifiques de mod_proxy, comme
          <code class="module"><a href="./mod/mod_lbmethod_bybusyness.html">mod_lbmethod_bybusyness</a></code>. Vous devrez compiler et
          chargés tous les modules correspondants que votre configuration
          utilise.</li>
    
          <li>Le support de BeOS, TPF, et des anciennes plates-formes telles
          que A/UX, Next, et Tandem a été supprimé, car
          elles ne sont plus considérées comme maintenues.</li>
    
          <li>configure: les modules dynamiques (DSO) sont compilés par
          défaut</li>
    
          <li>configure: par défaut, seul un jeu de modules de base est
          chargé. Les autres directives <code class="directive">LoadModule</code>
          sont mises en commentaires dans le fichier de configuration.</li>
    
          <li>configure: le jeu de modules "most" est compilé par défaut</li>
    
          <li>configure: le jeu de modules "reallyall" ajoute les modules de
          développeur au jeu "all".</li>
        </ul>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="run-time" id="run-time">Modifications de la configuration à l'exécution</a></h2>
        
    <p>Des changements significatifs dans la configuration de
    l'autorisation, ainsi que quelques changements mineurs, peuvent
    nécessiter une mise à jour des fichiers de configuration de la version
    2.2 avant de les utiliser sous la version 2.4.</p>
    
        <h3><a name="authz" id="authz">Autorisation</a></h3>
          
    
          <p>Tout fichier de configuration qui gère des autorisations devra
          probablement être mis à jour.</p>
    
        <p>Vous devez vous reporter au document <a href="howto/auth.html">Authentification, autorisation et contrôle
        d'accès</a>, et plus particulièrement à la section <a href="howto/auth.html#beyond">Pour aller plus loin qu'une simple
        autorisation</a> qui explique les nouveaux mécanismes permettant de
        contrôler l'ordre dans lequel les directives d'autorisation sont
        appliquées.</p>
    
        <p>Les directives qui contrôlent la manière dont les modules
        d'autorisation réagissent lorsqu'ils ne reconnaissent pas
        l'utilisateur authentifié ont été supprimées : elles comprennent les
        directives AuthzLDAPAuthoritative, AuthzDBDAuthoritative,
        AuthzDBMAuthoritative, AuthzGroupFileAuthoritative,
        AuthzUserAuthoritative et AuthzOwnerAuthoritative. Ces directives
        ont été remplacées par les directives plus explicites <code class="directive"><a href="./mod/mod_authz_core.html#requireany">RequireAny</a></code>, <code class="directive"><a href="./mod/mod_authz_core.html#requirenone">RequireNone</a></code>, et <code class="directive"><a href="./mod/mod_authz_core.html#requireall">RequireAll</a></code>.</p>
    
        <p>Si vous utilisez <code class="module"><a href="./mod/mod_authz_dbm.html">mod_authz_dbm</a></code>, vous devez
        mettre à jour votre configuration en remplaçant les directives du
        style <code>Require group ...</code> par des directives du style
        <code>Require dbm-group ...</code>.</p>
    
        <h4><a name="access" id="access">Contrôle d'accès</a></h4>
          
    
          <p>Dans la version 2.2, le contrôle d'accès basé sur le nom d'hôte
          du client, son adresse IP, ou d'autres caractéristiques de la
          requête était assuré via les directives <code class="directive"><a href="./mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="./mod/mod_access_compat.html#allow">Allow</a></code>, <code class="directive"><a href="./mod/mod_access_compat.html#deny">Deny</a></code>, et <code class="directive"><a href="./mod/mod_access_compat.html#satisfy">Satisfy</a></code>.</p>
    
          <p>Dans la version 2.4, ce contrôle d'accès est assuré, comme tout
          contrôle d'autorisation, par le nouveau module
          <code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code>. Bien que le module
          <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code> soit fourni à des fins de
          compatibilité avec les anciennes configurations, les anciennes
          directives de contrôle d'accès devront être remplacées par les
          nouveaux mécanismes d'authentification.</p>
    
          <div class="note"><h3>Mélanger anciennes et nouvelles directives</h3>
          <p>Mélanger d'anciennes directives comme <code class="directive"><a href="./mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="./mod/mod_access_compat.html#allow">Allow</a></code> ou <code class="directive"><a href="./mod/mod_access_compat.html#deny">Deny</a></code> avec des nouvelles comme
          <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code> est techniquement
          possible mais déconseillé. En effet, <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code> a
          été conçu pour supporter des configurations ne contenant que des anciennes
          directives afin de faciliter le passage à la version 2.4. Les
          exemples ci-dessous vous permettront de vous faire une meilleure idée des
          problèmes qui peuvent survenir.
          </p>
          </div>
    
          <p>Voici quelques exemples de contrôle d'accès avec l'ancienne et
          la nouvelle méthode :</p>
    
          <p>Dans cet exemple, il n'y a pas d'authentification et toutes les requêtes sont rejetées :</p>
          <div class="example"><h3>version 2.2 :</h3><pre class="prettyprint lang-config">Order deny,allow
    Deny from all</pre>
    </div>
          <div class="example"><h3>version 2.4 :</h3><pre class="prettyprint lang-config">Require all denied</pre>
    </div>
    
          <p>Dans cet exemple, il n'y a pas d'authentification et toutes les requêtes sont acceptées :</p>
          <div class="example"><h3>version 2.2 :</h3><pre class="prettyprint lang-config">Order allow,deny
    Allow from all</pre>
    </div>
          <div class="example"><h3>version 2.4 :</h3><pre class="prettyprint lang-config">Require all granted</pre>
    </div>
    
          <p>Dans l'exemple suivant, il n'y a pas d'authentification et tous les
          hôtes du domaine example.org ont l'autorisation d'accès, tous les autres
          étant rejetés :</p>
    
          <div class="example"><h3>version 2.2 :</h3><pre class="prettyprint lang-config">Order Deny,Allow
    Deny from all
    Allow from example.org</pre>
    </div>
          <div class="example"><h3>version 2.4 :</h3><pre class="prettyprint lang-config">Require host example.org</pre>
    </div>
        <p>Dans l'exemple suivant, tous les hôtes du domaine example.org
          ont l'autorisation d'accès, tous les autres sont rejetés :</p>
    
          <div class="example"><h3>version 2.2 :</h3><pre class="prettyprint lang-config">Order Deny,Allow
    Deny from all
    Allow from example.org</pre>
    </div>
          <div class="example"><h3>version 2.4 :</h3><pre class="prettyprint lang-config">Require host example.org</pre>
    </div>
    
          <p>Dans l'exemple suivant, le mélange d'anciennes et de nouvelles
          directives produit des résultats inattendus.</p>
     
          <div class="example"><h3>Mélange d'anciennes et de nouvelles directives : RESULTAT
    	INATTENDU</h3><pre class="prettyprint lang-config">DocumentRoot "/var/www/html"
    
    &lt;Directory "/"&gt;
        AllowOverride None
        Order deny,allow
        Deny from all
    &lt;/Directory&gt;
    
    &lt;Location "/server-status"&gt;
        SetHandler server-status
        Require local
    &lt;/Location&gt;
    
    access.log - GET /server-status 403 127.0.0.1
    error.log - AH01797: client denied by server configuration: /var/www/html/server-status</pre>
    </div>
          <p>Pourquoi httpd interdit l'accès à server-status alors que la
          configuration semble l'autoriser ? Parce que dans ce scénario de <a href="sections.html#merging">fusion</a> de configuration, les
          directives de <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code> sont prioritaires par
          rapport à celles de <code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code>.</p>
    
          <p>L'exemple suivant quant à lui produit un résultat conforme :</p>
    
          <div class="example"><h3>Mélange d'anciennes et de nouvelles directives : RESULTAT
    	CONFORME</h3><pre class="prettyprint lang-config">DocumentRoot "/var/www/html"
    
    &lt;Directory "/"&gt;
        AllowOverride None
        Require all denied
    &lt;/Directory&gt;
    
    &lt;Location "/server-status"&gt;
        SetHandler server-status
        Order deny,allow
        Deny from all
        Allow From 127.0.0.1
    &lt;/Location&gt;
    
    access.log - GET /server-status 200 127.0.0.1</pre>
    </div> 
          <p>En conclusion, même si une configuration hybride peut fonctionner,
          essayez de l'éviter lors de la mise à jour : soit conservez les anciennes
          directives, puis migrez-les vers les nouvelles ultérieurement, soit
          effectuez une migration immédiate de toutes les anciennes directives vers
          les nouvelles.  
          </p>      
        
    
        <p>Dans de nombreuses configurations avec authentification où la directive
         <code class="directive">Satisfy</code> était définie à sa valeur par défaut
         <em>ALL</em>, les lignes de configuration qui désactivent le contrôle
         d'accès basé sur l'hôte sont maintenant omises :</p>
    
          <div class="example"><h3>Version 2.2 :</h3><pre class="prettyprint lang-config"># configuration en version 2.2 qui désactive le contrôle d'accès basé sur le nom
    # d'hôte pour n'utiliser que l'authentification
    Order Deny,Allow
    Allow from all
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
          <div class="example"><h3>Version 2.4 :</h3><pre class="prettyprint lang-config"># Pas besoin de remplacer les directives de contrôle d'accès basées sur le nom
    # d'hôte désactivées
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
    
         <p>Dans les configurations où l'authentification et le contrôle d'accès se
         combinaient dans un but précis, les directives de contrôle d'accès doivent
         être migrées. Dans l'exemple suivant, les requêtes qui correspondent aux
         <em>deux</em> critères sont acceptées :</p>
          <div class="example"><h3>Version 2.2 :</h3><pre class="prettyprint lang-config">Order allow,deny
    Deny from all
    # ALL est la valeur par défaut de Satisfy
    Satisfy ALL
    Allow from 127.0.0.1
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
          <div class="example"><h3>Version 2.4 :</h3><pre class="prettyprint lang-config">AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    &lt;RequireAll&gt;
      Require valid-user
      Require ip 127.0.0.1
    &lt;/RequireAll&gt;</pre>
    </div>
    
         <p>Dans les configurations où l'authentification et le contrôle d'accès se
         combinaient dans un but précis, les directives de contrôle d'accès doivent
         être migrées. Dans l'exemple suivant, les requêtes qui correspondent à
         <em>au moins un</em> critère sont acceptées :</p>
          <div class="example"><h3>Version 2.2 :</h3><pre class="prettyprint lang-config">Order allow,deny
    Deny from all
    Satisfy any
    Allow from 127.0.0.1
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
          <div class="example"><h3>Version 2.4 :</h3><pre class="prettyprint lang-config">AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    # Implicite : &lt;RequireAny&gt;
    Require valid-user
    Require ip 127.0.0.1</pre>
    </div>
    
        
        
        <h3><a name="config" id="config">Autres changements dans la configuration</a></h3>
          
    
          <p>D'autres ajustements mineurs peuvent s'avérer nécessaires pour
          certaines configurations particulières, comme décrit ci-dessous.</p>
    
          <ul>
            <li>La directive <code class="directive">MaxRequestsPerChild</code> a été renommée en
    	<code class="directive"><a href="./mod/mpm_common.html#maxconnectionsperchild">MaxConnectionsPerChild</a></code>;
    	ce nouveau nom reflète mieux l'usage de cette directive.
    	L'ancien nom est encore supporté.</li>
    
    	<li>La directive <code class="directive">MaxClients</code> a
    	été renommée en <code class="directive"><a href="./mod/mpm_common.html#maxrequestworkers">MaxRequestWorkers</a></code>; ce nouveau
    	nom reflète mieux l'usage de cette directive. Pour les
    	modules multiprocessus asynchrones, comme <code class="module"><a href="./mod/event.html">event</a></code>, le nombre
    	maximal de clients n'est pas équivalent au nombre de threads du
    	worker. L'ancien nom est encore supporté.</li>
    
            <li>La directive <code class="directive"><a href="./mod/core.html#defaulttype">DefaultType</a></code> ne produit plus aucun
    	effet, si ce n'est d'émettre un avertissement si elle est
    	définie à une valeur autre que <code>none</code>. D'autres
    	directives de configuration la remplacent dans la version 2.4.
            </li>
    
    	<li>La valeur par défaut de la directive <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> est maintenant
    	<code>None</code>.</li>
    
    	<li>La valeur par défaut de la directive <code class="directive"><a href="./mod/core.html#enablesendfile">EnableSendfile</a></code> est maintenant Off.</li>
    
    	<li>La valeur par défaut de la directive <code class="directive"><a href="./mod/core.html#fileetag">FileETag</a></code> est maintenant "MTime Size"
    	(sans INode).</li>
    
            <li><code class="module"><a href="./mod/mod_dav_fs.html">mod_dav_fs</a></code>: le format du fichier <code class="directive"><a href="./mod/mod_dav_fs.html#davlockdb">DavLockDB</a></code> a changé pour les systèmes
    	avec inodes. L'ancien fichier <code class="directive"><a href="./mod/mod_dav_fs.html#davlockdb">DavLockDB</a></code> doit être supprimé dans le
    	cadre de la mise à jour.
            </li>
    
            <li>La directive <code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code>
    	n'accepte que les valeurs <code>On</code> ou <code>Off</code>.
    	Avant, toute valeur autre que "Off" ou "0" était traitée comme
    	"On".</li>
    
            <li>Les directives AcceptMutex, LockFile, RewriteLock, SSLMutex,
    	SSLStaplingMutex et WatchdogMutexPath ont été remplacées par la
    	directive unique <code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>.
    	Vous devez évaluer l'impact de ces directives obsolètes dans
    	votre configuration version 2.2 afin de déterminer si elles
    	peuvent être simplement supprimées, ou si elles doivent être
    	remplacées par la directive <code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>.</li>
    
            <li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>: la directive <code class="directive"><a href="./mod/mod_cache.html#cacheignoreurlsessionidentifiers">CacheIgnoreURLSessionIdentifiers</a></code>
    	effectue maintenant une correspondance exacte dans la chaîne de
    	paramètres au lieu d'une correspondance partielle. Si votre
    	configuration mettait en jeu des sous-chaînes comme
    	<code>sessionid</code> pour correspondre à
    	<code>/une-application/image.gif;jsessionid=123456789</code>,
    	vous devez maintenant utiliser la chaîne de correspondance
    	complète <code>jsessionid</code>.
            </li>
    
    	<li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>: le second paramètre de la
    	directive <code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code>
    	ne concerne les contenus en mandat direct que s'ils débutent par
    	le protocole approprié. Dans les versions 2.2 et antérieures, un
    	paramètre tel que '/' concernait tous les contenus.</li>
    
            <li><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>: la directive <code class="directive"><a href="./mod/mod_ldap.html#ldaptrustedclientcert">LDAPTrustedClientCert</a></code> s'utilise
    	maintenant exclusivement au sein d'une configuration de niveau
    	répertoire. Si vous utilisez cette directive, passez en revue
    	votre configuration pour vous assurer qu'elle est bien présente
    	dans tous les contextes de répertoire nécessaires.</li>
    
    	<li><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>: la syntaxe de la directive
    	<code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code> utilise
    	maintenant une expression booléenne pour déterminer si un filtre
    	s'applique.
            </li>
    
    	<li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code>:
                <ul>
                <li>L'élément <code>#if expr</code> utilise maintenant le
    	    nouvel <a href="expr.html">interpréteur d'expressions</a>.
    	    L'ancienne syntaxe peut être réactivée via la directive
    	    <code class="directive"><a href="./mod/mod_include.html#ssilegacyexprparser">SSILegacyExprParser</a></code>.
                </li>
                <li>Dans la portée du répertoire, une directive de
    	    configuration SSI* ne provoque plus la réinitialisation à
    	    leur valeur par défaut de toutes les directives SSI* de
    	    niveau répertoire.</li>
                </ul>
            </li>
    
            <li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code> : l'option
    	<code>DebugLevel</code> a été supprimée en faveur d'une
    	configuration de la directive <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> au niveau répertoire.
            </li>
    
            <li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> : l'option
    	<code>DebugLevel</code> a été supprimée en faveur d'une
    	configuration de la directive <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> au niveau répertoire.
            </li>
    
    	<li><code class="module"><a href="./mod/mod_proxy_scgi.html">mod_proxy_scgi</a></code>: certaines applications web
    	ne fonctionneront plus correctement avec la nouvelle
    	configuration de <code>PATH_INFO</code> qui est différente de
    	celle de la version 2.2. La configuration
    	précédente peut être
    	restaurée en définissant la variable
    	<code>proxy-scgi-pathinfo</code>.</li>
    
    	<li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>: le contrôle de révocation des
    	certificats basé sur les CRL doit être maintenant explicitement
    	configuré via la directive <code class="directive"><a href="./mod/mod_ssl.html#sslcarevocationcheck">SSLCARevocationCheck</a></code>.
            </li>
    
            <li><code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code>: la taille maximale d'une
    	ligne est maintenant 1Mo.
            </li>
    
            <li><code class="module"><a href="./mod/mod_reqtimeout.html">mod_reqtimeout</a></code>: si ce module est chargé, il
    	définit maintenant certains temps d'attente par défaut.</li>
    
    	<li><code class="module"><a href="./mod/mod_dumpio.html">mod_dumpio</a></code>: la directive
    	<code class="directive">DumpIOLogLevel</code> n'est plus supportée. Les
    	données sont toujours enregistrées au niveau <code>trace7</code>
    	de <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code></li>
    
            <li>Jusqu'à la version 2.2, sur les plateformes de style Unix, 
    	les commandes de redirection des logs définies via <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> ou <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> étaient invoquées
    	en utilisant <code>/bin/sh -c</code>. A
    	partir de la version 2.4, les commandes de redirection des logs
    	sont exécutées directement. Pour retrouver l'ancien
    	comportement, voir la <a href="logs.html#piped">documentation
    	sur la redirection des logs</a></li>
    
        </ul>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="misc" id="misc">Changements divers</a></h2>
        
    
        <ul>
          <li><code class="module"><a href="./mod/mod_auto_index.html">mod_auto_index</a></code>: extrait maintenant les titres
          et affiche la description pour les fichiers .xhtml qui étaient
          jusqu'alors ignorés.</li>
    
          <li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> : le format par défaut des variables
          <code>*_DN</code> a changé. Il est cependant encore possible
          d'utiliser l'ancien format via la nouvelle option
          <code>LegacyDNStringFormat</code> de la directive <code class="directive"><a href="./mod/mod_ssl.html#ssloptions">SSLOptions</a></code>. Le protocole SSLv2 n'est
          plus supporté. Les directives <code class="directive"><a href="./mod/mod_ssl.html#sslproxycheckpeercn">SSLProxyCheckPeerCN</a></code> et
          <code class="directive"><a href="./mod/mod_ssl.html#sslproxycheckpeerexpire">SSLProxyCheckPeerExpire</a></code>
          sont maintenant définies par défaut à On, et les requêtes mandatées
          vers des serveurs HTTPS possèdant des certificats non conformes ou
          périmés échoueront donc avec un code d'erreur 502 (Bad gateway).</li>
    
          <li><code class="program"><a href="./programs/htpasswd.html">htpasswd</a></code> utilise maintenant par défaut les
          condensés MD5 sur toutes les plates-formes.</li>
    
          <li>La directive <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code> n'a plus aucun effet, si
          ce n'est l'émission d'un avertissement. Toute combinaison
          adresse/port apparaissant dans plusieurs serveurs virtuels est
          traitée implicitement comme un serveur virtuel basé sur le nom.
          </li>
    
          <li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> n'effectue plus de compression
          s'il s'aperçoit que la quantité de données ajoutée par la
          compression est supérieure à la quantité de données à compresser.
          </li>
    
          <li>Les pages d'erreur multilingues de la version 2.2.x ne
          fonctionneront qu'après avoir été corrigées pour
          respecter la nouvelle syntaxe de l'élément <code>#if expr=</code>
          du module <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>, ou si la directive
          <code class="directive"><a href="./mod/mod_include.html#ssilegacyexprparser">SSILegacyExprParser</a></code> a
          été activée pour le répertoire contenant les pages d'erreur.
          </li>
    
          <li>La fonctionnalité fournie par <code>mod_authn_alias</code>
          dans les précédentes versions (en fait la directive
          <code class="directive"><a href="./mod/mod_authn_core.html#authnprovideralias">AuthnProviderAlias</a></code>)
          est maintenant fournie par <code class="module"><a href="./mod/mod_authn_core.html">mod_authn_core</a></code>.  
          </li>
    
          <li>Les directives RewriteLog et RewriteLogLevel ont été
          supprimées. Leur fonctions sont maintenant assurées par la
          directive <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> qui permet de définir
          un niveau de journalisation approprié pour le module
          <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>. Voir aussi la section <a href="mod/mod_rewrite.html#logging">journalisation de
          mod_rewrite</a>.</li>
    
        </ul>
    
        </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="third-party" id="third-party">Modules tiers</a></h2>
        
    
    	<p>Tous les modules tiers doivent être recompilés pour la
    	version 2.4 avant d'être chargés.</p>
    
        <p>De nombreux modules tiers conçus pour la version 2.2
        fonctionneront sans changement avec le serveur HTTP Apache
        version 2.4. Certains nécessiteront cependant des modifications ; se
        reporter à la vue d'ensemble <a href="developer/new_api_2_4.html">Mise à jour de l'API</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="commonproblems" id="commonproblems">Problèmes de mise à jour courants</a></h2>
        
        <ul><li>Erreurs au démarrage :
        <ul>
          <li><code>Invalid command 'User', perhaps misspelled or defined by
          a module not included in the server configuration</code> - chargez
          le module <code class="module"><a href="./mod/mod_unixd.html">mod_unixd</a></code></li>
    
          <li><code>Invalid command 'Require', perhaps misspelled or defined
          by a module not included in the server configuration</code>, ou
          <code>Invalid command 'Order', perhaps misspelled or defined by a
          module not included in the server configuration</code> - chargez
          le module <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code>, ou mettez à jour
          vers la version 2.4 les directives d'autorisation.</li>
    
          <li><code>Ignoring deprecated use of DefaultType in line NN of
          /path/to/httpd.conf</code> - supprimez la directive <code class="directive"><a href="./mod/core.html#defaulttype">DefaultType</a></code> et remplacez-la par les
          directives de configuration appropriées.</li>
    
          <li><code>Invalid command 'AddOutputFilterByType', perhaps misspelled 
          or defined by a module not included in the server configuration
          </code> - la directive <code class="directive"><a href="./mod/mod_filter.html#addoutputfilterbytype">AddOutputFilterByType</a></code> qui était
          jusqu'alors implémentée par le module core, l'est maintenant par
          le module mod_filter, qui doit donc être chargé.</li>
    
        </ul></li>
        <li>Erreurs de traitement des requêtes :
        <ul>
          <li><code>configuration error:  couldn't check user: /path</code> -
          chargez le module <code class="module"><a href="./mod/mod_authn_core.html">mod_authn_core</a></code>.</li>
          <li>Les fichiers <code>.htaccess</code> ne sont pas traités -
          Vérifiez la présence d'une directive <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> appropriée ; sa valeur par
          défaut est maintenant <code>None</code>.</li>
        </ul>
        </li>
    </ul>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/upgrading.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/upgrading.html" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/upgrading.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/server-wide.html.fr.utf8���������������������������������������������������0000664�0001751�0001751�00000030640�14740503670�021455� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Configuration à l'échelle du serveur - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Configuration à l'échelle du serveur</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    <p>Ce document explique le fonctionnement de certaines directives du serveur
    de base qui sont utilisées pour configurer les opérations élémentaires du
    serveur.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#identification">Identification du serveur</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#locations">Localisation des fichiers</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#resource">Limitation de l'utilisation des ressources</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#implementation">Choix d'implémentation</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="identification" id="identification">Identification du serveur</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code></li><li><code class="directive"><a href="./mod/core.html#serversignature">ServerSignature</a></code></li><li><code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code></li></ul></td></tr></table>
    
        <p>Les directives <code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code> et
        <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> contrôlent la nature des
        informations à propos du serveur qui seront affichées dans les documents
        générés par le serveur comme les messages d'erreur. La directive
        <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> définit la valeur du
        champ d'en-tête de la réponse du serveur HTTP.</p>
    
        <p>Le serveur utilise les directives
        <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>,
        <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code> et
        <code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code> pour
        déterminer la manière de construire des URLs vers ses propres ressources.
        Par exemple, quand un client émet une requête vers un répertoire, mais
        n'ajoute pas le slash final au nom du répertoire, httpd doit rediriger le
        client vers le nom complet incluant le slash final afin que le client
        puisse résoudre correctement les références relatives présentes dans
        le document.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="locations" id="locations">Localisation des fichiers</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/mpm_common.html#coredumpdirectory">CoreDumpDirectory</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code></li><li><code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code></li></ul></td></tr></table>
    
        <p>Ces directives contrôlent la localisation des différents fichiers
        nécessaires au bon fonctionnement de httpd. Quand le chemin utilisé ne
        commence pas par un slash (/), la localisation des fichiers est relative
        à la valeur de la directive
        <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code>. Soyez prudent avec la
        localisation de fichiers dans des répertoires où les utilisateurs non root
        ont les droits en écriture. Voir la documention sur les
        <a href="misc/security_tips.html#serverroot">Conseils à propos
        de la sécurité</a> pour plus de détails.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="resource" id="resource">Limitation de l'utilisation des ressources</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#limitrequestbody">LimitRequestBody</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfields">LimitRequestFields</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfieldsize">LimitRequestFieldsize</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestline">LimitRequestLine</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitcpu">RLimitCPU</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitmem">RLimitMEM</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitnproc">RLimitNPROC</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code></li></ul></td></tr></table>
    
        <p>Les directives <code class="directive">LimitRequest</code>* permettent de
        limiter la quantité de ressources consommées par httpd pour le traitement
        des requêtes des clients. Cette limitation permet de minimiser les effets
        de certains types d'attaques par déni de service.</p>
    
        <p>Les directives <code class="directive">RLimit</code>* permettent de limiter la
        quantité de ressources utilisable par les processus initiés (forked) par
        les processus enfants httpd. Elles permettent en particulier de contrôler
        les ressources utilisées par les scripts CGI et les commandes exec des
        "Inclusions côté serveur" (Server Side Includes ou SSI).</p>
    
        <p>La directive <code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code>
        permet sur certaines plates-formes de contrôler la taille de la pile.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">Choix d'implémentation</a></h2>
        
    
        <table class="related"><tr><th>Modules Apparentés</th><th>Directives Apparentées</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code></li></ul></td></tr></table>
    
        <p>La directive <code class="directive">Mutex</code> permet de modifier
        l'implémentation sous-jacente des mutex, afin de résoudre les
        problèmes de fonctionnement ou de performance dus au choix par
        défaut d'<a class="glossarylink" href="./glossary.html#apr" title="voir glossaire">APR</a>.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/server-wide.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/server-wide.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/suexec.html.fr.utf8��������������������������������������������������������0000664�0001751�0001751�00000100366�14740503670�020520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Support suEXEC - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Support suEXEC</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>La fonctionnalité <strong>suEXEC</strong> permet
        l'exécution des programmes <strong>CGI</strong> et
        <strong>SSI</strong> sous un utilisateur autre que celui sous
        lequel s'exécute le serveur web qui appelle ces programmes.
        Normalement, lorsqu'un programme CGI ou SSI est lancé, il
        s'exécute sous le même utilisateur que celui du serveur web qui
        l'appelle.</p>
    
        <p>Utilisée de manière appropriée, cette fonctionnalité peut
        réduire considérablement les risques de sécurité encourus
        lorsqu'on autorise les utilisateurs à développer et faire
        s'exécuter des programmes CGI ou SSI de leur cru. Cependant, mal
        configuré, suEXEC peut causer de nombreux problèmes et même créer
        de nouvelles failles dans la sécurité de votre ordinateur. Si
        vous n'êtes pas familier avec la gestion des programmes
        <em>setuid root</em> et les risques de sécurité qu'ils comportent,
        nous vous recommandons vivement de ne pas tenter
        d'utiliser suEXEC.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#before">Avant de commencer</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#model">Modèle de sécurité de suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">Configurer et installer suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#enable">Activation et désactivation
    de suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">Utilisation de suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#debug">Débogage de suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#jabberwock">Avis à la population !
        Avertissements et exemples</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="before" id="before">Avant de commencer</a></h2>
    
        <p>Avant de foncer tête baissée dans la lecture de ce document,
        vous devez tenir compte de certaines hypothèses concernant vous-même
        et l'environnement dans lequel vous allez utiliser suexec.</p>
    
        <p>Premièrement, vous devez utiliser un système d'exploitation
        UNIX ou dérivé, capable d'effectuer des opérations
        <strong>setuid</strong> et <strong>setgid</strong>. Tous les
        exemples de commande sont donnés en conséquence. D'autres
        plates-formes, même si elles supportent suEXEC, peuvent
        avoir une configuration différente.</p>
    
        <p>Deuxièmement, vous devez être familier avec les concepts de base
        relatifs à la sécurité de votre ordinateur et son administration.
        Ceci implique la compréhension des opérations
        <strong>setuid/setgid</strong> et des différents effets qu'elles
        peuvent produire sur votre système et son niveau de sécurité.</p>
    
        <p>Troisièmement, vous devez utiliser une version
        <strong>non modifiée</strong> du code de suEXEC. L'ensemble du
        code de suEXEC a été scruté et testé avec soin par les développeurs
        et de nombreux bêta testeurs. Toutes les précautions ont été prises
        pour s'assurer d'une base sûre de code non seulement simple, mais
        aussi solide. La modification de ce code peut causer des problèmes
        inattendus et de nouveaux risques de sécurité. Il est
        <strong>vivement</strong> recommandé de ne pas modifier le code de
        suEXEC, à moins que vous ne soyez un programmeur spécialiste des
        particularités liées à la sécurité, et souhaitez partager votre
        travail avec l'équipe de développement du serveur HTTP Apache afin
        de pouvoir en discuter.</p>
    
        <p>Quatrièmement et dernièrement, l'équipe de développement du
        serveur HTTP Apache a décidé de ne
        <strong>PAS</strong> inclure suEXEC dans l'installation par défaut
        d'Apache httpd. Pour pouvoir mettre en oeuvre suEXEC, l'administrateur
        doit porter la plus grande attention aux détails. Après avoir bien
        réfléchi aux différents points de la configuration de suEXEC,
        l'administrateur peut l'installer selon les méthodes classiques.
        Les valeurs des paramètres de configuration doivent être
        déterminées et spécifiées avec soin par l'administrateur, afin de
        maintenir la sécurité du système de manière appropriée lors de
        l'utilisation de la fonctionnalité suEXEC. C'est par le biais de
        ce processus minutieux que nous espérons réserver
        l'installation de suEXEC aux administrateurs prudents et
        suffisamment déterminés à vouloir l'utiliser.</p>
    
        <p>Vous êtes encore avec nous ? Oui ? Bien.
        Alors nous pouvons continuer !</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="model" id="model">Modèle de sécurité de suEXEC</a></h2>
    
        <p>Avant d'installer et configurer suEXEC, nous allons tout d'abord
        décrire le modèle de sécurité que vous êtes sur le point
        d'implémenter. Vous devriez ainsi mieux comprendre ce qui se passe
        vraiment à l'intérieur de suEXEC et quelles précautions ont été
        prises pour préserver la sécurité de votre système.</p>
    
        <p><strong>suEXEC</strong> est basé sur un programme "conteneur"
        (wrapper) setuid qui est appelé par le serveur HTTP Apache principal.
        Ce conteneur est appelé quand une requête HTTP concerne
        un programme CGI ou SSI que l'administrateur
        a décidé de faire s'exécuter
        sous un utilisateur autre que celui du serveur principal.
        Lorsqu'il reçoit une telle requête, Apache httpd fournit au conteneur
        suEXEC le nom du programme, ainsi que les identifiants utilisateur
        et groupe sous lesquels le programme doit s'exécuter.</p>
    
        <p>Le conteneur effectue ensuite les vérifications suivantes afin
        de déterminer la réussite ou l'échec du processus -- si une seule
        de ces conditions n'est pas vérifiée, le programme journalise
        l'erreur et se termine en retournant un code d'erreur, sinon il
        continue :</p>
    
        <ol>
          <li>
            <strong>L'utilisateur qui exécute le conteneur est-il un
    	utilisateur valide de ce système ?</strong>
    
            <p class="indent">
              Ceci permet de s'assurer que l'utilisateur qui exécute le
    	  conteneur est vraiment un utilisateur appartenant au système.
            </p>
         </li>
    
         <li>
            <strong>Le conteneur a-t-il été appelé avec un nombre
    	d'arguments correct ?</strong>
    
            <p class="indent">
              Le conteneur ne s'exécutera que si on lui fournit un nombre
    	  d'arguments correct. Le serveur HTTP apache sait quel est le
    	  bon format des arguments. Si le conteneur ne reçoit pas un
    	  nombre d'arguments correct, soit il a été modifié,
    	  soit quelque chose ne va pas dans la portion suEXEC de
    	  votre binaire Apache httpd.
            </p>
          </li>
    
          <li>
            <strong>Cet utilisateur valide est-il autorisé à exécuter le
    	conteneur ?</strong>
    
            <p class="indent">
              Cet utilisateur est-il celui autorisé à exécuter le
    	  conteneur ? Un seul utilisateur (celui d'Apache) est
    	  autorisé à exécuter ce programme.
            </p>
          </li>
    
          <li>
            <strong>Le chemin du programme CGI ou SSI cible est-il
    	non sûr ?</strong>
    
            <p class="indent">
              Le chemin du programme CGI ou SSI cible débute-t-il par un
    	  '/' ou contient-il une référence arrière '..' ? Ceci est
    	  interdit ; le programme CGI ou SSI cible doit se trouver dans
    	  la hiérarchie de la racine des documents de suEXEC (voir
    	  <code>--with-suexec-docroot=<em>DIR</em></code> ci-dessous).
            </p>
          </li>
    
          <li>
            <strong>Le nom utilisateur cible est-il valide ?</strong>
    
            <p class="indent">
              L'utilisateur cible existe-t-il ?
            </p>
          </li>
    
          <li>
            <strong>Le nom du groupe cible est-il valide ?</strong>
    
            <p class="indent">
              Le groupe cible existe-t-il ?
            </p>
          </li>
    
          <li>
            <strong>L'utilisateur cible n'est-il <em>PAS</em>
    	superutilisateur ?</strong>
    
    
            <p class="indent">
              suEXEc ne permet pas à
    	  <code><em>root</em></code> d'exécuter des programmes CGI/SSI.
            </p>
          </li>
    
          <li>
            <strong>Le numéro de l'identifiant de l'utilisateur cible
    	est-il <em>SUPERIEUR</em> au numéro d'identifiant
    	minimum ?</strong>
    
            <p class="indent">
              Le numéro d'identifiant utilisateur minimum est défini à
    	  l'exécution du script configure. Ceci vous permet de définir
    	  le numéro d'identifiant utilisateur le plus bas qui sera
    	  autorisé à éxécuter des programmes CGI/SSI. En particulier,
    	  cela permet d'écarter les comptes système.
            </p>
          </li>
    
          <li>
            <strong>Le groupe cible n'est-il <em>PAS</em> le groupe
    	superutilisateur ?</strong>
    
            <p class="indent">
              Actuellement, suEXEC ne permet pas au groupe
    	  <code><em>root</em></code> d'exécuter des programmes CGI/SSI.
            </p>
          </li>
    
          <li>
            <strong> Le numéro d'identifiant du groupe cible est-il
    	<em>SUPERIEUR</em> au numéro d'identifiant minimum ?</strong>
    
            <p class="indent">
              Le numéro d'identifiant de groupe minimum est spécifié lors
    	  de l'exécution du script configure. Ceci vous permet de
    	  définir l'identifiant de groupe le plus bas possible qui sera
    	  autorisé à exécuter des programmes CGI/SSI, et est
    	  particulièrement utile pour écarter les groupes "système".
            </p>
          </li>
    
          <li>
            <strong>Le conteneur peut-il obtenir avec succès l'identité
    	des utilisateur et groupe cibles ?</strong>
    
            <p class="indent">
              C'est ici que le programme obtient l'identité des utilisateur
    	  et groupe cibles via des appels à setuid et setgid. De même,
    	  la liste des accès groupe est initialisée avec tous les
    	  groupes auxquels l'utilisateur cible appartient.
            </p>
          </li>
    
          <li>
            <strong>Peut-on se positionner dans le répertoire dans dequel
    	sont situés les programmes CGI/SSI ?</strong>
    
            <p class="indent">
              S'il n'existe pas, il ne peut pas contenir de fichier. Et si
    	  l'on ne peut pas s'y positionner, il n'existe probablement
    	  pas.
            </p>
          </li>
    
          <li>
            <strong>Le répertoire est-il dans l'espace web
    	de httpd ?</strong>
    
            <p class="indent">
              Si la requête concerne une portion de la racine du serveur,
    	  le répertoire demandé est-il dans la hiérarchie de la racine
    	  des documents de suEXEC ? Si la requête concerne un
    	 <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>, le répertoire demandé est-il dans
    	  la hiérarchie du répertoire défini comme le répertoire
    	  utilisateur de suEXEC (voir les
    	  <a href="#install">options de configuration de suEXEC</a>) ?
            </p>
          </li>
    
          <li>
            <strong>L'écriture dans le répertoire est-elle interdite pour
    	un utilisateur autre que le propriétaire </strong>
    
            <p class="indent">
              Le répertoire ne doit pas être ouvert aux autres
    	  utilisateurs ; seul l'utilisateur propriétaire doit pouvoir
    	  modifier le contenu du répertoire.
            </p>
          </li>
    
          <li>
            <strong>Le programme CGI/SSI cible existe-t-il ?</strong>
    
            <p class="indent">
              S'il n'existe pas, il ne peut pas être exécuté.
            </p>
          </li>
    
          <li>
            <strong>Les utilisateurs autres que le propriétaire n'ont-ils
    	<em>PAS</em> de droits en écriture sur le programme
    	CGI/SSI ?</strong>
    
            <p class="indent">
              Les utilisateurs autres que le propriétaire ne doivent pas
    	  pouvoir modifier le programme CGI/SSI.
            </p>
          </li>
    
          <li>
            <strong>Le programme CGI/SSI n'est-il <em>PAS</em> setuid ou
    	setgid ?</strong>
    
            <p class="indent">
              Les programmes cibles ne doivent pas pouvoir modifier à
    	  nouveau les identifiants utilisateur/groupe.
            </p>
          </li>
    
          <li>
            <strong>Le couple utilisateur/groupe cible est-il le même que
    	celui du programme ?</strong>
    
            <p class="indent">
              L'utilisateur est-il le propriétaire du fichier ?
            </p>
          </li>
    
          <li>
            <strong>Peut-on nettoyer avec succès l'environnement des
    	processus afin de garantir la sûreté des opérations ?</strong>
    
            <p class="indent">
              suExec nettoie l'environnement des processus en établissant
    	  un chemin d'exécution sûr (défini lors de la configuration),
    	  et en ne passant que les variables dont les noms font partie
    	  de la liste de l'environnement sûr (créée de même lors de la
    	  configuration).
            </p>
          </li>
    
          <li>
            <strong>Le conteneur peut-il avec succès se substituer au
    	programme CGI/SSI cible et s'exécuter ?</strong>
    
            <p class="indent">
              C'est là où l'exécution de suEXEC s'arrête et où commence
    	  celle du programme CGI/ssi cible.
            </p>
          </li>
        </ol>
    
        <p>Ce sont les opérations standards effectuées par le modèle de
        sécurité du conteneur suEXEC. Il peut paraître strict et est
        susceptible d'imposer de nouvelles limitations et orientations
        dans la conception des programmes CGI/SSI, mais il a été développé
        avec le plus grand soin, étape par étape, en se focalisant sur
        la sécurité.</p>
    
        <p>Pour plus d'informations sur la mesure dans laquelle ce modèle
        de sécurité peut limiter vos possibilités au regard de la
        configuration du serveur, ainsi que les risques de sécurité qui
        peuvent être évités grâce à une configuration appropriée de suEXEC,
        se référer à la section <a href="#jabberwock">"Avis à la population !"</a> de ce document.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">Configurer et installer suEXEC</a></h2>
    
        <p>C'est ici que nous entrons dans le vif du sujet.</p>
    
        <p><strong>Options de configuration de suEXEC</strong><br />
        </p>
    
        <dl>
          <dt><code>--enable-suexec</code></dt>
    
          <dd>Cette option active la fonctionnalité suEXEC qui n'est
          jamais installée ou activée par défaut. Au moins une option
          <code>--with-suexec-xxxxx</code> doit accompagner l'option
          <code>--enable-suexec</code> pour qu'APACI (l'utilitaire de
          configuration de la compilation d'Apache) accepte votre demande
          d'utilisation de la fonctionnalité suEXEC.</dd>
    
          <dt><code>--with-suexec-bin=<em>PATH</em></code></dt>
    
          <dd>Le chemin du binaire <code>suexec</code> doit être codé en
          dur dans le serveur pour des raisons de sécurité. Cette option
          vous permet de modifier le chemin par défaut.
          <em>Par exemple</em>
          <code>--with-suexec-bin=/usr/sbin/suexec</code></dd>
    
          <dt><code>--with-suexec-caller=<em>UID</em></code></dt>
    
          <dd>L'<a href="mod/mpm_common.html#user">utilisateur</a> sous
          lequel httpd s'exécute habituellement. C'est le seul utilisateur
          autorisé à exécuter le wrapper suEXEC.</dd>
    
          <dt><code>--with-suexec-userdir=<em>DIR</em></code></dt>
    
          <dd>Cette option définit le sous-répertoire de la hiérarchie des
          répertoires utilisateurs dans lequel l'utilisation
          de suEXEC sera autorisée. Tous les exécutables situés dans ce
          répertoire seront exécutables par suEXEC sous l'utilisateur
          cible ; ces programmes doivent donc être sûrs. Si vous utilisez
          une directive <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>
          "simple" (c'est à dire ne contenant pas de
          "*"), l'option --with-suexec-userdir
          devra contenir la même valeur. SuEXEC ne fonctionnera pas
          correctement si la directive <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> contient une valeur
          différente du répertoire home de l'utilisateur tel qu'il est
          défini dans le fichier <code>passwd</code>. la valeur par défaut
          est "<code>public_html</code>".<br />
          Si vous avez plusieurs hôtes virtuels avec une directive
          <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> différente
          pour chacun d'entre eux, vous devrez faire en sorte que chaque
          UserDir possède un répertoire parent commun ; donnez alors à
          l'option --with-suexec-userdir le nom
          de ce répertoire commun. <strong>Si tout ceci n'est pas défini
          correctement, les requêtes CGI "~userdir" ne fonctionneront
          pas !</strong></dd>
    
          <dt><code>--with-suexec-docroot=<em>DIR</em></code></dt>
    
          <dd>Cette option fonctionne comme la directive DocumentRoot pour
          httpd. Il s'agit de la seule hiérarchie (en dehors des directives
          <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>) dans laquelle la fonctionnalité suEXEC
          pourra être utilisée. La valeur par défaut est la valeur de
          <code>--datadir</code> accompagnée du suffixe
          "<code>/htdocs</code>" ;
          <em>Par exemple</em>, si vous exécutez configure avec
          "<code>--datadir=/home/apache</code>", la valeur
          "<code>/home/apache/htdocs</code>" sera utilisée par défaut comme
          racine des documents pour le conteneur suEXEC.</dd>
    
          <dt><code>--with-suexec-uidmin=<em>UID</em></code></dt>
    
          <dd>Cette option définit l'identifiant utilisateur le plus bas
          avec lequel un utilisateur pourra être la cible de
          suEXEC. 500 ou 100 sont des valeurs courantes sur la plupart des
          systèmes. la valeur par défaut est 100.</dd>
    
          <dt><code>--with-suexec-gidmin=<em>GID</em></code></dt>
    
          <dd>Cette option définit l'identifiant de groupe le plus bas
          avec lequel un utilisateur pourra être la cible de
          suEXEC. 100 est une valeur courante sur la plupart des
          systèmes et est par conséquent la valeur par défaut.</dd>
    
          <dt><code>--with-suexec-logfile=<em>FILE</em></code></dt>
    
          <dd>Cette option permet de définir le fichier dans lequel
          toutes les transactions et erreurs de suEXEC seront journalisées
          (à des fins d'analyse ou de débogage). Par défaut, le fichier
          journal se nomme "<code>suexec_log</code>" et se trouve dans votre
          répertoire standard des fichiers journaux défini par
          <code>--logfiledir</code></dd>
    
          <dt><code>--with-suexec-safepath=<em>PATH</em></code></dt>
    
          <dd>Cette option permet de définir une variable d'environnement
          PATH sûre à passer aux exécutables CGI. La valeur par défaut
          est "<code>/usr/local/bin:/usr/bin:/bin</code>".</dd>
        </dl>
    
        <h3>Compilation et installation du conteneur suEXEC</h3>
          
    
        <p>Si vous avez activé la fonctionnalité suEXEC à l'aide de
         l'option <code>--enable-suexec</code>, le binaire
         <code>suexec</code> sera automatiquement construit (en même temps
         que httpd) lorsque vous exécuterez la commande
         <code>make</code>.</p>
    
         <p>Lorsque tous les composants auront été construits, vous pourrez
         exécuter la commande <code>make install</code> afin de les
         installer. Le binaire <code>suexec</code> sera installé dans le
         répertoire défini à l'aide de l'option <code>--sbindir</code>. La
         localisation par défaut est "/usr/local/apache2/bin/suexec".</p>
         <p>Veuillez noter que vous aurez besoin des
         <strong><em>privilèges root</em></strong> pour passer l'étape de
         l'installation. Pour que le conteneur puisse changer
         l'identifiant utilisateur, il doit avoir comme propriétaire
         <code><em>root</em></code>, et les droits du fichier doivent
         inclure le bit d'exécution setuserid.</p>
       
    
       <h3>&gt;Mise en place de permissions pour
        paranoïaque</h3>
    	
        <p>Bien que le conteneur suEXEC vérifie que l'utilisateur qui
        l'appelle correspond bien à l'utilisateur spécifié à l'aide de
        l'option <code>--with-suexec-caller</code> du programme
        <code class="program"><a href="./programs/configure.html">configure</a></code>, il subsiste toujours le risque qu'un
        appel système ou une bibliothèque fasse appel à suEXEC avant que
        cette vérification ne soit exploitable sur votre système. Pour
        tenir compte de ceci, et parce que c'est en général la meilleure
        pratique, vous devez utiliser les permissions du système de
        fichiers afin de vous assurer que seul le groupe sous lequel
        s'exécute httpd puisse faire appel à suEXEC.</p>
    
        <p>Si, par exemple, votre serveur web est configuré pour
        s'exécuter en tant que :</p>
    
    <pre class="prettyprint lang-config">User www
    Group webgroup</pre>
    
    
        <p>et <code class="program"><a href="./programs/suexec.html">suexec</a></code> se trouve à
        "/usr/local/apache2/bin/suexec", vous devez exécuter les
        commandes</p>
    
    <div class="example"><p><code>
        chgrp webgroup /usr/local/apache2/bin/suexec<br />
        chmod 4750 /usr/local/apache2/bin/suexec<br />
    </code></p></div>
    
        <p>Ceci permet de s'assurer que seul le groupe sous lequel httpd
        s'exécute (ici webgroup) puisse faire appel au conteneur
        suEXEC.</p>
      
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">Activation et désactivation
    de suEXEC</a></h2>
    
        <p>Au démarrage, httpd vérifie la présence du fichier
        <code class="program"><a href="./programs/suexec.html">suexec</a></code> dans le répertoire défini par
        l'option <code>--sbindir</code> du script configure (le
        répertoire par défaut est "/usr/local/apache/sbin/suexec"). Si
        httpd trouve un conteneur suEXEC correctement configuré, il
        enregistrera le message suivant dans le journal des erreurs :</p>
    
    <div class="example"><p><code>
        [notice] suEXEC mechanism enabled (wrapper: <var>/path/to/suexec</var>)
    </code></p></div>
    
        <p>Si ce message n'est pas généré au démarrage du serveur, ce
        dernier ne trouve probablement pas le programme conteneur à
        l'endroit où il est sensé être, ou l'exécutable suexec n'est pas
        installé en <em>setuid root</em>.</p>
    
         <p>Si le serveur HTTP Apache est déjà en cours d'exécution, et si
         vous activez le mécanisme suEXEC pour la première fois, vous
         devez arrêter et redémarrer httpd. Un redémarrage
         à l'aide d'un simple signal HUP ou USR1 suffira. </p>
         <p>Pour désactiver suEXEC, vous devez supprimer le fichier
         <code class="program"><a href="./programs/suexec.html">suexec</a></code>, puis arrêter et redémarrer
         httpd.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">Utilisation de suEXEC</a></h2>
    
        <p>Les requêtes pour des programmes CGI ne feront appel au
        conteneur suEXEC que si elles concernent un hôte virtuel
        contenant une directive <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code>, ou si elles sont
        traitées par <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code>.</p>
    
        <p><strong>Hôtes virtuels :</strong><br /> Une des méthodes
        d'utilisation du conteneur suEXEC consiste à insérer une
        directive <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> dans une section
        <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code>. En définissant
        des valeurs différentes de celles du serveur principal, toutes les
        requêtes pour des ressources CGI seront exécutées sous
        les <em>User</em> et <em>Group</em> définis pour cette section
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>. Si cette
        directive est absente de la section <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>, l'utilisateur du
        serveur principal sera pris par défaut</p>
    
        <p><strong>Répertoires des utilisateurs :</strong><br /> Avec
        cette méthode, les
        requêtes traitées par <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> appelleront le
        conteneur suEXEC pour exécuter le programme CGI sous l'identifiant
        utilisateur du répertoire utilisateur concerné. Seuls prérequis
        pour pouvoir accéder à cette fonctionnalité : l'exécution des CGI
        doit être activée pour l'utilisateur concerné, et le script doit
        passer avec succès le test des <a href="#model">vérifications de
        sécurité</a> décrit plus haut. Voir aussi l'
        <a href="#install">option de compilation</a>
        <code>--with-suexec-userdir</code>.</p> </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="debug" id="debug">Débogage de suEXEC</a></h2>
    
        <p>Le conteneur suEXEC va écrire ses informations de journalisation
        dans le fichier défini par l'option de compilation
        <code>--with-suexec-logfile</code> comme indiqué plus haut. Si vous
        pensez avoir configuré et installé correctement le conteneur,
        consultez ce journal, ainsi que le journal des erreurs du serveur
        afin de déterminer l'endroit où vous avez fait fausse route.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="jabberwock" id="jabberwock">Avis à la population !
        Avertissements et exemples</a></h2>
    
        <p><strong>NOTE !</strong> Cette section est peut-être
        incomplète.</p>
    
        <p>Quelques points importants du conteneur peuvent
        imposer des contraintes du point de vue de la configuration du
        serveur. Veuillez en prendre connaissance avant de soumettre un
        rapport de bogue à propos de suEXEC.</p>
    
        <p><strong>Points importants à propos de suEXEC</strong></p>
        <ul>
     
          <li>
            Limitations concernant la hiérarchie.
    
            <p class="indent">
              Pour des raisons de sécurité et d'efficacité, toutes les
    	  requêtes suEXEC ne doivent concerner que des ressources
    	  situées dans la racine des documents définie pour les
    	  requêtes concernant un hôte virtuel, ou des ressources
    	  situées dans la racine des documents définies pour les
    	  requêtes concernant un répertoire utilisateur. Par exemple,
    	  si vous avez configuré quatre hôtes virtuels, vous devrez
    	  définir la structure des racines de documents de vos hôtes
    	  virtuels en dehors d'une hiérarchie de documents principale
    	  de httpd, afin de tirer parti de suEXEC dans le contexte des
    	  hôtes virtuels (Exemple à venir).
            </p>
          </li>
    
          <li>
            La variable d'environnement PATH de suEXEC
    
            <p class="indent">
              Modifier cette variable peut s'avérer dangereux. Assurez-vous
    	  que tout chemin que vous ajoutez à cette variable est un
    	  répertoire <strong>de confiance</strong>. Vous n'avez
    	  probablement pas l'intention d'ouvrir votre serveur de façon
    	  à ce que l'on puisse y exécuter un cheval de Troie.
            </p>
          </li>
    
          <li>
            Modification de suEXEC
    
            <p class="indent">
              Encore une fois, ceci peut vous causer de
    	  <strong>graves ennuis</strong> si vous vous y essayez sans
    	  savoir ce que vous faites. Evitez de vous y risquer dans la
    	  mesure du possible.
            </p>
          </li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./en/suexec.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/caching.html.en������������������������������������������������������������0000664�0001751�0001751�00000145246�14737241666�017746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Caching Guide - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Caching Guide</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/caching.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/caching.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/caching.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>This document supplements the <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>,
        <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>, <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> and <a href="programs/htcacheclean.html">htcacheclean</a> reference documentation.
        It describes how to use the Apache HTTP Server's caching features to accelerate web and
        proxy serving, while avoiding common problems and misconfigurations.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#http-caching">Three-state RFC2616 HTTP caching</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Cache Setup Examples</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#socache-caching">General Two-state Key/Value Shared Object Caching</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-caching">Specialized File Caching</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#security">Security Considerations</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
        
        
        <p>The Apache HTTP server offers a range of caching features that
        are designed to improve the performance of the server in various
        ways.</p>
    
        <dl>
            <dt>Three-state RFC2616 HTTP caching</dt>
            <dd>
                <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>
                and its provider modules
                <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>
                provide intelligent, HTTP-aware caching. The content itself is stored
                in the cache, and mod_cache aims to honor all of the various HTTP
                headers and options that control the cacheability of content
                as described in
                <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">Section
                13 of RFC2616</a>.
                <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>
                is aimed at both simple and complex caching configurations, where
                you are dealing with proxied content, dynamic local content or
                have a need to speed up access to local files on a potentially
                slow disk.
            </dd>
    
            <dt>Two-state key/value shared object caching</dt>
            <dd>
                The <a href="socache.html">shared object cache API</a> (socache)
                and its provider modules provide a
                server wide key/value based shared object cache. These modules
                are designed to cache low level data such as SSL sessions and
                authentication credentials. Backends allow the data to be stored
                server wide in shared memory, or datacenter wide in a cache such
                as memcache or distcache.
            </dd>
    
            <dt>Specialized file caching</dt>
            <dd>
                <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code>
                offers the ability to pre-load
                files into memory on server startup, and can improve access
                times and save file handles on files that are accessed often,
                as there is no need to go to disk on each request.
            </dd>
        </dl>
    
        <p>To get the most from this document, you should be familiar with
        the basics of HTTP, and have read the Users' Guides to
        <a href="urlmapping.html">Mapping URLs to the Filesystem</a> and
        <a href="content-negotiation.html">Content negotiation</a>.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="http-caching" id="http-caching">Three-state RFC2616 HTTP caching</a></h2>
    
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code></li><li><code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li><li><code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code></li></ul></td></tr></table>
    
        <p>The HTTP protocol contains built in support for an in-line caching
        mechanism 
        <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">
        described by section 13 of RFC2616</a>, and the
        <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> module can be used to take advantage of
        this.</p>
    
        <p>Unlike a simple two state key/value cache where the content
        disappears completely when no longer fresh, an HTTP cache includes
        a mechanism to retain stale content, and to ask the origin server
        whether this stale content has changed and if not, make it fresh
        again.</p>
    
        <p>An entry in an HTTP cache exists in one of three states:</p>
    
        <dl>
        <dt>Fresh</dt>
        <dd>
            If the content is new enough (younger than its <strong>freshness
            lifetime</strong>), it is considered <strong>fresh</strong>. An
            HTTP cache is free to serve fresh content without making any
            calls to the origin server at all.
        </dd>
        <dt>Stale</dt>
        <dd>
            <p>If the content is too old (older than its <strong>freshness
            lifetime</strong>), it is considered <strong>stale</strong>. An
            HTTP cache should contact the origin server and check whether
            the content is still fresh before serving stale content to a
            client. The origin server will either respond with replacement
            content if not still valid, or ideally, the origin server will
            respond with a code to tell the cache the content is still
            fresh, without the need to generate or send the content again.
            The content becomes fresh again and the cycle continues.</p>
    
            <p>The HTTP protocol does allow the cache to serve stale data
            under certain circumstances, such as when an attempt to freshen
            the data with an origin server has failed with a 5xx error, or
            when another request is already in the process of freshening
            the given entry. In these cases a <code>Warning</code> header
            is added to the response.</p>
        </dd>
        <dt>Non Existent</dt>
        <dd>
            If the cache gets full, it reserves the option to delete content
            from the cache to make space. Content can be deleted at any time,
            and can be stale or fresh. The <a href="programs/htcacheclean.html">htcacheclean</a> tool can be
            run on a once off basis, or deployed as a daemon to keep the size
            of the cache within the given size, or the given number of inodes.
            The tool attempts to delete stale content before attempting to
            delete fresh content.
        </dd>
        </dl>
    
        <p>Full details of how HTTP caching works can be found in
        <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">
        Section 13 of RFC2616</a>.</p>
    
        <h3>Interaction with the Server</h3>
          
    
          <p>The <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> module hooks into the server in two
          possible places depending on the value of the
          <code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code> directive:
          </p>
    
          <dl>
            <dt>Quick handler phase</dt>
            <dd>
              <p>This phase happens very early on during the request processing,
                  just after the request has been parsed. If the content is
                  found within the cache, it is served immediately and almost
                  all request processing is bypassed.</p>
    
                  <p>In this scenario, the cache behaves as if it has been "bolted
                  on" to the front of the server.</p>
                  
                  <p>This mode offers the best performance, as the majority of
                  server processing is bypassed. This mode however also bypasses the
                  authentication and authorization phases of server processing, so
                  this mode should be chosen with care when this is important.</p>
      
                  <p> Requests with an "Authorization" header (for example, HTTP Basic
                  Authentication) are neither cacheable nor served from the cache 
                  when <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> is running in this phase.</p>
              </dd>
              <dt>Normal handler phase</dt>
              <dd>
                  <p>This phase happens late in the request processing, after all
                  the request phases have completed.</p>
    
                  <p>In this scenario, the cache behaves as if it has been "bolted
                  on" to the back of the server.</p>
    
                  <p>This mode offers the most flexibility, as the potential exists
                  for caching to occur at a precisely controlled point in the filter
                  chain, and cached content can be filtered or personalized before
                  being sent to the client.</p>
              </dd>
            </dl>
    
            <p>If the URL is not found within the cache, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>
            will add a <a href="filter.html">filter</a> to the filter stack in order
            to record the response to the cache, and then stand down, allowing normal
            request processing to continue. If the content is determined to be
            cacheable, the content will be saved to the cache for future serving,
            otherwise the content will be ignored.</p>
    
            <p>If the content found within the cache is stale, the
            <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> module converts the request into a
            <strong>conditional request</strong>. If the origin server responds with
            a normal response, the normal response is cached, replacing the content
            already cached. If the origin server responds with a 304 Not Modified
            response, the content is marked as fresh again, and the cached content
            is served by the filter instead of saving it.</p>
        
    
        <h3>Improving Cache Hits</h3>
          
    
          <p>When a virtual host is known by one of many different server aliases,
          ensuring that <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code> is
          set to <code>On</code> can dramatically improve the ratio of cache hits.
          This is because the hostname of the virtual-host serving the content is
          used within the cache key. With the setting set to <code>On</code>
          virtual-hosts with multiple server names or aliases will not produce
          differently cached entities, and instead content will be cached as
          per the canonical hostname.</p>
    
        
    
        <h3>Freshness Lifetime</h3>
          
    
          <p>Well formed content that is intended to be cached should declare an
          explicit freshness lifetime with the <code>Cache-Control</code>
          header's <code>max-age</code> or <code>s-maxage</code> fields, or
          by including an <code>Expires</code> header.</p>
          
          <p>At the same time, the origin server defined freshness lifetime can
          be overridden by a client when the client presents their own
          <code>Cache-Control</code> header within the request. In this case,
          the lowest freshness lifetime between request and response wins.</p>
    
          <p>When this freshness lifetime is missing from the request or the
          response, a default freshness lifetime is applied. The default
          freshness lifetime for cached entities is one hour, however
          this can be easily over-ridden by using the <code class="directive"><a href="./mod/mod_cache.html#cachedefaultexpire">CacheDefaultExpire</a></code> directive.</p>
    
          <p>If a response does not include an <code>Expires</code> header but does
          include a <code>Last-Modified</code> header, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>
          can infer a freshness lifetime based on a heuristic, which can be
          controlled through the use of the <code class="directive"><a href="./mod/mod_cache.html#cachelastmodifiedfactor">CacheLastModifiedFactor</a></code> directive.</p>
    
          <p>For local content, or for remote content that does not define its own
          <code>Expires</code> header, <code class="module"><a href="./mod/mod_expires.html">mod_expires</a></code> may be used to
          fine-tune the freshness lifetime by adding <code>max-age</code> and
          <code>Expires</code>.</p>
    
          <p>The maximum freshness lifetime may also be controlled by using the
          <code class="directive"><a href="./mod/mod_cache.html#cachemaxexpire">CacheMaxExpire</a></code>.</p>
    
        
    
        <h3>A Brief Guide to Conditional Requests</h3>
          
    
          <p>When content expires from the cache and becomes stale, rather than
          pass on the original request, httpd will modify the request to make
          it conditional instead.</p>
    
          <p>When an <code>ETag</code> header exists in the original cached
          response, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> will add an
          <code>If-None-Match</code> header to the request to the origin server.
          When a <code>Last-Modified</code> header exists in the original
          cached response, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> will add an
          <code>If-Modified-Since</code> header to the request to the origin
          server. Performing either of these actions makes the request
          <strong>conditional</strong>.</p>
    
          <p>When a conditional request is received by an origin server, the
          origin server should check whether the ETag or the Last-Modified
          parameter has changed, as appropriate for the request. If not, the
          origin should respond with a terse "304 Not Modified" response. This
          signals to the cache that the stale content is still fresh should be
          used for subsequent requests until the content's new freshness lifetime
          is reached again.</p>
    
          <p>If the content has changed, then the content is served as if the
          request were not conditional to begin with.</p>
    
          <p>Conditional requests offer two benefits. Firstly, when making such
          a request to the origin server, if the content from the origin
          matches the content in the cache, this can be determined easily and
          without the overhead of transferring the entire resource.</p>
    
          <p>Secondly, a well designed origin server will be designed in such
          a way that conditional requests will be significantly cheaper to
          produce than a full response. For static files, typically all that is
          involved is a call to <code>stat()</code> or similar system call, to
          see if the file has changed in size or modification time. As such, even
          local content may still be served faster from the cache if it has not
          changed.</p>
          
          <p>Origin servers should make every effort to support conditional
          requests as is practical, however if conditional requests are not
          supported, the origin will respond as if the request was not
          conditional, and the cache will respond as if the content had changed
          and save the new content to the cache. In this case, the cache will
          behave like a simple two state cache, where content is effectively
          either fresh or deleted.</p>
        
    
        <h3>What Can be Cached?</h3>
          
    
          <p>The full definition of which responses can be cached by an HTTP
          cache is defined in
          <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4">
          RFC2616 Section 13.4 Response Cacheability</a>, and can be summed up as
          follows:</p>
    
          <ol>
            <li>Caching must be enabled for this URL. See the <code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code> and <code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code> directives.</li>
    
            <li>If the response has an HTTP status code other than 200, 203, 300, 
            301 or 410 it must also specify an "Expires" or "Cache-Control" header.
            </li>
    
            <li>The request must be a HTTP GET request.</li>
    
            <li>If the response contains an "Authorization:" header, it must
            also contain an "s-maxage", "must-revalidate" or "public" option
            in the "Cache-Control:" header, or it won't be cached.</li>
    
            <li>If the URL included a query string (e.g. from a HTML form GET
            method) it will not be cached unless the response specifies an
            explicit expiration by including an "Expires:" header or the max-age
            or s-maxage directive of the "Cache-Control:" header, as per RFC2616
            sections 13.9 and 13.2.1.</li>
    
            <li>If the response has a status of 200 (OK), the response must
            also include at least one of the "Etag", "Last-Modified" or
            the "Expires" headers, or the max-age or s-maxage directive of
            the "Cache-Control:" header, unless the
            <code class="directive"><a href="./mod/mod_cache.html#cacheignorenolastmod">CacheIgnoreNoLastMod</a></code>
            directive has been used to require otherwise.</li>
    
            <li>If the response includes the "private" option in a "Cache-Control:"
            header, it will not be stored unless the
            <code class="directive"><a href="./mod/mod_cache.html#cachestoreprivate">CacheStorePrivate</a></code> has been
            used to require otherwise.</li>
    
            <li>Likewise, if the response includes the "no-store" option in a
            "Cache-Control:" header, it will not be stored unless the
            <code class="directive"><a href="./mod/mod_cache.html#cachestorenostore">CacheStoreNoStore</a></code> has been
            used.</li>
    
            <li>A response will not be stored if it includes a "Vary:" header
            containing the match-all "*".</li>
          </ol>
        
    
        <h3>What Should Not be Cached?</h3>
          
    
          <p>It should be up to the client creating the request, or the origin
          server constructing the response to decide whether or not the content
          should be cacheable or not by correctly setting the
          <code>Cache-Control</code> header, and <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> should
          be left alone to honor the wishes of the client or server as appropriate.
          </p>
    
          <p>Content that is time sensitive, or which varies depending on the
          particulars of the request that are not covered by HTTP negotiation,
          should not be cached. This content should declare itself uncacheable
          using the <code>Cache-Control</code> header.</p>
          
          <p>If content changes often, expressed by a freshness lifetime of minutes
          or seconds, the content can still be cached, however it is highly
          desirable that the origin server supports
          <strong>conditional requests</strong> correctly to ensure that
          full responses do not have to be generated on a regular basis.</p>
    
          <p>Content that varies based on client provided request headers can be
          cached through intelligent use of the <code>Vary</code> response
          header.</p>
    
        
    
        <h3>Variable/Negotiated Content</h3>
          
    
          <p>When the origin server is designed to respond with different content
          based on the value of headers in the request, for example to serve
          multiple languages at the same URL, HTTP's caching mechanism makes it
          possible to cache multiple variants of the same page at the same URL.</p>
          
          <p>This is done by the origin server adding a <code>Vary</code> header
          to indicate which headers must be taken into account by a cache when
          determining whether two variants are different from one another.</p>
    
          <p>If for example, a response is received with a vary header such as;</p>
    
          <div class="example"><p><code>
    Vary: negotiate,accept-language,accept-charset
          </code></p></div>
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> will only serve the cached content to
          requesters with accept-language and accept-charset headers
          matching those of the original request.</p>
          
          <p>Multiple variants of the content can be cached side by side,
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> uses the <code>Vary</code> header and the
          corresponding values of the request headers listed by <code>Vary</code>
          to decide on which of many variants to return to the client.</p>
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Cache Setup Examples</a></h2>
    
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></li><li><code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code></li><li><code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code></li><li><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cacheroot">CacheRoot</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code></li><li><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code></li><li><code class="directive"><a href="./mod/mod_cache_socache.html#cachesocache">CacheSocache</a></code></li></ul></td></tr></table>
    
        <h3><a name="disk" id="disk">Caching to Disk</a></h3>
          
    
          <p>The <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> module relies on specific backend store
          implementations in order to manage the cache, and for caching to disk
          <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> is provided to support this.</p>
    
          <p>Typically the module will be configured as so;</p>
    
          <pre class="prettyprint lang-config">CacheRoot   "/var/cache/apache/"
    CacheEnable disk /
    CacheDirLevels 2
    CacheDirLength 1</pre>
    
    
          <p>Importantly, as the cached files are locally stored, operating system
          in-memory caching will typically be applied to their access also. So
          although the files are stored on disk, if they are frequently accessed
          it is likely the operating system will ensure that they are actually
          served from memory.</p>
    
        
    
        <h3>Understanding the Cache-Store</h3>
          
    
          <p>To store items in the cache, <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> creates
          a 22 character hash of the URL being requested. This hash incorporates
          the hostname, protocol, port, path and any CGI arguments to the URL,
          as well as elements defined by the Vary header to ensure that multiple
          URLs do not collide with one another.</p>
    
          <p>Each character may be any one of 64-different characters, which mean
          that overall there are 64^22 possible hashes. For example, a URL might
          be hashed to <code>xyTGxSMO2b68mBCykqkp1w</code>. This hash is used
          as a prefix for the naming of the files specific to that URL within
          the cache, however first it is split up into directories as per
          the <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code> and
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>
          directives.</p>
    
          <p><code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code>
          specifies how many levels of subdirectory there should be, and
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>
          specifies how many characters should be in each directory. With
          the example settings given above, the hash would be turned into
          a filename prefix as
          <code>/var/cache/apache/x/y/TGxSMO2b68mBCykqkp1w</code>.</p>
    
          <p>The overall aim of this technique is to reduce the number of
          subdirectories or files that may be in a particular directory,
          as most file-systems slow down as this number increases. With
          setting of "1" for
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>
          there can at most be 64 subdirectories at any particular level.
          With a setting of 2 there can be 64 * 64 subdirectories, and so on.
          Unless you have a good reason not to, using a setting of "1"
          for <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlength">CacheDirLength</a></code>
          is recommended.</p>
    
          <p>Setting
          <code class="directive"><a href="./mod/mod_cache_disk.html#cachedirlevels">CacheDirLevels</a></code>
          depends on how many files you anticipate to store in the cache.
          With the setting of "2" used in the above example, a grand
          total of 4096 subdirectories can ultimately be created. With
          1 million files cached, this works out at roughly 245 cached
          URLs per directory.</p>
    
          <p>Each URL uses at least two files in the cache-store. Typically
          there is a ".header" file, which includes meta-information about
          the URL, such as when it is due to expire and a ".data" file
          which is a verbatim copy of the content to be served.</p>
    
          <p>In the case of a content negotiated via the "Vary" header, a
          ".vary" directory will be created for the URL in question. This
          directory will have multiple ".data" files corresponding to the
          differently negotiated content.</p>
        
    
        <h3>Maintaining the Disk Cache</h3>
          
    
          <p>The <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> module makes no attempt to
          regulate the amount of disk space used by the cache, although it
          will gracefully stand down on any disk error and behave as if the
          cache was never present.</p>
    
          <p>Instead, provided with httpd is the <a href="programs/htcacheclean.html">htcacheclean</a> tool which allows you
          to clean the cache periodically. Determining how frequently to run <a href="programs/htcacheclean.html">htcacheclean</a> and what target size to
          use for the cache is somewhat complex and trial and error may be needed to
          select optimal values.</p>
    
          <p><a href="programs/htcacheclean.html">htcacheclean</a> has two modes of
          operation. It can be run as persistent daemon, or periodically from
          cron. <a href="programs/htcacheclean.html">htcacheclean</a> can take up to an hour
          or more to process very large (tens of gigabytes) caches and if you are
          running it from cron it is recommended that you determine how long a typical
          run takes, to avoid running more than one instance at a time.</p>
     
          <p>It is also recommended that an appropriate "nice" level is chosen for
          htcacheclean so that the tool does not cause excessive disk io while the
          server is running.</p>
    
          <p class="figure">
          <img src="images/caching_fig1.gif" alt="" width="600" height="406" /><br />
          <a id="figure1" name="figure1"><dfn>Figure 1</dfn></a>: Typical
          cache growth / clean sequence.</p>
    
          <p>Because <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> does not itself pay attention
          to how much space is used you should ensure that
          <a href="programs/htcacheclean.html">htcacheclean</a> is configured to
          leave enough "grow room" following a clean.</p>
        
    
        <h3><a name="memcache" id="memcache">Caching to memcached</a></h3>
          
    
          <p>Using the <code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code> module, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>
          can cache data from a variety of implementations (aka: "providers"). Using the
          <code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code> module, for example, one can specify that
          <a href="http://memcached.org">memcached</a> is to be used as the
          the backend storage mechanism.</p>
    
          <p>Typically the module will be configured as so:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache memcache:memcd.example.com:11211</pre>
    
    
          <p>Additional <code>memcached</code> servers can be specified by
          appending them to the end of the <code>CacheSocache memcache:</code>
          line separated by commas:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache memcache:mem1.example.com:11211,mem2.example.com:11212</pre>
    
    
          <p>This format is also used with the other various <code class="module"><a href="./mod/mod_cache_socache.html">mod_cache_socache</a></code>
          providers. For example:</p>
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache shmcb:/path/to/datafile(512000)</pre>
    
    
          <pre class="prettyprint lang-config">CacheEnable socache /
    CacheSocache dbm:/path/to/datafile</pre>
    
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="socache-caching" id="socache-caching">General Two-state Key/Value Shared Object Caching</a></h2>
    
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code></li><li><code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code></li><li><code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code></li><li><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></li><li><code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code></li><li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code></li></ul></td></tr></table>
        
        <p>The Apache HTTP server offers a low level shared object cache for
        caching information such as SSL sessions, or authentication credentials,
        within the <a href="socache.html">socache</a> interface.</p>
    
        <p>Additional modules are provided for each implementation, offering the
        following backends:</p>
    
        <dl>
        <dt><code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code></dt>
        <dd>DBM based shared object cache.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code></dt>
        <dd>Distcache based shared object cache.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code></dt>
        <dd>Memcache based shared object cache.</dd>
        <dt><code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code></dt>
        <dd>Shared memory based shared object cache.</dd>
        </dl>
    
        <h3><a name="mod_authn_socache-caching" id="mod_authn_socache-caching">Caching Authentication Credentials</a></h3>
          
    
          <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code></li></ul></td></tr></table>
    
          <p>The <code class="module"><a href="./mod/mod_authn_socache.html">mod_authn_socache</a></code> module allows the result of
          authentication to be cached, relieving load on authentication backends.</p>
    
        
    
        <h3><a name="mod_ssl-caching" id="mod_ssl-caching">Caching SSL Sessions</a></h3>
          
    
          <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code></li></ul></td></tr></table>
    
          <p>The <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> module uses the <code>socache</code> interface
          to provide a session cache and a stapling cache.</p>
    
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-caching" id="file-caching">Specialized File Caching</a></h2>
    
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code></li><li><code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code></li></ul></td></tr></table>
    
        <p>On platforms where a filesystem might be slow, or where file
        handles are expensive, the option exists to pre-load files into
        memory on startup.</p>
    
        <p>On systems where opening files is slow, the option exists to
        open the file on startup and cache the file handle. These
        options can help on systems where access to static files is
        slow.</p>
    
        <h3><a name="filehandle" id="filehandle">File-Handle Caching</a></h3>
          
    
          <p>The act of opening a file can itself be a source of delay, particularly
          on network filesystems. By maintaining a cache of open file descriptors
          for commonly served files, httpd can avoid this delay. Currently httpd
          provides one implementation of File-Handle Caching.</p>
    
          <h4>CacheFile</h4>
            
    
            <p>The most basic form of caching present in httpd is the file-handle
            caching provided by <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code>. Rather than caching
            file-contents, this cache maintains a table of open file descriptors. Files
            to be cached in this manner are specified in the configuration file using
            the <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code>
            directive.</p>
    
            <p>The
            <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code> directive
            instructs httpd to open the file when it is started and to re-use
            this file-handle for all subsequent access to this file.</p>
    
            <pre class="prettyprint lang-config">CacheFile /usr/local/apache2/htdocs/index.html</pre>
    
    
            <p>If you intend to cache a large number of files in this manner, you
            must ensure that your operating system's limit for the number of open
            files is set appropriately.</p>
    
            <p>Although using <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code>
            does not cause the file-contents to be cached per-se, it does mean
            that if the file changes while httpd is running these changes will
            not be picked up. The file will be consistently served as it was
            when httpd was started.</p>
    
            <p>If the file is removed while httpd is running, it will continue
            to maintain an open file descriptor and serve the file as it was when
            httpd was started. This usually also means that although the file
            will have been deleted, and not show up on the filesystem, extra free
            space will not be recovered until httpd is stopped and the file
            descriptor closed.</p>
          
    
        
    
        <h3><a name="inmemory" id="inmemory">In-Memory Caching</a></h3>
          
    
          <p>Serving directly from system memory is universally the fastest method
          of serving content. Reading files from a disk controller or, even worse,
          from a remote network is orders of magnitude slower. Disk controllers
          usually involve physical processes, and network access is limited by
          your available bandwidth. Memory access on the other hand can take mere
          nano-seconds.</p>
    
          <p>System memory isn't cheap though, byte for byte it's by far the most
          expensive type of storage and it's important to ensure that it is used
          efficiently. By caching files in memory you decrease the amount of
          memory available on the system. As we'll see, in the case of operating
          system caching, this is not so much of an issue, but when using
          httpd's own in-memory caching it is important to make sure that you
          do not allocate too much memory to a cache. Otherwise the system
          will be forced to swap out memory, which will likely degrade
          performance.</p>
    
          <h4>Operating System Caching</h4>
            
    
            <p>Almost all modern operating systems cache file-data in memory managed
            directly by the kernel. This is a powerful feature, and for the most
            part operating systems get it right. For example, on Linux, let's look at
            the difference in the time it takes to read a file for the first time
            and the second time;</p>
    
            <div class="example"><pre>colm@coroebus:~$ time cat testfile &gt; /dev/null
    real    0m0.065s
    user    0m0.000s
    sys     0m0.001s
    colm@coroebus:~$ time cat testfile &gt; /dev/null
    real    0m0.003s
    user    0m0.003s
    sys     0m0.000s</pre></div>
    
            <p>Even for this small file, there is a huge difference in the amount
            of time it takes to read the file. This is because the kernel has cached
            the file contents in memory.</p>
    
            <p>By ensuring there is "spare" memory on your system, you can ensure
            that more and more file-contents will be stored in this cache. This
            can be a very efficient means of in-memory caching, and involves no
            extra configuration of httpd at all.</p>
    
            <p>Additionally, because the operating system knows when files are
            deleted or modified, it can automatically remove file contents from the
            cache when necessary. This is a big advantage over httpd's in-memory
            caching which has no way of knowing when a file has changed.</p>
          
    
          <p>Despite the performance and advantages of automatic operating system
          caching there are some circumstances in which in-memory caching may be
          better performed by httpd.</p>
    
          <h4>MMapFile Caching</h4>
            
    
            <p><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code> provides the
            <code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code> directive, which
            allows you to have httpd map a static file's contents into memory at
            start time (using the mmap system call). httpd will use the in-memory
            contents for all subsequent accesses to this file.</p>
    
            <pre class="prettyprint lang-config">MMapFile /usr/local/apache2/htdocs/index.html</pre>
    
    
            <p>As with the
            <code class="directive"><a href="./mod/mod_file_cache.html#cachefile">CacheFile</a></code> directive, any
            changes in these files will not be picked up by httpd after it has
            started.</p>
    
            <p> The <code class="directive"><a href="./mod/mod_file_cache.html#mmapfile">MMapFile</a></code>
            directive does not keep track of how much memory it allocates, so
            you must ensure not to over-use the directive. Each httpd child
            process will replicate this memory, so it is critically important
            to ensure that the files mapped are not so large as to cause the
            system to swap memory.</p>
          
        
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Security Considerations</a></h2>
        
    
        <h3>Authorization and Access Control</h3>
          
    
          <p>Using <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> in its default state where
          <code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code> is set to
          <code>On</code> is very much like having a caching reverse-proxy bolted
          to the front of the server. Requests will be served by the caching module
          unless it determines that the origin server should be queried just as an
          external cache would, and this drastically changes the security model of
          httpd.</p>
    
          <p>As traversing a filesystem hierarchy to examine potential
          <code>.htaccess</code> files would be a very expensive operation,
          partially defeating the point of caching (to speed up requests),
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> makes no decision about whether a cached
          entity is authorised for serving. In other words; if
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> has cached some content, it will be served
          from the cache as long as that content has not expired.</p>
    
          <p>If, for example, your configuration permits access to a resource by IP
          address you should ensure that this content is not cached. You can do this
          by using the <code class="directive"><a href="./mod/mod_cache.html#cachedisable">CacheDisable</a></code>
          directive, or <code class="module"><a href="./mod/mod_expires.html">mod_expires</a></code>. Left unchecked,
          <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> - very much like a reverse proxy - would cache
          the content when served and then serve it to any client, on any IP
          address.</p>
    
          <p>When the <code class="directive"><a href="./mod/mod_cache.html#cachequickhandler">CacheQuickHandler</a></code>
          directive is set to <code>Off</code>, the full set of request processing
          phases are executed and the security model remains unchanged.</p>
        
    
        <h3>Local exploits</h3>
          
    
          <p>As requests to end-users can be served from the cache, the cache
          itself can become a target for those wishing to deface or interfere with
          content. It is important to bear in mind that the cache must at all
          times be writable by the user which httpd is running as. This is in
          stark contrast to the usually recommended situation of maintaining
          all content unwritable by the Apache user.</p>
    
          <p>If the Apache user is compromised, for example through a flaw in
          a CGI process, it is possible that the cache may be targeted. When
          using <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>, it is relatively easy to
          insert or modify a cached entity.</p>
    
          <p>This presents a somewhat elevated risk in comparison to the other
          types of attack it is possible to make as the Apache user. If you are
          using <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> you should bear this in mind -
          ensure you upgrade httpd when security upgrades are announced and
          run CGI processes as a non-Apache user using <a href="suexec.html">suEXEC</a> if possible.</p>
    
        
    
        <h3>Cache Poisoning</h3>
          
    
          <p>When running httpd as a caching proxy server, there is also the
          potential for so-called cache poisoning. Cache Poisoning is a broad
          term for attacks in which an attacker causes the proxy server to
          retrieve incorrect (and usually undesirable) content from the origin
          server.</p>
    
          <p>For example if the DNS servers used by your system running httpd
          are vulnerable to DNS cache poisoning, an attacker may be able to control
          where httpd connects to when requesting content from the origin server.
          Another example is so-called HTTP request-smuggling attacks.</p>
    
          <p>This document is not the correct place for an in-depth discussion
          of HTTP request smuggling (instead, try your favourite search engine)
          however it is important to be aware that it is possible to make
          a series of requests, and to exploit a vulnerability on an origin
          webserver such that the attacker can entirely control the content
          retrieved by the proxy.</p>
        
    
        <h3>Denial of Service / Cachebusting</h3>
          
    
          <p>The Vary mechanism allows multiple variants of the same URL to be
          cached side by side. Depending on header values provided by the client,
          the cache will select the correct variant to return to the client. This
          mechanism can become a problem when an attempt is made to vary on a
          header that is known to contain a wide range of possible values under
          normal use, for example the <code>User-Agent</code> header. Depending
          on the popularity of the particular web site thousands or millions of
          duplicate cache entries could be created for the same URL, crowding
          out other entries in the cache.</p>
          
          <p>In other cases, there may be a need to change the URL of a particular
          resource on every request, usually by adding a "cachebuster" string to
          the URL. If this content is declared cacheable by a server for a
          significant freshness lifetime, these entries can crowd out
          legitimate entries in a cache. While <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>
          provides a
          <code class="directive"><a href="./mod/mod_cache.html#cacheignoreurlsessionidentifiers">CacheIgnoreURLSessionIdentifiers</a></code>
          directive, this directive should be used with care to ensure that
          downstream proxy or browser caches aren't subjected to the same denial
          of service issue.</p>
        
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/caching.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/caching.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/caching.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/caching.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dns-caveats.html.en��������������������������������������������������������0000664�0001751�0001751�00000030573�14737241666�020556� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Issues Regarding DNS and Apache HTTP Server - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Issues Regarding DNS and Apache HTTP Server</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/dns-caveats.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>This page could be summarized with the statement: don't
        configure Apache HTTP Server in such a way that it relies on DNS resolution
        for parsing of the configuration files. If httpd requires DNS
        resolution to parse the configuration files then your server
        may be subject to reliability problems (ie. it might not start up),
        or denial and theft of service attacks (including virtual hosts able
        to steal hits from other virtual hosts).</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#example">A Simple Example</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#denial">Denial of Service</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#main">The "main server" Address</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#tips">Tips to Avoid These Problems</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="example" id="example">A Simple Example</a></h2>
        
    
        <pre class="prettyprint lang-config"># This is a misconfiguration example, do not use on your server
    &lt;VirtualHost www.example.dom&gt;
      ServerAdmin webgirl@example.dom
      DocumentRoot "/www/example"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>In order for the server to function properly, it absolutely needs
        to have two pieces of information about each virtual host: the
        <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> and at least one
        IP address that the server will bind and respond to. The above
        example does not include the IP address, so httpd must use DNS
        to find the address of <code>www.example.dom</code>. If for some
        reason DNS is not available at the time your server is parsing
        its config file, then this virtual host <strong>will not be
        configured</strong>. It won't be able to respond to any hits
        to this virtual host.</p>
    
        <p>Suppose that <code>www.example.dom</code> has address 192.0.2.1.
        Then consider this configuration snippet:</p>
    
        <pre class="prettyprint lang-config"># This is a misconfiguration example, do not use on your server
    &lt;VirtualHost 192.0.2.1&gt;
      ServerAdmin webgirl@example.dom
      DocumentRoot "/www/example"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>This time httpd needs to use reverse DNS to find the
        <code>ServerName</code> for this virtualhost. If that reverse
        lookup fails then it will partially disable the virtualhost.
        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 httpd should ever have to generate a full
        URL for the server which includes the server name (such as when a
        Redirect is issued), then it will fail to generate a valid URL.</p>
    
        <p>Here is a snippet that avoids both of these problems:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost 192.0.2.1&gt;
      ServerName www.example.dom
      ServerAdmin webgirl@example.dom
      DocumentRoot "/www/example"
    &lt;/VirtualHost&gt;</pre>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="denial" id="denial">Denial of Service</a></h2>
        
    
        <p>Consider this configuration snippet:</p>
    
        <pre class="prettyprint lang-config">&lt;VirtualHost www.example1.dom&gt;
      ServerAdmin webgirl@example1.dom
      DocumentRoot "/www/example1"
    &lt;/VirtualHost&gt;
    &lt;VirtualHost www.example2.dom&gt;
      ServerAdmin webguy@example2.dom
      DocumentRoot "/www/example2"
    &lt;/VirtualHost&gt;</pre>
    
    
        <p>Suppose that you've assigned 192.0.2.1 to
        <code>www.example1.dom</code> and 192.0.2.2 to
        <code>www.example2.dom</code>. Furthermore, suppose that
        <code>example1.dom</code> has control of their own DNS. With this
        config you have put <code>example1.dom</code> into a position where
        they can steal all traffic destined to <code>example2.dom</code>. To
        do so, all they have to do is set <code>www.example1.dom</code> to
        192.0.2.2. Since they control their own DNS you can't stop them
        from pointing the <code>www.example1.dom</code> record wherever they
        wish.</p>
    
        <p>Requests coming in to 192.0.2.2 (including all those where
        users typed in URLs of the form
        <code>http://www.example2.dom/whatever</code>) will all be served by
        the <code>example1.dom</code> virtual host. To better understand why
        this happens requires a more in-depth discussion of how httpd
        matches up incoming requests with the virtual host that will
        serve it. A rough document describing this <a href="vhosts/details.html">is available</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">The "main server" Address</a></h2>
        
    
        <p><a href="vhosts/name-based.html">Name-based
        virtual host support</a> requires httpd to know
        the IP address(es) of the host that <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        is running on. To get this address it uses either the global
        <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
        (if present) or calls the C function <code>gethostname</code>
        (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.</p>
    
        <p>If you fear that this lookup might fail because your DNS
        server is down then you can insert the hostname in
        <code>/etc/hosts</code> (where you probably already have it so
        that the machine can boot properly). Then ensure that your
        machine is configured to use <code>/etc/hosts</code> in the
        event that DNS fails. Depending on what OS you are using this
        might be accomplished by editing <code>/etc/resolv.conf</code>,
        or maybe <code>/etc/nsswitch.conf</code>.</p>
    
        <p>If your server doesn't have to perform DNS for any other
        reason then you might be able to get away with running httpd
        with the <code>HOSTRESORDER</code> environment variable set to
        "local". This all depends on what OS and resolver libraries you
        are using. It also affects CGIs unless you use
        <code class="module"><a href="./mod/mod_env.html">mod_env</a></code> to control the environment. It's best
        to consult the man pages or FAQs for your OS.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="tips" id="tips">Tips to Avoid These Problems</a></h2>
        
    
        <ul>
          <li>
            use IP addresses in
            <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code>
          </li>
    
          <li>
            use IP addresses in
            <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
          </li>
    
          <li>
            ensure all virtual hosts have an explicit
            <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>
          </li>
    
          <li>create a <code>&lt;VirtualHost _default_:*&gt;</code>
          server that has no pages to serve</li>
        </ul>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/dns-caveats.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/dns-caveats.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/dns-caveats.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/dns-caveats.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/dns-caveats.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/dns-caveats.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/filter.html.en�������������������������������������������������������������0000664�0001751�0001751�00000035532�14737241666�017633� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Filters - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Filters</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/filter.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>This document describes the use of filters in Apache.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#intro">Filtering in Apache 2</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#smart">Smart Filtering</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#service">Exposing Filters as an HTTP Service</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Using Filters</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="intro" id="intro">Filtering in Apache 2</a></h2>
        
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code></li><li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></li><li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></li><li><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code></li><li><code class="module"><a href="./mod/mod_buffer.html">mod_buffer</a></code></li><li><code class="module"><a href="./mod/mod_data.html">mod_data</a></code></li><li><code class="module"><a href="./mod/mod_ratelimit.html">mod_ratelimit</a></code></li><li><code class="module"><a href="./mod/mod_reqtimeout.html">mod_reqtimeout</a></code></li><li><code class="module"><a href="./mod/mod_request.html">mod_request</a></code></li><li><code class="module"><a href="./mod/mod_sed.html">mod_sed</a></code></li><li><code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code></li><li><code class="module"><a href="./mod/mod_xml2enc.html">mod_xml2enc</a></code></li><li><code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_filter.html#filterchain">FilterChain</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterdeclare">FilterDeclare</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprotocol">FilterProtocol</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code></li><li><code class="directive"><a href="./mod/mod_reflector.html#reflectorheader">ReflectorHeader</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilterdefine">ExtFilterDefine</a></code></li><li><code class="directive"><a href="./mod/mod_ext_filter.html#extfilteroptions">ExtFilterOptions</a></code></li><li><code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code></li><li><code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code></li></ul></td></tr></table>
    
    <p>The Filter Chain is available in Apache 2.0 and higher,
    and enables applications to process incoming and outgoing data
    in a highly flexible and configurable manner, regardless of
    where the data comes from.  We can pre-process incoming data,
    and post-process outgoing data, at will.  This is basically
    independent of the traditional request processing phases.</p>
    <p class="figure">
    <img src="images/filter_arch.png" width="569" height="392" alt="Filters can be chained, in a Data Axis orthogonal to request processing" />
    </p>
    <p>Some examples of filtering in the standard Apache distribution are:</p>
    <ul>
    <li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code>, implements server-side includes.</li>
    <li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>, implements SSL encryption (https).</li>
    <li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code>, implements compression/decompression on the fly.</li>
    <li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code>, transcodes between different character sets.</li>
    <li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>, runs an external program as a filter.</li>
    </ul>
    <p>Apache also uses a number of filters internally to perform
    functions like chunking and byte-range handling.</p>
    
    <p>A wider range of applications are implemented by third-party filter
    modules.  A few of these are:</p>
    
    <ul>
    <li>HTML and XML processing and rewriting</li>
    <li>XSLT transforms and XIncludes</li>
    <li>XML Namespace support</li>
    <li>File Upload handling and decoding of HTML Forms</li>
    <li>Image processing</li>
    <li>Protection of vulnerable applications such as PHP scripts</li>
    <li>Text search-and-replace editing</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="smart" id="smart">Smart Filtering</a></h2>
    
    <p class="figure">
    <img src="images/mod_filter_new.png" width="423" height="331" alt="Smart filtering applies different filter providers according to the state of request processing" />
    </p>
    <p><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>, included in Apache 2.1 and later,
    enables the filter chain to be configured dynamically at run time.
    So for example you can set up a proxy to rewrite
    HTML with an HTML filter and JPEG images with a completely
    separate filter, despite the proxy having no prior information
    about what the origin server will send.  This works by using a
    filter harness, that dispatches to different providers according
    to the actual contents at runtime.  Any filter may be either
    inserted directly in the chain and run unconditionally, or
    used as a provider and inserted dynamically.  For example,</p>
    <ul>
    <li>an HTML processing filter will only run if the content is
    text/html or application/xhtml+xml</li>
    <li>A compression filter will only run if the input is a
    compressible type and not already compressed</li>
    <li>A charset conversion filter will be inserted if a text
    document is not already in the desired charset</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="service" id="service">Exposing Filters as an HTTP Service</a></h2>
    
    
    <p>Filters can be used to process content originating from the client in
    addition to processing content originating on the server using the
    <code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code> module.</p>
    
    <p><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code> accepts POST requests from clients, and reflects
    the content request body received within the POST request back in the response,
    passing through the output filter stack on the way back to the client.</p>
    
    <p>This technique can be used as an alternative to a web service running within
    an application server stack, where an output filter provides the transformation
    required on the request body. For example, the <code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code>
    module might be used to provide a general compression service, or an image
    transformation filter might be turned into an image transformation service.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="using" id="using">Using Filters</a></h2>
    
    <p>There are two ways to use filtering: Simple and Dynamic.
    In general, you should use one or the other; mixing them can
    have unexpected consequences (although simple Input filtering
    can be mixed freely with either simple or dynamic Output filtering).</p>
    <p>The Simple Way is the only way to configure input filters, and is
    sufficient for output filters where you need a static filter chain.
    Relevant directives are
        <code class="directive"><a href="./mod/core.html#setinputfilter">SetInputFilter</a></code>,
        <code class="directive"><a href="./mod/core.html#setoutputfilter">SetOutputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#addinputfilter">AddInputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#addoutputfilter">AddOutputFilter</a></code>,
        <code class="directive"><a href="./mod/mod_mime.html#removeinputfilter">RemoveInputFilter</a></code>, and
        <code class="directive"><a href="./mod/mod_mime.html#removeoutputfilter">RemoveOutputFilter</a></code>.</p>
    
    <p>The Dynamic Way enables both static and flexible, dynamic configuration
    of output filters, as discussed in the <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> page.
    Relevant directives are
        <code class="directive"><a href="./mod/mod_filter.html#filterchain">FilterChain</a></code>,
        <code class="directive"><a href="./mod/mod_filter.html#filterdeclare">FilterDeclare</a></code>, and
        <code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code>.</p>
    
    <p>One further directive <code class="directive"><a href="./mod/mod_filter.html#addoutputfilterbytype">AddOutputFilterByType</a></code> is still supported,
    but deprecated.  Use dynamic configuration instead.</p>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/filter.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/filter.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/filter.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/filter.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/filter.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/filter.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/filter.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/custom-error.html.en�������������������������������������������������������0000664�0001751�0001751�00000033121�14737241666�020777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Custom Error Responses - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Custom Error Responses</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/custom-error.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Although the Apache HTTP Server provides generic error responses
        in the event of 4xx or 5xx HTTP status codes, these responses are
        rather stark, uninformative, and can be intimidating to site users.
        You may wish to provide custom error responses which are either
        friendlier, or in some language other than English, or perhaps which
        are styled more in line with your site layout.</p>
    
        <p>Customized error responses can be defined for any HTTP status
        code designated as an error condition - that is, any 4xx or 5xx
        status.</p>
    
        <p>Additionally, a set of values are provided, so
        that the error document can be customized further based on the
        values of these variables, using <a href="howto/ssi.html">Server
        Side Includes</a>. Or, you can have error conditions handled by a
        cgi program, or other dynamic handler (PHP, mod_perl, etc) which
        makes use of these variables.</p>
    
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#configuration">Configuration</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#variables">Available Variables</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#custom">Customizing Error Responses</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#multi-lang">Multi Language Custom Error Documents</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Configuration</a></h2>
    
        <p>Custom error documents are configured using the <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> directive,
        which may be used in global,
        virtualhost, or directory context. It may be used in .htaccess files
        if <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> is set to
        FileInfo.</p>
    
        <pre class="prettyprint lang-config">ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    ErrorDocument 500 /cgi-bin/crash-recover
    ErrorDocument 500 http://error.example.com/server_error.html
    ErrorDocument 404 /errors/not_found.html
    ErrorDocument 401 /subscription/how_to_subscribe.html</pre>
    
    
        <p>The syntax of the <code>ErrorDocument</code> directive is:</p>
    
        <pre class="prettyprint lang-config">ErrorDocument &lt;3-digit-code&gt; &lt;action&gt;</pre>
    
    
        <p>where the action will be treated as:</p>
    
        <ol>
          <li>A local URL to redirect to (if the action begins with a "/").</li>
          <li>An external URL to redirect to (if the action is a valid URL).</li>
          <li>Text to be displayed (if none of the above). The text must be
              wrapped in quotes (") if it consists of more than one word.</li>
        </ol>
    
        <p>When redirecting to a local URL, additional environment variables
        are set so that the response can be further customized. They are not sent to
        external URLs.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="variables" id="variables">Available Variables</a></h2>
    
          <p>Redirecting to another URL can be useful, but only if some
          information can be passed which can then be used to explain or log
          the error condition more clearly.</p>
    
          <p>To achieve this, when the error redirect is sent, additional
          environment variables will be set, which will be generated from
          the headers provided to the original request by prepending
          'REDIRECT_' onto the original header name. This provides the error
          document the context of the original request.</p>
    
          <p>For example, you might receive, in addition to more usual
          environment variables, the following.</p>
    
          <div class="example"><p><code>
            REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/jpeg, image/png<br />
            REDIRECT_HTTP_USER_AGENT=Mozilla/5.0 Fedora/3.5.8-1.fc12 Firefox/3.5.8<br />
            REDIRECT_PATH=.:/bin:/usr/local/bin:/sbin<br />
            REDIRECT_QUERY_STRING=<br />
            REDIRECT_REMOTE_ADDR=121.345.78.123<br />
            REDIRECT_REMOTE_HOST=client.example.com<br />
            REDIRECT_SERVER_NAME=www.example.edu<br />
            REDIRECT_SERVER_PORT=80<br />
            REDIRECT_SERVER_SOFTWARE=Apache/2.2.15<br />
            REDIRECT_URL=/cgi-bin/buggy.pl
          </code></p></div>
    
          <p><code>REDIRECT_</code> environment variables are created from
          the environment variables which existed prior to the
          redirect. They are renamed with a <code>REDIRECT_</code>
          prefix, <em>i.e.</em>, <code>HTTP_USER_AGENT</code> becomes
          <code>REDIRECT_HTTP_USER_AGENT</code>.</p>
    
          <p><code>REDIRECT_URL</code>, <code>REDIRECT_STATUS</code>, and
          <code>REDIRECT_QUERY_STRING</code> are guaranteed to be set, and
          the other headers will be set only if they existed prior to the
          error condition.</p>
    
          <p><strong>None</strong> of these will be
          set if the <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> target is an
          <em>external</em> redirect (anything starting with a
          scheme name like <code>http:</code>, even if it refers to the same host
          as the server).</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="custom" id="custom">Customizing Error Responses</a></h2>
    
          <p>If you point your <code>ErrorDocument</code> to some variety of
          dynamic handler such as a server-side include document, CGI
          script, or some variety of other handler, you may wish to use the
          available custom environment variables to customize this
          response.</p>
    
          <p>If the ErrorDocument specifies a local redirect to a CGI
          script, the script should include a "<code>Status:</code>"
          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:</p>
    
           <pre class="prettyprint lang-perl">...
    print  "Content-type: text/html\n";
    printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    ...</pre>
    
    
          <p>If the script is dedicated to handling a particular error
          condition, such as <code>404&nbsp;Not&nbsp;Found</code>, it can
          use the specific code and error text instead.</p>
    
          <p>Note that if the response contains <code>Location:</code>
          header (in order to issue a client-side redirect), the script
          <em>must</em> emit an appropriate <code>Status:</code> header
          (such as <code>302&nbsp;Found</code>). Otherwise the
          <code>Location:</code> header may have no effect.</p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="multi-lang" id="multi-lang">Multi Language Custom Error Documents</a></h2>
    
        <p>Provided with your installation of the Apache HTTP Server is a
        directory of custom error documents translated into 16 different
        languages. There's also a configuration file in the
        <code>conf/extra</code> configuration directory that can be included
        to enable this feature.</p>
    
        <p>In your server configuration file, you'll see a line such as:</p>
    
        <pre class="prettyprint lang-config"># Multi-language error messages
    #Include conf/extra/httpd-multilang-errordoc.conf</pre>
    
    
        <p>Uncommenting this <code>Include</code> line will enable this
        feature, and provide language-negotiated error messages, based on
        the language preference set in the client browser.</p>
    
        <p>Additionally, these documents contain various of the
        <code>REDIRECT_</code> variables, so that additional information can
        be provided to the end-user about what happened, and what they can
        do now.</p>
    
        <p>These documents can be customized to whatever degree you wish to
        provide more useful information to users about your site, and what
        they can expect to find there.</p>
    
        <p><code class="module"><a href="./mod/mod_include.html">mod_include</a></code> and <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>
        must be enabled to use this feature.</p>
    
     </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/custom-error.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/custom-error.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/custom-error.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/custom-error.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/custom-error.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/custom-error.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/custom-error.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/sitemap.html.en������������������������������������������������������������0000664�0001751�0001751�00000063615�14737542416�020010� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Sitemap - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div>
    <div id="page-content"><div id="preamble"><h1>Sitemap</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
    <p>This page lists the currently available documents of the
    <a href="./">Apache HTTP Server Version 2.4
    Documentation</a>.</p>
    </div>
    <div id="quickview"><ul id="toc">
    <li><img alt="" src="./images/down.gif" /> <a href="#release">Release Notes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#using">Using the Apache HTTP Server</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#vhosts">Apache Virtual Host documentation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">URL Rewriting Guide</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#ssl">Apache SSL/TLS Encryption</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#howto">Guides, Tutorials, and HowTos</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#platform">Platform-specific Notes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Apache HTTP Server and Supporting Programs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Apache Miscellaneous Documentation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Apache modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Developer Documentation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#index">Glossary and Index</a></li>
    </ul>
    </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="release" id="release">Release Notes</a></h2>
    <ul><li><a href="upgrading.html">Upgrading to 2.4 from 2.2</a></li>
    <li><a href="new_features_2_4.html">New features with Apache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">New features with Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">New features with Apache 2.0</a></li>
    <li><a href="license.html">Apache License</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="using" id="using">Using the Apache HTTP Server</a></h2>
    <ul><li><a href="install.html">Compiling and Installing Apache</a></li>
    <li><a href="invoking.html">Starting Apache</a></li>
    <li><a href="stopping.html">Stopping and Restarting the Server</a></li>
    <li><a href="configuring.html">Configuration Files</a></li>
    <li><a href="sections.html">How Directory, Location and Files sections work</a></li>
    <li><a href="caching.html">Content Caching</a></li>
    <li><a href="server-wide.html">Server-Wide Configuration</a></li>
    <li><a href="logs.html">Log Files</a></li>
    <li><a href="urlmapping.html">Mapping URLs to Filesystem Locations</a></li>
    <li><a href="dso.html">Dynamic Shared Object (DSO) support</a></li>
    <li><a href="content-negotiation.html">Content Negotiation</a></li>
    <li><a href="custom-error.html">Custom error responses</a></li>
    <li><a href="bind.html">Setting which addresses and ports Apache uses</a></li>
    <li><a href="mpm.html">Multi-Processing Modules (MPMs)</a></li>
    <li><a href="env.html">Environment Variables in Apache</a></li>
    <li><a href="expr.html">Expression Parsing in Apache</a></li>
    <li><a href="handler.html">Apache's Handler Use</a></li>
    <li><a href="filter.html">Filters</a></li>
    <li><a href="socache.html">Shared Object Cache Support</a></li>
    <li><a href="suexec.html">suEXEC Support</a></li>
    <li><a href="dns-caveats.html">Issues Regarding DNS and Apache</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">Frequently Asked Questions</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="vhosts" id="vhosts">Apache Virtual Host documentation</a></h2>
    <ul><li class="separate"><a href="vhosts/">Overview</a></li>
    <li><a href="vhosts/name-based.html">Name-based Virtual Hosts</a></li>
    <li><a href="vhosts/ip-based.html">IP-based Virtual Host Support</a></li>
    <li><a href="vhosts/mass.html">Dynamically configured mass virtual hosting</a></li>
    <li><a href="vhosts/examples.html">VirtualHost Examples</a></li>
    <li><a href="vhosts/details.html">An In-Depth Discussion of Virtual Host Matching</a></li>
    <li><a href="vhosts/fd-limits.html">File descriptor limitations</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="rewrite" id="rewrite">URL Rewriting Guide</a></h2>
    <ul><li class="separate"><a href="rewrite/">Overview</a></li>
    <li><a href="mod/mod_rewrite.html">mod_rewrite reference
    documentation</a></li>
    <li><a href="rewrite/intro.html">Introduction to regular expressions and
    mod_rewrite</a></li>
    <li><a href="rewrite/remapping.html">Using mod_rewrite for redirection and
    remapping of URLs</a></li>
    <li><a href="rewrite/access.html">Using mod_rewrite to control access</a></li>
    <li><a href="rewrite/vhosts.html">Dynamic virtual hosts with mod_rewrite</a></li>
    <li><a href="rewrite/proxy.html">Dynamic proxying with mod_rewrite</a></li>
    <li><a href="rewrite/rewritemap.html">Using RewriteMap</a></li>
    <li><a href="rewrite/advanced.html">Advanced techniques</a></li>
    <li><a href="rewrite/avoid.html">When NOT to use mod_rewrite</a></li>
    <li><a href="rewrite/flags.html">RewriteRule Flags</a></li>
    <li><a href="rewrite/tech.html">Technical details</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="ssl" id="ssl">Apache SSL/TLS Encryption</a></h2>
    <ul><li class="separate"><a href="ssl/">Overview</a></li>
    <li><a href="ssl/ssl_intro.html">SSL/TLS Encryption: An Introduction</a></li>
    <li><a href="ssl/ssl_compat.html">SSL/TLS Encryption: Compatibility</a></li>
    <li><a href="ssl/ssl_howto.html">SSL/TLS Encryption: How-To</a></li>
    <li><a href="ssl/ssl_faq.html">SSL/TLS Encryption: FAQ</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="howto" id="howto">Guides, Tutorials, and HowTos</a></h2>
    <ul><li class="separate"><a href="howto/">Overview</a></li>
    <li><a href="howto/auth.html">Authentication and Authorization</a></li>
    <li><a href="howto/access.html">Access Control</a></li>
    <li><a href="howto/cgi.html">Dynamic Content with CGI</a></li>
    <li><a href="howto/ssi.html">Introduction to Server Side Includes</a></li>
    <li><a href="howto/htaccess.html">.htaccess files</a></li>
    <li><a href="howto/public_html.html">Per-user web directories</a></li>
    <li><a href="howto/reverse_proxy.html">Reverse proxy setup guide</a></li>
    <li><a href="howto/http2.html">HTTP/2 guide</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="platform" id="platform">Platform-specific Notes</a></h2>
    <ul><li class="separate"><a href="platform/">Overview</a></li>
    <li><a href="platform/windows.html">Using Apache with Microsoft
    Windows</a></li>
    <li><a href="platform/win_compiling.html">Compiling Apache for
    Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">Using Apache With RPM Based Systems</a></li>
    <li><a href="platform/netware.html">Using Apache with Novell NetWare</a></li>
    <li><a href="platform/perf-hp.html">Running a High-Performance Web
    Server on HPUX</a></li>
    <li><a href="platform/ebcdic.html">The Apache EBCDIC Port</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="programs" id="programs">Apache HTTP Server and Supporting Programs</a></h2>
    <ul><li class="separate"><a href="programs/">Overview</a></li>
    <li><a href="programs/httpd.html">Manual Page: httpd</a></li>
    <li><a href="programs/ab.html">Manual Page: ab</a></li>
    <li><a href="programs/apachectl.html">Manual Page: apachectl</a></li>
    <li><a href="programs/apxs.html">Manual Page: apxs</a></li>
    <li><a href="programs/configure.html">Manual Page: configure</a></li>
    <li><a href="programs/dbmmanage.html">Manual Page: dbmmanage</a></li>
    <li><a href="programs/fcgistarter.html">Manual Page: fcgistarter</a></li>
    <li><a href="programs/htcacheclean.html">Manual Page: htcacheclean</a></li>
    <li><a href="programs/htdbm.html">Manual Page: htdbm</a></li>
    <li><a href="programs/htdigest.html">Manual Page: htdigest</a></li>
    <li><a href="programs/htpasswd.html">Manual Page: htpasswd</a></li>
    <li><a href="programs/httxt2dbm.html">Manual Page: httxt2dbm</a></li>
    <li><a href="programs/logresolve.html">Manual Page: logresolve</a></li>
    <li><a href="programs/log_server_status.html">Manual Page:
    log_server_status</a></li>
    <li><a href="programs/rotatelogs.html">Manual Page: rotatelogs</a></li>
    <li><a href="programs/split-logfile.html">Manual Page: split-logfile</a></li>
    <li><a href="programs/suexec.html">Manual Page: suexec</a></li>
    <li><a href="programs/other.html">Other Programs</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="misc" id="misc">Apache Miscellaneous Documentation</a></h2>
    <ul><li class="separate"><a href="misc/">Overview</a></li>
    <li><a href="misc/perf-tuning.html">Performance Notes - Apache Tuning</a></li>
    <li><a href="misc/security_tips.html">Security Tips</a></li>
    <li><a href="misc/relevant_standards.html">Relevant Standards</a></li>
    <li><a href="misc/password_encryptions.html">Password Encryption Formats</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="modules" id="modules">Apache modules</a></h2>
    <ul><li><a href="mod/module-dict.html">Definitions of terms used to describe Apache modules</a></li>
    <li><a href="mod/directive-dict.html">Definitions of terms used to describe Apache directives</a></li>
    </ul><ul><li><a href="mod/core.html">Apache Core Features</a></li>
    <li><a href="mod/mpm_common.html">Apache MPM Common Directives</a></li>
    <li><a href="mod/event.html">Apache MPM event</a></li>
    <li><a href="mod/mpm_netware.html">Apache MPM netware</a></li>
    <li><a href="mod/mpmt_os2.html">Apache MPM os2</a></li>
    <li><a href="mod/prefork.html">Apache MPM prefork</a></li>
    <li><a href="mod/mpm_winnt.html">Apache MPM winnt</a></li>
    <li><a href="mod/worker.html">Apache MPM worker</a></li>
    </ul><ul><li><a href="mod/mod_access_compat.html">Apache Module mod_access_compat</a></li>
    <li><a href="mod/mod_actions.html">Apache Module mod_actions</a></li>
    <li><a href="mod/mod_alias.html">Apache Module mod_alias</a></li>
    <li><a href="mod/mod_allowmethods.html">Apache Module mod_allowmethods</a></li>
    <li><a href="mod/mod_asis.html">Apache Module mod_asis</a></li>
    <li><a href="mod/mod_auth_basic.html">Apache Module mod_auth_basic</a></li>
    <li><a href="mod/mod_auth_digest.html">Apache Module mod_auth_digest</a></li>
    <li><a href="mod/mod_auth_form.html">Apache Module mod_auth_form</a></li>
    <li><a href="mod/mod_authn_anon.html">Apache Module mod_authn_anon</a></li>
    <li><a href="mod/mod_authn_core.html">Apache Module mod_authn_core</a></li>
    <li><a href="mod/mod_authn_dbd.html">Apache Module mod_authn_dbd</a></li>
    <li><a href="mod/mod_authn_dbm.html">Apache Module mod_authn_dbm</a></li>
    <li><a href="mod/mod_authn_file.html">Apache Module mod_authn_file</a></li>
    <li><a href="mod/mod_authn_socache.html">Apache Module mod_authn_socache</a></li>
    <li><a href="mod/mod_authnz_fcgi.html">Apache Module mod_authnz_fcgi</a></li>
    <li><a href="mod/mod_authnz_ldap.html">Apache Module mod_authnz_ldap</a></li>
    <li><a href="mod/mod_authz_core.html">Apache Module mod_authz_core</a></li>
    <li><a href="mod/mod_authz_dbd.html">Apache Module mod_authz_dbd</a></li>
    <li><a href="mod/mod_authz_dbm.html">Apache Module mod_authz_dbm</a></li>
    <li><a href="mod/mod_authz_groupfile.html">Apache Module mod_authz_groupfile</a></li>
    <li><a href="mod/mod_authz_host.html">Apache Module mod_authz_host</a></li>
    <li><a href="mod/mod_authz_owner.html">Apache Module mod_authz_owner</a></li>
    <li><a href="mod/mod_authz_user.html">Apache Module mod_authz_user</a></li>
    <li><a href="mod/mod_autoindex.html">Apache Module mod_autoindex</a></li>
    <li><a href="mod/mod_brotli.html">Apache Module mod_brotli</a></li>
    <li><a href="mod/mod_buffer.html">Apache Module mod_buffer</a></li>
    <li><a href="mod/mod_cache.html">Apache Module mod_cache</a></li>
    <li><a href="mod/mod_cache_disk.html">Apache Module mod_cache_disk</a></li>
    <li><a href="mod/mod_cache_socache.html">Apache Module mod_cache_socache</a></li>
    <li><a href="mod/mod_cern_meta.html">Apache Module mod_cern_meta</a></li>
    <li><a href="mod/mod_cgi.html">Apache Module mod_cgi</a></li>
    <li><a href="mod/mod_cgid.html">Apache Module mod_cgid</a></li>
    <li><a href="mod/mod_charset_lite.html">Apache Module mod_charset_lite</a></li>
    <li><a href="mod/mod_data.html">Apache Module mod_data</a></li>
    <li><a href="mod/mod_dav.html">Apache Module mod_dav</a></li>
    <li><a href="mod/mod_dav_fs.html">Apache Module mod_dav_fs</a></li>
    <li><a href="mod/mod_dav_lock.html">Apache Module mod_dav_lock</a></li>
    <li><a href="mod/mod_dbd.html">Apache Module mod_dbd</a></li>
    <li><a href="mod/mod_deflate.html">Apache Module mod_deflate</a></li>
    <li><a href="mod/mod_dialup.html">Apache Module mod_dialup</a></li>
    <li><a href="mod/mod_dir.html">Apache Module mod_dir</a></li>
    <li><a href="mod/mod_dumpio.html">Apache Module mod_dumpio</a></li>
    <li><a href="mod/mod_echo.html">Apache Module mod_echo</a></li>
    <li><a href="mod/mod_env.html">Apache Module mod_env</a></li>
    <li><a href="mod/mod_example_hooks.html">Apache Module mod_example_hooks</a></li>
    <li><a href="mod/mod_expires.html">Apache Module mod_expires</a></li>
    <li><a href="mod/mod_ext_filter.html">Apache Module mod_ext_filter</a></li>
    <li><a href="mod/mod_file_cache.html">Apache Module mod_file_cache</a></li>
    <li><a href="mod/mod_filter.html">Apache Module mod_filter</a></li>
    <li><a href="mod/mod_headers.html">Apache Module mod_headers</a></li>
    <li><a href="mod/mod_heartbeat.html">Apache Module mod_heartbeat</a></li>
    <li><a href="mod/mod_heartmonitor.html">Apache Module mod_heartmonitor</a></li>
    <li><a href="mod/mod_http2.html">Apache Module mod_http2</a></li>
    <li><a href="mod/mod_ident.html">Apache Module mod_ident</a></li>
    <li><a href="mod/mod_imagemap.html">Apache Module mod_imagemap</a></li>
    <li><a href="mod/mod_include.html">Apache Module mod_include</a></li>
    <li><a href="mod/mod_info.html">Apache Module mod_info</a></li>
    <li><a href="mod/mod_isapi.html">Apache Module mod_isapi</a></li>
    <li><a href="mod/mod_lbmethod_bybusyness.html">Apache Module mod_lbmethod_bybusyness</a></li>
    <li><a href="mod/mod_lbmethod_byrequests.html">Apache Module mod_lbmethod_byrequests</a></li>
    <li><a href="mod/mod_lbmethod_bytraffic.html">Apache Module mod_lbmethod_bytraffic</a></li>
    <li><a href="mod/mod_lbmethod_heartbeat.html">Apache Module mod_lbmethod_heartbeat</a></li>
    <li><a href="mod/mod_ldap.html">Apache Module mod_ldap</a></li>
    <li><a href="mod/mod_log_config.html">Apache Module mod_log_config</a></li>
    <li><a href="mod/mod_log_debug.html">Apache Module mod_log_debug</a></li>
    <li><a href="mod/mod_log_forensic.html">Apache Module mod_log_forensic</a></li>
    <li><a href="mod/mod_logio.html">Apache Module mod_logio</a></li>
    <li><a href="mod/mod_lua.html">Apache Module mod_lua</a></li>
    <li><a href="mod/mod_macro.html">Apache Module mod_macro</a></li>
    <li><a href="mod/mod_md.html">Apache Module mod_md</a></li>
    <li><a href="mod/mod_mime.html">Apache Module mod_mime</a></li>
    <li><a href="mod/mod_mime_magic.html">Apache Module mod_mime_magic</a></li>
    <li><a href="mod/mod_negotiation.html">Apache Module mod_negotiation</a></li>
    <li><a href="mod/mod_nw_ssl.html">Apache Module mod_nw_ssl</a></li>
    <li><a href="mod/mod_privileges.html">Apache Module mod_privileges</a></li>
    <li><a href="mod/mod_proxy.html">Apache Module mod_proxy</a></li>
    <li><a href="mod/mod_proxy_ajp.html">Apache Module mod_proxy_ajp</a></li>
    <li><a href="mod/mod_proxy_balancer.html">Apache Module mod_proxy_balancer</a></li>
    <li><a href="mod/mod_proxy_connect.html">Apache Module mod_proxy_connect</a></li>
    <li><a href="mod/mod_proxy_express.html">Apache Module mod_proxy_express</a></li>
    <li><a href="mod/mod_proxy_fcgi.html">Apache Module mod_proxy_fcgi</a></li>
    <li><a href="mod/mod_proxy_fdpass.html">Apache Module mod_proxy_fdpass</a></li>
    <li><a href="mod/mod_proxy_ftp.html">Apache Module mod_proxy_ftp</a></li>
    <li><a href="mod/mod_proxy_hcheck.html">Apache Module mod_proxy_hcheck</a></li>
    <li><a href="mod/mod_proxy_html.html">Apache Module mod_proxy_html</a></li>
    <li><a href="mod/mod_proxy_http.html">Apache Module mod_proxy_http</a></li>
    <li><a href="mod/mod_proxy_http2.html">Apache Module mod_proxy_http2</a></li>
    <li><a href="mod/mod_proxy_scgi.html">Apache Module mod_proxy_scgi</a></li>
    <li><a href="mod/mod_proxy_uwsgi.html">Apache Module mod_proxy_uwsgi</a></li>
    <li><a href="mod/mod_proxy_wstunnel.html">Apache Module mod_proxy_wstunnel</a></li>
    <li><a href="mod/mod_ratelimit.html">Apache Module mod_ratelimit</a></li>
    <li><a href="mod/mod_reflector.html">Apache Module mod_reflector</a></li>
    <li><a href="mod/mod_remoteip.html">Apache Module mod_remoteip</a></li>
    <li><a href="mod/mod_reqtimeout.html">Apache Module mod_reqtimeout</a></li>
    <li><a href="mod/mod_request.html">Apache Module mod_request</a></li>
    <li><a href="mod/mod_rewrite.html">Apache Module mod_rewrite</a></li>
    <li><a href="mod/mod_sed.html">Apache Module mod_sed</a></li>
    <li><a href="mod/mod_session.html">Apache Module mod_session</a></li>
    <li><a href="mod/mod_session_cookie.html">Apache Module mod_session_cookie</a></li>
    <li><a href="mod/mod_session_crypto.html">Apache Module mod_session_crypto</a></li>
    <li><a href="mod/mod_session_dbd.html">Apache Module mod_session_dbd</a></li>
    <li><a href="mod/mod_setenvif.html">Apache Module mod_setenvif</a></li>
    <li><a href="mod/mod_slotmem_plain.html">Apache Module mod_slotmem_plain</a></li>
    <li><a href="mod/mod_slotmem_shm.html">Apache Module mod_slotmem_shm</a></li>
    <li><a href="mod/mod_so.html">Apache Module mod_so</a></li>
    <li><a href="mod/mod_socache_dbm.html">Apache Module mod_socache_dbm</a></li>
    <li><a href="mod/mod_socache_dc.html">Apache Module mod_socache_dc</a></li>
    <li><a href="mod/mod_socache_memcache.html">Apache Module mod_socache_memcache</a></li>
    <li><a href="mod/mod_socache_redis.html">Apache Module mod_socache_redis</a></li>
    <li><a href="mod/mod_socache_shmcb.html">Apache Module mod_socache_shmcb</a></li>
    <li><a href="mod/mod_speling.html">Apache Module mod_speling</a></li>
    <li><a href="mod/mod_ssl.html">Apache Module mod_ssl</a></li>
    <li><a href="mod/mod_status.html">Apache Module mod_status</a></li>
    <li><a href="mod/mod_substitute.html">Apache Module mod_substitute</a></li>
    <li><a href="mod/mod_suexec.html">Apache Module mod_suexec</a></li>
    <li><a href="mod/mod_systemd.html">Apache Module mod_systemd</a></li>
    <li><a href="mod/mod_unique_id.html">Apache Module mod_unique_id</a></li>
    <li><a href="mod/mod_unixd.html">Apache Module mod_unixd</a></li>
    <li><a href="mod/mod_userdir.html">Apache Module mod_userdir</a></li>
    <li><a href="mod/mod_usertrack.html">Apache Module mod_usertrack</a></li>
    <li><a href="mod/mod_version.html">Apache Module mod_version</a></li>
    <li><a href="mod/mod_vhost_alias.html">Apache Module mod_vhost_alias</a></li>
    <li><a href="mod/mod_watchdog.html">Apache Module mod_watchdog</a></li>
    <li><a href="mod/mod_xml2enc.html">Apache Module mod_xml2enc</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="developer" id="developer">Developer Documentation</a></h2>
    <ul><li class="separate"><a href="developer/">Overview</a></li>
    <li><a href="developer/API.html">Apache API notes</a></li>
    <li><a href="developer/new_api_2_4.html">API updates in Apache HTTPD 2.4</a></li>
    <li><a href="developer/modguide.html">Developing modules for Apache HTTPD 2.4</a></li>
    <li><a href="developer/documenting.html">Documenting Apache HTTPD</a></li>
    <li><a href="developer/hooks.html">Apache 2.x Hook Functions</a></li>
    <li><a href="developer/modules.html">Converting Modules from 1.3 to 2.x</a></li>
    <li><a href="developer/request.html">Request Processing in 2.x</a></li>
    <li><a href="developer/filters.html">How Filters Work in 2.x</a></li>
    <li><a href="developer/output-filters.html">Guidelines for output filters in 2.x</a></li>
    <li><a href="developer/thread_safety.html">Thread Safety Issues in 2.x</a></li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section"><h2><a name="index" id="index">Glossary and Index</a></h2>
    <ul><li><a href="glossary.html">Glossary</a></li>
    <li><a href="mod/">Module index</a></li>
    <li><a href="mod/directives.html">Directive index</a></li>
    <li><a href="mod/quickreference.html">Directive Quick-Reference</a></li>
    <li><a href="mod/overrides.html">Override class index for .htaccess</a></li>
    </ul>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/sitemap.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/sitemap.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/sitemap.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/sitemap.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sitemap.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sitemap.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sitemap.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/sitemap.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sitemap.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/content-negotiation.html.en������������������������������������������������0000664�0001751�0001751�00000103404�14737241666�022330� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Content Negotiation - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Content Negotiation</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/content-negotiation.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>Apache HTTPD 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.</p>
    
        <p>Content negotiation is provided by the
        <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> module, which is compiled in
        by default.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#about">About Content Negotiation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#negotiation">Negotiation in httpd</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#methods">The Negotiation Methods</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#better">Fiddling with Quality
        Values</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extensions">Extensions to Transparent Content
    Negotiation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#naming">Note on hyperlinks and naming conventions</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#caching">Note on Caching</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="about" id="about">About Content Negotiation</a></h2>
    
        <p>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</p>
    
    <div class="example"><p><code>Accept-Language: fr</code></p></div>
    
        <p>Note that this preference will only be applied when there is
        a choice of representations and they vary by language.</p>
    
        <p>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:</p>
    
    <div class="example"><p><code>
      Accept-Language: fr; q=1.0, en; q=0.5<br />
      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
    </code></p></div>
    
        <p>httpd supports 'server driven' content negotiation, as
        defined in the HTTP/1.1 specification. It fully supports the
        <code>Accept</code>, <code>Accept-Language</code>,
        <code>Accept-Charset</code> and <code>Accept-Encoding</code>
        request headers. httpd 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.</p>
    
        <p>A <strong>resource</strong> is a conceptual entity
        identified by a URI (RFC 2396). An HTTP server like Apache HTTP Server
        provides access to <strong>representations</strong> of the
        resource(s) within its namespace, with each representation in
        the form of a sequence of bytes with a defined media type,
        character set, encoding, etc. Each resource may be associated
        with zero, one, or more than one representation at any given
        time. If multiple representations are available, the resource
        is referred to as <strong>negotiable</strong> and each of its
        representations is termed a <strong>variant</strong>. The ways
        in which the variants for a negotiable resource vary are called
        the <strong>dimensions</strong> of negotiation.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="negotiation" id="negotiation">Negotiation in httpd</a></h2>
    
        <p>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:</p>
    
        <ul>
          <li>Using a type map (<em>i.e.</em>, a <code>*.var</code>
          file) which names the files containing the variants
          explicitly, or</li>
    
          <li>Using a 'MultiViews' search, where the server does an
          implicit filename pattern match and chooses from among the
          results.</li>
        </ul>
    
       <h3><a name="type-map" id="type-map">Using a type-map file</a></h3>
    
        <p>A type map is a document which is associated with the handler
        named <code>type-map</code> (or, for backwards-compatibility with
        older httpd configurations, the <a class="glossarylink" href="./glossary.html#mime-type" title="see glossary">MIME-type</a>
        <code>application/x-type-map</code>). Note that to use this
        feature, you must have a handler set in the configuration that
        defines a file suffix as <code>type-map</code>; this is best done
        with</p>
    
    <pre class="prettyprint lang-config">AddHandler type-map .var</pre>
    
    
        <p>in the server configuration file.</p>
    
        <p>Type map files should have the same name as the resource
        which they are describing, followed by the extension
        <code>.var</code>. In the examples shown below, the resource is
        named <code>foo</code>, so the type map file is named
        <code>foo.var</code>.</p>
    
        <p>This file should 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.</p>
    
        <p>URIs in this file are relative to the location of the type map
        file. Usually, these files will be located in the same directory as
        the type map file, but this is not required. You may provide
        absolute or relative URIs for any file located on the same server as
        the map file.</p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.en.html<br />
      Content-type: text/html<br />
      Content-language: en<br />
    <br />
      URI: foo.fr.de.html<br />
      Content-type: text/html;charset=iso-8859-2<br />
      Content-language: fr, de<br />
    </code></p></div>
    
        <p>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): </p>
    
    <div class="example"><p><code>
      URI: foo<br />
    <br />
      URI: foo.jpeg<br />
      Content-type: image/jpeg; qs=0.8<br />
    <br />
      URI: foo.gif<br />
      Content-type: image/gif; qs=0.5<br />
    <br />
      URI: foo.txt<br />
      Content-type: text/plain; qs=0.01<br />
    </code></p></div>
    
        <p>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.</p>
    
        <p>The full list of headers recognized is available in the <a href="mod/mod_negotiation.html#typemaps">mod_negotiation
        typemap</a> documentation.</p>
    
    
    <h3><a name="multiviews" id="multiviews">Multiviews</a></h3>
    
        <p><code>MultiViews</code> is a per-directory option, meaning it
        can be set with an <code class="directive"><a href="./mod/core.html#options">Options</a></code>
        directive within a <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> or <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> section in
        <code>httpd.conf</code>, or (if <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> is properly set) in
        <code>.htaccess</code> files. Note that <code>Options All</code>
        does not set <code>MultiViews</code>; you have to ask for it by
        name.</p>
    
        <p>The effect of <code>MultiViews</code> is as follows: if the
        server receives a request for <code>/some/dir/foo</code>, if
        <code>/some/dir</code> has <code>MultiViews</code> enabled, and
        <code>/some/dir/foo</code> does <em>not</em> 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.</p>
    
        <p><code>MultiViews</code> may also apply to searches for the file
        named by the <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code> directive, if the
        server is trying to index a directory. If the configuration files
        specify</p>
    <pre class="prettyprint lang-config">DirectoryIndex index</pre>
    
        <p>then the server will arbitrate between <code>index.html</code>
        and <code>index.html3</code> if both are present. If neither
        are present, and <code>index.cgi</code> is there, the server
        will run it.</p>
    
        <p>If one of the files found when reading the directory does not
        have an extension recognized by <code>mod_mime</code> to designate
        its Charset, Content-Type, Language, or Encoding, then the result
        depends on the setting of the <code class="directive"><a href="./mod/mod_mime.html#multiviewsmatch">MultiViewsMatch</a></code> directive.  This
        directive determines whether handlers, filters, and other
        extension types can participate in MultiViews negotiation.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="methods" id="methods">The Negotiation Methods</a></h2>
    
        <p>After httpd 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 httpd's content negotiation features. However the
        rest of this document explains the methods used for those
        interested. </p>
    
        <p>There are two negotiation methods:</p>
    
        <ol>
          <li><strong>Server driven negotiation with the httpd
          algorithm</strong> is used in the normal case. The httpd
          algorithm is explained in more detail below. When this
          algorithm is used, httpd can sometimes 'fiddle' the quality
          factor of a particular dimension to achieve a better result.
          The ways httpd can fiddle quality factors is explained in
          more detail below.</li>
    
          <li><strong>Transparent content negotiation</strong> 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 httpd to run the 'remote
          variant selection algorithm' defined in RFC 2296.</li>
        </ol>
    
    <h3><a name="dimensions" id="dimensions">Dimensions of Negotiation</a></h3>
    
        <table>
          
          <tr valign="top">
            <th>Dimension</th>
    
            <th>Notes</th>
          </tr>
    
          <tr valign="top">
            <td>Media Type</td>
    
            <td>Browser indicates preferences with the <code>Accept</code>
            header field. Each item can have an associated quality factor.
            Variant description can also have a quality factor (the "qs"
            parameter).</td>
          </tr>
    
          <tr valign="top">
            <td>Language</td>
    
            <td>Browser indicates preferences with the
            <code>Accept-Language</code> header field. Each item can have
            a quality factor. Variants can be associated with none, one or
            more than one language.</td>
          </tr>
    
          <tr valign="top">
            <td>Encoding</td>
    
            <td>Browser indicates preference with the
            <code>Accept-Encoding</code> header field. Each item can have
            a quality factor.</td>
          </tr>
    
          <tr valign="top">
            <td>Charset</td>
    
            <td>Browser indicates preference with the
            <code>Accept-Charset</code> header field. Each item can have a
            quality factor. Variants can indicate a charset as a parameter
            of the media type.</td>
          </tr>
        </table>
    
    
    <h3><a name="algorithm" id="algorithm">httpd Negotiation Algorithm</a></h3>
    
        <p>httpd 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:</p>
    
        <ol>
          <li>First, for each dimension of the negotiation, check the
          appropriate <em>Accept*</em> header field and assign a
          quality to each variant. If the <em>Accept*</em> header for
          any dimension implies that this variant is not acceptable,
          eliminate it. If no variants remain, go to step 4.</li>
    
          <li>
            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.
    
            <ol>
              <li>Multiply the quality factor from the <code>Accept</code>
              header with the quality-of-source factor for this variants
              media type, and select the variants with the highest
              value.</li>
    
              <li>Select the variants with the highest language quality
              factor.</li>
    
              <li>Select the variants with the best language match,
              using either the order of languages in the
              <code>Accept-Language</code> header (if present), or else
              the order of languages in the <code>LanguagePriority</code>
              directive (if present).</li>
    
              <li>Select the variants with the highest 'level' media
              parameter (used to give the version of text/html media
              types).</li>
    
              <li>Select variants with the best charset media
              parameters, as given on the <code>Accept-Charset</code>
              header line.  Charset ISO-8859-1 is acceptable unless
              explicitly excluded. Variants with a <code>text/*</code>
              media type but not explicitly associated with a particular
              charset are assumed to be in ISO-8859-1.</li>
    
              <li>Select those variants which have associated charset
              media parameters that are <em>not</em> ISO-8859-1. If
              there are no such variants, select all variants
              instead.</li>
    
              <li>Select the variants with the best encoding. If there
              are variants with an encoding that is acceptable to the
              user-agent, select only these variants. Otherwise if
              there is a mix of encoded and non-encoded variants,
              select only the unencoded variants. If either all
              variants are encoded or all variants are not encoded,
              select all variants.</li>
    
              <li>Select the variants with the smallest content
              length.</li>
    
              <li>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.</li>
            </ol>
          </li>
    
          <li>The algorithm has now selected one 'best' variant, so
          return it as the response. The HTTP response header
          <code>Vary</code> is set to indicate the dimensions of
          negotiation (browsers and caches can use this information when
          caching the resource).  End.</li>
    
          <li>To get here means no variant was selected (because none
          are acceptable to the browser). Return a 406 status (meaning
          "No acceptable representation") with a response body
          consisting of an HTML document listing the available
          variants. Also set the HTTP <code>Vary</code> header to
          indicate the dimensions of variance.</li>
        </ol>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="better" id="better">Fiddling with Quality
        Values</a></h2>
    
        <p>httpd sometimes changes the quality values from what would
        be expected by a strict interpretation of the httpd
        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
        <code>Accept</code> 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.</p>
    
    <h3><a name="wildcards" id="wildcards">Media Types and Wildcards</a></h3>
    
        <p>The <code>Accept:</code> 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:</p>
    
    <div class="example"><p><code>Accept: image/*, */*</code></p></div>
    
        <p>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:</p>
    
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*
    </code></p></div>
        <p>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:</p>
    <div class="example"><p><code>
      Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
    </code></p></div>
        <p>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.</p>
    
        <p>If the <code>Accept:</code> header contains <em>no</em> q
        factors at all, httpd 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
        <code>Accept:</code> header contains a q factor, these special
        values are <em>not</em> applied, so requests from browsers which
        send the explicit information to start with work as expected.</p>
    
    
    <h3><a name="exceptions" id="exceptions">Language Negotiation Exceptions</a></h3>
    
        <p>New in httpd 2.0, some exceptions have been added to the
        negotiation algorithm to allow graceful fallback when language
        negotiation fails to find a match.</p>
    
        <p>When a client requests a page on your server, but the server
        cannot find a single page that matches the
        <code>Accept-language</code> 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 httpd to ignore
        the <code>Accept-language</code> in these cases and provide a
        document that does not explicitly match the client's request.  The
        <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code>
        directive can be used to override one or both of these error
        messages and substitute the servers judgement in the form of the
        <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>
        directive.</p>
    
        <p>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 <code>en-GB</code> 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
        <code>en</code>.  (Note that it is almost surely a configuration
        error to include <code>en-GB</code> and not <code>en</code> in the
        <code>Accept-Language</code> 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 <code class="directive"><a href="./mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>, the server
        will ignore the subset specification and match <code>en-GB</code>
        against <code>en</code> documents.  Implicitly, httpd 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.</p>
    
        <p>In order to support advanced techniques (such as cookies or
        special URL-paths) to determine the user's preferred language,
        since httpd 2.0.47 <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> recognizes
        the <a href="env.html">environment variable</a>
        <code>prefer-language</code>. If it exists and contains an
        appropriate language tag, <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> will
        try to select a matching variant. If there's no such variant,
        the normal negotiation process applies.</p>
    
        <div class="example"><h3>Example</h3><pre class="prettyprint lang-config">SetEnvIf Cookie "language=(.+)" prefer-language=$1
    Header append Vary cookie</pre>
    </div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extensions" id="extensions">Extensions to Transparent Content
    Negotiation</a></h2>
    
    <p>httpd extends the transparent content negotiation protocol (RFC
    2295) as follows. A new <code>{encoding ..}</code> 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 <code>Accept-Encoding</code> request
    header. The RVSA/1.0 implementation does not round computed quality
    factors to 5 decimal places before choosing the best variant.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="naming" id="naming">Note on hyperlinks and naming conventions</a></h2>
    
        <p>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 <a href="mod/mod_mime.html#multipleext">mod_mime</a> documentation
        for details).</p>
    
        <p>A typical file has a MIME-type extension (<em>e.g.</em>,
        <code>html</code>), maybe an encoding extension (<em>e.g.</em>,
        <code>gz</code>), and of course a language extension
        (<em>e.g.</em>, <code>en</code>) when we have different
        language variants of this file.</p>
    
        <p>Examples:</p>
    
        <ul>
          <li>foo.en.html</li>
    
          <li>foo.html.en</li>
    
          <li>foo.en.html.gz</li>
        </ul>
    
        <p>Here some more examples of filenames together with valid and
        invalid hyperlinks:</p>
    
        <table class="bordered">
          
          <tr>
            <th>Filename</th>
    
            <th>Valid hyperlink</th>
    
            <th>Invalid hyperlink</th>
          </tr>
    
          <tr>
            <td><em>foo.html.en</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>-</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html</em></td>
    
            <td>foo</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.en.gz</em></td>
    
            <td>foo<br />
             foo.html</td>
    
            <td>foo.gz<br />
             foo.html.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.en.html.gz</em></td>
    
            <td>foo</td>
    
            <td>foo.html<br />
             foo.html.gz<br />
             foo.gz</td>
          </tr>
    
          <tr>
            <td><em>foo.gz.html.en</em></td>
    
            <td>foo<br />
             foo.gz<br />
             foo.gz.html</td>
    
            <td>foo.html</td>
          </tr>
    
          <tr>
            <td><em>foo.html.gz.en</em></td>
    
            <td>foo<br />
             foo.html<br />
             foo.html.gz</td>
    
            <td>foo.gz</td>
          </tr>
        </table>
    
        <p>Looking at the table above, you will notice that it is always
        possible to use the name without any extensions in a hyperlink
        (<em>e.g.</em>, <code>foo</code>). The advantage is that you
        can hide the actual type of a document rsp. file and can change
        it later, <em>e.g.</em>, from <code>html</code> to
        <code>shtml</code> or <code>cgi</code> without changing any
        hyperlink references.</p>
    
        <p>If you want to continue to use a MIME-type in your
        hyperlinks (<em>e.g.</em> <code>foo.html</code>) the language
        extension (including an encoding extension if there is one)
        must be on the right hand side of the MIME-type extension
        (<em>e.g.</em>, <code>foo.html.en</code>).</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="caching" id="caching">Note on Caching</a></h2>
    
        <p>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, httpd normally
        marks all responses that are returned after content negotiation
        as non-cacheable by HTTP/1.0 clients. httpd also supports the
        HTTP/1.1 protocol features to allow caching of negotiated
        responses.</p>
    
        <p>For requests which come from a HTTP/1.0 compliant client
        (either a browser or a cache), the directive <code class="directive"><a href="./mod/mod_negotiation.html#cachenegotiateddocs">CacheNegotiatedDocs</a></code> 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.</p>
    
        <p>For HTTP/1.1 clients, httpd sends a <code>Vary</code> 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 <code>force-no-vary</code> <a href="env.html#special">environment variable</a>.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/content-negotiation.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/content-negotiation.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/content-negotiation.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/content-negotiation.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/content-negotiation.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/content-negotiation.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/glossary.html.en�����������������������������������������������������������0000664�0001751�0001751�00000074020�14737241666�020204� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Glossary - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Glossary</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>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.</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definitions" id="definitions">Definitions</a></h2>
    
      <dl>
        <dt><a name="accesscontrol" id="accesscontrol">Access Control</a></dt>
        <dd>The restriction of access to network realms. In an Apache context
          usually the restriction of access to certain <em>URLs</em>.<br /> See:  <a href="howto/auth.html">Authentication, Authorization, and Access
          Control</a>
        </dd>
    
        <dt><a name="algorithm" id="algorithm">Algorithm</a></dt>
        <dd>An unambiguous formula or set of rules for solving a problem in a finite
          number of steps. Algorithms for encryption are usually called
          <dfn>Ciphers</dfn>.
        </dd>
    
        <dt><a name="apacheextensiontool" id="apacheextensiontool">APache
            eXtension Tool</a> <a name="apxs" id="apxs">(apxs)</a></dt>
        <dd>A perl script that aids in compiling <a class="glossarylink" href="./glossary.html#module" title="see glossary">module</a> sources into Dynamic Shared Objects
          (<a class="glossarylink" href="./glossary.html#dso" title="see glossary">DSO</a>s) and helps install them in the
          Apache Web server.<br />
          See: Manual Page: <code class="program"><a href="./programs/apxs.html">apxs</a></code>
        </dd>
    
        <dt><a name="apacheportableruntime" id="apacheportableruntime">Apache Portable Runtime</a> <a name="apr" id="apr">(APR)</a></dt>
        <dd>A set of libraries providing many of the basic interfaces
          between the server and the operating system.  APR is developed
          parallel to the Apache HTTP Server as an independent project.<br />
          See: <a href="http://apr.apache.org/">Apache Portable Runtime
          Project</a>
        </dd>
    
        <dt><a name="authentication" id="authentication">Authentication</a></dt>
        <dd>The positive identification of a network entity such as a server, a
          client, or a user.<br />
          See: <a href="howto/auth.html">Authentication, Authorization, and Access
          Control</a>
        </dd>
    
        <dt><a name="certificate" id="certificate">Certificate</a></dt>
        <dd>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 <a class="glossarylink" href="./glossary.html#certificationauthority" title="see glossary">Certification Authority</a> (called
          the issuer), plus the owner's <a class="glossarylink" href="./glossary.html#publickey" title="see glossary">public
          key</a> and the
          signature made by the CA. Network entities verify these signatures
          using CA certificates.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="certificatsigningrequest" id="certificatsigningrequest">Certificate Signing Request</a>
          <a name="csr" id="csr">(CSR)</a></dt>
        <dd>An unsigned <a class="glossarylink" href="./glossary.html#certificate" title="see glossary">certificate</a> for
          submission to a <a class="glossarylink" href="./glossary.html#certificationauthority" title="see glossary">Certification
          Authority</a>, which signs it with the <a class="glossarylink" href="./glossary.html#privatekey" title="see glossary">Private Key</a> of their CA
          <em>Certificate</em>. Once the CSR is signed, it becomes a real
          certificate.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="certificationauthority" id="certificationauthority">Certification Authority</a>
          <a name="ca" id="ca">(CA)</a></dt>
        <dd>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.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="cipher" id="cipher">Cipher</a></dt>
        <dd>An algorithm or system for data encryption. Examples are DES, IDEA, RC4,
          etc.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="ciphertext" id="ciphertext">Ciphertext</a></dt>
        <dd>The result after <a class="glossarylink" href="./glossary.html#plaintext" title="see glossary">Plaintext</a> is
          passed through a <a class="glossarylink" href="./glossary.html#cipher" title="see glossary">Cipher</a>.<br /> See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="commongatewayinterface" id="commongatewayinterface">Common
            Gateway Interface</a> <a name="cgi" id="cgi">(CGI)</a></dt>
        <dd>A standard definition for an interface between a web server and an
          external program that allows the external program to service requests.
          There is an <a href="http://www.ietf.org/rfc/rfc3875">Informational
          RFC</a> which covers the specifics.<br />
          See: <a href="howto/cgi.html">Dynamic Content with CGI</a>
        </dd>
    
        <dt><a name="configurationdirective" id="configurationdirective">Configuration Directive</a></dt>
        <dd>See: <a class="glossarylink" href="./glossary.html#directive" title="see glossary">Directive</a></dd>
    
        <dt><a name="configurationfile" id="configurationfile">Configuration
            File</a></dt>
        <dd>A text file containing <a class="glossarylink" href="./glossary.html#directive" title="see glossary">Directives</a>
          that control the configuration of Apache.<br />
          See: <a href="configuring.html">Configuration Files</a>
        </dd>
    
        <dt><a name="connect" id="connect">CONNECT</a></dt>
        <dd>An HTTP <a class="glossarylink" href="./glossary.html#method" title="see glossary">method</a> for proxying raw data
          channels over HTTP. It can be used to encapsulate other protocols, such as
          the SSL protocol.
        </dd>
    
        <dt><a name="context" id="context">Context</a></dt>
        <dd>An area in the <a class="glossarylink" href="./glossary.html#configurationfile" title="see glossary">configuration
          files</a> where certain types of <a class="glossarylink" href="./glossary.html#directive" title="see glossary">directives</a> are allowed.<br />
          See: <a href="mod/directive-dict.html#Context">Terms Used to Describe
          Apache Directives</a>
        </dd>
    
        <dt><a name="digitalsignature" id="digitalsignature">Digital
            Signature</a></dt>
        <dd>An encrypted text block that validates a certificate or other file. A
          <a class="glossarylink" href="./glossary.html#certificationauthority" title="see glossary">Certification Authority</a>
          creates a signature by generating a hash of the <em>Public Key</em>
          embedded in a <em>Certificate</em>, then encrypting the hash with its own
          <em>Private Key</em>. Only the CA's public key can decrypt the signature,
          verifying that the CA has authenticated the network entity that owns the
          <em>Certificate</em>.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="directive" id="directive">Directive</a></dt>
        <dd>A configuration command that controls one or more aspects of Apache's
          behavior.  Directives are placed in the <a class="glossarylink" href="./glossary.html#configurationfile" title="see glossary">Configuration File</a><br />
        See: <a href="mod/directives.html">Directive Index</a>
        </dd>
    
        <dt><a name="dynamicsharedobject" id="dynamicsharedobject">Dynamic
            Shared Object</a> <a name="dso" id="dso">(DSO)</a></dt>
        <dd><a class="glossarylink" href="./glossary.html#module" title="see glossary">Modules</a> compiled separately from the
          Apache <code class="program"><a href="./programs/httpd.html">httpd</a></code> binary that can be loaded on-demand.<br />
          See: <a href="dso.html">Dynamic Shared Object Support</a>
        </dd>
    
        <dt><a name="environmentvariable" id="environmentvariable">Environment
            Variable</a> <a name="env-variable" id="env-variable">(env-variable)</a></dt>
        <dd>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.<br />
          See: <a href="env.html">Environment Variables in Apache</a>
        </dd>
    
        <dt><a name="export-crippled" id="export-crippled">Export-Crippled</a></dt>
        <dd>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 <em>Ciphertext</em> which usually can be decrypted by brute
          force.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="filter" id="filter">Filter</a></dt>
        <dd>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 <code>INCLUDES</code> output filter
          processes documents for <a class="glossarylink" href="./glossary.html#ssi" title="see glossary">Server Side
          Includes</a>.<br />
          See: <a href="filter.html">Filters</a>
        </dd>
    
        <dt><a name="fully-qualifieddomain-name" id="fully-qualifieddomain-name">Fully-Qualified Domain-Name</a>
          <a name="fqdn" id="fqdn">(FQDN)</a></dt>
        <dd>The unique name of a network entity, consisting of a hostname and a
          domain name that can resolve to an IP address. For example,
          <code>www</code> is a hostname, <code>example.com</code> is a domain name,
          and <code>www.example.com</code> is a fully-qualified domain name.
        </dd>
    
        <dt><a name="handler" id="handler">Handler</a></dt>
        <dd>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
          <code>cgi-script</code> handler designates files to be processed as
          <a class="glossarylink" href="./glossary.html#cgi" title="see glossary">CGIs</a>.<br />
          See: <a href="handler.html">Apache's Handler Use</a>
        </dd>
    
        <dt><a name="hash" id="hash">Hash</a></dt>
        <dd>A mathematical one-way, irreversible 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).
        </dd>
    
        <dt><a name="header" id="header">Header</a></dt>
        <dd>The part of the <a class="glossarylink" href="./glossary.html#http" title="see glossary">HTTP</a> request and
          response that is sent before the actual content, and that contains
          meta-information describing the content.
        </dd>
    
        <dt><a name="htaccess" id="htaccess">.htaccess</a></dt>
        <dd>A <a class="glossarylink" href="./glossary.html#configurationfile" title="see glossary">configuration file</a> that
          is placed inside the web tree and applies configuration <a class="glossarylink" href="./glossary.html#directive" title="see glossary">directives</a> 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.<br />
          See: <a href="configuring.html">Configuration Files</a>
        </dd>
    
        <dt><a name="httpd.conf" id="httpd.conf">httpd.conf</a></dt>
        <dd>The main Apache <a class="glossarylink" href="./glossary.html#configurationfile" title="see glossary">configuration
          file</a>.  The default location is
          <code>/usr/local/apache2/conf/httpd.conf</code>, but it may be moved using
          run-time or compile-time configuration.<br />
          See: <a href="configuring.html">Configuration Files</a>
        </dd>
    
        <dt><a name="hypertexttransferprotocol" id="hypertexttransferprotocol">HyperText Transfer Protocol</a>
          <a name="http" id="hhtp">(HTTP)</a></dt>
        <dd>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 <a href="http://ietf.org/rfc/rfc2616.txt">RFC 2616</a>.
        </dd>
    
        <dt><a name="https" id="https">HTTPS</a></dt>
        <dd>The HyperText Transfer Protocol (Secure), the standard encrypted
          communication mechanism on the World Wide Web. This is actually just HTTP
          over <a class="glossarylink" href="./glossary.html#ssl" title="see glossary">SSL</a>.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="method" id="method">Method</a></dt>
        <dd>In the context of <a class="glossarylink" href="./glossary.html#http" title="see glossary">HTTP</a>, an action to
          perform on a resource, specified on the request line by the client.  Some
          of the methods available in HTTP are <code>GET</code>, <code>POST</code>,
          and <code>PUT</code>.
        </dd>
    
        <dt><a name="messagedigest" id="messagedigest">Message Digest</a></dt>
        <dd>A hash of a message, which can be used to verify that the contents of
          the message have not been altered in transit.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="mime-type" id="mime-type">MIME-type</a></dt>
        <dd>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 <code>text/html</code>,
          <code>image/gif</code>, and <code>application/octet-stream</code>.  In
          HTTP, the MIME-type is transmitted in the <code>Content-Type</code>
          <a class="glossarylink" href="./glossary.html#header" title="see glossary">header</a>.<br />
          See: <a href="mod/mod_mime.html">mod_mime</a>
        </dd>
    
        <dt><a name="module" id="module">Module</a></dt>
        <dd>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 <code class="program"><a href="./programs/httpd.html">httpd</a></code> binary are
          called <dfn>static modules</dfn>, while modules that are stored
          separately and can be optionally loaded at run-time are called
          <dfn>dynamic modules</dfn> or <a class="glossarylink" href="./glossary.html#dso" title="see glossary">DSOs</a>.
          Modules that are included by default
          are called <dfn>base modules</dfn>. Many modules are available for Apache
          that are not distributed as part of the Apache HTTP Server <a class="glossarylink" href="./glossary.html#tarball" title="see glossary">tarball</a>.  These are referred to as
          <dfn>third-party modules</dfn>.<br />
          See: <a href="mod/">Module Index</a>
        </dd>
    
        <dt><a name="modulemagicnumber" id="modulemagicnumber">Module Magic
          Number</a> (<a name="mmn" id="mmn">MMN</a>)</dt>
        <dd>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.
        </dd>
    
        <dt><a name="openssl" id="openssl">OpenSSL</a></dt>
        <dd>The Open Source toolkit for SSL/TLS<br />
          See <a href="http://www.openssl.org/">http://www.openssl.org/</a>#
        </dd>
    
        <dt><a name="passphrase" id="passphrase">Pass Phrase</a></dt>
        <dd>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 <a class="glossarylink" href="./glossary.html#cipher" title="see glossary">Ciphers</a>.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="plaintext" id="plaintext">Plaintext</a></dt>
        <dd>The unencrypted text.</dd>
    
        <dt><a name="privatekey" id="privatekey">Private Key</a></dt>
        <dd>The secret key in a <a class="glossarylink" href="./glossary.html#publickeycryptography" title="see glossary">Public Key
          Cryptography</a> system, used to decrypt incoming messages and
          sign outgoing ones.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="proxy" id="proxy">Proxy</a></dt>
        <dd>An intermediate server that sits between the client and the <em>origin
            server</em>.  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.<br />
          See: <a href="mod/mod_proxy.html">mod_proxy</a>
        </dd>
    
        <dt><a name="publickey" id="publickey">Public Key</a></dt>
        <dd>The publicly available key in a <a class="glossarylink" href="./glossary.html#publickeycryptography" title="see glossary">Public Key Cryptography</a> system,
          used to encrypt messages bound for its owner and to decrypt signatures
          made by its owner.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="publickeycryptography" id="publickeycryptography">Public Key Cryptography</a></dt>
        <dd>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.
          <br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="regularexpression" id="regularexpression">Regular Expression</a>
          <a name="regex" id="regex">(Regex)</a></dt>
        <dd>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 "<code>/images/.*(jpg|gif)$</code>".  In places where
          regular expressions are used to replace strings, the special variables
          $1 ... $9 contain backreferences to the grouped parts (in parentheses) of
          the matched expression. The special variable $0 contains a backreference
          to the whole matched expression. To write a literal dollar sign in a
          replacement string, it can be escaped with a backslash. Historically, the
          variable &amp; could be used as alias for $0 in some places. This is no
          longer possible since version 2.3.6.  Apache uses Perl Compatible Regular
          Expressions provided by the <a href="http://www.pcre.org/">PCRE</a>
          library.  You can find more documentation about PCRE's regular expression
          syntax at that site, or at
          <a href="http://en.wikipedia.org/wiki/PCRE">Wikipedia</a>.
        </dd>
    
        <dt><a name="reverseproxy" id="reverseproxy">Reverse Proxy</a></dt>
        <dd>A <a class="glossarylink" href="./glossary.html#proxy" title="see glossary">proxy</a> server that appears to the client
          as if it is an <em>origin server</em>.  This is useful to hide the real
          origin server from the client for security reasons, or to load balance.
        </dd>
    
        <dt><a name="securesocketslayer" id="securesocketslayer">Secure Sockets
            Layer</a> <a name="ssl" id="ssl">(SSL)</a></dt>
        <dd>A protocol created by Netscape Communications Corporation for general
          communication authentication and encryption over TCP/IP networks.  The most
          popular usage is <em>HTTPS</em>, i.e. the HyperText Transfer Protocol (HTTP)
          over SSL.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="servernameindication" id="servernameindication">Server Name
            Indication</a> <a name="sni" id="sni">(SNI)</a></dt>
        <dd>An SSL function that allows passing the desired server
          hostname in the initial SSL handshake message, so that the web
          server can select the correct virtual host configuration to use
          in processing the SSL handshake.  It was added to SSL starting
          with the TLS extensions, RFC 3546.  <br />
          See: <a href="ssl/ssl_faq.html">the SSL FAQ</a>
          and <a href="http://www.ietf.org/rfc/rfc3546.txt">RFC 3546</a>
        </dd>
    
        <dt><a name="serversideincludes" id="serversideincludes">Server Side
            Includes</a> <a name="ssi" id="ssi">(SSI)</a></dt>
        <dd>A technique for embedding processing directives inside HTML files.<br />
          See: <a href="howto/ssi.html">Introduction to Server Side Includes</a>
        </dd>
    
        <dt><a name="session" id="session">Session</a></dt>
        <dd>The context information of a communication in general.</dd>
    
        <dt><a name="ssleay" id="ssleay">SSLeay</a></dt>
        <dd>The original SSL/TLS implementation library developed by Eric A.
          Young
        </dd>
    
        <dt><a name="subrequest" id="subrequest">Subrequest</a></dt>
        <dd>Apache provides a subrequest API to modules that allows other
            filesystem or URL paths to be partially or fully evaluated by
            the server. Example consumers of this API are 
            <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code>, 
            <code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code>, and <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>.
        </dd>
    
        <dt><a name="symmetriccryptophraphy" id="symmetriccryptophraphy">Symmetric
            Cryptography</a></dt>
        <dd>The study and application of <em>Ciphers</em> that use a single secret key
          for both encryption and decryption operations.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="tarball" id="tarball">Tarball</a></dt>
        <dd>A package of files gathered together using the <code>tar</code> utility.
          Apache distributions are stored in compressed tar archives or using
          pkzip.
        </dd>
    
        <dt><a name="transportlayersecurity" id="transportlayersecurity">Transport
            Layer Security</a> <a name="tls" id="tls">(TLS)</a></dt>
        <dd>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 is nearly identical with SSL version 3.<br />
          See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
    
        <dt><a name="uniformresourcelocator" id="uniformresourcelocator">Uniform
            Resource Locator</a> <a name="url" id="url">(URL)</a></dt>
        <dd>The name/address of a resource on the Internet.  This is the common
          informal term for what is formally called a <a class="glossarylink" href="./glossary.html#uniformresourceidentifier" title="see glossary">Uniform Resource Identifier</a>.
          URLs are usually made up of a scheme, like <code>http</code> or
          <code>https</code>, a hostname, and a path.  A URL for this page might
          be <code>http://httpd.apache.org/docs/2.4/glossary.html</code>.
        </dd>
    
        <dt><a name="uniformresourceidentifier" id="uniformresourceidentifier">Uniform Resource Identifier</a>
          <a name="URI" id="URI">(URI)</a></dt>
        <dd>A compact string of characters for identifying an abstract or physical
          resource.  It is formally defined by <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>.  URIs used on the
          world-wide web are commonly referred to as <a class="glossarylink" href="./glossary.html#url" title="see glossary">URLs</a>.
        </dd>
    
        <dt><a name="virtualhosting" id="virtualhosting">Virtual Hosting</a></dt>
        <dd>Serving multiple websites using a single instance of Apache.  <em>IP
          virtual hosting</em> differentiates between websites based on their IP
          address, while <em>name-based virtual hosting</em> uses only the name of the
          host and can therefore host many sites on the same IP address.<br />
          See: <a href="vhosts/">Apache Virtual Host documentation</a>
        </dd>
    
        <dt><a name="x.509" id="x.509">X.509</a></dt>
        <dd>An authentication certificate scheme recommended by the International
          Telecommunication Union (ITU-T) which is used for SSL/TLS authentication.<br /> See: <a href="ssl/">SSL/TLS Encryption</a>
        </dd>
      </dl>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/glossary.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/glossary.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/glossary.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/glossary.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/glossary.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/glossary.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/glossary.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/glossary.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/index.html.en��������������������������������������������������������������0000664�0001751�0001751�00000022156�14737241666�017453� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache HTTP Server Version 2.4
    Documentation - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="index-page">
    <div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="http://httpd.apache.org/docs-project/"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a></div>
    <div id="page-content"><h1>Apache HTTP Server Version 2.4
    Documentation</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    <form method="get" action="https://www.google.com/search"><p><input name="as_q" value="" type="text" /> <input value="Google Search" type="submit" /><input value="10" name="num" type="hidden" /><input value="en" name="hl" type="hidden" /><input value="UTF-8" name="ie" type="hidden" /><input value="Google Search" name="btnG" type="hidden" /><input name="as_epq" value="Version 2.4" type="hidden" /><input name="as_oq" value="" type="hidden" /><input name="as_eq" value="&quot;List-Post&quot;" type="hidden" /><input value="" name="lr" type="hidden" /><input value="i" name="as_ft" type="hidden" /><input value="" name="as_filetype" type="hidden" /><input value="all" name="as_qdr" type="hidden" /><input value="any" name="as_occt" type="hidden" /><input value="i" name="as_dt" type="hidden" /><input value="httpd.apache.org" name="as_sitesearch" type="hidden" /><input value="off" name="safe" type="hidden" /></p></form>
    <table id="indextable"><tr><td class="col1"><div class="category"><h2><a name="release" id="release">Release Notes</a></h2>
    <ul><li><a href="new_features_2_4.html">New features with Apache 2.3/2.4</a></li>
    <li><a href="new_features_2_2.html">New features with Apache 2.1/2.2</a></li>
    <li><a href="new_features_2_0.html">New features with Apache 2.0</a></li>
    <li><a href="upgrading.html">Upgrading to 2.4 from 2.2</a></li>
    <li><a href="license.html">Apache License</a></li>
    </ul>
    </div><div class="category"><h2><a name="manual" id="manual">Reference Manual</a></h2>
    <ul><li><a href="install.html">Compiling and Installing</a></li>
    <li><a href="invoking.html">Starting</a></li>
    <li><a href="stopping.html">Stopping or Restarting</a></li>
    <li><a href="mod/quickreference.html">Run-time Configuration Directives</a></li>
    <li><a href="mod/">Modules</a></li>
    <li><a href="mpm.html">Multi-Processing Modules (MPMs)</a></li>
    <li><a href="filter.html">Filters</a></li>
    <li><a href="handler.html">Handlers</a></li>
    <li><a href="expr.html">Expression parser</a></li>
    <li><a href="mod/overrides.html">Override Class Index for .htaccess</a></li>
    <li><a href="programs/">Server and Supporting Programs</a></li>
    <li><a href="glossary.html">Glossary</a></li>
    </ul>
    </div></td><td><div class="category"><h2><a name="usersguide" id="usersguide">Users' Guide</a></h2>
    <ul><li><a href="getting-started.html">Getting Started</a></li>
    <li><a href="bind.html">Binding to Addresses and Ports</a></li>
    <li><a href="configuring.html">Configuration Files</a></li>
    <li><a href="sections.html">Configuration Sections</a></li>
    <li><a href="caching.html">Content Caching</a></li>
    <li><a href="content-negotiation.html">Content Negotiation</a></li>
    <li><a href="dso.html">Dynamic Shared Objects (DSO)</a></li>
    <li><a href="env.html">Environment Variables</a></li>
    <li><a href="logs.html">Log Files</a></li>
    <li><a href="urlmapping.html">Mapping URLs to the Filesystem</a></li>
    <li><a href="misc/perf-tuning.html">Performance Tuning</a></li>
    <li><a href="misc/security_tips.html">Security Tips</a></li>
    <li><a href="server-wide.html">Server-Wide Configuration</a></li>
    <li><a href="ssl/">SSL/TLS Encryption</a></li>
    <li><a href="suexec.html">Suexec Execution for CGI</a></li>
    <li><a href="rewrite/">URL Rewriting with mod_rewrite</a></li>
    <li><a href="vhosts/">Virtual Hosts</a></li>
    </ul>
    </div></td><td class="col3"><div class="category"><h2><a name="howto" id="howto">How-To / Tutorials</a></h2>
    <ul><li><a href="howto/auth.html">Authentication and Authorization</a></li>
    <li><a href="howto/access.html">Access Control</a></li>
    <li><a href="howto/cgi.html">CGI: Dynamic Content</a></li>
    <li><a href="howto/htaccess.html">.htaccess files</a></li>
    <li><a href="howto/ssi.html">Server Side Includes (SSI)</a></li>
    <li><a href="howto/public_html.html">Per-user Web Directories (public_html)</a></li>
    <li><a href="howto/reverse_proxy.html">Reverse proxy setup guide</a></li>
    <li><a href="howto/http2.html">HTTP/2 guide</a></li>
    </ul>
    </div><div class="category"><h2><a name="platform" id="platform">Platform Specific Notes</a></h2>
    <ul><li><a href="platform/windows.html">Microsoft Windows</a></li>
    <li><a href="platform/rpm.html">RPM-based Systems (Redhat / CentOS / Fedora)</a></li>
    <li><a href="platform/netware.html">Novell NetWare</a></li>
    <li><a href="platform/ebcdic.html">EBCDIC Port</a></li>
    </ul>
    </div><div class="category"><h2><a name="other" id="other">Other Topics</a></h2>
    <ul><li><a href="http://wiki.apache.org/httpd/FAQ">Frequently Asked Questions</a></li>
    <li><a href="sitemap.html">Sitemap</a></li>
    <li><a href="developer/">Documentation for Developers</a></li>
    <li><a href="http://httpd.apache.org/docs-project/">Helping with the documentation</a></li>
    <li><a href="misc/">Other Notes</a></li>
    <li><a href="http://wiki.apache.org/httpd/">Wiki</a></li>
    </ul>
    </div></td></tr></table></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./da/" hreflang="da" rel="alternate" title="Dansk">&nbsp;da&nbsp;</a> |
    <a href="./de/" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./ru/" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a> |
    <a href="./tr/" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/stopping.html.fr.utf8������������������������������������������������������0000664�0001751�0001751�00000047252�14740503670�021073� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Arrêt et redémarrage du serveur HTTP Apache - Serveur HTTP Apache Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p>
    <p class="apache">Serveur HTTP Apache Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">Serveur HTTP</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Arrêt et redémarrage du serveur HTTP Apache</h1>
    <div class="toplang">
    <p><span>Langues Disponibles: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>Ce document couvre l'arrêt et le redémarrage du
        serveur HTTP Apache sur
        les systèmes Unix et similaires. Les utilisateurs de Windows NT, 2000
        and XP doivent consulter
        <a href="platform/windows.html#winsvc">Exécuter httpd en tant que
        service</a> et les utilisateurs de Windows 9x et ME doivent consulter
        <a href="platform/windows.html#wincons">Exécuter httpd comme une
        application de type console</a> pour plus d'informations sur le contrôle
        de httpd à partir de ces plateformes.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#term">Arrêter immédiatement</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#graceful">Redémarrage en douceur</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#hup">Redémarrer immédiatement</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#gracefulstop">Arrêt en douceur</a></li>
    </ul><h3>Voir aussi</h3><ul class="seealso"><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="invoking.html">Démarrage</a></li><li><a href="#comments_section">Commentaires</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    
        <p>Afin d'arrêter ou redémarrer le serveur HTTP Apache, vous devez envoyer un signal aux
        processus <code class="program"><a href="./programs/httpd.html">httpd</a></code> en cours d'exécution.  Les signaux
        peuvent être envoyés de deux manières. La
        première méthode consiste à
        utiliser la commande unix <code>kill</code>
        pour envoyer directement des signaux aux processus. Vous pouvez remarquer
        que plusieurs processus <code class="program"><a href="./programs/httpd.html">httpd</a></code> s'exécutent sur votre
        système, mais il vous suffit d'envoyer les signaux au processus parent,
        dont le PID est enregistré dans le fichier précisé par la directive
        <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>. Autrement dit, vous
        n'aurez jamais besoin d'envoyer des signaux à aucun des
        processus enfants, mais seulement au processus parent. Quatre types
        de signaux peuvent être envoyés au processus parent :
        <code><a href="#term">TERM</a></code>,
        <code><a href="#graceful">USR1</a></code>,
        <code><a href="#hup">HUP</a></code>, et
        <code><a href="#gracefulstop">WINCH</a></code>, qui
        seront décrit plus loin.</p>
    
        <p>Pour envoyer un signal au processus parent, vous devez entrer une commande
        du style :</p>
    
    <div class="example"><p><code>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</code></p></div>
    
        <p>La seconde méthode permettant d'envoyer des signaux aux processus
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        consiste à utiliser les options <code>stop</code>,
        <code>restart</code>, <code>graceful</code> et
        <code>graceful-stop</code> du commutateur <code>-k</code> de la ligne
        de commande comme décrit ci-dessous.  Ce sont des arguments du binaire
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>, mais il est recommandé de les utiliser
        avec le script de contrôle <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>, qui se
        chargera de les passer à <code class="program"><a href="./programs/httpd.html">httpd</a></code>.</p>
    
        <p>Après avoir envoyé un signal à <code class="program"><a href="./programs/httpd.html">httpd</a></code>, vous pouvez
        suivre le cours de son action en entrant :</p>
    
    <div class="example"><p><code>tail -f /usr/local/apache2/logs/error_log</code></p></div>
    
        <p>Adaptez ces exemples en fonction de la définition de vos directives
        <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> et
        <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="term" id="term">Arrêter immédiatement</a></h2>
    
    <dl><dt>Signal: TERM</dt>
    <dd><code>apachectl -k stop</code></dd>
    </dl>
    
        <p>A la réception du signal <code>TERM</code> ou <code>stop</code>,
        le processus parent tente immédiatement
        de tuer tous ses processus enfants. Cela peut durer plusieurs secondes.
        Après cela, le processus parent lui-même se termine. Toutes les requêtes
        en cours sont terminées, et plus aucune autre n'est traitée.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="graceful" id="graceful">Redémarrage en douceur</a></h2>
    
    <dl><dt>Signal: USR1</dt>
    <dd><code>apachectl -k graceful</code></dd>
    </dl>
    
        <p>A la réception du signal <code>USR1</code> ou
        <code>graceful</code>, le
        processus parent envoie aux processus enfants
        <em>l'ordre</em> de se terminer une fois leur requête courante
        traitée (ou de se terminer immédiatement s'ils n'ont plus rien à traiter).
        Le processus parent relit ses fichiers de configuration et
        réouvre ses fichiers de log. Chaque fois qu'un enfant s'éteint, le
        processus parent le remplace par un processus
        enfant de la nouvelle <em>génération</em> de la
        configuration, et celui-ci commence immédiatement à traiter les
        nouvelles requêtes.</p>
    
        <p>Ce code est conçu pour toujours respecter la directive de contrôle
        de processus des modules MPMs, afin que les nombres de processus et de
        threads
        disponibles pour traiter les demandes des clients soient maintenus à
        des valeurs appropriées tout au long du processus de démarrage.
        En outre, il respecte la directive
        <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> de la manière
        suivante : si après une seconde au moins <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> nouveaux processus
        enfants n'ont pas été créés, un nombre suffisant de processus
        supplémentaires est créé pour combler le manque. Ainsi le code
        tente de maintenir à la fois le nombre approprié de processus enfants
        en fonction de la charge du serveur, et le nombre de processus défini par la
        directive <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code>.</p>
    
        <p>Les utilisateurs du module <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>
        noteront que les statistiques du serveur ne sont <strong>pas</strong>
        remises à zéro quand un signal <code>USR1</code> est envoyé. Le code
        a été conçu à la fois pour minimiser la durée durant laquelle le
        serveur ne peut pas traiter de nouvelles requêtes (elle sont mises en
        file d'attente par le système d'exploitation, et ne sont ainsi jamais
        perdues) et pour respecter vos paramètres de personnalisation.
        Pour y parvenir, il doit conserver le
        <em>tableau</em> utilisé pour garder la trace de tous les processus
        enfants au cours des différentes générations.</p>
    
        <p>Dans son état des processus,
        le module status utilise aussi un caractère <code>G</code> afin d'indiquer
        quels processus enfants ont encore des traitements de requêtes en cours
        débutés avant que l'ordre graceful restart ne soit donné.</p>
    
        <p>Pour l'instant, il est impossible pour un script de rotation
        des logs utilisant
        <code>USR1</code> de savoir de manière certaine si tous les processus
        enfants inscrivant des traces de pré-redémarrage sont terminés.
        Nous vous suggérons d'attendre un délai suffisant après l'envoi du
        signal <code>USR1</code>
        avant de faire quoi que ce soit avec les anciens logs. Par exemple,
        si la plupart de vos traitements durent moins de 10 minutes pour des
        utilisateurs empruntant des liaisons à faible bande passante, alors vous
        devriez attendre 15 minutes avant de faire quoi que ce soit
        avec les anciens logs.</p>
    
        <div class="note">
        <p>Lorsque vous initiez un redémarrage, une vérification de
        la syntaxe est tout d'abord effectuée, afin de s'assurer qu'il n'y a
        pas d'erreurs dans les fichiers de configuration. Si votre fichier de
        configuration comporte des erreurs de syntaxe, vous recevrez un message
        d'erreur les concernant, et le serveur refusera de redémarrer. Ceci
        permet d'éviter la situation où un serveur a
        été arrêté et ne peut plus redémarrer,
        et où vous vous retrouvez avec un serveur hors-service.</p>
    
        <p>Ceci ne garantit pas encore que le serveur va redémarrer
        correctement. Pour vérifier la sémantique des fichiers de configuration
        en plus de leur syntaxe, vous pouvez essayer de démarrer
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> sous un utilisateur non root.
        S'il n'y a pas d'erreur, il tentera d'ouvrir ses sockets et ses fichiers
        de log et échouera car il n'a pas les privilèges root (ou parce que
        l'instance actuelle de
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> est déjà associée à ces ports). S'il échoue
        pour toute autre raison, il y a probablement une erreur dans le
        fichier de configuration et celle-ci doit être corrigée avant de lancer
        le redémarrage en douceur.</p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hup" id="hup">Redémarrer immédiatement</a></h2>
    
    <dl><dt>Signal: HUP</dt>
    <dd><code>apachectl -k restart</code></dd>
    </dl>
    
        <p>A la réception du signal <code>HUP</code> ou
        <code>restart</code>, le
        processus parent tue ses processus enfants comme pour le signal
        <code>TERM</code>, mais le processus parent ne se termine pas.
        Il relit ses fichiers de configuration, et réouvre ses fichiers de log.
        Puis il donne naissance à un nouveau jeu de processus enfants
        et continue de traiter les requêtes.</p>
    
        <p>Les utilisateurs du module <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>
        noteront que les statistiques du serveur sont remises à zéro quand un
        signal <code>HUP</code> est envoyé.</p>
    
    <div class="note">Comme dans le cas d'un redémarrage "graceful", une
    vérification de la syntaxe est effectuée avant que le
    redémarrage ne soit tenté. Si votre fichier de configuration comporte
    des erreurs de syntaxe, le redémarrage ne sera pas effectué, et
    vous recevrez un message concernant ces erreurs.</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gracefulstop" id="gracefulstop">Arrêt en douceur</a></h2>
    
    <dl><dt>Signal : WINCH</dt>
    <dd><code>apachectl -k graceful-stop</code></dd>
    </dl>
    
        <p>A la réception du signal <code>WINCH</code> ou
        <code>graceful-stop</code>, le
        processus parent <em>ordonne</em> à ses processus enfants
        de s'arrêter après le traitement de leur requête en cours
        (ou de s'arrêter immédiatement s'ils n'ont plus de requête à traiter).
        Le processus parent va alors supprimer son fichier
        <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> et cesser l'écoute
        de tous ses ports. Le processus parent va continuer à s'exécuter,
        et va surveiller les processus enfants
        qui ont encore des requêtes à traiter. Lorsque tous les processus enfants
        ont terminé leurs traitements et se sont arrêtés ou lorsque le délai
        spécifié par la directive <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code> a été atteint,
        le processus parent s'arrêtera à son tour.  Si ce délai est atteint,
        tout processus enfant encore en cours d'exécution se verra envoyer
        le signal <code>TERM</code>
        afin de le forcer à s'arrêter.</p>
    
        <p>L'envoi du signal <code>TERM</code> va arrêter immédiatement
        les processus parent et enfants en état "graceful". Cependant,
        comme le fichier <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>
        aura été supprimé, vous ne pourrez pas utiliser
        <code>apachectl</code> ou <code>httpd</code> pour envoyer ce signal.</p>
    
        <div class="note"><p>Le signal <code>graceful-stop</code> vous permet d'exécuter
        simultanément plusieurs instances de <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        avec des configurations identiques. Ceci s'avère une fonctionnalité
        puissante quand vous effectuez des mises à jour "en douceur"
        de httpd ; cependant, cela peut aussi causer des blocages fatals et des
        situations de compétition (race conditions)
        avec certaines configurations.</p>
    
        <p>On a pris soin de s'assurer que les fichiers sur disque
        comme les fichiers verrou (<code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>) et les fichiers socket Unix
        (<code class="directive"><a href="./mod/mod_cgid.html#scriptsock">ScriptSock</a></code>) contiennent le PID
        du serveur, et coexistent sans problème. Cependant, si une directive de
        configuration, un module tiers ou une CGI résidente utilise un autre
        verrou ou fichier d'état sur disque, il faut prendre soin de s'assurer
        que chaque instance de <code class="program"><a href="./programs/httpd.html">httpd</a></code> qui s'exécute
        n'écrase pas les fichiers des autres instances.</p>
    
        <p>Vous devez aussi prendre garde aux autres situations de compétition,
        comme l'enregistrement des logs avec un transfert de ceux-ci
        via un pipe vers le programme <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code>. Plusieurs instances
        du programme <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> qui tentent d'effectuer
        une rotation des mêmes fichiers de log en même temps peuvent détruire
        mutuellement leurs propres fichiers de log.</p></div>
    </div></div>
    <div class="bottomlang">
    <p><span>Langues Disponibles: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Commentaires</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/stopping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Autorisé sous <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossaire</a> | <a href="./sitemap.html">Plan du site</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/configuring.html.en��������������������������������������������������������0000664�0001751�0001751�00000042557�14737241666�020665� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Configuration Files - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Configuration Files</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    <p>This document describes the files used to configure Apache HTTP
    Server.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#main">Main Configuration Files</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#syntax">Syntax of the Configuration Files</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#modules">Modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#scope">Scope of Directives</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#htaccess">.htaccess Files</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="main" id="main">Main Configuration Files</a></h2>
        
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#include">Include</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code></li></ul></td></tr></table>
    
        <p>Apache HTTP Server is configured by placing <a href="mod/directives.html">directives</a> in plain text
        configuration files. The main configuration file is usually called
        <code>httpd.conf</code>. The location of this file is set at
        compile-time, but may be overridden with the <code>-f</code>
        command line flag. In addition, other configuration files may be
        added using the <code class="directive"><a href="./mod/core.html#include">Include</a></code>
        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 httpd when it is started or restarted.</p>
    
        <p>The server also reads a file containing mime document types;
        the filename is set by the <code class="directive"><a href="./mod/mod_mime.html#typesconfig">TypesConfig</a></code> directive,
        and is <code>mime.types</code> by default.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="syntax" id="syntax">Syntax of the Configuration Files</a></h2>
        
    
        <p>httpd configuration files contain one directive per line.
        The backslash "\" 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
        backslash and the end of the line.</p>
    
        <p>Arguments to directives are separated by whitespace. If an 
        argument contains spaces, you must enclose that argument in quotes.</p>
    
        <p>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 <strong>not</strong> be
        included on the same line as a configuration directive. 
        White space occurring before a directive is ignored, so
        you may indent directives for clarity. Blank lines are also ignored.</p>
    
        <p>The values of variables defined with the <code class="directive"><a href="./mod/core.html#define">Define</a></code> of or shell environment variables can
        be used in configuration file lines using the syntax <code>${VAR}</code>.
        If "VAR" is the name of a valid variable, the value of that variable is
        substituted into that spot in the configuration file line, and processing
        continues as if that text were found directly in the configuration file.
        Variables defined with <code class="directive"><a href="./mod/core.html#define">Define</a></code> take
        precedence over shell environment variables.
        If the "VAR" variable is not found, the characters <code>${VAR}</code>
        are left unchanged, and a warning is logged.
        Variable names may not contain colon ":" characters, to avoid clashes with
        <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>'s syntax.</p>
    
        <p>Only shell environment variables defined before the server is started
        can be used in expansions. Environment variables defined in the
        configuration file itself, for example with <code class="directive"><a href="./mod/mod_env.html#setenv">SetEnv</a></code>, take effect too late to be used for
        expansions in the configuration file.</p>
    
        <p>The maximum length of a line in normal configuration files, after
        variable substitution and joining any continued lines, is approximately
        16 MiB. In <a href="configuring.html#htaccess">.htaccess files</a>, the
        maximum length is 8190 characters.</p>
    
        <p>You can check your configuration files for syntax errors
        without starting the server by using <code>apachectl
        configtest</code> or the <code>-t</code> command line
        option.</p>
    
        <p>You can use <code class="module"><a href="./mod/mod_info.html">mod_info</a></code>'s <code>-DDUMP_CONFIG</code> to
        dump the configuration with all included files and environment
        variables resolved and all comments and non-matching
        <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> and
        <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> sections
        removed. However, the output does not reflect the merging or overriding
        that may happen for repeated directives.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="modules" id="modules">Modules</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_so.html">mod_so</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code></li></ul></td></tr></table>
    
        <p>httpd is a modular server. This implies that only the most
        basic functionality is included in the core server. Extended
        features are available through <a href="mod/">modules</a> which can be loaded
        into httpd. By default, a <a href="mod/module-dict.html#Status">base</a> set of modules is
        included in the server at compile-time. If the server is
        compiled to use <a href="dso.html">dynamically loaded</a>
        modules, then modules can be compiled separately and added at
        any time using the <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code>
        directive.
        Otherwise, httpd 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 <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code> block. However,
        <code class="directive">&lt;IfModule&gt;</code> blocks are not
        required, and in some cases may mask the fact that you're missing an
        important module.</p>
    
        <p>To see which modules are currently compiled into the server,
        you can use the <code>-l</code> command line option. You can also
        see what modules are loaded dynamically using the <code>-M</code>
        command line option.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="scope" id="scope">Scope of Directives</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
        <p>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 <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, and <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>
        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.</p>
    
        <p>httpd has the capability to serve many different websites
        simultaneously. This is called <a href="vhosts/">Virtual
        Hosting</a>. Directives can also be scoped by placing them
        inside <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        sections, so that they will only apply to requests for a
        particular website.</p>
    
        <p>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 <a href="mod/directive-dict.html#Context">Context</a> of the
        directive. For further information, we provide details on <a href="sections.html">How Directory, Location and Files sections
        work</a>.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="htaccess" id="htaccess">.htaccess Files</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code></li><li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code></li></ul></td></tr></table>
    
        <p>httpd allows for decentralized management of configuration
        via special files placed inside the web tree. The special files
        are usually called <code>.htaccess</code>, but any name can be
        specified in the <code class="directive"><a href="./mod/core.html#accessfilename">AccessFileName</a></code>
        directive. Directives placed in <code>.htaccess</code> files
        apply to the directory where you place the file, and all
        sub-directories. The <code>.htaccess</code> files follow the
        same syntax as the main configuration files. Since
        <code>.htaccess</code> files are read on every request, changes
        made in these files take immediate effect.</p>
    
        <p>To find which directives can be placed in
        <code>.htaccess</code> files, check the <a href="mod/directive-dict.html#Context">Context</a> of the
        directive. The server administrator further controls what
        directives may be placed in <code>.htaccess</code> files by
        configuring the <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code>
        directive in the main configuration files.</p>
    
        <p>For more information on <code>.htaccess</code> files, see
        the <a href="howto/htaccess.html">.htaccess tutorial</a>.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/configuring.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/configuring.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/configuring.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/configuring.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/configuring.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/configuring.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/configuring.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/getting-started.html.en����������������������������������������������������0000664�0001751�0001751�00000036336�14737241666�021456� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Getting Started - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Getting Started</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/getting-started.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/getting-started.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ru/getting-started.html" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a></p>
    </div>
    
    <p>If you're completely new to the Apache HTTP Server, or even to running
    a website at all, you might not know where to start, or what questions to
    ask. This document walks you through the basics.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#clientserver">Clients, Servers, and URLs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#dns">Hostnames and DNS</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configuration">Configuration Files and Directives</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#content">Web Site Content</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#logs">Log Files and Troubleshooting</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">What's next?</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="clientserver" id="clientserver">Clients, Servers, and URLs</a></h2>
    
    
    <p>
    Addresses on the Web are expressed with URLs - Uniform Resource Locators
    - which specify a protocol (e.g. <code>http</code>), a servername (e.g.
    <code>www.apache.org</code>), a URL-path (e.g.
    <code>/docs/current/getting-started.html</code>), and possibly a query
    string (e.g. <code>?arg=value</code>) used to pass additional
    arguments to the server.
    </p>
    
    <p>A client (e.g., a web browser) connects to a server (e.g., your Apache HTTP Server),
    with the specified protocol, and makes a <strong>request</strong> for a resource using the
    URL-path.</p>
    
    <p>The URL-path may represent any number of things on the server. It may
    be a file (like <code>getting-started.html</code>) a handler (like <a href="mod/mod_status.html">server-status</a>) or some kind of program
    file (like <code>index.php</code>). We'll discuss this more below in
    the <a href="#content">Web Site Content</a> section.</p>
    
    <p>
    The server will send a <strong>response</strong> consisting of a status
    code and, optionally, a response body.
    The status code indicates whether the request was successful, and, if not, what
    kind of error condition there was. This tells the client what it should
    do with the response. You can read about the possible response codes in
    <a href="http://wiki.apache.org/httpd/CommonHTTPStatusCodes">HTTP Server
    wiki</a>.</p>
    
    <p>Details of the transaction, and any error conditions, are written to
    log files. This is discussed in greater detail below in the <a href="#logs">Logs Files and Troubleshooting</a> section.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="dns" id="dns">Hostnames and DNS</a></h2>
    
    
    <p>In order to connect to a server, the client will first have to resolve
    the servername to an IP address - the location on the Internet where the
    server resides. Thus, in order for your web server to be reachable, it
    is necessary that the servername be in DNS.</p>
    
    <p>If you don't know how to do this, you'll need to contact your network
    administrator, or Internet service provider, to perform this step for
    you.</p>
    
    <p>More than one hostname may point to the same IP address, and more
    than one IP address can be attached to the same physical server. Thus, you
    can run more than one web site on the same physical server, using a
    feature called <a href="vhosts/">virtual hosts</a>.</p>
    
    <p>If you are testing a server that is not Internet-accessible, you
    can put host names in your hosts file in order to do local resolution.
    For example, you might want to put a record in your hosts file to map a
    request for <code>www.example.com</code> to your local system, for
    testing purposes. This entry would look like:</p>
    
    <div class="example"><p><code>
    127.0.0.1 www.example.com
    </code></p></div>
    
    <p>A hosts file will probably be located at <code>/etc/hosts</code> or
    <code>C:\Windows\system32\drivers\etc\hosts</code>.</p>
    
    <p>You can read more about the hosts file at <a href="http://en.wikipedia.org/wiki/Hosts_(file)">Wikipedia.org/wiki/Hosts_(file)</a>, and
    more about DNS at <a href="http://en.wikipedia.org/wiki/Domain_Name_System">Wikipedia.org/wiki/Domain_Name_System</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configuration" id="configuration">Configuration Files and Directives</a></h2>
    
    
    <p>The Apache HTTP Server is configured via simple text files.
    These files may be located any of a variety of places, depending on how
    exactly you installed the server. Common locations for these files may
    be found <a href="http://wiki.apache.org/httpd/DistrosDefaultLayout">in
    the httpd wiki</a>. If you installed httpd from source, the default
    location of the configuration files is
    <code>/usr/local/apache2/conf</code>. The default configuration file is
    usually called <code>httpd.conf</code>. This, too, can vary in
    third-party distributions of the server.</p>
    
    <p>The configuration is frequently broken into multiple smaller files,
    for ease of management. These files are loaded via the <code class="directive"><a href="./mod/core.html#include">Include</a></code> directive. The names or locations of
    these sub-files are not magical, and may vary greatly from one
    installation to another. Arrange and subdivide these files as
    makes the most sense to <strong>you</strong>. If the file arrangement
    you have by default doesn't make sense to you, feel free to rearrange it.</p>
    
    <p>The server is configured by placing <a href="mod/quickreference.html">configuration directives</a> in these
    configuration files. A directive is a keyword followed by one or more
    arguments that set its value.</p>
    
    <p>The question of "<em>Where should I put that
    directive?</em>" is generally answered by considering where you want a
    directive to be effective. If it is a global setting, it should appear
    in the configuration file, outside of any <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>, or other section. If it is to
    apply only to a particular directory, then it should go inside a
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> section referring to
    that directory, and so on. See the <a href="sections.html">Configuration
    Sections</a> document for further discussion of these sections.</p>
    
    <p>In addition to the main configuration files, certain directives may go in
    <code>.htaccess</code> files located in the content directories.
    <code>.htaccess</code> files are primarily for people who do not have
    access to the main server configuration file(s). You can read more about
    <code>.htaccess</code> files in the <a href="howto/htaccess.html"><code>.htaccess</code> howto</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="content" id="content">Web Site Content</a></h2>
    
    
    <p>Web site content can take many different forms, but may be broadly
    divided into static and dynamic content.</p>
    
    <p>Static content is things like HTML files, image files, CSS files,
    and other files that reside in the filesystem. The <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> directive specifies where in your
    filesystem you should place these files. This directive is either set
    globally, or per virtual host. Look in your configuration file(s) to
    determine how this is set for your server.</p>
    
    <p>Typically, a document called <code>index.html</code> will be served
    when a directory is requested without a file name being specified. For
    example, if <code>DocumentRoot</code> is set to
    <code>/var/www/html</code> and a request is made for
    <code>http://www.example.com/work/</code>, the file
    <code>/var/www/html/work/index.html</code> will be served to the
    client.</p>
    
    <p>Dynamic content is anything that is generated at request
    time, and may change from one request to another. There are numerous
    ways that dynamic content may be generated. Various <a href="handler.html">handlers</a> are available to generate content. <a href="howto/cgi.html">CGI programs</a> may be written to generate
    content for your site.</p>
    
    <p>Third-party modules like mod_php may be used to write code that does a
    variety of things. Many third-party applications, written using a
    variety of languages and tools, are available for download and
    installation on your Apache HTTP Server. Support of these third-party
    things is beyond the scope of this documentation, and you should find
    their documentation or other support forums to answer your questions
    about them.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="logs" id="logs">Log Files and Troubleshooting</a></h2>
    
    <p>As an Apache HTTP Server administrator, your most valuable assets are
    the log files, and, in particular, the error log. Troubleshooting any
    problem without the error log is like driving with your eyes closed.</p>
    
    <p>The location of the error log is defined by the <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> directive, which may be set globally,
    or per virtual host. Entries in the error log tell you what went wrong,
    and when. They often also tell you how to fix it. Each error log message
    contains an error code, which you can search for online for even more
    detailed descriptions of how to address the problem. You can also
    configure your error log to contain a log ID which you can then
    correlate to an access log entry, so that you can determine what request
    caused the error condition.</p>
    
    <p>You can read more about logging in the <a href="logs.html">logs
    documentation</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">What's next?</a></h2>
    
    
    <p>Once you have the prerequisites under your belt, it's time to move
    on.</p>
    
    <p>This document covers only the bare basics. We hope that this gets you
    started, but there are many other things that you might need to
    know.</p>
    
    <ul>
    <li><a href="http://httpd.apache.org/download.cgi">Download</a></li>
    <li><a href="install.html">Install</a></li>
    <li><a href="configuring.html">Configure</a></li>
    <li><a href="invoking.html">Start</a></li>
    <li><a href="http://wiki.apache.org/httpd/FAQ">Frequently Asked Questions</a></li>
    </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/getting-started.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/getting-started.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ru/getting-started.html" hreflang="ru" rel="alternate" title="Russian">&nbsp;ru&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/getting-started.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/logs.html.en���������������������������������������������������������������0000664�0001751�0001751�00000116034�14737241666�017307� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Log Files - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Log Files</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/logs.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>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.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Overview</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#security">Security Warning</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errorlog">Error Log</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#permodule">Per-module logging</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#accesslog">Access Log</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rotation">Log Rotation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#piped">Piped Logs</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Virtual Hosts</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Other Log Files</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Overview</a></h2>
        
    
      <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code></li><li><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td /></tr></table>
    
      <p>
      The Apache HTTP Server provides a variety of different mechanisms for
      logging everything that happens on your server, from the initial
      request, through the URL mapping process, to the final resolution of
      the connection, including any errors that may have occurred in the
      process. In addition to this, third-party modules may provide logging
      capabilities, or inject entries into the existing log files, and
      applications such as CGI programs, or PHP scripts, or other handlers,
      may send messages to the server error log.
      </p>
    
      <p>
      In this document we discuss the logging modules that are a standard
      part of the http server.
      </p>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="security" id="security">Security Warning</a></h2>
        
    
        <p>Anyone who can write to the directory where Apache httpd is
        writing a log file can almost certainly gain access to the uid
        that the server is started as, which is normally root. Do
        <em>NOT</em> give people write access to the directory the logs
        are stored in without being aware of the consequences; see the
        <a href="misc/security_tips.html">security tips</a> document
        for details.</p>
    
        <p>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.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errorlog" id="errorlog">Error Log</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code></li><li><code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code></li></ul></td></tr></table>
    
        <p>The server error log, whose name and location is set by the
        <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> 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.</p>
    
        <p>The error log is usually written to a file (typically
        <code>error_log</code> on Unix systems and
        <code>error.log</code> on Windows and OS/2). On Unix systems it
        is also possible to have the server send errors to
        <code>syslog</code> or <a href="#piped">pipe them to a
        program</a>.</p>
    
        <p>The format of the error log is defined by the <code class="directive"><a href="./mod/core.html#errorlogformat">ErrorLogFormat</a></code> directive, with which you
        can customize what values are logged. A default is format defined
        if you don't specify one. A typical log message follows:</p>
    
        <div class="example"><p><code>
        [Fri Sep 09 10:42:29.902022 2011] [core:error] [pid 35708:tid 4328636416]
        [client 72.15.99.187] File does not exist: /usr/local/apache2/htdocs/favicon.ico
        </code></p></div>
    
        <p>The first item in the log entry is the date and time of the
        message. The next is the module producing the message (core, in this
        case) and the severity level of that message. This is followed by
        the process ID and, if appropriate, the thread ID, of the process
        that experienced the condition. Next, we have the client address
        that made the request. And finally is the detailed error message,
        which in this case indicates a request for a file that did not
        exist.</p>
    
        <p>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 <code>stderr</code> by a CGI script will
        be copied directly to the error log.</p>
    
        <p>Putting a <code>%L</code> token in both the error log and the access
        log will produce a log entry ID with which you can correlate the entry
        in the error log with the entry in the access log. If
        <code class="module"><a href="./mod/mod_unique_id.html">mod_unique_id</a></code> is loaded, its unique request ID will be
        used as the log entry ID, too.</p>
    
        <p>During testing, it is often useful to continuously monitor
        the error log for any problems. On Unix systems, you can
        accomplish this using:</p>
    
        <div class="example"><p><code>
          tail -f error_log
        </code></p></div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="permodule" id="permodule">Per-module logging</a></h2>
        
    
        <p>The <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> directive
        allows you to specify a log severity level on a per-module basis. In
        this way, if you are troubleshooting a problem with just one
        particular module, you can turn up its logging volume without also
        getting the details of other modules that you're not interested in.
        This is particularly useful for modules such as
        <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> or <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> where you
        want to know details about what it's trying to do.</p>
    
        <p>Do this by specifying the name of the module in your
        <code class="directive">LogLevel</code> directive:</p>
    
        <pre class="prettyprint lang-config">LogLevel info rewrite:trace5</pre>
    
    
        <p>This sets the main <code class="directive">LogLevel</code> to info, but
        turns it up to <code>trace5</code> for
        <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
        <div class="note">This replaces the per-module logging directives, such as
        <code>RewriteLog</code>, that were present in earlier versions of
        the server.</div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="accesslog" id="accesslog">Access Log</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_setenvif.html">mod_setenvif</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code></li></ul></td></tr></table>
    
        <p>The server access log records all requests processed by the
        server. The location and content of the access log are
        controlled by the <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
        directive. The <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code>
        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.</p>
    
        <p>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.
        </p>
    
        <p>Various versions of Apache httpd have used other modules and
        directives to control access logging, including
        mod_log_referer, mod_log_agent, and the
        <code>TransferLog</code> directive. The <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> directive now subsumes
        the functionality of all the older directives.</p>
    
        <p>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 <code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code> <a href="mod/mod_log_config.html#formats">format strings</a>.</p>
    
        <h3><a name="common" id="common">Common Log Format</a></h3>
          
    
          <p>A typical configuration for the access log might look as
          follows.</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common
    CustomLog logs/access_log common</pre>
    
    
          <p>This defines the <em>nickname</em> <code>common</code> 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
          (<code>"</code>) must be escaped by placing a backslash 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 "<code>\n</code>" for new-line and
          "<code>\t</code>" for tab.</p>
    
          <p>The <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
          directive sets up a new log file using the defined
          <em>nickname</em>. The filename for the access log is relative to
          the <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> unless it
          begins with a slash.</p>
    
          <p>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:</p>
    
          <div class="example"><p><code>
            127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET
            /apache_pb.gif HTTP/1.0" 200 2326
          </code></p></div>
    
          <p>Each part of this log entry is described below.</p>
    
          <dl>
            <dt><code>127.0.0.1</code> (<code>%h</code>)</dt>
    
            <dd>This is the IP address of the client (remote host) which
            made the request to the server. If <code class="directive"><a href="./mod/core.html#hostnamelookups">HostnameLookups</a></code> is
            set to <code>On</code>, 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 <code class="program"><a href="./programs/logresolve.html">logresolve</a></code> 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.</dd>
    
            <dt><code>-</code> (<code>%l</code>)</dt>
    
            <dd>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 <code>identd</code> 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 <code class="directive"><a href="./mod/mod_ident.html#identitycheck">IdentityCheck</a></code> is set
            to <code>On</code>.</dd>
    
            <dt><code>frank</code> (<code>%u</code>)</dt>
    
            <dd>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
            <code>REMOTE_USER</code> 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 part will be "<code>-</code>" just like the previous
            one.</dd>
    
            <dt><code>[10/Oct/2000:13:55:36 -0700]</code>
            (<code>%t</code>)</dt>
    
            <dd>
              The time that the request was received.
              The format is:
    
              <p class="indent">
                <code>[day/month/year:hour:minute:second zone]<br />
                 day = 2*digit<br />
                 month = 3*letter<br />
                 year = 4*digit<br />
                 hour = 2*digit<br />
                 minute = 2*digit<br />
                 second = 2*digit<br />
                 zone = (`+' | `-') 4*digit</code>
              </p>
              <p>It is possible to have the time displayed in another format
              by specifying <code>%{format}t</code> in the log format
              string, where <code>format</code> is either as in
              <code>strftime(3)</code> from the C standard library,
              or one of the supported special tokens. For details see
              the <code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code> <a href="mod/mod_log_config.html#formats">format strings</a>.</p>
            </dd>
    
            <dt><code>"GET /apache_pb.gif HTTP/1.0"</code>
            (<code>\"%r\"</code>)</dt>
    
            <dd>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
            <code>GET</code>. Second, the client requested the resource
            <code>/apache_pb.gif</code>, and third, the client used the
            protocol <code>HTTP/1.0</code>. It is also possible to log
            one or more parts of the request line independently. For
            example, the format string "<code>%m %U%q %H</code>" will log
            the method, path, query-string, and protocol, resulting in
            exactly the same output as "<code>%r</code>".</dd>
    
            <dt><code>200</code> (<code>%&gt;s</code>)</dt>
    
            <dd>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 <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">HTTP
            specification</a> (RFC2616 section 10).</dd>
    
            <dt><code>2326</code> (<code>%b</code>)</dt>
    
            <dd>The last part 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
            "<code>-</code>". To log "<code>0</code>" for no content, use
            <code>%B</code> instead.</dd>
          </dl>
        
    
        <h3><a name="combined" id="combined">Combined Log Format</a></h3>
          
    
          <p>Another commonly used format string is called the Combined
          Log Format. It can be used as follows.</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
    CustomLog log/access_log combined</pre>
    
    
          <p>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
          <code>%{<em>header</em>}i</code>, where <em>header</em> can be
          any HTTP request header. The access log under this format will
          look like:</p>
    
          <div class="example"><p><code>
            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)"
          </code></p></div>
    
          <p>The additional fields are:</p>
    
          <dl>
            <dt><code>"http://www.example.com/start.html"</code>
            (<code>\"%{Referer}i\"</code>)</dt>
    
            <dd>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
            <code>/apache_pb.gif</code>).</dd>
    
            <dt><code>"Mozilla/4.08 [en] (Win98; I ;Nav)"</code>
            (<code>\"%{User-agent}i\"</code>)</dt>
    
            <dd>The User-Agent HTTP request header. This is the
            identifying information that the client browser reports about
            itself.</dd>
          </dl>
        
    
        <h3><a name="multiple" id="multiple">Multiple Access Logs</a></h3>
          
    
          <p>Multiple access logs can be created simply by specifying
          multiple <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
          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 <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> lines show how
          to mimic the effects of the <code>ReferLog</code> and <code>AgentLog</code> directives.</p>
    
          <pre class="prettyprint lang-config">LogFormat "%h %l %u %t \"%r\" %&gt;s %b" common
    CustomLog logs/access_log common
    CustomLog logs/referer_log "%{Referer}i -&gt; %U"
    CustomLog logs/agent_log "%{User-agent}i"</pre>
    
    
          <p>This example also shows that it is not necessary to define a
          nickname with the <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> directive. Instead,
          the log format can be specified directly in the <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> directive.</p>
        
    
        <h3><a name="conditional" id="conditional">Conditional Logs</a></h3>
          
    
          <p>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 <a href="env.html">environment variables</a>. First, an
          environment variable must be set to indicate that the request
          meets certain conditions. This is usually accomplished with
          <code class="directive"><a href="./mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>. Then the
          <code>env=</code> clause of the <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> directive is used to
          include or exclude requests where the environment variable is
          set. Some examples:</p>
    
          <pre class="prettyprint lang-config"># 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</pre>
    
    
          <p>As another example, consider logging requests from
          english-speakers to one log file, and non-english speakers to a
          different log file.</p>
    
          <pre class="prettyprint lang-config">SetEnvIf Accept-Language "en" english
    CustomLog logs/english_log common env=english
    CustomLog logs/non_english_log common env=!english</pre>
    
    
          <p>In a caching scenario one would want to know about
          the efficiency of the cache. A very simple method to
          find this out would be:</p>
    
          <pre class="prettyprint lang-config">SetEnv CACHE_MISS 1
    LogFormat "%h %l %u %t "%r " %&gt;s %b %{CACHE_MISS}e" common-cache
    CustomLog logs/access_log common-cache</pre>
    
    
          <p><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> will run before
          <code class="module"><a href="./mod/mod_env.html">mod_env</a></code> and, when successful, will deliver the
          content without it. In that case a cache hit will log
          <code>-</code>, while a cache miss will log <code>1</code>.</p>
    
          <p>In addition to the <code>env=</code> syntax, <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> supports logging values
          conditional upon the HTTP response code:</p>
    
          <pre class="prettyprint lang-config">LogFormat "%400,501{User-agent}i" browserlog
    LogFormat "%!200,304,302{Referer}i" refererlog</pre>
    
    
          <p>In the first example, the <code>User-agent</code> will be
          logged if the HTTP status code is 400 or 501. In other cases, a
          literal "-" will be logged instead. Likewise, in the second
          example, the <code>Referer</code> will be logged if the HTTP
          status code is <strong>not</strong> 200, 304, or 302. (Note the
          "!" before the status codes.</p>
    
          <p>Although we have just shown that conditional logging is very
          powerful and flexible, 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.</p>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rotation" id="rotation">Log Rotation</a></h2>
        
    
        <p>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 httpd will continue
        writing to the old log file as long as it holds the file open.
        Instead, the server must be <a href="stopping.html">restarted</a> after the log files are
        moved or deleted so that it will open new log files.</p>
    
        <p>By using a <em>graceful</em> 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:</p>
    
        <div class="example"><p><code>
          mv access_log access_log.old<br />
          mv error_log error_log.old<br />
          apachectl graceful<br />
          sleep 600<br />
          gzip access_log.old error_log.old
        </code></p></div>
    
        <p>Another way to perform log rotation is using <a href="#piped">piped logs</a> as discussed in the next
        section.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="piped" id="piped">Piped Logs</a></h2>
        
    
        <p>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 "<code>|</code>", followed by the name
        of the executable which should accept log entries on its
        standard input. The server 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".)</p>
    
        <p>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.</p>
    
        <p>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 <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code>
        for this purpose. For example, to rotate the logs every 24 hours, you
        can use:</p>
    
        <pre class="prettyprint lang-config">CustomLog "|/usr/local/apache/bin/rotatelogs /var/log/access_log 86400" common</pre>
    
    
        <p>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.</p>
    
        <p>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.</p>
    
        <p>By default the piped log process is spawned without invoking
        a shell. Use "<code>|$</code>" instead of "<code>|</code>"
        to spawn using a shell (usually with <code>/bin/sh -c</code>):</p>
    
        <pre class="prettyprint lang-config"># Invoke "rotatelogs" using a shell
    CustomLog "|$/usr/local/apache/bin/rotatelogs   /var/log/access_log 86400" common</pre>
    
    
        <p>This was the default behaviour for Apache 2.2.
        Depending on the shell specifics this might lead to
        an additional shell process for the lifetime of the logging
        pipe program and signal handling problems during restart.
        For compatibility reasons with Apache 2.2 the notation
        "<code>||</code>" is also supported and equivalent to using
        "<code>|</code>".</p>
    
        <div class="note"><h3>Windows note</h3>
        <p>Note that on Windows, you may run into problems when running many piped
        logger processes, especially when HTTPD is running as a service. This is
        caused by running out of desktop heap space. The desktop heap space given
        to each service is specified by the third argument to the
        <code>SharedSection</code> parameter in the
        HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\SubSystems\Windows
        registry value. <strong>Change this value with care</strong>; the normal
        caveats for changing the Windows registry apply, but you might also exhaust
        the desktop heap pool if the number is adjusted too high.</p>
        </div>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Virtual Hosts</a></h2>
        
    
        <p>When running a server with many <a href="vhosts/">virtual
        hosts</a>, 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 <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> 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.</p>
    
        <p>If <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code>
        or <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code>
        directives are placed inside a
        <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        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 <a href="vhosts/fd-limits.html">insufficient file
        descriptors</a>.</p>
    
        <p>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.</p>
    
        <pre class="prettyprint lang-config">LogFormat "%v %l %u %t \"%r\" %&gt;s %b" comonvhost
    CustomLog logs/access_log comonvhost</pre>
    
    
        <p>The <code>%v</code> is used to log the name of the virtual
        host that is serving the request. Then a program like <a href="programs/split-logfile.html">split-logfile</a> can be used to
        post-process the access log in order to split it into one file
        per virtual host.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Other Log Files</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code></li><li><code class="module"><a href="./mod/mod_log_config.html">mod_log_config</a></code></li><li><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code></li><li><code class="directive"><a href="./mod/mod_log_config.html#bufferedlogs">BufferedLogs</a></code></li><li><code class="directive"><a href="./mod/mod_log_forensic.html#forensiclog">ForensicLog</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptlogbuffer">ScriptLogBuffer</a></code></li><li><code class="directive"><a href="./mod/mod_cgi.html#scriptloglength">ScriptLogLength</a></code></li></ul></td></tr></table>
    
        <h3>Logging actual bytes sent and received</h3>
          
    
          <p><code class="module"><a href="./mod/mod_logio.html">mod_logio</a></code> adds in two additional
             <code class="directive"><a href="./mod/mod_log_config.html#logformat">LogFormat</a></code> fields
             (%I and %O) that log the actual number of bytes received and sent
             on the network.</p>
        
    
        <h3>Forensic Logging</h3>
          
    
          <p><code class="module"><a href="./mod/mod_log_forensic.html">mod_log_forensic</a></code> 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 with no customizations.
             It can be an invaluable debugging and security tool.</p>
        
    
        <h3><a name="pidfile" id="pidfile">PID File</a></h3>
          
    
          <p>On startup, Apache httpd saves the process id of the parent
          httpd process to the file <code>logs/httpd.pid</code>. This
          filename can be changed with the <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> 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 <a href="stopping.html">Stopping
          and Restarting</a> page.</p>
        
    
        <h3><a name="scriptlog" id="scriptlog">Script Log</a></h3>
          
    
          <p>In order to aid in debugging, the
          <code class="directive"><a href="./mod/mod_cgi.html#scriptlog">ScriptLog</a></code> 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 <a href="mod/mod_cgi.html">mod_cgi</a> documentation.</p>
        
    
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/logs.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/logs.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/logs.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/logs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/logs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/logs.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_4.html.en���������������������������������������������������0000664�0001751�0001751�00000070257�14737241666�021504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Overview of new features in Apache HTTP Server 2.4 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Overview of new features in Apache HTTP Server 2.4</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/new_features_2_4.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_4.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/new_features_2_4.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>This document describes some of the major changes between the
         2.2 and 2.4 versions of the Apache HTTP Server. For new features since
         version 2.0, see the <a href="new_features_2_2.html">2.2 new features</a>
         document.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Core Enhancements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#newmods">New Modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Module Enhancements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Program Enhancements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentation">Documentation</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Module Developer Changes</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Core Enhancements</a></h2>
        
        <dl>
          <dt>Run-time Loadable MPMs</dt>
          <dd>Multiple MPMs can now be <a href="mpm.html#dynamic">built
          as loadable modules</a> at compile time.
          The MPM of choice can be configured at run time via <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> directive.</dd>
    
          <dt>Event MPM</dt>
          <dd>The <a href="mod/event.html">Event MPM</a> is no longer experimental
          but is now fully supported.</dd>
    
          <dt>Asynchronous support</dt>
          <dd>Better support for asynchronous read/write for supporting MPMs and
          platforms.</dd>
    
          <dt>Per-module and per-directory LogLevel configuration</dt>
          <dd>The <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> can now be
          configured per module and per directory.  New levels <code>trace1</code>
          to <code>trace8</code> have been added above the <code>debug</code> log
          level.</dd>
    
          <dt>Per-request configuration sections</dt>
          <dd><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>,
              <code class="directive"><a href="./mod/core.html#elseif">&lt;ElseIf&gt;</a></code>,
              and <code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code>
              sections can be used to set the configuration based on per-request
              criteria.</dd>
    
          <dt>General-purpose expression parser</dt>
          <dd>A new expression parser allows to specify
              <a href="expr.html">complex conditions</a> using a common syntax
              in directives like
              <code class="directive"><a href="./mod/mod_setenvif.html#setenvifexpr">SetEnvIfExpr</a></code>,
              <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>,
              <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code>,
              <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>,
              and others.
          </dd>
    
          <dt>KeepAliveTimeout in milliseconds</dt>
          <dd>It is now possible to specify <code class="directive"><a href="./mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code> in milliseconds.
          </dd>
    
          <dt>NameVirtualHost directive</dt>
          <dd>No longer needed and is now deprecated.</dd>
    
          <dt>Override Configuration</dt>
          <dd>The new <code class="directive"><a href="./mod/core.html#allowoverridelist">AllowOverrideList</a></code>
              directive allows more fine grained control which directives are
              allowed in <code>.htaccess</code> files. </dd>
    
          <dt>Config file variables</dt>
          <dd>It is now possible to <code class="directive"><a href="./mod/core.html#define">Define</a></code>
              variables in the configuration, allowing a clearer representation
              if the same value is used at many places in the configuration.
          </dd>
    
          <dt>Reduced memory usage</dt>
          <dd>Despite many new features, 2.4.x tends to use less memory than
          2.2.x.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="newmods" id="newmods">New Modules</a></h2>
        
        <dl>
          <dt><code class="module"><a href="./mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code></dt>
          <dd>FastCGI Protocol backend for <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_scgi.html">mod_proxy_scgi</a></code></dt>
          <dd>SCGI Protocol backend for <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_express.html">mod_proxy_express</a></code></dt>
          <dd>Provides dynamically configured mass reverse proxies for
          <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dd>
    
          <dt><code class="module"><a href="./mod/mod_remoteip.html">mod_remoteip</a></code></dt>
          <dd>Replaces the apparent client remote IP address and hostname for the request
          with the IP address list presented by a proxies or a load balancer via
          the request headers.</dd>
    
          <dt><code class="module"><a href="./mod/mod_heartmonitor.html">mod_heartmonitor</a></code>,
              <code class="module"><a href="./mod/mod_lbmethod_heartbeat.html">mod_lbmethod_heartbeat</a></code></dt>
          <dd>Allow <code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> to base loadbalancing decisions
          on the number of active connections on the backend servers.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code></dt>
          <dd>Formerly a third-party module, this supports fixing of HTML
          links in a reverse proxy situation, where the backend generates
          URLs that are not valid for the proxy's clients.</dd>
    
          <dt><code class="module"><a href="./mod/mod_sed.html">mod_sed</a></code></dt>
          <dd>An advanced replacement of <code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code>, allows
          to edit the response body with the full power of sed.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_form.html">mod_auth_form</a></code></dt>
          <dd>Enables form-based authentication.</dd>
    
          <dt><code class="module"><a href="./mod/mod_session.html">mod_session</a></code></dt>
          <dd>Enables the use of session state for clients, using cookie or
          database storage.</dd>
    
          <dt><code class="module"><a href="./mod/mod_allowmethods.html">mod_allowmethods</a></code></dt>
          <dd>New module to restrict certain HTTP methods without interfering with
          authentication or authorization.</dd>
    
          <dt><code class="module"><a href="./mod/mod_lua.html">mod_lua</a></code></dt>
          <dd>Embeds the <a href="http://www.lua.org/">Lua</a> language into httpd,
          for configuration and small business logic functions. (Experimental)</dd>
    
          <dt><code class="module"><a href="./mod/mod_log_debug.html">mod_log_debug</a></code></dt>
          <dd>Allows the addition of customizable debug logging at different phases of the
          request processing.</dd>
    
          <dt><code class="module"><a href="./mod/mod_buffer.html">mod_buffer</a></code></dt>
          <dd>Provides for buffering the input and output filter stacks</dd>
    
          <dt><code class="module"><a href="./mod/mod_data.html">mod_data</a></code></dt>
          <dd>Convert response body into an RFC2397 data URL</dd>
    
          <dt><code class="module"><a href="./mod/mod_ratelimit.html">mod_ratelimit</a></code></dt>
          <dd>Provides Bandwidth Rate Limiting for Clients</dd>
    
          <dt><code class="module"><a href="./mod/mod_request.html">mod_request</a></code></dt>
          <dd>Provides Filters to handle and make available HTTP request bodies</dd>
    
          <dt><code class="module"><a href="./mod/mod_reflector.html">mod_reflector</a></code></dt>
          <dd>Provides Reflection of a request body as a response via the output filter stack.</dd>
    
          <dt><code class="module"><a href="./mod/mod_slotmem_shm.html">mod_slotmem_shm</a></code></dt>
          <dd>Provides a Slot-based shared memory provider (ala the scoreboard).</dd>
    
          <dt><code class="module"><a href="./mod/mod_xml2enc.html">mod_xml2enc</a></code></dt>
          <dd>Formerly a third-party module, this supports internationalisation
          in libxml2-based (markup-aware) filter modules.</dd>
    
          <dt><code class="module"><a href="./mod/mod_macro.html">mod_macro</a></code> (available since 2.4.5)</dt>
          <dd>Provide macros within configuration files.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_wstunnel.html">mod_proxy_wstunnel</a></code> (available since 2.4.5)</dt>
          <dd>Support web-socket tunnels.</dd>
    
          <dt><code class="module"><a href="./mod/mod_authnz_fcgi.html">mod_authnz_fcgi</a></code> (available since 2.4.10)</dt>
          <dd>Enable FastCGI authorizer applications to authenticate and/or
          authorize clients.</dd>
    
          <dt><code class="module"><a href="./mod/mod_http2.html">mod_http2</a></code> (available since 2.4.17)</dt>
          <dd>Support for the HTTP/2 transport layer.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_http2.html">mod_proxy_http2</a></code> (available since 2.4.19)</dt>
          <dd>HTTP/2 Protocol backend for <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_hcheck.html">mod_proxy_hcheck</a></code> (available since 2.4.21)</dt>
          <dd>Support independent dynamic health checks for remote proxiy backend servers.</dd>
    
          <dt><code class="module"><a href="./mod/mod_brotli.html">mod_brotli</a></code> (available since 2.4.26)</dt>
          <dd>Support the Brotli compression algorithm.</dd>
    
          <dt><code class="module"><a href="./mod/mod_md.html">mod_md</a></code> (available since 2.4.30)</dt>
          <dd>Support the ACME protocol to automate certificate provisionning.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_uwsgi.html">mod_proxy_uwsgi</a></code> (available since 2.4.30)</dt>
          <dd>UWSGI gateway module for <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_socache_redis.html">mod_socache_redis</a></code> (available since 2.4.39)</dt>
          <dd>Support <a href="http://redis.io/">Redis</a> based shared object cache provider.</dd>
    
          <dt><code class="module"><a href="./mod/mod_systemd.html">mod_systemd</a></code> (available since 2.4.42)</dt>
          <dd>systemd integration. It allows httpd to be used in a service with the systemd
          <code>Type=notify</code>.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Module Enhancements</a></h2>
        
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> can now be configured to use an
          OCSP server to check the validation status of a client
          certificate.  The default responder is configurable, along with
          the decision on whether to prefer the responder designated in
          the client certificate itself.</dd>
    
          <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> now also supports OCSP stapling, where the
          server pro-actively obtains an OCSP verification of its certificate and
          transmits that to the client during the handshake. </dd>
    
          <dd><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> can now be configured to share SSL Session
          data between servers through memcached</dd>
    
          <dd>EC keys are now supported in addition to RSA and DSA.</dd>
    
          <dd>Support for TLS-SRP (available in 2.4.4 and later).</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd>The <code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> directive
          is now most optimally configured within a
          <code class="directive"><a href="./mod/core.html#location">Location</a></code> or
          <code class="directive"><a href="./mod/core.html#locationmatch">LocationMatch</a></code>
          block, and offers a significant performance advantage over the traditional
          two-parameter syntax when present in large numbers.</dd>
          <dd>The source address used for proxy requests is now configurable.</dd>
          <dd>Support for Unix domain sockets to the backend (available in 2.4.7
          and later).</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code></dt>
    
          <dd>More runtime configuration changes for BalancerMembers via balancer-manager</dd>
    
          <dd>Additional BalancerMembers can be added at runtime via balancer-manager</dd>
    
          <dd>Runtime configuration of a subset of Balancer parameters</dd>
    
          <dd>BalancerMembers can be set to 'Drain' so that they only respond to existing sticky
          sessions, allowing them to be taken gracefully offline.</dd>
    
          <dd>Balancer settings can be persistent after restarts.</dd>
    
          <dt><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code></dt>
    
          <dd>The <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> CACHE filter can be optionally inserted
          at a given point in the filter chain to provide fine control over caching.
          </dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> can now cache HEAD requests.</dd>
    
          <dd>Where possible, <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> directives can now be set
          per directory, instead of per server.</dd>
    
          <dd>The base URL of cached URLs can be customised, so that a cluster of
          caches can share the same endpoint URL prefix.</dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> is now capable of serving stale cached
          data when a backend is unavailable (error 5xx).</dd>
    
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> can now insert HIT/MISS/REVALIDATE into
          an X-Cache header.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
          <dd>Support for the 'onerror' attribute within an 'include' element,
          allowing an error document to be served on error instead of the default
          error string.</dd>
    
          <dt><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>, <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>,
              <code class="module"><a href="./mod/mod_isapi.html">mod_isapi</a></code>, ...</dt>
          <dd>Translation of headers to environment variables is more strict than
          before to mitigate some possible cross-site-scripting attacks via header
          injection. Header names containing invalid characters (including underscores)
          are no longer converted to environment variables. <a href="env.html">Environment Variables
          in Apache</a> has some pointers on how to work around broken legacy
          clients which require such headers. (This affects all modules which
          use these environment variables.)</dd>
    
          <dt><code class="module"><a href="./mod/mod_authz_core.html">mod_authz_core</a></code> Authorization Logic Containers</dt>
    
          <dd>Advanced authorization logic may now be specified using the
              <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code> directive
              and the related container directives, such as
              <code class="directive"><a href="./mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> adds the <code>[QSD]</code>
              (Query String Discard) and <code>[END]</code> flags for
              <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to
              simplify common rewriting scenarios.</dd>
          <dd>Adds the possibility to use complex boolean expressions in <code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>.</dd>
          <dd>Allows the use of SQL queries as <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> functions.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>, <code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> adds support for nested groups.</dd>
          <dd><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> adds
              <code class="directive"><a href="./mod/mod_ldap.html#ldapconnectionpoolttl">LDAPConnectionPoolTTL</a></code>,
              <code class="directive"><a href="./mod/mod_ldap.html#ldaptimeout">LDAPTimeout</a></code>, and
              other improvements in the handling of timeouts.
              This is especially useful for setups where a
              stateful firewall drops idle connections to the LDAP server.</dd>
          <dd><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> adds
              <code class="directive"><a href="./mod/mod_ldap.html#ldaplibrarydebug">LDAPLibraryDebug</a></code> to log
              debug information provided by the used LDAP toolkit.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd><code class="module"><a href="./mod/mod_info.html">mod_info</a></code> can now dump the pre-parsed configuration
              to stdout during server startup.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_basic.html">mod_auth_basic</a></code></dt>
          <dd>New generic mechanism to fake basic authentication (available in
          2.4.5 and later).</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programs" id="programs">Program Enhancements</a></h2>
        
        <dl>
            <dt><code class="program"><a href="./programs/fcgistarter.html">fcgistarter</a></code></dt>
            <dd>New FastCGI daemon starter utility</dd>
    
            <dt><code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code></dt>
            <dd>Current cached URLs can now be listed, with optional metadata
            included.</dd>
            <dd>Allow explicit deletion of individual cached URLs from the
            cache.</dd>
            <dd>File sizes can now be rounded up to the given block size, making
            the size limits map more closely to the real size on disk.</dd>
            <dd>Cache size can now be limited by the number of inodes, instead
            of or in addition to being limited by the size of the files on
            disk.</dd>
    
            <dt><code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code></dt>
            <dd>May now create a link to the current log file.</dd>
            <dd>May now invoke a custom post-rotate script.</dd>
    
            <dt><code class="program"><a href="./programs/htpasswd.html">htpasswd</a></code>, <code class="program"><a href="./programs/htdbm.html">htdbm</a></code></dt>
            <dd>Support for the bcrypt algorithm (available in 2.4.4 and later).
            </dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentation" id="documentation">Documentation</a></h2>
        
        <dl>
            <dt>mod_rewrite</dt>
            <dd>The <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> documentation has been
            rearranged and almost completely rewritten, with a focus on
            examples and common usage, as well as on showing you when other
            solutions are more appropriate. The <a href="rewrite/">Rewrite
            Guide</a> is now a top-level section with much more detail and
            better organization.</dd>
    
            <dt>mod_ssl</dt>
            <dd>The <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> documentation has been greatly
            enhanced, with more examples at the getting started level, in
            addition to the previous focus on technical details.</dd>
    
            <dt>Caching Guide</dt>
            <dd>The <a href="caching.html">Caching Guide</a> has been rewritten
            to properly distinguish between the RFC2616 HTTP/1.1 caching
            features provided by <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, and the generic
            key/value caching provided by the <a href="socache.html">socache</a>
            interface, as well as to cover specialised caching provided by
            mechanisms such as <code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code>.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer">Module Developer Changes</a></h2>
        
        <dl>
          <dt>Check Configuration Hook Added</dt>
    
          <dd>A new hook, <code>check_config</code>, has been added which runs
              between the <code>pre_config</code> and <code>open_logs</code>
              hooks.  It also runs before the <code>test_config</code> hook
              when the <code>-t</code> option is passed to
              <code class="program"><a href="./programs/httpd.html">httpd</a></code>.  The <code>check_config</code> hook
              allows modules to review interdependent configuration directive
              values and adjust them while messages can still be logged to the
              console.  The user can thus be alerted to misconfiguration problems
              before the core <code>open_logs</code> hook function redirects
              console output to the error log.</dd>
    
          <dt>Expression Parser Added</dt>
    
          <dd>We now have a general-purpose expression parser, whose API is
              exposed in <var>ap_expr.h</var>.  This is adapted from the
              expression parser previously implemented in
              <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>.</dd>
    
          <dt>Authorization Logic Containers</dt>
    
          <dd>Authorization modules now register as a provider, via
          ap_register_auth_provider(), to support advanced authorization logic,
          such as <code class="directive"><a href="./mod/mod_authz_core.html#requireall">&lt;RequireAll&gt;</a></code>.</dd>
    
          <dt>Small-Object Caching Interface</dt>
    
          <dd>The <var>ap_socache.h</var> header exposes a provider-based
          interface for caching small data objects, based on the previous
          implementation of the <code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code> session cache.
          Providers using a shared-memory cyclic buffer, disk-based dbm
          files, and a memcache distributed cache are currently
          supported.</dd>
    
          <dt>Cache Status Hook Added</dt>
    
          <dd>The <code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code> module now includes a new
          <code>cache_status</code> hook, which is called when the caching
          decision becomes known. A default implementation is provided
          which adds an optional <code>X-Cache</code> and
          <code>X-Cache-Detail</code> header to the response.</dd>
        </dl>
    
        <p>The developer documentation contains a
        <a href="developer/new_api_2_4.html">detailed list of API changes</a>.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/new_features_2_4.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_4.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./tr/new_features_2_4.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_4.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/stopping.html.en�����������������������������������������������������������0000664�0001751�0001751�00000042625�14737241666�020212� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Stopping and Restarting Apache HTTP Server - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Stopping and Restarting Apache HTTP Server</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>This document covers stopping and restarting Apache HTTP Server on
        Unix-like systems. Windows NT, 2000 and XP users should see
        <a href="platform/windows.html#winsvc">Running httpd as a
        Service</a> and Windows 9x and ME users should see <a href="platform/windows.html#wincons">Running httpd as a
        Console Application</a> for information on how to control
        httpd on those platforms.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#introduction">Introduction</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#term">Stop Now</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#graceful">Graceful Restart</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#hup">Restart Now</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#gracefulstop">Graceful Stop</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="invoking.html">Starting</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="introduction" id="introduction">Introduction</a></h2>
    
        <p>In order to stop or restart the Apache HTTP Server, you must send a signal to
        the running <code class="program"><a href="./programs/httpd.html">httpd</a></code> processes.  There are two ways to
        send the signals.  First, you can use the unix <code>kill</code>
        command to directly send signals to the processes. You will
        notice many <code class="program"><a href="./programs/httpd.html">httpd</a></code> executables running on your system,
        but you should not send signals to any of them except the parent,
        whose pid is in the <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code>. That is to say you
        shouldn't ever need to send signals to any process except the
        parent. There are four signals that you can send the parent:
        <code><a href="#term">TERM</a></code>,
        <code><a href="#graceful">USR1</a></code>,
        <code><a href="#hup">HUP</a></code>, and
        <code><a href="#gracefulstop">WINCH</a></code>, which
        will be described in a moment.</p>
    
        <p>To send a signal to the parent you should issue a command
        such as:</p>
    
    <div class="example"><p><code>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</code></p></div>
    
        <p>The second method of signaling the <code class="program"><a href="./programs/httpd.html">httpd</a></code> processes
        is to use the <code>-k</code> command line options: <code>stop</code>,
        <code>restart</code>, <code>graceful</code> and <code>graceful-stop</code>,
        as described below.  These are arguments to the <code class="program"><a href="./programs/httpd.html">httpd</a></code> binary, but we recommend that
        you send them using the <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> control script, which
        will pass them through to <code class="program"><a href="./programs/httpd.html">httpd</a></code>.</p>
    
        <p>After you have signaled <code class="program"><a href="./programs/httpd.html">httpd</a></code>, you can read about
        its progress by issuing:</p>
    
    <div class="example"><p><code>tail -f /usr/local/apache2/logs/error_log</code></p></div>
    
        <p>Modify those examples to match your <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code> and <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> settings.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="term" id="term">Stop Now</a></h2>
    
    <dl><dt>Signal: TERM</dt>
    <dd><code>apachectl -k stop</code></dd>
    </dl>
    
        <p>Sending the <code>TERM</code> or <code>stop</code> 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.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="graceful" id="graceful">Graceful Restart</a></h2>
    
    <dl><dt>Signal: USR1</dt>
    <dd><code>apachectl -k graceful</code></dd>
    </dl>
    
        <p>The <code>USR1</code> or <code>graceful</code> signal causes
        the parent process to <em>advise</em> 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 <em>generation</em> of the
        configuration, which begins serving new requests immediately.</p>
    
        <p>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
        <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> in the
        following manner: if after one second at least <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code> 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
        <code class="directive"><a href="./mod/mpm_common.html#startservers">StartServers</a></code>
        parameter.</p>
    
        <p>Users of <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>
        will notice that the server statistics are <strong>not</strong>
        set to zero when a <code>USR1</code> 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
        <em>scoreboard</em> used to keep track of all children across
        generations.</p>
    
        <p>The status module will also use a <code>G</code> to indicate
        those children which are still serving requests started before
        the graceful restart was given.</p>
    
        <p>At present there is no way for a log rotation script using
        <code>USR1</code> 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 <code>USR1</code> 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.</p>
    
        <div class="note">
        <p>When you issue a restart, a syntax check is first run, to
        ensure that there are no errors in the configuration files.
        If your configuration file has errors in it, you will get an
        error message about that syntax error, and the server will refuse to
        restart. This avoids the situation where the server halts and then
        cannot restart, leaving you with a non-functioning server.</p>
    
        <p>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 <code class="program"><a href="./programs/httpd.html">httpd</a></code> 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
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> 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.</p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="hup" id="hup">Restart Now</a></h2>
    
    <dl><dt>Signal: HUP</dt>
    <dd><code>apachectl -k restart</code></dd>
    </dl>
    
        <p>Sending the <code>HUP</code> or <code>restart</code> signal to
        the parent causes it to kill off its children like in
        <code>TERM</code>, 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.</p>
    
        <p>Users of <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>
        will notice that the server statistics are set to zero when a
        <code>HUP</code> is sent.</p>
    
    <div class="note">As with a graceful restart, a syntax check is run before the
    restart is attempted. If your configuration file has errors in it, the
    restart will not be attempted, and you will receive notification of the
    syntax error(s).</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="gracefulstop" id="gracefulstop">Graceful Stop</a></h2>
    
    <dl><dt>Signal: WINCH</dt>
    <dd><code>apachectl -k graceful-stop</code></dd>
    </dl>
    
        <p>The <code>WINCH</code> or <code>graceful-stop</code> signal causes
        the parent process to <em>advise</em> the children to exit after
        their current request (or to exit immediately if they're not
        serving anything). The parent will then remove its <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> and cease listening on
        all ports. The parent will continue to run, and monitor children
        which are handling requests. Once all children have finalised
        and exited or the timeout specified by the <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code> has been
        reached, the parent will also exit.  If the timeout is reached,
        any remaining children will be sent the <code>TERM</code> signal
        to force them to exit.</p>
    
        <p>A <code>TERM</code> signal will immediately terminate the
        parent process and all children when in the "graceful" state. However
        as the <code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code> will
        have been removed, you will not be able to use
        <code>apachectl</code> or <code>httpd</code> to send this signal.</p>
    
        <div class="note"><p>The <code>graceful-stop</code> signal allows you to run multiple
        identically configured instances of <code class="program"><a href="./programs/httpd.html">httpd</a></code> at the
        same time. This is a powerful feature when performing graceful
        upgrades of httpd, however it can also cause deadlocks and race
        conditions with some configurations.</p>
    
        <p>Care has been taken to ensure that on-disk files such as lock files
        (<code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>) and Unix socket files
        (<code class="directive"><a href="./mod/mod_cgid.html#scriptsock">ScriptSock</a></code>) contain the server
        PID, and should coexist without problem. However, if a configuration
        directive, third-party module or persistent CGI utilises any other on-disk
        lock or  state files, care should be taken to ensure that multiple running
        instances of <code class="program"><a href="./programs/httpd.html">httpd</a></code> do not clobber each other's files.</p>
    
        <p>You should also be wary of other potential race conditions, such as
        using <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> style piped logging. Multiple running
        instances of <code class="program"><a href="./programs/rotatelogs.html">rotatelogs</a></code> attempting to rotate the same
        logfiles at the same time may destroy each other's logfiles.</p></div>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/stopping.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/stopping.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/stopping.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/stopping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/stopping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/stopping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/stopping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/stopping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>�����������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html.en������������������������������������������������������������0000664�0001751�0001751�00000027444�14737241666�017766� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Apache's Handler Use - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Apache's Handler Use</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/handler.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div>
    
        <p>This document describes the use of Apache's Handlers.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#definition">What is a Handler</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#examples">Examples</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programmer">Programmer's Note</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="definition" id="definition">What is a Handler</a></h2>
        
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code></li><li><code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></li><li><code class="module"><a href="./mod/mod_mime.html">mod_mime</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#addhandler">AddHandler</a></code></li><li><code class="directive"><a href="./mod/mod_mime.html#removehandler">RemoveHandler</a></code></li><li><code class="directive"><a href="./mod/core.html#sethandler">SetHandler</a></code></li></ul></td></tr></table>
    
    
        <p>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.</p>
    
        <p>Handlers may also be configured explicitly,
        based on either filename extensions or on location,
        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 <strong>and</strong> a
        handler to be associated with a file. (See also <a href="mod/mod_mime.html#multipleext">Files with Multiple
        Extensions</a>.)</p>
    
        <p>Handlers can either be built into the server or included in
        a module, or they can be added with the <code class="directive"><a href="./mod/mod_actions.html#action">Action</a></code> directive. The
        built-in handlers in the standard distribution are as
        follows:</p>
    
        <ul>
          <li><strong>default-handler</strong>: Send the file using the
          <code>default_handler()</code>, which is the handler used by
          default to handle static content. (core)</li>
    
          <li><strong>send-as-is</strong>: Send file with HTTP headers
          as is. (<code class="module"><a href="./mod/mod_asis.html">mod_asis</a></code>)</li>
    
          <li><strong>cgi-script</strong>: Treat the file as a CGI
          script. (<code class="module"><a href="./mod/mod_cgi.html">mod_cgi</a></code>)</li>
    
          <li><strong>imap-file</strong>: Parse as an imagemap rule
          file. (<code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code>)</li>
    
          <li><strong>server-info</strong>: Get the server's
          configuration information. (<code class="module"><a href="./mod/mod_info.html">mod_info</a></code>)</li>
    
          <li><strong>server-status</strong>: Get the server's status
          report. (<code class="module"><a href="./mod/mod_status.html">mod_status</a></code>)</li>
    
          <li><strong>type-map</strong>: Parse as a type map file for
          content negotiation. (<code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>)</li>
        </ul>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="examples" id="examples">Examples</a></h2>
        
    
        <h3><a name="example1" id="example1">Modifying static content using a CGI script</a></h3>
          
    
          <p>The following directives will cause requests for files with
          the <code>html</code> extension to trigger the launch of the
          <code>footer.pl</code> CGI script.</p>
    
          <pre class="prettyprint lang-config">Action add-footer /cgi-bin/footer.pl
    AddHandler add-footer .html</pre>
    
    
          <p>Then the CGI script is responsible for sending the
          originally requested document (pointed to by the
          <code>PATH_TRANSLATED</code> environment variable) and making
          whatever modifications or additions are desired.</p>
    
        
        <h3><a name="example2" id="example2">Files with HTTP headers</a></h3>
          
    
          <p>The following directives will enable the
          <code>send-as-is</code> handler, which is used for files which
          contain their own HTTP headers. All files in the
          <code>/web/htdocs/asis/</code> directory will be processed by
          the <code>send-as-is</code> handler, regardless of their
          filename extensions.</p>
    
          <pre class="prettyprint lang-config">&lt;Directory "/web/htdocs/asis"&gt;
        SetHandler send-as-is
    &lt;/Directory&gt;</pre>
    
    
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programmer" id="programmer">Programmer's Note</a></h2>
        
    
        <p>In order to implement the handler features, an addition has
        been made to the <a href="developer/API.html">Apache API</a> that
        you may wish to make use of. Specifically, a new record has
        been added to the <code>request_rec</code> structure:</p>
    
        <pre class="prettyprint lang-c">char *handler</pre>
    
    
        <p>If you wish to have your module engage a handler, you need
        only to set <code>r-&gt;handler</code> to the name of the
        handler at any time prior to the <code>invoke_handler</code>
        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.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/handler.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/handler.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/handler.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/handler.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/handler.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/handler.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a> |
    <a href="./zh-cn/handler.html" hreflang="zh-cn" rel="alternate" title="Simplified Chinese">&nbsp;zh-cn&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/handler.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/license.html.en������������������������������������������������������������0000664�0001751�0001751�00000036764�14737241666�020000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>The Apache License, Version 2.0 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>The Apache License, Version 2.0</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/license.html" title="English">&nbsp;en&nbsp;</a></p>
    </div>
    
        <p class="centered">Apache License<br />
        Version 2.0, January 2004<br />
        <a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a><br /><br />
    
        TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION</p>
    
        <ol>
        <li><strong>Definitions</strong><br />
    
        <p>"License" shall mean the terms and conditions for use, reproduction,
        and distribution as defined by Sections 1 through 9 of this document.</p>
    
        <p>"Licensor" shall mean the copyright owner or entity authorized by
        the copyright owner that is granting the License.</p>
    
        <p>"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.</p>
    
        <p>"You" (or "Your") shall mean an individual or Legal Entity
        exercising permissions granted by this License.</p>
    
        <p>"Source" form shall mean the preferred form for making modifications,
        including but not limited to software source code, documentation
        source, and configuration files.</p>
    
        <p>"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.</p>
    
        <p>"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).</p>
    
        <p>"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.</p>
    
        <p>"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."</p>
    
        <p>"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.</p></li>
    
        <li><strong>Grant of Copyright License.</strong> 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.</li>
    
        <li><strong>Grant of Patent License.</strong> 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.</li>
    
        <li><strong>Redistribution.</strong> 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:
    
        <ol class="lo-A">
            <li>You must give any other recipients of the Work or
            Derivative Works a copy of this License; and</li>
    
            <li>You must cause any modified files to carry prominent notices
            stating that You changed the files; and</li>
    
            <li>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</li>
    
            <li>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.</li>
        </ol>
    
        <p>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.</p></li>
    
        <li><strong>Submission of Contributions.</strong> 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.</li>
    
        <li><strong>Trademarks.</strong> 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.</li>
    
        <li><strong>Disclaimer of Warranty.</strong> 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.</li>
    
        <li><strong>Limitation of Liability.</strong> 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.</li>
    
        <li><strong>Accepting Warranty or Additional Liability.</strong> 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.</li>
        </ol>
    
        <p class="centered">END OF TERMS AND CONDITIONS</p>
    
        <p class="centered">APPENDIX: How to apply the Apache License to your
        work.</p>
    
        <p>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.</p>
    
        <div class="example"><pre>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.</pre></div>
    </div>
    </div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/license.html" title="English">&nbsp;en&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/license.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������httpd-2.4.64/docs/manual/new_features_2_2.html.en���������������������������������������������������0000664�0001751�0001751�00000045120�14737241666�021471� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Overview of new features in Apache HTTP Server 2.2 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Overview of new features in Apache HTTP Server 2.2</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/new_features_2_2.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>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 <a href="new_features_2_0.html">2.0 new features</a>
         document.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Core Enhancements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Module Enhancements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#programs">Program Enhancements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#developer">Module Developer Changes</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Core Enhancements</a></h2>
        
        <dl>
    
          <dt>Authn/Authz</dt>
          <dd>The bundled authentication and authorization modules have
              been refactored.  The new mod_authn_alias(already removed from 2.3/2.4)
              module can greatly simplify certain authentication configurations.
              See <a href="#module">module name changes</a>, and
              <a href="#developer">the developer changes</a> for more
              information about how these changes affects users and module
              writers.</dd>
    
          <dt>Caching</dt>
          <dd><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>, <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>, and
              mod_mem_cache(already removed from 2.3/2.4) have undergone a lot of changes, and
              are now considered production-quality. <code class="program"><a href="./programs/htcacheclean.html">htcacheclean</a></code>
              has been introduced to clean up <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code>
              setups.</dd>
    
          <dt>Configuration</dt>
          <dd>The default configuration layout has been simplified and
              modularised. Configuration snippets which can be used to
              enable commonly-used features are now bundled with Apache, and
              can be easily added to the main server config.</dd>
    
          <dt>Graceful stop</dt>
          <dd>The <code class="module"><a href="./mod/prefork.html">prefork</a></code>, <code class="module"><a href="./mod/worker.html">worker</a></code> and
              <code class="module"><a href="./mod/event.html">event</a></code>  MPMs now allow <code class="program"><a href="./programs/httpd.html">httpd</a></code>
              to be shutdown gracefully via the
              <a href="stopping.html#gracefulstop"><code>graceful-stop</code></a>
              signal. The <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code> directive
              has been added to specify an optional timeout, after which
              <code class="program"><a href="./programs/httpd.html">httpd</a></code> will terminate regardless of the status
              of any requests being served.</dd>
    
          <dt>Proxying</dt>
          <dd>The new <code class="module"><a href="./mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> module provides
              load balancing services for <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>.
              The new <code class="module"><a href="./mod/mod_proxy_ajp.html">mod_proxy_ajp</a></code> module adds support for the
              <code>Apache JServ Protocol version 1.3</code> used by
              <a href="http://tomcat.apache.org/">Apache Tomcat</a>.</dd>
    
          <dt>Regular Expression Library Updated</dt>
          <dd>Version 5.0 of the
              <a href="http://www.pcre.org/">Perl Compatible Regular Expression
              Library</a> (PCRE) is now included.  <code class="program"><a href="./programs/httpd.html">httpd</a></code> can be
              configured to use a system installation of PCRE by passing the
              <code>--with-pcre</code> flag to configure.</dd>
    
          <dt>Smart Filtering</dt>
          <dd><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code> 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.</dd>
    
          <dt>Large File Support</dt>
          <dd><code class="program"><a href="./programs/httpd.html">httpd</a></code> is now built with support for files larger
              than 2GB on modern 32-bit Unix systems.  Support for handling
              &gt;2GB request bodies has also been added.</dd>
    
          <dt>Event MPM</dt>
          <dd>The <code class="module"><a href="./mod/event.html">event</a></code> MPM uses a separate 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.</dd>
    
          <dt>SQL Database Support</dt>
          <dd><code class="module"><a href="./mod/mod_dbd.html">mod_dbd</a></code>, together with the <code>apr_dbd</code>
              framework, brings direct SQL support to modules that need it.
              Supports connection pooling in threaded MPMs.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Module Enhancements</a></h2>
        
        <dl>
          <dt>Authn/Authz</dt>
          <dd>Modules in the aaa directory have been renamed and offer
              better support for digest authentication.  For example,
              <code>mod_auth</code> is now split into
              <code class="module"><a href="./mod/mod_auth_basic.html">mod_auth_basic</a></code> and
              <code class="module"><a href="./mod/mod_authn_file.html">mod_authn_file</a></code>; <code>mod_auth_dbm</code> is now
              called <code class="module"><a href="./mod/mod_authn_dbm.html">mod_authn_dbm</a></code>; <code>mod_access</code> has
              been renamed <code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code>.  There is also a new
              mod_authn_alias(already removed from 2.3/2.4) module for simplifying
              certain authentication configurations.
          </dd>
    
          <dt><code class="module"><a href="./mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code></dt>
          <dd>This module is a port of the 2.0
              <code>mod_auth_ldap</code> module to the 2.2 <code>Authn/Authz</code>
              framework.  New features include using LDAP attribute values and
              complicated search filters in the
              <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code> directive.</dd>
    
          <dt><code class="module"><a href="./mod/mod_authz_owner.html">mod_authz_owner</a></code></dt>
          <dd>A new module that authorizes access to files based
              on the owner of the file on the file system</dd>
    
          <dt><code class="module"><a href="./mod/mod_version.html">mod_version</a></code></dt>
          <dd>A new module that allows configuration blocks to be enabled based on the
              version number of the running server.</dd>
    
          <dt><code class="module"><a href="./mod/mod_info.html">mod_info</a></code></dt>
          <dd>Added a new <code>?config</code> 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 <code>httpd -V</code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
          
          <dd>Added a support for
             <a href="http://www.ietf.org/rfc/rfc2817.txt">RFC 2817</a>, which
             allows connections to upgrade from clear text to TLS encryption.</dd>
    
          <dt><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></dt>
          <dd><code>mod_imap</code> has been renamed to
              <code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code> to avoid user confusion.</dd>
        </dl>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="programs" id="programs">Program Enhancements</a></h2>
        
        <dl>
          <dt><code class="program"><a href="./programs/httpd.html">httpd</a></code></dt>
          <dd>A new command line option <code>-M</code> has been added that
          lists all modules that are loaded based on the current
          configuration. Unlike the <code>-l</code> option, this list
          includes DSOs loaded via <code class="module"><a href="./mod/mod_so.html">mod_so</a></code>.</dd>
    
          <dt><code class="program"><a href="./programs/httxt2dbm.html">httxt2dbm</a></code></dt>
          <dd>A new program used to generate dbm files from text input,
              for use in <code class="directive"><a href="./mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
              with the <code>dbm</code> map type.</dd>
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="developer" id="developer">Module Developer Changes</a></h2>
        
        <dl>
          <dt><a class="glossarylink" href="./glossary.html#apr" title="see glossary">APR</a> 1.0 API</dt>
    
          <dd>Apache 2.2 uses the APR 1.0 API.  All deprecated functions and
              symbols have been removed from <code>APR</code> and
              <code>APR-Util</code>. For details, see the
              <a href="http://apr.apache.org/">APR Website</a>.</dd>
    
          <dt>Authn/Authz</dt>
          <dd>The bundled authentication and authorization modules have
              been renamed along the following lines:
              <ul>
              <li><code>mod_auth_*</code>  -&gt; Modules that implement an HTTP
              authentication mechanism</li>
              <li><code>mod_authn_*</code> -&gt; Modules that provide a backend
              authentication provider</li>
              <li><code>mod_authz_*</code> -&gt; Modules that implement
              authorization (or access)</li>
              <li><code>mod_authnz_*</code> -&gt; Module that implements both
              authentication &amp; authorization</li>
              </ul>
              There is a new authentication backend provider
              scheme which greatly eases the construction of new authentication
              backends.</dd>
    
          <dt>Connection Error Logging</dt>
    
          <dd>A new function, <code>ap_log_cerror</code> has been added to log
              errors that occur with the client's connection.  When logged,
              the message includes the client IP address.</dd>
    
          <dt>Test Configuration Hook Added</dt>
    
          <dd>A new hook, <code>test_config</code> has been added to aid
              modules that want to execute special code only when the user passes
              <code>-t</code> to <code class="program"><a href="./programs/httpd.html">httpd</a></code>.</dd>
    
          <dt>Set Threaded MPM's Stacksize</dt>
    
          <dd>A new directive, <code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code> 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.</dd>
    
          <dt>Protocol handling for output filters</dt>
    
          <dd>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
              <code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>, using the
              <code>ap_register_output_filter_protocol</code> or
              <code>ap_filter_protocol</code> calls.</dd>
    
          <dt>Monitor hook added</dt>
          <dd>Monitor hook enables modules to run regular/scheduled jobs
              in the parent (root) process.</dd>
    
          <dt>Regular expression API changes</dt>
    
          <dd>The <code>pcreposix.h</code> header is no longer available;
          it is replaced by the new <code>ap_regex.h</code> header.  The
          POSIX.2 <code>regex.h</code> implementation exposed by the old
          header is now available under the <code>ap_</code> namespace
          from <code>ap_regex.h</code>.  Calls to <code>regcomp</code>,
          <code>regexec</code> and so on can be replaced by calls to
          <code>ap_regcomp</code>, <code>ap_regexec</code>.</dd>
    
          <dt>DBD Framework (SQL Database API)</dt>
    
          <dd><p>With Apache 1.x and 2.0, modules requiring an SQL backend
          had to take responsibility for managing it themselves.  Apart
          from reinventing the wheel, this can be very inefficient, for
          example when several modules each maintain their own connections.</p>
    
          <p>Apache 2.1 and later provides the <code>ap_dbd</code> API for
          managing database connections (including optimised strategies
          for threaded and unthreaded MPMs), while APR 1.2 and later provides
          the <code>apr_dbd</code> API for interacting with the database.</p>
    
          <p>New modules SHOULD now use these APIs for all SQL database
          operations.  Existing applications SHOULD be upgraded to use it
          where feasible, either transparently or as a recommended option
          to their users.</p></dd>
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/new_features_2_2.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_2.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ko/new_features_2_2.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_2.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_2.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_2.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/socache.html.en������������������������������������������������������������0000664�0001751�0001751�00000023046�14737241666�017750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Shared Object Cache in Apache HTTP Server - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page" class="no-sidebar"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Shared Object Cache in Apache HTTP Server</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/socache.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/socache.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
        <p>The Shared Object Cache provides a means to share simple data
        across all a server's workers, regardless of <a href="mpm.html">thread
        and process models</a>.  It is used where the advantages of sharing
        data across processes outweigh the performance overhead of
        inter-process communication.</p>
      </div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="providers" id="providers">Shared Object Cache Providers</a></h2>
        
        <p>The shared object cache as such is an abstraction.  Five different
        modules implement it.  To use the cache, one or more of these modules
        must be present, and configured.</p>
        <p>The only configuration required is to select which cache provider
        to use.  This is the responsibility of modules using the cache, and
        they enable selection using directives such as
        <code class="directive"><a href="./mod/mod_cache_socache.html#cachesocache">CacheSocache</a></code>,
        <code class="directive"><a href="./mod/mod_authn_socache.html#authncachesocache">AuthnCacheSOCache</a></code>,
        <code class="directive"><a href="./mod/mod_ssl.html#sslsessioncache">SSLSessionCache</a></code>, and
        <code class="directive"><a href="./mod/mod_ssl.html#sslstaplingcache">SSLStaplingCache</a></code>.</p>
        <p>Currently available providers are:</p>
        <dl>
        <dt>"dbm" (<code class="module"><a href="./mod/mod_socache_dbm.html">mod_socache_dbm</a></code>)</dt>
        <dd>This makes use of a DBM hash file.
         The choice of underlying DBM used may be configurable
         if the installed APR version supports multiple DBM implementations.</dd>
        <dt>"dc" (<code class="module"><a href="./mod/mod_socache_dc.html">mod_socache_dc</a></code>)</dt>
        <dd>This makes use of the <a href="http://distcache.sourceforge.net/">distcache</a>
        distributed session caching libraries.</dd>
        <dt>"memcache" (<code class="module"><a href="./mod/mod_socache_memcache.html">mod_socache_memcache</a></code>)</dt>
        <dd>This makes use of the <a href="http://memcached.org/">memcached</a>
        high-performance, distributed memory object caching system.</dd>
        <dt>"redis" (<code class="module"><a href="./mod/mod_socache_redis.html">mod_socache_redis</a></code>)</dt>
        <dd>This makes use of the <a href="http://redis.io/">Redis</a>
        high-performance, distributed memory object caching system.</dd>
        <dt>"shmcb" (<code class="module"><a href="./mod/mod_socache_shmcb.html">mod_socache_shmcb</a></code>)</dt>
        <dd>This makes use of a high-performance cyclic buffer inside a
         shared memory segment.</dd>
        </dl>
    
        <p>The API provides the following functions:</p>
    
        <dl>
          <dt>const char *create(ap_socache_instance_t **instance, const char *arg,
                              apr_pool_t *tmp, apr_pool_t *p);</dt>
          <dd>Create a session cache based on the given configuration string.
          The instance pointer returned in the instance parameter will be
          passed as the first argument to subsequent invocations.</dd>
    
          <dt>apr_status_t init(ap_socache_instance_t *instance, const char *cname,
                             const struct ap_socache_hints *hints,
                             server_rec *s, apr_pool_t *pool)</dt>
          <dd>Initialize the cache.  The cname must be of maximum length 16
          characters, and uniquely identifies the consumer of the cache
          within the server; using the module name is recommended, e.g.
          "mod_ssl-sess".  This string may be used within a filesystem
          path so use of only alphanumeric [a-z0-9_-] characters is
          recommended.  If hints is non-NULL, it gives a set of hints for
          the provider.  Return APR error code.</dd>
    
          <dt>void destroy(ap_socache_instance_t *instance, server_rec *s)</dt>
          <dd>Destroy a given cache instance object.</dd>
    
          <dt>apr_status_t store(ap_socache_instance_t *instance, server_rec *s,
                              const unsigned char *id, unsigned int idlen,
                              apr_time_t expiry,
                              unsigned char *data, unsigned int datalen,
                              apr_pool_t *pool)</dt>
          <dd>Store an object in a cache instance.</dd>
    
          <dt>apr_status_t retrieve(ap_socache_instance_t *instance, server_rec *s,
                                 const unsigned char *id, unsigned int idlen,
                                 unsigned char *data, unsigned int *datalen,
                                 apr_pool_t *pool)</dt>
          <dd>Retrieve a cached object.</dd>
    
          <dt>apr_status_t remove(ap_socache_instance_t *instance, server_rec *s,
                               const unsigned char *id, unsigned int idlen,
                               apr_pool_t *pool)</dt>
          <dd>Remove an object from the cache.</dd>
    
          <dt>void status(ap_socache_instance_t *instance, request_rec *r, int flags)</dt>
          <dd>Dump the status of a cache instance for mod_status.</dd>
    
          <dt>apr_status_t iterate(ap_socache_instance_t *instance, server_rec *s,
                                void *userctx, ap_socache_iterator_t *iterator,
                                apr_pool_t *pool)</dt>
          <dd>Dump all cached objects through an iterator callback.</dd>
        </dl>
    
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/socache.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/socache.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/socache.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/urlmapping.html.en���������������������������������������������������������0000664�0001751�0001751�00000064022�14737241666�020520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Mapping URLs to Filesystem Locations - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Mapping URLs to Filesystem Locations</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/urlmapping.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>This document explains how the Apache HTTP Server uses the URL of a request
        to determine the filesystem location from which to serve a
        file.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#related">Related Modules and Directives</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#documentroot">DocumentRoot</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#outside">Files Outside the DocumentRoot</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#user">User Directories</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#redirect">URL Redirection</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Reverse Proxy</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#rewrite">Rewriting Engine</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#notfound">File Not Found</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#other">Other URL Mapping Modules</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="related" id="related">Related Modules and Directives</a></h2>
    
    <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code></li><li><code class="module"><a href="./mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></li><li><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code></li><li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code></li><li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code></li><li><code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code></li><li><code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_speling.html#checkspelling">CheckSpelling</a></code></li><li><code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="./mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code></li><li><code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code></li></ul></td></tr></table>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="documentroot" id="documentroot">DocumentRoot</a></h2>
    
        <p>In deciding what file to serve for a given request, httpd'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 <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> specified
        in your configuration files. Therefore, the files and directories
        underneath the <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        make up the basic document tree which will be visible from the
        web.</p>
    
        <p>For example, if <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>
        were set to <code>/var/www/html</code> then a request for
        <code>http://www.example.com/fish/guppies.html</code> would result
        in the file <code>/var/www/html/fish/guppies.html</code> being
        served to the requesting client.</p>
    
        <p>If a directory is requested (i.e. a path ending with
        <code>/</code>), the file served from that directory is defined by
        the <code class="directive"><a href="./mod/mod_dir.html#directoryindex">DirectoryIndex</a></code> directive.
        For example, if <code>DocumentRoot</code> were set as above, and 
        you were to set:</p>
    
        <div class="example"><p><code>DirectoryIndex index.html index.php</code></p></div>
    
        <p>Then a request for <code>http://www.example.com/fish/</code> will
        cause httpd to attempt to serve the file
        <code>/var/www/html/fish/index.html</code>. In the event that
        that file does not exist, it will next attempt to serve the file
        <code>/var/www/html/fish/index.php</code>.</p>
    
        <p>If neither of these files existed, the next step is to
        attempt to provide a directory index, if
        <code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code> is loaded and configured to permit
        that.</p>
    
        <p>httpd is also capable of <a href="vhosts/">Virtual
        Hosting</a>, where the server receives requests for more than one
        host. In this case, a different <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> can be specified for each
        virtual host, or alternatively, the directives provided by the
        module <code class="module"><a href="./mod/mod_vhost_alias.html">mod_vhost_alias</a></code> can
        be used to dynamically determine the appropriate place from which
        to serve content based on the requested IP address or
        hostname.</p>
    
        <p>The <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> directive
        is set in your main server configuration file
        (<code>httpd.conf</code>) and, possibly, once per additional <a href="vhosts/">Virtual Host</a> you create.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="outside" id="outside">Files Outside the DocumentRoot</a></h2>
    
        <p>There are frequently circumstances where it is necessary to
        allow web access to parts of the filesystem that are not strictly
        underneath the <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>. httpd offers several
        different ways to accomplish this. On Unix systems, symbolic links
        can bring other parts of the filesystem under the <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>. For security reasons,
        httpd will follow symbolic links only if the <code class="directive"><a href="./mod/core.html#options">Options</a></code> setting for the relevant
        directory includes <code>FollowSymLinks</code> or
        <code>SymLinksIfOwnerMatch</code>.</p>
    
        <p>Alternatively, the <code class="directive"><a href="./mod/mod_alias.html#alias">Alias</a></code> directive will map any part
        of the filesystem into the web space. For example, with</p>
    
    <pre class="prettyprint lang-config">Alias "/docs" "/var/web"</pre>
    
    
        <p>the URL <code>http://www.example.com/docs/dir/file.html</code>
        will be served from <code>/var/web/dir/file.html</code>. The
        <code class="directive"><a href="./mod/mod_alias.html#scriptalias">ScriptAlias</a></code> directive
        works the same way, with the additional effect that all content
        located at the target path is treated as <a class="glossarylink" href="./glossary.html#cgi" title="see glossary">CGI</a> scripts.</p>
    
        <p>For situations where you require additional flexibility, you
        can use the <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code>
        and <code class="directive"><a href="./mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code>
        directives to do powerful <a class="glossarylink" href="./glossary.html#regex" title="see glossary">regular
        expression</a> based matching and substitution. For
        example,</p>
    
        <pre class="prettyprint lang-config">ScriptAliasMatch "^/~([a-zA-Z0-9]+)/cgi-bin/(.+)"   "/home/$1/cgi-bin/$2"</pre>
    
    
        <p>will map a request to
        <code>http://example.com/~user/cgi-bin/script.cgi</code> to the
        path <code>/home/user/cgi-bin/script.cgi</code> and will treat
        the resulting file as a CGI script.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="user" id="user">User Directories</a></h2>
    
        <p>Traditionally on Unix systems, the home directory of a
        particular <em>user</em> can be referred to as
        <code>~user/</code>. The module <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code>
        extends this idea to the web by allowing files under each user's
        home directory to be accessed using URLs such as the
        following.</p>
    
    <div class="example"><p><code>http://www.example.com/~user/file.html</code></p></div>
    
        <p>For security reasons, it is inappropriate to give direct
        access to a user's home directory from the web. Therefore, the
        <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> directive
        specifies a directory underneath the user's home directory
        where web files are located. Using the default setting of
        <code>Userdir public_html</code>, the above URL maps to a file
        at a directory like
        <code>/home/user/public_html/file.html</code> where
        <code>/home/user/</code> is the user's home directory as
        specified in <code>/etc/passwd</code>.</p>
    
        <p>There are also several other forms of the
        <code>Userdir</code> directive which you can use on systems
        where <code>/etc/passwd</code> does not contain the location of
        the home directory.</p>
    
        <p>Some people find the "~" symbol (which is often encoded on the
        web as <code>%7e</code>) 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 <code class="directive"><a href="./mod/mod_alias.html#aliasmatch">AliasMatch</a></code>
        directive to achieve the desired effect. For example, to make
        <code>http://www.example.com/upages/user/file.html</code> map to
        <code>/home/user/public_html/file.html</code>, use the following
        <code>AliasMatch</code> directive:</p>
    
        <pre class="prettyprint lang-config">AliasMatch "^/upages/([a-zA-Z0-9]+)(/(.*))?$"   "/home/$1/public_html/$3"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="redirect" id="redirect">URL Redirection</a></h2>
    
        <p>The configuration directives discussed in the above sections
        tell httpd 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 <em>redirection</em> and is
        implemented by the <code class="directive"><a href="./mod/mod_alias.html#redirect">Redirect</a></code> directive. For example, if
        the contents of the directory <code>/foo/</code> under the
        <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> are moved
        to the new directory <code>/bar/</code>, you can instruct clients
        to request the content at the new location as follows:</p>
    
        <pre class="prettyprint lang-config">Redirect permanent "/foo/"   "http://www.example.com/bar/"</pre>
    
    
        <p>This will redirect any URL-Path starting in
        <code>/foo/</code> to the same URL path on the
        <code>www.example.com</code> server with <code>/bar/</code>
        substituted for <code>/foo/</code>. You can redirect clients to
        any server, not only the origin server.</p>
    
        <p>httpd also provides a <code class="directive"><a href="./mod/mod_alias.html#redirectmatch">RedirectMatch</a></code> 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:</p>
    
        <pre class="prettyprint lang-config">RedirectMatch permanent "^/$"    "http://www.example.com/startpage.html"</pre>
    
    
        <p>Alternatively, to temporarily redirect all pages on one site
        to a particular page on another site, use the following:</p>
    
        <pre class="prettyprint lang-config">RedirectMatch temp ".*"  "http://othersite.example.com/startpage.html"</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Reverse Proxy</a></h2>
    
    <p>httpd also allows you to bring remote documents into the URL space
    of the local server.  This technique is called <em>reverse
    proxying</em> 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 (forward) proxying because, to the client,
    it appears the documents originate at the reverse proxy server.</p>
    
    <p>In the following example, when clients request documents under the
    <code>/foo/</code> directory, the server fetches those documents from
    the <code>/bar/</code> directory on <code>internal.example.com</code>
    and returns them to the client as if they were from the local
    server.</p>
    
    <pre class="prettyprint lang-config">ProxyPass "/foo/" "http://internal.example.com/bar/"
    ProxyPassReverse "/foo/" "http://internal.example.com/bar/"
    ProxyPassReverseCookieDomain internal.example.com public.example.com
    ProxyPassReverseCookiePath "/foo/" "/bar/"</pre>
    
    
    <p>The <code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code> configures
    the server to fetch the appropriate documents, while the
    <code class="directive"><a href="./mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code>
    directive rewrites redirects originating at
    <code>internal.example.com</code> so that they target the appropriate
    directory on the local server.  Similarly, the
    <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code>
    and <code class="directive"><a href="./mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code>
    rewrite cookies set by the backend server.</p>
    <p>It is important to note, however, that
    links inside the documents will not be rewritten. So any absolute
    links on <code>internal.example.com</code> will result in the client
    breaking out of the proxy server and requesting directly from
    <code>internal.example.com</code>. You can modify these links (and other
    content) in a page as it is being served to the client using
    <code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code>.</p>
    
    <pre class="prettyprint lang-config">Substitute "s/internal\.example\.com/www.example.com/i"</pre>
    
    
    <p>For more sophisticated rewriting of links in HTML and XHTML, the 
    <code class="module"><a href="./mod/mod_proxy_html.html">mod_proxy_html</a></code> module is also available. It allows you
    to create maps of URLs that need to be rewritten, so that complex
    proxying scenarios can be handled.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="rewrite" id="rewrite">Rewriting Engine</a></h2>
    
        <p>When even more powerful substitution is required, the rewriting
        engine provided by <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
        can be useful. The directives provided by this module can 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
        <a href="rewrite/">detailed mod_rewrite documentation</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="notfound" id="notfound">File Not Found</a></h2>
    
        <p>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 <a href="#redirect">URL redirection</a> 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.</p>
    
        <p>Another common cause of "File Not Found" errors is
        accidental mistyping of URLs, either directly in the browser,
        or in HTML links. httpd provides the module
        <code class="module"><a href="./mod/mod_speling.html">mod_speling</a></code> (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.</p>
    
        <p>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.</p>
    
        <p><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code> provides <code class="directive"><a href="./mod/mod_dir.html#fallbackresource">FallbackResource</a></code>, which can be used to map virtual
        URIs to a real resource, which then serves them. This is a very
        useful replacement for <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> when implementing
        a 'front controller'</p>
    
        <p>If all attempts to locate the content fail, httpd returns
        an error page with HTTP status code 404 (file not found). The
        appearance of this page is controlled with the
        <code class="directive"><a href="./mod/core.html#errordocument">ErrorDocument</a></code> directive
        and can be customized in a flexible manner as discussed in the
        <a href="custom-error.html">Custom error responses</a>
        document.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="other" id="other">Other URL Mapping Modules</a></h2>
    
    
    
        <p>Other modules available for URL mapping include:</p>
    
        <ul>
        <li><code class="module"><a href="./mod/mod_actions.html">mod_actions</a></code> - Maps a request to a CGI script
        based on the request method, or resource MIME type.</li>
        <li><code class="module"><a href="./mod/mod_dir.html">mod_dir</a></code> - Provides basic mapping of a trailing
        slash into an index file such as <code>index.html</code>.</li>
        <li><code class="module"><a href="./mod/mod_imagemap.html">mod_imagemap</a></code> - Maps a request to a URL based
        on where a user clicks on an image embedded in a HTML document.</li>
        <li><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> - Selects an appropriate
        document based on client preferences such as language or content
        compression.</li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/urlmapping.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/urlmapping.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/urlmapping.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/urlmapping.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/urlmapping.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/urlmapping.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html.en�����������������������������������������������������������0000664�0001751�0001751�00000031057�14737241666�020170� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Starting Apache - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Starting Apache</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>On Windows, Apache is normally run as a service.
        For details, see <a href="platform/windows.html#winsvc">Running Apache as a Service</a>.
        </p>
    
        <p>On Unix, the <code class="program"><a href="./programs/httpd.html">httpd</a></code> program
        is run as a daemon that executes continuously in the
        background to handle requests.  This document describes how
        to invoke <code class="program"><a href="./programs/httpd.html">httpd</a></code>.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#startup">How Apache Starts</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#errors">Errors During Start-up</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#boot">Starting at Boot-Time</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#info">Additional Information</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="stopping.html">Stopping and Restarting</a></li><li><code class="program"><a href="./programs/httpd.html">httpd</a></code></li><li><code class="program"><a href="./programs/apachectl.html">apachectl</a></code></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="startup" id="startup">How Apache Starts</a></h2>
    
        <p>If the <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
        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
        <em>child</em> processes which do the work of listening for and
        answering requests from clients. The main <code>httpd</code>
        process continues to run as the root user, but the child processes
        run as a less privileged user. This is controlled by the selected
        <a href="mpm.html">Multi-Processing Module</a>.</p>
    
        <p>The recommended method of invoking the <code class="program"><a href="./programs/httpd.html">httpd</a></code>
        executable is to use the <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> control script. This
        script sets certain environment variables that are necessary for
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> to function correctly under some operating
        systems, and then invokes the <code class="program"><a href="./programs/httpd.html">httpd</a></code> binary.
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> will pass through any command line
        arguments, so any <code class="program"><a href="./programs/httpd.html">httpd</a></code> options may also be used with
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code>.  You may also directly edit the
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> script by changing the <code>HTTPD</code>
        variable near the top to specify the correct location of the
        <code class="program"><a href="./programs/httpd.html">httpd</a></code> binary and any command-line arguments that you
        wish to be <em>always</em> present.</p>
    
        <p>The first thing that <code class="program"><a href="./programs/httpd.html">httpd</a></code> does when it is
        invoked is to locate and read the <a href="configuring.html">configuration file</a>
        <code>httpd.conf</code>. The location of this file is set at
        compile-time, but it is possible to specify its location at run
        time using the <code>-f</code> command-line option as in</p>
    
    <div class="example"><p><code>/usr/local/apache2/bin/apachectl -f
          /usr/local/apache2/conf/httpd.conf</code></p></div>
    
        <p>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 <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code> directory.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="errors" id="errors">Errors During Start-up</a></h2>
    
        <p>If Apache suffers a fatal problem during startup, it will
        write a message describing the problem either to the console or
        to the <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> before
        exiting. One of the most common error messages is "<code>Unable
        to bind to Port ...</code>". This message is usually caused by
        either:</p>
    
        <ul>
          <li>Trying to start the server on a privileged port when not
          logged in as the root user; or</li>
    
          <li>Trying to start the server when there is another instance
          of Apache or some other web server already bound to the same
          Port.</li>
        </ul>
    
        <p>For further trouble-shooting instructions, consult the
        Apache <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="boot" id="boot">Starting at Boot-Time</a></h2>
    
        <p>If you want your server to continue running after a system
        reboot, you should add a call to <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> to your
        system startup files (typically <code>rc.local</code> or a file in
        an <code>rc.N</code> directory). This will start Apache as
        root. Before doing this ensure that your server is properly
        configured for security and access restrictions.</p>
    
        <p>The <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> script is designed to act like a
        standard SysV init script; it can take the arguments
        <code>start</code>, <code>restart</code>, and <code>stop</code>
        and translate them into the appropriate signals to
        <code class="program"><a href="./programs/httpd.html">httpd</a></code>.  So you can often simply link
        <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> into the appropriate init directory. But be
        sure to check the exact requirements of your system.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="info" id="info">Additional Information</a></h2>
    
        <p>Additional information about the command-line options of <code class="program"><a href="./programs/httpd.html">httpd</a></code> and <code class="program"><a href="./programs/apachectl.html">apachectl</a></code> as well as other support
        programs included with the server is available on the
        <a href="programs/">Server and Supporting Programs</a> page.
        There is also documentation on all the <a href="mod/">modules</a> included with the Apache distribution
        and the <a href="mod/directives.html">directives</a> that they
        provide.</p>
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/invoking.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/invoking.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/invoking.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/invoking.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/invoking.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/invoking.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/invoking.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/invoking.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html.en���������������������������������������������������0000664�0001751�0001751�00000037062�14737241666�021475� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Overview of new features in Apache HTTP Server 2.0 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Overview of new features in Apache HTTP Server 2.0</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
      <p>This document describes some of the major changes between the
         1.3 and 2.0 versions of the Apache HTTP Server.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#core">Core Enhancements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#module">Module Enhancements</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="upgrading.html">Upgrading to 2.0 from 1.3</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="core" id="core">Core Enhancements</a></h2>
        
    
        <dl>
          <dt>Unix Threading</dt>
    
          <dd>On Unix systems with POSIX threads support, Apache httpd can
          now run in a hybrid multiprocess, multithreaded mode. This
          improves scalability for many, but not all configurations.</dd>
    
          <dt>New Build System</dt>
    
          <dd>The build system has been rewritten from scratch to be
          based on <code>autoconf</code> and <code>libtool</code>.
          This makes Apache httpd's configuration system more similar to
          that of other packages.</dd>
    
          <dt>Multiprotocol Support</dt>
    
          <dd>Apache HTTP Server now has some of the infrastructure in place to
          support serving multiple protocols. <code class="module"><a href="./mod/mod_echo.html">mod_echo</a></code> has
          been written as an example.</dd>
    
          <dt>Better support for non-Unix
          platforms</dt>
    
          <dd>Apache HTTP Server 2.0 is faster and more stable on non-Unix
          platforms such as BeOS, OS/2, and Windows. With the
          introduction of platform-specific <a href="mpm.html">multi-processing modules</a> (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.</dd>
    
          <dt>New Apache httpd API</dt>
    
          <dd>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 HTTP Server.</dd>
    
          <dt>IPv6 Support</dt>
    
          <dd>On systems where IPv6 is supported by the underlying
          Apache Portable Runtime library, Apache httpd gets IPv6 listening
          sockets by default. Additionally, the <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>, <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code>, and <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> directives support
          IPv6 numeric address strings (e.g., "<code>Listen
          [2001:db8::1]:8080</code>").</dd>
    
          <dt>Filtering</dt>
    
          <dd>Apache httpd 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
          <code>INCLUDES</code> filter in <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>. The
          module <code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code> allows external programs to
          act as filters in much the same way that CGI programs can act as
          handlers.</dd>
    
          <dt>Multilanguage Error Responses</dt>
    
          <dd>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.</dd>
    
          <dt>Simplified configuration</dt>
    
          <dd>Many confusing directives have been simplified. The often
          confusing <code>Port</code> and <code>BindAddress</code> directives
          are gone; only the <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code>
          directive is used for IP address binding; the <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code> directive specifies the
          server name and port number only for redirection and vhost
          recognition.</dd>
    
          <dt>Native Windows NT Unicode Support</dt>
    
          <dd>Apache httpd 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.
          <em>This support does not extend to Windows 95, 98 or ME, which
          continue to use the machine's local codepage for filesystem
          access.</em></dd>
    
          <dt>Regular Expression Library Updated</dt>
    
          <dd>Apache httpd 2.0 includes the <a href="http://www.pcre.org/">Perl
          Compatible Regular Expression Library</a> (PCRE).  All regular
          expression evaluation now uses the more powerful Perl 5
          syntax.</dd>
    
        </dl>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="module" id="module">Module Enhancements</a></h2>
        
    
        <dl>
          <dt><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code></dt>
    
          <dd>New module in Apache httpd 2.0. This module is an interface
          to the SSL/TLS encryption protocols provided by
          OpenSSL.</dd>
    
          <dt><code class="module"><a href="./mod/mod_dav.html">mod_dav</a></code></dt>
    
          <dd>New module in Apache httpd 2.0. This module implements the HTTP
          Distributed Authoring and Versioning (DAV) specification for
          posting and maintaining web content.</dd>
    
          <dt><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code></dt>
    
          <dd>New module in Apache httpd 2.0.  This module allows supporting
          browsers to request that content be compressed before delivery,
          saving network bandwidth.</dd>
    
          <dt><code class="module">mod_auth_ldap</code></dt>
    
          <dd>New module in Apache httpd 2.0.41.  This module allows an LDAP
          database to be used to store credentials for HTTP Basic
          Authentication.  A companion module, <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>
          provides connection pooling and results caching.</dd>
    
          <dt><code class="module"><a href="./mod/mod_auth_digest.html">mod_auth_digest</a></code></dt>
    
          <dd>Includes additional support for session caching across
          processes using shared memory.</dd>
    
          <dt><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code></dt>
    
          <dd>New module in Apache httpd 2.0. This experimental module allows
          for character set translation or recoding.</dd>
    
          <dt><code class="module"><a href="./mod/mod_file_cache.html">mod_file_cache</a></code></dt>
    
          <dd>New module in Apache httpd 2.0. This module includes the
          functionality of <code>mod_mmap_static</code> in Apache HTTP
          Server version 1.3, plus adds further caching abilities.</dd>
    
          <dt><code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code></dt>
    
          <dd>This module is much more flexible in Apache httpd 2.0. It can now
          modify request headers used by <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>, and
          it can conditionally set response headers.</dd>
    
          <dt><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></dt>
    
          <dd>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
          <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
          configuration sections provide more readable (and internally
          faster) control of proxied sites; overloaded <code>&lt;Directory
          "proxy:..."&gt;</code> configuration are not supported. The module
          is now divided into specific protocol support modules including
          <code>proxy_connect</code>, <code>proxy_ftp</code> and
          <code>proxy_http</code>.</dd>
    
          <dt><code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code></dt>
    
          <dd>A new <code class="directive"><a href="./mod/mod_negotiation.html#forcelanguagepriority">ForceLanguagePriority</a></code> 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.</dd>
    
          <dt><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code></dt>
    
          <dd>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.</dd>
    
          <dt><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></dt>
    
          <dd>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 <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>'s variables <code>$0</code>
          .. <code>$9</code>.</dd>
    
          <dt><code class="module">mod_auth_dbm</code></dt>
    
          <dd>Now supports multiple types of DBM-like databases using the
          <code class="directive">AuthDBMType</code> directive.</dd>
    
        </dl>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/new_features_2_0.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/new_features_2_0.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/new_features_2_0.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/new_features_2_0.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/new_features_2_0.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./pt-br/new_features_2_0.html" hreflang="pt-br" rel="alternate" title="Português (Brasil)">&nbsp;pt-br&nbsp;</a> |
    <a href="./tr/new_features_2_0.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/new_features_2_0.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/server-wide.html.en��������������������������������������������������������0000664�0001751�0001751�00000027604�14737241666�020603� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Server-Wide Configuration - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Server-Wide Configuration</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/server-wide.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    <p>This document explains some of the directives provided by
    the <code class="module"><a href="./mod/core.html">core</a></code> server which are used to configure
    the basic operations of the server.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#identification">Server Identification</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#locations">File Locations</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#resource">Limiting Resource Usage</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#implementation">Implementation Choices</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="identification" id="identification">Server Identification</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#servername">ServerName</a></code></li><li><code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code></li><li><code class="directive"><a href="./mod/core.html#serversignature">ServerSignature</a></code></li><li><code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code></li><li><code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code></li></ul></td></tr></table>
    
        <p>The <code class="directive"><a href="./mod/core.html#serveradmin">ServerAdmin</a></code> and
        <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> directives
        control what information about the server will be presented
        in server-generated documents such as error messages. The
        <code class="directive"><a href="./mod/core.html#servertokens">ServerTokens</a></code> directive
        sets the value of the Server HTTP response header field.</p>
    
        <p>The <code class="directive"><a href="./mod/core.html#servername">ServerName</a></code>,
        <code class="directive"><a href="./mod/core.html#usecanonicalname">UseCanonicalName</a></code> and
        <code class="directive"><a href="./mod/core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></code>
        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, httpd must redirect the client to the full
        name including the trailing slash so that the client will
        correctly resolve relative references in the document.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="locations" id="locations">File Locations</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/mpm_common.html#coredumpdirectory">CoreDumpDirectory</a></code></li><li><code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code></li><li><code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#pidfile">PidFile</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#scoreboardfile">ScoreBoardFile</a></code></li><li><code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code></li></ul></td></tr></table>
    
        <p>These directives control the locations of the various files
        that httpd needs for proper operation. When the pathname used
        does not begin with a slash (/), the files are located relative
        to the <code class="directive"><a href="./mod/core.html#serverroot">ServerRoot</a></code>. Be careful
        about locating files in paths which are writable by non-root users.
        See the <a href="misc/security_tips.html#serverroot">security tips</a>
        documentation for more details.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="resource" id="resource">Limiting Resource Usage</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#limitrequestbody">LimitRequestBody</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfields">LimitRequestFields</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestfieldsize">LimitRequestFieldsize</a></code></li><li><code class="directive"><a href="./mod/core.html#limitrequestline">LimitRequestLine</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitcpu">RLimitCPU</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitmem">RLimitMEM</a></code></li><li><code class="directive"><a href="./mod/core.html#rlimitnproc">RLimitNPROC</a></code></li><li><code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code></li></ul></td></tr></table>
    
        <p>The <code class="directive">LimitRequest</code>*
        directives are used to place limits on the amount of resources
        httpd will use in reading requests from clients. By limiting
        these values, some kinds of denial of service attacks can be
        mitigated.</p>
    
        <p>The <code class="directive">RLimit</code>* directives
        are used to limit the amount of resources which can be used by
        processes forked off from the httpd children. In particular,
        this will control resources used by CGI scripts and SSI exec
        commands.</p>
    
        <p>The <code class="directive"><a href="./mod/mpm_common.html#threadstacksize">ThreadStackSize</a></code>
        directive is used with some platforms to control the stack size.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="implementation" id="implementation">Implementation Choices</a></h2>
        
    
        <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td /><td><ul><li><code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code></li></ul></td></tr></table>
    
        <p>The <code class="directive">Mutex</code> directive can be used to change
        the underlying implementation used for mutexes, in order to relieve
        functional or performance problems with <a class="glossarylink" href="./glossary.html#apr" title="see glossary">APR</a>'s
        default choice.</p>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/server-wide.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/server-wide.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/server-wide.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/server-wide.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/server-wide.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/server-wide.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/upgrading.html.en����������������������������������������������������������0000664�0001751�0001751�00000073756�14737241666�020340� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Upgrading to 2.4 from 2.2 - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Upgrading to 2.4 from 2.2</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/upgrading.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/upgrading.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div>
    
      <p>In order to assist folks upgrading, we maintain a document
      describing information critical to existing Apache HTTP Server users. These
      are intended to be brief notes, and you should be able to find
      more information in either the <a href="new_features_2_4.html">New Features</a> document, or in
      the <code>src/CHANGES</code> file.  Application and module developers
      can find a summary of API changes in the <a href="developer/new_api_2_4.html">API updates</a> overview.</p>
    
      <p>This document describes changes in server behavior that might
      require you to change your configuration or how you use the server
      in order to continue using 2.4 as you are currently using 2.2.
      To take advantage of new features in 2.4, see the New Features
      document.</p>
    
      <p>This document describes only the changes from 2.2 to 2.4.  If you
      are upgrading from version 2.0, you should also consult the <a href="http://httpd.apache.org/docs/2.2/upgrading.html">2.0 to 2.2
      upgrading document.</a></p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#compile-time">Compile-Time Configuration Changes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#run-time">Run-Time Configuration Changes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#misc">Misc Changes</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#third-party">Third Party Modules</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#commonproblems">Common problems when upgrading</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="new_features_2_4.html">Overview of new features in
      Apache HTTP Server 2.4</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile-time" id="compile-time">Compile-Time Configuration Changes</a></h2>
        
    
        <p>The compilation process is very similar to the one used in
        version 2.2.  Your old <code>configure</code> command line (as
        found in <code>build/config.nice</code> in the installed server
        directory) can be used in most cases.  There are some changes in
        the default settings.  Some details of changes:</p>
    
        <ul>
          <li>These modules have been removed: mod_authn_default,
          mod_authz_default, mod_mem_cache.  If you were using
          mod_mem_cache in 2.2, look at <code class="module"><a href="./mod/mod_cache_disk.html">mod_cache_disk</a></code> in
          2.4.</li>
    
          <li>All load balancing implementations have been moved to
          individual, self-contained mod_proxy submodules, e.g.
          <code class="module"><a href="./mod/mod_lbmethod_bybusyness.html">mod_lbmethod_bybusyness</a></code>.  You might need
          to build and load any of these that your configuration
          uses.</li>
    
          <li>Platform support has been removed for BeOS, TPF, and
          even older platforms such as A/UX, Next, and Tandem.  These were
          believed to be broken anyway.</li>
    
          <li>configure: dynamic modules (DSO) are built by default</li>
    
          <li>configure: By default, only a basic set of modules is loaded. The
          other <code class="directive">LoadModule</code> directives are commented
          out in the configuration file.</li>
    
          <li>configure: the "most" module set gets built by default</li>
    
          <li>configure: the "reallyall" module set adds developer modules
          to the "all" set</li>
        </ul>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="run-time" id="run-time">Run-Time Configuration Changes</a></h2>
        
        <p>There have been significant changes in authorization configuration,
        and other minor configuration changes, that could require changes to your 2.2
        configuration files before using them for 2.4.</p>
    
        <h3><a name="authz" id="authz">Authorization</a></h3>
          
    
          <p>Any configuration file that uses authorization will likely
          need changes.</p>
    
        <p>You should review the <a href="howto/auth.html">Authentication,
        Authorization and Access Control Howto</a>, especially the section
        <a href="howto/auth.html#beyond">Beyond just authorization</a>
        which explains the new mechanisms for controlling the order in
        which the authorization directives are applied.</p>
    
        <p>Directives that control how authorization modules respond when they don't match
        the authenticated user have been removed: This includes 
        AuthzLDAPAuthoritative, AuthzDBDAuthoritative, AuthzDBMAuthoritative, 
        AuthzGroupFileAuthoritative, AuthzUserAuthoritative,
        and AuthzOwnerAuthoritative.   These directives have been replaced by the
        more expressive <code class="directive"><a href="./mod/mod_authz_core.html#requireany">RequireAny</a></code>, 
        <code class="directive"><a href="./mod/mod_authz_core.html#requirenone">RequireNone</a></code>, and
        <code class="directive"><a href="./mod/mod_authz_core.html#requireall">RequireAll</a></code>.</p>
    
        <p>If you use <code class="module"><a href="./mod/mod_authz_dbm.html">mod_authz_dbm</a></code>, you must port your 
        configuration to use <code>Require dbm-group ...</code> in place
        of <code>Require group ...</code>.</p>
    
        <h4><a name="access" id="access">Access control</a></h4>
          
    
          <p>In 2.2, access control based on client hostname, IP address,
          and other characteristics of client requests was done using the
          directives <code class="directive"><a href="./mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="./mod/mod_access_compat.html#allow">Allow</a></code>, <code class="directive"><a href="./mod/mod_access_compat.html#deny">Deny</a></code>, and <code class="directive"><a href="./mod/mod_access_compat.html#satisfy">Satisfy</a></code>.</p>
    
          <p>In 2.4, such access control is done in the same way as other
          authorization checks, using the new module
          <code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code>.  The old access control idioms
          should be replaced by the new authentication mechanisms,
          although for compatibility with old configurations, the new
          module <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code> is provided.</p>
    
          <div class="note"><h3>Mixing old and new directives</h3>
          <p>Mixing old directives like <code class="directive"><a href="./mod/mod_access_compat.html#order">Order</a></code>, <code class="directive"><a href="./mod/mod_access_compat.html#allow">Allow</a></code> or <code class="directive"><a href="./mod/mod_access_compat.html#deny">Deny</a></code> with new ones like
          <code class="directive"><a href="./mod/mod_authz_core.html#require">Require</a></code> is technically possible 
          but discouraged. <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code> was created to support 
          configurations containing only old directives to facilitate the 2.4 upgrade. 
          Please check the examples below to get a better idea about issues that might arise.
          </p>
          </div>
    
          <p>Here are some examples of old and new ways to do the same
          access control.</p>
    
          <p>In this example, there is no authentication and all requests are denied.</p>
          <div class="example"><h3>2.2 configuration:</h3><pre class="prettyprint lang-config">Order deny,allow
    Deny from all</pre>
    </div>
          <div class="example"><h3>2.4 configuration:</h3><pre class="prettyprint lang-config">Require all denied</pre>
    </div>
    
          <p>In this example, there is no authentication and all requests are allowed.</p>
          <div class="example"><h3>2.2 configuration:</h3><pre class="prettyprint lang-config">Order allow,deny
    Allow from all</pre>
    </div>
          <div class="example"><h3>2.4 configuration:</h3><pre class="prettyprint lang-config">Require all granted</pre>
    </div>
    
          <p>In the following example, there is no authentication and all hosts in the example.org domain
          are allowed access; all other hosts are denied access.</p>
    
          <div class="example"><h3>2.2 configuration:</h3><pre class="prettyprint lang-config">Order Deny,Allow
    Deny from all
    Allow from example.org</pre>
    </div>
          <div class="example"><h3>2.4 configuration:</h3><pre class="prettyprint lang-config">Require host example.org</pre>
    </div>
    
          <p>In the following example, mixing old and new directives leads to 
          unexpected results.</p>
     
          <div class="example"><h3>Mixing old and new directives: NOT WORKING AS EXPECTED</h3><pre class="prettyprint lang-config">DocumentRoot "/var/www/html"
    
    &lt;Directory "/"&gt;
        AllowOverride None
        Order deny,allow
        Deny from all
    &lt;/Directory&gt;
    
    &lt;Location "/server-status"&gt;
        SetHandler server-status
        Require local
    &lt;/Location&gt;
    
    access.log - GET /server-status 403 127.0.0.1
    error.log - AH01797: client denied by server configuration: /var/www/html/server-status</pre>
    </div>
          <p>Why httpd denies access to servers-status even if the configuration seems to allow it?
            Because <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code> directives take precedence
            over the <code class="module"><a href="./mod/mod_authz_host.html">mod_authz_host</a></code> one in this configuration 
            <a href="sections.html#merging">merge</a> scenario.</p>
    
          <p>This example conversely works as expected:</p>
    
          <div class="example"><h3>Mixing old and new directives: WORKING AS EXPECTED</h3><pre class="prettyprint lang-config">DocumentRoot "/var/www/html"
    
    &lt;Directory "/"&gt;
        AllowOverride None
        Require all denied
    &lt;/Directory&gt;
    
    &lt;Location "/server-status"&gt;
        SetHandler server-status
        Order deny,allow
        Deny from all
        Allow From 127.0.0.1
    &lt;/Location&gt;
    
    access.log - GET /server-status 200 127.0.0.1</pre>
    </div> 
          <p>So even if mixing configuration is still
            possible, please try to avoid it when upgrading: either keep old directives and then migrate
            to the new ones on a later stage or just migrate everything in bulk.  
          </p>
        
    
         <p>In many configurations with authentication, where the value of the
         <code class="directive">Satisfy</code> was the default of <em>ALL</em>, snippets
         that simply disabled host-based access control are omitted:</p>
    
          <div class="example"><h3>2.2 configuration:</h3><pre class="prettyprint lang-config"># 2.2 config that disables host-based access control and uses only authentication
    Order Deny,Allow
    Allow from all
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
          <div class="example"><h3>2.4 configuration:</h3><pre class="prettyprint lang-config"># No replacement of disabling host-based access control needed
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
    
         <p>In configurations where both authentication and access control were meaningfully combined, the 
            access control directives should be migrated. This example allows requests meeting <em>both</em> criteria:</p>
          <div class="example"><h3>2.2 configuration:</h3><pre class="prettyprint lang-config">Order allow,deny
    Deny from all
    # Satisfy ALL is the default
    Satisfy ALL
    Allow from 127.0.0.1
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
          <div class="example"><h3>2.4 configuration:</h3><pre class="prettyprint lang-config">AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    &lt;RequireAll&gt;
      Require valid-user
      Require ip 127.0.0.1
    &lt;/RequireAll&gt;</pre>
    </div>
    
         <p>In configurations where both authentication and access control were meaningfully combined, the 
            access control directives should be migrated. This example allows requests meeting <em>either</em> criteria:</p>
          <div class="example"><h3>2.2 configuration:</h3><pre class="prettyprint lang-config">Order allow,deny
    Deny from all
    Satisfy any
    Allow from 127.0.0.1
    AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    Require valid-user</pre>
    </div>
          <div class="example"><h3>2.4 configuration:</h3><pre class="prettyprint lang-config">AuthType Basic
    AuthBasicProvider file
    AuthUserFile /example.com/conf/users.passwd
    AuthName secure
    # Implicitly &lt;RequireAny&gt;
    Require valid-user
    Require ip 127.0.0.1</pre>
    </div>
    
        
    
        <h3><a name="config" id="config">Other configuration changes</a></h3>
          
    
          <p>Some other small adjustments may be necessary for particular
          configurations as discussed below.</p>
    
          <ul>
            <li><code class="directive">MaxRequestsPerChild</code> has been renamed to
            <code class="directive"><a href="./mod/mpm_common.html#maxconnectionsperchild">MaxConnectionsPerChild</a></code>,
            describes more accurately what it does. The old name is still
            supported.</li>
    
            <li><code class="directive">MaxClients</code> has been renamed to
            <code class="directive"><a href="./mod/mpm_common.html#maxrequestworkers">MaxRequestWorkers</a></code>,
            which describes more accurately what it does. For async MPMs, like
            <code class="module"><a href="./mod/event.html">event</a></code>, the maximum number of clients is not
            equivalent than the number of worker threads. The old name is still
            supported.</li>
    
            <li>The <code class="directive"><a href="./mod/core.html#defaulttype">DefaultType</a></code>
            directive no longer has any effect, other than to emit a
            warning if it's used with any value other than
            <code>none</code>.  You need to use other configuration
            settings to replace it in 2.4.
            </li>
    
            <li><code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> now
            defaults to <code>None</code>.</li>
    
            <li><code class="directive"><a href="./mod/core.html#enablesendfile">EnableSendfile</a></code> now
            defaults to Off.</li>
    
            <li><code class="directive"><a href="./mod/core.html#fileetag">FileETag</a></code> now
            defaults to "MTime Size" (without INode).</li>
    
            <li><code class="module"><a href="./mod/mod_dav_fs.html">mod_dav_fs</a></code>: The format of the <code class="directive"><a href="./mod/mod_dav_fs.html#davlockdb">DavLockDB</a></code> file has changed for
            systems with inodes.  The old <code class="directive"><a href="./mod/mod_dav_fs.html#davlockdb">DavLockDB</a></code> file must be deleted on
            upgrade.
            </li>
    
            <li><code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code> only
            accepts values of <code>On</code> or <code>Off</code>.
            Previously, any value other than "Off" or "0" was treated as
            "On".</li>
    
            <li>Directives AcceptMutex, LockFile, RewriteLock, SSLMutex,
            SSLStaplingMutex, and WatchdogMutexPath have been replaced
            with a single <code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>
            directive.  You will need to evaluate any use of these removed
            directives in your 2.2 configuration to determine if they can
            just be deleted or will need to be replaced using <code class="directive"><a href="./mod/core.html#mutex">Mutex</a></code>.</li>
    
            <li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>: <code class="directive"><a href="./mod/mod_cache.html#cacheignoreurlsessionidentifiers">CacheIgnoreURLSessionIdentifiers</a></code>
            now does an exact match against the query string instead of a
            partial match.  If your configuration was using partial
            strings, e.g. using <code>sessionid</code> to match
            <code>/someapplication/image.gif;jsessionid=123456789</code>,
            then you will need to change to the full string
            <code>jsessionid</code>.
            </li>
    
            <li><code class="module"><a href="./mod/mod_cache.html">mod_cache</a></code>: The second parameter to 
            <code class="directive"><a href="./mod/mod_cache.html#cacheenable">CacheEnable</a></code> only
            matches forward proxy content if it begins with the correct
            protocol. In 2.2 and earlier, a parameter of '/' matched all
            content.</li>
    
            <li><code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code>: <code class="directive"><a href="./mod/mod_ldap.html#ldaptrustedclientcert">LDAPTrustedClientCert</a></code> is now
            consistently a per-directory setting only.  If you use this
            directive, review your configuration to make sure it is
            present in all the necessary directory contexts.</li>
    
            <li><code class="module"><a href="./mod/mod_filter.html">mod_filter</a></code>: <code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code> syntax has changed and
            now uses a boolean expression to determine if a filter is applied.
            </li>
    
            <li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code>:
                <ul>
                <li>The <code>#if expr</code> element now uses the new <a href="expr.html">expression parser</a>. The old syntax can be
                restored with the new directive <code class="directive"><a href="./mod/mod_include.html#ssilegacyexprparser">SSILegacyExprParser</a></code>.
                </li>
                <li>An SSI* config directive in directory scope no longer causes
                all other per-directory SSI* directives to be reset to their
                default values.</li>
                </ul>
            </li>
    
            <li><code class="module"><a href="./mod/mod_charset_lite.html">mod_charset_lite</a></code>: The <code>DebugLevel</code>
            option has been removed in favour of per-module <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> configuration.
            </li>
    
            <li><code class="module"><a href="./mod/mod_ext_filter.html">mod_ext_filter</a></code>: The <code>DebugLevel</code>
            option has been removed in favour of per-module <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> configuration.
            </li>
    
            <li><code class="module"><a href="./mod/mod_proxy_scgi.html">mod_proxy_scgi</a></code>: The default setting for
            <code>PATH_INFO</code> has changed from httpd 2.2, and
            some web applications will no longer operate properly with
            the new <code>PATH_INFO</code> setting.  The previous setting
            can be restored by configuring the <code>proxy-scgi-pathinfo</code>
            variable.</li>
    
            <li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>: CRL based revocation checking
            now needs to be explicitly configured through <code class="directive"><a href="./mod/mod_ssl.html#sslcarevocationcheck">SSLCARevocationCheck</a></code>.
            </li>
    
            <li><code class="module"><a href="./mod/mod_substitute.html">mod_substitute</a></code>: The maximum line length is now
            limited to 1MB.
            </li>
    
            <li><code class="module"><a href="./mod/mod_reqtimeout.html">mod_reqtimeout</a></code>: If the module is loaded, it
            will now set some default timeouts.</li>
    
            <li><code class="module"><a href="./mod/mod_dumpio.html">mod_dumpio</a></code>: <code class="directive">DumpIOLogLevel</code>
            is no longer supported.  Data is always logged at <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> <code>trace7</code>.</li>
    
            <li>On Unix platforms, piped logging commands configured using
            either <code class="directive"><a href="./mod/core.html#errorlog">ErrorLog</a></code> or
            <code class="directive"><a href="./mod/mod_log_config.html#customlog">CustomLog</a></code> were invoked using
            <code>/bin/sh -c</code> in 2.2 and earlier.  In 2.4 and later,
            piped logging commands are executed directly.  To restore the
            old behaviour, see the <a href="logs.html#piped">piped logging
            documentation</a>.</li>
    
          </ul>
        
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="misc" id="misc">Misc Changes</a></h2>
        
    
        <ul>
          <li><code class="module"><a href="./mod/mod_autoindex.html">mod_autoindex</a></code>: will now extract titles and
          display descriptions for .xhtml files, which were previously
          ignored.</li>
    
          <li><code class="module"><a href="./mod/mod_ssl.html">mod_ssl</a></code>: The default format of the <code>*_DN</code>
          variables has changed. The old format can still be used with the new
          <code>LegacyDNStringFormat</code> argument to <code class="directive"><a href="./mod/mod_ssl.html#ssloptions">SSLOptions</a></code>. The SSLv2 protocol is
          no longer supported. <code class="directive"><a href="./mod/mod_ssl.html#sslproxycheckpeercn">SSLProxyCheckPeerCN
    	  </a></code> and <code class="directive"><a href="./mod/mod_ssl.html#sslproxycheckpeerexpire">SSLProxyCheckPeerExpire
    	  </a></code> now default to On, causing proxy requests to HTTPS hosts
    	  with bad or outdated certificates to fail with a 502 status code (Bad 
    	  gateway)</li>
    
          <li><code class="program"><a href="./programs/htpasswd.html">htpasswd</a></code> now uses MD5 hash by default on
          all platforms.</li>
    
          <li>The <code class="directive"><a href="./mod/core.html#namevirtualhost">NameVirtualHost</a></code>
          directive no longer has any effect, other than to emit a
          warning.  Any address/port combination appearing in multiple
          virtual hosts is implicitly treated as a name-based virtual host.
          </li>
    
          <li><code class="module"><a href="./mod/mod_deflate.html">mod_deflate</a></code> will now skip compression if it knows
          that the size overhead added by the compression is larger than the data
          to be compressed.
          </li>
    
          <li>Multi-language error documents from 2.2.x may not work unless
          they are adjusted to the new syntax of <code class="module"><a href="./mod/mod_include.html">mod_include</a></code>'s
          <code>#if expr=</code> element or the directive
          <code class="directive"><a href="./mod/mod_include.html#ssilegacyexprparser">SSILegacyExprParser</a></code> is
          enabled for the directory containing the error documents.
          </li>
    
          <li>The functionality provided by <code>mod_authn_alias</code>
          in previous versions (i.e., the <code class="directive"><a href="./mod/mod_authn_core.html#authnprovideralias">AuthnProviderAlias</a></code> directive)
          has been moved into <code class="module"><a href="./mod/mod_authn_core.html">mod_authn_core</a></code>.  
          </li>
    
          <li>The RewriteLog and RewriteLogLevel directives have been removed.
          This functionality is now provided by configuring the appropriate
          level of logging for the <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code> module using
          the <code class="directive"><a href="./mod/core.html#loglevel">LogLevel</a></code> directive.
          See also the <a href="mod/mod_rewrite.html#logging">mod_rewrite logging</a>
          section.</li>
    
        </ul>
    
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="third-party" id="third-party">Third Party Modules</a></h2>
        
        <p>All modules must be recompiled for 2.4 before being loaded.</p>
    
        <p>Many third-party modules designed for version 2.2 will
        otherwise work unchanged with the Apache HTTP Server version 2.4.
        Some will require changes; see the <a href="developer/new_api_2_4.html">API
        update</a> overview.</p>
      </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="commonproblems" id="commonproblems">Common problems when upgrading</a></h2>
        
        <ul><li>Startup errors:
        <ul>
          <li><code>Invalid command 'User', perhaps misspelled or defined by a module not included in the server configuration</code> - load module <code class="module"><a href="./mod/mod_unixd.html">mod_unixd</a></code></li>
          <li><code>Invalid command 'Require', perhaps misspelled or defined by a module not included in the server configuration</code>, or
    <code>Invalid command 'Order', perhaps misspelled or defined by a module not included in the server configuration</code>
     - load module <code class="module"><a href="./mod/mod_access_compat.html">mod_access_compat</a></code>, or update configuration to 2.4 authorization directives.</li>
          <li><code>Ignoring deprecated use of DefaultType in line NN of /path/to/httpd.conf</code> - remove <code class="directive"><a href="./mod/core.html#defaulttype">DefaultType</a></code>
          and replace with other configuration settings.</li>
          <li><code>Invalid command 'AddOutputFilterByType', perhaps misspelled 
          or defined by a module not included in the server configuration
          </code> - <code class="directive"><a href="./mod/mod_filter.html#addoutputfilterbytype">AddOutputFilterByType</a></code> 
          has moved from the core to mod_filter, which must be loaded.</li>
        </ul></li>
        <li>Errors serving requests:
        <ul>
          <li><code>configuration error:  couldn't check user: /path</code> -
          load module <code class="module"><a href="./mod/mod_authn_core.html">mod_authn_core</a></code>.</li>
          <li><code>.htaccess</code> files aren't being processed - Check for an
          appropriate <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> directive;
          the default changed to <code>None</code> in 2.4.</li>
        </ul>
        </li>
    </ul>
      </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/upgrading.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/upgrading.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/upgrading.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>������������������httpd-2.4.64/docs/manual/install.html.en������������������������������������������������������������0000664�0001751�0001751�00000065737�14737241666�020026� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Compiling and Installing - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Compiling and Installing</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
    
        <p>This document covers compilation and installation of the Apache HTTP Server
        on Unix and Unix-like systems only. For compiling and
        installation on Windows, see <a href="platform/windows.html">Using Apache HTTP Server with Microsoft
        Windows</a> and <a href="platform/win_compiling.html">Compiling Apache for Microsoft Windows</a>.
        For other platforms, see the <a href="platform/">platform</a> documentation.</p>
    
        <p>Apache httpd uses <code>libtool</code> and <code>autoconf</code>
        to create a build environment that looks like many other Open Source
        projects.</p>
    
        <p>If you are upgrading from one minor version to the next (for
        example, 2.4.8 to 2.4.9), please skip down to the <a href="#upgrading">upgrading</a> section.</p>
    
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#overview">Overview for the
        impatient</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#requirements">Requirements</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#download">Download</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#extract">Extract</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#configure">Configuring the source tree</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#compile">Build</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">Install</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#customize">Customize</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#test">Test</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#upgrading">Upgrading</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#thirdp">Third-party packages</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="programs/configure.html">Configure the source tree</a></li><li><a href="invoking.html">Starting Apache httpd</a></li><li><a href="stopping.html">Stopping and Restarting</a></li><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="overview" id="overview">Overview for the
        impatient</a></h2>
    
        <dl>
        <dt>Installing on Fedora/CentOS/Red Hat Enterprise Linux</dt>
        <dd>
        <pre class="prettyprint lang-">sudo yum install httpd
    sudo systemctl enable httpd
    sudo systemctl start httpd</pre>
    
    
        <div class="warning">Newer releases of these distros use
        <code>dnf</code> rather than <code>yum</code>. See <a href="https://fedoraproject.org/wiki/Apache_HTTP_Server">the
        Fedora project's documentation</a> for platform-specific notes.</div>
        </dd>
    
        <dt>Installing on Ubuntu/Debian</dt>
        <dd>
    <pre class="prettyprint lang-">sudo apt install apache2
    sudo service apache2 start</pre>
    
    
        <div class="warning">See <a href="https://help.ubuntu.com/lts/serverguide/httpd.html">Ubuntu's documentation</a> for platform-specific notes.</div>
    
        </dd>
    
        <dt>Installing from source</dt>
        <dd>
        <table>
          
          <tr>
            <td><a href="#download">Download</a></td>
    
            <td>Download the latest release from <a href="http://httpd.apache.org/download.cgi#apache24">http://httpd.apache.org/download.cgi</a>
            </td>
          </tr>
    
          <tr>
            <td><a href="#extract">Extract</a></td>
    
            <td><code>$ gzip -d httpd-<em>NN</em>.tar.gz<br />
             $ tar xvf httpd-<em>NN</em>.tar<br />
             $ cd httpd-<em>NN</em></code></td>
          </tr>
    
          <tr>
            <td><a href="#configure">Configure</a></td>
    
            <td><code>$ ./configure --prefix=<em>PREFIX</em></code>
            </td>
          </tr>
    
          <tr>
            <td><a href="#compile">Compile</a></td>
    
            <td><code>$ make</code> </td>
          </tr>
    
          <tr>
            <td><a href="#install">Install</a></td>
    
            <td><code>$ make install</code> </td>
          </tr>
    
          <tr>
            <td><a href="#customize">Customize</a></td>
    
            <td><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code> </td>
          </tr>
    
          <tr>
            <td><a href="#test">Test</a></td>
    
            <td><code>$ <em>PREFIX</em>/bin/apachectl -k start</code>
            </td>
          </tr>
        </table>
    
            <p><em>NN</em> must be replaced with the current version
            number, and <em>PREFIX</em> must be replaced with the
            filesystem path under which the server should be installed. If
            <em>PREFIX</em> is not specified, it defaults to
            <code>/usr/local/apache2</code>.</p>
    
            <p>Each section of the compilation and installation process is
            described in more detail below, beginning with the requirements
            for compiling and installing Apache httpd.</p>
        </dd>
        </dl>
    
        <div class="warning">Don't see your favorite platform mentioned
        here? <a href="http://httpd.apache.org/docs-project/">Come help us
        improve this doc.</a></div>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="requirements" id="requirements">Requirements</a></h2>
    
        <p>The following requirements exist for building Apache httpd:</p>
    
        <dl>
          <dt>APR and APR-Util</dt>
          <dd>Make sure you have APR and APR-Util already installed on
          your system. If you don't, or prefer to not use the system-provided
          versions, download the latest versions of both APR and APR-Util
          from <a href="http://apr.apache.org/">Apache APR</a>, unpack
          them into <code>/httpd_source_tree_root/srclib/apr</code> and <code>/httpd_source_tree_root/srclib/apr-util</code>
          (be sure the directory names do not have version numbers; for example,
          the APR distribution must be under /httpd_source_tree_root/srclib/apr/) and use
          <code>./configure</code>'s <code>--with-included-apr</code>
          option.  On some platforms, you may have to install the
          corresponding <code>-dev</code> packages to allow httpd to build
          against your installed copy of APR and APR-Util.</dd>
    
          <dt>Perl-Compatible Regular Expressions Library (PCRE)</dt>
          <dd>This library is required but not longer bundled with httpd.
          Download the source code from <a href="http://www.pcre.org/">http://www.pcre.org</a>,
          or install a Port or Package.  If your build system can't find
          the pcre-config script installed by the PCRE build, point to it
          using the <code>--with-pcre</code> parameter.  On some platforms,
          you may have to install the corresponding <code>-dev</code>
          package to allow httpd to build against your installed copy
          of PCRE.</dd>
    
          <dt>Disk Space</dt>
          <dd>Make sure you have at least 50 MB of temporary free disk
          space available. After installation the server occupies
          approximately 10 MB of disk space. The actual disk space
          requirements will vary considerably based on your chosen
          configuration options, any third-party modules, and, of course,
          the size of the web site or sites that you have on the server.</dd>
    
          <dt>ANSI-C Compiler and Build System</dt>
          <dd>Make sure you have an ANSI-C compiler installed. The <a href="http://gcc.gnu.org/">GNU C
          compiler (GCC)</a> from the <a href="http://www.gnu.org/">Free Software Foundation (FSF)</a>
          is recommended. If you don't have GCC
          then at least make sure your vendor's compiler is ANSI
          compliant. In addition, your <code>PATH</code> must contain
          basic build tools such as <code>make</code>.</dd>
    
          <dt>Accurate time keeping</dt>
          <dd>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
          <code>ntpdate</code> or <code>xntpd</code> programs are used for
          this purpose which are based on the Network Time Protocol (NTP).
          See the <a href="http://www.ntp.org">NTP
          homepage</a> for more details about NTP software and public
          time servers.</dd>
    
          <dt><a href="http://www.perl.org/">Perl 5</a>
          [OPTIONAL]</dt>
          <dd>For some of the support scripts like <code class="program"><a href="./programs/apxs.html">apxs</a></code> or <code class="program"><a href="./programs/dbmmanage.html">dbmmanage</a></code> (which are
          written in Perl) the Perl 5 interpreter is required (versions
          5.003 or newer are sufficient).  If no Perl 5 interpreter is found by the
          <code class="program"><a href="./programs/configure.html">configure</a></code> script, you will not be able to use
          the affected support scripts. Of course, you will still be able to
          build and use Apache httpd.</dd>
        </dl>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="download" id="download">Download</a></h2>
    
        <p>The Apache HTTP Server can be downloaded from the <a href="http://httpd.apache.org/download.cgi">Apache HTTP Server
        download site</a>, 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 <code>INSTALL.bindist</code> file inside the distribution.</p>
    
        <p>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 <a href="http://httpd.apache.org/download.cgi#verify">download
        page</a> and an extended example is available describing the <a href="http://httpd.apache.org/dev/verification.html">use of
        PGP</a>.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="extract" id="extract">Extract</a></h2>
    
        <p>Extracting the source from the Apache HTTP Server tarball is a
        simple matter of uncompressing, and then untarring:</p>
    
    <div class="example"><p><code>
    $ gzip -d httpd-<em>NN</em>.tar.gz<br />
    $ tar xvf httpd-<em>NN</em>.tar
    </code></p></div>
    
        <p>This will create a new directory under the current directory
        containing the source code for the distribution. You should
        <code>cd</code> into that directory before proceeding with
        compiling the server.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="configure" id="configure">Configuring the source tree</a></h2>
    
        <p>The next step is to configure the Apache source tree for your
        particular platform and personal requirements. This is done using
        the script <code class="program"><a href="./programs/configure.html">configure</a></code> included in
        the root directory of the distribution. (Developers downloading
        an unreleased version of the Apache source tree will need to have
        <code>autoconf</code> and <code>libtool</code> installed and will
        need to run <code>buildconf</code> before proceeding with the next
        steps. This is not necessary for official releases.)</p>
    
        <p>To configure the source tree using all the default options,
        simply type <code>./configure</code>. To change the default
        options, <code class="program"><a href="./programs/configure.html">configure</a></code> accepts a variety of variables
        and command line options.</p>
    
        <p>The most important option is the location <code>--prefix</code>
        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 <a href="programs/configure.html#installationdirectories">configure
        options</a>.</p>
    
        <p>Also at this point, you can specify which <a href="programs/configure.html#optionalfeatures">features</a> you
        want included in Apache by enabling and disabling <a href="mod/">modules</a>.  Apache comes with a wide range of modules
        included by default.  They will be compiled as
        <a href="dso.html">shared objects (DSOs)</a> which can be loaded
        or unloaded at runtime.
        You can also choose to compile modules statically by using the option
        <code>--enable-<var>module</var>=static</code>.</p>
    
        <p>Additional modules are enabled using the
        <code>--enable-<var>module</var></code> option, where
        <var>module</var> is the name of the module with the
        <code>mod_</code> string removed and with any underscore converted
        to a dash.  Similarly, you can disable modules with the
        <code>--disable-<var>module</var></code> option.  Be careful when
        using these options, since <code class="program"><a href="./programs/configure.html">configure</a></code> cannot warn you
        if the module you specify does not exist; it will simply ignore the
        option.</p>
    
        <p>In addition, it is sometimes necessary to provide the
        <code class="program"><a href="./programs/configure.html">configure</a></code> 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 <code class="program"><a href="./programs/configure.html">configure</a></code>.  For more information, see the
        <code class="program"><a href="./programs/configure.html">configure</a></code> manual page. Or invoke
        <code class="program"><a href="./programs/configure.html">configure</a></code> using the <code>--help</code> option.</p>
    
        <p>For a short impression of what possibilities you have, here
        is a typical example which compiles Apache for the installation
        tree <code>/sw/pkg/apache</code> with a particular compiler and flags
        plus the two additional modules <code class="module"><a href="./mod/mod_ldap.html">mod_ldap</a></code> and
        <code class="module"><a href="./mod/mod_lua.html">mod_lua</a></code>:</p>
    
    <div class="example"><p><code>
          $ CC="pgcc" CFLAGS="-O2" \<br />
           ./configure --prefix=/sw/pkg/apache \<br />
           --enable-ldap=shared \<br />
           --enable-lua=shared
    </code></p></div>
    
        <p>When <code class="program"><a href="./programs/configure.html">configure</a></code> 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.</p>
    
        <p>Details on all the different <code class="program"><a href="./programs/configure.html">configure</a></code> options are
        available on the <code class="program"><a href="./programs/configure.html">configure</a></code> manual page.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="compile" id="compile">Build</a></h2>
    
        <p>Now you can build the various parts which form the Apache
        package by simply running the command:</p>
    
    <div class="example"><p><code>$ make</code></p></div>
    
        <p>Please be patient here, since a base configuration takes
        several minutes to compile and the time will vary widely
        depending on your hardware and the number of modules that you
        have enabled.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">Install</a></h2>
    
        <p>Now it's time to install the package under the configured
        installation <em>PREFIX</em> (see <code>--prefix</code> option
        above) by running:</p>
    
    <div class="example"><p><code>$ make install</code></p></div>
    
        <p>This step will typically require root privileges, since
        <em>PREFIX</em> is usually a directory with restricted write
        permissions.</p>
    
        <p>If you are upgrading, the installation will not overwrite
        your configuration files or documents.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="customize" id="customize">Customize</a></h2>
    
        <p>Next, you can customize your Apache HTTP server by editing
        the <a href="configuring.html">configuration files</a> under
        <code><em>PREFIX</em>/conf/</code>.</p>
    
    <div class="example"><p><code>$ vi <em>PREFIX</em>/conf/httpd.conf</code></p></div>
    
        <p>Have a look at the Apache manual under
        <code><em>PREFIX</em>/docs/manual/</code> or consult <a href="http://httpd.apache.org/docs/2.4/">http://httpd.apache.org/docs/2.4/</a> for the most recent
        version of this manual and a complete reference of available <a href="mod/directives.html">configuration directives</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="test" id="test">Test</a></h2>
    
        <p>Now you can <a href="invoking.html">start</a> your Apache
        HTTP server by immediately running:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k start</code></p></div>
    
        <p>You should then be able to request your first document
        via the URL <code>http://localhost/</code>. The web page you see is located
        under the <code class="directive"><a href="./mod/core.html#documentroot">DocumentRoot</a></code>,
        which will usually be <code><em>PREFIX</em>/htdocs/</code>.
        Then <a href="stopping.html">stop</a> the server again by
        running:</p>
    
    <div class="example"><p><code>$ <em>PREFIX</em>/bin/apachectl -k stop</code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="upgrading" id="upgrading">Upgrading</a></h2>
    
        <p>The first step in upgrading is to read the release announcement
        and the file <code>CHANGES</code> in the source distribution to
        find any changes that may affect your site.  When changing between
        major releases (for example, from 2.0 to 2.2 or from 2.2 to 2.4),
        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 accommodate changes in the
        module API.</p>
    
        <p>Upgrading from one minor version to the next (for example, from
        2.2.55 to 2.2.57) is easier.  The <code>make install</code>
        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
        <code class="program"><a href="./programs/configure.html">configure</a></code> options, run-time configuration, or the
        module API between minor versions.  In most cases you should be able to
        use an identical <code class="program"><a href="./programs/configure.html">configure</a></code> command line, an identical
        configuration file, and all of your modules should continue to
        work.</p>
    
        <p>To upgrade across minor versions, start by finding the file
        <code>config.nice</code> in the <code>build</code> directory of
        your installed server or at the root of the source tree for your
        old install.  This will contain the exact
        <code class="program"><a href="./programs/configure.html">configure</a></code> command line that you used to
        configure the source tree.  Then to upgrade from one version to
        the next, you need only copy the <code>config.nice</code> file to
        the source tree of the new version, edit it to make any desired
        changes, and then run:</p>
    
        <div class="example"><p><code>
        $ ./config.nice<br />
        $ make<br />
        $ make install<br />
        $ <em>PREFIX</em>/bin/apachectl -k graceful-stop<br />
        $ <em>PREFIX</em>/bin/apachectl -k start<br />
        </code></p></div>
    
        <div class="warning">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 <code>--prefix</code> and a
        different port (by adjusting the <code class="directive"><a href="./mod/mpm_common.html#listen">Listen</a></code> directive) to test for any
        incompatibilities before doing the final upgrade.</div>
    
        <p>You can pass additional arguments to <code>config.nice</code>,
        which will be appended to your original <code class="program"><a href="./programs/configure.html">configure</a></code>
        options:</p>
    
        <div class="example"><p><code>
        $ ./config.nice --prefix=/home/test/apache --with-port=90
        </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="thirdp" id="thirdp">Third-party packages</a></h2>
    
        <p>A large number of third parties provide their own packaged
        distributions of the Apache HTTP Server for installation on
        particular platforms. This includes the various Linux distributions,
        various third-party Windows packages, Mac OS X, Solaris, and many
        more.</p>
    
        <p>Our software license not only permits, but encourages, this kind
        of redistribution. However, it does result in a situation where the
        configuration layout and defaults on your installation of the server
        may differ from what is stated in the documentation. While
        unfortunate, this situation is not likely to change any time
        soon.</p>
    
        <p>A <a href="http://wiki.apache.org/httpd/DistrosDefaultLayout">description
        of these third-party distributions</a> is maintained in the HTTP
        Server wiki, and should reflect the current state of these
        third-party distributions. However, you will need to familiarize
        yourself with your particular platform's package management and
        installation procedures.</p>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./de/install.html" hreflang="de" rel="alternate" title="Deutsch">&nbsp;de&nbsp;</a> |
    <a href="./en/install.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./es/install.html" hreflang="es" rel="alternate" title="Español">&nbsp;es&nbsp;</a> |
    <a href="./fr/install.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/install.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/install.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>���������������������������������httpd-2.4.64/docs/manual/sections.html.en�����������������������������������������������������������0000664�0001751�0001751�00000113012�14737241666�020163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>Configuration Sections - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>Configuration Sections</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/sections.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
     <p>Directives in the <a href="configuring.html">configuration files</a> 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 <code>.htaccess</code> files
    to change the scope of other configuration directives.</p>
    </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#types">Types of Configuration Section Containers</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#file-and-web">Filesystem, Webspace, and Boolean Expressions</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#virtualhost">Virtual Hosts</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#proxy">Proxy</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#whatwhere">What Directives are Allowed?</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#merging">How the sections are merged</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="types" id="types">Types of Configuration Section Containers</a></h2>
    
    <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="./mod/core.html">core</a></code></li><li><code class="module"><a href="./mod/mod_version.html">mod_version</a></code></li><li><code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code></li></ul></td><td><ul><li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_md.html#mdomainsetsection">&lt;MDomainSet&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code></li><li><code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code></li><li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code></li></ul></td></tr></table>
    
    <p>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 <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>, <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>, and
    <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
    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.</p>
    
    <p>The <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> directive
    encloses directives that will only be applied if an appropriate
    parameter is defined on the <code class="program"><a href="./programs/httpd.html">httpd</a></code> command line.  For example,
    with the following configuration, all requests will be redirected
    to another site only if the server is started using
    <code>httpd -DClosedForNow</code>:</p>
    
    <pre class="prettyprint lang-config">&lt;IfDefine ClosedForNow&gt;
        Redirect "/" "http://otherserver.example.com/"
    &lt;/IfDefine&gt;</pre>
    
    
    <p>The <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>
    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 <code class="directive"><a href="./mod/mod_so.html#loadmodule">LoadModule</a></code> 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.</p>
    
    <p>In the following example, the <code class="directive"><a href="./mod/mod_mime_magic.html#mimemagicfile">MimeMagicFile</a></code> directive will be
    applied only if <code class="module"><a href="./mod/mod_mime_magic.html">mod_mime_magic</a></code> is available.</p>
    
    <pre class="prettyprint lang-config">&lt;IfModule mod_mime_magic.c&gt;
        MimeMagicFile "conf/magic"
    &lt;/IfModule&gt;</pre>
    
    
    <p>The <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
    directive is very similar to <code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code> and <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>, except it encloses directives that will
    only be applied if a particular version of the server is executing.  This
    module is designed for the use in test suites and large networks which have to
    deal with different httpd versions and different configurations.</p>
    
    <pre class="prettyprint lang-config">&lt;IfVersion &gt;= 2.4&gt;
        # this happens only in versions greater or
        # equal 2.4.0.
    &lt;/IfVersion&gt;</pre>
    
    
    <p><code class="directive"><a href="./mod/core.html#ifdefine">&lt;IfDefine&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#ifmodule">&lt;IfModule&gt;</a></code>, and the
    <code class="directive"><a href="./mod/mod_version.html#ifversion">&lt;IfVersion&gt;</a></code>
    can apply negative conditions by preceding their test with "!".
    Also, these sections can be nested to achieve more complex
    restrictions.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="file-and-web" id="file-and-web">Filesystem, Webspace, and Boolean Expressions</a></h2>
    
    <p>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 httpd resides at <code>/usr/local/apache2</code> in the Unix
    filesystem or <code>"c:/Program Files/Apache Group/Apache2"</code> in
    the Windows filesystem.  (Note that forward slashes should always be
    used as the path separator in Apache httpd configuration files, 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 <code>/dir/</code> in the
    webspace corresponds to the path
    <code>/usr/local/apache2/htdocs/dir/</code> in the filesystem of a
    default Apache httpd install on Unix.  The webspace need not map directly to
    the filesystem, since webpages may be generated dynamically
    from databases or other locations.</p>
    
    <h3><a name="filesystem" id="filesystem">Filesystem Containers</a></h3>
    
    <p>The <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    and <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    directives, along with their <a class="glossarylink" href="./glossary.html#regex" title="see glossary">regex</a>
    counterparts, apply directives to
    parts of the filesystem.  Directives enclosed in a <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> section apply to
    the named filesystem directory and all subdirectories of that
    directory (as well as the files in those directories).
    The same effect can be obtained using <a href="howto/htaccess.html">.htaccess files</a>.  For example, in the
    following configuration, directory indexes will be enabled for the
    <code>/var/web/dir1</code> directory and all subdirectories.</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/web/dir1"&gt;
        Options +Indexes
    &lt;/Directory&gt;</pre>
    
    
    <p>Directives enclosed in a <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> 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 <code>private.html</code> regardless
    of where it is found.</p>
    
    <pre class="prettyprint lang-config">&lt;Files "private.html"&gt;
        Require all denied
    &lt;/Files&gt;</pre>
    
    
    <p>To address files found in a particular part of the filesystem, the
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> and
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> sections
    can be combined.  For example, the following configuration will deny
    access to <code>/var/web/dir1/private.html</code>,
    <code>/var/web/dir1/subdir2/private.html</code>,
    <code>/var/web/dir1/subdir3/private.html</code>, and any other instance
    of <code>private.html</code> found under the <code>/var/web/dir1/</code>
    directory.</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/var/web/dir1"&gt;
        &lt;Files "private.html"&gt;
            Require all denied
        &lt;/Files&gt;
    &lt;/Directory&gt;</pre>
    
    
    
    <h3><a name="webspace" id="webspace">Webspace Containers</a></h3>
    
    <p>The <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    directive and its <a class="glossarylink" href="./glossary.html#regex" title="see glossary">regex</a> 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
    <code>http://yoursite.example.com/private</code>,
    <code>http://yoursite.example.com/private123</code>, and
    <code>http://yoursite.example.com/private/dir/file.html</code> as well
    as any other requests starting with the <code>/private</code> string.</p>
    
    <pre class="prettyprint lang-config">&lt;LocationMatch "^/private"&gt;
        Require all denied
    &lt;/LocationMatch&gt;</pre>
    
    
    <p>The <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    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 HTTP Server handler provided by <code class="module"><a href="./mod/mod_status.html">mod_status</a></code>.
    No file called <code>server-status</code> needs to exist in the
    filesystem.</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/server-status"&gt;
        SetHandler server-status
    &lt;/Location&gt;</pre>
    
    
    
    <h3><a name="overlapping-webspace" id="overlapping-webspace">Overlapping Webspace</a></h3>
    <p>In order to have two overlapping URLs one has to consider the order in which
    certain sections or directives are evaluated. For
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> this would be:</p>
    <pre class="prettyprint lang-config">&lt;Location "/foo"&gt;
    &lt;/Location&gt;
    &lt;Location "/foo/bar"&gt;
    &lt;/Location&gt;</pre>
    
    <p><code class="directive"><a href="./mod/mod_alias.html#alias">&lt;Alias&gt;</a></code>es on the other hand,
    are mapped vice-versa:</p>
    <pre class="prettyprint lang-config">Alias "/foo/bar" "/srv/www/uncommon/bar"
    Alias "/foo"     "/srv/www/common/foo"</pre>
    
    <p>The same is true for the <code class="directive"><a href="./mod/mod_proxy.html#proxypass">ProxyPass</a></code>
    directives:</p>
    <pre class="prettyprint lang-config">ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
    ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On</pre>
    
    
    
    <h3><a name="wildcards" id="wildcards">Wildcards and Regular Expressions</a></h3>
    
    <p>The <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>, and
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
    directives can each use shell-style wildcard characters as in
    <code>fnmatch</code> from the C standard library.  The character "*"
    matches any sequence of characters, "?" matches any single character,
    and "[<em>seq</em>]" matches any character in <em>seq</em>.  The "/"
    character will not be matched by any wildcard; it must be specified
    explicitly.</p>
    
    <p>If even more flexible matching is required, each
    container has a regular expression (regex) counterpart <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>, <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>, and <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> that allow
    perl-compatible
    <a class="glossarylink" href="./glossary.html#regex" title="see glossary">regular expressions</a>
    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.</p>
    
    <p>A non-regex wildcard section that changes the configuration of
    all user directories could look as follows:</p>
    
    <pre class="prettyprint lang-config">&lt;Directory "/home/*/public_html"&gt;
        Options Indexes
    &lt;/Directory&gt;</pre>
    
    
    <p>Using regex sections, we can deny access to many types of image files
    at once:</p>
    <pre class="prettyprint lang-config">&lt;FilesMatch "\.(?i:gif|jpe?g|png)$"&gt;
        Require all denied
    &lt;/FilesMatch&gt;</pre>
    
    
    <p>Regular expressions containing <strong>named groups and
    backreferences</strong> are added to the environment with the
    corresponding name in uppercase. This allows elements of filename paths
    and URLs to be referenced from within <a href="expr.html">expressions</a>
    and modules like <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>.</p>
    
    <pre class="prettyprint lang-config">&lt;DirectoryMatch "^/var/www/combined/(?&lt;SITENAME&gt;[^/]+)"&gt;
        Require ldap-group "cn=%{env:MATCH_SITENAME},ou=combined,o=Example"
    &lt;/DirectoryMatch&gt;</pre>
    
    
    
    
    <h3><a name="expressions" id="expressions">Boolean expressions</a></h3>
    <p>The <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>
    directive change the configuration depending on a condition which can be
    expressed by a boolean expression. For example, the following configuration
    denies access if the HTTP Referer header does not start with
    "http://www.example.com/".</p>
    <pre class="prettyprint lang-config">&lt;If "!(%{HTTP_REFERER} -strmatch 'http://www.example.com/*')"&gt;
        Require all denied
    &lt;/If&gt;</pre>
    
    
    
    
    <h3><a name="whichwhen" id="whichwhen">What to use When</a></h3>
    
    <p>Choosing between filesystem containers and webspace containers is
    actually quite easy.  When applying directives to objects that reside
    in the filesystem always use <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> or <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>.  When applying directives to objects
    that do not reside in the filesystem (such as a webpage generated from
    a database), use <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>.</p>
    
    <p>It is important to never use <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> 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:</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/dir/"&gt;
        Require all denied
    &lt;/Location&gt;</pre>
    
    
    <p>This works fine if the request is for
    <code>http://yoursite.example.com/dir/</code>.  But what if you are on
    a case-insensitive filesystem?  Then your restriction could be easily
    circumvented by requesting
    <code>http://yoursite.example.com/DIR/</code>.  The <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> 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 <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> 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
    <code class="directive"><a href="./mod/core.html#options">Options</a></code> directive.)</p>
    
    <p>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 <code>&lt;Location
    "/"&gt;</code> section is perfectly safe because this section will apply
    to all requests regardless of the specific URL.</p>
    
    
    <h3><a name="nesting" id="nesting">Nesting of sections</a></h3>
    
    <p>Some section types can be nested inside other section types. On the one
    hand, <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> can be used
    inside <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>.  On
    the other hand, <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> can
    be used inside <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>, and <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> sections (but not inside another
    <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>). The regex
    counterparts of the named section behave identically.</p>
    
    <p>Nested sections are merged after non-nested sections of the same type.</p>
    
    
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="virtualhost" id="virtualhost">Virtual Hosts</a></h2>
    
    <p>The <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
    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 <a href="vhosts/">Virtual Host Documentation</a>.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="proxy" id="proxy">Proxy</a></h2>
    
    <p>The <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
    and <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
    containers apply enclosed configuration directives only
    to sites accessed through <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>'s proxy server
    that match the specified URL. For example, the following configuration
    will allow only a subset of clients to access the
    <code>www.example.com</code> website using the proxy server:</p>
    
    <pre class="prettyprint lang-config">&lt;Proxy "http://www.example.com/*"&gt;
        Require host yournetwork.example.com
    &lt;/Proxy&gt;</pre>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="whatwhere" id="whatwhere">What Directives are Allowed?</a></h2>
    
    <p>To find out what directives are allowed in what types of
    configuration sections, check the <a href="mod/directive-dict.html#Context">Context</a> of the directive.
    Everything that is allowed in
    <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    sections is also syntactically allowed in
    <code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>,
    <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>,
    <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>,
    and <code class="directive"><a href="./mod/mod_proxy.html#proxymatch">&lt;ProxyMatch&gt;</a></code>
    sections.  There are some exceptions, however:</p>
    
    <ul>
    <li>The <code class="directive"><a href="./mod/core.html#allowoverride">AllowOverride</a></code> directive
    works only in <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
    sections.</li>
    
    <li>The <code>FollowSymLinks</code> and
    <code>SymLinksIfOwnerMatch</code> <code class="directive"><a href="./mod/core.html#options">Options</a></code> work only in <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> sections or
    <code>.htaccess</code> files.</li>
    
    <li>The <code class="directive"><a href="./mod/core.html#options">Options</a></code> directive cannot
    be used in <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code>
    and <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code>
    sections.</li>
    </ul>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="merging" id="merging">How the sections are merged</a></h2>
    
    <p>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.</p>
    
        <p>The order of merging is:</p>
    
        <ol>
          <li> <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> (except regular expressions)
          and <code>.htaccess</code> done simultaneously (with
          <code>.htaccess</code>, if allowed, overriding
          <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>)</li>
    
          <li><code class="directive"><a href="./mod/core.html#directorymatch">&lt;DirectoryMatch&gt;</a></code>
          (and <code>&lt;Directory "~"&gt;</code>)</li>
    
          <li><code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> and <code class="directive"><a href="./mod/core.html#filesmatch">&lt;FilesMatch&gt;</a></code> done
          simultaneously</li>
    
          <li><code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code>
          and <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code> done simultaneously</li>
    
          <li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> sections, even when
          they are enclosed in any of the preceding contexts.
          </li>
    
        </ol>
    
        <p>Some important remarks:</p>
        <ul>
            <li>Apart from <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, within each group the sections are
            processed in the order they appear in the configuration files.
            For example, a request for <em>/foo/bar</em> will match
            <code>&lt;Location "/foo/bar"&gt;</code> and 
            <code>&lt;Location "/foo"&gt;</code> (group 4 in this case):
            both sections will be evaluated
            but in the order they appear in the configuration files.</li>
            <li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
            (group 1 above) is processed in the order shortest directory
            component to longest. For example,
            <code>&lt;Directory "/var/web/dir"&gt;</code> will be processed before
            <code>&lt;Directory "/var/web/dir/subdir"&gt;</code>.</li>
            <li>If multiple <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> sections apply
            to the same directory they are processed in the configuration file
            order.</li>
            <li>Configurations included via the <code class="directive"><a href="./mod/core.html#include">Include</a></code> directive will be treated as if
            they were inside the including file at the location of the
            <code class="directive"><a href="./mod/core.html#include">Include</a></code> directive.</li>
            <li>Sections inside <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> sections
            are applied <em>after</em> the corresponding sections outside
            the virtual host definition. This allows virtual hosts to
            override the main server configuration.</li>
            <li>When the request is served by <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code>, the
            <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code>
            container takes the place of the <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> container in the processing
            order.</li>
            <li> Caution should be exercised when mixing related configuration
            directives inside and outside of <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> because of the effect on merging order.  Explicit use
            of <code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code> can help.
            </li>
            <li> When <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> is 
            used in <code>.htaccess</code>, the enclosed directives in a parent 
            directory will be merged <em>after</em> non-enclosed directives in a 
            subdirectory.</li>
        </ul>
    
        <div class="note"><h3>Technical Note</h3>
          There is actually a
          <code>&lt;Location&gt;</code>/<code>&lt;LocationMatch&gt;</code>
          sequence performed just before the name translation phase
          (where <code>Aliases</code> and <code>DocumentRoots</code>
          are used to map URLs to filenames). The results of this
          sequence are completely thrown away after the translation has
          completed.
        </div>
    
    <h3><a name="relationship-module-configuration" id="relationship-module-configuration">Relationship between modules and configuration sections</a></h3>
        <p>One question that often arises after reading how configuration sections are
        merged is related to how and when directives of specific modules like <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
        are processed. The answer is not trivial and needs a bit of background. 
        Each httpd module manages its own configuration, and each of its directives in httpd.conf specify one piece 
        of configuration in a particular context. httpd does not execute a command as it is read.</p>
        <p>At runtime, the core of httpd iterates over the defined configuration sections in the order
        described above to determine which ones apply to the current request. When the first section matches, 
        it is considered the current configuration for this request. If a subsequent section matches too, 
        then each module with a directive in either of the sections is given a chance to merge its configuration between the two sections. The result is a third configuration, and the process goes on until all the configuration sections
        are evaluated.</p>
        <p>After the above step, the "real" processing of the HTTP request begins: each module has a chance to run 
        and perform whatever tasks they like. They can retrieve their own final merged configuration from the core
        of the httpd to determine how they should act.</p>
        <p>An example can help to visualize the whole process. The following configuration uses the 
            <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> directive of <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> to set
            a specific HTTP header. What value will httpd set in the <code>CustomHeaderName</code> header for a request to
            <code>/example/index.html</code> ?
        </p>
        <pre class="prettyprint lang-config">&lt;Directory "/"&gt;
        Header set CustomHeaderName one
        &lt;FilesMatch ".*"&gt;
            Header set CustomHeaderName three
        &lt;/FilesMatch&gt;
    &lt;/Directory&gt;
    
    &lt;Directory "/example"&gt;
        Header set CustomHeaderName two
    &lt;/Directory&gt;</pre>
        
        <ul>
            <li><code class="directive">Directory</code> "/" matches and an initial configuration to set the <code>CustomHeaderName</code> header with the value <code>one</code> is created.</li>
            <li><code class="directive">Directory</code> "/example" matches, and since <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> specifies in its code to override in case of a merge, a new configuration is created to set the <code>CustomHeaderName</code> header with the value <code>two</code>.</li>
            <li><code class="directive">FilesMatch</code> ".*" matches and another merge opportunity arises, causing the <code>CustomHeaderName</code> header to be set with the value <code>three</code>.</li>
            <li>Eventually during the next steps of the HTTP request processing <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> will be called and it will receive the configuration to set the <code>CustomHeaderName</code> header with the value <code>three</code>. <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> normally uses this configuration to perform its job, namely setting the foo header. This does not mean that a module can't perform a more complex action like discarding directives because not needed or deprecated, etc..</li>
        </ul>
    
        <p>This is true for .htaccess too since they have the same priority as <code class="directive">Directory</code> in the merge order. The important concept to understand is that configuration sections like  <code class="directive">Directory</code> and <code class="directive">FilesMatch</code> are not comparable to module specific directives like <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> or <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> because they operate on different levels.
        </p>
    
    
    <h3><a name="merge-examples" id="merge-examples">Some useful examples</a></h3>
    
    <p>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 &gt; B &gt; C &gt; D &gt;
    E.</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/"&gt;
        E
    &lt;/Location&gt;
    
    &lt;Files "f.html"&gt;
        D
    &lt;/Files&gt;
    
    &lt;VirtualHost *&gt;
        &lt;Directory "/a/b"&gt;
            B
        &lt;/Directory&gt;
    &lt;/VirtualHost&gt;
    
    &lt;DirectoryMatch "^.*b$"&gt;
        C
    &lt;/DirectoryMatch&gt;
    
    &lt;Directory "/a/b"&gt;
        A
    &lt;/Directory&gt;</pre>
    
    
    
    <p>For a more concrete example, consider the following.  Regardless of
    any access restrictions placed in <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> sections, the <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> section will be
    evaluated last and will allow unrestricted access to the server.  In
    other words, order of merging is important, so be careful!</p>
    
    <pre class="prettyprint lang-config">&lt;Location "/"&gt;
        Require all granted
    &lt;/Location&gt;
    
    # Whoops!  This &lt;Directory&gt; section will have no effect
    &lt;Directory "/"&gt;
        &lt;RequireAll&gt;
            Require all granted
            Require not host badguy.example.com
        &lt;/RequireAll&gt;
    &lt;/Directory&gt;</pre>
    
    
    
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/sections.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/sections.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/sections.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/sections.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/sections.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/suexec.html.en�������������������������������������������������������������0000664�0001751�0001751�00000071074�14737241666�017643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <!--
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  This file is generated from xml source: DO NOT EDIT
            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
          -->
    <title>suEXEC Support - Apache HTTP Server Version 2.4</title>
    <link href="./style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
    <link href="./style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
    <link href="./style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="./style/css/prettify.css" />
    <script src="./style/scripts/prettify.min.js" type="text/javascript">
    </script>
    
    <link href="./images/favicon.ico" rel="shortcut icon" /></head>
    <body id="manual-page"><div id="page-header">
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p>
    <p class="apache">Apache HTTP Server Version 2.4</p>
    <img alt="" src="./images/feather.png" /></div>
    <div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="./images/left.gif" /></a></div>
    <div id="path">
    <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="./">Version 2.4</a></div><div id="page-content"><div id="preamble"><h1>suEXEC Support</h1>
    <div class="toplang">
    <p><span>Available Languages: </span><a href="./en/suexec.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div>
    
        <p>The <strong>suEXEC</strong> feature provides users of the Apache
        HTTP Server the ability
        to run <strong>CGI</strong> and <strong>SSI</strong> 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.</p>
    
        <p>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 <em>setuid root</em> programs
        and the security issues they present, we highly recommend that
        you not consider using suEXEC.</p>
      </div>
    <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="./images/down.gif" /> <a href="#before">Before we begin</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#model">suEXEC Security Model</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#install">Configuring &amp; Installing
        suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#enable">Enabling &amp; Disabling
        suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#usage">Using suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#debug">Debugging suEXEC</a></li>
    <li><img alt="" src="./images/down.gif" /> <a href="#jabberwock">Beware the Jabberwock:
        Warnings &amp; Examples</a></li>
    </ul><h3>See also</h3><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
    <div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="before" id="before">Before we begin</a></h2>
    
        <p>Before jumping head-first into this document,
        you should be aware that certain assumptions are made about you and
        the environment in which you will be using suexec.</p>
    
        <p>First, it is assumed that you are using a UNIX
        derivative operating system that is capable of
        <strong>setuid</strong> and <strong>setgid</strong> operations.
        All command examples are given in this regard. Other platforms,
        if they are capable of supporting suEXEC, may differ in their
        configuration.</p>
    
        <p>Second, it is assumed you are familiar with
        some basic concepts of your computer's security and its
        administration. This involves an understanding of
        <strong>setuid/setgid</strong> operations and the various
        effects they may have on your system and its level of
        security.</p>
    
        <p>Third, it is assumed that you are using an
        <strong>unmodified</strong> 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 <strong>highly</strong> 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 HTTP Server development team for consideration.</p>
    
        <p>Fourth, and last, it has been the decision of
        the Apache HTTP Server development team to <strong>NOT</strong> make suEXEC part of
        the default installation of Apache httpd. 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 we hope to limit suEXEC
        installation only to those who are careful and determined
        enough to use it.</p>
    
        <p>Still with us? Yes? Good. Let's move on!</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="model" id="model">suEXEC Security Model</a></h2>
    
        <p>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.</p>
    
        <p><strong>suEXEC</strong> is based on a setuid
        "wrapper" program that is called by the main Apache HTTP 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 httpd provides the suEXEC wrapper with the
        program's name and the user and group IDs under which the
        program is to execute.</p>
    
        <p>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:</p>
    
        <ol>
          <li>
            <strong>Is the user executing this wrapper a valid user of
            this system?</strong>
    
            <p class="indent">
              This is to ensure that the user executing the wrapper is
              truly a user of the system.
            </p>
         </li>
    
         <li>
            <strong>Was the wrapper called with the proper number of
            arguments?</strong>
    
            <p class="indent">
              The wrapper will only execute if it is given the proper
              number of arguments. The proper argument format is known
              to the Apache HTTP 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 httpd binary.
            </p>
          </li>
    
          <li>
            <strong>Is this valid user allowed to run the
            wrapper?</strong>
    
            <p class="indent">
              Is this user the user allowed to run this wrapper? Only
              one user (the Apache user) is allowed to execute this
              program.
            </p>
          </li>
    
          <li>
            <strong>Does the target CGI or SSI program have an unsafe
            hierarchical reference?</strong>
    
            <p class="indent">
              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 <code>--with-suexec-docroot=<em>DIR</em></code>
              below).
            </p>
          </li>
    
          <li>
            <strong>Is the target user name valid?</strong>
    
            <p class="indent">
              Does the target user exist?
            </p>
          </li>
    
          <li>
            <strong>Is the target group name valid?</strong>
    
            <p class="indent">
              Does the target group exist?
            </p>
          </li>
    
          <li>
            <strong>Is the target user <em>NOT</em> superuser?</strong>
    
    
            <p class="indent">
              suEXEC does not allow <code><em>root</em></code>
              to execute CGI/SSI programs.
            </p>
          </li>
    
          <li>
            <strong>Is the target userid <em>ABOVE</em> the minimum ID
            number?</strong>
    
            <p class="indent">
              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.
            </p>
          </li>
    
          <li>
            <strong>Is the target group <em>NOT</em> the superuser
            group?</strong>
    
            <p class="indent">
              Presently, suEXEC does not allow the <code><em>root</em></code>
              group to execute CGI/SSI programs.
            </p>
          </li>
    
          <li>
            <strong>Is the target groupid <em>ABOVE</em> the minimum ID
            number?</strong>
    
            <p class="indent">
              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.
            </p>
          </li>
    
          <li>
            <strong>Can the wrapper successfully become the target user
            and group?</strong>
    
            <p class="indent">
              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.
            </p>
          </li>
    
          <li>
            <strong>Can we change directory to the one in which the target
            CGI/SSI program resides?</strong>
    
            <p class="indent">
              If it doesn't exist, it can't very well contain files. If we
              can't change directory to it, it might as well not exist.
            </p>
          </li>
    
          <li>
            <strong>Is the directory within the httpd webspace?</strong>
    
            <p class="indent">
              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 <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>, is the requested directory
              within the directory configured as suEXEC's userdir (see
              <a href="#install">suEXEC's configuration options</a>)?
            </p>
          </li>
    
          <li>
            <strong>Is the directory <em>NOT</em> writable by anyone
            else?</strong>
    
            <p class="indent">
              We don't want to open up the directory to others; only
              the owner user may be able to alter this directories
              contents.
            </p>
          </li>
    
          <li>
            <strong>Does the target CGI/SSI program exist?</strong>
    
            <p class="indent">
              If it doesn't exists, it can't very well be executed.
            </p>
          </li>
    
          <li>
            <strong>Is the target CGI/SSI program <em>NOT</em> writable
            by anyone else?</strong>
    
            <p class="indent">
              We don't want to give anyone other than the owner the
              ability to change the CGI/SSI program.
            </p>
          </li>
    
          <li>
            <strong>Is the target CGI/SSI program <em>NOT</em> setuid or
            setgid?</strong>
    
            <p class="indent">
              We do not want to execute programs that will then change
              our UID/GID again.
            </p>
          </li>
    
          <li>
            <strong>Is the target user/group the same as the program's
            user/group?</strong>
    
            <p class="indent">
              Is the user the owner of the file?
            </p>
          </li>
    
          <li>
            <strong>Can we successfully clean the process environment
            to ensure safe operations?</strong>
    
            <p class="indent">
              suEXEC cleans the process's 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).
            </p>
          </li>
    
          <li>
            <strong>Can we successfully become the target CGI/SSI program
            and execute?</strong>
    
            <p class="indent">
              Here is where suEXEC ends and the target CGI/SSI program begins.
            </p>
          </li>
        </ol>
    
        <p>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.</p>
    
        <p>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 <a href="#jabberwock">"Beware the Jabberwock"</a> section of this
        document.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="install" id="install">Configuring &amp; Installing
        suEXEC</a></h2>
    
        <p>Here's where we begin the fun.</p>
    
        <p><strong>suEXEC configuration
        options</strong><br />
        </p>
    
        <dl>
          <dt><code>--enable-suexec</code></dt>
    
          <dd>This option enables the suEXEC feature which is never
          installed or activated by default. At least one
          <code>--with-suexec-xxxxx</code> option has to be provided
          together with the <code>--enable-suexec</code> option to let
          APACI accept your request for using the suEXEC feature.</dd>
    
          <dt><code>--with-suexec-bin=<em>PATH</em></code></dt>
    
          <dd>The path to the <code>suexec</code> binary must be hard-coded
          in the server for security reasons. Use this option to override
          the default path. <em>e.g.</em>
          <code>--with-suexec-bin=/usr/sbin/suexec</code></dd>
    
          <dt><code>--with-suexec-caller=<em>UID</em></code></dt>
    
          <dd>The <a href="mod/mpm_common.html#user">username</a> under which
          httpd normally runs. This is the only user allowed to
          execute the suEXEC wrapper.</dd>
    
          <dt><code>--with-suexec-userdir=<em>DIR</em></code></dt>
    
          <dd>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" <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>
          directive (ie. one without a "*" in it) this should be set to the same
          value. suEXEC will not work properly in cases where the <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> directive points to
          a location that is not the same as the user's home directory
          as referenced in the <code>passwd</code> file. Default value is
          "<code>public_html</code>".<br />
          If you have virtual hosts with a different <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code> for each,
          you will need to define them to all reside in one parent
          directory; then name that parent directory here. <strong>If
          this is not defined properly, "~userdir" cgi requests will
          not work!</strong></dd>
    
          <dt><code>--with-suexec-docroot=<em>DIR</em></code></dt>
    
          <dd>Define as the DocumentRoot set for httpd. This will be
          the only hierarchy (aside from <code class="directive"><a href="./mod/mod_userdir.html#userdir">UserDir</a></code>s) that can be used for suEXEC behavior. The
          default directory is the <code>--datadir</code> value with the suffix
          "<code>/htdocs</code>", <em>e.g.</em> if you configure with
          "<code>--datadir=/home/apache</code>" the directory
          "<code>/home/apache/htdocs</code>" is used as document root for the
          suEXEC wrapper.</dd>
    
          <dt><code>--with-suexec-uidmin=<em>UID</em></code></dt>
    
          <dd>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.</dd>
    
          <dt><code>--with-suexec-gidmin=<em>GID</em></code></dt>
    
          <dd>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.</dd>
    
          <dt><code>--with-suexec-logfile=<em>FILE</em></code></dt>
    
          <dd>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
          "<code>suexec_log</code>" and located in your standard logfile
          directory (<code>--logfiledir</code>).</dd>
    
          <dt><code>--with-suexec-safepath=<em>PATH</em></code></dt>
    
          <dd>Define a safe PATH environment to pass to CGI
          executables. Default value is
          "<code>/usr/local/bin:/usr/bin:/bin</code>".</dd>
        </dl>
    
        <h3>Compiling and installing the suEXEC wrapper</h3>
          
    
          <p>If you have enabled the suEXEC feature with the
          <code>--enable-suexec</code> option the <code>suexec</code> binary
          (together with httpd itself) is automatically built if you execute
          the <code>make</code> command.</p>
    
          <p>After all components have been built you can execute the
          command <code>make install</code> to install them. The binary image
          <code>suexec</code> is installed in the directory defined by the
          <code>--sbindir</code> option. The default location is
          "/usr/local/apache2/bin/suexec".</p>
    
          <p>Please note that you need <strong><em>root
          privileges</em></strong> for the installation step. In order
          for the wrapper to set the user ID, it must be installed as
          owner <code><em>root</em></code> and must have the setuserid
          execution bit set for file modes.</p>
        
    
        <h3>Setting paranoid permissions</h3>
          
    
          <p>Although the suEXEC wrapper will check to ensure that its
          caller is the correct user as specified with the
          <code>--with-suexec-caller</code> <code class="program"><a href="./programs/configure.html">configure</a></code>
          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 httpd
          runs as may execute suEXEC.</p>
    
          <p>If for example, your web server is configured to run as:</p>
    
          <pre class="prettyprint lang-config">User www
    Group webgroup</pre>
    
    
          <p>and <code class="program"><a href="./programs/suexec.html">suexec</a></code> is installed at
          "/usr/local/apache2/bin/suexec", you should run:</p>
    
          <div class="example"><p><code>
              chgrp webgroup /usr/local/apache2/bin/suexec<br />
              chmod 4750 /usr/local/apache2/bin/suexec<br />
          </code></p></div>
    
          <p>This will ensure that only the group httpd runs as can even
          execute the suEXEC wrapper.</p>
        
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="enable" id="enable">Enabling &amp; Disabling
        suEXEC</a></h2>
    
        <p>Upon startup of httpd, it looks for the file
        <code class="program"><a href="./programs/suexec.html">suexec</a></code> in the directory defined by the
        <code>--sbindir</code> option (default is
        "/usr/local/apache/sbin/suexec"). If httpd finds a properly
        configured suEXEC wrapper, it will print the following message
        to the error log:</p>
    
    <div class="example"><p><code>
        [notice] suEXEC mechanism enabled (wrapper: <var>/path/to/suexec</var>)
    </code></p></div>
    
        <p>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 <em>setuid root</em>.</p>
    
         <p>If you want to enable the suEXEC mechanism for the first time
        and an Apache HTTP Server is already running you must kill and
        restart httpd. Restarting it with a simple HUP or USR1 signal
        will not be enough. </p>
         <p>If you want to disable suEXEC you should kill and restart
        httpd after you have removed the <code class="program"><a href="./programs/suexec.html">suexec</a></code> file.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="usage" id="usage">Using suEXEC</a></h2>
    
        <p>Requests for CGI programs will call the suEXEC wrapper only if
        they are for a virtual host containing a <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> directive or if
        they are processed by <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code>.</p>
    
        <p><strong>Virtual Hosts:</strong><br /> One way to use the suEXEC
        wrapper is through the <code class="directive"><a href="./mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code> directive in
        <code class="directive"><a href="./mod/core.html#virtualhost">VirtualHost</a></code> definitions.  By
        setting this directive to values different from the main server
        user ID, all requests for CGI resources will be executed as the
        <em>User</em> and <em>Group</em> defined for that <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>. If this
        directive is not specified for a <code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> then the main server userid
        is assumed.</p>
    
        <p><strong>User directories:</strong><br /> Requests that are
         processed by <code class="module"><a href="./mod/mod_userdir.html">mod_userdir</a></code> 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 <a href="#model">security
         checks</a> above.  See also the
         <code>--with-suexec-userdir</code> <a href="#install">compile
         time option</a>.</p> </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="debug" id="debug">Debugging suEXEC</a></h2>
    
        <p>The suEXEC wrapper will write log information
        to the file defined with the <code>--with-suexec-logfile</code>
        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.</p>
    
    </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
    <div class="section">
    <h2><a name="jabberwock" id="jabberwock">Beware the Jabberwock:
        Warnings &amp; Examples</a></h2>
    
        <p><strong>NOTE!</strong> This section may not be
        complete.</p>
    
        <p>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.</p>
    
        <p><strong>suEXEC Points Of Interest</strong></p>
        <ul>
    
          <li>
            Hierarchy limitations
    
            <p class="indent">
              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 httpd
              document hierarchy to take advantage of suEXEC for
              VirtualHosts. (Example forthcoming.)
            </p>
          </li>
    
          <li>
            suEXEC's PATH environment variable
    
            <p class="indent">
              This can be a dangerous thing to change. Make certain
              every path you include in this define is a
              <strong>trusted</strong> directory. You don't want to
              open people up to having someone from across the world
              running a trojan horse on them.
            </p>
          </li>
    
          <li>
            Altering the suEXEC code
    
            <p class="indent">
              Again, this can cause <strong>Big Trouble</strong> if you
              try this without knowing what you are doing. Stay away
              from it if at all possible.
            </p>
          </li>
        </ul>
    
    </div></div>
    <div class="bottomlang">
    <p><span>Available Languages: </span><a href="./en/suexec.html" title="English">&nbsp;en&nbsp;</a> |
    <a href="./fr/suexec.html" hreflang="fr" rel="alternate" title="Français">&nbsp;fr&nbsp;</a> |
    <a href="./ja/suexec.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
    <a href="./ko/suexec.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
    <a href="./tr/suexec.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
    </div><div class="top"><a href="#page-header"><img src="./images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Libera.chat, or sent to our <a href="https://httpd.apache.org/lists.html">mailing lists</a>.</div>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    var comments_shortname = 'httpd';
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/suexec.html';
    (function(w, d) {
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
            d.write('<div id="comments_thread"><\/div>');
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
        }
        else { 
            d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
        }
    })(window, document);
    //--><!]]></script></div><div id="footer">
    <p class="apache">Copyright 2025 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
    <p class="menu"><a href="./mod/">Modules</a> | <a href="./mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="./glossary.html">Glossary</a> | <a href="./sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
    if (typeof(prettyPrint) !== 'undefined') {
        prettyPrint();
    }
    //--><!]]></script>
    </body></html>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/server-wide.html�����������������������������������������������������������0000664�0001751�0001751�00000000751�13710016232�020147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: server-wide.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: server-wide.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: server-wide.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: server-wide.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: server-wide.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    �����������������������httpd-2.4.64/docs/manual/convenience.map������������������������������������������������������������0000664�0001751�0001751�00000111347�14236245221�020032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Mapping from directive names to URLs
    # GENERATED FROM XML -- DO NOT EDIT
    # You may use it as follows:
    # RewriteEngine On
    # RewriteMap dir2url txt:/path/to/convenience.map
    # RewriteCond ${dir2url:$1} (.+)
    # RewriteRule ^/+([^/]+)$ /manual/%1 [R=301,NE,L]
    
    acceptfilter	mod/core.html#acceptfilter
    acceptpathinfo	mod/core.html#acceptpathinfo
    accessfilename	mod/core.html#accessfilename
    action	mod/mod_actions.html#action
    addalt	mod/mod_autoindex.html#addalt
    addaltbyencoding	mod/mod_autoindex.html#addaltbyencoding
    addaltbytype	mod/mod_autoindex.html#addaltbytype
    addcharset	mod/mod_mime.html#addcharset
    adddefaultcharset	mod/core.html#adddefaultcharset
    adddescription	mod/mod_autoindex.html#adddescription
    addencoding	mod/mod_mime.html#addencoding
    addhandler	mod/mod_mime.html#addhandler
    addicon	mod/mod_autoindex.html#addicon
    addiconbyencoding	mod/mod_autoindex.html#addiconbyencoding
    addiconbytype	mod/mod_autoindex.html#addiconbytype
    addinputfilter	mod/mod_mime.html#addinputfilter
    addlanguage	mod/mod_mime.html#addlanguage
    addmoduleinfo	mod/mod_info.html#addmoduleinfo
    addoutputfilter	mod/mod_mime.html#addoutputfilter
    addoutputfilterbytype	mod/mod_filter.html#addoutputfilterbytype
    addtype	mod/mod_mime.html#addtype
    alias	mod/mod_alias.html#alias
    aliasmatch	mod/mod_alias.html#aliasmatch
    allow	mod/mod_access_compat.html#allow
    allowconnect	mod/mod_proxy_connect.html#allowconnect
    allowencodedslashes	mod/core.html#allowencodedslashes
    allowmethods	mod/mod_allowmethods.html#allowmethods
    allowoverride	mod/core.html#allowoverride
    allowoverridelist	mod/core.html#allowoverridelist
    anonymous	mod/mod_authn_anon.html#anonymous
    anonymous_logemail	mod/mod_authn_anon.html#anonymous_logemail
    anonymous_mustgiveemail	mod/mod_authn_anon.html#anonymous_mustgiveemail
    anonymous_nouserid	mod/mod_authn_anon.html#anonymous_nouserid
    anonymous_verifyemail	mod/mod_authn_anon.html#anonymous_verifyemail
    asyncrequestworkerfactor	mod/event.html#asyncrequestworkerfactor
    authbasicauthoritative	mod/mod_auth_basic.html#authbasicauthoritative
    authbasicfake	mod/mod_auth_basic.html#authbasicfake
    authbasicprovider	mod/mod_auth_basic.html#authbasicprovider
    authbasicusedigestalgorithm	mod/mod_auth_basic.html#authbasicusedigestalgorithm
    authdbduserpwquery	mod/mod_authn_dbd.html#authdbduserpwquery
    authdbduserrealmquery	mod/mod_authn_dbd.html#authdbduserrealmquery
    authdbmgroupfile	mod/mod_authz_dbm.html#authdbmgroupfile
    authdbmtype	mod/mod_authn_dbm.html#authdbmtype
    authdbmuserfile	mod/mod_authn_dbm.html#authdbmuserfile
    authdigestalgorithm	mod/mod_auth_digest.html#authdigestalgorithm
    authdigestdomain	mod/mod_auth_digest.html#authdigestdomain
    authdigestnoncelifetime	mod/mod_auth_digest.html#authdigestnoncelifetime
    authdigestprovider	mod/mod_auth_digest.html#authdigestprovider
    authdigestqop	mod/mod_auth_digest.html#authdigestqop
    authdigestshmemsize	mod/mod_auth_digest.html#authdigestshmemsize
    authformauthoritative	mod/mod_auth_form.html#authformauthoritative
    authformbody	mod/mod_auth_form.html#authformbody
    authformdisablenostore	mod/mod_auth_form.html#authformdisablenostore
    authformfakebasicauth	mod/mod_auth_form.html#authformfakebasicauth
    authformlocation	mod/mod_auth_form.html#authformlocation
    authformloginrequiredlocation	mod/mod_auth_form.html#authformloginrequiredlocation
    authformloginsuccesslocation	mod/mod_auth_form.html#authformloginsuccesslocation
    authformlogoutlocation	mod/mod_auth_form.html#authformlogoutlocation
    authformmethod	mod/mod_auth_form.html#authformmethod
    authformmimetype	mod/mod_auth_form.html#authformmimetype
    authformpassword	mod/mod_auth_form.html#authformpassword
    authformprovider	mod/mod_auth_form.html#authformprovider
    authformsitepassphrase	mod/mod_auth_form.html#authformsitepassphrase
    authformsize	mod/mod_auth_form.html#authformsize
    authformusername	mod/mod_auth_form.html#authformusername
    authgroupfile	mod/mod_authz_groupfile.html#authgroupfile
    authldapauthorizeprefix	mod/mod_authnz_ldap.html#authldapauthorizeprefix
    authldapbindauthoritative	mod/mod_authnz_ldap.html#authldapbindauthoritative
    authldapbinddn	mod/mod_authnz_ldap.html#authldapbinddn
    authldapbindpassword	mod/mod_authnz_ldap.html#authldapbindpassword
    authldapcharsetconfig	mod/mod_authnz_ldap.html#authldapcharsetconfig
    authldapcompareasuser	mod/mod_authnz_ldap.html#authldapcompareasuser
    authldapcomparednonserver	mod/mod_authnz_ldap.html#authldapcomparednonserver
    authldapdereferencealiases	mod/mod_authnz_ldap.html#authldapdereferencealiases
    authldapgroupattribute	mod/mod_authnz_ldap.html#authldapgroupattribute
    authldapgroupattributeisdn	mod/mod_authnz_ldap.html#authldapgroupattributeisdn
    authldapinitialbindasuser	mod/mod_authnz_ldap.html#authldapinitialbindasuser
    authldapinitialbindpattern	mod/mod_authnz_ldap.html#authldapinitialbindpattern
    authldapmaxsubgroupdepth	mod/mod_authnz_ldap.html#authldapmaxsubgroupdepth
    authldapremoteuserattribute	mod/mod_authnz_ldap.html#authldapremoteuserattribute
    authldapremoteuserisdn	mod/mod_authnz_ldap.html#authldapremoteuserisdn
    authldapsearchasuser	mod/mod_authnz_ldap.html#authldapsearchasuser
    authldapsubgroupattribute	mod/mod_authnz_ldap.html#authldapsubgroupattribute
    authldapsubgroupclass	mod/mod_authnz_ldap.html#authldapsubgroupclass
    authldapurl	mod/mod_authnz_ldap.html#authldapurl
    authmerging	mod/mod_authz_core.html#authmerging
    authname	mod/mod_authn_core.html#authname
    authncachecontext	mod/mod_authn_socache.html#authncachecontext
    authncacheenable	mod/mod_authn_socache.html#authncacheenable
    authncacheprovidefor	mod/mod_authn_socache.html#authncacheprovidefor
    authncachesocache	mod/mod_authn_socache.html#authncachesocache
    authncachetimeout	mod/mod_authn_socache.html#authncachetimeout
    authnprovideralias	mod/mod_authn_core.html#authnprovideralias
    authnzfcgicheckauthnprovider	mod/mod_authnz_fcgi.html#authnzfcgicheckauthnprovider
    authnzfcgidefineprovider	mod/mod_authnz_fcgi.html#authnzfcgidefineprovider
    authtype	mod/mod_authn_core.html#authtype
    authuserfile	mod/mod_authn_file.html#authuserfile
    authzdbdlogintoreferer	mod/mod_authz_dbd.html#authzdbdlogintoreferer
    authzdbdquery	mod/mod_authz_dbd.html#authzdbdquery
    authzdbdredirectquery	mod/mod_authz_dbd.html#authzdbdredirectquery
    authzdbmtype	mod/mod_authz_dbm.html#authzdbmtype
    authzprovideralias	mod/mod_authz_core.html#authzprovideralias
    authzsendforbiddenonfailure	mod/mod_authz_core.html#authzsendforbiddenonfailure
    balancergrowth	mod/mod_proxy.html#balancergrowth
    balancerinherit	mod/mod_proxy.html#balancerinherit
    balancermember	mod/mod_proxy.html#balancermember
    balancerpersist	mod/mod_proxy.html#balancerpersist
    brotlialteretag	mod/mod_brotli.html#brotlialteretag
    brotlicompressionmaxinputblock	mod/mod_brotli.html#brotlicompressionmaxinputblock
    brotlicompressionquality	mod/mod_brotli.html#brotlicompressionquality
    brotlicompressionwindow	mod/mod_brotli.html#brotlicompressionwindow
    brotlifilternote	mod/mod_brotli.html#brotlifilternote
    browsermatch	mod/mod_setenvif.html#browsermatch
    browsermatchnocase	mod/mod_setenvif.html#browsermatchnocase
    bufferedlogs	mod/mod_log_config.html#bufferedlogs
    buffersize	mod/mod_buffer.html#buffersize
    cachedefaultexpire	mod/mod_cache.html#cachedefaultexpire
    cachedetailheader	mod/mod_cache.html#cachedetailheader
    cachedirlength	mod/mod_cache_disk.html#cachedirlength
    cachedirlevels	mod/mod_cache_disk.html#cachedirlevels
    cachedisable	mod/mod_cache.html#cachedisable
    cacheenable	mod/mod_cache.html#cacheenable
    cachefile	mod/mod_file_cache.html#cachefile
    cacheheader	mod/mod_cache.html#cacheheader
    cacheignorecachecontrol	mod/mod_cache.html#cacheignorecachecontrol
    cacheignoreheaders	mod/mod_cache.html#cacheignoreheaders
    cacheignorenolastmod	mod/mod_cache.html#cacheignorenolastmod
    cacheignorequerystring	mod/mod_cache.html#cacheignorequerystring
    cacheignoreurlsessionidentifiers	mod/mod_cache.html#cacheignoreurlsessionidentifiers
    cachekeybaseurl	mod/mod_cache.html#cachekeybaseurl
    cachelastmodifiedfactor	mod/mod_cache.html#cachelastmodifiedfactor
    cachelock	mod/mod_cache.html#cachelock
    cachelockmaxage	mod/mod_cache.html#cachelockmaxage
    cachelockpath	mod/mod_cache.html#cachelockpath
    cachemaxexpire	mod/mod_cache.html#cachemaxexpire
    cachemaxfilesize	mod/mod_cache_disk.html#cachemaxfilesize
    cacheminexpire	mod/mod_cache.html#cacheminexpire
    cacheminfilesize	mod/mod_cache_disk.html#cacheminfilesize
    cachenegotiateddocs	mod/mod_negotiation.html#cachenegotiateddocs
    cachequickhandler	mod/mod_cache.html#cachequickhandler
    cachereadsize	mod/mod_cache_disk.html#cachereadsize
    cachereadtime	mod/mod_cache_disk.html#cachereadtime
    cacheroot	mod/mod_cache_disk.html#cacheroot
    cachesocache	mod/mod_cache_socache.html#cachesocache
    cachesocachemaxsize	mod/mod_cache_socache.html#cachesocachemaxsize
    cachesocachemaxtime	mod/mod_cache_socache.html#cachesocachemaxtime
    cachesocachemintime	mod/mod_cache_socache.html#cachesocachemintime
    cachesocachereadsize	mod/mod_cache_socache.html#cachesocachereadsize
    cachesocachereadtime	mod/mod_cache_socache.html#cachesocachereadtime
    cachestaleonerror	mod/mod_cache.html#cachestaleonerror
    cachestoreexpired	mod/mod_cache.html#cachestoreexpired
    cachestorenostore	mod/mod_cache.html#cachestorenostore
    cachestoreprivate	mod/mod_cache.html#cachestoreprivate
    cgidscripttimeout	mod/mod_cgid.html#cgidscripttimeout
    cgimapextension	mod/core.html#cgimapextension
    cgipassauth	mod/core.html#cgipassauth
    cgivar	mod/core.html#cgivar
    charsetdefault	mod/mod_charset_lite.html#charsetdefault
    charsetoptions	mod/mod_charset_lite.html#charsetoptions
    charsetsourceenc	mod/mod_charset_lite.html#charsetsourceenc
    checkbasenamematch	mod/mod_speling.html#checkbasenamematch
    checkcaseonly	mod/mod_speling.html#checkcaseonly
    checkspelling	mod/mod_speling.html#checkspelling
    chrootdir	mod/mod_unixd.html#chrootdir
    contentdigest	mod/core.html#contentdigest
    cookiedomain	mod/mod_usertrack.html#cookiedomain
    cookieexpires	mod/mod_usertrack.html#cookieexpires
    cookiehttponly	mod/mod_usertrack.html#cookiehttponly
    cookiename	mod/mod_usertrack.html#cookiename
    cookiesamesite	mod/mod_usertrack.html#cookiesamesite
    cookiesecure	mod/mod_usertrack.html#cookiesecure
    cookiestyle	mod/mod_usertrack.html#cookiestyle
    cookietracking	mod/mod_usertrack.html#cookietracking
    coredumpdirectory	mod/mpm_common.html#coredumpdirectory
    customlog	mod/mod_log_config.html#customlog
    dav	mod/mod_dav.html#dav
    davdepthinfinity	mod/mod_dav.html#davdepthinfinity
    davgenericlockdb	mod/mod_dav_lock.html#davgenericlockdb
    davlockdb	mod/mod_dav_fs.html#davlockdb
    davmintimeout	mod/mod_dav.html#davmintimeout
    dbdexptime	mod/mod_dbd.html#dbdexptime
    dbdinitsql	mod/mod_dbd.html#dbdinitsql
    dbdkeep	mod/mod_dbd.html#dbdkeep
    dbdmax	mod/mod_dbd.html#dbdmax
    dbdmin	mod/mod_dbd.html#dbdmin
    dbdparams	mod/mod_dbd.html#dbdparams
    dbdpersist	mod/mod_dbd.html#dbdpersist
    dbdpreparesql	mod/mod_dbd.html#dbdpreparesql
    dbdriver	mod/mod_dbd.html#dbdriver
    defaulticon	mod/mod_autoindex.html#defaulticon
    defaultlanguage	mod/mod_mime.html#defaultlanguage
    defaultruntimedir	mod/core.html#defaultruntimedir
    defaulttype	mod/core.html#defaulttype
    define	mod/core.html#define
    deflatebuffersize	mod/mod_deflate.html#deflatebuffersize
    deflatecompressionlevel	mod/mod_deflate.html#deflatecompressionlevel
    deflatefilternote	mod/mod_deflate.html#deflatefilternote
    deflateinflatelimitrequestbody	mod/mod_deflate.html#deflateinflatelimitrequestbody
    deflateinflateratioburst	mod/mod_deflate.html#deflateinflateratioburst
    deflateinflateratiolimit	mod/mod_deflate.html#deflateinflateratiolimit
    deflatememlevel	mod/mod_deflate.html#deflatememlevel
    deflatewindowsize	mod/mod_deflate.html#deflatewindowsize
    deny	mod/mod_access_compat.html#deny
    directory	mod/core.html#directory
    directorycheckhandler	mod/mod_dir.html#directorycheckhandler
    directoryindex	mod/mod_dir.html#directoryindex
    directoryindexredirect	mod/mod_dir.html#directoryindexredirect
    directorymatch	mod/core.html#directorymatch
    directoryslash	mod/mod_dir.html#directoryslash
    documentroot	mod/core.html#documentroot
    dtraceprivileges	mod/mod_privileges.html#dtraceprivileges
    dumpioinput	mod/mod_dumpio.html#dumpioinput
    dumpiooutput	mod/mod_dumpio.html#dumpiooutput
    else	mod/core.html#else
    elseif	mod/core.html#elseif
    enableexceptionhook	mod/mpm_common.html#enableexceptionhook
    enablemmap	mod/core.html#enablemmap
    enablesendfile	mod/core.html#enablesendfile
    error	mod/core.html#error
    errordocument	mod/core.html#errordocument
    errorlog	mod/core.html#errorlog
    errorlogformat	mod/core.html#errorlogformat
    example	mod/mod_example_hooks.html#example
    expiresactive	mod/mod_expires.html#expiresactive
    expiresbytype	mod/mod_expires.html#expiresbytype
    expiresdefault	mod/mod_expires.html#expiresdefault
    extendedstatus	mod/core.html#extendedstatus
    extfilterdefine	mod/mod_ext_filter.html#extfilterdefine
    extfilteroptions	mod/mod_ext_filter.html#extfilteroptions
    fallbackresource	mod/mod_dir.html#fallbackresource
    fileetag	mod/core.html#fileetag
    files	mod/core.html#files
    filesmatch	mod/core.html#filesmatch
    filterchain	mod/mod_filter.html#filterchain
    filterdeclare	mod/mod_filter.html#filterdeclare
    filterprotocol	mod/mod_filter.html#filterprotocol
    filterprovider	mod/mod_filter.html#filterprovider
    filtertrace	mod/mod_filter.html#filtertrace
    flushmaxpipelined	mod/core.html#flushmaxpipelined
    flushmaxthreshold	mod/core.html#flushmaxthreshold
    forcelanguagepriority	mod/mod_negotiation.html#forcelanguagepriority
    forcetype	mod/core.html#forcetype
    forensiclog	mod/mod_log_forensic.html#forensiclog
    globallog	mod/mod_log_config.html#globallog
    gprofdir	mod/core.html#gprofdir
    gracefulshutdowntimeout	mod/mpm_common.html#gracefulshutdowntimeout
    group	mod/mod_unixd.html#group
    h2copyfiles	mod/mod_http2.html#h2copyfiles
    h2direct	mod/mod_http2.html#h2direct
    h2earlyhints	mod/mod_http2.html#h2earlyhints
    h2maxsessionstreams	mod/mod_http2.html#h2maxsessionstreams
    h2maxworkeridleseconds	mod/mod_http2.html#h2maxworkeridleseconds
    h2maxworkers	mod/mod_http2.html#h2maxworkers
    h2minworkers	mod/mod_http2.html#h2minworkers
    h2moderntlsonly	mod/mod_http2.html#h2moderntlsonly
    h2outputbuffering	mod/mod_http2.html#h2outputbuffering
    h2padding	mod/mod_http2.html#h2padding
    h2push	mod/mod_http2.html#h2push
    h2pushdiarysize	mod/mod_http2.html#h2pushdiarysize
    h2pushpriority	mod/mod_http2.html#h2pushpriority
    h2pushresource	mod/mod_http2.html#h2pushresource
    h2serializeheaders	mod/mod_http2.html#h2serializeheaders
    h2streammaxmemsize	mod/mod_http2.html#h2streammaxmemsize
    h2tlscooldownsecs	mod/mod_http2.html#h2tlscooldownsecs
    h2tlswarmupsize	mod/mod_http2.html#h2tlswarmupsize
    h2upgrade	mod/mod_http2.html#h2upgrade
    h2windowsize	mod/mod_http2.html#h2windowsize
    header	mod/mod_headers.html#header
    headername	mod/mod_autoindex.html#headername
    heartbeataddress	mod/mod_heartbeat.html#heartbeataddress
    heartbeatlisten	mod/mod_heartmonitor.html#heartbeatlisten
    heartbeatmaxservers	mod/mod_heartmonitor.html#heartbeatmaxservers
    heartbeatstorage	mod/mod_lbmethod_heartbeat.html#heartbeatstorage
    heartbeatstorage	mod/mod_heartmonitor.html#heartbeatstorage
    hostnamelookups	mod/core.html#hostnamelookups
    httpprotocoloptions	mod/core.html#httpprotocoloptions
    identitycheck	mod/mod_ident.html#identitycheck
    identitychecktimeout	mod/mod_ident.html#identitychecktimeout
    if	mod/core.html#if
    ifdefine	mod/core.html#ifdefine
    ifdirective	mod/core.html#ifdirective
    iffile	mod/core.html#iffile
    ifmodule	mod/core.html#ifmodule
    ifsection	mod/core.html#ifsection
    ifversion	mod/mod_version.html#ifversion
    imapbase	mod/mod_imagemap.html#imapbase
    imapdefault	mod/mod_imagemap.html#imapdefault
    imapmenu	mod/mod_imagemap.html#imapmenu
    include	mod/core.html#include
    includeoptional	mod/core.html#includeoptional
    indexheadinsert	mod/mod_autoindex.html#indexheadinsert
    indexignore	mod/mod_autoindex.html#indexignore
    indexignorereset	mod/mod_autoindex.html#indexignorereset
    indexoptions	mod/mod_autoindex.html#indexoptions
    indexorderdefault	mod/mod_autoindex.html#indexorderdefault
    indexstylesheet	mod/mod_autoindex.html#indexstylesheet
    inputsed	mod/mod_sed.html#inputsed
    isapiappendlogtoerrors	mod/mod_isapi.html#isapiappendlogtoerrors
    isapiappendlogtoquery	mod/mod_isapi.html#isapiappendlogtoquery
    isapicachefile	mod/mod_isapi.html#isapicachefile
    isapifakeasync	mod/mod_isapi.html#isapifakeasync
    isapilognotsupported	mod/mod_isapi.html#isapilognotsupported
    isapireadaheadbuffer	mod/mod_isapi.html#isapireadaheadbuffer
    keepalive	mod/core.html#keepalive
    keepalivetimeout	mod/core.html#keepalivetimeout
    keptbodysize	mod/mod_request.html#keptbodysize
    languagepriority	mod/mod_negotiation.html#languagepriority
    ldapcacheentries	mod/mod_ldap.html#ldapcacheentries
    ldapcachettl	mod/mod_ldap.html#ldapcachettl
    ldapconnectionpoolttl	mod/mod_ldap.html#ldapconnectionpoolttl
    ldapconnectiontimeout	mod/mod_ldap.html#ldapconnectiontimeout
    ldaplibrarydebug	mod/mod_ldap.html#ldaplibrarydebug
    ldapopcacheentries	mod/mod_ldap.html#ldapopcacheentries
    ldapopcachettl	mod/mod_ldap.html#ldapopcachettl
    ldapreferralhoplimit	mod/mod_ldap.html#ldapreferralhoplimit
    ldapreferrals	mod/mod_ldap.html#ldapreferrals
    ldapretries	mod/mod_ldap.html#ldapretries
    ldapretrydelay	mod/mod_ldap.html#ldapretrydelay
    ldapsharedcachefile	mod/mod_ldap.html#ldapsharedcachefile
    ldapsharedcachesize	mod/mod_ldap.html#ldapsharedcachesize
    ldaptimeout	mod/mod_ldap.html#ldaptimeout
    ldaptrustedclientcert	mod/mod_ldap.html#ldaptrustedclientcert
    ldaptrustedglobalcert	mod/mod_ldap.html#ldaptrustedglobalcert
    ldaptrustedmode	mod/mod_ldap.html#ldaptrustedmode
    ldapverifyservercert	mod/mod_ldap.html#ldapverifyservercert
    limit	mod/core.html#limit
    limitexcept	mod/core.html#limitexcept
    limitinternalrecursion	mod/core.html#limitinternalrecursion
    limitrequestbody	mod/core.html#limitrequestbody
    limitrequestfields	mod/core.html#limitrequestfields
    limitrequestfieldsize	mod/core.html#limitrequestfieldsize
    limitrequestline	mod/core.html#limitrequestline
    limitxmlrequestbody	mod/core.html#limitxmlrequestbody
    listen	mod/mpm_common.html#listen
    listenbacklog	mod/mpm_common.html#listenbacklog
    listencoresbucketsratio	mod/mpm_common.html#listencoresbucketsratio
    loadfile	mod/mod_so.html#loadfile
    loadmodule	mod/mod_so.html#loadmodule
    location	mod/core.html#location
    locationmatch	mod/core.html#locationmatch
    logformat	mod/mod_log_config.html#logformat
    logiotrackttfb	mod/mod_logio.html#logiotrackttfb
    loglevel	mod/core.html#loglevel
    logmessage	mod/mod_log_debug.html#logmessage
    luaauthzprovider	mod/mod_lua.html#luaauthzprovider
    luacodecache	mod/mod_lua.html#luacodecache
    luahookaccesschecker	mod/mod_lua.html#luahookaccesschecker
    luahookauthchecker	mod/mod_lua.html#luahookauthchecker
    luahookcheckuserid	mod/mod_lua.html#luahookcheckuserid
    luahookfixups	mod/mod_lua.html#luahookfixups
    luahookinsertfilter	mod/mod_lua.html#luahookinsertfilter
    luahooklog	mod/mod_lua.html#luahooklog
    luahookmaptostorage	mod/mod_lua.html#luahookmaptostorage
    luahookpretranslate	mod/mod_lua.html#luahookpretranslate
    luahooktranslatename	mod/mod_lua.html#luahooktranslatename
    luahooktypechecker	mod/mod_lua.html#luahooktypechecker
    luainherit	mod/mod_lua.html#luainherit
    luainputfilter	mod/mod_lua.html#luainputfilter
    luamaphandler	mod/mod_lua.html#luamaphandler
    luaoutputfilter	mod/mod_lua.html#luaoutputfilter
    luapackagecpath	mod/mod_lua.html#luapackagecpath
    luapackagepath	mod/mod_lua.html#luapackagepath
    luaquickhandler	mod/mod_lua.html#luaquickhandler
    luaroot	mod/mod_lua.html#luaroot
    luascope	mod/mod_lua.html#luascope
    macro	mod/mod_macro.html#macro
    maxconnectionsperchild	mod/mpm_common.html#maxconnectionsperchild
    maxkeepaliverequests	mod/core.html#maxkeepaliverequests
    maxmemfree	mod/mpm_common.html#maxmemfree
    maxrangeoverlaps	mod/core.html#maxrangeoverlaps
    maxrangereversals	mod/core.html#maxrangereversals
    maxranges	mod/core.html#maxranges
    maxrequestworkers	mod/mpm_common.html#maxrequestworkers
    maxspareservers	mod/prefork.html#maxspareservers
    maxsparethreads	mod/mpm_common.html#maxsparethreads
    maxthreads	mod/mpm_netware.html#maxthreads
    mdactivationdelay	mod/mod_md.html#mdactivationdelay
    mdbaseserver	mod/mod_md.html#mdbaseserver
    mdcachallenges	mod/mod_md.html#mdcachallenges
    mdcertificateagreement	mod/mod_md.html#mdcertificateagreement
    mdcertificateauthority	mod/mod_md.html#mdcertificateauthority
    mdcertificatecheck	mod/mod_md.html#mdcertificatecheck
    mdcertificatefile	mod/mod_md.html#mdcertificatefile
    mdcertificatekeyfile	mod/mod_md.html#mdcertificatekeyfile
    mdcertificatemonitor	mod/mod_md.html#mdcertificatemonitor
    mdcertificateprotocol	mod/mod_md.html#mdcertificateprotocol
    mdcertificatestatus	mod/mod_md.html#mdcertificatestatus
    mdchallengedns01	mod/mod_md.html#mdchallengedns01
    mdcontactemail	mod/mod_md.html#mdcontactemail
    mddrivemode	mod/mod_md.html#mddrivemode
    mdexternalaccountbinding	mod/mod_md.html#mdexternalaccountbinding
    mdhttpproxy	mod/mod_md.html#mdhttpproxy
    mdmember	mod/mod_md.html#mdmember
    mdmembers	mod/mod_md.html#mdmembers
    mdmessagecmd	mod/mod_md.html#mdmessagecmd
    mdmuststaple	mod/mod_md.html#mdmuststaple
    mdnotifycmd	mod/mod_md.html#mdnotifycmd
    mdomain	mod/mod_md.html#mdomain
    mdomainset	mod/mod_md.html#mdomainset
    mdportmap	mod/mod_md.html#mdportmap
    mdprivatekeys	mod/mod_md.html#mdprivatekeys
    mdrenewmode	mod/mod_md.html#mdrenewmode
    mdrenewwindow	mod/mod_md.html#mdrenewwindow
    mdrequirehttps	mod/mod_md.html#mdrequirehttps
    mdserverstatus	mod/mod_md.html#mdserverstatus
    mdstapleothers	mod/mod_md.html#mdstapleothers
    mdstapling	mod/mod_md.html#mdstapling
    mdstaplingkeepresponse	mod/mod_md.html#mdstaplingkeepresponse
    mdstaplingrenewwindow	mod/mod_md.html#mdstaplingrenewwindow
    mdstoredir	mod/mod_md.html#mdstoredir
    mdwarnwindow	mod/mod_md.html#mdwarnwindow
    memcacheconnttl	mod/mod_socache_memcache.html#memcacheconnttl
    mergeslashes	mod/core.html#mergeslashes
    mergetrailers	mod/core.html#mergetrailers
    metadir	mod/mod_cern_meta.html#metadir
    metafiles	mod/mod_cern_meta.html#metafiles
    metasuffix	mod/mod_cern_meta.html#metasuffix
    mimemagicfile	mod/mod_mime_magic.html#mimemagicfile
    minspareservers	mod/prefork.html#minspareservers
    minsparethreads	mod/mpm_common.html#minsparethreads
    mmapfile	mod/mod_file_cache.html#mmapfile
    modemstandard	mod/mod_dialup.html#modemstandard
    modmimeusepathinfo	mod/mod_mime.html#modmimeusepathinfo
    multiviewsmatch	mod/mod_mime.html#multiviewsmatch
    mutex	mod/core.html#mutex
    namevirtualhost	mod/core.html#namevirtualhost
    noproxy	mod/mod_proxy.html#noproxy
    nwssltrustedcerts	mod/mod_nw_ssl.html#nwssltrustedcerts
    nwsslupgradeable	mod/mod_nw_ssl.html#nwsslupgradeable
    options	mod/core.html#options
    order	mod/mod_access_compat.html#order
    outputsed	mod/mod_sed.html#outputsed
    passenv	mod/mod_env.html#passenv
    pidfile	mod/mpm_common.html#pidfile
    privilegesmode	mod/mod_privileges.html#privilegesmode
    protocol	mod/core.html#protocol
    protocolecho	mod/mod_echo.html#protocolecho
    protocols	mod/core.html#protocols
    protocolshonororder	mod/core.html#protocolshonororder
    proxy	mod/mod_proxy.html#proxy
    proxy100continue	mod/mod_proxy.html#proxy100continue
    proxyaddheaders	mod/mod_proxy.html#proxyaddheaders
    proxybadheader	mod/mod_proxy.html#proxybadheader
    proxyblock	mod/mod_proxy.html#proxyblock
    proxydomain	mod/mod_proxy.html#proxydomain
    proxyerroroverride	mod/mod_proxy.html#proxyerroroverride
    proxyexpressdbmfile	mod/mod_proxy_express.html#proxyexpressdbmfile
    proxyexpressdbmtype	mod/mod_proxy_express.html#proxyexpressdbmtype
    proxyexpressenable	mod/mod_proxy_express.html#proxyexpressenable
    proxyfcgibackendtype	mod/mod_proxy_fcgi.html#proxyfcgibackendtype
    proxyfcgisetenvif	mod/mod_proxy_fcgi.html#proxyfcgisetenvif
    proxyftpdircharset	mod/mod_proxy_ftp.html#proxyftpdircharset
    proxyftpescapewildcards	mod/mod_proxy_ftp.html#proxyftpescapewildcards
    proxyftplistonwildcard	mod/mod_proxy_ftp.html#proxyftplistonwildcard
    proxyhcexpr	mod/mod_proxy_hcheck.html#proxyhcexpr
    proxyhctemplate	mod/mod_proxy_hcheck.html#proxyhctemplate
    proxyhctpsize	mod/mod_proxy_hcheck.html#proxyhctpsize
    proxyhtmlbufsize	mod/mod_proxy_html.html#proxyhtmlbufsize
    proxyhtmlcharsetout	mod/mod_proxy_html.html#proxyhtmlcharsetout
    proxyhtmldoctype	mod/mod_proxy_html.html#proxyhtmldoctype
    proxyhtmlenable	mod/mod_proxy_html.html#proxyhtmlenable
    proxyhtmlevents	mod/mod_proxy_html.html#proxyhtmlevents
    proxyhtmlextended	mod/mod_proxy_html.html#proxyhtmlextended
    proxyhtmlfixups	mod/mod_proxy_html.html#proxyhtmlfixups
    proxyhtmlinterp	mod/mod_proxy_html.html#proxyhtmlinterp
    proxyhtmllinks	mod/mod_proxy_html.html#proxyhtmllinks
    proxyhtmlmeta	mod/mod_proxy_html.html#proxyhtmlmeta
    proxyhtmlstripcomments	mod/mod_proxy_html.html#proxyhtmlstripcomments
    proxyhtmlurlmap	mod/mod_proxy_html.html#proxyhtmlurlmap
    proxyiobuffersize	mod/mod_proxy.html#proxyiobuffersize
    proxymatch	mod/mod_proxy.html#proxymatch
    proxymaxforwards	mod/mod_proxy.html#proxymaxforwards
    proxypass	mod/mod_proxy.html#proxypass
    proxypassinherit	mod/mod_proxy.html#proxypassinherit
    proxypassinterpolateenv	mod/mod_proxy.html#proxypassinterpolateenv
    proxypassmatch	mod/mod_proxy.html#proxypassmatch
    proxypassreverse	mod/mod_proxy.html#proxypassreverse
    proxypassreversecookiedomain	mod/mod_proxy.html#proxypassreversecookiedomain
    proxypassreversecookiepath	mod/mod_proxy.html#proxypassreversecookiepath
    proxypreservehost	mod/mod_proxy.html#proxypreservehost
    proxyreceivebuffersize	mod/mod_proxy.html#proxyreceivebuffersize
    proxyremote	mod/mod_proxy.html#proxyremote
    proxyremotematch	mod/mod_proxy.html#proxyremotematch
    proxyrequests	mod/mod_proxy.html#proxyrequests
    proxyscgiinternalredirect	mod/mod_proxy_scgi.html#proxyscgiinternalredirect
    proxyscgisendfile	mod/mod_proxy_scgi.html#proxyscgisendfile
    proxyset	mod/mod_proxy.html#proxyset
    proxysourceaddress	mod/mod_proxy.html#proxysourceaddress
    proxystatus	mod/mod_proxy.html#proxystatus
    proxytimeout	mod/mod_proxy.html#proxytimeout
    proxyvia	mod/mod_proxy.html#proxyvia
    proxywebsocketfallbacktoproxyhttp	mod/mod_proxy_wstunnel.html#proxywebsocketfallbacktoproxyhttp
    qualifyredirecturl	mod/core.html#qualifyredirecturl
    readbuffersize	mod/core.html#readbuffersize
    readmename	mod/mod_autoindex.html#readmename
    receivebuffersize	mod/mpm_common.html#receivebuffersize
    redirect	mod/mod_alias.html#redirect
    redirectmatch	mod/mod_alias.html#redirectmatch
    redirectpermanent	mod/mod_alias.html#redirectpermanent
    redirecttemp	mod/mod_alias.html#redirecttemp
    redisconnpoolttl	mod/mod_socache_redis.html#redisconnpoolttl
    redistimeout	mod/mod_socache_redis.html#redistimeout
    reflectorheader	mod/mod_reflector.html#reflectorheader
    regexdefaultoptions	mod/core.html#regexdefaultoptions
    registerhttpmethod	mod/core.html#registerhttpmethod
    remoteipheader	mod/mod_remoteip.html#remoteipheader
    remoteipinternalproxy	mod/mod_remoteip.html#remoteipinternalproxy
    remoteipinternalproxylist	mod/mod_remoteip.html#remoteipinternalproxylist
    remoteipproxiesheader	mod/mod_remoteip.html#remoteipproxiesheader
    remoteipproxyprotocol	mod/mod_remoteip.html#remoteipproxyprotocol
    remoteipproxyprotocolexceptions	mod/mod_remoteip.html#remoteipproxyprotocolexceptions
    remoteiptrustedproxy	mod/mod_remoteip.html#remoteiptrustedproxy
    remoteiptrustedproxylist	mod/mod_remoteip.html#remoteiptrustedproxylist
    removecharset	mod/mod_mime.html#removecharset
    removeencoding	mod/mod_mime.html#removeencoding
    removehandler	mod/mod_mime.html#removehandler
    removeinputfilter	mod/mod_mime.html#removeinputfilter
    removelanguage	mod/mod_mime.html#removelanguage
    removeoutputfilter	mod/mod_mime.html#removeoutputfilter
    removetype	mod/mod_mime.html#removetype
    requestheader	mod/mod_headers.html#requestheader
    requestreadtimeout	mod/mod_reqtimeout.html#requestreadtimeout
    require	mod/mod_authz_core.html#require
    requireall	mod/mod_authz_core.html#requireall
    requireany	mod/mod_authz_core.html#requireany
    requirenone	mod/mod_authz_core.html#requirenone
    rewritebase	mod/mod_rewrite.html#rewritebase
    rewritecond	mod/mod_rewrite.html#rewritecond
    rewriteengine	mod/mod_rewrite.html#rewriteengine
    rewritemap	mod/mod_rewrite.html#rewritemap
    rewriteoptions	mod/mod_rewrite.html#rewriteoptions
    rewriterule	mod/mod_rewrite.html#rewriterule
    rlimitcpu	mod/core.html#rlimitcpu
    rlimitmem	mod/core.html#rlimitmem
    rlimitnproc	mod/core.html#rlimitnproc
    satisfy	mod/mod_access_compat.html#satisfy
    scoreboardfile	mod/mpm_common.html#scoreboardfile
    script	mod/mod_actions.html#script
    scriptalias	mod/mod_alias.html#scriptalias
    scriptaliasmatch	mod/mod_alias.html#scriptaliasmatch
    scriptinterpretersource	mod/core.html#scriptinterpretersource
    scriptlog	mod/mod_cgi.html#scriptlog
    scriptlogbuffer	mod/mod_cgi.html#scriptlogbuffer
    scriptloglength	mod/mod_cgi.html#scriptloglength
    scriptsock	mod/mod_cgid.html#scriptsock
    securelisten	mod/mod_nw_ssl.html#securelisten
    seerequesttail	mod/core.html#seerequesttail
    sendbuffersize	mod/mpm_common.html#sendbuffersize
    serveradmin	mod/core.html#serveradmin
    serveralias	mod/core.html#serveralias
    serverlimit	mod/mpm_common.html#serverlimit
    servername	mod/core.html#servername
    serverpath	mod/core.html#serverpath
    serverroot	mod/core.html#serverroot
    serversignature	mod/core.html#serversignature
    servertokens	mod/core.html#servertokens
    session	mod/mod_session.html#session
    sessioncookiename	mod/mod_session_cookie.html#sessioncookiename
    sessioncookiename2	mod/mod_session_cookie.html#sessioncookiename2
    sessioncookieremove	mod/mod_session_cookie.html#sessioncookieremove
    sessioncryptocipher	mod/mod_session_crypto.html#sessioncryptocipher
    sessioncryptodriver	mod/mod_session_crypto.html#sessioncryptodriver
    sessioncryptopassphrase	mod/mod_session_crypto.html#sessioncryptopassphrase
    sessioncryptopassphrasefile	mod/mod_session_crypto.html#sessioncryptopassphrasefile
    sessiondbdcookiename	mod/mod_session_dbd.html#sessiondbdcookiename
    sessiondbdcookiename2	mod/mod_session_dbd.html#sessiondbdcookiename2
    sessiondbdcookieremove	mod/mod_session_dbd.html#sessiondbdcookieremove
    sessiondbddeletelabel	mod/mod_session_dbd.html#sessiondbddeletelabel
    sessiondbdinsertlabel	mod/mod_session_dbd.html#sessiondbdinsertlabel
    sessiondbdperuser	mod/mod_session_dbd.html#sessiondbdperuser
    sessiondbdselectlabel	mod/mod_session_dbd.html#sessiondbdselectlabel
    sessiondbdupdatelabel	mod/mod_session_dbd.html#sessiondbdupdatelabel
    sessionenv	mod/mod_session.html#sessionenv
    sessionexclude	mod/mod_session.html#sessionexclude
    sessionexpiryupdateinterval	mod/mod_session.html#sessionexpiryupdateinterval
    sessionheader	mod/mod_session.html#sessionheader
    sessioninclude	mod/mod_session.html#sessioninclude
    sessionmaxage	mod/mod_session.html#sessionmaxage
    setenv	mod/mod_env.html#setenv
    setenvif	mod/mod_setenvif.html#setenvif
    setenvifexpr	mod/mod_setenvif.html#setenvifexpr
    setenvifnocase	mod/mod_setenvif.html#setenvifnocase
    sethandler	mod/core.html#sethandler
    setinputfilter	mod/core.html#setinputfilter
    setoutputfilter	mod/core.html#setoutputfilter
    ssiendtag	mod/mod_include.html#ssiendtag
    ssierrormsg	mod/mod_include.html#ssierrormsg
    ssietag	mod/mod_include.html#ssietag
    ssilastmodified	mod/mod_include.html#ssilastmodified
    ssilegacyexprparser	mod/mod_include.html#ssilegacyexprparser
    ssistarttag	mod/mod_include.html#ssistarttag
    ssitimeformat	mod/mod_include.html#ssitimeformat
    ssiundefinedecho	mod/mod_include.html#ssiundefinedecho
    sslcacertificatefile	mod/mod_ssl.html#sslcacertificatefile
    sslcacertificatepath	mod/mod_ssl.html#sslcacertificatepath
    sslcadnrequestfile	mod/mod_ssl.html#sslcadnrequestfile
    sslcadnrequestpath	mod/mod_ssl.html#sslcadnrequestpath
    sslcarevocationcheck	mod/mod_ssl.html#sslcarevocationcheck
    sslcarevocationfile	mod/mod_ssl.html#sslcarevocationfile
    sslcarevocationpath	mod/mod_ssl.html#sslcarevocationpath
    sslcertificatechainfile	mod/mod_ssl.html#sslcertificatechainfile
    sslcertificatefile	mod/mod_ssl.html#sslcertificatefile
    sslcertificatekeyfile	mod/mod_ssl.html#sslcertificatekeyfile
    sslciphersuite	mod/mod_ssl.html#sslciphersuite
    sslcompression	mod/mod_ssl.html#sslcompression
    sslcryptodevice	mod/mod_ssl.html#sslcryptodevice
    sslengine	mod/mod_ssl.html#sslengine
    sslfips	mod/mod_ssl.html#sslfips
    sslhonorcipherorder	mod/mod_ssl.html#sslhonorcipherorder
    sslinsecurerenegotiation	mod/mod_ssl.html#sslinsecurerenegotiation
    sslocspdefaultresponder	mod/mod_ssl.html#sslocspdefaultresponder
    sslocspenable	mod/mod_ssl.html#sslocspenable
    sslocspnoverify	mod/mod_ssl.html#sslocspnoverify
    sslocspoverrideresponder	mod/mod_ssl.html#sslocspoverrideresponder
    sslocspproxyurl	mod/mod_ssl.html#sslocspproxyurl
    sslocsprespondercertificatefile	mod/mod_ssl.html#sslocsprespondercertificatefile
    sslocsprespondertimeout	mod/mod_ssl.html#sslocsprespondertimeout
    sslocspresponsemaxage	mod/mod_ssl.html#sslocspresponsemaxage
    sslocspresponsetimeskew	mod/mod_ssl.html#sslocspresponsetimeskew
    sslocspuserequestnonce	mod/mod_ssl.html#sslocspuserequestnonce
    sslopensslconfcmd	mod/mod_ssl.html#sslopensslconfcmd
    ssloptions	mod/mod_ssl.html#ssloptions
    sslpassphrasedialog	mod/mod_ssl.html#sslpassphrasedialog
    sslprotocol	mod/mod_ssl.html#sslprotocol
    sslproxycacertificatefile	mod/mod_ssl.html#sslproxycacertificatefile
    sslproxycacertificatepath	mod/mod_ssl.html#sslproxycacertificatepath
    sslproxycarevocationcheck	mod/mod_ssl.html#sslproxycarevocationcheck
    sslproxycarevocationfile	mod/mod_ssl.html#sslproxycarevocationfile
    sslproxycarevocationpath	mod/mod_ssl.html#sslproxycarevocationpath
    sslproxycheckpeercn	mod/mod_ssl.html#sslproxycheckpeercn
    sslproxycheckpeerexpire	mod/mod_ssl.html#sslproxycheckpeerexpire
    sslproxycheckpeername	mod/mod_ssl.html#sslproxycheckpeername
    sslproxyciphersuite	mod/mod_ssl.html#sslproxyciphersuite
    sslproxyengine	mod/mod_ssl.html#sslproxyengine
    sslproxymachinecertificatechainfile	mod/mod_ssl.html#sslproxymachinecertificatechainfile
    sslproxymachinecertificatefile	mod/mod_ssl.html#sslproxymachinecertificatefile
    sslproxymachinecertificatepath	mod/mod_ssl.html#sslproxymachinecertificatepath
    sslproxyprotocol	mod/mod_ssl.html#sslproxyprotocol
    sslproxyverify	mod/mod_ssl.html#sslproxyverify
    sslproxyverifydepth	mod/mod_ssl.html#sslproxyverifydepth
    sslrandomseed	mod/mod_ssl.html#sslrandomseed
    sslrenegbuffersize	mod/mod_ssl.html#sslrenegbuffersize
    sslrequire	mod/mod_ssl.html#sslrequire
    sslrequiressl	mod/mod_ssl.html#sslrequiressl
    sslsessioncache	mod/mod_ssl.html#sslsessioncache
    sslsessioncachetimeout	mod/mod_ssl.html#sslsessioncachetimeout
    sslsessionticketkeyfile	mod/mod_ssl.html#sslsessionticketkeyfile
    sslsessiontickets	mod/mod_ssl.html#sslsessiontickets
    sslsrpunknownuserseed	mod/mod_ssl.html#sslsrpunknownuserseed
    sslsrpverifierfile	mod/mod_ssl.html#sslsrpverifierfile
    sslstaplingcache	mod/mod_ssl.html#sslstaplingcache
    sslstaplingerrorcachetimeout	mod/mod_ssl.html#sslstaplingerrorcachetimeout
    sslstaplingfaketrylater	mod/mod_ssl.html#sslstaplingfaketrylater
    sslstaplingforceurl	mod/mod_ssl.html#sslstaplingforceurl
    sslstaplingrespondertimeout	mod/mod_ssl.html#sslstaplingrespondertimeout
    sslstaplingresponsemaxage	mod/mod_ssl.html#sslstaplingresponsemaxage
    sslstaplingresponsetimeskew	mod/mod_ssl.html#sslstaplingresponsetimeskew
    sslstaplingreturnrespondererrors	mod/mod_ssl.html#sslstaplingreturnrespondererrors
    sslstaplingstandardcachetimeout	mod/mod_ssl.html#sslstaplingstandardcachetimeout
    sslstrictsnivhostcheck	mod/mod_ssl.html#sslstrictsnivhostcheck
    sslusername	mod/mod_ssl.html#sslusername
    sslusestapling	mod/mod_ssl.html#sslusestapling
    sslverifyclient	mod/mod_ssl.html#sslverifyclient
    sslverifydepth	mod/mod_ssl.html#sslverifydepth
    startservers	mod/mpm_common.html#startservers
    startthreads	mod/mpm_common.html#startthreads
    stricthostcheck	mod/core.html#stricthostcheck
    substitute	mod/mod_substitute.html#substitute
    substituteinheritbefore	mod/mod_substitute.html#substituteinheritbefore
    substitutemaxlinelength	mod/mod_substitute.html#substitutemaxlinelength
    suexec	mod/mod_unixd.html#suexec
    suexecusergroup	mod/mod_suexec.html#suexecusergroup
    threadlimit	mod/mpm_common.html#threadlimit
    threadsperchild	mod/mpm_common.html#threadsperchild
    threadstacksize	mod/mpm_common.html#threadstacksize
    timeout	mod/core.html#timeout
    tlscertificate	mod/mod_tls.html#tlscertificate
    tlsciphersprefer	mod/mod_tls.html#tlsciphersprefer
    tlscipherssuppress	mod/mod_tls.html#tlscipherssuppress
    tlsengine	mod/mod_tls.html#tlsengine
    tlshonorclientorder	mod/mod_tls.html#tlshonorclientorder
    tlsoptions	mod/mod_tls.html#tlsoptions
    tlsprotocol	mod/mod_tls.html#tlsprotocol
    tlsproxyca	mod/mod_tls.html#tlsproxyca
    tlsproxyciphersprefer	mod/mod_tls.html#tlsproxyciphersprefer
    tlsproxycipherssuppress	mod/mod_tls.html#tlsproxycipherssuppress
    tlsproxyengine	mod/mod_tls.html#tlsproxyengine
    tlsproxymachinecertificate	mod/mod_tls.html#tlsproxymachinecertificate
    tlsproxyprotocol	mod/mod_tls.html#tlsproxyprotocol
    tlssessioncache	mod/mod_tls.html#tlssessioncache
    tlsstrictsni	mod/mod_tls.html#tlsstrictsni
    traceenable	mod/core.html#traceenable
    transferlog	mod/mod_log_config.html#transferlog
    typesconfig	mod/mod_mime.html#typesconfig
    undefine	mod/core.html#undefine
    undefmacro	mod/mod_macro.html#undefmacro
    unsetenv	mod/mod_env.html#unsetenv
    use	mod/mod_macro.html#use
    usecanonicalname	mod/core.html#usecanonicalname
    usecanonicalphysicalport	mod/core.html#usecanonicalphysicalport
    user	mod/mod_unixd.html#user
    userdir	mod/mod_userdir.html#userdir
    vhostcgimode	mod/mod_privileges.html#vhostcgimode
    vhostcgiprivs	mod/mod_privileges.html#vhostcgiprivs
    vhostgroup	mod/mod_privileges.html#vhostgroup
    vhostprivs	mod/mod_privileges.html#vhostprivs
    vhostsecure	mod/mod_privileges.html#vhostsecure
    vhostuser	mod/mod_privileges.html#vhostuser
    virtualdocumentroot	mod/mod_vhost_alias.html#virtualdocumentroot
    virtualdocumentrootip	mod/mod_vhost_alias.html#virtualdocumentrootip
    virtualhost	mod/core.html#virtualhost
    virtualscriptalias	mod/mod_vhost_alias.html#virtualscriptalias
    virtualscriptaliasip	mod/mod_vhost_alias.html#virtualscriptaliasip
    watchdoginterval	mod/mod_watchdog.html#watchdoginterval
    xbithack	mod/mod_include.html#xbithack
    xml2encalias	mod/mod_xml2enc.html#xml2encalias
    xml2encdefault	mod/mod_xml2enc.html#xml2encdefault
    xml2startparse	mod/mod_xml2enc.html#xml2startparse
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_0.html������������������������������������������������������0000664�0001751�0001751�00000001310�13751537426�021054� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: new_features_2_0.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: new_features_2_0.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    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.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/LICENSE��������������������������������������������������������������������0000664�0001751�0001751�00000026136�10147723030�016041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������                                 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.
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/content-negotiation.html���������������������������������������������������0000664�0001751�0001751�00000001021�13710016232�021672� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: content-negotiation.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: content-negotiation.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: content-negotiation.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: content-negotiation.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: content-negotiation.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/getting-started.html�������������������������������������������������������0000664�0001751�0001751�00000000474�13741307256�021037� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: getting-started.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: getting-started.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: getting-started.html.ru.utf8
    Content-Language: ru
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/configuring.html�����������������������������������������������������������0000664�0001751�0001751�00000001104�13710016232�020216� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: configuring.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: configuring.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: configuring.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: configuring.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/dns-caveats.html�����������������������������������������������������������0000664�0001751�0001751�00000000751�13710016232�020123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: dns-caveats.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: dns-caveats.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: dns-caveats.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: dns-caveats.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: dns-caveats.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    �����������������������httpd-2.4.64/docs/manual/filter.html����������������������������������������������������������������0000664�0001751�0001751�00000001046�13710016232�017176� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: filter.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: filter.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: filter.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: filter.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: filter.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: filter.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/invoking.html��������������������������������������������������������������0000664�0001751�0001751�00000001212�13710016232�017530� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: invoking.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: invoking.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: invoking.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: invoking.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: invoking.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_2.html������������������������������������������������������0000664�0001751�0001751�00000001010�13710016232�021031� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: new_features_2_2.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: new_features_2_2.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    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
    
    URI: new_features_2_2.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/upgrading.html�������������������������������������������������������������0000664�0001751�0001751�00000000321�13710016232�017664� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: upgrading.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: upgrading.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/custom-error.html����������������������������������������������������������0000664�0001751�0001751�00000001112�13710016232�020344� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: custom-error.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: custom-error.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: custom-error.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: custom-error.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: custom-error.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: custom-error.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/BUILDING�������������������������������������������������������������������0000664�0001751�0001751�00000000146�11562045315�016152� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������For instructions on building the manual, see
    <https://httpd.apache.org/docs-project/docsformat.html>.
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/handler.html���������������������������������������������������������������0000664�0001751�0001751�00000001211�13710016232�017320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: handler.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: handler.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: handler.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: handler.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: handler.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: handler.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    
    URI: handler.html.zh-cn.utf8
    Content-Language: zh-cn
    Content-type: text/html; charset=UTF-8
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/logs.html������������������������������������������������������������������0000664�0001751�0001751�00000000706�13710016232�016657� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: logs.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: logs.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: logs.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: logs.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: logs.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������������������������������������httpd-2.4.64/docs/manual/sections.html��������������������������������������������������������������0000664�0001751�0001751�00000000732�13710016232�017541� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: sections.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: sections.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: sections.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: sections.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: sections.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������httpd-2.4.64/docs/manual/stopping.html��������������������������������������������������������������0000664�0001751�0001751�00000001212�13710016232�017547� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: stopping.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: stopping.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: stopping.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: stopping.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: stopping.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/glossary.html��������������������������������������������������������������0000664�0001751�0001751�00000001212�13710016232�017547� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    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=UTF-8
    
    URI: glossary.html.es
    Content-Language: es
    Content-type: text/html; charset=ISO-8859-1
    
    URI: glossary.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: glossary.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: glossary.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: glossary.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/new_features_2_4.html������������������������������������������������������0000664�0001751�0001751�00000000477�13710016232�021053� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: new_features_2_4.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: new_features_2_4.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: new_features_2_4.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/urlmapping.html������������������������������������������������������������0000664�0001751�0001751�00000000744�13710016232�020073� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# GENERATED FROM XML -- DO NOT EDIT
    
    URI: urlmapping.html.en
    Content-Language: en
    Content-type: text/html; charset=UTF-8
    
    URI: urlmapping.html.fr.utf8
    Content-Language: fr
    Content-type: text/html; charset=UTF-8
    
    URI: urlmapping.html.ja.utf8
    Content-Language: ja
    Content-type: text/html; charset=UTF-8
    
    URI: urlmapping.html.ko.euc-kr
    Content-Language: ko
    Content-type: text/html; charset=EUC-KR
    
    URI: urlmapping.html.tr.utf8
    Content-Language: tr
    Content-type: text/html; charset=UTF-8
    ����������������������������httpd-2.4.64/docs/manual/images/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�016305� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/feather.png���������������������������������������������������������0000664�0001751�0001751�00000051231�13154224322�020420� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��������;���bKGD�6�6�68~���	pHYs��������tIME	-���tEXtComment�Created with GIMPW�� �IDATxwxUו$TB$Qmqlv'v8L&3d2%ɤMIq&̤ql'km\q0#	!ބzq$Tsmtkϩ;	5y?
    \-)yі$s.ͽ[_	Hԫ9<xF5+}ضQ|n!x!c&""�Ax5<z~xiGb;~	-5H
    EEƶ~դ<xHx{=_wj1uv^b"u="މ	*'^mz0|xiN/+4$HPS-˴]|1<xAc;?$V>*'RZI$o&""	G󤠢D0efTP,:("\|a-@'3&py}>r򥠼؛G<?'[?�jKFw-H-ҾZɻJY1溻r30KD/>+v(ɵVZ*(Q iZVUX`աΥ~#;/C=Zl_-틝vی9bA5"2dcpT#XȲ}%%gkc@ГL�9bAEɐnz<Mk9c}vȀBH>W%H祏$T钸.;/KbI>)]u4,doNb#
    ""la7aGv^n"ceK+Frߍ5V7&yFR<Ù}K) 0!k}*O\bzIU_D~(Ybo1gV2U\99#20w�)p:؎_"-3
    r]"
    8Gvf8ʴ5k,
    ;4۷wucI]X/Pmr(;Gȟ/I}wˌI+Ddw*e^ȧLALn,0EEExYEZO&[><X^~|PrD
    Otzݿ�"*&}3i}<Oɸu,pA`2PDvTysSFJ|3y_'IK䖢sinϞWsA6YC<Fb!:h#a-Gq|$Zc}/^uj'מN	7[MxWC~]"X&"bE[;CoLkXЏjf;Rw߈:BpZ4|Qv
    HߓbޖߠUY�}W{Jh+GO[~*"='Joxt1*X?*3Õ@
    
    ERGre1wFJQvEZPDO
    -y�n:Mo=]V�RXH3֦$\ca+i7<zD=Ȁ>u#gΚlI~VDM,ʇEwd1Sްw*cC&ܨ7GE1QL;ˇedX{ok=<끼
    |[N"o.#!aCC:&Xgi ocaN~hU֜iod 򞬉)y  
    .y+A5F_ͿZLT5s.c&@w o3$DOF3-NorPI~,%xqd
    -=ArlEOZ
    zlyh6ix8uⳄƵT$y 8ZgnU&6i}Ȱ-;B"l(ɝoM.JqAB,"m)(/yn9M[⬝]Ya?>5gNHl8:-)AxAmhmXK̶A|ɶLtEeBzTt	G1B#đNTдnbw'$3&
    &JƚbMRx[τ+X)7/@LU>o"cOSoGbnTmDJ"_(BW-f|-Zbc&`YKlWsjݏh*}(Y}{b,UՇJ;2}^mieXVfĹDvy/}S๻|qPKaMhRQ6ϕؚIÍڼai8Fq3pI	LS]&`im]݃}G`boia�kM?ew3֠Dڭb˖ްaHN
    [b#WkIxxV+3B׊[ઘ9盺vuK$R/?|`XޞrwW|;wmy.(yfkvޗ}D#娪Rm"ɜN?VFOCk	&56$/݃L;,*c1B[0Jۂ8t
    FQ!ȆD.؏J֪챷Qq7sXq`r)<uV3W?uؑ
    z`8}y ے;LOM
    âF 1/5*ucuuD~>&�-(�>mVޯ,#a~)jp2Cz&#KJ|?klhDbAIf 	o@*)p$~Z!RFp:qr&&!1؅{eFX⾔{qO9|_l_cC}P
    rF^͚e7r!8𼻌#FH֜9|˙tE)/(/Zy+y~͸A<x|@o{ ߝ&	:
    ǀ?ԁpn(Dj|&J#dL[6 *"ND94nܩEyE$3dI7"TF^l%[OyQoG\E?mfa;qnᠺ9_|(w֡u+˃&qUjm|Qxb	շs:(	7~#hS]ߜ6R	Y0>7"+-T7挘Y\_.&٥=:{y1<T/sʋ1+Y"qO1Cꙭ('vqoS-֐-(bmTSVŔw(߻<pĀ�m~{pIa s+)8uUD$R:m~FO&0{U3je4co?SpYX^4+wh(ōQ]8=@V'#c,OzU6-W޴PUwR8>Kn(;d1|~MΖp|d+*3ƒۖUQO*RĪ%IoMvpYuڈȝӪ6f_o߈p'	?{-)ece+c@2Y*<ێ$zgT!qD='};2G67;Vx{,WG#<`jnVb6MEی:wo{3=TSs}{vD9�>>`v*]Ɉ:)(/n;3Gr&ߘ?e#N>nlL�sK%c^9&k5@m9sݼ"|lUY<xpK�>'uO#%k0RDk	n?Mv;_g$0ke!hZbQP|/,SLnv:X5PIEGˇh];T喎3>gzAyc޴/�DQpj;pBn%cRdBhH(%A-Uu0Q%SDIf l|6'kTy:@K2d!b]o+܌=ux[뱘>
    \]	jd0݂7e{pTuj{wmH؝J$4BG+T~!NN;Cg-%8RIJMkѮ-,٬G`8
    8Kc}Aq]H-˘1]]vuo*wG-T9كFWB?(/9M<."Ahx)j;!I[~Bs"oҎ;y]~o%x-ވBY΢ٙ 8W4wugG<qLz5q$%6hT~|9{ĕ4,e[Cݏ.ߺu:uY57GD\S8b~M<1T?z/m߻!Z.Id;7z&*td/#i&"Il{Zwucuy}qz<R.Iˊ^9K(D,nq"ghϹ屏<֭ρ%eMD|~OcB׷=w+M<'['ڧmTa?5h—:XdZ\OZv5V֬*mr)Y=MgӢv/<Q'~QDzdZ#ъ<{{@ܭ[.E"C=o:sp?߂<5)N"p*&f̞Gˏb%B&y#x>vBZ|ETP^r]$kU뱓//v^{_֯"ҫ)p񶙹K+KF`Bjz'?KI5TyfMyy{K*QW(K;O?꜆K*JL t8BgF$|-gN!Lĉj^
    j=@Ijz?N]};>4,_G,D."iQ=b'Z1m,][4Z ם-?q\C~9e?._du
    nL˕Ѡj6rPͼ;
    /&-ݶſZZc F4۾`GEd켋pa`x@@`Ղ5c# mXzK"
    W퓏+]HVm?3lu#.m$AjoGqRZU^4fY5"DnAX.Jc-g,eniEs<-J(fp('Jb[DX}iE{+\/Խ/+G6;k<7sJPZFI<m(0ϘHC^p9C"<�
    [q11BXJ\Dnz-%&"%$tKXҎK"M!e͍Xm$a/bT~nc\bpZ43\?rزR0smcbUM%N5g8KݥTF~ߗ7[[
    `\/}Ei<YC)
    qՅdOcS3	F0By#6h$?=Ljn?IbOB+$urzG#6W̞z{4fYrrĥj%%}#D\5k}؇s>qc(;1ݣʘMK
    g.ŐJ>V܃[WBU<AO4)&j"ȭTƬmo=xWƀk8qõ7a%i/rIe%.-U[,$VWŊTy+km^>m9s,Vzv7gA>saEq=#.ٲ@ԧlK<-@R '{abi)vkSө]vr3^nmR`ޞ;ѫpgHb@RPQRݯNaM?rT?3+x>9yY]6[|-nowHQK*JoZƘ_	"x='wY.R."pUVꁿҸmgN`"izq$/=Yջo.cHYNn5\A//,ehRGUeWZRY3"]rĀJYˋ*zE_Z]Y>!yUY]³@ERgM0Pnzx]4bS E P6NWqt(YA4~L>R.^R3;R]GJNA<gZ*Y(LuY\4KG\f@/
    W0wgXd`0+ YEKn܋Y21}T'rͲ_[upw(ȔFKm<xp~8pH1(U<N"�N@7n)+VQ̓j۬IX떀Gڕdܭė>UED.Wa<UyխVb%yO+rĎʋ 'E9un	W@Z[$w*LFdL?3r+K@]zT`Y{{[^Y(;UD)As;w~Ss[ⲝ`Lka1Of8\U@jS/Ps8g*0-HGWF{ETAL^ΐ6)H]o$`Nv*0jv^Yd|N=(k7].X3%5NY?[rjxn9SʼAj6lwma[ҢbO~ШnaA	p.JhU5U<нJ'	MLʪT?09u\ $ibRV^џEL'>4KƐGbWU
    ť
    s rް=;%%OGo]VVqѢʽUe%"`T<puLDžď	F+ϡ9N"gCY "%ϑ$m
    ;_F+U֠c~N ~S>M7P*e+DQ^|)nЦEJH%—:Xc~沽H,J҂ys{6d
    <3LO
    kcjEVwmò~;n)ʍ;^U1gcg=pYX
    =Dm4W*E!'XȻ~?;ENU}Z1EΕjԊЍ#![V7*k䖊T=,&i]oTRW/'G9;Սj[ߗ(㕈V[B2Ƿ
    Q=F#{Ss`F<e3 $†3羰rO(?Օ}pcl#A\74`鎜|%4qXT43‚WUqn,{d^rd]?Ύ,7G[i-jmGͷ5@5㮹Xc3ڌiH(ѦB_۩XA{FZ\ׇWlsye*<䬏
    ܁``0WA:EƘe�y޲4pD53zU?p.+0qT?	gj	NFUT=8458Ih14/,+E`(;X-w{~:V=h0l\S瞥gMg_D̝ӟWBյe 71cV7e{p~HRc8s4en�� �IDAT /ijW{]@j[<5gy_K2ǔ~.v*nےp6Q8TGK+K(b'}y$bϒe#�
    |l!W$K<NȃYH_U?ԜxNP5Q!eBV
    �~2oOI:7Vo6JnR8
    a˚
    |8%/ݷi�RArn(C ܞ5+?/Gcѧ�׶P=w7m{LjWUI<0D"T?G%]fAeW`ZmͳXwM+"5Oiu3ed32Vnt(ԺX*h"
    AU
    KN#[a"J@Ʋ$p.Gs"C+*""]E~0?}e=$=x87	\DTU?P_ńm*>+/(H\ԋbBA�-pٳle9ݳKUY<D^beouKE
    +梲=Cf}bX͹ 8@~Or^1.Κ?~x0i	s<ډj݊ѨCͦWz{%BYӅ"rx
    ,/\;r_]\^|xs'#uwHn97/./%0w""kr-(/ypB`Y{<*0{K�C[Ծ	w)'o4qq=y._;
    iL-lOq9X*²w)9C9<;?CqwzcY\ܰ#'C]7Ϟ<× W0zn
    iտpg^QLbf
    kyŸ;.vqQ_f&S�n"2K*׸5`.0Y`YG\Z޿+@\9Q5n#7{‚m9y,-/sD׊O�n
    7 7wy[w[vep7qLg'^g{x
    `\[{\i$B r{X]s5ϾLR\X(`[,]ĸk 96-eMJ
    ̲GdN婘c>|鱡năY\"WG	zYZYpd('_V\
    WHF'\EۗU6u%|M`t|koX}hw׹=F
    =av;\1{οVU`zrjގim錻r׮~Xu-
     ݞ7ƧrK=pX o=FyDU{f sַr
    ;Zߪ	۳'+>;G$'lڑIro9G�̽rzi	_34#GJzQIe4z6Hipg%%1
    Խ]tgeL2vzѪST=Տm?i5f4S.ߌ]hk"lُoi}ޏ뀢|w8b)D}ZZQ,	>˶gsfOّ5ޞk<eu|뭙y.rŎl)Dܸ{Y;%熼^>1jԍ(zBp5iw<1&T㹧YI`D|goOB\i[	1]1߹A})70hRP�p0Tζ26|w*|U]5kve<̿Lo=\PQaϴ]K0ذu컖(זo}@LZΓW
    g9ۨQ6b	DN̲ŲXfOx:$Dv"@W?bj`BsANh]Cs7R_ko\142HΟ-CcJDmW-R>Dn*;r^�>�=>MCEz#GPo{W/hs|>=;e&O
    ֵmJ^(Mn9HO,"lk=LaO(u?,�uvP\NOj}UK3o'x';CJ=AD̘Ɣ[}]83Vk&!^+(<,f
    ErD]F>1fѨj5+w*ܜPm.<墊}B@DVDTD
    OxFUF,s}AٞC;RdF
    Uza]u^Aîٞ\HG>ŸkP,!nif`p:e%Y.{HGJc-,Vc6
    nX9qbxԞYr+
    7k)yUW_4I׵]A;�Y׭ܷ0<&ogVа]{ϔeE8ܫҥ![G"@_E?EEIϊH`0g(%.WAՁz	x]=*5ks' rQKk$?]>>BtK>w>jPN{_&t҃{h#:-ڼHZ+0Jg^stM,O+oP^6N[�"g~Υ*O]\'<:
    Dž)V>X7
    [}%#)viC?'RY^f@HK(QI<HA·*oۊ8(%v Tqt$Nhu]{=v'LQ«RǴnw3ع"W;"b=4;}p/ܡ<7xvnƹyވ|o$#Y[Tխf`;*`.WջCAB
    3x?|vg)eOK֭ijjӫӣAp4y&&?UAܙa4/,HDK*K^tcG .A\m{|ϋ#8*cKDfT+KOT|ȠwP7~uqEKˋyaTx;>~7vnRjnSpͥnI=J=Kݭ1./ 8uR,�p91FrG2Fv"qS;5twm]?gވ;qx\;*J6;T&#
    w|qE<0	<д0u ޮ$kV0Mo$DR\К"2C$זTUa޶))1BmλJK]jb,D혪Ɉ\S83oPb/)/qEͪ!El{:!`ZWT|Xipqh&8�c/1bֶÑ:rI?qjvҰ [-	k"d^qoPӎפ{{c2?w6"z-wmdSD}ķ\H0,99EǢ#ޣERfҳ-pضdr	[y1Jqow3ҀT %%~B<v|4ѿZZT[/
    c&I=b\8Lҏ@�SX$`XK-EM/˜vKໟϢX;-ݿeK{q|N&t5D#IAyɈ[/Jp$ëᭋ ?I(4Qcp`پw'Η^?	Ty1Ja4?̩W0QsuI0kZtFbCd^
    dq%qw	G.{7L4F[e4Vu:5u+)Mާح2֭"yLNxƒ<xOTSf)N Xģ(JնǭYrmĚ=:q'&M ¥<x#aaܑxۇ$3YBCNdI]|
    ȸd%iKڢ;F.
    ]UWQc-9@}.UIΚL;54X_p_q!'"h<xI]`,ZHNN-aaNm+8څbm+`qV2vKd3b�-'k+ޟyX7K;k-x:'"<	MOS鸇=EĚÜxypz;߳ud\ccU<ԗxu+@pB-xQ37FjKŤk׵^|YU#p<xp`XρG뛨+=\vj%s	N6j`ג6o<	SpNb\C9c/tI\lV0iE"<	b�jh8p0isg2 h>~K)ssKxYDI<x]@U35&x=Ahi@%C&2pN<x#p3՚CuPf:.^D}Qʎt3J؝+5| s,YWx/<չ<x8W1*0@)"'"vjsڢ9$Mb§{8muRqd|%V둷<x$~"B$(laMċ. \@U^Uا!)xZf}ZȗwU
    G<HHD&OAa5AcgOc\Nx$N}froyM<QK�ꇁ	Jsu#5
    8bb;	\s5ڭӻߩ3}W23 "ys<xxϘF?VJ4w$DvT?+mf2h>^MM6պғ"bry{'W-D_Rٲ=x4bs<yڦT`iөFT,!&6V@sHɚHU>Uwc<m"o_/ǗıP(eM>5<x$aiui/^`o1PՀ',Al[rj[Kp][%&gM$P\eWJxau<x#np�XfMū{)D,q9ѦH6- cX&,MÁԖF);S,%L\113&P]yMy\p*2'@܀^s{{ԫ//SB,~
    *(͇TLӉvx3fB9vOԞmLK&md/Ŕ5wA6�,=(ybGwT2},߰,{l<x#pw8|		:%X.(̔8�a+	țʔes\EL0]G}-N讃>EKu#M¿�ܐXTx<w!7,穝yPciǑ?#Ǩ8B
    M݋ `1b-"M4 #g"r&]05Ed'}{F
    z)̺d.GvkmI |K
    
    1XCpw2iV~l=9c)ۃ<o*_U@rY2)=~K? )cY+gۇQ!.}9Lm~TKYwa!P ,"#o<xx?"oDLY8Cofg\ySN&AwJSƲu\6%}"R5<x8_1T?7MXPjf	V,fڒlI*+ELBn[ZC2f|*R𞕌Τ!?2 ̃<xo)`\{	'D!uR:Y˲inX6yk	S{c#o<dRj/Y)AklK4i=xG}F'6jw|qcv4B%NJ#)3ȡ�2ff65P}Z7rkj԰[U-Q&O]Mʄ6^S3@fƘƤ})`ssseYɭG"Uiii-"PqjwniX,Vɺ!xD"mo $,h4|(p-7t͍h4PUUU.[ZZfHGPehjjfvjk=P-bb2>|8iĉZu)0
    1ZSSSFOv˻жˁļN\|@Ub`1;Ut1w->|o$czRhnbKD#|Z_ǾeZھ'Q&o'3y.z.dHMO3|]D.ZuE_hyYD.nڶNiT,C7osp@4]eE"٪?ܷo}=
    ־-oUUnU}*[HdN(ڵ?o޼"2޲,kPWP,ssssV02~	q~>">epծ89))韁;D$Ec>o?l)&sbu9R?ocS	7GQ`̄4/AZ`eJۨ\KבwV^y{."W[P(t㪪ԁ8m{NgeY={vQ4]qգLyeY?1w?~|LuO'ݹs؞Oϗ:@+_cKE#w"]KD6|׌1tF"2N
    ۶0<4e(9VuBdkx:ߎ[#L5ITld=t2\soLֲll
    O|*##ڌHXuX<۶/--
    udffIͪYpEEE|y7|s}TO:/!/}L󖌌p8?~|1>˲-"PhK$Y<=pU
    �>i3o֓(RA҂dYq� B9!?Rh:/͜sIvŚ4ޛTuB7ƉȊNuds3'͝.
    ̐vRSSomݺ'"?"?Oo1{UŲ"XD.63c>vKU~uU�60l;ɓ'Rs3f̸pMHdtޱc֞Ou5�ڠ,]cǎ}XDu>^c&caUX5ٲ"nYyaojjZ|kRuV_ff"re7W@L�f%Nu4=ZZZ:3v*5IU:ZB[//ܯz]C
    ?вt׳oo?oܻE^/#j]*3cL?ro8󥾼.\h"a��IDATn_맱q8hv,,ʲ\oy1|15`_SS8'1m,eԤw>ǝ8:j$,1Weir[n25mgeayH']1H$>+`)kN,s?1o_‡v*cm9Vןg~IUuL
    d+in1ӻ8:ORM6RpйF~kDp٭ɓ)ƘNy,:_j*s,R:FWMi1@X.vc}Tߝż={
    8pI'pYz"2_MUTf'%?rwQUY&�!A@_.le9"X;*ZnnhrVnj3:3:QqwuuE(O	$w=gHytBwI~G_{y}瞻>,@Ļ@vrP(
    @#DJٖ-'O.kkkkD3R9sG:u^OD'+sMMeYֿ^t5jԡh4z̿]<,z8ń&۶+r#e}[kضgYuDpo(Ic4H	`>�#qt?”='LcWV�jMD	]k\d#">\v='*{u
    "޼etz{@ߑߝGK.˿>:3́:Åw䳭w}=\a8{GQ5!YLD!"�vC(9Ϝ��Q�c0lXCmo5leHa}_x3݇h̘17W(BYYYlj|lYַBquFBGh4Zm=3‚M8r3bB��P>}͟{!9&6ejll\b08̼Ak}w<q"*11cٰ۟OD&=m,r|,ooAv^$cs)**jȇ;TO12/cZpڜS{@D?E?xfJJRkc:4iRTkC"z*J"Z
    g}�o6669iҤ�:3$mO
    -ZtE)u0�'lE󺺺ƣ琡7鉮|,|Z[)6P(tèlikC0\�;ط*gM�4$GD#ǵ�<GDqD4϶w>22m^OD&ݿ�b-X,P{T(g*L5nuyye*>z8v�Fpx9_y*l`2Iq[WW`0zVknn>'�g8Uh%7]۵7}�WλY"mgd){4;oZ߶琚+DT�\L`Eyyy]k(y4LH^趀vʱ.5daȪ̮{쉦pq
    )|VGS!?PW{�d=|^C.3E)("*OvM
    BGwwwV�,}mJ"֏#ѓZ!3#gxRu+hER}naa-Ɍї."Y5nܸ\pC\l˼sΦyIU"{ؠ8묳ƧhCc>ll1cF>sS]�@w{7`1aX�E.(AD�lgID8	 *qgSf[\��b{1]
    wyk@$"/1}H$r]:mUiiDT$555jY1[~R+ЮU>@2WUU)fn06Is[g(:&+33gzNDct4zvVZv]pumopdbL?̝Z뛇ݻ@k}S"s=OU?*=2JPX,6ue3ᐙ6y"Pf[D&6f^(@MM5@^Bg�PF]װ}=4:cOF�dlt:ujh[Y~x)WED_:riqnM,z(nT\ͼ65
    E٥RqDα�iBJ7Cbpa#}G螽|lٲ�\s!T`.�D;سN;=&X-!�oCD>/^Gpkf^
     9Q.˲9%TϒOѭJy%
    \̛.�\Vlnn~1Gݐ*m 2WKF,\8TEEEf(oI@m#єR`-=D.**:f(gx5~wꊳz�}23s˲n!˲nX^RR#ms:RjmۯfDэpJ"z:i0"uW`z~$sIW`yԨQ$N+++76"՝;hympͧ;"H򔂂]<t4)vy&omY\kͨ|vƌyGKJ2'kY*"Z:zJ+>`jݹ.8-"OJ
    
    }\kk)(/3eSW']]]HC_s5Wwuu51-yy+=)V&ZW'O'8ZoG)^0z=;xD"%˲ j򶳉-"W7uOo{I~}7WDdLgtuu3;ץ:N3	93->̟h}A}K}b$u5R602ADZﶷ%+bͩ>I忣0qP`}=PJ-afN#('Xc˛]#+DsY>߸WIYv:q
    T}Bfnřy3o3}\ãґs+G0s<;3QZ'N$]Je	3W3}|%cƠN4/xJ~kϤy�ŚePc5WHʙb┻sDtACk}]EEEw
    ȽY۶WsDh}<`544>Htu8jEҩ&N"h)-L'w|eY}-p]"(OׯωmHWMDNܣZCޡr� m{0
    LZF�vqO
    z1-"Q^|\)uݍ&<𘈬	JJJVdqv:Ydv]wCww\y2Ӕ"RʶqO0";2ںtwt^}
    "dkktG�)"z|`
    [>#?!kٶ_[tYғy"3/߿P(T2WWWK,!x<$-ȑ#/16:d...n,x<>EDaSEQTeYcrf1m"FDvzeYKV.˲UJGD~|Ny󼙖eݕd+{?i^5ޯSxǸ$C6*}|%J<;7n02d׮]h4:_Ŧ766e)͋3x).}~[[[	DPD${|!"0x."�xCD@#؃f,�GD`09XDdKm<Ǽg~Ws`0rс7+ڴi1k
    O�|ۨ`0s"R`+�44b:\p7�4n|n0Cm��݈tPUu4,s:�_`1cf%Г;F`0�MM
    /8EE�JD;
    `Ƚٮ;EcCcl0Cn:|ɗ:L7g:�D�al0C""#^;uk]v`~`0r߉KrF`:XEDS'"65ah&�^����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/reverse-proxy-arch.png����������������������������������������������0000664�0001751�0001751�00000026666�12663316405�022575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��)��M���\���tEXtSoftware�Adobe ImageReadyqe<��-XIDATxp\WOK,˲ǶĿF!YBKJBZT-3Tl-D@
    J,Nj`.d`fnv$v;jۊO?ndߏ~~uyG�������������������������V_V|[?csD>Fo"sDxV1W9j]tnQvίy]yt4,5\ (H"qD61?̍Z^C,\ª3jP%}S!)pUZq
    \[L*5CA:іU4"1.iTV8^wP-Gy^	gQW'ZÖ�#
    �,!vx%։Op'lΧL޼N[BM*m"8O~ަE6[Uj�M9vP/gzcn�҈haIXzC-X!!>A|XJ]zy0%brK#(c|XX|"
    䲌LOXY\f.+
    @рYCBFBrYXH9s9n餰vzR㍋7(z;"U#Z-l]?fZ:YZ@XOeKX5'">n~5EcB$ocG
    cc
    
    S:@/E hݻkqGmG2t	@Fk
    p%-9BC~gfQ0>+LsskvCLn)W@r\p`5d[:<,{^↫cx{s<ɸPc:9>NaדV:X0X64x_-D[br'G+
    �����������������������������+8&jLρR
    )DKlT7ߠ/dJ<rSPMXAT¤)L:S[M7xߧu\F)չnݺtJ\1ez*=կ:M�%4~ʌ!?+~ھ}"ə|o;�0"RvM>ω!t):}Md/c@?=ھc$owZ>?>>~�"t;<Aљm6jϝo#?!PO|{e$-ag)-Tkg¿04Ǩ�4"Pڥg>�ڵkFe[<�xz1r2X֏.O?rcOxT2 %8D"ID쬫]{|J,; R+P_oZsKxjM6G>Q~KP<wiUUՌ$LƝK,'(IXV+**ijjJ,%RnT	||+|S$M#TV#?=CSp'-T&i;NeT
    dtA @LE??y&(q[ҙ3N={.[NYQ,nO?KoKg镗_ =�(q;'!JYnw/S,EIUD:/BǫtUGPW*(>h}q')ٕqI&ݹܼq	.Nx|fU@;w߼;
     R%RO5zn!L.ܷ˵3{LLRJ/Zf
    5H~{*jT	:~{%7N2'cN2Kt2tO.}gMMG;|6'(4*p	D`%2ݵw
    WMhKS"3ĺO9)INqqZ_]?@Joód2if972xXŅ[7bZFY)PqG|J&}^]6ZPh`<ZRz\5ʬ
    x%;Aյĥl/rKuϬuT]]O--@J�M`!TƜ\n{1et1Ԓ1L6#Xq#Xq#]|-D
    @aޢ_Ok}9- yfLi"9;(Lǽ�*NqEJf
    67S}}}J$r",z˭~jٻ)x2��*._ f
    hyu+HKƲWw98/=;zu.]"z�"U\ݑ;wu#Nڵ&z%e=	1tHT<s]#]tBuG4ǎg}RB;.zeMI0eVZ)mmⰢ֭kgKkkf
    #d&^z.@ŝG~X\x/^ؘiDH8<l.K_'-\3r?sRAĜwTR}x%@we9wCd댹ؓ)e=9@
    T/c2KK٬yv.PYcOxƨׯ_sFoxRPP-bYϟ=чjq*P#P_$vl<-wwz뭨.%P; REJueU~ėXɤBe(i\.vy	Դ3?-DtE`e~,=]U](@ך:+<|D>g8%Ǩdf�p2EEIXKb6YPf9.Zc|
    @ךPBrvoMNNQC*++=O2*EeȴLqb5u,VzXxjz5}"
    ̙ߔt]6龽{iΝTfQPx>OPĐl%fK8}5:
    T鈕_MB*T)7i/]v> _aC$s<Y"!Nz^0wUڈQ�"U@<6ߤRKcc]y[.[5{|lcBZI9i&KJqD
    BfƠWpÆ
    -[owhQeeUfL%6ڙqg
    _Enjq2Vԍ7�"DK[]kX0QN={ȧ,*q@@rCс@b[UUUh۶mnٖTq2Es�K*Tm쫫o,u^&NaJD@UR1jN-L<Ãj� R`+&~Nt=&>����������r+@P8է&S)peYcWb?U�~Ju0��E.A_=	/�*,)>���"��)��D
    �� R����@���"�H��D
    �� R����@��e	$oOgHk3z0A_tyL/;OwuNJ}ynn,LGQ%ZPi!H-m~J"E+lu
    4یry_c"#U:,AGsFy)c9lqs]o &9^7
    C;6!lf^Dx/DKݾC<1<LJ}M@ct>Y7�]pƸE2.W?d:	
    1F`+m(saqo0b#4[<3n(Hǣ�^s%z3cڵkTWWG>}1c͛9QvU3$,#BXҨpN
    a(&\V!^ƕ3KE/&,9î壮| vs2ū�"UܼkSOѕ+W2֯^&''%^xIn{9zH<+t7~8Vϫݱvat#0¢#	X\,QKp->ٕYbRשw@iVZEUUUN٤-4]xog?Y\
    ޽-؉Ee%myjānytWQu'E<
    Ե'K,E;__|kjjdxzgs$/+*"b6NFK,\, :*PBK,w`(	>cuX.M9D,̙tlmmXDE*dΜ�*t'&&`f֭WTTج:8nH~?㩝۪yh6N%fY:HnѨe$|s�T˗sN�$_0A��D
    �� R����2f[G'\	�`I� R����@���"��)��D
    �� R����@���"�H��D
    ������@��)��H� R�������"��d[ܩ%(]$�H)OM*:J2bUM
    ,_7�B*
    tDGOH}TjQi@	U;Wr
    2̸ipmT5#rY5HXDѱw�"UXH70�����"��)��D
    �������"��)��H-QC<Q�XRMR<��̟wm\1=J(
    �XdJn<)۶j2<|4M":Ma7yoȷzܛo.صkRΝ
    %J*:UfP7>7+ZEڵkՂdcR7hGO=y5e2:BƊoݺutbǧ�*6J7}쩫vjl_} 9qFV*~�^)qh-s|RAwyMNYT8-P�@J3@|Qe=-W|d'}t=ueԮYrcB
    @J?+RYL*ݸXAlJ:”oCtOi||n6RDmm%_ҧ*ZXyw?@Q2䴯[	R 9#IڒRb::4�TJJ:9i䫻j_\8)"RM#ĩE^pdEj2VTEtO\/^03kWReeX>7P90BeyR1Ϊڤr'y^ƝT瘩iJ**l^$w;6o㎌ΛZnܸQ(}:TRE *+)zh-b^-|Ab-&ַ1aN(oSz(Os#={ӗnڞ)C9f\5;@բߓ"`jj*cyFફ{܈M77nӀhtD C3Oo?u󶃼_3|"l(ic1	Q5s<QrLA#xeJZ>A*>/agԦO}jv:lŋ鮻rB:sQ_!RE؋saXq>QWX;zjI+r=cZ9/
    c{8aI;ej:	n|@r˻*
    oOYR*&7cESUhʹ2\+˲Xrtyi+W=1Vut		BpL97u
    	*[)l1l\#b*)M_VL~ىϯwn?XY(ӥ3
    u?'cebH=Bn65G
    @V_4R_bvg7xnVu;o<vѨUU-qZz5mٲ~'F\1aɴ{cWn	tGx-\VQh
    4O<=(t@E`W3l_ʲ";Üضml%yZc
    7~ 7l]y
    I7Zu~X`<s7*L0Cx]BpY/>L`H9x>#P>`lU_g_;SiaYN~{ƹuoqY&&(,X?Bo=i:Y(,3g*UR
    %SN<*Y)kv�[>~()yˑ&kjtח
    z͹"{W/\m!JO�Dj$CREꙞ爕Z(<5пu^sueHDj-8bN,jF\[ݻ|.�"$U)%PɈ6[PF;t<JwܱcG}�Es*Lh"%J~#Pi/\xAEЯ)c60'�E$RCVKzwRq늪ׯxeVھ=;HQ]n	U܄3eK,;gÿZ_W|cMJ7IROPzXS݉ѯҘX+|2Oc:PnIj97T(~py(].?cD[c4?wYY\~Q/v(FKJ~_F`<ilEm{)wgӦMtO_ݫ;BO;tFޮ�{\:?#m_Qz%_ynqc4C$ž#L\NWB,:AaJ3oL٢P,f#Bz!Q.HOXEoMƞ0񰒣`ݳg>%VT+K*t/,~!Jfr1c6
    a19Ae]aY(7!J}bsY$,QTq~ u".wNPz+s>Aa3j:FD>CUoP"Nxq,dF܊ZFKʍeayM3c$^F	r-"w4VG#d.b=#Š1xzmYtqL]vlH}}O+1VQGS'{i_eŊ-kE+bjrr/6
    ،_ÐpӚ1)s`/,N8r9rMR,
    l]5UatEu0h$IAHPԗ~3/}ʍHU5ɘ V~6LPeZ^Ze"5�UVU-;3ZA'D#F0[EAwѸ{ƍ:
    _="%vrh劉X%bEQCB@r@eu Qn!ҹ(vw/1/WmUҔo-ʢT/EރkЂdʢϝ;lgTЛIE]n[g7.K&LaTd(s^ױ<|nyrﰈYb=rD^测2%GUf:HW0*w%/8'?T˟Gi1(.W6~njmA8Wr)G-~z<u9TˋOӯ#TriI9!�򮧂v_=4]>ܶHAG_:hOv#KB&8H-*cfm9>_ʂq_)۱ڿ||λp-5Z(!I:aZ]'Ԣ_icEvX钥Tt)ҨZ7{kH;i֭tʕy?&Uyϼs[}=@3ľϗzZt0It맺oۦ/W}ξ*]_y>r�5�P"~eBJ*헻OQszv<4NA7oBg?FGgihF�*:t A#J8:ɒ1`tx1%WܒHBcR� RBW˕mJU}k?ط_<@~'yb~Rv_%U�<&}Mǟ'sNMu5~�HoՋ'۳gK
    &E}/b+_p^2tnd(n	:uӏ� ޹3);s]J/)+X<~b1*(tbbjN)}zau
    @1{E<rsx
    wJ�46ڢÍwߥO?ہ>5�X,|a%|L�������������˶N�,>7-P{mS)peYcWb?U`%iϏRKp'9r��*(^Ƽ�)��D
    �� R����@���"�H��D
    �� R��Toy�`|[qI�(rM*nQ:y~REo?4Q)|+C?79Y"ױ*zTjQi@	FW2,8A�XiKݽż&3n#
    {`E
    x6#rY5 tA($0'�#|��@���"�H�@a.y`+J+pw,)��H� RTѯ=R*09~m@7nJ
    9#9RD<]. j"KgPԌ�Dt=t|رct5߾}ؘntRM2R6?'#FDhե{4یry_c"#)="D'a5džQ^gX0[|q@^{z)rJիW/8s=G==\zsXYMh02Xu>"`M[9mp,4
    hfahQ0,\OsÜs9&<Qw2GyOׯӓO>Iάmzp+++)H,Jy$ɞڪz+0F1nZHχX
    աqütݩ(lzc
    >cz1^oRͿ~v[r}L>oVRzTԗ%:{Xlq>%R#(@Red,bÖQLTy~ia+Ed伍Uu-:E\bx5.vw$b
    m+ͅr7eDI6b]#8Va<,b!v2
    㮲D].]]4O1]X<ߜ.AAJ07q-sClݺS***hll,`Nnmnb9"2d\؂%*Bd&hebA/s|L,.cǣ�"Uvnjj~WK4YYCS,OWM/:y^6Ib7׹=ۊ
    D%xFh6̢0b,,47\U.9o8	rv6s|(%ҔCbR]._\P~G}?HH͇H"��� R����@���1=:J��K
    ������"��g[ƅCk")eq*:Rj09!4[VT:԰'K~F|pB	U;,Dp%RbǮ	Po('sT^jޡrvڒ2Z-(A'9H_Y; R����@���"�H��D
    �� R����@��EG,պctҤj)0KTI`b-<^�{#|(P|Rz˾~MMihX&&u}ɥZr �� R����$eFҥKY]I; R+;-d>11$attr=|TQQ^�"2l,6>u{ee%z1VWWM.պ=H c]x1:Znzʰ{.ڲeK7_ׯHΝ7ϟϺI; R+'kƬۯ]$3466VuK|O!R%ݍt~͚ۧ^�""WsVrzԊP[[<z!Pw@Vlڴ)D"$rt-GTB<X2R3DYSSC/Q}}X,TjWih/qy�(?]P)-:4[YC.A
    5k\a!=*sY|GCsWPy9\bs[\)?[CO8oHXy	=^`~XB ,b0;XPL#b0cs-Υ>y-WrZ|aa[o/>
    sMV�XOZG{r"#(
    k!j"kmq
    5]BX}x[XX11bb],N؍y09co^/D
    uM,T1n%	1
    |Lk�DFocb7MQ]"l|blHo>9FXR R�M5w!`yO7vvrXY`]v]fEV
    p24qr�#('etº\nq"DdcЙeNЇLC\FK}92oB#|.�r_yz]atBlsc]2nc2AhBEsXvG<1Qfs]C.W2rG85nͧɓBvGX� R����@���"��)��D
    �� R����@��yw7F[6JaR{9S�������������������������������������������@�X653����IENDB`��������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/rewrite_process_uri.png���������������������������������������������0000664�0001751�0001751�00000320467�11744236202�023115� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������tEXtSoftware�Adobe ImageReadyqe<��"iTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c061 64.140949, 2010/12/07-10:57:01        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CS5.1 Windows" xmpMM:InstanceID="xmp.iid:966495DA847011E1BD8ABD14E281E1C1" xmpMM:DocumentID="xmp.did:966495DB847011E1BD8ABD14E281E1C1"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:966495D8847011E1BD8ABD14E281E1C1" stRef:documentID="xmp.did:966495D9847011E1BD8ABD14E281E1C1"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>ܝV�IDATxZ	TSW~Y	!pGqąภTKqVe=).պv챊4SZ<vpFAP"@	d#{o.I瞜wabD>SAZm<	x>12^;K	8hYEщ
    m!6>@c0Ow
    ڰ	&auvl0l\Jh4&߆7G
    5wrdo
    | f5%m0(=�qǜ[n X@r5/^%,xMF4mh7tVOND-</*;jtK*
    Ze	BQhb;x^ݞ95F1D
    uAJH:Dly,-kI
    @u[E۹@~~cc852bܜ52j!V	foslRMNmU_ŊMsw;Qh;@2@6fKXpc90
    ~lAkF
    8]h0j\]n{(ڑ,\8'.XY1`vbOL~Ge<`Cm0!·Qz|ie85q]؜o$G1W'>g}s60$$й{om:7m_ Qܥ5ɾRN}*{+ӟ(% N;{UG8pb>mݺu4N0
    J@_,%htwg铪\hdUuӴH`ܴC3:88X18l+-㸳y&k`CH6ATRϗH$'N0.VYY9s7U_ظjҚ/Md9]Mum+y)uaI6,J+5NHy>G|Kߣ4F./
    /UΖ֝ka3Lܾ@vE_[x/Roxyt#Bv!!,	 V~3ZIG7`N@>} TݳVsfxٳg
    @g
    eK\z
    1ey:xY,5$ULQ! IIna p:G6Kn9{@Qլf7+y0h%jjKn9_6z+hs{&_-LH$	iiqI'O-U5Yrz܍Xز<|7WWа/^)]_۶+w76][s#!`0hlyPQQK;6̗Վ5׬%Hc.ܱ#z6mڴ|'M2fmR\.
    3Tȕz†0ӵ23v*Rt
    BM>I);]dd.4v
    ˏUVǦgrhaa!!Rf&y&e]3vǩպ!8u3pۡx<^{DxaUcL)-a!59l^݀sEmX-€z;DEf-8<S3fpc	 Z=VR�JF_<>`>/
    }NOwc
    .{ Q$t4+"a1x^WV<IxzƂ2;++]}NExn4`E}dGr7+\Gwd7d:yb\UJ5֩Bd{{\9KgM/J~&#|@T.:\V]�sTJ$.OLpdBCpV
    T6GSDjD2#8tLPo/D&wLU,9g_jյO9}wJa80{ލܱWȷx8ULS躃X_	RSVv]epbRmhpa3!
    "S ՛C7%X
    Z[2x5riG;ۛ|~uq6]UYxI@D2p~=9{lֿ/Pau2+7'O~w�'
    pUG=arIwi@̔ߡԨ
    }9Ll<jPCrnkzr;r7*(RF!%�'ݼsXJ#2O?MXa=eø P}ftMtxAF\V7kd<mŽo^(}X]#ևO?\هƎ]oOqX�skI8IST.½$^?&,<yi�A@! 
    (n)X
    nmnZo}T-eVǮ]uEH0 *$6	IHA^1$$`7_p9sssgj1ٮ_Fv@&ω[7<
    1pt'8=p~1~o߬/۠Icg", hϾH[`ڰk	.Evɴhibs2tFm,u_~\ZZʮ|uEYQ-47|M)8lb;ww*T9)!	Bo~yο!*opuky6h,R!(,R�p@)G}W.T
    @cW+tو%:bqOOa`l�jkˎ+ fCPWeɡT/y}wOqc>PuvPS,d4[V~VZ,D+Hk)S93GZ�\}L/'r^!j:ڞM,wsz(eA__]y\C$lި߿9<==띝ƌՄw3֌9 ̏Ng,
    [J
    jw#vSK@q|v!@(մ;5.c"zO
    r$@xxjLN
    I[n!$Σf)W*jmgϞZMk/dw#F0KR9dW!{4	}'C2QS}xH(2#^?eIyk?ϸ<Xr20-\lBf)[S2U
    -m3#dfeemܸѰ:M#G}KtŻ%)HZPxb^ՙ_ot[Bѡ9?O4.aߦl2f#/?'Ö&nCooztCU&v,086lXo=f5`q,$)@=?8PH:4I`|vwBhi&5m)pN;^p8&%|S
    74"H!+ԐB-%>|dn?(GZL&쬱>OzlJ-F=#Gboܤhl 8֯OK\&Oimm߾`TG�Yׄu|Nsul`{KmY6tw*ދ%]ɸmOq(_6YӘAp ¨\`^D
    ܶb)eJ…x<90QR7gNƙfTVVt1R%`iIԘ+lONN6]K*Lq3fd<
    Xl<"C )3q>+$sâ ))	^l@z]&ut#BѩK:JsNW \;V	K?p@}+nvUuOOY+hSEDDݢ;x=MtG&4g@7 Uci&N%fX6Ri%~61)>+≲?>p|'PӨ%ЍW6$�YKU'Yzrۚ778ͦ58)k3͢>&k[T=P犞f#e<&xCWra?[r|֭WnTiX@A:V*ȹ!+�W<ͩTk5~T;䭣1OhPuI p(h	Q>k
    UjXu"y.$).~r<kKo)1fNThB>nB xи޻$FTzNᵈD虾ajƠD-^/ԫkv.J6VBWg
    aߓ
    v-".|90.mO6t| x&>hkXU[
    a\,tGݕÀL-!�_J2_EAD]j:'lWy~(0E()jWZ7“S6IH9F`2l
    xe!Y@ÀC};q{Wyh>vzMYCJٔV,RdC5CW1.&G㺎~}oqo2^|;6~׾J0(v3RJvɼwr
    \Q,znDB,S:a&qkk+Bh'~$>~\&X<c/O,7tƬ?>./D}rN V>J5|n	p*j�Ţ|f̛9=O"	^./ܜ|<q9	(m�	Tvf@MYeM"ZpCU"*T+VPԢ|`UD+Ped_d
    $$efHBX9{o޻snhT;PTK5Ec羵 0S`Q kr	_m#MBQJj+wu3^@x *)"n*nBbK)+NMf1677e;}q)e:Kab7r^4Ws7vO} \#JYYll3d_OOo?|7-DľH)n}Fq;
    7l?uyI�"9=,'_X	-D0#�
    0a@A
    ċD:>"*AD@Xhli[EA1p 2A9|FUqgWFݻЖsDгWq۔l
    
    zP%ԓ>ph}bG:/z<Ll>KsP(fٷnљtppG5X@^Xs?6ZLhn-eg\Ja'0}iK @,DoE3Uפ+
    v&y¡(x$ "j&T!zfBsPUc(n�D4g=rK<&|ZZEni88Fp7}ndkꨣ(n0UňeԨB0
    2?^_A,z%MـLa2D̒m<|0<:sV~C8eĊ/LfRS{p�F\dv+m	I|Cg
    =3ᗢXCMOOy巤€7=`n�(b\iЍ�"4$D8|dByyO>y|fmDR(22�:س=BO;L(cZ�l"Ei]RH_`?ON{12nEE/x˱U6mެ,_2:&E.
    @8<G/g~l3k߉yD`A2M17vikkk
    ŐOdRc(V$Q/p8(y`,g(Vgd[ΥW>W>Ikra+344TEE{7Fu	l|w9[wm"3Bt"(L'bF*!Zw
    /̏
    
    9"H!bٍSB( oȘBx}}A'US&+;*++;¾vZ}~VRPNUSS3""B=MǬj}hc}=joytsՏ8, +<QĊXr.Dyd
    fsꚫcY;1
    3OB.:ui	]d%S(z0^+lI�xiJh	r;f)F,WA@M.I*JMII\s뮫H&b¢v(t Tf}/R|E744aM6!4&&&|+$'w	V5ظhso~oKII	vG>{Jn^6*
     r#0w:G309v֓\vϹ2Q<c`/; Øt?g?ϣIoK0]b&9S?
    4
    +CxIrߡO,i	
    p>z
    6w;z0wQO讀s1r)%9~_ '#P
    yyÇ>}Z1¢)eMV#j+55)v7OKJK
    ^; ;	gr͖.<%C48C凙h8))˗y9[mU
    >ͬnn
    9n
    uuuM"{?{&>WESɳ\nUU喽EE,>hƻ'aLOO_e-D+OOOLƨUA8x0}0#۸qcݺ8q;tZב �Gss]b,4!!] 38_"266߆7].+vx^]g>roxΣ�pzv=wQD~:q1bSB%
    }/xacCrrocD"1E]QHCn\]Ո1:1]yd)s(32	OHb歬>;y
    s�Մ(&iiiUUUakW2a@^-ҝJ-q0舱Z]]?`_ł_SbZ},IeE%%!"*,/~7I5o@̇UlXLEވLS999={Bc\N\i.ydcN-+9w6Ar 
    riooo555**++?
    "?Oymm
    rgՑtu6/`[2glA{�%U)wmA
    r`jFu:y2ݿ}gƤ*3-=v["~G
    E(yl¬<iO3M*,^2" z#+4&g(ЧYa>+D[5Fd2n*{mnni>@dUX7oH݉ڄ/|TaLaP^FFF_O&<>󁸦T`9&�T#3;ȴW/e@Vt!hWElْBU2pe>rǪ?k�XG5tUʻʸ9{8?`kM#TJ-+G)5XUz*00N+`zj-Jc$\ʰu2m\
    I>iu55C٥Ϭ&Û<	<#K1ʖt֘߷E9QFAd?o"C8]öb)g3^VCXf]A^fov׷ҥ/ۃRճ_YY=#[2mҸ9-9KOV_�<v!ay1Q+g鋮BPң%kx~XfK{̗\xI/˭k3.)Wv;g_.H)iTuIЫh-/\5O6]V^RSsANQb	YKƋF3^mFuNN**.סO.he__V]lg>XFYa)OQCKY647ط?ڀ[l//N;.=@k�(7pt�@z?`_d7/}-.Q,u?y^̸g#BҒŝ�Li6|?AװGPU_)`r7z[٨k\IS	UL3;M٭VvC:"E~H�H)s,7OXV+f,X&Ty	%�` ';R6h&3x0pvۻ׬_I|w`-e+
    %hs۾oߎ6Thg
    M_;B&$[`Fc{'NjRjMՔ$gΔ>S,Mb<dN!0+RgecQpa.Lޠ/o0?v:riFXp]9g4VU-5-6$_Ȼ(=YX@EFPT=X+Qc&n
    ."U)23;]Aa]&}3w̼ss=u'F$ໍLa_R(�#x9~W'KAdAJں,k4Ψ#&0ǖrM݇BL,Ma5,t�{|v=1 Qrֲ&{+:qYwf^}hs+*&)Fu{ȩgk8"cT}eqvY.khLd4RIyZ<[lt5_~X/3l.9leރlD$
    [z8pرc^eM.j+;{@TzðL0A4t3j~~lT~
    _gR@!bH^H:_O8{< ^mBFY�"F{C6Ś|
    <oofLjD	/*y2	ܮNg#]`pFqf͓KpdgytZ	Eӂ븽Kl=av$J`6,ubI(-LnRz/f/1z_xG6a2LJ*9l`a3$#@(A7
    A%7
    \뿊[ȃ"|'vJ1~j	*<[(gV}oGrFkxg,jm\f(~4ANEB
    IAE f3"0<!t׻נ	QdHTnC!a=d:MI îZYZe*`&EAub_yK_(=dIq83($fvkkFLϧq7$tu{>$F!'_ڻgMydkic].&᫲u!m_W_kfjlio*7msD!Pg7RJ&jkH}4KuObf?NfjHU}7SeޣP(S'KqqC4bzE[NqmZ#Jj䕬]/Rϰ~TP{|
    sBX'T&:+eW.g-^ҶI tG
    Si[�JRwNjq2HZ%\!0)}"Rc~G\}6W*|QHfCds"ᑹcxoB3\#>1ΝH4\+/QaT"T~OxpI@aqTbָ%1>$2V
    5a-bah{R ћUrS3aĐ`󁠣l;tqKDoCMDo$w
    ;"|,}/ ϴOvRx8ul*|~Jogcҍ5Jeo/姮|rNqrqgEwwm
    %-)&GqtSΝsytߧHw#++AEEԽb'\uo_g?Nl
    *` 4hw	v#+ϼjo&Fv˽Aw�P3Y^efBJg.51)^ʠ-^V_N 1yxƴؘpQv4
    EbDLr[*wΣ>6na~^:v'|@QTb&4#
    1Г#LHcH8Tт9	ˤ$�%Pw?k*0AK;a> ,v̓&DM*e_8g⑮
    QN0B#ʵt]s%(6RRR>=+92jUDKZz![GeF$KC+U^CAП\
    +[	t~׸"܊),dPT<Ho#,~#-ʆĻiOr[?ޚ	m@z')+	Zج^~1]yYk%0
    H;j
    }<&䱁V.ʫΜ9{H.D0^"#&Y^?]/OdKL,	ᬽ&?Wwi훚=-rp%"atE1	T`HnUerNK)IK1
    Y"
    	"U7l{D^×/ݶ77rQּ\R:S$*fB$Z|Z^f~S={i5$:U6zL:4
    ?uw2a=?+V�{ܑ[y*,A nۨG"x'!;�e0ZcmmN3=&0 bowz#R'n>NWWWOOOuG
    zO/ıj:INVmQSfβCwrw6k{z¨#8{fZ#P1I{/>`fKQ?ZPjqVמ㝝_7o޼, Eɓ෦FƋM>S;@kw̞aW\QC؊a+z=3:E믿}#b	f3$iRֶOj:j~Pl=z5;􎵆(%)5N9Xu
    rmӄEm~YŜ9s
    
    
    aMu҂ںR>\6UoO{[@KI=oo'
    ɥtd=(t:](j@E)3cxOVwNewЍs~\i/~Isƾ@7њS7#B0UrZ|TdJ52@&CRE	lܶeS eH﮾ضhp7}wG^Lw.W\+1*#G
    Y?$tsijFAv2˰Z󓀕\Bd}zo$Rua9VQ7
    g|bZcTZXX444PT0p53nbJܼ]۰Т7N
    uIII}uآؐPDzl>vͿEVVn2`
    |ފ
    g~0O%	s'\p%"bݤA#<%
    8NNNg6Y'Dx;uÁ7tAΝ:}�Z)p\{:qFMHoHoK
    "ݏ6x<Irެ~É<x�NʝuuܜQL.DbB|\@`7J19ͨ@MAi>lfgY/%/ĕ|2D"�Axtr36\=Le&Nwvv$];GzCQNUe>Puv`bZ}ek=Q#1*nfB8
    #p"b(
    {W,6@u%^cG@p#""W1TL<{7Lz PVYR_'zA]\\z�_-ͥEF*b2zBr-[d\k+d_
    k=`ZƱL]f׵YSg?m<\t)k`累t	&OӼ|kj]RTDbYLMDQB"RftÓLLDƑ4S(BkI`$Id`><Z"Uqуa&f@pz~w@ܡtxϳ3k2	^#dn:dT7I-KǼkkkc.<u4\6ڨ]σ{yuu#	ӼBl=FzQ||!n=o.LS!~{$QV,?vC%Z(=s3<cz't*B	bJ!C
    (K/>IϩN*K)((JMMݺukyy=6Mױ}tvIԺu*ڔeY:gQB|crmݻvZǵJˢ$͊zEvG1vOoRlȯ7WÎ̴`٣vʕ]Eۅ
    ?^N:b^b}MNDUf3LMy1evYM3ªI
    {ګ/C
    ax-(W߾7~|f7A@G:D
    F|/�HbNsQ|7=o%C<!Kkܗ[X:%쯾t	[6DyEe85PUc@yYhѭ[:^Qxq:jVjGy"%A#,YqFſ
    F^4d"HTCܴՀ߲1$ur:VW yQ8\]OUwnll<tɽJQ{ D_!?*[mnX-ݾa)jn>9YXAo@j'T/5'jmRRR(odY^c!w.=CG[l?>-g⩢~-؈ğHӨ}^^P(;YB>LK3EZm%<gLv;d1TQX<]IWvvv---$%|E]~_U(ƪhT%DE1
    0vW1}zhho~aqQ0;{u.ct{ cչЬ1n-;>l%ꏓoh1}
    >`(VVVmsӦM7nܐd,ٵԳfCݶm۲e˾#Gڔԅ휠\_`稷U$ͪ
    7b9%ԡ4|&MԧOp#2Ϝ93::~gxv|\�_h	
    qVܲ9w2f
    _x3f|--!ZB}h$/}5N/@(;'lLʹ0r}wbG7{(a-~oEmq8(ipZnա4z-hT{;w+[vh4qK֎Rjbq8<w뾬m,/n>1$եՠ
    h/$VYބqt{b
    tz62}>RԳ�у[C3,U;̚y
    KVNgLWk|f͚pY2ֹ�K7׫@)*`%L,wT.:U'N)RX'*^5׿_O
    ~5EEELIMO;kRW
    N6y:dA$
    "1gzm'uP@QQQsU;{< ɰX,ի!^Ԯ#|=W_&6UK}O{qMw͚5׮];}͛7{"Nj=(}:
    �+4<3u[U["@i&P;zݼpa$Ś׌Utr6C\lgkt-G
    /+2
    Fkx}T-(TAm@
    Ҋ*6zON-VieEFbՠ�ysiANTz4gͼ*~vpt�oHrdvWXrK*<1PbUE@O@K6l\5]k' @&
    
    [w BQx	h.
    qD2G'ܸd"UӅ`H^[݃mU4aHxܣV)Q
    VPP�Bpj'[3t"(7/''ie88ijF5[ې6560*ˎ5P$3TB5BK_?_kkk(Ԍf*{*ϳjoky_-tdg}y6.`�HgHwv?& 36D<!tǀض|@,q{o0,\ĈN)&4L}:K7~*t_zbQOpNJuS?Zv?毹7Vmwjl~ji\b]٧-BmF:XDBu &	>ےTuDB,u'[a#<lNU'S(ɎeNTQÄ-KOQROI~9ro@o(+5&"⛑k32mjjh&.F{
    LL؅X<=\4O7J`Ʊ�_݁�!ufH 9~숸T@by2eAmxzW/(cW%3ˀ(
    6RSEA]f̜akk
    |QB84y|p@a)r[hS.%xւe?^x}ĈkNqJ%}ۜeOFjmF=2kcB]cccڣ$Ok{͖lU
    `y1-r!.OQ
    qm=ÜDaDY[&y^,{/fdB x^H<:[u&%?|͗\`^[A=U8!dj5ᲊ'~-R!m<}Hsf
    ăr&0er]s?(by̌O~XAd/32/ݽ&׈9
    ],m\,W/m&p99գք=4gI:�GN}a?o>~=@Ganr*7M~3ദQ%处qwq{rϳP^.mCy
    b)A$uyKfn1P"xٞp!y[Vn\ &m~8'Fѵl>eO};3EQO/ܖmS5!to1Nkf#ĺ>+. g]:1wΝVH?^D^	~c`ՆZVy>Bn=7.o ,\!la*&|Oqs2Q>pLx=&{;kE7A=`7;Fbź=6J<U("^R٘	
    6k\Ƒ?PphiP
    0ᮉ#41Wzn3)#qpI"E_ԨKF(�_G;/�ߥ=Ѽq:?p i4W.;0zjফ%)W7Gd2WވD8ښaxɴa):z{e>[P!YEGocf<tm0OjbAe,Id;}1K]Nޥfeg2(^cܴ3҃&8::VX`O3!KLy‡ӧ)1`Mr}<oQƨ݅I62MINlHU9K"3|0׮܌N'ظ4y(g
    9&nC:Ղǁ~X?EMSty܏B QH/HU2z>i4ӽo1gz9/or:kY<TF
    q{q1b|ON _?aXV_}"mƻ(L_E(A<߭G=2.Y/c3�,ރm>4MlKL=kͪаyf<U4X*!sS	J!Xl:9	I`:H7zEzbr*`bS8={<={Ŋ7D(H ғM68"bp~޼7潟z21	lQEFXqrhl�֠5(8,M&`,UUH8Mh!-5aJi$Ő+
    n!W�5H6Fjmu`A\V-ȦR$cm68t)mCmfed"zT�ę%5OƖ],4w54PyAؒ8Z=<\_mt(򲠌)pgeM:Gò%=toN[%Cv RQ8~QAv|F%7Ә^PSd絔ܪ-=5:@Ĩ,
    W];ס%L/;F6O$0 b*֝OƲ|FWvvvܹ3 *++ﯻs2<nLzğ<qK $v kiӦiӦDFFN4鳛;Am[ą<'٭}UI{uqRSSa픇H$|$+yS>gۙP<:h̻J
    >r[o($-
    ͬ==Hamy{|Hł0bD~-4B0hg)1,Er)ТaCtT	27Txk�@@,
    X)pIof.1HކeK`hgKS n
    NHL$ST7px?g<yݲ@Ae_{ދAV/4gW\]j˷됡H=z!26#m(ߦ8DcUgs 39?ܴI%FD/9bp!Q.(dDŽuYh˖-Æ
    k
    2SU"ZuPKjJ021BZĪ|vH$"qUZZ2D*D,Uʗ'NŎn<Ɖ%P]	Ji/cJeKq0sxmmg{e=O<|ut{H_L34}0A-9YMDέd]O}X샽hh:yiY	K{U^tKFU愔^U@۲q@�8kb%x<}n$`	,
    xhf[+P|DѼ5E_$V/<#2jd|ai_^[IAN7%Kye4Yg8	,<.T5-9Ar1ΤǑm\]u!qޘ:K}e.C/5x$sm1 
    f<tFV޺hbuq\vz)(6}|�!MP9�ۈ,JՈ[Ʃ!8,~V'_q%Cū0.6VJ+M L(x;)<Yb"
    idh981)6׸9qeee\\ɓ'Y,VˊH}+H
    
    500hi-%qL7.L
    uaLCa2¢ 71
    pD6*EitJEm?*BlA/Twtʢb
    br`;M,7!Q(߯%=%
    JܓE#Z׀o
    vpPſKRh].סN__H`/?.mN"@/p3UA$U;:8|v(KY*(43j϶5?-ع
    kVJpuihɎjfQUhIups	SVywm;MDCG>r0&2륝Iٻ7oCovw`yT͕0@&1t�vhybec9ףWĒnVso. ._2S7
    *:wO2cm>1֫< /ѢkX!B/]3I!}3Ԯf-,\?^	hժ[4QKoxn=t)}l31Ҩ'!֭cLXդ6n/q7^%͡jFo}bڦågzR⮹z;ÈH_Fcb
    겠S94FVM(
    `P@$2MDKDDcT{&I"
    (4Ƌ1ǀ./W|l4/BL3ϭisU:D3]Ǣj5-<DRA,ai1R2%]\0/<HnXRKkԳ.0(Ph*PIL2C>@"וBj(ǹ_>8k`;QWQЋ=>-"5$ikU֖4{</@@
    ,5Pl{ZkqtD FnN0=h;qE|[vX9T3pBK2xw%]FS916MZ{~^Ӻ/1u wX
    qp8w#W�W[1MmřGT4M^|&PhlWG	9l4
    Yx/{ѣ˄Gl	ʹ}E]kd1T>}MJ~x1gPh	įR?%	ё̄DqoJ3cPw=!I\/s!SݞwYLY'aiYދ=XWO#RDe>v~֝O4ɃV
    jk
    {8)s8BF>	UtK(,:dl%&≳2yC2ذeYh"۴!>=5աB:k/;ޗvj-&
    3-$,̕#/6Bo25HVw
    ++˿i'8$s8Hbo7npNՙE- N?C#�U<zE9Sǒ#ZvWiz.b@P6@g.{{;v�nAƍrʏgTTΝ>Lګ'l*L5	^C|@W&'qW4
    sbyi lJ
    	l{rK9,awmVfΜ9}tǾ0Qh&n{vtnwm@|(lOoL{B
    s˪co{e/9zgD7vCeR1k3KNG0IN{}mb
    /Xhc7RR3)TOk<p#q(lh}6vk91OvWQļD<Qϳ\t]==h"pR?;k|:_
    jKU!F$ /+gpYe
    tpBO/0ڿU|hQ~
    Ʋa}b	O
    I2WroMR路7<t/cPv[X-$2uԐ0uFeT5n#1Szm)DzA7]S5}з-8"NA}LC?SZZZEEE
    XemB
    ?]D0,dMMM"Q;C+bR}~='<Th@{.b
    y}Eb6[^vF4F;bR
    
    ɓI7nX[[C?*6|Kz폿"f!Mc<YwEr{k�p¹s֒bR&&ްa8ݻwĉ?Dh`-|mm:0=300�fffwк&TWWquu2dڏg_*iČ-.\)�ı9rNԢ2|4uԠ pT;w4HYV6F�eeeŀ+$wiyB!xĦ'JE1!%	f,$cǎg0vDnJ2ssxpfZ2<dCr2RxU6}=*((�Çs*N^^^K8%Co#x}RSXe{oI9O0Hzj2򬑧gώ
    8NY.>&C{"TerqN7ʯǯ
    W"]IzYf֭xZtF3Uo)KZG*Xo&pvppPBhwY_޿qF0f]3RaM*rkn.-RfCz*�Pki^UJ]x1М�ka7'XHHH�
    8'7m-L0A}&`jjj=assyH굡|ϐ;\X226u4kYT"xFt75	by?,U�͛7/_޷oT	-?s -N<y
    K Ry<Y^nr!A`1h9z<]üv6Vz@quz>$ILnM
    v=`mDfe~/.-׏{Y^׷󡡡#=zɒ%666M|>rq$RT.1XLYqUQAqDwTsŁ۞mc[?ZKpw]9�;z!",:ѣGرc#X /{q+/&itℓ	W AF�,lc!4	끒dN~EPqT[q+A*34tTW0>`1O )04$oZ^gpA1H.RoXSE- X К*OU]7'BcY1\:guS%y('{%Ǽ.?G֭[D;vh_U›gK24H(r%I'ϙS袵$Xx	E75G
    P!ݚ[  1Qk+<r@\F^<Jޝť"ܲݫ:}v_V%Ɓ3Pǫ^oO;c(iQ(wfz6܎ܧH̎Y
    \HB''ǏO>^i:S=5g뼱D?I6rҩ.pk~gͲj[JAЙi<T>:*@x%x|@D
    H*e(*ª$/PTy<.G`%hPL&A'Dd<V UTT9<>L%rk|.L/$Bx|OA`.R唦g'QLM͌԰XlmW=FSpp0B"ok~qxŵlͬldnw=cż
    <FJBf^\^ujwq:,kGScS---t>jb@O	E9^N@F-S*ߤ`n@3dU<K.]Z׫W3]vqBD:i)ZL-Jx71AJɧ33lL
    
    
    UTT
    ?b@5WwmX'c"%8XjhH0
    u0h4DџT1|F|7Qi_˵ݎ'\QRm-俣vvЬ711aÆfΜ9j
    LZ$UTTܴCómT1j	IQLL455`mb=w/s7eb5`-f[PD]̍_84uؐ[Km
    "w;٪x)l<mݍ.E=Dϙ;vX6,>Oۭ}O=R+CTjONSpSM**3-NeN/7աl͝i<AqܿK.i-Pi ҲZq^|}';s)"ؕP	d&&m#͈^HZ,Uo'bjX ntE]gxO~
    ?nFЉR	:WZB-1 [cg*UP(cԽ͐J W*Wnɿc`PTQᄊ:8&H/`@Diu]BQc'$^&\nUOG>s7,ddQK~}!aan,_ȍ\9]{~jNTK	t+
    -7f~*KuS##c߆opݻ#l6ZPcmfak(U#bx5w-ĝlLkq"ߐ:dcE9ZfdtHn+2*+孢Am3P'$$Ŧ0Ŷ@ӧP(]ov@j^CD^[MaMހ/H$cO xx< xd%bSgF 5ҩedKS###np^ynԍ'*A-r:uax�aa'nCT'x4Z	P.|(99NBheojlh-$ [21$k$"%=]IΡMص.5իwX�~[ry짤v̮NEhIф*Fzz+W@/b2۶m+..Vf{tl;vC*Y\r֭655{n~<y2ṣG~DŽ#;Jiok8i?F&0svXt/|.첲lmm*!/ywnvBD,Ā.uo_pˆM@9n_0h`JFpݎ#c޼ySKKAf X(N,!Py;rkp;Rvq,YI%+6$eV<p
    ҝRol:KztB2T!s$.y	R.dpqQ΁>Gm~K];w~֬Y@72J.d^yYC㨒>v:::-D<F[  2Bi\YSSc
    {f>~&ߣ'oג1^
    &S<g?eL-}x"	TL!g<`UXv>\sD@U_sa98-o~/^盛J/KeN6֓Â::}!~.(qÿ
    [},MO(m;{{ģ>O˽?99y„	iiigΜ<88QeW24j<$G,$Zo.9cӢYQT ̜9fT*c+D"aXmH͏FUTT"Q1Їεs<8%%H{_1kfdp@?%n7xCs=wwz^Y},r�,cW	ER{YZqMI%O/LJJpttnjSn.lGjAϥaBDR['<�ߛk~Aٴ{n//ϟggg
    nC7>y5}5YIy=j=zX7_6'lIL O>ƍZjnݢV_zQ5ȳ]4yv3T["i`A	:ivXT>?5F366�@W\`A+/Z7I*F=HE>bQLUe**dWGe'UW1t9yk2Amo8	qqqrଯ?6+妕y[)="z-ٕ27Ec׍u@p&UCtvq1~((Kϗ		<<<<yҊj >]\Ukba
    dD"9y$w@ԶԠ&e,׎Ӻʊ395!B00dB\z&D5DL蹼kGK߿޾}	YdքB_ڱ
    ۚoM>===…"ǃs1B6 $ yhGN߷}VO?]npxlv*U 1o<
    UXXx3**ŋu`<O{o/ᨐ̀�---�֍7M6رc
    .;E&
    4]DľJMšM
    ɗePBL9{?gy�ApYl:'ANv'�cƌѣXXXB	|7#1Zm$>%4z	8?ecbd&ioˤRNʍ.pLz55SCw7xٽ+X(
    <*K\FjF(u.8aGKܪC3qԒΎfr\Wi _8bKAs:"gM uWd2饴bf˧gN:Egms$@̵̧"!Ǡcуlz~xąc'|q]A!So{r'&:߫
    ML	BKN�=ilm2Kj==CLoilZAk
    >T*ҥK;*e%9I4A'_x˖"5<JRr"MMm6OD<2!ܽ1)BEbiY5p]p츙bS'
    (S7(~入w^9s挗˨-OoODfKKKsrhK#WsF$SWfðdU55'Nb!rH̳T[OC'v	B0E_G=%
    _@1ct߽"Hl&~AxU3	#38,^JJO7M]K}G9(Q_(b[e~2j(ϟiR&`�(ZT__Nw~>vopw2aԫX.=M۾Ȭ`?no
    A`:-.AztOPΎ;oqocd$
    ǍwΝ@-ͮV#(
    |RKVVV=l[&I;:I؋AAMjkH+	R,t!CR�[9F͉љL'> s]p1ٳ|͎*$rzu	>8|Kl۶@k"sq5�ljRԭ:ϸl[V-TI\69T%	x@(IYT(IJѻK9Ec܁yb%@ܣ
    @b`]m�2qN@:."[0KEXyPoNIf$)[&NصkאUV|A$Ϻ Ӽ[=J0ox𴄖/J]P8.]TO_
    g]V@[ w0vave<.>)%9'rsثAY
    +8<!ϣAQT<5&ƌ]=suC=ɗU'j{ww#0HWSE|kA?9b)p
    +R{ٕ47ߖN4[Y".uv7pE/CtWQ,`1w7O6ŋk׮9Y"rTPt_L%L XcO"pRLXU?0hՎlfAb&&Fp2^G߫
    }q&N~QWSf]<:~=lHWHX3p"˷=eZ2عytfvFfZvb5_FMs̬ͭj%,6[E۹7455ʆ~9s4RcE=
    `s:Zwq2aOnJx…h֮F&zzzOr=_SgY&)/ukh[OxcY#*++oܸQ7e%zI>rӌ
    ת*&$/SBܭ3E8Kqnif^+H]]kܭi;պTG[MpWAݘYwEbIq{>kdi'kc4tpݜl
    ^&x.'}BaA7|@$ܥ-KB@J	ps"U
    A,3gRKҒruLL@
    Gll%legjdh6=iBw&,ںmP|?T8޵otǎ>|2wC׋
    ]?dТze,W+rYMS0rc轍]m{2U/p1ksf8/FK~KK\@ KzZJusmId5ϏsT >GB
    dB70Q1$~%Ǫai6,<}O<uGMM#oga`۸U
    NOcK
    M?<qSTA`bX4-1YQ3Fal\9R;)}iWQ|'^sujPؾD@,Ad]2$	ȳ]XM@~awQ:tbQgx0}B'Kx:6300o^>v
    LRϜ$UTCMgHX_88-e2b[`>w3jÜs=3yH=TW7nz=:+Px<^dC;>hv͓H!`0(lF13*s|p%-v	DOziInzLKo"4[ Qޙ-,̌M1M\tݞi> f^1@o'/t2Aq>[ݽ6.pr/w	.`5,8n}np2!sA_SSuGWV#n.<�ՅW1XeeoI+2@\TKGcY6.&F&:::$u|9n+4 VG`q^
    BxYiU\Z۷ENWhׅѬiy9h77/
    mUכn2N`f&5Ͽ['(	$5	Z
    AjP
    +>@:dXWug]YjMkHq'gYL9	@A-yxxaˍ`JKDkcF>}&HN״[ٙkh("BK?w	9x1]ʁk5h:ݸ{lԈnZֱ˟.Z:(n+_,]g-mּZlN?s#k*AE_~L(ty!ĝ/,ǵ3`M*fӧ~vp]A[Rj0gmgEڸYzw2e-/@,ϛ]'"(cqP"Ctes9Vi`WqE
    sgxXR!¢be2Ëuf}VBhK:~x4j%3D_HY20F|޹tNZQnf|gMBs_8j1nIAٳ>BcS#!ʱRME.6$1Tg5R(_wP"7HxWAS"~"	&u֪J3+)3x
    !V?W<3m_a�RS-NDIև&*iN\KTvy~Vy<cߴGP
    Qhϭ#YI*	O6Rw4�wӋ:ZIڪagOͽ6`*lqܮgO7Zjl5'1pxlY13%60gm=7,qp?mϯZT<[h2pdeu/ͥ&|,#_6/O:jmm$RdӥM7WE^K&n?_
    $/:ڹu:p/cBhȰ~ML_u16�*'(WMm՟nvA; x,\V-YO_*-gpTI^`ԗ'
    "E=p\pH+"28
    eɫRwb
    -=\Țz=僔uteeo
    }oJ9#MRʹ@$=ǒ;ndgR5ȳ:E(#$wÏ;@(@h>BX!V3wLvi�yp$J?c݈A4u
    K,DB9(UQ'/pvrܷD=-0yND1&ϒbQ|';w;ƌ8>gql{O=tH�IYya gHIA&
    fLrw?;RDģ�ntvRܛ.Tlfhlh:a܁O%7BOźuҚKꦽk]fR$^*j-M8<.?8;?Mܬ~ϫ5cNU	qpyyy	Pǚx9(h4iXl
    >Sjp_Gq2DQ_#GYiQ|WI'wY{dR2x:!D__L&7NMwg
    =tC%U-"x(/1j>js $pt&z٩8SE#IT3θ8*d+oVQcDqj|.+<hܤrMLjHTu!K.74oQZ9εO|栥W('/A'#ϮOOBjpD7
    DNxBEwR_:hX!
    j~I?1[EkTzJ]�REimU)^n4uՈzKH&*ɘ_$H![0bHj9_U!TI8tf*zNjnc`*Ju
    H(ڭݝk׺kk`* ({=.7f3sf̿5KVa8" ]:@Gj,EL$˫EEU"%(WƯ5PkC5
    6`ダ\ C#ĵŋDeբ2~J^uZ7Ƥ2)l:ͤ0($]u
    8ƤX²*$T`2@])drK<#rR2Tt2OGF~[mz^ Y^u=u*T\mkOR)Jh7iJ!F^O_GN"`qE\P&Fn2*ATAhBIf1Hm/qa]f啗ٕ\\Vzl_#R<(:y\qZ!PuXGskMe.
    `hͨYĵ2Tf@.<Έ(`diM%#?@ҥB]gf:l}<kj/ۘ1T$ʹ:,kޞF<[Ft@2}gg n6OBH\{l:yi/l ;Ur䞶}K1O({qmt?-b	r2'X F=͸<RM&9%bٶy{o$p7\0б%Dȋۦf7'3yO`ɦT3dVlB_$W_f~pc''j9r?2(#]ZW( brOTcP-TKxsEj9%ERHw?Ç2DU9m,Ht]V+hR 	?8~5??R<
    +y	;OӦgd-8>G"i)t7o7}_خMZ;l"բU{5<eeddP((Riig\}cRb&U0Bʃ(!/vmM`4A^:_^XYSuZALe00"_x>x!tl\rƵ
    =V=<<ҠE8I'
    7<~)�ϤũJ+ymGf2$4P_Dd2$2JNF%Qh@N(^sJجu2`֜&0)A�qZ!t0/![cb0w˸U%pxQo$]7	NӒrE14zL=F,#~kVw*<[*r5:{Zo%C53KV�fܞ	hG_J
    qBr=>BA>6+ЁqEOtaRXXn£㳊u	Ԧ\,ғ)f|y4;t;vcNBsx`*DBn:"4G"U3rW4^A[-^2aԺA<q׋Pд1-z,?	""5{aY-Ki/;'"T̴`];}8wuXIZV)ݺU)Ǫl'<o^y+ ͉?)ZtfU�?C.UƪDѩwl<%OLheX,dj~poj^Ǐ퉃aXK|>NVeP&,y)P`reEK a*>Ʀ€9c"0h<N&!Nf|9O|СM/oޚ8Q෨B8<말+&D&`hnKgZ/(e$8EP [wUD ȇpIC@	wE$rdE@؇!yґԤF]&P5u-&g+I~<%%/m獊EBF¥B'CR`HpYR6iXW=hM ^;5g/Ȳc+A1	8}{vh570kaX J//=e	{l?)ٺiμy/""ssgE
    $o9g_<UD;H_5gˮ	GJ(ǦNer6h90˦*ڡƶS0<ыh'#0iww!|c)xs>ݫsb:TtUZ@}Q:~c?-qŢ⃉Aa/\|'U^?SLX�iʀ=)w/tS۳(D4Gm^ԷۺIfe/xg@;&ۧ؄s0lTMd^YG2NA	w$Ri42MV௴Fv[&xh$˶OA\{h3!dH@iL\$c,!)C9|ox[20"0QJBV2')2ưJH )B%.LK8-SB9#6o>uAQ]]rBѱأO~T6(,Jkwv$>_0t
    S0Oz𡲿6Dů zl+;M^y8DcY:CH{̃vϽ})Kr)X;O`Nt<y79䚌:;tϯyXC"c^n0Tߋn8u+wmYKGրt	aj]vӧO_lY1;wڵ@p_o$@ȫ5f8F
    GbT ݍ'e%JI|]
    Wwa60QmEsedd<y222Q҇*Dejc6m
    @o%բmcwi~:B$imޫo&3!	!B;>9h7xWB=/$#?rv['
    Gr1*$BѨ
    aٚ4F
    \}mvjZ"Kń:ASM#L)$Dc&K	*}t,s"Iu;v;ը0Ph(UR.'uf
    BnXLTN_
    EO.ٓ
    b[[F}}͆o}zqEmSبjC=u!Y-5z*\o;)5䶅gda-/_'D2^4|btߤm$,`NI%5	`7#}/6 *R{F8Qb,
    8i
    ~b�|B^zy@/&.3ӷnڳ*i3q±ص?x'ֲ}
    oSgJ{>}qߊgwyYL%[K�Ҏ8ϕћg8ȯwy.o[}?y깿qN>pS!PL!	K2s6:@W}aaߴ/_}0
    {HIPI'WpPGs&-X
    'ſD"]yz,Ɗ%^xɀ	LL͋:&*6=-&PB_J
    yP؈S+z3|'Fytf7UG^xb)p!cgvU!�ҟY6oUj;[6yV%<u6:gy[^<I:LoK׹c'~N,1J[=cCߺ`5fN3xf6sjZ7Oe{={9GnH!rgM]̅*CO1eQe]l>V,.ؽtE6֧WfL=ƿ
    !{쾵I JJ
    (NQ$'Ղ'$e9m-"ȋ	DT6[B[~_%ҢWØB>17f\FiI"hjpelt95g/+wdY{b5+Em�4l
    }3=XD:{*;4ZQi!7CӻF~AR!qE'N-
    鸴}75.MeQ'c%.Cun
    =BݿC"kP}=+ڄr|}Q;,�KZlƥC=ղI|H$_j%$JG*-"4`xp"'#TB(0	e!t!\# K0ӁVfK\TJrHKEcàvMRO"s:}Ƴ&w	?0\^$˯̦s/C2|1sJTg6vh*GF|	i-(dOi*o1G$&auyu.�ҎMr_G:Rɡ4ffP:?s>и36@M0砓~qPF.&[sΥ,;m6d^:yȄo]ecV>3mL=iMWn[D
    Ě>RަV㊛UMQ4%acjfJ:CWf@HdݗoYsr~`ꪭ5limIpeOmI-^3fFu,͸84MbwBES=,)SV=qb/¶|g<rifY鷜
    +p	:.?jvvS^'CD"vw%el``�,N!NE,J0
    `|{rAE{kYTBB,8Z2=nߞٽnh7<k2	#{B9OMR$>pkP
    MƤ_L`js ^\Z*{w0^$i+n.bRo_sTg=_#%ibaEQϿ녃T1vڐrE63K_Λn~h}�q9Fb(`.!FqB%T~UX{ק`r*IJ:6gF`"np=zfm;ܶ늵L!*Xݍ䗀bGsG{p\8ʹOߢam^dG7>?޻Ϳ%\8"$$Kmb)7O~
    {56PC+&	#뷮7͝ZMެ/e3$B~w
    J@qĄ##"`R(DHpRلoPĄ';:*,NwOU`5;6ѵDWW񫳜}Jtݨm=Eu&HAR@oHkt
    $egi! I><	bOgh൪
    89k(^+(oA<{!DHG>.lsv(ZkkkUL2eԩ}y$otI{BmUPтj3bqx]cj8u(soxIhvwCo"0XG0&s@jV|lXXX~&tرcG]zĶK)8XDn&sCM]2Kx4a5?
    W!Q9Xb	6΋ZdN_WG
    BDm8""|ܹ{ٳÇ/_6{~׌v	6*F*mu�пNe(r2LlD1D
    `�~?Ms5rdy{hkikk+Bں1NwQN8&H-dj׹#;C_*fggcɒ%ond.tؖ'6.Ԍ HlQȐXQ)򉯨_bh	hd@5#KVm^kͬϽute'g[RME?R#.Ğ\qR=L&ɽ#5Xb"##bbb#8)zM`MsQ
    @u�dϮDQ
    E=s->=䎴w7w0>çEHVV.
    jؐ,KJ
    pvp~eYd%5kݚB
    +
    
    wyZh0)	ztn&bQM-na|> 33366V(2aNxS{Z6ٴwaFK<^:5a1u|w[zap`ih{q!ӌȳֶAec(@HP^O|pyB4kwY4&5YDM�'JLtXt97sJ4񅅅;vj$AzE֢A_竰cmPZβM!樂%s5njA<L?Xωt=uQtn'_qDļɝ�	δG%ݗ#k$_ͺIv''&Fwxc04hkPCׯM.R4|K+|ed\nr�.#8 T$˸'`,&C i*|poҨPDi00jneNeD>hK)&3P+;4ͪE‘-˗9HC)C@pkk6M,ךW|Y'제8E$RBYX:X$b|^[3	$f5RR%l 8`gСÇ4iR^) \??並Q7ʉe$a.l F#;:X
    [4eq5_,[ͪ/^xƍ	&<yc8:.uF&lltt\n_}hf[qӀHUUU.r^vn,#eҮA[O`w~U]a꟡b
    #'.*sFLo"קGvhlh tݥUjAAAXX=7oތm<bԥAc\h-0x
    s2tEƂ@]:K6ĉO<mhdddTTBX^r,rOGʤ\:Ƥ"'F.&hʽJSV+7K&M@EbUn8.WSNYYYEGGWVV*$a9Gb`Mv린e8&ڃ=l4jb7+͢J>@ops�]<<LJa¸qܹ
    P8r?yi]_|HL&377WK[lؔAi̖[[~"jw~Nz;{l^'ߝ9B�O:Hffff	[liF[&n4c4rLFe{ݖp!6ecҥt: //yٳGQߦN'T*uqF"IK$u/F˴?C$ݖ=zL8^ZN{;v۷o9D"QT~I<.X	(cۂ:hk-TWW_zu@I&XBYsy͛aÆbﯰ|SDX?){Z8v?_.G#}H$xb;P(?~s_|uKS('#hb#Uh1ϩ6bzСC;vҚ1csQ'8ٶm[H20X�*iQj8:bøK,:9	L6i׋SjrBYdɄ	˛"rA]\ݻwvvv}\\[zE Dzq6׈(oW&cW0lԩӦMl'k_ڵccckjvΫ䵈5;5Ki)�L}kKz+`5
    4@6Qf<Fb5؃P'4ش�Xb="I*�pЎ;>zٳMW*|Ӭdʕ|>P*0k]5zLfelV㭽Z7}{ny'ek4N/_3ڵSѣ	)Z5_
    1ϟ?Q@z+,	B|+GHHr+*--TxiyNI,WheyCo4\?'1E?NTͨU>}ĵkannLC<ױ[եNx,dU]b@̠.nW&X0AG|pPrN-nTsN*RSSO:ui%Ho
    sw󶑊Q	_w661z~31eVģ
    b *S>)5<0?P{֭k߾ŋ^bh_۵kPѣϟ?\
    sn/xhK$>0H"-<|"n	wp|_#zUӨY00wq֯jҥ0@=`;#&Lh2T$~zs玉޽{njq&;FVF&R�_ۛTiuh[Y+<+|ϵb/L:It,e){Bj&Q-l'~/^,
    
    d}+k}nݺFFF`a)cv\DTKK9��C7T#0Ub[xI@nN?}1n=,Rk1N>(M!DE"ǧL⢴2Yooy&))	P*׎eTyvt3�bD-nW,B9Fe>.O5Jqpu-	DhUo5(rԈSɥK1{Sup=ڵkRf1;UYY{nUUj@oh9^g+BPtucQ	V/
    rc]/?DcAu({<|-'qgon%qPWfcG.w޽8::Zo<_=5lsxx82663gǏ3Fxt5¨N)a` D<7V׽.RH b_]/N,訴JEn
    $֭[}	\25	EEL/cEs?*k"ǐNkSݐGO<)*&Nz-w
    !WtRi4 W(֬hS83^]bb"0l6P߽=;ѰLI;_WMUFIعfW$2ǭPh [rm	\Њ(:`._H&-lklj0GJg:cq"
    {[MPaVI[YvuHq6FNn%WTUY{MیG[z+K8eW)RCE`3q}۽_L%((盛};ċ{wOGpU_'߻_UZV5dW*I\k`OJNk8
    EckvѬ\qPRI4RH}mg&/$SVLnhԥUmBd!/I"uǯ	K*H(9p;iG�xooOcADmݙ)S>:H(u:<eW7_[}-R̤֩ev`'##899eee=|7[}CON2*lo8dӺM~5z[
    '#'DbW`]@2nC 2rYiO;L-RESRV\޻f
    8F/CBEj2f;ovVZPŷŮ5=:k,}v{P
    f9ŷN*t71)F&#\4u]	w7@x?
    ˗/M72ӦM](VzڭRgx/U>ze>æk`b&/<0ot1*`Zؘ%I	B+'-gU	ъr|wUT\xI$YF`i/޼$u6eC2~
    a\Tڭ[׸muY0WnKPqF޹s'::ǧw={}A+Ͱx^A^IdRNjQNf~am錦no'
    3122J>	⢼ܔbmU[o{!`|JQ�D	.WјbA5PȲX<xd*!HHBLpƆ	C<JQШJ	F!K@"TYL@&!0)4
    S)u6662ѡ-af�1I_5_k׮],R.]x"))ijjjur$/EX>=y|[?Sk=>`i#>O:u?%bޝ<t*u{2\Uʍб%M544X(.dNaX㋊R)Ry%O=|
    7*4DLb:rR[|{. ?;+0uu5@>L#LJȋ412100TQQ!PkSի׍	bO?s]qJ.*/9҃Fkp};sLΚ5k6lИdWxEEQeZm\-ec,]A*~Gr܌�se29(�9HGgM]`@IJ!tkmfN`;v�pժUw޽
    fy)d+(BikAEVhiiM12]5̾]]*(ŵ=Ik)s2):4IE۳
    o,N<9eʔ:UT
    Y鹥ɰ&KE9A
    ң-ڲMLL
    
    YGj1^nWrM\f7J<H(NOJic5$:YxQnOm.;bUdA&LjJ-fEQ[b !644400h>SPXCѺ@⢓;O#3===P`iiЙ%	HϘía/o9JPUzp*Guq1qG*gq0[U&!(aBRQ!A^<&0@\!S*Ja
    D`(,a-gSLǽsN<м/!7`#'>"0H𫯯a�/^4k4}zfZ.2ZBپ] `a/"ަ{}wn
    |u2C
    F*0ɇRp)ay+�L}'	8ى6UܧәFwXAx`[`O|Eҍ_?U#hLg].L0E*Eb&eK=:8Cb7&~Z!E|ILF寣\n}]``}+�vl6bZ[%$?d1ںәAdRyIUbZ#]_<4445̡y@,o
    eYZ3U@nʖGj@PZ(,<9(NW<y#7.,[p%tDkWYVPEJz_Dx}>s\QwԄ/Wܐ,w;ȗlTHn?_x@RRR`ؑFFF)#';*;omg-0#i4wnnNzJ< >=ru윔[m=me]rBΡiB:3O[}%a@m)o&.A.3I^c+@E B4:{"( TX$>Q(₊Nfzjiik.((6V~535+ωx&k[jae䣣`0Zˬev_D"A^~nj|.QσΤ`(Fe}RD*eTy|.ΖxL*IPFXLsa2B4*J!:&&0~pgΏ/"ә*l
    &�
    [rFBܲD[O]cC}}p"+--+`l3@[Wg[jYUvnAVf}}5qSVLX
    B4*utt[PɠI6Rf(/,,/MySbafc4Y[L.-~i`O60624{Z'M 
    B12u4E!1،$cCS`.
    AJvu\w&Yj?@t]"q0͏8{k6cHTEG4˭egT	*z{!ʮ;ų}w877PX$zzzZZZm�H}DOA4c�PV\e@vald䢮NR[P//ز0bAm'or_?4qqҲ\TN�Z6%!l#9Au*21Q9Pwc5&ﳄqT0eN;?#99Fee̱[:ػkK2x@$ۨwd
    k'%sU<I
    /UofntwPg7(rd~R]L!WU'$E; f&FFJPlr_&�@fjbjm	8F^L|DՅJ#gdSl<SUU3ZJ5U6`,dX[Ȧ=ڛ{hk˘aH n}dݽ8Rvlv3"=+bX>X~ύ&['UrF8;k4cISRR~'d§2b3P6Z:(ņo%7Yz<zj{{{JR`.-Sǖ'Be
    2!ZJ
    �"~/_J.?,ۊQud}رɓ'̂p\(nܸ~k=W<Bm8.OcG
    {V̉!D3K:5Weee/_
    
    Zn]})MJԦEBdHse?|A	&>ŋ
    r_t	e@B`J=	E_;jdXRYðSH1æJݻwZZZ�JA$s?Bb)$Af[0
    -eYs#[^As[BD&#WBطH$R^grb.g
    aVVVkMt*)7鋊7GG̈́В&8DN@	Pu^sĩ߼4ϳ\8b7pۋ:融	zs%狊[)Z18x7yv1''ۛBݻK+IͬQknbH
    $HQ#}ht橋p.ƫo~n#<i;ƿ[}ՈcԲ?sD^c>zĀ+\*zz܃!Kd#V,],#hAлsI+qqR0\^^>zq=вBCxj1Qc:%8Y|�˶O*EMjS`nF3q&wN6hzl6$C8LϠDR7Կ?g*Ϝ1eakHNWT]UVkVW$_.D2I&π?$''J'N?J]@ cZd\7//p")2''�ETTR{o㕞}lLXcv5%n[b9@*K2!UEǯ:p|S.{TRc)V]4ߢ%֘*$Ґ7bk~m|nĭvv�izu	&h:")~^ғwE==FuJ9}̢A}{}YSM~?-_鼿kj,A乵564$cfkԹ0իǎ4hP(OcHk6ݼ
    )A"$m�hUj2y\MH'ԩPgϞ8qٳ_[Ͽϩ}JsJO7~MҲ1%$RhkԖ,beȔGvh޽L7+++JYpv"8NTttExXm q~:+mÔBwܦ
    NA'\�4M0v޽bŊ޽{ؼC:#
    ~TTT<<866($>q$wFXCZ#[%1I3f8p�fff\.#F(}3+)a\aczUZB6K�|a--r-[Ԝ{ǵK;h-]V<9*6RA yb16`c&|}u`<dfkhiEcOfqE7rzI
    +QieWo5 N/v1Fɚ,[L,,"UgWzSPςuprx
    ;WWW+///@_NRSYZR[#դjS]&?&Z8:0s^}jE<-4mB@'tU$2-T6ʤ^Q	y{Ȑ!@Λ7֋&j}L[Q	GWM-iLjیCjE}ܲb2+fPeOnG(L�޹sgڵ'O^~}fmjgNӽf!3=#O!}z#?▢1s0F%koeVx q={,''PUUɓ'95ps:1i< ^?MI:ۣ_Y"B%
    K!__J-WC#˶Nh1TdӦMg>uTͩ6<sSl+6NƟX{K!e%fi2W?ѽᘮ
    D0RD"ۃuݹs
    \St)VjcP\ETGqH$|!2@l>Mc4UX3gΘLr(WEGRz…|>cǎ&&&7o><O0??SF0[
    ߖɢRlL$;լz̽ulp2EMEɵwc	WH,Yr~U'ν)5QFFFwqqq!!!5~WrZ^$:~?,O\sX΃\k7P
    HC?WRV1+:qPFi
    9'9WU7gгׯ+8bG{B4a_zU 
    -:,·0ҡQTg[UaFWr"V.t1
    d%Xۃ|92?e:i̸GC3V!CI&-\l
    [,aJ~oF'“/4##X866#0*wd'E_;0}t*HQP*D(4UJ8*ۻggGN<�AurfRՃ/ƾW_Qt@}njllܥK/]vOx'֞^6Y^-P{Ǐn߾|#'N�5~}xS@X$	eh, [MH61w]:~疎>_r@kwBP(܌,z6�<
    rz#Gqwwwvvr߻ww4M,@,`{n&,꬐x<T*R&L�ٳgV􌌬%htdћ%\Wr+:|{*:j{ɻI,m{oNN 5SL9x;-[s3f03MaS3>|]N<zjЮݹsX]YZ-2{z5"2+\۵v%d
    9>2Uˀ\>	*1dd˴5RSHYzN>}Ŋ�>l2+5Ekccѽ{#<ӧ^?i[7/D*FX"$Ebtb'ppBiY(Q,tY
    Fk=o*"00,e)Iѽ{w
    Z/|H6JD+<}UgONT蓞WNck5>~LJȏneblfjjd~')ˉͮ`QGvO0<**cҤI׿÷>b_ѣ]k7PlC
    
    Rsj;z04+0\) 3vp86楮Eܭ'τfz7{”(TTY%B2uQA!IVb&HDopvna-]+?]2"�M$ŚwI Y=a4
    E<k`Y7/Ni`#
    Jg[ss:2v8|٬.O><2ә|V
    .M1yԽ;7͜aVm@X$/A%Uxk[+pV;x'Uri7Wiev!]]t*^JxcX*7aJyUGyV>\M*<---s6EAtTll>4qXV`5LOPQH
    啒"B*vjۯG
    530bDpOCj|VVQfv
    _hܚ)#V=|9³MWjgke}[e{sAȑ#'N�6h͑w^�Y555pֻO!
    RF�}+6%*dLJo&-g ō<S/z]y-*)#d8bp~HX*ŸEx}O͚kw6m�t	kg|gʇmj!҉{C4eZeVwkFk׮;4k ;;7?Nho
    #.y{ryE9JBH,擩,@8|fEU&I,W bJSU"PRNtk={PSCSV
    Gdh yb?eH(ALZ2ԩ<f̘g֬}1;
    XB\. /-De &&x
    켲K7M#CCC3'VUMEEF_RWzʕFn.9s&00kp,VCcmjbjmUR`0fQ	6.98{0L%(|ޮc>8FP锘9[%/7sU__˫W޼ysΝk4;)u.*�	Hƾ ?;ukM[]C-WB)2nLl=ISS~8YP-uئS/3
    ʺ'~YuHwv+1Qvg&Y>ۧ{ذaݻwYYW�X4|Jfmcgا!;=7R7�(ueW(_60jb#I%Z
    `5ܩ_|elk]ZIJmxBᛒҷo[nѣG5N?J_5Þ�FsSSk҂`a!6.Nғ\&zj
    +^~fw_n9_1o[1gAgZa7ϰs|]|N]W]Ǐߺuk>}<yfxjȦ'W~UX?FeeeAAAnvT[jii59Y1޾y|V~rD>OG]iIեR7oۺr'2©G%70_{TMloaBEަWV
    K2{萭ӧuv;w7٘U#]W
    q(ag֙qИT_t[˕}
    ^EZJb&mx&@Y*0?Vߜ֡K+UdVfldd	ɋᄅb>E05Sq'FnehѺ5;/̬9d?Lumg°&P
    8Fz|^Yi4ibK}%6n{/Ο?ݟ]"x8éFel_o
    Ybӝaʨge"]eQiS
    zfYձkMeiPgϻ3ܡɦ4}6mvt:]$EEEݸqcÆ
    _^0pkHAu,MYTDI!iz4D
    *y_O./5jۺbhSSWDQםm&
    u�OnÜፓI}~+!QB~]\\.;@H&DTTW[muT먣nQZQgՊ(C 
    Yd%;i!Eq'{{}|BBBZE[Y?yԏɥl'O(4FJGI$d"$A%zD4Cw0KV=pb'%O 
    xV}'0gcI#Zoܾȿ[VJ`7j9gѓ#|Cv>bi
    (P
    ;;Fط+?UphjJӉ$8441ׯn+lj|5cP#
    U}t2�1{0/v`Ap	דm83q=qfTw[HX׌zҀة'4|GSzEN2=jGE-~HfgҵAVF7!~EYuU)|=WW#WяG'"�)lʽ̛gh�,Hx
    g=7pyuwD|d]1o7=_m3BNl̶wtsE`iq`VإF{}k6])zN_/
    YTkW/eN�/;&�y9i0²;~>Ixl|rƼ9="E8~EA4h~z=L3Fx:s0	9^7(_8s~d''
    }P]>y߃?U-6X	ǟI%\|x7nJMjUWTxęC<Ft:nY.ZW%A?bݳG?{~=7|~5볏
    N% q
    ?A0wb:fA
    $Y$#t0tW'l2tEANɥ?ϫH<dկ?DRi40'BD[yY2̐JBH yuFIJxQFP|>?&&՝nu`~O۠MoKzi0(VH]9>^n0:U83"/y8]qo9dg;djT0ŎK%5lfa
    {($_6'>zAJk0ٞl�:fv'5Bٸt�q(?Lyq8,F5)}?%>*+˯%gFyь+0dʕϩoomjg$<Taњ8ꪪ*DP'<͘!*43.Feii|bk@PƦ`BGL t!Ѽ\Nv�Ձvgx=,..nӦMK9ikl-ގs<
    N'XPZTQUhjcoޖw'+X;pY,Nv1tl-U^;t}ÜR�䅰^1:Һh[8Zl'C9\.H$AEI·*0w k)ןöw%x|e !SL*y(\M$:<f4u[[N5BYT^Sq sf#<1Gl&Tu0t<
    DA#>ەrK8R(W�!aAx)7"@5͉b'�+|?}ĀV]1ם$-8lsR$B#yVeJZe[Zzai5<GڬBY34> S7=y2=l|2w͇drHecL}g?ftaDgWjyϞWWyƠcʇ/dsNIdsoU옷/mBoH_f9lG]mpl
    ylݽo\w^zke[ϞxE{\Z=щ˾I`o'>gڹFɟػfCwkCuNGYfv?ȚE
    wlS0_?f=ЪTC`-&DRhC~;8B ('ue}h됬lȦÏf9~][ɻfJ'mIr(;/gnN)2ֲgi^/#
    	F:rcuN(^Ĉ~Xr#
    F\T-t1;z-C\wj*)w3јr%
    Y*J1cjO
    -�]CG�h@l
    (5MAǕ
    t;S9nsv@֖NNΞ/_)#08�=c?{b8>`W[.л./l?Y<;f	{Ucs?5sF͊?}DX]b
    7hC-)yIrp::iJ_P
    Z4^ÂF(J%J:%
    Hp6EIc~-QS
    �Fs nqhߺ}ł;ISt1#Z%J!UaEiWEw7o�$H/6}SQn[\τ)s-[Ku1c4?{T9t2=JP6TN5r'0BpqSFpwrz.~3?2@ЄcW
    Q
    $.hVWGB~Y_?ox|Y<[o[#1_o:=D\}`Е$]Kw؈?rε
    MY'wRtҐW"tO%P:8`P~i,
    R^( Pΐ]PŌ-oPZܦH,,)*~d3*	Tt//*sY9:855Z]f՚Q /gI$R$	t$`q
    /M%آ7OkV=ۚ~*Q^~\10Aw]װ:}x<QMLp:YN}ި}V+]{xr^y`=@VJ(`{bCw;}fS}m@mO7>>Y6N>-NJۋ}elA=wpJ4S<k6rbno}-onrJL5OL9Aax<(Sҭ˞Ӟon/d%ұؠ:Ӝ;YgdZg'b+[3<vHuu5hKl>:ug\wܚ?߹#{7MC֊%~AE}	!4ܹ͜S>*u9:m0ߡ
    ېs7ؔ^�VoP[nڷ̟XxՎ8|d&(c&L&?.U{q9.v=vy
    HϞrD:lzn-<ĹaJbuW+*n݆t8\WCRC((ʩ"iTl*[q`Q2)U&U4XHy.1?BڃxV&@з!%K+? .Z6qSډ@6\nXD:t7dŧЪa,1w+6WI75wCqup8/-ܰH.�ܻxT++2'Uf?E[ff=A45rq
    ;fN:t)i{?O?[ms71P988/d@|3Rx×'c>׏`T+3[ٌɯݷq3@Ÿ
    �zNj'
    16\(6yβ1_Kx,F>az݆N#2q-9<
    7D6w7n`0IfuLZvM%xG2VlozK@H$ڢLE#ܭcҽ<Q|zC~n޶̊hx5GmO[e1]
    ipR
    =bl,/vPF8&(plcI@u\~d`e5A7$EtB^Uvxogql-.Mj�uQ10m8ٵÂ^	Mj\j"~O)S=(bHKM2kUФ}VO,B,sO=t0
    ΨX(_zTJ`klqug@ll9`@5	q,�%v1{돝}qy*+[KFQT-v̑>}^Eb-!t?gQ).Ъ&LZe%C׏m9adY1~x	?u"n<I{ط[bxUZQs
    3p-Nb
    赁�c+3sf٢<v.('|CDD0/ٽmJMۂ3g9jGyvڹ19[N,{.Bޠ2Ry+&Uk	ה7Jj!yA|	<{93;Q
    KM}
    zmM7''R*yAvr]*>?Uױd^Oen>G|%iY:h3v>EyDZ]/.[tJ0qssui.]*55eShU'!F
    ů#Gv!a.z&ϟBת_EunJAK:t;m|<Qd]w}iT%5zE^P$;sv#q|[bwc�fš.rNC_OktG4*R\*‘4/?
    5<&L^'n~PegAP¦HeQdsگ'}~ĿsGv8_D#IVRIXՌlh;L(-UHd	/.6]Ly1t?$e:heJqF;LO,{y?˥[rݘ&[vgMma{8l=um�[,xvW>9>vʩ/FpJ{hjέ
    w3 +'r2
    M-qT!Vt	mOww|?/K!3y$cTI*A9^H;egLQ k=O#Jy3lkV0J.uqjLJp&vv^mņ9LZH	}4}i^ޛoȴ|rEqUʕ>(sې=Q$Ȩ!RT
    %FsJFRh}@ʊu55|=5}=9ű	aT~ԞHd":{V'	ۣr/6;C%̦d2R	}}B0j~}@!@jdFvdܫ}o1j.v|0a.UhGO,=i]<W7M'G^1<�m_qt<θ/>ySi?o6FQ/ӈЄ͇GS&|z m5	Y1£/YE/Qs7[8wʶ[&6_Y^kT~vkZ[fL[2w'`hԞ~wU)$#6˶^1�Rwј诺#$SD!1B<vvX:/�j֔z_½m\|()#ۇҫ[m$N/`h"�b4k,
    ߸V<efzi:mRe@Ny5j`0@B1ak̏PMm2n6B(q" 	LB䣗s~~L?0[&lOj[}26*~>y�.kƬc},SSYX
    ~фDDe9,(3ҪRQ}<.cojB_.~tjǶz"'U$)t19JG[[&SO.h3FaXT
    AyIλ[;^gd<|!P(&>"LU5&MI΃:)iR+$5yy,_͑qX7Ks^ފb8T*KDŏ%A!6LKiesG\Á`ojL nX\{N*1
    D"(/ή0yzcк݇a9_
    i;n,0?E8#($@#C*a]~a6rq;BL ~)YdO0sLՉBcT=|
    /Z*Eg$+JM (Oy{DW r:LbF9葼{xZ#۞cggG&_ZJ/96[ЈympO3b['XҤjcFo@cw,ZDZX1w'=S(@a\jŦ8潭ÿiv$)㢅EƄ{O1PǨ.�]n0ɴLGYNIG|OJy=|s\xGn7_opi@_9wziiRDsO2/gGabW2~v]WoZM^ha�X�+˧CU:r~M,}*#ө,;Lt\rgn?>VNs?r~w?lZ{'c>/O/IQ"]+_kq[irA!9\;ۂs
    |<QM&NVלgW<+;y/R0鱽]ͬ�=lUhkZH(23*N\]8*L ~}&UnޯLyX%Sgm˲ZgJPaĀ�ښʵejVM d"FdGwqYB@
    ,HH(GXWjejJeZtbQ
    UzE!J
    \#;&I[$,:эeBmMqAAÁ[`*�8ʹ_NB ;;-P<@\˹.mWh(H7ٙoc#6_A
    -uR-`" I@ ØTZA -Fjt�7-NZK0fB:DCj7H25Nej\E!a9"	A6v9kp`#BK 斪�VJUJ`Lb8V	ϦY,&j)fXw\Dy,:3b�symgU-erma軬b%`�,feֿl[3D
    h4#ia$b#/$Bev"-_HVB*4)icʱsLXJ�9!.kt+W`RNŠ*ʂruzaBϢxG	ɒe'
    *F,I0"H	:Z<DYĔZ\ҩ49Όb-�<k!d:�kA<QQ&L/Oʑf*Pq6B;�l#Ka$`M˗gRdyer9&Ur:-x=>CcQ#MY
    AK5򘌊2ƄH]F"63Z,)GV--kV|Wk�z'~m2UV26<*<D	F\`8K
    ̂]MDlG.PGM-{++WhZS>+Yh$Zr8L#8A攨^&~_ &lo;Q3o{62z`8^xP^V"�҄b$7Y׍dDB
    1Oic	hN>R&/KY9[x8ؚrTYUSOB0bokW"[,Ϫx]�nQϦ702w
    XFaD
    ewew",D,_Q !F"�]6Rh'j-ಌ\#4:"9O4N:ZZKXa#:֛
    ha.A,2zj_~T|Ev\bdG1*#>�	*ʫ|
    E:4j#qw3Sz_J7p5^d3"PqKql1glXF2>³KM9]m:71\j:I)9Kf\F53`7Sc1PO>~}EEeN`Z255],痪ι2GAl0_슆nf[:y	V
    
    WZֺukVaW>w03dȐ?]S"܈Ƚ4N{5qjaV".P0NM.&F5w%K�	l"+X,ֶmۼO䖪=ͼ6ڔ3Ks޾
    "~XFRB7SFv|oݺugrX'>}]HI\Všɉ9ҎA6ߴq6#+,zwN2LqhFs3ӡh�k㯨W:
    ]}}I#Xu$lOާ2>6#b>)
    eq9tHTT}U
    11x$K\p޵KC.JKl �ߣ[ӳQDtLwٮu*	9
    
    @sYÞ
    
    ^;K2;ogwVV~Q?+UMѭSj"N/P,9",o|NF"_r
    Nvځe{6;9"&o+pk'{	P<ܶx)`ZO1ۅY֥?~❣;Jb){;X6yJߖ0n|Z4ԁ)grL+Fȴ{,>ˌƳRql4}T.,7y€F8"1ovf+g)"PN}SȴQ[*50_^#BCo$"	&_Q'45#4ɤqtV? "
    	Po8
    <z@Ow
    6}ǙCsg#mZBiOL2xݝC(kIU񣇷>0%Kz	xe-^]>yx>۶ij63<')*	XHY&󘏷OYDEL˹{l1l:{}Q﷌3D<`C?
    UI~L|MO<-DĞْo$wDˎ/0U?75E<],a2|g7yp%)r_nBE5*"bõԯ
    7":ˤ30{y:/.*pWfйD2KWpf'(ΉX,>e\�o"z+YJ8EʤпAPL&4mQ|gTEe[UfuE|뇒Wgj+/n_25ՃBk?)Xs~mGVȋrHĠ9D1a]l!fzaDr&ȹVqʞPq	A8aH\SS$⪥뷺ڞfAÆh.7# P(ޣƬ7slmDlw쐁-!zwrT=V]u<x	_VuO}i}lh~zŲKJn6o@335sGnml3*i󹝹lm|WOJʑŃݬ_Kۮ8bAoύQ{&7Ы5jC
    K"ڢ²r,VBštTpϭm?c$uU?lt!X
    LiNq˗/GQt
    c@T?Nakw`4GW?>Uvae	@=b=}˗w~:q5=<55*ς{nq|XmJ٠}<4ai= b\Ж8&	s8ܓ0[*B<P14+%\[@LHM)^8RdI!J*P>^9ٚјEJIH&̌B!wp3s3hk!":23
    $kl#I+\&#7#[9C2 ')O8:@qeayT'%)`:E!Tʒ,)eki@ iF">L0LĆ.`drg'8YkkʴPG:B}H
    .vfcc"&eёW^f~W~{yYz•RCoR,Ī牙OͶk>ۺ2mO}*?1(hP ÃfL*ۣ̣uo$qtf^W=Z`Qtq/&
    
    KIO_3.=S$0JWI+`{V@fNHD;ώ"BmV-Z?Ƅ0̧BnFl6=M¢M&ܚ1_t4Uomlx,_h;:=VId"EāSޔ"uzYIjLx|o1W]Y:A1N
    5|,
    E&tܡ,ep
    sYlƞ	c-!2݇)P;'3occwD%7E;֔Cd-oaZds\R]ٰtPi/wd@oxO`Ŗ^܂Sgߊ[`.<o(rr
    "72{-`	`;_Fw`0mґQo$H1bd޹ϣzx"4Dv]$2(ztrL]l^0C!Ol'@[v;tuKw-:w݁>.4%5JPyrrJŊF8)J&i~}eG1iLgFȟHa*
    ^}&4l	^/{D
    IGYtfD}:D^u<+F=
    k.Eƺ5;gOݾ_7'{y^GF?Ma!Z {SQg$[ى^q):γCuav.]Aj(Ҽ8«CPB዇\3s?{t'gGWvnygfsW`z
    &\Bݖ<7>1
    RƃS:p?4ȴq_ܦ<Ȧ9gj_
    l41G}·]7٭ŷxœ䐂8ǩvz7o4lбy&իsVig	^f_xkv
    MVH1B;)`D/-@(PH3
    ӜLٚ~nQTXi?.x !Ja-0rJ
    )1PQJ^Q4͇X0+!
    
    bR<TPS=&I8SE/AlT/5[�V!LA))f k�:`)ʃlz	ԐJEa`,G
    XP$(B	wecϕ1;oniQ~ì<v#,?@+ϟ_xE(֜	?@02B5@A}jڌĖ-[vY"jjE#.Qnb)f"&ɢ!E(DҞ8
    e?&&z@T]	#N̶r4c\0Bo#Sh6nݿ}fTq?+@d2qevbTP%P"APe0@b@,eʏ(suc:y<=S@f8% <6%'%uLi>Ck)\]\Xph4&%1grf5ӸV(MLOm=y*uޞАktJt":}n1$6KѩYJ.�9#㑙7s.40Q&-Z1*d?{
    WyO/'&LcSӕcŅ&-|iVJ13!<SR�VuQa)NBs:S'7KSLo%udž=a6.VL[,5!]jfcF_lDZFln2aFVk4gJ񧛖0	c2RVWhDf,
    0J>bT 
    YP%>j�:3˦38
    |[8p#\jR)(? ?-Dh!mZaÝ:Nߐ
    ]0z{cx={
    990~pb?UKpsO+ۛ4]quk^i70Y^ڇ?[aX-1,=<\�{W6A(}dzM{ă^|v
    5bR,aiXi@"!J0OjkČs*^\i!,xz^L	
    ?d*o
    :gD[
    gXa`a<V[#|^Pt)Կ˄I}q8O1$EvzRb1B 
    0O^ddN¸bW}b#﮼̮95SB6$?ݲRY{{ѝ25<pJ+ww
    8ucCZNX1n7;$z{@̺IgNz4޴^AUJq%<B+
    (WGi%$}F*Z|vf"vKu`dE"G*أ7.JBUN5^N=xo?=*>lDۙccg><HQ&|ˁ̱sRC'MlX-4vF
    ;qpSNk|detq\3oeOX5vfW"֦ka/-i7ojGfjľyoE{k/^Ȟ;|nڲ<˨ogw&	<j )sKf}519ٿْtNq۞a:uՇ0wn'~ۈ$^W>QNsvU=ˮ`C$)0JGiSB	hx=!@=8??ȵp0J'Ҙ[qĞ,{qTAF[ZShTj}%hή1@R
    Z<U!bPO|7U,sܥ5KVq/ѵM-hϟƗ>tc4=yfN"Pt|xvyӺi0xΈI[sQȔnmLf1kӜ"|5WǮf!i`!y4oعeє1	񹫏PbNft-N46g,Z5me*ZG_,5ďOիߥ*VT !YEanfod*„26[o"wt\Ai)ܤix0zRQȲHdz֣.Tn}|si{4T:HR%(5:~HH#ԫoǠJAk!xȦc!LFt4eAޞRJt.6T!'2>FpdCX_y$\M)0Xx909OlGPҤB0&r$B[Qp-O^{QҨ	=iޤ}PP$x$A!Л#0 T#poDŽ49eY
    9!K"K	4bq!e1zM&oɾ!5A!?Nh|ܚSQlG7wp-|	߱.UgNML8˵VZ7z0AryNRxB瘬0u.ߠ@a|r 6@̈lS g2!YLN,1q3,NyP('8~6BR󛇆.'ibӆME1E(q�K.Ȓ"RbFIyaAV))a 0%{/X2ɯ50jU	l['[SLaىٸъ@hEJlW(eTZoج^~ZFF^4gȫwuEM~iۘr儤\wcCaQwt*=s.֍"NM|DxY]EZJƅRіP;O`6D`QiErJC,!@!B*P	"JsX	PW$svu5jJ
    uMR@|^;v5kX.}N7v@P%TkgW\~mi`hTANAr'KSD.DA%6w:1-wks6B%t~V
    ZT0x0jJևRDSj3-[01J`†)Y(
    qcrJSh!<|L@ZQd9oßW"fֶ]^naܵ4%ʀQ;ga"ZRl+kMV`cQRksusK+s>_	aTRfweaM=G˕Xw縹ɔCWӔZ"Ҩ ZuzI_?kL?i8 )._M 	dư24h�ba::ڞA@:}WX%dW쿑8Ψ긍ˤ
    o{Q#_&@42~AúunNbF	`nA~Xiװ�Dtȴ'3vӵ	mv'?no/̡?cswr?֭}6
    ޘ339wȖb;np@N/1YÀLMM]Trya,FM"ZG~*,#837DmL5WX,ύ@V.LQ0{T`&hFWwB,ki+oOK4kL?X1 u}ֆvc87kY3^l+(w;ȪE˩5[ᨲo~�k,;"a9[ֵ֎sѢMvѵlFxXw4vlYhOVM9XKJ"I-8!Q,fYAu[e)VwHD67sbҡ%YݻG45þBBm=Ү!+H!Y9-F;%A9(!p-A6~ʂ>?ٶatRۨQLY8ka;<=`U+cHcbk[6UeY+D:Y5@V|׾S+V"0La(Cl6utQ{9;h=qڋ")Ρ;!--{xҷ%D'V,:w},i;!LHNAu̜d񆫮۟;Omh
    "
    I9DF`DG+ٰ͐KVl7,pN Lx96Y,fbB<d&'/$~M| (-bY-rQ[81nz>4	T9ՁZp󳅶ܾ6t3";t
    taFXQa1E
    J"qiޛY(hLzװ{a}eexy5Ƀ/>Co(ø1NߦH+BV~ᓡ[qJ^}Y<+ZЕs׀=J@2(w^,+?_fɇPqC<SS:| е:Q2]JjM`QA=K5Z5.:foS7!FVfl#f̄J"ޤJqȢԤrTlgge%#TݳP0%Ѐ~HaanirsƜonice˵lkېtb(آyCW&bvA+dy9q?SDBBg4dOo<seV&l>^o)U020)]SoIu&`&I1;?rkEYY*ވ3o|,CxEA̛w2ħBda@6ɳ\#q
    pe~*;-%q3Ә\ ]|V>N{6hf/BX1q+rJTsۧY bNmnN^l@S!߂$m~^{ctp_9W\=e׋=[TiWxxGΞ=['
    `!WM5wtîDE|’o_G=M
    kD|a!☌ucu;uC+KB^3A/Q׆0)`LiQfogb,\Q#3WjB{n0~X"$$dͫիKKKnZ
    a{HBmjp834diNAW	eX_WbAC:8fFYnqQ)NAUΌ N!Dg-|
    NŸ틀<&ciaajbbp@-H)
    t6pw
    :4,,ik֬Yi@\\h'*jӦM-AQQf),ߴq=-	*{X=PƩjWPe@
    ['حn+XWgwb,Bsj: Dt)]ȗkf#[[u4>K
    ѻiLQse$%%uرCK.c؍7�رʪk׮W[[3!yeɖbN[džG:Z
    0h4_gςbYtEyw1?3
    ظ3!-qaMz,580w~<omh3ͱ1EG68TjNqqfޜ[!OE3�t%'^k"ݘB2<^Z}Qxxe2و#Ξ=m۶/V^�Na6mYŊU'UZ|v?KO.	JRNB&&*o…)2-7?Գ-R	o[Sp(5}iNOs'gN.$=#$ܷ嘎GPb7yA~¹c xB
    +((I3UqFOٰ͖%9j̸}G$0UtM	T(te֢5C141_{y".Ќ?bӘFf8  @JZjgϞۏ7gΜ9P(޽ѣGA]jQ.&7|aQ$.'~a4HyctmmjTGf6~=i+߶ɂ<g/ZhEľ:/{'Ȑ)9#Ϝ;~[“{Ox}{Hu~k`Vr==vӄgֳ-2HmWB=K|w3. $2Uϼ' !".Pg)n5@~⛫:@ߒl/幧{5Rmƍ&&&cƌ5܀&MݻO>yy߄z_X9F>W"I`0;7
    q)
    Gq
    %)=CܭU|QD5TH&2)!aa:N96ժ2DxWPi1sG�LF<fU 	Q	(KKs318֨>a+93W!n%
    xGdaDZbksM*iUP2rb`ÙPOw|ܹ߷*tpp/^\^^.pW&hB?jB	ٴLFȪY|kĔ$9"?\;xB,f{eާ@lCW5?4(k˦Uߙm!@B	ޒ){irO,|}lAvm׶߬66Ϲ봖}iVdpFȊcw]9_*dP\>kY+̳doʡsJ.ޡ\E"cZKPg�λA贺4ōgblH0~YkrwʉٿPՀO>
    JjѢFY;&&V-i>\3N,Ѕ'\OLZMG	.UroRJwL56/\7TRb~gggZ{*
    >kC[;"~!IRT'$g>B!od1@T>(Re%9v̂&&v&&`ͺx(mm\*P܍5,
    i7n\dɬYj۝ϑNjD{A-1"[\ZQgF$UCPp+r@3ѭ}g!dq\"H$bٵ<<-cC\jt".2cʼnȜա͘eڵ		ٺu…9w]Ȯ4u#\m6(;PFSSSX!PI֠ #ofY4sÈޔrWe:Cɇ=ͽDucָ"fHfBdbdϊRvMm;w޼y3ѣd޽=}דOlfYjܣ){(Jalȴy]-O"f"e?'N<L;|'e͈!6J/^�6lXpppDD̙3%JީMm͸I)Scb@8=N5t3_".͠e)-3yBQw
    +Էt#:uɩփطo_~~~XX`ג_BQ_GwyqYzy[ƔSX6jٻ'=?y;dȐK.ݻw/4TV'O|'OԪB`i=`Zv-(ҥKk[FGUd>T(u'M)DR֔46O1͔,Hym"Kk|7+;鲅xΝ;eeeCMII9ydƍ8PJDA6tճgOP۶moj+$l&ؤ]ג$6u5]Mw^KHexSpt$" cF7&Ms΍7(jnn~mpÀjOqNVGZVӧOEEEW~:8~MPPT*ӹs-5ARj
    eqUqm󄢟f6ӥy"63$dK5_IpcRUWtGץK;vc7lfGYKU.ot7a5LKK?<yh33f͚]r0,S�elUԲג
    
    qWDbc3+6s06O?ɘvƈYf]vo߾hSK'7?˴6o`U=%.\ݻ;;W^YZZQRRR^^^]@<1[
    
    n.4񿣰Btжu,"/F82Tƶ*[1ڎryV%ѣ~-[ƦֲT߻=RM~[0L4x%UV5n866V"xzz+S	tG\,=ˢ~Z=l|f;T|WhUμN$˗r_|,Yyǎzjsʵ14pH	kkǏ-Zd7ni4ڶ`\(fDC�m3!sZzDxގ<~GLF
    z7sX721_DFF\TTtҥmۆ&''#}Z�e<SVXfg̘P(*πJxEVb[Pj,'{<4ÃMj<%_.U錍~T׍
    9@EVGEE=<))	@#׉*ԁ!-[a'NVΝ;ϟqFPk	:
    1�֞VUԧZ-n%g*ŝe{rӏJ
    YfWZZ,ˁ={Y])~L[Թx555=r8PTÆ
    \dRɒaҴ:ћN早M94HÌ@-FEyzZuիWHHHDDĴi�ݴiSBBÇRkt_C<yOy�;[[[i\<)/Uj!_~ed!Sa#ŚA/knm!bP@?/Eoh?AU|܁>|ĉB(└ӧOɅFRl�^pTEFݟ<yRK=瀖N|Kɹ[~yr/#V"T5b˓.!6zϽkl	ymgbpla^wӧX,n߾mbbҮ];`zPjp1~$!Ctuv0޿/@UޯÂ~E2!aFĝw\߯Z6᭒
    *TF5D/ƥ*7S*"66-[pAm>
    lذ`̘1cĉmڴiҤ	ǎ%1Eo^fe/?KK.
    }�udtZqD:5h"b?m@+=qdjٺ16p1ޢJDc啔lLЯ_[[ۭ[+TILF`	@iL^V(4Z8\\Pes#j;snk3O2*"bOSX|G1ʀOٳ׷Yf*t8Q>gU}AիK.;w=zWZ*
    aAjs^:Il-\HîH$	i9#l-x(IPqeR~w_xqtC@KD$?fx+!ELeee[޴i9/^4lh_`A=AU<)+<}{O_^^>x_p[n'Ο??uQZ$M~_"28Y-v(Ti*&?4+9F]\%VI[.:[aifB>a,Ƅl5Qcy(i?Vf<rP(6xXy%J2pѢE;v$
    Ve2eCJ@2ŋ'Mm66305@"m,mM\Y}FC!(QdZ;8XIl_xve\UeOQY;ݺ<ŃBɱo:{SiޕHm=7+b̂2ufrL>婩z2>}:K,\ܧO[nFr8**Ν;mzP@
    eWeݻϞ=۲eKFbz*}y$U[)4uY$_G,AN\>3+Й@u<y^Fr.G7	O'*	-nɍ[[pCsJO4m~AkέWƳ1ߗuí^6Pkx�OQn
    0`ǎ᧟~ڵ%_AJOw}s?=ںu똘WJ$mذ	T2U쫴K_?6E>[tltZBR_E${`3[CZ6ihem[{vO^N-}`vPN
    3W]oY	"z02Y#ei }%c~VjFׄɓ-99{�VҞ<yB$ŋF0lƍ.\�wѵg[ōcS׏
    3{0`@Zpa۶m<m4@NNN_fLq"78%6Hmmoaegq@DHJgp,+f(J'OgoKiѓjY>'8yd\}~4K1lo׎rb^etazutOĐ~ȴ-cB>=W\C-V~v}׮]pUn"X9kQ]6JJJVZ}v///0,+Vƞ9sXy<5>/3:YXQTݭmEP�/Dt_K;W	:ړ<_{nN1qNj:/L|F/J\\\<eʔٳ©_ڙqtݻw'N~V@svǭ&Mx_SQ)1{j(,.AjaWRpZRK@`+wC JДJm]M\,l9~|WA	&vl+jT;NTt/zʦIsQ	9}fٳ<oȑ˖-h޼9`꺁ܲؼܴrQ"21ldCL~=SI3*5GަC J~7io?asnض5;rsRz׏Q!صnWxCIiQmCMhAP49xE3δlڈѾ;<CA(&8|oEissLۿtCBt]-E$df(gi|g=)0Fs=9s캚6Cdk`0~mo׵f5ӂf&Lpp0{3f̛7OT޹s'((iӦJ:=Q/{)s29㕂=4rU{4`?<rRpC}q57,4;Xܟf`?,P2t~,fL_{ևEBs`Ց-Ͼ|/z5<5;6,WN9A߮4e{tڼsj7Q~F!~;W4GKsCl`w 4eK~9ri^ǵ釶LO767×R2XK6wx>nPDZ<	kBSAy^vzanĞkehsPye
    mZyBb
    5
    l8%oGY#L9kĎ+YZ_PQuu{89f
    ,߬촂BHoZEŤQ6''g׮]b87WhС;tP^wǾ̐jMkSPҠy<ЌZ_v$ -08-큜k`RtU,d4tXL]q'|_M#C-R.KXybCiG3S;Ϳ|A8iJZ7twRu_gx3:_t;i }K[GML]4VY^&S�YSIK+P
    Jbw{МBg=M7sMv|ZqfG7f-o~wgCJ7&I@G7kQBMF=+)j
    *NCtbV!f{1o\"b:,7sk`j|T&;;Ʀ2Ç
    N9s&===88￷J
    *sSD&7+if�ZЄ'4qa`*]<ǜ<%V/˚2g4R(ݻٳ/_fX:t<y3r93L_Vbm`cf-B.}@Ax&ڪ8bWM05ԛ'UCCL+&n_"j0wU\ *$QRIaU	h!EwL4;փ6!uVZj\Ô4YAQ7J=Qʤ)&IhBzlִCߎ6t6bNyZBV^|`5#	5ԫЖTFfIgД2MAvIVf:j!1g0dL\߉ʄ=ϒ#om^paʔ)}gΝ[		Ytix7o111嗀/TOҦ%BWbkK`~4*m(1/ (RQ^ 2c9y뗴"u9KB7mKީ03 ::_766?|0xǎ_h4wp337drPqIo|	".aӫ%ȥl[eo;5^ޥX1>NЈjN!mՀGɇtkL>/X&AL3`[!)vnbPJc?s+te{7oe,`p<2ȅ8,Vcx`MWun5SG7k=ϥ}<ݦ;A	e¸
    K^<FǰkZYE/4ԣGJ#H4";#8)҉ئ"_g߉s\eYZP{&.?~
    V:vسgv{DodItO6eae"{OY"""2AeȞ*C@ SVY-tIW]%߉Xyzܽy{m۶5j;ִi^ze0իjժbp ٥9ˋm*,$"X 撄yDyVXĒ]l2XԑDL*_r}JϚ洽{p[l
    #$ED	t:Vf̆2^g!RB"S	�Ҽ\j) @, �y�@LKdX!t#GrJ:y$v9]VXMڵ?裊-W/qyULPat]3?A0YCV }0czCoq/Ր_9|A6
    d֗E	Ѩ4rG3_+i/әsf_KT<zl6pU#>�#l:2qԩX,~C\~
    ],'Cuăy5JZ1=J2Af6L_'âHHjʃѩ.?Yq2ʀ+2fy̠0\0gʝV%(b,hK|+@$yB>h/ K9{=w|JJӊˊr4$\{~lĠeb٦D&}#K֛]&Laʕ+bXYf<̙3t7b8+eŰ�ԠsBVBpP+іH@ B^>hm@@�(Lv=[Um˾{PCT`opx턀٠tetƂlʀ".?ˉ%5E٧Owqqq]v7o�eZ:pӆ`<A~˲`җX,:/J*+B9|!ȗ:�"4KRyu2)%JVPHop�I�@Hwrw	8hpt;]bID(e*	"<@hq<A4ASIl"w.C8\:KN]NmAYIaT͋F`c:wkg�]`0̘1pW,�Y1V2b=*ʕR`tC{Q
    ~BjР`H"|#Xg�Q{gnٹz\]erʲJ
    `:</x&MwϪp吖ndޤ3-˾(=y$nЙ1dȷş~ܽҥ?
    >?~䓇-Y@8)i@~|Bno3{y_;:V2g|;]s
    j2O>=dU{tLcN˭:ݩF%*6o뮳9)yb|8\�T?~K.c}`E]poذ+	dŏ2b-fZ␓+j@#Hs%pPӚe`B: jɫ]֡~tБ>(sީX`Bp9JQΠB#Ub)?&>6"8?:lFC0!qdV	FF}O-6;C M ;8naҳXOg3xif߽{DE¥ւ}v,$ez4qwmYZ^ϛE,|)n4_r<k	gO3"^Yis33?\j
    *]e.^M:ڬsf6ڭC\R{1_P	DqeĠ&y#(#k#,@.3rKm?^)H6Xݛj5w?Lݸqcɒ%ϟ2eJNxqϞ=wڵjժC\2R}Pxt0el̰Z.]e H(A+D!`8!BW<h�񋖆҃9atԐb
    B*R>$�-s?$/S|4mqB][7GDܽ|uj0i}|?MaJfuY{fcqX4/j4`\)|y14
    CAK{tzw-̈=S18u߽.;nZ1mzjsn}/;^cP#Ny[ݺ`DZFAt6ؓp2XMg,	L^U`Bz<$jI0N"0\(N`APW/JR;B2oP�
    ~hNk8qŋ@z۵kׯ_4St:Š ?٬-oк0#C*R+ Plx]Vb()-rxE*D+	cyQ|�Ti	�+/l&vp0�+ss޺qBE0*\1	ꡗYJbN(
    *+S ܍\I矚gd[.')zqe3[pO;yN7D"$!Pfri7
    ~ɂu2PʐcL`"A;p9RIY4v	gߪt8o"^N|#ގ1Z}8su+]^nuA2t&>s&Akھ>!sCeac(�b:QCU�AE[nr
    h
    lrM}RhJO�h?^?1#Mg1tR0$�[ͥ,Z(ْhQA~$-�?v/W�+M$&$h/0.=*(BC>Gxz6'Z?7|Vte6
    fyG_5mUq['BcqK`3䠱-M|4A#z
    p#G7mlF}NqaQ-)xPXF(LIlZ8lAHF0_6.%~Ú[N?va73!6]٨7;zap6H.܇!,+ޙE}8{�((8nm^YaAͥ!ı�|\0p�0
    *#e˖ҥK"EV6TFb?FŸ0DG~2lUoҋuO#zh-=U^j6iqV)50D'W9U(<p�z0@-Tk,+*bb^@׋?յ1?�UV\KC,[zj-84:4T)?6$+	.#l^&1z78@Re늋HMSNbyLG\j/1&DU߭k)bf<.]"eJ*嗗['ϧzSoˉ
    ʴEv')AzNDpjid!	ᣮk\uD�*('R~K\lf)v
    C!a,DQ%\DeLKzˊEZ28AjQ >/
    d(.xa˘ߕLLrd:!6^C,N㶍jQ˦^ǝ3~nԮE*І ~4�(CȲ\fHj-41}Q/SM[qaIIYjZLDTZ_€SJ#4quڼ_ԛFБm!ԅsZYz/8vc&#0@\m),,p6E|JEP~4u;AZSB^Q9)ㄘ((QPomp]5ȫWo!
    %Nջgsԃ;;Z,.	@3z19+b(a7W
    r\($ߣZzSNg0EX%	թ-08BUIW�@z6mAַ)?]h`@ܲ15m8c["UUǫ?FZf/<1بD.SUR&!Yrd/ՕtEBS\![ZdŁR!M`�# =ckg(O!O.+dGFG4syJuee:;( O^W46`pB^""�0#|2p);b(:1WpP$BU}	!-ilPM'HDֺ8 #OF>Ȳs~{:}汳
    BM%
    P=22280h RY-r2騇Z옄cp$Q6Zu	^o}sp"f		�ðDGGO:`@ XpakooEăE"ǼSfK�h/Ϧ#Zp`0֬Y7fŒxU52[I;sxK3!�<W<[{o&5*%l!>o`a3tխ),X߰aC
    ̙3g.\hѢ|�>С^_lٳp#p'6!༖_3IXY`T+	؈_4425U'Ftnеkׂׯscǎ͛7F?DrE�ΝԩSF:w\Ǯ-eea6ۋ__N7\W$VBK!2J^Er/*#~YBz[M䔔aÆ믯P(>|x۶mׯ_߃O.\
    4h�.IOO9<4Ay"Hp0
    U:C�
    07Μ$&`	�qUYMS;!TXŧܱcGӦM4h۷(o޼yyJ6F%z'恠&M[tǿ٭;'Oxi*˅(|E�}8o<m۶9s@>@Yf-Z7#I(X! wT΄8LCK@Na"Wsk$P6\:dw@!4eBu ;9yҮA?[Vmv;	�#&x)RfvSҳyu1Jl!H<x?XF
    @
    oٲʕ+k$zVH/6:!O`m(]wxkSzo8ae@M&b0 :
    !	107DI>80FD@utHA0j/:بߩRҨۂL:uyiPɦZ|y$eltkPx	_TK'~׌[<!h(ug6Y܀�*,?.fБq*3gjڥK"֥K08Aiǽk}q떵#_<qԉ{�wM0Q*И1b@!TpٔnA];x/mRG
    y׷7n\97(/(ƥis
    Ie{h/p˚φw^yjAS>KWJS/>F,xW	Rpͯ.CJ>xbƠAKBiu5�LU[�|ްª
    7==}Сnڴ_nOY,W_}U_gqEv	ZUw-0,
    6z)2Q	x,:tTȡ(rSb>)(Lfq#׎
    ir聕{I
    Cʊ0z_agΟ;]B~-d}^;!t/ըá!'
    7=oxH@X\!ܤ7]J8VuP\:#dPdG,ݹy|HVJ`6�q'
    U�EQT.GDD=z۶m&iѢE_|{_n0VP_hN/0EX.b`M%hMe,qcӉ̭GQ6'㪗0)84>Œi? V̸	u;6op`oFH@%?4vFl򻵯㈘;;Up{);aUZy<&\LC@P|&QasDJ#wUJhnT;Ȧzn0.yt(ᝂcO쫊VyjoN嵫@n
    ǎ:4nL/eN7%JkE˝\~3E[5ŋl6;&&f;vXbF5kӧSSS'NoN'ؖ?{̮cTFbU,
    t~;�;4^E*d'tF	ȍ0ƀXˠ7pt0C.܍:&$I:m*#t	i0)6[x"	SqD ^p=L0h`qp<:I`|OQr!Dz$x`&O"piƩ&e`yl"
    {8Y̙3dϞ=+W,((7nٳg,X0s}tֳwڝ`nFԲOm^Л�NviS`*|D3X~+?#.DĜ`g8?]nCDV6	`\.>bӘ`\/lA*eU�d{(x{<RIff&K40ټvwyСCR۹%?]+9Q*/<I!Ƈ2?BDjr@eeHoD}Z?Tzh46,)))$$dҤI9`.LIIiӦM~~L&ۼy3n^6uk9̗@`ȹ}sXB fl&%e8r K0wyLUP8�qөU?bxRJ*>JNNtԩSN6m޽ΝrlRk>SC_RvMo4l6Iċ(Y]ugݝkjha2|G"D"�qՑY[/(>Վ;xwo@$I7<1r_(H_%/i(RjrQFIAb'0/y?_:Aᬬ~]|wy2;{n6o\\\P(ՉTlv3SM^O^npρ` H7xpäW.<qĔ'No}vX|̙uO
    ?ĶËij)Ft62?A'rbD@*N\׿rY#"Xs:ܹd+V(((h֬'|2apd:vX=,e{Em"{4cfgzPXl^-:7
    ]{RTh#!\bzi׹:W-٨2lNJJ733b3F&Pt(HԧO{3]g2"EF'Ǣ2+yev
    	X\2X�
    q@[6^g1/F6
    UxG~IEDrrr~
    ?j;y&yb{o&%P<=[@8 4Z݋5W/bϞ=Ǐ2dȓNjϟm'N
    -*5uϦԫfZl;\I55@k8 ",w7BΟֻB̮ljU*Չ'FhѢ܋/͝;Iϳ!;do9ac߈CҜ{vB515(08 +5XLJ/yC:D7wرaÆ;w*
    sCG`GͮnX4!8[?'17M`"$C�%IN/җ$
    n\PE$b !ȫ?)r'rMgQ.&1dBvpQDU0ܹsYfiiiCX,]zѣgΜϟ2e
    �W1ږOS;HWvQ2AŪ2%I⯫5#({ui+5h�WqyPd^4n}U1Z828oٲٳ[HVVwݻw/F2[o[#8)-˼5إrqD'`ULϖWe]0 -E&ȣj! :bwy{%lh[#Uh4?^R%%%1B&-\099Y՞>}:((QmfɌ>b1,(3PFTep@(!Ix7fךfW7T1@jJt;R®O[PP0`[\sNgJJʡCtҡC6mT*hԨ盦n^'R<O?xpO¼eN'$RL%�#(NGGe	tg9w1yD)W9-͖{&oAO^K~!8FsA
    '+]0^o׮ݭ[֭[7z@z,w<m5X2ڬYcOL&S}p]viٲeBB7N�~`!+0�h3ouvTJ2 U;Ʊ߲#t7o!7&yOfvI_bCNzp7{}(F`vSAP:AT'a5{Nc2nwS6�H"PAݾP/K	DueH. EEE7|ի{y1d+TSY)I_8/ ­[cƌXW:uΩ[mZ�Rf՟t.X'Y	uYl �|I��!,i^CG~2IFf7k7o\VgYf~60DuGmzmtjmKh7ao+P!5(AQ$,Fٴ}jAoᄉoGL/%իAhr=z􈏏9rwd^WIf/l۶m߾}|>޼yӧO߸q	:vbŊM2)\mYSqrA�A2l&L&WCC5X'AQ	z0J/IB	$e͠NPN	n)nݚ:xIMgn̊W3QC/!ti(ifLtw=k;]b^.FR4R-1'\a- I|}
    ܹHffɓ>LE"QyyҥK/^|Eolݺま}))))5k޽{/Xf
    8!�UAcW]ցZ{%xƌ˖-&z,o9<$	負޻w`9y+aRW2}Fja&	"bUBN`<~!`gC}4yx<ě}kr�4!pq<8qkBϟއkt^l:s̔s}f&\)m-"=.֯C|qtr8/2%ٮœrYC|FhW(}޽{Zj߾aÚ7o~ΝF5l@ܹs#GۀDO:O?*_s^X.+t96U{iн|MLbR)@ꖚ]cS.%>O18,(6@$U{!dlsY<a4ʈ~0B<^N鰀3aS
    fqe@Ǡ%)C2N40r1Dzy\#L$׮]A'OOO7oܦM'O%`qTT㳳'߳gO@b1`@Q6//@+!J-	MC.DZZZƍSSSAL!''oȨW ~!๹_~%I`^@¡Iu"^M]me!t&SP&DPchi|]
    xV.9~hժU߾}/^ּe˖m>رc@;#nsjw�+2ݙ5+Oخ^߾}{
    @f̘1o޼={�%kС`j…G~2wGjAcո,zX^ln9PظU-6兼�\Vh4Au}{äϝ5ٱGs8ǫl39LZf2ScXBTz4&?#À�^NM6Mo+))xdɒΝ;C>REk_(S/_3D/_Wֆfxpv˖-EَMX{~tkTs�p̧o؛>\ɕJ&ZHK0B!Q{qYnOaNIa~^&T2Z%|՝eZSwF+Vfq-nqb_#j!Rnh4t%22rʕӧ]T**`^yvh⛉Q'MtUQ䧑r5WnZ>_L&TVp`	_V:%l(P@qUDP:uh`vV눍7x]™ЙC?wوۂ{FT$%)9ʘ�6 I@�Q�ྲ�R!/ܤCn#
    |!�_d2i!?~`BKΒ]l:=5Du"ĉQ*y2d믿v*{/9{ۇ-ٯB;w)tgP1.
    nv0( O[%ٖFy\.Zb1,͒KC4j�W
    
    ֱsOZlaw.lr6ܳ΍fnVO6߸U:(6\.NnV+ň1cm61~;5P_3|e]G4y}i"fԖTӗ^O#/nu=J0YBD"!'ZeXt: 
    	
    ̽<ӥe73/AH˚rٟy>xj6	z5?Uxes:F(O"cCGl@˭lc I1(tBPPaenl5nO&R*ԡQJ6IQp$aSV^=qLMn9n^IVn>1y.o0nIG
    dAD֯Sc?1St\9|!-l5xٜ̐Ey9mw-x{Aʾm3ZC`'rKEZ앪&)ϯh/f0�y+UF!kGɎ=r~ϦV͎I*:t?RUP4yu6M;7TWC.//@8`�!!?e�Y
    �.;N@69TˈyP"D2bc,F
    g*x,s	c7mcPLxWh0M8)
    	$4#ߟ'!5<pu-nˀIN�_^S~n\]2
    [,ho/x!".k`z{_;4N/0oW]2!V캳Mmtr\5d@k޽;@Ο??77?^|޽|'j*2|(T*2eİ;vb6[)/pA.TDbe%̖TA҂_7,k?9ֵsHݴydErXy}blY1b!ܻeG72M:_|psI=&J&jf5\�i#"qQ7B6g~LAI,h(͏+$Ϝտ홵湻%WY➲*A]URgN}nSU[�ƍmv׮]#_?dg|s0FZydnd4uVd""\WDAW9kӲbFtPF(E<B[PVY\WUBiZ܅RѬ@2׭Jp(4#ԭ~Qzk׮IIIoҤ	`vGݻu/x/4zsz>O0lVdЛs,+(eARRʮL>G6&[	v"@(	|rķ$W{Iow-OڡbzpPnYquB:ʚ&.*S[IwJRW.)))..SNZZZbbӧ
    ҥK1߀9r0$$po~z VZoĐd/_5Q+~
    ^GWB.k~vpv0O7DM#x8<oYzuDV+)/<>wl:^a$Eқu|jaB@T"l,(V
    wKV	;w~W^|>_*^ܾ}E
    <e˖ݺuR^5Q9%�BT\{b�Ul5Mwm&-E2J*g^7d]ƕP0J!?Aj̈́I脐H
    ǞWH0R^։ry+7?FckU*k(19mޯUd5?u˅W!T��v{ND"GNxmLr\F@XPK~�-evƥJL{Ra6X
    g)q<R!�yWh{5dkJd|hHjAAVg*녪^12b	ICr`Qj~V:U&'';i$@x糲�;�x?'fnfcM:
    ?6b�.�({<६�-f9?
    \za8$D.~̒ĶS=߿ЌtNo
    ypԂ2D)q5cb
    o}),Fb(jE�}NVV@FXAͮ@LG!QlpV(23H_p}GÆ
    ۰aC�FSdh`p"ݖF@�(?ĠĆy0q9C*w9ę<uz|wi`Jl/Y΋;_q}oAVB	BJBz
    C1$Re"B幀{,QCSSUُE
    ُW
    6W]odB>
    FZjڵ;t Fzٿ>g_Ɍ-7�T-6�>p8AAA=7y)YXq;fMub9�aAφ͹U?P͇R{C
    ,F[ڵB3
    aD$Hd
    kģ8VYka1JLI^(/Ȳj8	IEH-We n(O9x?^%TH9…޾}[V˗/D�
    
    ֑r股IO8!AqNǿ2 Q1\˞q+|y,QO€g*{P겑:,8":2<U
    ?$HLzd \ڬB!Uaa\[qr᝱\Ě)Bi'wo;[v1>ݹ֠gJ>lم&	w^j@mJJJsss[nx1fa93~ovP@2Nm=k8-_Ųg.^UP
    Yr6._v5M?_OV7-z7Uz*N|[aИtp/Fg$y P$xS]+*h!+ əūm<domsV0y\u,EE۳Ϯٲ_g~o%d;ZQpx{$Dװد62ew}wԩ�;^pӰۻkm>M.6޵<]cb򤗆6ۧ5 =t9&m'u<xyJ%-{cj4y`ٱ#%LSZF
    0Ͽ.:MmOs7,sdfAjw{a|RّQp%rNbMJR
    OEM:|~ު^0l扱nwq}Ux
    m[ΙzTn,ܻٸ|NlP#㺖@Pv9zluXW0*+޽{ԩSݺu<0n-\ýEԏ
    `bK}1Vf&"|!D!^SؽJ#3h@'АEo8kY~),<&MZuI)y/v&~Rnv8W9?rxE=9X{,>ݮhzU:N]/ahZG5_=i߅8թV";{;?=AB^Ko}6uؠv'V^ѓNZ5teh{WlwzƩKVi@^MBLy:/~Lى?x K0PEk4pWq~'9M{6?]-n
    A}7/گq[cy\j%L8c]?7cIBBy"f~^F)I 1
    uvRI>Z࿟=
    L�\;z.Sl^f̘/F[fMf͎;kT,pĉO+CNZw"GwH�4+J$ZіN$j؜~=XdsJrpsᖔl}ȸ
    =o[`;ԻM{.&.Ws:]쨵~C׍]sթܰaN<zMΛ:dӭr/FE|^W_mQa	?UnWҼP/)~qEEϬ׹zo|վO_k`u^I!nA%x%w6맽gVOmq8I[|2LwanՑ	j5몾sw&<^_Ifl4SHZ#ݸRN[\hLo;N			
    �}dNJxIVԼb:FG4o޼+V�mР3''G |+ƍGϟ{CW
    VHgNI�tVdY>ڳi+Et	VYUslF.jJ`M4Ėo}gwMLڴ<H23!msRu~ގ_I{ŇG8|^z}fՖA.B&
    qf+K(q0f=$ܦr2v[zo1h`rr㢦
    KVi8bJ_b{!ɢ!vC8pnsYT 
    QF<趬/
    .́JC^z
    uEZ$
    "tCߚ=qt?=1jQOq1GLi?Gr\i7FEī!U(rQA$Cw,ȰfZLV)Eϣu:ݙ3gׯ?k֬iӦ3//ԩS;wܿ?bT
    0Ggtӎ4gȃ"GՏZnߩ0Sa)<ATlx2j̦T�8jJP_f1S$vN|'t۶궹
    '%?{^o8\3k%iH
    	FQ*2LZa8˃z۵7RDܯ瘦}~%uFx-x1Mf܏}<!|M]~}7+<WPcMzWTwmcl{N9) Q{SxgH_STfԢ\,8#	jD|?=ɤ<IEsȒUCj97"e?s3ͫ$T܊߶my睑#Gx<8^z3fhٲaHh5pXRu4b_*7C6*rXn)w@nvHE(:;Jg`*=t&؇Pa70XvaA}Vռ0JgAh:Bd2`*k a	΄\~d1t	0i4�EP\oэIy0KU_R׺I!+JϤ!Ηxjj=Ԗa%()	PH8\}J_}P>gg޵'fίZ+,*\mS-)ӋF_/TW>͛7;w.!LCݹsgIIIȢa
    \qSl[?dSJ@uc!\Rl^ <* �ȵyEZ|@S!_2>]Mm?9Kp'V( U^:,,YSh5?[=]vX,G}RohpfxZZ~�+RV7@-{4T5|?G0<GV;ePBP�g\,+6ME(-	%|@䣽ǥ>Nz1+u<+m(uӯKJ$TUZaC?,yhd"vȿ-�z@ xK+=(4еq( DmV:I#Mfek6-ő*IWge(Q-)Yʒ(�vBFcY^/s~ٲэ"{(L)ՑdL�wM^NC",o[Njyd4:<(x76;]:J+p:R/!I#ST؊_jawrDF#\VRY1xR+$LCbZr{Ԋ]Y‹^OVd[Eȃp%C1ȗh`Ғ2mQ]!<HUz[){ᴍ@P7$*=f¥2&Zd1iѹ=ǎ+ZݸmRg(d|jt_yڋ�TP"�k�>IP(I2l$$:"<nRL"păOhCκM9AL.1tċ1Τ#Fh7æ]6v!,P(&!o1.\2z_m,ۿ:q%\!f#nTqW3OО[h8^Jm|1/maĴj@~ߥo4I>Y62ɇRz}ik7	^{Έa->+Fyݮ,RTe_7MOLE:EKSbЏ|G
    ODHo&58VT?:]]ee~ל|eŪE~:ouԱw/#.D5oߛ"-�&*`i_
    Ysv#[Gd_6l)gFd8k(y+K/eo
    MlrN.'�!)0^Xz⧍G]3jov7<`qb}bUL˧0Zu9ǎaY:7dzu/kӮ/q	\.΁=^cq/CR@SP~=AhJIaZa+:_sg>ٞ*Л'ާ'~߹xpUx]f\}Ctr_BOB	lqr!hK,}>c+t�pfd͖eieN#(ԡJQĨ #ߛau"
    kYz_=jzG~o_z:1Q	aax)n/iժE]UILqr:Nyﰤ4	1,zZ}wB!k0Vݮ]HҾFd=|3w
    `_{EMOHh$	HN<D(ʡX
    '((Bl;;.D@B	iv{_,KV0�bJ5(	%_	߷C
    t]'y)7=AV친x?F@]%8bwFV2A˨,fF(?RlhJInit[ " yG7O("~xDvϐWyhV#<FdPO_}a3>
    (ph?ĥޓێTMǯ#v})`r!9f{`q%:LvÙpp#6jWME+Wk=QkooK4A&ƅӬ4s"pn4E]<# 2p]<y4-F`=;9rcw8gGcdOr<ȳA:hOv?c;o㷕:-
    ]hB6eSm)(_>uX`<1 ͻ3u~n@g{ڭiCfe6:Ӏ.^::Ec
    Ѕye,U\bhzvU;w:m% 6)I,
    XDLH׭>CP3bv%;ǎA%/}H:zdL7\\X͹kTmNަ}
    ?{iJh(`N*&G&m}COhl6Njbe>oh0\j8isZ�y"VWQV+I
    cOURt`HN-=ujėRRA/}rLHHPiR/J``LóQ,CUrްl4RN1,XR*)Ȳ<i</cgAHr9VDa>T`Y$pv1a>>4[1�$`Q`Il5&J
    .o_`]EH$ؓt7~<Aٝ}ί9
    }uB�>2Dmi4"FO5qUG?Ꟙe|B5ya{.dV't{{&G/4cƬץP׺L5SG_ycM#<ON}<a8I1-j&.%%'WR |D١eQֵl_7hES
    pFdmI #Hb8*1
    Sl. 
    փ^H1fl(2tlm;Q_]GIcOPiNXbl;eOoqx/n^	+uUHdЖ2Y
    
    z}&4.L+xFgO]gݎ{k1yj,O	pp]9ȉ\ʙ{@wK`(.<ekFsԑXq&2Dvunzg�3E%qF}Q2n_\/%ݤ9"#~>~vhLQܓײLč8P_ }kJ"ZiZ2DB8`I++*\mt3RQK[ZTneS_t^૑<A5ueiDBQ$?BIJC(t0yԳo{1U37ZU"ǡÆ \c*nsZySRFk9Nw>Ml1Ot_:fRZ&T�r7>S%OH#7SpH0hTyJhf`#XPUww?|,cZ5_	?Mne؈DV3$HM'LB8`z,#)?ED8GpTR$J8՚_E'|;\!p|`lSA]=-vL@oHC_<_cݨ-bʄ**OKBBHe;M6󿹑MxSV誨*q(Y6~<W8titii%_(Msg[GfN8Qpk\Y)ųDkS5DNB.CT+̬U:-j44<]~Te"H9&]l:nIWaix	]9DLJZN5yNtW֖jE%kM-
    )avcS�h/MVU1IT$f)Ix1:43{PWr<527YcYt^>+W)>=^`[0/8y6_[Bɮjfn?(ȼ
    ƀʫ&Mdd<] +(
    "qbS""zz=Ґ}bY+-5U/w)6Stbƈց0lS?񮶎'di<hͳCМ!SW·3
    ?a�v5{d:̀jcrL�a:WYN]`*"1>γEZ&`jTAhp6F<ӒL
    &$(ڒ(TR8hq2,8qԡ^f-Z%
    /Ht_Q?.zwt@�.(HQ0&<A
    NL0ddӻo=նQ*̾t$DyC,=P(gESϰ4GP*FhhA	'=M^VL][QQUjgn&l>˱?}pt}/p۽݆oXuYD;B=|](@N3###;m]oy߿/mݸg
    94Q.BH	}lCI'm#xWnwtm٢ebblܰ>=g>A/5~򻏳)יP|BG�̢S#B*JYmFLҟ^,nyA&HmEMb)1R$Rs	o *N`
    
    'J`MEH9so#F^o垻M|g?(|a&R{寏aA{h΃_thbcKk	
    %
    Vk1|w?{֋7,O�#_⨢v¢=M'/ȴZKᚕz_�ŵy5|@W%&':�0Su_I1Zt,ƛgkrF]"	-~|ÖקN�<%<shPP8}+û >wZ+_9aC0Gv}6"rà7"%6,`@�apxЕmCK"DpCֹw%<<lsYmGvJB["NC4</i?J6{>v~(Fܲ t&+LcoL:N@~x
    _?,i,_8w?^Ug&-*M=Y`hOeZo\Dl9Xki{˧}{c-ۺpފ׾2դ8^5߮iӒūN~Κ/7PVUm*r$?VU
    ZS
    "ّF~?dL»n9MJ`
    ئ lVޚvbϧ~ȱͰ}şXžC` eXD,bpZo_m߲ДE;y;oڻM34~+^5⛆"8R>s.f.A6M4b|?mFMԏ7*8
    h0Py%u
    F`	B4&qfK/g%/@?bD:|SP`i3omW^!ãNobT862xt
    |.	PÕ2ؔGa	ޤ'bU5bA-zM"[7qcCejLfU5~D&9> PklcLLC/OܯXzc/ 賶Y,zz܆ۦ~_p#96BP@$9M0r_\m5oJw`{oG]˜�<@s#dwl\8P虾dsc&f.zBI.[Mӕ5[}w&ô;w,sCMW4j6!n7)Ѫib2cپ*/]tlf9\ylPm7ŕD|]e	ut3',k3PS)
    ʦC psr,[T}'⽻Q[#PX%!!1at
    dƿnZf
    Lkr37eD|c91*U	hbbf
    "-{bU*NcetjbڰMI6MtͲF|#'ZՇj?%`*
    ŭXNK_4H,Qs*vHsAL<7)\XP0lg&:"шD(lփ֐@l9Xyt[gaCV{Og߲҉RR&nI¡Jժ33㒓'ghHi0Ypv9U+ˋ$mPp"LMsMM!!(uƿu][&/j	>r=~VV0yh(~ر3{߾صٚCnme{û*6U9NM0+5
    >ZJKIJmo}271Ż8>{b2>=\Rz.~=m/?mۘ,S/}`C8IRP
    4yN9wfc
    #䡲c(B$%7Cq\T|r3)<DŽdSdxDtCOսm&Bn
    Fquh'藛pGtw2m!j-oS>~}G0g_{`ޝ/qU$}tOi$ț,faqİP_YY)=ˑ&$!qw]>ݲrkȸ4pҾ6.vUjuZxK!V^"?\xFedgm4C&O}읟3ύnٔ2-+_[sx:6vY{H"IfqXLpnD6J
    *O3I)e"qi|kݣM2.c|H�$S^TsdW1fCJxc5n.AZ@29'+ɂŗV/617ɦD�Y8R}cR1|u#J|*:9iCZU1N{bN~DeuNq$ߘ]&&:Kh(bփ$ːq!j?t-Y+8:y%p#  cP8VWJ?]}Иgsu勖%:<:,r/&%&d.XBEcsZb0CO1\u%*yIhfn1Y|cD|K2ҽVKc;ːq!B
    yw5yif )NNułF-YpHOOgiI)zM
    3,Lp3Fp"1'q>	j@%(@=E`1AHWWK`0ER|Α3'^p�'q_RPYSUGRHV<1[ii=NU<'@/gT"B/` o>PnGi]Ɍ[J>:8FP%9vC6-X³*jע痗jrk񇩄Ǘ1
    1zRfRQ
    a"H=u S{itx^ܿWKb<Pm'OPe ZC&fh@HvGЦNJw$7s<1zOVc:kaCC;s5k|v]ZfúW|P
    t$!D˖\S
    ԳG^h>|N?tXI11ZgXdh&	"	`X!5}'�B&(<H>Hƅײ9!SZg-)5;
    :^WKVi6[tl{SZ:\PD|6Ln6L[ghGh�x^%s.Jbre&m*7!QB̛xE)=3rη|8lȐ]{=kAasnADQ5EWࡃqUAs;;띵4w7PCc6N|r\E [tlוx"qՙTD DA.yU.[UV!dL6M1q[ֈou.氟:ul 2.e8ZGLbR?}5rV)5z
    D5^$*FbC4'6Lb|8ģ:JZҜX?;\B%eJ!1|aW>ZG"
    Pm%a8H(Ip܀e'1A#4**).rn%^gZzz,L2~yq|jhV4&2.XEe#H0}ĭ[]"Z-9=ɑ`U(IÔ`yt8=W
    V:֞1Y:$_NV@K^*sGOŋ6e:ެDFr<^@\jV$Ew",K LjO,	ũڼy٫T*cfoC<d"->V_sr"0CP X78	ijPLD(+JKKJiNgǬ	:1f5Jf/6~L2.A\!1w*˸"M`rKZTCڒRmˍ#b`8EO"-&8h�:0/EQd"(8Q[Mº>9	JW"b0cr sݥA16R
    &0.g%JQ7SN3ႃL2rba0{@"E;]~osFG\3EW*jJKNkCmw{z8�݂L2w+>Zn= 'q"0r>oEո5!)j7
    wx#nRؒ4&>*8pP*1潺fL2{()'2KRT"K2bƯ(E3p/+bDgX<P	Ak1zb\l(J0SV⪭U~SikQ�u-W&b/,|lQͨ#+n`D,+8_4}ź'Lk>~1獏&B:HPPQuaUz3
    'x],6GAe#|MuU΢ubO:[p^Cc@qX 	{
    ?w`Ae %Na>>ݩ["ڜ	ۗ>T.[8.&EP@Cz蓗>iHwlUgOZCu皷(Q\BA&/ڹdNCLmN{NӞ앉XQ藓�^y9-Zh2mݲlz/7eZ?:7o6ս,11Ôe~6プ(	(U-ʂz:gy17ѪP>1{e"qVq{k;xM;:`զ.YGڵ2̝[T6'شn(\g`A<>ŔA;?~^/8%D
    |^XhKji=7һCwݼ-#k2n\T{#EUu;NTyiJk5]kJf(	gw/uKZ_Os�Q͜	8mE4*L2n'V<J2"O^_*He&ڥ2uj<λ�"FBl7F?
    aEx7j2ޢq)I
    դUu
    vV\&bMsՆKkK}<^ЩH0kvM]`U4,v\D}`GxAu4X`$#0mO8^D8)NWv#SqFՂ�U+qTd"q0ԍh`ym:1J�q(E5ZtJ2ivEXBbXg4-Mvi۰p,8*Êp,`B[QuYgD;)IC;?0Ec3!@
    &8@)BIb'cJQ•5.r%P�%>Dap!,c	E@/]ƀ
    %nSM�A@|6u!BCM_`ҤL73ajT:����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/build_a_mod_4.png���������������������������������������������������0000664�0001751�0001751�00000116374�11740644603�021504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������tEXtSoftware�Adobe ImageReadyqe<��"iTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c061 64.140949, 2010/12/07-10:57:01        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CS5.1 Windows" xmpMM:InstanceID="xmp.iid:99301F9781A911E1BABBF68D28AB7070" xmpMM:DocumentID="xmp.did:99301F9881A911E1BABBF68D28AB7070"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:99301F9581A911E1BABBF68D28AB7070" stRef:documentID="xmp.did:99301F9681A911E1BABBF68D28AB7070"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>h��pIDATxX}LSW?Bb
    *t,]5ΙGf\ɚȂH6b\�Qd#%Rg�)uE!mJ-m-O?~{9V;277	{{{\4>==ȒzT5CC@>ߺ|/r͖ˡ0_'dpp0(zzG4�Jӷ-cee*
    .^{.%b1C*XRp7Z̳KyyQ8&@_Zi?r,f
    Gv0\4"2[5%uhR.F4_sB!V{A+BBgB]SGrvJxtD�{o-{oS}_XT=<u}iEEMLL\NMeK@_O3UUj"%R;_焌<7lnkk;&*nݺ588-)w:Ɨ9ARKZ4ܔ	U 	Ώ+..aocN<{҂+iSx2CmJJ"1ˋ"KJJrrr0ؤ#D?![q'J]ujKa/k醄8fu<sK^1/*33�E|ڼ徯\>W5R/DA<�6"""66
    )ځ	6i?WX@(G	ɉ1iQ9r]	wC)R	ۢ9Urp!Fq/w>68uww?Jt)sdMY(ǭNV'<^9y枞$%%$l5&HIMn}Pv5{ DZFeB#2wZ߿䔨(T:::L&SnnC<�&Db
    53RtJ}Զ||bbbp[mjjb<WGe~DT\d ccc8???44t%	oD|?|l߳dee9cZ[[OVw’>�d6goً@ XtI}}>IgHȯEl
    
    |:ET2ߝd^VjBS`9q[0
    vz.-2oioeQ:VIz;{煮\Bj
    &riiktŠSH%2T[ѯNh}Ev	DΦ|E9%8pd$И~;(McqՕ }I{N;o(4tG?љF9n%eCW�1A&`gdD
    L&_SAݻFųJh*(S1~7V]+Œ1}T钟ytLhxA^(viܙwkV!p2%[COׂnڑ4'Irہ~)B%x	 K0ʂIw0[H8@Rݚ$'F!$YL7jHXMXZL,ǑRVKS_xeUM޳RQGK%-}(J#ĤPhX%Ma~Vg`ؽk,L	v*[!}@H/_?և7n܀0=~!J7nߟDϟg.Kv~8_A[YYR6[ػA1+kUڝ;w=%2tW
    M$666�"y@AAB8||zb-Wàʰ~j{r4a`hcޓco,	}:ZZZh6EQ|*a$*(e%>x0!<Hj2M3)(10ƥ80Dp6A
    eu	{gImAC3	9J!Bv[444콇kjIמZz5XL|PY{zB;}4b�eO2&-e8rsY9/‰
    )
    ;
    AF.6p0Zj[ZZp�tB׃+Dȁ#`<znϙK|	y{{+ܿ?0Ȁ177'mx@QQQj
    1�[guxv
    $	4D "w%�>~H4
    k
    �4bDkƂc1Hnz8n*9S!seйA
    ROTIAաt&q^t^
    -֐$
    S�ͼm nY00ܺ
    @eЭ4>Đf?	վ@3/4\Sǭ>qW|2�LSW2#3LBi$Anj�,9u~朡\dhSt.,!tj	D>.Xbq(fāOw^_)_R<9y{{9:y@~ߥ~&dCU`T_H^9	~tA띭y;ڑy
    sEKi
     wV_bvk!�?(_y3�<Dteǖ3@ύ|x
    
    ;V\آP\eV#<ȄZt{Kv܉EWAWHTɞc΁2e6a)Qtq[B)ѻ	yX|":B8_r@J^kim:ѕkÁb$ [:KJA9`çҢ;8
    xɫI
    ʮpH3–7})YT:a/�s`i؃zIc4~Oޞӯ%ۿ e{;ɫorQZZTRW0OS>lKg6*wMMb%###<nxB[91Θ:xigZS{4'j5Q}Qٳl2;9mg%11ZZZVDû&'&*IEh4__|VJh>#Y얫4^^^??P'`ŒGb7mP(W3	~&**-2lҥK,<x%cttnn&&`
    KAdW5kV\	fQ-·ۇBH>n?q}mkѴB>N&twn70;Yin􇸻"-x{*)
    QZ,Ew?(( YAI_q!#F)
    c;qJxE
    (xrVq0v$Ӑ%(Zp:`rx.&_|5k3�`(*	)yP/GDe8)q`Ed``3A88nx}C"9<;F4U@?^k!K.�
    V&w>;=`2SH\Dx<5T*OnD;, Kd"XE.baYS%<G2
    U}
    [&sGFW!8rHNN4UOR5MO_^K`8$wHm[η-lXa2u:K<==#""d2z�ucb\b6mr(
    gffw.,,tSn좢"׹c^]L;J"fX植3ƀK}E%u.dm?#vOhS*ĵ$>Ps1CoY?755x
    v50Lj
    3y>u6JmGNq:>nؿ`k
    btqb-"CTZ$y.Ps#bex(*)-2mb%GfPBkWq^TTCm@̄bnCd<sdzBF*m:(P(5u;`Nvbux/ 
    U8`¡ |)!lEqln1<-YcЕ1bz³$[0
    0^]E*anjx`TG|X=b
    ogbY
    Ձٍ$m۪rmo#"B`X:вYj)V@D뿕X jXZ?kT݊Z+v	jEQc&$`@Jy/ė@B{v=ܹ3o޼;{nd t\d
    ܼ]Ǒ<S;ۭ-TW
    G^z(S|Z�##x\sxtJzC!M*O(Njkl>1Aڭ=e;0ORIbes@]庨(Q/aH&$2
    nTL./p=cŀQ"yۄ,f- .V%_M(E*_Fn֙i~NjhԶ
    E(P9X!&$."t}ik>ӱ\fjI*B_ם=(Hz솳ż١rSolي"+taÆ֋b1,aӁ6M~roꋢQE\I7|3"lPb]X;"XE5#dJJ*%"gHmJE(#h+3ҁ4g!AH(EYI!r(a20RB8) Y.
    7*$;د5NГ;qVpX`5q$~7D	ލ)W𛼕-IH~`0{S
    t1B3Qg^ڸ<)Bo1)PZB$əo]m|_r203Ao�LE17/G=-q"pUk@D<VVM}5_#)+WBNr:REF2@,&K.}GzataCT荍|4*\yMЌbQI,¸k.^Zd3H֢ϭ7~C_mwyBEsW|n>yGN/1ȏm],Uvƙ"W\t"EU)'qыY䎄>}!B3I_t%f} ~Qqd,L*],r	2+p^D)Z[L=H>4-{6n0%3zxR+LP.}2ή66NNNÇ)yQZTDww{yyA7|7S,UJWD.TT*^}<k~
    avo*O2RƠFT^Wش,RTս&>
    3p:NPHH_"ߵf+Ϗ9|#Çׯ_HNNhH{2v-g?ĐB=Zl77RH!ݲF3c5lT]eP~`ٳgGj&iJ#'4X֖NF>zsI7En[XxѥٛYDp.	eIGie
    v�><00ޥ^PoyË`5/e3{_k<Tx)Fk.t0$SB$G7vxkY,I&(x/qcNI7 ĊqSHyK?r#2%A,$ rz1"/	RvJVjtRA*T8`̖S6(:`L0-X#"7	d]^'0Yp8FtֈaX}#Ͱrnll | $Fɍ43";*|,+(@ a؍JB`Hf$0_9?EB,63"tVXaDj_h־!sR݂B70aY{'3�;�7Ԁ(=@^ĕ+;Z$@;VO\ɧFsGuPGQ.]%�]Fi(
    {:)'ed!<9$4 '!
    -[f٘C*1LZN`zB-fQ@S&ajDždZgE-[tD׉,Vs_P*/srDFA9dB0@RAhrT8319z/CX<._L9p{�8AbLs=e?	}zK4^mz|rB!am}^_;z%.E!M&+&ʋ'2,U`SBKbKmg u=vEJ(RVVV޿?i12h>U_zʮ&&&RY\hI7Y/2]x#3Yfxnnn|>ǎֵk&L1Qv
    	&Նv^ś^?
    
    tmRgO(�z
    ]7=ICuz ooo&j&
    f
    TP唜EKW=\KQqC
    _oʡk{Y(v/^+t;
    D#Go۶mΝL&0בMMtܣGYYYЩoJI"%%%**#
    T<h٦G%,s5PH!Ignzy2(P_N,=3^D6г?	>糚@{
    3Rdhyb|!$$OUR6ݭJV]]]__lHѣ=QhBy2qq떆<L֫ m&::k=NqFH&z�4<hd999֠"ڢ	U4ϧs]:�<!/fh⵾/
    _RAiÓ9i鼼_IRĚOpY{ӦrFڡ_yyl"y4^Y[%#eb$EMY$oY5'
    bv/� %bvD~2w]ΟC(@_@Q%:2
    c$!i!j"m!
    }tլ1t kw;+7@6.LW:
    bH}3	D%
    
    ?y4|4|X\C"&ݗGSWi%VsVݜỳ|'LBs56'ng"Hy>T$$TV9_Ok44HD>C$j˓Mm8M&,5s{;#0cg:Ƕz$`n 6<4V$
    Uߢ\I (yV -aF6y*m&s~
    9�h?r}u[d_k:_Òtu'�{Oc-,HE,G}KVğeWE/+vMglEaWc55!"5$IMId<w>fj~{Νs{{?R>$ prΜ6Գ!w$ݼ8җ{@j_MYy/雪tc7w(;jWU\/uuu;y 
    5?1MQTnݑG<S8+f&ECqH&ႈ=q BT#6[LfNDt"AgG!>;#f
    #֨=bR`#P-7hG^eyw^=WVr/ah'�Jm^uL Ja'!>-q"dGE|vA'10I42Ǭ	gkp#VkFAj2	hb$+*8
    Ha%Q+p	V[ s6i?:q(B\$AKу
    9<m*	/:e�2k.obXZ[#l*">s#}
    Ōmk1Wlۊq
    '1cij'FC{*]I>~=h3:h(E2MNa|c+DI>)$+, L-1
    vL"sh!U47$p0p&uyg# h5(ByƬ@& d5D(V[m"{`vٟ411Qފ#`䪪B֜]49BoS[UN&=*{\#AnSRat|pkF[]7qAh|Tx#{1Ktc8B?xBd2oQTn~
    Olv'LC凐WFr愣f^D䂗#ۃ툾Ez*:Žnkm]کL#D@J oo6Wwݔhz~o#wQ5{	D(_ߤ)IݝLu	w]eѦ&3 <Р}N^&
    o=*-^KɕԈ@t
    kݛ%DB%D@[?9}4z|O_%#T'<MZ"#|E!i/oә%lc5to+cX%1xtƎaAH|nGxdr
    kCqc^]>I#YHi'^
    5zAQՐO3w9lEj*cyy;hy[\KE""g7<3Zw9lDs1o|bbLH͝þ?z
    `ɱ]p#
    SQكۑeTWE8n[U/zUX;üT=fRrf:}v,E
    |b4dQoGƯ[b$]W?/0ɂKCAOC_A]+拍WxG?M*eKqk9%ĔIsMхBОK-ȶG	5{8ֵ]㻪~A
    ky=sJ]dTat4}rǰ-W?YaaaEE'2&AMصk-ݿ+
    zi,UVuEGGgJ]v߾}[[[+w/_|c"G׮r55y飫
    -@*$?b'Cz)]ğ5|ًS͛7`w^2?oO{woU9-700�ERՍx@Um~`n	j'MV]Q[
    H<	$υ9Qr:<2Mߤ٭.7#eeewe%|76Ig	*[.Vv=>7377X_A]D}ݹa{
    ZaϞ=><r[%K?~\T{ڵ,AȠnnn{a^z9#�پg:R
    ;`ޣK+$;i3|"#{~t[|yI¢EL&BXkzXb׮]j;w		izgGFYvޯGfIX`_vE/d c+C7ZFP722sWsE<܌b1Wk9d]2{~zpæxj{}gV}z8~9ՖxGGH(}ppShBg�'ic+T{*wV$:ЯY?/Y\g8uwt,n$le Xy۶mT}h{߿nȖx~r'&mY{@lf;;zW$͍ב#/.dFRKƣ}"BӢxA|#[Y	cR"Ԡ_O 1&	F5uř^F*<=Ѯ}ݻw:w>yI{ڋ&$$aD<-uBS/S>hWW,ddbaW1UlϢ%XB.2').L$@iݘ\!ǑG>PZFbjb`\:'Cn9,1K-2ӓ+Wxzz*~Ui[g)
    ŝ-(P̾
    CCCccco޼6:`>}6Aj	2Oiԋ6m툌!ۜ9O^BHKCSH:iGS]&;WpHԩSpk^W"}0" R_vYZ/lXjgTt7n8{kDgaD?Ў?˜|#9g3G,h`Á5FsTm<(Xip*e.55wi}4itg~$-F>Ì40"3l"ǀ҂HH4? +<I##h!|p-N P0L& H`B&"_
    
    \L~c"6m
    B$Fw+81rCPB"[Qjp?[cA."BwKkHSV,1$@&H$Ð%Ԧ6lis
    I!A8b0'aˬ"  '#
    X֖5*%NC/
    ekUx#hz92Mh=[#r赳D>D#\?6{#D-"aY"䙙]0"rAXTõhBh,)J89<-/HdIKmh@s~cbD
    򬪪�	lȷZ98
    9|qUR_p"!_D0µ.Afpk^�#ΐE\D|o&~(ዾa,ÂPgA#ʹ,r~=y}זd~fȯuLD s2QRۄH:`_SNˑJ,xvvLߧ,ZHKK+**J$/[[[5$Ǎjkko'XLMd+⽭~̱Z
    Ϡܟnmccc[#|5##h2P>zhTX֭[윗lvTWWz
    Boڊ%FjtӖey飢5իW׮];}2>TT__z4aGn޽{h:Wtڑx{Y&%6}iݻJ@mh\.7::zf޼y6m>|8h*,'O>OH&I?^RRү8e]t?mƯeY[uME̝c_:~x#FܼyQ͒^+|t{訉)(yӜ4c333mmm+fee1vj9H*ŋ+W4B;zhAA5k@AAѡ[AJU>^}
    m_?4ꇢv˗-[~-yQydQrcӍ+LP^mˊzr@ KIB~$#^#f(4(߿ڂ===? ۡvRSSLfdd'-ru]4B)|?읊,fPx$:w͛7+UBzԁS<<<>0޿{Iggg+Cڌ"߿۷cSɓcƌ<F999 Xkc!\;;;'''7p$;v8rȇη#?0(x
    TÑ!auV|J;�aO5`P]VVkoo*ÃO
    Ċ\|a`` ^wFZTjΝ;=jmm
    ˗/9'NEpcǎ9[54VqiccA(}=)(g
    pyXL(uGhP[| ɻ1f7?;GɄ8p%MTxd> SFYCxgvZe]|Gۻ=/tG<iyΤ}`/)vrYB$	dK
    _٭U|gN?k+UJ~5
    hcS.p!-]p!~2sKjIfd]RH9ąHnL00@꨾N sX!Es¨$H֓U!L`$4Ý[5W"I:FHu[2#i>
    /X;_Tڶ38&x4qVaF|ԓ⭽QB6abG<Iiʞ-8i:#r~A̸3L"g8K4":F9"L_+q"?{JI	C$s6g!:G,h4:āi)rY;F--%حY5(4VMՠև1
    Q+F!4#1Q53mּ>W}l7TEef;QFa#tv1BE8~?_ PܟW4G@)W6wlQz1QmL+&Bql	Fr"!yAdq(|Dj״m矤88>wIs@:{
    Uݛݹ69h]`XbgXQ
    zljP[-aWXjEòJ"Z#K43a=6{߹w6d2}s;wsνi^i:We@٪Y.	D"Z8OjqLϞEֶ n9s?wyM=u+
    e:(-Xnŋݻԥʪf=ݻ^VOadܭWy(INXϋ9a
    \<)zZ"YǰIDձÒko޼Qް**;MP`qJbMJ$Rj6of?8I"^C+O!
    �8vKHxK- dy!BIH-ki|`'!†,*"c("-{.@zJpR|Җ
    	SZJ%zV!=B>+QipA՛А\y$5~�nSN\VheEs	R'J$*g.%ZՖՂբ*?
    Ҽʇ0K@fg#$o(-6ЀdY`K	v~dto;O[·4alTv*[3"Xȁ:$gOfcξ˹[uiD7tAbTՇaUsQ-zV̪]DWGw^o߆T^aY%R?~ejpyq(L<0JH L=%[K1e0QT�aKA4<@-qn
    SJH`8\l)oXͅ|,JCk1BIXɣ	#cqv	$`RmQ?M#-l#Jg7zA<8ְl =R>jKE#*oF4eQI{mYa	?oJFw,vЍZHÑm(4pɧ#
    YpC9Ih	܍iml}"M8Ƒ⻠my38i]˶Ohv꒷h>z4_EݧSHʘ3[zS%Wsm|GzMjA㗨vVO8gKв)Kʇ&{[Xk<#NrV^2&ѐMT)툉B0	P"!i
    
    XS&hɘu&O
    Sp4b$w>xU-QKE>lChW)!i֤wrHϾ{5zGޏlFjUh__39MB.t{RKH]T푒 +H<!%I7L&-n	BM{$
    ujbIy81ȜXbLYYIvKSHHУ͟@?QV&2F#𐌔`4=ՏCcDRKg*9[@GB^րgk 
    -G|We%86bΩNk$_)\AQDEC"Iȣn1r Ͽ݇$\:Abzp0u]S|>qQqIяsJ+fn&#׃ŷADjS[HFHkj3XvXv3pDLƉȐD1F[vp&'/b*#g!Ҹs}	GB3^Nĥ8@
    Dxz?oF| zD*8)˒hʾٰχ Fl?|7Ahfyeَ439'#+/wv-HgC˕)pPj_)\$u	ثloVTi^kY{Z[uEH9>y'мHb2([[2/?C9>ms	QxwvD`:ѐt-o!gA)eszAp^pH89�	5	=Rp?\?	8uM4pT3Ht¹-NBHM�)Yb25Ʉ&)u#3.אR
    %Պ&*tN#@0n$n4!fO8"4RJIx{xbj-A^'BUsR5w~=;׶=2ȑ{gypB;K\`'qHJC=_ɳуȳ[y߱mA)08!
    lRz
    HdeN<|m7? ~!lz$/>4_g}M~~~;z._EGѽAuVwuf3?c{p˵$qxDdiiEC%7m欍S7&m3I,4ݻ͓GXOE:Tyc-6CkL2ԛɟl{mp	=sSZ#)k逐}"V~!%Iz>œoCt'9'P͓ribR?xe+U==GAjyMk9eo6_
    n|R]yȻwܹr>cƩv'$TSSSE}eٰW83WD;&ޚƽ5YT|!b~ZۅeB&oݧiןND4t%	%hjwzEŏ;Xm۶hvZ]9Ig6{Ԭ~H@,[Pi!hifZtG=eFȡCVڷM[t7áѲeK#
    W44ګۀy)$ۨF-ZtQgc[E)8vf:Zٷ*dcrK6mڨ#i(*:hGF/;l!ehb 뙅OFC<r$ڈehIlrp7Cp	~cuz\Noۣhׯ_^hĚܡC1m߾(
    ΐGI%%:W*%тZ:n3t*tZA>nݺ訲="]A/T卍Pj}2ڳ˗e=c+Oj[gYYg=vizֺuΝ;CCCAAy}ϟ?|/feO<bl]`<X+-lꑒm4Z#=[Rˁhq}�ógqF0oqC455ȇT�t4 4B߫x4
    2U61BcP�m:M_<T~E6,P[6<mDioI
    zaa_w
    իEb]6ZZ 0`"Հ)jqaZP>~1;wsɼ(А|<d4)fP@X?+yq;I>{0Ilci׺z$gqԳg޷*/^xT^٥ṉs}!}PRC6iNaB$wz'lG
    K:::tġMqwKn.jժSַU~
    
    P(j>~svZu+>ܛbi-=ZZZG7`<}dq޼~Ük7:mP"i׮=׼O111׮]SܹsgQ6^zɓgFEE]V2&rFP-R"[
    [6`>r\287nj"DF{L>R"fk׮ IJЫ*&m߲￧e4Vj%߹`⹺S
    קOMZ&&_{A[
    ȫX3AJ;=5Ya捤Uj6zoa߼^ՄD>`i>~`oRr	5|Æ
    +sq/ի&XX]8+{gBT)oq,6`utW_L =[0ǘFn+# .Ӌ|w`ywpᕮlO۱'h^	dCB:|WX)u$`O<Y
    J__ߢ#{BBBCA[E
    `]cDŸ+
    >wxh0pVgbVF>wbMKs~YYlH%H8X㌀	W<
    r	|V`eN	h!"=v_XZ"%Ҥ~UY,4{ ץ/};2ԩ28Ż'/r϶:ϣW6)U-stt&0VT5*awl=݇|ԯ4,JA;W/SGBh@-_?~zKCo-CL(@([#h,)L&%N_|+&8˦!RPb(rRB{L.E"5-i%+$h,EhBåֺ6i�!h]y1eIKˬٚ6~V3,(Fʴ=u`(=I= VyAHؚL6X[P}m>(=V|W+v5I0wFpw=zԗc4sej*rrBXӣ.IbP4&NeNqo=15!PEC9Er:#uw=zTӡ_~edddr5L^g;!IIM6v8PO2;X|F/=eȴ@q_DB}Bli@b4>8K|dJDѼS҂0?HcTAup+]G(a2sL;;Q28͑e>U7?:Yݻ{y=}}:+MhrbBbKc\4RFLLP޷(:H>4pr#X_u7X|_J!5Lj@Iq|||Y50r)T7!<7HD	[>Gj';;{ܸqK.|EZ~^tV[Yt
    J'M0רּ:=z5TRɼX/vG8vp']kP%A選?~<==](H^mẎJ;eUa}*k󝝝X)ǰp#idS.bChİ5FƚaYYkNrCX6$$)
    ü!5$)x!LFBX<bS DFFC$rYuB@P|B\;̟?[)#<ʜj/&!!nP@~Z[>�&kՒϟ?^9F|ƥfK|0-	:yO(0mI)N~惒YnA^vo߾իO*=rÆ
    
    ,v76,u8>>Ei#쳻3yxn^mxrt&%%ή^	WU�ã5<7BDDĖ-[G7wK{!.m�(^AH|'bR38u5
    J~ll,ui*h0)V�A�,Qx_ZAWzYRU˶%eWL2`"T8h	kBJaMz$))IGGG1۪+\bW-UP!g�ai)2CfL(z#�ś	N]W[_Bh
    (mkȂH!"hNaNұY@#=D“Km�q)\ALpLN)LARvDpPx.9Uat$:x//0YHzY[W<FNB~|>E!JOSK?M/*W'ɏ*S8d*3*={6J#3Y`vyv
    ?ZLđL$R8MߠAP԰u^ӗ�MgIt?|?u(7I8!48K-!-ΊpeIrZaA@ru%`=AYP2rxbZx^2w35!du`ȕK7
    f7_uC#7Wz!vʞ=YyB"K/T8J,.Cr^vF<2b\),r+-(d:Q'dc
    FfDX=r=
    !$_>Ik
    FC:?@.ruN#�T_1m3K2Yޛm.	I`[KB~NrIYh	\p!)͇A@	%qhCa0ibzRd\)گ0lv޽{w	5doHgfRWrTp'{߄2uFH>2͟$8'ǓZFQMcVFvҠfzfë'"Ԫ~׻]~W̓VNx)|jjmtssɾ_5b?UP[|7Ծ}ݻ8{7c�TRUe>`XǎrW5޳g~9::|b=BCCmRܸs⚈b[[	&(qzסC׬f֕H[HRKpc~JJJ
    ~5e=bgg�e˖aaa=ҥEN>-
    5ʻg}ViY8c;ժMmzw+;lUm)�[wѵHAAa,ɢѬG¸q@۷˫*짟~1bߓ'O`cǎUV-X@eэܭ[m,R0U؍/s}ԡfS3:}Nj4ҴlNj
    Ν;=<<WE_~kAϵTwNƍsέm\n:
    8sWQFA4wW4%b00~U{QxP#MwGi*HqmQN5(z_VeF=5OkTlll߾}r
    ?3V'`}ǁK.<hϞ=n
    
    
    HNM9oIA}55pˡ}$uѝ{ZTpא{L_'NtnOy֋;mnzdS�cǎU:BBAN(~XXҧO777-U=Fy44^޾}[TTD&-g
    [E;W/=dZ>?o4AGL&$$T̂tX9aVD,y~מ
    dV`j@˝k׮4̙3AX[[	III?cҥ"�:9+dա1
    zɝ+#Ls3M?{ږ~̬MnkyU
    2;c֬Yw􌌌F+1L`	c@0w\PolU#
    s;=^FkœLJ>s-9=4fC7sFjj꯿=dȐh
    Z2Ϟ=;''lJ߯_?D}ZYGOwöWPVʕ,=RAk\Kh:|JG?FK)0Yr}MIIQJMI>d\Qu=
    ?<χ*
    h:nxMb9W':>s-B!X%
    (+A`ܸq0ڃW7oIfnϙTIN�оA;X[[kA;&!Йcą&w||^򉭹
    *CCC,.syp&Rv@ҳЌ k@
    ȃNiV_p႕?f͚qς~):L飶scEȑ#㏢"@x^]Rr-4k,(kŊL'|rNA{~xZwp;˗ׯ_t۷asĉQFYO5�%B毿ZŅ@q{3f}<NlڴJdE/c2RK	QA'N,((glVuСz1C>c%%!@J" |T
    YYYk1s!O>MN<T^^^#+f0�m}t;BIgtl}רĬ_^
    
    
    z,Y$))I?p8/^#]ClޗKi5Mp=W}dggCO݄B!MKΠS?/kf=B�#[DDPq&jү@^34P"4gΜ9U9
    jfhy=�:Z@N"$ (9߀&I9�;k]tq_>B8qRgV,9\Au/)-RƌI7|>Q?Y!<+ @/=;4&ywA.hƄJ6V^VxrC*(?j,V=U6wl,Ɩ1
     X@JI#`B'VYjDRP&Qq))؄Iꭧ)&U.'B5tL4u'/
    ^uBm&d"i
    ;>2+oD8@*
    o-</KmPA!d0ȓ&Î'z"tcߟ23 ܄ daвs:!nQʳ{'&\x1C7;sul8uVSzjvOtlAHUxi:]ц	{:Whb
    )z؃왥oEZY.깟LkT0הx@goQaձ5
    #w$POiTye'\h4@Ӑ/LAC$<zI(WDq7.';bys˩J|rQ7&GL1N(ȡ%C),ZY&g\w5@ӟ
    }:wR7B輅CЃ*'Gĉh⋯�RC6
    mM	5|h݁N4`c2Q+}y;b}tWp߽?>WPP?''R*"t2\U)�&МL1\4&+|E2CXz\g+}mXDZ^pZi7ʙ'>2CdIgӞ᧼sh%GО-݅wwTJ'|1lJ8@jX:oW>",r,G#D"?N,d4`HOrW{NCQP2&)cÏB&)W,+W|O͡1_E*O*I/`bXuM,_nf#}BͮG Pqc&p*W[v==bߠ<wB=~<BOEv=aUBDz@p+g&"+1:2lN<I peTz9̲jxd7*S?#Cf1qNL}0tkO*Z^b�nL|ܨA 28*[}R|	lX{&{;4qD.[oSVw!f=|`T	TI}8(mr#viDލ[vg@@vjOi>zNZAop-sG4A`x?3s"DK^PԞS*oe[)O0ajYhhEڈ4zWt\</%CA*˂6ty*i#ۧhgi
    [Ha8ˍ9"/cx\o.Y.w(sk641[7A0
    <҉ڢ?V6ChJ
    %ڻ7~Jʚ
    E^2Ha/CL!1ME6CYZlYDNTһs}-]sws#qGEnˏ=QR&+˖FC-vkL+ncڑ#5]ꗣFR
    Q58qiiͦNWt#O9mF^qy!
    
    /r/lSWAUz[
    .g
    y(/޴AoC>~}(4v=&B٧O)?kv#�#q@"JޜbA{_tږQ~[5EEEyYբbfseK"۶m̍Tb|peݠv!P)kj@S׼y
    @/+@/_PWC8ՐnwggrVLQHzᨑ.w4:HXAlI_}T|Nӷ2tP(vu%|~]]U9oɤuUˋX9WzՒdD}QAMM6<ZU#BauXO`Yw#cޟ?se9BaY\sI13耿L,ŢV)aepBl<
    ř�w	8"+aY$5Sl1qQV=/zTd_$LS2^<-xWeS_zIseϾP~a#-0W=81umPXD	"-ho j}3+pZ.V]jOM H4X3'QnvvDQB?4C12Y.st,V/}?>(_p[ʏL[7K),AXO^(	2}7ƟR6*0-{~J <1M:T��z[RaQI9sY>MkX܊O+2d`hR>/1rG
    ˉ%+H#@.ą#4.l\bהkK#`ɼK	-As#jd6d(AeOu%63f2/DVnD9Za8rp#gG_wk�A
    ^>t}Sws8sT*f;HvRN{DDO`>ϧ4Iz>_?LMvGƒ m)$۔ttBt9 )`Xd(j?Jm*"gvB4^(\VpR'mnDa>=/0Pz^N#ɐ?e㉉;F}D"I)Vu(qEzڢÍZ8˘̊JQ#_VeB&RrJWd4<y#-4.'z8?,#Hᔨ{(S'A"2l+
    xCˠwBRq5FF#ͽ(Sw/:Opp
    H{J7wÜfۿ"Ưh(ALQCZ;\{/K/tFL:NpϹ:pz~o~�
    :i?^K%&p.ߌDFg<W1H(!{/T[{yhAl)6mtc2r$ȔMeðغfGsY8!_=l8rYs!oBI683ce="mMdz�‚&	m6o=3ķaش$զHծI
    LB	d)Ҝ)$"#IˏK/gFe"&DXфe5e'1EV8"(6d"/4SlAbˏ(}!R`Oo5aœaꭹ|i"TtFԷux7o?3a*a-]X(B<r~`ǎ[nԀa\CԤ(qOZAb#uů޵iJXnLzعhc.<xlǑܦ2)sP;ۀT**"Gߜ\n]HfC~rQHIo
    Vs"ZCeb?~~e!$#b{)$C,
    8[yǓe m~9{dLjtq($n2ʺ[zp3}e Aލ%(vUFPl?J:5*_T	͑W7;8kEHfkXmW6rT8Œ1x}*ͣL#>H8kҹZgWR	bתkB3O>ضS>N|4&=!ZFX̐otӜ5
    q>9o>Hy8AY6Fr*ny޷2եO]]QB7?Nέ0)W2*1�^/ފվyUE	-;QΛ%7gTxS(
    	"@"ț^tgْ	@>͜ENAJ20j`zJFwi
    i	"Dz~VIP?8sp+ט!Wn(vǻ귦kZ[^7n81v*q
    NvɏB?/;}`,_=;}֧5ߎҧLDYɕޱuBdpv•CZw锼C+o"4!d)'e=_e:+Ru60!C"6nGE@�._6$ΒPR=OwM*۝!/zHΘM'-t)	"ןK]<Jr3 D'3ӳiRwRuFNz
    i'BY>+iq'3L=sV⾨4'x@PL+RpL7$	VXdʊG'[CޱBo.?7"b/^[0beHV,5փ6n/^]'8ΌTq`O|Wyg2<ruGe%Wzu?I 9"~	/;e=_!f@~
    տˆG%J
    M?x?8꺑OUUdDgC䚮1.//	?
    @wѰW]*}(裢{ G0KOZۂNPJm=wI6BRzvs(]vqdMMq;xP_otiB̓*Eоs!IK,֝C.';D_:j24kZb	Om\l k]ѕC~ߜN\ł7+C|8dǞ߲|`|Zci؏aI&u9SR78H:pNg8B4lsmpU5<r
    
    D[H
    LQѩas%hZ?oIkGeCHOm")r72I/%轜KT1pP9z"~kOf
    ؍@:�yQn.Λ	gi$ﳈH\$tqNJtƗ	I
    KQh薵OG2R"j;SҰ9i3K"%KC!j0Qgq۝3R
    giQ&3)M3}&h;/I5):?}O][æBo^8vo
    p㳕Q@lmVXΎ)ᲧFʨOoTat5kM];vܪ-gJ'ϻJ[R#DvOfBivYxgږL!X@sGwe\g1̥|i.b@|N;2?\[ݾ2ns߾60yqUVVα ߹Ƀ%
    羐PT,--i[>}7GM�=UC$kG.\mޟل c_L&8& WBMKi2^ 7kik['N7kDͫuY玠%dK^"j=cg7~|\a(dB:#z[hnxVƕ^b07F<jk[q/ݶmۂ***^K߼aJ6ŋ\ҵ쥤\z02^b`q
    =5kʼ{UUuuvaa}_Ħ7'L65~ 贁k;VK[4笈cƼ,HY13XR~+B64iS/Qva7Z2pjy㽌lV+Z5:o/_?)nˏjWkI?5ul׻wYws5R)h.غZA]:СspA(
    U˖-J(8G!EU�"::%-(Pt�OeӇgݹkbs.]Tu�WuRQFAY9Ȝ"5cp~J-e>)eS܊>'Ѷ+X=\Tou\
    j2KKKAțfɥm3ͻI(MyWL($tjFWKPj
    PH6mô|
    :BD0TWu`
    FoIqqԤj*"yy/^n!42Vn
    GKY/\2U\ѕ8aR-Յ#/^?Knڝ|i"TXPȿѻ>g�Tj8޽#i*.SVM]]=W͛)g5/i޴EsU<ֹT6One
    Pc\RXXPF nmݡgԀ ?C.E=z6ԙ)�P!@3-~dd4G˗/s26jPV}'hO>k9vњd{	o\5VR<H𑓝RbV
    Zx%fJ`,`:`t(ȥ׮阚2QgyShf^jj.V@I{""HXLB{E5-Eun1Q+|U\0KE9=#/^<{,OR?Ǻ{jrߧ56*yӂ;$i)ܩS;2M6gă%LmNV%o\VlbflWy(xoR\\⚝y	kr纕DcJ2Ta)<
    ]ZSTWa@PHR+&/nEQ]{⍿-),I&ۨ*0ST:‚ׯ_QqTuo_>OQ6i\.d?}"#5ɣg:FfJܐׁ++Ce*vٙ}Izݫ7MG^Co[)jPĞn%V899yΜ9VVV=z�W
    ݽ{ƍ.]
    		8pgPYlٲ˗/O<y3-W<ɦtjU+}fzrz{H
    Paʮ
    P`p_:pj z~wck^zhYA?|HI'hAb-TDĭ#:ώ4`\-K�=zɓ:t#\5;{~Vm_v-A=}:uȌ*~v5uE]qW*Uqy-՜1nn
    *_jox<inA	
    Bh|lr{5:	}^ʰU*iQM&-z1v:5P'mU]Y5ɑ7oѻ{NjU,A΋/[Uo$:2~q
    J*hB666;v6olkkkܖVN2\oppQv+eKr`` `;;+Vw=S<6D.B*<5emC.{!ﴘ)F=I6(7/&iYo=T[F150(\N\QwF~XyٌݝFqx(	(ɉRS7d%u#;	⚛DRZpr٩kH{Rg`5p&,r5*cPwIud1S)H_S:.]u\{!aٻW:/iY+tWl۾NӖuW˔FD~1.EU.]_HmذaCw+2'On߾X$3|'
    >6W୤Oڡk[Q-$:mwԨU!֭[q^Ne˖z[ХA8BVzی`p�:r͓JK@	~ѩ蒟޵ko5NJ%*YFq]vsl{0$5"rDbO@G"ԀO_kG+FJp-J=n۝�ȸGJudx6VeDgE5
    W*YЮ];:.]:<O}$'#ۢJ_:p<-
    >IUVV7|\[=-U8o>??.|~nedVcl:1j&wenv+	KǤ}|ف:⇻SvaoHN=K&@n&NKkoO1ƩXy#NId%;゚|uULd
    ra%{qXcѠ,feAMv+`ff�=᧚lO(hT}>?\+'$ÐP.RBzQYGdٚ(Rm`7k2!6y'Zg/Y"\Ekhʶh?MxXa3gMkeׁc Rd;vAOo?lY=ڶ,g>??ɩ000ٹn^fB##JH'/3GJ]#`il1r%fa�Ʌ9-%FqJ2qV\	Øm2E2JosfP~.[K2n(vW" +$$$@UY?Fb_d5s]SgW;-_`#7`vu^3CCCS͚roޓt?377obb	jjj`H6Jf߭}[qѻ6-sjL(�eu
    
    ׯ4gƌ_WYY5-gxNFӌ+SОgp:b)"^If6/AJ6<Mҹqt{?Hgҧm-<ݤ+�҈ijAkK)y{%@-,(by帴I:P"i{)g*"۷*$$*}TK˿&o6hRйrKщ'-Z5&&@sdffVVB
    +gG?靶+R1t(5[P{Mkt/e(A9ͥ*z]෎_f["@F@,XPg#yg""sFE>cyli&IN)^}
    v$VM5%R}SH
    oذoĉ/<<!˿KQY˿eIUU5))'$$$>>uPJ9&@!�7""̬f
    \ؤ'=.׿F$N/z!Np9"*'2i3QFɔ gǻ&VYc91vPrbahzO$GGꔠߟ1cFϞ=ܼe*=>Ccǎ>}:R@$5:5,t&3ENx U.wNZ~,-[Im>	QO.qB[AP+$(7uqaC9:/Z<yQTPrVtߛok]$9
    C
    f/N@ׯ_?,,$..N_.SpϊuEe[|?-s:A	]bUGJ8ҩdOiU}޾}[__Z:59s(h,kߝ,?ɮmЋJ欄;}wXDR#IX�AdZҊ%ևb ;%Jtl"VTR<9'ɬ:'2P*ggq/U:-IO?dg0׷649e>D7;=bY Ӡأ]څڔڠ52%{n%.yfr4kpsJJɓ=<<322&R?m㗒ͧ%)m@%V }7ä?2(2	Wi1uW5
    i?yP$Nj9%%$]&DZZjjdJJYQrm@^;B{D
    |77;w#[^>'W@@#n
    {Nkڞ>(X~jlɿ:+)
    %|ϝ0
    \K(+I6+ImN8LZ%P*a'9y4-,2i҈eY[(Y6DmpPJy֖	|M#uqƙPe;f	Ee�WΤtH@
    JIS;Q4ۿzj)r<<b9<7"W(yrkГ5P33:@E3IѦS
    $Ģ.2w Dn(эL!ukf
    u܇FHm]#GhhMqFtۄJFN(ZOp'D:7IƬVņS$;sP[ZP*6GoHFn|4b'Hd>-9SZtJ-8rrhϞ=#""jc5<߻w})VZ$r!=][A_|A+K?m"##m_2�RadB(g״zwjS^SBIY4e|$2|YLbF"y'$C4禮Ĥ%GOZ
    u,tikw_99#8�"?S"R[%G
    >hLLފ
    j|ggZ`-9DaAGQ
    hIt"<DEE \7VZ;IC(4k'^w`Ai7d@v<#p:چY9NJVt,&-jK)d$$Y`7dH{ԊZ GfJ'H$,"nV&SE۷Ǝox+nS+-Os*'dM:H=uuˑ4mٴ$T)YdPDB(G"bTChÊ*GOId+g~){(͚#aaa;wkXy]4ײD5
    $U˲NPh@Ã\UTc?ܕrHӢUQqutdAѣG&LZYYƶmm܄;r~
    .tވkKO*5p@%e7f"J?f^K+Zb<srtRh4_z***nRpd44-ewD(?ŬbG+@|⅟w}=&Bǎvܹ͛d>P&ԯ_˒Gj+,pEկk[)Wş|xJ*1"Ҭk*ko߾Cڵ{0Bc:{.(QUU)84-
    [p+~Ul3nAڪU1M>|Xvm.]
    Ν۩S\62U4|jQQx�|Sha^k5k}Q<*=6‡ɗsUS#|.:ԟPV@MզM(++%w<DOvvvU>_[
    ,Ey8l2;;;22255�J5u333[xEgGv}QhE&uuucccLMM[YPP5;`@$@@@8޽P@S϶ʰWFWXXRT,E^N6VD5x[
    4qΧ@MID圹&8zxx@WzՁ#ݟ6VW~Vo%V�ϟok[,;tS#F0`�׭l3ldB_L>+^(uz:*4k^a
    Kg"6?9(bP.o4Koy̍`
    [~=}VX3.5kmm˕&B>|(pС9꓏Çzt+\	MԩSoovv/^(oܹ3׭xȑ#.ix	p+px/pƠV:RhT7wy%/f4nRU6(Typ@žqLqqq:OjiE4nT*pڗڵkӧOOuvn�ҤImڴ@h=\J
    |Cz\h+>WƤcs @CZ^ue˪
    EL\&spTXX䔟?h x+R^go]ڷ4ޮw3esέ~jvl]$hXfddԓͬV>z($$ŋCFGIJJVsĈ_}׭>A	ɓܨjǸ
    6@ާO^iDp!x'Nm@y=VJ+T\kڳ:%\ȴ]~{VjwF]CCفV>{쯿emm
    ԩSڎ\f	Tm?hP9BHZ(4@cZ}AW<ygW37a[}_H]IN۵Rˇ#Z]@vnׯϞ={neMѢEN8Ѡ縄}<!ѤsQ#|ZBUU՘fA	@VSC\WWT�e?\X]X=+HPAa1cƿ['lA:ydxxÇ!^(WWqՓHPAuTpT>1@@^
    88Ҙ|s۷o
    6/kem[w6RE/rs>2V+1^usnTQRS0qqq!!!f4i@lKsG_:t%\qp)##cĉ�MpOB%uY5OݍG?ݽ3JȲqϞ=;u72]v
    իWu%@777Hjh�
    HDr+wU#8Hy"C[K.<#8R坼KPo߾w7oԻw޼ym%	AEDD4Ph5|%C5AȃA`@P=!!'W׊ʄ(7pU�4PAK>_mk3Oߜ"?ŋІ1&@u(pKET@Ch .P4`&u9B~o߾
    q05'{ #xq*GTc:%ӗ_F~:`xA" ٳ'>Dv1w9s&~)))̝;w߿~AK�=TAFZ]vˈA;G:<0PTHTT愧t_/88Q
    T8
    XZZ6�P3嶩U“ӸU?~߾}={u"\ſڀ"h!߅"q{o>h�AĀ˖-_=i=!x+*�GqXᨆ	p	(T�ch]9PROdΝ2B5etx G5@+5(jOa?~0
    +rG8j5#QB5::=qĉ=Y	'OWqG8H=իׯ_%EƎ`.qp	nذۗ&N&\̣PL(ߝҝ_�&>!
    1 )$(w+	7BP~$Z '< WOJj/[~0
    aUTΔ!@:W[bGƸ2Li3!66VOOo˖-)@F E*&4ͺR!?39fqmJ`۽H[~ZfU{ٵSLV"\
    EnllUKoljn-n]fQOlS"T_FVVBOXʄFeReVZdJCB6$Fbo+6PFAX,Q%l_֓$
    t%bҨ0L䝴
    H`D%}/
    !+Y\{-ڛ%$)oE{r|(@~
    ¯s $"#Z$SV)2R2h +r
    /BːFQ<%+DqK]MFwpCˤ	eȤNI{ia>$Db+82֤쬫,v)vnRq3{_7#=pϿ3	"4ۘ>WywL2"yǁ"#&2p_K"zYWVtQҜ[A>FtB>WDb8n)
    @╗kelRN缹pS8c1\ߒd;܉3rs·<ݥ/<VV9/H|@pyDڍAe<KU(7N;ry?#Q!-&.~牢Krʥ\XQșˤ"V	ֿL,欝Ge";-UXۙ_T%@3D+xd{5<4+VS'/u@˓%F'^yaeCh2G;*KՇVL]`h}CݡZfysMOg{uanNkCϤ$ODRꮾk7\<bW'BЬۥB~%b3diyt=hlu;/fg#ۿcWC\,.
    B&CB&GOR̰𐉌J4=MלER㸿k>PvU9a.υyWL?ѮușQNY#ቨ%2_d,FȾC~]Rw?fsS/sp(I?(+zH_ԏRNkt/R诎~2Ӕ5 2J	3kfvUߚ
    *Iw!SS8BAzG\#DCKoɉ~^k\N9#GnaD_WiCѴNoCV[k/\w>
    
    f?O;^Vw~	9BN%t՟e|>c2uR(Pd}Yuˮ?*3b4SD[msֶ.gezY;H[uC>n'Z 2,h. w3tqB`;.*v)D&kfR`˓gP)Uj&w
    TYdM5kϋ
    Lym:p8F_|l1;#QaXUlzxTM>2D>-CH]0fD!4I~	hyRw�W2ӵlaMO*:pOe^ssvV|_;x}]Vt#ۊ%?st/8n/]A_R
    ևE%TQSeGֺeAw*Y.߫d3x'Flf‹,prW>V`p>-HDlC[,	9c26LM8L>ʒkiwױEs1è͡zd@$W>Djbs$4vOƉה&-bb/=~	g^34Rnzfïwu2{'O6[~ee%!VQ,uQ%fPץȨcPr}LO@5i1F*Jyq{#9I3vI¸[ͭY092W
    pfr8(o#gҀ!
    K2n5\YBqGqQm	Y=$=����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/filter_arch.tr.png��������������������������������������������������0000664�0001751�0001751�00000004706�11035423623�021716� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��9��������PLTE���333ffff��	uIDATx^ˊ:`]A̋VO1+ж!zC3KVުOg*¸!)3!T)!=3=3=3=#P~ͳ3{DsWp<<)'	}G�,;=sAez陞/{/2=3=/+3=ڇ'@{f~pځ6�}G)G=y^^hOIcA'3*E_Yh)K:U?3תLT>2-ATfZ1Z^?YH#T=3V\ΊcHD+RgG8Pegr]<ճ@ēґVO䜒~zNÉ)'-/?Z.B3
    +<Ξϙk}Kis~#!ZWˁIJtsqRR|pHy	{S{{b4rnXyn+Jֳ�iǹy=u4(6{h穃=Xc:ˮ{G9_{υ_
    
    6V
    P
    R๷>U=ho w
    ? q7lPXHE^ʃjOX0>xl1y�D(uQ)XL=N!n"<=y3bx,2x!C&գGÏ_#=N[/"Xe)^ʣCєҵ0O"@<&rI*ߊ%-Ey_u!4sSxR[dG6Fz.BHbC=uQP<c=(s(ςS�	q婈</فXk|kĚ5k}Z>k�agg>?陞陞陞陞陞陞O`Ͼ~Kz)@1<ʫBOs(߀�;hꇛmn
    Cy*ֈ6-m<tް=`�|0S;xW%�]P
    s]F]ԝf_rIbD}`β}<|r	꩒أ)?n0ϛunL0w^@6o]izL8|T'}~}}痡yLړUpv^"o>?_#fU$_=N:Ϯp>c{Dìy`~_ofP{<xI|ί{~ǿw%(- ӇQ8?_.a�aS:?=o׏CϏs~y8W3eA8y<yYC¹UnU6MϞ�zmc P[OX)3kL�#O<-	º]N/k@k=sןiSϟahFS_^쑋'Qv7y$lURs~}mU,ZF?8Iﱚz
    zKpO`]:ϓ_·_bmM~62pdNWy͞'<t귪6zS~=]oy~=
    8d?{MA}7?}]c<o8T!ϛ覇x1|Sx 7<<ȣ=AU
    k0_qPqcw{c:փyeMiOG{� =RWf^{ j~Bn&S\' =^N"K~K=NY�AzO8R]~J�S˯`GF={m/x}?!%z,I s{23=|~`Hs8j|/kKg3[_([-֧C=NC=Oy4K0r,j0s,J0S,4̣<`�q<,�8a<C͡<y|@w@¯ɯLO6t�2_ 9A`YuDCx bV]_
    F{A/@띞=]�{x!д6N/JWwNR߿SQ}%8PKAxlS[H)(y8<=6��3='ᘞ{gB_@@XC��b/�Ze/c}>/陞陞陞陞陞陞1ezgz	gjo����IENDB`����������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_filter_new.png��������������������������������������������������0000664�0001751�0001751�00000002034�10671421551�022000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����K���H"���PLTE���1=��IDATxNAgw4&.L;&$zEib+#4V"510фYQxD~ݒmw62'9̜ʘ1cƌn[)K}6J1rE[B	(/1%)!PU,<cyc2@To4'jIa̜~[@<<u?cAj00E6/vIܳ#_֚h
    RVy{fQo^GӖljGQ�x(yE6?QNFе(6t
    !bW_2!b(V!wDe~$P"ҝ7jL4SSK2b0ů/pJFU P5Qq? zབ^+
    )H^e_o4*tp^t&oe9!{˖϶sd/%6"rkd>yɰ#׈ڟAq;*9DJt-f�y{YdgF)FB%eGɕ IQ냔'`7:I0
    rH.K!QzAC
    S9B8
    +U甌v/8JxN)w9z+-9N9%�Mm99hF_4WBM51\^t';Sl{a"UE؋GQQUԣ/b(N%6wbI5,XWeQs4+mLosbH8̬geCCCyR7_-H06|8	 *7z.AT8zv�^	tE+`Lu+~M=׵)A[T5m1YqRe(J47[P?igYRE9^vߖ'gOsSB@6FˢMJDz
    K΁֥;"be̘%?¥ ����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/ssl_intro_fig2.png��������������������������������������������������0000664�0001751�0001751�00000002270�10671421551�021730� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��������~Y���sRGB����gAMA��a��� cHRM��z&���������u0��`��:��pQ<���PLTE���i-���	pHYs����+��IDATxQ0<xPs�~i *3NY(|&t~˖2,꘥VY{~q~ڞYfe/t8<+@wX%2ڄј?OKqjxj"wz47	I�d@AD(V֚$Y]$�e69:{&!	 z:
    )q׃Ij^M9*Y~=_[7Q l"w,6sZ<]KQP	62P,]ˇ."sgKq>_ߏޚB%ҔASUmb2cxP^뭚APˍ7zpm
    ӐﱖF[Q֣$<]0Z>e -ﮪ+aU>0dMuA&v FF8k>kДMy[�ɨ5nN3o "(|Am0m~5n)%^޺ojrV,T
    8rM baJS-(emEFӑu<n\S H()]%}џ,v
    ,Ă#d5,2ˬbBo,2,2,2,z3KuW|9?`r6za!Y$6
    ůWUV]χ�!eD)_>ow,Գ:㊅e}keoX%VÚ[eaMo8`gYy:.}c	x kB2,2,2,2XSGdYfeYfeYfeY{dIIc:IcGuJ)Ne#)4Jf]d̽Xs:i,2,2,2,2˫?=2,2,2,2ۘ$S2,G{,rdYfeYfeYfeYfNW2,J)urd.����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/caching_fig1.gif����������������������������������������������������0000664�0001751�0001751�00000040203�10302702336�021260� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aX����  %&&+++&'(555469:::7894L(6H'>Y1;G>@B=CK4AQ,Fe3OpDDDEFHMMMNRXUUU]]]IOVIWhO^q]`eLb}ccdkkkgghimqoppssswxxIgLpSkPrOxQzLy~[xkefupXXYZ\`ycwkagfmkcou{tspx~vs{z~΄ێޔܜ֙ٞםܕڐх僳댴㊶댹킶㔹哻뜽䙾钾歼̤ͥԣ۫ҩ٢жƳʻĸȱСޯիڵͽĺ˳ҴۻѾԽٶߣ!�����,����X��	H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@
    JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿LÈ+^̸ǐ#KL˘3kg}K&
    &ͨSwB
    ɸ'Ei0٢o lѧܵOO`5cV.;cUpw-Md	R3F~ɌϭOWJ<}V[?\h`<d�	҄pxP	cgAO"\pAkT Bt>V BjcPߎ<Rq@I>
    @ h`mV ; c	 PF=e?bhLsA	<d9TעȦ1(gUP(dMV(S�!P O5C{eXwbS$dcB	!@�]h ť!(@�
    PA2Ǣ@J2Y(|
    z�h],f[S\Z뭏;\d�!2ĉ=��'mua"B�֑+V;
    p<JC0n
    (*>Td`s~'p2IӞqhXh2
    ,mɈ{S5UeƔa?[BpFd`߀c{c2n1AnQNa~S?Vd.(
    dH+ꮳ;^OGC^O;<n=So?_~~܃𻿾?;�hV�@,`x@2�
    (AF0t`jaGhA
    N%`WBr+!]XBNY' )H0ܠ}C7 {( *qMbh#NчA"Њ`LU�
    6pH:x̣> IBy;�&$"3JZRQ$%1Ijғ$(EYO&QSfT$Y	KN&air%-sa2%)ML]ǔe,	Lil6JƬ&5yq^t.pN<g-Jv'% 12o�JАH�l@
    ІfdC'JчpͨFOm E?Ғ6t&MRtt-}LvP6bt8MVLsSeuth=
    v*ԢFMfԅ=z>q{d~u&HԂ`u [u:Zt=޺z':1r}T1[HOvӦb-1zPtS@`@b:1vZ@M;֡Y³@zΣJ}>۹BKL9-2t #D(?w΂V
    -~@(Bjԭcg1)CB@h򥬼M`+Ow
    ~؃
    �@WT\~
    .~@H_ETBحf{"P @e<܁h(�`PE9"g[(KQpe/$@8.d<&9uf(DNPhNI.Y%tlǙ#1EC`'a
    GAm0?}:4$JQ. @=h@w-PǥA	>RLC8ĩK1%=tzckEþ-o(X9$DARر*܁&ςdֱ&o`h{[Yh#D1nC $ĀZpw65ŧ\;!в(NQ
    5�p<-8tWv]=衎qNo?�ۭw+AlT{>Jx.�.	BB'`<I,seނ!2GN41jc`#+*WQ_
    
    /OkBߋD}N<A*oXP@	Ao7Ԣ|ե>q!pD.&`hOW67~[JK}c
    \ 
    \[i~7-Fc̛
    fa7&
    0zv8~zgS3f6yK&^a'eKdox�tA'v|!!"ppCa~tp__EeOw9	`
    >G<Ѐ@ 
    DjlTUQdeWdփDzhofzqQ60b6S oC eSc9{F
    q'
    砄AS
     
    qӅ	々LVZt	c:}v jV
    ip@
    Cpx`*o C@\{eX5W^mphpH)qs#3wԖVqvo
    p
    0
    Hx|KF!!`p
    p`vO1cLdk6_4go6
    pjj0|t�`*)R	lP[6h_8]SVAx
    (	:K85`ȅ,TRt]Ń`u{
    6l]o	:, wWhiu]_L{PYq_z	( 	`C!_0y7[Q_D 
    gzjHDiըX_`P aczp0�	G׊x!!PI^S)WgW0B�eQw0tB(#t~KXaSc*MIE0]Gq}[M_Rh)u@
    ט?AVUW0h|Kp@	�gP1i8 `
    r@ӧ@Q^X_UwpVqXƙɧ x0F9QeWyh^GKwp	@wyzjY^8^R`ah
    @	Ç
    '"
    yy1\%wvkCvQ	X8l~Jإ
    P2
    svj7f?XNg`R`^7k(n‡(ixoIUhX5_OeeP	zE`*p	&W7HXp:
    >w(dJ
    oC 0
    ~dufyh"8|
    g2]_R&	l(#P
    �GЭ*qY@yev{	t0jڟъHDzȀDЋ4vYwR֛	`0zi"A[F7
    ^ss'w�rws'#[0
    pӹkxy�wqp@ZwP| J9=S-@yp3b%e<fwo`g[JZZUyɍ
    |�#XzنrkZ,*EG2)UEmd;ew"Hz@
    rKFI%Z߂@
    p@P	Ic_Uhs]񸂡s7Ȍ+
    +BԠaZ?r`
    PXy{Eع7Q-0
    kǻJ
    XXX>qzڳ*wcdQgsv_+L)
    |ɲ$e_h^cWv@q*xD	RY7]Z{`{#|yo+[
    $U3LP	c"Twk,qzfjpoQ
    xvk7Wsw^Qpu7e?kYquQɛ|)řnEqpvg[V5ixik-e\t[(
    ;aQY|U^3{sr�)Xiq7ܜ&v%
    xHq4<
    p9W\Vf%SZ:HA	fpR!	_B|ۮROp+`ϣw8)*O`&v
    f^6{IKGŘLtzqq]w婩Zb0{ I0	
    zNE@m{Cw	
    l
    u[\É�e4'Buύ,�XX9a}h7+l-IŒ{}:S`*79�ӹp&Y	:
    jP`KuH0^=ƪXi9GYFKZ	sF<YZ`ӸYM3EW	aƐmKUAF=W5Oyk+vIlqeb	|@~ǟ_׫3!i	E`yectퟮ#vxڡ
    P6V�	Js0O(.K5)vW|[[Ѿ@
    ԼFſD  jY QJƛ~{ׂq^pP߆ihm;
    MypB WLSpt 
    	<�iΖ W\qZK0gl![1[,qF׺RQVCPֻ])wTj\r0j\e~N/R aKn/e
    }>5	v^B|q`xQk
    sP/p%.ʧװ~pX}{fֵc!QWnҋImLՏ@
    r@uPZP_Bhsz?uXck^OokZ);�XJQu}ʉ h0{N&sH΀kQhǎ$O	xKЏ (7P
    v:XIO1_R=ߢm+0_i
    �h$5Ǥ{WO_~>t1C!^D;VFD鯢E_?yAb"B8hQ5ƔQ{'ÌNhSTUIaHYv̂jWj*);IRD.=p"
    ,*Z<yD;udLCjYQ"n|dʕ-�fNp
    LhңI&-4\T~k٭em;6ݢ,r5 8nАQ*&Sl1U][jm><wOW�˓B%F
    7pqcFr,M0-λR[vs@򦳭5zۭ;P
    䍴.OtOh!3:t0Aq3cM~65䱬H#1ӌ3(I'2J)'2K-<�PЁ"v8�.�-߄3N9s�`RNؠZhalܤ3QEeI;K)Vh:P3*@�K%TIK1UʐTrD+j\wW_9`wbkaxA`A%~/0-`
    *7\\UYq[\]qKpq6,B/j*#C]^
    y.w^v
    @qv{lA8baXdK+e׊2q5f`U59gwg:hs'a8Y""ȃ9F:kk}i)	G5Xk߆;n iiY41晽&p)BXP'r/w'"cR+<uWgݲjZz	s|Fuw=f@xG]M=yg~2y铿G[	<☤eI
    '3rA(ˇ?~e*ku}y/L7"݃6c<%:jD5i xV"A0�܌�M|sq!UYa+DC-#
    шG
    !'9$.- "a!ET\c:X0QJTUw<)"a
    =,j}G>c 	Ռ"PS^p1I4=A)	w$//K3e<Kcxc#AGd E$e˄ǥ:n1(2]1d&ѹN#M3I$-a@Pp
    Jv2
    P~"s:%{_@G
    
    |Q&E%zPe)p8H{$5:Ò+%:aN2 F ID-	*d!*9kIENC8!|4SUQ!abOpTc_KKE>	(|(E2qUyY5:=&wx
    $?p*"(!5t_cK9Ynvz83=HBV3d-p$@fGvy*mGȪe00!܁Ҹlw.wuu.{k'}uRbS.𖱴bE;1&ȁʈr]%_ձb|N@s50+[/[Hn>
    Z+:nrDԭVx
    qs9El9W0[J"aȘ73a8Os(<d#yrr,DbB.Npv,MtxFKeDxHA`5[ȗ,A6vrT=S%�h'3+0SyK\l:u	<$-jT*y7>0RBqBu2B;A8="8bP)d:6mB\q%nvI!
    `'Ue/u9?v*P7:+ܓ%Ä5hY#ݝ5M4mb7/1{8f#cR|2Lġ-Zjݔ#9\]h:3y|�7bվyef43ډnN0xI
    V+a"@
    >YǽUyT/an
    jU5S庳]u>99|%?j,ryg?AB4KrʏW<$넎ԉ^؟-!H=ax/|<}q>(
    +>~;}lׯ\yzL,<fZ֡:[ݑU
    B@9h?#*꣌~s7ۿ35m	>pC@59ܠs2BS@R.F@;Iˇ('oRd-Q[D<f#lҼ;Xx3;G+:KBBo !xLs3A@Z\,[/0$} Rz:'l>c"?ߺ[&'@j1:>˓r`:"gLC+>	?VA6ԠCԨMɊ<DT3cDƉB;9b@5"hؓ3kZT	U_Ads@1D$3Eb|7䟥{Ba%TLdCIK<@AtBK=P-ic
    *ʃU?n,EdGF!xK_$c7>Gwƒ\ ,F=}t~$8':MS?FTȘɇd4$xoǯjFﲿQ-dǓly<˜TSGbOLCEbFa$F4r.&x^87ICA+ɢd~]FbJtLHt"zCsxIlJ5$ɡ$[:%J$g~+IMlpzƒPsdļ2ʡJu2& U LG!ZGa!XL
    :4T	գ%xwK4dn<+lwr!DC
    FR̶Kqd"HTpIL$CL*&(JTْ/v3O޼@PZH<GDOaE(4^ AvKa$+(`-G,DN\L!d9B44"ܰeXШP!+LMB5L͔֋p8vQ]y<-M~KQDR̩.(V2R<
    RaR#M1yȈ.,<.ݜه`CeC=FP(#QOm0]8G]}F"J$TћB{
    7_8kjPKBM\ӷD"W>/US]+$PJmOM]~K+S6UQSnU-hI-Tݳ4/\T)Lu`="HV8
    J3RV8Lg]q1zDV{|##+,VJ4&{.D%ZX\%XTXW/ClցNΕBXEdS+[_-YiOx<PmlUYrW}H=9؏%EMo!PHʝfҙ{(E^՝}s˰ٜ(�@_hU YVYYLmڟ4~zϘBX֑,O'(n?M,+RmNN(0nXWo[#!?((ps[ge)]$>ЅyX,\+PXl~_U	<
    /CQж][(!l5#w]9"0@0t\ut⳪?LvUs]XFm
    50ܴuU{X.j0߂51?7sZM( =4:]?О_ _QkRe[w)`=6%5@Eu-mx\bl
    `%^Aul[-u.+//M@uW)xsbbq0](xxc[y|42�wYUq#aF226.Ѐ-Hy
    �(e@�zw؂i)O9v@n@5)؆-�0-e23�,X�9lQ	cc(8QeP�2.wP~(�4؂zg3-y 3(VL^y!nߡV2(�2w8
    P f�cP
     *@5P2Pf0c�.Ї3Ѐx@Xj�j( N3
    `
    
    .c�.x�52P,Wֿ+@H0ǃ]f}xz P�
    (gm.�eЇi(e0@�bR�ˀ20
    02�g0��PxXk10Ԅj#deaF-mBP͞1K.L^4f}�@4~iނ.@�kl*h肐il&d5@2@c(j@�5ˎ:3Zk%t`aI>j-.:wc60zЀKJ3}j@de0�
    xvi?~jZO`'ЄvXoJmf8*:.�4+�
    (}Ȁ5�*Ȁ0*�+ #i0QȀ?#z�flyp 3>?ɇb�}q$NX&~bq~H
    AW	y@A'4G @?El	S4|}qql$b"�_;c
    \˾{kPWL7'ɹOO�^oZ8CD$>Wչ+Y0SwvpnG+3]fOs-Zh�C4RHϟțɛ�!!mnVoM/,?P	뇥v)hk󸃱wWZ
    (�y#׀d8@�+	jHr")
    yj(i(c5؂-+8w w`iL."ifZb_x ߔO-Ȁ~0
    0pG�jP5~i20j�WX3 y4(w(n(zPtP(>~ȀTgedQ@h{acҿ{|g~ nPȀȝ~0{+�Ȁ2fWx0�p
    ؂8 ~5��24�Xw1u!m^}V�(hP1
    2lp!b$!ƌ7r#Ȑ"GI-Åh%3̅~W&!f,<D$"1jnjR.Rad(/Ywj*a?iH\\QY
    /
    0x0~lI!gȒ'SܱJ54c;Vq2  .C1hோi1ށ[ZOy|A"2z�vXVPQmELu/2/H0�vdInIH#X	IUӏUXQ2UQFwlQ1e*saUVO2TQtT0ƀijɔQ5bӏʀ^%c^9$_|ď7@!D%a:fbT~hɑ2L&&aTʷ?�E3g
    
    ^Ts(24%|wO1},8)a&`vMz*&)IE|22i>2,˟ٵ-D5:	ː4P<%`µSA�@)Ԧ+Y:R>Q .}4`[asAA+lWUCxWHSAxqjP<	25nHDx2?)zqeQ�@�IkIKbJ[I
    X@P'_zj~5+SN'BHm)WI<`BM護<{w{^x;9?S.y]wIsYgM1.>F'f�;;?<<Ӯ@v;!<O]P4?>>髿`v]R;LA{3_+`V< 2| #'HR`B!r/@j �@EB, 8CBuCHԡ%(^3:U
    mI(HC#.|Gγu͏$
    sl_ЀQPW^
    bKgUEoAR;F0$5Fq$T��pVq	10(bh*c1p pJB(A
    GM)DH!Րe92#A*(a
    /{y(/b^3̏#ßy>jRd7
    5͎P:¹}X2Å
    v^Kc	/qr$vXl(GQ8t#(''wLVC
    T]8H>"iS$
    3VI6{b
    E.vMt!TT#�B?2c3ꤦf%BUCY"+{wpb^@TrEVNYwaEE<xW8a&@Yk>d0zQ*V2D+K'+-!ɇ:
    ` SkMKi0!mPvyYF="I>@F2k5V}B*uùa­Qj]@CSF	CMTsKb=>$T}n^O~p}}cޛ27NҺ몕0IYB/G)ApSx$͇-`h=")z[p !--My=a#�E	tRȔLd`8$d1/if<d0f\ؤUGۖPY0Pq<*ЋOHAaAg�KR:0_(iYYLc
    N͔&08;hqqk̺ϯrGf`%&
    s ;+Yvmغ#X)�m?yNj}'KaVERֆ0mevDümߺ*}8ƻ!w[AfKi❵Gq[
    srsex&6n'Sk$/͸/\><ڠM#6͗('.
    z$5=0W!1σ=]AzG<֮c.D6l,+zY�[N	#کTwDjj>#Ж1Q~
    F(d
    |_CB";td8 h_V!kLa`?Q~9bco?lyי~Gx911pC0~aAm=F8t>'oUS0ET-C>`1-?C
    2?pC:C0؂EC-GC}I]^�C샞(D0k:`=Y0;'bD?*?-:x&ÑCXM`C1E~1>+B܂8:ܡB'(`'Db8|
    aDb` `aɠhRZTK.T1BC-:C''܂%
    ʎr"(?@b =8:�DUA"xы/=|B0=p!(=`>"v5b8C 7t=`:%='>(`>C<bcC/K )=-%҂rcCƠ=B:-8P`Q&0B:MK#UQZoemGcHiT[=HΐH
    U^)ĕ,C=I
    >ZW⑞/?YLYV>iP-!%yE5T;
    `Z[8NlΉWDdF%J"b?DZfkZBlbDZf@.D{m!kN^5_cסY90zUZNmgF̑HUC &fyCD;'yf;&c'{u^/Zy>ݫ~n{W%sB:V6~/mREp}h{M]f|b%mޓΌb
    F|Z F+b2rSl&CD4-B!.PMEIPi]eTO/@)?-CIiCi;)[iC{1AITYEu9B驑(L2ix6XI:A䞤>USFCe}*jCbYUL6̥V�b*JxÐ-yJAYBh%y
    &:�B:?Qfi'j{z)nӽ<kƩ2%b hT,8"bkjU(BLJY뿆S],,# kΨ:=SNlŠ8]ټL2[	 CcB뼶jݫlbB&ޚkzS2,Af-&lMg�zӹ-%ʖ0tƭ6!ޢl)F0jl-UΩ~lqJ-Vn8*!tFbI[E&f-6Ȑ\1lz|0.H,*WkJL/(6
    e>k6RLn*?8 n6%Jm%Vk=Rm~2źlB-'ԝo4z]Zۂ
    lѾ=HD8,V.b/_APFYɯ=l<<6�:1'/17?1GO1WW1T1C/0q'q7q11q_EH1 2/H4�h@	$r	p�P�x"O2%W%_2&g&o2'w'2(((�@E"�)r+/+r'2)+_-/20%	dJ4t]�3;3|4a<4G34O54k5W36{6gsAl8w379388�99:G 83<23s >3@s;33s5Ss:<t<:/;4E7tEKC<G6�!SYѲH4II4JJ4KK4LǴL4MO��24OO4PP5QQu�x1Q7S?5TGTO5UW5I'uNN[5WwW5XXK5V'S5ZZ5[XuIl[5]׵]5^OR4J`y�va``vbn`#6cC6bb6c/cudvcOcg'hSvcodw6h[e+6dck{j{6lvkg6e`vfo6ovoK6pWd7qmli'r6n6pOhc6lvmSa6kvtc7j{v_m_wtxvuv_w<P4P|ӷ}K|7}w}׷~78wx~~۷3x#xwgx'8?k8G8/8xC7xsx'xxxCxw88K9{[8xOy;#y
    999ǹ9׹9繞9V@��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_filter_old.gif��������������������������������������������������0000664�0001751�0001751�00000002316�10147723030�021744� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�6�����,�����6�ڋ޼H扦ʶL
    x.@Ҙx"jScd[OU!_U%&hF->Qf6Gw8EǸ6V8(h(Iy1h))JyTDƚ,<L\l||:
    6k
    ݽ#-^n~C.?O_oO_0 }7,X	…sh 'Zq^8~1ȑ@4%ɕ,[:s	4kڼ3jTI
    20
    iGJ]45u)+V-	̪ӬX=S(Te%+EAc/IL^݆ɔ*UFuw)A{&`9b!-,LbTEHNf~%,'`j}]}>nTf>ۻgmn?f<&9ԫ[P䃖~Ut_}r_?=g
    H`s\n" d҅ n7.z!tJvkbUAYtv"q9Ȉ֚-"$θ&ո!hg4tIwe`XMiLEHIeyH#lBd`㚈0!%:q4'*bNg`_ʓ&:袒NLX*ni
    J8Zj:*r(w~z\	jPeR6Ⱥ+1vGlM,ڈm}#yȏ}K%\r~2r^B$.fAص7kֲͶȞ	,3{Oќ
    +q qR"*lL—r2B4̳r/sB]/?t's2MgU F5?!嚣9]uaMI^si6chӎJwqm6i7;mtK"rwH&-橱ylgc6Y+ŷIyq!fr{;C[biQ?B/>{/JɹG-2]>*;LOn8{`#C}~ax2h۽67Oؿpnc�r@$J15,Tm"-S/jp*��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_rewrite_fig1.gif������������������������������������������������0000664�0001751�0001751�00000006705�10147723030�022216� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a���������,�����ڋ޼H扦ʶL
    ĢL*̦	JԪjܮN
    (8HXhx)9IYiy	� jGzږ
    +;K[k{;ؚL\l|7-]Bm
    -^@n/?ONmߝ0<8-TᴇrJ9i#vבG[(6^_$7LFV`ִyg![^<s5frJ4
    ?6HS,Dj"Ҫ[vz)A>$["km)u{큺bM@50ֻ0w᷂dW"iqaG.3vNxb9!֬u\NyƔu88ɗ7E͸c.6eТ"YxRi7Ԫ{e9|ʡd΃l!yfkXVpY69Rzީg^e(^p@
    fDl8{gX-ƈo&\Z:bv"QuٵEbSgyXq}d_PZne^~	fbIff)h暽f.py˜tb睳g,|f_JhG�>(.h0ioT
    .c|
    **"�\|6jƭꫢN3V룰JJl3Tˌ=笶F.n>.C\o&
    
    o
    pLp<r:0}1<J19\kR|1. r"L
    ,ùk<3q
    ‹A
    §"#tж\Lэ-{jNr"PT"[O|&bԿzq#r4m368a'2	}7w!p8~H^!MhT.~韫k 5밟.|n{蹻;oo>s7!>o=gF/gx/~ᗯ觩`ǟ[دC¿*B�"
    \@,@0,lR�>(t FHl
    [R"P%@^H򘟐@.# ,:$*s,qTLbC<	Ub
    [B,(z+Z�hE2b>BaXŏGa҇x$;Lz);f	d`ʢ(d"'g+�]HZ�dA46$mʷҒLk6tHukiCrԈ44z:9PV2&4]I9@/zRlg;tj(zLBrĦ>C3T@V6Wf`D:'H@le(xK
    iy{F)b<ʀڈ3
    ACJ!wj?=I HIQQ8"NMKU>t@MpRE#qwrȠ4Tj#tғB)c5cBGIDźL䰭K#$%N6Ȏ=jRal�JA;+
    &h*eB [ϞI¬H[&^�DP\k5�ad~IKo+vRq!7K˕oz,5Hui\]\ٝvF]Z껻.ț\!7 u
    v[/�x<�+Xz|a88`roeKJn 1<şP2
    Ş1h	Ʈб1x
    7
    ǜ2؈	#&p$
    %ʍl#YR#d�n9];di̘(5+932/;?�Fc%|b=3S썳[p<V'WgL@_�Q\z}ZLpquP"2K]4Mli(ښ|%KaO(GP?5XN1Q"c_sжm#<;m$ض!\1WTd
    H!I8t+Qs~Ma#~N2,(pJ\f/v?e33ݷtS	{V3P
    ~L.zSHy*U;oMcy>c>=&NU6(ĩThD)Q>Ɏ-zOXt5)iqV)ABqq>nf׫~/dWureMhG$^u|[
    N3̲'k=t{w?>h{*kgTԋ>}ex>нOރ͟iOgv?o	?7G_
    6(@`J 2ӀB9-G7f7+",Fr!*8!X6(x.d+#XW‚z?3v#'rF�IC6?ȁ+
    C893/4X+o\7
    E38KӅql|3<F3g*؆,i†:vx#e3&#jHgBqs+un|XHZwÃa;c6Vh!`�(5Ycch{,1ȉY_h5wcC貄81Hs8R (AЌQ [;hۘ_*\?0ሎ騎@03] ^)Iii~8yr�zvsIYpiIVii?v7!mlm6PjxgX eC->w0&Gl$ɑCtA(9@yl:)iGUin	REvyRiB"JxboRbqXV钥xPnPN�E%hsaEBɕ+;xIuٖԴ?"Mt1vA)x`PqL'WNi_	uqɗGk`v3R7P{PetTy9n<GUٚ|~
    +՗x65L"rsTJyvW5eSwYz	Noŝ	uExxN5OxxhIRbAoɖOzIsiUwAiztva	
    *JjZɡ"*#J%=jP+/
    1Z&(*-@58;ʣ=:&7F1EjG
    @irբMP*SJUjWY[ʥ]W��;�����������������������������������������������������������httpd-2.4.64/docs/manual/images/apache_header.gif���������������������������������������������������0000664�0001751�0001751�00000007764�10147723030�021527� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aX>��������1��1�1�9))!J�R�{�Z1�R�){�!kR�kcBB1�RJ�J{�Jk�kRRRccc{{{�1��1���)�!�9�cc�{�B�c��B�B�k�k�����R�)�R�{�����ƭ������!�����,����X>��pH,Ȥrl:ШtJZجvzC
    xL.znp~>>B==?UbI=?P>�=
    
    B=b>L��I$	
    *#DM�k=$#	.xz1Jw#JHqHY
    P P#<<	Jp81`_[6DrUɳG  Q{}J@Qc	2L5_d2'ϳhӪ5�+TU�R4p'j8Q`9,B6G`v˘33{È(0*ÀOW`k	ȱchsS!!7'S+^8Hw@TY"=c:"`C'p'OM J%=eBT6ܠ
    07� dc߈$`�X	Fm:a(PB|hN|&F)lXt Mh	h%d`	`n;8CDF0
    pʰd1@�.G埀j&e	0@`Ha=pF`$2@�1��xd.	꫰
    	Ѐ*A5b6U
    `	h:�i7*z.'�!B+qP`��	`HvU<iې6xG$3T(jn_98z5+bo(p�Q�th@0iP�=FB{C6@ꜥ
    {&"L7@ ,I#RhY~bUSɆ3	G*1
    p.)C6 8@�hӌ7I*@@g$\ְ�jOe0@&&K04
    )w2@@7tA@g7t7(zͨ!J#0xztqkSaTZj8L0!qz:7w7@ t/<D@|!
    Q<GEpttmktXE090(}'`4v67nC>
    T
    lTEIG/�ɀ@@dJ�(Kh�$0<˙JPU-7{wxpk*r],M`a,%�
    5x% E*T)jlĒӑ�p0	_
    ^W7`z]"0	ClA@8G-1f 
    hk@hcF5a3$hyP^/ZϊX	 o4G^iɠw9f@v,A BeI \LPP
    p3M4GI	Au#TOЅE$Hhu4ͱ(\
    @@"q(À
    6
    ͎UE-pC
    vR>3`nkhƦ9`
    J0M賂�5\p �#Z1ǣ˚MJУ`HbgΝ@w3mB7xdǦl``)PǻvJ@y�*_񨩜`RBXQh:F΃a+oz,JSH<<РGNdvmk9"P�ˊ5vFp	Iѭ>B&:A�!n|Q0jN[zz@Fjt0gL8αwc>,HAc @tU6	ɹX6ʁj~% ?7<mt@zj6gçC,bsI�E=γ>πg
    h�ZЂ<A6'մxҹ\`:8^c��/pf̃͟}fa`Z0$ހvMb.Z~4n
    hGn1RN5Jݶttf~4̊�KkHj*Z\@Y[Oc"G;Ҋn@`v:d;.ٍr ~Au<3fF ccٰ^ĥ$<q@TPg3HOҗ B
    *L"0X"1Y�g036k3X˫0;5:d�'ўJ]@xћ;?HK<AAP�e��J^ZQ:hfMi5az80;ʹP2�{(zȶ;Џ
    px{b3'j�TH�8X
    !-Sa) hXBgx(::%5!
    F'}XxMg+�`�
    �PuhmC 3Q1'oS)dvT/Gn&&=sMa	hKM!
    Cg}Z\lCy `u)�hͦ�lOWu1A!v\,s07Y(PTA:Xt\8 s&pM>WP|^k^�b�p%ׅ؉2"��)�l
     mOhUhu,Mub@x{dk|8V%(w(p�ȥ #!%�#0v؍4�
    cBh,W6mCfn9H9!VTa FhA+?� Z2 �1`9I_y� �s`FXLqD֓d`2
    ň*i=
    ,<+X>@�0M�s�6&�s$yD={a2K$t.fyh=)�Eu�� �Er	��`[ ��T/\KP$y�]%�p;1!!1!9P7iyF'T�R63 Fdm134o(Qk9=#&©opd!�;FA!"	]wi铫Y7;@NDbQw?|RX"iGR�|@Ӝ1shz6yX؝ڠX]'$!-j2�V�@{-@/Bș-�j::4ӥN
    '剞>ec^�fv42X,ğgLT*)"[j5`|rBN$9fj
    ^뉛!o=bdQw$L
    rPUTzZԉbZ7y$Bo$#:(Su	4Y MyvW0Z󪯺::l9oʣ!c]T~7	q|b0ɜXJZֺpvB7&j�Z�0;Q
    cfn7�穮V�TS
    9ɀ+'-
    *S5�ˑ  p{{B#Nrbiz.v^y-#6ju,۲7`c>jz*mb\Ĭ�>kDḰ;[GPR.[V{XZ\۵^`b;d[f{hjl۶nA��;������������httpd-2.4.64/docs/manual/images/down.gif������������������������������������������������������������0000664�0001751�0001751�00000000070�10147723030�017724� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�����s!�����,�������h.z޼��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/bal-man.png���������������������������������������������������������0000664�0001751�0001751�00000763705�12663316405�020341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�������\c���sRGB����	pHYs��%��%IR$��iTXtXML:com.adobe.xmp�����<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.4.0">
       <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
          <rdf:Description rdf:about=""
                xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
             <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
             <tiff:Compression>5</tiff:Compression>
             <tiff:Orientation>1</tiff:Orientation>
             <tiff:PhotometricInterpretation>2</tiff:PhotometricInterpretation>
          </rdf:Description>
       </rdf:RDF>
    </x:xmpmeta>
    Ү$��@�IDATx|^u}nRԢ%yʖm{'G|rMw6IMf4Ij'vl{'dC[ޛwxx(>e�8�.n}X__&ɐhC,,@[[wow{BaZ o2OwEwEf+:dTTs/WT~o]'>Ollr葍$`Z+N.))I444ܯ*hmm+-/;+X X X X X X X X X X X X X XP<Z[['?~ānnn{.jȂhS<>~tְrhP````````````Ryi'qi
    xX}
    =lk4xb@@@@@@@@@@@imi;]`d
    m휮鞵�v!X X X X X X X X X X@'''~yyyog}5:,@կ:bBpO	:W,YAou߆Cqj1!'(;ʋ`C8-NՓ#E(RXXT5&NGNd鯦9w3m樞pq$ɭҾwusqnpď9"v9Pw8Xii0@wʁ!X X X X X X X X X Xୱ@b1K0'\6V	~4w9x^IvIc,Ԝ`+KзIs[&uz	ÂBsd,*HYYYouW}q0`p
    M&|ps!teK:?Uܮٗ#M&xdI~#G:GhM	!X XiLr68ڧZV	DNl{]vvjG$I:'Ooi9Z_TO\GC[~57Hz"R>Rpu	:ruekvihW„/'J2uԓ[3
    <+Mf˖-r18qȰH\~q!2
    7h=~Y:y>^*zGq[rQ}*yQc4εQqu!7#Ǐ?.۷o͛7eԨQ|`Ht;w W7VK'Mk%g\関b>GjV*+8'9
    Cy)B
    6շ^,~\-DAir5$>I$?/_ZZeɡW#/:iZr<F[>:餫u;e$VYm\ns<L߿sqvgt�Y8809J=k|qtOl쓎G}|O:-f^sBƏa{n!t;v$=^m?bIqKH <7砻?{wJͰr_q:pb<uKKIt)QVmCߑQW@VvAf%jLL8:ihMȵ?]ƨc:Ώ9@8͛'zr¡97)&&D2K[><S:Uy?p	QRɋLFdK#ñ8/ƥWN'O,oQ,ѣxbӧTVVvz~WOb[EI߻^UDwK*
    'IDW
    {UjVw?-$y(=!N;
    ^_}_!mÓ[=p$dn=ijiV]_a[+!hO֎SMn|~RUUsNkQD({vT(y&O�
    pDT|K[O4̮._<
    /|pt2bh-һwo۷]|Hv!,,,,,,,,,,uĞΠp)۱IDF}w=]]V']aCFH7VH΋e4kk7}߼WS_Zιݪ#�e֢Dē.W$O9=V[~|,-\.3gHus4M
    ]yrw3rEBTN<zۑspFpy/wϞ=2k,wpS3G	VTr?m<|#DZN35XO"3\?on|^~:4Lu6\_89`><y&׋IA	[ܷnuVփn
    q@@@@@@@@@-렫Ǡp*q>+z֬[a/(=Zp6Tq^WkbhOswqp*:MZ&s:T53~"!mJ8`I}k/
    RT,+”v'P'~JqPxD,5Nاӆegtdc]
    
    M*eƃt4g#DFwFu*ԌZX7>/K<:+prC
    Q&h)3i9+cǎu;Hx/C]n<6tG_s|NВWX<5s8ɼD&NI`9\jǷ9!#FHqq;駳)'Ӗo7/ׁ?),,'!
    f`�<Fbu0W;}#lNbҔkih[ʌƇ[Lf\ΧI>OopbW8o)>-بgN�Gh0T=߂!n6φp-'UY7eGbÉ
    gMW̗
    x\Y0_Fwqlh'#7oq*8OaqQ[-塚'ۇiOqe
    /ņ8O&X<G`ql4:}+t>y(>
    iOGR}K[Gղ8^q⟎O\AZC>Fcϯ+icqWx4M.|VOM
    b,.mLϏZy:qƟT4><9B:xnOj�hFu[I䘃Ӟvy=%sfJxoL"s}s^bTTWqu+Kiukm:W$^TIARWU,_q8ymtN	p߁3<Ae>Fyb-gIRڨY#6Kʱ#z@w8c%)FHps#(O=Q]q˦&5=rPThTONjK)}4?nGާ1O<d͝=zAI'8;~f&S:N(E<32aqntq6<]'^\Y0_Fwqlh'#[7Zĥ}X6.o留V
    b܇i_fidEˣy!SFg1x~GQ
    ny?m8t:txQ:4pe>t⟎O:u6Jg
    mcqΩŇliITVNl8[V)Dqdorb[l-:XVKIqR7pWIuh\fSkL9Cwu9“rrh7<!֤!C2{. giZkݪZQ+o(*ëꢣrN 9R&\һTV5=%dXuCG\^VYg+3ɳ<88}<GϻLqt
    ޭPu"(d~\z:	)qyh\Y8o48xj䄶u^s~C+̉cB@_Q`Puܶvz\te2O4Eyvys1⋤Yq]yC]w@UQ$=Du�jb9@	(6ijo<~mᷟOR$iHn#m4>p~^Qf̘&خfCv0:Wr\A/c2�gqU:uk3݄8X X X X X X X X X=hxC u09z5RwՍƙ	G29rieMz΅;Jvrlooձ?[I1F9Z:GFuǗWW?.ZEy7;N▗dw}+Y5p~p*>f⌣bN|}7x)3<ҕq�ѽ[䡧G2v@<v=/"ʊtIy{BdRgX'UrZZKWZA貲RuY)XM):n%\cHYik?^}i"Vq(}Vyrycĝ)a,h::٠[3~e+87<O(|յcU*Hz8ɃZNg:yPQM17AQ^MZ$'�p[uoc;>.~҂k!Z<
    c[-[
    6''Nt'ꫮNZ̗ӗ|^\69y"HEEcL|xX@@@@@@@@tuT=KKm/Ԍ$GA&M֕V])y#V6D
    si?DW_3q98DyT]j^'9XE/HHoY�SĚ6_-}L,}rHP'
    NƉd؊!i8}GcqF6:bׇ~T~G-yUɳΓ/P҉c{o:Y5ygQ+/2D'ٲZ'7xȮ̋뮸P <T-*2\Glރ}@6ȃFV練oUΙ1
    JO/y&ʠBٴaʿ<X#/=HҦ}WEs'ȒE˲
    WI,?j$tB+L
    +^{D
    v\rf
    +fVʢVλLbQ?9:Fny2y?
    %wV;"yE.inaݻϟ/&Mo`M>Y۵kVmr~6D5!X X X X X X X X Xj:Q[S;=FJJy5VͺAˀ5V+뚈eKE_.†nUұܻR/.R/}k{
    ǺIuEʊKdZdذY:710B&(%3oNiWkv	GF⒏2+sd
    f|@_Mؾe/-7T':̻2Jɨahmo)o|9]?߽<Zn;yHʼ<.cG7G%Fg>ay_xA:._s@ɺŏ]w',&X-^9>n,-Zt v*dʕ2܉C]f6[O>ɨ៕o(ۚg˗?z<t_k-om}EqGOd峇wrt({~\/@*ş]<_?J:6m洕槭܏Q8<8[Y%YgG1N	gԘOoi0Q-8+w?
    !
    ;=D>[B&D	w1:76dϤ;nŬγYDa4+
    |x6iJp90nl2lD7u8id]CSQ8l97&r~,3|b7<+\'
    E{MyȀR슋drreݲA]_ue=orv}soJH?sSKtsfJj[U-Y,[M7 
    K9vo#dMrqkn=Ȝ/:W/jlM
    2nY2_z'0Z>&9[{3Ϛ%wnUzx7H	{ݓ%pr쩲c:?tTuoHYr㵗>/}Mo/lC5-vMݘwA7fN"\)#Ku~OzS�/J:`C2Y7uo9rߜNOG\LT7&5:/\;!@Ydn,,,,,,,,,n43`vAӚI:ຂa`i8gSyGm8{-!=#p)ס+JmXg$(W4㼰5f+qe3\~:<,}LPӬٰ믗!u9䟾MyQ}{:[Uk~Aq/<T4EUS&n@(LJsc4s+~:QkY[[,g=@EC/g͑~{lR<uL[L6XRf@*zͺNԣ$h+˗K^e+].͇tŸɵcK4ݫG'
    &}
    M"*K[qM�M88\מं_nib3^qTU
    2m03gt@`s:ya?lbpqY4hPG	ͮyNv<snI,=gwUROweC_MK]Gyf*|O}NMWdj[g#/z䊟
    ٧BF\}r8vٹ:IOOcWA~:2hבuMqI}u|N2
    E:Rϯu)sb:
    =Y$+"	Œ^}9>4sfI|Z'Vٸ5YR9:H]P=-@^޴Mo<$Y/Тs۷H)KRٳi6WVkU,N~ߵc}Rλ}˳%˴ֺSy2iT:C0@=y=oNvo>
    r˟M^_Cmwi=R#$;wˊ[`nɉ&։ˑ<<B6o^{#\%cV-_[?c˄DL!+_zYwJEqXR.BW;c~8Y5jHdewq+++AmlQ}_7q#p\'>M4MoiB-|W%7н]6ش]|g(_TtEƩu6rG-Ω}*d7*79`o]+MC~?Z&ĝ-p"#‰8%wb%ÇFOܧ5	]8|QW1w3cf9TW}@}U /D69e˜Q`!c6Yiֽ2z2U[ط̽>r$Z]=e̙=SjvoW^[%cuKdqRtXóO224alnjb=EߑO^'Ž\)3λBDcK3=`M-zAeޙRu-TǯbH:TiEdYxpsgOɓ'J^%yfiUBG.]xGe͆]2e愑z"F}^k(,UvO"q
    48eVӷg4>KS{l߱csmgDcz~4|S`[]&	xZ ⷅc
    m۶o>/\t͉1gAYy[,k<~un{|B,?_xN}:`f|eՓ>:SonO)>kd>V~MYf0~+*C9;_uQYJ|[骋6e	̚ҩN^IzdNW	&�BT8Z#{;Ɗ2w`YCR1}/~=˧ۦU
    Ż!Dg4ouLǎ|ݾgm׋;:[K%#>8zչP0lxZJFW?p&DqS,4XIT	~5UaBVgT|h)9euȔYߜ5&8Z[ձeb	L]-yfF:ڃtmq][2).Cwo /[%u2h89ҷT't@8^*?*u;t~ <D}*xeǵ/vL6CZjOB赫᥋G:?th{> DT!]]	LtWeTͻ˧gO1~\功I~.BMO=5V]t:ʲg;ou%Pt8t舣	j5f9V8#3s۝t>p	l
    Frp;~NjU{&r&(|>'x9=S+k4^!mpm3�/`ihnph])+mꤏ0CNoݷpC~X|+L^|a1pQ_|<|:㕫8ȉ8~O;v<Ig<pO-0!/sŏg?LrOOO9l^o7?t+2{&zJ~w_&L]>ݥ7={*/WLs)?Ol|葍pNztWҧTo~:(NsYۼys+**j:[`'5~4*n<
    b-(/ʃ2`>LB)Lߞw�TBƇncc0p91Dp<Ӄ
    ?
    @Yl47<b
    2<fE}yGq4q8.ak;'rq+6ab|B,,,,,,,,,,9;cS'axC留_'ӝagrt	2<#6|`0:M'}D_a$&,fiKނ<p}>!(=pf¥V?OۛCi}y8O}Y0k8\ӓ6y*Gq̟|IwVCee۶JNpmtјrKlcgwheGgzEM-O#$4Qh>S68ЁGL?xe~ga~ڧ48e>TiMo4iǕbS3ӥ}[le<U~ڧOq,t~ljKgT3
    y&]#Qh-KIKWf2|3bNRѥ;!1|]b2gbqdŕeקF,WKEO*]T0_iB;lLQ8}84Xbc&yhb5V7l K/}~leFc
    �qNUT|/IeTwmߢ/u~Ω-rMƎd u$֮]{(=`3{88z;}~
    s8,F:3CC0>>0G1Z@Q\+Gaˎd
    Qy}T7ंSfp,|8EaÏ3Ćkx>42<4p]v	q-qfCv<:,xߓ:`.?p#ƍi`q0<Sw|\k1ep(|Stͥn'PN;ȟ\xtz)IYgFpkjj[38PO````````l޵/^uY#p8_~Ρqg;e~G!
    DQ:Q\1^τKKKY\$/ׁ|n*xn|
    ޯG:*d].򌦻uuM'+<p3=V)yt@@@@@@@@�{}̘8vXFzna8|fxK%xSM#|:?sd\htrު\l:jy%k.rhy=o'[4{"�[{JqN7!&S]Sv{>{N7}c[:+8Wq²)?s.=U緣NoLB'[ -((HE\p3x*'0ZgQsŁ4/ӇʼnM?
    ntˈE[lp_R.DU2[)7]]0_h:No1^'6XTmMɤ`S)J'4|q`bzg8~OpE/?6^7GetFcϧ|lTk,O?XoI[lQÏ
    xX>]l|a><o~3Z_p|FO,aph<sk2M/`>tIUnQʍ>,6<ѧ+7i2n~n:8^q0x<+GTrf6T}x/|L&iQz*4f|
    xdMҾLҩ&#Sgz4VNWn0ʡ,U?Sw/+có27y
    F3:1#ãe
    ޜ	bNpe0�Tnti}ކ%X}AQ'Ugbp:|~&ǗmeFK[ljO	``]sv}FHfQɆo8(Oc>[6)[p,OY\0ZN*o|h5|m3}\?ōY>\pR23O,m&3&`qC6?<Cczg3E&Qz
    f8\p&?Zfy<M8<pnxq0p>ܧ1Y>Nh|~iÉ7X#6<FnxftQ~OǏr1<S|<?-.xaqǍ+7<?1H%>$m
    `�܇yIbg|#x:1Ǐ}zFce>M&,ie>7R5[Y,Gڤ2[q\Y.0i4>o+3X:+a%綸/4A"oLGsso8|KKK'y9?*i@	8x׷SnOiPדMhOHBʣ0ҵ1>
    t8=/,+˶S\W	u͵O
    N.ϖ_xq)~K˖_xqrN]	mŋպ+6NF6l`xqLhWΩ<1Aa[
    UWdgjp	q6Nݻcݘ"y_89ß6wyy8lODgx%et18O@@@@@-`ϫQ>^82AQ[3xY\Sxe7~s1Z.Nx)!__dIor(}Kr?opp-ű<q*J
    7Uޗgi!ot~Y,קtd7\_Fd[9i3)`e`~8zO`x>`p'Jkt81(O_n05:3+wdwЭ<6#cdppy
    f-X/<A7Ôpf41ݯwΈqqu"@d2dWquS0JZwZ4݃X;H
    x,N0A:ofVrbϞ='GUH8;vp"s6hf@HeӦMɧIGl-3gkx.[]wj~,3#;|4}:9较mdpqرc݀Utsz
    0ᇣΏ׬Yٳgw|s<%Q�gH<YܳʌDtx3:+rxWމ+VЧ]fQc4¬A
    F5>38]}FOler(Oc`Qq(M<
    g8\xx<`Q>6e"7+pYņc2yFH|X+7J4ӐQz+1Gv8>lV\}QCMݻcǗBs<[lI&ɨQcmcdQ8=u˗m8!t<_3+ax7J
    =Гm{}=i�w7Ϝw$"‡$6"$&)�/FN<绛VԷzUV늾=3ѓRҠ[�_T2`r3=|޹]OglT~O6RU3c}v3fsBH#8?'}̙ꫯ-Ǐϩ, vA߿#dЂS=[d3rymVyeFO+O'Iw-kPSixe]Hz$J.	$>Xf381660YDLrdp
    -	cy~7+|:ZN cK4[tG4gm1YȷWeSf2zAVwx=lzR-(0cg}hL+/gˋ
    R񈃣?qxQ^Vf3>~bm65Sssc;zXjӪ齕f:sУ�5;vlGFǍ1KqztΟ:uͥ2R*G_Qֳbao 8X X X X{^}{|._C?2ݯtp�k>ZtuqVi/0M
    
    "$Y^ZBQyTiOGˢ2GCeh_ɵv_&***2:&ntv(N<+5,J\\]
    u׫38ɣs6NLGI'$2}&_K
    r?mGq2ilo&q\@spM<3~ʁ[p^>veQ/^grxk*/m-격׹;YGUT0;wgyՕU.m
    ;ᬳΒ3<ӽ̃a>cz[-
    &}Tih{Jo(V[^.7꘡T?Қ/h?I%与7#:t2i81|hrA4f̘80*FҠ<,]T>OɄ	QGE@]cUۧM֡^vاX>/%m
    >IG6֕ΚON듥.cRo(IC%=TIDEB``w?ؽiyT5{у{Ɇ1i&<>[RC&׳VljCMPS҅]&tWfZqҕ&׀loe+3_>	Co}<>.1qx݃xu2;ڜ~LɓovTγL.$O8>'p$/ -[g4pƦ7ov28c׃F)h23=p"9_~&lNLrmۜcLplOU'_N4\zիW/,>U?SɃ7X},6>>~nŗvbP/|7|S^y׾\/11qL}3koc7Ojj?EARXOIF6TQyBlǙX~XXe;97;9
    Ke{CZڗ
    Vdz�h
    &Çw,3EO?~h	ښcRѷT֝cȑj7ѓnU0ٳk$tˎbۧ\�2NnB9y憓ꢃ	1|Aַ.,np.h<rHw1!~"f.>OQYYޑFOc\uD'ד*wy_>q:rQ&/UUϣϊ& -"ݛ6<{XYdlx_E냂rᇥ[xD
    ey>=9K?//$zq5/V%9|:#i=\Oϡt@STOk'th?8,`<K[]8z)_R>O
    2r=C<~)+7^d8Nt7\1v\p_[iExS_fg?5
    6Ȃؗݑɥ>+Wuhgs;d^1pGXt<[>ik7Btwȡ;r6f/m\&݁cMygkhnl^j<ϊ38Cn]yWd&u9$-ҔX"Z~-5WvE?|䳦v,nygeʔ)>裮Nnf!`?oܹnb!	/DZnɒ%O|MFot38\C_]Y.ULVTi]WW+
    ߖآZw㤰@v=ODi-㚮FN:�"VI_91}kB��2\lLڵk`Y2.gq"�ns鸨֗9YA:R5d>NOruii㰻!~r:7#o~xf,q2��@�IDATFΑDuglk<znkU]+F;?Ⱥ(78>qq>Fs';j^dOB\;vqOggt:_|EHr->M*R!sI(Rnb~Y˜km_G_춺s@fIv=̗K/=y1x}{U|;	}
    n'둼wL=pyϻI;OЇTw,7iQ1qQXé 31[\0ob:1c+-NE]2>"ʠM{Td3IBУ/ypx_OhͪLc<CZ>`b	OCCuw>zc*Nٴ2Zx9#ʸ=UR	Z@.qeKahc_lBc,4?t/`:a%Ow#~$;S|BW꭯R.^}? KBtkRi]'M
    #.|5}ֺS1[So菝iOژx
    7{|ee	lNÉziX39p:PQLa	&+>ieFl'xEzۻP-0P^5vxGU;}k2O\	@dɍD~B_u):03F07l
    y̖0
    )G
    [J!Է6u֭s>.X}ښ~fʼ3	uܓ<TFRW}X}I5"ޱV55-I~tJhNkNitV't,[7uI^QL2UFک}cwX7RGW6PO"$Zd놵ƺRw:cPqk޳[m\-{vYgΕ7ef{>NOZa+Ky:7uv2}Y6[[]|p}xҮХ
    IAovCk<NlDt19>~ƇzZH\c:-@zƀ	^8D]wuz]wɧ?=/5G<nP95_~U/?)iU.;Gv>;Az]!&/R_4)gN`T8iavقAJ#
    u_?a3茏o:{𨔔gܿ$=45gyuܻ{4^},yy?]Ə}c}+RYk{ΤCX4c#	
    :V?'uE V^qv
    �}?a
    g�L<ÒA?cu78Ƌt�Kt5{
    R}g
    ѓ0~MO~؜`8Ѵ+m(v&0QwM7w3t-?s>rׁ
    EsWr+smY4~F՛~`7+NK؅Gk5p;R͝I%f5D{0Ŋ34ܣу~MH	{BVR)-\,,5%CKkrN/żbE>8fk	8b/j]q\ϗKtm5cn<Np2۽'Ya6L9gG9p~" 'Yɇld$W~B/_b=4]]S4e;#.8nf0'<psuh;OX`02hEq10
    $YI!؅	o*N:q x8%?Q<zs9,/
    5s#IG^gkk:SY*+A?G]Xh]NU[o'DO/glimn+/ȔY6k*GnC';dM;嶛oow?"#&ϔr]>p̙4J6,[,<̘;[v{MivM^)G䵗_RپeL՝
    tAhjd+ecd
    L:[Y/ᗓ=TLU}vTnGHF^z
    XIg!A?*;%߂6ވ
    x**4QgriwpY$>%m{DLƝ/cIe+|r)qo4}ι
    Yb"C<3};Z֪ϢxHnȶ5/ˢ>qҿl.?wOލ~r0ڪLYLFLvj<lckްMwqEyN�Pѧp(plLT`Ήe{,0b$N/9I>Me,ȖvE9oø,⠛8Zh+2fġ@1Nd,я~A~Qq.Ѓ<c?=Q􌯙É?qam&\ps0WwYE=?]_N2Kf2lzĮ؍:PL!0_F<?_z8/[+Vp>	!!ٌ
    UֳA
    9DJmZ"zTӼU'A*e<߯\rNLTlZr6_`cqs̽篵nxZl|*<6%%=X6>?`k]=ڭB,jp*Wؘ>Y<Ǒõ]TT-W
    'zN%(7$̀?A�dvM.mq-Og.8TVV :lnR0<pБ?:7dbuYd7ե9T>SW__.Mydh8q0i^kJ!;2tHw3`T&_|VRvY2kJk
    Ɋ륰BΘ{>@[Q֮\!V!Cȅ'U;V?C2WQ^kX\̜/7\sj 7dÎ2DZV._ȬrlF+ߐQ_[v6>KrȵΒj\}L:_zɸ#cmZپi)R[O8n-6{wVG@;]o=YFYb՜~ˌSFm%PiS'K2]�t@U6ʝpX\wVRTN+6Cm=VJ鎁IctH8{Aojddx)/j QW&kȑڦTN$};dQ=ݹFk<|tL7JtSvm,7o`8emig!4DK
    uR_=bT'kmZe)ٿSw:52dIn۽Gk'Xവ�'nPn(2[Ϡ<fyeGh<}X6鶽V]Wlg/}R<AHO-*DZ|LJl#ҢNIkGd|s	H=kypx`RlQny}&yLS="W9ОmfFiсSeԐ
    ]l{ټ}n Sʾ	ٺyՓfHϘ"U{έRPGf1GsoYq\wZ6i3j0̊Y�T~>G
    8otk9p*3w>9\YVg8d62&>Lq3xƌ=]xw9ݗ\a};+;CNV^RKL]"8ԓv!`îHƍ_>	3f7CqP=8QC=38_.6nhexFİz3d1Ø
    ['rY^E/lkG7&$ uhҺC®yISFinmsȯ-oZ>5b>7$O)t̍C[@/m>m7#8ۀOAr-q4�V\<9I8uv}DydFGO=&с~.&)i?u:9`zЧ_х}}6-ˉt4�1D0[#??u*z.3MGɹ�ï$,?Pf(7rы!gV4tnƆ&)).%/?>E,oB~q5}@˜[\+y<t7fzT>ٛ'WuL>}O_,_#B_}ny'n[n]OOW-~rG?"k~w,W'ˮыUgͥjk\}B5{NYuVQ2~~Pӧɖ7WIqc:3mn(Eud*Yn'j@B9sӓkdD"dCL9|`+*JM#2oKzn؇+ȃϮ?[Y"˜R$57瞕/Ξ,+_ks&
    '~s9^>EΛ1J^~wZztYjO̝2Z~]i2E{aNJEȝ?o><:jKr;qq-o{|AYX\<R^)1M5}@>tMRs'dˤkrۧ>%7>*3ϙ'M6뷻]
    ׿"w=Ջ%+䆏~N-'~PceX<ȣ:iWOȜs/ԾH#$BxX=?Ϭ?wڃ4+E@geAB.h	x ܛ4qvڶI&-1ȡeԭْ_/I~r$mEcK<_G
    `>3fugw.yY`@�OV$qqYoد@;[ WЮMУau<>
    r|*Wϑ^jg_nR֭X"_X&Ϝ#[_.'Ţ+/</\xXLc_09n_ǐR#o1beۿ[
    k^�rQJ*4<~qwL☸k_>i&xrMe1<y8U8|64^~_FYL05S\fJt`}l|i<daƣlG1.^G׵1]rA-匱nS{c_v%|{s;pae1x9C&×kzYLlws8;[ݡ_Oxh;"xpϣ/A?";a$Ҧ9Dc|vy؁Bs`_2M'bK}w$ҼM97~^L#eFyouYW:Z/eIvjRfpzcoC:QwlM0h엑.se*=0lfz@[i6]|8"ǹړ/&&}g%}e}.(M?kߙ]gǪk|()D/~4]42!Wаl0Lps/eǃCNtHAn?*?sN$MHe9)ԕ1c:]T9MƩS;Q7=T-&Ek]Oo|\*_/.+G|FtϽ&[7kvf-U̚:L^1oq#Ȏt
    u7W[:h.}<=HWx19wl{s;ZŻ+}-屪Oo$*]zB}ĀHǴ9R5u-+d	rlzmstx\~�0qn="9[qmuC&.ҤnЇ:4p=r9g=)ojۏˍ|T
    ++G΃5r8"7,vEYl5z|Pgˮu;$4A'˕zp]޷wTe^زmR3su)4Rg2kd7eW':[*)/h˺
    ;drɘqfOUٳ}N&/^`Ww:vȇ.%+˯.C2we^z/]!xYA=wqlA08<	v?v4ޘ:_RGrL78ol>[
    g"zRS4KryJ/um(.p{<ISwlmKto(=C}P^_W~8eduXWɊW,/,(+W]_JۦۤfNVȇo\'HG=?L<rni#VeJJ>#&]̟Tȸ3c@uӟ92>H_¡	ıE=%/+UU}?nƊcBtbSYv営ؗe0b
    ԁ1 8+6dȢN*,[رkޖy%<&8r}%Ȱ8gꫯv"2)&Qij"kLDŽ|&'Ѝ&Y/x_#b;
    uLp0q}$v$J7<?MSo=h_mnڝU_p}~;#/pcs-UVV:~L;߰zGT:SNq~IWs5e.Q9Uϑ~J3lOɵZ*LcՁ>8Fcq́}-h oASԩrӋg&rK:^VɄ}ɧ&3
    K6?-)JJI .vg8}(?}l�v[-�i	!O_qE�j)v̉5c)n0A&ECSA\Lt2B`.^RUUًZtU
    K.4;.WGC1~YhK<%/_ZtvZ_JYq{̞:1/_O:M3"ҁr#r˧>,/ȉ3>xm@oT#Νl=*_xIιfY#mU
    4CtHndđr`Y_VݺusBuLKqB߿_u9g|I#+Ȫҭ:?@o
    ǥP[	}
    )cU\+eԚ^^tRK6CtR| iv[1PJ>|}hu	#M_}fW0K
    UIyPݦK,Fszk!Ckߠu[OA2">SY
    ]r@WĚ>yeRѯL_(I|iQꜣInߪL߾^m$	=Ag8je2iX`8u^27,hGi&ea9wDO;[Xo�ϗz$vkK=WF7_U(ť".-/T˾{sP][Iۮͪ	aR'*Վ6'$89wpm!zBo†}&a"sӛ>*.NH}cB'[|FNyV:ٲv-%Q
    ʰzkCԴY!@9Z{P^j)Ò-j!Rv1yc
    wvϏ#+_W3I�0_\K#\ˌXqB/*`x8R#ۯ5mବ\w�gfnK5k05^I傃=%'Dy3^a"t'__:}eci&10NvĮLzf,ߗ,	ɓ^
    ^t6>;'{7(,pE1;vFCߨ]}`ŵ.Y.%ٲlɖ{ly@�	< $@(IH^PcnMnj,|HsWƱa֝v朙ofgL[M\D�rbE;#X^QTy(ؔǺeNNr560IkX`;6j3
    АFbN_Q'Dk۸ؒ}+n}"ʫe=*
    njs@VE
    r?qQrˮZ>m)?6Ƀ6M&":e9VK8tczL4~_6WYo'lă;>؎8)g+##S&_K>ƗmزŝR+L5̄6fv+Wě"%=
    ;a&B~'-eRm=cG7><Cʗc:Zmj1^=EMϗഩcLΗgI[18y%
    X8o>*dC`矌O_
    O$ǙPz9{E|ɲ58HΔ4Wʪ$:vUcq™w/uIB`[d`ifN~zhRˀh;j	rcdROfm!w#{td7h1gL*Y҇J1waȟ6
    ur3}US<2EW]Qmes�v,Uj˭|1aw0{\ u",z*fu52&qYil(dee
    @Nz/–iƜf@QfRzTv6LQ'*\9݌^iغL:3pqb˃6E,/xp-֖sC
    l-ZFK坏N'[:|(KĎ
    K[*Wp]
    er}'
    F|B5b#ѷ{
    Hgd7'`@뫞9s!D@mΡsÕ 5,pw4Ҵgw_jȣYXyo-asm2QӚӞh|g	⇞Oٶ&a?AVej^cw%�nRF~~xPQ/\9*,mr|ǟtzg1
    =!ڞ0(6$|;YX>m|/h3 1f6!_vCyrJ)-)V*JD}$yz)
    ѭm5a؊<T4c%9�6Ug:fS~~8�{<0ǐjȓ|j6?Mtj?W29Ȳ?w\ÓRq}[ϪaZvf<t&n�O%
    G*"
    O-~T̻U2;WBfd)#ɴI.wp2}3'y'y7^8ȉnC	3=6q%sb8Iy	P<4~ʣ,r/wt^I4|'qJhlH2|W"<d
    9r9we3݊^`:gI"I.R/(a?I6n'.kO[14VS/~ h~Q޾/Wei>Y<wx>nI5_A`j4dͮ:ydad񶡡%e6/iӘZJaS3)4zxV-53͇ ZP&~hr(i9kŭF;De"Gw\x8Sl_eᖗO#ێG&M[p3p`\s\XT<4()ڂ:|w.)RIe!=(~ګQ8O5`w{_߀1V2+oݣAVwn?n^s;Jnw?YϹX.끅Ƴ=C
    æj]҈sʍ/ɶ]nĴS1 7OnxǢ|"losF|<JJZ|3xg*˷5iv᧨6HVP!i
    &0o<ŻRz$얂7ayBP䛏Î07x\\&;s'3O?1o?k]bPVf΀
    E9	2ti34\2R%g?BU%IG\lX6c;CՠZ~PeqM2[6c(Z1+
    pZ3px5(QvU4caȓ]�i`֬O䮀T?ǴcNYڊl}v|ແW#nkg8>$n-^'A:mz#"O)7=lt첩8r)=RdPea@C#˥kYK~i-#|Vw~}MWf
    ?[o--+ny1-E>Ht.ۼqёrܬgoGLmö-rsgB'\AiIS&WGl 8ä_-}DoA[Agu}!nG[i[�5*]TP9XRܞͳlg\IۡKj2IOeۂy)&ӧJ:l`4_m
    M9,'F+XNQ㷩Uҕ?Hq|HcQ孲騨R!ͭ,7'G	.^qř9a(eVE~}J#馡MwV&rfy F̡K9ageB]lOOyw4^z$,;1[9(A'@Na`]rb+??(|;	OiM"藁0Jdy	$jLx?	w\>AJ,n1O7(~3OCN_;~>oڶ5
    ynѼiMyn|s_3I[F|fX߼T;p8G<:cT.i}79=䁼Y
    >S={QeS.~f()5N.{e03dY!`n
    ;+|g}KV2;CfH;=@/v4JK
    ?pF[p6vΜ$_ɼۼU\<8i_ddu_ r!ێ[PG?KqPe#c{+/ÑN!Q'vУOGNDdɌc<_nR%2DLI#EVᲒկ?OŒː5<,d-YFy*[
    (Mr>\:Y92}&*\ !7VLrl#g!}%3zXfHyi>Y9ʪf�YO
    D!ĉr!P^X4g6RmMRYaT_\13GgWN^}!dWZ/"gs䂹r3CGM6
    {!S."1*Q>b=rz)vDO6PZQQ8y
    6A*lE6<f$r#c 4+I&l 	r32d*�X^CakIs̈́Ir, I'J~d{H!1ˑj7	c傾xi=>>a~4q4h+_|PhDep2l1Q>T'MsBGM~|pr~h|-teqΑ^ϽB!!q='@\KdKn:z2_ IVU1_4|Fx[ip-0'9v9
    —_$j%5G@LlӗwD:d7zfvo%eC#RV֡@YZޢhȅs.ƀi&Vb>r,h$]f5Ĥ~Ie4~9XFۃHAn8'x㎖|^yW<9&䘏9j*{,3Bǣ6p!xwuG
    S|8f|_Seqш'Y$'ZlD*|%'sGוpݢIe�u2ߝ5f,ĕJ*#=ϻZR+raxn}'BMAl{9Ե\'D_U||w=wEp.7¹S7sϡZW5]+rLħ|VNXO(MrSOA=Io3,+'UvG{Xw-+ƱSb[Qɇ4|439h+әvEZ)홓-d˿'/PF۶bVn^m۷atcDAMp۰q!+mPldY1<
    +38g8m<Y{<LG�yv3pݜEFpNrv,l`ޔ$PlMEN8r`!]X2amk�l&BS_U_|]zqo*my]])y
    |^XdBawF^XSv|?3Ar8(%طoÃ2_ٟ6];GPJY)+zKW"Ss00i%ߏ^0˞yۓk?uH:Ijؔ}.`R4F4ͯp;ߕמ2"sM.=W*˨_Ocsȁ.o{vpDeX?sf\űwp%ώW9�ʐp;h
    "k)N(LJ4v5M21Xycy8\ij/1?FO|긊y*_͊+WT<L<sF*m0<y~;3?S
    kZxۓeT[|4L8mCSQ랆w[C,?IyS?*'h.`hnҲjRܒIH:<*dB~ȗg;AxNɶO;' ?KgpቌQГ>.H:J^\5ɂw_ ߷�ѥu$SR)e?B|xT8Ny&=i9!|frF9)P/ہFi]pGvb	Y;Fy*]Я4O
    E峤صLqCNvp2?X4<A&zΑ\$˲*~a
    
    ʆF
    IOf͒\sM
    #=re6/ǢeBdax (_6
    
    `JR>PV]Qa6sƇQncpS 𛷕!C>I#şŊ^q.RDN+\~Yl~.ǎ#4Azb϶SSd{kI\h';LF1;1o[8<PA
    ;<R6^y*[icw֊\l;?)6%9G]"
    Î(Hܴ,dT7jkaJ
    mWW Gĝu
    :3u]l
    $W>-"*xqUJ?U*y7qŴjHqHݦl:〛
    3FGMS6WU9ձ!Çe{]Q m9܊Ǿ8.8Hq~O¹RIɁAő
    	
    J'FWeՉ&g_ki=`ȃ0e"%Cy!5ۃ lK|>8A{Sy矶v*)kL?Ƿ.C׾T`|ͬ)aD/Oz'yp2w&,#
    iXF_m(Z70]7:Vc<𯫆ee7n/1;jdWrZ\&y_BB"DWlk,]k֬FoS#cxjAY)LCXq,0.Ѱ:h:g帍*@k*'V
    ?h6"v*ʒt+&bҊV0AGp_@0^i4gCZK%P)O_K㔞4cZ'oM+~J-e嘌~xm˴1G"r[bZ҈ï(	3-it2(TZ0bq=W;cZ	}Z>AZ@>y7{Æh]]8ٝ 1ܹ%?aL2Z$|p�'
    :jYDVh)3`Y4-fڠ_9{Pcδo	iyΒc*l26s1a*ZSWIAY}TNWmmc,yxUǬPtG*eL#+^3?GʡtcZ֭o~5oo+@oe8wҴǟqlC{Nk[ӼB@[Fmߗ*(KwR1;*s_c9/
    MOFy'NܭEeƅt&+NbeG4╮=[)
    dR݆"y*n	=ʼn/}VYl_'Ǻ/Es,vg穅7:)(=	*ѯf:vRLMT9KƙT&<s5GGc*M0uKJIj
    /DK|$	):|_i}i
    gp'qd|~-%/!fgtvX[4A~to`"ѐI0!iՄH`mim߮qv=C�i__{%9k,'Y^17%Ϯl[g٤0>MkMej:t.}eGU4vzE+
    i	eؾ�1qf'LZW?-UmtLMۑmNqH<U6i8T^Hi0tnm782SZ[y~S2MC^6iGˇc~5-h&ۯn2c̓m~un0v˦5iLJ˲{$d(oUQq2hkٶEt(/hmRv0h]yT9A~ޑ)/4O=_?Qj(3+={4Gs*0}vŭ'ͬDc<s6
    n;p8A{Wx|ӍQro(]	�gr>"~`CA^W*wґ/"lvi4ekY\y��@�IDAT3eV{˧3yJg1i}ޱe:[V>:1c/]A׻ɂrT?m)ZItњGcY)(^AAͭ.vGm^*6"!Fə`^&B>czʹ6?QjV;Vik\0\j+M9vVz
    S[i3&HP~hItjk`kYO;m2ΛMe"t?[-nQێk|0Mci8iڶȶyi5NeaLkin;
    ÃFt\ۭaLk:
    y2Ʀ	Ʒ秎r4ߦ6MP`\{`:[ģx;MVi36v<EI关4oȭ6t	߃�8PژǞ{BKLG<'_Ãv0]x
    &K#6$A~u6~-J6:26toU5Ni;5uOu0}<Ύ,c<SVWpWW|H&eBiW>4h:\wIgX5
    ٟw6cePJ:"PY4hY gUTkzڜ]+ne`LfC!p8w	we~&_UjwU6-{L4!csRykhfpѽOdY`YᾯWE-*7ؖLFg$>]
    S	]-+wW{eQxOyGTЃ(<ijQYѶJpgMܮW΃2mgY:w4w{gWavH?n_$`;-^xQX4p;;(~Ni!]&Wmº&:/Gɔvx+λTf#u^R+ѐ?uŶFQXWd)-aAA5+-7ȋqvaeR>q;iTy'<`YHtۖk aJkuVKhZiIav{gWZ;H|4O4L0~oC!U@.6}/*>F>+f=RGp rk!W/8vn/#a<
    iq8"p0;8:B`l; |'84uN*-g	H{ 05mS!8o_#*-Y.#s٫檨+C!=E|{*"pgU;Ɵehylx{2;cO"w_7wgx'?NU^GJO=iʗ<v'4A[egdA^w)EJ0;_JlYtiVm늺*窠kt-*;p8C!2#/s].�SK_5_
    zW3NGWét늹a<r4_p8C!2"ƽ_Zue_|UN+੭ʸFK񝵻'}hڋ銟|ilmg?{/;&? rKcO䒷t¶ch<l9AGGAzo
    Ig׳n>מNgg{:7 Iy+?;f|Яi(^:ʧ*ti=e:OW˼t_He(>R
    k/m{q~_(DK-=^L dELo;ȯ3Oz0=4{ó=y7rUҵ:Cl4՛Mgql;6M$tA72j-i,^[;b##
    r!p0#\{UWW`_'0OWx9>"ڰkV3Ż*7E#W^]Y6?!GI*!W]Y!Y4p\C!p8C!p8?$C!p8C!pDE)QqC!p8C!8}a$9C!p8C *NA
    p8C!p8C)k'!p8C!p8Qp
    zTh\C!p8C!p8NAX;IC!p8C!SУB"C!p8C!p
    Ir8C!p8@Tp8C!p8SNC!p8C!p8"иC!p8C!p?vC!p8C!GE8C!p8C`!p8C!p8{52RDLL&k,ޤj]/YKNWC!p8@$ccNǙ}roMڮd/9]-w8C!p8AC!p8C!/))i#JncWwf"U;Ch"^"ٔvf0ܦS7&ӦwMi<M[4LJVVA?#Elڼ4^m&[Զy)ƩFimۦJCnխuiѭ<mw0;]GAZOvkSeжm'Z']4Ö<Fm9۴6κm^v`vA;Wykxg
    '~4Nme,OM6?uHn
    M,3Φ?F-<æ8~_ik-ÔNF4v5h+M0\Jo3F~V6?;VmZ`xG~ʣ(}|klZ
    H0Ӧ6_ۭ0uw6.(Kөjk<m-uNi4
    `AZS
    5AzWzpu&6Q7`8#iXNHcmklێ;GGc0c[Ãy	h`hz6iLC5ܖC ?h5mZSYӰ;wvٹC!p8C!'Ĉ}cp8C!p8=G˷(!p8C!p8hK!C!p8C!7c(C!p8C!p|Up
    W]9C!p8CF)t9C!p8WUjڕ!p8C!p8h~@W˜C!p8C!p|Up
    W]9C!p8CF ~ʜym$Ĵ	;Le9vy"Y#j.(鿃=xlK-I=uYKp8CGS
    z $^WGn2@gaN,uX/3A@~$2uUzW悚v;`[;Jrp8@gUβ>Xx{^>
    >e1/`++绽Z^GK{@XʕLJDsYtp8A@tdt%=&Xk7#)9
    5H_IcG!13h{hnn3
    d$㭈G[xXx>nچD4# L0
    f3e.,&Y_l/ۃy
    KzB2Xzw
    ~0aXvbҾt>;)Gl&L{*ݺ	.FS\"bS)mJ|gYׄu1#ǎCf]tOE$H.!p8vS)W/WI@S=RqYcPN&<*($&!X8%|ۿl?XARbʫPRnɉ|5^<AdtKEz,1s+ʣE^9[¥??'
    L68orM%:67g455GtS +xxJ[՘n2؈zSOṾ *ێ3R5qݷ㮇m3)
    z7g+R7OFK
    zk}l߰
    'rUcj3
    zNϭ$/KZIݺݻ\2*xsbݒ#R\C!p8
    (–o[,(a)*QnW$dAzE2I<Q|cdKtgY9n"+s)+/:hkWQ/Yu߅O}R:Nģu%DPYVa!O3ܭ	6VAo%@|c҆kU&[+,:c/޴WԸN`ڑsWU4۾^X4w^ķix<0_A71}]Ы2Q-?{x[h<OFGoϝϻϞOOcxG,O-)0:+ĖM>؎?C近-e54Bړ^xhfbqx�%3JM#f:cTnk pILUsgyΘ0غ�o~q#Z6?Zŧ5}rgg]eqpip8@tm|b
    
    QvvNR62呷ƛ#$\anypo):xD@X#>Æ
    6nPrdl睄yL6+eLyIo0X
    .dJcokz�m=BjZN෉P5*ARLӖ")	yUTasоo`ń1CQVل
    x?KcS-lZ&l(UyPHL5{ cչ(?fQ ۖ3yfH|eʕښQ+Xlpf"i++@LeIV.W.tAaY7pM8z8nX،<9ӚqEʇ
    BΦQY
    IE'y"jc,G:Avay)<MHTȊyz_!|d5hbbK5G;oaQ|=!|SMOE>(WeQ>byME2\@Zۜ~C!8X
    R}�jguOѦl
    
    MOeR98Q7 B8oll2$+JuGL0' \KHJ!	ɉ/WShȴ{&嬩(_qQ'y޵^`	anߜSV#RNāJ*qmp|2V6F䳻rgxM`ԅ:EoNoOk`[/JX<mD2I3iGCem"3NR Z<{XTHELJ?;~hvqܴxjDѮ�k-ZSBdg%.7{#RǦ5۫/doCib*J+GJ>MiIObgדDavekmLʼn64J6K9L]IDzl<,g%*"dX(q2/ߒƳ4>F~Oee!흄upCVjH<̻oz_|L[څ<!Zy\hy圖&ʶE3mEǷlţ!g<lol[A҄3M!dv;j9k4r4[J|=.]I3ŴIFO-C#ZN=?'!]LYmDOL"%?5;!p8
    zԩb>Dj V,+Q~#j g:#F``Yab3P-uXf
    b-VZzIppޫw&bȐ!(++[Uz2_rV!$grO>6?8NĕW-[En‰GNCwOˋ6wá� |Khm؄Rm݂j	J|RJ7d|6{Y O:ei8!M_Ҳl6w[S
    0lэ`h6
    rQD@Yك0֯^``[Є~v7rpX05cBb()edq~|.:4ɇ#J*j(Z\ҵfm!+Y&ᙀ|=GhR5J
    Wb▼g
    ؑ3kס1)0fX9lE6(:4{hhKyߓ@0L(kꨪov`BV6#=rd=8{(ٲkmDyYYQmtbc ~0d`l֮LY2`<lYsG"yӏDYgS?!Xfrlٲ;*	2Oe$O6$F!7;ӤQ%AmjG	,^%KW|p&a`P5Mw#A
    n8y?S,OMx_j]+cnj a9U[K/A<q17aqtq<_U;hF&<,߆526slbbXSW3ZΟ˱3))]Q.t9V|o5
    ̾"1
    ghX*,[U
    N}C,F>K؈
    6bW2`|CCjtCT[k˗/Iզ5x% �FJGHnڙ-N8kbݺuҿv'"�CoV)wRvVVZ&}fvQ/@<igC
    V~+VRSS/%O12Y!�aȱ8btMz`ĠU-l
    Oqe.1\+'j`GVZRJlT@E[ei墿\P/4bŲX`.^9D͠>F\"-!p88D1^hJz
    m}|GF4ߘ-ޟ~PZ3jΛ=k^EMI#g{ˊ=-}0la_}ëʳ3PWY==Qy;ܓ77\u#^EwY~5d'#5Jx͗o&Ml+o~Ы6
    X돷8wF?ajBe=_t7ohuQ]?
    K?1c#Q[<FeHJKض&DJvOxU~_#Ņ#׭R^?f?>35|ޢ
    &;#+&l3Ls7=ɐݏi޿|}ҍwF'`[47zo>e=;?>[O+m5Ԓ//3;^m(/~FN{-esظj/ȧ{yS>䛡5?*"M;l׽7?/O�tjPc?{_^`Kkw[7Ԗ0~ƲJmXwh>yBeB&m0oywɇ'PZ4ﴵ޸|w\xm0z޼.=|u_tO9K[Ę=
    ޻/?]t8
    w+g.{9D
    9{CXi"]%EOkdK!ޝ?w<c.7?RZo]pke7-bK:w^Ԉrm>~sWf;gx{�i|oݖr%XgC!8{AAYU9,YC/o6!-aw=/ҋNXZ9PϾ3/*W3*fcǍr$@'=g¯QKA#mxzowUWYQ}\=KP=s_
    t(5r7}wnwXndjv|o\3ۼ&S>֖WF7~xo15[}뽟}Ʉ`^[Phm-˯.?<c{RST&3v':ݛ:q	K:Kt/[VT_~3M}y㻓[_*5~syn>~d?Cff75x?`kY
    I1}zp.?ϡTO}B4.x/ZgBK
    2!B4OvnZ]u`t(Ze|
    {EAgf6;ofشkww_т-e(-Z}3_X/>3;-e5owkQt$)+>wKC~0g0+!}޹
    m$4W`
    4\X;ƛ[{ޫ
    yWC:]$'`p">z>[`I_-ru
    {o7ZKpŬ7t7=CuoSׯO>BGyу+˾zɖ|n}?r䳘[J‹`}5o"P>+/6{ZWﳜnq8A@׶(3Ɠ!ivSobX)o5}SXUxw=FN
    'W|ƯSxC1EGg= 59IVaǟśWaCs[ة;/ڪ.|b0y̛HO7alݱm#ސ<w3U&%{&5ij3jw"ExGF&5x�g9ޤ6x)>
    F1}2z6flo~rEx[cFc~qϿ76K77^<cXB:9F7*lzH$u"o"~xHv'ƼާFg?8X7yw<
    LDX|Nj\~Y
    [7÷^$9:g9;{�2G t
    alV>߼h>+7ށd}Mk&V.]ﭕJjvf<}�~9C<k'fOu'bbdVaC{<;+lQn>xFbtr,}K!-@PԌ^+>X21vH,^s,ar)5Tyvrsjn>ӏ;~e20ap,X<|4SFjI\^{َ؄7`	GnVlY?^`)/UW~G]yKs [xG6_;	}d[+&v͞<ƍz&qOpYZ@uxu-,[ĸ˪䲾}�|Hջ*0񍯝*qXM9sg$<͘6N.ܼ?[<,L:
    s?|.}49VNܳ6?-k.9URvXC&Sp/nLvf}2SBAN:,#ӕ'zC1k+GI],6OŕCy#-Yb|釸
    MϰF7GLr;riYxnܵŘ8aQZ7ȑ˸$VC?qرi%M٢.O$x51yhsa%#Ϲ?R+|[.w`)?o'wm+Ҥ"K;,93-w/kC|RO\'0O?܏i=
    ~1$'C0څ9I7~C!8X[
    8`RʰH~|rp^?mYG_rnx1mp8?`R!{Xf	HKޜ}#ʫAvU֊;܄Uۤ,g=_,D(ͥFAOwIHMĿEmի�sumE׿4ɀsE9n&`x~.yp>CS|\X_Gד3G}
    ]x}DO_,A$Yݕ6L&%yX|qAN97^v*>(܊F*9-.@J\ëBQο)mB~vG⤓NC-q
    y	]*xS92NM-(O
    .Z;W &"m
    ̗3EAk7oߊ9#qمgc<7v69i|#ʉdSkRq)g#i>Y",<O MߘO<
    'Ć1~snY|ظD)KfԐ|l]'H#8
    [4u3ĝD7Q;$캯OJeok;+y^BzqӰZ\l|xѣP'nqCKzUn;at>\U=EsrJ3.`ٸW݄k}Bo{WoTsrKo\e乩޿a7JvǞv90HrJ>K1xxQBb,sWop\!h,؅‹/Kx\~Bh>/Yb?opŅ'r`a휣`?k9O5eR3N:5
    9}2rd;^1,xB
    &p&cLnn	Nf(dG<q8]ȕ6ϻ2'
    ,K=ӎnCKݍ}<qGhaGNG1`@Hf&fy.|7w[PYRF3!@2d*E_?EW_G%S،J#7
    rVC8rQ΁p/F
    |Xm瞂Rs$4
    #1C<!Ƶ	'SNʼn
    QƓ{/ˆwQK
    *p`b~9ㆽq8C E`+`VT>_FV/+(pQF9\!3N?(5~e5|7R\"/U;le!o܈EܩF.|q[&\%vEkd&)pᢜd/7&}ٸ=DCjސP9OJBjǸqŏ/~|
    r3{ٮMҭ֙6l܄2Z.مͻ(!5~yR&׊~kz{\*u(g{Xm0QRI3rXL=D1NμO$t-guOo\3%4}H-nɸB9'�xALrƅW�5Gm0yQ^A~ax}g"UI[JU7EeqҖ-;P'E<I!
    8Kν7tL$t7\qFm?$Y	Dze7NJ{.we$"QP
    l0crљl&[a>9&xTѯ'^ IS}D4u[Sx(a1d$#4fCDD? d^pzQS+>,@ߐNMNNI.._I&?LK{hVTA(d[$7jKVq;f4ZZN8S[߈oC\蘚J!e�@ln[CƯr5b#?O'K޵?3m1#?POS'썅발sbjq75}??1{j\p1HK	!KPLn޵7kh,a{-e<x墱r)Mo^c0~97O:l5]&Af@ֈش}G6|VI[UrNTv9xp‘HFT(ug;*2/["m4Mul&S?'Ț4a"HRoq8B|,mXҿYHw|W0$nqhK1qXl[+m1
    zrcL[A_Z?s
    P0/`re\L=TWdihҍ'Mo'A%gC!r!6:[&L.5I@bgUQz'CtLO_?Eā.sZcZ!
    EAoG&?? ~Ȳ6jYvJv$Ō=QVV9i)trfĵI!B$;D(6wш|1V3~1d{+8x0~seo]O<W䠸>}sQsS08%+eGt	l)\
    o8]yXN
    Hg!9 :1
    M>.r[e;$Cb,�??E&6!}.MEN6Yݻ#eV\7M\n	1wׅdRIO@*猖ƨ[;c6eխYv)?d."sK1@nOMKWa[)m\wYz^`+-Z-Ãށe~&#ֺOJ2PWdv#4mձrT6vyf{CME1^דxU>o>c_yzȖ[cD6zڠϞ6R)i5^rċ;
    /AgDYeUQ\; 33EeHpaȴi/PȄȓfQe"Lnn-}N>�i\^cVŎ[4aFrK>$I21!LТn	8r~D!p,YRrAtJȥx~iאܭڵß]
    iغxFlh6N>}z@PSWU_|<ޘI&-+qM,?~ҖP"$m0N&LR7YΓ!W1b[vNÆg#Q	M7mu#ICBQsov%g_A|V �,}Jncdwg8C&wBgD
    ,>KĖ׮ιC!81:(Ah@ǑF70\h-ݶ"m=i+FVgZ1Ue0owzѵ&'^x<rlF1W6ZidťumD%rpksTfRP];ni܈Qp#:a8jJV?Ǥ)Sܹxg /=	C,
    Kw|mHMÂ^ЏOR9
    ۾a)~yO=$dmSHBAzBbTQE#eJel*%>($fVX7˭KIΘo5)S͊mMs
    	*(g~&QJU<8Hou.t]*yoD>e?vFsNƀI>I?~%1;oL~,&bwΜF#/QKlS}Wiv܉ן'x!Koϋ(D!V-X{c~3VVEAi8'Wek7Mdg;}3DoDbRf:,gm}na*~dږVغETMw˕3ۊ_ad4._*(MQ~OR0%XiH*Jٳ<_,>ֱ
    	l!`Blۡ"ld3CLM~W<௶;\_	qï[ё2pΖ{Jfc|W~n'LX=Z-0P^&xԠл.P>؎Dѧ7p+.7um^RrQroyU\_/Rj_EcA:p8)-�Qe&N&s.lm26+OFYEr$z
    nɨھC'g/s
    gWX(Mm˲fTn.0N;Ͼ-32Ԣ+
    -s3�C+mu5ìw^1	bׂ}iO/G#K.C]%u(腐;dŖ܃e�~1헍r>TiG~|L_SGn/YtgsA~^J"@HO(i&}h=l!J_'IuF3]I=0IϥΒ$pl3/ڷdۈ9M#[TadTy~A=O}طю!NqT.Qo0gTkm/͘῍r3z2bWCc#>RO	27
    z2cڊ>*ʾ/_P=YUv^4WbDX
    y8#ͅu>g�WS_r;ɯZH[Z]P.3B}GbRV]K\?;Ͻ?JtmIȄJ:'iS=zg6>t
    A(ۗecjb3weHy&BNQde5Fj-e]gz,2ܥ][q
    wF._,s;KeD	MshCL̞]0)\/FTV}g}9_rQCcٚ=wk'~r>G7|FA/nہ_<6˻wr1n1By,FX[;]jyXiڭNm|<3sɫyVc
    ,sr2x#8#0L~&ts-W_C!85ΖAG2ѥ��@�IDAT:"33Cґոu
    il%M/4ayiértZdn[7kD9yo]v)
    )<=[h妵(:"[͙kp,9s*e5Jp@EH(�!:Ji֯X3g^�U#ʧ\u&or\u%ekp)g
    m>/]SZU\85{i%_\|?
    	e.kGDS,:UׯIrac*nM۶~}9ٻ7`r_jW_|90�q
    
    &U:2gw"7я}<12t9'W$m43M-V/=B\r"잊!IQ>dVهBiΰ<k&͸e\
    dk|/a:)!Y'4}Y u@3cV_֍N.ѕm'H6ex-$9݂P=?{_Uѽlwۻ,KK	 ((b &((**
    +Et/,{ǘ{ę3̙̽9s߇;J
    i*0Z(}HKf,.,WԄ4{8dE=_xM1BqyYd�g#(R+wpPGԎ:UQ=:jћ5'7A1#]Ǒ
    +ԓi˚T@ZأN^-GB^settb׎]Ȧ\ґv!$'wD1M	-�
    R3W͒G=Mjkwd!͡5RU9< ',h1JsGAn<g:~E׼$Đm;w?1?X;X\vGOрX\̇X*ɎG6لwRksqXX4ͤvscmNA" H$'fyK!:45:,WR,#w<<WlY?r+?!>@.Δ23zhNH
    n4Iv!H/Z'!z<",&M\^Mu|Uyu?/HKkvaͩIͺ_bS0HkHJ_E%nǰm3"Z5MO aolILo@tgJMS8:!v
    )IHHCKqq\ij;vVag<iӻ\ݳIfyU_&'(uFpQ'嚺1<S|OI+!-bڐ`t]:#Ą9-(B5Z=6O
    7 k&>ݳ[(9iJ#kw+iH
    dwE9Y8}d/FM~+ۂi#>EzB8`e1?J%	_Rt\-g
    2hjJ2,$_<G"e%*%b4dO:>ƴJK]tzH"hAIqG9`1]ś"hZI5<wF)5~3V($ej0kQd\[:ű_g0vېDgzI(Oeݙ}=(B#h}^1R[ՁyxdL84/SOF6dћk_L
    CoHG:h`@n.KѶN~6Q?M9ޮN7_Aծ-8}~,\0Yrbr?\s&7N�xVT%NK_,şRZ&
    .]'csq	t$5""YWǙUXXTGV!kֿd<DR9
     -K.5lѺ?BBbZ9aϚX?&Gdc%:֑^jG	[U Q.#*u'~As#4"_+Oζfyøeȑɸh/ϸ�9yd5>03BCT-$D@"  P;lVM}PD+smu郦~a9QDĢIݽ}!x꘡O%43 N\\|0jٔV]ɷc|fMMu_b oR^'>ӬKN֫?.BJ;zO=0nAr;zFSgՇ4&hcXnfcAF&aw"ZE!;N}"&\/Y9"4P얒UVMYd:niEga.]	`I9Yh<$7EFيTPC8	ed̈\|sH@QK_]*ҙ~EIȀ$RxFdu'lNhEH
    ]m|Ʀo8z)	cpDNtbنOEd_<?l4	6k"FYoiYoR'Qb;xk˷_6Dp -=]:" �1
    ʓZwR;7	#5l>25"!`]0
    G�	31"l`PQ$mi!Ю#)e9IxE"n"*ש&l'FY?OFH_h!8	QŒԋ9	W2+ѹCkk<T9Fqr۳q0KuG2%e~<0`8x_GiD3DYağ 8=]D`4C|:tl߮wOJd0JpL~شSP?@#L}Ղ64!M4-5\OJ=Z''Qr*\i}J!;a} ,]9BC)bHϬk>5h[! p0\7Z<nD޹d۸kٮ+<
    QYw@ۖxQ8y	t$_Mh!秒{E?	+'qd16:fû</L5k`hj,߭J
    vd_ψ-8=3@ZU,h!6$'{ej^h`*m_J
    ,.2/3;vϡ.fp102d_#1wUxs$<d
    :_w2R9y8NLm[zb&ЮS4X8ӓA,ٌ~01hݼ)iآ0'
    $cp-39~:[2-9rg*?z,Pj	M%/'JD@" Hvڊ&"ڼgo[5pU+ߢ=ʁW
    Pٟ׼h}t4IosJJvQͿU%wnՁx׶[ioڶs)y*d<L痌5آX4o|O>w#gcEyN5-BF2Z	[ͷ=FU)k`RgQJ*,WO)h~h%ČѯT>[4ӄY)e<g'䙲cHぉPl1A{K&oē(9>trݷްNkw晔R^6xKEZV)eHi~9zY-@LWߧmߚnq#ɣ	!(3V|<lXĤT(k$dDgгo(YUNYAi&y}5$kcApT(~DbϽʸ/q}:TT%7mR^k;+y
    	Fi
    ׸T'kM_-2cbmskc8[rK<zhr9)SԠorӮ+#xiqK&ŝ=\gz伞CyO
    <ϕ2Q.byeʝuKA9CG%ǯ=h&YU	gn3Iz*2oC]yذHqvxt5OyeC#L4_b?*}ľ*4M}V9o_,U]X\KVW"H$D/V1
    
    񔂂?<,ѺÞ|$|vGT͡
    ۤOF26`$9~{](>v{aCoGPMT-QS}*2HGj۹+tѣG*)*ɢ;GJvT8/>|
    u
    ͍k`(&Mz
    BAy|x˨Xa\Ψm݁u4
    UN,ml;t^UTkt>9m/
    |8ָwàbwcpN8g#6?Q%iʴ߰0f,3&vG1 ^[uQ֎vi}nŠ;F`Эqzp,rf
    p�=X/	Q!}u
    jFW!(84ֵ	;ԯ4r2vi;v>s
    &/BBt;pJhѾ^_wN
    !ptNd50DEE(	;cb-D`1 y]S]D=ߍ`k[G\%RKu@pp>}C_&<|ؽPbg
    J[\39^xk9>\La]}#Cmq|=V�_uMONB-͵2̜%ƨ#Kh*6ڻ;>"ܛ4'>[G0~(I<6t6;v]u2Hv_]DZ'p=.y%wqG[3>[kC\IF`6ݻӸpжԭ;7k6mѭ[J6k[<0Hݮ
    ]ruiӯ)ƍ__fn,Ix
    ~l#:4C"1_/0w^bz<8']^l7[g<?>dTF!cMȮ:VyXg^^-dȌvŪFḢ֝^2t
    dgҰȎu{;ga^=cѻ'Zn^	yX +j0yVƶDz3.o~BZ®C[�p(uUy.,Z	K~t,dv1o*pqpgB|22Hr-IKKq2>>!Q{k6mݎ}	ĭ={aз'iqzRiW8HZC׮^p뭨}ڣ;t'}3^K27d4
    låqd1}ky C{pi˫D@" H$/3.64xEyy؛ϟd,č&pYNJbd#3+˪N	cTA[fMrhUJj&U\W5!'(( I*WWa2O@idA0
     ݝIdmZh`!J)s 5.t
    =]Л|
    #.I~:%.ةeHuޞ&g2cgTNSY"p%sDߚ{Y}&&덤sfy<%Y'45ՕEvN6A)5TK'('yGJ4)N1_h3'R{\؝\4aQZ.׬3mUϬVuwAЧE"SYA.xbV;8]1&!NAnA8_QZRr馏v;mzՆJz[RǨ/= 0㐑˒YHw'#ht~@oy#hhqzfV/\<wEeRPH5b3ԭ
    u
    Y*wZ^M򐓝Cc,MBN&썎-抛<31d#7
    vA4d8Xō{Mv:
    o1][Fcw.r)c@Xx!"PTU49pBk۝K7-7fr0~3`1V+*i8S?wwWmqK"99_w6㌏e>Q13k%vxExT05O1}D[mc0 yٌO:}CU|W2Aǧ]".4JƄҒ+O?n"*
    rɾFn^,Sd`ns%y\D@" }nFe}Ow=ƻ<	A츚5U'WgÝ^74J'P\5dySyQ|OKtNmҊo^&0Oc\M'uD4H&Y<<u6(]M4VNO+#GAcrs_Y?:SXc r5A�RAF�^:Oߞ]1+b]B4p7ygYs))|Zi"V_23w>u5RQcG+cx7ͼz|3m<
    ^~5pgp
    %n>S:͟x)!(FSyY" H$7J
    S<Y='hĈ
    .O28'tIǩœOD&jI1q
    4B8N_iʳ(*m3Ph8?f<LE㤶)2O^MiMW}W':9~uS
    TDrAS]WEq'..pZmྡ?N"12rqظ^NӸ$pYK
    qscru'֮r_AoۍƁ^Ve*`>TOmƵ13qZ}
    ǁ0Rg"'Uk!sA¹Z^IWcnN~Ucƨ=fL׼\zpXֳq<qChDSkeD=zțr{D8ԥogóFX/#b;4n7g	J~{4M>
    2~0üpwBü6(i\g'Sdjfe87/4FTpgTr8^D@" HP@f$Ƞk)OZL,XQ&sz󉈱]=Qė^yɛxizxMxEVM/3~~Hܐ65橱񤾱R䶾~7T8
    7>k64sno&iF[O}X3OpL;5o`V_1I'7F[ƣ6QcTCC<D?0WwX7>u!МnC{[
    4ύviZj:Ր^ܨ,SjSZD@" H$wnwo_" "-%!k"#''
    EG'0nÃq8cYD@" H$Dு 5*I }ldd!/9 D@" H$){_]"@s7`W H$D@" ?CΠ.	K$htF@eD@" H$D([!K" w"H$D@" "|LE#ْH$D@" H$)]{N-H$D@" H$(ND@" H$D@" " kI%D@" H$DQ)#H$D@" H$Ww9ɷD@" H$D@" ?;ec$D@" H$D='H$D@" H$R@GulD@" H$D@" ]ߵ$D@" H$D@"B@
    H$D@" H$+R@[" H$D@" HQ.]Q(4�79PLeU7azs-1ͥ(5/dgO77)#4zojj~ȫD@" H$?d6*)PE,-|_[ƘWc~I*A
    qI`DǀIyShmZa<JCXL<BtES
    K='P^sg.2HWk}|3|3==#빚P'V:4Dmd,/`iŎ1i1u~H-}{jU{&e"^H$D@" hT@G¤nC/Y'u$DZZY?@WO}q7E2 B7EB0׎)e̟i,8s^&Bs?<TUVfq٘4g$VWZD7NK¤1
    oy?|#fYUq?kWaY|T!JK00ά͆E]&idžƄD@" H$^Q篹8o=ظxU)ptr
    [ί1=?⪥s>$vT֨Lm~=Q>N;B0qz2<`km)v,xϟE~O7RU'UWϣB%J3!X:c=^Wco4,ųg]OOOX[8s=q|("^y|QF7&媫i7f$UqVKkVWUU|lsih,y8z8W`m/"ϼiuesOH@bR"%+.'aǚ]j%ؾ
    1gI@4jjmMS4hzlF=^Iqx2,|S$Yex 6%^^$x*J
    pTY9^Mtq;Y<`*S
    %U;~\gЬEs;z>'p'>
    rp~am/wZ)ɘeNOp5x,rjʲ"=q{_[{G8:8@(S'g~p	Y935UL%W{LWgکr<BÛ8}S	̟.nxVoێ`FZl2&UAVZ28pNma+;$AM:ģH$D@"  Ѐ>;>˗ѱM$V"*-MxOf9Mh<yD5H//O1-+A'Un%tp;NǦ./5O튓"wryLԅs~VwJshyE&W_I==^O4nǘGL:Øٸ-"M1Mة<Bq_qW^_K++eܙCwR]	甇œlZ(RXT5Kq%:�&b˂>u1;u]g|
    RP! !<twW|N	}'J'1mclql9tI37Sq/xhTLo/bp<
    ܸs߀J=7PysKKX5u�Eزu+>ǖ%9紴GhX�??vB'n5`TA6q<~P<<}%&adžO"'o=^a|+ƛ	n̓0+_OCp(,Μ<'u!�/
    mo$A8>9AÞBR|X;Fk]F㜟Kq<>NV(+3'[QaCÄqn؞mY߲}
    '.'qQ]cei>Y8.xW_<#D,
    1ꮁp3AWX$%D@" H
    k۫NdirXS_ܠuu@iQ&M"+TMˊq!4#<v)0/Gx#;=
    $X.Nj}㕚{4],8{ЮkV"-#UE;9Ehg{!a6o{%c灓+MмscyTw(\ܢ
    "<4(g#>^ȡra(I]$о2!48�1bMpuX!iPOsQBm#>v,Ѭysd
    T"=5
    a)ʈƓ9}�
    fN8tBzņRdeŽvQs3ӑ[P\I(**!1>ASeҕBػefmַtGMYR#>%!KDDnv^|9ehabLT qOb^G<q['mϠ	$?s>Y]۵*XG%jR1Q$k*kL,k6\-
    xЁƯ
    -h\6w)qO˃]
    ł,X׮ %3~h٢l,kkG7i3 [Z ߗP
    }Ygs`tiUQYI`%J/S[zj2,mPM}gO?D4
    E"!=j<]IC|rCC{"15aвslz!zE w{mQ0ڈ4x\DxOݻ2'{T03Ʊ
    ,J{7/zW.*\7d8ypsBZiiutBYa'v vڅGǾSvᨪ,ǃMƑp;?9Q^g`-iCT4"7Ct8Nw2]|g4/V-.ŗ(sUq=2}~�v4>
    @>3>Ϙdž#:Oʍl4FM~kk7D@" H$ЅQgf!�RT"gWtֻ8,_bHe[wwcxnЫ>ç`!sS)Evwv%^[}v[qØ佰(y|s
    [XN>DEu_QFHy>vmH4& %9IXd>+h-O`ւ%5 W+2vývŻ\�La+ık>])gꋳqMJp1U�][ɃxY	XV[%f<8nִ˜e<z?9Ib|VQpo،an5
    Sp0!o+4s>~U	Fc5pG=�Lk_A[HǺO?Eǫvhw%?m_awOwUEu"i1<`1F*8;;,L]jǎZw~>_JBA`Ud-K[xx"$.*uN9XpH.KWgaù#Ȅ-"dVx=[c'?t?p&ᱲ(_y}㑱m!P<><nHuەjM6Y9l(_5vnW$.ɗcP!ݾ߂Uxp+GòbGL#K!8xk/U}1lWf#{Gk3/,|]ne~|vLٟjơm?Wm=z#bhXakhسF_kWݒr	VVռmJ1/	9~>z-4P]{�R7 6LP5!Z7
    !DžH4)IsET_pw�3>82%4&jM۱-T|.z<i1�l-D`n#qSD@" H$L
    $UHZyoO2eه+?mڮ\)SV-~F<%9*>]	4])V.".^F9uxf}J|v
    GI/PbOWDZܹJ$սDRQJ	O*T.\dh|()Ps#J0=.-{Au,%!mkS<LRR+3s\pYIvAy{.#SJbJBZR%[cT^}n}l%!@)KWޞ9ArJQN ~RPXȘ(ǮeKr+_W8Ru$z&%p%1RK8!bEbveeD�YoVRkg]<EzQ~ru%#+[IMU^o2e2Q߱-k;SJJs')(iɗGFD),DIUTSW|GcR+;YD\Lyɗ}{+\:߮TVV+ǕD4E{(6}-x;ec/,TŦc|.xNFz\{rxrKI
    뢢BX)**e
    2+V2򊕼Xew)IlJA͊3”ʵP_Rrǻrb+xzβR2
    UO_iLImxlU).}qJ~NK4&ǿTRj3
    -y(4mWiQe)LZ]X0Cyu5=W(\DTTk}Q}YeD|:.R*>~UU$Un!Q6'2Or)^S.Ƨ*9i	+^@맕;ʅuge7unP?pk%+ͨfʋ(k?rR/.U%y{(U<sYҜiʌ	C5(>_LDѿ*<9cL-zrk۔g'|D\zLs֭!̆=Ej̎})]Trsrr̷D@" H$>̶	B'u2t^, DO{Oo;_:l<]8IRru	NF,0lwDګo>;/n!ضK:`C@`3$_9_.(4T6s]>41ld:ǎC0KK\3CA0Ñ6't<9)9zxH.6l<!>82)M셨fio2U
    %�]]g:VB
    <[}θ[�s̬ag(kKƻx}؉VaC'kȀXms$z
    sj5�CRwgLy=,5bԸiTT`_((G�|nJUǮ⚟|yV-1vF 5nx;aԬ{OgvʋpyvF=8GRpa/H, m
    7?]U"	:bLYnv~u̞m|wS#y[ɺQ/Zh#(7,ѫˑvIew9)iY�A!`ks{ssQcE5Y1.ڹt$�:4mKB	yʹHvEQR8\M[QͰ9tica/]sZ"CX.量jjiЍWEG-ޘ:
    #CEQHCޚ!D@jmh z4YvaeB8#xt"7\Zw`lZUU%ۃb'XܑlGI+ŧ
    3_6BQg$GhGj<~9ʔ pb_yU{97CeHAπX[!~sc!#gٖbx;%izw#9d#~޺Sg.fp34X)Ò$c{$b
    H{Z@b:rz/xq۴nyjPQ,NF=(h%gz)CX5UMH[ 8$ez@mMF" H$D@:bjJr
    Ud1>]:ހϏO(	pEn~!oGә2rD4;@>0T$.DzII	uӫK|76mފ6]Ea	VĕĈI:!=[-<x#:G'}*PYウ~dl;@+3JZMyjccs�5:擥uEs\[Y&O6d<TiN䩦	ڲYv%Kʹu&ޭ(N&X优u
    oL+:l૝A<:e	(Ƃ|N<)tN1|7WЦyK2ƼQ*K{j`Cƻ[dB.(|v͂b
    ;A0:_`MsU	ݜx1(<~H䔬{,H8jd濿^XMUmh!Ȇlg}w+xE6Mcy/]F$evqԊYXvgbX!psq$ؾ74#)	GLLJd|g?;tw=(G^fP46z79wk6zS"
     򒝆JU<J-IU/F(-ԅxLCx`K4*ASv.ص;W8w!E:&Њr*q̥-%]`eQZ`i£Z+eTŁή.4DGm}4w(=?{މw
    ]ȕ}xqnJؽ
    =D- A_"tҢڐ΍N:P9yZwd:66Tu*/qɗN1c,xz
    G^EmV4@>TD@" H$	zt}ba g/"e+9$Ԇv˛|*{:jEŸX[i	i<e]B=x克w>!D,C)Iԃv]T֪`agLډ	t&
    G~"NV{mXG8kYtIpuWPfԖ.%Cdt+XPMA)0b$ˏ'!o{1_+2Dyɕ;\w)LM=_OW#{;hZm0*	ʾ"'Bj]={[S"d,Nk[?.2<h:w[E(I
    qh�|kx{8Zp 0H-N,q&};I&|,:��@�IDATLT2s52m̰,)R/x(i
    #P{f:\?O=�OAF
    P^c`2T!ƊqHKKB-Hb=D-qEղD;Ap%!ŕƩ(%;bՈz2ddJ_nt9=εӸ el!B+x]싮훋x]vs$j*b	8~oph		͑x֛4!D ^T2
    3h I_ga71ȹ>sɮ}j2 XDۼȠJiX	K7k[wcݵ/
    3݀ov**H8D'p$^d#:I!CW	~ay[.1ݴ&8*BV6/"))3, jM#Жŧoa߰r
    ȺW"-
    f^ha>;ꗇ0HIJD5iUpblDh܃NYFBuҊqF`@ϥ#Suxm4g| H$D@"E@4PݻI$zTPSǐUrg_<OU?Ah`� އFê|%di
    ziVcǩxpB�F9xyc^x3V{j9>83Iת4
    kفϿAָvQg*rn^]1uk0g9Uc+L{i͆vpR9<[�&,R*3ۓdt$m^/o;R˵Ť?DC	>d
    ^#.g6ǻWNo%ruT=?ƊP4/mb`wubA[RݍfnC�,_wwcJL,r�|MI=&Mg.RO3gDcnFw~krȭ[9YWJ-OȮ\;#AMG}0ZN3wK:ӳ+'c+L@ޛ_Kl]
    ^,OSXُB;g L_'@;G*]ݴÃvy@eu{v/OƠ`Sqf?lqhj{L{SAQZ,=O<KuO~CEF]�sDz<C;1<C_6JQ*挞G罏V!^(v/򕴈~H~#ur,a|
    ޝkڦL3@|W	ݽUAT#w+8o9z9K1ebӸ{œ~TlkG,]ڄq1/H[,xڎ/=/J|[4F)gZVAӟH) Ẁa;+кy0V/Cf-EVKt~еC
    \U7ۆ	+VH£AvPy.M0Q1wG_Ǹrt
    A֭ѱuKTb>kIcհ+Ť䂎XU~&"M%nsȺ1{kr!6
    I8&Iz
    NH$D@" GniwvqDvD\\<P\e_ǝtnؚtGCaԝ_I\|
    7?Mh\!*%iD^-g8zwnL8y)';zvG[m椾CgE Z\?Lq$<{"?s"x'c
    "_gpU>ю&tSj#&ΎxMgzR6̞$[z[O]vF(щThld%3b0m,lk"7Er8*_xgN,ڣjLmKm _9ܿ/}
    5tjnŠ	V%(q«o,DvM5B"d졳^AoXmr;GގXuf>p
    CtPCjaaMNnbAHr/&YtpY`)dݝvyaʶm;Dy*,ЪUp+m
    c^IW/%rx~>ٗvipEk?>@_׎8.%ew	;ϊN*82vN$$@@I"\"m0nho`Rwf퐻Ơǜ>tUЮK/tܖId3Hw٢^R04q$Es&XH:Y9M60g=wÓܒi|7m U[H"Қ넶ۡ_ɰK?P;7@ޫ32ѴEKzp-f//Bi1Ag<sӖiN~H~Qݿ0;WϜ@rz&
    [JR*n,Ngͷ"wBg/Ǐ ܰGCJgM<A~�AB-	F$Aڹ#2{OgssL2ZpC]N6=JN@>ÓD`aႭSKk;eEo{Z;+%GGPd
    2Sp1gh׮=B""ѽS0F؇"̚:B].%ѷ*lTb_rݤYPbR((ѮS(ݷvQ#H$D@"/C&nݨuUHdLx׷fҶtY<5*tƺ$]Wu:lzu\CBVe%ٶ"W}[\̴'sCAr$0cY
    :slefT9s>lՏEy06FJ/cr%zĜq[P*"t6k,hPOr0rwr:L]z^$sʆg3Fc騃[#:űl>mG*
    '"-2TB
    7F!u+iǀ~y czjO.ޝ;
    ڷ^ x61cgmxfz
    x&!4)[QGNJ	V	ֶ^xXY`4pIV̋I6]'|Ck.oys:hlL4'CὯ>G{2ǂ<3L[{'ј~k/miF=kis;CAFI$D@" PzZ僧p.¹LLIyRB*txl(3N{UfAiٰ 	uh54
    4F,z6UฆmIdἡj<ӄsLm#‚3hڮ[.ab^/X2_dILm	Fm}Hp)WזSE0gH|st[US@NJgޅ Fjpa{pp~j@2׎IZReE:<G16%qƸiu;ƶ80p=lKjAJG7>K(P3`OFŢcux5xG?Bxc9r]88ۧuhxUzUp!䋕Z
    mKL顖w]焍v4Jܜr$c$D@" H4nj}bOB8t=Θs<h񄛧zh	B?̏Qٺ~z+Pekx2ӉSaU Rc9\_zPEQ"~tJ|^~>s%wvz>r^=oΓyzA5m1kB-zygDh.[7T۪eVt64R&e72?M*1aLEʪcC9k3I%ݖyґ+HwaFS¼\n)WPDq7֣Fi0mho(]sDZ\*nה_S^n!^ԟ
    ;cy,H$D@"BtI&O(J;qΥषgQvܨNsX}9.pY'jRm0o7"!H ĐIƤ.wc纉VΜW3rQPS֟^?=ӱucUo'g)80jF;ba
    	{oK" H$D@"`
    tUbAyrX;MlRMH2S6eP1<>Ma^}Oz~jLjN84m2c
    `z0Vh
    bzkmx|zjV_8ce`ZI]|b|ϾѺ
    O%D@" H$hT@ׅjr@V
    K`�_?x{|M2eKXу�c,8N4ijR]!(
    ZOO/a[NLa(o$!]:%b|fW/k̯WH222�ٵU]~g!TrEAz
    YpeIqHL̀wLtƢܿ%%,#|y^A]E1y
    	۸\WZ]4>Y�!	qqȢ	$l(paEIƢ!MɺjYٹZIљ՝΄a0'qtM#cj$^EZV><}ɪxhh6e[qaSPPR&?r,7^ŕ	E\//D@" H$D^ֲBEv5|Xt
    EY8X%k>Bh2buwEŦ	Y8ВDVh[x^F.繦I$v87A.:I*醲Gsilw~a=	yqq׽ 9qPeQ]ldѐ),.++[_nBn+6/lg;vUO_gNS[P	dloKKīgqdS-w2~a8JnƼ)	_	w#~*Jʷ^ŪMC>]Z⭅/SdQ!VU(M`v<:q�#"0a>.eo`ދȼ/ł'/C?f$`װji{X9^-w/y%l..?sѣG;3,԰!1:Y+&gYh?!~!1PS-߭"0_McL@t1|Awu
    -㇟`p#XebR,Yqy!-@-Ř-D@" H$D^
    eyx~ܶd*voG~A>*-KJ5PJniN솨dg6ZV^ZJq6-ΪТD;+8P9ŅydvN.z}W
    *.{ZK B$ŻuA�	NG#ДOq*]WE5\':L@5;''9{p
    kڞ>޳gCۇ!Վ|7׈vU=n0K,31`	ò믆Ү(-c;*iIh {AzU(WDJQ" wBM !JH='}k>;99{Wo!gf͚wfw֚5Y9yt~
    \]UZ:G3n-4p<zA] 4ZwM0=IZ
    9-6,{;'vattlS3fOxلu߀3uf'ZĊD_u۔r¹;v-C{s";5.Yi)P[sd'8+SX&kj.GCf~.nNLm
    WIrp^]W}4oj:&ǯ-ZaHu&ņ}g1oٳ}GCS
    g_\VY]F<9A@\>؉s1?[SS
    C" H$D@" ԃ@]A#6r?&|71n\$;6ïDvlx/#ܲ^=~;#)6"2^FcD.hd'_K._.-q}-mlS	'K}odb͗k`۰1JS,,_4tc3x%瀶
    jN:`6@sڂ+VDZ\ Ko|y7|u4k`O'M}]I?SPk]AX<[ͿwH޴
    [+ޟOj"rSMLFͭ&>7#믐W-Lt6sMw=;6">bNaWѺ Ye5h#sl]66;	`Kl
    ּ|C0Գ/y),g1Ν:(2i|,9R^
    g<]w),+	yp8퉾yh-jhi&QY%_p?m6I~P3յ3s"<?o({Y	:Afr"m7wtԛc;,X:=5	<t>MУP<;{D^r1ڇglpk>Υ@=t^n"ʌ0
    ,	i
    gbDH$D@" H$!P?A'R)?13ټ[7|hGEp`ۏX:VMݬyXُ;]e˖bqrfNr'1Q(ĿO0{0(F͋ѯl4;~O^.µXUT/%+k[l+tk'?	?Dьx\,?(/.{0ġq')ʲ+w7vpFHhuÈxJ&+++%0/NF<98b? =_j߮1,W#7:߀ػ̪
    z	?9
    +ޜ^#]	.k٨[_T8	EDRP*#&ˑ}h:7P\T$;Wu-D~1R7ۙx"$R;H)[~ă1(#&Oa_(*}۹%UDZrrrE#R(x:*6aީV\Xtb>?,}վ-iϼq܄ܜ8L7߶e (V6
    BNn	b
    [iYAxJ\t,-kE>Y;e+'o$D@" H$@}KU2{-1pn;vumLǏ_'l@3Bͧ	/|
    K^"z%,B#gdRj`uΈ{xݛ旯"GErFrb2Lh�{.x5ggl?P/zj(' ';%脞#;&nm""Kqn֖j>G.%w&-ZSڇZzZtNnc8ڪZIi .GA,QE.	cWHOM&"jFdl=~&t$hx;wHΘ>z4b~-8y�*
    ұi-*.\|G^Qo^:~^7;O%ueXO\^1`z%bo-Q
    ]{}I~J+.Ç0w~F䩡wPPUDF 2?'ރu:6
    Ŷki!D
    TW#VF\/&RMJKQ8^po[]ߤ-&=զcVz&޼>&c;Ю䕑ZJ
    |$D@" H$_@-Q
    [gOy5Drxf,{q8\ %3CfNٵw6I2yup-18)
    v8y!f=!
    	]F$q71ĻD(/+bf'G}6"gL4N$첒"{j!^y58;}:Uq7Ԕ`fFv
    oF%VUWpQQ_	kEJulAv$2]I{aNo//;oLoEh䄛HH͆~maRU
    ŌkV
    ,PNQ׵$sӍ{VX>G\-4"+7`gژ
    Ww6lSb(XDi
    #פgהB'̛z-qADA_&,BOLi`JkFi?9'sbeg7ܶxYG?-Y쾠O͜^َ?C}W(RG:!>~զ;}#<LWH?gT$FQJoN+!%D@" H$@%Ѭ 
    a$|Ԍxa"@$ڱ[̞ZK>:4̊GA-oTWdoA8f<Cѹ'vDZՕ*	"nAjآ$Z_'v6Gy1r+IW(Օ6ͦ`֎DL3s+XVdvo.).\Ӝ9ZT(9::Q
    Ol8OL
    [ηOFWiE>3Q0;}Ԕd\QR\KFՀkD"/uqw+nI(cFߪ
    QE˱`&od	L$'|\m^K&t|=�{5ʼnXUMU4xAE+#Wt3ܼV32q..r㮜¢UqZXSjpb8z4Ǒ=	Bd
    Ggl9w+ɢnG󳢸OcpߗThNݜd
    nE»oœqkbB7Vx1s^6F~H$D@" H$zxA糢X^U,/FVxs4ECo�@H+EMM话FeH'Cx|9v^C@<5,?y݇L@w3mJ_[vCO%ax8ڠ^b"�-"!6|>wشMڙ
    M,~%o	+#vޏ�z7D'm
    k/Uco•BmGel%jLV61'4oo>;ܶqCƨ*مN:[HQ'兛nȹ s*rîڏ^Dj9+TƫE؋Gfbv8yH?BZ6B}x<|M+cGEKMGgCȤz][8gS@Lz'V“;-|CYg]x+�VSg>ǎBhrQxvwSxӟѡhv
    ccXtiGc㏱O?ƕCu
    L~c|lشE(Z5b8e
    6m}g|RSD޴'~t2GęS"gܾ9z{FxǖUgBӆj=m@/?%D@" H$@}-h㖖srF3tc¥.V5n.mfDE_sjaDTJsNClm\{NM:c܈ARp-goWƑSu):rW/`kCBVI8Mܣm[q~s7Ydٚ_}iyczBL,G;macԧ#wܕ8b^xx;96ݽ#-jShr+wEfT)ҟ3:t鋌cQ\DL?~_PEI=0ykxvXrg4KL*q^|巈hLQs\8waC!m^5\Xغ7F{a۶hLӘOg{:@nQpM;aGxZ 2|\( p8}67g@&?Mк'R[""F&R?S v4aΌ'рگzb&JE|r
    -QOMXqر_y%3:#oܳGt9&l[xUc#wb3]:>,}[XDҕ(X9Mp CصmN^>Kȃc%_~I$D@" H$ch-GF*83/(,t'2y9(6"A[׎TJr7<&.s[^ZLngr47)�E\8qR%"|FJm&Rdff.^A窛~w^C(fv>ǝ mAD=?\S{ xEevo�ѭ%VS9bl8ի uPD˫M}tAp5aov#+p9awh့F
    Y(
    (x4t#+qh,pKv7VLeK>qV/4P?("Po-2I:aƨ>pwSZPGKEc^Ds@QS	|>["6*h<U]pV(FC&J+NY_ާ($D@" H$!%\ȐVjbI,eRGTϙzij(ĸVn)+Mp}r)
    E0/Z+A'\c],qI [9"1FjZѫjH 
    CkpqLT'~Fh	q]Q1:he?[DУlXS^K$D@" H$?$\	iI "_E\-Ff:+-Dq!+k]Gr9*H="2$Dz{civoݨY-1q5N\u*i崣ela]LmIoMdP[B2KSdɢhn+MA]zq륗ZE[g4L:ZMZgjf9*ZI-/ƀ.h?OGpk[湥Ez\`L:Է8bX?vgK$D@" H$A1$FLLNhQoʫKύZÇhLepiL9?Ӟkvy}qzojkzD_nGox\gGۭsQD@" H$D
    ?%S\*òT\22kcz{z.0Yצ(F6rj@ѺQ|k.̺kON7r%D@" H$TWVS00
    ſ)[ZJvF'
    \VXb9KsV1cjU<qe]Z۰p-5|^#4r/.8O|vk.w95Ek59jy9aA;?d&[a1WS8SqxJ8ږә##!tC#w4dTߏƮ?]VIOܯs<W,h羫c[+F^A!ÂP 95;=>j;G{Iɰtpp6Z뺊9am-ƀ5x>,u{U_8kۮ�Ev;<:~*F5JeBWCsHScuNfu
    |EC
    3MDߙsJufep'ڷ>@Yڶ%>iejƗTj2D@" H$Da
    4?~.=|~�BXЧqļIȳXJxqm4%~hs<}\F {f=^ZudRee2vxMXa-prpJlg,xiߵuEwOB(V\vP[55m⋥ĸ#[?ʞX`n_ޏ<߆KDp
    5L?"tR7J_vDžʕ!2֯߀y :&+x!Ay078{Qd~"Dh̽)7
    Eu^UV>Zƣ=)ھU^룆Xg2T58f2ƺV&O]H`YjGKc|z|Mm)H7Rb<	x?}~];jhG݉oOz8Z"amuKy=SY{4RשյVY%wg'Aĵq%Mv/P;b<!f#?NGCXpsTkD@" H$Dybe|
    t;GBs_+/kj5T;ެ\k3#"͉tp&Z*+|5I(t)4úJPJǰqI+,T*+#]
    tvBloJ)&:ދG|qR	J|<|dr9YVh5꣒jUP/WOPX+̢5YWD]􇟧eQe|/42OQuu)y"W_ţ;ڃιO?˗#<1SӤ%FC$~-CcԨ	:כq(#uR4?>KtTZîDBd@PJsEh%:]Mf^dTuE9{fc~}ŖX3%XÚ߽v}2u.qn-+-#NX�cz qyt\ խ8r}{R.X}8A| _*ykXc奥Ԇ:z`驥h%Q^	.|rg.GJV!>"D@" H$굠*sMԜqڷxֱM�~.2EܼoߌjsrAD0|�\|N T8s3v77{TZcީ5Y+qb>d4?
    /]_pgL7M|\Ei	k.O˥mнpAqv2vl`bf0wXGL
    q:N?Xb!Ξ#+g�zj2la^mBX$�OD!0'p.9[ʎ,D;q5Y#yc)6Dˀ+l;s֡9VWbۮ}),%}a	n<GD{y}c¸1s'F&܊0jxٚ#̬QaY`=7`'lftdML`o'b
    >Y9ye"I9~sG{5
    P^W>݀^
    m}&gêM§1ԇp)OAh9OGU~.H6_Pb"NAI5D^a1qpxt<{;EqY%<c1hʵO]bX+}QHg$Cԍ{{0Hsr'`([}i>Eщh䅋;tmpƂpoд=9V"ZSJ]^JX1d:C(.ϖљ3y2|ܼwłUhA1h\x.?N^gWDϮuho5׼D޹Wo?9~CFWv4e8s0riAa&._WP(L'pcxir]A?oo2pV:͞n8k;
    -�-;c̈{.O <{zwiаdaݚOQ#2.O1�	b.F\R6p5	B(cӺk@E~/x]t#D@" H$DjA7'qq~GU_#c,g2	ea64l8wFE.)P-hDuঠWp#!.&CV-YK潂V3@\>zF.ɈdfomϜ}:+$ѧc>%[X	WiVLlx Hqo%”U"\OǠEhWy|	7UO)YJ[u삡#GK&={S0>M͇"ѺsOX_WNV||,^}eC,<$k-Op<;o`ᲵՕ}7b9:D$u.
    IyfϘ)tW]`אUXj]>8
    tnX\Bh*׼HYU&4NYY3bK+AFfk+dx9`̠U,0~{8x"҉jIG쒒RUYD9SyPe>}ٓzaq^]c(?OR"^c$L6(ӧk[{r46;+d]<,]bS+XSxj8,zJ-a]]6?cin"#eE5~iyXN7ֶ	"o	<<==1{o4n&eرa5Sg1[T0`T4	CvaK+?PXGFeIVU,(}$L8e~4s(ȹWUYZOFs*/#6i<
    7-ΡoYFfaIn܊JcR	Wh/4&P*Ѳc{յCƑαK7DSo_dZpYaJM6-
    }E,QQOD@" H$ͰX5Mͭp6l
    gj<K7{}Ъ}Wx4-#pA!H?)͕֒JDHOKEN^<|a9<"aWo«L?2(&s6
    E
    ĤNaޢv<8A['aN.^ZLr}zdSq|.,=BܽG(!P,Y-зcs?w3 (3(wD?waj*hEbɢ7Т3<@VN6,r7p&zRnYXՙ=vj/w{t
    D��@�IDATZ�	D۶mkD3yU
    /돤$4s(BRf&ED|>D"۶hB?wI[.yxe:mb#p.+) v4^LȓB<8MLA{(YW_Vcޤ!q2<Q~zG6-jo{ט’D AJЗKX{xj`W!˦"?q3h܌b-�_B
    <;Ò}3seN!
    lэLHøpZY $&'B;bymXZUO4SftKsyE`c_dInGΣWOlsrώ#t,KƚբFs\�F_	7x+yQg: :6=w?^}n2xq[>pp_)Eslk
    LÐ7e@cXw>fa0VX!`9hac=ebvV&<럎lT4@7
    :7n.]Fn2y$9`5n
    zيgB@PoD@" H$Do@_ZADk39Y+1gz6dNǭ;3\̦̄ZGv	"aFDUx߹j8{xѴ%E/яx&sU2-2rngw�YQ5]2C&79gL91wTV r[ِ4J8{zA%VVhܢ*abhޡ3|h,D.p"$5u+ș PhU(,[U";i5Y ws;4;xMi~=ap%KJJTiN.̝"M8Yy"/C%�OWWU/_(gC{<_�xz	]̬lDaae<E8qAgU*9rcom"瓷,+RmO9xiRث܏Ɵ*e*˫ȝ\oqC;tD<7mE:r)ǫiI5(v@ۖИD2w„K܄1m̄).KN~M{×`e8iSѥm[_IqJupm	9nn^Ʒ7ϡRAic
    iE/p
    EhjNTR3E:rs0v$4W1mhrg/Ans5GGO[Ơ]#mSGfsv�~mv֭2nfTcd 8e{?cJ*
    S>]R̊
    WRL4dm?;X:ÿfv{'hzrmWлV.p8</x[MM2Xy&/$D@" H$Ss&Wwwz8D	'B~C[�4I`}Et&ŠHWR$]$J&rJ-Z3+"s;fJ[r&wx+[:61S"�0*~WS
    *&u߹ 1'^U:JZ#^΁kQ܉p3	/Jg'Ga0beLEA@^0F{	9Ss݂(aJ
    h&2#O1{4X
    M�wpB{Z C4j_y-k/c&M{N<*ʾ5HƲDmS?xS'r)y4-ېS8zo@Eơc_c{Ѻ]WdaBǐ]-O֑k0e
    eݶ<?ei1P	`Zeb&4TjKmtyF1)!j/d	O!Bdˑ[?;1퍟vC:�0fxot]@J1L0l3{R8Yz[4+iCgݿgv"`9Ymha*'!
    t$~KGDkjTv{SKx/*LŢ)$\m9B%yvDOwbXxK(N'KZ;
    iIHwɝ6"֟oJ
    WqLkSû
    Xݡ�y;lFeev,DLt0AclmGxGB" H$D@"?@-1҅sbxHu;xnD_Ɗ߇sp4n@D;d ~{~y~b9t&VJ"�@sX[u	.?'2:ZTVق]42Y#ey(dmsw�gP\^
    kSʻGUd˴F=윽D{LKxJxktbQu3&Da~أr)籎5=GO{`~O_[ɷG{aʝ0![|\�fD\*sq|2u"o UkR0޾t| Vz-KMz(D&k_,ڵMDjr"|9%:đڳiߴ6CB2t\1n;ۯQD
    X:>}9qznf*6^7<;i(Sj)Ehg]}rJʐtZt
    P?L-SqB(˪!15@ܭ۴@SѦ]6Aߐ@ҞD@!Ո=	*Lx'E|jZinݻ"rÀuN
    +Z)O=QF΢rKx�c㑟'w yH.`a
    H_!9+I1J+|~ĴGv�wC
    r5g#b^=:L~BZ
    aPlm?yk>(?#51	Fvچ[nT<+hY"] VM^b۪ŶZ3w˜�7o"#Z[w_PC" H$D@"FO-x=,.i9Y"}?|\4>E#$5@Bڸ9	)M޹hܪ+DNHֳJP�5K=As)--	u_`gqG7Ğـ>Xq4cvoK{ŭy*:}06nv0
    fyLmܤЀ�Ƅ7S~.F@	p#k@ؓ556dEfm(*87z߾/-4pTHM;*|$l*7qL[w:3z8Yן	I0
    ŢlPჱύE#hO4[W-m,d]}g*o
    w�"zɂ"7h5H"rِjYoա;>[0^~eyجXbڠ7{
    -�ۈ{Gq22GȨAW(17)(uɴaˠ92_hŵk2c|о-qCX:%8>'FN_@A얢Y5'.-
    zvi ך!޾^&ṗ 6z9tlӼp.9q1F}w&W4'w0~i�)X[͏?fB;›NK	v۶Č}0!ti鏘d3F>W Zc؅_/B
    JL{Q@EڪPs^[dW/z۸7?ſ>Z=wcbX;|~_gsXHӢԿٌV^0יӷèiǛxnx	CFmv9IO]l>~
    /_?fßt9>jNEyMà;R" H$D@"BgSqa>.Kk;r$e=@_ؑk:9™Bt:Vbz%tD{).$ْ)#bGQaiCDA\J"�LȪLg&Ҿgxyy!VIEAnDKLJ{=LAnN>rCWj}_/?J
    L.d]tq󀗧9.FAq)]\H7//HǧU=
    bg
    ??X>rskje縠0Pug;׵=Y\"r"o1"Q_)աz6=YK\іFp}eZB&dPr(u-baJ}2PO;P
    <=\Rڣ⬖Y7Z"@5[
    d_mqAWJ:O>-%4|nz\M^LxxH;*.\JgvS4 h?=CUܖjnT#wfMG˩b@$>h9L%'&$"X{^Ȣ16,LW,&
    6"bi),9\t:8y!{p$fL#ot3"11e͝;H
    LWOovjz_h+
    ~x0֎n K5ˡy<U:zx8jrxF.s/HGttÇ4oBgWx;J"--
    y%5juEyHJ&-
    7=E&',Liм\(Nr2&b~٘WHX3y32I$D@" H!A~׫;0`=Rƨmuꑫ:qϹMP!?1c|o )KK\N*pjOp/>~~nv"*~6TsM} 齾uX/C(Y!W9u`7?0:
    .`ԇkORsw^Nkct6Zh[WGyZx�QS5ULqǕ]G~2SsOqj4~Y>[^4ԯuWB>H$D@" }Cj\uu<MV)kЮ71Z9au}298=~M⤒~n(Y'~^'Ϡn5=ֵH\zr-ZAMJ}՞7?m>4pN,Az
    5Y|ܦ[uDt#E!Uyw5OkHyj|/;V.6EI3m	
    QE;<,G-LrBC
    }$+I+gW|{q_E[T"=MktUչ:弚(iy՞>5Xy.o$D@" H$cA7X'GvzS*K#Tu;!~=7.GQj_<O!-F%+G!Ѿ?Ӟ3<rTaǝѳF"_,kT[_?I\#חjgAƌ�U&K\p1uK_ĘQuoWW?Wor9Nu:վrD@" H$^קY%3FqO<7Ɔɦ8Z\I4,KZ!a1D]76oTA" H$D@" /B~4ZS&:ڟV_tLYnn8
    Z[+LKyudje]jsaV5k2HpQ^Hnes%�E̸խV\$cTAj,:u1xTseYqtz@cQU]#3'Oni(E^5]ָVA{Zt6|ek嵲sC,GkC۪&lk2Z" H$D@" MitUEvD68HDf~pkdKu=fbi%kp1DM0z˰ȧHGyek>Q:j{0G#J5~sqn?ԅ	z\㯟ѳ,+ztnCGZESh-	3qaEyV0p�xwE%yf
    kkKT;hZ7'(<EGuIU^4,	۪*ޫ}163Uؽ[T5lFeuQPiߵRs!B}[֣ȥ&邬H)G(⻶Qֶ`q1ss-
    ;f>OYM>3`ƴnv696X?/dN::fq+Sƍ-
    
    'ECY{?zsD\POID>/c!󷦯T{ܧwE+}N2I$D@" H$*Zi=BČ9sQ\mJGYmm;o<%mj]A6D9@Np׭Ǫ}jO{A*w"݄>LU=P3?a-Ԥ~5SS
    dsR+[m3>>>B|rx\YVZq}a},yuFZvCx3ZCd:΍E:=3:|IVtlѯZ]Fŧ
    \iJ1^/. ȴ(YȠ10dTJyDYOU7 !8^t3I_a4O8|-2}g۫Jk*vŖ_°aM䜓96�?,|C8j愾v2@$=<V6t[Qqezh߬s,=ߚuu繡9qWsnѨ=Z;BH$D@" H[
    |<7w&
    Wo˷޺	2ns(*)h֦:&0D?q3Ոp
    Wni�,l%7	Yv]D9ti~.|ZWxW:gd!':uA렆.+'u]*g!zEv=	9Č\X7@hOHT<qIEx&--mDEخ,Dl|*.>1abiаp	ęX`:7[pn{;,#;~§M}o4i Fo/f
    ^]_zE<xxvӦ{YΔ
    ôW{?
    {:آ[gHHSp#*m'<*Y,ĩc0>ޣ=QV+
    x')=q`:8;~(nߩ_6Yn=
    -pں}5:v!6siЙף.ػ™o7P-I2q{4_>6кyc܊r{ؘ\a
    רljb@
    \LǭLXU6`鄞=aUS'O!a=B嵅A_iIy0 :*,\ѣ{gTeP(1E^і	s.A-fYٺsnhԗzc
    TT.@~F2-܃nD#]{]Ԯ@zXD=[}B`xc;~>=ypi޽z%^zY43h¸7l>>^9<]C阺D>Hzw=|";:6^wnb߆Z4*$D@" H$5I>
    S3$ܽexBH&7S`FMĞE)bWCLyJʅ;E^F!pѥS(vTvr`G!VXw�Eؿ
    hE1et;dVi~ƭQXf6>'ggܸx?n>JjSQif'Wͦ*ehŞ瑑#KWCTd`欗p:I6CBYIۆ^;ϼBY
    s+K"EtFZ7\A%-<0e۰R35u*)vWΈXI|i1&)崂bIĸ
    _{;D>-DFcIͯ?Z
    G8(7"V⇷&E@_\|\>
    ;N\Cii)2蘹ܽuQ+ĉ;+;%sWㅮDNKAAQm@Zpa^>bk8qJÿ m,m‘>7
    P#p(@N
    w?998Hsxk2LA̱_:mLUprJ}
    =ztU 371LVaF6}_\&{4nS\t^|CHn;U?F?D^=0k'xGrVcq+02zN09Gu)v
    >ZVvOKWl@V~rbص4AhZU-F4+n@={RLJdnJƯТ8	SznJ
    ]6ͱHJ2X_$D@" H$X<ȥVӞV2P
    3L\픓QDR%/7GIIIVn߸02oE^ߕA#g(i⾤HPSYGƋLUYR-喫+*UuTr^(+Q&*qN(X*;O^U*젼zm-Shw	iJee h׃Ey\VJ*=TUQ)驩ʃʪURL兡aV+ə9J9ɾ}VicC*_Z,{q2õ
    Us8U+~\tRR,Ey{oJqIÕ'cteԾQj{ה͕C*v,1e%Ec5YuU%m7VRMuի
    e)~Uw(\ oM_1GgJNmwʷ4&E㛩l%2>YHQ<Jg+m,Z񃒚G*U*
    ?yNy(f/VrUt\VB
    X`‡Te`Uu&)/(raJw^uin`(e|(e93sPNch
    ejj?_PL]uUE"l$R┡-.{ި@+lUSOWO_iw"vWBqdCyۏe~2<zH,�Vʱۢ^kJw*{Z-Xp*KP&	%%''O)ו*-S
    IywN
    NHQ3n)6*9ywQEy(Od4w(K{o'D./]y/.eʏQzN[$/JJazD@" H$D8uql["Oyzw><,ɧ+pi3^[cV$k׬AlbqpO$/KD:^Te"wbK-qΰ4Whצ%Ԗ6(/,&kg-~xkrq\ Wr\>}�g+	&#1r
    V^m c;�*j{Q좨k⺊mZVlJ^$tH!!	ޓrsr#ݝѼ{g̙s~3r̙\x@<Z\Be_5Gl8kK^N3!;A(ܻ/	AAk0b'dhkCdھGװS�vT <vTh51n
    mKos{SG3$Rl0}."rPzi"xե,n,<Auցrsr=.q̗/5�mN6hCm<�^;
    چr]G#}6\6O2ۻxEH'zZO
    hdo\=?
    ކSpQ|ˮPjuk{gwwC3N[Px.&LWi\1rVF .Js_H^FeA1Д>!71431Qw?,x1$jo`l|F'QW9=-}pv&4)N%Nh˜@s̴g (.2T.A1sQsSV~6`D]6.Ə@?o7j`\|\ٲIMkp+94SNauo=B#.i79ʪU" H$D@" @נa#.*>StN3>xy)
    5p[^c3vtl:W.N8^wX3Ơ%0v1D72&l8=6hkB$y ]ݸlU$ցY577G
    ]Wbz
    &|s>#}qFuGnm6y^h fx̞�Ih4`Wf;7b/p$mY	o܋g	Ȁvuq~ص0 c̭UQ=<E`WO2FVFWHxS;>d{yWS,;h q.NpvaȚ8.ÕWAaa0ԟ y7tSYbtm#1^x"Z=`	[;q9BZkl${3Dő1xP=
    l;n4HA䛨_hf1D84dЎb}Hal{Nȃ&jy<o?<r.6B(QՏ|D vf,JkyDa"]49?܅q8v|=/".${{ZA{cw!(8ͥ{@mc4hƙ8s~:6ⲻH]Qi3|2
    .0D;?7oNuPmtyH$D@" !ljw*4!׎]
    GN;^tS&ODlx01FlXl-FaкaȎrFaժ~wwuG}YPPUL"c#7ac"+G@(|ҊF*		d,BiDuqk=J;W^s= ~cԵF!î8 Mͷ2W'T@If+hn
    (.EXDɒvi5Y#o&&it7$$vKxؐm	_=Xćhƹh,K567tt֝j%l󥣡BlmۤG1QIh ch0!f;IFڛa27'>ۃ9ty?~DxAmuxn=_9t҆{w@o
    l@@DFFZKF"J&#AqpIZil&8@%
    D=Ɩi sB3~uKg5lxݱ{NK<pelʚrء^UbZka6,\{VUՀ$zzboD{?P474Z%!iH&1gl8kq9tЎ.@=89~
    =]?D@" H$eN;慍o܉?vń^*ۣGM3gw/})7;4Uqq
    7a-r(nMn;e؈	fH31fB<qطM8/_[&&
    wއ�G}xb0sTq0Taم#<^L
    |4IA
    
    Lt&w)s`=2v`ڣxH ;4o<6vR=+pq]t$Q:
    @
    4Wcf҆|b v{&mzѾvx~
    d.yˮ#x&GƼki3C/d8FQ-VRNxV3�efFMūO,EVZ4˓p8߄-hgӦr*3#rnFVbĤغ6Ƌ+OM;ys؁;i<鉢0?gh%Nh:yDY4/GHgGɃCCM3FZzXK+Fy0.ld�Hm«üvyi<mDvoe$f�-e�xi�>'9;i	MV#%y2~J?֗Ȇ/BFu3- &4 :Će"1zʠA!琙V=DO94ȝ5=U" H$D@"𿆀}Z9I8,-][n|TWdÃu{s=dېo*\<r1L4)IGOc=0m@x{(0<XPNԶ#fR݉g'Q`eU
    pAҀTĄ&="
    g_SSi-{rk<P(>Zb2r:aC.bF3nzب}w!\FO;h|'rs)֠ѤΔ*(9ù05LHIF-'fvpD
    Iּ}jˑ_Th/4P4A#M"uxt
    _Z@zG͆,S;&Rb\[*M13x Q	&4CC(t^\T
    6!�7,uΡ8ZRN RSSL;54^Z\vx %,zp Ww022I'g+<L:wr
    
    GrJpW8o7@|R
    .1ݸ
    yƶNpCT?UeBػֿ{Pw{s쉌#55Fiu+•kC!y_D$ەv?ɠk*ېHkɛq	vs[I"fa^<^?ѳdz6>aE"4t(ԗX"Z?GxђoYWybQ[.>A.ږejk\.#6>)Iio@^	Ojƶp>L!iG]pNQ0,sxVt@|RWDy:D@" H$e1UH,v])~>m
    k&Q_H)"hu1v̳UA}S,bM&bQeƵtjF]i19mVVqho[m\09\4j#ml&\O4zԴ4۲z}^>_um|_m-Y-FZzA69نrZ=u}{&UWrk%9bKo7D@" H$1Ni3lwm`Ñ㚃zotmWqM;\QEb^58X-iW5_%|EctOu]z)+[-L7NyZ9\?NZ=A"t?*ZUyUQOtTe<U_>n&"2(~fzKy260Q
    ˓a~TmYgAV:<NnShS*z޸_a?	+syK}'"6`>~3r=YWMZ˨>,Zxps>{PފNA͵ż(T^ԯD@" H$iNk3:1>rjeVuiyZYiAMQz?s̩qƓQMӕ5,s1jB+Ǹ7ͺK|ZbWFkoɡg[9ө<tZ\_Os&ןОIݒF" H$D@"i
    t#ZUlͪV�٠5ڬ'o<b&*ӧuw[Qҵ8iXX<KzhlkWfm/^H/'0;>r>$RH$D@" H"pJToe(V&gi>\z#Ӷ϶ξt89dݭe�%>@mƭS}irn_jv8UtlΈIhoLg"Sf٢nV'U$D@" H~'mW==fڥ8љvAB\,\DÆ&lЄt3fdXX"|{6ɈizAX];:Lݝ]$5T,Y:r}^ےNU҇xIlU
    61qF™iZ:~d5X$€0a8–U>D-$9O7{oaanIABjrۨD*ǁ!ibu:gG=D0^?eG]S;¢1*sD�c[vM&8;;Ņ1:ý1)1()N�GsqxLODǒq>hxUՉ)x]6ġKyut;6im6~q1ڽʹzpP�ίcZ_<n\{V`ӗۊp"Ysj|O8z&r^F4B
    sdzuS͙n6m_nT4�M_wAڂv'L8Nc	Z5{SԻuoqYc@<t/7(,E7&&ID@" H$Dg {,ڔgט<m:6܍>CKgpX@jHj:1U%Z9*6T	8ބw<8}1/w[|6{GV>:4O.#r[x0a_U-x<g3V<F:z;\4ǔܿut:Ro&u}{'%f(6c:Y~wjMh}DaL1#݅բ^:?|`~$
    ̠sӋ` fn2`
    X~}Ν0<l۶
    V}ZK}Ztd4�8}ف|&1]u��@�IDATØhb޽jʪMVd?GQYе0[<Jy̓q M
    W2j#2#
    k?Cl7݆cpt`:*cҭuCy}KCW^W!?l<jAUyOXΒ`3ByHo
    jyNtmUD@" H$Dg#xݝ-|}XrvW0mHL9WQ(Cr:/IqlǁCfDDly#Ң4Lg-;	#e%EFƴtXOc3 F<vlb3'O	r*sDtl<b"CDdDQQ3tV5/m0$N|#ي<6r6y·rrBQqHK8{'Pv좙�9; g^lu}Co/asBhS(;v&rmVp/*>ߐh$…gڭ񁛛BD,u	y;+IPB.Ǝ؉"TVՉYO $YtzJK'
    7Gő㰣Ss}taFYfF;;#KI~҉\no?[ϟRo0ϋ1'pò۫.K:r$tuv~.C
    QRiٻZpn.;.$
    (ځ9YIAtzQ1ʎǠAiry\=8^GK@Ai	8DFaԔq뛻qOEw'4T|9IIgWp^!)¼82
    UIz6ה>s�t֗lOwҧ
    3+D}ԷcS*hmFEU-]Q]~uH48"VbĘpѿglWQ9%%tJg>+"[
    JL)߮++aU::>%έXêKei~&8ѹ둈F=HFIi%}yӁC)]m:>:Rx0pjg'tyb-KP)E'
    y,JŋA" H$D@"p8<H/r搗	LdxrvBh;V:&_x
    L54mʫ;h<C\*vxm-:ʱ?!%+ɵ,g'edas]ᙏv`p'R^:_}0*%
    n^Q߆'VۯZqټk_#mXbBo*,Ttaφmtd7[ojTĤEB8
    IzڑՈ^}V<}qd6;oV翼a#҉?G;aD[Q~C
    vl:x}لKR:ȈbP҆mkƀBls228{`7o↥/ayͫ>ĝ|Md<m]pqS(ki6W
    y0WV)i0W㽍6f$jޡݶ
    o|#3A=GlqiA:%7_ɳE1,$bG/D<:2t\ܽ<�.,FJtX#DfCt|O.qfނ-x0}TtVবd%rേvL?d4ƭKXywq|aDz
    6}7WرcWMO|c{Wa_	wJ\i |1_ʃؑ_1Y`òz{V'_CtG,ݶZJG9tΟ5d[_-PՉxQ•\eXtյ6u>:]ޖch>QL*q98/?�rwF|+9ܽO�[`}_yMXs|f/#16+}aOѠ^_Y'r1sr:J⎋U,+܁WW`ꤱH:7O˖He
    vǢ^ǂ#
    _2~5xSk>~?P;Wc2Wرa
    ڰ⭏c܄qrNՅORgf<g;\wΨc}!%}f]pOE !s:&#|ޡ;D@" H$i[>aeuVJ哗BD%Z9sΔ>^9ZRT*￰BX?QOFeG/p%D-W0"eO?)+n8G/)ݔSEZHCeMդ,3\ySQ]wJGliPʕzVn8A//׍T-Q4)Ю+uMʗ'=F_wrJqO+Y?AC"^WY:WVY97o>ğ{Rҩ\yʑj]lS
    ??kTFr`WAuJakhQ^{%60!WtRQ[=,RYt4(AB^CHM>vBQj}Rە:aP.%@RU[ݪ̟&Qo{CrEÕX"0o3\ʎo?R^rRQ_ʢt?^yS/RVI1R>)oYͣVhɬt46\Y-eǪQS*$T]ae0˿}JDne8YW]3
    R(?<t;?a0Gh2(M')vRnѩ
    ]lڹG9N<qXʤT*]rDRY2_7r'T{Ne͏*
    '/ܣ`bH=/&הnSJkԶZ;'\<?ա|s_\I9VVЬܽ*6hG]y{FaeJ&{_+m]Fv%>RԦ4T)WS;?ջT_.;ڭKY٫WoQ:n]-PQY74(w+Nzieu*V(ҡ<'JS[R{"W問UZ.o
    
    3K(<4cPSomW
    !JY'_VP&Cȧ?'蛔;
    U\L>TT({yTϛ_oey$O(_l!mS|c6(>rrm
    -JcJEuҭ>f6LD@" H$Dp<'wo}~]	cM	
    #F_pޜ+rn‘|V$G	֙Sѯ>?4Ǝ[y߶H8'7M?a(l_5{6Scw?]}vM{<<
    xjsS7}yJ݅?9'<8H	>_7�W& #-	ɩib2ZRw{ƉCז"{6GU_Іe=(>Rݕh⊀@ޞ@ dz3u7{FdQ8l&YH!l9;Z*Bq-Oa!b1 \Ӈ8~vco!qHK#t<JQӕyaFlU%9 6e뮼Ii
    5yMرq/\\?:A3ݨAJ6pu?dg7ZrU
    /ƍqyh֟6ƣ=r93Кz-~Fk٭6{xxݓk0I:ƍ#<0M\;ŋ2x8҇}Mh<QCDUF3}TD@ֵ+
    h	g]"tNԆw0ҁzKD-oV~"t/:A.-ƾCː>/!ApSןoO߃f{)twua٣/b
    t5V w\眇!.%&3i&g/k%LnY7\.!`aؑq#&Soo/]R/tTy9Q
    R9Ӧ^aʄ9@HŨonǿI2
    w]N@0``
    <ۉ=ތ=Ԇ]h8!c�!q-8zx6
    LEK~ܻgS3Hqj\J.-+s%}-kﵘJ$D@" H~ߕ20pu?>ب0Am2i7R:;zP/0`">
    /bt9z :*J
    %üɋEg)ذ{ZO>Xp9x-C'LMx?W<f$"س\ڛi͹+.n9
    Ms5[]Uo_͗1mT5ŝd^Y/W~o?{x}jL4bik4Z[Z2
    YJj;pk<]in6͟nZUMk>fdmEpM@q{E	'wgZX02}b*{'tq[s,3ŏV>AԴx-b
    ]*w*r!^~3̿t8swe ֊ӌZ	Si}~,hrkgnxdL$[Jؑtv6 /X71J5|h<G7`en!؄seZ˽ug$2ހ4,	HDK5ߗtSb~4O2*d*=Έ!wrxJ+
    vZ2pF#fqjB7=Bygr&"1!>CsK+^z.
    G[ißDhii-dYPg)Pg5
    ޤmK8ۉ/hZL"E=t>M{@WևpQVŌTpaLWa&xޱ�?\@OeGH=1X~@HI:s\IXn#C(/_x0bd
    bbïڲ
    ii L<cGfĎ]3p6"\qyRek+ܢO^1hsݍaaruq$*#-N%BD2H$D@" HN@:6VJ4:gˑg3٘>yCP2WoڂfŇp31oKL믗#J[8;K%71o91f8Ekh(Z'<TM3qf<�&fh0R>ԍd\uuc`!*`jPl~"300s
    FLcs%"
    _ۃ)d)ˆ�=.s'9/}j@Bss3iS48V]nl0VB5>2n<8s
    )De][%לpuZh79ˮ|;vrk.[Tj'tV̾	\{bmjTfQɐjnUR�;n6pYxWRFdM`0oP1h/ig0
    5kR뵢4akoMАlpqc
    iu\!Q|q(+B"0:5B7aC;{nV�A֘
    4PwBYǘ�g^=uر�H($/IG(^k}W/2۱n^LH|DMmG}[-RW5]ՆStf3%ǻ	lh&/}~~у"i쩡˜Drǧ@X#,)3IhY3DŽ\i`mԖ0u
    }W{+'4>#SutJfkXq(Qy}8?g܄N2!,
    )ޅ6+(,OP@N0D@" H$3@_]+֌vv^dQ)fhs6p:c΅Ұ	x4e6l9 Gva§?'!ψisF#bLJ"(~>y6<vV78#�5huE)y#C|lݽ0KϠ~	mMm5Xtd
    BYɑ{x
    Xvǵpz8f
    ZLq-k@Z/6l݁3f .._q='0\bsvG!�>~?=�\Gb\f͜sMsS1lH�49]WP2́w\ߔ[Nv<b
    x_vbNފk
    Ck=F0oj&Z	_`
    !rDBjVv	/-�&|7"X13'lG_lZ~^Lx>w0;puWEH:^M3ZDCk5xރs'$cKMEF
    GU;v"~!#
    $ϯ~4{I\;T:h67g4{6IW~!d׭|5̼q,6%0YTF'd_Nq:m*Ѧr=8;Qc]7+oDq
    q-VF^2#mMjͺ8z?I#]x}%b\]y[7Ya~OTH;iPRsbv(Fb3+*Kc<P;pтB.seFyW)W10ƒ=|\j硡�چN!b18&&RKn[w痸1y?*K>3]āv?e>w̸v0~It߫F%ϼڼq%3u9[}Wƪ2O˯*ϠD@" H$!@?hKğ쒣'zͤhq4h-.dQ~;1hƒ?B1s2F[TI{㯊h˱`D:Ȟ%Kؑá8{i0+r\z\UHuƴV<W>)iPPxɴ6ګYDĐKLju6b4k#RNUh2:ʭ]sMڌpr?QzhK0|*nQh.GYE5鈫3!­	D7RS 11~HN&Nu]|PIBp)V8+
    q)h}4V"elZ@?4TlP<0ĴPBA5YhLNǵ‘ve?%2	>!vw@(&&'#St2iCGbڄ,:ƭ!)}<&
    ]L^Ac5Nt�$[+Aaq9b$2҇!زspQ5e<*Omxg1aD]ueV1t�]"5ǬGȫaaC&LARrTWowX$~TpuWUȘ<q$;
    ”q(#[1<-&ɤ]]E 	~h.H�0QUgWLX0g
    jKA7"3NS)'Å[z#M@\l\h>x7	tT.@?vI'z(.o+p鼩2vN4U3:D}PppC2( Z"v4L}2Nu	7Lm^!&k"bhP*( 4xU3Q5/�
    jO}khG)C2Gg,J{(qwtڱQn^HxϚ1^(.*EL1|ILJF/j<}0:s4#9>KΞԧYSPET6"0*cɳ%t
     FfbA޵ OȫD@" H$D>fj+Q^Lk[+k6
    eH$]
    z.U˓Dӭ>^ZX9"o@ngظ=O=֘e##WQp`t.:S7/l]>0H5l렿5wAծ*jXVB\UѦѝvtkujWN`WSmӭ-s8
    jMOT^CuS%u$Z~콠Q)Z/Z6s~4;N a>w<woNߺN5=Xvf5lVd9tuc#5^aĝ3vՊZUɖ6nUDF$D@" H$} pJw(yF57D(i^O攍8δ"P9._UV
    0JH֗S	WW05jZt2q.d<lƖވ|MF50fY.i\NpKp!']sJG'3猱'EJӌsU?k9Yծz^jcAhe$-nZrПfxzԸ^==9^-}m,*5}?QU#R3ΙNGRv^)S_7i"5X^^.Lj1V(G\_,|	Vsܪ'E	g�]ofm}\W^A)m$tثqsNn}H$D@" )gй}2:cUt5wWx:ES~^^^d\PJ4tC7Ѿ,z=Ժ͵7E`9k	:z?8c><9Ʈ:R|QQhk<q͢3Ag:>9tݸt2k*Ε,`o4-TvUU9stF㦿j2q2>o_i> -o0ӌ\祿gV!mT|5j>)|nty&/PF@cј˫D@" H$D8~<~ۏZcWa_D51_R1D@" H$DS8Fj[rbk}`̤qGDK$D@" H$\~73J%D@" H$D@"pXu$D@" H$D@" H~@"D@" H$D@" 'H$D@" H$_4hD@" H$D@" H~mk#*I$D@" H$D pc3$D@" H$D@" u8Q٧4OUMrH$D@" H$D.H$D@" H$DwI3֮͜߿;ltt5=Fs4ηyCUϙNϻ?f[N3-vr}kiZ?V^㯿._O}zGo~:ڽve^|AH^mDTsNM	6?k[&^4ET+N_9}q&}v:+3-w::}>~Zo+O_G_}ktgr՗˨OWʷ[w˟i>]A#>?GwIko~:;{o~ToVwOO@\\\ߤ'#6440L,y/H$D@" H$i	6CPsfQ.S^H$D@" H$BMo[zdD@" H$D@" H$*tq?*d&H$D@" H$cG
    jU" H$D@" H$G@..?{%D@" H$D@" 5@?k%D@" H$D@" =@?{%D@" H$D@" 5@?k%D@" H$D@" =@?{%D@" H$D@" 5@?k%D@" H$D@" =@?{%D@" H$D@" 5@?k%D@" H$D@" =@?{%D@" H$D@" 5@?k%D@" H$D@" =gAQ7T!SudnNoPQGtƐyAi;n`Id=`~u;Sů56_bVUSCmtVڠ?~v_hII$D;Ǿ-|,EmLlPףuҞ~FPH$oSU2rsFDgX9<3Jsn&	fJ3G|ɨD@" H$g)
    tؐe9cg=ߧg\>{&h8eg,%:e%5q
    ҵ|2
    ?;E?RrD@" H#Я}t5F?o~e6լ
    <-_c�'
    PfO	#dcǞC튺
    w{{Ϊ{z[纘wRh&ތ[6##1z08*clEG.,,}h<AQ3ntKc4α&TԠ-urr|}`/Tn;vc,*WWcj~P?yNE+59]K{ۺ8O4N?rw̘1aSRgxދFg=(ܓ+rBw11g*BbU;dN?wˢwޛA'h bD)]TM sBͦaW}\N8	?jEԄ6堼Έ&CuUQ>Vms$tLs?+lDTrFd&•TLqYcMB՞m?$w%lk4|1Z
    (m%9҂8.\x-T*JvtA!!ps&f caSL"6srqGpP\H=&(uvuGxD],	g2t흢ܽ=?WmuyF^amߑ\^Xo
    '5Ed^zSs@}:{p {~:T$L7>NBfGxV~ܜ’ǿ,şaVOi=JjK"<1
    FhԺ\D@" H~?}>Ez	){DfP9i@\CNG{әɊ֨|֣=D+'cEȑ#yP2LP.՛.ਗ\b4}k]rc۞ڭhX
    oL[z[_Ez4uɁt_BNdTQ-8B?r;Eu
    字VyvWEKJM҂#ߥ<ߕ:}LéQ`r޳+”JfS>ߨ|ڧTʤו[Tc:
    ]6?R?ʁZA[ݪm0tF.dxjijVjۇ9ݕdݚōJ$^Vh%5wL]ʪW?'<.Wxtܩ�t=kwLt*wТ>F=rTٞT&9QÉ|.Vraɫ?:u#JuN}2Y۔EsGϿVɯld,#?sZݵ^9r>X=߮\d+p_V+-նW(oQ%Q'?<v]l3f%Uu:k7R͍_ӌۣop7[Q:wI`c7}rM5vw{W>fh/3Y
    ͡DYrno_t}(MUW.%D@" BMSFc6ӧ�ncz%m-3=ntvD}>XfSȰ3gG3NYY6sw<p4Ejkivecp26b݆Mؽm>xUlWqCU>pl	
    ^<:iT|~Č\lȲRQ5:xdfy46ӌ"82%0xၭ5MK?	F܊WpQN;޹nHtS0uD(7&l/}?Cw2kUYfIwa(.]bۦUeWχ3"s .j;D4[vR?dmEx!HISRhm逫+sƛgDno2
    m9љC
    '`3N4B1N">BB
    O?8K>?	^j&]o;?;mط|21^4˫9g h:!ꌯ)#y'gb́3UӕrCV];?_jwEIT_JNT~"cG3A(S/dRnAx{Tvi(/ij.;6疊a<Y媒xdܬ
    Q_PVVq^h?do[?Vܺ&|En~vx/*,rE'QH3ݢZ7~cgAah$}H
    b<8h3=oP?(Ϗݺ03'0BhC%ĉtN=\݉ѿ]mprlʊ2I9ɁRg@TnxW߰a%eD@" H$you'C)ҟiQQH6nőc0Ii?q"}wӁ\2oR#;�0zD҇PpHfDDDK|'\=|DZ%7=@;|qkJɽdw6b۶{(UT>~H#G!*ď abCͼ$t`?bTVբ	~!yff"*,Uph=HĄ#n=Jб3w%F1~U {n),B]c+C1dh2GZslڲ10i|@l-
    jrA!u®5h$2?MӉͫqqLr@_#Mؾv
    8{+o/Gx�;qn76k_jD=ܕPU߯C04b 5JbHD:clBq؎qIӑ5bXNPVrvރډ(
    BL2}Y1cijǎu_cF1R@xFulÖpbR]'N2s?+;[wCBws5,ˆ1 !RG*Ї5{h|쩪DΡ:Ga9Ð;;+r
    !A6*	,zJFu.N,/:
    Py>Mpp_ch8%TQXq).á}qrACnhk=8SV`-<CG~0u`vvm.DIA<ܑ22Y""v&#rsq8E^_N'L>=Wm)Ǥ":Bu]gO%eظ<іɃ~J?'U{g#!.(ؑQ ݡ^VzB=pd8U0<JvlǑupaȜGؑZ%y{QR܂?%
    :l_Kis!<N*).l(!nawĄHK(wd4f0E?^${wiò0g4SR*mx¿I۴^>N\`ˎ
    }xfbKS~Ǥw(QE/_l¦AuW|W5/?t7zjbl“1o$֎蝽޳pÐ:e2{_XűIHB<[hq-ҖmR+;uKB:B\ٻI~߁ww7gfΙsf6_)bqv=r۴EоUŷiNƙrAC?4oݺt;8|da;Zm~MP_Jᵤ𫶽*6nފ4
    
    @˗P9%2+Yf;)}ѱ,k8o7~8qÐPMyIt#)zDZe&DEqY5"ѽG/Duh
    ٝ`mc?&&&&&&WT	.1;jT+DЖS֝J۳~G|ܯіn9ҜM>u<kղUm{蕩ZNAwbzk<^wXKWJןTy4v(>K+:0uumOhcST~ghaMt<G^{EAƘԳ>NJ4^KwϳjgKUs>~g5ugڞw?*PNآտq=q#I!S{m;o&hRZv{{Դ_W4KABE:Fʹ7&~mޱ[;KZ?K=7iZfh	iܩq]us
    ʵ5ڶf^-56ĒV)sTipWfnp%MֻW~ٰWL".?|Gu.>ZYiI5GԭjkWoo-MR["l1uz!/i6x^{_r+=l6E3#;^\~;o1mZLzB{@OƝC��@�IDATk6h^xZkg5LT[iY)^axC�2F!.32I~݆wymtU2wfSڍ
    &iQ|%h{jW7M;FںV6hT!Wql6|	GSm_|	/״ni=YW_]W^UږEᘠ5"-OZ{njvsڱDesyo@Wy_^~xo<g/hSmҊIoܭ=%l^P<Ѝ
    Vafcu7Eܕ%Tdiq-ܤqeil{Sq95Zeh鳵o>2B;o),L|Z=,mgji5Hw6Tej^kZNIzrүzۍe7:&9j">8򮻴v
    h	[kZv61V:?ypUM>Z5`˵2kco%ok1T~$Am`G
    ƅ<\ؼ/tz:߽|QDݳa1oȈڀ,6W:Muoam@Gɳ{emq-:HJӇJmoUܧ%7\-~w.IfJӘ5i,N'ӴS�ۅ|
    7h78VYýaʛϪB~w&
    h*o&aw+ VONţ_;JHݾQO!ڑذj)EŴ:WӍ#1	bB[/|q=
    ad}8Ař3qi[1۷m<mq:�Wuz=)غv1?7ZڸLGž]?bܯU>{sH#Y"Z0ozj<:G"2`6{$>^]qݣ1%+@e9bO[⽇F0>O?a+ƪKpX4H`'Tb6ZwEO"�|=
    Qi1F
    
    Nl;HgoIup[:oi^('Ds#f`}qn2<7A]~3*ńI~3s|pm׀N`L+9e^.tl7">FHb*Gҍ>is_vpšRO^``z:IzkyT;f'ޏ܍7A؃lDp:	a9};¼ϯ5nHM©c;cS{A|Lx�
    
    b0@ :;olG[zcڌ8|$q{3.pl䂏_P2nˠo]l4䪐ms:{Er0
    S3|"}{ooVub&9sޅx5ztZ]5F(7l#;T^BhUx8ޝu?Yp3&o[OaǶS營ڒ^nxi-cE*z6ދ{
    F'n9!J_x&nsxю#Ľx$aH]ҪTVzESkյW@·j.ٿK{ggka/Wg݇:Nvpptˣwò_qϳԟ8A^Np˹i[n٨[8{;Z~to><ܯ,#=7\Jt&‰2zhȌ=nV;,ڰwƑ_Ң|^:iqX~+~2o	^N9_�	jkXj5ݸ7هPy^9Œ8smO}s	?/><8+7n�\=>Xt&	s)ᆻb.?_z@ɍ!:b|0Iʘ[x܀R{Xb!&}#lZ�:~7m[6TϙY
    0oY.}Gp^bk|LLLLLL"( D�rB|xyn|횉A2g9bC;h@8p~tg=սQ#車شq*.?DِN}?}U㞑CF~8t7nDԢgqS6zWW+;W4M4z:4'[=X@;[JwR׊\FhkJ*<zVnAr܏n߅Xwzޠ*+^ޥHKFhOFoT<0?]nFC^OQnÔ'az=SG\>ḞmvAMЮMKK@�*莛L*MnhֲjN6hͽ2sy&Aq;h"ְ
    G)/Gnz"|ZhD=Γ6mM#3PtFSFtZ)0A(jBb[lgغ'\N L1	GEIq--%Lczv>֒[#0nbg$vľ8YYȱC09Yz Y†n몭xݰrsF0dҝ=yV{[4S7 "k_9sTu
    )q#<
    M]!QDvpsr|u-grSxHL9ö	_+*ԣ_3p"\<a)2Du	c$7W_H_װxBuG<rSS4rҲ]:c 0؉q*dr'd!'Ú4ݧ07-EH=**_)rxy%0^Q4xw⷟S0z{Wp!7.ڻʈPgzGhܟ]553Ԍsuf:F]='?*{xv(qcN<?\Ń8`in?ש9dx0bcJWlgG{6o-rt©[%n[]VV^.,!<8^
    qjqmVeު/F%&T=N,PٍͅǼ{d遃xA>oCn*'T�'.Ӓ\'lwt~.J}$α;G/+73Gbh~'6qfY<rwL$R}vx{G`QЫgy8¹mL\4/p9
    }]QN
    S9$)n2vlƲ>�|صMIGjR?&&&&&&W-^w
    .A ֠D@ȵa[_Ãlqx豧٘Wɕ+c)QrӶ~%?DIر'^}-pS?z?1auaw8^	cUt<8v<"""c-162=*~~ӇԽ6]=	6#Wl[-$uN[UWWʨs`UW7--0NK
    CAF, 9z'G6pw E|ՔOZD ԅBPdmsHt6�II҃ ]
    `ꌕwmhXE]^.JM;7}nK_#Dekmg(ʕTң#d|q$jR73&k#~vR9YpQ$H%49U\
    мCI޺Z%0,Slۀm]-kpO*GrI�7'xVrُ.qHPV.8G^ԥ$oW'^ZӠtU1 )Gx yY⑯DO"9NTu{l*ШVA!PV5qg_/'M[keJ׹\>A"\Y&K-<j`JR4,8DC05ЅWV])>U\.pk2g(U5;''u>LևC`M0n\tXgڑ˒"H|Gr_rRekq!Ty/赱WYia9nfݦ2kO?3y_w6luH:7~C8Kyk>Caøw?9
    y3Z}OxC[T3gC@-떳:6(-mc"5	
    a\RÉ\T9@`nqpZt31~D4oM^܊+
    ~!NAXND۶;BxnNߥ"!<8Dw/в]^x\
    t#iW.mGOɃ٧eqG,p,!sb	(e׌.WsOdaS05ßIE2\+AAy)Ttl:)¶!>BR+Ƥ·
    m%.z6ߦk[,&h}b>Vt57N0p0YNVB�X#)\֢y8wlѕCѱq#.O-vG),A.~
    rt6-ڇ5<SJBn9�B9ItYmbR/[;
    CG1w'x:.<!?!9gSH_nx.m|
    <L*t(I9I91Y_ÿ%I)@eX:g~yR;ܾ5RR
    :x؊tE<ܲcʹ ]9@38&}θJEb򆥢-O&Jo>3P!TS*QYm;Ƽ[l=59lYwtu"{] ^̐4R:<>5)]w.1Ki\P
    ˢnCޤfLيfG{'_ORYVLنH:w-+q8IزA{ xB3ݍ3h:O{g1TC^8O97og.	8MAr8i=Ӊ9ت!l
    ĺH[nQl*j|<-V^{eP
    =
    By=+!	f.ZЮT(N'cē冶h&H"aYT!4e:zeÃ$YBB|Yփ*xx{=-J,dVީМ}*6뒝2ʶ:QuZƮo=;1/�.(i\6,udq~6psOAz4w܉Fpn>[ egzpN0B2G?OTqk-B�"q\lNNO磪]:O|ό}U#.TЩ:n7z<W^KgR-crfF}:TܹhkGTMf+[G[ErґWT
    Bl\to	"so'@u*Tf;#@RqgLKw966|Sܧ-F9	X=/gc[сVXnfrI7-'nol2)Gyx&<xaisNzҤ(\!]S?&&&&&&WPqRg|K) PP}x?xQlxsLt&|]ǸJ
    n]鷀%:IX0s^W�}!ݲ�
    |9b
    bzr*;&{Py'ܨ(OV0.GPq
    K/T
    (dGwR	CISK8`T$P/
    E9(P*PXQܳ\I+k(~m?liwM؀>?IONFr:oyUJ+]Z 㩇
    w܏=j/$Ƣz<5'dg(Q_
    \pF̸bTO!TWu<o~_<.Ahڡ+iYW4kT)g?{%<F+êb|<>? (Я"7X,ʨ'^ .*gfCqr^[tpmdZU(WB\׼
    JR/CL~XA,:Sik	ylwZB/x
    k|RS%7,bNOyvjzT~gRų:3YTPT/ƈij3@KPy(XXqP4>ݑ�`|^8Ib3
    [.9ə!:7
    EyB.ȫt܍d{NSް-XWɆO-eT6фn@)W:dcC0+9g<
    k/-X]</Y9Xf:B3\``Wm8qǻ9m+O
    Ŋk0v\uUs7ۡYv@`{s^aW!tꍙ_¢I{(Yú'.
    0%O	~h?'zSė.Gii|c!<4
    ]pv7hoa呧gp?KzeĶ~;}՝ȴЊXL	=*Gdp9M/WDvM1`y'ah^Z^n]xk,NG"'g`ϩ˸sH\ԭ0e>	{B	:h"`/I-dJt4�r*/&EȦ7-:3>VCPVKe~&$A'֩eka͑xi\̞1Q6d:Ę٫0qkh<0yX7,K-\$|R^Ų`S$bj.гcfTti#>i'Moz-CԵ6q-Q4\U\\AAYM5bMۋ{;l|:&ȇѷ$nթn,ط*N.TЩxcӺXs/Gu	<tE6cbH8<|P86Gl]H=#,V
    YBy9qBZwۺyxճN|QPD$xd$n-g+<xے*<o1G!}A{‘Ve	
    &Ѫ֬PuX˷S#ud<x<(h~֗Oצ;z6ą*y_1|]HZo{Wƫ3oc7uň?Qi[>-zwXz̰yMgCWj뮡g6iw,EţC1wDs^+KTGWWgFzy -swj:z#RP5~0P;he10+Qd{!ARBk w/;"MoCh͇
    #xU)]7�k9hMФk{ͨPWsɠq9`ޫnmoSvbw	X	ZYGt1aFʠ*珞:/QKy�XK7OĠCStH"]'Ŝ
    9xe>wr/I[s1uF4j�h|e�տ_oǺxm2.UvKsZPsݙs%	|7#&.t%ﬧu<h%S1+n{viU^9%o߼-oŶwb}.y[<W$:li`c)[c[[*t6"
    E".gV.<Q8r᫵g+-==Ejz?%_'?S{k/M3D	s
    l{z {?o/saќxr1
    ]y
    [{I_6ţxgHNګ|Y==1?}yy}{Ą`˅d	~
    =@$x=qg=vنڦ8yH!󁕇/~Cz6gckU<τ)CU2^BhwC1v{XCw�˖ [k,>?ߥaћ`xP#zXV;Jl3\
    Z/wEMG<݃J+.#ʙ]0C#Ó=w&G{QE7[F!hۦ5|čOE2e>:#I\<O`OsAfMÛyh4Д{H
    Uꎐ`Ӆ3):-$QllҔvG'7nv|IrEgffC|zI
    "Hf3z{QIKCZV.ݞTW*Igyk]x!܇(/>X7IK`):}A	H	/(=O>Fܓ3;K+OWWS]T!uҽ<VXZT!0()AV_<(+Ǎ1KU0'`(bg`2`,<"}f؉X/WE4m7@%=x`OS{߹)-gtN˻ uUʢ{97m6
    ݝȺʩ	}\$"⒪#G!{%&|uu8xZ5[E'][sh5df"rM
    
    Q\]K\<Uk�w䱮%/0ԟ{CDSG0݊ݩ(Vzit/.FNnyaHrHL5˃>$ƥ~A
    P5%+%ɉ(,뱜d#ɷz?˧Y�|J~i0?+dpJ&O(wvwCrSNۊ\\nA`HCx{vXס+cƾ[,T̗Ƴ3aTqv<8v^渐S7 $n^BӧR9VOGI		)HOG6.G𐑨߳wqFXF:3<X/8ND'"=^</^hNOo9,UGx'_`nRH}kT6??mC&[B}߽䥂DDl8HGxz\nn	HIρ7DÕn4#%49`	2Hrp+y8~rxp 9͚7WE-ZΝI"3[Yxj+7gUJ=մ;>FJy^9'J}MhT)a惦,QR	q)v+48I ډG7.|Z#<m(jIӝ\y^I}q(e$<[y-G'HOGrz&86FB)<D0Vwޘs=rS)/pS_YDVm
    TRb/}[2[+i4^<<>nRmjm"`"`"`"`"`"pe!pQ]aV%}iJHGPtu2,j4V<zO]'\Kbx+"Qm7'7%Hk[oa�3KeWqDL6
    wONJ1)뭡'8r*1#VYzb@.-7J
    v8(kwp^icCAI\my-مb3-fr0{ׅIeWRH!9}fT-�F*/.L_yntrĆʛs9߁G<R+:+H~
    Fz?u
    yVg
    lp?Q
    D^|q(I|ąlpwh."A
    ~6\w5z׹E@]DZD*+-W_\(aOE.ERY&\MLٮT$U\�o-ֲP~n䡄$	oɧ$/<2S~؉!7߉.iO3xٱx_1s&_'ȧ:%p^z]|ywk~}C/O\dfsa]>7.^^UA6Z|GX
    E3	0}}9ߗC}Uy�x{b7,Llm)ǰ`v<4Lz	
    z}M`30000"M!](hG1uSH|dX5D�$門Iz^y{_^ԇX9Q.NVv>fuiU[WI'ebc!yuB^Vm]_0c
    3#ܯK\(Ua@*I(F9FNRn2:]4*3&6Huxnzc6{ n_x3[#ʚ+@2	0?Qx+i]̭
    TY};"OQAS!%,9RU[KLQ/"/*|o3ǺtV'A3/Y ^c`-Z<WGӉ#~ُ]QJ7l>hz*D1`MAqq+e{X% km鏗~kQJ܉\BӨ0Wlv:4]ʓU]YԭoG*Rr$Xt#U?%^3Ty_ȚNl[?۵̲YnHZy@[++4nU/zRUdZa=@Br qDcyI2cyixzZ!l>'*H\y	f:uc⦯+d\㩼V2H߱QH:nuruv&_4F>M5w37P,UFLWhߖ2
    |:HgNcI_H$H<Qrީm{ T&|=&&&&&&W>&!<{nĿxF?ww]ӈCΗ//EGFܺqWQ"߶*
    F9nF̛Fn~M{$Ѯ.yMٳr�&!ÆrzcAQq	L:<(O
    /o$^}q=362N{9iu|.'W_N\umد"P^w9F<x<%]{/3?WA'ԤDDD
    KjKu>1Lr~Tg~�w?c&&&&W5~U7YZߕՄ@ʓ
    .H<݅Y	]]gTnZNRq#c a~\=
    ӖfMLLLLLLLLLLLL`j߳sW$DDDDDDDDDDDDDJGTЯ4700000000000*0J\
    ނ&&&&&&&&&&&&&W~U4Y	+SA[ФDDDDDDDDDDDD@TЯf4+a"`"`"`"`"`"`"`"`"`"`"`"p#`*Wz\^4
    VVVf>L	XioP.F�|tY\.]n*N^$uUHS]:Sui1,?{nM	*?,DDDDDDDD	e2000.VB0wY7BR3߄UUUSf6mlll#ޖ6Wd޽qvuu|`"`"`"`"p!!___\m?)EX(//W"nnnSPc
    JKKQRRwwwX"}lΞ='''tpttT?uL
    2̹2]-OMK{{&(|eRpŹ,tݻwW%r_ef\6P[\\4mT)PZ
    "::!!!BYYRC@@!22R)|h"œYP*"۶mCÆ
    tՎUF}OnݪS犊
    S8gMG̿-ZP0Wkoyyy8t萚߼'`,AdD˖-pG	v[t3\\RA@V]\\ԤpuBϨLUVJ9Xѯd쟁Q!m x)!YW&"0៉
    i73jAEƭ5mݺ+Ċnz7]]-ʗ,Њ(+-+92JosXXZ�V`ѿ#9yDDDDG
    LXb=Xi
    	+"@X8dy~YC{
    `+xP&oWWQh`bokb<3~/
    .,IӅo
    G^]_+~Inza]z!^voi'3j/Iz%Wu[3FTWIt>n8xvծS!4nu;Wi8Dʓ~Yw~+//q~=/]οSFcQ+tH|#_M'i/'nK*Rej?6jNL(Rh'>hF2dLzR*t#ue;HtT}
    L6ti|uk03AZ
    ‚VH[USx$2|0W[ON҆t
    R&Vk~gٟaq's
    n-2WӪv
    iA66ēHاHKݥd!OυAgdУfݤI}Jwޯ_Sڍ߶WI+C>^5ZV1q2>$RA!1VԎԟ$T3~YKcQSSԸ7Q4Bŧ]8ϟ{e~Dƈ?Rn}Hx‚ohtc̐mk՟qlqV[/2Rz]02nCFzia^'45/q,7R_޷A[-_]^:3*FUd+--V}{<PJU.s;lalj0&/
    Nu]^9-egYxɄkIޞ.'g
    (uE-KP]wOdͳxQf ]Pɕ0S7SG`(RYߒKmmPR\DTlm[SP2%=5JBZR2
    ?UZjK% ?9srE@?B0$aJxslGEΡaG7cqvv!Qmɧ>ڌ}&
    se9_T
    ?zK;q"|p~9uE<7SUU^J'i􏍭iEZx0'=gF~D7șH{1yGbHTˋr#]왗,Qp2UU -1m^rnIjǏYo%yU:|jmmY2WR]T2mrB
    KߨܜJ-{{H#
    궡чοZ`kYn!\񡴬T3ȷJ64M-*g]YzX%H60K.lz<3ԝ45dk[w%AƧ+Jt%?^+
    g82SȷpC`(88z!بKƽYh/.τ~%%dF%Q'}J,R{<|,.Ə5[ڣ-u6]xL~K~/UW,c%ȳ枺f-W}WOd>x9νv^.WKCV$CZZ:W'‰,3Ik{s�i-χKMI|ɷVRBQ"_rl] 5BI8>GUKmQ^*gʫ9QOkNed˸r$ZÊx;JǼ&	i|Ӣ/q^L -UVj7'B7?jxޅ|*ekǤڻ敉Ղ*j$Ua%~8n
    B1|04
    GuE)څe+ף݄Qʩ".N|2yVUQȢbLLtiEAԆ.4VЎXz=!7ބ"iEАx2@v~	Zw鏡u#kQ|
    K4Lxjrg"dǘTz&--
    UWX�c^]:0IM0
    e9FzimtJX+	Wf/+ܙGa5X4U6@ѮC
    0?7ۺ	ǓգZ6Ţ<gR}u~:֕4{%TiN9}zo~�8rϵ`VW"`ZtFY[\=Xf-~~ӥ3:E]{MYªNo>k\	,tXء0g/[ƈ~U>(zF
    sB.Y,,CY�'3C#Xp	*B "4E6	2Yϼ;G2)eGe_:JP
    eU`i]?(%Riwꢞ-oL7LcHǺ&7O~QdݩQml=ۼkvO." #5MCz+!V]E-ۨymA~f0s_چ`_b_;K>/M=j%,B,)x)
    [HZiG
    7dѤl~-Ng
    l?URcOБy~zI#}}}X"?Wxk_'!v#M5!A+k[$oynOR#_&,͈džM ݻF́(3t]T^)6w!e SRGMPTD:-Whl[>L89yEp帨Ϡpb^6l:{QV3F,Xu$cr__'^($bH=V1Y:]!!={uGXPC@{w@c	vTYgEDEi3vtVRG蒺<hkIWێ':_Oڅ4U,m[[f N-z>>AD*+ŽKvQcЛ8!؉ٵe��@�IDAT7aٹy@>Iߒ9{[%]ݻIѸi]pFKhD:Hڏ4	r-Ռ9IYܜX5zvFadDDŽCXl-*)cBw4m;\5mjC:*{C'bۮn۵=2Nb7cQg[mÃPyGƟF[ֿjزr):{O6훅[$D\$Xbs/#[#c{Cxֻ,MSL#1clSx"u#*B-s3\$'A2h;[{qx0JӰvn6uI۞OR	'R9IMʪ&%51d4bNNbMK<Ѥq88cצR
    G5"AG{Dj+u�2Zh%wp"T쨔RjDj+;87pPAT,Vp؁R-ߎeSkIJ,"\iiebɖ-$ހ<_w{\9>Y"[Oqx𥳐hFAD;Z7;#HE0aeEu@$L*4-#."[UaEx쥏x7?<N\X<sV-[&mG#_opEEĆ<-]$8hP-峜K;т#8)m 8>%/;mmNGٰ~c=&b)@Qnqމe	*]%eΆbHc}(Er]Rȧ@6Q-Hфl{ǓBxC6o}>,ʈK\aZ"-e.%RUB̽H>rAl
    Cؗ*%=I`j+H**mieJټP۵g?]ӟ¢:%vjql{;Z�.H
    uJX)Wm񢰷O
    lj~"לmAEUzזcOnZQ|tWuKbL>K"6,SB@H=Nѣc+IwC#?5V&/RXT[{V|BsEZWڲ
    Y_;8OKDo_2ү*&RRX+G[͌koDǚm+\YLRmP�XVui+i	:
    ;YVd.?-ZpA.]WQpI~em_^.N&	paz	}V5>JRbcg3%+Znm"(^e_??,@H?lmFaۈ :Siu /"gI)M5c
    5mB2IUT2=䷤v:d<agLLbq^\x% /Y yy|UCN<~aD$d|$ߎ֫~aFuQ,ۢGFh~$ss)#V8o@fb&6nlԞ0ɱ ˂\A!:4Ic?nRg߶2n[Y+SAޖx}*kѹl|>jI鷧aȼ%<"TJ9g$Cx0hKhSh@W9<EI{'g.J|)\~;'+?vJepo摡jT�+%"b=En{%}Qw=V<ѫ}٭n{cQ1@
    w~AxAtp$|*Mo)T&&&&W%T$Bl	K7n
    <5_R9o*4*'w~GLFk
    Vb_+W"\5:6GXv3|p~p"5wjBlفVHOMc!vhܼ
    뇶Ð+7'�.8z0^ٻ'|ʢM둘S~RKFq9N?-†a}VT`t茾}qHC'+0MCp~lٺgW#E;\ IW&^k
    Cyسsw@'ǎ#}:rFغ|NݎʼnE E	ұ#ص{/ʨm	7
    
    d$eCslh\.x#wtZY%h[7)!6ޮ5.<pP]޻xl޸;w`"uׯ/xǏFc玝827qzp@hFk'N'$:}b[бyԔRI&z3T<LA)6
    EС]+qز7
    CaW~Gb^-Á.EtF~Axu84u)n|3,3dD*p`nwyTȫ2
    .XLq;�ߔv놖!mX6dvl^Y-@.=qyԕr*N{yQ>ú@˸_#t{^OxqMCՈ쪊(/ǚNeJH`t[5o.,
    *h2HIʯ+}혚7hzuAINX2{_N`p݆
    [
    G/F+܂;bв]xЀz8:=\"d;{	_aHݏώK#ߛkJW}C6MCIgH~Oh.
    ]:@zQZ!-"ɖDlۼQY)G4mE~Iݺufm:GnhDzBY;~=khl?6E`geghܮEQQY4.JupD{zȢ#Gvn¢QPE*
    9uFרpEKYh0\eL`Om]@DIe]6oފSe]ZEa8߀N V@LJ>N‘p ֯_1qqrG[z�|z*Xk`?;zd`?q{0Q8,SʹW,3eqVL	ޥ1yu썼S}
    :j[G֣M>WF7|\pݧ78cM81h@4t{m9qDZB;k^_ݱa
    6ksfb{`
    
    Rl|}pK4vT%]Ȼm^޴8zm2
    D.-C{aЛ.tҬSXhʩufL]Ey,G`Uv:RsёzsvsFqoߍjk@Nʷ	|s;[Xg[.
    
    n_6v
    �gk^3ޘ69a} =5_Ͼ@%Xo_+נ{H#_͛;OeQ{�?Jh>@+<4is
    Kb[ZDJ9wosضcFEX._Dڏ!-#N֧yc+-i0}GJjG=dza8p${
    a.$ŎMk靘^
    Ƶ2ڵ-Šڋl!B$DDDDBVjoǦMQ�L2u,G3&Q]_~.0uo߹1\01syzl_%f.܍;zpHCw ۹`S	Z,6ˠMϼ&\*⋵'~˴`O$;JPI|7S4m'ORO[AQMUKnX	O݃s%68p&t"0Sw'`O8|(+ŤzUså*}F˨MF(([=%],$ӍogßZRƒ羮vރ-qat1y7jmq3OъTLzg>:uPWd#/3	klƈG_Íظf}�^AhʼnxSO|c8Sp< V9XъEuwWw)x7ᡝ}Īl"^284ꂆΕ66�>iAk}w%>o4o6&q{|;S:{.wmј>3!v8dwA@eV7?l^܃w
    rW'b;h|]wapsm;صǾœ&xjHg?>jllh؈)(pADT@,DEDETnf,Xws>&Ew~,Əuԅ}o
    25PlXٳfRxx(Ȗyu;K0LѓTeuC˜ R<mzϽLf8,8#C))ϝ
    R),U>zΟuFAvf?z6gBvYزx~Q[1)DE*?+Gw;wƑ1ot3Ժ	Xy(Jb%NŘu֕xp*Z=&7fg}d?OV?*VGْQE,Ci	W82</q%	ᗱem\%
    ΅~ՑĦ-Ck2:-W0a_Fd9d,1ӯ#X=w󝰛Kf6`c>^
    bǃᘕ$ż)x!%hFtUfRb4.؆fh"{vI-CJ\F勰ϡѫB\q:f!#&?N^%&0M‚q}? Ԯ|&JGY/28{J6iV1q!
    #_{11ZMJ&W\5UFgےqݙ>ұ
    ><b.%,ݐOT?Agj"U̙6$^nZ?|
    &ކEƟ{Py=ŕkȫ,FyL>9q15t0D|շ*ϼYX"8gRՇ_a~z&�A[B*!!\vHGZ"!>N!n#q`B|8n4yjǑSh#*ص'UWjS	ET_߱;WEzp![D\-pݳ]BwfpfJu~B(A߯%dܳ(T8B%{۩2X0o~8iP)�/Fa_1:wi3'c./ikg㋽Tޥ+Հ3Mh!oQOx�_"vd
    @$ߡ)য়8~?}J8Qʼ᠆E\vjRk*%8!N48wzB 3||F,+{?73/'3
    ]i:ާ*Ng8Q\ㅹ-!>voYH#tXy
    dvK$DD[2Yqz[><>"3F{胀BQř~L0A2	hȂ *ƨ$4]!WvT.ߎ$w\pCXvY4W-;ĴL|toʷcѷkkZkm
    ie/gJ€	9Sy/#\YXǠeVZs{Д1 r3-إF᳞/bqFF	/wJh|.蚓E_C9)Ui yōޑ
    "!u1|{sΕ-P+(S,
    W5|+XkPqQ4wr%Gv]II:wyM;tDBo	3ШZ̲&vwvv6W%}cgxu8g㉓(LY		YBHmPtkE\P	0a1n9jy
    !?yTJb3~XV/V*3:p$zЊEWnB:#+-Kʸ?Pb^EOTQ(rPjo!9	dŎ7.i9eA?a%QR)9o݃dVk ݣ-"΢EeqPMJis&m)dU,tt2M2)e&8"iVJ*դx:Q3z	@6-"NF҆Mq+矯@GX3o$@Pt�bbƓXz/UY:s__L6+M~@rJ_-2Qdf:ۅ;	K`:LCIꄀС$*	X7{rԷS\*8ߢu|b<q('\@rEpVB϶a.U
    dE,_,M6$?S샢N5F7BS?ma!p.eQfTk
    �}gH%W0#жaؼoUbȀHXHGqҴBC17	kc
    8};p"[xCter	}D׶^!pl
    4^<,A#Llٟ>A!xo"1vw:8\QUAe,>CC&}*\ed
    g5NƭhdWJNɼ_'-8=ѫnm̝?5BMQX�tjB[!l2>2"ҫ9.K#<RŚ)_WLJRcy9v}?R8Rlݺ95Bur&^g^F38f_ȝ6&NK4UQƷ9aW`+*K}*tv3jyRit\2,>+%
    �,L.殿G:!زr>1#"&nս?~	91WDxK@"V_u2|@\B(O唤T4Du^Ƥ"%lGBNHq/zm>Y+R=\Qj)^X7OdԪ2eJ"e;0b6l?=[zϒL	Nf|@gsi&.ڊF"90Ѹf9iT/67A:w7b/֝8MǒwGd^"|)"`WUԊ~sqwG\ωK.lѴ^EގB5gOQA[|/y<bq8	-ꁕceu#\.pq0J+X6g=P9Zl[>$Џbᓨ_3iw±g8t$4]IpUj•_mjκD^!8plM Z	8nY5E!J{$Ή{tEܢۡepK[l
    & `	O7@
     A/[\a
    Kg!V)ͦKgOE˰axn.6bcZ
    ε,ѺEja=X+l*]vX&CaqEœK%6CͳH%Ⱥ9m1w?Ww%Qed'$AAp:4(}sMF[yl,c2ҡҸcisYd25ALF:(l0͓aعt/G'U$WhGD<\U|>79s/_g27joХIUNp)IwOmnTϕBï]lߴ
    7iɊ+/2/W[UUbo&cT?k7Xj=r`COB䥣6nF",4dヅ;b0)
    oT:tZk~p+>|{I	_(5~gw 5)EݗjZj>p$Ʒ^ńdnKiwoG"=%ě޲4hwiؤ	~ζ$̐w
    ma;6cLVԭEmW`ݺ͸abdJH(DF>zÃHj_?|WqRBjD򩴙NT*wX=)R*{M/Qb4cTo+V
    .ŢՒUvҴI}LW[9Eof*QN*Պ9Qks:	!3:"NHzl[1*}y 0")bq"p˞4ھf^`]WCtƊF Phx*\E⦷A\oLw.=[֜ȋ<;jSD
    ɰ)Y0Ȕ&BHIxyz>
    U.g;7$MdRP]q&N-jH9L~)g>i
    a
    }Jb<ud]Rwع+T@6*0Q	*vyŏ'jkw$ܑfPNHCXhQ4P
    Cq	a!aG5Hpl7ܽA�nG]i5 #ᓋ֚$J
    v2<pDiЗ^
    s:ltp$AfJ׈K0~aPfSdf:0%K:(�"^\3c8+fO8X0Ri7ͶY8	4=3|l-UkqHYZS(扵[<ԫ+6o.RD6oXKI9O�/es@s	d\qp#HUFU/5Mn	?H<K ú|sxAx3Q"I�HػEaҩI</F0|ǀ!жEXуXb%v:�d,A+L%AݸV:9Z#*3U~L♱{QDB'ug
    c8gÈ߼:3w.{sT0PөyVHm[1nE3Z3ᙗM8x,洞*Fgiݗ;LhWgJ0uWUc	& TB1t1iԢPjP!6`voD֔lA%QX}SQBQڷ#ٸd&+=l\B=^'HT=3R:,>_Rʢbْ8{G#ű]Qb!Qޔ:uk,xMeE)L!SFJ
    4hbלKɔ*OԈѸvP>=`@@hG<bGҌSSW |@5ؘhܺ~Fw)M.H8IÞo,b_/җpJĄy_3	D%"pHL+|(")𭨞N:G7U
    y/ᅴIW+
    (BIc' 
    4xa�=E|;A)G4
    VHʕ3ǐBYH)|gd(8ד(j+xx8X20_AشdfO~FfhbToHDnq_oO'Er&^㺄#c(V7\�#Ic82h+e,ǒ|>8y?4!3'(;[Ӥ|)xP!@(ҟ"=}S=wbqy==pQ"fSQžӣ/]hFiPHE4LH!S
    c˶;T}Lk&1lz3.$$J2!s3uAH
    {"l>	5Jg6.OͰ`Wp2Çv`t5.ͻ.
    d	,]N$riOjdEw3+]y0;+'ㆸ[J$hkR|!i鈩 .3^]&Ķ0S}VJ-Uオg-E.ɲ6Yigx;|#n?Qsf+Av9iGJxejzJ'4[A95byJPlKhMuh#JےHy(YN cWs1A|uFW,TYchF	ɽ*lL}Xx.lہ"5ۣ$-rɬ2`]R]_.dh8x8LQJ:zR[/c㒝9?9NYD;W:>KSZI	$@&N[V}"tetlوvdosqwD.j ÃNd_1ڮxҪN"4q%GƯC\.XntZ0}ZU܉ęc>^_7mi:n G3(+D!eik^mP6BԥJ-
    TjHL/+]Gfd(7ZVHe8x:&9qJ^Js:Ke*a%,#y0,G&찾iF
    ^^p)7ae<p5V;bPƢ$G[h 9edU|#oɦI8spj=_J~v\^z{5
    D&z!!8`ki%Gr*h	@}%8|MA#:.ƹO鳍̕G$>"3^Mf1ALx X*"DZ$$"AqzJ<h
    IDMǏ.
    fhA̭<
    mͳ`x[;F$$vu8yp$ҹ,l(+ׅtLc$DŽc#/[yRBX#C
    QԐ¹j{)r/іQtIkeQ:WeG#q*ɔ"nVvZu٠^J
    
    BPȴ 
    QX82vX7]{{"ěHK(UU7mDN،+QGSaGR([QUO?#R0/v^NH<^CoHQhR*;Dq#ӹ"ۊ6ڨSMĹ03J)LMbo<H-{/-qY@)*P%H/[55C mN5Ճ2giA/ԢUX<n峴RՕ@&=KH$CB3":*G!T8*DКǻ9/z7@ɗD홸z#X6QFl I�ESU4(xd[mIOEFJy�XJ?*7Ua7ErNڃDicZtA-HQNoPMH=b#pĹuJ/		2edeh́CM2V7/YR8.Жuw9:\U�wX!R:ˁLZaOKXc+{'Fc+gJkWPǨu{DS5CdiKj9Y\#D3GBljb0JA'erC�QAT\c]hrzDU'{҃6ŏ_Mw:dXbjiNU7I{NԨ"r/G$j9J;I~F/KI0Z4|1VWwKl	Q4wKp9J1?LCFu%Yk8xL}$%toZ8$I+0uND;¯ásгD9BD'D3dNp>qhg%ЮǛc�yXbmPkRoٱ>/E:5xlسՖ"%˫LYr<d=_]2w`
    vx"ooḐS$må3%}$f&gڌ�E�nTۦ6?*;ҵ͈dݒq%O-_I)AkW
    Yn+NL' |=u̡]2BY2A.aa|YauB%oƫC}aDJHKMѪQY+l
    -
    8{ގdžEEDn!9"799G7C*,+`/W2c;m_ET<.
    F>	'(i_D
    *Xl.{<D*j'3Ԍ~&xDڔe#&U[Wo*6Qc0ƨӷ6~+e:M#l8pC?yȑCXWjPZ~۷MgɅs>'TX8u5Q̿0b¯`܍'-(L0A
    <b0+IspaD9N)ortD[�}?JEuNTẄՋ3W-oUHݽ{YjȗH_/Us|&c̨U:cQq,閐ډl咟O
    U**iĵs	emyi{o6Y
    @]зg{x{=&~9LÇRqxnH,K%EV<jy5f3~f<M)oP]3u%MSskG4l?'/„oZ<
    u3Ti5¯S~/*.[slX.&|->G˽6/y/y=;cW`mϣBbi7낑1/hs]ЩC{+D2
    syKM%/6Xh/RnQչ iZ9tBab,B(EvнMCP12IP03Jg!gҏ<sL6GMT%EO/<)=!')y1{ ̕j>fs+Hk7F!U>)陕a\{K:8`
    ,쐚A_GigkJWf
    i^aO]`VXt
    NƺXcT)G`?笨KڬC/R^D:U>֠i'{{%)hU֘0k	z念D:O*NsJȕ69jsTc+7jfQ%2X+}Ћ.d)N/}$6ץs<{O|BgVMʫߩ9;@jF_*^(^_a.ga8*˻pM@g75ƅD<ŔZxಘ9c"Θo>h?ܫ(]:&F'
    1O
    *45m;6
    hP*<3>1>;f?I땔412>9[q=Ӥ2+<1xWx`?T#&yJxYƭǭT<(U6ߌCVm	T-wP%m
    Bޯ_PZ3f5i+?~cоٜm_Qs.w0_}_ĸh\tVmHOc@3SB\qj;%%JT][9Ho(ޤyq0k|*=)A5d[}D)Ge^)	E[+	^N\{,v
    N.'H(]	ћ7XdXGCq1iG7DŽ7MN8>m:8Uz<絞4PDdy;Y
    {/vS[I[ė{[9cx\CV:H-rx?ZDߥh)^.ލӭ0aDe۩xm#2Sj=xO[ODP$5.uhU554
    D
    -Y=u84r,OCFw=\\}X_o\~ֵLB858e6!}CV?bteNa[(ID1+Gм}/:GSC45۾ݮ<NBZFg{ס;ѹQ<}k3%2`( -o#/Ԣ
    'seSRmL+L;|*/s}5>nL0A:P[TG[i}ɱ8ZD	Jx&'ӉmeO6Q%'%3-G69́m*nVt\i&RT:IJspTdڴqg#NcyN-$/gЮA
    ȅJZS#HZeɍ661
    P'Wױ.fTKuؠ%&$7SIt)+i#*9{Q/v;:G&+bFUUc)JH9,:2#Aȣ1<zXgY:+بʹD6&&lZ)
    DRv%@ɄRՎj:˖pxS%se\'"t|FV>gy,A7d'Gbį0vr9j<^s(k#	/+iwa+AF	52g݁Qqt8&28/]9ыf8<"Ȩh%wtBdIx
    ScKk;uU˓TÞcӑ\˳I䙦iLL5di"j9=[Nu6-%=OINKjzkcͅ<i+}-pdag"Бs욳OXQfdJD)fz/u3hue	EPqbCKKb!cOƤx59Jp$dOBC&S9j欿;my;>Dr.2lg#H4KIʴ$I΋f9{%6
    ~\+V#UZJۖT}s'1H]JyRYdkhVݦ͑V'AT/sPΟNd^#_cN
    D[9܉is,T!fkN*uVg-{w"Ⱦ0WCyQ]
    ;1%Swaie<Y<kxIlvWZ^Z!rfiK	CPY3)	G*;	g5ϵM̲֥]˕g'5#5Yb.kK){M,bX<ʋJiH府̹(U9#4J`/kJ[d|ӠDfb!*w9PsyKgoʅ,2plt|)q\Ȏ6I![Ul'9ʜy#cފpRcDlO-15@qػy)^stֳKkpMٍIƵڢukHnط҇9TUpRgwOt5]k"="SR`$s=o	cZ{Q}^{SLdϊ!Lq!>[2"?*g_ɪw)S[rqbjLXpo)E\PNp=&cK=B}";f5#�O3;y/ k_1 .N3w#H;zk?DSG2eb'[~
    EO[wD˜k&xYE-_Q>xM,Q=BN?9+>'xR	lS8eq%kr/Ԃ��@�IDAT%2DWu*٦$&xa+dH{mqy
    Y`3]M0Ax(.8	"&*b&1&HMWjSO+hFR6vner`K8MwqT Blʚ bs}/:AT?&c&I"wٰ
    O)̅.=qqa<$)Z'eHRPQ8R'@BƆL2\3#Uz(]:WWW̃TNy&txuϜeQ{HmBBIGɍi*_~$F|B2,XSAXW_
    0ڮ)/ȔNKR1Z_}lGkƼ>.E5Z@>\$}a<$yx5Cƨyd䥗=$坌iED.@<8&\K+i~˓*`ϸ\
    S�}_m/sT;Nןy
    `
    N0Vp<1U[X>f#CN58H^Rj>XSzu#ɞ~+#_3WeB#Z
    RۓpR|/S$ikq^L}Pk-9C}-4j^=y=|Tcx_+>/ʓ:K^Z$o5ge.(ǧx&Lk/HVVƴ8P}z16(19iuC{9@ᛯJ	BP	lY0'P5f<H)KT묏A5ee
    Nm5YI:ah_Cm7e'x.JKR0mɠ8VqF愾J|$8ƛVW}|u	.I2bG	eO"muDz.2om핵^eq,K!	,2"-eX@]
    4PUzL0A	Ml¯AVQ0CPD=M$lxdA/4)!t%ĉFH
    A9/CBDw@)C%vR!A=VG"P3 Z2V.[_N+ސ]U_KJ=Wh#&?n,|eĔHhA0j-cwyI|~R"+Dڝ)	z"ǫ̲yG!>!2~K$HcOi
    Ԉgg=Y@ kkA6d=dSAyj
    *0B-ؖ!.6ro_kN}0qxHws5^:F%Kyw{-62.Ȕ`raX'wd ߵ6zwbqF1uPSezJdQ-eܽרx{<UQq*yzft*Ê8~JTߌGyNG6XwG
    2ĹkǠ*ZLu9y6'%_c˽i\uAߙTi7{gFޥ}~>`=SHz0ӫ=_ݯz5@ٰk^y=!ܵưZzz}O`(C8^L0AJ<@"֚*UA
    !oWcîaqWa_q<J\#\"8p8\2#ȉH>
    I(H1L_A`-p@ʓćNm~8h%|2-ɿg_z΂la2?t鍿=h}Ǩ>>N'n6=NZ[0'_=FSAms=~_]K!xY=RI
    Lg^wK@\e�G*1ʚ*\}Hkt=FUZ7$v5>6ݛ `	&<]x .ƵkԦ*&jY&KoedB6>
    )qlH$q\>/yI*!Ǒ<JHɿ_ڤWJ=KzK%)/::ZAT̸LGڠ*xݩ˿a޸zAK֟d*@1˹:"9mLt:kH[e]XT^=XckIoG\5Oj$x)&}Pp0n+Gd
    Ҿr\1"2WO_Ĕ@/zUท}G{~}nG4ݼyL `	&x .uI]7:dA,t[ʆ$ؖ	(W'eCMN'p%|W=)_6C}C|eC~M[GN_` mH%i~6-wrW#1ҟPzR>}<K8uz?L0/2Y̹딾\6a\_GRWY'Nw5ST)C핶z}d-@}KG_p
    uAܥ$&'z=շ G[F/%?iaʷr&{2G{^_2^ck'?<ncA|v	& `	խ[ŋ:[7lZ^(oXŧJdoׯ+i  MJbSx  trMު]Bh	CWӪl	& `#Bࡆm:ĭ}Dh:|)"H\%`d֦>xMϙIjoHOH.xYiA?ަ `	&<(A,U=w.Fs.%4^3aH*4>2
    3Py(k]q)IOo~ǫ?Zc%hQVK|%W~GwZN
    "N珼_1~y/뽞~8y7$(cF|W^_;_/|W?I^ysjxZaʝq{v?@Ĺ_6r+/Y0~$H^ PF|ɆE>_?1x:WIǗ{i[0
    /XWNqv% -3]M0A<@7nl{kW|m|bӧW?(?(w#wz'{!
    hЯG{aNoQ6o�-T_Qƨn:Uoݣ_Q穿ן|6޳dnGu4tV{!\ =>	8+{{?G9/8YWI(y?Jǭςy55|F&A͟2?W_ׂ1]pP{j~
    o
    ~ן^%ԆEHULbOdž_W܂4^K_#>Ҿݿz&H9`	& C7\dQQF*nܸxzӝ[0p|YtIi(TaJXߜcF")><řٙ鈍O+m\E/wp#u.ElHEga]}'	N.(U.~^ycMZoR?-1{g`Y%,cWzRX'jl4~woX}!Z#|Cꡐ,;9V56<HcLa$5=%77%-^-RXIE'0JKpUXap?z>AePfeX_ʿN1W5ܤ
    xAjp3~r4nkql+ZڨgN!.a&xz<}ݕ4;=z}/3~{
    ^='/@ЪZOXE`wWzaT'}#&NE+B6(3Rpq!m	+ܿEL3xxUOMN@br==x滙R7^}{䊘" `	&<( ~2m
    H8ݻ|hnMV[Ep#<Dz-7GmtNCq
    RɥǦES0n2%_GogniDl "Sjȳ	g/*!akpQJ|UGbmjwhG:81llX8꼱pd@2d$_L?ӐI
    ]\ᨾ[<;	H$yL:s(qJpt
    ]zÈUVjDť<ظt&3#\v1RDH0@(J`fv*Vmzm:mH>0zm΃3rotvm;b
    HCс1q*mOL58)qrblJvmǀz+oaצ߳ތµG݈!X~Ђzܱ!&$18z%Rc0'oxۗcРaHP^_Kxakz!N/`1H
    Q!:<JD& `	O-	IrBlyb%86i󿄽y6+#Z$T
    ft^:oW+f`yXw Mzs`^$ !?Z6]5}:Z6T+&'!5gގl9v,99p4Zf*!z+[$NhJdq
    by,
    R)?0ZҲFb宓(㌜$܉*Q\IT"w7ABr2)U5}r6 u$2qX3c&8"R_Ll(?<H+~>N@
    ņ&rc"~  31V6
    
    >.8sd;j6lY=Edyѥp}rnȧQqw׷X4&qWпÅѪk?_jYQ8~Jz!z'uNܹv
    o7n6Sᵎ
    q|"mN\Er_r?6֒\+;8;r"}ʚG3TYi	b5ɣx7kf+jdf65R/f6s^ٓshY	0(;xoJEj�/􆔑tvyXSoW
    O
    Je|d9pSJ][X%S2s!^gBx0
    Ż_OFسa1d}od%$Ύy@!B6lLL0A#<q]Xb\{׍6\)_G^n}$Jm
    WA
    /Hؒ033ػ˅73s(]gjDk0qldS>2;4yz̝EvQRPe+bP)7"֩
    AU+{5*\W_�l[!ߢAhC-+]=K7 dew<d0EL'l?rи݋p¥;0oNeVptv?-
    ayG(]to79*
    :}ѵIB8k(Î+9b0Psسf:jnm LZܖ!i8g&b6vxQtJ$8Ɠq*ŕk98yx-Vv]v8}z,OQr:avmu<w:žg.ʧ~|XY>Ze
    aޏc`Ts;0{8WEi;u,fd>VQX4<iJTn#f#\Rz酲yrL_s"1dau*}*^}9ĭ[i)H{*/_s(+s'_pMQ+G0ce?Envlو϶DJ~4fQ+`ϩȦGjM;׋QՎκmC^I{Sڇz;7~K/^-B\E~&T)髲95_&#2)<rothYԾٰ|!f.XL2cӭлhUTY<6& `	O38+'=	M-MǏOеWnAB477L�ښ{.>$,otZs,8^f+7C|oƓFR9}fFa8uh7npJ353[bƷ#Ʉ9<f0Y&_kP| VÖ%c234Q/| H/`VL;S-TBMЉŭmK~1w1%΢aiv%-#!'bu}0m(O'_|
    H|Fwt+[Crw,VLBwCZ~j'K;3GaKsN&+JJWzTBF@hhY
    n+SmVAn`1H&pB5˽hR,(i#o7>w_mBLljU(G;Y
    mPTYQfRy+}-W	O[ʩP{ M}h84Wv|z?zg9.U%*G@n?!o
    !Vx([9ɘ8jGGQT6,H\Pjs%~Yz,_Ѵ+b3Šy`m~X$Е#thV}o;~Pwa۝pɫFװyiħ)|10*%EYcZ.U3#?Ė ;8Q	o_<腦f5qFl2�.{/c}ZFJBOtMM0A!$%BvZX9{j߁c#40ތd4'<:,JEA'?`}VLI%=GEhsk[Tt.-N*i.o};b͕._?YF+%"E}m0IGbz.B'0gF٢,8:[ݸUy,*�JDZkTBg{P*nb65	qI	NB9+6\k:@*wWm+ZQ5¶בDK}[{&Oɂ/r
    NB^-fI)Yf(ڠ	J"
    J::PuTWp{Nk{OIp҇CvO'v5sBUlW̢\:5b>13JKNŎcHEݸ,gBct~oȊMG&
    ɌZ5G3P 5~l@Z>w`nĄHJ!VCTRaaMk|RyVobzy"ZhOG?-֗QLRSսєQQAu0+V
    T'a/:2eHg{9rӱwfTkU'm%rPQ.صq>{N~BJd:Ko�o$$(*	^9imVh^q՚TcL?& `	O'FGg!hդx@OX
    \Q ^_Z6Gp,m-F"gNEIS_@Vgk"ը?D	Kڊ"!2~[/}v
    bSVt}&31k9#Vz@#Ld͌r#ɨlMقԲ#x$LU|/VRr9D-˖A:S�q#/֕SX~-5?vk|3;j=N2#Yh5/ޙ<4ILl$jqm8[]&1=%65iڳ�2|;]/eT΃6(,>yH_8imI"+#$gw5ۂĆ0v#sD
    �egnVT*4zR	53e_,';CVg[2ڕ˒9bGZ!4b.!G.C_?r7fp4sg(QL͢V;;jVwq.AvJ4l؀MR{N#bSЪ}}2|ő)-|}ԕsظ<}1PIs/SI4mP_Sm&%-n98J(FOG7JBF5=^0DX@ w޲+nL0A?Ѷ+S#j^֚lz x
    lOB3899bL\Ȱ:jFrHX<Yjs"t"9	`F^O_o~6SFouOgTOvj4Rq=&mC82z?p%e%H3H9*[!גa(Qo	C|>5/(Eù՛E$4X?w=L3#}dO['	tLB{Dv
    H7O6M/D8LK['Us_B-wm@[C'B`?٪	P067n>4:|:uyCE#_웟tp֙X`:ʃ<rSq!u$/Â^v3Л3?^:,ia'v7T)᜙Egd,/͙^rRclh4`~n~YR	&#fii|XX23`>!4/@+y-[cl|]9T=ˏ3VmG498ѝ8q5
    AUQd/?#H
    li~g'8[e̯,zL:M%cĒs0:BtM k_'Sx3oL0Am'|
    hЮx3݉;cheT}i6MS۫޼~;vƦKq`>O54LY3khe&]{֫\7qV8fzzRݬӾ7mߏ7o`ϖu91-Qvc,<3D.~WEM5ȱz85+oό}{U3K'<ۮ#./<кz1<:{x:e'")9'5=j=^`iܸ~s~[nTY<	"Tm~;QԜ'vl]=GNX`
    퍏Y@'fdĤHr}$甦O_Ȫq3V-3>Ü%q;:LR:H+$Xy5]Ӡ)xf8V-ˮv+B9]<|WxR&HD*ձp*4i5	ѿa
    8z$oGQSbu4㱖.~8_c]qvDs5d	?u<H͈:PvnXe\:EbZڇtN"ea(UK:,Y	Va؟p]0e|=sD
    fu4g27N+-F-<\å'0N\A71y<&ly≫g!x٠0o	& !`1`~:"x%J<]驢7~VqDw T.SsÞݻq&2CI-Ct&^+N#Ҷ\3V"I^nl
    ۪Q\]a*mls7m`S|7z:!#9kƯ+]`UE{zPPPDX{wZVwu^{A H IoKL)x͝rssccz�y'Y7JAA{"ɓ&#a+t=kt?551УWtN`�ODLˮh٠D0LR_̐lGGG+8<7j;٩k=piTJKFbjSZ(MlgKybТMdMƌs0byI@dݍ[bD[VXIhٮw>|cIߢ]:!Cv7nDzgw
    ]_&ᣐ᛹f7	s~
    U!}=Y?_Laѧq5ߟh	taFN[v@~K{o.j7n.ox;;##xpa'nmmߏ0#cS)Kz~W>*8233WD|E'Mn>L5Wlã/iuyc9l1̹23`;si|Rf޳m@,h%SAYOYf<@=2<
    'ԎBzJwl;xI8:k8}[�
    мhXǙJ
    IتIRB>D&IѠq3hQcal#07fD\Tܴͮx~]VkPOψxtz6~7Ǵiߨ5r1a
    \z~Z2%whwJSn2sky\tzBh(e^tBm=1ˏy44-Y{VoDמW3ǼYS[
    vǾ}x=`B<aǞ*eʙ_Gs$Ɲ_QMn**o<1ⅇF9&Kx.=!:WV7)Խ"$ׁ-hVe!w5%J~$Jgl݃,zy#cO%lR0+`\b
    yx[ꊿ)m*G|ݻQN#||#Wpʷ+p~68|E?�=]G1σ3\1U*Ǝ|QO}�n!-¡.mg]%EHIˈX.:61jp^
    UQ>NLm<BeǎHq
    
    c<MZhIQϢAN~1b^# k	y|b@`Bt|8׎vۼy3((˰Ñ2҉Tdd"^ax~{hO}hkR,F;dao^]N/v\{1z#-EubR-3Zg;D@u
    =c_:ilbcuĨ0Kӕ�y�2|BCT
    x.#v9$٣2sF].^AY%H'ջFg4]]v@rƼ_G|Jk!y޴(ໂVxͱEkնI:Q8t`|^/0	QV^n6qΟCb$Jc
    `X|];v@޽MyC<x8a0hI	e	#!?B4n%̩SrS
    O>-84tv؈Ȫ۶o	s#<d:g>.}U?,յ8QT՞<5jck~
    9?:cނe<0ܧ|$۔TUs_UNpرjWՆ;]NJ	>	Evk
    ^w>6_WaLmIHNq4n((׼ kLzaO8~J'? 'L<Y4m40(f^f8neTnKes{h>PMm;}g6yAe~aVy̵̓-cWuuqWUpl½ſݖӽ;U2=4&
    :Аu*}+_2yuUՎo{osq:kUun}X刧Dx
    }UٖWw^W%շyUW^Օsw׵)sN<ב*uGg
    EJv;cܡΚeKOg/U?q1 ^+Wݎρ"QP	 \u/ט[s؆pM^F9WӦ(*PUsT9/_G4/"98'dw(ծ;[ǻz0aT-(+fi_v'KaJ0S
    Ú56BDM#?JIJܤx;LVʓRĹI374l?ya
    )5Ϧ|}Hw$#TĒrXGka9TTW%\:U/*0d¼9~ua߇b:ؗ'<2j΋[Nه?^KVAV͝a]~~XQIpWw[·}v<\a'#�Z4'f	p<<g%\j]旌MuUS}=И*Gc<Vrc5G_O	Wm:WѾV5oǦY\Etz?y#6_eu'Nb!wz7>bAuB^P׫oeeΟ/	(<D`АalyTl;]}rvƒmۼD8">]yCml׍HWޭ<8.{}eCuUOų=.ox~NbU*oMʫΡUPl[WYWyArS"zT|*jl!-m-j*I]NE}B:wR;
    *Y3uϋkז1WinEOW8www빅Aw�j۴Ww>՝e+N9e+σ-
    ]zW.s[]PWWur]]mګw_]Nύ]}oQM|ϕq?w\;Rv"/jPm{{~{ulVnGUNsk鑾DQ)լ<F^mkMVO
    **_7ƛ{RqnGrUw9K萰+m?<{w-synUǖ׵:x.mG6˶U S-fx8.+…3zq*3!$8%$HpˮV^֭[	j]ޛ>KEdl4ß#8I%}Y_Hnٲ۷7$[Gk~=5w4o,@ƍV5i.k)))HJJ2/q\:cm۶K󸐿(˟冫VB˖-g䊪hE\mUw6r2Ŭmڴ9a]}0aÀ|IMk~$ |lq}4NahGrIlg{tVӋQL	c<~.mU9ϿljgS8ѺKLKx<101,o<x0aÀ<x0a�ǪOkɯ_#[Ǜ#߻_~{dpkÀ#A8eL<x0a2lX2{0aC$c�iaÀ<x0aÀ~aÀ<x0aÀ?z0aÀ<x0aÀ
    ~BM<x0aÀ<Q1)ԙaÀ<x0aÀ'<.X<x0aÀ<xbS3À<x0aÀN(x
    	5]<x0aÀ<x0GŀQg<x0a1@YY/ELgi/p'RGnj!9<x0aÀ<x0aq??cI`u=K9?UaÀ<x0aÀ~/K]Z]yzz:222<Ey_�hÔǢ?%%%ǢO!P}EMO}QyaǣyZ{x[>qϓxÉ?nxN{gm,
    x2mf;4P3d]՚C||>.,YE^z(..6yv<Ƕ67UUppWynxj<7YUUUՎ;޻ڼUU{W~UjPmgj}8p0ݻZF
    XQUU:vU?TUpVVԩSGE~RdTwu+?s5[~{J{s{_6^e5߅ؽ{7jժf~
    ۖ-gw{U9h]`T}o۳W^m*_)55P%Vp{{l9{urWϕu3j5?mVUO
    OUugT򁁁f߿5kքK0ku-w8m[;w4Gddd9
    uy^ϔ*rmW>Mܩʶ ܫm}DcG%T]J&]ϝ_^)**2UEGT޶ߝ?TY;\8m;gujU^UuT^|
    p3Wݹ1`dhsLL
    ou{DNNq8jI>Ϗ6­lKs6?1--+<Vտ㵼?;O>L~Wuhڴay=Mh,[5K	.sݱc6oތN:P%pc9Y*a]vN8\=//|ڴirs+ŋM͛7G~~Qg$_W
    9QwދP)zuKW	-ZױI[0icK
    41{͇`XpxuDGrss
    ~ڶmk_cY^s-CΥHh}itxM"67n7D£]R׮]kd(CwX$-[]5ZV2СQq8%.V��@�IDAT0Se uV3ʕ~S_=nY8UM5$Dԣo:ܱ׆KYXߣܱNU5F[^τ;PX^|ʫ	CQ?O8:\X%[iu-ԿC[DDc	3:	µc;Twaұp[;hnKqz<ۦ_:wr[|=
    oڱخ#{/53rT
    Y։1=~кPҘ_ttDcnQrrry_G{A
    an/7U,$-fF;iG!rN~M#Q*xmIyF++זcwp4yeKu!6,cЂY}y`:tuPyV|:V8aWKa{VhZs\wU.}ֽ^noU1Ċ}á{ܿhqVזRu{D,T|ov}ŽESmLkTV&tr ~CHg?T\/C}inԿW+7#/Ku4=g*뤃y>j綼
    <W.S~>iJ9sspre0y즌r^+,typ?7
    Xg{[WV_͗V޴G@ō1kBcHT7=;8:TA:c#a]7<Lɝ6_W^Ȥ¥¡|w|]3{sweyWSM=ݳw!"^w~Et[)JKPaMעR�" XR(NK-�v(m
    9DM^*{>q``0<.T_W?'pNc?@?ҷZhC~w1dwi@yYw_sϾ8ᔟKHPw@x}m	^	ʖ~UEDX5NWkHpV~*Vs9c>T݃|f}Sj~+طÒVo:ʰjOPC~?K]?pk>$kX)Ed
    8l-{ս}ǂO{D{EysT
    "V~*;wƯ?}YL6}=ٽo[*2h:HҠ[]ÓlҜ~+^^M28$MՔ9Tpb\0غ2hS#"F>avyS%RCo\s|b.ޠ}"yPCc4Ag&`d*mJhq`wsps2[!	nQi[;v7,H.|ǧI7xOC-'x+v/KôώxWc0W*YLd	I#4VOá£5J[.;4FK[2_[	φfdI+mӚ`fCOt
    m7G"bq-=̝*ڰtXPG:)Kt.[#/'aE$@6oL'*&\ŅyHߗM/#nB^vXf؇M2mg7?Z5kvͦ m͊kUڧA),žQRXIHPQg"G *2E,/nj2rm(q1Ki-Dz>!҄iG~,‹6VVf&򙧱Q5h0V�8\U='Hr9Q9.%J&??J"C(d8DZ�U$NUSsfcp^"E?w݊x!=-E%RlE?1<"iH?Aywzva(F۶-Q֬X,Z4oT@ܩ
    //8GQu/8p5媫WU6iOTO;Jn?}/3AAx?JeePetWw1@҄<Gsϰp҂X@	k3j{O8[N
    WY?vQa.DߤTCgGDEï$KX² 4(o,Z8p۲M<u<&)MQFQUF?2{_vs$hyrc3-kuuL0)d\d~rOeOZuT\n<fbu؟-FB,J
    >K,ܪs}ozuT14Trz,l{Hݟ4 ^òU{&Se3jy=SYUIH)D @(K&J,<:VAUWsa~vtQ-.ױO7"ȓB#3eŔC)BxDBG8CG4ʉ&]
    iHn}RHg^Zյka5٦~)5cmQVX@\䛐fι2ZLE#"2YcmB RdKE~ʊ\B~fyg_ZC9M/tpn�s*pTϴA/P͡nC2gsJѴYsLp^
    'zpfG\PD0kQH1 $:ʭb\*qz<NݪiЬ2h,j,9ܼܖcOmh\/;"͘}!KV!=SZ~R6Y3Pq349MMl_e?MBҘpDE>RfߗƖH}2#T>=#}.whS֗̇kc7^~Gӵ&Tvn^
    [w!&5KA8q"%;?βW(uR\}EF,U9W2{ВظxGwξfeƣ%
    %_<*WQg
    FI&6,tθ.jkEcьYxPXtH.܍g[EFsHڔZ|/_,|.
    1{nNiEk3k*YiW;jA:e0;JBkSO!;=f`Ѹz!s˽*\J+�Z"}Z g|%<;q~8Ms1|=ڱ ?›="ɚ1oWxd&Ƒ	UB
    tvz<
    a_t-ͅ6cm~C�ؾ@Iւֵ#Ԫ�:qm+ka8%>�[V/k/$!撯˱Zt@~}\o'q*bVfMH5Ec<"adžbԗNj!C\d( G*똽b7bBI3Yg[ve6(Ozm4}7(ػîìap
    7wIxxc2+u'ڵqyFF^T2 N/<[ѸWkC	oKxՋǡ᜞""̱ʻNe 4o_$e?1,|ݷ7v,FORLqyv:%V̽`+
    =eꄱ.^y&5i1[^8
    u&OQ#?sLWMZǀ/edn;マКmp~2+蕩!O#_~̜%.ك!C.BGҔb
    Ga9@q]xhEW%:**AbX	2s,X>/Z7î࣯BX#2ϵ}k=
    vԍ~sL3Lp%CХ}Sq}k\w@v֓}Y{+ïl;CK{B^�ܴ/?2#c@HGӶ'a�@Z	@<z,-2c`2Ԇ1!]»_qJQ>n|Spn暪OE!LJ!M	S}KsdDIIۊ;cZIj(R]jǹZ
    r'nA'uGpV{0{S>8wgV(93kwè3c,)/?×3РaI)sǝ=+`zJ6Hw<jb8c|Fi
    .C+XљW,ΰPy5QrmÐx
    qhR6
    ̯?^xغa%&3`]菫=N:.K՗^FvD\qգ3‚ͫW7-qٗaĥN# 55o}kQs"%>0rXDi/8A{kW͙oBzPiɵ+q=G3.IJ1WYxܠcR9]v|ڋp<ѵ}28ϫşnzW_<�"(a0k.Q\r \ry_+JD(fǟ~=;eX>.Y\tvgsR}҄dp Ɔ!|Z3i8^]Kwu$(iڤաyhSZPJL4yLb2'K>$dވ7x3h/@&BJ8oԯIj:pz1V\4()f)a0ׅ3^}r{kIsd	7?Cpx,[ˈu━7ۆ9yR=vn>Cnҁ9
    kD`G'Dú5|,?XуP_1L{
    W8Q!Hݶo<÷]#?;_O/Ѱ@`EZFf}1pPnFɑ݄w~7kY;4RLyg]ySD%2f,;OAt	\wi?DŽ!s.@|{V(?`	/W$bqcFgx,	gz*>
    ]qQHKς_q>o?;3_|kD8Բjxov13f]itB+¡QqQ?z}$=|4ڕ�~6)
    |Z	W0F&} oK㚦|Y$pe(0F}	\iM" 	k6alW^ٴ8:(z"
    g<ӺO_ە#3Yo,<~&KWve.rlwQ#ߎi-#wU
    K;Y|}T:QɓpN_�Hi1Q[ںN
    /'1瞞y-e/&Q("U~	%Gs.,0(l=?n[DL`TD5!eX^q5VVpZPFoZ7b.Y9j<&ORyPąɋU\+y#/R[PdhcaH݆~}#,PkUݗf<D!G*KA߱aII=BV-_̘/>YFnh28@nvnQcȇ2@ʜڒ𳟖||jReH	F'!>yuIQh)(fT{z[s%yv$D!�=4Fsl*_X(3Iw9l)`ǃM18v0�{<#&O?Zo.Z'SaJY'	jѷq=
    Ǎw܇Iزv!^{S|Ztnb:Rd9(42vj=4>_Tn}IxhZn`F'!3u+xxoѣzc'gO<(y
    TΧe/zq q9-+*!mw9yGyǁr`W8{w4@@419TܹdSc4/(&|1{($$s({!6-Enz#Y3!,B-\Jo-K)M??
    ul4A^ܧ|.OdTJ	Y>o4F}DfP#A‡cڿZQ10Z܏^\(x$(đk-rd}9|=g)u%W Yfx.ܗmPdM'>ZDEx4\E\s
    [
    -#]r}%ihE~~YNBYv;&\o4�_^3_$RX|RIWLd$
    rܜeOMpk%<٤;#*	:'2;LPR})?scDFE~ا#!k3uZ-9Cw5^Q3fҽFx(R{^ֺ<|njS-C(lfgsҢz2PJ kWLt$ʬ#zF}7	F1ffˠ%9W);	|;˲+f6ڥF&#ky~q
    б}4ǢqSb[5^;;^{xI҈hOC5}g`"RѡG6#3ш$nEO
    LGSy7sf
    +,C(i2>՜r/i6~3{P[XgTV8YGOC/8tՈKY90vSQ[ /Or#<J.=?=O߳{\(g"!T
    iѯ|0=c1~:\Z_L^v
    C?5z[FV	)"yy™Z\V
    NNFc
    QdRH/].dR%3
    [sC|Xջo
    GRT$F
    L5|d'&-Q@NY0(+Tɬ#^ΆYw?i5!::d-nr21G;4 DFY
    ֜pmY@ĄGb/[f>7a@g
    i&@HriD*!=ge6y.D%;f݁T]
    j<sg6GpKx7v_	:NnMzy/sۖ2 yqgd5W-&/$	Q@VNnz.5¶fiHqfȡAk;3|knyS&#a4wy
    6.Nc&r-װw1vESD'M[tH#C"I#/#mК/Lu#zIݟ4.,J}%]/mWbBh$I⪳[!2H؊mL
    ;v1)R+x^
    H|7cF¢gA
    @ȒW? ];?$lg)7ehp�Y_{EqÍڦ1-Q_|W^뎧K/Bv͑}WQ]6#EO\6lDsh2(uwfcI)qDpZH
    #n]?Nk|k^̻#,0G;50!Fie/DI<wllڱB8_REGt o�?O>tX||x{~L?
    /!I
    _�\z	:km.	<m
    :0aQ
    ѭu}ثv:\WD2eјx	7D}<^˦M߈x2pmףUD,5<n{aii`&@7f4}5	t?ר.g>uT=KeFlZ=te-=k"zͦh޶uqV8/IDv̚:@ܴ+կs(_�ѡc'fWͥqFؾjb[#;]R42({)F$׌7L0
    G_g_?7hBfK]b}MAn0;팩4unߎ(\1bdص`*8]7.:.wK~T3?[&c-WCV4z-BjpCx%H`=	KX]瞋u4ŀ ?BQ{?cOBz~	"0pj?(
    4KwHFFp'ewa2sJ}8�:3"-w!g|k-f#.I]k/=Lu&?	My^;59ޤr^~#|xZ[ᗾo>GsD~~ylΏ71Jhق?kް
    yrBqwS:
    ^l(b5w2V(S&6C8!Sl”_āH.DDCe'#FN2fa5°!QQTP#0{ѣ]23g
    DKzK
    i&JelF:!I"QЉpN]	&8t#1/3i%=Qwr=uAxwZĨާ+0tQ/"ͿM	-Nð+.A`,~6q(
    R#`M0	mʀ/2z:kA8YS&bqش}7 zab#X$U		D7JiP[8&>l4#ighC!JWGs(n2Ѭ)x⅓_7yry?FH)9Y;Qt9ci9t<jR~T͘mN/&OF<'(Ki
    \/EC'3v]%{fgl[[n)&se疡IBӺtG	3}v-6aԫ?<⣑c+
    =uP,pW@0	]ORQAC
    riQ̝bߎm)�ۣ[wlIsaMemP7
    K&
    WFp^�f{)T%X2h̞TuEd^Mpuנ1/#HeI;~_-C.<C#ΣL,X5ЃACs*TnBFb[P2v1}I_R.^ۢ60isT7Glj{ŧrDFQ\̞o訡Q9\T⏎]{0gcaZsF݌Fs-ٜ΄hܱ;n!^LCyR_r4N<Xνb۷'bK0u܇=gPRU[wvرb"OC.@,v*^y3{v^s_G[ze$Lqrgf	%Q<LryV%[65$͹m3sOW@J'm׎_:Z{<wL43fS)ܱf#κz\;liW4}.#gQsp'ӔZ4#Gau&w)
    vaɘ2u&hܽe+:s!q%իI\¬tp7eTMdJ0Qyq$5N8>g^C0{%k~}Nݶvq92L.~t8&xХTJbB0iT<>!_v`ξ?c<NEyߑnkOrGٷc3>y
    <?~+ZetxwqwscD39G	1iλJԍ*"4'm׆{q}bC%H?Ǘj4soI&JW̬~CoMÇ	EٷxN{}=S%
    Ù]Z犜QԹ*/"W
    S0xhs0{	tnlŷ}+.)a9o>j=-Db8pAnPh0I8B2GX3"`מHdػ"QZiMqf!_8kt/j㎻c?	;T&I'O܍2FIKF4@f5iÔz|b	%1PCBq6`LyާU༛KGw=zNwZ̧;NsC+ʰk.ӽꖖЪ_BS4%ga;,Zsbv
    L)4Gc[M-Ei;/㕩=bڼW^b4,ͻ	YB$z&k7-.ƻѨy9a*CMŽ|#FZ7e,zٴǛ9qΕlZ}n
    2=~X!n4y7'|5|1i
    $Hg%C|##?u3t|@Wg6
    KҸ	g8ķN=H"0]7!qCDrHOorr=whпbD<GPOdl{Wpe5-/tB	~!�K>9)f݈kE s$BÆT"}H�߅FRׅWmd*mKo`ףi8Q4&|}[/6,3p׼=]F>uDjb'{QP[0)d3NIZ
    3ڰYze3Ͽ3
    ЦuK4lМkZ)4.ĝ'6/݌o'Tm@f9P)2L7B鉢
    c>z-t6i<٪u;oa=GY,hIY/tnߊƧx)FtBMh٬)x!M_HV4G\c`{F<r
    ޿QfT*fyiB$X)^Jc4p$7
    
    Q4l*�^~i4_{�1	}uݼƼ~{;31}T-1DƴG:(cҹzHy1x
    o^<<v{#mBE|`Ո-,}l%E{llBA`*r0F,):D
    	[;y.	Zi҇]cUȾ:
    x|U'M+a4tliSfa?gE3K3)7ίՊ`00q"ذ@cI	Cy>&w9W8~i9Oa
    W?Q
    9a|Ixl1.A`l}ףSԋ	Z"``S1_"RW :%%l@3[{lxE|tz>4oݱ}Sok,)J+W4"@A9.Rs>r@|Fx;>]y&g_´#Gpzطk=HŔoq9Ѡ	F~N;L̚;I6AJF 22*]Y-;V;Zx~ۺܐzcf&ܺ؏NД&?zWGyr0k4lǜU@LF<Ŝ+1-ka>L|s:^o̻"4Of#ŶsܹHdz1H#ưv
    ݽofO[	y;}0}+p
    0tw!#]!GQ3#Â+f'<6SЫ)ţsNMs;+M&ڮg:V#/mq)=;~o&m7	qvKwQحjk:+Q@q<\Ea8mqcr"z?x?A!'3^-OÃZ k$O^G}<Du$"P{4SQO4<L5VaCxګ*Z"ȕ1O)E4t]vEinÙsfp8IG۳~Cqi߮ػa)ɛV='vr.1njcܐ]s><ҷ_
    xe(VQ篏#K(`D/Kס1Kь{L>Wa҄<D'^wn4*Cihxh䝀
    ǡ[09|=UפYOŒhUav:3/7ƀ1-cm)BplFSP.u(9Ǒ2QAYs-˝sGDVΑ�u:N45ЫD#rhEz/uہ2vy-Jìߛi\_psQ<f6shhG󿛌W
    H\Fi-Z$I=9[>}z"amTC+"]8ۉRwG=[ETf|3W3)(C/ErVh׬ʇ!
    ժ^QЍ=a΢{JdR|mšx[8a4JR3,'εez7Jinp~jк	-݃s軴֭Y2InX<[S<'s
    .b֡hS?n'xnEڴE!S?ࣷc^vXf}XlsR1Nx? nOG aXJRJJyOAxdV<)'U(bPs?uo!w`xZy%q9ٍٓ<Jwb77p/t,Xɾa4k'26ȹ_`զK4in<lWȰZ17mGOu5VD4i
    <9ph)FPY(ZF2"٭:<KD$I?|3Zk/@*K"~SA;Qo5C	q`&sXR*[/
    ]4}69qןoG='۰xQQ+Cn\&VoI
    ["(wӢ/ت-[1Mf
    W
    v)m43E/E֘{Koi )37fYDr_Q{dCexŦ|Cܱ-N=mh2܎-\/;;Aزs_ehzJ/~ǧo`x#.;ř?RY~ŵs
    NmmxSR#eR܁|ܸv#^9_9?)>vm#;m\PSe>.w羘AT�z#Ɨ)TMa
    &nxIl~,]8||7]}!zl%?FA
    =)(ai&
    ֮!ui]N5�w^>~0q0M])N!)nxҺv\G!S"aaF(;^6K"}\Js'~FoF|(� m{!?6ϗamr�Q9g@ ^gNjnfR~EWb@SP^~SS2.ٟLA}y|j⒛wnj<5uGtjY+6?e6Ԣ!awhQV,
    !Xl	+KVQ9WRHp
    =_sqhT;}{=ס^dh,ڑz
    ͑Y@LawLg0x0dژ7MyN-�y3pQhФeB5pKY,[?p
    W?k+�_"PMgK½릒돔)E7~}D5K%SAaSC,c+ıXq(3.+8l24)31_e8h˫F9o31yDRXXl-:LB4pJw?&w
    ^z}JR$ `Ǩg*͝I^2B=$@J).Hї=_a
    vΚhz
    zYh %ϽO2BG1޽`ғ?{
    ߐ]?epo<
    M|/3w>z=xddG[~Ԝiq׎)`5n7y>Cq߽2R36`fMig)bהm|4eXV?ӸdrIZc3NRع}񬯤QVtͩks#<FFMy=bQ`~4rD#ƨx~xl\Q9Gx[5HSQ\=; "I{ޡ{Y]vNh6,wk@
    ߥCM|ƾ=5ma#
    '־Cc<RVp
    g:!Ǹx/gwF"
    m0XqF,j؝ٌ50XCC*hx<1"7:^<wIn6{Nag@(S`54룉;L|ԐFz6>
    mO>5k%\ьփn
    O6s.Z
    yaTmtdᔓ1{16%؎U\t
    g
    s`8M{3(sʗxpy>;͎4xHJ<JiYQY#Qy!
    H
    X:<`ֻQF#~?	|d"ppbe]k(ƒ$Hui&?k
    O0eV>m݂9)35�N}%ipN4tL+sO793>eӖ8wu<6{_!x7pj(hfg^Ÿk0"ݘAQ
    z-eci(ݟI&"?Z&mϧu늴"}ᅮ^C gي
    ӐP0FTéđ`8]ui~ۮhѺ5:6mh^aY\<VJJJ+؇,PJݺ:5wb[3(:i᪏ZЊ֍͹9s]FϘ$imdd%d+IQvFRïUs&`TYٸn\+s.LJi?];	vXFguPgm[.{X!CHxJѠQJP`QbXA \?CH:A/pJ)%x	g %J*WB-k&cz/UP(R1"qWjܨ9+M	ss$-xd<CD>BD(X\,>&|Aoi8m
    ©yA+^0rgD6-ul"aX8W6CŲY|#4^߳0*T6ONd*7~~ԓ|;y]4%9ĘXrogI''F5x֐|Pr`/[Hl܊LCB%r͞ks!7jh~y!��@�IDATHH1<0�z}N$Ϗ4lؖkG^nhLA3޾s~muW B\z-Ŏ0ot~f̛NcД-ޅi.@w8yޜslUg
    {ZB"m�t8/>l14kP(ӣs.6z:~)!~+̗R3N螑к*eT②O̖Qf
    ZM[/}{[=Nڠ0.KJAzZNi)2$PO}L+:cpU*JEfh
    bЯ]4YB{sNBF
    LalY?y;@gL}KwHK`{وъ{^hVjۮj&co0Zu9->Uxɻi5!oT6v!T}X.&_suS_^ֶөy3Ҍ:DuŝQB<:oY\&GC6gM>S;ԩdIRhȜf}`uxaXIof3IIgKi,0[6kPxrh$	&¤?-}Uy?#JJcPdȨC}TY=*k"׼5]~CznY:H+?KL=~
    a]FѶAHә
    F.m٣Nq3/QV_x2(Bayhkt
    4eTA.-<WNXOGiTvG9X|;oÇOI'`{	v  b೴/	@P<	~g9ȔUBdlf8nZ=JF<_ӴK:Vy�6<R&'t7Chy&ezB甜5)ֹ5Ű{;N'GFYKm{N3~,Թo8
    G9! ΄GW'Ѹ%~LTR{}AKpww)[*}k[Y꺵ݺQZJqi@W"yf{@7-;s̙sΜ3uj]`
    uMޫ6KZZF,`_
    8տ8XonjAO#lt[5uk߾16A[A
    -Jr-|_tZ7m1o Ҥ²ڠQ!^2tdL~<!<3bX7q<}`⹸;Ǎ9aa4Λ[&}V<>z)e&WŌ'S8qFdY=yb[EUQPw=ՌJxLZ}\
    -.:.Pf`mH8obsDG6lb57gbn}ԜjMD,|ѮY	NaNO_?}npFS.ql]u+.89H4tH'Lӳ<:so@rRD7COb+= 	Xɡs\g']U
    zq$uwWm좥+i	gN2NvL̝ۄ7;1#*$%Rv~фV8<><u}yqr'7Y4h
    Gs8ՕǞȷ9]mŠ/QQyw`n0$$N+
    8y8\A1@?V	"Ibvd2ߵwiðE\A-4ChS\\ryFm',̠J,Wt-G3&\oUyWDZF�dHTUNc$4N>o<{sC[+F'GTd
    cţQ8l#gi<3KEf_LAȪMl:ۅ"y'9˪PR cLj{!Fi\o=4"�)ʕk|ӹJ&/bE9
    9SԤB!c3p.>!/}Nڡw:P4q\ ͣCGQGeaT=4(VJA[TVjXxVIpUNvlKjy%BR7ӫږЦ]{ѿ#.]xLg%�sMj&$ar!\AeT ]ZJbuh
    {šv-ZѼ'^ћNZ9hJ1٘>.YWlҌ:dsf<$Ѱa@z{ϬiWk{iPq[-X26قޥ^uI3L4(TNL)Yw֍Ц-QZ4^,i^|^4W3c\:cLc(8mْ͛QX>L@8gv&b]>
    r*"σqQ*ei}?͙M_.ص`@t
    Yd:2[qeTlrZmc5!.~߶c7h(m<з̵fD?e61s^-yxxo\f@<)иJN24:)v\bFhm+;DL:NR߷>
    /<nWm/^d}j0/7ie]~6|RhI3z~j0F%ݔdG"=tdu[vߞ[=[W/
    ̣YY*
    &L5fpTU0qXdӄbhAȄV&C$WK5&<ía'91"C)HU4BNpުco<:m9ֳix7Ծ+o!|\Ɲ":7,ْ!V 
    )۫2N4xmHtـ RWQ_ҩ$V-qn_?}'5?~3sU:r7Υ$K7$ёnz >W0[	B}GaiZpHiؗp6q? D\M@tH':/68a56pA
    ,?Z[b�+j^5A GX%M+aK46�̠`tlPM6 
    ԐƁmt.|0}{u\ǚ"&c
    WfE�в@tθW`^l8}tDVjp
    Lx-Mѹ\9NN$˷DSy
    :.Sz0"ՏP(XE&M5׶̎X$%A^a騭*C4SJ*[դ)wE 7;YlBè(|_1<>Pk#GrUs+^]*^2_hCv25xKwJ\]_p@!=\ѾZ8ѧsSjOBqאf4v&[4蔳G9jNC8o!_J_zōg#kl+dEںd((^tT)Š:_/>Nͣ�9)fyQs=g1'3:Mqϰوݱ?/Eߥ9.ί/ɧKF&!nz
    ce#.1+c_(8݅o?x~EGБYMpQuc]_9'۵G3IW+£m/jp}xEֵObʭj֖6Lg9\kҺ+}v'1쁇ߎ}xO'SebX	
    Sp^DGvMɚkqS<F6yq<k?$`ѢEӐ^ĽFF7d졭Ag*‡(>x+HO+mφ
    YhT7Iq`3i)U!'|?yse|EhWv?TpMȵJzS7*}.,Y4e_~% ꘡&r5f쇌L.|ɝ˦UOC#&Cs~Xs>lJѴe
    (QBÙ:1W9Hߒ6TV~k/mnq?&pqh݌J<?~i9VK[v֎Zxz‰>2<5p\q޾%5l{_./3"Lm"v$R5js{o&~M	3CеC[ȑy<wL?G;­vg>€tсea͖\{?1jHw33.}!\ z<{]^cwʹ/pfA8}zt4)sՋxo$ʽ3s=uDtiy1?AM/gL}v\A_^dhzс{<X:#"=\wN8@NyW#ŭc/O3С`/^znss7*ǻ[}Q|Gcyތwj&WE9c~;xЩwM'>NT+kF͐8K砺)7>//8tÕ=[1ccxQpщ`yߡio\ww<: ĭ[ai.A0
    r/t'
    T>inaspZS	O"nMTXgx:74QZ5ώxcnIth>).zHٲo/>VjӑÆEtܖ>&w
    7b̵\=Zp.;F^%@{%OSt''28[~v2^c_Nɋ`pw?ǍhL泘q4DD0㘉лSK3Qu8{٩u׭&YM1[[fO
    ѭb=+l!Js[=<&bڌe&].
    N^%}!V,]v"QֿQ=}3rI;ވcK(;JOg{-x1:Ez[=uHG3ɡY|s}
    @NxM杷Ď%erUyfn^|\'ͷGZm;	?;gcDlY!Gn<+N>x繗c0L.DŋO<h_m9f|^zWB)-[i;1W>ěA7.75_>ߛanOʅAtפ	fd	cwGj>f|yԸx,/zᤒ>CIfgas5ѣO?:p=_{贑Gj?>'_?˭å�];	c)-7bAսX
    SydK>|{<q'27qy<>7FKN`�(OP'q馕jv5s݌i«ɿ]CG9S2XLl?e6?K.$pcl,®_~3;hBv]p\?oDBۨ0/t8@T
    45+Vznfх}}Ϲ-BA44ߜ=x,N)>?\8R&nL:Qc&c8C\	g^᎛5tإ&m˅F->ɺUjmw	⹩2u/C}r{b[yFVa	ˬV}	vTKB}R\1n".WOfYsSsVz=gmI;$bwb?īOއsfbwu�L
    mW�u֚f\v^ފOH5v&5Y0:^_
    t'n8w=H78-თ̛ѡM3qDŽB'l$a#6EڞӾ'^+?8Vشe-^-1~lNjExJMj訕97^(lnxg_'G5M7;|_啲>{`Ⱦ rD)?٘Od&"~[mN:!wfix<nkySSL$$-^H'1
    мYC(Eu(;nl3lU913'inr[}ݚHؘ_ap2FzFTsd(7ݎ/,+nu"]9FSFԿ'$Ԅ"ɚ7ƙ$xy
    1ӫX.W>2je[gpՊ0b'HL|~61Wde0t
    \od%5ax洂.�7Sذ7]i`4[0(,Oa֧)e17=
    ƒ՝HIFa	nc*7-{SOcL썧^bSPO1W4aѼo~_c~1hE;,sy7q$T!	¶mCקm]ZDnm-P9X3Ma5x935Ѱ1K'm!Θ|,o0_zms$-5Y>
    S:WЧ{o-7Egkpo<n,\
    /ć}_Wm0#Gcѣ
    A}zp42{;6:u3פ7@>p[6檥lq--Ā=ѐsI=M
    PŰgx^G	_+o<T<oֺ]Xtx@8|jeMҜ\<?`:m㬂m}egԀn<cqbqss\LKICZVQC!K+0a60qZ)+f}A?fP󿝎?ހckx*TX\feXȤ#D8gۣ07iFnŮ]?%o8~Tz%!a!*LC{]\lۜJ7j
    :r6'9>渱7{*cs-;&M[CIGc$WT8EKθne!|]XnhPIPP5
    )#-6&~ЃgT64⹟}oJob9	x[/G5i'>aZхTuFOT)94r0oFnYڝb�ʘVԙXmǬTcf=	k(W_1@cFtH%l5j6l#W
    <Fj-鈨U3…:ūt6-/׵+q'6xY=x<?E;2s>D0fTUIC0| կm^r~tSދ31~C#8ǟx!LV]˦7~K@x~7zi'V@<;@߃Uuuά똎Vn;rr&ύm\
    pEaiǡ9}Wj5vtTnFC;n2^M	z)͚fC&\y"ހ'C~kuqr(NU}Ѧ`xϦO?-D>k|8yJuα&:3,|'t(
    #(OC
    8陗f]Rjӱ/nُxsXl"
    Ih݉+
    8-`Y9d.NK$:[ǣ^4"*n>6m߆ZۼYsM^*Wec5ѽ__zieK;WZ3y2;}"4;c2=NH0eYўLޑcFVj*Ϲx
    :Y<1ɹF7sXO|eWa@fKv(| +P{.Ht5Fc:WXGW}صK1Qw\~5wBӆ\$wU!?k>"4G.ݩ:qbG=]<MDcF�ٜնtuYuɔv$c@>F>Q'6Y%>`_+)w^C/#sn\"!Rd$
    5WW+^\ˤְGZF_U0o9~ne_\]E)H
    3C%ϴM2ybϮ68*yj(F#̪[6Y)4~ҁ+Ҳr[N:۹@GSl~A\z!w2Θcp$]+HI#x:g<ۚk5=)H20d=}PގA;ӯ~ĺq	'`Ȁ^ܺ^%R47z=8Pi2 plj$$AI\k]ٿb'SpNLўimv⮑Ћym41*㱱lOFupkf''ƈK?hܬ5oMDʕkl0
    }{tFD<&ƵX=cohs:hF2[Bzr8?z"yAڨa5y<dVkqHY7?5q)Փs &¶*ʅpimsT42m5GU@!ŭС7N0}UF9`K;tO4چa<]mel:IOP,Z9^:ܑԭ@a~1NlŐQcq砯x#7s|Z֣ψ10e5=;l`/z-5o-u)Իu+T~6+l@g7QSW6e;V^O#:1FF码U8χGn9JvaXC@#NdvuAs)abo04n=ؒHxcǙZ&@熯`Ͽ`$z+.ln:h9ԙl߀AFZƋOEX<ۨqs#Q~8YXIszrw0L%/HIj7MFHlOno�:s"}S<
    A9A*?&%!݌S69ґCIn^D{uu)t$!�fT3ӏ6FcCj*įDQXv˛fsN|Qϲ(ౠ<Oy>2pQ}ڤhTdϬYѶxwΙYxQď#﷠-/>}"/5D9	}6e%c̀!\�,mR϶mZоAǽ/!1{lK}ɏ`U33\f,9xͨf	#:[	elh
    m՜(謮#il3f$:ʛa&t
    0NuD
    ?v.I>=#u
    Db%Vx]<mg,'5la@s)6h
    ȵPaj5]ehh%m!3_[XҸe4KKH?C#Æ<<ZHNNBHucg)mI-R*ܱegjQJ437[G^Cɹm3gȁl=	ͨJ9}iT5<Z^pxQ+4rVt@n3H2b{?eKh;:X_Y|y6W0:
    M(X^;*CUm3[JazVLLC5A
    Nhb!cM|yՕ1ɦh#5p*>
    v,8ЩS[[x=WVr$wwkD~jp'QyZA]ꤙ
    Z΁Xwx~T	eN΀{u3zwk~7M~]Nb$Ǻ'l_wk6;uR@ζIȐKݥNNDvbljik&Qnh;W2Ϻ^&Q橽ygo5n-3ڒ)=MJgꪼuMG.J$yɈ=zb,V#ukɡۉvvB
    Ud)z։[wY9!ҪnȦA]NjCmy9D (G@E7,W
    40KWiNAF(K1w]UHaGN5
    hA%nӬMݠl;$Sλ+ⓧnG&K9&qU]tM7f!iFy3gbi(i^կ5+fA&8⎛Zԩjjv%Kdh>Zu5t6B]}plX(p}IgX	S,˝jGe.e}>J:T_)<+1yɳx#wAGpҰP{E-	WrGɹHz:sDzDl㸌*F6r#GPGWqO8`$tI(M?hL!`So	_}tX^nL2P!dҮ._A:G]/,A&KʾHC3tEɵ!7)D+*WtUPb&X?,uBN|D+\rʮjʎB齒uUyiO=ԍsyL4L=I~}HPZgKjWW/goq _$w7ztTDg
    gI)M騌.~H<Q/+UU|#}"Y}'WKF򥏨פD7O:bPp,SKd񛵩>6+}23uuƆ7tU[:?/,dn!kXiӗ[$6D*Cu)S,GtU?I'#;BIX]6dpAZwf1v.k^L2*P뷈iN�فX&ՌlҢX	[:E}?^Yd@6xMeu~<mP&YʟK!t!{R?/Q;IYcPP2idߊXax8#|Ә̻	XNjE'#w%_cǖ-[L4n8/,w.A�ݝ=,<0rybuJ
    vaki |F绌
    8*hߔ#"@<4v@2y2
    SV/NqC;J*&18T:g
    zC$n/GJbJ	٥ǹЧ~s4HHu*/gńk読bԠ0F1d4Bq{2O iV1!I1N髑-7tv
    ͛77
    ?FԃD"&Q_kԚ*OJNm):W|a'DaS1,le~6ӹ2DK~hIVH!"@1*TȘNS:Vdfl~9VPWQtW+-VPys"ArZ=!)ūZu~�	/4:xq�'sQyU`P4Ǘ\�jcWy</wF?D?ʒ+bQ)xWʣ`:Gt
    %g]%SBSxw%󋣹Ru<k[ndЄt&7D(qfEާj"P&t*FxUڢ]VXY9yKgP}#^ZO;.?oI;`fLȐFK&m ptWTgGDsiԯY2}2JI2GɿkItPOe*8�϶Y%#[Ю:Q#l)ɸˠt`KiHڶѮ?OHƼF,=	mhϣWo??i?!-8u2^_+]{lJkdRDAH_Ootٖ0MrniLь5hSj#S\S\_ïg#O )fv*vޕtn1
    )`ieV22|*Ww4uA"Mò_͚ФxʗxBm6UmTߒ3zr.*[="(';N|A\n~y5}MjF䈤2rdi.]26ɮDۊ.>6}߄)}J6א#Wb:tS9\_ggt`+*26q,ZZX<L__s? Ty6[\
    "V�G>NtpS}4XW`,/ޏ9n~%zqko
    VveO
    ?.[l16Q=@׬njuQCƔ;AvL)ԥBlqUs%83/ǥa`VYYL}zp8x~D7?B-ffU78)\{IzB(.
    �\i)_[5ɥJ/6SI>1b\:Xh=Ž[	ڰ^2J)B~EoP-)XYV,\WBiu3i	KJKc77vPܧ}BqW' ͌5�)'z/
    ?;oɅ##v>3)j 
    l9A^ԻLy}5y0Kù;8I\8t$5#| C2_JP7_ÑyU>S<!u7Gж_0eDJOk
    	�ũ)Kd�1fo5J2¤Q^ȣv?WJkov9]i]ҨBR.GtrAx,|,TY,t:o
    ɩ]D //%hay44.y@x[S'y|G}R>s!H/
    X5v|Nqy,XLҜ/p`}~k`I4N=5s??shI?/8?J1%V-/QWXA񮞡8(
    ruU _-l>܀lڅhO< |+@u60|uBZV^nz&wD99\h,
    8ZwW/+i%>5JCi('xO;ǗJϧxӂpʿEg/ٌB	-XO%T׾V'T)E	K	q;M͞>5b;}WRh?snTK#ebfG=p
    .{LCˣ*YPq'rpݳdj)FҌ\eq<.=%l{[)Mϲo.T/iWCҵ"yi]yuMmWO
    F-:AKX"̯|.z`Ӹǒ ʣ
    GuJU0$oVLnpm z[>PQeuJ䧫I6=m++_w$fRӖ,򤎋%+"l7=D� ,][$e8#p\ogY�'FcXz$8+ңd˺RJ=Wp/݄$f?OVZ&e
    N>T~FMzYr_WV=TZQѪpS^#
    \|)N8{*}ѥU:?e,iu0Yd'$W\YA=~xһoe=GwV?N~]å=EHrϲpq%ӖNwGZ[utpӥ#Go=#goOzP|8Tv`#ʁ[V#~\W+\rp/NYu++pvDY2^}eVs
    Ζuue7m?4]Ч?]7xB8j,ҕ%dW4nr.M.@vT1yrh#CKo<WppxƟ}-sիѦMc kUYIujDA)Ӭ�лjXǸtYZ?|1uiiEt|ŏS(|Eq:.Eh!D~Z_>,§"j[9&Dt(v3:W6M'pj[oʢ嵭iE<NV*Oy5[
    /j[&+~^;R+2O|Ehd߶joq<*uiKq'[C_/HkETn"4)cOVm傽[K
    dV@
    >*&!+4*X~O]ɇ˿ŔLt5%<CuJ<I򥷵B'w:_Z֯ʒ[',=EiCPv.Z}[OɈ&j[:Bi:ֵ?[ExM\-_}J?-]dɄBiqYt<F~{%ҹKc87l'N8p<P|s0@y\tɎҺ}wq9>uX~{</9^dI%&TӯG/9n$|_>&|vߖ<Nq^Wm ~o߾ݻwرc
    t
    
    LWQס8%+AE@UܟY?,{
    _Z~Y=9EUy|4(jGWGGK+p/:"cJ8F{?H믯p)
    0%xpPHB+/Ndk@^~=Pۊ)ɭxG0Buk#tVI;v00ru  8}&-4]4TP"~m"JһKoW?>4}sOTA|5/۟<枥([hWj~NvworCU_*C=CC'o>BUYd\sn*ɭBtEV%G˭F=KS*Hn(|4yt#yQ==">v4<p xA8>S:~C0T'g?8qozwyJs^iyݷЧ?wh%ˣ
    Z~&;+p|>
    ƥt8)cɑiT/.'ʂ*._T.[6">stСՁ[M+
    /Mgjpɹt$)W.Agi:3T';J]۸G(WgΜi\̷m`GR2.
    AV@Թ_84
    IųG2heTӿb1_+AF&id|MAt
    Zd-A2.MGZNʪ.?eX͏t@FC訉<
    A`-pք_)O�]/\Aߴio&YPըY7Cg(#	w(eHHя*Bt7|h\>��@�IDAT.޽ϣp GfA\|yGN
    w:im|y0v>SWLJq便)-Υ#|(hI/P}7/P|I)D'm{hM.W#t͇[Dϑ'z?MFGwYps~CxߡUCSMwOɦdC[KQ*Ϟ.QDq!%R|q8
    \}K,+0_
    '.w|Zyi*uWݞɍ}__5f\T¥PsTZt?MiqU\ywC2*`hVx4:z;\UV,*P8<:VfH+ni84p}wYjkއyieW˧T4O!v*Ck}>q	Yx`<0 C}*8
    -Si\+<eXYn&'p:%@ZIp	:m/~h4A<vuPPxe_B#b_M[v0}?tز,/z~WiMC|j)NM\һ\ЧKOLN<Qs]~xwVNRNg[imFAtO\~4tW!z!76?~.
    piCɃF8$h*:64In^յ~&Qi'LZѪC7eui.^P]*N9w8(MiA^\ЧamȣxvCv$CN7t凾x6ЛBiسJ'ͻ 4
    rpj@_kŗ,-t۽/59ܯ??C._	k}<2%+nmr.Oy9gE4}wY\G?=5{U^YyUWO~XK(ʃp=ܕ^ʪ+Gǜx(E~O*?PܛaʧR.}'b9U?2+eف?WV+裴tC cBKDZI.T^JH7!ŻIOV$Cg.}Jcax55dA)Wa]<.A	S~-`t`hVӤ[IJQVKKW*BU~Yi_:@6#򪁠k-~^wTF.|۰˦]ԇbi8MUV_
    *_JyC:\-Ab`RD	~H]VщD1.%Ok
    F[r9؀Q0KT$//O;z?B4	^.&^[)SqK?\Kt/q
    jln'QxjtP=L[&[J?xm/;ꪮZ2<mYCeώX!uEݚԋ
    5FOfF!;r\Fx5n&śtQ2@[!uSbN>™QAqx
    o+ʢoYGme2 @*ge^9��+CQ͆ۻRr8A?\**c[boNplz
    bZ5i]hK[͵6mheX7RvDn4ol	N(e+
    eG<"5CnQ+<x/s\vz2bvţJu:Vhe-тV
    -DU.]:!>:ApmoDLXY{aFIBzЩSGԯ[j|,_�ztfj:J(3lۘ׏8%ґ]qH+q̴36~ccMBn]ѤA]ɾ oK_S8@Ĵ8Y^5t
    402ǻ<xD89q8lٶFM
    Oթ3ġxw+fתM3=BjhѬ1Ԝdl5i5ͽV}2mݱ1غ-9{
    :whX^Tqío)܇Дm'~'0he'"ehkn4mC�"#=	͔-6`GlРQci
    kEqv!#k"z5deU94Y*WG֭QVk߅sS|,#鑋vcw`_X4iX2I[)Y4?dy:ܕ+/~prsvԨ
    (_N6iS3|,;	{k`UW[6aԈBwa݊EuK"Mv~J	DZsurjjrjEp3]Wau2v<nm;f+m܌ڭEs	;1sOzwjM/CROׯ*kޱ['N<dtҜi7p(oՍ)
    m}_aV-_Yv4q3HV^!DNA~*OtRȳ/cN~-+bts(b\u)q>d8]u61<?cz	ʥ?oomޭHgpfҭxo'p�R[{7c
    Wrdʙn}+$)PIWy:\KテE#M�\!}qF[Wg]p)?W1xٸMQ8	T꬧C({>Gj	tD;*@Z|
    |^z.t<\|X6y8(Q^뻕Bm\ã|XY2܁<u_2ZR!|_}M?oYmoX�߯ĝ4RѽvإIp'c}+~I}:`z$&J4}YTv3oPͫϼѭٱsK}D|ګ	&~<8:tkZ2a<z؂J4pEZYK980a<xuذ)UM挆xѿsK~/0Ǟ	wõSAz
    K>
    qhXeCbD$3+[֭C~
    Wr/<V717%:7}7*:�Ou)T[ꋥ
    H!fBL>s4QaxpљǡiMK8~kjӵ
    sO~f07=\`ߟǦ^muFѩי2.
    /[
    )`=h';W>CxBl^	AV5cw♅1D2ģEQ$z`.R{x/ŢG^Z/n?d~H|^"MZYYݺ>r?]uN5@
    ؕɱxɪ=ݲ6~Z'_x
    iڂɜ]jfգ<ZZ5h*0a"<1tյD%	9pɬaxį_cΛ<j+acbeUwW{<K݅q}`Ű=\
    ?*
    R{ȍ' m8T$m9+QhZ/&uQRbϡE*Oy"{7z^i~Mq,wk\M|/zMBDm+/_y=ZE_o	]M<pN_tNBoݺu0/կx|%$fz3̛rkmI^ZjMvJRS2ܜ^FjO6ey9^t/qY^!')޻wMX,~򳳽,eez>Ze^fFgF^
    KKrs޼\RG6qV(/`~"_;f~v/.>ʀ쥦ԤT7lmR@=
    4/|Rvy)iBFr*iӋOHwd
    L/';ecW˯(N__K"
    ]p{nmۼˋIs]r/'=ۺ~un/wm	}%lcϐߵ-۲9plp&ޏ~r^6vx=DEntd1f.8~JG'i0:L:_jr"yy»Se%x~1;s_	/\]9
    _ʩg;u׍/5d"
    m۶ͣxܶv9B/%9ɡnK6'Ëٲ[*ORgR7%{);黷zww{cSFyt+]za͗{ϾEq4oX/goPolݺգC=^HMA۝mZHz?b=?thm޼ʡ˃y_:;{9^zV?}ߴTgS
    6}/Nޗ5^bSs=&eշ|.I9YeoPH}loWB
    [53#sVX=d//×I;3]ko֒kO՛|s6(cmA\/5njY?z	i}s,˦xWޙۼ+&t^GJ^ܮ={)V|
    侜TNjkeQu~#G??kQǓū6}m۰{ۼorӽ'D{>'ŋ۝%팉樂LZKO~>`{&yWL]:i5]io
    zs;ц?qyg~G{'z
    ٫7r/6`)FK:LLѷDRÿ
    g<ؐu-\;Zqu*uH&;=^̓	~ǽWk_-tٽ"޲q&+N	ች["'%֛MZ?Z~]0gyۓݻ~eeRvo7f!Ӥ.=&{rw,^qW]}8j~Qc*ѧ6Yz7oz/#3óû}w(yk֬bw'
    m۴e;mez/wwxb}7k\o'Gނ/2*;ftFqepmqF/N#宠
    =ø.o3#fa2
    ZmOUs䋭H]
    LFsX>?bUNIEXw؇
    Aڬ5~3of5M0fmHnM¢6b#Q7Xo{G{ӟM\2e &'~Ĉ!~dkX<wLD;~^Iƅg!rH_tLG	>	6šy1si.e"s(Řs?ˏcФm
    -c<&isb'IihD_Ņ|I9_fZ[QWA½o1~/pYitv4zt`tܶ;,nAܛ.扜\A$~Wf~<;%n!̖7ijT]qYh2~x&ŻCܗC«FIp	o=5#dd;W2|
    {1l@\t0ԩa2x-v;LǕq y0<WY+6W3~CY,D/9%	E=6p
    RG"<ܒlٵ7䏜F
    6S!͓l4YiaPrL�eNo8+јWI|W_Mqrt7x<1G[$nۄ3ѩk[4w60όw_o)SG18V>V-Wú7]S{qVݸt+
    y k2IXzNy8hA׎gٵr*pD=,<);=;1gNIN>;]OATx|;*Pɱ^nZ
    ?+oYFKб1;1C`bX9 jUæ8\Q&zA'jYW5Ï=;tBG%/{ahkygm,:6
    RN}Wfgao߁CsY"RZQzrWJPflcqǢZhodHmw(mׁUOQ̧X:d@=qݸu
    
    sQv+nF|A-F@hDEȧ/a))8etq*ߨ	hŭ
    "AQ+G*c&/]-IhVWwPfIGtX
    ghĘIѱcGثTZ+e\FX^۾g1q;b7j	PZvꋩ݀WaqCx
    w:l{%k{g9>l#ѾGoL`8ӖVP+xx'Ѻta\<p$Ԫ;K<#*#,9..\'8Qh^1mqw8G="eV)G�)cccʟfn:8y0rۿB|a-cvɘzFcO-7\Ӧ\OuΆb͒{
    `*-/D$NrOBf0^~,ν|$
    >#AߖI8ܾYm(n7V^FO<ּSm¬UfnAO]VamjZ25ŭ4Kڄ|&{#09>?ƨQ⟶Cj2a{~kV30ډhyX`Gu6ݚdU
    3[%atN@K2{9}%L}l\́\9n�j,ێ_Yxy׷hz\ј0*c#ǧNt٨I8n'
    θx<^=cxBz9>}WeYv7mL{N9mTLRh|86
    OA|q'cO):q:֏iSvsf rhgĩ߫v@J&?xr"b})c/ۊ6C9}DZHd|y"ݚlOؒ>}mItX"%
     gjͅף)<\AjShӎ=#ϳG"ת9d&
    _mק^M( lɁB�$ry>4+#Q Z=nNŧ_*KM?n>*0μ<&d
    sf{he
    rP/xnez9:JC׎Ǫv?.'X0=4ۤo瞍)];)݇XS^s[9bl	5Ga4@sE4(y Fr^U4oX
    F͚umV/9b%HNWLGÍ5ދ>]l?
    NjSڵT/r0do/=|?lQU:ѭ-^~=xDjl2;|-$MX?'pqub"gВvZ'$^
    _>􈣏+>5aq?ѩ䚻c((V[9<{>q];pW`bs<@CjFEߩ>.~Pho]VY\9%um\	$W@;{2Ђ:QXX
    hFo㾕U֑ݤÜ,l*at@YmٗqijPspܦի16:ihLZE_nHKIBu1xشr%$҂Y'pJ~&ۚ%[1U&܁uKq1ٹx9Vp~ؓFǧ?Ts\}'h}ʹ+YFO<mN܂k/>cԤp=gWIu3锟y2Z3>~u%^x&"w5_N=]q;?aw_bAѱ]χNc*+eaѷUcOiR9b]	
    <qbB3E%P^r*ss3b(L~^EhP
    ;Jisvq�1q<-'GXhٱ%z+' ktöͻQ6'FuSj*6!6fvĕc#'1LH)DNaIJDfL"bwF!-uijqzn\[UԤQ_yo/m];=5]`UE{%{Gmquw-mk]]uuuvmk_*K Rh=3Mr!`pg ;̙oΝ3swo[^[ULVêeY/Vz&z;"p'#1'cܨdཟK!쉋8=
    5q\)g7`ݨ>n]Q+ $2r{+\<X=aq~,DOG`F*MހߖpKVQۿecL>cz/k3g(DqyBO~JXRH9WHwGfIbrԃ>s=�*C5'PuEͻ,?Ë(13w:c) !!N<|-Wa`k2kج]4#e`H~]Ԍ!HHJGRR"+\U"߷qC%"{oɿ_p86,g|߷߄pjc	=]߮i2B?gX?:qXwdAwf)+
    zjǿ+k8!^!MW0kkW(5+mRc<z/)V
    ~gʔ{4']h/CGOM.Xr'FL8ڡbѐ7e~˓-QSoJ5!hhP5YCy3o~_[aVe ߗ=-.pm|Nw&l1l>x?Ǟw;ZG5
    [?ا@VZqc"u+/c?yoƈ@{j002U
    xFc7?%}a_gJ+.Oڠ[]js<2u(0P7
    r-/s+8J&}~KQ[]լط}R^/+V5[yR^oa'j֢STlF]?hϳJ'?:doa+)g_O]p´Wtfu(.JI9U,^R\xcB9+R6w?6>q1q8x88a9S0yꅸ1kxcE1Q뽿?ߜ4>
    /k`"9NmxH-ٺ{4-ڨ_e{C_F7
    Pб㩮zИrbKKly/.x__Qcfm9FoB&[ll1괡Wi2c-,.Y/NkfnVCpDWr*6?(Jz5ջB}qYkWӃ'¿?Z
    TSt\R<nP0/RUf(xi(lgiI2:lQ)TϷ!w<|0HGJM%RIΧNd@
    ~C1Wi�>1z!8.#yidpRG܏*een⡙'"̡{=~ae	CN[r%!F<
    iIcTWUU Q>wQpE~7{1~b35ɔc_yԫ
    rz#{GLi#ӿI:}:+!Үe�b}wY Ώojk�</֣ڦgQU?<qkJ)jږFcp@ZcWS(
    lby+g`
    O殠
    ߎH"为StS݇{s(2+uȕw1ELazG<hor;Tv|<J6:Cۼj$I"ffM
    sohc-{IsXEsE|`\zx?c;=Y%_725sލ`8
    JՀQkpOsOFMxǜ~f7@e*MXTS^%;~Nx,w<
    e=`u1?`>VI)iƏD~p!ѐ-j[*bzҴ1mh|YX
    jL98K/NET:آ-T_Vx:c۹ܺFXmEtuFw UBi}rLtÎN{$Q`ԝLw[E=O?ٟ㫣:R^[ͭ*.R;՞<K[HGz9c_WI5[<5S̀k|^Ӌ'kӿqe~˾[[;Wͯh9 N䫌eyg_pDBPI$.t:5}N짌
    V1,~P6-F'LҨX!	�iKC'~<N(K5jBy%?KϣQZWDEqVV7}ٸ(k*VhcCf<8Psźfjh.�փ2n]{0']rjP}%cx,~9{/2FlCn~;|LGj^jvq8!6D1(	!9p>!g/ZĈž#o>Tְ!r؅='=_~κ8L9c8(˞7p2㾕Goϟ;tkzFև	cT4TE@ݓb^"+kѿܔ,ݹeHz18q	8('k'?g:-E_ox;vfݩJ]"$X
    !Ga&6-߄xMM+\eLNNV5C:IhޏU$QBknE6iyABx׫8-x
    �c-CW_VUClBC@4Z$3v#ּee]{݇J\
    5r]ƕZ2J<[Zq_;O`*[]K)GǝOO]p2g+>V>dUי+5ŷIG'rf3AڏK;S^?bSNncukߤI5OB(44qEp7VEp?x?+e7#YWIU*nat.TsrB\ME)vCveq}y:ڻSI*3ƌm>~euc4_Iv÷kn{
    .ZAaC9$?yV5X(\U˱Z&dǎXsǓ7/ݏ}圻~Z~Dy莫ДqF>_T8iNv&_q	8t}F&9fl|/6?PJ,|ojtdlb-'xc/)Iۓ}Xe{(_.PMO!RSmd,.WV|n(DZ%S"|+u+c?N{ގAQ/ji-HY;qcc;j\,8
    wI5XZR@	S7Yv;rL~%g4PE56Un	jj[ay[]qVZ^ȵ`^(F9-~e{-
    ureC{p'4jM67KQ~\ԮgLא�xe>fqZHuP,n%;8j
    BuՀ:|2zU`'
    -tw̾^y*VK}}CN ?Q錊
    wzo8
    g$k*0kC bb-O	gJH\L>
    k؋Bxl?~ܗ+E`	OEfXӎ-njS_hO01yυ8ډí>U3cWpM+opw#^^nx~~\+_j
    EJP)Z	؞V޽Mՠ‚
    
    \IA0cJa*R<:CMMZppEӿEgDmXd]#oi+\yٰ7TaE0h<6}}2xNSW¥
    ?N$sbbq	:,.S|s@ =p-6!F6D/t華T(ٖ ߖ/̜IfeuM'OV07 kj|`x$HMO~^\GGh3\P<%U⡧{?"*I[p4=YJNl<{|
    $} 6Ѝn6"@41q5W<rlV ?\|w?DzzWã0| c8ĭ8F^KόՋ0kpo`�نgb≧O_1g)F%+_ޏzߤOdKn}ZgZ{$_aaa_8\rp"(5c2*&+3]u.[Xg=pڅsNǠ꘵ߟwzKj$h)tD[$׽{P]&_-ӧ У|>-+hoi`5dyӖXr	|B!HgUDzUq7elב)ðj,dQ?/<ߨc?ḙ '^u*/7boQ2A)B~˶a	ȦO9F0qxxLX]yaFQ#~ɷ;rZu@M2D-pjTn3:url0^Yu<WϨIx_ cqoG`8;8vLrk傟"`ϱ6hI([gft~yr
    ٛ6b՘g(J6?22Ѐn r6w:AxO -:"y3/,0Qm3t5S;dMX9|>FO[p#$HK1\Gkx;ϭ1cgK\_zi&~\we8[6{p,7o.eWp2j'\_aϾcƎV
    ^xm0Tfb[$:lp$ny7>~�9+q}/Q@\ƽy&{
    }tFϲ/]몫Bk.;WsC\rHE7
    @xo\セOކp홋h܍WAC&=bN_�_$pl5{K)ݪGs{ΙY1޺u0ik@\xDs14܈DZV!.qFFhWң^T7w
    Gb|0FzxЊμ*Ll2N8&Qe	녑J
    }3ecU|/V~w<WyEW1]@OzaIOǸ1b.9FcN�A!'ÎUrkO;{hFb	C9qd;/;WNJW{'xa4^1Q/w`<n?a\kh(8{ xpFuD؃HkxF
    ;5&BCp'"W*dO{Rcʇ 
    ϝKP�TgNcbըGLJ4'Nѓq)m
    dJŠ~%wAM`5-\&")?ҽذzʐ84G'r";R,U9މ84Zqf"dJBJV0M2|i,ʃ{ኾSQ?߉[,w&+ZmS~gW2NE?khCPWѭ-ds:~2Bj9$?~K&65<|nG޺EwUǟc)�h>4M;ZOe qݙcN:E8Pպ#:Rb{+2TWKݗ6FJћ'CXNs•Oǀ49rQt~CF`4;,^q]᪋΀;d
    !Q1pC|A8fpBz$v"0juT!zYN=Y1f|I%O&)BL$5`sCbj?G/5Y?) +_/I�i+2bO.T`X|gX|
    Πߞs
    emsKMW>p ZuUشz),Z˖>_yn͈ѣ%;pӀ]XSqI?{Ӿ
    uT"o2p֋&Ϧ+NA[۸BM@qٺa=b,D&EdRz�>1;n,\ĆU\~x085FP\ZDOM!¢S0đ\\z)rUە]}`hu})}Ib󪥘p1Vd.îzz8n4mS=ueߵ{	{\y P8a#q"Djtlcˣ{u9wOkڡz<]EezY)ۑ6`�¹?<*G
    3>Ǐ"Õ!$וnq'VsfSQUoJ/{s2ۮBS.A*dmPO3eWx90v ܔB;̽c/HEժH{%4㧌];8a
    )GCCKu$hGb^?L3WՓ!Ž@+7'_Y/W7ZPys͖g_~ȷC!sR*j%sc4M�aQxa��@�IDATX6k&f|ݣ_dOh{Q.>sp}\ŝ(."l& 'knl'a@FC_G&e6%%InU"MYG{$4~emUVZEP'aTyNP;Vͺepƕ=Υ%4G3x~>
    cG`eg%
    (9ݻ©?`ߎIQI4^<azryV7r/%P*[%)[n$GBdGf}blLc4űTeϚ
    [)j	āBxn:78aRfby(گ GqeYj	/TƼʳ:ۖ쇏CF?
    v('냖ec`'eu 1WUƸ4\LX7'j{n|QڛXo`''¨U!HU?z u.3s#.㸚-5,cCcFU#Μ-PLjqH$3<j_wu3ph52cϳ4Lk孵,,1/Z:md|0#9̫3>M`{nsN#X
    {>b 
    Tno:V^V,5	DvVN+4Tz?Csi]}}$)#Qx(8{GǗ
    A&ߵKQÓG(X5&hFǗ'Tam(Q
    pagk:gTB2'Ovo8e`_^ZBNǻc͞A0ݏ@Q)n{lF9JqCwƸ
    3^\	R"Rn{c]UNkѰ$D{kiD8wC\UZj,]P|G7r˥+Nlq˗/erGj??݉E?56i:LMo$%%]V8yۡ^}l^ҩM8ix]-bsǞiuOH23éc2m6G4Ok9Ν;
    嶠bK~<Ko:߬uPvA2q$nA%8ԑ,9
    O	z߰yVJ,{Es417MxmTɦ|
    UU\s7cUU4;ܐ٪]";>~$.&4%$"ތ:p6
    KʀJI%U8'#Y$GY8yZZb\&
    rg[9UYHW[m_}eTIBA!^IwE:QE N48|%}<^rBu%ƒ܋aOQ}D~NW|	ގhK)GG6!}p@7ߡ(aT}=z+t'?gUңԵ΅O56A[cyۦw	]<84bq*w"j
    gmVI9nT"#}г)ĝ3z'ECC^Y2bWԃK9rVuλ3"kmU׿i8RI'?_&#SHqv|[<rqh5_+k޴�U-ڽSz͇j~v8@okWo N&ﶼڳLVZ^(6|#umlCdhąj'r=B9>МxrU/=c[b<5~ŷqNAJAT'jltyu5PH-{Y^W<
    ;zy4
    P-B[nu0k	,G\Ӹ6/la$7[)vo~[cs+Ϛ=L߷5?/Iao(/+H\[XJ_/,'?%.8yqޔkc<U&bMw:MϑkW@fɔQ|@C%kҷD@pN1mrEKO{wȌ5=
    vGϚמr$?{'I_x
    ]‹1f㜆mW4-Ri|o#vUd[}ռu|<kvCOvzH<4t<b=y/jJ,
    yfO+?O-:}K~ZԯN9sWMXr3UqRK;1#s+;?:\:9Cynmݖ4Բ7"8*OM&U*mRUY85k{2*5 w
    ޛ-i@U%[&ymB%g+ν?ٟBg	Mesqoo
    Ce1KhAW(ں0Zc0Zxk~WI]\kqZS4jVҢmO08^`i	Vudvt19q<ȝ1]7,p9&uh9zǫ#|EU(	oԷkzh>C2{n"yӜu6}giro?Z5zSCI뜟ٿœCGxYǗkGiqw^lO�T]Iw헣-A8j~t1G![Qaռ8ͅb-іZ6)%bvk^j:N{OڋIM,6k=tigKcÎ<qqiIul[)i+'mG]];w.vs/>P5QH6.֝Bp2ä:6є1yjqs
    桭V]9yjRJ&/ƺJ:qͥZwMCShkBXmF:u֩nm6ԙ/,ʻc1B/YÝt42|r2DÝҗI$
    W%iSWVejI_z[XVR"%%%5GecNNf
    T_"mEҥKM_dl!I>#ٯyXrz^}:>R~T8ڏ|a7vZOJS'H(m͸! 8EpoK\\dԳ_Ѿlȉ
    ڟL[D-u\XX
    q>2"MVch;ya**F{Ryl*v 8ɾ5~s֭Ч/|:H=}"Z40ilj [nAc[SÜi
    gWt|;گvZyZ~AD`+^6'uµ¿#z3ZÑGk4#-c=0iY
    ~_Y.mp|Ȯz=.hK;;ĽI=MLY{zrM}`g0?qt;טv~8{i
    2撉=t=wI㮤=6|krI9N+yM](KlA `0A kBTq?_SA `0&Ym!Gt?Ty{}2Gq$$8N::kki;g#ss<^38tn6W%c).f7A `0ۛ�hW@5cf0A `0@&{A `0A `0Jh]T+Q�:W)A C=ÂA `0AZ0|pўmw[\ G6;x$N~B `u#`_wſr)S.\{
    `	^$9RCmwF/D@IlA `0A `0]G@djLܮf*`0A `0@"ЮH-w+C_(dM5AR7Ҹ髤i8<ڢmi409=LDZ_5mxq[+~8ӕt|YItuv}k4[K/qE9k_艳[>-yp}:?:sNg4OWMǞ^/qgMG}k45?0MC:鉟;_ei-㜇^~:\u~_.4MqOsvښ業t:s|/t3
    ͧ=NqVttZ9_k7{s^Yۺj?Iai-M{4tyh#:9܋sNgZ:OyӲ#av{&WޞVa:Ngkk-sN#~'tŵECk.i[thtN΃^'W,q
    tߞ=^Gap;=MC_]AwfP'2WA p#^xo0A pt"
    j6A `0vtYA#q_2(:3A `0$ZZ^\res{A UD03(M4	!!!J7A `0t7-t{j{7Gj^[[UVB	G]!A `0Z=<<TWW7Zբa
    f0j eێg0A `i+ˀVVOVF'e/]*:iz8Լx6,ڂ
    hwm'1z('=z n"Vs,A `0hW@\do{2n"<k?zBrztusG]m?yCvpm߉U`":+S7*eFf꛰;J斑:N	S}\ݱ
    tk{89zfS;SA `0AC4mW׸L�^`mlFM5(*u___xPprwD@%
    Q%ePS[opWBdiٲsK@q(L[yYTx \h?*KQQUwOoz{+Xq8jkC?:&7sJ/HĩD1ō@g75g׼lΗ^j~6Ӵȳ8{xؑJUG2A:؂=4?0)=?{{<o-Og0A `0sDp⁂b?b_i9(8V,'|7ŕ89J-VIC0*BɵAV-(ax;{{|ٰeDmyf}~ؐV>mUcɝ%Q +?yq񉗑 BDʽ:&ϩ\z_Y9%ɉ+V}5
    9RvMЈQ/a'%h[¤	(ـ瞸ϾUaI6k5}W*Oʟ8ow
    
    у-0@~|^%s=/oEB:?MqҸqxO4,[quXR59˯.Ck8*T:º)'sg0A `0t_.0з7{J*(p
    +}VG><<੄\yvI*
    R)0QUHL[YV?qAe{‹
    yհwu^/[kd8s愃/|yzz
    xR&I=Z/a\/'+œL`xyy蒽\uyD!	ߤeWT4-/a!$t‹'iIEP|y2oo.ԣзx0Q[	�ihx+
    ^\Ա	$ďuaaxm	*B&ǢEdRAՃUG,j_,ԫ.ԃ	ۛ1$&V1Gw/L|"bƒ&(ęHl=:!~Lt/|eZ}I%CXA `0nCK*ݖa%DIE<ͻ]	)`z\j8d\
    :5
    v`ݚؾHJMG>i]Xv/5C;*&ir
    zNLظ,S=ك#:!Qh>ˇ(8!jS&q"P ZQ[6o®=oP(oƈ[Aw`rvw|*ˀJ{voǚkW+%'Sm݋Bz-vnی-[KnIJGߔx@Z.H;�q딌&l.ܵda_Qޱ7ea[{p+'bS�/ĆuPQ6wBbKiSc:ݸUݗnSu5:\	Z¹8ܭz:/_`h^[sw76]mcώ-WPTq胜
    شm'c䍜ť"=1
    {U>HNc=dǓJZO*m�Oo_D%OtxFlڜQqп"x	Mc%sbeqUGFǠo X|5qg@Dx/TA!2FC|iC
    lo2x8.Xzv/EjEإ
    j. `0A `8$+AǏ%"+eyX"ŻzY;d5uTQ
    m^:ԟѬu8},뫸c7g-&Da"IclՀѭxg,O`y+ϤklISyLK9ˏƃϼO#c-sMsQ`;oo~cx8}Xx71Q^Ow~d',f|r1zqwɾ<|KxO1qJ(n%[`s?0;1|h(?ąpO:ه+ PxϿ)N[V-ƃ\E9R) *{ˊz؝62[Cfy:.:cě=:|~O
    kO\OX|گx#;~3x\7g(6᣹8=?XU?<~$6,]3iSa._v/bL>dϜ)폿C<qϽwu'mg^1܅߉]q+1+Ma^ǹbeƀSΜ_|g\dxKk".*B,QT `0A `
    ]nW2%b`
    -X%_}#8ȡp{Mwᡷ>1 *y~-xW0y-U#*?zLxrBJZ2|(UWFAk՘2
    ,^'?a><"Rcl	!#.3�\pe3"0kƇxXUqp~ݏFbuw9?0w.<}"jKpERs͗Yx3ĝW_ذ@iVbWO3?PވK=`1*op~E]~wom>xƎj:P`%+&_k_\?UW݌&c
    \QPͅN7Pn"K=ǯ>=ݎq18)w=<>p16wgpbfQ8?{pcRN_Ut8m?'?
    o
    
    )]^Hvǜo>V
    w<iFs@\u0oΞߌO;WM�UC5V.Q	'_p9' kͳfej]N
    -Vyۮ_<x1z(L0Q7߇d`oM0iL_,[%Opə'˧s=bWX`*5zA8A `0A蒀]v:A+UfC:/BvCEE	vlS6e/FQ=h%!*bm˦,TQIkJ4T(f\P$$&*w`鋤HGgЇ
    ѣLXA
    Zֲ;w):{!ƌJugGD)kET].d6c ?k5gP
    uv~ł[�y�jH{'S[ܩde
    OErlj*,,+JK}'*i'TWlh;TkOCֳ~3Ͻ�6zѣ14!{7(נyS4N<n
    M5BqeM˾vص:
    NLQ{fI㊟K5{PVU#ޅqBc3r\}bj@]JJ 
    <TVne_6	&᪫E _ߵ?=Gݛ`ܰ<B⹝x{s~G!((!avo>x
    '5	)}V|ض&oZ|8I2KʷY{QE,,~7n ꊭ6vxP/)T-ܧs5�js?gC=3 `0A `8t~:q[7Z0ON@߸(ԔRڻ_Q=R
    Ű$%_zvzr5~-;tu֩T^h1ZTW[­۝+W:6swVJd둍)Q
    p1hRQzSsսZBT痋3p8FKq4Wxqﵯ{5[™BT[/ҷ2cRV`'!~\M}uȦj5[6GO	S*\qu<NyRr4
    'ˤl~48i!V!wn0o]k8T1d8Fqu
    U8P봓}t!wWNpLp;7ہL܈?j8,yb`Me!2X
    jHTպ!00?ƚ5I3^x71pd?VZT1Uy<H}qje
    kqUKGYCm
    wW
    VKi`aXn-g.K_=[cȾM#>R5M\"g0A `04؄"ʳAwpŗªl"T8ʚZ !>Yc_Q%zG#%9	.ػ٪e
    9dZokh2
    `7
    ĺM[hͽ:1x6RV j(PtuF4o⇟А&̜Õ_,gtK}җJbo:P/{?XI#xk27ÎbZ6<t!O߇TuuQGs,Z_ش~5|*(Ez�շ?ZNn?]H?/RJT/⥬!χ's~sc
    +N߉>^8vZ{92O~#R
    96.&>+qh.1Nq,|S4M?_^yOES+w.^YA4hWլk㋄Ǫ|סWdR
    VOye؋7Sϻr+U,{QUK@;L=&nUh8}\PNl^:݅{[Eѐn-&J<hP�yYj~[p`J$&O:	6Ozn4A `0"`-lN^%@--O9T1%|	3O>[G&#Jxƹ"|6(^18kL>]~Wyg%OJ6
    4p&n?4:
    KGw5xzeQyMR]%^LVS`ĩ7scμ/SΙ=ࣗR*$Lr|幄�}
    Y	]g}__1eo&r!6mo݇'Oè	psg,iwO"#9eq`+Jt}}
    N�b	S׿{+$+AZ	vl;w7kZjEܫ~^w]!i]&6sM7a@/K_GTɣiOxQ'F?ܓI5
    Z§+(;)}?]7ߜ%^zb,d<熻1tP:2zw>/Hr['_3kMEs@ڀQ~қp-BE6ϴgsmk_sjg_!޷RϯqA `0@"@cDz<jUٳgsvWRj^HΘ.ڟmT{B2 G;sylY1¢/7ߋ,rRK~
    OE{ytX4BùJoٲq eۑ#C"bM&G&$!:2vajvRH'g9[ږ_KKϠ8Wlݼ%uHP?ھM
    ^Xx^Bo9')/ 1q񈋉Qm.(ؕm8PRJQ	HIE9-oٱUk8(ADl<#eZi悢=ںMHX[XdN2=yظa#XǬő純DҢ}F- 9#a<zmWVص܃&6Qh;h,JV^RL<ύ7mJO$R"4F((k,E
    ލ^<rO97s2%B{>TOJIAemF^>SN
    Ǭ?_I*Hcx�Ǜ7$Ɓ+s9ch/z؇ZnPq/u=ɓԑT!m9ط�5-*x0wx
    vasj")1~^
    7ȽBS=2:ǹ{;7coY#$oAmxnW:4Jya[\׻W0s̚SrL-[gOF4yA `0#i([1A++dP~y,_EWe\V[P@Jj-|qJ@HXgmݜyҲK^j.K+{ݸOY5mWNA<?%`oQ8'j\ɦ'i2.Å/[N׾Y꿇+Aۅ‹yjkO㙴ܢ]K5z>X
    oW:x*.i	Zcn['Ԥ,uD%Ҙ?1p|ZYI
    s:Ԇ_J	v,I4rcgVa:dr#+əo>z5x|]\rxuf-eU:Sޜ0K4Vש6#tQڇjr~Ox6%!eՓ?i2I!mDڥڃμ܄OƓ`XQa#
    LL4GE&
    A `0 С22g0.UXG5i/D�DC`8(4SkWu
    A[RH$S#մm	/V|AN+ggOל:y[ĒF/5QIOo8#Kؔ3gYn*ʇ2[OBxTz;)/k_<c$Vu/Az^YQH
    WWYBqj*Mh"Z<<$8Z?G2gۉАHs.	0?jP!jReXg\%ֶۗyr*ppe+GړlthY_U)3PK.uN	0eNdpRiäA `0
    貊UAYir
    s#O�yj*%5=.2�{<;}VY4ҴW[Vm1]&O3!kkΊc?k稇⣰ƀ"K>vg+a>Up.vܻplq'yu<}^صM4Ͷlg[WM[mqJHfХS2A `0_b\V+g"jj*G?Zg48]:K_mӴŋYq%ɀ^TeB4]ߙ`y,+޶\[M~:m@xμ<:G[r՟S/1A `0�:зoߎX߿(--UWH}||_ĉ"+bXϯY\___5(BE_=;}D{{{7җ^<N%oͷ
    }%jB[B_0gGU/.k�
    ~"??_rũrܝ/-,M0/u]+gGGuL_Tݏm+eۂd˹uD߹;c{\WV[}mWC_ʥ}o;ڪ+yu]iwq[lQ5 `0A ГH}i\AT^=L;ۊ+8Ǖ~II	s=,ujK]/mai9n[<l=ngy:H8ՙJ\s嗺i#·;ߚ8粶ǿ}͚583WA `0/@+(+zP,d 5u\kW]IӕI_YUF"(ȳy;_ٟ%NkuUv=:mktтYWښ=eۺ/C4ڿ:#AߎOo0=_%#}8A `0@OBC]SEYqrߚADYTU19زkQ;a8;/L[Ge)$>X,_Rz;,&A `0A-:e@+څʳ\H[Z_0v~>\m͙\]ᦎFI:[N1ݹx `ˎ@v&A `0@P@D8U' 5T1P09/Bu涝/8:%xpV|4Kc:w*D9;}�d%\_kNc[kJq|sԧu::mWY0
    lhAa~y{`P0}
    z~HZ'G1׮#z2 `0A pXP@WBu՘?{6ӝk(|FM1Z:Q1$_|jp{7>(I]h8`CiQhZeE/Y(x#|H^sEȲiEer;\
    W(e! @}xMEk酺ji(/+EXLL>a5kRS	B>Խkig*ʳ8iSrŸ窷4rgܻs`p-$mvƌUު|Nq$qA `0tUT^knL<ɏ-Jmt3>"*aHV'KhCa%0:\<~mQKQ!X`cErE sg~]ˈ4&u
    ps�<jEb27aIgА,5ppa1%GI4&Ք20\kM%v<M,3-݈gyEѧ\Nri_6,>.u mMz~G}H[SmW=#GS
    f]#_]]j)ݝC'mN%F'9|{"eL"BTWAeBڒ#i>zmWˢy88bA `0AW@tJO""_y8w5s
    Z=v,"fܐX1kzK>!؞Q8v8E!k*,Zq
    Ǧ[gIl	H"nE+�ۄZW<k-f.%QI])XA蟑*\[ʒڎt6�Ed*{b75,9\eQZ]daxJ|>,1~5Bzw/37Õ'*hx?>.؞�)}bAܿ-Ğj:
    q<1w<x;eCAb̙37{-0Xd!X;6FFFJ<{v˱eNT' (ƲeSB_P7i!b7xyI2\!q 6cLFߣ[QR݀#`h4NL{DS!6)A `0@tag,#p׆TRo
    ǜ7wہ&_/g^+O<SѰ\|ӟqUSQsxA{|E
    
    "ʪmO5g=$_)AX=~8s9^n>$㣙cPb V-GiGE!/ݎpJ|xpΥW#Ư?|/q2>{nIT)G#kԜWr�vD;+D\YGy1žpۃ�1(+_py1 _vZe/JUpÝO/GZ4w+03H'}E\s3{~'uG=^zEΫ7F`ż/#xr7͍w)Ǝy
    :*``roTsoެk0A `0t^@~M\<mn{mT})*ٌrO]_/0"{ϸ
    87gZ:CIE%aY��@�IDAT1PQ)[%{w{9wf=̼;wwf&?\}[OWk։f[
    qU_AD(gim2MX8:!,ׯ%Ju.㐕v[\ɨ�?Q)зC3ܹϼ>럗%2llrRw0%_Б.ܒiŰ?۠pxrL?ڏ~3&FVf{s6yz*\BP9zޔ)Fk,xe
    b|OAꈭ8>j9GΈ
    0w,\9GD]tuu#%ҮSwxDQ_-Wmv|G<2+tm^	/G5嫽'·0sg>!FjV$DP(
    B@!P#p�0pTl߀\Q13"z}*L|iӭ-|m-aX	Eh�ɸgΡ
    ӗ\hy`LzIX|t֨`"Vs`VPp7nrGwpvCnj輶Ӛz*z͚0]?';5TS;bS]Ib6"3-MW(J7_|HE?MEDw#1۾7@wrq7ß-ˆ`)h�Cj`6fsL}3QިV&ŬF!ֈӚqs>gCѾQ8Xg8AqՋݼ`1B׬`d:M-ڣ^:ڭ*UCV1Xe&&m^Z%VY649;d 5FEF1'O"ϐWqqըg|e8z'`}G!P(
    B@!_G	:Ք7[)
    5S.7IcfjEJtq#9
    Ħ\bts228Ÿ6c
    7M
    
    M$af]i,8{)N	0s0}~g|T/~K1}63TF-3F\ɥޕ'ى39s&(}‚&tLmԀP/#/rԫNq;qONLsud禵Ƌ_!;St4o@(۟t:zb={�EѠge#(։ψgQ]yj$Mq2݄iߏCgqFvm}
    7
    0!Iwwʛѩ${aL!Q"Aǵ8*ķ*(
    B@!P(1Agi9ںkqZ1srP^s4S{6gJzM%|5;{>}	]NgҌYzۻB}qr'D7	/tNL2dEۘRlճEM8iJ]<i/AF.vw)'oZNmBcN;
    uP]LOY6u'-ytƢ@=77>AL_go=f<8\;
    x>DGk+$8	ؿ{NdOriFڝrIϼ:hi=;Bt̹8w8kTݸ7ECqs4cv*]i ј2`NI	4@҆pkU7ap1Į
    HZ=k Yf<.psgUP(
    B@!P(C	Πo[t{Mx5
    ;cGv9VM6pK羏y6
    
    b9rg ϒfA_7"Bg*DCbc}1%xdvTIggQj6(KUz8%bҳfo}2^}~?kE뼦]F_D@udދgh.欪FQhP
    mZ%DλxFDXg"f>75*(=_<g'Y1Шv88cH319d&f-|)b|lҊǏF`np˾FOyԮG#nG^.䕡
    n}:LU}L՛y qkj	W!P(
    B@!:*K~
    ʕ^Ro* B$,h//o:6,g\=i&2^vjri3/>6+o/3oC3PDGg!<$/h3tfrB뇝$t잜Դ<,<EH%۲8 !;#W._i;<i	A!tɇo@ + 7bЮHJ_o/n=#-Ek;GȅM"SQZvЖJE;"qerGOCFV^@
    nt+2"!48r+O
    �Cet1ZƴG b'DFGfnԗ󑒜"tKuHx%+-f$#7@
    GBO9R?KM4l""B3iWAN^>|DK?Ro�ᾝtBN6H"bOEȥ>N	
    >^d)`KWTLUd	́бcGDFF
    _S(
    B@!Pv]|7X1hof&!f؋i06YHzF"^[0T'Z]HͼBW߀`_D=GmhkXDL(Gb_ڥV�my$(tGRX'۹,"{ֲi&W<TGky2(,eK\&?S9H~n�""atnɠݻrmgĖ'r
    Ϥis]>#iHhu3!
    %>P\L"!:Omi}bİ2p~L3<2F;oe?(w_^\Nj"8#"AÚͲ~wU(
    B@!PܖHCA/42F$[a"8ppA|PT
    6bs mdKق3TYk:42/l_6I獻,Ϻ^I#FXH|AY_
    *4x[@B;XV4Nb.q]L4 mUoKp;yOPq~lL欃sZIvq92>kNN)e:P<8W`?N6}N,e4/+ߝȔ;r2u:U!P(
    B@!w p[γd\~kiF4y24y_N';!ȫ^+몗<e:z`{0N...pU([odvyF^VSoWK;*ʺe彽,S٠8=#ֶ{<YWv eUاq_2W_^iy8r^-*Z{VU,7%_//ף
    B@!P(5%詩bM5Eg.LFʤ]$z,eədmyn%[s.?og_l2Ѻz>VW+֣RZ[?c)	?V~/j?V\ߕKK}AWVw%cC'OgGB@!P(
    mP2WWWAr3+H3Q^?2MʖuyX<eKϲ/uEr94[nl^?˺ƙ|YYYzH~.vYVϲeٯ˒~+J__Kǡ4\lc'ʪ˶6JKi/m+<~,,~GI}/@R>\˲EK9Ob_b!|/ǒso/+˖y3bd3[Xʾ F<B@!P(
    B^C3!ݦM"oW4dd#Kމ'e2r~YWbŊD0F2H}Y^ˊ|.MVȫ^^ʔuKg,W{gWt~iJ1[z.e4qi*?xڧ?e彽}^V?K94^^xgW[[-~#AXb̲tiP(
    B@!o%AgxV|W}iWײd^Ndd)k]F,F_]L}^deLYWq2^KYyOg&#JKriۮDIY&YYn܍~YJ]]eylieò6}R_})b*J!P(
    B@!!p[γ74]~_v뜬?0N4ᨯlbɼl(M-M4v=IJ$kǺl(Rgʱ=\Uf?Dr:^|DMivPm,_
    QiO2x>MQ忹20:[Gh'd	RUWiu#\?ŋ$?ݜ.ej{ {}>~{Yl^$^W(
    B@!PܖM9䱄LU9LD$ː,Hg[l$QD
    !Y2>$ɽ)^WGY>
    kKbNHnive!5Jl>̾J
    LK<EgME0H^O,
    HkjlIՃ Օ퐞3lzZd_$$规s֌:rK	Jx�Ϭ/V:-*QWB@!P(
    ]@ѝG!kFD?^2zǵF2]&p\8qPN
    xlT'W&\hŐCEtw//:vfd}L/vCZ�yjN.p@h$L縛o6	⫻u-4dpf"$dqڙ[d/Co0.d0X
    Lr4jAzF6_GŤ'7/G	vkH;=RB`T/J3RRP@Xyx!(_ؚ͌2n2ҙ6swsB幹gTD!4q9FyvGgb9K	F򀓕PHIK77|rM8~8_-'(\̔HLAʕFm̃6Lڹ
    
    y<:RБīp-)*".6\n6SgP>?0>n/ٙ΁+.ڜI9ng$f:R@'$(ϞBBr=]QaB)?+#6"	n#QQ(
    B@!PܓIS
    |ts
    uԅ_ .%y 'O9p(ʕ!Bx7D\9y_~#8;"ȜBlG7b<YK~u|x2zF|:(2bϱP"Bݑg0R͆ߧbÙ`φXfA	)PebxsӰXӯ0v5q1d�*ņi&e:!jL8Y~NA
    >X˗eq؁0<7m
    Ć՘;wN&d"~h$EaO_R>]N݉1Ve)ѸvEB	6ec~<r>~7mҺn_"62uu"{wZj:~C{�gm+cA.Jꩽ䳯aDFN=+%	nUп7$	
    Ч]߼pr,ى&MDۃsc3!M;a옇]KQ<1ޢ~-:G߸Olό*S2b~?nMKӞDT'^>nPxg5<Թ~.|8]Nˇ1#15ZRV"fl^;nHMICaL䜖YI׬7o/gQ,['1ZBOw{.Ɯ-iiA~
    B@!P(O Iqa\5PT\X�JӬ6ZBИtҬ0Ys2dFvĜ&8Ҍ5=YRB[
    ̙S0﷍xwd];^x
    O.\!b.ܾ)7	Yl)۹Չ8s1=FcHtcRpݘ'éfۉZQ>g6-Xx`fZ[I6$6~;3߀.m1rp	Pf͟>-t|pspB\@Qf-4P$ލb'sM\dơ][}>CG"lJp�|,	MG~	aBK9E	6d\9vC%+BhҶ'*̓C~^SƸ!ma17"VMضn~\>5дa}op4'7/$߉~&aPx"4
    ]nq6&':z+4̫xaxcxv|p_WuFd
    9p47m1magvi׀Re_IMxY;u;ʟr\oHHܛw̾xЖo芕0#մPd3SC)dD\թ=|1ァY8cz##;}F>6!?2vi>xmʃp!O*T|>)x\3B&EpGs8%/_'�}'P(
    B@!_IL	/_3oph;\XC3L69g/$&*ݘ=M?v]zezWHJElt4ZiY`&ebT4"qfNDC[x*q
    j-6~HBIQ=1ah#kLSvjFW.r#hT6VnylJ̓\8\yJΛwѴUM8{㑑CiSUD,xU�RѪaC4o
    
    *hѬ|ҒO;OhT7FWRe4k"r'WkB٤)Pɟ`]0;/ƁPuCs5[y󖸯r+2+n.>:9"9x�8Hԭ"*WEhu?4"?
    
    FuJu&081SL/vQ4R.6($HE>)ԞuzDrϏnonz!ռ
    ~*{1Ӭ-d?=<iYе0"ĕGGbGb*
    &9Q!s?yј4n8hC#4lg'NƎAx}gu8P(
    B@!':ržt
    ѡ8O.OvoDŽV5ۂh?L1e@=
    žߢi8~~ͼFF*Dժr~kd|A.g] ݆|2bC#f^~O3Ɯt\Xjg-9$_,L&^cqsA\@|XZ͞Eo؀H3DM.hޢϿe"AA8".\U<<~
    =zt7iZA[k򓻇YZ3nqBv-Q>fEx:tbbD&22ŕy&o
    VX0mhOZP)-gvLm"fxۊۯ?o'v[:%lNf<N]`"J<:Ղ1w{j< SLsn #)K;ІzzG1_6텧ڛpY@~Yf$]ƍ6m":ďo]#hL[K.6^n= [И{NFK"0AZ)#B_->}QNۏNmJ}s1G®۰z7y|pj,?·3گ\3iP,S89КE4o.ڼ
    :uG0
    k
    ?Q(
    B@!Pܓ	G�4h{OdᗏK2~Tx[7!p{Ķ)4+莺18Vn=C:yn);Zs;G_80Jع7T2yW#ց{TǡJL0rsp	,^
    &3v.
    8shNo },[ǚp[LH1r3z
    b/dn'ڨ<a bџȶPpquVfXn3frVXxixvJ6G	=ģhGACUbu ?x>x-j**T(3n^?)%y&0?[֮@N:s״
    <O?2UȽZ?ac~e@V$Lex74TQ51лkkx󦅔MKFyԮKx-0,2Fǡu+^ϛPsk{,17q W/ ߌe߀5NgNaDh=GvmƦKޘÂsKQ$; B(9{5x߬܅H?40Dcrm+~ߟ⟿&z�z
     y+CX|;F#1rAW(
    B@!P[]0N…g$L	\ig<tjR7 zENZ̩ٹ-B5c'�i	$IkmH @YGg# pڰޝSՅSEp^ݿFxgR?	g?@E
    xvqPL3E͸i?Ĉ}4ćȏِ3'“ZwZYi޽|B\F0)b=v4
    "?,Q IwyGy1bdfYʼnv1M@3oFu0IHKK%sѥ}z	Ubk)`6]aoe\rm1xtľ-7ܗm^-,CxoZ
    nnz|7ҎAo@s"^(!Ĝۑh{"
    ?݉Pl]ݰm/|]%f$&"-=
    >tnY,Gim=׫~\t6[Ξb	�ȕc먿my'Vjp1^7�yj`io|tuLQE-7"ETӖG@\fy[ET7nV13ݑf+l7_.ƀN5k;)=
    y3{sgq%ހ=w3%hX3
    Z6%<+ӓv!31U+/юG!P(
    B@!pO#pt
    #>˛"XJ"HJfC]xU;^6fAK(i.MFZG˴B_IT&؄澈?@,>}făѨIkL'^1]av[3kאȱF4͞<~ˡv^hE.#{""f#\މZQl2DsѳO"Qp< l	4�p5
    60`4b<xQqH%4^R
    Eky+_Pcx\LH+!T0m<)y]ng|PET6nk'6A~ú\iuAP|Gԏ
    sM7–еUhOtG RZBѝ=C&jn=491xmˋJGƱ_AЙs8c=.ƚͻPFQ=$?0zriD=$#бE|SMNxlяs6xBI1~TP1g'b+cA
    `m<َ{'@l_u0=[Ik1u-C	eh&r\Wd?W,9<rW/]B9L<	,d?uhF-9XWtA^6^Z뗴VWB@!P(
    *,f]Int25m;>-]Jظ|&|P	0~:4+􇋰bTb=:rh2؈d9{z*<vnhW/>SG@*8w|nd(:thV(&rrarrZڟgcY݆n<n3Ьhc|tk<w}FYXXo\+hНv6$ዏA(N3,Eظ͠m=+syowT43WB|̜x]Y"̎qM.ރƀj(pv?}yM`|\WōEIO߈-kǠf^ү;&#yMÛ?:[zV-yȣhD3
    5=2
    ^atͿ7`
    3p|z^կVYLoeuNep^,EGh@K%jP[kdMɝ9DUmQ>`H~X^%*-9wt?*BH_"ٚ-Elty	6̼6w߻g4wIo{84-+0aPcB)N~ 4,q=h'~ig>޽	~
    cSX#\"J(
    B@!P(Y)Vjѧ=!'n^yQ_@񡳚aƌZ8yf6Dyʹx%	bl{v/>JC!1j|㉖|ԖҺێ眇]6�r5G)ԭ"u*W_E,Oᅫ6
    cǘ<1$Gpo4	'NCZMFXݧxoi97y//.6RΘJ~Ddz^`‰rpI�6jDž3.6h(mg'X֎4/B咎1FMftܖ{nݻYЁfh
    AH
    HJ&#к1OI#
    Tv}?]j#<SР6u)fr2e;OoZ	܍؇Pp#GEFuXgX
    h}_e!?uXmx:n
    <JOT[7x"8zz$nb&ܼwصk/LӯcFX4Dlg#)L	ՌkYӾ&Nݎ`ʰqغ(6D͡U,Sa:¯PيeY߬\=)
    B@!P(
    㝿mA1n: >>|{cE.i@ҝ|ҲrQaB+?
    P>Z;f9~ں\Nr+13vYRin׿eJrWiظJf³DB̦P9R#ά'#3tN/Fn<SXX`DrJ:pEY^G.h$mZ;1QDg[ N:)1ҩ<ODQqt^kCG
    LZ4::67sGXD®LFdf;NMNDzVf~VDǔqtݓ(o,`11˞I!i@lR-tpA`S`2 FYL it޷ccȽļ}ٔ	APY??)A:Aj[{hڒmZONK0iesТr/;-krx7U,-Nbr-vu hlnl5כ'OM|MyFpD@tVf&+i3<z<3w_sҮ<^}gk8._u}Ho-Q]
    B@!P(	AH'!I6JMX V<k|J	EiG	9Z/aÅB4unC;Ք0[O{)~Q0Іglڑ}W|[Sݼ
    w9^'
    B0)8k{_ĆޔM>hͥ.n[SJlq6Ytr<?
    Q"ǪO?0)ޘ6/S]2'v0z`z9xplrD?1	^[㻢EvhѰ-	n~ }*<xe{
    ~ۉռֹ?0|$>o}{)~˦Q
    B@!P(%4[ZjU'hN[8]QɡbRO@(W8S\oL1վ5LbI8v,>[.|DYhM9㡯#h2.~[لiWgNҵd-<5W';uiu]ŚtQ&CXۑus${,
    tvtj"QdlCzcݜm[y䪮!(~xguՑtyZ}J*77]ݭbl+.405k
    	m"k¥FەT2'rYRa2'HeTǬl:D7_3F'>?}WndݓʫEZnʫ=H[XuU3ढ
    B@!P(;nK+Uw8?d2U!WF5AU
    B@!Pr8:u8J)ˢ]y&΂vuuhMt6d3rƕgfJϳrFgr~.[-~mZ[g[L:݌O=z>]Θ=cV>R?<xyy	[%/K._V%m&38N
    Ki_Z_ͅ;Օb]/p}^)iXN{,-b&vmep_ckz,Y&/F~2ߺ"s[Ɗ}LHYIJ+}_zXRW{_mD$''vmZB@!P(
    BBLOOD#W^&ZL:#eTKٜQek&?yܩ~nLV$Mme.ׅdrAJJHcLs^C,,u㲥m\.'Ɯˑzeql8?"<㝴wmu7}!lpl+9N⡯3O 8/K{,=_Z[q&ĶtŶҷ/_~6~}_/sJJk+Ao+p[q}Xݼ\pзv/pe_|yy/x
    q^
    B@!P(uqE*U%Y[�'$$B
    m%eB�b
    :ϠI�Ly BB@!P(
    mԇ7c%<T(
    B@!P(
    �yvqns*+pt5\YKy]xCYR2ʾc*,ʤ,e׾l}2E+Sn׻%y�vncnxST>eͷ薷+;CnenVC|u2Yloަ;w`V'uP(
    B@!-A|wkwUn"|S)J/S>Re++F]V^}?&+OznlNӗzx3OZZI&c<K{x7|gDg.eUFn,MցW&dKO_OYe4fz;M_wO	*
    B@!P(%nO2bowpJsyϞr"~xKQ:t&cŅt(~zބ\#yY8}<KWd`S{duS{t&;ͻMۗM煣'†QPLgg-[e$87\*,\ĉ˸)nMP`¾=p%1ChZpDg[p>8~bp	^iSaZ?'!;vBrA=3!3*vޏi+_M8^	Ku}
    ـK/>>T=֚ivPg.˸4r(3Ov~;[}.5LQl#qU=gs:zfat<R3TW`ρc0=_1)•sǰ)XqO?N[q^]
    B@!P(
    	AgMHIIDH(8#>:Y݃5Ԛ;Ht!#I8G#;#
    Go[<C<Mc?`0Hf+0E((gGr{lՇ<YG*pԸ)._9֭[j*||1alwQլ?*D/YIHs]R='(^3AbOϪgaίB0@W2Ej<Qd}JbJ8M_kal7!74<3C]nH/~KYk}V@?D|t>*uX3ia~ƪ:*NP҂J[9eڟb
    qOXHc,[b'˘XKGV%`tfHȤS�Lw\}[Qk[TH{[@Gܽ}[LY×riWLS7
    BlkB��$IDAT@!P(
    ۺ1}s8wb^բl:S<�o_x
    ?-f#R⎠@"Yd5+aSz僼i&vƒG^DtzO\E*XhtNh�Q"㣜fr
    9ȷ8!48J13!=#pr/\]fc-Lxs.i%rvsEˎ]N/,N(,0#95
    r׎c"i0Q	
    %fĕC^N&$*p@yt=NKYh1h*]P1ނDWǧB&CѹM4z.$)2%d
    q[lDA6Y##:ἤ!=-
    ήnGp8	!/4@…1+D?t>Mx{SH΃paLs?ƳnԆ\\=DgVXL:؉oԣC-:wKdȣw/tv/| 8ď
    yԧv[V')deб^=<<Vo¦>chQ?.daV\`au77*GÏt	LGf_M[>F#<2Xɣ
    _?ƒaqC@؈<sru	dOJJ抐GsbQ}=ܜn	Ҭ	NbQ?D<Q[MH*
    B@!P(u}TAJ?D2#ocl6|ї(p@Fk	rr|9^Hͺ!Q|05t폷_{
    BM@}6w鎶a#?`F6J=q`l\8RKϡ[p.wb$"وkLD;کL|QN5xz0vnnw?6.1i(T"2dIů?|e…#۱cbdUl‡|ge`'.߃O]ǦLD\жUX'S'ADt,̖�0nu46Lx<"B:oI/C-"],v7fhjĜey֝Rn_R</ª)xz"Ȝu+!ZpHXh3l!
    7[qCѫss8aφeXG3l۸:-qN,]Ql݀pN'fb˨^)Y&'(4KG h.x{-냧^x]4`n~Hx Ԏ@!Wsq!9:!y7L0!4hxsػ	?2so#У
    ^?#q=ϓ=c1JķE7PZy"& "^^^ewH:fxjW+j">ȴK'N!0plz|5dOr]FNĄH7vo`$=8g=޾	\	˧q<!,hPOd\ҭGQ1&}S>E=E8kG
    L
    B@!P(:AD4O$uW8i'<8o	˿F&pzԎ7'cUܾ2,)gЫU7xosP7b)2dg1={;6&5GVN7F23ŨcЯo/lY9z׎|H\rm}W9deܙ<f *Gk3C䄉wAO3?O={iPޙ ,C.ڝ_O!>}zWN`xh7Lcњ]Db/r6ۧ%zM3M:D"7A{hNhѮOk#—wp0Ӭ;y`6MNJBaHъDYϥch״<w`;\@=A�QzSطm/ėDϫЪv/Y[C%Llޥ!~ڻ5ѣ;~etf{VOlzn`w4jm{L6/]?!ǃZq|ワ{`󯟡cOL32[w7@Gbwx퍁0]N`2DE>+ϼ_C
    pz<0YW]
    S(�W	ƾQ`*@DLZ>
    1G	޻3סS(ZT%k\Ä#1`@|(<7yfaHϦZ	00}dԙ+<i6NGarعb.u+?"Ljo=C\O̘WX{7Dz`WWUd\'lO7#oKp.�T?
    B@!P(
    {;ֈGjк]'9{K;|h8vcغr	<C=w~:Uc1w1cj'-
    hņWDxұhsf,?bQ^gxh@pp;1dKtI9u˳MUQEG8bQ_b'ʗ+'[hS|;ޚ0ڵh,^%Zt/0hpHU\yjҎGjGԄ+"7*xw1zxW"u~cnY^x5/w:dgAi	G&<Ahk%ɼpkfW8thV7D6uqhj|}`AfMYXH4V
    +~Ɣ_cԀ.zBW@={ApEŸxwzݶWt1o')׻	FrK@Zz&BcPZU>s.e 9ָg4{*lO7z<x-r?/GGV
    FVXzqr:S}r-i$u3&<_<v##%)><F B?nLMR>ky3a*5k̩S8r0RP'r~7^H^*/B|e\>q=[
    OS/к
    ZQAK4Ж#degАA"0ax˃K%67QDH8.[iS5n:O4SF6-0w7mh9w "d"]z]P(
    B@!оUVXDd9ߠ<uq3]$*uZ9a6kC"+#ĥfM0+u͜D*1ʹh:ܑhW}-O.yۋ$Wm
    .xBD17τ>!"_Sw!o_A˜jj;`kzunETpX( :#/3^!үW@zј\iӈȦ7ɤIC;'tH;kPNnnp!-V栥Ҏڙvէ&qo
    cu"Fc&`ѿ}/L:	ocSIq\#;w>-H
    ?bG>yMԪZŊQP3aJDD{'r?k7VZ#N70t&<xTfX [\-5;Ov
    /npqDrԎ()7N"@؉֏:wWH.ZeNo;mDrײi9iCmTO#VGr2l}�*F*-GX<w^xǟÁׅ=fMI1p5)luF4``%"N\@n#֤ˁ	~Qaeσoh9|n	6"Cж ~(nłFPZ�`=hXz89 0%,9)(iQCN&R0aǦ?ЪKg$U?
    B@!P(
    {5:ӷ<S
    ZgO	CL͞;MZ
    MqyN6t.bGrޡזrkހ'_at4\Ӥs^^K\rN%bKɮB:""0AtsGNf.Հ[l;uK%$ o` m[ˉ/n`dN~9ș0+
    fŅ[[Qjb#m8gÓۂ-zZaD-B`@d&`Ki?*
    d	^rIk;r
    T_oL}5jX71GwWĶѣpl~|֭E]N.];Һ}3oh/B-ρwތȽۛ׿Kx15͊LT[8ZH-p&B|t)?@3ª_6؍ډQrZp?qwjFȬر!4LT_7?+ѦWOT{h6s9Pj|i0@b\IњGM'/s*Wj.#{_c^8&lE(?\mrF@1I|�/ow&s^<)sv&G?{fh&>A/R?]Dha΃<;પ3I ְ'H(ZvZK]RXSmu:ZI"e
    "V
    ȆG~߹<^hjpߙ{Y=~9F~k-*9'^)CN6
    dFeROt9{'|2Xl#L'}	�	�	�	�	\Z@—?nX4dx2/Lk'c?bLQf}7܋ᓇJYZ(E,;\)Iq:T,30Oc91NN~ʺN|_<^~xʍ1uo.BvbL#^>>؎wWbDށw~RKL3EwüDwAjdD//O9#I#:M?^Y{t<uZwBG0ԌaCw)SG?}qsF>cg};dpmc;HBn{e҂9!ײaQq{).*dgG-=.[Ut潘;EKqߓb9Rq?-g~Ь(_/k62|_	vڅZm\sq{&fet5:ſ}$kB21^6*BDHTlo
    ĨdB),BGX^A%1=}g{8ի#sDVcGŸbr|2)[l\Otμ9oef.E"	gv`;|\y2=OWw
    0iTo)-wiq()lr"~2G=)/E#}%Q.0#d^�yq3)(˸V'kH臙׏į~;s./B"i
    e)pob#{0Ƈm柍 e7PU�	�	�	�	L/dVzjχ]elzp>g|U-E׷<q:,1t@O>,-d\Eo!p&tnnCDDdP,ũj0ww|iVI▯@T|od
    yzK]qՕא_5PKqFeeP#aQ4"ITSor,^/{q0U�3fS'/6Vc˿
    ˯c=O1KEn՘?,+(@^Ƚܕ/	=(VlމN3rsNl3flSl2
    -
    PGɘ:nP+exu=rY^,ğx02]n]ƚ=+S	4Z忁M5r2UzԸ|ea>}8e=,_YoNЁCh!}GLa>q*B ^|1z"n},>_DwFu`>cYȉ8.CGAya\Gl'
    ≧b˖M((چY6Rci뚌1S/EK
    ]lO65xeXP5wN.2‚_gQ)t8d[C}xr#'g;R]iuB&<'
    Y/"G	wYÚ%ȋ5ذO>|/MAɡb1c0f0iS=9!3d*/Js^+QXpD^rgLX6]7Gϱ99z/OcX+ڧf;v@R̩ oC'ݜHHHHZ@CU*!6??=z@~mK骡~[C}M\yFsWʬQi9rTKTY*ECk{^kiGGn2ӱDzzۋ'u<IiE:,Oz~ufc	ϲcO5VqHL7EA/j$7!1Q.p
    m
    .SuYx	##Zu${+^1jk5En2ޔ'݅+A1!u̿we}9N-[FZOq.Ljc5g%FFp=RrT&D1vPϼr@8wv56ke3~=.*ү{{.Vcex,|Jy4\\CXCCGNC_0zeܼ0Ƚ(/OD+YǪSqS2潓5Q3w/1Qs
    U'O!J;H?R"E̓ }W'ͽ(%'W
    |ROǣKղ~z/u\|C|OhBR/8:ɋ(/^ʤwoDF\6i~/}SK/e7/G?HHHHH:5ǡö-5mZ>DDKAyge"jIL1L[>-{ۖXTǡ[Nd,x^25v))l>,˓]`ƴ	ENzxKӂ˨q.xpItnm1.<v5dPg{cތyYb@9ӂ|R!d[A87.
    ',ew˺+0a)
    ϼ~ۤ]9(dGM6ZkCmٛVz#hQN9Fu:~ḥ6R}ˣi^gZvʦ~II=2~:򲌗,YB$@$@$@$@fǠ{zӽ2PeZ֖4UӽyotDMMl^y֣۬NZꨨF:RȖ4j8cv}ڶ8RY/sעxl=-,Or%d5gzC|?iħfT2
    w}x4{Cdh#^ňֶtkgNC|zrBiHD(7p'IS%~AmCe|Qإcmx8(=MӶ#жgVT#V-|nX|$n;Ss7Ym}ݛkpytia%5\eud`ko\I\Դ^}TTyj1l$w[ֺ	�	�	�	�	\5.-iҵmn^}Ӽco:u_VVT#ڦvB;F-ӰCjL8T[?xP=Rrh5w'IU[ZrCȽ>+۫sޤhgOd,#\J0eϛ-߹lN9QkT\j+XVSڎI;CƬl=^๑�	�	�	�	FY]׽ްa*d3Okp/hm}싌R]Ɠ03y9fE8_uڕ[ĦP
    77Kn5S_:Y~i
    (B&h~{w^2BF$@$@$@$
    $tLT:q/3pn5YH e+22L~١C]oWAm�	�	�	�	&Z-
    IHHHHHHKi5H'n�y/& ikPg$@$@$@$@g#Ф]+!lO$@$@$@$@$@$@NHf'k7ϒ$@$@$@$@$@$@$@g#d*2HHHHHHHAװv9߱cvڅv1ܽS	�	�	�	�	�	7f	m %%b8@f			f`oIHHHHHH'`
    tu'%%=qR$
    ~77       /F@葑nR@zA$@$@$@$@$@$@$Т
    qWwLzLa$@$@$B@R	׊�Vʒ@@SZ�&�	�	�	�	�	�	@cϖIHHHHHH @z�HHHHHHH@o=lHHHHHHhPHHHHHHZ�
    cϖIHHHHHH @z�HHHHHHHf
    ^<����IENDB`�����������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_filter_old.png��������������������������������������������������0000664�0001751�0001751�00000001342�12272200752�021763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�����6���I���gAMA��a��� cHRM��z&���������u0��`��:��pQ<���PLTE���U~���bKGD�H��IDATX혽n0|4*2u@${7	>C>�cU�*ceu4v|n)~;n"E]zZx<tERX3fZWS6Dfji7^k[);nZnXvnz~FWl?r0䠌!Is66s/�X5WK*ԳimME5,֦rm툑RiU\~w|JfsJy)f*R/H\`BvAk{D;fNY*9Uc/c3Qݍ&HXHRr($t+sBwVh?[C(vrox_Rvx8fziDdat*99aֳdu/|`2i&`ۑ+d.R7AMs4���%tEXtdate:create�2014-01-21T17:00:03+01:00F���%tEXtdate:modify�2011-11-14T13:04:57+01:00$����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/build_a_mod_3.png���������������������������������������������������0000664�0001751�0001751�00000144061�11740644603�021475� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��W�����0M���tEXtSoftware�Adobe ImageReadyqe<��"iTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c061 64.140949, 2010/12/07-10:57:01        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CS5.1 Windows" xmpMM:InstanceID="xmp.iid:49A5E7D67F2B11E1837E8BE7A41B9359" xmpMM:DocumentID="xmp.did:49A5E7D77F2B11E1837E8BE7A41B9359"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:49A5E7D47F2B11E1837E8BE7A41B9359" stRef:documentID="xmp.did:49A5E7D57F2B11E1837E8BE7A41B9359"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>u��ĥIDATxVkLU;3.Rж()@b-DCĦ?%@*5mIXS	@@X ]`Рvg\0YIKxrrsι|;.@WZ`#%9`e�1\js7*h2#(P@?iw4>V+^%ا˲!)A8:;%k)H=7_ʕtz׭KGWlGYxUamːBev<XeZ�yeb9c]g3LⰞQux%H8T�Ӏ26glP'zTN|g+;GN<rYWTm[gKL3 ectMꌆ<Uiϴ	^&i"q!H@Ҥjnf%cUq{,Oޟ)j~a+XD}NO\GsAA+q{!�N"OB&=W_oMKۓr"Qz/A+%WFcekgruqyFL6F;o!iVq5o�@A�)_oUNwxWP[bqLJjt83Aʍ[#kjV΂	!IRʡq'%(د ,mǺ*�:fPg^*Yċ
    ؗ]!(�Rb2O#i'&&+oL…䤃OGT7栰7�sx
    򵸔5.[zAp^_^2;6q}?uYhtT^RF؄O%֫+5<4XڝTdya
    W=J=Bz{{;:0U3yL794pQ*XEdsiۍynLSq@7B 	SN7mnd;5tlZl>gkH随Ơmֶbc00Y=vwwK.555AFW15pX,<270sp=LAӲLdKzf8&SAl]TQQO222dk�ܗLSWG҂[LFEM$]F?`fK-&F),LBpS@D¬*Ec0[r^޹w,}l{-"eOr@.gO`ކ3P '/$H૔[2_둟I]j.$fNmb?1p|P"~{d�̋>/ߋT5]4n-`u!}V^s3ku9yO@	úJ2ɻAɐ!빧iw{J0`#+%Yk�JWPD
    jB4u嶅BVq?QO@@B:lfev68C{ t>%8C{8>mYpJrU<0{!	f_ͅdL28"|tb8z&?AmmaS$QOa~cV1ڧ
    1pKAdVu 3`t
    @3ĻM0XȻ':Lx]&~0}~t`& E7;G+ը*OQ,mC/9xaGHR�R屖;�ya6DãFd Fj0D}-^<'؁GwY|/rC^<h#tb566mT<j7=_gM3G,?x~pٲj5&W\UݲtJZR)nL4M&%,AQт`+V*ԵTRi*}`|qsxdS*Kf=l:VT|fxR{!)و8^R?J].6~p5 [f�#.?$-=/܏d`C5EE
    nb&`hΟ:9	Rκqf1߿+۵k/IJ9uBwt`=Zx1..!,,äcpWYpLIP/L~ZlmD sLN!ɓV?+aH	8| Y7'9;=  <**
    Nzs5z~QCt:V]%�uԕ#	�1	(�XEJ.Zw
    (̸vE@\qiU*(+CTID<H$rssCLvn͜Oɽ?~*)D7�D!%3<4ud}YFcXGah<#L&W<�<!D-q1?$g7feǾ⨈`ќT('PAH&["?<B!0{{LO@gGz@/j%&�<.5;-&eA& MN@ |%pYsб\ʗ_i [h5W.8ݍ-ْ[{„XxDt~)osfXɓjW)6&\Z#	3SF'dV:#Fs�Ut[c:J-ٸ7Ӵom%-G,?n0[ߧMV*150(;eeqi{-~D.JuƖ~g&T;V={yO~ni5U342?Gz:'Xݗv|t
    )`zOaTJX(cJ铻0TWkV؃נ_.-?Qdx3͵ˡRw
    (CPU"fOq>hn\F>ڱYgXHJ	veŢYG?H5/ٜe"/QS;LF.yp. L`dGXp[V;A 69tkp<Xz$y-QxgG64u|f7*g;$^	aljYO>'BS*w*CRx
    ?q9({XM=Xg/~.`@ T	7�4f[((4|a}Iɻ1^lf[Y tC~&rCȲ
    B\!U\)c
    }RXkg`
    #=̙s45m궑�>{;A<[9HǛ:s
    jOjOv'
    sx+<*qS:"cOlK)rpɱ}RW�T&/I2TŅ-$ 6u+´ꂣHo|♌|/-:_8
    vګ8q5fnL#3ScN2=_d	�+\LYF^Pt:@J:;
    4-#/Jq>o"d&^['gKh6bPQr([>LpOШTɧczJ~@ڗ$-PUՍ)IcN57}|A+V/p-U7mڄY@V
    
    "U@'p;LזWu˺ĵAAo}ɇ1╴bVEoh6P@ß;'ľCYjM?oڲ/P.ߕKyzJV54"M@V5wtv
    _
    NZh<54T9p軺
    (VS$7S2¨1�S5M57jkL-�)P%i<jrr„V>w̌�(wW==D` J5H
    Ayy/yXG#l!Y	m*6Ȉ\.EC(Î,)z|lz*0"wHaA|9'0& dٳN
    &Pip{[ϵAH<:>	'0&LðAJfLL&ـ%Ȥ\7€(NEaӝ\.ݝN7/hbc`Ry
    F}['$Ynjjt:'t؉b[�ɞ~slo%`QۺgaaD6AnqAI%DsŨ%Ds5q*&и>"DYaPfXdW=EMLr믧):uM俬<>rJVYfUݾ-e>F|[`bXe#@*q,'BN^ec|In'؍0^a#JNZhOnK+_Fzڈ8:}JD*y
    C-@+dPKƏ,Xm�Tf*@xAJl[`fɩ#GO&ٲ]fBג#G:Ss߯O#1@Qj#q1oPd7lO{hJ-~@	bk}J,n禔KZ2l}NƙTWn`u[$#/CnA\̛x<r
    NJ#\/Q	tþ	(<{ieʙGmR*nqc\
    7"nam|hpFR:l)I7{k�fI<'76w	ٳ~+PxdMwmJch{?{vvKǁd`h"?td9*0u`rL.0lYtew};" }
    g,8E3l_aQT
    كJS=+*q=e+:I`W(FJRt"y;{j{!8ml]}n,XC\楫.=j&@_+$\;jx~	�,+PˉX3}+%,�|[-`FXq�<?cLF	2 lʫP"J
    
    A15's\qc
    PMݘaSFNAv‰Nw=>j-/<\|Zݞu:R ϼsvf_Ft[?eE&.Ƽ<UQcjDHh%OڔHPK3IcE%$hQwҧ=٩ݪ'<[1Eꦛ�g,<?Bѝn)1k_1i.]ΜjJ
    	?io>0
    gCKyKOCQjtJ
    u�u\tjP#H%Y,-,R,s)M
    э]l49iiAcImSѕdP4APA(0S,l/D9k/y,@k
    .{z,Vuw9QBs^,�ä$B"/E}>,/cPJ&@Qz6c(15̝v{E2~+#/Q;NAz)eA頻ӧuÜLb곝>;)7oG]QN^>Ga[]ۼKx+n~RZ]lC"\z3 Lhl=)T2P>MPS7HDSݽ<RwH'50&!۰1m.%4RhWOZ,$iKVUB,3}ݿK=,(Ti,Zyko=a##n$w%G@;X4n	g'gDOI'Oa[WRLE1ȋ?\9qɓҘ¾=.kF%|m/tگeCqgslG(n?fa\+3&.,a͚9CRY#("X!մ?ฮ�82vr%L;LMT*յk?.ڤ6664FbXxOӉpaCwMRE|m^Jv,،k	7A6@J	ܝ\pn[S=J2ÉO7X,&h h8ZA΁ ;m%(U<G/OQc(֖*{ 택giԏOqfE)Ơ<>Q1f+q'Lzxؐ(͢~nn?Lѿ1�F@+p5g޼S$fvPK-tt4m߄.1S8NJQf[V'b	,҃t:Ȇ#555%^
    	jX,8x`'Vj§<'N9ӹ<3TL(-9	T{0,uu	6{wo4Ăx&[,Z5RˊJf9
    !	f?~a|~6pNx~mm|8/]&XR(\Wy*a.Rkt,&yR֚֡='"5gM37nakk7Ro_99<o`ƌJuYyUeysq8y:';;;AUUU0k+31Fb
    3&^Hzaqfg:*Dz*b˾NwE6\�Z&;	Iqk	Y~Liэ!!?D;\P^\qv1$-=7$4H!].\0PMn\f(xyy8]xa4NߡӨ<M\h谏rO,&I v-_t$qaZ1hTTTM0xιW+sy'/Km9p>[`A}Q+wƌ3E
    &{!0p:܍ fp^,,\u{
    B,WTT<z`E4usbۚōM9@ a0.Tłt4q]xg,ZBxߢ6Y.({bJF-xӮ^   L…VC326m{\",=%�3P7dȐ^u?Z.==8,iu{$Y`s#U`*Sz!l=7|x[w
    p~8-IIUo,`{>F-"P=k޽ڑdg1]ccEEHS/\yRoP(r!./@1uCxlkq-xF-;Ar@=8J58ꀃiR[YYxHO_bpkf�:3p#49}07j}J[NTG:}eƏC$vZVfv]CM[ZrPPh1qK88ɉf#20&.GܫЦ\\\DL\I
    q'Or6$>>/,,&qCYEW}Ue(+4j/:Z3F	ޞd,3ݟ:DN\_0$$/U
    gk988�AsuuZ
    Ha2P"q0\	֦_Z9 _h֊QmErJʙٳĆLHN~50
    S ێ;e2٥_#"Ѡ*@7|?<DBQZZh@
    <S⚞k|Ba@6(j]։-κ(j[K(mG]⨊pE6a$$Vq$>y{6o\y~юL)cBǾ
    os;r@wt�ɳK`eQy7& k탺\mhSf/X3poAy%)n,LPxV7u_"<س/P3$0><wP}q}8ZjPQ/h)(I鬅�ȹ*}[[@Jaj<
    Gw -6G�.^5wR	�owtNVѱ-ǰPh!-5y4z34b(婓_)%<۠wyڗdɚ"�<sBB::UpIJ4oȃ4iƄ!a}ՋyfȰ7�>jPiP	"
    Y%O%ئLW(\.08it!A363Oߠ)$=[<!6@TɶOnX3룍w@\+Y=B4uGEZlȊu"xE9zmAԱw㑴T
    @`3uSb|Ezz>k`zV%aHϏo츱,&[WO
    _EֽW\ڱ˛{56G{CQHy<chRLkjpP'GYF&Ւ͖bM(u@Z5:0Dbj3<J{[mcPtߩ( )'Ӗ*($Nq5<<(ur
    }!ݕtV?RznWրcgkJ%־IK'ӷgB[;},�]UG88>mc"A?-Er~@bYkȷEw_\!]נ)Cg&rƠ�g W.GQZYXAP]SRРY?'Ǥg_V[)oE[5Os[Z-+' Ci{wS5R:s|މk]m9`oǩ}d7ÄmR?yR7hjUo@WY,7M-L5k#dC>3&ciAGZ\R|`*2*x
    630-u߆s4)v!hV0Ԋ+0[@9,<\˭'E8Ǯ#8DĝGF>"7gޯпe#5OۚI4
    @+M;f"|?=tqUia
    z-Cn(fJ(*ݦOZ ,Cڏ܈E/PVoӝPkah#Oh�R<se0;|n'?	gڕwVI{wT(7+uGFQ鵡ISWd6CחW6ES_o�lQ0:0 +}Ah3uVhXyS?3|bb�Cp{!T
    )>G>=[nΧYVal.:Bgݵ߄LZw't5wuWW\ۣ&Ji}ĽSzh')
    qp3S 0pKI%NB.nBj^B$)S5{z}Ƅ	j2R	vdO8;kd,ۧ(]&Na4@nl
    `(qB$-ω*{r{E^�ǡcl[_Ͷan[R@ݾ=sf#bcM;1WMV8Nh4>i)K8r,6FpL:xJi1w}TJ릯ꂠ$_72ǖv\9wT9…MlHzp2Ajb֯o8
    ׎_
    kg]1Üі.Q"	}"t`@@SPG85w<I>q
    *Q-h;
    >A,"~1)@lVG@	55LAG-ˋY4u:<,ae5RTlM,z[Ix8v2\C9PTGNШ?wxyQYo5[hWԎf/=6&ꗘC<x\-SVFݤi)ͻH+GǚR
    	6f9~wOq-2S]Y_WQecg^S)JJ,T}ewnYe߯<+]E5E%3j5׏;vZ:kjUèVYY>^WFm8#˒<V-6xabl>LS/okתN_2Kc4iξm>tVZ[[vƹ7Ί(ۙ:-=R%==Ч{U5`]䁑F
    |SK3yn{67?J*۷8طrPTT":bXHh5	o؀V]'=7q=q_DחX}Gݧ�r^4l,VK- :֭Ԡ VՕ_j^x?ʆj)
    ?U^VQx1];~zϊ;nVѫ#E/4ܷݚuVZ[hC.l>BvQбOJ33C(Q#1L]2Y|A
    Qh\ƛq}EWB#SyƪtsʴTe^@P�xXd$C>!CKS*zzvar;u
    6rEX˂P3+M0'd-b̞ԭ+w.LU`j:1NvW0Q e8YyϝjpR^RY"gS겫L@冮^a̎DMWln.AGn,~/*,,*/|i+E&}%Ӧ.psBm<ga.zqz%(	4/GY&J\F"y>]ҋ!cjлzHj r ܪ=1[M`V]+)t3*4p�!fd9b@/.\�A0f0޳=ߢt-+�ߌt"|f�.wE[?	J\=k{)+EG"J|?ɴM4[~)K*6ŭB,ֆ0Nb }=(‘Knsvu ܯVّ"_THu
    Fgϧ`ŋI;Ykw^g.NKϥ&2-CNjcXVy?ZblõgZu(y>s}42<
    h$qbziR$B䇓?-
    mBRP߻{w^=߫4,-t.!XSD4*aԿ�n&-6w3R}bt[y`|Q=с
    00'fL>#N碷,>IF XΰYׅ!KQ|'iG-
    0bRءzRkmLb҈ٮ\\3kW4U`ઓ'$Q'g1tܕvl6oZw`},k[fw默ݭ
    h`
    		v=`X]lZ\T}ϐ>ͳ"�@\*-6-3KRiMMM- {tYFB_4EP[x+dlr[uPΧ%=nCΞW^^=}CW
    8(A15w>1##ӮעZ\G_%m}H<^D,-,.wq>>j#]H6e laÖw`c1VdLR52"	k?ﰀZ1\֑:::S{xJ"HuvԨICNU81{VhQq˩L<@Qw;KrOz&LRiGG>y2~B@#�nπT^.wg`W[[k;KC"Փ99.^v$`Þ7d?U&̚`w\}CC9<G;ԫ@Wu[xhX\PPlb87(X7zFJKlH侾+'ض2d耏gt`O5srA<|6{c_3oWL׳J�A^`
    G>}ӎVN[[g
    EKgQBeo@/'>C^PfXfb'5a܈ZZPT	岺sVWffۡ@nX\Xx.5I3/7ǷJ%}u2,iJu�;UC|njMs� (/wp`
    vYr5jm/Zc W.Ϛk
    5p҂{
    }ۺNf*uBSqFE#k,<Q:Ť	WJ+H5q=N	73Z-icn2:ӄmHYz!!B9Z1<I35KXR7sƒ?<vڙ=:yt
    %Q5X"+.*zP.d)6nxeE;"&"D
    3?JbINt}Jy94`t1c?fJY
    ʊ~VA\iRcP(/xђ-�[	gzF6c.Zq%E%e
    2|Y$Hrҩ@i,zN/
    Tj�ȻOGtpIBm�{w虝J p
    ={QD.]`GL�F1w3?BQe.
    o8~zUUM޳tUM]%g?I:`Ҥ`N$"c?Y\t0 `̢Eb⫪)B
    iÆ%X
    
    ɣTgtN0LOݳu/G�Xu[aa	A{2])8^1vP
    <VZy7G}_ʄuEfdybܒOU7vtǷ=Á^|jt<I3bK?W�faܸcF>/]r5e`@o_z͛MtJ]$
    ϶bhgWA	660[XXp8@�H'hQ�4̜9fݧ
    `zS=A�4U32k9॰�BP�b0QUU]*az{k0b8+]dz/i5x*x+;`O_8koMOZU䎮։7hإK'ԶHT~juU?>bflط/ɟ.))OŅu9u#G{y9ܿatnmӪF?&,-\Kohm|[kffffF033K]e2	 >FfX<}#G�/�mM|	6��zﴰI
    v774-1{H{gvƞ8KK^zLuWb	|8zcO͙ /+PZWW}3>**OZ4I_KQ&"*޹[_i17G6Ah?#׹@o)V[juBBjHH	4a,H}}=혊ee55UFCop-|2ۿҽ{ճkIlBd=_/'v/	xYLVn溪I)R.HZrOOzY`4�Moѵ#ZAn@�\j]�ud񻶁iLL&kRi-h9
    m			GPS)HJҲ¯Gɞ'WjΜ>bsi]LT.SdgWJ-11Oq o&[H322:uwu"ʠ	Ze0@R)n>	q)Cd@27\CGT"TFziVVR(p711^'EwGS4=|VflR)Oݻw�~}tR�5|i~F<[t�EbJa8F~c#ӜMMMMݑ+j5БG,:7�j*>ij
    8Ӆdʊoccl+c%C_˚`:8^JG
    6&jb;;VT@rzw~Ehݲμ3;	o͌/X!ʥ9'Q/f𭅙6VX\d/WW^uxմY+௲Ŷj~g{ݔi@[lwk6v|¶z)�F@mu߱:߽	-
    }pР 0_j{l&ʑ5":1jqNJ6loJlM|.9k4@\Qs?JYmĢNFT0<)<9)-6)3a)	ᡶ{egۙid4+O4%v{wl5j@HHHtɅt'T9
    +gޭszcԂ?+]߯-iggEHM?2!Ó/ǫ8qi٬Wf]C5רjuRpKSu;z{|Ra׌Yjԥo8d\Nppe1aw%HUտE,R]6Ĝ42xXbL&k@RbV-k	8>~]ݑO覗un8LFk(zArNNnAw$IoYIUnԽnUI\keˇ#i>Jſ%``
    Yahv]\ˮU=)?(y�-.V'c}߳etb\߀apuٽjƵiR*++iE
    q)U2q
    @[[VVV"9!LUsa\VJr4uHE?D?#9#n38P+@`<z	IΠN+_v(%Pf	8^/0pkPo#
    DIZ[Zcu
    **,I0H$0O
    [B6iƸٮԞ&/JͰ3%iRFe~>nDPⁿm#		MWp�ğuU5|j4F;Y3ٝlI'4pv,V&d25:^ӣ�jň"=f">�ap%P`*v�Sa_G%ԃnmV;Le"1S2JI"H T	'
    ZWR.IE8iaOwݝ: ( yO^׼7<RYk\5:֬A<З"E\+zݦX:bsJs?EY
    $_.=<@LNK@I]/y!٩
    b0G}b3Dq(gu;݈2}-8Z4Z+I74Jj�VDD(xSOvHCGպ!fkC'k3w0SQT
    0(|
    DJj%+nP*xB<ԔULTJד`f!,uh)*ifHEdˈ<=G0l?ua_w="B
    �k>':-E�zsM?μ>Q3GB^{g]zc.LMKN%l6tFIJ3e5dM:hUm6B>s04̄{}|øOY]Ym0PUy7	VqถĂS4_Z;E/P' Te'{Sh\�ywTNzA7.j@)^^hfȄi÷`*l@v39[%Wf}.A/P0Vx̮eyΝe2'nKҟ=q]}`̌=?j{;@Vǡ-\o36[}crMkZ{*̀
    M?1}MUtzೊwA�
    ivwy/
    ?&jyӍsA
    DrƸǿ$oz+چlHyrp&O4bJo&7l~}zFy5$de6ަ_̀h$%cB`	,=g	ڤ]2%I1qQnMU$b0&0-x9Iq٢I37YO^܁qFk߬oBЄ0fvz{'x߬k	X9Yy$|vF,G:-ru<dpU4Y?~JIjaf"Yt2~
    ƝPE\BeY.Un[<|e4,QF'jCzM"Vh"`ղKR)}rj17*7p/@N|>zvʦN˭XyҘeB�'d,u(y%@ Y0i;#I*0VVHZ6z%0ڷ}\,�pYTT`R�ȕR6^TΘȞqX|g׮:fOϧ.>-5"%U
    @5φ^fmޔn,~QVx/&*'@ӯ!,&Ѫs8Ԓ劊xF;2:~a8=Z.~ן@npf#(4BU$'Z�"M[dw^pd\OJHS.4ڏ]3GYhu߶qq8X35Tb&"<}VGfX.-:7i%&w^}0aaRQwNhl=8jR&kdX؟рe?̛9~l9v
    TKZ(=G}Npji/ʠ[>onGkoDۮ<m+S^尺3@m[�ȵP	 +O۸J\%t5s@w%	z3:%b~ߌ2Riweh$a͖oJp\wHJηp1CZ5lNi4J%�Rd4m^0~-&9zuM7+zkLaqaԭ@৷-̓�:
    002}ЁMCw
    P*QJ61|=NaQPQ	@XmPJ8cerMor$zhi#$x9O@mi!b(AI6pg+LBIXVmxw
    eer	|{+-MθjB5u߬ek1IyI60/+
    qlu:c (Ӟrէj�j|d`TS1`bȎǶ>5J^J*y<8]]3j܋PavvT
    Úf:IZ/^|Y[24s=f2`02cra\<y_ȑ^C]MKH&>,q
    uu;
    >v욙.D_XU�*X,k`b4Ng`9(4f*ͭ5ܐy0у\_BR߬8i=8,a+"lfoRV֤;
    1р^=4)u45'd{ׅ>+JN>[/WW:TES]_2kf`xmdxV:Z8on<E7;-y~xϩwԡ"2k3P^%_WJ15&wӧz~cfXZVka>t,bw M.z�`Ioos嬢Wg\DqꌁFSˬE0$ԩ&Z~4F&YIW
    Pl.̘Kw`%Gh4_a言y^+̨%5!P|UWWI%*6:2Zqfqh5DdeYz{M 8T5![.:El6&&:egL>[U&nEb:daF=EI&Sٴ.RWqZrι~
    w'TS)+~FʏeN}}:6`J<[z
    &%=̵Q!u
    |q	knPp-CQL_efl(w`,:èB›ЀjAۼL??/LF1�ڂ"�)>!-I%۹]+ӏT$m&z`<ܰ)#~f4Հ$3O6"Cݪ>k$c"s7%K^Ƅ%eP=Ujܝ'GX<y<.~5v^8qq-11ML\t/!1sfA<vCY)PȣCFE.o2蒮o"eoeW6dѧT Yцo_G:8tUR@nt[P}KWUGKɯVLT8o!W^+*)/<3(̅|R؏of$i6iy	SKee0fE0KRfhh0ikWOWRmLvl_f3d(; S\&_J)mFו4a4J'442 jک0uٻsykjf18T wdK!ȝdb$ETeo"ש>#Y0u@m3CǑ7Ϩ(2vrΪ];bjL4랈=q8;.ؑC={tYt;'E9%gC/QdNl>yQ#Aѱ3)@VCGlBL
    ͇ҪO[?
    �\AITؽ{/^iv .)Н׉	3m|}c+J2ru?s/:d"F\E{yxxka5RFeoF޹s47?c֭{Nh
    o&LP//\e?jp,[P!�˲n3Pyk3;bG0pڸP\,&:F%xV*PQ@xjRtBca7f~#}d371=3Y7qʮ@?C`9oc1b
    C'pUI'\&(s
    wӉ*_~b(.܎ `<ZVVXV;,4b:MژY(CuM5Jr�2e, ɣ>JOɪw�X?|zxرLrrr8
    ?}a&v5hzN\-ˆ)8kQq	g	c"?O6B.g}y
    ļٳN#͍._/9{Β=h@F	5~wg<<>g%qJ4<DK; wܷV6=n-~<en=3e&S毙"sE'nên]ֻKԅCoL}~Ď{nc^%Be	/Nm=8&mCu/#CuqJ~)l- gz#z#!LJd&,Aql
    E4GOٷU$cR깑:y:yI��I!3If۹	׽^|lbbпBMvv^eE13SڱC={ޝ{9#RLc8s’3a;WbrگTdt	}Z+P8ft7<t\-YW?
    9q~FV"T	)rkNMsj'61TWsv&$ް^qoG܎Izi!)&cz*9``.-`UXL+nq<wztr5t0ͿPE}
    e6OYQ5Lo- LVB-d�X,kkp2f5
    Y$'z>r:*ꞅYzfo`llŠ6RtZ""~YZ'd+]֒T,;[/8ZlrE|!77;G]ıHW.!lk_[lRQ	~s'u!Mc(+gXGѩ�p`Xt}UEWVvan-
    O/8PFzGI:Uq=ztR&;q󗑎1дn=4e[9&B:Nrtf	uA!G본=@qJ#hMWWXHӧL@m�mRtt|nz`em6hP^::m[9s&{݌yam(ŒV%TLehGa<Y>橾ƦC~8.%XJ)3am(b
    CiW0f2`^=Z1|KUE^0A*u<F\H8tP]$oef�34Tp++K*_T[I&Pe+^F2,6J"t69BLNde7	akZs[G38*i*ZUqOI6jOf$FoyNNNVVVjjڵ!HX,6w8v~cc+tOL,jʔq3[* S5Y''M2~QPJ𽩩\HBFԦll]1&]]uAmK*k'LӶԿl*a^kP,CŽ%DlƠN5X-&?mݯKWgTue:yo}ֿ_St<!9K,nqŢ,f~״KuXclVk`4wܼRL⪪*aa(7A72V
    Iaj'Vgmm~r#)x<'6-Tdg<#A-MΝ<'N8(pߞ7oݿ{|==Ҳ
    9-=τ+(+-nJCCvJ%ME٪䔴Qw:8Y J\[[,x.4hgOz*ɓȴшQ3"^5 [M&E-`જiĔV0C<+GЕJ%0"#:j{/,6jck߷o͕btڴӦ3n('ďCbb83믻Ξo`LqETT:
    6zk"HD5hCPK=Ye٢Q	&N&uRoKI[Q.hc 
    >w>}JiI2i{&>$%%IBX$+|N@�4m0E+++i%
    بy9+&]U)=wWg.8wk~͏}ۯwɮgN:g0/ʉ	o'1YLjNxކS ;\q
    +2Ma0vI_s~
    g0lB&2mњ_]}Yv68`ED0n8�}g
    Nrs
    s;wx'Yjyy#G/z*n#qww!=�
    rq,)ʟ6m٭TW�{vֹ+Woϟ?LC(j$U2d2[-{0Ls9Ժ1x"V&=ȕndo^H$k[[+O^'`a?̛fhR.6!:&k7vL`>?z;Gr~BQ`ht޵WggY=ȭb8pw%kiP� i[VVkˀsZѯ_M6.>mSW<6nظoL1R`)(ׂFpe?;G?0#q\_UX\r4U$]]z<G"%ۼgq(\1~IJCLt,KH7ϜeTQ",`յ];3
    >y-!0
    ML9|~qA)&>;(0l(LpL$OO͘>X,7~̖#\Q(tπ=}7Ԅpp#p)
    _.i[eaҐ=sU(Y/	T,%ETFsyhɶ]+2"rnXæ+~vݏ\Ub}=/,+;㺹:/qn.-p 	TʙF9]#Ifu!y+sK|]HC-a/~ڹY&%I-t߮S*==#Gp9!aK뾟56-.|ݧ!Cz/^8M*@^Guθf.ff<F )?%$FDއa='BFy30,="/m)�3נ9
    B~1qCF*Ii^v>{wTR%uc{tR tư,\8Μ)zF6nۻg
    
    Jƍq>++Q<Uo^^{懨!:sb5WT)U*.ik>w/wC aܺDG7hI>0++e-]{3^;BMmO^]=zgRWTv$V*{p=fefJ!4J%.Tp~{``/vag{046.9==)=RZ4k1w7W55WvEm2޾(Ļ>8OEEps5ѣV
    *d=;XlT
    `wްiKо=[_s$6Wv>c'nkaEM.c)N]=CƎjllu^jyV!5Ujj+x5=}Ad&ܺWOo<V6<]ں؉b`X5?ߘH*]o:)0`ȵ	PIaŕ֓fr.k1(@kbSؗhj`+K]TY	7o:fo˻,޴U|(}W.B7*{p4Se!1*73߳Coz:5+'_=\�PS#k�W0
    O\dٶ=:{{yѼc۴Ԥ;COuncc>Q..vD02EiYixxlA!hQ&PB
    C
    @UX\uҁvgTPv&;"`OJ$ha*T14Ҭ((ˤ۱G7ZZ[lPl<6jqDHdhv|-m!!B>pw_;}|tߵs߲"0鋚=<z~umS.޺{'Sy9n⒒Co[|֖֭&V&$%J)@?\AϞmjkV),.*,obL
    ,m&LK1rpk$ H𡠠0''Ȉӿ_[K
    >$(*(\]'
    r|#_M3N]FDMXR62X&LGp+#~ۍhfC~Z*3_lՃG/^㏇/ֲ躁,)yMJ"=SWupKO�!G5ݘU"?%/Ok<K0g͜&(TVci'{4q—Qɀ=߭M
    *ZTTQ{w[M-:`XEel>}e~^9ćX̓AG=Q]~|lԅZ2Qhl\aq;l~zqw..-;{ũS;<9鞍1xi󡋗rGSI!`L$..뜲2Œ=iH:먎]]Iicdc˖PUsJ	J/ǷT?
    UX:TI;xZ6D@0df<ɡuyHjY_J̯u�F8gя!IUY	A�H?SPX2f'IE9ӾI&޸i<�w~	MjhX5FD-E9\FuP̘N3&:%%%-5aN0HB!-Za3RKAAc)̮�_!t0LЪ0-A'oKPu5Yg~5L`6g屣jj~yxvû�ssc67D]@upݿ<{鮝?=~v"LPkm%*(i.:Oᦧ�ѯ_G{zjySNȾGPd=Ff=3xfH0	b֖~,ydg^5I.g?DvSԓ0\bް߆3f${~SD:.]<'H$7+W|*"s'pޒs{KOMMM�o-53 lWHKK۳wyz2SjHvq'1'J!#K__(?_ɓ+1 W*֙A@HpI͝^'Wju!]Th=H4	Am
    C%<tUA&9+PRLw##RS+פ6 <6L`*+++*:M.LxȀQTY9B҃@
    h
    tR
    iiY\woSc-2	J
    ~*=c(*5T+x#'Y! ,x6])A訨9s},z _VhFJU:LTiŏWWLLtiNe	id�b3w!s5&ILX&{k>t^)=Z*Ciitt֦fY~TJG99+((Qƛ�Zр| [-=fU-YllnuɄbKԅ&&&ZZtA
    /42~fN?M1p@vg=G.~VVVB
    /kXBErjki[YYZXX�Ƴ,5^im?<!8hy'ogj3(+SIFiR_~n5�80!55-%%~toiBԇ	)y0$ln4@$mnnTA"��3H:SLҲ*	$@MH֗%B+	S*b0a`^GDG8	.Zu|)2`$:ǎŸkzDUmLVRrNtL	�6P7f؀,S?bb1�$Dc0HԹ+.%UbCC`aݧDq1��	t1m`ANT+'''SSS'SV0NgdL}=:H
    V8(QUZZ�7u`_%[8***D"QaaX,fhp01
    LS 9/WTSMޓ:W23,ݭt7/A1BAr�}nu޺u;0H5�|rrѫWYJssS:v<}NXUmk`Bdeeŧ%YB<
    ?ӀVo(WVVҫy^|br?
    wotbQE%vη�]XWמ}aYXX:""`kb1{=c/.*(H,lߝߙ5KsYvgܹ={~]}_)UtR2k	1Hhn.8_QvSk
    wn'??&r1f@TĊKAxdh[xiZj!h_Qd+.Q9ZKN6u`(Oe[͢V6_
    x7d?]:@͕(Z(	p֦Mk~E_"e(iͣ;X&(0@jay߾%&_;N!H~RXWUNv*_^k׮E-i*f
    Oy8P^]GȬ_+
    |*@9vv}*;(bJKF	}Ea3yyzF̬G+Xypl|^�0'$e]9KkB\]C_%
    TxU'Ӏ.֖(ɛF~s:<)Ls<.Q:i(͡X5B!RYt?ydpPWF7SQTࢲ\ʄ]9)F	)t0l^Gf#53b*NUnd#qV`X(
    	H۷w%+.\=[+LT˺e߂
    S0PF	-8Vf
    7p?"F,)-MIO7J~	)PXm'pP.Ne\hj?xX(Tb:rmmFf7JۓJBHDa*X0rj�.	WCS!uS8&`IݡgOLf߼z99nV&R2Xubh`R@5%z[{>bN)EUvEĂ66i`*䅋o>ۯWg`;EDV`gF12/׆^mmR_(wrF]xC}ln$EŜf|YpK菷꿃0fyeSxXFX[ϡi'O
    Uh|Hu}_Gԋ"sL`R^cGG招WY-˅Q=z�֪]'81|ahM7YxNHUK]~X(R^ufk#_Am=˜4C)CT+U̿chӨ
    MDT�]N+*eؿ& 3:7[nDDł
    H6oާEd™E(14ʐ~ٝTԦq\Sev
    ծu@ãg
    aĥHzW=B:R9f
    m `'_=;=D1UyiЪsS!z-00=L4t>
    ?%~U9׾�˜څs%>ˆAi&)G;V(Jݽs'!g9Qr6-`sfxaMVX$i2rUqp+\0̟
    ^ƕAamr	{r^fmX^a'8SOP4׫M>PkY&H\cr.?�"$]=1~&(#
    SoA}/C.dk%iJlZFnyt;bB -<m9\/{z	ӠF
    _$]&5M	Ab(l87ri(�]L0t8#<2>?r
    Q#
    ,jmuOYrVS,$Z_KYd'C2"/_F<P7P׈ԠE])x_U+!0qSm4% (N@qGGBWbZ
    @P%,d2TTEfue@q#1\NhM'1{*	OMV,Uj(3Ǫbs!.YB`b)Qi0PIgٶ`9m:܃aD}|�BYL(E#'+3VD\u+u>jY'wPn֒(`ry7n_<BP"+y6VSaD,RME|@`1Iqti啝f8B0(XB*`)g0b9ZݖEWH|GΌ&kew0٢ضYM1ϟ^{>j0]'o
    U|H|*,1]FQԅ$p>ƥ)iԗ/$, `D1T??
    :uE׺"użf.sf^BI&Ǯn1GWu/#50TEӈ` lQ�ؤZyKNZNMO~97E`ȴJJΧI$"Y&T4=~vn!Ьc1jb"E8g;3u[Ժa?O1FKs[Q[q簧.NѰXF(P~}]2qG~8_&sՊW*
    ʭꘕ8~Gj۪Tv ^k\qZ}*Tc+s(@@nl#Tgau0TFX'"3J|O-x`Ѥ>f+(gܵ?P-8mxX.e\^*:
    nLDz| $WSɁ~K-ڭ.o9'AݝzM�q9W�LfoQVTD4'qa/C|&aҽ(
    02xYRq`I$Ǚup�1BÙ'^uqI]zF8;,v&c3-O9G~c,059-DV\:ֱi"^
    Z>?z;AG�BőCarNAwx	jz3VzAGE
    M�Q~5P%y9deGwN9	rM(K=N`^^"T.Z^ȋٗ8mQ{ZKPcAkMJITQCl,X&uУ+u[81Mnﴵ5cPz4d[VnmeJ2o+w]y\=qja\_ޮaP+	F".HN})!O
    ZF_#D\R6*nL_lAP
    pсc4*rb?/E4s,*.qV~XVݥ[l>pg
    05G"uS�V<]ga2mʹ`Mq4{FQLaSaw �`Z{o#a
    R`h5(n5Lx#d�kE
    y.IQ3hPUlhVSLf
    		•eQ$MJҔ4YV	6wD'gQg4{]8ͽI[α03*떝v\xi\(BK.Vz8/7SƵkQ'.<iPd	[;w{
    _k+"#snFxʨyLE\o[wg�{oP{^D9#ajtSF^F跥!UFQ+#_^KˊjN#�NV\׵�oh$.u]mϠ�~"Ҕ_S(F67ʃ-]{�gλYS{fQ8b;ڨL9eG苹b+MpiV&ݾ+Mڙ1QW~.̫(ߜ2~4/|0?r!.9dBRFܽQpUEE.b",$n}@�D0zQHUi1ݏ*F^ͽ_+	;rW�0W	!׏Yl"�{Ј@
    o0j7JJJJo?G(0^\W6eǧ>sul0l'\4;IL4۷@! <LHct@x_;Qh�~Ю#Mhy	;5wK^3I_;bϢgssS\Iluu
    |fׂ)ִk=pp&bVϖ2Q9_(oȄIȮfωN^w@0ݨIW-/9 \+?7AlG	rreem;7=I<'}=;mou&Oy"{׌Q_94o  Cg#⤣ܳO{-Py[N58i&#aXwna
    sH!]{�K["h'*	äL#\_ć!3A:
    _=`P}~˭qo&V\zcR\O:=h\'q=5\k> 6/XQL=g^i˜Nnp}42o%
    0R7o,"Fq
    qSoA*@maO,(
    Ea6Al(`Zə
    eeD8vH^5\xbq3anBUV�e005 ›@S`8\Hߴm>Pjn.ս!_jOKOs=~_yČ)=w]~[O]Y+&)@иPb`0
    P`MiN̰bEtBeQʨ45*#AQ!^�D.ZEo1jT̈=8Vhc̘^1}Ado@M8�ɿHܩRAi`PRmy6vꌜC%UtjԚ48`<xJ浇4݂`"]ѣ3T7M>\`DhҮn)Hh>ak	摂oP_Ҿ{;9b{[82f(RRd4#'57?$	vMWGV3m };Oq{cP )R_ 09_qw7IS(:x_@8rǫ]s02:=-
    sdIE�aXiCzmyO,}ܓ6^dv}IE8;pCێ ̴�M|ܞ-zx&e6bSʰŦ[nPgCNV%o6]3s.Nmxң]O)q2?dD󨟦\~K<Wi.Xy>ݧ~n9yƽvmqx2Gcg?Fz/_fQEB�
    
    lhJ؁"a&6M[0;+?Ϫ݆(uU"F?Z,S4q?a.̔sR�H]~.3e-R sLaHߩ
    X:oWb1+MĂo؛ĄΝd$Ef{ujby٩c"3SUR^|;"7_~L``5nա
    C5#	@A?_bU^n;YPAQ6CLʊ$R @Ӑ2y4e
    $H#۱9]^=գ�5@iwMXhֈ?ljIkcLz&I@5o 2oš^G4:hi
    /۷Llv"D.ꙥ?.ވyjɖ;תO䟘6oLdִ?>_2Mq''t	4b))	/xt6Col4	(9~!`4d{.i#cy#MZi’NذxخA9u
    "﫲<ox%2fDĭ/~*(גcɏ.ϯCq̜P:PMS4F[EpCUl0ލ֐lP@Pg,>>nVI+JOӁ=1ϋ0%%ǼJIJԀ#a 	s>oG\x}AvZiwO߶gWo}R!~_P	 'TiJߜP9�9֌&G`RS
    /]eG3ōvZfb3rEU,vZ=bx1eH@r%SN)�}Y#~b0N"`",�v Lə`IF1D8Q#r7Xbm@4�Uhά>Y
    6=r.�k8XĀ,|9V9sQܗQXVv�#5p<e}E @UdM:D<8fcx0d;E6͝{Z_+|PNWHvP52'k}(B
    F9,w8}0Nhgw*P=B1�YŐ0VI%Ծ쯢)M03n[ޝQ�Z5j$IN,,{8-31;/0п;qa[T}�@%G
    Y*<WTXLe"1kM~}F
    U˛7%A&cfŢȫ߾+7rdO.98873L7n9rөր64ҁɋsFY'JtucE1]I&΂?I�>̃^	/KՄH`ؿέ$4D8Qg4o7itr
    v]"sgb5XE'LzkS&.065ǽ;|f8t`Ln[nEO1ޅoݚ/V[pm-R`f�E8NH]A9wp$&v�V˛g\̈)<XBD΋
    8+2
    PةU}~˜ 4Y#Wæ(hیvr4PD 55ƍkCwry܍6ZIOLLL-S*e6d`
    zEːMyd鏣<baWaAP;/r|+0GZF�أ£z2YC4i$(MC@qr"'Pif:n_vs<5<?/[C7YA��`8]MBf "Wq�ߘ^
    v&`(1)88.{P(rHeQ=y>lР:%ft'^!xu|�fѤVW@[FZ1.r@9(Z=fWDĵ~Wj?G,<Sb2<&>qdwHj/K=}g[;Onj, {^h\>JٳZx;^:
    ;_Jdt2F*9RYF2H]Hhл:zmZ|!+7yѹ\gIpμ_wMÁ?_~䟧ָ8xMK.]<q0{Fx׳0<zfWleeA)F(}IRN(qe�9Aq
    ݽs?o%qؗ-,
    "4H	efhR�U|@MnWژ+
    &vm}0gUICOKEyG+*aR
    (ǂg\WIhVSt؋oP^Ύ�#	ƍ[]ҾCm*MaH5h`&eFFQZ(!%6-+)eуl5+I>_X}DHֲQGg;da`?ӫMZ$$r/v '?eۡE"ٰ?=xz%-+^V*XګO7kz>Vet}[GHBMӷr0viB""^8ْeivXhf&vTjiwRȢ%>x~תUә'ՅI+;@gNg8x{ԡ޽;r$$
    *&'ضQg]jyNi|D/jrH}mލѤjH:Y.hی
    n(@dFFfX؅o]4Wf5
    HMEה@tZeVnZFvZL؄gEE*ux
    PŊ<Q̯©;g蟒d^VufkK.m;^yL˻ٷ>yqM޵lۯ	+zp%]yqr!cҒA}R৖)rƟ-8i肟'XYi	V*/jѲ^ou(^uڹ;?!1!I xxϟ7mLh{z-{W6(uEX
    *v1EcueQ$k`Ci"ȱm]ٷkro3D�g/&PFc]oASPܫuq.L�M0T`@Q�OW/3f:{答`9y9{*-]lSVi	(Qxd^cz e~,-u:
    }ҍc@Y.hEaR`ҵܛ7/w25Ѿ{N%R[QlۡCwldrqq}}?bR)MF.ׯ-;
    W̆a"UzQ%&)v2΀HL\`|4lUoe闛hN6㓔Ips^qGmqa11kzƩ(Qe�^O
    HvvUJOC5مD"Xre$7#cbԭuDn\\">R2{cO=rԖV{֮^klꅱ837#:)ŹNn{t
    A"ɹ})/"1k8שݤgQ6no^S&f2
    lϊ|rԫ"V##oY4b@FUd&"3#^feXۑF1gP+7Zӕ/y1YHUzNj!f+wWSXEazJҩ;wi5D/ߠgN^<\"_i?k?Nei%	
    ͚s;޿9);9zʯq[s9DppB#Z0p@굅׋_f0;
    
    LA9=ε#
    %ʄߋc~J|]>mWi9WfP&~T57? cdHAudI
    _@wԕ0NuRR.{L`D`^P9;vUchwgìt>}:/]D0oxTŞǼ8sgъ25\PΝF`*3G!=,qsթ%?n{G^A$iN*p]"0&UgP>r)wZ8|+=a/ACc1sؿ6225\	XxgG]+s$2=9:78lY!}y!iJpt,8Ľ37"Ki~9_*
    BU}d33[
    ^
    VPֽaU\HjÓ2Z�'zy:y.d 
    ˼hSQEQњnүZ5j=O_B"u׹4]оmS߿^5F>	66V)I۶Rb1`/m߭Ocbq50#,x~Lė?r":.z\W4�8Reiwk\/Ֆ(N9M�@faDz-aMp򗑭F4T Dvc; 
    8[7':2bdcG,YΞ4h<jIS4uHπ$
     t[[𡝎N.oO1g₍m-?q}6^=Ε'YԱuo';WN:yis7LTg؆KcwhJ}dISu~X�A%5omnsZAC#ő7S/{J&gxw�YC$W|](J8pk$>gRݿ&zcag/3~_>uE$�<9*`똾"͝]s/lީoL)=Дt)k=^JKi
    smgYΊ'L3�;7wTuN^7Z~N0%fBAk4hwOL
    1[6W+M\"zmgm\Am٢[rr7rД;9?�5{; v<U)g}&(2Wڌpme=sKRoS=6�
    IyYFf}a#H5k9|l.QE2މ~
    *)J(Lܙߍl׮u#;unvV//FWN;_dAqw߽}F"15{	hbE08֦M~ѳ'3 )lb@!e￝qɡnxe:!Dn/$KnG3<nït}-*:*S>6f<N	ƭZԶ.JM~[PxԷ
    A]^zQ,g{qM;`NK|ړ-TM/X7/Mƨ (n8}kQt[';g	0T$B֯/n_L']sw[#݋/8l(S.,WwufA2Hee�XxJܴ,D,ioG_Oʽ<Ù_lXEbm'yV,f
    jڭUvvAӥsȑʔeOltqǺ
    Һ\GZz3;R! �"+'3}4ZyZe;�U3ۖ�88oFcSNޛh(M@9t&�;w!vpLɿoj{T.w/ASo0OguMF$XM#2H$iѢsǎLJGT}cE7+(¹s	^ӷ]Fv/^dfϞFEzy0L~N\\;rҪN۶JK@ڥ}]oIGXxgo2LG@%(R(:y4o؆͑3TBhRH@1BNm
    G&Po+4vXnfn>~_vv%@#{w:qXfv雧to8's/CNھ/u;歋[En6pş!;{yYuOxA/܏V'Air:56bl<B\ap1lk}[{KZDG^|7>ĕ57>l8ۀ a+j㊕kĬoמloݐ.]~Tkl&�iuOID=	h3]NzVV&	xȗnLH*0w;w΅P̊20Ntjw̵.VejPsI:lE;P(4VJQI+K0Jݲs0pvxzXY[<AHADShN߼d"ZLf9p`Aԭ[[l&g�i!ݱЏӖTj{P`*lm?L�fylC,>vh@^(W"ȑC-T*!
    ;MHL{ߵKcG@7#>Par[BhDaH
    B	6j&YфID`#}~gm~|aD˅BV+{b
    eJI9ig~BԴA~⊨IN\ɐH5kÆWw?
    q52;3	h jP+F&Vm|rl#Pz+AY
    Q)!Si_Jbb5oU9uZ/~煥T$ry(R*-[J-ńbOAޝ0qY||ڄ{zڸyrrM'L8E)hΜ>ۻϸܿC!MLL8aͫ*B@BCfd!3dM-Ln�$Ihsc9
    a/!0߿kVJj'?iA,8z}`AhZJUVV@AiK	DƜXjah<.án|,	|
    j6dpzgSOz\vOi?yM||JNVX,SZ;[4 X,@�pvȢZ#3OLAuH3(`())y;բi3/h
    KzZָr8gL\HjyhpJY1|UUQUޏʪ<gX)FQYۻe%
    
    {
    hl+EF#@,Q)%yEAA2Y{'LL;PPӕveO2GY֬^mߞߌ`&`˖m޶〗맭dv,wI7‡I{TYWIC-}p$G1+>C_0 bxƾr9չl$	xN-iMf|ig'tqpr0zZ` $Lo_x4\C=zn]Aϣ##D9oz^aCUx#si?]r+`?㉓FD<ielN	6}ⅳƌIt.8:Fs�#+,`>g㠑cc5e�M+e_�8P*~-YX*7zYEM8t~~S.ߵdJ@_XYI6a<wͻ02?,1gꬋAU9ɵV}[i3�?�o1
    䏰^dz5`$bM�"2*6ºu,Q3
    8R悃*щvpBc'CLO?aQzzFjZKRCLĶIW9{T2
    tУ[}.ضz衽:{ʋ7}<{ѷ}V,9U*IiڷXpڠ.(RBJ&@DyF.^zn!vecm%	z6cirհnղi-s-[ZZ	{UbkXp#4z`ZDfzoܙ"3{*v[Yi1vOXx\Kڔf!e�te(̈́MZ8w-xJ>rŠUb`�	>N$MN66DӈDJPK,pei&]uz&"5/]@#)ɑK~e 7iKR=~Ő[-ٽH{;ΝZCB/��|o>~˖Og))*ys :k~Y>srpG2qҒΝ7kѼEsW.4Չ)ǵg%}%]˝
    )UGҊ>udV[LO?=vnʱwEfv=1F
    u/z%>'OZ˲M`mF,0	Ft`ڎ`sٰq?
    }6L9ɋ:~"3k.j
    B.ԫc<o
    Խtᰍ54gِ'kf
    BcV,\!tʟ3'l:~Dn[dd`3F"Y
    >7fPM\�dAks%%*ʒl$up8"5LCֽCؐK
    xGӦݻkϯ>'4o)3yͿ4[<=\jO=OwhZ1?c@uW=AZt׎u%%CҢE333sc|y׮
    .L֚
    !4aiFV$HJT*TZFf
    Xmxl@P�0IQfiki,1Un!egs+vM-Vx9Kď_%K-8Ƨ	Z/|3|X5D>8py/1K$bD*RP;_IA2R6mٵkǏ0h\蕣笈|rsV}a~]4qŅ(7SaӪ#3cF|yLbaOōgɎNd;{ݚu,xG?Ӵ1k׭=t`7#nnnz8QC(-W?0$P&v*Mܭʼ@oJB<-?COpnsPL&3rA!z5.T.$"RAcnέeRK`�V,	"@qAFLIW23FqzFޑ5i
    
    K=skC&:|#mzٰoٺ`hvڂ+2Mx{{\>`0xjfϚDJ?ao-?܂R0`#2\dg%f&&'+
    LXBQEqXϒ$f \>㟔9f$d'o=w%]ܯ'R}\a=`ZԬ>]]IRl.qq #1ۓaZ"ہ)"P>
    �So޺vݖ<E6O<wמ�E3w8{.]z}A߸c:@F;�=(
    
    յj*xܻ9q
    �ÇXj]mRbp"^[2v̜/Yv3@]=s?n0&[3d|#3DΓ:ջ>U,ZV;J5֯qK'G;�|>}G*ėBwAC:V,�T\BuwyxZJTseuNA^fTT+ww9]RRfg'kذn~wZ5,777<…u\/]ӥxsf/XkV<}4Ҩ�ڵf\|ѣyhޣiiw4d|BRp`MP$Г)ֲ?#zaTJ3c⟾J~TP"
    ̈1dj^֌n-),θu[j5(f 9PKTYzhxKum㚖q!]h2	xGw!QS7
    .n`S-ِqcm\goϝڪeC89,`ɲ
    B똛ڥЧQ/Y1�}╋o73+wݚ9;v-*RDE]"0Hju:Я�5�}#'$;G,
    -]�4!7~x>lh5kg��Q[WϱawF^tɪΞ9a/e|QPpoJ}CG@ñ?aB%B_:C4kc#xw<
    "̜&)X_PRut8K%Rd*$B""/7/4K}dۧW[nx(=J;v	#Kvqvwtz@(5s[|y;?�vԹ8VᣧmY7baw'NpH>b֮aB<0"T,t5pqs-͙Q
    ٟn|;q/3>B<*RHϘџyS5n4|w{`\gwt3|/im7hqtB٥Kಥ\܏9ϓW("c˗OQQY~l26MNAYq	lM-W[7k@WΔ7%#(dzfo};rԨ>MuptI5-0ML۷Ϙ5(d֌kr>u3N  JY88O>I,ӓ#<txQj4PV)`
    :2JQ0fQJ,ŕ0X ),T?sscJ#z
    ٵ3DєbgˣhS.߯;vl7naaڶ&;r24횗_sKٸiS-\qƾ]qߝ\ b#?<piC%"O-.vul8:$8P^ԓ?&N|@CEpnͯg.1}ڡC?`oӨI'ONLH
    쇠HzC4ˇ8k]6,4ya0nqhԮfp6,$	}$FLӪ‚ԬKO"KJ7͙8Ҩ:*4E	V�PersEń+7+4PT5vb>7~ӧÆXrNSŽuLNN>/E+ULaC{۷+ lt!z*3ϑ&8x/;`(SD=ϯ%P`^D*qGK P*YY
    V{3;E\90,bb݋ڷl䓗bAAJZlFKa4qopvpԱcGӿ|rB1$8o\n(.SظHDqx<%hpi9<prMCwz%"aiWq
    ;U㇡̵]9|1IQ}>Jllg-`/]s;u	Aʁ&;~z Tj?.6~!WnV#=m5EaAu\\7._DNN! b;3Q:bsnsuog4PTaih؜Ԃi@^r~2+b?~=tH׵@,SK:޵
    6mitjzL	򱎁LA^UBxX("CpxF>r\"pv`p*6Р�tRvvg'''VVYz6; &&ۡ}Aؔ$=/vNgݐb31`u}<LN:ZC9"\p*4]KBEOAR@[	e10εe2*'tKZ#'{999m΃H]59<?ґRF5bZWzF-c+LQV>McccGD߿j]-6oЦ+?Lb</[|b): *8̬첼<-Efff"lS,QjZ[3bFRXxw<;ׯ߻vݞ;oN
    Ͻ܃5rϧJHܣ<GKM;BޣT7
    u0”hh4?V	�3-x˴h?MKK>•qp47!|,)W)5̊fMUk"uap{mZD9jϗo=r'+l~	xL·mG|`Ϙ-@̌_v|<w*xaєI?]zV2S'o[ZnEOkCK-]>\G~gl2�)gA9O.qLX~~1hIkkiiЯX,@=	
    dPk'ǘ*TSPD�t�/>
    أ<@/b9으LA66母,`FDv<e7UWՄV7xXHګ9VhH1qVNNVVVeOq6myÒRμ\n̬xzQC>I	_9r6:^^4mi$-G~
    @*+uۉto^zԶ1^-&+z3}^r.IQ~/x3wΤEBf?=~>{Q'gg-^t
    QOC|FI9q̊I	w=iӦɘ?GF\װVStzĹsf+lmezuőe2Ct0&r
    3TPtBZ\P�\uޕ7qյuHȖlCb&mH9LK3L)3mgLZ&&I!-ЉKB1p�sphFFúlZIwV+@0Xwy=^b㋘l/@1M,Au+kfXxqEJFssΆkWgsG#~*ENV~:#$V\ipb~`z{-sj<A,p۹�7Sz>((k
    ^UT8E(0=gXXZLÉ$c=/O	E%OU�}%KT";3G8�y[Wp}?y-p7oݻ^پ}
    c'<V;wMvۖ_lq%xPkT@;\}QsKc4\!5[8VYR_?[WW0^E<'Si/׎A6!`CT8G"|ó̚HebCMAsTyF�:DT?J9=B,x`ަRiPG>QSy"Xt.IDGijEIՅ@.saV8* ~F�/ <}幦,(;A36%SvHYMznNݬu
    v:\mf?jmm÷_Zp8u<vtj$kh^]}/!9z�
    fB/moDzˋ/ﳄǸuBãrC=ׇFFHK$�yT-JӜ<<,O0@  : [QQH8ʙh'!I	N,pq@\ixMM^?T@U&sBg`@S,1^RIpyTz HtRΏ֮YE'riTJ	;mzv5wlYfiݜ%=￴x埬p۽=lxuu?^Q=Âtr4nowTw>+ԂuV6ϙSe0i4E 1
    2(`81XP,wZ-`pAv6 ^`;<#{pv{<LtBSE~<e+S\'|zՀ#$­,pI	D;NsQ-�.]^*Lhb#PbAĵZi>OWJn6)
    z_}u%GAϴr󆲒1M8szŒ#}|./ٶMxg_/6Y3kx<0cW/_iaIgϮ~kgOQ*}bt5q0~p$l#VNxp	)@^r6]Ǖ
    8ZC^N-l4
    2@KpXH<?$wc\1Z}絀L/D6+*>_JY�ƄA)8	ٳƋ:]`ʕ+Ϫ-4S8|MeHg2o.ΒŌeG샗j|=m6\&Q47,nӼy3sre#ddAQ|OR
    ۽=]1X,cDJD=B#4Ӊ�U 4�`XVh!.0X'ĄXqf%JdB#+" X�_ˆT*js!17F*eNWNRJ5:1^̙CqM%8ǤIxGg\طhY4K4TM+)+*L>4&QNdτ^H,L!rF"\yYVA!<rbN?X:`Rp	V+aXt:qӢ<̛SYT
    0>sL5~9
    ׼y(weXG;6/`"hr
    YbHPv׽�26N%㑓A{8-tB\xRɓ_S[E]Pto|zkx=v[^]`h("99$ِcGADY66hؐ(N$@[̎sE|O2,�xyuH"Wx�8y\ƙcC5U;J(QO[}s|~pn?khQ&Q/a&a=C&AYB:q.MߦlO=UXVVV!tpvd28q-J
    INJdqX#-Y@Pehu877z#h$"!=yRQHm'֣%80Iepl,BE( +/OѨsssA'B�x
    PF%/*1haRL
    i}\ϟh=c!?<۽fu8@` Gg��?.o2+-*pTD	c	$xEGʰ+%PiqLW"|L	cXjY>QZ	L&O~&dRַ2'2Ռ&ϰCm%$Iiۍ&e(RWϗf/p0T,VOOkpGFJJvTj|Oʰ d<?IPELS=8y)iz>;ʰ@fM& :@H}4_8s�9B;+Q"s2+ńcx̚?gUG<����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/bal-man-b.png�������������������������������������������������������0000664�0001751�0001751�00001164504�12663316405�020551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������sRGB����	pHYs��%��%IR$��iTXtXML:com.adobe.xmp�����<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.4.0">
       <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
          <rdf:Description rdf:about=""
                xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
             <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
             <tiff:Compression>5</tiff:Compression>
             <tiff:Orientation>1</tiff:Orientation>
             <tiff:PhotometricInterpretation>2</tiff:PhotometricInterpretation>
          </rdf:Description>
       </rdf:RDF>
    </x:xmpmeta>
    Ү$��@�IDATxx^y&WSEQ%r,x7ylln'mml+$.bQށ$Kyp03_9g9π222Ž}}}ٖ[֗A\H-{ds*mmmV4Kdj`n-Z*`4~}K%G.Ed-·HgxdzwRᥰ_;C?;vNdžk{!ϡS V}"M\cy	ϴ36x x x x x x x x x x x x x�W`gYLz?A]<ۖ_>.-
    x=؜	\a[HE	Y6<�=KrBs	D#`;4(	pEv3À<33vj7�>]thPhm	< +Okp*S#nVVICiU!H클t.+HP.yɣv
    צVMMMhiiAgg);jp<塰#GDqq1XWz'/y@@@@@@@@ڹ%AZ3T:Cʡ0ɊqNO+jpTUU9[vuAJq0qwz0/iQ:їɍહv{ttt~{vO�'O0cƌBzR@@@@@@@@@:3qXiLy06ؠrHCdS	'>F.ҕ#:-Qu={t6L43
    
    
    hC2}ESm|Q8Lq68 $OO';&d2|Oz*8q'C:ӗ|pQKJWWWɓ`>}[Qty*)t9amрC*`]s)999NN~~/YN=>:&-x29Áfʥ|0Gyy9*++݊#:(/!\).2h>!ܗ!ZLhM'C0߆8LR3\ZO&7i`Ϝ)2SN^o&^uuu3gܤG\s@sZF	cP]ZZ؀t744)G�eqUiԨQhO6qQlbNYs)tʧ<<}4ゖS:[h8x2Qem~9AWWY9iZN%7*ϧeY>]&F:&$	cl×+~鈓Mu9r,pVXIC<<<<<<<<<p<s�s<s%+kLeiws']]k4MެkR@r6qA:omؾ};f̘
    A;X?&\/.S.<5NHqbj….Ms_0V~�M9Jkm\"A5?:)%s:tEaCď]uEe[mOѣs8/t6>0OeQ/C4ʣ>Se!XV}>Uf$;'<~dzL>E>>Y٧Wy(Q2aʢUN:&ygΜ&>y9*_@@@@@@@@@Ey UFDh�ϕh
    5sd'm:tƗA^2U@@>aSeE>jJ{0٪6rST&I>GsGu˜ӑGeDQ8PQ/Cʐ^/xGuVpEiUW&i}h9J~Yt/^KXw]ϢJ&sHȟcI@~Л|>^~8Tz$CO3:	Mpرcz-Cݾ*ǧ;dY{z,P!\dp
    v@kGY$0[P0iPoo[*cyS88X*mPhS?^2'*#_!h}ĕ玻[h8�<4;nёuOqhY2'gPz�I<h"It>1ѲgR3|7P8ⳳ,{8piu0^`c6[p)0}k(_T7z.٩ܷK4KK=JCK_GT/8SoAhhrX55~xúOCT:ĉ[h.x x x x x x x x xr@
    :Hswa0Iz~`A9θ/	E^{ eH˜LQѦ}^7bĈ?/y`Wt
    |x~$?JK9L94ڈƟCqI)&Mv2ub-UٕSi̞s.hm	x"sy?g짍ugPԆq'"/˂sDC]5ZlĂL3N7e,k#;7>1e}jO]nuFO|BDž׊O'eI/7UxYEpkbII|%%*68Ocn	?Os!++=tinC倞r4уtP;JA?h?.8L/!/'
    sI2'O8`:iY&{UsъF	E]1@Aͱ7/מ_W7/\^_`V{;ǰeQd9\9b232V8s,tN&y~,p6 9ٜa;k?a߉Z̓klGȳvl䘍	mGv'p֩+7'$v:٘κMP`ߣSpt%LG2X9^[lo~1񣇿o/>ґ^IeÆFYqouq<<<<<<<<<px vnsO*q@͕l\y㠞<U9W)J)2PbٗC:?#UQ4g`E%䴅r;/WחG<d2g\$Л҈Is/}3&'q㕋P[
    6/^qZ@k{og;vlۈGOcX8o:pd
    :ۚQЎ9WǴbF:Q0Lgؾk?L²وۏl&LS&2^xuW0wg(~mV3P8֭߄,\Jph>[aoGݙj䏚aDa6Nދ]oAFAL++Akc
    lيL["L@KIlڼǒe1nd܊z\dgd=~kNtU=_2%}6xO<~Jw&SpvIUwأ~T?iǃ'6?^_Q9<<<<<<<<<~@֟׸j̠A9H'hd3hN6@')tyh;#LQd)(W(I~De[-ЀZ
    >MJ~%Qh>ާ'ܗϳǰ}Fg"ׯCKhX^wV㱗7OkUaNBӱx`B#,}Ũ;	OهaO[?yG)i9JO5/Ds&J;#l)aL[YOɽЂ\,\Kreko
    ï`΄x?f[m<g|fWGofN.o_>rZ>ǡfzwfLē~~Loh-w?Nv؎Cx~LZ~'60uMPϝSSuo(p⍓\6YcݕW^
    wT@h@t?r<~O:G:V~.ٽėG[O:
    IAVP+h`Ε7mwנr+� ]D:ғ$٩wi#'OԕJq~i|Kɋw>f;#|
    ~Ё٣6%cJvWc˞qt-2rlBe{Eexއ}Gc|/s_ǟmGVʏ״@{Y:j^y%y`Ms&VM_ggVij݇P^PoQ<¾(ޛb^?{j7_ݸע|D&^ٴ+nwet4z-ݾşɟbI(J~Gvnۂo\Ҍ<73]2gݽ5ω#s;>/7Rɕ ,3fnV|^ü)t$}۶mÚ5kDrw=3Ύ|u`v%G
    tܓ=%Q=<Lc`zI)K,+0a1/CU`QZ:euY06Gs_bBt4=Pنl{Fowau:ڶ7`fbƴY`*hqP{(zl}FT9V`jC5vMa7PӁ܄>Ǩ7xV.=W͝7-~]c,؟]{ͶП>q7mGqnrF
    _4ƍv.(1#2rgpnlu9]YZf{mcԸi2qul̘'D}yxkgt;ﶭhY1ܻf$_ D<T%N`wvOq
    W<31cT"u~1^.Dܧm^|9Ν8[oɮk٥pӵ6<x x x x x x x x x쁴t9@wPҢ�?Sepdp0p:Oٚ/_vQO.^'ׂ_~Ic+=ݝض%߾;JZb?a)
    UVc֭#7,įw{{hwv9ise:~3ƍXm^éF=1e=Xy*كc^Պ*wt-\ݶ]k"lywgV?	MX܄o{_/wݚ][m/<}593xx'޶MM;p2hsGo6]X&�F6j9?χ_`83'd230a\E'xPйa"G+2e91G=s[g͚v~hSH
    K9hT|9~RHN<y`"/0QpGL&uM;51Oo}Mw_~�&db
    ß+uxQyYX&ƕᵵo+&)_oFOYۍySv#c_pix~\`޵pJqn:۾َ2,^qVن93+Wh	ξWEpl|_b7gٲd\4~V>7l\_? ͫ}0m•hjc\a2D2\Iuϣ.qQZ#]~]0U\W\iӦC_P8} s+{%
    >^OL2r锭y@@@@@@@@ۢ]ڟ&x0ᗮ<n^2Tn89K!'Nw&'[PS[vT1ؽ\d?8^
    GOxayΎVdmGD=vt939ݶ۶tyţ0UǏY8ƏF}~).imoB}c+FG?ysC=Z:0ζww4et{]s;&l-33kyζdۇmջ]p֟9
    ;nkS}Q~k�ǖTV%yBGo*@q^NWנpd)D%;>̓ Lu\	߼y3,Xe'/%gxnetK_\z̀BǮ]*ߒ%Kjat~�5@CQ$yq>,Y	G,{+r[i뱠]ݽ&~ׂ^=nl/8jnwo&&0l}]ݶbr[5yr=6l:<䴷!#;ʙ#ro5xJle?tkbPuAd{s=^|Q8ބr~,#X8k+u]&?l%Iss$#^r.Z'<Égl'ذagΜ9ח@X<pg`y@@@@@@@@!@Orwl7n܈y湭ܒUB2ID
    NP	
    FzaZbrgD<agr0+KZ_|&efCl!tL볉({uv9<vB^ԜBCk'Fbt{=)pv%t_Y&‡Zg[U~y(:^&ϣ9rW]u6w8wYGh,x x x x x x x x xr@_NQ�iߣe"|QPE1$2TՉa,s1y|ZUvp/ӾVҞ)K5dn#AGzѰt
    ܒ}/EϜlm,x^<F	0UNM=S۩o5@>\GˬIIJcaY2>̗-LJz}+++ϛKCWiB9x x x x x x x x xr@ϼ^fҥK]ɟb!:
    H/O0&)%_.}#Gti)#ᗥ|J>/̈́p]h SӒV	ctқlE[y
    HJ_2m#LI2YrV4
    ~٧c
    >}tٳ}Ή,Mh:S~|dػ/2)&\__kׂ?5{lt(`Q!ć,\`1_:6$>E;%|h|ͧnRRlh}`,ě.QG|?\:Dܗ!|”W|L`{'׮jiH/>C
    @|e3
    [oQwƤI0w\j.2!x&bd1[Lo2x8Z˜mJJK&7}<qtRnɦ%(I.s\_g~Y3n}uBaJ<x x x x x x x x x x2l@}n~~Yts[EqUUU. 1cIrh(�!Np&|;|)sp^ҙѸC3H/))qe	[ۇ{_@@@@@@@_
    +y'ƌΟbN`OL+.>x2|} z˺_,L|E+~X}~ՅO&Cx3Ee$(t(8xTFy*~ڗ,*[zg(\83O>}uhokw+t
    /x x x x x x x x x x<d؊e
    ~+|y0N:,~̓ӲCvG+\yOWdDn>e}#P2t126~8㴐O;Mgfud28=Á:cg	=cyeF]]eG/�<9B
    =0�?r^&?x x x x x x x`(`_L\99ulnNhã,Gq<I6Ud.L4qr%rTҥEidmM7j[/d?GE'|)&rJN*Z>G:__AHO29qxɑ\0|-K>Ȧ8':|0h×%i|xR^ɉܗKG8EuQZEA|&Z&GXx}SⓜҊzz('Ά8q0K&'>G:|N[t&q`g\>,qmaqqtlNKG,N~:d6鈃4q`>`e__t&,܇|H7NҤ7N~יJn*\T`zIL~2t91@'U9]>I78X*]>'?
    ˨`=JIA8"0q<\PZNfT(oLCɓɑM%݂>=>m2ӑ^rSH&ilG/ɈOXS%78=$O2z{;dEW*q8XTi3&#dvɏEu^l=NGl8z(''OWw2D|0tttR9]lXʞ8|LE
    FC<$#Iqq0v.q8d&#OXvP`4tRn*dʦT2MKqr^9iR58|LS'?ՕJ&iL&d.F8˜!^J%W}CtG#Ics @	T@re42iu8wS}oeC*ᢴ3
    U
    7ڑQŴ{9ַ[gԾ}44\壝;s#4{k/<\rHp}4\w^y9\[_@@{|c\u}bN,p+uA8a<(y򴶶8ꖎdl⣴%rO&#_2xTpՅOW~2zKIq#>p%0^8E%4,T'>*882$KO'XF:eW3e	KFM+`򉗽>-%KpU&eO>]TƗ!>`>·$9iI#(Nu}#>JO&jN0եCpJ/Q^CdGi8ߋo?W{}`˗>އMQZHtQ|`>tt0
    &gÇ<,_jWW^Ն1TwC'm|7^sߍcAnn|;Y:2V}<uFmM&+ԩSIQNqFKAԁa@]A:WݹeA/NB<<<<<09,q'֩<&4'ҤCI8+Qz`,SU(NHEu&	<OCKFBb>.
    Sc9i|d
    :i`+	zTDi<'}(Ozt\x:$;&SݗW's44KqDaQYIOW,Z
    <\YTTbT2S.\dzū|k$hd18#FUs	WcEO8\I:6>R'!HMG?x-܉gaHxԿiϥkrHS[/nF*6=~ݺٳn!o}es2&gZMkmť0_ &t6+w+cǎu։PGth߾[otl*ߎtu<CGRNu^n?OƧLyLOJW*/C(}.C5CJCo(He~f܇$[/IHjbpһ(;\MǾ.0|t_l;bߥ9VC%ZB7^gJ>vNl(Bnb(]J˥jw`m2-R9T9o2娮MtRH\~lCGi/ò7j(7> D#},4*Y�R@@@@p=oGO/NY/=t.2La ގmŔEQgᳯƍz@اO<L~KILדpKQ9Gact�_Vq8zbGm:٠T ~(OE}Schdpuއx#?]5MRRBdF/s)GZ^Lu'W<e]4qOF#*+S#置sgt��ܝs:v$\7@ts*!sb`;g)I&U؆<R~PIr(icDق%Ε6`kd~#N?M*\Ɉ,F?^|de*Ecw&Z6T6PqC&+'|^K8>o2~]eG]e3ҥ8%92g[ύ3l8>jBgK)"ʣ:e/|1%{V:O2=yEʎp>
    t�aa0`nLf2x2=q􄩿q<)O}.//c5ȃ6$ ɏS84PJz+xjtVu_NօT&NWD8_yl \6'Z)uN8ٷx0E ^0"z.D\NuW;(Ku^!0>W}<NV?'}ZnS׷UUU5+Kcs_\.{M#G/rD/X*tHfYIW\^0)7oQS[v/DgdZOZ}(33nԸqcPbVktah,
    rK:?(rLcq7݋SNu4 Cyաѭ&DBxN&xMM
    &N:a:a~8Sٚk//=?g튳;zNQK?M*q2`>-[_wDgr^=JrtEtM>s)&ٔr4uRҟ,6YYr|==Ys'K0ҋ'K.0�wBϱc�]C~L˰
    *
    <ODldg*۠2'98/yN>%ϓ'r޷+#_̗r.Z啌td2[&SNR89fbڽ{M6SH.w}h@#?mVN=ǏwΜ9TMqy2H˝?0^C+\	31$W DLSeͣz89?'ck9'f;:'^WR_Q._}Ww830.>&X@t̘1-Z:e_~f79p.VOWmdŶ1kjjrmeF^#|ȼ~_}Z䂫|:>2eDD
    vGe%7&8t-͘2eژ9rcǎ~ĉφ̛;sfͰ{e:
    升'Od$oHYv;<|:>Y勗̑#G|vh|^\ئ8Ӿ7y{l_4l6wǑhl'(D=R6x~);btRۖPSruݩ+&
    ~Hסw_Ե%@1*-́x]KtvJQLs[<~.?IO23gб~g@.ﳁG_m
    7oB϶m(Z9*;ahՙ
    N~>vڅ@ٳgc޼yzU_yPs׷�ϝΩr1pEO3@\ye],p&̹ͮ~le$~cOÅ;w�6IO-r\W*H:ɓL瘗k]\8%Kܸhe]zYc;vp_V2:}y,I:%CuH #z'>e2KЗ~S!e'đ~Im2ɾgF!85Þ74G;KJ8mF{tv5!?yl`J[)?8Q;?NȗKq"A-A?F^E\EqD)JOx$OKp_INsz|*'	=ז
    GI<QSN6ufG7Ԉlם6m	i.EML?8w.x]NR2
    2޸H֓C[<l%׿a~N2({XI`G7mpW]u&O<Ёc~NTIO$OD'Kb�́ltP0HdEܒh>,AkdW`|Ioqz([t2P0@"�RxGL%
    ㅈ QMKעN>D"T
    |p0aNg'sPL:
    dא*+?i[_eϫ»B{87q
    F/+oA&ƽ|R.aʣx8 z\
    _v[Ĵ%?=G_O\1Q=×8Sy?H>%>D'<r'OM>൥)Y<i9~8(42WHPRvIt)'<}!{|yY昑UVVwr6`iM?8%=u(+j/9ʉ㸗ݲe˵M
    '*'/qe2罗rl~<8ݾ.!,J:?bY}Oe.8s&Gs~vPm޼)CxŶsbbѢE\jKo~~k;.2lRylCf=+zgXj8AZ[+<㥛9Nvq%MqŜ_ߺx=~_[N:Uf4Q~β//K<\Lq9i8)1+/EzPâ{xop2ՙOw;k-Gk?;nw%8R./&fE#@ 2ئ&Ljr<�z}^8[oNp6rH3h^k3GF2Oxa4�:aنlDt5ף'&%]^q5x:*&A=uu;UFv	J:54cJ݄tuJw_ƌg3uk]-8]]܂7V[Z>8hpcc+FLta~4om?:ZM^=̔F~uv]2<QY&%ꌓMb9{'aRa.lq>#ͤu)+
    Ӻ*wgb^'f%?Y>.T[SlL0&s/m6[)
    y-=2m_ˉrX{<"O5sٚ/ZZ-F&MF9K~#dEO6p.wpYAn-mhmNv!WhFͷP`/hC=+bjnB#JJ1zT"bÕY98%#;hW~i<#n?y~ح|]wu"49uD-g6}vhTTi={:P}ŶK̓O}͛Ⱥ[y>~J&6϶è-AO<W^y|/ԟm{z1ƌ5kn`KyM9Eh##nLU5
    Fb_>ٞ8Ԟw\JϔG(0J׸\P>n۷ow+q‘Fq76
    4F_4d⸏Ss'ޗ/ZrY!;WXf!)99qF,_aŋ`fM2~PiM6J'~ҳL=<tn=&(Hˀ,*%00ۺu7t!η=m$…8Klލ<s7}uj@GmptM"Υ[s>30g\Ή	%R9a>\eRu__D\4\eh?ieĝD<K&fgNNS#}QŅeyO}35LIʼ`@I<x�?82tR값ˢDaAz֕W
    5reC�`yN_oLSޛn0&}O$řMٿ|oԟg?O8]<dx?z GOBYqY,c?{{Y:k0Oo%98c^xMtk*\s3nX1f<U֞>L݊Eh9g~'ZCƳ;>Ԍkף=|g#ᕄj[ݯ^Ǿx&-Zܝw3DZ-6d(Տpr٦4>YM$C7ӎկ;i"u
    8}#ު1p牲%&ު)?qدGh3X{/><NZ)@ƕ`52 
    t/93��@�IDAT='!.vDO^DK|W_21^F?ڛڋ/`j6{P<s2O'_D_Vj䎟\�&/]Q4p
    yM>ܵ	Ͻ=vĊoK{ױ/ݘ;wϓ�?/-p}?8|Alذ?OҲ~(iDe[Y_
    ]6�|6Nj5DRg[#C
    r<ޯmX“9'+**=g͚IASϞ+o1m6oV^
    D\xmS}-iks=ދkv&l.WdAo9fp+vb{\f??ҫ8[s,U89&cU"-p+hO:dH/sSyN	VCM>d* x4eL鈃h7cNp>
    d/e˖	'0&ѸJH1:O/&.qD:_^Ɍ}&1NLR߁f/8gHV@za^8k9s清B\OrO?*Eu
    <}d+-ˇM5 l6˂jT׍GMS-bBYwjpA)Zh{m?y-HYJLMx˜k[EQOt6+d9mrq/HG%'އwٿ؏yWm6ECv^y
    %|E8:X2/nqvpS8O"g
    HN6sd]jxa:G
    \F";.a] ZF_wNBo]6)>[i?u$3Pn6vZHFaR{):zԀ&?
    xQvw
    4lUcs6w4᤭Dv8g\qw`Amqһ/t\_<ziq<㨸ط
    0b2öm翂f?›&#-=eܗ>CGQeX6{鳘\>E
    ތvdtibfuYjL`gL[/9
    #l]>wNWڿJy͍gҎ2qB=SzQoݶƒk3]:t֛m2FutvN_^Vjl*3�ҘXLjewBLF hiwoL}JzLǚe3<:ZPg(Q]Xo9|Շ2VnJk6p|cӟۧ�VYs;/5.|Q\hꜶvv¬d}k~id־{vXY}}vm!n#MgiC3`
    8ܘ~X͘1N>юL?wܢkjr|!llVC[<9<ߔ-k7#Q:2zֶ,[1$@GhͶ
    =
    %~[:1mahMmCħ?q޺H~n@m&n/ym/ˠx捜un9{Ӗ߁ۮYC;'IR܉Gfp>|ĠYuEHQ6sCgM74pWVV&$L~`&, ɱ�վʫV.Bfduٽ*؋
    '9V`03"{=cl7TlRXÜLɜpIgn\b؍[jOs9̼nl	
    Eug}/#m⺣<ںzw͏udpZ;;f}o>eޞN475P`C@\Q?aQ7.-H\u`
    Ƞ.}5nfM^O$2Ts\=kXl%d9{LGFeWSLqcC2qNr2۩K:R!hUx+\!5+wCWA:FO>'G'v1糉Ssg8'HC*:?nFԷyY%`>-k+9llS4$LyHK^O~N¤Wxg;�x+k-@=Aw{7j+{Qf]65ͲwX-qH+_/muv>I9Nz0GZ/>g\K2}8e\q2;7I\4/ۇO4<7,d\ɗ!ټC2Ge'Nm]]yfθ(w/1V6vTˆ5I9<<t:;8O7k9=N6e΃I
    C7Wl֍zI˜7$ޔ9K!x?n{A_O+oPٍ3ƿшXy2Ĺk_$n÷d|%x<=||ނc8v{3}U|fcAł?/wNƒ?mT516;_
    6וʹP1�5
    6&,,2G.x@`DM0:cǍRtm&'Ɣm&jNfEW={g~ןRL*C۷JYk]Cx,ɷ�Wߺ
    2CUHx'lS/F^A};1x'Qߙn)lͫ>E`uxyYLޜeX~$P4fmh:j3h+oM6 ^4pϞ>l+'۶w؎()Ukl�/<='\^0z
    ZuڎWos
    -:mO=}
    L'Zn\3Gl+3hE>FZj:\t:66>fAhʦU7v<:`sp!v[	lC$߈'cBŸUPfv-u+Zl9{vK<SZ:;]vZЛ_j>\x7]0&Z1j$Sh6|0z9vm|7v+0;0s}bT=s؂mnDv`ӛ\MH[5էQ1*ܱ*۪ڨoCem5pd6n;JlɡV[׶Z`ދYQw<>q#V̟a]vp$mg;g޴~uqpji5[?~M$tngNޭkmht*̚T5>{ODLrF)+mb?s&+3}vّ͕k۟&.uEC[/agA7^‰QŨ;n*<kS,.&[(Gʳ[g4z5aEf
    EZl~fOӶe{16G2a_eX?=~-|prJǕte`R.^W}@='lnLM,
    
    PTafo$d.tԾ`}EWвsao|$IKܷ-->șxnLE�)qRk(Mѕm/=ǭ&|||tj?x%tdY
    ߸
    Kfë?NaEXh}
    8AՉZc[sH7͸%)L!x /`"Q)[n+xr&#'8
    F9,_r$(LP`qD<G<³mM1~mpBcP?r%Ky*6&2%0�OZҤJQS1}Hٜpጫ\e");.'N0
    asLߓVm'2F2P>HL'|H }uL|4	F`"mdOK؇f_
    ?@0?זk-vm<Y?O.{u(|]<N>mO5/Hull&=(H}& ~NyQ}:'1(K|R>6qLS6R$~Չci5\&#t.K$9`sض\2lgD]7œuN-#+lqA~ci<L&
    O4ixPsx3!<Xf^Llfu	x3o ԗv٫,ۊى7_xO~<^92O/(>̾n|۰?}( @x|cEIq/|
    ͻ-9o7q|;o`=*Sp7?DX{W.ŝʖ}Ğ/Q,[O#6<ƌmZҹ?g:[fY`S݆I"Ϝ_y�*[Aon|ힹӶ䏰S	`3qMdQ}#߂Uw\Ŵ؄Rn�agfܰhG
    jNbp͒YX#Xan>1=7.g5wbt~bϣ
    yilog]	m=8&'XW>	Ӌp>,U̼yqrݝxQ[fĿQ<|CbOa&66Jttgawc|^+&K1[G_cr[_;RoF]x;}S[GwoYgPY~XΪE-}lJ̞>قL4c峱pL*ླྀf5ݯkqlt\(
    -o`wU7>�M6!{M<gW,^z̶gѪwaLN~cέǽ(^{^d_&㵧GzOaM*T|�OK5\tvY8ft)PV}N6<j,?{`z|Bn[5~bg{mgwߋz0͝aO>O#$fW}[3b>~Ǎ'Qkij*\_z
    ȶ
    2C?Eg7A^bܳr4^c5r+/E^}Hf+jGE<#X}>݂_;qvnK6mx/w$>2nhgڻ
    q-w1᧰q}z/N3v^n~{̙b۸gTkv/صYPSa*̝܆nI~p
    7ؽ;MӾw^B|7i3Òk֬q>zU=8= 3'Ӟ%p6Vv,Ѳ]mCAVͰڪmEnu,8�a>WjND30Sk^GclhS+aᢥ7;|3:j06�e\N3J'-7=|sXfM&䏠b<06sKb({	Xiy6!۵5sLXHX_\4\oP%^Sq5sy9c/}9{2h%ODZVqϝY-CҮheEq:q,G=0c@4@3
    E)ds)_A�'E8F$Wy/Ac:lA)}{5'<8±?G헝!/sd{UTT8ix.Z<.',uh//q9'WZy0|β1*dx}*ӞsYhc{or@4Go?΃9W]>!86D~1WOy}%m-FZa#\ri!zLGa:Q`ɷ#1Mt[,5-Y6e?h#֗yqN6h7Fe徑t<TVV:μpgM00u}y,̣I`oJxPOm+*Fk]Ɵ?߰TpM_&oϰVr|}v6.muݓ`m-63^|cvlZ#'VGW%}صIO_gUbխ`\
    ~ۚ\1g)ϰɶ':x#օ硯e4mه`
    $O:ʹpk3q5vC5*j.	64و#N6?뒶:V;l%LM&,k'6Xzna>>
    -wjrGآZ@
    ~{@ms'rGf:1rX"J<>rrbQ߳kCB{s0VSDS6>4ڪvc9sUj͢?
    a#lE
    .X0=Wعl~)/YܢQk%A]]Pج_y>vŜ
    ԞiUsʱj:c7l۽q$4wU`m;j9>cjoFcy;P}<c=fh{aqV݂YS
    kɶ^}k-yX^i]+o]_?&`hwvٍ!38vF�U\;nT�icGuOJ0�W\X_]/g
    {ػ4#=m[>&o'/N܋6b9]MU/Yq
    Gƍsc1
    L|52_msxbG#e8|FXmb2aEfS#6AS?
    SIoW:gla(4w@mk	MǦNi,Ze+v۹[ۏb޲tN~ƛꎣ6ܵv۹b
    ]mغn=Jl{?i
    5-Yr2N1;Oe;U#cygF.n!=laXؼþL~˽vZ_]}ndq5U:{îkmkmRБ*w͎8_Z<Cؽy*rzЖo7k#:p7cr6so?{5L1@,
    f3eO/8;Z;b?yVj܂^b~+ͰN6}wbG3;s)mC2<y{x,s1\ d>_G2s
    pCŬ8bb}{mvu`mڅ*g{M5n9,h*8c{Tyhl[|(߰MT6h塜xyH bI/)dil1Wg9)]k
    |]*3WvLz[2o0p<1#SHVkG23@S=$f+lt>AIǔ^HܡRaJצ~a}Б:(k0%mdyjMj/p
    'hS]lUsN63)_d&'䗌a2pZ.`;KKG:HQA$7QcLbro?͔{cb-1wRD@&.,,vJsf2̜9N;Ym=LJKz2Ni,βpCgt/h|s
    [K7cc3ec$/{<A_:_KLv5K4NB?}S14v:40M4vپ3BL9kb2{[f36h++}3PT:4ūrL)
    ٴ?Xgtp2'NqOllcM@ԧ
    ݃NZUprDK@8ƁlIK:u2v*_,Τ0sl88GK(sN3hnâ,`.*M
    W{J4'a0_^}1يgS2E#FVM!Rd6K!׻Vu٫^CɏpZYe[g|z2,DO{3˗a_QKIJX~fˎc	eFr{ĐOȢw^2xTt Ӷ'/-]!'FyU/G$fq�PA'CsOKacJq`vٰPƏ.5EX\L:iQ)m*9V&#by)`$Yc\Wa)cZ\?‡qUts%fK;N0;}qҥGÖrJ
    N@]ss-SR:6l0fPMSqh]dӚu�"3[I
    e3LB2Ng
    [yXQFY-+l,&/"Sx?/idzW#'_YlٻyX`<cvE+Q
    Ok59O*
    A:qْ"{�cd~0:#S:`[K0}[߃OA0lW!%ڨ\u2زQ~*I䍗_|W
    #]eȑm,"KWn3gτ{c/0>W&z3MpX6-fCS|0,o-wl<y918|NP	�Y�j;`[%Hi=\.&S*o*0i\b*X1>UB@
    aJI&C1Cg{Y>AvHO[ymdVhԱ�x|V/Qk3Kk$о`E2wʕ!s&*Yf'O	GÜ6oHz5$^uGwl$P*$)Y8"ߢͭܧY.
    LJUغ#6W|x8|7N:47nӀg58h߄K.~Hc4:asI}
    MXʯcGO'~F9؊3+Ʈ(Wy?AY}jz?a\,Yb>w,78:E)H]lZ4
    `QA%@cILW4JkZF99ifFEbN1u�ө0FbF#ye*Ø]\OW.J=s0p\{PO^u>OygYrЃF+%,sW^&CSv0[KZbd3`-ן/C?bŲeYq0	fLLhpf8֩fT4€á-7б
    L3&UW6\o7w`qbߐWmxNy۔SHkyp)kazqzߒrQyA4}#OK $:M=@:1Iھ',>g(
    ݂K;EKN0mp
    Mˌvha'2:bӑ<YXaƇ4f.77tT9u|xxp}änl9Jw/n0a{\˔/~2䉻%G0k6R,X(co>XYl܋?sfqN	2#d>>(=T\'qXƽBnA<.55aAmeRO
    SV2ٶu#mza^R[rX>ܾS2.%v~(b̴YXYm[?avXحtȼ+^+K7/ZJžT0ďxrtfh|l%{RxR.+^(=/_}9e~2ƛkԔOIX?_JRxUattE,)ƞݾiKhy/0r&]w.uH"^f}{BJì8sjaH&c6}0v{WzfTaFN%F;o,8!9h@y4Zxo]k.eC2u{{_(mgM{7ﮑY_�laXp>2yPCCR u·2G,zm,.C0Z,JoS^eʢy{0i ^qRwqw(/2R(4ßJLa2
    ?m=-e٭E}~n2/,9Ux"?[RR,	m2O<}ѻdԫ%>,%*C93zdJJ;\K.cFKYRPR!c{6Ɋ1c%8|@kUO^=sߑ>’ )i}`3g8޲kJ<WǤwW=e</[ɐ!˪Wɺ~WvaЅX_6-kZڵq;pn4^Q.}=2||wSgH/+/vedV.('ʎO?%}/R&/q}X1tJg|[V˘!qB2\x-ȍ7h1Ξ=ۼئ{}9s8;(K.u1+ztXGa;2{.9O<rYX񃞚x|'MiAg@T~u{iw+;ݻ` 9ߛL.?~H/˔Odb:Njq؎"cdmx/Ym9)e<3>%Gk#>Op(o-ߊAafޠ@E@
    }nJib')
    ;]W W.i?-l;zOŁ$S&oWuO=)k
    IGy;rgz3C_s
    ,MSz5-Ćq9=gUeWꢑ@}a8T'y([y3}S4o_ÛsAh!0GÔmg%gߜ|tɯ>
    4c[
    XYT
    kx4i8𸕀/WsѨppF<)}L"šZTtsɠ8,uU!7^b&ΐJ<J̣(z80_>1tZv|:dKT~^iqJoF||X'YoiccsM+i88
    <;N LhY&YƳTr_J,+yS�y043T2, iBhTF:+3sj2>AHOc\i4>�6QaFKIre=gau+|[s;jpmrIz]|oN#)8z%pH,ܹ#{x
    d
    S-v"`ijV'6q{oJ~!.&y[^qV"~NhH/d<th?.Sϐ)s@GnrIʦhġ\GA=_#IK9>0}8IM.^yUY}ɕȀn9ztm;B->$?\,.~..'p}?s@\
    ff2:˱ůˁ-mavũqLKϬiI%?֡Go)2eW(MAsK|	(tarbi
    y~ga|G:fRS
    Xs]VdwnNoR4R$]0ûy%ᠷ1O18\&=zv2<iŧ^zRcv^0:ŽRP+$
    Kߕv7cvenq&eU jlgk92<3}�aoߵ7O\,(k#I2c
    pN6b,|f钒g,ҫ;e*	rŕw|f{�qѾ_SW2$-r{HOçZKQdcKJϡlSذ 8
    ^I8#a0,i
    Q79HPq0#a%VF[~2	KR2Qyeg	YL
    69p|KعoS^*}CV^,o.^(;cJeԃb,x9K2pu29\ie52slp۲Y{!{֧J[p�W^;b;rs_GzoQi
    a[&ƍg^-#U*ahH&3gL-?X&ckGv>!gnis=/}IyR_>OC%buUc[H\IصGn}-6Jg2%Tf>Ğ^V|jչ$ӫm:<gGAg)S8|?s	-;V*xC+->6k,7Wm+w^ģJ"[[hJfbXU'=Mۜ`KΔW@}|Ь2~gvlhSߦ]Ɨ7
    N?ZzCMvYc).1C`_'_e25~:K?b:K2Lʡ0iGy+xfF"uiD
    i:g_&dGaz5^W.H\7bKR)jթLޫ\ P3ΦWtnY?]Ϭ]m:AHuҧ|EzmU:WGtg8v8`Wۄt)9¯A&r0p;-
    *ꥭ&Nc+:Nt*7=J|`;+m,m:),<<_|ooΛR*3ĒeKig8똾_ȧ?iv`<eA䳯U"7l吏yڳ4^E4,??_Vm֕]( 3Ē9}HFu(ȁ+$>Sj#7cbS`'Pi4tV^&
    &g�V>ِ!/~jeTpď2T6è>uA\W,/T5@.˭~P
    3ڵǨ%
    A硪,|`}0hx*s
    fH8ExNFOM%>P0Bڷ1Lwey>rLc9OQaVb",ϊb9哜-؛Kqj:M,%U]�ݵ0
    ЉAʇV0h;vyO|g˰	2~(bF,\2L,PNm<#AeX1J|Py><g@>g9[ew^`U�?z
    K|[5abCr!uUյxt489A9Q'\UQ&ajU<M̘+E23C\%$FLF{8<_^M0_aҞ1f|RtyұN(L6DN1xYT\|ҰܝXXQ6\_T`)W*-.§P.�O>-QR+1˴0�Dg,H(,$B0Ϛ=uoܔ
    ㅦγ3zBWABMg֢9mXEx21Hg]2#SCփd<
    sJQPSQ|Lj=g%|VSTvfVؠ-�Fk)
    1yQxWeC9?.g|7(ׂ
    ˠ];^=tB(g^ԧq|qELm:WgM86=(*g7~	||7mR<ޫ'%a2OTI8�z[$m
    P_Xv-qL^zߖŰ0}O|`d˰K¦1z|�5۞,~hnBSML�hGWID;Tg0ϰ~Ҳms`OybC@˓	g؉T)	aˠaBC&˕;Dld:77\S>;)\HOtϴxb.܊[(zvt|ie'AWK*=ek.Vyć<U]nyH,.`pB4\ʲ=ZnWbMC s`A϶m*8F#Pf gG~eIYcZiЎ~2Qr C]nu_yYyݍPsvI2Kj0Łl$!'3źGGHHL;#`v9˂ii1L`Y7ܽ_sXmHTӖywRr!3'䜉c%Ɋό%ZA#l9FG
    q zOYXQY`!/+Y4,nǖ0`a|!{hUSoXeDGd6Cubz
     IVlc;Ne7]tH-e1_4-
    KӉrl]WIN:|OYOxN�,@5'0Y%LV5ahqQ0"mS.7K˼CzOog,˲x"a	#	EH:OH#N9G0v<9XŪ#a<0A3Zj뻇ќP
    J^xyaeT)KrnIpf10t6%;L|B߯0z;Lu8H4CT^6*7yPLi.Nh_)nƾ,N^gxiq0
    0zAY`Fvks{vGdØ~vm9M#,ayc<qiQ:qK{+,Leipy:Kȫɉ%teg4Zfm:9.-q?ip)0/M5#6'(uxNQL.7W:ŧ.x|p{9D<Y	M0pRyT/A I91q,Z>l_:m+:a@gٳ^}uttjlY(S=VY7H+K`L`i'yT
    ,&ۢDLNecBgr/a0A`~TQ$Egj4CEP2?HO>HƳ9ȇA<C}XICg**One=s��@�IDAT-`iU~Ag`ᤞ!Sz^/o};V;Naz=(+4Rn6US׍M^p0xh}a|vX׎QhT
    p	zOdOaҨaאS^:4*+<[Oi8֠KNUӔY&_Gs~BA9hi`\cv*OU&g/l;<h4f/5YecC|9cT^|-K"Mz<|Z&IyΠhrL:+^_F'ı$M84A*E
    PՄ
    �ˊ8NϗݙS\yk7zр5f|>KAKdʦvW㳥rI2m^OOOOu{kKOCϔs"V%}{|?pךw
    'zM_
    4v1ΫMøh.lz|Gi_Ǿ-?;rY	e\RqNڲmya|zC/Guhۼp֖Cr|V,^
    Q
    銯`Oͦ-[G%pͅMDp~}){Oy\̲W:ձLǴ]`x0-{O_O<x?UzGK?V ;wXW&ruvtnpgýs{Eʃ>͊Fއ%\͇,h@.y5GtTNT3vavg~sa+N?֔|s'`z<uSSGL*N?~[GoGi_ͥn+0k@'qiUOÂ>&Fm9ѮX}14$𐰹LˆFшNe4au3=+Z%jNW,M>W4EoNg_/x&K]?=4[kA9'ܳr?.6`ӀPpv"Y0|?rߕv>fD|I0hL0e5M|?(۾2y\Q?H-ܦikaPΖ
    '}蠡roc=/-uFGG=R(ه5~(e[)zOIP4%'8K_H>kXi4Ę}?Zx.ڽh4aIX\aCƧiRᨯ_m2[,9)!L8J\miY8Nel6kow[n0}v\Sך瓭–G0JnM#&ֱc{Q7'a6FR
    [|85BdZ
    +	svs8"ez\1Y�ޢ
    :H|Hn$s49å9bA9[AGF:aaar)0'&M|6Zv5D9:Loꗱ[38Lk\4O7&:
    jNc8FcxRpW/^m|Ϭ{:r.Yh+S:rZK&k9~Xzτ'!p8|ő|&ȗ{D)㨵鍮ދzlgg'tif,r=X8/۝:D˾W>,aZ_x
    	1NÔW}֜SySc"ޫO:_mTrM]uזmVz;LyxF_d7G0<u?TMa|W'}0LmYټ6Mڦ۲5LU;HUC,Nuq&"ʿ4-ͫ$fZe+nj\0L5ͯv|صMGq
    .Y%HҦp
    qhƙnA`'<`Fp(9
    N.חpzkυN#1FgKt\մl~_qUW-#WEv}jI]bJbKmk>[WSy4M "|YAA-Wdn_CT^cQ+OXZbUs%?0q닺UyN?d|S^ϧ:W]Q9}׊/%a릴 =y8e5%7Ly[]uRVz'V<Dpcٱ؜8۔�RGփ@]Cb[1_(4v:4>W>}-KӑdNO^Iy<#oK
    ꤜh[W'LoPV0XUoΠhcG:0BkøU'bA㛒X
    6=6MK儥Ŗu4|X+:ӡ LXޠΰ6kJ^5S1wC Vޅ+
    1/g&5L3q49[Yu.{=Hq3c|Pp8NĄ!@3uxE?:φ0tzyO\kzA^u(M7EcR*|v.L5G{nyͥ%;mȋcqMե0Za^77L2Tf^i4\UF4_2h4arlY'fP6qJMA::gq kS:ټG?{WvhR96Qv^e*Ml({r5mKkL+}Ô%6ʢl;<Loq*/fܵrF]O?^k&ќ&ަ	}46UM0x[fڎS:[Oyq5>]Sq>_Tԡ4CZ
    5S0[ypqʯyM-;(8O?N2,
    |6voʧa`ЏW吞v18U|}`ԑΎ{WZؼE(އgXS^rGZ;,tt8?!mJʰZrM9i	TG4:G|ztzo4viޓa5^}PW0U~ixP-_#)_hڃ6oSq6]sה)a?LGXeFo>QȫijIzZ_aSi5~PSaS^ٴR?LGXFoNL<.|mzt[װܦ&?LN0Fo_۠pC!p8C!�?+U͝+󯌐9ŝmPkX4lZaOeh3Ny>MFk˳lv:ڎW>hd5LC4yvxSv~c\X) mPÜMkiKi'OS4̖zciQg>ZXXхz["AL
    Lc0.Lo&(CcSzt2dEl?L~0)^7Ӗ֦QͅE9殃%f_a-k["'mXaaLKf3^&ڵ%rTgXױ5H--*74Fa*[ަ
    ih|6MK蔯|4ok;aaa8u
    y4*_}kx4_1>LgP۴A(_WZztuhh}oN'h:txWZZ]lVh򣅫q{~ܺuꗸ3qdPհ҅h5<\fhќ1>Hqv-7?:)3NS4a|6mPkޛexU>}9ռFK;Tj^Ng^5M^W;|(o,q	ƪ3iCTY0>זۜ*MSTh7GM҅dGeibIA^-X6%9AསO}t(OmGeqh}UM60h:x8My*'̏F-\e3LӤta~ei򨬠?(3 Ǣ7TݟreuFOi4̖gUvi|pF^;Odj*}פ|6]smG2.Z4S㛒4A=aoȯfSdB:M*'=Ѕ9C!p8Cl!gKGIG)E.-f?xgt_)/QJCPO9FHS"Q-׏jN4Ks<2bHGO
    /}.tv6ti
    k?*8WKsx|zo:&#,l8|T)\|,:OX4Gs6#,SCa~jKg%C!p8C!pp9ީu8C!p83m4ܵC!p8C!p8@?G;C!p8C!pv8C!p89Bx!p8C!p86@pC!p8C!8G8:C!p8CF6!p8C!p8g#ZC!p8C!p8F];C!p8C!sSp8C!p8ghkC!p8C!p#~wjC!p8C!`#t
    wp8C!p8s3NC!p8C!p8l<ϳݵC!p8C!p8�s֩t8C!p8CF ѣv8C!p8C s:pE\\\N/юB -2|Bs&22;y\t
    34ʊMStbϷnTOUnΔX"	Lp8C!p8p#s8C!p8D~&uC!p8C!#	'7Fَ!p8C!p8pKcʑ9C!p8CL"3p8C!p8pz@92C!p8C!pI~&uC!p8C!#@(Gp8C!p833$NC!/yytt8C!8;$Ī&	W<[0oĤmKh*,,gZgSW;O_-i)yr8Bڹ
    kc8oa4rjȁr8C&q0sbunW`4,Ē@r|D/`+/vJdF+S|ϷS۩$Jt7m{*!p8U5/6rtpo𔕖HYy%P$&Hzzb15Pbwm,J(ʓb)2r#19E2ө70mZw}n˨XU툏$IKKGۑO61&~"*$$,Krb1No;tv3\UYF^T<O@KbB+S!!D$55]Z$E\hrC!H wӵCߥ09o:>ՊP=%3y۹khW˒#ɲc2{s_^љqs)Vc-o?!!Aa,I춒�::aqAF{aN^8B,7|_ApcuyڽWʪ<?S['ҵ{OiN,+>FIވR.?hT=/6ZlVv|⧿o~Ҷua/~(H]凷}MvԦJk\}wTz379e$xJG&/l:&˲mF^<<dCb}ܰ¹|nC!p9p},ވT~MȨ=NsN]4D
    Cy٧3+NyhR�TYtH~lVRW[$عġ^SS*5U0γerr2(oR$@Klܻ惇WgE`9{
    QS} tɪV(*.ҳs}m)Pbl
    zu%c~*%&w>+'
    >yzyr:}1U881h]_cfhfomfjC#䌄T˪zRۚR[S?HjaPd"k"?q4֩iAFp[D,O>&K\UHF'=j>:
    u"C!nbzhxa4?i6tv1+t&^@yI)!
    8ѠtquN6CFޓt!_{q7yU%yw/Cۯ(?}}w24s�9+q2'Sl@� ]2X ߜ|5&
    eR&,~Zu
    ӗtGM#uV[^=O$5C1'߼!s~OWL3M,1oJ[s2a;fˑcd0vC}eм28҄S	gh9Q(4,OtPSg_XΗgq'N>|xsh:-o:e86Y~HJw3eai+FK{nP
    l#K"keJ*n*J{iflܐWv2Wa3(U||+\6Hatdv2`N:]2o+Y!w,Йw1m8L6)kFk}JGͯ
    -+y۷u1kkjM4eQKC!p8/c.K/<mZ`&ZGrc5t41 7ќ2>ȯ<'C=ŧe鼮2A<aߺoG'=] =vD'ؓʪ;!2Nr	GfOo^cYӑ>39gǘv^X?A}T´õ\h,3LO}e2D	|a1yW:MӠ|Rz htȕJI/݋"}?vd }]Od&JBRWGzf:h46Q-XP\.i1L4HfklZ?'&QhW6H#	)bB+l/h4iq;[#cn_cߓуzHO~$U54yK1Cyk>xr@UnDOj3㜁~cqƴ
    SeZ3\#1–A\֢z5YRqʀ
    RHy?^[5~jBgp7m?^]\zO!
    o$nY&	3HZjKH>,uUvC!p8QNDsh#
    mk@jWcRő0$;I$)@;;y(/Ғ9v0 v0svҾ];IDNk	 uUUʾ{%2j%-vɖzMD.]Lvl}>+r*0Sj{Vߛ7W;߶�baNeeRTx=.զB-۷6F.mP~YD~@9/IIoxzRVUՑLIj`7-qLl+{v Y~G:Z,O=z4_rS-С}F+�L^*3Їք
    F:YmI.]$=5tE#0
    M;[% 8Ћ
    ~]mB*hAI²-|Y4Nfa�ղHޝȇ[IvN{)e�uĥʔSqa!A"")O2 ;<JQw@|].{3`5ʩMZ&H&ʐNyJIq+(Ҳr<7|6}&
    C;SGҠ+](K=^=,2!xntΝ;b)SZZN7Tle%rA?v?SCҹSFa~ImM̑d#8-)#qp1JNMC}#E5jd݆"Cwnf%NI
    &cE{Q{tD;v11њn%%h촷A:VDҎ:&U2R|P4ͳ)'ǎCyRTRrd=l͌9m,#XϞ;*G6gFV[С=d`6+Z6^k=c}o߮U=1-ezFWtwmOtUr{vgaY>>>h37ⓝC<XG:QXTj|HAY%:WY	q(Hb)Ns^.hPxsC!p4X{$7}vHjY]ydނhμV&ORz\Чբs%r,t@yW6RҭL?N.x̚y2i:R"7|R~IYi~%rRQst"OCΘA
    qvk%̕;|GRaxtlxeo>'yI)S+&pph6sLpdaTY_Rwڥ?+yI)^=Htȟ<a+;uOO"90
    SIʂW|TVnIj{ _
    ҿ{{?`S+[֬7|S,[&{Ih.E.>[eţ$;6+sȢ_V]7tL~ۧ>)_8uX_sGlGɥn>qlYD\H֯~_L__p�ҫӐ=Yz˧SF7ʃ߿gzVRRܙ:WXqUeH<~E董䊫fM)~=3òB1Uϐ_F9S])"I?|󟕡|bbuڳ}?ɾ
    ٱYN2nh4u\9m}S`:SSQ,*O>N0Pv="mP3fv[gkJe2wl{`jMo2k序͐9ؗylΜLn8\V~[;
    {󕹲tZN?'rach,Yr(˗xٿѽr;%6}UrWnΙY-yKޔҝ)|6m̞5]ci<>Q[)6.WJ[8X*㠳Z˼Wʒke2o/~|V᜘vK.YQzh'9U@|eyǞ|]2k2c2mDD۠F};dd;KeUoF(#G'_!3gLi)r�u?Qv)]7[ZE.Mt1}Usuq?fVWe<y⡿X=˷puI6biZ?Wxyܓv׻.UxfbI`NG]4`f
    
    ʢțɼ7ʦ
    \rQJ^ӟYLeRӖ#坿.n?\nΗk;Ioh'.C!8=ܡgeV̛CǓ/SU8Dה{?^s-7cL2<݆eoz6hס	rrrz/o^a[%^zC??=%_@ݛ[i5	9^un7q<
    xO񗆿K\g`Dޣw~;fw=WaW{�oai9^VZr/;pnjԉ7C.Z~'ޱH"Pfl8({➟67f/~Fa2:o|?CacMѽ/jgV/[_wԣ*b˅оw4^a?QgKKNiov~+o_hᯉsMy؟|RyWj?eI>v*#[/6|wdVoZ}?k{֫pi:A妕\gcMO>/2兇Q=҄o]yOvz8J}׿Fa߸gW'QO|#y{64wr߆WWȞr]#aeWX^C5o^w#c}o|},{ޮH=p[i
    }3LEGy^NIB'o+<kڤ .vϣCv4J%ez`z7^o9+(0?{0%gԷ
    z/?jJC!pwDAdPg
     VOQcnj﯒ї_#u? N9ǎ銸d72dݜ?H?,=,QIeIXyTyywHI(eN~_Qژt;oBcbqRrplŌ݀Y'_2cҽ(n?xeyg	brI֋򿯯vy{|w&TtӟK5ݰI3eҥC;̬Uˮ??62⑲tɻ>\4v߭`ϒ)߹}RV޿<4n䏔Eci.
    vz:yjYဴ"/Z
    $I5{?X}jؤf,yWavx'Kuپ}s_Mt͒m8n_1]ۦ*oVdܡɺ
    sL3UE=>+O K-|lyҿW,tZٻ1&H2½;S3临,{6n7O{˟a䉻dªje$ofٺ3XO5r(G=K2
    4{!{%wG_M&\<V&[?O<6JrcU3+T/Y){䝛?)fO_D6Hiҷgw,>yoM(ڱLeIrZ\CB}32WٱYzcYo&lI5+sCrm.9(=}s2g'ٵqkߐ
    )=et8yʅGm7$@&
    zHuM?aX\˩e1HNI8YF)Xж[?dp9bOMnssW]ٲ
    2S49wY6D^?MrR}~n:{K HMmu/lJ::#cЅ	80H)/䂞d9/#.+||7ΔȲ#7oTFJ<8 fZ&,vȜ0I5z"g3|I2woeN<HMzy;kjcVI9 o;	c{]k|tQ*<+OӮtb{TayޟoxDž|l}Lʀnٲz[ʐctn6|WH.;&s+ãoJ~%i/.9RUU.;mq(ç}A_ėHU^*S-meҩ]&mNswX8p8y@!SAי<ݟq3f{aޔoVmcf+˽%o<o`v_gzOaouޱFǏ|?<xp#cw 2y5+s5ryݰixGV _͠F]t^E}şӼ+6C_?\[-ss{znTz,y˻/o`izdN[6ev;a{=omM7](?i<)=~L~ZujzoMxKg3>}Y{̍Fa6Nkoxǎ2pMzye_(ewLX{v^:RYtdݛ'#v2#,{/wTeSz:a?Uۂ,ӽ]^/wy-cBx85A>X7QO{eIf7\}|\7OxfUN:sr{Zmٴ{XaQ5?^%e׆Ïn 4og[
    {?Ȣޏ:=ZgTx<//+..n[+3
    Ͱ~y[v֕$_"Oy+$~w旼GYۼt2'ۧcy.M0⡗̠sۿ{l~
    u[^=}ѽF:z`C<tėx/<KҮ7OyZEQphIpv9&ޯYޘx_z	_*"ivO_goOA]k}בY^GW
    ͐Q|>qЗQS=y>u4uK_Qo|+,8mY»۟3#m^=#ۼ4"o6'~0_}^iu<qKf{'?uox6oV5g|ޢu֧eł=?=wbyͰ}6W	ܼқn�Ɗg4zz׾W?XT?z'ec^{o޵ۻWYڧ>!p8AgW!!ywLhg9e	"$_x|)36}:,zd|cӤS:[>&\p<)!o5k!_U81{"y&<M<\s)ßJ:=zt14q}ܴdF)84?D2>u%I;)r$	0C2ߕP}"8C`]p8O}M:4:Ȍ<CFKdcp6}6p0GEeuH}yn^ZG&pϔ[ i=O
    -bz9co~,ND68Jd#fR1U|p3CS|iե8HI1JJ>uSrH'eX4`Z71+|a~Y~>y~+CaT쳞_`6Ϝ<_
    -%.Io/V!gɖ1<YvGW2Dz�(:Kٿ@*UIN'>lz?£{ڳ�3ݳZn&g}r6ʂ8pU2Zlߐ)y(BթjrH*^ٿOKijVᅰ\w\ׁ2wneaw&ve^ YiWa/xPcJjKkI.2BGdy??XUYQ&= }&+蒓&ϸʳ+qKހx=V'`>]JZ\1Z^V=G"t,
    /&Us7ϩX@˻!μ\2Ѿ0L{BtS
    Nag"lɖkC>1
    qzu<?Vɐ4YY[Akgh[U
    (fAj;e7I.a:`܄ÇzVU/=`>]RXM}ךbg[n|슱,89<g%XCTUiiM\zګpE=Үko
    _vf=N6,
    38<JZk^8Mznp99vb&1+Rڶ^16θ6iҽGGo#wp8y5vȾ>ߏ4˓rd΃J<%OVXF
    jF]yR囝ҳ2t-%Ke-}ÿDQkDlêC'n֕| nY85M_Jb瓮FƏbNw@‘9ONf~/\%\:;W\*<l[q(:ٰ~ZrYxµCfzu߸~qL#Зad60WhaIqZz[8�@Qt6-jq!;ֈp˿PcZ;d[AQX5	5~S@-07Dw>ÀOU0dԵmZ0hxz0DӔrJL2~$MlD.3BRmŸс0|[ü ])o5ˣʦMeJ{
    .-Tx\brJ
    aqRb;RY<`1j@%8m֭VfH]<sOH&	rmُQk*!U?{T˞]CV,^TTOqLnO`A>r*o3@yt%eܸqҿwO	7j~l-N(]-ڝZHm	'y&"ڧH>,��@�IDAT&0'w2h5֙92zx%U~7+Y-<G7vXطnO]7;Ŧ>)FKNo@WDMf|aŒv'q9-۶ӧ^jsW9蕒^&M;Cڽ͓Kmpw8=҆i]hymR/ucn2ӛ
    Qa@eBpuG$zx/+tC~u�̢ǟN л4A
    ( ذ`r{*(
     Ez$@{o9oބP}nj)g<3̙sLO�*lW@8\?9v.B0lDFIZ&^ijy][
    F@#h%S$a2!t1,ӿH_wA4DgJ+U?<tt]<"%XN欮?T2VzPq!EbUNոrx㲄Qcí7\gzN8Z7*?Q^=b]Xl%wAftkf=IƜޚlE,4%<*_,~n~Jn2j|k4tF*_CV^i	^#9>j9JטS`eCh9؏/&ߌ#?{EA-oz>UؓtT%,!Bɝ1)Ipʛ2?Tnv]0q˟#S7qo#7ΣG{Hd@ႃ.}'6OfAI^'.DyZc	􃦮2!"J\6r!:7Z }ff屃YJUPm
    XWRPM@~1V|8�q^*쥠l3>#$ЙV~>OVX8QbZ5#Kvn\s5G<ZV<;]B3VԳfƷAĭZN!Ifrg'İ pv3Y`QY]
    c(Yun#!M~L&wzwmS.UqS	
    *~"z w;.}'xsAo$8;Ż\{6h
    9HڻG;tz*]�wMǩ[:*Y3F@#hkܙFufLej<)J
    ZmC�YԜ`-c
    %'{V[	tƾ{}PzѹQۀ+ނ³xS8xᯞ4.7;կ9!?Urx+')H|p!|X<+(jD@ߺS8o~t&o^Vp7~@p8͈˭)dS.LrH[Hߛ30HLsxґ:̜J?=aZU;:3Tc	r
    q'1$g/[ >r7&>ZJQIr<FĶ0g<7#ZPk芐eMz:ZШa^	P@߽ff5d�dUe%W"B6-؅8ٟ|ߎ1# M_7?Gۤbj!UC02C8o߾-1hL737~7=4JBX)ur@<EgSh$W@+5VF-Iq�c'Ą+FZ,k7,>k^x>p|ѱDx1ԕ2h&6b,",~S<1N,Y;"bqi#V~u5[cD.4ze>əqFf6eBČ2*:6sT-ZSn-{m,b%ĭpޮ]"8>Ôk.GX֬
    Gf?z`-1$Ɓ&x([u9v|880 WNŦ5xWj2n[
    7.=$!|/9%$T2ep5F@#; pTkq%hNRMA;IB�M$yl
    ȥvaJ+jML3e(
    ^N}FusD<Fу5W	u.Q̉+p2({𚇣jj8XݼwNGfWLy4+i*+S%N>%Tp«oߴAԅg[`j8M7C=Te
    hҿ#}f<<f)3ow u[i+ֵ!8!8@l+k?و9h6I9
    Az`??NsJ2ѡ{?Y4Jj
    eu{CV/umCѓ_͉ypݸ|:UDX޳Uc-9ia7e]r움$ߍe󧓶&gyZ۫8]ݗ[ѽ~:`d],Jih+]ݜLhzwW\B1thXF^[K@7^-<1 ^fHLCaq%"<NϩYM?YpSz*Z^zvxlr$`pwB5V4gҜXW_+s|?-@qJ+āڭΠ2	T=rs#|@K{t/>go}a5Qgn0Ʊɼ=יn",B0T6,ŵ#{?ƟT2;,j+QnéHOGT9rXnZC?ZcީtaK$sU'2AF@#h0fcgsA)TdT))DҁdGdt4.E]XŏEAf;ϾcE78%\ܫ+|]QV!{\p@՝f+`#(!sq"_ZSx%cWҤdޒq@dpEgg<R0?Yyȡ q'IUEUC"舉R#ʘܵD]8P8pimq@&x:r:JhAv}9ӱ*E_e>c.TuB2>n9	\w?ZtJtыѧ\xzwu>"lO:jm>ߴCsC4K{j]Mb֕ebi|Zc˨Aߍ]v᥇Xh򌌹,5{, 5w1V+jtah/kq9{%FEPH	Vꇋ'X=UV^@p=\ݻ2xٝX#ᓏ>W_(H$Hd,d jʁl�x^Fz͗vYWrMsZdC!1`}+j
    VIW^WxHu
    dK@ڠ2~
    B΅;vPsJ
    |BZGV/ߡ6J1q}bukofۛ|Y7߇뜌ޮB	]h)9{w9|=7gLlF6yߚґgwS:Eƛu!*>ұy|MP|dbZ$D<iwO`Î$8{}:b$x{<8
    %í[fe}~ZdqYTF@#h4;("XI_ddr׽1c<2΁H8g7[F
    zo᝕щf2t8b&%:K5҆q{x#.z^@{Mٳ.|E}"Z=y̍^{Q[C5b̛>gPc_aDKHQtM9]L3H	u0e,Ğ?W*
    z|EFGVzzuZ7z'Cw=;ƠW  <"QyrfiǬӉf,EoQFow_qVyX=,-eSX~FN	jkȸNi;Aq||܏l_Hæ_K>С i`7׿ƍGя~e\	LAΉ‚\ط~(~^FJq8;}Ec
    ûD-WTL?5C-"pH4ՓT^`bN47[]tuKC<wԆ1zcZkѓmEjtiV_ZB~"$TPknNdpqgg/dcrx',>AQ@jlˬݑun*!(Q z	·5Ǔă.ϗ97vy!Zқ|5DZTY7雯nOwnAskAF,Mntl;p
    ꋐpum>,XW�[6Jx\Ч
    ׍4(#	lЍf3_80MMtY0k ukwaÆ}?ӑ:)6GzcC*0etNe)a0ok{-QG#sBkTp^:|gY}<
    
    |qڴƢaET[6QuDy9�'Z(@|Y(bo2!+pwŎ.9ЧF#{GD
    x;X%څae߂F
    	>c<={p[Q$OP{K8:ƞ>7"﵋7di,ՆX?y#dep)ErZ9֩~F3mSF@#h4pB|<皏e6B[ﭸkvVeKsSm|LP_UML=%_g)gڞ(Ӿy^Uκz)WN{v"ަR}*-<&֭kW
    gY4mU޶1);7VZYNkhx}˃.~U7<םUcH[y͟=
    kp,_4>%�|5W6:4'٪81*+/-zt۞!wu[A3%Mc	w=j5׮,-[gP̳AUnyy͝!F<XB=ikw63iyv2ߟ:gO~<':dlױrWx~
    mBB"m!>Fek%3<o+2d.-}y]>:ly˗}dJC/xvՖi6tw̱`4 #77[΢ӡ_B*A7A#-ymNv"ovdHmnFh.@M{Uot
    zۚe(^䇞唙cL=PD2R&^hfuf8^bVn/j8쏿0FvO0c
    \sSUNs8۶žxGK-2փƙܪW>]N#(Gm_F<mjfb.ĸ˨q~;|7o/4=%NQ(IYŅu}VgCmv7MYx9mޞf
    y4BM:a˞Q1~6m(ʲ͛>DogkӄPۡ<=V){F#h42NV5p4QBVH.nO{jz~zN64e9v(\8g5ԙڜ80LQ5i$&b+P^VD3uC{<Z#[-=	n;ym/FуIsc8:㹗^ã@Aa3E1Eznt5aT)2O{|\
    z5p~1Y
    3M@ɕdzP|ɛ*;hvUx%c\Oc{+2oZQB&8J(elw7T/TwO=ҟ}EEވC:7~L%5jvِdž*Ӌu͘%1ԑ~
    }O>;8-
    w:$t$'ߌuM.GY^vCfzV
    ["-܅<O?c7;J5(Þ,#Kb93ӌȞ#`u`}XO}')p15틐V]"o_0M6Pcn8}*_6$}'\y_*nA6gcXT6x8Y<o~թZx"K/|r%/']xSw%P%t?~_z!DkfsKJmRK7jkSSM.=;R<GwSo?ﻉ/@rNGe˧߷b'U)y;w'04H9/Ց
    9+G{
    sm	7^u2ij"<<m
    l~|0nm1媋GS3vR+}Í<"8%Z⑙jW3;o7@"dA=*[UGc,n?kFJ*GSBzj3Td!$~~	t
    ֶ`u~M
    cV>yŔčWdFr$xe8A?i4F@#߈,(qI*D*RLbue{r)1Ď5qc|=q$6NzHۗ' ];ĵT.%\(lĽ!NC߶vbݟ7iv:A56yE,NǶm[!ȞPt;EI^:d+m㔥ɭsO:jܘ 
    _oema"t=EETt	øz?)ڙ¹
    c&ڳiCjg+krPU)ܥ3I?gos;oܻν}2ӢfsJ9whɤ#?sĉb:sC
    aaMt^'1Hx}4&n4l11i>eL
    8x~s2229(
    @dTZnθd̵c=;<<e\q^q45=}*Ȓʭ4RG
    TcV}yVn)ɇ7A4:tָ(.6DVջ"[;ufH;YtJ	E&Gʎ>Y41\LXioko9M7pj:I,(m];&48S3hl2)X=˧_*V(<qw]:Ƹcj,_WP8Dec'HB%JNEFE"*5ZqIʲb$.n$",VgX*m!AA.x
    Vcozoָ0 +J
    L#5-XcZlCbhES}	T2MҾ}({9sUcnTZj
    =Sm
    	+,[M=9%{"JG߶퐘~^g?1~}1X>@/,шEHp�EPӎ`3Yc!$<	|uj8p8ǟ5Dzoan&&F=mԝl|\Go3TsQ�()sBLweKN%)m6
    CqhwRh4s�)RS`݈bӎM|ߊ
    y'2’2u)QHhЖ	/wP
    ۻ?	9<A8Q1ڵ#|0G#h4:N+Kk̹armFՊS! Gi)';ꉓTfŘKr-'RL&喜a;bMT!Rx<#
    R5'owb9IxV9q`9pPIwgtpJqg,
    Ov8GqE,Uq|Xup.AY[—%`n,QgmWMrOpVM6cNq`^zmm̃JzO;S-߯X
    `;xd_iXM5eucwѻCk
    yO+.L9Κfp9]CnO]4Cݓ 09bji:te4/Ѭsj�oc~?d<X£юo+N
    t;/y1٪*ܵiy<K|Vuu,k;5O
     8>V04>4thc иCs%N#6V5h4gm˜њXqNLeB'Z4
    .
    GMM>804"8x9NP,gşɏQ4,
    @’YKBS),u$PIg$OU'jDY OMϖ>+R՞;m>Sh:y7l
    !U&К'QL'IvA;ýIWS2>*g8Sޗ:XEu]Ƕ6Gc‡@iul3q{׋g#cOv=:*ejIhxڌw=9Z)r:)^ɳXP>7+R#Gses|J#
    3G\6x2f:'WCoX 
    ,^,oyN'b.7&e̍OfT4WRY_g^hHw`<V
    O'iD9|O|Lz;-,$xp,,x6[mss5F@#B4ǚ iM8̍T15V19I5L
    dŚX9XIhZT48&Bgш`64l)Aڊɫ>iޓO0#IRЗ2ҶuK3'G4xrH0u4%*MԴ|zȧ׮ElhJ+U_ry~:yYjѳ걞9S!e9{c<Iy#O0M߷
    4d;$0l=0-<,ǻQRų#-cg`[mS#ﳕYD^>urgdѲJiq77hIvl4Jťi:.bnYZsc<˦LrczMiacVyx	ձh4FХig38sp
    S?UMi:>7c3[%TOoE,
    4>sS?]
    t3l*og|6x=:,R%UtWu=]^ǴXq,/gCLyΔnӼԑFtBqL>%!my}@tGN]qɥaCeޠ}:Ө.S c3w|+ܜ-l-NShp:-^k|8U|C3qfH=Z'JG*^#h43g܃wf^X	ԣe(**BQqrn%U7:AA-Ͻ*UJDgҿF@#h43hLWh{]	Z8C͹F@#h46qW)h4}vkLtF@#h4s-ۨ	[5f!q~h4F@#h\yn*gvʎL#h4F@#7D:oȚfI#h4F@#h4Z@?wZT#h4F@#hho95F@#h4F@#8w׺F@#h4F@#7F@Ѭi4F@#h4ϝ-h4F@#h41Z@wfM#h4F@#h~nF@#h4F@#߸s4kF@#h4F@#p suK5F@#h4FoƝYh4F@#h4s-;}[h4F@#h4c\φ7O;99ωgS/ţ_zMCLz8h6fOj)ůGr$+\[6[=ώU%O1_Ǥ/
    Ƹ_{mXt*L,;^7jܾӧͻn."͍m1"/*Xt4ooSQF@#h4Wpјe2I=H+,c̉>sӌFh>$ϲt%oҶr6ٚА<5ߠ8O3uUs6ǻx[:f84=k32/W@k$J=]ImjBi>y8R
    iyIi.wV~()nG?h4F@#D0?eUpu@@` <\H>`M7G|͗k|v:Y?�Օ[;s++asrTHѶ!4_.iM땸jn,rw:"h7]Pp,ӘR㧊2Գ->^*A%'/M(MK{EX(Ƒc'
    !>jl6(|YǐU\1pZOiq
    Kꁐ0I:5ը#qř 侮Y٨ $,*b ZO=Z?ĴS7m'XvOhog'C9Ѿ]<PSZ^[_
    ]sws#iA꭭BI)d^ sO
    /櫫ā}VH10E%pb?C`e7ԽU`c=[M%]*/A~azg}"e+(RxeE%
    /Fe$r/w[Fˈ/[q΁j\[2ςe1tuR'yϪʊ^Wc.
    R$,zh4F@#S[ˊ|R,+ԸyRZF&b1nj.=L'Iz0ɧqm'D^ee+
    Xul;_n-ߎ0
    pD$o
    Ǩ߆8zkAV
    ?<8C:Pֱ.#E%Or7`PW'[ ,ۮt{Ih3ё7IM0Ńu-/8'9`X8*'Wb9f'V*|ȊFcB;rs01Zn2}¢!dڈ~~puqAY^:\gNE {,tB,^iN|D̜6QAv*k<_C<tX%..
    V$_Ye
    lV~>'o
    {
    ˿D>ź^}56Ҝ4,|3
    z"'WIL݅ϼz]`n{NOތ/ö?Dp;vV>Ueq/QasCMU)ABT'*f:o-Y cTKX7w~I񀛧-g/xw{u$^pwacqW#У;u#wOj\Ż)3O͝e2P߿[yθa5/_#CsQN*,|Wo"3\;
    &CpO%BU|>-]: ;߂W_@_V7wCvpliЅwyth4F@#8whV@&_b'W)Z
    :F$??X`0t75!745uM7L	y]c~|Z9`n `2YhY]$UŠZl|]/K(};v`zIkNYH45M=YM.pwm9+ג%hu%0S|IYoi168+&)~=9d`QMU=$(lul[-<<<<PS]NpOzTWRF0W4n0PkrHjd,y[rl
    iI4h$\ZYW¹Z3gŋnŊ/@3h4KQ~z	-X|~>\+:Z5jƔ
    յpG51QgpŞj{R Tu]#>5ƪQ`!u֔fcs1yAWxl|;Nkj+˱th3jlj/7wzvibR-$_ꌅc'`¢eXm f~;UqǰU{"
    2ۇGH]M.HP<q(VcB%WŽ>fFz#8N-\nL|u	ny*gol\:28ĔCq3Ҝpݛҟ1v({`ۗWFRW%F=>|:ۆ>X<
    n~կ`C|K?VK^_cVkw0᪟6_P3EHOڂA#3p5C=z'55zWF@#h4sft΢EˏbE$G~(,(*	r
    wI"&,�wo-{7nBo1KQ]O>1}/^퐖,9Epi+O]PY/\(;q1[.2:uAhlG,|lV^ˇ2ïŦ~¸Am֬PZUkжU0l$mLvnn=0a@Oo-tM3o@22@kZY߭CuzAHڶwP;9u-0mƍܧ3͆P_YD}Ԇ#%g(!^U)az^\(+Wݖv(	+G"˕q;+o
    jqc%kݛ/[x3䉄-|a7F]3㯸" Οg˿Cqe-b;a	h:?c{#'V??6BԱhѠ=72.\2|Y*-\|xЭ·pۢ0Qh੆!XH@	}~va-qWk;c>]p
    ƔgWHt	|pe(x
    .q+!YL*@¾m`}v8~/YR[l8]\[
    &]P8qg@Q+']zULah*>q}2h28t>1POOޥ܄Q4bνt'uw/Ǭ`o-WJqF7LE(<
    K?;%W\ˆ+1f(sFiQn+OOqh$%^K7Ѿc~~رm;7>mZ(C.}CR|?q;i&
    U\<!Uܶb.$4.TwK}=;3!Ͻ�O}..JnY\-Fb}p òϸ~wG|VG#h4FAnױɔ5TpB#ģW?S/>]=@M]3
    35+O|0({".:YIG_ڳ	So(=fNSwG8&82gcؗVHo^f}>CʱLՄT,Mx0ٮk±0vb#濼NmEfREd~\>=S'½<ٹE:\%|{C/iFKWt̘90!n{)3j{pl!6Dl	Sqŕc쨋ҫHFJψ7Wca沁u,_E˄}4e
    &]7݋>^epabh~(Ŕ)ףSvލ*4ǿX֝bUpӤy~Uno)=]G,ON<)VZڲI[2PW-~EWj)KhNkݷ?>[vr!(
    8(EnvEZIOi>38KS˚T]u\Z<ډ:h�"P!,'na:B;
    ߋ1ySH+G-&L|sJ11Z#�Enܴ㧌CLTf20{^XGw8&]?	IߍZ.+3S'DD#.<o:@~;۶UE/<Z+Ǐ&x\T˛Ķ;pYcn̚9N1S#\,0oum\[G
    <_dlf!'#MOYi/wEzF*~~ou[6_�k}ZqwC0ڨ,'+O?b舋}DQRl
    eߕ8`0C	q@1$XOyb!"?
    ~ͺ�xDAt$iʂF@#h4,j+C1ns%K"u4Y㢱g":_*.mctŗq&qo;uW_~]ڄ)FHIv|lEKV<7ѹW?v@w~FQ`%X[Oew쉉=`cyJ?<ӫ3XE\pti�7{/u#(<FtN9UJRl@B|ڄK<(B.m8j-GV⪑v&][_<<xhC-n6	.B[jl=1$
    v~J{.,AՐ)ޭbtJekƦѱ�g@|cI:0Krv
    c8LT!:3Nf@ܴxhʹ:�כdu?u+q$-rD{^n$z`1w9}2B:D*M^I,S'We2_>dž*kI -V[c̃ML7k~YF¥ZHBfuȢ3@7C:��@�IDATVDH*.;!,:UnZލymC~=ʎ3eVd]+1|0^-ѳ l=ݍ^>qg
    bw';0<5^
    H+BaKp"T^#!0s$?ŭ7\Dv7pPʢrЯ?yd38
    ģ<tkL|rXܡ+Rћ1wĬ�nD`
     t*x9v)1;_c栰4	O.
    Pn;	;/c`xD⅏Vbu*:U'+Сc{h!CCpMp=Щ֬�OA\\:-ga}=M Dz@Ӕjq<<RΖ>b!}!&etʗ%N]g�SO!Iygj9F՘-ǒWLJ{(L;a#ұW#:̯6wF@#h4
    
    Ju3DVN.NOƽ_B{ȣV{ise;'"2΅nln:>wE[2jLyi .Xgi?mDtA0x5l݂)ÎͿ;DL7�PC掊d|[P]W[9n}>ܞBT<ei;1s=z``f&Ւ'ѐՔܷ?$ɫZvr:%�z6oZnh'Ͳ2Q|_6bå�?
    ~1q4
    uenpZ
    l=7zCLJkUq#(F
    Q=5[Ȱr[C$,YbzF%|4	珺QȢp^q?[inVe^�t;]VⲅKpQBUA^97v)dJ9X/Nܝ[
    p7#MQk="خ$dc|*G@mV_`[*`
    Z6E,%Muq`.Ā&|x?_	prTP)L$O3nQs7RQW}jac~"J+܈ݽpų:fz9/.,Oͽ-b6ğ)׏Cp5oP0ۆC"k	a
    ZӾlTUA#"=򹈴z{9o 
    CLBoH?g8~	ĩN-(4>>{8Q:gرw<Bth\s''k}v]8>%1yc
    \_U,5nE-+_{┱O^h4F@#p!ЬnhϩLe5CD׽y7<q1aAwf/B;MwF]{#nA;{9c2Q߹f~nr2O'nld7+'g2^&ݖI
    Y.5`�^;0ftA_UY&K~GZG
    2IӴ#4 ԤnQd۴W?sX;0{FmyI碂ywSM21 
    \4J ZcAA|LM_wEމcpr{n߭ѻoD41Y<dHa=pgG۱&+m5?PQ>Y,N<1&߹s+Ȫ,9OLaiSsn/9VI_/VSoOOasRzSh(&bү"#ĕFpE<=]"Es1Ǚ<r]hdoQQ>jZr
    Q}m"؜Y9VU`_p8Ǻ}=gZa?I€W?ǧ`q(
    x)ÅBztK2�陨%Ԕ#ea
    "O:`#0ʴ\@7gwen9 �.؟wA^*Ո#@/Oeu!%KD*ހI Oz$K9p *eD,$TaøÛGj'ϸ\\Z烶*1&«\<Ko좫,EBԟѾ>Ҳr->gqx{I%=)96ţҔ,?`9N$އp@4>yo]W1o^y4uZc,;.tD)&ܖ1CI2~K颗Z$ZǨI^Y;ih4F@#p."`ME]9bLuQ6x|.+$>'Nޭlqqڭ|5lw^+q^wP6{ӕ*0avGZMw<ᗌ@qc0~_YEe(/kV#xJo^IOۆ~T&v00
    y{꜠cU1羗eA]}X/(Ms~W݄י&ӿ
    "*&ݺweT|ɞX(ߕ&ٙ{//\㷞Bey2lF se!>|q,z]+$w򕟡'wݍo?�?m.	(?Ya:WpZY&{kV\F\}xީtM/lE9e֒Tzh7QR(+FvA1<)
    u94Pvݎ,нC,Kq,PB*;>SՓAgރSi/	98qtfd\#wUzAٻ/"Z
    7>gYZ:K°!2C"|[ZDo,ytf%wboԫy4^Qb;@VtxϿqI+
    .ӗ=dȢX:S&ܖPAk
    !PÅ^=ƎyW6_4�V>8tY8
    f$|N]x,<w~޸q><c̐be^?X(?gǷF6o9>z
    QAbTهQP]Q9fqɥgmO3vVБھ1,]s݇iiH?_}БZH6EYIزm'HA׶;v"R>ګE.bܯ6L>}?5M[TB1xl8ƅbhX,~~2Q\ȭa1/ž=')En5bLF@#h4lzK
    :_f-ڹNC&cM-EWī/cc^8{
    #dKE"b0fiv7	_ꕃU}z{S3vQkp%+%=Z‘Waʘ]<^2FUXi<]&EY4")6XmrYQ~vh:x:|];^4pԓ{UD<t%٨#Zt#3M{suT{Wڥ]SD͟<$S;8g4HS>4
    -#"0{C8tۯb'h<vø0o.63.5$B:X?h-ǣ>BHև(RgPv}ٰ+n":Hq6,F	OOHo#.oe98s
    ٩x={dMYGwÑ	Pk:u닜p'ņo09B*"I.mhdDQmb&oJ$Л#n`w8{Q(H3<&n~!kW[{0by+ͩ˻$'W3-T|Tr1ynlY=u8^_^}^Es^<|pn*=z�ފOSwoKB{oq7ŠϿ܏Ud7GLqؼ^mnСqp;`w]fhCWjRV/-=nT;<6ok?ĪO+}6Z�ҰN@ӯb?'LF/VG["zGeaRrbSJJ]7j?z0TQp7|#-oܪzrG1n\1| jqp(Ӛ{zg=G9sZO`ڕq%G,G!s-?Kx֟O)ԧ@GF>SS F@#h49'"=d]Jj
    Klρi@tRFcA1W>
    jm˨(hDh:h3-ZH~v2rܟh,</xR5ܢS}E_CoHjF~p%W�zt9/='+۩E6mxBAa2y~Jr9#6>A [}0϶
    lQ	RP%EE4_5W6T"Zk֛E{/…[.m-US;ŷݏ<֮QZ5uǎPK\Vh(_di'هe,~¹QKl#zE0+*(m7A]9j-q=>-`sO++>9⼫6/ܿ+g{rL	}B@�ljϥ]oժ
    }
    Sb|�aX[ѣǻ!&&~鐱
    ]X(m;HAڝFpQad?I,Z’ro@Wʒ:>YŞ޳ØbkΉtȤVZ!WA4-c#1d
    A4	�-iQаPj㨢[7\
    _Zz9ofe[\`Q9Y B.5yjc.yO­Sz!$0OIA|ף /.hE	~g@'l=ͥ%JIƅ
    Xڡם%!$<¨dŴNaCM7`^qP$ fR?cu<#7›GI^!\՘72@y8z.-2˘B.U[f'VNޭ*h4F@#p!pJ]h*h8cYWǴ:sw4)ML;>[{-Z1ɳ2oD0=VPy&V\IC0#zcKkd^$&387YT)ɸU"ߗyFSf䵱p8!m㟱W!#okl:R)C
    }؞%N©d%aYpў,e'7giBc;*C@7)@EP],X/^b J{IH	^Nf}>{h{ʚ5^Fl'Ŗé@gÉ)1%s	KiߜCu҃m~Ƕd/T&̣K-[M_?}v9G0#
    c_.jk*mW]>=ߖn�ڊkGellnT\/K/r2M" H$D
    %J&
    2Ǿ'fd:]g#i̲֟b8q	bAL.Y]{=TOhu3&4meBT^f#r=XӇ[ۜH{QYj3[z\5YfL.nsU8u*	=b+y_,1:h/,ڨ5mCH,)"R}P1l4brD~jNnLJ<հ8[Oh孯Fd[aZc+-
    8r`?<:c`boaϲ1}ÃGǕylh`FT]ն`<	Zmq$Dkc#}-t:b%o{}
    T/ѿ*S9JPEi汬jRn?hmrY%Ay^;C(^ }p;Attᩏe&L=T\@mkcSy-}k
    1^}f!$D@" H!]DP֞ԫJ ,?u'gus~=`hX#rZ.Vi(˩y.Mgʛr,ZVZ_-^ZO*L$X^N8gOuY?#?Rǿ//3_RD@" H$DF	:[OkOT_DBA!z>|ypxvwj~t{˨y;T[}q)r<iiQySu@T78TVW(Cόzbet|ZUJAtq_E/D@" H$D@@G_M`ƏZhA挿x)p>u/qx&Cn'
    4-5ggY^-	F"T݌"Ȕ]_A`$CsB@ȡ|B7c]^S-kď˳FB	%
    jyDZOx}>N` {kUӍ8rP28`Lm
    j6Ar:(f2?5Z/|]q+ӠX,,CG<#k*cDŃo,4T5:^Kw^:E1OW*H$D@" HA:t24RgWO܋6:x0j(DqFQvZ_V#,cIzD4ӍJvOͫ:
    K',_Aز4ӑ\%$BXEs]a#Qc-5%56{6~]ȗy9.Bde+hmI͜ϥȲ߷ԹL;q*"-͍	k*Sgi�tV:
    nfC(,3>gY'ǩؔ]8ukTݩK4f6i"\N+_KV߷lG5Yګ?s5b#CT8w|5(=y6y9	
    |6SFvĊj8mss",?@7C~DYL+M|7cjO
    Ӈ|:Ǥa[Y7['̼v.
    @Ց>	~
    Q	0o5S!i|T[m[~Ŏ=GPRQ.1vl4 0u)mбp̩n\#l?uKTd=D@" H$tn$}ע߈	p
    \"${᧿?~NN(#~ftFЌ5r|s&Udً^{wo!]GRBw<H5?yuyEZuqι
    
    ♕0P5vr7OG<N<\]LDɨk((v+lsڒ,<d&6mw,Ag=9<֖_%9gӦ;r2|=J}=z~zf;
    ݇Ly3wΫgG*a'|(+҂71p$;ނW%|wjo<nNͳ-DiRGQE@~Z޷b0}1[1yPL=[$	uYx|A<NUa]-w;nxEW6̾C
    H~O4n]p#KH*Yϟ؃1 ,^8[ߜ?`-[>K$D@" H$FtqnĦƒ/G7!6e֘ع�Z5:cG
    #
    !-ᝐUq;t'K=J-Iloþ==QWQ߷xa1%|WS	Fcy!*1|deI}͢gH'{9q(e`dCA-{bEy8~&!sHxv
    ]m>7R{~e=  PRGV0z`lI.;a=Kp̑Ehmƾq25.^<|$.8J}_}1a0x:lQ2N.$QHaDu1NWc`[n/jշvp?}�G�'l]9=.0z
    X}̙6]h@-;bƘx838.I=tInaB;:lK,yc,~ca̱鉛40ԗІ1:^NJI^&LE<aDgoՏb1s>pvS|a|{42ݨ-1}`4uŰ}J9E;^c1$FG=4b0쮕XZoG`uh\$D@" H$W٥lvm")=Uh1ݺ2vl's9o_Y&(;G%"5ּ<Obɨj%[XCp&zI@}qmiK G"Ss*ji"(wpDNV&N>صk'ҽgKXȮux㓭h3.VcтETGq&|}2͋m-,+egtr
    j`ЬsVϥ|N>Χ#5-54CUDEPރc"Wf<}Bl;t
    11
    +@Me%v&LYԶ_^mg]<9jۋʷT#ċ>愮_(z8D[n&SBqN6>~�Ƒ"l[߸e՜uQ/hlENv	Єq�FšoK.Tn^ٝ0kQCqv*f̘hBeEʔ!4h*!q(2/<\ޮ"3 Mzs<7c#\<9jC
    K__oJmB6MOsp06Y<D@" H$D@"`@+b؄=bҌkѫg$iS'ǩ	|
    F9WN-3E̟5.pG0Z􂋣=N$v[Vf#.w!p/4KQǑ}w\58GpYpj'֩)G|']`֣}Q]1gړ/羱n1tNZ~]Nn?c.x7q#,)psRy*{bC#h(Ķ\os"7,~}
    WG}Y/v]'@]V>p[7G8;mHXi9bf2GD׼,pMhۡ�/=<sYH?4碖;::iEh=kd4& Z+W[jJgqdխx!r>|c%
    yЈ}`m-M4A
    STf`;]N)6۷DOZ	JNp7k`ֺf!&(anL'p|EHsJ{/eMgmO87U⽗`�4T]Z�'3^
    Mn997d H$D@" HfVdJ~"ooґ{%aGph#]%7QGV'N6az⼙/.>19,#گ6o
    <F\x!HΟbscl
    N6hn%d2ނnTmmԀb"W^ލcǐ=Жx΋/>@mef@L۞r)mJ95[T(c^Fϒ+c)%2n8"\BpH޻DBs[zc3x#E	rUpdݝA砩w(~]<ضq(=pxj83ZE1AfXSw'`YOmt0(ALPm)eeIx>x+<\l1wdMEu6"NҮ�s}xߎH1_AJb|4fZM0!CZqB&@''lɰ|M@Nj~U񲧍xg=x&?>cI+J#y'H$D@" H.%ֲۉ@ya�k!g(ZSw93i=;a9@q	rEfowG;3o~
     OxrsSF%cUi{wm6׹JhD90VigE$69<"1ё-WLݖ
    Fep:-B:jdQ5xqPr&~љV0v#f̫眢JanJ[C# sEvH'M>NMހ/8֑{3L)˩mn%uD0e"xh־N}H(,zY%LkKs"}<|!F
    /?w=PkЀ&7VmhX)J3aN[™s)wBiE؞wvJQYc>L;*i[]f$KmO`Ֆ#xVsm.e $n>>(,.Fq&[KKk<ćm	4cl�^"͎*1l\Za:R=)D@" H$D@"`@(|;ypBեHK>a
    �<LV}).h[IqH[6I׈l#'ě9g9
    T
    w#k}vEK4v骪F!n"jZ`v-<dEˆ8
    "ojq^|ݠnqRuUa进lۈ"܄qo:n$v,x}}=DҪ@_W\EWkZeceTճ:ϙ٩ g
    
    @P'9ތsS]✼rŊɊw\κns;JJj|+׿5|־7m|nFNmh"?\g-#ojvw.U݉}\5rRףgDJRI	mL8zz"<sh=!<]0&cwnjm>NmI7k|o`'F5b=3oo-~zѱڽ;?{G8 ҧ~?ش Z+;qgxvDyY)'z~"
    ؂ΪL7>ʋD@" H$D@" BbmUKӈ=V[+:g#lcWOn)†ƃFԎQu;ֿ]^d*1:Qٖ1H,}	8g㕷N@ol|y;
    ]qwOhq^f
    Z<~JDzw?LW\DF"q|j l\iHuqK{@pno>ftf
    uS,xNȧc+Y ֽɏ7o+[X	
    yu|"Fvxh@(8vTct:̇5޶vCK)>!?E]>opnQ$]ZIQr+pb챘xMic-Yq:S6qb_px{*}FAn&'`xIX;<8^ͭ	ukboWaf㹗}? sJ:9b"F[1/=yƎcY' ,uL9)1B^x{1[삱X)<Ef~yFp$O!dt|Ii9sXJ:wF@<K}'PE_D@" H$D@"p)ll*2hBNN
    \q#rAThZ9gj,FʙTj;aҭ;ƒQ]^:DDv拤
    (%]t3jd
    sgS_L[]#aO^d LSPM`DK_XJ29:̌P^NDhG>K;
    wt
    	U6Gv#ge'י,Ե9!2"XH*+Djjl36Vx}P*uߵk8LF+w;7[UčtV?;Жk{tFh[梲Ŵ]AxDEVh8#=5	Nֻu`>x8Qs,-ERFtT8zQ^ nndlv:ZB~94ULRY/C�a&|D&]d#)2ؠ{XDw0w/'Wx
    E͓ uUekA›
    N?dFޙWձT_M6!0K[[rB6WaL	/1	ݨ}LA3YFLtTJ_D@" H$D@"`F]#2߱1/ui$@m2Zv5t|w|MJ̺eN}y:BX?zm׉6H}޺k9/։Ӭg7g4aB!)\:QVPՙYhڑL-]O[8vxLRtȫD@" H$D@" `.C)Z&,|13-
    1Y.'ӏg\?s=ф*rGӮn,\Sf.AK-bBBG.#^i[ԹJAڢ,Ɖ&ODm$")j.MV^/.cQ^<um_{
    #[%1uTk^ic8hi(&}4̩.CjE>#H$D@" H�t.l$o)a¢l-t?am[U¦EMxZrZz9KWwv]F1J8:MM$UK+cLyiix}'44}R:Vk:YGM25ݵ>ўQ2?_nȟ%I$D@" H$cށb֫dQ9-4P{k__fy	G6bW+f
    ;K`9+Ɲ/hm~g{_!㯌M" H$Dͪivq.ʦezf>[ZZ(:T:EZ^,(ӓS$XׯOsfYv2*tWW;X5\NKEfZdZԳuԛ0V3Zu#{-t$-9px=x2P0n_%K_{Ɯ8Ӵg8QWk4kZ&ݕXKu!ק{U~DQkmf}Z2ɫD@" H$DK1}s.YN!_GݼBx,knu fgq7tyA.\q\4ҢMBJfeDF'dGKiqTt^YJ:N[٨;ׯnyWe(D]^>5Xpd:b4uve\l;Z{:.'0Y[+ZW[#4nwΟ?CN{wtP;;6č_
    />!_)'#1#jq&=1dj*qA=gDƒ\奟ɔL9:{sK Ξ?p<	{:KhzC`K~cƈPG;ml<(ErY=֜vz3uCrG,=8DnWRxVU;O4n(F_VBr{G.0Εp#cWjj'׸&6Wm׮GMeh	1ʤrdx|jCDEu,UXZz=v;jKc]5ʫ�WgQ/?D@" H$t7`غ�>W|/Ne3#ږܚiD8o
    |nX(4(fg 81V?2zb!d[ϤCui>^}{(N\J0ԺԶ5YS{!Gۣۢd0b̘`186|PN`C[s#&Dyux>z3ix}hie$}[k~eL8o~sr˖|qx.:n
    M-s1v�<'ilFCU6n܈Çcͪ1ze݅]U1}jO
    LcB%QC
    s 
    1ycҼ3ƫ_tr5⩖3o7s]M
    5U]=(k:}{ofyfTP/Xj|8.Ʒx/u.ﳆ*ňN/
    bvu,ƻ(>f{Q޲͖BÃerΡi(U"H$D@"  _)Wa3ƒx]y'nEBdҪiJ:8-LL*!HEf{zF6 '+h@VN7u\L4lJ
    (Z&? &#Vhud;++piBVnBtGOFr7%B)}	a<"Դ!6>|{QPP\s2;Z~ǙqaYX@T6ߛHU֌3ȺP7jɿ{h'?XSӧȇ|-'1psr
    $_YB>ӻ	*)QIMEi
    KЭgw8<N#ɷ8a[@c%pBA]vprLj_U_Jef'3fNoC1O�89_~WW]L?M@LH,ǥv��@�IDATz"?
    Pkއ|Q!^h&\hU3sh)Ù3IEPhF~<W'	ʺ_vCN*ic9ZZ;ңzu;"*p*)Eh\&$jZE:dνzE"?f䐏tR8M?W!gSSJ8:"G:{8@>=@WD􈆯3r3 5=m6N:(@l9ӵ!$D]>Ә·b|4ӎtbpq|kSMcjt#]ilGҙ4ۡk^>\6:#-9wFBe_2ف.~	Z4zZ{3]C:Q\�_/d9gbCw`/*щ	WI	
    y#H$D@" #`BGZj}8ׄCӶd["!H-믧-^8sl%<Ū՟{\""CQv%cYp7w-61v)ŀ$PS|h04!vܵ2^A
    \Exy8`'/D/]=πH;	ۇC_w<1m>U/~#F *3_xX'mU~*gYz(<^Zg[=0l`;~
    Ͻ%܉x>	r :a0Ri{ʦxaApw`ȸ+`!vr۝1
    킺<
    |3>.
    >|iaPb/;ǖߋgG>Èm~9}ݏygß7DŽa+l#7]	DDBWohOD8}F`ʰ\8UG]#z_07Ȁ϶g+_;ϛ|\{|A!m߷fbqpJsR|<o<]`ooo"nh{a}@i܋BψN?ҫ^]	 "]tӖwt܆J|!}31XvW1m"Q~<rZaP+oT_vA-M:s#8
    k!9)p0窩lģw,Giqņ"/_"T?h/EF~ġay˭OwDhI{`z"ve+h.#ϼAcĸ}`0'KsfNûX(C_;l݈4	=VL7T[p0&Nd{R
    E7#q(a]>Ͼv/7)DLpl۔DH8V~<jxz̡x;hx-Qچz|{vi琴e\iDAxg>rZ'wăH$D@"  sQm!ϯa=G*3.<u5JQQRZVdg(wNܽjH;c2q-JQA<(E%
    _o]/dm?u^:U2*)Co{Zi3{։[*m[I~rd~2o'͇}W*+?Dݬ`cJ~~R^Y-򵵵k{s1Skں$8d++qpW<+gmUu8%VV*ԖҲR%~e1i$nvT1G6#iJy^_n+%7T^j(畞)9i7$g]P~	}(%5-"-/;S+^USxN3D|8]14)
    gb*Uj
    RQ╃\[pFٯ'/TY揔)<ը}GوT<uLS=	㕔0m@u	ymV;UգPbGWj=S%zB%g0>5J;(|])SZnT߰BS]2֧*55JYBcbIqQjƪ"c9V+>urCS*[IRg(ޓnW۔MJ΅bB
    ʜ{^QD״)Ҕf,7U	{xNX~^`:뫔EٹeJzab0)%)	=7ެpUK)RP<{e(͊R}w2הc3N(]i|~ZoyA2ɚnS}H/S͵ʚ)C>4XyʒI<:*E9׏V|k_UK{S,wSҖzaSܬ$AItr\ؠ457)5Օ^=uPEzvQmضOW*kRFON2	$D@" H$\r6`hiDܔ[܆W^ymMصi/G{ݔY+؈SUZ)Do;
    +PNtV4iw
    O}
    vHĨm@HW�'wn CfvPgϞAr4ә_+P3|__UgpO!]$/IGyWlҭ:^O7oيYEd̀duvPF0nrL#Vn"{b1hhrLۥw__4
    ˀ;m;޵gU˺,:}�u"h'& w/'KSv3gdg!Ķ}oǃ\V6tk/{#\^F{H@PXB|we_t
    sZmo<#m%hhAȤOWjqQ!MDr~~{|x3~]X-;
    sQAGhOʼnR`ϝw!mc*p6v%*d7G0I;1t\y<>(-oG>g7o<rHw`X@G#!!8͍1?ctakLH 
    2rRPYHŋg4;- z_.SoıDoPny|ƆatWOO[DzLڍV<h.n@|Uq<i'M>m6t 
    pB3rCWԀQĸu..xP~!B:2юw[_KbPhp5x{x-JH?D@" H$>w%5m#'cF&PAB8{d[6\/ލp">-$d*5 h0!qn{C|ږ{ϐ+6"s6tі>ik5Ye3o7#SF{eٖV[[;"w;-mxꓣ
    N6mЇQ>MPv.H$=[wi#VDA%466�.$zyfj.,Fx:*hJV	6½(K`7i̹o&R,Ă#..-d={TG‰۰y|[~{
    "ocm>AW\hv|zz!f@XR]Z7F4@u4U0q2vrΦDBmm~(>JIE6
    ff?l!~5sGW[;{2R6'he}ƣ={@U'f
    ,Lmh6=nWBA\ԓt;ѱ7>W1pbbK/,v;2:2CwG[d)m݂GbCg:&|҇�;γWzzj-Ci~mjl\B^d}Z\ [cə9{6(b#bngӕ&6$v릅f#1@6X0|wCG
    8ⓗ7W@+tL<w
    ogzhrvDik<#MdWh_#QtWD@" H$_Ktg
    ɤ	lT:08y0E(g5S2ﺐwӱ\8©2J;%j-5@0޺3,[8=ȸZ5);W+ RdK"g6F=|g_{b̠4!b8yBvD(`[Ro',i&>R_t\
    f�b;8mK"aط:\9<z1a2j#:{aZ�O%m%
    (/s#gX"%f<EgcTǕ#go̺ҪfI,;{!~sCĆ4<d9)ŖWuNEws9go/}F(L9)p
    <&Z֥Y|
    lMhVT{#\u#H4*+h21֤ofmw"027!dAxfT=O0cۛ]X
    㦣h*ѳcz| N3^}B1pݷ3y4͛Sz"?휠:nO6eL)(UبDfO6~GQ3Pu1j,3`it�huA~x2X]ӀF¥<L?_Ag<-FNJ9mejLM^@B=qb^m4<ɺH:!d:ݒJCȀjHJlRYH$D@" H\kڶFsiiA9+|7鋤n遧\p
    K“+_Y#ZHYu
    3V
    imO4m\I.!M&eΥKu̸y)']{7c$^}:|3dA+^~z˷^?
    <!ieO3:bH=
    eHpjŚoAgRrL䀷5dm2+a~8}w퇝x'EElzwJMG%T5ctB">}~ۖ,EKi?RuUx5qnLE'io:U'^,*s5Drh}oDaľdދV5	%CV&3(4t`h2Vfln@`aa2Ŧc[{'oI}^s{	O)$ږOXkTK`r8cë㮓ywངWk&FA:~T^Mwq+_FUdځ8]'^?ftLӻEs1ЂMYFN*)-#~cЧG)\Mniǽ d
    LIFҾw@'BBP3<X0`QxǏ1nL<ʛ&?YO`^}8T&p/{Fc*Q*z
    N+apȧu8>Qx!n0vGёoy;
    Jp/1+"U_~cŇ9S0
    *?&@<t
    })<}݁Wn[sU5"ǨmchgJ`s=Yq1ixUȱz1:H<#H$D@" !@+fe\qL=3iBEhrt9'xa0[7$$&AY'*)�GinJA|(ZkFdlDt}`>݄&9gSIV9�K~C/y,{p<9ړP1a
    G^]LvW=>CǓߠp=68!ChZp	Ţg@m[rK7:FãQ%0` }UC5?Nb։o7 \jU5 ~kUZr!{vA~i#&Aua&v>@.ig;xGV{w?O1`@xRi%ࡣ%yѴ
    =~TSd^hAZg!brdݿ,G#A6
    y`Gf^1G8<�.hjg]AfdÀ'cPI'#dU-4apXr3Sk>4&	1pm,m)swݎƨ357tF" i{
    -pF|@끢T`-w#}NQ
    
    
    ե8x$z
     rvds-]1j(Dt&7wzC8p4\}1adtrqmiND<{xp7prpsH6ɥ`߄dAm+#Mػc;%Og7GqrHOA9eXN/Fs}5Ә	'IzΞ>}Vݼ0ppuq)¸	~!5j7߽Cq	¹?{H!Q4"y.Զc~K!8rdA&M�zw=C"�t6#H$D@" +#1A7jtrދ�TN<>/-ʢE-.cΦ?sLw.]+s3di==B]q\-Z	=Ev`u1aYFFEYd\u1@/GeTڤO21$X2&3ڊC;Z>^^OE?hVt巐c̠K1<ZլlLVM)¢z9\^{֮L-֜_T.s~eo@u-i*H$D@" k"p-}ds3kZ^#ed@<S.|,Yw@OuΤ˻LV9Cߺ>MEJU,j2*'?lg|m:KZ^A?U#B!2vT/׺M"i-Le3TRa4U^SeFR
    '!4a0ʱs@Y>4E"|GiziҌ-ku	,(jbQVvxS~Y?M9Z֯Ƙ5Z.
    zS6˺jhrIoF0KW렗e&%D@" H$5..5
    fbc?69.H>߫@76kzf*nB5I6-^gJi"EkDY#1emYNgYJYMWk4ݬZ~x~dhyMy:‹ta{\V+Cҵ$n,_e&՘J]6h׋3dNtnORXե3&yXi:9,ҧiDQ&_ίUqM%2^顥[xqq.4\XuiztD@" H$D/t�V+˶E1!bctL@4/Jf#_ofhq<2'g4Χ'LE;ѽhֿi16;L+N=lD@" H$Dߋe	:CR&Fq{)#?s uȥ0j{Q|GnϷKJm8#NI`](I$D@" H$i.KYB9 x9S*r+Z n>ljE䥧T"d
    M%
    
    ehNqd*m*K[%[LrIXx᲋IG#-+a/T2<N U#¿:7X74.cօW-
    i�+/z0}D&]  [jhDžHB3Y
    =`ڪr䑅oؓ{ުf ߼!])pv\deMA޽tD]WufGɗ4Zqpn,CE閺.0~zƌ9\V'?GKS Wՙ	?¯0ae_gGQ-'
    9r+KgV=#'`˜pэAMW.?վWʫQq\Z=,,[ANF** =tMKacrEOsq'(M#_JjNZ^]{IqlBD@" H$D@" HȦq?uݰ/6-8y�bnCN>ͮ:
    cJ(H+AOo5"`MdlLr@.A%1LL۸ԙa"p%Z5h:]V_n8JL>ۡB__Aҁ1Xj%wl-xՕ8c18h'_b͋0;߭~WǗߊ&",m9}ǡS()o==(am8o32#݃=]k,XS
    J+v|6`"z̴>a2gc'Lm
    ppZTO=N|w,WxITśvC]l+"N[R'Oɸ4a{<QqLzu]kUfG}jjܟ/Y5Iqݣoe1x3Z?ULQ}lc9cʤ34=[=$ݍ:͢ H$D@" ?@]C}E!_z^8s#|F>u:_F[{u_Ow!	q݃hV]E,#Uhm5A!ApԴ2ZUY{'gPTRA0BVT;w3
    5ȽP;'7Í||Vl+**H>()O ds@qA*H;$`dL򈀴6|77
    Nj57FU'C]e)r.a pʹasbzL"QvTzs#0e"v3^1&pu7h<}qMkahxI쉦FxzmFm.57Ԡ]]\TC:٫S8WT֠4/΄_!T.!,J+Pn+7ښQYC>}0tʵhrdԭH=uO/)cי|P٣Ple8kG>]PVۄN4>v䢲 
    W|'('?DPJcnNhޙ3X_v)n"lAVdg!a䳝vVbuPWC<MTxpt14R<(v
    3OAmuil7MRqD/bGS#@MU]]PRXv[qsE4aS	;gxp36v+N,Hvk3Qo__^f(+eڪ
    4�_Ғ](#aԟܶ6=tp!]hɋD@" H$D@"!QD$aaa3j[SOŒWb۠T٫{>$D",hڏ^۱H=y/i6gctCP=�j1DgXDNALy<v=O?z(
    %e߼9mwLJk^/|CBpxǏyj<tup&bɫDd&ۮB};B#{^L
    |U;ö-o 9=a
    mp1޳abRG={Ub0fX"|@V݈/_;*{PCJ& HHP@D
    " ^C J*)3{')>יݝ9sf;qT<:Aa}}Q'0didW	yx$DbNwh\	Q0!װzvd)>=N4LlW_z	v}i?}^'~;ڍ"po5z2&=>Znzu|-Wq[֥rfc
    z%g3$/͚b/asi#9Xw&
    [.¬2q 2v�o>6cxn}x{O'ɀ؎q~rakHoޘIU)qQ8]CA2~]
    ;Ů~X'
    ƥp*=xcqF:z
    /~3~.(tm1
    /g܌<qhҴ!Rn\^Sp-x݅X5Gv?EKp+ůΟ4N>GޅX	kWO>VlOE,,%h
    a~vz^}u#ƽIp/Ŧı9Λl2ւrg>o̫ȰQE@PE@PȰh+R>KYsW_~QkD_miӅ@R
    KZbrsxp~agwzDK+guu5ZKMMlY)#dߟ8LC#KMbiڍ37kRӴ'k7bkOYtfDKYKP)ڙmAn.`Тi;v29Ys>g$i.\'iֲI8;Y{{Cvk]Т.&쩽Z-Wg$\Ӧ覽hQcЯk/~;++@/hwJ3#zjJrS:j7y+-)<+ǵڞ3_;>}EQzzjvۘ"mj|$d\qux>}-K/_u_;p*RKy]7.mгYM=_C9:6+vk66('E{	4;h'NRo^TOZIqf+ZS;V
    qҦ꫽pMnߊ֦nhVZ}<sڅ7{3צD)EՒA{UZl--V+PB7i:]|A{uPmZlr;=Z"ŧKDm_9,Ԣ{~ϛE
    Rj;1Dvio~BߴL</_<E]ҎVCtD_?U,-$c-.)Y;gJKiB
    cn,ֲ
    dj۶2shMj
    Q8G6L-')RMږ˗/k,Ҭh#t
    3ⴱ=kk-ݤJԛQ}jGWƐlfcڍIBkL9E@PE@PE@	ȁJ}I-K^AUcx9X"oyfJZ||w(6؃ܼ\\
    _bx)<e4=~3	iI1"#Kx�G~cת3#|ǫԙ媃jX>>H3i㱼8zk	kz!FONS!;w-7�z6aCL+9uěس02og(;fÉFj]b+/bP6";Oɀ	8qh>$=u	OHCHhFsR|6|mLwPظ6e/uQl~OD3KqoeKS`Qxĺoy#5VX
    MSD7B|;nZk냔,FAN?[dhlw"FchkD~V
    .k7b.!’ٳ0f@eq%m
    GU
    
    h݅fB_;},߆ôZ>S^ˈhz4iv6h/oxg	Zf	!S3cl鱧(|cR7Ȼ[6A:{ލ�صi^}c!0N0d2
    vf6o]F=,~z˚hǰ.xl`JgցpQЬ"	2gwڊiTHuF;A׀_.8#8Z(A}ZfF=HO
    �zo`xd2O :.hn<?u2:5	dMⅩ=ޣ!"BѾqbo]e\9(}
    kx|`kZ=W!wA9E@PE@PE@HhU'\LkcGbx9xwg|6CsDmбp0#mi+4.|07DkѬUYEd%ӵsv#ȿզukf+E.-aC늓bq31
    S9P炣}Y.~
    a8E`Hg||#ri0lh24hqVhڼ%wD&dl\uvdY]n5ΥHIГm0?g8,iu|}hi
    +oR{ZtwHHGui9
    ԱqZI&4
     |dJJiy+~*7\dmR_Fh*?sncŊֺ>,`oW·;{xB;I^ԍC$!:6	]3뮭<&e&7Efma-fG{Gb*]>u&7kg]L
    n6 D) }Vvb-4lL*7[+).vB$omcGj71hAi6mށe^gz竈nJmrb
    #SWߚ?pZˑ+Zو~
    ٥Xf=B`O;n.^;?tW9.ZdgQ&+0ޮ>řvq!6GOF4("("'Pz2vg.,(DvaOÎpbQ<vc΁61
    ˏÍ!ydp|,t<\LLYКlgW|e/	?ڑے
    R2plpR:ZƨFgYf!@z PX2_^+*1`ttMC<xnq.v,/|3f=5BDw*#g=sdID^<tEқF
    tn8ÉBvd~p޵垇(#On
    Ƽ-pg}p}Oߡ޽ _YOƞ
    F]ByXn�lLg2
    73vM,IƎ6CKF-;fANjM#p8meLesH1#ϿC&,^Rn\D5d4"N.''fP~n'9<[Qݐo9FZoKYю	d wF/mf(ۨnh9\Ti|r>8ɚBÊ:/7:rԧw$+/Nc"}}=G'RlA:Xz=6:N߈=Cɠyg~,oE[Z[":xq>^}e㱶?9{ڠx4ojCC!A3]F-zzWܤ(."("(<[W`SS1ehڨ19a͈Ds;s&`YDF3͓mŦ-[вvK#yYѰ2N4|ۙO^h{!
    	{ݙmpߣSCM"7PL#ҥ<w?]D:OGϑYHZ94V6x6Q@05U}`@FXD33A}x[me;Qg<0$n
    hwd
    KÐ-;̑~x4wp>~jcm'Es]-G.aLtj'/Ш4D2f?4bMť-
    L-3�u'ud	~+"i'A̜0L}]
    nM埈!bˬg+<<}g#ԯ]A4j~"BhZTm\O{G¦ϡ(-#G}Hp~yp4j-	ݦ84B3.&͝==K&Wl+98~5L?w(lsEbm'ӐEElKh?1.c1ܼ}زq2a%r6ؔPJF=I˚@#qgG
    ۺm(ڻ}`0:)ش "Gm=x-]#w4	`ͨ@Kȅ~t¨ǧ⣹DnzC: 3>!mvm'/O#CBQE@PE@P^&WeɐB,:*)1Y7G}ذ(\}0|P_4kڌP1Ÿal:SzX
    \@݆~hL+BM>q?4jw:'N|GNF̭h۹+ڶhHGK{p1"
    =У{w{ '
    3OϏHpa'£~壡|wHm:'<5
    ߁ڭ־)lh}_mmAbM[H7eNx9wP_O�Ղ+D_06kmع6p󩋎;Ÿts]л
    [ؽo?N:R0ަVOQVMZ<EuhzW4ClZ6kDӿu#27m	g~`x=i4T?Mէ#|еqFp	];N4`R4C�ꮔq=:ݻV:Kh䚇mv܅Ȣ:wZ]	m4#-Ղq+<(Bx݆4ez":-(kר5&ϙtKZg@4kPVB|k	ڔ:iVnU/!^2<Xit͔ahD]H4MQ^8n_^(z7B7AC(!iZ^n4TQryt6BX Y,ۙصs7;T8
    mu�CQ'bu
    ZsVti��@�IDAT!ui梬JtX(;b~gX;yδD:P]Olz�~,L߂xߋ:P[#j@/ãnE@PE@Ph0x+6 տuͦƴHqvÝ
    ݱW[{14zA^hB<벹XeXMyX*:R~y3#4s)ӥ+ǧN
    D)JLfMQ~O
    مv3
    ULT{q+'/7XC+2ͷ֫[цltZ;N+ɬ1M;fV_Cid˳M'bЖ5VgݬMc8w\;2<zo`MȕQ\�wVPSVseiq'N	21u("("(CdqL_iH㻦L?k*3OGgûܸ,"kb陆Wuϣκ&/dj>ę@}yU?­u
    GV;;٨Xwj,WHnOտSs>7Iۯg("("	Л25h٨l؈|_#6599\#e392"7&:7&t07
    zM~XFIo)/tA8\~(#DI/#*swS,MtaQ^j9LW^M,TH[eOpHii8?KW]ZR'㰲Je,4*֕L+_g߄uU8emUœq*nL4,<eD<3Y=LrErVe[1Qi_E@PE@PEIȇ?nU>x3ʍ 6x~Ylx?6,t\gvXNp9 z*d
    W)kdiCy=<ywrJD*n7҃+UDGzwY,L)"("(+
    tahT4"Rj8ҩ)Z�?CyG٨T*UWUOs7Jy4OWXt}5ɚX<s5{T.GŶo.U/yWnܩA)"("(U5蜓|ڸ*/@ZFZnn1Ɔc_be<jXg|(xΦNJ褭h4ݕ|Fq$P]ݨ5QQf\`WUe~Ƶ%ŅHII\us]UT`夫Xf+ss
    ngeYII<roFlve?H܂"{>]QbogFy>].|/7r2W_qy~E>eI<k4KmYdz͚,ofZj*`�O2Rxc^e?1k񙈠#z
    :X5D_S.տڷmMkیL_1iG*m.b<\>Uat]z
    J,/aY$WzMY\*(H}2.HYuUE@PE@P@砋Oql|RxcvcǢSU~r\TC@	d]'sMa$(dXAn&1:ZtTUfZ1#CK
    *!ٰS1“_Yj<3vG_8=gna!ʅ;gb0x]\xu΋w<iMǦI>s@9tJDǍ锗rnK."Ƽq6/ƜLJo;1:v/)Ė?GG.C̥
     !!MsA>}}N4%|;S~="VG6S6`h𶷮Xxޝ$ʍt],Dٌ?x氢\,56)c{]U#6V>.S^=׶`⏄F
    #6ݘ4a!~7q@|ɶ!A7f]\8vBNU[WW~'_<vyZc`׆8y3Ñ|*r#!W]>jxt1gYSgeُaW2S^PE@PE@@:G0~VL$Vgecy{:?E%BI1MVmmty94M9(%YVQ[XhghF-iچۢRQ\lmh:>
    Gݍ1Ĥ&tF[䤯ќF1rr(0+8884tcFCnNŸN~b|Oȧ aCFeuct	ϢW^pRD݋-鮸gWxi艇 _NEf΁-`gC)2+aM\y.ή Ġ*GCqq1Q_@Fi8ޖ`Y/&c؆@嵒uRR$FTNQw:dY,v:~9.⁻c&1@}Ѯ`H:_/`/g\9s{Af5^|z|:[YF7bt&x<,uWl#QF嫈AR;,uO r튎+E1|o ^{aim7WgcywboeiCǠ91Fa�/kNp=1۷q<ڤsXNN8欐ڼ8ꎊ#g/>;Yrybޒ򧿃.h͕|T)o5S\ xťPl_n;YYpcy6K\J(}'#/efU(Ңiʷ迢=>b:RUpbOt=s,车L?奘έϢwXw}kvT'Q9(/VT
    Yl\w:Kz}؈aFJՏ"("("'TkK]@6hּzŹ4	))˹BFm͏hQ<:;ZOaak:Ԅh셳7aT2}Pp;|%tmv,-aoMBqV}9Jku.Z-~H<f>1Jsht75>HK3P\f=1'g_U?.º]GAl^͚ၠyF͖=~Ydfq0zpwXnX "oi"
    ?|	2AHhG`Yt3ڰ-F/ڷ(]`ukߪ?P
    O9 C5c|BµXhD'V`c@?1G̿Cl9x!(qq[c^q~!/8AqF0|z�c@#BJ$WB3fDH#_6C-O:c
    e	G}WE}W8s%{뗄v
    }9~h}_74i
    e*Ѳ}kd$S1N`׉kxttj[@gwУm#a&\’idQxp 8�V.A||m3ry<cMM儸,i9b8S`UӟP"[l{J]ģllzj#4~X6.ѸL>ǻd/]q\E?bĹܩv^o!:"¸@c}XR'gĜ;0噧)ذ'9Acc#IEYN
    eꨲı=al'(,[Θ0e*$~[o}
    ߰0Q'Wރ1jx:vR'M&KŒ 1e	|j*{p8]파gGb<~&h^kL>>n4{8{gQ'yw?)qR$3/߀wȃ#on[]s1m#wtӦ~xbX̐c6pT"}f>Й{7cѣr"("(" ̀jyĭFVu8\['{g%aˎhy�ZǑkѥ#68ڏ{iïcI#_W|)EΝPOyWi3xmH"iͲ/M#n3|YL8>'b9[ǼG=Υ٫1~\,
    j̬,]=�<U]j<ݩ"
    Â7qCbY3ۏ3^o._9r۽`	{ޝѴe3ԫ�[Gΰ}qEZgg�VݥkI
    ȸyv̛O~:*7oLŢ@7g:<l
    iMvЫpg[I۞;o@o )ƑiЧ31בZEQF,x>b-kcot	XړX7mSC�.7DGHBAW˧1dLqNdh[굛
    h /G[Z̥_G+֊1l<>W?)ׅ5:Y,=jahtjx)Huj|/N{ߎ[MU@-8n$"s0xp™[p
    {mnhت
    Cր˾G๹/:|l#bP;\<Oԉ0` gR^_Eo^MK5h}Rc`ڔIq2z{�mb1MEm9l{/~D#KMyx<5?^F<w^{L{ێ8WA<g%`q^|
    JЯg7LǴyq1ft\Kepv3f3##<vHםu+2>z=ObΚҬ}~s}B#ڷo]	çxw1xf8z97Ə#j]i`|a+1d’'V%X[X}6_}o6)>B6:2ۏF߼^.PwQ?"("(rׯֵa_=}fpy!44^Z~dlixB|D<{6i3@Vu`	2^@ܑ"8bshlE{K:
     F`7x~xH6D+ڤFl<rngՏ֩(?鷢P4	A-Шe!EKS>4}+"_yAx:$h3n}ž?~ԉb"ݨi=fO:"%z7#U.nyo([~F"Ҳ+լ
    /D9=c'SC]1yL_ysb,#v@ӶH#+bFL{g7?thW^Ell*JaBxYVK,CԱmXy?u`vm|F<zR'gE\M6O}]™6cQ� 7n4əSij?`($}8&TmlQ/SA]1gG=shSF0x{xj(2@ʠשC#YXa:6>A3/L!ybYY4zOhunWb9;:7'
    )Xl(&][6/W}Dzaei1iÆ(lvAiga.u>yьb209>3Nykk3s&C%iggLB(lG{}=[|	>1Qqԙc|Lz`J3ex	2iEmL$V[h&MZ-.7oҒ\Y"_`4eKa�zC0o0ܠA/(% )q7yAԒ׭QxA-/(ĩH	k;p|<6Љ\5e(:>6⮜CqeQ7Eſ‘6tD]ԷCZcixƁ8"PsIԯ"("("PL?>�,W.!:.Wm>
    C`W7R2JhnG7ᏮCmCc`ҥ7nA5-lغFP`׶xjP87.].RExcסS5-N۾qSn;cP@dLZB#'#Ku1ψGƌ:hۨ6-DLrȋ[~CF>:
    '.AK#ζA4>
    ׬7.ĩ/;[ѺQ2,ɣJxd	LkplaNnp ßebDdZOu�;7Lb;
    .B'z
    vQyh4; <L}Cpi٨Nj-]Z_U[\nKgǢ]aٱ	`n2K
    4
    ,(-dIz9~y]3;IOq.D(3M*+ΎG-mh?c4CjWӯ#m^g̿3zؠ#Np0.?,_€Vn5݁F2dxu)'vgCoe_)7/cMe,XUW޴N/PQh-w!
    PXkr̥BD]0:_?@4PI`,B	#bL=;B~
    Թ+.
    ;#k^A[Q=wZXs?bo@U+i`{Nrzފ=9#Q+�'?Fvn.�;߷X|NKae`bg\vۋzs?݆֭I)8s|?Fzu}Cvܻ7}a%oH{4ڹ3|U֢UE@PE@P P:ɱ<~]̞,\YѨ-YiY}v
    lJX&UnF~im8}tQ0oֺ{?x/]&\�o5clr}+ṿœC�lL)#emup0^0{zS<1sM{/=5T|df#q70/aCf'rltFw`goq"*3sM񈽍#oCִf-(6}ǚ6swMh	;$Cax;XҚBdPZ$HI~MG|@k؈߮Gpa^l0Yog'FoG^ҍ2,h^OVC
    ;jB%quĎ7rwsF>xbKxyĖ0yL~d8[ݥǰ̪Un\r;g/bel"!:E4Fh|4mgGh4x%qNhR\7bct+KgaPGK�x&# `oW0[htgȊH$FgMMxAeGhB"o*HR[M4CnR'EGmwh96 h26D̚+Ρ2Guhc4u	ۼq(
    kgCƹi_Sfg;d'^ħ}0kZr,u]Sg'EqJsE0'ڏOX	k7Xg#h^
    >
    o2j覆+>k~fu8}8
    =u4h	5X%?,BRue,쨛:0}y'\_ΛKr4{닗R۷写BQE@PE@P�yWY
    vyYi8A1ʎ
    yo(ƉX2hM9s5v+˾y{Z=fkCO) Һ1nހ.9M}C`>FC}Ɵބ&<rΒ>X 1>q	mf<3n.Jxtl\];|}+4]ޝyNWp}Qk0Fdl&# q|pム04կ/,>{hnrrNڍ""yaWq!D^B{׷]N
    vO;y4.+CulȨmD6}W{gA39Xp!M%Sv6^2v\p.>117s-6lRwwȖT+)7J»c@ӕ]GNHF,;pGFhqܲSo_4O]C0n<0E;ػy%Z~�/|9C;uS]e]ŮຎR&fi@ 7~	6Ys~ܸ7
    -ޓdY#;2zDdT>](uC=S_ÑSE;9Li'ѫG/<<&QO–KTz*6SFr,%=|g`45$]GqP+ȅ&lJpZ~[z#ZB[QdX܆wmC>̳Z㐔TSiKQ 6x:@'-= ;
    t.M"em6[2leNnwY2S|gїrr/'^%9NޡwW4k&.CG:Bg`=<:_ARb<ڈU߿ؔLc37L;Or"("(!`2*UJ;n.vWi@#mܾCHa$]GR#9h`e@_#c(﷍(Gzk۩zYpY-ܰ"?Gliw@Xkظ$n Qڴ
    BpL!^m;0hJeNѯng<<r ܝu"Zz4e|?܉IŘcz(B^`>;A,֯]אڹ9<\f%Yhݺ5",Z
    +D4OʹV@Mw
    fuzVz2hTcV%�Noq%6BCid4mi?FX?gu)<kե%sMSydN7~8ZS턶tv]Lbf6iqO24nf ,[Oў!eui.NMA
    uhG1U쏦uChDSxf_9kXi7&Z	ӵg$JszL3Sigq;tމBBqmթ|ݨ
    ehZ/I7-ZЦ1S'TN&4*'V]޵tBN:~Q͘$x7`=y@HKѪq8ux6KhWȸl|폸xVҚE;ڽ<V8l3Niw$h.׹5:`-:se NWZ޼AH?)jB{AG}i@:$kph{5=]KsѼCg{L|$8Z4C?:peD8.,7-9ڵm-dgN
    h߹o#}Ƞݢ#!
    / updezh١MMD
    Vڡ%J͠>f!N_'GAqUm1Wqle1!Qg[�댝1yQٿ;O'Ѧz;:TvT4wKlhvGP7n-`s,g\8w
    ـ
    -E-mZWD}D>FoJԟxR?"("(@DwdgEKThQB:GY*!Ja	qqM~Ad#>y8X(|0,pwB,|}F㗟AdRK. cGomZ/mh/Ϣui4⟑ڹɕE?dA#v4-6AD)jƳeiTq6'*^F
    [t\/Oil
    RS3`ikOOOZ{KǜѨazF\FS
    y<En-)p5:Kޑu2fњ\M[}~<t56	!|dYp?a1jf#\>	>^sGnK<ڎ=xR-wO/:'ei]3mS1:xK#d|'%'#f$yxχ`ycqlye⏁Xzj'ʮшxMs\:Šۏ-
    iLgg3>:6+'s./tQ^jezvQYz&xii<==PNr{wwvs)x$YwѶn{:W[ u䤟/.무nѾ!ƜO3z;ȥi䧐"z(=>Gq9-%-t>ILH@Awϟ:JQJ4]gg'h)gCj>p6d3̌tz3u2S')dS{yy9z[2)+zvm_O_ozGFړhOW7zhʞ_+X<S9E@PE@PE@R=g64Tڇ,-٣<Feo[!X(dBgiWmKzy$ܙ~?yNlo)UEBv`_b#i7G^05qk*q+=s�Yu|N2>_MO%}t1+UaRxUmΘAS2^ɨJfv"edµR]r'^͙:δ.w㘴kWm)tN:̵B>\3'/*ׁh+˟i==%]U;-a̖:S(<͒)"("(5@͎
    Zb69
    r0oS;7PiKi5s9\iNDDp헤|sÃr4U8_yȏ?Y
    TXЕ5BӢrx%O<s<v`y?nݔ^ye|G>G`DQat\A)@><rMHIJ|Y8hD2[(ez3gPA}m4ܨW023:++ꓲN
    'ә-Mgם(Er-zL0Oc#>`׳./uɫ|g䳼VLuI)_g_:d$+NmyZtf+;фwlC{3퍙Ä*twN;˪O'y>([[_%4M4QMz*"("(]?Ju?OcKh<[q2'E@PE@PE@$1%>68ٙ2}]F>`N|H^PE@PE@P],Nb
    QE@PE@PE?@_&("("("*oe(SQE@PE@PE@PEPb)"("("()e82E@PE@PE@PEPb)"("("()e82E@PE@PE@PE)ZiiiMU1`꘴*(OE@PE@PE@P1k5жTⶣ("("("iPZJdUXw4OGd^#u9C.M~$J$Kg_G:M7{;kUy0z'yY<wyϦ2Uq#2U0S]ɽiR?uf^ݽ.S99
    37MW&.=>Wu~|g)oz0Y
    it&90gz_StUt3/iܪd2L^_^eUUpc*cf{*uJN62K}U~2U^^gTe3_UU?/%&?iql*g'&L)k2d|530OizaqtR˸Rj&uƗ5Kys3˛[IUg'䫩+;O<T#Ǘ2*e|y4c.'e̯]uz5st5\F>^M3{&e䳼Hy)','4gI9s2:.Ite|y2'ez6-/gy/}||!*]+	8q6l@PP+EV"("("("P=6KJJDСCn c[P@ʂm@]E@PE@PE@PEf(zuFH_PE@PE@PE@PZa\T=+"("("(@5װոM2qgE@PE@PE@PE=߳\T,E@PE@PE@PE@0'PzVE@PE@PE@P2J"("("("pG~G"("("("PUiUE@PE@PE@P2VE@PE@PE@P@{*"("("(PRŠ"("("(C@WUPE@PE@PE@#@#\JXPE@PE@PE@{(᪴*"("("(wD5Mcgaa!^:<z
    hsU1?GƟ_1'Y"~4Q6]RwCgE+uWyĨ~D݈U+)cB\k?*Wu*}_=\zIW+z7Jӵf[VU)$]\n,P]p-b~.d9UPE@7W,:_TY|rkqUU2̕8kiYD	Ӳ6?͔i\i3T.4#{rU|^UJOxu~︀SUͪxV%ՔrwzgYI\Nꪪ0{Xj%^FW]RNzzĿJm࿗5"("j49-H+))`VVؓ	v}ru鷒q+-6.5X!23Ҭ'T\RTĄDd~>R\Vmu?e
    =et0lməSe~z+g=_&/t#1ܬt'$,[{GަL?X^
    Hȣ4;Kюy&֍$Ԕl~^pVrRR=l,;~Jbxy^ٖ '逍-IΪԥ;89$u+iALId_9y}X[[;ĺd\S}FFy=T"e΄M`(R+%γU4
    Dtw;["
    
    E=Jdǭ\YG#Uܯ,Z	R{'WwN,k`U~&$K
    <Cp�GWʣ3եE@PE@5kw1JtbmACۦuI)]G g9z�N8E85N!<6Ƒ(tY5}dzuv` N#Ί>s2WNjW0Qp N	irGqUSŇq
    ,?XrxdzW<MY9@ltu.g%8q,3n.+xx 4ڶouBP/!;v?,虞quuBz"_A<Soy%18	a^6@RE|G"lG>d]boY>9ŷϒGW3;1mLS~{<h$nZX#0X›G""ԃ7jezc$#N3iD^y7] 	Ym.O<5NBWQ~f},OA&HgErtGιbѺnd}"Sx;7COae'~.:%"oT6긬zN&FfH>y{r3]?cYfbsG+PƷ>/*ЦL{zKKh&%r~:\KHO0q=E]p޹p3Lڵ~�z8&}@\.ݼѩ]Ԯ%I8q39d7 {?b^齓N^	WO^YذbW삈""Ez�	BI=93wnnsٳ3}{v$n7*_V劏y'rg3F6mBQtN7_cZ:մ$oq/{_/>?5lE<c%+xBAt}Q)Io`,1#ޞ^N]`x͉xyFFFFFF@
    "{qT]{P]
    ICY#d#xmJpvLz!rm@^^ZK9XB
    6,>^Oϣ}B3%%R<Ŧ"\QY<tLx2ӄ;"K)r#hgPxeM)`.᪂tr*O]]Af~q{g,כ^
    /?z#<jͧᇝVMBIk!QgP+7GĀ3c>X':4qUz
    Z3+73{Q^[e*<
    Coͷk	%O?+o㚟L e]EA^wSz6~t^,:Tn*(_YpݘgY8Ueg},CO)Tx\]i7nۺE;葶'>&wuNqaǺ=x{<`k~��@�IDATUHQ)8_Q^pkfnNxàV|IJC%Q?(/G]ճ~ziF:3qc$WӞ
    7B_IT3jKE*/T>$'ơYb{pOG64jplK1sDюpŗ�a҃8ԔŴOOoqKٴW\7dөE߁Vz?-
    ibcp\5j
    CGf~D[Z+	JM4I[^.(wOQ).$o(@:lj׀/Gcۘow�}:nR
    zYE%KFFFFFFo@
    9U<5ݧ~*G}w!+BZбɺjdLn%/Wq||jh܁jD B+2Bߩވ`~�Q)VM%233"+i|<
    C~\M-dJGfV6DU-˱>s2f\9LOþGkV+#"ՑHFʫj[ *2|h7>IMCIYԶr^YV nQfTgZ]2ӡ'o=QWU-0i܋Keu
    2@*>2ltYpf(.)c9+uV-Z[җEZZN>RQpPY8|"crsaW $,Qj38@uM1ہ|؆XG"N+
    lQٻ'>QaP~9G;u^Fƛ%˱Z\ڄ/ê,hM%*\Iݍ[XPQRR]M�pz&jU(<8,*	eqKݼ؞RVTx/A5pUv{YT0Jr󑖚
    ێwMdS<	pz
    +ƣ͸%<&.xCӧ@}lb4İ><ngX@h0"0;ey"^e<R:Ȉ$ȄOoaF6Ż8|BR.yhW{ðzGalk	) -9IYQR!;],gjLeEAaYA~82*DjA"4KBAVjE*+þ݇)'$,m:4GMJLGwK.
    G^e<<rWa"G0-5hު=:o&Pt|)sw
    Ms(hާ8'&if|N/މ>1m"<lv-G y*?ڂOfǹNG[R{sƽ4!V.x~߆ϧF.m<ڵG
    Xqֱ}{rr`XSY=w p"cбcGcՕ8"}>hޢ%IWwcw+,9m7ԇN&fYQvLF!wE^J]h
    {L(!p(	8)a<RˣX9<%CqLDr֥*2G!ݺv">V>yF
    EWb)xؾɣ
    llllll1p8Ϊ,n篳-碭X=K1k8=}(GE*o=t~}ױ友jM k3vPbwZ{^5_m)|-G5[uS{96V=϶a!, }u*3}aUHe9էHc}VY:zdhiXs1VﶜIpg0Nhdkp$^YW4r6ZfxB?멗Y??Rz΅|sMWurhq^
    |+sv^:v:Y\S4~cPvW5WhKl:<,wʒMVF>+.WlՕ[_|0*/nZՉz+6@skݺ<ll55꾲 zTZP{6.n;[o}WRl^6t}k=*ժ6j_ʹ:9떳?nuY,bMd=Y?<ȿ'[Ǐ&NXn-эיˬs1=k*?-b{\xzVʁgDzuXdydu=^:m==ru0K]]e>.Z楨(mF]>?GuI8krš47xoߟg=몫'[G+۶Ywc#kLEqU{jiBk]E*=8X/2y,M=Y3=kZɩ;|n:3Yַ-Kʚ6vu^+[?fuY>y'FY}X_MeI?dM|nuRz^^~f7]׍ƙl.e|XWmWYo?9\|egTf,^g9zJn
    =sO<ڝM†|g:ثss|lY\xVFIFKٛOOZ爢u=4ROtJ}Yv>~SZ)uHK^uLpэ֒u;[VFkc7u0X3gBZ.;}5[ЦzxSVzVJy`h.eoXkw>{W۬{VO3S	oTG|3)a7A}}OZkY&R1ciL2q쫍Y]F<V*Kr0eX|C L[Lgqύ'Wc;`ʕ7{<pPI^aW<)ǟ~G^|Oe6|ӏqٝu\4 h|[xwX|7N"
    ZyO|Waix+q1n~m/[4#&C\xgXt	kEJz^ŝMgQO!S=]x_9ߌ-<Rp1x[rRc|
    Xis#m_
    &6ko`.WY[[~#b̨xWU>JUq	I)Ŀnό~}=ջ(Ț];q}1^yBpt<cX
    ~dĽ7<On8-س/a+M\8!cfC	yBYq-,q\3Ioucw_^4֤ج6{ϐ+q*7yɧ_8cF'-W߉i3fW<|5*ȡKP:-9ť
    UWEfK˰%9q=o\oƪ_ýOE,<sر+I^ſ܀u+n;Ao5^|s
    اL"X
    r}T{WdW7aӦC*mYs_]p7ɑb?/.ᮎG`@dkdVWop^5ߔܖO81iO2>R|Kɸ�&cp%,T:ԅ:xs+,(qo(wf$oШ.~ƃon5
    ޽#ۢHBWUեXb(%Ѷ8m�,k,':G@"؂ZWQ)_^Y_
    A:zq>ZJس'7i3E7`PWkqŨwzD-xb์9�]h`7\?h(6#8\	vn"!Yy8vKDSvpG*V*#`)xϐojO/ܸVM)2kxwuq1pH|5sw߇)gc媕O1t)X5k6 skW?#bg>]6uex^̦AXڗo8,QWY響ȷ'Fŧ?஺Njء�?{7x#,}_~~^Ɗ*ޠէXZ}gϱg=v|
    #xE'8{sN#So|%8_~
    !lAx_FFFFFF@[܏_8-ș;}z/kgܳb؍›±UcN|mxN1}[PŢs9j*FК0iVO(;}	O|q!^TT񔙢;ݰܺ	)go6oy>'7O)e7JEwubJ}"hzh>.QmuܒLg
    p*C7)t*r9Jr`UG',dž!0#*;D|Jw<
    S?}G{ĩ?sVv)҈-xzWHgp;;GL`ո[n%ocO8뢡8zr0$z+=c)q=OX?a-qMwX>+-][+h\s(>ܓABJ?[wȭ՞܂۱G|"rvвlwY.{aбy̽Ri2>_}{z,;3;9
    \p&|4Yx18o_mw|9?t9h}nKq!.Q$U"
    zѸsMڢ[RXMkHѼZnv(Iԁ}(S3^%
    D<F;O*_Pt)sжe .y}
    PʭvnA:ؕqܐn'cu_	~h'Xi%ATt=rh<1ZBE"Q#NJ<NR̶é0ݸxPgt\2&[yEqb7%/)J<RH;_'0~Tq� i'Gp[C؞jEK-dYD(=#Bz=~B$X{:&ًW_pL':c@2Yؿ~z{᪛|
    hQ{mk}H(A%"2SGƼQ#CZGcMkFVhD*_k~QB٥?oy?GѱM+[|f&8ԩE,˗fˉۙ2?H_tSbce*:7}#e-8a?_/ލYMTzul[wkE-yxqR~죑?hCE6	
    2^s}
    ۷Aic끞jIBbC{j\E@A|>c	Ϣ{(;ӤWTztHd
    3Oj*ۦ8zܒǵ~Wގƾ{X@i_e1K~~[C(yWccWaǿoAK3?ם8"h''EJyT?cF6P-*_[?:c'jZi.-^zr.ԪyQĩΝ+|Z_xxA	[`W!3߿;aV>Chls^*m\9nW0s;XC'l׭JG+WbI_�"x8Z$%(?+\VSpاgK0tBYT&cȤսOe}*roSzkvQԽRDf~QJr-;au(gr3qͫ_H^{NVrDu,e\yd=n6].J@
    IIC,G	PY&7N
    x6}Q[⡻J"[]wށ;nϨP=dVŕ**X9tA?$-}ZWQw&uG}޴W$4,_0?GEP\BR4zx!7LM@Tqyk1u<[TZ
    J݌3JU;ǿ/3AZ
    B}QD9*WXh,&mܱc[m$/
    =18Fy*vSى!roaߨ6_4Uply-DB
    W%}T{vr7H5wvPF۔16*WƏay҈T8;K?"}$!ЛWv%m0ry޼kVj\Q+{ $2*nYexGVrt൒`
    0Y!GP_SAm,#e?~pp2a Z)LzxQ?/$&WSp䰊ElOt3u{̏%9oX<.ΏrgI
    Ucۯ1zb@lmeXdQɷ|z-?lACےf2WK^Wݎ^Z(,ٕwW&x0tTK*w+'#n>(눿+W^]~*+s
    x(:bPܽ7;)tqTϴ\HF#4ڏy)QAZP
    ,8.P ߩ'>IQ$RP,^m$(WNesR͇ٞg$gw9&
    豈ڿ"Z@mצR!&.WT"^<ԃqiP?kb)jG!#ʇbS,sH>Tf븍s'OEbϚ|-@dW(9䍲R-0ÜD3MzunH!Vô`ev>
    8w=6Z~ݰo&B�*lunI3p9s-4u3l˪Js_vS,eY5spEA(nƫ UIq^>*M>7!ğѣE4Huei4IJr לsTnڄs*اv]�"ˣjDi`oplM+/8w3_<ixQx:U.f|̥8
    Ӱ8f1Zu_7ƍ96ǹ4'\M=#,Q攣Z-tܞ]F%O[ƕ|Yŭw^TtX7XǑJuKht(SҺ�Ҹëa[EwFiN#z\@'s;^+r3ʒ<xWO�p{
    Y0r�M吇L[иZ*ҞJ`ɂqҌ1+*PZVEZʬiTQP
    0gpUgS{aTDk_ZXJ=$*_rP92?VrZv-w1R9ҿhSZԡe߶K&!꾡rā(Hz,qctYWMH1N7Yݝȫ;qxʩLveKT_r$Vϩ~(Ʌ 
    mɣģܴ'>7kWc߹h1GENvĜr%ׂ3LOكo~!t?Xa焖mQ}
    &̳/Q
    J݊|cόg*A%$sn2maGЈ?WʹCȔ((i]ZM-qR!Qq=LIxOp,cm
    
    z"ԭ3}3Eα 
    : }'|/qC(FW B4cZCoYڻDSWggąg'Hp\W7ۘұ}pEMt)bKeRY1~({OzUN̤⊠q0k?k@J~Jx*͢~"r]mX01zwL\.VbaC4~S{ r1>jۡoXnMνEjF-C`Rr V-Y1سc3/]"ӂ<9z|GbsA/CBmLeh~J	c־	D766V)kD_
    F6ի1)hے+Z08#e<a@k½Z:al䝈jQhyLS9s@?F!q/bĒ:LonMRɳhig/ŝ~FBUZ2c'�
    nw`*b-⢰g]֝T	Uʣz%fͱwr?Wd⠆ĭ^ݚq>XM{m%V.p`(.
    )V:{1l TJp-gL;%ѱqZÚXk=[9*Ͼ۱]x#(PCCEl(M\^4{36.W8th)-"[(EWeEۍ[E(XJtv۞	h> S&ĄñfՅ?'Ăv8t`s\vEwZX1w39ѢM4{W#u~!
    o*%zk]
    2ؑ;X(whpõ3ơxױR\~4$N8d8)2,Mi1~i+Wp9-gUb  ,D)ܪl4Cm^vm.D~iqT=e/-b~16/]Ή
    +#ߑ=3+׻ѭ{<B˰a^n)]UǁkqF\Vv6-gƒ
    w|SĕHDe˔r:xWw|1ѻ;vXbR2Z~λSw}.m@ճ'jK9v.Q[9Oh^
    OaO3qљZY?R4.9ZQLjr1<^7˷oAYCr�Ghޓ_h"%d-lTE>)ќ,:Q;鳖Y:lUne2wbz'P.?
    w<?Ι!•:KQ<�te?B̳֮D?ٽuI.8sϧ~9q5lc֞jc£Qpfh5+*\GXG<{SߎHv666666,qJ{o]H�MmHI/hwS6,tXvЊmHsK𻏜iR+吶W5/5wv7
    qsQ`ՖDe=y/sC\S98Jww*ޖ?ʴI+2r[#nL'yD:MͶ7;'L[+HYvBT?TZp3~=:^h-\y.ɲq¹�Ya+}ZZ/5iZ˳ƍAW>ykš"s)^o
    ёd]GʭJHrNU4K]/'p/rX7u.XOMeiYZ�KRH15]k=IKc+Zi5wQ"s;^8/Z,u![<mo6nJcR>KdZ-hgoFkUlG>E'+eMbUYRbM{:<^7=̹b9ʚ:S>n::#6*+i<$7z7?ښ4Upђc֥OŹ+5b뗾&Gމ_/.esiϟDGV"|,-Ka;ﯶ*~+{.kuOm&ZE]\c]x+5C5?.!~R#IUR[yo:avZ؋*+jk%\kQQݨiE^s)6k_2츭f|:Z/]e[{Gcsu;ں&%Y?-s|vBϯMu4ϵAa83*5YԈ=	+PUQk-nbðf͜=;ުtf(<Q'y6Jw%3ܙϘ8{m:kemzvVmqií)=eŜrYVJgil+M֮`#`#`#`#`#E~	o{WXƓ;op͇ߴ*Wdo5\]x3$W`vFv1з'U7`o0wj} )&i{=CD/ūQ튽{Q*/~v'< 8@cxE_И^Fr[mtQ:q=μئ`ޢ(n={՚4&T`?ya
    #cz9s 5tŶ1ؿ{;I#otW_| $B"cPxz%tj~+^)u5o?33}r߼
    <~s<:
    1">x՞:N:Ƈ0Ù!~hޓNjgqq%_g@xDȅB
    W9Z4Sg.@)vA\[E@j
    
    k1hަ;>_�A"νi,Fsug>8gk3~tFmM=+|o&\MARsp㬁շGFպὧ	/ASz^bG,Y
    G.NN9ǵ[6pZ|=y@7|Yѝ
    i_vJ'tHAԑW?~KSQHn-#њrӳ_vmi:.^^nɽL()E@D0kGط(:mŵM_:/j%YK=67~!Txa{_}/IwsyC}Xl8zyn~[')-S#;G$DsNŗa}}!øΝоr
    |жBjw8%3f'BFVeSR[V$Ӫ/&>Bbkƒ?rbo|móE|42(TqSؼ~?WUb=Q)x^%+i0,PS/ΐNHC�w@|3kW�lw0dܮM?^L+u4R83G~/^r'E!j9v>l>ک 7.I1ܝ!NV[x+O=='UiCO+bPhi,u7i|	/]Yzo$pE6u8~ܓ;c~~5e4pUȕwq}Ͻ[W`wJ
    + ~.'bd`ҿ?,څD:wAhx8c[`1)W}5hƿ<#~շGp,X"i"ȻEOETˮ0^|
    ~%…"69|>y@B=j;vGԪK/>ED$w
    y!.~I]᛭0w|ZOE'bЀa٥	*<ę"G &SYIP#u<3W\B$PQ\skk偠@ܹE-Up˪mAEoY	'R<^ɻQ35qyJO<++y&ļhp[rj!QVhP%SbG]rXOL!;1'¸1Q>ƳڴN/!Vp+g5?t,RIjnå?eJxUp$r ׮y??YtTʙkD^\8Ҩ1f =-e2F--?uY|7PUB"y3R#BO8Dnƫn	@p:+ggbry6?)yzSA򖩳4`<ٖ33E[�^䵴%%yA@8q�9﫱5]|\LYU?qF~?]>nJ$|y,w<|<?txRnj\aj*G<|y0?1` g=ه9yXAE>,/9gR r_+|H5(+ʵ7҂R}!,aXtQuJq	ލ?cޛ~]ڰ!T{48
    6#c%짬o3&3x&݉đ/'z'fT;rSW!^ޜu32F	5^:Nо'Y]CZbXߞ#% I[J@j	rg~Kf!yɋ@00>ԚFŏ\+}n!AN8q۷m"l]|#^?C_hZ[r0U(" BH&"t2Jx2Š(Չ6o|$~=`Ûx7/bIyEZVSL&V>>EHF:I<Q.Dmd`i+Dq_Q0e`QTUt,B(!`7N/|J…אG{+o]1u�gRz“qgCh>*ܱ
    /^=A
    OZB)*f@LPhT/N3L=8Oq_~ϟS*jhA_~w*ڈ4`J'K]5 `Z_>%2NKߠ/F6C~ɤnIysHAw兼K3@/<y)/Bk*2q$ܔ'Cdlq5\kɇ74Nq0B'/"|ϗ*b_-܅Wb!
    |͔EK_cp? y28Q͕hwv3JA>g&.0%ԿTܩWC/3#ɿLY)7*q~l8Kh(t4ZW'7ԏ:LQIeԏ&de
    nz7|iZ2a025Yx~;r`qLN$oQ~13w(pj~SaM/CYB5؀>y
    	8yLε˗E>x4L\diBzFFFFFFXAׂUa]RC\D=ـyx	woM||M\Wz~لITs|eH L{Msr#|ů3-C5+o&Nc?
    h8,񍿹:ۅK::.Ѥk~Tԑ(,pr%ڵ5=_(jNQ$xFtfGZw%e1<HքK]㊟k:״r LeWTF?*�:X;~<&mؠ>q%QÛkYL:W?g<fF}ȳy /IB	 ~G^G]Mnފ|^*Xowm~:qIh~00tM3yȽ)7vMso<mҤ0W'uQF=&1$ucziWhI=O|Tr^8I	`nQ
    Sq:\09~*o7~'/ۺIZΣYye{(/GXltl՗پ KQl>mN>{1RlVDQ=OEWA>*FoE^o;_?y?C@mAv6M  +[ũ;^q翈�{ý1Em4w3SY?[AT]E\EW)2<  dEo<.m6lllllll?�Nj#`#`#`#`#`#`#`#`#`#`#`#`#pO5_BVlv"\<mj6666666666666	[AKىlllllllllllllN.~r%l/f'8
    Ӧf#`#`#`#`#`#`#`#`#`#`#`#`#<Q*˲Nlpss/jgi#`#`#`#*~FnNsNȟfU+_M+$G<'
    ;lirMI>^0ߍߓM27~>y7i4.<sm7K6mvUTTSNO5v*%Q]_K]]|||pQٳ:t@ppݞniRHOOG.]sMM=S:nܸ-Z@LLN+c7))IS뱩rT%L[ΔK]v}
    
    EUU%F>OOOEǎ6㆗p!wn66666"pE͛#!!/*T,pUFy3jO;#43&8	7W7r=^Z;^	x&̤i,5aw``sQwwW&gԻ!)J5_(OCg3?/q]ɳӉh;&5o$@:QHGC?}뚧gX:ѽ>̵w
    k|oh$LU662߆gCτ^fNtCTT?)gxmʣ>7Nt5aWS.W?sJCCi2'cDf~!ƴqbkͽǣ)q5v<D?M蚤qp
    k꾩D3qդgt#c(5
    +V&gIZ|37N7̽<^Njkܛ8U&g3Z㥕8Mgɧ)ZNj'DN!v6666LNByռ0
    r1&\ٔ_ɣ4&	?ej*?!FXO9օuW&yJs8י'Uc5#x*ԁ7D+;^R��@�IDATK?tk5E˄37GH׳kƑ{ox)‹!%V>Skq7<')o||+++
    #嫯GnI|ONR??D+LJJ[GNzTx*M2JYGI'4G*cFFFF	t)PKE^r//3*1yԪV#׍/w͓΋j+Nv`ZaO*fʩ$B5AC",l[Q8�#a'q-
    ;jQ+Qu9kp:_O{6J~0WӸf*ԓ$l%Ox<xwFc&dE6  @Չr4P.g)M^TXמu8WTkk8Ngw0'zzJۈ`mᯎ~2Sig7~҃?N8Nvgo=g*ܚwH7A	=Cc]-=X#}JIM'w56!dڀQ5i?Ts
    7yLX=/ƧUK]I Aɟ+Ь?><
    ŋjV~ocyIzǘ5_ʻMIyU\>4Du`dF1yI\Yx	4fr/a'rsb+c%Φ4|S!6666W~WAw2/#»k1qLGQOdQ$B$qE$m<VLg^"ɯo/OgYiTL8ҪGtsL3q$˲r"W-˛[W$=9{.^US]xp9';X/O+ZyZ諩BUlP.+5)#o*<¯V|W	ѵ&3Ϯ(LpUOܘLMuť^L<<)u ~Չ�(8FKRu#4/AK:eU`
    ‡+BDUWg8?8M&.#1t*ܑSQ6|�Ҫ(cyݠi*]BKKo
    +RgJ	dFpԙUݩ[O=ҟގBj\vxX'}C4|q*=Lޙp
    /2f~„Ql5NJZ3/ɯeK$o=2 ')K,hrFTl'VqO!^CvTX0)۞WKaW[]^cĩե]8Ai:=Ya!{KMoaVi煎.nZ}(ĹԗIMO6\Ǜ2c#=Yw35Aۘg0LOeu&I7x)t֭`Sa7ʬKY~
    _Vu-8iL#a&oyf
    2e[_Z-,joūBS"
    /z/zRBx)zCj6|g	w-o_mlll^«F;
    otш`?2>r�{RPU玄m:1/+-D5V͋F3/{5w87oiQa%XWԮ!$?yW
    :`DyK$/bJ@-ZEs.gEGb&))<Er3{8?)>}ϛfg e.?xun
    @<%(V'FqY%"O7Ve'Ce1eW^qB}(S0<
    oƙGxbH1YnȁE0Y_BxxiQ?E^Z8{IËt^)SÂ1O7JTjޥI>RNUOφDoRQؕ	^8fQPJUWuBoMWo7
    T|žn?1vAAlx !̜c՗uBUSmE)VΙ[`@,vgԓ*;wwNgrJioQ#O)A͑EE9a瘵>F=mcl,Yp#"|/e_v,xȳ~zݟU@RCuylݎJN8o"q+Ьy+DycS0g[ zwj;f+aj&
    (8
    0
    nwRvQ.uZ6UävkAyq>ҲrÉB}r!
    Aql߹iόEj<ўƯb"CY,h%W06.+uX36^KS8kfZW_tN0=U
    [GuLM;tlǎwW/`80_IF'"ѹSzɨڪrd:JQqcfQ~r
    hbur%y~uamȴ)7Jw#U:x [ۑ1v3R(t_ʤLXx8r$'/(;t7!pMG%ZAR2kcQ(̓ ٹ
     6ѱ'_##!2Ci^LYcVݿ@0)އo~f+оUWĨ؝zunJw?c	c%'<&e]?(+Y1qnb"	K1=CKp6T_YV
    Rwnǡ<xxmNmv0/(|;;}3l#ߋ-bne^Vd5<>gM\j#`#`#`#D^k|Z`j|x_T7&|KEUQ6VΝg}G1,x˔/:(q^0R
    ,]~[_hnz.8[yQ_r3xu+xSot",B'_rp˪Y1P#Qs_'/~p̙?"ݙ
    ET*9 e Mq^3�%Y:w*.CȊٚPFzl㫛B݁O?xS正_Cޗ1G~j>z&.KaB	U\9b{/+.N~YJ
    18_r<ձc<+!X+ALUXҐ?y2g!'5W3x&+ĒuVmOY,
    !SiT:kXJhH(>h!NeK;"YtWꀵ=wszvhy*^qyB|ȏ‰#q._EUwK+R
    cJeTQ7a*"]q|}QVIMY߿i6~q7z8WW
    ~WEҞ\,Ŧw~Cw-ٶA<ǪHU-'*kI_TΝ^TzkLjU'\Քf%QDH;W-ퟅPF1,$ӎ3}UDє_3^징G`mwaz7
    #מť:	IsUT\Lճ%wN]18I?MƤձM;&mpEY)	F3J|W23Sp巢KFD?JK>eǝu^yo3iL$&ĠV=h>Ių#n|k+?͈G\5J^fxwM"ev!$R6ƃq=U?>K;cvA*_-vpGzyoSHkJ'1y\
    w[o{\7?}'|dxd\5|~DM_v{BM\v`H:U?&{/Ƽt_V=QPYj5"K%5?56TIkoLE]y:޽OZ%PXTX_VUK?Bލ|8xxSI�DeC/SICJ~o+Yn蟪T-sR__zW)UyW
    ;9>֣#ۗE'V_VC{a
    ]M%'E
    yzUR7j'Me`ʻ
    =<'Ӊać;\rypsGF\wøl(<y0p]jՔOX2Y,1CKpړg-$?q·llllK#Љp>8SP}3ܙ!gsf<%Fڃg'e8e`/Wk-%DhdFj^*`{vxaYμ8S.Nz -ZɏGvm,4yY>BCD뎽{SP-ѶuKV; ;+zDByQhgR"Qei&	̣ ?)i
    V֭⑗y{chrGEImU`J9pCK!=^bԔ^@ܨpHMގ5秦:ꃛ5GJ0_v
    DwGXtl	#(wPї%AA-Z%!*q~v%rsor>lsMz.̜@bLĞct\ڶm :r+m_Z}pVZ!2,G9ylgHZj(ܳ?dEL	TT"08ImڰFA<^GPh|ܪqyMaj![U#R/8/^yV${ax/wbܤHb{zmk7:iyI3ut,ZU˧rZ:EhD[&Rɥ@~y@v~!ZA6ڊ\/'|ø) h1WBВjضDa|Ng+*,T!59eĐ0HLDt0{s,+a?8Rp)f/뱸^\m2;j*oj!#U"
    ((q=*i65+mh{۲lOei93GideOYs䨾ZG_g>9YǑPҮٞ.8NnhRb̶h՚LoP'hF.<idʅtJkxd:7pC~}WOL(Ǥ)NPL0ޔqjDru鉉-3Yq^WJg(8tFhCG?7>'&$#PṅsNk48Io
    gfv	u\}#$BqE
    j&nf/|wlhޢ)RQ!D$vX;
    :�{;!J\牌# K�g-(E.!|l~b?a8պpu Yr
    2ɕY׺<<E}%^t:Ekbbrlrmddu u"~S^CwG#ΕӠ1\ל29{9?�*D
     !<\s<ܱC]G*�FiG3PzxqjӺq*D 840x:
    JwLF\Jn@[q&Qx!Ypqk222p$8p";<S{w*כxaL&W<XHmܐ8CsoOE\6	OTؗ9qYϛvoLÊ97	՜�Wv9\Oe~א+A(@LLJS̵;aG�}:x+$/5Th2+c5n[xx-u;qڎlvS*kS'W
    lZsEbΏeوMHUs)Wp%4D$h*vlm[|.J�emJYD"2J?z0p.q~ms78Gp1sLa|ZJzexauk>DI{r
    GE7O7;ȡDddJ[-PQ8#짧8px	6
    aloaU˗	Iƾ]ۍnNHϣ弅SoV>»W<3Bi4\ouquݔ
    M6"7D<nuϛ_kb1w'f^|xK}qF;V]z=;~ɈڷX4~17]S
    t4H1*Ƅ_7ve"InQa1q#'fYyCTw<|mWuWāFRJsf}F_GVq|7u;~3vmi׫[WPMԠJy2Vdc/o7>{I0x1w\;Pߓߛi%&[,6+<S?f9
    ccƷ6m6v2oصg;S<-Ԍȋƶ]n\vnN!5;cvշgP{zύC}9}{ ֘Żu[?m4Mysm~F{ؼcol'֭[gٳHLJ4~v7JcźƑÇ[#yX/F?0dҥG5rUu_ğī-?-18urb|>'xv@Dco`2Ȓ1{OF\ng*?oݼزi>2ؽ?طcqkN]̱)et$WѾ}_.\i6&?t~YKú@53f^rR6ų?0auvvcƠ`Q
    ݌9K68Qŏ7at"#>1Xfjظ8@|q0%وqƊیS\mw*l悟QƤX0^5",c[t#/1b4>x'"}黎[c޾ɘ4֚,uhƮqeFߦf,_g$'?o+2H6cF6fo2fc(jHHH464ߠqF$mNgPp4hiVO1Xz릿BK?wSoc]"Դ+ߝnlݼxj	IƯV-JcVql0G+Zg cp_]ȫ?CB%qUUFN0~kD
    0"SG>Y06lbνC96vG06.hj]u13orn8`p^Oa,[Ըu9ׅkg	2]ژ[o7w_s}h?ry#yӦMFd#@k1As%"Y-0>E37o|IF$ڨAfy6Ă	d|h4p3uK1z6ofo,nѯ%)|1eI/Wwh*ǥ`Z$#**Xv3j`,_+\ˏN15!co>rĿv
    ƷV̰q6~ZĸiH+h5b~klLyfш{tL5PhK11{*Fl'fW:s_4z㥗tp2,_X]a}]G~\fxfq~Yg˄Y];/[`o!El{Ǝ	Əܗ_YW޷U{^lawP?E'`׳QYra{%tuIf/i,,^7_[~n^!/K.e!xndlGi8,v.çc77YE<IN'_݄9X|ዸbŏ6\S/`¹gC٘zSc}4AK/#/-<=Czuɴ]x0G08q5zv6%|rѽq˘qк)oXo@aWG44j@DɉLꈒX5
    e:Wot($`}xxͩ^
    _zEe"|p-]7n˰nFYβBܲ=
    /NNfƪ_`xNHKM1ƿkГ0D*
    ?O|ۄ[θbĕ5I;7)õHx8UKҧ3Ͽ4	-M#톣I1xy@p<(˯רFE&w'{@!}^~o:SCmWSÔh	O}L?Z\;b(|QpǠXkeEÕ;bcZ⤈SQG<jRlJuaUZ$?pKc|SGV8oo7`h@@	n{#pKbX^]WKy"YZG۟_ \+O1چ0JD3UOi``�\{,8_Q#m3NSID9Vꢼ8??EcܣS0rhW$ڌG''/÷O݌&f"&!mI1Q*!n*0IԗބgH4,[
    (dJzUG8Ѝl)P!@rJ(w
    JG-Af]9nnİ~q`Z|8sf,r?Cy!<;m|t#nq89d1xd2I+ҳE:莺Yִobޤ;P^^|S^аAS&(E'v�<ZԷħބP|C�Snb#w*u83>
    (<r~7oS8 )f+sX7(8݇W!?BG揯VbyEo(N&s{Ck[aW?b䄧1=t%(^~azvUU9pcZ}pKس)X\7q1$vlHm$z4Lj['):/ڇQU3}1k쎃{7Ȼ̸q:?
    /  ol?1rb4Dm	3RЯK[JkK>7�GCOcƛϠp!z]”w?E{>7IUIObp7>Y'e6Hġ&"0cҫ7:ƆSq�k|E1x0w8}
    WlS<ʾ>GmZ@J1wZ:
    8v/<lSsK{Do[_33u-f;I>bQ{P?jVZ:\^!kQM8iUKt}7Ģybƅjo^t6o'F�?䠌 
    0kO{;:]Z)}|Yo5Kcؼ|6SE;!=›}f:pӅkky	,VlK&!}oщ7{O>݉G/֔q8]Ng:vgb+`dm.2a|oR[?j:9N{SA^`e6gÀ
    60?",נ(oX]˭gu(q;&4dgui-W{P/sKIp.	»AxU^|\.:Q8/&?E+/+7l CP(
    \vN{^%Fcxhcۡgo᎑!Tgq:E9Q>Q<0>e#\-f?}nviVm̓yWUuБzFnš? AQ~֌<' M0v桑mt\iQ![u`;7-;Gq/_P�x)4P=,iz^Iv+>]#(:A܉bÖmXr
    o٘R1C^X{%b&Lݫj3BCZ~^)U+WD0x^P]IuAV~{>7+AX`SQ`;ū,:w^:x
    2хQ<@iEљxhuJ	XvsDe‘")čE0KoXw+'T\gGJz৔nt	RLX:gpXYSrIvi}ÑHޠL>EgY\灗cPԣ:@~q%![bS4 23\"uW>]ғz<6D1֬CSѮ#Mܘ7}<g\~CXT{~~{c5)8t8ݢi+FFPhzԬ訋]iiWn5QDo^\מ}N	
    *;n_vGC	B)9Ux}ĭ,fň+QdxM[Nf'Ś% m'K_ Υ'C<. GCPu@tW+sU2q1Q&Q왺Yض)Gӑc>R3rX!MOq>8‡N"PQk_q,=bTP7|9nT	wynÁ8so8
    ɭ(&~bUgh@,];U$9F@
    ر'uq-}{>OP\K.p[](?CX`>qP
    /߭{6&N
    2Cq:WQĹzL{Oa1!qT~-Z!$>v!R$	KՀV(^.1\t;2H׫`t
    nw?3k.UD<D]FӎK^>=ǧaJ#OmF};5FΝ)D,U@86aT=ILU! =3\oj$bZU	/MMPNOHntFutCٶ1Q
    <xz'-ЩKWx9`RJhB\CQN{꨿q#:^x�kỲ~IgKܪ_wQ�W<E]ˇc(	eb0+UwK.]Т#RMJE7
    Mh|fg*I7~ho4q]TUgs1Ts;bQRdžla࿉DfR%jࡊDsSҼL,]|f>McoKMڌ1WSlPSrװq3to|ta>urQ1{da�{3p֐"Tv'1=W"gr׸
    Ě@srRqd3a.uy�Tvs/%2̲hBpR:x6T8Wn*b<Dvw>z~ߺs,v*7\v!~L#:r$7xVºB0ǐy4˾K7Rߞ͡~EyL\	i 'r|@WUe8@B®L\'865fq)+f.׬{18Pf敡g<sHMw3?&G	)B
    u.<1kelߺɱ47Lǖ	]~mO5YSw&C]9;Tz͙]ztWajru`a*^NlOG.=*[yztZ\r`lSxO\SZ0uR1~c7X-oQ{ =<sb[uW=N<ᢟltɈ+F Сcx4H%Ny@3wx
    %RhZGJ޻(^y!?q-SǒeKZ)7hȞƍ8v6yS8Q5FQ/tuXZ\K]hOQ
    ̽z!zcOzHk9ZSp"F[.u2̟HL
    FbI%%㘘˖Z4qOѻ T9*wCrgqU*$Ę#hP@WN"85ʂ\Z \}-<Vy_^
    c:z:>diWc':ʉ%񓺈7qe4܅Eۿ?@UvrÆ	_)‘ï┇B]
    ؚH~s.'*n[FԘ)D>UoDG_=Uc,D#N8oC+?sIT}Mեq"AYS�f&nCƭT;͛L0jv[?恱O|V~Ů_1Tc	1^Ɲ
    z}<C!"-v3	B(1j&F];Q7pj̱@blnjXuvprRhobPMɴ0
    N*%]3s%a/`,@`:IUuc:=3y5ruqk6miǒ1Ç1w1IMza|xosmED!:jDw'W!XH	cNFyq6MByF]Қq[ЊΜHL1lǂ4`aG‹8(s9zXz522[fhkv#X*4o&72X*
    60`j	ӛV٣_N|ҠvR9c*ہ9I֨o[O%g-`ظqM{j<d7og*6ñª>X#y4FCEm[z\}p9RqkD멲{CĻ5B|LаZRB<Fob!t?'SUxA=[R)nQ3E>e;f^7Kz߮݇ԣ'7XH{SZ#>3^BkW6nM
    {Qe{y.'i O\FZ46T4ks5GJDR*u<h(cܵ}G`h0%n&؍B)牯sqBc'wP!^sFe@^07ɭăzqXZTr?iHqh\}uXt>	>(@Cgc|Ոڶ/)&­ݫ7CJ!Do77U>ٷSЅ\EgJhQQis0w\:M_&0/2PN8'7r->9_%ѿ'
    :!w݊Kɕ%E߻3'&WMih*mxѫGW1K; <
    "UbhPWY6҇y%w;_P_
    ˙׼II@FV72N'yfVwo^8]x8n,-cgK
    Ѷ[6cZףXF!F]{h,	fLT	(5G)
    ^ض87lpJ
    ʡxd@!G
    aE$E"`H{)`5�2ʈZS+@'dIou|dg_M<Q-Z"Usnh�Ǟ#|<ApӖƥKT7(C
    EM]0
    gp!	BlKII䉇234<bݞzZPż'
    xtNYg^_y@P)'nkDfN؟#
    ͞o0*w3}4&
    rqɇU4C<Trb>r37tzD(FB,ĭwF+̵'a}uQC=gdP$<	hQ\vi@Jؐ?:N9`+DuB,͋SCGNȂ<
    "ˈhDqP,_Y8
    wλ
    0.)
    z5W؋O<d<z;'g#DjDz8}L[Y_|Z8YbN`:ј\PP'zHBGPV@b>,f@R2}Ұ_90( c@]iHl8S'lnDGiq`.0M{y5	rIJE1-K;xR׬vW1OByxMs+@ATٱ<C		hA+z&]"\XƓn3I+xDZ$=6-2>An0=DZHIa#}8g/O`Q#&-7+dP`Dzƪ1MUr܅l$y�-F	9^DeP8E謙	URla Bc硹hw7yŕ0Acot3_}>.A"2UDRwnWbA>F
    @߰Y5/~̫ܞWȥHp1;Zjp1	�r(#:POFO-?)+nOkafө
    <jMT±E`q'iZ\-Wg+HK۞NqM~:"M(hĻ{ӴNH7Tg	>J!IJ,ܱ0\cMD-SZ$e޵3In
    7gZjˠux9i)4ϡy=ZwG,Rdҁq19eoQwL_\=;rqoӾ[xvE^Dĺe7ǧ:SG{iz9x97f
    uDr܀9~@9zⱗЦ@7w+QG{솑ֵqw\GY/mqEwMᾷŽ^F&4X{}z8Y˗Œ"\vCYvvuRWd~I;%I)39'imy`7xtU`%߂aPloNAƕ*d\uHLb0ΛT3WEaIEpwL}iLVtXƴ~|Cǽ=C͍|!ŤEDZ	^\Aenq+#GvÑUO[AK;]JqZqE,_a>E+'Wfyo?z6X.z*eA+>>5I&;Nd|#y	EPnN;*W<›^±Nn+IT|b
    NԭGJlY&',HVp,2~I'B;ũ_akѲm('ĩ<g.^v~ڞ\|W[{aԯvr(
    fP!H��@�IDATaO.5FvD/Fٺw!	2$2U<'.ԕЭ)1}&Lxq{:s.6^g4^K_NuOʦFxA}Ϙ+lOqZ$oQي"CQ$9p;c\"#,/v'uPATr3(I1?VWp4/q:s?Dbö]ʵv|M{Uy+֢Y֐YqϺ&>⹉Ixm7m	$[9
    UC$\G^9(3f7]˟yZxÑPGs$8CaXI_C"mչLs(QԄTuy@6sg,1^=zEy/MS	N.ľ;;/ǣmpn7M@i4C SDoX[iTڝ^]r+
    \ӯ3	"<=y@qWG>(oי6~~tqCX) gg9r&!B�A	E,(J!ܨ4ڮHsϝ"{Lb~EūEsŮA~}Wib!cEBWi?!էi-q{v`'&ĨnRH-\ɸj̳H<" v<}HĠ}n588E̥"!vzJף[C%癎=q9ؾbB9^xiTm3fPmlas zj.Z`mڴ!տ"=<r7	!R,T>TW|ڠu“QJAeBfZ*!׳+J'-q
    G}^	U:HMJ.e&{DHk^3ō[q!)tʣ.܎Nʒ!*%g+u=u+Kxއ"*g
    mN8HnMLj6-qƉR3r(rrK(ٌjXpk4ύ1B\t ҹi7+ZwofSGټ,uMVvJӔW/EAqIQmƫҜ.u"GSb')&W*y7o̫DQ>yVrQױN9:{6DpPKRO
    HPYy0Q;qklbQߵ)Š[j(_RUEͧ,\xb
    htɹermW]ԫ$>@]$ꄣ )V}OAɂ8?Cq
    uX`QRr	KL!wvmVr#S̇L+^OSUƫx;J]<!DeQhJs=×퐛|x{#娮IJ:*r2bݼz7zH8x-ƃKN!97	oST_aIx8S>|sQyRCrqDЎJ]8hX^):-o1TDQ8Y<\xҸ1X(7eYlx+QB8vvSy%mPU$RT=D	3󻹇VcymV.8R7*(Qն9p#rkrsKm[8~'L9WH_ބƒ6x0WRuIrGAcՍ+
    =Mj+JB/	dR!8,BI�%EHvɱjͫҏ$#6
    G9+ȉ&#ӴC3JpHTCslw6		o
    ({<HRt}XKDZ{nd*7'{d*(צ9ϐN#Gs.^G+i#MzEyT'	>p.urpD%aٻ*˖9�Ec[֕I	?x^- Fs
    &Gp]U-qhо\՞nԙu8rF&[!hB)RŠ07[1stn
    /mk]c!mP99W%4/"8n8BChs$cQ"vހ@
    ePrЉ$*q>RRZhW?Ι!#g;TuAxp^usO|9C/cH!7o!M	Qc17Ntehlg7Rh$ʘd]#[d}(9kHE4K?^L\NT
    Z=]Bż25U(dVmE	`*Wtٳ,Vv\8onV\+\׼i%S8. _bz,}
    h3aJpLQg_q|]rwFsuQV\4mdz[7O`pumHU>9!qDo9D~r=q	xA<ÉjY4Кe7½	c'vi:RڱA5&'<C':ޖϐ%R"-=~A"e@)K4ĔCReZVzF$J;wh#σ8& "{Psze4ԁ6vh\7lG"RE{.Ƶ%۴p-S
    $˫"6}alWcR VɅԇΔXp}cUe&wˆZtC=Rf	k/We^cZeJ7Xd:)K5A!WnEigz	WbQUkg-y1C"-U)W>d'|(!u*pɥNb1KZhLthO͚(Dw*}.eB!LyO'",$R;%ʇu:(]^H\?YC
    +!+iv㉫o?2p"KK{ʁA$�WoݚIy|N+<	#,ﬗHp.pKfWXJ?r6|њxC[f}AڍpK"Ҧ Yߥ³YR,f[KkIbi+YILH(p	Uѩ6Uof" .N=G%qlj9Ƥ](M~(xa2jY	iU?nO~R_Iج4J.sd_"JՄy5U?/\aMJՉﰤj&>_%o1%0Kn	qOilGiS%qK_X7xx 28Sob_|~gbHp&j)+//OI
    (QyR
    Đj?H8d|\mes*_r<T]$L1eopX|}^'_Q9p2LzQ7H|2C 󃴑U=fsLzIkys0]%Yz$&?{yxOig!yR/5ħঐ'^0R߂8=yQ%E`qZ }E+a24N#L=n>iG\k*Кk"%ՈW[Æ
    M!,l{s^9LgUJjuOz)sO ]2k7ģW$jL7co-jND~/XUs1Yo;`5do!+9H{gfd'sd2b&U"3%%K<lla0w穂,.\^d];LtDucj'Xk_u.Y\+F(Ib*$Y8ƩUUMsS,^Kܸh+EOR	$eSi5|*
    7C5q(Xft&YJ4MlaC "<:8r^GAoY%l:lfTYTo9G/
    rg3;'x
    YV؜{ �,|YʑMa
    ƫ>
    8R'l6z	F(0eKBU6'|wjhW6Wb!]@T
    dsҹiD݇%Z5lӇ:K|f/VpRn?5~f?az<ʷ	(f_.~Ӏ9dkT>.j'-{yT>f^ Ȃ'ɟոWHs5囄1$RvSyg73+@IKƋ8O;LW]KXK,L+˯ݧޤ,)G~X͜$Eϑ
    SfY >6ũ]'D<1@DI3xkqoŒMu\UWj-~Wid#Y+ĩ5yC+%q)$sK~YIe'f3sбa~M#t2?-cڟd$뺈(	9y2>oe'PyB+A;T=Q2䠦Y!`"a=S*NleTìHƭE⟹Zƅb(8sO롊<z2%L8M{=[ՄWO*G1뛀"cHW˪
    !`3 Rs3қ~B~(X!k[Fʴ%/ireݗ[iWYjՑyX1t]t_TcYvЯ@ҏ%0`À
    671plEOK86Jtk?%Os}	Rh>k„G9ag/*?yfJ<jO_7Cj.OD0I]d-y*.+˭8&$*Z5LqwI=-s+Nco~ƳǩI:Ԅ	j3
    OWgƔ/3)C•6p\iXaP}M}$nm8'J҉#ڝ5UU(gZçt-\鳹&y௉T&к[S?kb׼OC	.Έ>aZ>ȩ:%"0
    ϪYvyQx1Jp<̺N5qL(`]+	#:g<tSq	*uvrIgs<$LI~ozB"{1.+oHsxS$ BĐWw:|QU8yBMs9[Ʒ~.~BHU7[ҹ<ug+Oq]#!Jw[:\ǟNg]դ9X5q.7a!<mΆla࿉eq4w0BV{#3\=_SUw13u=~	a:+B8csqIs0hCKhf"mnDzN駆QHG?|]9Km8uϖFæoHOG$RO+˶~?#>?j[;斳vl>JglqjYǯ
    :L:SJz
    Q5LOB[?ǡu\
    Usǃlq/`9ߜ&i#m^ڰU_a+st=ǞYWke!HHz+8;JNw]g}x롤Qh?yp|i4<PiJ,}T$iCޥ~;[:]~j8ign|iy^"ߺߟm\I8BI?;h_W26mzjlaѣآEiV(L6k:-q²
    GRoeq,6"f&QFcˡU%Ye"~32s/0
    ~Y4]/uv349vÇECqWtMDaT:j"l}||޼]myT󋴑ټ9\㰜Ps8ls̍2G֞3IeN<d^sWk
    .s^#7מckzYؿs0lkąVHsxKj
    :G bmӰHV|~s1sK'N8z }L`cǏfmla&{@
    C>}e)r@N6Q'rqj?uW?[eAPn0FTƯƋ?;Sq_CҟrΕFH8
    Gh"@:]|tvzg
    ~O8<W<kyg]|8)~~P&V3yC{7H)útĿv\-5RzbD\|H}m|z/kuԸ0k|~?}?$Ɵoz6a5'N5jW	mqv8?W(5yZK
    VlactY(DJ(6`@61B%
    ,6c@6P%w9Jsj^|,\H1lC}ǥOF	A2VvBîH\&MlS`a${@DJZ$Qa\:8L#3.j/29S6ߚwYêw h|je6K[gR6w\vt^gãƱđ:姆[su'%IW}(^.~<ݗ	X)W[LM>fn5/,4ͯ=W?n<T80`À
    6w1p,dЂw64ɂ„Fг??GQ`==dW᧥p-Pn9Khmmp(ENM:.u⤽.|Zc9<I"e#tqp\z˪Zw7'A97j7Sƪxδ#eV^?xY۲al?W`z5x7*O˅۫Z.>I*;EΜ]и*V>'3+X192Y2t}uef,'QD
    ]xn`zsSzӰFLfz򵺝h6FsNh<XgUړoq&~gs:\T+<I\aWsOVΎ5&?n~`r[iPL	HdRܴqS+ʊ󑑙
    ;PjgKi-}USh<5KxxΥ 2.\/wW.Wm5e[jm)"׺}%a	
    VrtPpC?QI#ĕzU~/c]:~MZWŕ,e#+wkc4qo^lryZ{F%8z2ޱnQg$Q_�pip~u3sf.FRw6q`qm_
    60`mO
    ^l<4ZW׎oHUbՌ/ჶ~5¶0kP1B[Ba1ʝь	Y%A8yDm\2u-dXػzã3䚍<)@$Sޛ=̙s`U	if~Vt95W{(4]짪mpS߁hᆝVcޢptGcqJowGn]4.F?ӯ~7q0;-Ɠ|و6Xpںh҇Y̋#:fc0}ƗXrMF&n֤{3^,^[x]1^|3;sp8>g	#G(=RKz)˺C'a!X.Zk5/_2WtѵXgNJK¼_BSo_4k"3Y?8,tiK.A"֭
    bgjΙ5Țir+N#&�S4tvTҌS%OYWzǼ6bOaڼpqkFYp*+QpZ4W=MSQQE�W�chBE!f}&!cVD58yJ,Lś705kl㪘gc|'%tCrv,q#˚e}۴2o*@˓-YUH#qqͼ?m/60`À
    buɱTZ/Ud<Zw;܄&.NUVa/2
    ڪ*˱wL}%\yh((&܇X=O#zr|l;5ٗgoGjzԇ.zɷWsO#2*e#o/O~Fa%\sٔip1q(-Q}o<r%8=B}yIۺzX,|xoCSS+?vv{uQv5d,Tiq*ϚTM'ȆM_.]N3Nˋk`Gc0ƌEK48?F+i2\3~^OeKqm#P_S.s#cFҹ{�3um%fR8(-1p)'4+'`|~]hX=OjM^̲u2
    Ѯ0;GͪI%J9D
    N9XVfDܡ\D*w!U7=w՜/,vav۵c}jxɹvz	:Ή(J?ۊ�9#A5yBcw-ik᭾%Om<[z,޸3_.^csHvFS+2U[y&4&{}m60`À
    qyz {ƽتYMV\1MAlޞ5lw.->p݆
    BMfGg74s#'թcm(naӦ_p".nе=%v6o
    'OUhN8DnF}gg3/8X͔S]4c>
    0WM#:bY[VQ/ګj+l"2B_E
    G]n6k%lĺ_`̈ފ٪MʓؽcǣN}Wt!juprHvBAܘU6l
    Frn)~5
    ;navZgnn.2ƵH1HhɑY%ɋxɷa˾>@׿_Ox5rĨ'?_Nj[ؾm+vq1q
    #K_Td V~n0Qa}FbS1y~4wu@P/d0~tR]_\JN>S&czaے@lsZ
    iYaߎrpv===U(F^z7o/fve&EH,ި0x6Ba/'z>M]
    7֜bK%*BЫWw99`ϖH̜ws㓀Llݴn"6:[!c
    N9U%b۶-)C/?rlYdj	Mzڶ	mH8,+ƞ߶cAqpBpx'to'Y֭ō?E]^rB)&-B2d$	c#vS 6 q87n~MK`p4%[dA4to={#ȗ,y`|plaw˵TkLU~۰7ǓhwXqrȉUd#vź
    [e9rLx77癩j}IKWVV>ENâ
    h=b͊㞺w#?ԲbYD\Vq?sɢBr7a{^օT`W!uYhj7YA2	7teyXbzx\H:nGWc}T9!-}	GvSp%Y a޸i)O_>|GL?~}.hިs'_*ƭ{ԷKTNp&
    *bT<$Dm	%zZ"JR	#naV >
    ͛(쉧RN
    [~Bs$Koq#s2Speg6i7űc:.$Mkvre#"P:jOҿCMԢ^=
    ]
    y\n|0}1n{u&ͱzq\AFؾs/
    K=Ǘ_޻~n߉hP4&K֩__t¢2J܃[w!;8-iZO2=bіXIM%PDF_p}3x4(ٌ֮A{Eb,=t?y$'FקP)ѕхݵTOm<[Uu7o><
    Ϝ4o#wT1cf>	A_1q{'Ə&)*1NXh67q#+dalu	(EVN1,_flٗ㳛nE܇f,˲8Y`@[dB:}&9NK<><af$KjkkAq9%٘3u.e7'pԯ1rXoD^^Oa͗)]["E9:q�zK=ELdS҂H̷eԝN8_sFe]i..
    ѪxևՊmsDO&-C:%xg",uQ?kC B(],Pl
    QbGTT~l(bǂ
    Q^BBH%%`;yrwwvʙwΜ9gھ$tJÞK!"7<g[4*Wd7_t_nA	a!sk/4G*'(KȷO'(H*O4֊pfx4Cx/pƀpo-@%^oMCOSE6i'P%3GkZ]@t,7/gVvqG4OY{9%MmWlz ;L+;Lw'N%Ŋ\|xzuÅgtDJKpK88tkk݌~)H3
    sN[^(.By+[&[]VѫCZ&y"ޙoi!̙k�s6F^r:.5ކ"?o܄W4˰2MTb/oDL}AsUW]*w
    q!ʼnAdI%`֥bSE8쐬^o_G?m^WkvoRҖۢ,}nSWK}5c̓`D!/-
    w?Dtmocam[F'*6
    (Pp[BBBB(!pt\cG/L|,_z~_$u;
    <:#9]98F2PswŒr3[yi0kqѮCW\<h ˰/%0wswoQrMCF)\wf>n<Nisd(�l $0hU'8>t{Q
    *\~w2|cR4!u(߇w{Cyxi;uŁ;CdL/0Ct!Sp;6k/RrFƮ<$'6s"$(㤯l4۩<w ƃܹ8U﷫dɜ7݅EɁL5gkQ)5fttdvR_SZYcwgL	*{GQe Byj9Ð	Y:Wvjaid5YI&>s6":~ݱG6_}{{\N.+-jULr\rީ
    4|ކ>�nExD+,>R|ƻ`oGȦU"*K
    k.?O"w,}۪s$m2,s.sbZxnN1=%u.Syop
    v歷�w6 Zw¨[w_ζk_Z%9YInQ[]37]u
    t}F'Fh,,,,N}%{KOa><fH'&s
    hrčI?{ri(n6í~l	8Ë3[E{*9-EeKsr
    Ͻ"mw Cπ?/t=;KEGPp3xs�aMS]W<I\k\r"r
    ~J#Ƙue]xwU]y(-*BQ*9[y3}y$a~FV\Y#8c}쉤fr褽,UcSGtz u>[3Cr2cV`Oq{a? l}=yPxtR1+lrkG�WVRv
    rx.m.+=RjX
    :tҼeCz ޭxUqYyy+8NjNLjrd6g܂^}1WGòɝ}vb$VWSҿ,/={|hX1jBM[?U@p|$VMk5߀ix7r6@WI֧bsEK!Ie)dR9i;z=<ynΈ:
    N0KR
    Vp@!?yᙷؾm>~#<4f<fvX­4
    {#RTCpa`k֬X)6!2ܘQUAy̫S4{@JPpO$JIP话MR7)㿺s*; >"%{qgzqF\{#|=o	QXb|BiīCtra7<P:[b~]FyblM;g(ct]*˞!FTTjB:N}1R
    	GT|UmNDy+KR]yTL#'&!4
    |yQk]a-SA?5&{MQ%H){P2qO(*7.FCrl(\*M@jTt^Ʊ"$c#3?
    䊸Xs^ķR٪ţ.Iiщ	}<Drq|t⁞5ױg>"k�KƲnN6~y`ą(h\8R}1Ϣܭ!br@VWIVӹ4<p2x[g|P>O-j9p[//,+++)Qĸ3[H߶nSycFG~=n"8FP-d˘2/dcGwΌ߅t2�-z@DÃfkq(uڊ̂J8w nm~N|1o9lN]YW pgХӣ_շŰ~ɘ1U<ZѦcH\~]~~'?e7^y9QAm3wnފɯOǧ?-BT7m];u	?cKGކyלg?Mwk!anRF`;/I!.Uݒz#0u,fς> �G@+$kpn6j(c՜4k�xj>EhDT6㓩Cw&ryYQŁra</771gUʪ?<n(RFy;d&i5DNHsfĒ[B|#w'xVP..s+
    (';`ܮǙxޡzm.x{_}|+xڬ9zX?T)Oҁ#+qSmƘ!8U12H#ʕc3<xgg_G?Ĩf*OH=^hNӥ~ٗ\rf6xԑ?eNIi΅{KnÀ.þuwϽ/z#@25=rƌY^T]pɈm0\k1tô7ѩ}W7#Į)' snG&!"~1^-KPҬWpU,YmMW=p&U!ͧ<3^{}O~L|i&l\
    ­Hy!ƌ{
    qq&qFBBBBE+QFm\Ӝ9szCiHGyu o֮^}yňMDGWfʬNmWg#KҶlFBˡHU\VŵmCȄ|AӪ()c!=^Kl1+FgvmǎpĿedڵm_fL㧦yJ_P0Z#U36!u:xBtD(gG6[S>t;/KODJ;npYf'B)ݻw#::\?{	^
    fc~wh:ΨNO'ޢ>K;6?:vVXO/Gvܹ#-"ܕ
    =yYlʙx?kΟuEJdQBXYYY8WU='M=]i[y6HNIF�cgMEhٌXs6lΝpyL-4}*yfhBo?K
    rzj)@ʵgL4%)oXX\H2UbÚ5؞A-#ѹCq~Np\IbbbFVvcn!R!%A}Ӑ1''
    }r4xf!噱֭G^i;L;[òyض;ިurEw^-vrkGZPn;wӰF5q߉JgoF./+l*Z%B*[
    ڵKrn.*$Z6ۈuy6<P˾tiu߶e#I<tܙ S_ vKW{QEEE]
    ́.QɉZyzؕI-ãІtPGؼivs5|&uMAfuY7n-,,,NbND٪FSsgbƗo<a߈6I%~]cxk_}Uϰo̩to-ˢ[ӆ,^۷oV`h.jtHHEusأ[	c'}~)/^z9*T(H
    #֎%Y{]fj!<?A܄H=kKJJ F|23T>G3[1O��@�IDATҪdC;>MZ״ʹ-VA<kooWp9P@yW.wU6Y.@flZ~F\UPr&}P2:ܡL2#*91gvթr@9={z~J- =
    2sk1\{&VȖ!{20oH@.y:2sӋ,uk!`!`!p
    "%1sWNaQ�#T`C ӦE9d+)b}V(1B_Y&=ZƸ<KQd7ĀF^WѨ,0h2B/N84V>E0N]STPPw+=#q'2z^̟}^4w
    ܌BFi4
    [OЈOX2JYi*gk.ct۷[SAgBJh9]DJҦ
    H!vGd@DQz0?K31ͣAQHS#%YgQȨ>Iū0(WNrz=i؍X|<rIT2X
    tc"XoRmAb{qlMbJ<u\g3*mF>X^tTx}FBoY.»dakzFq~Bw~A!:XH^_UcwS)ĕX̚z83"t}CO)yJHKS0M
    +XBBBBD3bccRߓx'#$P6N IQQ1ɏ-̄OߢܥbT	�q!AG1fO%'bhoW\\'DvLnfZ~2UE?@3b߿_hToiQ~IV6;r=䴎K@�jKwjҙ%jUbˌ(ޛG-%%E2:&%/4dX/4~d&F\&|lrD/ˇEԩzvp@M)a&ْԋ\-[jժTUMDyiWtɒ%G˖-UyUVsPe>i>Ҵ	dkrf>>͙9k8^o2a$''+#PƢi|\C;t֍7۫pt{M	�,,,,NM;Ϗ)GcH|F;esڛX)R^1E12;&?M˞?tWN9nN|`,?:Qe	,q?up,y*!+DqS|`sjyOE>2i$Kܥ^EuwxrQ)e(b wGү
    -,ד	"ڵkΝ;+^'6
    I)NLz/%p?>@xr'z KVޓzpZSi*:Ɋ(2@*U<9ڲ88tv?k*I̤[BBBBC%O
    Jd!`!`!`!`!`!`!`!`!`!`!`!pb"tZBBBBBBBBBBBBBBx#`ǻ-,,,,,,,,,,,,e[l`!`!`!`!`!`!`!`!`!`!`!`!`!p `'@%X$XXXXXXXXXXXXXX'�~TEe[<`!`!`!`!`!`!`!`!`!`!`!`!`!p `'@%X$XXXXXXXXXXXXX:ȿ,,,,,,,,,,,,,Nu 9�,ㅾ
    ΠWUUA
    Gύkt%|S]8szޜ^:)u~J\w3_|(?	㈉9܋ݡm,i,iy;9\cƮ׎:Ƥ>FGVux^3ɽ8sxj#W;^i{18rp
    #:_9q|g\5Y\3 4uW{xj;Խo~tѮiYUw|k6,Nߛ6vu,co,åÛ69K89㽎'WӴ45V:F;4yKkOi...
    ړ̴9=s4tzg/iiZώWs:9|ӒgGɳ8x?kkci4*{Û'aٙo^Μ8~ao::<{s]y~Û^|uBɽNC~*^̴O6{i(:ߙi0r/9sދ9WGi=ɽ8G:Jx{kL8gpAØ㊿~gOsctprNv|i?󳎧NKirg)i_Ǹnnn25Bڵkտq&F{"#VWW'*'4]RRRf|Bm#X.	>'Ch~]]]Ov~R_t"neeIAvXODp&RN>?sQɎǢI)}}'c-8
    ݂x:B[nRcݏdVlٲ02-%I^Z	i8"(Nd',##vB>}ǻS8rM,Y=z􀯯2xÝB{YY-Z|@@9
    /i355AAAFEE1HMX͚5SbxyysNtJ^L(2``$''DׅtY(I}.˗/Wy'$$PSZZŋ+9"%Rki{(**ʕ+*z\,MͱW}Ɇ߬,)9UeV<z벚k'6lؠB՚cqrClk;!:	(+XPNDWT^2,2ЛKRblvE)Jg{28]f*e
    ڵ'VK#'Nv͛7?ocibFڿ*I*Ϣ6hIƒXh2hteW)22RI0s9]+9wt,IW}J+c6&5҇u!!!_k
    CIY{FeAt	Nj'oh۶N]V#*tn/}ȉ$+5G*"C@\Fa#ԻDN7ٍ$?Fǩ4)Tj?ޠ45Lx}
    CORhdvR)e>^%C+t^w]{%/s7%COic[q|n yJG "l
    fvwBt^vyW{E9̶I
    IWM;RIvB'8Mzhzmύ'~aOKzx/**
    2	mm
    B(#"C
    ♦$?1$2Nh1;$/?]"6FA!,%Y3i1s(MSWpP731?y	#H'$S2s0ߔ'44=|emSp,/h@Y$ KYdAײ;>^dΡtY3:]817<$mWeLڕwg<sSy=ݍGWSxC^+;.
    ̕eTгA_ʉxZTt>)sf13cӭ#aOtB{=?:4~)=ei
    4LF%NJX7)T̶BNʃj;ufڍ"ɿtr<_c1ty{4?)ѕH>«B8Z!pA&S($2&tN?+BGOI%)H\
    E_8.u0^pީ2)څjcq|5i*s̓Zr+l8IkW;4!FLGL?sPZM&G|3G@P4)RTL`'mu鈏!O%L\Xh10fΑi2U/C'Nzu:ҮiݔANyWG]A|){{zo>pJa~YJ#m
    q<X6x|86B8)( aiHX_%WKKYRCYr8'kZ$;s'ԩT?)gAdp;i.SMznB`* L6"KO7R2~So8s#w/C:lJk؇P?W;c[eX{amT7R1|򮢬{J?_2qc#hUi5SQNCT_}Ӎ3k5L0h,dJ'hZTW,ׇRcƤ1?!ՍͅXV{Zws|z=yIC7;^Ď]89PNP׻B,
    4u>Τם$X^bJǖh8lM佝>#B:RpY?*ː=pvS])%~h8!ύaN*zB*uiHڼ/f^ɫױ+d_qa?iR'400f*;!
    TxJʧZKsfU] HgPޒ-1uLʦH4
    t?rf~F$yDN^yKv"MI[s|3MTmTE5ӤFi6'ubpAS~nj>6Kcۯ7:Lc~8wi5pKʃeWj <ھE$yJcjL[::ǴC"6!{\[N?]}Fڞ)X:~B>ta:R}7w)yNxkr6 iz1h%TiAUvGCeMj'Av3.MTm|2 7^޾V1e`X"[_6J9CG(%8QjGӐ;N0Qy'ߝ_iՄzCΧZ͜<0R[tZFXvZ2,T93}c.)x0anG*4tr`eY󄏫koOW䡬^>^2*te\ca%_:D]fs4a&!M)9O.-*Dqie'5
    2#;5dk+gk/NZ)A<M6Џ+\*X	aV+1JIB="Wը#:4wmDk�;1aHGK%MOna3(>{v]}Ch
    IZa2m㈿	rLTVûsۗ
    \ D5@eyV.5iH}v@af>*j+閭o
    BQGZV9	c'ThQ<?Z^v݃''OLF|L$Lj!NFլ1wUǂ1 0{ex4CbB<|ܩ:#Uɋz6HIe^|o
    X,ܽɉtSVJG`^;:&Oβ n	g@mMz(, q6qrvEuI.eƌPJADfk\$
    |peF+2ĤgEy(ܹ#.³݌ S`MJT6kώ
    sa*gRgyV?-i(ڌ+Iw|/SvajֱpS1%/qovX6mFi%мEKDƣc
    VuI~d
    b:_rNj!L\p\'yveYl\V`wf6<4DDF!)9Sڠ47l#11> SI
    imU6oZ}hVTT^3͜F=?N/tN̈́O򑁅LYA*Aeg!,S&<-Ux;28
    ڑ'
    \mH*Zeزe=#uǍx^f(3){3%9ݒXFCY WMXx98Pªᅈl)4VefBxScha&DNշ਱~VT\>`n+NXF0g7Ν2g_1S:ۘ;-FWO! Nysxc'ft7R9f(*C;)+Qm\Eߝ<(YF	$eb;CJ^8w.
    {)
    `?m~:azTTcRWt̢[9֍Q~?z٠KB+i咚-Bo̙<ѷoo5FUI>VXUѮgtiĭ(֮ƚuw_.<|w-^*O۰KRWDJB2`b(Adޫ39l̪oWOv,}]~vty!))~>^(هY=*;A߮IjMzϐ #U{NE<]UQ]<_xqDۙA%AEh_KHmIY픧&[n>= C
    Nۄ<K/AhHSڶQҘs֭\嫷rПG
    J8ӾzwnK]LVQ.EQ+O
    $&%!gUPa34d`&XH	.Kl3)ʯrh_:My᥇ƢSR+5P-qfWi^f,ZJZ6AV1HNJ4u'_`}tnf?#QVߌa6xەWcq&ŽjSyY)#Я_zՏҋz5uœxkNQX<3}U<دۖ!eW;;-69ꪰjBٜݵu6d?–?1-ȪVb("Լ%"G#z>W;ӳb(<eK~z1\wB2H8Fm\VEG@_\dzEDԣW ?$:I[th-B(qҧbp2_wbܗWՠ}Хmk~"咫uÂm|h:gNj]@.Vyi^xe'=‚<v\<ܻ
    NqaHۈǞzH<$
    ]\-r(2)e9UuE9ʇLF+#Z LK!<G3ȳ(j<E�H_F%
    	 -[V˯|Q=:@y|)5'kqcd	~QkQ*U_@{F4m+>lD$*vla
    }/(�K6x@3pfچs+/!4$*ei]
    مcJ@1)/sxgaHJX#$:1}4󎱼P%}p2^3x4KKe-W+WoǗrtp/	w݄4( L0?i3nTR4f$y'#N_g;QP
    <9xUCK+fo,Dg;045T1Q:G^UǙ*İ4Rעz0dxFexʧd+;W ed5ige_wG՘8v8IŢ[L0>!0
    W^Ќ8
    Hb|˘	cU^>isBtPTs5BUѱHR'WTtGe^::?L\wM@腘3qv<T)NJ"(DECҭ垬{#6&yqϰ'(אj@?,!O"Jeze
    K
    @_3RQqhV|- ޅ'Gcv Om<r*˝6gYEP6w]M؊[oVMd?gދ'<e鸠_7dƕ/!Ѷ^}j0#)R{ęq߅0T#<<~وhs»cmYSpWJ]2(rCxAH]=dnMRYyFگO'ra?Ϟz9ã&NE	j@V䆝u%8J^Sugŏ<({AYFQB%e^0Z1P|I<:'d]օxA	ӳ;$(oxoHiUm%-SĘ'ѭS{T^^L 
    ?qMCf
    gطs3h<q<oZ9c}xN!cѳkGrЕY}ROˬp͔1cWap[+뿪%[K>i<lmЇik&ː,m@*S/
    ڎR˲('<L,+ķ<z֦R#wž0饗==h\u3ID(R3Ĩd֊欽ix~F`]_@N;0:ep2UBʄQD&E 1@~R3",KBJa
    Qq8D*XPM4뾯V8ϴw|{kEO2G@C5w?˪χyJ,Bg=Y$6
    5M\gn
    ebIE*xi_j/&SO=]Kshۤԁ3u;A[pCC#K,;PTJ6.)	e<LzqM&ʊq>^W&ޏU5FΞtu_)
    /5f_0~~R'U+]Xԫ8z۵y
    {%tv7t*/<_mΔ0*
    QNWݓLc[b-icf#NCvP:J$JV(0yLHbrBҏ"̓	̝;¢qn,ˎ%\jR"rm3cJb#-1Fى5|WFV6o&$sD'A~L+˗@g"-' fyp0'S͌W#.'*je*6nKDvђۍcZQ'
    5^ѹC[Ke4j'Cal֠=<Pk1gк?=}5|\\q9_3*"h{:'x*/u?F?6`蔒�ә{ӱfjOѭY܎+—KNvĪc_!:w�
    ,䧉OFLt,v�\Έ.-i0gY.D29WQuaNy4Lz{&c>8QUw+
    ԱWjpdqXQlWt7Ûqi
    Vn؎m;!"ȍ<Te뛍BXDu
    T`-qXz=P	
    G.]o`;KŸ_=:`Ǻp}Xzh
    WvaX"7);qv!Z.ANۺ+ry{a%uS:�vȕ-R-Yb'_$FҐ@a.<iU:J.B<z5nQ2BU3^Xd>VsfZ-6̶oKۊM[s3':Gj)%*<*m֭Щ}gvcTdp&Zx'&>'ۦYg{#{I^^wo.%D:ZZ2G]ذ@5sY&ycYk+iZZjz'Z`]2,}qQ{u쌘VFQR؝/mIz#i[a]8[D\DBBMǔnUGTQѶ}n!Xr).fMr_(dDzg$K6)K#H\܍
    #}w&P٦`u%?)vRs&lӯΙΌ%@˰pTdE(eG$H\^QMl*4k)m+"èр@Ʀ
    y[bkՁ=Xt)ڋD^|6W`Ǯ=pF|1^JX+WEqg?RbP)xm?,LqK2|`Xz9oWQ~-\OIӂ˙ڵ6!%eـ-i;^~h˓\*eNTNr]2Ӳmҩ_HlU?4K'mNVfmބ֩oQrV+B<,HL+V}5AT*gqײR)S/|5s&jw_?Å#5Πq[YqڍUogʞ6ĶD%Z
    x0MP(F~W\ЇypYfEg|s*-uBr8f̙3E\~GJ5F'VGakJ9ۺ{J
    Hߋq3mPT:wtލ/gP-U'}f`e[o_3t>\e箸]Z[y":!/}zɹu.1K{#<$ƅ\͗͜iY/xѕa/g8NwRJB|d(u&_ұ#=ͣЍ<FD.+cqP'Yv O	_ۧݛSya.5z;CgԙVq%Y~JKn4肘ᅠ~\5{6p0*ż*] qFax;0/s@`c9efVqZ4c_n޽z£�oX9?}mL]MS)"!-бs\*a*DWxOOJ|x<UQ`պ-m
    	1YW陪_7m!I\_#2d)
    '^\4B{uh�zL1gM"\>9*ixmݺ6m2YS9VK]f=QVJ>E$u.E}R))w'cY!|SSYm[~&׉q[EfМ}#$2@+.xD'
    r5CW.PF]B&LЦObZbHn[ 1_~qŭwp<iCIA$6F#^=ll�We,e*Y@e2@)<qǍÑۊ+_+RƪT[sqA6V*ѵGO{#+l؁H)b_|FFpٞ#C|\mECq¦t7{2ݓNóco@8|Ny%I?$PPxp==};ǫJAB{:KB=Z`:vtJ<H[v砹|ݦ8}yZDڈ/6.䋝iiL@gB%N1;
    t"̥A./|WF!HnJKGnnҷlR!lJgpKQ٨[}ϧNf<a/3�/Əbz	z«/KoqђWk@c:GqeovKEG%TptD4"9#h
    QWE4Q6h:iW4�gC8ڵ<}?%"G5ەqoyexaG5{cpBa^2qƍ}(l2hDe'\*.o<s7>LNd:�.p-+ǪQOf؞:?<
    _NSq|cy!46.7z3"c1\wEӰx"qqQs`*2n";flco}0icݱcrFE(sDd=>WZ\_(*̣%|{0r);0ȗ{011h؈{>?'\7a,֡i?guVؽ[<'y$Pfw'oW½e4*PJBLm,;8h›?48cdP/RLq%&r2n\:~MD{fx)?}(^i6p)&MJ{1cњJ4nAI٬,^eޅM2m:]׾޹
    oo?/Ŵĺe`sbˑp.߂~W`ʽñm}ަMޝ:E?/Qs-7Rh<.ӟ"ȭ
    L~oZG$lǞmQ\JglWR\8pǝ=ъ̑T8;[Q?b`/!h
    w#%*| XQܜ#|2I4?|W/QIcbpoX^1/t ^fذ*\m|LRfE	$ё[h$l\	w�}żŜƂWg )Κ~Sr4r&z
    7=ϸ.r<G#qoяsళplNU%*ypFbSqؑCo~AgJF#Ƨ|zo㪁g &L~Zd0RD7Pf%Z<Z*-E8f԰nۖKA4^x>ůw<[F^`je$DQ344̪]x1X9OL,||e|qϽRo|2H
    ’߿xP9[{xjC|"zeѾ,Xӷ0vQ99#n
    c12"î	yŜ6V]<jlE*C+Rx8E
    8`qըQ/SǹI_>D%VY'W.j Xg=0U0<T?o_sDUg37uO+ٽ2FKxYFDӯFfӵ]ozaݚHR37R'SEyZ^RF}R*u
    xefaRaZ!YĜi1mʢϓ~ʿeM>^xq6'&aѮI㧠0r`fGWJgv-aƛ9+bٜ/0nydmOC:bHrfaƽ7T=WvLiʓIaAL\:%FdN#_ʖ]kO⬁QY=SC@\>B,xv߾[qTzC&3
    nB|ʐɓpqsf1_}w'Xx< Xjy-m]ԽiLιa='~Rf́/~|IX9x齯ѺE,MCwc^N-y&n<Gq]'q52+K*8Ytd@Խ\DdϏ*ta){FjdX|LC_O}'v'zs<{
    t쐈;qR'vKSPq>3
    9g&R^,Zxr>5^̉,.\%~ߍW3ZmX�8#yUcRRB=@spnso<_Ӂ3;t\9a
    N'`k~G:XN\s2vмZgnuRG!#(e;sOgAQ_0d8*vsbGvpw	D|(5+~P=/�T(C8Oąx	^1<2,LZ~)^|$rܯU#G/FM.y:ei^&GCKsͣ$̤J1{`6?uCL|hQ_){WR͡%jh\cj{*މCYRoLEgtV+Ü~Q#놲.vc#1'0i̖tФ9kуw؉Ұ7'-=6GrnGaCQFOyƫ|�I8Y1=TϦ*!؋F毿+|Kq&o23NC(7"dSi‹NeS#(醏x
    Q(2hs_^t)o%7!j@ku\Q
    ˱1.y;qijK?|P'#%2+y+�[HX2·#/=;VbM"|-
    ʿ(j={D[f85|j$Կe<)k/cJ27?y8rH*H߶	;E";fVQx%{Z7_l݅N{'pB.Bv1e_p!MǓǯMcK/$�Ķ
    hl$칔4vAg2ߠ	7F^>y\K׌@bKb{_byK¾U>w-.Q߲}r0
    d궡x/͐:o=Jg;/E{hb[qv]θ3:^$W<8ϰap(\qފ_AokTQB1+-
    A|O6e#?^6K1x N7S3"P;*JuFbݧBk.WCuT8[w*՗#'rg?crnl#M9Iݹ	"!&4^#zr2օF͚Q̹3';#mew`$mE&YN0%Jwňs텊9#CUbëf$A -i
    ub(LJs3\/v"?|Kw_;-_?X,ܷ>~}-;['?%m}8?\R4D.z��@�IDAT_L,Zʥ*W[G*/`mg6]kLU]k8q>pV.]GŘk:&w
    >zI֣薤-)a`crOߡ[<
    hܪα	
    F5q4|ꃈrWӦp+QK~?.�]?K>_QEjuE\x!BK@k7˥Ӣ[Ȍe0SL`bquKt|m΀ ٸ<SSMVƫeaq3a$rUH_|Ҷ2..Vys=Kϼ>6sJaq!Y9 =z(ڳo=2H<
    ܫ;z>ĵǯN?.QV%n@+>
    ~Dܾ\3ɁsY
    &Id0mqRtV*S
    :#d�h.'4NO%6+00۱'
    SgLy-QUXSw,nĕh=0%q&Lj;{ЕYʲVo~]
    ]*,73׺ù"Nob0ql*5ˑu~K{r$̻+Oo9}4Wl۽ۆaW#FߊU/D>YCQk/ݐGr6�>NX<w2ί?u6r6{׋rU
    qEVv|W[@Ѻ߿.g�8On
    Rh3dRw?0F=9Ohq8"Tf_РQk]/ށ7t\8<O@TtQ.!҃rҟ$h}@Ys$H5@+2S�NJʊyL6�OZsOfNV~јt7t2-lņ܎JdRvWC=[ՑfBeS35HO q׋ Qxy}=5<+/�?7~ЋN.75<C?ކ侸qmM4?d7dcO?Q]hEӤ[埻8:٩GF}mˀg]d(Bfnӳ;MAo-N7Pלe	mp!*_4ũ62!(*|޾1erda18u/h
    C\/sQ^u$n\Ɏj;`q+M}FLa5v\|tȤb]&np4g$ߓƙHC\TV|ܣr+6tN#54{]|&|>9"X!LAQipWqp.Iöb<>̳:v߁w^s
    L4q߻Lxca_Ys�̪~(!@IH!zURˮ}wZ׵+k/ 6TA,%$<3w޼$\G}ܙ3gΜ9sf̙ушQC-=^G.*hESlZ	L7)WMVԹ3چa%Wӹ!{yb/L:K$M_Ň]zI4Uƺ-H5iV,w
    at4mv[qQ8w/Q$xOy+v
    a4x[q%aWд0\}dtN.QiXs|K1ZW1]6kI83Љ;eё{�'NM)Y5KamQӴ*(M\HE^BCb@g58!UrKs/^N@#0ڐu;O*pY3PJm# ƴZw4+J=kgy/GV8νGWa#	[.\:;e$vd7nHHzBʩe&bFtjؖhrC\f]:ܷLFEwTt,&&s7|GSڧL4f%-6śoCTbwǕ4/lBT.LbCz'Mo¸с|ţ"VgaEKMvѵkg:Kچ:R	chJSn:f:Qt荜
    TD1vYKL1GWAaذ<<Y\̿:*J&˨=-=-2TF]4˞�w|#zcZw
    pb
    Č%ӯfr1DIZ$T;X@!&mi׿/ڷo :a̎!^+اQd^'Y3uA~q#:RWV<57}.ypdxc!ة
    bsq9(ʯ1ubL80hV\XڐiU`1:]cM={ &G?DΝOlU
    xf�Tfl6
    $@ﮤbl9]p2(
    eYV"IU4]fe.eBrj6ȍyѭapw\L)Lp0nZdH7VP`<fMДM[CN-R}:zm2JҔhi0*QԼ
    ^n>}ӪQᤋ'(Q5,A֭MSܫ;]v3LnVXzGS;y�;1h+0ڃGŗ؄o>wň<2%;mؾ8-SFs;ktsޜKlAL0~{!#SG.ok_~v֠UiK,Y(Qq_}?424L imɗ&#|CCB뮬N0d)4
    ߶>_cw?HM7qS⧏'φqe�WK:0{o=�	/ӊۓ6([oZNs.
    G~|3çp6WCwc+^zpmw$.;c*"2X͆%X#BlbZ(HF\&g!sΡa<C?GHxޭfl{x/'LL+[nHoMeA&ܵ'Z?�fdAg-Z(;G3_3XU&zs1ǟzȦuk
    ˳?AUbO)C`ZVU0r0MYװ!e݊}TҿpQ4>謶@\u=8O|#q9q-Cy„#rz6;#׌=͋>Cpʩg---#pH$?v;HO65kŨ8::o,Yu-Sx3VIwfx+/
    H6γˉBy&)t^oIJԱFJբݭ5~#tNh=fBlǞ8z07s5-f�dhefxl{.?xqd4ϹLlAxص׮3g(xݜa7ub^.kd~qp\5o<}f[#s DrF8Jm7ۅQ;ᴃ
    L�奓&\'8`1ږc9DjKcy.X+-AAZ<
    8<ûYߒ&6S)WFo2gem( 3?: ^	Nh#v8{JHep9r2eGTzrCVi{BbXT?1wg:ѡC"@@o=vԈ)BIYYt"]Zz<կ3V A-G-
    ;&∣&?~2'yV9x*\xgṭ?<ii)$�*;~#-Ji
    o-hex獗;;QuDhwe%\e|7):bK RSy])w�&`Q¶7bm&derMx:i<{.VGFf-#dYIr)ckd6d2qHy"FoNomX71kpL+
    y0Y):pFnݬB.4C l/GtzE@fq)rlRQLq'߇urS;0sd78IkM$R>JWk`u]pQqh<=x!(d5g(JoҬ5-GLHMێV,\L{j)MIG7:Hk5#Ͼe-\5c]diԩ"sOJlIZ={[z_t5nO8*egp$(Z@PGbٓNgԫ'7ٹ5nk^Ɣ)GӲ$'2RiMWƩgqU[_]`Z,j*SB;|ΡшUH[GY2lzqѹ$'I2:&<_kr)!I۶L	g.Ѥdwrg>8oB^!E[Ps2.koL?g߹b
    E^B4F
    
    xV]}Pgg駣d,,쨲fG%4G}sOumȮ1nhO3e)VfOXjiiS]V)y6:*	q逓0Εؐ	
    5*X
    2H%^a&mvD`)&xtGS_
    3Fe|]_؈g?iLC^֜8Q85]\E+&&[Br%$򔝠OAŹ@ikX67}3IF\q	q(L;OO}VW%i`7AQ
    kOOAcKr*-aaƋ`&n!*¦cc8b`#\WEMGu6%ވ?D>;~0AOչkw9q2Z4?UNv6\_GqX(y9lܶwE~1FMZ`đ'>Ha=ׯO=:po&./rԩ{M5
    ̵֮Mk֜Ecqs{toE
    -9
    7rB,HrA(q+%=5ވo8UΗOwkD'_ătB'mtffpHZ#F"$m\-}z\qQ}~*1kfC-_Wz!-;b.I3y.E<kbG&MI-RL	uo BrҒ
    nCFqzd:jPwDp7,4=ѭW:%i⽹p%
    ZCHNN9v#`Cֵ@}84-“oīԮ9t]L:<m"#yGRn�40빼^_
    t)s,w�v$cj f`lHIE͐gW.y|\pkC|mQ^lR}t1w3:髕F^ &Vp$
    cg$4ֻN9
    N;JѸ#Q7>.swZuv}X0o.,5Dbَc{*I
    8``2	S'G[!Oے9)JAps
    h^!$tyy|M=WixEgߟwP^ƣ&,drxy]q7-3|1m~\ъ}w	MxwZOo
    (˥n7a(#dgJ`mY]"tÒġ0/Bh.DcM"s`"zT31�mnd*v,h]wc]Vj3(Ӝ2&h֚}𐱼d1<?cRH7Rp2WiIf9H#8Rxù!#;ERqNRp7,p}'xik&>TvɈ癱L:O`ҵODĶM?'w9QoU줵?Ay%wAtUm:"N\YZQI'{)οo^Ibf7$.'9};ϙΜxt@%4jZfibP-߰sJ'Д;raT6tԸ
    _a{S93uVn�VMGއmv<%�?_tdQU&0l8(qRaTJFZ/6xfp|2HDlaQ\DŽDХcP<f27}My
    1e<y>kׯ"МvHEŗL݄MIyG13OIϛ*NĿ{GTc(SC^/6F#?]lɃqvV|s1g
    rҧ]X3G^!fq8piRzT`l䓅H_({u2hx|B^ŶMsj3hN;40΅_q!1ǛH‚9)9)tki>)0UStCrNvo~	5f9*veXeNњMu[	PAZ(Ȕӈ9P3k8O6L\GN^qWN{9⻹4]kŔgNOڕ]
    Zhܴӱd:#1PK0Wհp_)D<KF/pA1w%;p"i6ՖҷaKRzpw)?jZœӎI&Iަc
    9Y
    "os?Aھo1Ǡhm'<9CƢM([1
    C1<&4VЂƈX:;q˵Г9Y^1&?g45cْϐbd^2,Z&UcК5
    jAL٦PB}M+4TZ}}ͅ\ùr'ӿB.pQXp|	3Q!h)*6;=6*EFu?ӳ;چ#-}|Xj皡
    %<~TUy"'S0$&EVò,^"0tnu9<Z~K끝\8tzuma۠;elLf29%�]:c0zuxe8mbu	+^I&0ChPs'
    `+&A%lPɗ2VcL9RRkQS ڤSF!lSmmxʅX۩oF?:ܺSv 	}29Im'VGo&O4'Ӽngm$I&
    :lQO+sF+(چko/(nQ1p-|Sb"j%xӾ<2�n@.xmyW|tjt֍t}ضGrњ} 7Wz;U8MԈ{z׸&FkAْ#7iBQaG4[e=sAcz
    @yY,rs1;pʲLuR
    n8s8A_wwq⟷\0._2)O>t͊Ͱg-]	ML\x(ϥ�n!HQ>N E֭N;*ޛ|63@Rb6�{xAOdLot&s4#wW/<qǵJ}t<՞ғYο_owig͘D0YLGkNw^~"{v\xu@xij!lb=~q(p5cY0kGqe
    w=^]㎹y?|Tr5>23N?06o	|	:?/u?[/?~IsE**Ap-pa֫3
    <Ľ�՘px<zO^x4=no.d}~A($MTyW_pX�wk;BUo3y0-Jl3g.Qkg\/=v/<#OiS~
    |2wupurxgsŅ;R<Β'3PkA]mހwv;hZ>\c_{3FѪ'/~q~N><<FБء'r=qu'xwt8XRZㅇz:VF8;<?<Og1.EOOp)鵼/28&*hg!Y+?z6?Swq(FC]҄;E,?Çb_qeq n<gZs@2*>`=*H#^Kg3{m7\U#^ƈqO`׭36y6)ʈԿS�=!؋m?'0M]S?!M+k	&zRDc?XN+vs2aiKMa[?rF
    bE2}(!2YЅM?;ŀk)FRKzn<m#S1K~y3l|&Pi7-ڡGBKhWayBчiCh{I"(osև^8I
    5v~81oOΤ:-LxQM'*=)m"R6w$͓ߌ?uW]ęc5;żP.LU5aV'kҩoY3Xԕ><
    ǨfM4Oub/O-4ļY<?nnCB4th1'݁bD!-d*PDEA>wޘbŋv 'vqqyw!Fr)nd4&6Lݢk,3MxbƋ8=-]h/;
    ߮v/tQV9^Tcjf1U[ic!
    Շw1h.Y?(˽Z||~4/]96T='bWYkH:k[Yxzڕ\:s+λ~:vz<A/\$¿&
    vXe!kry[CA'0=9ĤV^i~q@*Pe(^*'?YyoنGpιnjLDB+Xoz^=q;#~o2|<6b{
    B\.aok@DRp/b{^ơt6f�Ýn؜ǜ\+zqwTG:
    E.o^r*~*M|N<;ѡK/`:Q%+o@srI7ǻycɁb.X"k%'>ekc]*p<>tVJO4_?70kxe(8SzvO4R2Q_RR&qRDzBWCN"?W[<W
    )HRCXgRx!m۟:OROap(nk7UgL4HcK/SjbSڴN/AzpW5
    zu{ѢE4-湼fU$\RV=dZ3~<N<@D!=di;vqU8xmބ$%mق]4	(	Њw(sG %e;w%)i4*zhФ%Wф+\+=<Kӱ=7#Owt6XW9x*6: 	׹Ζ܅Xm!3hgpk{+#Dn4%nOzj܌jx#N[޳p)m"ۑV*
    ;,:i6WIlvQb;ϘP4iM"w*yŦ3R<t4C<GR7'klv	N<6rfV3vil,N+iUێT6ʐ4f7k6BwHekd7&&y<cGy9of?:KFd7wcY0WOL5<!=I6o&I[9ik:uHd#55yt5JI\|{(n*y<,
    #Cd|gV+Y
    s2~-{a\n׎mkkhF(D~%3;ε)8I'ﲏ+FahŶ,
    Ƽ$6.4()Fۙl&h]FXwG>m	NJKYF]³H8։7#ߑT\#xdy0xUJ&ϺDO;&)XQ%!{p׮Le)WՋ$h߰!1B:U
    Ro4rO:)e2{~6tԶCp
    RGth3t!Ũ)Եan*eVt&?dI%׹F"M~(erJ2yGwrQ]-i6WlG(OxG)RZـţY#zfɠi|j!99ʤcPa]uk҂6I(!]7¶
    mI@9Z">ߞMuN8i>֚fZ4B^yӸI37o%,2Q">!6);sgaK^iY%۰1)GKB)|+/"x׽л3PE6&ٰ<6L0yWaT
    $c
    J'cyֶ4;IqGxW47|ţ
    =~Pnкu8|DQ~ia?uC6\{«<l"sE;70pl`-*,0cڔoؔdCj0q e7C&8hG qXKO+x:hLXrmَ}UVܶuOj޳OFMx弮Ȣje(e;mΝR~I^iKG*5W2fpG
    ἥs':s$V;ӑCJCһvf`;etSYU(7f=Q>(91%;
    -KKACppcYhW~ԺDցts:LS_iN<႐hK2rIG/,@)픙%4cv#86hL+Z-k474hN	w|RRɨPd!#eJM(9V\@(nN=&6-ۨ2e'u9=QnS*gp34~MS^Q'OءtJ2h;8w-xJ4&dI�ͪ]vf{iP,cGjlMAuxwu*-6mњr%R5P,5Niu)ȦL`9`IYRH?6ߤsj3RW6#%stt9݄	/3t7o˴+K/4rlcQ_
    9FIS(ƶ֡eDb8NfYGsmlаV17Ҕ;%%>]M܎}z|t*:^.Y)HZI&9zxU$<fTXa[%mSz
    |p)-d]5g<@"KLU4~epC:hI]6r5Ky+nyCc@9Pk
    8fcHU1FꋻJr]׼/I<d~$z�S81>mNHNC٧E{-REQ$feBdh<ygZj
    iG4l6:.9P^~EDөL=<:1C^9K"S&ڜ/iѲ)L6ćemgq?߁#TVFܰ/+L,UFڴiӊLy+_tT�+bM>]2:\ktV24ƪocNr%t]oFKq$A+X
    2%6f%Qa^1lb2h'AlX\cZ)2o4)%/;;{%3!;<emp&%8F+L[79Ai4:KijݤHIRV4V[4ʼnsL^Mpkr&PIoGeGA$8`U>@;ޑY@pBnbۛ˔.
    VB-|\=ycߵ
    .:__9s.]V˙Ք")4�
    Eu|<%LGCAT~rUgM3O&y/hZuun_eeȔ̶g*Z
    Zy
    wK3A&<3fU?ѭZN7Pz8>T-\aL0|Õ#8
    mwJ5+gεПWF
    E#Yk:{~l2/me%s
    _F?;;t;4sCѢ3J^C3ëz*|~/EFh$Q?rӨ\Ʃ
    INGUwC8̫p5 *)NsD͛f X#Knl>~f7Ï,WJ/%uOxQ㒛Lu.7VdA-k:UO4,X*h:y0HcejtCkxqIc5Oj#O.;!=^pll3k,$8wvWQ*.FgwÓꍵJOvq0BVXzABg5]p,Sba9*WrcAeN:klLoHfӸqw}}Ͼ�>*\\W5k8Y[]	jyCF8G`u>>)R#18QY{"T@_cuќa\ЂmɋA"\wFx)hU3}kwmPٶ7SgMޤ*ĠzIhbp0rʾ"]dd_u[Xf1:G{S qzcc-	ԑHj:XT}͇FC8l'-wrߖ*;C^\B.Jb`fFfI!
    ]<c"xy/Nf~yxsYۜHo'deRe=~/J(/X?r#xa>)\vl<IKOd@CWi92WxZpKc^Ҹou=iҪlCk0*[ozql|vj7JK=#)٥
    CJQhi	$Ai5p	3YP*ޚHh52up*-ΉkOjpqk	[%u]O~Gi:'X%opO
    :($Sk];S*N3	O۷Ĵzf3J0ß2Q6+c;)_:Un.C&$
    v�v
    6׆/%ّq|#$s7%\N߫e:1<\F9wi@\(ߖ!~%Trn%0WkGCTWU%W	{vr<FbU�#rt;+}O[p2%Au9ʒR9rkCG
    m? ]ʷшXO	ilm,
    8XP9\}9A[|M%JrO&NpLpT.Z1j4+Kc`ں]{V7Lwq0k)%-z3ÍsRL4S5R7rXlDQ[-!WT[ڝ)L9F^x8`Ŋh 9opeR1ke29KɧR&JGLݽF/`;0r!~eywp՟, 
    $@Mt3�,O)W/Kgq4TY
    EZem;EC9صA2/hhruNx|xҜUNSٚ8<2Zm*wip}cu}$5SvAS}69xһ7G{8T2F:hjdqXJAhdYa̐,%-^ftfJh`eX
    wwe7߮	"S絕՗nr_
    zpsg)ZˣxkTᨶXh`1틤CBNl&vzR8<
    oj\Yo*xYe)+ܼNm`]%>D-YO}&~\\cEENZ1	7d{-=DZ/�3�
    #-�CKƶOCZvV!xmY~V܁qpsII4
    zDN	7GW {-]}p0)\j;?N-v7QPT]Eٝ+&A?~|d92<!"˥)Osz&]{[Z.]S`o=ĕgc3�ц~ywoӵCmʵ?Էz'pB{#Fuš?<7K³ԝȤ!2ڢV.*X_!P-CK Jhɟ,	kd]#sm@=:41m;b!T7GN=ِOe)v\pO{@dpM]0SnM*L8wsO}W_駉_`|g	s8xpg裼cv	_m:><zmdN+V_=.-<|7]!Hhﹴ|
    ի^�~DjCW}F)xO4U|x:{{W[M.ӻT핎4{'~~|և0>ʳtٴ<\ޞ'=(}~#X:b�z:u$7,o=tq#'/ڣ-SfkK2g8Sq��@�IDATU1һ8M]Z=P\IYpy>iEw(?_>{kpZ?.-&|GK[zɨy&8}}}]ǻCUb΢oչ>|a̶dn(sH'O2M۽ǥ?8	n+(,M|O̥dN%.hwuuxk }tBOWK/|~Aq>;q7^
    )Ƿ^g`w8<ŧxR8x.^J<emr!_/?7Ipry|ʿ7~:8r}tj+W-ֵ+>yG2ğ.Z6j+Od`]E?8WWO[9+Nm/NŵI0NjCC,۩}S@Om~!zy~
    +~S?1ɪ	RN}}?m]Jp}şѡ~pʥ_+,èvm(֖_u/.ٍ%:c-U/2Yu7ڻ`q[Ш.O5c!5H(h SPUCo.{*^NU>VK+m]釯
    {.p|sQZWWux*ߏmw?.=>	|uU+p[]kM3(u,׽ܶ
    "*''VW{*@+O{qd2\q*Gjs:*)Nf%4{
    '
    _tuwQ[)<ŞT<uSų.Eyp?]7Us
    _??|VK驾h(Οx>>8νwx}~.j3xŻ|.ރՖŹ.|瘪r3.A<#C-ф?;\U>9y.ʧ j嗮!OF0|W|q+ty\p},GV
    <.2AU.]ZɟR[x@-w<PˎNmO=]݅`:ZҺ<mpץ	~]9&JO+`[rKnm<ǹ`wSt^۽.뾹x}w.=w=]&g
    O0\?Z?k/~>d`ǟo߁qQe+o//vp
    ~o]ձ~dKW|{/%ҫ'ʣrꃏ+8E_i.˪RgzjΫ?ɒ$n…˻k{&D*۷ҺJ@wx/w-GGL
    kE?Ύ.n_,):t`
    -c_81{zN~u<j'RVz?uq֟A?D4}L(8CQ=]wھgmFŹ|z:E#9r+KW3ޞ'S}3p|||J~]pkw-XmqX/:Smwtܟ.nL'8\Dz|c`H}iת6ߟ.WZ_ݷã<I䡜I!W;>s~;
    WiR&oۗlƩ4xBK-Jp;'uYhʻoSviŗ{WO{_M\}UIZm=zNڵk6aܵ?Ww!$S!?
    l
    6>*_FHS@G@v=!M@.U^r3gxQO?nu5]?8q_{+(V=JQ3L;9zxBeҟp%8Kg'C@]))A% s#p/
    Xո}=nܝGKW_]Kj8U/zIfzj@]?Wh)ϥwxVY߻y]$;\W=㭗[>CKpuz*ΔԖ|2pw_#\NYwRvEe$YOCpSpӸh__pyuQI{˳NT&j M2o	;~NR]~<lRj;[ǽ+a?OԿ5vmgMz/lO\I,
    1o֏'%Q>mxO
    ?զ.7="ݟغS0z|''G3ۏU@?pP;o88~qqy
    '7F'J	zu$r fԨ<nߏBu#M~WeQIn?u_-M.=8Sj77.puzӄ~v~l4_DZN܉0]>U+G\YIK[S]?:q!]e.Z
    Gÿ^{kRCW_$E�\mpvO-Op\8i<J\g׍`vyG~YCloo{0)(_p݂5sBe5#	�\	Gr}iRO`?=nr"⪼JLU};~-`Q�A'Rsz/+dL}sRb+ظ�.^]`~\u2�'/S5R
    W򸶲mW_3tnߖV-նn+^AZ�+~+Yk!_Z"DEYSҹLj".5x?͛{%leqƯMgA9qp\u]鯫sJollO҆=ӻ/piV1KϚkΥèަpj1߅k
    qm?
    8jn;vr
    Gy3?3'Hˊ�MuXs#_?J]K6i{ke%żWuk`ϓO>yj)R6kp)@ӖnˬTʁ:OUssN4!!(A-[p]NW9'lmM'@@CG\UѶ"av#/'tt״yKjYw_p8u7q%m⵩$o&4{&x&aP4]ޫ;sKb7y3+/iC8HeГ4P\B(/*$>c4}Z䰼y
    MhBODWR^Hv((&v5H?2]C#f_s"S%
    VT50mZWn6yOyxDP%׿
    9upiE[WN]:Y++J-Ѻ0u5@]tp{{wcW\sb9^97~WRI)V&I9ګ)F1ؚٙ]֬F{%	ݿʋazF=ݦm|.蛃t۰	Z^hָ
    tZJEVh٢i*[~S3qđ";硹4'Ml+5I '݂%4'oUZd7Dڈ'MB1~xYe2y˨θ=t?on˕jDM~=ͪS<@|sHz	kW952,xeJzs3v`|=erexԈfx(f!>{vD 2]9;q%s"̙"%1c�3 ߒ֬~_نD%8j@3Yzg$Qа%
    1s1~hOoY}u翁kpuB|̛C&c}~Z[s
    wq')ݺ9Kγa#q%Ies�؏wKo!<.JrY)*؉'a|\ JTsxgݰ;\q$nĘfV/HZg sޘEiUc>T{I	g{}ku}а=E_]^/GҚ2rR17z
    X=,6֕N@3cUE2q"]MqSל<$<嫶huK.uџ^v/Yhބ^9ؑ[/GfaMEΚ:ԇGXX:^z1:F
    i` aO!5ַۘnIn:	-w_~_jpb^k@lZN6[A['Cf݅1ژIo;o*r+3p<?)וs3@VA/<])w`ϣz200ѿG<ۜro矄~܃{v7Eo߼
    /=,>Y-?\c&"?k+>l:#LϔXͷ@\i
    0{+5g1't\8XyEbc":t}x*L{&'g:9x9Ɖg^)kBȲ?7w9wB4!~A`xq_QWz/~:'9\}U0V|ѻhyryjXyzJK~x흅\j1v!hDx<>'w(zl7h laޜ9A7pk[MF(lH.UFW]^G =قoqxYس3`75*uT&L^A*+ՃxzOkc
    )«WA݈ܳ:s(Ė(.(Fia>+:a<u:	e?y+[mLhzTZ NXפؓEī~~w<=_Yw'Spп>{ƜaP\"b:`C1qѻk:8].y]
    zcL8÷K\Q=Aw�Y{eI^~VѯKG<cuehFE'!ܡ0R
    B寥GcN<x7	o(„)'e8ljyW_i+2iU9>.~j5O4ۄ%8Q<:um^}Fpʅwc!q4T6i/:(B	F�ve#!.Ю*="\vW`XSy!/_~Ͻ6YnH]t'ų_.kDDCaNG~U8وƈ¦ُ3;<ܳV0-OI%u#LQ~\ǛOf=	\Y}hj&&Gʯ9@s8?_OsTQ-k	gvW㸡XҕX&'[4C\T+|`qo+VZوv!<y֏hx㵗3E_y�/9`P0<xΫD,eM>feI.>^~qxw+|;_?7k2|4|q4тIRΉKGEO1y,f=膞F[o~kzB\@P.8C9'w?\ǥԩGp'Lޛ)<MK<V|sـ$FEz_\|#(K'MB؂8yalc\oZoԬmp͵`H8Z/zs~mh<nP)F9Էxis+pn\n_y]^EߎvF7@aGuIg@XzlTM>^{wwF֑#m&&W"?=kcQEXSf/*G2ڄ҄^ن`Sf;KHV,\AGX[I&?+X:+쎈Q]PQB	Mݎ5u!ٹ
    6nė+1blvhӫ+E^,D0lv
    ߸B848+8!z|4W-GL:}$aٻKuWL=uWh'Wf~ncbP߶grl[^1\.ƒE1MR26/e;09i۵DaVZ yu
    RR0~?/!
    ntzFlxL:i0b$X/W'&$?I37<reѻ_㛕IkAa\ŚX2͚7K�?4`|2{rcɃ0zdW/,X#9q֤!9;}DD`I8Д'Hff'>ꈟ+B|=u|{3A7LC]8
    0x*	0jpR]Vs!
    2~@C(Ni[^+TJt||qoFpwҢ~iZ=AGXykyN:n2-Z5Ee1>|u$SEf#?ts!y2<
    n&xǥ<x¬m}x1|�woMO�'9MsR݁}'.yN|8)K8z@o=˟yg|4›2NZۧ�Fr|Nۢ^wr
    ;z9&t)SOBjnS%3HlP}h•89EP5^qmcinko#݆"%3AmzI}cҼ
    :Ocn#jeɲEuIYLΟ}g1.<~L5
    ǣYfyu҉8-pUk]ccĉHpvq@/U/ 2.>צQ.}sq1L>Ck/;:EX??
    Ӝ=L.1*Iu7)? d=<C{7]>dq!OoNǟb%7]bT?^4
    o+B9#
    =E7	dTȃ|~iLJي<^!}{{K%8z,'aYnŴoc̠hzPhA_;WJ|o4+3_֌<8ѳci]{-	
    C[b0y d&}a^w|CGÐcqÀ,ˎW\wFҶvnڲfonV<Y
    ̹a
    w70%*7夼7opDŶBV2"M9`t@VhPYϦ/ŝg|v4*
    >_W]~T~ٷUPaⴋ%~d"bjt|qp^!g֞Ks0;~;x+PUtZ'sk
    =_}ݼoz5>X	l(.]%
    q⹯2}Vg`u"GGr(ģ,@vnt6ޟIKS$thkÖn~N[VkrUL�_=%Æ{W'E1jR',x
    >K
    ʙkקzl[&_;M]ۊ4y/aZ/<``Բ\ƬT:7vjmAzj.<k5sbp,_#ל3q!µg`2W#+qטؘIX#
    C {+_Oi0xڙR!ؑ3
    G=<flv8Ry~JB*FU7nS\\Bע"xir	kFܹQH[
    1Ŵ	oEGǢsDDPvs~8₿ch?;9B#p䮔[n.4v>V͸Hhm=((TG.>6NfsGLaCws#GX= -m\ yuR�;2iq8wvxq?2!<l\<0w'S;VVW4j}G#1Jlq՛6
    Zx-y5OH(ToEBs}m&d6yC~ U43fy,|
    mP.Wߎ7>*09g!ł`]Mn6
    Fɇ0iBlB'Ei/|˾gcXk_dL'-p?Zҳ/NCF7TP6nO&6j㇇ -3D	T
    BZ0eQkUR
    ~.1WՉB&݁>O⦌_h9Xp"屭g_=U:qW
    ]As'rv᫏WS82O6LI¢Ϸ`=+0A	/u%0W3}\sF[n4hH/m(&u7^
    Lpv()f$eIg)'ƉcNĈ>12n0>C0MnQcn<J&ɺX!e+	<%5.5WN|i4;w '/نOGtźrX2
    Y?CaJK4j[><Mf`4GQԴzABZMӠs;,!঳dVW<zv:kHO˥D&*چ`mvpGڎGqh=_Ivm@>Դu�VUd/JH AD)!UWWŵݵ_{w+*]aI{oB@޽wʙ3;gapdOl)س+AĢ #&CcZltTgbj{I}	3q_`\LJȳ3~⍛eM-yĪbo̘=YUMDٝQ^\/C|pp*Ȏ쁿\5
    2b1/
    e*dRν8LT?.ށGF×@R^?}J:xb_us8ᪿ+l;n-r<|N89wcpÏᘉI:N|ZLBӧܛg")zaż"~4lbhv)Y(nA0ljm׸!?XwfˌH@"T^X>Ɨ	Ed[
    15oۡ_|MB?S-<|=j.<	/n\FzvY8*nZk FQ8:88`0
    pԔ`ѧK_ᇵ;qԐ8$njϋpdz{z	)†+kժ0G qjn!><jQ琚н
    dS[sਾ
    bmEZ	k@W|k6|c}vԊ"}U]}9;pU11#u<]j[i
    ޓ]k?_[?"J+*Ԭ;V
    lZv7w?8@]uѽ8~6єǫA#1Mہk֢[1|tҠ/^@a|Wf")/""ۈH.qʊiX5W!I$†q]c9 wraT[/4'M$5t6/\5Ա5bRyꍓ W=4^h56ٯEw@CudLSM+Nꕾ/%+͇_0$&4KWV JVE[2n."&D&epWWĘ_0M.Y^p/|1,	X}Ո;eD/Gp??<yr
    NQx#7?߂c14e=]
    76<*qLLWrTvsh-q8p($s#q\V3΍l4
    y70܍{�Uto٨d$~b#g1#[зف8y5Taܓ7HI01;*)w`L}rJ3rfVxP=>F8]ظzҳj7GvZ	yugwʋWfN6q4+w Zh?d\I*_=Jh҃oQlaǝtvMٷr/ڷW`P/koZi^>>z[|e.E+_C|	._
    \&8q	j)^704lP(}qGAMZNJ԰mͦΗ+N)V_]6!SZP~W&gųԽ78<ѧ/gϰ8ukcjG#<ZYrdO?ъ[գ_>ۍ	�3TouM\�QTPϏ%I=ri|,'zEst*r2@_zژjۯ82?#_|0>z$Ox ?TM H]s?N]pD$1OP)ظ)+O܉;?W=ߑAm_2Q~h5@ƫ53H(;/ł&F=mYesd$_LG^#J;-RVNdPۻ[#xӏg̰bDjBCY&g^Y))1ǘxꡱ*WžBk<SfAcg"[85͛YØp.>V,7XDW�oІO}RM8c)1yߓb)2||}ջЫOo_#:ިd7y?5,M6Ki:GgoA=˩'dF8\ag
    Vкz�WK[di#ߨ`+oƑ#Yu,][߮_o@7-b܎�~ӃCj4ǒ!
    P[a^(7K5k3:d]X?7ю	n|e(/+y\.7Hn\
    9mA	_d k;n:/*NntjOIT.i.ˋpҔ<t�V)[,:);&b9xE<ƒ^gGA|89CCY'wp[3fJT'2>>aK߉מYw̺֚Dx_0g1>"3i	=!w5>Z~"x_�TGk;
    Ae01-E
    LGNG%s劳KV³0 9)ix`'G<n3}l"Հ2ĔԂ+Lq3%MAf	,V
    ȫl!,ŨSӆpֶF}LE^�ZzJ˨(3O	*cWx*L8\ei5;#?BIeŒ\Zi.yaKۼ{}q,entŗD%ƥ1{@cŤmQPZJ|%k۲0Pܴ]51<i}yR!ߚb{R]WBǓk#D8HosnU%RV_*yRo̻1z\+y?yY)땟hVWVbYs1o0mzО|!p-?SbSw&˩W+B/([PH#cڕSj$:njuwS̼&BeTg[tj"獏5HT{"{90#;*ŗdϣuTg*^G-:'Gg4q^mq
    Wcoế?;><@Л[Kӟ'@i].Z\s8w:e"hT4zzN(V{@,XrZ>#?\6I	#8򓱛w[CGTh~=yXŏ6}6/PyP)MWsi[Z9Y12:4o&󦹿/R#*k7]ypIɦzcMT]XT97dd!ڟWipbГڙrTUz�g`ǦWՎ{a7<"Gj((i֑P.5VwGR?%UD8w7Od:FPNC4
    ٕ£u;�
    nRInq"z(7zx^s1!~]-[f<
    i3@VJNu\TϏfR"Pغ#e@eހܟVqew:V7(|Lك};ҸwFPu4ʨvsdb١-AIQx|OHѱn+ncPI	
    Dl/
    ٲA�[/F?7<x<0aa/{!ab_&>g8GnxXv(B,a
    P͕GI}fc_gWpHT4(?ǧ\MǮNy^#gd"%rY|0Cر5Ǜc+
    0dd_h~Z
    x#փb<(6SEx
    *n⑱`#Eô)azT!Wxf	Uy&dW$Q^9g]*E%Z.Au{ӧ&*oA_es<pv~g?+E&;'Y<ôJԗyw8|۽/}kY_+ā̵|On|կع;ExUmnmMX–9TKgW5|=W>7td\2}#.~l{8޶w<RL%ji5>O>OUa/Ɔ,<ׁ8u,	el.#o;dV
    O_i}鸩C7Cyi[W`Y#l97R8x>q/#F}`OPuq"ĪrQltZGgrܐ?y}+껷m3̥l߄~JԙҒt2gUy>x>uX|7EO~eJ=*%ۏH;y㔱N֭[#yn^8GҦo[~
    2sPTE'x_'4yl`:޳`δ*\&-aF=Uf_'=\}:hxeصm>}CuW]Kvl߆[`(Osqu,篋0T7$Sv{m;x7H3y*aܖ>[:rNEr޻$mn9KKkn=7c7bq	O17d5
    D85B7Ⱥc&{LoHkڛC#+;YihAc8WڥI+n:T;͉@iUv9/s
    MD%`8<Ƈ1U-0kaʸQȔhVҒ<VEF֮}]ҴB5'?x|J|d=|xO+.%"'(L/<p1F0NP1)9vfx,-0ӱ﬌lإ"q3ߺ#ܹނ}D$$sD�9jR/e=Kفso|_[GmX4enކΠu.yO?WH/Œ?LV|11}5(B+f>)H9}I`n
    $$ZIUh/XzU`щ8L$gg|y";wg1k1T	,lǠoeĢ(+ܸƇ[w*|j΢55ظk:>+r|(xesАxo7c1
    9*6Ctzd<BNF6b`_K%_WqV{℞ަoYTNMǏԿ9
    2
    ~Q7<ՙbz3kS㍣$˽		9<6%ƦagJi~HU&~[>#{b݃sb`´(oV4LGFE#ңgM)WNC7xM]\)_>ev;ᳺ*X\A2gݿ:;?IT劋>ߗ2-/r!|?S})늵3/»w?4Zu߭`έx$Μ9I,
    %%%K¿C.m~ٰ
    Bϸ0[GX$UݛyY'`6ί1S'7Qx{ݒpLjA·{{C/~ݛ<8u
    `RoGTOM=�#Q(+,X@nkze^窬Vs5ad,Z/+psyqSuj۱|_.Aj)%'\85gHV7aOSgBxhOd}^:o~~^!֕u]7^QֈVDB剬mႩ3Z?-Zn
    xR9_\EjJ;�;6/NJ-97ݲs
    zFc⨡θHǙO|UC{3OL57|G`ާ^7~+xN_qdDi4,KŒo>Ƶg潍S{
    Xe<|!|vǀ#T
    s&ODt(mቢ#l=Xi1!$7 vQO‹ob؜q	SRkcoK7]?v,"R#�N4 ՞v ݐs9I3ϺϹqUcO=Rjmۈe6QxZ7ڌ'^�k}ߧc+OPLͲ
    q4Wo,<߯|Lm�l5)2hTX/Po{>vo`z}'VoF03N?54!r	1?)I\��@�IDAT)M 9ƫ[AR̞mȕ޳@	.yi)ØCnKJՋ^EMp$΃yG̽'P}+8~.5q6񰤕)c�ԕ\yyz'l>G�(;{JpԉiŶ?Gaǎ
    x7q+Kp;t"3Oys&n/y*TpJ4VŸ<fޝ^|
    xGѾJ}-PBrrrSWS|íKD^BuۗJO:FE,rfQ1a\wG.?{RDȽPҊ#j�F$ˉBV^T*t><<rhEˁժc}>4Pd}]-|"RՊY/|*+X	`)@O4&Qs,.p5"h	ЏWW|)4p ,-WB"BfT&80ݽ-\&f	==q:1ÃKu4TZ5O*O6l̢`Z?sr
    +B@"hxFhI~JxLZ(ģ,QCR7oQ*)9
    ^(~4r,"\j,gxoAaé9Ƀ0R\a8Ud"č+ڙi9_Dd 7"[7d*$-SkI_WU
    D3΀R)Eht6,/{_<zJC^T
    jKՆNt?t={*n'fSqc3=$h`L6c6@+_
    hGFQs !!vd_fNɟi);Xݓ*-OJ4#4:)Jꝯ&90	B$snv6<81_V\wF=bbPYRjDFEQp w;tsyI?*/f9w#}<8,II}qR@FN*+,3'a8YX*-v	#bò7x=Vs<eA~;<iH&\LAzpOe*h*1E=no&UջD&qڢ0k.ǫ6\<LWQ	H*ΧQ@dyvv&xl1}
    Q崺QaDI$u�'Ƣ{۟-_ܲB({jEu[rh~5?jH=WsɣYxtat?Ndő\Ts!rUɏeԊ`!PڑI7a;{jWtdrܝGSFqU[,㏼\dU5fAdT4+P\Y>@_4L+'X:lknv.~_;צ<)=qO
    
    mIŬ{$Tns_{wm	"i{\B:ֻ~G&-+ϫDеXBI?JK...GOj2W4Cy]:#in%DQKTU+Ld'cuC
    1L^<|/^Ab3'`ѷONFe.Jǥ'
    +<T٣&7{Y6n8X
    |@j$e }yXJ iغ-UЯFG]My[/A`CYomTVe6}tPժhٓ^r
    u%]+ɛ+4*Fƀ|ԞsiTɫ̟3EO`-15P}JUև\o
    5|QT~)"#NN2\ʣJPvV1f}K2#řYE%_WNQu7TQ-l,8tR/~eH%cxBd5{qUjZ{STqnBCVŁAq/|El|>ODd+j(@4<avzҩ`r)7Zd.E|
    5]1끑/[uY,KZ+VNpސ&~Y>	44Ysפ�!:bV6ȕn+pris#9ӋʾL𗲑_+6ޮ
    Y`4'#~ÏHItU]c~D@T&
    _ۈ η
    kЅNL%4v]iuoZ\넜!}є
    `{	芼85`3o;˳/}DAaGtR^pG	:dzykgWR)3o=ӷuulOR;Pv}.2rHptA@WEݳwA]cCyyW@t+*;V#`Kd<}]w-sZ<ǾnD%^uZ@	sU4jg&#ߥx+q*ּU9Zp7(⸨,L 	O,W;B);'Zbh't1;KutKRstb7blo
    y5juXi1(	N%
    O*%pJ,GѺIʣ"-&r*KZ^+
    Z1�(ǧXPWke&5;Cfj'%^%^)lʊ0JᇉEPnG^o蓖sEp+_F/q{jl`Snbl?ckŴoΓ9w\?E7X¾Ƅ֜ɯ6e,7¯E$x2JvvWpzr*	GR6H>s҉ެNv$3?H[-[X*N#%Q>rVYtvB\'l
    lS(+y.۩n-і>H\Y}A#t}(QPmy#ANY{Ő@!s5M}`Zi5_:ƷhZr/qt<:nw<;e|彨 q"Mw(GG[{?}IKiv{<u)͓⋼6_$n+V?IzU;fn	M˚EC
    ۤа.+8gĦ>tVxZ.m]qŏۑNXX	z>$_óAqT4fՁ)ˬڄS86ss/mE{KFz@6=qa(gvC7w1t4EԲ[N&3U	W\Ke	t;?Mim\>p1efڹ(14%n G
    8;[{I=tVGڬlc]hqnjBTSہĩg*pngs[^ڊ{P7o>}@qAp~ȞϮ6KڙT*rrxUjQ{_gOCt»qgm(nLNT]3vIKe'mÍOKufQg't\ne:S:)Ev2o&SWre/߶Юvy-4|9m4VC.iuGnmܸQ1Ug:Zb)ˌ^mj[ZGX[J]}W:r9Sv?+Pw)Y^g^wGDg=e:q,fEEV^Ç|:;~*Z
    CQ6=^v2'MDc$mI/W_9KW
    ^a:tz^kmܶ[
    TÅ$r1rJu}/e~7NLj|ȨG
    &>v^ʽo
    %Bw6v^WΧ(MͲB7`(휣8*+
    ;IƂ"Ckս~D1D(dBބ[N U~ƒQGwκuԤi M	.Gho=FYm{-fˡst;2{ 
    Z89KSL:K?]퉯#yh$DW[֯qMu<.Qy/eWE-hm=KXGX4]{9/Gܽre$@p}Sz̓۔xDZEWpe@-v;҆c ]g5^42`HlH|:AKWoiO3]ZVe?itU΀OKuVLT'λ;3`q~!BW>[jl<t},t:BΖJy!Bs5=CS<؉2 
    NU&dCH{_Z5Qi!j&ʽqC@#cTOl]BpU#]2IwUgkk͓`u:[lPS{c&i:[%]G{,+jDZ_giÇ`i~23tA `0A `p@{L `0A `0;hߣD4hu]g0A `0A@oupEH?A `0A `0\#Кݢ.R}VVhmNHUά<at%Lɽi+}][tt<}4
    m˽N:jh'Η״tsK{N_[qq%8]{Ϳ䪝=Oqںj0awE@y{ù,:Le5?;-xt=OrsϮ0:ӷl-NCt{#WMSifkGK\ǵfU;49=}{5]UY<tv?kkyUɳ8Oqts"9~tZWy=~y:4Z9g9́.׶Z>:Nmg/
    9{g*O;]VN%8sOiԃG
    a:/ڎ,8+}p30Fj?ciK<;NtrQ̣(};{͋=|mO4vu^ښ=}iH[د:
    iqq]<]4Xu=~n@裏r\qA `0A `09Ei).w)=;;3gn
    A `0A pcꂃb
    -2A `0A `0TQqSzv}"GK__uzg/W}/y8;&Omj+ܙ>tL9ҵiӶ^9O_]o-U|gÝ^Wڵ#q[cA `0Z]AwZ#d@WB*;\|;eb^[]wqC
    .#d*7^[E=Xtg;3oSC+c;L՞8Puv(3yA `0qhQ@廙?nUE:o0A {"tY]ڳg222 f3]yLOOOMcc7A `8#W6n܈
    6gϞ݇[ju}Ck?M<{N͞NǑ{M%t
    媝+~5?rC9iyt7cķ{{
    {?rszWUk~j-s\sK۟i:w#WH~mů%gfN+WlCJJ
    bccn7A `0É>Ye0`�R@5A# z}}=;;߆?A `0?
    %YYq?ZB}+̾i6;jZwLM[|{O#:B9E]MA `0tmZekE_E܏t O]I˾͝|Xv#K)PF8JLň)\l#60q8ݧNfP޺MpBe6A `0t
    ZХZP]XIcPduuʙ[	
    
    PX<<"8}Y|?j"K~6G
    fh@HOHrkZUk]Cϣ;m>
    A `0:m
    v~e§;*J
    F7/tCk
    G :*j{Uh7Ê#ގH^^Lہe87
    ~
    (.	_oxyV-sGY$.}ia߼ON0Tc岟Sq >&TmC:O(IS喸npkD
    XC×-
    WWΫx͇t]VY2vוј8a4B|QҴ4
    ,F3	4'~	>]p'*>	fʨ/+-&6
    	#<=UtB`F
    'C&Ty΂|S),zhRgߐrg0A `0<Oaj<wf|8ǐYX
    w
    ̍5X<vl,Z
    ")i_?Y>_"IUq|0
    *9)w>Dm;ϼ*h>8$
    qϝaB?i4	pժ<+O??_o/Tko7]
    &ÄoMZ tjUf(pY}([]5Z	7Nޞ/'DD_:te&M:h.ȲVdƛoǍ׼&uKNV=Hêco
    »Ln3Ϝ?%|Ʉ7JNuAޓ~/e
    i3Ԥh.-G=zIŗ
    zx4𓛾|!|ZTLG(.TyI;pv.CSм4y֣BM[06@06A `0 СtYe*Qޘ
    >"0zsRV(zRžTQBdT"#B K5U,BEeٓSHXBC)\’7>)uUݽ߯�W)c(Ȫ$=Rވ=/w`(bIGVZ!^
    y4iLzPP"2	@}
    2v#;/U|BCmFQI9W`b	Ҩ,Gfz*)yHx$ƒ/l ğ�,`[@
    fكOqa}MҳQ^Qh#2!ai(-ʀ'"E>)9Ej$8(�eE(.@(HYDDCUy12rX~-(E!ةŇek'+JҊ*
    ~
    8Tx 啬wk*PQ]@s%!ል{#J
    U|煜"x""<uՕHczE$AVNA%'\rrsd''$y)QmOp
    Eģ#02>D9P#|DG255#n
    
    dݗ!!$1*U&$5!7;5ubeĖ]຅_A `0@g@Czg`mDTZMSJ|�
    TV[B#Y(W/|UVG8
    ^r!i~q_b8~':s/3M�k79#pb_õg΀oGoU_b]jFM-
    G@V	;2)+Δrx7+9O>$qf@OcO2c+QEgxV3ƥ1Cz#o|}Hw}ppԚt0L|,\|yK^g^ƦBYԨ#G'-|Oȷ;}6.<lL?;aE''obF;1_チE�^*LȴdAxxכι:=w6jsv3/	x[141|M\vC8wD/8AضSϨApMWc؁رG\v-ڈy=3>,d.¨Ac==[\OFvbw>B&'_5x凑8 k˷_geUԾÏEsc'ٌ2,|a<�'O¦e_cͮ$ۮ
    GDN&7m,x-dz2X=Ht'=_!&!YN~ `0A `h	ZUVѭPH_'>bkq?|~3/4	o%xUt£yB\r
    *`ʬ?j5ܫ.y˯9s3|w|!Sjz=¼m*\kPW߂÷щAV2j|Eaa)++][}^r#?a"v	70%">2~>{y`<t)ۉ7ߍ&qj^3p.9'#16BEԺEo?-|q}!xy\Q.-pݏp9~~\TdmÝ<_WC8˚l	v}	^sy)[{$˒e?~p繳k
    x9TqnDZMɈ$p
    hOTw/U`d;xt.psxu<(p	xAv g+ˆKnňu;}0w%0ykJǯw
    \t=;((#z+g/?v8bTTlJui1vo>sB3g?.
    5\M6st\rn=R%Wߪr_q/n}CQ%s-&
    SO9gw˧`XX׋oaqX%+ױm'5x"~$,QpoyDbg0A `0@t-Mpư	idC
    T
    jpU*~NU"]z[e-n]s!c{brFznXUTs@-FW#2L;wS@g	=Ǡ`.><e0~խ˩b^0X'+__[+|esDtFF*D)̕8tq{2jш$*}dfIO֝۰z2m`T.Q3=Z,Ksac>\)ZR^ЕХX*7
    "؏=bS?Xmb֬ށOCzF/XR/#zD"λ7>2ꩂ/W~hsDN	2iDN#jr9.ŠZv^{o!Z[6ס*6'2<<|ϘC⥻IP]p~̓qΉmUOᓭ(mSκ]pBPUJHzǶʤPMQz4TVX[.J򲑒q18vH$D`{~[_Z])=ӏ?}q
    3R=;6狯'p<ʑ�v�Gd\{_0k e$5(*UU5*-Uڍ	18n)!=P9*398S4=Lem~A `0@Cs))'|zڲ||:Xq><^Oz+~a~6ՔЗ̽1IêNtܟn	j"/¡veϴ8>47٨/�W=Gz[)zs3ڕ/tqJA^}U\Mu\IE\qE(}ܣLp^>OWIuk`!PC{ɕjYè2:#CWWyr~wTgpKAbqzNĊߑXCj4B⥖j�{s_Xαj.Byun֩ԋea[ՠΟ7޴y4zAj/8ݻE3O481!NQ}b/BPPUXrv"B=شQxť^8ĴĞrX*)g[/cNWÎ	S7#|!o
    稳pN6˽6}b)Y#x~"xJxP%cʬӱ;/
    ?T}7}Ao&İnA `0n	I"!f@k4&UMc%
    (DQ00L;K^TRxP~oo
    >˯�[ҢWEr:"!,ğZ[@bNG�IB{ИwQ3&;=qAdEफ /4yza,CFcI(6;fqjݸ:XY̕tHE
    9sM/ya$FLDD2Z'EZ+f:$su߽kVDU#	ظi;H8||}iJg״22yS/rv`(ZiyEa:|M`I5pf?@<j0jdL=>4ye&VWP|/?<]M4PPWEC2鱕Z	?XeZdFu5"HHLF8Iʀ\	WjfP\t	f{12Swn’YS>?ǜ|S3nm8"t2y FhTNܺ͛hK"I'w6ˋ@9iRC
    ;/8'>s=l?s6pw/wRq`DDEc0A `0�лz8i?:v:'Vsd%
    ^է_h|s2q%bzŪ9%eJUxq+wQ�ro�-^yo͹.6u2%dXĭ/Q+ARRktc1xWp궍8kXޚ!Y5
    F
    ʲNz)I3S(ש3i<Ov9䷾
    w_7+f֑XpjL:mO7<wOpy9x|IoG_/Û.Ix(mo3@r4bJɭQAc=*~>[FfC~$@\% rcO͘	
    R;ky6xXtN&|sUԳET;{5w_,ƵI	_[@t;4֓+քLJo=4%+T~7~bBX=gT2_礌Wӏ<Oxb/x{׬QX̳>i.>d|x
    t۟,ņ#NCb<*zf+pM?)Ui~َZA򠑘'Q_,,`	T
    Z`@a[M
    Zm0**i<Rp.ײѫg'{z`Դ/IsSA `0A`?9R_]PVhsX2$5Ty#L:Ge:^9|0#&&3N^xUbI44m
    
    苘n	
    VGEbbh2x3+yTW(~}{#jc@\$t^?9+~ѣF &"{y\Y=+)}=(ફ%zSż'Nԣ#JV y11?‚P^^"1rpb'P<ӎ>IXutY11s׻yKCC7r$e
    <x0r[KCt8!Tΐ*1ǢGBwjP5+Qu{A޽&L"Q|c{>}0{.CPB7~$
    L
    ~2{%1n
    0d$f9cFń)C1x`uYLd9uM{7^4(&$Q㸷%E8#F8ph"=𢐾u
    u=O ~!F?ŌI㨅#GoO
    <b0bhhn"jXE%l_cpq.zXX;w"p=g6S�UGepŽ�Sˮ2uqODD౓#.+'47]t6􈡍*" 1^=?|FPBf^	<	W\3ÈEc-
    Å$!@b	='dAWYAwL4fff"99YZ]ֹ޴A `0"69*~JMݻ7jxr6ba	S=u\MP/FySWKyVKFV1RN4]MSA7GVk)p2'Zl6!.ˍTa"_R}^TU9O
    P|s5#T_KD-^k_òհln4NlDRj>
    8ShD&	OeK^̫mE%2]""V~u:sl	rHxM8K~r|5+*XGr»M;Q;"RO>A2ʟԡYxtno=v|k	zU"g[e|Y5wCg]KA/C5Hvt2W,h.G3#+V+,uw϶-Z{g,e3ECISgu/B:_iO+WČ3GcwRǺ:/3A `0?�mU;@V뫫8O_q8-][o%�[cn-F:9T—Cxdi"sqBSpʀ^
    0&&o
    %^*854)CbIH[+*ѲH,¯6+m%Q?fId^‡U.O˲</U.Gņ;_>jY,iDP\-!W!1w
    \M'XՋG2U
    ,g5
    IڽKP_0LʯC::fʒlEIK-O)8]roaR$.:
    a$7R�%W'u@ǝ77dD,8v)p
    t{<Es:Lbp2BVLE#!#XH~Tnϯ)=S6G$$LaLIB/묵T:nkqLA `0Ap Ц쯟W{\}x[o%hIxbiy0qu|4"XtN>g9?E^tt~:~Ja4}ͫ3=f&DքNwk/JQFMOOC`<hX~\Q`Y~*ϵmOU~GY%⯝>*w?BjEٍV'6_-A-Ԫ-grdi%J-dG?5c->{gm״Ϛ|Plu\gm]ﶶ.it+^m
    l=%M&A `0A#.]j�-iɿ5Z	k끻%8w׊,O'|5]i/_j?M_vAؙ滽j+L7-++rծ-ڊoz+?W#<zXNKuߗImVw3]K4ᮞu\'6⵵8n?W\[pi7A `"Цe"&ǔӨ\+ؗaeQoooo~*{l^,~2Xt>+aB7eee}>]/j"DY$-%yF_JKW[e?p;//Oa$B'FՄG)>!�&zEZlU~ԕZjSWf+;mV[^kEeߩ-wn˺-~%mYښnB_<j^=m+g,罠J>q_A `0
    60% YU DhA:L&qN|%ifE~$L˟yqСMM#%tC7:˪n]F0'm?űGuՑ\Wmxu44}N6_rnk+G[X:#a§+j.i+M_בj^:B_,Xt&IgWN_dL&;t~*Sc0A `)`VDzj%Z9H2miÜ@괇 Lf^r'4WxG?t_g{{OgWq|sl|sYiuV:~aW{}G?pWWV\ign0=i4E
    
    U/RFA `0	}tڝ@V8t0{w559 j|ô_Up=̇$rJXVZĪ9xy&B\ϙgN_%iaIq:MKqtx{hZ4:qZ"4[ǙS_yRM28it8+㻊'/4:_~u|竝j
    .kOߴ3A `0C>`e`]K:|-^`N%cY=}s˪i!t4^W]]u:}{g簖hno>JVвDZ߷xMn<*OvFSW~^er4-ONk~0WWjtzqj0A `#@,:ɪ,;Hke��@�IDATqsri\<V-%U[|Y4dOG4_JV5
    \_WHvl])G롭6`Oӈt:|߰6gO[&oi4{\wv:=sl0A `0tmЕ` Rk}oۂ²
    xR'l-Ш8$&tO
    j"HhBŵ=8bJK\{	fwMte5=<Y7QֳG"/iʳ$/BY;&wWRݲ܌]Hȃ;
    I]_]--WDx3˸7u;rԹjNH}SmQVhn'VnxRWsz9@Zt�h,~I3O!VW:FwW}ǩy3A `0whS@y
    /)7ޏeQ]G!B-=(q566:xxzQ�[pb_=U|K[@$==er	<:G[i̗E&eVX�$r)j޴$񦑂)hWHim# 
    ر\t݃&yvDs-7c�ozBMB-;("TE}b,R&!	@z#'7;7KPQݝr;<93cckG"la7Qfb\L}nǔO8:Xc%:<Ax.E2Lc^-*dcڭ:vrSCV&&"C@qJ12r
    B@!P(
    7\AֲЉ΁p֧Y̍0T#ac%"3BBB)[[{'8񄡢vR΅?5!r3u!n^pE΅x"χxBV\g^]i@!LEfV6J+Hy;{ (8~^DFj*HѹYMPTT8q&rj'%!)%
    UFx	{;g�[q溲alEٖ}F`QqvDiY<ࠕtt4Dz(B4Xt9ҸG~nJ*iPm(sԇ@@�T
    h: 358cUTUQTd䓿
    =PvFey1h\eP^1G7Ip b7~[xOp\AC=I.*Az8{őߍ(5mOdOD
    ׎zG3UB!P(
    B#pYK&aUh�?d;9E֧ߠkx�,]+ULݛo~."uహu//YC 1v?�|<Ǹ}l?S):6T!ػYK³~(ωTfC"tFu	ꈹw
    Ei)w#1[XCoY#65I];nB;k``=3'	晌IG7asq >~psεW۸p=O8}J?~L0	pjy8XDi@Qw'f"Ƚzw;&aoaز9gISqRDPƧa=s0tӰoo4ODL0{R9~۸
    O,\ LDz0yx{>27k1هY5'gOCaHK8'ςwXjxfhi&rw*R
    B@!P(Q#N^7џ~Ͽo-FNi>{'ˈ;ؽhTDg|xt|y}#[:{^:`=}X0hBLr4g`83nBUXtY6}?|# Ŀ`r]N7#A|;z4Z�z\Wś1q0r ȥ?{+}	ڷ=
    _'1$d*\rJCu@/2Lzt!|`FaՏ3O#NmY2"[5C,-ӞGw`÷b7t�Fh
    Ww1ЭGot"4ܖ~MwЫWwt4ȹ/,:4ogOÃ&rNWxV%S,(-:ս(}_)aLٿ{DC8gcpM9vF=DB"G!P(
    B@!EN:њ_Avk@q9BNޘ_'^XeGb�&l;:]a?A;rD>v̝6>N5ׂsh%B#O8Q)ݓ\b78R_@%h.T׀1n@q}}s0aa(r86 +;I:	WJ"c"A-#1f`Ox9٣'E%|~"UjED]aoC{ h}{otBAyl>2ssiDGзS*Dٍݶ݅8;oBVrV1=%!QQ/Y,X-u�ʚ×,CCh:]חR[r{D;t�ti@*A?>9
    g!0kǹpbC4*}ESP(
    B@!P?@h'skhw@":٥҈4T‰I.I;{Zr.KE([;6G'GxP|6S-Y
    D~M{B@pі֥{dy,JWŊIٿ/Sc"єlgKq!ؗގ6
    7^nps=ϽJ
    $nPN'ke$GNp�m"@	^^>/֗/xxz™vw	9x@ޤ͞6tv	|!ktu٫™6^nΘ" 2AXC5nW>{[oVbwBf>&/?Y͛6cW`JSC:ф>ăǞ>ўN.nM&So{靇_ D�8QN(
    B@!P(ƫi`NzlڀX;SN 6r (|h֪EcDV~tD[>'Ca~q
    ]BtCO6D+++hq2D$c䅉1|YAV 	ǡOt5p"yzS<2D{#?\#M�~~"9:OCDH>InoeC;P&NdO wvq~h_mwL<6DeX.
    M[_x]<~VxiдK!tD8;E\0m& WӞw6y2yvJ}ܧgW4lr|X8oȿ8/LsQڼGi;DI	#yo8ӆ
    )= Xpցpwq
    zD٥]oT?
    B@!P(
    <WeAg>@4E9i+[ն}pS|=~}tm'݉K^:}nWnCDy#x_h/uhr;IF$ NĕVVI�njtb;~6ضH/uܞ<s~&Fs8_j"5D
    9]Cm`XrL{J3
    q}8
    "ўtZ-T?�SPC.j9tߜ[+#̝"m}*<
    3oێ
    6{+wlGډA!%h:0$xa<̾2z
    `3X
    8b欇ЬpjS{21v/"Hj]L>49(Ki
    M‹Oǖ=}"icd2}
    Hl=pь(~
    B@!P(
    u@g2=ZcV͛G>ziEp 2[Ù4TCb[uC.Qۙ6:s)DH}}ӗxfgh0ë)j߶<]/	:vhZLV́vqCOݺw;}XΦ]Nh,cO�Y6K6
    yhѱ3ӮG}6
    :MD3d?#NAtl<#"#(_8[+7N	¢"Z{#)_(]Ӏ'džs18L.dqFg77	qrə#y(K/F˶a)oGM~:v�<ma$$<>xمmҠ3y8}%t>ᨃHHNc*5_lZ$֥G!)5go "ZB;ζ<z)hݱ#&4QJ8Jc.;A[m[FLO9O= 48r 2KжC$|_{WX9|0+UP(
    BW$*r3%ᴼlv1lכ{
    [&G1_+Jsᕥ?aܠ^5*HdÎ,l5gb[M2.q>je[+/)H=;
    _]ڹ-ca}y;QSDyw/
    >v{vQ%\'gKu:5tF;ɌL4lP8	A0v4&x8_~?^]MK 3[Ν>t:/KGz>c(Ou馾c<$=qL͋ x\IF5Yy4Vn.y,׺$LCP.ozX6B%d,b	-
    K~2DkPV(
    B@!\ŝI&+#q2gĤEN">Q|8<`FěqF&3V%P[UP1	VLXY[ɘ df)$\-07r'Q6yp8ϝ6XpsU8!BN}wix+?N<}czs.lJkyC62WO;Dru¬1dcTjbz <F(\1vicM@QANc\P<˲g(ϓB<!e2(2N`O;u*B@!P(
    BEt&e!*snԉEm:vz7Tцq6H4WrY!2`gBL:`bBR>k"D"C&$B/ɺ9F1}Y/׳=##72XW+Rk-#_zr>W+e~z[z=Z,}r`δi[uyz߳7\R>RKƄ幜eemg.CSAƓ,Xj!2e=r˥-+_хs\eܕ[#/G<x[
    B@!P(u.Ge;\Igr-?n?-[Y>KYh<I<,Mb&&ꥴQ>t?Wr2j2oJ,A$H3;No"u)k]Uɷ &-\jO7#l^YNʹUx˼^Y_e:e^yoG>t˫LU]42^]
    B@!P(7HIfr		A~~p.))Wu?vu^}#CΤ2yx&I,Za},#/T7T|>Mv%R':J~s\ԅ˰KY.X`Vz6Ljׅ%ƒ_byK_n,\M_qY>ː}%qu羒yXO^WcK9ָX.W[W[ȗcAwѳ~uW,[PXX(I*
    B@!P(n.!Jm.]жm[UI�ytLd_4RXʽR^_-G@A?*øXtu/2L8Xo)c)eQz+ɗm׿{եZ_\.Wjk]e.|Y_|m9dKܯ+|;w.	ԏB@!P(
    BA!bKjL4hUB@!!
    B@!P(7HYQv1i.(U1Y?zfvfؽ"�PIkmE/s="qV>_r%|גW_UwJhƄV+ayQYDX3g(Wg97RUyi'/PA!P(
    B@!p!pEz-mcϔ,òuy+_9X/f-u~yz?\>OjE&#LȲ_.q"/^e#Ȫeף
    үNBn4b)s^koR&]u峌w 8p>O1McOkrJB@!P(
    B/!pE.>RWW /op-u+MҪ
    ˇz#Nk%c9ol&uj)!]tX-/)FQ;mJgOGY>Se<Y汖"2j"J+-^'b(p(-z3\NYz99R?%4^*H\5,3mFgWXW$Jή4YT',[[`役TGyY	HHN41 ͓oivI7P7
    B@!P(
    +BeUaCks}}7e),Oe7q[.`;ѶMx~QyQoamÒT-cQ6�c
    =D߿;b6Ue:|jv܋�R.O'b
    Dف8s<
    O'TCX*;7�-B(O
    N">)Ii=t
    *ݷAߞalTqv*v~zBz8ggH"M<
    0CEH=oe&c׎8}zЫW/xVQ\cWT*nj;8M~ȐT"jn ʫ/ t
    }s�
    i}WfIdhۥ5\H>m#SOD9Y1~Th?g8ҎU/:DGQf"|sp}I18x2	}
    sio1yj;KdG8W?g0zҝ7b Hc(pœ
    "n/[;8ρ?`J<<c
    \#?<r>1pPƼ!$˱evxউw`HߎJ~()A.1|p?һ/l4vl߉Ii+AmP[toG3}X~T;؁HfKmXf~<IO6P(
    B@!QԴOkJ͒tdƓ>OEz^Bime"I/z&=x<:KxS̚:.\<]ywrn"7ƢOػ%ܴKY]/?NUDEĄ1ca7%yXWA<NGmCND9h8k&9
    iYɡಐjqt:4kz-ʹn[
    _ۇj740Yc/>CN~!rEInϺ|-۠eh#S̙_M \JGp#*+"]Qi{2Og\4FvQ~Ci7ߌ7܄"\@aiQNUOdt]`WWe(Gn6#郿n7CgPXb: kߎ	)'1~(b"|b7CV>{ĩIu[i!s\zɾץ1_6,|/^\[FTbp
    l�zjh	v(<%ߊ#=GDQ;'q'w¡A<\D
    ч]vԦ	^u4_)TbUX##
    UwMl3;Z9SQнqD}#T2b_ٗ&J
    
    B@!P(
    
    "lݴMXM}Q##7GᢻV8
    t^nM=u5y
    s׬Y]蹾3]~Q~~~O1@֔ <#GI*3(ޭ8n	ύ+z	$TY"܎*w	Ȣ8	Cqk0cxjCBOaf<?s^[%XD@ѵG77OxڑEa[;@0'CGȴ1V>By!\5
    zS`w`}w&r=$~x=/iJ9/]0ok=HBsCXH=ت,ڊc;SL
    aCY+Lo3s�ϧw&3t	܃؇)w߇m%Jy
    8;9gcGWaױ'gx3nxXCwB~7uL׫L)%	juQzoFc؛U"j=%pv>gF5ѽWV
    ѰA(:�o�o׼/:D1qnߟO&Pq…\6xۼ
    -K^(4�ho.$axBQqԽB@!P(
    BFB_'R9Dz97{~s.G;`H,3nՅ'#,%8&
    #cIШAoJ\ԫW:[ x!?'k^9_/R"n8LIk*alҤ 6p"$2ARz{
    UDAH&G"9VR"bca"ax=ڐM]\E-\#񽐝4Rc�47~=r牑ߑ^ܼѺNn
     H㇛G	|#&);Qy6o%҅ĉCOhΞ<}9~Gn3Bdttz^|€P}<h
    [
    _iD}OsFMAbC5)P2h|x$ޞ'tRKHZFh /ƪ
    $&$M5#OtعASyC'vnEi>;֮cvWǕЩFZO}I^+H4%Y7;1~QgaA>Ol=&ғ8JXYbWp~*	1/ _lA#=7"$_)4hd6uU(
    B@!P܀>]ŷn'do}GlYޥV#Gy7j ˰/<)dqд=~6_dxn-D<ZVuj.A&f$5A|lѦmK*ǺU;1`<<}ɒ>G @Z>�¢H߲|C:j&B ?N58q$:5'km4,~Y]]ӧPN_U-T{{xD<ZA3&[VVj"8UU5(/JA]{՛he0>2	;ț'cۖhѲ-~ڑt]̙7Kd\@H3[yp,>c=?49z-CaC-,7=&"hte<yj۵CGCDhG3
    H:UWT-5ƪڣ$cl*#y|o=ɣ1v#Zwh֐&ФEPX߾wVyS݇h"6=$ZCD#| ߯.Cay)&?4s 6˷P`2;|KMɅD۰6U,Zۅ>MO	rq{ߊ>_Es9r8	O8I=M:˳oS}f-+ ї?C)Ѯ$CʙCx0 ⷽ[1MQq%L4o
    47lƒm8Ryd^uU(
    B@!PH]@nvoʥ3`-hFC8y3oCjB
    O>{|miMZbYH"k%ЅȬ3Y8p2~s|V|aa!/=|"={1g%oe8*|s5
    Ϲ6n?a]q跍p>uYAS]B|s:qDɚɛ
    4oΟgXVWW}M t9*iŒ%z8-b'}FH	"^D#I)x-<9m+gI+Yh#0g"Ts_|C'NC\y?)݄^w</~M>:Q'4|2p'\0aC싘3gDKCBkF8?}UȺ
    :7'Rʙ&vZzkT@xNlws'<0e3;q>!?vWFԱ/йy'"1·pGk<~xYFNb֛ns0#Rc|a/:wV؍pnՕN2X-<
    C[Mbi#W':hbj*9xaeخ1~ShA3úط4'-;G1*']1o=0ޜ_l:b-is,d44%7zG"Cp]p8dbF"9w]mS]
    B@!P(77AD3Hag292cdcŜ@%B_5d)e)ۓM뷅R|CNown�|޽=zwhb2QAaSDđ7&+I�^\XO>zkD&}3{,:0VEaцZ�?X=`�r7
    b:W:Uy
    ***_Zhٶ5š5FL(xk3L<&[zw	:'{zo_LE\[,{ԡ&jg]2F V۳@p2皋Sumk䜃
    Y'F?u@Sl#\g_Rr;Ն?X3)
    'lGIZ&zQ54AL_Zڷj@wl<o-żg@a�a$><fo^1yp
    7/ur
    /`MяD 	RI7[ןY
    Eԋl~_88q0W6.܊q[Y1Qy_j|*vF=&MB;'MȞh4	O,GK]
    B@!P(7"&Vv1nB;~X`OK]"|~Lg<68Z.&,SEb䥂ܛj$Ixq\ߏWܕyإHQAly}-м]O<׮;</,ͦL
    TEy{xN}qw#TĥA8m''7y$ۅU哱D6]0w2^Z=;And Wt\>
    $7O3aPS}"�Oz.-7*
    ]kЩi#v4й<]]H':vRʾ:яL
    e8ң@†abЫgw&dl.+-]ڳ&_s,*d/|lYOO@guHsC[YF5f٭֝v%r莆0Ц~Y!|�sJKhկV6ç_4CT؃@sَ-0ɟft]EZE-zŹ4ģ͏VR1|xsæ%xwF^T$\wӗ}!ԐJ+[Y)H^!AcDPBή4J
    !I	ɑh3Fhppqc(ǯE3IDLsʾ-J?>|DL̉EʩB@!P(
    
    
    E;vk
    ۢqKOL+_~N-iC*oG0ޑE#DUD
    PPXW[a2-y+
    M?}Z$Lۢ}C&X"\a\Q:[Zߔ/EJ\#~h!>~X3F*Yti-9%x!O-&WQ0\?Eg5Xn'YY;fnA'''8-_]?BC/>}5^~|
    JR:ܵ^0<=7Mr\EFזD>oH3d2OEmwO.#4	aK!xsyx/=2-_ÓxԒ}Y!i\9*&8Bp4)}{!.j+G^3MƇM辝`O;/_�澅قvJ;O*9Jj)w4큆a-O_z5N0mWڸǟg|odڳG!"rfLୃ
    /a]-7H*U`цej?|QYyxgэNiz}&
    hcezD(&`t/zƈuߖ<Iͼ�أ{Q|(5o,3~
    B@!P(766nfU-?޷mۆ
    """Id$fU6p5db}H#b
    =wֶ0řL4-||m&;o[X_'<l=@FD;qK"dǏwP34'TɄ}6sp$a4;
    l_yFc튗i2VWmѱpoDq&8Vm`WUinF[lMLgljh&&`Gk^L9tIt+"ZGbݱV]sgO#GFhnF'ttf{\lSPTRF3ڷkE.v7ݦ:-mׄv"ǖuF"L
    Lm''"YA@pCtԁ,$^^US'Oѧ"{\HM<kId7M4">u6hX,йMFY.u!-QpAnP6T %X{WPLA
    cp95eXxh4i=7]w]s.~ck²Mmt:1sNW`Ƥ	3SL^/K	.h
    cTמmsG?=8TzkyX~i_h	=ptB*yXg:.L^hь`F_}J}aHmfO@%u% lذ۷MLB@!P(
    
    Aй̬ɵui)?/Jr5Y!ooeee䲛pqb]vmlc#gd$N�DVT:?NU7&
    ՑOm0⻥/bA]o?Ε櫽}iWs'Eeh%jflɊ20ᮡI*/6i"BL]T80#s:Ӄرyɘ:u6t<[$o4~Wwf_k] ˍ\'vNO,}
    }4qrjw᝘&qhڴ<P!q%9W—ęSHHƫb+0{5_>4GK[#
    B@!P(njYUhW�]K~%Yy3*aA3;VgSi'0Ly~&q1uakNZ[NRv�;cq9GvS|-\?yi1)ޖ\G1DoM26:c'r*&-~,u^T^'km>[4
    kQ~MIOIM?O< 	8>{Ʊ68YiY8ͬ0qWONǟ|b.mrb'~c%Ξ…J"i~a1dƞuby66DtG|9cGZ2#oNޚPn;%cMiFsa*Ψk^V
    NǰC xśノ`/?ǿTA!P(
    B@!piӦ
    
    ^[YYxnUTcشiڶm\ujB@!P(
    qhA/..Mlc[gŖ0W.kI*syzF|g]zze0;|R뺊q݊i#֣;ѱf$ֺHu/Xe^ہbi0U#[Zt|cY,WKutD5KuֺԅXCeY2f]HgC%y5оW)jkm_.}ǭ׬?-jO89"Nz˫!W];:)='z4Tӱc|G,e{ʓi\
    
    B@!P(
    	KG+߿!!!HOOrss닂AFcA߹`0
    "e|||dEYXvttDii)G˼�XGr&\']|	6usY֑uurr?Y>�a9g\vv6Z:qn3ú>??Vn|ƦJ`%'9VK^Ƃ1~K>>֟˾btԕu_q%˾+nXWՏnyY3g,?<d_]n,%S_fqX[ʯiʱ,.VcB��@�IDATJ}u_k+_16b,Hv{[X`<X6JWϾ}={G
    B@!P(7WtqgСC,ҲW&od<~qk.)R!e s]?kA*˶^U_R>_khBSZ]ߥ-s֛%t%\NJ3#yX+߷kw#W˾bYz_IKe[]OK>K.bQg]UP(
    B@!P\bAV-pVի
    גjeZ^嘭|
    KYU9,|?S*ސYג4;岅<UB@!P(
    @,-M2vpY.gYʳ1׋r;QW)wgE:U&\beRynմ~۞Dz+q/EW1|5!%v'J'dKk�Qb(�þر\sq]m8ELkoy8GGz|_WZuYgYRzr 2j7XO7=9z۲+-{N~ MW2/[JmvE<\=[]SW%<f݉GR*
    B@!P(n.!C.uuY]N-uuɸ$= Y=n,Z9Oް.,輀-&h##$rXF©p=dQIhmde9X[?>ft2dEWg]36:͍}9d]jYܳ~\)ѥD9yd;e-e48ׇg9tz;#˫B@!P(
    BFB_jZu%se$p8/}G}yI!bw>	x2(Ut7K"QܿDŽܙ\g%i()CVv.Th]Eak=y91TW!--
    e`U#B&$^T&?&/MiZMYY(*AY,\g&L$F\׿^()7c}2ibdff@|3eZogGeyu<xs7NQ\Fk*׀:VgRZ4JaL2^^9/失gD^vrJlm)PQ.PbPEг'+-G\XˠcCڠ ޹<M6-!?h0uU(
    B@!Pk+]P+?3cűNl:IyؕV5SZAV]<<_ހ'O`eLzh:E3&w`x2ػ%EL{"jޏv#sNasp>3`{/罧 ^@Cpd"ݒ9{4_{N&L:E4`w᚟)(MƒSnߎT~YV^#.WvA3N:Ͼ6Ktb(JQJ8^^@I33ËƘ⥞[;n=c2ʡ ocL9cP[FǔL/5UE%~^=uIjK;ok7lR,ߜƺ0ZET\9SHPSZ5?Gqi)!/=RT[OiZ
    /ryh/,kǒL=a9UNp;W7I-VՃVM|/7fUEӃ(
    B@!P(nCnZ,>f{	lMA浭NنG;PG7c`]xqidA*JQ'G]G39GAX_jMvGl^M"+Ϣ`$OgPcKȊx�*E_ciiL“ zxfFY?&3:9QWr0j3Y/|6_RKuŞ�DFJ"%01[Iؽ' D56
    
    .Cg`x)Xq"Nd
    �;Gh	/7抦%X5Z!Q3z8PY䲵<}+UR(?ߛ=leb[9^1AfiW>^_[}WV	͚缳h=JsO.8{y䄃ep2)DŽ^AAF"]͛e{7TQB@!P(
    
    %kЯ^qUejUz"!80h@Od&bHCp6b(tuE1܆aރW'iވ;"ѢS?о8Ԫ?7ls!`ENh&Lfj,lݴIqPjƍA&D>lP]QwXhDfZz(1o}
    _9F]Эg]ll̀M<QϠC:7<Lzr>[݃*)g%͛Cgeۖ":}ܐ0`gۧĝ3Y:?CPl1xxXuc>	@A22,'2$b€e`Jue&`Ӗ(<,84$>
    
    噧P~C8ebۖ->
    z0d0Ohb$!斡Gث2Ξ]#F
    eؾ;@g?
    Eh�zv7թe{rh[ccѦklv	>08ҙl}NƧQvB]1oR:vb8B[_o$'CF@00a7K*S#GEMAv]14ęزDVq
    lwyEH1-8d;yDe$eYounW7oxۜ7!1W'5cIn#1{ӵhA*=;c!$,C̑@٩9`9pRWB@!P(
    IQI&F^<d"/ibiX/	;ű_CZ[wkӊwċm|;63j(5ii)·wuu5S o5[Lq8888`o-3�VMǬ?Bn)۠
    "ynw˖Z?1SK"D͜ /"|0l.+B_Gķ6]ܹ"a>p&VY7Mw~4IPs}'Sμal1"T<`(d"d}w؛Ew1LSMIXeX|9G~_vBA!!{ ~ٲi"ITVR<8U!W"bh2"^mX<'>v¾EGav:1C!8/܃; 'zzOشB*kب
    >t0F_.zM ό_T>OwD.
    Ѯ}[}=6
    |HL:HlZn7<4<)6Phm;WBc;ibrl�;d
    #]KsS`˩,4.瑐]lZ"mB68{h8rߑbh{yY)aCļ}vbpߜyI+"TƱ{bꤱXbǞy~R'z'i	'o!li6NG۶`W~ن7g޴\�<yB5-Ƌo@}кfq-7}FdO<3yX۶ߠ>Aw9G!P(
    B@!p @r5?oݺU;}x7g7FQfj	B5jhyF.9?5FElZx+J=VN:kڣT:LMSyA6cvkEg{
    -%9Y6JME""6j6Z\fs(xݧFuA+/V}@[hF<ߪLFk>`_sZkٙkܬym_P]C"o};DQ2v>ڦl?yvKDZ^1-N۴/\!J_;^,z0JOV|ŲW_}XB|(ZUڰ!C['ޤ+~]6e΋>BHC`VjgNYEʵ_zP4y-Lsf-r=ZRܑ,&,C,~6~"-#W\zxٿ^`LJx.-.2Rsqw_,!aڙZuY`='E]?u7j,t~1D#D^X3^m_Ғ<mKVP0FX$?YI'lm~u6SQUQцzhދӴ>ۯ+iJk6Ԝƽ(J[m˴r
    %Uky1&-i͵QZnYQg֊|_hGLΦ䋴GR&k)T_kUF0[{mm˴ڃWljk{ Bߵ}jG]ׯג] ăQ(
    B@!P.bNDQB$̞2ܺuAM0(,E~~)o#BM"ѱlwU+=4e'‡c`pҝ\/TWW'@.SZWra'dxX3zɞ>d-&Kws r!JZ]_1fULZkh3BӮS$Bnz
    j\1GiΘ0t#	Gޱgy# k+6n䆀c&ዱqAy]څDueև2*)Y1_e	z.&98™Y1a23#>}aL5KLV*dE	INl=^ŏF?5#?}49Éi3c.
    W0fgncXhe]\#DbCHOѨY(*Sҵ~geg<6"B/#{e.flD*++o|0eR6۷ݺtpro#ƄX]\֬ď|F}nDcr6z4f;z~1lѺpajTUac<�(>O!$RA@QTQ*Y}6φ FBH#Ιݹws("ݙ33g~3왶>ivnTF?3Q4$'& n`~()%hQ>b5n<q;.w4^~
    B0j{LIlL""*cĢ%)Xl{vVҖfLCe98:gH3g
    f_ÈХU:[ZB@! Bp#`lCYcc($Od*/Jig2PoZףy+MƁ{s
    2vy.Op]RV/<2G`gw !*O~4m&Aٝ5֦Z8!i{+SY6eYn4GO?u4A4dP_¢J-F[
    O90@}ϣpE-:{#<u8ܹU)蝹i5ol]3aG44Z k1ߏ:(r9qڠKDVID|0
    ^p
    Ə;F'mQ(eg	))Ο7|Ȋ?M!#%=KtǐmӧJ`Dݏdh`'êiGPJÂbW|ov/#gôK\l|i51-DGK`Zu8zH0RRѯX3܊ѪIwjɠ?~\thCk-ގW둞9k_]q"MqG\5ٶr1Ɯw]iψ[Q7K!twu}*ӽzm:"-S9|qaИF{ |,a%"ÉK.HzFypwy
    bg>?LkfuPY3I7Aei-B@! Gr^d)l}I_N}1kx}ؼW<t$&&#>.	1;mh'xaQA*/o[ln7])MD3Zoӎ´8%-(dIJ
    4h9[@n@|b~_|3dҥ4N-5U:1zدCM0{m:Ъ{ZKQC)">Z%ཧn֟OmX
    /OepGƩgK[`kdZdi(O{po"M3'u[`q5UW_;ލӎDf%٫4@W2]@D,&\;?0_{1b"Q eyo˜Q jmmw>BZn1bEl:VϢܥk;+SE.uEE	:7M\˻g"ؕьq69#u|`n_e;$8aޅ7gƠ6_(\7]V~
    RN_rN>'Loڳst쉟}[2E#-c"|ض318gEKd]}{fA6`4Z]N,B2zs}2Rם#lז"%#ĩ|9"!>TkZ�)VcuKi3N1pe"˥(_+K{}_'&]r›!>>%޲
    T/>eXGZLY_:¸hۆX[zwSV#N! B@tܣ>o<>\r-<g8f
    |F'{O0`㲳.BqTdⲡxSxϙш6^Na99Hݑo]|6<(G<#{ƐOmEFQlZ6zrRᅡ.]{G7L@xlY`nh86PWІ_~[ѵp1~U	Dxx֋0\hf[BA1.N?x73+[#la/щ>'mVnsghO[=r&qzEXvWl+i7'1|2n?'uH<8Ɵwt.V~w@x	M:l!d~nǡ¾4b	Qشb&hԑUԢŷr_�jr
    j+Tr`чfH򆀵GUxlذtn~
    İQ{'ISFPU6yv_KtI
    ;iy)2
    !uh{9"ex!>79/Ǎ=R^}`yt<~)B3P\9PB3oTh2<;q�
    z_1!xV$BΚZ5E�nCj'|+O=t-ziGy|6ל=W!|!ѦwQ~5x1s>KH_H8Hj3g8FCB@! 8'[NchHJJB.]lX&|d痡5Y}56ѧafl[K#^7#_LTYRbk=*[\B^OK
    SÛǢmRᒻ?P$SfBw?ΥtJ)4市vA=Y;R#-c'/XFBR2'FMNL>$:S&њr�UFcwDqi9
    v={A}θ"{u(Aۮ={s&}ʕvos-[k,މ:&n45
    kGrܢ;:	Lh^V:3V< 2~:էͮ+LD}Kp<~RT^!4:ЂFGx(Uau؜ISyO4|8WіhIq!�IVVNn0j)nvZ&u	42*鶐HyI�tiI(s=5Cirn|W6}*Y!to%u
    RRaGV6E]ѩ].c=Hݶ
    Ӻ-zviXr-g6TeQh(BNJ+im}^hՃdA\R[DPZjJ*1i$>%=4 u2ztBJtBbI 
    WW!3k5?*} '3
    Y%ud4]۹[7Öl$̉`F6+.<
    <횠}nG-}T}N@! B@>
    dtm�$]=_-P67;-^^´a/ގ(94;m–CSi8Vܝ
    MH@cqvᙏSØ3\זcqwyڹ`Oz=p8tgVN==H/ܹ>OJkyobMegƕ-T\ϴ<=3k4XƛN7f<_ݗ/}So1Nr.B@!pw֕
    96ezMG]&
    smZ95/N97y7r/VyՇq|hXi= gVlGry̐#<2m;=ƌCnVʪ:#v,z.qЖٸ,ae5.#&�ʷmGj@z䍸@H>F\}8Y>sLSFFjͣdt>Mu|
    izц&k;1
    t^HC3Rzq\q\n$5ԟk>Fjt:7#yӺpɗ>ڋŕD4/n\8?ÀaF|fGI
    ظG{q=D,zF; f2g
    rVwz_B@! Bp 9sChӦaRza((`fݺ#
    HхB@!p8:9%%zm,@QC;!  �;w.NoMQSwj{?�5G	݈Nt.^g! xx@X}gF?=Gu#)fT.ɟş#CYl)QyA`Fгhf
    ℀B@! D`trk׮Ŗ-[N)^qM`큼Apfj3}(Η[nNY&9?Xӈp1b̡V)%! B@rktCs'Ok#o͑:7i4u2y1|4Gg)g֢{,oSyfΝG9ϝ2܄ӏyդg&=k㿿Gyg5od߁y+#;2<6rM=5=ԙ|s5unpsd9_}?'B@! {5%E! B@! t{]ΣbFP|B@	蹌YJ(B@\y;U*%B@! l&
    t`( i! B@! h@gOB@! B@! �ffd{ΑE/DBBͽT$@! B@! ؃�xP?sѷo_9}gddAAAO푛x! B@ߵhf̴LW?V܇K:Alll*@o2! B@! ^sO8! rHJ:B@! ?^
    tb=9sK}2|m~U<u2zz7aGW9479Yv䍌97Moq<']Y=מ~3yG㲞N]{۹IS3Sv_$gJÝ?|-
    Ǜ|S~qLM?&ONy9:e9uny{+gnM9+JP.CMǙ[J3ڙ	)<gz=ݛNNYܙwk*7%kutw;ޜ3ynx3a2#gq_z9)-1?os[}t%&/#{ q7x;zMF{"~B@! B@! 1b]$;! B@! G,1Џت! B@! D@é6D! B@! 8b	~V\! B@! 'bN!! B@! K@#B@! B@!p8p
    E! B@! XbU/B@! B@ÉSm.B@! B@!pz)B@! B@NR{񁏷``"/]O;[Ԧ}8_^w0:9yR>llX?߃7dG'khhp!!}kw%s؞(z4Y7z߃]-4QL! BG^ff~F32gAmF}t{3W^y{#×zqLNS_^y_oR2pgj;zcϋ{x5)=[yp;ζJQVo=Q&WB@! B p
    t2\WS]rPUۀȨ4CuErsPCQ-d;ʲ"FE˸xDHO^)̑VSYT+4iH>:ݞi;C-а-=.q{)L3Mގp(cMz(um-;n'rG+IS'̻ 9EP##>%h}rcvMxue9\RnaБ8kJeLZVQi9B#!.%}M8`)ȤR|n7ٟ4LdVIYQv 8,rL
    FaY5m̝͓W[U]T
    >9cE=t e1Nn܊o! B@Cyfz_ƫ
    ^}5"5P@/j^^+wg{/EKLn\Ү=:vh?-~YXb,]
    ڐ4iXJ޶םӁ⟅u0񫷕Caj6l+weFh,]2Lϊ>V^^FzwXJ5q2&geӭ3[ƾ3ik>X̴mX/Xq*ktpˊjR,m9TTnW\i'TuZ`q\FW.}L\-Y0ǵ}9/[.	]w	t튮]gښ>nQ~9h؝{'CGj?-[Epx\g9˘iosxQ\mp6jQ`ioG1aV|7=ҳ=ϝ5G7|t|/Z3?y:wsz,(&fI~&<]:vZ̓wksf,XO?sm,uĝ~o]<ùMyY9
    ! B@oXNo4Lwgo7-[rmN<i8 0;i*}
    BglG	ConJ|*w_[Ѥc
    5/VF浣<]%2~z_3Peu-kųNMoII]|g\-Û*k*|,G2vzŊWގīOކ[47=s~ۄ\` z_v.vYxMهFҞc9>Fr&z2dPUw^ocοGHDTBkemݩc=[ɏ*}F-5[^
    Q]VZ_E%.I:qݧήb\%pg&ƾ+$Hn:sck	A|R{0ٲf	l
    \4;$kz2x*eAϖ_^a:❇w_c}3÷pOyB@! 8	4a7 t~=B3MQW[`$d,l۞Jy$;B#48@4Mĕ?44.!	<J#3[LhTpD`˱?嵆O[nC_uòu(\+,DBbZ4e]IxghvM/x/v}]
    QZ^ #5yEKlKCҍG(6)S23"d FZƋGVz*RwQ-ѩK'DGp8PAFZb/qPե4UneLFNii-(O@ bbb:^kEuvӬ0I.ldBQZ!Ju+6IrQC$\9~\LvilpW񒄂"=-ZĠ([?TfhuLEC]5S#+�a1F}m
    	T#ʖMr	-Ѻu+D5 CN2ؐm
    qrpSpVLG*Ephªk)?B
    "5`b5ʟ"d2w-Ad$`ۦ
    @ъZCv.UpMGDXj`uDP>�y-塄
    E+*6.)qx*,܍;KvRڑ4#|mAQߙThּgܝؖ9Q:u"=wn^>DCd?rwBΛ|..C�TV"*S=/7>:zwiOgĈ�ѤuՖ`.8
    I1Ćxa)?DpGKTNhKMXͮ
    yhNO}%mي:?nН&[ȯ:wEb\47=FV?	mڢ]rk&`?B@! B�^\)6,Vf~_\h^jUUT55k?cYMG_Fem].C 5ozo-yono|NAє^Uo+u,I*ʇGBoyх'}r޾NboxO~e.-P/3Yz[uW袦EkIr2UHsoj꫊^Tm=ϹNjkNetVP/jeKCfD۾~:YeT^Iԫ%sQЧL껅knVo@_RwvzWi׽rqTMS)R,Xuٴ%*yuǝSVtc*eU_瓮wk"٦ڶF=2Fr,;›U2-Cتn/떨l:SIqV3o~}5GTq*V]N-~Bs{SyV-s۬37RcYy\zjdWڧ^6E޺S+}͂U]j]Y^v=ObTuq=uzb֯kWՕw7ҥ߫
    -Tq󏨎1*JwՠκB--SqG^}q>SUӯ{\eӥ;Ԕs;j[ˮM5jW^	jCFN-+urVVfzx}\-TZuj6o>F;A}6k)ܙљO}ԤoQ1%{V|8U[uJʪ+Q7^|+\0Hwʂ3qB@! B)<Ź
    -٬'V'LT_z}1SpzufOK&q(V?8U
    l}e7-km[/mzoKCj^~5=Fz1u5]/ď.K_-^^}#5s/qCh3'?*H*?}:Nox;-S7pzwY3~M]p@oSUA%U]6ʏwiҵ@{"C@=:l[�uǃw?6Xşy]\~u|عjƼjŒꎫ~yYR~fHtaƌ1+
    w{<I9JߩgFnJenXJﭏVׯV=uژ/V
    l:U=[jcUMRwsaRi:_5?wīk&ݤ.<ko,y66hθ*/.ҫR5,_9?^xn5զ:O6ЍGkSNTZyZWwՍ- 2\uǥ\r"O1S@_NMǫ{|DMZW͍U֫&]{m>xpOTv	]_Э{vOB=қj̙VW_h^ReW7sߑc7OR
    jVHR.|@M{2~wQX
    o>B}\v;~}ߩrTUvum9GR}ڝV]Vi%he_ܥr:˘T}xTBv~aǝz]DOiT{Kjkԛ:2cFbRδe\r³,ms&\|,k_3֫X~ξ\mNGI! B@MOqOMݼY?Z'fGG3j/;��@�IDATnZ/=c©#Q
    kgTV\JSUi|Ys'wꉫn	Ͼ?-q
    ;fXCG4I5BDө=q�
    27!+^|V݄S{0n;4mT#9n
    VTSNUޘz]i5GbR[i&Ly>>AP^T2,و{^\={英Ŗ2T>{K_8r0x
    o:t1||B߉x'1jH]4rVJijfjI-ܶ.
    GZ|='.MSy۴+>wcᾧW߁ރF{nD+g׾e3|34{8\r-F
    365!XӘ}kw_ܱCe\l~JTTb:]:%`x4"]ѮcέGk~l9G"aa7O]	x~nr9nazAΉWqoXr@K
    ZdKnAl3r�Mя4'))ڳNBm[�֯EVAM)wLjQK1x}bRV߯Yng#_^c]K#c;D9ՠ ėKAU
    ţZ
    
    ~}N	<74g%b;ɿ4-=G6ث2"g=mu	ÑؚvM@4ꏞDƿnAϘ�DǶ!tL�(DTz?>Հl-f`pѸQHjuH~^P'/s޹i:
    π#קkV-|
    =,s(X_72iJpp0),_8;lعWCݷ
    )SЪ[,Z&m^(X_]7\:zTd.64#)?XL' 7PY09)wbܨ!	i?TF'B@! <-(�z䥱z(]+>cBՑKlHT|jQRLk
    GOkiz`(%O:3odl4;+h/IkŴJGiݷ֒F]%9;0^m>ׅvf׶Wi!ؔ<wŋH:0j;wbċHRC1|`mӏfCΥZfG#cSly\vg[9(BˠZNg)O?>pko]QC_?UV
    ꍷx!q}8<Pag'*=zh4ZJƦىndHSjkuKr<׾O{EXnp5WZ||lo[qU_GnrAxId</PQRLn3j
    	ɏF-
    Yx8GChtk;>@K,wgsLwCA_,/>yfXz|iC>22ZRd_oŒ#ч*־1Gw6iDR<~E)EK,9->T4MjtX3ʗAv;S6G!zj
    
    z�:,q]Wg6:.a$:ʭKO ^e8Нo濈q WϝC%&Pm2H$qJh�vo^7ݠSЉ:7C#rKQBńPan"'B@! l
    ~gץK7t޺p#6&Kiϲ8h0dg>q_zg^F?w,sc*
    IG?ySmG};&`pԧhvGq>בq'WĀOqSPF;h<_4Ѧ-)6b+4)f 2h$z.:dȠ"cwihSGۥҦihJ;9镝q^
    ƺU+OieXփM&<QnmpwZwd>Gg[D7қѴc6ٟ1)M
    U:Lך.=##4UTK	T:~Xn2hCU-_W؊cY$Vp!Iwv:__뼘60sA^Vl>dDj@aܴitV]urpڙtEdiݷWrCI'Ls=t>ļ
    n10_Wlm6N*VgTUw̢V•T<l6S/;{oXN$nN+o�Ќڠ7.לXP"S%fJ^y3’2ڈ0BlUe5姣Sx,|;?G"f.piaJv.0*5t8?	v_XD2}*t*NYrntGm=fYa>ĩº\;`]_! B@!&m>ݏ[kF=/?Y?`΂(;v??!rVZ,3Q楛{v=GŶ͛ɘ)@>N֑xͭFS\\sW_Mײ:$y=Rƀ~}i(TVZAqWX7+ DX=펞i3j G;4Ǡ
    q@kwfwm_M;LNTL+7fݚ,=רo>*A=Э[g=E8/^MJ68FŨ>Wϋ
    '^7M9g�]OFSD},#:|ܾ#zH증ۭq_T.2ӱ5%yy=}?+l.弤>FXekc㲑kF烀pJm>ze:>#4{f=QFSQWY9s" -?&Mc++Me!mmҲ3c>ʰbr:K'$B0k/=m_'N\mTp}ŌtN:f
    dgl2#B~LUY39"eCip;,v
    I�ːL]~VHU纰g2M'nﳯdbݲxz0P_\TL4Ah߹zv@;:Z'AV}2_3d/.|'Ly=C9(J̓6ڸ`)aex{8usnH]OÜy[{}&Y{N2][DذMrtΎk;g|~>Kžْ,Ywqߺv-]vn۞>!ϭS#B@!  ˋ㝩-?w&+3}kZ]{2ST'N;n۱~τo$noɶ
    r_;WMˣ4vH޸O:ZUDeK]Ȍrooww2XգMs5LPYsMw‰ԧ*k{Ė֥eӞwǧN<xdUT^RWWG9<85ءvq*R_+h=	r[Wdard՗>j7<^̽Q^jѮxoi
    U/ڔ] CҸ=Wj]i-i+t3ѶܿDeo].9޴2\qѦn5%8;+SOMw4?UZXn;,Qdf^xRרKOp1vɮn)%qV܋zCU-0yhOYƆ4-bԼVQGP}$*5v#l(WONO*UKf|?5W[5Aכr,z8~#Zy_c}G|}N(Tkygu05zW͙0U/~xԗihOPZ?κA-zU^li"˴~`6FܕFwUG~+^Ѯ\R7j}׳۬xGy2=*NQu
    %>@R(W/?4.+	cƹ6Cqj4L](9! B@M;ybO?Z 3MZQT?T?<WPdtVmIClRyY4^f1xǐUΉ:oMSM&E=do*l{
    !q ;+%V61qїo⽐irkGzlش-/
    kW{%4<ԉ04o1T
    $FcL9}XG:wAcoasAޏuƜw!%5Fqqɧ!8m{ǧ`Xr
    }6;=C=.&O>�jca3:<
    ~#u6mފt歸uH;r8񿐶~|,m)6oIAMށgk$NW5QRT~D̟i6o>2h|V~)
    캍kg|
    
    X�N1hg	uk8w^^CYVqH[]'
    _ǃ4=fl߾?G'ۆC>G3!-1c2toH<	#-ƴ]1j	8NqEoeLsɊ*:
    7i%B5ܝ1	pSpTvZpI0caem\6R;la6u
    J@i$>xf,DAE'5f!<rN}&u!qI¯y+k%m1E+oF#
    o/L߂i+{Ba{0pYCi7aYe8w[J;	WCEbD=4|W˝vqhNK(h$ڴcE<߱m=<#ҥ#]/<"Sl؅䎽pȣ$YU͚ь-!"޴y;}>�o}WD-/U/=yŪ+)?aSO5ܞCia1dҽhcf8+aqds!LH! B@6{rp"IѮ[JSC#D)K7Oo^L˼dc
    Qu47{{5Ya[Gkh=h`p٨|
    上6*~!d,Y	xIX:XFj֥G[љx\\e84͗x3odFOĆc#Nez*]4Mqz&M+/ocZϝ)_XU~V73vU>lAF/,VZ4BO	ff;ro~�OA穿\>]*Vߜ;)Ey~\T+vGIN|{x=Z,~)ch**o.Om%Wi穗SX껖X҅fvzVs|rzg^;_YQwqћ:bZ{;:S[MKoiMu/AP-?K7o3hI%}uc!45ޕ�+MUӏ\Q[{Tp3v̈p8/yk|>#hW`F{[ܗZj0'q۳ſnUnsn5Ի|9Mֈͪh
    [לXWϪ'22Kk?3
    e2
    \2`
    _Zьe;=B@!  :	{0//c׋1
    ,(vm\/lLӏցlhiiTskwn-@:hޣ\%i2ysEH~Iw8rGFN=ݱ,cSx5du
    }Ʌr9B.M΂CauJr		fHclGNONݸheW]֌>X5w=X'W6t=ډfE2{w{yˋ^=P,6,Y?4jqGe{_8YyXˏ▣&=CNڼ0G93^C"ླmAW;̕w^߲~=k.p|0p,Ɩ)
    8y18{\HP3_)>!as熑,l,wg-fN<\m'B@! FS.#^fHgzy.K.:_V/5a|m33G3Rh][/0~1-3Rgt;"c-~QwLomXW#cp7~FۑfK4q<eLNter&.Wi',3!rrf*RKsmc4SY<9?\M9:썾Yht̫Q�]oېMܳao6_Dx=Zq#9{י©#[F>kK;L}G ,-#<F8Y ee4S4*`v@m׳ܓSg"x.&Ӏ~g3W9B@! 	@o,.WB`
    [|	;|	x[~T÷B@! _b/);Pc/+&!\\/dݲ#&2r*B@! @?Dc{G3O"r-B@! ?^7ZuCH! B@CKݵB@! B@#GtKᅀB@! Bp! RB@! B@@?_
    /B@! 1=B@! B& ]Rx! B@! 8\~Ԅ!B@! G4~])<wy:N;qש4ǜ;?	3G06zxx^;:ύ=m=ü{;x眎gY2qkgΝX3̛?-ISƩϾd<e=M=zkv|&-}#-הӟ=L|#cƟ~NYoFLۄ=:sv39:w)c3ymd̑)xʱ)kΝs-<:3aMqLM9e8˱oLZ#ρzӁ$Oٙr:;:ϝ2M5aM3gyvry3|4y3̜7ƾx&9
    ! h›! B@! BO%tu=u-h.B&`=턀Bp!W}ؾ};M;\=� ף:|"' MWp
    7-%Q{fS΄JG߾}]~6)B`?	aVGY;v숚òd#1-DII	6l؀Ν;#&&q Q0@m{dcϧa�/>XZ+,�#�w"==[nE;8V!p0Н)Qy6mr7&=B@JlF%~R)KMDFF\fMKB@jObǽ{8TفSڹ.y=,,LNƿ|Eĵ1NrK}@ &۰jTv:q]yhvذgqBH$r
    B@!;	@4QgOK1g1}0=iHM\liv"+
    ̃eڻJ=ɺ:~(ע~mdlBA67ΰm_?E8*Y
    +@#&/yqG,d=R?wڼՊsbt}TKCc_GGvi:X73X$?b邬ׂhhqZnfdm
    2d䳁neW B@! +ex^{ΑtFּƨv1o+Yޤ/54AZ;)0
    79NM5E;"i}t('xEUy?jÒ\gǚ	ol1a&msHCvs#g:,ۿiQ{eAhNd>+DMPMF|C=akqB@! C/5͋bQN-[C!)&^MЇF%oǶuXjCHxv.K/%YX5'R;05Ћ/}0ٻ+`Qk쯦!'.;kk^pM^|c?{_[+C0qX7g\CBܳs=h1acv%F`٨{Z-]mk=Q`VaVFޔbzCvQ]1m%9^?Wtڔ~7q#)#f=3O2|PAh|/ɗ%k@f92Fk-eڤ*G! B@!~c_^fb)cWjlK햕spcsz6݇/{uv-/{k	/.y++c]nRPRm(l0,aJ;8y7i9wuvXv^f
    ~u!ˠf36`5PTn=m='{]rƏ>Fv<l_xglkB|1s4|6{5m܌5NrjiT2o}96-i֣}쪲>ƣ쬧u.B@! _:nT)[vm(2aQ[[1M'#8V3gw[qL(]A("ҿ/GNI
    z]/˅2۲((AbN|TrX~Zsg#9!iEY^
    kVa-jAd)/ː+qi(I;kz6EEaŦ0d:ҐU.4# a~)HU3P^\n}!9Swπ67"[?/@Vؾu=1t0b/!0:#-KqoDh>*r$׌]ΧQ4$tNϪhj-9
    ~TyMqo͏<~£iˢNt:B@! 8@[W2`HQ]^<2֫ơOZp^1_~7=|Zv]6G65WJY{n
    3mDmEnp>~>vc4i*
    _=
    fF
    GbܵBjZ/&r]o`Yxihulm.k�℀8<Xc@ }cME-Ƴ?Yჷ"R~X5-c0|ԱfcsP¬x?o!(&W
    64]ޟsQqhX4ӱd׸塷<6{QC	6yiΟTA3E߅.[':Ҁ139Jx8! B@Gm-)"#˔HE`/ƺ]'~Iy۟ptQv:_<1؎4Z_Djx[22[^.x)>{i~ɗ?g
    c1r@;<l\~\9zKg`P$L8k44�?<gh7:{N!~eXvI]@\DPYA$PSU5W]p_^:#e{
    Gc-¾cIYa'z`eb<7?XԖ`Ԙqhӱ3ҪcC)aȠ8j t.mNJD~4~;ԇØ!]1O畑LC/Mg1~۵u>Ȧ^ԝ;1Ȭ�vth~(%qLFS+0"LtVG! /sYfW~ښjtzz'Z6wߋy_sny+xFoYѥx"NfV)!Y=r2Vˮ*kp.((ت`r_C;Hyйbr+}k얤Z;9i/CpשǓq~l|`jۭǎ_d~(?BoN⎝ۡbZ!wܥ0{ART R?0vr4r::ϐ%ANa	SRL7}~|&戇F*uxthު5B}(efx&?x_c>bݱ>8Hz	K! Bw_Ko`=bƹ^^S{!Э[w.9saێ\D?h{}Œ]Mm-kWEC:T]-ýΝw@G^}0|pտ/Ɯw
    6:nrZk7ӑLq-E�m/lT*|(�}ͣ\AaQtQgKD1C4]^
    p9Gn|KVmGI~&hZKD޽QξmqVgSRW\bV7ȭX>X@aCN	ȠgW%E4BmuLҳuu�VUdJI`轉"mVTvUZwuW]kWN銂4!!s澓pr9s;għtA OPL'_Rɀk+J<kjr %ރyph`�`FMʯ:~-ۿ[H>e("(@;C`/*۫RKKh7)e%(+u"(rȒSb,?cb{QCp&)WU 4"6ѫ�L@6d"kv:%%2|̏v_k:VuַlZgo{
    ))Hꐈ?Ŝ\MYVX/
    Wo \0֋"4yW4VH#Ż	8v(DD% [*N7:t4ZWP&
    ܳ9?CjzWHGJqv&c: %94576s$kj;�;yq
    3( %};G|To'g:yEG|SE@PE@9̻;W~bKҍp-ŸAP^pL=D7.VᩗiqظsfFyNƇ"齠N"^t>x z		Vx̣!-}N𾋛n댃F?LG4YhjȯZA㎋cʟ/S7o	SoGt\(.zrxdKp?x‘-v1Br|
    ,
    4H}+E }<�48XPRN)iEqr=t#!}m�n,u775eHH:s%3LFx/.AD.TO8ndd"$;
    n
    u	f?V-jfxi1C
    vtN\1+҅6*Y5)OE@PE@P:lɚ"ґ̙3ѭ[7ׯDM"rePXZNPQWPgOH
    ¯Wראq&]{c`%?O9]zpfc5d)N41[BDbȕq
    ~,ץCAC0x`_Z/HƘCF`|: tXm^QKBϡ+eHhaҁ'l;;,m#tZx|2z0=6Z.i~2mX'x»"|+**e 22ۍ++EEk<M+3}-+U_nb.8e`7KGy/(�tw2,i!λ�&c@;@sXHG?QQQfi
    s)"(!WtJl(
    Nwj,ȦD}R<q>)lZ7+q͛7#55U!><\%++qqqq6<yB̍h}Th {r'F<dMnKy3<5gyJטwge6&fhS?ӹ~.ü_X`'J;,&6t%YA9T\-͹Z7
    Vᑩ9D4E/em"(-^.MkٴF:b1uidwT%e掳{NtrRæn?oH}Xa-lxEV&U(-<oa<!!lI/,$
    CG@Fؔks7|&WaHf$hFTn5sμ)ńAOhMTE@PE@h4KAS(n[vTpYWS
    H+QhqbZ[LSߑ3Ein+Zɾ].D}"l_w
    -ir*:9�ሎq6kNٶBHlkg]"CN)^aZu�W σ("4
    abN7{s29N.[oyhn^ylw/PӁv:<;R(_E!==ܕ",[V	E@PZ;(<++
    hw reeeFuU<}?:f_I岜&4ǩڔ
    D+|6_öȟvF~{d_pXJg*s:[^ʠ-hoZ54F?9*"G:o
    W\\=V(@A`ݴ盝322$%%e/66(|by
    R4Lerss:Ϣ"9+!f>&rܳΛ5?+F?OmsĊ[~TX_m5n?ꜙN;B̃Mذ;^O211K,1VB,NhRZTYK47.᪚~D/b>:E@PE)4{N0tZeSl+vNFߔ2͡ݛnA|cx{ؔ(~h5܉ߡ<Nhkt߸q?#̠ZT^E@P=@C<E[յmآ;
    ܁{ڶ,=+ofp\]F9
    9d3x:E-" ky&;-EYP
    ţp@4j2l^v~}vzcanXY;_?;Bk422b(=tuaa_4<v6tvnx2n,6@|F|g'XJ_hif'rHy_w6mгώ}f̘sE\#{?/א4|2~z^o'V~?n:t^<7H}6qϮzcХ>ҹ'a.osntEΓp}<21au"(@SAA珙|LKKruǙ6PZ}<Go7%,|JoΓ2h4vN3DKsmZ;bv^Ce|7M}vyqIo&aʳsCoo %,\jj*x(Yygyi| E] 	+3ݻwGzzz-iҸ;D#5F+K6W"C}4v՗<	/qIwo,)|@e8-P-E@Pt;5
    8Z*"8iı}!VtpE@PE@PvD*FvNk}>FkaIy?u"вK7xYAϝ?ZʝOXn9Cf8qݺuψtz/[UE@PE`w#*t_7oJSGieI
    4SAANM.(@suϦCC67ה]^wq8Na"i4Vv+W7NƔ
    9"Ύӧ&NhN+"("!кtlS6œKp"	,GEy<q8ɽqsq&7V)Os,:NntP%|TSULD'!)>QkbcE`I)5/
     ~wnK*uJ;.7g
    7TVT^҄F|wŷ$,и
    
    <N0L蜜wѼ'Y]X5y_и"("(֥[heǹUg˯GNQKFjؼzRRE5w8;;f;O182:Q[U㮼G߷v*%#㞿{fQhbWo.Y
    LFnk	kC;xLIIA\\ϛ7CAΝMф׾'=("(֥"GkQሌĊハˮ
    A^!&5ŔزaJXoVZtYUIaÐ(ܤ`[+~]y!ÐޥcmqD/Ŧנ<(
    =KC0	[y4=76Z^xqA$[\"쎊<\@JRꙙ{%^ZTv;<sį1£~k2n5 19/SwʰA#1ƍaQQQƊγ)"("#P��@�IDAT@s@[c{XPpQY(#|g#"<!jtz&/A޽p۽O>sΛo38`(}6Νg,^;͜s.Kd^K';8hM&W3|g$u6W/=\[??އKV~a1{:geS]CAUl7.uIgKbf}j;�+ϫ_jxի,"("(eACVtcu!JHp0**QRTA
    UȔl[JGU./Fgֿ=)Qx1풏0vXo\~qOD
    ei8opPS۟>_#n}\uP.?^xv"Qe[z؊Uz8ЧpWP]}}RZȍT(݅2i_xTlJgg)~$e"Sk{i֢qYuJZ"("bɎw؂<7`=8J
    <4	&x*MqƩ1ѣ/&OB9m2	_eG/;?`󰞦^n+kP>*X>ybmnT8Tsl7yN#"2qш!Ka:{/1r˹5Iԫ"
    >VW&В
    Z"!t'&&*{۳W"("Tswo`ޑ|5դ}*iwjW!apHQtOt?` w@qi%nz;tu[VZvRCkk!O$iޕ{s]βV7dyVVE@	䝔HWo6fkr
    3h
    tg
    %v|DZdwdII	6md6Д}nF֊~[QE@h4KAߛM#/,'%p\ʱ_MSi(wDygr^P2'û}̚wG9^̟=ERЦsQF3cI_f
    WSEQX\fxT2O.
    okBV<9NPEPv :֡ǥ3OcCŧ&q/!m蟞ދ;۶R߽kyC7]y#Pi/mv("("bkՐ%|OQcfKtoPZy!*+GvqAey6eN?~,c=|}Sw)pOS#78~,ao(|pɉ3ދhCp3Vd3]3(.xξnl]6	=GEarpXb1t:๸<NPv^3M1~[tv=HD
    ;
    .ؼyQEgNt,i}W("(@+VhL?::@M
    
    	ǔ>D~==u]A7	o9CN^B^He7YO:jNY8y
    8aܯ1gBc1k/=|?j"~!q]9QIkңxmNt6g 91~!zJ3qkӏz! \hD?T󀩢kji7IIIFok7%עl"yrOm:
    +"("/ 4Μ9ݺuC~ecotlyXBw|4lsYrl݌-stܑ
    sN\W[uDΊ
    c5<T[Re�~=q5DM'i=KvyQ\e8w湰4M+amY4N;Oi9noNߎs7{ξkswtOKKCNL9^δ|F1zQ|job,6SPE`/ Њ-9Ο9V]BΧI9o#کTlSf)L%Z:96cioJ4z"3'1 sig=&LrB(@vM+aNe%ΓB~4;9a7/;nccc1h tyo<2psQZE@PE@P*譽T+'pjQH3EY<ʠS_{c:3u<\[{DE3v%$$㬬g=;V!2aw0.ksγÍ|<	4v^x}IMi(46?
    +"("^hTA;Pvxw"2îiqo+n~r'ӝub.ęp̧.wm\H#rQv?o}|644vئ6MCyv!~v]4v)4BZbBߘedfCK[#ǿay6$M}E@PE!UC#~Cv%Oxi%n4oӘQwHg}lt78[8,q'd:]At=8;ᵿ]e[+Zt*"0e_
    \E@PEAQ]:H
    XE@:=2|_E 44j݊"|w[*"(@+BA?0-2;n۶͜ašXxgpj1-	�	-ʖ.^kV/dn̼S/p?[x*svn%e(Nn[~-eeYvn<?2ŸXq[ʟb>"?ƒݲ粫V2tY^r;2ygWt<i	%,KHZss57j;w|+{
    
    z"o}4L
    j(Oj&Ps6𷙿˗/G^^9iBx("4@
    :d2.beY98d?|i83=;.k
    +˟U˾-[7h`$r.0&gٖAy	>RŸ}us9%(n;˦Nho溝-g#Uw=O~;]'c@itE"f@=)"(MEs{=z4ҵr<b>;E@PEŏ?1cƀg\YPE-#ШAd	j
    Wdgktx>Ois:S<#D;m5./x/9oOx)EBO-܇#[*"(@kEQ-*tnDN\,n;-QIUXY,qޣAbWqi/s޲
    :oj;
    }oV[(";hQ}/}K5*C@9VyuVy:E= p
    "9E#f(
    MvFi֦MdiLzZ";Gf_tVCJoެ&# #Lt~H^)aC)/Y*V'
    ("(@",~w{QR;\v':`9hL$n*
    0 t-*T=fɊ^C@7y.5/Պw
    o;RE@Pv@3tfs'98$Ԝ̛mN۲XtHu!8A(<┩ei,vwb4|[((:s%OҘjh4>{=42&[8bUݦ26<M.bH<e`~ܼ$.+myܿkNWc}[n(ŶkE@PE`F9*;?S/
    Ӧ[n)qrc9k5Ex/Z}>zL#qQ;mxzl*q7,zw3o}jGrVg_x
    YN[':>[./<ٱ}|iY¦!کR*i@Coo`PQ<k<VkE@PE@P*
    `Տ"Av_pUWԳ0R^\T‚BWV094xaX
    C:}i&Wyi1rPY]WZ}IVHYgeKu%^TW"7'E%|^sm8y~P]s|Re[i>"Z563C~!
    H5\>o5rO\#fp[V|¥VR*ZwɮUK-DqY5"yU0!9NMg|'C@G@
    gaƛ@nQ1^}.7H.qE@PE@PE!w%f/<:4߮[09o=
    KR>?<>dlX8Ӆć ,vҐ'Wfʇqٟ/Ð)r\q鹈`ދo	KqDڜRRqԩgcG!3ʣY]?v؍x8w]|
    <X~2>[⭗G5У[7~-7^΃q5#1�O=(Jx%FO:S>
    qa57xF[3p)	뼯�\};/*0ױ!ߋuopW`ڕx<Xp$r: NF馥x'_\~ٕ8I'~/ქ+!6AA@A@f< Ǯh+^}qvŝ|X?/._w(OK"o[70ӶZ*"("8
    Zm3hᅨ~z/VoFv84qObҕ ,T_n1Ұ||>v+1{]Rn]Spc
    \YF<}TvʂKyxϓ1cͼppH
    #A)[tX`ŒyX'x0H)~׷7;dᘣ0l N>SN;
    9x۱]pσΛN;_ͧB9&:Pe=lz{cPLy{7b1gΗNI	i3ƩǎEIsdt^,85(vE0gTfMF/@GDyH_<<{:0ն.ShOWE@P#PgZmB0|5|l+
    Cρw^=�^6d:(yQ\NӮcBU45<*258'pΩGu\zx/m�G<O^CExsشKߌ_UO9S0~X]\7Do?ϣ|3~R덗`t4<`z1	F37#'!vWՏA0M;N$Kx|u	ĝ~:H#ĖeM)1[Ei14 8hq41npGspGcQ9(GM:e\^G.BTLxƅ1s¥x$9A¯@F@~pcPaojIiAn|;m1wqӵi"("#d;%Y[q'C
    y
    UKp`0P{x+B3ST%ź֪?Q9/<Ɛ2Ok)#OW9~.	X
    3�K~E	b^f9/]ڹS;Myj%\nZ6RLų9K׻א|e@DPI}^O^VZZsQ%ߙi·̱#zjZCISD=y9)A`=><!lĥuXҒR:QS
    =>�_2n\}VN<|\ywPc; ψψ棧!!܊W(gD-wBauziZǏ\Ӆn{iþQPE@PM3<	wt=s?|&ݏ lYI9hm#e5l714E{9?<֯+FjL1]qbl&kQI*gAofxZ;)>-gX:%YǏʊw$nT|,#Lr
    mFeس7
    Cd[dD$SLt:د/(t\ad
    pȈjH	o\ለugs((,Op<m
    8]zƙ\F"AQ%tC>6,c|MU#o7ZTE@PEJ7T:LSkHd4""+6~Gax|q|Gn:^dB^cy%)K'<ƟĘAimaO*)<|Nz#κt+8\>8Dzh@Gt3KT^Y2g:E,w#R\rg:ٙ~cvEAaeo\%|ֳRvA|Rg]8Ы{*{`9O⮫E~Z4>Zc~(݂]Ya2ry IOit(|0kl/
    Y/ű߂5b"Ȳ?];&v_g?vztDNd7G8tGy1N׎
    gZrǞw-BAa)nr%DA1 iචM&*"("`]qvyk	:FeKwd:1B	kmBhd,w9PGc,wD
    vWl݌|PuOǰxٗ0Xɋ'+FL'tLTrdsð<yNQc'a'fa9+1q$96Ka跟COBNj>֒oZYQ8ӐCjcYErH:?z'4~^	G{!)d^zeǍcw;_`颹l7	;cƍMz<kfuJre#;֤`W!,o-~\x8#LSy
    i?<wӂqe!qTWw3a/sb}8Pyv54[^(ZZZj~[:q4vѳgoyqڻi
    ?vV}^<WUUUQQ2I>hc� +))AFFjY@m]*"(@#ࡏ_k9s&c#KkKشP䍬Rlڲ|lٺ
    g1dbrPDGtW^u>O<sfcJtHuyuIi IdzlWgEi2 )9q1(4e/Attx֗D۲sI5uf C$L*JE !1		f@Msk촔t:4m/CEz4?4n�J˫*̝S_\"G 9)ȗb۶mD[w^x
    <upyp;NIM5
    (7m%V|<sRcU9CU2Izk_SrXp!ƏoWΞ0#ा"(4c{8c2Jk:2&z'(L]tr>Tܵ;:זTNMَ!/;餱OqRTc=]d2$.r
    ?xFu_:;He!;auҸ4uQ=]ϘH?~AxS,%!>Xb8]c$tK{}mdEIa)
    ]ƕ^Z."q^<CZ_\s#3sqNnF腖R<;.a)wD(5>wM/q7"WE@PE#Rv5xv-gsAK9wYd-;̬49Ζ/S	ʲ	.gҘvurY{ywSs9gk
    ෗es6xD&ۙ&+9n-t´{@L3TE],	Ƃq|Y	qptd"Yhs>I3Ehy#Fv&tNRN/즵v˻MY;+T>n:;^{HwWE@PE#; XXč*�>wX5Pgr%g۲l;eOWy4Ɍ۱ͬ8ʷ[IߖS,">bu^硭w_^Bh)WE@PE@h^g CiK8VZ(DSh)NG~LU).11uˍnyo)9E`gwݝER)"o"Ш.}}jw/�[BNnT}x`nO}v[iԶ/do[JzE@PZteeeG(**+x|
    +Ǭ':v[?F|)Üy6_.<מϲs[*?Ƕ
    @X’ekcNN{=NtRl6v˵;-Q;nPMM)4;#S4[)43gT^.CԞněcORvOCk[c.iܷom^^9@xj"("РOݻ9Ǔa%7J^YYQcSMTPPD˰`C>^NSTukƊ$V<Fge[r"̋y
    UrQhY62O_.m6n;7.YvV+V3&
    cX5ğb%+?,ҥKk벌|)膡^V�?'7@^n!}۬^TAoowXۣ(@!9]tBj[d8hC+e4_mҹlCy6@ᦔ
    -(�AiihIII1܁ "("{+oٲ-„	rQE#Ш?0tJKnTrE@�@h"ȳ]|Z"(@{@Qa%ܮ)4RM+qɷ}_qIg_ܾM#a7;.t撚MS_Xhŷiߦ;|1Vؾ_8ήBm~vM'@4&>kHN7M ~6iRI1MK|;.4nߦp}.4qi8v<wܦ
    zϴ҄YVe0pc"S)*f]6VgӄӚf@8MfHz4ɫ5W}ttw=k"7o7;ht;5NŗrNKą^|JweI]LW_}ChApikXPE@hTAiߦ/|qM)+qۗ<oHMi$nZm:wŷi%γۗh%/Pvrh$Mu<M's
    7Ћ	ۗ|˗t7w4]NB9?Pa)a>>ve#QN{I RDR܎a[s^(B%tM2vؖ՝n5fWx*[,h%M|[.w)42uǛ.k񐴦	ivq;,4^m}!H4("",}߅I[(@0V3Rl`]ܭ,7Cm'y+ofi;ެ"YQtVE@PE@J([	܈?52z"د,sәvH7fuشi]2RX¤s*6VE@PEu!!حK>f7#Vv3{e(Fvk~۞j(i͒o0|`/<;TtO>++7oF=зo_#+Js1
    Ӳ
    <E@PE@P=Z<Z"ceg῜;^X18GUodnڀ
     [߀d8�1!NG95DϞ=ѱcG{Ν;
    222=,,^hE@PE@hߢ+Zv/M�~_tDvxB"p)Sp딱x녦Ybni/GFSo|
    ^%]c^wΛ9wwvD("("*h3
    :w24#f6N-$ex)9)m?\nM(=7}e@x{kG/?22M9t&^c'рJ3-Q("(":e>>6g7Whhb
    iv'>@"[Y)'tF@h"3[xk`Qt^yH0|Ϯrа2Uwl;n(JnZy+ROPE@PE`/#K
    c,csذ3†{7?w!|;́L.kN;rE@hsYm58_,	:#މJTUWLk"19܁r2l^"("(C`tY^Vm3p֭$Դ;~PZƤE֦q[A� cZ,]dm"-X~�K,DV~Q-q;\(GN6o[QXtF*6mظ(’E%۩cZid~^#Nh~;ט)@uV~:D/"෢,:g_y%4=ȯ/=^"*o9""Tx.*Ә˨SE@PE@h4}n%?+E:w>PTʋ>CGAnM5gp7kQma"Dze1e^J!DP6|k`i2<h`uQ73N%vA<Yjl(ƟGQ۩66˹oރԠl\38ХOY,3B9)\u:3d8\縼.QuYR=�?w.7_=Y	LF6!vUK%kWD5sÃXFq[|]ދRVfА˰B"("(G`:=ٺ|[[=qnx,/aiɈtcBLtQ:5TQQOp|r.rv锈
    U頉	͑$y�WVΩp6IK*ޖn3~W>脲2x=Hڝ(+rAAXwSΊA|tK|}�B圔\TDyAiQT8YDVZ>R#Le%((*CTl664!""y‰nl	жSSJE`"`t`وqcղXLlBãᗳ1Q
    wD#<ݫtw<cO|HM2
    n@gRR|۴.**24r	SE@PE@h좂N<RO9s1Qĭ!7D
    vRm+۪<bڋy_~W|edmW]ӎ8[n{]{@Eiz&~
    RB۵ckޛJq51#.~zy6֫tRʫF#pEgj<DcR|1>r23ڪ;y<p=(HE_ܩp3,HoU	VәCA$u$猲lK%T=.laIa܈>O>"8Rз~{mT{BP
    9^#Ҝxw8uuf➻øR("lރFjh t,:Z8-s:;6ݤ5d<ޙl۶0FGG#u|̚{mPE@PE@h54qcR%:*XG&uy^o~m%(݀.Y=[S8'o
    M=(UTELB
    .a:\~9x3s<<4~9b:%W߀cFرWa2<wu~>WgǵsrK5WY4XU<xǛ~2(<:ǒ|uk.GŊ~`)߈K.xŕf~yYbso=3/~	^z5b
    Epb<(^/p󝳑Lspŵwa/ߏ&7܃߳h
    ~.2:C,Ï<|y#\5�f)Qe
    Vy܌;.rOwKLLDjjQsrrj0+4윁E@PE@PZlA熘]RdMFCKQ\^p~!f#$ھ(hzvl\&Mv{Cbiz6LF>mƮ\d$>0==׬C1U <45%[11OZژ·+ŵݓp_r[yފN;td^v
    i/49Y(aQ1u`N<4x9x	ԃOA?>	_<
    7_{>t	'{_qxwS`tO sW6->LQGnڿ5xyD&8i4d<y-tPZV;xU};ŜH[ڦ(tdd$(\{I\sJE@PE@PEA|؞`eEld()^
    <�nb,[S=7\5F솏^.."HGxR/D͎w-O5`D'`I/G
    bn:ȇBIv@<x2:a^*>\Cu@U[h_+|57
    pFQIb=Ub>̓
    j/jK)8vx,
    
    10sji9bKC[߆U
    8,G;wٴ^56^PUDtlJ<MՔηFzQE@UyϩS),If^rVvA}QNr:!wt㼶cE@PE@P=nQ#rn	8{\yHBr\7b?Ld'릿N_Ŕ?lxeba9U0!S+!aضuD}́alSdQl,K 3=>ʳc5=ns:UsM>^o._S䰙cbLI8b~p5藞Dt$s(wbM[ah6cǝ`ZΛǕ#(lK!
    pe!@&)nE-̞AQt~/mR>JرrN9χB
    >O^[텖E@PE@PZZr=C{3~6,^O{v0W}iqEEf/ز'<"юɺ	deqqغ5[,_+<l%z`O+<>8דX>4+xޟ1阳7d%z_t{^{VuQ|hGt]ذy+V,Nϖe7boiwytg]
    KWn
    +nBxwO͠s*qp^
    _ s[6֯_Z^d6}}Jϩ_EU?aFnK'I*<E@)sXgJKGasd<ggn+Sh+%>+(9֐%Ngm(Y^\8cOp^|S.
    +"("<u&&herJOpl^yYTW"("{3	;;FD'ʣcBiO?]#PD~ѣo/wM[a>ಋѣ3[L4yl2^xn*#->y%LDS:hME=k/}Wn&C=Z1	?,TY0㬫o7߄>cƠ~`C.?`ڨ֓3Et3qy⑲Gq &";|6uv%==M_r$-<xf A8$:O:1Q;N]-﫩\~6+gm`PBdt5'r
    ̀YMGvu8ιjLx�s)sBR~fAx>nS#<HW]n*h6m\/` %2/WE@PE@h
    Щcw8*3g[nׯumz͛c><'Nt7MutFxyI̭(#YIᮦufmxu5mFhAa)\b\)l!Tw'۲&u1H3kVYYM͆oa,YT_"C*!Vt9㥳+z9[MV-[P
    Bj.2ca{5MUg5wYRB	f;nc91;9V3^ރC->_~fGgLJҍ�zQ݂M3#0㩛5!zN?mc؛qiGWVOC0=Ih/ތrw0EE<ԇ?>L"iJcu/	CQ:YwE>߃&рE}4\(@-|zoҘI3.\#*7U("g��@�IDATԇ@`>�܎;lfC5+Q'.ϔTrN3:wA+Hxm7fDg4rstvJNn1Dk9sfɏOHuB|{)6rqi7)iӝlI'~56\tu66FhdF#mu"0Ͽ'oWcahz'#ѣ){b9qfPUY.j14/#(O`Fד9p8)FfHsEޅ9,ƃV{0oݚt~ݩSE@PE@h0.wH)?7MÒξ(vi'j0rP6'4~!/#;O#"/skUQ[Ng]"]U'i~gf 8ǜr.~3nF%@by\r%ӬҠPdlXe@NawtRAn}">ES1}5ݬ!v4("("*;%+hK*iCyF)oMN
    7GmZNM/? !|__	MW&#`br}Priuq<;fԀtd(=;z!޲|>c8b1~9svS|kUYŠ5ṫpԈ,R
    wcaA)"("2vقڣ4�w)@"%)|Sץ!v|tb~AS9%|?k<çAG|ϰ1D\Cw8"H	
    & hei"("(@"
    z«E`B?k&8*{'s:pҍiPGk޼n:u4HiwwG̴u9:c`
    &ymQD:81423V+'5؟6K[VpE@PE@PZ<Ž5I%RE` 1V{"p	q!ṑp#Yܰr1n8dLQKEeV6ʋ+jq._U^Fz;k8XI}*B]*p\U1Ҋ0DF+%zNPE@PE"
    z+)*"Q؂nk>3yG|,;Jg~�㮽w^10^_5mְj?'<&ɓ(
    75hRڹO}8/Ń=eHhUE@PE@سg&q{�~nAx9شnV]RRlӛb:ﯾ8:]pd<yD$Y	d`)@Dn>̃_NJS<O
    ^B,OÂБ7c0[F"("({U({2$n#P{_ogZ(e8-VޣCڈ۶#/xz_Jyޔ{p[` OU}4("(@kC
    t([[TSS˽a(;�^ڑ?Ykγ!Iobp*>+pk ՇxGuIzw 홿Mxk"4y<%E@PUUCCy"btW#{fv
    	qnv܊@kG 5=CQGw$l3ϩxcmEЦqvʎ]"H)"1ZV)"(MAQ=33(..6*WWW%yQ+s9_F
    D(鰶$CdqϲI[C˲4G~Vn?P[O}wl!**
    qqq&]kʏEiE"`taܨ|8nE` 䠼}LZ"(@[GAe˖O>@rr$%%!??(++37 +HHH@nn)>Y94:+ >>?f62\QQhe?`^<Ag<h.nV_J6cŘ1vF?//(̥Ɔ	d/X&&&bҥFuq۹E 8;D'W@*.:(*nC}_f'E+
    E@P<R9-̙3Tқj^*-.e%l"ŚL3|
    U&47D+yB>(p瀕rhIII1r"(-wUKKzInĂb/X�`C=+*"bikB@H?sΝds ,ܻmfv;7gw;F%HynsW^['y(3\=n`UdCv[2~UǛh'7ڊUD\	<;^a?w)"xىǹ*`
    z"(UR
    t1Nƨ?7bf98.B+';:e+<◅<4,WF``ɝFNgv\VY喇&zUϛ.,veړSW*YiK+-_,+Wui_N2獎.yKoYf;QvYqt1yNZg̲uYY-A43]hwLsƅ}cg.Mb\TeqT7\S("@)@ 32q.]'=V|OtMwu"Wx/Oyhr8�N^=VPl49o13Kؙ`g}=KgF4)yB~.Y
    kix?aqt˶ϝ\RI[E@P7@w1IA!@٣iw>ӱ<KJ9կ$׉u[KPy2߳ܮl/qXNh6wzYS<z`B^E4pQ2 *sв48OEִ'2kCdxPXxZy(JE@PNNN#qp42Cot,wA/
    qHF?Β=QYJk=2ƀG鈰ώu6ÜfƝo:yv!fвM'DS;yhθQV_ZNzoye3zЈ/;Ӝq]X蝾)[_KzE}SٙU3nef^YfNzߙoƅF|0;q}9L3i%l%OҜ)O<qY'Ot&
    0;w&ķ<5˕ry`9ǩLծS:cr>!=h;-!tMuv18_ERq}
    <E&3n&dr�_?x	`aX< q%gBB7�1^E@P;
    },ư],&7E
    `:2qu|۾_2bDz8sux	`83H.r.|WY_	KDdX
    ‡vƅOh%w&/:eIKe7W:ߩξ37i݅雲%O%.W7pȲcqIg_V0{<=qЈ/if7%,Igפ4S3gٞ<>/g]y-Wb֜7KmF^~[7%a
    ~ٯHɷؘ556pso͏k9S'f&bOH>t8GN~Oqy3-fxy?{wcVhzE#y?-:u	<:3 =qHͰJ)W6=ͿĚm-ٜNPE@js{ar|ǃ3f⥹oU둝WTlټҋ=W_Jc'݁qzrxKx*+nHm:8,bj0]
    v<5_{3yznAf;tK>	ehtii5ǟ),@99Rۥ|21:E@P,X-"ZoF~Q#	xjFb?YArmNҊ)6|1<0.͏o,|ϖ?n>WjR]"H[dm}1 \NqvlōMAﻗr|8	$gf[d
    >Wrx
    si+阆pFb,'ٓ&fZxYѲm74߃;¢p[PE@(;ƚ3d=x۰p?OqC4(NL~rΌDPcgbns#l|ذhS+-#H)3ݘsnIŮÔ+!7LfwQ%t8F:+$~s2lK:JvS8??>;f),poh,NaKJU_PE�oǜdsŪ0MFV7E@`jjشm2r
    QNڶmj(m:lt
    Mײ;6�
    "=&O>-M"22	Wg?V`g\C6�֯杻N"Vu$�c5	ı;Q(u'}T]P]jEGe9$X"֬Y)=ztCxn*|2\<nRFM$ª5됚&ڣszF;fm1zP'vQ("J2Ћ?nztl\/wF6֮Y^>"p=4jk6BιGr2Uhץ76EdHAHH8V;#[VriGЌnJZ4` ]˾{#pP]m40,N˱yEDG3Тa+WLGDc7BNzXLD`H8ZN AKduRrKHFѫg7;Yضe;rӐvӼ=aJzmډfTטj⮓UyRE@!--;7᳟57L/&WY3d#!v=x#"AyIuF?}<6.zRwg翏gB&\$:@(j\yE/D6K{zؼ{c.jݍaoxL}iy@ԏdݳK;<83?مicݒw(5fQ=}'蒋qlwx?Û/ZЍ%yɳWރ9Qֳ%^97^׭!I{g$; MC>Tr.Zxw<Ɯ3^%n<
    _~9	\g)"(eA-uh|ك,Ѱ~@p8y lXooxqH*؍G~3x	^>>?{
    ǦX<2g.&"88:	v`/M^؟t\{Fo,cs~7vF2ꭴnhV;4|>M"v"pCMHC=c
    zzJ^{t>WdfL}|ұxt{HqC+{]ϼcIx~yjR||lt~5+bؙ=~/g{\KE@Pd,ޝhڧ4*6yxNvqaAA
    |)_`A\#L!L	l8}5A
    vѵq-7gVvCV,Y⬁=B&qDFv.|BpKi?aZu+'!3/'#8e/1>zAyQ;ϝ >]4~~9)@Ҟ
    qD|던zL/}_P;o9= q"x	{E=ꋱ_>-SǻAx},f?o3㦿CIߙ:t=qp$)J3."E@PT:5V4mscյ#Zi>Mu1|㮝ZXŮٹ>ÁM10_{݀=I=Îu.>dG'b_`.L?wxs&;{3kBߎpثХ]+Idžu"sx)Czbӥ1q!qW_1H?'ӟk.\bA'e_2en`s1gga{oCTp:ń%q9PdEoO>-EVy}̚("OA KmX;ڮD=-u622o}
    l3:A=о^lo$
    0o:QHbѬ1dds5.-eڡ\\!\|3
    y/k:(L̙P
    
    Ah@ ­dC-cᩯv"5�adSn
    S~M@«o+ǡҶoVSys$GS-pRW];v!'KKh]V>K^jjjʵ@[riܮ}ې,|&
    ЉwH~⍨UidX("J2ЩͣNFw?;]y)_EPd_8E "byk#jT[>s͗sU4�CF\	ݮ7#$q=^Sue=탚oka8l߼GĈ[fᝧ@ʱxjW;cbPG$oN:m)tŭS}ndzUhk}:1y.-}qql}kьsvœSF!v7͈hL+Ы['2ι+k-cA/GfTRE@#~L7a!d۫\3clMs鐴_O`ocܘwѐf[tjnD' @20kjKyVv;76h_Ա6e{61&ryͺ̖a!tl3$i{n"#wNht+m[]^?AWסV݆y.`
    bЊ2ػuD{ 7VuMѤi]?Zm'v^ :v=i>%]v3{ 
    PUW;ME@P#`Ze@0Z]{>L:׸:"Mn;~c9KSͮI�j܋|үvD"a/UkԪ<{oBw`]סY"|(X**<J1Ѫ91y<+V;A,:}zhԊs?e˰e63uոsRlؼ
    iw)0Bh fѹ@#FvټO>/g4
    ~9P("Da_!Cx=-/ޝP=iӅhz"|uZt-0_7-U/%:pNfR2疈,$[v0j¤]l;&P[G{|Xٛch83@KkԨw6BB\m4Aפ&^'\z.8w6N!jF-?1йK3l23
    GWQJ.[4^'&WA-ĮOod25O<ɅF7vK?ry4nϨ9K"("P&*@|j<_�9'"B%vFԌFKe1R8>5?Gcٛù}1p
    Am{p٭1utKL8LF4]1V]8=_DYI|tx6AvP ч!v pl[�&ɴ_<KGz/F#)M?o9nd0٣0`@<"|n!+#Q3r.=
    mFcώ-ߟO[<<
    ЅNCr6k}ZE/E@P&r{ƃ
    7_n2r붥Sɹ݇xk~Ͼ7`]D=0;s
    J/p׍ФMkc8wk|jěs_ŘO㦱C,<
    -[|ùsfb۵ƽIHxf̤ZogaOc!q?a)Վs-YcRh6-"3;-Zw~C6_@L/yW=!<3ci]|-/G+F"⿷t+k=8w0,LkFu=[Ⱦ/>:	x<N۸1jD3nJ/E@PE=~39AEQ&JNҝL޷y7
    @¾8,S{=zj.;0})}/?mیᛅοZhòpe3h$<1;!}:a##=~C/Fc+}wB(Cf$\?\٩5v~:Dvnŗ&NK`:6:&Z(/u.ca9Թ8;)ѩa |ae>=V\:b o,݌/MCξO0ӕMnƀMG 0_-|-z⌎,-/"*;6^GqףEᡝ4�Q멩4AВ4j
    `0[Z("J4'']{=zpLGT_bcZj/~w[3	Fv>g#)9
    cO݉m[sth׬9̂@:ڟ?d230܋0VU+xʐcSE.-iq~T;ljѵЮcgF6Ǯ8i'gNA֍D\#k79IKn70
    h?<8m;#C3#VUZ7Gݚ^B:8vZ
    0nܥh۬pڠMvuh6l4hFjZ)v`ı?	ti^===D&MhY@>IQ4(")4h/^
    u֥6*—;w`{nKI#
    D4{)ޑXj
    g]u=vefaAHƟkbxnSQ;mA^`]hvN]QFRm-WDž%tXu?+-r\QfrHKϢBмu;tبgAWff4B.tݙ_.{#3{vBlYҡ6ӐD]ڛ7fuvt0/`cׁDog+kZ׿lݼkEKuob]!4z�պ>"&;;:m7&&СCBc_"(@ff5(ZuWv0U_V|ֽ'?НԔ+KYA"8(w</%FZj)rЍp\#U.y#8->m92@<[j
    d
    U?weh"(@Wi
    g!Rڡf]NaieMWO>o_AAȧb[g5 uGҹI㌋,/t*ꋮ:ѽ<eѯ,4BʬzWuJt/yI~κQ:w_NJu⵨l-ugyF[ܞy)vdޕGtL_֛]ev;ٲ|_t36y9wҚrҗ}xEz`/L/\um޺i^i\PE4*g`5v.
    ;7xY5h"ȵ4js- SyƠ:冑(j\Si9z4>~\8&oS(iŝg\|wbnCގo_z~E
    <iJVYvm^{>Nc/tSZѽ<e-2ʢ_Yh*SʒUUs)yyw<oWr&` -riWXȗ4)܆YqÐCmqV]:ZzpHޛz姶pv:Ŏ/J03,\K"SF<v_ĬY}FYh)"(AT]
    yaFL,Vʧw톹ඡ&9Ұ\\tʹ^F/FUK䙍	:HN
    αAOV"~JȉGiq)-i啥"(#ZW޹˲>jVVp'0_u
    !țRzKc9=^N3"WQš'ٚ("CT]f͎;AҼzFpσ�QsJ.+KNaE9386D(XKyHHHsQj8E@PNKgׂޔ$~oKFge-kJW�/ggi\qҐ"(@jbdtKQ"<պ2ʪ~~~t<jKEvu,,qo24OPEέ,9r
    g!}&ZE@Poj\d9[#.ЙS�ϲpg}qaMp8SE@89hyrp>եp[9E@P @gc?@:uH###c`?%%źϕOb^2b]%Sidp
    N
    |-,<si/|;##|^NiNҲw?2XW9u:<[ƄqdX>߁+uLҁPzLW1LPiq\O<f.JY	_NSwj\#`Ͱztf]Y+l43l8&F$yygw4g0噴/y.<")IoI_h8i,w:7e3]ΔqLɗtg'2X7_qF$%%`x14RE@(:qΆ&tc)6-ǹAbQg[h8!)#gzcrl.)yXf?R;3b>euuz|Ƅǹ,ﮮ'رLogs<Ky;
    < :kH'mYЗTTu
    &UnUI?֥*W*'ny<::G)L,E@P'ރޢE4iY;8klܫSE@P�Ϟ/_gye;ثSE@P<!psCFřIW-x;,y=@gן-Np:ES2Z[8pʫxkϦkd?-OP/Ҩ/ouOoOodz|ނ{ow$%H.aٙD87<c&EMU,I3ir47fc9e-d3Rٙq3l69̎3FhMz]%})S҄_=L:L컣9z5'>S>SOT^:c8W*IPUiy_Z'w:w˶g]_"OA@VPUf}]/{5\#+X	UY=cWD"("pKtipa;pWt@uMjybP]Rfq쎦C
    me[!%J!3wRSer"99ol/$40(J̙K9Tܖ4E@PE@8T@NvI\*F	SxQ.aRoQ:}X0i0wW{ϚXRg2! F[*Sj	*ntL)I+t%H-AGqOeq:ӲSWKODevV2&a}< ;3
    Bjz""kQzuaR\F1PTb*[gaÆ
    -fE@PE"PDt*x‘cE
    3Bub9 7~_u[Zp^Awl};c/ټy!M=m)98p 2sWmml9]8aJKMoǝcq0>iPqh
    Z[ʱuc|l]Ri46uc9ަ|Lg~w])"PY,n-I%_%~'w3MnB;P4I&ǝΩD,n[Mov	rgC}<JkOKީSд`{km	9Zj]`c[bSE@PE#P~
    ٶ]5Œ )=J㎘t*_<|	|bMC] 9,eןG
    鏫ȬḍxؙwSq玉ȗ4[[aǁcvyܧpWpf3e&³Nz.eK+y-:^ΗowN_tc.cYnhXPD@C{͇o|HfnrCh7++zr<=5		Hwoay
    fbmTN<|R,6~gr\&s6.'ˢAb>D/5-vy9ɵLWg̓,O[BXKsq$!iɱm8]�>n
    ٶʧkw|)))hDmsѠA><s޺ukPc\mCFE@PE Pn6IقlmS𕯾X@ݝLz1ND!Zf[
    !~V-}||C!upҳ(:]Ŏ:
    t
    ?5Oԡڰ~#]:6`Sgn:|VҲ2ґiu_̢_2h@:\uOؽVyiIG%ߠEzuuڨcH).''/
    򐚚?0iuT^)%i~$4ʰ;9t
    PyAdt:}V~)"pJw9
    $ۼW>X%cKA+=?S&o}An&\s-{7nN,]WXّ,
    <;4mgWފ޽	7nk
    2'ofZ[}o[<7wր)7"q^/}&oèscGZ+~>Y.Z'f=I4K]w^z,/=KkN/̺M|z8:tiQuF?tQP{jP/^Uz<vҦ	y=**JWE@P*@9
    thfݏڍ/-'eX_߱Lv]=S&OsGxHU팤xY]['MƽW߉jadCwК񿯖ZDAA|/۸|1e|h&nJ"H߶b>2Y=<|l~SKF^!̡%KWmw\\zM1vK{{4Jۿ}:_q	5g6܈o.哋?'{eF?aV'˟띕W}(I{sgcI1}*&~/Vlewo>}&۸1wǓ3F\0VHE@85nUH˾s=Xlg%b%+cнe?y4
    =,m};&[75;
    ԏ{od6\ݝhLxXYO<i4s.X%gzorBr^|Ojȓ%I{CѰ~f6f=zB|hfي߷톰ef$GAWZS-?squ_LCl<=!lI,jkR1';tjc%p~%y5(78lSE@P@Vq5;6Š̆:GlIa~^}߸oT\ط)@<ny<<<C~M!8IZpG#fcwW^7NÙ@͸s[/w`ָۦ= (^�xC$'Gh{A[
    Cczd}aXyu
    cFt#3'BJ>xC1$[1cdFcײf#h!?'= &5B/=^zw=2h&g+A]ODDN[	`5(I@bn_E-AYxHHjnoi+/Cm~wȮkرTԬۖ,,Zd麖zw1w__ʪպ#ddw{nA1X0|MhIz-_AT5Ƽ
    82yX@:+.�?fXH<`=_$~uob[0!INj==;#/39BN-7Ҡ=8L
    O܃t%`{!,E@PE@2[؀ߗ~3i]Tr@Ȳh^4qЬV8
    ={wԃ?ǠR{?/1cP##]XW
    Ғ\l_?l턻"|4ä1i@޽aIt�ꏭ۶!*+FCKÎ5A3-vA{"nnޅGmX~pۍXZ6Akz|^F198
    c?u|L22b�$RW7
    غ5jP9ɇW[MO®eoݍ}E=6Ch;Ѭ.r1׺",[	<+_"<eܖ
    kt6tzVԠ-Raǟɨݩu[͚Qe	yNIïK}4kg}VdZ'y7w#cE_kD8X"#,>װ
    $Ӗ  w.Uim;":݆WQz��%IDATŠ0i8oGkZObd9yVo<Y#\
    2k{wnqkz}1}@wX nϘfljZRcZX5}E@P@tİ;r
    l윊ƁHON�/u:"=?'
    A3	}>ΧwprSԱ+w]uM=0\y7\DDGSg%YhӹmŎGP1/m"8::wkAO*FOa7h:#2܆.z^<H&-ЭV&-]pM((Ay䧟76F4o`;3"iv5h||hFщE	AAxexg!Zq.Ԃo1Y'Y+^[	lԪQ(
    hϹhA+_"
    hvׇ$,G\1٫İ!uF:$=(0�>Krhޡn4Vqd<,`jS]mE6SG޻
    Wb1aϫ0ԋEf~m~|6	PKKTم>w|6h8Rs0YؽeW,%^VgPX8lHbwQcѷݖpj]:aM׻0\iPvRPE@8@umWaWxvgagr <bLBU4P-ԏl?efRBwx%$o:Aoԣ)*BÇ	\pmŸk1)t\ ho_x\4*
    /23#~ؽn65"2g^}= ~GDt=WON~1N{ޛF+
    ąۯGBb*հtݽcy9?ua/ޚO
    :(nGq
    Vwe02#O
    ϱ+Ni%9DQ'=˳"9YHIrWGP@m|
    ("PymϞy
    i_TD
    $`ȸq,k_8�S]\N=jʾCFM־pYȘ`p<h^ϞiivނG_'ixRJ8^7DWGLp\&cנi4Yu&oڿftQsGͣ
    	%
    a4
    P7WĒwS-Mm5e	߬5
    |=8cߐVtzPOEBt34("('rYq1MMkO\,6hdVXMkAز<G;l*`ؐ{Mg=XQ`x5U|9=̞8쇳w^wG?7˖vG`Pvhܴ%V܊:ǡa(ɼhgKWYF\-ZY!Z
    LkԺn鳞S\m+0xwZkf�%Qܹ!0="D6z}
    `,ńbi|:4:k	YC9r.]5^kŻ|MPfki_"$dJ]v<25WN
    vv<c(}'A膘qt=&eaܗbIAr՛P+5a=^~4٬yJ!}YE6@j4=^x鶍4y#\8%bpwܓI߫z\>
    Cɨ/ږNZze[.,<UhX͓Pgbwb*~Fh?4N2z^>g^Ajg#|xxLMuwLu$܅O
    cgV㋗@BZZBCC/dր߁NQ("(Uj][)_x1T>)%܎-9cCV
    h^.uhaA>\i.=
    MоMs8o{Z_z߭܁={j:1N{Yp'#A୷ա/c/W,^/{pۭqn\7xeԙ
    'N@f
    vϛKϢYOh}>ɳNҭK~
    \>C|:y-}=nkemXA׫-7NBMD@z>5l?bzec.<!~97=e/ÎaN?~�wMjO;t}Odҕu݆\~Z:V�w^n)9&3
    7r%H?@ݺub̓U1*7w	3i:Ea3
    8~_Tҝt%-%	fÚwmQyY|mfHp|G8k$H̍\=~:P>^y|
    hGP7JKƁCAqirGSPdBz1\zdYwgXՋ\^(!AᑨN+rDh:4֠-PH"3!0]IȈE9>!>oePɥYI/ʉA|Ɲ|?<ӓ-*+6`|9Z
    
    L<ۨSE@P<!Pf]:CtM!5гp޺<jio5w Ri^zvi/	�ܬIJFhHDl/Gw3ԥDnn.~֕jG}S;-{ēiulu8ݝaXFmursKxy߻/:fglQ>q)) h=a@rlG\$9(+4i"d`ڻXicyug>4R|Z~l߿ꐩn?-:
    tI_8u5YT	#./dyBb$ĭFfO1kp>QnuY);kDNqDtSl9Ź!K(H85EA-E|ggwۈT$wTVQ@(rʧ("P;~t�ٹ3;܉񣆞?b1FD@	!>[@�w#DF-3whuXA.mT>^vmq9vF+aA#aT@2LJ:wP/tgן;< Ny/8pv%PԪOE0_]2jg!v<sXdS<+xnAOb_629~eϞn@$mkɲ˲Lg1\}p%4qbg%D,W%8(|ŊP!FxP>+JuL+S]Zi("(!P.;vg^..v';#viK:U6^Q2.J.Zȸ:,\ݡ)pKge:[el3S0py:ҭ4Ttb�&9Jlnl8rB.;ѓt
    JA^Z;V;Xne=xz2`Q_:82]Q~;zt;i$"iC\lŞb*;[qyć=_;fiA*;kTPE@P*@tiHdžNLɺfYU20zTYin{LǗ#ӗ2i,숚as:R<7�ttzD̤}B08eSN9>eaa~`}ߞO9HTCWE@PS@tVScj{B	f>OOȕ/aN)))kSꪉ�8ɠkw]t=OsPwZ%+"ODT]n
    ?rd}6"YJ?'neyrF@-W|Yxe5\ZqKE@P	x5йQٻwuKxJ?|ghFɤY>I-pHrLS>]*ZԿ"N,:u)|BfƒadLǎa:k>Od޴ioZ,\*-ƒy{VNoI˿~N%nY]߂%ieҰο{e=+{;\dᬛUe*ovݖ2۷[m<BQ("pbIYa׮]hڴu'70Vѣ͆;7DlZscB>;XiFؙk,6r9b`Y,e$Y\\:>?ˍyZZ
    c$qHNN.’8\)ٙX|Ƌi(d^S<+ߛ|֟Xo|֑/o2Uiƒ;e1[sx -0o3?c&qw,Nhϊ^S>?W|yV]<|V,_~[cJ~'YU|џ`;a/o}[a+/,|V䳮,[s+c|	DNowϸ{/ȳbwxrXߚeU<+.'%v^߂o)9_߭S3[%߭;ο[w'XoY[p&_5?\iӦM)"((FU+OB4]P"VvI'^q&/3V(_Axp%!!+WĠAj
     q:E@PE^3vV=A銀"PxgJ3#Drb>O"("("p2(@Q`vfڜmeiwBoNg<<3yazvώyK]_htE)ה$ݔa_h̓Иq3:}å/4&_i<o:xEhY;or%lI:%M|3fWZW|el)ChϺ_LVZ6xyh+S塭.&KM*)qy{}Wx*BGM<јB#y=Jɠ2LOбF҅L>TU~߉+"TJ5MUa43,44;}7}'3^Ze	{M)+yNߤ*_8K4_&_hDI3itY&7Z>}Y%ד|gw"y)W:lq.L$S6yY:
    .⻫9
    oyxNmEt1y$\o_NY\3S+SZo<RЈoƤ%ϓ/tVO!ez}O4Vw	"(;ei"xCs>[gNfگiLBu⎭C0W-=N
    -$y>A`t>e Ӡ"("("PI%
    
    S'ij8LˇiPf</'G 3'>t⼃(#	82__|4y)y4ˀ"r\
    +"("tde(9Ϛdh;^.fw׹u-F6Ӯ:V;'y}Urv{	
    ҒT"ÂZKPE@PE@8IOAE@P13Qx_ObDL2v8G=7/ߚEB~^6
    
    :xAY	"1)9)1l;:qFIڇA,c=h8-X("(""t*;r}Nv݂Q
    ùc&}Dd%loou>GvT4]zh5Ln4v^x6D>-coѪ9݁_)K�ع;
    |zX^Z@Hk';aK"("('	5OZ"D@{n
    Sf{{ţ/FX~ތ|Ԥ#
    |llL	׮r!:nß9O~]?akEKP}HK=t
    sOE[9ӿ+E@PE@P'c-AP {{%XإoߊE7uuFMg	@&sd{&11طs/cĠ3Q'2MKѸfu5kw#'/aaEph"7YwܹGI"("('݃~EFc6n»?B`4?wOٛ={<Z?}.YkcCO'dX³<;L׼>grsE{7v}nKPE@PE@8_KWN_;ߚ7by}j'q [~Ësp%gY4toqtC^Ҳ,<rp>(yHIIENN6
    F02'_mףVx:E?}ZsE@PE@PjWZ(h3rydLs<2st֯YgШ^
    ~
    9zOh4a5ǥHKެ4Smz"UD]q-p:
    qEFt8j6LGuqօFeZ:zHt4("("p*=rU'ԞIZx1҉ȭ[vSLEKRSSHv+B^j.ƙV&-wrY'9%qBZZri{TT'VMWE-m7Xj
    P'("p#{OX,c7##*g6s5�ͺ{ԤGKs%qG%''#  b�u"("(F@hU"p" Fs`` C!$$l{2x͙S9ϞQ("(",J5Х}rE�/RKޫuַzEK=XT=Qj(R
    t/ŎgNTSPG 1`[uRc-O:&"PUwz^"(U:wTvazUPEN;ソSRH{>"(U'(0SE@PE@(܇)"(eE:._*PSE@PEtDW
    Gpp0oA 3#ZgE@P!p=&{bb"tUF[IcaӜ0;!yf1.q-+
    HY.͕U4YgJ/o'x$})0{қ؉,t;}gN7&eLN7yS3l91tRS3NCifSS3OwҺ5̰K&4eE;zO
    Y0Ӌ,Nos]Y%|3E97/<"Ǭ&Ox7iǾ'zqKg|32$wGcqt,zpąNʖ8"iN7ȓ4^L,ӝθzKgwzxJD&:6zYKݽakXPEEК+"(@"S)"OEƄ?E@PE@P*W1ܔKPYPE@PE@PE@8x=T(e*"("("(#jO]("("("PP=UHPE@PE@PEtD@
    kE@PE@PE@PjWG
    )"("("{tyY+4v3y$lHt%O|gE'3nacX;ܥKsLs&
    盎	'aSXh&7yJZlw<8iq)rf9Bg;~_w9&;}S	ŗߵ3n-Ϥ6uH|3.4sI=I4fI+a3,aw|My):y3iعK4%PWyiiT4^g'4M^3l8Þ<3'aE3.N~Igzvfܥ	=Rf=#ӗ|/Iolᑸ%}q,S9MY|w|fyYOxLwa9t&ϤsvkaLw6L>gؤ38F#|$3;Z)fvzs:N3ea'|^^\^d
    My|)_|u%]N|wierD;Rf*("("("dtI\SE@PE@PE@P!uڵk",,5MPE@PE@PE@P< KŞٳ'5kf-w8ۻۖa �c_
    rAi*<I\GEBw3x\z^J9 @� @@|~ę<{ͿA^'<$- @� /ov[y@_e� @�_q/k7+s|d5-qxfe쯵x-޾ޚ{z7go\Yk}})xĔ9};í=([rWvokMZ:2.̜|Vx-Z_kshg׻W>G4f+_Ͻ5fSmŶk{1}99Wޏ䟝7RD#sDSr/y
    zJh	 @� @ډJ @� @�p@O	- @�8QD|	 @� @@
    8� @�(M١5t����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/favicon.ico���������������������������������������������������������0000664�0001751�0001751�00000002076�12657415644�020440� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �(�����(������ ���� �������������������9s0Nj8T#zh?\5=lR14ȿA)B,M8gUE4* <G3Upx1c&g@t����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/rewrite_backreferences.png������������������������������������������0000664�0001751�0001751�00000110453�11741262733�023517� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�������rC���tEXtSoftware�Adobe ImageReadyqe<��"iTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c061 64.140949, 2010/12/07-10:57:01        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CS5.1 Windows" xmpMM:InstanceID="xmp.iid:5967343983A611E18AFDBD2E847BD27B" xmpMM:DocumentID="xmp.did:5967343A83A611E18AFDBD2E847BD27B"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:5967343783A611E18AFDBD2E847BD27B" stRef:documentID="xmp.did:5967343883A611E18AFDBD2E847BD27B"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>#%W��IDATxbtwwg,@l8 v7n\14Pi4#
    |/si'7#
    UysP!-v:/.*�]e='Q6fdY?PpBXX< __OIuNl3 @P]WPQcS/G-
    dO^
    @	(hDԣuϺ
    $"t_-e`Q]vt
    d[~PEV [}iğ R[K
    X9^	*R*w4ry%36݆z+#̭ > -v.mٰp[\:6002C¤kѕw'o2aKWzhTdo߼'Mˑ�j' 4%pHpGFǢ�_}NVBi)C#cHO@vʔt4ns?6͗
    dƅ7"FF׾BĿwR!ׇ&9P/=-m�SA9 
    d2@He`:	Ql|9ƥNքTj!Rm=#qRLŁd5ˈo?>a
    ~yru5_<j8:B�4P�
    =\ehZ}c¯ˁm)ޜ``Pr?)ßf)OTjh:å)9P_>ܲlQݲ{5QR<`֢QQPՙ=:2>W|ob1DdF?9,̮Yqn캂h;p+lPY{j"[Ծ8cI2.Tt\-?q2~@pgdp 
    U[02|9
    &~j$޿y$ן0PJ`_`'C"m~uŎPv쿻ہlmĀ3@2)20C")e6Ě	cR$Nϙ׵ȵ6?x-~b=xPp쭳]{S_NaƼE`cnV&BŽԏ<A{/`ժ`ePd$c&$*3!(j_Aʘy	"T2vMq6mZzThcn}ϰ(R-[bdK~+eK^00z0NΰXr;g7�
    c);He9\!.9*:!?wPP
    -f[S-Xſy3FLs	F{P� Јێ;Fb`ħ[[=5SÕwW@rl\DOF̆0֧z֒$mPedM
    `Wad``x[0G
    P>S7h%u-8<=mHA
    S]yx"߮?i./hL‚8 ȸGPRjY_@uՆV[`޴4R	{8~ėsX�l	Ztl]l+W@#,Bb,x8@﷯?\WO؞E
    ͓,|C.5s
    V?霧o@K~G3?ވ9�-woZ}xnPm712
    ݤf%(2a
    V2>gի9@' 0lי2X�yf(E/i>!V&5mZt% 2&*"wNK!ƺ{3jl:|lrh^yQ(%wPaӲyUA@WЖ4X<ߞֲũ,
    $'4-r%n|$xnqE[Z/@cDoK\$P@q^[38){~e,,Xŋ|oO T=4)jgװV
    <1?{
    5E#EDxYpQ­G#,,PEc6�~LΝ0 g}DHYJ2Nf5u޼(Q`2wX\#Lh^=	jQ iSQ<i!hXaduijo͛"|}vZ4VMZTţlZR"V@ƍmPCi6�I~pwAR~@ȥ=V+硔hR2s`@ťZwtJ=)g<VbE=LP'2g*Åi1E6 Pp՟2r}E
    Wpbhn"覗@rٕϴs@M֩7~f3,lUE>& ̽|bP+^=]q$L1Q@+00|"$
    2C@O> WaziCfS͊Mu-DacE'
    y
    VV:'"(O ݿq(:!ȱlU`sp
    'OLI�w1e{,QBZQnmU0~*Mh-͖w\b[ym%;1S<:{νNņD3ι=~9߃6d
    U$
    _9u
    t|8\/\}_o3񌆉 iL=
    =wb>#ķ%7YrBkRā&iߤD>Ž;\jveRI8Srf)<1hȏuhWjT=Rሻu ;V|2ĕG>+U7#IiUVQ2Wϔ''.M4\zr$7Z֫5Fg8JͽtӃǭZ{7P 1C\&jǮ{ǂ"nbX4בf'S%y}YAC6epvE7/%+<ɱX*ƾyލewiq`k@+nOeVM"L&>aRE(kjM=mYY~dÜ5͹>>pVG۶ia:At=�>1ۼ?)::&QPn`bl˾r)$Mo<wuI#:-E�
    ,`b7̬"l:=wg+MTir:Mnx,2~zF[
    
    bȠvoe쑞nWnΫzuRQZn	J.OKY]a::A{}V@RSGt`4LnxpCA%єZFmS>5a<zp]P+x
    :,7>�C	KD"%h:rZ>CmMIDBTĤRQ
    ܝNCӔ{Q~E8\eBtTA$LX'7.(]@Zڿܨ?0A.�dYH$@`QeLI3yUx($
    9W`CX۹~5k:*7"q>w}"fcQXAKpV[	YS|܅<Q]
    v-|T9Gɨr60ׯM>hY@Ph`(S$(hmv22r7*GѼN,TN|R!½dQlȓ,|))V9{?[1	ˎ#\k.Z5wE.;z9/6<:\Rf<B~Ga;K;*7#~dH9&1)f:+a}=Zӷ2#`2/8t9-wL$|^?({=5VW�[O?CTb4vHfwߜ^&6=D iw<\<p(>'_(>_) 9u:.QvUG˦e?].>
    jxe<)'9pB])eQȇ1~K튘@3,,T,>Dkr-E`Z{I2f>/X:6R0o[ǑHpv<߂ԭO:ي&8n4u!YE{	NNʃ1It#^	ޘu	E)'RV^
    d7-4{17G2l~$IB9n=9*baz%G)C.?dwIYq
    P}tw:wfB"W_$EgYʣQ1�"n�b{>j)s-}
    銁?ۛ|>QYŻӄ�arXQZص8ŵ(/'-`5^1%6/\&*QT?,?2 GpXyw$W!uL4bfs1*N3=G7vңI�¿oM]jf]F=  &OniIrF>#1rnUb
    PԿrGj0@>c7lt1Pym׃!Q~B[Bp@3 R RpF{3Kf33Ĭ
    σð(>/ߴo0A'fŢxeH]G
    ԏΪqؔ“�$IBCBȣp=|>rR!Px(<?sziw20M;#öG$2Z8޸z;�5aɞwtzt\@!m1,?J6#}
    OdhJ͵z&�*[oxs֪*La3>kΠSXT$`꙱3}zo}q0g̕%̻K[2O3�`@.5vGj'
    �
    ޕR3%KJBEJ%*-O-"$HPRh^E"*,7sg̽rozu>pܳ99s7_DCrĀ~ ^ f.kU 5  k ~с&7bd
    p{
    �Av8!ߢufb%]ɰU#+hm9~K>P�C@] ]sV7`+7D?{XP3h|8/^%n
    Bc|{	2w‡ v.N6K./Ae狛%nwFzEW9G:By/GA!U}@;ip8&v)֍ �=E_Fi☹d[!MF#V>y~\6VY`�jY1ͮCЏyw'ӎ+GW*PFG|KdnY(V95]	И{ypS`q{!&cژ!n8'`1\
    -U&KS\RvI_Uʸ[(rʱoM"BPX3(×EK$V-O
    $�H֮#lQLHf=}zyQ9J9AFG{"U5QW$p+V?V'Bz3{f,<p}Sט(MתTw~svcao`M*#^ӭ3-ߧ
    ܾIr㌡<GΜ_�NXz&cq**WbaQ417ݠ-xE {读E˰�2s.g_ _p:-8B��dPyyV<º{֤Xa{-gD0Ή2rȒ5Si_]'9hkzBek]}%;س˙X(<\6yJ8F^pb7Jm4=U"sQc6X:]wiaxsZڍ{<Ъ;aADKl5B	^B@@@�Xe
    QMTd}-sD~:u~6Vqƀ޷ =ڹV"
    � b/]V\.aLsYPJJLV`T^Qs
    5UI㮦͘4iԹnLDv#BHCbljї=vԘԙ,o$ۡ_pKͥ;r?O
    P6[߷OZ[͔\#lՠ#Lֵ˻O!W#D�F6v@.Q!˵gjlBcDD7\{=k+Lh(xzsp8.7_L0rVL$)_dZ4*zX? >0Q,hÇJ{.L)*�=S~h[HhQŒc
    [GU�OlNd5!4Ӈ솛wjKϕ!ܽ7';<~u1qMIH
    ;K-ϻ
    :|79!he930wguuq:߼nYCj6ն039|%oF~~3Oqǩ\8mE=E.͢->Gь5VGv-qt^oaNYm=wZMZ^4aC6gYR8RAGj$rSMYz{./;Jv3K7:ZC^2Lۂ˷źɒ7/be|lEV"V{˅
    rw2\Lh�U/X،#4Ԅ�@S`qӍ7
    rVw֠A]klL-B^Uhi(t,%kx/~Cof)K74^w	#6bޠp/v'u.b"rjI`29=ܳ?vJ~l!<UwߘrRVch:ly52&5/H:R<{V&99)q.,jCuVw
    d
    }Ӯ㸫[}|1^NNxܗΠj{G/^|nNoiI;5BWo^'XCG,k1h'k9Y:~B+]@z7h
    f;c4Z$%Ú}-lѝ5i5rV?~}էm5c^gCvH%ʝ6ƦrY
    ~LOC>wsՙ|)+t,z[xŒv#Rc:?yD>ϼI*ٵ,->!((6,wy7okk֩yW_Sdű2Q5+) ,7cv;ݱi]qqy*q	H㆘gZAI""�6î=!vwHLvP!1b#}dy{4?X$&^Ȓѐzd:_}G%Ͼ?
    aj2F;tvkE]t?Jחx\j4s[x>;\,T'E2KAkN"ߺ_Eq3uK4{JD@9%9CXE?8%y+qr.zZIP\ٳjw%t_|(0pri`:`6ZT)Hj~myGTTQTò7Bq.p	G^cٲB\hŝ,Zu^@˽oX;C(SՃg�Vb"W<HUoE%YRl6RêDm~*."x=ϙZꪻ]F}n0فLJoWD(j+yFw7	ᑿrp;WhYJ�\`3#!:o(Bъ9[.FxDt|DSrj 	#\"	Hȸ쟰HoF1d/Ümzh#ʆ5d޶;6@6ě{+[ȥ$enJ`nd
    U^nT۸O
    sRymG]ʹ;_un`%׬^"<.TuTtjVU1|nKKZJWOln-*U
    ?znQDkRL@!Zl	iCk$B<0}-8k~5/GE.r_,C<6GBF\}BMD($WY5
    @9O+0,POq<u-nUq.rP)i&"<8hNvp:Id5]A]0dUͭX>/<rڦ:Mh+n A'vXFUr`�<cDl/I
    Y|W;^ꚍ
    joSN>Bo_8{('1e1X&`<ߟY.BEfqk_f6Iy̒5T>1wVbi׳f:ZLXG宁QfajӚDj>ϧ3|	a7
    Vs.HI׊T}͌ll䙫`z,k;MM^z0rÉ
    YR	6FAdo;+)/48JhLϥcOjV}>9:e.\F%Ow<!}G%XطZUf_,\[!`B8,4e>Eʰ|E|tj.aQQ"{s Lg4m
    'qDÙZS|ee
    	xâg]Ns8i?
    HklE	-/g6uQtkyI׵lHx|uk+Skj!�4Y__C/;ŅSڶ
    hʦ==*t֦|ށ,46|#W|,v.V'[E,oyQx&9UZ]§4dDK-~4,7K+hA!Ar�s;Q}&;3ES˗Lz
    6(δuCӿZ?	/=s`҄VPB"{9j&|OC+kk?(F
    Q{dHh?>#Z�x?qӆ: -	a$/Ǒ.Ks! 5@];{Òʠ('
    뀫iBQHi)#GFdd%eBEd{ɈHR!]xϸv[o^|?n<g9YDK6	B/!  �|zzqjI
    Zc݊gt	Iu<wbEE.PDPϬH
     8M>+*"!')H
    m]wCy, 0f˧,IqH
     �q?],qH_54~Y~%/p7i**pf REMxa-HV	x!`r-|<aC~\[e:uXDcĿMTYϷa[=ǚbt4yA"2K*DqR%w,(f߬C̄ xl8Tb1λү"]̷uE[:
    u׏J6מH9�=Đs/It1|Jw\qR8Z>I
    }m\dl,ldiiw8e5w\
    m2ps
    .�_:hes/Şw]x?!1DZןy|
    k{mju
    3 #^p	&n.ƎX})}ѾnEj&%QӸ=*R6ZOºJV[s8nk"llum9H ¸輓O1&iFC[yig�oM0r{-L1~g3
    8�d8F
    �E
    M5Yr56`[6gJfx	ʀczp!ʳOrLl)WȰƧpK3Zg|yQN8}BkݿVo	*lFEhRhW*^?Cs.wjk|\/W
    l�6d:�Rb3P-"n1.KⱤŃEr`MZ
    u;5|RJЗM\.nrԞk ,w	n]&
    ؄q]=O|?	7R%3i@Nvz{H[)�9齬dZ)U)r68վ$g|86�ݬ9R2@ɤaᣴlKZvp-5tB)ڜsQNg]n�/<ߧ>ySBB̯uڴ&aʒ//vvcH�ˑJ녳ny}y*0/z*Ny;;ZŚAt>G S$esNЈ,	c[}^2rȁ&/4JU^o�8)CBh."@#FJ	d"
    }wTS5_*6Sd?}c(04-ueA	0);W9Ŧ6[iL,~'qʸGlRS?Ph_ _|q4n<
    {kmk5Vv{yn7K;9Rq}	yhlTٻ	;՟?3Q_{Dܖ(EѴ[*0oٓFԜsSBxϤ%Xm¨yO;7{&<¸DFsDJI	�KUYIx�!bYg{JK^e
    Do,1 ;P$q2q
    Efd*7SZ*<6GkC%oL}?
    qam5u6;$6T(@Į3a=3q_,|y!%lw�Ku|?~�}8P'CfY	d715QKXE;E\vӳϝ&~0맆=LF3@"d޼Y*VnF;CJKq*li	˓PbB<ƨr)!�`jf&_w@Q!z:=2cL\X[4i{QU68󰔚}uJ,ʚ.-B*k#
    SѫˇhkѨԒXtENkgAX%>ʭ˩{ή\6*	
    ,ɭ6;)#ls7dp;?FI8dnɟY$1VDeN َ5nG :?•؛NղRsk9`1Y-
    G�赥
    GcJ*j&}	U%_JHg_N#]?r
    ;Wزɏ`
    FiqY@DDBMq%qοa%dy=YB7JC@@@�Yd
    5@PRD%|DZ(EIIq7UJeg+{J{L~TZ}-Fg}5-NZe
    Fgw!в|BSډlgSCÉG}?euj�>vsNSOcIe,6{uГ{
    'Oedl2i*J_cYS>&|޹ֹ'{UA8죣k*ӋMLF؍ö9N6dvkE\E8S;}#s~2ہr"]Ei?}~.3*TwOQl>n3pt#Uhcxs8aT*`v
    ,V=h4eS䁝*hK<0z{6529ztjc#y~t%'r2јLш24*wJkV^˳A6J7,Ok^ueq\*vԔh~M%(޽j	~؂^ZQH8_N;y̾e}O徢 ,#EkzVT|1)[#Rkd0|A*,Q#f0Hfd46rlf#C^V1-2b1l^nE)e�0|jjd0ޖ5iZ8oM4SvD%$	n<k@0쯯q0r_R;
    K#SWVrXX};3CIe/jtIq}^ffq!$txw3/0)COpdlLA+'o%o}\tcg6iDh
    s$eoq'0q`Ǟ,Iv;+ӱq=zt}q�rNZo#dCsGԴ)MQUWDv=cȽs4m'	1)6ڋ?LoMrlr:ybۅR##_}͆Gof|gM_2.L?S/C͛2º9ibb^'ߎu3wqyj;`,J	W>\uݸaևZ?z?j{4cNbޥW^0agw)HwLJo@!C-]u5�Fװ6kz~t»h1Zj&ґj\x`ɍGW[.%[7^4o
    MwB^))wRwBϯ:co�%3mܥJ\x.
    c|7>wrUkڶZ.#>o#T!_Zl?h_"b7͊r)c"%U<eMD
    bWeBRA	s8`\S/ôjZtajFX[4yu
    DGث~u(svnk}!TWY[P̟&(]
    =S[o.�gWq%)/VVyzY<8kd*wGGl[E0,Q/PݲZ&ۼ.Gs=c]{1sfJ|{ߙͲ$-Wֲ5$q:HalV�Loֆnca
    ,E0{d[CN^giyxT[L{NdH	fPDV64͂DoUalPJq@dBBB"8-)(RTJUvze:#Yؠ+m>_`7]R
    Wv_u6>3tQG9m:+?w9DJg_<#(&ͭYڿuNw``@�Gio&QqQ"R*A:\CP6*V]t3�$@#[SFk$ܵy:Zh/5VA\}~N+xFXF�e#	>]XEժd=2ߍ8A1M@$sNSApψ]\Bz
    ykZQB~Usc-pё%o@>l|bigMca'сd֖XWW=*qd⫥Z2&7n"HwzRKN:Ū4})E3~e#jٶ'*	vexJ㬅6dܢ4,@m2,)NLvsN|],BM+:C>2W`F@0Z5Ǫzv%#ZK�(K7\4ib5UE(3eUguȢL
    猫6KIJ܂>lYVJ֎?E_<|c}.1~E#.Ta"d7lTHBiauU3SG*Zl0վWB#gVaR<u/I&1^.jr
    H<יilBX<^Iɲ82$TcbHoV.=,*t<MIFZ%l?o~RLv-?:_j+扊7"QVaJkD[?5ǷqX
    G<yiEĄa#C]3JU<&?h>P\|sS,ݯxE惡Y
    dFN/!/TE%5@@@VTX.#+5~zw>4Ę)gZu
    *M8pxH*Ժ*_?q5'<. ".%FaV<l0sk	N~V#)~!"]{N)l<Vz4]~,u<Rk4C޷ݵz(>4k)/;Ҡ'AnXX9XNÛB*6em=hQX{#^[RCx&vcg$EDCƧED6]HnS]4Qw[)yc,H
    (tk+C<mn"p/yHA| ys}[T*hsoN[7pܾaLJ,&`Z{'Է]veuV۬}roy+t+~$8v>Säa Sm͈W%9oۣ.f'/=5j0~6Az'^3a#'*	NxCg}4uKzκ3gĘO=AKiIIIޑQ-O_({+-T56Ե;d܈fAh)~@zFKJKKI:O'QIyFAOP)bɾְ5dǜ�"KΦ<O8*ZOXx7rꋧͪö;?55sGs_?|sww\S+nMKL,qf:F=:DLf\gӃ}pжf%'�HT;%pʤaX?d
    1.[:W)AKHOK	@3ڨӇYc]r[$Q2Mj�D8d*Dž[D{(FKYS!xET7=T΅[?x3o$9}OX6u(+yL�zG^M@=*�Hq%"�d_*)BZx%u1wJz	9iDDBNN1E/̶[i.Y#ֵ_"x(5u5bDɠ6no/M"BڅՏꀗ6m&˱H~i#Ty>!^Vq{&JQSߘS^~+q)U7ZFf\93olo%$O%ep�W7#}"'g	#Y'ѓ$҆fq707;+
    TS[©U|E!tiB%B5k)E9Q/qN&etob9n*X|!jEBtl[/>~ Ͼ�r�ǖtct,pV~Yx`QC쟔8iϔqYG)9MyyǕ7plQb.?SMKM;E{kߢU#׉C,.edcv1ow⣦ |ZI^lNW74UHĀsm&](k`ot!m_k;1#7Q*4IX̤N@Aj_Ks:uÞKm=|iyUϪas<tv[bñfc֖_5F"v~PMY4aik(¬a|i2
    8*VEM\^
    K}C{ڃز[y-rR蚃w]?
    dr,ds&
    k	l9$ѕbJb.	x=ԃqwi*
    c+[ʔ0=E60Vc"*my^U
    8hF8ܺ7ƪ_7WmP9du\[t޳KWQ5fG-BZp,۠Q;[qAcݐ	EB@X)XtS>}*L ަ._?yy"U=dqWUALPiOB1U'\I|5cdU�nѪoO3�I@|.xurG
    ^n_XMU hlZ|n
    c1{ESl|e<>e4-c@mۏ+-L8v}/XE-FT,KɦZiGL\ʴ88S(Jtle}�1橽yzpbzϿƗT%t?WbF{_QƦ{>^'+5
    D*m~쨅԰lߠMIPR%.P|v]Q".Dc%+>e.(sz'j!0!_U\4l?9c׋J_MK<vKY-/HI.	@])Nc]JnBMRh
    aWqQD)sEť㖞0,a\n@gi\)kd7#[;;}cx0;{u\X֜{W�+Vp
    {ckxcNZl$1%0]pz7f7v?=6!+8RawvL0r{)rS	ZT'Dʨlj6w&t&F"V[7]~QGb{:8L*<֥w$c7OciJ\\#\;ѮE%fzmkp[k
    sGy5
    (ˊ@jR=jgNt=|"mDOu&T`WZ[b
    A/Fz/tm	l1z/w6Þ*)r6utQ ˩]+yI?K~#%ZRL殑-$q9n3#cVJt|`'TVGnx$;Jk[孰0WXy,xpy߀ꂔمπ2z8:БL|QX?P@^t{%K\H8"&bP\$`Z2)!01/Esדz([ڬ?KZD3^>.zE
    }rę0y¬1m|q#MZ
    I]a4CG2J^;*YS2ϯNl@#_]	 FbBgrSc
    w?uK1a
    I9v>p	Ks5Ut0GQa|^EQYlP{P2z")`M2ENѸb|XES�ZG,P}.;p셋~^/HZC^v@/
    K+]gc{NaXOFP8;bA?3/)߈
    }4557ݖNT\ Ťfv"$-(@ol8&{ly kfO
    ڼ%@/d
    =>[U[L1_${%{c2+kZu禺Ғ߆\*?t,xn?,cPjYd
    5@@@@�Xi'b@"tn>f-).)qqʾcు>!5 .XH_eo߲t~ ) ~BYD
    _Ljs!$/7YB>~w
    C:j`3#¿ϑy
    FX@"@$Q	9'@{Wcn{^J!2KlHJ!(JY
    #RICiih[<n}>s3~g9=?6..�����W@�����@�J�����>K
    S"k?t�?`,MfY�i��Bi8&7`Y<
    �ZsbeC͑@��xB_W�$l6bp@��P��������������(
    �pM-B	~,z<b@8��'�xl-QnhINROC>б5n3���J��肩ͦ7^K|}X��O��	J:\���ATHr›@���(
    -XYzJM,J'2t-		սyM2B3.'%OTK8}~)KTC䛆t	+GWu6q?2WZIF'°E@ 䤥`t!	uA3�k']((*QG8mbse#‡&QAϡ*{3=-?1i;-ѡ'%?=̋#G!_wfۈmQ=y"Ha	y8o.YgHyq9圍 RZYW^ ZlMe35=nulVRQ׏77Ȫ
    >;3O0s
    "!4a[=&69ѷe\e*."a"]Þ#^CC]7vDL).c{
    8$l˿%ڗȈHœf7!Ե%
    &auח\3"w4tnhIuG]`q-SC},W>oSpQ/8L04Hhe}oXl«v5-(y;29G*䥥D(��/1Ȇ7lajS~x.Z3SSs
    ;fJCٛ1;7ugT|XŒ*�X6eDwu>Wf=0.(,}w9]R禥gffeh=0,2ZJ1�C)G߾.;7V"S*P9}y9{?MWZSTɆ ,߷w-MMVXDߐ/ET| &j0Ohku	fcޓ5l6-KÇ1ugDa9+
    aXlեLnYSLŇq| {e.Uͩ6IQ[\WV!MHIת)ud0,#s/Uybt:B"?9
    ofJ%'GM\^>+R*
    
    &Tme-x[oҔIe}6dz",05@&q`Rl4h�V%:0r`,lFbȥ|ԅb?_#Uܶ?=Gݸ)+/;u
    *z.ulN~O;y񡥊N:-L8cmr%VnW?2w,b
    ,CE͓󉅪NQP7`�WmDauOgø1JB{q0<pGvg6|9Yր<SMtXI}*ˡLjMo20^8Gu<.&D$Hd2D"m#>ͻƊ1eŅ	&2';lˣ/s숑_D\IM\rgk/
    nI
    fFAne	i
    °)*ӃjbNߔnHYw?@2D(Չ[0?E(V۔ǒ2gߞ-,i�FFrzWijP^kN8smD,.!-l_BQ<9^6J(Iˡ<9Wն8l&﻽X^O q%2SJj
    
    tN,	
    L)^j7'W5cL CX
    +ɋGrv}#ٿ_̎ɇCNy,KxGɧb:�Q0((I+J_Q+&#WQ/^/3֖F|p"\kz^=r(D#TiqHXFR'̖ǡ;+voPyp>Ί80�4)5w'nB(~F_>{zamɔEG"N2ힽxP-՛2h?]KtQRY#5k6wni5ԜhGT`S:TqWF0ޑRP!PVb1Hkݚئ{ `1Ta(5rùpfd4WPーNXx΋fk<-ub![qu6^zՍ&qCWG^/ݾЬdʐONkVʁJٴa{֖:z)ܘ^Nއ$0ȴNDdTUbȀOZUYCVWJ!~my	SJMy{:F)!mX9E2Da4bsmyY9d,6NZMN`WR֝_xo(g4WNMzk$8kɍIt+*V5ؐ|upMCKů3 No-$Ƨcä6${`g^2#BCgubiLV7g=N``Bmʸ{aj2ZGzh3~40�`TBzm$Sm4ߌg5Օe%
    j%2q503=we;.= ;dmPb
    !aYb=|N)*T^WCBuMQnt}└Z	]NV DàNo:tG
    " K~^:/p}7W:7OC2|2N]{b64Z	*As\-g}#7[݅ϛl2l T=^S!9̚9F(/Ĥd)6C4G$
    t;s
    UAzfǎ0F[^s̀ 񈜴L\vIAmLfH,pg?E35JGiޜqfN4)ܹ̄L
    sr9_y˫1^mtLUloNmqA{>XS0;1ۥ{x]D݄֠dr5.[`6�߃-'ܑuZlwdFHD4
    pݏ*tRЯo󲚹&|ҽs:kk+hz7LaL
    Hꛘ)
    u[ӑvhZrJz&&G.lzңQ_AI9jbX,nnأ[::Z6
    ',@N?=jE<?4VSDG7XQ	:J+Dt=iܯƠ:ty#Xl..1y	L*e
    g^v "zD]lk|/wihh.!\;*0t:Y;9
    $a8%HjFQׂЫB}Ԥ`	TTAzzr*2f$x#g9d4!Hsѕhyw&,!${Ո�D8~
    U@24jW7N89cSSMTMTsBzJ}!N"2uw.&lON/<zɹG/tlT`sЉKg6>wi|"==
    |#G0cNQV��Ayx撪,{@xu}WDֵ"@)
    rvK.85ӱ6eJy|qO2!��eف{+_u:pĢI>pkDY}O9=뢩ؿ>v.!NW-)X<֫-6a6aub	@e0V<sl?Mŗ4=ۼиyv'M^?
    @<V�������������P�������������P���P)6"��J���|D9��@i�������ߊ{NK,0h,bWև+ӖaXH)"0Fی,F
    *<�ZQEEFO}Gf:['X_>-&Ro2kg
    vrif녖?I̛K.̜VK@*]bbFF
    2VU _cū/O
    /;LɌ\I),5gfR67\GZ)faZM԰Jǯ;l5LE6Eo0*-6{\ʣT<a嗑{\tWSC,,bf6@Klή$Ok-]cSSS!cLWJF/<#\^Ukf¨9H`:g
    `)-t!@]xŠ~"|H+>C_}ssӁF2X͊tny7OPR`f6MIUsz&ӷR]M{N7S<-k#1XzT2C9{\a>=CA>gd'g=O.m;^y(,F2R9h"WjeWd&c׃oK
    Vi%ȜeLxX$ѐN{KOfJp34!6kuy{`e)[e&"=OΥWTUEWG)r䆻q"b8Qxtd^E1i˝@Vi+.a38֑ޜ _.s[bg͊O!vX;ؕu%κ\y%=:^7OV{'7HUAfAoBPΪ݌'8տ#%\eY2\rW$?jnAZp.3<	Lf>^^T*7aň+y!dj*n'zÊ'AI9 oz]u}%iFe}_wFAQ73c^;Oas#+{{ŋM<'_7k׊]-=qZ7g.iɰ.ˣ	{;2Zz6+Xqߴ5*KEwoo8@Ont[\\:|u`i/\䦈U&}Y	9KP񍗶|iC=l_Zўק.JMM?hZ-76=v7@CCٚj,fd3ϕy過[=u%̾W/cĺ3V:<. &CUcZ3m׆kc~y/8.|F&5Zyٖ{%9`3(UegnmAbN6&ٳ̟e+
    M lqˌi'LGFѫOc q¢ҐS"YӚX{]⛽)Z|*ecr^؄|/w({NJ`YtHW]a<IXQ㥌W04~N
    3S]=dc5my]m>V=BTS|(|[>k2[$4}g"#mj}KEVEeu{$oB*MW_Q0-YAFm^j"8mVn02;Dx5y[H^\ !
    KIҲJ}~ͳCtlot:;b۳"eW-TFn%8/lwR{yd*T&B4\[7?|o؝Or:3&nؾZ:cI|ɂkoԛ[&9DUҾݷym~0mK6\V,%v5tr}	D3WZNF3}CC:|l›lBޔ}!q)FKw}.^9kg̊@.aO ohz)l*;)t;f0ۙ~Yܶqg_ m:11UO=뒠՛u{~C=XJs-PE۞`3.ghBp}E)>UW:̤!dKISCГ5m7JBm's<R./pGe3d:o!7>yAyA]ӧAD*$)Ĥ2 ǹ5}L'jUy&l&ֳT�!sYU3A=|qa.�.:o6"V(^_'axc1'w{߼"b�#j$t]`,٩)oA)n
     zFmI,A3l;JOSH2r=J0#ڪneMlXEEe؂#cb/B:xD_sO$)8	ѫR
    Wi~;sHfQpRETDn<EF]IbTsN^cwS4]G%P4m'APk#2@jcbXPgxO9(tW;vPX)y	M_-m]aF-9ϵYL>aQ	
    =ѺH#f1ن[}._eq,6jó,[
    zS`Onauao2iP{'d?Z^Pɩ-t;e!D@_TW]\_Z:-#vyW9t6Ý$^N\fDkX![`ѳl89%^GB
    ePh򣉾sߥMJ_/pZ+*󝫉8)r*
    *0nJںgAfc'@ǡ	Z<Y=앳5$ґu6J0v#-22m8C@&̏L_EY%,hLxUkNem>N1+lq6t0ſH]9BF2˜[wtkxw9(g[81@=^`O.
    uAfϟ)2aA͗R(&&lUUYvS_3R=sEGy^=\|޷-Y
    盛 hB>m<Y+Nmlf
    3?=p٢Ѻٛp*}8jiDŔ8#*3lV_oB&>P'1LOI"ᕗC;V؎;-d9odط}imrebʕs9j4!C{n@'d}Y(ט*<=xoᝲ I_ {h_\9ϐ5Z1\Ԕi
    8/;Q𰍛u!@i=Kf>^┣'^ȍ]`1cY8&VҘS##Z(!X|6)g!t+R),NێuV\=~pfP$t[6m/*ngg0*+$Dm3lo2]M	_Ut
    e?O@:
    JW7-4](jdS.a_�u+"bsV6j52|A4Uu5zS)9 	kD_tSrKDb`}?9s}Yip<=~4WS`0#hp]O8㈸cPߙ8]}{e4J;~΍YV@[_Cs>߿2?ViH4+ʦ%_ו~m\'R8a绨0M$iuuhLdư>i u~I7Ӗ}=&/n%UŊ)(K
    @I(+ʉȧHU+3X8BԖ~GgSVh9d©}~jLf7uy]6ԗҐ5 ĠA$8Ğ;񾫇cȖЍ:gmY4g6qFHtKOttiOUG)&&'RWFo(X0{mך.5jKn‰IӔl"jR}Zs<(̢+gݸx65G3YTw%#sF 	}Om':Jzg6 JVQ<`Ee8◔Ɣfrܶd96~{oQSϝ3)-ňkH>gci8vO]|q}|-'ogR|u'a#m3fyjs)9l;w'n7!	K'A~RheXYey9	~%ԥyR&g%2w۰*v0,~'/7^qs~撪,{@4OwZY=>D\HLLoPUYc޶]UdDQ+vS`"Shk880N/3
    hYK-WzjeB"~3.WWAEfCТ?%vvvXPm>emz͛ZJ-,}d(tX_S_^%)z_F @c0"n!*7<�(
    1eM۹`=+_$@c1U6NX'j?BK3q-[y.chЕ)nmGp4�����R^*)۵>\@�',"wKDчO7^54�����OsF)=;p~ßsp<����?9 $,:6P�����lgp<FgX~UI5]VC}c_eEcj15')ͱ1iRL,5g_w$Ą^Mc.A-LL:['AY&?K>xOU@g+
    {[/[ml{qg}ziYqr׮ȇ9[l
    77WDN.i
    ٱk6zE_v;r=k%: >:nIhjPY,Kzz%o.
    PrNKqΊy~񾤼f:d<J:ql=W|KݽdWXÊ{\ِ4{CR&$!/9/!oOw;Cx倢;.O=gKwn۷>On}-4@w<S4Jkrhp6@"Vuܰyjw
    +X/lY8Z6O$ <z½m<|u"'r+OaߑMYzEus[gaũǾr?ٹ^JIYOOG|6Uaϔsn{l3|wBgy-v낞qF[ܮ<1Ϝz_}gc%MrZ!H{W-[h|h˭yk';sg#͚<Zj
    ګ7y^vlQ7K&VUx7~DZ3m!&z
    A(mbaYdA޴3B5%ZUk8c)hк_%/RxJbJZbnL|U[wuayTA2-hOy_./+p{c֔
    :>6Jcu/fON
    EmXxieC|#}MdfSߺz;3`o~ss^n1p>j7DUփ/^fg%,	}&ܯ􆒔Ş:aπ%]lcF\+b!y,$x/a_ُ3cg(q݋8lonc}zzB~wg]	$/Fz({;z~QgD;[Y)A2ӎ}ψijcߧv]sl͚kzK=ϣg_<tu妘GlDu=Mf癖u
    ΀y]C' ]QUu]~\'Ĩbj4‰7.&U:5gZbb58rcbASl=z}J΃!PҵE.?ٮ Uh^iWD}fpaoi%յGkoN/t8MI[ٌe|+[kvm_pVJkBg}SN)']~@iT\n?W 7aʉ./vAVb+*nxXN:ZݴV!HYRZGe)5]h~ߕ5.ˡPfq|7f=Fi-Bȼ/-Ĭ|r/]cv>5uy;YL<jlDbpA/M^)#hwɢɖ{G4R}uuxgGM
    QsSԆϬ#^)uuO7n16pg}_7|sȴgn󳮶-,2`wns;bYf`*g:͘PJ!1ATTia^sW6S OIUz22A$F*GY
    Q9鮆ӭ~no8:II`f=n:;|mt|.ڰ)UߑsB^t6}zu^H绹Vd<MݎJM=Znp:%=PWJ8W|UK40`̴z1uWjfu:%#7İN1wSm}ĵ]{}`A=vڕy).ne*|Q^܎q_A:RC](x7R"<Kt2U{ 2ܐP/o�$o8RcHȹ!!h)<Aw?Вx[5C'3~yu
    #ܽ,;gl=3:.Wi0Md$5qFv;ZVsQH׺@4FQws[%jhb\+$g:`1H/gk݉AG_Uh:y_XN{Ɏ\$:>j3ߏ;	NpŴݿ_.i`|?Yhg9614$L*}v~k]H[jM;S(-$mݫ' ˛'&Jt^7dPX8kW>ͩCV!^0)f7
    [j
    !%2g^ZZQ?CnKmw%qZ	BïiX5'1a%kŲk;d]
    -AŇb1 		3	и,'9c
    !,ⱃp
    	
    ux{iv)_{0m~ۂO?fLꗪ̸^$YUHߩ~c|sdXCm۶[\~J"{F$xVAp?\WT_RboN(k+jX>/O<Lxqz$+
    1Ҏ?x}QJDBɸ+^7ZV^mihsѷz<pջN!#vڳ%.テR�: l655n~}:6̓w_ej|aOU6w{[2'Aˏf㛚pgݖhݐ5?ЊΚ~qw,u0rۍ ],;!Y6-ܪiyzWN{RvB~
    8]�ACxoζD�{ƻAӶe8i94e4|ޅW:k-a',Xٰ_EXӝb6n߶-qHW<\3!:4
    6	iw�ma'7:C2~M_ڊ]逞{ũeݷ_jީm)7tҚh$d]#L ͳLІ!U<B~=PR}GKq:l rٯxʛu*覥6t"A(+hO8!|B4z|pRgK;zf?EϮ]Zf $gH7Eryz۶$eT$&^*(xbVNs�]2'4l+<{?ȩjj;4!hQ-D?mv]U?h	Y퍘};}'-Bߦ'߿Quk{fPVl˵gWmc}
    \КIW.~R\O"x
    wLۓ^U�u*m0Kkz[+Mv[6E9evFpƇ	Nu͉zB@qz{(\\_xq˟CP'3\vMP#fM۾-ϗ7F3k:YjH"{%57ˌbye[{ˆIicJX?BߑHdUt+YHJyoͻk)3lƅ}H|]²˻5{7Flh2վlL{*wGGOaZn-�aO:' *6φz^s"
    lRZ𐊊<
    ;(l
    R[Z.&/ϻ僰6Okw}9FgXt�Rߝ72_=̧>uNT{=0:zR Ԍ8bf<UmĖVHd%QmIEO׳K<nGB:
    >NmKqxp쀰M2W1t-;' .*0⣊rD!9aUhQ`Ś	>Ž7>qE%p"Wwo~|YK;GC	v=Չ;v庳sE̝)Rmax/y.vłHbѪ##bR8ͩ"aә\fwzR=Imϓ
    J/G:c8J.y�AS7]ky$5k*
    A/VXSD<
    y!8
    'ps<ɩ!K'
    #x<˼t!B!~-z[>ӝ몃zb0pȍa-E_@E^_LIP
    XEMiFAа3k{+̶{`e=h9tcF__;LQͺ{8KQ)u%a/Teۯ$(|y(ħ5y}MN+Tb;ZpYM$^EzTԛg~6inxT5NdB#o*a5NBĨEkΝ3@ˍ]ӛ<ω
    DE)̲>=-XAi[m_7j
    
    Za}YT(uIoqeћ[({MSă<I=V5naA{{>jޤْuvH4ߥ7wK~fAL'IOfq7	
    B1C=+9sG4ȓig{fWBϯ]}
    6j y]׶̶h
    زor2z'±b=#Z&Ģ85F:#iQ=~ʣjB*CNDCt^ר:BH@гlMM|~ͫfA1)7L2^b
    Y_|e;WؚP_(6eVVGf޸:*Kd@Q |X;OkzL)"&X|kIᄃ@!?w2=V\ʮRL"I)/d|s9-`9냧Z(QhB?i߾r?4y[,{ksZ#2KsG]9yoM>	ۚ2r+.)	icJ#9akdA[$TgAXB~Q2_|Ɲ
    xuʉnmK;N752xM&	^weÖgJjٰ>[}$R"iGܴQ*B+n8rkWpy(+2[sni$QSW	*v+	 „H yYft/,x4"3!sn~ӆ0S6fL}wۄ3!4mK
    ^S(͔95ݭE.4lQĊK뗍רvoVZu$x/?2tki"nk~@)nD
    2E%
    r!6(~ KMoe!6]8ˑw:`3Ɉ"F} V}itn1ĖV/ѹJᛛMeC3KΤZZHmDA@w߅Rx<ƣL#έH�$XGI<wE*?hHIL$^lxDf0--x(Dϩw'Д#y_߿&[/S3[s>]>YjB ӑL%3Y}4J%R$D2Dgv[~E~nw-p$B_}#5|wK)ǔMP	D:֫{}S1IHz*sm!~rEL!"MJl!1{4E	FE	FF>Ә*&}Nii%P9=鼭hCm-Dn0)DrgRLZH_	wN@C8Cfh,@@Fh&'=Wp2BPYRh=kD"a#~w	'v:Ǎ8Y1:F"цL=jj}!2һ(bR)=:Fauz<;B(Ғ<R&:kFkx:g ?QEo#Q	*J%wNrj
    aRZ[Zhd"\Dj~o{ܴ{!Ԁo
    dщd2|vdА<$Jǿ6"Bpd>m%qd!+!ۮZi�j*[?%ҷ\>ty%մ*^,|,)U˧-V3]Seנ1`Y5g
    6\}lf**kaL
    ~6Bxj/Ʉ&d'WUՓA/)DX3|g5&b]nIK3J`Id!̷4XsZ-?'^Jν{*
    0?.%UY �W'j�m#<5\3kv9.9%DMy1;;;p#$߁@jЈkXE/e:z+YM9y\f''mJ���"-31k^d^mzcErkmD>4����m>jC}*M_2'!W~p1t"a*Mlm\��A[;L$zjwlzLahgɳ"$9qfԬǛTBUNJ����~!BȿnU(#+7O�������J������4�������J������4������c	9)WYQ7x
    �?zrskuf#LD$4ʱ	TP)0hHK(i�~`g̟A̎{#<-߀P O�������J������4������H�?)uuAN!(!	�&ΠRdtt(��p.ѷ��_8������'۲CVH����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/syntax_rewritecond.png����������������������������������������������0000664�0001751�0001751�00000127514�11577356155�022766� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����)���=h��iCCPICC Profile��xXy8U]_$%Hd"ysP<DJLȐ$eL$*B=]빾u]{ߺ=k{�q��/lvPpƖ4Ѓ@‰D	419U-�u$׿(H@[XB*&y8@Lrܷm*v]TLrھ��j.uq|!N�Y|7)mYZ xVd�?Z�xLdf
    QHoC"pn�ell*X+�VR9xS.oC%x׈G϶=Wa°q,U'P6"NYKI]r쀞L|šoj+ڪ:qݟzN3506fFo.fafaUe=bCg+{Ǝr,C#)ӹŕG>g4Jsu{(\A!˜PЎ<{R+Z!F<;!n/<>۔p%1=),) U!mw:wK&M¹i9.eve޽B|犚KJKZd^
    ,?ZA
    W5W=pZMD-k
    m7ܪi,۔tDK]M(e>i+i~ءPQgWn'BO?m5/pd9/^Zx5:\4"0M[qS>H:q$OSϢGX̢gsv}u[_߉i?~d//Xy}y}qcLUd'RD`hFp	Y
    ظ}9wS |T(*b#"&"g^voԮed3>((*5+/JUO6F@е:~(^?BRr
    kfG-[a99`v1+{{Ss)ݥе{#B@_g?�|d
    84<:U=͑Q'mUcbcN==_v&lx{q|2OFxjkZAzb_9,l=vn΅/_zV [*\XtزDtWSѫ++YT)TsW^[s.Aa[}n75Miko	ksO>_+u)><n>aD/c\_@ʠ3Ck^T~}uș7G*q-+;A}vbIO<F>|^x&szk׬o3YQ3{/5M `!!oPP\
    S"#f5v1ao;cSxU7<"R);BIG\U䧽CI6= x`NQ<BQY@QKRm:fDy]zxCw#i&Lϛ0(OڸJ.cwu6ӎ؜I.<.îܷyx"xyX2vE=~,GI$28>D:d4lLlD_(1%nqq/O%:xfloB]bVRhul*sꫴt̆s^YY/wϙPu+|)/$_60I%ґ+Wʱ++SyUTU/]VS[^
    uM[jo蚾jՒw7}V6v2r;)tI?ѽdG_oiicΙOKTr5'`�ș	��H@�vG�LLvA(�3CNP@xރo`a@	D1B@,R4 OI
    ŏRC9bQ>O 0b41*
    
    M�kMvhqdHjӖ.ә]w0ʨXD`:L˼ɲlaC@vDX<
    >SD.Uܞܫ<7F8B`.]"ζosZRRXrqoϾ
    ete+p+r*q)H*Rаtӎ&_኱i9l9nrѮӞޱi$ru{W<d?Jk>80E1|$)*)3_|V*5"cj\s>9js]n,n.}p|YUڡٛM͗n!D'oea΋a7JcnMzM|v}y2Ӛ
    FChc @A7s@XAD!"ֈ'!HҏLА{U=E+A	 kM8;\	6mqhhhFUP^Cw!\f6t,V.{[ːm|G;=Ϗ rpdYeɵ]so!!
    U�
    Aw]"!ƻİb[JDIUǷoCjl}geds+n(<PQ{EcMI[\HM?آU@:Cf棖RV6zد9z:$ѸX^u[lf		#S2!¼#ҢOў*W<4>q69<v1C !K+7"oh^ae2+=*ꉚ77v6EZF巒;v>\x)}p#Jıw4vSF}YX[X_[ůaF76W >3xm	A!u ŃEQP%Wh>:݃ac*0?hi|*a38\-|l[s{OH?1ٔyi;n";أ;x>q_qOP	-inS#{$B%cf*չ�Q"W ߣԔTzx=4w]!zSLXsfJ+#(+N~\qx{}7
    GDž"a'"N܋+=y4A4q%~jRSfyp2Zʥɵ7nv5495kikPs;KROn={7ʣc~X|?5YKLl\Jn99߻G͢bǒRO?WLVJW&~	rUkrUdm5cۚZZ:[3B]T%j�t>dam'du;<)Dx߻y8@K#Tİ6CȺf!r҇0Agi1jQu8!vt{XXO$YB,u.xP[\\u~1:X<Y@9�W 	m%V}?[Zm2ZR76d@gK�AzA,uMjZj6[3	\iA[|?L#b05" `. (<Qc33"oϪ!E_`w`!yԚBWt
    9�adOw@&*A8G+AR5b4���	pHYs������� �IDATx]<?!ƭFB4B颫h[evv]]jSW+鶊tE"D!rk`swfƥ2:<9yy��F�#`0�>`0={N_`0=`zX-`0X{�#N9}[`N�F�#9`s#`�F�#s:%n	F�#:�F uzK�F�#u:0@A�ӗ%�F�t|`0�=/qK0�`0={N_`0=`zX-`0X{�#N9}[`N�F�#9`s#`�F�#s:%n	F�#:�F uzK�F�# %''Q|z5W}zYzL15W܃y7y7_[ol<Z*'IrC�;4͜I"egd5!4aH:uvwilk5Z
    @yAzpx;ieDN?3KPn]8%XDDGw&Z5kU;f>ŜLuJ3ZF䇌yr9%iv.y5ۜc[WcF2T@;[en\d&и�{FymVo"	3].2o[r^[<,օ
    "%TF6TM@LN&1WGĭ6dA\\pq|{oСQ?.!Kq#|<{xɦRi3߹!lGnA	s
    I27Ң+%3^}2;TCۛPUzsK2GP1>P>CaNͲ:R�ι5¡cFq}iQ(@UGl"Q|H
    .U'&jNpI 8eD:Zڂ.532BL6[08(T;#L$ٻYѓ7X:$};K$^*g+D-iM7h-1166&mrQUh	x\~DhY@-*Dez7S'ds2E�D
    pmsRokZlR0Pׂ^{"^C*t~};/O#w6,8:]Һ4*9YR	u(&	0g~23'-̴n�0r2uNZD̴̜PKK###J3OC*HDZt,q2�n>AiE	4('a3iJD|aEqdt&933!1iV!C$5ńlDsJp_-(:4(ΛT&ԛQ:s	iA&D&pC%hiZӌ'Y|�#rN~b
    CYBv	ic	FjvFHȊB	Aҹd.	Ֆ/&�,M8B>V#S 1DJ"'t7Mɖ=Q"(NBʫ@'ᄢP xO1PPPy06f݊kjIʩt:JS3_h]|&g8עyq	^;^dRaoSH1D *RJTM^ףtM;"sZEr>Vfz�5%E/8PD˛Í1<
    s_Pv.5^ۙP+us.w9TEzPD{QlXiG]"[JTpՒէZ:BUP
    )-緉W^\D[%ۏq%&R~}Qba-%~yHJ9P)*k)9bŽ	X_i*zZ"rz�XK\'z<,%_)jzn1g7K{_tkR`x&m,;׎U_Aynm=cI~W5^K/2cCBrN~l`TݶlT.4+Bo)f|O_T08/FmPz+|f-
    >fXx*ra3Q16 LأQۮBBPDf}ƍ脢HO*`?wJww2N$%Q᫦lB͡uӻd htu"鶀ECr<]3]�rӗ0CXӔoㅆvӌ)ɈQ6jtU,KDZ`8"C}	?`lwxT2ki#6t^²B<7;N\6ŝ=DD>@UNnj0
    G$%؁S.^1酤jphJz")KQګw�|m1[2'rqh`JuZ:;&14ҾN#\rVvcQҔ�AVԹD#(|fp~蔴uWmi\shFZK*oDu<SH38u~th9M]CXShL6Ա^\8!mTh~];m)`ʐ%a-e'aMf:rdE81׍%Z&ȉ Txd -l˪iw<m$#ӻYt$4Ffp_/;CR7>yRx
    _Gu\-\u@UBF
    U{v;"CzPCCSyTJHjiH9IQbR=`$Btm*S<4F6(!Vc%EɠPWUTTpIg}Co&gI:y�QͪĿEtI-\u3LYX,4xҢ8:]ºXteM0kl3Q,�}vوwm⑸ )Fx/S8@!xHià{~2&z$0mI1ꏊp_k'EKG.]dĤ=<00=JЉ&Qh΋x0g̮Bp̰A;;J:zЗ^
    w;{a8b3UxWv񶫾(=J(iM*`쟓F%3tMj+B"ޫ&5/([JQX6K=%{ЋPџ)%摍3uth[	[5__Y:3y\m`4azC@}IsD_>#Q]{`l<y41x,yHt*8y9t6U_z}*TrQ@&rr Cpu Ԭ7nBP}9:vGddLI8	+0/~
    O*^%-pN>�$
    
    udTx;$W/gH;s~IݎKDP	fCiD+HDnbN>u,#
    u艅下GDo'2%K:Ns70,sӄ7삢fXgw_PE4*#E
    7-d-\8fU"-#n?,f d_\NU)dXM14{+qʽ�m W_ӝ'6CH,x{RK>46?e]Tj_񤑲ӄV?e99L''OK{*![_LH$GR7U,Q^+>J~N6lerUn'^dEƖ[3cB/+G-犔PdiNYԇb0u]AcCLcI(|Ҋ4\©a2XN*~+@^v@Zc[c`(6%&2
    9N1P?dΤyj,T'3�EoTQќe
    _	QF.ԇ9Up>>o]%G{dH4<2ْKi]_jWV}!tEu#JBʒ'g,妈ᅅpn=SXMC6Gx:	>~m>ie"d/2\©Sa4a
    &ijc\q<
    O yq}.`
    E.b	flIN&hXx]ܿh
    8iSp|mCZC{)PKdy^z�caJh/L";BY	3eclؑIC3�ɂp*?pОpab=JӁX˝۩rWfI4|Ln-WwP"ppU
    {ZG롉I6[ 7$%נ
    fZ:Xi)R[9f\w1 F:Hc[r5O':`%VZ/sG_|u!<OT=u-w>0mGd4|:Elyy+*(LcуkjtMUCGCC,(OL\zݜj\M&M
    "UI y`.y}ֶA?Î	>63Z.l0`z�XN4;'ҍ,Cc	2#\4shgRFZ!㖦G|㸍Vqz+HpF�#X8]b`Z!uz+HpF�#XNخÂc0V`
    `$%�FX'`0E�t:,8F�#h� 	�F@b:]b`Z!uz+HpF�#XNخÂc0V`
    `$%�FX'`0E�t:,8F�#h� 	�F@b:]b`Z!uz+HpF�#XNخÂc0V`
    `$%�FX'`0E�t:,8F�#h� 	�F@b:]b`Z!uz+HpF�#XNخÂc0V`
    `$%�FV)]a	yӨ�*/P+s:_\oϡ؏a+e8a%k˛M~a$ MɚIJ1Qcz2%vNv6g9p[ei^rE$4
    ik7ݵ<仺MB`lbcbд?b(˾u'.J,I;C-vu.r١!
    PuT>$,s0BctCa
    *
    <"4[D_trZ~ƌ:So^X2)R@4QEg]u1HZe7 ˝(HXS
    q4;ch|,КA~5tr4RPALjK'fT_`Pg�sOVØoّ{9QiS(-y;Hb#O3@GY11ciVX|TKQUю	u�CCԽElAr	>meb8%h"ɚkAR=p*eG
    P2<~PHjc<PBEG|MV
    lFoHVm!0m5Y2d
    5Tx$۠64ף}'I	g",vQ@G۱]4
    T^!Ch&>]y�y%E.xyB\JrboQdE흥v*4!7EZ7;S9suӃvxViugn8NqC>[df`zAZh#BQW%YPD?w
    R]ʺb~ڐwU
    
    ,ѓÓTgMxכFKIIK83Hcs#+֌JG'g ˠuS@n=W/Y{my t~#zVjnqjuc.G?s{7aʣ'_Q½__iBi+8X~d*8p1k<8JeD˭:v13x8մAtjcmmC/.Rstj{
    ꖆİdcNX􇗕on9@ �37K';5m$8ԥAwk.h&aA?i-}]PuX-vƭ{sC,A@Uzaꤸ{uhp4R9eU=8sg4$�YҬa@J}iᡳQ@un}U	]ˎ9iwbzdA}b9Hח%
    #6DW*3m$90-]|P@ 
    ?H[}Pr2(M\E%k_V'~?p~<#)R>Re3ٝ:V;فmN$qi޽!7+~H	8ư˥*nU<2\cJM\>\\0ѠWrvΞoT[1BLt썫f\3BӇOh%]|Bo-cxt_uTVsR[ѕjITEܹ {􉵬W[vDט̚~|Xc�Zq6)RWT+GCeRi3g\%<bOn!oOxTy)Xt7-ޓ\AUz7k
    EE�`Ҍb`D߼<j--uWN3Wru/toZWWz<ȭPh{gw7-rW}-őHDzU9U8d72]K:vpOa#UZAO]ὦr;s\d:\~\ofH3[fOG4ip|?q$:E:aO|@eUrL·MQKBU
    x1MV܂lPQ$L>1Ij\ȷq%P
    t]!ͤ!fwdTP,"au.]M~4�k�a�xսlz
    f؉'.̞xU˳
    /~^e(W
    n&m5QQ`7[CYuSL<Q~
    bo)n@r[Q�qʏA+G/R:ev3Ċ8GH(Ϫ@SRyڵ9=sOo_hJyům,7L+Ne4_%pH`d|ӊ9_ݏۗ
    tYYH$!-2EK')"m߄o؇8|r_'"
    Od]õs,EChK?(:}LD(Ԁ*+D*-._\]U3Т?1L*î,VM7M)ISA#AmYuώt/z
    DȻI`!4
    C<UVWz2T=b먱j4Wia(xEܻgl&>fPE·Csڄ2MI�SͿȈWUpj,]�QM4ڶYj:!STe%�tx&@[(O)h�#D`NJ}?cfN=5£h⋘[b�B4?ǯ4noF99LJz#}�<4FHa\q۟sIcGB֑+h
    �� �IDATǰͭCf6Fr.nfq$ġy씚_:5�SZWX1t•5ݓ	
    ‚_`hٔ<)f5|Ё$fGvL^
    phh[lQ*ܺJÿ)oc	3\xSoy8_ԿdFP
     ?70V
    
    h"ƻ]70=*0ѳ'Ќ'@cS*qxx͟5
    Jg<U"d*c	
    nnoM�&~7'9 RL8�šۊ~D5җ�Uk0Fʗӂ=-t�X5?ј5-⍓TAoz|.OV
    /&>/3ӛ*h$)|+1P<UG{*LYSx!Q!DɅ@vFo
    co@c_i0pfoyrz^9tg%c�{Z*XQshT)BbR
    J(TYgۂS8;Ow#Ms%VRB\/y_<W>5_(++<^#'V)N1/jrsoϹA
    iɎ/.ե7wuد|欉ꤾo\@P.hdC*DPxz̻7j4QcϬ[)si
    Yu:Tj^ቋyu~2]N~AL0q):s@*P}cd\Blڳ uۦY܂o{Mf
    /,"8<71?6v/c']u#
    CG{uC54sQo8"^:QFbOi!!|GL?B
    .ԫnILv`\Fy
    ߆eEp$nŚ0SM1#̐iGry)r'!KBm~J6L񩊹aeC,ey/HqJҪLȽOkhAdSW}~ٹHćOxF͋ǭ�+n/_Ĵe6b$r|,>XfLf'?o⩻VaqA|RP4d*bbJS@>Pu\JIa6wѓ.Z/K5?	
    Om&�Ru,|bc/8A6RÞAnQ^ح6`ꏵR幷䑣
    D*sAޙI@
    dMK}YPU%LMf8aSS[67'I�hP")#^OvQ11k23/}t`T;V_?<HZҊhWXq׀9bQ	cT8Ua�a5"S55)LC+ܽlf`Vxpc
    C3x&;ȕ+Bfn0~�#`>``0r<4q�UI0lU{<s9-t޶8t93Y,՞-i\,8}v-)>
    J\퓓.Эhڷ&EgC]-P}NT(OUMKY
    M@oέG
    
    /O,gha>�=CXy(-As{SoX‹FqhHHksD`avIҞ"|GO|=/lFbx:1P\{9כg31ɏ1aJ{sRƪ_zMJCua}oip:'feS\ONƁ۶vXkwWp|T@|nfcŨtARlTԐraW>Wm/ o̜f,}i}6m@>o'[g
    tn#EvkVm.,
    8{nT3qk^VA3,Sf\st
    psqDQHzFb9
    lZs ݵO&X&۔j!0LnK~b}[[ NOwˊRX]-Lk_ʐa^Cl
    ;)[oN#u&CSܓ{KSDLjSl1Z{# !Égh
    xCީW8^Ʈzgcgt;N@HQa_e$\]@{sphnzrql)"+}mfpR&0q.s @_a*ӗ]\W	E+Ѡ~ +@YKC,󬔑~B+-<DŽ=3FKSk~br䷝WY{
    F@VNunVC7'YR`w5TJxX=?nhS=ؔ~xO-0*KZ?~x%ew5şZ=ޘ~߸sg
    K]ώmDȓu	GaLđT)d*|WBϽ}1Ҟ~+{2rlwW	^RIkp0414?nvF
    bzrg^F�҃to?0+?Z.d"
    l΁̗	п=9GUT%?ueuEO?r%b_q۵BA]Z7N_۲'JR~ |ÝJ7@&on͂C5nA9[Jn]urNUlԆs	tv׺/)_
    meö}_PTgtwPȍInET01~V}`
    :ìq(B~ɗ<C4-(Rcж/ze�Qӟlw:[G֗ + hi8A:''1F黠zp{k'~
    }_h_}JXrxĽV" !:n'r yԍ`lBߑKjAGynK"E{\2g'8U]}sFgn:p?[H2C*xv0$g�kb6egYXY]~�wZ?iyP]Z?kV#RePj~x^rr++?lH�@+OOJt.{i3!#�G/�4+yƎ1:Oqv-ZݎuBVX8>-ꫲುnK.>xtE^-u3#)!Bx3)}7o+}(U1wz?Ƿ_:	]S[p/<Ȱ97|vH5U&.f"08b4=e1DEdMpt!:1(HoMṉ`cY[DzRCQpޫuAr&6fjA.laFsǨU`KSr+
    )*~#�9.nN:sSadjf\=H<quÕA[ЧOHk]QjL>.ņiF&y&�^!HRpg;dq!Uk^ԡ$aRcgJ0}Pͷz(U`HȄ8/)F掇ٷ|CԆk@؍/33
    
    ;  A:8Ƃ5ݴ"ҏ3g6v�n#g3�OfGPgk뾍"k/%I_u6D .Dg<79b>{8{2CLU0o$En_6%d[Q
    #jUM�9Z*MfejSf5yCt7l%y_6rG 0$ީuSPGJ
    4zQGdWB~}JRenA>!"C@y3j0~K-A"4p7IQdVp?}cOW85uKbXqvi1VG:BWG)CbPE|#cá#&ZhP:8
    oٰ8$~ƶxk�F1r$^"
    ?îNCY2%4|f'btς#5ڒ?,3T,&-]q/p("NzWoS�~Q‹:*^>)>;C*&L
    a~0$ܹH3lܯf[-aoWV,-GK%MCYU{FQh7QصK&:^v^Ge>�RFGaώ!ME,qˢV>nؘt	>[<)S+'e`J�E>pX7|34b<ҥ!qxW$ߋEGcU'O-\w@ɜEp4C|3Spvr Ng);[QefۃC(WxTœ9
    wN{u
    YC*v,/tn&'˂H_Ubs@*ÄczfpD^�*{`4f#Eys̃vuZJToC!C"$B^>˧~UEn+֬A)!Ec4Dt^?=Xʩ'8oI'CU';*A@v)yQsedu9/Rt˧,ϳ,1b^N/AkUsJxJUf8z]3ߘ3ވ,Pqt�10Wuq4Ѧ�Tk�5E-ܩghȜJTsh& &6 珇b
    z+$UPlʙ^[۵cI/ρ|e^xC7ѐң("`,x(XX\S
    Ԧ>i]L]8]>G. 8# Xa-n!%nz~xPY!ugݸ=rql%YJc=6=zx
    {lq"uXXp"F�#HzIXh�F�#�,	O34=|}4M%pez5nԀy(x-^r'Á47&.4CNEpk w"ICY4ASQ`YaW$?K,C&
    pu>p,ZBZ&FT#
    ȋ-d
    kѨ]]0N_SK\i*N<;䊀>|CeA	;>4I3ciKKrj_umzBox}`_Ltr	.t9we)l&Y:}fiCj.hq"6gL1Nv(�}7;"i~7PXߗԕSî)|.p1		eىCcp=
    /&{a/r[zx)9.r{QW]Džc#҄__�C{)F_2,&SOZuy4-uȪ-HYq7DݶÂ?c[
    PJQ+13:v䊀^P;>ѹU
    լfm
    9aҞmp'0p%_ń#'t(ccd1uR)75k
    9(7#O]t6
    ,ԇ;TUUdBG0m߹`?i{q^`@ͱ?Ƿ;QIJ5
    }�ދ{O0<j<Wa$5zDHb:[O&
    (j.KXlK.�@AF[<C(NE7a27)XKMu�=\\*|U1٥{bA
    f[ArA>"
    zϒ?FoOdmTx)
    W:=/	Z{E8xn&ܣ4ykJേ4->GPy[7#Vpߖhx:'q0VywR[G%
    kMÚw$]CLEd )O[(LMpam^s69~=R3MԠQ|��}{yt<D}
    5(uۅ#kD7OC3i2<A'͈<H7gc8J^!%W2wԜ$O(;ty<$Yu
    `|ʠjFoq
    �'U@1{&y/rQ1s!M#:23ZƦnVsѓ.mVJB,&	ӡI-1m3Y8jMb/-gCS6UyEs.Ǜ,P:EX8gnNv?jHpK+<fz+kjE˰B�miܫW&Oe6G/7'l$+ɢ'n~RvWy
    lF;;L iɬpJ"`<aE*a=e2mցt1-CxbkaҴb+?mCGW]aVSsKbBή?P4V\i}MMzӻyH+1/P<\#
    }wxcz;ҝ[RBe0~X׺`## $<GQ?suE:%waE
    i�l)9W>.z,'DFs?Bl\t
    ҿ,!#I~#C"5v+D>u+^gT]P'θri~Q?x)E5TB<n%PuPGAE&䦐nR2(GcG-<h,D1e;r"C7.Yz@u =TiYFW\~HU5fk[rM_mf^w�]][|'hCt鞅\hUlNj`_Ֆۮt@G4Νvx'Th0(kݬiҽ#y94}}9zT^
    &M(r"i=^YRfO83a	tfMrD
    [l7qm	/Mz2lH ?ݠ
    !31'zV)4gˇG3b3h
    4Ϲp͏NLl/dUCz<Z7G:NBOsa%6zn#W_|u^V!
    6k@eHmp++_I)PЛAH輬>r@02hT
    ]gR^ĚCk90,s0U:=5|+js-onߢL5b<(0qZ3y0l&L":|]@c.hȰ<hͤl+Ȗ>y"f9/[qgM36</MY$<MO_M\2Q!SX:/d(B�],HWBj(&"Mme@JT3'&Yo?n!C133_Z/D2(+d~u@ֿZqNTc%448ss�� �IDAT.%^d,AQJz$m<k	$|&]l{Nuu4?M� �	+i`e+0KzkQ<6P}j<mj!`ΨG7@[KHSwz�yi"9(*f{
    Cw*觵rV3rWZNQh/%0-((- bfD%&0vգ'ZqIC8|$>Uof5ч?}ND
    i%tdL7,k9Nn_k\Ha6YλFyM
    7:2poܹUDGeݑtmЌc<qٮi$̄4|T[UJN0B4+vqXn
    7oJuAUAU
    od<O@}
    YOfd]_)OgYbJC2WsyIW\/+)&[Pt>Ҟy*6)qխ?sqN`*N3=f
    JӻM1`c^-ZΒꇳFJnn_dH)0؟_`çPbƐ!p/GI ՞?m[�NrGؖuYtpl
    ?P/Zlgژh3D0hrC0Y'SF¯;FCHIt"mb
    B{1H.`AaX{gzQ+<u9B+gh^"JCgp$c8Q%:ae޼Q1)6\FOh$WV}s]
    hsF)s+s_R&2\tML_QV_{ȁ섴__c]&
    xpe/bTsaJ,
    `	\'e𜻃fG
    D@0M*J>Ii7̐GBfi5=_gظ k[XpQ#BlZ
    wKhn`z/wwmAeYHCCxl*j0"hfW5%y
    A_M~>CUf)WT&lA_SqP.!Y,-'
    3@]?
    P.OC㇞uWOכvpGo;Xg
    *>I'_&s~O%S[O,=mZ/WuoӊA3[1kF^S8.bG$5DY#+M̗va	``BN'Ku|Fm_[=gԗF#ygɨX&lӟeWUU}]Y[u%Uc#B�t|`0@^RLL
    j}T*'+4NUiqAzv{ae%О..3�ܸY	+pr_#%l_*/Z +۷ܝY۔AmnQ3w14d i%)0
    f2hsk޼i1MfNfLP\9ugN4n7i__/ipc;wf:Toۊm1^2MOV.'\~s" #%''ׅ�cbr$z(}d-R#:Y0:=(Vi,൤Nj
    3|~FiL4zggp-[ẹCqҕ%@۬4ܹ~Zibɜ?}R$Znz\-*=SV;eY´{0z?pp3xk"U{۝>6�*>V+wV@,Be5gݽmNn(T
    
    4y޽+j^ލMJ)
    閂wd^ܯm59}%U@:RzAhJM&0=>j^Y/?�7]`ى#LœB's/tTʥ6Rzڳ旯~6H\N589vP'dqz7Z.3Ѐqe@/b~EGccխ[Q#4*_qSE\8{>99\߽jy^_teö}_PTgtw&(`ž	ҵY3LjL;7oμMg1}t^POןZ$;HxcףU=,cPAҙ-KׇGtnWvac|N:wrT]'?dʗV-tFԟU=xE=́\ElXз?y|]xI*vx,RURrC;ON]6HIkxnA:X+W?:*ܙV<ǟFչm	PtxqɄ:,!Sƾ^sPqAI#>+LfQr3N~|x}]
    9Os^vx#++m9Nr	4wV֑b
    ^!	.vu==O\3ud4pey"Q|f6;zx`B8X#HTFDfkZ1s*ryEma
    T&%"坷#Hcf)}8ǫs`>N]ݪϱݪ:[6C_sfoa!PWS)_i ,c;T?jt('!mhV5�X1Ryp+#oX
    WZ"'
    Rg`=Tp¿yk7+eVp?}c}+bͧyos/S'*.DzZ%n7w7#dWH<|c*kaK/w52W`==>
    _
    
    SBr9t`x#
    a~rl]ܑg*o翎߶s(N�%%h̺L6Y9מ.t
    yA0_9 d"TYyrPW9Vў0~iKNVW;ΓRi[[:IuWe9|3[R{)=-orDn.vy]:KpNoc1>6Zњ_pJxJt�
    ӥYz^^QɎs|\DlJ]
    aw}SԱN{V>qϵSߍ3S!P>z3k73#ofn)r,ByRs
    twο8H_QPS3,@)ߝs*J\fWyxCyUt;Xw.Pqc6s<3iCÛɚ
    272ׯ?xIeKi)R'1#$Mf%SDtud}LU+^:Z䏿'8\3mKV_Ǯ˯糫dR,C5:].~,x2(S|-=%X;SU�4snm
    6aP<3TxSqM
    :_]ܲGEɩY/?L}NJgIK|}H]kٿj!DZx;jw<(1upPVN"ݜ-;
    $-x&aj#�m/EX=pFx䅞[E�BmA=%EůJXJE1:]b\	RcHXd@@si!jWuzWyG�8#!<2/;CpHXKdIЕt]v`\UMhBޣ=R:]UlnԧBW/554ԁ3kr^֋u?CMcUE}�EZyeY誺;?l{=Cte%@&WpE/V}J$I=ID>mag?uRhytK),$!˘ %gEOdm?W=؞޽K3XlfUS	nSg&}L:?M X̻k?vmk"
    	%EO{}Miq%ɅE{Ord<~^ccTtBR�Kxȫ攃ޜ:ڕaޕb"0N+#s؋zDl{y	sOKï>1uXhk*0F`׏:Mc	8vm7lؖ]	mJEH:XKzJĮLqP1]*)`.)=Cp4H>)!Mt'NNRSӰʪZg\DFee]'#`:>R.7%k`\1AgۿrWQY:kfT%zo	nUo
    .LW棘:Ze)Pq
    }<IIZ.O6&Zאy+|M}M:Tg@f�+SNVގsgĀ0Q&))BL^InruY鱾)mR}P)݅wӌauW'4TTy*xuȤ꺔qhr;5\LXk1a9SMN$TȚ5rtM5HZ@֯ޢZ|ЯᦫRuwĆw*y
    {TC}(6tTrl2}#c]pvGUk:
    @CUvv|@bWpJxG:dŅWuL)$[[:ΜNb+e'l?um[V͍R_\B0ljZ_>J9VrR9R>?X-GQ12?GעZs(%P2T5Zz:ʌ~]CFBZ姷rbR	:p:7vƝMkHթi{\nU7zOOٲ1"׬Ýi?-ZT"A}C'X+û
    3	>kԺ\94l0&xY16ۄYSsu+^rs4[Q#̡6t:xVttPNws\
    mJew%`Mk{@¾GD"*o+j[^Zo뭷umjmW-X*ʾʾJXÖ@H9'	ŅRp!sff;f;%)C\ZʒG^ssKT:#RЅmuw?;|GT[EhF;_]Z\Y YTXaJQαQP{Srvi)wl\}U]W�v+0g`]^Wü"=l+߯mnޚU)y	�|1gM	8(v3
    ].N[I$(pV8,ˠ_=оĔR|ç9c16,dux#؁ʛRao,6\V�WeLWS]ۄưP�}QCdyy3z!y:�mY".j�(iz;MzʺUM"Z/XR#к3Y(mvCBNy/҆|U^<ƹ_]ܓW�^*1ҍgF1?.;Vgnj2s6iC
    uc†S<A@<[kFwr쵇Vx�NfH_fOTՙo}v`Ĺsv9�]?J[ɩf3[`X.aMr1C:tu%ѺΈ-bK�Ί\yd©}0D:>(K+9Oi9PGweUUmyC*ۋǟD*h}{=Й"ϖmMUwnhd.c̞68Xi-W躬+WhAVx]3{./),b_
    :|0LUq{P\ץJ�]`AI53D̖ki*5\8/#tƖsM1IsʝtiG&v6ZM[ {(|n@}0BsNLx6|o+Н7'u)/n'O0|5LDBVVkp:^u;H,RkTrt`%!6Z$?j!:_	SQXR_
    kV(*i*5ݑ{dЌ=yXZ8hb߾ܺC~qD	uo~d(	C%_yYi"s>=0f6䓵PپInXQhNS<*{4gHS;#5e:�)Q:O6:]<6b)
    C:r�{EQ|B"fXi0!!-B%!U|=
    L+?~gƚܚ܆ŏ�ǦmާϽ}b
    
    /4$e�/PCұKKLh꠭+Hj/v.I
    fUx.)5OnɱJ_Uq�!4Tz)RҶ"2@I7>h~BGfkAWM/=~,0 R(v޶zFkc7'LvD9uyЇ^eEG
    
    rjoW?q6qFYqj'zqmX؍0q*~-m:EEX1kx9YI
    P7\?*MAĚbkF.AY4=z5D:v]#FA	k|^'
    jd
    ͲPe]^⩮,L+cKV$o{R�\7[A.ktm]BSUI؏<si}53wѨ)kz,Vq_.7ŗxTVl@
    G-gG	|LEKŪj퉍X礉E!ɎЅ
    ]=u	VGχ+ԅO_㑪K̦Ql].V/AWc[9}USE̹f]E_Y]
    3F~N{"I|"'7yi)l9g~Kv;Gg{3-y\6a-QX>{@wUPT(ë3tCl[Zkt{~oinעCT^
    Msc:RMÁ墥Sc@VV=<Aft'%v
    W:;lB9L]xʑy-$ma}%cS
    T!fAwfUiiҟ#?V(B\WXLxQ�4s8NE>`Q1]eY~Ioֶ -;b"s}	Q
    <}v8|bg=|@#SH:Lt8-0\Nu)^z%axƅ25Ztfxy3zTpc̛k"Ye@%U̍x;0bk$X�� �IDAT}9Ϻv3g08s?H�?B{krD{mmohjR-<Oe<n<zV/6SGrus	Zd
    +(S`PW-g=H۷=0N2Lk,so=saÑ6$yNT1{EA;9
    <'qW`W:p4PsqFE̚]/}w\D;Oܖ1`˴1\87+oz;�˿-Tw@
    ǻEpvEb;>߉) O6|?tw\fm,X7v(] i�0N7{Ӝ
    ʟymb3	X[B>OTѤjG	׾Mfaq^	`g#c]BwwQǰ2QÆ	Nw0iR7ފ8ÅLѩ@];g`n'SHWp`_$Z'[?RY!?YUeG=[kyx;i'Zzo
    w:�˙Q넏1~X@9U'VEw@i>#߷
    )}GQ*DQ6FGWƖFSk^ӡ?)vƘ%SrSN]zf	~x0澺*t	YK&.xoWZىS%*AWͻݡxn	pJf/RqxX.(KA%<cvE~ރб4j�+FQ߇&.o6#FX/RX4Xϒ߁¨@.E4~-|ϩTތ~~zlEz?7?{E׷'5o/rt?ZzՉfu~kBu
    &Gߊy[3RKz^W
    n}[g'km4^EHKCeڲ؇\	ݰPW8l3܃9/.4`*Ңk_<tU	k>[_s}#{XAY]F&;_bcmѹ*H!k;M@3"6Wp^~Zd{_(8^)0G�(%k*V`Ќ^t:Qp&BSMVup_;֖7WRDFԝj�܌#gИH?qJ|$&;_q4%~wml\7O"8lЫm>p<מulEJ}UqaP]Xs؛,1Zo텋n.s3ƶ9;rx[F
    A0	]w@]“Pwj^\Z$}2_�q`12&hL#sD҆?rbBC6F-g~ii{!겎DW~ʂ-^)QKaH,-2J4b܈+t^g0w`(*DX
    bZA2?na"i7n,VƴNY]:L&ٻ]9e7dgdsME/w8XW�'[1CT
    nzq:Y؜	N?~h}:߹qC@xO	`dosw<g|UaG(}@	ngk/)t8Mode.DR\^[,梬5_9΀`Ѻr3iP_*iQ~<UBAk|~�s2PpS6UMtz;;J/ĉdײ8w뇅FOw\qM�LuVt�m)t�ּv,qH&hH+t8)yUGPpQB2 z}Eخǵ<(MxV~^aŲ
    1AMM0t:ela$q3"A!.arQ22:@1,ho8zR`|.wfU=B.N^v]se	
    Ki~};Y!o	b)et^tFmQ< 	'Y˝AwŋTXX"/蟕u*tA_B<eOCڝ+t0}>0*OɄ1P_5CVcTfMqO46{!iEM'Sজy9;Hj:(
    eYأȮ"/S
    i!9
    ;|w\']}o
    pA,~9\�E6~O4gjit~)wD
    }^TAS@hn1ܰB)"$1>oI~)0dBg<z@X:L<
    ~`=~
    W,n
    a<gVrVj=8.nl~^[Br.~9o;%3hZ*t;x4UԟA1̡2=|<Zj
    4]Yǜ
    HHa`d
    M3?+?2`')c:}6-Sl'lz-M
    /AA[CS~
    weߠNt^yT&2
    ͻ%{ףgbf`z1᝺NA7eQu
    .$nٺy-LĎ=&�e-s*TLͬܘ_Etgt%
    ]pցž"`@-p\NmˁMOgy%z绻umK15fZ3uד;tman$ZНM.LlBS,ŸY-AQi/Pb><'�*DT7^D#C]twLR%8)HtGYҦis9\m1}y&dymgW!]wޫ,_DovzӍXo71ᭃ}"a%5#
    yߧZ_F@{R}܍4UHu,\`F
    2/i*#7:7MaˈPCo3y7:gz̧|w'[g)Lm.M)tWY,W%]ih%kj\X7r˒x`{qLкew-6DSB Xȭ%xCM)< �U
    lRXLhHẞU�z?-++) i:R鎺d61S'Tf1?8eF[ճïlI1يy~0q{D@@wj}|w86?H*G*`<Ϗۦ *~X'WxyYKUW>|§
    [NexL*''e
    /,yΚ/]n\tn/!94psnzNzT޿)$3֊gk!T#€7@~~}(	wf;{~s;
    <cm+o2_}XU]r.4=;t0^z92s.β
    -yר*ewSپIڽI}@Iѝv=.Dȟql]^MV)t4uWmm=pKΗnQ=^sǯmm5 J幯aN3k||gh൰4ZCŪ0=k4/ح_0MQ?r?4(|bb$PEU͛~͚OMV_ۯɉ0;ʒiz"(Y<>7QybuI\%ggPC
    AݖX.=nWA;翳EO~sxγSB_7P8k!l1AtAfbB@H(XsL+~=
    .N:ZުGgECw#颸ʧaWMɛwO1JVhrD;QNR2�홋{{=<R&~8m*\Vs,^M9-ܷ!?[4:u?Fb<0@؇Wq]EȌa
    [hĺ_B'F[T_*y<xM̓@mnErJKS&IeE|}=yl\G<yO2a6Aˉٙ72Q_̰QjmjLɏ6ucC2jH*>6XɓYm#Au+MOϯ+J<Qкxg-mNud]~VJՔAȕ9l]<A_SGg
    w3?X:Sb}lbI+*\q3jJc'&:]
    UXq\Pqcyiԥ	K3Kfc{ÿkud'jF~vzZIE:#rsmn|9:t`8)B--!f4D*?]}=e_94&Os|ޗᯞNA>H<2>EͿL;2A4س,YT&
    ` ,_Tt	?ڟj!0QX=SΜ2Iϐ�_&o'0bH?XdDcK8,`u-
    ̃["}e~xvNr/Օ:\TG!"tf7]]
    ;|&kͨuj_V\rv
    rJʂ*awT_V	>#0	HL"yQ7eo|9d'2ҟ]9dӁz-"ἦԸϖM݇/(_,HDE`^liх}u0&gbI<gφ@ 5ҿ⬠>!gC�g
    B`X{K7`Hˇ$x44I-{^N5Fg"?mB@1_σjD"YYUq	H'T
    !0f)zL]1k	~)@:f4ȿ,ADQt_v&HǐN 9Ixޝ"ʮT0*ό�Z#}fPE"@S|驆"YNSi+@v=h3fP(M2Ez"E�qx=-b<B!XWVVn#C9\)=Uy/}$h"0IfF&*$1=g+le =2
    oB/?:Psjh/'G
    >fr~4~0YO+qo?E<wǂR@E;Ng"Z:me$L>ߋn+wOw^h{ZN;Ei4=5LHT֔|eX4tR
    #Sg%-;sB|EJKِ/{DKA5}o`�)ՐC`X1M:%gɧf2g3\?Ò5�?۔iPsNoˌ6\0�O A`3Pj^<e"~:''u?Ek d2Ӝ<XCxq5w45 hXaϚo�rQSEZË\gU%<6#�<D!~Cd S'R�Hʼn$M1ÑVGj֧$򆦣F<e?V源V*^fb+jУ,1lL�mjz4XR]%T,^x[>ah8Xe)iwwmnp+i;p
    3-`9=PNrL&aꞠg3YKd4M&Ba0\H*$w=)9sV?s<]\Ei7NL_>(	<
    2 (eH@Q<fyP#v	꽜.{B*wR#`IǃrG])puMUroomD
    JՕ=$PW9:G\f03{#oFGg"#"{c5zg]3,o\ͻz>;;үlj[nw0/w4(yS3N`*-$LfmhAzptpHh8_3:>wz؎3}i3f^{u<()dU<"P}f:np?4tU"Ub:#rtXh!;}tHR@`Rtx{kn	&][;`~޹]ő7}T(~Y	A/=XsgÜ)5In8ߎ	hn/ا]5`�ɕyͰ�k^ONLi>.�v[:wY�&zYr*�<GpjrCͳaf޺/�Z&:̣a܋F.*m>݌$�Ay..jÊv7waIQ7/jO�K#!0|/PcQ[*2I XA.
    AkB3 b0e%x0U
    �+@0=5]_6� 5T%1@sIb< A4uhN,I}Y)+@TN6.SUԴ֋R8<@RCΊo0;rp[slպ="c[hA
    ;ݎ_B
    +rByBCtnTS"ij#S†GK>f0 Oj3.5(m�Y�݉-$:KV�tH*c*Hi?,V)"3”MrlE˳'u`h;)m*ij| hE19"ԖXP]x-dD8�um:
    h|Zt+5WAQ"`C-hP@�M lE4^_GD}a~cM–/%|h8xjW~�sCÈ"�W`.KYh@Y]xܔ{KTEΦ`UK$U	AKk``ߵAnO06G쀩T@O
    $gg
    S��<1+>�?q.dz``#DM8OOA^\
    (<%Ԃ6lA`Gst"vB1YIBI`ل\IJ-)?Ҏ{FNEKxEe	2P�[bj'Z(sQ⵩@}}SRt>ve)dj`ˢt~R[ϰO-D{i�d*^Φxr9oLf_;(gC%#or:kދ$G^Qj{0넣1
    @Ć꫓Jk渐AI0
    :p!r^,TdLBZsmvLgԷWdIOe+2(f~*)Rl|E1BR@G8JSu�
    clLoɾ勽x)ɢYªA)R_V;vJf4@`RepO$.Gu#抓ܸ2rxޘ'Ux@a)/jV֒U5b0-1 {RQBtLLVL`JG{j
    ĵ< AY}d4x<j˵զtZ+%w��IDATOd<
    ,B`hjE>jv"sMq!!&�l
    I�5R^H*nS%�n_G֨Q8,Φ>W]V|߰O<j_'{&I
    K/*DiiFoݾ8Y5.:e.@H( !)y2c9`!X	
    @ug~~t 3|*,S(f
    �ӟK.2n[{]VrB)x}/PRo_R'/_Rep�q:UP4F5)Lޛ|%`}}.Rrn(9"E3Mi|,�|q�_-Xu7#d/GPcGmH" 
    RS=snj
    n|xtGwOS2pv@X[qQrL+
    ώ@j]ٳG5TeW{*^bsxAEuM\x&
    m=5H8}b!߷4kIO).;$8ʥD/Z3(lRwhkɴ|Mv]P_.&c3SE( 2C\MU;=oW5ބks:61]o.!)e_ҟBexw.ۄȷ.3*EG 7&8BTvzumƦkgpQ`L`o\Eu;r
    {yyF8
    ƽ[F$hq_5NC*BJRBR $T^U]mL)Zdcg�CL`]譌6e5]ebKk^RIH"&߸]-Tt9bSЄv'n.,pR͡)ܴDLJF,㒚k}b202ߺ(**?%@`RלkЁ_K6f1BO1.u
    Q¥N7sfZ͠Ckryk:[wW+]`1N%p~kޔJcHZTXԜrZc0R l,~(ob>Ƀe3gٹCp}:KDZbv8x5MwPm) Kfh;H@x&<\mZ;qbfjj(2xtgs"0G
    dRAcK]q0.{]o8 bAސ77\o>Bu&a!Y""u1oVf�b=ck]E|>q#Bg[1vT`W7GU`Cdl(Cʔ72D[C9+?45 a)PҐ`t�XPU(b$2|Xԩ]0-?rx=rPByS{<Q4_ۘO;@_Fީ5o8'}G1Lt
    <FG}3K*z5i%_􍧎S{^	
    v7vcaZnsѵĹRwHJ&IU+i4@k9"X(!0MM3ԜɾxL.] ^1/?IvR67= !)P)0rrk֑s+
    ǷZ@s*(^ERhC,ha?NH06,FeHf1,<3s;әEB0!x7tQ߅rd-\ʻ4̔<xOK62`͒=WQUAoOpGbbzQ9@f^B#0^Ⱦz=mJ{
    [;I	z8o71o
    T1H}p5
    xS*:<TKQD3XAŸz@f#N8:e wo4s
    Ң@[}Ҝr;Οqs;- 5;DP;QkgQ~AA>ytYv53~g	'n<)f_x__(L'G"0t"4[K}dp Bc!!dS+_,--bZ)u]Ѫox«A
    !<pOGD	@!J!*^۝Ĥ'P(%"![{R'S³Q{sJi~)
    %z113J*v ||Syͱ5r g+mVA
    ]1:(!0Nv
    %6%]h3ʠ/u<HTml0 '-}x]mlBR_fNgC8{Ynۣ/soyM^J&ᾗrѠY5{:7)PRW^|i\gn㪦"k6Ŕ/$98e"L&Sx]Ye4xgΆ<ꎮkzfp{/Zk3:n8:(E#0HGF~lѪEDNw7U#k4t
    b
     ͋lU%xSAl1j_؁K#wxlsƑ'}
    �M{%R:o[gP//NqHpƞM5P҂{a<,TtN9>_q(4;GLSNrIhf`[u2ƓL̇-%ܖR<܏A1+JPPqtPa!i&N'>Z%AQm~Lzw1uI]>q!
    ?Y5imyw45 hWPRVqeȄ堯ZE&{L'7WyikJzMg`J[Wޜ֔r[H<q
    !敕U}L	E(B`tm8gs4F1hoW){B:1זCJF1]�:;uH–3u @@_>{>osELXYA�NSI`w@|c{Tl:Ǔ=qsAwCtyQ93k?+?)М%pcjzw&}-ޤBwj1dx͢-	Ƹ`͏P7c/9jhÿK27Kt,ߟe
    *Qn룜֦n_אVbWig0Dj-fgsfԳet!?/TzMiZSm|6[XZ
    jw2ЫiaAF靦d5)홽F$Ի16d=y9{om5-[WU
    g(՟hl7{|C&pAϣ˹_#A}5+nF?|(->SZAfiqcl[axЃz$Ғ+Ӧ9MjS?)ks1ɤŒ;TY)&_ilb`gͩ4\gvw=@'#7F<kcU
    ~keYy^xXv^wcVt;Z+zwAti]6xją܇)Z YW3?ub;nF$v{qkclJi\\B
    }lFRS2Ayu56`EN00:fMGў^T=-
    +fX'$iٺ<{Ac!~f~Gbpͻ`G (89/{�IڼؑŦoɢ*Q19IFaif!8coKZݕDid|y{�U-zSmТV<46֦n	#Ÿ]^tsUEJJ/KƾG )5ǮM*R3%c;S]*k7%9OĊ.>YUZqRD(cʋiDo[/,	bu	R@//\R	VRD\L`lu
    Ʊ.	\v[A.H	ֳ kBR\K0ZMIU3*H't@;;SY jX8_c8U_KY5W9o3<rYİOIs/aԘ#DL.DfBVEnJHɔ,E͍u :3uk4e"rDFpc÷ҊLC6u@MѮ`{c#.k1ȹ%	w"dUT[6oϪyˆv'cr\w(TS"B;Swf{7Kƞ.9pF4fLг[\i}|Pms!0t:80yZeU=kffŇmJт^*# αcY\E4c(uסڧ`涕˂JPW'brnRHXb:)ߺwث%0[Xj.XDPu>
    
    Sqioc3tVguf+1k2CvhmpuxG])Jxop8z
    3aY_|7Ҡb
    da\DMM"^Ys+<Ux9=BQ8"|ԉ3#>H3"m}*'jj̵tmt(v:@#mLګ:D+뺹5{x+xۀ-Bʣ?c`
    cT|/lg)!{{6:ߖz:^'d
    7s~l/Ԟ$V@\DfeHZ}mSrh#9"Lr53イ<K;Wm9c~!IΟU0(Tg,KJff.	,v·cTb>b:^K]N!ɽԨDpt`<\.S@"p&5c99d6fhhLSQ!?m}pWҔ)JSI8:UtfGT:1:5L||T=y*pM6mz[kkFQi,k	GR'Qؚf"$|望kNO!.
    &=cL\VQʝ
    !{[x=O(CFH1GR+tX+JiYtQH[uWFP>":zcD!I’ crB&4_}fӉkG�xY?wDžoqZC%@:/9-S�BWxB�!@xYagdQ%!:_"m]|2\+oMU8:&בw웽*wǜJQD1-{]`EMz>VEi@a;JD?z-#Je?egNzakGU.}_�!6q((h6�xýtU9͘2bgЃ
    ]t2*VLtD*+_?ƃw`EEAiE`D1q4-;L'r|i|jOTh"Hۙw0efx,Z]B;ڂK%D9FR\9KH2J&,ztxB'/{>=}oqPI�B/?}V8kI|<<L*+7Op|姿\Z%J$ǪXQ!�6,-X1I$Gea└1#6 ĝB$QTK^Hz5@-PvL^QFeQ!L2O7_`pr7c'G8H:ee@)>dk
    d!4zfGČVΥ8)FK.M{`IDE2f1gc깕ur8%cS=C)_xG|9.$P/7~j}3`qaR;~i<zmus7ob-@L
    &vv%-LUts7֓g;J)Ir/"%A>=ZfJdr+s%Oe
    _ghA;4	ѿ
    ]A6Bk4(yS3Nd*x,ZO3I=̰6d;Qї�P>Rܢ(E &.NO)0:DӮPN4MS$In7COr-1=Ag[_@Jb)wdc؉BniT
    9a<]5oe!Ñ :u=sVX
    c@{kGřueK⛻[bDG`RtМRd7Q'<q
    *4/~t,/"Rm@"(a~}e/ƌ:H^V&|46É'RC"gI�=:Z:S*2.Ʉ̰u-"%ؑuwFODe%lw|O޲Kc)@ud/[͠Pa&_d<V&Ë18gbqaJfFq6Ys&GX@L`&?]4Y]⾳DwWvS@_/3d32<8Qm&lS
    +ik>13F 6�tAr%ty1!Y$AÏFgS(P{YD�D<O65VV!3$iKk`ߵXy~t1/hۚ|,:a-JO�B`#0^ /N ;މ_:qwD)l{t:Qcۑ8xƼMI>ts.x@Y<p1Dxkqt=f#9
    y?Lr{4ʛBvtE`my,~hMgاYoq~gB m,LV?�B` 0t"t_Fݤ!prorO?Gl?	1RjHvѽ?9bF	y|!'pe
    gB->?(!T:lz9m}t] H9M7VYOX	Fj	E @`R0wۚRKn܌e<E?}{H?d(B�!0L*;},B@`{�."A�IE �:j!@
    H
    H*B�!NQ�B`l@:}lpERx txD c�c+@ u&B�!N\T�B�!0 >6 t"@�@@ W$!@HM�B�!06 >6"�B`<@:}<PGm"A�IE �:j!@
    H
    H*B�!NQ�B`l@:}lpERx txD c�c+@ u&B�!N\T�B�!0 >6 t"@�@@ W$!@HM�B�!06 >6"�B`<@:}<PGm"A�IE �:j!@
    H
    H*B�!ގz����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/custom_errordocs.png������������������������������������������������0000664�0001751�0001751�00000041417�10671421551�022407� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�������W���sRGB����gAMA��a��� cHRM��z&���������u0��`��:��pQ<��>PLTE���qqquuuQQ}}���0ee릦��00eeeϚ   ���e��A�4<e0��e����0�0��000��0�00�00�0000e�0e0e�e0�e00e0eee�ee0eeeeee0eee�0�e�e0eee�0eϚ�Ϛ�0e�e0eeeeeϚ�Ϛ0ϚeϚϚϚ�0eϚe�0�e��0�000e00e�eeee�0ehR���	pHYs����+��A.IDATx흏cƑg)UJrdSwVJ3Q)e_s'&##襱.m8?fvPDP3	|8.4b�
    V•l0ƕqec[&M67ƕqeceN/gm:!_U_WMwZ#j\{;e}PWH$`^l%ې9\Óŕޫ\%\
    ~@fM4qm4]\4to7K66^0~8I=]TlWڰjwwgJwcްW&Y[VVg[
    \*Y6^D�ffŸ6dq@2~pMnȍNn9/ƍpݡλV�WP	RB9ۻ:θ+vX.MiRfCoY@5@ vmqE\<@>2hM/jn4=*_:Z1cWsrE0PVܼ*.W.`ۂp6}2+h0%E[umĕ;Vm0l+Ƹ2l+B7Y0,g[]4m%q-s`?gn__U{ŰO`Oȣi|Hao`2s`[]\˔\
    BTKE	'3pt{R7X{v`[]\fqU5pp-s-<_#%V0S3q/1=xBAllZ%Gu{*EMػ/h�׹c�%;U 3PkV¸wZ*3F`lzvq/W@Y$i4�dV`ƕqecc\W6ƕqecsp`c[mk�[u68*`Oʸ6Yqe{
    ]ۂ+[Mpml`v.]Ý	MlC0$w'-Wi8x5QaWtܧD)<9ٸnd�ք9ܠF}oGTGG8Uh`N4z+\'
    gtkmt9ٯ{Ɗ
    Exc`GvDž36d/[[>>zP Y
    ŕڹIeo;RgFע~+3q:tl=n3z5N+Ck{:~~(!r@P<̊]^_6@\5
    	OUØb̸4+ia~/`ebW03\
    &zUՃ5=Cɋ|MBҊzg͠<y:3h`7
    p-ޥ]Q{@bbq}l?;h3DѪr[{^Ό"̉kɢV)\Ǘ@qpuaap%^<c` (qκ[B/u-bʸ{1uõVy^C_,.eslh?[93�3=In^!^)3,9F+lK]R\χ!Y*d*LJm%o5ͭ'sΉS̻6ڻ]ܖ	jIk|Ex>KlkAk.D\1յl5ƕ�llK
    W6ƕ&R,*.ll_̵gub׭Ŷf¸ŅޝE*e͸Uĵ(v52fX ;baR_fƕh}м.ҵX@:v.w6yҰD+/rp5Zd^3HVn|-76	NY\U׫:[HS
    ׫	s3\76<\Y;ڗy;p3\wgfc],6RRJOcnߤ434u:Wphݽlc#0
    Q]<Z\*hGP`S.aѝhǸ.W;KB,W
    9\loW+pQи�-;W	\u,Pk8"{vBdG&m-m9
    >xMg&`F<dYaGl6T,=WS�zf%ħG_P9U8t^
    <A{弫A%,.6wŸBIZk
    w4gҸ*M\E)\޸Wj2&V7UѲu0pm71n6]/"]\1_DJt{#ZWVkc:}KzנTUP:?Mw3`
    i@'3�
    '3tܳUq"K3^"JU<E%k$cI̸Ů`t8tm*$Ӳuw[
    ,gmouJX(s*ի&IкĚMt7fk]	
    tFxۻjٽ1emqm@h3-lKv2
    ׼6;M"l6Vטmךl1
    ׺~.2Vr7u`YbZi\:e[ǵiMm1l]{mbk\E<j
    }<\J>]l4]V�W5߻O۪z,xX:0ۭ㪻k&Ph>>BͲ
    :
    @pJj%+]J
    ޵JW_	X|'zf\V̻4(}s0Fk-vຕ5aɋ]uURveqgaު߽kGY�΂+"S~FW#3  EXa,pLp\5,wMc�Y*t]5m9Wl\m^J㺌cY` <Pf PzWٻBPWXu
    Fw=LK"Ij�T`Uq
    qA=Ћ/yOB^\ }y[A\^.a<}|fAEqM剬i"Fa.83Cͳׅ+8H͆F]i (\bq?\]cB\s-]A
    v5UWVl,GGͿҸ)m*<X癸vWfk]kXaT3$զ~v]0űvۻ.W+'Y	WQ
    Wwwp9zǮ;FՃY|]ƼUk
    @~QNp5Yk{J
    Yy9qRfnL#f@m3P	^QNjVXQbPW8)Amx
    !5"Kr}%%/(H6A8h8nBA%w:Й]ЪV<yC\8l{X7wƒ0U#YGDIZZiZY{{\(Q@qke1&zkʲ
    ƕe1j+b-?,vca<\k(jvk
    e1V'5le
    .{5`[2	@\v/QͻKm,|N^.yk]d1Vι8,b59<F7`4<=hw,
    gi~zғYElG'itrkd1VWZnʭ
    :H:SnT93P#YU]u@5@2G7#
    $#b4u`[1\!A7׻ձ{+]0 Z{m޵^l+giW_+9=4LwOй/jQmpE~UJ%V(;cW,dFf&]i4ob\٪B9y}ǯ?ϩo
    18[
    2`NeUpYk5GQżVTU3Y5k,“Co9+X+pDDǽQb5Ad1V:Gj>/ǾhQM 
    `x/|Es&8`l+ɣŪIT+ǻdzGGALfa@[9U#Y}l}M.
    q}-So>k8xk-d1V˻
    d:DGd?ǮBn`{l#\r{Xz;_L[FYDh"rQ4G5A9Y`wfhD'wf<8Py׾wE^G9ֿdkU	XfւQ$dr1AXǓ9yHlQ(?zBYaEʲls9֣Nө(/Q=+cZ,v#墦wdykacR@8B<|:kyʲl7=.uBtz=>DΥ]1
    @^Dƾ#rUY,vâutMm!O9WjN0$FE9bW`~F?1aѻRQ/i-k6,6A"~ECcD YHUZ,6/ⷔ̚N~:F~W�\HNTM0#ʲls޵uqۋ3{Z$dW̻RWr؂PEczWbYyle_Ư=
    TjIfDr225v eu8k!bUvڷ^Z'V{%n#ܤk!bU\ {%)Zt:Z#L9q�bC+^ʀ8OM\Od
    g'}*,`ߨhH//ޥvO|.M:T$h̲l`}U"U+|md,"`/Q TbY9CR{ګipc_ܭ%e`9ho뜱+bKYjP`/kβ'K؉XZx+ƮS	˶lSiU`�_c%x:'ߛc`[z*jZ*G$bY(OԦZ-{l&=gXsby߻KJZ=`iR$d&`2X+g8)cYf]0Ԁpv# |1;bY*֗IQ^B,:ؖK`GI{#Xm.'[ڷ	4/3ޗ}"W;NgGpyll:KN^].uq,
    n3@1r0,F 4sXt{YĚIq4*S0#YP{P5Aص,F^I<j6l/U}Ju/!יHb)>Ud1 }06U^\%{IsX򯗲@Pu""9$KZY8 /#P1P~Fwnl5I
    W/la[>ud1�{5+h%
    .X/EZqql
    բ./$.�3$5ûp^x5{a\4fK$Ꞽ@dqkVPU@VxM׊yJw5!we\9	o֞HMUVm@~F*aABZ]شTʸeJ"혥ɔ4u?գKTU]U*lM9;nH3�Gp|,XYE2u6q":K¿pH_JAksT;We1~R7gBs`f:\}2%ͷ&4t=؇RuB*v(a]*eQ	'.,U+TRWX%]a@yן{EbpZg@u{YnKX	ubiH-@Hyy[d-Po+״{^aSXJR}8|=&X1-dzͲlEYһ^jmJ`лX\w>ʲl% vK1ޥι%(šC)]ѵ&{,[9;Cw5Öߒ6z_Uczߍ[Hm1M@]Į+[Z~{'N/3!󯊠渧GIZRC5L֜+b0Bd2K:R	\nDɥQJ;nl6xrSU["hCfPUD19]+bU
    ZNx'Ѫn?wXBi!E"{*eK4Li[,kRJ'D?r+SF8`�#n8WE/}Q4�£t4U^_)o4բ^g#*WҘŃH+"l50&g[:3l
    wxF`e;,Q]Gʦx&?$1e1F48u";ЛSN&Fk@7~Oj(LӪ*#veYȕ$P͛/Ywu it-_OQc"X\d1]STvncH\u^R7rtǓnu"JQ,4o4)
    /!\&R!\wd|B*Xs]bS\#D:L@>/DWR=SxDY$Mݐ`&q,He[ˎ[t|HbI\EX]	ȔXyZUz״T(B:՗\DĻJ*U;'5I9wZRuDG5_#cb܁wE(%A&,A0\5rDhl6!<
    2#fZV,FyZS֒
    U=zh:%Q^/-aa	]Ss4"'IK:+4fW׊ZUd1J*LRElZd[Q1_'c$/=P=Hk~w*vU~UU.D�O#'?H]V,F%Z3\=M]{	wNEiPvKvRȔEi+{E%ۑpͳbT5bN
    4l{[S_#өl[Lށ+z(΢ׯהWG=s˻.T՘n޸c-i`n^Bp*EXw~;@)em6$l])W:J;Ve1`@Ut:%qe|N"NixQ>
    Rؕ@.Fg*Hj$uѲ\Nq]i��
    Ov"1_
    
    :8~JC2UҮm3pY@"K8Yš.%g+6wo(Djѷ'o'd4/9>'-3̉2]K0Z,F^VKe:z#HxK$1pjiX̶|�:!=F@g:ѲG	}ꋞnڶJ]!7@&
    �t
    L<-NͶX5P:PX!bxD6LA%a).UGTeߩEI:,v]1&j;=4;jNC|ؕTqh0P@:֤mD&n:x99cW`3o)$zJ^	Z=bU.'Q3n#s^@yױ:wlwEzh`Q"&Ud'rk-˩,*mV+j,[h/s{bu4v{p$]ʱN+neAURz$AeʲlESGGTH� VHi+
    wh.גkcdUǰ-ĻȹɚY#9P:Q'o$Ǫw6)cF/nqZ&x9W`sqD۶P�u@AiOKH*V5yՑNLӮjՒTV,[A0דuZDQ aOcd)aQ:iv$F,�{%i!JzQ$>كX
    J-zI�Iްi$l$X',  8@JX8�0=H:m`VbUueYEĮo1ъm\OH0EG.�*@auĭi;ج<e1¸NULG*uEFJI].k(E^pI즎^Kʲlu0:N=)U.қD$I+ӣB|%!a!e{W`SRe} R.wtw>(E(kbLf0IcM?w],:d��6
    KJ(N/@ziH	Pts$NusZsƮ`[J�5<z~,]HU<+2IwźI6ke1 t${S7:b:}hWyסjSD2P7Yq=k[Td:gEbwͰvx@rtH/8NS;vhBo2eU氌.FS5YR+K=urcj+0l8[NdqnԊƕ4%1ޅ</SvV<sa{`PƎFؑ80.tPk%dVGS=oRe1 f\+C
    ̿K@1H`+dڴ4փA71Iׄctގۋ"q#\ŭ*WV_Eڗ[}G5L=éggyuv~FOrf,\$néY4~V@:KnZݥ˥+(nL'3ӯ
    ^	`,:"zpK2{9{9d6,O:Ӳ㿘˻ŀ_#yfeK5X]Z~bW5!v55[,q50/n+a[AVj1vfn:8dWͅq*yGWq.a/VBN)+p13."WosBx,-ܟ6w"F9t"\�f*SWp5a\oۻlm4Yaaq
    vTf;D.^Wpۿ*{8V0iN(;[Of2rGi	i1<+nQu	cI
    YOW͂Ukgv]T8X,̛y5=渞0g5dMp[Nd-U滚�uaʲl5]Y>ޕe1]Y&ޕe1j+bɻ,[+b(veYeXޕe1]Yvull`c[w],R3%e1VŻ`c[ص,F.OLOzo[;zB	[9in"BŢ/"e1|rݝ5ޔ4c�WJ!zصUWOh
    36_WυUBuøړ\wmx=h	
    &]o˜1a[{#W#Z"_!PJt¢e?@v>U;rȸ'aĮn檘BZ}Bk{5_DP=<$-ۑT)ʍ8&]}1>jLde"W`B;wpSB}Mu` Us fMMY.?pi*p萧5'Li/]o*d\*Zu` לPWKP؂yd1>:{A
    ?ى,<n@ DB8cXuВIpoc}̌<V2q1Jn,ìž.`"v+S!.	%&l}t+ §]-ʸ`˔X+W`weY:zW`Qʲl5,[-+bɻ,[+bŻ,[+b(3l5,Vص�*Ů+[MbV+c6d1V$-a&
    a}jwhKO,cA`KNG?F;$&4fCq}7-BCehANJPicO75pgVGMot*<B?"c2uuۭsb2yJ2س4"XI9BKp&-e
    laA[0qsaL3'$ٴ4#8Yt!/h5�ݒ\(3G|-0#{/dOt
    kd
    x4aċy6HoٌHlH^:FeI+"ifk^ Eb$�GLV!m\Jr@
    Ng!$8KTeXLOڌLcp)	lZަ&kz_ڸ-kҕkyYyh*KˌJWU '!5,\fvDrN(K`oDdVX?^dv6e9d1Rq\m43L\ڕwkFmG*[d9<I੃F)s:,9bz ²{_AsL{wZ"(i=qđN1wnI^
    (t?�b5޵,Yi	::zD
    ~
    EAml=9"y_˸`
    ejYEx#%:V}@.wLZ:F0I-ڙQAx#`hϺ'ǻ\cMt;KΧYvVVYtit:,[e1W`weYyW`weYyW`O:l]WĮ,V/ʲl+b1-�ZAmek	Y6U]Kbw-+v޵,۝zjllwllw]+b�?GEZJ϶ke1WflĻ,[+bλ,[]+bȻ,[2,V3ʲà,Fm|,l玲%oq8$o�lCamj#ͲF� x-(Ƙm``2&,1�i`9٢sĮ,Q\SoAX`N&F)`qcN`2,i�7Ʈw5phy`(1A,ghU#NN/۠tFw,Fݜ֢epq;Xý-cwt27fYV0�*XFƲlk+bһ,[}+bĻgYVUe-qEuR܏kEYNH ůo'ikJZ"%Sp1*eCJYh(?cn:Õb}ׯܲw-%Q;EWݰ[/ba:M]g^-U[1۸D#|@>BwLp}o7v]SY�X^];"dv+aחo	%Ay}#}Kq\X[YtWW%%=d_]5{.-�~+?azkue1Pϯ^{J(ʕo^%:6qmٹޞw]Yٳ/_=¸1N?OuJD$Df}	m_VR7]WCUgD,"{Eľ/?`?&.?_!a	m+Eyŵ%Yfzue1b*)_=Ȣ|In}#Yyz6ҳk+}7;,ъe/ϟ=K}lY}O>9f0YN?|sKvuň1F3%V9^RK"ˬ%
    JWϾ.b<À =!K+Q?9ӳZ X*(pEf
    dˢ9ϟ{G*>!lQ??ܚ~|LV׿\+9>$S?ݧum˸q){W}!+}NY_*gOwӸV\ Kf|Q"8!ǩ~R5D#~A Wd^Rd!\*{N~߿Yq۟~|JNM\"P..ު.~Gu˸�ꮯs>Wxw2u?mbcr[\1SWFi?o^?5VM8lp%zZJc;T‚+*{}O3[VۻMcXEpyV|_O
    \%ol^Γ2=@zt-lqi
    Q) w
    Ye ?*e\*煱Zg7ۏyzEwH,e
    ;gVƵ2&ٲo?j^p<CԲ9ǿ\�FgxGO?8E-]1xſ{],F�z,ۗŰw}'UoZcx*v\gAr7FM`\a,v=b3{cY8n>`nV0RLֻ~�)!OsG8oן21Kk#M[;>ep}K�?]tۏ>ĮX#M[WY^;z(n^qk|~gFcg>~U䴏_EV]uU߻,F=g�ҴsL~Uޞz)wUh<'?b*\,#$}V۳ͻ,[MRV,ۺy׵`[[ﺖl,zfVmb=ͽ/ކ= PLŁ\MQ9aDA2؊9TH;34t7& .|]w㷦!+xֻw"Ԙ
    gFf[S
    ,Έy8h5gC<11bNxɁC1%xX[E[#`zGd1Ho&�p6Mɘ֒QWy/T<ML/-rL=[*㷚fɜ;~y׻ŀtHa�{RWXۃW�LokrjL7c^A9azz:uַ~mp;ܑ,c;
    ۷1D)#VWa'u=a^ٚݼSw>`HF@-Z4~z5ŀ^,Ÿo,Fbwl뽒`[`bq0vK޵,F,/`7ȪrɧElCJ#/8w]w6e1jgޘe]Ak^fUE#
    >Q+J(gٚu#bX-w*}pkZ:TŵԑCSG%@
    ׍0e1
    nFYR$-k435WkƎ�Y
    ̃s7h\clTE6t!d/a}4`k^+X:ݶ_ev3YWcdx"k&8Cf+q	xmD
    %c~ܨAÿ
     JX*?/NK^*XhhqVuϡhp..Zlh"d64G^{6{BӍgpZaЮ 
    ݍo3۾e1Vm末[ _Qpwu�מ:rG:V9WBJt:ڦG~>8Fw]bxc:ٓ!tQKfn+ks_+Օ<rLJs*Pȹmϻ
    ַ_B'zגvfwa�+tn~,kb`wIwb3-1ܑ{}No3ٸdj8/ZyR8:\bcגV8ԓ{y7w[`nz#%<XmɻMAӅ`~;R08_<fJ*$>W`-yŸ9bzw_Ӱ:\-紖w"6w+Y69kiYNfZGZLz?`tqҟ}3aT#2e1l̊v
    ?ZpN;":jUd1:i-uZg.Gcur}%\zgk9֎z.Qu:}d.5Cc3n7`cz0wl*RV&bYt3IbW쌞decN7el$17j\Mu\S^f5w	wٜ>Ů2UX/D$:GvL,]yD:~c/Cr =Mp2&=amo&."k'󃰣掰W0Pdx3݃5VʡIu!TüNԙ}05pu~.:8W@:vv}!MO+lnnYÕu´F׈:mԌ;v<[z3Yx(qO&4Vlŵj0*
    eٔD;A;;iw: ";6̀ȯv\@z03Ϝ[ýXdoTԒoXuj1V1NBLb,۹2lV`c\_n$vwV`c\Y6_	[Umٸnƶf`c[i`\jguVႬZ$⼕BdۺU [csʸ1+znoom*a^Ͷ|jv&֖�4Rn7Nn3ݻ%mڈ]w-X|i֌vvB�*ƕŖum6f]Ǥ2Ju[ѣG
    0õk2�Һ+v"\J\7%.Uؔ
    T8n7W``slo6!\%];*џk[Jfâ5부Op7D.DIvf2IJn7ݶpmZo,Ƶwkƕq
    v[y'nJ0[m]Wӣn7vȜX@J*nqdfʸe9n7)%qc׶a2^ūZs&dnBwD{W5'3lbu޳cj 
    ūvNymBB+4we?36V&iM+vmv޾ljZg%Rʸ2`@4v?AﺻMNng	2ش<knf@z]mƕq
    .vV0-g^Ѿɯq9ӳ:h~Xkø1+zK&/쇭Z8ܵFƸWɶs\j`+ƶ,\&ll5[n����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/ssl_intro_fig1.png��������������������������������������������������0000664�0001751�0001751�00000006403�10671421551�021731� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����G���xk���sRGB����gAMA��a��� cHRM��z&���������u0��`��:��pQ<���PLTE���o`���	pHYs����+��TIDATx͊뺲2
    4~
    Sߧ
    Jw\a=	B.&,wv'6{\=UrI*i==M2$L{	!G<}7F+%U-tXBhRPm@݃��/p]E)qCEg
    %$ѵөRETQ\P71>�FX
    tmU*%_3 ̖=-Df9#_Ri˨6z=lٓ" 0{H_JiVQm"@S-RRi }`X
    ;2[(Q'mN[5د	b"fvnnE6rAoMy BpCdFlgJ6_CU_1XHZVԃ‰
    kr7Ɇ
    @цc4s9F *PnQ~M 
    1P"剘-1#2$beb{D9b{C0,‰Vh*Pmc4k�s12X0m'"F[$nD\^؊wDwߕr`+*uZmJLܠiW&zҬ֥܏@*UZlxSZ+-/i+SM,Jkue�=<;ZL$Y.-9ѿAc}&6!ojwc cC@ن�> 7PٷQm\x> 0X$b:ԍ\^1>h޷>f{DC{s�
     >�0Bԯ|0! 0"4߲oj261\|[R$P=z\PתJn}?4G%K!oHET%BrJ%%ҴMN2QJ/.*B$e64JK=R
    ;|,J6ølGho[[߭ՏWL{z@d<ߥᏏO<ٰh}C9X`N&0Dp4!6rDE	b&m@qs bFno-"[>Q-YZf1BEd&/E`{ ȌCw(Cm7x
     qr�3-лi>Wo12o=0cM�&``@W	E)P,gB
    -(QԛMYY*JrS J!U[R"2˅àj[LBljA-D*JkRP|Ҳ!<T0J]sQ'?DUfU*2dSV90rkh<uy͗Gu)0R<%-C
    ~\va<%b> q�&Qtm#XӰC-_~P@<%B$Z],kV
    [],k4
    z}4rH-9iu;T}M+Cw=I;`dߤ5rJ1`g=JҢTrJUàRU3ZLjtVYERgP(JgC
    JijlEU+YnѤuLVcjDrjBMSu}un)-=^<-=4$-=04-=l2,-})w9iY$enҗļG
    0gu~"U`n"Ɔx^ǴM1@]`8`9#{O>ڪKduLfOqGE,>>]tZ1<܋:qn�i7guL
    ;y
    D!oyw;I4n@6WM%:Uu\B_GPg͕J:mtJ뺮?lhN+R%J+Q1N+VJu/C:i\HVPm@7>:kTR]DyDf@5W*QeY-<
    {QlM,ɋJ]xpX=LQu_L_>7l5|SgBM)>'Ԅ-o-c�(Wm-Ta?mpYRetNlVU-WAmt,vBWJQUK=LJU&-εˁlURJ8r!pɹR)h�E&7vIzU݊U"Zt/ӇPٳS|u'_=.5QZMkJP0(1Joi\J*QePZRUjQlK	UeWtV&M[giuz\sJ={AԸD}%C#o>^dFK3gn<`]Ķ0o= h[3![9|`5V3 36Ė5Pa TDh->P;M,�V&Āx@bfkx@C1@ϼ%2�խ&1D&7Ulԃg7&	!P*mtB8qRjBj#T$IiUe^ᮭ3Adҥ.UIrGtUB*UfP*?V}wjtRBD19J-^RJRJ]nhE^ߋUJE,7UT\t�Hdؘhq_.D"s{ܢjwC+ǻlu\5w	'=jląxZjuj%R'gN3j$-jV&z7zTz%l9Ү*UiudY[nVrnو)$ҳN5	5:jI&dI&9l~P/Oz/l?vz~={Q?_|{>Uk6/~Ͽ_z@ξDO/F{yuj>͞^fן|2{_ϯ$L2$j
    ^>;.U����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_rewrite_fig2.png������������������������������������������������0000664�0001751�0001751�00000002545�10671421551�022241� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��}������$���sRGB����gAMA��a��� cHRM��z&���������u0��`��:��pQ<���PLTE�������`p���	pHYs����+��IDATxM<*
    M/s{GAmtV~'' b?=*n94@4�B?8�p]w)O��ynlrّuϮ@Jt)�g9*p|_��.7\Eb
    rPUR=Qx�Q=J3�{\c4<j#��f38R?Sd@ffl+ 
    I)FaqVڻ/8.	ԻG(3pbٝ=qQU9�)%;2pb@'C1<ybb{QJLd`T\I=L1(:K)fK@v
    `1sU^ty/33׷ȃGK("JE㖱xc
    #0Ïm; 3@ig֭5�m`ߙ]4X#N8}AN`K?0f-?8
    ׊=?pkV?8}A=?([`8oѓ~`~<A6EWOΞxh~rjmmn`M_xS?0|
    x.~W7_{�{̮M)7kx0?pp'+A$?@_Y_7�򃸲Vi,�ij3k]]_
    &`x,?0AX~`GA@esXL~i4@
    �7qBls{;^u4@4@4@^'µ4Ih"g.�'�g@_\s\|�o{ta~C5#Lv^8Jv,u]̩jXLR6]PJN^!;Ro5RJQZaޫ0wpr\L"b
    BTL,
    ybs6Rk/SG$d
    0 (jP5$ə;b)R7Y`
    �H*\J@]/Ji/dUO@2|�D2OLD$Ikz8`_ix94d����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/ssl_intro_fig1.gif��������������������������������������������������0000664�0001751�0001751�00000013152�10147723030�021704� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aG�����!GIF SmartSaver Ver1.1a�,����G�I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N5;{0'9%˧7#5~}!3-ஂ&
    |}"&a4qUG}'v
    )
    mDBSN3"6A,SgGѬ$t[]Ҥ1=p>%fvkVZZ`;ۈd/5;-YOlѦnٜYԗX*^韗.7>6#]ϟmoצNZ9y}=[`9*ߓq}'*Qis[Z7tsή]vŏ<Ễ1/YKzk~wyg^z�7[wY:8{wb'be`Wxg[yf`f(F݉U0
    :FpJ!;HԒ"nQ8l6h[]-�Ȣdlyԓitu[:W\|V'~`Z|gnF<	PS*Hq zjj{cjjB뮼묷+$$쳗±V˨	̨mLwSZk9(I{r(ʻz2kuv-ꟄjהokSXօ[;of,avZm㦲2b796H32*:2}"nWԸ<KC8H7hO赜X2VC;Zvz݃	h^z2&6	=<th7]Mo	8t2go6Yi\uF“֟^)0%J•AJ8G†.B}q0!<%/:ϤS9\|b#u)y$S/rlHi槯cb#٧>?�z)QR"DID`6p}<4¨۠Ҷ}Cyt Xz%q@.o΂a=
    ֤24D"@&~;T&%.`X֝u*+ڝh0Ű\"8:QBdx28s.
    [g8eYj\
    U2ms*
    )8ͅI덯&IJZj&H9Z[甆(6[`9@R>l9MN+-2*	+F񘦬HIZH\!!q*svdrӌȀl&y/6f
    D:i.wkEϷS�U53~^OM(|UDu=jF9ϋqHGJҒ"=(%V
    T,)\RXCtz5J?=R+)
    FMJ!58E]TԞaW*U}
    ^*XǚկUg
    Zɺմm+\UU@iMӾA{=LEJXVMl�{|)+_S
    e9⥰jֺ,fٖp|4JD;–bAqknS깯PpD&Y0'ƣ„qg%Q|8ܙPnrCRzwB+q[%v5sX% kS�&Myu;dJܨ=5
    !G%~ q,I))n[LGu8ơ'OdSeXLAdM
    *0Ϻ
    ZbD1<$'y`$41_\،ʖ2&H4{ ыrqأ8zrQ]ְ81ey~7d/t-I@34BP3NƓ	+zα[x93҈9ZK&ۼsEq*$߸fj|ӟb!=j@78iazCvҊ\VDij%f.kͺvq*E
    Uxѭ>N]RNhf*#ʾT	4}Jgꁶ`lFpi
    ځW5ތ+⛍|qK_8Q!ҫR?!}6DpC<	b?3-Hŗ_%
    dF'1ҏx
    `W#ЁC:W9M	QQ=q8ouW;y?۱(:8ݯԧCI-*ˣYK&;;h,%j,Xd7UWoKaL]eq=S9B>p28nnQ&lň;4>f4wB֒[ZM;<?c.9}&
    HFjd9B+Ζv(Lg&kG6|q+j(c3'D1s5b'ZD%B-(vz}^ru@tvOƃs|@XEGZgGԄ%PPRHPTXIx
    c^O``bAql؆nxVAxL\P_sl`CWp~D{؇qBW{ȇ${#>3?v>G=I"uEqHU?"QAT^CBr1舛Uae'EB8\ys_%B]ͅHev'>vys7dzw^}Td[E'TRrը^'8Ɖ=iH]}]o
    v5Vtc(Wp�y-[فِT)ly-8ȑ%DG(ib&p-/y
    1kV8i	P}<YY>	@yn?)ATSՓETvVxuWKyMɔOVuUNiRP99ɕQXX3]5W*i,YFpjWcɊoySl)gn9APS7AOx)SlYZSguq, "ń#bh$%gydXgrshg@wO\Lgg]	Śu'ChɒID˘]8^cbkR<nBw|DzhGy6yi{dk=x?nGqb@gfeф/Eǂf[;6&2iqc}Ŵd);&|Y7225tdGf~C
    :y^vJ#hw#ȶK'93%0:Ij4
    h~FkckDN4F#jq)`M6#*:&Hd9DFlچhqxJh-:|зm=:נ{ƤYZ[ʥv6~z4]sgXBouz�;鴤:pPY
    J
    3YW7YI貝g[*ZIqؘYة0.>F*qԃ.i::諿zq"$yI_`y7[Uy.H3'0iHt9"•Cjg4䪚txx^iuhI;Ģ׬!Ww1vY{v|b~5NhC	J9WsmB�ZǍG靊Ha9Ԉ~gE*@^J0 Xo{⭬PhB[T[ǫṵZ5*EصrgbGjm붎/١sKš1ڷz-Zx`~{{r{+UŞw<�H6Oe[:k빛{b4 ֺ{kKka{Yy;9FT:HYLu+JT`	ۻ;֛ػ]K`˻|PKo5{X`*an0U8r(G-~Y+[wJp	.%v#Ț66t!ҍ+k_r
    
    U'\t|[~ǀ,lLvOǮDĻT;.]|Nw4eҘwO|wh:V^JrQ#'�[\c,*<6`PNJla0_Þ	wT<ȧ[ɉ_ȔNȁZɳ'ʟ|_dʣ|=}Z~|_²;@hy뿦˗Hs6ʻl,HUˋSKLiy9l ,ɋ[F',D,|>|V,`+{{[3y2x}=~&=T(˙}3d@4vxٴe{XS%ق*b%/zWzsG,oЇHs{mT&קgi
    *%v*8Ʊ4l	'�Ӥ:+꣔sHP <$5r>U
    jmMjoydKay%(|	JEM 	K"@E�c"hj6)o X~"H)L=՗
    ڜLЛ{<1̀к]uʒ|MڷΕXZSE,)
    ck
    {Lŧ	y=,8>	y(_ە>h#mN1l0ˌ| ,<Yƚ\Ah+F,dYE7(d٬.\Q޺fCԖ8mp�#%Lw$t
     JٌgM5\flLz:+KApr%9ohB*D:u}5k˴Cf:mcJJzز
    zJu./ϒݏJp	~Ҡ&顾
    `~R؍-U9MnͿy^
    +̜YQ#@\<G^4,{iZ(sޚ#.Cl|2UgD'.T&vH.o
    lÙem֊k	/pIjC@)E̢?$_&(*,.02?4_68:<>S:y5yUL"[%VS@@S5.PaROS"DUD_V�=phV_T>uJ&TUCPp
    U@NZ:1#KDSu=E0&Xs}{Wu2#x&@XE>KjzfZ[J޳Edvn#vy:$,tXXDl44T4kDc
    %-5=EMU]emu}&.6>FNV^fnv~V������;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/ssl_intro_fig3.gif��������������������������������������������������0000664�0001751�0001751�00000007664�10147723030�021721� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aC��̙fff���!GIF SmartSaver Ver1.1a�,����C�I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzx5zn|Nx<y2|$~+g%f"i{gǃ)#QƘ, W߇�_,4Jxa-+OS~&*cǎAOC0ppT˄+䐠͗jҚi&&OvFKzLң$JMXad1 =뚓R7qtT[4H.eU:jݫJ`Z8%hF"ږ[dX$Xj~
    [,7S+Xg#-7bL)qʍ:]hʾn-9fݟ'
    FR^WiL_c\rP7
    8VB=lyѹ^__)5!/Cq.|==
    J|`|6mF8؃V(džv (bzh:'0xU2h%t<~1`)(5AD&ߒPF|!)XZ͖Yv%.Tid
    yۙeY擣3pȦ*i')b8|.`)V"砈vq'@9梐V
    9X)jp.|*N4*	v)^JES�,0+Tq>DB&l
    Ùr["Nе8l2aӰbu.jڋro.p\ްoRyW\pD�wY󰿮Fܱ/L)怯ɥؼ3qn,0ss6<Dy%4o-;A;9n4zu_0b`e7zljƭoӝeޘ.vJQIxê.("1nC.&VΥK9ؠ3x?:.ش#%CAS{"pUپǛVdOp|[|OȿRoޣ~Yd~#/vƷ篾U~ȉ1I,�*ACg@d€@ vNɀP3(@ ALn@DF<\]D	>4+	IeZ3)WP,!+pH%ωXCEXbX\i./
    Ad.a`kƥq#HmuqvLx8-4P3F-fScH,ЃE)$m؎'r'AuytAK=1pg
    fCI$$]cHj!d+=PeF>`/FI2�#!sTqt9#GN=(;I^Α[#M2!-]IcN$8	
    7RҘlif&bvP"Ja
    YC3]<(q0
    1yӋ.HFDɏ9A7rk>Jړ<h BSixRR-jaN4{0j=z\.yUQe5XV5mZWu-Y�ּt+bZZaYF=.dsc5MqHVJuld˿ֳ
    ΅XmhZ-kg޵bֲocV=-!E.jiܪָE!c5]V7GCu]V%7Zgj,z':+|zYN܀`wW
    .҂;a	?xkzF=5,[=8+ً>8LqNbc֫ÄmؾCr]Lg)9R1ee�xy�^�1h&+?Ʈ'39l׼g:0"[x=yφ>=9ǂˣeҕ3i`ӛt(R;XĘy,izƢMDzwjoGh&󼤜sOl سu`*!Yu;i0N7kJԛAidݢf6Wԝj櫋mdx6]o`׋z	I޴jr0h;_fGP{{˵|sMqyere<0坣<(+C':ܥhN/+ԣ*QVRs(L^ϩX^<I:f'ڦ}mЈc7(ǽ6~wvjq5/T+e<x']�n-7-ä]w_5[L_I{	w~K/M3&+Lv|Cع%+
    F##-Pj N\;W/5<я>훿_:hIGoZ.LϿD<?'oFE\!
    QrGkg2FȀKyRNv'*NBhy@b!eU&_(+浂҂.*024X)6xov:)9؃ƃ@(?8&FhHp"xzL؀s7PUUV7XQZ@x`x:se68i*gȆm|Hsv1hxzHMX~(z"HnO9HwqsgsmhW,r$nm(q܅8W9ah}f>S}{5'v&7vKU3CfxSq3'h(AȈiusQE!Q<7hHf\UvkGOWdaP%}~;Gp
    MEsy%ЎtXA4WAȊlց�5MFwe"9O**h,֨/-w0;$^Qq8BY$vfrajC҇1fIxBYӔs?	Ty{XN;>ȕ]镉r`b9fGJiɖ@qRrIyuI&tyk—n(,~I~I{),iYm;axYYb.?<Cz}Sz5z
    	x,13|1s,y%yŚ3%I)3Ƶ9ٛKh<R[˹9)ә|i)~ɝY#QɅYp詆乞a؅)w.6i3""i�0�Zz
    ڠ:ZFsؐʡX$%舡b8>hO&2&:(Z Z*5tpu(h<:BZDzFzQ;jMCc<4zVz7ʤ+=
    enD} (6fZ'2ƥq2J\$OrhZej8`>	A҆3PJjI:z:dl	wKZHWgzr60G$e`ʪԥʌ<tx֑Zk/~joI&By9ͪJjѺzzZ݊KȐʩz'�^0AJ=5eU]=qH8$GdRdI>'QSl5Ko)|΂MtZfka w;.|?@<=A¾@ĿC7JKL1O-P2QS2IVWؑҞZ۟\([]] `a7cdefghibklmnopqrstuvwxyz{|}~3D������;����������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/bal-man-w.png�������������������������������������������������������0000664�0001751�0001751�00001334171�12663316405�020575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�������[���sRGB����	pHYs��%��%IR$��iTXtXML:com.adobe.xmp�����<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.4.0">
       <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
          <rdf:Description rdf:about=""
                xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
             <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
             <tiff:Compression>5</tiff:Compression>
             <tiff:Orientation>1</tiff:Orientation>
             <tiff:PhotometricInterpretation>2</tiff:PhotometricInterpretation>
          </rdf:Description>
       </rdf:RDF>
    </x:xmpmeta>
    Ү$��@�IDATxu.OΘ�`AD"	0`h*'9|~~o^k%5DZ$JV %"�� 2H�D�s{5žw�)U@OU\TÙ;222f[nhq!\<(|bmvE~~cέ=X9ӈ`9<<<<<³#]Ow|>RPPiqywgl
    2Q76y`be1P`_	x7{Az30϶uFybs
    `O@@@@@@@@@@@{c1h58lkuR„ݯY6<�=rBsD-`uۢ4(	<
    f(yffft`xxlChIDzx}<y\ZSaI0`h]䒟e|wc.K/qJuѱ֥-sW䦢%S`Ļ2|8қ6?y\,geeE/7.<.T]%7\.HL<:;;:> lMWOEz@Kyyy(**”)SP\\|6XΐW<YKeip~!A+|丁{G˟nYj؈( g#??~w%J{1dom.g[\dv1dLFŠM%C:m#v{~{1\nUUM
    <һ:hKH3e
    Sm%^`n�+JGZn#m"<]9t$Qmmm8rHdìY`~d>‰?7q$z]XD`waqzD,a+,֙\\\\x撧\8eݗӺ<^\V.9m󋗸tI&ɓ^,NZ^Ѐ3gDM,Vy@�vwuul0N8QwlA;ǁ?el¹L9\qvdM"SW4A@
    #Y,LiR>7|՘?~=xI>pa,pҺpɌ'ɧwKF:pђI<N\,\3I~=AuuV4qT0MOӫ.]`>\~W<]sL^[ZZtRß@�xspU5kPN<a9h*x\@GhS�3E[!Bĉֈzdtʢ8D?ٜ):q(h;wndڑL.}wLlpnYvd8Z񹰋Ir4*'('KF+[<NF,\2,xhwǏcŊѵV=Gj@@@@@@@@E@b<hsJq7y`A0¹Qg7D]|9MMSha\ڤHi;<t/^Ġ]8;KMunYz]Xr`'^?wD+Њ%ˇՓ`%+*_wi9h"̞=;r@@@@@@@@@=Ssq:sNWy2r8GKKrʢ,_e&~슁DdOS>mÇcԩQpN'=_q9iw˩`Ĺ*+“ѺpOe<].\eG\>WnYnⓕ]zѺ_4+zy0Hܱc
    )x x x x x x x x x xx-:6n@
    LI+^4
    I#Y)exI$<˴tԣ`^x7'
    )b%i|{0*\;X֡Oxʩ([I2DJ`ڢ.ʢUݕ|_f2zrp,ϋ̙/WY+0.:$Stt+~,;H|W)׍#y@@@@@@@@{^+]ɧ\r(-勆ꂑ/6�7D9<ӧO>D	�>Wos.w.q>qyX88$''.Â/#GY~wp0&,YNZ=M.<T2m#\x]>v2d$z\]ׅ|A>]YneNLUTTDyhlsaD]C.M(W=t9nwЭ'}Lrpů\0#JSߡ;ЙCqx%]Hŧ\4q|.匬laA>^{aA>$+o앁,kO=cM"Nɥ\02m+v+9ч	Fg2Tg.'xD`|Z'ӪC8}<:\s[oťw:1cF:iM릶6t]@@@@@@@@{oYA׀i.7SH9iI7s7pHGzW%dL8?( rsiXh)ߥa}2L̹]ޕ&{%Ot.\Asey2Z.^AwD}z#XQifϪBEC|݀\u?3٣سmfaɂ9a1:/vx0}{icGK#Z:{1
    yM(8D[s=ڻP9srgD?k"g ~,4|)@DP,q1\lp%uee_)ӧ%LgdWy=qQ+)\#N+GL7^7
    Tٹ{s9]y.x x x x x x x x x.D&
    z1h�H9AY|9
    +,_ae^hR;=/d;#,u~Jp	%~sf?s18a[nr]_ӌlyrW6)vz22owsF	zNX;m5>/tʛ_GЩ7ct?m	9c.29A8ͦܜYjX{6gm1'7D]OU~TuqT0ī<̇u3u׮]x衇p>ğP~={D0H$~_M:7(=0',]\oW<t6q7;|\f`55XOxs@ίS.PS0bnM\#?Rۤ?BǗʝL[h/KKypp.e2wܧwyp0[<@K/|gL?~q\we(i^CG?p˱`Fr6Vw68QEXl1;p]hj%/E͜*uam8jypECg!OukW"s9NT[kp?_%f"/7gNc?ԟ+n@FV^9pVXl2ط�2
    ʱ򲕘QQFss0szM4f~
    zj}.�׮Eei>ۉVV`eδ@,g:Χ}ZՉOƟ.n.Z^<sysswE\3]$\ug͉0s|<x}Wh˼u	wA2rs 7\E 4=p΁8™8xgMyAV](I~#N^:0C\-ljj¬YI	گ6}` ɀ2U[I9ps-DV'^{e+eo�xg1Γo[=Ỵ#b.NsW<AlG1g41T:ׯ3o38ՙ~|'l)uaji	l:jO̡#͵{-f`֟_u,YG
    v[pyO:.YRx/va2<#j	ʳ{#FJfW@+/ǿ/xØ]Gw{F,,y0vOͭc}l6\d4|7^NɜϋEP'+_y捻kuH
    hsNfѣ8tq9N
    E<s8q"L2%ĕF[O:9W0LRҵ,8H̹sNYYנ^q9i0HOfS:rd']|It7&_heKFKOkĄvF{*?-9X9
    qQjhFfVNYspޏ53{ ?E/3+_{жͿ#{sp5+aJ6u@<ljev?
    XvgqG>gslw .LGQ]Xs(*/dc7*y%㛏YyS𛟿*Tgz&|P^5]''^ǁ=۱HXUS‘׋wa6|ף"	cے)܍.B_o_;/GHs/|/Nx]s$ZWw�}u+wr89k|%޽{7lGxUWWGSO=rp4Fdx@@@@@@@@`+�g&HS
    %KrX׀^dŰ)le/nq�}�=ݢwqIGK']K+<UVQfam{>{L-@k=^8Yȳw32lP"hƮmj4kG\fb(ɷoaNe%Ϝp,,7V3uހ}eSEb>֏oEMGiQMخ
    3>DԙX2U<?pղ9Bo_7jkQ;)N;_TYS|䧡$mQC}G3؄rҊ5=h.vAsW'{w"?s�7zKe+Sˢ܉`Vڑ+9 NI4	O|nJFK={ױs(HWnF1^.Dܥs
    e">]W_}ud~M;S|9jWȃ8"xVrVT&dҢPrm]:&kS1 |w[PjLT,H&w2q2mW
    <h~Y|Oߏ݀޶f.V<~SƇ;dۻ޽B?>0`rԊ3kq/mmxq#]L1eSau(n
    [_Ne^|՗cFY!:-޻e3ۺ}#h774bph=3	\ݵԏⅧǖCG?uLmϙ3o`=h<sQtgE%[u	YV/)@wGѫ=o,0,:6Qy"d*rΤ&h",]4ʹ_W'<ws
    Uq~ras̉%K`^O/a˗/~P/+ԃp]Npۄuѥn9^Bx]9qٳ.30Q4stW.Y5rь[�Vsuu<pW_نk?itd'?b>S¼_i,l<9|׶=|wWQ~iite5_M2V~qeqZ˯+gG_^Oȶge?p{?u0%X`~U7rsc_uϲӠlYbtl~02g`%>#N~Xjk:fPY8EfJx4Q?X9s	K&d(OOH#~gdԀA9_S6̤<HsIs;{'
    p5t镌=a[TEN}&x09}49}Hz踁%ҥO8X3߃&rԅM8Y[2XPʭ}=+”l}fcro*><~鼸S
    P_{umZ53f6N#͵weec?yWGGP9}wktT`]6}zۛpl-:=Hȵ|gهmջf6vLns=-?MXpv$i
    #G?y[aDkBA%;磎}V)[A}%WehsWɎ;bŊ]vRn\5@=-Xk_ɗnWG�x{ Iΰ
    UVE,
    `3@CLӑ?5W<	=#跕Lnϳ[#6	1bmFoaaV7Ƴt94{|h�#F[ma7yzyܕ0@̳;^ۦΏj8W[3\gF˶@?FW,p_\M&;\Y'ߠDug?1wpX4;I=g}ȶYx~d~z&unj2Z3ԇ-�mDˋǕkA:r?}�x7z IΪVۣm4n*!%IĤ88X*Ťg-"Â%'VL<eUNHY`L:ѲN	QߙS$MV28</*.6mDal(1o7סg�S@";6ؘNSׇO>yKFݲ;Q$+'G:ex,x x x x x x x x x⁴A8T�ԩSתsT
    &W؈S \01y%WhK+Isn+'NK'gW⍈9+HR]­	ߒ=SFɱbBs|&cd/sv#9&*%m>ՕKᬻIQu_EDzhYfbwa]~p^:|p[m<~{OE�}+a+| ߓe st7rחGKX288uiI.-y]ZLaJYu.>Y٥cܺx'Fu:6ضΎHo[|RkmHfx81Se&lP]H&D#|(O6mZ9l[˱c݇	ɞoAS@@@isѕ}ݠC*FCgt(`QpU.\e0VtV/N
    u_0(OO/:,hoh}x%*+?JtreWv<6YPų&'.-Xg0w^a(..]IezB9x x x x x x x x x xl
    8'+"
    ?PlgruNLdW:8&#OmMiɏ-\WFLy2hӱ׵ǗI+,˗y-FgϞhbi>sh
    \ْ	y Vޓ:ܦq~QuuuQ@RWWW%8@#.qa	p9:ܥy/ߎ"t8$a�_4R;_!
    WC
    @/~:s]f~sN`E̸pt҅/6ʎA^ӺOqx_x>Luv2|xx㥇Kå4!O˺h\	 6zD_w)x x x x x x x x x x 6>k0.R
    Uw8ڸW#8y.}*$#.weOYW`"Eu)-#/]>N~7MK׮KFn$'#7-uv&)m2x'Q._'O
    9)\2S8N|O]~$	N!O*Y>=i	syzqrDO:/<ݮ6˓JqTSuߥ=qtq\+pbٗIdK|&xj+>$_
    :e	Ʋڪ2s%ҹ|+wHnܕ!:NuiUWN:OpE󺴤9Qm2Ļ$+Y!d"gaJ1ǻuWNJm+CS鍳Wr^קMFGd7^ɖ~'}T:E'i&O/݊389?NOC/?NO/dz2lk|=�* pGhb=ހ8Oڅ!x x x x x x x=_,tǕ%ds+.ҧ?Xu>wi]zW'}:r]^Kqt&+<NxדM.'I80ҹ2\D<NNI&¹e_uV0悳LqLE|*	p>< \H+Ke`#&dIph'h˜Ʌ' ~WYl!p.§9OD8:¤Wr]˂0?CC8:wuH&8ZѐO8
    'Z})Kr]..N¥˲YfJ&'Mrr8K/[|^<~.:EGp7rDz+%¥ץTgN':Nq0]\:ާsePn\X8񂧒rWr0@ओ-a</ɏ/8|28>,HʤK}gA8"0a]n9ydz#]M!,/Ԯ8q0SJIg>.LJ?N)+~!,/X=yRy)^.N..Fɤd`NҸ	I&?q;Txě*O%#26%Kծ8D2seOwiq6|މN$#dLMKEқJp ܭKdrɎ&!>N列e&\z$hq0W&E8'D4“6N..F~7qq,!\"$ەRѻ|q\},OD'қ.>88DNz$'\\
    ʏ^9i\!i]0SJ}.o2XGEkC*'.כ卓I}.O2A(m[w	c@.%uܦI<qzR&jL*w'{[I/۩d;w~=_>J$򉗹+BzvO&6_毚j+uOt~lSRжo_la2n;Dmc(<p-{'0?ح{\.t
    YGfS&pϘ1IW:XJweƅLFlI'Zc=Np`p̅wa*򹴮,87q:)![>L.N:}xDqi}z\,Å7SUE\YqI+>Vr\`	'	up\p˜\_ǷCTqFWxwst<`}8ui.t>έe#_p񻼂)y6..n;}2\Z&W|䕬d<L,Jqdz]]Y>/勣,..`]D#Z	wiX6\_wwBїߩz	s^/ʤı|1kƙ3gmqg diQͯ5+9|<38Wݹe}_%+z@>g%<qLp!Mx+3%',<>n_S.|L%+>aYt2L.."#:ʔ<EOe72]K$	v.\e4I7&.ޅ,9A`D<ܺ+«ua.x\≣0%O/t.̯dޯ4.q,qV!4.̯|I'>x<F89q/~]8L.><.du fpNA%%%ʹHx\e.Lp<X
    ;!;Dž$>ގup'!m.ctx'Kd{5
    \6MFdh%'8\zӥ&#k2~1elEN/ʤMmmmBt{>yz/V&M9߱AW˧L`_	Φh0UYY\PH|qVsss, fYՃELwEEE18?{-c&OgӸυJN*/GtyҥTddMbL%gtOn"Ã}NI]qq9\zīW_\QpǹtēLv2<Șǯbγߥ:A?VZZ;
    fūL8S~CB=x x x x~ۤ>z`{g{Н#3&qVWLN0s)x pa6/%KOT׆/[דg]3Ix‰Η'OƎ8ttCۥz2dp1'_:.
    dur?	u8R4>_w8ʙ&]ӳms]w݉VNµК<nEaL68uHt_AY-p?fk)_Cp@1nI^"'%%Jm'AJHÜtqđ'ٳI�Wps5ąOtwwGKE={?r"fߩ�]DX$,0z{a<;3{)#d19+	wq+e3_g.t�2qK\QTs.+Oe8A\SUvc.n>D<gmI:Sre0_EuIW|.=a_E<n.~ĥҫ_reLT^ֵT:IKAYs
    aC8h#Q9J9(j	uqe0.Z/xWW(d6i,cOM$KrI˼.],\8]t/.	c(7|O5vv:
    v:1/Ht4z_
    XD@mPjԭQ)?
    :et~-r
    O2o3gN!8&N#T	miixNIUMx"8O:&TUUE0ǭ|!I6H\_&^/]&Kn�?ڵw.D9_Io/߯oymu{:3Mt$otfHUwHreM9'1bPd[y]S{ړ|R]*33!w9X;D#|J&N43q\oo_8Ф`~?9<uT*ŋ >,d)3+"_
    .>!~qHu'ר{^naJ'~7uan|<vr'*rIsvrӧQ]]M &>,±N)DDm"}1uT̝;7O&󅯓]l<u|&=N6
    eeeQg(:t߮ȞQ;6�:/.OF62NkƼ0Xg[n}뗯b\rYW7Np~]p7
    s넻0y>@K/jwN4~Ӳщ#G};.بdJ	N<zwva%Xd+s϶)6@	Ҭo4`1JtBW\+V$
    u)'3K+e^$Ǐ㐎yՉ rFB箭lQcX~Thg,5%,W#8җ|sv3P{Ny0BЎDi1$"Rʏ|=v
    ~O)=xM>9Y (;2urFً!{h_?Fз{vF
    7 gabwWՕ鍃r8ػw/|9̠˗G<''9I"O:|tˑ(]@79*O&=y544_L|łc0q|tI?q<H]/1~_@,\T&M#~^\јѥ+}\
    且vP?dzE'<Ǽ\9mʦ2p[fM4A\*/+wD}\K.:?*KhTW|<l?<LI\Q]9mgHҗn[_HKN3fD4d:%ågXd"=]d
    ޛu2z
    :`'sk[,P7$2"ڹJ
    ȗl5ĉ435qdAH[|Z˜#y]\Dh\;ŋyfΜݣxm眶Pl/x�ݴT0Չ\[%Ők"Ϭz}AC5:*WwХ\@*9ͺh\	Spuh`;v,P|nN`!=gw:]Iۨ7^{
    ĕW^ܓ_pu+G}z*M#¤9s +z)`..sr<YƬȰc|UZ]ıq{H9`[Xrrl {S;W>)=3D?v[̡z\~<㳀(?\9b+6l-Nt$0*+'gN{!ZC6yAd`;aGxVE+g`tf5<E7 V>z_=*v 0Nd~a(B8~h2K/v!p5矏7$"1oɄσoa8oƴ<.#-s8�?]"bA^_W9i0&j0q2x䘎cHN411!?oN
    OEc\åxAǎ\?	G^pqo	'q:}yIC2F%*+'2u;wF[ܵ{&+m,KVNV0Is{y0e D[8FuҰDZ/ō=XwmIO%[Oh+zbO8yCۨ΅UVNrn{ݲQg{8
    9Oۼnd
    swD!G7!LӿIQx	9xž;<8.'X7˜:>ٿXySSkN'8u˒6p(4<׼nx%H#]/{[Nvf$}=#-SeE؂�e0Tt)a446.
    /TYpư3S6֫R>y(Gx?p�.\r466b$�u}Ee΄L^nÃ8v(rK*0ju2^	nGۘ� 63l:a?kVUVgcYwyم:22&vPeC轁n446مJfPlkFK['
    K0mjYt>賋C63fr7&suM),ʩO5u^T=n3<S\&4y-ybHwZx֯c<ʐopޤ
    C;eJNa<yV_$/g1z$۠_Qߦ>3fifc괩@ʹ
    e`fU>/09cܷj|!?S|yV{dۦʦbjYI#q6tQϸ4:'kS4ӭ4dڴa&-%V-ј.zW`{z0"{ 1qۯN�8E}m	Y<gQ7n?tiɍZ>vҢvc8+m)-{?p"E0%k6m\9:?.m+klgQ@é+߅C/["tK)H6́7~Q@#q,}h+|G>Pt]xwgZ9[P^#3>
    ֆDR?I\S	
    52ԏ3
    ((@ٖ"<p|p3%,s51[L㞃	ϱWRz%$q뛁
    5/y$ ?DϾ℧,(wxҲ̃:(
    YǕӫ.]:۷okFySQ8ēLҡ:d0瘞�9וr`%9v_fN3` |?0 creHW\;la?fѤyeukzi.,}V:p=a?l;<F?Ff 7sM6Q0UEu_WW20.z*`uwhM'G.O2sɈE׫YfxhJlέ]\Eec;xOVS9aW"[c{IGͷb̄},Gwh(t";`EKS/4x1Q:,y?N'usl$OyTLt.oܖ󢑝NG[)wߡ榏d Kۨ7q1>Gog5>מjmܴGmdxJ;i1ضѧfh;'|
    mјܸexs+g`xhm]x?zeحrf$xIY�Z	G}F=G-@;U<��@�IDAT~~x?f|¬q^L;AIN}2gLLXxZIJgһ<º0N~LvS8Yo
    ş=]OD@•㖍8w;^>;MRĨ/Iw\kIо-x9;\1{zchO=6a7`?SeAӟ`ƪMd۞A5:Μ>ʨ'mNX3xWpǴ!͘j#ηKEY2"sqc9&8_?	U_5~ȸ6K-'Ju9;!D;Q}
    /|ь#<o}[رcxLO#);ύݓgο٬Bh�N~[J[f50d4VI>]D4n[ESlgs=9\cB'Y	]#؆{9p9
    7(&e8&g{u
    vG~nPsUß䁸>N?+r̜Q/Vq+8HI7M
    s,99cU"-mᘎ+Mz™ϥqs*^\⸐cIҰ <珫]9,3%ܶ.,KJn$s~8#BCuʎIrVgN,T:\.gA	%ḟKC><^27ۨW^#k˖-
    99IT5k֬蜸1D:vsvY\`4XAP\&百QFtVb_oٷO^+lg%]>rsa<&,ұ,lTG'ih3{À$.N0^3I.
    ˢ㓱ɷR>ľ~>Gt8>L,ӟ"TN/TP8O"C3Y,Iyry^z@yNF;-|'IJ^\k<
    ,G삫ðU.`^Cv1V!gƾv>ӄ)娪|k|~DhC3Ph>{ꑕ_gWC:Pk(*+zWo}|PT`~"g4\1zvU,lgƏvX<.Z}u~S2?+lݼ/>ꇦ3_Zƃ?|S+nlt5dC;TDqv>ҒiwilVkʶq,0jNG7_%2~*jbG+uSQMЖ|ۊӐk36�&[̦)<kGɠɊAQ6uG`-l0g49-{fmwDwcf73`	]`(&yQmʱvkabk%p?`֮v⥝qݟ´N|߿sg!Vx/ۮ>"3As֧[;rkga~{VصeflʹO:Z;`3Lb8YDZ⶝j[{i8Xʲ.d#|8׋AÕ"yDvtD%7;o{
    _ڇ;TW+W/m9E}ԮJlB~c]-Go堷>q
    3{F2liI0lT`>WmQ˶-ك0:ܡc#+=rqQAkzNryiwwvت~n]1ڽg۹xor~WvІnXDY(+bw&̇w(87Fugʼy6l%}n~yl%1�=rpD鹋l?YU~Fk{-f�TbLjwY?uu:N9?x$1[$q3s|&cشysazlt^tMwdsͭ6VRc=v-v_0lżܞ@y?ktMy?	YpqE
    y=1ͳk44tqlŠ.k2M<d3wijΠK{쉂%3:%fNL#(.]ql*=al/m_n]4.$_1#:œʖH']~[qh \rmc^~At+_L8E'@rl%DA'Iqd+uKnXn[x^i`[>/nwaMsQEOzSY1
    ii}Mt՛Xkq,@1PsQߗg`L\>ޝgcD,骍dqO/BO|pg
    q6$`jKDzg}Vu}OM9nr,p}uD&˲dhD;Z/qANLrE0i+q=7}yPt]$r:7~~V@*ag
    C3[UW])lWi	dS6n`Ďm/L=$ֆ\t^>؄L_چ|_oAT.ހ.|~pr<l˟
    m%o�K6=}8emk—>~h3bFvCjc^e>`vbf)^5sF4Jpm5akun9Ѭuyirϴ4:mhC7n(/.D+8xp56DT[~x<i𥶢ԆW]-G۠AF/>TEBNڅ6H{}anYV?A}/gu]š[˻,ɏ7ފKcOcgsp7$~*+6b:rn?'6?lw|ʊ`!۱jtq}#6]]#Pb>hFVIm?&_;Z
    7_wzV'ЛYpkqqQ^gZW.ç?TY?қcAM\ٍЮ^Ol72ZvWU`3N[yr ZoQ5j^>w67vavfrpH<-,C7LFq]susbn+Tc߫kd6>,c3k0ͨAP&g͈Sq@ea?71kMn*57{W6.jM9Y07٤[6kKn8mi}/DMD4ۃEh<~�'ZlƂ\߼Ѿ4ق1g")76qo|Gjj\{<s܅xj[,(+ۯf}ħ1<㘳rn*t77n3X8[)Vb%ojdzoMl2&6>Ol>)TdG=֧{WE[}ܮ:<fd@zp^g@EIntۺ`<l6-vؽ&n,]8/{$M\&^tM>>|_3 ,ľa])*}%?k.{:F^=%n_
    +</avhلR'elKF떃a>ș3QR>HgD7XYcܥkW"<7k[ypMע!<g0cڍÚ%xG,YkVǮ->|b3Kv2W
    ?Yqۄ^=n%ߏT
    ~‰o7u\6U"Vξs'~N݄Qh\eα!n)SL!?>}zr9>-h5KNpN;t
    ߗ+̓Dyc9xuk#$G$ AZS.'@8f`Esn޼yU%W~&_Q)N08yOG/Ciu2XfbYqU Rtl';o[0bV\0oT#.Lek%\[M~OMppKB\Md�kڪTk-)^n1bS&mWۨ|<Dr|}7+?:LJF/8uZkb)\2=a9d|ma3m!9}wOm,+o;
    fRNB΁WL&4ttZ\\G8gx&f#烅KrStYyȳ͏~x�߼o0,YXZ܍U6[2ڌ}�'maxmd<ugQ{
    ‹W@?Ƕ|{n֯}^>t:Zp{k?YF+/me�F;jёU[j[K,/طfUG,Wڪu֥xpΠ4[w-h	[.Ai|%>Kqi
    XZNaʛppb<ē]nLs	n=$nێk.[[aelU~blyxy.]'r]k
    e>L槞ĵ+k'gn=p?%xǫfaAɐ=<ZqoǥF].vj7؁n<Z;?9,[@rFcUarpm0#_8p|)
    m5ЩV|azn|{{R,jKgMSȫX
    ^}YqχoA뉽.^ދ?I̯<-l^i-hwؖy֎SCCάKp%qbs8؊)S?y~ܴ;_݆[if=ldcpx׋Zp[8m'FtnYPaK۰ĞMwMQ|#]z ʲzg_7|?}<~K
    %o	7vv5b1e<~Uv(hWa]}h;ĵVJ]SpM	/^`hmV]bӖⅳ{C85_1rcN,,/mAɌyt}_u2V/Ƀu-:sùXd]~j48<4r'^rڂ9KLI6+6fGĺ%WE;SQ
    vO#O3fELͳ@qj˰{xV̫CwwgdıS_D]m-#֧~d[`u+P{h/roĭ_b:EA0vO\zpKr0#]w]4|+?Q|hx)apSlr-;oWYaXV {P`mpՄ-zcz̑8e\Im.01@=398`Or=fـc
    ֿaɚ;ZeEvoƒf=|r\[[_AM
    h?ʅkxpW1>kA	`zm/*'6VT^n
    ;>KfZbUµ1n[Wd LximLr7vuk+{8Ѳ/k+>\OC=\Lkuɉ9~Ըѕ>ѳm2� ql0^+j	w#prķ]rݜM\=9qs80x$|}ّOtN\Te}cޫ�9]Nl#mpTpe 8!+Λ7/VSIK\R	_=>̓uq'YC'0jtX036,I.xVڎl^5ꦝڮO.@uק~٭G+`y_#oH5jeT|e%ʚ(&^9xTMص{2x:skMy<:zi[er\xsgL3.29g	R9u:Ãti򦤙B^0ԓn޼b47Xw�g*cR[f+]jm@c<f4|my=ڊX|b+x{0:}
    ;v^1淾56M=B.It-f.	u!_Vb{přŶ؀+VPQhGpglulLZ{�eڗ_f),�'vQۺkUvTKYոeW\eAaom'vZj9k#Ͱ<Eѵ=0my4*{w~ˢ+'C(GOlNƻF\Fm?sMTsݼlsݼڪ+#O'貙ڻl,IJVC|8o*Mmr_G7xq
    :mmQZ^yոA,_:߶wW5;1dhmh<ap&LSm%[O*ޑ3	u'@Qskɶgf韊?=ҍW^u+Fr
    {O5ҕ豭P6̼b[hunGpPgrkÀ},n4:ێj=NJlb%XnR2v>vkpe7?^}u8mO9|�GvoǢ‚WSڛeKpXx2׋6#GOlori.Y^HvdD+Z`@J`ܗ389SlmõAQf?[4
    7߈SgjlZk}+g2-GIEItew$d9'ږCG7u/`BSm3/ߩ9ή!m;!˪~.i[E<|wjmEb6VW,žم챀ݶnd$]ׯ5^ʬGl<5㸽g]tޥc%͵A[\vlv:k7%(]]noksJu}8x$Kq	2cpk,^SNݤ^AI/ewQfgbvOcU`2}dS]=3&W49�>)|r`g.pZWgVPދ
    THc|i$?͘IL/F[,`Cҥ#.e?;{efΝ3yW&Q^hϘzݓd;چUKeO^u^FcAQ8i@9PFVcUJJ١٥94蒄52$G0O/}1MN~-^]b
    S5#yN[ЏnŸj7.4e~˱p~q噫:౿reI3)pn@fQsRNy4m*4-lC8kMit5u`A:0ʋilϨɉN;SC]X7?:R:)PN\&6
    㐎~R.q`<QjUyʏi"/ݜB(G	egUMC?0=1.Q>4,JiӴ%Ci,'<#Q&ø6?+lko_%}I{LjV.I/7qv5b[d8QvM_몸P'M&LTۦxaØ/Ĕm
    ٦hyi	)?+OF}9-,+hm|f\jl\ڬI,3R:	%RGcOc>tC75geg͸
    .ΰq;;iIZQ7mM;l*Og޲g)ّasV.Τ(h'|hεrU
    φ$`*!՟MRdTȪȃ*E.p4WwJjppH
    .`XӰ^MQ9׈&;b|_l}wȗGtJxⷶtVB}e�N�@%YxeO_,y2r@yGJ�g	LOft9g.<H!̒Hl7 LζzLۍ*9ކ}Ybc0KJN&ЬXQm?(N9:]L>¥qYyS]J2@d,yM90al7l]V^V԰?QΜvcfj&ckI0zDnBí+oC65a*/@@KSLމkWFI+wB^ؙJdz0	9й]b,]AFO8[f%y;hۂ5\T2,Y]p�0MKl	7ַ_ٲ0+H641)I(
    خ_cTb&lOHm�u3zg
    9i	2Iy[~Nʰ;"1otP^6jDSΒ&ϓ	dgX( =qyM{kHHq$zY
    r0݂l:sEJ|隟tv^Cӄ8B{Cf0d5ro}5MYR?CSg$gH^6YGK<4<Ӛ,X<[,w2Bܯ�2~!@(ϔ²Z<l4eʥ$-3O>lYl)vKKp̿|^>UɆ,?b4,::C#N,ոoפ"4ؕZc2l)zSvtFiQ#_g(L2E^{5>{$h^qGZWwx$|`3�4hNZY8i`8IGIV!="SeزOmMmʹџ3fxvFvt8,N2\y}Rv ߄O'yYIҰ;Vٺט#^qf9U(:Nrrtb3&<1Zof<A]h<ݿm)O,0nܰe߉e餓N2
    
    ʦrعe749aR;n
    ",Krp1wPpU.;tS>A9an!F2{8ceߕ#ĞntuesMz{?ϳĀi^4R&MPNmĄ}zdh v2oIwď8Xjf@|Ni<U:Ċy˝\L,9[ԇtć(g.r'W,ⶉ4{wJ.Nl<(V_'pM2jls}Z50S
    eL3cJk-QL,DfNn7ŎiҴk5mƸ(o[X6O>+X:ST0B|Cm-Ʊ9u՜lfcopgKMm˻?ꕨU0Ka<L:f$$Ұr;G�ؙ͟fm$05�L6V/k(b^tܴͬۑWɝ?}4V)߻j\\nٗɂKa#e	C|Qn:.5rϭ
    _Bۖ3{
    ?UrʝzLN;PꮑsοT.9oRs.ZaplYsqUVGr:;7`Hmش͜cg՚
    x!mzq9fһINF*Vc\#5
    `8]p.8<%j[.�*'ْ2ڌ[;֙8X]'EyYuW{7ry-Rb>=ps.(c'-jWoݿA^_dUYӯakrai,zYһgWٹ)j6;&X8G<nt'D"Hgl޻{Wy2|pOGg%3um^Cz%;l<>d,ضct&E8v35K<Zue~aw6\DݶI`zSq/�/TS	s^%6ɡ̛
    i"г%_d`%?;@ljl#&SJ\Aؾ=|c83^TiHO5XXَ8Z˛ȏTuGpbEql} Onmq!ܫ[>stGۀ	DԱ=GL:LzrQALx6ņ@	&pb2:VB:~]vXŶ
    +?KI?L4upZ/B얤<.NM%[o];~SlSo4ETy/oHҡRYdX%_>wԡ7+sޖ>I#.X܄O;r~af'"&6T;vI圗_=d+sd8s_&"Lh{0IJ[KLd@D
    '[jQ9pjލ#o⾅JY-ٶWW"0܊~V~ڹ~qfӰ0|PQ$7n*6Rj`=sTeGŖ|rov
    r2ڌLŀ>	'095GmXi;gj+oĉrӰ<w\39ζؐ}>Iѿ{h@�sE_M~LWݺ`7nF'|hHo܁QQeD_swLyW!ܭ\#AU	<Phئqug.v9L8Dv,3<42,SQm>Sp"L+u>ڼ9hS_}GHqhٲefs}F-A)}NA|ɋ顡M?88<!_5Wʇ6{X^gkfzXN8 fPpP~9's8e	<[Gܨm:r@)prlYFe<l<	\z峯BX&9hLLwy3D?/an¤@Ę$fA\Tb1xǶԗmǺf/gMضxN&1ϟo&$9)'s	>[=@NPcRYfw (7aq32_:ůBn6K,n7|fgfكtK|f#KZ/hl^TLiԟ6+�;nF_ll4MwBBtCY>qrw?YRe7SΖ*ߟ;XIiκX.f̔ .O1c479@N8C;{ZnM؎]'2eI8(<;yR6ɳdð߁3$Wqvr<yzȞ͸)$fcOVtx.ycaET'I�|"O.ι>/=xRROMܝeiR‹ VY!;kƥ2g,}w7+
    }
    .ۇϧ=Vٓc3|2gbytx]f@'Brp3'_:]zƭ9@4)m]{ӧʬߐmk{&N(C{ۭ{|0PFLpCq^ڝдtA?Λ})t_T#:[#F.`øTc2%#uVjt|+#N!/3>g|s6VϕE.�~
    =Ǟ$瞶GzRc9G
    N8c`KV.~S
    K͠);f̉MZ=�w2qΥy}9Rr�ߖ~LH#q#5.( M>C^3SV-@<f\0V	Tvw!T95Yz`e*yrtrd3_w\XZ,sJVF4˷`u,YV?[OiJn=eSd MNa/aw732U.~6&#=\\{yrwSwI&YOJN<clyf,n<x!EYp6c6JzwQpBwӆ7X74z҇(z$cG5#?qqJFyyr'vǸ*Գ')I$n*ǟ%嬳k3\[3s36`rHdESJ12'P&E^jҍfy nj}]w%7p̚5ˬP|_LV[Di8AԿ4o.otבmuk(	
    |f]]?5q&}<$a‰gؑ?ӄ4+beO47oyq'"2>5Q"W\2wF<ϭ/b|B:3zY,pKj<{<o$SPyhL<C<th_e`/kPv壍M3GXG%匝VUo6E,7_=.OyVy|fQvDi7'W
    ;MSt3xQwN7iyn9Ȥa?:p|V2Տh8Q」R'b˴9iUʓ`M0VԟlPj3NX<S:M<Y&ċW7,?gqF[ĜƟV4>m-'|G3O3ZhgU~At2L'so-`9&L;ϭ̳0.M,״OL<Lp
    ;;35L``7VQ1	
    8ʵeT:ۦėFПeeq_'
    ʥMJpƳR =J|fY[X4j#UplaGa<Y7wiG<6mzˤ^fUm2bVPiԏZpFyԩfK((6ӟHpߦ "q{@7ֳ!	Op
    ft
    TMu
    GĮ0VQ$WeP@{7+&'`0_
    
    ?!%F?e`5|gMKJp)/4auUTx0Υ3*¸1d7l>uwH?9F?cpV'Ktv_s{Rz<[N=iхpu%bE6;+#"2+qF耊kfMH3t7Y00-A:6ce*>[ŕNO<c0Øk>KyRS|bB6/VYy⧲ s'\xJQ''&Kؔv~kq3r,5D?If>)	[dpiƠM1sɃJ|FpbY0m.wJOhp0+93|L-q`0㝔	e`ڕG4|?qO`i%~1	+,S&_19XevFDTs2s"uFj1@Ī>Ӊu3i]~tr0>l+>r,8sCe;lqq0\Wy,dYU&eU"?d0O
    .	A&
    ¹ˡPxhi�>lLC]?z2h:>ӂ(2VUKiY f
    hSa!O3mXONd.l\Dڔ45g*02iBX*&#ҴvN3A9F,YbfNÁ';li6WW|=Ҍ2{9ҩO/gVqF3b}@JĤPɒ($~%ÏiЎ/uׯiF0}8{6vxW|1~5>Y@
    M:|Gv29R7*M;土lD32
    0"wnP'K5!r-|oZ'逴-Z[z)&m'b?۷ٿ3m,+zp+9Wm"چ|X'9YUY.W:)gM;L3y\|k:*WɃ|ixng_ε#<{8`dQ;waMn.1oK:)6Xd)j.%*OE']8d4}g:N
    G'W~|l9'Hƶ#xeHo+Rb)>SXg.}\(M'NPNDtq&\nhi8dk `zueyad<c)
    y0$
    e%RXƍ/甘q&`߆mرqo2e2#GvVzǎg”f8AaCNp5ˌ^%,$`bggܰ`V6?-p-~,Rg$!K,V:ajƬ`ӯEa)~;h=h9-d#xb{vQȀg'�iT™anE
    eA8�OHA+1a|y=J"&/5ϭY0flxs?k0iȃiC?.I6\ͤYf/0гLS6Bedzs$2;6sN�?sq}2ߎE=1Q0ClS0ff>Eg"@?$de*D0f|FM6LW	ceEgaH8i/}8AВnɗǝrQ!7c8ch0Iӗj3x!KDP""&		iOt@-}i$�n4ˁS
    >~9hg0zAK33-4S7Qⱬ*z!]AQޭe\<L
    	(\&vg}gG349)VuZ=ClL<I,k%?Vن]JÝ!͒:d$mV1y6K6^Ky9~`��@�IDATqDdG=hWxFQZc>ˮHx/c$0!leNS'??�S)ieyׯ3џ>rBvVo#F>j|ЏE
    Gc6./RdUKm
    <#|O<cɥ?]8+R7M{EyC'F(9Ȣa^0L'3#GYKyx@4l,`;6ۨ]e?wr�}ig8 X>Nb@O,Gŀw3Ucϐ7^
    \H>:|i0>1w
    AH3I?{LG�4.amGnum\<6/56aA,|LKpq黳M'.JKj;2vwvf`4&Duèn@ZEAX9JCaʄ3zʠqHoQ/CLuۼ(+3!GyPCokl5G9M9~ϤK0+/ǖ4'Rьl;}|80MOu_@o͌�iȎX;ֳG`F[0 6&CiO݆Wch~]YyLÞ[3gxZne{{
    3{uNdUBk>Bh8mpPkJJمSVN^Q;}<-yn_Q{)[yMgwKF,;=ҟ/U_tܖZv ό17҄wDV=1r�wSo<MOmyVFF='nCbaFkG0M\
    ZDE\RnUpv`Gv}%/yH7Y8` <2HC?L8e?O{*Smr0ϕJմnџT+ՙl>|Vk	ЙVc?a8v:mkXgVi3O&WyڶJMK0d\;Ly
    N='FOyǒI c/wxBƣq=py2՟_L/pwAkO	}RF5"l
    :QuR9CωNl3:	渎wӵPܙÕ``%?ҷU0;mX&MўVbŷӤ4Gw)vUo*:wa&E0-)؉;6m2I\hzpMYP(S@$W�dEK6_Z!V~߶nVM:>S6yә>s˗gw8uDun-'</a춱QNv/n.L0>)yj5.ƒ|l|yCfn-/lM>,FXiCmv.1=ڏ@zLc
    0\YD3c|1/n{y+E4m?4>_Lnb[NvucÎ6_`~,'&9L);A@}~dGn٩Tat69,IxE?,Ҫh=wMo?#}֕2\,kh0X0 yX:WO{gSLPP}p!o,( }_Ҩ?mhM1&ʉִhnS?>tL#1/-;,g,Gri8́9M6bJ<8)ÅTǟҷ.ݑ-#)fmYT3qz9qIFF/dܭva7'Ithbf*MFز#FHҶp*p3C!8RxGؙ;/jt:8PgG)j8`ď!1_Hp3xJV/r
    !_{<\T*=JמSPV{<>,_}DO;WۭWi~ڔ ~ń1T֚p
    SZ6&*tNĚTG>Zin3#Ъ�7&\D:K9Tnfgx6`ϟґ~6[&zNzM~<}?d8C!"w
    Q|p2/@jEE<a	/(Cݴ*W'6XYtq`.V&dZHßm4Lm;,4je^Fm>s(Oi_5\6=ynUno[a6qk foѿ-qb(/SMVMg?kgЭϦi5̦ӑv<iOi{5[.vn][5Vm EP_#ǒIZҨWm;,Vmdʱi4v>kX,ۦʥ[Y8^�P0VA:#F~#1qg
    s"|SX2C!p�|7Ix{o_AmU&(?d6z<#`o-3v;x-Oy}$&;hˎhtU񦵣m<{G2Unƣ~*j;3|l`;ȃq;]eoG[e_à?DݖxA	t$E#|Qp<=s[;
    WŒƳ1n-6o;~V>kߖ_㨛a4c?aKf,Kfc84p?Ɩkjߦ%Wmk҇ѩ
    Qm+OU;,#WiV0Ii_,'̯->:ؼmz>kϟ:yq`)g˴yVmFW_0_4->?̏6Ou+0-^6a>ClZ>^lw
    ֏~A^Jg)o;ƳƧ=S@
    Kvq?Jt	k׮Ѓ/&T4rVwVguMHt`Εrй#Mp@<CsLU.6x/v#7޴MQx°	ƥhՉ0a~A=h"-4Lu0OVۢSzcŋ/r_=]/]{4#iH:zGǎoS	#U[Ҵ_iVZuL_&hEa6/mzIg[mMXѦQAw(]͏aʋJ4ڢ8Aێ0g_0z{Pxz)it<ndo٦-Zh0COh2- tnS?mix,ڣWJGngn~f+
    9 ׁ:PET2UygxO#V?4vmO:;</nw}|l7:ӭAkOk+Li)/
    Sտ#`<
    Sx0>a~KTGڤk&GVXPn[nC|V[ĒWz-asw[aWQo
    \mvjɴC[Â-0>a~6}{2-;LXrci|ԭ4v0_iՎ%S-Jʰ݌cl oҵqHg
    ʤom[ 8Av\gG|TnP~
    ӧ2i
    {i m{;:"#H^ZI~m{r?*2#*7ǣUl><ű%8˴ߦ9h4fX4ʐg?C!p8C!p8l8nϽ2v܏ҳŝ	" :V7mۏ#Ciq:BkG 
    <(Ӗ0Z_,l>iOnݶL
    miOWirm_{n3Wil;mg54v<>+O˭Զy*MmcV>W=&ZƎgrb56`\	ata|OyCkhܠOmg0n
    l?}&=aiڂnQð ԏa~6armi4n[r4A^ŢiFig{n?VeMC7*]&:1Dy9/?ea<56OeMol h\V:ߎOi4<ȋnGk%HrJG6ȏJNÃ覱yƢiX˵ibѸJ{,:۶/V蔗+#Wio{n[2m*[y*-mzUXtaӦ峆ټ5ڋ6ȟVyfy6-V^ўPF *Ew,t5v2#c{<2U MX\iL
    ҷ#(<ڋCmHI6BZG{i
    @cXa!HppJ0qxQ>aq0LƵyvDj+͛aԷ=0$鯲l;LgwX\Kw0и/Vav,0Aa2:&mq5^ByS,dS&>\Kf x8)׸!"WLg5
    A;,nqL	y43	o#q;*3{<2ɣ8uɥVOڊSG=G	uO{DGGU_rqx	ո	VЕC!p8C! s:X e+EC!p8C!p"_;~ȏĻ;C!p8CXA
    Џpz8C!p8qp8C!p8
    n~!p8C!p8k�~xC!p8C!8Vpc%'C!p8C!p\#u;C!p8+9p8C!p87@?%!p8C!p8�X	C!p8C!pq.C!p8C!p JN8=C!p8CF
    Џww8C!p8c7@?Vrp8C!p85n~\gKC!p8C!p+NC!p8C!8p:]C!p8CXA cEC!p8C!p8[SSSĻ;C!p8CXA Xp8C!p8䂂6.C!p8C!8VHtwX
    C!p8C!p[܏۬w	w8C!p8c	wNC!p8C!8nHNHH8np8C!p8cX	C!p8C!pq.C!p8C!p JN8=C!p8CF
    Џww8C!p8c7@?Vrp8C!p85n~\gKC!^<Os!p8C!^H;)?Jg\w4}a<Z#:7G[~az2v$xI: l*vy=;C!o!mؽK %ztY>O7I
    IoG|LLdX[#J&؉LGG@]5ѼZnQ^)g0bj~^m+ⶩ{7G,i6		|;p8Gvma}h`UTJbb477IJZgɖx:@mt!~[,󤪢Bjj_Oj:ӒN9<-~Xx_kQv;VKEeE}KTΒI	[;^շV+*[V1ɕ87Qu\F**ИV3d͕$CSSTKC3&VYْ)	r8C!/mtYolٹt|k/1E/Yobm:CGt͗iWLRY5i7\'Y)\W:;ߦ-rY[vD%-dddJAA&cli,>q&L&K^+_/^'iС.~ގpJټyT{|oFYijwtBD|ۈ5Nrٴe6H4NssqI9\#y|YO5J}Cu-es^/O|N;Mu.޶^OɺFLRz߯dԐl6u;`&Q]._L)8M+6H[<ñ|ɨIgD}k{ȟ&LaϟKJJB3q,kb9Cࣄ@:
    \i`ݕsd},Y:w:fič&ng3fD!`$rr3;MxHL^cϚ"\|\zrҠ^(M+Ho
    �_2\JTEb<B%?]#ihSAY\!=X]~Q@&/%ٔlUӧ7_S]s[.}?RcڎǑi1Vň-XI]OX5sIw[GY;mމTD9UҢ<:(^_)ˣM�xTx!o}ۦzyq;Xo<YM25l|Nwm(Ôc4^}[ng-{%;Ƀ=-MɘrWH9<C!p8'}߾ɍG4qD>/tP?¼PsS4aieF3mC9-<p_BRz☡Lt5QR*:O0:W
    K;_eydŦ=QZMulHz~XXSrms#OVy|h#TƧ'[aKJgV-uPCx VzFŅ秧0iAG;q߹Qټ<JF(33zw!8MeVͬrt?MKV`(w'ҘQֹ2Ӹ󡜖藧 vxJQ|}o;gHKs|+_'=T01q;;|
    օOf2I:$o1ʟ2mj/k'ߤ1RlVqc7,Ir#.ӒYt.kNļI;eG݌g6䟕t(@j|ɷu,%_׿"r}Dijdhs8CC@t+YVplQ(
    {0H�];]Gv<x>04>WA.;.|NtF:!ts5*Sӱ-Q[nt#""m	®HQ"ٺy;yWN'wo7Zi,^<2~pǂЛ =;426i.v7|ى(/Ɵ[T<Ԉѵ3n<Db#	J)s!1RU-{)Cs{H:N>$>$s|N\q.~~[qoÓ%^t/-M;d?<(^*Sr@	'bڢ[icaWnI:bczHە-9I‘)c	Q-Ƴdv
    ݭ Yzzߕ1zKUQS#cl|9޾<cCJǡ`4[u?4viZͣ_AZbN*gЏy3;P#Znomǡj?͍ $&~jC^l@PG?&J҅'IVIN92ng;C!DuN2=T5Ti8dGM*CUknWR*^.x.1֣Hzt^v4YjnjC55RUU%eeR^U-M0ltJ׮]%-ŗ)Sښ*پm?PnV0tvC1bfp/F BIݡjyk,g.[6m{{@Q̩A\zT.pU:H+%T9]LZp;L_ivLJ˥9@69][n%'3_;D>p{(MuDg1]͒/N܍�|/;ٍdo~9q;Jn]%;錛$Dxrw=go1&#$tsW^~ͣEJYo>ɘhE:iUWIp
    ]r%L[30$:)ۿGҊz\srIN4V2<$)]k5#;۾ȆzjD9(E9Aƴ'₯.terR嚃Ue*aJZΈƺٶu6 :gʠKf'_qScTWre8 QQW('w*deHaaWF$q!1W'
    #;vjz_]zu
    u
    ~y}z<L`EٽK(/S&&:$& cvf!ilg”l`;AW=A[rCǍ&J&R:gK|)wveYڵXnNdtл{M|FKLT,edInvfF8'̀<&ݻHʠ?ѕ$h{z)yX6e4Qن t<PZzOʫe0tG&TS]6Ԕ&M�:T>V=3a2\aS'JAMEݺ/(ҭgo}jҲ/O%yh􁋔=d$t°ebWA';]4IftdCԠMS\"x."x+.IrP
    0B{KzC!p|X=@g!hcꀉvpy<eM>iL:C.b\Ztܸ-]޻nwKM2Vq%@Λz~r%E*v']Pyyd.P%FbԖm1<kkm�v;$ҳ[aUQ޵|GIFNwJbjJt+/=!R%_\Ȉ䔱eE˴gJnf:)*~ڹLh7_xB_Rל(Tyqe9?jy<,wRثH? θF=u}l؃۔#|30J5ʚŗ^Yw9Sec.s/f%/7g~F^3Ofjx](]x|Y2m??$}z˾eꕟO]u[d1rzdp\51̏Tv㿕VzOo5߅diVG.kM9f9&tn^iJ_@^<j<8vErs _PgʢWoҥO_@iٗʅFWYqCCe~ErwȎzyw"Yi_4ǝ";O.</ǀۯ0<72G?irޤīۋ%slܶ[֭ry
    nF\nsg3ΒoΗooÙS.B9Rb5>Tz,O.)@~rҫK3撷eo\>{$Z
    GVo˯~,\\bpKO-xj:
    ]/Ef�ۀ՗䩧_Go)0QeWɴ%3pC;J5e?,[+鍲"Kn7ePtyy3ƢnJk?ѢϽMvȋ=#|AyLk.!&J45ʼnl(~I^7O.'6|8;fL2].|)J]oC6﬐UvDЩ rʩ2q2wWiO⭟V`ԣ^oysyoȟ屮#B\}Gj򟡐zu`VyeY/ϽĐI>@1].2>E(F,ݽU4eyeWI=DN{;DeԀ,_3/-|LtEpAo9RYV,o?Y3oT9p8cfՇ8$odoٺ&gB㣣7T{3+,~2{uZgsboetÎHF,f罓]u=_~~ףW/*8raMaο=*-2܄
    mypW
    Gn	'	!sh`c'y"iMqOy56_403KW秏i
    FYsC7?G㴕˿#@A͗I+O(Z< ~J)Wy?V~2Jo_ߦH}=<X}B?էy싷ze$oа~Q]=~(?oG{M
    {k|^E#O{aG";=+7x)7:h]1xm/2#PSQ4ٷ=iV{mQ>|޶}QxǛ}irS!h#.j㺥/F㘓3>m-45e{o?U_ϼ{L<mOn
    _\J7w(еO۾n7sk6/{[W7~'oOY^h[zkZY0^;[mQrɸg]{)RN#z[<Ĵu۴ӯPGұEwYg٭kQFnHh]ߵDiZrx~Ui|g'fze;G{a%eEیgxv,iC!p8JbHDWY.V-/3g\-W8Ww=[+dD=ysһ?{A/UWgӳߒ',]Sŏ] CIɈ|�n7g
    Ukd@vo(>͖H~n5˱+	؊]UQ"f?#xedˆ-['^xYA5~4FMQRԵl޾y{[KSO/oa%J'a4Q VCsWDfmZ"$7}7riM0[:jd'5eXz;U VtZ"=~&o}2|XldL@'2f8Ydp-P+Z*=8ӟxg4cUU6wvL=IY? L8LYr !pBg
    Y	M}WIGKn܈7hBU*#-S?%#6ÿOYΝtٲZo9(#Ldͨs/iHPVdw䯷%?tYM7>/Ϛ S
     \g#H~'K-'?nf?TYb0?pt\/fY^_tj*~XaԷ7> e%d*eSv"y'=O?/'#(®x2ُ?99olYhXE.v/\Jߦ8csM-U;d+_M]&eYI2qO_$)έ}*2gŶ+?M
    *%p S|I29`+9Ra0v[g_rM>2Y:S_)F-kǿS1=R'(?1{vfy|SE[&cFrooIyeFFZJ4ϣ�$`t񙟆?X"W򛿿 CF-~[|;ʈj\a#qځr-_O],ЕxJ'&sEy;drU+g-[wA<jvNr1BnүRy˶ˉljWQ^vy?Ԩ]K8"[gٿkMܮ2z`YtIPxDb??<<O/]7Xf=zZF<Nw._|sRԫ|c%;K!zjz$ki2}#?G_؄
    2v
    8 ؝[9
    z.o~JjJU'w8CÈ@i#_Aו|~g?FoFlSC赧QIHOhk;7{~oʃ5ԭ:˯o6qN8y/-R%Z~guy[vky{ۆfpǑ+*ራ4ٿAysEWzoɼϚس߫וoR67z
    yۏ j
    zd}[<%oWY2_O=r
    ܽISkynXG]mh|hfdU*7{7\62~	O}koyC^Y>oWaWПr8cЬ'>g3a"7yO'Y]h%yO=ݻ˽⍸ޚjGⶶZ}{}!WM?}?˻xjyrg*m=wV,>v\OJYZ밳?Ao5ަ~&჌?ƒu˼G}[iW}($"e
    <ԏ_ի`^3Lر}[RW޲/24u7]O⩤{g;:AN].z%ʟ933ަ}*vɎ#	g}o7i4o4%-Gv)TJwzn+#o͖{MmK"rǞ<mT`ݾ>9Q\ze{z7Lk)5;wy'ڸVЗV'a}kTފ#]{#gyw=8+s|N?1_xok~4V{ax34wqo2֫,6{ۻL>^y{ǼlΪXɮOiC?`Pc?xfyYA/g7g_&owx]4`EFzܨjx_ü=^!Łۼ~&IcOy&x
    ÏSs#Vg|YvoTz SǞdLθ̛hWZZܱ۳wFҊs8C!A诠z{mY")Ɗ2^w4yNLNɗ
    ;`#6p\{t鑅˥W7m]RKrjp."HGMɲs^zBXgYNpɫ&bS>+M
    ֟Wc[qVg9-O~&%7\/wae%K~8+<Ua=Lv/LLՒD|~5.U%Rp4͸�m9ɸH2ىª?.,;^|",ϫ;Vvq%ɏ_}j^!eH]aUnX%SP)~g"{JTNZZ>}~�J\_
    K`Jߢ<\̶_Rz)qaW>ݲqn*)Vƪ|E>9/-ߺAj77݅p:_}֯ J&i>4|TO|vwߐ$'W6l/&Oc1YjjoNN:
    5%RyR"d.PIϴl:ݒϻP>u$+Qow>r2\jKr{h?jٵcWTHXwP:84$S#\K3	Ps?~!\4٬\ݹw\
    ^]D/a"/%lɄC;P=.|˒T\vi2kfjŕkO(n<:8އigaokx_rz9N=x6t\hٕ
    >̜\٫X-馵~K?Yb-N_}aTO~ٙΒAcLXZ&q2v2[!3;TD~}r^tI|}P6l
    `ap'SX+kWlq|S.=Q))\?-7/'
    ȑU-#XXW.%xOϕ7K(3/ryn~
    )GӀKwnY=*X#i>d6u Rr_crєF&HrSs{kCwTX^TX-Li%T|d5v\z_rZVN"k?"k6};Bjd_.Ozc,L"U_P ]rsdQ_%hSnf)erh|?ggݣ!p8V2wx%6ϑ(3d@tcnNJt9vb,?z\%R{}e}MY~{}QkE1�ltJ8@4b4͌7a@$3;)Y3Ə$Bnnn=;ѿSTHny2W1df
    [!KgW,Kӥ7Oi<x9ˊoʻ;IMNϟtlPA۩3rqa<po-:dOlݲd:/?ykm)>iYk��@�IDATCu/v2lߤr_$28h܎\UUa򁦦
    3{/4a谓pډ-3Fvv9-Y&IrDaVn
    18 uL@T^9=EIQD+}`{O 	$^"
    H,6,QPQЧbGDED @BH zߙݽ	_ݙ9s曙eΜ3g(-_6<}mC! (
    EF}kX'=ĔNpGbƊ\I!Ae'мڎpNlN'q{vd@&ADks-<P)ݣy0|i%b._YZcOPFF,q'e~]Hs2@cUyxQrz77|yR06ƌwI|mxY[2(Fx /-
    =hWTþ
    3D<4솽uA\}0<mkGg^Xj|_&B	'j1V	01MKu)I
    e^1dqev0yBãﮞX(+nܼ\l_[w.THOnJ8l6H7zPˉ#{XYdž/Gu
    sYBd#Ȋ
    Ur"AXX4p~72<S@/!'Nc͠ӻkqYzN|#cpж=;E<:!='(<ѝ3 <AYϪ?ŕWF#njCS"hV>g+!
    H$I¹j4F?sV@?\$Vu#UQ!ŰLѣ} j	"�X]S#TZ(<xy١=.UDf~F5r`	.(@vJD{)O皔KEu1-5z=&9ɸ
    l݁y.VÉ
    j_ǰO֋X7q0)]$,.=/}9n29I,XlWAk0rbCsxFS3itCΕpTinL^a
    Nrs6H}	uLMdV?Fվ`LL.vk*;9YBf-q!hмsź;4GВE)EHþw0uK	Rͤ}9Kl$`T]uuz~ظ;twJsK14;ZUD%yഒc(1%YNaA;۴𑆡$Ceu'&$A,ϵx:7
    u6,CK4p1쪄)>
    h
    sGjLZb,'/mUYQBCtu2_Ww!gg;Ds3<s]>OBq&py񭕅;4k	; %<Qbi{+bna>fkm.y|ߙPq08[瓗)3$TcƅrbDžXrl V:=7VvƤ˱mֳ=~h4F?sk< fMW,-L\O9,ny'xZg*:/Wy붭sN4>cߌ#$Ic_uvU)ܹYse$,HQU&$5Z%WW7-i\ڽ'%uQK9S-C8F3nw4
    w?4sy!~s^x	ώgvCVjx]%V'd
    1hڰc'y\[7_4T_c*f[Fm†5h-O^gDXII{Z9	<ޒ:+xPK
    <񬢓.!`/ !:>,GUvYXE!;;li^	"dYmg dB7.86ݟcEuwZg|.DF;fRꮍ¹/7
    C)>n4w?|0O%<cXTŭ9Ǩ#7~<yfgAi$n|57�
    0kvFO7s#=_pS)[w#nu8R\Q>#Ky)p̅ d3\%rr[Gi5f2,huuW%ŋED7q;"Xa|+%'*^e$TI#INUb*_,˝ *1*x|̏!cԕ\a+7tq!$@.O
    L+Iދg2͚`ym~uh`:[#|
    镆kP(i'jÁ\5>Q6 \+|rDn$vٵñeM89|o}*Is+D֋b	hߙhe`:J3TTrCv}h4F+gKcP93-[%Y  %w#53x	Ɋ`/Қupڴ{0K:6BLWβAU5ϜXZɽ}"֥RPE/ܝ<`Ȼ`5i'6Xtq0QZ*G	5nJ,6K#֮ݏ´G!)$ -v΋5mZ'(pK0xnk#TE9VAa'\DsG!ӈ
    n@f;T"%&:a :GhR+YiHhWumuNV(,Wr$3PU{=X“51oܦf}!67O-+"n\`iAns?pClQe]!S8VoU-e>2VxS6kߑo7#0|yM0"7)ZNV&Ey|H0Jdž
    [с/M_4.,(T4,sna@ŋ^CTGwZ\T?%D<V<+BCX[7ٹܲCX9RS{Qp0SWmTRهq_Za{pA0y-.,T%@k,9A6}<eOFj;J?}d 8"ǏmwmS8E.e'v*9`.DZI!Dȿ#Ҩ~#k2;Y!T[JWRVyq!\оG~iLHNN$W:85Twۖ\%[j\`E wn7E_.F@#h4YTj]kT9ؿw#سg83~+Dt\<]AgM9G"y⧟WLA940~d'cE7`_'JGP$pTɵ	Lx=Xw $?0	-۩ԼJxv>LÃ*b~;xu4RO#8|`7>Cp)Pn
    #b$^x[$TBKDX9ǓU6
    vVU2n`p`Id2SiM,*Y3)jʲ\MlLs8ڴH&g8rځ
    gNӷf>mKo':^~wR&#ӞOo[w=ǬYM|l	31xd'o/^~t4"
    K"m4
    کλ$H?&
    Ugh:[y뺋%jbKVABPZgTinn=Uws"(^һqEa⨱xϱ߇[6bc…*N	BÀ	[/'3J@woOLJrxU?}g٦YwR1՛=ec|:x{/aMfԧK&t:VID{TUoêGx ysE0gb{GS~lz6hkUHtaz
    6=[ҙtWF|xNgqXmj~fc;zomPjVH>25KsՑގVeF-E,nÒeM(ʷSmX_r-!}]Xc]c({Coǟh<-#T5pUP9/f~/d:h4F@#🁀)5K(eHAzDov'Wg/eG^<?w,1˻g.6>^_S7J7
    7e!,1osmfڵb#7]=y$7;q/7dryc:	ؼ~%>'FrCa5)6w]W
    4PIO)Ou?YM0\4@bd]	0�"W!$T:[6xq,>_V"4:GTڜYeZ)hv-Vڜ}syθ7Ga)[o!
    Jpo,xXˆ){_
    Q+U@	韼2Bt2RaϘ"P[oCHzsy:<]hת1h*ţ2[X�yM-#>ʙK+ ~<
    !ԉX.RjbN44ZT3g.Mѥmc5~Xظb*͢~˗u˵[L:*5>.bl]/ODeRU7
    {g)+%q;6<pm{ J(K>ݸM̜x+&\A<:v֭׋9:8;Vc_$p}fg#=gLKїrrPQsʽ{c1lzm#?yNrބFf=!30>z.MvM6Pa~I’N4%xρQ/¬cS?M͝y{w?]vƆcÏFa8s# ѓ'w=yZ6;
    57“/.:sZ5,޺|9*+&_.2dS3=KwZSvn
    s^~)<夜;*Uf9vp6t7[1	t/KU6nuħK'ZlIO}[{!4v["S̙OڣAhxyzpmM;(3jQ6"[gZ)Q^}w$+x;sfF(Q!O7)h4@[êeƫ!7;E<DŽٟ<׷{l%r5Cqiicٚ-[aB1h[ZVAעGKnn/wOwW[@qF޵嚇1SnUԫŒöq7Reb;Ҷ)+)沮&Ȥsb{|6m!k	QfRi,YAcGqħyFmArq.ul8iJ}JUF-|mr{	R^X\tG[xv8YۢOw
    +v)K>?+v~Z]x2^˶6^EEMR7s6`[}.8}`J{ZDN~�O}|/8ݽ~u烯2ҕ۾KlQG<-:>ېF%Eyr70(F+^JŹlo>`,4Vb]Šv
    ]4#/}mҳUa-
    ޢڸlJ_Ԁ7nl|caOb(4>?d*I;mwljh2-0{~Xcn9u61bKl(N~_Z߯佛mYfu=yq{Uر'[&$#=*&m;|U*پ{>
    ;1='mY{45nXoc  sLA7f6+F	0x5/mBf*.WnQGvnie;+-<'e-5cyzWcg-\?K2lύE.rۑL>ոF@#G!p3A<@[tN
    gcj/tMTɛV_+圧80)<6އ(ɗļ^	e9IVq&S
    r\Gs.ӫ4xwo܃n(HW
    őKr
    rvOGXi'F4�t<J3Sν|ʌqP2C</(.̴:4MJ|
    @ZwK~_TC۫nWR)
    $E?I9bC+Rm*(X<l|ץ)N$0
    zittttwcx!8}nFvcya!lR~v?FH5Ydox#B:2~FdɳbXcM%sv]ؚy')-N_ɻBA/C],zWb퉰)޹Y}64	zgnipxh|ydсFT!0oxǝ?e}ƌD/j4EilԵs%x堞62%)>2.됈iz-훚T128>[r_	'S
    \sKk`
    hSuA5Tn|2W6{U/䛒dd1`l<Kzo;tڏ&p߈AvBYΰMR{ZεCb/0v ӳŭ.䑑^
    #v‘{phJoMg8QtHcc*I#|?ſA}ubӿEiO82lɣ[$t*:�O"K)qӳO~{Gǜm=beyl؎zS@`v6ZV13,:h4.t{YĈ`uJ4jz2xKh�[L(Çss2(	q_:kFm8*xغe3MPNph8&6AMVFF9֝
    hLLh)42ӱcvg"[ۡUӐsh,#A:j⿮*[q4=t3vѳsku@`0x&J"Dxh~{n޺1ѬyDŽd!9:",^b"Cl8q䨽rF_`8%IJEäEg1дyKG 5 s3.FBJ̵"V}"-t6ϦWjӟ׃87VLIuMїs3s8gqMoTXƢ~3+/;w20Hξ&Q/osstt4cblREZFywSrQbrdߨyV\NPN)[wlF{j-q ǪzfHK['*߂
    JU)aZ[a3;ɽn`If-Sɇz&_9,Ko)--%>pc\xqb<('Wh_s}"(@щDǰyfMCNJHl7DQ&LGUADOm×i.U!;+~%J=aypnhŒ•02-C/OMeMOީ'RqDȒ=݁A!FTd$|(K-KqayDK
    ҏ?	tV[s⑜ʱg5aznê߮Ң<7O{<k\NT`Ǖh|"C'c-ly"yk꫅4/?r<AB}xcR7r3OCXx1Ӊ# `4B34;/:1eԙ~G7A\lbg-gN[NG{Lب)Z4mt94I71oЗsN#))ɕ,ɹh8^6rc~Av0Ʃo22,P]]ZG"[ċ}tlCnٗsΤ~uaŝ$6_T"A~n6W'q*-
    ˥D9q3׆
     if`K1 NeDpa[Rt,Tbʨ/F@#G"p^]joL0+)cK(;GKscb
    sBY=w]4d/_()rΝ1ḟq+Də9(I#,VDM^x*kA<.={mg8ْZJ`k+B?I\XeݢB5bk\2hkoF{(u�?xq6͊y_2-(G_x:-Z'{$FYZdW,V\]/ֻVs)C9oiGyph~~{>gY~<q
    ;nL|k!ywƛm%˷ˢ"Ip,YՑ)TţkݭwǸ:ƒjQȳ#>4YoqfǼER6|K~G<uS;h4=T9?LMΟXk&Tk&4%!qsrb	b2l\g]
    Kĸ 
    ܍ryQđZmehdb'WP'm
    ?WXuʊL2EXv{)|y7W%p;`+^IrWIeҘTEf&HhUGu#i|rWZ<;gr$gn'#qjƸ4#v	y$T(?_pY&HBSUD[&=~+4QqgWk}EplY|\ly΅Ym(|'jbq[{~,i%
    w,F뵺q5^]䩋oHOƑ%'s<Kz;`O#v[IcUYLJ6*[`m+#
    )N*o:1aZiƘ/vbf
    5۲f
    K#h4$.(Ke?S1kfMBi		'usR;!VOk'p~L$5]&?h4_1-!H^3uP[Y®%քkm݅QyUEYzZDz]iYmkuoŻafx3tU;[;! HϺ;wi[ߟEߪ*}V>nѶZ#X%VyO;~i|n{5U})1~8b'O+=jsd+8Cu:qExR=i
    a1N	^:9HYd¡MOuŅPV_TU.Fu:-~Pg+N;۱nR|,Lb|oR3.Gby=pV4'+YO3*&.V^[
    J꧃F@#h4)_YUkq4j>rGb~s1eX#糄 .8^(4󵋕11زϽTIjB~22{mjz_;>_Z;W޺+fpq@=x1<=x|&$s?84^FM[%E7*a*Obgd5EUhfΉIig;;ojzd."0r/n|^sPzU|ټ3)h4
    ܃oéfD#Bv!77y(s+QRQxBHp0|}	 Ӌ=8U#h4F-ﵹFe|A-ۚ!F@#h4s)F@#ooBL|BuF@#h4F-4Fڂ^;ߑ͓F@#h4F-_#h4F@#p^jetޤ:R#h4F@#h4-]jF@#h4F@#~`F@#h4F@#߅h4F@#h4@@Nh4F@#h4-]jF@#h4F@#~`F@#h4F@#߅h4F@#h4@@Nh4F@#h4-]jF@#h4F@#~`F@#h4F@#߅h4F@#h4@Ϥl'frrr`LjqVUUE~i{YBX>Ol*Ι[۽,n6bO*pvv#Oy¹v=jc+p!Vǻ&yu}&mc,YJY6=EncѳӨ:ǮVݿjZWF7f.fTǾgό+i7qX[EרX9GlF@#h4N49j%Q݃Qsmf
    #b2ItV&*o?vj$j`U7}+ߟ}W7E0GmKgVgkbtVk=WAVYdisrxmrW~[{BwJ_'u<5h4F@#߂ytk'2OB~Q	\=ow;1T2u~NcLn%zw.zJQVa"/,(
    >ޞR kTUœcR&V";'hZy_~[*W~[iYjYNaA>\mԓ	Dh8;Vz+EX)/)GDJ=;:ˬc$VYDr'7+Ypv@Dd$<\6C+/+Ax;ׇd*EQvUy	QnsEDtCT0byQcG5�(«.<I.[ځ"g?jU%E()>ʒU(,,<lWI'e#7LQqGIWIgh^^|>s
    ypFdd\T/#ME1J5,|VYKYʁ~APRәٌw B8.(*xy[; 7*@F`(7Pdu(-ɴSx **؎+z&lQd@n~!,#%߲/8+®;p*۵G\tp?G4F@#h4ݚldaїo+8w:fSIk.n5״&j	)eLՃȤ	~u(3W<d$Fr\	
    sxho:Җgl*OO[LGhgSjU#:몛CJ7pL'CnhG<hDB+'uѰ/|TTOVoֽ(;?xt6".kkEWD-+:|4d5VԹqc1~G11E_Lڱ~!pssEdBlԝ(yլ(<y'ײVspؑ
    �gW_I^K$IJo4+ԸA*(paVhdк+Lm;]{"V)VqCmyd`k@ƢwD{X.ӏ”s&>RK$bpڙ]sx{tlUDT
    #ԩ8/?|)>t!Q]wGpz`aZՎCVKXEU6^1Ig
    \;w!ߖc?y]݄!ث
    ^vR1�břhxSŅ,svǘ‹oe{G	EN?w¢5PUQ7߁wAD]ZYVo?~<}ph:}w
    Q\'O7GfMm
    5,ҏF@#h4)[KP_{6e9~^8[MOcEطR@wSr)|ƆJc_YݭrD+*ay/p75FZIA*++)0
    'SXqBhX~".{l\ۿ
    M{
    =loRj.K*KM!H@O“Q^Iq><<<]op6NĆ*NEBqQ!*v`ܘ+m/`q9J%cD9u4*ovms?g0/T`)D_Q^ƺU¹2,g	L{ii9
    
    AaX*
    F
    h x	M&BYI1J<G,ɌL>OK??ǔ((?^Z!' Fw
    h
    7/9OUeIO;"Ԏ!ǔfkR}qo>ES6
    o+K?Z2bT'-D8Rxxy۱ 6.F!l}\Qi㝙?ǀ-iw](�Jei1xTRtqe{pm\nB-d:q9&K|^|>/xX߼;#^
    aAֿ*j"UWwoR"-JSkoj?VT\sWs޾]~-&5s	*Jwz,ذe7)c/n	쳇lo#;z{{`ZAʖ[o7<	1"ܫo^'ES㤪>|n,?[a2F<p[`]Y1U-qt}-£~'V?>Cq(qiwF@#h4~(<l\5S+{\bm:"?/n_}e#Q##;ϿmEر~})c8kMM&ey{QA8o3ٮn:GIn|Px(DSJ}ih|S<a\߷E)𧻓G^A&1ڟ-Ĺ
    q-0vj#_a_s)uKb᲍k[
    !6F}(?}
    ?g2ؿy=~ݰ3_%gx\ѭF
    p%9÷P	î5>Ht XUb%xwTrKeZ›MnF*}( =M;b#1A!ɇ.2[w[oD\,0ذoo/]rgpGza~Z6,:+`Јv˵VRlXY*oھY|56mX#:[+o"l2ԏ䷞�<N-�BLKf%4@,d`o>@Ǧ
    &]^ /
    hXG㗭G0:RP{R¼ϾBF~)lktiYKxYލ0>lG,w?DYX+4eŞ-kxc 0n`v+bO%-%z\V.O(WFT{h 
    6
    ACܴ$4s6zrunȭ3ڟ1cF![?nu?u6(
    }F
    ,ەp[qcoQQJlXYf{COlYsE!6^[b=c{iYcNJ0w.�,3d90V܀Vݣ#!:IvT[qf*
    Mm[v.CnBl0 CFq5p6|4)[p*F=y߶ߑh0Nraǒc[yy5҂ew">#O^´VbuWp7O?=}F㖋7N#MK4vo>--0|
    H/F@#h4+yj[K4ؽ'OAy%rZWSxxqӏ/s=9(}oLڶlҴݘ"d;7`=y4xmi{9nQؕLWq/'ѱ]s &J	w\ҳOSqy-:2ߴk6(9'_ETp߽wai1~kq}!	Y(/-Bj3,uC_
    iҼSp=]M<1`8r*W*˰|%"H0'Sb8|}I!yv@?AMgT
    Z,p.؀WƄ;nn7~W.nowƎ]_=IťY{##&L mbqr*k-fڍVcx[Tǭg ֖ggSyJ)?\zOpk0*.H(/85+~Bv͸-UW7}_~fi,))@f/GsGDԃoA6s;n8z?cйc8jpcФ`L}l
    fp/s"q|?&~/<|=l;PKleعinzb#"WU('^> +qt2L7^Mq?O|JZ^٣<D5@bD%r3u욡hܦؑ1dHWlݶW巴Tzuh!ҾAcaӣm!
    @f><>mDЙK8SlCy~f<~NyIqc#W1Io	<<k܏_ʉ_͹?"x
    
    [+8^7_i$%#pcӊXT=Ά�*rR\
    D&UFM&(7Ƴ=`tOAAPbꝙT]o"ŏŒ4Gk	@%hڼ
    Z7O0J/F@#h4ԩAշś%.z0d9yoM!6,-trDI3:t'n~<tM[3E4Q6B׶ХI$V/Y{FAXp>5me&~7lu{%'=>g.��@�IDATy5vR(A+7l#{a}(I{30=M99q\>x(
    .鄉7Pto\ہh$_B:3C\TS<Т2MOBxNtDE<_.X{wV<7h{\
    30?1~h/>yhIa3-ܨV~ƔuMF3CZeM}ѧk7|׾	sv]
    pWSRWX0.de^cc#C!]r>"{C2UUbwj,t{ǎBDjCb]zFs1EleРfo˕FY%(asC`t<^zqB=p5
    3?X	#.8)!Sjf
    ٕp4v?,čm~ŕ*>3>Gѳu/u7ތtZWH8ؠ74oH3qO4n{mG	$nx68~kj07kuxHb£ٕUѯU/'gM+*V䓾+Ibn%6n
    2r+co.9{yInpI<t^$P�m[>"2ȶGpp0f-j+>%jv+x0kR|twCT|#tm51
    Ɯ/믔"0.->إyxc<	*!\{�tBb풯ڬYȘ
    qͺcxדE938Vy+c+=i?mL;ک:U2q+@'w+rˏUE?hRa6b8_*|WA\yj}	,3	Zݏ�.܄q酌Tͅ~h4F@#_@N]*nAgsq©ԣ:|^ĔQ}}bg!#@y~zd95sG{Fشu7`/7(d"0
    k,uCjB7Å?bbDpf,qk͗Cb0Qx&3m\1F|3eIyȡs9&O{4/U?1‚2(!<th
    F!GbԈ9ᦻ<
    8P^\nhJ{+R�'M(0H/٫;zgh'Q1f^cvn_I[Tмcݯ4ǞSa#}n_=j_~ܹvn\W~qi&HM@^Yg0w_%W}wSb{ ķH۶%IXIJ+ĴY1W.CϫD�[D^%Tw_m-"HӁ)'rIl
    b:6k~o~FMHi@ҺP/?ꜫevUU\72*[u`[\I64ۗS]݆
    $Tebُ"?}RÏ=0/7G1ߌ.+ʴ~Qh+w/|	—+=_	 D
    ,#Mm%LCyaER:~%Ν^ڇ9<7U¹};Ke,PI]dG�Sb86$fe'er>JяmQXw$[lZ/A/y�-@Wp;Gn`X\OĕC+Bz:g+nƽpiFvO1>;[h>$BBIWnJ~_(=h0ZVVL]>(¸)Ќ{ߓlw_.2:vtsv/ɢ
    ,[?Zw^gbyhiXQϒR~JC-N`PWF@#h4$H
    
    %		B _6->44
    C,(yPDj,W`N8Fp;ЮI*@-q2V~F2\}y\aެrJl?JP$}w,+.;qc0$鲢4t>
    1wRF>\*!eq(
    3e j]o$aAL22c59mԥ v(\ј8ؙIߐ@N#
    ,Sa)hWc/Ҏu1udnu1kԶOya<Hzd4xrmie꽷'S')>n6f<p"*K(B-GSoSTQKb<Or=SMeY)tNLy
    C,O+Q
    D;.mSY`Sh ++,w|\ZqjԏE=P*AMjfgg<ȏG"HG̜Am+?`r*Mڍ~%sR2$ݝf+bT֥\Iq@>i]Z)R_iO*@r\i^ģ+`(PmJ4߳e9p%Oaɍnkt'*k
    ХMKwc@Vʙi+^I~S?IGa.:\94O[ivbXa<@Ss"rCMһGZw*pEtq0U<,ТaM(s9X!$i\Y4%|H$qE	XR,T֬�Sx.*-q|>&*zlUTO`#
    62hh` ;΅Yi4F@#"Pc*ja`\231ϱgAO>[7+
    &C.xXK,j܈g;;Qkyo2$X	PwcspgpŕDo:yӸ})'YHK9-g("ƥ%8j-]=6n	ϫڷHP|QxTڴg�}x	a)9/=DBbSVyC0Ji
    +Ґv̙CB=^=Y" \ڵ\ܐ N>z	p]+0LSuGq}(<CsrC
    7S;~ًpѿO7S82??d?L޾go;yk/Ʋվ{mJG:ϧAko&qOv]OKSRC{!'34i(jEI>N{yW<غB^Q۴"̚O
    .۸+~WT 3ݺ!:D| `;/>xAg9I.jӇEqjzExo|2
    W/]fۦc~r~J˝#E8zZыopфZFruFsqBX=A#zC%CBKۗsSh:vhh#'+<̢>_X{\\7mՏɛ55LU~ͬп@XH$$㛴S7`ɪM8{ᙇGaEF.Z}غ$!39\7
    b^|3<DL?#i8s:˗|$yi>bҢ\N.UXWTlؼIǎpL~MMph%W?jtB1N%rN9Flݹ;m
    (o߲UuSUh唆#wAٻCGq"c00	oNoXq|V̼>\ٷ;B}㶂?W2eiL0z~nS_+f-tk4F@#/"`)Kk*<ѡK'4%SSő;*xRC~A%&SplۮX~Ẇ_&G⺑sp8 .5'2=mԶ;6�3fLǺ-Uqs^˨tsC[:
    0ͧAKbQ?Dƒ~ḌWsp_D&}oǣ%pl:4?W^E-w�
    jG-nDM_%'wLkvyih55ږި3ђD.;'T+$jqyo/̘8F䋞vmMͬA(S?@Mo'LȪġ'řn+r&9qSf u{gܼ3WlzOC6<ܧōh4V
    \01_Żgb
    MW\G_ã|Ж]'D6n CLv
    qcEe֬W9,H8(B>SkDε>	[xGdS[/[ZhZw:	?F
    '@tC
    stqIyA4g.6q4%&?�xtx\
    B/ln>S -y`T"-BЂBࠛQͷB.lx'v(9}xcwƲH\6&t]sWv`/'mk]t=К^z'rB}Tc%_`ךQB8,{Asxr;Al.(	502Y.�A0/8s_-y`Sh0Fy/)ݖ,|2cO7=(vlSIQ;}viXSD[$GtFxkJ+9axo(}d9ʣU{PgN4j	`h8u:"8=5+e_GE.Bfy�~^;m鋯M{XN8ʑ]>"?e7:&~T}Ւدb!>6\wpm̱v.ssw?3GR&c^(<j23y7=%BpˈsO<>G%!ֈ~5Cq5xtQDE#h4FZ֭׆A)ME;._�DD)(4j8s
    U|8zrodť4W&ނ&CGo;-Pn#�?
    3<8/P<$T,:4}3=)Hx{BE
    DTd	Gf/7]Bnxu.y&xxs|=y<ٓf-A;[9]Έ\Pyxԅyɏ1n/ XGܼB3G\VROqa\<PH)UB4ۯB2چ'Sh[@=4Ӷ]N2N#'_0	TN\(䲎v>I /|r.M"(,t
    n
    tI,Y҄]L49Zdq &bOa2[O}n]kBEo%<C
    }. ::D
    .sm?lcGJ
    i_~}
     	*Rq&XaI>'.X42ҩU͆+L_QVza?wFzo*E)wWUd{OHz
    W EEĂ`[]ZW\((J ${O3#Av3w9swg9#ĢiXaڊ_\:x­4ܨs@kEym7ӑv�G>Lkb#U@﬍kxߦb"2`,0MR塸9w߽=/Oݼ}I-ڪ2nrH2rʊ
    z\tĮ|8t9PZZ*_;7dm25w.dKx[i^1^tTǜB"<0b6>9H+bso/Roig^*n9牆de砙^B)	5]ںB~j)!'GKaC+Ko=wdU!P(
    BUйWXX[>[[vu[S[[>˳	\yJ_а ̂,LiLźْ<'	si;\V
    d%Em56۪}hbF`2!F64XXvJZ
    YOWog,Qk>Ze(o9>fZV>،A`1:>"ªΏ+[<s+nO_b܍wm5!cݶ|[1Bq;>;ɂkͣճ.z	VDAk%ձJ#	`I |%r?,]qr.Մ\۽^UvkB@!P(
    Fa{VdH4ͦ.Sw\N!ß-c4P땘'b˪701?}ŖVqUSUι,eeږ2KyYL7br<'jZx!7=1>C`U0fc(\hKpLqvBWODw`q-s{j,idsG)g[X	wv*Qb[e=^}ΙVeܖ,qIYc֔)F"^KvJ#rycʴj�ˡ,i\1oOB:-sCbuYK,Ysw/4ՓjוڍەU<5Y]& ETkճ;%9XsY.^|r\,RoCzh+)(V˲]vm5(-}m&Mx</{$Eje:&{K+R
    B@!P(C7tA[	JWVY-#?^>H>y|[dߢ
    ^Җg_˺Y.kXsZ2G>ӕmoymmo'ј4]FŋZ<zee[>3Ϳ+~JyIW}*G7
    B@!P(O"
    P:H˳|Ǒ$]Dj
    'ɺWw[gɣr!2ʭő,-WL{ml=¦UQ{<֋L򷻠օ>ڞdz;zvZ5Ļx[zT(
    B@!P	nt%Vq]a:K%>J.?l-^mp{ڒ%,e{;lJ~4ϲKylCqVeY	4rBέ,-Ժ\-ˋLRY,g>9*-)9"[mmn>p=bsZ
    Lu'R>re-Nή,#dіAI6_F7
    
    /hGo4}ڜ}zܾCl&d^397p_NZ:ufY7/G'grϭ+˛c2qXe3`H?el_?wՆB@!P(
    B6ìR0RآSc-ĤIS0wg&ʦKY)ǬѳT[>RˡJKW6fnO(A.OމΝ6ŃBȡҼEgCcE!>CtpC>Ƒx}ͨ(B̅$
    .~'꫱oGgqTB
    IxhqWw=MNJDK,l\ƣCXO̿e!G[LqV+2$HW#P,\�<o6螝bYg‚Ugā)TCfNB-g
    =ضgE7Rh>}Luŗӹ:ٳ6z;Lv͹NOnA;oשe_]y!vlـ~>�[�Y'E~)_g2нp,VJ|O]s�;m
    ^\V>Xx
    )NuY\Qc@x2IYl_?ՎB@!P(
    Bώ@tJW(4-FMIO_`Chޑ!?9ʈ~,?ǜ#(-xٖ(h#ҐpO=Ww@~0&cwb Qqúu)dSMe
    +EYya6z;)HjkzMwsSoKFhDWD",3BJ@r!GV"sqa:)Leb,$ogW%%46.x0&đsićyd)7݊'1hѳH)}9sz5k6D#bL҅X*L>z$X1kgK#{P+,"pv#fށ߆ok%xr.]9"᝻gp,KX6bkp]ᎇ¢bδksgU~27X3;{%dm'4-;Tgc5m6|b9:d`q>9_\C@'G{ʇߠ[LTWB@!P(
    B@!`@tVXi,/[>3~Co1כ2m*Lꕆس*k�MOgd'' .5AHCmX߽Do0цo(L3Rs
    S"{(JqivA]q.2J1ϱId-$j&Wbт9CCH.';r;7,6(MD=A^.ƶݓbq7ԡ8_[n9/o5Bq$�S'{omޥ\{0&Y­R}U	ٍicOA~d
    AVJ~!.#\7u|\vY9ŝ:Spâ(5l݋QQwÁ-$hߩphy.:cxxct_`3i_4bpx!10Mب΢LH|dlt4VZ;g&Ͻ0n:طa<ƌo›SAF8!LB>_WNa꘡D1Mw
    NGcK!+pdloYɃ`}3 �C_uǥ|7c7ιxo[k䋸9pż 
    B@!P(
    @+ڴ.9"8"v.u
    MbxXX'7įX3p
    RųXva?/MqףçWX־5뷡Z߁ijr,"rM؉Pze
    tй.A?KVINH!--;wlG>>#֬i.I=F^نI18aj$:ڶm4-(/-CAA!2;c̯P۠?[[_y
    bb2.^(X݌{|'.pkk܏I1m?rUV\Y
    
    ;Uϰ1ctՍٜYfY&V΍RiIx
    .,྽SSXͩGܲL3UulWgx:{A ~mڊ<>""
    YT�i9((ѭz5x߶
    ,?7Nm83	܌
    ATNF-}###/4gJr1g$>0j|#K'kttvʹī1ԥTZ\3PΙ>06Vo(	ŝQ(
    B@!P(m#Ц]ߒKJ;fV`lMj{w!#`l:#RMI7c֌)s|)&^̀+B=@&
    yp *—9O}:"zXI.#kbp1gTz?o	W:KgE"Ok
    7m|qGB:;[G;p_)puaڕUpruÄsq'ّ2=M\'gipѷFdO)iXZ臚a81|u
    Ů~
    xa|[Y',dY>�RtY^>qzcbHD
    w~dc|$ƗH*)+O]/}"|P_ͶcS"g{dh@CSSk?Ǚ}㌽k>]ޡ5YߘO꼱MP8l`h>:aOyeٗǰ>@z9z]"hMžN4d'jT߄ڊZ zF9Rba9yz<اċV-}	C~^JgсɤQ{SWB@!P(
    B@!p5TI:5zkܽ,9yHN;nFaAqr-ƩPYK+1{r\֌=t8:ޓs]^>وKB/pifSX308�)oy߶>f"=IlD
    '}KetimZ>v%+uFRZ8rȒE;t@pD9+|ߒmI!4Bhg{{DCXY҆Yﯪ(3[9_k4"0(�1{OObO?ž8L(r#l:J�cAeE-$Wu>75jn]|'DD/N،>:TbK⣺4/Aa}hlx6vLtoc@d!;h&l]p%(v\L
    d:o[rhKZ
    mitߎ%4%SŌmӡ; O&[Nu-yY}RyYhu{#g^dqI0UFR=xl0.4
    K(X)fXKS(
    B@!P(W ж.1xm_#b70QcƠVGRMc6፤d;vn{˰p/Bc9MP߀Q}#1Edgd羇Z:Nq4ԒKqJ휕L\d2ĊsNa5T(?it]2r艼o`BgmYYdEl۱HCҶs'TWEG*)($A~z0_}1c\t!p-Xrp%E͍MǦTPQk:n7.ƈI7R=P7N%<x0lZ^"_|
    =_-:_g7WxJ2εilhqOXɆ	1R-68
    )ºaPFkVMGGW١驾EFm1)܃+teZ,ѷZepmu}Õra4
    ҂<tab&?<)oH?,(%;˛UJ*gyWD;+t̥e$B%B@!P(
    B@!6uf:LBU[v<r]9q={vF0ӶN!;)Y6+յbt<f2qۖb
    3JN8u9Z*tBH砨XcZT[[YbirZ*R\u1r2/8d
    >s9%)CU-(@Yd46o-q#=3uCUP}p7ڴ:]+3`HaĪkjL,M|Zw銚;p)%!Б-+Dn5ACCu16oXQ¡8Vƶrw}6G:=RIܔx&/�Kρss
    rsrP^];W?prO~Pݛ7kyN(,\H+6Έ<o=uMɱ܇[ѧs
    EZz8|0m؄`/۾1$iŖ?@c輸KMgER~ۗ΀H{l+ڲz_ZAǰ85Iϝ:G^]3h㯇@uƷ8;/>J*n͡ko|lCli(<RV]
    B@!P(
    @HSl"y٘1~$,]BaWg
    0.B&[&/q*lZtKs2	o×WcHmFN3a Xr8զc8
    dQ'V2
    ̛ͫD\=pvg_nxywŮ_A(~Aھ}t?܄b+gjEo*
    	݇܆G
    -cоp;'ݙNf/v'{{!8s�~
    ^7?v⭿Ơ[Ǟ |^�ͥ	O<i\&s%ƶ	?o8'C	&5@;9ˢ}_醙JKnLc᯷c} *Ć//F		Q”h,NFO?W=I-Ɗ{ű_c;_bHFCl9oG:w	-܉%=H?
    ~siO'KSL;x7-HKrSqw4g Z6M/	>C>N<sxl~
    ;.Y>i)y=ɓƂFj|,Zw}Ceq\H]^IJo8
    Ğ}7މlD/[suQ(
    B@!P(m"`CJmW$iim|:W\O[<}Й,>̔(I(roGs2oT5t
    #)zS�%(n$qG86n]YF%'!3w9#(iL,+;ˇ)MByҝ"6_*z"G#j^
    $¸oo@0)@vFmG_ڲ\MqAT!))١KD	Y+i'N!	TW³e>qVڨ$OnFRӳh˵NmO۰+kPRT֣Wxˁɉ/n(ƀEZN^K+Iv
    707'v4Ey-
    ҽi7(/ypqqM39^#/!gOMҥd?(}z"{V$Fy(\%TlD[¤噶%rhxhȮV#/MgsSЮ޽T$_v~	лWP$C&
    (\.*)+x�e$ܽ)X8,+¥K(n@xt"B_~
    B@!P(
    @⨫rm2e6+XWRtWsڣk╵QX3i,j:,Jh(+-LY20_Iۆ+kevr%ehˊ5v[s~[<95/Si۞-4WΏyԯB@!P(
    B@!D*
    :t+) k,\S[ʒu=AH?lfe0s}V-j>3o)5Ad]7|[s4}UTQӚ-ItfT\'ժO{,7L'Ί|!>.T(ʙβ=1yK]~fzEm99%ɛeϜgMpuG<<yw|c9%,3cO\	1hKЪB@!P(
    B@!pSEՔ$JIɓj4şO.LHz8ʼj\̺?BKZ�iaUTlϲ\ɶ+C1,c-sMkc"8`PRlӂLqV[V䳮n6ał*(
    B@!P(~SAoKߣ$ aϔg-I,,ֲ1N󀟛zm(]?OBVG<wg?r!גCV,Q
    B@!P(
    >XWPn>ǤRfhjdԆc%$h)_Y(^Yrd}̲ٛ3.2]ok:JD^FxAf֕(tZp]zz/J+
    |*Vι{pחlX<)ĝSGΊ+k(Kӵ8IeO.c嶩ƫvxq%bt5e&|/iVymҊ
    *K!P(
    B@!'GEJWW~ZB;:b<R)3=[Hn?u%ͻ{@Ol9ڃTX1<I&z|uiǹFa0g>̉1ӟY&o[(;Q/3y[)*h%/vdOˠCgPij_HYYvs:+ʑϲ^3ygQ/bsH>H_8~ف4Qygxy8yMZYgb.b<Jwm'Fy	MT_琘p+7Tc矢n=d+3_"3Nb}!&zOtKK^O*4:_Y%QI~
    6o	wd"<qZ<*J
    WX
    7sĕnܦ2ON܆h'�ۆ.!_JYl} Yr[zY{2X11<ěFs;5%+;u\G7,elǙyR,
    G
    `lW!P(
    B@!߄@t5~
    nBt\"S/w@LRaVn*Y,~EAX
    ItP>؉SK]]$W~3-l?Y20&|Mԓm銍Nl7Hvv:<|v'l]\%%e&4 6)Xπ3.\T<d;\.L&I'Lgl)&;fP@jICƥ8kyaqM74w0{
    X~FP'yEU"#rw(ԝ}#<VBP_ӧOr>zӦMǾ1HJL@\b
    t@+€=KL@q'1Xm3e:i|e{r
    ܉NΣ:VbeG؋:8'ӯMbYs]Zs8굁l:ӫFi='yĬdJ>s_dCqex02PKyt-&+Έ'}>r(7]%-_}63ZX*9QMB@!P(
    B]=Fu{-<(m.0{'elET-��@�IDATQh.{D荾Чň
    p9)bIdYHm
    HN#+)xJ6:up#*'ŭp.ypqF>}@Zf#ϝE|R= t
    
    "L<]dS,ta!VqĉwI^&b/\Dem#B1l�8UoX\:x^h BNF2.^FĶspAFqY(ޙepiIP삁C <OWkw>YpYM;#)zi>DE~I:tLID\|HE߾Jy*Bf^9zG;2SQRLb_[t
    èȱ˛ NnKGLW[ј2)"V3G#־,/^E`p:`GooD=Nھx'9As%Ɣ=8ѧ({::^pi3q::�ѩsw9Jzɫ8:Ɨǫ[ݝ殮f :<*)@^Y:x##
    {vۯ#ƏCcPS!TX}{8{$iabϯꊞ¥m7j zw
    5!+%1SFs#\vabf
    U.{H?{ґ$59F
    dNI˄_HxkŷOLJ
    h,AFn
    J:<	8{"нO$aٍvآ	bSHcꌮk'Ĝ9gp`.KoٳQH}g玢9׾QC+RR돬sqw؃~}(GP(
    B@!#k"We%+5L@fadd7Q+51oO\ERqܶ='lI-%YȴZ=Eؾ}<ߑ]VG6`Wg1n l}D1֖^è[W=
    ydJp_p1xuLr%\J{M
    LVb4u[#)'1f;(>ǓϾ]{㡗CNy{泍 &9O/LET~ؽ^9
    XM_kĶk5t4$ðH[Yw^~
    _l9
    |x }8$MljTQ4PN<6Y/^Co
    �zp6N&dS/?_ɋYT@J,)Sb+r=)I*\?.<p(
    N(+)UXrN2D]>x_nݏZjsNtij==_\m#c\=~ݹ#Oϊ:{yԖW[~رoxW]o(~=yQdş߇}g.(n_S߯'܋xe8|$mxWh<s4T]^2~Xڇg`㍏ +=iqHOoĎGPY]~ƒKSc{C8v!Mp>3N=W_^Cd:>A,nhMyg;r!.ҢWaѣ#ޓf}?~ن`ΣO1lr=ƴyᕕ`/_^G] &%Eq[Km
    >7\"z_!97vJ\2~!	+R}x&>_<}{v_V6'ç4M?"R
    ,۔.
    B@!P(
    ?7d"ѶTs/WvHtbҊ"KK=4#R{OE?jSgީ4R
    cnKe-n~e-ZӚj/W=
    _VGlLeZ\Bv96ݞ3G]YԼ(w~٠}$jP+tFQ֗kQZAe=iҒ.hZ}@m6ArT\UQF.|/=6eODv~>M:ORVqNIA[W=d7֏_~HK˯`7P;m.ъt<rsAGk_Q]O&jMՅڒѬk9k1ɄAEm!کbM3jw}3FX#^ܟ6Jx6fr^+ߨmZ+ȼ(76]+I=];nW%<i
    D}I3U/~cz]ByU5#sj)^kkJlR-ZiEǴ
    +h,)>:->\<3ه׬*ĻD{kٍڜ'NL_i?S]4C+1hOsmr M{ja64*)+=My_Mb2dg[4Tk)9mZaZZ>iqͣCKۏzkL{QڒI:*m6R[V`hg]KsEڒ	6ڋng߫]{׋ZVa%5T}'*1cPU=8mv_Ӳ
    8?]{dp핏XN[2mSiYi=#=Vgؠ6uMMc[SبTWO
    
    $z^Qw7kcZn~V][]<]xblB6hvџԯB@!P(
    B|y5CC-xY@=?~3<T7mلb=mfS[b(jDsCwNj$c#MH'r Q_UD?1Q޴=v%brQ|x$qVFW:[oƠ_T&ɄlP[Q@[t9uO\/$!l$G<wYQa:\mwrV1pD,ǜԙIf!_oԩNں*䖦bܜ4b(s$ipd^dL˂Cm-vm+%1	ug8y^Pn[{u1mN	k)qu&rjqθp%r,]%pt t	a~MkD![䜡Ř/nas†V=_NZV<͓~ؐss2G4nBVA2
    @ѿje.1#KqFUKo'l0r{:Ři8ddgU$lXpR{)(CuU81aѳ:i|uOLq/|=;�ACX=AnZҙXrjoB1t`\~GsuF>J6k
    /<urfٝCmЖVt�2眇8߽
    k/d~	SƎF�=OGo&[?̛;=":4ħFߌD|чD1Σ0q}O!}R?hP8	g8/@l۶
    h,i\RFiG$]�^aOGxDH(
    B@!P(Zşzt
     uWOxst{.nX҃Pru6<;с0j"x::^AZ'OZhOάl FpAansY3'Ey1%'p?wsq^e'בN3<#Ƴc�T
    +җ&b꒷{)^x`o͢_$Ⱥl)L׌kƎ($.A	1pIy#n$]3@ͽ?;q
    >ٺ>m>zO%/1\W,iUĖp嶹p'nO3YDW{'Fy	v<|Bܱjq1"#͸2}K77jВLВso76^}SqG(X3ba7~yȑXp7u?SWEe2I&/0!c.F:vd$jQc?":!6Ph3ÅV܇舾8r{soEL&y|u<x{q+|1>b@AK!>b$zzҖ\3G߁K0ڑwDw[D)B,&4ώ><u뒾J:bCch TҢ,Gp8M?zi%r;*?bQ!GTrTW!zn^Ӹ78_<KyBaB@!P(
    Bvtq[SU2ŕ>KΝ:D
    @abqUB3k`feŲ2]JV0w,:^3>H˘
    U%ƆEǃDp4Ֆsz8vvnۿ5=O6+`ċDrؚQ=e!ح?=zdՇ-u1/VZ
    p쓹յ#3.B=YiwΙX({4Oι3s'qؿmfT(!L.^ 'y~:%tf/P@݃
    #TSLQ8iFnFؠk>K=uߌ>,GcbF&⁄7ŇƗSrNv31sXN<:FGǬW#%0t9f?=*q/Y	[,DtA.(,;;SNFNؗVaX&@Wиt5Rji1Ss]o_7#cBFa-zIݐOaXglXisF
    WT^a-BUE]A vBpfC-Jkv|LL7K={:{Y@}#^>вΐ:hF%^q4HGka^-n9L|pGqݨ0֔-|dvD#gTh83ɔ$e`A1Wo]fwvNzzO	g\$au8vJa
    -{F,zq(Cwa&&@UظK0rhcB(
    B@!P(Nm?vUw֐6nǺG1`@(μ%zl_/[<{/+y1>9ՔQ|uRNttJTzk˽Xu
    ;ʃg㓵oa갞xmO_yK?=S}.9y׭osV@SpNJoӣ{N4if/:xxgp׌>wƚyZ#Gu*N4"[
    H7y	&;}])v3)s¾_S
    ixl^Ʈj*\
    fykƲ4,
    Q&Ҵ 
    /�L
    ˘ȱ]1x\`HVMNML25ꊎ	.M&[TfcGǘ^ѕ-:d6ּr;iC/~ӯxQÎ慟EfZ5fz`=M3VB[2JN㙕xb#pcV<n!E0NچWX[9݅v]ܳU&LCF]O/_̾	2l
    $1Qtb|9b^acGз~
    ֝1;f85#fbH.1S3x<W=o1+m[O^%z߷xb7LÛ?l5ӆ#7Ч76c붙՘`:R_KC![<Z5u^70Оknǧk!nq^φwdѫ=i"erV	-o\9Vpio|;4cǸjCeӺb18Gڧ":ZfycO-ý7Gba|8ܥYC}-*iWfΘGĬw2&N·
    :ČQ(
    B@!P Ik%YI	HJ͠yKYútGA|)X8ڋZ􋊂
    vsQ&Β6tqq8x_Ϯ02ڽmFܙFnBd$T",dZgY28y-d?slk!093D<;	KZ~Px1rRAL;*Ƀ|)\P_NQH#�Pyt&7	OW4|wGg
    
    2_NLDu-|h7ࡹcle98q8*;ӹAt8bYCGRbdψD;ytF85
    Q	S'7&<B>%ŝAүsNDJ~mK@W↱磣^ObVRGgϝCU$OR<
    ?F!zPG[VX!)ȸr
    5P`fQ{#-\U="w^ocNzzQ(MaC}e!^y^:0>#zvBU?@NZ"8MGhl}|h D@aV?A\u#-\%QhX�>
    BG'N$T?$FBDg@8"8#,_;OmK
    ,hNOх0NG=ѯO/8ы)1&9%'׌n#(|D}!CAV*M(EFS,qkr`^c*hF$<y&5
    	!ЕB_q(^#|\1hvǸcl,?B"<ꄌQPL# āLxԒOq&ߡ')T[~9kz\%B@!P(
    vt]m*[TjEJby⃺vZU`HZ=е˷DYӵîZlLr{d>T۸P`aQ|՝i:Lk 
    c-_sez$dLYj%gQlW/iylY{y/5/\[WBqg1E-k%s+Zg\M1$poŸƲ|j%+'+^A-S\&+~KUP(
    B@!7!p-Wn{IXSLZϣgʐtGJlَx&uZ#?-d>_j-S[4f~D(T1!e,CK̓;}E]Ry{
    &uظb݆Hʹ/q"ėj/4ъRrYc*xq}U=57<1!t2lmo՞HYeϺL|l0vɫwӽwr6Ǘ;Jc�r^p;T"i="ԩuytB6kZԡ-ezg˾ϒe9?7.42,|峬/<x6LylW]
    B@!P(vjAgGeG,?FuO(~ؖy-itYt墭%A/?JmZ|3^Eyez,W˶=Ie^#ee.n[wx4\K]%}[咇=L%F|Ob|XJW̗,Jy,l䕷We\ZhxZ9db"I͵2mY[TmLg2o42ߚ9Y9-xYUϗZx[fܢVRa+ud5=tvaG3Q(
    B@!P]
    zl
    wI4_]A-جH%DxzV*^>_K>\K2?qlymo߁%nB@!P(
    B@!@
    ؎۞*U{\5ZylS#|KY,m]1^4~6wK3,ua{V4Rl{Ľ-<^l5M հB@!P(
    B@!oD
    :qsD#vuB0zQ)+ܝUItvp2p3hV8eS(id=5i:QL?fifz`YsxΜOIE	M>~IRam&7?l6%{g@q^&2rȓwɣ5=Pc)1<*KɨkЩs7ݛt;)-(ζ#tMl]M竅mx>4yhLtY>Phə_	cFp44ƌ*X(�b<[Cs<ht __SExS̷eHYLaxQʟ;z�u4i,0seb>w"c܀맍%obr3G(dѷ[>҆ɫK&<_`9WLOB>SL^Ћm1:xq9S2C쇐JZr|Q2B|qnDb'00KPMqYb;=QI!P(
    B@!0m
    @7eG
    5_oڌ7o²%s؊7(Z	QJ+tv</)=}3Tbt_AKRA??Y9`CVz.#j_ו
    '%jA+~q,ۂ,-!+wv
    7O9^D!JsC%|>ꏟG\I,/U
    *5շob̤x`H)ֻ rb={x e7)7?pd8|.R`&-DeK(m&\ٖz<‰}xayTc(1x<i,(SX�fH
    /$[bpkR92+L8\Fmrv&٤|`:Y4g^&,Y!Q]2:KRNsh4UA!X nu9~m1JZd*߄۶&|hEO-t1:Ay-xI%sQF|Y6
    B@!P(
    ŝNuEs_3"	s#2
    ;"KhrrP[[G_#)D	<�GRi_Dq]D"ܱ"Jm~vgw.,eR}wt^n.ӀB
    g;
    !nJKEqy]=oWۑJyy"vs3m3D'aJO_PsW ⯻;ۃcfP0xW!fe$
    Mb/)qaWrLؙ0夈)#`č[A!Xfj[nFvØ8'N9(OѓLq2E,<l;ҘDb3^0:ۡpF1&/ShE1}ѥsgRQ|z¤~0UbwSg1L=U
    1qqoO!-=3:w_O=U!-3.>A̐<63yט|*6v8ҸS̅|4=\PYZlbGtow;jPYgav
    '˝
    ":ϓvX/Q]Ql8{kΰ1 %9
    ޞŋe׽MpwSh^*0�M/4VSlmޙLb 107y%stA`P0|r
    ՐJ|'%Ƭ9RzyzS]Os{!8I	dqC%-Ј|z'y}7
    B@!P(
    VK*;{xۃ_7 _Ar)f&f3cʗaQ3Z-)wpa<*?K=@
    ${ RĆEJG,( (Mz!	^7?gME}yݻSΜxϝ33걡r.yxITwGCؓCAb_Vfxp:2SF<Ƕb܄)V5u֘<nz`|Eǰb8cߣzDM[7=^|N4LgA@F%";CNMQD?ud8c+3
    ?n՛$"
    |`Q=I6i[RbӾFSlL;tp/ذ><p;i�1m1o=+K!27"̟]? '*NgMo4KxS%%9Xz#d.ƽ9n<`N'vaWL%_'/дU;}c=p<2]}QfuVeտNx(=Ox{+sB*Hx
    Sî;kG?xAʳ4p!,~N?ġ#x{c|fA/io%UgaCDXWmGVU$\Ļ5�%7h"1زvڅW}Io�O'ӌǗOƘ!qu19xI{[LzxcЯcCDD/bثϣbNŞԭ_coVůc?rrq,p||7pPϘD/J6]xjx(>GՓ=o
    `/`i|'o{*-0e[lXlB{o\;5/6xx/xU"("(�6rs5ŭ7ࡣ;cF
    :[I_q>!UIIJ._RRŵꈷI޹Zt5P$bsE]iiUR2C=^/ĊԤDៈBJrl}"3+[\:&68$bOj",!JHWk=RIOSfbզ]+
    p^-YTdIh=揜dA3fĭX1{+ѓo,j!xs
    Q�m!q)xWKE!No?Y|JaRK67&џ.b5!o<"%bgEIn:@,6byxhZC<}(O+e %Gkpʖ}G~#/Y)jHH7/_NR1!/1"-9QL[<0b(Ԙ;mKY1QE]bUQ"^jѸb#"%"~<HW]"-*:>=F&YYūڈ//7xvbkEIalD/qj-qK$FLFТlqwVzzZq+5S&RZ4_1Ήq/vϏ!2rEbXZb9Rޕ$Wliiby͔tqf{ݾ(X~L_HOOϔZZ$dkW.k	"-5Up%k\ig(z+WR%EJz8ke%uP v0c"#9A{Xg
    kڽ䄉S"')Zԡ1E9tLƉ
    J
    ľqRvݲCE~JxvvAՈWŐj/E)(ocjnqYA2R11B})"("(jA/
    ?N:ZĆ_~Č1u0rUuù3'T4-h<؋Д1=̪okI|swq35e|.=~y<sq>4Vn5"S`h-lۺMSk(*l+{w|ÇۣQ!ν{@ro٦x55; 6g۾i2rqqWzܷcպTB׶4HRv0쓆IC!ҳpUZ$O-3Ӽ/Opek|+OhUg8|l;oV`p,iJڎ\Qbe\Kl\'ns#xjn<`ԏ6hجz@jv6C!-[hZ;D@o$9z^aH-q(̹(pwViƻS2e(+\=i\@@ YJ!Ib$_êCu
    -Gx9̀Cu�Bl6dև<E*?0͟>_5ԸX?߭z~#/�>]AE>CM{xyڡ^x~ճ\Qɥ1zvF-{È3ǠkVVN^PnK9<w}to'!+hӆhIGk2hѳxgWВ0o;$%eȼ~ޓհGnزc7
    B�hv}Kgw7~k OwaF)7
    =8;EۺA8q`;5sx3VEyalc8u1t?B:HY|qjT_"("(=
    \mu.0ƀǺx압X=ԬFFݵU\>rCx0@&*Lh֥[eim3􂠄ժYiqZΆ?@ ݻк\Q4q-zaP"wЇk0r.ob|\ܣps܃n;VG0k,ti&4vf+oXl^KqA
    
    LTVb[ҕmG䮜YdOrȘuDe_A9
    CS]bh
    e";cQZoV6JE7lO:i}bMFд>q>!NWmB{fAXb
    "v@u.¢"澈7$Ei׍ֿ=x!F;u*BQ,E1m@/i
    hZNMv5)σoXM9pciwl@ɤ- }-(8_<>zņ5ӌBpquIT8JO+?p,u=m^d/&Jd9Ɩ{�AOaBcEpr)sڰNaJ/zh\Z/o
    Q?s/H؛_:x{l!D
    žGDt9ފƾ3\}ص
    o@>,e-Kl,U/E@PE@P5xe#'e uj$ٽW@[ȴA8K6]a~fo>rn^{X缼KyVRRʖf	ݽWm�QvsqUc1d@V9O9h($#ާZmtC?Fbh@e:qnoqv-[	
    )g)Q3l6:rhUhigllDٓvw0ZO'G@-Ph3fhS>sI^�p`l#o+ؒΉdAY'gwE
    <)y
    ^A/creo#4ѱaGQ#ɬ~6;.^FAZ33襀wm9ښtJ<lZw/EtU{8.;1i<[ۏ@k4 i,S$*)tzZir.âqy8Gqz,.[%m)xZ8*ff}1x8Mߦ'v:Ky!#ح;\bokHB9o-ƺx1p
    l7Ԗ,]}jke)4U.1X]ݭf7iE�|HװOE@PE@P7;ló˦A0_TrF8xkY㘯',Z*9An/ΕTX+_0mK~i_\K`,k+)J-d9ڡQ8c&īwƕ;q!3!46\i/e�yi1(a-'DaԯѾ�]2ϡKGNyt+k逑IUͺQO.# 6mނ%Ab7ЮX8z` eO<Alie !Émز!>w4ʡ[xms_9�+[LL,vzI@3643\JQ(xi@։]
    s4m&v?,Ӹ>ZGPhLFdts"6KU['zoa̋nȱh䀸5[PϦʑ˗]6!Xxtj`2Twm]S[T`=I8+*?L
    /8SFJ,'iða4fc1gn Fd(
    [7ÇӵK4;2Vm**CTllcWD"wH/oY"t폽k`xd&0/qɚ+<{.luhi<ShS*-}v?^sz8O=I_TM*ԗc#	94z>2
    dq4mNmj&%#\]f_}6{>M/ll_P硗J{߅NZӔ}6i
    "("($
    1R#"m8s G̶;5Fv>Ax>hT.c
    Yb4ArScn}; >%;C޽Q6[fkDh6WLkv0^BZ{L42
    ѾS4GF-(FqYp\ڷC%Or5n%7@mՖoqGé'a]C^y5h-.zPl}~79<٦>S֥pYa?F5n5\pa\w5tU9$KGÊX!Z"ƒ̸-_Gk}к#hH;Gїӿאv_V\Kx]LNXtnP;#.ni]6ЪRI3#yxmקa#GO 
    mÕ&E&~��@�IDATMGri&
    k^gCR
    ZmڴA8|]{thߚv#܈w 2Nw<֧qV
    F3_{jX#!m,5r/hDe6\'~GhGGYKzІuԤchrzRq8ԩCdz9ҍa:عZuALyXuujn%S֢זǾۺ[
    CǛVǥN6	ԪY^EEA{qaes FU]ցx?uNxO+t;o
    %*t$-43NG5l-ևyiu2
    G)ݻwǾ4mtOGˍΪw!toW5zbZ"P=6i
    ?OˑTߊ"("(Ͷ
    JҮܴFΌcLhr]0ݵXl*cN1$rR>{{c1>?N[:
    \󛾍-HGZ.(g~9`)Wh7Ol;9Yꬕ+_o]fzH lـ26[VRnw>5KxM</oډϜΉ}K䵥ba.[6e<G,,t{ӋVto/i-E~A!hћaiBZaC#l8N8-tMe]%dxO9FLCPE@PE@C:?P9ܖ|H5?)e)5ښ`-NKJhY^'=x6ZrkT_U7&2˩1v"n6q=进ܿ&q܇^qcd_ZO3}/BIw^3YȨHr{=^_~l"B]/ww-E@PE@PED|7e.`ЯfJSef4IbzL9/ś~p>g,ɲ26djqgKϫ2~]l
    t)+Yףl(꣜mejiu*YlydD]YVY]g]7K9m87_)g2qלGlsui%d-cDYYs
    ,ڤѬYgXeu}urt٦oc,^MrLsГ>MoKYz[
    jJPE@PE@/]>x߅g٬w}_FRG9NǷe6mfn-Lь4]œeyۜk9~0+=&L%,ucAcrX={=D5S("("(?j
    vAWr;
    w*/߮QPűP~S~B|qzf	RZ\qUp!2Ky[/[>/m\͕f"("(_I:W,ckۋv6o+	ltu3gfcMoik,tKwt7Ac 3G\Lx]qfLbztZݔhԅq[yvM<8ɼ2[ӱeHH	7?xЬ6kb*S)|閲hWZ<[Su0G3C.Aϯi.
    o87ޤ,#=
    	^T0:̓v
    M'<o-
    rg{qC̴[H)B`@݊rNєx
    9hڰlnbdOeJSHa?mxƉ0344^"xcSѰqcv'!ez(-'pe^5۵C\>u0L=ӌz۲eS͵<ڌ@-F`?4(Bk-z\ov5Oo#Q>XS>|ߜ&e<_U_VE@PE@PBsM.whjLTo%Yi0c+/Se6m|կMô4vn٘0.mϤcWӰti:{:% Y'�U=\:DsUmԱ0rX'Sn`gٽy<W{Mmkp9ie$Iذ޴TA.C$t5O+(CbNs?fuo4o1`ءcO_!J{ҩCqJ.Q__QCë8D#rs`eH.$qSVQG:ƧoƼ1qu5
    ӥn9=3%Y<ft	ǁ!˾aĀnxt++ī6f1Nta薐JK]\JI<:e497Pux+^~e>U]_,epMW>>38՜um,?e svo\C0i̫p&Uik-zyǛ9	ř-[4^-(E,_IcYNGiT,WjVh("("ܓ@e+8S_~VX1tm5gb~A?.c騦<:^0L1ͧ<<iƝμ<rڒBo
    ;{{ۙU*χMp!r#Zz#@j|4&
    fO72QXTLOtV3nogc26J舲LJ]]\P\όLpvv%ݵcGlˇLёkNpsu/'9~бmd(yzʶ1O%gTy_8z�Rнk{8>hT/R2h33wW'N7Bi9;tܜ-lm7(>`ok{V|ˇf]\=T5<c܇tt^.[>ǻ0>>你~d`Ɛ(ٻѡ-Վ[QuƲOүEF;#,:PWm![8`0hD<cAau
    [WmGz£R0t
    
    VWw>D_TJ3FdZ'H%j,.viq!yg>>eU6<nORzq!a|�=>ni)H<SSSQd7mMF#
    DS]v䙒W`/W2Y'$V/C'a؈noMӀ:p}NtC4BuOo8j<bgrP@֋gK [&Ƹ;߳XrւPcEgҽce/)Qt@`P"B:њƪO"4npƣ,/o8pJYv}-NWWbJg =#N.4.
    o6
    QwQ5_@=c6քXzt/o_҉Y
    jGF2{7GIaCPE@PE@
    &uQvu8SFĂŭT\ɽoC5n&?6-o~nu0j04;/͢~6>2
    m,3X':'Y~SU>VoaH:PNh̟;Qzؑ옏E?|F#S>&@~c(-r&~帛d<KOvU~:~]Vn;
    *G`k}ޘT%bXzIGPQ=z/*.lZbh^7ȗm/,<PENxh0qÜ[hq2|]ɦapeL7}5{P/«oG(Iof1&
    ņ|6ulp!EhPzپG?𝱨GVQp ر;C䥝ްuW,޻Ƴ}{Mp4
    u:G,mfZȺ.~FHOVd(&?_7FbT.8wl>$lEUUL`<zk,
    NaY\Hc&myx64οǕl8a(|4a.SZ*,Y7:}ka;Pͥ�u1Úcks%4~23.GX0\޿�&Ʒ%dvbڴ@
    &ǣד5';#Of*X8;<3+i]|o
    Bu@o݌ÏE;b4MyZaX0qcGc3@X~;#wmF{m}i߸3m0ܣƾm+0nܗ٨
    ѨsoD^%p+*%q:M?d&^)a+I/hrLY%yc׉K(,.A1ią{1s,w9+x hv|+4N^_P�L|^@%w/0dĜY3L["n{2#a˨^KLĀ	t"("("p@YMq+$zXdiQgdy>V;Z^·bɯ+ʼnSgŶU(.HzH\F|C$ed1aV'41MYRɘdYmb(C{6߬ܥ)QZ L-B{
    )yVycnqj8{lx96S"N1oNEbߪQ1VBXx8p&/1hd*mibvBEG^/Ƌ{~)39Dn/gω/ㆈ>)v8$]"n&ĈΡv]쩣bhp;_JMzRTI\#mE]wŹMgk7ťO?$R\O=9ľ{SQ"6qu	YEN$ENJb=ę'ωI"\(@vo2/o5E\,zD?7PLYo?+FO_ vH\yɱPhl!rQ7߭Y~ZUP=gINBS	2ēȓgĎ5$ՇK;)7uZ|>~@Drn(μ.^J|0g)9(:@-{T|lzvs1J̘ՂĂ/GgϋLgq!H+&WG"!߾Vn/^:OhězJԵĢi7O*=!nfc?B,[N_[iDswħ%];/sDb|^q) *W2c}kE=sJa?fLjYlt.ӑbϾCjlܻYT7m['⁁H97E*migo<,k׆B1Ѣ#DtLNysŅ"5Ӱnf-N]',v1g%f[$#l\!HI	bPg/lEb7ē?WŭϷf.yld?Kl*qyQd䤏QMa("("{Π9c͂?1a4FԮ=hH{MT٧\Lq&|9֒~C6Y'Ώ@f51~L4䒏Oi>NNqtű=晱h yp
    Ī_-/#*NMri|y(&4T3՗3p7$	\X@s3dRLFn軀4h	m\Q?FNo$)V.Ĕ@&Qeo1ڴkwsCC@[oJsr?ֺ lexT#̋oa+\B#1buFu?; Drθ~Y՞&"T6a v2]+nmtl&sKmMiy�K}/ނ_/¢/!#5EZnXl'r_G&kr	y#xahK�.Ϫn:eClmmKmXC.,G@o[	-]Ѷ32Y
    y%-kktA}`Oz,ssV/NCZJJJP!pm[*X}>S
    ' ZWߦC麝u
    ~5xph&8OwƮm[0ǵx{)},8ZN"k@Ahݴ<|wwRÐ}sロEDԗyFF!7P(l1ֿY@xcpvxdԺ/w[^$f"xc͂7y=5$=u	RҥHxXm^QghF
    BwspZoKG^?fZ5	ԚBK%|{܄ff#*Æ"o^HyNn@NVa-`~=ۓDZw<59P:v4~1 /9OE4I4aؼx{p_k6?t	wm<r맍(䈽}juOE@PE@PE$9-=\E3?nڅ	C-EZ!7!A78C=ivRhm[6yѐC9عWb툊Žm{0^ҭ֍ќlzOwhC<Ǻ5"_2k5Ķg'Z"_�'w<;ctIDDX0j5h.FF~1xrf~]ԡ5x/qzJX3^+�?_t={O]D6u\Z#gV,[1nr6H=lͥuPR\Aj./^Pj(VXNS^]XuYq>?֒]DauȤvqFnbEGǻb쟑HFT-=]5dzInԀ"�WaoXv*z5q~e!6itn띆k7#vX'NT)st_<!e}{z7 cT419J3 ^iiOb4_`@]@\>
    [3<Վ^P:! tigz"/GCj!;vn݄_D?~8
    d۠nXI\M*l/B~QTP`L'cE/y494JlzIA{*_od{H;UShsGqҺRz	¡z1i^P*=#g/^�%p1~*!~NڊՇzQ͞Ri㯾qqPxG~BZf1 ('෕˰i3i\]/-7Uu[9Ïc3q^<?9x愙Ԅ\ˊȳ%6P_c`W~l@R JE@PE@PAX{	9@3ώ#jNEl!ܞ5˞~;	_KȪxhYIj|mه>{cךڼ.)σ1|	T
    n-x^ˆ˯F@Y7݀qسv+)ŴZg!&~-Ο܏A5Zt2v*@1>FlE:<AVf~=>acZ;uuC:?_li7g,B1\4=y(Ɛ=mgo[No}�Tv%c2/72J7jG3pztx"/k>z%=S/m2 xr,@m^zp‘|3G1\B3O@7E/8Ͼ;ڔ(-%OCj^XfIŚ3Nxz ujQ݂5)cԉD6�e sH
    mΛ>@ǞE*!e8UmFK`k`]JF<+W0 @S8;1$8и!TA1(h^Kc2x*I[lJyۆ#d'@Pg/Wx7UH/mto-άIhy۱n49qJoMC`˚RTyӋ*$ٸ3Gj#{'`.|^%13Ğ;z Afxrc,K!?&lh/66"A+o?̝x<sFaesW1Jc	ls ?z@)_GXqmikDFr
    "("((grKnf
    v'7H9"ڜio:m偾2	0/ch\:n!Rk`>
    Avp66C:0vl؄]#MƳytfF#ڀ.8w6
    /_a35~YXe?
    ږ\WOڅn
    rMhGk@?xFa#싯sCNd9W*=#66{?-A.޴ySe6;yyV;w@HE]5͸4ʧvp*"ڢn#`֭[ϦM;EE?gƗز86d0!2̭<C38w(fM^a~)Qkf4N)=+c¹ذ
    UD.ק/];-:c`8[ZLJ@3ð1\~D9?A
    rKץӌhȢw93ػ74@KI<͛ '3MF۴
    y%%;}.sX:o6w
     dފ&9Ă8Jܶ]}n4l޶ΜC'^}<y8D\\VG/zxm$h6`KʐA*Ҹ^OɐU	=WǮ(]gaϢz+HٰwBhL6v2CS_l\d.6fywyl:Qgqxݲy5Gy/8(:}wF{鴡]
    mp@^ist6rGZbAKeN~3ūH[&O<vhԍp]=w'LFKl@NP	kCCo硓M`m�䑑t͋"=˷2Յ"("("p76(TAw[NOMA5�h\O:ú,r}uB
    H3ky,]8tP|5q]mʩF`%Oժ(v ғ0ga,>>=L>(S"\kTq4FڌbX[ً
    Zj&.AHz3fǙ'wQ<5m<ܩ%rb1o׈<}if:`<g
    EyKgذBbF>uip4Y	?/\d5Yr]rٯ8s-M7A횡f-_R{ԉ	/kj#9%
    >hWПhڤ|L>ȌFbցӱXhԾ'j=ab<uO`ѱU}Z3/Kk73EC0u}-@7ʳAd≆ R$ق3'8	ի`96
    M5
    Lhޮ3"Bk;F2'Oxpr<KE/NB"f0(<K#@oOnӜHzaq^Nk NHM<i}4)ˆo 5mJtV}}+m)8�оKWUĭ[9#9uitBjJ6|TGZt4X%C`媵|3[AQJ6.^.{"!z:|o`ܟ
    -H&hڰBJ>fA 95>GK68$Mh'tצרEӀſcDgƻ2v~r8F>YC}gB笯Τ#3Ip"xy;M[6;Зt^^9BUCh0,kޮy4l{:;jE?.|u
    sxVQa/>11<~3۱7Zt3{a㎃8y�nKNL.#)%&:l]hF+r^n4
    J#	6BM,^ϜžQy{4YMwCFuAtѣgQq;ZV-I')U"("(@ȣ;6e(
    JhLOcQҐ C!5&h
    _ei.eй|VgjWr*ì_Yvl^&m|0vA3Ғi/:ח^X\dyw6A[C\ϒӚLv^R%S+L	捱ҍ{zmh]ܥ{eBy5@I7m><3t!]^|mh]6_bvu v%|h\=im4#|
    :,P{ΦsrȽ>t3#32fk>=l�T)gA.3e%%<NG9!e0Tw>iK"LÈ甔y浛'I\/6/	
    Q->x,Ίsgh9Hlj[Y׀0~1A[rebdAt\l.M4H6gxb3Ǜ
    FZsϧan+-p=\LiL".j"Cx
    >FA!1璗Zg66I+q?D͉^zpEĆ[-Qح-s{q(?x`O5vg}y<4کt_~/c$+oߧZ9ҋڭg`jCggdfSΨT6PϱOMM'w{{xў|F:φ<LZ y<MB=
    a:S>9@}%yN_3ZD�/0&/E@PE@PEj$ߖלA<l8
    îgt#/9yb+J:IV6Դd-^QK],gKð|Z./$nÉfKIٸ(+iVsp:U]dbd6^iRo	Ec&=O2|c5dL{9^bei9T^f9ej_^^';]߲n@rY}eU^^YX[r*~v$T9ʕu5~Zr`qiY5g14i2,Ar²MepE@PE@P{͟ؠ5=-˥zzY(.M=�Ӭ'LgD$ 4,y[y ;<,qFbrh5d#AkH5G߹/l.z}zlN:k]]6C31p9NiƂl׌
    d	,:N66t\ߝscuXٰhcY\dbS|em:E٘5E0dLR"F̹b6WYGSQqX>Nk`*ש5<ͺmL2tz[[p[|L+#d2}<s_6Cx\r8t�yz[FYZL~AhmŲۥs8^Oy*$.G}+"("("pO^tlg)G3*]qSE@PE@PE?@ѱɁgT$omgͳ9յ"("("(ȿKc"QE@PE@PE%3E@PE@PE@P
    g(PE@PE@PE@PMomVE@PE@PE@P,ecF)("("("o"So*"("("c	(5J1E@PE@PE@Pۻ5ҏ[>("("("(w'`Eg;;l߫𝄪xE@PE@PE@PE@nkߞ@gƍHJJMEeU"("("("܃^JJOfo3-'ObÆ
    `!UdE@PE@PE@PE@$nOGni{(R?g\٩薐Ե"("("("pt#w,u~ǜ*APE@PE@PE@P2[Tnr2I]+"("("($Ps]]
    t.X_^X}>6^o?Ȓ;>,e뿗eY^-?̽W#{Qz~Uߛ~S]([IKKPE@PE@PE@K	XҕpE@PE@PE@PE@/@/L*"("("("P_WIWE@PE@PE@P2ʤ("("("UE@PE@PE@P"¤2)"("("(-e|tE@PE@PE@PE(0L"("("(_K@-_%]PE@PE@PE@/@/L*?⟮OPE@PE@Pk*%`eeu"z*V\%Z:}m1Nl4ae;1p?m;ᏖgTl_-Vr8SAغ7CH"-c"]u*0n]w?2KKY.eAH|tf5Ce>{s~fm0r^Iv~DJY?&%OPE@PXG۴�$p񉅕3=WP/%y'Ys3-/Ϛ
    	Dw?|Sרjŝ|]cv*jW(w\TH Ōf?zƳ^!lsG-_H^D]T4fn弄޷^>E@PE@	@J
    %(**dvvpFHH,N6D)n%^ɰs@8ڡ%mRɠ/Ps{zzIQcbU\-6.u1*lYކZ|;ʢ-~p<Z?Y4֭ml ^zO{u:VwgE˦ܩ\3Rn 6>4Z:ܜB
    Gs=דp3).ΨZN6a~mnynfb:`gj5$LK\uٖ\o7Jt1!X|O}z3ҽuY%^^NT[HٹY8:!?&,QRĸ$U|aG7.x>&9-1~X2JK
    pU8{ 8*蝙z}zY	KPT\+kc|lxM9nWgKTx(E~aLwt)GFTPV./2t./,^,Ttra@b|3А`8ڗO&J4
    =Su<"�[kѽ]	`K|&ABPE@P'	6ϐ$\>KV 1ϼ4E
    Eˇ'eݽ\a-g`AtU(Dzy!	UxQ@!p*a%q,nn%=2кm{ԭ"u1ƪъmCQn͘g-ۯ>`0t(_L;˹iZegu|8iJS>Hxz`8۳#!VE?�!hס#GT!	d#V]ԩQ
    VF/]_}FXO'%1OEq偺 C+]k2ԿFdhzX2'+>8~b̺QqM!ֻl0#~<hCLB]<ڢǮ,O2X
    !3]3/"alo?:Z*%X\Fg)IsK`<d8MLt^6<37(TB:4y\S~pgq%]ůW,FizT3>}V`܄dY?ِ0Ca>v,܊'GI1|LWxXI&ʫ[ڲVIg:PyGvi%5<}Yϧ}3ҷ(foט?_'J'#Y8." +3).]R ͤԉڑrϪ~{'B{]{Ǖ P]( {{ =gM;Μ9sr̜ŗɠ1K)Oe5/#	?v%n13q##⬆Zl[?.i9h;:w:'	/59"uL#E]3sS4
    CwjNr?:SF{~\XuKǕw>o|>03el2lS4܄QfU_䗼8K9::&qmE!^w XJ)|aUČ) Collllll132Z_Ia>KekY=@8ZA+B(Z
    4arj0$ޞ:W\*[Ͽo;:~:#KMhuq 1ٙx-yr.Ъ|ND#K2X3-9*:̌3sZL|s)ݣo8
    ߧo.ـT)kɗ*݆I'sΧPlKZN|+
    3⦸ˏjz휎PQ'6bJ9x5ڳ _]fmȣʍ4[Re6P5*?
    ưSm1x	}UR++WZ;[R;ڑ/��@�IDATAE ć|ltY9&<qƩԔdNum)znI(3/NDT`IFEj~!rVa㷻NP)CfuH)ގtxx;k`)+!q`qX^TԖxn8L#0Gj_caBZWdg1w#Uv*L@DIy7V^?zi.Jǽ(TXj0͙:$\񷖾;e\]%gSYqg]q>VEG/}c<jCR_q7؛D)^“KyKGtr%nuJ~aAR3;nȳ37#~HJ>o1rߊ'gPgcs^#wOµ h֫.d2jq:*K
    {^z+#bȐ!
    fL9r6**ՠ΋]uG޽E=3X^{~%EfAJ%SsAPG*t]2	3NAtÝ>l}I)ݪQfY(-<|е{4z|G/G!+e,=9	9(-)砐h>AyczTf2THGMsg%' !5`*FDJR"2rPUS]DP`8;ҊxӤ?f ]
    Hk*&7Dv$%¿C$E(R+lYȡsq	#UȢ|+FuM-Qu' v_$S�OѥbXf>^*))7#¿6RY2z!-%UuM
    %!#=En]"Nq+,5" (]F!{WIv<7#n;U%;o?*T=ry+-�4+9XLxOJz."ɇrJnv3nDHJ*q!FCGY=*9()bwWX0ݙ&ĺ2H^Vf壼)8t[JFUD0|R҃]/tH!P0pd/Dv
    ܜefwtn;!8[ WEfPQ5@ޑ7jhj@^f
    V! ,#PCUztX^º	!SNP.&ox?O
    kь4|qnqdFq2ؓZ
    !(pqsJnEq	sUĎQpwyY5
    !OnHOBNn%Cfw"+{D`а+J*ǒ^*אN7;B,k)V993Tہ{д=Ĉ!iO:Xp&r4L%Mkpxj<j8"3vNݩt\|E揸]0w+J'?>BwM܏`~b
    >X|cG 5"[MًCpq@WkÆV݃nIilrA]0t0tW
    umu9RSRZV�:x堲 2t1taÆ"4ľmq*'Rʾ{т(SBl2<ĤXɟF"<lwyY+D@h/3%وޛag7R
    F@Xٺrݍ<n:b0ߡsv
    g_d[U)&c;TqMV#߼uٶ_M{
    	LeMRE#t>nIQD9)CZ\_lUYרf%XqU3MMsH`owXYZ&X+f&Xo/Hy[-ͷz܏WXם^<Xs>*չY*϶޵
    jrRWzUVJd7H't[_^(Ln­;xz䮿+~?[j)
    "Өq*fޮm;[XdJ-*.Xu7``|7L϶f?-|vZw`umVnzuXM*ݦC3nTtUM,'mOrRnqQ[g=vxE3hET*|φyw?/oT)~#ǞaUU'u\kżE <a05^Ӭa<gPVYsM>wa?hq̴^~gTEk3ujW}i*u-sějbGu
    Y)+YIXuywcPsVJ
    :kˏOzٚ@@?i}}"ٳzuǘ#Lo{
    vV8|5YsκN;#+ؽۺi{H&k5Vwe;{`;Nj
    gO}dl.+֚z+*[x|~z쑟r+i~ߴz3]0b;2%V~{cS[}X^w_uٯ,zcZʚs߇Tk8ygşjt	yUOc?έSoW_]`=vg߹~XaMAkT\f
    wAS?]VM]k*5G=F]du<6gϻJ-t*]}y5΋)ZV~^$ӏ>}eØKmqo߷uu%SЬbN͸h.!+6POٷpã)ҵ;7|Ssu{r~?9ouit=ם:݀p<񚇭_d&j=[Qn}J)Q{~9[\]!kzRڠ:ot[c|??[bߕew+yXE;e;V6_ce([fF.TќYzt{X+30Q�/o/	|رs'vJkf!WJ7_(Gf”gjѸi:;;1
    = ~My3F
    -7wi̛ꟗ;eXx5sҝ-~K`W{O/X2<~?=7Bu/A۽Gj/>k.ΚizEǸO3sxRX*o]RÒ5۸O^NdUtxxvzԧ̏3_?`s.=<_{x WpBipۿx	7>RٺU?cɊ[f@jdGn�LU{hGEHZ5ʗ+e߱n)}etĻ`}XB|ĦZʏ1uu
    iW܁ӏ.w^xu\8a�b-`ɦt\|b%>z}1޿cOս?ہ}|gCVWi{'lAqggcIJyFawD
    膏߻;_f':#jĬasi$la=}ǻ~Cy-;Q=Ppыq-|>Zd)]B,?/7EWs:2sS�4ܼlT BO|/"fha_i^S۠ҕv*O5%ض�UhL*~z6~x,
    a#X#**/œ;}6g$x0EmzEsC1T=Ll͹7\1=
    X.IcM%_Otp<"%x(3ύ	XTjĢW`ʫ:~{~Yx>&¬׷÷7PlcA
    !E0B8Rt^={5}ݵAb&K߷tuf?zƍ͕.<׵wu><v]=(Zхrk!"#ϛZ,<qB˸kёs%m)WeUYw]Y|<s;I[~~4Ԗa??xZ%݄I7o?yuӞe+sq??_rv
    xmxopS#5+[WM,eW_bj:ޟ9~`xfvgQ|fhCPs	n{e$e!
    g1j'xP͜s'"bd,fϚ=^>X&)
    y`sao"GZРQA;`hO>b"{}nz~zkg]0Շ2ibOxk0O$EIy9**x괺lw9Gǽw߅.KRm~eN2{ݰvvFDRjt+Ns\:wd#\CP'xyy(ykyE,n*kDN5̫˳1k6Ͼ[FPkiK^Rt|y=18*=TyݥƠRE4GXzʾxqN4O	T{FVJ ;oT2zLcm-߸I.?/~
    I00鬱\v=QRZJXA4u+1i
    ^rFW( 3]I^Jq2`5Pazط
    bFuW]3ƅVmp]X<,eI7ndr(#/|~Oerz/n$!E@H#9z=ASqѫ/F柰5i1aD$ξDdDYY*kj<:9{1?47tpVDͰ+	~7ՏrQ9'<F<L8+CҧYلZ-8E.qCR54nBTjpy=X.(/T玃9K�)i7,>^BQE{O@T-tyd$|q=tyJ2f뙉~N".;+ň
    jϸՀMq/MQz{SEu׍kCJ⹅p	23~A@w
    !%!'G?L6v."%ƻޙW?B]o1e=)kzؒp#pţؿq5-[6`\p4&y.o]w�W,ZwuPRHCSu*^k#ԩx޳xEM斗س
    TjkeRWM$Ȟv~!fek/>u2{@UΏ[YT˶+sZ=ŧ2NPs-3	l«g}^C;nݲyUsaPV4�]'d'+)
    Q*^:E�]+>a>OI6o:\AN
    ~^mEg?r1bOK)_*tO$lv3mA]za4B{^}91M�QI̚_!#߇Y
    56}Hde{Scm5L!62Njf7An܃(C{qPjgjo?fj|k*
    sNSAdyxu@r#eo>sxwI'ӡrjL&/5zK1&xGLf%_P)5Bq`,d
    2\)璦݇MA,V}>ԃ5#
    ?Eb0z遛쉵w>N9jHر};v& 557g8(+9ʡ0}\|ۘ|tyTnx;] 2wvuс*7oWAF?'uyk6a:-S<t"O?
    H*
    4V4&	_uH~J?ɥ+9Ut<}�w5{ᛝjZN\�MɘT*M%NY&AE~eض=QS?D6*UT愃fGVq_co7]VV5yvahz;&K:t@]^ŕN2U`V!)zq'AmIB6S7qx{f#rq^]"+ܯXNt{B苜rY= 71Ep ݯ4\NG0	J^&[E5Q}3u]=͞`{-<9YC:ۄe
    ĤW鸯u܃ϔX+*YZiSio?'KlDE(?``uxa>g_
    MxrZ8I˞pu5bݢlYJ^)T)S0~hOb
    $3\Q`8idoDžA~eRYfR#hl\TnIe{YJvsG
    OĜNk7Z#/i(^tĹ<IFUcƴ{0XOV ^y<4m_#Fr/><I&NJjΧʓR_/NsחI3
    ~> ,	gy4prтb)	qGY*8]
    cЬLH@(WT<4NFkv_saqΉobLkC1G`lqI1KLi4#7+ul~<+O|hAWa+y;͛!~2_㧖	QîM?9@|`.8u$wؓQtREˁh:ڬrXʌbr"1f*5V1Ճ~_7;r|
    E]2|{PbBm6"0j�?NK8zaB>LyJujZ~q(xˏpY㑺w- 'BיqnA4H"bVRRRB;9ѹwƁ!x۳An1@Ve<j''XS99Z{f.reM9*}*-ΕF)V,mQĉ/ߖ6uA˯KK}Ǖ5]oJ-8]RI|t;o J3oh4-F-NE~UST/_W7WFc],Tc+?MyJaU1)VRԌZ*Ҳ:Xj-Qz%554DaTL]:cAa P:JӹE_0�
    .n>$.8J#4;^1C/r.L.NƎ݉xiK!d	fH#RGQi6bb*5i)w\W	*y�[@ i
    /	ne;eq3& ajQn.`er5i|tzC
    v-߁P{+,RW5
    "e͘,o+/Dc4a^0h&"_uMng_S"tsxxcϪArz*]aI]8ZeN-LG$&v.,'~}~C)#ΟM~ql7qɣ¾P>YUNKWX>8ttEDpLpk+	::|I](edǖ	x\DK.LTCB%5<4Nsqޞ:O,nuh4'QXŭ_.\O?QEq5UK@r&2bR1N8k:Cyѓ+nM|O\Gh0t.6aطk3VڨœmWR%Xgq*̞iɕ|MA|qbpFEFCjy
    o_jَxvK\j:,4p֙f7f!~X4ݰOEM:l
    _~/9\O�oo}4e 5~-WtE[|&&&"!1,:e0BCPIGs,zy
    r<ەiڏ5L]8SSx:u)TkWϫc';䀛΅Es+|;S0tD\wMʿ,(k[t=Jn[?R_عc+~;Ox\~;][ʒuD@POE6M-E
    t"][ݦxCGFu(:Rŀ42 -fmE5J6sa@ŹyɲRG@OU҃%؏"ѣOUp,jRy|.~iy2Dr?OO.s֑\Nܻ)	,;gLRlDɉK!`؟PH#ogg+j)~]y)6.K{`?/:hLTe߅{2?n)A?I;qՙ5%HC
    [hx$ICj!N!ʖ`.]N~A_7GP2—ذl?$"'9[V$pA=#fUSݷQKJq9YHNJþ+?y;Ow4de{8~%Y+<hz9f4-س{7R=ڳSslc]k!cr0rtBgB'*c=OXj36blh?~!_ZTϨ<$ҢV8ϯrcKKT7;[PɍlH>{S]Ozf)^zT-'rQ_=!$š:v??|qi쇥9D|wДm2)fѷXu7vmYu)?9A_&:FDL"�W\Iם9cLxȖ$cES�w@M=N?DNA.zKWIZ&mlllll2p�ӎ) bkZ)z)V;ҭ-+ZX?ߣ^4E~G;Jҧ?ߎHwe+="hցغ>.M'(ͱY/>麜n%+‰U{߶9Њ,JspB(Q|98qtvS[s&Y$*چBk4{Zvu:5u>wى;S}[ӼxpWa1V|M\"OqrzQcx2Ћ:
    /**ͦ{QOBNPSf}s9d}-]m&%yϓOS]ykk-9Կ )њӽ<@u֏+Su_-'^˭ww7ݚ{9~KT}?mmتOOInmQtEG<|:I~'eY.XcxR< ?d	YI|>_o]sɗVN|ۀ_<p|maߚVngc
    *L~ɗ
    VOUMĕIC$og]~G<}^nQ4Z0g>O
    RO1-Sz,s
    ֪+0ѤNzMúZǥ_u_Y4YNƿkKi.Νڹ|u*YOI�_K\K;l}hNM:TX?2:~F_ϏoS[蔬>LؖFe}qU%sFsoIo]fQ?6d-+܅7q{Ŋׯ~N/]|XW;tg?h8nlVOQvS75_\ٚī<}jwo;:O_@ڕjmImGp|Q|9>7&8v:G{N0OJ67;^Cd(߹kmT߱ndTtxD[18Tle	V߆z>
    Q~<P+ {@`˃<1|0{\B0p/	
    ?>r8S<]d;9yÊXM~Ֆ;<HGO(B¹=^g f05J=~G|)VӃ-\1LN@K ::yvE+.s|ۨ%]_$.fxm+ٙJi1G <4)ɗp9W`wl
    Khnܫ@_}aD9JG\W߉CNF:MJiJVw~C;WF>Qܯ?'5dq嶂ߋ4niFb&<nZ~Bx8Zd:ȞC0wٴܯY\uLwH,w1jP\41K{a̙7ӏ#;7ߪn߳F>1vKpοo9߲_7ɋ{M]i=ٳ)'^+VQ};o;0Do95UdSFq;"xp,ZXW_C]1zl/wzkqdmDY(qziX`,?t=nKs~~ߵBmJdd݆e]&ا.0y%s
    \g
    CJAm\	ѽX.޸K0䤡<?q6 ԇI>8㱈ߠ-Ą+GKC
    ׷
    t|O<y*Fն}~nU\r[F :R%^1΅^rE	Cp֍Lb)O*&^v*-QԱw1dL?yOh@]h/b
    e<?EP׎knzs2rt֓"Ciї@8^H.(Os!qn<A7ͽ߃Q[VzU=C'YNxӢ=${
    xtNLkSLy`$/z3xBWb=4,ܽU܂̷XZDb	us	;5!08ݢz1#'-[r֋ΝbftWco"D HOξKېz^.sxY]t-V|5[/_%uHL`?ޛY:90oU,ߢqr_` :Tƞ9t^e{EyMxvBqb_wHtoŌHX\j5$O8	ǏnEıoFFFFFF/�t:FhdG	?̋ҕU<xI?CHpxC�ƙsz<‰}:3Pq}Z[+~M q(k\}r?
    yMy8_LaX4zµfrb-ދr/{ʧxv4TYmIA!-ʒLƨsu~^9X86KDf/_u*r[Yqiu3gqmZTshfXnS!\~*/).[5VQ/K4٫{q?r%LGSkF=Rr;O!t~j_LsW>`Z)/&&$#9JٺK<@	b>+Q~/uK>źUÓ)AUJtUNY9QTY!}p42:lOKR.P`]QpJ>dxlC�Mu5XF.s/O}x:F$vJ,+'yi@*!4=ٜ[̳<X8 B ;b턧myB#,d;#"_-N̘Eʁd$r$?9^Mg2ޜ|)~x8H*0<ƒXՇ0CƓ<H^}̛cڬ9կ|;⤉ýs?gG_y=
    GS8~Dnٙz'uJ\;
    c[~Pq-9SC\CJ9@w;8sƒeIZnT m][4/NӰmxP[
    .@GNd:QA3>/ԥ+!mlE0[$7_YB4B;!	S:۶m嶝YG{{}gWcGGNyhx9ys+&5?f
    0Q"`7!PkeJ"	ۡPq0:-MiYb{=C9ll{H~F.I΁lƋ
    #!Rz8#!R+w_Kcg:.#n{8A8ʉ__R$uY	N[V}o_ɷ$U99mBV00_\E%O7\ՋIac_9)ܝ80J8fҡŕ]/*5r'*d
    cxbL"uIhx}\zJ5[29y5)1m9<Mh#}al,\SI;23/2`'[YUvM,Ֆ{`En[ Ik䤄;on7񾺜
    k	kZ2H]1`+c~iyL}x͋Sb3%tɇ`RfE9ՈG"O{5Gy,朋D^O9yRjۓ#hk鼵|g)rHIoz	7JtNf,<dRKJ|8;M#_IWUY)?.܎	/ܭZ,VǟS阦PJtnO~FPKpZm5	b|-~6lGFFFFFF/QWu HyuȘЊs97AoљxO;fͳMr]x|0 5ƻU|<",c眦?gLykߡ|ɳZ˭,a)
    3&N[!$.tYF{ã},td\{LJGVW}q<ɽYݵ_IYh΃ynR1~k=)Ru6ԴIY^MdmΣ}Gې	.:yiEWNT6(ZTVRX:�W;%?ԓ&'e4JXp{1_"C9 JќOSٿtZcےoOœlLgoKۚp~-:kL5mKj}7w-:hn	CIC[KyHE~cמp7s%N$%OLСzG<1t}86
    1[j?
    u܋"׾{8G9"?.V8m66666>cnx! c1QQ
    J>dj%uk-o" mGWh.\q7F7S;'l'g4{c[A?΁1n+Y`"�6K#!`+GBO#s?[ASh[AoFFFFFFFFFFFFFOEVTlllllllllllllGVS?n;1q}mllllllllllllTt˲Tallllllll~&)llll9۝1W666666666666(GUeڱ+L࿋>R{,
    #^mmlllZ#p.޽{(>L[&RG)?7w^jǂRf"Lqޙm9	vܛk[&=o*|nh|L~&e˳8G?tMy6;6*1r=i	'WqL
    󽄛*<M7W;Z|̽3/'W#Tܛ0C+~7~Bw3t%_9ɳs|ygTw5-~<e0t_d^ax9mShw48ߛg\B[YY!C`С*؄Zj#`#`#`#pl#pܹ3{	;@EEEpxt5�z5%SWAXo۶
    =zUR^΃2ɯSo^ЩSl~⏒M			ƠA':mo%%%ؿ?WVCkreMHLLD~~U
    m6666eL;vT̀At=K~$IQKyy'B?[Ϟ=U	W?'H ɯ(;H?fFD9U޽'Dz3	ϚVe9*~8VڑJKKñ\'lmlllQty;*,a@jc#'BdP)SbrH¿mHd*oIKd&~"<ssyzar$+?y՘@:m|γ- )w.=]Fՙo;p*KpԜCy)?ۓIdQʹGOAU6/z&T&$i#)*li~rmV=yjXzme>>>||˷mMX[-LɩkHmdɗ(mU&@om_)>o=bG	0i	I;  @a+zR0w>R$}X%eX&mg#`#`#`#X>��@�IDATD
    dY^(楢ÉF,/s*7a; sq14b`؜H°\ nD455r'|ɠL
    0ė{EqBk傽3D~WWfxJW*{&˴=NSh,j"n(I.#n'T5;i),L&ĂAD&X:;26ȟœпAdQ2H* ,]jr;4KpL�ծS%~qYGԧFEATuL,`\ZfIEa_%Qg^4ѾOQJ;KeERp7}C[xXXT\YsK/Ns�RNrtηs"n ߑ%.J2<|4{՛_F,eo0V?C+t
    I	-eHHeҖ4_3/GȳK,WUX\\9FsvО,G^iGkޒ53䕷|(JbWaJԜ]N"h.ѢJDdFZuN9MgLxK=+QSW/oz{5iNWςKs�o$JxٞbxJ}}}UK=9o⠩<=8%X&<r(*JQ#Ϫ
    qA-y/uըJ[N#3S3k)CWfDQnlk=R
    EFւK䂫ՈʊJsRьoVgܐ2?9]Ȅ'1<78WSUZ7Cəg34uYFgުmoIY)8|UTeWyvWڼ5Q8524q7mQb9VTV0J奨J/<8RK{Mnh[Ҿ|4)/)7q'.پYl݇K&\cیο7O5fmM<6Lq8_0xT=Di m_	
    ?GNG0!ēpqFb^kxT-W=YoŦ
    U5T<ǺȄR3&]6-8"/_R80Lg	#loWϺ&H(mP$0ߊo!	+d$fL<K3VX^)쿅ύΊ#g29ks0hTyr)mxDMl
    :M}>}/G&rod{T8yZN}Xx{qҝKݕk[KtX|:)tIμ貖	Zl2isKkxLGC,
    pgXIkLײKcL;R&
    edrP<-miM&}k!$],Ajjzt}uՈݹ
    vv@(!rqfOHFÂԫ"6Dgۦ+/(Q|\3%nynBRZ<@Ņظq#bš	:v�u"~Wy	jWdP3BCՀAde߾r1f,HK1'-^Cs"$ޑMӒ?QdʵEfdg`Xzn߅,UTÇx{ #%	Iܽi?|>|;{ =qE[輚t==ݐ/<;?H&21y{q3Ad%auq-vY9y�e⬰&L$|ˇy4IYNOrH9Nru@cA|3
    LČ9weEK)zQSI≙+fb6]6")%IIH5'pX~ՀM㪫C]PO^,H4_9I&W&T2[ᫍз:
    W剅*c`:w鉞Qy7鑵;+(~vl޾iHJLBJJ
    CyUImHHX<=Pq(ޜ[.Ɲ9:`咯s O_ĸRER'dG{i۹,̳*[^_Ml]OÇԕc	HOKSyLNNe{v5T_-SƢ{f9up<&
    ON0Q7-N;	䥔GKLٷ
    }:B8CT+b*<d`Æ
    OLa>ŧ/0A,-uMYQbZ]<]w!1طN9ط'/'X]Z.UL򖼪6F1:.W7xHeI!ͺZP\p{QDf䱿7U=$puW
    T&rvDZUqL9M%5o]VU 91
    '$'$qADEwoæ;{aQJdnZ~'xX$})XՒOHDQY2rGANΜEݷ/Xgdfjڂ(jվt^^7:uFMu
    '/*/#6mER2dx滣4 (.|'%]SlT5?焺'
    3o;0` t1^/8DXK*Ǿ|;e.e; !A~R"[qAeGYuŏf=iGSh0y/w*|,*M=e!ʻ)::Z+'j#`#`#`#p,#;VEAJS=6-s]kN@]i,O;;/hOy`A+fd|"2+2Xt#R>`&Sx!ȳ7Ϲi
    J,2czrP"+2#q((2٥*Q-[6cIW%s%
    "C)ydUՊ(e|LbUCf.׃^4"/i搈tnH޻={89.gsWk'#+W9Aܹ^�Fbo8C̖-᧵5W^A喸jU̧9JPFVNL]9CcvoYn
    ?.#tSESf>X>Z6/Wd`i(n5i >1Al?0#>"@૲FW2Q+̻+e+~gs`I#ˊmV$ŹZgL=љO3&"̏ugs&:PJ)KwZ/PX4WVGJ@ʃB<Ԧ/.QʙɄ]{C%WʘN@Q<72Ņf,'{7/“~$wpTTTy@ibwh8 N
    	L?}'ʶ"L(kI&gWV"&ݍn?Rm~
    {xJ<ÔLӃ#۴T;QloR8iSW&\wt֋y?e脷=bƉ*8+
    ܥSi'[nzBME׋ɋY<̛(ܦ?<TH'};gsqG/LAoNUlI~Y&ue}ztAi_OU>Ɛ?qDW"TY\U s5XdWuyдXbߠcxE^~>CgC\뾒,?]=e%:)Wʝ}W?T~R|30:[}Iqcwch@ULDI"9h@9U}TrH=uKUkq^wK^j)+å*+^|";(jԃyIREtX5bT"h,owCϿwoOU2ɧ/K2OWp?y>}i7]pW+[걼#~:+2K?-}[ʻLM"\CcKQw\OP'ar#
    LoWޘS8y0Pdq<%RmÍw?&]A]j#F9=PK%?Jz7g/ߊE;C5LzH?-Vm""-[ǙxQYS\K~/ӆUjS-L^*llllț7XuJS ;Ok6#P|Qe6BPAf~M\_n\
    @='YG];z>]NW\=ы+!&)O8]54CR90(+B}ON'_Wt
    D`c\2牬44yb�?a늸}+@><0|{t\ʰk&fg?Cш ф|݋lQ=zhC9ػ�%"ȡ(." &嗗KW.RWߎ~8U6p%
    	ao%_ѫ_x#t*rN]!LAop�8vE`*(.C̀եص7u.jeaՒJ9|4\z)cnf2-_EK)/}qAn=0)4#FD<W23?WH]~+WqBgGbM5HT6pӍwwd&GrV>xB;j&_օ!bd&]
    ~wvYqyftƯ[cx/\xh=tڑ'#Sfqy%
    XG<j{dT&bj1}X;D酬xeERtC#Fq^5*<+j{b_TJB'f�Dz?~}
    ?c"|]Qݵ	Y4wn^
    Si];�6�?!eJ5'@P(ӗA+J~"
    ѧWaQV7TEiQbc;##+(.?Nѷw߀X$#2*
    T2jڽO";i9dp~X9pԧ0p<t
    *_0P`bPU-FnI
    -	X+K.,j,<1h0tat`{Wec0.]Ҡb  &v~`(Ht#`k:'{=<~;c5QPxq2ډd٧S.pXRˠ%|Up1>̓@(+VIM!c
    
    DenFif[lWc[I
    »=Fds9>t<4j#XrUF*%O_ٍ}YxaKnyJgx<VFq(W rjk~ly8#.5~n-Rѣ8Kqto@ A=TTp44Εu錄pFZcM}
    T Sy48>?r'BDtcMNR6;؆/?=C(ͬB2^><b\WAGI'ggJLEs)9�uJ۬a'M7hӑP}D1(tf^bUaߎH@]jBG5IJTcY`|Pm
    wy=:ܴ]7G^|(\+GCr7R n}4"=92iѤMOcwu]y
    a
    QO6d)&jpJc"NN!s]n
    $dt07E-G?t/N@ul\3f[WnGA\Wa05VGJU_;AlWqQgo"kukѰ>p)O8՝8lpDuh8&Aͻj41L3mC۹5ܫʦgȓ8s\T9cP=:,I{ׯCPm.Q:7k4_8vxN'\WoqB2|j^?25rsH
    ny|ɣd]&(dc6
    (�+wuCBBe˖T3e<sP_gSyQ=PW>m<q's݌i=یGvSzJ㍧SC2B0`zoOi|G^p׌GŒ{'ݫum1Ogu?]K|yE:Sf\1{c'/LPi=ܯH{c5l]kL6FVA?4;nuVQ&
    Mc}XwƠ[
    =g,XfGD{!=VdcwS9l1m7ƲρC۷w^1OgL2Ii'
    +wmu
    ƲE3<yش}F.06_N-il|-&_XzseqHq`V㵧Pq:lU}ic랃ƨ>Ի=wkc>yO?ܨuG_~⫟5&?9J=={P㛏_SeטdqDG]oq>Ν;k2N>e,�c]FTYyPoף6/UM1
    54ӨmE;BVto_	_z8x줱mFO&גiZ b8CoMk"KmF,3N͒Ʊ/Qp}9ck+W{wo4Fu1ݻW3e{1nx{ˍ<~z~},ɓƲ3械aW_g#dbWWT6P-e~.cFĩјЧeFXW>T('X53Ro<cc{76,Ό6cUYm!
    Է6g<sW"o#GQvo=gӡWcH*}яw0n[o<<o`;iǮ
    KuFMx<|,TG=ٵ8vr
    cɓMT\_㓙41V._nlj=jͷh״Wcd17Mx0csQ{-k0Z1m`<1cL8z4Rlz'muc6y;~70Vz؍Oa9iX[`#Gc]pm{67n_CⳝgC?c'5lÌ>][4c&M1>flZcrwmjA.d[
    3f~riF>xb㞞{
    -s8eoQ88^cӞX62;aa9e3fpLOf?<eKn1bQØ9w4(o57ɘFj\_9v3̚jԲԫ86{5–5?{CEq*7p
    8mݻXf
    O?_�cF̹^R8Ř~;qnhߌ_뚍Ə3>VejM|cՊ=7w*6(;vTyƍ7WG1^}̜Ss^o'i݌dtacw_m<a(6ck:-Wtvz2~|.gtԷ'X\τ7<`4zo{McǾCjZuYHȆFlQKn4PH.	=K:JB.^.QOu8;w߷Rg.wXjvyAk쓈9_|¸X&>|7|F/w5?eѴC7Tuį+r3݋>:}GcCQ.'	bٷAB<5'ӞBż`exw0wY<.NeJ@M;7υaik1[dDTAr~YqٛߢoT	o4j]{9AC/ݲK }Cjf++5Ttp�?S?)G[}vkwm8l:gG
     =)]ͼIJ.MGw8Usy6ƴ:NSj!lYZB>NZ%`P
    ҩ;m[7}R`~8|;va#Fg䏾_;|^2
    .n/3?ĐLyk-PNxR!.=]q!>~%GBSJcuFyyP,>9Y=l
    Ofc;*SР<} d'E'_E[1ꎁƁhʡeCF:mاgS:]A
    /;']L)KCat\_DUT	4[o:_,߅;�ڪ^UO5Zd)da4I4ȠDvw/
    ,ym*܁T-aO=-BA؏7&v
    35?N{@=w8سLU7my=mCLC߇;_y3
    S{We1@95|Qm恮xmq]2JWWOӋaQ7ՂNU^+}*<CD\@X	*f9YWQJY!+!O<~Y;G{3`a(8X4w*neWûhL}j21kغ%xkfߗfC'm͹7Sǧɭ5!M}T54GVe((LzpPH{?h}�ߚβ* *տwة4L$A>*6LԂYݳ3mD9Fjw?>2	-@N}-0GF4az͒KgPWm'WfGv\eYBPisp&�#1=#?&W|l`/SJ�V=?@%)Sr+ëh;m8\*xm|tƏh}}2t5]7>|~Zϝ,lY?y?Įe:sEEv
    hPoo&=pi~?N{[-`ϱx,4dk*ݣލ1f$ӧJY=,
    ERZF:89r,
    2YX6ٙX=:6sϡoFk_x_/ߌ7
    Ō^gAٮ\i
    \7[K/n	EԅDusҹ!1{i;≗Ō% uG|h<8\cƹXxb ?m
    I	8r`?"lپEQo]n>}[Tp+پ#Aϖ_crﮨぜ˱t|P<'h5_v‘SϑR114sowt6\`jbќw0}lֺ=>yLztFm)NBZY)pNĻd^<2j,FSChΰG>D~\~etkGI~Szr`6
    (o
    D	кS/f;h7ˑ[բQ::ydrr6*b(`#drWc{qg7sz1	4pb:�4lގ&{*oӣMh\tJ(rs
    XsМ2	Ѧ];M@�:tꄶBfzajc?7mi.110"fgT=` ֱIZ?:}QCŕIRY	JXԐ@8<e͢dQܱu.۽;Ǒݴ=1CCd=}[TSl:>PۿGO:0x%?wzpdL%MKcaFC@Q7~]EAS}pGcK�vڋ=BpT<m\~3,Dy2;+d}*<]Le[YѴI]!>i;gg԰Cloٔj>N0)T/=)	`n4ZjO.-逄&Ѯm;\s69hLn1bq'7YWZ[LQ$N0 ?Ov̗AzrM9TbA298x0jD<+g2MSzG3CAONLQ6b*A6."*TtVnu=MMNUjjQ]i߾U0Uq)3T/-θvBTX4C0e.Af0[F}-[4CP`$O`͎
    TM#d.ؿu1UoistE,=mbTQa!xvcn�'*qb})i'U')ԅ0.%aIhܴڷi#܄ٻ:t耔,M*~;{&
    z[z~x:(Q-~'5x(Wg_:t. Uxjy,O
    r|\ǣ/ӉT5:px&4	YMLB.rb m\T%8M 4}Fܦ-,9i}ԝĦdzTW8Gs	ڶ)STݗ_FEFc#IgK;yGK	8wJ+>R&6cׁPi*?NXM:ua.ztNU\Q~Tr¶gջWqQc.h6Z}nUW8p]:vD{2Q>}:}:ȆjoZy7h?6쟳
    4rt?Qs$jTˮÍD;ۖӿ_#l'z{Y˶p!u" f\ڴ:4:Opb?ć&nSgA?yrDŮM#Mdd\�v&qc~ҒY\n֫_tyoChٺ
    jW-{�[N;$#%1U0Z#(0�[HZ#͚R{qleKSs!'&oG>ڍ345#t<8;H'43phf 9"㪄*5j*s&*eykTlM}qVŠsY4jg
    nI`}vd4}c@O8_Ʊ]ѧkgo'/ǃ�Mh*VyUJt[Ϋ:1:޳s{{nzR>u횕8vb4C_KhJ!r1|9n"lQF7Lnh/fjxpu2]n2E7gƝxW1tDm߶a_t), s)=0HURMɍ[UƸp0Q';f0'fݭK{ڂ9⮻C,rEJ.�.'3g9gځ)	&$0!C1Jsj1g.-][R$P@oUUtS
    )^AY4m۝3У#3=uө
    d49s\o	b	/s׋6~9vBGNS)m$.NRKjiאw(Tˏ6ήv~%f}3iKY(4@F Qд}OvCv
    f|eێ#v,vA0	:{{քwJdgj*~B	ؘ9K(k9un"PG~,u<ZA~ZJ*a.?$ms'Rm. %%s,9s8@'-J' NRh6|m2ð_U}j%G2mb~d0/9evNJO­dE*j@6B3\ؗoJMS~>b0mй)
    v|wƌO_[L{QnlpSC4-MU
    y4~}n-%1w:,x�?>ܼʠIl%
    "CQŴSun:J�K$ta_ڈ}-
    Vո	% )ɜʦr[iDW&:`B.ݺ¹RY9nJgM&UEUMHբ%"yPdJlH!s,A65U ::"S@FѪ~�NT}#iJޞ¢1xqG=^=/XfM%]Nf`ɥ!UlX;7mG`ަϱr?D4WNrAQq㑕kЮ~JIꑺQ8˫?E|^v'z5sf}(E;pv<wM0jyǯ51xԙܴ*S#vɳ8" 92dPo	`A^<01){9^FqX(vl2F?cp0IZeCq \:k2Gae)
    xFvsPhNs$m4fY%iGH9z6 TP2m̉2Jp&¶, rLj3We^h=^w;\+W6KUԢ/'$Psm{w}/9ZQyͼU
    $kK?1IP:^V̺$U>J<)#'!H~R3\Dn!nDu;ܦm7!IˡA+>{Xr%%OORÍ)=	nӉǖcK6U*폍6
    (`7L>g]NBe�)r8QeSzlҸ!U$Q UO)psѐ!u7h]RF&ΝN'+ZT;\GO*#R"ED '`0FISY
    Xx<*J0/1% oǒHFh	(G_�zęLyt*Ҙa<"SmW܁]pA~xd# =P_ZaNVyT|{"Y&=ΆeP:YRˉ-)	.=9aC&t|6,s=@O)=CN7	,ёֳ#Uxc�n.*!8%s.qߨj]CF4|yeDX$NE]ХkWWŴ+H'^$)5i:uFu_$5g^h<wl:~jHhIɲj%Ϲeo2TpQ32x<SmtH1TGܲ~%*S%UϏ \ajfwC!wS3X3NsܙѶ%¹Kf{JIe"٦N#'V2z\t&8 }RjhՔad)'^Yϑ'(b4/Lթ|jO=YE4a.<e<0׉;ņEx.xTNք2!M<*p!\je2sC>y$Fn6ĎeǐoO'TU&'Bvَ5%@9r4Ɗ"�͐!^ݪ?AYWq#,_=w2_*jGJ?v(]19
    hD&saIm>3Kqep᱕N">7w	mJR<r~]48d(A5+qHSYK<sH'd%43:e]NPjc\ݾMb٤sFv7.Q^z>j&4o;jC@s3r<N`nP8z=豜LPjܐYBb9:]a5V9,(20C3
    ho8tnrOq2n8U6tIṴ̈̀E"2>L'|E'aPogn2R&gȱv(GKq7.jҪ]Wuqi:BX=ɑ|Fٙ"9HSQmFNNgb'Cͤf-۠]xWsLi#O?VA0~a6ʻq/ʷ<a+TCæ8_MOoJeq1:}㤧JgI6r"[itj)Ttql۳UwX=hqë&.2pOܰdے~*(1ճv(rki9Qen5L2WFG ^ե�1C/Uhȳ7+܊Y!g_y	n<Zh3{*==رp+֠󠨸<y~	bպ!!|: Npu6GSV_R5yE_S0<j'
    πWMŴQFlQMnTz.!'7Y<.GІ*$ԧ7wO#FP
    ΜRiE7b4�jFy`p'?L/__d=m34h<3gf[LVP*Ը5ygxd0MaAnT7Cb:w9)K0Y1>'N=ײʷ63}w 
    Wx6~Ƭ8:cϞl(K"UܙxgB6l_21vD~Щmc.fea^gӚ!÷V3|?Vyn<G<\\b~ߞ's)ݼDc*Nu<}aEF_ʃW@=8[Jb}Ћ/m:;�S,X1(iԻ)|_iW?`_^xkgU2a]kL2N.ا=SWƅLn}2T{vJ73r	Ž^+&iHF,%6k^1%xeͅ*U~+<]-Ћc.0'9cF݅VjKR6ɍ>[s^֨Co0lHl.L$pfi1rۂeONOިqC$~fZ*VsÀO"*-;?׵Q4;*,Lz%8-bOz[blY3/A}G3v,+3˗O{|	T8Q%]a7f~4?jcwlأ^ӖTjk:ގFubui2aڻ?XLl(u}gcaЋLzZP37z0CMFB3Y0Tc<⎊h'ŀy7UԔ鄧f\}soҫ/)fn
    ޞ;)퇦Ă'
    xcpXg޻A}FO$le[1K4Sad
    ŝw0ԪS \R6Kd@fQnxx>2?aZ&&,w?0_,$	E6ipm|LlX8S}W:myͳZ��@�IDAThóسӧjOM2j$A݆aO)8/[KA'غWqOxxὯ0nsqH_{PiᲢ"/;B> AeS*GhǠ!?Zޔ$C2$$ގ?Nf֮C'R_㓟'MAX8~`νrBUѴEk|ձ	#AayTwDKwU?6%V*7y}nWZ?7l޷7".6D"\<'frPFM0T+4'@2Ga&PKh%G7ʙ2*Y6r1xUǺ$	7vO_~5Ǝڵ .\Kds"iO�xg߸?ЎDGiSRw^$QFܰ;'ٰq8`7u*+>rArJF6܃SO":c&$ݧ1cUD:Eqp+k\m^K)M,%uQivk6
    (/')sud)<jdÆ
     fg"Kpfn58ygsgAW�䨝KIq
    =,.޼)G
    KvdTγs+'WJQF`ǂ,JXbt>+)KHA~zR"O<JΜšG~F"x=S7Ǔe!)dґ_@|Ҙs<+]?9Y./P-~){&j{#eEtN%@̅jqDdj~T$ӖGpqhGG`N]Q"Jn/^H	;*)NjEQ*%I-ґRT	YND
    OpT\LF^P]4%I)=K<fp.<֫nZ<(<̑:<^4JƯvmE#ן|>QT/tT,&Rp	WT^9D>J9Oâ
    .j~ȽȈH$<=yz!xdJ*j?{wFBĔ˪MPH	]9dAXxGM!EŜC46cc٤-p>~P)TRJEEG!%[yʖ@i;\x<-IBMt䡤rLNJjmjy]MڨB5wFǣbuJ;3(ʾt%dkX1ڌfY$gSzKǚHa -y̚QUvڿrKibL|/tdvytvWYE]@Puٙl;9䮂.qQÍj<0~'N#Ǭsg%+1A-KtW:CL')%_#gXir<Hc.$rq.3!gJ,EA.6Й_�T#c+c8;w6hwRe9xxW,aPfYve6\Qᜋj$;tC骄tڢbK"IFןG("je͠&=I#1-eQV*VɣytO
    3l{9U\yc %8˾$jժN"#ΒrdF$#NiOax`zOooTpĥz1gqcr8,x8ы<ĉ<2lW^<265xTɆV<XjUhOkU@g*Ej|@dxX.?qɡ"~܀/i'dfw
    Il|]dݜWh (>>6%GqnT>sV-#`uWƚpB
    Jlv՗>>1c!i$<5s^8KGRӛQCgye 7:7*PJl+nq7m2}gkq΢}tGmubc1]Ƙx)"ٜ_#I	뮤ep<2ٳt	wjxs-eH<އzJ9w})NdrtNŲWcF79R5:>y-r̚Fe2%3qK<V^
    pRދ֩Y&}qT4oqv5*f"WmJگwX86j:So
    
    wjP>g"THZxWY*L
    HD%Ù&zlѓ8Ogbb=5=(kLjDqrܙk5$>!4d.ܢ9&DO-Jƫ,i<gv/ƝGJ�~Kmi\[SbN8Or蓂k|1cnm&lmQF..]9aڙx_,DMve)|adŮL6&6p\lXI%bT|;NJU0-R02VHDB,.+%C&6]va?jLDy,DR.b'.##>* -7jzNG`GJ"((
    b,/JCE:+u"YW$6lhYЛDS<D%Ulʔ2(ă7@JvZ },抓<]GGw %ҜjTGLRM{rK9ԏod$=(I]I;EhY-4z1K7*{d;7ہėuaU;ZcJ`t[0=sA6IZ5zt'Bsi:H٤R]R.%n	VK\n=
    vX^Aڶ/U+XڰG<;AB)a<KRF}/<H!ϫ=	3/゙>l
    ԧGEڟ?WşevO".yK9ĮT{2򂳘r)$_T"Z_INT;4.՟Y~]0/>1ߥ=șԲa c'_y^DeWEO dlB:KVHSH~21H-ܳcB/HeScUw5M9v,.RN;Kzb!mzY[3i$>H#⩃cM'#t_6'ェԱ1v~eF!sIG/�D[Uhe1[b+͆|M4<9U9LƫR{Ѹ$Rfު{K1G�7d	mGԿEso8`,t8@9pnE @,z.}W2S&Y̳xNyVJ=2%տe7g.JJ?~.uFuH+K;cG</ 05U_Lj{%1Z2J[|9ۍ"4Vx)uqerhi[68r~
    1S*.28z5cSszszQ;Us˖e
    /
    ֽ"Ѵt]mQF..@zYdyмND/'Z2Qɭz"NIF?[Ǒ&AEu8Q$,t\9ʽ\W2K:bdf&(z_,ebzQF
    :)󐒘x^S4fzY=KyWᨿsA;BOCjTd,- ?&-
    fN;K,M܈b+'/$UEnw~I)0@ǩ)&Tۂ±|u*p$"؄gWkQ%uZ!lTT×*w\,H	:OGI%4Q)UZ)f$m*;KBgKK<,AQْ^+/Yƥ+fƔǂ,01DQ0d,t-Y6p8t`,yrohL'!|&M,i0:A`Ky/\d**W~	:+'LK(nWK>kKCÖ=k8E$|Exo59#\u
    ҂SQ:HTYt9s4,L{\D+aF{t&ݻv@EM*[M'#a/c^"$Qhg(	b8SLdg$,.yM?6ӄ5"Lr&5$yo37Wֱi)N=V~N:+Ye&ߊ1QiTY%?3y*ͱ-_uK+Os7K%KAMӧ]näijlQFdAF$2ɤSe)pJƱ~Ls#Woji$WS{Is#%miqe'ed%+i1^,̄)?"Yh<;
    |D+XbiǕܞv\DQZ@Y.nꊋe,=S_1~cRB	J&<i"zK@kr%,ndi_Z7]ʅc1$WXڙo̫k]?ϗEΒy]	8oftWO2N)ɡH-J^fw?K<կ׎{At|7 8H[yJ:keqt4}iyN:7*	ZEmC5ʫaÉ5Uu^׻^
    h	)=Za_כKWU*^g:^,ˍ_Z*O/NSj*}U6S212K.5cibo?,zG]UKPͽ8w	yZ\e*&*폍6
    (`?deRHWJɤ a`dY!Dd㔼4_&{-z\4߅Ю$|y
    ފAE.Se,=J;iXelO
    CUUCoD*W8%iK9>k=Zÿ^\<tiRF{=|4쥏˴J{pFRFΫWO145K{Sh*j"	h<.X/<
    ̘N])ԏ[?#Xc
    O sRZ}Go
    4:i4W~8,seN(`6
    (
    3^^^ib'-̣L2"07M%\e\ĢBNae!$N{,/jGkRk/gpoDhKGK\0t
    #qum,_^@Oۿ<%R_"lH]qe|)mqP3e.d1B#=Zz=ٟ8KQnƿt_o(9[+#mOΥ#Vp
    Zi2Ch~T%HH}<'L
    ]s"cYp{q0)/mzF[oml6mQFCk2(ܹ36lX2IWJֳķN7fqo"
    'q2yV5-坎g}-G[UEIb5ǒyYWGW^dm~-x%a,V,esD~hĺaL[7]׻^+u~pJU{!q%wr_ZZ8%7	*`)~4XM#Y+M7zuz}/-u\}|5kxt
    |$mix2>7j5.j?	5W+SZYKg٨E1<|=$[Va0G]aw,Bg_]+MW_{Mk[iq5^:r]ދlQF&.,�e
    .6+	-Вi/X	 sr/7&mXFra2eSBXgd`6
    (`N
    \w%+j_dRwu(%̾
    M/އ/b2dK"^0l~_QJ_ߤO
    ݍ@B_Y,4PeZUFqJ+SG[?+7E,:OWźC-啠gw*.xkgKjMNN_|2FYW_%Ӗ|W_k}qt9YHL\jWkX_?`DY!xe7۴jz^EHEnJ$2VD%?畘?I"W	73n\
    ^Y
    s3upS\|ŹlQFi.'/􄠯7RXs^ڴ}%ŒI37'R&&+s1J%ϚβHwQ`M[2mvfFwmgʔ.-/iwR&/1	p4f1mעViU/X!c&A~V\
    r%|0Z~Wߤ͊Ӽ
    kw7WZlxzd}n6_K|H`J[͍%c|$Bg$и\ƟԘ{Śj6p#KEQn-6
    (`?e{f=ide"7e˗CRU
    \NMARjrQ3$#'`OW*Sɑ7:Jwr)\z q̸*&cv%$e¥FM0GGfvʖ+ga^ByWʎoG-n$S)(SI;Uk5\*N88jøD(t4]$kZoecPX"j6l0oU$WR?*HUY&Yc+TeՑx\Hpq{
    %!|<*WsP;nu}EFVN*T
    کVt.Xl8r<Ll6	I)k
    ΉbanAm=^q՚Ss՘ȑUe#itt1
    $\FlB*Oxxs/:ׄ'ռ&mP,JMN@nq4EG7wX*WK&R_(vd|PL#nrb9\і󤦨4%uE6
    (`G
    spu)K'Gsp6$U<Qb׺y<A|ض'2S\nz~GƘ*fDjGjعge=LTa!4<N=:D.6&.v3O_'~<8E9Y3>={A;+W䟜\_=EnX^n_><QĹsU+`z!+E|'x7>o\1_5E}P@?9
    \INćcsbC+0܏l_'܋	M؁xI8qҹw#%v+goO=FKo~3*kl7G&2&?}OywOtf;_-Z[!嶳]Ф̟<`ss/'aǶmxIBV=.d.`qX UxQx7nn8NO�fio_T!2Te)DZ-}5?_Ujna*#+|*V8fܠy|OJ&Rbsً*Oխ ~qt'`ƛ7rv,Y9$t`)T{5[ŰQFlD[ $$V^F"MyGԏBe!I`p<uwyz Wݛ#r%gADX|-ĩ=! b9)x'oNvV;űLe#Dt̠*{y_XB"Fyc2P4C(1o,IQE Z4"Ş”FמEzf	ف?zLyU%.z*3sAzvzc+v+d"u$^]ǾC`w1m..IJ-LMk\$\KL9#^!E2!so5#8ZCz4ڟEzX'<:v*P.ALkԗT_ >o:ݷ'1v#ƿ	b/q@a nA.-(uA
    %cRfr4ޞtgonhqA(En	\2}Ӛ-1R%\?u(fݞ򷘨2*8IdX0o6juBG_,%Ǝ-s3>KMzy͜Ldz`1[ΠI@H]1bw+E4=L�)6)~[]qO`e0=�V$H9&|]W'bk6
    (`�)p]tL.{7-k!98V0|e*P3Ҩn	ݱ\Ԫ후s_J^J\IE:i@5_gðjuSҩ6Ym;@!P#`HG-ЯOwԨ"t~t?Z8UEFA8Vv!sP$Twɝ}KV8!s)C$ro,AJ鵢םkERg0r`7S6(XIƞ;ՔGx% Cq)W@ȲĄSP#p)߉Rhް2(ȹaPڣyn٩
    R}ޱ2FMxߵlcO@vrAf]SXZ$"ruumi;صWmވ@wmQ?1kӻxzJ7lۺk.Tj⍐u!hٶ=M7
    ,]/MKi;?_izٽM:7i~xFº2Fܪh$bʅً،?K`cIU5Mn2ut9;G_4;U,['GY6l(jźQѻ1quUqGţX}W/ƙ5в]g({aRY*fhV
    +~)Ygwzvk'
    Y_gcmH¶-Q+݈֯6}|Kɰe8v�!"%#|ѵ[7QfML'x/eb϶Mh9`YVz2oڀas(ۣS`TrrDAf6[&=2~v#
    "կA1ẁ*neh~ Nub;s0sS&9,֬^\pE\?
    q:tm؆TnW=Il&XE
    폍6
    (`g
    \tQst~o݌mL|~yӆM&LuI377<q,:wONsŽ(6% NVJ2ѦM+&cd1ɨ>c*ݸ5^EK+v#PEHeGϒK]d&"d<0|�jT471p'$=%⡱#1ɏ^l!0=�Fp-.`#[62TtvCh5UD+Bi&^rӢ{tmޯW:ѱزz'&nUu RVGŬsq`kzE40ρoZa#N)J]g|l<RitGañ[mhLŸsѮ57Tu@m
    [LKxxJҽu9.t
    A3UKan%n&lt^|Ě۶Sl}5x}x4Em-H4'ܻ?iUFm\J'gobǾHHHDjZ2U^C4$#9j*Eg-Nm/">+b㓐-Ǽ5Րq&4hq}!bP37uv[paav*z.~]tܩP:]v-Bn4[Q/G1+z[,1
    瓩K
    GRt<=25$+ 1<2Re&=[v+ořlQF%yyYHzծ3hЇ2�2f|jTR6nzde,ؗ\pW^خYsQCہLgZ9|v,wi_W:)Œfۣ3r}i0}
    {,BЄ70QM|ӮW)Z3ҟn*YV Ap/IvB$",~fǠZE)Į 
    ˣM<KCvaT+wT^M9L^O!qgfL;SYѷs#17QgF@'Ww5-:oLsr1o9zvl	g'W@Æ-qto.Ak7 up+7~TU#q(R>|<-4FTbuzr9g^[˰1ܥW8nG|Y &jϿºoH}:KOը#]T
    H'{
    -v~?%˫O~Ӕ
    rt
    G{f`CF5+=7ӒnMk
    1⑗/mK@&D&F8xrzcUh}KۥʤT;c5W7v|
    ǧ�-qΔ0a$P%xqwZw{v;CASq6Ti1w$Xmw:3
    xǸG n
    $1`y-לdΣ	'CcQϧCwa‹Sp$4	PE*"܌#U=y-W%і~$J]fo_wm#ρ%v6MĎ#oE}_IM#_."vhY{FjR~(FlQn.)|$]/{wjF3j|{WѴ@BNw݅׿5ڏ{qw	Dϳnr	In!ݭ޵)G/2F̳"ÕՔ{iMRE4ϫq4teݔo;ж}W\|ۍiH߸z-Dw7n݁sO8b|*zyYxMPM	FdDL4£TYPc׮t:<s9.)DFDwZ5t%Y+mz"jpd:}X*G1{G2ܱ0E)tq߸
    @GJY˷e@c^&PhH
    >~ŅEƍzcsy۸rq]<YCwHk	Z!!jak!%vE/R.#`=1amЗ3ԬpG,j_WlZK7OEZ/q탍M8ɻˆhݶ5tT]kwߢgYwcPcx.e:DЂx>L <aӮ<~Rw#eGN1poA YL3h։s�HM?I
    <ѥjBusy%Fo<y"f):c2~P+[&^.q0R*:j+Sm|_K;gCۨ\thW^{2z=!E
    +=
    x(QAk:rgup
    +qLhD9^sUYǚ+ctMS.ǂ/(b?AѸ+v:?D*H9(DttwoAT^":s${ /d?,Z||KЎMq$�~B<oȠt'}d>LK-y96!;0�E"={hyUX{zs9}Q_ƑB�axqS,e)+b*?)Sjϰ"y~]B4Mq1ݬ%NTHޒ"Wl+\ħzey)i6 @Ȫ1n.(o…8P][xsp2zwp\ej:
    *Fff6"*0;bzf2
    |	5b1u|:ffMeHX3Țc>?z~[ib}/!Bqb+X!/$o]~9D`q&	9	0?5.Elh!vs[B< y"Z<rL:yZs6BnGf
    Y.?YKS�Ǝۿ.E}*csW#f)h&h!qӦ-<KW7#3go()/Nk?y;Y2ӷ`f\4+0/%ۤ
    N8t\|x_Y	-67Crߛl,^|YZX1.zI(8
    Bơ@v7^^GD#yrB5po¯_Ouo$˟Lz7?FZܜ,fSA)dn[C�qժ]7`9ΫW[ljcXoFEUC,!bj;χt:&L-V9;|xm<SN^Ɗp଻^Br8H6Ϥ	L}{A{lh̨epv�5i/_Sf0/:<�5-䇀v^ӘC!a߂ؤ)&}6FNpKhh{l9hv6Ee+enfb/_ⷂD$K䀆W,<qnUG YӖ
    NJU+#8^,?"l֤!8ڵ%f(2k*6A$q>FFF=^7O붚|fMĩs<í̸Ǯ-~90{D6f
    rQ	V}>
    Y\P޶q
    &L;c)گjU"=Q{ٝ#m'7ŸUS*iZ	)kV`4Sӡ:sy^s]Uz<
    x(?F|0۬I_NO5]y?;z:6Ot,\Vĝc<1_"=,Ə[o	I1EuI{*vv;O>qíwb
    'bN댘ףS*|{t|xHJ߈ߌmzs{`wgg_.X23$&P>]V0FU.wzqݡJ~ڧЩU]45sv٬�V=мCOz兩�#ݦXx<^,S"''chH8WC/~77ҧߣ	wh>uݼ琭)9HWCK
    G[vÔ~M)c.G8||S]WL.nG9r
    -wKT!}o8pͩo~Fx9=`3/[o#
    F=)|Bxn	wO>1cvgCРFeӐ<5p+wj]W^u7n4|T<p݈EH;ϻ]N�ZU#0[5k'FyA9S/
    wͺ_}z6O>
    ]92&q5 }?Z�hnӓH
    <W{NOBgc
    y9>@I^xMSʇ_6N|6*w<ӗ@Mwݝh[)s6iG<
    x\HX Eq->kFƍKD.YF$4jPl=5x|?qo>tIQ\@WtĮVY˗c݆ܝ
    C$ Qoӆ[׬,w`ŀȘ*]Vmb%GqfG!66a|;	|݌:g	4THeҕ E}Yf
    իgDTpI;BO&cюo�/;͛QjqR&~HöO3R]+p
    E)ʎoz6~>`6my8~Jwp&,[n:j":IuK,7
    "Ubg9Kk}jƍhР1,_ C^܍֍̮YzV.b@RDDKC)QUP;@z#ۇޅ"!!|@QE¸Z(yxqeUY&*E�l
    ȫ+--_M6DN僂mK⒒x*m'ߓ/_MGĆjSLJލYmWMiXbҲ
    P/>"󑖙Gτ:ܲ/YRQv]FE$*:ረO^K.;nڄ\P$ f#kJh1qEE,Zu5oO24|M+.'_!T2'']56SH[~_CkncvZ8ͷ$mdZz+׮\57Q	A5Pf
    dcL3k^:Q"=
    WTDlŔ=ǀQG@WܻVS3{2)ι~x*lՖonS	Iޞ&,|Yq.)<=j4,Zώg@7/G7n۶|U6~.y|z6*~$j:._ZT>nR:hSs^0ucߏ|L0K8'AjǛ]J5zJû>Gjp㚒bU}_�1syˋG{fagcbc
    P^ʋ?ƚW&m۷o7.UΘlHlg,C7+UBy(Bg#LyS47S<Bzkm[QJ,]wu	yw4\2{6۝‼]x'"ׯ-
    .sN+©(c񍅓ʗi`_^\ڹ0lH)](^^54<
    gw;IbߚqN~R̤bjLlh<cGԆ&rñNJG^̦^cU7$p5Q84=!2&��@�IDAT͓jZTLi8;,X:[*Aʷ5'lbXv|DO-Q9bb4rAznaFذ
    /+N>M=N&A1q}H
    6ɡ 9nEŸK=+ǀm�|Fw)@?ԨypNiOnPH?t>U_jtk[:ǬU
    E:H;Oſ.ǎG|y!bC'?JMsj^7u~۶T|R^3}Ϻm^
    w5ɜ7lP}և/~(Rf,k..YﴱD~qUYKē� zf*/Zc^SQG$*A1bbxL6XEZF*UUyDJq\9y73чDFWsG.̢Σi~ӑ2.C
    u,\sq?Ty(Q@;]bRz+߬
    (ky_mεxU}ɒ巳,*k<^\[i%mj];7oZliD]箋iQSޝgonN(̾)	yW^6Y
    l9&xqr+Ij۶٥8>(mϻucc*i^`geĉ_9:a9;we|{^m+>U{5jd~`۫<
    qQ\4Oi{6*?fḟ{nSK-±Wp߻ݻk(/Oxm-wӽ<,X,n;F0:;ͩqzg%%IeSQ&c1sQQ[oL3g7oXW1llʛ&*Q4Ѕepqc\Yَ#�
    ߍH_-뎴emŻ(QGPˈJi'C[$u(<X-<g_j싔~~ioyip`/
    lvWv^^ƍ}(y`_‘;a)=/m9RxӴiS!<D=W{z(Q{e5Neyqh=|+Dx};G/Uێz}xҫͣG@?\xx(QG<
    x(QGU
    TxhY_<
    x(QG(E/ΣG>*4=w<
    x(QG<
    x86(a'K<
    x(QG<
    xS35ϣG<
    x(QG
    xO<
    x(QG<
    x(/g;kG<
    x(QG<
    c<,=
    x(QG<
    x(Q_N@w<<
    x(QG<
    x86(F?yXz(QG<
    x(Q/`y<
    x(QG<
    x(plP "4
    
    PXX??5``a[YˊZX[(-gU{c_a˸U^A*}s+;U:vsS:m_UEl(͍kJsߛW]tZY{)ʺ˙Be2Yn-+"啩p¡tܾyՍ81]Olsq6]ӽٍc˹TF9Ożjm~]{wY³pfl^{i|6³Ϻ*\>ga}ou-/X.ݗ
    CYzܸwoX+gpӽlg]kYi:OA:mS:ަ/]Fi^s*/;myouem\՝²84|eټؼ.Nca˂|;N
    SɵoiX;m콭ǝ}_;M6W\׵|pmZM/gm-oK_-\ۼ+ޖ-]W+}oZ^Kǹ콮
    eyʃS:]ʊ՝jgn\:͝Ǧ?r~D6g<
    x(QG<
    x(Q2l~;wFVVǫˣ@Y8|F ??hDm8	w뉴ABɱjdx�ߣAm:=RAđ:~eXA$ۧrHU6]LtU8tc
    Xܤ0~05AYi٘5kTRdڴCXy)O-1qy[[?\Oߟr"pZ0j(ޝVÝ&$rrr_DDAhP 
    "'04yeff"<<ӝf*:?6]*{orҤҰD#աɤo–)
    _6[^W>wYUtŕ-.g)}gʋ/4VVYw\y*oc_kuU(]OY&#l}-yh=x¶WkK÷.cN/]>##t8);^nX],^/]"S^[֖ss+^p6ʻ˓#gCi6^-<uڴz}Epl{Bi9%˺ӂt7<t]JƗfk>S	Z6Ml~woi4{_|woOh˻>ww׽-ou8*guem>O";;HθR[,wq	fi8]ş«9p~v+BY9)ſ2]8'[uJQޖ/}gl{gOigeʧ~IMME˖-ѥKU,wCy,--
    HJJ2N=
    n
    #]ׯT&kbŊh֬!WYpXOtR?Kq<y2:uHv!O%CCĉѾ}{~=^4͌3Pre4h(!})鈋CÆ
    !ϭc(OʋѨQ#IA<㑜xxp0aڵkgxpIm]Nأn^4i$tcǪ7Qy`rsiΝ
    S?{a( ٬<bf�k.2*
    ёKXFMpBӖ(3O)n9[G.E
    7on1w.^>B]&-)~4QHR@ʊ]	J*vg)s5XIC
    S~_)7Vr֭[jժf7DM6VZk\5mԡqEC2O񗲢a?dp>mm͚59T
    ّ]+ZjeCD#miHD}8$ORļfƅdvJ_}Xy-̼!cztN
    a2ĤX,<z6c-ްđ\.76 G̩	-(vt8GEHtyG2ThkKzŊ"宬8R
    |U_V=6Nem;qn6]qEy3j-Zgxy@.ހ	_	0M
    W(-lYqk˔?0Jճk~.j"Qw,X/x,bN^pw[Uq5]gvҴyޖtIظp5,۪?:K_m$0Ddai6j-ݮϢp<nn^QރAu즓[FjX~أ{.U{T<>:Y-#wZ^+ӝ߯ΥCyK/`˸qDƛ"Ks˓DS]n)Ly|vTV^w5-w(cS2ѳp4_nj֟xBW'Jܗʑ=K,(BY~r6^6c]g[Wyl]EĢx.+-V^OS2VDd@bb"w$[~“`@??
    b8SPފd*G41+ySNvW^mSv,,, ٳ
    Τ2n^4qםŨm}jWVT78ݟzAyHKX'Zq&"WjV">4QyO-&V݋vGY3NW`80i54E/G4cDm@\Th
    ⥫)hdS|V;,NWŶIyl/i·<iqWі]pH`qdmwdhȴxTi #3ά[SҾ=	7O4NVN`bI+S?=ea<S(O>g&p3Ѽ.4(3LND3
    }nE$0}49=Qb*<F~D9Q{1[^-~,MM^[h^([Q>/+Zi%s^4.
    8[<:tX;c{1lwxwBM!pԽDS]CζK89xI/maFf锃lH^
    t\H#kq)\v0p/pv7
    ,a+Ne̤O%#sWRp8b (dy!
    |'CIOiv	OgyE
    M<
    9>`a Kyi;֤mXڶY\98ʈ+Dо}!8_'@h0Pҙ7ROJ_}]b–7
    1:#0&pփ+*b+^)_7󇅣̟ζ>+(M۝ӌBiơ {mM_P9Bz>Sy;B|Sj)V>[ASn6[cB	KxMʂgqn68?MdxPcH~m$mP1V}ific1["ULO
    
    FH0_Ei1ĎYpsT?w$M3SO8H54]Y񶼽*ȩxsD~nlHي�TExH䝲4wh1Oh1͖SޒMc1htҕ?}JUP)2\UOԐ"bqҝONkPKo`yE0DZAxOYu|TčmW^N&6nG6DxI/
    >h?/FD	3[룿6^Y'tU柟b[f|Im=6lPCIx&݇j\y[P wZ hAU|aZf_Bs7B&N:әTln?Ÿ!p?eR ζOsx;sbdm
    "_V_{I
    &Em-IJQv6h6׷}|,9~%MDl:zThh8>whlil򔠑#TofY5"شpljs@z2;_yٻi6̱B,<+f62sL;}Eym~=2qvhpWWrEm+GR}
    c*zSZ~n6o ӖJ!Hݼi(	7-^QP[q 1z#'
    #
    pk\PNegC^n|쳯i�ܾwBpxsKPNy	V1ު3W
    L7MI tyr>B}A䲍Tf'Xzm|:J[;L#zaM"6gOoBmqqQ#6NĨQO=
    j!e˯	GNDZEJD28P`�2TV̚;.1g߆Wb#P9NgET}_̭\8ez?SN9	{'Oc׭=/DV>)h/@HhjID+_]=;7cޚvHnP
    aẄ%9a_JN~d#*UFVh޴B:anZ%Xl_wbrׯ߳""Zj4Jߥ^=Jqtբ>r,):жMT#d$w<)A];P΂U�TxURm3Ю%"CѩA]\=1j"7}Vn@間C7AuUЪm[ԯS*)yEcHDƱl:
    x	|.XS/t.~}.4ST"5!8`&L0Vr׬q>A$iI1B@Xu})))V۫QʣFW.Q^cHn�N@>8}z|VrǩP9]x!&)f`BԭMѕo
    MO{M>Ѭ!?sݝ9f!%5-uD*TxE_M-j[mt;BdhP!:wlM4e&#M떨f[ 7sgMDKcNSM`�~1YZU:2M1OA&%wm[
    ,i±Q39u8~-j!n,]/*՟Kt.d͜)ۑܲ
    ׭n7B󂯭u0y|붍xC`o|\ɩÇ_ÆBA B©kЄg#c?ƨ!a,ĪMjƟi#[/lxDvC{ިuO۴?cp)'q>L@.]qf#|J
    6ǔ>*2z{Z|ڭk4Yj(aG,
    ,ZL^QL!<Σ3+{GvM&+3c3EU#|U4ݍI#dSvY>o;"86c``3_lCgvYϫvd`ʚ_PZ\I߆)`ܴrIJ)>o,]4&'@]86Bvفsȱ.=m)6[mPq;ا"Bi$_b TPpLE|U 8ڵmh.Zڲ
    ?^n3tN62D214e5l)ͦ3Ks20t;x_^1`	[6`C|[N:t4oXΥsa#QeW׫0rZ/'3ovdvRC#:k*Lc0rvWcy|;v9uiC9?wFS2(AαU"9Os1CM,CbPs&LwƸ!is`t&)3WSiA憕x+ߍŐ'.U#uIc7ǥ?GDTԫVԋb9|4<c9h8l6^K-v^IP[>w:D0y0U7ĩjU":9i	xCi'?⸶0iq~(3,"}/wt;fC}з{[.<K\a?qj0lYL,[wd!v]i:CB"v쨯-8pdFvWj3g\K8纻p׍W rВ4|f̝:M@fpRΈbŎ1rN8?Z6G&51g=6oGlhզ-:wդ8zdPpS7cðfkm@#нmS
    cޚ+9Pw䭕{A%엁^G"%i)e wcENY9ffmج֪u+w>ZFT3,XQE/Ǔ1]4gp;b^U*FZ;
    h�h*bT\Vb.QF		as+^}}@9Lj4
    6C_*9A[t�'|2
    _ 2K}бw4c[vE0,3`ז~oлcs*$l>g¬>%yU;dke�Jn*4`99~v)4h5@4*
    /F1E/a'"L"_9Sg
    ?޸N
    )6;!Bcf0l)9,i�q
    "@MCwˇ&Ù;Ѵn<N\zG3fHl;?ǂv)b);ئDU]7_S[Do&8^
    ZIJR7s!滭'^E?/UJL:nf0eUfĩ7?M "x
    ѐcuegjw{D`/4;}ʱ_-q;sG~pL[_zƠ/^|֬[7^v@9#
    {F?x*#:NchK	,.C:^P6@}vS0կh"Fä1+j!b7/ᯅ)o{2V
    æJXhAݩ_I$&~QsNRWS1n[xsL<hT6yE2l]cPyAmR}-&Lc4oߌW|$GѨb<]56&md
    v*vaЌ7=U7Dk܁_^}k#ZyACyt	D'GR:Np.ԗ5|cbgӶm{bsqո#OѾf8r}HEOGtJRcxߋ$f3a9Q5|l$sWvt91mP
    9C"r<d{CSgCxw\Np-26㭁zGަIJCӨ5wj0N;M/?bU?]`g[Jض~%zr.~b=T䏹^1GHk͡}taLz?%3_T0NDHnhSΌ-vdv|AXى'ÌM."9cJ-&0M<Ͼ183h@ǟmΨ^ݻrbѸ;5&>1䓁oG|le1[k>cSyiTc88:|mddڰcK
    n.ƾjZ  ?dj2Ɣx™*./A^p"4>WzAsKI$4X\ewo{/#J/澧qͅ#&}$UiV1/Er\`8t+F#KWs#sscޡ@1Nj4]R7o9XA*D>}MY0AE/
    $?&Dw@Bl4Xޝa[4
    <1SFӉ
    j4|W8?!W{97xWO4伿k:9|3SᴮfY}X\ol?Kz&HGNKVtC՚
    q
    7nF:TTFܤ?fFT?g.om53ޚ-r,č:}AG0!1؍R#y9Y	AuT>L"M<vTQknp[#?̘Q+q#^"~a}1Tg~NYmo[ERVk넄{^VsgCYYn#C"ѨY+tj	qر-GAN`$7MkW!0*Qs9`CaF<mڸ&NP[FND8fxǡQbml\ѵЭW΂d;*o4lHLd'GUgzB2>4J?ݏOuUTj&P;)w6kTJ>x2-EGLQZU)tC#Zvԑ1HY�#FOBѳGWDgcXfz;2e|9#odJ0g""q3qWԥ	y`oBr!|s>i
    NIqXb)rt$6jΝ:Om1fXlF޽QZ%,5
    cAˎ=P76Ǝ1$7KWFۯ7w"O)3J7Й)Z4*DA|>@b4<uX0GXy&Հv„	nzڶ4ٙXHa<elq;o74SE!*]yґc+F;P	c۩4>= \4;/hL߭WXnO<u0L>'LUk]&"c5_ep	UB1zC]+Y֡W}`̸XvQбy';nq%7ɍkjl}^]EWIJGAN:fOe.7I5 ֛1I1c<m&ڍѧ/ԭa8sZݘ0gSzFz	Fyj$Gq;"?]΍+&Ql|HjފJ}+lZ6FMbI"bN4W
    SqshLqLu2y
    'w@DZ^{"z,bXrDgw@֪AᚂvMpHAt,VӴA
    _:]ΚISlTHfS1s`Hݑ*h߮33p[,@кQ[M嫙?
    M[CAGV,]tkj6LJ|͓fBkzd>}Ur8DزFN@pL-Q܁>a4RѦC7md3gbeؕht!Yjн;w#jBzQLBTF޵#*Gp$^Ed"�-9\͝3fb]GkԴnԸu^ξ븳FDUBMIV܍K`ĩ�fcrMcxc4*qۮ?XGF3u}~g8bݪfs~ӖR,A%^cVU|cW?ㅥ+|~\\nZ\\MM
    -[4ZCYJC
    vm/n*60lXmϢ7	WnBu}#rzbfر~9&RvVF=ДnT;e`;
    T5]ݰK!a*ܠqO>{zq|p~ҨؔS"bEۧ"z%PP#hkp7&O	3ۻ;f)Ӣ	RƴiRn9?M	Iѭ4V/YɜVS'@mk-)0[!h֘faQsฎԤnb,kff&z32uj|=8?㲛qyrg2nn)`*1.^%m>
    ~'o5{C^BG&-b65Q6}#
    3o:uЧw/T	S(ϦcUu&;04hvMF(zlBx|tqѡXoL2k5@0(d3,<j%mTiS͍IfQd*CC1uE>&s/x08^t߂oTb9DUFsiō0)gcH2qԽ 2 s̢< NY)A1a,ZF=\2P&'pf,O1\PG"jN͉!f7<[)ß'8'}Ҭe+ASʈɦ6ww9.!3C3<92v\'B4ZthŸ<NWiaj~5:fDV ͞8~e7TBzO:tB8QA#$TǒѰe[WE\J	+%6
    \s9D9U[2rpdglȡ_<KѼQ]~aԟC鍣b^P:iLţ/
    |nTKfc¤iGG
    kVƜܝaѫ[l\:o@u~R4+m\INZvU\03DרQYхX5
    <?c9Eי(57t
    yV¶n!mrhe&;Е.]kl"sCy.'
    ?cOW߈)0AxoPpiqWՇNS;GEo_ݓmxJmyhߡ-"9X>oĨ;u}B+v
    v0Y[bb2![P$NQ+T`xhYTj6ҍ<nB\ k(|M/pE-zEKWHn|<:"82}M+[›ArR5hpǽ܈g{O<UG{Kk?O4еE`lZ/~&\Qm!>p :s=>f|ԯ&WMFL̝IG:x4Vt?mS/-/>^_Bjr5"
    =EGaH8̚:
    ^{OY#m/
    ŧtq:ըZhKpo݄{]1lw
    wbOr?\]:V}3-=۶nE_wBlͺMw	cŸԮfe^;YS	7?𬩨m9e"Ю=&>ذp*|UԨ~b0^'="}H|ގр0΅:t٪ų"	/<kǦ6e׫x~C9pd>}ϼ/mk^ƻ?{^5V#|--;1-c9Cf’sNfj<_6i5sǐMzaw߂`9>_p
    c}7/^M\8YNf[2
    m[!}<<+{ӣF\{~w[S“ιB/`wd,=2J7]e򳹃h`S4?i+D%<ҳxD| Jѿ~|ܽ&SaiتS4w3JO!ӪRUz_q6-g]Y?H|ݓL2Ixؾ
    -ݺyѭ]q
    \;k)9C\ô[7Iqx/Ъ	JC`o`g1M?ᩗ>ew>/e(5N)Я Fkz80|gWS{#h#N
    @|H>~3_[㱍G|LI5дq2FPfR|_
     <U9#WS^"eVV/OLrkOp.Nc;4/k@%
    +ܙ[иi?DSa-ؽ=0f2R"	cgHh^#駟Pso=Q=m㖭JÄhЅtzԎ6.ho,_cF\ŧ&vų狮>'Y'u>vfEY}m䇯@M@jFHQ16vr
    ߲n)czwcݏWr,rڙ=\/P"T<%TyW}</[Ձ bgogo=AMbשOd:y,26/ǹqf)LZp駠Ur#cĴ\l{͎(q$s�#riTAoOF=|:I5/bMBxu͡e2C
    j92~6cų-1[ooonoP^sSW<Z5}
    kk@xL#&/X܅':&)\+6}U5Fv@{w%W\�kuub6g�e\DxU_,9>-a|ٍk6,}}?kp`6.Ďճ=`OKOp5wl8jZ> |P. _AxtE_f0EJ΅?>xEHLd
    kѵVQw?.bx|^m1m[4m5n*Q!ƀ.‡FF,'"γ%[ȏL&ޓ}oIq}gck.^钗ըKᎽ~hW8"=\'We>x\^|<ygx:mE3̕xvןQ;m@N;>wwvlM#Kcnգ#5`ۍT\zGu6ԝ+a-k}}[Ǐ\?W<:.OjIK۝cϸA<|Hh-<&kደ-N?wdc;$2a岕J-_1%utIDZQ<͘yWҽ8#e2|384.Bѯ	0bQUFúnBjsZɩL7qU7^|$c<t7ݗ[X~9Ǘ<5.	"Nĕ]&	3HA
    F:ESab+dy17x)~|qxP�7o{&Y+GuCWWm2߾Y)U6a1Ͽ~4ls;P}2;֫"Z};B�#o>	D4^;r\j_ݻ#${3M~K?
    WjN!nV@̧񔃯1:C
    1rc~]o?{'}9DtJ
    Iߧ;TZksmpm/⏫EFT;f}˪y8E}{#9WA?b48
    *b?J9<2>36`<{
    i|?_Kֽu"fMrk}q.s
    2
    W'
    pT��@�IDATYx)΍m^NsSƂ6O;gC]_'/O1%e<RSwakN|c<b%se<lh~x킳߿loxsR;Ű_Y<֮V8u8臛z!UH.7}?4m;'`̟o-\9UNt|?ԏǝWī)gǖcEd'\s8B<\�x{p|xp楷 31E'O@—-3Rg8XLð%z5'`OK'n[!2,;fjMz0yݼ	؍x^֮09.Ywh^3\4Tp0L2˟<a7/t3OaT
    IPY!. ^[ceXubQ#/<}˷hsѫgwl]	}3_
    ˧O2yo]x099lv@=HK˝6WyC9rF$v";e'ϺqpR^Ъ%و@:x3?
    ԎCO	
    q"EF|i9Z` 8?-G5m
    |,߉goy;D&1KCE0c6zda0gi
    wʸ5s1{5a�B6\aw4]\h\^i\P6~Iqz	?=30rS7=/9WG/ƯStG5wNã/%U-i@:(|K+Nz{0]a_Kp=sca<8o}~ԍǏgEQ5v}bءא]>#W݂Cvs:;J2(</rtsCjw&֮c\3iX}q16XFI.h_*C3Ѹ8J(>km0g
    }Ù&&>|1ϸ1;P?R֬V;d@:5Dݏ<.VmbDnKo7\|
    Sੋ/>ӏP8oz>{$rb~8IJͱto:Ҡ7K">/
    uQ\6f錵8q@lп[SLg?wܫ#
    ~5XUhrM
    د7eyf3>'rDÙ\-u:~k6lQ6#4ѯk;Ԩ+H&Lwʔǹ Q2(~Ԕۺ'b_~1Aرi-7vaaؕ	}n_<d]p.gc&+17*Gi܀14'7_D+˯~gsSM/=Dez#AczU}k$yHepOC΅_$悰?
    ؚ|:z,`; f%TJ\*3 乗LwKO>߇d|7,0]bN5r:`E?::q~jҔc1;$<
    <yI#Xą)Zl,o|!>=O<"!LDUSqN ;S#Z)9u5eZ0G<¿A4iQV5.!SJq h;LW|ŀYyxK_5Ǎ|'o?rrBr^'tM6{špwFʳfsQY$O[<Q#pdBv?EBzG�
    `]E3?nLTBEBEQlDE)eܹ.a{{9s9g4Q\O=>nl%;BÝLfg<2UKHh3t4~k|y:[$q45nn	~C6}<mu
    M	 /;ܝ>"cBR):XBȧH
    jK(p{Şrb=+>FgD?b꒵1瞍!CN5jhߟG	
    iC)%y\g&}Ǣcf(ܵv@ХC'4 !
    ;wVAFv.ִ]k	L_3D4M-sWADp򖗾\~%Aw<.Wa'ep"ޯWT/DJFֹp"js{|0;8`ԣ%e*'lK(CP*+R"4qӢtנy!&9
    9 3Ko.f-947oyWP?z(p7g+Vy`Bb=ZGf!,m9WVSnV!,E[1MGǦn=)Dw[ev7 s0N~qF`:<+M$$օfq$Uc{o[GͱĆ
    Q;et(t㝺a&9mڢr)	wMکj־')~uFfs7FD2$HkfbһcqM$8I#nQQܙ1q0Y/@f5#bpe>X|W…4bsPЀYUby4]8|*49Vb(
    Mv^(7:?<EP~`Ds&ap獟U={bȑRv�;G]˾RNĚs!2`̙txg<Ɛ4VavZ7z!p!&ukwY,uWwnB+'.q[ޔ42˔@R0XCq4Lz[uuOgpc0f,LG#s#3!K±7ϼG﹋qƐ8b0
    W x;&pᨋNb`vZ4 
    f.|rһ}^C[3qZr@۲_"i?~Dž"n.8ii}<[
    eX("^B0>D;~u7'_8p?=7K6j.C^#ɏM^IJM]O_{F'{'QP\
    S9a瘠g<gZ9o$:V	v`e]BԷ04mF琭[ash׮wsVQfq7=<s86;1g~s\my&{.Xr̙M~mֶ-"f0t-PQB_;,
    6/#7,4i2Qo@8Iےc&Urrn⎵ĭƅNdZ�=O텯^T3@ǎmQ"`VvާУCSxWM-2nLOݛ- \ҢPFҽw+#J9ThҴ鴼QəO"¯~Z)j>(Qa粛α:vN@^ᤌ0u;h1-Qe::'8hyu:C$3p7WRYl*'հ	N܉\c5+n|:ǟS&ġauq	/Wǟr28ch߽?a~@cORgGqg~)o¹xόN<]4-hi?0Qǟ%hЊuդPZENZȣMlZ3fƂFZjdEp9
    k}v{|5£MpяǧP_	G 1lg۟փ!ضq.=|dZɛ̜@F`|	C!K;Wvp1"X3lF^^+Fa7l]w7K-fciJk&oF>
    \aWGnۥ9U"9k#hܲ=F7yǣ	\`l;ccHSfο?)`)6|(q;zG*A |'MWD{dk324C3P<лs[FppÕ#v6
    99y\]J|v95LS̤Z9׸<w3&5M#i^FsxQ9dP3Wn+2hݢ!
    فm'lj0%2Vt߃UqMb:w5G;zh
    f!ň&0̓w(qy&yN<DEcH4̼Vf:@))B:QN&5Rz:PI[yK)E8A=/&CgNǪqcΗxa2m94N׸ GnZP!V2!|Z<XNjN)񧟃M\(⑐W*>,Y>?.ayި<wI8S+)'<+A@XAWHrb,;o4.*a;ObehV<-ɦˣ?
    83y3fia4_Z[ߚ&u'ov;ɦt9͝"dd`	&
    |Mr_y+;\,Y6ĝ`۲eKQ<xaڌ0ώlyWw9h8Jg'qVLCכفl^[w]hߵq*/]|7b#..jtײN^.Z4ןg.1!Mʸb6Iӹ?
    IuG⴫GSSc;`_:z+	:geEJ3r]Kl:g˄9nL8vh(Io]h9[l&a'?d̷FYI!zU]F7piMfnxN9
    y<[(RE#}Wm{G
    zZzN/Y]͎sw';,#CF3COz#ew}w	|?cc8+X5dÑK̏!I~:v&x
    V5%
    rͷ%Km<҉~ȷdG;y7*"+{
    �mV:ś<dM$(k?DԤ,+ek
    }Qh4DcY1Bp9uo>A=/9衠)2m#qMkߡcgŒXKS(x]k{]4E-NJ7YiE3^{w
    iiל~^:=vFwWnީN<f9;+J95}҄:3wFSRvt%i1U! TLf0q9Ms){sVp1Q6ݚу`XvTt$Z2fM`b6rb9vRފ׸
    %Z-:�S
    y3hP4Nr[ErFY]Du[ASM6FH3rznHjqJ]`IĴXw9]dxHX,0y'3̫wxZ}XET3"LC!
    &bgey?Z$
    pZ\"o0n>'U>cs?ĢzrԄckkN"c	xɴꆷǾŞ]EґO?]>ɽ'=`F'!-35#y9v4v`k+c0kdzv,[7Y3r2Xexk{a,DZì@?3ly74~P&!9)))Xb	Ǝ?A0A7z6˝8.45AhN:1Hn4L/[.iߒWXq%ztܴKȧl|u
    N竩Q\ҵ;buS,7?QHhtpCZ|bz-' $q�d=Z!9s}"`)m_jW_4e*)AuS6v;W]mඏ09eWY>JxPC;*pM@jGŢa*ʜJa[WLۖ<cB&NQZwbtS$NMߜq]Ј+<<nSyFr|+ŬmpG#f.	^lvv|jx=Wjl?,F֚͢<3yVeq0>\W_百nHٸ&/dZ qC%ꛁWpóo5ݏӟy]I٤;}*6-[Deǝ~<߉&bR	I|}BP|YfqٗcNЧ{45Ъb"}wPp2NCS0?S>hNͣoMجի1wNQ
    [|C<yLwwR8NxMχ3L+DT\C~zޛ;?7m8ޠihN<kS
    ƍyH>V6u
    6\斟j
    }M3|3֑|:BZLP~SƝ#y6RB@hm�ĕ=jpLp2f.qpH֯Z,:vk#IbٺGK.niPb=
    +"ȘNW1N;88i?
    x
    |^TuyݸK.sϰ6Oo7'=U;p//�ryhҴxmmv8*j2l5
    "M}աbҤ]wiP^J\vՌmZ֣�y/شy#Ul9>is|oQk#O'ڲ4XJقx.0/`y݊V5;Z]ڴ|->-}gkc	gCV*Nn
    ~YtסC{:M,tBI˱nbL+:\<׳ţ;9l32oMvħ'bDvE)ߍa\o‰r,BA
    1ח?5"nɽ{&8d::|1pXkkܓL9<cF~:tFرy-~NN>ؠƉdaFSLvd׎_'bF.8Gפ@Zj)qAԄM3$^TDɂ*}|:i";L'Ԣw?eޫ']鏽Ք6D︋kK0<K15>6P#>zt/wzC^9;LIF\NlhӼ:d#'Lgb9H߂)_+	'v"^[&O&~5Fq,$w*uhőh=|eӄYA)Ƅb6Zа:|HC׹
    iML}i%yP<td&î?(ticX?5͇m5iϺk}=hft '3<*ѭ`$b4~;	8VϺth&f7N1t5Km?ھ!ECBѼ+h+'h_MZ1]h郚^WC)NŊN.2T3.ZS
    䍉	e$oj>U:k؄�liYH*ܩFQn`{?Qa
    wHlkaϙs@;h5ѐ<j4ݩ!ws	Z͐R.}3GZ|48mJ&vYHb'&w+ge3G괅ؼ($s:Z)Sna-Ldjzԅ3sTT/tkגG\̱&;o:%NS(0To'o0R!g][$q&&YI`E:X6cԊkFf='E YOąמm_.tyh.EMtMkˆb^},^%v{cHf_#qV"	bjhYNªA=3<4/-)7JjPּ;6cGSmOp~6^*ZtbfhMގml. g^<Gow:l;R@xqxHdN-dvH)ņ_ysO{ܦH^M8:jgo&rc\.8JNd	\mGq~ƻ5[ޮ
    xqݣХckw~_ 0Mp֮	Ѵi>]k]/:0&z@y
    ݙ^_GtbomlVM&V*|h!o-c^[WkryYðH8x4kh&spsc{5\>Z>xyW w({KDnD]~M10?JOƝqMk^y^<vӽ/tьl-UU2IŷC10&4ꆇoʗfpRi_:QtT[1iLp>'`p򄯸8@hܦ+:wh[|bkTH4#~{q
    bst'{ny`$dYB'<~<ɻ!rx<K5kMq հY:=ѓ>?grsixw3�
    ؓ?=j#Ըi2λlv)M{tą'ȇnuw=Fﱟr7#Bf<+\O0&yc1|:U&91{/3Qވy!/H^j5h;]nCϿ;;<ag\Zx1moéWݎSgI8z̜6ﰾ_w*cZ7`:ɂn9IB}J8Ojמ<NΝν#}^WW'6g]z/k턋3V.p\f8.e{C3\<YwuqDbk#)ָ@É=Jw{1>GжF[vѯk[ԏÿ7ol\>zy�DFװSʧʓ/-$k�;&!0�c{�9qiѣ-Wk$y{B.n	p4.+t=j5hĭ,->j#=
    F>i�GHGk7g|Ϻ}4CВs5I;nZ6o5֣`zr=Xs˜zf"=F_:ғynuĦyd\r2n:Ǝ]!Dt׭W^ıϛ?%qwGP&zTWԸ	</3
    |ay8pt=|q׭#к.%^mjKPxGFyNRw]s>z-ԣHlmzŊ+NF}͛uki	}#:(DPus᱃9q.8HAH@X&`<z)1KhJorP(v༓rq:{{n1MѿSc`=3+xsPQ{[on#Z2vNlw><S&z.RsY}q_0yOn8\ x']7[q]cakG_Y	sbDh`�D!,Җl&u͘DxIA>Y%L]&>)~x5kg.qH)P1#l'Z޵'6FL9/S+QiO nv6GsY+\q0z6{<*q)<B$eK~s㪰w{2X-aWs|l]>
    ݅X\iѦW
    aL'zbXGiiRd9
    	S.DhX<sS~P7rRH}p]s/6])َw_q܄iӐ>p|n'еi\pe׸Bz*f={+ιUQO?<~uC/cr7/Tk'=g;u녶VWDg|]}0[<yA2nrPOe?ĈSCԕoN6V:C%yfwb2j7\DAq%e)%ozRn*NOIS4Y,\tݜuAT6x잛p}O/>]SOElA
    zt4>*mMovcТF	n_7rcYN);qI8}]y:<BB9`mK^Y[w'^V(ܺqm5cv)/
    heeP1-Lc�'Ԩ^|G=s(C97,w˩6$QECվvV9V13&/>u<b˔t N*5һW	ѻcg#0Z&qm(?l~	Ca`O<ԡ76T7=`""ijxt3p#8fԛHLym?$z/6sA!GG/&=蟼Fb흄ϛ7L"ZliV,t+E@x..gh2`S)ͭґ_34gvb]"DzV9kTAC^EVQQ>M38MOaVrlU=Nʑ疸"BuIc*Si:0^kSx,d*qA!Q(@Ji2vox=hU·֏N!EdCzFXk l48U
    ZiQFeZ@,s?C^I*wT>Sm4:ju/+#<JAyfZ9f+w%2xuwSF`U<mڴqׇhJ?IP,Km)Q'PC8Ru2C4P,Z0AEf;lBL[(Ͻmټ<֠ŗ8NlP8v3G9tϝmy̡ߋ!t_sv&񥹽L3kG>8 /y]OFt\4($qCWDҔW
    WfP0ֻ>n{'fҜSQUj}߲SIǓgKf`qcyHVp!YI2X|^VØF>N+z|p\\ lʰdP7U̝]l<M
    ©GTwghiμnt9ʅ`]ʤWlXwY_wjw<NZ%'k&3L:b
    -ucv*3|3թ{7.wwr[w)~E|(@04g4w=B5䓖){1FhHbnzy0gg=RvQ	78mز-8+	a1q=uJ1tI<NJzS
    P�
    B_HI=-k̝2WN~"ھjԁ9lהiW5Ct�LdJ9ˣ>J/)tL#k­wǥW�Q:YLJaeMQ14V
    xǁ)$/:wgAҧ.av�8&
    z0K]"9zsȦLVƛ�kraz꾈{)]UaM+:vtMA~נPE`]9	۶>4'fְQ#K5;cZcVf-⌙%HPꥬ]ԭ[zڔ;DᑞÉqI(k(
    U|t-qV*eX'=O)$1$hvQKoJOUtR)MөCucL8+W,Rvlǎ3LF
    	e2XU4OdOI#mII}L	xMD{F'2t@BW_Lʌx6uxT ɦL�;K84P/IwC#цn҅EDvn'P~i4q(QFFT.ՇjsgX;9iM\b}H^5I_n۶W"oy>;ю$E|if<;}C
    Fp˾WV}r4 >7ŒL^6aҙ|6jhW|zeRKz9}
    ă_lVzMTDHcEWL#}Kg|䒮tހtDo{6ڊ5;ᮟmѲ`b?)%{:]>YA:2-eL$6**U?K
    JAcݺ5%|
    DEF>Ct{xϷȣeV,i'c_nFP(zX\ǫ3pfh>KDi+n=P=(cSJ%M^C}h++T7!ChDucv9Ia[sH0d5:踨P/,X5:qA]ZhW=}d<L_Zm"WKOё@.8\5z}SXı,)&n`_>QG4fʱ wH.yLrlʶks9^%d8azeҩ3kQIՏfS7Ci1⩏P/H~1eŔO*UGc[FaW
    gYbZ>S'H6Pӌa-I$MtM}1~6e0∮"!:#Qc,0#_Q	ڵkM0tP_ѲT!i?h.ljVAЬ')N#FMv\5َ%Z)Usת՜OxQ#t³5x<)jR	c@|W5 0g*i|I08VPRS?àW;;gpH曚rHT|pW𵋥pr4S9
    DC&jWUB+P$~Jc;1iB(!;QU1On4ݬPkyf?1[DQdmoWz
    [T2.HpީJEnwG;'^Q~#[}|oV@)}M&!>L:)Mc!u^j-=Qom/
    g99vM~ФЌIy'Q]DSO`:ȌLܔ<MV&j>?"N4ן7M-_z4p:QӶttׂ&Kl.S&kڲ镒�/F|m/nwjv=xv'<+b7:oBwm|:mURU'QӒ9}`"i
    NV~yS9[)n)}֔eK-T3	?Zsg}C-i|_[25Plj"b&7wL\:663-K7tʏ0r~E:!`|;`Z:T7Qo#y'm<x^ibat jxKzH|>ƫh|ޠcc$|eiA69jz(^m\T)L5|xUha`>J1|)I|L|h#}(>:fi+DK?&Na?zjS;%^v
    G#MQF)v{ȝުmoH)7T8
    1j<ÖFvLKYts]NеСɯ}ڗP	R|-nIkL/OO讔^iׄoBy坠n7%|ƶxC:ϓDz&r
    kQvt}Bhb]A瘱l[!=㄀Y\Yi{z؂m1U^|it+*𥰶CB<"|̂2w^иH'ǎ#y'~%lmyE$v,lNn&O	2'<=7<0\GrJs{ui*P,[ԻҺwy]i5[PԺR8^M66_XKk#"1Sv,c.Wo.6WlR}W@K/J
    {h*ߪpqVqSh\]:s8/W&vO;ݽ~꽋N;8at&c1^0�{8ڤ>؁ytcڀ:b EKoaND3WSh	g~zXz6vO|7m`pZܬ+irgh@2k:*&I3.K;X1 s<RԶ{d9mM#*Ke<a
    {N@?*
    d "*G{S h\d7L,N{?UWWDDw|isO+?L2 &2ah`iihZ[_D7PE9t�,J11BopO(J߽u>Zwvr^ zE<₃kZLD#jvxh^a
    ʪ(?"Gk'/vo
    &T^}p<cK#Yf?/\_JAqڀ)zx25&n:jkμDwEez|%Թ,K*2P!n)~33#8|zgA?qs&~:2yYL2P՘LyzA+W4+nwx
    =ɾKht靂xߕ8�%!O>lzcajɼZbvQFFpm;%ﺒ42PZV$hް,'TUҘ::uʄ6MReQT
    oM=)?ZT'[\NyBUuEOr:H>U+d0M=DQEG&Ặc?GC˷PH?>\(M]g`x*w&זپo\Zh[) LCŴ1R447tt*h~i~9tl*,(h=kB	XB
    <U?.Q(G 88U=wGӂԸxwTZֽWz}_M{ lFOje!,*`8\^JrATp՟Vvk��@�IDATW=MSOO3ri\|i՛68{Ǔ	]
    =+W{p,C+*ɛ2<ny)Uގ$NKUO4tfkW9FTV	g%ë_ȤpIu9࠺^^xa7>�׆	eRYÎˈ}t/$^u!P7`.^)oCM
    MOC-XΕ(.+gUǏosp#|JH9U3Ws82N-ɠKFH:~]i}gQN6ڷ
    RtQ0.V`LWs鯾_8:(tvkoZ^p߫z:{a7CT+8eӺ}ey]4
    }ueDZ*V.&A+۷o7\U;iJʩɪ�ˣtV$B*/\/|G—)VZT_ot@@xA.呹L`ެwSmoi[y^rsrv,qέCtS;*sm7xjJzQo[%*T̛xUQ\*~r+GBɊ;8~s|&SjAe9Р2lPl
    2TyE7ݗ<XAm悃߶=Qz5jfeq6|YÛF.YgS^ne.Ӱ/OG_<#:'e̗|?v&r�;Nnq#>;.eCU<zh޺xG{o]+?tUqG?PZJ'y1N`z	GžhBG*V~뻋wms+}U0]^=|G'o~Ce_ăhyoT�V *W`]e0'|%\2.#~{
    q
    .38xaz+^Kf4ux7YT	֕7ϾwࣺWG,p ^j|h۸qc]H:$S;5 QZ
    5P/E|S~W|=/bV~+
    pypNVWꅯ쭮JK/|hy޶R[
    j:ԛK{}mcoʫ︶u5L"{^/;^;>*GPWW袧R4U>>wW{zNUzAyն6ٕeop-/W.<]D;'+)9~]1MM[m~CB+ᤉ<O2%{+5˟'^>>+Y^.Mux=[WJ+xVi@4W~?}@i݀G?8VW~!G<>K}h 3~e:u:EpNOjh/~phH]|/pY9XP勆
    
    ƲN;:W%U`J/H[4U\oMӜ.u:͵xXumVTJ^͙3M4A֭6H%aVm%G͛dC8x97sjFL'gb"hp�Z\4ɔƍ͂"BJrhCJ=r0hgv4N@^xXgdS!,+sb&
    64B.OM(w
    ZҸL7_k֬1l0S̓CKUPVa>(`E%H?S@5vwǿ2(ʓp+䤲vRC_媎S+SFk
    N߿P9USxOwi
    cӤ4su&x
    =׮}S @}=)Y/pu8U]T8z~:?oD^]7\4:iiIr5Ll/Y< ޲>WNOoK{>*0ž<SoCmgiʵQ\tp'G4ur䞎Gi+b?ۋ>eAhfvp*L"m;)ޕ\{108UIϟ^<$M'>aqwG)�?c%_&"
    ~?"jy%ZoG+'c6okenQTؿ.xXlBksKB}ofd<qO/LMJ*Ȭ{y6d�N ~ǁuyCG]jTY^X7o>*,U$K9AcAy؟"W3mN/
    "	?cH#])oK3m"Sמ
    *dWI xL?/ͼk5_~
    ϛ^)Cu<6epc!fP`{zthȲ?ZAMuWf?A4^,Jq3فňI;?F~e04aCpe@x?@ٔsQ FVoǺ|.b}88NmϊIo7I,^xoK	3Z\8m鞁77MI9ҳLA߃GcIo?^4AaK@E[?1;VVΕeKk\=^GE=wګ<>oo~xoy|.r9O>8Z[`\}? }	nz^bjF#)1ܥR�$eYNr`U@T_~o[rѤeC	Ύd-(<il[-8tWW`e `*-顃7KQ~E߼	^wnZuԞNW~+Wpw%""
    MG3P`_0r@Y(.㽮Pvľ{̐LDDF#~=#S!bn^iV˯*NRD3_EtN+KN!eTHML(VjGyㆂfU(/QT"kFO{_aK
    mN $VHjx<T9�NE߃$4LDD-Kg#*ċŅHy¢DԍFB|l`MӦ?P4?^NpݥHODhmڿ~EO1 eW*xxtlE52-Vƻ~1)^"2
    #$=">e7·ܬtfd72
    q1Q:zo)_oawnme+zc>9Q!yvD҄o8&Iy-*C|BD{'or*XyYfy==ɽqV/tKHIChD]$6oׯ\2t	2;ڼ;Р%HMم<:f9
    m9^\K]&ۡQ?`TDÚ>|2SaHn
    |2p\=3S/ 5]@rЎ1x_Mؼ"$::!+wѱ]eP	#bL{r&gJКUúWb|>͢n,f6Eam<uwr
    gb;xiL?\wNEt6Sw˵Q<Ic_o_=f0-**'@(+;&r޲H/@
    Ř(L+/yk>߄öV}(C\}l;1ꦩ8'	1R:mkDXQn:}y4ٗ	繁_03Ob.Nx
    7Lg@0	kצVKq+C(�,w߄,L~4:H0U	SƎxgmffz>.8T$'p!jt;ן{e~fE}$
    ,?O>*[4C=FaǮLtΕ8}D_.HXS=VQƟH۶}
    |+8qeP?ަsS>_pKߎ_G'<_uioj*4o)wų>!]Ea)9xWVmqqc@3[wυ	ȲBL73n0t6g6CyQqݷaXnf!&f❗Ĝe)䢀Sqb'ocQI}qcb:Λ~<]]Jr1xsqf
    R#]
    ÿ.:MbjƬ n8E:9ۑʅneKǏ9єmm@U.'in61%|:"Cq1 7#ǼjѤ rҪ馉_/Oyعq^3	ǝq1zuUU
    c>ٹ~1.=?{)ڥaO5Q-\xu8VRKz
    ~dqJ~({Ʊ=3Dc,\u]8^Lǫs0;031^{c2<	Z\I_K?9l
    }q	QlQI	2W_Uמӗ[۶K2tɋ.NvtQJ;n	Q-oI(>d{G]qlOX}Nн*2*j.r%*6٩9#wQj9inP36^6#ꄱ!ijI]yu\>Yg%k.+GU:s
    2W.)߷"*#`o{eR
    Ɵ+NJ(!\!t0̓WZ ࣄeWەOë:VNkB^U(m0Y-
    8K2Y50mB0EREԉ@
    lRƗnL
    cSF>y5B8fy5t͙;YپaaBSJ~Jޭy5RcСA9x\#77&)ꈇ78st(/;˾NK7&R�WJZikp1x<Gݥ).BG|E5SZv9y/Jë_+G.6t7z:sR9wG	غf	3hn'zNDEF}ft:*5ꈐ`BѬCw͋#3/CMM*q"9exf	[zzu�pݙÌnw+]U8qﳏw|lzvWN}7Z_
    Vo�[s݂	upx0]d_\d"^(>
    :Bi7GiގY/Gr&WfUWiEh\zPET71܋?E@o2pt8Gwt7'>,eR,(,f(U\:ʻ1Ǖh/ODWZ*~zq.E(+1O㌫[Sf_vFMk}IFX部Q\qQ]RHμ4tڌG~S\p]xyh tnݓC3T~y|LD8_7ӯFu1qc0;.?C+'eE	x0Duʅb-NM,>~'Y2܎.ƄG_ϑǣa%8OGO|	Cn~wڙV*-N"~z$:4o_ГOA&pTGE:la꾕aTvzӷ7;<mKѱ04H
    ԋxFGYGŕ*|7Y<_-m'JWP9Jm&з<Z2QRQґ?̛=p0k/Ddb{{24cpWճѽM6_c/mCpՃ^?XmND&h&MEfF&$uIƑC[`˱q''Xeub#k[bLg]s$Gjdu؜{&t棬bCdwq}9μ/wK0PcGIv>#huPGmNG.er*
    G?L]ڡ&ز'~GۦQX/nY??b95]ʜUXb|bn8Aܦs,w A͚|K:}�zwŔfa'+G{8jUBxkdVCTM:z];ų-ىF}K$㉋%<*mذ�N?9:D	
    Qr̛݈nV\4�Ez&UorE6c5t'r_MG.8.찫c|ԎQcjRWQGw⮉kwQ^9dga:=wVpAiz1joyLzêE~4V{
    Mi74}xv}}B-^H0i醎#v-sW	`g'i0g70`hTؼ�9prt]Ŀ8}3[u~wĩ&N
    $͟?Gg^hK=NKwf/#%	.tDi�؇Q9qsq8v,&lmI݄oQBf}O~9`;\.O5M<;Ej̔z:*BJ/-(U!l>)]PmG@ͨ~tikAx3r89WahV.	mW~ĺḾC?ϽvCtQO{}|DrT<q(g?n-L'A�~P-
    Ĺ?R]BAMn3臲#</45*'w>hmͺUojhٱ.hWߏ}9c^5\^XIѡ0Wj5Bѥ`ߗ*@KZ,?:~avc
    ל49oxF~.f	p.pԩ1qCh-44ŗ_M<$u~\	(ɅO~U<cnlل~{-B$?}>tt_Dժ]q7'aXna'~>`}/˃kpW|;t;0KvɷxؑUq.B͌5RV&LxMe5N9g4ikc7߉#Ƌ>AG#d	iégs?MSݴ6X]Ci9e?Ts_1-úW~ƔQgZCF65:bpv#	5ʰpO0v3g_1S?]R21-fw]hU7;ijΊmچ?Cɦe4EنlL`^{m)
    6c.L{zBc o.̚Iٸ0	f~oq5,@\ͧ2l_,i~i%AMX$Į\;{g#%z5ǧ7ɋsM6mhئ
    pupU69k&6rCM\Q,C=n;f&j%5EwaҔŖ\zͷ]srO~3xtz>w8Vqį8AGn^
    F%@E+Y#x~U)NuBm@ʖT.{kijSa_MxyXR6
    wAbƼvY_9,7+7ضv3~^T9#/
    ,9aէ6oJ
    }Evz
    ҋA<׬Sw]Tw<{Mʱtߦ7nO߈?cަm\1fhwq0.pnjܥx9֮\}:tmv2Ok۝73
    Z8i>pWÔGoQ_.-MZtpH
    ._&!9Ҷ#PdRgSCъ! YyGVb{oG|geľz(w[H_	O(NizorNK2)ߣB6OLdq">vg~	ZGX^5~>W^o|[RLZ}E\.Oꛜ˲ͻ8g4˖ձWa@/a3{dL<br球Q3?MSLƄcYؑc"dgǯrhP;?\eްI2qѼa$<MiIvdK~͚L6˥{+ݦ!!hڼ59E-։AQwhEhqh"ɟ 7s:7�q!MvBʶ(vH8S÷? XI3yY*ذm45-<&!kz|8Qe?4/H64mڒ9RhV(;ljz!=إ=]-7
    к1:t^bӯ?".2
    +1;M[q	-u.8y(&^ڱ
    1y.}Ab(:W+.w肤F}${M΅FQn)zm�N>2h0ivD\z7/i;1pDNK8yQX1<$JŤ9p	]Õ
    _d2qXEYwM˿_^MкYՔvRؚ]땀Tr[p3%E:3~L2ػ,;!$H#=QpWYmmZvZߪ.h7nA7a&@BȀeϽ%o>D|x{=w=7	?Fs1tD
    UϘ\=’
    dfh`CaAgUcȄ&Y.
    !ѳG4W}}wb"_>붣&\]A͉(<R
    /n!^R*>Tq�ƭU{;.	W\5Vu<wA�1GӲz~LOHTQi=Wp;LrƯ7'S޸t+xR[ZsqJ]XϬ>)	tH$SݘCa2;^'^8UpO,('@NT@VN)Ȁ[BH&N:Vۇd_g]AFz0^h54b#c({\їn'9*O?04UZAA1΁Q=T\)5Gl
    ՚U0UЬQ=	Ŝ$m[hg7^ƻJe;EMRtZ^<(iLЙ=
    n/Y-zUy5Jf�Nj@	mnn51UG<VT:e+9WKEGawiײN>xjzdͽUNlV~@܈'911jhZ-RkNQd6߶~k뽯4(6o�9?s\Zl{Y􉏠FI0<Ιso+Fr*-<NUU5S4ngHÒ9BƟ1
    ݣ|ím\iFO] uبf>Ӫjn(d[/am!wiO^6'�dm�%셖:jH%Rfbq|˭B
    NGy"l▧R姌}UT}Kސ$9"Q'
    pHh)P뇜"\Dť-rWuACaҠ\LJe^{E#~~}-")yV~9vFD?f?.fm؍CxKp7n<"pk,#u
    jexqS@ͩ冯6DUIBQ]7?xՕVRk-?8Cc4L?lɾ}BsOo3PY9H~2õ_u	QUfqa-//203JBiQ0ۼ+1Tޣ(2jtXxAͭ}OXdiIrU=&_=s8㓃իvH&8'd�DACMi%]Ej~<qރfE?i8<k.z_r'꒬ΓaK
    e˗Le<S-Rn}sHgA}ЭOX/TH3u(>p^FLz#nQ ]g{^hkEVUd/1]=c5-WKio?Nu*c 2)�mn!b8;j[y{3tx:YĶ~RaP(UտlU$NV`',aUٌg~ZjŅ7ZA'8VƷKG(aƋpMFܲ):r`KT_~z<E,
    NK
    O}M nR<:󒡢L~,)d&.#?@YV圠QOZ]Ⓘ#=y.<le/<{и^J{Oë\vJp.iD%'g}ᾭ0mqSNH;+~y;_ksgI}|G£3cݗ㝿RZ'?|N-uh-)iq)xov S=/;ڕ5 ö ]Uorj8؉CPڅv
    U
    4C/=ԑkQUUVi*sS18NfqZHq5>G˓woam7U7j۪HM[k,w2.+cw_wbnF$Oդ<B#J4>^X&ѵ$=7O7Զ[tP{26h(Pp8!J9Ϋ_"h5%aV(-30I?OK6Y40Vōqmïܗ¡}ʋ
    90D
    ?,#s6TyqTQќ],`kA+]-+PsQ+}cșè"qE@t;w׋3GC U/GY|p
    O^qW3|	~j%b&$脨%?.S&/o߻.jDz7??×z8IùɍL}((I4y@Mf}ϕZbGuJ.GkDjꑝ~>8�G|eA5?mK&jQ]m@ۗ¾/
    :rZ{	bZ)#
    s	bTPc٪xm8?ƒUǹ^x u@ž,EN+$}o0i(R,zx*d|yC#;a(砘Zҩ s\=[y6&.j1]YF}_?NHtC/
    >a2@!/N{	mWƗ"HoG??
    soOdD/+ž1O{at{8eNq~~ǫz'KTOG*B_H
    #ۃd<*"3jT.?z<8iRjr+pNaaBUR\[緫k|F2iF9jeTqi?JvvAAV{矋;^s-FtÀ	!6*\~fp%p%S->+Srܘh_oL}N
    0^qU*)s7s]LN_sP*Ү6MFnLTdV>
    U-ЃH"^D{*q�'4NَFB'ܕӈQ'B6)]Ncz2%jǶvR
    QzwhYrϠDDc(F
    sUMLƷ~ZEJ/՚0w#؋߲j|dP-]ESaGGE)h`tq	iB]"'s/m{@h(ڷ
    <7Xmѣ=,lTsb"[|)oYai9H[~[̘=_ws~Z3>?m~E�VRZVJ2wm)V+~<VE
    pT`ۗv`݆<Hq%5<}(6.^o؈#Kせ>lkS&1nZO)pU`T#OCpǠk^ZTycK;Y~^4"·hf
    rnt%%"hC쉗ohuniW_O[z"s/<+9GIxebW>|<g畣40HyA9?A_Vǿ{(-+G~NrrŜxr~-?*AAQf1r\pu?
    R>{6?-[<}έ^
    T)@^
    dbx<w"ZVQIې]R<=[s6\Jc^2[dqcv̝U^AHe�Uޟh%NL�'QZX}KK
    s
    yBn'tHWܻ̞݀<NGQW\??t
    k&lY۷oÞ,Yr8;c<wKyу/}q#)6do=W
    Ӷny+qOOEҸio˩=#EvTW`Gf>I)˰/#[))1	1W܅Q([yҭŤIC{1>ޛc'Wm}1apز$$߈z[n&\~x/Xf9'9&BC]|.~쿱P2h+ƌ'"FlL=(L~?,ͷ<+
    ?qO;`,f[#v_2^ĬE0wwEv;ntT}={7m5i'f3fesknJQ.-U/7­WL.VGE{)˿fdɝs6Zy{ko9Ux9y0o'$pcUinKK5jJU"ۏ׉ߪ2[}Q#17≩x듅8y{jcU?8s1}6oukY6mEQ9m8U<jf \!9Q
    Qp$[6l+f,u=u:J,ZL5YD}E;[׉}vmc|7]\|	nی,nQ-h[pE;wC|L
    1mo\n~1qYD\A[EXmIѬ=ij<:i$
    5j2%9RPxx+ճ'܋^<uh)~u#8ghjFH+mqaPsghtTNlW]RfZȲ)ܽx2r܂Ƴ,Ad$wDŽ>x!NO[^v+<s\dM{&٥I?	Ҷc5e3NFG!:W PΐFGGs5H`K#j8FaDtsKǁ))TI;Qs2"s&e첡P-Z-0<!}4Bt>M>^ݎnAdIZ-,(8Oa]U~0=/x8P
    UΑј~HSU<2I<mTJ1@عgXD;3c(-BY~
    @w
    `'8;3c$!c턛<Q4l0xl[qFwːo>#j5	9?GG1{pk++X=+|F+u,lp?<gʠuYVD!=؛?KÁl\Caާ!;raߚ}Ɏ5*S]+7f"mA6]?^Ye*?Sjyr6"l�7?pT#ˣqՈR}mGw§ɩ`4}~6]\\0Qƚt(Yǖ4ŭKzutCU!^F- W(K]t*tW?v+0#/
    ྞ#WfەWwMٸ]ZW޲<w8wNltSTH+YJ}Y]UGs239)ɥq_�FwON`ZVmDVB0h8D˙T͘H9.Q	l
    \6#?ӃF 6C91N _Vq\~=ߋ1Cp
    #J{Z/mW෥\G*-C_,?G݆__Ji [XXO`kԻdBB؂K΃WkˉmV$/oNBpE0;>|/벯iht><+8stzmw~q)Wyڼ+-FwcX ;cB0r`?Ȏh;|9=?�ˎ
    c_6&r`7#.9'tE~fn\{+~{`N,_Xv�Ͼ*_iϰWӝ?^ȱFXh; Gtd;fڝ'Wu~u+XeV|]+oPa5[a_.6ųCg LB;;Ε3gN6[=��@�IDATԛ|7d Sޯ6P_~ 4/OJǚi9p ߙt<oco4VXw~]2\Ѵ"<g8s3%4?¸r2$t|<x⮿a%!![g8;E}aѻW<q\~d5tG?A?Ŕ)&&sĿ+WeT59a}:\1w\G`ؐʼWoOM	@~/>97\37Fx|.>	ĭW_r}ʘF4~Z]Y~hrjI$6;U=PS1ƍ/i`t|j2ϗ%/ڂǞ7&˅�M-g_/'_շ㖟_d{։6<~uז=sFCe7}c;MzkK}[rrrcS]OXW)>_5iW/_|((JCeUgˊgHXf^RP\]l|$^H94AuexKu@bU\
    ZH/Zo[^`вS?Ͱj\`gO.@|/gj9p?*Ii�}-K'k<e6L@TV@0y=b0[?zϳC<*͗bNL;#<r%ޗy4q<ߙ+\@xa<zH+9v4
    ޾)a
    /COr&Ȣ_0ώo
    K%CЊr5 2&3+p.KClБme,kKc/# 
    U!N9X$L
    q|<'Y%&?1qaYbgɃ;>[! T	9tu?04Pש㞒*r+	PΚ(ə!΁T6`g
    vd#Xɋ޽{nM't?QJ8_d`QnkqYf-
    Ӆ|g6Wv8̙hZij%䄈R**2XQh)ۣd*b+|GD(
     /{O%"+ӌh8Bá%V΁;~GFp
    ֠j"Ny㦱*ɇ1@b�T>(AMQuV]oop9k@]yl|Ԉmlt*]<=Y2.,_jOT*IhyK@BBjò%A#Gxnv="c4YSαo-.m,9&p.א_A
    ض)1~!y4_՜JGDDR %Ŋbݙ;
    1
    ӂD%SqE'3|>PڑI_wr밈!G(cZa\TR2,llJ�<^*X&_NzCv.~buj{J[P.vȖ"qtSqU
    :'tA4cqz8?/y72ʊSʤc{]mp5QyR<_bk$-4*,|x-.!>
    g`;e0W};DZu#=y2//O32>芊JօB
    \[{>BvUQR̬r奔N9{1=q?6VjV!i|8w1ܑos9&muRUo5P"8$X7PV:HmbD:kTyq<O.&u#[0P&[_iI",$e[-N={Ygi8YqZ,ZҳgO,l-Ȋ
    ٓ=4J&F(;A/
    y7L,V6 @|POf{`0bD>h4N}E-ޗ3WvTbͱD:'Bϗ=j=d[L}[JQKT`)vx.[ϛv?VWwQg2@V%(WQTT.(|55tY^ -ip/NUa\U]`VT|E,?i d0 X�
     7{2q9'/E-Qb4)˞K+-g\wMY&/OK%4RFRep\C")\did@
    K<8cyPsمzw
    ~\uV:FL@WRYYGGCphd%znNvD�4*K^:kjO<7wΞ.끁k)I+ݱ
    ?璯`wR#|fWE#<&Tݯ~_ʪv2(`)nC/2$
    {}99irlYѥnPuɢ:o
    BUד'~{y'~t|wr==8Իʘ7oDk.3·Br
    NFu.‹z'}5?4Utv]k87:f8p
    x-8-Zضw#++K	BFR8.Hi{	Mo{MqOޝ#}]
    piZ.Dds
    F__^r&۝&=*5``nFq~Z5"p)Z{N=wJ,oЦޕ<J9q#V»=3Щ/S]g_\!
    vGgͷ:L]1lnn;OӲإuZA@4ݲ3c̤d-PIC->kPxNс(kID$X@x<å9Yyqԩ,nȀ
    >.O
    R9J<n8Z-吼IA4ƴ[BZdEţ-C=_RFq*WXm̃qoi/jpҏ8Qq<j
    ?CΞTKNJ+]t6hWe/bPTI$"N?s}P“_z:]~P'#3;rkKԻ|
    gR:O4?N>hʀ3,ElYH4",,m$Mc>+дD4wOwͿjOʕyut{BE"P|o>AU#$	:?I/Bf%vy?q6*LFvwQӬZmwmAk>4{Y\C^䯉IM|O5?|髝ıU岗C#2qhiiO&Us2a˝={'VuqG$Z1^])ڞO]<@>fZFւZ1u"ri
    #�]-bhXukhò:y`c>p. 7?"HT%"!y"Vi,rzP\x;~/)[cx%5}t_WuYr侩?KV8"0 {i-	2g=7Cxk;J]*zIRtSvy!f2]IDq-!=`;:;K	y	dC/q(I&V(;̄IPCOu]	{ǻJ>>mL#W5w\
    KTPv/~cw4\kKhm5_ x85'1w*)7%IxpVڛk7<	>xrii0טֳ;^]iH'εܥ([\4s!5>&6qVNҏ;Iv{FcnZqLИkx9|
    m]9$c}.yp
    i8-e<<La7Whjv^=o@ӉKN&ZrhI;yDߢ$NcVBw=u6>UHbn=ET6̽܃g0"͐-_"5bKJ>'[Ӻ4rqi\ɳݹ&,سI˅J#cl,lԱ4qI\6&ŕ[MB7>my4u5>k;YAl۶mjۇHt'aangWpΑ]uF;(#D-mÆ
    2d3+uCwǃL.֭[Txy|m-1ec$
    QMlj-sE{=C_>'[ʿ%i+Rfȶ5QooyOhU=<Iq-$u?2x`enGxwOeeeغuưl)oB@=y77oެ?8HO׏ݚJ4$Z[.{x�5m:s
    u[xAմ佖oLhZʢî]T;4hPTKs	>ݞ{?"X={iKն&!׶<$lKWfo!>y=
    	˛NhԶ_w|hz~vG8{)E[_6XOgN{aS=Sqex:;X;ǩ±p<T/_86Qwmlx}*=&X&Qݏ	;U
    觊	A `0A `08&uL
    A `0A p
    huVe8|,~$YGRӱNZ;=y6m7DDwT:z_{z9U|W:JSȣ-uQhS;%AQiKZUqDuds5rt||:2Lc2uy:T~C7GDǞ~<dz(||W\z[0A `0A `0ڎ@*"ًLi}A `0A `h?z\,6̻R:F@	%`hϻs<A `0Ad! J(?s.ΫEwPTTjuĚ
    ضLuܺ1x=kWuo'Zh:NZ\fW&W2_k5xo+-x1sxe4\ʇk:{Ziav?;mw.kh)ǵӐp0s-Ӹ{iN6`ӻkvӳw޻pI皇O髝UW{|}i]|i?MW_ݥyIj?{]<]tz8_⺣)_u<M[t=ܻ:{z	s}v]鋿?yritVhӯ=5嚏p5^kϚKu|MW?itxkepMkfW	皧=x" $$DݺVt)A `0A `0'cT9oA `0A `0'+Vt `0Xhcє `0ABU`O4A `0鋀˺ `0A `0?YA礈0x۔ ?XM{? `0AE͞={{n$''d
    i'jkk֎8
    g6A `8hU@E>}bӾMPQQa0A `0t8ZEZ9;\)~`ѵfX)<qI ׌FmLM}```О,/Eh9 `0AT!Ъ.LbD0v_`w­5_D-"hT>Wa:PHͻ'yi@$d{t=BA蟜Ic2^RNy@ړNr2sX1;ٱ2A `0,+ہ҂ݯދ
    oo
    }uJhTFD	A0eNv0Kp#Z:,,40D B`#
    -Bu\:(lkVZфA `0C]&|zsu 2QD}mݍ#K<L[‹[,O[y723c%KƴiJdg!!GMiV-]GqY30 %^	|T.?f6@\,^9VgGhN6!:rIA?gYd&+
    ط}f9z#NfXpaCw|huUi+sĂK8wDޢ!5y4ձgLp&Wt^vzֽ4hzMaļ'g+<ɉ'Oۺs?}FbYjGb@yZJ
    p%OE&m.ḍA `0A pK@')Ij	r~4{u>Z,PUUa͢]
    v
    op>-H>UeELJMBVWE5뒂xg"ofLSu
    
    A'6}=3D1b 'jɁ}K0)ካþRe.Y1/,GBF=z<9pT+JVօoqrq12`\K-G‹3~!4(�hƁ
    M\%8Y6 aW1h÷N夀}-RA"WX7x2,xi
    9AoEP\V4dFụ(de!ᨁo	9!hmgA`Z/i}	>
    [͗\khAa	< ]_B۸.8NwK?dw`#vvDP.e4LH>lRϚ3A!qd2Hi8A `0A .q~rީX"dC!~<>D]#YyY	w ]BAq	]%=PQV9()h쨘NM*"ҍOEUi!Ir}.޾c^ <g'rGRS9pA9ZDu[R7%EpT`8Dtey(Ş8RTr!c&~yIWZ	wQo@x?W}PxrC=b8Sio/T"co	^BR%%:' !.`sP`=2D&kB,y5~NPk`C@AVsݰXK`U5)qQx{0UQ\V_ $&@lTrQbq
    A,pVq䵢(EyGnݺRGs!aQyyFE}Q뒨²EGru(5GDdW'(DB|s<&r=RDD<		䀣fp#'ebv(.e~٨rpBR,7'@23Pʶݩ3"‚ՄnA `0v!.iŴ]yJƵԋ11ʄ?k*
    QT\xR+ڊwf`s]S@^&-s^|^L՟⩈(@(gglӷ=_p
    _~|
    *o,YNxfֳ8kxp5Vɻ"ZQ8.ò?<ۘ܇?l"$=1P|Oz	(9F}97|5=x)xe1}z<<ۛ	YݖUU
    E9;^z-|
    BJ^o
    'tΝ:xz1?-Y=JAvv:7M4xmkwxybt
    2`;ooY:d3󯽏!Iax~BpYx1jH^ƙK zyfLMp]bؙWHޞ9S}k≗Cf#&Nj#*!G1GRX?$^x1C8T|O_G#ݗŘ?=lx>K?xᓍ4q|/
    Ͼ7Y6b/W "3
    91'_ER'>pֈjɚ&l[A `0AK@o'(:窮*˸3rANaj
    %_~۟pyq`JۇW?}z ,'"|S2K,X~FUMK-ET;qC@ <U�W]TŅƦ'ƶU%fz>pp%m=Ou=bl|TW*g	*F	8(DƆ]ܻV~ί\qX߲>$:b+|+AMa&\U,GU]UKA
    P+TfoNpq"a邏p8f:~sݥ0|TWa5J8u2T[A﯒"U΄~3;/Ki0$9+}g^_]:w<R*^⤾eDd[*peq.>yο}Styg_Ꭻf71̜
    `6Ws&#4\#:ݲ|xK߳QbOP/'OCG5V~ίOi_KYo-@.X6Ϲv\sgcסBUbop>q%3Q
    h'�pTWXqTy߷cS8O?^A5x{
    /0")-Se_c喝=;V,T	/	TxVbˎݜ<"8_qԫc0A `0%�]>'%-EPBq +\Eܳu܅�Qݮ(FvkQo-^YTiFRx:GbHOGaKPkhckLR9S9B)S{N8r05T7pHRz-%s0jIOVk+/coOGd/I+Q%\bܠxR@ߊJy.)>תŹ7U9O=.ʧl߶E=k0>'U+1tlüeG
    ݝi�p>j5AseGck*onLϺj:U?'|Gx-TGLR "]`Hh>RhJuq㼳 }ts+zu~>Zߛ9o we-pEKo3!]g5'3QUtpy/7,:ߖ�!xwm�A&?OU~|؁;Qu{-DH?nyAC)t$w
    G:I	Q)ޭ†Z
    ȡ[Ə@}{yd8ӧ_
    TzAy<-^
    b#Fn5OynFlBiҩ
    P̏A `0A p"K@ׂdxJҊd.Қ3;
    eW}tFM|2B	^Qk}-
    4NO|BbUBp԰չ:/f'et(rZȕ(zߗ{x(+'ӲZg~<W	Aj/u^*#,xxqĻSMPyߥG_յBj]Au O. Cș$uTW^`lqv_
     DrK|u?y ,<ե]˪{PeZ>r@ du�ՖSa	/-7J]֓@s�T𝱤hu4V*OFa!c);{$rc_“*u[(o'LF_+b1S?×q£0i%51ޫ*x,Y_!BbʻF'W#:jU ugmn2V_"/l~>V)$O�&s~[cW9FD>5ʫ `0A `K@ٜ┖H%QK"OkqbiۏchK\t|L;g"Pw2J}\u?TڲzXaQVpUr;'0h“XWOiJ,kK뚎-¤XnN!/c4USñoGgl Wt5
    gUny'?U&Ӻ$2C;RQ0
    Xb-F]ѧ@%LK\aIoCϤO0~Hox1Z'2_`�վ'˗`ڵ4`Olہ.4MHa݆7 XBumbXv6IT~o/B:VZlݱゐyPv֙?mjT<|ƫѳ['TU(<&8p5{퀁�dSh|w*<s^]􃙘7]}1'?vZRR2ef]rĖlgp8h-&7}3щשgOf=0.SZ9E6Lx$k1
    ]nHIᓦ0wfb#-!V
    ,+t+7n";V+P5iP/-Yڠ`-.ߟFJSAcbq}7>|~
    	_8o1f`2XٗW͢A `0A;!.Pqo¡%e/㊮#(dHq.X|OZ
    fK_F^-	|sظ8i>UsԊhS
    yCF>MGc clx/WާP5[Ca]#6-Q%El6އr3V߉;2b㈲SS	&VU4鲥\8«22u>π)c`O_l3}47edJZA5~jk˸?yW.gCJQr[_,)gcguPm%v-D.+Jm)'Ǜ" 4E;kGW~lSb_Hh)ZAZ</<&>x_-b#.Õwс#H'qx_bOq~/x|:G Ϻ]RVE;Cb䫯jٝK1ﯗ7ǛqïoWUseTg_C3?O\l^VyhEρ#p·-{6"h=~ScQiĨΩݐAM~f}	HC٦&o$;E$6;EA `0~kh"TVV"%%E|IH|Z1_njB0zhr{wl݀m{o�Rs-c˖΁*!aH;�Ç@%9_Rb@AnB1v`'Ļ;?]=vo<3}zPN\tcİRǘbdU:ݵedAyU5;aHS1F!)>lmi9#R |dJ6UZsU^
    rsO[k/+J'zMŨQKnF| 1{`-roKI*mqP黙WyN%cؑĽa
    <cÆ"SZM^f-
    *<0vtg{mHZ(_GKV.Ǧ}U?vu^8q|jt
    I�q1a\Ŧ;)AV/>}WnOwGCD,kJYi8=qa~ذzvXDK{\y-ӽ3׿[r_Ip˶wflض]`Tŷӣ\߼isQMu9!HCk{v`Ӗ܏>=C
    Ghܳ
    6nE*kxL^72swf+!5AT52Z{^-I)A<cP͕k#CD5ҍ8dzjЅwrO@(됑SԑcѳkgZNwNa28)!ׯǴiҷBLVA `0?�?J]p^-+\
    6&ˊV
    >\E5.q></qwדGt50)L(Ps͜齔<IO^ !rN@Zj>`J'| nsD[t50od,{r/4KZ)U1	\T}n}5D'٢-fpu-a�YTpoo.e
    K2B`-+k=Qy{s>Kȷ<_Kp/+D旲Xe,PI
    '|2LԡW=K%|SK,jȋ!xU}"h
    =y.}<<Iy9jWğWz`[K΍73	k[GX>iRnXyywKxd93TX�Gl .꾴AՆ{&[X'_g>3l-pF@?=pi0A㪸ˠV;%Cҽ=LDZӐpt<ۅ,ygcXOK0,*ºS~RBī,nEdAB/,jE @FpWp(zZ0+o
    n"`/BijSuTg-D`x,LWY'mah͵\|mUU"r*7uAɛ0kZ)ոuϸ:/H]	j
    ǟ{u"$TU=YX=I+rK|L/=#U퉗%RBLD(ʯN`_Ъ859cSF"15ᴦ&�TkoYվՃ}I9	ۢ)	GYufype^5:A\<9"8ɄLT\BC+[a	.qe*5ᴯL'[elj~_\S\g[q--UDl?tu2͋k:\
    A `0
    jE낸8%~Kt\}մuSt:LC	\vg+"[hu0:Lr@ide[x~u&Z<4}Ũkc9&2w:xX*rU)X7;ƲkzbNUy9y<Xצ	I#l9F{/%L(i:M4
    ͛UaFB.GU+x=G0ijzw"L[¶d5Jlt8%7壼,@"=qN_g׫ٯO՞F%\3A `0t4+ˊ༥0W;a퉫yiJoI"8:X?Kt,Z{M˺:yiوxkg}4z%Yxc=Vgc\Y,'0>kgE0-i\y0W皧Hb@&D`*d~5-MC_\tXVjJK{-wi鰖[5ͶiO\;}}7A `0t+( $$YJ]AUnYGqϫI+ix6s թԞVYEIwe_^j+}_{K^js/bDOѣGh\O0Z/jۢ.FWwzEVӗ3zgX֕*%}kuu*w5ioJUU{ښ`ʵ-֕R[^H[q\z[gNH=g0A `HH\NN%s
    "02Dq"Xp#cK<qN;]J<^\+Lb<xPY]ʪ9}weh[j76˶ԕnc]ܵMW_VW}odpݸEץPc0A `8
    zddZAC"Zpdz`뉦io=}d53,,h:-]qd<jr~-]qk\=iWӞ4Cyt=Q[C=q^&
    =T-g0A `8.2-\jEX_}m�"z"NmmD_D]E^hk{=07WZ׸'욏&-Eڒs~m)=N[5ofo0>\f)'6jO9Fޚv.n:=aq#xҗnKkA `0
    
    2Ny۟mF{㷕N__BCCQwFto)[RXK˫؟J籮>{=}[%NKis9MZj-w4]%N.;?]|iqrm/o&A `0Ad p\)Qh}+,vVµӽ*jt4_mG8vy~M44/M봮i${.WY\Ow|<DW+O"6PU͸Ez/u܋scWyXюI85-{:y	lAVZUpb-y17&d#rxrg.A `0
    Zi͛SXJڏ.Cu)۳;|<ꛝ/
    2DT
    ?Kij@WDӱZJ%/銟N+aVeTk��@�IDATוWpq9J#¡a:З4ޮWøPuGpqهhر*qE"h{J#+}:v0MSs%LhKKr;9[“DŽF-o/bbے~h6פQ`ǦUc0A `0(8.
    u,`65w1ЧOoZ
    u"PQ(GQGYo{-.f[y#:%4f	Y^^޴ߴ
    )
    T*ĵ<*r0#ŽEq1IT"+$)2
    <|ʏ�i!K"~ւ0?A
    8sc㦜@0xTհPӋ魄d栞5-=ԱdlϺr
    55Eˏֳ=<.vè\6ەLʈHMMW}lal9/q%Fsj߲]ďA_QöVbg{d,ެwB\
    A `065;GF^y}8pxi="csr^ :,�ā| %9	G!311./|b`GvfFXtbƒ$&R
    =sH6=ߠPpVHJI]]*xP		EbRw?{^UuWzq�i"{]y(* *OQX@((]zC =nڿ;%Fs9SY3{fIVI"#.Q9puwEiQ.uBj 3	""Qld:u^]Z\K#(!sFh: (X!aĻ+R_
    c3k!Eϡ6f-͑_X[gX]
    4		%._k{Z %:JQ;|P鳧[T_?zFj:%r<._DNA1]=
    owgA3p$\OF)yS98!V jx!/3Wi('nG
    Zbc0ܝDt\H'�?ɩYSHVΰ67FRb"r
    E#-d_G[T(
    B@!P(&%^Φi
    &Dx`\^LVd#8;9#e7uQ@w|X;O5pp7x
    prFrb?/.v@Փ:}GcqlfS>V)"'_OV7.-lmEqe�!a3PG7~GWdE8`¤!8g%hQ'&٢wl/-@H/Î=}8ph2*ez0Vt̟^"5Gԙ4fV�`k##(&==ꬃ/CNZOr
    zaW\o=оK߳v/!*6#&?۠~u/_~vrë�\Пx0GC37}5cqt}s&os|w?_~NŁ5ݛ[HS1Hn;DzϢ`Ԉ	&P(
    B@!D	:ӚeoaͲ.Z5lSk_Swl!rm3ѯ-\1d*uj3
    ޡYN4ei:MZ۠v
    wn\IDxtôY1{nEdbUᰳFRlO_8w="bGW>J۾PWOW?Ÿkxױxlr.+۷_fDم]@UBrZuO0
    1QX,N$,]@Թxi]63p|#MH/?G~xp1)_g @
    <44	1rB̅S0m$y"9!f}wLo?9ŌÜ/6AH�,i/P5fu>.b&4ԯB@!P(
    B'd㵸N꓋EFu!Wr4lBDv!lƳyٹԫf-Z“,MlSiͮzݷG7Lb"YQLe]	׈6Х9w9Bt]=.\կ|u>ǝ�?Ûqhڼ9:vL~Bъ%&}Mשn:&2Ě`^laaQaEWtϽ	gf1w8ZR|ԮBX;{cĤ'oi|;ѩE^2r/P]4jV	fevgD2z,:=ҀA~dv'n<ȵ;Rr`Zm bߴ}>>`�JF$6
    ց7Z	
    _䔥	g ⟔m4GHp-ؔf6\lFѦ]se81$Si*(
    B@!P(=A'>^qhܲ
    *\i7V%DMLZ͛Y ]H]raXdDǔ3ZZۂH
    Gbd֋4#JbmZkZˁ˦'Dӹc<+oWy	o;᥯/lŤ0MM̩6A}6h0wFӦ]EQaYV
    }a/~P݆?hܭiv'Ƹ&`m>(GoWy/$	5tC?c*5qDhNќO!}k/|
    mGbهBȧ౑}ߏ'ñ"m1n@Xrz˅&D޵2e7W6£`F]B@!P(
    B'D,rrԉar8xlD|.VfD4 D:q';$iEfڟ[h-SUY3.!9BHѪEsxґVrF%;Ntla۔6I=QN-S"6 c$֦*cٽ㢮p6C3+4h�eÚO3h߭۳:ڼ)ǧ":2"篅2#ߏ<̓3:"L7?=q#PAux4h#\LDa-
    s+18y(錸V]{~gZhBSrF
    6 z\=CÅ6;.Sݖmaok\4#UUt '*ؾU?
    B@!P(
    ;wA٢\
    |W`WMΚGM"մu :#r᭍[ѱRߞBޟ6Nv)HS6ǯ11ғb_fK<TH{1rWDzYZ7KVD±]9$gb&Gr%R:A䍙1=<7}"1)WNߓE'999pr
    3"V҂+"]!PJnߎ"4_y-XY!\K<x~lm['Ѕ
    ݇U$Z5CH;-yAX)%S3.~_x/==֎4P1mTsx3:]ghLzUJ~}CV-mhp5CfF/'/N5		,$qSEdt6]ۄlAn+e<UP(
    B@!P(0"w՚eH*C.Fg>,%MptHLrұT.v戼r	1ɰsFmw۶faP�.{ZKW+w@PPm	Y‚.I.kjJVD\LQh2*ՈHHCM:j-b((5jКdïv<M&çVm
    bȫ(XQkA0.ƹQPb`x9BWبH19y0]=I C!M뇙K`ymag:-QOg:Z.ao7:V/a!|k!V
    fE:f-~5aZ1}GE<5,uuDQ~ ֛Ʀ[|ii+WO[1tt`pE\KLF`E~t[I^.]Rȣ6N4I�/Zj6H6OQ89/Y̓CvM?2u&]#yWaIV`XQ�mHw�%{h 0x{{;Cr(
    B@!PMܑ 00PNnjf%$'+[NŴ&5&`B.ⅹ)X-,Z?C:	oɭܔs.ˉ0CnElgjF
    b't#xp^$Yf'".–SZ;_BVw&gfTw9wh̜dx^Bm4	!ݍI_kbbD<___܇lG)am8Y#)x	b5߈KĹ9`Pv~=]h:Yi0q_{F,W#p>Ј.qE]N1RiTNa@xLcuw9;<J(D5vz6t9h<rmk:JT5~It]*GB@!P(
    bLRÖ"*ŤSFgelFPsr
    5Yu9/OIGK/	[$8pY눵,Ztmg[/R5v/,\Y.arR.:N̈́x,^!uGxsA9}E}`hB?>+ݜ֗ǔQC`E{6 P[@&u6*e9r}$ [<y@ҧq\O.O>q<q"pEc\ڴl0^ݔX߾JU(
    B@!PܑӺqhʏ[&e@#lzK-:
    Fn2%ۺiyy#,>B-\)e1,^ʭ.!|yn 0=s*RߪJ-@M1A䒏Z3ĉq0߰l{+߅|Z*VKC
    K9|ƥ1<|h(Yԅe,dW}^psHrް*�22ף-CB*ye
    ]r
    yeܝ2?_|Ǝe:{B@!P(
    ?	zͮlZʫ!QfHrDIWK@SsaUIlG6_oWc}neHe;/9
    ;61N[gٲnuK=%t7yvi RḔީen#9֪Eb~7U]}%uuS,Yv39F3
    B@!P(&SpBttXS͛剉([ԙ3	)"7vf ݈9p^.+#ԴigjXf9P>dz?2˖^w+=֓RRRN[uJ'Y$˪T`I3>9ɶJP>5P>)~x_Uücp+}߮Xnc~/K-NcXjUP]_I|þ+c~a?u,K_qri<ذaC:VCoxP?
    B@!P(
    ZM6hԨQ!b�WcCW*K^Yǽ,2l[URvIDhBu_W]{)s/yӿj[ê_cMan'ݻ+&V
    B@!P(
    ;tGGGQ+-Msl=gìM!~OfPW(
    B@!x-Agm=eACkZuve}333.
    mnت0M՗]
    RCUYj(ܘ2xqzV-/
    T#Ӫ˲|ynuo(caي<H._]܍eBVoUeƥ
    1L37cPx0ocư\P!R͵8
    U
    ==P(
    B@!xX#AuCA4?kr`d`2QnZVʼ{lRKM"w2n֡J$]ξ5"֏U[WSnw]]_?)XXQ1.S;K⪎43|(g?ĞP(
    B@!#A#ȏRQXjOooY_oUHeeYHHS+{xy>Ѳ~voȀ 2^Ӈeȧ-a퐊R]F:c&*eNIJBQ1=`aZUڮY+ʰ\J7)‹TȪLWs%ȾiS:ǻ6g>NWTWURB1k_Jqjl1HʋUjMTWoHhCA:ƏVVR]ke5*%wT}Q~
    Sy 7J,d22;:N&OB~v/j0l!
    #c7bRqOe2RHB3mD}2O.Y3,2'T&uP(
    B@!ܑ
    '?KaX;5h'MÝ e0q65>^vGI>xrw"~x7ql9R>_e3c׃PU76�ޤ?•,cf,kIA~+49OLlliF
    sm-֒ n>|V;[+!F5iB!N9nGdɱv{gpqt܂x_v #BVb$~i: _ke%e(#wBƎ@"`p[Y;�{􀻵1~3Ji"R3&ڼzC?Z+NKĞ_aoPld
    [GW
    MB}q^HXr@	"{Of )|V<ҵ?:l$"Na柑Wj[+Qߖ#7+f^Щ
    R#7`ĸ|;]@!Caghm+~?tFf֭rs|qɣƬmΪ} y'ILy֯'8U!&(_qb:F'kS..lJ˺ehF!CS\͛ĉhEC+I+aD_z
    >F?~uy`YcmVɘ+է"ޫ}[Ů(1w#bbTP(
    B@!P<<T|k/&"s&7Iba$TsIZjwx񰷶$їe-|$FdcbɤaϖX;?R|/7U/N2ZOD5S31d2Z3
    7"yؼr"vXз[{|6sr"[0sZ8yӃ{uD9u-`<۹	YW SGLprwaϟ(5ɘ:1$Sb߲=o_x	3l&\3b_T>F8*[9gïfM6	ӧOG|N)Wۀ$?
    1Pᄈ/$K}]o
    󁭕⍲B#^zu.fk{.UËt	�28AEر#'Z4ԍex	X12cGE
    `Āp12FV.>Y,}U6O]Ĉ_�1ş. ?^d9\ݵ(:6~B6%)kɈXj<>y$~ܱ<L*Rp-w]zBgpd&_N3?A8'CZ3&N}wccwCTXAIx>hdSɎGBϖ~HL
    ۹;׃+/>pUP(
    B@!P<TπFcۘKBu"YuH_~ݍĴx׬]:VPجx㒮Ƨ٣:w튚dM'>CGPQc{Vq}3-.\Ad	NPȨ0|
    ?edAB
    9uF`HXsXV@!0c
    R@̦&>�{z.܂)#ɔd9cBOj8VW[ު"Ԥz\n-a&Y̍5a=	_=�]wG|L<ݼhℭDbNb횟0xqG`xc1,}_EG"{N1pxLl[mw9'書x^g`xլQ!?VGmҨ0odgB.Z֧%&Ԧx{>={,v'&Ԛ:^͚ܰ<ǛwpWc(ߊ"ɱuF;p]}ܢP-eiXӨ3v.v.{a̓55^3;x$-y_PFmq~*<l^3i4uDQOb= 
    ٿb׉(GehʋOЯrU'9s
    cENȪ($D]m|$E{)rB@!P(
    Ç?N%$%:ZJkSpiX9#|0\uq=Ń[XE`ы=/>"ڃغj^I9:A7LYwqb'#=#STW"mxaIt=z*]\i,@R:]YD,ִ&"/]3mR.}.)7App0^qgG[Iq13C`x8x<C;'p343$ksgħPBzY^ ػypakZmaG.liihg)y9Ykʁ&jI]Z QFx2e@!ݓ+>[Z/Bx<?忄{3tF״zjOqgBUq-6VӮ-'Y9	]1�fx1$|8pmsWanAkR2Yh=sE4QѰMXݫ(1qDH-k佈<
    ~F~}㢭FV2bоb͏D)qa
    Yee4F5j;d'RMiID\l<\8<;s}Sk>@ϟBvCoסF˯PSo`Wz
    3ڳU(
    B@!P<<	7zC1[p_pr|x9#h'
    ky,2gC=umjaaxbp;xiD[ukOj	}v+Mػ-ڄwWs$M5NFS1imlKİ9i	ؽwtk9Lȏ	<nFHz+6_-+%_,#l"ጯ?}yEԻpCWL5db&APp$4i`UoBAq(CQn2MBrk2 "-4@OOZ_'[DHfIqI;FPb7TRWWZk<5`,Ő=z}&̲BO&2.c&lسOA
    ڐC>d/xf@о|ncD`2^WZV\oEC8֪->5a!ZrѻZ5Ox""!-;c]ۺ!owARH)y	:XP'1W/NJM`\za1
    +<t"^bN
    O"=kFUl%Ԗ�G~O~=VxA
    ΝŇ_ǻN'BmJX^DҽIGMƻ_mG+1j٩ظj1}c9Zz/֤Zinh;[ƵpduZJ5\w!ޙ@
    ~e{En
    
    B@!P(
    뿴YTn$!]A䜃o�xnRQ/L@M"3]}6y\K#"0l[Uy3ImkW2}K14k6\cxXdol
    hs$=�%6b)[])cDbܳy?y.>x	XQO'{5Gw{[P+d}qQ kl=6&WmHp&&غSfrr0OHgvvtr	5F|4cciY8fo-E?
    %*7wR`øu&~nQH;7 \l{
    };4֗b2KA
    _"ia'?~~W81z}"Z*iϚPck<Na
    'jD{nF%~1)`TL,U~f3:M l?$j{⛭{0OgY?C]	KK͌$F>>;'&&^~1B<9>mw�LwG@?$޽۸!8~Lhτ)/.ո$>`@KA}Dmcg0Cԝ&
    "CqlO%aպ҄.jp(苹q8{^8Cae|N+gO0abK>DH]
    B@!P(V\I˦A(C>A#"ƴcwEP|KSkC^4:tI$W3k<Ҷc6xmgq8d%&@@P}|˴X#vښLFѵy(%rM'U\'7NCCdH82x]!hڕ&s3@;>Tu^W5NB`G813c3K*gٟw|75-ن~E$Q8"qԀJN
    C8lW_yBgZGnahwu`BV&?f6~PFljJ,S 7o5j?N9/U8!\kuY65h@1*,MFиT9u;–3&L)6',Ɛ1х,lecҮFX4y3|>Ic-Bz5Xq\z
    ӱsf
    ɍ҈.?k({
    ORWI}H'\ǿ^x-^\gŋ
    jfaW7rwsGaL.㗰(FlB&ڀZ"4(YTBuz_'E+;B@!P(
    ÈCF[JGVׯdžaY /9w؄#/~D.,qGAGB{8/w=)p.,*@Eg>(I
    8v^Wt8'|[BWk53rgbSҟEL|/	y|rX<ff^4,G"61$@pÓ,-Ȇ?l]2(M'W%&֪OMĄСIo-Cם6:
    KtZt"kD`ݝ;`#[KǶޖ_^\̤kH?3[^G>l˾ޭ+#/޽s ,lڸnOo[d*GĘPO~Y))eL,mQq}Z5BJϧW-GO>$,Kw}II|Ա\h_<V7mj6$;y2Mx[=w]9->^n
    [N"%1Kg+mVO)'y"Dex�[șcbZwэF#KI{>;,/rgp9׆
    OߡmP7ϰh+_,0*JLJo<]3SGfq#$=8Ɍyi4o8G!P(
    B@!P"tZ+,l?6Gn+0j۽?>|`QᅧA#&Ih1eٶա9>31{QQQYdFS2aߡ/aFP
    ~-Aιztƴfm"lռ9)P5m	X"&}j&VkHDIs~>hk^3yhWq:ǻ0WӬ,ϼ9<Cژ^H=Ϡ|3еY}|dŝg_GcޯiC3�Eš!ZNאe>{:zҀߡznX7j}DVZJG%S<z56ؿvr|?
    bxXDiMX:)ugpS|E!nHɕ|Tp2	
    O@.p',G~|l,sZHVM]ЖXPnFLeZG2+U*SDȵfv[9bl=p#vE>8"H~[e<FK.Cyߌ<4#KkJ˗Sv~*1˃[܁M؝W{GsXl'ęۓֶAϛr8sl?l[E48ݵ[P(
    B@!x#
    Xikk.!!!7?Fe %+5jͿFBJ&Р^H_V3bw
    4jPv&fR^Ą"%*K?R6d:[Xe<W%K;O:
    -JisሌOG`݆%r:]ďO,>׽7ӊiXڻMxI@^V*"cřf(DbR:ѓ("S%e>uwfjT>`HF̛6<KA^bD\۠V`0jp--rmd݄�QԚkq<rkV/Nz	WBra7:Kݑvy'!?E>/!T&ی%[Em鈥iY6#ڱAAaCp9X9KG9CL|k"2ȓ!LhxWfn>9"ȱ~"VKHIςBB'DTX꧌L|0jפILS@ocybD'lϵW
    mRۭɮ<VqcI5?-ۀ^-hzU<Jr(13wѲ %:i<Kp]$8DFR,"^(yVhK%Tuvi+x:_."үfO`r̭[QF7xNSA!P(
    B@!O!pOd~+\#6暴uar䭲V/f-FꞗHԩSGER5dmU;*Rb/dž\[‰Z=Dv!]o	2ycA-1teuEMedyy!û68+WJ.FN0q*
    WȬyUe*hcBIc^+T;>
    %Y8J6~#3\>eo'V=^[.cM`9}&<-*&N$]XL4h˵wrs+)©pjޘf.?nXt
    }=4vTfUB@!P(
    ?=k(β
    ?0$CZ<ӕ3$&eiA3W+{qB?P5SO<p;nh#W/vQow^2.	h^jmڭi.
    IoްYgh7sZԆ[2ي)ve:J+Wq=~"a~t7AG:¯N+aagG+n''
    ymǞeS&"E|8?e1H+3WznQgMp#קsnР#QQWD{9TZޯiw»
    Y/q6)9^<y#s,٪d9Ƃ;EZ,ߋ@q%4K^!t"Ӳ
    :aƘkOɭHT7
    B@!P(
    ;ZkժSh˗/~wάr(?xOy	v9a)*V(
    B@!Pwꀀ�.洎XoЙl1֬Ő-l4>ʫ˖Zib.iW7绐τX*ສyYGz]U;7l+'+>/c4MoeUo?H_3Ŝ񹩯vٿ/?KO|~Lȼ7ɯNǨNUJӿQ1y*:,yemWs_b)1ԟn\26a_U}WyUk;.u|~o2Mc[!<,'hoIձC5r
    B@!P(%1{
    B\	7L:7N\3i2|g(DI^P|&LcI,P]92XX&LVYbUhkϙ;9Wb:]Yw&
    |Ϙ1vR򳽽}
    cX1fK299ل kOw#'W+K&H}zfddܫ0+&CRWRX0lG5&7-8;BGԹl}Uu,TŒfv+ñp'Uձc_-O۽:Kb<X;=*Q~UP(
    B@!P<LGMi)taɹ Lg:LC|y5LS'Žqj7dB@!P(
    m-,-IpO&+wÃi/i!C;ǃM%Y!P(
    B@!#Agwqr*U".*N+͂nl:
    V/׽K8MM2l8fEB4H.**B3M��@�IDAT7<<ZT~C&ُ\*6z6i!*unvÍpey^q/yoy%>A)t99|_wޗZDk;hb!zT9B@!P(
    @ݰRmw7*UIyHN9}[7!Q[sC{x07\
    `6&w]٠=5aM)^w<2߭e1nQXB1>z9:.sizc'q^'b
    p5+zI)^Tp3I~5]E>GuL㼆<}Ys}]_Xy ڕkO1N!P(
    B@!0 Lwh`g#}A\Ol=d#8E&t|
    ?NA^1-EZJ2]KDVNgrPܪg&Rx\Cq)WgPvE[ۓsg/L\pYCtdd	ê\:^l.|\r)zܚ֧Od5crBN`1;֏/.AqSX`SZ~v.G\Ena|N!,1[)d*_yy9/XkIް9A}{Ԗehux4J}qib҆{sLnwan6".]FvA)G6mVPmy+ަ$ "2qwALցF!RJtJi;DѬ6ғE"!
    B@!P(Agr%X1M|F\/ai>W)
    5I8^~--%z�<SD?B2S'i`ǁS(RV\s@~c+}:x$7Kwߔ賘>K:#*)rP+%FuXK8z6N<s(Vbl]ATre⹁Ͷ"穨C䫾>NƬ<7FV/Wf=Y_ʩ}U.ɐiiŽ$biW!U	V||/2֜Y8t.RZV˄Rz\q-O3v*|CyrZ&eXE:8?SX4qO=݁C'/UqުBlZwА'j-mh2)e䣔ւ9aߟBӺEszim8UӁˆ[m%/Rt-ƕKnqҕTz-B*
    B@!P(~KKӘl8-T1JŰDI|>L?Ou^X-;Y!d[_E-[Sl#7QMw/Mc"KҠ geБUD)IҮ06	5Ȣ,?~McԀΜs_st(/$l
    m"@GGřw&U}YgŠaAS4c/)-+ENV
    Niɩ$iZ4VfrcA=j5%_W*fp]QҩJ憫$\n7̮Pl	u[u$w
    JɚEWZ8{ܢb\	Qaڸg7r&
    5M\v9)`faICr#S6^n;#s4m&psJ	326D$ǜQLI>*ΐo"{@~Ih4DKӃR	_j~�:0f	RjbR2OWh9S;LL+}{=ɣSSEX{B.+"j9CIKJMRR\Ϛ֎+ظq?dtkY
    
    B@!P(
    %1_׮E:Y~#b#c^H'j-bRFAmA3uYYkн5ңñtX5o׬BжY{и}k`´XM֘$-pܧcG:]KG^ᇐ	wL6	-
    _}a3FC"cG@֕sX9s.6h(Fg">8zp
    oNuA5/lP^{_l&m`p-Mz|Q:8xOb?1lHx:ZOS	;f<<_js"1sQo�譯,wu1$a\@#$`_uBEK.s!ty1_#`]iւ9Mp}_sQsѺQ[cv\ttطw?v1a_a1ƢaQn
    }5'KX8x	YMCD!6ϧ%�.܏y()R?ַЈ{q^>rMDha=/Ǣ;4nÇ􁽅F`E.'R۾{D$Bfu	ؿeE0G8;?-Θtqb:|m�3{?�4cۑ0;y tǏ_v0f8<Ccię<I22.\H4hHx#1$
    kNI	_%.>bgL63mz;q&>?u
    2붍i?!,fFO;Ь^@cL<B@!P(
    CZB'3ffOo.vGܥp̚L0yDd#c^Uv&ƀгM(O{an:MH9vKuBif?�/Oʶ-x[libI4Oq>.z
    co%?{en,'7~*[PI[�^|fbKױlO򨍑{)#rрcD^CѸS?Iъ| 7*^0x@48">Dl,̓شz1EF-+:,ѽ?`gkEspM,x{/~.ާksb/@#lڽ_#,&qNQDryhDVJ#aTxwe&;5|q21f~n2x~)I䐏6XDI7C4a,ZbAعR0h(&mbLh"}
    ѣXϿCXк2:(sH?4_MG؀a<1,?;`޼G/Z|-l<'cP8rb5/=<3c:wň/B|hebo&M@S9"b`aОpAQύ%4,Хw?=M}8FIY.>]:l<1hpzk:{Yc>+>BȻ,fF4P_r/L4	]ZťKKcْX
    Sо@Eۧ6^/?|$bңOanX8l.p۹~xmEmdg
    ,u9سcvGQH~
    B@!P(IpEVСm
    u6Îo8:qxښaw
    ñ#l;|=Z+n|kBsѵK0qp.oVB	CƵKxs_d
    {i9gw?SVX
    6zix8!
    6L%^ŒW?ѱ?щ<
    `aZdn֢)9
    uKȭ8~Ə$~Yy;bLXزo~LOаÇxrB?95UtEi�Lز9dUuj\+Og|hצHO.%
    x%d+${OQ_,dڞlR}XuQfd\`A-Spr%+Tľmb;Ѽ7{y~u5ԫsv`ex!Zo-2j5sAvl݆_%)TbšJѵ4P+'jҵeO<g=y{b'8maNX矅'MtpGqudfݧ6.,X+.-L@Þ^ŋ>?k|%$edeV_o*ԭW͚cOvu'b,;m#sVۣ}uq!uBаa-k؄6PÆw"Ѯ�\O,8y. 2ZŜIC;noyv2$`miܬt,xAh,7 W{X{hPL!W<Z}UhJ)
    uƯ[1[{qY�tL1Y..*n
    B@!P(;A'vWZZD9噭>k{hjY9M'OLCgEu[Ž\u:mZI&0폴"Ca:ef`>ҹiip5&	\]aEgVNԆve/)
    Ԭ\Ɗrn.j^.%Lv~82SPhvuCeB1,eቩ}l+uXoarp1H>L}CDR^Y^MY[Ò&"t:Z{ՔsFh]r&%sqA)=,aAkjt<	'Cb02<1 U]4YYaqS(AZv:wm!9ǕZjZ\Z?~v^�
    [\"xl8;;q0r
    kÖH&+kzۉ
    I^{N[(=ͩXW,Py<\\\*Ƃ#:40G!k&7#qgsZ]�+Z&1a|	~4:j!(ai҆ȼE!MPfjO9&N5ѱQmO9nźxPHc,]:t{L{59[I2#8ۓZmhB8ѬMYIRnN^R7mԎcǡeO''}qDQٹOՄٍ1Vuj"7%%~}4^	^7OK)=h=}-f__@]
    B@!P(�A7h?6{+"Ny^$vZ\sSs\hC4sRFQԚnl$z&}f�a_bS@Fy$rו-B2Mh1"mEk]x3%x:<E eE`2IDjeĬ/ZVYF9:3#t
    Yi]nzvvEl\ oژIN-e결O�MXhS1y,*''x[eˈD[ҒjRYe&F{yGUt}@!B{ `O}E{W,k{W*Ҥ RI%;&3ޝ9sf晹뜩oj}M{xTC^/=tabPWsK/ķ7='Vj@ͻkib<aA 27g4!޼dޝQdR
    *&z-sZ.J܍fbޢiL߫<\[C)mZ~隺
    i1;#jj{~}[cs%t-r[6o3kt-ug7bw:i~_pӰ~wFDmlt DϾCqmwrZ+Hx0ÃV7ߏxY/[NS*(:'17᪻^ƺ}4	(Ⱥ
    <MRnНԮkҡh޷C[UK
    bwUw O`Ǒ{hѢq=dObFA61/V8syxY|zHNHCLKq|@Yv,
    ?=G
    @Zzr#B@! Gmۓj	jf3ѣ,xnv;].Zt=wFD+t׹%یa}0`[3a-sOBdd$e>:_Y|,/"z2M;%t7v
    :vkާ_\(,Zt=Uag+EjJrcνt{	#sa%{vߦ(-8|9#۷fb-ȣ+/~mI]?y^]0b93[f{S2e%'<L3f3HLeHx<Kx#Y0>_}
    ̘:ʳe t
    nk8k|ᇸ%X?+>݈IG֒ݚB^pσbGL݋}K+KewCOo%JDn^|CS:D|Tr4{WEљ,:;͐ߦg)--]*	Pd+-8
    J_VPMK`ذaJg1gW3qڽPE,YC7lvyq6nXGwg!vv,[;ase)hϗ߈iȣ[R·u&bÚ/G[w!NLgIK'{6A
    .O_9tOQFGs((NFa{I"	˗U@yC1":?_߱	[EE`8$z9Hځ?Et0"7ݛr86gٰ'B@! Ne'e]w=Fد5x~&^|~[J`P`{u
    zqphq%_/�x쑚\]뇨o[gM3s,M_{K6cǷ
    7Sygnt0ސ+Zx
    acf.TE~dѣ^/jmSpS97sAᦋ<}<D⳸{щngnp456LK.is󵝠E	u	yёGSl3*ue l:M~?`W͡zB!m_㎍KuN
    |g59/ȍ޵EA#_/'xxȉaڄ!(K7
    W3CcՏ_ggaڡھϿ;SG^T/ad۪ͨ]
    ó9.>;L\]<D�yվjM-7pM-
    ?@C=MtSڲ\gGG4ڟo:sЄѭf^&*boEU	<c,]+ 9o%ẫn[OO3�;uE+^|KJZ!ϫ;t7NW'y32k0Ͽ!~8vrW^E+!ho;<:<,\J	ǷDwǵ3?Upٶ5#qf)5+0N-6''"N! B@\aotHmW~b:U+u?RFV'!j!]8�mgr$xk5SQHK+n^eE̹؜FotY@v[O!fVVV4A侸0e4ٺyEh֟]~v&2vtW@+?gnow_c.h^N-@.]^O%C1]gօwkǖ..YX2:uPK=)j7XKny
    _0}ChRivfs1ĝ6pJ~-{䕨]ޡ׆U/XhOuks1stҳN+lK%mԮ5-~j97$i~ѵKDkQPj*2HIa
    K蕴>-[qMf!!)>خ
    ]AۚVȦA!-ѢPNm-[buU=<Q<
    H/Ytp	@XPMi6:D. :h>'H8JC13Ct \V.u;t%e4ҡZj-hD'?/e(Fqа.hon6Oc>4M׽VIZz
    KѦmB;~}Z	AKt[0<<:<Ϸ%'%t\R2mMm"T\)IHNFђNqlM4,ذ̕J߿}S
    I! B@D\VN1g
    G3JR3ȘG$۸Se.)))S3V5ZFqڏ?܁+uj&Ld.k(5õkƅHY['nn7ǮS}*@/7%!3s\nYTGmOyW\^m*9,a1L@Yleq)ƪBφkZ/-5g~F?6cۖ]	)g3}EzܲG)-7\
    S?1w! B@Sa-6Mv0Su-8MLOIuҌ8j>]-cwqɛtSFigƃ,shfm9<
    mGწ"!N3+þ{e#jX<p!u+T4?ѡ�8=ҔYq誸<+syX~6ӼMnk|||Tb;N
    ֨=wp< ܙ5oő:kG[0dci:0nfVZ\ʲ~u֋cWz9:c#tW䴹e6˥p;u~?NKpdC9lYiv&w[]tZ"B@! BT ФΝY6عx*8݉wKC:gӓTHs49xBC17/uz=k4,o=Qv<k368i]SCDhw	otr<;nVw8>i1I3u>~uOָ:ƟqcaXCacygl#:;oy
    //1/N! B@Z ܳg^(Óe?4:k~֟V<U2G_K>uG`3YYYXv-&Ooooy4J^6LqU6z8J(\F%6\3gXp$G^e>]SaZ|ZYXӰe_4c6^V}M0GYgirn~Y#iGiZW:O-ߘ©0YrZUBg'6Lp<n/<^
    ӗB@! Bdhrz,$O3tW9iKjVp\tpQE8ucƑ֯䴼|
    S�Wp(VwI{?.yB@! h`,%B@! B@!phˣH! B@! ?@{y^'!B_E[k3t
    2Dqy<<,;NM\g33zlΗGg:9;B3t~
    2p8YJ~DU|te;ڒ3}:hd
    v8:}6=J>eN]5X+yh*%@B@! B@!	n#zDB@! B@lf>--
    `
    ! B@! ݡC4nܹs'-ZVWB@! B@! �O~k{zڴi@g&gee%<")B@! B@0Z߿Q Mƒ�! B@! Bhrv?)2! B@! Rڭ4ЛhU"B@! A8p>\.hlNT:6+іheOD'"#arHwGV[GIKB@! B@!p\	W\! B@! 8"b&B@! B@!p|	~|v! B@! GD@#$BB@! B@! /1Џ/_.B@! B~DDH! B@! % +څB@! B@1Џ	! B@! 8@?|EB@! B@#"~DRV0`p\tgzi[)MK՟YdOD4]c՗}s[Ӑa8e
    o()$cB@! )MH5ZFq#9.~V}&;,_!5z>h\U)U2rҾz~;X掵k?4.YلM|hy3qӳ8'%ꅀB@!#B%ݭomv9JC9S+S%)
    @gu:M塩?PFQ:P8Qg|JN	8g~N#M<Ǚߤ8M! B@sM\mM
    ,7Nҹ{6L~UeGqy:!<$yGy
    1ApTgMiC_4h9[6: s):]ۘ.PFew:.hy2KSX2-Yk}+J.,G2խ0㙳:IG]:
    lLNaX\:Z%DEM-Gn{uQ"jX^!fyqk+Kw Eehpu6^kq=ˮetUSy{0G}z)EJIB\rZFD8Q8N	YPؾMy5fNוZZV)?.ņO:>^[7QWgڏGxZH{k
    r2ZWt
    vZTu,=M<}8ܔ1۞pSZ™y\}uˋ
    q(uC=כ3`kZZ>B@!$h(69O=z?f>8||z!<6kv<8Ԑ!36ٕİaC-/`,6CW+*</�@z^�΢QOcF[})kYQUK_̎;;uR-f|v5Ey39b8f%<6CǠx#i]3e/cӥuZn&qX7d_~%+"3DAvV,Y?-Fb!{U۳axoPRYSr]m4g&b]~[X%.3*zݹ\}1GcPkNebXcΤGꘂ4m=Ք7W+PhG?~677#쬎a_ee>UQzG\t(1gz�Q#.ABfS7ž
    Ml,Z@)5i=7O˟,u[]}RaMeM&oi=O.t]tQ~DR)1{0hP<SI]m[.W
    tyqbvfx;AI7jepy~C~a[Wx}Wu)Ő'! B@	4ie^\ݨw['	#:1pBgv>s4=1A;ygϪG0;|fG}JY'Y'Fr8apqC'SO1;.R@tnv&tZc3.dr@V;BBs4/gL>G=/۩g7f};
    NĈ1}l,2/=?~]muS_-͔Q.aΒx
    qB3
    #ú~.í]rS=R|l[f
    tԽ/0(6D#mKJnU|c+JUc7u$Dg>è}4m0ICسu
    Q؍߃^]CJ~w'[΃i6<+ti-槳xV	ȼXV
    vڢmG$?6ʓO׺<σe9-8>|\04cS":=`{`V쌏Kfc#f(3jb95=˰֖a_]6PB@! FFO(%ѿw?FEMuZ͘Fcc/*ZyW-¶qg-`YSii:0Qqf%hОqD\^ZdU?0;g& 0n + R3BѲE3TrبHHjA>}ѥS2d+J2t=�OL)cq1(*-'#؍F e3$C\,D6oGDgš0&2;[-ܿ:uPi?1?g#&:	)1\: iyrer̻vF
    ݓݵ	_oe!*&^aT3
     x5F!пĸ(3ҿ-0pwh"-
    4ܾ嵢C^i
    z>@mU9bC-uhN-Ċm`ZZͮ�bhz2ʪ
    jK`J�(۱eGۧGWѡ//u4#S;iND{AWZƆ&%"3'x 48J
    -aDxhK=yHGhDO>.)Jop%vމhɽJ45u})@vAw�ŕ
    Q^}"QT^OCe<q{JKIFFVN4 A,Իa,T?o\+ѩJS %4<6en掊'D)kА"PWihFiYvAzײU	АNѶceHCAi:!DeD
    
    %ߕaoCm	(vEPՒUD~V?+ga/T)@?Z9\yS)7r
    PM?Aahߪzoh	
    Z4kтm8sOR]^xSQY5azPv!o zRJN/Cѯgj{奤?Emvp)G޽wwr]@-KkiM<'{"~ѻo?tډ3~/R[5R*Z
    .!bԌ;}z
    e	Ey8@宂ڷo޵U8h0B =�vً*w5;-}|Jه9~BOqƈ: qB@! 7Wkm"7l~#J1b[Jc_69>sFm7–mil^;۞a*ZZ=4nvF^yWRww<94uyUbV]:7]^/L2n<V=_? ۟(2V̸%PQ%˷Cr_,\IiŻmמ{d2-IO[JN㾫q؞"l_q02QXVils4#Y'[2sDnOQjp71j(Hc-\0.ol,۸G姦W}ߔ\nZԽ8[5N{(M4?2t=K~1+Jǘ*\6>yASg{̦cxHW]]CIri
     xֳqZ2pygLhFG̭S5ȼFPk_[Z0>\HO7eʞu${b6X%RLsfyȌROgC54+9ʘޓu55Q8Y%ع|&\3H,TEo1r/9TRa1W0yM?6Vi2uJW{[TKF|˅se]~o~J%]gZM?e|/PRq84FFnΦߐo7ƭ7LsFlzߞ~T/ώ3:5nF7[Xf+?|߸t\EOO-ff1Zd/X~*Q+a˶S~e/Xjz߳ɸ}ƔqzU &Gn62A5w=eDREm0hGɜ5z{m_e6GmQrcϫ>(Qv=|B@! j	u?;d[N叽:ym3s1oO6FFJ`6cM[
    3^f$vh<Ƽ_ry4~.GxQmL%cמxF%uU|0Xz6]ddw.;O2?z:};\9B}}=޼tW*_fz1C[qqά?;kUw*~^ng<o7&g916}qذ;5CɱƳ?xoذWYϾl|1gi~(mcTڳ^�N[i<׍yf7=	6M(^w/nӇߚ"?)eW?4g^и;bm@,68-Dśv{alm]=ͧ_Xf#&;fzW7rOvl#5ۦ>3f1u�7C%FJ.L#(bd?1|Xr+ϼs]FF㺑-Ts/1>b;l.I#[d8>#-Ȩ
    \Ѻ6�sïS~*Tx衭<+=o/s_7JxQyϬgflKQUk<u9Pgzw~+_n,c8C.{ȤA~$9)QaYAj?z.s)my6ӍizA$c#ܣ|l$L3m[c\:!L_T=Wy=X5Zerl��@�IDAToƶۍ^)7F#%Ҩ.L6nla<~Bt[z}ڭiL3ȧs/>xӘ2ipڈ۱ήkX52c=Fzjn32mk>Y-N4>%ƣ^nF|Ju	]g7g?05eo
    h<ƣj'o<ʛƓ3`YL0Yy'N! B$@Uxi"dEafH^m[R@
    b`Rr?	XC�~?s0M;бA8g繏\Lb÷}@>ї}ԴQ\_�BiInMK;7BҶJã[{øl牠nO)NtZZZO_^pn/P^NX%ߌW9s5}hbddeۦ[LZZ֔_3۟aԉ0j[MJL<5%Q=BQQ!-onpq
    /YX"LZZt:9miĄ+m16"\|x9+]x	zu4&d͠'i^\iN"՟7oQ5]v.ʳ wlMX	T(+*FV.tq-wZwa#z9iXN~(.)D	-K뇠 s?oq|-w1u9|f*ٳJטcKе}=߹;cvOs</? w@%-oGK٩=j_?rZ2V턇K!
    hsDx?\tx_ۡ~斈ප0804"e%G֓˯
    _4
    -CV^°	gCѲ}ZsrUgbw+s&B܅ҵ#%.5BO-]t;-ks"Q(Ï@a*h{DDsp0ZS_IZR3k*`ϻp*HDh@nY]/ϧ-%Wo۠d/ڲ$!`<=**&Fcߕ37 %4=~&pT5~ߌgO0<Ldwa!=3ťvA΍nz\ͥK=t@ƞ悽̛hH
    Ŭ䗃:{³Yk+7]3wõ"ۋ]K!�<=h9FU!~_#g
    Q7adWlX	>@wmT`^|&m36y;RW^z)Οt:=!+)r9Z{Q!xGpӑw=.G?ۯ5~?
    JһKq~D؊(y#:t4cC! B_Nkelѿ;f>)~JTSճyK4wAIq`-B=UT6S6F~`ChvB:+3ͨv깠ch8N>{D{?76;нĺ
    [+www,2нG/}d|޽ȆdQY2<<Ͱ.{_.JԖUsP'coke;uv?u	itUlhĮGJ[ʶ	ytڋ+W~/=86،oϕ-@vrV9l?=uzuZkwmW{JlΊJn
    F3lAC#:ucۑ\9^;Ɵ}m]#̛+h A';!T>4KL9PtuXE~!9@{
    h|	<|H;?S!lϒ1AZ^m
    jՊcCp0tU56c|*:Q9OnV"kգthHmsєаxMpZ$&Rm[,S|t5
    ^b!$sV^-p$77ZzZZ*,deݑa5-qCaÆu,8d.?(򛏽QqC,z	p<s(p$ۣ2�>Tr|PՕ@xړC+E%_7}q.f^^x!Јۮ$ʓh|ʇ;jX̷5V[SZO=Sgj#Tm4v1gZ:7<-He'݂ArWMyлZ^F1O@_7:eA$ÿ|w`D9$D=q
    |.)B	MК
    Pcf~~<@Ao[[É}d)ʕaͲO6ZG! B@&pX;Y>􏻾<W#f!!*DP6
    w,c'eƏ6!(03;iӺPiDA�@_a!&_0L
    M4C*liqh@%4e=t(fөީ:tO'ՐaQ<'FY]v-z_"۱#qSTեRt7_:aWt(Qta$2UcdEE`1w#FUiطsf8z)zA/Mk?A0Τ�Tb_L4jg̮lbY6nˌ
    6R%
    4'-3l#{T:1V#/ŔðGvHEفW̺"gS^mp -vb3hi!fTV:y	J֕fC+@gM?fZ\WTvJ˧@;^\o4H[4W `򫦫ȟ]bl$2@f-ۢ^!qj+7s`Bd=	Oѓ?;ޔ2mW5oN�Ƃ釟0q2e*<3矇q6ԾqЖhVKO\uf|;|i_w濁|2KLp1-{&J3iw+ᕺ&MF{.Oo"C?:<k:A*P{8 ;}MJt="1/-ʧ6|6{s.]D
    n۱gkk烧a1z@(V/SV5G;TL~M=XEZD`WYYAJ}`H\l#tY
    RU\SښG%W2}1ޝw
    ۵:SxGBUPmЧ{gulUlEfbpx{{Pۤ5T-؞]PH씣ū]()nf>ѧ*)VYaUQu{7Ŭx16HblzL˧B@! t	.@.._Οyӏ?_
    t7'btqgCJ;ۄ#ZSC?墰}EbJ&׌džx7pnuiqg:ERG<֜IxsЫ@6g޷m&:;V,2枮`cmSt=ǭw܅ko]}sƳظ77d[e7b]$r/ebiyz%M^"p%j$=sPMӄQCaMw{l )wfľX8{]5-Wnsvnۊhe1Cr[i	Pgh'׻9wm윛Wst3F-oO?dxozeT˾v@^0yL0HDHӆ
    vAK߻믔Xr
    
    `ʕt1c@׈Pw1k8x)8F`(+LqQشy+bQnQصmBFn!$!|\:9^@[B~_}U
    mx0Gۖ0PHFR,^~=DWW͊Wh8jٲkqwnʸzz)Rf)8^
    r1}-.Z`下/R~={DXX9�-Yث=
    ?]phvlmn]#kWۍɕb[*p&m_-o-#?}F,@vё{i#^txm%؂:e֑$SwUoe_n{S%ù C]Z@mHw]8+QE}hn#ԪJwۚB"uT|"/]JNb4[�m
    {򠚛71Bɬ>t@vZ"	%T%G1zHB�ꦇ*&ٲKmYg`h7N0~]{$#j,m<kp<nQ̗yJCv{i>pC#u2%3sh$@ #B@!h9Gf۵ܭl6:`Ӯ>FҾ?zXVesh5kDm�!}QNrqN:oUz6/nlMΘh	_$YBN]|u8VPU|N4_pDFeȕFZWNͽ4zpvťYtq?(OfWSa{kcMA#N6(?yˮʑ\:BkULc~O?t)3NqkP\ɾb(6^<5`|7Riw0zq?w*\=mkL<}p'>C׿>?7x?`>QXix[>S.̗?1r�.J`pm'ژY O6nUqZQi*?Rm1FaVqn:?nL0no="3xqO|:$֦eݜP[iy�KWSyzWYWy)ƅ]0w)7K[S>݆E_ԅge1jc|dQ`³Qm|o9nU9|NdաNy!㉋)-ξHCmXJ]g>1wctxw&kdV}kϯ_yYfT$w7<>.1nyCT2zwͯ)!quz5mau{VlzoWJQ[c77@nǹN
    +8
    G8cv󐺴vwYfla\78#e}xx,|0z1Q3Ǥp
    B@! @=.:
    `FR$mI3~4CˍjZF
    3!7-˖.ǾD`-iYBDQz)Xj
    *]0x(YM'Bmش.*R9F]:Z3}$?pr&<}[aDK>KaúuH-1jp=d
    _;Ь)
    ňc1lP}|'Hw?4Cj)M;Ӳ1ǣ[7ELb:-tѷk'cEwrk:eѭG_Pgatq5:s|<I4|[CKlۉĤdW|o6l0:V$g^	߶t8X߽2Tz:l`׎H 7�'cXlٰsѳ | k]TCGbP:.Ö?agT*
    As:\07K),{ ~<ve˶`ƙN=شe(�E6fNT*
    kIݼq="<@DzEyt Zlٺy
    0jg#B;vG}(ƍFtb|6~?j -6fgضhȨQ#ЂWbʹ2/p%8�q{a/*)EaI5Ι~9:xaUg⃕xЇKAsZ=|lf{oƎ}qhM~ǎ?CP0"q04?XKŌܸGNA䛱ik'eDUlRLjQcJdc5H)Fێa=zZAxG^F2֭tX^.C>4ɚv73WDEA7nE9^ajt
    "wnν}GAϰ šfm\Yh#P38[Ҫ:
    ~~
    TﮥYذf=#OMjhFw
    b@<zW9B`ʥXq; iCz7Θ?bX)%q
    ڊB=ZG{Խ磆GM	ؤLtgT̼Ll?1CvGAV<;ЯG搞6C];mî!+f}ر#zaTNlZ
    1yعj4][XZ]}.FB֕U
    +?xpNDކkG4>ֳ?ƍK;jZFw^6
    ޓʈ(pToۊ
    t3XUX|W>9#u[zT2G! B4j3m'ٰ,^
    .:{rIJW?i{Bަ^צh#y4ВeOp0f:QONFBV=4ICxyt29fԾVWn[f2liϼgǡ+RU?27,1+}1l`_TgcO_?hZw{|VpTx1;dg9ȶzth<0AAglZ
    %0wS.>e5:N-o68ܙ^]k.^tz-^}z<wxy"{e/뵱qHO?QI9[%D4Esڼ[;u$`=p=|&@;(a
    ?Y3&eq='~K婞l;'fv76
    nGwŒ+cxVg=
    *;ˎQ+wО '%7oi²?̡t2'M{`G! B@"ЄF:
    QW#�62Ν9gԌZg'i7g8IO`y%AAα6ʬY{J<=m{=Y71b;D?sQ=lեk[y`ctqͺϿNTP<˳ܴq≹ y0s̓{?y~h=:AO/ZQ>qR~fLN}I.ק̲/Xs|)j|myc:k+KM3z̸b2Ω1@An.j{CywrS0?rZc6mq~gcӷrИ<s9)gNןpA͹^N8_B+)IC;ѧ[0t]!]Sā>H'|\tZNh=n1~TԣZ|
    ! B@(MΠ5ډtkgZ[,
    樏]SohhpG}V9tߞ&)t7Ei3bIPų4cW:
    GN)oT":תìqeaw</[HNC
    \_F'd6?KuBx`h͉YשկWT'i>|7kYqwgʯLokjixia>"C]cܥ]YTxۙvL}t�x4FrA=Ɨ;NhQUZ-f0M4p͂btNPU̝מ$laiyt^:/Uc._atz))G0u;=ǪK%B~??;͟E?cήCU66p>XWJ}^&yB@! p$pX1|MН*T{sF995KcA@XPB@! wQ'&,3y9vݓC'ldOFf9hy>	>&IQ;=&)! B@3ϨSNH+C/GH&&l
    ! B@`b`B@! B@g,]gTO! B@! 	& 	.	! B@! pF@tgTO! B@! 	& 	.	! B@! pF@tgTO! B@! 	& 	.	! B@! pF@tgTO! B@! 	&TzaB@! ߙ8! 22?kH&B@#%B@!p49^SSJE?NT-w&<<<P]]#&rBNIX8G]]eg1*B8h`[GكhB�p*.3y^^Ut1~GOO&n2t2kŸ'ʟ2dTF*1Bh`[KOOGѷo_TTT gS=3=B3sLsQ?5\^^ݻwW^j
    #Iϙ>z%5:ؙ~6g5Mgt;s;\wGCcqP:;9=wGgG^\UU^eX{dYvG֬zѤՔ~GM:51MZ5?xZM,Lo
    #i?:.:#;;[Zhu[ӑg! Nj@BCCѪU㕾=B
    
    :Bi'@iiZ"_22
    s^#N]]*B@9&
    tq'wĝxĝ(,,D˖-ѬY3_
    QH̛7Of,Q$'q<lh<GYgt_�~\	pqMK! 849l?'�ׁlj:9abԨQر:GUI M9]l7oTm85ENN&̧-BJq$J<Ӿ1}x\
    z[vcXޔΑ.wӿ�m8q:MUz|3ISVJiB@O5VL\HX(>~*	$cpJ222տ7\~~~j%2yۍduJB@92ЏԗS;m<ToFo|hvޖ` ݹ|smѦXut0vlSm!0;.rssfũᡶ4)q?~<zt]Կ'B@! a}n!P
    RJ5ޞnf
    [JVqxiXsieX[;-PXOKѓЭSNJc=~y)*|cWG)G%iP^(kkkP\T/x	̓jIh=s޹:=.BJ.R]]캒{$0g6333A)d5Cb
    uP%~齼Z+,B@O:ڌ^u1ο䕘w뎜Y4e06v]rm~[m)}H9T_Ye\ZN}t6{awn:?sP8'C[wR'WM5
    G<
     N=^Vp,6킾kq'@vԕaaajy||<ڷogUr B@4c:IqەUc
    pLCx6GXx8}}h,+FZj*z@1.GuK*u/VswstkoQ<v":-,F6f| 5)	r;"`V.Z=]Zy2O/tjGsiPxR5U8_7(/FfNC劌ty@-Url"N	|xٷp_c0re[>7UNNE׿H.B@!&p\t-n㡌nƣg9f:̺NԆDufA]}>%L.<FQYox.j'n5muݍܴ8,]:nWڣ7# `wL69ML~)|??&zh?zyfay1?dϸ{&.|Lͫʇ_L*cw#;&M\t}Cԭ3zC3Grr1؛NK)ǕT irr2>8nϞ=VFߩlW! B@OTVstܹxYn
    ^R;I<{.8/w@`Xon|Z,sf?.x2㶮Tp^Hڽ)H+ץ\vx摻Ҷ
    O.UЇcܵ/[	GšhĦ!}rrv-8g`6Ákp[`?v�"7cG~ا-bcAk~ݸN?mA{1ЪKF햺$qxYЮKl[)zkuooo0@K0?*J"B@+6kwrnv)ɈJ3es/yny-0m[ g6,5tr𶝻<l
    ^[p#bʸea|mJoAwu@ۀlSNhFaH݇v۷D>)+A-pI="'T]UewAP4^P[4FAc4MM41XhbMFcX`A:{w,v9os73ι3w.r%@#_B{8=v`>p!M%sDM0@F %_ISe	555a޿"UVVCFo=5]C0Ct&ԜLkllBȖrrr[V[jƒcDj0cВ$+rz=\WAd%~:MeW5P/@u՜|
    
    ؏9BE<=hO
    3eC;ZWEFC]G[ܯw7* 97$o=db4.,Ӣ/=}=%5
    imG kȓ9?d,]*^!`!`38j! +,*Ċ܏El^{H/%u=^|^\u'`i{c
    N-3E^f6|ֺ*5ʎm"@Jj/?̛o7NcǠr[AAXS&ω靖,jy(Ќƺ*1@:
    z
    ǺƊux#˥*arJ{_<\X٧Xz<AqvC`g@rLCuVoogt7#СC뮻b̘1=z4
    K~ޜ!`!`AŻ93?
    Đ~PQɹ}qᒛǟ|~p5z}9ݼ�&Mn.yͨY缋1+,F}f1}pи<}oުP[Y+Ɋ䥤co>b@3|1[(p{8gcq'`Gg]>rGnʏ{OBJS5"*7{U?sfb0xHBql.wuꔖ2CȂOOso0C0C`#uL9<hiw1WVk[[q!<83r!kwŸ%>̙3L#<>N^~?^PCϸ͍҈I-rDݱg];KSȣ|/iB1yxx7G48[?CR'O1`+_zq<#(,:#;80dhO'nmK7G;
    kd`Sk:퀱ӈG}uֵ
    ۧʋfg4s!`!`$Yu־Lٳ1x`o
    Tv2mm[zdijöI
    >xKR>w"Z]{f{\dq"}o{.9R&HZ/MMn=k-J5Bur	)u$_C>("##c6giB@,
    +^z)v]>zk\iDѲYveʕsEEEr|Ww3oܹsʔ)GZ0C`gDVcDOo4lyi󒽉^(.8헧9 +ڜTn|Lc9eҸ?5ν4699~ܒ[[^)c=5a厕EUPۃ+|DCyЧ^;$LC0C0B`4Xhu㤐?7_H2ښo3Α(Z>}YId™V32g2 86MnyZHei@E@s5K	XlZnW-nhK_4!`!`tqNڌ=C[
    XAHJro4JdD6yHirs~R4Oԏh
    텀?i{(..Fuu}cr{ift5n[wlg!`Ό@\Yd[:Uge4mHt`\ei\i4UsZ_P-ˡxwp常ޚӲ50J+[F*MӰ˫4?ȣ<I.擞au<Q_ikZGK&Wi4q
    HJO#](u.m0!C`РAm,']Zwo]]E7AWV4ZWt
    kcGyUViw]$ZQZQ>Whz0-,2hЏҩEo->ˣy*/o!`t'N|Y97E]Xh4LILUVGJWӤ$%k
    &Q6軴qiy滼A,<|MwJI.Wza4մ*ϕiJ5-VӔq~?[[жa4wD4+oG<.K24DXx\Z7׍tw.aDia<V77
    |o!`$"4
    }ar;<ɗ<=Ffeey4rm<'�s7NS)4%?Cś*}䍵#AY*e0|Wԙ*:Sw_[[b:DIK׬Yկ_?TTTx0}ǗmRgV#X[1ݕVOY/W~Gm-=/Dk/}A*Z_
    k+wmMVa]]a}}ZRT>VG֕u!qywF+-gUkZW^k mum+klP`[Q/}ٕkxmm}
    G>ۚWuAۊk_/Y#`_Gk8,6m>%8i$Bg0CHh:4Щ9oq"ɉsrI}u$"-yG'_i]Ӊ8p\]NYO?c2莤ʧݴ.Uϴ K0LO>NVukG_k[yuG’tC<W=U~$,<aFEeҼH<ZW&T'6,_Ji:Vʣ+,Kur3<cO^ϕBZY۔}|�'M2Q?\SZUYi4Mi:RW>nJ49E蔏VvU'FuP,|W>y(/(`[QVbyQ>5Y7vNLӺiQ:kUҨ2T> O4Ww$_ۇ}FO|GÊ8QSLS1T7ϕtX?wܒiJrg>.Kn	 O(<yAxu(}?s!`@w@ w[88Yd^/'-C0C vz-ԩS@Р7g!`$Q=>'މVb�Ч=VMWnL7J^UmkHTzD'C0DG ٕMwLs*-TC vug'mƆCV+C0C`{#uUȶhl+J2:�Wy{{$W""\;v}nB!`!y2;_L
    V7';\P&H疤3OwݰDsy,l>
    ah'0C0cUܭFd0҄0li7ۄTVlFb:>oo꫎ig+#‚	
    }=D1S0C0@2YoiPDTtI&O05-L=X͛܂LpV4u4Nf9g|O1$%9G^ə8w1n($6J1C0C{#�:Wcy-Q_?Glɴ蝹ќ&|>v^ᨯyY}Ow.@N~62r1y'bp9Y
    쓒19H0
    SǎZX
    d߰hU{iol'<	K?]k6cȨ16gNX1!`!`@"Z;FI1ι񕮮z3~~XZn[S\1uCpI'cڄ!8c<Zs&t%YW__ӏ;o>3KWx8B�/p9'm]t,l͠��@�IDATAtt7g%s%?9^_X,`!`!`tZg)i8h$v`fHp̟ȣg _{Lwg=u+oW}g-;}SF;;6._<�>t9>	xO?2z?/񵓏Br:s=8yfL/`C`ZJUWހ1
    Og\{ۿq~$=DDk0C0z"	lj+*~ZZrz~<3x}kM8|=3>O^aaUEfn/砶|nJwyq8=K.|>:.Eh0dp)%;X[[M5$�GlO1SQ^^ӏBaXNJ﹘KhCI늄!`!`t-	޶]S@VT%$+_ǓO<yXz}</# ;-Ǿv?Ӯ!CvgS?w}
    .ػ|<ܛrL$u(86qC_4U6|,`|	QWSAH	pu´l}C0C0oȋ=.gI;r;md9ȭ9
    +5{~=LΗ�H&ccqĽ/ƍ拏E$7^fy�:L9
    5hllBR}').[V9CC[uMBFv.V9-iiBiCgqZz#஦'!`!`2<dRS<#z~82Z_Q}dL
    Kh$˪]UEE~Q_GタB?0?jjԌL$7U}5|1&?̵lC ){b
    
    ^7>8G5sg?A(%Nk!`!S#P:
    ͋>G-@FJ,*AcR*^~}ꗃ2~v{8v>
    ,;z
    ǜ5_}>6^6
    'aųaG![ph*d#;/s|֭	Pno8zR$~Wh\q
    WէxY9~p饐UvD`$C0C0C`B ԴLuTC%\Ǟ;Cgq|.mp^2VZ#嗮ǮHi&z1=[ŷVfa#%5g</60<ܓ3yfr6:"83ӋϑZ̾7>Xe
    #/$aþGNš(2U!`!`;!IjM1͞=Ƙ1c*WSCJ GGFjl[@|˓myto?9*lXr2<QԷ?AUm綾nc
    ߧ/64)j\^|9ս<hj2f ?'ˑmZF,]kۦF&#}_['?>=JyGב6katܾ9w\9e!׹NOg!нHtHS2[0-Mhޫ2rP2D~EǛs^A*?78X~#<r\QVZ,
    8L=Q2=u8'[(aЇ-MXM1C0C0	c{OeN98k.koϡO[wF|]\k+CbACpHክsH,
    `[m!`!`t=Q
    t`w}$e+n84htwirp;Ot>Yw@e!/7woruj}]pWMF|M$n
    C0C0:?+F	':i*ӕFJI~s@XxF+.5/W:J3[黸yܼ`9ۊVV]2|FLǥpP^0tyx<OWRꑒ֭Okzh8k~$+x"մxC۝^*c[ZGD2⡍Ǖc<H<x,<.ILXxቇ6L>ehuY0CHT虙!lFœEFݲ4-̏VeYZ2|4d>{4-VZ޶հ+0`z<<.qUxxTՒ-O	twp&W:hܥѰJۊV
    *Ce״0ߥp<z="W(O<ratiq'ǥp`:iaqO<Z^<<v$r8a6g!`$:mذweҼ1qu3鑞++Gnq8}]%0#?(MG'v$_m.\;&(Ļ;ۺT~vP}+G?^,]}[vǸR,Eek\/|.XiҪʏUlWWoW~.ZKK VNZ^G;bCW~4ڎQwD<Ҫat6.a<.a)׶,/^]:Qr<a!۞_7Zۜ!`!thoǏڵk&m޼ztjL҈,--Eaa!6m4.sssQ[[Mxϧ޼OMOҪ|A]]7!DalŕOY|&6Ϻy5'rKb/((0 ĒP>?UEZnqAOU>ۢB>EVOX|NRԗX^V'QU}!־U_bD}m/e_/"[HvvE_p-1Dm"u!l\8x4n9}}'qI><5x=b[^;پЕp^c]q
    v]L_`_먭WK1|~0CHd:9s<coܸq;F''tPJiWڰ$\} mgwuxAă+V`IzґeE?(?޶$_u~}@ʏ]mELu,Ƃj[H:k׶E_pHֶն]!}Aalm_~&}GZֹmgUh\پ@]+>}`[}|C0C Q@={6FÇ';K,!CNU["	9'|V.M0?xhxx%=͏k9�w:4uT3L7C0tŝpm/#'ID|ia~<*#*+}pŁ+\2mAC`Z0|VAyqi5&WӕЪxxuk8SӴϮ_ޛs1H]=4/5?<jZ<0MuDiAZ7\ 
    nu`<Z%|Wn0O5-OXh\ٱxi.r<C0DG 5op:R?R4/wyhCYZ2|44xO3M|ҪJڠ,LUxi/(/WX+o<<.UNth4=tV]y͕C%iږ<
    iB04Cp
    	tWE+;/a%|W/o:[0CHD蜔,W';BUZKYؑdlr#[kf[ޝܵH4C0C0@T,'%8kiD+5[2Fp\&ےb
    ^3ٖo!`!${]R['OikJ~l5̃,C`gG@qp;;.ݽlKkފ!`!`$*	e\W]æYoRgbQ2?[WpKHxR4V#( ܚ܈MqfwQeeƿs30u[.yvڠ!Dt
    kb,LFc!`!t\,ێv0]ul.ne>X~}ﭖк}C\HJ5Wd|A.7
    sO`gʟĔ3[Aߙ[n!`ZAoΥIhFiOA妳0W/w?Et1[rgxR$gaرا[A_f%ʪ1t`U*˰tK r%;fRk0yXv#ra(ҥˑ׻}hӊߖb
    C0C0C0v2h३ޒ^b-*؉{`SE>/<q|j8?LJd뺸^|W^wjxP3\zd\ny|!>%`QQZWEw7܁ueX<^u5<C0C0C0C`HzfrO?ƚ\}y80=	:G\.9$4kn7!+uuM"PW內z=ZR1e⳾{:>�0[0fV%!Av-dN4U0C0v	iJ^_zu7N>iղe(}N:f:Gza	vw\l^ʑ])B‚BTW^k+>t%|V6#YaW^^�yL�9v=h!`!`!`@!^Usg~LUxm(E~Fwb{FnnuȐy*{SSR秧g =&5ףQwգGN1G#Cλx`v1SR|Yzhk
    CCv6!`A Aw*JP\RGǗP%Y`y25JCjK
    36xk׮Ģ5HyxkQ]_df}Cw8L?cG@vZR^WUzKWmsuxC0C0C0D Vi
    
    zF]EpgOΘDnSGpY3qeϨx`@ 4xEH)c'Lӎ•i'_DKj~?нvA2mn\pb!q>1]vpX!`!cH(]Mff=Axl4f|:-`Gy!^*ޞ"}o!Mգ2n<xzh(_%2'
    au#q7cxJefǗ\gꇧ}vow/u5b!`;VXC0C0z,I~mFu5{l<X>Fӷ%T9zhZ`{H	H"*Mjll/"##cEW<hAUUz]O4}Ab˚RXh}c7"[Oӷ6V!oΝ;N2ֹNtIFa!`l?H7L/M&٪prqθތ0	[s 9G<zMsz	o0"#ET=?5B#RkxGce!`!H-.jDD~!OFD{*K/Lku^7 ̷xGڸ0C0tNԘUTN0-wu(t#2@az&Zu֣nx"=tK/&bӦM'
    Y�<ē0p{{4Z$Ңו;HuID"OZOS<7ZC0@T5ZpχkYO׬$v]%jD[ꦲgAAx~LJQ'"l^zyRڶ[$ҶxywtMD"OZOS<7ZC0@T=5'ygIt5
    `͍بCJen0CHt:4iR>ۮʕro]]]4I񥥥yZ(++|ƙ^WWq644 33;9//ϓ6t䠢K򳲲P__|lOK3uM<Qu!/Oԙ&:rgXHY'Vk׮x$_3+?VV`[El3ۛ¶
    kamE|ܾQ[~ϾO[ɏtJcVE>bɾ/r]`m/Ǖ{Ѿ@/B4nU~낋%ۓR$?
    57H}Auqe,}A=8z
    /|.DjxamqGw*/ם`_`'_,m=8ҽ{
    ^m}({s20C@:D?NysUz9D.8'JM40Mi2(Dߕ(B=疣q]uuQZ׉~P'E}!e>'ʧ<R^$H:'Hl+rzsC)*W|[S?Q_cMSJKytB:3m\U7Vn:VOl+0+Hm4s}ō..<WI}L'Ҷrӂ򵯹An\NX>:S'WoWZ՛OZW~H]OIbҺ}Xu"ۇUiS*qiU}4.|]9*_նRL*_}3n74LGj+bttJKutV=]0/|ەbG/(pW^}AHÞ?s!`@w@ wG魞wd,Y!Cx\O!`!ރSz(_tuY&0CsJp$0/U90Uq)+G<ViHEL\
    *F$	I婯tʣar5_|:aʫ~4S9Sv$^/Q(E
    sW;rTkyn\ê#V_i<M0ΖrU
    s[Jw
    !MGyaLg24~X^GN.oq:ƕQ^'U*ssz0&,͕ԟi^0a>R9+S1i)-]yI>ԑ.Rt4|WҸi*GuqyItx]ya4trEݜ!`!D5#U@oxA|~O7t
    }-30ynVXHLS~,ʣ+GJiA(ϥsu	,7_WxӴ X
    t6XNX<O[NOWAHxh]<`^n4ؖ4^1du4N_wӔNwi4-y5jZ$Hi.oX~$`9aq7H4nቇVT]4-y5A"_iwZ0CeL7@}j:@4x
    ts=F
    鎨]wV!`!`l2йrt(udF'	km
    b񭭳1HTAWb]jFv
    ކ!`!`$ q%jod-/f@o  [ajYq5;	[ۆ3C0Czb7eBVUYO!OwE/{tWznzWi>*Nɫr*Tz!9EJZ#sDz>]~FQ֯Y\.]Z!+-Pv
    W)QT`=-nFO;|C0CD5mnţ;C\X+N=TL=n,'EXrO̠#d78eG7Pۥ?`eؕsOປPU"i*{io\<.n.TgqX~okڙ8}G$9]`@@8xȟ:zuEW
    CHڔ`:!`@OD žj4On8oc٧c+W_^/j}ջl36m.E'/ssjkj<}P'<
    i7ߨlڸeb4#MX]M|ooRXlGj+~TD*TTע
    yE^.fb#O=9^=psS#(PWS
    "U'[ojGYi)*U]z:\VჄ&L\qo{�qC0C0C0@t#c^uWŽPW	>g/:4k˪S^)KqOAwcobXSهapY'ŸMb7#SO8yU7;S'Cd.\7laeɺo,QԷ!Qo|;iP`ữ,5'6_o^[zu5^]:潄vꑎƔl~98E݃וRz:f|xUl<z>y	L9HuX[pEaa}2œ!`!`!`@F tIVe3k17P)9ǝqL\xxsqխx+ěW,Eښ͸?cCY5{Бc0ȣnX9
    3pW?Z+߭{q^^Q$طKX|gg/a{G*GEԃPos1GiYmx21ܿwn99Sト_^}Y_}FK6TbSyKqiXd%r`0rq1bC<UePY#+Bo<C0C0C0z.1F+c0Uu/00
    ek]
    ܎cg!Įg/+̽zղm>
    3t4w(Ҧ쉣?g}MM-exp!SdZ,t1}ׂ\<|5t_l}w<&R"$xeC:Aޗ7?WEW_藓E1Vs>MHFɨ㺼sG8g}�/k.ˍ%hll�χ\~UZ308?MhLaE>/[=�8œ?'+fzN0œ!`~(-az!`@OC foFxƒI{TVU9}vb~q"Vyoq,FgΕoyN:MbV]U’>y4q3N.n;+ƨq(~7f9B\W#~'cxv^{9T)2knFIn
    >Zv�CުkВ"j(_DqM݂)-x9xBTkxeau8+ƹ^Ђ49)^[[S3]< q^! D:$AT35C0ClVmN<Oz_6y"~oW~j7~Uk6}LHϝɱg3;ͷzS6?N5;=3ɝ%2p䉧a2('I]o[ZNBc}-zxq=T\?~#yHj؄>#ǹR: NYXb-V|b;ˉ@FZ*5ݜ*??/Պt!JARK
    7Ͻ@ޏ%_&~|RuK^:tqMb7/-]^7	uKD*3C0C0C)lAlc
    <1\2SVg%ǝy&:7x2zU9�\<YqMK?}w܎'_z+_ƼbŪ/g|k;UP^?^ž#[]}m5;5b
    ďw\PU߄'|
    7y5Ul*-NJŋȃ`ZLz ӏ3`劥x'ԻRN}[Oq_n M;psij/aԾzgxd]9vk:^*ǰz:?w)}d>`gc^93/GK{qie[C0C0C0z)I/ϑ/[٧KQ0l&0;h{7bg�|kn/?$*&ʟ|%Ey-<1Uʪzƌ?I~sB|!{x[q]WÍ?ʩNu]34{MET-'yAFKWߛ
    _4c7bP: ?<|x1Sq'?9c1ul^+!?33~o/sO,.KP9�};n˯FCSwUNcaO{į޹^-
    w~W^HtZo/bB};^Jvvv[_>@IU
    e7T(MXc37W\?Ҽ!`	@Kٳ1x`3{WZᝒtTˉ)ɒamcBnl?~j<]Ӟ"GK-teP^Y<1Fe[q[ؒ"x鮞䭫&Al9*Ȼ<9@ӕmڀͥHABd9oiUliп܄-52jz7yefe!EzTneHBQQod~u国rӳQXXTނMUl45ԣV>)!2t;KzmE*|C P#+Tɹ|g!qFd5`{^-FoΝ;N2볬ݽMC0z&eSݒJ旗ʌd1j&iri6=O_nӫHU-E$1vsP2Xm+
    Zmnn8gYdk5{OIGɐnYbӑ3?.yoӿ@4/7GOrD>X4c!Н`*°^=[Z
    C0C 1@
    TVC:55eU3abpGGH<^ޖ�%oc՛:ue0?vh7djٮvr*]s74sگݫm$xvoi!`!`G ɘ:7즹nXi|_
    -S5/RH`ܕk^]X:ˋeZ;Yؑ'	<c+[Yהw=N!0g[m]؜!`!`@"@>G&errҠ]Z
    iqUX亴ZJa	191Q9a~P>
    
    `9)[gy?xhxx-eO0C6m#'9MC?ZʏF[Fa~G|J~G!GǶ++#ZOpXyUv,:ƕ./m%_p+Co]]-l!`$"Q
    tDni͎N}/G|Vat5-̏Ve"ץ24-W:Hiɺb嶅Kϰ	]0MVyԏEVҴ0_bY#?Z-7mIKmn#AU]hJeJNA9aD05=^\bۑ|A50CH4:49
    unW퍜tq]ksŝgĒg獔?>&6|Mht	O]X0kM>	/LeP>Ӱʰ~zQdR`IX']<IBmam}9^]bW;[;n)}A屿^HGѱ<LqEXS&aXtzP>郺(SV+ٖ߫ҽQ#yW_W_]cY'⬴gG`tҾ축ꭾ϶r+_ls_`РA0CHd,&ǏڵkaE(m&weeT7^ycq<~Nlgh`z%o켡s{R>NÔO9	2(p-q̉o9r|Gyl0	Յ>⊊
    OWLٱ'Y.,|bC*
    Ss3G{+>qmEa$,mET'>I%VAn[E־uU״/v՟:RC ڗQ|jamtk}8s}-ei[6(m|mg_q˶bn_϶&?8nl+[O~sO){]Ӿ@}WPV5m+.3n6n{^#]f܆]mu!lރ'amH-k4m,}Az
    g]G.4|':t(!`@A3g:ĉ7?ܘ>+aySD|:iU>iU~$xR~PG鴎a#g8[|9JJJ1C0^/{'Oɤs0C؎tNcOiѠt}/D!"{[tF
    va$]ŕxqbŊ[Wa>P}@Vh'ooZ|^VcqI3N<S5-Vrnƣe~!mO<׺˧jm,H+ih=(]]?<͏&?R=0Z-Cˤn_)k7EP0Lwo|-/(qG_nyAHyEVD >J~PҪa{V9aܜ!`!thmet11+S#ޜ|pK#'Tsߏ~yQ9`;6
    j|ki_}w ]
    k^t5ln+ÇĪ<-CA_]?Hq&Vc<HóhU'?ۅFe˼qjDiZv|.4|׼D
    ܾ˭<8^ӂKi5c\xx|^WuիѿaۯT^ЏEl-򫼠>vq!Cv(/ ]
    k^|.4|Lvŋc=3kf3C0Vq
    k5;M"mzrU|kOX^X:(/~\9䖿6cc˧AE#=JٶQӧ8)}G4ayK?EMkK#[KSh~PV0?R~$nv~l,5]z7&ӥL8Ѱ><OUp'Qyʊ~|F:l/Fo!@R&;J\b/h#vƏT^gD	入GGq!DuT1w_lep//6-<.En"VFw6yh<n\~YoK7	cg,4*7Z	󃲂0>+6+0s|j_1^ԏFi;'
    WLҨ4)cG9`}V/C0@T;UfgЕ	Wt<I%&XmuaxMDs]tn%^;Ak5bKZƯ֞>:& b\	va
    i4D#$"zn/]{0-Q˓b-?fZ
    vثs~m)E^\:txm~mqʦn}毠TG^9NqII|8gt<0l0CNޝZUWORfNԻa8)\ԃ'Z4@v|CNϛʊToKcI&>]S
    I$KY)y$6	[zV-i^ӀQ-5_e3\W>1ӕfQ
    0x*m:"x4
    .t^9\aDCe3L&97j8(3>4v[A~:Wc5ʏz0-Uʖhl}{ȉ)KUݧ$OAJ%-.eǙ/z}߫7?V>LWA=_]_-+5Mϭ:u46"]бoFVx׏־BcU($LN-ҧӽ~Cw۵]'?w:uF!`;
    3w,כp$+u7)YY9:N,W8WVPGds746:aƹ8'Jh@eY)k<b:ꚜ<:		_'M'7Q׹Yӝe1?7ӵBGE:o9I̐wssd"dō^}X7)%{3,?'yl7bX2@0NOu|'kRQy>Z
    )+C2(RҶrHB[b0_iDqɢؼq|bЩbtBҫ%!KNMKoWe/e쓏Q.S;N /˞^O;0��@�IDATJ_W՛aV歮cY	~ycݐ*RL4yP~
    >o-7gaQJˑ|>0hi|7a]0tp10Ms'G
    >bR,|)r
    ®@m7HK7m됙-xy}m
    6C4*@V/ֲ)AվtP_xJk+qF5xc![A2nKSS65-=y쏤˜^0bZ|gG6v0MV7b1Ч{㵥Cs^uuuq?6b
    hhjRrY2WV"-#]>5=j:<p{uz†
    ;--#]'>uP<t4v9W,ѻx8F
    xO5Xa\DGcfVzIexi
    tl{6
    \%zNO+^bϖ},pp m)h⏱tZ
    3BD.1g!`t7@n-&rURIMx{_9x$7V?O?=l/x=BUmLU<uIS jiL8}
    
    2Q2IV2dRʉoIeĕUL՝`z'|y
    ȔW	j*y>9h!CF<hk	[UA<7Ȋ7dSWOYԔBZ)["*E,;_ Ī%"&Ǥ){`iS=㒺NbK=]d~ZP/S1I&ί</\w3n!o[&ԛm_)$ۊM+qwϓ`@BK:'\!؎:BL<zԄ+wk-Ë~`hnsg"{E8liHjd}R|QrQ)tՆU7fb0(id?dzI0)]^{
    66䣡|֖a;aw>3bҌ%pʹR1VI[VD_>`Ye^<�!ϦUKo/Z^d{_hҐo ~sş&'iF$KqҚpz4IX||{?Şg]8&o~
    q0?/o㏿&Ri,IT$yo?1Sㄣ8c?k*!rB~)\}2>SEc*uۭH'N=HdFA>pM~F\%ĝ}xR]dYX}|cy:Ͼt;RqS2n:Mb`�qgx?l_Ig9|_2-UV7xw+{O)ׇz|qE?7/3O;Žszxc<}ӇL=1Yb{4SŪ׿ވr]>[Vez9՝\۫E|w?F5~|%;Wٷ!_}kKs[G<?w	ӐJ<x]X՘O:F
    (s5w-y&mރIOכfKZw4@*|ȣ{;yj|s7gx/c!`!0u4xky2cp'N8l_(an]ςnBuMd M&A4Ĩ@]mLꐚ!\>! |Eb0p募JVqMf;Y((,C$[Mʖo'R^Vldg7+I˕ILi0c}ƇpY_A~N*dUPV~5; [)S&I22*ˑ\Ymp'DlgסT&}ymPUQF<=C%5CV]3d"/+eg܄bacΚ~-ÿqNFQN*eAYokeJv9QSS#E*L:s'Sqb1dقjYULo
    FBby@p_/
    brRp<Y%knQzlظ
    I^wCHXtLAq*uKxoiPԕ'h/FYeǒ.z{ut˪{U
    `A&i:T2-779UҲ>3+EOs۴k~i_q݆bȘ=qՕCa`dJ==,q&ߦHϔϒ+f`)cFnjcou0)q遽=m5(O9]>LuP+Yd|C$uRRYV&[SkNR-b
    II
    rI>/즆:eLWAʿ<>{}'!?;[#z]q}ӯ'Q_?Mw
    W=&hXnGpV.rB\;{J߯o5:+RgJb|f)Ce|pzʮtiJzwm
    �wĸ/߼IV7!'P~6j|w7W4|D^`lW}Cyjxɓω_lQ8gncn^)[?^/Ơ{/n~'<c+"<GWODߵUAZ<0I:m.1 㖯-y~-2<D\>vh*Fԋ.?ߒE?4E`:뾛[Ť'GZK-^_`N:h7ᪿqta#FL4ȵd־;mS-zXg&.qr=oIÕԔUx^7ؐ2jʵc#C
    w#6lrml2%_9C0C!`z7k1]mwLp1fsٹp353>^yQ=_B1wpgĊ_-w>\sDsN>T=@dbSO?<?[}9
    Gs,?[0뼉wexwuwLUmS<e`i8q-4y8S;_|<6^f;ԃ@f8!|	u6`og^=G>澃c&+Gc
    F
    )ƺ%[nAq82F{,}z?xb<8[g
    ŽrU6_o$j3<({JՌ~~~S&=G?{_XՑC"`ݥ*n궻vwҭ֨X-	I}s$GPx9sfΜb7qP?-]ڿ<&i�-1h0;a "{fΚmɄf>̬W#2)g:Mƻrg:tN"|X63Ӱe,Z	m:瞍NmZ,5>?k6Bz6BqeuNP"p\	im`_LHԖoZg!95
    [7o2ZZ,ق0?ô9ѮN>f@0|'X#LZ)'wӏ'agyw9睇A "4 QHoڔЙ+gy{%2~ڇB_Esfi@t%{1	f4lزkVEag;oCjx^x	h޲8ѲU[e8h@IWbղ(Gs8Z53pj0a'Xiw3G'@vlY>FE5W53F	:SRh<sF.
    rPM轾Liޮ͘x|x̜m;ĉsuO19;HԸsvl795z_frm#;[W!:Td	]qN}M!~BQ-!W؎]D,_�k*޾@\p(dN>tK)Pbq9J䄓p/W&}!>ye3؈CNǕxq쓨L믾͓a岹ϳ#M?\shl[21�sS@-Caa$.-%XlG8Oc>ĥA덅֙	jKTU>^]~%Z%;4%a:֌t">>{Ù#NEӸHϙ	j/U&Ѷa)>6A?j[a𠁸X-م?yߡSWhq##K/
    ,GV>v89ߍ{lh2%ٛ0}<4mg{c?و7_}ۊ$󿟍E{9
    9#OG:"g&/ǟa͜8SIl$-_?,AU�'hT+"""""p!
    ]OT+w^&u
    +0a-e#xid.%y�CON/_LFai1:P
    O߉Ưp<7o=8%6N;VNǔK!	`V̙)kGѥy#|] 45q՞)<1N+rϣRŽE'!P
    ͚m~6I\i~7p٘;cnsws/6,zr-WPյo>1&-O1];ό}_k/끢0eD{=3Ǖ dϽh(|[%sR|?k$/?qu7q9vs|&|&OFclY6_}9]
    U|;Nq&ը`_ajtQ*c}@`Y1&1O;n]Om`ŢpuѕD`Qo2/틿Ą	]Pm񋎠*6)XHtWpPx0>,)z>l+\XWp{WqX5>=KJdQxop?AZqǴ;oV9<jFBVRՐIc6ZA%Ol!nb8WvO>E}8cX9wnPFW>n`'M6i?7E`xS	d0³i?NCQѺ^{},^4)-prFBdi嵌_37	o?CO
    4GUXjʩ0c~}
    B=90D!݀+\럯"iޑX4};)>1<3VU-ЏF	dG!9!..T7oYmQ
    
    "14WŹwӸU#HGʽMsj<gOȈ݇SD-.AMv,[qim%q˸ <ϛG	eskLKΕ+O!.%
    #z|2qX2[|9u.t
    r':I2S;r{O6^z'u}wa{{u逘Hjp897ijVz8妎`7*&
    85ev>2\ѱ3KrG1)E'Ʈ?O?A|	8Om(
    6Gb	X+"tt2Au`@Nh	"Le{VNgcBq$		p'}f1ye&N4wi>}$mMdWKD&i8fq79>|	gjEcKЦI8g+^"""""p#p/{)amTƍ*[71yJ?##1M+1J&+`gƽ_ҭ(]w&q+oۋpgJ̷OEjt�G0imFIy)nQe&sJh n$,\Pz"9[;g]xJ'<r#.dV颩"G,0Ѹ򬡈Aʒ=#]C{cc6Xw?qE#јƜ0'ӨR
    O?j5>Y d!)&셭e{xm]ho)pO}p8DNui%G8Ϸaj+'& >ݍJ#3sVskB!Qe=N!K.$)ݹߏۯ:[`wcT)/AtD Z	ե'ܘ,Ƙ~/Nꑅ;Pm4(~M>K>U`w0mU_+#(ks+yrοVƿkn%in#P0̉/Oe4MIcgq>mkr\`l2/
    ;+p޸P״0yXqz4FI-ڷZZRejĵ^R6	։u-sFD	-pԤ8j
    p.U{wlb
    m\5έGJ
    
    ɊVވ]R-	G6Oh0uS%8*ٟV,]n"0u,s~1wfOePlmcpD&qB	A	j{䟯2pn
    8нLaW;ߣެ]?zH[ߢ7>%7?8̜2qxF_y6ο$6mF߀2VɷvMiE[3`zNB ѤE{v;DVi*z9j9 [n#L+<K:9kb`C6mHzoK.ǰm0gLY[{Â$?m(jf0?,^Uv$eqqGJbc[6PQ3CP/5m7"�Nʩ')ڞ~zN<S矄<(:΄f}˩ZW>=d%gz7cXƟuG?
    a4g`xc4\϶ӣ-e&Wܡ=ְI?][.+P;_5v츅c^ZY5^i"6o^-sGA4UeAtk %(#vߝJoVawԅ	qpppp8pҼ.2tT!>q%qf#\ɕTVMSaAka\Zdl˅p?o,Ѩ=pxT9~W�*
    4oR.9ڶiKh/tVp6wטVqC1SETbm$ixFF;*!TqJ-)hي:6|^cO
    UsU(ݶޭ(ݍ`ִk#̝Ͻ-X6hֈkι*l#>~9L҆􂑈`Q:`K -'~=;i9,֐kʥ#Ukpw%bUH<2\UlIYy6ɪ\SgcNF79IJ35	(ErU0
    :$TgzMMiOӊ|ŠtqWrF5ud$CM{`&5Yo(8ˉ	VCu82e)-/贡/%,`U9<"'@uZړHQi'Cq~{ia>A8	U\~Q1WCѝ[(Ξ?|{q3v1n}ʐ7l:zJ|?5VQ{ôFjQhz'x@n4q}Sb+;жEW)6w胦Tn`kkcgc8aN:j\p�Db=1^腸FS\!	EcjaAvbV`TfAԮشioFz!^|}1�IW/Wɕ{[o};7o£ϾYХm	c,f<46Ey\VYhע,Oz@3=䇳ÿa.<i	1}ЬE+('|-x{.I83`
    {sM7vnA,9헸1`fcQ?ޭ}mZZ%8W(x#BO1$-kIx滱A*F
    mFբIo'ks1*G^Mܒu2>uLX2Tt澈T&D	a[5ʠm'vBvbv�3va?s?ᤦPDA99;QшOp&11a_ӧPkmg	Ё%f\O9{T׽/8\BKp9itKa\!v,:aÆ
    O̯86gdQ:T
    �0ANXѻ;v4$q5HL'G#F˭)g_<d4QN8a_CdCQ=l$?ǫ~:AR@y (_F)1-
    
    J
    l6Ƿ:j
    rPW=+,.Bh6mci#koR({=z@z#:IFR-g=ӀvL7S`	!+-j4T_ϱmj#?7<2߯[m(t)oNTqE0-nVU)wxèx<Ҹ=:K@bDcrGQm֘jVBij'9"M̉$&Y1i܍y_*NOOӜA\
    E ģqV|
    T9t\)d&.ad×G1l'%\=ߓC7\yfoR8#HD0Z>e=pU_7xB
    F84r4b;op2VId/ݻc# B�req8i%Ԏ*מ~RI:ʍUn=
    I;qc\$x46H!DL
    F"HֵSc{J%j3 T2
    4U#dNzlG7s?:uCUHk+iCvT8!SRʾV-V?CJ<3\T3.0cveSNm\0#bLlm4Fo
    @xKh,MMIM<$NoO?~d
    1fRP)?9:4@X
    	fg&bi,!1UQ۞iӣmipVSG)P㘶"zĭ;K	_DD<ܧ&}OfC'ٱ^&'c 0*|w07'L9cÏl,
    3hPJ8TM[>[fI0GBϔ τ6o?
    arߏOfc
    vFl~f<=;PKۢrvn`v96cǕ4*�ru.....5~U.yd�Wɧ~1qhLW?Eeg!)	7o7$cKKn2Il޳	#`͚3:OK/Sү3s {y֤#	i-pcȽCzR,E3oAV;pg&6W)\)@OѩW߆?_uY|,)ryw6B.=r6/%c^qRcPvGW+Osot@;z_JƞZh*We}IlZ4ۗMg�Itnی{Ry2I:"Ie=ΞIWyxajcua:e	_N
    Ju3>?PX	`]c2ˌG%FꟲT-q{.âкcO>w{(axct;+|J̧$xвv<3v:ϻ2D5J@ӟ­>b٬/NTM7/>~G[UnWW߫5.%^#:`GĭϿ̖X>D"w74/:Ǐg
    dLlaڄW9dA�Sȗ[f%MgL&)OzxUn߄wxL7;S=stN}f?.[a_Bevˇ`ޫÏ`JV*or;ڳ@V+/udVeU9q\P-؋x~UKxjؼ#m|�Afe4#~DA;`J~'
    E$'x4V+
    0{LQX.3۸bs`9ϣؖO%}o"жko4o
    0E3s:TnDzy54[\֫&+!xkv7r/<@ņq!#K`ҽ	�tA{ڃ{\/K<8M#bW~(eͭ3>&6|5~(8BD�:eiJZr]`&ttb5MR߈P?|Q	?͹Vz,ɗ
    9YS	FSn{xN1עŃ[Mz1DP[4
    xg1#-N2�#f4ش~rfkgrg	x*w9'G|th4MM@uu[["HIsǎh4
    n<3~Ә\6'8"CG=30xp
    "0M|swKq@ttZdݺuT-icw=|d6jԈ[V\pQHPTO cӖAhݾ#ڵmE>Ѳ
    tE˽E`tH]{KV-CWҐS%B3ѭkWZmZvH	Ǭ9?"W\w8oWTxB5HF^=4Yu
    iI뽭ii91Xr-"SZcHO3AmԽfc"yktn{f0[R	p奰AVf:DWRсV+pN1Ua8p٧F{XwSnڡ-UC)quu?PX^`BXp<u3MO׿zsٙ֌Gܧ+%nؽ�9~HisR Z$e+!<6zvDt|sb89�ؘWAS؉C>}e)F}**(*ELG"LW 4!@SI\NNRܹcu,d-Z@~}ѳ[7iHd	WyQI84Zb,k$'yU1ۻ;nWnYf,0_y>񍨾KM
    n	uAڶnIWFtMSi7Ҹw=-77c&ֱ-{$!$neu$^iQ>55!]g$R<4!\pɕhiHQհ'w沏tGGNqb>)Ƕꃫ]("xn\M4:4YIh3=uBUˋвKo\lgwtoOqܿ#F&NoHtO"[~3$6I.
    njguBSslݮ:ja+z>+',<h"?=jŲ6N5Vѳk'zHw1	u@Z!pEs8XxtDf?P@n9-zz5n.y9^[erR19P|E3mEd\랅Vͱ1Ww/Gg^
    u~~:vJtJtL3w+ sco١
    z脰j
    D\rK4
    Vbڬ.Bћǽq	26otzW_~]O[X>%%<j/JydXpbkZ&
    '6iCb]ݧplM>ߩM9
    WNn!k:cs|Uq]RN<X=r?sDVecU/^ʀlݐ6]U1t;zoބsؼu;z6<@PsNhb�ˮ139;aը斟Q_8iMb͖F3ٿO;KC1h@?o߆G,wl;nQ9<"+O&@ 50*4p9s@cӈ\Zv_)i<Av2v57ݎgyS8#y<`ڴXf=q,,`Lmڙj{#/	)1pH0<:0㳌w6k֌Z([MM"Mֹ<E½KcZN7Z2L
    غ*779:w=w<s&7:ן#fL|ZNJb>`{#֖+G+OfFg_+/5?\9:[ְu~VeM*Zn�WfRS~"}rGP
    O>MΐOiyڙ�!WC&
    )Z唾CR%?
    tΗ쓔,|ȑU22TŕJmsUP[RWy
    x{bbB&j:]ҭʒH[AIKU8qC#USBGUsj$mkE_O1EbU^)DV̕)3#^&?\uJS4u4߽sC#{
    *cOs_K7!56+[HuoSKZL6!Zѥ%nE)']u=8[<2~t}iN"B/k>P{[?
    v'bbbV[/?	D0QX,K
    ۀB!&|%W2XpmfGjjQ_v7vvԡ	h~O%Pgʫ-suΣ(]5ʵd0U'QFm^z9Ӵˠ6!)m3IuDP2BKNe1l_ Zמpr}n$FE3N5Of"*%Ǧ<`n`?&+H{i-Z@+i{װX	xЙ.ʨd\'<b(I[xk<'՟Bذ8ff`&__G?0)SFmD5g,c41*O PtH\\
    1u+-MfLN9>m\̣Q~7zמ78}뻵ZM]=S6�+)]n͊0d;'0i9}?M@^	$CW{^b
    3A2x`%nݺL7zv@-u,PpDidIKu5ʄҼ}FS2Q8,5 ,[$'P~4U8WR>{=6IbcL!BQdTCwrdzRl\1LT':dJ•C&ȁ\#T,LDUM%Ϧ<dTx54%OA(MSBs#CW7G8I0Fڙ&bk/IiY{	fI7!ߟӍ^i<3ˆA%MPH*MlOVSp<-&Q˷F5驫<"lC6UV[
    5F#O](oSDB)
    3AM1MV*/j'NYTf}1l|!ǫMBsj1V 
    o&N<`v8?cX>Ѩ:Ă~vP'$f8u4%r	;*F0dB2֨tYߞܜS0':`3KCTF*\mVE#sMhزOafEկC5 ;5bMf۾PUMC)i2138㗩ƶm_ȘXY0^4VMXԻ3^$Ԋ1td/US/$ʫIph3e1*-8W)3g׸%=rmޝ<I>e"<%)8pP2fDSwNݚvKzk;,ڎz?|93,p�%�PL3DC,E߉*N(om-}ݨo0{SFEg_Yi_ls*)qpppp8~CKi
    bY$$:?q%n#`3D5
    %1I:epwOak2zgÓᕮhUW5NWp0,9=ۼ2h&HsqCen6ou:BB
    _铆	Ϸ֙-*	U/Zm/{
    (鹿jxZBᨶ&
    YCMӔ)qM~6!_VAInн꥖C\06j^>{zqLk|kWBM:}ɹ74PDBYzZuN_0$|Ƴԅ}vkb6WUjCmC;X+?5ڭc_l~z/gӰgݞ 6>	RYl|Γ'wJӌ_8C>l6m˃R\=ӄ=,X|m:u
    l7 Ίij@}U;щqu?PݛU~iaoܫ+/5Eٱ,^?/OJERJSdX0:FZt6;={F816 u_5^0C-XAPNyxg
    q
    }SO8)LqjR@9JO̾Q'@Ѻ\}񑄵yNgcλ6M䀘~m2Ͽr;tzӡz8w*~0p uiڪ>l[R^y}qՠ*VT]$Ijs;Z鋖ah.yW"~)	[gTn:.....GW@?ZHB9#990bxĐ=2hT*FTHiT**2Wv
    S	geFŘO8;*WS1G򓁞C/zFK][fSҢr$ׅFpo]*GK0vvM]la=nPUkL]uTNݪ۶,>mz8mǻgӘFaKc4Ϋm|ێwP*}ayml[P:*o܉.MةM6&ڏ'L~
    ZKxdy9)(~֩mYAkc{\W,]7ʨTWY~UTjD¶FA)S$
    7nҥKig?...7��@�IDAT..0~WN]ɈX[C?6-1\Vps)A
    '
    Cq/f_`PWX	J_[&`۰姦<e_}ӷ̟
    닏7}"a!-Kӳ&G^țMGe^yuuִ=խsX
    ?(Zt/pTEHѲmHuuim.,m[	*w&ML0pGG3Auvk
    l'eERa8uSyd܎_j'~H֩spppp88t2
    |X5̼Zp&JVݏuRwI(Vw;n:!x/ˑ/aI\7l4oZUd
    i]X{Q~	?pXwS)uLvKf?ҏ쑆?kSъVq|	c}^$ޘ{S \~K]jV9ߚ#4h,;Xm9~c^`ݡP_ԼUa{]%5
    aM/Y;_*tSx^mY|/y/%trpppp83eT=ظyi9GHu3gnj4?M(j?bFL8
    -礡;ˈpL.	[{wh+kLOGlՕɣҦE
    ]MCCm//;'pҫ~&3gAkT_;;>וWWW_?g{oW_mg6pz8FuS`W{iM`R@mu]V6ﰖN<l<^yվc04Ǧ7}>86M^]\\\\'	~ܲy؃bіR4OK@kO>Wti_~qp	ΆѮL!݉#	Ͽ&By|/;'xT.21w�y#'x\m_R+W~[UϿ*4gG﯃t(w.j(`aվ{j|Gk?~xxoZŷ,
    Sc{U5(8Ǻ@GpcidլzCm~`9o܏ ?)#Ż?,DR
    ;)?_w$y}N`#2;O\OxEmG}Q(OE2pgʗ.q0VxԟNoӴ#oO?T>iM"""""p pLx!hr⊑GPR\b-
    憴eE|3CCI(/O"ӿ%zwhj@ǺxPpx/ƥyDQhH	SQV=<['Q2#./,;z3Ee(.)#4AЄa56:;#Tr6Z~aĔITdkFBż8J޻奴_κf]LTi]HV7e!]ee
    Zu![F{4?5_xPXXl&i\.:5]ۿM(UV<$TmذLrH@.;w,6mX;ukZaE\sG $Huy'`[.w(۱eӆU5߶m1n&*ޖ7
    (-I6D
    NlestmTٽ{6=/ʈ]ZZZͶ;U6"jԏ
    16[&3jC׹ih"Fq_Z{6mdl�Ȱqspppp= p薥j.5@$|9{~[.~ݗ_P{dt?\<S|8ۦaR\ǛpI1kxZ"fNz+
    /MtH!8.>�acú](+؁p7Yb\?cKZ󞽟PWje;}2!o#COŨ3NCjBCÄyleĜz3z!:GLyffY= #$,jeE̚-[ǬٺWQY&b`|,Æc'#Qu!Zpl{ٲe-ZN+yiӦm\'c7Ǹǜkx3ѱ?ltjnڗJV睆s\Zj!cVTZ	rJ4kL@KBhTQ޲{g/$Hlw>wBLPEMӡ~/!TiTtJKš	K,A۶m:9bӱVcؚS(9y0GPv{kkt6339aEMHHB\amؼ<{wq~6&~1>[V""6#:'!\Obח
    D_�&
    >lw߹X?GHM7܎^iaMNn@$h^Ԑ3Ј#xw~ڰKGhpwǙбKO!ch$*c99uF|(
    s7og(?Qٮ9d=
    :k𦻖	/Ơ3ߟ~\E+{OߋFGӪk\aL
    ]-#WCWYYb¬0hCjUE:>kՐj&+Mt8$NF<[WnY;N=_	ѡՅ1ZZu:bi׮(Kh-c	~+Mߡ{U
    KgbpV_t|uZz$w彺V~|2$Tj"#==v-D
    gI7zt9ac
    n0__'$D`ph9mJB<cţhB+5:MlͩmjU4NNھi+O?܉_{;-egww='mdЏٶE_zjWD¹8TMN<WG[w>&`piOWD#D<p;I׸Dz;[}Cb͚5*wXEEEEE1 ;PSޠa
    n?H~m3Xv9Vہ[ozÕHm-Q}9"39`m>g%<g#mvz}vl2ڵy;[61}c=nTu-+=(~R|2λL3:_FXdyv+h:$m](?ҧi0Y'|ȕuKGjWayͥX˔U29 c‰QSiﮘvKg]m'{Rp{s<vgeڶƟ|8ϝ5;M13I&[,Y-	R5z0k׮5+ꪛ,͇ou5'+x?E0wj
    xaSw|:|;s	'$vُؒ[a=; Яn!ݛ&J=WN|
    kT5	s,Hux}X6\NT=S_D|`0Aغf)VnA'aؐvN,Vʐp.5m+ׅ&$IX@I,sEF8>YY0-:ˆA̩ؔ+`LnEmhL-1AZCZ9FXJHj 9
    ږȋgKULZ;0e#p2}=U(ݳ,E}qƩ hx/M:RvEp^W|jjNH~#|ۓoGmI7Y"=o.&N>z3{C$CkmrV1d+7WY^fjyJ}(-)X(._Hǩ]@.s'2G]fpx֮~8~湪\/݀sRun.F9L)3G1/`wQ%:ŒǖI$xF(Hv_;
    veX2ɲB\J]W`ڜf%pռhֲ9GkȧjfK|aoC*Zlw=xٮi靖;׼i~a{vn>
    ijڗ	4nL@NǙ83q"A15Xn)M2Jpe'biBᴢhՕtUcޤO1f5|W9,|v墪=HYԹ5�*%|k+pJc_3[A.ĉ5"׼}w<rÙ5y^=w"~*-ތ0OW
    <vS
    s	2S}y#+*4]%7S
    ~v*d!EpH5;vCu]>Ჽ`Uʧp¸/:]"""""k!p9q(CJR<ƙ_Z<!ذu@+`{�e
    )<UD,{%}7g<uxcϮlTZ	=Џf%B.м=e3Xh
    8QIC@eh4G6R)wtQeBY4!gOz܉*GzGlb.@݉s'gD0v>pb#Z>jq]%J<E,AT
    un@ 
    NLMA
    
    J*7܇{7b;5D^Ů0+
    TVj]]zi"TZu-@XۉABq>
    п3m]<ѣ]
    JIfVtlAm1AOM8Ip&`q'ݟAHwRr8PhH$fNn{vVK8o;NzivgۑR*ߛv1P(8a{x2"Bɳ@9>&qSAq{vDrl1
    Nd[3`j??YZ`Oڥu�pnٻ
    7\ćF58Qf,ہ7.գNB$6Ԩ4b}eR_T
    xk^\\\\\s<߮x[+{b\8t ƾfϙE㍱);"#cG^WSga)KCb)~X0/3#�#C0cXj8O=`[bC/:_xi(*j$n]ڏ[-ړ.~lق+;:8
    y -AiɈ
    si'w	aajVsVFa$O_Ѷ_,$~"@fgTʴ8ݾޗR q!dr2(׺8T+l}rUU+p@|89{#.3JF&m#qGSjyH�9ykc^[
    A0ʺ_4ed_0ǃV]bU1	#J}H/Ͼ=]
    *4Ue!	y͘qh>"3yAgb4'8		i[g_AΚr~+Suq	i.*GUxyG2i:3u=]\\\\q{
    qNlv-fO/2;v,Ѩ۔0k+{Gቛ{'Ov'.߄_~Qq
    ؅ N9x+(׏{ǽ+oߋMh18EG矡_W?L@-MԁǮy8-fa_ꀗV uĄVZY.f|=2Z@r^
    U+<_�ip(,*91
    a_Cr:QUЦ	IXX~yd]uUQNSE<-epgD]z8uaPc.,=]m[lHڶ-wS
    GܟG*ӁmјF'QMW4:�aഩ:A,vepW4NmsRvCyd6r,HDMiho",Fx>9ilj
    ;Ώ<*,	`ʫ{Yo!І*FJp<kRr3IٔmbqeY-,o|Ehn5VmAvtS_5ٟ�bUS틪x<q ϼ9y2~}=j4M5lMn9'Cx.*546Far.....4Z͝>bLcoƙ~n`0[?\0<iWތA/52^p(ѱ/p{Us{uq۞';b&a9@cd"m,坜d>شh:p4e[vb~͘5YtLCYQ.>yi<1n;f<0Us+:"[ÕwKȷSJe]PUFo&FͪF8>[,CNs)r]h<i<
    ݔzWz>p&+cL
    ee֗Q{6̂pa٣кw8WNUbޔ/pbnKB+M:%{jL^Y'+	5+]W^)/0CG^{gdC?~'_?=Džlgdbʼnrs~-V}t}YUm<]ۖR0K;2uǟ3o~Gޅ`,ݎמ?hqN׶�}m[9"/c(h2i^dt|h'ᄕGŘ.GHڼ
    ~҇߂^Y9HԬUwJVA,^IW[ա\FK[>Aζt8&tq
    ~v>c3!Hl|ઍq�?
    qK(yY0	Z6mh\4stZH.yJ
    75ֲ*|:ezqbIèΩcjċq]fҤ&
    *">ݺzEUoVGm. IT<v?ۮ9	[ۢ0q}r!
    RJGIq(ۦ% aYX>Qv
    #!{5-͇Qc@.ĸq)qٵ7!j_>~u뵏p>GZ\Wps.jYl\=j		Ե}gCXq}6=GM
    !5m4U\)O$CĥpEYĐ&3Z%xmJXYGiLPTn{
    s:;;�k|1u޳h"쳡nxE~Gcئ<b]âm?D5ٶ]fEt'xS>Mk,o1GKLiu3$IU	DѪwsaDXTK}D0v%߾I̽qpppp @D2oԪUa6s{	Yo5c{K׳9OOvB~;cxMRkfa?_OΩsuYfa5eUi1
    Kk.晼cnF"-ylV=KQ=a|-VRnjёe_riHǫɥ{h4Bj֬QxEEi!줆Bhx.bkώمrcB2I,gB4b]49ѶRՄJ+0a@:GbmܣHM#fPԼъ[7of
    UfӤqeŬ=<aF+>f܅h؞AE·h넡xYr5<{W+ Q;qfCd4KoP{UE)v"acDqޅ!1{CM_WE\	8KՄkRWh֟7<"3,+cb6lbl=W#T!q#3z9b('|k!kF}Q啦Z:OjBmƵIgkSjm8{/ƺ_TJ[qav\eؖ8C!KU6T.+99^m\^b;d̝;֭)~cl|"""""["p̬[ZW
    +08#\MWP~W'fqWZoҊSD4 	a^oHUVU3Y&4}*
    5u
    "Ѫm{Tx2&E]'';t}4ԬKp ܭfՅR89uj˩c0?􄁜&?@k#5b],JJ~r6=5XqM*6<Æ<pE8yӗ�/L%VUUr2#ݪׇ72Iq=4<m:O&9Z-(&|20>QͣE5!Ftq`y]i:CGs^x#a,j'LGliAu!a=clkHָ/}}4[lhr\\\\\~'s_SB&1�ŵLe.-]Q׳
    # s}^$rfIqcMHH$oڼKhGԅebqxXzGzonrՅq¤!'<PGR^m?N9i.nP@j&ѩkokqUP@ᶃ
    <DZ-C,oN#16SB!))q@HjDQ;V&I-&h{lPr8yP1Ǧ)!Eâ"E?
    h9}m5ͣ1֗MK}APc{F14ʨ="1ytlt߹^G~2K\d0_UKI}]k+h2:fOg@=Ͽ	x@]83KotG0uUv;B"-ށ~{s=*	ӮP]m/kڼ8@OIX*oae}w<_v)qkf`%l|UCaeVϭ1=7.}#gN`LTg2K@SVuNҿ|9|@nSK}V\"rҐu2BSo+usLQ`Z-hEMf-lw%i1cu9(FG`G�1GFYd[US7ԅ߰.l9<u1+^/lz^,g$,xc[GXUɄ9n+Hzv<89]
    uDRz۶zG)LMb_s'M@f\n#jCѸqCuXTC3 .~'3SNu겧SXSEEEEEGЏ
    :3SMaFΰVν]]`11irdk5rᣕ?KCTG/-o:~Oﺄ[Oϻ.;u5uQEwKC".=T*;#0~Pj,e޴ǏsMqplX2+A$eq�<־CAպ]<֎Ǫ6vjbeU;j(9cCwEyŎ[5.P_t⑕F,.L4Xjy=. ^O|:Vu}S\![$Q�v╈{""""";BGk2bJ0?V7g7KDӦp>^Vsga
    s o?4#셐Uږ*WKj|dҜU㎦~?4eQ~;ؓE)莍oc1Yݘ3sۆ}kT,3sA=пWW4`N`BZVsn6]U+}-#]4MLb4X;DA{[ov/eYX`F{=3|sΜaѴc>n.6eC;j3z}ҏeQSog%߇#9֍mwPwX$Իaҕ(
    SXE.@N/FOf2ʼnWV0S6! X~9ȁ1]¡NQ6Ԫ'*%wU#قN"˺f,&VÔSo/DAu &L85v\*'[/&L@iT%
    t?.)㻸ARʳZ!8EyXR>&`pvصa%܈]I~n3݇\ָ͉i60>Ąe7
    @~=s6QM:Pj:^hպZ'X;lXrRaZP󦞏V^XBNǠQap$-<V,*waF~7}$wOk}I.\u;9A!`zKkT mx2I1Xj-.nH5UpSQUV_g_1'!;#U$jAB?�eN$90b߇#2j†\'&<k‰GBW<D՛pMW^ Vdhz~OCLp
    -`d	S)[�&@g〹iͯ$'Fv>=$Ʒ~87|}mr]ooFh7{w`;ƞXٹdBЅIǥn!FMx>O+ߥ_N5ks&{FOHL8Pw^yK$CPnSM,l=!bpp|K8$w"E#;>]$翛W2SHܐ`Bh-rr/\9]VqI }(Jhʦx
    hkVaOjthM"]^}
    o.Iå]	6=5Jr
    EХF]/ɉr21GݎݡV-8du`3yU&ĂXTOC<V=2[M`,VF$#'{cYF@fv.磒;]*^mA$o
    Wm^=݅yN<6ًT5P5T={53@KA-zwhdDL9q	
    1eTdy?]̽xWpO▟M;*rE~9o^'%A@x&-sW1!N)9.҉3*gC}!yk.B$,~{xWW `
    ^̅Q(:]un|ljD5%`W%vӴ.tN$Iʀ-tc[D-qe%e.tq5ۦM,ǧ?8,Y0|1Gh~nDo>˟o{I	j5UgqVGsyı&킗J&=hcIS}LבJm^Se,Ku	fn\_>҂L7x^f,`|m߾OHnTl`Bb"s!\4wnG;.!5Ntᒗ:AhymrRw.78QyhF1`~W7?f9.=:3yc/o>v/CQٸ+-Յ߲oek*vT[w1}hIWEhD_Q#9qᕷ⿟Džû.`_3u1x1W[><shò]$FpEޑ-..Z?|ɛ>?8q/1"}8s4<k	TJJ
    Q5[*Iu! r^^'Bnjڣ9EYkNķ>xٿ5~'mgL
    7]._w=
    B
    Ė
    ۱y
    ,Y
    ˱o[qh
    ȭĬjP
    Y(eZp)q!t&nOqamNɣclF,xYD^xIw!.,mI0y@\OGay_"8$7džmܻfk6!f"_{+}%ua HOgj\BUpM(R_S<'׉ʀYykD7׉B,oz2}Ϟ&KVCph8EOqȿro^|�EmV|x1NǑۑQ}!QoE%y?P7}LOROE#&$KHDer;7qs]?;ZUi_6\* ^߂.!a4d.#C{:~;xC>+ұaf,+M됑_>}{Ÿ*o"__
    \0XG&wJbN
    fb!q{8юIUk&u^
    [QXK|:BVQwIhm7S
    鏿&f^ؾ ҏEFe֮XڱwI>Z;]wwOP5.9'5R+.pGo>J7ARia<qޏqU#(A!]i`mo>7b)}V|jn:4v@dQmqIz�E$ĄH$K{5MΧ9>wM[=))	έZj00'A `ht"`
    pB;7o͗܆`х8i^
    ?_tꝌIpV>uɽ1h\0v05臱o
    &
    E$Qu*p[D@Y@b/s7c酉۪pr':HS.zDgB9AYܣ<lٲ	W]~")%#x?E1:esO FɽLǖ)8P$YvJݔB(l#!VGyW[o[Ǿw$y
    5z yږ&!yj{If~uV(?01^>ŻWВ=k8ᑅ˯9r	u=c+~rS̑Es-?;bj<+
    Y4{#ӗ`CӅiMף|B0{1{v\7}L+q3Hqi%mU7܌ZKնgN΁}	:N<4/2xnq5f9O,l|DSQUfR
    xu,+gvjM޸h)A1q/~*Ů`p:c"z|H߇.&J]oG{K7VCKw1NV8P-1GwP-p~
    Ac'?}ɂoDLR{9x}9tQ
    	9a2N6Q!^}ZUV{Q	8I,A p"!	:CeuUpty(r7ZmCS8={GBx=.rLK5l-8lPLP$2T N
    tN>Ora\
    r)\dUM燨vMN?~$$-e#Bp0zZä.<~($	ERQ]_lqT$̗
    գάݝh2aNAhd`P7/>zUz
    Zc1D;5b=OT(oOb3Mljpxg]٧o-)U u0@Er008.:
    6 |3Oڪ>Dz^߉Ucz"}LuuNf*B#H`Et&wGloTzM6ѳLRV}kFŐAwQẾThHv2,mgŨva{RG\HM]RBux{ZJ�'2/(;v`hG)'T1dHHHNR4?mHw;b|ȝUIR~Qiʉ'ZM9A%"`KftzphIgMiiY‰:*/¦
    *zx.)*EY)G2h_YY21
    907eV(
    Kϩ>z	b*,Os#; !8WSo1PVZ[HnQISNWESr62ꯋ
    S̊]ϩņ2*quKG6nC#(- '3$Jr:䄅Śˈ
    B}Teb'Ɂ<.LߟرU?G)1Z	;QZ3}JP(,M9PFgODf{@uwxa5-B"=|=l2m5QAjDM(ce)\@_~KP
    Q%*jXcf=Wz<>S(sY1㾋n!~a(K_Bwwp)I)dG9ߏ?`(	]_yj$Qr/z5fީ7PzGTʖ󪸋cA `8)I<)!>j<F{_9GdukW/=腎[	5n,9ֱS�J#1ZrWfUxznzDeҙbh:C3h?C=Y2'g.,_4iJj}yv0ƭ'
    _t
    IK)<!}7RIx"5ҫ-%ڪxbN[_-X
    &H(L>+v'y)j-@<ap NU?)\DLWHp$R/MZSK":Aˇv+#8Ue)<8?Z(>_2V`E7W9+1߁7VcV4	5X��@�IDATs$]=㭇=)gKشr1>ҬEbIEƭk]Ў}�+؇SU}t�AoE>,uvvY99":ûWNdBBu\tr/F!6~ͭ|cĚG,T7�:`hǿ|\̺j6/WdoKiw}m"==MfnA pF[ZPAԉs:\<7mL0
    3ny+nRn@
    H~~DQ[P(ڬӄ]HuQ|F>B'܃{WE�XO:S�Z	]'~rgcGifMTVz޷a$hQIvղ-@dvڌZ?17Ԝɉ6\ze>[obOq/`𮜅%47?+|j<9mSXPlnFTKm{5x5Ws tO
    .[(Pmw#y^I20.!t렂. kJFz.Ǜc҈~8{Oޜ8\0Gkf5d8C,l`yTL[U/:Lo;H/A8?|M-.D$b
    -]y4!кG!.U>5
    $f|}&
    .7D"gal],@a&}f)x+>MEV77TAGBiRwE�[BMFmX\GgtDsƟNou>~x`,^2(t:58U%PGtL&g;KO5ٮ ܲlxn5G}װ\Ɲz$ZO~i০52@KB-,2XAPdxߛ3ӏ!,П"1}hUjw λ$=#.ETbs=(WS2 x=u?\8
    4nפ ֏ʑ?Fxqk$ڥ=Ȱ:1z?7/?
    SvD'5$Ț!?ά5V=Gcrvs-.M2pFgXNd+|6=>mkۢ(rT"jd.D7?ĺ_�_-]$W:txG"oZFڟOJ	z^nE%VT 58l{9XpK)X9ޘt-7{~rz6O\w:Y)b%i.wXt}Pic5G;\~($[-	3L4VɻfNΝÒ
    Q"x,D&xIホW LdwBXxSd zCtPu]ϯ@Ni:ܒ/�yc."+6WīCнUaP='f=b
    63_}<VRIu1_z:$*3~6hZC	phom>&u#6"I	DZ$&Kw䖁lXGMA `0�06ȥΟ?m۶U[zkSD@c^5{EΝ˗/Dž^Luf+K*njG D]*Y4&5>F[J/A.z,~j/"iVRb3E+71ȋj G\FRR)#{[pIAnn.-c[ Cyq25e\ôCREzYăxmК;&$)$=9YI6oX{;`OJ'ߛ
    :/g�nel[zs)H|Oo4 ^=39f6hɫ4t81SBsaW"..ncر*/-B
    |H<#k>'VX5׊72|ȽYC$+LG#|ͭxYl*VT]gX/ӻ|
    _qx'dPB-E[KL"{񾋂Pwɽ#'X.ԟAO\t}!߰vQުkK<]uU.TkŌ_/˵
    |؅Y@k"/Hr?gr\QY^}vy睇իW24H[鱎`05RJcqu0}MWTx""s5LIPexƮ	JeЃ4)zxoS0v;pZ4M
    $ju'qm+qR&yVe]oYo"
    V%Z+NW[r~nOX_J㮬$HGnyaol1
    i<zuvaa
    'al֮bMuxma~nǠ"Gu9~^W^.~vV$_Rm$];Hʉ,Y||G`=sg,dzҠ
    <XqB@D)tN :b%;4ȄAyWvYYϣ�br:plX	/vut{҆V1qmlϼt~_飼ﺭhT0fʰHZ(2a>NdUM$0|]�NRཉ|uvIKqe$zѳX)$]/!8~Ac!2!]bžN?yIGrW~?@*|J~ЁqZ"͵A `0x_sz#'ϠQ>xlkZAggkk;=:%|7UzM;8Fq.Zs	'M
    YV{oj6^{Q4s3ū4-xU9U^n}]~{
    D1rIxB/ tBpY<K8JǞ~^ǿ#r]}ty-	.R)\$1y-%#21:!+E$JP%7kH\[
    u?6V;l=Ɗ:oy^<5P]2I"Xfxx'w d`!BH%lGYIuo{C55'w_tz֞„R_q@o@5bKBؿ$HUK�.>m9?gOU%٣u)*v7gm/ݗIA	Ϻ[1Ɩisf0Ӌ!&.
    xQkNCѳ7l2HG*6ԀfuYYYhݚ*4ʣ˫<u|}G%&^HgՕ~@WGrz{^{ڎO(W
    ϴt<W+**טk>z>y홾k;2Hp]?6N]io~O;Oٯ<Wgg9	Abbz^)>Σ~,@-v:Ƴ_Nii>ےSA `0XD59(5W=oey
    ɩY]>kO/j]۷K,QZ3eoLi<u}oLymO+YH1m !ɟQmccJ><x;wDqqUN)1Ny<ŬTc.IXq;ߔz4噺`\&N-ZT^y{^Ny+L[3QQ@>}pvzQdв8ϣ=>L:>֕3N:7KIc;Ϲ?QZ'?*	2!WC/--U7Yg>GǤϊN:{|8t򸗹yo~CA<ưlBIkyjOwC8mTI``i `0-
    :k߾=t}NG@UVj!2EE
    H}Qw'#eQؔgN4~γ,/<!ꂿ=xnJZls=cy(':ȸ4Q/gN/G{מi^1igޞ:=u]3]N+5)h\iuǗ/ni?znJZGKҾ'<k\s=}}ij{G'R|D:~<I3y4V7:%G m&nȕ+WId}NM0@KAt}|<Y:퉂U:^E>ǦgN[4C=ts4A8Xxc0
    A pJhl~F|2==j
    ,,,TtD dR49%%%
    
    U&t&Rֻ=1		QG+P9fʶ/"Og(dH,Ii/|@\RI1S3F-yI)y%_dIE!ZTM˗|Bkk,/FbN)rd
    ͹hd/ݑ $^IHZ{]|l<J_K|c/|Si/V?ݤDKEK{K[I{ʷ"߳/xilv
    QBCm%/H[h޺}A#ЉթO{;/x]WiCBC}Ac/|pオ}|ݴol+o<o]hJ_XSڠ}A'n.B]p{_7/4
    ~7\Jm8p�-[ɓ't&AE#Рի8	jd%FYke#A)uA "G\3"Kqeo/u"u{ʗk@d%օ/d/
    =k,>Jܗ!~gE,z&|)	-ԡ1meo.>%_nȗj+{VxUcm.՗5\رl|^ˢ'_wmVVq*.`UL/ߵߐ|DJ5|{YNF_lk<;˺]~]X6춪/H9G;(u5 `0-		ѩS'$%%2ȀUȈd+A7ؔgVߔgTȗ:R~I^XWZ"ILDi|IxGI49=K:?'~Af
    B1B#  1ME@Y%A<"_LL"uɫo\iu~RγcSʢe؟qiy}iuN'GWўV7%<#}FLl
    gu\}MO;xN:=>/;
    )e}6mZ!.M0XF&A#p\ng
    CoL?66V9C1-J{޶msBą@eff*'bi#A&WkSDX04'FA `0LDOfFֹhi8˒5ftnZHYbbb>n&͙&D`	s4A\@s[PdfLM^i2v"OVi<{>9Z:Igƞs^bޘ{,|<hŋ?o-mmJG;jzH}V[ѫ>kK~Ɵ
    A97 `0!b:k*G!artq@.DSjNeͺ\3^*6eEmds}"|ʟזc*zwG,HARn/]^K>B/5 .Dϥ
    ޔϼk,=nO4SXYHͩ/Erl�)L='XH:E@h+M}X}}׿q(՟Jwױڛ;A `0,A7= JEbXt!\$Bhv!/:7lG!.摙*GD!$(dܛϋyW$</ s$	I+l$!/.*dz)3:zi#4w,M;~>>{%,s2svFJ yOm-G$Uq'byK\MxN˰p`.gE/s!8]vTe?VG/uzTq'9Z׳.l3wJGiS�Nqi9A `0\,-|dgBHTD+Z]YՋ/UwPCۯݏDZN15ފ(Lg\!#n#rZy/o^VS&cÔC{6cΜan>q`2u*^+Q{+|t{=_旕"}<y8"|1嚿b#FuPdNdH")-іZ}5AB-ǃ[ר2(*"65uJ'2YPuV\O^`gNHs8v5udgHT}yXxWj.pj"㜔پa^z%|`9˸;ۊ�XVXH_QUVz}n~i|(I=s5ۃ)_;ւ3E1A `Al&dY]C`b/UisS2eg:
    1{Ee5IzjS{&R<?\k$%?mS1I/Qʦ_u~�z*T4ri:+%夁! ~48=bo׵7T[89	9;҅p\$O
    4]..j+**9aźrW	.%=)EVw[fBȹ[X[e&Lk|_UTNj’V,DӊWꭈ5"GL.ȟKAF̱91s?'"a<_d	>_QY՗%CO0eB,~ڿϿ!d];%!!2[e+_|ă|HCEXJ+7'xA5LUbibe?"%W~UI徻LMA `0L0B.OBvC"cUa!d5h:+3s!N6bŪ5-BDL}Y-{PV^	?ݻv$!VŢ%uux- W~XrR[R!#ѯ'&adH$S~*-P<x<r=	٘?cQ;,48-phv|yd3RD|Rw6!$NNہ+Vb}^1dPF)۷aæ-'v鍑C?*sdh~p7[ŴN>
    ڷ"yzx>#xrD!<Gva!z×p͒a.K_N$DD[XvIM}~XRУWoJp(C$#v,^D޾j9Aѳ[Tg`)BVq<2
    Э�
    )6`kFMl$1	*EޥIO8j!?Rj;0$FMDUCW_V1a:r�o1vD2ذ}*I1?:UF`@_�Tb
    H1EھXǶCXjoiҮc7>m2C[H10A Pn.,m%i
    -WcW|phȜR=&;q]Ð)bd֘+ƐqX[xyn~]oWGB@βv㽯P=k>7_?)tKWom>WtoȧҞL>'#Q;f`d{::
    3Nj&9)vޥz?>2`v}w^=?/}|*mY;)|&u'ޣDBQ/!$8;>~<
    Λ4YL(Oǟz~A]bw=i8~Y~:8rKx~K];<;^w=2GaO ѧ_>GI=N1r�,]?.jeRA֠k-DzS-hծ#&\87u뜀6)&\>$>|o.8o�Ò+xNTH�d׈z<ro9)a`(:O	3?[y|K3Ƙ+n:$F(`0A 2F-lTg1Y&I8sAr.?	O9sA߮;7Ү)	!=6kLjoj'?=qWΘ�LBzx[Ps3_{ZjCmfÕ;3;<P*ۂ\/04w="98LJAIX<c<k}(Xh9p͝7qdmXi\EoqO&Y5!4#{1'+=m-`b/$WS1_Ah_|xXavn3_K,׹o^92@F-_`pNC\T$^YC
    />
    3Vbq$;	AEK/aXX|{y(_sbucغw?W dOl5>gZ\F!y(EWo؊1}[ckbS�wŅ*tnɐDZ{,HlHz.w4q2	cڲ_*}"f܂iӦ0
    )߿og;/ZcPLPUA `80n]u!b~.[F{oŸy-Q\L[+$Q|'|L|‘C$$4߿{>IoAQwHP?L<<$3Zn	!hݦ5]лk't
    د#NQ孻LN,y0F䡴Q!& k*Ν{nHݹA]WRNiIdY]l>cA+FZf?nQZ]YO5"ckQ(S\*<	zEvֳcf)ml\30O,-!Y1p~,Sc-	N/TKyUeϻvƥXZЯwչVfWq
    xBw!%ȹAkͽDkϾ]Qэɣ;7bEصg\2jؕxZu3Y$V:ˑ!߷csAKw/陵{ `0A `zis$@s-c:tM}h*BFګҠ*\z%z&%*'hŅA
    0Mgě]O7T)n%f\rvFͷY7;h5,W50?THd!őDs7rߵںqʮ(v}t ̠
    T;WmYїǤ*utF/9	 NńqK7_?n_
    ;m"}ɧż%нŇZiU%YM(FW~IŤq e3nLx.pu"gК[ge4OOيow@8_JOt^~qHgxi	0N9sOlJq:Y?-䤍nQ?ℍYI{{:̸d&
    );6W	ˏ>G)^}:ZAmjg$@<ir2ޓݓq1
    a?#fHLTkТ`41A p#`a�LO-pCqEsjoŋwMp@7
    T""2Wè"j<e&H=-נjjoYB]^l'E3+GMQ6o݀a\3.�YE")X'eBɗ}Cc1buOϹuᅤ_e;*3\EEl5)!{Gz( 	Ot%iH:h?Xd)qkǞ7vAEr[u뮹t0|>yk1rW-~7|^bе};xA
    tuCt@BOK(dhy++.QqhAA(+*%֒NPmieABE5PImRL?K
    z:hR:Wh4Lp>K=h@DБx//J^BZJ,*sklg%|3+|9:#jtE]z
    r
    NeEXz
    ʭ	zA `0<Y]"<+>[&~<S,݆fjMo<st8
    fQBt/钱<\}<JG\"2GSm	vyCA)�?7�'#jØLEn0ZA;)5ËO=^ys]4}Ы}2
    e5Zv|*;H~-ȝc՘~х3bܶ0^߇m	&0U,[.zxxܧF
    0p+
    oS/~�{w0^0o^k~�=EPG&Kd}>\b;tWM
    7]�]zD#GHhejU5gi}d񾤢~	-eBRAgXh?11o}6Lߋjڶ
    ;_}+}
    WpҥN0chtx#|[
    t_>_={~fU}r
    5':
    A `0Z
    \XK;PrTG۶mэq-gpB:F+ָ'JiIMo)#c[1erݵ$'..F!l@é((*Qf!aልGTX=bCE%T&$Y72ҏQ*[q.2#+7[	bL !!>tj!",XӅHd͹8`̜\N(poon1XRzH;ֆXuYȢ4pijԘWTnF eEtdz.RuwGFǢUB*>?-Bi	g)e"Z-$ԇRg>CۯABX al-9Yi	,i_^MȽY,#	R9HIٯLݼd鑝fň4B"d"#3ށ!%wnnrI?U-I&qKO@	=˭hZ#;85oljZV:
    !
     H**/Epғ{q$3q>E4_w 5YU>N˩y'&1q.-
    @)XLȻaL:aaaC<K+)OFoi䏁|KZвQ53FFW!=^TT&}+gZs[MMMzem8˪9H%8oj5QsGZ'8&UZ^IyyOqp8=3/[xg(]{/Ih@^V{9n]֏|zfdLLk}BFe-ޏۇy3j)ubAQ2V[P5̪gaC5~ֺzwKwԺ^4*z~=ģTys4'eݳBN9
    KWϸ_Vm:(,y[q6T{y.ğxKeee1jxEje3iG6ĒԴ5++mjYL`}nlGWö>
    a!l;鯲#$E,au&ҚKA2e!	'>;`	h4S1q?ŀ/X$E/BU J^("K!"-ݨp{%8	z%\î	%]%yZYyWYeVTX^e:)5ў٥[H KI2%]?!4ZoޓJQQnɱa	RZ[7i n}q&y[.jKD]/4R&G~?.!oj]tչ	O]^NιW(8\SN9)<rZNٷ]R6)U	9~8ARvAnHZg[ljϚt[Fֶ˒:-[&eT"Cbbla?r"A `hvAovMfЇԠ
    1!\ў
    #♷{+Erb.|!l_ikngj*igio>H4})A `0?Cz&# nY5ƥԞdv+XzXHZFF"Rf;5ڧW,e~iZ[ԉӋ `0Cna$KALF$LY%{Ǔgi;+e\N#syƞ\]tz9֕Vɹϼur2{r$gOkݱ~u~`18wˡ}=>?29c7;N.y"Q*ԅӘt&boA `0sCV?u!CЫW/5kOcL-M섨۷OΝ;	M暫tEm1la:מty@'NQ'&&bҥ5$]c0A%#`zKnlBdYWlA!d{5p*&sdمų9(rByswqfI>
    羾.BX@s.3ͽ `00>dL|! ^%:*r	gAՙ8HST;ĤZ<1H'}P?NsO/<|4J]\Vޜ4Q'=I;i=)sR30A `0~4VDMʅhLupr@XD_wdu8H8ZV4:dFgvrq!kow2rDs.ېFufJz6)Պkۤ-TBBZ*Iƅp-qܦ^?L'zw"t;lܓSr]cKH1A xdgF"`iw-S0JSȅڻM	%z4=,Z킂RqeVN-=k@HQ= ĵ6ww}yx׺Rn#?Y[.yԪw(z	X.򊉏*DO\# `0!gRkvdUWU"7'ť,P12!^W /E4XNʟ&'.>#rӰ~+*[z@bmjR@=^WW[ޯsqXHO3M~j]j.ɕ`;*9(-Pɕ6"$PkWQQrW
    2vBVځf?n捋:ya'	y:yymɿ@2A `0?c!4{#=]]-xw!fӯ~@_Ygh[,z*ŗ~خ#0w{u;=e-*V~aAzh	
    YVUsO^鲼4yOw144Jkv[꯮OYY":^_I�'0Ç}*鍡cA8w+fA.3(
    {uǑ=q8k}JT`0_GJV9mjU(_셈@oub8	:'9gTy$vfΩf+l0A4"`g&k@KGlˊx7cƝW`ɼO`L%B+ˑB#ƝĨ0=3VlLAHN:`j+K%E̊wU#?7y=!ĔBi#:UQ)Ǚa6=:zEۯGETWpM?3.7_܌4,\acԩ7r(ڷoFadrlDIX>y<ZŅߢ5Ds%Iw9[5@D3W:qBt{c8H-z>5'AO؁/ޞƜA `8[0%M=NN.؝xeUϿQzyd.܄o@j-up:؟]1wzM1uV.o[҄wg5*!eΛvۑky.:!(IgᅢoWmUqq%Ƀ*[pĢ 
    srַN*xMh	ͥA=*?qcΰ0nfcص3x"5<%ѡkGl^CDvaީr_WP3u~lLVrlp^´..ݟy9u3A `0?C<F9hĝ	g1|
    t>
    }TᣕBY~<ronmw_EN1I^4;۶OAl�='7׆IX0tOG=_܎o=Lj4V|rl^1Sq33qرzZ[#3Psc"3PCظm>)G`هܙp/g?bQVX*a7^
    gwÓY<lK ?63
    ~ `0C6;YMkv3ˋ"|xٿdϷ-RSܴ/~xJ9iK͚}x7rKI()w"bOqgHiOߚ|:OsW&bxʷCT�>zS{#0qW;҃rqGZƭLVk�@/p#(Me-Q೧?ůz7m-I置tjIlI^甓8rZ
    .'FFA `0#`z13Ohi
    +stneJh<]# ܺo_?>Ԧq4š\DT$|ײmQYWr��@�IDAT2>פoնnEQA!+0y02I*u=NigBI4\Ag~}5S'EL^ů`"}i1Ѷp?a.j~@˳_8j}5/y�\bс5]Hͼq?se0ٍ!gwڝ4CBBmVt_ C?Oχ_o3FRl2mb/zZw\?!ŭD}$~(LYL.vvܬ~p=,>\{.Tr	tu<<\2btyGƮUxwV#Ub/s!yHtlM'r33iNhk7A*烔܁A.bop\ޝ}�-t@:[_Ȫ$T01 `0_y my धZt	'_]۪
    )Tw3}g}L>ĪmpR[wAj	ՙGI(8noRŶƤ+.ozf 5e+:d0%DcxO7aw?d[pɷ5fՖ3Wm+x}}2{Aj?<.~,{A혈VI[,GVN\HEȽ1:t>'MUӿ,n78K`}
    bxgE�sQ៞chRK{2A `0]
    ՞6͆h-faND%{OMC"1G9@Dx}"<T}xALx\{K߃g;|q$уӯ#}	w2m&>p2;bf>y/.|ўn}ݲ˚
    )Xؐ<�+x}}2ZlWWg Cd$<-.5f^MK%m;bUy\Hw@ɵħ*¦ޟK/�¼<pכ2TMdA `0AQv�rh۶-u4H}`<͌O-\y�FUl}ٖ5. UtlXw>|TT("kHHHl|$ @nrƷN=%oLi:uRS޵~MW%#a4=m5$\xMy)0){w6!v#*@GXFQ1pڨR8%X\\֮;]t;
    qi#1zK]Ni{8ty	{Qke֭[@oݺAnnn.͈(ERRRЩ3hc	q(z;j1q~L=׃C.=aH"..N�	B8o<8NK8M$! @zHXm6DЋ!Rr8C1\LGE+8'""5J'R=4ڶWO=iڔtg[T4?n'33?pę觚lT\:$:>N3+Tx)}y8Գ(!_z0V5/ΩR	B@! D@|
    (cY0af
    ƻsBN73HtYe/^ק3s511QiMMtFsd5y6bNr6tJLJMW:m?Z6"3_šMjB@! @p&V#	i|E֦WOΣCui7*UUXX>bqhwf\.o2KB@! ~ؑ`o%`\~I|vu9sxz>v0դ]UoMX;u»uUHu1m6 (B@4
    "0N'Yl\Ry*y*	$KG{۶mJhkz98c[γ<D͕�6oެ
    Óc+5	! C@zUT~x7!k,iZ*^W|@/O9%KUq؜T-B@% =`aƞ.] &&Ff/W5Eg7p^~xpl׮ձw39'*B@' I$s:)hA"%&vygy]/v3Ceḻ!NE3woA4!xz볤	! BFTȬʘUqʃ^y~~V:Ol$t~<ty		v~x)!-pma
    3
    Z.B@! ~K�"	#`~7՜v:j2Mɞ]*OoMQu!	:JIgE=Hkt']/>hC\1[MZT4\B@! hBfWBQӟYp:5_keo韽:x}_,kc[zm*@q˙@8U<^7PDvb_]C7ɂ5ҋIPRVT?h_{P$J! hă`V:VX`(AN"i׎-؞
    '~:kA퐚Z+q˒S^]z\W4Ҋ|r9Trzd__,"訰-pDƣY$Xh0tVcDY؃>!Yiv%7Gr|fe`ˎL$EF{iZ{>	sς_
    A]pb6? D<={Py*	! B@RؗOW</6ؙeܧ^	/_:X,|3D8ihF.FdоkA
    sWm"fLP?~C?>$y09^r'mdz<(J_z[ Dٗ_SUߋ00/By%npه1,U==Ï+yٳ$2yB@! "냺	0_oCBGFy`$lh<\N߉qٓ
    dދih$Q	{vZbbȀ-,MSOZ]GpI.|7V-.ŠˑSC"5Auavf$G(ٌ{NqS>FGa/Sܛ߱ǠIlaE	ڃ_><u3yӿ%/z6y{zA"IB@! hTD7K
    aNzQ$:ajsh>Nb\>E8#O�q;FvK_;Ly
    Šp~1q/Cg_S\.ARb]a(ܛIFu}/vnm{�%quؾjz?C됝7�]~71}hڡ[Љe겠k$0'teAv1pO~4/MÂe4w~P̳>퐶B@!PD'}ipc+w ;hl@ȵරDg{['b7A{_)'D+ۖ1B.|^6	|hGg¨#lQ)[o~Xyu1 $Gzux앗>9{|d$ًyԅ3qn}?N91c]ݽq1{IE$E9#3U`;h7O2."Y{H9hhy)`ЦrCB@! @}^KK#F"{JKQ"!*wND3[顗1+A'bXr#$
    .s2ڴHQ|οDӿaOn?qمg"μ6v7%Uɯf!^=;x;+݆ 9)4�4U#qBf́A"M_O<|g
    F!֟9j3֜~[xᴾ<̤
    I+/ B@N@zCa_(-)ưCqckMѭs;ֲM{$Ӛr#x9'͙Ǔ{i0>:q}{VwS
    _Rd,&֜69ѼH`Ƭev_S㰝fY{Bx0"\r+VGSnMg�gӮtW
    fq{OY0:
    $tZ}\JB@! 
    "k	Xi9=go%G7jtxvgХ}Fš4[OD!::I[6u5Gu5`W"8CˍV[H,^Z㑜MܰCN]4{~LsxOXǡxFb„3mlw(&j{~8?{2%)�^яg,֤kq! B@._!P<B7FtL#eÄAe77/L7BbXq7z4CӅ'_7b('_!ٛv{<+!KzYW3.J[[8i:{/.Nkf)qTM}%lܼƣcvp؞v5;mb7`-EQΈhD:?i6{$+B;M䌕CӁijMc˦S>>/]dFB@! @^?ܥM ǿYmc[--W	vS1'_t
    {vFiJ
    qhaͳYcؠX.Ne3dyCz3f^•۵1y|&;/5`uJ<.gDǚ5tb,ҷhٶcus[VP#H;]4;-5^�ͺ84S5TW#! B@'l#P!0~t7Sb/,&^q߉l}M~K
    ĂӱCTiEpEqaaIIƑc:.i?_ٳ4A
    iճqӨڣ,-|yȷqs1QLIuxl%! Bؿ:'IY$ڢ#M⼲sAHC7}]b׮]ؾ};yg+~ ;xXJwr;6%$£~+VDF/Pm*Կ`@<SB@! @C& !ns`PfU͢u?seiӡqbćYq>Wo"'$$_EOeEEELcăcSʦBy<GB.>rVjtt<byC]^Q~e(Bj<2Fe*6LدHmFh괂26;(u! BDWdY,r8ކWDbʱǗn{t{ =AJfQ)|u(! B @1ir>Z?<ړb{,rhC=+I8p-ι'<rn! 
    ;3{ҥjpAA?ĵ(;sSյ_<Sk<TJ7e>T9JlYGEEaȀi	B@! h,D7~մ4t,@%`qXtd&-Gmw|^ӦMc5G_ B@" =+]8{bbb?ҁ%0݆!ckYs8욀1\B@! @
    ^z
    :/uXKF@@2nZdp
    AΞu	
    >Ź^6Ȍ5! BHj
    㻆7	ړxy
    0~>85Q! F3ԍf4HՇSPjMɚcaaajy@lxlW! 5N@z#
    �<sPQŵu)~ z(ky:<}nD:wxo)ќ{N	b[b9ϒgiT! O@zXPX,Xh͚FwVUe[{̶P6x(3Pe*:;jE#Ÿ:^r^2lg{L&y<RN! K@z@xJ֝KK=hު
    #'},7%.=>`h55!W\ʐP'iMr\+{j{X'|T9mҵׅ?|,ƍ9	/XXnO?vsf{˓a%~"8doDE!ե7m>f-11qF:A{7 c}'6en_>B@!   A4 &k<{kyܳWuBBbǟTXw<(iJԕ:?IaUF'Wb
    "?2;(/
    8א_|fYǏ8	JnJ(MmZMRQN,^gq!)	>r]>*NLm߸}گf=̹[aƝpOxg>ޯ&B@! C@zXR%*	׎޻;nGVM-u!++عmV\]{I`ej\[(p*i\˗a+Tb!7'{^ع#vV^x-=%@Q	vaXz5V^,ebch&cQDe
    Ξtw&ށ'}<lX[ܶ#7;+-WDŸ/34W^lXk֮WWº
    go>>?BSp/`yK9!7]oaa!؋^Ẑ-kS݈gM-*˲ߧD׾aٵ<:
    i)!A! B@2ȣ#!û*4<z$#<<\݉Casד?Eϳo=|;,YgxG<|v[^Wl'<h4!>bƜݮ6܉kzCQm_47<!ym8v/e#j!)�p}wcPJ4z9I}:cA:yݷ_/#1̋N]:a?uHr"ZLŽ1os1okO+f eUx<1-;;LLj=m7]nT
    ^)\m #+/-{#|7K\]{Rw[n6:Cf$! B@$ =0E:*,h
    )]9s%"SwQ}Տp#qEwcc
    HKN͓gQ}.c:!Żݩ?޻oO'ǝ0&='l$n%8ϑЩ&Ԓ~\:ŻO]nEkuPa)ffbwX4KY珟㶷{`2:BTbfo7_>WWy(|k\{z/as5@YYw"p7Z&9z2v!Pvp\O$/kK;˗]Z)B"Ч@o�XBB@! @@"F
    ?HjUF
    ͖4^pڧ5fR1ڛjd˴44OGg.['
    _+p1OՏ~_ޥ8p]D6|w[,.-\b6gEX&'zp+W[`wV!:i0ӿ8`׏{uj6!!&~ߎWc{PbݺX!KOMUc016?T_GhiVzytfut>jM.\p(ol1 vO! B@�' k|ļ#`e)ZߥnQ1	0[4=s.!M;b7v0fg`֝>z{[)_Qaβ=Ȍ1ob,^NF>M{>r|aҭ+uM\ogHrm='a֩`#נq0I×qЎzuX~Z7g	/%w`˶]}ӸNi(>SEΡxжUs<ؕW9	`yCmg4Oo7Oq69	vg(ynbZc*ī{m]! B@/K!!
    C|R4Ì5l34pJǰ9@ڙ<<a>.&
    W,}ݏuƚrN(V;5FS,A
    Oh./4b-+ASv?}7N8IZs�	G]>:if5i	>l/'_:iG}6?b<bdmv—?	P=ݏ;;6QmkC>V)֬Rct:v.Et6'ҹc=D^.G	ࣺRjEuUOKmW@[mᏘގi LX+
    ! B@# I#bvo~OV,a*N2ػ'Klj5Iw@W w9xA=M}mSO Q(KfJ`sy<ź%7S�doNnCN6ݾ
    .]/~F{h'ӖOÛSYl:|<#<0v6\rYQ?ЫY
    u;b|H~Gs.9?n~OcX<w"bhm4R+֚o^E($$V)ckM/IǞm86z
    5S4SQx;2f
    $! B@@& =GGl;|&n^n6|mU:2,&&w:	mӞYY3d,Rʻܺ[2/n+oG\Rk67VGtfl:=ўrl~nHj}ЦY-4
    I0e8O?Lhl1@?$9(kyG4]z
    {cѵbDh[hv=>2	=ƝvpmϢiiv ,)oN8ʻ٤+9>i{s⛟`ݲǓ^@4c:h}C/Es<sQFJWְXv6v/l,B)+)B@! B XG-v-1G/hѢ:v~jVyf `N͘1M4ANosjTY,[
    WW1Ji7rA~*ǛzMD_;d(G߅g?$REEt^bCD1w^\v9inZ;jMѕQ*8hc8N�~KN1ijxZ~58={vv㏏/2S$D3Mr3ymZyݒewڵKmٳ1h iVFQ~qy<zfIB@!P{LdkY5-C%fqZm/z
    4K4JUV,G"r@~0qn*6lŠt:Mfq)/$8%t6X\hM~TT:nė(qa(a^uF~a=,E3cǽ$V! B@?^c ,ڴ&3ƍZivĆ(o9kUj6b|EYs7޲y\
    ܆V˛JԶx?ӰuwZ lkx$U%vtcI2*!uYկהEROmX>ў)B@@' =GH;b_�s%,vA	bSDU\rYS5jW}[	*j>?p	qI2RXLn.]UZU6@6cT޵ g[؃%i*hh(<Oc{t-K&cKKKիۗB@!hDڈ4{�㮚Akū:>%'~vj"""gM׳Hg;]Vo7_-sp3an8uN^s{ks<<UpgF\! B9кh;kh6=Z8եM,]ox8	
    �l
    װXz'B@Z ӕ7lؠvkfOZ�d1+z�F~bxρ[qPtB@!D4\X`1J."PU{ž\:{"؎
    Q汩1(}JCyxwC%! AH@zZ0?{6⍿$Tc啴AIGfeexB@!X@o,#@dŁ7/Y�
    L^!-uzS@פMbB@! 3"4	|8;?E~k$999Q^@Cݍfpcxy|Y�|ܽ녀B@!ph"Hr0V50tfs}&b,%4,<0FB@! ;@	nW`۰6uAUiX{uJ>(YrP<(B@4Ao$ݘY@`U-XV@\5l}ku-܍ӟ⽡qCNO~IB@! @c' A})^a/ղW
    QG>('Y>kTUZz[
    gѰssNJ`wnxm]p}}7WmPZy[̀YBm* ' qp>*B@DW&"
    �5kJY'>[xZĦ1lIڶtE+@K-ʢ\Su&AIJ|>0+_Ǡ}$olaA{2㹗YW݌]i'JJd+|T??,02|Qvu\A7Ta22ጌELdei/B@! B `%dl\|{ǐzirsfyeġAq4NpTYЂw.U:Q8kCl{N%סΰ(0q,LI<8rMi~z@	́.sR7Jm)a_٤bjCً^9|Hi3n,Ϣ˖GȅB@! A3�/
    #FBJzw†v|}HK~;sKaIn3f'N^^44{\MqoVHߴ}e瓠w`Q67laTf]n4o:͓߃ٿLǼ%H@E{N0%qS@)O__!cL:
    ǴżТ9vmXLw8
    @<\oӿ%k]>ǐa_uF!ʥ	ÎGRTJ
    üEd[}#"57dIv>O1Cz'[ZP}=ܠ
    ~, ο/߈%%xq~Q)B@! B =IL<:~]Jk%+͇ZrsW}A$F'oV,[ٙx0#F@Y%_v`L8lpz1ɸOapl',eUJOpnnt@q~^3ZǍ=Ec)+O񿷞<v]Eh\{a2?u~Ewjw=v|	|ӷ_;/ĈS-g?Qs:ƍw|ErygͿi/Bqqqy=hw <}8^$Ѝ
    B! B@!᠉ɇGj%gDHü.Dv+u9vge oVB1)Ь􍘗Sq]0x	<;W'>|:^@!9u8a@_GX13p⢱a?H;3	64v<TyyjÀA'БgⴡUͫ۫>~M9bwGxA9W޻^?V]T6,.oc^;vHĖEӎ+qmO`7pl@I<z�ޞ#
    hu}x{$<d2Py}j!yV$SḰ=Y5 vJ! B@'l(sK0_~?D[JD,yp:4Ŷ5/`iztʿUϓim
    ן	1јphڦ&(.;�r&7^|ZGkAѮ7QX⁋_s@fg'q9+f`H߾8̳iZ|=zxiiZ^.))ڥS=9r99\t('2h.W12K0>Jsl
    (AMzYp,ȏZR>Jc~(qeֺE{ӹmxhgzfb+gS! B@#8jbsyy"?*<ch	
    BLn?
    ]'9mJ6=Ͼsތm[6'nŒ-Yx㉛p
    a賰c8e"./S8
    U猀ģN텆,_-݁bҹ7?58i6Qj~|ǭb7og%3;g+pn큗hʼB.c:=R]EJ7O;:5C!aJԝV *x5~UXɻKB@! N\aNJZDglTYuv;/ܛML9'lw Ӧikֱ;NE=شq̚|p7?_Kh<z:LCB[awf;zлq=z4Y{h1|Yл8.ZUkר
    i9wA.y
    YE*ji~}iϼ֬߈?Ṁ:#qӄKzBKP%6mS[ǯ,dglƲ<.O籫Fp8z~m@cB! B@ݐKEiM6#fѴhGFq&
    .mRr|3UAia6N4g\z-Ӯ᫳"7
    ڦgcDVX`)ޛt+Z6OAƵc~1?/ųpֵ{.:ϽbĠn;&|)8v;pߣOa`(n8[#㱯^•IC.8j-]G-j÷&Iԧ[/Ű`@x㳙ӣ=įB$#w(;?o)^N>}2*X
    $Be^! B@
    КAE[_~A-бcGTW+!phԌ3ФItIe�5^bVMHHJvS(`o۴[ҳܤi4V%&F;܉]p,&[e ؙ͇'7CV-`/SR͛6aO^£bдi3D`g/ty6mKGjj?MgaiZєQNٓDЮxf@Vv6"b؛twÄ^4N7!6çxϢiqz~.lڼ
    %׸D4#Ü6o񱊧檌=4cGi<Èx9c)u^#RqevR0{l4qqqjiHK@ܼyԲ^z'i! 4A{j�KqG/ZVhQoخ1}y9`):qszѮ̑TOh]9к}'6MۡMpcΏS圍8~@o=&Ӻoe_^D[Q:<4x@ʣѝ^]O,՜8(8^ϏbCuͱgxbB@! j"+-x4N*$PY(X;+z\@y4J:h6Uyśn"f+s]#,4;]OamH:?_s:JQ#cCf
    ҹfq}}dϊ/mEkM"i{x3.'֎%Rkmc㩯k=[! N@zw_n"ayj:Ċxz:u).++KsSU<UUQqE7'TN*}~ PAOHHP<%>7&[�!B@! @Us?(P(@U`e_r~CYiO-jWKM_h{CXX`!WTTm{3"Azk	F! AC@zU1T.?j͵u{sknk1g!""BÆ@W8:h��4IDAT,cn%A! 
    j^}7>B+0U'GF@{OY@gA?#cȥxCCC#nM! 5I@zMҔI/_k~
    s>-7kԡztSNѢ\]Z}ztǟ:?AC2t}܁vlذAsB]6{)׫e<pz)=B@! 	@?8Ia<cǎHNNVӕу^H`VSSSSעkab]xxz ! B@46"ۈsY,-	B`@w:&i
    @\\zx8eB@! 	@/G!uAlR\<uA=Ђ'jl&6<թ:yjx P}bWmoM,u! B6	@MR~G|-?C#	9gIIIJ7zP
    ��t^¢<++K>
    ! B@Tj
    �*?02x:t-!&i 6tn뭍~U^sY({,C'�c$	! uC@zpV
    }BZ�SW^E2ErT|h;s͌t;t=ِdW<v,yz5HB@! @=^ -zLñH0!{+<|:WU*UWeJ⿢mnmQVe{t%o5O(\OuTFnuz
    :o,AMVr5bTRgxYҐB@! �1	hq{&lؚψyK:ѡsWGG<y_V{<8aHxѥHDLJ@^^^k�!Ey(.":&6k,,"]q{IJ^_y}~DYj=6j	pY~Zd1CzQFm;oؿo>Is;}r'B@! �	B`Ag?
    |1u3e*g,!$T
    ku6d[7.Ì($0疗as_q'iYxwPb3./C>[W/VkXmkq6|AYGk%z)cq!6R;b,llUNe7faaɽrJ{{t<7<=k9W.'B@! B 	=GGl1ڍϺ"pҴnvyy6`9мU4K';BйĶ,Jm^p
    a.Æ
    _h4oXw~6D,/ 5*
    ͚[BvlߑDtp"<(|lX9%!{hX8SRn6m(Z$I{J
    ndf#6)۷CʽF5^wعƜ5s{<{TGZ ʰJtX:g\zճxQ<0^8Ms)X$! B@" 1.fbJX_'$D;v~7A,ݘڸO4)V|ևgedWA{wo߈Y?Vc/=$43>#/ƺU?P^x]Itڍ+
    ?Nz;uNE){מĭ?g;Bj@Q<pŸ·]^LSϻ|6ثP_iۍ&^*9lxc+5>ڇ`GD	sS^]\>B@! @ z VS߉[rn;0p5`$f1a܌{OcƢ{(%/M;psڑi).~|2
    {vӂoRQOwOi2WGF(DG9(]w+coSjg	l΂pc֢ح5-	_4o@A"!܏N禱/q;qL5�]ÏG0lnZ47\{[h
    `[z:6QH}<@?0ҳ淿~-if*Njd-#I`.B@! 6F%
    FNA<M+/(F-X2&LSKe7ĘC'^a4ͪ:u*hE{E	d)ً@Sۛ5kXχw	.o"?ZyZyJb,4-~m^
    A-0fPS:7ڊݙ?c\4
    8nej*+оe-CYQk(=hڋ/DN)~
    Fֱؕg>譫pHQF\n+i׽>2.-+"xKυB@$ >K@d`qpc0Yˏ݄'FU9	rBi{D$[_|IoO\|r*ӵEӶ#yQ>pɻr3yGyߋx1#)
    Ztc56sзs[z޲3ZPg!
    hC:fMLb/+m<ذO<Sฮi*P! B@@&`@Pl5L 2{PTDq
    Ixx0ѳ'R#86VGڄ
    5[}O
    
    nyd+]Eu:3|G6
    'M%?"UbӺi^b1?[}%{j-V:v́03nF~=5_+pDžB$FSޕmu$U'�ضovրf̙q{V8fJZ! B@(YGUoe5Nqa9Տ䤳1.m}%-$n*.yڼw}Ag͞w6M7%ׯgӴ4̛|)Z1#1qW>v
    <LzFSco_4	FHd*{]?Tl\|%۸!''pչcwJ|9c1z4
    _|9n~hj=Zg؀KKpYRŎ4Xy5.r{K/#>9kDNYS\
    ! B@% =`FI,ŵCSߓnn|8Ƿ/B߾##UGMx4<k5A||J,^?ms1rp:3k+Zoӭ?=f.V:;[[Q8	gͻbXh	I78=6eO:[@6ih%tLвޛ
    /vڭ.FhX1mhBxg9jtOyiateM"8uf{Y:xt>@1g�V̄XB@! GO@3�5kЁ],z;v[?mWY%$Ǟ|Q	;BZmr.kWa	cܰQ>?ڕdض[?(ƚu[фv⇏>3#Қ'["}}A͘~˿U6iN_NӱppGSrJSUZ)3.9`-h&>UZ]){OAA'&},)Q/D9:G.
    ! AN@+ /GTdx[hZy.V{nBE/s+ܜSlHY;!g?}>ښ0i1lvmی>	8hHln~voLM6v7sbDDFF,˚|}w,K׊OO;m! B@2Rbg0!̕4|,u7DU8
    s#
    $E̪La(9BLrsݛ7O[OJB8Vrԯ D9iS:xWv՛6Z'k|ѱqj{lUV'A[XXH{O61}&q4Ad*B@Z" JK@,ifq4~_aiJ'VC-Teet[Z:#B/8
    Z^[aU.:auu텇;^kGbs6g`i||ǭrmN)cc>P;ɣVy)-! B@4v"7@̂\Hdi8<,^|3Ej6Ul.Kyй@XX!Wm|AQoAa)B@& Ju&`+|MBYV.JP5Uϡ9XZ&..`E%qҬ	B@! hD7Q>z+W"Q"q0ij7oV^s<<S �oTTL:
    Yx@uIv! B@%=;)(B@!P*1Ϣvn! B@ڈ4p{+ڥKĨWt(	TgsЏ:)ڵkMdD(B@5R*./^]j'dE-**RSYǜEGGq]BB@!@@o Lݐ4Zkyboogp}Ңfuivk^:y*{]N<	! 2O!$pcsكΞsTExDD"#+΃. c[RRr\,B@O@zca-[^9[N4WٕGVUXkf:8},=(#D
    	! BހSR?~[!Y+(xm%=}][fZQ|<=!!6kZ^B@! @# 
    tn	ᢵѴBD>o)K
    f-w1s(ene!FnVtoi=s(˃ؘxnqPkOgj
    Aj8CҤB@! 61	trXnL]d.T9;'+G(klUt{hs&ӶXFiZ-g;M<`
    nL8ZT}]
    .B@! �+	B@.c:`/6Wle'wypgFn՚Щ@d<^|\x
    ~ٞʱV5n}^,$?$(Zɕ]
    7pwqB@! BI!P>gTpxTRpwGؤ6$.V&tNq"&>t3"յn}LVJl\7f/؊gH's2ԯu8m
    
    Vﲢy?7N;,ćyU`^bC{n>GOR! B@!pLK	!	:<2S}o}Sv[[Qs>ZKĹ)'!!lr~׎xoP6<奅yWcSVBe0h֪"~,k:ޛ'm
    `
    ڃnZ/	B@! B1zceciR6O^ijw"kRj3ևgyﱵCLluX[Ni8vw7)jGhvoJ;=a㟬54g~:G9([ɱejuWsZ]ҒB@! "뇻P.؛zs%BFjs7G֌GQ5	qcgrKwX	R&k/8}
    N]RiyY[7|$! B@@@7Q><|A8
    V]yyy9C_M;jS;׼�$ܕN4uFi'1;Rw	X7lwwnB@! BZDWdpW�r	.+n>/<'ظe;2wbYh.r'C\l2~e̜�;hmgx9JsziIJ<j
    =s(-u!ݠ<t|QQAyB@! 
    Lqo,ݫ%M^h'm	vg=m}NŜ?O?߾ðzj9bJWFcnA✑1	<cΜpaZdl34V7"2%m)K]uex1U! B@!GN5n<NxV17&5!Pu&>p"vΆ֦G!9)6#YNsk{D<.^9BahLBmFM'Q
    jǟrB,ܢwS%M(((PkbmkjBH! L)L1M"NH'ccz:81D:`u\9+	x RlGXDnN*#22rf?+bA1σjIB@! @P&Fc6- :/=ݨb1&u]\r	֠9@{!|~'<:;%B@! Q~{<8z/^s)n$JRцP'H	PJ@RH	4R)"!DPU"!PE)A@{]yw23g>9{#ϼ̙wg" Eֲpy8&L;ɴzŭe}+Wi~^Ncu6277O}%}9c@�@`#
    A߈{I�xFhm/uUUOpĿɓ'+X^>7:� �\�+Ztc--45Zb:>lwW0� �l`zHx
    H|ETWG.q-n޼8־w[׿Ԡrι[	
    &@�@JvÓ#ݚՌheD!o7zkf,rSjVT^OW.5^k^ONq裶踳F9%j/^ko_okkٚj6T
    mց� P.tY'ޙ*ʉaݻwǷ-N4(:bZ52k[$ԥ+\5ήja]4I[ˆe4]v:U2~Kڶ>k)Hurri"P\@mݑ}9c@�jM Ç'T[n5:
    4DJѠ)=WW>Gyu,,tʩn{ևԪ)CU0bx]H|E1/7�뻒YOmmU'/#/_'IˬW߷Ykn
    ڍ
    ۍ&y[S/KFq9VZoSWji&dP$iU	߷~2J߷V^WA㻻Cվj踣V˔q}n0~*o[W:,T?r_ѾJmZެ}JK}ik_%kqAy-vA?|ߺBZ|?7WڷU%k'?oJ߷Eg}'s_
    讌!۵k(@�iN2FGG;~8/-:qև>wv…xxy=I:Rl<dKy_ԉU^|V[1uΥD:UAƊ[UWYu6h[k[C2Qy)4nn̊mRiu""]Tϴj^9r<+*N*NzN01ڂ+b{p_y)׶R]_vڶB4xg8ۚlʟIKd|o	[v*n(~O-q'_-h݊+m߷EښiJ}[-im-U^[Hˉ_-1o^gB1\uҺUǢp#jý]1܏jW~Ja|?﫼sVsYi;ur-~< �Ԣ@Saw4\;vulJKN8a|ϟ48Liy<cdrmS^ZA4.ˊuMX=@�"~lJ;&-i<>Ǡ؞c%K-WzrߎaLV̬YˋԺ<F/\暬Or>Y>Lp}m}y>=pR ׬<y �Ԃ@tUPW14dYqƔ?aU?mYӓxiyXE=FZpY|i˦-KI{pyִi^h9ծ(ꪦjMuLWkuBP~qrK<i2+5ﱓ|eᴗI鴼ZǗ8/t'ˇ=-\N.1֏[mb@1Jv6X>$WY݆۫u[˃[MV_sjyoQ7*#tTfmDE�@<%;Յ.ꉂ� ﲪm۶J/R_:W*U\@`x. �J^O$l�1
    r̥'$_ʗe
    WMzs^^is1׃@�@�z�PWWϳ@)iPr~쌍厺;q]\o۩/<Dzz^^e:x럼tΜ\sYQi`@�@�@J^A@~e:\r<(/oӾoeZŇ7'zФJDWӣqiξ_ZC{o_yeޜ/<gG/u	zNk7NxuL#� � P/\A=E=5w>_}kmԞoؙ6=m>lo_jv"d[:yŽ{.ME:zNEq4\u{^ko>m}J_�q6 � � P\AF+޳3vutlΞc;{
    O{ux~ٿ}'~6zϠ}UOG/ء)ѿŚڷ;y-;9kO>)k^W[M?ƽ~xmj.Gm � �ԩ�WtQm-~;^w^|ؾGw{~iXkeю};ʭ8773in;}_^yN_'~Q{_g>ݸxt<J}jn~{OGwΗs8v`} � �
    zy=H:Zm<}ޏ[o
    Wtt}v_f7ngњ[lvk.r/6z;mCwluom=6۝?1ۺz-v@uwuZOm닽M7lc@�@�FQ4ۉ@îN+g5?>o<jotЎ=e'yً'oyzc8Sc695-'Ҧ<ojnw'flΝ@�@�[+=&>?Ž˾.;ewz=_w>e_rm_?o?[QG|?g7t/ڛ.gy?lKa?sodSs0?ckGc'?QlݴRua � �\@StΣ`~­;vخ]V-uR@͛uI3ϣ>v؞?4c׾fζ]}uob;oѦǎSvİ]\h^i+mͷUݛծ׆lm6ggm7/O={uAW/]zoo/ǰX?4@x|:pcDh �"@^D`AĵO|rUQ}tQ"<ؘXwww8?q@`c�@�A/D.R@'Z[[b{泳|Dp:N,+Ta0tՌ@�@�z;#,%5]ݑꊯJ{;>^R/߄+YVϭ,Μףi#arr'E
    ^ $ � � tyzjY;ĝ.CzvW3 � � P/kV/N=@_~w\/|iOq^繒qV|-g@�@�@^r;j淅^6z"@B8\s^Z2gZ~9ԯ�ǂwh4܇-.gmP@�@~~5G�I 
    ~V瞳ao$@�X@rBÑ#GlϞ=+[Ň
    &@�jL]O!|ܹ*iaܴdCy5<qZ0OZzڲO;8-vڲL8d.K.u%в|8eYy=//2+4
    yazdx^fQz/4V$Ӕ߇:|^^&Ji˒aO2
    iu)ezqNJN{\-ukg-3kǪOe|Y둬&\#964N:ۡ+<H˗kܞ05΋I˚X4'3\+xӦM#+<4 �"AVv@�@�rpnSEb �TR ws%WNl@�@Zkb_z@�\ |9SyƍF>Z?F[sZZܴe^mk-),C�@�w2oq'S � � � PiܟYʉ� � � �ti	 � � �Ԁ�	T@�@�@�:@�@�@�j@ )z, � � �G r;yS5 � � � ŝv� � � @
    
    nk+2k`oQ@�@�@�Pzqq1gٳn馸pcAggg:::laa!Lb@�@�@�J#Sǹ:Jh2f>	nnnn_b$#� � � @ښD=	 � � � PV[s.C�@�@�@no׶v
    6ۈ� � � @jI@�@�@�r� � � @WK � � � #@=$@�@�@�%@ZҬ@�@�@�:98$!� � � P-:Ւf= � � �A!	@�@�@�j	A4A�@�@�@ GzI � � �TKzY � � �9tspHB�@�@�@ZtЫ%z@�@�@�C � � �^-iփ� � � @�@�@�@��jI@�@�@�r� � � @WK � � � #@=$@�@�@�%@ZҬ@�@�@�:98$!� � � P-:Ւf= � � �A!	@�@�@�j	A4A�@�@�@ GzI � � �TKzY � � �9/夓� � � �XRa
     � � � #%G/Y"	@�@�@�2v1!zi=B`@�@�@�@
    q<ZO7oZZZhIW � � �TVjlnjjWMD磗5p%}ف � � �[ꃫ/Їu����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/feather.gif���������������������������������������������������������0000664�0001751�0001751�00000007110�12657415644�020416� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�F��!6q$ﬓl-d*Ij( @Yo UR-䏙XR#K.y QYġ{)~:1%sۮ.c"6Դ[Zx&j$wf諷ť ]̕^+ :u' >&vgx+(d'xF/ Br'ڏ?0X,42ռ׻ FӭN\ڂ Y2ܝ J Mo񻷹 H7 O D%5q坧-3?@ <#jMv„ 7<[(4C좘%({K+zonlGhB03{̯ϛ_/D񒒕$pn(8|=P5ˠyw<k.S!���,�����F��qttqqf((fq͵((א__i$C[ 47nB/iCBB hC
    .ǰ'=HE1p <B:CbJ@"h"
    z2#QPi9-]!̚7oZ0ϫ{JuΎFK6Wvq0tҥ̪^Je2)v$pN(YxcPLH
    iv
    |"O޽6Lb瘝 +yY
    qh#5m@:NU|>#م͘ȿ+X%	fBϕM.
    $EĀŁum፧nz@ZDPQg%'gOp`)1x 	z�`y7Aq
    !}"wrSae")Řch#ȣxXFF hp!]=i D<~\i�Py%'P4`xnsYg�$T}>YeQ&~Box�[D
    
     Hdi
    vZ[rj
    $jߓn@BDZk(k*0cˢA릨jm+$B a!>ADB4r""j@nƒ)4 [od2cũ
    }5߂+('flvL
    PTW|\')3k:H3AK!@`15t$Pa^H!ՄS/]]f9:lj_
    Y̵L]x7%Mq
    @7rl39sirxtTPZ!/\`1ц??dߺ]82G+y	'dn )=/VoI�׽/|�
    B3X>sŠo8�[G@jT0lW
    t$on=|l@>0"q�apqфՑ'Z
    o8m<0,X*#Tpgy4&ԇr!a�!A:>X`�X:EWS
    }$,X7bpRu8(AYC"2_ÝZؠBP2$y�G/Ѓ(JNsc @$)OYT|%p@<!H~1| EahH!D-$"rEh5RL*JrS
    p	NE_Xy3.
    'I0[{%DCBw:bs}(*%
    =sh-m9\V
    ̛$e̬~h&~&BӶ?
    *79Q2=�TL_-|#J	!�)ا $�t;攳?ah:<A:uk[}mwl++`Hʓ@�,IkdבB!2 ڠ-@DVմtc]`ťSY[Fn	~o-lKJʹ�Y݀r|�	&tSjSE-+{f4h;?J92Ksm	ge\P.6@�X�0{j͟nj*NA
    =rFmy˓)rY"n0|?lZh{?hHM]�06ibEqS+. Vb"
    /HhS1[WsTY+NBuGE*.<Z%0%by._z^4�1(QӼ[͙k9*RfAR?Lm}^Op�@>׊f4y_׸8αZiK͙nx9=!kMvMXDKDRcIE?4Zq\[�浌Gn3;E|;qNecN
    5肒TTvSj:O37U[']_�:`3RTw^D@дWG::q'VvEdC
    (?Y,p4 <ev[\u9b5ȵWq?܋]K?=x:�@|".CV^�V+3dpUV}t6o,D`GD䘆zPClG,,fb~SyyyP'�Ir |EFχduRpG$}.L ehl'�qyyu'M~awx ;)7[&xK&eZ@w{ǂoyؕcs'P6.ap5p|^=V,zEU^Fgpv1GyPvFf69v%G D Da'Pr&=BͦzixERL/w7`G!PDb DpaBF]h|Sygdf1ktl@{`@x- BAtoTDXfviv@oJցt /n�cg&|6ru؊,i#M捌�u8Ȃq긎ug|f@Ha$R
    |8ctlhaA`gY ItR|ϘlLՈH^U&)	`v)I9~2z*ytBY 7|݅~yuiO	ГT	A
    L`(zxrf9
    "ivWmIEɕ^I/C;Ury	p@}Ytْr
    cf>ט w�}{lon	xWNG,g9"w�v,	|JIr5#"-0	~i~QSba
    P$s"P-`G	tp4HZX7FXYC��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/sub.gif�������������������������������������������������������������0000664�0001751�0001751�00000013703�10147723030�017555� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a>��RRRccc{{{����!��1��9��J��Z��c��s��{���������!�1�k�)�)�R�{�)�1�1�J�9�c�9�)�9�J�J�B��1�s)�Z�c�c)�1�B�{�9!J��R1J)�Z1�c��cB{�R9kJ�c�c�skRkR�RJ)cZ1911)�{JJBsc��kc))!BB1!!99)��������)��R���)��R1�!��!B�B�J��R�B��)!�Rc�c�!�Js�)�Rs�{��1�ZZ�)�JR��)9�c�B�k��Υ���J�ks�)�9���9�J{��!�)��1�99�B�R�ZZ�c�������B�BJ�Jk�k���������s�9�1�1�)�)�!����J�9!���R�9�k�J�1�{Z�9�B�)k�B�{�J)��s�����R�)�k!�s�{J�!�s�B{�1�k�c�Z��R1��B�R�J9�{�!�1�B!�B��)J�k��!�!�)�9R�Z���!�)B��!�!J������������������������������������!���,����>�@�	H*\ȰÇ#JHŋ3jȱCCIɓ(S\9Ҁ�'NƋ-4pas4gv]KMڲ `@$pWVYKٳhRj
    #?p@Q嬩Æјƫ-\PJ*S5]RhP>ty1d|^-5װcˎm�(>8C.Hn]7pEsv6n؎&IqT~UN.IrD)#Ic;uް)#&0p)}M~rw'\%-s0ܬ@hOj߈$h(,0(/"0EQLPH!ENLEJxR(Lj"W#AY"We|V`jƘ\*l)PH%(rdB+o>&",."0X3L8`Ӎ9T
    sy*ꨤjꩨ:?QD#;JQQ@h-R1@M2`cN:K11$Ì4d#34M.L.LcN9c2\3;<@<L@pD@X�v`A	`@	^G,Wl&e|u#,b,˝X"%7K)R-_CaƬBrm" LPH !Tm)	<chlۢ&tm`m9DT4@XU 	p
    PW!-WnyF`	$X]Cc7CE1cL1Jwb
    )6r# z?ԓX0~7GWuD2|�BOK4ȕ|@APM0NK0h'}I%1	AGuC43AcNԆ6acw �A	IxB S
    @*�hFH*ʐAV@82QZ,^Nܢ݁"F!$B0Y0Ba=W86dh2hL0D<(H!!UOB/h<:
    G;1p%P^ZF:^`'	v%#8aXډ�Sxn&F	D D"KD%.aR("t)rFYIE,
    a؂BkIH7qEe9X9" zHZ2  $�l`Ḩ>OCš@6tBC<`7aP`ߠ7ڡt4"�E[xJAԥp(O�
    ؔ8QZ0̀aP}82>Ԧsb8`ZXj@V>�4V#&ѢaZ@S+ҺV4x]1LjmЀF:׾nJ<�]�'@^}
    3&;'TNͬf7zD&hGK@ Sj*ҚҺmD
    `@.8i�*0zO{�2 
    8!�]JdKZy�
    V�4 5IA
    @Ёɣ8Kt
    I<+HщW
    QT08?8uL�.pF�@Oι
    d:1~AI$
    `PHt8ClC�
    *a7AG�܀.A	,y
    8bPHE*T."Ir!A?E1pI&j *ع
    �
    π.4h{^G5]8 5G7]C;82S`xwxD'dE`=2&Ƥ;
    rC
    A6.Ev!>
    Jm@[h;ndc0G61t@Ƨ
    <12dD=9x'$2ou3lPZ~a]0;
    (S PJM78-x
    ; DN9Rz`	;x�<eBhG6dX8-XN0t".I>wf֐0zdȏ01EjX'A*AD,AKB0ŋD5X:&u^h�H
    �	*gxGިGRxy'	(<alXȠ@.ar6�	EtX#<FTw؝2!
    <~+b`>lneTlt!AK0,tzV-h!p	R8B
    LQL0|
    G
    A
    
    3uL^Xjw6
    ؒ^ )DN ��/0=/:$-S(0, wH"$9I?S 9 -0p%E p/-p
    ) H!�`p
    0( >i�+	~J؈Ul2&&22؉Daq$=
    ?sT"vU,x
    X5X&XZ55>pG@TOIf@@҈pP\2l	0_	]wh"P�
    PPC
    P9Z5,
    3Ռmu]*yps_!	 +B
    	$R0�(Ւ02P#�6�h"& &p<a:0DYF@LٔN#+R9a�W@XZy\AUP8B�.QhBA�*"*@bb�~_^1jY<7;`d/p-0+`:
    \x
    00AmQ'G.)%`ٚY7^)=0=; [w7
    Ѡ
    z;;`cX!Q�Peyayh.`h0\6h# 6
    ِ
    p|>ְ
    t	`	`A 	E�2_�Ն:$a�F J�^R^P|!
    �pnӠ0`	$	~{Q"�J.AS+2:iya8tPo~<tbm�Fb_Z	=<`)(@` 0
    GF;jp
    DmD~k@bP\BU,J�gɥ]-�	pu;9<h*p ކnp
    �(�
    }b	1s	o@l!l-_
    p$&n�v� !4�Xg4Xh.Q3?@Qv:
    p6[&pYD
    0D pgb}@&p0F%&mzohwP	pՆBdך"ZIF2 xh:p
    P&`
    q`
    %Ơ
    q
    
     
    F;`oef-EDk_PpVjzh00mK3}!aTP�9r<V��_hLv/-h@6�
    q0@[jQ{)F%fx pk0TŪp'bz�	u
     
    
    r0
    0�Qs3h@=ip
    zs|dÀ&;a		O` �KRsSh0ZU^[�&2zP~е`v 0
    
    w�G'R*<  5  ( d/
    sP
    @Q; Jfs�-`w` j],\x?!'vs$Lp|=
    }`@�-�-0hnQ�Cq,*A
     5A	
    #p
    ~@U-]]u+#fjzPl@!	`V`;� `qD0
    /%�:-5A~o0K7+yE$FgSȋlx h0#2	'V&3�	p{	P
    0G߁
    )'
    u'
    ˰0H&1Ф+QIBP>#2PKPPE9ZP"fp
    	�p
    	' `(D-GƐ
    qus`̐ڐ,7)4]X4j/!=0]f
    *KuZN~zJ`y	
    
    
    zMG�9f|]q
    (!p:$!J-ӱׂM
    }�%N �N*0x(X)g۾"Y�JE &PQ$B#P8"اLu'GG0
    ˔
    (
    
    TxӁr
    qb4:f/>/f�pO �+�-=*YY�q;"Sp>x"
    pN
    P"-n
    |T
    ``pP :G+Ѓ�	](0^>1505S�<Pް
    ᐓް\ 0
    2p
     @/@
    
    
    =P
    ِ А_~阞Y1tx``Jd0`"@$b
    P4
    _|}B�4X"55aX1CG^zS2r0%VP\3%IV6
    CP0&
     `5N"Xx>L1a#(/	83	eh0"#nOs$ )썵Р._GȾC<2p_Q28V.r
    0W1$BB!9%no^UEh'pUj^q(#*
    
    `$
    0S0i
    ^j8XZ%.?_1�;�������������������������������������������������������������httpd-2.4.64/docs/manual/images/index.gif�����������������������������������������������������������0000664�0001751�0001751�00000003004�10147723030�020064� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ad� ���������.�	��	
    +���""�����"�a�.�\���__��谰�.�#����������77�%�mm�#�F�&�����.�)�,�'Q��i�z�**�``������AN��l� �.�LL�*����k�-���ZZ���	�.�@�m���޲��.�!���22�hh��"�Lt��2������
    
    �%%�vv�S����
    �O�b��`��������
    ��ty�33����������0���pp���)�M�������.��i��n-�F����_��cc�~~����	��44����S�&�..�"��	�  �;;�VV�qq���.� �=�_���''�BB��d��&��`��II���c���9�. �R�f.�
    ��{�PP�.
    �kk�!�F�.���rr��@���!�a�`��
    
    �*�*{�^^��X�3�i���*�^.���.��+�����������������������������������������������,����d� �@�H*\ȰÃfఉ<ȱW`d30��Wcʜ9ն``Ͼࡲ7XjA=,%1G`lh
    AQQS&f2Kͷp7˜"�"0bFZܿbH/Pl`mY!KGǐvRg`(v*/^Ҡʤw	E@Ɏ ]4(BP[k"N
    cc"�L5e8%nr8�@
    ?XD�kX/(8B@A	A, WdI!lP6�`5C X'N=	ϰ;*5SNdJ1I`U<@C3L6AE:j\wHhł٥ Lpᢚ1	!q,_ED%D^c
    Xe@7e�"`sA)"�@}*p]s
    #.AY
    mAhFbpQF}e0*qI} Q@Ĉ�c`$t0>=GBR>
    d"o&ctU6ds\
    �-$Q�&	$813!x<r2XTSSd9H:0;Bx#�
    435tJ/$
    t+�&NT;<	A2nL7`<h
    X@�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/rewrite_rule_flow.png�����������������������������������������������0000664�0001751�0001751�00000116605�11577356155�022571� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�������rK/y��"iCCPICC Profile��xXy8U_!1DDI1Hc;ǜ)JHɐ")
    IR4HTh "]{~gֻaYk=�9��~A}ZvDVvIg25P6 'R4_)v]SNt=S
    19ص`GL@$`K.ؒC'
    =]!Xbi
    q&
    lN!{l_��~
    buW7*⺺R~g�B@PHОc+1mG@�d�j|٬BT=2&-ڬ([�+kkJVJ@ŗL	YׅAo5@Crh/qDQ}a,	*3]ßxkO*&)K4XlBJMR\*c碴'{d[
    WU.~U۠Oj'oaQqɐWsFqKsHja[;CcY.n|'=ۼ|vW
    8CAbf+BjvԾhXţq<LfMxvI)Ωi3x2YYsF;sO18#)w
    
    C)n*I(5/()ou1`%j%j|+j"kIWٯ~{u5
    7oirmָxzWrˣҶ{N:tt>2{$^B~OJr?},#C/Âï_Ƽn
    -̻/M0M9IlI)it̶/\_,~44>6GμʟWWhV其DcQ7yXy88hd	
    YkH1+eUzc2cre”T$j$]ZC$յ?aQqI%:#߭q6\S?䐵#9(9õȭGz"D ?�@V*4<22E#ݑMQ1vjGG=>ޘP~"dDGIB
    oZXZKzaFR)l3zv3͞S^(W*=_T|ĪTl[9s***S/YV+^湼|uڒquHK8{S֦۶w[>vݼW~>R'K织
    ]<63Wӟ:D}pӚgU/h2oī#6UFGzߔ1N?>#?	~p*kf{&ڿ՜
    O_H:@EWhLJ˨4Üĺws
    8Ӈ8T|%	
    tmk),A!!&K]wv˘3# #0XLRTEWT8ISZsAs.>}z48o`ac$t[,-ˬlyvvo9vhա񸓡3KufA\CDQ|_?�S)?7E$ʄ
    u:;t4=^0	'6:ٓx5);9,&U.%EzjHL,|V)l79O;
    䎟>KS[<טZ W0WX_|^jR2BpyuUiu._^򤦶6j_6&n7IldhzkFs;w[4[dɶWP~)PkKңn>MCWc'wL}Xh9'@G�`y4k��pt)v??"09$dRP|ƒH"1!'ByLP(:@~&H%0fFƌcll?gKu)~tdUzRE3KXFg;L<LL#t71OгıFEoُnAr�8YɥvkS/e4>AkzD<XPMpD(VXDq9pg;H48.i%%"5{Wt =r*;DyUTT5,:hzhkG䐮>_ђYj=atɾÁy,zmgOӾüjK0!$(Y8)b81:9tt&>8!tbKer|sr}-l=PTvBo@Փ+u9Cn;]ópwJҀgCG[ݘ42e"۲դ5ZChC B@3@!D!!6#eH#҇|D!j(}%9VD<F+Rg:yx~zA`.!haFUB&7ঽwa<vVVl6n;[ˈ}lK0# @I
    ʾۊ{W_E VYXHHǶBP18w-;$vߵ&=Lɞr)
    %JTUuwEY[BD׬e?nS3}L+iq[=+܇RVnݗ=}8|CFtR萈Я>21=G}鏕&(x4O?)Uӓy/o$<ԻBwEBxMպkmh46)h!)o`c>#Ϧ$GH!oƱ?LGgX_X]&VFV֌W~ >	N'^GBSUd�E風R4+z?:ݍ8`*1?S8e\nog"}�G7NLNL6133W^fs̱=|~h-g!V%n^<y=&/	񂯄n
    !*+Lo0.Jw%K*t+euxu>
    ϽuUO.þPvM8*k(ۺqK.o\z	x0C3ć!)GܣcZމ/;u,Q,i)nZrsfipӹނڢRrۋZĪ+)u"w66:75	ommx_c+krߖOn<
    W*#G|'28vrȩƙ/wV|Kn553CGͼ|ޅ?~._,Y\\2]*[%Wee˓++++9++S\z17Vք2:ioK|(DCm7d2fxQC,HNu:@K#T1İ6C) vs`x'bEɍJ#D	6X	07klX/-!΀<@@Ozw|CK
    [@K*+l]�P/P/I^
    |VxW[bչ	WĈbd0r-FHad10k`TFXU!_E_`O A_r9�/ &MO)IVE#k���	pHYs������� �IDATxMo(Y=$(KBnZ5$jtF"!YDO-ʟew}yvmy|;oܙs3gi*(	(	(	8^tJ!JJJ	(TR@I@I$PɹCQ$$PI%%璀B%jEB%K
    =5JJ
    TPPp.	(TrP(	(	(TR}@I@I$PɹCQ$$PI%%璀B%jEB%K
    =5JJ
    TPPp.	(TrP(	(	(TR}@I@I$PɹCQ$$PI%%璀B%jEB%K
    =5JJ
    TPPp.	(TrP(	(	(TR}@I@I$PɹCQ$$PI%%璀B%jEB%K
    =5JJ
    TPPp.	(TrP(	(	(TR}U&|ZGz/0]-pτwNÆgf}y{[K*IxiNMi/.
    ~bw~
    oϑB%ikx;ީ5ȚG/%<ZjXiD%ܺv529KݡPC�DJi+l"IT%t%�6g?Y
    w|H2vaݼyp>ZL`S6=YNSw?Ѵ/utJȘ1!wf}PID4	ֱ͜ςG5-yޥk>s2OVX4tZE0NDPnW78+He7D
    &M{_+qǹVyRZ/>p&^DY;?K +JJj.89JN@<%v{\+\
    yJ'Ja%'B%'o 7'oժUǎss&{	u>+	XA֭,XRE.-|K=rMնB%[IV	LCO
    J*PH@JWPȭ	T[7o"SHǬ"+YEnVB%7kPcGJ.`v!W]Ĭ*E
    bG'+Tw8j&pB*9axIJWƎ7
    -*P
    E*Tr&tig#*HxI@JeRa
    d*])QD(]c>*!uPE(TrFs#*QcZJV*(P3DQgQ};)?sӧ/^8eNY[[o*(=8;
    [UDׯ_ϒ%/LBTTJoSO+5ܶw 篼Jjg(JSHy$t%iϢd۶m
    4w͛iҤ,)(n-I@Jl/Ub|`W
    mܛ^xgϞL`3mڴڵso~w񗀚_V*%pڵ9sQK\S35-Tڥ?jɜ93M6'O=f]of1S2ҕl!U+S�8ӫ޵kq_5f&׮OMD\c&UĦPdS:ED'_uHMɓK"kF]"B$JtUB%4Óӵ=mtywTIIu(8+i5>Fѽ~J>#l/䙧yn:~)DMYZ)zdɒq):ͩJ	P3#=3pʐZ?#lӨfg#^^ձCQdddbϮDK�;$?@("`}$๨~fM1,o`Ǒ2jZe#i>=gL֡J3k;8|E҆o^O(?5'ko-P%/ߵ*H"2}=�й(;.GS#ˑD#X25}&jڙ5]Y;O~ér佳cSwSG_ԟ?ClpWpmy5yA@A%]KboZݢ2as΄JƖIZ3<A?;~4ԯ36Vm9.|xǮEasB.3Xn鴰7~},nb$(J6U[Lٸ2*8w)\]h	yר?-aڎ還kSjZR-Zؼ=?[=Eخ_ݱ%lX"
    vB4aĝw4a޼jg7fM܏bf ]QH#ظZ7)N@,&97f{&%7
    mشzDjgZzGik5o^7w5cڷm$mߵZ4E^ػCk84Ȝ>k4ї pdt%6++%qkA >=Iu%s)F$U6ksR8;`KsiؿK1WJsS_4[m2K
    f69
    j;+jՎ第A^fp�Klߖ$R)`:WLd4֕K"߸}gرI5R^yF{)o\o2Z|z>zHCww*\Ҧ3o9V<@ˡioc JƘSU@s&Sx%Zʋ2"o]<mƌiّ]Ci2b[1+m
    CE`2r}ܹs֭ڵk+πEg7|8π33':e[tVqgZdO$3e%{^^\g=9'n]n=Y ]ٕ)mŸ`s.U 8Bٹ键dgۣ:ᐐ%KJe2
    0%aT}+e1&w;3rfe!-ui>%G._㵧)&K/غw&i
    %NbU=iB%wO:u`	lED$q77%oz-
    ϓM{7r%(J׮s�N=nl,PԹlɣEPs
    sEP3%3D͔<.r,aŶ}7k,E{nCɑ@rWv!0D];kL:4D[ͨF}5KCl`?<qĽ˖rkua٪B
    3뾞i^˞5Z Oz4w/[)̩Ԅ]MVʝ(	(])b\Wʕm۶R߭[7PZfϞ-_}U`` qaÆ-7vI8qܸqAh|=NX""aaa,"E4o\O8f9|qƩR�'q֭[AիWS	^ߕZSߡj}:ި!l£n4ϋ]BK١yQւ~s6=~:֢ipw}PŴ[tc쉁[׏uvCnjbY!~+
    3
    L<4nd*&U},VPk0wyȑGf̘QG
    > #|Tҟ/^8耞(KI^z|Sl`}a~fݻ7kOm(OXayĴ~!�EIHmҤȹ
    $8G;Ӂ_ҊU-Wjy0!ʼnY2݉ZZSGt_8bq5ٴ)sn,#{ԏ÷zOWЛ=g8ȃU.x3[ˢ=l(<Z7:cPO&T뤵]p!G|
    dх.UT
    $kc-xtS"(cOz1ӽA
    2|^^^W5jcB+اy2J[qѽ+iZlQ銗E?UN;(JrC-[|@I28ѧoIhن}Ҿk^Ͱrso{{XQtJUzfq		(T24W\_+Q2hE3"ѧ�(P5kDcPeKϴsO:HόݨPpat޴ԧ]?pٴ,j|DIH%-[khU6cYSyҫԯ%"R8{µҤO1dPN퉡;B<=q%̪S?[-Mըc:u
    V+qabnoa2%(b,!YZR/XH;3QiS?cO]FI?$;K{=E\5V8LT߾0y}zRʈkj̮bڑw41ɍjZ,TRJvJ	x4
    5wI|kc.&Ӂ̡YyNz
    uZ㏌ӮBV,eaz09Q̵}_LQI+gJ:r\q5*">MN*i8,x*M]fڼ2+Gtf	x>8Ԣ.]4mڴM66I
    Tbbd'v%lLG)zNdj@#%KS\<u!&|OKKI
    _xb(d;+.:^<ZߡY-[-[#[pO,0Ut'XhH",uL^${Iixܗ_~O?iZA$$TJ˖-ΟAŔF7S4}O$`YJǏ۷/A,@*	(	8؍*UÙ$hQP,G?|IZJUPp2	˗g#ظrhA$y%
    :|rJaDI%�ٌ袅hgU$JgpI<+ IR<#GT6kI@$ABxPS<Eln;㜳]~|+brd\'^فxElCu
    S	-*qL5yx8$	18D4rR%'eq _0vspvV^f-pe;.AqKFD%ꏫ$ඨĩuֵ\XF>
    EI~o:)@?zI%֜._L�$%Q;ҥK+zq0̀P I8"8sہ�5LH	<RdЫpOTP!N}wt>=3XQbhI(I:9PJfڑA#*JK CJR
    CAWHBKDuH)%H1"G#-U*t%zȊeIث%=QpkW0̠X~2{@Ad 8Lb;ۆpA&"&qӑ6FD
    HM2T-AOF H IG%ʀ/9vd"BV!Uٳu|ŋsmOQ:g]J&z?E)�@%HE	LigI
    *H+)\*ٳQk3&8𢳧(.qtH+f9>&jGN@\LH 	TRdrC]ɚ5$CXI@n=Ϭ"f)vH!ׯ*DnJgϞUs7-
    EzD2K%ޞ5u#
    NMOQJ
    gpl3Ёv
    6X>1S^KJ@cvG96Љ-݊U,J
    Q"*љ%w82:|<6i-Upv	(TrR)	xt&8OkHůH
    Qʕ+XOݦ#J&7D֏$7D%>KIH%r+Gt]fg붝-(wCnGjq29[v̙3vYVGn+Ňm7L9?dڴiMX	(Tr=v%8A
    wUUHF]L3gxl
    fDjԨ UϦt!*]~]VTv$JsκI,P=pCTbvFrW.*VĚﮜ*$J	lM	`эm۶3f,ZoܸDo䈾
    �OΗ/KЬl-2UU$?~*Ū	.
    ό(Tvw$ׂGre]ҥKsM&G6CVP{X堏`]JI1$F{ZK,yEն&#)ݜ/eF7ƽ[RC	Zl(zl'7D% ~o;!E<f_f=ؤq;wpTJQDܥqCT7SߜS
    $	*:@Zh2Ջ[/ӿ+!HHRT
    jkbUS?W!	iղywV,h<9/k9CxPnbINW0=W
    ׮]cۧ:Cg5$ђچz-KԒ9AN'V}A3wgVr�>pKT5..7!*qkkJ(AhImCZ̮-5M>;w!*U*Ik{ҩ}JzY%]!	6-llijLh^0 26&13Q&yW"'Jצ"$q?oy_6mE
    0&7)p7TbT>EH.fq@0͜ԤO֭[fxF9#!&[jnt&7l'4.]<s
    mI^0k0qmhhV%gB'$uLװB5]|YiLX>n:e!"$&-[6/W2˴/%ޯB0['LWy<X~ƴ%;#hIW|}Ig
    hٳrHHqwC%gf.\IF\cGԳ
    ݸS,0YEYSnL$-?0[# 	~6nz7oTXr^JXŚB%jn+3H`xч�$lRV?k~\+OӦ
    9`qIh.LJc)ϱT^U.!mQ	в\M!M2-Xԯz_@cZte\*< I5.Xͮd
    =_Yd[omڴɊK7?%H|9[:$7$T uw>[æ݌y,Y'O+>^ .M	PTѕ}^Kt(l?O5bZLч8^RgiSJp,jתx^XKӷGU`2X	0͝;U"VpajyKJ
    $@#COEj[մzƏ9!N<"aT-kU2MO sH>=]$Ly5iFnFdth*+	Y2Vcxll]}2�lf-Bҙ3gۥtT3vqMfYkZlYfM6Η~gϞpڴi|>0O?1䯿:?7olٲ_~g:u֮]K0v~a#N,Yi`Wb|Y	,LYfͱ�� �IDATfWT.?Ѐ!H� =0֦ZҩSZ6ӽb3�ӛo8]s.PYx͟??s~~~`
    )S+WLc@ĉ/2ς_jB{{%[UVaaaj6g$3@$
    0XV,KV"uDlޤʎ$1Ǐ4iL$"E3xjݺuݺԢin۶e_fΝD(VXP@:
    Fʚ5kиPOW]IE%)ӊ^[F2΃JPhaYL:0]M'i_Z(Ԣ٠~U:`]~ڿV[yXm[q-0L`THD/y桋:tX-y…}86n8Kiz6ITWS	X謴U,]Iɰ,Tv&l޼iӦ륥eXG@480@ҐUlͅMNg`"##3'|B%cg;ŞMPlԜ[�⛒hѢ˗!޽̒r.1EM>YCV@%JUJWG%)@6M44iR4ixb!gΜm>'r]^#F`:bO8ͺvh=dغu+�ij9s/5jtرݻCƍKx:<B>D60sңiu!ѣa*k{Sie;޺4ϭ/Zg5M wdGi٬Ԙ[<|ɔy
    *D+?k,"]IG(TܢJr&Q%X_}w˖-Ǐ߳gOٲeY
    $
    8044?j(S`bht	z>}Pf̘^^¬ʏ9rΜ9D�;b֭ۡCq0 'VѣGC!P
    ŋMΚެAA?fp2/vk+N&T)ty+/>+lD)2v+ab5%Z{מH^;.Gޜkrc?8ʯU@�QfM"q$ƱܬY31loߞ`}MΫ^|yY!N!lVQJg43W&/^^n,SPd
    =~K'+8`Jy4a
    @t@={v|(޷XRoP0vS@^}Uy@޽{1|ԨQ]%g`*&Z;s
    Â@%Ս&f-|IҬrn
    <gm?!-ͦS~!C:ݺg^
    T+ڍ6Ñgɖ;
    H`ݾLlI@	k:h޼E5	:c2n$q3*DnRm*`jUF\/ĔHGIE%ȗpyaƅw>k靦B)S"C=E":j`1E1V§O<bE8G%K}H2d3$(#|ʉ-xIӎf£v0 ԘBj':yRhor`wݡU&ݏSЎqwW;|n0Xec=_TX1S2L[3AtLQϴ->cJ-x81r<ul2)q+'Dz3c3@3z?2i۷]F
    $–D
    qߍ;79$i5yL!Pr\7W܃,R ڽ6Eʗ
    me4G~bo�I,e*O'QU$/>+)۴i-*S9#9b	XLdڃvp5T�@az`!۶mLKcJqzA`FS03-Z,Y1CQzn!	%+8?zX,-_	Txp=AvO3v'P�Io=6qw/;MA^'zᅪ&`(=tj`wmOϏ=y4̝ڤ]6ׁ	9.=6GU%`5TC'e#/4!}_]0oOyn>y霕zs*XR	AMu{zX\Pmf0 66C%c0tE	casiذa[^)=$
    _\MmY5{W0H7Ou.7s/?<wO[u[ڃ]HwO*ZkW^,VW|Qy4ÌP|d,fڇ`qS\q9OؕG<2JΌsE􈨇7`	Ǎ7<7f9i~C8g@9b15I!I1uAO%Y#ؼI!劈ҥKY@TO[f5RW	N&>(ۇ̟ެvRi<^]
    p^	o`Ȍ~Ej)9c[LL;sh%$jOR
    I|GhrBER*U
    焚
    -آ]3fV`ۊ6&$vM|&J|"iZGOW;f:1^D#M_gր׌u u_;>Q$.<~zWKE]X2p%-Wmw(r˺c.-i/{-ZmRa'"}p,װ^:`tΝ|繋צЎ I4(:]43{NxTTid0#K%?oDj4aȒ!ݎ,:m#%{@j CPD܎8De"C?'Cej/ɫ�*UVA]+NZɺ]g2;<Uyn=1pQyN|MmBjvٿа,_iƸ<WLxпOL67$ 2<T\@y*թcs_0qo#Y_3G<<XU'OgbKv6c :$V
    \x+Gf
    6E} %<,No„	?@ڵ+nDײ歾9`h>'JJYwlVISoqp#:ԮuτK7(vf
    CVt8f7OA_'b].JA,JhI;_6%ֵۧ*Z(I.z}vKٴ K#胻|r|аA'׌-	w'?bqm-(q	TҢh^5Ccq>L;ӣOOװ<HO<0jqEaYʺ-<edG/w5AOqȊm	*?kruA-ip6mCɏ3lZdo꒓{YԒ[zDDjg^2}*@CXtq2ޥl@Wڹs'DH:Jy.'PPN=Oڝim:u4Xsi>\y%k5(ӷ'Obl"RD\֪yj\t~_^%L`{m2,v|c}?9W[25YcO+IW	)X{Fj_1ulԧCG4^wğ{1:C_nG1
    yg74K~=>.H1
    I@;7j9aȋMZPymڴM`"ݪWB%#uÉdoPE[4*]miwRѫB
    wQ&wnJk[^9;W4x1cVSV9o+�&}ا7o}nge:g۠nBԷ(Wͦm&߆5S<@-1md״-+qղ39zpvTi2_#%KRSɳc`MDL0<	*	8yfƌig\NЕ2Хveg-?i+Ưi8}q޽"vQݩi;Zy>3}nr	C*
    '͒ҽ}6p"VO-IٖmG,رbK9jtbQ@
    6)*"Pu<Β+NHփ$Gizvh޲epK7l
    
    ׯ׏QF#s|vB;i׋6Xzk7ZǨr^S]?~ʇ߳ԙТu_c~w!KjKg$ld<?̼*BkeaӖ#@RPPk"L_X.Fwe̗FuV.dv-28!VJܹs7iҼu%4cX`o=OIݪW޿ZBWQ1O
    Ūo~-25^UKr|Zsͮi|B[3˱zdq71Cwp@$
    $x-Wxfu`řPBx3a}Q.ZB%m8+$0\#Fx?sei
    6mm6	{NSxu?\eP')ɰ_=GpIuTKredٛ9iEFeHe
    GĉJk7ey@UႫeMOr_&̑*I_@<'`uI IגØ]4NĢc~F{մ{)?cy}۟@BKd!DpR;+Jywﯷ
    JϾgs>A׮֬;ؾ%]Y�X$`o� l5v١r蕝sj\ݮ"bvz2%t
    0ĐT~..Y?/<fHvfמ9<(v:ܽr>ojG~>U~YZ	؅mB_z Y$%%If/&;_%[R]קt%o"(LІ$zssD=z_-e>\g^]Ƥ�
    ,+S]8	-3[=|r9@r}LƟдe~+$HeM$L\јJdUS#gK!�Wy( !lcjh1BZ63)%݋H8[c.2yT
    ;9oFjknϯjE&\%.	*+ LpQ|G"ϛ'Hx"фBM݌_ѕn+/40x,~.F2x=5(U!r0޾y ZA"q@R"*#tJҡP{"SKbfWI)t%n,Ҭ]F~3L:Tߞs8kHb)$7$`WT$8BSIԅ*3_|Rh`z|nN\3a
    `3V""wXɬ({5Ǐn<Hүf$7ؔ.6m٦UbV@%0^T;{W.wbᑫε+EaJ4L@MF]沞]X,։g-
    5pdfDQ*5mMa峿#g޲*邓*ˮ$boYDfS8C綮x-E6I`ƀ&#ǯzܧ{UR&cĘm@;]]e2$rW,2h94,ٰ5**+L1>d9o廏C"rW$SױL1ҨQq
    {U-'L>j%mWђD
    <.W/02&ҕ&F	A6җsml!2Nt2+o
    Ȏ1W^k&Qוf$TNW�LCya&6+sm_L}0hIA	 $ykRNYt%b*IK(Iq{!�P6HJ"!W\jUk  ^)
    $Xฏ'?X;YX0
    0MiZ6kbҐdXDLUt"<֨H@(JHGR9_7n,#)>KipLT.[ĉ|#M^֭ה-)ML34a؈7OhIsXИ{ί%M:">o*:8\X+K/t�wr$?EJ|z*GCX|XXgFz(8A~Ҹ5llblL}6s'4ç3{> O*�nݺ_9pY$D/C\&Do/Вt;7w	z{$=§Rl>C2B1Ĵ-'?Q0"`jxH+hJ}zV__K@æ|֨\	A%W$1ʦ vYQV.]TRQIaI犈ITX,kŊzMQ=% #*W	vw҅"O+raS^'f)qY5~dU
    WUHtE Iѿ6mڰP~+ϡ+Vb5TBeqke$mIthM0I`9Z
    #j*zYΝy"E0Kb6k+M0<L7h5a E9%Ap<˷zmVUbƤ feƀN_ьtHT$[(JXvr
    bɳw^+[z=M>͛%]ˊ:sQ`dn2(`c ƚ+jW?m|D3{`uG�#	܍
    VpWF�>ZXqK=hTB(JrJߕ5$%DھeƁXȷJzɔ&勲�;& VU
    E`|@(hИ&"٣ߚu_^y'mN$mW$poooP	�'	{g*!&ntTdʢ݈߮¬Y֬YZ囎"}$l.00W/jkUBД2Xp�#PI4&"hL_zrYvpզoOaKF$CŢ$WVm׮]}_|4<'5QIZl[`#˗=ztr]BH#GY7Ek&A%S`bW_T.i1SJܱʭߟI6nyKȎ;pEi4>b)(L	*_R|+nʕ+Gٳ=uZگV-}2lmoĊ'ZV$	+BAX&}Df𨸛aNL%O>k׮cLN@Oa@͘xLS4SpBvcgضt$vr6qkӧOq-i*	*a`$ؿ$4&HNR01�$: T8Cך/`0dٲ? ږ#̴$n$r1Ks$#E_'OHM4l6HLٚ+ٚ]	xKM4UC`񹒱CADaZ1#~ݚ&篘EGآ_]0ju $q0L{\@QP͝[{8եKWTaǣ"nbWbڹ:ZjŶ,I*e,dnPc	ؿqo_0X	)0dok\QI 	TBb6�@!Otɜ_wyMo�� �IDAT=GFԙ<0kn
    }I;#jOօ.'l.Pi-�]	<֮]/w5Kڂ-M[?|�~dҐFG\Y9pUL
    hԭ[w0Ob/@`rTs"'쀿SLa�
    0K/&{�1G-I$2V]TKq8q+wlfvmSf	Lҹna['
    \ҬyOH^򆩈q2#�1
    zfot"fjA-/^AAJH%,IIرްbBDnaܸ1xa&}�0E<#w/]ٱ8Ŀc8NXb[;b5YO=	}:tA˜0Mp&4zoܹ{,hjtd`*7Lt;_jg&f+9lٲz:tرc\U01�,*am )YHADW4o쀹#Gs3,
    I҂`0~0?p࠘!tunlB3wpp0WT5Z&ѕnd꒠qΗJds]H?|}{M̙Or:SGF}ɐm	P)f'>Е1ܹ3˓f$ՠ)5#]I&6CLXD#ׅ$CÆ}ˁ?2훺_wڧF}0f=ݘ1~vؑe˖9�WqЀXd}
    ömp0I&W$IC:΄B4(ƃ5x(\2~*9.{oo>fXO&S`2M} 	bJ"F%$rdȓ@!Ñ)%`#I4h#a?ᗔ!}"7v>O�WYSdǬ/UP8:Ź~)#41AD!Qג@%ׂ$G8w:O:)r	*y0)TJJQF-Yȑ#LAI0HI+DK'גPt-IyӥK$I6tJYjwcRdx`MpذamRk*(�:z%6
    qK!	Pm:$ovJj[2RR R8DuJTn1ڷoOBcST	5`DѭSbH$P	�)pݻl#8b]({q;˒iw|\dz`d	FD2${ܺ~fӚ8~ڈl6n8+C_*nāx6ź<*񦢅x{8gFcŽ;qD7IhI={vmmIKxxDƳ_NqpW`ryT:wߌ■R ˂r�_JGI"$ѣGG/o'@ns>iTtp&.^1&v
    #Ft)qD@$3[Խ{G6$!
    V)ׯh_ݻN"DP)Ѣ|iEdHm[7osf.+떇$._�o}U:	u<*-9rX].V,3$ߟdbUQ�#)$qsRxsfJLkRNVN\|'=D|ɴcK 6Hԩ˩n
    tTM4w;vlJƤPN?Nl5*U*dQuÇŃ,a"$dL{բ ؇pra;tq'`Rdȹt�foKw+ڵ_~7n6m'UqLJ7odK;PF킳dXoFفت�o-KAlsuˣەԦM,\POQ3	ݻ˗//upPy~@:uG)S tM mH>^6%N֭1)A-^ϦAĪA+/ogHc%JCnƌQǬ<'OᔏqF�UW0xDfHBMi*w	r*Hz"
    ΕMpK\<F\r%`rmTb5Bkj2-ڰaÏ?%S`);?%E^dq3H ڴi?o3vc͟Ѽ@�01:&&FgϾVv(>[f͡CP{TѣG/BfmIĶ`"$Qoppo7BHe|δfE~!uɵQ	oaj28}I㐰=jժ͚5˚5+n֬YO&$č"3-nb.߻v^x9r1[Xș-uS9JV+	+uּu͛< 7
    tbΝ9,LZQ1!|ʕV-Kq7$ٰ%E>̞`ڌhwهw};y8 czm+3&6)U"3L
    u-B׆?#F
    qن.y[dI_\|eJe>Qܕ_hMgx[
    ];4u}}9q_}<F^Wj6K-6k긆Kg
    jF\bB\,;=W}]>09(=3HB \t)(Yr&mD^n#+C:ݛMhɻ<}d"cb;ojq&w1"8Γ:Ne\h>C[1UUMۤ1U*f[a/Wј\8$W\q,kNK’q駰KD3++~�Hs¨/4ͯ釿ާb{'yZ|?lpi}<[/67./73
    y{/F-u[ϼGCgӎC~gȡL*{v
    uUxkFˠ008=A9Њѣ1{߿?n%rEᚄ7;NN^xs79rllnǓ.|ΠEhѢiyGwa
    �qtVo2-UN@k{P?yzeuKyiܻj$=e(P=o>>1|RU>;NՎ*aɒmlx5,X>@l"w¨D±;gΜ]mٲٳ̙Ӯ]N%
    e\(80חyiq;+/
    Eg<·@1cZ:oޕ_|Xm_xX~*5DUXfILe^^/c%\_!F)wʭ|s.Jf9YS4fg9.Jl2?=0{�/ЍsІ_Qh	Lc&X+QȻ]}_֓đ_~O߃څ,[yAtb䣿60*jsF0bWhtVfk
    }ʫyyu.>?WYczՠ2)])n%KOtfw3gΜ'zfq2~1cԭ[ӶJ;8ۊP	LrZwnګ�T]Ht(O[NgL5_f',?b	ümrd/^Y7읭i47Yp7+60]I™WT9rZ!!@%!vfӒJϟg'M[oqd{<$nYرPBI./^02ǕQʶ ըQv2`o{eϖhKm[wGXݢjXDRW4IqGe4307RKVe7Sre	5fokk\ſѯHvIj׋nW>|7n
    p*'T\kT9'Fq;/<y2^.Co,e~jA€4a.0D@Wbۧ׬Yˁ]?lzb4#)UL{(1޽Ly٢Cw#S'7*՜TDFs+>GwX%`*lf7ǃ,.<\-5otOax@Cu)'T;Wpް*Mgxo|$-WvsI=g7A1dC|RժU/LqG\[#)Tr-Չ}#tqtmӀ^zqmgtJ,+zDŊ
    .T7O[Rj`.\J*Îβ3]IuhbI鎮,'5mtӦMs222te2*e
    .^ιR!˕+/|	ki
    LΉM.J41o!jJW^͆"9sUV'(G2zJK:ueˡ1U6_Lt8DB*)SVJ`__rjn&ȗoƑntܸqx{Pr'`8?IGiIP+*d(
    1CwMl\˔)SH':s5Al93U6RK.
    ļ
    0	.plg
    YMj޼9PAzEЏr.S(J^
    7\0K*λ%+՘t-$A3APM	Y38+pۛ5jԈ-zDWg`);\&a(=P%K;^h"g`\J-Q=$I`@u	uUIX0%é!ӔPoݪU+>:`Ʋ{֭.]vuvtEQp`fp2al
    ,+YDZ
    [H*CP+WQN$gV<)%82t݋Eip.2\֤_w/Rp*u&.]xA>};]QrfHBJؕؽayQs~>_~*gɜFb;{ܺ	LL޶;E1#֝RlbŊ!U#Iג\=:&`v	Z]+^4h0qDqK !S{^8F0eP\~SOPEVLhIa
    IǔŜ\HK>868qqVԱc*VxQr6Jk4ٔ)S=ck7n65|R9S帲W@30ửG"?B*kIF4ؿDErQHB.9c%}Ž!)X`ppp~,X`nz/_~~&[P%
    C]ۘ$Q*1w\ou]+Kz๚
    W\cpD**@]Ŗd*7D%wuV2m<lڳgOrbuac8?;b`rEFt,M<l/+~@I`^PYD%7v0kVs1{kٛ&DÌ5f'F0S=B\vV/WɉY/?61	$*@$IbKrQHBZ.i]wiӦYo۶$$w]j8қmv:P0 LC=fbguժ5ikH I7l<1ksHg^O1ѕ$fpM4]q40]vCADS]I$7vYJ[~T泫UŌa@i
    I, -	z\QUQP7G%Aӧ^NKN緱Dҡ~[	L1DA#tIoŷ'V^@:$GKGsqlt4'i4s�6׾}ٳprx#-Zئo==)wor^u�A+	cZ%J6PqA[F{RzM
    
    
    u*&mZvt&dLd҄":L	vԪ׸弭K:m۶j֬KR\M$q'HBhJSV*FMzV	|3.{NcEԩS]K1L'1I|Lv&oz4fiOٲhV8
    4>3H(d*>s|Mٰ[5cbeON&*[,.	:Χqe^kLc1ULV튒NXYdI\ϷїO}q-k(6m9nQcBJ&$!+׳+?7B8YJvȿvZ7o&SN H*"v-U@'-nяI/\g٬WEEgOdæNKcB{Cq=T+9rOZ+W=�L*RqkU[9i8L/_|ly>o<
    46p(DX""W5)9AB'M70ߠuDxke97o^݊$O$zdg]IF4"iQM�ZH\SK4Yf7
    $"0	D$WəJT|<BVjT,kl}_}$Yt@sn*i<|`ʐ!
    Ot9XpHUIIL_t豒i7mXY|e话zW/nK4HB&.Jkm֜6?D}eJݸ/4`rH&$$LɓAF]>\06)iq[߯o$DFr-I$㒨d7kA%-	`bR�T2hB3
    %TZrz[
    0ln%V 	c6`$NhLx-fS*T) 5o<@	OXdxJ	,̀tt)a?ZMPY=%{
    -ff<%S%RB)b‚Sk70m3�L;;3]\rB3&~qK7hب!+##6Y磡Hde'H¡<HB&.JXQn~+eN
    .[d0^K'0 ,7k%X4웦Z�IDJ\%ZGAMbo{vAHo\u`'nYZ2+u9n'2dD$�y:Q_w0BW"XHBJ.JW\qt5dCxrA%&&H,$vGC$z(${;w>l0I�$qdHB.JW^?d@}^);ե`b*ё/"T#OO魯PIq&q\ј,gU�xDEJ$ޏ:u8	EJ<rB2q1Tbggn:6G39$<{~xTSg|ZCȋ ;H$!ODND>}	*1$)vqf|Kn-"]|%D2D]2~+
    n(C/>lKϘYb?<CԴoUxaw,p3ᓗȻ0Wa'MS,=3\KӅ)p\&8� C�kdv%H@6D 'C2Q!!>8=K6$ٟfGTe`r?!.wD}G<X1g֯XBԱx˙y�� �IDATugl\USz{zI%S	-9&P	-&mYhxYw35o:J%Ik*TzNǏ/tm%۝=h
    fL`|_|߻;gQok&j'Oh>U.ZT/yyyW"oXf?1~H*ȱE`H!ز5MWyi(l^sgN3MY]ӏ]=JQ$%TÎ#b0cL![|ĵM	IiA`(MY#O$dPZ]RjFjԚZhtV`|fXٗ~q%ӆNI2Anب\,7̞Q=3FK[6wP?.;p*4Y-]r-zSjڷ=o\Iom=-5g[?ӟ\2wliK0ҧlv}қ,״kfVm'^U߿{p֢e+StYm7^%n(G&P$LӸW%Y2DXo޼iz-$2.-l(=w^ߓe~TZ_8ڋ)ӜxnOR$vޓƕ{3Gj=g<:IW{UHwq}ȉ;J`ٞ,YEomc}J}{�juGrzuz^yRzWY4Gv&{cHRl̻ڮ궸^`jZΡ*XnxG-[
    01AI <DI$dJkpUZ)9Up9G}o~y'c #d72�,/ȍaڙ}Υ>sBk*VR/ѝsg$Bwv?	|D>pܲH:g`.9}'Uh}*5
    ͸.t:3bcŮU)KZCW:΀5I=!ɸb*"ޫ̫spmq
    'xSչ붏Xh~ԩ"Ŝ}5tAWl0z~ѯ/Mkm4P)#VFZ&f
    4޸ftoHӎܻiĔTMoppCxtqA¥ cfc#V|tlT7UybX(ٜ>}Rhճyԯ'�QOt'ɮ4pf$*B*%Fjgud״h5$`YI!G'ܨe6(eKXڦ˯Ff)^7/9KWхSֵ5dW
    xtiwnm64̨UމqTu8u}1yvC癔>szS|#þU˝Bwhe}2<	B>xDˮ4숃Gz1bLc�*ޙFQm|V@EXufUTH $$\Š  p)(ACPPEByCL&$3?zjzZCjUesD2o-ѯɞj2Q7&N_9)-c&>1W.Ev92i}Sv¶Wru[sU!
    8.Ri/F/_9ů]YVp#^rEBdTv1ohd/͉_v̊1Lic]2//kRe_#P0{e/NKK0gg�8cEN3ܹgrNLk"sspJ-WqΞ8y3ʕ
    |18wE`4%`*~tef)tŤPw^{!w
    Oee/p/QLl-2S0g4)BosȴR(]68{+]V=8o*[ZL+8ɗ&ȟ,,sbd/޽e僯Qx_ҿ!`OxOk,@۶mׯ_//cǎaQ]q^zZ,,+]
    (<~;]JT
    	
    
    e[޽{eG=G+CXjV*|15%!CfDDAFJJJ"			ݻ0o0~$ȫ^YK@d4A@D?p׮]Amp"l߾}ժU_!\|#j%m+9c'x 4lŝ8qBl۶jժh]۷o	,Mt)1ISpt@�!ЫWO?tx(V-q)&NؤI4M:Ջn%YC%EFjH_#L=#
    _k׮=bu_ͭu5o޼o߾۴ic]A[WJtKx+ԣI#I6Eo9rX7k֌@U|ky4+VRIϑ4
    Ԟ!�T?(TRe�)”Ko!f*K}MVmQSagG:Jn&r`#֣t$jx\}R˅�	4-+5�]CfW$gbGlУ\zI>_O>
    7z懅
    *f0	}&R	LUs
    ]0&D֪	
    t<rYmmڴwFX;>m�1_S%F34+BI+(Aӯ`0>4Fʕg޼yO>$QJHYI�
    sJ
    PHtf>1ё#ѣ+$Y�aHb£	V	+Aa8e[bXPH[gn#]͑ED:sW3oz
    ѣG!A)Y	88HD$r8plq*L"`%VBWٟxѯ0W_:d(Tsg3y2f{+AO	dƕ$8)II!`%Vb]#%}ң;Wn%`AahQ-kԨ&	1)	)	=7+cYKF;IѝQ$D$JkSMb=ztÆ
    ԩIkBFiVRi Y>t!BF"8"#<$Q	VB5k|g>	*b"HG\#WX4+}F"ыUxe$	)8р52L`OqGYf
    E4Dx99]#`1V嗜3a^"=)x%H$HiC=0h7g@鿥dܞ�@KXJQ._ۜ�{)oX߰aCHHVA-weU1O+K+ɫGbsc՝:uCa=-…1)&Y[FDDxTƷ굒Ժ][oi-­[fL#W6=J*U=ZV_~]ke?Ek+OVxXz:|4n�Im1h%VbNwgUYԢZVۇzQ]?^mY�[n/-34go:t8->={GFaf%V?*:,Y/;z!KIa%f߷Y֬[|zhhf% n$ex$%jVsPo߾ѷHF;*UHi|MJΩe!errA슏 #8HLMpEPB\"&R	n:y*BfϞAd1k'rK.-/nԩr+##CB|A.i3D(GhvBcSXB.b,re1Vb'&ؒh+�3q[$ŢAVxXpi5ZrexxuX~g4iB7oܴiStLC0ԃVBe~fneb0yQ,J|6xN:Y#4k֬Ɏ1bȐ!][n62es='=kLIIɝiCGs.aWLKYrG4a%;S ֫ی%&&~ӦMs{W
    'Nl7x1olBBlРk )cUVeӸqǃRڵBI"%A:HI=Tܙؼ#F]LҬ9\$%6m1}1J~AJ>j
    Hks YO9z`MFL駟YB	p$bοFJ!Atg%i^RtYbx"%&J뮻|i(u\`qwFa"u# +lRA?GR`+1}j:&*z\(I
    У!%Ut..R!U3Z0o{JL֓QTK7n4aYr�QQQFrKĉ%\CT	n"IAI`yQUZD)h"qǏGb=%&JT	
    BlR'/y,U,hR~QT Vr	aP&"z(	/..3^_ID
    =LۻJJL֓hZdNQ4J"F4 BIF]1w+	,JI>Qj]U %Qv8hukPVb >G}CG.A-Z`cСdcJ0W^yu^RPҽ
    2SR1;>yT6,JT!6輟ycuj@͉			L<^^ӭk*MZTdl19e
    7`7b*+ر#::8Uc	كڨ`Df27%1=z4&kU&9>5t醌sTb+b^{i|I
    AΙ3	?ly4?yQ;#=xcq(xn֭C];gVΪDa.KM*{ڞtDe˖lmc[
    {$~Z7r<nTB1YuG}3̦, u
    ~Fv;v/ZP{f킢o}yD[/9UKWLM]RV2S,Q|v8X(m9"W^)B#%�FiX$YfM
    -2yQLTК#mUȤ
    m+/;o›o9#8jV9s& 
    _:y@EbQʦ3f71Oʉ$V]$M^DfH6&n.a~(ԑ�YWnmY	9qf+,0`kLA9U#%J~f׵kxn>kg~2wn8V,:eHC9˳K`ʰsNA}۱gGaL=J?/JJTTD<G	-rB⻯18PDe[\jjjѪY?e*;ovSp^9tKIJ~-^{7pU@S ,oo-Cȧx0$P^GyDlTqקux^W_1pطq}wN۔0yyizkS uϞ8Ncݰk6LOVk}]͡,lG7~gYqpˋg`~:16]p1+QF_paY?hr*Ca#ġVmnXpK2^ޜ3h)pX5aÆ`CѯzqÆ~kժ'q؍+fN.0R	%BIL3n]Fm#Q1_QǓR>9z]ʜyM2+gib
    VDӜ<y2T)XHMY"q(.
    bߣ}^gEGwG_4_P_.^zG
    7_rf<іq]Uh#jycܭzP 6�=C”+Wft {wg<Lo©Կ;¼Zsh(pwU|'/JڻwolLԘZulhԲIo{ս3;=^us$u?G))sgIVWZn(PDqg2%T
    <{1U&P&z8)n)Qc7Rqt
    W'aLrC{~0'\+Xtެs֭cE)Xy!+1%f6bu@GCqpog584<P4lؐ2Nt4BIx\	Et*Vh<GX|\uk^dG])U/drfRq)�Yjf8=={X(쭊	Nʅ|4.-[0Uzuzxƍ6ylgvYQtrq>}HKrw3X{񘤤d
    *YS`JSSB{̏4a+qɄrȐoLm_0>3 w;><~_S/ҒѹctLݻΘ18P1Yf@mZaw(AYߵ3nuI))ŧ$+]wns˰=9HaiWozb=P3ĴX8(Ez7@f%˗DPiwө�FJ$KbpIwh?.;EkV]U[@I{]K_ugM3"O)YJe9G֎i)ZM(ݓ_lӲW
    O8yJv}+ϿTFzb+/S=nQkё%&KS@,,Xv{bf,A! (tT+.VٻWQ5_Q=RL
    %u_V2*`m۶:tG_d%6JP222YGsn}<
    GaM>:54}t8k(Wι_k" }~\L6123�_gD@J;>-9o&�nra󁈸96
    %"SvP|7tMYI`;ziӦmڴ	ìtE!(6	5ֶ_l"lqo.2Bq^	Sn8⹼LԙhK}[?snj/YI^?\t)uܙT=D�I9~8H_G]￳ݟl@(;%a/|>c7$,x
    [N|8`aJidJ` xoӁ	'ѽ+
    Y)Z,Y=ڵm=c3	~p"Q0\î+QW\uUV+:	
    Vk˖-#G_0;Y;<Eg[*4Js}fOUp
    -{b3T3b߰?2.e5jJ9GZVU�(s:5be	P8-цki5tG#a%$8!+8s3fdK\yjWe[M]S#wvN>_q̓3cڵcCY9
    ˊD)qYɪ1v܄1أp*ţ7DezUy&B1_	]Z|z(䋠$ d^ӧZƧ
    <|Ïw_߉7WNb}։ζT‘y|TFEVƑKʋKzQI#KzHlsK,sӤ��
    IDATbn@AVb*[,	dZH$QŚ=N÷S8`͘3n#9pDp3x2_;FBx(e(Lʠ	r1A+ػ6[jtHQ~*rczNն)s6\J#:Z/w洢uzqvF؈>4]ewl>݉!7UYr?R,SO(i=1v9(R:#I٪CG*0�qRYuƉub򍂛.uhOwWP 9W/9r$m0eDҟ~#
    -8ʁk]b{͝9%cziGg~pȖ·?>;~Ҷ)B]Gp!qUo<l{u|է'Y)#N
    Σ.Ӭ,LI){)a@As	
    S)@0W@6!?軀EmxglP
    +JrT
    d۝`ԡ'}`;x'ueMlҴ(2NlJ~$___-C(:C13ܹ?Cg_8	׳93oYg3*k?$|Viv~uƿ:(KNZ^\Աc'-.!Y(&R|y`S&V	_osQӊDOоۈX\`pH㏥/L.[9PV=~C[YXB#^ҍ	EVr[=e%A"(1ʽRFC:v7hqV%pL
    W)֎T~r\Q#i"4w:^xw<utjW1.uܴ,*dBL0h3)  .yLz%3Ն΋dzyl8t'N:|%N69tв	Zc|_G\:._ϖ
    .W!L򼭃]HJb|y	Y	bBD3-1iY@d?%GpsQ~~.GLяbUnͅIs>J2F
    IINQɼfum�Sf?�c0(IH?n#3ϽY2R\$%3Dzbᓶa̕+W4M4bJCg)v6EƑ)Chi8yhH]!N_Z=u-3'.RR>$%SjVfbYIlKHH u7Wvɏ;*lX+uZ@@=Y/1(44|+k&/JN4CB`I5pˋ)4?%E)l;8(2>n	&>|.ir+IGzkKB[7\uzқK{9듦:E$C-AI J^nNmڴҳ=M5p8^~NKoE$;x̝rNZusGQȸu	7ʕ+D"QJu�7rd5+yIK0lfCޛdHhWW~h1rNsH$%f%4<kƽE_	ye!&T~[__u!-U/</]ڌ-PRJ$#AY]J4+\L)͛7'tʔ)(.>S"�%19"I	^Ob(g[L/y$lZ)>VJBw);fRI2f-}G{|�Y1Wdt
    oeNV~۹;BpL,](.[b*iΎNFJn
    0J4IrL߱<oD )w~E$aP|V~Bq+S)%n@IR~0(<1S`ӼEc;W�?JR�|(	TJf%?_g1{+,yu{Y٘d٬DŽO?4}^3pMIȞ["�SiV*fя&71SN#.EbJ<s>5W}NRV%fA /bxʡ>wnє	aE�ߠUo8AQmPS$@'Eh0"�2PpcYժ\iQS8·~.I(Ip$W2pc<H6
    hV2a%ȢbVk]ۖ%=1 m{_Kh,"JRK%pGb$(	|4+H]+#1G$`o۵*}mx$#\|AIH8EI`ܚ\ۜ(#%&	W 0{g֏w}Ӿum#g8xXknƶY}GP'$cRVkVz
    (AIy]2$ӻغ?e9K螩>:^_$d#!&<FJ]LGƷ$hzljOgq Z8N3]pվ~X^*,=Oر3|$)JbM6-6%f%6G#P"&Wn:y$p;T
    iɱ;JKtϬD
    )VBJ
    %b	&&3#!&`oQ~ќI$<fgOBIBFJED2θ!"$jV2.r٧9ϕt9_8MAC"E&$I͸ه�P?0"t@_4Ө4qie1ݡh,׆ARxIIe%c~@Gb	Y	ƶ )X	'\mKIT
    #yIL"(n�A	5tv<mڙDQiF&&B$Qa%8Jbb%
    Bbn}fr#Y)7&:D#P,"	+1|cACW%(<+Vf%՘ίGddI,٬$J(rKT>Bt"DJ<jV&:-Bᐕt &ؙ�JjEڣ2}`"xGM>@F\qđG!$WXt6-p
    7Gm	+ٙ1h,[:  LFJ"�KJ,jV:a7q	%_YI
    	XO7k4+t56C)\W#0)LZ1:["YɶU0)LZ1:["YɶU0)LZ1:["YɶU0)LZ1:["YɶU0)LZ1:["YɶU0)LZ1:["YɶU0)LZ1:["YɶU0)d$5,%T����IENDB`���������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_filter_new.tr.png�����������������������������������������������0000664�0001751�0001751�00000002456�11035423623�022431� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����K������	PLTE���333,/��IDATx^1n+7	<@0x)Ҥqb2УlJ&XyZBwE?`ªn2(ʻ
    Q^JT/_Z>(J(JR >919$Һ�Gي(.pe(ڃL@KQ@%xϋ5̟QS+xFUT4J%`G+ëD0~1QȫS\ Da*bq%ܧ;m&Pv3BŃ|"$ .۩Ɠ~8GL@Sn�$Dmj@~D(~@_Ost)l_>t骝&_	lNKE@:ӳ9&U9BAB2TXA#R%)x@w&0Qs_u)QQXD'BFr(b
    7N7>V|3N`CAo2Mt1OFVTAu2_8s{Tr=T&ro~6U1(y.U7ķSuS^F	VQ9H8P
    P&%wuN
    4o6!$*b|CaEQ)[̦A<*%g�1"i灕JPEKtJ!"NBvL\)Dg[R7x̧
    \0pQ(c*QgfQӦR|%RD/!8!N,*TMy
    T;0;}h
    UQ&5^+PMώ(pa(O+Rmgw5.S\t};k"+S%R,?jRkg"vVvVvVkgM)֫L)J(N_ՖYmH22J0,+UPMHꗋQgS.Z÷3M)*eP.٬.Sv%h%ba	8pڽ)SRyMJܹUjQ$
    t(T}SWJΫ5lj~:1<#JS u2%>Sq*C	"XXg o=hPSФ"SQN<N`֠G-$~xJƏx/zQ13%BZ{oPw9L?"?Yeu2(����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/caching_fig1.png����������������������������������������������������0000664�0001751�0001751�00000032214�10671421551�021310� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��X�����
    ���PLTE���  %&&+++&'(555469:::7894L(6H'>Y1;G>@B=CK4AQ,Fe3OpDDDEFHMMMNRXUUU]]]IOVIWhO^q]`eLb}ccdkkkgghimqoppssswxxIgLpSkPrOxQzLy~[xkefupXXYZ\`ycwkagfmkcou{tspx~vs{z~΄ێޔܜ֙ٞםܕڐх僳댴㊶댹킶㔹哻뜽䙾钾歼̤ͥԣ۫ҩ٢жƳʻĸȱСޯիڵͽĺ˳ҴۻѾԽٶߣ^\���	pHYs���H���H�Fk>��12IDATx
    T[םQ,msŊ]`
    t;۳l3IgvR==G9gPyqlg�`{k7J6Sc$i(UJԵ,i8͡ı,"}}6}>~}[!3aY				&,&,&,&LXLXLXL0000a`1a`1a`1aRD+ӽ؃J6inuf:|5ײe`ͫvn$1X%u@r#ᔼJt# 
    AcG]p8DYrlX3ʫ	Hra-t:]0/q'n۱v݃@ӈ\]jk^a\/1|mcb{[aȅ5b,
    ZDiNެsUk$MT
    6hj@hIۚD6jj@Ĩ4VkM~A:zj\�Vu’A..%tܤz\K`IW\j<V=|U47ׁmh%
    ^vXDi^1̹.p$+u(`a%kJJbQAC6B&8on})0B
    ͭrKU*/dt1Wv{H6%-W.hr"9-&�E
    ŭMuI&x 9dt摆|6iLR�ӕ?5ǟ�ɮ8&)Xk1q>ׅĵE-ѯ?qxW�X+V^/9_W)V},|_=[ZǿjקdsUkV�	fVWR{P5sWxS%xGc/<){o{S9L鼯Xlb *1a)&,&,&,&Y#ńi,&L	*00XLXLXdJ$#čl2
    GCagmrmEq춡cg
    E;u!\_$a	}vPoX'_p##vk/u?odnu_WbFahԏg̚Tig`ݴ|xz@OT
    _X7/xhp@Ou4"\ÀsU')|#tTR7=o?df_ZhP
    F&TiO}nbϬijW{wQ=hqEOxCi	FǻH⣏EFVQނGݼ?k
    | pFcyE[O3Bp62	K7ukpOQ_i
    eGWj
    N`C;#9oMCLL~
    =m)cpH`Ԁ*Ƣx-hin<'j̝4*K�+⡵4zɧ{Ni6]#kžС.ƊxԀ9:knOPu`)>zh7l;h)8^س'yb``<>u0=NMnr;<)ot#D	0.ㄊ}m<ԃfxWl[Z8.M Š탨O(xv}]GNfr{E18Tf
    `mpަ{;;w:
    cƓ?fԛA]Jah&ž;qꈢC22G;j�wP0m}Gp`#mܹcGω* MB"
    ,n	eFp6A⊞ى}Σz3Xj~>ET8A
    tA؀*8qRlhi>ʁ菤h
    2D6<6#g>xhؼb �Q45	LawSNܻ'rޔ+njZO.p
    NNVOQu({xDr멠D7OkJ{jF=(cw:yRSء…B	v;SZf
    G?SGcSs1ja7MhSBM1L@Ma?yہttPʊUe]9/`$<Mt(>L9ZE
    M6<E)Bذm3d=Q(^v6Q	\iJ;lj*PVIlt	F~i]G8�Զ7I@`[qM~Dذ
    ƅ*#5V$`##xڶàmF/[\q-KOqd	b8uz&Ti~l'AjJqҥq4rK/r|͟YYQATѶkx]%>YVwTUorm*wO~yp6nş3sPFK&/I1t�u01<SX8igVg"r4)fM(i2tti8Gś>zL$ i73pm 5̹iK	:`
    /	{ZJrO_84~8nz`@Q˲p+O3zٖ]ˌs{K7b7mǻD=ŝNh>:]kgYr]O8	_ħ&
    ,]Mw3/E;'pS/vr0v{!(O|hNr˘ɇӹeP=dpj~Zq:Aѡד5x4	i}iO%tኻCz`	6Ht"8pEGvtEGˋRO랇8Cm9H|1OȴbOS.v҃H_>e`)%Zk޶Pϩ'=>u}Xp'K1\LŹ T5m;xM"WN7D
    6\iʙJ7jLw>POzk4g*%6h>9cPU6+N%r=߻ʜ8?b`#֞<tB)?t,cM&'lb!q@F+|tѓ)!kn'\tcW|N_aMr_*(-DGIQ0VJ2w9k@w&Mݖ]W8цT;:qo2kR#pDJ(,3 2paQfI-/AT+"`K8hfc;Z7pMU!Q_4t"JjWĜ	4(z@J5w, }iBYH^džU@W
    4+)hvFwON	'x1JWĮMǚj(b"X)J"\8,Q~ɹ<7/;KYRRcCvn	V&–9)zț Dͭۻ,	cʦ\HNB+ūM>+|d4*QڗgWJ>zsdIt).Ӹ>6wdOQz6c#XcM/p׹{]Ww<-Bc^YORYlvh
    AqՓbXr-8ދchlp	*6.G*X{4)ܼǁ;M!TIoދ	wUsd @|صnzrhсBGҥv0N8@B
    h&
    .Oc)WL"KP?+ύa=*Tqhb0%wOBm@87\hہ]G0_ѣxҽ'
    3
    V-Y[:wB_UD 6jC<v @Ø*ݩNK]c8nnR@nb#"(]X`mX*U	9;<ưo& ضλ$%Z4
    Zݢ-sǮ%؜<b0c.`zbww=�ٹyAJMCc3gi}H1J9*03(ΧV xB	.HEm93uy3sBe&DܧfePez͵5-#K�zvsq4Lf1|YKgQe$8	+~C{V`qf=g)dfF5z24bÆ`=0zcX3, (yST[Tʔ$,C7oNU7,9xc*R[l__1B(DݬhZi.$!\2ymekǍ{>Kc
    a.=YnV`RzAzZdzY0:2KCصW:Mɤ06MJoqCi締
    6*VE#\m9K^8P>4SKv�!`ˮUK2VCPۧQT`:87Џh0)듌֝@<$"iw)9J7e%zm\|ޭ6qLj`SnX*EPbw7nL~Sc]1+f|<̞9sE7XyO)b,{9ڶ}͡(y-|;	9ZSRn7oYL=[vw}}kvfuqd6~!yWTëS[;rwcrqIqMm}ĝ
    s
    S3fxmn5aAWkw}oUТӶдOCfͣYw7b'Oq/~;n]s[ΚL+k?ſwܮլOnκ;W_ojr>ş\
    <	h2}AjW:VZ澪a|:r
    )Y~1￿o?p緿U]S߰F9U-pd(*0[|[ʴ|ܷ3xyGi$cĄe+ʾml}|Blc.s͑u}a\t;6}
    HDȬ#cEFm|4zg.Pƻ}a׭2m9_hE{$J
    !6iy�dCLx /1U7W<֍.Ldԕ/RfzX7\qX1B(2Z$)f1EVIFΦ~S۵/z
    VZL!kNipmt3m
    0J(fU@c"(wq݄Rۚ|=|PW=t71d)R�VAR:=AR<`EBv݁{G;䞗XS7zڡ;9}s1+`-pkȀJ0 bQ!={x/+ofI 7*+{s(^"
    ,RMiλAI <2 y8,Q"7	
    :o<p$D"XXZըtw 
    DQ]:Si7ID6ZaVHnkI(9	ZIH70S8콥on?
     BE	^PuT}Et4+Ƈz\iܣtidt?e)4wD%X8  P
    RcEB6$¸Vl'7рƊCи$!>`A4>¹;~$G)LN
    ~uyu+{4&}Kr@8cZ+c`
    ;`ÃeZJ¢¹\-=<[Wbpr"\l
    5Lcy}ٶ	?	U:Bخ0	1NM<֬Њ+=٠_brPր59fm{XZnI؎~7`˷Ae$tC6h,܊7n;"BtZX,*9X#}+b`-:Rlg20=sABk
    ld|5l-;݁	Vrb+,lQȀ'{hؕЩX(k^}tYn`y!<迋2iQoP!0TnHXxDY6	N4XaIqǿv;tGcrm~,YiujDe e
    X(Eƚ?*LMHD3W]WJIgiWO^,JZp_X+O
    'ְa%װf"!/e$xĂ
    <@VXO3l,DXEa=,V+$I;ﲓ+X"s+(;'tw(r;,"`-4ؖ~|KkסZJfLh0RM*X~ky
    9qZjpΗmC0["y]Xs†{{ɄԼJ'Ů,Mb
    SFm{di0f
    oVFU;#aC?~>4#V2wk	ɾٸZX1xˏ\X,*L"XՄd"ySmp윉ky,~,F}~S3YyO߯ZP[&DY�*P{C
    e-ϋ캳FT Zaʄ~<-!ɋ)6VXd߯P`ՄgjBe>J;HCJٝkY)q`jB,lW
    |e>`}G
    nxw:P[5U&Hvwٝu'J`,DXc9'ZሥTLֻlY`Cl:X2oՄ7gf]:Xv0-ZWH(X~;pvMN2\rkۀJ9Sao䌧خ5˕4X´+dMCP+jBCũw+`4+ `fR
    VQʄ)F;8n3t(,V!,LK25`eCTEC<	EbQa2?,0pI0l5w.BŢB8gh	eś´^
    'ԀUBDX˻8|:M`ZaBWw7|1XTT5jo|ErAUBMDX)6]FFߎ0h]!|L8b{rM}_{TBRW8yGvcky#La{j7t1NXV~&(˫awO]
    Xxñ$bQ!0X0`}\>&])d$ȝ
    Sd	Y)+jW0nMnzzj=Z~ISP({uokiSKTEUe+X	eݽ
    hX,*4Xw\zzvz5>Zj{n,7UMT8^FX%Hj_J
    FJv}r镏M`%f
    u?:X1f ao<#֊BME+`DX%HkuVVֈ̿_B5%55s?(`6KX]`FEtMb\e6\(1^TJo4mJЉ:ܰPrԙQasUMfsC'k:f.дvwquW5um	i<dWzP(:QmD"Mx^]`pK8inmNOyōOui׭-6ʛ3n@k{o>,a>PYzQQ65yPރEW[$rrU~cN}9uś9MiǛcPK%0ʎ_i+LYyyN#J"Z`<G ѱ1V
    JZ[uujW
    bX17P`5Vb5:]
    Wi%TvqkDٵ^[䕪qMF%bZk9-Չi,մ&_+T<J$Q`&P2z!(kA/~:)(F!xFJlܙ"
    ^H`eB2b
    QF:k1b`VF4V1U\}B
    q^H+Fdjsj:HC<'VA}HѬ%VOkbJ'yϯaS!!㊢Q9
    
    7Up(
    @TIRq#AqX62wO~"Һ*y@S,M_U�YAQz|(UCުΩ))@l늂C3/l
    UJg{~AJ@cZ-r%](JAёnHS$HnMC^-륀ؔ#kjDM>BNDEՍ6~IC4S(7j۰qk׸�S/k.7-jJ!%o5&I,݀W۹{ߤ&+	bX-
    �V w3(XE)ڜ#z0NKvjEsf\DT)3qHWy:$uԊڂMR>u/%
    ˂mX59UyVX
    vhA^Sc)Xd0WhKuUyjЃ쀮kܲ1P55[$gUc`=N|3@mqܳ.D̨eW5|O-B1%!i
    #vmx*b`I>꣰!em~Do<$kŏ(KXRE".󸬞~I+w}me9Sfc@bR[ji	7(+AOBw:bҬX2_E)uQF(;rVXH̉1dDcE
    m
    Ѣj8ǁȹVYfug>-�u+WLO;3D*LaxW`e1BhpX	J7% m|ZI	ҰCo|!,ӧ_64r55rjV SVV)\%DU-JUHЪy7m$PcYu/?RQYpR1A8h4] +Q%
    /wpsrXQEN	Q%XzO?"ZrdޫVޢZdGTm<
    ,z
    A%G5콥Z]`zs~,UX(`A7mJȽ
    4V{/(VCi떵ˆn*`19mm_[},MώR2{~D'XXy*_al%tBh`-B	V.UƎmf`1+`p_[c�V?N!X$o߰B<,bny
    +zS~R_G"CmИ^xl$o}3f
    U?n6
    ceTc`_[3+rPv*`1=`LceR5i45EhLy{Ʀf
    3j
    ~e`1}!`;p}VX+S`͠
    ?&SHb룽:-Ma/3Z
    >lZHuީ~<lጿ }ר
    GھLFXau~S͔ܳ2	$:(g.Q;c*k{6?E){|#JN*{Xvީ
    {x
    K>XG7%u
    m†7j,VX6~ãoK4U~UJ
    doIu0`}H+X_Wn1RcM+_!2c
    ួ|S
    u&]%֫ǸƨX4k=HC/w-}L1X_+D5;zZX0S`Ϙ,|k
    "C{o}mD-Xl]auGhˣcyUs_[
    tuj-aҢ_y+=o4fBca_ۊEVhШUZYs~R
    ՛D|m۟~-ȴW,#JNq02+TtJ~[f#mVxn+o|܈<j#wn6H2,}I^Af\~e,o-}~`nê+l	Cv647]#ޑ974yzkk4ﳄ)~+b`g}08vh	DuU:U<Qa
    ~jܰ?uP`E~_X+5F:B6a< *$V%�+g~n
    `
    t[!jܘ79dyqEn35NYC~ߐjZla2uȪ>'
    
    ۹a#51},RNwQ?
    ǧkǑY/0sjX^gGKY
    ɟ/ɛP¾ܙtP8zmfYegbQa&5ܡx.?£BMᘽ+e+{AZ "
    `Wk
    Ӌk(`c{Mb1mxSHBtylrbغh,
    M/~w',a7%RV&-QXiڣ°Uw\NŢ$0X]ELŻDC<w#"~.˞,0`+~|h5a[6LF�kK`>i/~|hXgL\ۏ22ևDžMߠ,WHBE(זtgOA1zQmRVZȣW&'	߭#,[
    Uix{Ni,
    W/#M!K7QIt+,٭!
    oH(,/>yqlUbE贃~`|V`7*XiLEak%ŏX2
    _,vq&n?M3�X^?~v^WHXsjcg\,{z5֨e(5pqזJ!Vx`|9,qѹpޮx:+c`љB~[%BɄEkˇc~H]tSm
    b~i+r_Uڃ+Lњzuo|=b&Yw+)\t:W,V+L3XVΰ	VƄ<Vd7tIRX+`ykX,ݐL"}+,T}\;Rx&L?XlT53z/j�Z!pJn׋�
    
    ֙J%BJX R/NMc<PRҴ,?~~^1iY3҂`;>;KRfM>>|~&keB`͕+\YK~f?VĞ%y>W,
    0Y,_bdAnXLXL
    b`1aIXI@bӿN==o~"?E_ԣ?kyyOߛ7=?[yz>`,ӏ?}Ǐi<S3_wzݳk){w|'8_	
    0a`1a`1a`1abbb„ńńńrbl 6RD����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/ssl_intro_fig3.png��������������������������������������������������0000664�0001751�0001751�00000005010�10671421551�021724� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����C���l?���sRGB����gAMA��a��� cHRM��z&���������u0��`��:��pQ<���PLTE̙fff���Q<���	pHYs����+��	PIDATxKr8ž qTS57fAMKɀjulYq	Q@iӦM6m?1Nor<9)TPkqPy1a;J(�cmp/;w`3P,+C!�77P�ChQyuX笳puϩX`aaB~X{YgYqk@JPrXqo%
    pIPL@1(egQMEX235X�PM<c4,aRP@(4|;c^qHR@D\2�UYV=fzDOFI~oP=
    :&+߬xśU_/vEr%LCCNbjHRbiV^ˬO-CxeiQׄ;HHGw$dQAb&I#1CAYXH@L)leͱ;ƦSoICē8Q0iMg!Ob8%eNU�%CIQJ9ág-
    !SG:%+~"bb{G�zN$mq9kݡ}i/
    Y0Kg~2=lϲÜ/X
    exf&$U9<Z5ȴ(
    $DRri2rDp%&*%#J&*{BJ:J</2ҾL
    T\a0v=FrzJtQIiCMx:)(TTCCv<a%C.1vF2LeEġd❡I2OBc2(|�B?F!/AɮS(뜵nYzbA5r=ž$Z893嬳CM
    %PB
    BJ&fF;P>t^R,JX9*(`/(jd+`RcI=6E6E6H~6e~D{?[!Q?ks)oaoj8}^ԱEr
    P
    P
    P
    P
    P
    P
    5,*į.	S[A|3ns*ҡڴ&UjQ<PTR/~>qA^PHH~'#R(+B)BeBkw.XDS%T*GJOPe
    (sJU$rTQ>V;)5N+&1OKd9lJkA6�Ioio!obZȜndFlST?~.MefSG۵Px|u{MuXR~hSB]ze-ٔ<aSsO z?nJĪβm-JשUuMU(}p=U]6RUX
    M*b*TjK:/JHDԍ]W(J|Hue|d=xGQHQM$PjoɦΜ{)OXG_Kf3PrTӌM:D,)seޥ,("柳EdI-柳C)JYPD]g=EAonσS:f=A�OO`eR(R(R(R(R[aG5UBӳ)*ƨ$ZJOI^!IRYh
    P
    ʂJLq+;3AI=7ALq(BCr_S%~ld	
    #9]0PhA,`	5p}&~68ަ"L&l*Lo8AR~Y]YUkS`MP36JR<{ ,(#Xؓ65P`T(8
    s\/=
    f
    5BϸEc+B)B)B)B)B)B)B6-)NܬP@1 faLTT[!3
    ED!m
    P_5A5&A
    ZOWӱB)B)B)B)B*#v'aY4*Q(ғBϵ[P>6_B,j|W@[fDRl~m*T_~"%5
    CU+&!]u(.!~61yH6E&1v-/N6}2/ީ~Nbxwktӱ_PnwkP>?;K%u2ԭ:6mڴiӶS[����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/right.gif�����������������������������������������������������������0000664�0001751�0001751�00000000073�10147723030�020075� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�����s!�����,�������lcrJ%6�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/ssl_intro_fig2.gif��������������������������������������������������0000664�0001751�0001751�00000005214�10147723030�021705� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a������!GIF SmartSaver Ver1.1a�,������PI8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzసE(zn|N~ϯ%SQbŮȆͺO`յذߞM^۬K\%E032ȈaD*H1#DLxLU$)Qœ2Qi䬗H)ʛXIEfB?9
    Yd+8oT
    Ѡ	jt]uIh+zjYwZz։ˎpFpAJ`.ݐTML|»5#C-R$o;zSKR^}Ld364<7#1+Ā<7cܼO
    s/WM;6l+j5b|ߖ`5D`]Y}B
    jIVcWa_f[	BWauM @"0ymMk~9]B8ckx\q8X@,Vgbo#EM$Yh!SMoP$X郖f}4'|qz1yd3f)h)c~4f�"$n$ru\r<K*V&jZb9;I$l裧0Jj***嫩:`UFk׺"Ϡr&3ƲjV,e\llr8':RL/yp6ک⶚®Ǯk:9qyƘo2Vi>>p.ʣ0ŀs8ttziݝ,s0|15
    |b<9gupnYL3^x3Y]$25N32@KFBbp"wm:퐊j}RH'Jx;/z>n륔}y@7пJϤtӤm5ʫ$޻,WU#x
    $'3%sTol}_#>>e>g^ï|_Ni*Ck"g.̀kPπrg+nN )grFp3�sac`u
    QQh
    0%7C'>1H7E*.Xb9H/|bB15h/@:x̣>Q IB/L"	!$'9GR̤ YFMzl%CIR<<*WJY,Y$.wO겗&$)bs<2)b2<3Ijc̦6ŗmz&8IɈ$'6iY}v|<e@3!&SB1pgvO|~|Oj:%!!'A =4WD:7B._ĹNi;iA
    撞D!c-%THg6"33;5Z;oXLA*8;КLIS;	TR>'<~H\VCSUaXZִ:]UP@iV(G4|G!l;lo7?B,WZ֘fzhyњv=jYպ}l=ږn֐pXw=ry:W}tZ*ѽvz8xy?Mz�|Kͯ~�LN<_N2'L
    [3{ G
    (NW0gL8αwc߸@HNl%;P|,*[92.X^`0hNsѥ653L+˹xs>y|mc6jh}C/9Ў1;)[F3MJ_�t|Ei C6/AiTԮV1WPԛ5U4չ5gka1ymdήEiZG{Ⱦ6iZkq{>u{~y{}?q
    ;\	[Ᾰƕ{ȟґ!?e񕻼)OI8Ϲws5|@q˃Nt�Hѓt.PϣN?I:֋^9}f?Ӯ;7._v8]m4}6{m/m+~ތ/w{wG}<A?y77=Þc_us{۾=-ᏻ63/_S>]헺45O.Ͽ�8Xx
    ؀8X?��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_rewrite_fig2.gif������������������������������������������������0000664�0001751�0001751�00000004771�10147723030�022220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a}����������,����}��ڋ޼H扦ʶL
    ĢL*̦	JԪjܮ[�8L.gΖ;PS89u9x'LJ`8F2)3YxHpi`zziyI#+	!W
    L
    iKiˑY,Sk-}z|]6=@fv`
    !|~*??=ïP^{i.l	%gC!~*yH+@^ƠYh@R!ԈI{D~pGćK
    kZӦh=r
    1RtЩΗ<<֎�&EI֡f*ZUlp@kvOf$'ݧ^9MР_j\1?�AymPhxi%2砅{"uahG*زԥ1)D)GG0o}uao<%롖H_mf~=|!fZC#|q`jW0@`("we
    0hnPX{p(b+hb$"	(046 :Z`	c(^EBdJdG>^^eZne^~	fbIffn)%Vf
    fl)gGig;g0g%*hjhLĠVy
    h`8ʉ/az)[(-kb^)D.]%eLYT:hjZ̝"\.|fNJ&1gj-XB-~GAʧQF3.y~I@S_>O?w"W\V*5חnE7Wq2g/ae]&_Ce"vՙG+u7΄ǹR]}&KGlݽv0mqtOe!GXr)>|0_o_ln,Tm\K5BVjt4d-vF[c5vHbri?Fiւs/
    I
    *uؽ.Ynɀ?Њ0y+fۋ.L/j'BDᠢP,aVo9�:f~~_OcwA߿E?{/�M ^=8`	*00E&h"+i?@ODpAP!_pbi8C8|G
    цSDjL|`&J	\DE?pA_DP5glRAP61*s#
    1\#A@6-`#vd0HB|@"C	$y�4rCL&/TN,'UJ#AL% I m/he,kHDj/	`.	ԥ	oY "\L!B38&5ghk0,&YLn9TyN5L%c괄¹xf05LVpUis$d8)
    BoL?pʳ<>UC
    #<&	i,Zxv9|]"*-:*QLֲBå
    NK6ҙKO|KCHgGN
    4]F
    碌'O&MMLzNsnՎt2łu9]m:g7A
    3Ԯ/ۤe=jQs};6:UgiC28Ņ+Zpi]̅KW͆0mժnͳ6r{b{VegSֱ3t{Ul\q삎Ekgɺ&
    KE/hs{Cs
    Kz^Ҥ۠:eb'`rEn*QHjbC踯X-T)ؽåNUؖpm(Hכ,$)/qHF``q7#׀_0'ˀ^p+]/\
    @-iš,q<ye3gɂ^!
    m/"^hB:4gK/Ӛ;OPumj:zZ5W)ֲk}jB:ciԥԀ+%Qo=*L?4=R:nQZho;tȹ@kL+�*yWZnS
    qX-Uڀsue
    ̭\^Rf<z-F/4s
    O1&u@nA[6k߂\dNu.k6bǜ΀4C.!70YyEcN\_zνO{7dNU58get\g(M&`;IϭB3F`*UF~Don:%upEf.R\0%>ZM{=wO?ԗk+oKԯ��;�������httpd-2.4.64/docs/manual/images/left.gif������������������������������������������������������������0000664�0001751�0001751�00000000074�10147723030�017713� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����@Xq!�����,�������iLrezJ�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/build_a_mod_2.png���������������������������������������������������0000664�0001751�0001751�00000221333�11740644603�021472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����,��T-���tEXtSoftware�Adobe ImageReadyqe<��"iTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c061 64.140949, 2010/12/07-10:57:01        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CS5.1 Windows" xmpMM:InstanceID="xmp.iid:E0CBCE737E7711E1A894F91A1B262053" xmpMM:DocumentID="xmp.did:E0CBCE747E7711E1A894F91A1B262053"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:E0CBCE717E7711E1A894F91A1B262053" stRef:documentID="xmp.did:E0CBCE727E7711E1A894F91A1B262053"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>gaC�OIDATxYPSg>77/)!*R(](L]ietԎiw]RV*XmAJQ;( @B܄ǽ$#g79/'??M	AyXm547w@k::n}:;MkeuαII
    4Pv.QMwH7{{K@5!6"zcO\r,'E[tLp]MSida==A.p"j@
    sUme
    O.ȥ~`2?zxWu*^HSt4x	bɉ?tt{e@ E@e"ĬrZi%[S\/ڻ͠b`#xww:999ӗ7E؉-NA
    eGn(mtfP[{ #֔ߍɄL *y7o/yFZ0Ѐnb0\tm~؈Hݾyde6wnxsXˤODtں{\W`@	@w�;@OAT5ɯ^8δ̎QzVӧZh5|nS-HA1ؓq&FÙ\HEʤչN0J~~-[a-yj]UvtD=!{oM.g͗`^\^v�R[[;5E*؂ejhFʊMSluz۷/==k
    7@0cǶ^*?{8kZ㉀9i6ca<bߑ9j
    LܑO}LؓQD<ʻIGi�u!.G2RRVKy*d%;j|5%ps9mat*iOX1M�ʈ=
    WgnZs!kA?1G;w	!g凵c?{heGEnj~!@0l?0F0(u'S[ef.
    \"mto93,]TΦ̙]ɑ;N\d)~rZ\\Z&<Bsd4!1l~}{Jgnνqٯ/O-))@ LxV@[qfyY\|X;%di+oyuܐݛԍ(\8ͫ1_ORE1ɓ')s/]?<g囬{6mCApSnqe{jU7fO񹇙GALݝ66?@
    k1]3|}Dxn4MhdqȷN</`.PENkWC>ݘw$16`}s71E[4p^h}YI+Ϯ|&on믡x\s#;_ȽÁ+Vo{;֊3/y՞6oMa֬Y8IƆrS{j(@<朗6SJ˵/:�KzmQͳVq8ކy+04g]*M4|<-*As		q(mȹ3gL*((HtDwOd?|oko8r`p1}$v-}Ft!ڵk
    燇[/***//
    EڶD"-}}}P
    hb#mTV;ғ.Z+jG!Wt@,xL[⁵ZG۪"(#`mŊTk;Ѣ"(P	X$$%H hyٷoϿ~'GmsvIC=ŊՐIstb;:ʣDbc.!2b{LZ?BN4DяՔhT3^ª@T(Iu-%*[NLTK2*&,yuulV:>j�]		%Cl`JGiwўo2>�07^�?Ԉ,wBm͋q}CUe%Q;x0)cg)3n+|(w r$1;6A<zV&u|덨`򟷟e;bl]t-JGe\<_g7'!<w	�zjm!f:ݚ_SSǵ0B!WL:L;%b̫en"
    ts
    �bLK5!>=q?}~ 匷ma~c!BiO'R	jDyKokMgcpFA ,Vu,^t1{eíML!͘4<1bz:nH,?Dsq~ĕ7G<UBoY2HT\P-c"N744|en;E3(�\@/QUr=9z;|Z>fuuT#bc䷖
    WK٤S>"EI~9K5n\1_<A	G#J@B}KJ:kjnD-@*?Kt# 8xֶ7#X=Nw`TntPPЩSU"Nų(n<%%Eq5EQC't
    r6	e bz*\]};
    ȟjNKKMs)Þlއ9Iaq'@{>j$AT"j)T=xw	0ݼNӢ:ڌfĉb{|ϐ!a6רmk[KqlAqmB%v6J]ޟWqaI7G?jd45B@rrZLQOrw. $KYijIr 23{#zhJ\666|U;bh	?Ʀw%YF`N.pED')+,4[m`=T
    JqP>7(ZR0SOEʺ29f\}E�߲U(INi}]0B76l豲43!b2Z:jzM[յRo1y7Lَd4c:	9[vy0%B<o@ݨHzWe]_ H&|[[[M!MLtF\_dw;	frMKTź_ʩv	.)J@yl6{?y,:A"%;%ĐllAذƭhll`ͷ7Z0*31gnGK^<kFf5U_'XC
    vvv3WTW0-YStS$3%MJjrvq�G=u>p눘�.7pA
    
    }#G0ا9x],SP45SbbKXJKKӹys
    *N*psqQU{ܙ;+蠲tTD@iRT"T斄\eiZizd"K :ìv3w={F٨#£2ҺZqeF؀?|ȡAmcEiCxڎdkW^``JeZt|wk\>f@cjj~ĆbG_1UU}
    |q4kwXw�Qo'h�4;ǽ*�Qb3F-F2u]d^FD0m*~N-Tt�,ȁv`1PQ��a4P""0;6@6<;"	nɚ5r5@L
    21`�Q`3?
    `9::�4�N%ɀF@
    l٠	0ge
    c4g8w췫Z03g槬};}J0:1ݫ_̰GxnGzM-O%Ъ/^t~JP_/G{MwmQnT0pN_UYAa^\>Y8>zlZw�Qz4
    @3Kuu۞7_-IScaQrRWhD
    `'R@PSFmH$"Wk)FSmmJ<[&s„	<ϲeSS^Iv
    kd25Oj9%e9}xg^gTvjլs3D^}+AKS&OƎ%ܡR][B۰Rsɓ\GGG:<%C^^_yx0~-K,'_[>tjyLe!;WN؍/9dUKȹC)BMJA${VP1 ʑ
    "!f/\kq,rJd3/�ox?8j
    xB
    ء%\~!1!;?,~܆}AAA1y1;|.	L~ULsä`aSm;rb${M
    SG؛)Q?E?ψBBnƌhD�5Ys
    ;z։R/`0222e]PrhF΍/ZP{S
    HMִ_8�j@FJI3?-0 F+XPO"Jk/[{
    (MsY!ݛVk,Qs[!@!TmP\W/zD$%&8^.aOncٵKʲo}7Êt(@۲5w)㈒JR[c|NŒ@~oUкCWl{n
    JW5(sgU[|k峛Ҷ,.9.D�d&r(`R.:L!DvL'"QpO2)3GY͢ⓜҮh 3Bw3B3ÇXu8	I/[	9Ê>/_Szs{N8MVy/{zy 墢B}#hЕ»�iiC6\Iqex2/ ?7'՗9QV"!]5i[BW= lYVJ뭟Q&m:&߲}E~}m>ċ/
    
    w4|#r|=
    nfNhlJ_fIay%v;3D:@D*il0B3aR'{ygLP>u'DiR\\x?n'j%khhA'~̙;w?WeRޭ6Dd[~HM3RpQVh[O7~E.e-ݩhÅ_H];+-}{8m*<dm_₎2elYJԨYdm3`2q7yxҔ3#
    `7<-em\YFu03}ݚIEwl/lNk9C0->8Qk"U#yasD2gΜ2F9׿Gנ7RNny:t=I{ba㕴((6P[|ՑMKͶUvI*A!jtlX,#1JE7t?ߙ(RSw[^w?nnn̏\<<=neji--*#Wq6*3ճI}W-$1֧kNDQ*t%999N8Ab)1sssY(nxs>WH_&(DT*(LZP'}=.=27=$Ɋ)\PXS[~YWWV H[<,UG#\}Sfޑ*ܬI)E7=6ۿŪU?mPù7_6t,vٲ.4ޔ53`HPC<(N)Fމ�dT
    T[3Y9gd*C,c7$g,b{bDLBFy..Eyp~.%$*2PpxiK-le1*
    I-WZ)ioYsd۠j
    /?DD]%+�hmmŬ0a͛ﻎ!Ivvv=cU*Պ+zrm0<<<tHїG#Uj	S<<<(<oػ(-|g/ebԇ"bA&>MGM4)Òb,X0c*ҋeva̼;ݥX0ܙ3ϙsϹs>~#Q~HYYXP0X/Q.뢴l:æBI
    Sq5쒽{Wែ*!1,{OkW?~]|oA$Ym`bb4JI~~[Oм~rY}BtlEna(?x`ecS'bd3Mo�p¸GrƯʉy7j$K9iZ5(֘<u,-deLdiKH^Y3
    ;s8w@v}&lsשG̜e<˫"36o0'no _ҮwY H2\4Ai)}yVM4&yBD+u2Ffhhڎ>CkK%ϧbac)b:_&,/ŧzPS,x2\fR&$z,xyI%6+s#`bB-d=FGx<o	`ףՙ$}r4fkluH=4+$Իr~j*j)F}H)}ɕ΃nԣ+9~{J/Q�
    Ai, z\kBieWYR�%FYY#jqʍrlt C@FRN�r9P[V=I!Tr8/N03
    WD6m7.V{&bqѯ?Vv<u[)(503a԰VJP7ŧNZ\A߷vRd^Ծ)OS{R2q|b2ivoTP1s#I'X5lQi%x	iIF/]hjvkfhKMQE5T4h_l%G
    Ϫc؍1'-̬%R)˚JeƜ^phMraPkBKAl܆1frU۴{]u:r-e2]aW\`CuU}z()$5W=/wO4X?h
    (>3!99[`<X+='WQ(eYu+鴤qZ1k^b7ZDr׮
    Nwo�nqQ\.5FzQV7=Io~iX"3�emikm3ҕc8Oԇe^*/)`"iQSwijm	d-XUܽG ܂Byz_MKkᓙa!z&˻nmZf;][&ㄏ/;k[?i|Y:Bb8v
    �8^5 -4;oA7㚭5A~:K"qsAD'JJJf(2X rCc{g--u2DE¸nm^NJ|>B̢ѩW&�, ��3# A�2֢S݈;Tr-|N,jL.32}
    ߁z	T1*FS=6e@KPV*Vqwc88YxsqQĉ\x(#W	+E<9gaXh}t_0ritB.cYiBɆu}wlib@Vu[n_Vs$\.mlѸ*�h+ZPBB'xϩmh3נAuX+j9	t§֨ZBzNN\Ţ
    z	@ 0xS=| 16mzz6+g23DTj^6f
    Lz=	I0g/FC_rttKSR#j9R1Eē#n\]o?2muA{Yb^Xn+YS`O="bmכß>r3/n}GŐ˧a[v3p|w#J#gP2N>=33ٳ- [[|4%HT
    .EuY1bZWFa@	~=ä)q$]o0a8'uxvʾo\P(
    lN.܆x3S40pZQ.Ml|ky65g?[Fir4%%E
    +WM%}۷@A.\`ǨY<puQWYfK8z@1~>ɠ #"AjgX*Xʙ
    El>U�/+=P*9Y;YSNiu!p-VIShyyypҥ
    sGaKo=3 $Pa~Z"%j}7EBH0֔:&T.xC8)r~Ĥ7q9ٛ=V|ы];'
    %+M*b�&yiݬܿwq[nH<@bzO{U45~U*R<]v;v[$>|;<<0Uox#hቤ
    88|d+&`r1.qJlz._憴[v/RߝVΘ}R!1Ȍ,C&1=:f9ɰ!SAq*[czPRRRhh…kfe`mC}5[z|Hml\nCX
    -[H%*FuY>tCv�aBa@q8JE9ʡJjj2(;_ܯn˘
    (p{ظzXQRu(
    ~B*K�وm$!D3g|𡓓é\)Gȏ_YW(ܕs+X7ͪrdqݰ lgK Qrlo
    @(@~>~irH**S_,
    7es6n"ʔ
    l3sY><#hJ GB^.%0<p
    ևTʣ%jՃP3:usJLՏ}􉊊NEJIZu@U,-}ĀnK<NoU$dsögJ٪%YCy,*.Uۭ[B3}ݺuU\Wmdݩ5RG_MOVb#j\bʿ2klu?q;{Y|0buT!>|ڋ;YtEK#u
    BۋxM_5ܾ|rذaj oYM%eb+3v镖|!KUL:֬3mWן&i$@HVyU!7d83#v(_yFBΌQwњK.Ǐ#Ov*^_$	YY3>G>fŏ2
    "ڤ݉?yiŗV)(_;	<Ŏ{.{>mٲe\.wѢE)Vg$І65՛~(+9)A3u�<ZGŒ$4.ArͶ&Fcb6mzkd^A=~>6'V[5KVE|)=ۜ&p&r!gΜ7>>vb۶mkxLYX}iYƢ(w]/]#"XW^#4]CeeeǏիPm^jooͪ>  |tHT^939]mc}B9^Zߙ_~Gb�ac9d'u'RSS/^Bk+$Q: (9tةsKĢ0'..SCF/t
    :b}XbIoi&uobH!!!cǎA@/_x{;90ⓥ|&S
    6 WTaTFPzI`ΝP;vP?u`G|Afm}'Kj)*Rb.xqa(vfr+++G%
    1ɓ'C###/_,R5DOY6 8>wwI`#ފ x2A	-
    r9h19s@䝖RjFh.qͭK+qs*V"|
    �eO<h(4.@NZ0J!?=̣6}Bk&XM
    z@JS:Vb2S[_&l}
    ۴i%1Pn
    
    0P6
    ((I
    ᖨ!YXS.n*!wٌLʇnē&M;ʵ$[[۸%v8DLtgf#=d:pbf6"GR{fW??|`Hh`J]`<
    e^=8:<yVA7UFUl[MkAJBf=ED1J}D%Z5)~}V"D"';)Fk
    ݼ??;ю'W?rZ4Jkv_aaC[3nt[P?'8խq!e:h٘mZQ<ϝI+S3yɄ3fb9cǪ=e$!e[`[eZmӭ7F4;BQZ 3ͭyneA㲴.\x7harrr
    8':AI:Jݸeyʃ‚tܹ%x
    s5Mu_b
    HjAy,\'VR+i*ɥW@!NDTRϔg]݃佸@P@AgӀebd31363;1e<c6ݭPօ| S?ُ{9)f]Kp$b]^ny
    eC'2/Ž%
    ՝ɛnnP,u%w'e0P;z�5¸WTe\*=pdTʰECJ9uxɐUˑؾ"|ڠ�wcqA+ʙcBz$jTo&dW8|rA+˹s%K=zr}b#jeUd$B~WL:
    s6$a6@ř9{jJGoSbTej4nIL,2MǑiH0WAD5,(9gsՋR|-/^_D	G--R3R*ܐYXr)
    +M8@$#P&Jgp0f|'O|)**N̈́	d*ϢN>G&sM;Л;}?x~|>o{ܹͫs&tKTA^I(\2,,v
    񀀀wm} --M,Wegg6ߥ5^57o=|�J0Add$4͛%Fg^>a|%A뀋{Q ]P+K` XP(5{(n"v,
    (
    Ҥsqno;3Qy鲷ev?o{XnF(Fi:rc) S3�qMXflssD\>_'*.2ݬGm�=1o27YD*H^Z*+++/(il5tx\Q*O{?[{
    B1V^<y͛!*
    7A8fp
    j5PĢܖ�A}	コ-tsrgGwiGMw4n@>o�<_צ
    DZa۶P7B[W۷vAf@=hXB"WOΞCe_[7}ږȾyg4Aj#T3/ t@L҄ρ{y!s0i@jH&ĄaF'#_iQ2~PqY2Sl.J%	E[M+(ذNF(kDTR</q%:f\ˬ6$iigVe]+(,P}0oѽӦM		bEx}ً;2z:rj%A*[1ȠM�]AO0Q>/VxN	B";^ĪO_N&fݸf5@iF] 0mH+Ȓ6A
    E/&@Hzv&b@4q*6xPo}iQoy9SB(>upf|_Pj:G~5Cd*AmyH
    
    U!*P�Q7y~g(rb;"Ņ.X,J*yΦ	�4
    #`(B1
    Eq|@@GiǮ0+ŻMK5{e	P0{9)�M>p+Ex#!cԾFZ}ȸnZ+_w
    &+
    <u2r'Iqέ	1qA5WFܮ�M#0ٶWھ/?ɡCazY/&MZ�B$�m9|㥿DJ(0u煍|Òm%
    .0bn2@)ܲ<!ьa0؂W.�e(OQJ:#dqYERJUld UinN*u
    וa-+*R٩k`|
    {{ZiSU1񽨟mQWcuCQP/ΟՇT
    5捂nݝ[JˉgE)gOKOzul4s/{?PI^K:s޶)OZJ9"Hӧf}G4%0ٹ6m5344li�ϗ<mF(:3*R[[똙Br洋9Hyx!�9w׭[31ˀ{z;]s4zsktw[|Ppi1amd2*%~FS0$&t;@_—fCH*JJZfU-IqNZkFd7lnt~DKL1&#Đ<|U$O}M_d}Q>]<HKOYQ"…/5wԫKKKD)(0hI
    3™Hx5+X<YuQ?uˏ?tӺ(r/M`AA;[("{Z<)G{k31%󠀎V@ώ&Z^v!/V/=u(uZٮòݵǒN,׎?oEԖ|瀎-חI?zrュmS~d[*h>r-LMkNJeIIINnnaa!QnqBPT!r\GkQL~}]E
    P$ZXX(ַeX<wg][OխȊX?:҃לx�}yyEy5jpʦ[ߪV-
    ܀{d2Y>'~Sš5Siivvu9
    
    EFZf(FMuBßʋ
    2yI^ggOXY6254455p8P#ȷ?P43l >tK	�N*iu>kiܴgBjCXW(yC|Ѵ\&:$6G3߻{dAAۈ+g2$M''!AzVV:^Ex	Y+*ڷELX<I0LYoŔlWĨ7C1doAvn;v]N-WEȒ]OxE'M6!t}U--Czu^TܬYṀ<a0t{/G
    [%LZ-}lxa	@fig-ÆbEYBQT'HW"w	X4zFDzBP8Ӝ15c:%<A~^DRvbkֺX:^NVf6RT`B_".ܜTa罰<e%	m!S=7\ޙw=m:
    #f˟k?9hO&,[bB
    App1sBV"SЮ3+?L[	JR̍{Jl޵[:itF~n<V44G~\.xr9Vh;[.{<`0ڿbPc̎S}@L,tpkb	Fs#ju3*dgodr׀vob𷢕?bЁRuDxKL\R'XJع_հ/P円VZ[ZBڨMUDL]U!s-]
    XKǎ}"c\fJU)^=PfՃJFq׷L7Г(nLwL;+ʻc_#�N]
    0sʁ\Zс\
    e6	E*,غKgP&:l!:n~+�&=X4t:cc3'\")v0Vf'&^bD'[�Jz?0CT1?+5t޽FM@24؋n89iPxh$|##uNska`CW'Uf|(WJJJ$ɻpC(hJ⭛^t.1]WWؘf7)Ugi/叉J}y!EKMJuKc6Z>|O߿' Z4//K8賄EAi}Teceeuvvc5.^$՟8ʭuڵirC` q"HP�4K	ט+L
    \d*`Q5Id
    OZtȓ}P�՜hv2Q늡!?µpZ_m5|a>}X,tС˗/o(ENdz'/9gFoV&l|X
    W_^>0Էۂ?WMptFS0Pu
    kW1X*[PH%7nܹ311qcǎݻwCxiz])T-;G!'gcZsR$Z=T$ G�|@P��2]e1�ǿH@&zF@!*I@$
    !e�%2k'+jCk-CC"##!622oolc;O4yg`@e&\!#'}{BO76/tY;&о}[?zh80l666fʪkI^@ZN#Ss<|OǾ^5gw7W
    hʫsЈ2	ƳE>J40n\%@֥%Ȁ]U0-y
    Ul';>6*_U͊tTJj
    p(((y
    \}9G\P�gIn!@\+QiSҫ@jᛒF.QI+N/oYYf.>@&JDI%E*\g/#O&K=ρ4 u@G<s9yɋboҟ,(-/<{
    <8;㤟_p?Rd/Ljdr``222~N2Çyzz>}s,ˡS*ȫ~M}yQ~k昩;*	aY_WOW8@)@*rJ�RrPB#AyIgn_Ä5Tn_yT`Tma֡|©FMx1jg`v]eŘ<{RYWsI*cCK<ڥ{uc
    ;ؚh/K3l(bGPHdN#Oal5phhۚ
    "*Ajٌ�:= l*JR\&U0l7mk9Õ3IKK;<TCn<{i,RvgbnCZ{qYLc9]'6y]ҢEdIi}V>5͛7G׭[Jl?hfP[x�4ituL@\@6v5uRvH]I-ySTDDe8L Git}9d5teok6nܸsΕ߿!)2e
    $ǏH<h$gӷ,oe֭{!5,nͿ4{[Swh=G|HȼѡĔrcFJKcE)vF\#ࠏ1&>1}^JD&yGQGliT
    fZzQY*1#M9Gh7=Gs<R/\i=`dҩ\ia|Cv[w(`P~~�]e*N>2,&,}"P2c;2k΢%2x?r!&pݽ{7$7T(58zU�Ry(i,1swV/zM,@=i۞Kw)?.ڰ|~x%?yrN*qk8$']r,<}A6RE* k[,{̭sC&,;<ِǰM/G_[c'99ÍÇ4h2'^?Rꄴf!
    r%3ȹr	]~Ư�B\"0ۀ<Ͷ3P峳ÆHr<q6IWwi<%+WN +ر@5_Y|o<:I/98W+/^˖-T%\o:+b+5m#Τn6J߹[ع?M\E߽/+]{:YߊVWXNhڵݟw			a;wCSca̟U),1`Q5S_2MR@EIhJkɆ'm
    9iuSg۴ŏP,ܑ|9l~7Q]~Xc̰Mg-}(׏-f{ Q';[qT=z;_tq 2ķR)I'VQBGi4y$K`T.~QT9LӀi
    $UcJLPUjR%DLϩcxc*wh/2%(3$Vb>
    m[Þ]F6o‰Nm7[}ժA>jڱ0fd
    }K9wB
    	$<_Ɂ[ב?}kd2YZÄ-M}t5;JKMshopR:PR~D͸ͭr!��T-Hˍ)/0-[P{X.JO?M`_Ai@ē�e˲~
    ĿH'l
    ҉rx
    ??ݻoܸ^"%'=G|d'>FOOaN=iOߜhkƂhigyۡ|FB!
    E"4B:eʔ'_ׯfcc:N�SXMe˖Kd<e̢*Jg<}Y3(0۶ppgaAuhд[]]o߾ZZ;>wP}uO8-I@n
    ?^mu|7y})"$5F\NXOOOBmXDʼn\0f,ػK58S@F1v^:,5ȑ#!4^ڴiZ~]__UV}E~L8NHx&%"=8|djэB UpEC!ʶMv
    x7/<WcP.8Hz,
    Y폻l@)=~[fK�`=
    @GN]hò-r.*BfݤYUU\UMBB	O:\;C|\8x"Ʉ#aZYX/EXfiEv
    e)(Ëtefn.jcUs^n!=w\H߶m[xx֭[G
    >wxHUM@4˻d}DRBjBDGPE95PjnIy@5@@pY3(~A:x/֮]}}5E7_TN00z'
    ⲔxO%$uɂ+D9d?!L:}\`\xZDZG
    ؈}ڰ(bg%u;NB$[ca}%
    CW0Vy 5Pw?>33S__?>>ҥK_v0
    +ܹ0y*4$'j
    h9P᪉Rh!	g_6!_U8{κ
    a͞F�jHuj~GScw\L`LC–X[4LiV*!ہ:""Cx1PT_<aX;g&v	22~]ѱ&MЈreX$1ά~TPH`h_ Q
    CMjRRVa og`X[[L:E<1ֳ$It]chGKO2vvv/.vƏvIGOj^ٵlȲ3V#aPFYEEVȫj[566Sxg>t{[:h&tjZ
    !ov$~0Ā\u>Dz8:MrQdK=#[J|!il2j\V
    `)_.9ܼ(<=
    GOh(yfi4h"jJgr1LpJp2ǦcFerAbo
    |CtPhL='XTXcRi^^^fFN	j.,y@45UHF)2
    ܶ666wޭEK{l#YO2KC8[ "TǨGm,<2nNޠM3Cc]591EaS^_~sQ@OL}E9l޼yhk623D+zۺwa3
    *їbP%V:5mDOO?]۷oײQBJԀ4T.'QjJ**:+8)TBE*5AW1L*c
    KBQhtB9ƒ6p(kk+k(yKRQ}ö(kη]PM33&4+.ȨY[Nlk6l/5 ~lB:ou1$y{9eoH%.)j)ݯԦh5wF{^(ER	ލ>r?fD~ȵFDbkBT*cv誮D*|xB9X,ˤBGej&ڔMd9,bޞpV
    	=Giqۅ.
    9^1c.c;ǷD4͈3m7`>S'SAe8e30z4bx'Ne[r+ݞ570f	AwHDuuu$E	ft޷v(@>M
    5ލ};Jׯ^hF$w+al!I$&T
    ńBnB&-`۴RlRd	 3ҝRgkLDBjoN`/C",kztR|zN^:cמ'y*Z^-<rH)-<9<xNi7.y{]�5nL+f9.˯ݮѺ0eAAJrdh8liBW^Di?G?;ҦoӔDa>ʼn516Bd~g Wvqq|g[_t
    BCC#"")\}
    mjjɚ".wb:2I=+{W!ࠥT}z4l|(P#BP82WNh|RuPveW.F?<fQKImM	k'GhdKwTαӀ$c䒢?nw==aDsW҄6w:֥k3NcTV>
    )FK&qSS2WV"U<]WsS70n9/Zx
    *\ܩ!SBvuuN,Qd(ZjU2#=m>A./:S$gԀEU@NEDm~oIT-r //
    <::cǎzzzռ,4VX1}/rE###ss(lOxfVzܹs׮]P(ў={&Mdeer[Pbaqqqdd.TxB'**ɩ]v&&&_rF(sVVVpppXX$'BOOϦM~u14;x<^||<yU(,--4F(7J34<8n86&PE(
    |zI#Q]&hoC'�{gwGi(ذn,Qcklލn^b(
    
    Hzީ1Fo77?o{&lV6ILP6ILP6ILP6	&1I(zZK@�֎@J3G8L;|h&gef&EAD�Up9"c,D[\.(Pt:_3_e},|0qog˱b[G4yaF*5gccI)^WQ8v5k
    \ݐW!C)g>gg۶leVcaTqUݏeeiʸBdnꡈإyKj_X}QP*_ˢquLP6zspw͔I[6[Y9iPBX=5.W(32϶N(VRu{@,swNlw_q<̩;%v43#qj5Ū"en.écG²z(Д::&<ٱ([ЊlǻvMn%Z,I]rr@>j9;k݌ /
    7;:҇@Y^$O5l,
    b/񿭶լTW9J)`Ul%bWPUN6݃.W'F/	ߘe#]Zۿ[K4H*b$b]-
    ;#ʈxWF  KỰ%$':CrO/LVѿ'
    Ah-8A?]6\�Mdr�{2\X�0r.tbW0h£(0ِ8u(x*.ݴӍ$VعK҉c	߀~YOi@`~
    \hKRNKRow]ml"WA=7_(
    zUo/vz01EFjܭ3^LY`fJ6*
    7A$s+:SxQt?<CO!.M:Wwif]FM>wm[>C|05.<7E2Ijv]bŅƗZF@H	"[/muZ8nյsWqzr0dr3ZVYvze^Kq~kQ@]Gwy`і, r	~h>p̜t:wj=yY8׫opTayU/C%(HzvhJq+[`Cp]|{u ,B('K01B܁D)X}{mW
    |哐3(SVHYֿc'>+f2?Nd7--Q^=I$<׫4!^-뫎[}AY%]A[jT,.TN2J# !ߟ1
    ԓ} ģg`�svC\\8)n92wd:mF}j1S,>Pt*(EJKKk>E{,ɽpkp ]HA6=9R[uk6@j)4x'2&pc=6m_?
    *A	K_^>:!,<=Q.VYR.t<&uR(	T-z4vY=}}Ӱlú&?8k10vɡ
    $hErU[mY>Q"x0nctlWF)S7Y87Asz^rdHX= Fdy_b<\"-A #)\fonasGqabyޏ21M5<>u;#Ȗt"@ס3G"NxCd
    U7ґ.<pGFNZ8_y)uIsgū=>b(^T Z}F&Eez$m.Rz$	pڱqÞm�Nr8G}D<nO3vo:o[k8bzJ3vomO޵VjU8IIdb�	Q&K="	flt}TOirb-~Cܼ|Rzwdg7n5iҽUG0&p,dNsj9Ԧ>b/i&v�|Jh>-4	bceP9ȥB(�
    /P:�~d�JYso՛-|uP
    `ft
    r韃'`R'=ω{Tg FWoF eF~՝N<+�O'J$bXB.	DYPP{9|.޹ݹ0A@3bq!>GG\,.~*.u:HZslg|ڶwQ8Dݦ	Vc.0877}2YrS&XJtgg\
    {iE$8EQz$Ru릦e+O_gggU:;wiJvʊ|
    )IECZ6Wڇ625=$TU`RU|ĉjM;[qΞK)=)V*;G.?ͪfun@[q]VǀVa6L&KIN|Od}9:Do YĻ2,#/^XUϏy|yhIVah^]i&
    ~RkRC<Ǖgcz8P=vIz]yHa[#j|]�Ru^4;1'pKK/@(27
    l6LZ=
    (�;E@	;ry:Ԫ]EBiT,}*DouqhT`P\dXJʞkl;锾^@\hǵT>;a�Pi/JYc7=Y P
    3/;K%ܐz|j9*vmkf\Yf6pgj&M$^pO]r3bjM}	Sp黷9
    )8Au}{AC%$Sef3K{LXupQN7[} $QN\۫[0o(l]l+I=qZ
    %`$bbzuUNr{K	:=ym]:.l۾C\H}˜d}/zeMOpe`6]H[=zԄOKVɐ_M嘗)97U=5y4|?wP,)!_w#:؂\PH@0uK֢@ÍgH�r�+Q>z?}ʰIPC6=K|nD̸䬬)f#lmBPOJ0߷/*qκ'ёO/?ia{DܡDž9CFQϊ;ǎuc2rĠQI5 ]ٷv鄳~@q{_F^Yv"
    ,b$Z9Q=vbwwqju^UTD$G7
    .)+̧]{Ժ ð{Oue Ϟy0kt݃K
    wlas~{f\P* ᫗X#;MxfzNoI׮lŸ(ȉs@Is32E"engGOtj2$? 5U&ymmm!NA
    	5+?obocHgdddX޺-Dy<ZI^ܬQN5+O }0\
    r8&
    E&e<P(a$|	cj/|.L:G!@_ncqV
    x~mx߯31Q!>1rR*l]pn83(H(ggkmQ,LzYZu빸0i7@|]rØLI;L~(6^,m
    {/0QH*,J@^RSE݂:`{h}WORҳoh)5'agVޯak&w�,zǧU_|�udz2w7LR*:˧jT!7˔~~!5Izp_s/dU~CG!
    3.6FV(c;tjgggX,u)XJ2Vg*W)%ԽۅsR{LnȦT{+N޳f\w#7nZ
    o]<YJe^҆wkE;4qFwveb@^~`^}G&}tp%1
    IQBVm?[+rCHddS~uk_4CRomTtn.v'i'4wt`-)oыd99Zf-˶`[א5e.% E0zCXGQxSV];ok65	pre#}3wd\z>'vc
    i)KBӖ$uTGgY:,[oԮ|yh=
    #2`\lcڲZY+"Y}-PbS b&QEk_$A:-_gBD>ooo/vu*2.'JK*Fҳ:>`ZxV qP~+3�E!g0Z R)2PHeJWjN;
    Swvl�-Ȁ^hMhITߡTn#wvw WRz
    NK@%S8LZ]~VmtoQ['֨lNa\PB,
    չFQCͨu:c{#y
    ~4*@\b5B һ<+r`j(-`Eb�(*cqPG:KZAgp\DBH_FI/P�z4AUS/s0|ۖ
    `OHuRƍ^SAlOfZ0:Ih+ymn~zE"~0a]0֦r2NՁ
    \W%:Ibñ0l?;-I0p}AӀ2ǥ>yT-[W~߈kȚ	4ʸC'R23<5b&@#GvvƴoW+3W>~ƭj$R=Iå=t^ 7 TZ}F!5Z,i@n䞵^)buj.$ؓ	�A32:52ŋB@/22)إbXZfL.�E"~ڜ=Pq]	?UOy5jztJ`[[+L8lPF>ĉn~>>?}#jgc{Y[ژ39ޫOLjղ٠b,GCfXSmY&jj	mZxݝEʱvڷ󳳳c~׾](#Vҡ޷Q$P(UJ^RzN'j� __pxݺ#Ľs?wG'(Iu<~m>;LvhI*(Հ"JuRĄY(gYE
    nAsD-PZ}c==no	ԉ߿RbɃjv}CW<8ĉᷳd\0{>6Xz6\O#Z)L
    #33JY9=/?馍M6y	
    ?9/V|}+Ìr333BaBR%33no>dՅkh)W꽹
    z6)cc㜜ml*	7
    U@L#|gݝt~^;v|hQgOGz<ƲHaiiYI²M`J:X,~u`e=+_oR7Z*XT$gC|> ٷocSHLR9lq)4tŎ?4kιIIwBB *ca*ott۷njS	.uW/:Ϸ$5tQ(Rib#au1,݄M}M= 2e޽{+2*08c/Y~k4!�c[u~`)`DG*KUw[;ǕY ZR*/J.[!r0	2	A-P)UQaniei@I#•?vh^QȏJ
    vdY(mnf@'XZM0ԇ_ѾQN"H^-Fr,+tODWe
    	v+9쩨W/$[
    ͉Jz(l2Tgq'ޫ~-e?os+ܢ,2la)?n^qBv'{޳=g]&HsI^@F,]Ǘs{nO^'''^]'MZq''+\Uy]UɅW9Իs\v.za?fNO97ߺdޢ*	CrC}Fʨ
    pʑdMdݾ,}EI9zX("{{踸C&$$4kyԩ(++l
    ?(�?־\َڴY>>L"jt2IˎJTF\^֓,-tXmVRa[63!W$�~_ۈ2;Jo^cbb?~UvyVVV_\3)-a'<}RYׇ*B)yҲr=T(	dm
    U@*X[|QC
    V6@%�iͳ$o-dcN;fe\o:OD޿"hڴiM4"9WM!ˌ$Bs/$"5Z/3rBCg=Y7?+wqرׯ>gϞaaaw=-*ΩD	cBS{裏S'Tw(lP'}"(1P~_(&`6f׮]_?%$iE@i6{ƶ
    Q_9`W_e^\
    E{17ۡE捺7oܧ}ͧ]^~U3l
    )H.5"%̪͙,ΠwMNYLH26DI㎯jWz(4v(زv3>@y 9Fs;򉯯sss۵k_IޙV#D)L`u
    #vzkVK;
    xq]d|^q:Jfy>[ec9 :u8&^\tS)eiio^kk4Zb]tB^͕Ȳy`"rv!h&v`ab9d-E(u	@/R-N5,jGs$i*)|/t"QI+NXk(&
    91^Nz0:V
    [4[&4ũ1`l *.hq.z/&NW,Pk�G>n}yF8AKBSVCFEEt}^2+WT!(m禮Z[|wxX<Qb߮nu5aîg.s{5V&ɳ1_5|Ȉ̸HꀖAi̝>n\ш';hL75�'fVeo̺>>["t4eR#]vvYϠJkݺ1WqJ�2b7ffР[÷)
    13[GW@OIieT6ú4ApX~\O~Ҥ'Nݦc\}[$)zwֵO6̙\k߰&5܃jr1+;H^N>
    ֜9s<yVv'}Wrcn<p퇮rh{ZoX*ClX/
    QR\gwV&I$5n\wP^%ūT8M9BTlW[◶5-M;е$Kyy8U!U�\k)P/]w1)r"uZ_Gi!_@0^Np.@Ҫ@�9i<(\1j^
    (Zh0a_a&%͚xR}I1oe~szZZ.3_:99b	u6iڴ)$e{)8tVР)5`dPѳb�EC	r EJuo@_
    ^>u`a	pzosBƢOk}^l*Kr.3טݺCn%z+dcA+ĄlĬ@n+(IYX1Y9
    ^Mf.ɾPcI;	.Ĩ=O|<�Aa5dԣ<T 
    h8{tZū{k޷UsoYeɓ}m[X?,>뱤;ַKj\;D~##BqǎgϞڵk=~I_fܿ|vf'
    ԵfR~P<WZrz<ξ<_MnnEKRȰV
    vXXجY7*>#zf:25rje䍭07n̜HU*XXX6rh/N0aÆ
    !!!۶mKMM/O/Lbi�cfR{uN&x@x6zFPZGFAbj}O9B;�Kڛ
    X/yftL/5@M	XbţG={ٳtr`^OW76eT9?.Loέ{,9Ɯ<<G
    pBVXWlz2#4>,?::ˏsЦp. l4.`?IÙl:S�a]xf߇6eY
    n.vW9e
    _z5˯u<Nxrfg?eoG+taXݺuS\\|5j\[�8Rt|tWkVw:O`eZ
    ju,+
    6O浕FfU(HPӮEճZKf�k4Y.M64ȖGz
    }..89Va_U#f>{(dQגw(fr�^։nǺL]L'vT�F+uKy_+l%,;h?0$e[eXe{xŃ{L`342hy+b7h6c򸬔wEp,XVD63kw7oLLJۺA,dޟ}bΜ	xxxƬۗ	T-`Nz=`ݟ]\j?~[ܕ#ߛ:yS'uwnOXa1${Ǜ:h2#/thg?
    xns}NE0dW'}x93>;e}o@L>((hepPhwɂ^vt Ba)߲<<}Qf5Qqu[]լziqT\xh5(<K:t4k4vYG_(&ֵi'}7P~Ã!-g-#ro;sq;jx{)TdipDPŏ)	@͒w۹څAv:yK`Fbܵnm7iGj�n>ݱfev�GӜm}SCn:=Ity,Nj6i4wܮ]֩S'**4Ce�P:5a<wA-k,LxXHqnyt9yWrV;c
    $tsbWw/=gc$wfk':<f*GRc$ۛbq兲t⃜CKt4LG
    +n
    C]4-6-0ӯ\(@_/2$&>0}}ț%AQ-SPn<�gԸG?7qDh,^xРAu(3Зpc2\71^!J'V�4~a՝j?ˁ>&7#+۾q/3K>4eGO}=B
    CzUyDU›?E\fMNNH$2dZH83nBއr\gn^W{P+$Q+c|P6z0C
    ma.N\=grss7ohvQzk),kK@S(2BețƳPjA1{zVS8K\٦=dqeӳV21Nڴi~mLIÉ	Z�ˬ>Q')B*j}(e2-[=f+Nvm[%Moh嵝Zx|+&n9k.VlVkAm0ftW_<\]٭W_~wp/9^̳THߡ۱}U(+A.7ɓ':u4v/8":=}~Z
    "
    Ue055e@U,LK	R%Ɉev^V&^=lnT+	8571QAjV1zTKʁe]ڙV1pGfc^uDYfAݻZj%i)ѿ5*M"?]HP(Rޙ@YCE:Z'/,N,˲sd&eh*5d[MzcΗƙq=Y=WmN
    R8yW]ok=6i
    [rlKu ̉:,_3UZ[#((_Y>777n$	YGݺu7oܿru~SQ@y(NXQYMM>3$)քiQf6Hs-1f	cٙF''HЪ4RZPȕbx޶
    <EKN
    ź8R6Lde\ٓLfIk:dM`VǷ<<ɓn.W/°>B;d$3lD\i-U4S[?qرcu}7O^PPs);p{;+?	$əEq98r`^_AyGC9E	nض.!B?3^I	Zmʳ۴Z^.'VpnjΧ|9q׮`gozrrarrr9볲1x)oٸToq\
    |B(Ǧ+P$<oz,;=ВNd+-Gyq]YXX(.$V[@Z\r	$SG/e舞~^~9sٳgɒ%F"9fs$˶յrc'EQū@oMb(3h5>9{^^^zJrR^Z^v
    rú"p-<S!C3~*WPs=\+<١CO޴iM67r\Р,RP	cɡ Om%`
    MQt¹`.N7ѬP(d2TEdE]<W\zjh܇Xre-**l0fffPx|ƙYFvFUq\Yp85U%%U:ɣK5zZ
    $c#F9sܹsoκ4J7o/_
    /ûX,5kPF*Ğ$5xyz~҆U*nIU56/)&U
    fUXt;v@Yrt%f~SNUR|U`Dzߞy+2@R쪰dA<qkLܶUi][3�YTqkOCٺuk޽KرcO<yĉЯ**3+[պ
    "p-Vy'z?^
    4G!=0eHO
    |aJNj/LS$Wu`<ϣذ}yoKJbr-nCѕ+W!-_>>>~ժU5kZBx<7W_ǥT^HGK
    QWZ|mkm.y@$ueS֭k٢�O*@OAjUKo{b" |Ubwi<l	EBЪm?X֧c,oRR1.G9mw޸q|}}
    4s~�elm{+/ôCh3C~6"
    x0dX3`NYW	,ھ n]㾅]m2PO2rZ
    ӻ2Z |4.ސ+(g5jM05dc)
    lȆ!eLIIٰaC<h=zhLLĉ6lOL٠LqQ;+Y0lU<< E~;^m^"إ04_R'f!Ew囻
    Px؊
    NU8w0Ws7^Hk h)
    *UZzGց^o֬Y.]Ο?sΊu@	fh8Z& >
    ^RFWȏ?^
    =rcԞ6k?o~,iaԇjFTZ	*s~aĈ=ZYyCry=`ٻw	ʰ00YK+qsPQL9U1(ˆ9:x[)Fg͚m6?!55k׮OoI>Ihm8U<%z)'BxJi0)ug!5Qi!)ǏkJLhof.]m~PTTԦM++cǎAbeqeF1pJSꍍ<<u"fga#Z vvcapBz:bf,!թI5в]?c4i9/^8"6oܤIpY1PzZ;5OMde-P�	KuM8=v
    J|˶N%MYA;laF3-EV[~4lI62`yV%Fz8E?װa*􄀞9sț<PhTf|QYI)^yr딋6OU(G:11=(3"-9ej̚E|V'bAY,\6nh7vv\ynW-p[wX<^(0WxƌM<zG-
    AL_yY7I A1a?Oy$
    nDuuNh2ߐ£ϸ 8BH"mf=UN);0N7Zz)EC;ib>|طo_6!<fIC}b9ʝy|}qAX;;W+{g()�4Q`QS<+PĦ
    {G-lEE"QX͔5B}e;כx_Kj+V|yeXR\,Q8YUu9.\0r_~e&`vrle6Ua+.-;k/cuɁVVVV2aT~e 3s#Ӷ4nԑ /re,%^PEb,s65:im&~a&$$|E)2̃޸qc7Vv<]k|Kxv3_k:آJRj(!�9�j,@;u-6?i3(~]#?j
    2S,h46l3cƌ4M"WwLJE"K@.O{t~.Vׯ
    }KrzڋiGL1=gkw<aM3	aI>ftx~KypcOX7ekkkR	%/F	dUc#a67aWKgߌ(pkV\oQ030¶ kdž~w/"ڞB
    3eΌ.hٰ1h4%M0PϜ"qast?TfO*S<Ɋ9%Dfk}CP@hHnafW u5nGPmBoI:`~{A?oDboශǜ;]5$0)[+#FuV#M=ȏ.}ΙRO,PW52z_ڶ('h"ZZ	͹a}u|B,772oƁ̭p'nP[K߯09"pm.#
    tܤyWª|"(4,h$iΝy<9@�p(\096J0^W^u_N:^gffb)L]V\3o٤ϯ$YrşcN^.`~r}dgQіohsĬܟhbnm5%ش+us}4,[lԩ0V?ёfRCtn5KoYEj
    oZ+3D̀%2RZRcPW`qJmƺX.}ٮg.1vمaQ
    ,qvqcl{8myز<eda-f6
    lƩoo9rU'P%l	aTBlD7k{]#{T\S;Z;f*-	5.[wI
    xX7Ww	\k(C;rR;\#޺YO<}{]A]լ۹,muB,O>\ߪب	:m|Z-@?U,͞?u@lq0 ِH$9999E;?;Ig5>c#EmE"kyLo#�Z"l!10-pL\Ӽ�ao	b
    crXp@)aH	`LN V)G:sj+W~-o>/1/'07Ɵgؿd,F$+^k4i_ښa?BQڗ(zRo}K\z5lEUATTmMF9ÁI^TXT(΋,L1\l݂>.$x̴."&B`h+ "v}İe3C4">+q1$bHN~9IPC[YYA8:j
    EqD"KolجQCCOZ_ɕř)YB)Sc	~t¾axU_*@	Z^_[y:L;,.d'\,!Rul%{X^Ib\_ZK=\e皊[\ޠ8D"Ȥryb"@oiAVw$:=rhu,OŤVRzr,ͪ:Yqn_P3/=Pϝ6?Jw:/^t}e0'fA޵>ljsTĮE#۱C{~8ƺs*Y>f1OjԾ-]G7dOZ{\\7qSԹwu}UFScWnr|3]3|b'*>;
    pMP:&4a&feXqbs.3<#v_vTwX UM*E牦Gp4
    rRZMԫ]1Ot}nxZ}硂5G@
    m[~?mmOFZ3lY3y^2uftl3}Kvi̬Pnd{6O?׷qFxxm	6)d)ӷ	71mm-^TxRZFNTsMe'k1)L Fq6 }P(hiW!1T3P6w^kUU:*`q8$3‚䎽ӱhwZ6s/v{р52
    Ndžx9بI&Ng#j˶˺[qexZݙ/f-BG'G- c%'I֬jǯF͒HJa`gGwAzM*̈́_LB+z%^M]8܈G!Sv^&X4\E:9:U9~ĠB5c\ڝXT9~`z`9bTSI``LdD-[ysr
    ޾tB1_C|pO!JV'mOO<X[:؊ll:Ԭʳ@v+5%*6޲e˔)S)r)?ߦ|>dҴSmT幣`fVAMS'rT	yE)~)3,Nf2t$@i6UojF98.hkkk:Nk I2x\&ilh Le<6,gra>]HG&#óC
    ]EO qdr>ϓYֶެù7><<`|B}.s/elڬf^&m} }M@CmK;߹SZz̭:w%[%Ԃqnw6`&֫-p܁?vj-[ur7+~~;zo1kc2E!9i^,tj\~w+VʤcgMpk6.X<ڃ\(yW5KG6'WĊ3?#yݎ_=0,}SlV(Sґ(6lיuߺfa:N'~5vG	V6Ipe)TM;L1dƭdz<YA	\_W'UJFX˿zV=V~zZv:*b:_׋,{N	mZtrS:.wW~M	qK@IڲB4*WPPPJgdrJ.mpL08fB3ᚓ)+*\5($d̈́/'ؔVa%@Z[3P\Xy
    l"p%o)ybED={L<{tƙrij
    e4
    
    ^SIiUayP*ձNAcER\HAlW'+&gIJeڵZyСe
    H'!ɹ|)>onnn".95U,XחvD"uVf;g*y+R&33ҥK۷/
    49Ϝ9ӯ_?PE&BC\s\F+0(%k LԵ[-ݻwO0
    M~OKMٳbo.ڴiӸq\]]JKWMP1
    3̙wjŋ?"re2Yrr֭[_/\pٲe&r%~(*7n_}<|'''zڐ	&(WrB$խ[7::[
    qeX{k"&)h4#F,X�7N:͍i±	_ob
    H'omm7A0ܹlmm+M^q\"Ph±	_=�қ
    4JlMbMb
    uGQtv$!�)z ]Io*!RDPD)J(4]zj 	!]mf""Ru͛DOQDE"(,("("("("(,("?SYI=qфv:-[Y\!J z|(odR2*8XswsrB5y.| Dx #j"ĉ򒉐߇e)ŖmqÑ8<\j5�E{O9
    y{j5驎քZ-a�k3b)ܻQe>2JK(J(B.TߓNje[A13tG|RWKl.ڻq68XThpS(L&,d$
    !pVm)VDӲW$ ľ!(<tpUGfbX(wJ>ntCQd^㾾(]lu"vԼCA<qә@3pࠃap~O__H,S$IC-'۝EEQRэwH_e89.W
    V,'.vv-{D{Ոjp:C	m8HpO
    E=?Dڧ~'\=2=##q-=cEP?4ML7ʎ_S5*CMA1 Eq\]Ppٻ"ka~8Y-9\[Q!i42YpڪU1^X0D(?KCpQ1ʢ˄⣇R]Dw|?�Oòsg8U	SW�u!<f.j!!֬,;T\NǛ3h0}BVeQ^>݂f6y^UcQ
    8IsϺ*!4E
    6MW&	`R/+5ge_w:NժEy	ؒw{j߰pIEy@{(:<I9l5*[QeQ^D8(*k*oF݃Pkހz:VB~sϼsb'l)J]}6Vb>`�/9s4gouO\|"BXrLoJ఻rA޷xWn{k{ws^�d䏟Lj1}޳rLW;׶y{Zo$DR>/sFLq^H2ԉ;Ľ)ߤoް⃱{
    Z
    ҷzF?PX0&x(In߰aoNzm7^rYq>]^0r%p5ppN~ssqG(pGiOXP'嘵PZY/�vZZNX^7δ6_jxH;/|74l1;oւ;N?DB
    FXeo+rʚȉJ(T^1>}tҲ7:Zt|fԛg8pṩe̟Yzۥ6v1cG_^oH5=j )_pcb^"ˀ"(AAMgŅ�Q2(4`Xԡ
    3&c
    ]inD^8tly~͏YzJ~+Xyc`i,j*E+۽#N(>A^)zھGG羅vwmڷA>	.?g)JpC;S_a![fq"8J:*V=Ѱ^MnӬoz ٗc8SXD/%JEiQUahٖorr#?O
    ZQFza3س�f1J2;(BITcʔ[*P�!L:H$jǨ\@TEP<*[+:FZ`<<P<m1qN	^մdez<e1m_�^LR#hJG5p6.
    
    l[U(?eYeQ=k8~=]wQT.|
    @	w;YCM{Oرb='9r#9mH霼\}pq+ʢ<YcY٭eKtzOĄ ɧ<8@QZj4u@O|ۻ lYgτAEXAY'('L_𹯟WժIRPrOx	"}?X*/kJFS!
    (sѩy%{RF,Y\^˽|Uޙ1{mb('MٹwXO٣*9I˱q80ECG^=^D!B߿so+:#5 avk[;-P[jgove)kѣ	<e<{)k$oÁMsX1J�53^i3"*M>W}ik^'ϜK̝qFt|NG'
    qR.\vaĔN}WP ,{^}$Jԕo[4k˜ob]nJxky[ϔvZ`- %y޺i$6^kpd~;hB%6w5\?-㫷4_ :mMަy)o7Zs;\*ua8wh`Z7!`)CeQɂ4m++	&gBAO0N 64)ܝ"|˸tl׻'^oy%XˍNݱy+GWa-u7.9*0F_'2w~K?-ڎ#uay!B	n~tj%W鱟%]>>YS[3	CGsΣakOPf)[؀IsVxO2f,U|o._x".bu"tՉ5G>ISnPpP6\ݴ= }YގZd-If Yh5MKM*qCQEP&
    Zrb <\&Nt
    ^cxgoqI7)Uf#A*@IfmiriΜٵ=M3NeEnpN'vLN`8N�.eޕT8l4+os͘4l1;9i70�^"G	Fp;yE1 ?\ MG%tvyP6<p
    H898iEH$pa�aI'PמT`@bg
    pPv;P\__g%MiǎzE%(`{Kx0X;�kxVkՠBX{i,gZy$CS&7h>̖	^]diG|%/aLN8)7OqW\qsr55RBQԥLQ;䒽kwS*j`~r!¦c)oD"z"풽Nͪ>TKWU$sWv6N�[ieQU#ԭSwU43@`lj*Z8?4nIzk\43ViA&SKJl
    g+xRfOjʢ<\(j@x.yFEFF	#K%(j+9Gv<y%ՠ)0PcΑ-g`_ ^s/u8&cdmh(D'ƠQgkyt:T*"ʢ<!;idlbj:u7V@0[
    
    pdr\
    N{V.88zOpT"f1)kIIP$1ӝy@*%
    3O-WHS|}}4
    AhAYRqPXI+u݁
    IX"<"@MLPN
    J`h/ەHLEWTW_<*kvqkvS'	]Uz*J&Ḹ2ew/.]h2~[!=PBKHU#tpɔ%!!H-b.2	 ȅ&q9D\MFEdʜ6m쐷wF.@{럈
    @"2r6
    hԧ
    m5ozr1Y3~E*ź06c23J{l5,(Hj5RcB!HD#sҴE;vxGE4h*,
    ?0Y!n-e7ou[
    y`\F{TNR2?!t<_MTN,.qԓ8cGKB}Ft0cHê.n_ei3M0E$ͻ\\wg:erftVS_r}yk)L}^oBG6fQgE)!}HhٍtVGmIHpB
    @Qe4MT|P$QV)T
    1n,/(.lް+v08σt-7oQGJϦ$Iq>iTqD!g{y&'w`ˀ 3Yj9[=4CKڪށ&�M*>|=xW_v-kL?UWq2xg0EtxSV%,`hhrcO3^5_܆b9	Adnea"1 0LJ!J!J]OCq01
    5kJd`>&B?$0@PncZ]hPjs
    j~泶x�B08?6`wT
    4RH1`�9�V9PbdٝP
    7(Pi�c4&?gjS?旋G
    gp׆G{5ae^;~‘6aKFiķCzk?zgͨ&$
    <DelB:U15S^kt`T!Z$VMLNUo
    N",/MH#WqQ)u{fq%B/~6exY9eDMCk+%̶k6~L5ݻ_~0&o+lPv*]a6[1L<aA48-9Vߐ"wN͒4oI]MjgznoN\=M?}t7deg6o}Y䉚]FOܷiP^�s:,9Zٌ
    `0gd΅P)1Q$(JC	εJ wوi;ܣ8P*(q9#pv
    ,
    h��v|[@) N+/;
    
    Ο9M7kXNP(܆sLYXgCD1oOmmhg07)pwn*|Fjs,`h/
    u&X}R+>x}	8D*
    q3eMu
    h;c(\Y1E-d›Ln˱ouzc6Y9Wf͝f]M	&`}qpBId2YEI.joc4^).ǎi2U8U2TBNq5e֜˟Q'%mw
    ԫ`40+i=iV؆#W~e}&eJn4%%{v[$Dh/8S!ؽr	KL^Yh1htݏm9Ag~FU74
    z,ucɰ.}uM (uhb�6L6
    6mC}=W]}a6gs#tk׭KQ_H8}qSc^?0
    
    "-[;y#B$PU*^^^bZfYRv2[^
    x	lBA{1c6zKXu@�NH	'+]a=o8Mle99YAe5jxNZJW4v{aNNٜɓG9lf"@SXH\_MpcX'0]|
    *5
    u%]ohwު}cG&c;%ؔu
    !Ы]l@2�!VL٬];xB
    6n8.?jm8~LLƏ{~ɹ#K c!Fo\	8bF޸yVoq.w`vUOȿp3޾}] MP[@Mh=&}=A|Rl.(0ÿ6D|�F&թβRqq
    NV<Zt:b\"z?E:Y%$.P^snԾ7
    ;o[h.iJCHTpn
    4=#aY'Oȵ~Q:hpgִ'r""LPAɐo2%E"V+Fӂa	KI$	ٵyɜJq-"L"D!*\wD /-$DK<rq`ń4ҏ2j?I
    j^j]%e4T>ST>~2N$Ҋrh$|,3rȺAA))B)8>_gXvlcXN]"<<4D"[pk!pbJ9w,7q.$n5	7=΃B]te
    Q4aT=BZw{\W\9Rvl܍o~hW@e_޾Fa
    7իIRT6IF#k9]b&EN'J:!2Rnt-i:&لbT.G	r/okXRDp(&t^?CAQQ
    iUr믽$Y&5l\]=K|wǽnrk"(5*?4s+.qVFXv,ep�;nn>,8v#%Ei5W]őwfJ}2gb|\XOOqeDVQl~2iӮIrW\<?8xa[422j%eu;.W#s@u6<!ё�3
    YT�Hc=!4/Uݴh}KϜ""b+yGcW<IhW*ZH#nB*z۾8ww!m-@c6ըpwVἑjT;pw/<_bdLQ%zz!OWQȣݾwIA 8vIXnh&*WiVjHaS
    cw1Gg`-C0viwh)^azDz}}Rj;
    moV�q
    Gb{D#U'u:J%W_Ņwi1Rpe'G9%>o]tHA!?5~쀠GNE}xos7w?/"W,xGÞ_2zFa>츹_5sQO+in{:7EfsQK;mhFk2iqTƯ
    rû
    [CD.9~	[O?,bRI'!!	(ǹulDÑGM"`@)JβjR<8!83tc7O#Fp8^xtL q_LBbqk(|e<*qkXLƄ-ӌN<J5:ɉXQ=uN٩#"LMRu
    ͤn2mEyIq9(4@jP&7..ge.*%
    _90j UDq?,_8P�{Cvaxjb_ͦ
    ߅d/r:M,I$l% $e5H݁?%2T4ٺ.q;)sQtC3,l!pǤ2aU`˦+#vn[WX)?\
    d(L,V
    �ڝ^+Is 45cj(<	@1Ru$jcj^-ej^7;y=lLAؖ+pڛ5M|4\+1T3hEq3ޝQfkk0O
    †lMp8Mzu]zlBduƎh5mLܻaBrLIsikWGHtj}S^ȇm:nQa˶T)hoVh9W냃+(R\~,(ȿJGQM+w-(:]r;hYF|t&36oEE$j{wz`5xXh<%�r{	50KaA^z\[l^⢲lANK{#v{HW)#(Bu)g7�nv9A3*+˨֔HJբvgdAZ r#O|�&
    	�nIȿzb
    IS|NβsiWlPOc4޶Z!}!Gkj.+i5QDPTL(@Q?wnjpwm�]KՖoڀB[]V<uB5WW?Rȵ�q:xW4fCQԤau{~Է"?bs2JӪ>}}j۶^>IԨ
    Njf$("(vζ@>fFTWfXcye�*eM9^O┬c1Dr۹-k9q-PZ}`jUYޙ2_bURޠhafݓnu䎋Sl,{I˛}*
    t\s&r/[4Hm7*.xpMvٮKuU1BҶex܎jR;n[+Mׯ_pݺ&("(?LqmIV2{
    _}{p*1f+ֲ18X!H#X@WšG5v4a/MbAֵ#?Y3Ÿ}_-^޻uXg9 (:|W3.cAfN2(&UNnfP\uid|зw$v"S˄K}}}sssrR[FQ5xzgQL*Xqѵ|c*9vt<M:HN@gYAe|0›u+,sYx9l6D۬o
    @�!cdRs|{E&X_zXѪUASϗ4(<}ׇ&q@_MG^>3z	F2aIȑl9-%+v[ޭ[6OQTv)NѠAcǎ]vjժb"p#I`9|XltֿY`\RK9\8\y!IvҮTXFC%BN )9;g0"Q1~B(#OS_;%	6Gd^pRBbyɽw#E/%n:uPyPm6jԨyuEl
    QDyTvW+^ɹJU		
    =i;@h?�;pG}B#ylֳcJ	5o`/{HlyϟeZR1EDvK͚5ǥKDPEPpJKKrs/(P81&JL|2U4ML/8X9$vwP+gBs4h ػ-[)6("S~dq-θciZ/P͖GR׵?dx@\\>VNh8N-7ϟVQj	W{N?LABᒠʊZIJNh4J6Ayw6KRRʕ+srrDPEw/4Be6xf3ԇ=͹Wn(Q]٠_X鎟p7H{>ZZ~}׮][1U^Bg>;1!`p7Iz}ǩ}=X=&Vu7^p)u=<<<t:+M7QWJ@@@jN8+Dk,6'E9%#Iz
    4?rQRA]08d߁}h:F
    aSe1L
    tzVP(Ĕ>	?sLyy P5,	EyfEj5RJ3l+ι+TJesZFF"߬8eNZ5ֽV(J֭3"(\v'ٗ	QPk\sʯAxMh;J	)&Qf}mLc9@M! aXax	T'p~pW-:u*ɈD8w4]pF4h
    Nw&ZcRjʕ+>|8::Zl9MڊS_.tz4j21	jU8s9e5w;gY%z_yͳ-&X2ܓȂc$0Y$ j۵ѭ[b.�Ӂ)Mj�jδTѴk&^߰eH-gў
    w+<̛j:   ,$RfhӦWl٪Ҁ	5cCCC | aaa'NPݏž凐97ŀb<!e__*/rKzZsS|ɐaowן\ݳV2�*tf2ƿ3l@7zos2-!v~=_	>G!Ϝޫ*bamJURW5aO"ާ݇
    *;VX-F|-VyT\ƟK/r[3 joصǏ]lXK pC}QFuWV/={$)gFqKsR3:KM%cƭbTE+o
    S~޽{^
    %mvv?XE^5,tcѫ)(}^X~{kFWtMoܴ/|ڇU{b`5&s~|:U0Njz[!msV'VK:f(c_[rfrZz9t/^hPwVfȈk׆H-H^yׯ_|իk׮)2
    0,vD2 TfV3c8	ࣕKt,NWnwHhH7CMPyc}AJ>}"i:xBqO`cf~]z8fDXb99- i7(G+"|dh1WaNu}%cW)MsxԄWu!cz4@a#p'}@qI;i%ޠHlߐ	>:S~L?d:㋊SSS>|A	5שSl$)jb
    T+\#җgەr-
    ,BKS}y)e�<EqT(ʌ^{Q7~/O+G-?yRW�oRwfM^Y`}IeHnnѣG;^VVVRRj7RCߩrĥ>ysKFćHT>Pn4eeT䠸;.kGeAAA=\;~SΟ?k׮TwKm�`ko;|[1B=iS6 Ák0?/L4j0FuMQ/J)!:J)@89
    P
    Ud71
    o
    ؽ΀'*%SiճWQ	hp0Y8P*iN`?OyFp[whR\R`3%_ʻVsr͚5{7/_Jdffʕ+,Ĉ5kB@_xŋe3cCeJa-'
     rP|a0oH?\Iei(h%9܅np̆r ep'r;_2M&
    1*\cv&+T.Т@&„u.=W~Y۲O>O.JR!Ν?~&ȐOS/5oh˚1i2^,In1 OcFE>ueϖU۷}_vN~Q^)gt_�
    T8`(@pUrU5]F=TƁ:7Mkljw\&l.Qˡcl_[,d_\߽VnW7xR^':֡|_ԸP7xLiCϷfȲ&L�+ݕ
    $\#p
    .^Kq=>,
    hRM+ں+�ͲO7�-{_<?ѹ$$$w"KJJ;uVHo߾
    ^~			+WPB={[WFFn«}sK|05p@4ز;N4k߬AղV5kѕIx7j,h';l&in-^5ac?P)|g?{{۞KcFl;:Gs7C	6ȱB[UMy|�!GjyF=FB𔐖 /h8MʷJR Ai3)na3Uvuh3VcO|v1cDgʿ~l}Ak۾`oʔf,mej؂Eض%Ñi}'6`W+hSZ:aF4lN_.Xf[F=Yc75Y+^!vխofi,%^mY^`7kU/ߩzw^VkjΊ[GfNX̱-~J:nڕ̖skc9'Ɓ)I?mvD␶֨8o}`vg5=5̭Ĝ#ll{']s+{JT6_L\ѹsZu
    {ڍ;jQ
    }/ob'g�=aK<fnhÑ}_wP!r2##!m+1NPeGe@!%,,,Ά�}v배ؤ$|qca|pPLYY	mN}br]fnپcj8t
    [Uv蚥*?o-vTfUIxEmWT7p\�؇^5ӧ*]?3Z=Wd!Z]F
    +wh6%1AY·$'^rjͧ0
    V?dh\`gMᲐ<q
    Ƶt;<PvZzO	`ro3q_oHY;댋0֨ݒ
    O\}Q;N^BPJy.'c�yҜyJ_;Kϻ[I|gեVgϦWs*mWZuR>UڐAotO^*o^%+c>@p`Y/a=Gh+"PBP@G]xşvt@<_dg5~x[0_wBL.g	T.0`?}
    "%8UvrŬhйM~z6zޕ|p8o-0sIrrrϞ=$Ib8qo=z4<vG\
    oѢEݺu!j+gȁ'l!ڒ^KvW}0IG>BrnKC
    emxVڨSM)5]ZR}*G\롑veOO.,D�.6Cq^,epefOp#"xxJ,zdGpS܁i_tr[յ9:KdڔZz8F,~q}tԧĔtG6`ʰ,X-7w?s[*LagbiMTΔl_tM8Y(!1hY
    }cǥ󑪠Q,NƏ2ݦDT59ؘ.qZ=�)A䜾|=9cf	<<(CNah6xmT?zo):kDKOiX4
    $j՚r62q(^ej:?XPU-mhzV;bݶhRBGA硃"4=9!r؄#|Oro^HKo	%('`8|jj*$W\x"j׮	
    0Peԋ1	%g:}/p$j)Xr:&bSYTf?y_Oa(-W6>=ZZ!,HZ0mPQhC;Ua]\i	 
    sc·T�+$	]<�3C`P9~%C.K+UXK w),N@
    y]|R#ʵ&骡T.
    nrRQ�	+ݫ<Ts�N�'P@�2Ѯ`eamJ\wyHiAz}3{͛ׯ߿[|||!XCt7?Qa|ZNP6=-ϒ)a~IkJ;yz'Ɗv}jwϸ7Na%={eqSqwX0\	ڍ&7dmzB5p2PUOyf`j#|bKڵkwyt}͜9RrxZj5W;JvG6_H[0 AWr�O
    e.\~/aOsOqŋ-ZK=	Kvyܹ3g(5j@^:<~ Rw̩ee^6k[YkA+X_RQt|uN
    L'Vl9ժv*_PdH�u͇[)P%Di=+{/ Sh^pM#X`''8f/LwVx11?\(xfxtω65O+ek*~=Z}u?C[vk$}*;~͙3hǏ駟:tPJIII۷裏>t
    f;[ѽ2[vP ǘ3Nls�%ut+o8M^mc.MKFyޏ=:Ŏr2(
    'nԻN^j/ܙ'!\ʫʦQjaiao};j'J6}ŀݤY~G^h쬥I}糽w}4ye&ke5R4Sj	"RL~-_ݱkꮛ9S/XlrթN#9^>)}�*	p<Lh8p{_2%l)eksJ겾kXۄGij;A>Q4BAA->`wҬQVl:(Vsμ,k߾7,f1CG]_b+C~}Y"]33^l;]xq,e6'HiݺBj_ږnoJ	vtA!3$U͞K9v&((/ڟZUG=(q@jФIiӦALKK;}-[7n|왯\:Zax2K_o[7?w�;*OLﲬ^zn	y?lk޻Sko`Ӧ9Q9/-ү?%4^xV)[`XLYt|	+\.QƸ}:[C~3֟؇vZeݻpLvD7ԓfܾF~V
    ~(Z>n;kոYeg_f駯5-/MRP_4뀲c~P]jn4*ʰX٣K޾kѡUKo˺240cnKb&/ۙCcT0a±cvSeX)|<:N/]c"ƏCᾘJr^[Yi@(wvu\iEƆL}f㼶dn%d߯20qs&6I^Q{dOT
    x8f)<3'd2W
    d]&&:cGf|؞,Qh"?0R^iDJUƿm|pT"hT*_~RbBMͅ>"_zkwKSM'ui>}{mJ�ۆO,kiY^|@f8k.iELa,8Ҝ19ӯ$ 76vbhǭ[a[-]xB^kcq`ߵlyʲv	A(em7^S絟XN	.[(i!�4-|w	punя><X>]~>o_?K^G3p U?C~joRCN_V+Lz+#-�iu﫾yk
    *//UVF:w$SPi9vRҘ<Ӥqr'
    xRӄ_g,BdpTӮc
    a*T'lnw^k򵫖�+KGtZIWU"Y*WUt蒟NPaTZL8uth(,Si
    r儏|D:)\bzyE&mތc$'%NX%  )%J�Hww੮Kܑ9[?
    H݅q@SPP6&:%&<	d*iU2H4,/24~*<iT“V3*cCn2.xhFeraZ(qXL!S:ͥV;cr!^>J9`iiU^2)˜K&
    Jo܍AP/*xgFC	7$r^O0+C
    (iur�`�Lkz)#K)kfísl^jŋYQƀիj^ĎRprxIS4hbBu[;(F7m:#CK\2LkZ
    8W0)N6=e~ds=no?i蜟;ɱo}߹&igsVvīγ;!׶hV-efΜ<~I@|{y_>a]KW?8dy^-'O1!L[_$*D]ޙ&D>AY J	X>nm0?匌;w8pѣ}iҤIڵ2}ᩀ(OP9w<m4mǢ 򏔕-,,lK|;Itj @hS	')0ٵy8..6UҒbgVQB,BI<ߩ	l�]"iD^=T[QzE>k{f$!BH h!Hq-N")"*X)R
    -E%Xq[]{}
    �²޹9�ĖRFF**h<ITZËS_I=|wu20`y\fp>e)!a'*z16šglH.uP>_
    :[X?=,Ou!1bOٴ*KҢ~:-߫H7?NO,Ӛ/Q/Z >m!ywTa>v\TGļ 	̳baH'ST:.#u.Qlu
    ZCz$~YgƚLfMX)C	d"D]zƍӧOϙ3'))jժ͛7:RJ=@6Bu7e󞐒(aI>LjUU&0ߕ/EH]~F	0Nrɹ/u?i=NӽԽk/\/{
    UlJs8eدT7	2
    Glہ	Ab?e3&xP߷6~ԦF=δ=CnCκ~w'ڌ]ܦo6l;=FoƔ/R/uw
    g/ةncHbٔ2-TM 
    		y9vmϧdy`h#=K	f{
    NOO_zQ
    l۶m˖-!o@y,*9F_fy9oYAj+`)C`A%^[ߋ{=L%�28ZhڭG*XQO$
    c4^N:UY|dmi6>]zxC}ҊUPƺ~sw<(eZ7_F64ȽzÎjzwe-EG-kel8i[I5z.A%[gOL~uٕ	4V
    At1K#捚F8#*<J%:ZTVVmѢE_Gܹs̙; ]t:ZIeY :mFuZiyT
    ˋ{3-mc3s3rl?C
    .=ENMZ\MpLk5t3'4GcxY1_CKRXR\IK+pTxrm^.fJ%CN3yſts]7\0g36Wp;iO*t6m_KqLpa-hN蘈`iT	k.V*GY7ŊwSt}k =K
    	edSiu֩W!}LrR1$ar͝0HŊ(Cy9K{,Y6uF7Գ73a_d.Q 0dtC)dǕx&@s{qo&55PsFڷoqE1RN&)n)CX>o?3P>̳V
    k4@=@�fābvS.2:2,,+H*T%WT�X(aB7f<x	L=̫Fs*ɝ(cxh><au.jHpJWD)#(P
    Kic5_xsVũ$S308M@,;O1ܛSWS!Q(>@w!&pd2=Sf~=:"X&!糌/:A"DW#}%dd+wUr巌R{]v^DDDt֭SNj/iGYEf2bE%Mh9>_q\yy:@?-c:~Id)ݷݔM[ U
    *\%(-:r6K?X誘[l&{rRT#uyAU?zNh9bC4b7+�Ox0%򪩄S>{nrYwreB(=ڰ`Ϟ=IIIǎ-ZԨQCR=Q�8`g/ d_WT֫:\.txRv‹ŗ�٪~jZK`WYmDx<٭",ۍ$EjFגJ>lXLcQŕezJ={c-E3_='I5U/tKU8F4F
    *ϠjRyv[>fTBw=&&ׯʶZ,E&{͊?!X%@,MxBi|g:~sH,,c
    AQ~ <$Qh~ ek㴊*>ff<|ݻwiаa%|EELzd2UhݺUMK=1DCV&W(J@FbU{y�(u]~8>>~			@D{*ɌG^MA!s\cBHZ@$o<R.<aMr2<^Z[@F5Cb+?i8ET`2~%453x
    >֠RB@6SΝ;8zٶmʕ+?�|Cn
    XsM6rJu��^^ѽ.##ĉ?rHpppÆ
    T>.CwA{7ⰖA^$nh
    }\zI i9'Cb_ꖣ'
    c:Is9aN<bhkTSʋ2eff.\<>b1bP[3iiiVھ};PիW3fL*Uv߿۷;	j^xV	aRgQHg	HbO=nܫP
    c9z9!7ZH J	|Ps&tl [,`ӧcǎ/qO^vsfs//V*<%`u$	l2S./D~zZt,WFR܍H򰯥z_W	k&tVRV[=咺Vaٕ{/"ΩkDv0<رHǏGGG'&&h%MNڰa8txxx6mv
    l|1s.4urz\zI0_~I/"8YQ19zN,!m:fX
    羅kn1S~�UFX,m:J+zw*W׫t1kar_H՝?|9P!h&w-4R\9gm>qjq1y&"~~E~wz\_O{$G\&<]=Sg][saե/NOԈdۦ-ဪ/zŖ{w
    ^Bx7�W{rh'MYgSz֭fD!Cʔ)Zz3.,Yʕ+/:w'RGCh,^V? zV,G_˘\>_z3>2c}k?jx
    5YrauO͟4sklPj@reCm=e䢩#驣niܬCbm9;hu@p͏Zܙ瓷Nr]'z"z"zo{ꌘvsԼI}{G"Z@Nqa=qހ7}&B!!yF_#3/<脦_
    Qvüa>_E-ĭmu%˷o޹sU:nժU~V^{3Pm
    @;O0ѣ~~~Cm֬/KVRC%AUlp/S{d!eC$NarZy~9ݧZӹH^qhת}\;-|N,E|D4,чJ?8avwN7]6xlxV9X3j{3+&FËɡ؏|(7xAY_J\P~'W	<΂xk~{!υ
    LM;{	` +NQ'zB논dž
    �'''WZuرÆ
    {2l^XXxy))):t۷VoҲ8CD%Vlz72,獳8_
    #,q{֊eRavS,"w_3q$& оL6&Ia'Q
    8L]`D	Ʊ`*;1WAbìw7C=|aL$G]T4+nK`1ʶ�wy5|ܹs/]Gyk*�%f͚[>xmڴxSI@l%
    
    <Yݍ7&?+i*rˌ3펺NZ"tavViAkD8.\o2W^|z?Pлwʕ+7hR)7IT/׎<Bқ8j/݂VXgϞ̘1+WH^|ሉ0`@g<^')J(& F#+K"FQrY9,˔R#iL@rD@B^0?`Cg~fEY#6ȿ\,&nw
    +i(Mn"az~Rrj9DX8{t/V50~3?h4<yr…k.�^jÇA4klРAjR(_xxǏaXv8d⸵xlڴy_ul˧UBFÞs-ݔfň=wմ4aUڦ.:y9XM[u(_
    봰Jc%T
    ,QKa_pXUzXVQ/xleN=w}`?a쟻11hQ?XX:tJ>zһKHsA7o~]vG`d':uxɗ/_Zjpp~z!}
    R]nѪ~jVb?큃<C@Ç'Q\BS I<꧙H>{cűC+oc
    S~5 fMFD£=ɝ*%naq5=[Zr:ֽs<𓝣8Ng\{qS
    r8ـ-|z
    fJOc䎼+w)FRY½箜ұuƶ3_>bW[d=4Ӿqd`Q{Wƍzʕ+#GC\\ht0z?rcccv5&r=;)K$Ls"ʕ(@R\
    4-ޤSa"o}3^~QP8=CQ-LY;4ОPمT#oGBp˜
    [mv+1ACwl.("mK#*t^
    zn|6:B{O\L v9A2Y4xzc/q5Dp)v(p	5.MY?ճ%rAٜ:3dRA?~Ae
    3`a8ph4ݻ{5jZI#eccufkLy9	ƒ0a>d$iƁo棒ydi i߯IP",n԰TJP)'<n1t9mЂ	QCd](.O</>+)+dͲ,LGg6N;Ţ&(ʗ
    fޜCx<*粖O[h@pǖtAM\Rq,"8{>
    
    jԨQ~*W,4g}*be^-@_u<`쿤sE^5|0#<+{
    Yop1_Em	68.a!ڛE0Qa#^{g5h[3/`s0&n`{t?C}K8">MVS+
    K
    rJiO>	ZF'ețnt>wVlBs8K?Ĉv؀VAJo"YJ{ݺu={zݦMaI�$I|=HLD]>/;00U=9^-,[JC;YrRj/_y޼y׮]+[l׮]
    $X*^)Ff+*0˻=AwI/#0օFps/|K
    Ok1HT/ϳ_^Bnt쭴3LEC@?F-ވ2YV-]V!OjMO0ׯ_ߺukU_1j5rÒX-&/bt	&9g=yVnaz?`Λ.VC8F
    3疯]~4]Cwڇ_Nj+]WoWn8=Cdmp6b?]ܫ^{zB?oӴg˵	rוo~|bvG@V\rK@.4eLą1JRȒ;JQ@`Z֤$[)_>}RSS)3#zuRdBmiU4Gi(]ٵ|ܬ 3n9vr L,6Zl^n];?L:vo6!HLjddݽkkpei{'W:tF"f�"MqӊUt2I5i.6 `0[(C'4WVKRT9#fǯ!4E%Gpi-FCUk02
    BUe{p
    S%L`E>
    cW4L.EY҉,"idc wX裙.sq0$<XE!`3T0${~%V.VH1ˇWGl}J3.!񧖍vZ+2E|#\N%xm`a{730g\Fr>.~̝yȉyv`YHWo;Y{zf´oG]]zE
    M1v$NZ8cR1u6K}iÀGѓwxRz|_F~Lb4EF*Y]RW0	Fa(--ˡ*ChBC+Ea*SMZe=77K&B =Ihe&E+qyi&�ڶtJRM\F:(D2OOkY,jϹvؿv|
    1;;.h>_h�)WiӦ'Nx\`Yeȝ&Sa(aVϼVaxS鵳O>3饉7ؑNv`g'YPQ)LXv͌Tݰxd}kkk>,rVC._]<lWvשDiX4XŢH.3;yK6~вq찥XTR7?<VKFݹޙ#wW6`07../U+a@2z{p\d:oCB
    r11)o$3UH$R1?]ЋX>@o R#hءeŧ*׵X~<,UXo<?ƫedv*p+*:uӐpNU*7x2*6Hz#KaqHʼn˷DY>”kJ5z㱟W:%=aP7޸mTmlMu<߬?QEY36KwjʸlXulޕphk#M±uqpιgV}cV'9gn?77ܳbK/Df6ͼH M;p^
    rl!K}œ1(|ap7t@C"YN|#X"-9iybR6kJ@,_%X5u}jbLb.eNIܹZ{9U{4	Z˵1V?Cm7|Аޕ ՟?
    N?vS!Uk\42r1C*nE0xXEMh$e8-q}=)޾oOsחc`4zc_1fWgdw$:5Bp]
    np�N%l`
    
    	)'+Gؿ=<JQ̜	SIV({.űc^6++d8rشAR[F&+_6weݼ~@8|r,Ua)2X?)Q֜;&[ZM5	,tf6
    2`uH9osipb^*qY]2QA~Lqne؊uP (ʾD+O`0WbE}QJI	5CAn?Np!$_bP)2,İ,P/XEY"
    Z&*y(??QeiR>zWH)"߫<B,�
    7'e!D&Ys]f ZTjCT27/[8"(|9,|me]&u)HBU
    1e2\.Go(~1	@Cu: h GtU]+m"ИFJb9^#>(#�pvl,XrSH
    H*�zZA?K$p;L*f=ZR"HcIA	Rn@E21PIwE0_"(&B!>h~}
    pQa%nH$O{!7KQuv
    
    A)otSР�軣>G`jO	jyro\xN&
    _˽:Z0mhqϝ�
    A9)nv`ctX!Z7ʈqF"	4,{!4)ca!ItΪ4{y
    GJ{^\mӈ!?5P{s*:o,Q<=MKtI1MaQ0b8xNE\RBn�,(#?v#z*99FAe/NNIAUJp%KV">{!]ʵ
    dźv7;SN*RL+"6E`jo'˯엞YYW~1}qJSCrE#)m
    hO{69-fv\ /r@bߕ}uf9/B H 7<G?:"?nscb+4t+b2g8aڍ�{d=bh8JN"QcD*PQb^V. \ߧOb^~¿I2#`;>7Sͽ'EV3V"Q($~W?a͢_.?sNmڙE[EXtvNAum$wL7󘚶>}'K8|eZ
    kn5 ׯC#8GfOY\b3QB(1kxS썃fP:u􅟠3*w_ ׽ۈz0]mԱ>ɚiޅO=L|ʈԞ_;ܫWʛ׭,aE&BZI3o:Rg>tf_dݖ:Z'.2n8%2nә3;~'
    u	EԳ*6^#^Մ1xGqaA^Ne<$^*K<oවqs#EO-xv2XMZYɑPT
    ;x+4iW)h9/1eKl`fMknߙհW&$쩕*py5Yy^zo΁Fn]/mI>R7W\zKT~\. ڌ>a%b:}Wdn8E@<;u{;io{2U|@qU˓*tgӕ;9aā̇]yXٔm0USnkvV?Ț(
    G8g<8m6))BzC63l	UpQ-(CѠ	PBF(Nײ^7v]>9I?=:[NO3;JjF|j	(
    h4͖|)Z@
    a1"pX"(7ewԧ/
    s_O߶eEw“0Mfɀ;q;*?u.YߵKܬ1>tb'8S`i+gsӒ?0y(,�DΡNj
    s-}xݲ*+4j;&F2TFmod֨u:ng>'bjTIp#Ƀ(M~\_ML7B@fHd0w6kɺsbid'WFVԛZ\<2IMiJ M~bժ"C333Rlz(
    JL&+$2>fAs>ѳi~BFcƍ!qX< D$JK$SK8C?#"Rd(KNNYCq:F}]u3(!N'`2B8}�=&%8?rf7?!eR"f%*%J9]SKr	岺G٭pR&a?zbB*H	
    Kaw"R;9rIHe
    r8/r:v2dHjƎ+ĽJO;KUB)Opp
    J
    y#dRc(ل4<uހ?}3QO.eIqF)4än2X> mcq[h9 A/& Dv~*-@OmkދHxi98ӻH|eNۣMhN}F cr>ۆZ D0LKݤIMp;GO2m�Cjݷ_uY6b?	T@̋Ia%67-SjD·K`7bwVan5_6rPɶA+֖rQERID�	aB[ul6%R+m)G\ⰠF-[D0E]Lo=p&JU;)wүWflBqbřǷqڪ
    U+ t&QYG\HA*CB.BPBܾ|M+(+7m^%L[N8v`=DtnintYLKkR׈׳˫)޻ODi,m50L؋m$fOK9TkЊ#(WMqBx#HePg%c]b\}hGFv1v>?~qYJ.S9dK#;}Ł_)M~9g~q:ZNNU}v_}3mgneR"I?3PI'kGbw0N.̻-}7udG7SdY'1*Jrm=ȼqfI'VL:LRZnx]3!||Mco…GZ,Õ�*e^Oe$e"Ct΂H/b;qVn'Cj=,Pn)"RNQN`2[l?R$]lE]w\gQyanVZaԏ߿Q[և%'m9uP8\F>uC iq<aqmh{ϟ&?ur֦_j
    94_}yohnM>b=&,@p_04#Ԫ/]$͊To_nq՟WOb[\!i2{�pjϩrhHN^ˬ#sauB"eÉVUZG[1
    ^|4{B77Ws8^a=5#^d-EM}1F'Y+:~޿fP�
    я&
    zaUa$ACQE=R˥ЪCh$?K,4ҩ)oݺUHYʡG0f!NYPr('e_ɅWp"H*kHV8HY2UsRەLLLR*sd޵T@@@zK$B)/N<>_)M>�tǏ?עE')RVVRvI޾ȾKb2ݻ׮]p9`+VP*`ZVr@T|UQ)Lrf@;vHOO>|X,f>wk׮l}t@'}
    $@ e7|!dX,w]|yfիGJB`ٳ'--
    ㈈ j5wv�xQ�lwu§@9sݺu0/%@R R3̀Fcvve˪WުUxFFի:~|t,JA�xiv[,պo߾SN
    :TOu{͚5M4iРFt,}k �/h9i6Ν$@cA<…kԨѾ}{R	XPSoR o2PͧO޾}ad^z5`nݺ�)guGR S/Psnn͛/]Tvm/nR 5Hf l6MZQ(X7):iv&c) @
    �,@�R @� @�xU����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/syntax_rewriterule.png����������������������������������������������0000664�0001751�0001751�00000150167�11577356155�023012� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����>���H��iCCPICC Profile��xZgT]!< QC9Kr"H%HA%*"$DDA@AD[SO v=44�GYiW�+gx1bo;1}2 �9b{`8fGGF 6Y;C$!	�x.x=v1vw+bOtwA0o챃evp?2,C_0"B{=xy{ �
    
    
    Ab;D34i+@p!gds_@�̋ɂP�d"@lr~B,Oý"h!}^�_ۛ�ڵPZ�@@h�`̀5p�. A<Hi d|PJ%p\<` D 6@@F%�AP	C)PBePT݆:^hz	MBs7ha*	悅`)Xր
    a+CX8>	ep
    |ng	^Q(fBPdT(*u*EբZPQèϨU4MAKѺhk;:@CWo;C	"zCb1z[Ib*0M{e
    b:X[6-`b8'S\pY\7{[xiO+w
    >
    
    #
    7HR)&)~P())(ɔ9W);(_P.Ra䨌<SRP=Z"5-!pPFC!,Pc*'˩ۨ_P!Јhɥ飙iyhUhmihONAt<tttQtt
    tt^)e[Z^113*3:01121n0q332%13u1}`1111g3722d`QcqcIaDz*z-
    ^vFv%vTjA$lfXNINkx
    ǜK\\$@<\34܊nMox<2<<<y^x%yySx"2D'qb-%"'i69~f~-P}BVIuo	*~݂+BBB)BMBSZa#"(9YUQqQ'ѓDوk?&~[={ٳ(/a+!.,)&"++)OOX4tuiNKt22>%/{twaߨ\\yy
    
    6
    
    Z	-+JJAJJ3n_X<UV5RMWُݯ?e֮~O}:4FF&FSOfATdO:OzͧM֮Ҟבщй{LOFJPﭾ~AA!y)#qCFqKIɺiY/s,--Z,іfEdzݬYLJ1ym9(99:
    :F8>pbttjtF9[9W8/>pE%嵫k[[;{{٣œy@Ɛuho:O/ٷя?[�c@@@AAARǃ'CTBrCBBB=TFv?+<&|$B:"3c$)4r#!V4cth@̞:qp[\aG?ӑ΄DnG;%}L6HII	MIUH-L8vAHZfڗo>tb&8!%#>c*S?zSᬩ'NJ8Dz؞i9۟WO?ybAfs
    U
    +>;uABE؋mȖҖ)/s*{\R^]QQ~emR%W$_Y"WjxZDͯڐl=~zShz
    >6li2hjpMo1JocűeѝV6껂wmiO@w$vߏ3s.׮w[u<5}HQwN_c'ZOk|Jz`P{{HowpɈ3gGGǞ<zA~12W_'NӌaSVmDwF>98sǺY9>}y{>celQb/_}?ĵTpjݏ[?V9Wה;onm2cXo,7usߍP��`
    Q~G�B;
    !(,BP:4;Q':n<҇@#AE?̘ì-=W9"(э/W!^a(b^odzdoQXRRTW-E2
    Z6(:zS_
    V
    7ɶ9dⰖ1;a_iy˒;<^H>/Ac!"\-#L#FƦe.=r35ڔԲcei%KNO<u2i39QayAgm)qg@R<QSZSU_apI2SWVM^Tur.߸uT;Bm|ww]nOKkg#>Oy_l*>:Liqt^}5FfmD;)HɇYs͟N7[^x|Iue?>\Zsչ$[`Ҁ
    0jF8bp)G5FIkN0TƢ:nQŹ#ΫHT3?(.xZVg1&{|%%I}a%
    wVC~ZRIJPG5aZz|5IzQgVwy{7Te'ZDZZXg^+trvv>Xr͵{Ggk/wP'CBEH(hX8ÁGlE2%a֒S>;66z|ģ;Y'ϝJ?~& {0*_r9Bph|ۅi%ƥeT/U2\abXPPK:Mu=Ue#	}c[C͝Z*\h-h˿\{IGλzF~4Wof..
    /,<yeƫz_vybu׻S'>̜̔=4gIE/S_=c)|Bz̮a	9.Cf�0:t냫4:MxB
    ҩ21j0c`dyz-ݛCs;'ל(G@`0Hh8jRtReRe,-ٖoVQU|T":Z[4OiФ:ɺd=#[&fTfvVtomjlct:f99g6Ļ깱͸H4b _Q?H8T"%SaPDo(hX͸=DiWNjMML?:-Yc'j?={,+W67|6 MJw.*1/WV]>SR+UW}jk\;Tאx-f-w[
    ^cS{׹=^Gv}Ꮟ=2pghG㯦4ZWwOY
    �8eE�R`NȔ,
    `>=�%�7@SpϜ2ET݀ +WOU?akPchj&:
    ]`0y!,-QqY!<;_ߢ0XAXWw{NB
    .u#
    &6v&}`HbD1&1ALGs2%*{()n>&}1P"XƧвpHآxc6?dFg%+ (ĩ̦¡ʿ_RMUV0vNs}` kH6:ggn&fN֎6mvNn.̮.n='||{I'
    d~7ߒyT'i1%KZ	LR-,P/d.ziK*V
    W]ָpZz~]"ݾm>+qfg?y,<|Z/
    Mխmvh 
    D zCj
     ?4t	jAj
    `{5U
    RBQhz?:<?Úa83O!||$E¾'PQ*&3j
    4EtttyR&Lhl^V1HnX,2Z.1YB5{
    |*1ÊS" "&#-3!۾|	X,r*Mm>YcS$㫛צŐHi9762ivם9ttsF?~7ބh6񆟉DEE
    [?7q )0""MtSӅgrnirPRlQ)kQ_VSKwmVᶱ{;<;n,?Z{B5 8h:|YWc*ot&5Ncfg~\H2Z&vE$Pۉ
    < o<	r\V]8_PtT?킾^
    XlvgG59bʍjFHCCCSKkAIwޝ1Ii9Ee̮
    ,O
    oQ7[d3Wdeȇ+++uՔ|55IڕzF=&2yH<lEk]mke;4:D${r"&^If>r9#^ʥcG[dgv?r~:b}I~ّWv]ϪnlyŽm^lg{oe<Pd8rk4קUMsz/8635;9~leKתomؖVxW~(nwҚZں_ȿ.8qwcvqf--ĭ[[ێg{wkg�01I{ynȑhSł^FșٷBwlcvD?X;LH[<4Bk!;4yB/DGO!6Dii`AwGY qv,{ðo/`g,&@``D`dT|A0RfH@$&
    х�0 E&HCi_{$"e!h=O~;م%k?;FFfNfϜhyZ
    VD4HJz�蔁.Fz3ǝ΅Ī"ڝGlw�
    7R?[iEtwu#o[9fVBBc||#H$Yh)%A+# {���	pHYs������� �IDATx]	\M/m/-R$*;:SAaX"3dߗ$$}'/[alM$)di]Bʹus
    sss4Q(@eA@W^eE"@~ZJ@;OP*ԭWKJ;DTm[ן"@tP^.)E"Pnj_{�E!@zC@F}i)J�uQ(U֫P*ԭWKJ;DTm[ן"@tP^.)E"Pnj_{�E!@zC@F}i)J�uQ(U֫P*ԭWKJ;DTm[ן"@tP^.)E"Pnj_{�E!@zC@F}i)J�uQ(U֫P*ԭWKJ;DTm[׿\^MiQb4llpw߭kC!!lrqq*
    آqHHÀ2G^):1u1R+uDCB?OX|aWϟfʪuI{aPk֩S־@>}/eMI89v|UgAhJ�uR
    מ<ififfV^=ssFff_ߥ/_om-`ΜW3Ƶef۷eJ
    |ׯߦMG11666ᦦJjOC'ӊ
    9̰NƍǞD4iC$BBsPPvx2P^z
    ==%''o߾fm]*iԢ@UbF6iMDǏ,W>;wB?j_,!AAΙLb\I%3f͋ړ'OMNHxI̽ظrqۛZ\UWIn_N=z"/={$#,xR32P:=JRRgy#v3gg(܈lA)xH44ann1hOR8,ҚlH>as>SHNyW!lIuʩNN2 @z7Q?#yf|ZZi3f;{
    ۼaܘwwI{ڵ(͛75
    }�O#"[ΐ!zzz m۶`G,hϏff<~4C_3f M}$6.qbiim	l2NMʃ(  �g2Bۚs=Ellm`㛬_Ys	:�]Ɗ.┤Sʛ0		_;F`ґ2_z3""ng!j]_HAuƕ"ile@
    |_<}ʶ^sHx"M{𠟟M~ll޽|Ҳ_#Ghk?>+-5S pvжmh"))q_7LMqbffm<9ybBٳgيl_Awp0!LL|C~C.4lcCw"))…hRTTThhh\\ ׮M>1w_]Ҳ{dmmOq
    N..ǎ۲fO>7,DK޽eC6`ѣG5??7jԭJ~5\yZsOHH�b`t锲×/7o\ݸ]:D-3ot/>|k9̩S--f##}ȏ(OsŠ2iRG+53yWԭWkֽ{wvK)0ٳg?o))Ɉ"{ue~AcilcGf񉿿2v-嫐GU|P!3-Y燳7+++>}JErE^^#nJm̞S$d\s*;[+\\aa###0D+WU-2իע;ݱꓘߵS' ;NQ11PvIttxzO6HyxxDA:5kR-M~ZZڐ^`D@~/cbڰw[[GrÇQl77_RHug}42eLE /Xq{P[y}##=.0Դڄoã͍`Tzi}gψ?<llf3F
    WCu6矉ф	e|.3ُ/_\fX|;e+@U5G
    +|u\Idrs-7_1_?)7a,F8;i}Khw...P`#]676ӫ>!}P~q7
    
    _m]Iu*L{SSU72l(02
    {:82cvtBnL޽{7
    LI?/%We3]KWdTUCՓ.@+t^/EG[[;ٙ<YO.cgIEE椧ra?yY]%.0YH[Ņ|$`F-Z1$ӧ "woH=ۆ8u%MMf&$#v
    f2a
    ^M6-&&
    ۗ/g>=ڷoy
    |O 1*1B>SN~^I	Cu{R؁]*q߲֭ kkoDVW"T @G")j+:3gQ@d?<{\=Pm0,1{ޙ>90	nk6iϪ@d71z
    c-U	w=*9%1~G'ʂYG'u娨u$:11lC4IOZq9A{` 5d-q-AΎ[I\Aft<`'o
    ,VW
    z""@GI8?&f	\t4Wvss6mlW?G7(bC|80a<k{09Ħ!l/<3q3je%Yan͚B8=k0�	<�!>5aݛ7g%"_gipeݽ
    f,hʂ7uD֮ORrB!J!q@!KKHS3$@'ɤŞ=W9(WRR.Ma)+cJ�u"c U6a:xtW`ѣpB,nkdd~L`I7X]|gn:;ހ�vmnsqrs	M^^{s!Gs7
    lXI+۫8|^I+c_
    5Mx',R3yN,#`c3w7 a3ϟtxy{;;uqHc]^}>Ǽukh5g`yZIk7˽QNg.
    `Ĥ(
    Bx/*5CT1.LZxSxx(:`+ 	f'E0OCquc7m0+Dnؘ1k.#:(TibUiS:'RRy^~. @7\P(|C M#$s٢t5>̐>qb=+OWVf֬q>HAVӿ Lp/&h+d3׮aY+L<x̎rcapf#Sግi܉d۴`7)E;o<iӦ7y–<<6[إJ6e1Xv9AAyUX~!!]yXY9Y֬YzNlFUVڿ;|
    >i8黢ڴm{i,L22jHj졠nB_AI1UWWǤ"YWKPz�N0TTSSʂTjF$`J8F{p̑
    \
    -lh	NT$URZLJ`+OU
    <¿rz�GOw E|`"ݎ>=67,QD|	*8?S\DfQJ, qqeH6KThl�/ő�/[XP2oH7hw"aIF�E| @G:v+a$22IҮڣP'4^>mE"@hlKPe(@yFaաmP(%FCFP(�uжQ(#@z!(@yF|uh(@nĐ�E<#@zy:m�EP^bh�E"Pn<_6�E"Pb[/1d�E"@(P^mE"@(1ԭ2Z"@g[/W"@K-@P3ԭCFPJ�u%P(աmP(%FCFP(�uжQJPOOXUUՍ9=%{d)%r)١f(@{;ю2_j&-.l996U(gdd%L={Yhb0ŽwǡҦJ_�c~lE" `1>o/SV991h`y
    7rܺ=l\*>zv@s_�u_-M(CH
    	
    "iϛz	uVH3S?KT>~x-(VT L	
    @
    5!G}}G{I٣WTToɓ'[ڎ+6ӳ5]޾Y,IpsFFf)3Sބ>3[Αb:500CiG'ڵ:sGrh]III&I{e
    cRyo㳘eDM(;԰LSFVhrP%''Y 0~ta)ltgm5^ýKEj**t먕,Ku{?aɫMmꨊ&
    oxqkIgҮjP72ƝմlS.wmn!<9ZAE}}߿bJ/3MWIZ8d4:? 40(ڡGP=#)ƸZpA:pn@{8^,:R`r7nѹ@UGΡ$>CCo:@jcon48;EeCCh&n>'O@HS^yMZu%[8ЯO11i_jXljEhȡ@E޾4ʕ׿O\E !fbRIN(ll`tYY*?qsppr˭*bݻNZ|<9
    L?<L<u뇁6NQUZr1av6\;W`A(>#H?,Q,QA(g|[m8LK[AzzvI(җW,A"4_Ex|/Sݼ9|\=ɡu2'ϓf3֭M2/^)^lWTFY_ HMHH̳W߆1Ryr_%ژ5}"d#!o~ߧڧK!uع:]l㳔,f1F@!Áw
    GWWZ5Qoc鑜,Y˕q%%񹑶!_Һѣi5:S+?mz6iֵSR	L;uǶnsze;DDZ3GVtuy5TatW>5l<{]̌OpTZrr9e"9Y}s_�-##&0olܢ󡖙 0ׯ_Yj֬QRK 4:,6յK*"]B<aQafM0`~ʹ?
    u:c߱ϞWZhV-m:zW׾$xmaisSgo>^NufizYi60ry6=|ѣ5DVo&VachbIZ
    ckiw{{m<<OKCy>j73̈xh6iwU2י3Ƿik/T/2EhѪٓ'_	NΟ3y5|E"5#\RC}fWZ`)+c4op7ۧ$'/X(&m]1c)�a9G R,^իˠ
    >^.	YILv[mKW>S.^
    nVQ zVOOwNI>Z]`N[;_k7\^lw;=!iRtP:G^[4mz
    Fp"5&4_Rh{uu#7q枓'#I-)==kha!JǞuc_1=9}aTcƭXsAK}fAB+Pf'|}oڱ%?
    kGGGLNk354^}DA#ٺ57]lyӧaL֨Q#74iTW֪+Μ	.XgX&){W %K:w*;O""RyժUV	ÚO>q>lhAtRVVى<I'9|2L¹&pʏ.^	j$4:f-8и\MSAs}gڭ[;'<o^Cf3f C`cKdӨe9B9=D\"~D8fZFGaF[_3C2."
    05Cں.~.66aOK_+mZ5}/ +aH5'	**L0	7-p2st_߄))e_BOLLn.r>*Hؤ>Wt}R˗a?۰#OoZXF#_̷ի]_f7o8"c4ss﵉|c|Vʍ[EyqySx7~[cx:ѥ8!.<Z5妜8O:�Tp'^vJnDǤp5p50!K#	qg	,|W1h=ƽoNl5bTѺfX/YP\hhԷm<+GTMuǍ۶mcrqc; 1z[fV}QOjjj
    b~)H̘9n!==X8`{韮Nv^8Fd׮#=$>y
    !'m\;wQyxOIɐHIkQP8ߵݥ;xG5**(Z5M[ywbC?+ٕ⹬^zWHa- ێ.ք4aVԩSq4E =q0_}hǢUmdfѫ[C%=~Zj*ouijx�� �IDATƬK!NN܂̏vv;VYԈ2^5g{1\@𡁩ǎmM`.xsG_3甯xaɵu|]8#+Y;w3:k>}L=Z:Bf;l=16i&M@%B�ʝ[/P`1;FY({bCRvUVC.$J$b
    B4~/l2I\	
    fHD:K
    o#rA:ϙV	\rέ	.CZy
    Cɗ9hO:u,zD`+[|-Nf5}1TDVx«+^0E‰'Pn]R
    L_f2 n8g9Sk)I}z`\-T307UD&:0d\/iEyNNMf40hԦo."9<>VWScl_rE"U!kYd*C^vŭhj-HODJC8«*k&ѣO9õ_l|ęG;k|g}Ďr-a
    =*iDxm1).&kIdˇwtKO{vQ̂b%ܼIت@ٳgKF(V_b9%DJY^f]\fNSdu*[7*cJlҠ#H6:п/of aM&Bv(CQv	L2Ǥwor:) _On(I K ߗԤ<Hlu|<J2J{qh=~
    n7t;֋pZ[]|EY5մn/D20g~"M>.7LHyO93-chai9i1{fn9""bʀfxXA"^wY%IMYu<[e5=Ûr[hkRIBr*[WF#v=]xfʣn"EK8Ž[Gg4;xm\8fV.!
    jՉ45oQF\\ej
    `ee:e@!O6
    [_y
    _F-2F/+*NN>RLxSp@xU2
    Z2XOMbٿ>,T1QwX5Y_^XWK;-HeQWo!;r8cSIi'5cmx^l]ظgǟɂEsBε1gWͳM#ǻƢ\?s38eSJϪa]Msq;b;`mΘqlLFj41u@Ȯ[KHv%Cl;:ORo&&FOnfIjlGNYyى#:}ےB;ԭcϹ5
    %Lp'_/xJc`G5_'Ovˑ5%ӢU##oJM
    q幹?OZ_r4S64~uO/.1\ggf(Z;w&
    ^J&S0cߠzYϬ+[<<Oa*ɉj֚6qF5%+|؍ڀf(7m1A-Pe"AkԊ=0;r?L(J 04k7'#
    󬐛m]E$	څccH٢r>N?uxijL	7ѤTO0LU~7
    fgdm!u[�Ql#
    տ=֌;auGp?K~=o6:ޏjIqkfwT* gYha!0`ԆlAG8΃;մo-Fq"+kd6M#;Ŭ警
    ז7)+9}6qHǔa$	5?eoHN)UlJ?Z̞onme][Gbcc0K9pHiqHI4z9f:2'':gssj;j$,癊E*tba8ҚmIqi
    M*"(6O0+e->>3>>]V[<Iʦ|%*-jzzDotրnN+VcR׮p{RlNx% +t,pهVz.'!<#UkmDBnjlp/5\ajj#.9vc#M,.):;gA<)	;)w
    ;8=f
    DC)aTQ%
    5=^Kw^r-xhH$:{Ճ/n(%;QH
    %3fI
    c
    u@lmM[^<~m[4C$�NXl„	y+tzpk䐫sut0U#uwo-SG6GŮh͛TAlV\M4ϝO,vk-ikAVQgƌ@SS#,;O\0xW1N(H^7sK1Z6NiL	 N wFS|-&E2.׈jXYP"/ÓPd{wR	lw8=&Cើ#u&TYrHءɑ3-KZ2'yGETIr=$ɘ
    zOn0+-.bp0uoetCt<cNSZun\~)1GFr?MKsk<0@곻&щ?h(${fi~ݻִ&6ݳ
    ~ߖ;]< ~,@Gv-j/̙svˈ%S[�PoZefytt^pticrrs;qq\9s.%wC7_Gpѭ~i "rk]~W<>n(ifP8^
    W!QWI@,N.j1}]$ϣ²5[fin6H<mմ;L3[lȎaک#qĈsl̸gfX{ĺ3i>OKj
    째*3O?LH
    n=vr05~-SQNZV.dlömgf!O|V_fy#^4{l?@*Jk_g`
    "Z8Ƶԭ|KHP''`B&&VLT>"$Z˔|pKCrRմ_].Yr=yWxh4i7ix#B4'2-<>l/@,4Qo[ȑ?n]WW3-3k&K}YBAOPWpkO?ab ŹUc6p'`?1M5l5G$b(2
    ]Y2yb{hF'\LQBw/gϘ^}գܺ,:3)6>A+Xѫb15֬r*Fyy>Lф<pYILҚD0#OEpW39ɓsGXd	oƪHRXFO555x9S⟬)LNu#b,;D"FsXiD"UQ$\KbP>Î<z!aGYۯ
    +]y$7WAknɔ;N!_%hQ_Gȱ!Z_v3fgW8	[5ks(0ne)ΓZTy'Ir,sVnk3{j̸r4Z
    .aU0V
    ذի\cuY2U|T<!>4IQCqJjXHrR)6L9ee4
    <|<QpF_WJ=\|u2q;Ypl3NK1Mo 76♦u{1tGN.s#&vFt=WZ|s"WSUp3bծWOf}tB4SLbܷd4zt"LEr;[xAz"!2t*p
    4S(wS6oLn-oc5.x-NqڹIG3	W$R'sԯ\}yX>w#玥`�t\yYafM[`ZҲKo|*$YS'7Zx㬎F
    nRW3ujurh"P8BԈ/="PLKK{P&%8v0	,&vD6{}qIjjnMY*vz6m܅|qW;=g:Ctަ49*]=W=="%TE^ێK{;[2%U5O<#4f[ϟua>}q|,IBn
    6bZGv?oZb̥P'#\{x𘴺6"??s-sh"@4cuZfۢF*"k%).5S0$."yo⭻56y:XO?ycNRJ@#9s
    2X6UKHQErYòա/F�a�+rNC%Oi,\QҒ{yȍD+g61+Δ:[:eXW!'])KS|;q%OI˺oc׈"섏QӦ8]v-Zy"6RQSC<OKQem\|%Bd9㇤hX8o_89pճB-Agmҥ7P3fT‚-vB4	ɡR_vpMAΣ6ndݜ0®քB*1nGJ+P٪eɓ18;=u%@oe3|B/;ƛGnFBvzvԎDNyk7~*קz_`y.fdWsT55>wp
    '`{]\EFsːW)ZZc_)Y"],l<W5YUA
    I+w¬]bw+EPݛC@NRv_kAAEꧧKŘTR{xL"__ɋdL>]
    H+S:Z/Sx�^xt/.FR_m}׶<;f\CG}9uN
    zaf>%S	lm]FA>#)r\PiY)1{a7fM2/)M\.p'Ek7k`lk/K]޾q"J4&M@ gz.N6wb8~s[']Be~9Yw9?ensiZ\ۜAnt֙)oBne
    {0%q
    PɊ=κW^N*j㎍.KDGZrOIi*:,^(;T_1	AŴ8ikkA{cgӰ]~[6%OON>xdHMۢ@M|O3j=lymŊGY;7ML|l%&֬pC\Gްu?L&<zRHɫ}LF[wlyYyb߱-uh
    [unkzi=멭ͬ	M*E/p*7wƈ`7n.CuQYa
    KXݦ6uTE 8pX{/0PNe>6!%;<fcuRq"u>}?Xj-|sMS‹^A%Odh@-_'+[x
    ᔯi`𣕑3++G^,傥|X䱓'.E^Gačo>/Kf¼_panSiǥ9Y1&2+aWHIj?~NCwr8.I0$9w6,M-_ybvܺ<}`1(ƈQ[mρJ
    
    ԲxQ,Ց3IPe	E{g�}1P[G츸̬i՟6n<%\u=Sz.\u{J}WG Ik7bmi>ڹAޡ{FHHR7}=>|D{>?O8޾4ʕ*zxv Y˼400G;?E?<!q^fgMR]tu'ȏ c[v!7=xks!5y!E&ݺ54umxU^4
    ZN[|~ R@8Ta/{!9\8#OOfW#85,C0D:[V
    wKShb|J~Q+OA
    žz?|w$<6e3%]L',`u1N!Oay$%r
    
    2);'/(9 S\&I߂*+
    {vx1dN
    !s
    mO\?nv0Ņr60>^}5wyU3+Go6$q	B/_ee!x!i:"a.PgMY
    :uHpy#c"ǔ,`Y$%`Yzc)'T+tFsG< `P(\\#4ru*N,
    oaa5I(ܚ"C9c,\>A*�r)qM}zWdnN(d'qz@(<{ux݁d(e8,'C[b	{hUd@.-H3sm_ij4'QAxEę<vrRDZCIJک?jlڴ!WkվyeUu^ٟ!cKJfHr)jk֬Qx1eWa+1J8z7~PL5->לwڑũ+|$j8$i+:=db^=~()z%DzHl
    C>bY=2So##cWdsaMUԏq˗z"hɓs4ܹXp^Nug hS7m
    af-A'W!׃6l<tMeCƏnkeXmH){~3
    ?g.(xDHu۶`N:q7XjVV~[ϨG߽-;~.VF0|]Ψa66̳™g49y.k[-]wg԰l:اCVst
    $
    нsiO%BgA;G\Z[.5ԯ+${Ney۩9z݌YXk`{'Q\KۤǶ}6L~
    K޲OKA~Gy9gEb|81�#YЊ}#>ݫbJo~FRz.>y꜆9C\\]rwcρ褻\	xWlʊm$%{nI?g_}ݞK7->kKK~3K!&.^xhv):IXҿxv!Y[TF382�� �IDAT\!l=p=Ted8u`-� x ^*X0O<X|b>}{zz"fujhihijc|!ж@y1~rg]Xڒ++ҩIJoo/sX?|"ruXIE~>AtLȐ<AY
    
    
    ^a,YU,~klA;|Z.04sˀG,cd|1jYu~d9M8TdRsIgsٸ;\<%ذ#xEۆ_N
    u'.) ʯQn|_<!|Jjq#ǷoЛ7ݝ0xwVVV~6'Ǔ2@Z.Ǵ񃍰Xp>qYe	:"_KgšDnns}gڭ[;'<Sy;wAM''wөwtꓧFGodp?;ύ&\Yd8bqkkS]]teY=	P~/?K/vroɶ-
    27e;3oWJ4)Ii$ܛ$/KN䲟`r&FZpD{+y
    őWȧ-9b.[RYSTT-R
    <߿O[1+es>]nB0vci΢|h)7=b.񐷶6!/;P.#/NҲ
    =lw۶I:^}E6mmR%Vf߷Ӈ֭ឥJ
    _)<gO@R#LQ	i$0luNG*5L]
    Lz5lb-04>6Zih ,I,qy}B\5Y'pOl>}1):Fp~9^d;'bqtfp'"K,^$:bsYMCBpYKMA{lCNO:6lNjED13P \g<}?rs54zm13aV.:Wry:f[g_lͶ1'}aMH6ED$6>P_а;󐤬U1lp=W5&|&E{:W8O:Z_28CD.XHu4	!gfK!wHWJ`ֶsƓ
    (ca;'̞j8`�4
    nsX)N׌`mzyڏYtm,WM:|gp1d9MCf(	2[$!  _:
    [b_prfb$!j!_*P+ϠTܞ _N[G@Ų--,߸,œ*	b9
    ,6<^c|5="/62r�RE!cNVJvRLP'3/<h0ZJAB*(su\%	#آ&ԖQDPdeѠE.U4-BX|C'@Ӹl/v߾*D]M-5d,~)I5"<\dGJG'n
    5vKyɒBHr4&%)
    C#bIjZlDu8SSGDe˿rLLi念_�VJ&_o011)_&im\8YVKv1h@qZ
    ORb<:r葜Mn'cG6K`ܺswVVJ80'72Uu2[AJ.H\,
    dg%uIyM530XhmW|f05):5%p3L2	q
    4/v];,,'ƭWY+wU\djnڸvƵ31TGL4u⭈~H_Y90ukad$ E1oj
    &,D^`
    z.\(M={_5մ8cl`iBRfΞ`祰?9|,O:\yhl`FZw[)^'wtVz8aDwnfi9u1ԘmG0鹴KxɓV߿|:h֥QsL]D_D}tY<0pr`)b<8WoqWW@en-
    h#zX#uӼͶܗw8~C3z.ՔV.*l/,9ZY0:xQouS;G ൰;Wjut=}Ⱉs6Y6,oڅSrxҕyR39Z5~X}y	KQa~j
    HʣǖʹplTFS殛ERZ3gWx^)(
    G7-24i	&몠ghojg7oj-IMzf&FHc{IXnKR: omiHzžv-[S�~c
    K5p8벖ZJ*wPG99vv]ίZ�Pϙ2+P$#X7`x?2/cޣVQ,>	G9MjuOѿgdfv2lwP0iȺ'=Y±Exue)jNNt\d35&yuٗ9/8]|2.hճ'kYCúd$]%i|&bYI	U,G#S?}ML^G~vlԩ+k|;S+<fnA۸ϙ2CqJQ-^\I
    ɱPѬ%3g2[.45Maa/Cy0U*ԯ共IOseޜdXuIG3Ir	]wIyjIlPz>Ozsy	\G=v\j	~.J%x;v2(:^
    cNYl$@`
    gpx"	;/Hmy+_{N\g^$+\1z^/@ϟz|(ȁ; f¥~\
    	WN8"3Zn8ZKSӾf#r\9{`$`].y\RtIŘ)Z͜M>5CCOwtvw_<VMZ"u5:(O)c5(7H	$ohjͳ>8,L>KVn[Ņs3o		|{=_u,E[z..}oG@ב%
    p~c,77oqBe2~vۖXb#urRQ	Xu<ąET#.X }nĀx4tAÆtvOl.guDNr95Rvyx0yN}ز	gʂ!B==f�w_Y2KP#:8k@;Uoڵ5.Q̎6mJZ_XS[9RNFժ|!OzaP]^	ԜZno{z^<a'0V^;1OSg9//	ͯ,aBuH]QURA^7-cHUWGHǰ^s
     p75]Gp+¡\|
    {xꡏmGf>l@Am/55ENX^#MȖ�kYtӶ.Vm7iؘa-mnaV#F|!ɘ>Z}ldL;ĠgݎG];x+?tY9"XՕc$-^Y[Nv͚ϟ+lHԵ䱭Ǐm|5lMK7nk
    [0ORvE!lg5F
    3_зէL-a,�c^X_J`.V"Q|n;gO-]O$\bGb_y%e/+[JqxzfCIyX'`ryA~!̏P/Xt
    lq&,ȥVI/>pOߡ=`|0̚idz.˓nի�Ͼqj,vMy>
    _t6Zcrp{x�V[j`lm7_nhጂ[?~څܦ"$Y|>W	59-aDEM񩪎)"y9߄	1u	-kqq?ge<ǃ	;M9u?θ(gԨVnqq+22{屮k?{.]w9IFfIccٗނB]Ag6ͨ+H.Dw! �n[錞<#Ο
    cc,w>[gޠk>b"Ȭ.;C'&VfO6
    CQ][8>@lckgN}Qz$O_TY
    /5Q`].9sX	淐V^O.6^7\F|u)t<
    
    U,]ħ/[ t.|N1|yRX,'Y|
    f:OXr.g͛㇚�}yѡ*V:<y']X8DuF-}/UsA̴0.?.JNNV\\	Ͳc($J;;eX9d;.{_v!1Lzvf$$�Aݻ|x3oλ�|ln"/'Ll"]ů6l#H'B~EzfOy|{H8I~b
    Q]&RQ-5εq2/RS\FJp6sl\).[JDͲ9	BOa.W…R}\Q#e̲~vAF|:9Sq}::R&nRoc-LD[)7n9vА9e%*;rY9Z:+g~w,9 E$s˴4 [M]xP$,=�;zaL';L�8I.}q
    *҉yP.CLSY Pcblޕ.,OIG߉.CJc0eD\eذoHK,zAZl[tSSS7?$'Q_{qɺ.[
    E|Ha{=~DӹD~F9{[<_"~&f	i:
    .wsuxV
    |2(H||u
    쫑+JIMME.=>ƗdplxQtMUοydq[B(;=#z֣68aouij,p'C8u'|vhۭ+'y\Y/Z&U쥛)b-2{GvU%ë&Q^okXG8:zq악4�^vo_
    վNC坿gܦę;Yگ>j:iV|̃_cf߱s]$==G#'.fQ5o;E)@q(uau?)R?8$p1,
    [eҒ$E!GeL/,f^,lJ;O<`9߃m۞Zb6�jdT	1%TEF024eŬB4?x'%xU�EuBM6:Ѻumx
    	0?୲)$~)	l1|RYn 7kA`1k'jTʧC7Փj*8L"MYy1-(+l6Y"+�Ek(M-BbNoѾYl1;khf`~
    L?~7_RUsJJ)
    �|zw2x*c ڡCƕL_eU.].RTeU	.TU:MZ4i{L[t~m
    HE%/h嫼Fia<!-$UT
     ý>3&w3~M�$"uE:*?R^V*i	:^qwU*JK-QJ`;hϝ<n'`i֫ze0,wנB|v=UYb
    ԭ*@u
    LM
    @qv_Tԭ=]F[ed>e`T8ԭ=[Vn=SY﹬],>Q^:8R+%Ezu[/)lUZ"jQoMG@CZiO++K4j~HK**m+ɅpTOȮpͦ
    Kzqn8(QG@KK=5"P5k4H.B.Q`)E"@cEBDK7^ihSi>q/}$Y)BG느E�A:Z/[+ȈѕjՔUUEF&-ڵ2c@@Y^`BCO)L&aJb@E:a	XIhF
    ֥�	]{WE?r]*S^�S
    ФAPdafև#{=P]
    "ü{R{93Ycw9{~;qktLBTHV	=nYT}DږA q܇,u5ծmh.H|:W&!F|d[TT?=qv
    ]^VxWQo$]*nP^R2`Kјi" wXg].)aI=h+a!m{1eT5[7ب2uLBGe
    /5.**pCF֖hPE"PѢ_�xx/g"-D(Due#YY923)cL-WQ[_﫩)*++իWYGEP_u%J5+M_*KGGG$,ˋH$Ԥ_/-p415Y[C:,KBxDx٪=y3ſ999ׯʚ_Ufǻ۹>{N~7CFw:Y)%II̥K(
    ?wz?{]c{OUz\qPqL%G*
    EOlڞ~JkJjCkKmVUH
    +9:ras͙ofߙ*b7b'YPxg!_Ж@{oKc_3`(=<V?+a2*�ޮDRdHB@QQ,J>1߱"9V}t:DnK#c0::6#`X;:n?qZoa[.0
    x0uPfڀa�_`㫽H
    Ew7[-/RPU%lз1C"zU3de0f͕ܼq,PXߍưܹGR]*l=E߉[-[(ͭ'SA6C9,%7[pr̃ֆ.S0lգj2q^#+_9/VH_-Mʳ+�� �IDAT[nf5"{-ͪj�QtuZa7
    ފ#HGΨCV&\i3|r{EOii$;}RZsUKM
    _=uxyIDz6`:I*!eO<D.{wYHoV'{>w6πq1_/I6kf;&6xqXwjAW-R%
    $dLv0FFZYY%
    $0]Tˢ=d
    w:VmMh#p]JTbwh:it(2<ЍRJ#b2-Y[[wRW7voG:RJSwo.dӻYln	cS_JYgY!@(YkJjCˊ=s[<u%q6l/.$Q쬥sq}7$Ω?	}>ҧׄ	Ki�x``&J)+ee4bxY011ю=d1Xooø$ޞF,V/L::·܄=,EfAqǡ{aRQUK^s1;Tk]ϧտ[lׯ_K^zwg7GNs|?|,Y`"6-
    $h¶\6wنͺMdnB<iu9ճPeuī`
    _یGcWxL+*Xm	64b3_/Ɋ
    apMT.t9qדI6ʲ?*gQ)rpGag6WG؛Vx⒕'<gWw?g59oxw76Oo)"<Kmn	KdbD5B6[{/bBxyhDQ3̙#+[P\(c-*"5sVPPk.>z$N%6~hp:-Ȩ馕IOMl[)mլxIαg-_'nI[E_񑦱+fUef
    	[t3Yd>'q͢sW?j5[yxxb>(H<Ek5g*Yф!yX3T5ϼYpYXV%Z/?O;O鸁"Y]Vr]$16&bYYYiQeE܇a*'=N=MUXR,(0gM/ؗy9$on8G9FmR<羶3ܒiN>eQ^p(%CE&sRWҿ$;Ѡ"Z+\^{k?P߄^&bfEkiP+c}ìlYDEuQQ36Tul8jw1VQV
    ?3?)e7127&߰̑箑	KItgN_xkk5]>0.u:6e,eڤYb5sTK94=XUTUͲV…#W(!'Ζy&so
    8}$.<~xgTUįQxlVϛJl>y׽uQ\/zk/ECVpw^PnZVqBƑi;._{v5#гx|6IJz{{n
    4rwvO{^|l+O._Rƪ5@`t.%񸐐0g)&m6ڨrRJiG٫a	cǏNa?
    {ݺݻˍRie%6|-?֍iKԊay~Jg2Sf\�
    4YXۓ;idqC<91US/=OiT&bwAq%v E|s\/&2C	ȇ^AZ-oY-6uFE]׵"(Fь&rX*ۗyg?6(<2cCRЦksr{;-?K8VB¥]m(
    `}[[sz\꬯?guaf	!_ޫ`Sr-ɂ
    Pr_SL䧛&w~+eLcr;?smhEv+(xwu!~&dyn޷;9f%V~=_dev´}FLtfx?{Y2.	?l2X&e->̯l1<]hAޯ9)7ŻƯ^J,,iXv)KV͚kO?z-o=Cs7C><aD|F̥@7Ǎh	2jܞ=uH-rRȏvxĬ֣qqjLe	iI)I^^RcPPPT\9h^^'A!߳Gn#u,4PX2BO?r;t534&N:{_NbbVĝ[g\GI+ǹd,	!S28MxY7I2~lB35\c{CB]s״z׮wdB2-_χ~QSyn,HE,>{ugaK8�'9[&܏9m[퐞*~r_OB?'P{&)}},xK*.Ӷ7Z^x8Qi+]{0rrR!;vr_l¬An?t:\Zx{k]I<na)JF߼s@ۯQTTNrG~+|4
    
    >}׍ؿ a߬7]H=M7O1su? ~<g5dOr7tqGWVVE~:t!w+~~kv-EzM6ǣlpW?j'M?`@0\"n_08L*vpٛSx"sE?4ʹ`
    <0/e
    |//ʦ>#96źc'voQWcM&NH4He3zluf;%8cٳLÄ]_^	^a2�l̫6M5
    D}[
    _PMQGǧ@e&lJ@0a]1ݦ7*ȃ9EVHAB iҾ7l{W#Q6o7L߆~V:-
    㽺(x$iģ+(FyvZ[&v$z4%n<Bx\frȳ<y/6
    k1kst_KJ*aߔfdÀ1m4d06]Y]FrN.^MJPjԻX%Rf�ry3{ZWRcln ~@?9-fWW63yl痶&$"м62Y+20a/_YrMAe{\l:a}ˈ/aԃt.udMuѝW̢>#a)7$$J#rr{6.?Xw~~
    L<{?9.=	CzS]D1;A<jAV]}=[D_%-a(</t`$Kt<]NnvbYE?x( fW՘|@?KȀ4=<EjrrQY)$KT.`_>J3`N03_NkJjD_l:hρm]M8~�ha)%*$|;BQ1be6MłA-7Cn`5ZCo~!YÆ. ٭#zmNNN-&Emշzᴶv
    ʶTv#~<TmA"DqCqRMM
    eYC~LL|_%O)`حP
    I}}2e0L]&AJ3@m⪴djx~y˧} Ic�-&'ɕ6R \e 1z
    
    *$>U,5kl\T܌鮮i1ˁ6"=]{x_YHNxUQQhx%544�@??m`|z)o'R^1rj)ٱ#.Iwa))M8YC_~
    R`t~l|}cI=;BHޜ@
    {5h^�wh޹Or;ѽd9c/8޹NcĊ) ˱ch{uoN~|mFinkK?7>C-̝4l!|hBmlvH'7
    ɌaoY)H] y	ŗş|"{[kFFPW1lԒfOGrcgk
    b.͏65n6f֫
    
    VM>j5CZĤPrDq۽븩eưYQ/{M
    ݿ<k
    J_J:?ma+4&9r6	V3իU +]NR3d?<	tb1YwK%ϟW}[[?wwWt~Vn+:L;?:(U
    ݂	犋aZ)G^;$/zR.Oͱ!|;߄\Jݳ1#`	qE8k<poF_-..ngT^ktx'X~ė̐V˸Z{y9.I_ο6&byee][,3_PtVlDI)wr+0Q,*@g@x?B.>7 t3ŗ?{mjԆT0\VK(L@-+7/MM_MM?eE2鈁[z^VaT?Cxkܿ}eE s-U7.$>Vaw1mg8/aUco<B5C4VO	`]jjO"E?	aGKL0|$N
    dss#q<ge?M^~!?o2	ޟ Ǎ
    KNCM~/(㘑/!$e2mw9ak[RJ,Ž=;*Nk9z3Do:bU2a限uޯݰWW
    7Dag7׊7ܪ7o~z%)�KA?m=WlD!\F&Gi~~;_Ha_OkǝBXay=`kLE>#BjpT˺OoIDO
    bmXt
    ן;:gپzr#xUGs
    !ãW
    L~忬°;a)kpغ/sK\skhN,+Ȟ;$t<eˁCZaׂQ:Z
    uyO~{'۷j@C!UxO
    uﳄtM\QOP6Ws
    Eba>L!8_]^H=7Kowp{k\"aL=Q,Yk0YdӕlI}#@~bOSh{;NfiaCAD'5ʳA!?=p3yׇj/XʣG:iim}?)11k~}v'^M9uDmD*C~POˍ[s/{'AǷGQZ:fk~
    Q^У4t,XۊÔi76+V30"SVVoA4/a*mV99,}lYRX Lx".&ڒ5zYr<0�JJyy/(`,	a/(̘ïZzPr>%Yͥ@Hzh{_=SnMeƋb57I%[ O<<jZJL*n^a>P]8b:jJ~MnI(BKk[VJ,hO	:E:8P"",^}_+hIg7nݞ!*2ΖZˢJo'f}H𴧿8ۺdkK6j[bQ%rr?̉>6-*ٌO6Q{OJ~)0A6Gy&1,.N0i6Z@ 4SV)�mw-m<2-E#?4(]5O솠 02d;Aa`:*`.b&%h9a%LK@Wrhqґ͛7wd%LG�uu6nAh0o;Y	#o(!hW3:|*@ >UYTjWCs8#	Nlkw=C@߰O~ִcd>( >Ȭ<lf@#JʣM(1zY7B# G�D g1J1W3%|HYh"]1A82~pw#b(!A@f !fh(Oc̐F\(=@f=D#0!
    p:`>Ҹ7|!@fC" `c$еH&Y!ЏzoeHB�! �.5["|1rJ*DQB ~-
    M%’B9ڲUb9+	GS=c5z[zpnRZ0?oö?PO6^HӍqĤ0*.#@b~'1`Utax7}:a<
    81Oh%QWψ	MI8P]eC<v|DKX唒go-ũGk'P}'!EG66"Ѭ]crn[ vn9ہk\wa283GI{i~:&▸<۬-꒔~wqtz.#{YrKe/$eG@A^_+<Dn`|ok{%@)yLC%)[%Ç`WGO0a*WH'.V0aASJZoU|ڃA²#@.$@{#{Wf2R|= uٖA220'(rbW{gV.?;KJy+e0,e)X3vݙv9^*$+.v^1tN5AThd9}!qƜW]͋
    |Ӈe۸И9H~M_]A)r'D=JG:[]δߣ^w=7ŷQ>:OwBC!F6�+O6/0K|坻l<sa&ן
    ;6.1*�� �IDAT
    =+֪'OksNQ; w⵸Kn3
    Ru*}uԤȓ	wհǜu#2|}ӰO9Qx"yg⛿N.bB6@P7ݰ3gJPVI]t')hJLPS�&S
    P3Q߻m.:;b/&gԳXõ-$"du(!!hofĤF؃(QN</<bu_p_j *fSvNVKœ߾}ZR/xAm]d
    i܇1R!eK
    !+7e+*)ݴ*m�YSE]Sp<$۸bk#+7ߤ6>Cm>{II@}޽k<pjh*utC#adY),7XF`D0F`HS2*M>pq чTQK=|^
    y5tOj%_NL9fbK^9F@ʊ
    p( C|8,}-M/5yQW̜|.5e@^;aZ}i2Ħ?!+++߼$gj4IB@#TU&dܪčzRð[q-1U'FFOւ
    VKjô0:X%\X}n^W@DM.׷\{W0A	*?{]JdfwI
    qf|^ֿ°褠uBb@{c|-ؽ#aaX}#p*T
    ;zVj⊊v`j
    l45xiL0lIB4Im*TaʁK?<r.+)W 8ҘoZ4ž/)C~ҕKj.?č+/+-IՄ9$
    'y%浗+ޱI]%	&&og0^xO(H@@EAu=OJF|�.~&.gbTe'.hʓ>K7ZFO7W`6a`mj1	{~Hm|ㄒb{-IoߥiÂj,|~9`n/jOÍod^bS^P66c7^C/E2qQ*d\zyf߷,[K%,x8aޞX#FMx`3AMox9su)!py|/$Wq(
    !.iIh`-@ePB[II'>rӉBJD/aPbHP@e)FzPGcdOH|�:qnYEWf\9tSD�z{a~sIM`ya)
    )qY4Y\JB[�(+f\۪`F0K|R@#X
    ȷ,JHhfAv%lG.31a5
    f,v(B!(OavtvJ7h@[	#(!"9?m A:#ѥd"|d^pPAzJWAWq ]/^gg(*둈r։0&2ٰiFZ*^梆ed2^m۾cvNZ
     9xbdZ/LKr}~0*f:ݽ{"Rq>dTjrZ+Z1d/Caم=?{JٛIvWUF]i~.<*zTzY{jZG劍5dzvS2!)
    9wk-2KXnIjRPg|G[Y5mqbe?\6|(GOU9aZ[]4.q7}yu4@)lo_WC}qK̸k`0π�l19jhJ5,Z\$|Q'
    Z$DAЧl
    ( >6-xM DsY˿JҜRyne/`E(nM-fkEQ)%*en`T3@"�XSAakW2r[
    O_ʜiYTQ;`WMnbJ2Ɵ>YCנ!rl#H@(:lHN6ZR>aj6\Cdy^keƇD$
    $dEg#Bpz];9FjJ/׈Å=%dms@\;߶ڌZFhou^e_7.
    {i^Od&O^dzx`-7	[]cAIG\:.~X*ZʊW>,bXcٷ+9"P_~?C; |3hbѾjMWVVtf7<t璗/)A,tB\b1L
    {*?XД@GUU|z$C|bpX.4u:'g25L|w{zF5ml
    n,ECu@
    bU#IAdu@z~rUFޮq*cu?<^HJ-,YhwpSRpYe!^])*sx'1iVc*޵?&΍@:>[_ڀ1JW.~]IM//I@^
    DzmЩS8,j)>+)<fǝ]:L]]YL1/	d=/Aж6oyOTQc0	[|m6ͼ"
    	l\n.CHc+T'镆jaL
    F&{BjSY𚤒
    V@P?bAO�/YA?p~^)Az!6p(*T�cעwU1ךj^RreE چ7CﴍV}X9=N2}1SOCT	+(Կy[節	7Y@ήI 424CLi
    pG|4~^O	 I7u1)]2롔HzNHcoRb
    .zU
    'IuCTƤ63l9FڋhN'0B,Vd0
    M)t,{`oɭ=ĭVw5R`gqϻ*0N]$g77KoyAPaWT22L|*u&N5]Trx`a&	J1 _K[2K$\47mCEһVER[4nFee^2nU6m6+ tt[1/{0)<<)%%(D_dlע:BS?zh+'fNb
    uW}pv3Fȇ5ݐ\~I;$Fǁr}^6_[G^G'պ?hK(yZqV}U6ۗ
    oPaDibE炿&RT%IF6>>2/Y
    :E[=�v6S1tCi}I|Y6B-/'ÝE!h|~0}OXXt![p@J*m6:,%% NÎPIU@AhV6̠#6T@]%Itd\6oSl2Om3P0	#tӦ6XA7F~ABUKt+FFOR" ",(Jt=R@)Dz�6T$Bo]-*(*i,ߟfP+¬כ&	s?&iSC{J!҃v[H!*|pUjC p:m@#bLCH?_5#q׭`=c5ȭp=~BZ߉uUǏRwx-+TJk|8~9՛/
    ӘRyuFBI0
    H``NtuSA�w@]]-a~kW)4n”Xnr`թ+Lx?Z4PI,
    a7KYܨ	T/5ח %`
    \KU,L:~;LХp;\h;,e~|.lQ@!Xv?~6]5[u
    vyb'~z=+x5W>lpVmLORBdBJFs_;md[~$J$$(HgӁDp}- fesk;&NI	BdBPK/Z˧!cOӈ??:&_s`n/殤ۗOnR!Bpat,DIt;MZdn`Η?{'x/$ֺGŃDeԸylUƾe3l9zQa镱UTvW?`o35v;[�Db|qkK@HRo<	ctByB^CI`/CGh1ƾvU�U-Kr3/.GKdbWu(esgz2Iwo^S|zlͳ'D'<ZZQ蠣uNMal~a@O~rWעȣD	E)ȁ{C&Y:';lf/>vmdYq,8K
    Xί͆Dk*b8VG:<"dHHSј9ҦCʟ)We3vrQ%b.3R.ڻg>ʴAw"ǜ=0.7(56#5!sONjrNvvu&V]ign@ܗ<=)lNԸY[N?m$jXG@urM"IS@&bЯ?]G! \9\kkyPBãTP%%arjJf-KĀOe?˅([7xhrfrj`2&�+Hhd+)ʠ—).P3#*qqzhYp=!2JXv{;F7�%L.ڕl-*'5oN.t)]]=eMZF``8ƛY9q?O8_
    Nͤ$gւEnƅAXBp`KI/8ycL:D<㝔(>Qeu
    _0)65U~
    u$^fW^y
    w_N7ÿSɍNJ
    :XLƲ+)a*BLn*
    EnwO9췵%b9	SLgW$3.|~},'s˲^|E%krެc2[QygCƘZٛ\ZP1Cuq6
    R)o^7PUY8;DCŠ)(+x6
    @g㹀/}@91F}|QRmͽ@0҇m	3Cݜ/9me
    .<\*qǝkM:g3ʤI.O8b0d9>vld8U
    u4(At\NWVVVðN| Kg _Kqѣ}=[E{�3i>sNsR(a18,]z%
    fksj'‰^\
    p
    ?ly><i)S}mpfH	&)<~_	U'%xo(t8;p?ׅ9X<Y^^Ϥ%7{=
    
    M2҇"h:|n@ܡFKdwG|Sm'0"S$UßH'E#u^3;?asniFY㲗	yEYeKO0"P!"A9a6<gt1].>$yPqeh7	9}!q-N)St22/1)/a(Nn^pO>KeXz
    d~$צqk,`C+nN͍ȥq+!kƧ=&qz}kDW.¡铗uUXz=("L^Q7f;2:*ʛSfU'h�V~A,yw1mLlN&fJ4](DK0+oVoSQWQU5FeUJL<(YvnѥkoMݲjDdwm*(tm(M ʕ^#Ň
    paCQA%(0Y[̗ӟ}!VlAP+`4HiA) TT	]I<';?h:q:`kvRTVĂ?2ka?|>,`.�2]M8z_?-?<B9e*�[o۷@WXt}+Q[0"}�B@�5!@|@F�&FvcbrN[saɝԖ[^mcҹ煷BTqNm
    NIr&,EeY{"7/G,n,E%2"5CcFj(ρЬQWψ	MI㰺6G
    :!7ʮI"":ԸVtލҐS"f)u-4\dˍOϘ׳?9Wn
    )/m(!i׏ժ,X,\l00BOo~D*+uj%d\˗vLJFo`,1$f$.
    ^d�By>Kw󵵊3W=?p@W:GORv״{Q&]hԅYInSg
    #7w#lĀ
    RIFWWPt8φ-;[S|qk -)(]a'
    L%cRFDmjٞX:v-5J'ѥw
    ,̷^%1O`{"w/I(-`1ٚ
    
    (2%A@houVL	99GnM,#2gWK[Hl|7a9n8Md2Q	'/Y<|خ14
    @EQY9/X*Zʊb3pK7
    kƒ98ϺʲZt|`BvJz:,.Y7BWNM:6a4"*^X]#-C’IW2=pL.a@sچG7d(7`2V_j/$%Sϖ/gLJ0. nH'BVSώ;sV?`+B
    
    e9JJK~<,PaBvJ,:
    Rq֚/@sc)	""B Z@s¼}%<�} jD/X^@Rɫ`|nn-dy~~ή̬& 2"b$D:n!g$'>)RkMTrK%kalhS*H]Z#f!�B@:άCwz~��OIDAT|frJh`:4Cm1쿇#k7
    5Fۙ}cr}0||P^Ao節U.׃M7j)zU-)<Ho*q遅c2K{UK@/a(!h愁AzzP"sSu;u8Re''h$;Cf)wNJ9U޾=Waw!Cb9$jy'_{^a0VYLX4ng%@tT`
    `P%�#9!Hp*aܚCXjkͨ"HbIL:zj�ߔ6KC}R(S
    "|pPu@Ҧk΍<T"	1y '{AB@Kho009Xbzm;'1L!U}?!&wٺf灢,MLOmﭺB%w*~5̋&d?}cBQ}YPPRl,L
    !V1
    lܣ'g4M#%(Za3ӸOG<͞8h\3gw1k1_]ԉ'@F)q4b&|Z.pe<¤}N[tYTP!h)hrY0BDN(簷^
    ̠#6TՎ=Lo8jNQuQjMvBf7+It,t<"CTDB	nDX!HfQZ.RpP@-Z;=^x=65CYzqȔ)J4'=5ZCt�ڛo2pkdG{/M/�BhoGi@ mi	!@Ȏ�}ډ$a_F~
    wh
    ?q1~]	_,~H4PA~^g?
    5\%.#ԆT"mַ[H.}iJ}U6NU=\(\Wb?OX&\RZI_L!K*J~ud|cH2qPԈ R{09`6Xֿ&[q3`A@"H!@2f<֌ϫH_20LYUvYz.9;|Sd	p³a
    tȂZEÆP=k>~0]aAbLᷡS4A`UMnE[/JXS"uz$.ԯ/"v9FMVIbrvyT?)AtdڧY'D|\vF3=XS|M82T+K=_.dx~
    cWؼJ^GbGLH*(.͗@lDL5J"bhN[/,�9#98Vm2,%]8jjTGMODEA[~g<WRJL}ݭD_LK#J秝=Y}$9S^%uc+YzIz!bWfNgV%7qq'TϜW+0O>7_.HeKړ+r9v|L-KrNo~gS]ĭ-
    ?,;Q}  F@�|[
    |K/M7�/zL%cvf"h[|#~SQSiҬfYj0,?b!g__pGE@@,E9g>Z%$M�~,UO=SYy2#bw<aVI
    Xί͆Dk_g_uW2z" |M:+Ddc;0YPƭKnX,&@{"7]4Dɝh|ru_v'G
    oὡ@4@{ÜL|wq3>QVɠ,7SU17fy^UCƛRlnLԽtYP/{n?nvR\	ґ[^֎`L/t	jjcl	T3⥚=2'{V=<+LIiJEEKW@doHwG	J\%52QXô_vh$mzK۹r\4dK'B�! fցr[g2=Yf;tKM)'%QP\u͖zg�}aRDt8J:WBAb^�|n=qZȷ06(k7c1.ײ9x~+Q/>
    PUǖ^ދ`8&l:q0û(
    !Fݙu:}1
    ?xu'[2�&LpمHSY-edܟ9+t6=KBP+P6KpӅ%{'S2Vf]AYB/").-=Wc09e�#mz!ڛo8g_1l]bAX(L>+@fU Nj'sG%0iKGK^vY|&�]xM
    1v*`HChJ~052"G_,IŔ:gy_࣮V`F!'p~/dWSY<H
    uy˖~#hG+	\t&w_	U
    �B'OyEF	�`]|.Xq􍧞~BIZFVWxڮ
    q7\fSA	Q0M7k.\ڬ`jQT(ڿq:Ęq_t.]^\c+>ߘ5b+;zT'Q6[cXŴCx/Ҹ~.ј.-=d醆j_1YKU5}RBgލzީR(@HA;77B&.[ʷCH0}*AY0N6`pCK{\!"uhRB	.eKU."5!@HgxP@Bu-MU󃽳VkCWY�B":~/fڝůӟewػ:@t@Ǖ0ɼwe�B=#>W´;@ "̺�
    9ȼg5+L
    RnSb57XӃSWo\NhV5`"3/D]1>JNN(!x7Y;}tܻb/J&rkw`DFb
    qC]+셒&�嬖oz`')c}`T3bb!~-k-
    g`#OMcƜ\1iQ(xYظ_BIYA	>'fa-O"_^BceMnB-EU/TPD@{6]30q%b M
    %ME.DII_AA_/^2jk1O)bY%U$N#DH/Ѭҝl(6T!Ўh+ad^?[c"EocF6YoKͫݞ#VMnb &d?}l>/|cA.CLlUW]nl.Bf:ElYR$g+!rPBL9'*q
    ˾piR
    
    ɷ3=y@(̻7`{p>Eit;MZdnU;_\=tJnN//>/%8�]/y2׉X#xB!Bݎ֯\oNE-DW}8
    #.hbfoeZfSyԕsƃʼn`gS�2T&۷T\0k9tΜ}+
    Ok՞O}GE+,L!|'sq42H/4;+y/LS?9, !f|}ӰO9QP/}}̯@ԒFC#<I{17G??s>B
    
    G#>:Ew.xϑLxWzM Zh,()?&4=:wArU_YpGׯ_=uJJKrTCc;~䟱M]7k97ΓATlM{P%:RCY	QANNky*
    OH%'isx8:j21R!eKJ*A�Z3u',/'t+7??zQG!@;t:zjU*MY,%9+7Uk0~Pgt!KJ.7W`P�}&I6ݩ6=u^/1/%.
    T+f洛8r?!V7ʊ|CiK05pO+O)(qk\Y
    6T޸N.)^Q{P_(3k{|N)plxLO�B�em8zz{6R}\r7'ר{D{jY**k}U*fXl`)z5p,^̇)�(`Ho6ߎ?t))d7)PŸM`kǶUUz|Wr6[PlЩ:Y(F!ViSa'M"w7UC9!h وlB
    C |Xu0Lz\ʡhpJ|;̅Jȉ6Sժ7č_NwQQM	UH$9gَv0>�n!86KIBq:k9,OՄ9$u
    %=ɣ7:⛞}ij6[ZR
    
    ѬYL9K)q(SPmn8B])KuE:08(Qj~{Ɍzv[S‚Ȼ�Br ˯#9Ёպ?$&fku^yWcW'Jۍ>oPiѿ.DWA^K.Ò	&_Z^xDl,(I)ZFO'iܥѬ{Q۝xd^bS^P.9!ABqaoCHWyAT$^0`WtϻB!{6ŽR5#St$u)_NhtI-lƋ-m�<zE,#IjJGtL)cTV_;É
    9ly'sw2o9BX#@R-(L[ͦk[i֭9_Y%H�!qhoS;WRRpZ5AǤ-wiv.(׾،<0mV6ͷ:Z�8aJOh*�B�!j jP@k zk@ �25!@Ȭʨ�B�!j jP@k zk@ �25!@Ȭʨ�B�!j jP@k zk@ �25!@Ȭʨ�B�!j jP@k zk@ �25!@Ȭʨ�B�!j jP@k zk@ �25!@Ȭʨ�B�!j jP@k zk@ �25!@Ȭʨ�B�!j jP@k ozP�B�!*)+Q	c7����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/caching_fig1.tr.png�������������������������������������������������0000664�0001751�0001751�00000026304�11035423623�021734� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��X�����
    ��PLTE+++%&&MMMgghsssx555~u[tQzfzskY,Fe'>YomX3Opc{fy1;G(6HZφpXۂv녱噾ږ4L~탔4694AQ޳ҽc׫ҭͳʺ˽ɟgܤԶƕx䣽ی㩿ٯյu둷789츿㝝EFHNRX>@BѷsUUUԥ]]]ӎޔܴp{왷١ỿĢ֕ڄېwxxkke&'(Ig\SkIWhIOVO^qPrLb}Ox  kkky~Lpwoppaccd҉޶쁯��imq]`e���333䓔ʣ:::DDDU��)IDATx^ɪ0aλ!ĐJ`CDW3������`l$�((k�ϫZs;Ƴ˚/UilV{ɱ<=)1je%9b9+PXH5X
    -yvjsƸ{Bâ5R[>uu�cy"!Gk<+\b-rYa?{U2z)RYS`~NMja(MA?ͧJ߃iH\6H>g_!E.�@Y,7`
    )
    >З.?,VNDǙ=%Yڻ	ޮg8�0�E;VG(R,~<+Vp-^_!BX ,ڿºٹ6+_ҲBJ*R"mv7nZ(I+1IhHڴq'U!߫@3Q='`H24vr~g=+�Ӎ{VO{՞{..,A0L>n�Dl1mA
    h4Ym~dz},}`,U`b
    ;]z<9xN>4pЬ"wbDl k5Irۺ+("=VJΠ-+^~5d9,NP$+i
    Λ(gt4M½'d,p%MҸ^ⲉKT 1("ݗov
    P@Sc,6E&'=W~$t:cB79OIOUeMg[?~'~9di>d@D#NO<^)m^[ux)dbq]Ew5ƢF 2FM
    QMґX&Hoˤo΃a!4UdXlDR-wڌ`¸Z#CR.MVjgF^etW--\	lv?~7٘t9Fe9B+of<kBK`b:bpRj<^Y2<]jNʎBcQ2ťi]O]]ʅbG~!ig$�>$hM^Yf,k@Xn;lHoNU<hKY7 9sΎ͕@R-zrɲJIPf)*"}t�dzCbE)4vyIÑ\"DEN|
    ү
    ;)U!.
    $שRc<XOѐs̭U(6jġ޽Uzh~tCnQ#hZ)nPY(4i2i\>*<bu#c% n)&'Wh,jp	*޾XiEv1>.OeÑ=REV(Яݍmkl@$(o
    |<UDOZ�K $:4zvfa6VO^av1[ 	nhJ P);XU3(n*-[Ӛ<(Mp19!ơR
    icf@eLhcǧe8P-Qƪ	s두ڍMe*X,4},&DrLB{X�yOhN6ҘL. 6@hXobPdd]\
    /,-3b C80ECNÅO4am3!puIU4f(ˬ_Ghr!�zdQSvK3{xTpH^ri;Fk6umg`5SnU9܌>M}Wf\؈oo!kz+Qܛ)Tb&38g
    C
    ܨΧ5YͿENә|>rK>LMNtw>Mg$>36w&6Q
    /-=t3KG@d�*B1ڣER(~4~otILw'S鏢=6}
    iSs!;
    L/0{){9zj�,0{鐢O_A#4+~"5Grn<3|ҀE8Ȅ0j;MC=jm*lOf'@UbD6iU8E翞DYd"!.ށm7'ֺRB4
    "@FIUz,,g!Jk,%\*f%/J)Ā
    ^m?4
    nP5qq&fT,M,/"Q�ZR=Nc,Ad1jc<5ƠXPKO'M<>�֮.`m~8q`M
    ,pxY1-!B,ߛu7SIpK
    Ӝkk-WցU)Ʒ}𱊡`DWRe{1#�vC=1[SelazN	,N'
    ѰG;*Qhzwb\;BY~N}wց%T+9؏ܴr7fxͺ,M! t?#%�ILK*޵7X@V{XFG={WRtŽ7inՆ<@37LY:X0ѼW&XlCwoU2QRyhb)EU5)צw`PY
    (�PV8{CXfqϕmi6dRZGuͩf1(k#ƊӵH`"l:GD1M1ڑPJӦ(H>njxSwiͳyZRgSӃYSdY"KZ:|�]N4A9uJOV$eMu0D>yF#YU?kK!΍;[ŧ	p^R)@].:}VtF(m*Rg`񡏨Vuetڙx.Ivf2]밇"n-O2kGX,
    [2FyEҁZ	M/hZgGdb=%`<"ezRWwLXlM(_bh~bn'{{_j-+oX:>56%~yˋdlvgm"hw`5djAŻ~
    wݢb8o&lS
    $hŤ%,(F;`RqshPl(!{=K,:Q<,Cv:z
    |`ZҖ*
    vJ8gny
    9K^^8hO#Xyou{}9bl$.oC!(b'ȻդBv*5Z>+ԑU]l7	_I|Ie+Iǰ�@X ahÑ:s[t#4Z4;(4
    	 Bk5>sJ[c[9aE$/qP+`XcSCWSw)lfPDjt+ņ)B>(h,n˸U"P6MT8[ǰ睤9z
    ٕBI*rfgYM4V8+
    CN~Hf%tK8n`>",T/ALmydlzyVYaCh[XS|RгMڡE}"K(+22	XSZFy?R
    q>OdO
    S
    ŶXe/+~WN<B5."|@cWc72V)	…_W+l!/
    9)o'~?CX@~>|)m y1;vh
    7ޡT0-lagOC*}^c@z0֤ѧEo&,ftl)·3;ͷ[?,T._m	L	v{'Jzp04sShN	/"BkgiГJRqx‹e@":kR'lK_)ትmIշ?{
    ZSvH<׺}'!bXlqitmam7WDxγq.R^>bb(,z'QZ\:6`[
    s(w.:tp6/jTr6ͻ@+ߐ^AѸZ:>(`2ׯB8_G�zxiBM c6I"76@'%r-2-HCI͓A5+;R;2744W8lY}?-q8%2{X@FZgVx6{}y:*OMV$=CUcjzۨheωc[b-2B%vbU"QH&wI)Sx dɢY2SN\3ѽskjpm߶ˑ
    3`G&*ߠ0T5U}58_kr^Km]6�+Nk0k;K̬[rss}�Kxٓb!$ 2%St[�Q3<3>)ظoz�Q`ϾըFw"qX:
    D%]a�б#$f{].z-b_J]0
    G�X"xRgWP�,RR% Uuv+?
    76IKŒKBc	o.kRA>:[!ȻsZuP᧭}	sW̰'Aޟcu.EY0ݭR%PwmHz`8ގ}r"1wx8or^aG9O}lo+�kO䝼̰\WE5Va% Y6Fart}|.B7a4gZis,t,>0Rv/o@ EfnҼ/e AGXBH\.tB�mXFˍ+�0Au2Bʱcꆹ"r!ĕ":mp\] CqYip2dZ]_V]MFBe\R}!Wx	`n-oGB RB�D9γ@\w:;/(Cz}!Wl7=%yǕkFZ-K(^xt,aq.UÉl`Vp<F,XXt3VUBBDF)V
    б(23>hB
    iM4U+9B+`'Za/=;�2"$5se/Ѿer 	`	3,huV^@%}ɇ
    HwRB
    б܃7_/=jxp"0xv	%Nn�H8ј{|; ,縑ywJQ5*<sQ:|y,wX	%XXܘ}2`>4
    o`h̺{.aѻ+|�e	r}a'xT~qI
    If!Z‚/֍ŁI
    Ij~Ұ?
    I(3k.Wȼ#ĢԨ}
    ,BtP<ͬ^]0ˆuJ1
    U-cz*W� %S:~h
    XtF쳼h� i(S�X
    fX":VHMḟB;Nb3hX B '}}]u,eJx.aJG2֗V|4;#&7@c	p'KW]�8QY})r+C#:7=7,�[Y~ 
    ǧ4#{\M(7]y?3Ck|xEhɤ/.+T4Myv_hS1P	AMha&0
     
    ]OMZ/Χ %םIFb;!^
    Iڞ<q/Ս7%SӊD*?G[Ji55ii=9z*Ȼ7X1{k8LmBswBMzb*v`H6m[Z
    a
    V,UWܦXݱcs?XËsi%X
    6HWw`ܲ:I,B|FiR'X5ۄPP71%s	AdE6v\T,TiD:
    s		BMWȸ)'¡MhWnH!W.Wq
    SS;ۄ*JՒK
    Zwƭ3lBBzT"TFH&$}SRP!X
    cU,g:eҷLҏv_Ƅ
    37yȀՎWtu&m(F!B5Vu
    ĥ�Yt)Xر.r턆LȮXV^�O~F_]qSVر6CiKLhW#'g˾ +d9qFIND{g6q7[$$-]J.4D*/"m%SP/\6u7ިȵZUM
    %)ݥ.[ۚZ&{3Rpg<j`
    L⥳s`7t •qj
    `IkY:
    ag,XqTjHjNoـEʛ]~jX|U)KUU@}/
    ,nPC.Q`_!
    ˴t+XM4ݽ
    B hL;7coWO:,{D+
    ԉكc`ΩG猇5!ӁuPHQbx WZ_78P-yhHG?сY4_o+u䖨HKx~K"gm9eEɯ̇BcpLى%�;įʻ^Q"c`Y_S6x]yJ2!V
    (rPVʓr	Y:AYW
    ^8)f;7`fk.RU']c4	Rp3˗Hq
    ͇cQ`)4_>2>~CW6,^g	ac
    ԵڃepcN)QM`ϟ^P$p)7}Y:V8"`ٚz@
    ^ϠS9"a_z*G,	\{,*J:QK=Xm|"`gZ-2r~cD`n;-w %!-p
    7Curb49Y_ccKu+ b5LN
    nsj!NBq ' ҁ1QcUzWos9V6t&t,Kb
    j?"]>sԏ=Fy{Ho/\MyoaiFP\
    X=,7Ehi0L&ģPxls7]<&%3RR!i5q'LwXR$J:aOtwp+~'.Bt5^bfֱw`ew[O>5'"n
    Ta$籚]z,
    +;Vq=zC.Bӡ[)vK:e_oX#yVN?OӍ5$kW%bVBQGIh}quɺj
    K,z^l~@cꍂk"ִn(rS+3W5Q`Etg2#?/~@f')57&F\xp|%P#18\M`{G=ǺB12
    
    cI8ݹcqj^1XރGj,{xY+7FPm3Vcyw�t`6$�Y+b-X5AI}-ss޽2XyrsޥXF5.])
    wVd|~(a`λ"1֜�<XjR)XBZQJS7@:XWR8<{r,Ɲށˣ[/נ⮌8=B!BiHAٝy�a=Q	`}5f!yw@
    Qf@E@O`-BD$PH
    R4^(5nZa}:|SM<̗tBhsmwEF֞;
    彣;{hR.v\�롰PJS"t+uXw	CQ5#Z.,NR}YtS\|:9Hb@#D,xhAXWx3rnN>ЬB^PWXKI]\!ebaU(KO@CK2$qU$P>?W$DT,BwUV;1*I]>7PW.
    =e.X4	-~i;-,Y!ƫ0u]>4̰D<
    ΢֑B!r�gXEYa<_*;ߧ#NiwX1	-aL3.A٧+(CEHB*4LOйI%ِ8-L~JP2Ah7?ƞ>^MGo|gޛ	бk,U:z&	R*-yģ!Ky,UAgAH5`)7士mh~{'}oLW;c>ybHD ?7{g`)dx^@u^gߣv;Bdp|`AnH*<8Fo$U+[bc6
    aQ?bm1GN75`ĿU!a/i`ez,Pmf*SӃsQ"(Pc1s䰢(b(azh:6{e!bjfwe\a-R
    P= 6n&	GlX˅T[:X*r
    z@]~1N.Jr8HLْl*EkX.|No+TFu,}go	R:>Xa,ْAJ;t,
    TISUTX[g?)LBb:p_!	<Jf\*Ej6,-�Zx&G.Hyl5#5
    ,]۟/Ξ{%˶{5`%/7ZXz,/��6o=-}+\qڒ^Qˏ_J
    +F(By}62y']Xl5eAY:,U;kdBCnpzjndB+T2oV<zkc,Ku,L
    (б
    1VbXlc&l^nz�^SJ4wX[rb,XɌAW{!BZy,7'<۠,X	x[V!"5XP
    kC�^ynTͅX�NK-ud˻kc?X7^&X6oт鬈]yTt'[7X0yv*($S j*Lsn�VV[u�t,gYO
    	
    =JU)EiwMSA*ęwedM\~gY!'k>B^!|Rψ=
    1ülBr;T:= `ݠ1<\e`r:O7bcnl
    ͼL9cajU])Dݴ4zCf?_ln6
    >VI|BBH	;N;/69_~�`u챽Nj;H8D{fjKmVXcI8x
    "(4=Zc�yǒjv,PXg
    t,:xw�@NYx.?P6m�묱	Ցǔ_c9-U~Os 1TrJ"w%#>.	J]v}O?coH���?9J������8L����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/filter_arch.png�����������������������������������������������������0000664�0001751�0001751�00000004553�10671421551�021275� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��9�����[cc���PLTE���U~��	 IDATxOLxɖ5HiixhU`"U&C[岇,T`I0{/TBJza{qDH[Ro=*^o޼?d3}Yw{{߿7!IKZҒu1.#31z45O~v/f$t}@�]AfpjRcFwڹlF$F@5	QɊ@k%G2=P
    ?=^<̿o(C}4}uPIu-ONk֏Ƿ7s6[ݜ݉ݥûʸ5VxiF�_U2/샹5h-nF#;О9_>:bsAv8ܖ֪d&#Y=Ş�z6ֿhb}6Gխ(=z~p2Fr'd3UH^q@:-99?:nch5n7G]ƵȠ[OJ6Fu(�Zp@HK
    Ԥ]AE$Q(+<ۖ�P *}Oi=ګq,PHR%C}K)CۣАeXB^d\d)
    ӥKA!O˺d4~טc|?Ѹ\C$bB#64Хw~ARټv	d\uTRP/!4H7(@[ӉD@
    VF@6HH,- #@_9=1:RHgC.GPBw~@G&d?td (ẕDdP}Uh"l(H[`&@9,"IVDt`i?#h̀ﰆl6^<E#YPJ@	(%74z*a/  N1^vEAh5: )C 'eGn+{JqeI'Y$WVOqFw5.sM"wn8/JqAPa\]ܸb]u7?9rAARH,W_cu <Y{2PO yfZp[P!ҧ7/"
    ~bI遴);R|.ϑR"G)w]^r'[#_)2S?b=>\q0?崙wLdS',"=Ia0AWOc'9 ]-@m9_lӸWQY0x?*PdVP"ݥvl^)a}~^.ЂȤn6p SlyDܕR>boe<YN~|k!tMXZ#7VSea*/54_=k͈>?[JԉڑγPZH!Q`jeT[͈NF#_2[HCXHR=Squzgհ24f͖%<㯕QԾw/lZȔE2;R\P*Ծ=h_#<102VwTIz`mZ kc dt.{
    *~#XWs Ұf^}Hnxr6(ZxoW1ld_	*brW1A}XtZLگkdi"t,vRȠTw)Fg(h.'[oeZEBݮC{tᧅ?~f=F_4gˍBsv36p,ZŌ i6Q*f  |R9?PcڑZcʦ@Oaׁ _7wA%&nrQ| F(dΑ,�
    C7Wt/b3h4G/yAAIDtABj&NW5i"iE,
    4
    {6ϯW	O?~+#/@Y,Q3@9,P/"`>5DȰ_eQ@ڹH+^)_	ɿU
    (sWԑze	$@
    "̑d{׉臭rA-
    `T̯7؂
    (8;7Wƴ~h.jZ&6dCGXn!ђh:GWF
    B^:O1Z]?JhѪ1ՇīXVCժzFz:I@	(%4?)03����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_rewrite_fig1.png������������������������������������������������0000664�0001751�0001751�00000003244�10671421551�022235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�������Gm���sRGB����gAMA��a��� cHRM��z&���������u0��`��:��pQ<���PLTE�������`p���	pHYs����+��IDATxj<�`y&1}C_AN!2 L`;It#ԍRNZFkF-RK-RK-z(˫1ƆƼZjijlh̫-2X!"Έvh1,b	�P"G/Z}GiѰՃONfJ8rhu^<'Π!bDS4.Mǻt,{#tc#"9	"lm2nL9I`&S1r$^uDZDl-Y.EK,z!#	`oX{bZ8֊J!gSQljY|ȩekpE6�#Q0#&1ȿfI&.@'%akOZvy^-ڪZ&kKgk?kZV|a[|U<?\f\oZr3U}kgeYVfٕVTM5<ceYcy{rw.dNKsxqmrc}|wj]mş_V!SZE
    mJƦZjZjZjZ?W||_Wjrxt2nu "7aS3`qeDD2.:Uz^_Em5\UD<7VhO[Z7SKMZ!尲Z^ġA"u5T,"M| ֿׄAp61~YC/�Cs]O6Jœxbc03- "-Ƭva"ffBnjX1YC@tjU7/F">vb%2'Fb`1?P|I RI%RH4Nf'v!z�е~) ^-}$2E?jŀC�_V"�x=?8 R9n'pyVςp>ZjZj֟:lwg53ZjZjZjMbߨWoTVs/יQߨׅ76ơE{\bUoő)7Rz[m5׿z7c7,9Q5Rc۷dFձ1P86RoߨSoǎoD7-coZjZjZj5OoY/wכߣ6}]Xd;Ǹjk=]Y.|z<`-|UgXe*WsXeUl3XS[?~٢Lc~]o]37֏Һ~-֏Q:֜`Q?vQsGt]Zj=ƱZ5yLa:X;kKe,\:XL!6q3y_8v,O8hM8lM8hM)j=-ƆƼZjij̫q1ZjT箈${����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/pixel.gif�����������������������������������������������������������0000664�0001751�0001751�00000000075�10147723030�020103� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����!Made with GIMP�!
    ��,�������L�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/up.gif��������������������������������������������������������������0000664�0001751�0001751�00000000071�10147723030�017402� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����@Xq!�����,�������
    4{n�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/manual/images/home.gif������������������������������������������������������������0000664�0001751�0001751�00000002671�10147723030�017716� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ad� ������QQ��=�]��C�
    �ss�������`��9�zz�����i�� �>�00�����+�77�"�E���	YY�� �^���>���*�� �E%�?�,�11��E�c��m���-�E��3��?�/�����T���$$��3?%��^�������?�������?�22�����
    �(!��?�8TT�2�?��� �w�b���}t�.�%%��{	����J���Nc����������!� ��ii������::��/�E�d�?�P�?�
    ��6&&�\\���o�,�E���HH�cc��~n���U�ػ��� �_�#�P����>��'  �;;�qq���?�6 �&�E�4�E&� ��*�50�''�]]��� �6���<�]�dd��
    ��,�&�	��r�kk�?,��?$�?"��?��7� ?��:�rr����@�
    �����d�b�h
    
    �������@S�c�v�a��%M�S//��JJ�^����������,����d� �@�H*\ȰBa"Jhн
    *LL�YI氤ɓ
    [|BIM�pнѡCۓ'an s(C/QTaIiR2�ؤзf<<	!r8d8pǬK7:T.&JENǐ#KL2�h2kޜYH7ˠMH8V0m0aB;ad?sd8Rs.+_QK~dJ	7<6	WGU�*0<e ɿ@ўΡ^T	x
    Miҏx
    +EW<c`N4܈$8mkYᖉɡ8;4_H
    	bbՔA'v'2" 06,㏷E9<	0V\bX5X#`hpAE%b:TeB6LPEHq*蠄B6>A-AT:6%0P;xAE+)
    7UXs5LPC"I8teR1@"�2
    �Q]<G \N@X!(SRǰ�@�p>R�	!m{˿Āր4
    HD&9@CT&u҂		"5@ 
    (I,Y@�;�����������������������������������������������������������������������httpd-2.4.64/docs/manual/images/mod_filter_new.gif��������������������������������������������������0000664�0001751�0001751�00000004530�10147723030�021757� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aK�����,����K�ڋ޼H扦ʶL
    ĢL*̦	JԪjܮN
    (8HXhx)9`yyp`Iũ@jp**ʚZ1j	Qj뉪{{,,[-Lkz<[
    ͼ
    l^=ݠNOڎo2.?/@]|5",X'CW+Z1;z2ȑ$K<2ʕOֱ|Y%̙$ҼI!Ν5e!С=
    ҥL:}
    uϨ?Ri֭\z1+ؔbǞ,k6ڵlۺ]mǸr7ҭ7޽|l8)Q<bXGd-yVqo58kVYg5)5~!Wa5أfq:k3Lz+^rp-͜'FFzÀ)q:}~YN<8Yh_wƩ_\~x=,qX _t7Ӑ=F[r0@#~"dTc5wV=,IvB_[iR##Aԓ9H&
    ydq=n!O"˔TN`\iP&*D)m2'un	ʝ`~فI
    eA.ʨajf4&*%ʙi<pC⏇&H.aMҩ,S骥R3-"mGZ\áiNi**
    a櫦$5;bt2▱cbضQ٩,q+AW.to7�]B
    _>2ICs'j>-*J*hˍ;{Wkj[0l/תحZܭNuB[jӶBHԴtTSb}c,==3u�m`=tBh03Ŋ#966
    gh
    &'?Umw|pӝ{lפn/p¶ޚ;»;1u
    &B<YRF8\[ޚx҇+?^$D~nb'6	}ZfOb|x�d(`ހƫnr[R.m~]`8LcOx#CUP#;Gg73,uA nHTY7*
    EYy)+cG14\3EvZsaFF8ob(?
    [`Hj$fcHKy?Yh2,,)OTR$d+'Wr-kxKEܥ@	LRVf.iL4cpM%9aS61C(}\8YBhS\`ʓ[
    l'&ቑrlȴ>ǽS;H
    (@pĜ;Jz6%G:AM71X=
    љȹ`*CI4ԁ?ЉnbD>e'~++5ӈ~p_UHP	K=GZ0SC~a';cPM8͟ґi:O7ՔdM=F2(cݫX6s
    #3:Pe3[,ԘW#*
    jZYL)լ7qqZCe;;Go%mT*GFonRS.NqWi(׮9<pЋoM؋®mGid\ڦ.]-[GdoqV"Z/KK^Hlj4 8y,SC=w08O+b;LBXE;SbqmC,S52&1k<(3kyl7D.#9K~(KyWx2M|Nfy\a/Ṳ!ό4!j~^7yt^r=<co^y\X>*MhZLM4IGDGnF:/Жtieˣ?Sj>9~9u^\}U/Ú\5dlkJ.
    =Leڨs\xˌ9ojXJr=m.g7+f
    pU!6뮨ywt#ۇ
    k~_\5nW`)~)Ci8#䐹ȃ}rۤ+?p˙\3oN\i@W9O;B0zMb[LNTK}Tկk}\׿}d@��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/�����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�014510� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�015633� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-manual.conf.in���������������������������������������������������0000664�0001751�0001751�00000002537�13076415352�021511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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.4/
    #
    # Required modules: mod_alias, mod_authz_core, mod_authz_host,
    #                   mod_setenvif, mod_negotiation
    #
    
    AliasMatch ^/manual(?:/(?:da|de|en|es|fr|ja|ko|pt-br|ru|tr|zh-cn))?(/.*)?$ "@exp_manualdir@$1"
    
    <Directory "@exp_manualdir@">
        Options Indexes
        AllowOverride None
        Require all granted
    
        <Files *.html>
            SetHandler type-map
        </Files>
    
        # .tr is text/troff in mime.types!
        RemoveType tr
    
        # Traditionally, used .dk filename extension for da language
        AddLanguage da .da
    
        SetEnvIf Request_URI ^/manual/(da|de|en|es|fr|ja|ko|pt-br|ru|tr|zh-cn)/ prefer-language=$1
        RedirectMatch 301 ^/manual(?:/(da|de|en|es|fr|ja|ko|pt-br|ru|tr|zh-cn)){2,}(/.*)?$ /manual/$1$2
    
        # Reflect the greatest effort in translation (most content available),
        # inferring greater attention to detail (potentially false assumption,
        # counting translations presently in-sync would be more helpful.)
        # Use caution counting; safest pattern is '*.xml.XX'. Recent .xml source
        # document count: 266 214 110 94 82 25 22    18     4  1  1
        LanguagePriority   en  fr  ko ja tr es de zh-cn pt-br da ru
        ForceLanguagePriority Prefer Fallback
    </Directory>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-vhosts.conf.in���������������������������������������������������0000664�0001751�0001751�00000002757�11720462450�021561� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Virtual Hosts
    #
    # Required modules: mod_log_config
    
    # 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 
    # <URL:http://httpd.apache.org/docs/2.4/vhosts/>
    # for further details before you try to setup virtual hosts.
    #
    # You may use the command line option '-S' to verify your virtual host
    # configuration.
    
    #
    # 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 <VirtualHost> block.
    #
    <VirtualHost *:@@Port@@>
        ServerAdmin webmaster@dummy-host.example.com
        DocumentRoot "@@ServerRoot@@/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
    </VirtualHost>
    
    <VirtualHost *:@@Port@@>
        ServerAdmin webmaster@dummy-host2.example.com
        DocumentRoot "@@ServerRoot@@/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
    </VirtualHost>
    
    
    
    �����������������httpd-2.4.64/docs/conf/extra/httpd-ssl.conf.in������������������������������������������������������0000664�0001751�0001751�00000031666�13106652031�021031� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 detailed information about these 
    # directives see <URL:http://httpd.apache.org/docs/2.4/mod/mod_ssl.html>
    # 
    # 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.  
    #
    # Required modules: mod_log_config, mod_setenvif, mod_ssl,
    #          socache_shmcb_module (for default value of SSLSessionCache)
    
    #
    # 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
    #
    Listen @@SSLPort@@
    
    ##
    ##  SSL Global Context
    ##
    ##  All SSL configuration in this context applies both to
    ##  the main server and all SSL-enabled virtual hosts.
    ##
    
    #   SSL Cipher Suite:
    #   List the ciphers that the client is permitted to negotiate,
    #   and that httpd will negotiate as the client of a proxied server.
    #   See the OpenSSL documentation for a complete list of ciphers, and
    #   ensure these follow appropriate best practices for this deployment.
    #   httpd 2.2.30, 2.4.13 and later force-disable aNULL, eNULL and EXP ciphers,
    #   while OpenSSL disabled these by default in 0.9.8zf/1.0.0r/1.0.1m/1.0.2a.
    SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
    SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
    
    #  By the end of 2016, only TLSv1.2 ciphers should remain in use.
    #  Older ciphers should be disallowed as soon as possible, while the
    #  kRSA ciphers do not offer forward secrecy.  These changes inhibit
    #  older clients (such as IE6 SP2 or IE8 on Windows XP, or other legacy
    #  non-browser tooling) from successfully connecting.  
    #
    #  To restrict mod_ssl to use only TLSv1.2 ciphers, and disable
    #  those protocols which do not support forward secrecy, replace
    #  the SSLCipherSuite and SSLProxyCipherSuite directives above with
    #  the following two directives, as soon as practical.
    # SSLCipherSuite HIGH:MEDIUM:!SSLv3:!kRSA
    # SSLProxyCipherSuite HIGH:MEDIUM:!SSLv3:!kRSA
    
    #   User agents such as web browsers are not configured for the user's
    #   own preference of either security or performance, therefore this
    #   must be the prerogative of the web server administrator who manages
    #   cpu load versus confidentiality, so enforce the server's cipher order.
    SSLHonorCipherOrder on 
    
    #   SSL Protocol support:
    #   List the protocol versions which clients are allowed to connect with.
    #   Disable SSLv3 by default (cf. RFC 7525 3.1.1).  TLSv1 (1.0) should be
    #   disabled as quickly as practical.  By the end of 2016, only the TLSv1.2
    #   protocol or later should remain in use.
    SSLProtocol all -SSLv3
    SSLProxyProtocol all -SSLv3
    
    #   Pass Phrase Dialog:
    #   Configure the pass phrase gathering process.
    #   The filtering dialog program (`builtin' is an 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
    
    #   OCSP Stapling (requires OpenSSL 0.9.8h or later)
    #
    #   This feature is disabled by default and requires at least
    #   the two directives SSLUseStapling and SSLStaplingCache.
    #   Refer to the documentation on OCSP Stapling in the SSL/TLS
    #   How-To for more information.
    #
    #   Enable stapling for all SSL-enabled servers:
    #SSLUseStapling On
    
    #   Define a relatively small cache for OCSP Stapling using
    #   the same mechanism that is used for the SSL session cache
    #   above.  If stapling is used with more than a few certificates,
    #   the size may need to be increased.  (AH01929 will be logged.)
    #SSLStaplingCache "shmcb:@exp_runtimedir@/ssl_stapling(32768)"
    
    #   Seconds before valid OCSP responses are expired from the cache
    #SSLStaplingStandardCacheTimeout 3600
    
    #   Seconds before invalid OCSP responses are expired from the cache
    #SSLStaplingErrorCacheTimeout 600
    
    ##
    ## SSL Virtual Host Context
    ##
    
    <VirtualHost _default_:@@SSLPort@@>
    
    #   General setup for the virtual host
    DocumentRoot "@exp_htdocsdir@"
    ServerName www.example.com:@@SSLPort@@
    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
    
    #   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.)
    #   Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt)
    #   require an ECC certificate which can also be configured in
    #   parallel.
    SSLCertificateFile "@exp_sysconfdir@/server.crt"
    #SSLCertificateFile "@exp_sysconfdir@/server-dsa.crt"
    #SSLCertificateFile "@exp_sysconfdir@/server-ecc.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.)
    #   ECC keys, when in use, can also be configured in parallel
    SSLCertificateKeyFile "@exp_sysconfdir@/server.key"
    #SSLCertificateKeyFile "@exp_sysconfdir@/server-dsa.key"
    #SSLCertificateKeyFile "@exp_sysconfdir@/server-ecc.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 convenience.
    #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).
    #   The CRL checking mode needs to be configured explicitly
    #   through SSLCARevocationCheck (defaults to "none" otherwise).
    #   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"
    #SSLCARevocationCheck chain
    
    #   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
    
    #   TLS-SRP mutual authentication:
    #   Enable TLS-SRP and set the path to the OpenSSL SRP verifier
    #   file (containing login information for SRP user accounts). 
    #   Requires OpenSSL 1.0.1 or newer. See the mod_ssl FAQ for
    #   detailed instructions on creating this file. Example:
    #   "openssl srp -srpvfile @exp_sysconfdir@/passwd.srpv -add username"
    #SSLSRPVerifierFile "@exp_sysconfdir@/passwd.srpv"
    
    #   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.
    #<Location />
    #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]+$/
    #</Location>
    
    #   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
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory "@exp_cgidir@">
        SSLOptions +StdEnvVars
    </Directory>
    
    #   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 sent or allowed to be 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 [2-5]" \
             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"
    
    </VirtualHost>                                  
    ��������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-default.conf.in��������������������������������������������������0000664�0001751�0001751�00000005576�12003240052�021644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 60
    
    #
    # 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 Off
    
    #
    # 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
    
    #
    # Set a timeout for how long the client may take to send the request header
    # and body.
    # The default for the headers is header=20-40,MinRate=500, which means wait
    # for the first byte of headers for 20 seconds. If some data arrives,
    # increase the timeout corresponding to a data rate of 500 bytes/s, but not
    # above 40 seconds.
    # The default for the request body is body=20,MinRate=500, which is the same
    # but has no upper limit for the timeout.
    # To disable, set to header=0 body=0
    #
    <IfModule reqtimeout_module>
      RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
    </IfModule>
    ����������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-dav.conf.in������������������������������������������������������0000664�0001751�0001751�00000003612�14743443462�021006� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # Distributed authoring and versioning (WebDAV)
    #
    # Required modules: mod_alias, mod_auth_digest, mod_authn_core, mod_authn_file,
    #                   mod_authz_core, mod_authz_user, mod_dav, mod_dav_fs,
    #                   mod_setenvif
    
    # 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"
    
    <Directory "@@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"
        AuthDigestProvider file
    
        # Allow universal read-access, but writes are restricted
        # to the admin user.
        <RequireAny>
            Require method GET POST OPTIONS
            Require user admin
        </RequireAny>
    </Directory>
    
    #
    # 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\.[012]" redirect-carefully
    BrowserMatch "^gnome-vfs/1\.0" redirect-carefully
    BrowserMatch "^gvfs/1" redirect-carefully
    BrowserMatch "^XML Spy" redirect-carefully
    BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully
    BrowserMatch " Konqueror/4" redirect-carefully
    BrowserMatch " Konqueror/5" redirect-carefully
    BrowserMatch " dolphin/" redirect-carefully
    ����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/proxy-html.conf.in�����������������������������������������������������0000664�0001751�0001751�00000006131�12006245256�021224� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Configuration example.
    #
    # For detailed information about these directives see
    # <URL:http://httpd.apache.org/docs/2.4/mod/mod_proxy_html.html>
    # and for mod_xml2enc see
    # <URL:http://httpd.apache.org/docs/2.4/mod/mod_xml2enc.html>
    #
    # First, to load the module with its prerequisites.  Note: mod_xml2enc
    # is not always necessary, but without it mod_proxy_html is likely to
    # mangle pages in encodings other than ASCII or Unicode (utf-8).
    #
    # For Unix-family systems:
    # LoadFile	/usr/lib/libxml2.so
    # LoadModule	proxy_html_module	modules/mod_proxy_html.so
    # LoadModule	xml2enc_module		modules/mod_xml2enc.so
    #
    # For Windows (I don't know if there's a standard path for the libraries)
    # LoadFile	C:/path/zlib.dll
    # LoadFile	C:/path/iconv.dll
    # LoadFile	C:/path/libxml2.dll
    # LoadModule	proxy_html_module	modules/mod_proxy_html.so
    # LoadModule	xml2enc_module		modules/mod_xml2enc.so
    # 
    # All knowledge of HTML links has been removed from the mod_proxy_html
    # code itself, and is instead read from httpd.conf (or included file)
    # at server startup.  So you MUST declare it.  This will normally be
    # at top level, but can also be used in a <Location>.
    #
    # Here's the declaration for W3C HTML 4.01 and XHTML 1.0
    
    ProxyHTMLLinks	a		href
    ProxyHTMLLinks	area		href
    ProxyHTMLLinks	link		href
    ProxyHTMLLinks	img		src longdesc usemap
    ProxyHTMLLinks	object		classid codebase data usemap
    ProxyHTMLLinks	q		cite
    ProxyHTMLLinks	blockquote	cite
    ProxyHTMLLinks	ins		cite
    ProxyHTMLLinks	del		cite
    ProxyHTMLLinks	form		action
    ProxyHTMLLinks	input		src usemap
    ProxyHTMLLinks	head		profile
    ProxyHTMLLinks	base		href
    ProxyHTMLLinks	script		src for
    
    # To support scripting events (with ProxyHTMLExtended On),
    # you'll need to declare them too.
    
    ProxyHTMLEvents	onclick ondblclick onmousedown onmouseup \
    		onmouseover onmousemove onmouseout onkeypress \
    		onkeydown onkeyup onfocus onblur onload \
    		onunload onsubmit onreset onselect onchange
    
    # If you need to support legacy (pre-1998, aka "transitional") HTML or XHTML,
    # you'll need to uncomment the following deprecated link attributes.
    # Note that these are enabled in earlier mod_proxy_html versions
    #
    # ProxyHTMLLinks	frame		src longdesc
    # ProxyHTMLLinks	iframe		src longdesc
    # ProxyHTMLLinks	body		background
    # ProxyHTMLLinks	applet		codebase
    #
    # If you're dealing with proprietary HTML variants,
    # declare your own URL attributes here as required.
    #
    # ProxyHTMLLinks	myelement	myattr otherattr
    #
    ###########
    # EXAMPLE #
    ###########
    #
    # To define the URL /my-gateway/ as a gateway to an appserver with address
    # http://some.app.intranet/ on a private network, after loading the
    # modules and including this configuration file:
    #
    # ProxyRequests Off  <-- this is an important security setting
    # ProxyPass /my-gateway/ http://some.app.intranet/
    # <Location /my-gateway/>
    #	ProxyPassReverse /
    #	ProxyHTMLEnable On
    #	ProxyHTMLURLMap http://some.app.intranet/ /my-gateway/
    #	ProxyHTMLURLMap / /my-gateway/
    # </Location>
    #
    # Many (though not all) real-life setups are more complex.
    #
    # See the documentation at
    # http://apache.webthing.com/mod_proxy_html/
    # and the tutorial at
    # http://www.apachetutor.org/admin/reverseproxies
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-mpm.conf.in������������������������������������������������������0000664�0001751�0001751�00000010550�12012563134�021006� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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.
    #
    <IfModule !mpm_netware_module>
        PidFile "@rel_runtimedir@/httpd.pid"
    </IfModule>
    
    #
    # 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
    # MaxRequestWorkers: maximum number of server processes allowed to start
    # MaxConnectionsPerChild: maximum number of connections a server process serves
    #                         before terminating
    <IfModule mpm_prefork_module>
        StartServers             5
        MinSpareServers          5
        MaxSpareServers         10
        MaxRequestWorkers      250
        MaxConnectionsPerChild   0
    </IfModule>
    
    # worker MPM
    # StartServers: initial number of server processes to start
    # 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
    # MaxRequestWorkers: maximum number of worker threads
    # MaxConnectionsPerChild: maximum number of connections a server process serves
    #                         before terminating
    <IfModule mpm_worker_module>
        StartServers             3
        MinSpareThreads         75
        MaxSpareThreads        250 
        ThreadsPerChild         25
        MaxRequestWorkers      400
        MaxConnectionsPerChild   0
    </IfModule>
    
    # event MPM
    # StartServers: initial number of server processes to start
    # 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
    # MaxRequestWorkers: maximum number of worker threads
    # MaxConnectionsPerChild: maximum number of connections a server process serves
    #                         before terminating
    <IfModule mpm_event_module>
        StartServers             3
        MinSpareThreads         75
        MaxSpareThreads        250
        ThreadsPerChild         25
        MaxRequestWorkers      400
        MaxConnectionsPerChild   0
    </IfModule>
    
    # 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
    # MaxConnectionsPerChild: Maximum  number of connections 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.
    <IfModule mpm_netware_module>
        ThreadStackSize      65536
        StartThreads           250
        MinSpareThreads         25
        MaxSpareThreads        250
        MaxThreads            1000
        MaxConnectionsPerChild   0
    </IfModule>
    
    # 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
    # MaxConnectionsPerChild: Maximum number of connections per server process
    <IfModule mpm_mpmt_os2_module>
        StartServers             2
        MinSpareThreads          5
        MaxSpareThreads         10
        MaxConnectionsPerChild   0
    </IfModule>
    
    # WinNT MPM
    # ThreadsPerChild: constant number of worker threads in the server process
    # MaxConnectionsPerChild: maximum number of connections a server process serves
    <IfModule mpm_winnt_module>
        ThreadsPerChild        150
        MaxConnectionsPerChild   0
    </IfModule>
    
    # The maximum number of free Kbytes that every allocator is allowed
    # to hold without calling free(). In threaded MPMs, every thread has its own
    # allocator. When not set, or when set to zero, the threshold will be set to
    # unlimited.
    <IfModule !mpm_netware_module>
        MaxMemFree            2048
    </IfModule>
    <IfModule mpm_netware_module>
        MaxMemFree             100
    </IfModule>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-userdir.conf.in��������������������������������������������������0000664�0001751�0001751�00000001266�11573244531�021706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Settings for user home directories
    #
    # Required module: mod_authz_core, mod_authz_host, 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.
    #
    <Directory "/home/*/public_html">
        AllowOverride FileInfo AuthConfig Limit Indexes
        Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
        Require method GET POST OPTIONS
    </Directory>
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-autoindex.conf.in������������������������������������������������0000664�0001751�0001751�00000005455�11405657151�022235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # Directives controlling the display of server-generated directory listings.
    #
    # Required modules: mod_authz_core, mod_authz_host,
    #                   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 HTMLTable 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@/"
    
    <Directory "@exp_iconsdir@">
        Options Indexes MultiViews
        AllowOverride None
        Require all granted
    </Directory>
    
    #
    # 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
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-info.conf.in�����������������������������������������������������0000664�0001751�0001751�00000002137�11405657151�021162� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # Get information about the requests being processed by the server
    # and the configuration of the server.
    #
    # Required modules: mod_authz_core, mod_authz_host,
    #                   mod_info (for the server-info handler),
    #                   mod_status (for the server-status 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.
    
    <Location /server-status>
        SetHandler server-status
        Require host .example.com
        Require ip 127
    </Location>
    
    #
    # 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.
    #
    <Location /server-info>
        SetHandler server-info
        Require host .example.com
        Require ip 127
    </Location>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-multilang-errordoc.conf.in���������������������������������������0000664�0001751�0001751�00000004220�11405657151�024033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # The configuration below implements multi-language error documents through
    # content-negotiation.
    #
    # Required modules: mod_alias, mod_authz_core, mod_authz_host,
    #                   mod_include, mod_negotiation
    #
    # We use Alias to redirect any /error/HTTP_<error>.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_<error>.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@/"
    
    <Directory "@exp_errordir@">
        AllowOverride None
        Options IncludesNoExec
        AddOutputFilter Includes html
        AddHandler type-map var
        Require all granted
        LanguagePriority en cs de es fr it ja ko nl pl pt-br ro sv tr
        ForceLanguagePriority Prefer Fallback
    </Directory>
    
    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
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/extra/httpd-languages.conf.in������������������������������������������������0000664�0001751�0001751�00000011726�10764234743�022206� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)
    # Turkish (tr) - 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 tr .tr
    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 tr 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
    ������������������������������������������httpd-2.4.64/docs/conf/charset.conv�����������������������������������������������������������������0000664�0001751�0001751�00000003345�14743443462�017037� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 
    # 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  Croatian
    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
                            
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/httpd.conf.in����������������������������������������������������������������0000664�0001751�0001751�00000033036�12754716707�017123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # This is the main Apache HTTP server configuration file.  It contains the
    # configuration directives that give the server its instructions.
    # See <URL:http://httpd.apache.org/docs/2.4/> for detailed information.
    # In particular, see 
    # <URL:http://httpd.apache.org/docs/2.4/mod/directives.html>
    # 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/access_log"
    # with ServerRoot set to "/usr/local/apache2" will be interpreted by the
    # server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" 
    # will be interpreted as '/logs/access_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 specify a local disk on the
    # Mutex directive, if file-based mutexes are used.  If you wish to share the
    # same ServerRoot for multiple httpd daemons, you will need to change at
    # least PidFile.
    #
    ServerRoot "@@ServerRoot@@"
    
    #
    # Mutex: Allows you to set the mutex mechanism and mutex file directory
    # for individual mutexes, or change the global defaults
    #
    # Uncomment and change the directory if mutexes are file-based and the default
    # mutex file directory is not on a local disk or is not appropriate for some
    # other reason.
    #
    # Mutex default:@rel_runtimedir@
    
    #
    # Listen: Allows you to bind Apache to specific IP addresses and/or
    # ports, instead of the default. See also the <VirtualHost>
    # directive.
    #
    # Change this to Listen on specific IP addresses as shown below to 
    # prevent Apache from glomming onto all bound IP addresses.
    #
    #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@@
    
    <IfModule unixd_module>
    #
    # 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.
    # It is usually good practice to create a dedicated user and group for
    # running httpd, as with most system services.
    #
    User daemon
    Group daemon
    
    </IfModule>
    
    # '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
    # <VirtualHost> definition.  These values also provide defaults for
    # any <VirtualHost> containers you may define later in the file.
    #
    # All of these directives may appear inside <VirtualHost> 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:@@Port@@
    
    #
    # Deny access to the entirety of your server's filesystem. You must
    # explicitly permit access to web content directories in other 
    # <Directory> blocks below.
    #
    <Directory />
        AllowOverride none
        Require all denied
    </Directory>
    
    #
    # 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.
    #
    
    #
    # 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@"
    <Directory "@exp_htdocsdir@">
        #
        # 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.4/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:
        #   AllowOverride FileInfo AuthConfig Limit
        #
        AllowOverride None
    
        #
        # Controls who can get stuff from this server.
        #
        Require all granted
    </Directory>
    
    #
    # DirectoryIndex: sets the file that Apache will serve if a directory
    # is requested.
    #
    <IfModule dir_module>
        DirectoryIndex index.html
    </IfModule>
    
    #
    # The following lines prevent .htaccess and .htpasswd files from being 
    # viewed by Web clients. 
    #
    <Files ".ht*">
        Require all denied
    </Files>
    
    #
    # ErrorLog: The location of the error log file.
    # If you do not specify an ErrorLog directive within a <VirtualHost>
    # container, error messages relating to that virtual host will be
    # logged here.  If you *do* define an error logfile for a <VirtualHost>
    # 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
    
    <IfModule log_config_module>
        #
        # 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
    
        <IfModule logio_module>
          # 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
        </IfModule>
    
        #
        # The location and format of the access logfile (Common Logfile Format).
        # If you do not define any access logfiles within a <VirtualHost>
        # container, they will be logged here.  Contrariwise, if you *do*
        # define per-<VirtualHost> 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
    </IfModule>
    
    <IfModule alias_module>
        #
        # 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 <Directory> 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@/"
    
    </IfModule>
    
    <IfModule cgid_module>
        #
        # ScriptSock: On threaded servers, designate the path to the UNIX
        # socket used to communicate with the CGI daemon of mod_cgid.
        #
        #Scriptsock cgisock
    </IfModule>
    
    #
    # "@exp_cgidir@" should be changed to whatever your ScriptAliased
    # CGI directory exists, if you have that configured.
    #
    <Directory "@exp_cgidir@">
        AllowOverride None
        Options None
        Require all granted
    </Directory>
    
    <IfModule headers_module>
        #
        # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied
        # backend servers which have lingering "httpoxy" defects.
        # 'Proxy' request header is undefined by the IETF, not listed by IANA
        #
        RequestHeader unset Proxy early
    </IfModule>
    
    <IfModule mime_module>
        #
        # 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 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
    </IfModule>
    
    #
    # 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
    #
    
    #
    # MaxRanges: Maximum number of Ranges in a request before
    # returning the entire resource, or one of the special
    # values 'default', 'none' or 'unlimited'.
    # Default setting is to accept 200 Ranges.
    #MaxRanges unlimited
    
    #
    # EnableMMAP and EnableSendfile: On systems that support it, 
    # memory-mapping or the sendfile syscall may be 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.
    # Defaults: EnableMMAP On, EnableSendfile Off
    #
    #EnableMMAP off
    #EnableSendfile on
    
    # 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
    
    # Configure mod_proxy_html to understand HTML4/XHTML1
    <IfModule proxy_html_module>
    Include @rel_sysconfdir@/extra/proxy-html.conf
    </IfModule>
    
    # 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.
    #
    <IfModule ssl_module>
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
    </IfModule>
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/magic������������������������������������������������������������������������0000664�0001751�0001751�00000031410�13507631724�015511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 <janl@ifi.uio.no>,
    #
    
    # 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		
    #					- WAVE format
    >8	string		WAVE		audio/x-wav
    # MPEG audio.
    0   beshort&0xfff0  0xfff0  audio/mpeg
    # C64 SID Music files, from Linus Walleij <triad@df.lth.se>
    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 <keith@cerberus.uchicago.edu>
    #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		\<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
    
    #------------------------------------------------------------------------------
    # html:  file(1) magic for HTML (HyperText Markup Language) docs
    #
    # from Daniel Quinlan <quinlan@yggdrasil.com>
    # and Anna Shergold <anna@inext.co.uk>
    #
    0   string      \<!DOCTYPE\ HTML    text/html
    0   string      \<!doctype\ html    text/html
    0   string      \<HEAD      text/html
    0   string      \<head      text/html
    0   string      \<TITLE     text/html
    0   string      \<title     text/html
    0   string      \<html      text/html
    0   string      \<HTML      text/html
    0   string      \<!--       text/html
    0   string      \<h1        text/html
    0   string      \<H1        text/html
    
    # XML eXtensible Markup Language, from Linus Walleij <triad@df.lth.se>
    0   string      \<?xml      text/xml
    
    #------------------------------------------------------------------------------
    # images:  file(1) magic for image formats (see also "c-lang" for XPM bitmaps)
    #
    # originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
    # additions by janl@ifi.uio.no as well as others. Jan also suggested
    # merging several one- and two-line files into here.
    #
    # XXX - byte order for GIF and TIFF fields?
    # [GRR:  TIFF allows both byte orders; GIF is probably little-endian]
    #
    
    # [GRR:  what the hell is this doing in here?]
    #0	string		xbtoa		btoa'd file
    
    # PBMPLUS
    #					PBM file
    0	string		P1		image/x-portable-bitmap	7bit
    #					PGM file
    0	string		P2		image/x-portable-greymap	7bit
    #					PPM file
    0	string		P3		image/x-portable-pixmap	7bit
    #					PBM "rawbits" file
    0	string		P4		image/x-portable-bitmap
    #					PGM "rawbits" file
    0	string		P5		image/x-portable-greymap
    #					PPM "rawbits" file
    0	string		P6		image/x-portable-pixmap
    
    # NIFF (Navy Interchange File Format, a modification of TIFF)
    # [GRR:  this *must* go before TIFF]
    0	string		IIN1		image/x-niff
    
    # TIFF and friends
    #					TIFF file, big-endian
    0	string		MM		image/tiff
    #					TIFF file, little-endian
    0	string		II		image/tiff
    
    # possible GIF replacements; none yet released!
    # (Greg Roelofs, newt@uchicago.edu)
    #
    # GRR 950115:  this was mine ("Zip GIF"):
    #					ZIF image (GIF+deflate alpha)
    0	string		GIF94z		image/unknown
    #
    # GRR 950115:  this is Jeremy Wohl's Free Graphics Format (better):
    #					FGF image (GIF+deflate beta)
    0	string		FGF95a		image/unknown
    #
    # GRR 950115:  this is Thomas Boutell's Portable Bitmap Format proposal
    # (best; not yet implemented):
    #					PBF image (deflate compression)
    0	string		PBF		image/unknown
    
    # GIF
    0	string		GIF		image/gif
    
    # JPEG images
    0	beshort		0xffd8		image/jpeg
    
    # PC bitmaps (OS/2, Windoze BMP files)  (Greg Roelofs, newt@uchicago.edu)
    0	string		BM		image/bmp
    #>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
    
    0	string		\x89PNG		image/png
    0	string		FWS		application/x-shockwave-flash
    0	string		CWS		application/x-shockwave-flash
    
    #------------------------------------------------------------------------------
    # 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 <conklin@talisman.kaleida.com>
    
    # 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 <triad@df.lth.se>
    # from Apple quicktime file format documentation.
    4   string      moov        video/quicktime
    4   string      mdat        video/quicktime
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/conf/mime.types�������������������������������������������������������������������0000664�0001751�0001751�00000167052�14743443462�016542� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This file maps Internet media types to unique file extension(s).
    # Although created for httpd, this file is used by many software systems
    # and has been placed in the public domain for unlimited redistribution.
    #
    # The table below contains both registered and (common) unregistered types.
    # A type that has no unique extension can be ignored -- they are listed
    # here to guide configurations toward known types and to make it easier to
    # identify "new" types.  File extensions are also commonly used to indicate
    # content languages and encodings, so choose them carefully.
    #
    # Internet media types should be registered as described in RFC 4288.
    # The registry is at <http://www.iana.org/assignments/media-types/>.
    #
    # MIME type (lowercased)			Extensions
    # ============================================	==========
    # application/1d-interleaved-parityfec
    # application/3gpdash-qoe-report+xml
    # application/3gpp-ims+xml
    # application/a2l
    # application/activemessage
    # application/alto-costmap+json
    # application/alto-costmapfilter+json
    # application/alto-directory+json
    # application/alto-endpointcost+json
    # application/alto-endpointcostparams+json
    # application/alto-endpointprop+json
    # application/alto-endpointpropparams+json
    # application/alto-error+json
    # application/alto-networkmap+json
    # application/alto-networkmapfilter+json
    # application/aml
    application/andrew-inset			ez
    # application/applefile
    application/applixware				aw
    # application/atf
    # application/atfx
    application/atom+xml				atom
    application/atomcat+xml				atomcat
    # application/atomdeleted+xml
    # application/atomicmail
    application/atomsvc+xml				atomsvc
    # application/atxml
    # application/auth-policy+xml
    # application/bacnet-xdd+zip
    # application/batch-smtp
    # application/beep+xml
    # application/calendar+json
    # application/calendar+xml
    # application/call-completion
    # application/cals-1840
    # application/cbor
    # application/ccmp+xml
    application/ccxml+xml				ccxml
    # application/cdfx+xml
    application/cdmi-capability			cdmia
    application/cdmi-container			cdmic
    application/cdmi-domain				cdmid
    application/cdmi-object				cdmio
    application/cdmi-queue				cdmiq
    # application/cdni
    # application/cea
    # application/cea-2018+xml
    # application/cellml+xml
    # application/cfw
    # application/cms
    # application/cnrp+xml
    # application/coap-group+json
    # application/commonground
    # application/conference-info+xml
    # application/cpl+xml
    # application/csrattrs
    # application/csta+xml
    # application/cstadata+xml
    # application/csvm+json
    application/cu-seeme				cu
    # application/cybercash
    # application/dash+xml
    # application/dashdelta
    application/davmount+xml			davmount
    # application/dca-rft
    # application/dcd
    # application/dec-dx
    # application/dialog-info+xml
    # application/dicom
    # application/dii
    # application/dit
    # application/dns
    application/docbook+xml				dbk
    # application/dskpp+xml
    application/dssc+der				dssc
    application/dssc+xml				xdssc
    # application/dvcs
    application/ecmascript				ecma
    # application/edi-consent
    # application/edi-x12
    # application/edifact
    # application/efi
    # application/emergencycalldata.comment+xml
    # application/emergencycalldata.deviceinfo+xml
    # application/emergencycalldata.providerinfo+xml
    # application/emergencycalldata.serviceinfo+xml
    # application/emergencycalldata.subscriberinfo+xml
    application/emma+xml				emma
    # application/emotionml+xml
    # application/encaprtp
    # application/epp+xml
    application/epub+zip				epub
    # application/eshop
    # application/example
    application/exi					exi
    # application/fastinfoset
    # application/fastsoap
    # application/fdt+xml
    # application/fits
    application/font-tdpfr				pfr
    # application/framework-attributes+xml
    # application/geo+json
    application/gml+xml				gml
    application/gpx+xml				gpx
    application/gxf					gxf
    # application/gzip
    # application/h224
    # application/held+xml
    # application/http
    application/hyperstudio				stk
    # application/ibe-key-request+xml
    # application/ibe-pkg-reply+xml
    # application/ibe-pp-data
    # application/iges
    # application/im-iscomposing+xml
    # application/index
    # application/index.cmd
    # application/index.obj
    # application/index.response
    # application/index.vnd
    application/inkml+xml				ink inkml
    # application/iotp
    application/ipfix				ipfix
    # application/ipp
    # application/isup
    # application/its+xml
    application/java-archive			jar
    application/java-serialized-object		ser
    application/java-vm				class
    # application/javascript
    # application/jose
    # application/jose+json
    # application/jrd+json
    application/json				json
    # application/json-patch+json
    # application/json-seq
    application/jsonml+json				jsonml
    # application/jwk+json
    # application/jwk-set+json
    # application/jwt
    # application/kpml-request+xml
    # application/kpml-response+xml
    # application/ld+json
    # application/lgr+xml
    # application/link-format
    # application/load-control+xml
    application/lost+xml				lostxml
    # application/lostsync+xml
    # application/lxf
    application/mac-binhex40			hqx
    application/mac-compactpro			cpt
    # application/macwriteii
    application/mads+xml				mads
    application/marc				mrc
    application/marcxml+xml				mrcx
    application/mathematica				ma nb mb
    application/mathml+xml				mathml
    # application/mathml-content+xml
    # application/mathml-presentation+xml
    # application/mbms-associated-procedure-description+xml
    # application/mbms-deregister+xml
    # application/mbms-envelope+xml
    # application/mbms-msk+xml
    # application/mbms-msk-response+xml
    # application/mbms-protection-description+xml
    # application/mbms-reception-report+xml
    # application/mbms-register+xml
    # application/mbms-register-response+xml
    # application/mbms-schedule+xml
    # application/mbms-user-service-description+xml
    application/mbox				mbox
    # application/media-policy-dataset+xml
    # application/media_control+xml
    application/mediaservercontrol+xml		mscml
    # application/merge-patch+json
    application/metalink+xml			metalink
    application/metalink4+xml			meta4
    application/mets+xml				mets
    # application/mf4
    # application/mikey
    application/mods+xml				mods
    # application/moss-keys
    # application/moss-signature
    # application/mosskey-data
    # application/mosskey-request
    application/mp21				m21 mp21
    application/mp4					mp4s
    # application/mpeg4-generic
    # application/mpeg4-iod
    # application/mpeg4-iod-xmt
    # application/mrb-consumer+xml
    # application/mrb-publish+xml
    # application/msc-ivr+xml
    # application/msc-mixer+xml
    application/msword				doc dot
    application/mxf					mxf
    # application/nasdata
    # application/news-checkgroups
    # application/news-groupinfo
    # application/news-transmission
    # application/nlsml+xml
    # application/nss
    # application/ocsp-request
    # application/ocsp-response
    application/octet-stream	bin dms lrf mar so dist distz pkg bpk dump elc deploy
    application/oda					oda
    # application/odx
    application/oebps-package+xml			opf
    application/ogg					ogx
    application/omdoc+xml				omdoc
    application/onenote				onetoc onetoc2 onetmp onepkg
    application/oxps				oxps
    # application/p2p-overlay+xml
    # application/parityfec
    application/patch-ops-error+xml			xer
    application/pdf					pdf
    # application/pdx
    application/pgp-encrypted			pgp
    # application/pgp-keys
    application/pgp-signature			asc sig
    application/pics-rules				prf
    # application/pidf+xml
    # application/pidf-diff+xml
    application/pkcs10				p10
    # application/pkcs12
    application/pkcs7-mime				p7m p7c
    application/pkcs7-signature			p7s
    application/pkcs8				p8
    application/pkix-attr-cert			ac
    application/pkix-cert				cer
    application/pkix-crl				crl
    application/pkix-pkipath			pkipath
    application/pkixcmp				pki
    application/pls+xml				pls
    # application/poc-settings+xml
    application/postscript				ai eps ps
    # application/ppsp-tracker+json
    # application/problem+json
    # application/problem+xml
    # application/provenance+xml
    # application/prs.alvestrand.titrax-sheet
    application/prs.cww				cww
    # application/prs.hpub+zip
    # application/prs.nprend
    # application/prs.plucker
    # application/prs.rdf-xml-crypt
    # application/prs.xsf+xml
    application/pskc+xml				pskcxml
    # application/qsig
    # application/raptorfec
    # application/rdap+json
    application/rdf+xml				rdf
    application/reginfo+xml				rif
    application/relax-ng-compact-syntax		rnc
    # application/remote-printing
    # application/reputon+json
    application/resource-lists+xml			rl
    application/resource-lists-diff+xml		rld
    # application/rfc+xml
    # application/riscos
    # application/rlmi+xml
    application/rls-services+xml			rs
    application/rpki-ghostbusters			gbr
    application/rpki-manifest			mft
    application/rpki-roa				roa
    # application/rpki-updown
    application/rsd+xml				rsd
    application/rss+xml				rss
    application/rtf					rtf
    # application/rtploopback
    # application/rtx
    # application/samlassertion+xml
    # application/samlmetadata+xml
    application/sbml+xml				sbml
    # application/scaip+xml
    # application/scim+json
    application/scvp-cv-request			scq
    application/scvp-cv-response			scs
    application/scvp-vp-request			spq
    application/scvp-vp-response			spp
    application/sdp					sdp
    # application/sep+xml
    # application/sep-exi
    # application/session-info
    # application/set-payment
    application/set-payment-initiation		setpay
    # application/set-registration
    application/set-registration-initiation		setreg
    # application/sgml
    # application/sgml-open-catalog
    application/shf+xml				shf
    # application/sieve
    # application/simple-filter+xml
    # application/simple-message-summary
    # application/simplesymbolcontainer
    # application/slate
    # application/smil
    application/smil+xml				smi smil
    # application/smpte336m
    # application/soap+fastinfoset
    # application/soap+xml
    application/sparql-query			rq
    application/sparql-results+xml			srx
    # application/spirits-event+xml
    # application/sql
    application/srgs				gram
    application/srgs+xml				grxml
    application/sru+xml				sru
    application/ssdl+xml				ssdl
    application/ssml+xml				ssml
    # application/tamp-apex-update
    # application/tamp-apex-update-confirm
    # application/tamp-community-update
    # application/tamp-community-update-confirm
    # application/tamp-error
    # application/tamp-sequence-adjust
    # application/tamp-sequence-adjust-confirm
    # application/tamp-status-query
    # application/tamp-status-response
    # application/tamp-update
    # application/tamp-update-confirm
    application/tei+xml				tei teicorpus
    application/thraud+xml				tfi
    # application/timestamp-query
    # application/timestamp-reply
    application/timestamped-data			tsd
    # application/ttml+xml
    # application/tve-trigger
    # application/ulpfec
    # application/urc-grpsheet+xml
    # application/urc-ressheet+xml
    # application/urc-targetdesc+xml
    # application/urc-uisocketdesc+xml
    # application/vcard+json
    # application/vcard+xml
    # application/vemmi
    # application/vividence.scriptfile
    # application/vnd.3gpp-prose+xml
    # application/vnd.3gpp-prose-pc3ch+xml
    # application/vnd.3gpp.access-transfer-events+xml
    # application/vnd.3gpp.bsf+xml
    # application/vnd.3gpp.mid-call+xml
    application/vnd.3gpp.pic-bw-large		plb
    application/vnd.3gpp.pic-bw-small		psb
    application/vnd.3gpp.pic-bw-var			pvb
    # application/vnd.3gpp.sms
    # application/vnd.3gpp.sms+xml
    # application/vnd.3gpp.srvcc-ext+xml
    # application/vnd.3gpp.srvcc-info+xml
    # application/vnd.3gpp.state-and-event-info+xml
    # application/vnd.3gpp.ussd+xml
    # application/vnd.3gpp2.bcmcsinfo+xml
    # application/vnd.3gpp2.sms
    application/vnd.3gpp2.tcap			tcap
    # application/vnd.3lightssoftware.imagescal
    application/vnd.3m.post-it-notes		pwn
    application/vnd.accpac.simply.aso		aso
    application/vnd.accpac.simply.imp		imp
    application/vnd.acucobol			acu
    application/vnd.acucorp				atc acutc
    application/vnd.adobe.air-application-installer-package+zip	air
    # application/vnd.adobe.flash.movie
    application/vnd.adobe.formscentral.fcdt		fcdt
    application/vnd.adobe.fxp			fxp fxpl
    # application/vnd.adobe.partial-upload
    application/vnd.adobe.xdp+xml			xdp
    application/vnd.adobe.xfdf			xfdf
    # application/vnd.aether.imp
    # application/vnd.ah-barcode
    application/vnd.ahead.space			ahead
    application/vnd.airzip.filesecure.azf		azf
    application/vnd.airzip.filesecure.azs		azs
    application/vnd.amazon.ebook			azw
    # application/vnd.amazon.mobi8-ebook
    application/vnd.americandynamics.acc		acc
    application/vnd.amiga.ami			ami
    # application/vnd.amundsen.maze+xml
    application/vnd.android.package-archive		apk
    # application/vnd.anki
    application/vnd.anser-web-certificate-issue-initiation	cii
    application/vnd.anser-web-funds-transfer-initiation	fti
    application/vnd.antix.game-component		atx
    # application/vnd.apache.thrift.binary
    # application/vnd.apache.thrift.compact
    # application/vnd.apache.thrift.json
    # application/vnd.api+json
    application/vnd.apple.installer+xml		mpkg
    application/vnd.apple.mpegurl			m3u8
    # application/vnd.arastra.swi
    application/vnd.aristanetworks.swi		swi
    # application/vnd.artsquare
    application/vnd.astraea-software.iota		iota
    application/vnd.audiograph			aep
    # application/vnd.autopackage
    # application/vnd.avistar+xml
    # application/vnd.balsamiq.bmml+xml
    # application/vnd.balsamiq.bmpr
    # application/vnd.bekitzur-stech+json
    # application/vnd.biopax.rdf+xml
    application/vnd.blueice.multipass		mpm
    # application/vnd.bluetooth.ep.oob
    # application/vnd.bluetooth.le.oob
    application/vnd.bmi				bmi
    application/vnd.businessobjects			rep
    # application/vnd.cab-jscript
    # application/vnd.canon-cpdl
    # application/vnd.canon-lips
    # application/vnd.cendio.thinlinc.clientconf
    # application/vnd.century-systems.tcp_stream
    application/vnd.chemdraw+xml			cdxml
    # application/vnd.chess-pgn
    application/vnd.chipnuts.karaoke-mmd		mmd
    application/vnd.cinderella			cdy
    # application/vnd.cirpack.isdn-ext
    # application/vnd.citationstyles.style+xml
    application/vnd.claymore			cla
    application/vnd.cloanto.rp9			rp9
    application/vnd.clonk.c4group			c4g c4d c4f c4p c4u
    application/vnd.cluetrust.cartomobile-config		c11amc
    application/vnd.cluetrust.cartomobile-config-pkg	c11amz
    # application/vnd.coffeescript
    # application/vnd.collection+json
    # application/vnd.collection.doc+json
    # application/vnd.collection.next+json
    # application/vnd.comicbook+zip
    # application/vnd.commerce-battelle
    application/vnd.commonspace			csp
    application/vnd.contact.cmsg			cdbcmsg
    # application/vnd.coreos.ignition+json
    application/vnd.cosmocaller			cmc
    application/vnd.crick.clicker			clkx
    application/vnd.crick.clicker.keyboard		clkk
    application/vnd.crick.clicker.palette		clkp
    application/vnd.crick.clicker.template		clkt
    application/vnd.crick.clicker.wordbank		clkw
    application/vnd.criticaltools.wbs+xml		wbs
    application/vnd.ctc-posml			pml
    # application/vnd.ctct.ws+xml
    # application/vnd.cups-pdf
    # application/vnd.cups-postscript
    application/vnd.cups-ppd			ppd
    # application/vnd.cups-raster
    # application/vnd.cups-raw
    # application/vnd.curl
    application/vnd.curl.car			car
    application/vnd.curl.pcurl			pcurl
    # application/vnd.cyan.dean.root+xml
    # application/vnd.cybank
    application/vnd.dart				dart
    application/vnd.data-vision.rdz			rdz
    # application/vnd.debian.binary-package
    application/vnd.dece.data			uvf uvvf uvd uvvd
    application/vnd.dece.ttml+xml			uvt uvvt
    application/vnd.dece.unspecified		uvx uvvx
    application/vnd.dece.zip			uvz uvvz
    application/vnd.denovo.fcselayout-link		fe_launch
    # application/vnd.desmume.movie
    # application/vnd.dir-bi.plate-dl-nosuffix
    # application/vnd.dm.delegation+xml
    application/vnd.dna				dna
    # application/vnd.document+json
    application/vnd.dolby.mlp			mlp
    # application/vnd.dolby.mobile.1
    # application/vnd.dolby.mobile.2
    # application/vnd.doremir.scorecloud-binary-document
    application/vnd.dpgraph				dpg
    application/vnd.dreamfactory			dfac
    # application/vnd.drive+json
    application/vnd.ds-keypoint			kpxx
    # application/vnd.dtg.local
    # application/vnd.dtg.local.flash
    # application/vnd.dtg.local.html
    application/vnd.dvb.ait				ait
    # application/vnd.dvb.dvbj
    # application/vnd.dvb.esgcontainer
    # application/vnd.dvb.ipdcdftnotifaccess
    # application/vnd.dvb.ipdcesgaccess
    # application/vnd.dvb.ipdcesgaccess2
    # application/vnd.dvb.ipdcesgpdd
    # application/vnd.dvb.ipdcroaming
    # application/vnd.dvb.iptv.alfec-base
    # application/vnd.dvb.iptv.alfec-enhancement
    # application/vnd.dvb.notif-aggregate-root+xml
    # application/vnd.dvb.notif-container+xml
    # application/vnd.dvb.notif-generic+xml
    # application/vnd.dvb.notif-ia-msglist+xml
    # application/vnd.dvb.notif-ia-registration-request+xml
    # application/vnd.dvb.notif-ia-registration-response+xml
    # application/vnd.dvb.notif-init+xml
    # application/vnd.dvb.pfr
    application/vnd.dvb.service			svc
    # application/vnd.dxr
    application/vnd.dynageo				geo
    # application/vnd.dzr
    # application/vnd.easykaraoke.cdgdownload
    # application/vnd.ecdis-update
    application/vnd.ecowin.chart			mag
    # application/vnd.ecowin.filerequest
    # application/vnd.ecowin.fileupdate
    # application/vnd.ecowin.series
    # application/vnd.ecowin.seriesrequest
    # application/vnd.ecowin.seriesupdate
    # application/vnd.emclient.accessrequest+xml
    application/vnd.enliven				nml
    # application/vnd.enphase.envoy
    # application/vnd.eprints.data+xml
    application/vnd.epson.esf			esf
    application/vnd.epson.msf			msf
    application/vnd.epson.quickanime		qam
    application/vnd.epson.salt			slt
    application/vnd.epson.ssf			ssf
    # application/vnd.ericsson.quickcall
    application/vnd.eszigno3+xml			es3 et3
    # application/vnd.etsi.aoc+xml
    # application/vnd.etsi.asic-e+zip
    # application/vnd.etsi.asic-s+zip
    # application/vnd.etsi.cug+xml
    # application/vnd.etsi.iptvcommand+xml
    # application/vnd.etsi.iptvdiscovery+xml
    # application/vnd.etsi.iptvprofile+xml
    # application/vnd.etsi.iptvsad-bc+xml
    # application/vnd.etsi.iptvsad-cod+xml
    # application/vnd.etsi.iptvsad-npvr+xml
    # application/vnd.etsi.iptvservice+xml
    # application/vnd.etsi.iptvsync+xml
    # application/vnd.etsi.iptvueprofile+xml
    # application/vnd.etsi.mcid+xml
    # application/vnd.etsi.mheg5
    # application/vnd.etsi.overload-control-policy-dataset+xml
    # application/vnd.etsi.pstn+xml
    # application/vnd.etsi.sci+xml
    # application/vnd.etsi.simservs+xml
    # application/vnd.etsi.timestamp-token
    # application/vnd.etsi.tsl+xml
    # application/vnd.etsi.tsl.der
    # application/vnd.eudora.data
    application/vnd.ezpix-album			ez2
    application/vnd.ezpix-package			ez3
    # application/vnd.f-secure.mobile
    # application/vnd.fastcopy-disk-image
    application/vnd.fdf				fdf
    application/vnd.fdsn.mseed			mseed
    application/vnd.fdsn.seed			seed dataless
    # application/vnd.ffsns
    # application/vnd.filmit.zfc
    # application/vnd.fints
    # application/vnd.firemonkeys.cloudcell
    application/vnd.flographit			gph
    application/vnd.fluxtime.clip			ftc
    # application/vnd.font-fontforge-sfd
    application/vnd.framemaker			fm frame maker book
    application/vnd.frogans.fnc			fnc
    application/vnd.frogans.ltf			ltf
    application/vnd.fsc.weblaunch			fsc
    application/vnd.fujitsu.oasys			oas
    application/vnd.fujitsu.oasys2			oa2
    application/vnd.fujitsu.oasys3			oa3
    application/vnd.fujitsu.oasysgp			fg5
    application/vnd.fujitsu.oasysprs		bh2
    # application/vnd.fujixerox.art-ex
    # application/vnd.fujixerox.art4
    application/vnd.fujixerox.ddd			ddd
    application/vnd.fujixerox.docuworks		xdw
    application/vnd.fujixerox.docuworks.binder	xbd
    # application/vnd.fujixerox.docuworks.container
    # application/vnd.fujixerox.hbpl
    # application/vnd.fut-misnet
    application/vnd.fuzzysheet			fzs
    application/vnd.genomatix.tuxedo		txd
    # application/vnd.geo+json
    # application/vnd.geocube+xml
    application/vnd.geogebra.file			ggb
    application/vnd.geogebra.slides		ggs
    application/vnd.geogebra.tool			ggt
    application/vnd.geometry-explorer		gex gre
    application/vnd.geonext				gxt
    application/vnd.geoplan				g2w
    application/vnd.geospace			g3w
    # application/vnd.gerber
    # application/vnd.globalplatform.card-content-mgt
    # application/vnd.globalplatform.card-content-mgt-response
    application/vnd.gmx				gmx
    application/vnd.google-earth.kml+xml		kml
    application/vnd.google-earth.kmz		kmz
    # application/vnd.gov.sk.e-form+xml
    # application/vnd.gov.sk.e-form+zip
    # application/vnd.gov.sk.xmldatacontainer+xml
    application/vnd.grafeq				gqf gqs
    # application/vnd.gridmp
    application/vnd.groove-account			gac
    application/vnd.groove-help			ghf
    application/vnd.groove-identity-message		gim
    application/vnd.groove-injector			grv
    application/vnd.groove-tool-message		gtm
    application/vnd.groove-tool-template		tpl
    application/vnd.groove-vcard			vcg
    # application/vnd.hal+json
    application/vnd.hal+xml				hal
    application/vnd.handheld-entertainment+xml	zmm
    application/vnd.hbci				hbci
    # application/vnd.hcl-bireports
    # application/vnd.hdt
    # application/vnd.heroku+json
    application/vnd.hhe.lesson-player		les
    application/vnd.hp-hpgl				hpgl
    application/vnd.hp-hpid				hpid
    application/vnd.hp-hps				hps
    application/vnd.hp-jlyt				jlt
    application/vnd.hp-pcl				pcl
    application/vnd.hp-pclxl			pclxl
    # application/vnd.httphone
    application/vnd.hydrostatix.sof-data		sfd-hdstx
    # application/vnd.hyperdrive+json
    # application/vnd.hzn-3d-crossword
    # application/vnd.ibm.afplinedata
    # application/vnd.ibm.electronic-media
    application/vnd.ibm.minipay			mpy
    application/vnd.ibm.modcap			afp listafp list3820
    application/vnd.ibm.rights-management		irm
    application/vnd.ibm.secure-container		sc
    application/vnd.iccprofile			icc icm
    # application/vnd.ieee.1905
    application/vnd.igloader			igl
    application/vnd.immervision-ivp			ivp
    application/vnd.immervision-ivu			ivu
    # application/vnd.ims.imsccv1p1
    # application/vnd.ims.imsccv1p2
    # application/vnd.ims.imsccv1p3
    # application/vnd.ims.lis.v2.result+json
    # application/vnd.ims.lti.v2.toolconsumerprofile+json
    # application/vnd.ims.lti.v2.toolproxy+json
    # application/vnd.ims.lti.v2.toolproxy.id+json
    # application/vnd.ims.lti.v2.toolsettings+json
    # application/vnd.ims.lti.v2.toolsettings.simple+json
    # application/vnd.informedcontrol.rms+xml
    # application/vnd.informix-visionary
    # application/vnd.infotech.project
    # application/vnd.infotech.project+xml
    # application/vnd.innopath.wamp.notification
    application/vnd.insors.igm			igm
    application/vnd.intercon.formnet		xpw xpx
    application/vnd.intergeo			i2g
    # application/vnd.intertrust.digibox
    # application/vnd.intertrust.nncp
    application/vnd.intu.qbo			qbo
    application/vnd.intu.qfx			qfx
    # application/vnd.iptc.g2.catalogitem+xml
    # application/vnd.iptc.g2.conceptitem+xml
    # application/vnd.iptc.g2.knowledgeitem+xml
    # application/vnd.iptc.g2.newsitem+xml
    # application/vnd.iptc.g2.newsmessage+xml
    # application/vnd.iptc.g2.packageitem+xml
    # application/vnd.iptc.g2.planningitem+xml
    application/vnd.ipunplugged.rcprofile		rcprofile
    application/vnd.irepository.package+xml		irp
    application/vnd.is-xpr				xpr
    application/vnd.isac.fcs			fcs
    application/vnd.jam				jam
    # 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.jcp.javame.midlet-rms		rms
    application/vnd.jisp				jisp
    application/vnd.joost.joda-archive		joda
    # application/vnd.jsk.isdn-ngn
    application/vnd.kahootz				ktz ktr
    application/vnd.kde.karbon			karbon
    application/vnd.kde.kchart			chrt
    application/vnd.kde.kformula			kfo
    application/vnd.kde.kivio			flw
    application/vnd.kde.kontour			kon
    application/vnd.kde.kpresenter			kpr kpt
    application/vnd.kde.kspread			ksp
    application/vnd.kde.kword			kwd kwt
    application/vnd.kenameaapp			htke
    application/vnd.kidspiration			kia
    application/vnd.kinar				kne knp
    application/vnd.koan				skp skd skt skm
    application/vnd.kodak-descriptor		sse
    application/vnd.las.las+xml			lasxml
    # application/vnd.liberty-request+xml
    application/vnd.llamagraphics.life-balance.desktop	lbd
    application/vnd.llamagraphics.life-balance.exchange+xml	lbe
    application/vnd.lotus-1-2-3			123
    application/vnd.lotus-approach			apr
    application/vnd.lotus-freelance			pre
    application/vnd.lotus-notes			nsf
    application/vnd.lotus-organizer			org
    application/vnd.lotus-screencam			scm
    application/vnd.lotus-wordpro			lwp
    application/vnd.macports.portpkg		portpkg
    # application/vnd.mapbox-vector-tile
    # application/vnd.marlin.drm.actiontoken+xml
    # application/vnd.marlin.drm.conftoken+xml
    # application/vnd.marlin.drm.license+xml
    # application/vnd.marlin.drm.mdcf
    # application/vnd.mason+json
    # application/vnd.maxmind.maxmind-db
    application/vnd.mcd				mcd
    application/vnd.medcalcdata			mc1
    application/vnd.mediastation.cdkey		cdkey
    # application/vnd.meridian-slingshot
    application/vnd.mfer				mwf
    application/vnd.mfmp				mfm
    # application/vnd.micro+json
    application/vnd.micrografx.flo			flo
    application/vnd.micrografx.igx			igx
    # application/vnd.microsoft.portable-executable
    # application/vnd.miele+json
    application/vnd.mif				mif
    # application/vnd.minisoft-hp3000-save
    # application/vnd.mitsubishi.misty-guard.trustweb
    application/vnd.mobius.daf			daf
    application/vnd.mobius.dis			dis
    application/vnd.mobius.mbk			mbk
    application/vnd.mobius.mqy			mqy
    application/vnd.mobius.msl			msl
    application/vnd.mobius.plc			plc
    application/vnd.mobius.txf			txf
    application/vnd.mophun.application		mpn
    application/vnd.mophun.certificate		mpc
    # 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.motorola.iprm
    application/vnd.mozilla.xul+xml			xul
    # application/vnd.ms-3mfdocument
    application/vnd.ms-artgalry			cil
    # application/vnd.ms-asf
    application/vnd.ms-cab-compressed		cab
    # application/vnd.ms-color.iccprofile
    application/vnd.ms-excel			xls xlm xla xlc xlt xlw
    application/vnd.ms-excel.addin.macroenabled.12		xlam
    application/vnd.ms-excel.sheet.binary.macroenabled.12	xlsb
    application/vnd.ms-excel.sheet.macroenabled.12		xlsm
    application/vnd.ms-excel.template.macroenabled.12	xltm
    application/vnd.ms-fontobject			eot
    application/vnd.ms-htmlhelp			chm
    application/vnd.ms-ims				ims
    application/vnd.ms-lrm				lrm
    # application/vnd.ms-office.activex+xml
    application/vnd.ms-officetheme			thmx
    # application/vnd.ms-opentype
    # application/vnd.ms-package.obfuscated-opentype
    application/vnd.ms-pki.seccat			cat
    application/vnd.ms-pki.stl			stl
    # application/vnd.ms-playready.initiator+xml
    application/vnd.ms-powerpoint			ppt pps pot
    application/vnd.ms-powerpoint.addin.macroenabled.12		ppam
    application/vnd.ms-powerpoint.presentation.macroenabled.12	pptm
    application/vnd.ms-powerpoint.slide.macroenabled.12		sldm
    application/vnd.ms-powerpoint.slideshow.macroenabled.12		ppsm
    application/vnd.ms-powerpoint.template.macroenabled.12		potm
    # application/vnd.ms-printdevicecapabilities+xml
    # application/vnd.ms-printing.printticket+xml
    # application/vnd.ms-printschematicket+xml
    application/vnd.ms-project			mpp mpt
    # application/vnd.ms-tnef
    # application/vnd.ms-windows.devicepairing
    # application/vnd.ms-windows.nwprinting.oob
    # application/vnd.ms-windows.printerpairing
    # application/vnd.ms-windows.wsd.oob
    # application/vnd.ms-wmdrm.lic-chlg-req
    # application/vnd.ms-wmdrm.lic-resp
    # application/vnd.ms-wmdrm.meter-chlg-req
    # application/vnd.ms-wmdrm.meter-resp
    application/vnd.ms-word.document.macroenabled.12	docm
    application/vnd.ms-word.template.macroenabled.12	dotm
    application/vnd.ms-works			wps wks wcm wdb
    application/vnd.ms-wpl				wpl
    application/vnd.ms-xpsdocument			xps
    # application/vnd.msa-disk-image
    application/vnd.mseq				mseq
    # application/vnd.msign
    # application/vnd.multiad.creator
    # application/vnd.multiad.creator.cif
    # application/vnd.music-niff
    application/vnd.musician			mus
    application/vnd.muvee.style			msty
    application/vnd.mynfc				taglet
    # application/vnd.ncd.control
    # application/vnd.ncd.reference
    # application/vnd.nervana
    # application/vnd.netfpx
    application/vnd.neurolanguage.nlu		nlu
    # application/vnd.nintendo.nitro.rom
    # application/vnd.nintendo.snes.rom
    application/vnd.nitf				ntf nitf
    application/vnd.noblenet-directory		nnd
    application/vnd.noblenet-sealer			nns
    application/vnd.noblenet-web			nnw
    # application/vnd.nokia.catalogs
    # application/vnd.nokia.conml+wbxml
    # application/vnd.nokia.conml+xml
    # application/vnd.nokia.iptv.config+xml
    # application/vnd.nokia.isds-radio-presets
    # application/vnd.nokia.landmark+wbxml
    # application/vnd.nokia.landmark+xml
    # application/vnd.nokia.landmarkcollection+xml
    # application/vnd.nokia.n-gage.ac+xml
    application/vnd.nokia.n-gage.data		ngdat
    application/vnd.nokia.n-gage.symbian.install	n-gage
    # application/vnd.nokia.ncd
    # application/vnd.nokia.pcd+wbxml
    # application/vnd.nokia.pcd+xml
    application/vnd.nokia.radio-preset		rpst
    application/vnd.nokia.radio-presets		rpss
    application/vnd.novadigm.edm			edm
    application/vnd.novadigm.edx			edx
    application/vnd.novadigm.ext			ext
    # application/vnd.ntt-local.content-share
    # application/vnd.ntt-local.file-transfer
    # application/vnd.ntt-local.ogw_remote-access
    # application/vnd.ntt-local.sip-ta_remote
    # application/vnd.ntt-local.sip-ta_tcp_stream
    application/vnd.oasis.opendocument.chart		odc
    application/vnd.oasis.opendocument.chart-template	otc
    application/vnd.oasis.opendocument.database		odb
    application/vnd.oasis.opendocument.formula		odf
    application/vnd.oasis.opendocument.formula-template	odft
    application/vnd.oasis.opendocument.graphics		odg
    application/vnd.oasis.opendocument.graphics-template	otg
    application/vnd.oasis.opendocument.image		odi
    application/vnd.oasis.opendocument.image-template	oti
    application/vnd.oasis.opendocument.presentation		odp
    application/vnd.oasis.opendocument.presentation-template	otp
    application/vnd.oasis.opendocument.spreadsheet		ods
    application/vnd.oasis.opendocument.spreadsheet-template	ots
    application/vnd.oasis.opendocument.text			odt
    application/vnd.oasis.opendocument.text-master		odm
    application/vnd.oasis.opendocument.text-template	ott
    application/vnd.oasis.opendocument.text-web		oth
    # application/vnd.obn
    # application/vnd.oftn.l10n+json
    # application/vnd.oipf.contentaccessdownload+xml
    # application/vnd.oipf.contentaccessstreaming+xml
    # application/vnd.oipf.cspg-hexbinary
    # application/vnd.oipf.dae.svg+xml
    # application/vnd.oipf.dae.xhtml+xml
    # application/vnd.oipf.mippvcontrolmessage+xml
    # application/vnd.oipf.pae.gem
    # application/vnd.oipf.spdiscovery+xml
    # application/vnd.oipf.spdlist+xml
    # application/vnd.oipf.ueprofile+xml
    # application/vnd.oipf.userprofile+xml
    application/vnd.olpc-sugar			xo
    # application/vnd.oma-scws-config
    # application/vnd.oma-scws-http-request
    # application/vnd.oma-scws-http-response
    # application/vnd.oma.bcast.associated-procedure-parameter+xml
    # application/vnd.oma.bcast.drm-trigger+xml
    # application/vnd.oma.bcast.imd+xml
    # application/vnd.oma.bcast.ltkm
    # application/vnd.oma.bcast.notification+xml
    # application/vnd.oma.bcast.provisioningtrigger
    # application/vnd.oma.bcast.sgboot
    # application/vnd.oma.bcast.sgdd+xml
    # application/vnd.oma.bcast.sgdu
    # application/vnd.oma.bcast.simple-symbol-container
    # application/vnd.oma.bcast.smartcard-trigger+xml
    # application/vnd.oma.bcast.sprov+xml
    # application/vnd.oma.bcast.stkm
    # application/vnd.oma.cab-address-book+xml
    # application/vnd.oma.cab-feature-handler+xml
    # application/vnd.oma.cab-pcc+xml
    # application/vnd.oma.cab-subs-invite+xml
    # application/vnd.oma.cab-user-prefs+xml
    # application/vnd.oma.dcd
    # application/vnd.oma.dcdc
    application/vnd.oma.dd2+xml			dd2
    # application/vnd.oma.drm.risd+xml
    # application/vnd.oma.group-usage-list+xml
    # application/vnd.oma.lwm2m+json
    # application/vnd.oma.lwm2m+tlv
    # application/vnd.oma.pal+xml
    # application/vnd.oma.poc.detailed-progress-report+xml
    # application/vnd.oma.poc.final-report+xml
    # application/vnd.oma.poc.groups+xml
    # application/vnd.oma.poc.invocation-descriptor+xml
    # application/vnd.oma.poc.optimized-progress-report+xml
    # application/vnd.oma.push
    # application/vnd.oma.scidm.messages+xml
    # application/vnd.oma.xcap-directory+xml
    # application/vnd.omads-email+xml
    # application/vnd.omads-file+xml
    # application/vnd.omads-folder+xml
    # application/vnd.omaloc-supl-init
    # application/vnd.onepager
    # application/vnd.openblox.game+xml
    # application/vnd.openblox.game-binary
    # application/vnd.openeye.oeb
    application/vnd.openofficeorg.extension		oxt
    # application/vnd.openxmlformats-officedocument.custom-properties+xml
    # application/vnd.openxmlformats-officedocument.customxmlproperties+xml
    # application/vnd.openxmlformats-officedocument.drawing+xml
    # application/vnd.openxmlformats-officedocument.drawingml.chart+xml
    # application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml
    # application/vnd.openxmlformats-officedocument.extended-properties+xml
    # application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml
    # application/vnd.openxmlformats-officedocument.presentationml.comments+xml
    # application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml
    # application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml
    # application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml
    application/vnd.openxmlformats-officedocument.presentationml.presentation	pptx
    # application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
    # application/vnd.openxmlformats-officedocument.presentationml.presprops+xml
    application/vnd.openxmlformats-officedocument.presentationml.slide	sldx
    # application/vnd.openxmlformats-officedocument.presentationml.slide+xml
    # application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml
    # application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml
    application/vnd.openxmlformats-officedocument.presentationml.slideshow	ppsx
    # application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
    # application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml
    # application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml
    # application/vnd.openxmlformats-officedocument.presentationml.tags+xml
    application/vnd.openxmlformats-officedocument.presentationml.template	potx
    # application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
    # application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet	xlsx
    # application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml
    application/vnd.openxmlformats-officedocument.spreadsheetml.template	xltx
    # application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
    # application/vnd.openxmlformats-officedocument.theme+xml
    # application/vnd.openxmlformats-officedocument.themeoverride+xml
    # application/vnd.openxmlformats-officedocument.vmldrawing
    # application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
    application/vnd.openxmlformats-officedocument.wordprocessingml.document	docx
    # application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
    application/vnd.openxmlformats-officedocument.wordprocessingml.template	dotx
    # application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml
    # application/vnd.openxmlformats-package.core-properties+xml
    # application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
    # application/vnd.openxmlformats-package.relationships+xml
    # application/vnd.oracle.resource+json
    # application/vnd.orange.indata
    # application/vnd.osa.netdeploy
    application/vnd.osgeo.mapguide.package		mgp
    # application/vnd.osgi.bundle
    application/vnd.osgi.dp				dp
    application/vnd.osgi.subsystem			esa
    # application/vnd.otps.ct-kip+xml
    # application/vnd.oxli.countgraph
    # application/vnd.pagerduty+json
    application/vnd.palm				pdb pqa oprc
    # application/vnd.panoply
    # application/vnd.paos.xml
    application/vnd.pawaafile			paw
    # application/vnd.pcos
    application/vnd.pg.format			str
    application/vnd.pg.osasli			ei6
    # application/vnd.piaccess.application-licence
    application/vnd.picsel				efif
    application/vnd.pmi.widget			wg
    # application/vnd.poc.group-advertisement+xml
    application/vnd.pocketlearn			plf
    application/vnd.powerbuilder6			pbd
    # application/vnd.powerbuilder6-s
    # application/vnd.powerbuilder7
    # application/vnd.powerbuilder7-s
    # application/vnd.powerbuilder75
    # application/vnd.powerbuilder75-s
    # application/vnd.preminet
    application/vnd.previewsystems.box		box
    application/vnd.proteus.magazine		mgz
    application/vnd.publishare-delta-tree		qps
    application/vnd.pvi.ptid1			ptid
    # application/vnd.pwg-multiplexed
    # application/vnd.pwg-xhtml-print+xml
    # application/vnd.qualcomm.brew-app-res
    # application/vnd.quarantainenet
    application/vnd.quark.quarkxpress		qxd qxt qwd qwt qxl qxb
    # application/vnd.quobject-quoxdocument
    # application/vnd.radisys.moml+xml
    # application/vnd.radisys.msml+xml
    # application/vnd.radisys.msml-audit+xml
    # application/vnd.radisys.msml-audit-conf+xml
    # application/vnd.radisys.msml-audit-conn+xml
    # application/vnd.radisys.msml-audit-dialog+xml
    # application/vnd.radisys.msml-audit-stream+xml
    # application/vnd.radisys.msml-conf+xml
    # application/vnd.radisys.msml-dialog+xml
    # application/vnd.radisys.msml-dialog-base+xml
    # application/vnd.radisys.msml-dialog-fax-detect+xml
    # application/vnd.radisys.msml-dialog-fax-sendrecv+xml
    # application/vnd.radisys.msml-dialog-group+xml
    # application/vnd.radisys.msml-dialog-speech+xml
    # application/vnd.radisys.msml-dialog-transform+xml
    # application/vnd.rainstor.data
    # application/vnd.rapid
    # application/vnd.rar
    application/vnd.realvnc.bed			bed
    application/vnd.recordare.musicxml		mxl
    application/vnd.recordare.musicxml+xml		musicxml
    # application/vnd.renlearn.rlprint
    application/vnd.rig.cryptonote			cryptonote
    application/vnd.rim.cod				cod
    application/vnd.rn-realmedia			rm
    application/vnd.rn-realmedia-vbr		rmvb
    application/vnd.route66.link66+xml		link66
    # application/vnd.rs-274x
    # application/vnd.ruckus.download
    # application/vnd.s3sms
    application/vnd.sailingtracker.track		st
    # application/vnd.sbm.cid
    # application/vnd.sbm.mid2
    # application/vnd.scribus
    # application/vnd.sealed.3df
    # application/vnd.sealed.csf
    # application/vnd.sealed.doc
    # application/vnd.sealed.eml
    # application/vnd.sealed.mht
    # application/vnd.sealed.net
    # application/vnd.sealed.ppt
    # application/vnd.sealed.tiff
    # application/vnd.sealed.xls
    # application/vnd.sealedmedia.softseal.html
    # application/vnd.sealedmedia.softseal.pdf
    application/vnd.seemail				see
    application/vnd.sema				sema
    application/vnd.semd				semd
    application/vnd.semf				semf
    application/vnd.shana.informed.formdata		ifm
    application/vnd.shana.informed.formtemplate	itp
    application/vnd.shana.informed.interchange	iif
    application/vnd.shana.informed.package		ipk
    application/vnd.simtech-mindmapper		twd twds
    # application/vnd.siren+json
    application/vnd.smaf				mmf
    # application/vnd.smart.notebook
    application/vnd.smart.teacher			teacher
    # application/vnd.software602.filler.form+xml
    # application/vnd.software602.filler.form-xml-zip
    application/vnd.solent.sdkm+xml			sdkm sdkd
    application/vnd.spotfire.dxp			dxp
    application/vnd.spotfire.sfs			sfs
    # application/vnd.sss-cod
    # application/vnd.sss-dtf
    # application/vnd.sss-ntf
    application/vnd.stardivision.calc		sdc
    application/vnd.stardivision.draw		sda
    application/vnd.stardivision.impress		sdd
    application/vnd.stardivision.math		smf
    application/vnd.stardivision.writer		sdw vor
    application/vnd.stardivision.writer-global	sgl
    application/vnd.stepmania.package		smzip
    application/vnd.stepmania.stepchart		sm
    # application/vnd.street-stream
    # application/vnd.sun.wadl+xml
    application/vnd.sun.xml.calc			sxc
    application/vnd.sun.xml.calc.template		stc
    application/vnd.sun.xml.draw			sxd
    application/vnd.sun.xml.draw.template		std
    application/vnd.sun.xml.impress			sxi
    application/vnd.sun.xml.impress.template	sti
    application/vnd.sun.xml.math			sxm
    application/vnd.sun.xml.writer			sxw
    application/vnd.sun.xml.writer.global		sxg
    application/vnd.sun.xml.writer.template		stw
    application/vnd.sus-calendar			sus susp
    application/vnd.svd				svd
    # application/vnd.swiftview-ics
    application/vnd.symbian.install			sis sisx
    application/vnd.syncml+xml			xsm
    application/vnd.syncml.dm+wbxml			bdm
    application/vnd.syncml.dm+xml			xdm
    # application/vnd.syncml.dm.notification
    # application/vnd.syncml.dmddf+wbxml
    # application/vnd.syncml.dmddf+xml
    # application/vnd.syncml.dmtnds+wbxml
    # application/vnd.syncml.dmtnds+xml
    # application/vnd.syncml.ds.notification
    application/vnd.tao.intent-module-archive	tao
    application/vnd.tcpdump.pcap			pcap cap dmp
    # application/vnd.tmd.mediaflex.api+xml
    # application/vnd.tml
    application/vnd.tmobile-livetv			tmo
    application/vnd.trid.tpt			tpt
    application/vnd.triscape.mxs			mxs
    application/vnd.trueapp				tra
    # application/vnd.truedoc
    # application/vnd.ubisoft.webplayer
    application/vnd.ufdl				ufd ufdl
    application/vnd.uiq.theme			utz
    application/vnd.umajin				umj
    application/vnd.unity				unityweb
    application/vnd.uoml+xml			uoml
    # 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.uri-map
    # application/vnd.valve.source.material
    application/vnd.vcx				vcx
    # application/vnd.vd-study
    # application/vnd.vectorworks
    # application/vnd.vel+json
    # application/vnd.verimatrix.vcas
    # application/vnd.vidsoft.vidconference
    application/vnd.visio				vsd vst vss vsw
    application/vnd.visionary			vis
    # application/vnd.vividence.scriptfile
    application/vnd.vsf				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			wtb
    # application/vnd.wfa.p2p
    # application/vnd.wfa.wsc
    # application/vnd.windows.devicepairing
    # application/vnd.wmc
    # application/vnd.wmf.bootstrap
    # application/vnd.wolfram.mathematica
    # application/vnd.wolfram.mathematica.package
    application/vnd.wolfram.player			nbp
    application/vnd.wordperfect			wpd
    application/vnd.wqd				wqd
    # application/vnd.wrq-hp3000-labelled
    application/vnd.wt.stf				stf
    # application/vnd.wv.csp+wbxml
    # application/vnd.wv.csp+xml
    # application/vnd.wv.ssp+xml
    # application/vnd.xacml+json
    application/vnd.xara				xar
    application/vnd.xfdl				xfdl
    # application/vnd.xfdl.webform
    # application/vnd.xmi+xml
    # application/vnd.xmpie.cpkg
    # application/vnd.xmpie.dpkg
    # application/vnd.xmpie.plan
    # application/vnd.xmpie.ppkg
    # application/vnd.xmpie.xlim
    application/vnd.yamaha.hv-dic			hvd
    application/vnd.yamaha.hv-script		hvs
    application/vnd.yamaha.hv-voice			hvp
    application/vnd.yamaha.openscoreformat			osf
    application/vnd.yamaha.openscoreformat.osfpvg+xml	osfpvg
    # application/vnd.yamaha.remote-setup
    application/vnd.yamaha.smaf-audio		saf
    application/vnd.yamaha.smaf-phrase		spf
    # application/vnd.yamaha.through-ngn
    # application/vnd.yamaha.tunnel-udpencap
    # application/vnd.yaoweme
    application/vnd.yellowriver-custom-menu		cmp
    application/vnd.zul				zir zirz
    application/vnd.zzazz.deck+xml			zaz
    application/voicexml+xml			vxml
    # application/vq-rtcpxr
    application/wasm				wasm
    # application/watcherinfo+xml
    # application/whoispp-query
    # application/whoispp-response
    application/widget				wgt
    application/winhlp				hlp
    # application/wita
    # application/wordperfect5.1
    application/wsdl+xml				wsdl
    application/wspolicy+xml			wspolicy
    application/x-7z-compressed			7z
    application/x-abiword				abw
    application/x-ace-compressed			ace
    # application/x-amf
    application/x-apple-diskimage			dmg
    application/x-authorware-bin			aab x32 u32 vox
    application/x-authorware-map			aam
    application/x-authorware-seg			aas
    application/x-bcpio				bcpio
    application/x-bittorrent			torrent
    application/x-blorb				blb blorb
    application/x-bzip				bz
    application/x-bzip2				bz2 boz
    application/x-cbr				cbr cba cbt cbz cb7
    application/x-cdlink				vcd
    application/x-cfs-compressed			cfs
    application/x-chat				chat
    application/x-chess-pgn				pgn
    # application/x-compress
    application/x-conference			nsc
    application/x-cpio				cpio
    application/x-csh				csh
    application/x-debian-package			deb udeb
    application/x-dgc-compressed			dgc
    application/x-director			dir dcr dxr cst cct cxt w3d fgd swa
    application/x-doom				wad
    application/x-dtbncx+xml			ncx
    application/x-dtbook+xml			dtb
    application/x-dtbresource+xml			res
    application/x-dvi				dvi
    application/x-envoy				evy
    application/x-eva				eva
    application/x-font-bdf				bdf
    # application/x-font-dos
    # application/x-font-framemaker
    application/x-font-ghostscript			gsf
    # application/x-font-libgrx
    application/x-font-linux-psf			psf
    application/x-font-pcf				pcf
    application/x-font-snf				snf
    # application/x-font-speedo
    # application/x-font-sunos-news
    application/x-font-type1			pfa pfb pfm afm
    # application/x-font-vfont
    application/x-freearc				arc
    application/x-futuresplash			spl
    application/x-gca-compressed			gca
    application/x-glulx				ulx
    application/x-gnumeric				gnumeric
    application/x-gramps-xml			gramps
    application/x-gtar				gtar
    # application/x-gzip
    application/x-hdf				hdf
    application/x-install-instructions		install
    application/x-iso9660-image			iso
    application/x-java-jnlp-file			jnlp
    application/x-latex				latex
    application/x-lzh-compressed			lzh lha
    application/x-mie				mie
    application/x-mobipocket-ebook			prc mobi
    application/x-ms-application			application
    application/x-ms-shortcut			lnk
    application/x-ms-wmd				wmd
    application/x-ms-wmz				wmz
    application/x-ms-xbap				xbap
    application/x-msaccess				mdb
    application/x-msbinder				obd
    application/x-mscardfile			crd
    application/x-msclip				clp
    application/x-msdownload			exe dll com bat msi
    application/x-msmediaview			mvb m13 m14
    application/x-msmetafile			wmf wmz emf emz
    application/x-msmoney				mny
    application/x-mspublisher			pub
    application/x-msschedule			scd
    application/x-msterminal			trm
    application/x-mswrite				wri
    application/x-netcdf				nc cdf
    application/x-nzb				nzb
    application/x-pkcs12				p12 pfx
    application/x-pkcs7-certificates		p7b spc
    application/x-pkcs7-certreqresp			p7r
    application/x-rar-compressed			rar
    application/x-research-info-systems		ris
    application/x-sh				sh
    application/x-shar				shar
    application/x-shockwave-flash			swf
    application/x-silverlight-app			xap
    application/x-sql				sql
    application/x-stuffit				sit
    application/x-stuffitx				sitx
    application/x-subrip				srt
    application/x-sv4cpio				sv4cpio
    application/x-sv4crc				sv4crc
    application/x-t3vm-image			t3
    application/x-tads				gam
    application/x-tar				tar
    application/x-tcl				tcl
    application/x-tex				tex
    application/x-tex-tfm				tfm
    application/x-texinfo				texinfo texi
    application/x-tgif				obj
    application/x-ustar				ustar
    application/x-wais-source			src
    # application/x-www-form-urlencoded
    application/x-x509-ca-cert			der crt
    application/x-xfig				fig
    application/x-xliff+xml				xlf
    application/x-xpinstall				xpi
    application/x-xz				xz
    application/x-zmachine				z1 z2 z3 z4 z5 z6 z7 z8
    # application/x400-bp
    # application/xacml+xml
    application/xaml+xml				xaml
    # application/xcap-att+xml
    # application/xcap-caps+xml
    application/xcap-diff+xml			xdf
    # application/xcap-el+xml
    # application/xcap-error+xml
    # application/xcap-ns+xml
    # application/xcon-conference-info+xml
    # application/xcon-conference-info-diff+xml
    application/xenc+xml				xenc
    application/xhtml+xml				xhtml xht
    # application/xhtml-voice+xml
    application/xml					xml xsl
    application/xml-dtd				dtd
    # application/xml-external-parsed-entity
    # application/xml-patch+xml
    # application/xmpp+xml
    application/xop+xml				xop
    application/xproc+xml				xpl
    application/xslt+xml				xslt
    application/xspf+xml				xspf
    application/xv+xml				mxml xhvml xvml xvm
    application/yang				yang
    application/yin+xml				yin
    application/zip					zip
    # application/zlib
    # audio/1d-interleaved-parityfec
    # audio/32kadpcm
    # audio/3gpp
    # audio/3gpp2
    # audio/ac3
    audio/adpcm					adp
    # audio/amr
    # audio/amr-wb
    # audio/amr-wb+
    # audio/aptx
    # audio/asc
    # audio/atrac-advanced-lossless
    # audio/atrac-x
    # audio/atrac3
    audio/basic					au snd
    # audio/bv16
    # audio/bv32
    # audio/clearmode
    # audio/cn
    # audio/dat12
    # audio/dls
    # audio/dsr-es201108
    # audio/dsr-es202050
    # audio/dsr-es202211
    # audio/dsr-es202212
    # audio/dv
    # audio/dvi4
    # audio/eac3
    # audio/encaprtp
    # audio/evrc
    # audio/evrc-qcp
    # audio/evrc0
    # audio/evrc1
    # audio/evrcb
    # audio/evrcb0
    # audio/evrcb1
    # audio/evrcnw
    # audio/evrcnw0
    # audio/evrcnw1
    # audio/evrcwb
    # audio/evrcwb0
    # audio/evrcwb1
    # audio/evs
    # audio/example
    # audio/fwdred
    # audio/g711-0
    # audio/g719
    # audio/g722
    # audio/g7221
    # audio/g723
    # audio/g726-16
    # audio/g726-24
    # audio/g726-32
    # audio/g726-40
    # audio/g728
    # audio/g729
    # audio/g7291
    # audio/g729d
    # audio/g729e
    # audio/gsm
    # audio/gsm-efr
    # audio/gsm-hr-08
    # audio/ilbc
    # audio/ip-mr_v2.5
    # audio/isac
    # audio/l16
    # audio/l20
    # audio/l24
    # audio/l8
    # audio/lpc
    audio/midi					mid midi kar rmi
    # audio/mobile-xmf
    audio/mp4					m4a mp4a
    # audio/mp4a-latm
    # audio/mpa
    # audio/mpa-robust
    audio/mpeg					mpga mp2 mp2a mp3 m2a m3a
    # audio/mpeg4-generic
    # audio/musepack
    audio/ogg					oga ogg spx opus
    # audio/opus
    # audio/parityfec
    # audio/pcma
    # audio/pcma-wb
    # audio/pcmu
    # audio/pcmu-wb
    # audio/prs.sid
    # audio/qcelp
    # audio/raptorfec
    # audio/red
    # audio/rtp-enc-aescm128
    # audio/rtp-midi
    # audio/rtploopback
    # audio/rtx
    audio/s3m					s3m
    audio/silk					sil
    # audio/smv
    # audio/smv-qcp
    # audio/smv0
    # audio/sp-midi
    # audio/speex
    # audio/t140c
    # audio/t38
    # audio/telephone-event
    # audio/tone
    # audio/uemclip
    # audio/ulpfec
    # audio/vdvi
    # audio/vmr-wb
    # audio/vnd.3gpp.iufp
    # audio/vnd.4sb
    # audio/vnd.audiokoz
    # audio/vnd.celp
    # audio/vnd.cisco.nse
    # audio/vnd.cmles.radio-events
    # audio/vnd.cns.anp1
    # audio/vnd.cns.inf1
    audio/vnd.dece.audio				uva uvva
    audio/vnd.digital-winds				eol
    # audio/vnd.dlna.adts
    # audio/vnd.dolby.heaac.1
    # audio/vnd.dolby.heaac.2
    # audio/vnd.dolby.mlp
    # audio/vnd.dolby.mps
    # audio/vnd.dolby.pl2
    # audio/vnd.dolby.pl2x
    # audio/vnd.dolby.pl2z
    # audio/vnd.dolby.pulse.1
    audio/vnd.dra					dra
    audio/vnd.dts					dts
    audio/vnd.dts.hd				dtshd
    # audio/vnd.dvb.file
    # audio/vnd.everad.plj
    # audio/vnd.hns.audio
    audio/vnd.lucent.voice				lvp
    audio/vnd.ms-playready.media.pya		pya
    # audio/vnd.nokia.mobile-xmf
    # audio/vnd.nortel.vbk
    audio/vnd.nuera.ecelp4800			ecelp4800
    audio/vnd.nuera.ecelp7470			ecelp7470
    audio/vnd.nuera.ecelp9600			ecelp9600
    # audio/vnd.octel.sbc
    # audio/vnd.qcelp
    # audio/vnd.rhetorex.32kadpcm
    audio/vnd.rip					rip
    # audio/vnd.sealedmedia.softseal.mpeg
    # audio/vnd.vmx.cvsd
    # audio/vorbis
    # audio/vorbis-config
    audio/webm					weba
    audio/x-aac					aac
    audio/x-aiff					aif aiff aifc
    audio/x-caf					caf
    audio/x-flac					flac
    audio/x-matroska				mka
    audio/x-mpegurl					m3u
    audio/x-ms-wax					wax
    audio/x-ms-wma					wma
    audio/x-pn-realaudio				ram ra
    audio/x-pn-realaudio-plugin			rmp
    # audio/x-tta
    audio/x-wav					wav
    audio/xm					xm
    chemical/x-cdx					cdx
    chemical/x-cif					cif
    chemical/x-cmdf					cmdf
    chemical/x-cml					cml
    chemical/x-csml					csml
    # chemical/x-pdb
    chemical/x-xyz					xyz
    font/collection					ttc
    font/otf					otf
    # font/sfnt
    font/ttf					ttf
    font/woff					woff
    font/woff2					woff2
    image/avif					avif
    image/bmp					bmp
    image/cgm					cgm
    # image/dicom-rle
    # image/emf
    # image/example
    # image/fits
    image/g3fax					g3
    image/gif					gif
    image/ief					ief
    # image/jls
    # image/jp2
    image/jpeg					jpeg jpg jpe
    # image/jpm
    # image/jpx
    image/jxl					jxl
    image/ktx					ktx
    # image/naplps
    image/png					png
    image/prs.btif					btif
    # image/prs.pti
    # image/pwg-raster
    image/sgi					sgi
    image/svg+xml					svg svgz
    # image/t38
    image/tiff					tiff tif
    # image/tiff-fx
    image/vnd.adobe.photoshop			psd
    # image/vnd.airzip.accelerator.azv
    # image/vnd.cns.inf2
    image/vnd.dece.graphic				uvi uvvi uvg uvvg
    image/vnd.djvu					djvu djv
    image/vnd.dvb.subtitle				sub
    image/vnd.dwg					dwg
    image/vnd.dxf					dxf
    image/vnd.fastbidsheet				fbs
    image/vnd.fpx					fpx
    image/vnd.fst					fst
    image/vnd.fujixerox.edmics-mmr			mmr
    image/vnd.fujixerox.edmics-rlc			rlc
    # image/vnd.globalgraphics.pgb
    # image/vnd.microsoft.icon
    # image/vnd.mix
    # image/vnd.mozilla.apng
    image/vnd.ms-modi				mdi
    image/vnd.ms-photo				wdp
    image/vnd.net-fpx				npx
    # image/vnd.radiance
    # image/vnd.sealed.png
    # image/vnd.sealedmedia.softseal.gif
    # image/vnd.sealedmedia.softseal.jpg
    # image/vnd.svf
    # image/vnd.tencent.tap
    # image/vnd.valve.source.texture
    image/vnd.wap.wbmp				wbmp
    image/vnd.xiff					xif
    # image/vnd.zbrush.pcx
    image/webp					webp
    # image/wmf
    image/x-3ds					3ds
    image/x-cmu-raster				ras
    image/x-cmx					cmx
    image/x-freehand				fh fhc fh4 fh5 fh7
    image/x-icon					ico
    image/x-mrsid-image				sid
    image/x-pcx					pcx
    image/x-pict					pic pct
    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-tga					tga
    image/x-xbitmap					xbm
    image/x-xpixmap					xpm
    image/x-xwindowdump				xwd
    # message/cpim
    # message/delivery-status
    # message/disposition-notification
    # message/example
    # message/external-body
    # message/feedback-report
    # message/global
    # message/global-delivery-status
    # message/global-disposition-notification
    # message/global-headers
    # message/http
    # message/imdn+xml
    # message/news
    # message/partial
    message/rfc822					eml mime
    # message/s-http
    # message/sip
    # message/sipfrag
    # message/tracking-status
    # message/vnd.si.simp
    # message/vnd.wfa.wsc
    # model/example
    # model/gltf+json
    model/iges					igs iges
    model/mesh					msh mesh silo
    model/vnd.collada+xml				dae
    model/vnd.dwf					dwf
    # model/vnd.flatland.3dml
    model/vnd.gdl					gdl
    # model/vnd.gs-gdl
    # model/vnd.gs.gdl
    model/vnd.gtw					gtw
    # model/vnd.moml+xml
    # model/vnd.mts
    # model/vnd.opengex
    # model/vnd.parasolid.transmit.binary
    # model/vnd.parasolid.transmit.text
    # model/vnd.rosette.annotated-data-model
    # model/vnd.valve.source.compiled-map
    model/vnd.vtu					vtu
    model/vrml					wrl vrml
    model/x3d+binary				x3db x3dbz
    # model/x3d+fastinfoset
    model/x3d+vrml					x3dv x3dvz
    model/x3d+xml					x3d x3dz
    # model/x3d-vrml
    # multipart/alternative
    # multipart/appledouble
    # multipart/byteranges
    # multipart/digest
    # multipart/encrypted
    # multipart/example
    # multipart/form-data
    # multipart/header-set
    # multipart/mixed
    # multipart/parallel
    # multipart/related
    # multipart/report
    # multipart/signed
    # multipart/voice-message
    # multipart/x-mixed-replace
    # text/1d-interleaved-parityfec
    text/cache-manifest				appcache
    text/calendar					ics ifb
    text/css					css
    text/csv					csv
    # text/csv-schema
    # text/directory
    # text/dns
    # text/ecmascript
    # text/encaprtp
    # text/enriched
    # text/example
    # text/fwdred
    # text/grammar-ref-list
    text/html					html htm
    text/javascript					js mjs
    # text/jcr-cnd
    # text/markdown
    # text/mizar
    text/n3						n3
    # text/parameters
    # text/parityfec
    text/plain					txt text conf def list log in
    # text/provenance-notation
    # text/prs.fallenstein.rst
    text/prs.lines.tag				dsc
    # text/prs.prop.logic
    # text/raptorfec
    # text/red
    # text/rfc822-headers
    text/richtext					rtx
    # text/rtf
    # text/rtp-enc-aescm128
    # text/rtploopback
    # text/rtx
    text/sgml					sgml sgm
    # text/t140
    text/tab-separated-values			tsv
    text/troff					t tr roff man me ms
    text/turtle					ttl
    # text/ulpfec
    text/uri-list					uri uris urls
    text/vcard					vcard
    # text/vnd.a
    # text/vnd.abc
    text/vnd.curl					curl
    text/vnd.curl.dcurl				dcurl
    text/vnd.curl.mcurl				mcurl
    text/vnd.curl.scurl				scurl
    # text/vnd.debian.copyright
    # text/vnd.dmclientscript
    text/vnd.dvb.subtitle				sub
    # text/vnd.esmertec.theme-descriptor
    text/vnd.fly					fly
    text/vnd.fmi.flexstor				flx
    text/vnd.graphviz				gv
    text/vnd.in3d.3dml				3dml
    text/vnd.in3d.spot				spot
    # text/vnd.iptc.newsml
    # text/vnd.iptc.nitf
    # text/vnd.latex-z
    # text/vnd.motorola.reflex
    # text/vnd.ms-mediapackage
    # text/vnd.net2phone.commcenter.command
    # text/vnd.radisys.msml-basic-layout
    # text/vnd.si.uricatalogue
    text/vnd.sun.j2me.app-descriptor		jad
    # text/vnd.trolltech.linguist
    # text/vnd.wap.si
    # text/vnd.wap.sl
    text/vnd.wap.wml				wml
    text/vnd.wap.wmlscript				wmls
    text/x-asm					s asm
    text/x-c					c cc cxx cpp h hh dic
    text/x-fortran					f for f77 f90
    text/x-java-source				java
    text/x-nfo					nfo
    text/x-opml					opml
    text/x-pascal					p pas
    text/x-setext					etx
    text/x-sfv					sfv
    text/x-uuencode					uu
    text/x-vcalendar				vcs
    text/x-vcard					vcf
    # text/xml
    # text/xml-external-parsed-entity
    # video/1d-interleaved-parityfec
    video/3gpp					3gp
    # video/3gpp-tt
    video/3gpp2					3g2
    # video/bmpeg
    # video/bt656
    # video/celb
    # video/dv
    # video/encaprtp
    # video/example
    video/h261					h261
    video/h263					h263
    # video/h263-1998
    # video/h263-2000
    video/h264					h264
    # video/h264-rcdo
    # video/h264-svc
    # video/h265
    # video/iso.segment
    video/jpeg					jpgv
    # video/jpeg2000
    video/jpm					jpm jpgm
    video/mj2					mj2 mjp2
    # video/mp1s
    # video/mp2p
    video/mp2t					ts m2t m2ts mts
    video/mp4					mp4 mp4v mpg4
    # video/mp4v-es
    video/mpeg					mpeg mpg mpe m1v m2v
    # video/mpeg4-generic
    # video/mpv
    # video/nv
    video/ogg					ogv
    # video/parityfec
    # video/pointer
    video/quicktime					qt mov
    # video/raptorfec
    # video/raw
    # video/rtp-enc-aescm128
    # video/rtploopback
    # video/rtx
    # video/smpte292m
    # video/ulpfec
    # video/vc1
    # video/vnd.cctv
    video/vnd.dece.hd				uvh uvvh
    video/vnd.dece.mobile				uvm uvvm
    # video/vnd.dece.mp4
    video/vnd.dece.pd				uvp uvvp
    video/vnd.dece.sd				uvs uvvs
    video/vnd.dece.video				uvv uvvv
    # video/vnd.directv.mpeg
    # video/vnd.directv.mpeg-tts
    # video/vnd.dlna.mpeg-tts
    video/vnd.dvb.file				dvb
    video/vnd.fvt					fvt
    # video/vnd.hns.video
    # video/vnd.iptvforum.1dparityfec-1010
    # video/vnd.iptvforum.1dparityfec-2005
    # video/vnd.iptvforum.2dparityfec-1010
    # video/vnd.iptvforum.2dparityfec-2005
    # video/vnd.iptvforum.ttsavc
    # video/vnd.iptvforum.ttsmpeg2
    # video/vnd.motorola.video
    # video/vnd.motorola.videop
    video/vnd.mpegurl				mxu m4u
    video/vnd.ms-playready.media.pyv		pyv
    # video/vnd.nokia.interleaved-multimedia
    # video/vnd.nokia.videovoip
    # video/vnd.objectvideo
    # video/vnd.radgamettools.bink
    # video/vnd.radgamettools.smacker
    # video/vnd.sealed.mpeg1
    # video/vnd.sealed.mpeg4
    # video/vnd.sealed.swf
    # video/vnd.sealedmedia.softseal.mov
    video/vnd.uvvu.mp4				uvu uvvu
    video/vnd.vivo					viv
    # video/vp8
    video/webm					webm
    video/x-f4v					f4v
    video/x-fli					fli
    video/x-flv					flv
    video/x-m4v					m4v
    video/x-matroska				mkv mk3d mks
    video/x-mng					mng
    video/x-ms-asf					asf asx
    video/x-ms-vob					vob
    video/x-ms-wm					wm
    video/x-ms-wmv					wmv
    video/x-ms-wmx					wmx
    video/x-ms-wvx					wvx
    video/x-msvideo					avi
    video/x-sgi-movie				movie
    video/x-smv					smv
    x-conference/x-cooltalk				ice
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�014336� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/���������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�014763� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/htpasswd.1�����������������������������������������������������������������0000664�0001751�0001751�00000021203�12352211121�016655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2014-06-24" "Apache HTTP Sunucusu" "htpasswd"
    .nh
    .SH İSİM
    htpasswd \- Temel kimlik doğrulama dosyalarını yönetir
    
    .SH "KULLANIM"
     
    .PP
    \fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIparola-dosyası\fR \fIkullanıcı\fR
     
    .PP
    \fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIparola-dosyası\fR \fIkullanıcı\fR \fIparola\fR
     
    .PP
    \fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] \fIkullanıcı\fR
     
    .PP
    \fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] \fIkullanıcı\fR \fIparola\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBhtpasswd\fR, HTTP kullanıcılarının temel kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının saklanmasında kullanılacak düz metin dosyalarını oluşturmak ve güncellemek için kullanılır\&. \fBhtpasswd\fR, güncelleme sırasında yazmak veya okumak için bir dosyaya erişemezse beklenen hiçbir işlemi yapmaz ve hata vererek çıkar\&.
     
    .PP
    Apache HTTP sunucusunun mevcut özkaynaklarının kullanımı sadece \fBhtpasswd\fR tarafından oluşturulan dosyalarda listelenmiş kullanıcılara tahsis edilebilir\&. \fBhtpasswd\fR sadece düz metin dosyalarda saklanmış kullanıcı isimlerini ve parolalarını yönetirse de, diğer veri saklama türleri için parolayı şifreleyip gösterebilir\&. Bir DBM veritabanı kullanmak isterseniz \fBdbmmanage\fR ve \fBhtdbm\fR sayfasına bakınız\&.
     
    .PP
    \fBhtpasswd\fR, parolaları şifrelemek için bcrypt, Apache'nin kendine özgü MD5 algoritması, SHA1 ya da sistemin crypt() yordamını kullanır\&. Bu bakımdan \fBhtpasswd\fR tarafından yönetilen dosyalar farklı algoritmalarla şifrelenmiş parolalar içerebilir\&.
     
    .PP
    Bu kılavuz sayfası sadece komut satırı değiştirgelerini listeler\&. Kullanıcı kimlik doğrulamasını \fBhttpd\fR'de yapılandırmak için gerekli yönergelerle ilgili ayrıntılar için Apache dağıtımının bir parçası olan ve http://httpd\&.apache\&.org/ adresinde de bulunan Apache HTTP Sunucusu Belgelerine bakınız\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-b\fR
    Betik kipi; parola için istek yapmak yerine parola komut satırından verilir\&. \fBParola komut satırında görünür\fR olacağından çok dikkatli kullanmak gerekir\&. Betik kullanımı için \fB-i\fR seçeneğine bakınız\&. 2\&.4\&.4 ve sonraki sürümler içindir\&.  
    .TP
    \fB-i\fR
    Parolayı doğrulamaksızın standart girdiden okur (betik kullanımı için)\&.  
    .TP
    \fB-c\fR
    \fIparola-dosyası\fR oluşturur\&. Dosya mevcutsa, dosya silinip yeniden yazılır\&. Bu seçenek \fB-n\fR seçeneği ile birlikte kullanılamaz\&.  
    .TP
    \fB-n\fR
    Sonuçları veritabanında güncellemek yerine standart çıktıya gönderir\&. Bu seçenek, Apache'nin metin veriler içermeyen veri depolarına dahil edilebilecek parolaları üretmekte yararlıdır\&. \fIparola-dosyası\fR belirtilmediğinden, bu seçenek komut satırı sözdizimini değiştirir\&. Bu seçenek \fB-c\fR seçeneği ile birlikte kullanılamaz\&.  
    .TP
    \fB-m\fR
    Parolalar için MD5 şifrelemesi kullanılır\&. Bu 2\&.2\&.18 sürümünden beri öntanımlıdır\&.  
    .TP
    \fB-B\fR
    Parolalar için bcrypt şifrelemesi kullanılır\&. Şu an için çok güvenli kabul edilmektedir\&.  
    .TP
    \fB-C\fR \fIbedel\fR
    Bu seçenek sadece \fB-B\fR (bcrypt şifrelemesi) seçeneği ile birlikte kullanılabilir\&. Bcrypt algoritmasına hesaplama süresini belirtir (daha yüksek değerler daha güvenlidir, öntanımlı 5, geçerli değerler: 4 - 31)\&.  
    .TP
    \fB-d\fR
    Parolaları şifrelemek için crypt() kullanılır\&. \fBhtpasswd\fR tarafından tüm platformlarda destekleniyor olsa da Windows, Netware ve TPF üzerinde httpd sunucusu tarafından desteklenmez\&. Bu algoritma günümüz standartlarında \fBgüvenilmez\fR kabul edilmektedir\&. 2\&.2\&.17 sürümüne kadar öntanımlı algoritma olarak kullanılmıştı\&.  
    .TP
    \fB-s\fR
    Parolalar için SHA şifrelemesi kullanılır\&. LDAP Dizin değişim biçemini (ldif) kullanarak Netscape sunucularına/sunucularından göçü kolaylaştırır\&.Bu algoritma günümüz standartlarında \fBgüvenilmez\fR kabul edilmektedir\&.  
    .TP
    \fB-p\fR
    Düz metin parolalar kullanılır\&. \fBhtpasswd\fR tarafından tüm platformlarda destekleniyor olsa da Windows, Netware ve TPF üzerinde httpd sunucusu tarafından sadece düz metin parolalar kabul edilir\&.  
    .TP
    \fB-D\fR
    Kullanıcıyı siler\&. Kullanıcı belirtilen dosyada mevcutsa silinir\&.  
    .TP
    -v
    Parolayı doğrular\&. Verilen parolayı belitilen htpasswd dosyasında saklanan kullanıcı parolası ile karşılaştırarak doğrulama yapar\&. 2\&.4\&.5 ve sonraki sürümler içindir\&.  
    .TP
    \fIparola-dosyası\fR
    Kullanıcı ismini ve parolasını içeren dosyanın ismi\&. \fB-c\fR seçeneği verilmişse ve dosya mevcut değilse oluşturulur, dosya mevcutsa silinip yeniden oluşturulur\&.  
    .TP
    \fIkullanıcı\fR
    \fIparola-dosyası\fR'nda oluşturulacak veya güncellenecek kullanıcı ismi\&. \fIkullanıcı\fR bu dosyada mevcut değilse yeni bir girdi eklenir\&. Girdi mevcutsa parolası değiştirilir\&.  
    .TP
    \fIparola\fR
    Şifrelenip dosyada saklanacak düz metin parola\&. Sadece \fB-b\fR seçeneği ile kullanılır\&.  
     
    .SH "ÇIKIŞ DURUMU"
     
    .PP
    \fBhtpasswd\fR, kullanıcı ismi ve parolasını DBM dosyasına başarıyla eklemiş veya güncellemişse 0, dosyalara erişirken bir sorun çıkmışsa 1, komut satırında bir sözdizimi hatası varsa 2, parola etkileşimli alınmış fakat girdi ile eşleşme sağlanamamışsa 3, işlem kesintiye uğramışsa 4, bir değer çok uzunsa 5 (kullanıcı, parola, dosya ismi veya açıklama), kullanıcı ismi kuraldışı karakter içeriyorsa (Kısıtlamalar bölümüne bakınız) 6 ve dosya geçerli bir DBM parola dosyası değilse 7 değeriyle döner\&.
     
    .SH "ÖRNEKLER"
     
    .nf
    
          htpasswd /usr/local/etc/apache/\&.htpasswd-users jsmith
        
    .fi
     
    .PP
    jsmith kullanıcısı için parolayı ekler veya değiştirir\&. Parolayı vermesi için kullanıcıya parola isteği yapılır\&. Parola takviyeli Apache MD5 algoritması ile şifrelenir\&. Dosya mevcut değilse \fBhtpasswd\fR beklenen hiçbir işlemi yapmadan bir hata vererek çıkar\&.
     
    .nf
    
          htpasswd -c /home/doe/public_html/\&.htpasswd jane
        
    .fi
     
    .PP
    Yeni bir dosya oluşturur ve kullanıcı jane için kaydı bir girdi olarak bu dosyaya yazar\&. Dosya mevcutsa fakat okunamıyor veya yazılamıyorsa dosyada bir değişiklik yapılmaz ve \fBhtpasswd\fR bir ileti gösterip bir hata durumu ile çıkar\&.
     
    .nf
    
          htpasswd -db /usr/web/\&.htpasswd-all jones Pwd4Steve
        
    .fi
     
    .PP
    Komut satırından verilen parolayı (Pwd4Steve) crypt() algoritmasıyla şifreler ve bunu belirtilen dosyada saklar\&.
     
    .SH "GÜVENLİK DEĞERLENDİRMELERİ"
     
    .PP
    \fBhtpasswd\fR tarafından yönetilen parola dosyalarına sunucunun URI uzayından erişilememelidir; yani dosya bir tarayıcı ile okunabilecek bir yerde bulunmamalıdır\&.
     
    .PP
    Bu program bir setuid çalıştırılabiliri olarak güvenilir olmadığından \fIsetuid yapılmamalıdır\fR\&.
     
    .PP
    Komut satırında parolanın şifrelenmemiş olarak görünmesi sebebiyle \fB-b\fR seçeneğinin kullanımından kaçınılmasını öneriyoruz\&.
     
    .PP
    crypt() algoritması kullanılırken, parolayı şekillendirmek için parolanın ilk 8 baytının kullanılacağına dikkat ediniz\&. Eğer parola 8 bayttan uzunsa kalanlar bir uyarı verilmeksizin iptal edilir\&.
     
    .PP
    SHA şifreleme biçeminde tuz kullanılmaz; yani, bir parolanın sadece bir şifreli gösterimi olabilir\&. crypt() ve MD5 biçemleri parolanın önüne rasgele üretilmiş bir tuz dizgesi eklediklerinden sözlük saldırılarına karşı daha dayanıklıdırlar\&.
     
    .PP
    SHA ve crypt() biçimleri günümüz standartlarında \fBgüvenilmez\fR kabul edilmektedir\&.
     
    .SH "KISITLAMALAR"
     
    .PP
    Windows platformuda, \fBhtpasswd\fR ile şifrelenen parolalar 255 karakterden daha uzun olamaz\&. 255 karakterden sonrası kırpılır\&.
     
    .PP
    \fBhtpasswd\fR tarafından kullanılan MD5 algoritması Apache yazılımına özeldir; bu algoritma ile şifrelenen parolalar başka HTTP sunucularında kullanılamayabilir\&.
     
    .PP
    Kullanıcı isimleri 255 bayttan uzun olamaz ve iki nokta imi (:) içeremez\&.
     
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/suexec.8�������������������������������������������������������������������0000664�0001751�0001751�00000002601�12203356434�016340� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2013-08-16" "Apache HTTP Sunucusu" "suexec"
    .nh
    .SH İSİM
    suexec \- harici programları çalıştırmadan önce kullanıcıyı değiştirir
    
    .SH "KULLANIM"
     
    .PP
    \fBsuexec\fR -\fBV\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBsuexec\fR, CGI programlarını çalıştırmadan önce Apache HTTP Sunucusu tarafından kullanıcı değiştirmek için kullanılır\&. Bunu yapabilmek için sunucunun root tarafından çalıştırılmış olması gerekir\&. HTTP artalan süreci normalde root aidiyetinde çalışmadığından \fBsuexec\fR'in çalıştırılabilir dosyasının sahibi root olmalı, setuid biti etkin (u+s) olmalı ve dosyaya root dışında hiç kimse yazamamalıdır\&.
     
    .PP
    \fBsuexec\fR güvenlik modeli ve kavramlar hakkında bilgi edinmek için suexec belgesine (http://httpd\&.apache\&.org/docs/2\&.4/suexec\&.html) bakınız\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-V\fR
    root iseniz, bu seçenek \fBsuexec\fR derleme seçeneklerini gösterir\&. Güvenlik sebebiyle tüm yapılandırma seçenekleri sadece derleme sırasında değiştirilebilir\&.  
     
    �������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/ab.1�����������������������������������������������������������������������0000664�0001751�0001751�00000025025�12352211121�015410� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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" 1 "2014-06-24" "Apache HTTP Sunucusu" "ab"
    .nh
    .SH İSİM
    ab \- Apache HTTP sunucusu başarım ölçme aracı
    
    .SH "KULLANIM"
     
    .PP
    \fBab\fR [ -\fBA\fR \fIyetkili-kullanıcı:parola\fR ] [ -\fBb\fR \fItampon-boyu\fR ] [ -\fBB\fR \fIyerel-adres\fR ] [ -\fBc\fR \fIbağlantı-sayısı\fR ] [ -\fBC\fR \fIçerez-ismi=değer\fR ] [ -\fBd\fR ] [ -\fBe\fR \fIcsv-dosyası\fR ] [ -\fBf\fR \fIprotokol\fR ] [ -\fBg\fR \fIgnuplot-dosyası\fR ] [ -\fBh\fR ] [ -\fBH\fR \fIözel-başlık\fR ] [ -\fBi\fR ] [ -\fBk\fR ] [ -\fBl\fR ] [ -\fBm\fR \fIHTTP-yöntemi\fR ] [ -\fBn\fR \fIistek-sayısı\fR ] [ -\fBp\fR \fIPOST-dosyası\fR ] [ -\fBP\fR \fIvekil-yetkilisi:parola\fR ] [ -\fBq\fR ] [ -\fBr\fR ] [ -\fBs\fR \fIzamanasimi\fR ] [ -\fBS\fR ] [ -\fBt\fR \fIsaniye\fR ] [ -\fBT\fR \fIiçerik-türü\fR ] [ -\fBu\fR \fIPUT-dosyası\fR ] [ -\fBv\fR \fIayrıntı-düzeyi\fR] [ -\fBV\fR ] [ -\fBw\fR ] [ -\fBx\fR \fI<table>-öznitelikleri\fR ] [ -\fBX\fR \fIvekil\fR[:\fIport\fR] ] [ -\fBy\fR \fI<tr>-öznitelikleri\fR ] [ -\fBz\fR \fI<td>-öznitelikleri\fR ] [ -\fBZ\fR \fIşifre-kümesi\fR ] [http[s]://]\fIkonakadı\fR[:\fIport\fR]/\fIdizin\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBab\fR Apache Hiper Metin Aktarım Protokolü (HTTP) sunucunuzun başarımını ölçmek amacıyla kullanabileceğiniz bir kıyaslama aracıdır\&. Mevcut Apache kurulumunuzun görevini nasıl yerine getirdiği hakkında bir izlenim edinmeniz için tasarlanmıştır\&. Özellikle, Apache kurulumunuzun saniyede kaç isteği sunma yeteneğinde olduğunu gösterir\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-A\fR \fIyetkili-kullanıcı\fR:\fIparola\fR
    Sunucuya TEMEL Kimlik Doğrulamada kullanılmak üzere kanıt sağlar\&. Kullanıcı adı ile parola arasına sadece : konur ve sunucunun buna ihtiyacı olup olmadığına bakılmaksızın (yani, bir "401 kimlik doğrulaması gerekli" yanıtı beklenmeden) bağlantı üzerinden base64 kodlu olarak sunucuya gönderilir\&.  
    .TP
    \fB-b\fR \fItampon-boyu\fR
    TCP gönderme/alma tamponlarının bayt cinsinden uzunluğu\&.  
    .TP
    \fB-B\fR \fIyerel-adres\fR
    Uzak bağlantılar yaparken dinlenecek adres\&.  
    .TP
    \fB-c\fR \fIbağlantı-sayısı\fR
    Aynı anda işleme sokulacak bağlantı sayısı\&. Aynı anda bir bağlantı öntanımlı değerdir\&.  
    .TP
    \fB-C\fR \fIçerez-ismi\fR=\fIdeğer\fR
    İsteğe bir Cookie: satırı ekler\&. Argüman olarak genellikle bir \fIisim=değer\fR çifti kullanılır\&. Bu çiftler birden fazla olabilir\&.  
    .TP
    \fB-d\fR
    "percentage served within XX [ms] table" iletisi gösterilmez\&. (Geriye uyumluluk için vardır)\&.  
    .TP
    \fB-e\fR \fIcsv-dosyası\fR
    Sunulan isteğin birim zamanda (milisaniye) ne kadarının (yüzde cinsinden) sunulduğunu gösteren virgül ayraçlı değerler (CSV) dosyası\&. Sonuçlar 'bobin haline' getirilmiş olduğundan doğal olarak 'gnuplot' dosyasından daha yararlıdır\&.  
    .TP
    \fB-f\fR \fIprotokol\fR
    SSL/TLS protokolü belirtilir (SSL2, SSL3, TLS1, TLS1\&.1, TLS1\&.2 veya ALL)\&. TLS1\&.1 ve TLS1\&.2 desteği 2\&.4\&.4 ve sonraki sürümler içindir\&.  
    .TP
    \fB-g\fR \fIgnuplot-dosyası\fR
    Ölçülen değerler bir 'gnuplot' veya TSV (sekme ayraçlı değerler) dosyasına yazılır\&. Bu dosya, Gnuplot, IDL, Mathematica, Igor hatta Excel tarafından veri dosyası olarak kabul edilir\&. Veri sütunlarının başlıkları dosyanın ilk satırında bulunur\&.  
    .TP
    \fB-h\fR
    Kullanım bilgisi gösterir\&.  
    .TP
    \fB-H\fR \fIözel-başlık\fR
    İsteğe fazladan başlık ekler\&. \fIözel-başlık\fR, aralarında iki nokta imi bulunan bir isim-değer çifti olarak belirtilir\&. Örnek: "Accept-Encoding: zip/zop;8bit"  
    .TP
    \fB-i\fR
    GET istekleri yerine HEAD istekleri yapılır\&.  
    .TP
    \fB-k\fR
    HTTP KeepAlive (kalıcı bağlantı) özelliğini etkinleştirir, yani tek bir oturum içinde çok sayıda isteğe hizmet sunulabilir\&. Özellik öntanımlı olarak kapalıdır\&.  
    .TP
    \fB-l\fR
    Yanıtarın uzunluğu sabit değilse hataları raporlamaz\&. Özdevinimli sayfalarda kullanışlı olabilir\&. 2\&.4\&.7 ve sonraki sürümler içindir\&.  
    .TP
    \fB-m\fR \fIHTTP-yöntemi\fR
    İstekler için özel HTTP yöntemi, belirtilir\&. 2\&.4\&.10 ve sonraki sürümler içindir\&.  
    .TP
    \fB-n\fR \fIistek-sayısı\fR
    Kıyaslama oturumu sırasında sunucuya uygulanacak istek sayısı\&. Öntanımlı olarak hiçbir başarım ölçütü sağlamayan tek bir istek yapılır\&.  
    .TP
    \fB-p\fR \fIPOST-dosyası\fR
    POST isteği ile ilgili verileri içeren dosya\&. Ayrıca \fB-T\fR seçeneğini de belirtmeyi unutmayın\&.\&.  
    .TP
    \fB-P\fR \fIvekil-yetkilisi\fR:\fIparola\fR
    Vekil sunucuya TEMEL Kimlik Doğrulamasında kullanılacak kanıtları sağlar\&. Kullanıcı adı ile parola arasına sadece : konur ve vekilin buna ihtiyacı olup olmadığına bakılmaksızın (yani, bir "407 vekilde kimlik doğrulaması gerekiyor" yanıtı beklenmeden) bağlantı üzerinden base64 kodlu olarak sunucuya gönderilir\&.  
    .TP
    \fB-q\fR
    İstek sayısı 150'den fazla olduğunda, \fBab\fR her 100 veya %10 istekte bir, standart hataya bir işlenen istek sayacı çıktılar\&. \fB-q\fR seçeneği bu çıktının üretilmemesini sağlar\&.  
    .TP
    \fB-r\fR
    Soket hata alsa bile program çıkmaz\&.  
    .TP
    \fB-s\fR \fIzamanasimi\fR
    Soket zaman aşımına uğramadan önce beklenecek azami saniye sayısı\&. 30 saniye öntanımlı süredir\&. 2\&.4\&.4 ve sonraki sürümler içindir\&.  
    .TP
    \fB-S\fR
    Ortalama ve ortanca değerler arasında bir veya iki standart sapmadan fazlası varsa ne ortalama değer ne standart sapma değeri ne de uyarı/hata iletileri gösterilir\&. Öntanımlı olarak, asgari/ortalama/azami değerler gösterilir\&. (Geriye uyumluluk)\&.  
    .TP
    \fB-t\fR \fIsaniye\fR
    Ölçümleme işleminin ne kadar süreyle uygulanacağı belirtilir\&. Dahili olarak \fB-n 50000\fR seçeneği uygulanır\&. Bunu belli bir süreye göre kıyaslama yapmak amacıyla kullanabilirsiniz\&. Öntanımlı olarak bir süre kısıtlaması yoktur\&.  
    .TP
    \fB-T\fR \fIiçerik-türü\fR
    POST/PUT verisi için kullanılacak içerik türü belirtilir\&. Örnek: application/x-www-form-urlencoded\&. Öntanımlı değer: text/plain\&.  
    .TP
    \fB-v\fR \fIayrıntı-düzeyi\fR
    Çıktının ayrıntı düzeyi belirtilir\&. 4 ve üstü ile başlıklar hakkında bilgi, 3 ve üstü ile yanıt kodları (404, 200, vb\&.), 2 ve üstü ile ise uyarı ve bilgi iletileri gösterilir\&.  
    .TP
    -u \fIPUT-dosyası\fR
    PUT verisini içeren dosya\&. Ayrıca, -T seçeneğini belirtmeyi de unutmayın\&.  
    .TP
    \fB-V\fR
    Sürüm bilgilerini gösterir ve çıkar\&.  
    .TP
    \fB-w\fR
    Sonuçları HTML tabloları olarak basar\&. Öntanımlı tablo, beyaz artalanlı ve iki sütunludur\&.  
    .TP
    \fB-x\fR \fI<table>-öznitelikleri\fR
    <table> etiketinde kullanılacak öznitelikler belirtilir\&. Belirtilen öznitelikler etiket içine <table \fIburaya\fR > biçeminde yerleştirilir\&.  
    .TP
    \fB-X\fR \fIvekil\fR[:\fIport\fR]
    İstekler için bir vekil sunucu kullanılır\&.  
    .TP
    \fB-y\fR \fI<tr>-öznitelikleri\fR
    <tr> etiketinde kullanılacak öznitelikler belirtilir\&.  
    .TP
    \fB-z\fR \fI<td>-öznitelikleri\fR
    <td> etiketinde kullanılacak öznitelikler belirtilir\&.  
    .TP
    -Z \fIşifre-kümesi\fR
    SSL/TLS şifre kümesi belirtilir (\fBopenssl\fR(1) şifrelerine bakınız)\&.  
     
    .SH "ÇIKTI"
     
    .PP
    Aşağıda \fBab\fR tarafından döndürülen değerler açıklanmıştır:
     
     
    .TP
    Server Software
    İlk başarılı yanıtın, varsa, \fIserver\fR HTTP başlığında döndürülen değer\&. Bu başlıktaki başlangıçtan 32 ondalık değerli karaktere (genellikle boşluk veya CR/LF karakteri) kadar tüm karakterleri içerir\&.  
    .TP
    Server Hostname
    Komut satırında belirtilen DNS veya IP adresi\&.  
    .TP
    Server Port
    \fBab\fR'nin bağlandığı port\&. Komut satırında port belirtilmemişse, öntanımlı olarak http için 80, https için 443'tür\&.  
    .TP
    SSL/TLS Protocol
    İstemci le sunucu arasında uzlaşılmış protokol değerleri\&. Bu sadece SSL kullanılıyorsa çıktılanır\&.  
    .TP
    Document Path
    Komut satırı dizgesinden çözümlenen isteğin URI'si\&.  
    .TP
    Document Length
    Başarıyla döndürülen ilk belgenin bayt cinsinden uzunluğu\&. Eğer belge uzunluğu sınama sırasında değişirse yanıt bir hata içerecektir\&.  
    .TP
    Concurrency Level
    Sınama sırasında kullanılan eşzamanlı istemcilerin sayısı\&.  
    .TP
    Time taken for tests
    İlk soket bağlantısının alındığı andan son yanıtın alındığı ana kadar geçen süre\&.  
    .TP
    Complete requests
    Alınan başarılı yanıtların sayısı\&.  
    .TP
    Failed requests
    Başarısızlık olarak addedilen isteklerin sayısı\&. Sayı sıfırdan büyükse, diğer satırda, bağlanma, okuma, yanlış içerik uzunluğu, istisnalar gibi sebeplerle başarısız olmuş istekler gösterilir\&.  
    .TP
    Write errors
    Başarısız yazma hatalarının (kırık boru) sayısı\&.  
    .TP
    Non-2xx responses
    200 serisi yanıt kodları ile açıklanamayan yanıtların sayısı\&. Tüm yanıtlar 200 olursa bu alan çıktılanmaz\&.  
    .TP
    Keep-Alive requests
    Keep-Alive isteklerinde sonuçlanan bağlantı sayısı\&.  
    .TP
    Total body sent
    Sınamanın parçası olarak veri gönderimi yapılandırılmışsa, bu sınama sırasında gönderilen toplam bayt sayısıdır\&. Sınama sırasında gövde gönderilmiyorsa bu alan çıktılanmaz\&.  
    .TP
    Total transferred
    Sunucudan alınan toplam bayt sayısı\&. Bu sayı aslında hattan gönderilen bayt sayısıdır\&.  
    .TP
    HTML transferred
    Sunucudan alınan belge baytlarının sayısı\&. Bu sayı HTTP başlıklarının bayt sayısını içermez\&.  
    .TP
    Requests per second
    Saniyedeki istek sayısı\&. İstek sayısının toplam süreye oranıdır\&.  
    .TP
    Time per request
    İstek başına harcanan süre\&. İlk değer eşzamanlılık * süre * 1000 / biten formülüyle hesaplanırken ikincisi için süre * 1000 / biten formülü kullanılır\&.  
    .TP
    Transfer rate
    okunantoplam / 1024 / süre formülüyle hesaplanan aktarım hızı\&.  
     
    .SH "BÖRTÜ BÖCEK"
     
    .PP
    Duruk bildirimli sabit uzunlukta çeşitli tamponlar vardır\&. Sunucudan gelen yanıt başlıkları ve diğer harici girdiler, komut satırı argümanları ile birlikte basitçe çözümlenir, bu size can sıkıcı gelebilir\&.
     
    .PP
    HTTP/1\&.x protokolünü tamamen gerçeklemez; sadece yanıtların 'belli başlı' bazı biçimlerini kabul eder\&. Aksi takdirde, \fBstrstr\fR(3) işlevinin yoğun kullanımı nedeniyle sunucu yerine \fBab\fR'nin başarımını ölçerdiniz\&.
     
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/apxs.1���������������������������������������������������������������������0000664�0001751�0001751�00000027400�12203356434�016014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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" 1 "2013-08-16" "Apache HTTP Sunucusu" "apxs"
    .nh
    .SH İSİM
    apxs \- Apache Eklenti Aracı
    
    .SH "KULLANIM"
     
    .PP
    \fBapxs\fR -\fBg\fR [ -\fBS\fR \fIisim=değer\fR ] -\fBn\fR \fImodüladı\fR
     
    .PP
    \fBapxs\fR -\fBq\fR [ -\fBv\fR ] [ -\fBS\fR \fIisim=değer\fR ] \fIsorgu\fR \&.\&.\&.
     
    .PP
    \fBapxs\fR -\fBc\fR [ -\fBS\fR \fIisim=değer\fR ] [ -\fBo\fR \fIdso-dosyası\fR ] [ -\fBI\fR \fIinclude-dizini\fR ] [ -\fBD\fR \fIisim=değer\fR ] [ -\fBL\fR \fIlib-dizini\fR ] [ -\fBl\fR \fIkütüphane-adı\fR ] [ -\fBWc,\fR\fIderleyici-seçenekleri\fR ] [ -\fBWl,\fR\fIilintileyici-seçenekleri\fR ] [ -\fBp\fR ] \fIdosya\fR \&.\&.\&.
     
    .PP
    \fBapxs\fR -\fBi\fR [ -\fBS\fR \fIisim=değer\fR ] [ -\fBn\fR \fImodüladı\fR ] [ -\fBa\fR ] [ -\fBA\fR ] \fIdso-dosyası\fR \&.\&.\&.
     
    .PP
    \fBapxs\fR -\fBe\fR [ -\fBS\fR \fIisim=değer\fR ] [ -\fBn\fR \fImodüladı\fR ] [ -\fBa\fR ] [ -\fBA\fR ] \fIdso-dosyası\fR \&.\&.\&.
     
    
    .SH "ÖZET"
     
    .PP
    \fBapxs\fR, Apache Hiper Metin Aktarım Protokolü (HTTP) sunucusu için ek modül derleme ve kurulum aracıdır\&. Bu araç sayesinde, bir veya daha fazla kaynak veya nesne \fIdosya\fRsından bir devingen paylaşımlı nesne (DSO - "Dynamic Shared Object" kısaltması) derlemek ve bu nesneyi (modülü) Apache sunucusuna çalışma anında \fBmod_so\fR modülünün \fBLoadModule\fR yönergesi üzerinden yüklemek mümkün olmaktadır\&.
     
    .PP
    Bu eklenti mekanizmasını platformunuzda kullanmak için DSO desteğinin olması ve \fBhttpd\fR programının \fBmod_so\fR modülünü içerecek şekilde derlenmiş olması gerekir\&. Eğer bunlar mevcut değilse \fBapxs\fR aracı durumu size bildirecektir\&. Bunu aşağıdaki komutla kendiniz de sınayabilirsiniz:
     
    .nf
    
          $ httpd -l
        
    .fi
     
    .PP
    \fBmod_so\fR modülü gösterilen listede yer almalıdır\&. Bu gereksinimler sağlandığı takdirde \fBapxs\fR aracı sayesinde DSO mekanizması üzerinden kendi modüllerinizi kurmak suretiyle Apache sunucunuzun işlevselliğini kolayca arttırabilirsiniz\&. Örnek bir uygulama:
     
    .nf
    
          $ apxs -i -a -c mod_foo\&.c
          gcc -fpic -DSHARED_MODULE -I/dosya/yolu/apache/include -c mod_foo\&.c
          ld -Bshareable -o mod_foo\&.so mod_foo\&.o
          cp mod_foo\&.so /dosya/yolu/apache/modules/mod_foo\&.so
          chmod 755 /dosya/yolu/apache/modules/mod_foo\&.so
          [`foo' modülü /dosya/yolu/apache/etc/httpd\&.conf'ta etkinleştiriliyor]
          $ apachectl restart
          /dosya/yolu/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
          /dosya/yolu/apache/sbin/apachectl restart: httpd started
          $ _
        
    .fi
     
    .PP
    \fIdosya\fR olarak bir C kaynak dosyası (\&.c), bir nesne dosyası (\&.o) ve hatta bir kütüphane arşivi archive (\&.a) belirtebilirsiniz\&. \fBapxs\fR aracı bu dosya uzantılarını tanıdığından C dosyalarını derleme işleminden, arşiv ve nesne dosyalarını ise doğrudan ilintileme işleminden geçirir\&. Fakat böyle önceden derlenmiş nesne dosyalarını kullanırken, devingen paylaşımlı nesne olarak kullanılmalarını sağlamak üzere konumdan bağımsız kod (PIC) üretecek şekilde derlenmiş olduklarından emin olmalısınız\&. Örneğin GCC'yi bunun için daima \fB-fpic\fR seçeneği ile kullanmalısınız\&. Diğer C derleyiciler için, \fBapxs\fR'in nesne dosyalarını derlerken kullanacağı seçenekleri öğrenmek için o derleyicilerin kılavuz sayfalarına bakınız\&.
     
    .PP
    Apache'deki DSO desteği ile ilgili daha ayrıntılı bilgi edinmek için \fBmod_so\fR belgesini okumakla yetinmeyip src/modules/standard/mod_so\&.c kaynak dosyasını da okuyunuz\&.
     
    
    .SH "SEÇENEKLER"
     
    .SS "Ortak Seçenekler"
     
     
    .TP
    \fB-n\fR \fImodüladı\fR
    \fB-i\fR (kurulum) ve \fB-g\fR (şablon üretimi) seçenekleri için modül ismi belirtmek amacıyla kullanılır\&. Bir modül ismi belirtmek için bu seçeneği kullanın\&. \fB-g\fR seçeneği için bu gereklidir\&. \fB-i\fR seçeneği için ise araç, modül ismini kaynağın ismine bakarak veya (son çare olarak) dosya isminden tahmin etmeye çalışarak saptamaya çalışır\&.  
      
    .SS "Sorgu Seçenekleri"
     
     
    .TP
    \fB-q\fR \fIsorgu\fR
    httpd'yi derlemekte kullanılacak değişkenler ve ortam ayarları için bir sorgu gerçekleştirir\&. When invoked without \fIsorgu\fR belirtilmeksizin çağrıldığında, bilinen değişkenleri değerleriyle birlikte basar\&. İsteğe bağlı \fB-v\fR seçeneği liste çıktısını biçemler\&. .PP Modülünüzü yükleyecek \fBhttpd\fR'yi derlemek için kullanılacak ayarları elle belirtmek için kullanılır\&. Örneğin, Apache'nin C başlık dosyalarının yerini kendi Makefile dosyalarınızın içinde şöyle belirtebilirsiniz: INC=-I`apxs -q INCLUDEDIR`  
      
    .SS "Yapılandırma Seçenekleri"
     
     
    .TP
    \fB-S\fR \fIisim=değer\fR
    Bu seçenek yukarıda açıklanan \fBapxs\fR ayarlarını değiştirir\&.  
      
    .SS "Şablon Üretme Seçenekleri"
     
     
    .TP
    \fB-g\fR
    \fImodüladı\fR (\fB-n\fR seçeneğine bakınız) adında bir alt dizin oluşturur ve içine iki dosya yerleştirir: Kendi modülünüzü oluşturabilmeniz için veya \fBapxs\fR mekanizmaları ile hemen oynamaya başlayabilmeniz için mod_\fImodüladı\fR\&.c adında bir modül kaynak dosyası örneği ve bu modülü derleyip kurmayı kolaylaştırmak için bir Makefile dosyası\&.  
      
    .SS "DSO Derleme Seçenekleri"
     
     
    .TP
    \fB-c\fR
    Bu seçenek derleme yapılacağını belirtir\&. Önce belirtilen C kaynak \fIdosyalar\fRını (\&.c), nesne dosyalarını (\&.o) elde etmek için derler\&. Sonra bunları kalan nesne dosyaları (\&.o ve \&.a) ile ilintileyerek \fIdso-dosyası\fR adında bir devingen paylaşımlı nesne oluşturur\&. Eğer \fB-o\fR seçeneği ile modül ismi belirtilmemişse \fIdosyalar\fR arasındaki ilk dosyanın ismine bakarak dosya ismi tahmin edilmeye çalışılır ve mod_\fIisim\fR\&.so dosya adı bu isimden elde edilir\&.  
    .TP
    \fB-o\fR \fIdso-dosyası\fR
    Oluşturulacak devingen paylaşımlı nesnenin ismini belirtmek için kullanılır\&. Modül ismi bu seçenekle belirtilmez ve \fIdosya\fR listesinden bir isim tahmini de yapılamazsa son çare olarak mod_unknown\&.so ismi kullanılır\&.  
    .TP
    \fB-D\fR \fIisim=değer\fR
    Bu seçenek doğrudan derleme komutlarına aktarılır\&. Bu seçeneği derleme işlemine kendi tanımlarınızı belirtmek için kullanın\&.  
    .TP
    \fB-I\fR \fIinclude-dizini\fR
    Bu seçenek doğrudan derleme komutlarına aktarılır\&. Bu seçeneği derleme işleminde kullanılmak üzere kendi başlık dosyalarınızı içeren dizinleri arama yollarına eklemek için kullanın\&.  
    .TP
    \fB-L\fR \fIlib-dizini\fR
    Bu seçenek doğrudan derleme komutlarına aktarılır\&. Bu seçeneği derleme işleminde kullanılmak üzere kendi kütüphane dizinlerinizi arama yollarına eklemek için kullanın\&.  
    .TP
    \fB-l\fR \fIkütüphane-adı\fR
    Bu seçenek doğrudan derleme komutlarına aktarılır\&. Bu seçeneği derleme işleminde kullanılmak üzere kendi kütüphanelerinizi arama yollarına eklemek için kullanın\&.  
    .TP
    \fB-Wc\fR,\fIderleyici-seçenekleri\fR
    Bu seçenek libtool --mode=compile komutuna doğrudan seçenek aktarmak için kullanılır\&. Bu seçeneği yerel derleyiciniz için gereken ek seçenekleri belirtmek için kullanın\&.  
    .TP
    \fB-Wl\fR,\fIilintileyici-seçenekleri\fR
    Bu seçenek libtool --mode=link komutuna doğrudan seçenek aktarmak için kullanılır\&. Bu seçeneği yerel ilintileyiciniz için gereken ek seçenekleri belirtmek için kullanın\&.  
    .TP
    \fB-p\fR
    Bu seçenek apxs'in apr/apr-util kütüphaneleriyle ilintilenmesini sağlar\&. apr/apr-util kütüphanelerini kullanan yardımcı uygulamaları derlerken yararlıdır\&.  
      
    .SS "DSO Kurulum ve Yapılandırma Seçenekleri"
      
     
    .TP
    \fB-i\fR
    Kurulum işlemini belirtir ve devingen olarak paylaşımlı nesneleri sunucunun \fImodules\fR dizinine kurar\&.  
    .TP
    \fB-a\fR
    İlgili LoadModule satırını Apache'nin httpd\&.conf yapılandırma dosyasına özdevinimli olarak ekleyerek veya böyle bir satır varsa bunu etkin kılarak modülü etkinleştirir\&.  
    .TP
    \fB-A\fR
    \fBLoadModule\fR yönergesini daha sonra etkinleştirmek üzere satırın başına bir diyez imi (#) yerleştirmesi dışında \fB-a\fR seçeneği ile aynıdır\&.  
    .TP
    \fB-e\fR
    Modülü kurmaya çalışmaksızın Apache'nin httpd\&.conf yapılandırma dosyasını \fB-i\fR işlemine benzer şekilde \fB-a\fR ve \fB-A\fR seçenekleri ile düzenleme işlemini belirtir\&.  
      
    .SH "ÖRNEKLER"
     
    .PP
    Apache'nin sunucu işlevselliğini genişletmek amacıyla kullanacağınız mod_foo\&.c adında bir Apache modülünüz olduğunu varsayalım\&. Öncelikle, C kaynak dosyasını, Apache sunucusuna çalışma anında yüklenmeye uygun bir paylaşımlı nesne olarak derlemeniz gerekir\&. Bunu sağlamak için şu komutları vermelisiniz:
     
    .nf
    
          $ apxs -c mod_foo\&.c
          /dosya/yolu/libtool --mode=compile gcc \&.\&.\&. -c mod_foo\&.c
          /dosya/yolu/libtool --mode=link gcc \&.\&.\&. -o mod_foo\&.la mod_foo\&.slo
          $ _
        
    .fi
     
    .PP
    Bundan sonra, Apache yapılandırmanızın bu paylaşımlı nesneyi yüklemek için bir \fBLoadModule\fR yönergesi içermesini sağlamalısınız\&. \fBapxs\fR bu adımı basitleştirmek amacıyla, paylaşımlı nesneyi sunucunun \fImodules\fR dizinine özdevinimli olarak kurmak ve httpd\&.conf dosyasını buna uygun olarak güncellemek için bir yol sağlar\&. Bu sonuç şöyle elde edilebilir:
     
    .nf
    
          $ apxs -i -a mod_foo\&.la
          /dosya/yolu/instdso\&.sh mod_foo\&.la /path/to/apache/modules
          /dosya/yolu/libtool --mode=install cp mod_foo\&.la /dosya/yolu/apache/modules
          \&.\&.\&.
          chmod 755 /dosya/yolu/apache/modules/mod_foo\&.so
          [`foo' modülü /dosya/yolu/apache/conf/httpd\&.conf'da etkinleştiriliyor] 
          $ _
        
    .fi
     
    .PP
    Yapılandıma dosyasına (eğer yoksa) şu satır eklenir:
     
    .nf
    
          LoadModule foo_module modules/mod_foo\&.so
        
    .fi
     
    .PP
    Bunu öntanımlı olarak iptal etmek isterseniz \fB-A\fR seçeneğini kullanmanız gerekir:
     
    .nf
    
          $ apxs -i -A mod_foo\&.c
        
    .fi
     
    .PP
    \fBapxs\fR mekanizmalarını hızlıca denemek için örnek bir Apache modül şablonunu ve bir Makefile dosyasını şöyle oluşturabilirsiniz:
     
    .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
    Ardından bu örnek modülü bir paylaşımlı nesne olarak derleyip Apache sunucusuna yükleyebilirsiniz:
     
    .nf
    
          $ cd foo
          $ make all reload
          apxs -c mod_foo\&.c
          /dosya/yolu/libtool --mode=compile gcc \&.\&.\&. -c mod_foo\&.c
          /dosya/yolu/libtool --mode=link gcc \&.\&.\&. -o mod_foo\&.la mod_foo\&.slo
          apxs -i -a -n "foo" mod_foo\&.la
          /dosya/yolu/instdso\&.sh mod_foo\&.la /dosya/yolu/apache/modules
          /dosya/yolu/libtool --mode=install cp mod_foo\&.la /dosya/yolu/apache/modules
          \&.\&.\&.
           chmod 755 /dosya/yolu/apache/modules/mod_foo\&.so
          [`foo' modülü /dosya/yolu/apache/conf/httpd\&.conf'ta etkinleştiriliyor]
           apachectl restart
           /dosya/yolu/apache/sbin/apachectl restart: httpd not running, trying to start
          chmod 755 /dosya/yolu/apache/modules/mod_foo\&.so
          [`foo' modülü /dosya/yolu/apache/etc/httpd\&.conf'ta etkinleştiriliyor]
          apachectl restart
          /dosya/yolu/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
          /dosya/yolu/apache/sbin/apachectl restart: httpd started
          $ _
        
    .fi
     
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/htcacheclean.8�������������������������������������������������������������0000664�0001751�0001751�00000014707�12133545173�017462� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2013-04-17" "Apache HTTP Sunucusu" "htcacheclean"
    .nh
    .SH İSİM
    htcacheclean \- Disk arabelleğini temizler
    
    .SH "KULLANIM"
     
    .PP
    \fBhtcacheclean\fR [ -\fBD\fR ] [ -\fBv\fR ] [ -\fBt\fR ] [ -\fBr\fR ] [ -\fBn\fR ] [ -\fBR\fR\fIboyut\fR ] -\fBp\fR\fIyol\fR [ -\fBl\fR\fIsınır\fR | -\fBL\fR\fIlimit\fR ]
     
    .PP
    \fBhtcacheclean\fR [ -\fBn\fR ] [ -\fBt\fR ] [ -\fBi\fR ] [ -\fBP\fR\fIpiddosyası\fR ] [ -\fBR\fR\fIboyut\fR ] -\fBd\fR\fIsüre\fR -\fBp\fR\fIyol\fR [ -\fBl\fR\fIsınır\fR | -\fBL\fR\fIlimit\fR ]
     
    .PP
    \fBhtcacheclean\fR [ -\fBv\fR ] [ -\fBR\fR\fIboyut\fR ] -\fBp\fR\fIyol\fR [ -\fBa\fR ] [ -\fBA\fR ]
     
    .PP
    \fBhtcacheclean\fR [ -\fBD\fR ] [ -\fBv\fR ] [ -\fBt\fR ] [ -\fBR\fR\fIboyut\fR ] -\fBp\fR\fIyol\fR \fIurl\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBhtcacheclean\fR, mod_cache_disk deposunun boyutlarını belli sınırlar içinde veya kullanımdaki dosya düğümlerinin sınırları içinde tutmak için kullanılır\&. Bu araç ya elle ya da bir artalan süreci olarak çalıştırılır\&. Artalan süreci olarak çalıştırıldığında, silinecek arabellek içeriğini tespit etmek için arabellek dizinlerine belli aralıklarla bakmak dışında uykuda olur\&. Artalan sürecini temiz olarak durdurmak için TERM veya INT sinyali göndermeniz yeterlidir\&. Elle çalıştırıldığında, silinecek arabellek içeriğini tespit etmek için arabellek dizinlerine bir kereliğine bakar\&. Bir veya daha fazla URL belirtilmesi durumunda arabellekte olanlar arabellekten silinir\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-d\fR\fI süre\fR
    Artalanda çalışarak \fIsüre\fR dakikada bir arabelleği temizler\&. Bu seçenek \fB-D\fR, \fB-v\fR ve \fB-r\fR seçenekleri ile birlikte kullanılamaz\&. Artalan sürecini temiz olarak sonlandırmak için SIGTERM veya SIGINT göndermek yeterlidir\&.  
    .TP
    \fB-D\fR
    Kuru kuruya çalışıp, hiçbir şeyi silmez\&. \fB-d\fR seçeneği ile birlikte kullanılamaz\&. Kuru çalıştırma sırasında \fB-t\fR seçeneği ile dizinler silinmek istenirse, statlarda silinmiş görünen dosya düğümleri silinmiş dizinler olarak hesaba katılmaz ve tahmini olarak imlenir\&.  
    .TP
    \fB-v\fR
    Çıktı daha ayrıntılı olur\&. \fB-d\fR seçeneği ile birlikte kullanılamaz\&.  
    .TP
    \fB-r\fR
    İyice temizlik yapılır\&. Bunun için Apache HTTP sunucusunun çalışmadığı varsayılır (aksi takdirde arabellek içeriği bozulabilir)\&. \fB-t\fR seçeneğinin de uygulanmasını sağlar\&. \fB-d\fR seçeneği ile birlikte kullanılamaz\&.  
    .TP
    \fB-n\fR
    Nazik olur\&. Diğer süreçlerin yararına daha yavaş çalışır\&. (a) disk G/Ç işlemlerinde gecikmeler olursa ve (b) çekirdek bu arada başka bir süreci öne çekmişse \fBhtcacheclean\fR uyumayı tercih edecektir\&.  
    .TP
    \fB-t\fR
    Tüm boş dizinleri siler\&. Öntanımlı olarak, sadece arabellek dosyaları silinirse de bazı yapılandırmalarda büyük miktarda dizin oluşturulması bu seçeneğin kullanılmasını gerektirebilir\&. Yapılandırmanız çok sayıda dizin gerektiriyorsa ve dosya düğümlerinin veya dosya ayırma tablolarının tükenmesi sözkonusu ise bu seçeneğin kullanılması önerilir\&.  
    .TP
    \fB-p\fR\fI yol\fR
    \fIyol\fR, disk arabelleğinin kök dizini olarak belirtilir\&. CacheRoot yönergesinde belirtilen dizin olmalıdır\&.  
    .TP
    \fB-P\fR\fIpiddosyası\fR
    Artalan süreci olarak çalışmada süreç kimliğinin yazılacağı dosyanın adını belirtmek için kullanılır\&.  
    .TP
    \fB-R\fR\fIboyut\fR
    Disk bloklarının boyunu denkleştirmek için yuvarlanacak üst boyutu belirtmekte kullanılır\&. Arabellek bölümünün blok boyutunu belirler\&.  
    .TP
    \fB-l\fR\fI sınır\fR
    \fIsınır\fR, disk arabelleğinin toplam boyutu olarak belirtilir\&. Değerin öntanımlı olarak bayt cinsinden belirtileceği varsayılır\&. Değerin sonuna kilobayt için K, megabayt M, bayt için B harfi konulabilir\&.  
    .TP
    \fB-L\fR\fIlimit\fR
    Disk arabellek dosyası düğümü toplamının sınırını belirlemekte kullanılır\&.  
    .TP
    \fB-i\fR
    Akıllı olup sadece disk arabelleği değiştiği zaman çalışır\&. Bu seçenek \fB-d\fR seçeneği ile birlikte belirtilmek zorundadır\&.  
    .TP
    \fB-a\fR
    O an arabellekte saklanmakta olan URL'leri listeler\&. Birden fazla aynı URL varsa yalnız biri listelenir\&.  
    .TP
    \fB-A\fR
    O an arabellekte saklanmakta olan URL'leri öznitelikleri ile listeler\&. Öznitelikler şu sırayla verilir: url, header size, body size, status, entity version, date, expiry, request time, response time, body present, head request  
     
    .SH "BELLİ BİR URL'NİN SİLİNMESİ"
     
    .PP
    \fBhtcacheclean\fR tarafından aktarılan URL'ler arabellekten silinir\&. Bir URL birden fazla mevcutsa hepsi silinir\&.
     
    .PP
    Ters vekilli bir URL silinmişse, etkin URL \fBHost\fR başlığı \fBport\fR, \fByol\fR ve \fBsorgu\fR ile oluşturulur\&. Bir sorgu dizgesi olsun olmasın, URL içinde '?' daima açıkça belirtilmelidir\&. Örneğin, \fBlocalhost\fR sunucusundaki \fB/\fR yolu silinmek istenirse silinecek URL \fBhttp://localhost:80/?\fR olurdu\&.
     
    .SH "ARABELLEKTEKİ URL'LERİN LİSTELENMESİ"
     
    .PP
    \fBhtcacheclean\fR'e \fB-a\fR veya \fB-A\fR seçeneğinin aktarılmasıyla, arabellekteki URL'ler bulundukça her satıra bir URL gelecek biçemde listelenir\&. \fB-A\fR seçeneği URL'nin ardından arabellek içeriğini tamamını şu sırayla dökümler:
     
     
    .TP
    url
    Öğenin URL'si\&. 
    .TP
    header size
    Bayt cinsinden başlık uzunluğu\&. 
    .TP
    body size
    Bayt cinsinden gövde uzunluğu\&. 
    .TP
    status
    Arabellekteki yanıtın durumu\&. 
    .TP
    entity version
    Öğenin silinmeksizin kaç kere doğrulandığı\&. 
    .TP
    date
    Yanıt tarihi\&. 
    .TP
    expiry
    Yanıtın zaman aşımı tarihi\&. 
    .TP
    request time
    İsteğin başlama zamanı\&. 
    .TP
    response time
    İsteğin bitiş zamanı\&. 
    .TP
    body present
    0 ise istekle birlikte gövde saklanmaz, 1 ise saklanır\&. 
    .TP
    head request
    1 ise, öğe, gövde olmaksızın arabellekli bir HEAD isteği içerir, 0 ise içermez\&. 
     
    .SH "ÇIKIŞ DURUMU"
     
    .PP
    \fBhtcacheclean\fR, tüm işlemler başarıyla yerine getirildiğinde 0, aksi takdirde 1 döndürür\&. Bir URL belirtildiğinde, bu URL arablleklenmi ve silinmişse 0, aksi takdirde 2 döndürür\&. URL'nin silinmesi sırasında bir hata oluşursa 1 döndürür\&.
     
    ���������������������������������������������������������httpd-2.4.64/docs/man/tr/rotatelogs.8���������������������������������������������������������������0000664�0001751�0001751�00000021071�12456632712�017237� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2015-01-18" "Apache HTTP Sunucusu" "rotatelogs"
    .nh
    .SH İSİM
    rotatelogs \- Apache günlüklerini döndürmek için borulu günlük kayıt programı
    
    .SH "KULLANIM"
     
    .PP
    \fBrotatelogs\fR [ -\fBl\fR ] [ -\fBL\fR \fIisim\fR ] [ -\fBp\fR \fIprogram\fR ] [ -\fBf\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBe\fR ] [ -\fBc\fR ] [ -\fBn\fR \fIdosya_sayısı\fR ] \fIdosyaismi\fR \fIsüre\fR|\fIboyut\fR(B|K|M|G) [ \fIsaat_farkı\fR ]
     
    
    .SH "ÖZET"
     
    .PP
    \fBrotatelogs\fR, Apache'nin borulu günlük dosyaları özelliği ile birlikte kullanmak için tasarlanmış basit bir programdır\&. Günlük dosyasının azami boyutuna göre veya belli aralıklarla günlük dosyalarını döndürür\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-l\fR
    GMT yerine yerel zamanın kullanılmasını sağlar\&.  
    .TP
    \fB-L\fR \fIbagismi\fR
    Belirtilen bağ dosyası ismine geçerli günlük dosyasından kalıcı bir bağ oluşturulur\&. tail -F bagismi gibi bir komut kullanılarak günlüğün sürekli izlenmesi için kullanılabilir\&.  
    .TP
    \fB-p\fR \fIprogram\fR
    Belirtildiği takdirde, \fBrotatelogs\fR yeni bir günlük dosyasının her açılışında belirtilen programı çalıştırır\&. Yeni açılan dosyanın ismi programa ilk argüman olarak aktarılır\&. Bu işlem bir döndürme sonrası yapılırsa eski günlük dosyası ikinci argüman olarak aktarılır\&. \fBrotatelogs\fR işlemini sürdürmek için belirtilen programın sonlanmasını beklemez, dolayısıyla sonlanma soucunda döndürülen hata kodunu günlüğe kaydetmez\&. Çalıştırılan program \fBrotatelogs\fR ile aynı stdin, stdout ve stderr'i kullanır ve ortamı da miras alır\&.  
    .TP
    \fB-f\fR
    İlk günlük giridisinin okunmasını beklemeden \fBrotatelogs\fR başlar başlamaz günlük dosyasının açılmasını sağlar\&. Çok meşgul sitelerde, sunucu başlatılıp ilk istek sunuluncaya kadar geçen zamanda günlük dosyasının yokluğu özdevinimli işlemler yapan bazı günlükleme araçlarında sorunlara yol açabilir\&. Bu seçenek bu gibi durumlarda yararlıdır\&.  
    .TP
    \fB-t\fR
    Günlük dosyasının döndürülmek yerine tepeden kırpılmasına sebep olur\&. Günlüğün \fBtail\fR gibi bir araç tarafından gerçek zamanda işlendiği ve veriyi saklamanın gerekmediği durumda kullanışlıdır\&. Dosya ismine bir sonek eklenmez, ancak biçem dizgesi '%' karakteri içeriyorsa buna uyulur\&.  
    .TP
    \fB-v\fR
    Standart hataya verilen çıktı daha ayrıntılı olur\&. Çıktı, yapılandırma çözümlemesinin sonuçlarını ve tüm dosya açma/kapama işlemlerini içerir\&.  
    .TP
    \fB-e\fR
    Günlüğü standart çıktıya basar\&. Günlüğün zincirdeki ilgili araç tarafından gerçek zamanda işlenmesi gerektiğinde kullanışlıdır\&.  
    .TP
    \fB-c\fR
    Create log file for each interval, even if empty\&.  
    .TP
    \fB-n\fR \fIdosya_sayısı\fR
    Zaman damgalarına bakılmaksızın bir dosya serisi açılır\&. Örneğin -n3 belirtilirse "logfile", "logfile\&.1", "logfile\&.2" serisi açılır ve "logfile" üzerine yazılır\&. 2\&.4\&.5 ve sonraki sürümler içindir\&.  
    .TP
    \fIdosyaismi\fR
    .PP Günlük dosyasının ismi yoluyla birlikte belirtilir\&. \fIdosyaismi\fR '%' karakterleri içeriyorsa bunlar strftime(3) biçem belirteçleri olarak ele alınır\&. Aksi takdirde, özdevinimli olarak \fI\&.nnnnnnnnnn\fR uzantısı üretilir\&. (\fB-t\fR seçeneği kullanılmadıkça) Uzantı saniye cinsindendir ve her iki durumda da bu değer, mevcut döngü diliminin başlangıcına göre hesaplanır\&. Örneğin, döndürmenin 86400 saniyede bir yapılacağı belirtilmişse, strftime(3) biçeminde oluşturulan saat, dakika ve saniye alanları, 24 saatlik sürenin başlangıcını (geceyarısı) göstermek üzere sıfırlarla doldurulur\&. .PP strftime(3) dosyaismi biçemlemesi kullanılırken, günlük dosyası biçeminin günlük dosyası döndürülürken her zaman farklı bir dosya ismi üretecek yeterlilikte parçacıklı yapıya sahip olduğundan emin olmalısınız\&. Aks takdirde döndürme işlemi yeni bir dosya başlatmak yerine hep aynı dosyanın üzerine yazar\&. Örneğin, \fIlogfile\fR için /var/log/errorlog\&.%Y-%m-%d belirtilmişse 5 mega baytta bir yeni bir günlük dosyasına başlanacaktır\&. Fakat 5 megabayta gün içinde iki kez ulaşılırsa aynı günlük dosyası üretilir ve günlük hep aynı dosyanın üzerine yazılır\&.  
    .TP
    \fIsüre\fR
    Günlük dosyasının yenisinin kaç saniyede bir açılacağı belirtilir\&. Örneğin, bu süre 3600 saniye ise günlük dosyası her saat başında yenilenir; 86400 saniye ise her geceyarısı yenilenir\&. (Bu süre zarfında günlüğe kaydedilecek bir olay gerçekleşmemişse dosya oluşturulmaz\&.)  
    .TP
    \fIboyut\fR(B|K|M|G)
    Boyuta göre döndürme için azami dosya boyutu\&. Belirtilenin bir süre değil de bir boyut değeri olarak ele alınması için değerin sonuna şu karakterlerden biri eklenmelidir: B (Bayt), K (kilobayt), M (megabayt), G (gigabayt)\&. .PP Süre ve boyut birlikte belirtilmişse boyut süreden sonra belirtilmelidir\&. Dosya yenilemesi, bunlardan hangisi daha önce aşılırsa o zaman gerçekleşir\&.  
    .TP
    \fIsaat_farkı\fR
    Koordinatlı evrensel zamana göre "dakika" farkı\&. Belirtilmezse, sıfır öntanımlıdır\&. Örneğin, -5 saatlik bir zaman diliminde bulunuyorsanız bu değer -300 olmalıdır\&. Çoğu durumda, bunun yerine \fB-l\fR seçeneğini kullanmak gerekir\&.  
     
    .SH "ÖRNEKLER"
     
    .nf
    
         CustomLog "|bin/rotatelogs /var/log/logfile 86400" common
    
    .fi
     
    .PP
    nnnn, günlük kaydının başladığı sistem zamanı olmak üzere /var/log/logfile\&.nnnn dosyası oluşturulur\&. Bu zaman, daima döngü süresinin katları olacağından bunu cron betiklerinizi eşzamanlamakta kullanabilirsiniz\&. Her döngü süresinin sonunda (burada 24 saat sonra) yeni bir günlük dosyası açılır\&.
     
    .nf
    
         CustomLog "|bin/rotatelogs -l /var/log/logfile\&.%Y\&.%m\&.%d 86400" common
    
    .fi
     
    .PP
    yyyy, yıl; mm, ay; dd, ayın gününü belirtmek üzere /var/log/logfile\&.yyyy\&.mm\&.dd dosyası oluşturulur\&. Her gün yerel zamanla geceyarısı yeni bir günlük dosyasına geçilecektir\&.
     
    .nf
    
         CustomLog "|bin/rotatelogs /var/log/logfile 5M" common
    
    .fi
     
    .PP
    Günlük dosyası 5 megabaytlık olunca yenisinin oluşturulmasını sağlar\&.
     
    .nf
    
         ErrorLog "|bin/rotatelogs /var/log/errorlog\&.%Y-%m-%d-%H_%M_%S 5M"
    
    .fi
     
    .PP
    Hata günlüğünün 5 megabaytta bir errorlog\&.YYYY-mm-dd-HH_MM_SS biçemli bir isimle oluşturulmasını sağlar\&.
     
    .nf
    
         CustomLog "|bin/rotatelogs -t /var/log/logfile 86400" common
    
    .fi
     
    .PP
    /var/log/logfile dosyasını oluşturur, sunucu başlatılırken ve günde bir kere dosyanın tepesi kırpılır\&. Bu senaryoda ayrı bir sürecin (tail gibi) dosyayı gerçek zamanlı işleyeceği umulur\&.
     
    .SH "TAŞINABİLİRLİK"
     
    .PP
    Aşağıdaki günlük dosyası biçem belirteçlerinin tüm strftime(3) gerçeklenimlerince desteklenmesi gerekir\&. Kullandığınız kütüphaneye özgü belirteçler için sisteminizdeki strftime(3) kılavuz sayfasına bakınız\&.
      
    .Ip "\(bu \s-1%A\s0 \- tam gün ismi (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%a\s0 \- 3 harflik gün ismi (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%B\s0 \- tam ay ismi (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%b\s0 \- 3 harflik ay ismi (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%c\s0 \- tarih ve saat (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%d\s0 \- 2 haneli ay günü numarası
     
    .Ip "\(bu \s-1%H\s0 \- 2 haneli saat (24 saatlik)
     
    .Ip "\(bu \s-1%I\s0 \- 2 haneli saat (12 saatlik)
     
    .Ip "\(bu \s-1%j\s0 \- 3 hanelik yıl günü numarası
     
    .Ip "\(bu \s-1%M\s0 \- 2 haneli dakika
     
    .Ip "\(bu \s-1%m\s0 \- 2 haneli ay
     
    .Ip "\(bu \s-1%p\s0 \- 12 saatlik kip için öö/ös (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%S\s0 \- 2 haneli saniye
     
    .Ip "\(bu \s-1%U\s0 \- 2 haneli yılın hafta numarası (Haftanın ilk gününün Pazar olduğu varsayımıyla)
     
    .Ip "\(bu \s-1%W\s0 \- 2 haneli yılın hafta numarası (Haftanın ilk gününün Pazartesi olduğu varsayımıyla)
     
    .Ip "\(bu \s-1%w\s0 \- 1 hanelik haftanın gün numarası (Haftanın ilk gününün Pazar olduğu varsayımıyla)
     
    .Ip "\(bu \s-1%X\s0 \- saat (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%x\s0 \- tarih (yerelleştirilmiş)
     
    .Ip "\(bu \s-1%Y\s0 \- 4 hanelik yıl
     
    .Ip "\(bu \s-1%y\s0 \- 2 hanelik yıl
     
    .Ip "\(bu \s-1%Z\s0 \- zaman dilimi ismi
     
    .Ip "\(bu \s-1%%\s0 \- `%' iminin kendisi
      
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/fcgistarter.8��������������������������������������������������������������0000664�0001751�0001751�00000001736�12243525621�017371� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "FCGİSTARTER" 8 "2013-11-22" "Apache HTTP Sunucusu" "fcgistarter"
    .nh
    .SH İSİM
    fcgistarter \- Bir FastCGI programını çalıştır
    
    .SH "KULLANIM"
     
    .PP
    \fBfcgistarter\fR -\fBc\fR \fIkomut\fR -\fBp\fR \fIport\fR [ -\fBi\fR \fIarabirim\fR ] -\fBN\fR \fIsayı\fR
     
    
    .SH "ÖZET"
     
    .PP
    
     
    
    .SH "BİLGİNİZE"
     
    .PP
    Şimdilik sadece Unix sistemlerinde çalışmaktadır\&.
     
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-c\fR \fIkomut\fR
    Çalıştırılacak FastCGI programı  
    .TP
    \fB-p\fR \fIport\fR
    Programın dinleyeceği port  
    .TP
    \fB-i\fR \fIarabirim\fR
    Programın dinleyeceği arabirim  
    .TP
    \fB-N\fR \fIsayı\fR
    Program örneklerinin sayısı  
     
    ����������������������������������httpd-2.4.64/docs/man/tr/logresolve.1���������������������������������������������������������������0000664�0001751�0001751�00000002732�12133545173�017225� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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" 1 "2013-04-17" "Apache HTTP Sunucusu" "logresolve"
    .nh
    .SH İSİM
    logresolve \- Apache günlük dosyalarındaki IP adreslerini konak isimlerine dönüştürür
    
    .SH "KULLANIM"
     
    .PP
    \fBlogresolve\fR [ -\fBs\fR \fIdosyaismi\fR ] [ -\fBc\fR ] < \fIgünlük_dosyası\fR > \fIyeni_günlük_dosyası\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBlogresolve\fR, Apache'nin erişim günlüklerindeki IP adreslerini çözümlemek için bir ardıl işlem uygulamasıdır\&. İsim sunucunuza bindirdiği yükü en aza indirmek için \fBlogresolve\fR kendi arabelleğinde oluşturduğu eşleme tablosunu kullanır\&.
     
    .PP
    Apache günlük dosyasını standart girdisinden okur\&. IP adresleri günlük dosyası satırlarında ilk bileşen olmalı ve sonraki bileşenlerden bir boşluk ile ayrılmalıdır\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    -s \fIdosyaismi\fR
    İstatistiklerin kaydedileceği dosyanın ismi belirtilir\&.  
    .TP
    -c
    \fBlogresolve\fR uygulamasının bazı DNS sorguları yapmasına sebep olur: IP adresine karşılık olan konak ismini bulduktan sonra özgün adresle karşılaştırmak için bu konak ismine karşılık gelen IP adresini sorgular\&.  
     
    ��������������������������������������httpd-2.4.64/docs/man/tr/htdigest.1�����������������������������������������������������������������0000664�0001751�0001751�00000004261�12133545173�016656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "HTDİGEST" 1 "2013-04-17" "Apache HTTP Sunucusu" "htdigest"
    .nh
    .SH İSİM
    htdigest \- Özet kimlik doğrulama dosyalarını yönetir
    
    .SH "KULLANIM"
     
    .PP
    \fBhtdigest\fR [ -\fBc\fR ] \fIparola-dosyası\fR \fIbölge\fR \fIkullanıcı\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBhtdigest\fR, HTTP kullanıcılarının digest türü kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının saklanmasında kullanılacak düz metin dosyalarını oluşturmak ve güncellemek için kullanılır\&. Apache HTTP sunucusunun mevcut özkaynaklarının kullanımı sadece \fBhtdigest\fR tarafından oluşturulan dosyalarda listelenmiş kullanıcılara tahsis edilebilir\&.
     
    .PP
    Bu kılavuz sayfası sadece komut satırı değiştirgelerini listeler\&. Kullanıcı kimlik doğrulamasını \fBhttpd\fR'de yapılandırmak için gerekli yönergelerle ilgili ayrıntılar için Apache dağıtımının bir parçası olan ve http://httpd\&.apache\&.org/ adresinde de bulunan Apache HTTP Sunucusu Belgelerine bakınız\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-c\fR
    \fIparola-dosyası\fR oluşturur\&. Dosya mevcutsa, dosya silinip yeniden yazılır\&.  
    .TP
    \fIparola-dosyası\fR
    Kullanıcı ismi, parola ve bölge bilgilerini içeren dosyanın ismi\&. \fB-c\fR seçeneği verilmişse ve dosya mevcut değilse oluşturulur, dosya mevcutsa silinip yeniden oluşturulur\&.  
    .TP
    \fIbölge\fR
    Kullanıcının mensup olduğu bölge ismi\&. Daha fazla bilgi için: http://tools\&.ietf\&.org/html/rfc2617#section-3\&.2\&.1  
    .TP
    \fIkullanıcı\fR
    \fIparola-dosyası\fR'nda oluşturulacak veya güncellenecek kullanıcı ismi\&. \fIkullanıcı\fR bu dosyada mevcut değilse yeni bir girdi eklenir\&. Girdi mevcutsa parolası değiştirilir\&.  
     
    .SH "GÜVENLİK DEĞERLENDİRMELERİ"
     
    .PP
    Bu program bir setuid çalıştırılabiliri olarak güvenilir olmadığından \fIsetuid yapılmamalıdır\fR\&.
     
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/htdbm.1��������������������������������������������������������������������0000664�0001751�0001751�00000022622�12133545173�016142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2013-04-17" "Apache HTTP Sunucusu" "htdbm"
    .nh
    .SH İSİM
    htdbm \- DBM parola veritabanlarını yönetir
    
    .SH "KULLANIM"
     
    .PP
    \fBhtdbm\fR [ -\fBT\fR\fIVTtürü\fR ] [ -\fBi\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIparola-dosyası\fR \fIkullanıcı\fR
     
    .PP
    \fBhtdbm\fR -\fBb\fR [ -\fBT\fR\fIVTtürü\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIparola-dosyası\fR \fIkullanıcı\fR \fIparola\fR
     
    .PP
    \fBhtdbm\fR -\fBn\fR [ -\fBi\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIkullanıcı\fR
     
    .PP
    \fBhtdbm\fR -\fBnb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIkullanıcı\fR \fIparola\fR
     
    .PP
    \fBhtdbm\fR -\fBv\fR [ -\fBT\fR\fIVTtürü\fR ] [ -\fBi\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIparola-dosyası\fR \fIkullanıcı\fR
     
    .PP
    \fBhtdbm\fR -\fBvb\fR [ -\fBT\fR\fIVTtürü\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIbedel\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIparola-dosyası\fR \fIkullanıcı\fR \fIparola\fR
     
    .PP
    \fBhtdbm\fR -\fBx\fR [ -\fBT\fR\fIVTtürü\fR ] \fIparola-dosyası\fR \fIkullanıcı\fR
     
    .PP
    \fBhtdbm\fR -\fBl\fR [ -\fBT\fR\fIVTtürü\fR ]
     
    
    .SH "ÖZET"
     
    .PP
    \fBhtdbm\fR, mod_authn_dbm üzerinden HTTP kullanıcılarının temel kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının saklanmasında kullanılacak DBM dosyalarını yönetmek için kullanılır\&. DBM dosyaları hakkında daha ayrıntılı bilgi edinmek için \fBdbmmanage\fR sayfasına bakınız\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-b\fR
    Betik kipi; parola için istek yapmak yerine parola komut satırından verilir\&. \fBParola komut satırında görünür\fR olacağından çok dikkatli kullanmak gerekir\&. Betik kullanımı için \fB-i\fR seçeneğine bakınız\&.  
    .TP
    \fB-i\fR
    Parolayı doğrulamaksızın standart girdiden okur (betik kullanımı için)\&.  
    .TP
    \fB-c\fR
    \fIparola-dosyası\fR oluşturur\&. Dosya mevcutsa, dosya silinip yeniden yazılır\&. Bu seçenek \fB-n\fR seçeneği ile birlikte kullanılamaz\&.  
    .TP
    \fB-n\fR
    Sonuçları veritabanında güncellemek yerine standart çıktıya gönderir\&. \fIparola-dosyası\fR belirtilmediğinden, bu seçenek komut satırı sözdizimini değiştirir\&. Bu seçenek \fB-c\fR seçeneği ile birlikte kullanılamaz\&.  
    .TP
    \fB-m\fR
    Parolalar için MD5 şifrelemesi kullanılır\&. Windows ve Netware için bu öntanımlıdır\&.  
    .TP
    \fB-B\fR
    Parolalar için bcrypt şifrelemesi kullanılır\&. Şu an için çok güvenli kabul edilmektedir\&.  
    .TP
    \fB-C\fR \fIbedel\fR
    Bu seçenek sadece \fB-B\fR (bcrypt şifrelemesi) seçeneği ile birlikte kullanılabilir\&. Bcrypt algoritmasına hesaplama süresini belirtir (daha yüksek değerler daha güvenlidir, öntanımlı 5, geçerli değerler: 4 - 31)\&.  
    .TP
    \fB-d\fR
    Parolaları şifrelemek için crypt() kullanılır\&. Windows, ve Netware dışında öntanımlıdır\&. \fBhtdbm\fR tarafından tüm platformlarda destekleniyor olsa da Windows ve Netware üzerinde httpd sunucusu tarafından desteklenmez\&. Bu algoritma günümüz standartlarında \fBgüvenilmez\fR kabul edilmektedir\&.  
    .TP
    \fB-s\fR
    Parolalar için SHA şifrelemesi kullanılır\&. LDAP Dizin değişim biçemini (ldif) kullanarak Netscape sunucularına/sunucularından göçü kolaylaştırır\&. Bu algoritma günümüz standartlarında \fBgüvenilmez\fR kabul edilmektedir\&.  
    .TP
    \fB-p\fR
    Düz metin parolalar kullanılır\&. \fBhtdbm\fR tarafından tüm platformlarda destekleniyor olsa da Windows, Netware ve TPF üzerinde httpd sunucusu tarafından sadece düz metin parolalar kabul edilir\&.  
    .TP
    \fB-l\fR
    Veritabanındaki kullanıcıları açıklamalarıyla birlikte standart çıktıya gönderir\&.  
    .TP
    \fB-v\fR
    Kullanıcı adını ve parolasını doğrular\&. Program belirtilen parolanın geçerli olup olmadığını belirten bir ileti basar\&. Eğer parola geçersizse program hata kodu 3 ile çıkar\&.  
    .TP
    \fB-x\fR
    Kullanıcıyı siler\&. Kullanıcı belirtilen DBM dosyasında mevcutsa silinir\&.  
    .TP
    \fB-t\fR
    Son değiştirgenin bir açıklama olarak yorumlanmasını sağlar\&. Bu seçenek kullanıldığında komut satırının sonuna fazladan bir dizge eklenebilir\&. Bu dizge, veritabanında belirtilen kullanıcının "Comment" alanında saklanır\&.  
    .TP
    \fIparola-dosyası\fR
    DBM dosyasının ismi\&. Genellikle, \&.db, \&.pag veya \&.dir eklentisi olmaksızın belirtilir\&. \fB-c\fR seçeneği ile birlikte verilmişse ve DBM dosyası mevcut değilse dosya oluşturulur, mevcutsa dosya güncellenir\&.  
    .TP
    \fIkullanıcı\fR
    \fIparola-dosyası\fR'nda oluşturulacak veya güncellenecek kullanıcı ismi\&. \fIkullanıcı\fR bu dosyada mevcut değilse yeni bir girdi eklenir\&. Girdi mevcutsa parolası değiştirilir\&.  
    .TP
    \fIparola\fR
    Şifrelenip DBM dosyasında saklanacak düz metin parola\&. Sadece \fB-b\fR seçeneği ile kullanılır\&.  
    .TP
    \fB-T\fR \fIVTtürü\fR
    DBM dosyasının türü; SDBM, GDBM, DB, veya "default" olabilir\&.  
     
    .SH "HATALAR"
     
    .PP
    Birden fazla DBM dosya biçemi vardır ve büyük bir olasılıkla da sisteminizde bu birden fazla biçemle ilgili kütüphaneler vardır\&. SDBM, NDBM, GNU'nun GDBM projesi ve Berkeley/Sleepycat DB 2/3/4 bunların başlıcalarıdır\&. Ne yazık ki, bu kütüphanelerin her birinin dosya biçimleri farklıdır\&. Bu bakımdan, \fIdosyaismi\fR dosyasında kullanılan dosya biçeminin \fBhtdbm\fR tarafından kullanılanla aynı biçemde olduğundan emin olmalısınız\&. \fBhtdbm\fR hangi tür DBM dosyasına baktığını saptayacak yeterliliğe sahip değildir\&. Yanlış biçemli bir dosya belirtirseniz hiçbir şey dönmeyebileceği gibi, başka isimde bir DBM dosyasının oluşturulması veya daha da kötüsü üzerine yazmaya çalışıyorsanız DBM dosyasının bozulması bile olasıdır\&.
     
    .PP
    Unix sistemlerinde, kullanılan DBM dosyasının biçemini öğrenmek için \fBfile\fR programı kullanılabilir\&.
     
    .SH "ÇIKIŞ DURUMU"
     
    .PP
    \fBhtdbm\fR, kullanıcı ismi ve parolasını DBM dosyasına başarıyla eklemiş veya güncellemişse 0, dosyalara erişirken bir sorun çıkmışsa 1, komut satırında bir sözdizimi hatası varsa 2, parola etkileşimli alınmış fakat girdi ile eşleşme sağlanamamışsa 3, işlem kesintiye uğramışsa 4, bir değer çok uzunsa 5 (kullanıcı, parola, dosya ismi veya açıklama), kullanıcı ismi kuraldışı karakter içeriyorsa (Kısıtlamalar bölümüne bakınız) 6 ve dosya geçerli bir DBM parola dosyası değilse 7 değeriyle döner\&.
     
    .SH "ÖRNEKLER"
     
    .nf
    
          htdbm /usr/local/etc/apache/\&.htdbm-users jsmith
        
    .fi
     
    .PP
    jsmith kullanıcısı için parolayı ekler veya değiştirir\&. Parolayı vermesi için kullanıcıya parola isteği yapılır\&. Windows üzerinde çalıştırılırsa parola Apache MD5 algoritması ile şifrelenir, aksi takdirde sistemin crypt() yordamı kullanılır\&. Dosya mevcut değilse \fBhtdbm\fR beklenen hiçbir işlemi yapmadan bir hata vererek çıkar\&.
     
    .nf
    
          htdbm -c /home/doe/public_html/\&.htdbm jane
        
    .fi
     
    .PP
    Yeni bir dosya oluşturur ve kullanıcı jane için kaydı bir girdi olarak bu dosyaya yazar\&. Dosya mevcutsa fakat okunamıyor veya yazılamıyorsa dosyada bir değişiklik yapılmaz ve \fBhtdbm\fR bir ileti gösterip bir hata durumu ile çıkar\&.
     
    .nf
    
          htdbm -mb /usr/web/\&.htdbm-all jones Pwd4Steve
        
    .fi
     
    .PP
    Komut satırından verilen parolayı (Pwd4Steve) MD5 algoritmasıyla şifreler ve bunu belirtilen dosyada saklar\&.
     
    .SH "GÜVENLİK DEĞERLENDİRMELERİ"
     
    .PP
    \fBhtdbm\fR tarafından yönetilen parola dosyalarına sunucunun URI uzayından erişilememelidir; yani dosya bir tarayıcı ile okunabilecek bir yerde bulunmamalıdır\&.
     
    .PP
    Komut satırında parolanın şifrelenmemiş olarak görünmesi sebebiyle \fB-b\fR seçeneğinin kullanımından kaçınılmasını öneriyoruz\&.
     
    .PP
    crypt() algoritması kullanılırken, parolayı şekillendirmek için parolanın ilk 8 baytının kullanılacağına dikkat ediniz\&. Eğer parola 8 bayttan uzunsa kalanlar bir uyarı verilmeksizin iptal edilir\&.
     
    .PP
    SHA şifreleme biçeminde tuz kullanılmaz; yani, bir parolanın sadece bir şifreli gösterimi olabilir\&. crypt() ve MD5 biçemleri parolanın önüne rasgele üretilmiş bir tuz dizgesi eklediklerinden sözlük saldırılarına karşı daha dayanıklıdır\&.
     
    .PP
    SHA ve crypt() biçimleri günümüz standartlarında \fBgüvenilmez\fR kabul edilmektedir\&.
     
    .SH "KISITLAMALAR"
     
    .PP
    Windows platformunda, \fBhtdbm\fR ile şifrelenen parolalar 255 karakterden daha uzun olamaz\&. 255 karakterden sonrası kırpılır\&.
     
    .PP
    \fBhtdbm\fR tarafından kullanılan MD5 algoritması Apache yazılımına özeldir; bu algoritma ile şifrelenen parolalar başka HTTP sunucularında kullanılamayabilir\&.
     
    .PP
    Kullanıcı isimleri 255 bayttan uzun olamaz ve iki nokta imi (:) içeremez\&.
     
    ��������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/httpd.8��������������������������������������������������������������������0000664�0001751�0001751�00000013200�12352211121�016150� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2014-06-24" "Apache HTTP Sunucusu" "httpd"
    .nh
    .SH İSİM
    httpd \- Apache Hiper Metin Aktarım Protokolü Sunucusu
    
    .SH "KULLANIM"
     
    .PP
    \fBhttpd\fR [ -\fBd\fR \fIsunucu-kök-dizini\fR ] [ -\fBf\fR \fIyapılandırma-dosyası\fR ] [ -\fBC\fR \fIyönerge\fR ] [ -\fBc\fR \fIyönerge\fR ] [ -\fBD\fR \fIparametre\fR ] [ -\fBe\fR \fIseviye\fR ] [ -\fBE\fR \fIdosya\fR ] [ \fB-k\fR start | restart | graceful | stop | graceful-stop ] [ -\fBh\fR ] [ -\fBl\fR ] [ -\fBL\fR ] [ -\fBS\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBV\fR ] [ -\fBX\fR ] [ -\fBM\fR ] [ -\fBT\fR ]
     
    .PP
    Windows sistemlerinde, ek olarak şunlar vardır:
     
    .PP
    \fBhttpd\fR [ -\fBk\fR install | config | uninstall ] [ -\fBn\fR \fIisim\fR ] [ -\fBw\fR ]
     
    
    .SH "ÖZET"
     
    .PP
    \fBhttpd\fR, Apache Hiper Metin Aktarım Protokolü (HTTP) sunucusu programıdır\&. Tek başına çalışan bir artalan süreci olarak tasarlanmıştır\&. Bu tarz kullanıldığında istekleri işleme sokmak için çocuk süreçlerden ve evrelerden oluşan bir havuz oluşturur\&.
     
    .PP
    Genelde, \fBhttpd\fR'nin doğrudan çağrılmaması gerekir\&. Unix ve benzerlerinde apachectl aracılığıyla, Windows NT, 2000 ve XP'de bir hizmet olarak, Windows 9x ve ME'de ise bir konsol uygulaması olarak çalıştırılır\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-d\fR \fIsunucu-kök-dizini\fR
    \fIsunucu-kök-dizini\fR'ni ServerRoot yönergesine ilk değer olarak atar\&. Yapılandırma dosyasındaki bir ServerRoot yönergesiyle bu atama geçersiz kılınabilir\&. Bu seçenek belirtilmediği takdirde /usr/local/apache2 dizini öntanımlıdır\&.  
    .TP
    \fB-f\fR \fIyapılandırma-dosyası\fR
    Başlatma sırasında \fIyapılandırma-dosyası\fR'ndaki yönergeler kullanılır\&. Eğer \fIyapılandırma-dosyası\fR bir / ile başlamıyorsa dosyanın ServerRoot yönergesinin değerine göreli olduğu varsayılır\&. Seçenek belirtilmediği takdirde conf/httpd\&.conf öntanımlı değerdir\&.  
    .TP
    \fB-k\fR start | restart | graceful | stop | graceful-stop
    \fBhttpd\fR'yi başlatmak, durdurmak ve yeniden başlatmak için sinyal gönderir\&. Daha ayrıntılı bilgi edinmek için Apache httpd'nin Durdurulması belgesine bakınız\&.  
    .TP
    \fB-C\fR \fIyönerge\fR
    Yapılandırma \fIyönerge\fR'sini yapılandırma dosyalarını okumadan önce işleme sokar\&.  
    .TP
    \fB-c\fR \fIyönerge\fR
    Yapılandırma \fIyönerge\fR'sini yapılandırma dosyalarını okuduktan sonra işleme sokar\&.  
    .TP
    \fB-D\fR \fIparametre\fR
    Sunucu başlatılırken veya yeniden başlatılırken komutları şarta bağlı olarak işleme sokmak veya atlamak için yapılandırma dosyalarında kullanılan <IfDefine> bölümlerinde kullanılmak üzere bir yapılandırma \fIparametre\fR'si tanımlar\&. Ayrıca, -DNO_DETACH (ana sürecin çatallanmasını engellemek için), -DFOREGROUND (ana sürecin setsid() ve benzerlerinden çağrılmasını engellemek için) gibi daha az bilinen bazı başlatma parametrelerini atamakta da kullanılabilir\&.  
    .TP
    \fB-e\fR \fIseviye\fR
    Hata günlüğü seviyesi olarak LogLevel yönergesine sunucu başlatılırken \fIseviye\fR değerini atar\&. Bu seçenek, başlatma sırasındaki sorunları saptamak amacıyla hata iletilerinin ayrıntı seviyesini geçici olarak arttırmak için kullanılır\&.  
    .TP
    \fB-E\fR \fIdosya\fR
    Sunucunun başlatılması sırasında hata iletilerinin belirtilen \fIdosya\fR'ya gönderilmesini sağlar\&.  
    .TP
    \fB-h\fR
    Mevcut komut satırı seçeneklerinin kısa bir özetini çıktılar\&.  
    .TP
    \fB-l\fR
    Sunucunun içinde derlenmiş modüllerin listesini çıktılar\&. Bu liste LoadModule yönergesi kullanılarak devingen olarak yüklenen modülleri içermez\&.  
    .TP
    \fB-L\fR
    Durağan modüllerce sağlanmış yönergeleri olası değerleriyle geçerli konumlarına yerleştirerek listeler\&. Paylaşımlı modüllerce sağlanan yönergeleri listelemez\&.  
    .TP
    \fB-M\fR
    Yüklü durağan ve paylaşımlı modülleri listeler\&.  
    .TP
    \fB-S\fR
    Yapılandırma dosyasından çözümlenmiş haliyle ayarları gösterir (şu an sadece sanal konak ayarları gösterilmektedir)\&.  
    .TP
    \fB-T\fR (2\&.3\&.8 ve sonrasında kullanılabilmektedir)
    Başlatma ve yeniden başlatma sırasında belge kökü sınanmadan geçilir\&.  
    .TP
    \fB-t\fR
    Yapılandırma dosyasını sözdizimi hatalarına karşı denetler\&. Program sözdizimini denetledikten sonra sözdizimi geçerliyse 0 ile, değilse sıfırdan farklı bir değerle çıkar\&. \fB-D\fRDUMP_VHOSTS seçeneği ile birlikte kullanılmışsa ek olarak sanal konak ayrıntıları da basılır\&. \fB-D\fRDUMP_MODULES seçeneği ile ise ek olarak tüm modüller listelenir\&.  
    .TP
    \fB-v\fR
    \fBhttpd\fR sürümünü basar ve çıkar\&.  
    .TP
    \fB-V\fR
    Sürümü ve \fBhttpd\fR kurulum parametrelerini basar ve çıkar\&.  
    .TP
    \fB-X\fR
    \fBhttpd\fR hata ayıklama kipinde çalışır\&. Tek çocuk süreç başlatılır ve sunucu konsolu terketmez\&.  
     
    .PP
    Aşağıdaki seçenekler sadece Windows platformunda geçerlidir:
     
     
    .TP
    \fB-k\fR install | config | uninstall
    Parametreler bakımından sırasıyla: Apache httpd bir Windows NT hizmeti haline getirilir; başlatma seçenekleri Apache httpd hizmeti için değiştirilir; ve Apache httpd hizmeti sistemden kaldırılır\&.  
    .TP
    \fB-n\fR \fIisim\fR
    Sinyal gönderilecek Apache httpd hizmetinin \fIismi\fR\&.  
    .TP
    \fB-w\fR
    Hata durumunda konsol penceresi açık tutularak hata iletilerinin okunması sağlanır\&.  
     
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/httxt2dbm.1����������������������������������������������������������������0000664�0001751�0001751�00000003452�12133545173�016764� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "HTTXT2DBM" 1 "2013-04-17" "Apache HTTP Sunucusu" "httxt2dbm"
    .nh
    .SH İSİM
    httxt2dbm \- RewriteMap ile kullanmak için DBM dosyaları üretir
    
    .SH "KULLANIM"
     
    .PP
    \fBhttxt2dbm\fR [ -\fBv\fR ] [ -\fBf\fR \fIDBM_türü\fR ] -\fBi\fR \fIkaynak_metin\fR -\fBo\fR \fIçıktı_DBM\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBhttxt2dbm\fR, RewriteMap ile kullanmak için düz metin dosyalardan DBM dosyaları üretir\&.
     
    .PP
    Çıktı dosyası mevcutsa dosya kırpılmaz\&. Yeni anahtarlar eklenir, mevcutlar da güncellenir\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fB-v\fR
    Çıktı daha ayrıntılı olur\&.  
    .TP
    \fB-f\fR \fIDBM_türü\fR
    Çıktı için kullanılacak DBM türü belirtilir\&. Belirtilmediği takdirde APR öntanımlısı kullanılır\&. Belirtilebilecek DBM türleri: GDBM dosyalar için GDBM, SDBM dosyalar için SDBM, Berkeley DB dosyalar için DB, NDBM dosyalar için NDBM, öntanımlı DBM türü için default  
    .TP
    \fB-i\fR \fIkaynak_metin\fR
    DBM dosyasının üretiminde kullanılacak girdi dosyası belirtilir\&. Bu dosya, her satırda bir kayıt bulunmak üzere her satırı şöyle biçemlenmiş olmalıdır: anahtar değer\&. Bu dosyanın biçemi ve manası ile ilgili ayrıntılar için RewriteMap yönergesinin açıklamasına bakınız\&.  
    .TP
    \fB-o\fR \fIçıktı_DBM\fR
    Çıktılanacak DBM dosyasının ismi belirtilir\&.  
     
    .SH "ÖRNEKLER"
     
    .nf
    
          httxt2dbm -i rewritemap\&.txt -o rewritemap\&.dbm
          httxt2dbm -f SDBM -i rewritemap\&.txt -o rewritemap\&.dbm 
    .fi
     
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/dbmmanage.1����������������������������������������������������������������0000664�0001751�0001751�00000014256�12133545173�016763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2013-04-17" "Apache HTTP Sunucusu" "dbmmanage"
    .nh
    .SH İSİM
    dbmmanage \- DBM biçemli kullanıcı kimlik doğrulama dosyalarını yönetir
    
    .SH "KULLANIM"
     
    .PP
    \fBdbmmanage\fR [ \fIkodlama\fR ] \fIdosyaismi\fR add|adduser|check|delete|update \fIkullanıcı\fR [ \fIşifreli_parola\fR [ \fIgrup\fR[,\fIgrup\fR\&.\&.\&.] [ \fIaçıklama\fR ] ] ]
     
    .PP
    \fBdbmmanage\fR \fIdosyaismi\fR view [ \fIkullanıcı\fR ]
     
    .PP
    \fBdbmmanage\fR \fIdosyaismi\fR import
     
    
    .SH "ÖZET"
     
    .PP
    \fBdbmmanage\fR, mod_authn_dbm üzerinden HTTP kullanıcılarının temel kimlik doğrulaması için kullanıcı isimlerinin ve parolalarının saklanmasında kullanılacak DBM dosyalarını oluşturmak ve güncellemek için kullanılır\&. Apache HTTP sunucusunun mevcut özkaynaklarının kullanımı sadece \fBdbmmanage\fR tarafından oluşturulan dosyalarda listelenmiş kullanıcılara tahsis edilebilir\&. Bu program sadece, kullanıcı isimleri bir DBM dosyasında saklanmak istenirse işe yarar\&. Düz metin bir veritabanı kullanmak isterseniz \fBhtpasswd\fR sayfasına bakınız\&.
     
    .PP
    DBM parola veritabanı sağlayan diğer bir araç da \fBhtdbm\fR'dir\&.
     
    .PP
    Bu kılavuz sayfası sadece komut satırı değiştirgelerini listeler\&. Kullanıcı kimlik doğrulamasını \fBhttpd\fR'de yapılandırmak için gerekli yönergelerle ilgili ayrıntılar için Apache dağıtımının bir parçası olan ve http://httpd\&.apache\&.org/ adresinde de bulunan Apache HTTP Sunucusu Belgelerine bakınız\&.
     
    
    .SH "SEÇENEKLER"
     
     
    .TP
    \fIdosyaismi\fR
    DBM dosyasının ismi\&. Genellikle, \&.db, \&.pag veya \&.dir eklentisi olmaksızın belirtilir\&.  
    .TP
    \fIkullanıcı\fR
    İşlemleri gerçekleştirecek kullanıcı ismi\&. \fIkullanıcı\fR ismi ikinokta imi (:) içeremez\&.  
    .TP
    \fIşifreli_parola\fR
    \fBupdate\fR ve \fBadd\fR komutları için kullanılacak şifreli paroladır\&. Parolanın istenmesini sağlamak, fakat hemen ardından alanları doldurmak için bir tire imi (-) kullanabilirsiniz\&. Buna ek olarak, \fBupdate\fR komutunu kullanırken özgün parolaya dokunulmaması için bir nokta imi (\&.) kullanabilirsiniz\&.  
    .TP
    \fIgrup\fR
    Kullanıcının üyesi olduğu grup\&. Grup ismi ikinokta imi (:) içeremez\&.Kullanıcıyı bir gruba atamadan açıklama alanını doldurmak istiyorsanız bir tire imi (-) kullanabilirsiniz\&. Buna ek olarak, \fBupdate\fR komutunu kullanırken özgün gruba dokunulmaması için bir nokta imi (\&.) kullanabilirsiniz\&.  
    .TP
    \fIaçıklama\fR
    Adı ve soyadı, eposta adresi gibi kullanıcıyla ilgili bir takım bilgiler buraya yazılır\&. Sunucu bu alanı gözardı eder\&.  
     
    .SS "Kodlamalar"
     
     
    .TP
    \fB-d\fR
    CRYPT şifrelemesi (Win32 ve Netware hariç, öntanımlı)  
    .TP
    \fB-m\fR
    MD5 şifrelemesi (Win32 ve Netware için öntanımlı)  
    .TP
    \fB-s\fR
    SHA1 şifrelemesi  
    .TP
    \fB-p\fR
    düz metin (\fIönerilmez\fR)  
      
    .SS "Komutlar"
     
     
    .TP
    \fBadd\fR
    \fIşifreli_parola\fR'yı kullanarak \fIdosyaismi\fR dosyasına \fIkullanıcı\fR için bir girdi ekler\&. dbmmanage passwords\&.dat add rbowen foKntnEF3KSXA  
    .TP
    \fBadduser\fR
    Parola sorduktan sonra \fIdosyaismi\fR dosyasına \fIkullanıcı\fR için bir girdi ekler\&. dbmmanage passwords\&.dat adduser krietz  
    .TP
    \fBcheck\fR
    Parola sorduktan sonra belirtilen \fIkullanıcı\fR, \fIdosyaismi\fR dosyasında var mı diye bakar; varsa belirtilen parolayı kullanıcınınkiyle eşleştirmeye çalışır\&. dbmmanage passwords\&.dat check rbowen  
    .TP
    \fBdelete\fR
    \fIdosyaismi\fR dosyasından \fIkullanıcı\fR girdisini siler\&. dbmmanage passwords\&.dat delete rbowen  
    .TP
    \fBimport\fR
    Standart girdiden \fIkullanıcı\fR:\fIparola\fR satırlarını (her satırda bir tane) okur ve bunları \fIdosyaismi\fR dosyasına ekler\&. Parola şifrelenmiş olmalıdır\&.  
    .TP
    \fBupdate\fR
    Belirtilen \fIkullanıcı\fR'nın \fIdosyaismi\fR dosyasında mevcut olması dışında \fBadduser\fR komutu gibidir\&. dbmmanage passwords\&.dat update rbowen  
    .TP
    \fBview\fR
    Sadece, DBM dosyasının içeriğini gösterir\&. Bir \fIkullanıcı\fR belirtirseniz sadece o kaydı gösterir\&. dbmmanage passwords\&.dat view  
      
    .SH "HATALAR"
     
    .PP
    Birden fazla DBM dosya biçemi vardır ve büyük bir olasılıkla da sisteminizde bu birden fazla biçemle ilgili kütüphaneler vardır\&. SDBM, NDBM, GNU'nun GDBM projesi ve Berkeley DB 2 bunların başlıcalarıdır\&. Ne yazık ki, bu kütüphanelerin her birinin dosya biçimleri farklıdır\&. Bu bakımdan, \fIdosyaismi\fR dosyasında kullanılan dosya biçeminin \fBdbmmanage\fR tarafından kullanılanla aynı biçemde olduğundan emin olmalısınız\&. \fBdbmmanage\fR hangi tür DBM dosyasına baktığını saptayacak yeterliliğe sahip değildir\&. Yanlış biçemli bir dosya belirtirseniz hiçbir şey dönmeyebileceği gibi, başka isimde bir DBM dosyasının oluşturulması veya daha da kötüsü üzerine yazmaya çalışıyorsanız DBM dosyasının bozulması bile olasıdır\&.
     
    .PP
    \fBdbmmanage\fR programının başlangıcında @AnyDBM::ISA dizisi olarak tanımlanmış DBM biçem tercihlerinin bir listesi vardır\&. Berkeley DB 2 biçemini tercih ettiğimizden \fBdbmmanage\fR sistem kütüphanelerini şu sıraya göre arar: Berkeley DB 2, NDBM, GDBM ve SDBM\&. \fBdbmmanage\fR DBM dosyası hareketleri için bu sıralamaya göre bulduğu ilk kütüphaneyi kullanacaktır\&. Sıralama Perl'deki dbmopen() çağrısının kullandığından faklı olduğu gibi Perl'deki standart @AnyDBM::ISA sıralamasından da oldukça farklıdır\&. Bu bakımdan, DBM dosyalarınızı yönetmek için Perl ile yazılmış başka araçlar kullanıyorsanız, onların da bu tercih sırasını izlemesini sağlamalısınız\&. Benzer şekilde, bu dosyalara erişmek için diğer dillerde (C gibi) yazılmış programlar kullanıyorsanız bunlar için de aynı durum geçerlidir\&.
     
    .PP
    Unix sistemlerinde, kullanılan DBM dosyasının biçemini öğrenmek için \fBfile\fR programı kullanılabilir\&.
     
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/tr/apachectl.8����������������������������������������������������������������0000664�0001751�0001751�00000011771�12133545173�017002� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2013-04-17" "Apache HTTP Sunucusu" "apachectl"
    .nh
    .SH İSİM
    apachectl \- Apache HTTP Sunucusu Denetim Arayüzü
    
    .SH "KULLANIM"
     
    .PP
    \fBapachectl\fR önyüz kipinde çalıştığında \fBhttpd\fR programının bütün komut satırı argümanlarını kabul edebilir\&.
     
    .PP
    \fBapachectl\fR [ \fIhttpd-argümanları\fR ]
     
    .PP
    SysV başlatma betiği kipinde ise, \fBapachectl\fR aşağıda tanımlanan basit, tek sözcüklük komutları kabul eder\&.
     
    .PP
    \fBapachectl\fR \fIkomut\fR
     
    
    .SH "ÖZET"
     
    .PP
    \fBapachectl\fR Apache Hiper Metin Aktarım Protokolü (HTTP) sunucusu için bir denetim aracıdır\&. Sistem yöneticisinin Apache \fBhttpd\fR artalan sürecini denetimi altında tutabilmesine yardımcı olmak amacıyla tasarlanmıştır\&.
     
    .PP
    \fBapachectl\fR iki kipte işleyebilir\&. İlkinde, \fBhttpd\fR komutu için basit bir önyüz gibi davranarak, gerekli ortam değişkenlerini atar ve belirtilen komut satırı seçenekleriyle \fBhttpd\fR sürecini başlatır\&. İkinci kipte ise, \fBapachectl\fR bir SysV başlatma betiği olarak \fBstart\fR, \fBrestart\fR, \fBstop\fR gibi tek sözcüklük basit argümanlar alır ve bunları uygun sinyallere dönüştürerek \fBhttpd\fR'ye gönderir\&.
     
    .PP
    Eğer Apache kurulumunuzda standart dışı dosya yolları kullanmışsanız, \fBhttpd\fR programına uygun yolları atamak için \fBapachectl\fR betiğini elden geçirmelisiniz\&. Bu arada gerek gördüğünüz \fBhttpd\fR komut satırı argümanlarını da belirtebilirsiniz\&. Ayrıntılar için betik içindeki açıklamalara bakınız\&.
     
    .PP
    \fBapachectl\fR betiği başarı durumunda 0 çıkış değeri ile döner\&. Bir hata durumunda ise sıfırdan farklı bir değerle döner\&. Daha fazla bilgi için betik içindeki açıklamalara bakınız\&.
     
    
    .SH "SEÇENEKLER"
     
    .PP
    Burada sadece SysV başlatma betiğine özgü seçeneklere yer verilmiştir\&. Diğer argümanlar için \fBhttpd\fR kılavuz sayfasına bakınız\&.
     
     
    .TP
    \fBstart\fR
    Apache \fBhttpd\fR artalan sürecini başlatır\&. Zaten çalışmaktaysa bir hata verir\&. \fBapachectl -k start\fR komutuna eşdeğerdir\&.  
    .TP
    \fBstop\fR
    Apache \fBhttpd\fR artalan sürecini durdurur\&. \fBapachectl -k stop\fR komutuna eşdeğerdir\&.  
    .TP
    \fBrestart\fR
    Apache \fBhttpd\fR artalan sürecini yeniden başlatır; çalışmıyorsa çalıştırılır\&. Artalan sürecinin ölü olmadığından emin olmak için yeniden başlatmadan önce \fBconfigtest\fR seçeneği verilmiş gibi yapılandırma dosyaları sınanır\&. \fBapachectl -k restart\fR komutuna eşdeğerdir\&.  
    .TP
    \fBfullstatus\fR
    \fBmod_status\fR üzerinden tam bir durum raporu gösterir\&. Bunun çalışması için sunucuda \fBmod_status\fR etkinleştirilmiş olmalı ve sisteminizde \fBlynx\fR gibi bir metin kipi HTTP tarayıcı kurulu olmalıdır\&. Durum raporuna erişmek için kullanılacak adres betik içinde STATUSURL değişkenine atanabilir\&.  
    .TP
    \fBstatus\fR
    Özet halinde bir durum raporu gösterir\&. O an sunulmakta olan isteklerin gösterilmemesi dışında \fBfullstatus\fR seçeneği gibidir\&.  
    .TP
    \fBgraceful\fR
    Apache \fBhttpd\fR artalan sürecini \fInazikçe\fR yeniden başlatır; çalışmıyorsa çalıştırılır\&. O an hizmet sunmakta olan çocuk süreçleri hemen durdurmaması dışında normal yeniden başlatma gibidir\&. Bir yan etki olarak eski günlük dosyaları hemen kapatılmaz\&. Yani, günlük dosyalarını döndüren bir betik kullanıyorsanız yenilerini başlatmadan önce eski dosyaların tamamen kapandığından emin olmak için belli bir süre beklemeniz gerekecektir\&. Artalan sürecinin ölü olmadığından emin olmak için yeniden başlatmadan önce \fBconfigtest\fR seçeneği verilmiş gibi yapılandırma dosyaları sınanır\&. \fBapachectl -k graceful\fR komutuna eşdeğerdir\&.  
    .TP
    \fBgraceful-stop\fR
    Apache \fBhttpd\fR artalan sürecini \fInazikçe\fR durdurur\&. O an hizmet sunmakta olan çocuk süreçleri hemen durdurmaması dışında normal durdurma gibidir\&. Bir yan etki olarak eski günlük dosyaları hemen kapatılmaz\&. \fBapachectl -k graceful-stop\fR komutuna eşdeğerdir\&.  
    .TP
    \fBconfigtest\fR
    Yapılandırma dosyasında sözdizimi denetimi yapılmasını sağlar\&. Yapılandırma dosyaları çözümlenir ve bir sorun yoksa bir Syntax Ok raporu verilir fakat, bir hata varsa o hataya ilişkin ayrıntılı bilgi verilir\&. \fBapachectl -t\fR komutuna eşdeğerdir\&.  
     
    .PP
    Aşağıdaki seçenek eski sürümlerde kullanılmaktaydı, fakat artık kullanılmamaktadır\&.
     
     
    .TP
    startssl
    \fBhttpd\fR programını SSL destekli başlatmak için, yapılandırma dosyanızı ilgili yönergeleri içermesi için elden geçirmeli ve normal \fBapachectl start\fR komutunu kullanmalısınız\&.  
     
    �������httpd-2.4.64/docs/man/rotatelogs.8������������������������������������������������������������������0000664�0001751�0001751�00000023547�14401204253�016607� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2023-03-05" "Apache HTTP Server" "rotatelogs"
    
    .SH NAME
    rotatelogs \- Piped logging program to rotate Apache logs
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBrotatelogs\fR [ -\fBl\fR ] [ -\fBL\fR \fIlinkname\fR ] [ -\fBp\fR \fIprogram\fR ] [ -\fBf\fR ] [ -\fBD\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBe\fR ] [ -\fBc\fR ] [ -\fBn\fR \fInumber-of-files\fR ] \fIlogfile\fR \fIrotationtime\fR|\fIfilesize\fR(B|K|M|G) [ \fIoffset\fR ]\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBrotatelogs\fR is a simple program for use in conjunction with Apache's piped logfile feature\&. It supports rotation based on a time interval or maximum size of the log\&.
     
    
    .SH "OPTIONS"
     
     
    .TP
    \fB-l\fR
    Causes the use of local time rather than GMT as the base for the interval or for \fBstrftime(3)\fR formatting with size-based rotation\&.  
    .TP
    \fB-L\fR \fIlinkname\fR
    .PP Causes a hard link to be made from the current logfile to the specified link name\&. This can be used to watch the log continuously across rotations using a command like \fBtail -F linkname\fR\&. .PP If the linkname is not an absolute path, it is relative to \fBrotatelogs\fR' working directory, which is the ServerRoot when \fBrotatelogs\fR is run by the server\&.  
    .TP
    \fB-p\fR \fIprogram\fR
    If given, \fBrotatelogs\fR will execute the specified program every time a new log file is opened\&. The filename of the newly opened file is passed as the first argument to the program\&. If executing after a rotation, the old log file is passed as the second argument\&. \fBrotatelogs\fR does not wait for the specified program to terminate before continuing to operate, and will not log any error code returned on termination\&. The spawned program uses the same stdin, stdout, and stderr as rotatelogs itself, and also inherits the environment\&.  
    .TP
    \fB-f\fR
    Causes the logfile to be opened immediately, as soon as \fBrotatelogs\fR starts, instead of waiting for the first logfile entry to be read (for non-busy sites, there may be a substantial delay between when the server is started and when the first request is handled, meaning that the associated logfile does not "exist" until then, which causes problems from some automated logging tools)  
    .TP
    \fB-D\fR
    Creates the parent directories of the path that the log file will be placed in if they do not already exist\&. This allows \fBstrftime(3)\fR formatting to be used in the path and not just the filename\&.  
    .TP
    \fB-t\fR
    Causes the logfile to be truncated instead of rotated\&. This is useful when a log is processed in real time by a command like tail, and there is no need for archived data\&. No suffix will be added to the filename, however format strings containing '%' characters will be respected\&.  
    .TP
    \fB-T\fR
    Causes all but the initial logfile to be truncated when opened\&. This is useful when the format string contains something that will loop around, such as the day of the month\&. Available in 2\&.4\&.56 and later\&.  
    .TP
    \fB-v\fR
    Produce verbose output on STDERR\&. The output contains the result of the configuration parsing, and all file open and close actions\&.  
    .TP
    \fB-e\fR
    Echo logs through to stdout\&. Useful when logs need to be further processed in real time by a further tool in the chain\&.  
    .TP
    \fB-c\fR
    Create log file for each interval, even if empty\&.  
    .TP
    \fB-n \fInumber-of-files\fR\fR
    Use a circular list of filenames without timestamps\&. This option overwrites log files at startup and during rotation\&. With -n 3, the series of log files opened would be "logfile", "logfile\&.1", "logfile\&.2", then overwriting "logfile"\&. When this program first opens "logfile", the file will only be truncated if \fB-t\fR is also provided\&. Every subsequent rotation will always begin with truncation of the target file\&. For size based rotation without \fB-t\fR and existing log files in place, this option may result in unintuitive behavior such as initial log entries being sent to "logfile\&.1", and entries in "logfile\&.1" not being preserved even if later "logfile\&.n" have not yet been used\&. Available in 2\&.4\&.5 and later\&.  
    .TP
    \fB\fIlogfile\fR\fR
    .PP The path plus basename of the logfile\&. If \fIlogfile\fR includes any '%' characters, it is treated as a format string for \fBstrftime(3)\fR\&. Otherwise, the suffix \fI\&.nnnnnnnnnn\fR is automatically added and is the time in seconds (unless the -t option is used)\&. Both formats compute the start time from the beginning of the current period\&. For example, if a rotation time of 86400 is specified, the hour, minute, and second fields created from the \fBstrftime(3)\fR format will all be zero, referring to the beginning of the current 24-hour period (midnight)\&. .PP When using \fBstrftime(3)\fR filename formatting, be sure the log file format has enough granularity to produce a different file name each time the logs are rotated\&. Otherwise rotation will overwrite the same file instead of starting a new one\&. For example, if \fIlogfile\fR was \fB/var/log/errorlog\&.%Y-%m-%d\fR with log rotation at 5 megabytes, but 5 megabytes was reached twice in the same day, the same log file name would be produced and log rotation would keep writing to the same file\&. .PP If the logfile is not an absolute path, it is relative to \fBrotatelogs\fR' working directory, which is the ServerRoot when \fBrotatelogs\fR is run by the server\&.  
    .TP
    \fB\fIrotationtime\fR\fR
    The time between log file rotations in seconds\&. The rotation occurs at the beginning of this interval\&. For example, if the rotation time is 3600, the log file will be rotated at the beginning of every hour; if the rotation time is 86400, the log file will be rotated every night at midnight\&. (If no data is logged during an interval, no file will be created\&.)  
    .TP
    \fB\fIfilesize\fR(B|K|M|G)\fR
    The maximum file size in followed by exactly one of the letters \fBB\fR (Bytes), \fBK\fR (KBytes), \fBM\fR (MBytes) or \fBG\fR (GBytes)\&. .PP When time and size are specified, the size must be given after the time\&. Rotation will occur whenever either time or size limits are reached\&.  
    .TP
    \fB\fIoffset\fR\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 \fB-300\fR for this argument\&. In most cases, \fB-l\fR should be used instead of specifying an offset\&.  
     
    .SH "EXAMPLES"
     
    .nf
     
         CustomLog "|bin/rotatelogs /var/log/logfile 86400" common
     
    .fi
     
    .PP
    This creates the files /var/log/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 -l /var/log/logfile\&.%Y\&.%m\&.%d 86400" common
     
    .fi
     
    .PP
    This creates the files /var/log/logfile\&.yyyy\&.mm\&.dd where yyyy is the year, mm is the month, and dd is the day of the month\&. Logging will switch to a new file every day at midnight, local time\&.
     
    .nf
     
         CustomLog "|bin/rotatelogs /var/log/logfile 5M" common
     
    .fi
     
    .PP
    This configuration will rotate the logfile whenever it reaches a size of 5 megabytes\&.
     
    .nf
     
         ErrorLog "|bin/rotatelogs /var/log/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 \fBerrorlog\&.YYYY-mm-dd-HH_MM_SS\fR\&.
     
    .nf
     
         CustomLog "|bin/rotatelogs -t /var/log/logfile 86400" common
     
    .fi
     
    .PP
    This creates the file \fB/var/log/logfile\fR, truncating the file at startup and then truncating the file once per day\&. It is expected in this scenario that a separate process (such as tail) would process the file in real time\&.
     
    .nf
     
         CustomLog "|bin/rotatelogs -T /var/log/logfile\&.%d 86400" common
     
    .fi
     
    .PP
    If the server is started (or restarted) on the first of the month, this appends to \fB/var/log/logfile\&.01\fR\&. When a log entry is written on the second of the month, \fB/var/log/logfile\&.02\fR is truncated and new entries will be added to the top\&. This example keeps approximately 1 months worth of logs without external maintenance\&.
     
    .SH "PORTABILITY"
     
    .PP
    The following logfile format string substitutions should be supported by all \fBstrftime(3)\fR implementations, see the \fBstrftime(3)\fR man page for library-specific extensions\&.
      
    .Ip "\(bu \s-1\fB%A\fR\s0 \- full weekday name (localized)
     
    .Ip "\(bu \s-1\fB%a\fR\s0 \- 3-character weekday name (localized)
     
    .Ip "\(bu \s-1\fB%B\fR\s0 \- full month name (localized)
     
    .Ip "\(bu \s-1\fB%b\fR\s0 \- 3-character month name (localized)
     
    .Ip "\(bu \s-1\fB%c\fR\s0 \- date and time (localized)
     
    .Ip "\(bu \s-1\fB%d\fR\s0 \- 2-digit day of month
     
    .Ip "\(bu \s-1\fB%H\fR\s0 \- 2-digit hour (24 hour clock)
     
    .Ip "\(bu \s-1\fB%I\fR\s0 \- 2-digit hour (12 hour clock)
     
    .Ip "\(bu \s-1\fB%j\fR\s0 \- 3-digit day of year
     
    .Ip "\(bu \s-1\fB%M\fR\s0 \- 2-digit minute
     
    .Ip "\(bu \s-1\fB%m\fR\s0 \- 2-digit month
     
    .Ip "\(bu \s-1\fB%p\fR\s0 \- am/pm of 12 hour clock (localized)
     
    .Ip "\(bu \s-1\fB%S\fR\s0 \- 2-digit second
     
    .Ip "\(bu \s-1\fB%U\fR\s0 \- 2-digit week of year (Sunday first day of week)
     
    .Ip "\(bu \s-1\fB%W\fR\s0 \- 2-digit week of year (Monday first day of week)
     
    .Ip "\(bu \s-1\fB%w\fR\s0 \- 1-digit weekday (Sunday first day of week)
     
    .Ip "\(bu \s-1\fB%X\fR\s0 \- time (localized)
     
    .Ip "\(bu \s-1\fB%x\fR\s0 \- date (localized)
     
    .Ip "\(bu \s-1\fB%Y\fR\s0 \- 4-digit year
     
    .Ip "\(bu \s-1\fB%y\fR\s0 \- 2-digit year
     
    .Ip "\(bu \s-1\fB%Z\fR\s0 \- time zone name
     
    .Ip "\(bu \s-1\fB%%\fR\s0 \- literal `%'
      
    ���������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/ab.1��������������������������������������������������������������������������0000664�0001751�0001751�00000024464�13357447342�015017� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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" 1 "2018-10-10" "Apache HTTP Server" "ab"
    
    .SH NAME
    ab \- Apache HTTP server benchmarking tool
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBab\fR [ -\fBA\fR \fIauth-username\fR:\fIpassword\fR ] [ -\fBb\fR \fIwindowsize\fR ] [ -\fBB\fR \fIlocal-address\fR ] [ -\fBc\fR \fIconcurrency\fR ] [ -\fBC\fR \fIcookie-name\fR=\fIvalue\fR ] [ -\fBd\fR ] [ -\fBe\fR \fIcsv-file\fR ] [ -\fBE\fR \fIclient-certificate file\fR ] [ -\fBf\fR \fIprotocol\fR ] [ -\fBg\fR \fIgnuplot-file\fR ] [ -\fBh\fR ] [ -\fBH\fR \fIcustom-header\fR ] [ -\fBi\fR ] [ -\fBk\fR ] [ -\fBl\fR ] [ -\fBm\fR \fIHTTP-method\fR ] [ -\fBn\fR \fIrequests\fR ] [ -\fBp\fR \fIPOST-file\fR ] [ -\fBP\fR \fIproxy-auth-username\fR:\fIpassword\fR ] [ -\fBq\fR ] [ -\fBr\fR ] [ -\fBs\fR \fItimeout\fR ] [ -\fBS\fR ] [ -\fBt\fR \fItimelimit\fR ] [ -\fBT\fR \fIcontent-type\fR ] [ -\fBu\fR \fIPUT-file\fR ] [ -\fBv\fR \fIverbosity\fR] [ -\fBV\fR ] [ -\fBw\fR ] [ -\fBx\fR \fI<table>-attributes\fR ] [ -\fBX\fR \fIproxy\fR[:\fIport\fR] ] [ -\fBy\fR \fI<tr>-attributes\fR ] [ -\fBz\fR \fI<td>-attributes\fR ] [ -\fBZ\fR \fIciphersuite\fR ] [http[s]://]\fIhostname\fR[:\fIport\fR]/\fIpath\fR\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBab\fR 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
    \fB-A \fIauth-username\fR:\fIpassword\fR\fR
    Supply BASIC Authentication credentials to the server\&. The username and password are separated by a single \fB:\fR 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
    \fB-b \fIwindowsize\fR\fR
    Size of TCP send/receive buffer, in bytes\&.  
    .TP
    \fB-B \fIlocal-address\fR\fR
    Address to bind to when making outgoing connections\&.  
    .TP
    \fB-c \fIconcurrency\fR\fR
    Number of multiple requests to perform at a time\&. Default is one request at a time\&.  
    .TP
    \fB-C \fIcookie-name\fR=\fIvalue\fR\fR
    Add a \fBCookie:\fR line to the request\&. The argument is typically in the form of a \fB\fIname\fR=\fIvalue\fR\fR pair\&. This field is repeatable\&.  
    .TP
    \fB-d\fR
    Do not display the "percentage served within XX [ms] table"\&. (legacy support)\&.  
    .TP
    \fB-e \fIcsv-file\fR\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
    \fB-E \fIclient-certificate-file\fR\fR
    When connecting to an SSL website, use the provided client certificate in PEM format to authenticate with the server\&. The file is expected to contain the client certificate, followed by intermediate certificates, followed by the private key\&. Available in 2\&.4\&.36 and later\&.  
    .TP
    \fB-f \fIprotocol\fR\fR
    Specify SSL/TLS protocol (SSL2, SSL3, TLS1, TLS1\&.1, TLS1\&.2, or ALL)\&. TLS1\&.1 and TLS1\&.2 support available in 2\&.4\&.4 and later\&.  
    .TP
    \fB-g \fIgnuplot-file\fR\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
    \fB-h\fR
    Display usage information\&.  
    .TP
    \fB-H \fIcustom-header\fR\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, \fB"Accept-Encoding: zip/zop;8bit"\fR)\&.  
    .TP
    \fB-i\fR
    Do \fBHEAD\fR requests instead of \fBGET\fR\&.  
    .TP
    \fB-k\fR
    Enable the HTTP KeepAlive feature, \fIi\&.e\&.\fR, perform multiple requests within one HTTP session\&. Default is no KeepAlive\&.  
    .TP
    \fB-l\fR
    Do not report errors if the length of the responses is not constant\&. This can be useful for dynamic pages\&. Available in 2\&.4\&.7 and later\&.  
    .TP
    \fB-m \fIHTTP-method\fR\fR
    Custom HTTP method for the requests\&. Available in 2\&.4\&.10 and later\&.  
    .TP
    \fB-n \fIrequests\fR\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
    \fB-p \fIPOST-file\fR\fR
    File containing data to POST\&. Remember to also set \fB-T\fR\&.  
    .TP
    \fB-P \fIproxy-auth-username\fR:\fIpassword\fR\fR
    Supply BASIC Authentication credentials to a proxy en-route\&. The username and password are separated by a single \fB:\fR 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
    \fB-q\fR
    When processing more than 150 requests, \fBab\fR outputs a progress count on \fBstderr\fR every 10% or 100 requests or so\&. The \fB-q\fR flag will suppress these messages\&.  
    .TP
    \fB-r\fR
    Don't exit on socket receive errors\&.  
    .TP
    \fB-s \fItimeout\fR\fR
    Maximum number of seconds to wait before the socket times out\&. Default is 30 seconds\&. Available in 2\&.4\&.4 and later\&.  
    .TP
    \fB-S\fR
    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
    \fB-t \fItimelimit\fR\fR
    Maximum number of seconds to spend for benchmarking\&. This implies a \fB-n 50000\fR internally\&. Use this to benchmark the server within a fixed total amount of time\&. Per default there is no timelimit\&.  
    .TP
    \fB-T \fIcontent-type\fR\fR
    Content-type header to use for POST/PUT data, eg\&. \fBapplication/x-www-form-urlencoded\fR\&. Default is \fBtext/plain\fR\&.  
    .TP
    \fB-u \fIPUT-file\fR\fR
    File containing data to PUT\&. Remember to also set \fB-T\fR\&.  
    .TP
    \fB-v \fIverbosity\fR\fR
    Set verbosity level - \fB4\fR and above prints information on headers, \fB3\fR and above prints response codes (404, 200, etc\&.), \fB2\fR and above prints warnings and info\&.  
    .TP
    \fB-V\fR
    Display version number and exit\&.  
    .TP
    \fB-w\fR
    Print out results in HTML tables\&. Default table is two columns wide, with a white background\&.  
    .TP
    \fB-x \fI<table>-attributes\fR\fR
    String to use as attributes for \fB<table>\fR\&. Attributes are inserted \fB<table \fIhere\fR >\fR\&.  
    .TP
    \fB-X \fIproxy\fR[:\fIport\fR]\fR
    Use a proxy server for the requests\&.  
    .TP
    \fB-y \fI<tr>-attributes\fR\fR
    String to use as attributes for \fB<tr>\fR\&.  
    .TP
    \fB-z \fI<td>-attributes\fR\fR
    String to use as attributes for \fB<td>\fR\&.  
    .TP
    \fB-Z \fIciphersuite\fR\fR
    Specify SSL/TLS cipher suite (See openssl ciphers)  
     
    .SH "OUTPUT"
     
    .PP
    The following list describes the values returned by \fBab\fR:
     
     
    .TP
    Server Software
    The value, if any, returned in the \fIserver\fR HTTP header of the first successful response\&. This includes all characters in the header from beginning to the point a character with decimal value of 32 (most notably: a space or CR/LF) is detected\&.  
    .TP
    Server Hostname
    The DNS or IP address given on the command line  
    .TP
    Server Port
    The port to which ab is connecting\&. If no port is given on the command line, this will default to 80 for http and 443 for https\&.  
    .TP
    SSL/TLS Protocol
    The protocol parameters negotiated between the client and server\&. This will only be printed if SSL is used\&.  
    .TP
    Document Path
    The request URI parsed from the command line string\&.  
    .TP
    Document Length
    This is the size in bytes of the first successfully returned document\&. If the document length changes during testing, the response is considered an error\&.  
    .TP
    Concurrency Level
    The number of concurrent clients used during the test  
    .TP
    Time taken for tests
    This is the time taken from the moment the first socket connection is created to the moment the last response is received  
    .TP
    Complete requests
    The number of successful responses received  
    .TP
    Failed requests
    The number of requests that were considered a failure\&. If the number is greater than zero, another line will be printed showing the number of requests that failed due to connecting, reading, incorrect content length, or exceptions\&.  
    .TP
    Write errors
    The number of errors that failed during write (broken pipe)\&.  
    .TP
    Non-2xx responses
    The number of responses that were not in the 200 series of response codes\&. If all responses were 200, this field is not printed\&.  
    .TP
    Keep-Alive requests
    The number of connections that resulted in Keep-Alive requests  
    .TP
    Total body sent
    If configured to send data as part of the test, this is the total number of bytes sent during the tests\&. This field is omitted if the test did not include a body to send\&.  
    .TP
    Total transferred
    The total number of bytes received from the server\&. This number is essentially the number of bytes sent over the wire\&.  
    .TP
    HTML transferred
    The total number of document bytes received from the server\&. This number excludes bytes received in HTTP headers  
    .TP
    Requests per second
    This is the number of requests per second\&. This value is the result of dividing the number of requests by the total time taken  
    .TP
    Time per request
    The average time spent per request\&. The first value is calculated with the formula \fBconcurrency * timetaken * 1000 / done\fR while the second value is calculated with the formula \fBtimetaken * 1000 / done\fR  
    .TP
    Transfer rate
    The rate of transfer as calculated by the formula \fBtotalread / 1024 / timetaken\fR  
     
    .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 \fBstrstr(3)\fR shows up top in profile, which might indicate a performance problem; \fIi\&.e\&.\fR, you would measure the \fBab\fR performance rather than the server's\&.
     
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/dbmmanage.1�������������������������������������������������������������������0000664�0001751�0001751�00000013176�14571614732�016344� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2018-07-06" "Apache HTTP Server" "dbmmanage"
    
    .SH NAME
    dbmmanage \- Manage user authentication files in DBM format
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBdbmmanage\fR [ \fIencoding\fR ] \fIfilename\fR add|adduser|check|delete|update \fIusername\fR [ \fIencpasswd\fR [ \fIgroup\fR[,\fIgroup\fR\&.\&.\&.] [ \fIcomment\fR ] ] ]\fR
     
    .PP
    \fB\fBdbmmanage\fR \fIfilename\fR view [ \fIusername\fR ]\fR
     
    .PP
    \fB\fBdbmmanage\fR \fIfilename\fR import\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBdbmmanage\fR 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 \fBdbmmanage\fR\&. This program can only be used when the usernames are stored in a DBM file\&. To use a flat-file database see htpasswd\&.
     
    .PP
    Another tool to maintain a DBM password database is htdbm\&.
     
    .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
    \fB\fIfilename\fR\fR
    The filename of the DBM format file\&. Usually without the extension \fB\&.db\fR, \fB\&.pag\fR, or \fB\&.dir\fR\&.  
    .TP
    \fB\fIusername\fR\fR
    The user for which the operations are performed\&. The \fIusername\fR may not contain a colon (\fB:\fR)\&.  
    .TP
    \fB\fIencpasswd\fR\fR
    This is the already hashed password to use for the \fBupdate\fR and \fBadd\fR commands\&. You may use a hyphen (\fB-\fR) if you want to get prompted for the password, but fill in the fields afterwards\&. Additionally when using the \fBupdate\fR command, a period (\fB\&.\fR) keeps the original password untouched\&.  
    .TP
    \fB\fIgroup\fR\fR
    A group, which the user is member of\&. A groupname may not contain a colon (\fB:\fR)\&. You may use a hyphen (\fB-\fR) if you don't want to assign the user to a group, but fill in the comment field\&. Additionally when using the \fBupdate\fR command, a period (\fB\&.\fR) keeps the original groups untouched\&.  
    .TP
    \fB\fIcomment\fR\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
    \fB-d\fR
    crypt hashing (default, except on Win32, Netware)  
    .TP
    \fB-m\fR
    MD5 hashing (default on Win32, Netware)  
    .TP
    \fB-s\fR
    SHA1 hashing  
    .TP
    \fB-p\fR
    plaintext (\fInot recommended\fR)  
      
    .SS "Commands"
     
     
    .TP
    \fBadd\fR
    Adds an entry for \fIusername\fR to \fIfilename\fR using the hashed password \fIencpasswd\fR\&. dbmmanage passwords\&.dat add rbowen foKntnEF3KSXA  
    .TP
    \fBadduser\fR
    Asks for a password and then adds an entry for \fIusername\fR to \fIfilename\fR\&. dbmmanage passwords\&.dat adduser krietz  
    .TP
    \fBcheck\fR
    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
    \fBdelete\fR
    Deletes the \fIusername\fR entry from \fIfilename\fR\&. dbmmanage passwords\&.dat delete rbowen  
    .TP
    \fBimport\fR
    Reads \fB\fIusername\fR:\fIpassword\fR\fR entries (one per line) from \fBSTDIN\fR and adds them to \fIfilename\fR\&. The passwords already have to be crypted\&.  
    .TP
    \fBupdate\fR
    Same as the \fBadduser\fR command, except that it makes sure \fIusername\fR already exists in \fIfilename\fR\&. dbmmanage passwords\&.dat update rbowen  
    .TP
    \fBview\fR
    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 \fBdbmmanage\fR expects to see\&. \fBdbmmanage\fR 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
    \fBdbmmanage\fR has a list of DBM format preferences, defined by the \fB@AnyDBM::ISA\fR array near the beginning of the program\&. Since we prefer the Berkeley DB 2 file format, the order in which \fBdbmmanage\fR will look for system libraries is Berkeley DB 2, then NDBM, then GDBM and then SDBM\&. The first library found will be the library \fBdbmmanage\fR will attempt to use for all DBM file transactions\&. This ordering is slightly different than the standard \fB@AnyDBM::ISA\fR ordering in Perl, as well as the ordering used by the simple \fBdbmopen()\fR 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 \fBfile\fR program supplied with most Unix systems to see what format a DBM file is in\&.
     
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/htcacheclean.8����������������������������������������������������������������0000664�0001751�0001751�00000014514�13523273316�017032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2019-08-09" "Apache HTTP Server" "htcacheclean"
    
    .SH NAME
    htcacheclean \- Clean up the disk cache
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBhtcacheclean\fR [ -\fBD\fR ] [ -\fBv\fR ] [ -\fBt\fR ] [ -\fBr\fR ] [ -\fBn\fR ] [ -\fBR\fR\fIround\fR ] -\fBp\fR\fIpath\fR [ -\fBl\fR\fIlimit\fR ] [ -\fBL\fR\fIlimit\fR ]\fR
     
    .PP
    \fB\fBhtcacheclean\fR [ -\fBn\fR ] [ -\fBt\fR ] [ -\fBi\fR ] [ -\fBP\fR\fIpidfile\fR ] [ -\fBR\fR\fIround\fR ] -\fBd\fR\fIinterval\fR -\fBp\fR\fIpath\fR [ -\fBl\fR\fIlimit\fR ] [ -\fBL\fR\fIlimit\fR ]\fR
     
    .PP
    \fB\fBhtcacheclean\fR [ -\fBv\fR ] [ -\fBR\fR\fIround\fR ] -\fBp\fR\fIpath\fR [ -\fBa\fR ] [ -\fBA\fR ]\fR
     
    .PP
    \fB\fBhtcacheclean\fR [ -\fBD\fR ] [ -\fBv\fR ] [ -\fBt\fR ] [ -\fBR\fR\fIround\fR ] -\fBp\fR\fIpath\fR \fIurl\fR\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBhtcacheclean\fR is used to keep the size of mod_cache_disk's storage within a given size limit, or limit on inodes in use\&. This tool can run either manually or in daemon mode\&. When running in daemon mode, it sleeps in the background and checks the cache directory at regular intervals for cached content to be removed\&. You can stop the daemon cleanly by sending it a TERM or INT signal\&. When run manually, a once off check of the cache directory is made for cached content to be removed\&. If one or more URLs are specified, each URL will be deleted from the cache, if present\&.
     
    
    .SH "OPTIONS"
     
     
    .TP
    \fB-d\fIinterval\fR\fR
    Daemonize and repeat cache cleaning every \fIinterval\fR minutes\&. This option is mutually exclusive with the \fB-D\fR, \fB-v\fR and \fB-r\fR options\&. To shutdown the daemon cleanly, just send it a \fBSIGTERM\fR or \fBSIGINT\fR\&.  
    .TP
    \fB-D\fR
    Do a dry run and don't delete anything\&. This option is mutually exclusive with the \fB-d\fR option\&. When doing a dry run and deleting directories with \fB-t\fR, the inodes reported deleted in the stats cannot take into account the directories deleted, and will be marked as an estimate\&.  
    .TP
    \fB-v\fR
    Be verbose and print statistics\&. This option is mutually exclusive with the \fB-d\fR option\&.  
    .TP
    \fB-r\fR
    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 \fB-d\fR option and implies the \fB-t\fR option\&.  
    .TP
    \fB-n\fR
    Be nice\&. This causes slower processing in favour of other processes\&. \fBhtcacheclean\fR 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
    \fB-t\fR
    Delete all empty directories\&. By default only cache files are removed, however with some configurations the large number of directories created may require attention\&. If your configuration requires a very large number of directories, to the point that inode or file allocation table exhaustion may become an issue, use of this option is advised\&.  
    .TP
    \fB-p\fIpath\fR\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
    \fB-P\fIpidfile\fR\fR
    Specify \fIpidfile\fR as the name of the file to write the process ID to when daemonized\&.  
    .TP
    \fB-R\fIround\fR\fR
    Specify \fIround\fR as the amount to round sizes up to, to compensate for disk block sizes\&. Set to the block size of the cache partition\&.  
    .TP
    \fB-l\fIlimit\fR\fR
    Specify \fIlimit\fR as the total disk cache size limit\&. The value is expressed in bytes by default (or attaching \fBB\fR to the number)\&. Attach \fBK\fR for Kbytes, \fBM\fR for MBytes or \fBG\fR for Gbytes\&.  
    .TP
    \fB-L\fIlimit\fR\fR
    Specify \fIlimit\fR as the total disk cache inode limit\&. \fBK\fR, \fBM\fR or \fBG\fR suffix can also be used\&.  
    .TP
    \fB-i\fR
    Be intelligent and run only when there was a modification of the disk cache\&. This option is only possible together with the \fB-d\fR option\&.  
    .TP
    \fB-a\fR
    List the URLs currently stored in the cache\&. Variants of the same URL will be listed once for each variant\&.  
    .TP
    \fB-A\fR
    List the URLs currently stored in the cache, along with their attributes in the following order: url, header size, body size, status, entity version, date, expiry, request time, response time, body present, head request\&.  
     
    .SH "DELETING A SPECIFIC URL"
     
    .PP
    If \fBhtcacheclean\fR is passed one or more URLs, each URL will be deleted from the cache\&. If multiple variants of an URL exists, all variants would be deleted\&.
     
    .PP
    When a reverse proxied URL is to be deleted, the effective URL is constructed from the \fBHost\fR header, the \fBport\fR, the \fBpath\fR and the \fBquery\fR\&. Note the '?' in the URL must always be specified explicitly, whether a query string is present or not\&. For example, an attempt to delete the path \fB/\fR from the server \fBlocalhost\fR, the URL to delete would be \fBhttp://localhost:80/?\fR\&.
     
    .SH "LISTING URLS IN THE CACHE"
     
    .PP
    By passing the \fB-a\fR or \fB-A\fR options to \fBhtcacheclean\fR, the URLs within the cache will be listed as they are found, one URL per line\&. The \fB-A\fR option dumps the full cache entry after the URL, with fields in the following order:
     
     
    .TP
    url
    The URL of the entry\&. 
    .TP
    header size
    The size of the header in bytes\&. 
    .TP
    body size
    The size of the body in bytes\&. 
    .TP
    status
    Status of the cached response\&. 
    .TP
    entity version
    The number of times this entry has been revalidated without being deleted\&. 
    .TP
    date
    Date of the response\&. 
    .TP
    expiry
    Expiry date of the response\&. 
    .TP
    request time
    Time of the start of the request\&. 
    .TP
    response time
    Time of the end of the request\&. 
    .TP
    body present
    If 0, no body is stored with this request, 1 otherwise\&. 
    .TP
    head request
    If 1, the entry contains a cached HEAD request with no body, 0 otherwise\&. 
     
    .SH "EXIT STATUS"
     
    .PP
    \fBhtcacheclean\fR returns a zero status ("true") if all operations were successful, \fB1\fR otherwise\&. If an URL is specified, and the URL was cached and successfully removed, \fB0\fR is returned, \fB2\fR otherwise\&. If an error occurred during URL removal, \fB1\fR is returned\&.
     
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/htdbm.1�����������������������������������������������������������������������0000664�0001751�0001751�00000021763�14603014256�015517� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2024-04-02" "Apache HTTP Server" "htdbm"
    
    .SH NAME
    htdbm \- Manipulate DBM password databases
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBhtdbm\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBi\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIfilename\fR \fIusername\fR\fR
     
    .PP
    \fB\fBhtdbm\fR -\fBb\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIfilename\fR \fIusername\fR \fIpassword\fR\fR
     
    .PP
    \fB\fBhtdbm\fR -\fBn\fR [ -\fBi\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIusername\fR\fR
     
    .PP
    \fB\fBhtdbm\fR -\fBnb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIusername\fR \fIpassword\fR\fR
     
    .PP
    \fB\fBhtdbm\fR -\fBv\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBi\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIfilename\fR \fIusername\fR\fR
     
    .PP
    \fB\fBhtdbm\fR -\fBvb\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIfilename\fR \fIusername\fR \fIpassword\fR\fR
     
    .PP
    \fB\fBhtdbm\fR -\fBx\fR [ -\fBT\fR\fIDBTYPE\fR ] \fIfilename\fR \fIusername\fR\fR
     
    .PP
    \fB\fBhtdbm\fR -\fBl\fR [ -\fBT\fR\fIDBTYPE\fR ] \fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBhtdbm\fR is used to manipulate the DBM format files used to store usernames and password for basic authentication of HTTP users via mod_authn_dbm\&. See the dbmmanage documentation for more information about these DBM files\&.
     
    
    .SH "OPTIONS"
     
     
    .TP
    \fB-b\fR
    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\&. For script use see the \fB-i\fR option\&.  
    .TP
    \fB-i\fR
    Read the password from stdin without verification (for script usage)\&.  
    .TP
    \fB-c\fR
    Create the \fIpasswdfile\fR\&. If \fIpasswdfile\fR already exists, it is rewritten and truncated\&. This option cannot be combined with the \fB-n\fR option\&.  
    .TP
    \fB-n\fR
    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 \fB-c\fR option\&.  
    .TP
    \fB-m\fR
    Use MD5 hashing for passwords\&. On Windows and Netware, this is the default\&.  
    .TP
    \fB-B\fR
    Use bcrypt hashing for passwords\&. This is currently considered to be very secure\&.  
    .TP
    \fB-C\fR
    This flag is only allowed in combination with \fB-B\fR (bcrypt hashing)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 31)\&.  
    .TP
    \fB-d\fR
    Use \fBcrypt()\fR hashing for passwords\&. The default on all platforms but Windows and Netware\&. Though possibly supported by \fBhtdbm\fR on all platforms, it is not supported by the httpd server on Windows and Netware\&. This algorithm is \fBinsecure\fR by today's standards\&.  
    .TP
    \fB-s\fR
    Use SHA hashing for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&.  
    .TP
    \fB-p\fR
    Use plaintext passwords\&. Though \fBhtdbm\fR will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&.  
    .TP
    \fB-l\fR
    Print each of the usernames and comments from the database on stdout\&.  
    .TP
    \fB-v\fR
    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
    \fB-x\fR
    Delete user\&. If the username exists in the specified DBM file, it will be deleted\&.  
    .TP
    \fB-t\fR
    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
    \fB\fIfilename\fR\fR
    The filename of the DBM format file\&. Usually without the extension \fB\&.db\fR, \fB\&.pag\fR, or \fB\&.dir\fR\&. If \fB-c\fR is given, the DBM file is created if it does not already exist, or updated if it does exist\&.  
    .TP
    \fB\fIusername\fR\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
    \fB\fIpassword\fR\fR
    The plaintext password to be hashed and stored in the DBM file\&. Used only with the \fB-b\fR flag\&.  
    .TP
    \fB-T\fIDBTYPE\fR\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 \fBhtdbm\fR expects to see\&. \fBhtdbm\fR 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 \fBfile\fR program supplied with most Unix systems to see what format a DBM file is in\&.
     
    .SH "EXIT STATUS"
     
    .PP
    \fBhtdbm\fR returns a zero status ("true") if the username and password have been successfully added or updated in the DBM File\&. \fBhtdbm\fR returns \fB1\fR if it encounters some problem accessing files, \fB2\fR if there was a syntax problem with the command line, \fB3\fR if the password was entered interactively and the verification entry didn't match, \fB4\fR if its operation was interrupted, \fB5\fR if a value is too long (username, filename, password, or final computed record), \fB6\fR if the username contains illegal characters (see the Restrictions section), and \fB7\fR 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 \fBjsmith\fR\&. The user is prompted for the password\&. If executed on a Windows system, the password will be hashed using the modified Apache MD5 algorithm; otherwise, the system's \fBcrypt()\fR routine will be used\&. If the file does not exist, \fBhtdbm\fR 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 \fBjane\fR\&. The user is prompted for the password\&. If the file exists and cannot be read, or cannot be written, it is not altered and \fBhtdbm\fR 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 (\fBPwd4Steve\fR) using the MD5 algorithm, and stores it in the specified file\&.
     
    .SH "SECURITY CONSIDERATIONS"
     
    .PP
    Web password files such as those managed by \fBhtdbm\fR 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 \fB-b\fR option is discouraged, since when it is used the plaintext password appears on the command line\&.
     
    .PP
    When using the \fBcrypt()\fR algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&.
     
    .PP
    The SHA hashing option does not use salting: for a given password, there is only one hashed representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&.
     
    .PP
    The SHA and \fBcrypt()\fR formats are insecure by today's standards\&.
     
    .SH "RESTRICTIONS"
     
    .PP
    On the Windows platform, passwords hashed with \fBhtdbm\fR are limited to no more than \fB255\fR characters in length\&. Longer passwords will be truncated to 255 characters\&.
     
    .PP
    The MD5 algorithm used by \fBhtdbm\fR is specific to the Apache software; passwords hashed using it will not be usable with other Web servers\&.
     
    .PP
    Usernames are limited to \fB255\fR bytes and may not include the character \fB:\fR\&.
     
    �������������httpd-2.4.64/docs/man/fcgistarter.8�����������������������������������������������������������������0000664�0001751�0001751�00000001714�13617567463�016760� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "FCGISTARTER" 8 "2020-02-08" "Apache HTTP Server" "fcgistarter"
    
    .SH NAME
    fcgistarter \- Start a FastCGI program
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBfcgistarter\fR -\fBc\fR \fIcommand\fR -\fBp\fR \fIport\fR [ -\fBi\fR \fIinterface\fR ] -\fBN\fR \fInum\fR \fR
     
    
    .SH "SUMMARY"
     
    .PP
    
     
    
    .SH "NOTE"
     
    .PP
    Currently only works on Unix systems\&.
     
    .SH "OPTIONS"
     
     
    .TP
    \fB-c \fIcommand\fR\fR
    Absolute path of the FastCGI program  
    .TP
    \fB-p \fIport\fR\fR
    Port which the program will listen on  
    .TP
    \fB-i \fIinterface\fR\fR
    Interface which the program will listen on  
    .TP
    \fB-N \fInum\fR\fR
    Number of instances of the program  
     
    ����������������������������������������������������httpd-2.4.64/docs/man/apachectl.8�������������������������������������������������������������������0000664�0001751�0001751�00000010556�13317625777�016373� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2018-07-06" "Apache HTTP Server" "apachectl"
    
    .SH NAME
    apachectl \- Apache HTTP Server Control Interface
    
    .SH "SYNOPSIS"
     
    .PP
    When acting in pass-through mode, \fBapachectl\fR can take all the arguments available for the httpd binary\&.
     
    .PP
    \fB\fBapachectl\fR [ \fIhttpd-argument\fR ]\fR
     
    .PP
    When acting in SysV init mode, \fBapachectl\fR takes simple, one-word commands, defined below\&.
     
    .PP
    \fB\fBapachectl\fR \fIcommand\fR\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBapachectl\fR 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 \fBapachectl\fR 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, \fBapachectl\fR can act as a SysV init script, taking simple one-word arguments like \fBstart\fR, \fBrestart\fR, and \fBstop\fR, and translating them into appropriate signals to httpd\&.
     
    .PP
    If your Apache installation uses non-standard paths, you will need to edit the \fBapachectl\fR 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 \fBapachectl\fR 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
    \fBstart\fR
    Start the Apache httpd daemon\&. Gives an error if it is already running\&. This is equivalent to \fBapachectl -k start\fR\&.  
    .TP
    \fBstop\fR
    Stops the Apache httpd daemon\&. This is equivalent to \fBapachectl -k stop\fR\&.  
    .TP
    \fBrestart\fR
    Restarts the Apache httpd daemon\&. If the daemon is not running, it is started\&. This command automatically checks the configuration files as in \fBconfigtest\fR before initiating the restart to make sure the daemon doesn't die\&. This is equivalent to \fBapachectl -k restart\fR\&.  
    .TP
    \fBfullstatus\fR
    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 \fBlynx\fR available on your system\&. The URL used to access the status report can be set by editing the \fBSTATUSURL\fR variable in the script\&.  
    .TP
    \fBstatus\fR
    Displays a brief status report\&. Similar to the \fBfullstatus\fR option, except that the list of requests currently being served is omitted\&.  
    .TP
    \fBgraceful\fR
    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 \fBconfigtest\fR before initiating the restart to make sure Apache doesn't die\&. This is equivalent to \fBapachectl -k graceful\fR\&.  
    .TP
    \fBgraceful-stop\fR
    Gracefully stops the Apache httpd daemon\&. This differs from a normal stop in that currently open connections are not aborted\&. A side effect is that old log files will not be closed immediately\&. This is equivalent to \fBapachectl -k graceful-stop\fR\&.  
    .TP
    \fBconfigtest\fR
    Run a configuration file syntax test\&. It parses the configuration files and either reports \fBSyntax Ok\fR or detailed information about the particular syntax error\&. This is equivalent to \fBapachectl -t\fR\&.  
     
    .PP
    The following option was available in earlier versions but has been removed\&.
     
     
    .TP
    \fBstartssl\fR
    To start httpd with SSL support, you should edit your configuration file to include the relevant directives and then use the normal \fBapachectl start\fR\&.  
     
    ��������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/logresolve.1������������������������������������������������������������������0000664�0001751�0001751�00000002635�13317625777�016620� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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" 1 "2018-07-06" "Apache HTTP Server" "logresolve"
    
    .SH NAME
    logresolve \- Resolve IP-addresses to hostnames in Apache log files
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBlogresolve\fR [ -\fBs\fR \fIfilename\fR ] [ -\fBc\fR ] < \fIaccess_log\fR > \fIaccess_log\&.new\fR\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBlogresolve\fR 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 separated from the remainder of the line by a space\&.
     
    
    .SH "OPTIONS"
     
     
    .TP
    \fB-s \fIfilename\fR\fR
    Specifies a filename to record statistics\&.  
    .TP
    \fB-c\fR
    This causes \fBlogresolve\fR 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\&.  
     
    ���������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/httpd.8�����������������������������������������������������������������������0000664�0001751�0001751�00000011471�13317625777�015567� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2018-07-06" "Apache HTTP Server" "httpd"
    
    .SH NAME
    httpd \- Apache Hypertext Transfer Protocol Server
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\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|graceful-stop ] [ -\fBh\fR ] [ -\fBl\fR ] [ -\fBL\fR ] [ -\fBS\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBV\fR ] [ -\fBX\fR ] [ -\fBM\fR ] [ -\fBT\fR ] \fR
     
    .PP
    On Windows systems, the following additional arguments are available:
     
    .PP
    \fB\fBhttpd\fR [ -\fBk\fR install|config|uninstall ] [ -\fBn\fR \fIname\fR ] [ -\fBw\fR ]\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBhttpd\fR 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, \fBhttpd\fR 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
    \fB-d \fIserverroot\fR\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 \fB/usr/local/apache2\fR\&.  
    .TP
    \fB-f \fIconfig\fR\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 \fBconf/httpd\&.conf\fR\&.  
    .TP
    \fB-k \fBstart|restart|graceful|stop|graceful-stop\fR\fR
    Signals \fBhttpd\fR to start, restart, or stop\&. See Stopping Apache httpd for more information\&.  
    .TP
    \fB-C \fIdirective\fR\fR
    Process the configuration \fIdirective\fR before reading config files\&.  
    .TP
    \fB-c \fIdirective\fR\fR
    Process the configuration \fIdirective\fR after reading config files\&.  
    .TP
    \fB-D \fIparameter\fR\fR
    Sets a configuration \fIparameter \fRwhich can be used with <IfDefine> sections in the configuration files to conditionally skip or process commands at server startup and restart\&. Also can be used to set certain less-common startup parameters including \fB-DNO_DETACH\fR (prevent the parent from forking) and \fB-DFOREGROUND\fR (prevent the parent from calling \fBsetsid()\fR et al)\&.  
    .TP
    \fB-e \fIlevel\fR\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
    \fB-E \fIfile\fR\fR
    Send error messages during server startup to \fIfile\fR\&.  
    .TP
    \fB-h\fR
    Output a short summary of available command line options\&.  
    .TP
    \fB-l\fR
    Output a list of modules compiled into the server\&. This will \fBnot\fR list dynamically loaded modules included using the LoadModule directive\&.  
    .TP
    \fB-L\fR
    Output a list of directives provided by static modules, together with expected arguments and places where the directive is valid\&. Directives provided by shared modules are not listed\&.  
    .TP
    \fB-M\fR
    Dump a list of loaded Static and Shared Modules\&.  
    .TP
    \fB-S\fR
    Show the settings as parsed from the config file (currently only shows the virtualhost settings)\&.  
    .TP
    \fB-T\fR (Available in 2\&.3\&.8 and later)
    Skip document root check at startup/restart\&.  
    .TP
    \fB-t\fR
    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
    \fB-v\fR
    Print the version of \fBhttpd\fR, and then exit\&.  
    .TP
    \fB-V\fR
    Print the version and build parameters of \fBhttpd\fR, and then exit\&.  
    .TP
    \fB-X\fR
    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
    \fB-k install|config|uninstall\fR
    Install Apache httpd as a Windows NT service; change startup options for the Apache httpd service; and uninstall the Apache httpd service\&.  
    .TP
    \fB-n \fIname\fR\fR
    The \fIname\fR of the Apache httpd service to signal\&.  
    .TP
    \fB-w\fR
    Keep the console window open on error so that the error message can be read\&.  
     
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/htdigest.1��������������������������������������������������������������������0000664�0001751�0001751�00000003636�13317625777�016254� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2018-07-06" "Apache HTTP Server" "htdigest"
    
    .SH NAME
    htdigest \- manage user files for digest authentication
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBhtdigest\fR [ -\fBc\fR ] \fIpasswdfile\fR \fIrealm\fR \fIusername\fR\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBhtdigest\fR 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 \fBhtdigest\fR\&.
     
    .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
    \fB-c\fR
    Create the \fIpasswdfile\fR\&. If \fIpasswdfile\fR already exists, it is deleted first\&.  
    .TP
    \fB\fIpasswdfile\fR\fR
    Name of the file to contain the username, realm and password\&. If \fB-c\fR is given, this file is created if it does not already exist, or deleted and recreated if it does exist\&.  
    .TP
    \fB\fIrealm\fR\fR
    The realm name to which the user name belongs\&. See http://tools\&.ietf\&.org/html/rfc2617#section-3\&.2\&.1 for more details\&.  
    .TP
    \fB\fIusername\fR\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\&.  
     
    .SH "SECURITY CONSIDERATIONS"
     
    .PP
    This program is not safe as a setuid executable\&. Do \fInot\fR make it setuid\&.
     
    ��������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/htpasswd.1��������������������������������������������������������������������0000664�0001751�0001751�00000022615�14603014256�016253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2024-04-02" "Apache HTTP Server" "htpasswd"
    
    .SH NAME
    htpasswd \- Manage user files for basic authentication
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR
     
    .PP
    \fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR
     
    .PP
    \fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR
     
    .PP
    \fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBhtpasswd\fR is used to create and update the flat-files used to store usernames and password for basic authentication of HTTP users\&. If \fBhtpasswd\fR 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 \fBhtpasswd\fR\&. This program can only manage usernames and passwords stored in a flat-file\&. It can hash and display password information for use in other types of data stores, though\&. To use a DBM database see dbmmanage or htdbm\&.
     
    .PP
    \fBhtpasswd\fR hashes passwords using either bcrypt, a version of MD5 modified for Apache, SHA-1, or the system's \fBcrypt()\fR routine\&. SHA-2-based hashes (SHA-256 and SHA-512) are supported for \fBcrypt()\fR\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-hashed passwords while others in the same file may have passwords hashed with \fBcrypt()\fR\&.
     
    .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
    \fB-b\fR
    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\&. For script use see the \fB-i\fR option\&. Available in 2\&.4\&.4 and later\&.  
    .TP
    \fB-i\fR
    Read the password from stdin without verification (for script usage)\&.  
    .TP
    \fB-c\fR
    Create the \fIpasswdfile\fR\&. If \fIpasswdfile\fR already exists, it is rewritten and truncated\&. This option cannot be combined with the \fB-n\fR option\&.  
    .TP
    \fB-n\fR
    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 \fB-c\fR option\&.  
    .TP
    \fB-m\fR
    Use MD5 hashing for passwords\&. This is the default (since version 2\&.2\&.18)\&.  
    .TP
    \fB-2\fR
    Use SHA-256 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&.  
    .TP
    \fB-5\fR
    Use SHA-512 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&.  
    .TP
    \fB-B\fR
    Use bcrypt hashing for passwords\&. This is currently considered to be very secure\&.  
    .TP
    \fB-C\fR
    This flag is only allowed in combination with \fB-B\fR (bcrypt hashing)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 17)\&.  
    .TP
    \fB-r\fR
    This flag is only allowed in combination with \fB-2\fR or \fB-5\fR\&. It sets the number of hash rounds used for the SHA-2 algorithms (higher is more secure but slower; the default is 5,000)\&.  
    .TP
    \fB-d\fR
    Use \fBcrypt()\fR hashing for passwords\&. This is not supported by the httpd server on Windows and Netware\&. This algorithm limits the password length to 8 characters\&. This algorithm is \fBinsecure\fR by today's standards\&. It used to be the default algorithm until version 2\&.2\&.17\&.  
    .TP
    \fB-s\fR
    Use SHA-1 (160-bit) hashing for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&.  
    .TP
    \fB-p\fR
    Use plaintext passwords\&. Though \fBhtpasswd\fR will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&.  
    .TP
    \fB-D\fR
    Delete user\&. If the username exists in the specified htpasswd file, it will be deleted\&.  
    .TP
    \fB-v\fR
    Verify password\&. Verify that the given password matches the password of the user stored in the specified htpasswd file\&. Available in 2\&.4\&.5 and later\&.  
    .TP
    \fB\fIpasswdfile\fR\fR
    Name of the file to contain the user name and password\&. If \fB-c\fR is given, this file is created if it does not already exist, or rewritten and truncated if it does exist\&.  
    .TP
    \fB\fIusername\fR\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
    \fB\fIpassword\fR\fR
    The plaintext password to be hashed and stored in the file\&. Only used with the \fB-b\fR flag\&.  
     
    .SH "EXIT STATUS"
     
    .PP
    \fBhtpasswd\fR returns a zero status ("true") if the username and password have been successfully added or updated in the \fIpasswdfile\fR\&. \fBhtpasswd\fR returns \fB1\fR if it encounters some problem accessing files, \fB2\fR if there was a syntax problem with the command line, \fB3\fR if the password was entered interactively and the verification entry didn't match, \fB4\fR if its operation was interrupted, \fB5\fR if a value is too long (username, filename, password, or final computed record), \fB6\fR if the username contains illegal characters (see the Restrictions section), and \fB7\fR 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 \fBjsmith\fR\&. The user is prompted for the password\&. The password will be hashed using the modified Apache MD5 algorithm\&. If the file does not exist, \fBhtpasswd\fR 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 \fBjane\fR\&. The user is prompted for the password\&. If the file exists and cannot be read, or cannot be written, it is not altered and \fBhtpasswd\fR will display a message and return an error status\&.
     
    .nf
    
          htpasswd -db /usr/web/\&.htpasswd-all jones Pwd4Steve
        
    .fi
     
    .PP
    Encrypts the password from the command line (\fBPwd4Steve\fR) using the \fBcrypt()\fR algorithm, and stores it in the specified file\&.
     
    .SH "SECURITY CONSIDERATIONS"
     
    .PP
    Web password files such as those managed by \fBhtpasswd\fR should \fInot\fR be within the Web server's URI space -- that is, they should not be fetchable with a browser\&.
     
    .PP
    This program is not safe as a setuid executable\&. Do \fInot\fR make it setuid\&.
     
    .PP
    The use of the \fB-b\fR option is discouraged, since when it is used the plaintext password appears on the command line\&.
     
    .PP
    When using the \fBcrypt()\fR algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&.
     
    .PP
    The SHA-1 hashing format does not use salting: for a given password, there is only one hashed representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&.
     
    .PP
    The SHA-1 and \fBcrypt()\fR formats are insecure by today's standards\&.
     
    .PP
    The SHA-2-based \fBcrypt()\fR formats (SHA-256 and SHA-512) are supported on most modern Unix systems, and follow the specification at https://www\&.akkadia\&.org/drepper/SHA-crypt\&.txt\&.
     
    .SH "RESTRICTIONS"
     
    .PP
    On the Windows platform, passwords hashed with \fBhtpasswd\fR are limited to no more than \fB255\fR characters in length\&. Longer passwords will be truncated to 255 characters\&.
     
    .PP
    The MD5 algorithm used by \fBhtpasswd\fR is specific to the Apache software; passwords hashed using it will not be usable with other Web servers\&.
     
    .PP
    Usernames are limited to \fB255\fR bytes and may not include the character \fB:\fR\&.
     
    .PP
    The cost of computing a bcrypt password hash value increases with the number of rounds specified by the \fB-C\fR option\&. The \fBapr-util\fR library enforces a maximum number of rounds of 17 in version \fB1\&.6\&.0\fR and later\&.
     
    �������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/httxt2dbm.1�������������������������������������������������������������������0000664�0001751�0001751�00000003267�13563002277�016344� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "HTTXT2DBM" 1 "2019-11-13" "Apache HTTP Server" "httxt2dbm"
    
    .SH NAME
    httxt2dbm \- Generate dbm files for use with RewriteMap
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBhttxt2dbm\fR [ -\fBv\fR ] [ -\fBf\fR \fIDBM_TYPE\fR ] -\fBi\fR \fISOURCE_TXT\fR -\fBo\fR \fIOUTPUT_DBM\fR \fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBhttxt2dbm\fR is used to generate dbm files from text input, for use in RewriteMap with the \fBdbm\fR map type\&.
     
    .PP
    If the output file already exists, it will not be truncated\&. New keys will be added and existing keys will be updated\&.
     
    
    .SH "OPTIONS"
     
     
    .TP
    \fB-v\fR
    More verbose output  
    .TP
    \fB-f \fIDBM_TYPE\fR\fR
    Specify the DBM type to be used for the output\&. If not specified, will use the APR Default\&. Available types are: \fBGDBM\fR for GDBM files, \fBSDBM\fR for SDBM files, \fBDB\fR for berkeley DB files, \fBNDBM\fR for NDBM files, \fBdefault\fR for the default DBM type\&.  
    .TP
    \fB-i \fISOURCE_TXT\fR\fR
    Input file from which the dbm is to be created\&. The file should be formatted with one record per line, of the form: \fBkey value\fR\&. See the documentation for RewriteMap for further details of this file's format and meaning\&.  
    .TP
    \fB-o \fIOUTPUT_DBM\fR\fR
    Name of the output dbm files\&.  
     
    .SH "EXAMPLES"
     
    .nf
    
          httxt2dbm -i rewritemap\&.txt -o rewritemap\&.dbm
          httxt2dbm -f SDBM -i rewritemap\&.txt -o rewritemap\&.dbm 
    .fi
     
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/apxs.1������������������������������������������������������������������������0000664�0001751�0001751�00000024644�13317625777�015416� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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" 1 "2018-07-06" "Apache HTTP Server" "apxs"
    
    .SH NAME
    apxs \- APache eXtenSion tool
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBapxs\fR -\fBg\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] -\fBn\fR \fImodname\fR\fR
     
    .PP
    \fB\fBapxs\fR -\fBq\fR [ -\fBv\fR ] [ -\fBS\fR \fIname\fR=\fIvalue\fR ] \fIquery\fR \&.\&.\&.\fR
     
    .PP
    \fB\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 \&.\&.\&.\fR
     
    .PP
    \fB\fBapxs\fR -\fBi\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] [ -\fBn\fR \fImodname\fR ] [ -\fBa\fR ] [ -\fBA\fR ] \fIdso-file\fR \&.\&.\&.\fR
     
    .PP
    \fB\fBapxs\fR -\fBe\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] [ -\fBn\fR \fImodname\fR ] [ -\fBa\fR ] [ -\fBA\fR ] \fIdso-file\fR \&.\&.\&.\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBapxs\fR 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 \fBapxs\fR 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 \fBapxs\fR 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 \fBapxs\fR 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 \fB-fpic\fR\&. For other C compilers consult its manual page or at watch for the flags \fBapxs\fR 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 \fBsrc/modules/standard/mod_so\&.c\fR source file\&.
     
    
    .SH "OPTIONS"
     
    .SS "Common Options"
     
     
    .TP
    \fB-n \fImodname\fR\fR
    This explicitly sets the module name for the \fB-i\fR (install) and \fB-g\fR (template generation) option\&. Use this to explicitly specify the module name\&. For option \fB-g\fR this is required, for option \fB-i\fR the \fBapxs\fR 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
    \fB-q\fR
    Performs a query for variables and environment settings used to build \fBhttpd\fR\&. When invoked without \fIquery\fR parameters, it prints all known variables and their values\&. The optional \fB-v\fR parameter formats the list output\&. .PP Use this to manually determine settings used to build the \fBhttpd\fR that will load your module\&. 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
    \fB-S \fIname\fR=\fIvalue\fR\fR
    This option changes the apxs settings described above\&.  
      
    .SS "Template Generation Options"
     
     
    .TP
    \fB-g\fR
    This generates a subdirectory \fIname\fR (see option \fB-n\fR) and there two files: A sample module source file named \fBmod_\fIname\fR\&.c\fR 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 \fBMakefile\fR for even easier build and installing of this module\&.  
      
    .SS "DSO Compilation Options"
     
     
    .TP
    \fB-c\fR
    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 \fB-o\fR option is specified the output file is guessed from the first filename in \fIfiles\fR and thus usually defaults to \fBmod_\fIname\fR\&.so\fR\&.  
    .TP
    \fB-o \fIdsofile\fR\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 \fBmod_unknown\&.so\fR is used\&.  
    .TP
    \fB-D \fIname\fR=\fIvalue\fR\fR
    This option is directly passed through to the compilation command(s)\&. Use this to add your own defines to the build process\&.  
    .TP
    \fB-I \fIincdir\fR\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
    \fB-L \fIlibdir\fR\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
    \fB-l \fIlibname\fR\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
    \fB-Wc,\fIcompiler-flags\fR\fR
    This option passes \fIcompiler-flags\fR as additional flags to the \fBlibtool --mode=compile\fR command\&. Use this to add local compiler-specific options\&.  
    .TP
    \fB-Wl,\fIlinker-flags\fR\fR
    This option passes \fIlinker-flags\fR as additional flags to the \fBlibtool --mode=link\fR command\&. Use this to add local linker-specific options\&.  
    .TP
    \fB-p\fR
    This option causes apxs to link against the apr/apr-util libraries\&. This is useful when compiling helper programs that use the apr/apr-util libraries\&.  
      
    .SS "DSO Installation and Configuration Options"
      
     
    .TP
    \fB-i\fR
    This indicates the installation operation and installs one or more dynamically shared objects into the server's \fImodules\fR directory\&.  
    .TP
    \fB-a\fR
    This activates the module by automatically adding a corresponding LoadModule line to Apache's \fBhttpd\&.conf\fR configuration file, or by enabling it if it already exists\&.  
    .TP
    \fB-A\fR
    Same as option \fB-a\fR but the created LoadModule directive is prefixed with a hash sign (\fB#\fR), \fIi\&.e\&.\fR, the module is just prepared for later activation but initially disabled\&.  
    .TP
    \fB-e\fR
    This indicates the editing operation, which can be used with the \fB-a\fR and \fB-A\fR options similarly to the \fB-i\fR operation to edit Apache's \fBhttpd\&.conf\fR configuration file without attempting to install the module\&.  
      
    .SH "EXAMPLES"
     
    .PP
    Assume you have an Apache module named \fBmod_foo\&.c\fR 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 \fBapxs\fR provides an automatic way to install the shared object in its "modules" directory and updating the \fBhttpd\&.conf\fR 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 \fB-A\fR 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
     
    ��������������������������������������������������������������������������������������������httpd-2.4.64/docs/man/suexec.8����������������������������������������������������������������������0000664�0001751�0001751�00000002434�13317625777�015737� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" 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 "2018-07-06" "Apache HTTP Server" "suexec"
    
    .SH NAME
    suexec \- Switch user before executing external programs
    
    .SH "SYNOPSIS"
     
    .PP
    \fB\fBsuexec\fR -\fBV\fR\fR
     
    
    .SH "SUMMARY"
     
    .PP
    \fBsuexec\fR 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 \fBroot\fR\&. Since the HTTP daemon normally doesn't run as \fBroot\fR, the \fBsuexec\fR executable needs the setuid bit set and must be owned by \fBroot\fR\&. It should never be writable for any other person than \fBroot\fR\&.
     
    .PP
    For further information about the concepts and the security model of suexec please refer to the suexec documentation (http://httpd\&.apache\&.org/docs/2\&.4/suexec\&.html)\&.
     
    
    .SH "OPTIONS"
     
     
    .TP
    \fB-V\fR
    If you are \fBroot\fR, this option displays the compile options of \fBsuexec\fR\&. For security reasons all configuration options are changeable only at compile time\&.  
     
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/server-status/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�016412� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/server-status/feather.png���������������������������������������������������������0000664�0001751�0001751�00000004765�13103401117�020530� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���%���@������	pHYs��������tIME,(I|#P���tEXtComment�Created with GIMPW��	oIDATh{pUk $bPZAgt)iU( u j@ /G<40` r9{s%P73{{}kOr8st`~tN{gunwF\9 &W-T# ۜbFc;7|=_Mӝ/" @DI`ϴkjԿ_qDu)P/.!>*)9Ǯ}Pm_3!ma�8DFD&]>iI	CT55P[`ט.w#;H`A|@)P7(T*6<sDmxdO, VN,z؞ZyXKsD-\�.Pۇwpm-ۂ /4w(5S[Gt#EA<�ۮUZ{Q@fV׼Tks}QG {Ƌ0C9*>Ai#UH|EΗS|s9&�I-e4cc@Q}\3s}@I7r{\o#B0i`1>Ӫ˘޽LVAV=Yx<#1&~NւϿY1UЪkoꉿ/mXV�/y.-!gtւϿ:	1SEmYȡHSDQ{StKUvijgWtow:i@%OYy743:2KP*F<W?ZW<#Cn�H胮$GKuaWXuuψm<,$+>ϊ'ģ.J̜PV[LZKXΗudž
    P7HTިV/
    "a	"^S
    F\;5e_#:æ@s0A%Dda2(梼mjjiƵ.^Ʋ
    ZW%ڰقN*3êb|‚t#)umR`&1)Wuw%*s3o?L7b0$	3Mdz}GϢԀz?&XCT�Ł %~+O`fDSFw|7$cv8=bH㐻P.ʊ-1DAfOgm18A)C)IZ\.ٻy!gk.NJTӏml
    s%&qSnaܠ<ݽS[ =ly8Dg8š
    ^!js
    Tnw7S̵1,XI5
    2z&7kFSigG &8JGFފe!Lx]P >Pd�*BOUOTe&1
    a	`\,8̌0*H{qƙo6C0ՈC{XtÛsJ`	Y;_{?j@jAݽU'W;K&Li*-8ܰR.*ɳA&@R)/|wӰY2R0ţsmoqO�5Eq+X蕯Ѧx'>
    qf?oy;:cP'-3]^I=w4h=@/D5+X+saF馊_Њ68Yrn^dqZ_|߹ΤCphs2vjͭqWn<1c&4~V
    ~@ƴ^41۞ȝ=yVNyJxݘ΂,K3r[o`Qk4s0n۬Sn7aˌ5Nd0i	d:hbG:t%2Gi"iiuZN<y{ LKP011#V=2sI*�'0U~"?؉7ЉF^HQj:Ll#[f.yeȂ$"'K֙FgrC}JgЉpBG	mÝOK̝;}T:F;C	6(�
    '/R`HPtflyX&QoġL+01w\8nZvrُ]=1sNNq@< ?{9uyUS֓r	L=n-^VxWNWΘy?L6ߧvgIE�:>/{;o?jP%Es!: Yp==Qoӎc]'Y"H`?rޣ/bX&ΜvCk+oy
    rݫ9Z����IENDB`�����������httpd-2.4.64/docs/server-status/README.md�����������������������������������������������������������0000664�0001751�0001751�00000003043�13103401117�017647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������server-status
    =============
    
    `mod_lua` version of the Apache httpd's mod_status using dynamic charts
    
    ## What does it do? ##
    This script is an extended version of the known mod_status statistics page for httpd.
    It uses the simple Quokka Chart API to visualize many of the elements that are sometimes hard 
    to properly diagnose using plain text information.
    
    Take a look at https://www.apache.org/server-status to see how it works.
    
    ## Requirements ##
    * Apache httpd 2.4.6 or higher
    * mod_lua (with either Lua 5.1, 5.2 or LuaJIT)
    * mod_status loaded (for enabling traffic statistics)
    
    ## Installing ##
    First, install mod_lua (you can enable this during configure time with --enable-lua)
    
    ### Installing as a handler:
    To install it as a handler, add the following to your httpd.conf in the appropriate VirtualHost:
    
        LuaMapHandler ^/server-status$ /path/to/server-status.lua
        
    ### Installing as a web app:
    To install as a plain web-app, enable .lua scripts to be handled by mod_lua, by adding the following 
    to your appropriate VirtualHost configuration:
    
        AddHandler lua-script .lua
    
    Then just put the `.lua` script somewhere in your document root and visit the page.
    
    ## Configuring
    There are a few options inside the Lua script that can be set to `true` or `false`:
    
    - `show_warning`: Whether or not to show a notice that this page is there on purpose.
    - `redact_ips`: Whether or not to replace the last few bits of every IP with 'x.x'
    - `show_modules`: Whether to show the list of loaded modules or not
    - `show_threads`: Whether to show thread details or not.
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/server-status/server-status.lua���������������������������������������������������0000664�0001751�0001751�00000240652�14037275021�021745� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--[[
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT 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_lua implementation of the server-status page ]]
    local ssversion = "0.11" -- version of this script
    local redact_ips = true -- whether to replace the last two bits of every IP with 'x.x'
    local warning_banner = [[
        <div style="float: left; color: #222; margin-bottom: 8px; margin-top: 24px; text-align: center; width: 200px; font-size: 0.7rem; border: 1px dashed #333; background: #F8C940;">
            <h3 style="margin: 4px; font-size: 1rem;">Don't be alarmed - this page is here for a reason!</h3>
            <p style="font-weight: bolder; font-size: 0.8rem;">This is an example server status page for the Apache HTTP Server. Nothing on this server is secret, no URL tokens, no sensitive passwords. Everything served from here is static data.</p>
        </div>
    ]]
    local show_warning = true -- whether to display the above warning/notice on the page
    local show_modules = false -- Whether to list loaded modules or not
    local show_threads = true -- whether to list thread information or not
    
    -- pre-declare some variables defined at the bottom of this script:
    local status_js, status_css, quokka_js
    
    -- quick and dirty JSON conversion
    local function quickJSON(input)
        if type(input) == "table" then
            local t = 'array'
            for k, v in pairs(input) do
                if type(k) ~= "number" then
                    t = 'hash'
                    break
                end
            end
            
            if t == 'hash' then
                local out = ""
                local tbl = {}
                for k, v in pairs(input) do
                    local kv = ([["%s": %s]]):format(k, quickJSON(v))
                    table.insert(tbl, kv)
                end
                return "{" .. table.concat(tbl, ", ") .. "}"
            else
                local tbl = {}
                for k, v in pairs(input) do
                    table.insert(tbl, quickJSON(v))
                end
                return "[" .. table.concat(tbl, ", ") .. "]"
            end
        elseif type(input) == "string" then
            return ([["%s"]]):format(input:gsub('"', '\\"'):gsub("[\r\n\t]", " "))
        elseif type(input) == "number" then
            return tostring(input)
        elseif type(input) == "boolean" then
            return (input and "true" or "false")
        else
            return "null"
        end
    end
    
    -- Module information callback
    local function modInfo(r, modname)
        if modname then
                r:puts [[
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
            <style>
            ]]
            r:puts (status_css)
            r:puts [[
            </style>
            <title>Module information</title>
          </head>
        
          <body>
        ]]
            r:puts( ("<h3>Details for module %s</h3>\n"):format(r:escape_html(modname)) )
            -- Queries the server for information about a module
            local mod = r.module_info(modname)
            if mod then
                for k, v in pairs(mod.commands) do
                    -- print out all directives accepted by this module
                    r:puts( ("<b>%s:</b> %s<br>\n"):format(r:escape_html(k), v))
                end
            end
            -- HTML tail
            r:puts[[
          </body>
        </html>
        ]]
        end
    end
    
    -- Function for generating server stats
    function getServerState(r, verbose)
        local state = {}
        
        state.mpm = {
            type = "prefork", -- default to prefork until told otherwise
            threadsPerChild = 1,
            threaded = false,
            maxServers = r.mpm_query(12),
            activeServers = 0
        }
        if r.mpm_query(14) == 1 then
            state.mpm.type = "event" -- this is event mpm
        elseif r.mpm_query(3) >= 1 then
            state.mpm.type = "worker" -- it's not event, but it's threaded, we'll assume worker mpm (could be motorz??)
        elseif r.mpm_query(2) == 1 then
            state.mpm.type = "winnt" -- it's threaded, but not worker nor event, so it's probably winnt
        end
        if state.mpm.type ~= "prefork" then
            state.mpm.threaded = true -- it's threaded
            state.mpm.threadsPerChild = r.mpm_query(6) -- get threads per child proc
        end
        
        state.processes = {} -- list of child procs
        state.connections = { -- overall connection info
            idle = 0,
            active = 0
        }
        -- overall server stats
        state.server = {
            connections = 0,
            bytes = 0,
            built = r.server_built,
            localtime = os.time(),
            uptime = os.time() - r.started,
            version = r.banner,
            host = r.server_name,
            modules = nil,
            extended = show_threads, -- whether extended status is available or not
        }
        
        -- if show_modules is true, add list of modules to the JSON
        if show_modules then
            state.server.modules = {}
            for k, module in pairs(r:loaded_modules()) do
                table.insert(state.server.modules, module)
            end
        end
        
        -- Fetch process/thread data
        for i=0,state.mpm.maxServers-1,1 do
            local server = r.scoreboard_process(r, i);
            if server then
                local s = {
                    active = false,
                    pid = nil,
                    bytes = 0,
                    stime = 0,
                    utime = 0,
                    connections = 0,
                }
                local tstates = {}
                if server.pid then
                    state.connections.idle = state.connections.idle + (server.keepalive or 0)
                    s.connections = 0
                    if server.pid > 0 then
                        state.mpm.activeServers = state.mpm.activeServers + 1
                        s.active = true
                        s.pid = server.pid
                    end
                    for j = 0, state.mpm.threadsPerChild-1, 1 do
                        local worker = r.scoreboard_worker(r, i, j)
                        if worker then
                            s.stime = s.stime + (worker.stimes or 0);
                            s.utime = s.utime + (worker.utimes or 0);
                            if verbose and show_threads then
                                s.threads = s.threads or {}
                                table.insert(s.threads, {
                                    bytes = worker.bytes_served,
                                    thread = ("0x%x"):format(worker.tid),
                                    client = redact_ips and (worker.client or "???"):gsub("[a-f0-9]+[.:]+[a-f0-9]+$", "x.x") or worker.client or "???",
                                    cost = ((worker.utimes or 0) + (worker.stimes or 0)),
                                    count = worker.access_count,
                                    vhost = worker.vhost:gsub(":%d+", ""),
                                    request = worker.request,
                                    last_used = math.floor(worker.last_used/1000000)
                                })
                            end
                            state.server.connections = state.server.connections + worker.access_count
                            s.bytes = s.bytes + worker.bytes_served
                            s.connections = s.connections + worker.access_count
                            if server.pid > 0 then
                                tstates[worker.status] = (tstates[worker.status] or 0) + 1
                            end
                        end
                    end
                end
                
                s.workerStates = {
                    keepalive = (server.keepalive > 0) and server.keepalive or tstates[5] or 0,
                    closing = tstates[8] or 0,
                    idle = tstates[2] or 0,
                    writing = tstates[4] or 0,
                    reading = tstates[3] or 0,
                    graceful = tstates[9] or 0
                }
                table.insert(state.processes, s)
                state.server.bytes = state.server.bytes + s.bytes
                state.connections.active = state.connections.active + (tstates[8] or 0) + (tstates[4] or 0) + (tstates[3] or 0)
            end
        end
        return state
    end
    
    -- Handler function
    function handle(r)
        
        -- Parse GET data, if any, and set content type
        local GET = r:parseargs()
        
        if GET['module'] then
            modInfo(r, GET['module'])
            return apache2.OK
        end
    
    
        -- If we only need the stats feed, compact it and hand it over
        if GET['view'] and GET['view'] == "json" then
            local state = getServerState(r, GET['extended'] == 'true')
            r.content_type = "application/json"
            r:puts(quickJSON(state))
            return apache2.OK
        end
        
        if not GET['resource'] then
        
            local state = getServerState(r, show_threads)
            
            -- Print out the HTML for the front page
            r.content_type = "text/html"
            r:puts ( ([=[
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
            <!-- Stylesheet -->
            <link href="?resource=css" rel="stylesheet">
            
            <!-- JavaScript-->
            <script type="text/javascript" src="?resource=js"></script>
            
            <title>Server status for %s</title>
          </head>
        
          <body onload="refreshCharts(false);">
            <div class="wrapper" id="wrapper">
                <div class="navbarLeft">
                    <img align='absmiddle' src='?resource=feather' width="15" height="30"/>
                    Apache HTTPd
                </div>
                <div class="navbarRight">Status for %s on %s</div>
                <div style="clear: both;"></div>
                <div class="serverinfo" id="leftpane">
                    <ul id="menubar">
                        <li>
                            <a class="btn active" id="dashboard_button" href="javascript:void(showPanel('dashboard'));">Dashboard</a>
                        </li>
                        <li>
                            <a class="btn" id="misc_button" href="javascript:void(showPanel('misc'));">Server Info</a>
                        </li>
                        <li>
                            <a class="btn" id="threads_button" style="display: none;" href="javascript:void(showPanel('threads'));">Show thread information</a>
                        </li>
                        <li>
                            <a class="btn" id="modules_button" style="display: none;" href="javascript:void(showPanel('modules'));">Show loaded modules</a>
                        </li>
                    </ul>
                    
                    <!-- warning --> %s <!-- /warning -->
                    
                </div>
                
                <!-- dashboard -->
                <div class="charts" id="dashboard_panel">
                
                    <div class="infobox_wrapper" style="clear: both; width: 100%%;">
                        <div class="infobox_title">Quick Stats</div>
                        <div class="infobox" id="general_stats">
                        </div>
                    </div>
                    <div class="infobox_wrapper" style="width: 100%%;">
                        <div class="infobox_title">Charts</div>
                        <div class="infobox">
                            <!--Div that will hold the pie chart-->
                            <canvas id="actions_div" width="1400" height="400" class="canvas_wide"></canvas>
                            <canvas id="status_div" width=580" height="400" class="canvas_narrow"></canvas>
                            <canvas id="traffic_div" width="1400" height="400" class="canvas_wide"></canvas>
                            <canvas id="idle_div" width="580" height="400" class="canvas_narrow"></canvas>
                            <canvas id="connection_div" width="1400" height="400" class="canvas_wide"></canvas>
                            <canvas id="cpu_div" width="580" height="400" class="canvas_narrow"></canvas>
                            <div style="clear: both"></div>
                        </div>
                    </div>
                </div>
                
                <!-- misc server info -->
                <div class="charts" id="misc_panel" style="display: none;">
                    <div class="infobox_wrapper" style="clear: both; width: 100%%;">
                        <div class="infobox_title">General server information</div>
                        <div class="infobox" style='padding: 16px; width: calc(100%% - 32px);' id="server_breakdown">
                        </div>
                    </div>
                </div>
                
                <!-- thread info -->
                <div class="charts" id="threads_panel" style="display: none;">
                    <div class="infobox_wrapper" style="clear: both; width: 100%%;">
                        <div class="infobox_title">Thread breakdown</div>
                        <div class="infobox" style='padding: 16px; width: calc(100%% - 32px);' id="threads_breakdown">
                        </div>
                    </div>
                </div>
                
                <!-- module info -->
                <div class="charts" id="modules_panel" style="display: none;">
                    <div class="infobox_wrapper" style="clear: both; width: 100%%;">
                        <div class="infobox_title">Modules loaded</div>
                        <div class="infobox" style='padding: 16px; width: calc(100%% - 32px);' id="modules_breakdown">
                        blabla
                        </div>
                    </div>
                </div>
                
                
            </div>
        
        
        ]=]):format(
            r.server_name,
            r.banner,
            r.server_name,
            show_warning and warning_banner or ""
            ) );
            -- HTML tail
            r:puts[[
            </body>
          </html>
          ]]
        else
            -- Resource documents (CSS, JS, PNG)
            if GET['resource'] == 'js' then
                r.content_type = "application/javascript"
                r:puts(quokka_js)
                r:puts(status_js)
            elseif GET['resource'] == 'css' then
                r.content_type = "text/css"
                r:puts(status_css)
            elseif GET['resource'] == 'feather' then
                r.content_type = "image/png"
                r:write(r:base64_decode('iVBORw0KGgoAAAANSUhEUgAAACUAAABACAYAAACdp77qAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QEWECwoSXwjUAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAlvSURBVGje7Zl7cFXVFcZ/a50bHhIRAQWpICSEgGKEUKAUgqKDWsBBHBFndKzYKdAWlWkDAlUEkfIogyAUxfqqdYqP1scg2mq1QLCiIC8LhEeCPDQwoWAgBHLvOXv1j3PvJQRQAjfgH90zmXvu3nv2/u73fWutvU/gHLX9C3IBOLCgc9MDz+S+dGB+l6B0Tu7re2d1bgawd0bn5Fw5F4D+uyCXJsNXs//pzi1U5SMg25zgYkYQY4s76ro3H7/2m8R8PRegmgxfTenTnS8R1SIgG0AERAQR2kma/gFgz7Rrah/UvwdfnpCucUR1KVAvLo4hFj4qiNDz6yk56c3Hrqt9UG3aXxbaw/gz0CHebcBhANE4RKW+RrwW50S+yyavtF0P5T7nH6IfxxCVAWlJCUOmVDXsqzVQW+/PAWDXmC53I9wXO0hgQRh8QClQN7G7KKAEiFTWKqiINuTL/Nzmzsk8c4qL4vkV5kRtjXhkiRKYTyyosCBWTix6gIP+odieWgG1eVi30EtzlhNEvfctkItcAC5QjpTI24d3cP2hbRYt24KW7yCtogQvup80d5SSFpO+KN817pray1NbR3Sbqx4jRUE8ANuunlWKWntRQOy4+Wb201bT17xUa8lz833d+4vKG+JRR9Qg/HvGi8gwEUPU4jkqPgZBy2mrI1XXSKl8G+/60UXOl6nmU8fFwPmCxeQFAumf+O58xQWCc4L5ijkmAKzLz0ktqPW39ghliOk0i+nVzhfMBxdjrQukmfn6gxCQ4Pxj4IJA9vlRferw9O5cM3N96kCt+Uk3ct76hPUDe1xvASNCMIKLaWAxPreAvs4H8wXzBRfTquCey5i96sDevdHj1kyJp1b3657uqbdBlFaSyD0ehepZiXj0EQE8IzEW5ibbD35O1oLPv6q+3lkxVdCqF2tv6om/L21YEJVWxxgAF7PnnS95LhaXLaYhg/HxwGd01oLPv9o6ousJ654xUx+37UXPbctZntHrAo3IoUhT57wGRMQDUXtTlXT16EtVdrzEs/tnh5dX9N10b3c6vPhp6kAlTwJZee8BN+Ph6jQzxOMI6h7ROjJL1FCpKhmIx0Y8rqtXP1qa+fyqk1eEswG0PCPvDkNuFgAf9cvwvQa2SOrog64SJBKyg4GYodjbR0t1YRC1uletWHXKdc+IqaVt8vA8GoAsBbokKz4c8RoFz4onw8SjLkrMnPkSUN8CVltMWksailjOl4e/2XXHhg2pAwVQkJE3SFTeqFYvloryDSIDxWGYCRruIl7SU38N6kaH9Fz5qTvV2jWOvmUZvcNfIzqr+pjDppjJQHPgMEElRGRhMrUo5qK8+G2Aagxqaca19C5exrKM3sMNWlcl2rDZgk6oKoIzw6qKYnz648KCxf/pdCMpA3Vt8VKWtO6djsgUA5yBmWAmBzEpFqFXdXeYJebZKudzM8CesrJvP4/V2EyeN8zgYjCEJBMfCfIzi98Fqh9NgM8Cx7O9txeUfZyZR8+igtSAej/jJpRYuqFDwFQAw8WBua0gvSV+KxAST2Bmu0TEU5VGwHcCqpF8Nxb/AyStY4B2C9A4HA+H7gY9YkjjkLtQLhfKiqAtMfaA/0RBZt7pHadPZ9Litv3pv20xvsk4EUHjsikOQ/IV7ylJWtoQXPIuhdm7ecXLBtTEIaedpxZn9WsuTkpUDMzF049txmyeCnMlDiZx0VPMGW6rwGHn3KDrthfsPN29vlO+11vdEuYg5z1sooTSeTgUH53hRGc4BJfsFwzFoQpetiH7agLotOQbvHMRsxoNVMNudxY3sRgBtlPMtTGR+s4szg4IHsdYE4BJNQ3w0zJ66ybaN8BrGIS3RgJTnGmhE69ngEcgHiaKk/g4SoBHgBRGrd6Kf2X2IaVMAQR4XRWrHxaNUCDMPlBkvAAqQhBPAxr3Vdz4T91U/K6r8WX2uya8mjG4rsENAWHUCYpguxH2gFwsOMyMMCrBiZdIDHtx+saZFPtvle/lNkMw1YhDe1jczAGK73Sow5tzzOBKYAlZBRfKO69f8Xu7P7xqQGpB3b39VQInVzu0rksmTN1pKi0c2jiIgwzwsOSzEhibBxS98/iizAHcsOEdUi6fE++2KrkHzP6kovnJs0GyBiaizspA+gPcUvQOKZcvfHfTsI9ZMveUG1IRoO2rMJewt8Wjc8RtxW8WvZlx6xkfs08ANbZF/nHfK6XeD4+SFljola8C0aaGprl46Cc+DXFm3D+46G+vvJZ5O4OK3zpjUCctM4+3ze+LBR+CXZqmXkk9dzRo6Mo9wc0RoYtAL5FE+TUEK4xY5d0rtXNhRummil+W/cXOFNCKNh31OKbym8VZcm4dXmQRGslxCBVaX3wU37n5zqSXQ3CJaHMy+q6ihR12asvmza30nrMBlLRx9Z7JV4zikR2zmdxu9DwxrhWhY/jWJpjfyB00xX4FVgq8fkDS58a0XoM0/IfF7Iox257InZn5gOQXPXlWwE55Snis3ZjOgiwDSxcMM3IFW4WgDm+XYFEPawQ0EXOFmN0wbtusr1PxbuKU0Tdhy4w1TmSTieKQzwLx+gQa0TD0aQlkOmhi8Nrho0c6Hah0JdMyR6XmnWn1jvyMhyJpaXVaTt08eXsgskyQrghLnOlQFTAxxAwxyh3MFyNWt/4FPR7fMnNJKgCNHPngpScwVX60IhCzluPbP7zYiTfQiUYdXomptkiWFVGcajqio0xs6SNbZi55ZciClLAkIrkngLrwokvEx9aZ6UZncplDyn3TSmfS0InGDKIOqXDIQt/k0ke3/P6DCW1/w52vDk8FS8ydO/vvxxl9VPajEQ86RoQ7wZaJ0UOgsQkHwDYolAD+7wonL6+t/1KMHPlg90i1UHRmbJy+edJYgNEdJo5R828DvcSht0wrnLQwMXdc1jimbp1aG7h2nHLk19mPXZ7f/rEXkgGQPTGPc9ROmRLM006B6PtxQMzcPLEgP3viOQF10uR5/1VTEBgL8taTG8YXco7bCUw90OMZ5m74LQFeVnj7/Z604VdOv/IXV86Yeb72P6mnTL0RvvA236d2Z8dJRQCjOs0+L/t71Tuubz9qUCXR3UWlnxSs2HMhsPGcgzqhIJdZ+R0Vh4/eE3+TcP49lZM9tFEMt2/TjpdjXdv+/LzZJ8nU1Vn3IkgGsBZg5bY/ct6j74utL2JYJtjOnHZDz2ugHZ8SjKYYK9ZveeH7kwpy2t2r/L+dvP0P/Tla8usTzhIAAAAASUVORK5CYII='))
            end
        end
        return apache2.OK;
    end
    
    
    ------------------------------------
    -- JavaScript and CSS definitions --
    ------------------------------------
    
    -- Set up some JavaScripts:
    status_js = [==[
    Number.prototype.pad = function(size) {
        var str = String(this);
        while (str.length < size) {
            str = "0" + str;
        }
        return str;
    }
    
    function getAsync(theUrl, xstate, callback) {
        var xmlHttp = null;
        if (window.XMLHttpRequest) {
    	xmlHttp = new XMLHttpRequest();
        } else {
    	xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlHttp.open("GET", theUrl, true);
        xmlHttp.send(null);
        xmlHttp.onreadystatechange = function(state) {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                if (callback) {
                    callback(JSON.parse(xmlHttp.responseText));
                }
                
            }
        }
    }
    
    var actionCache = [];
    var connectionCache = [];
    var trafficCache = [];
    var processes = {};
    var lastBytes = 0;
    var lastConnections = 0;
    var negativeBytes = 0; // cache for proc reloads, which skews traffic
    var updateSpeed = 5; // How fast do charts update?
    var maxRecords = 24; // How many records to show per chart
    var cpumax = 1000000; // random cpu max(?)
    
    function refreshCharts(json, state) {
        if (json && json.processes) {
            
            
            
             // general server info box
            var gs = document.getElementById('server_breakdown');
            gs.innerHTML = "";
            gs.innerHTML += "<b>Server version: </b>" + json.server.version + "<br/>";
            gs.innerHTML += "<b>Server built: </b>" + json.server.built + "<br/>";
            gs.innerHTML += "<b>Server MPM: </b>" + json.mpm.type + " <span id='mpminfo'></span><br/>";
            
            
            // Get a timestamp
            var now = new Date();
            var ts = now.getHours().pad(2) + ":" + now.getMinutes().pad(2) + ":" + now.getSeconds().pad(2);
            
            var utime = 0;
            var stime = 0;
            
            // Construct state based on proc details
            var state = {
                timestamp: ts,
                closing: 0,
                idle: 0,
                writing: 0,
                reading: 0,
                keepalive: 0,
                graceful: 0
            }
            for (var i in json.processes) {
                var proc = json.processes[i];
                if (proc.pid) {
                    state.closing += proc.workerStates.closing||0;
                    state.idle += proc.workerStates.idle||0;
                    state.writing += proc.workerStates.writing||0;
                    state.reading += proc.workerStates.reading||0;
                    state.keepalive += proc.workerStates.keepalive||0;
                    state.graceful += proc.workerStates.graceful||0;
                    utime += proc.utime;
                    stime += proc.stime;
                }
            }
            
            // Push action state entry into action cache with timestamp
            // Shift if more than 10 entries in cache
            actionCache.push(state);
            if (actionCache.length > maxRecords) {
                actionCache.shift();
            }
            
            // construct array for QuokkaLines
            var arr = [];
            for (var i in actionCache) {
                var el = actionCache[i];
                if (json.mpm.type == 'event') {
                arr.push([el.timestamp, el.closing, el.idle, el.writing, el.reading, el.graceful]);
                } else {
                    arr.push([el.timestamp, el.keepalive, el.closing, el.idle, el.writing, el.reading, el.graceful]);
                }
            }
            var states = ['Keepalive', 'Closing', 'Idle', 'Writing', 'Reading', 'Graceful']
            if (json.mpm.type == 'event') {
                states.shift();
                if (document.getElementById('mpminfo')) {
                    document.getElementById('mpminfo').innerHTML = "(" + fn(parseInt(json.connections.idle)) + " connections in idle keepalive)";
                }
            }
            // Draw action chart
            quokkaLines("actions_div", states, arr, { lastsum: true, hires: true, nosum: true, stack: true, curve: true, title: "Thread states" } );
            
            
            // Get traffic, figure out how much it was this time (0 if just started!)
            var bytesThisTurn = 0;
            var connectionsThisTurn = 0;
            for (var i in json.processes) {
                var proc = json.processes[i];
                var pid = proc.pid
                // if we haven't seen this proc before, ignore its bytes first time
                if (!processes[pid]) {
                    processes[pid] = {
                        bytes: proc.bytes,
                        connections: proc.connections,
                    }
                } else {
                    bytesThisTurn += proc.bytes - processes[pid].bytes;
                    if (pid) {
                        x = proc.connections - processes[pid].connections;
                        connectionsThisTurn += (x > 0) ? x : 0;
                    }
                    processes[pid].bytes = proc.bytes;
                    processes[pid].connections = proc.connections;
                }
            }
            
            if (lastBytes == 0 ) {
                bytesThisTurn = 0;
            }
            lastBytes = 1;
    
            // Push a new element into cache, prune cache
            var el = {
                timestamp: ts,
                bytes: bytesThisTurn/updateSpeed
            };
            trafficCache.push(el);
            if (trafficCache.length > maxRecords) {
                trafficCache.shift();
            }
            
            // construct array for QuokkaLines
            arr = [];
            for (var i in trafficCache) {
                var el = trafficCache[i];
                arr.push([el.timestamp, el.bytes]);
            }
            // Draw action chart
            quokkaLines("traffic_div", ['Traffic'], arr, { traffic: true, hires: true, nosum: true, stack: true, curve: true, title: "Traffic per second" } );
            
            
            // Get connections per second
            // Push a new element into cache, prune cache
            var el = {
                timestamp: ts,
                connections: (connectionsThisTurn+1)/updateSpeed
            };
            connectionCache.push(el);
            if (connectionCache.length > maxRecords) {
                connectionCache.shift();
            }
            
            // construct array for QuokkaLines
            arr = [];
            for (var i in connectionCache) {
                var el = connectionCache[i];
                arr.push([el.timestamp, el.connections]);
            }
            // Draw connection chart
            quokkaLines("connection_div", ['Connections/sec'], arr, { traffic: false, hires: true, nosum: true, stack: true, curve: true, title: "Connections per second" } );
            
            
            // Thread info
            quokkaCircle("status_div", [
            { title: 'Active', value: (json.mpm.threadsPerChild*json.mpm.activeServers)},
            { title: 'Reserve', value: (json.mpm.threadsPerChild*(json.mpm.activeServers-json.mpm.maxServers))}
            ],
                { title: "Worker pool", hires: true});
            
            // Idle vs active connections
            var idlecons = json.connections.idle;
            var activecons = json.connections.active;
            quokkaCircle("idle_div", [
                { title: 'Idle', value: idlecons},
                { title: 'Active', value: activecons},
                ],
                { hires: true, title: "Idle vs active connections"});
            
            
            // CPU info
            while ( (stime+utime) > cpumax ) {
                cpumax = cpumax * 2;
            }
    
            quokkaCircle("cpu_div", [
                { title: 'Idle', value: (cpumax - stime - utime) / (cpumax/100)},
                { title: 'System', value: stime/(cpumax/100)},
                { title: 'User', value: utime/(cpumax/100)}
                ],
                { hires: true, title: "CPU usage", pct: true});
            
            
            
            
            
            
            // General stats infobox
            var gstats = document.getElementById('general_stats');
            gstats.innerHTML = ''; // wipe the box
            
                // Days since restart
                var u_f = Math.floor(json.server.uptime/8640.0) / 10;
                var u_d = Math.floor(json.server.uptime/86400);
                var u_h = Math.floor((json.server.uptime%86400)/3600);
                var u_m = Math.floor((json.server.uptime%3600)/60);
                var u_s = Math.floor(json.server.uptime %60);
                var str =  u_d + " day" + (u_d != 1 ? "s, " : ", ") + u_h + " hour" + (u_h != 1 ? "s, " : ", ") + u_m + " minute" + (u_m != 1 ? "s" : "");
                var ubox = document.createElement('div');
                ubox.setAttribute("class", "statsbox");
                ubox.innerHTML = "<span style='font-size: 2rem;'>" + u_f + " days</span><br/><i>since last (re)start.</i><br/><small>" + str;
                gstats.appendChild(ubox);
                
                
                // Bytes transferred in total
                var MB = fnmb(json.server.bytes);
                var KB = (json.server.bytes > 0) ? fnmb(json.server.bytes/json.server.connections) : 0;
                var KBs = fnmb(json.server.bytes/json.server.uptime);
                var mbbox = document.createElement('div');
                mbbox.setAttribute("class", "statsbox");
                mbbox.innerHTML = "<span style='font-size: 2rem;'>" + MB + "</span><br/><i>transferred in total.</i><br/><small>" + KBs + "/sec, " + KB + "/request";
                gstats.appendChild(mbbox);
                
                // connections in total
                var cons = fn(json.server.connections);
                var cps = Math.floor(json.server.connections/json.server.uptime*100)/100;
                var conbox = document.createElement('div');
                conbox.setAttribute("class", "statsbox");
                conbox.innerHTML = "<span style='font-size: 2rem;'>" + cons + " conns</span><br/><i>since server started.</i><br/><small>" + cps + " requests per second";
                gstats.appendChild(conbox);
                
                // threads working
                var tpc = json.mpm.threadsPerChild;
                var activeThreads = fn(json.mpm.activeServers * json.mpm.threadsPerChild);
                var maxThreads = json.mpm.maxServers * json.mpm.threadsPerChild;
                var tbox = document.createElement('div');
                tbox.setAttribute("class", "statsbox");
                tbox.innerHTML = "<span style='font-size: 2rem;'>" + activeThreads + " threads</span><br/><i>currently at work (" + json.mpm.activeServers + "x" + tpc+" threads).</i><br/><small>" + maxThreads + " (" + json.mpm.maxServers + "x"+tpc+") threads allowed.";
                gstats.appendChild(tbox);
            
            
            
            window.setTimeout(waitTwo, updateSpeed*1000);
            
            // resize pane
            document.getElementById('leftpane').style.height = document.getElementById('wrapper').getBoundingClientRect().height + "px";
            
            // Do we have extended info and module lists??
            if (json.server.extended) document.getElementById('threads_button').style.display = 'block';
            if (json.server.modules && json.server.modules.length > 0) {
                var panel = document.getElementById('modules_breakdown');
                var list = "<ul>";
                for (var i in json.server.modules) {
                    var mod = json.server.modules[i];
                    list += "<li>" + mod + "</li>";
                }
                list += "</ul>";
                panel.innerHTML = list;
                
                document.getElementById('modules_button').style.display = 'block';
            }
           
            
        } else if (json === false) {
            waitTwo();
        }
    }
    
    function refreshThreads(json, state) {
        var box = document.getElementById('threads_breakdown');
        box.innerHTML = "";
        for (var i in json.processes) {
            var proc = json.processes[i];
            var phtml = '<div style="color: #DDF">';
            if (!proc.active) phtml = '<div title="this process is inactive" style="color: #999;">';
            phtml += "<h3>Process " + i + ":</h3>";
            phtml += "<b>PID:</b> " + (proc.pid||"None (not active)") + "<br/>";
            if (proc.threads && proc.active) {
                phtml += "<table style='width: 800px; color: #000;'><tr><th>Thread ID</th><th>Access count</th><th>Bytes served</th><th>Last Used</th><th>Last client</th><th>Last request</th></tr>";
                for (var j in proc.threads) {
                    var thread = proc.threads[j];
                    thread.request = (thread.request||"(Unknown)").replace(/[<>]+/g, "");
                    phtml += "<tr><td>"+thread.thread+"</td><td>"+thread.count+"</td><td>"+thread.bytes+"</td><td>"+thread.last_used+"</td><td>"+thread.client+"</td><td>"+thread.request+"</td></tr>";
                }
                phtml += "</table>";
            } else {
                phtml += "<p>No thread information available</p>";
            }
            phtml += "</div>";
            box.innerHTML += phtml;
        }
    }
    
    function waitTwo() {
        getAsync(location.href + "?view=json&rnd=" + Math.random(), null, refreshCharts)
    }
    
        function showPanel(what) {
            var items = ['dashboard','misc','threads','modules'];
            for (var i in items) {
                var item = items[i];
                var btn = document.getElementById(item+'_button');
                var panel = document.getElementById(item+'_panel');
                if (item == what) {
                    btn.setAttribute("class", "btn active");
                    panel.style.display = 'block';
                } else {
                    btn.setAttribute("class", "btn");
                    panel.style.display = 'none';
                }
            }
            
            // special constructors
            if (what == 'threads') {
                getAsync(location.href + "?view=json&extended=true&rnd=" + Math.random(), null, refreshThreads)
            }
        }
        
        function fn(num) {
            num = num + "";
            num = num.replace(/(\d)(\d{9})$/, '$1,$2');
            num = num.replace(/(\d)(\d{6})$/, '$1,$2');
            num = num.replace(/(\d)(\d{3})$/, '$1,$2');
            return num;
        }
    
        function fnmb(num) {
            var add = "bytes";
            var dec = "";
            var mul = 1;
            if (num > 1024) { add = "KB"; mul= 1024; }
            if (num > (1024*1024)) { add = "MB"; mul= 1024*1024; }
            if (num > (1024*1024*1024)) { add = "GB"; mul= 1024*1024*1024; }
            if (num > (1024*1024*1024*1024)) { add = "TB"; mul= 1024*1024*1024*1024; }
            num = num / mul;
            if (add != "bytes") {
                dec = "." + Math.floor( (num - Math.floor(num)) * 100 );
            }
            return ( fn(Math.floor(num)) + dec + " " + add );
        }
    
        function sort(a,b){
            last_col = -1;
            var sort_reverse = false;
            var sortWay = a.getAttribute("sort_" + b);
            if (sortWay && sortWay == "forward") {
                a.setAttribute("sort_" + b, "reverse");
                sort_reverse = true;
            }
            else {
                a.setAttribute("sort_" + b, "forward");
            }
            var c,d,e,f,g,h,i;
            c=a.rows.length;
            if(c<1){ return; }
            d=a.rows[1].cells.length;
            e=1;
            var j=new Array(c);
            f=0;
            for(h=e;h<c;h++){
                var k=new Array(d);
                for(i=0;i<d;i++){
                    cell_text="";
                    cell_text=a.rows[h].cells[i].textContent;
                    if(cell_text===undefined){cell_text=a.rows[h].cells[i].innerText;}
                    k[i]=cell_text;
                }
                j[f++]=k;
            }
            var l=false;
            var m,n;
            if(b!=lastcol) lastseq="A";
            else{
                if(lastseq=="A") lastseq="D";
                lastseq="A";
            }
    
            g=c-1;
    
            for(h=0;h<g;h++){
                l=false;
                for(i=0;i<g-1;i++){
                    m=j[i];
                    n=j[i+1];
                    if(lastseq=="A"){
                        var gt = (m[b]>n[b]) ? true : false;
                        var lt = (m[b]<n[b]) ? true : false;
                        if (n[b].match(/^(\d+)$/)) { gt = parseInt(m[b], 10) > parseInt(n[b], 10) ? true : false; lt = parseInt(m[b], 10) < parseInt(n[b], 10) ? true : false; }
                        if (sort_reverse) {gt = (!gt); lt = (!lt);}
                        if(gt){
                            j[i+1]=m;
                            j[i]=n;
                            l=true;
                        }
                    }
                    else{
                        if(lt){
                            j[i+1]=m;
                            j[i]=n;
                            l=true;
                        }
                    }
                }
                if(l===false){
                    break;
                }
            }
            f=e;
            for(h=0;h<g;h++){
                m=j[h];
                for(i=0;i<d;i++){
                    if(a.rows[f].cells[i].innerText!==undefined){
                        a.rows[f].cells[i].innerText=m[i];
                    }
                    else{
                        a.rows[f].cells[i].textContent=m[i];
                    }
                }
                f++;
            }
            lastcol=b;
        }
    
        
        var CPUmax =            1000000;
        
        
        var showing = false;
        function showDetails() {
            for (i=1; i < 1000; i++) {
                var obj = document.getElementById("srv_" + i);
                if (obj) {
                    if (showing) { obj.style.display = "none"; }
                    else { obj.style.display = "block"; }
                }
            }
            var link = document.getElementById("show_link");
            showing = (!showing);
            if (showing) { link.innerHTML = "Hide thread information"; }
            else { link.innerHTML = "Show thread information"; }
        }
    
        var showing_modules = false;
        function show_modules() {
    
            var obj = document.getElementById("modules");
            if (obj) {
                if (showing_modules) { obj.style.display = "none"; }
                else { obj.style.display = "block"; }
            }
            var link = document.getElementById("show_modules_link");
            showing_modules = (!showing_modules);
            if (showing_modules) { link.innerHTML = "Hide loaded modules"; }
            else { link.innerHTML = "Show loaded modules"; }
        }
    ]==]
    
    quokka_js = [==[
    /*
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     *     http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    // Traffic shaper
    function quokka_fnmb(num) {
        var add = "b";
        var dec = "";
        var mul = 1;
        if (num > 1024) { add = "KB"; mul= 1024; }
        if (num > (1024*1024)) { add = "MB"; mul= 1024*1024; }
        if (num > (1024*1024*1024)) { add = "GB"; mul= 1024*1024*1024; }
        if (num > (1024*1024*1024*1024)) { add = "TB"; mul= 1024*1024*1024*1024; }
        num = num / mul;
        if (add != "b" && num < 10) {
            dec = "." + Math.floor( (num - Math.floor(num)) * 100 );
        }
        return ( Math.floor(num) + dec + " " + add );
    }
    
    // Hue, Saturation and Lightness to Red, Green and Blue:
    function quokka_internal_hsl2rgb (h,s,l)
    {
        var min, sv, switcher, fract, vsf;
        h = h % 1;
        if (s > 1) s = 1;
        if (l > 1) l = 1;
        var v = (l <= 0.5) ? (l * (1 + s)) : (l + s - l * s);
        if (v === 0)
            return { r: 0, g: 0, b: 0 };
    
        min = 2 * l - v;
        sv = (v - min) / v;
        var sh = (6 * h) % 6;
        switcher = Math.floor(sh);
        fract = sh - switcher;
        vsf = v * sv * fract;
    
        switch (switcher)
        {
            case 0: return { r: v, g: min + vsf, b: min };
            case 1: return { r: v - vsf, g: v, b: min };
            case 2: return { r: min, g: v, b: min + vsf };
            case 3: return { r: min, g: v - vsf, b: v };
            case 4: return { r: min + vsf, g: min, b: v };
            case 5: return { r: v, g: min, b: v - vsf };
        }
        return {r:0, g:0, b: 0};
    }
    
    // RGB to Hex conversion
    function quokka_internal_rgb2hex(r, g, b) {
        return "#" + ((1 << 24) + (Math.floor(r) << 16) + (Math.floor(g) << 8) + Math.floor(b)).toString(16).slice(1);
    }
    
    
    // Generate color list used for charts
    var colors = [];
    var rgbs = []
    var numColorRows = 6;
    var numColorColumns = 20;
    for (var x=0;x<numColorRows;x++) {
        for (var y=0;y<numColorColumns;y++) {
            var rnd = [[148, 221, 119], [0, 203, 171], [51, 167, 215] , [35, 160, 253], [218, 54, 188], [16, 171, 246], [110, 68, 206], [21, 49, 248], [142, 104, 210]][y]
            var color = quokka_internal_hsl2rgb(y > 8 ? (Math.random()) : (rnd[0]/255), y > 8 ? (0.75+(y*0.05)) : (rnd[1]/255), y > 8 ? (0.42 + (y*0.05*(x/numColorRows))) : (0.1 + rnd[2]/512));
            
            // Light (primary) color:
            var hex = quokka_internal_rgb2hex(color.r*255, color.g*255, color.b*255);
            
            // Darker variant for gradients:
            var dhex = quokka_internal_rgb2hex(color.r*131, color.g*131, color.b*131);
            
            // Medium variant for legends:
            var mhex = quokka_internal_rgb2hex(color.r*200, color.g*200, color.b*200);
            
            colors.push([hex, dhex, color, mhex]);
        }
    }
    
    
    /* Function for drawing pie diagrams
     * Example usage:
     * quokkaCircle("canvasName", [ { title: 'ups', value: 30}, { title: 'downs', value: 70} ] );
     */
    
    function quokkaCircle(id, tags, opts) {
        // Get Canvas object and context
        var canvas = document.getElementById(id);
        var ctx=canvas.getContext("2d");
        
        // Calculate the total value of the pie
        var total = 0;
        var k;
        for (k in tags) {
            tags[k].value = Math.abs(tags[k].value);
            total += tags[k].value;
        }
        
        
        
        // Draw the empty pie
        var begin = 0;
        var stop = 0;
        var radius = (canvas.height*0.75)/2;
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.beginPath();
        ctx.shadowBlur = 6;
        ctx.shadowOffsetX = 6;
        ctx.shadowOffsetY = 6;
        ctx.shadowColor = "#555";
        ctx.lineWidth = (opts && opts.hires) ? 6 : 2;
        ctx.strokeStyle = "#222";
        ctx.arc((canvas.width-140)/2,canvas.height/2,radius, 0, Math.PI * 2);
        ctx.closePath();
        ctx.stroke();
        ctx.fill();
        ctx.shadowBlur = 0;
        ctx.shadowOffsetY = 0;
        ctx.shadowOffsetX = 0;
        
        
        // Draw a title if set:
        if (opts && opts.title) {
            ctx.font= (opts && opts.hires) ? "28px Sans-Serif" : "15px Sans-Serif";
            ctx.fillStyle = "#000000";
            ctx.textAlign = "center";
            ctx.fillText(opts.title,(canvas.width-140)/2, (opts && opts.hires) ? 30:15);
            ctx.textAlign = "left";
        }
        
        ctx.beginPath();
        var posY = 50;
        var left = 120 + ((canvas.width-140)/2) + ((opts && opts.hires) ? 40 : 25)
        for (k in tags) {
            var val = tags[k].value;
            stop = stop + (2 * Math.PI * (val / total));
            
            // Make a pizza slice
            ctx.beginPath();
            ctx.lineCap = 'round';
            ctx.arc((canvas.width-140)/2,canvas.height/2,radius,begin,stop);
            ctx.lineTo((canvas.width-140)/2,canvas.height/2);
            ctx.closePath();
            ctx.lineWidth = 0;
            ctx.stroke();
            
            // Add color gradient
            var grd=ctx.createLinearGradient(0,canvas.height*0.2,0,canvas.height);
            grd.addColorStop(0,colors[k % colors.length][1]);
            grd.addColorStop(1,colors[k % colors.length][0]);
            ctx.fillStyle = grd;
            ctx.fill();
            begin = stop;
            
            // Make color legend
            ctx.fillRect(left, posY-((opts && opts.hires) ? 15 : 10), (opts && opts.hires) ? 14 : 7, (opts && opts.hires) ? 14 : 7);
            
            // Add legend text
            ctx.shadowColor = "rgba(0,0,0,0)"
            ctx.font= (opts && opts.hires) ? "22px Sans-Serif" : "12px Sans-Serif";
            ctx.fillStyle = "#000";
            ctx.fillText(tags[k].title + " (" + Math.floor(val) + (opts && opts.pct ? "%" : "") + ")",left+20,posY);
            
            posY += (opts && opts.hires) ? 28 : 14;
        }
        
    }
    
    
    /* Function for drawing line charts
     * Example usage:
     * quokkaLines("myCanvas", ['Line a', 'Line b', 'Line c'], [ [x1,a1,b1,c1], [x2,a2,b2,c2], [x3,a3,b3,c3] ], { stacked: true, curve: false, title: "Some title" } );
     */
    function quokkaLines(id, titles, values, options, sums) {
        var canvas = document.getElementById(id);
        var ctx=canvas.getContext("2d");
        // clear the canvas first
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        
    
    
        ctx.lineWidth = 0.25;
        ctx.strokeStyle = "#000000";
        
        var lwidth = 300;
        var lheight = 75;
        wspace = (options && options.hires) ? 110 : 55;
        var rectwidth = canvas.width - lwidth - wspace;
        var stack = options ? options.stack : false;
        var curve = options ? options.curve : false;
        var title = options ? options.title : null;
        var spots = options ? options.points : false;
        var noX = options ? options.nox : false;
        var verts = options ? options.verts : true;
        if (noX) {
            lheight = 0;
        }
        
        
        // calc rectwidth if titles are large
        var nlwidth = 0
        for (var k in titles) {
            ctx.font= (options && options.hires) ? "24px Sans-Serif" : "12px Sans-Serif";
            ctx.fillStyle = "#00000";
            var x = parseInt(k)
            if (!noX) {
                x = x + 1;
            }
            var sum = 0
            for (var y in values) {
                sum += values[y][x]
            }
            var t = titles[k] + (!options.nosum ? " (" + ((sums && sums[k]) ? sums[k] : sum.toFixed(0)) + ")" : "");
            var w = ctx.measureText(t).width + 48;
            if (w > lwidth && w > nlwidth) {
                nlwidth = w
            }
            if (nlwidth > 0) {
                rectwidth -= nlwidth - lwidth
                lwidth = nlwidth
            }
        }
        
        // Draw a border
        ctx.lineWidth = 0.5;
        ctx.strokeRect((wspace*0.75), 30, rectwidth, canvas.height - lheight - 40);
        
        // Draw a title if set:
        if (title != null) {
            ctx.font= (options && options.hires) ? "24px Sans-Serif" : "15px Sans-Serif";
            ctx.fillStyle = "#00000";
            ctx.textAlign = "center";
            ctx.fillText(title,rectwidth/2, 20);
        }
        
        // Draw legend
        ctx.textAlign = "left";
        var posY = 50;
        for (var k in titles) {
            var x = parseInt(k)
            if (!noX) {
                x = x + 1;
            }
            var sum = 0
            for (var y in values) {
                sum += values[y][x]
            }
            
            var title = titles[k] + (!options.nosum ? (" (" + ((sums && sums[k]) ? sums[k] : sum.toFixed(0)) + ")") : "");
            if (options && options.lastsum) {
                title = titles[k] + " (" + values[values.length-1][x].toFixed(0) + ")";
            }
            ctx.fillStyle = colors[k % colors.length][3];
            ctx.fillRect(wspace + rectwidth + 75 , posY-((options && options.hires) ? 18:9), (options && options.hires) ? 20:10, (options && options.hires) ?20:10);
            
            // Add legend text
            ctx.font= (options && options.hires) ? "24px Sans-Serif" : "14px Sans-Serif";
            ctx.fillStyle = "#00000";
            ctx.fillText(title,canvas.width - lwidth + ((options && options.hires) ? 100:60), posY);
            
            posY += (options && options.hires) ? 30:15;
        }
        
        // Find max and min
        var max = null;
        var min = 0;
        var stacked = null;
        for (x in values) {
            var s = 0;
            for (y in values[x]) {
                if (y > 0 || noX) {
                    s += values[x][y];
                    if (max === null || max < values[x][y]) {
                        max = values[x][y];
                    }
                    if (min === null || min > values[x][y]) {
                        min = values[x][y];
                    }
                }
            }
            if (stacked === null || stacked < s) {
                stacked = s;
            }
        }
        if (min == max) max++;
        if (stack) {
            min = 0;
            max = stacked;
        }
        
        
        // Set number of lines to draw and each step
        var numLines = 5;
        var step = (max-min) / (numLines+1);
        
        // Prettify the max value so steps aren't ugly numbers
        if (step %1 != 0) {
            step = (Math.round(step+0.5));
            max = step * (numLines+1);
        }
        
        // Draw horizontal lines
        
        for (x = -1; x <= numLines; x++) {
            ctx.beginPath();
            var y = 30 + (((canvas.height-40-lheight) / (numLines+1)) * (x+1));
            ctx.moveTo(wspace*0.75, y);
            ctx.lineTo(wspace*0.75 + rectwidth, y);
            ctx.lineWidth = 0.25;
            ctx.stroke();
            
            // Add values
            ctx.font= (options && options.hires) ? "20px Sans-Serif" : "12px Sans-Serif";
            ctx.fillStyle = "#000000";
            
            var val = Math.round( ((max-min) - (step*(x+1))) );
            if (options && options.traffic) {
                val = quokka_fnmb(val);
            }
            ctx.textAlign = "left";
            ctx.fillText( val,canvas.width - lwidth - 20, y+8);
            ctx.textAlign = "right";
            ctx.fillText( val,wspace-32, y+8);
            ctx.closePath();
        }
        
        
        
        // Draw vertical lines
        var sx = 1
        var numLines = values.length-1;
        var step = (canvas.width - lwidth - wspace*0.75) / values.length;
        while (step < 24) {
            step *= 2
            sx *= 2
        }
        
        
        if (verts) {
            ctx.beginPath();
            for (var x = 1; x < values.length; x++) {
                if (x % sx == 0) {
                    var y = (wspace*0.75) + (step * (x/sx));
                    ctx.moveTo(y, 30);
                    ctx.lineTo(y, canvas.height - 10 - lheight);
                    ctx.lineWidth = 0.25;
                    ctx.stroke();
                }
            }
            ctx.closePath();
        }
        
        
        
        // Some pre-calculations of steps
        var step = (rectwidth) / (values.length > 1 ? values.length-1:1);
        
        // Draw X values if noX isn't set:
        if (noX != true) {
            ctx.beginPath();
            for (var i = 0; i < values.length; i++) {
                zz = 1
                var x = (wspace*0.75) + ((step) * i);
                var y = canvas.height - lheight + 5;
                if (i % sx == 0) {
                    ctx.translate(x, y);
                    ctx.moveTo(0,0);
                    ctx.lineTo(0,-15);
                    ctx.stroke();
                    ctx.rotate(45*Math.PI/180);
                    ctx.textAlign = "left";
                    var val = values[i][0];
                    if (val.constructor.toString().match("Date()")) {
                        val = val.toDateString();
                    }
                    ctx.fillText(val.toString(), 0, 0);
                    ctx.rotate(-45*Math.PI/180);
                    ctx.translate(-x,-y);
                }
            }
            ctx.closePath();
            
        }
        
        
        
        
        // Draw each line
        var stacks = [];
        var pstacks = [];
        for (k in values) { if (k > 0) { stacks[k] = 0; pstacks[k] = canvas.height - 40 - lheight; }}
        
        for (k in titles) {
            var maxY = 0, minY = 99999;
            ctx.beginPath();
            var color = colors[k % colors.length][0];
            var f = parseInt(k) + 1;
            if (noX) {
                f = parseInt(k);
            }
            var value = values[0][f];
            var step = rectwidth / numLines;
            var x = (wspace*0.75);
            var y = (canvas.height - 10 - lheight) - (((value-min) / (max-min)) * (canvas.height - 40 - lheight));
            var py = y;
            if (stack) {
                stacks[0] = stacks[0] ? stacks[0] : 0
                y -= stacks[0];
                pstacks[0] = stacks[0];
                stacks[0] += (((value-min) / (max-min)) * (canvas.height - 40 - lheight));
            }
            
            // Draw line
            ctx.moveTo(x, y);
            var pvalY = y;
            var pvalX = x;
            for (var i in values) {
                if (i > 0) {
                    x = (wspace*0.75) + (step*i);
                    var f = parseInt(k) + 1;
                    if (noX == true) {
                        f = parseInt(k);
                    }
                    value = values[i][f];
                    y = (canvas.height - 10 - lheight) - (((value-min) / (max-min)) * (canvas.height - 40 - lheight));
                    if (stack) {
                        y -= stacks[i];
                        pstacks[i] = stacks[i];
                        stacks[i] += (((value-min) / (max-min)) * (canvas.height - 40- lheight));
                    }
                    if (y > maxY) maxY = y;
                    if (y < minY) minY = y;
                    // Draw curved lines??
                    /* We'll do: (x1,y1)-----(x1.5,y1)
                     *                          |
                     *                       (x1.5,y2)-----(x2,y2)
                     * with a quadratic beizer thingy
                    */
                    if (curve) {
                        ctx.bezierCurveTo((pvalX + x) / 2, pvalY, (pvalX + x) / 2, y, x, y);
                        pvalX = x;
                        pvalY = y;
                    }
                    // Nope, just draw straight lines
                    else {
                        ctx.lineTo(x, y);
                    }
                    if (spots) {
                        ctx.fillStyle = color;
                        ctx.translate(x-2, y-2);
                        ctx.rotate(-45*Math.PI/180);
                        ctx.fillRect(-2,1,4,4);
                        ctx.rotate(45*Math.PI/180);
                        ctx.translate(-x+2, -y+2);
                    }
                }
            }
            
            ctx.lineWidth = 4;
            ctx.strokeStyle = color;
            ctx.stroke();
            
            
            if (minY == maxY) maxY++;
            
            // Draw stack area
            if (stack) {
                ctx.globalAlpha = 0.65;
                for (i in values) {
                    if (i > 0) {
                        var f = parseInt(k) + 1;
                        if (noX == true) {
                            f = parseInt(k);
                        }
                        x = (wspace*0.75) + (step*i);
                        value = values[i][f];
                        y = (canvas.height - 10 - lheight) - (((value-min) / (max-min)) * (canvas.height - 40 - lheight));
                        y -= stacks[i];
                    }
                }
                var pvalY = y;
                var pvalX = x;
                if (y > maxY) maxY = y;
                if (y < minY) minY = y;
                for (i in values) {
                    var l = values.length - i - 1;
                    x = (wspace*0.75) + (step*l);
                    y = canvas.height - 10 - lheight - pstacks[l];
                    if (y > maxY) maxY = y;
                    if (y < minY) minY = y;
                    if (curve) {
                        ctx.bezierCurveTo((pvalX + x) / 2, pvalY, (pvalX + x) / 2, y, x, y);
                        pvalX = x;
                        pvalY = y;
                    }
                    else {
                        ctx.lineTo(x, y);
                    }
                }
                ctx.lineTo((wspace*0.75), py - pstacks[0]);
                ctx.lineWidth = 0;
                var grad = ctx.createLinearGradient(0, minY, 0, maxY);
                grad.addColorStop(0.25, colors[k % colors.length][0])
                grad.addColorStop(1, colors[k % colors.length][1])
                ctx.strokeStyle = colors[k % colors.length][0];
                ctx.fillStyle = grad;
                ctx.fill();
                ctx.fillStyle = "#000"
                ctx.strokeStyle = "#000"
                ctx.globalAlpha = 1;
            }
            ctx.closePath();
        }
        
        // draw feather
        base_image = new Image();
        base_image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAAEACAYAAAB7+X6nAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACJQAAAiUBweyXgQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z13vBXF2ce/z+65hUuxYUNEuFyaF0EEwRaDPRobKsYSW0w0auwKWBKPFUEs0ddujJpEDWo0aiyxYBcEgqKXJsJFEQuitFvP2XneP07b0+utnN/nA/fs7MyzszO/eZ5nnpndFYrocNC7q7s1SMNvUY40qsNQa3NVvkGZbYw+02Ndl6fEW9OciSxp6coWUVg03Fd5hqreoipboaAKqAT/Bv6pUmtUzt78kqX/TSevSIAOgrX39Nmi1PI8BhwORHe4ESJkCP9Vo/xlM2m6QC5Z2ZBMbpEAHQAbHqiqttU8h1IVTozq8BgCmMh5VX3H+Dlyy0nL1iWSXSRAO0f9fVV7gvkPsEXUibgRL7EawEUGmec4Zr9EJLBa/haKyBUN9/ffD8yrxHY+BIauxCcRmyyA6AjLtp7TO6vKYsUUCdBOUX9f5TGq+jLQPVkeCf4nCciQAGPXNzI5oYwi2hc23tv/dEv0IcBOmTGdGTBucyCoomI4dLNJS18NiShqgHaGjfdWnizwF9J1fhrEaYfAUBcVHvj2lmFdQ/mKBGhHqLuv6ghB/kqm/eLq3IT2Pwoaytun3DScG0otEqCdYMO9VWNRnQ6UQHBqlwHE/SN6tCeH6oV6/8gSKBKgXaDu7srdbfR5oDw/SRr5mUo7CDv8tOang6BIgDZH4wOVA7HkRU3h7adEgtGeoMND08FwolgyHsCT00WLKAjqH6zq7fj1TWCbvARJ5I9ClCJInl+OUA34iEW0AfTu6m71dsO7qOyaKp9Iut5Eg9M+SRcWJmaqaDlmUNEEtAHUi1VvNf49XednAAM0EWUIogkTmgYmChb5LWt0kQBtgLptK6cBR+UpRoF1QHki7z+pahd1O4cjiwRoZdTdV3WmIBfnK0dgAa41grDjl+lUMJC3d17RpiKyw8b7+h0kKk+Q1exLEnhqMhMYQjBmkKxcXIqGJQKgsLZIgFbChrsHDLEsXgEqsi0bQ4D/AdsCPaMzEWP+JcEvV0rAEviLJqAV8NXF1Vs2fCc3omyep6gvAr4+fRKedTt8ZBQW7lkkQAtDx2OXlvr+bpoY529gXk4yAmHhDcBHKCOT5YvfB0BSfyCYZIoEaGF8XzngJoVDARpX2yZHMUZV7wCOy7xITPwgRjsE4RQJ0IL4dsKgIxW5PHSshpH+OvkoWzmCTBVLTiWl00e2u4RAij5Ai+H7y4cMQPQxYtq+cY10RclGEzxv0EqUnTLJnGQfQLK8RQK0BL66uHcXx3L+CWwWe06NVDdvsD7IUNRSFZkpcHymy8MxVwv8SU6GjcXFoBZAaVnFvaqMSHa+6UfZobQHPlKr9AYR/RPKw4WqlwAqkRmjwrdFDVBgfDNx4HmqnJYmW7+mn6z3U+ZQuUBVLiHbPQJZ7BISdFWRAAXENxMGjsZwa2gFLhWa18lglPqEJ1X/ArodMCo6ubC7hASWFQlQIHx1cfWWOPJPVMrCT+WEiJCYDNs1rrFnJkhfatk8gvDHwtQsyS4hARUWFwlQAKgXy8b/hCp9CTyJE/6nMU/quOGrY7ga1rqSmsSyfm2M9X9Aac4VSrVLSDHGx0qnQf6njnxWdAILgFU/DbpchIPB1ccanIoFvS4NnolSz8pWjT9Yb3TZxhwAICJXqjFHAMPzrZOq1pkm62vjkzW+Rmk2zZSpw1ao9AF6A1tt+1P3T4sEyBOrLhg8UpXrFA2stiXYmiGQlAj+ehmjDt+JzceIvI/qe6mupyqBXUKKUSOrjY/VpknWOc3i8zdLifrpoYbtCSwWDUwuiP/JA3N9RQLkgdUTBnVvbuBJoJTgKg1uIgT/JiSCashT79bwnfV2t16+PxjDSwoGP98ZR9aroc7x0ag+mo0fNX6rBIduGLbUwIpg6F/WUJgJxU2heaGpjruBKgTX6I8QgVBSIiKE1uRV8TXx8PoVpaersiMB259zx2YOKRIgH6z8/aDjUTkldBzu3PDoT6DyQ0QI/hVAVR7H0oVqeALJw/HLDurxBOIQxV3BOaD2t4P62R7rY6AHouH4uzvyEk4LnwsSITo6s9o2zbuY0pLHgf1jzrUkZm83ZcloKD4YkjXUO9YjlvUPlB6RbdYSfhoX11O5UVNAE5wWmqi0c9Qu/SVG9o87l3Y3eO4QlRdCv4smIEt8tfLba0Vkz7AaT2D7wwM4pe3nSUv97xiPvTC0QcftF0TJLrRGMPw79LNoArLAl2cO2VfhTZHgo9spVX6QErFqPRCF+8H2+apNecktoKfGnHPldz3KVTgi1Gw3ZcnQ0EFRA2SIFSftsgXG+RuCHRn9kQ6KHuWBBA33pkb1naLnaknJEFU9JaoMLgdRcbFBw4985esnKPKY+7hIgAyhHv9DwShaJC2kuENE0IDzD9FEQII+QsBhfLrBcp6vwPMJRiQmJoC7WEA2uPdxJYwoZg7HUedxd0KRABlgxak7/1rhmLCDFmX7XUQIdZuLCODuI/mh2Wf/obycKxQGRc6F/YIASaJkE/6RNrScHi/2nrp0pTuhSIA0+PKEQb0clT8HuyicHj/vj6h8NxHc837gDyW200MME4MZo2ICRJXOMLQcqz1SEEGE/4tNK04D08DxlDyIYcvA8m5gyodrmTdutc8QnBZKJC3Qc//a8f6F0xHuVZXyqDLBpeOoqWSS6WX8NRNMLxNOIfXzbW5e8kZsalEDpMCyk4aeqY4eFvtoVqa2XyVIAtF14jfnf332kFNQDkjgF7hkB+XkEVpONIVUlTslATWKBEiCz08e1hu/My3c0GEbTEa2P5oz8scusKHBYUpI50ap/BS2P9vQcpgIrjqJxXoP8mii+yyagARQEPGZh1Rlc1yqPCq6F2UGQipfoiOBgc0hc/tsWHBPo1hXAduF1Xisyk6k8mOvqUQiirGmJ86MROpjVB7ZeuriDYnutRgISoBlx1afp5YEHCZ3IAZwv2cneQAomA+MKntZJfZqcBYglCUNDrnKh66TSHZ0XYCgvLj4QCSvT7EG9Lp14YpE91rUADFYNH5YP4PcHLWfL2oUSnAUxqYTM/oF1Lq7398WzBI101DKwg6ikfjRG6dZXBrBJTu5ExivPYJ5H03W+VDUAFFQL9ayT3aZocK+uEaqJBiFMSM9ZvQD8C0lJUPE+EYg+mZCbREsn2j0Jh79SfImkhk4dhxjDdnxzoWfJ7vnogZwYen/drnIKPtqjA2NtsHEjNrEtl/g0r51Azag3B7vF7j/ScbTy4RaIcUU0ihPpOp8KBIgjIXjhg8EbojqgBARTAoihJd+XURQ3t3pHzVP1JbV/FaV4THnwrLjzUAMEQzJiZDejKhHrSnp7rtoAggo+88P3+U1hODuXBI5U8EfaZxAMFiMwSn73CppXIIE3wHoluM2G7FyotI0gRlIqfLdPfp077sXjU9370UNACw5bNiZqBwQpfKTRt9cTmCiEarc3//Jz+aIp/FPqmyTcJSaaI2Q0AlMFFHMfArpWOr8KZN73+Q1wLIjh27r91kLVQJv3IqM/tROYJRGIJz+k1PaPNAypZvZUINometcQs0SNdLTTi8zm0KqcF+fexeek8n9b/IawNcsd6qyRba2X+Nsv6CqVw96YskPluEOVcqS2f5oJzBz25/hFLLOOFyX6f1v0hpg4cHDDxf0hWQ2GGJHv8anRf5+WlUyeMQXLPi5qLyRUE6M7U8+vYy3/YmnkPHaQy25bqf7F1yTaRtsshrgk4OHdRXlzsjolTS2n8QbO0P/0MuofkoxckfCMG0C258wtBxl++Onl6m0h6h+X+FzpmXTDpvsYlCpXyar0A8hauUNIOGCS7CcuP4Prbyp8sqgFz7771IZdiroLgQe3QosDCnuDT1BrohrYUkj6UQGd7g8rtc6hssHMsZuSjFY12/9cE3CmH8ybJImoGb/4aMt+ACwUzteyVW+K81xjI4wXc3i0iZrIRaV0bJinMmkJsZlHpKo/DRTyJrVJV1GjHpgri+bttjkTMCMsWM9YuR+NWIXYuVNDH8d8tKnn5Y22ucClfEqO6LKU5mYhCo/lRmJrreqI+dn2/mwCWqA+fsMv8Rjy61A4kBK6G8iRy04ml1pdeq3BzqbN68vabC+QNgmxapc6uml67oSrFPi8sSMfgWRv/V9rObUrBoiiE1KA8wbMmaAs8bzezU057fyFk6bNvi1eatK6q0JqGzjPpdwNTHV9DJquhejEZJoj6ATuB5jJubaJpuUBvjfoFH/QTjM09W8a1eYnwE5234RvtPyxgG2r6Lc4HyB0D2jhzoKZPtD5dXi/Mq/18Rt9swUm4wGmDdo1FEoh6Hg32hXYmiOC6RkYfvV0asGP794g1FzDUr3qBBtFrafbG1/dJ0/XbFy6/vyaZdNQgN80HvPLmVdfJ8BlaGRY3c179gVum/mQZeotfgF3zpbDN++9McdgUUIpfna/iSh5VTaw6/oXv3/WTM7m7aIxSahAcrKnYkYqXSPUqfe7o+hKdGCS9xsIOQnRHbdXLLfW2/5Ra0bUSmN8gtytP2JQsvJwseqYGBKvp0Pm4AGmFM5sg9YC4GKWBttdeGdkm7OvuG0sFftzke07UfeHPL2vAMWHTB0mGLPQ7ASzhRcMt2ysggtJ9Ueqiy0u2/crd8jtY05NksYm0AkUP6MBr7SoUqkcxBMA4O1gkaR4Ns4lfine4IIljXG5hIANfYUJKBBw3KVcG9qWCBR28lDUgP9GqhMomcDwzIUJPohUZ+onlaIzodObgJm9xt1ECpHRyW61a1hG3+dPSvTlTdR/jl0xrxPFu434ueq8otMNnbGOZMZTC9TTSFVrYv6/yt/1R9CpyVATXV1qSB3Jc0QbFxTL0Mw1CfzwEO2H8Xx++3rANTRaxP4BcmJkGhWkXBzRxrbjz424F/z7ylkO3VaAjQ0VFyiwSdwU0GVbXz19uw4JzB+182jwz6cu6hm32H7q/LzNDtyooiQTWg5afgYPqSx8axCt1OnJMAHvffcQVWugkgbp4JTJ0NVpS7ugc5Ix/gcy3NjILN1TWynZf1AZ6plZU1EBPm4udEcPuDlpU0FbSg6KQFKPM4toN3caamIIMJWzkZrjtv2R+/ZkweHvTd72YI9RhyoKvtmYvs1B9ufZAo5w24sGVv9as2PBW8oOiEBZvcbNRrRE5KdT0YEf6PsooaNsdE3VWk0+CcDGMEbZ/tTESFL2x+3KQXu8Xd1ftH/9bnrQvWcM3Jk3FdI8kGnmwYq1rTIjCq58g+dCU+9hS2dBustu4sZG7WBQ/Tu4bPmr/x0zPCD1bB39HQtzZO9ESGuKWDM4+DBcjGbUlYb9JwhL81/JpRv3phdB9iOfS0W04HnMmmLTNCpCDBrp9HjBH4WSYnMn5PBfcY0yTC7jA1qBWL7ImykyZkayGh5w2VCnea6TrjTg3P6QEwhpiYKad4LYFD5u+W3Lx381twfAOaPGLGnipwjPk5E1CNSkvd3h93oNJHAGWPHerqtqJ9P4Ju6KZDaJbQ9+pbd1YwFUJEbdp0394+f7L7bL0R5uUUf6kBfN7ZMqH79k3mfDt1tmPFYR6DmFIRBLjkLh//vfzunvr/s0Gk0QLcV9b9XGJKe0am1guOXEZZjrRVLpcRXejuAGLzhEkF17o4URkY/rtEfE1EMnovVHoq87zRb9/nX4UHk3I+HjjzEEXbERGyKBDWGIs9n0BRZoVMQ4L1Be3fXZt/VEN2tqcmQlAibOY3yttWF16prPvxx/q6jDlNjxsS9JiZEBI2M9HjbjzHIahH9AcNGNdKEQdWRElW6Gb90x5FhCH+LeAhuc+GWK1hiwm/4LBQ6BQFKm5qvQCTu9epxHZIQ8UQwfrbv2lR2ZyDVuQYVV1w+qvA6g3yLQx1Kszrix6FUjXQ1PtkKpSewLcK2hEyC22SE/mow3h8e6a6aRYiwYpd58xJ9YygvdHgCfNB7zx3AuTBVnqyJoHrv4MXvb5g7ePQh6jd+Vd5WQB3K8Ut3VXpi6Engw5DJp2Xi/hMazpp8uzggxBMBQAyPSgJ1lS86PAFKPM5NChWZ9HKGRPhOms0DAKZJrzNNMjpl7lQnQ+Y/yu5HrexlRAQU9VtEveK1UOjQBJjVb/RwVX4dlZgnEUSYOmrV3Pq5fUcfYmB0ukGXGakIB4qiVH7wRBQRQs5iWK4AvD7qszlfpLtELujQBBDVW0ASRzNzI8IPXbpUPADgCFdJ7NksAkvpMkY6PYYIIRmuWYNY+ud0YnNFhyXAzH5jDlbVgyAzNZwJEUCmVNe8tXF23z3GgvlZfM7MA0s5ESGREwhLd1049+V04nJFhyWAqIYfgc6o0dNn+qFrRZf7AFT0qhynkFlcLjpjQidQQUTvFLL63HxW6JCLQTP7jjkKGBObnmyhJ5NMqtxSXfPWxjl99xgDemBGsqLCf1ldLmnGmO3ia+wuvoczKZ4rOhwBFCyBa9PkyZwIgYw/dOtacQ+AEXNV1rJagggGMHrb8Pnz6zIplis6HAFm991jPDC8kI2uhjuqa97aOLPfmGHA4bnLyrxOGdRrnaX+gm7/SoQORYDpjLcVvSY6Ne9GX18qzXcDWKoTY1Zrk8pKjfR1SidLVG8fUfvx2iSnC4YORYC+fb86haSrfUIuWkGEu0bUfrx2dp/dK1GOT5gpAzmFrBPwrc9j355WfAHQYQgwZ+TIEoP+MbNYaMaNXm/bvj8DqCWXITGzooIRIas6IXDhHktnrc9IbJ7oMARw1ti/ASohGzuautEFfXC3pfNWz+w3Zlvg9KQZsyBC3uZB5eGRy2dPTyumQOgQBJjRd2y5IlclOpdHo/t8UnJ7UMhFCl1ynUIWsE6LSxsaL0h/hcKhQxCgXBp/B+yYKk8Ojf7E3ss/WDGzakwPQcMvVcxhClmoOjVg9MTh37XstC8W7Z4AL1UdWoZhQhrnPIwMG10t29wCII6eTYIl3YxVemGI4IjKSbuvmDMv3eUKjXZPgC38P52B0BtAkXSztDBSN7q+uPsXcz77vOrQMlG5KD9ZmWdKkqVZ0ZNG1X5UsJ2+2aBdE2A6421VuTS24/MlgmUCr1Ff4//xJIVeeUzXcsrkylKPyLjRrej0xaJdE6D3Tit/pSJVoeOCEEF5b/cvZ74fWGeRS+JzthoRalV1792XzXoJYO5Oewz5qGr36nRiC412SwAFUZHLAr9Td3w2RMDWKQAf9t3zEESHJs/YYkQwIPc0l5YMG107++N3++yzxUd9x0x2LPN47dK+i9LWv8BotwR4r3KfXyoyIpuOz4AIC0cv++glAEvNpa260BPItERh7Ojls86z6kzJrH6jryq3m79AdJJgXXM8Tzlpq1NgtFsCiOqk0O9sOz4ZEUT0ZgHzUd/dd0U4MJK/hYmgrAS90Gp2RliOMbP7jn7U43G+FrhBYQvg1d2Xzyz4nv9M0C43hLxXuc8+atg7dOz6nHJOx8G0r+wtnSdYDkatSxL1pYbzpkLmm0GA5cBTIroQtQ4wpXI1sHVMxnpVMvq4Q0ugXRLAGLks+smbvDo+9PPWUXPn+mZWjemNn6RPDwfKh8qmQnoiANtCIIYhkiSfyDVjamctT3mpFkS7MwHv77hXf+DwkBrPV/UH035s6NrlLwD4uECRkkzqUoAVv4pUsgRm1C7v0yqrfsnQ7gjgWPaFitjutFyJEH7sUuTe/Wre2vjeoL27I/wuUZlUaIkVP+A7UefktnD83GhXBJhZNaaHipwG8Z3oTsv0OJjms23nPgCryZxpsDbPN5ZQAIexCdHjR62Y+01GF25BtCsCNDhdzlKkR74d7yaPoI/vsXTWSgVLkfMzlZEOeRBBRfS3o5fPfifji7Ug2g0BpjPeRvmDO61AGuAOgA/77nkkUJmt+UiHLImgilw8evnsv2ckvBXQbmYBW/ddfQSwUyIPPudZgPDGPsvf/ziYdlFQI2QkI1laMmQwc3CA8/aonXV/WmGtiHZDAEXOgdQdkPWxkdsB3u23z3BV/Xk2MlLlSX0fobJRaFDllD1WfPRMXIE2RrsgwBs77t8f9EDIrAMyPF7ysxXvvhxMuDBbGZnmSQYXEZYgevwetR99krZQG6Bd+ADi0XMVsZLM4bM+DqbdLmDeqfrZ1oqcmKOMjMokgQKP1HftMnLM8kDnv99/r23SFWpttDkBPui9Zxej1umh4wJN/35saOjyNwD8nAOU5+hA5kqEj0X053vUzjpjG1Y3z+o3evzMnca8ZjkmZQSyLdDmBGjwdDkB2LIQHR8+Vu455Lv/1tVUV5cq8vs8tEi29ahR5AzHtg9RlR1m9h3z8Ia6bl+qynSE/R3HfjrnhmohtLkPYLDOgoI6f82C3gPwff3Wx1uY7bORkeN1GxV5B8MqLM63HPMX4gfX2/t89f6qLJqmVdCmBHi98oCBatgDCur8Pb7vine/ARDVC1rC+UtwXA4c7O7yuDwiT2TcMK2INiWAMdaZod+F0gAqgcDPm33221vR3fNZQcy1HgnSfFaz+VeGzdKqaDMfYMbYsR5Fwu/3KZAP8Pb+y2d8AiAWF+YiI8frppShIv8d8/VHa9K1SVugzQjQtLzsEKBXQTtAuQtgRtXY3qqMa0XnL52Mf2bYLK2ONiOAIqcXuAO+7tFz/fMAxmedTfBBz9bUAElIuVFLpU32/GeCNiHAK70P2VJEj4DCdQDKvaPmzvXNGTmyBOE3Be3EDI+T5Hlyn8Xvb8ikXdoCbeIEmhLrWFEtg4I5YU1qyUMAa9dsfizQK1dHLpcyqeqO8JdM26Ut0DYmQCN78gox8gzWkwcuf+O74MnzcpHRQhpg0T617xf8/b6FRKtrgP/0PWw70J8XcuRZlrkb4M0++1U7IvvkIiOXMmllKA9m3jJtg7bQAMera89fAUbezAOXvTEbwG95Mt7xU0jnL4mMZstj2s3Gj2RoCwL8CgrXAUatuwBeqjq0B8rJbaH6E8pQeX7vLz74PrMmaTu0KgGe63/UjorsWcAO+N6UWM8A2H7ndBXploOMXK6bVoZlt9z7fQuJVvUBbMc5kdDmuAL4AAbr3sOWvhz6mOJZuchoER9AmbPPsvfey7BZ2hSt7QQeV8AO8NmO8wDAy31+cYCi1TnIyIuAyequIrdm0SZtilYzAc/sdMz2iowKHeerggX918FfvRZYXrU4NxcZ7uOCOX/Kyu5bbWh3e/+SodUIUGo1Hw6Bj6QVogMM1r0A/93xoF7AEQX24LM6jkm7Y9Tcub7MWqXt0WomQFWOUOK3ZUNOanvhobUvvwPgs0vOErSk4HP4LI5daRsc234oq4ZpY7SKBpjee3wXRQ6Awow8I9a9Ajqd8baonpmLjEKo/gQyHjpo2evh7/x2BLSKBvCU+g9QIxVQkJFXj8PfASr61f9SVXrnIKMgzl+MjAb8dBjnL4TWMQEm8gr2fDtAVR4/4ssXfwqeODsXGe7jXMokkmFh7tp/5YyvM2qPdoRWMQGCHlwoFSyq90EgqAQc0pbOnythY6OnfFpmrdG+0OIa4Nkdj+6vSL8CqeDZh3/5n7kAtt/8TkXstnT+wjKEaYctfXl1lk3TLtDiGsDYVviRr3w1AHAvBPYTIvqbTMq0pAYIpq3xeUra9C0f+aDlfQDlQJXkT+UmSktyvFaa+SfAxtruhyvskEGZFtUAwYObD1v6cqu8278l0KIawIvXAsZCQTTAI0eseqE+kB6I+2dQpqU1QG1XX93dmbVG+0SLaoChlZ/upkZ6QgFGnglsrnih8og+xsjBOckoRD1cxyJ64V4rP2zIrlXaF1pUA6iRg8K/8xt5M47+8t8LABy1zgLiNpRke5yP1ggev3rw8tfa5OWOhUTLEgD5eYGcv/sh6PwpZxSiE3Mp4zpuciy7Vb/s0VJoMQIE7f8eoeM8OmBNqaf5OYB1yzc7QpFeBRi9+WqAa3+57KUlmbZFe0aLEWDnyppqYLN8O0BEHwlt+lCR32VSJpPjPGTMKu/beEs2bdGe0XImQEm49Ss6S/oG9zklDwM8U3VMb0WSRhSzPc5V9VvGnLnfW2/5s2qLdowWI4BRa0/IswOU947/8qkFADicTgGcPzeylqFy5S++fLUmi2Zo92hJJ3CvfEeesawHA+kIyukFst+5lRH5z2ErXuqwEb9kaBECPLrDqVsBAyCvkbeuvKnpaYBndxq3nyL9c5ARd5wjeb5sbi49TcAVAuwcaJFAkFNij1JEII/Ai/CPUOTPiHVmTjISHOdQpkksPfaYr59tl8/354sW0QAbSroO90nJEshdA4jRhwCe7Xv05oqMy0VGATSAqsjvfrnspTnZtkFHQYsQwKg1dL3VY10ezt+c41Y8Mw+gWUtPBrpkLSPJcTZlVOSaI5e/8LfcW6L9o4WcQKn2iWf3ZilZmEsHYEUeqhTR3xSi47OVIehfj1r+/PU53X4HQsEJ4MVrKQwBWG9vVh9Kz6ID6prt0icBpvcdv6siu7nlt4oGEHnmm622P5tNAAUnQEXlj/1BuijgxxrZQOnCbDpAkX/+euk/1gMYtaJ2/LaSBpj+3Zbbnnj23Ac6zN7+fFBwAnjEHqqEPGlhg92jAbLoAA286eOlqkPLgBMK5fxlIkPQJzfvu/bkTaXzoQUIYCzCnz9VwBF7tyarbEGGnbTwpBVPfAiw3t9jHEJP9/mW1ACC3vFx7YiTO1OYNxO0RByg2tWoAKyT7mZr1hCbnuD4gZAQRU4N/c5jDh/V4Uny+BDOG7f8uQeh3b7Mq8VQcA2gyNCg9g+PMCPW0Ear/DNXnkQjsdnnK/kbwBM7ntBLiez6KYQGSJLnR1H9xTHLn233r3JpKaQlwE0DLx2cqbDgHoABGhpbLiKss7qlVsGqz5/29WNrANQjJwN2Th585qr/Axtn5DErnn0z0/vrjEhLABV7+8kDL5t+U9UVW6fL22Pguu0VyoI75ggRQQVUrKFNVtknkLST/ho+VjklRw8+6bErzQGm/LjVlmPHHim3iwAADrJJREFU1T5Xm+g+pg28tGe6e+0sSEuAqxZPnQGyTizfZzcNvPToVHn94ukb+q2EVk4CakCBdXaP0iSd9G2vfqv+C/BY5SmjgF3c5wvo/C0T1X3H1z49KZmnf0fVhed6fH470bnOiIx8gKZm3+UgfsF6dvLAy+/39vWWJ8pnjO4UaezQvD5CBIMMabRKP4ntJIP1SMj7th3ntEKq/iB8wJ10Zfj4FU9/kKju0xlv3z7ggvvBdL9o+Z+/y6RdOgMyIoC39o61oH8I+uJnlZXWv3dz5cQ+sflE2Cn02x0LiBzDBqtHWSRPoJM8+B8FmF49vtRgFfolkm+L0V1/VTv9wuNrntqY6P7u6XPOFl9Xbf8sah2y1r+hQ7zcqVDIeBZwxZJpz6L6dKAjdaR6zKzJgy8d6c5jwm//jiCWCI7I4AYpm+fqpA9Oqn1iEUDzxtJfIvQshAYAPlWVY06sfXJseFdRAtxeddGejaWlcxU5QtVM8tY+0phpm3QGZDUN9JTK+cBaAIXt1Fgzbh5w6b6RHLp1oK8TjdwIEdZ5ulcAqggqEefPEfv0Ajh/i4xYp1m1ZsSJK558Ntm93Fl1ftltVRfeqPAuSD9g5sVf3NluX+veUsiKABNqbvlWkRtcjd7diPXSzQMn7gOAWNuFbX5MLCCEwHlrUL1dPg9oMGo9DfBw1RlbC3poIE/WGkBV5A1VOdZT6x968vLHH0v2VW4FubXqkvE+7BpFrlSwFZow1lkSclc2IWQdCfSVVNxV4qs/B+gf7ICuDubZG/pfspsqW4MggIbaUggeh5o3UGqjdOtRrs1Pn7HikbUAtt85SZGSQJHMoniKrEZ50hJzz0nLA2YkGbxjvZ5uq9YefquKF3Q4GiXHe+my2z/Nti06A7ImgLfG23z9oAmTRHnK1T09xfY8AbodRLz+kPsXGlbhTWIKjlC1xurqfr3baRl2/Ocq8jzw77LlTR8kG+khTBl04SBL7TP4ev2pirV9uHbBSxiVt3daurLT7PPPFpI+SzwU5MZBEz9CdVQiIRKjSaMNQPj428Ze3Xb0vuX1P9rv1GGq8klMeZ8iqxX53of9sVjyjlViXj1z8cNJP73m7eWt6NplY6URxqjoPhbsDTog8c0qoKtK/LrbpjTti0VOi0ECer3oZEGeAVCXanf/iozeULkonfCo9y2vH+Anu/vhJWre9Vmech92D0c8WzpYWwvaC+gF7AqcLoqZPPDyVaDuDqsX2AplB9i4mXGRLKkmCvzfgOpxm3LnQ44aAAJa4IZBkz4GHSauxGgFHrpIvEYQYw2dtHRKjXes1+P5puFLlO1jNETS8pE8GnPsTkpUj3AGn2CNu/zzaf9JfoebBnJeDRRQFW4HV7QvagoYQQIPfu6kpVNqAOxVTQcrbB8qG+ruVOUj10wQcQwnJaoHKOJDOKXY+QHktRy8ub/uiaCdBiKdoCEiSHRnhuf1oq6dtvprd9kwESQXIkg8EaIJWSeiR09YctsmN99PhrwIcMHSu5oUHgF358SOyLjO9Pn8+gTAlEETuqtwVOK1g4Rlib6WOy1+8SkiB0TkKyPsN2HJbS/lc8+dDXlvCFHLeixV6DeOCKKveL+Y9j1Ao9jHABWpyiUhUTBPsogjuIkA8obf59v9iiW3zs73fjsb8iaAd+FNnyGyIN0aQKRj7Ij6N6FPvCQvF1U2CREgWcSRDWCdP3HJLQddFfT2vX0v2jyf++1sKMiWMEWeCvxK6ngR7NB1FXVNLwLcOOTK7RH2z7CcKw0XEeLnB2EiKM8bx6m+YsnU/wvFIG8aePlh5VZZj0Lcc2dBYTaFiryiqtdAeI7tmnNHYgGK9eQlK29vAPDDCep63j82chCJKSQ6G7psMFWjcs4FJl75+S1vuKs4ecCE36M6eNKyKUUfwIWCEGBVxeq5vep61gFdFQ33UHgNAEK/wurfKL+WUDxW44I0cURwHyUMMYsswJEbrvz85ifdizo3DrlsKI411aC7lzpaTRFRyDkQFItrBl/xBsj+EaHRRABq/7R4cqWAequv2FkdCb9pI0rJa2xaID1RRYPXmSMqN/mXlP/bi9d4R3orrLrGIeI4e4nIUQL7A4LIr65aPGV6Ie61M6FgzwUo9jzB7B/4DYE2D55TBZFHw+uBjnWykiRULIEUjSJCvEkJljMgW4owzTOo4bbrmbg5Gxs2FwDLilwbHri62PkJkZQA51edX7aZZ4tTEYyjvucmL5qc+gUJyhcqyWy1qO23QupfFE4KnE+cP0KeWCLEmRQLqDShMsH0KMdQrHcdT/n5FJEQ6UyAXDn46j+JyFUCM0HewTLveUo8M70fe9e6M/5p8JWHgLwSLTzce+9du/CmnwFcNeSqfS3l7UQXTx7zJ7TilKDCKWP+c0p8HDhp2ZQO9RmX1kQ6E6A3Lbrh2qsHX/2pijwK+jOM4G9yuHrI1etRvgLWCrKFotsEi8SPVo18Q9eCE2PduGSriIG0AEIOo8YRIfHMQZH3Sks5ctLim4udnwIZxQFuWHTDv8AMBV6EcAP3UJFqhL1VdGeFnqGuCc3Pg53X1Fyi0wHOGnlWiaoclzJsS5oIX0wwyG02QtcV+Ic2lR90xac3/5Rle2xyyHoWcEW19zgxzq0CUdvCk3j+oOa56xffNA7g6uqrf4GRl935oiuRTM0nXlIOFHFTgA0icsGfFt30SFY3tQkj60jg5Brv0z9UfFelwimKhF+eFI7cScCTD41OseTJcGEjJ8bmc+eNaIQUEb6o6xHWCAgv2pa1S7Hzs0NO08CydWWWVWavMmqeV6QB9GexkbugF7/Bqih5AcDb11vejHN0XD4IzAsgydQvWTAofPa/BuO9ftHkD3O5l00dWRFg4uA/7mKLda4iJzrGbAapQ7iC/Ns711sP0FTOYYL0SBnqTRkDiDIPP4E8Jap3exffOD+beygiGhkRYMLQ64dY6tyIcrRRlUAHJvLkYwM2gXX/AJwTI6WSje7AuSREWA76GvCiZZe86q3xNmd1p0UkREoCXNz7ti4lPdZPFONMUgg80xf8AFRk/SXmOQDCawA/rK747jUAb7W3W5PRw6Li98H/E0T46hRWgsxHmC+WzjdGP7lx4Y0rCnC/RcQgKQEuH+o9XMyGu0D6BrttlQUzjPKBWLLIZzxf2Gb9j1MXT90wYdCE7pZWbC0WFyHm/KD6f/qB4CPYjWqOAqkA62XgNohMAiwx6oj+oLa9xvfjujW3B1cLi2gdxBHAO9JbUV9v36HGnKbwsiBTcKwZUxf/cXEyIVMXT90AbJg0+JoBIY3gIBH1r3JCQC3ooSLyyuQF3jtb4maKyB5RBJi483XVGxq5DPhYPLrjtPne7zMVdOlAb08sDXwkUuWrLgt5L3xSZJkKjqC2ordOHOL9eMpC7zuFuokickfYBztr5P0l3ZpWb3fbZ1d/lYugSTt7f6/BL3uKcMvNNd4J7vMTqq/dT1SfAbYQdMGPXb7Z9YFN6H187RXhQNADc8/25dr5AAZODP124PHY81NrrplhYR0KbFRk583re52X67WKKBwKsiFkwiBvL2z5CrAUXXTLAu+QZHkvG+I90BZeBtb+1GX7Xg/MPbuoBdoQhXlPoC0nKlgKiEjc6Hdj2kLv68BNCj23qv/moFR5i2h5FIQARjkhpEz8jqZ96qbLNlwvyCy/RMxGEW2DvAlw+dDr+2PJyOAiz+zbFnnTflDR+5bX7xf9jYjsnu/1i8gPeRPAqJyowcm/imvunwa31ngXqPJislfOFdE6KIAJ0BOCS7jGeCSrjZeNzXpdk6e0e/51KCJX5DULuHiX63YRI/MBFN68veaPBxSmWkW0FvLTAI51QujxLStq5a+IjoL8ngsQjgdQaG5yPEnfyVdE+0XOGuDi6htGK1IVXNF/9e5FV3bKDyt2duSsAVQY7zpIGfwpov0idwJgHRP8VeexS18oVIWKaF3kZAL+MPSGUQqVgSN5Ydr8y+sKWakiWg85EcASz3gIbwUvPnTZgZGTCVA1xwZDCBs93cteSZe/iPaLrDXAecOm7qZIfwBFX7z9w0uKe/g6MLLWAKJmPBJ8LYvydAvUqYhWRNYEUBgHIEJ9ueUpqv8OjqxMwLnVU3cFGRTcxf9i0fvv+MhOA4geF358Q0KvhiuiIyM7J1Dk2GDot74i8JBHER0cGRPgnKG3DFMYDGCwXiqq/86BjE2ACseFnvpDKar/ToKMNYARjgss/Uu9pRXFt212EmREgLNHTNtZYEjwrRyv3FNzXsIvcBbR8ZCRCVAjx4Z+W2hR/XciZKQBfMY/zsGg0FjSpayo/jsR0mqAk4bcsJMfZ1dLBQvz8l2zLlvfGhUronWQlgDGco5RVbFEELGL6r+TIS0BmnDG2SiWSlNJg7/4pa1OhpQEGDfMu43j+PZSVWzklelLryuq/06GlASo9zUeaQu2JYqR4tJvZ0RKAvjFf4xBsFR9HkuK6r8TIikB9h40obtffftZCJbom69+Oq344uVOiKQEMNJwuF+l3BJBoPjUTydFUgL4xYwTBUvFlCDPt2alimg9JHw6uKrq/LJudtNqC6u7JfLBnEX37t3aFSuidZBQA5RRf7Bf6W6JYhXVf6dGQgI4thmHgqiiYhfVfydGgsWg8TbKEQCq+tmiRQ+mfedPER0XcQQYXNVtH6AnAMK/WrtCRbQu4jWAJUeGftqqRfvfyRFPANUjgr9qaz5/5JPWrU4RrY0oAuxcdVo1woDg4bNEf82tiE6IKAIYS46KnCiq/00BMSZAQup/9YIldR+0em2KaHWECTC032+3BUYDILwITzltVakiWg9hAvhL/EeGjkWl+M6fTQQuExCe/jUZ4fU2qU0RrQ4LYGSvsyoQ9gdQeGPx4oc3tG21imgtWAD13fyHoFQAUFT/mxQsAMWE1L86ar3YhvUpopVhwXgb5JcAKG8vXfrQyjauUxGtCGvQoIo9gK0BI1jXtHWFimhdWBZyFIGP+k5c+Plfih9z3MTgUZVtVfSwxUseKb7xaxPE/wNdTWzU9o0tSgAAAABJRU5ErkJggg==';
        base_image.onload = function(){
            ctx.globalAlpha = 0.15
            ctx.drawImage(base_image, (canvas.width/2) - 64 - (lwidth/2), (canvas.height/2) - 128);
            ctx.globalAlpha = 1
        }
    }
    
    
    
    /* Function for drawing line charts
     * Example usage:
     * quokkaLines("myCanvas", ['Line a', 'Line b', 'Line c'], [ [x1,a1,b1,c1], [x2,a2,b2,c2], [x3,a3,b3,c3] ], { stacked: true, curve: false, title: "Some title" } );
     */
    function quokkaBars(id, titles, values, options) {
        var canvas = document.getElementById(id);
        var ctx=canvas.getContext("2d");
        // clear the canvas first
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        var lwidth = 150;
        var lheight = 75;
        var stack = options ? options.stack : false;
        var astack = options ? options.astack : false;
        var curve = options ? options.curve : false;
        var title = options ? options.title : null;
        var noX = options ? options.nox : false;
        var verts = options ? options.verts : true;
        if (noX) {
            lheight = 0;
        }
        
        
        
        // Draw a border
        ctx.lineWidth = 0.5;
        ctx.strokeRect(25, 30, canvas.width - lwidth - 40, canvas.height - lheight - 40);
        
        // Draw a title if set:
        if (title != null) {
            ctx.font="15px Arial";
            ctx.fillStyle = "#000";
            ctx.textAlign = "center";
            ctx.fillText(title,(canvas.width-lwidth)/2, 15);
        }
        
        // Draw legend
        ctx.textAlign = "left";
        var posY = 50;
        for (var k in titles) {
            var x = parseInt(k)
            if (!noX) {
                x = x + 1;
            }
            var title = titles[k];
            if (title && title.length > 0) {
                ctx.fillStyle = colors[k % colors.length][0];
                ctx.fillRect(canvas.width - lwidth + 20, posY-10, 10, 10);
                
                // Add legend text
                ctx.font="12px Arial";
                ctx.fillStyle = "#000";
                ctx.fillText(title,canvas.width - lwidth + 40, posY);
                
                posY += 15;
            }
            
    
        }
        
        // Find max and min
        var max = null;
        var min = 0;
        var stacked = null;
        for (x in values) {
            var s = 0;
            for (y in values[x]) {
                if (y > 0 || noX) {
                    s += values[x][y];
                    if (max == null || max < values[x][y]) {
                        max = values[x][y];
                    }
                    if (min == null || min > values[x][y]) {
                        min = values[x][y];
                    }
                }
            }
            if (stacked == null || stacked < s) {
                stacked = s;
            }
        }
        if (min == max) {
            max++;
        }
        if (stack) {
            min = 0;
            max = stacked;
        }
        
        
        // Set number of lines to draw and each step
        var numLines = 5;
        var step = (max-min) / (numLines+1);
        
        // Prettify the max value so steps aren't ugly numbers
        if (step %1 != 0) {
            step = (Math.round(step+0.5));
            max = step * (numLines+1);
        }
        
        // Draw horizontal lines
        for (x = numLines; x >= 0; x--) {
            
            var y = 30 + (((canvas.height-40-lheight) / (numLines+1)) * (x+1));
            ctx.moveTo(25, y);
            ctx.lineTo(canvas.width - lwidth - 15, y);
            ctx.lineWidth = 0.25;
            ctx.stroke();
            
            // Add values
            ctx.font="10px Arial";
            ctx.fillStyle = "#000";
            ctx.textAlign = "right";
            ctx.fillText( Math.round( ((max-min) - (step*(x+1))) * 100 ) / 100,canvas.width - lwidth + 12, y-4);
            ctx.fillText( Math.round( ((max-min) - (step*(x+1))) * 100 ) / 100,20, y-4);
        }
        
        
        // Draw vertical lines
        var sx = 1
        var numLines = values.length-1;
        var step = (canvas.width - lwidth - 40) / values.length;
        while (step < 24) {
            step *= 2
            sx *= 2
        }
        
        
        if (verts) {
            ctx.beginPath();
            for (var x = 1; x < values.length; x++) {
                if (x % sx == 0) {
                    var y = 35 + (step * (x/sx));
                    ctx.moveTo(y, 30);
                    ctx.lineTo(y, canvas.height - 10 - lheight);
                    ctx.lineWidth = 0.25;
                    ctx.stroke();
                }
            }
        }
        
        
        
        // Some pre-calculations of steps
        var step = (canvas.width - lwidth - 48) / values.length;
        var smallstep = (step / titles.length) - 2;
        
        // Draw X values if noX isn't set:
        if (noX != true) {
            ctx.beginPath();
            for (var i = 0; i < values.length; i++) {
                smallstep = (step / (values[i].length-1)) - 2;
                zz = 1
                var x = 35 + ((step) * i);
                var y = canvas.height - lheight + 5;
                if (i % sx == 0) {
                    ctx.translate(x, y);
                    ctx.moveTo(0,0);
                    ctx.lineTo(0,-15);
                    ctx.stroke();
                    ctx.rotate(45*Math.PI/180);
                    ctx.textAlign = "left";
                    var val = values[i][0];
                    if (val.constructor.toString().match("Date()")) {
                        val = val.toDateString();
                    }
                    ctx.fillText(val.toString(), 0, 0);
                    ctx.rotate(-45*Math.PI/180);
                    ctx.translate(-x,-y);
                }
            }
            
        }
        
        
        
        
        // Draw each line
        var stacks = [];
        var pstacks = [];
        
        for (k in values) {
            smallstep = (step / (values[k].length)) - 2;
            stacks[k] = 0;
            pstacks[k] = canvas.height - 40 - lheight;
            var beginX = 0;
            for (i in values[k]) {
                if (i > 0 || noX) {
                    var z = parseInt(i);
                    var zz = z;
                    if (!noX) {
                        z = parseInt(i) + 1;
                        zz = z - 2;
                        if (z > values[k].length) {
                            break;
                        }
                    }
                    var value = values[k][i];
                    var title = titles[i];
                    var color = colors[zz % colors.length][1];
                    var fcolor = colors[zz % colors.length][2];
                    if (values[k][2] && values[k][2].toString().match(/^#.+$/)) {
                        color = values[k][2]
                        fcolor = values[k][2]
                        smallstep = (step / (values[k].length-2)) - 2;
                    }
                    var x = ((step) * k) + ((smallstep+2) * zz) + 5;
                    var y = canvas.height - 10 - lheight;
                    var mdiff = (max-min);
                    mdiff = (mdiff == 0) ? 1 : mdiff;
                    var height = ((canvas.height - 40 - lheight) / (mdiff)) * value * -1;
                    var width = smallstep - 2;
                    if (width <= 1) {
                        width = 1
                    }
                    if (stack) {
                        width = step - 10;
                        y -= stacks[k];
                        stacks[k] -= height;
                        x = (step * k) + 4;
                        if (astack) {
                            y = canvas.height - 10 - lheight;
                        }
                    }
                    
                            
                    // Draw bar
                    ctx.beginPath();
                    ctx.lineWidth = 2;
                    ctx.strokeStyle = color;
                    ctx.strokeRect(27 + x, y, width, height);
                    var alpha = 0.75
                    if (fcolor.r) {
                        ctx.fillStyle = 'rgba('+ [parseInt(fcolor.r*255),parseInt(fcolor.g*255),parseInt(fcolor.b*255),alpha].join(",") + ')';
                    } else {
                        ctx.fillStyle = fcolor;
                    }
                    ctx.fillRect(27 + x, y, width, height);
                    
                }
            }
            
    
        }
    }
    
    
    ]==]
    
    
    status_css = [[
        html {
        font-size: 14px;
        position: relative;
        background: #272B30;
        }
    
        body {
            background-color: #272B30;
            color: #000;
            margin: 0 auto;
            min-height: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-weight: normal;
        }
        
        .navbarLeft {
            background: linear-gradient(to bottom, #F8A900 0%,#D88900 100%);
            width: 200px;
            height: 30px;
            padding-top: 2px;
            font-size: 1.35rem;
            color: #FFF;
            border-bottom: 2px solid #000;
            float: left;
            text-align: center;
        }
        
        .navbarRight {
            background: linear-gradient(to bottom, #EFEFEF 0%,#EEE 100%);
            width: calc(100% - 240px);
            height: 28px;
            color: #333;
            border-bottom: 2px solid #000;
            float: left;
            font-size: 1.3rem;
            padding-top: 4px;
            text-align: left;
            padding-left: 40px;
        }
        
        .wrapper {
            width: 100%;
            float: left;
            background: #33363F;
            min-height: calc(100% - 80px);
            position: relative;
        }
        
        .serverinfo {
            float: left;
            width: 200px;
            height: calc(100% - 34px);
            background: #293D4C;
        }
        
        .skey {
            background: rgba(30,30,30,0.3);
            color: #C6E7FF;
            font-weight: bold;
            padding: 2px;
        }
        
        .sval {
            padding: 2px;
            background: rgba(30,30,30,0.3);
            color: #FFF;
            font-size: 0.8rem;
            border-bottom: 1px solid rgba(200,200,200,0.2);
        }
        
        .charts {
            padding: 0px;
            width: calc(100% - 220px);
            max-width: 1000px;
            min-height: 100%;
            margin: 0px auto;
            position: relative;
            float: left;
            margin-left: 20px;
        }
    
        pre, code {
            font-family: "Courier New", Courier, monospace;
        }
    
        strong {
            font-weight: bold;
        }
    
        q, em, var {
            font-style: italic;
        }
        /* 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;
            text-align: center;
        }
    
        #modules {
            margin-top:20px;
            display:none;
            width:400px;
        }
        
        .servers {
            
            width: 1244px;
            background: #EEE;
        }
    
        tr:nth-child(odd) {
            background: #F6F6F6;
        }
        tr:nth-child(even) {
            background: #EBEBEB;
        }
        td {
            padding: 2px;
        }
        table {
            border: 1px solid #333;
            padding: 0px;
            margin: 5px;
            min-width: 360px;
            background: #999;
            font-size: 0.8rem;
        }
        
        canvas {
            background: #FFF;
            margin: 3px;
            text-align: center;
            padding: 2px;
            border-radius: 10px;
            border: 1px solid #999;
        }
        
        .canvas_wide {
            position: relative;
            width: 65%;
        }
        .canvas_narrow {
            position: relative;
            width: 27%;
        }
        
        a {
            color: #FFA;
        }
        
        .statsbox {
            border-radius: 3px;
            background: #3C3E47;
            min-width: 150px;
            height: 60px;
            float: left;
            margin: 15px;
            padding: 10px;
        }
        
        .btn {
            background: linear-gradient(to bottom, #72ca72 0%,#55bf55 100%);
            border-radius: 5px;
            color: #FFF;
            text-decoration: none;
            padding-top: 6px;
            padding-bottom: 6px;
            padding-left: 3px;
            padding-right: 3px;
            font-weight: bold;
            text-shadow: 1px 1px rgba(0,0,0,0.4);
            margin: 12px;
            float: left;
            clear: none;
        }
        
        .infobox_wrapper {
            float: left;
            min-width: 200px;
            margin: 10px;
        }
        .infobox_title {
            border-top-left-radius: 4px;
            border-top-right-radius: 4px;
            background: #FAB227;
            color: #FFF;
            border: 2px solid #FAB227;
            border-bottom: none;
            font-weight: bold;
            text-align: center;
            width: 100%;
        }
        .infobox {
            background: #222222;
            border: 2px solid #FAB227;
            border-top: none;
            color: #EFEFEF;
            border-bottom-left-radius: 4px;
            border-bottom-right-radius: 4px;
            float: left;
            width: 100%;
    
        }
        
        
        .serverinfo ul {
            margin: 0px;
            padding: 0px;
            margin-top: 20px;
            list-style: none;
        }
        
        .serverinfo ul li .btn {
            width: calc(100% - 8px);
            margin: 0px;
            border: 0px;
            border-radius: 0px;
            padding: 0px;
            padding-top: 8px;
            padding-left: 8px;
            height: 24px;
            background: rgba(0,0,0,0.2);
            border-bottom: 1px solid rgba(100,100,100,0.3);
        }
        
        .serverinfo  ul li:nth-child(1)  {
            border-top: 1px solid rgba(100,100,100,0.3);
        }
        .serverinfo ul li .btn.active {
            background: rgba(30,30,50,0.2);
            border-left: 4px solid #27FAB2;
            padding-left: 4px;
            color: #FFE;
        }
        
        .serverinfo ul li .btn:hover {
            background: rgba(50,50,50,0.15);
            border-left: 4px solid #FAB227;
            padding-left: 4px;
            color: #FFE;
        }
    ]]
    ��������������������������������������������������������������������������������������httpd-2.4.64/docs/error/����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�014714� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/include/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�016337� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/include/bottom.html���������������������������������������������������������0000664�0001751�0001751�00000000421�10653711064�020520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
    <p>
    <!--#include virtual="../contact.html.var" -->
    </p>
    
    <h2>Error <!--#echo encoding="none" var="REDIRECT_STATUS" --></h2>
    <address>
      <a href="/"><!--#echo var="SERVER_NAME" --></a><br />
      <span><!--#echo var="SERVER_SOFTWARE" --></span>
    </address>
    </body>
    </html>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/include/top.html������������������������������������������������������������0000664�0001751�0001751�00000001477�11644657163�020044� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!--#if expr="-z v('CONTENT_LANGUAGE')"
    --><!--#set var="CONTENT_LANGUAGE" value="en"
    --><!--#endif
    --><?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="<!--#echo var="CONTENT_LANGUAGE" -->" xml:lang="<!--#echo var="CONTENT_LANGUAGE" -->">
    <head>
    <title><!--#echo encoding="none" var="TITLE" --></title>
    <link rev="made" href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->" />
    <style type="text/css"><!--/*--><![CDATA[/*><!--*/ 
        body { color: #000000; background-color: #FFFFFF; }
        a:link { color: #0000CC; }
        p, address {margin-left: 3em;}
        span {font-size: smaller;}
    /*]]>*/--></style>
    </head>
    
    <body>
    <h1><!--#echo encoding="none" var="TITLE" --></h1>
    <p>
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/include/spacer.html���������������������������������������������������������0000664�0001751�0001751�00000000011�10147723030�020456� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
    <p>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/contact.html.var������������������������������������������������������������0000664�0001751�0001751�00000012737�14016700775�020034� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    Pokud si myslíte, že toto je chyba serveru, kontaktujte, prosím,
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmastera</a>.
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    Sofern Sie dies f&uuml;r eine Fehlfunktion des Servers halten,
    informieren Sie bitte den 
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">Webmaster</a>
    hier&uuml;ber.
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    If you think this is a server error, please contact
    the <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a>.
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    Si usted cree que esto es un error del servidor, por favor comun&iacute;queselo al
    <a href="mailto:<!--#echo encoding="none" var="SERVER_ADMIN" -->">administrador
    del portal</a>.
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    Si vous pensez qu'il s'agit d'une erreur du serveur, veuillez contacter le 
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmestre</a>.
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    M&aacute; cheapann t&uacute; gur earr&aacute;id fhreastala&iacute; &iacute; seo,
    t&eacute;igh i dteagmh&aacute;il leis an 
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">
    sti&uacute;rth&oacute;ir gr&eacute;as&aacute;in</a>, le do thoil.
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    Se pensi che questo sia un errore del server, per favore contatta il 
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a>.
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    サーバーの障害と思われる場合は、<a 
    href="mailto:<!--#echo encoding="none" var="SERVER_ADMIN" -->"
    >ウェブ管理者</a>までご連絡ください。
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    만약 이것이 서버 오류라고 생각되면,
    <a href="mailto:<!--#echo encoding="none" var="SERVER_ADMIN" -->">웹 관리자</a>에게 연락하시기 바랍니다.
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    Indien u van oordeel bent dat deze server in fout is, gelieve
    de <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a> te contacteren.
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    Om du tror dette skyldes en serverfeil, venligst kontakt
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webansvarlig</a>.
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    Je&#347;li my&#347;lisz, &#380;e jest to b&#322;&#261;d tego serwera, skontaktuj si&#281; z
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">administratorem</a>.
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    Se voc&ecirc; acredita ter encontrado um problema no servidor,
    por favor entre em contato com o 
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a>.
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    Se considera que o servidor est&aacute; errado, por favor contacte o
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a>.
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    Va rugam sa il contactati pe
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a>
    in cazul in care credeti ca aceasta este o eroare a serverului.
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    Если Вы считаете, что это ошибка сервера, пожалуйста, сообщите об этом
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">веб-мастеру</a>.
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    Ако мислите да је ово грешка сервера, молимо обавестите
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">вебмастера</a>.
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    Om du tror att detta beror p&aring; ett serverfel, v&auml;nligen kontakta 
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webbansvarig</a>.
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    Bunun bir sunucu hatas&#305; oldu&#287;unu dü&#351;ünüyorsan&#305;z, lütfen
    <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">site
    yöneticisi</a> ile ileti&#351;ime geçin.
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    如果您认为这是一个服务器错误,请联系<a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">网站管理员</a>。
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    如果您認為這是一個伺服器錯誤,請聯繫<a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">網站管理員</a>。
    ----------zh-tw--
    ���������������������������������httpd-2.4.64/docs/error/HTTP_GONE.html.var����������������������������������������������������������0000664�0001751�0001751�00000040273�13317763731�017770� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Zdroj již není dále dostupný!"
    --><!--#include virtual="include/top.html" -->
    
        Požadované URL již není na tomto serveru k dispozici, ani není k dispozici
        žádná adresa k přesměrování.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
      
        Informujte, prosím, autora
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">odkazující
        stránky</a>, že odkaz je zastaralý.
       
      <!--#else -->
      
        Pokud jste následovali odkaz z&nbsp;cizí stránky, kontaktujte, prosím,
        jejího autora.
    
      <!--#endif -->
      
    <!--#include virtual="include/bottom.html" --> 
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Objekt nicht mehr verf&uuml;gbar!"
    --><!--#include virtual="include/top.html" -->
    
        Der angeforderte URL existiert auf dem Server nicht mehr
        und wurde dauerhaft entfernt.
        Eine Weiterleitungsadresse ist nicht verf&uuml;gbar.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Bitte informieren Sie den Autor der
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">verweisenden
        Seite</a>, dass der Link nicht mehr aktuell ist.
    
      <!--#else -->
    
        Falls Sie einem Link von einer anderen Seite gefolgt sind,
        informieren Sie bitte den Autor dieser Seite hier&uuml;ber.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Resource is no longer available!"
    --><!--#include virtual="include/top.html" -->
    
        The requested URL is no longer available on this server and there is no
        forwarding address.
      
      <!--#if expr="-n v('HTTP_REFERER')" -->
      
        Please inform the author of the
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">referring
        page</a> that the link is outdated.
       
      <!--#else -->
      
        If you followed a link from a foreign page, please contact the
        author of this page.
       
      <!--#endif -->
      
    <!--#include virtual="include/bottom.html" --> 
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;El recurso ya no est&aacute; disponible!" -->
    <!--#include virtual="include/top.html" -->
    
        La URL solicitada ya no est&aacute; disponible en este servidor y
       no existe una direcci&oacute;n a la cual remitirle.
    
       <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Por favor, comunique al autor de la
        <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->">p&aacute;gina
        que le ha remitido</a> que la URL est&aacute; obsoleta.
    
      <!--#else -->
    
        Si usted ha seguido un enlace de una p&aacute;gina externa,
        por favor contacte con el autor de esa p&aacute;gina.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Cette ressource n'existe plus!"
    --><!--#include virtual="include/top.html" -->
    
        L'URL demand&eacute;e n'est plus accessible sur ce serveur et il
        n'y a pas d'adresse de redirection. 
    
      <!--#if expr="-n v('HTTP_REFERER')" --> 
    
        Nous vous prions d'informer l'auteur de
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">la 
        page en question</a> que la r&eacute;f&eacute;rence n'est plus valable.
    
      <!--#else --> 
    
        Si vous avez suivi une r&eacute;f&eacute;rence issue d'une page autre, 
        veuillez contacter l'auteur de cette page.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Acmhainn imithe!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute;l an URL iarraithe ar f&aacute;il ar an fhreastala&iacute; seo 
        a thuilleadh, agus n&iacute;l aon seoladh nua ann d&oacute;.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Cur in &uacute;il do &uacute;adar an
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">leathanach
        thagarthach</a> go bhfuil an nasc as-d&aacute;ta, le do thoil.
    
      <!--#else -->
    
        M&aacute; leanf&aacute; nasc &oacute; leathanach iasachta, t&eacute;igh i
        dteaghmh&aacute;il le &uacute;adar an leathanach sin, le do thoil.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="La risorsa non &egrave; pi&ugrave; disponibile!"
    --><!--#include virtual="include/top.html" -->
    
        L'URL richiesto non &egrave; pi&ugrave; disponibile su questo server
        e non esistono indirizzi verso i quali sia possibile inoltrare
        la richiesta.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Per favore, informa l'autore della
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">pagina
        di provenienza</a> che il link non &egrave; pi&ugrave; valido.
    
      <!--#else -->
    
        Se sei arrivato da una pagina esterna, informa l'autore della
        pagina di provenienza che il link non &egrave; pi&ugrave; valido.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Resource is no longer available!"
    --><!--#include virtual="include/top.html" -->
    
        要求された URL は既に本サーバでは利用できませんし、
        移動先もわかりません。
      
      <!--#if expr="-n v('HTTP_REFERER')" -->
      
        <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->"
        >参照元ページ</a>の著者に、
        リンクが古くなっていることをご連絡ください。
       
      <!--#else -->
      
        他のページからのリンクを辿ってきた場合は、
        そのページの著者にご連絡ください。
       
      <!--#endif -->
      
    <!--#include virtual="include/bottom.html" --> 
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="객체가 없어졌음!"
    --><!--#include virtual="include/top.html" -->
    
       요청한 URL은 더 이상 이 서버에 남아있지 않으며,
       그 객체가 옮겨진 다른 URL 역시 남아있지 않습니다.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->">이전
        페이지</a>의 만든이에게 주소가 잘못되었다고 알려주시기 바랍니다.
    
      <!--#else -->
    
        다른 페이지의 링크를 따라오셨다면, 그 페이지의 만든이에게 연락을 하시기
        바랍니다.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Dit object is niet langer beschikbaar!"
    --><!--#include virtual="include/top.html" -->
    
       De gevraagde URL is niet langer beschikbaar op deze server en er is geen
       doorverwijsadres.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
       Gelieve aan de auteur van
       <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">deze pagina</a>
       te melden dat deze link niet langer actueel is.
    
      <!--#else -->
    
       Indien u deze link hebt gekregen van een andere pagina, gelieve
       de auteur van deze pagina te contacteren.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Ressursen er ikke lenger tilgjengelig!"
    --><!--#include virtual="include/top.html" -->
    
        Den ønskede adressen er ikke lenger tilgjengelig hos denne
        serveren og det finnes ingen adresse for videresending.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Venligst informer forfatteren bak 
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">den
        aktuelle siden</a> om at lenken er utdatert.
     
      <!--#else -->
    
        Om du fulgte en lenke fra en ekstern side, venligst kontakt
        forfatteren bak den siden.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Zas&#243;b usuni&#281;ty!"
    --><!--#include virtual="include/top.html" -->
    
        Poszukiwany zas&#243;b nie jest ju&#380; dost&#281;pny na tym serwerze i nie
        podano nowego adresu zasobu.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Prosimy poinformowa&#263; autora
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">referuj&#261;cej
        strony</a> o nieaktualnym linku.
    
      <!--#else -->
    
        Je&#347;li pod&#261;&#380;y&#322;e&#347; za linkiem z innej strony, skontaktuj si&#281; z jej
        autorem.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Recurso n&atilde;o dispon&iacute;vel!"
    --><!--#include virtual="include/top.html" -->
    
       A URL solicitada n&atilde;o est&aacute; dispon&iacute;vel neste servidor
       e n&atilde;o existe um endere&ccedil;o alternativo.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
       Por favor informe o autor da
       <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">p&aacute;gina
       referida</a> que a URL est&aacute; desatualizada.
    
      <!--#else -->
    
       Se voc&ecirc; seguiu um "link" de uma p&aacute;gina externa, por favor
       entre em contato com o autor desta p&aacute;gina e o informe sobre a
       mudan&ccedil;a do "link".
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Recurso n&atilde;o dispon&iacute;vel!"
    --><!--#include virtual="include/top.html" -->
    
    	O URL desejado j&aacute; n&atilde;o est&aacute; dispon&iacute;vel
    	neste servidor e n&atilde;o existe endere&ccedil;o alternativo.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
    	Por favor informe o autor da
    	<a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">p&aacute;gina
    	origin&aacute;ria</a> que a hiperliga&ccedil;&atilde;o est&aacute;
    	desactualizada.
    
      <!--#else -->
    
    	Se chegou aqui a partir de uma hiperliga&ccedil;&atilde;o externa,
    	por favor contacte o autor dessa p&aacute;gina.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Resursa nu mai este disponibila!"
    --><!--#include virtual="include/top.html" -->
    
        URL-ul cerut nu mai este disponibil pe acest server si nu
        exista o adresa de inaintare.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Va rugam informati autorul
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">paginii
        referite</a> ca link-ul nu mai este de actualitate.
    
      <!--#else -->
    
        Va rugam contactati autorul acestei pagini daca ati urmat
        un link dintr-o pagina externa.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Документ удалён!"
    --><!--#include virtual="include/top.html" -->
    
        Документ удалён, и адрес перенаправления отсутствует.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Пожалуйста, сообщите автору
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">страницы</a>,
        ссылающейся на документ, что ссылка устарела.
    
      <!--#else -->
    
        Если Вы обратились к документу по ссылке с другой страницы, пожалуйста,
        сообщите её автору об ошибке.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Ресурс није више доступан!"
    --><!--#include virtual="include/top.html" -->
    
        Захтевани УРЛ није више доступан на овом серверу и нема
        адресе на коју бисте могли бити прослеђени.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Молимо обавестите аутора
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">исходишне
        странице</a> да је веза застарела.
    
      <!--#else -->
    
        Ако сте пратили везу са спољне странице, молимо обавестите
        аутора те странице.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Resursen inte l&auml;ngre tillg&auml;nglig!"
    --><!--#include virtual="include/top.html" -->
    
        Den &ouml;nskade adressen &auml;r inte l&auml;ngre tillg&auml;nglig hos
        denna server och det finns inte n&aring;gon adress f&ouml;r vidarebefodran.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        V&auml;nligen informera f&ouml;rfattaren bakom 
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">den aktuella
        sidan</a> att l&auml;nken &auml;r inaktuell.
     
      <!--#else -->
    
        Om du f&ouml;ljde en l&auml;nk fr&aring;n en extern sida, v&auml;nligen
        kontakta f&ouml;rfattaren av den sidan.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Özkaynak artık mevcut değil!"
    --><!--#include virtual="include/top.html" -->
    
        Talep ettiğiniz URL artık kullanılabilir değil
        ve herhangi bir yönlendirme de mevcut değil.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
      
        Lütfen
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">istenen sayfanın</a>
        yazarına, bu bağlantının güncel olmadığını bildirin.
       
      <!--#else -->
      
        Başka bir sunucudaki bir bağlantıyı izleyerek buraya geldiyseniz,
        lütfen sözkonusu sayfanın yazarına bağlantının güncel olmadığını bildirin.
       
      <!--#endif -->
      
    <!--#include virtual="include/bottom.html" --> 
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="资源不再可用!"
    --><!--#include virtual="include/top.html" -->
    
        您请求的 URL 在此服务器上不再可用,且没有设置转发的地址。
      
      <!--#if expr="-n v('HTTP_REFERER')" -->
      
        请通知<a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">来源页面</a>的作者,该链接已过期。
       
      <!--#else -->
      
        如果您从外部页面的一个链接访问,请联系该页面的作者。
       
      <!--#endif -->
      
    <!--#include virtual="include/bottom.html" --> 
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="資源不再可用!"
    --><!--#include virtual="include/top.html" -->
    
        您請求的 URL 在此伺服器上不再可用,且沒有設置轉發的位址。
      
      <!--#if expr="-n v('HTTP_REFERER')" -->
      
        請通知<a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">來源頁面</a>的作者,該連結已過期。
       
      <!--#else -->
      
        如果您從外部頁面的一個連結訪問,請聯繫此頁面的作者。
       
      <!--#endif -->
      
    <!--#include virtual="include/bottom.html" --> 
    ----------zh-tw--
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_FORBIDDEN.html.var�����������������������������������������������������0000664�0001751�0001751�00000034247�13317763731�020540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Přístup odmítnut!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Nemáte právo pro přístup do požadovaného adresáře. Buď neexistuje žádný
        dokument s&nbsp;obsahem (tzv. index), nebo je adresář chráněn proti čtení.
    
      <!--#else -->
    
        Nemáte právo pro přístup k&nbsp;požadovanému objektu.
        Buď je chráněn proti čtení, nebo není serverem čitelný.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Zugriff verweigert!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Der Zugriff auf das angeforderte Verzeichnis ist nicht m&ouml;glich.
        Entweder ist kein Index-Dokument vorhanden oder das Verzeichnis
        ist zugriffsgesch&uuml;tzt.
    
      <!--#else -->
    
        Der Zugriff auf das angeforderte Objekt ist nicht m&ouml;glich.
        Entweder kann es vom Server nicht gelesen werden oder es
        ist zugriffsgesch&uuml;tzt.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Access forbidden!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        You don't have permission to access the requested directory.
        There is either no index document or the directory is read-protected.
    
      <!--#else -->
    
        You don't have permission to access the requested object.
        It is either read-protected or not readable by the server.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Acceso prohibido!" -->
    <!--#include virtual="include/top.html" -->
    
       <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
          Usted no tiene permiso para acceder al directorio solicitado.
          No existe un documento &iacute;ndice, o el directorio est&aacute;
          protegido contra lectura.
    
      <!--#else -->
    
          Usted no tiene permiso para acceder al objeto solicitado.
          El objeto est&aacute; protegido contra lectura o
          el servidor no puede leerlo.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Acc&egrave;s interdit!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Vous n'avez pas le droit d'acc&eacute;der au r&eacute;pertoire
        demand&eacute;. Soit il n'y a pas de document index soit le r&eacute;pertoire
        est prot&eacute;g&eacute;.
    
      <!--#else -->
    
        Vous n'avez pas le droit d'acc&eacute;der &agrave; l'objet
        demand&eacute;. Soit celui-ci est prot&eacute;g&eacute;, soit il ne peut
        &ecirc;tre lu par le serveur.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Rochtain neamh-cheadaithe!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        N&iacute;l cead agat rochtain a dh&eacute;anamh ar an comhadlann faoi
        iarratais.  Is f&eacute;idir nach bhfuil aon doicim&eacute;ad
        inn&eacute;acs, n&oacute; go bhfuil cosaint ar l&eacute;mh an comhadlann.
    
      <!--#else -->
    
        N&iacute;l cead agat rochtain a dh&eacute;anamh ar an aidhm faoi iarratais.
        Is f&eacute;idir go bhfuil cosaint ar l&eacute; air, n&oacute; go bhfuil
        s&eacute; dol&eacute;ite don freastala&iacute;.
        
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Accesso negato!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
       Non disponi dei permessi necessari per accedere alla
       directory richiesta oppure non esiste il documento indice.
    
      <!--#else -->
    
       Non disponi dei permessi necessari per accedere all'oggetto
       richiesto, oppure l'oggetto non pu&ograve; essere letto dal server.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Access forbidden!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        要求されたディレクトリへのアクセス権限がありません。
        インデックスドキュメントが存在しないか、
        ディレクトリの読み込みが許可されていません。
    
      <!--#else -->
    
        要求されたオブジェクトへのアクセス権がありません。
        読み込みが許可されていないか、
        サーバが読み込みに失敗したかでしょう。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="접근이 거부됨!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
       요청한 디렉토리에 접근할 수 있는 권한이 없습니다.
       디렉토리에 첫 페이지가 없거나 아니면 읽기 보호가 되어 있습니다.
    
      <!--#else -->
    
       요청한 객체에 접근할 수 있는 권한이 없습니다.
       읽기 보호가 되어 있거나 웹서버가 읽을 수 없도록 되어 있습니다.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Toegang verboden!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
       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.
    
      <!--#else -->
    
       U hebt niet de toestemming om toegang te krijgen tot de gevraagde map.
       Die is ofwel beveiligd tegen lezen of onleesbaar door de server.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Adgang forbudt!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Du har ikke tilstrekkelige rettigheter for å få tilgang til den
        ønskede katalogen. Det eksisterer ikke et indeksdokument, eller
        katalogen er lesebeskyttet.
    
      <!--#else -->
    
        Du har ikke tilstrekkelige rettigheter for å få adgang til det
        ønskede dokumentet. Objektet er lesebeskyttet, eller ikke lesbart
        for serveren.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Zabroniony dost&#281;p!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Nie masz prawa dost&#281;pu do &#380;&#261;danego katalogu. W katalogu nie
        ma indeksu lub katalog jest zabezpieczony przed odczytem.
    
      <!--#else -->
    
        Nie masz dost&#281;pu do &#380;&#261;danego obiektu. Jest on zabezpieczony
        przed odczytem lub nie mo&#380;e by&#263; odczytany przez serwer.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Acesso Proibido!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
       Voc&ecirc; n&atilde;o tem permiss&atilde;o para acessar o 
       diret&oacute;rio requisitado.
       Pode n&atilde;o existir o arquivo de &iacute;ndice ou 
       o diret&oacute;rio pode estar protegido contra leitura.
    
      <!--#else -->
    
       Voc&ecirc; n&atilde;o tem permiss&atilde;o para acessar o 
       objeto requisitado. Ele pode estar protegido contra leitura ou 
       n&atilde;o ser leg&iacute;vel pelo servidor.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Acesso proibido!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
    	N&atilde;o tem permiss&atilde;o para aceder ao direct&oacute;rio
    	que deseja. Ou n&atilde;o existe o documento de &iacute;ndice
    	ou o direct&oacute;rio est&aacute; protegido contra leitura.
    
      <!--#else -->
    
    	N&atilde;o tem permiss&atilde;o para aceder ao objecto
    	que deseja. Este est&aacute; protegido contra leitura ou
    	o servidor n&atilde;o o consegue ler.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Accesul interzis!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Nu aveti permisiunea sa accesati directorul cerut.
        Nu este nici un document index sau directorul este protejat la citire.
    
      <!--#else -->
    
        Nu aveti permisiunea sa accesati obiectul cerut.
        Este protejat la citire sau nu poate fi citit de server.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Доступ запрещён!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        У Вас нет прав доступа к этой директории.
        Отсутствует индексный файл, или директория недоступна для чтения.
    
      <!--#else -->
    
        У Вас нет прав доступа к этому объекту.
        Файл недоступен для чтения, или сервер не может его прочитать.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Забрањен приступ!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Немате дозволу да приступите захтеваном директоријуму.
        Могуће је да нема индексног документа, или да је директоријум заштићен од читања.
    
      <!--#else -->
    
        Немате дозволу да приступите захтеваном објекту.
        Могуће је да је заштићен од читања, или да га сервер не може прочитати.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="&Aring;tkomst f&ouml;rbjuden!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Du har inte tillr&auml;ckliga r&auml;ttigheter f&ouml;r att f&aring;
        tillg&aring;ng till den &ouml;nskade katalogen. Det existerar inget
        indexdokument eller s&aring; &auml;r katalogen l&auml;sskyddad.
    
      <!--#else -->
    
        Du har inte tillr&auml;ckliga r&auml;ttigheter f&ouml;r att f&aring;
        tillg&aring;ng till det &ouml;nskade objektet. Objektet &auml;r
        l&auml;sskyddat eller inte l&auml;sbart f&ouml;r servern.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Erişim engellendi!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        Talep ettiğiniz dizine erişim izniniz yok.
        Ya dizin içerik dosyası yok, ya da dizin okumaya karşı korumalı.
    
      <!--#else -->
    
        Talep ettiğiniz dizine erişim izniniz yok.
        Dizin, ya okumaya karşı korumalı 
        ya da sunucu tarafından okunamıyor.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="禁止访问!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        您无权访问所请求的目录。
        这是由于没有主页或该目录不允许被读取导致的。
    
      <!--#else -->
    
        您无权访问所请求的对象。
        它可能不允许被读取或无法被服务器读取。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="禁止訪問!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="v('REDIRECT_URL') =~ m:/$:" -->
    
        您無權訪問所請求的目錄。
        這是由於沒有主頁或該目錄不允許被讀取導致的。
    
      <!--#else -->
    
        您無權訪問所請求的物件。
        它可能不允許被讀取或無法被伺服器讀取。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_METHOD_NOT_ALLOWED.html.var��������������������������������������������0000664�0001751�0001751�00000020264�13317763731�022105� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Metoda nepovolena!"
    --><!--#include virtual="include/top.html" -->
    
        Metoda <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        není pro požadované URL povolena.
        
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Methode nicht erlaubt!"
    --><!--#include virtual="include/top.html" -->
    
        Die <!--#echo var="REDIRECT_REQUEST_METHOD" -->-Methode
        ist f&uuml;r den angeforderten URL nicht erlaubt.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Method not allowed!"
    --><!--#include virtual="include/top.html" -->
    
        The <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        method is not allowed for the requested URL.
        
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;M&eacute;todo no permitido!" -->
    <!--#include virtual="include/top.html" -->
    
        No se permite el m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD" -->  
        para la URL solicitada.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="M&eacute;thode interdite!"
    --><!--#include virtual="include/top.html" -->
    
        La m&eacute;thode <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        n'est pas utilisable pour l'URL demand&eacute;e.
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Modh neamhcheadaithe!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute;l cead an modh 
        <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        a &uacute;as&aacute;id leis an URL iarraithe.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Metodo non consentito!"
    --><!--#include virtual="include/top.html" -->
    
        Il metodo <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        non &egrave; consentito per l'URL richiesto.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Method not allowed!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD"-->
        メソッドは、要求された URL に対しては許可されていません。
        
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="허용되지 않는 요청 방식!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo encoding="none" var="REDIRECT_REQUEST_METHOD"--> 방식은
        요청한 URL에 사용할 수 없습니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Type methode niet toegelaten!"
    --><!--#include virtual="include/top.html" -->
    
        Het <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        type methode is niet toegelaten voor de gevraagde URL.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Metoden er ikke tillatt!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> metoden er ikke
        tillatt for den forespurte adressen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Niedozwolona metoda!"
    --><!--#include virtual="include/top.html" -->
    
        Metoda <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        jest niedozwolona dla podanego URL-a.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="M&eacute;todo n&atilde;o permitido!"
    --><!--#include virtual="include/top.html" -->
    
        O m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        n&atilde;o &eacute; permitido para a URL requisitada.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="M&eacute;todo n&atilde;o permitido!"
    --><!--#include virtual="include/top.html" -->
    
    	O m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD" --> n&atilde;o
    	&eacute; permitido para o URL pedido.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Metoda nepermisa!"
    --><!--#include virtual="include/top.html" -->
    
        Metoda <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        nu este permisa pentru URL-ul cerut.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Метод не поддерживается!"
    --><!--#include virtual="include/top.html" -->
    
        Метод <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        нельзя применить к запрашиваемому ресурсу.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Метод није дозвољен!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        метод није дозвољен за захтевани УРЛ.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Metoden inte till&aring;ten!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        metoden &auml;r inte till&aring;ten f&ouml;r den f&ouml;rfr&aring;gade
        adressen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Yönteme izin verilmedi!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        yöntemi istediğiniz URL için kullanılamaz.
        
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="请求的方法不允许!"
    --><!--#include virtual="include/top.html" -->
    
        在请求的 URL 上不允许使用
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> 方法。
        
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="請求的方法不允許!"
    --><!--#include virtual="include/top.html" -->
    
        在請求的 URL 上不允許使用
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> 方法。
        
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var��������������������������������������0000664�0001751�0001751�00000022721�13317763731�023115� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Požadovaná entita je příliš velká!"
    --><!--#include virtual="include/top.html" -->
    
        Metoda <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        nedovoluje přenos dat nebo objem dat
        přesahuje kapacitní limit.
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="&Uuml;bergebene Daten zu gro&szlig;!"
    --><!--#include virtual="include/top.html" -->
    
        Die bei der Anfrage &uuml;bermittelten Daten sind f&uuml;r
        die <!--#echo var="REDIRECT_REQUEST_METHOD" -->-Methode
        nicht erlaubt oder die Datenmenge hat das Maximum &uuml;berschritten.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Request entity too large!"
    --><!--#include virtual="include/top.html" -->
    
        The <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        method does not allow the data transmitted, or the data volume
        exceeds the capacity limit.
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;La entidad solicitada es demasiado grande!" -->
    <!--#include virtual="include/top.html" -->
    
       El m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD"-->
       no permite transmitir la informaci&oacute;n, o el
       volumen de la informaci&oacute;n excede los l&iacute;mites
       de capacidad del mismo.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Volume de la demande trop grand!"
    --><!--#include virtual="include/top.html" -->
    
        La m&eacute;thode <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        n'autorise pas le transfert de ces donn&eacute;es ou bien le volume
        des donn&eacute;es exc&egrave;de la limite de capacit&eacute;.
    
    <!--#include virtual="include/bottom.html" -->               
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Iarratais ar aon&aacute;n r&oacute;mh&oacute;r!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute; ligeann an modh <!--#echo var="REDIRECT_REQUEST_METHOD" --> an
        tarchur sonra&iacute;ocht tr&iacute;d, n&oacute; t&aacute; an m&eacute;id
        sonra&iacute;ocht breis ar an teoireann cumas.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Richiesta troppo grande!"
    --><!--#include virtual="include/top.html" -->
    
        Il metodo <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        non consente di trasferire dati, oppure la quantit&agrave; di dati
        richiesti &egrave; eccessiva.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Request entity too large!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD"-->
        メソッドがデータの送信を許可していないか、
        データ量が許容量を超えています。
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="너무 긴 요청!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo encoding="none" var="REDIRECT_REQUEST_METHOD"--> 방식의
        요청으로는 내용을 보낼 수 없거나, 또는 보내온 내용이 그 방식에서 허용하는
        최대 길이를 넘었습니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Volume van gevraagde entiteit te groot!"
    --><!--#include virtual="include/top.html" -->
    
      Het <!--#echo var="REDIRECT_REQUEST_METHOD" --> type methode laat niet toe
      data te versturen of het datavolume is groter dan maximaal toegelaten.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="For stor enhet i forspørsel!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> metoden tillater ikke
        de sendte data eller så overskrider datamengenden
        kapasitetsbegrensningen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="&#379;&#261;dany obiekt zbyt du&#380;y!"
    --><!--#include virtual="include/top.html" -->
    
        Metoda <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        nie zezwala na typ przesy&#322;anych danych lub rozmiar danych przekracza
        ustalony limit.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Volume da dados muito grande!"
    --><!--#include virtual="include/top.html" -->
    
        O m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        n&atilde;o permite a transmiss&atilde;o dos dados,
        ou o volume de dados excede a capacidade limite.
      
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Volume de dados demasiado grande!"
    --><!--#include virtual="include/top.html" -->
    
    	O m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD" -->
    	n&atilde;o permite todos os dados que foram transmitidos,
    	ou o volume de dados excede o limite da capacidade.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Entitate ceruta prea mare!"
    --><!--#include virtual="include/top.html" -->
    
        Metoda <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        nu permite transmiterea datelor, sau volumul de date
        depaseste limita capacitatii.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Размер запроса слишком велик!"
    --><!--#include virtual="include/top.html" -->
    
        Тип передаваеиых данных запрещён методом <!--#echo var="REDIRECT_REQUEST_METHOD" -->,
        или размера тела запроса слишком велик.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Request entity too large!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        метод не дозвољава пренос ових података, или количина података
        премашује ограничења могућности.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="F&ouml;r stor enhet vid f&ouml;rfr&aring;gan!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> metoden till&aring;ter
        inte den skickade datan eller s&aring; &ouml;verskrider datavolymen
        kapacitetsniv&aring;n.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="İstenen öğe çok büyük!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> yöntemi ya veri aktarımına
        izin vermiyor ya da veri hacmi işlenemeyecek kadar büyük.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="请求体过大!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> 方法不允许传输数据,或数据量超过容量限制。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="請求體過大!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> 方法不允許傳輸資料,或資料量超過容量限制。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    �����������������������������������������������httpd-2.4.64/docs/error/HTTP_BAD_REQUEST.html.var���������������������������������������������������0000664�0001751�0001751�00000020165�13317763731�021034� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Chybný požadavek!"
    --><!--#include virtual="include/top.html" -->
    
        Váš prohlížeč (nebo proxy server) vyslal požadavek,
        kterému tento server nerozuměl.
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Fehlerhafte Anfrage!"
    --><!--#include virtual="include/top.html" -->
    
        Ihr Browser (oder Proxy) hat eine ung&uuml;ltige Anfrage
        gesendet, die vom Server nicht beantwortet werden kann.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Bad request!"
    --><!--#include virtual="include/top.html" -->
    
        Your browser (or proxy) sent a request that
        this server could not understand.
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Petici&oacute;n err&oacute;nea!" -->
    <!--#include virtual="include/top.html" -->
    
        Su navegador (o 'proxy') ha enviado una petici&oacute;n
        que el servidor no ha podido entender.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Demande incorrecte!"
    --><!--#include virtual="include/top.html" -->
    
        Votre navigateur (ou votre proxy) a envoy&eacute;
        une demande que ce serveur n'a pas comprise.
    
    <!--#include virtual="include/bottom.html" -->  
    ----------fr--
    
    Content-language: ga 
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Iarratas m&iacute;cheart!"
    --><!--#include virtual="include/top.html" -->
    
        Seol do chuid brabhs&aacute;la&iacute; (n&oacute;
        seachfhreastala&iacute;) freagairt n&aacute;rbh fh&eacute;idir leis an
        fhreastala&iacute; seo a thuisceant.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Richiesta incomprensibile!"
    --><!--#include virtual="include/top.html" -->
    
        Il tuo browser (o il proxy) ha inviato a
        questo server una richiesta incomprensibile.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Bad request!"
    --><!--#include virtual="include/top.html" -->
    
        お使いのブラウザ (またはプロクシ)
        が、サーバの理解できないリクエストを送信しました。
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="잘못된 요청!"
    --><!--#include virtual="include/top.html" -->
    
        브라우저 또는 프록시가
        이 서버가 처리할 수 없는 잘못된 요청을 보냈습니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Slechte vraag!"
    --><!--#include virtual="include/top.html" -->
    
        Uw browser (of proxy) stuurde een vraag die
        deze server niet kon begrijpen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Ugyldig spørring!"
    --><!--#include virtual="include/top.html" -->
    
        Din nettleser eller proxy sendte en forespørsel
        som denne serveren ikke kunne forstå.
    
    <!--#include virtual="include/bottom.html" -->  
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Nieprawid&#322;owe &#380;&#261;danie!"
    --><!--#include virtual="include/top.html" -->
    
        Twoja przegl&#261;darka (lub serwer po&#347;rednicz&#261;cy) wys&#322;a&#322; &#380;&#261;danie,
        kt&#243;rego ten serwer nie potrafi obs&#322;u&#380;y&#263;.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Requisi&ccedil;&atilde;o Inv&aacute;lida!"
    --><!--#include virtual="include/top.html" -->
    
        Seu "browser" (ou o servidor proxy) enviou uma
        requisi&ccedil;&atilde;o inv&aacute;lida ao servidor.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Pedido incorrecto!"
    --><!--#include virtual="include/top.html" -->
    
    	O seu <i>browser</i> ou <i>proxy</i> enviou
    	um pedido que este servidor n&atilde;o compreendeu.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Cerere incomprensibila!"
    --><!--#include virtual="include/top.html" -->
    
        Browserul (sau proxy-ul) dumneavoastra a trimis
        serverului o cerere ce nu poate fi procesata.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Неверный запрос!"
    --><!--#include virtual="include/top.html" -->
    
        Запрос, посланный Вашим браузером (или прокси-сервером),
        содержит ошибку и не может быть обработан.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Лош захтев!"
    --><!--#include virtual="include/top.html" -->
    
        Ваш читач (или посреднички сервер) послао је захтев који
        овај сервер није могао да разуме.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Felaktig f&ouml;rfr&aring;gan!"
    --><!--#include virtual="include/top.html" -->
    
        Din webbl&auml;sare eller proxy skickade en f&ouml;rfr&aring;gan
        som denna server inte kunde f&ouml;rst&aring;.
    
    <!--#include virtual="include/bottom.html" -->  
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Hatalı istek!"
    --><!--#include virtual="include/top.html" -->
    
        Tarayıcınız (veya vekil sunucunuz) bu sunucunun
        anlayamadığı bir istekte bulundu.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="无效请求!"
    --><!--#include virtual="include/top.html" -->
    
        您的浏览器(或代理)发送了一个服务器无法解析的请求。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="請求錯誤!"
    --><!--#include virtual="include/top.html" -->
    
        您的瀏覽器(或代理)發送了一個伺服器無法解析的請求。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_LENGTH_REQUIRED.html.var�����������������������������������������������0000664�0001751�0001751�00000022317�13317763731�021520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Chybná hlavička Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        Požadavek metodou <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        vyžaduje korektní hlavičku <code>Content-Length</code>.
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Content-Length-Angabe fehlerhaft!"
    --><!--#include virtual="include/top.html" -->
    
        Die Anfrage kann nicht beantwortet werden.
        Bei Verwendung der <!--#echo var="REDIRECT_REQUEST_METHOD" -->-Methode
        mu&szlig; ein korrekter <code>Content-Length</code>-Header
        angegeben werden. 
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Bad Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        A request with the <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        method requires a valid <code>Content-Length</code> header.
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Error en la longitud del contenido!" -->
    <!--#include virtual="include/top.html" -->
    
        Una petici&oacute;n con el m&eacute;todo <!--#echo
        var="REDIRECT_REQUEST_METHOD" -->  requiere que el encabezado 
        <code>Content-Length</code> sea v&aacute;lido.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Longueur du contenu ill&eacute;gal!"
    --><!--#include virtual="include/top.html" -->
    
        Une requ&ecirc;te utilisant la m&eacute;thode <!--#echo
        var="REDIRECT_REQUEST_METHOD" --> n&eacute;cessite un en-t&ecirc;te
        <code>Content-Length</code> (indiquant la longueur) valable.
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Content-Length m&iacute;cheart!"
    --><!--#include virtual="include/top.html" -->
    
        Is g&aacute; go mbh&eacute;adh ceannt&aacute;isc 
        <code>Content-Length</code>
        bhail&iacute; do iarratais faoin modh 
        <!--#echo var="REDIRECT_REQUEST_METHOD" -->.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Campo Content-Length non valido!"
    --><!--#include virtual="include/top.html" -->
    
        Una richiesta con il metodo
        <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        richiede che venga specificato un header <code>Content-Length</code>
        valido.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Bad Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD"-->
        メソッドのリクエストでは、
        正しい <code>Content-Length</code> ヘッダが必要になります。
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="잘못된 Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo encoding="none" var="REDIRECT_REQUEST_METHOD"--> 방식을 쓰는
        요청은 올바른 <code>Content-Length</code> 헤더도 함께 보내야만 합니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Ongeldige lengte inhoud!"
    --><!--#include virtual="include/top.html" -->
    
        Een vraag met het <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        type methode heeft een correcte <code>Content-Length</code> lijn nodig.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Feil Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        En forespørsel med <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        metoden krever en korrekt <code>Content-Length</code> header.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="B&#322;&#281;dne Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        &#379;&#261;danie <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        wymaga poprawnego nag&#322;&#243;wka <code>Content-Length</code>.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Content-Length Inv&aacute;lido!"
    --><!--#include virtual="include/top.html" -->
    
        Uma requisi&ccedil;&atilde;o 
        do m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD"-->
        requer um cabe&ccedil;alho <code>Content-Length</code> v&aacute;lido.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Content-Length incorrecto!"
    --><!--#include virtual="include/top.html" -->
    
    	Um pedido com o m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD" -->
    	necessita de um cabe&ccedil;alho <code>Content-Length</code> v&aacute;lido.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Content-Length invalid!"
    --><!--#include virtual="include/top.html" -->
    
        O cerere cu metoda <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        necesita un header <code>Content-Length</code> valid.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Неверная длина Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        Запрос с помощью метода <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        должен иметь правильное значение длины в поле <code>Content-Length</code>.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Лоше Content-Length заглавље!"
    --><!--#include virtual="include/top.html" -->
    
        Захтев са <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        методом мора имати исправно <code>Content-Length</code>
        (дужина садржаја) заглавље.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Felaktig Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        En f&ouml;rfr&aring;gan med <!--#echo var="REDIRECT_REQUEST_METHOD" -->
        metoden kr&auml;ver ett korrekt <code>Content-Length</code> huvud.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Hatalı Content-Length başlığı!"
    --><!--#include virtual="include/top.html" -->
    
        <!--#echo var="REDIRECT_REQUEST_METHOD" --> yöntemini kullanan bir istek
        geçerli bir <code>Content-Length</code> (içerik uzunluğu) başlığı gerektirir.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="错误的 Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        对 <!--#echo var="REDIRECT_REQUEST_METHOD" --> 方法的请求必须带有有效的
        <code>Content-Length</code> 头字段。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="錯誤的 Content-Length!"
    --><!--#include virtual="include/top.html" -->
    
        對 <!--#echo var="REDIRECT_REQUEST_METHOD" --> 方法的請求必須帶有有效的
        <code>Content-Length</code> 頭欄位。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_PRECONDITION_FAILED.html.var�������������������������������������������0000664�0001751�0001751�00000017551�13317763731�022144� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Vstupní podmínka selhala!"
    --><!--#include virtual="include/top.html" -->
    
        Vstupní podmínka pro požadavek o&nbsp;zadané URL nesplnila pozitivní
        vyhodnocení.
      
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Vorbedingung verfehlt!"
    --><!--#include virtual="include/top.html" -->
    
        Die f&uuml;r den Abruf der angeforderten URL notwendige
        Vorbedingung wurde nicht erf&uuml;llt.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Precondition failed!"
    --><!--#include virtual="include/top.html" -->
    
        The precondition on the request for the URL failed positive evaluation.
      
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Fallo en la pre-condici&oacute;on!" -->
    <!--#include virtual="include/top.html" -->
    
       No se ha evaluado positivamente la pre-condici&oacute;n 
       de la petici&oacute;n para la URL.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Pr&eacute;condition n&eacute;gative!"
    --><!--#include virtual="include/top.html" -->
    
        La pr&eacute;condition pour l'URL demand&eacute; a &eacute;t&eacute;
        &eacute;valu&eacute;e n&eacute;gativement.
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Theip ar r&eacute;amhchoinn&iacute;oll!"
    --><!--#include virtual="include/top.html" -->
    
        Theip meast&oacute;ireacht an r&eacute;amhchoinn&iacute;oll 
        don iarratais den URL.
        
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Criteri di precondizione non soddisfatti!"
    --><!--#include virtual="include/top.html" -->
    
        I criteri di precondizione per consentire l'invio dell'URL
        richiesto non sono stati soddisfatti.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Precondition failed!"
    --><!--#include virtual="include/top.html" -->
    
        指定された URL へのリクエストにおける事前条件が満たされませんでした。
      
    <!--#include virtual="include/bottom.html" --> 
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="주어진 조건 실패!"
    --><!--#include virtual="include/top.html" -->
    
        미리 주어진 조건이 만족되지 않아서 URL 요청을 처리할 수 없습니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Startvoorwaarde niet voldaan!"
    --><!--#include virtual="include/top.html" -->
    
      Een startvoorwaarde werd niet voldaan bij verwerking van de vraag naar de URL.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Nødvendig forutsetning ikke oppfyllt!"
    --><!--#include virtual="include/top.html" -->
    
        Den nødvendige forutsetningen for forespørselen passerte ikke
        vurderingen med positivt resultat.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Niespe&#322;niony warunek!"
    --><!--#include virtual="include/top.html" -->
    
        Warunek wst&#281;pny dla URL-a nie zosta&#322; spe&#322;niony.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Falha de precondi&ccedil;&atilde;o!"
    --><!--#include virtual="include/top.html" -->
    
        A condi&ccedil;&atilde;o necess&aacute;ria para a
        requisi&ccedil;&atilde;o da URL foi avaliada como falsa.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Pr&eacute;-condi&ccedil;&atilde;o falhou!"
    --><!--#include virtual="include/top.html" -->
    
    	A condi&ccedil;&atilde;o necess&aacute;ria ao pedido do URL
    	foi avaliada com resultado negativo.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Precondition failed!"
    --><!--#include virtual="include/top.html" -->
    
        Preconditionarea pentru cererea URL-ului nu a fost evaluata pozitiv.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Условие ложно!"
    --><!--#include virtual="include/top.html" -->
    
        Условие в запросе к данному ресурсу не было выполнено.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Предуслов није испуњен!"
    --><!--#include virtual="include/top.html" -->
    
        Предуслов за захтев УРЛ-а није испуњен.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="N&ouml;dv&auml;ndig f&ouml;ruts&auml;ttning misslyckades!"
    --><!--#include virtual="include/top.html" -->
    
        Den n&ouml;dv&auml;ndiga f&ouml;ruts&auml;ttningen f&ouml;r
        adressf&ouml;rfr&aring;gan passerade inte utv&auml;rderingen
        med acceptabelt resultat.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Önkoşul sağlanamadı!"
    --><!--#include virtual="include/top.html" -->
    
        URL talebinin önkoşulu olumlanamadı.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="先决条件不成立!"
    --><!--#include virtual="include/top.html" -->
    
        对该 URL 发送的请求,包含的先决条件不成立。
      
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="先決條件不成立!"
    --><!--#include virtual="include/top.html" -->
    
        對該 URL 發送的請求,包含的先決條件不成立。
      
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    �������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_SERVICE_UNAVAILABLE.html.var�������������������������������������������0000664�0001751�0001751�00000023153�13317763731�022141� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Služba není dostupná!"
    --><!--#include virtual="include/top.html" -->
    
        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.
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Zugriff nicht m&ouml;glich!"
    --><!--#include virtual="include/top.html" -->
    
        Der Server ist derzeit nicht in der Lage die Anfrage
        zu bearbeiten. Entweder ist der Server derzeit &uuml;berlastet
        oder wegen Wartungsarbeiten nicht verf&uuml;gbar.
        Bitte versuchen Sie es sp&auml;ter wieder. 
        
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Service unavailable!"
    --><!--#include virtual="include/top.html" -->
    
        The server is temporarily unable to service your
        request due to maintenance downtime or capacity
        problems. Please try again later. 
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Servicio no disponible!" -->
    <!--#include virtual="include/top.html" -->
    
        El servidor no puede procesar su solicitud en este momento
        debido a tareas de mantenimiento o a problemas de capacidad.
        Por favor, int&eacute;ntelo de nuevo m&aacute;s tarde.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Service inaccessible!"
    --><!--#include virtual="include/top.html" -->
    
        En raison de travaux de maintenance ou de probl&egrave;mes
        de capacit&eacute; le serveur n'est pas en mesure de r&eacute;pondre
        &agrave; votre requ&ecirc;te pour l'instant. Veuillez r&eacute;essayer
         plus tard.
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Seirbh&iacute;s do&uacute;s&aacute;idte!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute;l an freastala&iacute; seo in ann do chuid 
        iarratais a l&iacute;onadh ag an am seo, toisc 
        c&oacute;th&aacute;bh&aacute;il n&oacute; fhaidhbeanna cumas.
        D&eacute;an iarracht eile n&iacute;os d&eacute;ana&iacute;, le do thoil.
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Servizio non disponibile!"
    --><!--#include virtual="include/top.html" -->
    
        Il server in questo momento non &egrave; in grado di
        soddisfare la richiesta per motivi di manutenzione
        o di sovraccarico del sistema.
        Per favore, riprova pi&ugrave; tardi.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Service unavailable!"
    --><!--#include virtual="include/top.html" -->
    
        メンテナンスで停止中か、サーバの処理能力の問題のため、
        現在リクエストに応じることができません。
        後ほど再度お試し下さい。
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="서비스 일시중지!"
    --><!--#include virtual="include/top.html" -->
    
        관리 작업이나 용량 문제로 서버가 잠시동안 요청을 처리할 수 없습니다.
        나중에 다시 시도해주시기 바랍니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Dienst niet beschikbaar!"
    --><!--#include virtual="include/top.html" -->
    
        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.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Tjenesten er ikke tilgjengelig!"
    --><!--#include virtual="include/top.html" -->
    
        Serveren er midlertidig ikke i stand til å utføre din
        forespørsel. Vennligst prøv igjen senere.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Serwis niedost&#281;pny!"
    --><!--#include virtual="include/top.html" -->
    
        Serwer nie mo&#380;e zrealizowa&#263; twojego &#380;&#261;dania
        ze wzgl&#281;du na konserwacj&#281; lub zbyt du&#380;e obci&#261;&#380;enie.
        Prosimy spr&#243;bowa&#263; p&#243;&#378;niej.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Servi&ccedil;o indispon&iacute;vel!"
    --><!--#include virtual="include/top.html" -->
    
        O servidor est&aacute; temporariamente fora de servi&ccedil;o
        para manutan&ccedil;&atilde;o ou devido a problemas de capacidade.
        Por favor tente acessar mais tarde.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Servi&ccedil;o indispon&iacute;vel!"
    --><!--#include virtual="include/top.html" -->
    
    	O servidor est&aacute; tempor&aacute;riamente incapaz de servir
    	o seu pedido devido a uma interrup&ccedil;&atilde;o para
    	manuten&ccedil;&atilde;o ou problemas de capacidade. Por favor
    	tente de novo mais tarde.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Serviciu indisponibil!"
    --><!--#include virtual="include/top.html" -->
    
        Serverul nu poate, temporar, sa raspunda cererii
        dumneavoastra datorita intretinerii acestuia sau a
        unor probleme de capacitate. Va rugam incercati mai tarziu.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Сервис недоступен!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер временно не имеет возможности обработать Ваш запрос
        по техническим причинам. Пожалуйста, повторите позже.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Услуга је недоступна!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер тренутно није у могућности да услужи ваш
        захтев пошто је затворен због одржавања или има недовољан
        капацитет. Молимо покушајте поново касније.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Tj&auml;nsten ej tillg&auml;nglig!"
    --><!--#include virtual="include/top.html" -->
    
        Servern &auml;r f&ouml;r tillf&auml;llet of&ouml;rm&ouml;gen att
        utf&ouml;ra din f&ouml;rfr&aring;gan p&aring; grund av underh&aring;ll
        eller kapacitetsbegr&auml;nsningar. V&auml;nligen f&ouml;rs&ouml;k
        igen senare.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Hizmet sunulamıyor!"
    --><!--#include virtual="include/top.html" -->
    
        Sunucu, bakım gerektiren çeşitli sorunlardan ötürü,
        bir süreliğine taleplerinize yanıt veremiyor.
        Lütfen daha sonra tekrar deneyin.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="服务不可用!"
    --><!--#include virtual="include/top.html" -->
    
        由于服务器维护或负载问题,服务器暂时无法处理您的请求。请稍后重试。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="服務不可用!"
    --><!--#include virtual="include/top.html" -->
    
        由於伺服器維護或負載問題,伺服器暫時無法處理您的請求。請稍後重試。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/README����������������������������������������������������������������������0000664�0001751�0001751�00000004333�13317763731�015601� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
     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                            |
      | Chinese (zh-cn/zh-tw) | CodeingBoy & popcorner                   |
      | 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                               |
      | Japanese (ja)         | TAKAHASHI Makoto                         |
      | Korean (ko)           | Jaeho Shin                               |
      | Norwegian Bokmål (nb) | Tom Fredrik Klaussen                     |
      | Polish (pl)           | Tomasz Kepczynski                        |
      | Romanian (ro)         | Andrei Besleaga                          |
      | Russian (ru)          | Alexander Gaganashvili                   |
      | Serbian (sr)          | Nikola Smolenski                         |
      | Spanish (es)          | Karla Quintero                           |
      | Swedish (sv)          | Thomas Sjögren                           |
      | Turkish (tr)          | Emre Sokullu & Nilgün Belma Bugüner      |
      | Irish (ga)            | Noirin Shirley                           |
      +-----------------------+------------------------------------------+
      (Please see http://httpd.apache.org/docs-project/ if you would
       like to contribute the pages in an additional language.)
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_BAD_GATEWAY.html.var���������������������������������������������������0000664�0001751�0001751�00000026512�13317763731�021007� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Chybná brána!"
    --><!--#include virtual="include/top.html" -->
    
        Proxy server obdržel od nadřazeného
        serveru chybnou odpověď.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
        
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Fehlerhaftes Gateway!"
    --><!--#include virtual="include/top.html"-->
    
        Der Proxy-Server erhielt eine fehlerhafte Antwort
        eines &uuml;bergeordneten Servers oder Proxies. 
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
         
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Bad Gateway!"
    --><!--#include virtual="include/top.html" -->
    
        The proxy server received an invalid
        response from an upstream server.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
        
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Puerta de enlace err&oacute;nea!" -->
    <!--#include virtual="include/top.html" -->
    
        El servidor 'proxy' ha recibido; informaci&oacute;n
        no v&aacute;lida del servidor de origen.
    
       <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
          <!--#include virtual="include/spacer.html" -->
          <!--#echo var="REDIRECT_ERROR_NOTES" -->
    
       <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Gateway incorrecte!"
    --><!--#include virtual="include/top.html" -->
    
        Le serveur proxy a re&ccedil;u une r&eacute;ponse
        incorrecte de la part d'un serveur sup&eacute;rieur. 
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->   
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="CONTENT_LANGUAGE" value="ga"
    --><!--#set var="TITLE" value="Geata m&iacute;ceart!"
    --><!--#include virtual="include/top.html" -->
    
        Fuair an seachfhreastala&iacute; freagairt neamhbhail&iacute;
        &oacute; freastala&iacute; thuasthrutha.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Gateway errato!"
    --><!--#include virtual="include/top.html" -->
    
        Il server proxy ha ricevuto una risposta
        non valida dal server precedente.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Bad Gateway!"
    --><!--#include virtual="include/top.html" -->
    
        プロクシサーバは上流サーバから不正な応答を受信しました。
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
        
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="잘못된 게이트웨이!"
    --><!--#include virtual="include/top.html" -->
    
        프록시 서버가 더 윗쪽의 서버로부터 잘못된 응답을 받았습니다.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo  encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Verkeerde Gateway!"
    --><!--#include virtual="include/top.html" -->
    
        De proxy server heeft een ongeldig
        antwoord ontvangen van een gecontacteerde server.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Ugyldig Gateway!"
    --><!--#include virtual="include/top.html" -->
    
        Proxyserveren mottok et ugyldig svar fra
        en oppstrøms server.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->   
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Nieprawid&#322;owa brama!"
    --><!--#include virtual="include/top.html" -->
    
        Serwer otrzyma&#322; nieprawid&#322;ow&#261; odpowied&#378;
        od kolejnego serwera.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Gateway inv&aacute;lido!"
    --><!--#include virtual="include/top.html" -->
    
        O servidor proxy recebeu uma resposta
        inv&aacute;lida do servidor destino.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo  encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Gateway inv&aacute;lida!"
    --><!--#include virtual="include/top.html" -->
    
    	O servidor de <i>proxy</i> recebeu uma resposta
    	inválida de um outro servidor externo a ele.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Gateway invalid!"
    --><!--#include virtual="include/top.html" -->
    
        Serverul proxy a primit un raspuns invalid
        de la serverul precedent.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Неверный шлюз!"
    --><!--#include virtual="include/top.html" -->
    
        Прокси-сервер получил недопустимый ответ от
        вышестоящего сервера.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Лош пролаз!"
    --><!--#include virtual="include/top.html" -->
    
        Посреднички сервер је примио неисправан
        одговор од следећег сервера у низу.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Felaktig Gateway!"
    --><!--#include virtual="include/top.html" -->
    
        Proxyservern mottog ett felaktigt svar fr&aring;n
        en tidigare server.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->   
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Hatalı Ağ Geçidi!"
    --><!--#include virtual="include/top.html" -->
    
        Vekil sunucu üstbirim sunucudan
        anlamsız bir yanıt aldı.
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
        
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="错误的网关!"
    --><!--#include virtual="include/top.html" -->
    
        代理服务器从上游服务器收到了无效的响应。
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
        
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="閘道器錯誤!"
    --><!--#include virtual="include/top.html" -->
    
        代理伺服器從上遊伺服器收到了無效的響應。
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        <!--#include virtual="include/spacer.html" -->
        <!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
      <!--#endif -->
        
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_INTERNAL_SERVER_ERROR.html.var�����������������������������������������0000664�0001751�0001751�00000040774�13317763731�022521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Chyba serveru!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Nastala vnitřní chyba a server nebyl schopen
        dokončit Váš požadavek.
    
        <!--#include virtual="include/spacer.html" -->
    
        Chybová zpráva
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Nastala vnitřní chyba a server nebyl schopen
        dokončit Váš požadavek. Buď je server
        přetížen, nebo došlo k&nbsp;chybě v&nbsp;CGI skriptu.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Serverfehler!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Die Anfrage kann nicht beantwortet werden, da im Server
        ein interner Fehler aufgetreten ist.
    
        <!--#include virtual="include/spacer.html" -->
    
        Fehlermeldung:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Die Anfrage kann nicht beantwortet werden, da im Server
        ein interner Fehler aufgetreten ist.
        Der Server ist entweder &uuml;berlastet oder ein Fehler in
        einem CGI-Skript ist aufgetreten.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Server error!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        The server encountered an internal error and was 
        unable to complete your request.
    
        <!--#include virtual="include/spacer.html" -->
    
        Error message:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        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.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Error del servidor!" -->
    <!--#include virtual="include/top.html" -->
    
        Se ha producido un error interno en el servidor y no
        se ha podido completar su solicitud.
    
       <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
          <!--#include virtual="include/spacer.html" -->
          Mensaje de error:<br />
          <!--#echo var="REDIRECT_ERROR_NOTES" -->
    
       <!--#else -->
    
        Se ha producido un error interno en el servidor y no se
        ha podido completar su solicitud. O el servidor est&aacute;
        sobrecargado o ha habido un fallo en la ejecuci&oacute;n de 
        un programa CGI.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Erreur du serveur!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Le serveur a &eacute;t&eacute; victime d'une erreur interne et n'a pas
        &eacute;t&eacute; capable de faire aboutir votre requ&ecirc;te.
    
        <!--#include virtual="include/spacer.html" -->
    
        Message d'erreur:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Le serveur a &eacute;t&eacute; victime d'une erreur interne et n'a pas
        &eacute;t&eacute; capable de faire aboutir votre requ&ecirc;te.
        Soit le server est surcharg&eacute; soit il s'agit d'une erreur dans
        le script CGI.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->   
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Earr&aacute;id fhreastala&iacute;!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Thit an freastala&iacute; ar earr&aacute;id inmhe&aacute;nach
        agus theip air do chuid iarratais a comhl&iacute;onadh.
    
        <!--#include virtual="include/spacer.html" -->
    
        Teachtaireacht earr&aacute;ide:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Thit an freastala&iacute; ar earr&aacute;id inmhe&aacute;nach
        agus theip air do chuid iarratais a comhl&iacute;onadh.
        Is f&eacute;idir go bhfuil an freastala&iacute; 
        r&oacute;l&oacute;aidithe, n&oacute; go raibh earr&aacute;id 
        i script CGI &eacute;igin.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Errore del server!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Il server ha generato un errore interno e non &egrave;
        in grado di soddisfare la richiesta.
    
        <!--#include virtual="include/spacer.html" -->
    
        Messaggio di errore:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Il server ha generato un errore interno e non &egrave;
        in grado di soddisfare la richiesta. Il server potrebbe
        essere sovraccarico oppure si &egrave; verificato un
        errore in uno script CGI.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Server error!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        サーバ内部で障害が発生し、
        リクエストに応えることができませんでした。
    
        <!--#include virtual="include/spacer.html" -->
    
        Error message:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        サーバ内部で障害が発生し、
        リクエストに応えることができませんでした。
        サーバが過負荷であるか、
        CGI スクリプトにエラーがあります。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="서버 오류!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        
        서버에 내부 오류가 발생하여 요청을 끝까지 처리하지 못했습니다.
    
        <!--#include virtual="include/spacer.html" -->
    
        오류 내용:
        <br /><!--#echo var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        서버에 내부 오류가 생겨 요청을 끝까지 처리하지 못했습니다.
        서버에 과부하가 걸렸거나 아니면 CGI 프로그램에 오류가 있었습니다.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Server fout!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        <!--#include virtual="include/spacer.html" -->
    
        Foutbericht:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        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.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Serverfeil!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
     
        Det inntraff en intern feil hos serveren, og det var ikke mulig å
        gjennomføre din forespørsel.
    
        <!--#include virtual="include/spacer.html" -->
    
        Feilmelding:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Det inntraff en intern feil hos serveren, og det var ikke mulig å
        gjennomføre din forespørsel. Serveren er enten overbelastet, eller
        CGI-skriptet inneholder feil.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="B&#322;&#261;d serwera!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Serwer napotka&#322; b&#322;&#261;d wewn&#281;trzny i nie jest w stanie
        zrealizowa&#263; twojego &#380;&#261;dania.
    
        <!--#include virtual="include/spacer.html" -->
    
        Informacja o b&#322;&#281;dzie:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Serwer napotka&#322; b&#322;&#261;d wewn&#281;trzny i nie jest w stanie
        zrealizowa&#263; twojego &#380;&#261;dania. Serwer jest przeci&#261;&#380;ony lub
        napotka&#322; na b&#322;&#261;d w skrypcie CGI.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Erro interno do Servidor!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
        
        O servidor encontrou um erro interno e n&atilde;o pode
        completar sua requisi&ccedil;&atilde;o.   
    
        <!--#include virtual="include/spacer.html" -->
    
        Mensagem de Erro:
        <br /><!--#echo var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        O servidor encontrou um erro interno e n&atilde;o
        foi poss&iacute;vel completar sua requisi&ccedil;&atilde;o.
        O servidor est&aacute; sobrecarregado ou existe um 
        erro em um script CGI.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Erro interno do servidor!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
    	O servidor encontrou um erro interno e n&atilde;o pode completar
    	o seu pedido.
    
        <!--#include virtual="include/spacer.html" -->
    
        Mensagem de erro:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
    	O servidor encontrou um erro interno e n&atilde;o pode completar
    	o seu pedido. Ou o servidor est&aacute; sobrecarregado, ou ocorreu
    	um erro num <i>script</i> CGI.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Eroare server!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Serverul a intalnit o eroare interna si nu a
        putut rezolva cererea dumneavoastra.
    
        <!--#include virtual="include/spacer.html" -->
    
        Mesajul de eroare :
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        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.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Ошибка сервера!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Произошла внутренняя ошибка сервера, в результате которой
        серверу не удалось завершить обработку Вашего запроса.
    
        <!--#include virtual="include/spacer.html" -->
    
        Error message:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Произошла внутренняя ошибка сервера, в результате которой
        серверу не удалось завершить обработку Вашего запроса.
        Сервер перегружен, или в CGI-скрипте обнаружена ошибка.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Грешка сервера!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Сервер је имао унутрашњу грешку и није био
        у могућности да испуни ваш захтев.
    
        <!--#include virtual="include/spacer.html" -->
    
        Порука о грешци:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Сервер је имао унутрашњу грешку и није био
        у могућности да испуни ваш захтев. Могуће је да је сервер
        преоптерећен, или да се десила грешка у CGI скрипти.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Serverfel!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Servern r&aring;kade ut f&ouml;r ett internt fel och det var inte m&ouml;jligt
        att slutf&ouml;ra din beg&auml;ran.
    
        <!--#include virtual="include/spacer.html" -->
    
        Felmeddelande:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Servern r&aring;kade ut f&ouml;r ett internt fel och det var inte m&ouml;jligt
        att slutf&ouml;ra din beg&auml;ran. Servern &auml;r antingen &ouml;verbelastad
        eller s&aring; inneh&aring;ller CGI-skriptet fel.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Sunucu hatası!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        Sunucuda içsel bir hata oluştuğundan sunucu isteğinizi yerine getiremiyor.
    
        <!--#include virtual="include/spacer.html" -->
    
        Hata iletisi:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        Sunucuda içsel bir hata oluştuğundan sunucu isteğinizi yerine getiremiyor.
        Ya sunucu aşırı yüklü ya da CGI betiğinde bir hata oluştu.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="服务器错误!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        服务器发生了内部错误,无法处理您的请求。
    
        <!--#include virtual="include/spacer.html" -->
    
        错误信息:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        服务器发生了内部错误,无法处理您的请求。原因可能是服务器过载或在 CGI 脚本中出错。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="伺服器错误!"
    --><!--#include virtual="include/top.html" -->
    
      <!--#if expr="-n v('REDIRECT_ERROR_NOTES')" -->
    
        伺服器發生了內部錯誤,無法處理您的請求。
    
        <!--#include virtual="include/spacer.html" -->
    
        錯誤資訊:
        <br /><!--#echo encoding="none" var="REDIRECT_ERROR_NOTES" -->
    
      <!--#else -->
    
        伺服器發生了內部錯誤,無法處理您的請求。原因可能是伺服器超載或在 CGI 腳本中出錯。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ����httpd-2.4.64/docs/error/HTTP_NOT_IMPLEMENTED.html.var�����������������������������������������������0000664�0001751�0001751�00000017265�13317763731�021530� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Nelze zpracovat požadavek!"
    --><!--#include virtual="include/top.html" -->
    
        Server nepodporuje akci požadovanou prohlížečem.
       
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Anfrage nicht ausf&uuml;hrbar!"
    --><!--#include virtual="include/top.html" -->
    
        Die vom Browser angeforderte Aktion wird vom Server
        nicht unterst&uuml;tzt.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Cannot process request!"
    --><!--#include virtual="include/top.html" -->
    
        The server does not support the action requested by the browser.
       
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;No se puede procesar la petici&oacute;n!" -->
    <!--#include virtual="include/top.html" -->
    
        El servidor no soporta la acci&oacute;n
        solicitada por el navegador.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="La requ&ecirc;te ne peut &ecirc;tre effectu&eacute;e!"
    --><!--#include virtual="include/top.html" -->
    
        Le serveur n'est pas en mesure d'effectuer l'action
        demand&eacute;e par le navigateur. 
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Iarratais dophr&oacute;ise&aacute;ilte!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute;l taca&iacute;ocht ag an fhreastala&iacute; don gn&iacute;omh
        at&aacute; &aacute; iarraidh ag an mbrabhs&aacute;la&iacute;.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="La richiesta non pu&ograve; essere soddisfatta!"
    --><!--#include virtual="include/top.html" -->
    
        Il server non supporta il tipo di azione richiesta dal browser.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Cannot process request!"
    --><!--#include virtual="include/top.html" -->
    
        ブラウザの要求したアクションは、サポートしていません。
       
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="요청 처리 실패!"
    --><!--#include virtual="include/top.html" -->
    
        브라우저가 보낸 요청을 이 서버가 지원하지 않습니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Kan vraag niet verwerken!"
    --><!--#include virtual="include/top.html" -->
    
       De server ondersteunt de actie, gevraagd door de browser, niet.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Kan ikke behandle forspørsel!"
    --><!--#include virtual="include/top.html" -->
    
        Serveren støtter ikke den handlingen som ønskes utført av
        nettleseren.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="&#379;&#261;danie nieobs&#322;ugiwane!"
    --><!--#include virtual="include/top.html" -->
    
        Ten serwer nie obs&#322;uguje &#380;&#261;dania przes&#322;anego przez przegl&#261;dark&#281;.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="A requisi&ccedil;&atilde;o n&atilde;o pode ser processada!"
    --><!--#include virtual="include/top.html" -->
    
       O servidor n&atilde;o suporta a a&ccedil;&atilde;o requisitada pelo
       seu "browser".
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="N&atilde;o posso processar o pedido!"
    --><!--#include virtual="include/top.html" -->
    
    	O servidor n&atilde;o suporta a ac&ccedil;&atilde;o pedida pelo
    	<i>browser</i>.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Cererea nu poate fi procesata!"
    --><!--#include virtual="include/top.html" -->
    
        Serverul nu suporta actiunea ceruta de browser.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Запрос не может быть обработан!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер не поддерживает возможностей, необходимых для обработки запроса.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Не могу да обрадим захтев!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер не подржава акцију коју је читач захтевао.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Kan ikke utf!"
    --><!--#include virtual="include/top.html" -->
    
        Servern st&ouml;djer inte den handling som &ouml;nskades
        av webbl&auml;saren.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="İstek yerine getirilemiyor!"
    --><!--#include virtual="include/top.html" -->
    
        Sunucu, tarayıcı tarafından istenen eylemi desteklemiyor.
       
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="无法执行请求!"
    --><!--#include virtual="include/top.html" -->
    
        服务器不支持浏览器请求的动作。
       
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="無法執行請求!"
    --><!--#include virtual="include/top.html" -->
    
        伺服器不支援瀏覽器請求的動作。
       
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_REQUEST_URI_TOO_LARGE.html.var�����������������������������������������0000664�0001751�0001751�00000021232�13317763731�022534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Požadované URI je příliš velké!"
    --><!--#include virtual="include/top.html" -->
    
        Délka požadovaného URL přesahuje kapacitní limit tohoto
        serveru. Požadavek nemůže být zpracován.
       
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="&Uuml;bergebener URI zu gro&szlig;!"
    --><!--#include virtual="include/top.html" -->
    
        Der bei der Anfrage &uuml;bermittelte URI &uuml;berschreitet
        die maximale L&auml;nge.
        Die Anfrage kann nicht ausgef&uuml;hrt werden.
        
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Submitted URI too large!"
    --><!--#include virtual="include/top.html" -->
    
        The length of the requested URL exceeds the capacity limit for
    	this server. The request cannot be processed.
       
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;El URI enviado es demasiado largo!" -->
    <!--#include virtual="include/top.html" -->
    
       La longitud de la URL solicitada excede el l&iacute;mite de
       capacidad para este servidor. No se puede procesar la solicitud.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="L'URI demandee est trop longue!"
    --><!--#include virtual="include/top.html" -->
    
        La longueur de l'URL demand&eacute;e exc&egrave;de la limite de
        capacit&egrave; pour ce serveur. Nous ne pouvons donner suite
        &agrave; votre requ&ecirc;te.
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="URI r&oacute;mh&oacute;r cuirthe isteach!"
    --><!--#include virtual="include/top.html" -->
    
        T&aacute; faid an URL iarraithe breis ar an teorainn cumas don 
        freastala&iacute; seo. N&iacute; f&eacute;idir an iarratas a
        phr&oacute;ise&aacute;il.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="URI troppo lungo!"
    --><!--#include virtual="include/top.html" -->
    
        La lunghezza dell'indirizzo (URL) trasmesso supera il
        limite massimo imposto da questo server.
        La richiesta non pu&ograve; essere soddisfatta.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Submitted URI too large!"
    --><!--#include virtual="include/top.html" -->
    
        リクエストの URL の長さが、扱える長さを超えています。
        リクエストの処理を続けられません。
       
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="너무 긴 URI!"
    --><!--#include virtual="include/top.html" -->
    
        요청한 URL이 너무 길어서 이 서버가 처리할 수 없습니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Aangeboden URI te groot!"
    --><!--#include virtual="include/top.html" -->
    
       De lengte van de aangeboden URL overschreidt het maximum
       voor deze server. De vraag kan niet verwerkt worden.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Forespurt URI for stor!"
    --><!--#include virtual="include/top.html" -->
    
        Lengden på adressen som etterspurtes overskrider
        kapasitetsgrensen for denne serveren. Forespørselen kan
        ikke prosesseres.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Zbyt d&#322;ugie URI!"
    --><!--#include virtual="include/top.html" -->
    
        D&#322;ugo&#347;&#263; &#380;&#261;danego URL-a przekracza limit ustanowiony dla tego
        serwera. &#379;&#261;danie nie mo&#380;e zosta&#263; zrealizowane.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="URL excede limite!"
    --><!--#include virtual="include/top.html" -->
    
       O tamanho do endere&ccedil;o (URL) excede a capacidade limite
       desse servidor. A requisi&ccedil;&atilde;o n&atilde;o pode ser
       processada.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="URI demasiado grande!"
    --><!--#include virtual="include/top.html" -->
    
    	O tamanho do URL pedido excede o limite da capacidade deste
    	servidor. O pedido n&atilde;o pode ser processado.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="URL-ul submis este prea mare!"
    --><!--#include virtual="include/top.html" -->
    
        Lungimea URL-ului cerut depaseste limita capacitatii pentru
        acest server. Cererea nu poate fi procesata.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="URI слишком длинный!"
    --><!--#include virtual="include/top.html" -->
    
        Длина запрашиваемого URL превышает максимально допустимую
        сервером. Запрос не может быть обработан.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Послати УРИ је превелик!"
    --><!--#include virtual="include/top.html" -->
    
        Дужина захтеваног УРЛ-а премашује ограничења могућности
        овог сервера. Захтев не може бити обрађен.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Efterfr&aring;gad URI f&ouml;r stor!"
    --><!--#include virtual="include/top.html" -->
    
        L&auml;ngden p&aring; adressen som efterfr&aring;gas &ouml;verskrider
        kapacitetsgr&auml;nsen f&ouml;r denna server. F&ouml;rfr&aring;gan kan
        inte verkst&auml;llas.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Gönderilen URI çok büyük!"
    --><!--#include virtual="include/top.html" -->
    
        Talep edilen URI'nin uzunluğu, sunucunun sınırlarını
        aştığından istek yerine getirilemiyor.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="提交的 URI 过长!"
    --><!--#include virtual="include/top.html" -->
    
        请求 URL 的长度超出了服务器的长度限制。该请求无法处理。
       
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="提交的 URI 過長!"
    --><!--#include virtual="include/top.html" -->
    
        請求 URL 的長度超出了伺服器的長度限制。該請求無法處理。
       
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_VARIANT_ALSO_VARIES.html.var�������������������������������������������0000664�0001751�0001751�00000021104�13317763731�022223� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Varianta má sama více variant!"
    --><!--#include virtual="include/top.html" -->
    
        Varianta požadované entity má sama více variant. Přístup není možný.
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Variante ebenfalls ver&auml;nderlich!"
    --><!--#include virtual="include/top.html" -->
    
        Ein Zugriff auf das angeforderte Objekt bzw. einer
        Variante dieses Objektes ist nicht m&ouml;glich, da es ebenfalls
        ein variables Objekt darstellt.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Variant also varies!"
    --><!--#include virtual="include/top.html" -->
    
        A variant for the requested entity
        is itself a negotiable resource.
        Access not possible.
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="La variante tambi&eacute;n varia!" -->
    <!--#include virtual="include/top.html" -->
    
       Una variante de la entidad solicitada es por si misma
       un recurso negociable.
       No es posible tener acceso a la entidad.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="La variante varie elle-m&ecirc;me!"
    --><!--#include virtual="include/top.html" -->
    
        Une variante pour l'entit&eacute; demand&eacute;e
        est elle-m&ecirc;me une ressource n&eacute;gociable.
        L'acc&egrave;s est impossible.
    
    <!--#include virtual="include/bottom.html" -->  
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Athraitheach intr&aacute;chta!"
    --><!--#include virtual="include/top.html" -->
    
        Is &eacute; ceann de na athraitha&iacute; 
        don aon&aacute;n iarraithe acmhainn 
        intr&aacute;chta f&eacute;in.
        Rochtain dodh&eacute;anta.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="La versione variante varia essa stessa!"
    --><!--#include virtual="include/top.html" -->
    
        Non &egrave; possibile accedere all'entit&agrave;
        richiesta perch&eacute; &egrave; essa stessa
        una risorsa negoziabile.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Variant also varies!"
    --><!--#include virtual="include/top.html" -->
    
        リクエストされたものの variant
        はそれ自体もまた、ネゴシエーション可能なリソースです。
        アクセスできませんでした。
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="형태를 결정할 수 없음!"
    --><!--#include virtual="include/top.html" -->
    
        요청한 객체의 형태 또한 여러 형태를 가지고 있어서
        접근이 불가능합니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Variant varieert ook!"
    --><!--#include virtual="include/top.html" -->
    
        Een variant van het gevraagde object
        is op zich ook een te onderhandelen variant.
        Toegang is niet mogelijk.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Variant varierer også!"
    --><!--#include virtual="include/top.html" -->
    
        En variant av den forespurte enheten er i seg selv en forhandelbar
        ressurs. Tilgang ikke mulig.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Wariant jest wariantowy!"
    --><!--#include virtual="include/top.html" -->
    
        Wariant &#380;&#261;danego zasobu jest r&#243;wnie&#380; zasobem negocjowalnym.
        Dost&#281;p jest niemo&#380;liwy.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Variante auto-negoci&aacute;vel!"
    --><!--#include virtual="include/top.html" -->
    
        Uma variante da entidade de requisi&ccedil;&atilde;o
    	&eacute; por si mesma um recurso negoci&aacute;vel.
        Acesso n&atilde;o &eacute; poss&iacute;vel.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Variante tamb&eacute;m varia!"
    --><!--#include virtual="include/top.html" -->
    
    	A variante relativa &agrave; entidade pedida &eacute; ela mesma
    	um recurso negoci&aacute;vel. N&atilde;o &eacute; poss&iacute;vel
    	ter acesso.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Varianta deasemenea variaza!"
    --><!--#include virtual="include/top.html" -->
    
        O varianta pentru entitatea ceruta
        este ea insasi o resursa negociabila.
        Accesul nu este posibil.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Вариант также варьируется!"
    --><!--#include virtual="include/top.html" -->
    
        Вариант запрашиваемого объекта - и сам ресурс непостоянный.
        Доступ к объекту невозможен.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Варијанта такође варира!"
    --><!--#include virtual="include/top.html" -->
    
        Варијанта захтеваног ентитета
        је и сама ресурс који постоји у више варијанти.
        Приступ није могућ.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Variant also varies!"
    --><!--#include virtual="include/top.html" -->
    
        En variant av den f&ouml;rfr&aring;gade enheten &auml;r i
        sig sj&auml;lv en giltig resurs. &Aring;tkomst &auml;r inte
        m&ouml;jlig.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Gösterim çeşitleri de çeşitli!"
    --><!--#include virtual="include/top.html" -->
    
        İstenen gösterim çeşidinin kendisi zaten kendi içinde uzlaşımlı.
        Erişim mümkün değil.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="变元是可变的!"
    --><!--#include virtual="include/top.html" -->
    
        请求实体的一个变元自身是一个可被协商的资源。无法访问。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="變元是可變的!"
    --><!--#include virtual="include/top.html" -->
    
        請求實體的一個變元自身是一個可被協商的資源。無法訪問。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_NOT_FOUND.html.var�����������������������������������������������������0000664�0001751�0001751�00000040744�13317763731�020636� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Objekt nenalezen!"
    --><!--#include virtual="include/top.html" -->
    
        Požadované URL nebylo na tomto serveru nalezeno.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Zdá se, že odkaz na
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">odkazující
        stránce</a> je chybný nebo zastaralý. Informujte, prosím, autora
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">této stránky</a>
        o&nbsp;chybě.
    
      <!--#else -->
    
        Pokud jste zadal(a) URL ručně, zkontrolujte, prosím,
        zda jste zadal(a) URL správně, a zkuste to znovu.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Objekt nicht gefunden!"
    --><!--#include virtual="include/top.html" -->
    
        Der angeforderte URL konnte auf dem Server nicht gefunden werden.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Der Link auf der
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">verweisenden
        Seite</a> scheint falsch oder nicht mehr aktuell zu sein.
        Bitte informieren Sie den Autor
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">dieser Seite</a>
        &uuml;ber den Fehler.
    
      <!--#else -->
    
        Sofern Sie den URL manuell eingegeben haben,
        &uuml;berpr&uuml;fen Sie bitte die Schreibweise und versuchen Sie es erneut.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Object not found!"
    --><!--#include virtual="include/top.html" -->
    
        The requested URL was not found on this server.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        The link on the
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">referring
        page</a> seems to be wrong or outdated. Please inform the author of
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">that page</a>
        about the error.
    
      <!--#else -->
    
        If you entered the URL manually please check your
        spelling and try again.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Objeto no localizado!" -->
    <!--#include virtual="include/top.html" -->
    
        No se ha localizado la URL solicitada en este servidor.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        La URL de la <a href="<!--#echo encoding="url" 
        var="HTTP_REFERER"-->">p&aacute;gina que le ha remitido</a> 
        parece ser err&oacute;nea o estar obsoleta. Por favor, informe del error 
        al autor de <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->">esa
        p&aacute;gina</a>.
    
      <!--#else -->
    
        Si usted ha introducido la URL manualmente, por favor revise su
        ortograf&iacute;a e int&eacute;ntelo de nuevo.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Objet non trouv&eacute;!"
    --><!--#include virtual="include/top.html" -->
    
        L'URL demand&eacute;e n'a pas pu &ecirc;tre trouv&eacute;e sur ce serveur.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        La r&eacute;f&eacute;rence sur
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">la page
        cit&eacute;e</a>
        semble &ecirc;tre erron&eacute;e ou perim&eacute;e. Nous vous prions
        d'informer l'auteur de
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">cette page</a>
        de cette erreur.
    
      <!--#else -->
    
        Si vous avez tap&eacute; l'URL &agrave; la main, veuillez v&eacute;rifier
        l'orthographe et r&eacute;essayer.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga 
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Aidhm ar iarraidh!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute;or aimsigh an URL iarraithe ar an fhreastala&iacute; seo.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Is cos&uacute;il go bhfuil an nasc ar an
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">leathanach
        thagarthach</a> m&iacute;cheart n&oacute; as d&aacute;ta. 
        Cur in i&uacute;l d'&uacute;adar 
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->"
        >an leathanach sin</a> go bhfuil earr&aacute;id ann, le do thoil.
    
      <!--#else -->
    
        M&aacute; chuir t&uacute; isteach an URL t&uacute; f&eacute;in, deimhnigh
        go bhfuil s&eacute; litrithe i gceart agat, agus d&eacute;an iarracht eile
        le do thoil.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Oggetto non trovato!"
    --><!--#include virtual="include/top.html" -->
    
        L'URL richiesto non esiste su questo server.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Il link della
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">pagina da cui
        sei arrivato</a> potrebbe essere errato o non essere pi&ugrave; valido.
        Per favore, informa dell'errore l'autore della
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">pagina</a>.
    
      <!--#else -->
    
        Se hai scritto l'URL a mano, per favore controlla che
        non ci siano errori.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Object not found!"
    --><!--#include virtual="include/top.html" -->
    
        要求された URL は本サーバでは見つかりませんでした。
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->">
        参照元ページ</a>のリンクが間違っているか、古くなってしまっているようです。
        <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->"
        >ページ</a>の著者にこのエラーをお知らせ下さい。
    
      <!--#else -->
    
        もし手入力で URL を入力した場合は、綴りを確認して再度お試し下さい。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="객체 없음!"
    --><!--#include virtual="include/top.html" -->
    
        요청한 URL을 이 서버에서 찾을 수 없습니다.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->">이전
        페이지</a>에 있는 링크가 잘못되었거나 오래되어 없어진 것 같습니다.
        <a href="<!--#echo encoding="url" var="HTTP_REFERER"-->">그 페이지</a>를
        만든이에게 이 사실을 알려주시기 바랍니다.
    
      <!--#else -->
    
        URL을 직접 입력하셨다면 바르게 입력하셨는지 확인하시고 다시 시도하시기
        바랍니다.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Object niet gevonden!"
    --><!--#include virtual="include/top.html" -->
    
        De gevraagde URL was niet gevonden op deze server.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        De link op
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">deze pagina
        pagina</a> is verkeerd of achterhaald. Gelieve de auteur van
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">die pagina</a>
        in te lichten over deze fout.
    
      <!--#else -->
    
        Indien u de URL manueel hebt ingevuld, gelieve uw
        spelling te controleren en probeer opnieuw.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Objektet ble ikke funnet!"
    --><!--#include virtual="include/top.html" -->
    
        Den etterspurte adressen finnes ikke på denne serveren.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Lenken på den
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">forrige siden</a> 
    ser ut til å være feil eller utdatert. Venligst informer forfatteren av
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">siden</a>
        om feilen.
    
      <!--#else -->
    
        Om du skrev inn adressen manuelt, vennligst kontroller stavingen og
        forsøk igjen.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Nie znaleziono obiektu!"
    --><!--#include virtual="include/top.html" -->
    
        Nie znaleziono &#380;&#261;danego URL-a na tym serwerze.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Odno&#347;nik na
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">referuj&#261;cej stronie
        </a> wydaje si&#281; by&#263; nieprawid&#322;owy lub nieaktualny. Poinformuj autora
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">tej strony</a>
        o problemie.
    
      <!--#else -->
        Je&#347;li wpisa&#322;e&#347; URL-a r&#281;cznie, sprawd&#378;, czy si&#281; nie pomyli&#322;e&#347;.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Objeto n&atilde;o encontrado!"
    --><!--#include virtual="include/top.html" -->
    
        A URL requisitada n&atilde;o foi encontrada neste servidor.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        O link na
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">p&aacute;gina
        referida</a> parece estar com algum erro ou desatualizado. Por favor informe o
        autor <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">desta 
        p&aacute;gina</a> sobre o erro.
    
       <!--#else -->
    
        Se voc&ecirc; digitou o endere&ccedil;o (URL) manualmente,
        por favor verifique novamente a sintaxe do endere&ccedil;o.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="M&eacute;todo n&atilde;o permitido!"
    --><!--#include virtual="include/top.html" -->
    
    	O m&eacute;todo <!--#echo var="REDIRECT_REQUEST_METHOD" --> n&atilde;o
    	&eacute; permitido para o URL pedido.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Obiectul nu a fost gasit!"
    --><!--#include virtual="include/top.html" -->
    
        URL-ul cerut nu a fost gasit pe acest server.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Link-ul de pe
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">pagina
        de unde ati venit</a> pare a fi gresit sau invechit. Va rugam informati autorul
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">acestei pagini</a>
        despre eroare.
    
      <!--#else -->
    
        Daca ati introdus URL-ul manual, va rugam verificati
        corectitudinea si incercati din nou.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Объект не найден!"
    --><!--#include virtual="include/top.html" -->
    
        Запрашиваемый ресурс не найден.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Ссылка на
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">странице
        </a> неверна или устарела. Пожалуйста, сообщите автору
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">этой страницы</a>
        об ошибке.
    
      <!--#else -->
    
        Если Вы ввели адрес данного ресурса вручную, пожалуйста, удостовертесь,
        что в написании адреса нет ошибок.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Објекат није пронађен!"
    --><!--#include virtual="include/top.html" -->
    
        Захтевани УРЛ није пронађен на овом серверу.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        Изгледа да је веза на
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">исходишној
        страници</a> погрешна или застарела. Молимо обавестите аутора
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">те странице</a>
        о грешци.
    
      <!--#else -->
    
        Уколико сте УРЛ унели ручно, молимо проверите могуће
        грешке и пробајте поново.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Objektet hittas ej!"
    --><!--#include virtual="include/top.html" -->
    
        Den efterfr&aring;gade adressen hittades inte p&aring; denna server.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        L&auml;nken p&aring; den
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">tidigare sidan</a> 
        verkar vara felaktig eller inaktuell. V&auml;nligen informera f&ouml;rfattaren av
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">sidan</a>
        om felet.
    
      <!--#else -->
    
        Om du skrev in adressen manuellt s&aring; kontrollera din stavning och
        f&ouml;rs&ouml;k igen.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Nesne mevcut değil!"
    --><!--#include virtual="include/top.html" -->
    
        Talep ettiğiniz URL, sunucu üzerinde bulunmuyor.
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        <a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">İstek yapılan sayfa</a>
        üzerindeki bağlantı güncel değil. Lütfen <a href="<!--#echo encoding="url" 
        var="HTTP_REFERER" -->">sayfa</a> yazarını hata hakkında bilgilendirin.
    
      <!--#else -->
    
        URL'yi elle girdiyseniz, yazdıklarınızı gözden geçirip yeniden deneyin.
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="找不到对象!"
    --><!--#include virtual="include/top.html" -->
    
        您请求的 URL 在该服务器上未找到。
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        您的<a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">来源页面</a>上的链接可能出错或过期。
        请将错误通知给<a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">该页面</a>的作者。
    
      <!--#else -->
    
        如果您是手动输入的 URL ,请检查拼写并重试。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="找不到物件!"
    --><!--#include virtual="include/top.html" -->
    
        您請求的 URL 在該伺服器上未找到。
    
      <!--#if expr="-n v('HTTP_REFERER')" -->
    
        您的<a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">來源頁面</a>上的連結可能出錯或過期。
        請將錯誤通知給<a href="<!--#echo encoding="url" var="HTTP_REFERER" -->">該來源頁面</a>的作者。
    
      <!--#else -->
    
        如果您是手動輸入的 URL ,請檢查拼寫並重試。
    
      <!--#endif -->
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ����������������������������httpd-2.4.64/docs/error/HTTP_REQUEST_TIME_OUT.html.var����������������������������������������������0000664�0001751�0001751�00000021124�13317763731�021727� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Vypršel časový limit požadavku!"
    --><!--#include virtual="include/top.html" -->
    
        Server uzavřel síťové spojení, protože prohlížeč
        nedokončil požadavek ve stanoveném čase.
       
    <!--#include virtual="include/bottom.html" --> 
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Zeitlimit &uuml;berschritten!"
    --><!--#include virtual="include/top.html" -->
    
        Der Server konnte nicht mehr l&auml;nger auf die Beendigung
        der Browseranfrage warten; die Netzwerkverbindung wurde
        vom Server geschlossen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Request time-out!"
    --><!--#include virtual="include/top.html" -->
    
        The server closed the network connection because the browser
        didn't finish the request within the specified time.
       
    <!--#include virtual="include/bottom.html" --> 
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Tiempo de espera excedido!" -->
    <!--#include virtual="include/top.html" -->
    
        El servidor ha cerrado la conexi&oacute;n de red
        debido a que el navegador no ha finalizado la solicitud
        dentro del tiempo permitido.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Requ&ecirc;te trop longue !"
    --><!--#include virtual="include/top.html" -->
    
        Le serveur a ferm&eacute; la connection car le navigateur n'a pas 
        fini la requ&ecirc;te dans le temps sp&eacute;cifi&eacute;.
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Am don iarratais istigh!"
    --><!--#include virtual="include/top.html" -->
    
        D&uacute;n an freastala&iacute; an nasc l&iacute;onra, 
        mar n&iacute;or chr&iacute;ochnaidh an brabhs&aacute;la&iacute;
        leis an iarratais, taobh istigh den am sonraithe.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Time-out della richiesta!"
    --><!--#include virtual="include/top.html" -->
    
        Il server ha chiuso la connessione in quanto &egrave; stato
        superato il limite di tempo entro il quale il browser avrebbe
        dovuto eseguire la richiesta.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Request time-out!"
    --><!--#include virtual="include/top.html" -->
    
        ブラウザが指定時間以内にリクエストを完了しなかったので、
        サーバは接続を切りました。
       
    <!--#include virtual="include/bottom.html" --> 
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="요청 시간 초과!"
    --><!--#include virtual="include/top.html" -->
    
        브라우저가 너무 오랫동안 요청을 끝내지 않아서 서버가 네트워크 연결을
        강제로 끊었습니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Tijdlimiet overschreden!"
    --><!--#include virtual="include/top.html" -->
    
       De server heeft de netwerkverbinding gesloten omdat de browser
       de vraag niet heeft be&euml;indigd binnen een gestelde tijd.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Tidsgrense overskredet!"
    --><!--#include virtual="include/top.html" -->
    
        Serveren stengte forbindelsen fordi nettleseren ikke avsluttet
        forespørselen innen tidsgrensen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Przedawnione &#380;&#261;danie!"
    --><!--#include virtual="include/top.html" -->
    
        Serwer zamkn&#261;&#322; po&#322;&#261;czenie sieciowe, poniewa&#380; przegl&#261;darka
        nie zako&#324;czy&#322;a operacji w przewidywanym czasie.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Tempo excedido!"
    --><!--#include virtual="include/top.html" -->
    
       O servidor encerrou a conex&atilde;o porque o "browser"
       n&atilde;o finalizou a requisi&ccedil;&atilde;o dentro
       do tempo limite.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Tempo excedido!"
    --><!--#include virtual="include/top.html" -->
    
    	O servidor interrompeu a liga&ccedil;&atilde;o de rede porque o
    	<i>browser</i> n&atilde;o terminou o pedido dentro do tempo limite.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Time-out al cererii!"
    --><!--#include virtual="include/top.html" -->
    
        Serverul a terminat conexiunea cu browserul pentru ca acesta
        nu a terminat cererea in limita timpului specificat.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Истекло время ожидания!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер закрыл соединение из-за истечения времени,
        отведённого браузеру на выполнение запроса.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Захтеву је истекло време!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер је прекинуо везу са мрежом јер читач
        није завршио захтев за дозвољено време.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Request time-out!"
    --><!--#include virtual="include/top.html" -->
    
        Servern st&auml;ngde f&ouml;rbindelsen d&auml;rf&ouml;r att
        webbl&auml;saren inte avslutade f&ouml;rfr&aring;gan inom
        f&ouml;rbest&auml;md tid.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="İstekte zaman aşımı!"
    --><!--#include virtual="include/top.html" -->
    
        Tarayıcı isteği zamanında tamamlayamadığından sunucu ağ bağlantısını kapattı.
    
    <!--#include virtual="include/bottom.html" --> 
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="请求超时!"
    --><!--#include virtual="include/top.html" -->
    
        由于浏览器未在指定时间内完成请求,服务器关闭了网络连接。
       
    <!--#include virtual="include/bottom.html" --> 
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="請求超時!"
    --><!--#include virtual="include/top.html" -->
    
        由於瀏覽器未在指定時間內完成請求,伺服器關閉了網路連接。
       
    <!--#include virtual="include/bottom.html" --> 
    ----------zh-tw--
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var����������������������������������������0000664�0001751�0001751�00000017231�13317763731�022626� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Nepodporovaný typ prostředku!"
    --><!--#include virtual="include/top.html" -->
    
        Server nepodporuje typ prostředku (media) přeneseného v&nbsp;požadavku.
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Nicht unterst&uuml;tztes Format!"
    --><!--#include virtual="include/top.html" -->
    
        Das bei der Anfrage &uuml;bermittelte Format (Media Type)
        wird vom Server nicht unterst&uuml;tzt.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Unsupported media type!"
    --><!--#include virtual="include/top.html" -->
    
        The server does not support the media type transmitted in the request.
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;El tipo de medio no est&aacute; soportado!" -->
    <!--#include virtual="include/top.html" -->
    
       El servidor no soporta el tipo
       de medio transmitido en la solicitud.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Type de m&eacute;dia invalide!"
    --><!--#include virtual="include/top.html" -->
    
        Le serveur ne supporte pas le type de m&eacute;dia utilis&eacute;
        dans votre requ&ecirc;te. 
    
    <!--#include virtual="include/bottom.html"-->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Cine&aacute;il me&aacute;n gan tacha&iacute;ocht!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute; tacha&iacute;onn an fhreastala&iacute; an cine&aacute;il
        me&aacute;n a sheoladh san iarratais.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Tipo di dato non supportato!"
    --><!--#include virtual="include/top.html" -->
    
        Il server non &egrave; in grado di gestire il 
        tipo del formato dei dati trasmesso nella richiesta.
       
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Unsupported media type!"
    --><!--#include virtual="include/top.html" -->
    
        リクエストで指定されたメディアタイプはサポートされていません。
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="지원하지 않는 미디어 형식!"
    --><!--#include virtual="include/top.html" -->
    
        요청으로 보내온 미디어 형식을 이 서버가 지원하지 않습니다. 
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Niet ondersteund formaat!"
    --><!--#include virtual="include/top.html" -->
    
       De server ondersteunt het gevraagde formaat ( media type ) niet.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Mediatypen støttes ikke!"
    --><!--#include virtual="include/top.html" -->
    
        Serveren støtter ikke den mediatypen som ble forespurt.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Nieobs&#322;ugiwany typ danych!"
    --><!--#include virtual="include/top.html" -->
    
        Serwer nie zna typu danych przes&#322;anych w &#380;&#261;daniu.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Tipo de media n&atilde;o suportado!"
    --><!--#include virtual="include/top.html" -->
    
       O servidor n&atilde;o suporta o tipo de m&iacute;dia
       transmitida nesta requisi&ccedil;&atilde;o.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Media n&atilde;o suportado!"
    --><!--#include virtual="include/top.html" -->
    
    	O servidor n&atilde;o suporta o <i>media type</i> transmitido no pedido.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Tip de date nesuportate!"
    --><!--#include virtual="include/top.html" -->
    
        Serverul nu suporta tipul de date trimise in cerere.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Неподдерживаемый тип данных!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер не поддерживает работу с указанным типом данных.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Неподржана врста медија!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер не подржава врсту медија пренесену у захтеву.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Mediatypen st&ouml;ds ej!"
    --><!--#include virtual="include/top.html" -->
    
        Servern st&ouml;djer inte den mediatyp som skickats i f&ouml;rfr&aring;gan.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Desteklenmeyen ortam türü!"
    --><!--#include virtual="include/top.html" -->
    
        Sunucu, istekte belirtilen ortam türünü desteklemiyor.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="不支持的媒体类型!"
    --><!--#include virtual="include/top.html" -->
    
        服务器不支持请求中传输的媒体类型。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="不支持的媒體型式!"
    --><!--#include virtual="include/top.html" -->
    
        伺服器不支持請求中傳輸的媒體型式。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/error/HTTP_UNAUTHORIZED.html.var��������������������������������������������������0000664�0001751�0001751�00000040656�13317763731�021166� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-language: cs
    Content-type: text/html; charset=UTF-8
    Body:----------cs--
    <!--#set var="CONTENT_LANGUAGE" value="cs"
    --><!--#set var="TITLE" value="Požadována autentizace!"
    --><!--#include virtual="include/top.html" -->
    
        Server nemohl ověřit, že jste autorizován(a) k&nbsp;přístupu
        k&nbsp;URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Buď jste dodal(a) neplatné pověření (např. chybné heslo) nebo Váš
        prohlížeč neumí dodat požadované ověření.
    
      <!--#include virtual="include/spacer.html" -->
    
        V&nbsp;případě, že smíte požadovat tento dokument, zkontrolujte, prosím,
        Vaši uživatelskou identifikaci a heslo a zkuste to znovu.
    
    <!--#include virtual="include/bottom.html" -->
    ----------cs--
    
    Content-language: de
    Content-type: text/html; charset=UTF-8
    Body:----------de--
    <!--#set var="CONTENT_LANGUAGE" value="de"
    --><!--#set var="TITLE" value="Authentisierung fehlgeschlagen!"
    --><!--#include virtual="include/top.html" -->
    
        Der Server konnte nicht verifizieren, ob Sie autorisiert sind,
        auf den URL "<!--#echo encoding="url" var="REDIRECT_URL"-->" zuzugreifen.
        Entweder wurden falsche Referenzen (z.B. ein falsches Passwort)
        angegeben oder ihr Browser versteht nicht, wie die geforderten
        Referenzen zu &uuml;bermitteln sind.
    
      <!--#include virtual="include/spacer.html" -->
    
        Sofern Sie f&uuml;r den Zugriff berechtigt sind, &uuml;berpr&uuml;fen
        Sie bitte die eingegebene User-ID und das Passwort und versuchen Sie
        es erneut.
    
    <!--#include virtual="include/bottom.html" -->
    ----------de--
    
    Content-language: en
    Content-type: text/html; charset=UTF-8
    Body:----------en--
    <!--#set var="TITLE" value="Authentication required!"
    --><!--#include virtual="include/top.html" -->
    
        This server could not verify that you are authorized to access
        the URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        You either supplied the wrong credentials (e.g., bad password), or your
        browser doesn't understand how to supply the credentials required.
    
      <!--#include virtual="include/spacer.html" -->
    
        In case you are allowed to request the document, please
        check your user-id and password and try again.
    
    <!--#include virtual="include/bottom.html" -->
    ----------en--
    
    Content-language: es
    Content-type: text/html
    Body:----------es--
    <!--#set var="TITLE" value="&iexcl;Autentificaci&oacute;n requerida!" -->
    <!--#include virtual="include/top.html" -->
    
        El servidor no puede certificar que usted est&eacute; autorizado
        para acceder a la URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Ha podido suministrar informaci&oacute;n incorrecta (ej.
        contrase&ntilde;a no v&aacute;lida) o el navegador no sabe
        c&oacute;mo suministrar la informaci&oacute;n requerida.
    
      <!--#include virtual="include/spacer.html" -->
    
        En caso de que usted tenga permiso para acceder al documento,
        por favor verifique su nombre de usuario y contrase&ntilde;a y 
        vu&eacute;lvalo a intentar.
    
    <!--#include virtual="include/bottom.html" -->
    ----------es--
    
    Content-language: fr
    Content-type: text/html; charset=UTF-8
    Body:----------fr--
    <!--#set var="CONTENT_LANGUAGE" value="fr"
    --><!--#set var="TITLE" value="Autorisation requise!"
    --><!--#include virtual="include/top.html" -->
    
        Ce server n'a pas &eacute;t&eacute; en mesure de v&eacute;rifier que
        vous &ecirc;tes autoris&eacute; &agrave; acc&eacute;der &agrave; cette
        URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
    
        Vous avez ou bien fourni des coordonn&eacute;es erron&eacute;es
        (p.ex. mot de passe inexact) ou bien votre navigateur ne parvient
        pas &agrave; fournir les donn&eacute;es exactes.
    
      <!--#include virtual="include/spacer.html" -->
    
        Si vous &ecirc;tes autoris&eacute; &agrave; requ&eacute;rir le document,
        veuillez v&eacute;rifier votre nom d'utilisateur et votre mot de passe
        et r&eacute;essayer.
    
    <!--#include virtual="include/bottom.html" -->
    ----------fr--
    
    Content-language: ga
    Content-type: text/html; charset=UTF-8
    Body:----------ga--
    <!--#set var="TITLE" value="Is g&aacute; f&iacute;ordheimhni&uacute;!"
    --><!--#include virtual="include/top.html" -->
    
        N&iacute;orbh fh&eacute;idir leis an freastala&iacute; a dheimhni&uacute;
        go bhfuil an &uacute;dar&aacute;is agat rochtain a dheanamh ar an URL
        "<!--#echo encoding="url" var="REDIRECT_URL" -->".  Is f&eacute;idir go
        sol&aacute;thair t&uacute; faisn&eacute;is m&iacute;cheart (m.s.,
        pasfhocail m&iacute;cheart), n&oacute; nach dtuigeann do chuid
        brabhs&aacute;la&iacute; conas an faisn&eacute;is is g&aacute; a
        sol&aacute;thair i gceart.
    
      <!--#include virtual="include/spacer.html" -->
    
        M&aacute;s &eacute; gur ceart go mbh&eacute;adh cead agat iarratais a
        dheanamh don doicim&eacute;id, deimhnigh go bhfuil do chuid ainm
        &uacute;s&aacute;ideora agus pasfhocal i gceart, agus dean iarracht eile,
        le do thoil.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ga--
    
    Content-language: it
    Content-type: text/html; charset=UTF-8
    Body:----------it--
    <!--#set var="CONTENT_LANGUAGE" value="it"
    --><!--#set var="TITLE" value="Autorizzazione necessaria!"
    --><!--#include virtual="include/top.html" -->
    
        Questo server non pu&ograve; verificare l'autorizzazione
        all'accesso a "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        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.
    
      <!--#include virtual="include/spacer.html" -->
    
        Nel caso in cui ritieni di aver diritto ad accedere al documento,
        controlla il nome utente e la password forniti e riprova.
    
    <!--#include virtual="include/bottom.html" -->
    ----------it--
    
    Content-language: ja
    Content-type: text/html; charset=UTF-8
    Body:----------ja--
    <!--#set var="CONTENT_LANGUAGE" value="ja"
    --><!--#set var="TITLE" value="Authentication required!"
    --><!--#include virtual="include/top.html" -->
    
        URL "<!--#echo encoding="url" var="REDIRECT_URL" -->"
        へのアクセス権限があることを確認できませんでした。
        間違った資格情報 (例えば、誤ったパスワード) を入力したか、
        ブラウザが必要な資格情報を送信する方法を理解していないかです。
    
      <!--#include virtual="include/spacer.html" -->
    
        ドキュメントを要求できる筈である場合は、
        ユーザ ID とパスワードを再確認して下さい。
    
    <!--#include virtual="include/bottom.html" -->
    ----------ja--
    
    Content-language: ko
    Content-type: text/html; charset=UTF-8
    Body:----------ko--
    <!--#set var="CONTENT_LANGUAGE" value="ko"
    --><!--#set var="TITLE" value="인증 필요!"
    --><!--#include virtual="include/top.html" -->
    
        이 서버가 "<!--#echo encoding="url" var="REDIRECT_URL" -->" URL을
        접근할 수 있는 권한이 있는지 확인하지 못했습니다.
        잘못된 인증 정보(가령, 잘못된 암호)를 보냈거나 아니면
        사용하시는 브라우저가 필요한 인증 정보를 어떻게 보내는지 모르는 것입니다.
    
      <!--#include virtual="include/spacer.html" -->
    
        이 문서를 사용할 수 있도록 허가를 받았는데도 이런다면,
        사용자 ID와 암호를 확인하시고 다시 시도하시기 바랍니다.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ko--
    
    Content-language: nl
    Content-type: text/html; charset=UTF-8
    Body:----------nl--
    <!--#set var="CONTENT_LANGUAGE" value="nl"
    --><!--#set var="TITLE" value="Authenticatie nodig!"
    --><!--#include virtual="include/top.html" -->
    
        De server kon niet controleren of u gemachtigd bent om toegang te krijgen
        tot de URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        U hebt zich onvoldoende geauthenticeerd ( vb : verkeerd paswoord ), of
        uw browser is niet in staat de nodige authentificatiegegevens door te geven.
    
      <!--#include virtual="include/spacer.html" -->
    
        Indien u toch gemachtigd bent toegang te krijgen tot het document,
        controleer uw gebruikersnaam en paswoord en probeer opnieuw.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nl--
    
    Content-language: nb
    Content-type: text/html; charset=UTF-8
    Body:----------nb--
    <!--#set var="CONTENT_LANGUAGE" value="nb"
    --><!--#set var="TITLE" value="Autentisering kreves!"
    --><!--#include virtual="include/top.html" -->
    
        Serveren kunne ikke verifisere at du har tillatelse til å besøke
        adressen "<!--#echo encoding="url" var="REDIRECT_URL" -->".  Enten
        oppga du feil opplysninger (f.eks. feil passord) eller så støtter
        ikke din nettleser dette autentiseringsystemet.
    
      <!--#include virtual="include/spacer.html" -->
    
        Om du har tillatelse til å besøke siden, vennligst kontroler ditt
        brukernavn og passord og forsøk igjen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------nb--
    
    
    Content-language: pl
    Content-type: text/html; charset=UTF-8
    Body:----------pl--
    <!--#set var="CONTENT_LANGUAGE" value="pl"
    --><!--#set var="TITLE" value="Wymagana autoryzacja!"
    --><!--#include virtual="include/top.html" -->
    
        Serwer nie mo&#380;e zweryfikowa&#263;, &#380;e masz uprawnienia dost&#281;pu do
        URL-a "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Nie poda&#322;e&#347; prawid&#322;owych danych autoryzacyjnych (np. has&#322;a)
        lub twoja przegl&#261;darka nie potrafi ich przes&#322;a&#263;.
    
      <!--#include virtual="include/spacer.html" -->
    
        Je&#347;li masz prawo dost&#281;pu do &#380;&#261;danego dokumentu, sprawd&#378;
        podan&#261; nazw&#281; u&#380;ytkownika i has&#322;o.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pl--
    
    Content-language: pt-br
    Content-type: text/html; charset=UTF-8
    Body:-------pt-br--
    <!--#set var="CONTENT_LANGUAGE" value="pt-br"
    --><!--#set var="TITLE" value="Autentica&ccedil;&atilde;o Requerida!"
    --><!--#include virtual="include/top.html" -->
    
        Este servidor n&atilde;o pode autorizar o seu acesso &agrave; URL
        "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Voc&ecirc; deve ter fornecido dados incorretos (ex. senha errada), ou o seu
        "browser" n&atilde;o fornece as credenciais necess&aacute;rias.
    
      <!--#include virtual="include/spacer.html" -->
    
        No caso de voc&ecirc; realmente possuir permiss&atilde;o para este documento,
        por favor checar seu login e sua senha e tentar novamente.
    
    <!--#include virtual="include/bottom.html" -->
    -------pt-br--
    
    Content-language: pt
    Content-type: text/html; charset=ISO-8859-1
    Body:----------pt--
    <!--#set var="TITLE" value="Autentica&ccedil;&atilde;o exigida!"
    --><!--#include virtual="include/top.html" -->
    
    	Este servidor n&atilde;o conseguiu validar a sua autoridade para aceder
    	ao URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
    	Ou forneceu as credenciais erradas (e.g.: senha incorrecta)
    	ou o seu <i>browser</i> n&atilde;o sabe como fornecer as credenciais
    	necess&aacute;rias.
    
      <!--#include virtual="include/spacer.html" -->
    
    	Caso lhe seja permitido aceder ao documento, por favor verifique o
    	seu nome de utilizador e senha e tente de novo.
    
    <!--#include virtual="include/bottom.html" -->
    ----------pt--
    
    Content-language: ro
    Content-type: text/html; charset=UTF-8
    Body:----------ro--
    <!--#set var="CONTENT_LANGUAGE" value="ro"
    --><!--#set var="TITLE" value="Autentificare necesara!"
    --><!--#include virtual="include/top.html" -->
    
        Acest server nu a putut verifica daca sunteti autorizat sa accesati
        URL-ul "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Ati furnizat parametrii de acreditare gresiti (ex: parola gresita), sau browserul
        dumneavoastra nu poate furniza aceste detalii de acreditare.
    
      <!--#include virtual="include/spacer.html" -->
    
        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.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ro--
    
    Content-language: ru
    Content-type: text/html; charset=UTF-8
    Body:----------ru--
    <!--#set var="TITLE" value="Необходима аутентификация!"
    --><!--#include virtual="include/top.html" -->
    
        Сервер не смог проверить данные аутентификации
        на доступ к "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Вы предоставили неверные учётные данные (например: пароль), или Ваш
        браузер не знает, как их предоставить.
    
      <!--#include virtual="include/spacer.html" -->
    
        Если Вам разрешено запрашивать данный документ, пожалуйста,
        проверьте свои учётные данные и повторите запрос.
    
    <!--#include virtual="include/bottom.html" -->
    ----------ru--
    
    Content-language: sr
    Content-type: text/html; charset=UTF-8
    Body:----------sr--
    <!--#set var="CONTENT_LANGUAGE" value="sr"
    --><!--#set var="TITLE" value="Обавезна аутентификација!"
    --><!--#include virtual="include/top.html" -->
    
        Овај сервер није могао да потврди да сте овлашћени да приступите
        УРЛ-у "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Могуће је или да сте навели погрешне личне податке (нпр. нетачну лозинку), или да
        ваш читач не разуме како да пошаље захтеване личне податке.
    
      <!--#include virtual="include/spacer.html" -->
    
        Уколико вам је дозвољено да преузимате документ, молимо да
        проверите своје корисничко име и лозинку и пробате поново.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sr--
    
    Content-language: sv
    Content-type: text/html; charset=UTF-8
    Body:----------sv--
    <!--#set var="CONTENT_LANGUAGE" value="sv"
    --><!--#set var="TITLE" value="Autentisering kr&auml;vs!"
    --><!--#include virtual="include/top.html" -->
    
        Servern kunde inte verifiera att du har till&aring;telse att bes&ouml;ka 
        adressen "<!--#echo encoding="url" var="REDIRECT_URL" -->".
        Antingen angav du felaktiga uppgifter (ex. fel l&ouml;senord) eller s&aring;
        st&ouml;djer inte din webbl&auml;sare detta autentiseringss&auml;tt.
    
      <!--#include virtual="include/spacer.html" -->
    
        Om du har till&aring;telse att bes&ouml;ka sidan, v&auml;nligen kontrollera ditt 
        anv&auml;ndarnamn samt l&ouml;senord och f&ouml;rs&ouml;k igen.
    
    <!--#include virtual="include/bottom.html" -->
    ----------sv--
    
    Content-language: tr
    Content-type: text/html; charset=UTF-8
    Body:----------tr--
    <!--#set var="CONTENT_LANGUAGE" value="tr"
    --><!--#set var="TITLE" value="Kimlik doğrulama gerekli!"
    --><!--#include virtual="include/top.html" -->
    
        Sunucu "<!--#echo encoding="url" var="REDIRECT_URL" -->" adresine erişim
        izninizi doğrulayamadı. Ya sağladığınız kanıtlar yanlış (yanlış parola gibi)
        ya da tarayıcınız bu kanıtların nasıl sağlanacağını bilmiyor.
    
      <!--#include virtual="include/spacer.html" -->
    
        Eğer erişim izniniz olduğuna eminseniz, lütfen kullanıcı adınızı
        ve parolanızı gözden geçirip yeniden deneyin.
    
    <!--#include virtual="include/bottom.html" -->
    ----------tr--
    
    Content-language: zh-cn
    Content-type: text/html; charset=UTF-8
    Body:----------zh-cn--
    <!--#set var="CONTENT_LANGUAGE" value="zh-cn"
    --><!--#set var="TITLE" value="需要认证!"
    --><!--#include virtual="include/top.html" -->
    
        此服务器无法验证您是否有权访问 URL "<!--#echo encoding="url" var="REDIRECT_URL" -->"。
        原因可能是您提供了错误的凭据(例如,错误的密码),或您的浏览器不知道如何提供所需的凭据。
    
      <!--#include virtual="include/spacer.html" -->
    
        如果您有权访问该文档,请检查您的用户名和密码并重试。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-cn--
    
    Content-language: zh-tw
    Content-type: text/html; charset=UTF-8
    Body:----------zh-tw--
    <!--#set var="CONTENT_LANGUAGE" value="zh-tw"
    --><!--#set var="TITLE" value="需要認證!"
    --><!--#include virtual="include/top.html" -->
    
        此伺服器無法驗證您是否有權訪問 URL "<!--#echo encoding="url" var="REDIRECT_URL" -->"。
        原因可能是您提供了錯誤的憑據(例如,錯誤的密碼),或您的瀏覽器不知道如何提供所需的憑據。
    
      <!--#include virtual="include/spacer.html" -->
    
        如果您有權訪問該文檔,請檢查您的使用者名和密碼並重試。
    
    <!--#include virtual="include/bottom.html" -->
    ----------zh-tw--
    ����������������������������������������������������������������������������������httpd-2.4.64/docs/icons/����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�014676� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie7.png��������������������������������������������������������������������0000664�0001751�0001751�00000000423�10671421551�016240� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���HIDAT[u̡0W"R*h"*1`Vn�ȯMG-YigIU+C?6a]3E!���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/movie.png�������������������������������������������������������������������0000664�0001751�0001751�00000000420�10671421551�016510� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙fff333���A���tRNS�0J���bKGD�H���9IDAT[cHDA$50K)t63-ؘ-
    ,
    f*2P�P
    A�e4U���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/tar.png���������������������������������������������������������������������0000664�0001751�0001751�00000000405�10671421551�016162� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEVVU777١@���YIDAT[m
     NAX?S$/s2AU"e+FD9�| g�L*Po`n_UOjl���LtEXtcomment�This icon is in the public domain. 1995 Kevin Hughes, kevinh@eit.comy'����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/back.png��������������������������������������������������������������������0000664�0001751�0001751�00000000464�10671421551�016301� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEfff333������tRNS�0J���bKGD�H���`IDAT[E	0EQW�.R^(qUڗD#.~Ӑ
    TE6\ECI?M
    
    J[[8y-{>dŘO.&l���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/binary.png������������������������������������������������������������������0000664�0001751�0001751�00000000466�10671421551�016667� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙333������tRNS�0J���bKGD�H���bIDAT[u	0D@&}v*QdqBU
    #7vAqL2Sk-D2
    ex v_pu;5ٓʘ|!v���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/script.png������������������������������������������������������������������0000664�0001751�0001751�00000000442�10671421551�016701� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���QIDAT[	�1l!\	�_yQyb3c!**1dӲ'+ޯ{$[/<=Ү<���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/folder.open.png�������������������������������������������������������������0000664�0001751�0001751�00000000514�10671421551�017610� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������d���PLTE̙f3333���n���tRNS�
    A���bKGD�H���tIDATWϽ	 `W8'#:*GHyT<lvHY_fF솼\zyK؀�(6Y:s*dMOJpQ>8p���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sound1.png������������������������������������������������������������������0000664�0001751�0001751�00000000513�10664777241�016621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33̙f��333���/���tRNS�
    A���bKGD�H���pIDAT׍	 En@u="zOo$b4G �7Vѳ!-ځ>0l,Ap2a<}Q)סVU쮡ftU'fX���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/image1.gif������������������������������������������������������������������0000664�0001751�0001751�00000000422�10147723030�016512� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����3ff̙f�333������������������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������mpI)5W$:BGZ/MPxs`d^z@Al6/4ifԮ3:m5WrmsX]nzT@CC5*�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/icon.sheet.png��������������������������������������������������������������0000664�0001751�0001751�00000021472�10664777241�017456� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR�������d���`PLTE̙3ff33̙3f3f�fffffff3f��UUU333��3�f�f3�3f���������������B���tRNS�KF���bKGD�H��"IDATx흍b6I-%{,sy@I	&y'm B1`�U�S/1@A/X@YE;}~}fvsiu}slp�'(HN�%ة?1#w+4~]:0[X)ڭ]&;:M9ﭗKC[lyX;y;<k-RnMHǏk@v)?wKT:{«&ְl!;'OekRfvw24`RTwL
    zN4)*.e6^<$<!x ZV4%sRJt˿Gqiovn
    vyv~굙l4ḧ́I)FҗӃ&	`IWv0U~2+YXD�0��`�#�n`3FZlhryom̖:Q7\*+"r;6,ɭ|p`|r.*c&n1܂j/`uٹw, L$TGT
    p`Yn{_lTUՇ3I�`X̀Si+`Sr`v}?|>~>~5KM\^j;7	6
    Fx|BdN_֯yn(jVo߶(w�
    ]
    BjD/W;.N]*pQ4XAK$W`7#]6W
    e7
    /	O}L�ח̿DL`>j_cus3ѳw-j*+7~fP{{Tq)5sEh${);֢ٹ|?δu,(̢>}�7B)&|Ǥ}
    ŧO9!)U{~XE~&
    1AJi�+7'<=c<~c_<���`�#��`�#��F�0�F�0;s1Ttr2.-|ٹ}ͪ,5G"2z.n 
    xhwr %-C048z
    #|#kZrs}W e78([HZ0/\L7 qDb2Lڪl5s-gd~5+4{;oIZcy[%[
    pAiVx`b
    8=:`ОPBOq~;{Y}U'B6Q0/,
    GM=6,|fc'
    Io�+YXD�0��`�#�qx`v�,5owg1cuCaW(Q63viӱ"!"|+>w9ލK%o/R*^׶?m:Ϯ/?~i~hXM[Fw¢\Mw@Hn(lJ?_\_d%cս߻hnՋ�:W�vw3�`F2xZ�n&F́n_}Zojw+3<Wv{E?vb]?0_ap{.\qB?Eh!q8`U{-ػǧf|5)9XZ>&l:sj�k.L%GָGSIH_o€)'pa_IRoSjebh$Hsg$\ATaܫZL&+vk>MN]WUW60*떒Y8#nXGovQpG?CY.${\i?3oQUQʛ4+_K_<W<ArGcy?%W(G~p{/.?)8V!_G)C3KJսszp&6eǪ[0�F�0��`�F�0��`�#���`�#�q,`{~DZs{GN|W1M
    f;`4#bF1;7gb^Qpj)ck ?g⋚i!W&i8.AR.Ͽ:`:whV׵k~u']mrkAD9j8n0'72dkjv'u_x%�^ˍ6@2w_wnV
    bk!31/t^6s}+mݕhLr]G)[ט]8es9]dTTv{?}#_H~
    i=W{@J+YXB�0��`�#�QKO=<pa=x'"L{{Q8�\{x,/n�=T5['gxR'-t�]cgZ
    AR^�V"(>bN|[S)
    7ƻb	wa3Y6}c8Y	"ed/5R?>7)ad
    \᏷!F$|*=0𛔰-sEIwm[|Lᥚo{"/3pՓ		'YrnH�vzL'{o2²I=*{dpV�/L
    }|t[\NC"+-[hM@X2\#}o^xqj&`;\+olŠsU6߇Tp=Oj&BvN{A7
    1xk1.XuTKY9|c</*qUpL/րUY>/<sx�LR^Y%;DžyiHsyzL/aCMe5��`�#��F�0�#��F�0��F�0�0ˋPe*8vDk\f()EڤW{IY~ţQiY4لDQ`f/@nҶF=f;4ѝyϓf%~n=#7>yʧrdiP<UlLڋI]>IZUYa܈ōڍ=8RG1`n�wyЦ\ܨp+7u7ƹWryÎ�7bvZu&+x+V'ríIGUI[Ua./ޯ;$Q1_`'\6~tX[^'k_܉3^TߴSZtvb2M;}/Iw-ܞs_|!iJb%K�F�0��`�AٸCЮd9FvX1EZ>sq۞5`�0p�8#*
    x*9!`pa1k"
    0m(Cyzy*�SD%EO`o+bw$᫫`,1A
    Rp#g;oSRlH!N>|?X5Jp'^ԣwo ,0ݡz=sjڡpU5K4%@]E3Q!0ݞ^۷q90%@=�XyLl *ol#c$򄀩ܷ,yoMRƔ`ۈXؘܐN|
    %ޢ10
    _dW{Oxx<R܁g;0l?xzqp
    nkN܏֛t7jq|~q=agB:G4Xe)q#&MJ?c=db?D+Y
    `НhusҺՒnjZpPSlqN'zsDB/~l�0��`�#���`�#��F�0�#��F�0bG	5#1`g0i۲ۛ_(dcg{ns&}$֨
    sM1KqX|׿n
    >7nxge";ąY_V0oN
    GjڜPbSRUk\Z
    Ӓ3-LwF|Icv]O)Gy䲚[y.mKfB9d/B9`"5쮦
    ^x{	+Ī`˫`Zm#`OG%;6u|/1--+x{*ߍ|s�#/ef{4Y|/޾M'A훚R4g-ۿs9WQ9)J*��`�#��53jBӮjov+gUVK׫Gfv3{}pmv;C
    Dy>0\)kۏa+B(iKW˯KJ݅ؗwps`V'
    M\]~p-ʕwXjJݮp/H	XX!$y�7%`nK�_ܾAQZ[Ā}.vSom\.?7o*A؈�)x1WGp!MܪeRJwB\ٗhv|]	�n͡Lj6`B
    p]߮R76vĐ\ `BGB
    /vJxF_gKb-rOΎGX:=>h`$|1g$k3o%EUR{L%++%o}Wzu1
    .t"~ݠ*С`
    S=&)*a]<<�慎*XaC݋snr,o
    V|\Xץ:,tp5KE:3jBӮ
    ]xC\Msܟڃ��`�#��F�0�#��F�0��F�0�x4`{G7giWg+
    ~2#׬";6WxYi54^)o5-\M%73rM [ي9tl-w2q^~.ÈKGr+%^XyL}n[n]y)WZC&tD[E[Eggi[@g#
    \Y#3>ϖ4}b2<_'k\C9-Fc\da�F�0��oA	)`Cp!SDuAn0?9`p`CP$r%A'\ae{p1rs܅\?-M}A_E\R1u0wu
    v17Ź~?Ɛ�6f�u
    @;6,>iYu``d~>}X1|WD+6>0,zؔLrJVQŜ~%ܲ+Y9:r}\Ztn܅Cu&1Wif?p>r�#J�0�#��F�0��F�0��`�0��`�#鴦?yS/hWO7wo.]X*r{ZO�."aVXxOlhx�491T;y2*IYU0򝠉/t}|V֮WYB0ԐQ۲BFBWyW`
    Dh'b!(l70ħl}
    h>c)8uWIh՛�~]o0ef¿c3TA2͈q?:wAi$bO#̓6_y7}#]>J�#��F�0qo]_Agw5~M}vf־(rŰwoꕾVXҷnT﵍JntOo+�&
    ߴ{$='Ĵ,U[�wx[""||mjyW*[l<|Ep�D]|-VNBлD
    ЧSޒzmX\᠂%JfiBr[R;chW�SXX*iB
    $�*Tl*8J'J$KVeoaM;
    c�/Ud(K.U
    1`ed9co(fKtt|	ke77%]/ц
    j86(`
    [!`w6peM9$FmuHv6`V}`l倷5;?{oQjFn_|jWfdp	�`�#��F�0�F�0��`�F�0��`D	LອB)	A>oI?^1̡a':I0^y_ce�\M&$_}n^9O4OLs"=4	/ަ+	BomJ$l^)Tktw7Q/́=qLcGs8Sj;6Yq%8#1XA.WGr\F
    -lBMc^<ߠ	/;|w~m1gGSOn|G*ӜM=|\Rӎ
    $H;;!&O da�F�0��o+gw&>˯vULsI"K�X8V;85.?):2`ŶG;9~Vv4ΚB�0^H9V`31<q.qOnv QK
    x{_ռ^.5)�Bgy2īoZ*X9gv{VP^.~ͫ?Vը[;7rcGsiɳQl`?;N~յ`ӭƙ6r#gs�Xl`ߘoܴvL	`v
    7̥}@W=�
    ^:mK[x6QoHHb's�:+�<߿%W;qރ=sCYE@]$]<K6)+XGynȭ`͜duPrsiԦ_Mdol;yU'-^9Ll4I`x<Kdj'd)+xChc2?4q̢w%
    xEQaR|ex}n	/Whi`X�-q׫k
    x+#,Q\~|2c't	̇o<)\~8B�0��`�#���`�#��F�0�#��F�0`Zuqd~y/UK+F-,4.N'EG
    H"`
    	i%<y:0z^A紒ep4~^R08Lm+<%j-`/[^QFgQZP<]fo?T&WH<"l-Ox8|
    7*F*8<-LyfѴ`d2(ݍj6w&__^ރ?{7WQ&>sכOWz؋PnbH[z;]G	+Y�F�0�#��F�0a܅͙,t.ܡ]Ͷ^O%X`qJ�WE `?R a!26Dt]Ox0{3](,un-ھ
    owbd><EA]`A]N
    p[�Kf͸;v،$o^cqxd>?ќ4P3֗owv/3NR#4R*LtP{&ǵG~>??O#;15s
    60	o
    r	
    l4i`;\[�_|>o%�,IDB,xe}V�|Yė
    Xo7a5<V�|	k43vO|V9o*i�Kĺ"wpy/\u0ɪ{ۢ܅2ºvb96)j᫬`JC]9]vU9pm<Tͱ߳,U#~6T1Ækwm�i-Zh]q'-q{`B>Чrq3:�`q7"P7?���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/forward.gif�����������������������������������������������������������������0000664�0001751�0001751�00000000333�10147723030�017014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����fff333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������N\DԅAiQyNS/EH`m+}Cdq03�
    UO)lwk%ˊ3��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/c.png�����������������������������������������������������������������������0000664�0001751�0001751�00000000453�10671421551�015621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���ZIDAT[
     @@V@PDgKSu3'R\bYIQ/Inznt�ٞƈ]\(_���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/a.png�����������������������������������������������������������������������0000664�0001751�0001751�00000000462�10671421551�015617� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���aIDAT[E	!DKtXRX"Mu233hq.]sni=Qx7mbR~	uhK'j:F`)u~~���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/generic.gif�����������������������������������������������������������������0000664�0001751�0001751�00000000335�10147723030�016766� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������P80@#i;U"(1RDmL	K:K
    |9㑨 e,Q)vL/q+ym%��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/text.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000345�10147723030�016337� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������X80@#i;U"qDR'
    nJn(<:{PټVEnY2~Oڍ	�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/burst.gif�������������������������������������������������������������������0000664�0001751�0001751�00000000353�10147723030�016511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����3f�fff333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������^(0ʩlll7\'4kuB5'PcRHS6LA| م٪3�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sphere1.png�����������������������������������������������������������������0000664�0001751�0001751�00000000533�10671421551�016745� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33̙f��333���IĄ���tRNS�@*���bKGD�H���|IDAT[u1
    0@\
    8:P2JQrlKS	a[ɐy
    mU&0(
    R);'&\%! ŘxjyA=g/Wm33/lq���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/unknown.png�����������������������������������������������������������������0000664�0001751�0001751�00000000463�10671421551�017077� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���bIDAT[m
     \
    a�	`!hzBj)!xŘ^騔z5n'2[{fߔ2.F,biz;Yӈ:F^U.+���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/hand.up.png�����������������������������������������������������������������0000664�0001751�0001751�00000000460�10671421551�016732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙f3���$(���tRNS�
    A���bKGD�H���^IDAT[	0Ьp$.`?S5~կǡmִ/x\Vt+mPIsA-Þ^ɘ!ÛxȩƊlS87V x���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sound2.gif������������������������������������������������������������������0000664�0001751�0001751�00000000335�10147723030�016564� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙fff333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������PH-tYC$!zP(
    WɝEzU[4J쯀1T/g�O9T7A3n}7њaʌp^$��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�016006� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/compressed.gif��������������������������������������������������������0000664�0001751�0001751�00000000200�10147723030�020615� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���kkkZZkJ�����!���,�������E8.)bԮ9&^)B|U}JAt #D#-v
    x$zQa@]E�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/image2.gif������������������������������������������������������������0000664�0001751�0001751�00000000212�10147723030�017620� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���RR�{!�{RRZ���!���,�������Oܾ@Z
     uQB
    wFQN-X"ʡGt@if[hzL��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/comp1.gif�������������������������������������������������������������0000664�0001751�0001751�00000000202�10147723030�017472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���)!Zcc9s���!���,�������G(0@%xf	GTTj)pP3C@,1qT:Ђ4KQK`G8`��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/comp2.gif�������������������������������������������������������������0000664�0001751�0001751�00000000203�10147723030�017474� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���RZZs���!���,�������HH06Q-o`9VtaEACZ
    0pċeR:IR4:0Epx\L��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/sound.gif�������������������������������������������������������������0000664�0001751�0001751�00000000202�10147723030�017603� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���sss֜��9JJ���!���,�������G(p1[;D
     `W@DPo v͗cz7a,F`
    AQX��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/ps.gif����������������������������������������������������������������0000664�0001751�0001751�00000000270�10147723030�017102� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�������999kkk���!���!by Martin.Kraemer@Mch.SNI.De�,���������999kkk���ExG0HH-F`M)TY?8-W@$v)kFKc zE�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/movie.gif�������������������������������������������������������������0000664�0001751�0001751�00000000206�10147723030�017576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk������!���,�������KHL/I#;^i"D
    (RX$رx&У^GY)
    i+NW
    J�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/tar.gif���������������������������������������������������������������0000664�0001751�0001751�00000000204�10147723030�017243� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������IHܾ@k1
    Zw^QU32;/3
    SqG)6Îv*6x<-�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/burst.gif�������������������������������������������������������������0000664�0001751�0001751�00000000200�10147723030�017610� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���)!ZJ9JJR������!����,�������E0¢Dh0CR,)oUaKׂ2lQ[fL,)*+t�P)G�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/folder2.png�����������������������������������������������������������0000664�0001751�0001751�00000000264�10664777241�020060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEkcs9!sJƭsk������9rar���tRNS�@f���bKGDaf}���=IDATc` 08�&..Ά&B`G�À4���:3\4����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/generic2.png����������������������������������������������������������0000664�0001751�0001751�00000000263�10664777241�020220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEkkkZZkJ�����:A���tRNS�@*���bKGDa���9IDATc06R6cWcaÀŕ	`2 PQ(``a(&((hl�&en����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/generic3.png����������������������������������������������������������0000664�0001751�0001751�00000000253�10664777241�020220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEkkkZZkJ�����������!���tRNS�0J���bKGDo���3IDATc% `1`�a(@*0
    L6L.����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/sound2.png������������������������������������������������������������0000664�0001751�0001751�00000000253�10664777241�017733� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���VIDATe�!m
    EQAjAx8ˠ}!ZU`;τ�#,wWG"uY
    wj#k����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/doc.png���������������������������������������������������������������0000664�0001751�0001751�00000000336�10664777241�017270� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������7���bKGD�̿���gIDAT(ϝ
    �!Di˚lek
    A8w!s C(0�=}z&ZeZ= <f.	zu;aAZSMv]	���$tEXtcomment�by Martin.Kraemer@Mch.SNI.Deh#����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/rainbow.png�����������������������������������������������������������0000664�0001751�0001751�00000004573�10664777241�020173� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��/������e��PLTE��pp�����(���((�0���H����H��HH��������X���X���X��X�hh�������(������xx���h�h���� ���  ��@��@��@@���� ���8���8��8�``�����������`�`���������P��PP������P���8�0��0���0��p���px���x�������������IDATXí[G0BEr((ժXRT$Z4
    |gvwfw{cwo5HHKKghʷ.T&F}髠ר/iPj:JmAuC-(6P@[R41=:ht5:	*,ϡ^#Hd5]�JT4zx>00pBr\j	4W*q%:jXn,˷Q^'PS,{zjhhH4$eTht<L&_5O?k׮Gz@:ABp511'jԺ:
    ]W�0k˛5geyt	4<`f)ex9D^`%�fsd`P3F%`4.�Lxup9"/Sdq0.�
    �fyyq`ʷyw^󂸼C^b%Q
    �yq(`&%yqeDB 1&EĤa/
    &"`h`B .�sQ 0C`~\N.y	0
    fsvƵ)`:^JEsi<^	^]0/
    Flme`.�L�a`K'ø�0{0W40˚Fhi3pe8N} ^)
    0G[GCGHqeiA$ō@t\ѱHaHH
    qk\l-QU8dxY//L,fH	eHHI/M_(_d @*X{QP !0:V188_^6E�ū/:\9<HRBq#]`8yDqdnxbByqDp{b%_8t1/Gy#]wn#/"n_yDEQ)
    AE/L(*摪9Qw"h`G_87BG2}̣I?2]<rK"ȣ׼Mݽc(/	xS%Buw։#w_DMy#/*}ȣIh^Twl%_4/_ZDݝ8B/wŜF/rN(x9;w.vP%<A=]_9S_4{KAs/…/_EIb9G`lr~jG'Gbi=2e/K_l);//Uv
    h5ĹṆVCą닳R޹nN^ |+p>:/2r6"Q_w9^rA	Vݶ>vGO_Rlĩ)[>*zEnT`
    9
    /岳r>Jx[>#/v</_	}dɣѳ}"#/!sQbq
    L+u{ͣyY.wͣRD	]kT>/w}D}λ/CK(D>r#xOHw_vun}tTuŽGkGEbÁ#wCHwλ{}/x}TﻣaN|W����IENDB`�������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/binhex.png������������������������������������������������������������0000664�0001751�0001751�00000000262�10664777241�017776� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���]IDATu
     Y+3e	c
    AB٢ŕVFQ2I gynH>'$68jdOEXxeYr����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/image2.png������������������������������������������������������������0000664�0001751�0001751�00000000313�10664777241�017662� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTERR�{!�{RRZ���v'���tRNS�0J���bKGDa���SIDATcb0000Pe0`F@z�!n�fC.`X
    c0 �i`����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/key.png���������������������������������������������������������������0000664�0001751�0001751�00000000322�10664777241�017306� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������7���bKGD�̿���[IDAT(c` G8?tѕ+�A z9m	(
    !4H48)p$cS�L+R�
    lI�RF7Ǜ���$tEXtcomment�by Martin.Kraemer@Mch.SNI.Deh#����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/comp2.png�������������������������������������������������������������0000664�0001751�0001751�00000000327�10664777241�017543� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTERZZs���k���tRNS�S���bKGDa���\IDATcp,P9DII%UR
    3R40#Xؠ0
    
    kcP(C0U6J�E@;EAj\A �.⦔S����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/compressed.png��������������������������������������������������������0000664�0001751�0001751�00000000324�10664777241�020664� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEkkkZZkJ�����:A���tRNS�@*���bKGDa���ZIDATc0ccC(ÀA`2!F !ld,`f00 bs 
    
    �[W+����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/generic.png�����������������������������������������������������������0000664�0001751�0001751�00000000225�10664777241�020134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���@IDATc8``py\9.K @@6)p'.�.Ӡx1����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/broken.png������������������������������������������������������������0000664�0001751�0001751�00000000270�10664777241�020000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���cIDAT]
    �!PkWH@
    bpp27MO)8`Qaj $P
    ^]\)
    ͒g?[NĻA:Gcwa����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/folder.png������������������������������������������������������������0000664�0001751�0001751�00000000304�10664777241�017771� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEޭܮ}WK;+%������~M���tRNS�
    A���bKGDaf}���KIDATmƱ
    @P
    (ְ	Q`pG\%RV}aٙXa`b~#Xg(,����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/comp1.png�������������������������������������������������������������0000664�0001751�0001751�00000000330�10664777241�017534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTE)!Zcc9s���)9J���tRNS�
    A���bKGDa���_IDATcP,0IPPptq*3҂ 4BCHM
    
    
    MuRbH CUP(' 2_(RRXnNJ��2;s����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/sound.png�������������������������������������������������������������0000664�0001751�0001751�00000000305�10664777241�017647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEsss֜��9JJ���V;���tRNS�
    A���bKGDa���LIDATcPd
    bb3*+1(
    (1200be()A兌`JJbj`@a*ì@�
    ޗ����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/transfer.png����������������������������������������������������������0000664�0001751�0001751�00000000323�10664777241�020343� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEkkkZZk���&M^���tRNS�@*���bKGDa���YIDATc0ccC(ÀA`2!F$a�	c`H1LC]\BP0�2DRCab1D9F�ZK{0����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/movie.png�������������������������������������������������������������0000664�0001751�0001751�00000000237�10664777241�017642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���JIDATc8�@!z ,!,`
    d�%b0  �� b/=Pl��_f����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/patch.png�������������������������������������������������������������0000664�0001751�0001751�00000000323�10664777241�017616� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS��v8���bKGD�̿���NIDATӅ
     CQՙg@xItQ[̋(%'@2q43&/ބT`B���$tEXtcomment�by Martin.Kraemer@Mch.SNI.Deh#����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/tar.png���������������������������������������������������������������0000664�0001751�0001751�00000000255�10664777241�017311� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���XIDATӅ0Ee&o*ՒqF3X:@<�ؿp4#)E]2
    wk;-=3XfT*y>BHv����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/ps.png����������������������������������������������������������������0000664�0001751�0001751�00000000331�10664777241�017140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������7���bKGD�̿���bIDAT(ϝ CY3cHk?xr|U
    2( 0€�p;]6UNHS
    @tI;@?I$a[u	!k~���$tEXtcomment�by Martin.Kraemer@Mch.SNI.Deh#����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/burst.png�������������������������������������������������������������0000664�0001751�0001751�00000000322�10664777241�017655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTE)!ZJ9JJR������ϽQ���tRNS�@f���bKGDaf}���[IDATc`X\ Q�CPRR6662p1JAC0Tk`p2@$P0#QbK(�=
    1M����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/forward.png�����������������������������������������������������������0000664�0001751�0001751�00000000256�10664777241�020170� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���YIDAT]Q
    @1UMRQS[c(*JM��BS0T8U,D24q@5w
    ˉ6sݥ]?Z-3̩����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/index.png�������������������������������������������������������������0000664�0001751�0001751�00000000341�10664777241�017626� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTE!!!ZZZ9B9���v3k���tRNS�S���bKGDa���fIDAT5A@0A9�}|46K-&A!�`?by#$@ua4kX[uƁhqbJŴ*$
    	
    ����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/back.png��������������������������������������������������������������0000664�0001751�0001751�00000000265�10664777241�017424� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���`IDATӍ
     PVapd(F+՞J(	z	"x+l@;=(	@fS�E*5oѯ]����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/binary.png������������������������������������������������������������0000664�0001751�0001751�00000000254�10664777241�020006� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���WIDATӍ
    0ՙ
    C1k0*t
    K1X2`D
    nGQ�	lx@ulPA'/}{Nm����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/unknown.png�����������������������������������������������������������0000664�0001751�0001751�00000000254�10664777241�020221� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���WIDATӅ Pr&Va(&ASz|q9eԠ6
    *pK1p?�%b7E&A~�JǬ0����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/image.png�������������������������������������������������������������0000664�0001751�0001751�00000000305�10664777241�017601� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������R���PLTEkkkZZc19���I.���tRNS�@*���bKGDa���KIDATc0aZeCPFXaa(LPF1#�f(Ch@Ab � 6����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/blank.png�������������������������������������������������������������0000664�0001751�0001751�00000000144�10664777241�017607� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���IDATc8F��
    !
    X����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/text.png��������������������������������������������������������������0000664�0001751�0001751�00000000243�10664777241�017504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���NIDATӥQ
    � e& SP}0v;6Z.Bqu5Ewbna BO݅7OQ)8,!LI|:�پ
    ����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/folder2.gif�����������������������������������������������������������0000664�0001751�0001751�00000000172�10653705265�020032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���kcs9!sJƭsk������!����,�������?0J9U;A0`YY($yZi@6Xn
    cs,@XX+1�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/folder.gif������������������������������������������������������������0000664�0001751�0001751�00000000204�10653705207�017740� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���ޭܮ}WK;+%������!���,�������I(bΔ1Ѐ2v$GQAy6#v"_dE輞
    t`$eP	8 ]n$��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/blank.gif�������������������������������������������������������������0000664�0001751�0001751�00000000067�10147723030�017553� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a������!����,�������ڋ>�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/uu.png����������������������������������������������������������������0000664�0001751�0001751�00000000246�10664777241�017154� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���QIDATӅ
    0@ՙX52P_d	ڀ![	|V3	@t)WFSO'~����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/binary.gif������������������������������������������������������������0000664�0001751�0001751�00000000206�10147723030�017743� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������KHܾ@k1J'\WDlaDF!opS``ŷ)7B<;BC",Y�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/uu.gif����������������������������������������������������������������0000664�0001751�0001751�00000000175�10147723030�017115� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������BHܾ@k1J'\WDla4p-pA/.|sX{ň<$&j(]R%ve-�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/continued.png���������������������������������������������������������0000664�0001751�0001751�00000000243�10664777241�020510� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR����������:���tRNS����bKGD��#2���NIDATӭA@& *
    bdlߗl	op'dlM"[ٗO{lXV8Ta
    91	T-Zk~'[&iWh����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/image.gif�������������������������������������������������������������0000664�0001751�0001751�00000000176�10147723030�017547� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���kkkZZc19���!���,�������C8<'
    s(!xal o#LJ
    0m@{іTzTp.˅@	�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/continued.gif���������������������������������������������������������0000664�0001751�0001751�00000000162�10147723030�020450� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������7H0IY+5
    E ]�
    ibp-HǓTi:G�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/generic3.gif����������������������������������������������������������0000664�0001751�0001751�00000000161�10147723030�020156� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���kkkZZkJ�����������!���,�������6!0BvqK'ADJ0"q4p'	`l:g�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/text.gif��������������������������������������������������������������0000664�0001751�0001751�00000000200�10147723030�017435� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������EHܾ@k1J'\WDLAjxFlPme,	Z		*oJI,No!α$zE�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/generic2.gif����������������������������������������������������������0000664�0001751�0001751�00000000177�10147723030�020164� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���kkkZZkJ�����!���,�������D8*ORTY�
    qwA#9a@QՓv.ېh-aGHV0l�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/sound2.gif������������������������������������������������������������0000664�0001751�0001751�00000000167�10147723030�017677� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���������!���,�������<8L/� Μ`I_(4%1E	R(ǑF	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/binhex.gif������������������������������������������������������������0000664�0001751�0001751�00000000203�10147723030�017731� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������HHܾ@k19FVQu$2S%+<tl&|
    OɆQ&qVLl#mp8H��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/generic.gif�����������������������������������������������������������0000664�0001751�0001751�00000000164�10147723030�020076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������9Hܾ@k1J'\WDla*BrF}ΜN!'Qc+	P(k��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/doc.gif���������������������������������������������������������������0000664�0001751�0001751�00000000277�10147723030�017234� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�������999kkk���!���!by Martin.Kraemer@Mch.SNI.De�,���������999kkk���LxG)HYdmWM]6e)ҺVt4+@�D#!d t,>kLK
    !#(E�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/rainbow.gif�����������������������������������������������������������0000664�0001751�0001751�00000007343�10147723030�020131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a/�����pp�����(���((�0���H����H��HH��������X���X���X��X�hh�������(������xx���h�h���� ���  ��@��@��@@���� ���8���8��8�``�����������`�`���������P��PP������P���8�0��0���0��p���px���x�����������,����/��CCaaQ;	;	oKKAAccc#L$ww000^^P:pHH...hh)VV***��{{|2UUkk''T  sssn`A
    5YhC>"CbfhqcG =I=R8’fM'8yI&:QY",`6XٺW
    b@lYjU+-x;7e[lL0tXx)&"`CM:`ټgyBmtWXZk(bPC[
    Znˆoq9@@9$sǘ>u%h½"Ȅ'CFy@+Yލ{7
    +P>)|ٿ/�8HTDH#DZ&Ad‰'2(	+` ,.P/S182@4\
    �tӍ7|3Α|#C:<cӏ?�
    $A\$C
    =$QDQFqQH$I
    RKG$LxڄCN8PD%ADXP` SQM�UW]ZuUXcUZiŖ[pt݅^{eC`f!X�Yd]ugKiڲi![lofpr1\tRWumxGy{7|_`#Nn2h!#
    	wPJ,%X-ˋ0
    3&S8#M
    Vc6AnHcNK;PIe>WP@[e>@MDfb4j~tntRqιRu”MN٧NSMTBU\Q ĥbdjhV
    n%*p^ kbيkUFYf;,k,1`n[m!msun@nڝxw@(nP޼'}o+& OR_0hXJN
    ,Ӳ-�Ɋ1#G;5`#
    H5tIkp<~6%c(�%.ii_jHF2)MW׺�il-SLdO~r[PuBnvcTU6HjR}\bN-R]b*eUr`d1Wsd&9ЉnXLHdN5Zl\hN72r-mN9E<q];:%A=^|U_�_T )(`{$־LXaLA?~+-�Q@fLGhY5f5St3xhFxpAi'LB=PXֶyk*9P6<DO|:(
    )J[%BZ߾"M
    pB'8.e@T5WrSc]WL8Gќ.uc]dnZպ]q[^<`yZ%L^{^}< JBZX,I#,400x,Q3	hR0g|RϮ*YIY	pLe45q
    ]óDm:ӟV#&)wkTޚJm\b8!-r!1/vrd4GR]usь>ҖڡIֲغ&ZҪ og[?U$tH!\BwTb2^}G|(1TR}J&<0Ѳ~ֺKB_Ȇ1W	d˘=<06 :.A
    F
    A@,aVrQ9PNtIvCD=b?E(C)5AZ,+WLhQq0iEz+
    )
    Rq5j
    u5iw{zD&2id(oI$z:gԞPW@#)ծF}x%\VSUD#ṟo2"/7$I$`{¦-ıbHdNĝpf&;{BNF
    wUB*[Jp8QT::fn>ir+,JM,gv]nY$yFծwz'9
    ]@)߂US2d/DH+^Er%0-|ᔥ�k̜YpHMR1%Wh.&8Q8NXISyY8-$=}us4"eY剮}-B,p^mظ1̮{4ȍ;ǔhо;=F;e(ԧK{叧wC$TR>-)f\2PXW63V,\/ofAvdJdoqĖ ᴶ
    ŠNoY@F':t'8pnF6>1DTDsDUo
    ue
    %[)8Z[]*39+rphp
    FpW:ww,Zzg!;W-DHe-%<#7.I)i<6=Ii=s/Z_sJ�K!d?`L`?/}k$~w5
    Y@63]WKX;DX0m7bkXFNvcqNkNmR6YAF6fSd{ZA6dU7DP]YxW[XE8EyU9)fiF9nFu]4xzzg7U;a;3hS<G<h&WT<eIG=_U|T>%j	r>ɗ>^t7`BV!HW1(V,W$23RL(3~+kxæ~džl3'&gb4ڶm(X9YnEDrPo(EQxSof[f�pdyWp!5\#łR\8szgwSzWHq$rQ^w{ir/PiAs/X \s ]>4`#Kdtk11N1Ha%c2Ƅ@ɔū~WGu#v4v(6+vXXrjcn׈pw9&dyWn{w@xq32PbxMPeeQE_F'H�gF#z"gt6wG2z:hS׌^Fg{XM南_2w`�jd_0|0ftr`}aǏ{72~W@i73M~c'%el)mmpw59Vd0an	Y}'nrs(HPD*UYowoɁ1)(eƛbkƓ+XRkp(]g4qq"AqD(DrD"+ǍZs5i��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/key.gif���������������������������������������������������������������0000664�0001751�0001751�00000000273�10147723030�017253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�������999kkk���!���!by Martin.Kraemer@Mch.SNI.De�,���������999kkk���HxGY5k?v-Ga	l(U?y;a
    %C`0ȂM
    Z2H��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/broken.gif������������������������������������������������������������0000664�0001751�0001751�00000000213�10147723030�017735� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������PHܾ@k1J'\WDla*BrF
    2. �? 0(5<Ylr\N:7:}T$��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/transfer.gif����������������������������������������������������������0000664�0001751�0001751�00000000174�10147723030�020307� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���kkkZZk���!���,�������A8.)bԮ9&^)B@ZETDN5@Ff(oP%̉yi
    T+H��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/patch.gif�������������������������������������������������������������0000664�0001751�0001751�00000000266�10147723030�017564� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����999kkk������!���!by Martin.Kraemer@Mch.SNI.De�,������999kkk������Ch6%2c	85Uh@
    A¶:
    !]jRS&
     	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/back.gif��������������������������������������������������������������0000664�0001751�0001751�00000000201�10147723030�017352� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���!!!111ZZZ������!���,�������FX
    I`LV tf]Qn(iàZD,00ZLa"* ѰEq3J`p#�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/unknown.gif�����������������������������������������������������������0000664�0001751�0001751�00000000203�10147723030�020153� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���!���,�������HHܾ@k1J'\WDla6:TLu!ݩC�+BJe(sgiNP)H��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/forward.gif�����������������������������������������������������������0000664�0001751�0001751�00000000175�10147723030�020130� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���999kkk���������!���,�������B8+�XVDe$ʼnCE8Xu_HG"QqI
    .r$��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/small/index.gif�������������������������������������������������������������0000664�0001751�0001751�00000000221�10147723030�017563� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���!!!ZZZ9B9���!���,�������VHܾ@Z@`GEqxHpkB`Db3rBgX<hT @)Xۂ-Ҹn<H��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/generic.red.png�������������������������������������������������������������0000664�0001751�0001751�00000000433�10671421551�017562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEfff��333���0���tRNS�@*���bKGD�H���BIDAT[cpgccc'% PA0L(aiiiPLTI	Dw3A1�)a���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/image3.png������������������������������������������������������������������0000664�0001751�0001751�00000000522�10671421551�016541� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33f��333��3�3f���{D���tRNS�
    A���bKGD�H���qIDAT[M1 .ѵW`r4NLasbvcu2^Z*ӗ4�[P4hh&N)V&5Q�[)㡤t7u
    s]IڝNOb4.45(���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/continued.png���������������������������������������������������������������0000664�0001751�0001751�00000000450�10671421551�017364� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEfff333������tRNS�0J���bKGD�H���TIDATα
     CQ
    ,A] WLoK;,NbΨr%i.֊.0|)N<@C9���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/alert.black.png�������������������������������������������������������������0000664�0001751�0001751�00000000445�10671421551�017562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���TIDAT[m
    0Nn!JDvx!Hd_̬*'"}0BEzdD$Mc_kGl'\�</-���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/binhex.png������������������������������������������������������������������0000664�0001751�0001751�00000000477�10671421551�016662� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEfff333������tRNS�0J���bKGD�H���kIDAT[e	 DEp+*MBqS"GFB 6^ԛ8bRL"7h۶rYa3b-8O!hc1���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/right.png�������������������������������������������������������������������0000664�0001751�0001751�00000000376�10671421551�016520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���3IDAT[c(	& T0L T0LD"""Zd-{e+8:���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/generic.png�����������������������������������������������������������������0000664�0001751�0001751�00000000423�10671421551�017010� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���BIDAT[A
    @EZ WBk@7Es$I
    w0S33w˱]>jj�e	T9w~\���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/link.png��������������������������������������������������������������������0000664�0001751�0001751�00000000472�10671421551�016335� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33f��333���\���tRNS�
    A���bKGD�H���bIDAT[M	 Z{Vp lAGpb|O gIi<J)Z$p!<- tmZ26-f#~~ ����VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/p.png�����������������������������������������������������������������������0000664�0001751�0001751�00000000452�10671421551�015635� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���YIDAT[
     @@V@P3)A<_'+$ifJJh)EI1&Uj<]>Sn_{ˊ>ie)A���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie8.png��������������������������������������������������������������������0000664�0001751�0001751�00000000403�10671421551�016237� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���8IDAT[cd*j)\je(CتUBT($$UBB́	2�6}(+���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/blank.png�������������������������������������������������������������������0000664�0001751�0001751�00000000327�10671421551�016466� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������.E���PLTEsQ���tRNS�0J���bKGD�H���IDATc�Yi*pl���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/up.gif����������������������������������������������������������������������0000664�0001751�0001751�00000000244�10147723030�015775� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������#MZ= XbI,LvP��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/binary.gif������������������������������������������������������������������0000664�0001751�0001751�00000000366�10147723030�016642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������iH0@$Y
    ]!�q^	k굮jAvQh)n%Ӗ*ԂZU)􄧴9!_8s;	JI;CS	�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sphere1.gif�����������������������������������������������������������������0000664�0001751�0001751�00000000435�10147723030�016722� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33̙f��333������������������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������xpI8:@ AjtnEC��w-T2VTʬWh5awE_=}L~$y{~VSz_qwm?|H5j&�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/README.html�����������������������������������������������������������������0000664�0001751�0001751�00000106331�10664776532�016534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html>
    <head>
    <style>
    a { text-decoration: none; }
    img.whiteico { padding: 4px; background: white; vertical-align: middle; }
    img.blackico { padding: 4px; background: black; vertical-align: middle; }
    </style>
    </head>
    <body>
    <h1>Public Domain Icons</h1>
    
    <p>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).
    Andy Polyakov tuned the icon colors and added few new images.</p>
    
    <p>If you'd like to contribute additions to this set, contact the httpd
    documentation project <a href="http://httpd.apache.org/docs-project/"
    >http://httpd.apache.org/docs-project/</a>.</p>
    
    <p>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).</p>
    
    <h2>Suggested Uses</h2>
    
    <p>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.</p>
    
    <table>
    <tr>
    <td width="25%">
     <a href="a.gif"><img class="blackico" src="a.gif" 
       /><img class="whiteico" src="a.gif" /> a.gif</a>
     <br /><a href="a.png"><img class="blackico" src="a.png" 
       /><img class="whiteico" src="a.png" /> a.png</a></td>
    </tr>
    <tr><td colspan="4">This might be used to represent PostScript or text layout
    languages.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="alert.black.gif"><img class="blackico" src="alert.black.gif" 
       /><img class="whiteico" src="alert.black.gif" /> alert.black.gif</a>
     <br /><a href="alert.black.png"><img class="blackico" src="alert.black.png" 
       /><img class="whiteico" src="alert.black.png" /> alert.black.png</a></td>
    <td width="25%">
     <a href="alert.red.gif"><img class="blackico" src="alert.red.gif" 
       /><img class="whiteico" src="alert.red.gif" /> alert.red.gif</a>
     <br /><a href="alert.red.png"><img class="blackico" src="alert.red.png" 
       /><img class="whiteico" src="alert.red.png" /> alert.red.png</a></td>
    </tr>
    <tr><td colspan="4">These can be used to highlight any important items,
    such as a README file in a directory.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="back.gif"><img class="blackico" src="back.gif" 
       /><img class="whiteico" src="back.gif" /> back.gif</a>
     <br /><a href="back.png"><img class="blackico" src="back.png" 
       /><img class="whiteico" src="back.png" /> back.png</a></td>
    <td width="25%">
     <a href="forward.gif"><img class="blackico" src="forward.gif" 
       /><img class="whiteico" src="forward.gif" /> forward.gif</a>
     <br /><a href="forward.png"><img class="blackico" src="forward.png" 
       /><img class="whiteico" src="forward.png" /> forward.png</a></td>
    <td width="25%">
     <a href="small/back.gif"><img class="blackico" src="small/back.gif" 
       /><img class="whiteico" src="small/back.gif" /> small.gif</a>
     <br /><a href="small/back.png"><img class="blackico" src="small/back.png" 
       /><img class="whiteico" src="small/back.png" /> small/back.png</a></td>
    <td width="25%">
     <a href="small/forward.gif"><img class="blackico" src="small/forward.gif" 
       /><img class="whiteico" src="small/forward.gif" /> small/forward.gif</a>
     <br /><a href="small/forward.png"><img class="blackico" src="small/forward.png" 
       /><img class="whiteico" src="small/forward.png" /> small/forward.png</a></td>
    </tr>
    <tr><td colspan="4">These can be used as links to go to previous and next
    areas.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="ball.gray.gif"><img class="blackico" src="ball.gray.gif" 
       /><img class="whiteico" src="ball.gray.gif" /> ball.gray.gif</a>
     <br /><a href="ball.gray.png"><img class="blackico" src="ball.gray.png" 
       /><img class="whiteico" src="ball.gray.png" /> ball.gray.png</a></td>
    <td width="25%">
     <a href="ball.red.gif"><img class="blackico" src="ball.red.gif" 
       /><img class="whiteico" src="ball.red.gif" /> ball.red.gif</a>
     <br /><a href="ball.red.png"><img class="blackico" src="ball.red.png" 
       /><img class="whiteico" src="ball.red.png" /> ball.red.png</a></td>
    </tr>
    <tr><td colspan="4">These might be used as bullets.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="binary.gif"><img class="blackico" src="binary.gif" 
       /><img class="whiteico" src="binary.gif" /> binary.gif</a>
     <br /><a href="binary.png"><img class="blackico" src="binary.png" 
       /><img class="whiteico" src="binary.png" /> binary.png</a></td>
    <td width="25%">
     <a href="small/binary.gif"><img class="blackico" src="small/binary.gif" 
       /><img class="whiteico" src="small/binary.gif" /> small/binary.gif</a>
     <br /><a href="small/binary.png"><img class="blackico" src="small/binary.png" 
       /><img class="whiteico" src="small/binary.png" /> small/binary.png</a></td>
    </tr>
    <tr><td colspan="4">This can be used to represent binary files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="binhex.gif"><img class="blackico" src="binhex.gif" 
       /><img class="whiteico" src="binhex.gif" /> binhex.gif</a>
     <br /><a href="binhex.png"><img class="blackico" src="binhex.png" 
       /><img class="whiteico" src="binhex.png" /> binhex.png</a></td>
    <td width="25%">
     <a href="small/binhex.gif"><img class="blackico" src="small/binhex.gif" 
       /><img class="whiteico" src="small/binhex.gif" /> small/binhex.gif</a>
     <br /><a href="small/binhex.png"><img class="blackico" src="small/binhex.png" 
       /><img class="whiteico" src="small/binhex.png" /> small/binhex.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent BinHex-encoded data.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="blank.gif"><img class="blackico" src="blank.gif" 
       /><img class="whiteico" src="blank.gif" /> blank.gif</a>
     <br /><a href="blank.png"><img class="blackico" src="blank.png" 
       /><img class="whiteico" src="blank.png" /> blank.png</a></td>
    <td width="25%">
     <a href="small/blank.gif"><img class="blackico" src="small/blank.gif" 
       /><img class="whiteico" src="small/blank.gif" /> small/blank.gif</a>
     <br /><a href="small/blank.png"><img class="blackico" src="small/blank.png" 
       /><img class="whiteico" src="small/blank.png" /> small/blank.png</a></td>
    </tr>
    <tr><td colspan="4">This can be used as a placeholder or a spacing
    element.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="bomb.gif"><img class="blackico" src="bomb.gif" 
       /><img class="whiteico" src="bomb.gif" /> bomb.gif</a>
     <br /><a href="bomb.png"><img class="blackico" src="bomb.png" 
       /><img class="whiteico" src="bomb.png" /> bomb.png</a></td>
    </tr>
    <tr><td colspan="4">This can be used to represent core files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="box1.gif"><img class="blackico" src="box1.gif" 
       /><img class="whiteico" src="box1.gif" /> box1.gif</a>
     <br /><a href="box1.png"><img class="blackico" src="box1.png" 
       /><img class="whiteico" src="box1.png" /> box1.png</a></td>
    <td width="25%">
     <a href="box2.gif"><img class="blackico" src="box2.gif" 
       /><img class="whiteico" src="box2.gif" /> box2.gif</a>
     <br /><a href="box2.png"><img class="blackico" src="box2.png" 
       /><img class="whiteico" src="box2.png" /> box2.png</a></td>
    </tr>
    <tr><td colspan="4">These icons can be used to represent generic 3D
    applications and related files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="broken.gif"><img class="blackico" src="broken.gif" 
       /><img class="whiteico" src="broken.gif" /> broken.gif</a>
     <br /><a href="broken.png"><img class="blackico" src="broken.png" 
       /><img class="whiteico" src="broken.png" /> broken.png</a></td>
    <td width="25%">
     <a href="small/broken.gif"><img class="blackico" src="small/broken.gif" 
       /><img class="whiteico" src="small/broken.gif" /> small/broken.gif</a>
     <br /><a href="small/broken.png"><img class="blackico" src="small/broken.png" 
       /><img class="whiteico" src="small/broken.png" /> small/broken.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent corrupted data.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="burst.gif"><img class="blackico" src="burst.gif" 
       /><img class="whiteico" src="burst.gif" /> burst.gif</a>
     <br /><a href="burst.png"><img class="blackico" src="burst.png" 
       /><img class="whiteico" src="burst.png" /> burst.png</a></td>
    <td width="25%">
     <a href="small/burst.gif"><img class="blackico" src="small/burst.gif" 
       /><img class="whiteico" src="small/burst.gif" /> small/burst.gif</a>
     <br /><a href="small/burst.png"><img class="blackico" src="small/burst.png" 
       /><img class="whiteico" src="small/burst.png" /> small/burst.png</a></td>
    </tr>
    <tr><td colspan="4">This can call attention to new and important items.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="c.gif"><img class="blackico" src="c.gif" 
       /><img class="whiteico" src="c.gif" /> c.gif</a>
     <br /><a href="c.png"><img class="blackico" src="c.png" 
       /><img class="whiteico" src="c.png" /> c.png</a></td>
    </tr>
    <tr><td colspan="4">This might represent C source code.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="comp.blue.gif"><img class="blackico" src="comp.blue.gif" 
       /><img class="whiteico" src="comp.blue.gif" /> comp.blue.gif</a>
     <br /><a href="comp.blue.png"><img class="blackico" src="comp.blue.png" 
       /><img class="whiteico" src="comp.blue.png" /> comp.blue.png</a></td>
    <td width="25%">
     <a href="comp.gray.gif"><img class="blackico" src="comp.gray.gif" 
       /><img class="whiteico" src="comp.gray.gif" /> comp.gray.gif</a>
     <br /><a href="comp.gray.png"><img class="blackico" src="comp.gray.png" 
       /><img class="whiteico" src="comp.gray.png" /> comp.gray.png</a></td>
    <td width="25%">
     <a href="small/comp1.gif"><img class="blackico" src="small/comp1.gif" 
       /><img class="whiteico" src="small/comp1.gif" /> small/comp1.gif</a>
     <br /><a href="small/comp1.png"><img class="blackico" src="small/comp1.png" 
       /><img class="whiteico" src="small/comp1.png" /> small/comp1.png</a></td>
    <td width="25%">
     <a href="small/comp2.gif"><img class="blackico" src="small/comp2.gif" 
       /><img class="whiteico" src="small/comp2.gif" /> small/comp2.gif</a>
     <br /><a href="small/comp2.png"><img class="blackico" src="small/comp2.png" 
       /><img class="whiteico" src="small/comp2.png" /> small/comp2.png</a></td>
    </tr>
    <tr><td colspan="4">These little computer icons can stand for telnet or FTP
    sessions.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="compressed.gif"><img class="blackico" src="compressed.gif" 
       /><img class="whiteico" src="compressed.gif" /> compressed.gif</a>
     <br /><a href="compressed.png"><img class="blackico" src="compressed.png" 
       /><img class="whiteico" src="compressed.png" /> compressed.png</a></td>
    <td width="25%">
     <a href="small/compressed.gif"><img class="blackico" src="small/compressed.gif" 
       /><img class="whiteico" src="small/compressed.gif" /> small/compressed.gif</a>
     <br /><a href="small/compressed.png"><img class="blackico" src="small/compressed.png" 
       /><img class="whiteico" src="small/compressed.png" /> small/compressed.png</a></td>
    </tr>
    <tr><td colspan="4">This may represent compressed data.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="continued.gif"><img class="blackico" src="continued.gif" 
       /><img class="whiteico" src="continued.gif" /> continued.gif</a>
     <br /><a href="continued.png"><img class="blackico" src="continued.png" 
       /><img class="whiteico" src="continued.png" /> continued.png</a></td>
    <td width="25%">
     <a href="small/continued.gif"><img class="blackico" src="small/continued.gif" 
       /><img class="whiteico" src="small/continued.gif" /> small/continued.gif</a>
     <br /><a href="small/continued.png"><img class="blackico" src="small/continued.png" 
       /><img class="whiteico" src="small/continued.png" /> small/continued.png</a></td>
    </tr>
    <tr><td colspan="4">This can be a link to a continued listing of a
    directory.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="down.gif"><img class="blackico" src="down.gif" 
       /><img class="whiteico" src="down.gif" /> down.gif</a>
     <br /><a href="down.png"><img class="blackico" src="down.png" 
       /><img class="whiteico" src="down.png" /> down.png</a></td>
    <td width="25%">
     <a href="up.gif"><img class="blackico" src="up.gif" 
       /><img class="whiteico" src="up.gif" /> up.gif</a>
     <br /><a href="up.png"><img class="blackico" src="up.png" 
       /><img class="whiteico" src="up.png" /> up.png</a></td>
    <td width="25%">
     <a href="left.gif"><img class="blackico" src="left.gif" 
       /><img class="whiteico" src="left.gif" /> left.gif</a>
     <br /><a href="left.png"><img class="blackico" src="left.png" 
       /><img class="whiteico" src="left.png" /> left.png</a></td>
    <td width="25%">
     <a href="right.gif"><img class="blackico" src="right.gif" 
       /><img class="whiteico" src="right.gif" /> right.gif</a>
     <br /><a href="right.png"><img class="blackico" src="right.png" 
       /><img class="whiteico" src="right.png" /> right.png</a></td>
    </tr>
    <tr><td colspan="4">These can be used to scroll up, down, left and right in a
    listing or may be used to denote items in an outline.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="dir.gif"><img class="blackico" src="dir.gif" 
       /><img class="whiteico" src="dir.gif" /> dir.gif</a>
     <br /><a href="dir.png"><img class="blackico" src="dir.png" 
       /><img class="whiteico" src="dir.png" /> dir.png</a></td>
    </tr>
    <tr><td colspan="4">Identical to folder.gif (.png) below.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="diskimg.gif"><img class="blackico" src="diskimg.gif" 
       /><img class="whiteico" src="diskimg.gif" /> diskimg.gif</a>
     <br /><a href="diskimg.png"><img class="blackico" src="diskimg.png" 
       /><img class="whiteico" src="diskimg.png" /> diskimg.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent floppy disk storage.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="small/doc.gif"><img class="blackico" src="small/doc.gif" 
       /><img class="whiteico" src="small/doc.gif" /> small/doc.gif</a>
     <br /><a href="small/doc.png"><img class="blackico" src="small/doc.png" 
       /><img class="whiteico" src="small/doc.png" /> small/doc.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent document files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="dvi.gif"><img class="blackico" src="dvi.gif" 
       /><img class="whiteico" src="dvi.gif" /> dvi.gif</a>
     <br /><a href="dvi.png"><img class="blackico" src="dvi.png" 
       /><img class="whiteico" src="dvi.png" /> dvi.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent DVI files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="f.gif"><img class="blackico" src="f.gif" 
       /><img class="whiteico" src="f.gif" /> f.gif</a>
     <br /><a href="f.png"><img class="blackico" src="f.png" 
       /><img class="whiteico" src="f.png" /> f.png</a></td>
    </tr>
    <tr><td colspan="4">This might represent FORTRAN or Forth source code.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="folder.gif"><img class="blackico" src="folder.gif" 
       /><img class="whiteico" src="folder.gif" /> folder.gif</a>
     <br /><a href="folder.png"><img class="blackico" src="folder.png" 
       /><img class="whiteico" src="folder.png" /> folder.png</a></td>
    <td width="25%">
     <a href="folder.open.gif"><img class="blackico" src="folder.open.gif" 
       /><img class="whiteico" src="folder.open.gif" /> folder.open.gif</a>
     <br /><a href="folder.open.png"><img class="blackico" src="folder.open.png" 
       /><img class="whiteico" src="folder.open.png" /> folder.open.png</a></td>
    <td width="25%">
     <a href="folder.sec.gif"><img class="blackico" src="folder.sec.gif" 
       /><img class="whiteico" src="folder.sec.gif" /> folder.sec.gif</a>
     <br /><a href="folder.sec.png"><img class="blackico" src="folder.sec.png" 
       /><img class="whiteico" src="folder.sec.png" /> folder.sec.png</a></td>
    </tr>
    <tr>
    <td width="25%">
     <a href="small/folder.gif"><img class="blackico" src="small/folder.gif" 
       /><img class="whiteico" src="small/folder.gif" /> small/folder.gif</a>
     <br /><a href="small/folder.png"><img class="blackico" src="small/folder.png" 
       /><img class="whiteico" src="small/folder.png" /> small/folder.png</a></td>
    <td width="25%">
     <a href="small/folder2.gif"><img class="blackico" src="small/folder2.gif" 
       /><img class="whiteico" src="small/folder2.gif" /> small/folder2.gif</a>
     <br /><a href="small/folder2.png"><img class="blackico" src="small/folder2.png" 
       /><img class="whiteico" src="small/folder2.png" /> small/folder2.png</a></td>
    </tr>
    <tr><td colspan="4">The folder can represent directories. There is also a
    version that can represent secure directories or directories that cannot
    be viewed.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="generic.gif"><img class="blackico" src="generic.gif" 
       /><img class="whiteico" src="generic.gif" /> generic.gif</a>
     <br /><a href="generic.png"><img class="blackico" src="generic.png" 
       /><img class="whiteico" src="generic.png" /> generic.png</a></td>
    <td width="25%">
     <a href="generic.sec.gif"><img class="blackico" src="generic.sec.gif" 
       /><img class="whiteico" src="generic.sec.gif" /> generic.sec.gif</a>
     <br /><a href="generic.sec.png"><img class="blackico" src="generic.sec.png" 
       /><img class="whiteico" src="generic.sec.png" /> generic.sec.png</a></td>
    <td width="25%">
     <a href="generic.red.gif"><img class="blackico" src="generic.red.gif" 
       /><img class="whiteico" src="generic.red.gif" /> generic.red.gif</a>
     <br /><a href="generic.red.png"><img class="blackico" src="generic.red.png" 
       /><img class="whiteico" src="generic.red.png" /> generic.red.png</a></td>
    </tr>
    <tr>
    <td width="25%">
     <a href="small/generic.gif"><img class="blackico" src="small/generic.gif" 
       /><img class="whiteico" src="small/generic.gif" /> small/generic.gif</a>
     <br /><a href="small/generic.png"><img class="blackico" src="small/generic.png" 
       /><img class="whiteico" src="small/generic.png" /> small/generic.png</a></td>
    <td width="25%">
     <a href="small/generic2.gif"><img class="blackico" src="small/generic2.gif" 
       /><img class="whiteico" src="small/generic2.gif" /> small/generic2.gif</a>
     <br /><a href="small/generic2.png"><img class="blackico" src="small/generic2.png" 
       /><img class="whiteico" src="small/generic2.png" /> small/generic2.png</a></td>
    <td width="25%">
     <a href="small/generic3.gif"><img class="blackico" src="small/generic3.gif" 
       /><img class="whiteico" src="small/generic3.gif" /> small/generic3.gif</a>
     <br /><a href="small/generic3.png"><img class="blackico" src="small/generic3.png" 
       /><img class="whiteico" src="small/generic3.png" /> small/generic3.png</a></td>
    </tr>
    <tr><td colspan="4">These can represent generic files, secure files, and
    important files, respectively.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="hand.right.gif"><img class="blackico" src="hand.right.gif" 
       /><img class="whiteico" src="hand.right.gif" /> hand.right.gif</a>
     <br /><a href="hand.right.png"><img class="blackico" src="hand.right.png" 
       /><img class="whiteico" src="hand.right.png" /> hand.right.png</a></td>
    <td width="25%">
     <a href="hand.up.gif"><img class="blackico" src="hand.up.gif" 
       /><img class="whiteico" src="hand.up.gif" /> hand.up.gif</a>
     <br /><a href="hand.up.png"><img class="blackico" src="hand.up.png" 
       /><img class="whiteico" src="hand.up.png" /> hand.up.png</a></td>
    </tr>
    <tr><td colspan="4">These can point out important items (pun intended).</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="image1.gif"><img class="blackico" src="image1.gif" 
       /><img class="whiteico" src="image1.gif" /> image1.gif</a>
     <br /><a href="image1.png"><img class="blackico" src="image1.png" 
       /><img class="whiteico" src="image1.png" /> image1.png</a></td>
    <td width="25%">
     <a href="image2.gif"><img class="blackico" src="image2.gif" 
       /><img class="whiteico" src="image2.gif" /> image2.gif</a>
     <br /><a href="image2.png"><img class="blackico" src="image2.png" 
       /><img class="whiteico" src="image2.png" /> image2.png</a></td>
    <td width="25%">
     <a href="image3.gif"><img class="blackico" src="image3.gif" 
       /><img class="whiteico" src="image3.gif" /> image3.gif</a>
     <br /><a href="image3.png"><img class="blackico" src="image3.png" 
       /><img class="whiteico" src="image3.png" /> image3.png</a></td>
    </tr>
    <tr>
    <td width="25%">
     <a href="small/image.gif"><img class="blackico" src="small/image.gif" 
       /><img class="whiteico" src="small/image.gif" /> small/image.gif</a>
     <br /><a href="small/image.png"><img class="blackico" src="small/image.png" 
       /><img class="whiteico" src="small/image.png" /> small/image.png</a></td>
    <td width="25%">
     <a href="small/image2.gif"><img class="blackico" src="small/image2.gif" 
       /><img class="whiteico" src="small/image2.gif" /> small/image2.gif</a>
     <br /><a href="small/image2.png"><img class="blackico" src="small/image2.png" 
       /><img class="whiteico" src="small/image2.png" /> small/image2.png</a></td>
    </tr>
    <tr><td colspan="4">These can represent image formats of various types.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="index.gif"><img class="blackico" src="index.gif" 
       /><img class="whiteico" src="index.gif" /> index.gif</a>
     <br /><a href="index.png"><img class="blackico" src="index.png" 
       /><img class="whiteico" src="index.png" /> index.png</a></td>
    <td width="25%">
     <a href="small/index.gif"><img class="blackico" src="small/index.gif" 
       /><img class="whiteico" src="small/index.gif" /> small/index.gif</a>
     <br /><a href="small/index.png"><img class="blackico" src="small/index.png" 
       /><img class="whiteico" src="small/index.png" /> small/index.png</a></td>
    </tr>
    <tr><td colspan="4">This might represent a WAIS index or search facility.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="small/key.gif"><img class="blackico" src="small/key.gif" 
       /><img class="whiteico" src="small/key.gif" /> small/key.gif</a>
     <br /><a href="small/key.png"><img class="blackico" src="small/key.png" 
       /><img class="whiteico" src="small/key.png" /> small/key.png</a></td>
    </tr>
    <tr><td colspan="4">This might represent a locked file.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="layout.gif"><img class="blackico" src="layout.gif" 
       /><img class="whiteico" src="layout.gif" /> layout.gif</a>
     <br /><a href="layout.png"><img class="blackico" src="layout.png" 
       /><img class="whiteico" src="layout.png" /> layout.png</a></td>
    </tr>
    <tr><td colspan="4">This might represent files and formats that contain
    graphics as well as text layout, such as HTML and PDF files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="link.gif"><img class="blackico" src="link.gif" 
       /><img class="whiteico" src="link.gif" /> link.gif</a>
     <br /><a href="link.png"><img class="blackico" src="link.png" 
       /><img class="whiteico" src="link.png" /> link.png</a></td>
    </tr>
    <tr><td colspan="4">This might represent files that are symbolic links.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="movie.gif"><img class="blackico" src="movie.gif" 
       /><img class="whiteico" src="movie.gif" /> movie.gif</a>
     <br /><a href="movie.png"><img class="blackico" src="movie.png" 
       /><img class="whiteico" src="movie.png" /> movie.png</a></td>
    <td width="25%">
     <a href="small/movie.gif"><img class="blackico" src="small/movie.gif" 
       /><img class="whiteico" src="small/movie.gif" /> small/movie.gif</a>
     <br /><a href="small/movie.png"><img class="blackico" src="small/movie.png" 
       /><img class="whiteico" src="small/movie.png" /> small/movie.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent various movie formats.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="p.gif"><img class="blackico" src="p.gif" 
       /><img class="whiteico" src="p.gif" /> p.gif</a>
     <br /><a href="p.png"><img class="blackico" src="p.png" 
       /><img class="whiteico" src="p.png" /> p.png</a></td>
    </tr>
    <tr><td colspan="4">This may stand for Perl or Python source code.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="pie0.gif"><img class="blackico" src="pie0.gif" 
       /><img class="whiteico" src="pie0.gif" /> pie0.gif</a>
     <br /><a href="pie1.png"><img class="blackico" src="pie0.png" 
       /><img class="whiteico" src="pie0.png" /> pie0.png</a></td>
    <td width="25%">
     <a href="pie1.gif"><img class="blackico" src="pie1.gif" 
       /><img class="whiteico" src="pie1.gif" /> pie1.gif</a>
     <br /><a href="pie1.png"><img class="blackico" src="pie1.png" 
       /><img class="whiteico" src="pie1.png" /> pie1.png</a></td>
    <td width="25%">
     <a href="pie2.gif"><img class="blackico" src="pie2.gif" 
       /><img class="whiteico" src="pie2.gif" /> pie2.gif</a>
     <br /><a href="pie2.png"><img class="blackico" src="pie2.png" 
       /><img class="whiteico" src="pie2.png" /> pie2.png</a></td>
    <td width="25%">
     <a href="pie3.gif"><img class="blackico" src="pie3.gif" 
       /><img class="whiteico" src="pie3.gif" /> pie3.gif</a>
     <br /><a href="pie3.png"><img class="blackico" src="pie3.png" 
       /><img class="whiteico" src="pie3.png" /> pie3.png</a></td>
    </tr><tr>
    <td width="25%">
     <a href="pie4.gif"><img class="blackico" src="pie4.gif" 
       /><img class="whiteico" src="pie4.gif" /> pie4.gif</a>
     <br /><a href="pie4.png"><img class="blackico" src="pie4.png" 
       /><img class="whiteico" src="pie4.png" /> pie4.png</a></td>
    <td width="25%">
     <a href="pie5.gif"><img class="blackico" src="pie5.gif" 
       /><img class="whiteico" src="pie5.gif" /> pie5.gif</a>
     <br /><a href="pie5.png"><img class="blackico" src="pie5.png" 
       /><img class="whiteico" src="pie5.png" /> pie5.png</a></td>
    <td width="25%">
     <a href="pie6.gif"><img class="blackico" src="pie6.gif" 
       /><img class="whiteico" src="pie6.gif" /> pie6.gif</a>
     <br /><a href="pie6.png"><img class="blackico" src="pie6.png" 
       /><img class="whiteico" src="pie6.png" /> pie6.png</a></td>
    <td width="25%">
     <a href="pie7.gif"><img class="blackico" src="pie7.gif" 
       /><img class="whiteico" src="pie7.gif" /> pie7.gif</a>
     <br /><a href="pie7.png"><img class="blackico" src="pie7.png" 
       /><img class="whiteico" src="pie7.png" /> pie7.png</a></td>
    </tr><tr>
    <td width="25%">
     <a href="pie8.gif"><img class="blackico" src="pie8.gif" 
       /><img class="whiteico" src="pie8.gif" /> pie8.gif</a>
     <br /><a href="pie8.png"><img class="blackico" src="pie8.png" 
       /><img class="whiteico" src="pie8.png" /> pie8.png</a></td>
    </tr>
    <tr><td colspan="4">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.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="patch.gif"><img class="blackico" src="patch.gif" 
       /><img class="whiteico" src="patch.gif" /> patch.gif</a>
     <br /><a href="patch.png"><img class="blackico" src="patch.png" 
       /><img class="whiteico" src="patch.png" /> patch.png</a></td>
    <td width="25%">
     <a href="small/patch.gif"><img class="blackico" src="small/patch.gif" 
       /><img class="whiteico" src="small/patch.gif" /> small/patch.gif</a>
     <br /><a href="small/patch.png"><img class="blackico" src="small/patch.png" 
       /><img class="whiteico" src="small/patch.png" /> small/patch.png</a></td>
    </tr>
    <tr><td colspan="4">This may stand for patches and diff files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="portal.gif"><img class="blackico" src="portal.gif" 
       /><img class="whiteico" src="portal.gif" /> portal.gif</a>
     <br /><a href="portal.png"><img class="blackico" src="portal.png" 
       /><img class="whiteico" src="portal.png" /> portal.png</a></td>
    </tr>
    <tr><td colspan="4">This might be a link to an online service or a 3D
    world.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="pdf.gif"><img class="blackico" src="pdf.gif" 
       /><img class="whiteico" src="pdf.gif" /> pdf.gif</a>
     <br /><a href="pdf.png"><img class="blackico" src="pdf.png" 
       /><img class="whiteico" src="pdf.png" /> pdf.png</a></td>
    <td width="25%">
     <a href="ps.gif"><img class="blackico" src="ps.gif" 
       /><img class="whiteico" src="ps.gif" /> ps.gif</a>
     <br /><a href="ps.png"><img class="blackico" src="ps.png" 
       /><img class="whiteico" src="ps.png" /> ps.png</a></td>
    <td width="25%">
     <a href="quill.gif"><img class="blackico" src="quill.gif" 
       /><img class="whiteico" src="quill.gif" /> quill.gif</a>
     <br /><a href="quill.png"><img class="blackico" src="quill.png" 
       /><img class="whiteico" src="quill.png" /> quill.png</a></td>
    <td width="25%">
     <a href="small/ps.gif"><img class="blackico" src="small/ps.gif" 
       /><img class="whiteico" src="small/ps.gif" /> small/ps.gif</a>
     <br /><a href="small/ps.png"><img class="blackico" src="small/ps.png" 
       /><img class="whiteico" src="small/ps.png" /> small/ps.png</a></td>
    </tr>
    <tr><td colspan="4">These may represent PDF and PostScript files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="screw1.gif"><img class="blackico" src="screw1.gif" 
       /><img class="whiteico" src="screw1.gif" /> screw1.gif</a>
     <br /><a href="screw1.png"><img class="blackico" src="screw1.png" 
       /><img class="whiteico" src="screw1.png" /> screw1.png</a></td>
    <td width="25%">
     <a href="screw2.gif"><img class="blackico" src="screw2.gif" 
       /><img class="whiteico" src="screw2.gif" /> screw2.gif</a>
     <br /><a href="screw2.png"><img class="blackico" src="screw2.png" 
       /><img class="whiteico" src="screw2.png" /> screw2.png</a></td>
    </tr>
    <tr><td colspan="4">These may represent CAD or engineering data and
    formats.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="script.gif"><img class="blackico" src="script.gif" 
       /><img class="whiteico" src="script.gif" /> script.gif</a>
     <br /><a href="script.png"><img class="blackico" src="script.png" 
       /><img class="whiteico" src="script.png" /> script.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent any of various interpreted languages,
    such as Perl, python, TCL, and shell scripts, as well as server configuration
    files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="sound1.gif"><img class="blackico" src="sound1.gif" 
       /><img class="whiteico" src="sound1.gif" /> sound1.gif</a>
     <br /><a href="sound1.png"><img class="blackico" src="sound1.png" 
       /><img class="whiteico" src="sound1.png" /> sound1.png</a></td>
    <td width="25%">
     <a href="sound2.gif"><img class="blackico" src="sound2.gif" 
       /><img class="whiteico" src="sound2.gif" /> sound2.gif</a>
     <br /><a href="sound2.png"><img class="blackico" src="sound2.png" 
       /><img class="whiteico" src="sound2.png" /> sound2.png</a></td>
    <td width="25%">
     <a href="small/sound.gif"><img class="blackico" src="small/sound.gif" 
       /><img class="whiteico" src="small/sound.gif" /> small/sound.gif</a>
     <br /><a href="small/sound.png"><img class="blackico" src="small/sound.png" 
       /><img class="whiteico" src="small/sound.png" /> small/sound.png</a></td>
    <td width="25%">
     <a href="small/sound2.gif"><img class="blackico" src="small/sound2.gif" 
       /><img class="whiteico" src="small/sound2.gif" /> small/sound2.gif</a>
     <br /><a href="small/sound2.png"><img class="blackico" src="small/sound2.png" 
       /><img class="whiteico" src="small/sound2.png" /> small/sound2.png</a></td>
    </tr>
    <tr><td colspan="4">These can represent sound files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="sphere1.gif"><img class="blackico" src="sphere1.gif" 
       /><img class="whiteico" src="sphere1.gif" /> sphere1.gif</a>
     <br /><a href="sphere1.png"><img class="blackico" src="sphere1.png" 
       /><img class="whiteico" src="sphere1.png" /> sphere1.png</a></td>
    <td width="25%">
     <a href="sphere2.gif"><img class="blackico" src="sphere2.gif" 
       /><img class="whiteico" src="sphere2.gif" /> sphere2.gif</a>
     <br /><a href="sphere2.png"><img class="blackico" src="sphere2.png" 
       /><img class="whiteico" src="sphere2.png" /> sphere2.png</a></td>
    </tr>
    <tr><td colspan="4">These can represent 3D worlds or rendering applications and
    formats.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="tar.gif"><img class="blackico" src="tar.gif" 
       /><img class="whiteico" src="tar.gif" /> tar.gif</a>
     <br /><a href="tar.png"><img class="blackico" src="tar.png" 
       /><img class="whiteico" src="tar.png" /> tar.png</a></td>
    <td width="25%">
     <a href="small/tar.gif"><img class="blackico" src="small/tar.gif" 
       /><img class="whiteico" src="small/tar.gif" /> small/tar.gif</a>
     <br /><a href="small/tar.png"><img class="blackico" src="small/tar.png" 
       /><img class="whiteico" src="small/tar.png" /> small/tar.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent TAR archive files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="tex.gif"><img class="blackico" src="tex.gif" 
       /><img class="whiteico" src="tex.gif" /> tex.gif</a>
     <br /><a href="tex.png"><img class="blackico" src="tex.png" 
       /><img class="whiteico" src="tex.png" /> tex.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent TeX files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="text.gif"><img class="blackico" src="text.gif" 
       /><img class="whiteico" src="text.gif" /> text.gif</a>
     <br /><a href="text.png"><img class="blackico" src="text.png" 
       /><img class="whiteico" src="text.png" /> text.png</a></td>
    <td width="25%">
     <a href="small/text.gif"><img class="blackico" src="small/text.gif" 
       /><img class="whiteico" src="small/text.gif" /> small/text.gif</a>
     <br /><a href="small/text.png"><img class="blackico" src="small/text.png" 
       /><img class="whiteico" src="small/text.png" /> small/text.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent generic (plain) text files.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="transfer.gif"><img class="blackico" src="transfer.gif" 
       /><img class="whiteico" src="transfer.gif" /> transfer.gif</a>
     <br /><a href="transfer.png"><img class="blackico" src="transfer.png" 
       /><img class="whiteico" src="transfer.png" /> transfer.png</a></td>
    <td width="25%">
     <a href="small/transfer.gif"><img class="blackico" src="small/transfer.gif" 
       /><img class="whiteico" src="small/transfer.gif" /> small/transfer.gif</a>
     <br /><a href="small/transfer.png"><img class="blackico" src="small/transfer.png" 
       /><img class="whiteico" src="small/transfer.png" /> small/transfer.png</a></td>
    </tr>
    <tr><td colspan="4">This can represent FTP transfers or uploads/downloads.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="unknown.gif"><img class="blackico" src="unknown.gif" 
       /><img class="whiteico" src="unknown.gif" /> unknown.gif</a>
     <br /><a href="unknown.png"><img class="blackico" src="unknown.png" 
       /><img class="whiteico" src="unknown.png" /> unknown.png</a></td>
    <td width="25%">
     <a href="small/unknown.gif"><img class="blackico" src="small/unknown.gif" 
       /><img class="whiteico" src="small/unknown.gif" /> small/unknown.gif</a>
     <br /><a href="small/unknown.png"><img class="blackico" src="small/unknown.png" 
       /><img class="whiteico" src="small/unknown.png" /> small/unknown.png</a></td>
    </tr>
    <tr><td colspan="4">This may represent a file of an unknown type.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="uu.gif"><img class="blackico" src="uu.gif" 
       /><img class="whiteico" src="uu.gif" /> uu.gif</a>
     <br /><a href="uu.png"><img class="blackico" src="uu.png" 
       /><img class="whiteico" src="uu.png" /> uu.png</a></td>
    <td width="25%">
     <a href="uuencoded.gif"><img class="blackico" src="uuencoded.gif" 
       /><img class="whiteico" src="uuencoded.gif" /> uuencoded.gif</a>
     <br /><a href="uuencoded.png"><img class="blackico" src="uuencoded.png" 
       /><img class="whiteico" src="uuencoded.png" /> uuencoded.png</a></td>
    <td width="25%">
     <a href="small/uu.gif"><img class="blackico" src="small/uu.gif" 
       /><img class="whiteico" src="small/uu.gif" /> small/uu.gif</a>
     <br /><a href="small/uu.png"><img class="blackico" src="small/uu.png" 
       /><img class="whiteico" src="small/uu.png" /> small/uu.png</a></td>
    </tr>
    <tr><td colspan="4">This can stand for uuencoded data.</td>
    </tr>
    
    <tr>
    <td width="25%">
     <a href="world1.gif"><img class="blackico" src="world1.gif" 
       /><img class="whiteico" src="world1.gif" /> world1.gif</a>
     <br /><a href="world1.png"><img class="blackico" src="world1.png" 
       /><img class="whiteico" src="world1.png" /> world1.png</a></td>
    <td width="25%">
     <a href="world2.gif"><img class="blackico" src="world2.gif" 
       /><img class="whiteico" src="world2.gif" /> world2.gif</a>
     <br /><a href="world2.png"><img class="blackico" src="world2.png" 
       /><img class="whiteico" src="world2.png" /> world2.png</a></td>
    </tr>
    <tr><td colspan="4">These can represent 3D worlds or other 3D formats.</td>
    </tr>
    </table>
    </body>
    </html>
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/apache_pb.gif���������������������������������������������������������������0000664�0001751�0001751�00000010557�12141202160�017253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��ҔTmG?ktDӲ444hHHGNGZ6RI{Pp[on{{{���eeewNRR
    ~uWͲYV%lM'L*G;ͨpQfՕe=hS]]]*71HJ''(](>;ӻȓ𴳳lZ7w[21>Ej+`'Dפ
    V5jAV1Kzn4
    Hfm7ۋ{NF(.d!_(S K<F?WY7XVVV{�x1kgyZ]`ERD`Y<"Jǿg
    $Ax(aopq
    8X:*OfY	ɹƿ0HII?9?ƿHѕSf*rC<�~rf4x1]03K Nr1jiSj7:U3:]3X"\3._@@>X_ckyu3w~O>ZU<d1lbov		W,.�ɄТk0P[`\WYiu|qBb¦OOOрr>T?b/X\Ǘ�)ǰ GϜh.LկҴZhŻ~P!���,�������	H*\ȰÂ(I ŋ%;)0QH6s˗0@f81s.@cAȸB"1Cu4:E8bfʕf	2kW>	zb (XЧQQ`x$*)И]s&hx.HY4V@;4.(t{	<z+مKm_@1\2A(VbWE"_Gc2i	$\^>p]jF6^rq
    PX0&E	M͐@M4. 4Ib]p@E3д1tL3P^Lqa3J2?68VT!
    3@WGB"9`XaB+&RBB&B0\s$M\H^p1^?H 
    (rUMsϏP~`@|ӢA@#MF6A5#4iE烊}( @>sH|Kf/T!H�	-=!Kh3i4MU?^D1r=P]ԱÎX 0yJybddxn|@}NW3@";M]@30@�&`*J#0h�cC
    y4Ā` 1Z.^@D1ഡV<[lyy4t%A1G:̑6W<`(<PJz#V]B'4	NUm?bYHTz�4 G)|m?Pͤ1y.Eã8[_Px"'^r4ɠ՛,A35ی �3*l"h``ThfA"`�&+&R!2A3*"B]?a9O �UEhWVu{h HK3"2o (҅9Wʾ �|+H>@$f6 2dF0
    &0�ȥT4.H djB'C;Ͱإ%.,H8H&D%#4ChlERFM1>q&Mѡ,҅`6tpaNAF<�th	x	4	N8hFQ=1!yAf]@ b9ua�A8S	rzޓyt 3GA:xR A�Oǐ@a{@P)Y=uqBA\c2@C.yя?Q0X
    l�tO 1	y
    B*дF( 
    pCjmt]8&ծ.dAPqc>%
    6" ,jrCԧ[ 0#[&xC+Rg[Ѓ40
    ( -�,ڮ4V�Ah?$ 
    :)&ʸ5>(�*�㨑h*i*Mn~qLò[!7u%hB1!=�
    L(*41ȁfAfu@6*,c@ԙ @
    `2
    k7"QZ-2$IPP x1߈�=0Q\Fk$|db8eP2a@X Pl0"@c� (0Y@.w+Bp2gp/4D#p!UЀg[daZPAAB
    _ '-i$DI[LB)@ߘ�7	D!�O ^Y-rZn*pTM4I5g8١`@j[&�2Ngf4Fȷ}/A!ZV|@(nG)P+I^`&CjZ@D
    $\t AI;lflߡn>nnp9Ql*d[%nv;=|`R4t D
    QU-CF 0�lB;x_M*,§ |	TBo`b;\|5'F0l$DXq8{D
    �؂[H2$X z" "
    �"ЀT85`$0	O N/Πcak6lTk@Jpjlφ�35:Gm~s1E�<m1gHFn 
    *,@oʗ2Pd.@ppi&�
    T&i`�&l@%rL $jru@32~g q3
    b �J�
    eXP
    e5Xz
    1?gFg��E7/qֈ18XhpWp>9�G5@VPPr%`&6&�w wQ>SkrcPV͐
    qD��P�eez&zA6mw~(dvmPz6{�Eaf	hooXbPp
    `J��Ko^@Ic%_@04e�}	VkTk@HD�O@P �@
    6sAs:YsBy~Pp8%(GzzPghXh�!ȏ:!	`�oL MbMn
    P
     �Dx@`%ndr V@e&WT  �	.Il_@|`A9AGn7�'{S)InP×h\yo_
    )f!\e
    
    `��b4V
    I4jV&Y�NJPyk
    75lis6@Yz�GXt ||f!&xuu]uuB9H	']
     
    PN40 �
    y0
    N0M5p	$�lF
    t@TZVjsП6uFG
    `6z@	f!S<I0[pnnėWoo}:2M0=C)t@bo
    x
    .pK:Ő7<l@ȥ	#MitH궬V)ou_9US3pEP>cɨC]`.@C06	`�@ =3)cIR8YsYvj0nem^zOI*0hʬiJ	w
    oz|}J8atڭ9>`
    &ۭEa)DGY
    04kL4;*@
    >K
    Pg0CkoFC�`Q7uUtfZ`Y
    Z0d[fk�;�������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/svg.png���������������������������������������������������������������������0000664�0001751�0001751�00000001762�11141176336�016203� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��.PLTE33***+++,,,---333���;���tRNS�@f���bKGD�H���	pHYs�������PIDATc`EPs֮\x>L(m֯YtYz[7]b'vCDYׯ]t9&VEY׮XhzX$|yMjjd�@MMey@�jRSQ>IE4/3):,"8ebG[c(KJBdhDR%E06$"PS^",ll*-a
    auqgń0[B҄#BZMt!|An6\Lx~f^/7{[SN&5`|30*)@}ݜ,MZU!(�tlh�d	����IENDB`��������������httpd-2.4.64/docs/icons/ball.red.png����������������������������������������������������������������0000664�0001751�0001751�00000000441�10671421551�017057� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33f�����ֹu���tRNS�@*���bKGD�H���KIDATc0R0P0Ȩ
    a
    2
    C*.P+g:B!.0s]C1m#׽��R,ʘ*���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/world2.png������������������������������������������������������������������0000664�0001751�0001751�00000000553�10671421551�016611� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙�3�f3������tRNS�0J���bKGD�H���IDAT[]
     PZȅw&m�;I6Cs%'Cxyy@4PwFnpq:zTjO95xL/!\1WkZCRbnĨ_"ZV~oa,4l���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/README����������������������������������������������������������������������0000664�0001751�0001751�00000011764�10664776532�015576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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).
         Andy Polyakov tuned the icon colors and added a few new images.
    
         If you'd like to contribute additions to this set, contact the httpd
         documentation project <http://httpd.apache.org/docs-project/>.
    
         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.gray.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.
    
         dir.gif
              Identical to folder.gif below.
    
         diskimg.gif
              This can represent floppy disk storage.
    
         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.
    
         pdf.gif, ps.gif, quill.gif
              These may represent PDF and 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.
    
         tar.gif
              This can represent TAR archive files.
    
         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.
    
         uu.gif, uuencoded.gif
              This can stand for uuencoded data.
    
         world1.gif, world2.gif
              These can represent 3D worlds or other 3D formats.
    ������������httpd-2.4.64/docs/icons/quill.png�������������������������������������������������������������������0000664�0001751�0001751�00000000511�10664777241�016534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEfff3333������tRNS�0J���bKGD�H���oIDATE; ᩠;&^�`h}$*&q/!o!"xgOJs
    rEiAt)-7kʘb3m+(\7|OT^HL+$e9���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/binhex.gif������������������������������������������������������������������0000664�0001751�0001751�00000000366�10147723030�016633� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����fff333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������iH0@$YjU^+`Qߛ<[@`((&hLb.]|@s;"".Ͷ<ҝh,DC6;M	�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/dvi.gif���������������������������������������������������������������������0000664�0001751�0001751�00000000356�10147723030�016137� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������a80@#IjU(R'10:"(;Hhã4\6eOPʂW}es4<rk$ȞW~_ÈW	�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/apache_pb2.gif��������������������������������������������������������������0000664�0001751�0001751�00000010212�12141202160�017321� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��h.mUontNLLLMt@uTUU_U̫R'Y|||4B6Rjjj[ʅinJZ~˔WZZ"orsqR:dqP2���.8l(7#Fŕ\2nXƩV(D985=6'?gV4ssszEwE###1ؘUס
    W&Rqi$5$WsƺWO7D	Ju%_n�շXCGĮ>ľڹ+.HDgC>!Jf:ŹwG}ZLV-bQk&Lؙp]AET.ei^AK>RM^`aS0YG[\LFD37^K2š8W:�~V@H֡\Nק°1E}GUe?<Ol޸4Q�0IOVڼ.Odrz4Zanu.�LBBA49q^C<U?#
    W,ڪGu{meԴCt>fJl(a]@BNVYV1h-N-LqNMaeE,,,{EO!���,�������	HuXe‡#J!2Ǐ C)
    {m]!O<>iMbi	kȳѣHv&(TٲqICc]%%(ADǪ]a{8`C7>;(TCĚҞ�[_*Iz4b @ą
    }
    ֛Ϡ4fxTj!֤-x	vp띒R7[:eѠR]OAB4 3
    ``iDC%!h=5PT'
    =?|wr$(6W
    CUi=L�'PxDF!
    pAbO?D>SOTLSNnAG~TB4!
    r-]t^d⠄jMA
    W(P01UdO>L2Yt[a, I$
    h0BMI�eBЀ?.0eFfS-
     1!TydtJ@s=4(
    pY]P%
    *n@AeU=0ULr/qhj@K3
    UkKVLbF.4�j
    t@LLd<Pź
    4?/"*p!=HcOv=A!B@LPD(�fWS	<'�p�gZ\$wB9$ܕ&22zxم4)xk@	:PL6av`%-ΈU d[SMTET٣	��0!H�El-JWl3`ABRŘVLwY̯493^<P+?)0]\!Tb%}Q5We=EgaTE6.p=LI'�:Z%l:iT8:}]O�-qV6i''&FTqi�AQr$J?K:Jǐ
    A$��	8�Dw/
    p@X&(#`U� rp`0Q.z0tf=Q)=PTC#|"9[E pp/`R,A-c-H]*+A"61`؅?3L2[(*B@x\1gx_K<D௯BX�(Ƞ*	HB;&:�YB4G*>8P:$!
    KQ3l"
    RR˃DKhSN�Tj1vlB>xO&08N #fp8NB(1`��I`LI2$`D%gB�-pM$$=[CGjA:B7V(@>P>
    UPADR�.�8!Į́k�lQ}eaU+mq�!\CH!W4⶷e&$)L1&b"p\7$	�pXؽ	qox'RyA׽xXPG-;
    .hslA	F]:9/xs�( Gr``DD0~q
    D;8&:4X@2@
    PGHL
    w /L*Wi\=֓
    W08@-'-86yh0��
    eCYʩ!Q
    1fa$ �I"hʦpc${@җ1BN@"RuR7Dd&Sgme,w$وMe|2h5`d';ѦsF0V>'`�Z �a3H<k8`&(A/<҉eD,:>B[ :͈ԁA
    :DȪj&rp8Gx#XRЎZ,\*frN<H`x@3*g 4 3‡@bp H@B4&}F`(D'B!+qعnq>{U#rRxo"ځUP@-Z�
    z5K|a�X€9=)3:2`5_C-8 ppnHpc=aAڣ񏱿{i{ގ' 82	v2#O]*`
    ϸB*@Oa	w0C�aA:`lJT3:`pHw?zQs^b?'j` q%b0	(bcMЃ>؃ 5�c5``@pcQF~RGkV8
    !PAf%PtP03	@3�3PK䆦b04wN'`*TЇ�0KK/bЈgQ{'
    !�-VGiHPiM$Q~M~x~^WhS@ڐ
    :
     �jIP$Z	C{D6Հ\%Ca_ 0
    _�Ka`�((Pn
    n(&o!}b }Eiv�icHH?v]N@r!wdUqj4DDq`@(mp@P*pC yCp5N0
    9 	�&?a&b
    d'iP	˰v!}+pX@}}b(d$0x1EVxdTV9s..
    o>
    )
    z@4PyA��	
    	d	@OxH		P|QٚfvUo!\bYayhP0!PP ]qqPVeP
    )l@"P;�.@I
    FP�
    @20tp0n2@0np
    )
    p
    	qxP&(f'!}^GccL8pCsٜHkYX(UUG]zWЗD#F
    PoP
    @
     qDϠ
    YD8iv(Fi*w'!w9iQc *d77!G'je)jHU]AD]PY|!g0QyPJjZM0Hje	p:3$@7pN]R|W
    a�
    @ʺڬ
    
    �;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/apache_pb.png���������������������������������������������������������������0000664�0001751�0001751�00000022733�12033030440�017271� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��������2`C���sBIT|d���	pHYs��+��+#W���tEXtSoftware�www.inkscape.org<�� �IDATxw|U?II!@(
    qU*E\U].s{Ϻ*͵(*.WdEJMf&۷dy^"sS9;<9B)υ'x"t^�H+77wj7|GgÆ
    7/Z.s|Gc
    Gߋ\N>=lϞ{L租~l맢Jpr˅$e?n#BLgS`YopW)h0cƌ333MMM-[\tud%3o|W��!l]G0�BBn'uK/z8uvjuKᄍtʔ%D3h~RZ?˗AcqE~;y&M/7x#.8qbŪU.<[ZZZ1cƌC?|>�̛7Ҋo�8z֬Y3~~o鍊nr=WN:uϸqz^~�pr;&Lpdܹ/=sez衉;f̘ybbL@&WZǏhɒ%�`…/V\wu_ϻp_V\tE/Bka#klll}'{֯_eM�Fg,1#Xaz$5z6n
    /&nij&>J
    >ٹE"..ίRB�L$�[޸q_xGrrr+СCxy1999SlkllVrdEEEkhh999{WL6m:Cmnrݹƍ:o޼XccbY]YY"d+Vx45NR^^~O86?kٗ_~СCcd2MMg6ɱy rwvvjժ`eeo??innUQQ1n„	w_#޻b
    M$�O$<C;1Q9QA2BHdX.a%ߥRRR1;ȓY.թgLlީza
    {[^{볊n"` kmO8feeǘڅ<cΜ9Zꫯ~y9rdƍ&�O>p8
    gϞ]%Z3όioo5L|ii;v츧:g=>˗O(((h)//k׮Oԫ[u뭷~7ק:ukxѣ׽{7oȑ#cd2-[sOln=|ܸxkl6p:tE]~aaaC0d/۸q#v'@JJs|FwAż%�}iA�7BxRZ푴\;zIX~5P'=\24!"OgciQkDwd(5fk""M+HTۢ{4qʋḲ	*Y0X{W�Z._yw6nܘ/fj_�mN8;;y½{niiO8q[fff)7n+V͜93�"}W7@8VQJՕvbg}o?y_|�z?�8NRNL$	ɓ'�F}l~3�عsgCkkdo7o^_Z]]=rv}}}h'NzF_s|>@}I]t۞Z]n~Rl]q]P"֯$vF>~99%�KˢxzAX]$s8FyjSEoX �z̙3kk�,PH�:�%N4i攔n|RJp`0|<Y��&��<o�X,&Fh4j5LjpF՞)�ѨxƱcV3CѨr{�@&Ed`!?aߵɓ'hWb15ʕ+Ѩ0)`N|]wizz׬YOɓ'
    �`^SSӆgRi$o[,((`Ag5E/9fR�PQO'.1u~VQiK`H11�T*C^O3!BB),,<l�hmmIIIo-Zԕrp(y >>>:qĝ-Eь�� 55׺u|b,{RUP ##}G79պz"�D"g20>/~�L�h4�xG)**jE
    �l#Ӆ~0CҲ7peee
    6H{a].פ^zipȳ>q3"6G!Hx5>%B"ha뉢˔aRKN
    f?l"Y*|E͇t٬}ovٕW^USSs	�dgg�`XRJ޽;'==n-۷o?ѣGl6oʔ)ѣݻiW]uf27t^{TeYYٌs
    tvm3oܜ}}}ׯݼysYUUg20wyw}?tP60f};vLLLM4iÙ
    #SnLl0x|ׯǎ;"
    
    
    MvHIB0
    ڨYba~%&r{ٵTgIBQ3C6:$.
    dFKD/SIl]ORMp<}"W�0f̘ۺu3f};vL7eʔ�<3_eΝݲe��BNyK.s0cǎ?㇎Ϛ5k�<#5eee>?l6͙3g;s
    ̴i566vuuse]	v.̙3w>ǾF>B%f>)5mL%qOtvu(,&#qtۥÇI@@�	t)2x]Lϒxx%$maXƇVG\'BEyF;LIhv/b4ii\gٟŬ21bPt~kwYSŎuvvtt.5=~�{;
    A־;N?xqkkh_<#5�p/|O=Ԟ}jժ[[[KbtO<?:;;s333$''>|:FK/}p]˗/?l6iMMN7vط~ߜ<q#eeeŋ-Z9xz3ko[T8fljvnK՛R,[6F~5FˣGlU�Y(4VNU<fdش~#UAfB;C0HTHi[˜%c{	cbhJ-.GH5IR�Behe.cqZN.mWj]Vs+VT;_߽W^yŤ뭻wo<ܶ|˖-u>5K{p\j%|=KpJa+ђkkS;3|fEU:CE/5}@&Cʊ+f8I
    7,Mߩđ^$4ЯADk";DέF ),9*KOfr=RD#K1|lK8Ĉ8dԨg	UXCTRSvJ4;Vm"WϹoCM_4`Ŋ7Yf˲[~7_N{5Ӗآnԙ-DRł?ˀy9Y]idY.^JXk.JYqi#(6ג}ޱRFyt!3l6enϬC̯Gjv/uJ3j=4_b]ToLrMGUrZ܎ /=SIgɤ,Lp9I<m:Uee݂"kRˊr2|b(79ݵ}?E
    /;;{N}k0se١*
    [m]\'[o]nef:5@vYE!EY>b8"C%ԠiW.s;xEX:檤͎FV$�]"12QN*t]<x3##3C6SbaZG9tq,W�tD)0=�
    bkx´=]T%%zSj>$51=\$ՍZt⛇[~QDž�J<
    Co}~Ϣxs@R4]ڷ/dөJD"rRBqD'DY+	*a@.CVjo ;5hFLNH`e,vrhc%^
    YIzM]I`'j(IB?P+ 1МaRSLޮLla)DeRvkbg_Ot,^rcg(.pW^́_$EъB?fL<1ev
    g[:L?u(!@/:Dg$5{h97- W4 f�q�LD|$�X�@5@}-C7'XG},%+A1oPj*C>A3Z>C �q
    IL&+E_xꠚ#DJIdC0xZ 2"+AN;ШgP(}g%1BÕI+&y*�2I!C11J,n3hW<z0ە3$.>MFۓTN1A舡KI
    #kiΨ	eK[3N1{(tnV&]-li,EǮCZ_
    q0NcLx�
    '
    (=z	MsO#-8xf�pH>+j%^A�ŀtdOKLHrE�!Pax��؆{D肔ǎ�deU(_@ڒו_=cFJ F&0UOD]@64,xJZNNRȦaJ.xiζvVjEjLdT*3QcؑrTz#SIX㔡UԶfP~ΏE2?
    m*EF-$*X5gi7귤OMQQ6,Ø1ww6P�}<xj1A:ggmŋ)No0c2 u#Ni��r|R;|%$%�w�zi@�p�PFG's7&IFj�ML{GM&g:Hi+zS(hH_2Bd|Z/l8g$
    D0<zpCI=EU3Dج"$y/D9MNve��c0,R$p\c!E\ j^U.I(ҠΞ	BY0 n15 =bȞ"?T~\_1
    YlI3FpQjJ[	'/7Cm3X0P^menT^ٻ=AZLpFt@	Yt=Eǹ`\~* ^@O+Gi*�sOL3�fJ�hBZ2 nY}1R{')A6AO8&m�)08{BG"j�PPPp$I	9+;vDkJe/mx$e5?!hD όF�Kh|T,
    ȺҺ]ƴ$FNxStb΋&L+eYFj !H:Iu��M@4"D,
    o4p&F GLfrv	d${W&K k2r asr#V[\P1kI31DKN";k.Ou3?{y]{vϦ$E70g]Xp�\:;l@/Ck	!BO[
     #wL9�	�Y�9}Ic@vq(�4H(=q`cҙRWW7e[$IZ.Mݕ%Eds'^8$9ۂؖ 1c`GnJfɥؒmغe.FPdU$]TMB,W&?$ɽz)!&v0a+pd'7 Ea/L*.�|$$I ^*�j#Vnu2
    w#$zQ!Sؓ3PeFjC|8^-hȘ$>иlJf|4pOFY2hj^~Cv(mz%p�'ZJ`y0�[KXOP`gF؎bq"kJ� AA/ȳn>w)}7Nz
    hg,COz04 b#9[d=6TPېN6�iHϡ]@ ~"wRJs}.d-Qq,٣uQ!s[XQ4LV(JUQe
    DY R!I>eRFX!1T|":%Ԥ(nFb8h4SR1HE6QX  e" ȃ0T^	P&SOR7Qq<R@,vh,L5Ri<+-*%#cMhwxųHQ&1̎XtB'׫)I]h,]nS! r(`Z		n%TsZn3�:�;\` 6�]L!d6HrO]<!�K�tЅjE4Bp> O ;T?h0yyy@cc b2t3܁q[nrC;[b8@e[CQeJ4}ļ=NVeNAuNhy2qrC=dҾ�@(	~.;צ_ݘZ8jty,yf}1|:6bT-bR ?$ae'$cR%MĔ:%U]W"TY/	C=AԴ#u5ժ8IS)b5'Kq?
    snVY{+%L�C�,;�:w$E�[Bpx-ŐC~ΆCRcCA`n8��)G	H@VO�]d, ؗ՞OG{r+!výmDCeFլkYT<4g*u2{IZ)\~I1%Mwq$G>|M>OU1+@S'
    L<MT5=y�/}!*(*DҴ	0TZ2< 4'RԂQ9`BEr17mc]"o[1?8FWd,*)ɥ_ݱ#C-Ip%>à*�x�?\@E_
    #f(+w
    \`yc1C,n_o�p=pCA'aad~Оp&!*违C]kPx>8vQ‰0 FJ4@b^!Wb燃
    *gi<m]H|xü&2+#>P7'1#8v61Bl9m4f=ݪ?NbL)&	>$7)+;Z05��LIDATߤe19j7ē((tZN
    ]JP=<[}BLX#Y:c}+cAVw
     n%hpyԠcܪL	&9s�8S=+fF1$B
    P
    S'e@tO]!H:�`p�P�}v!t@!Ab%=g0'0Cűd` Z�0 qB^EVnIioäƤzsxIY t2974vĨtPDjoTpQW�e:5ti"W %f
    =C5 RPfjQm8FM5$Ш n-9ϙR(:Fg$f!yT#-Hzd!;gzaWsss?"V
    N]?WR,CgY3`ah<@o]rD�m^6L'�a�}j@42ˎ`SA:1?Ah4Z*IRZ
    J+ LJB[xfZ6MIUa_[c
    ).5bNM'Re4q
    ^8x>pm{JT1:=V_n=_%MH64{iicJs>FUUxnWVOJfī='9)CM鶱*5W$8$I
    1ى��$x7
    ܾ3	0`zr_nj;HD%gvYj,�;''8sAA,
    )`8맔.$$I0$�RaB6B(^Q=ad}2DsLmAOOZ$3
    _DE
    vR@
    pFi77@|5uB*tSJSB215b 
    /�`)%tSaawK0{Z;Ϧn$P<1DQ
    \wAK
    o8?0DxOS|a@zI_
    4q�=AEIQ*E1R/I��!KSJtB$I}w1O)
    HG)M"���rA8Je]Xl'4N̜"9%9mp:R?~-m�rN�(vmavkϭ/|d0'0 
    b6<V)�:�0�S
    tVW
    Ƒ2RQARr?<(
    yz�?ż
    ����IENDB`�������������������������������������httpd-2.4.64/docs/icons/apache_pb2.png��������������������������������������������������������������0000664�0001751�0001751�00000024241�12033030440�017347� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR��������%}���sBIT|d���	pHYs��+��+#W���tEXtSoftware�www.inkscape.org<���tEXtTitle�Powered By: Apache 2.4���*tEXtAuthor�Daniel Gruno [humbedooh@apache.org]%���tEXtCreation Time�October 2nd, 2012٣�� �IDATxy|T?Ͻw%Lɾ  
    (kŵ.EZZ[k|AETp/		6}6�Am~教9<99%~,<sqmmm1&GDDt~hݾ/n_߿׏?U_rhn㎪B!4�� @'�fC>Sp+woԢݻkm)|_9yoڴ?}CʢANpHj㇈�Š(��.#Ƙ}X x�™3Z$uҔE\y_|ִ&ӦM뮻&?G3<st笫 'qy@�.˒,a>op�"[pmf^:Wcr&̎ϼeٲEL)g*fbG԰<s\jU֨Q UWWO=!;o2eΜƉ']o.l߾]po
    
    
    |n{�7to
    
    
    o�瞋;wW͘1ӟgu]ǂUV8cƌϳ;`Ŋf̘ynnnرc+.5+WL;v1_|999&M>6A%??2//r…�<pOAAA)Sߍ~:w%ŏ<ߥ1`*c[c�z<�W�2g|뭷f-#�YeDX"45d~TL\rԹd6.moxH5md*b\_zY`mƘ4/Z(j*'�Hzӻccc}EEE^7?�MjhhȱBJJd�N)..kٶ\ۺu;w,LMM6L;v츬9?::zC=Q\\<1lIII�L0AXzu̇~aeeeѣ$Ilٲ_xᅅӧO??lݺ
    �HJJ2y#u'˲f,//;ldϴRSS/pGEEyM&#ms4wgJKD<�f
    siii{{챮M6Ң<
    ,#OsMb0t_"ʤT*')Jh>j36/6)˿Q.}1/}.xAZtJ˲kg͚cr.O6mc=tc(**W_EFF�l�p8cƎ[jׯ_<tttܸgϞB̛7ow{`jjj,/~n$%%}cǎ***k}1<OL,++�.\sŦl=Sr]tw}C(|ߔ
    �&@kk$�HMMW$pYc=�J�� ==.O?䓇_~eڵkp
    󌱊7ȱ=Dg}#k:BK 99?0B
    4r hW3t}AH_ݚuS-5I_�(W_�j<gΜO͛i�})ʻZZZUUUϗ^{mJmmml~jnwvyy%555mf^$IPՁk>�#�l+77w{キ. �<׿%IBSSSFp-Zظq�.;[Gk4;|v֭E�^
    �222>ݵk]]]cood�HII||q�
    �n=s
    c(܉7S(>7lؠ</d7}P[Qw7h9,4:"F=
    fΈpJ4ZTWW6٧Ɍt߸P]R;||VVe'p_>}|UWfٲemڴEI$^�j�"##[t:6\y_edd4766ZZ[[t:yZm0*fR4}t7@ @L h4Iq'YP(d�`0<bt
    1NȺzG
    D�J�Y5�0{GT]]wkkkcLH>D4W�p:^!�FD(7'-IyްaCM@ pukke
    KoNUxQι26ڤ`aesr"Cǣ9^BJ3ag
    8bJOA8i
    xX.x W;;Zi}}})�PZZZhRl.E1#_dff	ڞ~�bbb�ln�j̙i�lw5TիU*\.jjj8?"'F]]h�~?�Je�,Z(o~Y^^~gEEI}ٲe#<,,!j�pclA/F>)KKK-X`W_=ĴvZ{n/#..LRj@Pg,fIJX-JvT0,[2@I~ԆD;)Pc|݂+ao*ŮvZTxo41
    ,C0k֬𦦦i�?99y�lo�\cǎѣGox<"ݻSz�7>T^^K/_nݶ@ zGZ855}XRRrܹs_(zQz·~̢ceeem۶|cJKKG\$2l9s\~С�U|B~׮]wlݺ5�O?�
    �+-c!|�k00#Q&	��c쌯1oTUUUe˖,?2�FDbuy++ŒGCɮ]gzD^}'{Fw;{Y{Y5lfv){S>y1T}[gޛ`Jm͹5*OmS)B]yO"sk
    wM9c�Xwq	I:N&N15k�ظq
    ҥKo9�f6>4N�v{j\}Ϙfഓ&Mj;!_dɝ^�LRɷ~J
    ޏ>5T]~"ѣGZ*}p	&`iii7n4/Ͽ3^�<6̫xG4ye
    cg8gΜ%%:>Hddv-	Q&
    U/g'@zB瘞 L"ˣCSBBxW4s*6?ryp*ecz]
    =!\%F.E]֧G={{n7g0�`ҥ={z:up׬YK/ձcĨjOFFƮ˗	&`04>|WXtZz}q<!_n˗/_õN{7c4뒓_'IRhVXqZ@A||֗cN	՟a`۟Nw�%KF?U)wuuvwaaF:[7N~tɭrEO)n;�VTxf�hBX)+dc.<EɃ	>l 6'$>%vC";\($	dP!Sp*B@'CIF!9h}o,3_	?z7Ƽ;s:nW^y˳'=y’~*/GpJRsD<gmrXﱎ^<gnUD!c%mS"9GX:xYv@U3.DUQ:&3A1Hor$#7c򊳺AhʫrOf>4"fsP3;8z8R" TsjHvs@emGcYo߮~{JKKu(b֬Yo|Wwz?3NN%|WfVfV
    .x!wTfG㾒d-OuATeś4U{*-"|RXmoZ��(y5³"RSGyIMxua#FfH
    ~NI}9V9DRM2G@򑀊	؜d(>dn9SQUve}>ii+nNq}/gW;~'3
    djwJJ1cƼCt,8R16hyB<5ʪZ;dRu^`JSopެp9R22IǷy$olBX]W5/IM:
    CV}Bi\qcq!yaETL Ə6!<2pAF9"=AT
    n"
    +凟IrIb˩v:POlr}A*ѻ}a!njZ۩`/Jr
    ~"6O`o^/;JD!
    
    (XA!-F8REARnwuMSfϘkw].2(z1(~t$KQ"B[08f)z.6!
    ^;N%J+K&	$d`Qj4rj4,Sۍ[I3YUI~6r!T$㛂PkH\EZ-mznr]x#zNa*$	v17iaڱ'aG7s8/T<l/!r79Tz4}?#hRnK}00/w)&`0%t
    0P0ZBFA˕�nB,��;�^W�4T(J cz7{I-�z#Qf([=ueN
    .g4
    F�Ic%gdd<P[_R<V\[ϵe!",)E_烁$@>,vUj֤H5]u4k6J
    v=�<*3&$94Lo!F+SOKcBo;̍mr<+YFZ=*N+X$TkCr9˨wI7	7[3Jv$t`3j%.�U$[4?ٙk:4ƪ݌1{3wp%;%Y0CZg �ɯ<u64< �}+ŬWp,.0hYH `��0wS
    �>/.bh\Y	~=#d%==� =5u;��Y͸Wn|m[J&c[D$1YFdc@ʂ<)%K#t[yqOf^evX[w8~F~s23R"bzF:uؼ@JTʢzBQ#sWkEj$vd�!.cu♔1\|h'$'ϓJ&sc3J
    
    |\$䬋ViKFuyBU޵vs 0m~./I�AV	ɻ�~\=Y/礌uO-Nd0!,u`�(htsߐ޼233+ ==ݟ;bϕ}vir(SHjp)Z,�Z NQr$pehxQ#URC{R+OI[-xպfG3;>"DkXD0Q
    z,)a/qi=zr"*c|c02qyL9ֻlJXߓ|]XXK2fӉ_ɦ6Rt2rHt\sF5_m}&++kۺZB/ozsR9`-U9!�Q'<-�Jn5Cx'#6X@ޗ)sWWAO=uʛ7h0*��~߯<c>Wlt³y[lD[_�iiiN�QRƮn8Ыlsy+J(
    hS[V�.(K~>A-;|3(@d#jM{s/)ɍ>-MMF*,(
    :¹Heh4𑂁e*#DZ"GYFlRi@q
    $q6Y(5$)%w[Cam8J+*3_9?Iya ]a[6<TA!63\	+yf,aB	÷>F+0Mr ��iS>9EPAӝ�}#`[ι@�f�ɞ3*OU�Wн>tgzvxfhy}(#;ddd<SSS%qbJhtVٽ{<1>UU	c`dmr<d5�t1"ՂDQnQQAȉ=$j
    6ZJSIT!1A"edPx1_;cG(R�_Aȴ^j#>>*BRZPH"zRĢnxۖL\JVi9~fQ!^oHkq۸?eyS;pO�` y|MT0S6T?�6@8i�h`@+!|'-ۏ+aaw#]{ʜ	燽�[sXncN^?܁3C&}{1
    �Vz+脼7^G^+5{ڼ�6>	G$kWJn!hcJo
    ]r#!7:1SVj07$uA\˄H?wJ܁x#.j
    pRM(6U1mJ$̵+u`EᛨDxn꥔TcLr($쯌)A7>x}5"H4`Qs4,>.1p:Y
    Eqm@Ū0-3tYS<=ˮ,uLmGxqu0w3@78K{y/�6ijU;b*�`ܩRشƬX)=9?u�i`s�6k|t[dK>dT|O#o۷`;ҟpm+wqoWY~ T׿8vOoĐksYq_g䉵!5^w+C$F<B/H!dx>B^4q)vuK+م鍄05y'i=\I57OVۂ&%e<܊3vfXP	~X(2h#R>|i]nlsp<7Ղl0hPY8<qdHNLbjRg޲pﰾ\<3ۀ1=8ñ<2,#0`#gПV^#r�@O`0`O<`+=S!Z;$VC<`O2&�Fp*"1p=E;]Q뗪3+PSNYuHR%3˨Xډ>H2!κc"(-Ff'ej1��IDATډҭV@E)'xdƲ:	GU|_2Ivɗr\t�*t{sz'[ps>Ą1AaOZF^)x;yL^`(4q 鑲8ɏzWmpsV5:&5?Sk,!I�iw0a*)�2s1|5\" ߝc`Ezb@;1Km`/#ɩ�
     eASCƟv]Xw\`qv48['I˰r9)`-1/Q}OOsZ,3[8kP+{*ߡ`P)n\\4hĨ2JE
    tz$VgF^TAMshRRx_6n'/CjS+1N!I7B[f49qȣd:|M /�6mX3rܱRQ΍crbѱG]r{ߙ:4`z߿v/e2?Q8>m9ˆ! wT
    h^G+#@*n<ؓ}'Zb/khKJBf6k#Q 9=O$ITWWObM�+�"<�m$v9:`hh\@Tȣj1AʭA
    ̽Ï'j$#_熽Z2wюxPƀ,,PFGb awg2k
    7A'2k&iY6^6`̡>A+Bt(Rb0,^WT
    Ft2:ON~Z?33s'aBS*)EQ錂YVF�y’+{Fa`uCf�X	\-sAsBR>B30
    Ħ4�Z�?E،u yӐ SS8W?84RLT(d4Fq,.)7T�,1cq1s8ͪҮ.yv]m
    /{5_T\Na>91IޯTvHN'ű}zK>믉GrY6as"9
    blg^LfeǜƤj7vKBqŕ	t$$5	c
     qNzٰa#܈%#Cokrq6C4?ep!iP�f�	p;�\%O8߿ٳx]е*-O/#sjkkS}>KPnw^q\,F&�e9q1"eYfD$ma+XvIwt2|.LjJneohqTWӳܮF^&K]o0�Hb%Yc�x�舨@,E*ꝤS+70]6c(f#w
    >z[#zzP+Fg��h%H_!,[~H
    _2O3r{]|wŏm]/pԤʲT*@ v܀rw	c^"JeY8.
    1v1#"c^Ƙ<1=EQ)OZZZ�TVVJ6Dt%jZߟQ@<�yaI&v'
     *NL#id4dMۍ௧gbz )_{;J ߃!cniд"OB�F10Nb^�`N*p48{xxH#:-փGKcI&.pu(RTl����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/tex.png���������������������������������������������������������������������0000664�0001751�0001751�00000000466�10671421551�016203� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���eIDAT[m
     N
    db�#4-e6"jjD r^ASH<�+SǠb+؆.\{m[v{W۵')c���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/hand.right.png��������������������������������������������������������������0000664�0001751�0001751�00000000467�10671421551�017432� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙f3���$(���tRNS�
    A���bKGD�H���eIDAT
    C1Y7X~aXiR$TWȟLrڶ IZ6p`5$-(նXIVcl\
    W|cײ/POM���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/right.gif�������������������������������������������������������������������0000664�0001751�0001751�00000000254�10147723030�016467� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������+⚀QMZy}R؅eHjf^lt=ݸ^��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/box1.png��������������������������������������������������������������������0000664�0001751�0001751�00000000505�10664777241�016262� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙333�3�f3������tRNS�0J���bKGD�H���kIDATuΡ
    0Ӗ&
    
    ve!{^7×)ӄ%~9;gFdW[NXscS8
    Sıl/Bl`)SZ$fA���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sphere2.png�����������������������������������������������������������������0000664�0001751�0001751�00000000523�10664777241�016761� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33f��333���	���tRNS�@*���bKGD�H���wIDATU1
    0@ѸOt(%PPMG$p2"1͠cK;yMvZ˲N<uz垸Bp'$C\[Q'{�z-C���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/apache_pb.svg���������������������������������������������������������������0000664�0001751�0001751�00001010327�12033572341�017314� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!-- Created with Inkscape (http://www.inkscape.org/) -->
    
    <svg
       xmlns:dc="http://purl.org/dc/elements/1.1/"
       xmlns:cc="http://creativecommons.org/ns#"
       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
       xmlns:svg="http://www.w3.org/2000/svg"
       xmlns="http://www.w3.org/2000/svg"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
       xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
       version="1.1"
       width="587.63806"
       height="68.379463"
       id="svg15391"
       inkscape:version="0.48.3.1 r9886"
       sodipodi:docname="apache_pb.svg"
       inkscape:export-filename="/home/daniel/Pictures/apache_pb22.png"
       inkscape:export-xdpi="40.103409"
       inkscape:export-ydpi="40.103409">
      <sodipodi:namedview
         pagecolor="#ffffff"
         bordercolor="#666666"
         borderopacity="1"
         objecttolerance="10"
         gridtolerance="10"
         guidetolerance="10"
         inkscape:pageopacity="0"
         inkscape:pageshadow="2"
         inkscape:window-width="1855"
         inkscape:window-height="1056"
         id="namedview1253"
         showgrid="false"
         inkscape:zoom="1"
         inkscape:cx="293.81903"
         inkscape:cy="34.189732"
         inkscape:window-x="65"
         inkscape:window-y="24"
         inkscape:window-maximized="1"
         inkscape:current-layer="text5115" />
      <title
         id="title4227">Powered By: Apache 2.4</title>
      <defs
         id="defs15393">
        <linearGradient
           id="linearGradient4225">
          <stop
             id="stop4227"
             style="stop-color:#0400ff;stop-opacity:1"
             offset="0" />
          <stop
             id="stop5005"
             style="stop-color:#9d00ff;stop-opacity:1"
             offset="0.125" />
          <stop
             id="stop5003"
             style="stop-color:#ff0086;stop-opacity:1"
             offset="0.25" />
          <stop
             id="stop5001"
             style="stop-color:#ff005d;stop-opacity:1"
             offset="0.5" />
          <stop
             id="stop4229"
             style="stop-color:#ffa600;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3510.3682"
           y1="4186.3037"
           x2="-3520.3882"
           y2="4153.2837"
           id="linearGradient23811"
           xlink:href="#AIgd1-0"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,-2022.5977,2980.6621)" />
        <linearGradient
           x1="-3510.3682"
           y1="4186.3037"
           x2="-3520.3882"
           y2="4153.2837"
           id="AIgd1-0"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,-2022.5977,2980.6621)">
          <stop
             id="stop170-2"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop172-11"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop174-6"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop176-4"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop178-9"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop180-5"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop182-5"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop184-2"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3788.0986"
           y1="-3507.6162"
           x2="-3789.1638"
           y2="-3479.4058"
           id="AIgd2-1"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop193-9"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop195-2"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop197-0"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop199-9"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop201-4"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop203-2"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop205-9"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop207-8"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="linearGradient3725-0"
           xlink:href="#AIgd3-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="AIgd3-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop214-9"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop216-7"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop218-5"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop220-40"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop222-49"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop224-2"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop226-3"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop228-7"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3806.9058"
           y1="-3505.3105"
           x2="-3807.8401"
           y2="-3480.5605"
           id="AIgd4-46"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop235-8"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop237-7"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop239-22"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop241-79"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop243-8"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop245-9"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop247-2"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop249-9"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="linearGradient3727-1"
           xlink:href="#AIgd3-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="linearGradient9145"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9147"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9149"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9151"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9153"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9155"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9157"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9159"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9161"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3825.4375"
           y1="-3503.8936"
           x2="-3826.3342"
           y2="-3480.1453"
           id="AIgd6-5"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop258-8"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop260-5"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop262-7"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop264-9"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop266-5"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop268-0"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop270-7"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop272-7"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="linearGradient3729-7"
           xlink:href="#AIgd3-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="linearGradient9173"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9175"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9177"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9179"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9181"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9183"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9185"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9187"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9189"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3841.6636"
           y1="-3502.4297"
           x2="-3842.4236"
           y2="-3482.3"
           id="AIgd8-4"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop281-10"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop283-9"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop285-0"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop287-4"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop289-4"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop291-7"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop293-9"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop295-2"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="linearGradient3731-8"
           xlink:href="#AIgd3-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3817.4316"
           y1="-3498.7192"
           x2="-3818.3076"
           y2="-3475.5176"
           id="linearGradient9201"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9203"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9205"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9207"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9209"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9211"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9213"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9215"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9217"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3733-6"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop304-0"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop306-3"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop308-6"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop310-0"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop312-49"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop314-9"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient3735-5"
           xlink:href="#AIgd11-4"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="AIgd11-4"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop321-9"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop323-3"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop325-3"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop327-8"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop329-8"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop331-3"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3737-7"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient9236"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9238"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9240"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9242"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9244"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9246"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9248"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient3739-5"
           xlink:href="#AIgd11-4"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient9251"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9253"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9255"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9257"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9259"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9261"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9263"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3741-3"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient9266"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9268"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9270"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9272"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9274"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9276"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9278"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3743-2"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient9281"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9283"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9285"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9287"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9289"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9291"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9293"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3892.5645"
           y1="-3497.0415"
           x2="-3892.7126"
           y2="-3490.0823"
           id="AIgd16-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop346-5"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop348-3"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop350-9"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop352-1"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop354-7"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop356-90"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3745-0"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient9303"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9305"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9307"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9309"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9311"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9313"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9315"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3747-7"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop365-7"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop367-9"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop369-4"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop371-5"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop373-0"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop375-96"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop377-1"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop379-6"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3818.3081"
           y1="-3506.1616"
           x2="-3836.2568"
           y2="-3532.4282"
           id="linearGradient3749-2"
           xlink:href="#AIgd19-1"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3818.3081"
           y1="-3506.1616"
           x2="-3836.2568"
           y2="-3532.4282"
           id="AIgd19-1"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop386-9"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop388-6"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop390-1"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop392-0"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop394-1"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop396-9"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop398-5"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop400-4"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3751-1"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient9338"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9340"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9342"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9344"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9346"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9348"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9350"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9352"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9354"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3818.3081"
           y1="-3506.1616"
           x2="-3836.2568"
           y2="-3532.4282"
           id="linearGradient3753-4"
           xlink:href="#AIgd19-1"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3818.3081"
           y1="-3506.1616"
           x2="-3836.2568"
           y2="-3532.4282"
           id="linearGradient9357"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9359"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9361"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9363"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9365"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9367"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9369"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9371"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9373"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3755-9"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient9376"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9378"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9380"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9382"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9384"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9386"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9388"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9390"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9392"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3818.3081"
           y1="-3506.1616"
           x2="-3836.2568"
           y2="-3532.4282"
           id="linearGradient3757-6"
           xlink:href="#AIgd19-1"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3818.3081"
           y1="-3506.1616"
           x2="-3836.2568"
           y2="-3532.4282"
           id="linearGradient9395"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9397"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9399"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9401"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9403"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9405"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9407"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9409"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9411"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3759-6"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient9414"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9416"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9418"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9420"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9422"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9424"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9426"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9428"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9430"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3761-1"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient9433"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9435"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9437"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9439"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9441"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9443"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9445"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient3763-3"
           xlink:href="#AIgd11-4"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient9448"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9450"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9452"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9454"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9456"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9458"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9460"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient3765-7"
           xlink:href="#AIgd11-4"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient9463"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9465"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9467"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9469"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9471"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9473"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9475"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient3767-3"
           xlink:href="#AIgd11-4"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3878.0732"
           y1="-3508.4204"
           x2="-3874.5449"
           y2="-3484.9487"
           id="linearGradient9478"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9480"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9482"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9484"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9486"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9488"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9490"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3769-5"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient9493"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9495"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9497"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9499"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9501"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9503"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9505"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient3771-6"
           xlink:href="#AIgd10-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3872.1543"
           y1="-3503.9727"
           x2="-3872.3848"
           y2="-3493.1567"
           id="linearGradient9508"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9510"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9512"
             style="stop-color:#f5d65d;stop-opacity:1"
             offset="0.186" />
          <stop
             id="stop9514"
             style="stop-color:#f4c35b;stop-opacity:1"
             offset="0.38249999" />
          <stop
             id="stop9516"
             style="stop-color:#f4bc5a;stop-opacity:1"
             offset="0.51980001" />
          <stop
             id="stop9518"
             style="stop-color:#f5da5d;stop-opacity:1"
             offset="0.7809" />
          <stop
             id="stop9520"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="linearGradient3773-4"
           xlink:href="#AIgd31-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="AIgd31-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop429-7"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop431-9"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop433-09"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop435-0"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop437-61"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop439-8"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop441-92"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop443-8"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop445-5"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop447-5"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="linearGradient3775-0"
           xlink:href="#AIgd31-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="linearGradient9535"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9537"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9539"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9541"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9543"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9545"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9547"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9549"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9551"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9553"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9555"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="linearGradient3777-8"
           xlink:href="#AIgd31-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="linearGradient9558"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9560"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9562"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9564"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9566"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9568"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9570"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9572"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9574"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9576"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9578"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="linearGradient3779-4"
           xlink:href="#AIgd31-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3644.5117"
           y1="-3531.5527"
           x2="-3636.6318"
           y2="-3508.3506"
           id="linearGradient9581"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9583"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9585"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9587"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9589"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9591"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9593"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9595"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9597"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9599"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9601"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3738.23"
           y1="-3453.355"
           x2="-3733.0664"
           y2="-3424.071"
           id="AIgd35-5"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop460-37"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop462-2"
             style="stop-color:#6f1182;stop-opacity:1"
             offset="0.0752" />
          <stop
             id="stop464-4"
             style="stop-color:#831380;stop-opacity:1"
             offset="0.1935" />
          <stop
             id="stop466-3"
             style="stop-color:#a3157b;stop-opacity:1"
             offset="0.33989999" />
          <stop
             id="stop468-0"
             style="stop-color:#d11975;stop-opacity:1"
             offset="0.50880003" />
          <stop
             id="stop470-7"
             style="stop-color:#f21b71;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop472-9"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient3781-9"
           xlink:href="#AIgd36-3"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="AIgd36-3"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop479-4"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop481-5"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop483-7"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop485-9"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop487-2"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop489-8"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop491-9"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop493-4"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop495-0"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop497-7"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient3783-5"
           xlink:href="#AIgd36-3"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient9624"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9626"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9628"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9630"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9632"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9634"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9636"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9638"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9640"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9642"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9644"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient3785-9"
           xlink:href="#AIgd38-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="AIgd38-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop506-9"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop508-9"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop510-3"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop512-4"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop514-9"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop516-2"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop518-16"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop520-7"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop522-88"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop524-1"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient3787-4"
           xlink:href="#AIgd36-3"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient9659"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9661"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9663"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9665"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9667"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9669"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9671"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9673"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9675"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9677"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9679"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient3789-0"
           xlink:href="#AIgd38-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient9682"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9684"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9686"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9688"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9690"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9692"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9694"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9696"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9698"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9700"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9702"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3711.1768"
           y1="-3514.0366"
           x2="-3709.7402"
           y2="-3493.4663"
           id="AIgd41-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop535-3"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop537-9"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop539-4"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop541-9"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop543-61"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop545-0"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop547-1"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop549-0"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop551-9"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop553-5"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3718.4951"
           y1="-3510.1016"
           x2="-3716.7441"
           y2="-3482.9595"
           id="linearGradient3791-0"
           xlink:href="#AIgd42-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3718.4951"
           y1="-3510.1016"
           x2="-3716.7441"
           y2="-3482.9595"
           id="AIgd42-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop560-0"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop562-1"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop564-5"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop566-1"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop568-0"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop570-9"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop572-5"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop574-9"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop576-3"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop578-6"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3718.4951"
           y1="-3510.1016"
           x2="-3716.7441"
           y2="-3482.9595"
           id="linearGradient3793-6"
           xlink:href="#AIgd42-7"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3718.4951"
           y1="-3510.1016"
           x2="-3716.7441"
           y2="-3482.9595"
           id="linearGradient9728"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9730"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9732"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9734"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9736"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9738"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9740"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9742"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9744"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9746"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9748"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient3795-0"
           xlink:href="#AIgd38-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient9751"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9753"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9755"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9757"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9759"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9761"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9763"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9765"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9767"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9769"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9771"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient3797-7"
           xlink:href="#AIgd38-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient9774"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9776"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9778"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9780"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9782"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9784"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9786"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9788"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9790"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9792"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9794"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient3799-6"
           xlink:href="#AIgd36-3"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient9797"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9799"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9801"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9803"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9805"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9807"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9809"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9811"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9813"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9815"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9817"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient3801-3"
           xlink:href="#AIgd38-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient9820"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9822"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9824"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9826"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9828"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9830"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9832"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9834"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9836"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9838"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9840"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient3803-1"
           xlink:href="#AIgd36-3"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient9843"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9845"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9847"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9849"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9851"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9853"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9855"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9857"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9859"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9861"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9863"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient3805-7"
           xlink:href="#AIgd38-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.5049"
           y1="-3512.9565"
           x2="-3712.3662"
           y2="-3473.3286"
           id="linearGradient9866"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9868"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9870"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9872"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9874"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9876"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9878"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9880"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9882"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9884"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9886"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient3807-4"
           xlink:href="#AIgd36-3"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.3066"
           y1="-3509.6641"
           x2="-3713.6802"
           y2="-3491.7153"
           id="linearGradient9889"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9891"
             style="stop-color:#681083;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9893"
             style="stop-color:#681083;stop-opacity:1"
             offset="0.0006" />
          <stop
             id="stop9895"
             style="stop-color:#8d0f6d;stop-opacity:1"
             offset="0.072" />
          <stop
             id="stop9897"
             style="stop-color:#ad0d5a;stop-opacity:1"
             offset="0.1459" />
          <stop
             id="stop9899"
             style="stop-color:#c80a4a;stop-opacity:1"
             offset="0.2229" />
          <stop
             id="stop9901"
             style="stop-color:#de083e;stop-opacity:1"
             offset="0.30410001" />
          <stop
             id="stop9903"
             style="stop-color:#ed0335;stop-opacity:1"
             offset="0.39129999" />
          <stop
             id="stop9905"
             style="stop-color:#f60030;stop-opacity:1"
             offset="0.48840001" />
          <stop
             id="stop9907"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9909"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3809-6"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient9912"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9914"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9916"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9918"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9920"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9922"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9924"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9926"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9928"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient3811-8"
           xlink:href="#AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop603-7"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop605-7"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop607-0"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop609-8"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop611-8"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop613-2"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop615-9"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop617-5"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3813-4"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient9941"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9943"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9945"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9947"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9949"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9951"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9953"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9955"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9957"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient3815-6"
           xlink:href="#AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient9960"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9962"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9964"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9966"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9968"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9970"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9972"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9974"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9976"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3817-7"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient9979"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop9981"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop9983"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop9985"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop9987"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop9989"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop9991"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop9993"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop9995"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient3819-6"
           xlink:href="#AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient9998"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10000"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10002"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10004"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10006"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10008"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10010"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10012"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10014"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3821-4"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10017"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10019"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10021"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10023"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10025"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10027"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10029"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10031"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10033"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3823-8"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10036"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10038"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10040"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10042"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10044"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10046"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10048"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10050"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10052"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient3825-6"
           xlink:href="#AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient10055"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10057"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10059"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10061"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10063"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10065"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10067"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10069"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10071"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3827-5"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10074"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10076"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10078"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10080"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10082"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10084"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10086"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10088"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10090"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient3829-3"
           xlink:href="#AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient10093"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10095"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10097"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10099"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10101"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10103"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10105"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10107"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10109"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3831-8"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10112"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10114"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10116"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10118"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10120"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10122"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10124"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10126"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10128"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient3833-8"
           xlink:href="#AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient10131"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10133"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10135"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10137"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10139"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10141"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10143"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10145"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10147"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3835-2"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10150"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10152"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10154"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10156"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10158"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10160"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10162"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10164"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10166"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient3837-4"
           xlink:href="#AIgd52-8"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3690.9155"
           y1="-3526.2993"
           x2="-3702.7354"
           y2="-3558.2568"
           id="linearGradient10169"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10171"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10173"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10175"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10177"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10179"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10181"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10183"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10185"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3839-0"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10188"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10190"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10192"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10194"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10196"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10198"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10200"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10202"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10204"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3841-9"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10207"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10209"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10211"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10213"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10215"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10217"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10219"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10221"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10223"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient3843-2"
           xlink:href="#AIgd18-9"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3716.793"
           y1="-3522.1724"
           x2="-3726.813"
           y2="-3555.1924"
           id="linearGradient10226"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10228"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10230"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10232"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10234"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10236"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10238"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10240"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10242"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3772.377"
           y1="-3509.7163"
           x2="-3797.2949"
           y2="-3537.6816"
           id="linearGradient3845-3"
           xlink:href="#AIgd69-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3772.377"
           y1="-3509.7163"
           x2="-3797.2949"
           y2="-3537.6816"
           id="AIgd69-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop656-1"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop658-8"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop660-0"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop662-0"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop664-67"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop666-7"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop668-8"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop670-57"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3772.377"
           y1="-3509.7163"
           x2="-3797.2949"
           y2="-3537.6816"
           id="linearGradient3847-2"
           xlink:href="#AIgd69-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)" />
        <linearGradient
           x1="-3772.377"
           y1="-3509.7163"
           x2="-3797.2949"
           y2="-3537.6816"
           id="linearGradient10255"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
          <stop
             id="stop10257"
             style="stop-color:#4f0c81;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10259"
             style="stop-color:#690c73;stop-opacity:1"
             offset="0.0701" />
          <stop
             id="stop10261"
             style="stop-color:#9a0a5b;stop-opacity:1"
             offset="0.20900001" />
          <stop
             id="stop10263"
             style="stop-color:#c20748;stop-opacity:1"
             offset="0.33680001" />
          <stop
             id="stop10265"
             style="stop-color:#e0053a;stop-opacity:1"
             offset="0.45120001" />
          <stop
             id="stop10267"
             style="stop-color:#f20032;stop-opacity:1"
             offset="0.54809999" />
          <stop
             id="stop10269"
             style="stop-color:#fa002f;stop-opacity:1"
             offset="0.61580002" />
          <stop
             id="stop10271"
             style="stop-color:#f7ee5f;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3498.5225"
           y1="4158.0396"
           x2="-3482.3647"
           y2="4209.6001"
           id="linearGradient23809"
           xlink:href="#AIgd71-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,-1982.8965,3021.3838)" />
        <linearGradient
           x1="-3498.5225"
           y1="4158.0396"
           x2="-3482.3647"
           y2="4209.6001"
           id="AIgd71-2"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,-1982.8965,3021.3838)">
          <stop
             id="stop679-7"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop681-3"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop683-9"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop685-3"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop687-9"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop689-9"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop691-1"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop693-4"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop695-2"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop697-1"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3849-2"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop704-5"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop706-47"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop708-0"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop710-8"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop712-9"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop714-1"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop716-8"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop718-1"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop720-1"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop722-6"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3851-9"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10298"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10300"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10302"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10304"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10306"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10308"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10310"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10312"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10314"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10316"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10318"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3853-0"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10321"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10323"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10325"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10327"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10329"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10331"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10333"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10335"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10337"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10339"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10341"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3855-7"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10344"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10346"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10348"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10350"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10352"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10354"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10356"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10358"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10360"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10362"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10364"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3857-6"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10367"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10369"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10371"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10373"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10375"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10377"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10379"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10381"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10383"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10385"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10387"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3859-9"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10390"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10392"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10394"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10396"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10398"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10400"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10402"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10404"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10406"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10408"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10410"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3861-9"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10413"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10415"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10417"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10419"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10421"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10423"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10425"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10427"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10429"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10431"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10433"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3863-3"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10436"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10438"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10440"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10442"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10444"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10446"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10448"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10450"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10452"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10454"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10456"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3865-3"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10459"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10461"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10463"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10465"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10467"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10469"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10471"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10473"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10475"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10477"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10479"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient3867-6"
           xlink:href="#AIgd72-6"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)" />
        <linearGradient
           x1="-3704.9473"
           y1="-3493.9082"
           x2="-3688.7896"
           y2="-3442.3477"
           id="linearGradient10482"
           gradientUnits="userSpaceOnUse"
           gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
          <stop
             id="stop10484"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="0" />
          <stop
             id="stop10486"
             style="stop-color:#c9d9de;stop-opacity:1"
             offset="0.0849" />
          <stop
             id="stop10488"
             style="stop-color:#a5b8c2;stop-opacity:1"
             offset="0.2184" />
          <stop
             id="stop10490"
             style="stop-color:#728896;stop-opacity:1"
             offset="0.3836" />
          <stop
             id="stop10492"
             style="stop-color:#405766;stop-opacity:1"
             offset="0.55369997" />
          <stop
             id="stop10494"
             style="stop-color:#667d8b;stop-opacity:1"
             offset="0.64170003" />
          <stop
             id="stop10496"
             style="stop-color:#92a7b1;stop-opacity:1"
             offset="0.74199998" />
          <stop
             id="stop10498"
             style="stop-color:#b7c8d0;stop-opacity:1"
             offset="0.83740002" />
          <stop
             id="stop10500"
             style="stop-color:#cfdfe4;stop-opacity:1"
             offset="0.92570001" />
          <stop
             id="stop10502"
             style="stop-color:#d8e7eb;stop-opacity:1"
             offset="1" />
        </linearGradient>
        <linearGradient
           x1="224.25386"
           y1="107.27033"
           x2="583.86816"
           y2="107.27033"
           id="linearGradient4231"
           xlink:href="#linearGradient4225"
           gradientUnits="userSpaceOnUse" />
      </defs>
      <metadata
         id="metadata15396">
        <rdf:RDF>
          <cc:Work
             rdf:about="">
            <dc:format>image/svg+xml</dc:format>
            <dc:type
               rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
            <dc:title>Powered By: Apache 2.4</dc:title>
            <dc:date>October 2nd, 2012</dc:date>
            <dc:creator>
              <cc:Agent>
                <dc:title>Daniel Gruno [humbedooh@apache.org]</dc:title>
              </cc:Agent>
            </dc:creator>
            <dc:rights>
              <cc:Agent>
                <dc:title>Copyright 2012, Apache Software Foundation</dc:title>
              </cc:Agent>
            </dc:rights>
            <dc:publisher>
              <cc:Agent>
                <dc:title>Apache Software Foun</dc:title>
              </cc:Agent>
            </dc:publisher>
          </cc:Work>
        </rdf:RDF>
      </metadata>
      <g
         transform="translate(-11.473237,-21.469327)"
         id="layer1">
        <g
           transform="matrix(-1.2697137,0,0,1.2697137,225.64827,25.009594)"
           id="Feather_x0020_shadow-3">
          <path
             d="m 0.281,44.304 c 13.561,-1.867 63.613,-4.392 85.943,-8.05 17.961,-2.937 35.502,-8.285 52.242,-13.9 4.328,-1.453 11.991,-4.434 16.896,-7.07 3.104,-2.373 10.571,-5.889 12.606,-9.222 -32.45,15.407 -45.513,19.649 -83.582,27.354 -15.436,3.169 -71.617,7.72 -84.105,10.888 z"
             id="path4-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.59560001;stroke-miterlimit:4" />
          <path
             d="m 48.301,50.277 1.454,0.498 1.418,0.119 1.417,-0.23 1.417,-0.574 1.379,-0.766 1.38,-0.994 1.305,-1.145 1.301,-1.227 1.228,-1.26 1.149,-1.266 1.111,-1.225 1.035,-1.148 0.958,-0.957 0.881,-0.763 0.766,-0.499 0.689,-0.228 -0.576,0.036 -0.611,0.038 -0.689,0.077 -0.688,0.074 -0.69,0.078 -0.689,0.076 -0.689,0.038 -0.612,0.076 -0.957,0.88 -0.921,0.841 -0.805,0.842 -0.729,0.844 -0.727,0.801 -0.688,0.805 -0.652,0.764 -0.691,0.729 -0.688,0.727 -0.729,0.65 -0.767,0.65 -0.882,0.611 -0.919,0.576 -1.034,0.535 -1.149,0.496 -1.302,0.42 z"
             id="path6-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 43.551,50.082 1.688,0.271 1.569,0.037 1.455,-0.15 1.377,-0.344 1.265,-0.535 1.151,-0.652 1.148,-0.766 1.034,-0.879 1.035,-0.918 0.957,-0.994 0.959,-1.072 0.921,-1.033 0.956,-1.033 0.96,-1.033 0.958,-0.955 0.995,-0.881 -0.381,0.037 h -0.423 l -0.384,0.039 -0.419,0.037 -0.424,0.037 -0.421,0.078 -0.42,0.035 -0.42,0.041 -0.421,0.037 -0.461,0.037 -0.422,0.078 -0.459,0.037 -0.459,0.037 -0.46,0.037 h -0.46 l -0.459,0.039 -0.347,0.535 -0.42,0.652 -0.537,0.764 -0.575,0.805 -0.69,0.881 -0.729,0.879 -0.766,0.918 -0.805,0.879 -0.844,0.844 -0.84,0.805 -0.885,0.727 -0.842,0.611 -0.844,0.496 -0.843,0.346 -0.804,0.189 h -0.768 z"
             id="path8-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 40.411,50.119 0.958,0.115 0.919,0.076 0.881,-0.037 0.881,-0.152 0.882,-0.189 0.843,-0.344 0.841,-0.422 0.883,-0.574 0.882,-0.65 0.882,-0.764 0.882,-0.92 0.919,-0.994 0.958,-1.188 0.997,-1.301 1.034,-1.416 1.074,-1.607 -0.651,-0.002 -0.613,0.039 -0.614,0.076 -0.612,0.076 -0.611,0.078 -0.613,0.072 h -0.688 -0.727 l -0.616,0.613 -0.573,0.65 -0.576,0.613 -0.574,0.688 -0.575,0.65 -0.535,0.689 -0.576,0.648 -0.539,0.691 -0.572,0.65 -0.574,0.65 -0.612,0.65 -0.582,0.617 -0.65,0.572 -0.652,0.574 -0.65,0.574 -0.729,0.498 z"
             id="path10-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 37.081,49.96 0.728,0.387 0.802,0.154 0.807,-0.117 0.842,-0.342 0.844,-0.5 0.881,-0.689 0.88,-0.764 0.884,-0.916 0.841,-0.959 0.884,-0.992 0.804,-0.998 0.805,-0.957 0.768,-0.957 0.729,-0.84 0.689,-0.729 0.614,-0.613 -4.099,0.382 -0.462,0.611 -0.498,0.611 -0.458,0.615 -0.459,0.609 -0.46,0.613 -0.5,0.613 -0.461,0.611 -0.497,0.613 -0.537,0.572 -0.537,0.611 -0.536,0.578 -0.613,0.57 -0.612,0.574 -0.653,0.576 -0.688,0.537 -0.728,0.531 z"
             id="path12-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 30.302,49.076 1.188,0.768 1.109,0.5 1.11,0.23 h 1.074 l 1.033,-0.191 0.995,-0.342 0.955,-0.539 0.96,-0.686 0.919,-0.842 0.923,-0.881 0.84,-1.037 0.884,-1.031 0.843,-1.109 0.844,-1.146 0.805,-1.148 0.805,-1.111 -0.689,0.114 -0.536,0.037 -0.384,0.037 -0.345,0.039 -0.343,0.039 h -0.346 l -0.499,0.037 -0.651,0.037 -0.729,1.033 -0.727,0.955 -0.729,0.922 -0.805,0.803 -0.767,0.727 -0.767,0.689 -0.804,0.611 -0.768,0.537 -0.766,0.457 -0.768,0.422 -0.727,0.305 -0.689,0.27 -0.689,0.229 -0.614,0.152 -0.612,0.076 -0.537,0.037 z"
             id="path14-0"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 26.74,48.843 1.228,0.152 1.186,0.08 1.149,-0.078 1.109,-0.15 1.036,-0.227 1.033,-0.346 0.958,-0.422 0.92,-0.535 0.92,-0.572 0.844,-0.65 0.843,-0.727 0.803,-0.805 0.766,-0.842 0.73,-0.918 0.729,-0.959 0.689,-0.994 -0.767,0.039 -0.844,0.074 -0.802,0.076 -0.806,0.039 -0.69,0.076 -0.574,0.035 -0.42,0.041 -0.191,0.037 -0.076,0.078 -0.191,0.191 -0.308,0.305 -0.382,0.385 -0.422,0.459 -0.536,0.537 -0.577,0.572 -0.648,0.615 -0.731,0.607 -0.764,0.65 -0.768,0.615 -0.843,0.611 -0.88,0.572 -0.881,0.535 -0.921,0.461 -0.921,0.381 z"
             id="path16-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 22.031,49.109 1.033,0.191 0.998,0.076 1.033,-0.113 1.034,-0.191 1.034,-0.342 0.994,-0.422 0.996,-0.498 0.998,-0.611 0.919,-0.648 0.918,-0.689 0.881,-0.727 0.845,-0.766 0.806,-0.803 0.766,-0.766 0.69,-0.768 0.651,-0.766 h -0.461 l -0.574,0.041 -0.611,0.035 H 34.33 l -0.613,0.074 -0.613,0.041 -0.496,0.039 -0.423,0.074 v 0.078 l -0.154,0.189 -0.381,0.346 -0.537,0.42 -0.653,0.537 -0.764,0.613 -0.845,0.652 -0.882,0.648 -0.92,0.686 -0.918,0.691 -0.881,0.65 -0.846,0.574 -0.766,0.535 -0.689,0.422 -0.537,0.305 -0.382,0.191 z"
             id="path18-0"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 16.822,49.066 0.612,0.613 0.806,0.266 0.996,0.002 1.11,-0.266 1.227,-0.461 1.262,-0.646 1.341,-0.768 1.305,-0.84 1.302,-0.92 1.227,-0.916 1.147,-0.879 0.999,-0.844 0.881,-0.688 0.65,-0.574 0.423,-0.381 0.192,-0.154 -0.498,0.039 -0.538,0.035 -0.574,0.037 -0.572,0.041 -0.614,0.072 -0.614,0.039 -0.611,0.041 -0.652,0.037 -0.688,0.42 -0.688,0.422 -0.693,0.455 -0.649,0.426 -0.689,0.455 -0.653,0.498 -0.688,0.459 -0.653,0.459 -0.69,0.496 -0.65,0.461 -0.688,0.459 -0.651,0.459 -0.688,0.42 -0.691,0.422 -0.651,0.42 -0.69,0.383 z"
             id="path20-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 12.993,49.14 0.652,0.229 0.649,0.115 0.65,0.037 0.653,-0.109 0.65,-0.195 0.689,-0.264 0.727,-0.383 0.768,-0.461 0.843,-0.535 0.881,-0.611 0.959,-0.688 1.072,-0.729 1.187,-0.803 1.265,-0.881 1.379,-0.918 1.534,-0.957 -0.653,0.039 -0.727,0.039 h -0.65 l -0.65,0.037 -0.574,0.037 -0.459,0.039 -0.307,0.039 -0.116,0.035 -0.077,0.115 -0.229,0.23 -0.346,0.307 -0.458,0.42 -0.574,0.496 -0.654,0.58 -0.689,0.57 -0.805,0.613 -0.805,0.611 -0.843,0.613 -0.843,0.533 -0.882,0.537 -0.842,0.457 -0.842,0.383 -0.805,0.268 -0.729,0.154 z"
             id="path22-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 10.198,48.716 0.879,0.344 0.958,0.152 0.998,-0.072 1.033,-0.268 1.072,-0.383 1.033,-0.498 1.074,-0.607 0.996,-0.691 0.958,-0.688 0.92,-0.729 0.843,-0.688 0.728,-0.691 0.653,-0.572 0.495,-0.498 0.383,-0.342 0.232,-0.232 -0.613,0.039 -0.577,0.039 -0.571,0.037 -0.575,0.074 -0.535,0.041 -0.577,0.037 -0.61,0.074 -0.613,0.039 -0.459,0.42 -0.501,0.42 -0.458,0.422 -0.499,0.459 -0.498,0.498 -0.497,0.459 -0.536,0.459 -0.538,0.459 -0.536,0.422 -0.534,0.422 -0.577,0.381 -0.534,0.342 -0.614,0.309 -0.574,0.266 -0.613,0.193 -0.613,0.152 z"
             id="path24-6"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 6.831,47.642 0.765,0.535 0.763,0.346 0.767,0.154 0.767,0.039 0.768,-0.152 0.766,-0.232 0.766,-0.342 0.765,-0.459 0.729,-0.498 0.766,-0.611 0.729,-0.613 0.729,-0.65 0.727,-0.648 0.69,-0.689 0.689,-0.65 0.69,-0.615 -0.422,0.041 -0.46,0.076 -0.497,0.037 -0.535,0.039 -0.575,0.074 -0.612,0.039 -0.652,0.074 -0.612,0.037 -0.192,0.461 -0.267,0.459 -0.271,0.422 -0.346,0.422 -0.381,0.383 -0.424,0.383 -0.42,0.381 -0.496,0.307 -0.5,0.307 -0.537,0.268 -0.573,0.268 -0.576,0.191 -0.612,0.154 -0.61,0.15 -0.657,0.073 -0.649,0.039 z"
             id="path26-3"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 3.803,47.066 0.652,0.266 0.69,0.193 0.726,0.115 0.806,0.002 0.767,-0.039 0.842,-0.115 0.805,-0.229 0.803,-0.229 0.768,-0.344 0.729,-0.383 0.65,-0.422 0.614,-0.494 0.536,-0.539 0.46,-0.572 0.345,-0.65 0.23,-0.652 -0.46,0.039 -0.46,0.037 -0.497,0.076 -0.5,0.039 -0.495,0.037 -0.537,0.037 -0.574,0.039 -0.652,0.037 L 9.78,43.699 9.473,44.084 9.167,44.428 8.861,44.735 8.554,45.04 8.206,45.269 7.863,45.539 7.516,45.768 7.135,45.959 6.713,46.15 6.292,46.339 5.833,46.493 5.371,46.645 4.876,46.797 4.339,46.912 3.8,47.066 z"
             id="path28-6"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 2.233,46.529 0.23,0.229 0.347,0.152 0.42,0.078 H 3.69 L 4.226,46.951 4.8,46.837 5.413,46.644 6.025,46.455 6.638,46.185 7.252,45.878 7.864,45.536 8.401,45.151 8.938,44.731 9.396,44.272 9.741,43.813 10.048,43.315 9.705,43.356 9.397,43.393 9.014,43.43 8.67,43.468 8.326,43.507 8.02,43.544 H 7.752 7.483 v 0.152 l -0.343,0.305 -0.576,0.422 -0.767,0.498 -0.917,0.496 -0.922,0.5 -0.919,0.381 -0.806,0.23 z"
             id="path30-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 1.124,45.455 0.078,0.535 0.192,0.344 0.305,0.156 0.42,0.076 0.499,-0.076 0.574,-0.191 0.573,-0.229 0.614,-0.307 0.613,-0.346 0.574,-0.381 0.575,-0.381 0.461,-0.346 0.42,-0.307 0.307,-0.23 0.191,-0.152 0.038,-0.076 -2.986,0.342 -0.229,0.152 -0.384,0.192 -0.458,0.23 -0.5,0.229 -0.535,0.27 -0.497,0.189 -0.461,0.191 -0.384,0.115 z"
             id="path32-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="M 4.573,43.886 3.922,43.925 3.348,43.964 2.812,44 l -0.498,0.037 -0.46,0.041 -0.497,0.035 -0.498,0.078 -0.577,0.113 0.117,0.729 0.343,0.346 H 1.279 L 1.968,45.19 2.657,44.842 3.386,44.461 4.037,44.115 4.573,43.886 z"
             id="path34-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 4.459,43.505 -0.653,0.113 -0.573,0.076 -0.497,0.113 -0.5,0.076 -0.458,0.113 -0.459,0.115 -0.538,0.119 -0.574,0.152 -0.038,-0.844 0.345,-0.535 0.537,-0.193 0.727,-0.033 0.766,0.15 0.766,0.193 0.651,0.23 0.499,0.154 z"
             id="path36-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 44.298,27.949 1.684,-0.651 1.611,-0.419 1.491,-0.113 1.417,0.076 1.379,0.309 1.262,0.459 1.227,0.652 1.187,0.729 1.149,0.845 1.11,0.919 1.106,0.959 1.074,0.996 1.071,0.957 1.07,0.921 1.073,0.882 1.109,0.807 -0.384,0.073 -0.421,0.038 -0.421,0.039 -0.383,0.076 -0.423,0.039 -0.421,0.038 -0.459,0.036 -0.421,0.039 -0.422,0.035 -0.461,0.041 -0.458,0.076 -0.422,0.037 -0.461,0.04 -0.457,0.074 -0.498,0.037 -0.461,0.077 -0.382,-0.534 -0.495,-0.653 -0.576,-0.766 -0.688,-0.768 -0.727,-0.843 -0.805,-0.843 -0.879,-0.844 -0.881,-0.806 -0.959,-0.766 -0.953,-0.688 -0.957,-0.615 -0.997,-0.497 -0.957,-0.385 -0.958,-0.23 -0.956,-0.039 -0.88,0.152 z"
             id="path38-6"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 41.423,28.597 0.96,-0.345 0.92,-0.227 0.878,-0.152 0.923,-0.077 0.878,0.077 0.919,0.192 0.88,0.268 0.919,0.423 0.956,0.537 0.959,0.691 0.995,0.803 1.033,0.96 1.108,1.11 1.11,1.266 1.186,1.418 1.264,1.57 -0.69,0.039 -0.611,0.072 -0.576,0.039 -0.534,0.076 -0.537,0.076 -0.573,0.076 -0.653,0.113 -0.765,0.117 -0.689,-0.574 -0.65,-0.613 -0.689,-0.653 -0.612,-0.653 -0.649,-0.649 -0.649,-0.65 -0.613,-0.653 -0.651,-0.651 -0.651,-0.612 -0.688,-0.574 -0.651,-0.576 -0.688,-0.574 -0.727,-0.498 -0.767,-0.423 -0.766,-0.421 -0.805,-0.347 z"
             id="path40-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 38.207,29.438 0.727,-0.611 0.808,-0.307 0.88,-0.074 0.879,0.191 0.958,0.383 0.956,0.538 0.995,0.688 0.996,0.805 0.996,0.881 0.993,0.921 0.956,0.921 0.92,0.958 0.841,0.88 0.84,0.805 0.729,0.691 0.69,0.574 -4.176,0.496 L 47.659,37.565 47.123,36.95 46.625,36.337 46.092,35.726 45.555,35.113 45.021,34.462 44.448,33.848 43.913,33.272 43.3,32.698 42.688,32.125 42.036,31.587 41.348,31.089 40.62,30.592 39.854,30.169 39.05,29.786 38.207,29.44 z"
             id="path42-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 31.926,32.113 1.148,-1.111 1.111,-0.802 1.073,-0.534 1.072,-0.307 1.072,-0.037 1.034,0.154 1.033,0.385 0.996,0.498 0.994,0.689 0.955,0.804 0.996,0.921 0.919,0.996 0.957,1.035 0.917,1.111 0.918,1.111 0.919,1.11 -0.729,0.04 -0.611,0.035 -0.498,0.039 -0.461,0.076 -0.458,0.076 -0.499,0.075 -0.571,0.078 -0.692,0.112 -0.803,-1.034 -0.766,-0.919 -0.803,-0.844 -0.766,-0.728 -0.802,-0.612 -0.766,-0.538 -0.728,-0.461 -0.768,-0.382 -0.728,-0.309 -0.688,-0.229 -0.728,-0.192 -0.689,-0.152 -0.648,-0.08 -0.653,-0.074 h -0.649 l -0.612,-0.002 z"
             id="path44-5"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 27.442,33.145 1.267,-0.461 1.187,-0.344 1.187,-0.189 1.109,-0.077 1.111,0.001 1.071,0.155 1.035,0.231 0.996,0.347 0.995,0.419 0.919,0.537 0.957,0.613 0.878,0.689 0.882,0.768 0.84,0.842 0.806,0.922 0.803,0.996 -0.803,0.115 -0.919,0.111 -0.921,0.115 -0.921,0.115 -0.842,0.113 -0.649,0.078 -0.499,0.037 -0.191,-0.002 -0.075,-0.075 -0.192,-0.153 -0.269,-0.268 -0.343,-0.346 -0.423,-0.42 -0.495,-0.424 -0.575,-0.496 -0.65,-0.538 -0.728,-0.499 -0.765,-0.536 -0.844,-0.5 -0.918,-0.495 -0.92,-0.424 -0.993,-0.383 -1.034,-0.348 -1.073,-0.229 z"
             id="path46-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 21.775,33.828 1.034,-0.418 1.035,-0.307 1.108,-0.115 1.073,10e-4 1.111,0.118 1.108,0.229 1.072,0.346 1.111,0.422 1.033,0.498 1.033,0.537 0.995,0.651 0.994,0.651 0.882,0.693 0.881,0.727 0.802,0.728 0.726,0.729 -0.495,0.037 -0.612,0.076 -0.689,0.075 -0.728,0.077 -0.729,0.075 -0.652,0.076 -0.573,0.037 h -0.422 l -10e-4,-0.077 -0.191,-0.191 -0.38,-0.268 -0.574,-0.385 -0.689,-0.42 -0.805,-0.5 -0.919,-0.537 -0.956,-0.533 -0.955,-0.54 -0.996,-0.538 -0.998,-0.496 -0.916,-0.457 -0.846,-0.387 -0.762,-0.307 -0.616,-0.193 -0.495,-0.115 z"
             id="path48-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 16.413,34.936 0.537,-0.842 0.805,-0.498 0.996,-0.188 h 1.147 l 1.264,0.268 1.379,0.422 1.455,0.576 1.415,0.651 1.455,0.729 1.339,0.766 1.265,0.73 1.149,0.727 0.954,0.615 0.729,0.459 0.496,0.342 0.23,0.117 -0.537,0.116 -0.61,0.077 -0.653,0.073 -0.689,0.038 -0.727,0.078 -0.729,0.074 -0.688,0.115 -0.689,0.115 -0.729,-0.345 -0.688,-0.348 -0.729,-0.381 -0.688,-0.385 -0.69,-0.346 -0.688,-0.383 -0.728,-0.384 -0.688,-0.382 -0.689,-0.35 L 20.701,36.81 19.972,36.467 19.284,36.16 18.595,35.812 17.868,35.507 17.141,35.196 16.412,34.93 z"
             id="path50-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 9.558,36.768 0.844,-0.611 0.956,-0.346 0.996,-0.149 1.07,10e-4 1.113,0.189 1.148,0.348 1.11,0.421 1.108,0.5 1.035,0.574 1.032,0.575 0.919,0.614 0.804,0.536 0.727,0.499 0.574,0.459 0.42,0.307 0.229,0.193 -0.612,0.074 -0.574,0.076 -0.495,0.076 -0.501,0.037 -0.536,0.037 -0.496,0.076 -0.576,0.076 -0.61,0.074 L 18.706,41.062 18.17,40.714 17.596,40.295 17.022,39.912 16.411,39.49 15.798,39.069 15.186,38.646 14.574,38.263 13.96,37.879 13.313,37.571 12.661,37.266 12.048,37.034 11.4,36.845 10.785,36.728 H 10.17 l -0.612,0.037 z"
             id="path52-31"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 12.084,35.661 0.653,-0.423 0.688,-0.305 0.652,-0.154 0.688,-0.074 0.689,0.037 0.728,0.152 0.807,0.27 0.838,0.308 0.921,0.423 0.959,0.459 1.07,0.576 1.147,0.614 1.265,0.65 1.378,0.692 1.49,0.765 1.648,0.768 -0.613,0.039 -0.689,0.074 -0.688,0.078 -0.691,0.111 -0.614,0.079 -0.457,0.078 -0.346,0.035 -0.153,-0.035 -0.075,-0.078 -0.27,-0.191 -0.345,-0.308 -0.459,-0.344 -0.573,-0.422 -0.689,-0.459 -0.729,-0.5 -0.803,-0.499 -0.879,-0.498 -0.882,-0.497 -0.955,-0.425 -0.957,-0.384 -0.958,-0.303 -0.957,-0.196 -0.92,-0.111 -0.919,-10e-4 z"
             id="path54-9"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 6.491,38.719 0.691,-0.766 0.726,-0.574 0.729,-0.382 0.766,-0.229 0.767,-0.037 0.804,0.076 0.844,0.192 0.804,0.271 0.84,0.422 0.805,0.42 0.842,0.536 0.843,0.539 0.843,0.536 0.803,0.574 0.805,0.578 0.803,0.496 -0.459,0.076 -0.498,0.039 -0.574,0.115 -0.613,0.072 -0.649,0.08 -0.69,0.072 -0.65,0.078 -0.653,0.076 -0.229,-0.498 -0.269,-0.422 -0.305,-0.422 -0.384,-0.382 -0.383,-0.344 -0.419,-0.27 -0.5,-0.271 L 11.434,39.141 10.898,38.95 10.326,38.796 9.75,38.682 9.138,38.603 8.488,38.566 7.836,38.567 7.186,38.64 6.497,38.718 z"
             id="path56-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 1.778,41.242 0.193,-0.307 0.306,-0.268 0.422,-0.227 0.459,-0.155 0.536,-0.114 0.612,-0.036 0.613,0.001 0.689,0.037 0.65,0.114 0.689,0.155 0.652,0.229 0.61,0.27 0.576,0.307 0.534,0.383 0.422,0.422 0.381,0.461 L 9.779,42.59 9.36,42.666 8.94,42.742 8.517,42.816 8.135,42.853 7.827,42.894 H 7.6 7.522 L 7.369,42.816 6.988,42.586 6.336,42.279 5.57,41.937 4.689,41.628 3.694,41.358 2.737,41.204 1.778,41.241 z"
             id="path58-85"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 0.858,42.81 -0.036,-0.609 0.152,-0.461 0.271,-0.307 0.42,-0.191 0.497,-0.078 0.575,0.041 0.613,0.076 0.688,0.154 0.65,0.23 0.65,0.23 0.613,0.23 0.535,0.23 0.46,0.23 0.383,0.154 0.191,0.152 0.078,0.037 L 4.533,43.461 4.263,43.348 3.843,43.231 3.384,43.079 2.85,42.927 2.314,42.812 1.779,42.738 1.28,42.736 0.858,42.81 z"
             id="path60-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 3.389,40.248 0.612,-0.498 0.651,-0.383 0.729,-0.342 0.805,-0.231 0.806,-0.153 0.803,-0.11 0.844,10e-4 0.841,0.072 0.804,0.156 0.804,0.27 0.729,0.307 0.689,0.383 0.649,0.461 0.536,0.535 0.421,0.613 0.344,0.689 -0.499,0.039 -0.457,0.078 -0.5,0.035 -0.536,0.076 -0.535,0.078 -0.574,0.037 -0.612,0.115 -0.65,0.072 L 9.862,42.208 9.591,41.9 9.284,41.632 8.941,41.362 8.558,41.132 8.137,40.902 7.715,40.71 7.256,40.558 6.797,40.404 6.3,40.289 5.84,40.213 5.341,40.173 4.844,40.136 4.348,40.135 3.849,40.173 3.389,40.248 z"
             id="path62-6"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 139.729,21.932 0.077,0.117 0.192,0.307 0.267,0.497 0.344,0.613 0.386,0.727 0.382,0.806 0.346,0.92 0.303,0.918 0.228,0.959 0.079,0.92 -0.041,0.918 -0.192,0.842 -0.422,0.768 -0.651,0.687 -0.919,0.535 -1.189,0.384 0.193,-0.578 0.117,-0.611 0.113,-0.611 0.076,-0.689 0.039,-0.689 v -0.726 l -0.037,-0.69 -0.037,-0.729 -0.076,-0.729 -0.074,-0.725 -0.116,-0.69 -0.152,-0.651 -0.113,-0.651 -0.154,-0.575 -0.188,-0.574 -0.155,-0.498 0.191,-0.075 0.154,-0.04 0.19,-0.076 0.156,-0.036 0.153,-0.077 0.15,-0.039 0.191,-0.078 0.19,-0.076 z"
             id="path64-3"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 138.429,22.468 0.534,2.108 0.382,1.914 0.189,1.646 0.037,1.455 -0.077,1.264 -0.23,1.072 -0.307,0.92 -0.347,0.764 -0.46,0.613 -0.497,0.496 -0.498,0.347 -0.495,0.267 -0.54,0.191 -0.459,0.076 -0.42,0.037 h -0.384 l 0.229,-0.613 0.229,-0.612 0.192,-0.688 0.154,-0.689 0.152,-0.767 0.118,-0.764 0.116,-0.767 0.075,-0.803 0.041,-0.806 10e-4,-0.843 -0.041,-0.804 -0.073,-0.843 -0.114,-0.804 -0.155,-0.843 -0.188,-0.766 -0.229,-0.805 0.457,-0.154 0.463,-0.152 0.422,-0.152 0.418,-0.115 0.348,-0.113 0.381,-0.115 0.306,-0.076 0.27,-0.077 z"
             id="path66-49"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 135.325,23.424 0.231,0.765 0.227,0.959 0.155,1.073 0.072,1.186 0.041,1.303 -0.002,1.301 -0.116,1.301 -0.192,1.267 -0.271,1.187 -0.345,1.109 -0.499,0.957 -0.572,0.766 -0.731,0.574 -0.84,0.304 -0.96,0.04 -1.108,-0.307 0.422,-0.691 0.421,-0.727 0.347,-0.766 0.307,-0.727 0.229,-0.803 0.231,-0.768 0.152,-0.805 0.154,-0.805 0.077,-0.804 0.038,-0.841 v -0.805 l -0.073,-0.842 -0.076,-0.842 -0.152,-0.806 -0.152,-0.845 -0.229,-0.803 0.383,-0.152 0.458,-0.152 0.461,-0.153 0.46,-0.153 0.46,-0.151 0.382,-0.153 0.346,-0.117 0.267,-0.074 z"
             id="path68-3"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 125.586,39.307 1.036,0.08 0.997,-0.154 0.879,-0.381 0.805,-0.535 0.766,-0.73 0.652,-0.879 0.536,-0.994 0.499,-1.109 0.384,-1.188 0.309,-1.266 0.192,-1.3 0.078,-1.302 0.001,-1.301 -0.114,-1.303 -0.229,-1.265 -0.343,-1.188 -0.422,0.152 -0.425,0.154 -0.456,0.114 -0.463,0.152 -0.458,0.154 -0.497,0.153 -0.46,0.152 -0.497,0.152 v 0.804 l -0.001,0.879 -0.04,0.999 -0.039,1.033 -0.039,1.033 -0.038,1.072 -0.116,1.11 -0.113,1.032 -0.156,1.035 -0.152,0.957 -0.233,0.919 -0.268,0.806 -0.308,0.687 -0.384,0.577 -0.421,0.419 -0.461,0.267 z"
             id="path70-4"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 128.317,25.715 -0.384,0.153 -0.383,0.114 -0.343,0.115 -0.386,0.077 -0.382,0.114 -0.347,0.113 -0.384,0.116 -0.38,0.153 -0.077,0.766 -0.041,0.84 -0.039,0.92 -0.038,0.958 -10e-4,0.958 -0.001,1.031 -0.04,1.037 -0.039,0.994 -0.076,0.997 -0.115,0.994 -0.193,0.919 -0.191,0.844 -0.305,0.802 -0.346,0.727 -0.422,0.616 -0.536,0.496 1.108,-0.267 0.919,-0.383 0.767,-0.533 0.651,-0.614 0.537,-0.729 0.423,-0.839 0.306,-0.919 0.232,-0.959 0.156,-1.072 0.112,-1.11 0.039,-1.15 0.042,-1.225 0.037,-1.225 0.039,-1.264 0.001,-1.264 0.078,-1.303 z"
             id="path72-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 118.156,42.058 1.531,-0.074 1.304,-0.305 1.07,-0.496 0.882,-0.652 0.689,-0.841 0.502,-0.958 0.419,-1.071 0.27,-1.188 0.154,-1.226 0.114,-1.261 0.041,-1.305 10e-4,-1.262 0.001,-1.305 0.001,-1.223 0.076,-1.15 0.078,-1.071 -0.421,0.114 -0.383,0.113 -0.343,0.117 -0.387,0.113 -0.382,0.113 -0.343,0.115 -0.384,0.077 -0.423,0.114 0.039,0.113 0.075,0.269 0.078,0.423 0.114,0.537 0.074,0.688 0.078,0.768 0.039,0.881 -0.04,0.996 -0.114,1.035 -0.195,1.145 -0.347,1.189 -0.42,1.225 -0.614,1.265 -0.766,1.339 -0.921,1.3 -1.15,1.338 z"
             id="path74-3"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 112.945,43.703 1.035,0.191 1.035,-0.074 0.995,-0.346 0.996,-0.537 0.956,-0.725 0.92,-0.881 0.844,-1.07 0.769,-1.188 0.649,-1.265 0.576,-1.378 0.462,-1.456 0.309,-1.489 0.192,-1.496 0.041,-1.531 -0.152,-1.454 -0.308,-1.456 -3.638,1.146 0.037,0.613 0.037,0.729 -0.038,0.801 -0.08,0.92 -0.112,0.958 -0.192,1.034 -0.192,1.072 -0.308,1.109 -0.347,1.109 -0.421,1.073 -0.461,1.071 -0.575,1.035 -0.612,0.996 -0.729,0.918 -0.805,0.842 -0.883,0.727 z"
             id="path76-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 118.702,28.619 -0.573,0.189 -0.729,0.192 -0.807,0.268 -0.84,0.229 -0.806,0.27 -0.804,0.227 -0.689,0.191 -0.537,0.115 -0.076,0.881 -0.042,0.955 -0.075,0.959 -0.038,0.995 -0.117,0.995 -0.077,1.037 -0.115,0.994 -0.153,0.996 -0.19,0.956 -0.232,0.921 -0.309,0.916 -0.344,0.842 -0.422,0.807 -0.498,0.688 -0.536,0.65 -0.65,0.576 0.766,0.115 0.803,-0.039 0.804,-0.189 0.805,-0.344 0.804,-0.5 0.807,-0.611 0.768,-0.764 0.766,-0.957 0.689,-1.035 0.611,-1.227 0.578,-1.339 0.495,-1.528 0.388,-1.65 0.307,-1.758 0.194,-1.955 0.077,-2.066 z"
             id="path78-4"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 104.021,45.226 1.725,0.08 1.455,-0.154 1.265,-0.418 0.998,-0.652 0.841,-0.803 0.691,-0.957 0.497,-1.072 0.386,-1.224 0.308,-1.225 0.19,-1.343 0.116,-1.3 0.117,-1.302 0.038,-1.303 0.078,-1.188 0.075,-1.11 0.117,-0.995 -0.535,0.114 -0.463,0.115 -0.419,0.153 -0.418,0.112 -0.463,0.117 -0.422,0.111 -0.496,0.154 -0.576,0.151 -0.116,1.038 -0.112,0.992 -0.116,0.996 -0.156,0.955 -0.116,0.961 -0.153,0.918 -0.189,0.879 -0.194,0.881 -0.269,0.844 -0.308,0.841 -0.382,0.805 -0.422,0.805 -0.536,0.801 -0.576,0.768 -0.691,0.729 -0.77,0.727 z"
             id="path80-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 99.389,46.066 1.532,0.078 1.34,-0.193 1.188,-0.418 1.036,-0.65 0.88,-0.805 0.766,-0.957 0.615,-1.107 0.537,-1.188 0.458,-1.226 0.347,-1.3 0.269,-1.266 0.194,-1.299 0.19,-1.226 0.116,-1.15 0.116,-1.073 0.079,-0.919 -0.539,0.117 -0.459,0.112 -0.42,0.115 -0.423,0.077 -0.38,0.113 -0.425,0.074 -0.495,0.152 -0.576,0.115 -0.192,1.496 -0.229,1.417 -0.27,1.301 -0.269,1.226 -0.31,1.109 -0.345,1.071 -0.383,0.918 -0.384,0.883 -0.383,0.803 -0.425,0.727 -0.459,0.613 -0.422,0.574 -0.459,0.535 -0.461,0.42 -0.498,0.383 -0.459,0.346 z"
             id="path82-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 95.021,46.636 1.457,0.078 1.302,-0.189 1.151,-0.424 1.071,-0.611 0.881,-0.801 0.805,-0.92 0.69,-1.072 0.614,-1.145 0.535,-1.189 0.422,-1.263 0.347,-1.264 0.308,-1.262 0.271,-1.188 0.192,-1.149 0.152,-1.031 0.155,-0.922 -0.459,0.076 -0.46,0.116 -0.462,0.114 -0.459,0.115 -0.462,0.115 -0.458,0.112 -0.46,0.114 -0.497,0.117 -0.038,0.725 -0.116,0.805 -0.153,0.843 -0.269,0.918 -0.27,0.995 -0.382,0.957 -0.385,1.033 -0.422,0.998 -0.499,0.996 -0.537,0.957 -0.534,0.879 -0.577,0.84 -0.574,0.807 -0.614,0.689 -0.649,0.572 -0.617,0.459 z"
             id="path84-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 90.237,47.513 1.49,0.193 1.38,-0.191 1.264,-0.496 1.15,-0.766 1.073,-0.955 0.921,-1.148 0.84,-1.301 0.77,-1.34 0.613,-1.416 0.537,-1.381 0.46,-1.302 0.384,-1.262 0.23,-1.074 0.192,-0.88 0.114,-0.65 0.001,-0.381 -0.573,0.111 -0.537,0.115 -0.535,0.152 -0.536,0.115 -0.536,0.152 -0.5,0.113 -0.497,0.115 -0.499,0.078 -0.191,0.651 -0.19,0.765 -0.229,0.879 -0.271,0.996 -0.308,1.035 -0.343,1.071 -0.384,1.069 -0.424,1.115 -0.461,1.07 -0.497,0.994 -0.537,0.959 -0.574,0.842 -0.653,0.725 -0.65,0.574 -0.728,0.422 -0.765,0.229 z"
             id="path86-3"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 86.752,47.32 1.377,0.307 1.223,0.002 1.113,-0.268 1.034,-0.535 0.882,-0.729 0.805,-0.881 0.727,-1.068 0.652,-1.15 0.539,-1.225 0.498,-1.262 0.384,-1.264 0.385,-1.227 0.307,-1.147 0.231,-1.035 0.23,-0.918 0.189,-0.727 -0.419,0.076 -0.423,0.038 -0.38,0.075 -0.347,0.076 -0.384,0.076 -0.346,0.078 -0.305,0.074 -0.345,0.041 -0.118,0.879 -0.189,0.919 -0.232,0.917 -0.228,0.883 -0.309,0.918 -0.347,0.881 -0.382,0.843 -0.461,0.842 -0.46,0.842 -0.537,0.805 -0.615,0.764 -0.61,0.689 -0.729,0.689 -0.727,0.611 -0.806,0.574 -0.879,0.535 z"
             id="path88-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 82.385,48.005 1.147,0.002 1.112,-0.115 1.07,-0.268 1.037,-0.383 0.956,-0.533 0.959,-0.65 0.842,-0.764 0.841,-0.842 0.73,-0.959 0.69,-1.033 0.614,-1.15 0.573,-1.185 0.461,-1.264 0.385,-1.34 0.347,-1.379 0.23,-1.414 -0.498,0.113 -0.499,0.076 -0.536,0.115 -0.496,0.074 -0.497,0.078 -0.459,0.112 -0.5,0.077 -0.459,0.115 -0.231,0.805 -0.191,0.842 -0.231,0.805 -0.194,0.803 -0.23,0.804 -0.228,0.803 -0.307,0.766 -0.346,0.805 -0.42,0.766 -0.463,0.803 -0.576,0.766 -0.688,0.766 -0.768,0.729 -0.918,0.766 -1.073,0.766 -1.188,0.725 z"
             id="path90-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 76.18,48.728 1.495,0.117 1.454,-0.076 1.34,-0.229 1.266,-0.383 1.187,-0.496 1.112,-0.65 1.033,-0.768 0.918,-0.916 0.844,-0.955 0.767,-1.074 0.693,-1.148 0.573,-1.221 0.496,-1.304 0.425,-1.34 0.307,-1.377 0.233,-1.381 -0.423,0.076 -0.46,0.117 -0.456,0.074 -0.461,0.075 -0.459,0.078 -0.5,0.114 -0.497,0.076 -0.5,0.115 -0.152,0.955 -0.23,0.957 -0.31,0.96 -0.383,0.917 -0.457,0.917 -0.502,0.918 -0.574,0.883 -0.648,0.842 -0.691,0.844 -0.767,0.762 -0.808,0.727 -0.879,0.689 -0.921,0.611 -0.995,0.576 -0.997,0.496 -1.072,0.42 z"
             id="path92-0"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 72.772,49.107 1.264,-0.074 1.226,-0.189 1.228,-0.307 1.186,-0.457 1.112,-0.537 1.109,-0.648 1.034,-0.729 0.958,-0.842 0.881,-0.916 0.843,-0.994 0.73,-1.076 0.65,-1.109 0.536,-1.183 0.46,-1.226 0.348,-1.267 0.229,-1.299 -0.419,0.074 -0.385,0.037 -0.346,0.039 -0.343,0.039 -0.346,0.037 -0.382,0.077 -0.458,0.075 -0.539,0.075 -0.537,1.112 -0.459,1.031 -0.46,0.997 -0.422,0.918 -0.46,0.881 -0.424,0.805 -0.461,0.764 -0.498,0.727 -0.537,0.729 -0.613,0.65 -0.688,0.689 -0.765,0.611 -0.884,0.65 -0.996,0.611 -1.108,0.613 -1.265,0.609 z"
             id="path94-54"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 66.645,49.488 1.877,0.076 1.763,-0.072 1.57,-0.268 1.455,-0.422 1.34,-0.572 1.187,-0.691 1.113,-0.801 0.993,-0.92 0.921,-0.992 0.844,-1.072 0.729,-1.109 0.688,-1.189 0.652,-1.184 0.577,-1.187 0.538,-1.227 0.496,-1.187 -0.343,0.036 -0.461,0.078 -0.573,0.076 -0.575,0.076 -0.613,0.115 -0.537,0.076 -0.456,0.076 -0.347,0.035 -0.46,1.074 -0.499,1.074 -0.577,0.994 -0.573,0.955 -0.652,0.881 -0.688,0.879 -0.729,0.805 -0.804,0.807 -0.804,0.727 -0.885,0.688 -0.917,0.688 -0.96,0.613 -0.995,0.572 -1.072,0.535 -1.072,0.496 -1.149,0.461 z"
             id="path96-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 63.006,50.019 1.034,-0.037 1.071,-0.152 1.15,-0.268 1.186,-0.42 1.188,-0.494 1.189,-0.613 1.188,-0.727 1.187,-0.803 1.149,-0.918 1.111,-0.957 1.035,-1.07 0.999,-1.15 0.879,-1.188 0.804,-1.261 0.691,-1.34 0.576,-1.38 -0.575,0.079 -0.575,0.074 -0.611,0.037 -0.612,0.077 -0.536,0.037 -0.461,0.077 -0.382,0.076 -0.192,0.115 -0.69,0.535 -0.689,0.575 -0.729,0.688 -0.729,0.688 -0.727,0.765 -0.767,0.803 -0.767,0.844 -0.768,0.844 -0.766,0.879 -0.804,0.842 -0.805,0.842 -0.845,0.84 -0.842,0.844 -0.845,0.762 -0.842,0.768 -0.882,0.688 z"
             id="path98-0"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 57.415,50.015 0.997,0.654 1.032,0.268 1.034,0.002 1.073,-0.268 1.071,-0.537 1.073,-0.729 1.111,-0.916 1.11,-1.033 1.112,-1.188 1.148,-1.225 1.189,-1.301 1.188,-1.299 1.188,-1.264 1.226,-1.263 1.228,-1.148 1.226,-1.031 h -0.425 l -0.494,0.074 -0.576,0.038 -0.573,0.116 -0.614,0.076 -0.612,0.113 -0.572,0.115 -0.5,0.075 -0.956,0.88 -0.957,0.88 -0.923,0.918 -0.919,0.92 -0.881,0.916 -0.883,0.92 -0.88,0.92 -0.845,0.84 -0.844,0.84 -0.842,0.768 -0.805,0.688 -0.804,0.613 -0.805,0.535 -0.767,0.459 -0.766,0.344 -0.767,0.229 z"
             id="path100-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 53.086,50.511 1.572,0.002 1.492,-0.152 1.342,-0.385 1.304,-0.494 1.187,-0.613 1.109,-0.766 1.075,-0.84 0.995,-0.92 0.997,-0.994 0.956,-1.033 0.921,-1.035 0.959,-1.07 0.959,-1.07 0.994,-1.034 1.035,-0.957 1.072,-0.918 -0.382,0.04 -0.458,0.037 -0.577,0.074 -0.572,0.041 -0.577,0.073 -0.459,0.038 -0.382,0.041 -0.229,-10e-4 -0.651,0.151 -0.651,0.306 -0.649,0.423 -0.692,0.573 -0.689,0.686 -0.729,0.805 -0.766,0.844 -0.769,0.916 -0.88,0.957 -0.883,0.955 -0.997,0.996 -1.032,0.959 -1.111,0.955 -1.188,0.881 -1.264,0.801 -1.381,0.729 z"
             id="path102-4"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 138.314,18.982 v -0.153 l 0.04,-0.42 0.038,-0.649 0.04,-0.807 0.039,-0.957 -0.037,-1.033 -0.038,-1.072 -0.111,-1.111 -0.229,-1.033 -0.309,-0.996 -0.38,-0.882 -0.572,-0.728 -0.654,-0.537 -0.843,-0.307 -1.034,-0.039 -1.186,0.306 0.385,0.384 0.343,0.459 0.345,0.574 0.306,0.613 0.305,0.689 0.27,0.689 0.264,0.767 0.271,0.804 0.228,0.767 0.19,0.806 0.194,0.803 0.188,0.766 0.155,0.768 0.152,0.727 0.114,0.65 0.113,0.613 0.19,-0.037 0.154,-0.037 0.189,-0.078 0.155,-0.037 0.151,-0.079 0.155,-0.075 0.192,-0.037 0.226,-0.078 z"
             id="path104-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 136.9,19.558 -0.497,-2.489 -0.535,-2.108 -0.535,-1.801 -0.532,-1.492 -0.539,-1.188 -0.534,-0.958 -0.533,-0.689 -0.499,-0.497 -0.536,-0.347 -0.458,-0.153 -0.502,-0.039 -0.42,0.078 -0.419,0.152 -0.382,0.191 -0.348,0.229 -0.306,0.23 0.536,0.497 0.533,0.573 0.462,0.538 0.494,0.611 0.424,0.615 0.422,0.648 0.382,0.652 0.344,0.691 0.344,0.727 0.306,0.766 0.307,0.768 0.268,0.805 0.227,0.842 0.23,0.842 0.227,0.882 0.194,0.919 0.457,-0.077 0.345,-0.036 0.232,-0.077 0.153,-0.077 0.151,-0.037 0.156,-0.076 0.153,-0.039 0.229,-0.075 z"
             id="path106-0"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 134.984,20.283 -0.113,-0.918 -0.194,-1.035 -0.305,-1.15 -0.379,-1.226 -0.5,-1.264 -0.571,-1.227 -0.611,-1.187 -0.688,-1.111 -0.729,-0.996 -0.765,-0.843 -0.803,-0.65 -0.842,-0.425 -0.881,-0.151 -0.882,0.152 -0.842,0.499 -0.882,0.878 0.688,0.498 0.65,0.576 0.613,0.574 0.574,0.576 0.574,0.611 0.496,0.689 0.459,0.691 0.42,0.688 0.423,0.769 0.343,0.767 0.345,0.805 0.267,0.842 0.267,0.879 0.193,0.92 0.189,0.959 0.155,0.994 0.416,-0.114 0.461,-0.152 0.499,-0.153 0.498,-0.191 0.461,-0.189 0.421,-0.154 0.344,-0.151 0.23,-0.077 z"
             id="path108-60"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 120.057,10.239 0.919,-0.612 0.92,-0.344 0.957,-0.115 0.919,0.115 0.958,0.307 0.919,0.5 0.882,0.689 0.843,0.805 0.762,0.919 0.766,1.073 0.65,1.188 0.572,1.226 0.496,1.305 0.384,1.376 0.306,1.38 0.151,1.416 -0.461,0.114 -0.459,0.116 -0.46,0.15 -0.46,0.154 -0.497,0.191 -0.499,0.113 -0.457,0.154 -0.498,0.075 -0.346,-0.88 -0.305,-0.959 -0.383,-0.957 -0.348,-0.957 -0.379,-0.996 -0.419,-0.998 -0.423,-0.956 -0.421,-0.918 -0.456,-0.884 -0.499,-0.805 -0.533,-0.766 -0.539,-0.651 -0.609,-0.575 -0.615,-0.459 -0.648,-0.346 -0.69,-0.19 z"
             id="path110-4"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 115.844,11.383 1.455,-0.648 1.302,-0.344 1.149,-0.038 1.034,0.193 0.919,0.421 0.806,0.65 0.724,0.807 0.65,0.957 0.575,1.072 0.495,1.188 0.5,1.229 0.457,1.225 0.457,1.264 0.421,1.264 0.459,1.188 0.497,1.111 -0.421,0.037 -0.384,0.115 -0.383,0.113 -0.385,0.152 -0.381,0.118 -0.384,0.151 -0.421,0.114 -0.422,0.074 -0.038,-0.151 -0.038,-0.383 -0.114,-0.498 -0.114,-0.689 -0.189,-0.803 -0.27,-0.92 -0.306,-0.996 -0.42,-1.034 -0.494,-1.034 -0.574,-1.035 -0.728,-1.035 -0.803,-0.958 -0.96,-0.918 -1.07,-0.767 -1.228,-0.691 -1.375,-0.5 z"
             id="path112-4"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 110.406,12.185 0.882,-0.651 0.997,-0.42 1.069,-0.153 1.072,0.04 1.149,0.229 1.148,0.461 1.108,0.615 1.111,0.768 1.07,0.956 0.997,1.075 0.878,1.225 0.805,1.342 0.687,1.416 0.537,1.533 0.342,1.57 0.19,1.687 -3.945,1.029 -0.228,-0.649 -0.307,-0.77 -0.306,-0.803 -0.382,-0.881 -0.461,-0.92 -0.457,-0.956 -0.537,-0.961 -0.573,-0.956 -0.652,-0.957 -0.725,-0.92 -0.766,-0.842 -0.803,-0.808 -0.878,-0.728 -0.959,-0.613 -0.996,-0.537 -1.07,-0.421 z"
             id="path114-5"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 120.542,25.02 -0.572,0.115 -0.727,0.152 -0.729,0.23 -0.808,0.229 -0.764,0.267 -0.729,0.191 -0.649,0.189 -0.536,0.152 -0.382,-0.957 -0.421,-0.995 -0.422,-0.996 -0.42,-1.036 -0.421,-1.032 -0.458,-0.997 -0.498,-0.995 -0.497,-0.997 -0.533,-0.918 -0.573,-0.845 -0.614,-0.804 -0.651,-0.727 -0.65,-0.652 -0.728,-0.537 -0.804,-0.423 -0.804,-0.306 0.692,-0.459 0.764,-0.344 0.806,-0.23 0.88,-0.075 0.918,0.076 0.959,0.231 0.957,0.383 0.992,0.576 0.999,0.728 0.993,0.92 0.995,1.149 0.954,1.304 0.919,1.532 0.917,1.723 0.843,1.992 0.802,2.184 z"
             id="path116-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 101.328,14.973 1.571,-0.841 1.415,-0.498 1.304,-0.114 1.187,0.193 1.032,0.458 0.996,0.691 0.841,0.883 0.805,1.073 0.688,1.188 0.649,1.265 0.573,1.341 0.534,1.34 0.536,1.302 0.498,1.265 0.458,1.148 0.456,1.035 -0.534,0.076 -0.459,0.112 -0.422,0.079 -0.422,0.114 -0.421,0.114 -0.459,0.115 -0.498,0.076 -0.572,0.112 -0.5,-1.033 -0.458,-1.036 -0.46,-0.994 -0.458,-0.958 -0.459,-0.958 -0.495,-0.88 -0.5,-0.881 -0.495,-0.806 -0.575,-0.807 -0.61,-0.727 -0.612,-0.688 -0.688,-0.652 -0.769,-0.615 -0.801,-0.536 -0.92,-0.498 -0.956,-0.46 z"
             id="path118-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 96.577,16.348 1.419,-0.765 1.339,-0.383 1.265,-0.075 1.225,0.191 1.111,0.461 1.069,0.689 0.996,0.844 0.921,0.998 0.841,1.149 0.802,1.187 0.726,1.227 0.652,1.264 0.611,1.266 0.537,1.148 0.455,1.111 0.423,0.957 -0.574,0.113 -0.5,0.115 -0.46,0.113 -0.421,0.076 -0.458,0.115 -0.461,0.115 -0.536,0.076 -0.613,0.115 -0.688,-1.533 -0.688,-1.417 -0.646,-1.302 -0.651,-1.188 -0.614,-1.071 -0.573,-0.961 -0.61,-0.84 -0.574,-0.807 -0.612,-0.651 -0.613,-0.575 -0.611,-0.498 -0.65,-0.421 -0.653,-0.308 -0.685,-0.269 -0.731,-0.155 -0.765,-0.113 z"
             id="path120-8"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 92.977,17.379 1.378,-0.65 1.307,-0.308 1.222,0.001 1.19,0.233 1.07,0.458 1.033,0.654 0.956,0.844 0.92,0.957 0.802,1.072 0.766,1.148 0.726,1.188 0.613,1.188 0.609,1.189 0.5,1.15 0.456,1.033 0.421,0.959 -0.459,0.113 -0.42,0.113 -0.424,0.076 -0.383,0.116 -0.421,0.077 -0.42,0.075 -0.462,0.113 -0.496,0.077 -0.231,-0.765 -0.342,-0.845 -0.42,-0.842 -0.497,-0.919 -0.535,-0.919 -0.651,-0.921 -0.649,-0.92 -0.728,-0.92 -0.765,-0.841 -0.805,-0.846 -0.803,-0.766 -0.804,-0.652 -0.843,-0.613 -0.805,-0.498 -0.802,-0.383 -0.806,-0.23 z"
             id="path122-5"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 88.648,18.484 1.417,-0.762 1.38,-0.345 1.379,0.039 1.301,0.385 1.264,0.612 1.226,0.879 1.149,1.038 1.069,1.147 0.995,1.229 0.881,1.264 0.8,1.227 0.65,1.187 0.536,1.036 0.422,0.879 0.23,0.652 0.113,0.383 -0.574,0.115 -0.498,0.113 -0.498,0.115 -0.5,0.115 -0.496,0.115 -0.459,0.074 -0.499,0.077 -0.497,0.076 -0.344,-0.651 -0.384,-0.804 -0.458,-0.882 -0.537,-0.921 -0.571,-1.033 -0.614,-1.034 -0.646,-0.997 -0.691,-1.034 -0.727,-0.959 -0.767,-0.88 -0.802,-0.804 -0.803,-0.652 -0.844,-0.537 -0.844,-0.345 -0.878,-0.152 -0.882,0.035 z"
             id="path124-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 85.508,19.709 1.266,-0.842 1.224,-0.459 1.149,-0.113 1.149,0.19 1.071,0.461 1.033,0.692 0.958,0.842 0.915,1.035 0.844,1.113 0.805,1.184 0.727,1.229 0.687,1.225 0.574,1.15 0.535,1.073 0.421,0.918 0.383,0.766 -0.46,0.077 -0.382,0.114 -0.344,0.115 -0.308,0.113 -0.347,0.114 -0.305,0.115 -0.307,0.079 -0.343,0.073 -0.344,-0.955 -0.421,-0.958 -0.422,-0.921 -0.46,-0.918 -0.537,-0.919 -0.531,-0.844 -0.613,-0.844 -0.65,-0.805 -0.689,-0.767 -0.764,-0.688 -0.765,-0.614 -0.844,-0.574 -0.919,-0.5 -0.919,-0.421 -0.996,-0.308 -1.071,-0.229 z"
             id="path126-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 81.523,20.625 1.113,-0.422 1.109,-0.266 1.148,-0.077 1.074,0.078 1.109,0.231 1.032,0.345 1.034,0.536 1.034,0.652 0.956,0.768 0.918,0.92 0.881,0.996 0.842,1.112 0.802,1.226 0.689,1.34 0.688,1.418 0.571,1.491 -0.498,0.077 -0.495,0.076 -0.501,0.115 -0.497,0.153 -0.496,0.115 -0.498,0.153 -0.497,0.115 -0.5,0.074 -0.343,-0.842 -0.343,-0.882 -0.347,-0.843 -0.342,-0.883 -0.422,-0.842 -0.419,-0.805 -0.501,-0.842 -0.534,-0.767 -0.649,-0.729 -0.688,-0.728 -0.805,-0.652 -0.88,-0.613 -0.996,-0.537 -1.11,-0.498 -1.261,-0.424 -1.381,-0.344 z"
             id="path128-2"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 75.855,21.961 1.455,-0.609 1.457,-0.385 1.34,-0.189 1.34,-0.037 1.265,0.191 1.226,0.346 1.147,0.498 1.111,0.652 0.992,0.805 0.994,0.919 0.884,1.036 0.84,1.15 0.764,1.264 0.652,1.34 0.611,1.381 0.535,1.491 -0.459,0.077 -0.46,0.076 -0.536,0.078 -0.501,0.074 -0.533,0.078 -0.538,0.074 -0.535,0.076 -0.535,0.076 -0.269,-1.072 -0.383,-0.994 -0.42,-0.996 L 86.766,28.402 86.191,27.521 85.54,26.678 84.852,25.873 84.086,25.144 83.244,24.455 82.328,23.881 81.369,23.342 80.374,22.883 79.303,22.537 78.19,22.23 77.044,22.039 75.856,21.961 z"
             id="path130-0"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 73.062,22.265 1.302,-0.19 1.262,-0.113 1.262,0.038 1.228,0.154 1.224,0.307 1.15,0.385 1.109,0.498 1.073,0.613 0.995,0.729 0.954,0.844 0.844,0.919 0.803,1.034 0.688,1.15 0.611,1.226 0.499,1.341 0.38,1.419 -0.46,0.035 -0.383,0.038 -0.382,0.077 -0.384,0.077 -0.384,0.074 -0.382,0.078 -0.46,0.114 -0.496,0.076 -0.651,-1.111 -0.613,-1.073 -0.532,-0.958 -0.5,-0.956 -0.535,-0.844 -0.498,-0.804 -0.497,-0.767 -0.572,-0.69 -0.612,-0.651 -0.688,-0.575 -0.768,-0.535 -0.842,-0.498 -0.995,-0.425 -1.071,-0.383 -1.264,-0.346 -1.415,-0.308 z"
             id="path132-6"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 66.973,23.064 1.914,-0.457 1.8,-0.268 1.646,-0.075 1.531,0.154 1.417,0.307 1.302,0.461 1.187,0.573 1.074,0.77 1.03,0.842 0.917,0.96 0.844,1.034 0.802,1.112 0.728,1.147 0.688,1.227 0.612,1.226 0.611,1.265 -0.307,0.037 -0.42,0.037 -0.459,0.115 -0.501,0.076 -0.496,0.115 -0.462,0.114 -0.419,0.036 -0.346,0.039 -0.571,-1.148 -0.613,-1.035 -0.689,-0.996 -0.726,-0.918 -0.766,-0.883 -0.805,-0.806 -0.878,-0.725 -0.919,-0.69 -0.956,-0.616 -0.996,-0.573 -1.034,-0.498 -1.07,-0.498 -1.111,-0.423 -1.147,-0.383 -1.189,-0.346 -1.222,-0.309 z"
             id="path134-6"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 63.335,23.443 1.068,-0.189 1.113,-0.037 1.225,0.038 1.263,0.192 1.267,0.271 1.3,0.384 1.303,0.497 1.302,0.614 1.3,0.729 1.224,0.845 1.186,0.92 1.147,1.035 1.035,1.149 0.956,1.225 0.841,1.342 0.728,1.455 -0.537,0.039 -0.533,0.076 -0.538,0.115 -0.536,0.113 -0.459,0.113 -0.385,0.117 -0.306,0.036 -0.19,-0.037 -0.769,-0.46 -0.763,-0.537 -0.804,-0.613 -0.843,-0.689 -0.843,-0.729 -0.878,-0.768 -0.92,-0.768 -0.916,-0.802 -0.959,-0.806 -0.956,-0.807 -0.995,-0.803 -0.996,-0.729 -1.033,-0.729 -0.995,-0.652 -1.071,-0.613 -1.031,-0.537 z"
             id="path136-6"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 58.237,24.895 0.958,-0.955 1.034,-0.572 1.074,-0.23 1.109,0.077 1.148,0.308 1.225,0.575 1.227,0.769 1.3,0.879 1.301,1.074 1.341,1.11 1.34,1.19 1.34,1.188 1.377,1.188 1.377,1.112 1.376,1.035 1.381,0.92 -0.421,0.074 -0.499,0.037 -0.612,0.041 -0.613,0.037 -0.648,0.037 h -0.653 -0.574 l -0.497,-0.002 -1.034,-0.766 -0.993,-0.804 -0.996,-0.808 -0.918,-0.842 -0.919,-0.805 -0.883,-0.807 -0.878,-0.805 -0.88,-0.767 -0.919,-0.688 -0.879,-0.651 -0.92,-0.575 -0.956,-0.5 -0.996,-0.422 -1.034,-0.345 -1.073,-0.192 -1.11,-0.117 z"
             id="path138-7"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="m 54.408,25.352 1.61,-0.381 1.493,-0.152 1.415,0.076 1.343,0.271 1.262,0.461 1.226,0.575 1.186,0.729 1.148,0.805 1.11,0.919 1.109,0.922 1.071,0.995 1.111,0.996 1.109,0.958 1.107,0.959 1.188,0.843 1.185,0.807 -0.38,0.037 -0.498,0.075 -0.576,0.078 -0.576,0.036 -0.572,0.079 -0.5,0.072 -0.38,0.041 L 70.368,35.59 69.68,35.588 68.99,35.399 68.263,35.051 67.497,34.555 66.731,33.941 65.888,33.213 65.009,32.406 64.09,31.562 63.131,30.681 62.1,29.763 60.991,28.881 59.843,28.037 58.581,27.229 57.279,26.501 55.9,25.85 54.406,25.35 z"
             id="path140-3"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <path
             d="M 49.583,26.689 51,25.885 52.495,25.543 h 1.455 l 1.49,0.309 1.495,0.576 1.494,0.804 1.454,0.96 1.415,1.034 1.339,1.149 1.302,1.15 1.263,1.075 1.148,0.993 1.033,0.844 0.956,0.65 0.843,0.385 0.726,0.116 -0.61,0.077 -0.653,0.113 -0.727,0.113 -0.765,0.117 -0.767,0.074 -0.767,0.115 -0.728,0.038 -0.652,0.037 -1.07,-0.806 L 62.211,34.7 61.332,33.933 60.492,33.205 59.725,32.475 59,31.752 58.233,31.061 57.507,30.41 56.778,29.798 55.974,29.222 55.133,28.685 54.214,28.189 53.218,27.728 52.147,27.345 50.921,26.997 49.581,26.69 z"
             id="path142-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4" />
          <g
             id="g144-1"
             style="fill:#d9d9d9;fill-rule:nonzero;stroke:#d9d9d9;stroke-width:0.25400001;stroke-miterlimit:4">
            <path
               d="m 142.345,10.982 0.191,-0.383 0.153,-0.42 0.152,-0.423 0.113,-0.421 0.117,-0.459 0.115,-0.496 0.077,-0.459 0.042,-0.5 0.036,-0.459 0.035,-0.498 0.001,-0.499 -0.035,-0.46 -0.036,-0.459 -0.08,-0.457 -0.112,-0.461 -0.114,-0.42 0.611,0.804 0.459,0.882 0.345,0.842 0.189,0.88 0.076,0.919 v 0.92 l -0.116,0.918 -0.194,0.92 -0.228,0.918 -0.31,0.883 -0.343,0.879 -0.343,0.88 -0.385,0.843 -0.347,0.842 -0.346,0.765 -0.343,0.767 0.074,-0.152 0.037,-0.269 0.042,-0.266 v -0.345 l 0.037,-0.424 v -0.421 -0.46 l 0.001,-0.496 0.038,-0.499 V 13.74 l 0.039,-0.534 0.04,-0.498 0.038,-0.461 0.078,-0.461 0.075,-0.42 0.116,-0.383 z"
               id="path146-3" />
            <path
               d="m 154.014,26.885 -0.729,-0.422 -0.729,-0.462 -0.687,-0.421 -0.688,-0.422 -0.65,-0.383 -0.651,-0.422 -0.616,-0.385 -0.609,-0.42 -0.655,-0.383 -0.607,-0.384 -0.614,-0.422 -0.652,-0.382 -0.611,-0.386 -0.654,-0.342 -0.686,-0.386 -0.689,-0.382 0.61,0.61 0.613,0.616 0.613,0.611 0.612,0.576 0.65,0.611 0.651,0.536 0.65,0.539 0.688,0.497 0.651,0.461 0.689,0.383 0.651,0.346 0.688,0.269 0.688,0.229 0.688,0.115 0.691,0.037 0.691,-0.035 z"
               id="path148-33" />
            <path
               d="m 148.317,11.561 -0.536,0.308 -0.5,0.345 -0.495,0.345 -0.461,0.344 -0.46,0.343 -0.419,0.383 -0.424,0.421 -0.423,0.383 -0.384,0.422 -0.384,0.422 -0.382,0.421 -0.345,0.457 -0.383,0.422 -0.346,0.459 -0.344,0.459 -0.346,0.459 0.153,-0.496 0.192,-0.499 0.191,-0.537 0.229,-0.534 0.231,-0.536 0.265,-0.499 0.31,-0.498 0.346,-0.495 0.382,-0.46 0.461,-0.381 0.498,-0.385 0.537,-0.344 0.612,-0.269 0.652,-0.229 0.765,-0.152 0.805,-0.076 z"
               id="path150-8" />
            <path
               d="m 142.614,6.961 -0.153,0.767 -0.114,0.767 -0.154,0.766 -0.116,0.689 -0.077,0.726 -0.114,0.689 -0.079,0.689 -0.115,0.689 -0.075,0.688 -0.117,0.689 -0.074,0.651 -0.118,0.689 -0.116,0.689 -0.115,0.689 -0.15,0.689 -0.157,0.727 -0.076,-0.842 -0.113,-0.805 -0.077,-0.843 -0.076,-0.841 -0.037,-0.807 -0.038,-0.805 0.039,-0.805 0.039,-0.764 0.076,-0.767 0.116,-0.688 0.194,-0.689 0.229,-0.651 0.269,-0.573 0.384,-0.537 0.422,-0.46 0.497,-0.421 z"
               id="path152-9" />
            <path
               d="m 146.714,5.703 0.692,0.648 0.416,0.729 0.189,0.766 0.04,0.805 -0.153,0.804 -0.307,0.843 -0.424,0.844 -0.498,0.841 -0.575,0.804 -0.611,0.805 -0.653,0.764 -0.65,0.689 -0.614,0.689 -0.534,0.572 -0.463,0.539 -0.383,0.418 0.077,-1.147 0.154,-0.995 0.191,-0.844 0.307,-0.764 0.306,-0.65 0.386,-0.574 0.382,-0.535 0.424,-0.501 0.383,-0.496 0.424,-0.495 0.382,-0.538 0.307,-0.613 0.307,-0.688 0.23,-0.766 0.194,-0.919 0.075,-1.032 z"
               id="path154-4" />
            <path
               d="m 141.803,17.951 v -0.805 l -0.039,-0.765 -0.034,-0.765 -0.04,-0.768 -0.036,-0.729 -0.077,-0.727 -0.076,-0.727 -0.073,-0.691 -0.117,-0.688 -0.114,-0.728 -0.189,-0.689 -0.152,-0.689 -0.193,-0.689 -0.268,-0.689 -0.229,-0.689 -0.306,-0.689 1.111,1.073 0.918,1.034 0.649,0.959 0.457,0.92 0.309,0.879 0.151,0.805 0.037,0.806 -0.077,0.727 -0.195,0.689 -0.187,0.651 -0.27,0.613 -0.271,0.533 -0.23,0.537 -0.229,0.459 -0.152,0.459 -0.078,0.383 z"
               id="path156-1" />
            <path
               d="m 153.022,20.603 -0.613,0.114 -0.614,0.116 -0.611,0.075 -0.613,0.075 -0.609,0.038 -0.616,0.037 h -0.613 -0.575 l -0.612,-0.039 h -0.574 l -0.613,-0.077 -0.573,-0.038 -0.613,-0.04 -0.575,-0.075 -0.612,-0.079 -0.574,-0.075 0.498,0.229 0.498,0.192 0.535,0.231 0.537,0.19 0.574,0.193 0.576,0.151 0.61,0.156 0.61,0.076 0.612,0.039 h 0.651 l 0.651,-0.039 0.654,-0.15 0.651,-0.191 0.651,-0.27 0.648,-0.381 0.654,-0.46 z"
               id="path158-6" />
            <path
               d="m 149.457,23.702 0.461,0.078 0.419,0.075 0.461,0.115 0.457,0.115 0.463,0.194 0.456,0.151 0.421,0.191 0.46,0.23 0.421,0.23 0.421,0.267 0.383,0.271 0.386,0.268 0.343,0.307 0.308,0.307 0.304,0.307 0.27,0.344 -0.269,-0.917 -0.422,-0.808 -0.494,-0.688 -0.615,-0.651 -0.688,-0.536 -0.768,-0.5 -0.84,-0.421 -0.882,-0.347 -0.919,-0.306 -0.919,-0.307 -0.955,-0.231 -0.958,-0.23 -0.957,-0.193 -0.919,-0.189 -0.843,-0.154 -0.842,-0.192 0.42,0.153 0.574,0.306 0.69,0.463 0.841,0.497 0.843,0.535 0.879,0.499 0.842,0.46 0.768,0.308 z"
               id="path160-9" />
            <path
               d="m 151.214,30.559 0.345,-0.881 0.117,-0.844 -0.116,-0.842 -0.307,-0.766 -0.457,-0.729 -0.612,-0.727 -0.728,-0.69 -0.804,-0.614 -0.843,-0.613 -0.879,-0.536 -0.919,-0.538 -0.884,-0.459 -0.801,-0.42 -0.767,-0.387 -0.651,-0.344 -0.496,-0.309 0.532,1.113 0.538,0.919 0.573,0.728 0.536,0.652 0.574,0.498 0.574,0.459 0.574,0.346 0.574,0.346 0.571,0.346 0.577,0.382 0.572,0.384 0.536,0.46 0.537,0.573 0.535,0.691 0.497,0.806 0.498,0.995 z"
               id="path162-2" />
            <path
               d="m 141.569,21.129 0.422,0.652 0.42,0.652 0.421,0.65 0.38,0.613 0.346,0.613 0.345,0.649 0.346,0.614 0.305,0.613 0.304,0.652 0.268,0.65 0.271,0.613 0.229,0.65 0.19,0.689 0.192,0.65 0.152,0.689 0.152,0.73 0.384,-1.455 0.191,-1.265 0.041,-1.149 -0.115,-0.994 -0.229,-0.844 -0.346,-0.766 -0.42,-0.652 -0.458,-0.537 -0.538,-0.499 -0.535,-0.421 -0.573,-0.346 -0.537,-0.306 -0.496,-0.306 -0.46,-0.268 -0.342,-0.307 -0.31,-0.271 z"
               id="path164-8" />
          </g>
        </g>
        <g
           transform="matrix(-1.2697137,0,0,1.2697137,225.07184,26.323784)"
           id="Layer_x0020_1-5">
          <defs
             id="defs167-2">
            <linearGradient
               x1="-3510.3682"
               y1="4186.3037"
               x2="-3520.3882"
               y2="4153.2837"
               id="linearGradient20285"
               gradientUnits="userSpaceOnUse"
               gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,-2022.5977,2980.6621)">
              <stop
                 id="stop20287"
                 style="stop-color:#4f0c81;stop-opacity:1"
                 offset="0" />
              <stop
                 id="stop20289"
                 style="stop-color:#690c73;stop-opacity:1"
                 offset="0.0701" />
              <stop
                 id="stop20291"
                 style="stop-color:#9a0a5b;stop-opacity:1"
                 offset="0.20900001" />
              <stop
                 id="stop20293"
                 style="stop-color:#c20748;stop-opacity:1"
                 offset="0.33680001" />
              <stop
                 id="stop20295"
                 style="stop-color:#e0053a;stop-opacity:1"
                 offset="0.45120001" />
              <stop
                 id="stop20297"
                 style="stop-color:#f20032;stop-opacity:1"
                 offset="0.54809999" />
              <stop
                 id="stop20299"
                 style="stop-color:#fa002f;stop-opacity:1"
                 offset="0.61580002" />
              <stop
                 id="stop20301"
                 style="stop-color:#f7ee5f;stop-opacity:1"
                 offset="1" />
            </linearGradient>
          </defs>
          <g
             id="g186-3"
             style="fill:url(#linearGradient23811);fill-rule:nonzero;stroke:#000000;stroke-width:0.25400001;stroke-miterlimit:4">
            <path
               d="m 0.241,40.672 c 13.561,-1.867 63.613,-4.393 85.943,-8.051 17.961,-2.937 35.502,-8.285 52.242,-13.9 4.328,-1.453 11.991,-4.434 16.896,-7.07 3.104,-2.373 10.571,-5.889 12.606,-9.222 C 135.478,17.836 122.415,22.078 84.346,29.783 68.91,32.952 12.729,37.504 0.241,40.672 z"
               id="path188-1"
               style="fill:#000000;stroke-width:0.59560001" />
            <defs
               id="defs190-94">
              <linearGradient
                 x1="-3788.0986"
                 y1="-3507.6162"
                 x2="-3789.1638"
                 y2="-3479.4058"
                 id="linearGradient20306"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20308"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20310"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20312"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20314"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20316"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20318"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20320"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20322"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 48.261,46.645 1.454,0.498 1.418,0.118 1.417,-0.229 1.417,-0.574 1.379,-0.766 1.38,-0.994 1.305,-1.146 1.301,-1.226 1.228,-1.26 1.149,-1.267 1.111,-1.224 1.035,-1.148 0.958,-0.957 0.881,-0.763 0.767,-0.501 0.689,-0.228 -0.576,0.036 -0.611,0.038 -0.689,0.077 -0.688,0.074 -0.69,0.078 -0.689,0.076 -0.689,0.038 -0.612,0.076 -0.957,0.88 -0.921,0.842 -0.805,0.842 -0.729,0.844 -0.727,0.801 -0.688,0.805 -0.652,0.764 -0.691,0.729 -0.688,0.727 -0.729,0.65 -0.767,0.65 -0.882,0.61 -0.919,0.576 -1.034,0.535 -1.149,0.496 -1.302,0.421 z"
               id="path209-3"
               style="fill:url(#AIgd2-1)" />
            <defs
               id="defs211-9">
              <linearGradient
                 x1="-3817.4316"
                 y1="-3498.7192"
                 x2="-3818.3076"
                 y2="-3475.5176"
                 id="linearGradient20326"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20328"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20330"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20332"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20334"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20336"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20338"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20340"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20342"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 43.511,46.45 1.688,0.271 1.569,0.038 1.455,-0.15 1.377,-0.345 1.265,-0.534 1.151,-0.652 1.148,-0.766 1.034,-0.879 1.035,-0.918 0.957,-0.995 0.959,-1.072 0.921,-1.032 0.956,-1.033 0.96,-1.033 0.958,-0.955 0.995,-0.881 -0.381,0.037 h -0.423 l -0.384,0.039 -0.419,0.037 -0.424,0.037 -0.421,0.078 -0.42,0.035 -0.42,0.041 -0.421,0.037 -0.461,0.037 -0.422,0.078 -0.459,0.037 -0.459,0.037 -0.46,0.037 h -0.46 l -0.459,0.039 -0.347,0.535 -0.42,0.651 -0.537,0.765 -0.575,0.805 -0.69,0.881 -0.729,0.879 -0.766,0.918 -0.805,0.879 -0.844,0.844 -0.84,0.805 -0.885,0.726 -0.842,0.612 -0.844,0.496 -0.843,0.346 -0.804,0.189 h -0.768 z"
               id="path230-2"
               style="fill:url(#linearGradient3725-0)" />
            <defs
               id="defs232-7">
              <linearGradient
                 x1="-3806.9058"
                 y1="-3505.3105"
                 x2="-3807.8401"
                 y2="-3480.5605"
                 id="linearGradient20346"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20348"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20350"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20352"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20354"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20356"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20358"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20360"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20362"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 40.371,46.487 0.958,0.115 0.919,0.076 0.881,-0.037 0.881,-0.152 0.882,-0.19 0.843,-0.344 0.841,-0.421 0.883,-0.574 0.882,-0.65 0.882,-0.764 0.882,-0.921 0.919,-0.993 0.958,-1.188 0.997,-1.3 1.034,-1.416 1.074,-1.607 -0.651,-0.002 -0.613,0.039 -0.614,0.076 -0.612,0.076 -0.611,0.078 -0.613,0.072 h -0.688 -0.727 l -0.616,0.612 -0.573,0.65 -0.576,0.614 -0.574,0.688 -0.575,0.65 -0.535,0.689 -0.576,0.648 -0.539,0.691 -0.572,0.65 -0.574,0.65 -0.612,0.65 -0.577,0.613 -0.65,0.572 -0.652,0.574 -0.65,0.573 -0.729,0.499 z"
               id="path251-04"
               style="fill:url(#AIgd4-46)" />
            <path
               d="m 37.041,46.329 0.728,0.387 0.802,0.153 0.807,-0.116 0.842,-0.342 0.844,-0.5 0.881,-0.689 0.88,-0.764 0.884,-0.917 0.841,-0.958 0.884,-0.993 0.804,-0.997 0.805,-0.957 0.768,-0.957 0.729,-0.84 0.689,-0.729 0.614,-0.613 -4.099,0.382 -0.462,0.612 -0.498,0.61 -0.458,0.616 -0.459,0.608 -0.46,0.614 -0.5,0.612 -0.461,0.612 -0.497,0.612 -0.537,0.573 -0.537,0.611 -0.536,0.578 -0.613,0.57 -0.612,0.574 -0.653,0.576 -0.688,0.536 -0.728,0.532 z"
               id="path253-7"
               style="fill:url(#linearGradient3727-1)" />
            <defs
               id="defs255-8">
              <linearGradient
                 x1="-3825.4375"
                 y1="-3503.8936"
                 x2="-3826.3342"
                 y2="-3480.1453"
                 id="linearGradient20367"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20369"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20371"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20373"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20375"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20377"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20379"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20381"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20383"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 30.262,45.444 1.188,0.767 1.109,0.5 1.11,0.231 h 1.074 l 1.033,-0.191 0.995,-0.343 0.955,-0.538 0.96,-0.687 0.919,-0.841 0.923,-0.881 0.84,-1.037 0.884,-1.031 0.843,-1.109 0.844,-1.146 0.805,-1.148 0.805,-1.111 -0.688,0.115 -0.536,0.037 -0.384,0.037 -0.345,0.039 -0.343,0.039 -0.346,-10e-4 -0.499,0.037 -0.651,0.037 -0.729,1.034 -0.727,0.955 -0.729,0.921 -0.805,0.804 -0.767,0.727 -0.767,0.689 -0.804,0.611 -0.768,0.536 -0.766,0.458 -0.768,0.421 -0.727,0.306 -0.689,0.269 -0.689,0.229 -0.614,0.152 -0.612,0.075 -0.537,0.038 z"
               id="path274-0"
               style="fill:url(#AIgd6-5)" />
            <path
               d="m 26.7,45.21 1.228,0.153 1.186,0.08 1.149,-0.078 1.109,-0.151 1.036,-0.227 1.033,-0.345 0.958,-0.422 0.92,-0.535 0.92,-0.572 0.844,-0.651 0.843,-0.727 0.803,-0.804 0.766,-0.842 0.73,-0.918 0.729,-0.959 0.689,-0.994 -0.767,0.039 -0.844,0.074 -0.802,0.076 -0.806,0.038 -0.69,0.077 -0.574,0.035 -0.421,0.039 -0.191,0.037 -0.076,0.078 -0.191,0.19 -0.308,0.306 -0.382,0.385 -0.422,0.459 -0.536,0.536 -0.577,0.573 -0.648,0.614 -0.731,0.608 -0.764,0.65 -0.768,0.615 -0.843,0.611 -0.88,0.572 -0.881,0.535 -0.921,0.46 -0.92,0.385 z"
               id="path276-6"
               style="fill:url(#linearGradient3729-7)" />
            <defs
               id="defs278-5">
              <linearGradient
                 x1="-3841.6636"
                 y1="-3502.4297"
                 x2="-3842.4236"
                 y2="-3482.3"
                 id="linearGradient20388"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20390"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20392"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20394"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20396"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20398"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20400"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20402"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20404"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 21.991,45.476 1.033,0.192 0.998,0.076 1.033,-0.113 1.034,-0.191 1.034,-0.342 0.994,-0.423 0.996,-0.497 0.998,-0.611 0.919,-0.648 0.918,-0.69 0.881,-0.726 0.845,-0.766 0.806,-0.804 0.766,-0.765 0.69,-0.768 0.651,-0.766 h -0.461 l -0.574,0.04 -0.611,0.036 H 34.29 l -0.613,0.073 -0.613,0.041 -0.496,0.039 -0.423,0.075 v 0.077 l -0.154,0.189 -0.381,0.347 -0.537,0.42 -0.652,0.535 -0.764,0.613 -0.845,0.652 -0.882,0.647 -0.92,0.687 -0.918,0.691 -0.881,0.65 -0.846,0.574 -0.765,0.539 -0.69,0.421 -0.537,0.305 -0.382,0.191 z"
               id="path297-5"
               style="fill:url(#AIgd8-4)" />
            <path
               d="m 16.782,45.434 0.612,0.612 0.806,0.267 0.996,10e-4 1.11,-0.266 1.227,-0.46 1.262,-0.646 1.341,-0.768 1.305,-0.841 1.302,-0.919 1.227,-0.916 1.147,-0.879 0.999,-0.844 0.881,-0.688 0.65,-0.574 0.423,-0.381 0.192,-0.154 -0.498,0.038 -0.538,0.036 -0.574,0.037 -0.572,0.041 -0.614,0.072 -0.614,0.039 -0.611,0.04 -0.652,0.038 -0.688,0.419 -0.688,0.422 -0.693,0.456 -0.649,0.425 -0.689,0.456 -0.653,0.498 -0.688,0.459 -0.653,0.459 -0.69,0.496 -0.65,0.461 -0.688,0.459 -0.651,0.458 -0.688,0.421 -0.691,0.422 -0.651,0.419 -0.69,0.384 z"
               id="path299-7"
               style="fill:url(#linearGradient3731-8)" />
            <defs
               id="defs301-6">
              <linearGradient
                 x1="-3872.1543"
                 y1="-3503.9727"
                 x2="-3872.3848"
                 y2="-3493.1567"
                 id="linearGradient20409"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20411"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20413"
                   style="stop-color:#f5d65d;stop-opacity:1"
                   offset="0.186" />
                <stop
                   id="stop20415"
                   style="stop-color:#f4c35b;stop-opacity:1"
                   offset="0.38249999" />
                <stop
                   id="stop20417"
                   style="stop-color:#f4bc5a;stop-opacity:1"
                   offset="0.51980001" />
                <stop
                   id="stop20419"
                   style="stop-color:#f5da5d;stop-opacity:1"
                   offset="0.7809" />
                <stop
                   id="stop20421"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 12.953,45.507 0.652,0.229 0.649,0.115 0.65,0.037 0.653,-0.11 0.65,-0.194 0.689,-0.265 0.727,-0.383 0.768,-0.46 0.843,-0.535 0.881,-0.612 0.959,-0.688 1.072,-0.728 1.187,-0.803 1.265,-0.881 1.379,-0.918 1.534,-0.957 -0.653,0.039 -0.727,0.039 -0.65,-0.001 -0.65,0.038 -0.574,0.037 -0.459,0.038 -0.307,0.039 -0.116,0.036 -0.077,0.115 -0.229,0.23 -0.346,0.307 -0.458,0.42 -0.575,0.499 -0.653,0.577 -0.689,0.571 -0.805,0.613 -0.805,0.611 -0.843,0.612 -0.843,0.534 -0.882,0.537 -0.842,0.457 -0.842,0.383 -0.805,0.267 -0.729,0.154 z"
               id="path316-0"
               style="fill:url(#linearGradient3733-6)" />
            <defs
               id="defs318-0">
              <linearGradient
                 x1="-3878.0732"
                 y1="-3508.4204"
                 x2="-3874.5449"
                 y2="-3484.9487"
                 id="linearGradient20425"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20427"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20429"
                   style="stop-color:#f5d65d;stop-opacity:1"
                   offset="0.186" />
                <stop
                   id="stop20431"
                   style="stop-color:#f4c35b;stop-opacity:1"
                   offset="0.38249999" />
                <stop
                   id="stop20433"
                   style="stop-color:#f4bc5a;stop-opacity:1"
                   offset="0.51980001" />
                <stop
                   id="stop20435"
                   style="stop-color:#f5da5d;stop-opacity:1"
                   offset="0.7809" />
                <stop
                   id="stop20437"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 10.158,45.084 0.879,0.344 0.958,0.152 0.998,-0.072 1.033,-0.268 1.072,-0.383 1.033,-0.498 1.074,-0.608 0.996,-0.69 0.958,-0.688 0.92,-0.728 0.843,-0.688 0.728,-0.691 0.653,-0.572 0.495,-0.499 0.383,-0.341 0.232,-0.232 -0.613,0.038 -0.577,0.04 -0.571,0.037 -0.575,0.074 -0.535,0.041 -0.577,0.037 -0.61,0.074 -0.613,0.038 -0.459,0.421 -0.501,0.42 -0.458,0.421 -0.499,0.46 -0.498,0.498 -0.497,0.459 -0.536,0.459 -0.538,0.458 -0.536,0.423 -0.534,0.421 -0.577,0.381 -0.534,0.343 -0.614,0.309 -0.574,0.266 -0.613,0.193 -0.613,0.152 z"
               id="path333-2"
               style="fill:url(#linearGradient3735-5)" />
            <path
               d="m 6.791,44.01 0.765,0.535 0.763,0.345 0.767,0.154 0.767,0.039 0.768,-0.151 0.766,-0.232 0.766,-0.343 0.765,-0.458 0.729,-0.498 0.766,-0.611 0.729,-0.613 0.729,-0.65 0.727,-0.648 0.69,-0.69 0.689,-0.649 0.69,-0.615 -0.422,0.041 -0.46,0.076 -0.497,0.037 -0.535,0.039 -0.575,0.074 -0.612,0.039 -0.652,0.074 -0.612,0.037 -0.192,0.461 -0.27,0.457 -0.271,0.422 -0.346,0.422 -0.381,0.383 -0.424,0.383 -0.42,0.381 -0.496,0.306 -0.5,0.308 -0.537,0.268 -0.573,0.268 -0.576,0.189 -0.612,0.154 -0.61,0.15 -0.654,0.077 -0.649,0.039 z"
               id="path335-9"
               style="fill:url(#linearGradient3737-7)" />
            <path
               d="m 3.763,43.434 0.652,0.266 0.69,0.193 0.726,0.115 0.806,10e-4 0.767,-0.038 0.842,-0.115 0.805,-0.229 0.803,-0.229 0.768,-0.344 0.729,-0.384 0.65,-0.421 0.614,-0.495 0.536,-0.538 0.46,-0.572 0.345,-0.651 0.23,-0.652 -0.46,0.04 -0.46,0.037 -0.497,0.076 -0.5,0.038 -0.495,0.038 -0.537,0.037 -0.574,0.039 -0.652,0.036 -0.271,0.385 -0.307,0.384 -0.306,0.345 -0.306,0.306 -0.307,0.306 -0.348,0.229 -0.343,0.27 -0.347,0.229 -0.381,0.191 -0.422,0.19 -0.421,0.19 -0.456,0.153 -0.462,0.152 -0.495,0.152 -0.537,0.116 -0.539,0.154 z"
               id="path337-9"
               style="fill:url(#linearGradient3739-5)" />
            <path
               d="m 2.193,42.896 0.23,0.229 0.347,0.152 0.42,0.078 H 3.65 L 4.186,43.317 4.759,43.205 5.372,43.012 5.984,42.823 6.597,42.553 7.211,42.246 7.823,41.904 8.36,41.519 8.897,41.099 9.355,40.64 9.7,40.18 10.007,39.682 9.664,39.723 9.356,39.76 8.973,39.798 8.63,39.836 8.286,39.875 7.979,39.911 7.711,39.912 7.442,39.911 v 0.153 L 7.1,40.37 6.524,40.792 5.757,41.29 4.84,41.786 3.918,42.285 2.999,42.666 2.193,42.896 z"
               id="path339-60"
               style="fill:url(#linearGradient3741-3)" />
            <path
               d="m 1.084,41.822 0.078,0.536 0.192,0.344 0.305,0.155 0.42,0.076 0.499,-0.075 0.574,-0.192 0.573,-0.229 0.614,-0.306 0.613,-0.346 0.574,-0.381 0.575,-0.381 0.461,-0.347 0.42,-0.307 0.307,-0.229 0.191,-0.152 0.038,-0.076 -2.986,0.341 -0.229,0.152 -0.386,0.192 -0.458,0.23 -0.5,0.229 -0.535,0.269 -0.497,0.189 -0.461,0.192 -0.384,0.114 z"
               id="path341-7"
               style="fill:url(#linearGradient3743-2)" />
            <defs
               id="defs343-5">
              <linearGradient
                 x1="-3892.5645"
                 y1="-3497.0415"
                 x2="-3892.7126"
                 y2="-3490.0823"
                 id="linearGradient20445"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20447"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20449"
                   style="stop-color:#f5d65d;stop-opacity:1"
                   offset="0.186" />
                <stop
                   id="stop20451"
                   style="stop-color:#f4c35b;stop-opacity:1"
                   offset="0.38249999" />
                <stop
                   id="stop20453"
                   style="stop-color:#f4bc5a;stop-opacity:1"
                   offset="0.51980001" />
                <stop
                   id="stop20455"
                   style="stop-color:#f5da5d;stop-opacity:1"
                   offset="0.7809" />
                <stop
                   id="stop20457"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 4.533,40.253 -0.651,0.039 -0.574,0.039 -0.536,0.036 -0.498,0.037 -0.46,0.04 -0.497,0.036 -0.498,0.077 -0.577,0.114 0.117,0.729 0.343,0.345 0.537,0.001 0.689,-0.19 0.689,-0.347 0.729,-0.382 0.651,-0.345 0.536,-0.229 z"
               id="path358-4"
               style="fill:url(#AIgd16-9)" />
            <path
               d="m 4.419,39.874 -0.653,0.112 -0.573,0.076 -0.497,0.114 -0.5,0.075 -0.458,0.114 -0.459,0.115 -0.537,0.116 -0.575,0.154 -0.038,-0.844 0.345,-0.536 0.537,-0.192 0.727,-0.034 0.766,0.151 0.766,0.193 0.651,0.23 0.499,0.154 z"
               id="path360-5"
               style="fill:url(#linearGradient3745-0)" />
            <defs
               id="defs362-2">
              <linearGradient
                 x1="-3716.793"
                 y1="-3522.1724"
                 x2="-3726.813"
                 y2="-3555.1924"
                 id="linearGradient20462"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20464"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20466"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20468"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20470"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20472"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20474"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20476"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20478"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 44.258,24.317 1.684,-0.651 1.611,-0.419 1.491,-0.113 1.417,0.076 1.379,0.309 1.262,0.459 1.227,0.652 1.187,0.729 1.149,0.845 1.11,0.919 1.106,0.959 1.074,0.996 1.071,0.957 1.07,0.921 1.073,0.882 1.109,0.807 -0.384,0.073 -0.421,0.038 -0.421,0.039 -0.383,0.076 -0.423,0.039 -0.421,0.038 -0.459,0.036 -0.421,0.039 -0.422,0.035 -0.461,0.041 -0.458,0.076 -0.422,0.037 -0.461,0.04 -0.457,0.074 -0.498,0.037 -0.461,0.077 -0.382,-0.534 -0.495,-0.653 -0.576,-0.766 -0.688,-0.768 -0.727,-0.843 -0.805,-0.843 -0.879,-0.844 -0.881,-0.806 -0.959,-0.766 -0.953,-0.688 -0.957,-0.615 -0.997,-0.497 -0.957,-0.385 -0.958,-0.23 -0.956,-0.039 -0.88,0.152 z"
               id="path381-8"
               style="fill:url(#linearGradient3747-7)" />
            <defs
               id="defs383-8">
              <linearGradient
                 x1="-3818.3081"
                 y1="-3506.1616"
                 x2="-3836.2568"
                 y2="-3532.4282"
                 id="linearGradient20482"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20484"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20486"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20488"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20490"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20492"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20494"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20496"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20498"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 41.383,24.964 0.96,-0.345 0.92,-0.227 0.878,-0.152 0.923,-0.077 0.878,0.077 0.919,0.192 0.88,0.268 0.919,0.423 0.956,0.537 0.959,0.691 0.995,0.803 1.033,0.96 1.108,1.11 1.11,1.266 1.186,1.418 1.264,1.57 -0.69,0.039 -0.611,0.072 -0.576,0.039 -0.534,0.076 -0.537,0.076 -0.573,0.076 -0.653,0.113 -0.765,0.117 -0.689,-0.574 -0.65,-0.613 -0.689,-0.653 -0.612,-0.653 -0.649,-0.649 -0.649,-0.65 L 47.781,29.641 47.13,28.99 46.479,28.378 45.791,27.804 45.14,27.228 44.452,26.654 43.725,26.156 42.958,25.733 42.192,25.312 41.387,24.965 z"
               id="path402-5"
               style="fill:url(#linearGradient3749-2)" />
            <path
               d="m 38.167,25.805 0.727,-0.611 0.808,-0.307 0.88,-0.074 0.879,0.191 0.958,0.383 0.956,0.538 0.995,0.688 0.996,0.805 0.996,0.881 0.993,0.921 0.956,0.921 0.92,0.958 0.841,0.88 0.84,0.805 0.729,0.691 0.69,0.574 -4.176,0.496 L 47.619,33.932 47.083,33.317 46.585,32.704 46.052,32.093 45.515,31.48 44.981,30.829 44.408,30.215 43.873,29.639 43.26,29.065 42.648,28.492 41.996,27.954 41.308,27.456 40.58,26.959 39.814,26.536 39.01,26.153 38.167,25.807 z"
               id="path404-7"
               style="fill:url(#linearGradient3751-1)" />
            <path
               d="m 31.886,28.481 1.148,-1.111 1.111,-0.802 1.073,-0.534 1.072,-0.307 1.072,-0.037 1.034,0.154 1.033,0.385 0.996,0.498 0.994,0.689 0.955,0.804 0.996,0.921 0.919,0.996 0.957,1.035 0.917,1.111 0.918,1.111 0.919,1.11 -0.729,0.04 -0.611,0.035 -0.498,0.039 -0.461,0.076 -0.458,0.076 -0.499,0.075 -0.571,0.078 -0.692,0.112 -0.803,-1.034 -0.766,-0.919 -0.803,-0.844 -0.766,-0.728 -0.802,-0.612 -0.766,-0.538 -0.728,-0.461 -0.768,-0.382 -0.728,-0.309 -0.688,-0.229 -0.728,-0.192 -0.689,-0.152 -0.648,-0.08 -0.653,-0.074 h -0.649 l -0.612,-0.002 z"
               id="path406-5"
               style="fill:url(#linearGradient3753-4)" />
            <path
               d="m 27.402,29.512 1.267,-0.461 1.187,-0.344 1.187,-0.189 1.109,-0.077 1.111,0.001 1.071,0.155 1.035,0.231 0.996,0.347 0.995,0.419 0.919,0.537 0.957,0.613 0.878,0.689 0.882,0.768 0.84,0.842 0.806,0.922 0.803,0.996 -0.803,0.115 -0.919,0.111 -0.921,0.115 -0.921,0.115 -0.842,0.113 -0.649,0.08 -0.499,0.037 L 37.7,35.645 37.625,35.57 37.433,35.417 37.164,35.149 36.821,34.803 36.398,34.383 35.903,33.959 35.328,33.463 34.678,32.925 33.95,32.426 33.185,31.89 32.341,31.39 31.423,30.895 30.503,30.471 29.51,30.088 28.476,29.74 27.403,29.511 z"
               id="path408-9"
               style="fill:url(#linearGradient3755-9)" />
            <path
               d="m 21.735,30.196 1.034,-0.418 1.035,-0.307 1.108,-0.115 1.073,10e-4 1.111,0.118 1.108,0.229 1.072,0.346 1.111,0.422 1.033,0.498 1.033,0.537 0.995,0.651 0.994,0.651 0.882,0.693 0.881,0.727 0.802,0.728 0.726,0.729 -0.495,0.037 -0.612,0.076 -0.689,0.075 -0.728,0.077 -0.729,0.075 -0.652,0.076 -0.573,0.037 h -0.422 l -10e-4,-0.077 -0.191,-0.191 -0.38,-0.268 -0.574,-0.385 -0.689,-0.42 -0.805,-0.5 -0.919,-0.537 -0.956,-0.533 -0.955,-0.54 L 26.367,32.15 25.369,31.654 24.453,31.197 23.607,30.81 22.845,30.503 22.229,30.31 21.734,30.195 z"
               id="path410-6"
               style="fill:url(#linearGradient3757-6)" />
            <path
               d="m 16.373,31.303 0.537,-0.842 0.805,-0.498 0.996,-0.188 h 1.147 l 1.264,0.268 1.379,0.422 1.455,0.576 1.415,0.651 1.455,0.729 1.339,0.766 1.265,0.73 1.149,0.727 0.954,0.615 0.729,0.459 0.496,0.342 0.23,0.117 -0.537,0.116 -0.61,0.077 -0.653,0.073 -0.689,0.038 -0.727,0.078 -0.729,0.074 -0.688,0.115 -0.689,0.115 -0.729,-0.346 -0.688,-0.348 -0.729,-0.381 -0.688,-0.385 -0.69,-0.346 -0.688,-0.383 -0.728,-0.384 -0.688,-0.382 -0.689,-0.35 -0.688,-0.382 -0.729,-0.343 -0.688,-0.307 -0.689,-0.348 -0.727,-0.305 -0.727,-0.311 -0.729,-0.266 z"
               id="path412-9"
               style="fill:url(#linearGradient3759-6)" />
            <path
               d="m 9.518,33.135 0.844,-0.611 0.956,-0.346 0.996,-0.149 1.07,10e-4 1.113,0.189 1.148,0.348 1.11,0.421 1.108,0.5 1.035,0.574 1.032,0.575 0.919,0.614 0.804,0.536 0.727,0.499 0.574,0.46 0.42,0.306 0.229,0.193 -0.612,0.074 -0.574,0.077 -0.495,0.076 -0.501,0.037 -0.536,0.037 -0.496,0.076 -0.576,0.078 -0.61,0.074 L 18.666,37.432 18.13,37.084 17.556,36.664 16.982,36.281 16.37,35.86 15.757,35.439 15.145,35.016 14.533,34.633 13.919,34.249 13.272,33.941 12.62,33.636 12.007,33.404 11.359,33.215 10.744,33.098 H 10.13 l -0.612,0.037 z"
               id="path414-6"
               style="fill:url(#linearGradient3761-1)" />
            <path
               d="m 12.044,32.029 0.653,-0.423 0.688,-0.305 0.652,-0.154 0.688,-0.074 0.689,0.037 0.728,0.152 0.807,0.27 0.838,0.308 0.921,0.423 0.959,0.459 1.07,0.576 1.147,0.614 1.265,0.65 1.378,0.692 1.49,0.765 1.648,0.768 -0.613,0.04 -0.689,0.073 -0.688,0.078 -0.691,0.112 -0.613,0.078 -0.457,0.078 -0.346,0.035 -0.153,-0.035 -0.075,-0.079 -0.27,-0.19 -0.345,-0.309 -0.459,-0.344 -0.573,-0.422 -0.689,-0.459 -0.729,-0.5 -0.803,-0.499 -0.879,-0.498 -0.882,-0.497 -0.955,-0.425 -0.957,-0.384 -0.959,-0.304 -0.957,-0.196 -0.92,-0.111 -0.919,-0.001 z"
               id="path416-8"
               style="fill:url(#linearGradient3763-3)" />
            <path
               d="m 6.451,35.086 0.691,-0.766 0.726,-0.574 0.729,-0.382 0.766,-0.229 0.767,-0.037 0.804,0.076 0.844,0.192 0.804,0.271 0.84,0.422 0.805,0.42 0.842,0.536 0.843,0.539 0.843,0.536 0.803,0.574 0.805,0.578 0.803,0.496 -0.459,0.076 -0.498,0.038 -0.574,0.116 -0.613,0.072 -0.649,0.079 -0.69,0.073 -0.65,0.078 -0.653,0.075 -0.229,-0.497 -0.269,-0.422 -0.305,-0.422 -0.384,-0.383 -0.383,-0.344 -0.419,-0.27 -0.5,-0.271 -0.497,-0.229 -0.536,-0.191 -0.572,-0.154 -0.58,-0.112 -0.612,-0.079 -0.65,-0.037 -0.652,0.001 -0.65,0.073 -0.689,0.078 z"
               id="path418-35"
               style="fill:url(#linearGradient3765-7)" />
            <path
               d="m 1.738,37.609 0.193,-0.306 0.306,-0.268 0.422,-0.228 0.459,-0.154 0.536,-0.114 0.612,-0.036 0.613,10e-4 0.689,0.037 0.65,0.114 0.689,0.155 0.652,0.229 0.61,0.269 0.576,0.308 0.534,0.383 0.422,0.422 0.381,0.461 L 9.739,38.958 9.32,39.034 8.9,39.11 8.477,39.184 8.095,39.221 7.787,39.262 H 7.56 7.482 L 7.329,39.184 6.948,38.954 6.296,38.647 5.53,38.304 4.649,37.995 3.654,37.726 2.697,37.572 1.738,37.608 z"
               id="path420-6"
               style="fill:url(#linearGradient3767-3)" />
            <path
               d="m 0.818,39.178 -0.036,-0.609 0.152,-0.461 0.271,-0.307 0.42,-0.191 0.497,-0.078 0.575,0.041 0.613,0.076 0.688,0.154 0.65,0.229 0.65,0.231 0.613,0.23 0.535,0.23 0.46,0.23 0.383,0.154 0.191,0.152 0.078,0.036 L 4.493,39.828 4.223,39.716 3.803,39.599 3.344,39.446 2.81,39.294 2.274,39.179 1.739,39.105 1.24,39.104 0.818,39.178 z"
               id="path422-5"
               style="fill:url(#linearGradient3769-5)" />
            <path
               d="m 3.349,36.616 0.612,-0.498 0.651,-0.383 0.729,-0.342 0.805,-0.231 0.806,-0.153 0.803,-0.11 0.844,10e-4 0.841,0.072 0.804,0.156 0.804,0.27 0.729,0.307 0.689,0.383 0.649,0.461 0.536,0.535 0.421,0.613 0.344,0.689 -0.499,0.039 -0.457,0.077 -0.5,0.036 -0.536,0.076 -0.535,0.078 -0.574,0.037 L 10.7,38.844 10.05,38.916 9.819,38.575 9.551,38.267 9.244,38 8.901,37.73 8.519,37.5 8.098,37.27 7.675,37.078 7.216,36.927 6.757,36.773 6.26,36.657 5.8,36.581 5.301,36.541 4.804,36.504 4.308,36.503 3.809,36.541 3.349,36.616 z"
               id="path424-3"
               style="fill:url(#linearGradient3771-6)" />
            <defs
               id="defs426-3">
              <linearGradient
                 x1="-3644.5117"
                 y1="-3531.5527"
                 x2="-3636.6318"
                 y2="-3508.3506"
                 id="linearGradient20513"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20515"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20517"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0.0006" />
                <stop
                   id="stop20519"
                   style="stop-color:#8d0f6d;stop-opacity:1"
                   offset="0.072" />
                <stop
                   id="stop20521"
                   style="stop-color:#ad0d5a;stop-opacity:1"
                   offset="0.1459" />
                <stop
                   id="stop20523"
                   style="stop-color:#c80a4a;stop-opacity:1"
                   offset="0.2229" />
                <stop
                   id="stop20525"
                   style="stop-color:#de083e;stop-opacity:1"
                   offset="0.30410001" />
                <stop
                   id="stop20527"
                   style="stop-color:#ed0335;stop-opacity:1"
                   offset="0.39129999" />
                <stop
                   id="stop20529"
                   style="stop-color:#f60030;stop-opacity:1"
                   offset="0.48840001" />
                <stop
                   id="stop20531"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20533"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 139.689,18.299 0.077,0.117 0.192,0.307 0.267,0.497 0.344,0.613 0.386,0.727 0.382,0.806 0.346,0.92 0.303,0.918 0.228,0.959 0.079,0.92 -0.042,0.917 -0.192,0.842 -0.422,0.768 -0.651,0.687 -0.919,0.535 -1.189,0.384 0.193,-0.578 0.117,-0.611 0.113,-0.611 0.076,-0.689 0.039,-0.689 V 25.31 l -0.037,-0.69 -0.037,-0.729 -0.076,-0.729 -0.074,-0.725 -0.116,-0.69 -0.152,-0.651 -0.113,-0.651 -0.154,-0.575 -0.188,-0.574 -0.155,-0.498 0.191,-0.075 0.154,-0.04 0.19,-0.076 0.156,-0.036 0.153,-0.077 0.15,-0.039 0.191,-0.078 0.19,-0.076 z"
               id="path449-2"
               style="fill:url(#linearGradient3773-4)" />
            <path
               d="m 138.389,18.835 0.534,2.108 0.382,1.914 0.189,1.646 0.037,1.455 -0.077,1.264 -0.23,1.072 -0.307,0.92 -0.347,0.764 -0.46,0.613 -0.497,0.496 -0.498,0.347 -0.495,0.267 -0.54,0.191 -0.459,0.076 -0.42,0.037 h -0.384 l 0.229,-0.613 0.229,-0.612 0.192,-0.688 0.154,-0.689 0.152,-0.767 0.118,-0.764 0.116,-0.767 0.075,-0.803 0.041,-0.806 0.001,-0.843 -0.041,-0.804 -0.073,-0.843 -0.114,-0.804 -0.155,-0.843 -0.188,-0.766 -0.229,-0.805 0.457,-0.154 0.463,-0.152 0.422,-0.152 0.418,-0.115 0.348,-0.113 0.381,-0.115 0.306,-0.076 0.27,-0.077 z"
               id="path451-0"
               style="fill:url(#linearGradient3775-0)" />
            <path
               d="m 135.285,19.792 0.231,0.765 0.227,0.959 0.155,1.073 0.072,1.186 0.041,1.303 -0.002,1.301 -0.116,1.301 -0.192,1.267 -0.271,1.187 -0.345,1.109 -0.499,0.957 -0.572,0.766 -0.731,0.574 -0.84,0.304 -0.96,0.04 -1.108,-0.307 0.422,-0.691 0.421,-0.727 0.347,-0.766 0.307,-0.727 0.229,-0.803 0.231,-0.768 0.152,-0.805 0.154,-0.805 0.077,-0.804 0.038,-0.841 v -0.805 l -0.073,-0.842 -0.076,-0.842 -0.152,-0.806 -0.152,-0.845 -0.229,-0.803 0.383,-0.152 0.458,-0.152 0.461,-0.153 0.46,-0.153 0.46,-0.151 0.382,-0.153 0.346,-0.117 0.267,-0.074 z"
               id="path453-2"
               style="fill:url(#linearGradient3777-8)" />
            <path
               d="m 125.546,35.674 1.036,0.08 0.997,-0.154 0.879,-0.381 0.805,-0.535 0.766,-0.73 0.652,-0.879 0.536,-0.994 0.499,-1.109 0.384,-1.188 0.309,-1.266 0.192,-1.3 0.078,-1.302 0.001,-1.301 -0.114,-1.303 -0.229,-1.265 -0.343,-1.188 -0.422,0.152 -0.425,0.154 -0.456,0.114 -0.463,0.152 -0.458,0.154 -0.497,0.153 -0.46,0.152 -0.497,0.152 v 0.804 l -0.001,0.879 -0.04,0.999 -0.039,1.033 -0.039,1.033 -0.038,1.072 -0.116,1.11 -0.113,1.032 -0.156,1.035 -0.154,0.961 -0.233,0.919 -0.268,0.806 -0.308,0.687 -0.384,0.577 -0.421,0.419 -0.461,0.267 z"
               id="path455-3"
               style="fill:url(#linearGradient3779-4)" />
            <defs
               id="defs457-2">
              <linearGradient
                 x1="-3738.23"
                 y1="-3453.355"
                 x2="-3733.0664"
                 y2="-3424.071"
                 id="linearGradient20540"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
                <stop
                   id="stop20542"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20544"
                   style="stop-color:#6f1182;stop-opacity:1"
                   offset="0.0752" />
                <stop
                   id="stop20546"
                   style="stop-color:#831380;stop-opacity:1"
                   offset="0.1935" />
                <stop
                   id="stop20548"
                   style="stop-color:#a3157b;stop-opacity:1"
                   offset="0.33989999" />
                <stop
                   id="stop20550"
                   style="stop-color:#d11975;stop-opacity:1"
                   offset="0.50880003" />
                <stop
                   id="stop20552"
                   style="stop-color:#f21b71;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20554"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 128.277,22.083 -0.384,0.153 -0.383,0.114 -0.343,0.115 -0.386,0.077 -0.382,0.114 -0.347,0.113 -0.384,0.116 -0.38,0.153 -0.077,0.766 -0.041,0.84 -0.039,0.92 -0.038,0.958 -0.001,0.958 -0.001,1.031 -0.04,1.037 -0.039,0.994 -0.076,0.997 -0.115,0.994 -0.193,0.919 -0.191,0.844 -0.305,0.802 -0.346,0.727 -0.422,0.616 -0.536,0.496 1.108,-0.268 0.919,-0.383 0.767,-0.533 0.651,-0.614 0.537,-0.729 0.423,-0.839 0.306,-0.919 0.232,-0.959 0.156,-1.072 0.112,-1.11 0.039,-1.15 0.042,-1.225 0.037,-1.225 0.039,-1.264 0.001,-1.264 0.078,-1.303 z"
               id="path474-4"
               style="fill:url(#AIgd35-5)" />
            <defs
               id="defs476-2">
              <linearGradient
                 x1="-3716.3066"
                 y1="-3509.6641"
                 x2="-3713.6802"
                 y2="-3491.7153"
                 id="linearGradient20558"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20560"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20562"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0.0006" />
                <stop
                   id="stop20564"
                   style="stop-color:#8d0f6d;stop-opacity:1"
                   offset="0.072" />
                <stop
                   id="stop20566"
                   style="stop-color:#ad0d5a;stop-opacity:1"
                   offset="0.1459" />
                <stop
                   id="stop20568"
                   style="stop-color:#c80a4a;stop-opacity:1"
                   offset="0.2229" />
                <stop
                   id="stop20570"
                   style="stop-color:#de083e;stop-opacity:1"
                   offset="0.30410001" />
                <stop
                   id="stop20572"
                   style="stop-color:#ed0335;stop-opacity:1"
                   offset="0.39129999" />
                <stop
                   id="stop20574"
                   style="stop-color:#f60030;stop-opacity:1"
                   offset="0.48840001" />
                <stop
                   id="stop20576"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20578"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 118.116,38.426 1.531,-0.074 1.304,-0.305 1.07,-0.497 0.882,-0.651 0.689,-0.842 0.502,-0.958 0.419,-1.071 0.27,-1.188 0.154,-1.226 0.114,-1.261 0.041,-1.305 0.001,-1.262 10e-4,-1.305 0.001,-1.223 0.076,-1.15 0.078,-1.071 -0.421,0.114 -0.383,0.113 -0.343,0.117 -0.387,0.113 -0.382,0.113 -0.343,0.115 -0.384,0.077 -0.423,0.114 0.039,0.113 0.075,0.269 0.078,0.423 0.114,0.537 0.074,0.688 0.078,0.768 0.039,0.881 -0.04,0.996 -0.114,1.035 -0.195,1.145 -0.347,1.189 -0.42,1.225 -0.614,1.265 -0.766,1.339 -0.921,1.3 -1.15,1.339 z"
               id="path499-3"
               style="fill:url(#linearGradient3781-9)" />
            <path
               d="m 112.905,40.07 1.035,0.191 1.035,-0.073 0.995,-0.346 0.996,-0.537 0.956,-0.725 0.92,-0.881 0.844,-1.07 0.769,-1.188 0.649,-1.265 0.576,-1.378 0.462,-1.456 0.309,-1.489 0.192,-1.496 0.041,-1.531 -0.152,-1.454 -0.308,-1.456 -3.638,1.146 0.037,0.613 0.037,0.729 -0.038,0.801 -0.08,0.92 -0.112,0.958 -0.192,1.034 -0.192,1.072 -0.308,1.109 -0.347,1.109 -0.421,1.073 -0.461,1.071 -0.575,1.035 -0.612,0.995 -0.729,0.919 -0.805,0.841 -0.883,0.727 z"
               id="path501-0"
               style="fill:url(#linearGradient3783-5)" />
            <defs
               id="defs503-4">
              <linearGradient
                 x1="-3716.5049"
                 y1="-3512.9565"
                 x2="-3712.3662"
                 y2="-3473.3286"
                 id="linearGradient20583"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20585"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20587"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0.0006" />
                <stop
                   id="stop20589"
                   style="stop-color:#8d0f6d;stop-opacity:1"
                   offset="0.072" />
                <stop
                   id="stop20591"
                   style="stop-color:#ad0d5a;stop-opacity:1"
                   offset="0.1459" />
                <stop
                   id="stop20593"
                   style="stop-color:#c80a4a;stop-opacity:1"
                   offset="0.2229" />
                <stop
                   id="stop20595"
                   style="stop-color:#de083e;stop-opacity:1"
                   offset="0.30410001" />
                <stop
                   id="stop20597"
                   style="stop-color:#ed0335;stop-opacity:1"
                   offset="0.39129999" />
                <stop
                   id="stop20599"
                   style="stop-color:#f60030;stop-opacity:1"
                   offset="0.48840001" />
                <stop
                   id="stop20601"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20603"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 118.662,24.987 -0.573,0.189 -0.729,0.191 -0.807,0.268 -0.84,0.229 -0.806,0.27 -0.804,0.227 -0.689,0.191 -0.537,0.115 -0.076,0.881 -0.042,0.955 -0.075,0.959 -0.038,0.995 -0.117,0.995 -0.077,1.037 -0.115,0.994 -0.153,0.996 -0.19,0.956 -0.232,0.921 -0.309,0.916 -0.344,0.842 -0.422,0.807 -0.498,0.688 -0.536,0.65 -0.65,0.576 0.766,0.114 0.803,-0.038 0.804,-0.19 0.805,-0.343 0.804,-0.5 0.807,-0.612 0.768,-0.763 0.766,-0.958 0.689,-1.034 0.611,-1.227 0.578,-1.339 0.495,-1.528 0.388,-1.65 0.307,-1.758 0.194,-1.955 0.077,-2.066 z"
               id="path526-0"
               style="fill:url(#linearGradient3785-9)" />
            <path
               d="m 103.98,41.593 1.725,0.081 1.455,-0.154 1.265,-0.418 0.998,-0.653 0.841,-0.802 0.691,-0.958 0.497,-1.072 0.386,-1.224 0.308,-1.225 0.19,-1.343 0.116,-1.3 0.117,-1.302 0.038,-1.303 0.078,-1.188 0.075,-1.11 0.117,-0.995 -0.535,0.114 -0.463,0.115 -0.419,0.153 -0.418,0.112 -0.463,0.117 -0.422,0.111 -0.496,0.154 -0.576,0.151 -0.116,1.038 -0.112,0.992 -0.116,0.996 -0.156,0.955 -0.116,0.961 -0.153,0.918 -0.189,0.879 -0.194,0.881 -0.269,0.844 -0.308,0.841 -0.382,0.805 -0.422,0.806 -0.536,0.801 -0.576,0.767 -0.689,0.728 -0.77,0.726 z"
               id="path528-8"
               style="fill:url(#linearGradient3787-4)" />
            <path
               d="m 99.349,42.433 1.532,0.078 1.34,-0.192 1.188,-0.418 1.036,-0.65 0.88,-0.805 0.766,-0.957 0.615,-1.107 0.537,-1.188 0.458,-1.227 0.347,-1.3 0.269,-1.266 0.194,-1.299 0.19,-1.226 0.116,-1.15 0.116,-1.073 0.079,-0.919 -0.539,0.117 -0.459,0.112 -0.42,0.115 -0.423,0.077 -0.38,0.113 -0.425,0.074 -0.495,0.152 -0.576,0.115 -0.192,1.496 -0.229,1.417 -0.27,1.301 -0.269,1.226 -0.31,1.109 -0.345,1.071 -0.383,0.919 -0.384,0.883 -0.383,0.803 -0.425,0.727 -0.459,0.613 -0.422,0.573 -0.459,0.536 -0.461,0.42 -0.498,0.383 -0.459,0.345 z"
               id="path530-0"
               style="fill:url(#linearGradient3789-0)" />
            <defs
               id="defs532-82">
              <linearGradient
                 x1="-3711.1768"
                 y1="-3514.0366"
                 x2="-3709.7402"
                 y2="-3493.4663"
                 id="linearGradient20609"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20611"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20613"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0.0006" />
                <stop
                   id="stop20615"
                   style="stop-color:#8d0f6d;stop-opacity:1"
                   offset="0.072" />
                <stop
                   id="stop20617"
                   style="stop-color:#ad0d5a;stop-opacity:1"
                   offset="0.1459" />
                <stop
                   id="stop20619"
                   style="stop-color:#c80a4a;stop-opacity:1"
                   offset="0.2229" />
                <stop
                   id="stop20621"
                   style="stop-color:#de083e;stop-opacity:1"
                   offset="0.30410001" />
                <stop
                   id="stop20623"
                   style="stop-color:#ed0335;stop-opacity:1"
                   offset="0.39129999" />
                <stop
                   id="stop20625"
                   style="stop-color:#f60030;stop-opacity:1"
                   offset="0.48840001" />
                <stop
                   id="stop20627"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20629"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 94.98,43.004 1.457,0.078 1.302,-0.189 1.151,-0.424 1.071,-0.611 0.881,-0.802 0.805,-0.919 0.69,-1.072 0.614,-1.146 0.535,-1.189 0.422,-1.263 0.347,-1.264 0.308,-1.262 0.271,-1.188 0.192,-1.149 0.152,-1.031 0.155,-0.922 -0.459,0.076 -0.46,0.116 -0.462,0.114 -0.459,0.115 -0.462,0.115 -0.458,0.112 -0.46,0.114 -0.497,0.117 -0.038,0.725 -0.116,0.805 -0.153,0.843 -0.269,0.918 -0.27,0.995 -0.382,0.957 -0.385,1.033 -0.422,0.998 -0.499,0.996 -0.537,0.957 -0.534,0.879 -0.577,0.84 -0.574,0.806 -0.614,0.69 -0.649,0.572 -0.617,0.459 z"
               id="path555-8"
               style="fill:url(#AIgd41-9)" />
            <defs
               id="defs557-8">
              <linearGradient
                 x1="-3718.4951"
                 y1="-3510.1016"
                 x2="-3716.7441"
                 y2="-3482.9595"
                 id="linearGradient20633"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20635"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20637"
                   style="stop-color:#681083;stop-opacity:1"
                   offset="0.0006" />
                <stop
                   id="stop20639"
                   style="stop-color:#8d0f6d;stop-opacity:1"
                   offset="0.072" />
                <stop
                   id="stop20641"
                   style="stop-color:#ad0d5a;stop-opacity:1"
                   offset="0.1459" />
                <stop
                   id="stop20643"
                   style="stop-color:#c80a4a;stop-opacity:1"
                   offset="0.2229" />
                <stop
                   id="stop20645"
                   style="stop-color:#de083e;stop-opacity:1"
                   offset="0.30410001" />
                <stop
                   id="stop20647"
                   style="stop-color:#ed0335;stop-opacity:1"
                   offset="0.39129999" />
                <stop
                   id="stop20649"
                   style="stop-color:#f60030;stop-opacity:1"
                   offset="0.48840001" />
                <stop
                   id="stop20651"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20653"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 90.197,43.881 1.49,0.193 1.38,-0.191 1.264,-0.496 1.15,-0.766 1.073,-0.955 0.921,-1.148 0.84,-1.301 0.77,-1.341 0.613,-1.415 0.537,-1.381 0.46,-1.302 0.384,-1.262 0.23,-1.074 0.192,-0.88 0.114,-0.65 0.001,-0.381 -0.573,0.111 -0.537,0.115 -0.535,0.152 -0.536,0.115 -0.536,0.152 -0.5,0.113 -0.497,0.115 -0.499,0.078 -0.191,0.651 -0.19,0.765 -0.229,0.879 -0.271,0.996 -0.308,1.035 -0.343,1.071 -0.384,1.069 -0.424,1.114 -0.461,1.07 -0.497,0.995 -0.537,0.959 -0.574,0.842 -0.653,0.725 -0.65,0.574 -0.728,0.422 -0.765,0.229 z"
               id="path580-8"
               style="fill:url(#linearGradient3791-0)" />
            <path
               d="m 86.712,43.688 1.377,0.307 1.223,0.001 1.113,-0.267 1.034,-0.535 0.882,-0.729 0.805,-0.881 0.727,-1.068 0.652,-1.15 0.539,-1.226 0.498,-1.261 0.384,-1.265 0.385,-1.227 0.307,-1.147 0.231,-1.035 0.23,-0.918 0.189,-0.727 -0.419,0.076 -0.423,0.038 -0.38,0.075 -0.347,0.076 -0.384,0.076 -0.346,0.078 -0.305,0.074 -0.345,0.041 -0.118,0.879 -0.189,0.919 -0.232,0.917 -0.228,0.883 -0.309,0.918 -0.347,0.881 -0.382,0.844 -0.461,0.842 -0.46,0.842 -0.537,0.804 -0.615,0.765 -0.61,0.688 -0.729,0.69 -0.727,0.611 -0.806,0.574 -0.879,0.535 z"
               id="path582-5"
               style="fill:url(#linearGradient3793-6)" />
            <path
               d="m 82.345,44.374 1.147,0.002 1.112,-0.115 1.07,-0.268 1.037,-0.384 0.956,-0.533 0.959,-0.65 0.842,-0.763 0.841,-0.842 0.73,-0.96 0.69,-1.032 0.614,-1.15 0.573,-1.186 0.461,-1.264 0.385,-1.34 0.347,-1.379 0.23,-1.414 -0.498,0.113 -0.499,0.076 -0.536,0.115 -0.496,0.074 -0.497,0.078 -0.459,0.112 -0.5,0.077 -0.459,0.115 -0.231,0.805 -0.191,0.842 -0.231,0.805 -0.194,0.803 -0.23,0.804 -0.228,0.804 -0.307,0.766 -0.346,0.804 -0.42,0.767 -0.463,0.803 -0.576,0.766 -0.688,0.766 -0.768,0.729 -0.918,0.765 -1.073,0.766 -1.188,0.726 z"
               id="path584-3"
               style="fill:url(#linearGradient3795-0)" />
            <path
               d="m 76.14,45.095 1.495,0.118 1.454,-0.076 1.34,-0.229 1.266,-0.382 1.187,-0.497 1.112,-0.649 1.033,-0.768 0.918,-0.917 0.844,-0.955 0.767,-1.073 0.693,-1.148 0.573,-1.222 0.496,-1.304 0.425,-1.34 0.307,-1.377 0.233,-1.381 -0.423,0.076 -0.46,0.117 -0.456,0.074 -0.461,0.075 -0.459,0.078 -0.5,0.114 -0.497,0.076 -0.5,0.115 -0.152,0.955 -0.23,0.957 -0.31,0.96 -0.383,0.917 -0.457,0.918 -0.502,0.918 -0.574,0.882 -0.648,0.843 -0.691,0.844 -0.767,0.762 -0.808,0.727 -0.879,0.689 -0.921,0.611 -0.995,0.575 -0.997,0.497 -1.072,0.419 z"
               id="path586-93"
               style="fill:url(#linearGradient3797-7)" />
            <path
               d="m 72.732,45.475 1.264,-0.075 1.226,-0.189 1.228,-0.306 1.186,-0.458 1.112,-0.536 1.109,-0.648 1.034,-0.729 0.958,-0.842 0.881,-0.917 0.843,-0.993 0.73,-1.076 0.65,-1.109 0.536,-1.184 0.46,-1.226 0.348,-1.267 0.229,-1.299 -0.419,0.074 -0.385,0.037 -0.346,0.039 -0.343,0.039 -0.346,0.037 -0.382,0.077 -0.456,0.076 -0.539,0.075 -0.537,1.112 -0.459,1.031 -0.46,0.997 -0.422,0.919 -0.46,0.881 -0.424,0.805 -0.461,0.764 -0.498,0.727 -0.537,0.729 -0.613,0.649 -0.688,0.69 -0.765,0.611 -0.884,0.65 -0.996,0.611 -1.108,0.612 -1.265,0.61 z"
               id="path588-2"
               style="fill:url(#linearGradient3799-6)" />
            <path
               d="m 66.604,45.855 1.877,0.077 1.763,-0.073 1.57,-0.267 1.455,-0.422 1.34,-0.572 1.187,-0.691 1.113,-0.801 0.993,-0.92 0.921,-0.993 0.844,-1.072 0.729,-1.109 0.688,-1.189 0.652,-1.184 0.577,-1.187 0.538,-1.227 0.496,-1.187 -0.343,0.036 -0.461,0.078 -0.573,0.076 -0.575,0.076 -0.613,0.115 -0.537,0.076 -0.456,0.076 -0.347,0.035 -0.46,1.074 -0.499,1.074 -0.577,0.994 -0.573,0.955 -0.652,0.881 -0.688,0.879 -0.729,0.804 -0.804,0.807 -0.804,0.727 -0.885,0.688 -0.917,0.688 -0.96,0.613 -0.995,0.572 -1.072,0.535 -1.072,0.496 -1.149,0.46 z"
               id="path590-7"
               style="fill:url(#linearGradient3801-3)" />
            <path
               d="M 62.966,46.387 64,46.35 l 1.071,-0.152 1.15,-0.269 1.186,-0.419 1.188,-0.495 1.189,-0.613 1.188,-0.726 1.187,-0.803 1.149,-0.918 1.111,-0.957 1.035,-1.07 0.999,-1.15 0.879,-1.188 0.804,-1.262 0.691,-1.34 0.576,-1.38 -0.575,0.079 -0.575,0.074 -0.611,0.037 -0.612,0.077 -0.536,0.037 -0.461,0.077 -0.382,0.076 -0.192,0.115 -0.69,0.535 -0.689,0.575 -0.729,0.688 -0.729,0.688 -0.727,0.766 -0.767,0.802 -0.767,0.844 -0.768,0.845 -0.766,0.879 -0.804,0.842 -0.805,0.842 -0.845,0.84 -0.842,0.843 -0.845,0.763 -0.838,0.768 -0.882,0.688 z"
               id="path592-3"
               style="fill:url(#linearGradient3803-1)" />
            <path
               d="m 57.375,46.383 0.997,0.654 1.032,0.268 1.034,10e-4 1.073,-0.268 1.071,-0.536 1.073,-0.729 1.111,-0.916 1.11,-1.033 1.112,-1.188 1.148,-1.225 1.189,-1.301 1.188,-1.299 1.188,-1.264 1.226,-1.264 1.228,-1.148 1.226,-1.031 h -0.425 l -0.494,0.074 -0.576,0.038 -0.573,0.116 -0.613,0.079 -0.612,0.113 -0.572,0.115 -0.5,0.075 -0.956,0.88 -0.957,0.88 -0.923,0.919 -0.919,0.919 -0.881,0.916 -0.883,0.921 -0.88,0.92 -0.845,0.84 -0.844,0.84 -0.842,0.768 -0.805,0.688 -0.804,0.613 -0.805,0.535 -0.767,0.459 -0.766,0.343 -0.767,0.229 z"
               id="path594-7"
               style="fill:url(#linearGradient3805-7)" />
            <path
               d="m 53.046,46.879 1.572,0.001 1.492,-0.151 1.342,-0.385 1.304,-0.494 1.187,-0.614 1.109,-0.765 1.075,-0.84 0.995,-0.92 0.997,-0.994 0.956,-1.033 0.921,-1.035 0.959,-1.07 0.959,-1.07 0.994,-1.034 1.035,-0.957 1.072,-0.918 -0.382,0.04 -0.458,0.037 -0.577,0.074 -0.572,0.041 -0.577,0.073 -0.459,0.038 -0.382,0.041 -0.229,-0.001 -0.651,0.151 -0.652,0.306 -0.649,0.423 -0.692,0.573 -0.689,0.687 -0.729,0.805 -0.766,0.844 -0.769,0.915 -0.88,0.958 -0.883,0.955 -0.997,0.996 -1.032,0.959 -1.111,0.955 -1.188,0.88 -1.264,0.802 -1.381,0.729 z"
               id="path596-4"
               style="fill:url(#linearGradient3807-4)" />
            <path
               d="m 138.274,15.35 v -0.153 l 0.04,-0.42 0.038,-0.649 0.04,-0.807 0.039,-0.957 -0.037,-1.033 -0.038,-1.072 -0.111,-1.111 -0.229,-1.033 -0.309,-0.996 -0.38,-0.882 -0.572,-0.728 -0.654,-0.537 -0.843,-0.307 -1.034,-0.039 -1.186,0.306 0.385,0.384 0.343,0.459 0.345,0.574 0.306,0.613 0.305,0.689 0.27,0.689 0.264,0.767 0.271,0.804 0.228,0.767 0.19,0.806 0.194,0.803 0.188,0.766 0.155,0.768 0.152,0.727 0.114,0.65 0.113,0.613 0.19,-0.037 0.154,-0.037 0.189,-0.078 0.155,-0.037 0.151,-0.079 0.155,-0.075 0.192,-0.037 0.226,-0.078 z"
               id="path598-9"
               style="fill:url(#linearGradient3809-6)" />
            <defs
               id="defs600-4">
              <linearGradient
                 x1="-3690.9155"
                 y1="-3526.2993"
                 x2="-3702.7354"
                 y2="-3558.2568"
                 id="linearGradient20666"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20668"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20670"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20672"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20674"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20676"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20678"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20680"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20682"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 136.86,15.925 -0.497,-2.489 -0.535,-2.108 -0.535,-1.801 -0.532,-1.492 -0.539,-1.188 -0.534,-0.958 -0.533,-0.689 -0.499,-0.497 -0.536,-0.347 -0.458,-0.153 -0.502,-0.039 -0.42,0.078 -0.419,0.152 -0.382,0.191 -0.348,0.229 -0.306,0.23 0.536,0.497 0.533,0.573 0.462,0.538 0.494,0.611 0.424,0.615 0.422,0.648 0.382,0.652 0.344,0.691 0.344,0.727 0.306,0.766 0.307,0.768 0.268,0.805 0.227,0.842 0.23,0.842 0.227,0.882 0.194,0.919 0.457,-0.077 0.345,-0.036 0.232,-0.077 0.153,-0.077 0.151,-0.037 0.156,-0.076 0.153,-0.04 0.229,-0.075 z"
               id="path619-8"
               style="fill:url(#linearGradient3811-8)" />
            <path
               d="m 134.944,16.651 -0.113,-0.918 -0.194,-1.035 -0.305,-1.15 -0.379,-1.226 -0.5,-1.264 -0.571,-1.227 -0.611,-1.187 -0.688,-1.111 -0.729,-0.996 -0.765,-0.843 -0.803,-0.65 -0.842,-0.425 -0.881,-0.152 -0.882,0.152 -0.842,0.499 -0.882,0.878 0.688,0.498 0.65,0.576 0.613,0.574 0.574,0.576 0.574,0.611 0.496,0.689 0.459,0.691 0.42,0.688 0.423,0.769 0.343,0.767 0.345,0.805 0.267,0.842 0.267,0.879 0.193,0.92 0.189,0.959 0.155,0.994 0.416,-0.114 0.461,-0.152 0.499,-0.153 0.498,-0.191 0.461,-0.189 0.421,-0.154 0.344,-0.151 0.23,-0.077 z"
               id="path621-2"
               style="fill:url(#linearGradient3813-4)" />
            <path
               d="m 120.017,6.607 0.919,-0.612 0.92,-0.344 0.957,-0.115 0.919,0.115 0.958,0.307 0.919,0.5 0.882,0.689 0.843,0.805 0.762,0.919 0.766,1.073 0.65,1.188 0.572,1.226 0.496,1.305 0.384,1.376 0.306,1.38 0.151,1.416 -0.46,0.115 -0.459,0.116 -0.46,0.15 -0.46,0.154 -0.497,0.191 -0.499,0.113 -0.457,0.154 -0.498,0.075 -0.346,-0.88 -0.305,-0.959 -0.383,-0.957 -0.348,-0.957 -0.379,-0.996 -0.419,-0.998 -0.423,-0.956 -0.421,-0.918 -0.456,-0.884 -0.499,-0.805 -0.533,-0.766 -0.539,-0.651 -0.609,-0.575 -0.615,-0.459 -0.648,-0.346 -0.69,-0.19 z"
               id="path623-7"
               style="fill:url(#linearGradient3815-6)" />
            <path
               d="m 115.804,7.75 1.455,-0.648 1.302,-0.344 1.149,-0.038 1.034,0.193 0.919,0.421 0.806,0.65 0.724,0.807 0.65,0.957 0.575,1.072 0.495,1.188 0.5,1.229 0.457,1.225 0.457,1.264 0.421,1.264 0.459,1.188 0.497,1.111 -0.421,0.037 -0.384,0.115 -0.383,0.113 -0.385,0.152 -0.381,0.118 -0.384,0.151 -0.421,0.114 -0.422,0.074 -0.038,-0.151 -0.038,-0.383 -0.114,-0.498 -0.114,-0.689 -0.189,-0.803 -0.27,-0.92 -0.306,-0.996 -0.42,-1.034 -0.494,-1.034 -0.574,-1.035 -0.728,-1.035 -0.803,-0.958 -0.96,-0.918 -1.07,-0.767 -1.228,-0.691 -1.375,-0.5 z"
               id="path625-04"
               style="fill:url(#linearGradient3817-7)" />
            <path
               d="m 110.366,8.552 0.882,-0.651 0.997,-0.42 1.069,-0.153 1.072,0.04 1.149,0.229 1.148,0.461 1.108,0.615 1.111,0.768 1.07,0.956 0.997,1.075 0.878,1.225 0.805,1.342 0.687,1.416 0.537,1.533 0.342,1.57 0.19,1.687 -3.945,1.029 -0.228,-0.649 -0.307,-0.77 -0.306,-0.803 -0.382,-0.881 -0.461,-0.92 -0.457,-0.956 -0.537,-0.961 -0.573,-0.956 -0.652,-0.957 -0.725,-0.92 -0.766,-0.842 -0.803,-0.808 -0.878,-0.728 -0.959,-0.613 -0.996,-0.537 -1.07,-0.421 z"
               id="path627-0"
               style="fill:url(#linearGradient3819-6)" />
            <path
               d="m 120.502,21.387 -0.572,0.115 -0.727,0.152 -0.729,0.23 -0.808,0.229 -0.764,0.267 -0.729,0.191 -0.649,0.189 -0.536,0.152 -0.382,-0.957 -0.421,-0.995 -0.422,-0.996 -0.42,-1.036 -0.421,-1.032 -0.458,-0.997 -0.498,-0.995 -0.497,-0.997 -0.533,-0.918 -0.573,-0.845 -0.614,-0.804 -0.651,-0.727 -0.65,-0.652 -0.728,-0.537 -0.804,-0.423 -0.804,-0.306 0.692,-0.459 0.764,-0.344 0.806,-0.23 0.88,-0.075 0.918,0.076 0.959,0.231 0.957,0.383 0.992,0.576 0.999,0.728 0.993,0.92 0.995,1.149 0.954,1.304 0.919,1.532 0.917,1.723 0.843,1.992 0.802,2.184 z"
               id="path629-5"
               style="fill:url(#linearGradient3821-4)" />
            <path
               d="m 101.288,11.34 1.571,-0.841 1.415,-0.498 1.304,-0.114 1.187,0.193 1.032,0.458 0.996,0.691 0.841,0.883 0.805,1.073 0.688,1.188 0.649,1.265 0.573,1.341 0.534,1.34 0.536,1.302 0.498,1.265 0.458,1.148 0.456,1.035 -0.534,0.076 -0.459,0.112 -0.422,0.079 -0.422,0.114 -0.421,0.114 -0.459,0.115 -0.498,0.076 -0.572,0.112 -0.5,-1.033 -0.458,-1.036 -0.46,-0.994 -0.458,-0.958 -0.459,-0.958 -0.495,-0.88 -0.5,-0.881 -0.495,-0.806 -0.575,-0.807 -0.61,-0.727 -0.612,-0.688 -0.688,-0.652 -0.769,-0.615 -0.801,-0.536 -0.92,-0.498 -0.956,-0.46 z"
               id="path631-0"
               style="fill:url(#linearGradient3823-8)" />
            <path
               d="m 96.537,12.715 1.419,-0.765 1.339,-0.383 1.265,-0.075 1.225,0.191 1.111,0.461 1.069,0.689 0.996,0.844 0.921,0.998 0.841,1.149 0.802,1.187 0.726,1.227 0.652,1.264 0.611,1.266 0.537,1.148 0.455,1.111 0.423,0.957 -0.574,0.113 -0.5,0.115 -0.46,0.113 -0.421,0.076 -0.458,0.115 -0.461,0.115 -0.536,0.076 -0.613,0.115 -0.688,-1.533 -0.688,-1.417 -0.646,-1.302 -0.651,-1.188 -0.614,-1.071 -0.573,-0.961 -0.61,-0.84 -0.574,-0.807 -0.612,-0.651 -0.613,-0.575 -0.611,-0.498 -0.65,-0.421 -0.653,-0.308 -0.685,-0.269 -0.731,-0.155 -0.765,-0.113 z"
               id="path633-4"
               style="fill:url(#linearGradient3825-6)" />
            <path
               d="m 92.937,13.747 1.378,-0.65 1.307,-0.308 1.222,10e-4 1.19,0.233 1.07,0.458 1.033,0.654 0.956,0.844 0.92,0.957 0.802,1.072 0.766,1.148 0.726,1.188 0.613,1.188 0.609,1.189 0.5,1.15 0.456,1.033 0.421,0.959 -0.459,0.113 -0.42,0.113 -0.424,0.076 -0.383,0.116 -0.421,0.077 -0.42,0.075 -0.462,0.113 -0.496,0.077 -0.231,-0.765 -0.342,-0.845 -0.42,-0.842 -0.497,-0.919 -0.535,-0.919 -0.651,-0.921 -0.649,-0.92 -0.728,-0.92 -0.765,-0.841 -0.805,-0.846 -0.803,-0.766 -0.804,-0.652 -0.843,-0.613 -0.805,-0.498 -0.802,-0.383 -0.806,-0.23 z"
               id="path635-8"
               style="fill:url(#linearGradient3827-5)" />
            <path
               d="m 88.608,14.852 1.417,-0.762 1.38,-0.345 1.379,0.039 1.301,0.385 1.264,0.612 1.226,0.879 1.149,1.038 1.069,1.147 0.995,1.229 0.881,1.264 0.8,1.227 0.65,1.187 0.536,1.036 0.422,0.879 0.23,0.652 0.113,0.383 -0.574,0.115 -0.498,0.113 -0.498,0.115 -0.5,0.115 -0.496,0.115 -0.459,0.074 -0.499,0.077 -0.497,0.076 -0.344,-0.651 -0.384,-0.804 -0.458,-0.882 -0.537,-0.921 -0.571,-1.033 -0.614,-1.034 -0.646,-0.997 -0.691,-1.034 -0.727,-0.959 -0.767,-0.881 -0.802,-0.804 -0.803,-0.652 -0.844,-0.537 -0.844,-0.345 -0.878,-0.152 -0.882,0.035 z"
               id="path637-3"
               style="fill:url(#linearGradient3829-3)" />
            <path
               d="m 85.468,16.077 1.266,-0.842 1.224,-0.459 1.149,-0.113 1.149,0.19 1.071,0.461 1.033,0.692 0.958,0.842 0.915,1.035 0.844,1.113 0.805,1.184 0.727,1.229 0.687,1.225 0.574,1.15 0.535,1.073 0.421,0.918 0.383,0.766 -0.46,0.077 -0.382,0.114 -0.344,0.115 -0.308,0.113 -0.347,0.114 -0.305,0.115 -0.308,0.078 -0.343,0.073 -0.344,-0.955 -0.421,-0.958 -0.422,-0.921 -0.46,-0.918 -0.537,-0.919 -0.531,-0.844 -0.613,-0.844 -0.65,-0.805 -0.689,-0.767 -0.764,-0.688 -0.765,-0.614 -0.844,-0.574 -0.919,-0.5 -0.919,-0.421 -0.996,-0.308 -1.071,-0.229 z"
               id="path639-0"
               style="fill:url(#linearGradient3831-8)" />
            <path
               d="m 81.483,16.993 1.113,-0.422 1.109,-0.266 1.148,-0.077 1.074,0.078 1.109,0.231 1.032,0.345 1.034,0.536 1.034,0.652 0.956,0.768 0.918,0.92 0.881,0.996 0.842,1.112 0.802,1.226 0.689,1.34 0.688,1.418 0.571,1.491 -0.498,0.077 -0.495,0.076 -0.501,0.115 -0.497,0.153 -0.496,0.115 -0.498,0.153 -0.497,0.115 -0.5,0.074 -0.343,-0.842 -0.343,-0.882 -0.347,-0.843 -0.342,-0.883 -0.422,-0.842 -0.419,-0.805 -0.501,-0.842 -0.534,-0.767 -0.649,-0.729 -0.688,-0.728 -0.805,-0.652 -0.88,-0.613 -0.996,-0.537 -1.11,-0.498 -1.261,-0.424 -1.381,-0.344 z"
               id="path641-1"
               style="fill:url(#linearGradient3833-8)" />
            <path
               d="m 75.815,18.329 1.455,-0.609 1.457,-0.385 1.34,-0.189 1.34,-0.037 1.265,0.191 1.226,0.346 1.147,0.498 1.111,0.652 0.992,0.805 0.994,0.919 0.884,1.036 0.84,1.15 0.764,1.264 0.652,1.34 0.611,1.381 0.535,1.491 -0.459,0.077 -0.46,0.076 -0.536,0.078 -0.501,0.074 -0.533,0.078 -0.538,0.074 -0.535,0.076 -0.535,0.076 -0.269,-1.072 -0.383,-0.994 -0.42,-0.996 L 86.726,24.77 86.151,23.889 85.5,23.046 84.812,22.241 84.046,21.512 83.204,20.823 82.288,20.249 81.329,19.71 80.334,19.251 79.263,18.905 78.151,18.598 77.005,18.407 75.817,18.329 z"
               id="path643-3"
               style="fill:url(#linearGradient3835-2)" />
            <path
               d="m 73.021,18.632 1.302,-0.19 1.262,-0.113 1.263,0.039 1.228,0.154 1.224,0.307 1.15,0.385 1.109,0.498 1.073,0.613 0.995,0.729 0.954,0.844 0.844,0.919 0.803,1.034 0.688,1.149 0.611,1.226 0.499,1.341 0.38,1.419 -0.46,0.035 -0.383,0.038 -0.382,0.077 -0.384,0.077 -0.384,0.074 -0.382,0.078 -0.46,0.114 -0.496,0.076 -0.651,-1.111 -0.613,-1.073 -0.532,-0.958 -0.5,-0.956 -0.535,-0.844 -0.498,-0.804 -0.497,-0.767 -0.572,-0.69 L 80.065,21.701 79.377,21.126 78.609,20.591 77.767,20.093 76.772,19.668 75.7,19.286 74.436,18.94 73.021,18.632 z"
               id="path645-0"
               style="fill:url(#linearGradient3837-4)" />
            <path
               d="m 66.933,19.432 1.914,-0.457 1.8,-0.268 1.646,-0.075 1.531,0.154 1.417,0.307 1.302,0.461 1.187,0.573 1.074,0.77 1.03,0.842 0.917,0.96 0.844,1.034 0.802,1.112 0.728,1.147 0.688,1.227 0.612,1.226 0.611,1.265 -0.307,0.037 -0.42,0.037 -0.459,0.115 -0.501,0.076 -0.496,0.115 -0.462,0.114 -0.419,0.036 -0.346,0.039 -0.571,-1.148 -0.613,-1.035 -0.689,-0.996 -0.726,-0.918 -0.766,-0.883 -0.805,-0.806 -0.879,-0.726 -0.919,-0.69 -0.956,-0.616 -0.996,-0.573 -1.034,-0.498 -1.07,-0.498 -1.111,-0.423 -1.147,-0.383 -1.189,-0.346 -1.222,-0.309 z"
               id="path647-9"
               style="fill:url(#linearGradient3839-0)" />
            <path
               d="m 63.295,19.811 1.068,-0.189 1.113,-0.037 1.225,0.038 1.263,0.192 1.267,0.271 1.3,0.384 1.303,0.497 1.302,0.614 1.3,0.729 1.224,0.845 1.186,0.92 1.147,1.035 1.035,1.149 0.956,1.225 0.841,1.342 0.728,1.455 -0.537,0.039 -0.533,0.076 -0.538,0.115 -0.536,0.113 -0.459,0.113 -0.385,0.117 -0.306,0.036 -0.19,-0.037 -0.769,-0.46 -0.763,-0.537 -0.804,-0.613 -0.843,-0.689 -0.843,-0.729 -0.878,-0.768 -0.92,-0.768 -0.916,-0.802 -0.959,-0.806 -0.956,-0.807 -0.995,-0.803 -0.996,-0.729 -1.033,-0.729 -0.995,-0.652 -1.071,-0.613 -1.031,-0.537 z"
               id="path649-5"
               style="fill:url(#linearGradient3841-9)" />
            <path
               d="m 58.197,21.262 0.958,-0.955 1.034,-0.572 1.074,-0.23 1.109,0.077 1.148,0.308 1.225,0.575 1.227,0.769 1.3,0.879 1.301,1.074 1.341,1.11 1.34,1.19 1.34,1.188 1.377,1.188 1.377,1.112 1.376,1.035 1.381,0.92 -0.421,0.074 -0.499,0.037 -0.612,0.041 -0.613,0.037 -0.648,0.037 h -0.653 -0.574 l -0.497,-0.002 -1.034,-0.766 -0.993,-0.804 -0.996,-0.808 -0.918,-0.842 -0.919,-0.805 -0.883,-0.807 -0.878,-0.805 -0.88,-0.767 -0.919,-0.688 -0.879,-0.651 -0.92,-0.575 -0.956,-0.5 L 61.417,21.914 60.383,21.569 59.31,21.377 58.2,21.26 z"
               id="path651-8"
               style="fill:url(#linearGradient3843-2)" />
            <defs
               id="defs653-7">
              <linearGradient
                 x1="-3772.377"
                 y1="-3509.7163"
                 x2="-3797.2949"
                 y2="-3537.6816"
                 id="linearGradient20702"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2070.8274,1900.0875)">
                <stop
                   id="stop20704"
                   style="stop-color:#4f0c81;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20706"
                   style="stop-color:#690c73;stop-opacity:1"
                   offset="0.0701" />
                <stop
                   id="stop20708"
                   style="stop-color:#9a0a5b;stop-opacity:1"
                   offset="0.20900001" />
                <stop
                   id="stop20710"
                   style="stop-color:#c20748;stop-opacity:1"
                   offset="0.33680001" />
                <stop
                   id="stop20712"
                   style="stop-color:#e0053a;stop-opacity:1"
                   offset="0.45120001" />
                <stop
                   id="stop20714"
                   style="stop-color:#f20032;stop-opacity:1"
                   offset="0.54809999" />
                <stop
                   id="stop20716"
                   style="stop-color:#fa002f;stop-opacity:1"
                   offset="0.61580002" />
                <stop
                   id="stop20718"
                   style="stop-color:#f7ee5f;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <path
               d="m 54.368,21.719 1.61,-0.381 1.493,-0.152 1.415,0.076 1.343,0.271 1.262,0.461 1.226,0.575 1.186,0.729 1.148,0.805 1.11,0.919 1.109,0.922 1.071,0.995 1.111,0.996 1.109,0.958 1.107,0.959 1.188,0.843 1.185,0.807 -0.38,0.037 -0.498,0.075 -0.576,0.078 -0.576,0.036 -0.572,0.079 -0.5,0.072 -0.38,0.041 -0.231,0.037 L 69.64,31.955 68.95,31.766 68.223,31.418 67.457,30.922 66.691,30.308 65.848,29.58 64.969,28.773 64.05,27.929 63.091,27.048 62.06,26.13 60.951,25.248 59.803,24.404 58.541,23.596 57.239,22.868 55.86,22.217 l -1.494,-0.5 z"
               id="path672-5"
               style="fill:url(#linearGradient3845-3)" />
            <path
               d="m 49.543,23.057 1.417,-0.805 1.495,-0.342 h 1.455 l 1.49,0.309 1.495,0.576 1.494,0.804 1.454,0.96 1.415,1.034 1.339,1.149 1.302,1.15 1.263,1.075 1.148,0.993 1.033,0.844 0.956,0.65 0.843,0.385 0.726,0.116 -0.61,0.077 -0.653,0.113 -0.727,0.113 -0.765,0.117 -0.767,0.074 -0.767,0.115 -0.728,0.038 -0.651,0.04 -1.07,-0.806 -0.958,-0.766 -0.879,-0.767 -0.84,-0.728 -0.767,-0.73 -0.726,-0.725 -0.767,-0.691 -0.726,-0.651 -0.729,-0.612 -0.804,-0.576 -0.841,-0.537 -0.919,-0.496 -0.996,-0.461 -1.071,-0.383 -1.226,-0.348 -1.34,-0.307 z"
               id="path674-5"
               style="fill:url(#linearGradient3847-2)" />
            <defs
               id="defs676-3">
              <linearGradient
                 x1="-3498.5225"
                 y1="4158.0396"
                 x2="-3482.3647"
                 y2="4209.6001"
                 id="linearGradient20723"
                 gradientUnits="userSpaceOnUse"
                 gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,-1982.8965,3021.3838)">
                <stop
                   id="stop20725"
                   style="stop-color:#d8e7eb;stop-opacity:1"
                   offset="0" />
                <stop
                   id="stop20727"
                   style="stop-color:#c9d9de;stop-opacity:1"
                   offset="0.0849" />
                <stop
                   id="stop20729"
                   style="stop-color:#a5b8c2;stop-opacity:1"
                   offset="0.2184" />
                <stop
                   id="stop20731"
                   style="stop-color:#728896;stop-opacity:1"
                   offset="0.3836" />
                <stop
                   id="stop20733"
                   style="stop-color:#405766;stop-opacity:1"
                   offset="0.55369997" />
                <stop
                   id="stop20735"
                   style="stop-color:#667d8b;stop-opacity:1"
                   offset="0.64170003" />
                <stop
                   id="stop20737"
                   style="stop-color:#92a7b1;stop-opacity:1"
                   offset="0.74199998" />
                <stop
                   id="stop20739"
                   style="stop-color:#b7c8d0;stop-opacity:1"
                   offset="0.83740002" />
                <stop
                   id="stop20741"
                   style="stop-color:#cfdfe4;stop-opacity:1"
                   offset="0.92570001" />
                <stop
                   id="stop20743"
                   style="stop-color:#d8e7eb;stop-opacity:1"
                   offset="1" />
              </linearGradient>
            </defs>
            <g
               id="g699-6"
               style="fill:url(#linearGradient23809)">
              <defs
                 id="defs701-07">
                <linearGradient
                   x1="-3704.9473"
                   y1="-3493.9082"
                   x2="-3688.7896"
                   y2="-3442.3477"
                   id="linearGradient20747"
                   gradientUnits="userSpaceOnUse"
                   gradientTransform="matrix(0.5318,4e-4,-4e-4,0.5318,2110.5286,1859.3658)">
                  <stop
                     id="stop20749"
                     style="stop-color:#d8e7eb;stop-opacity:1"
                     offset="0" />
                  <stop
                     id="stop20751"
                     style="stop-color:#c9d9de;stop-opacity:1"
                     offset="0.0849" />
                  <stop
                     id="stop20753"
                     style="stop-color:#a5b8c2;stop-opacity:1"
                     offset="0.2184" />
                  <stop
                     id="stop20755"
                     style="stop-color:#728896;stop-opacity:1"
                     offset="0.3836" />
                  <stop
                     id="stop20757"
                     style="stop-color:#405766;stop-opacity:1"
                     offset="0.55369997" />
                  <stop
                     id="stop20759"
                     style="stop-color:#667d8b;stop-opacity:1"
                     offset="0.64170003" />
                  <stop
                     id="stop20761"
                     style="stop-color:#92a7b1;stop-opacity:1"
                     offset="0.74199998" />
                  <stop
                     id="stop20763"
                     style="stop-color:#b7c8d0;stop-opacity:1"
                     offset="0.83740002" />
                  <stop
                     id="stop20765"
                     style="stop-color:#cfdfe4;stop-opacity:1"
                     offset="0.92570001" />
                  <stop
                     id="stop20767"
                     style="stop-color:#d8e7eb;stop-opacity:1"
                     offset="1" />
                </linearGradient>
              </defs>
              <path
                 d="m 142.305,7.35 0.191,-0.383 0.153,-0.42 0.152,-0.423 0.113,-0.421 0.117,-0.459 0.115,-0.496 0.077,-0.459 0.042,-0.5 0.036,-0.459 0.035,-0.498 10e-4,-0.499 -0.035,-0.46 -0.036,-0.459 -0.08,-0.457 -0.112,-0.461 -0.114,-0.42 0.611,0.804 0.459,0.882 0.345,0.842 0.189,0.88 0.076,0.919 v 0.92 l -0.116,0.918 -0.194,0.92 -0.228,0.918 -0.31,0.883 -0.343,0.879 -0.343,0.88 -0.385,0.843 -0.347,0.842 -0.346,0.765 -0.343,0.767 0.074,-0.152 0.037,-0.269 0.042,-0.266 v -0.345 l 0.037,-0.424 V 12.06 11.6 l 0.001,-0.496 0.038,-0.499 v -0.498 l 0.039,-0.534 0.04,-0.498 0.038,-0.461 0.078,-0.461 0.075,-0.42 0.116,-0.383 z"
                 id="path724-5"
                 style="fill:url(#linearGradient3849-2)" />
              <path
                 d="m 153.974,23.252 -0.729,-0.422 -0.729,-0.462 -0.687,-0.421 -0.688,-0.422 -0.65,-0.383 -0.651,-0.422 -0.616,-0.385 -0.609,-0.42 -0.653,-0.384 -0.607,-0.384 -0.614,-0.422 -0.652,-0.382 -0.611,-0.386 -0.654,-0.342 -0.686,-0.386 -0.689,-0.382 0.61,0.61 0.613,0.616 0.613,0.611 0.612,0.576 0.65,0.611 0.651,0.536 0.65,0.539 0.688,0.497 0.651,0.461 0.689,0.383 0.651,0.346 0.688,0.269 0.688,0.229 0.688,0.115 0.691,0.037 0.691,-0.035 z"
                 id="path726-3"
                 style="fill:url(#linearGradient3851-9)" />
              <path
                 d="m 148.277,7.928 -0.536,0.308 -0.5,0.345 -0.495,0.345 -0.461,0.344 -0.46,0.343 -0.419,0.383 -0.424,0.421 -0.423,0.383 -0.384,0.422 -0.384,0.422 -0.382,0.421 -0.345,0.457 -0.383,0.422 -0.346,0.459 -0.344,0.459 -0.346,0.459 0.153,-0.496 0.192,-0.499 0.191,-0.537 0.229,-0.534 0.231,-0.536 0.265,-0.499 0.31,-0.498 0.346,-0.495 0.382,-0.46 0.461,-0.381 0.498,-0.385 0.537,-0.344 0.612,-0.269 0.652,-0.229 0.765,-0.152 0.805,-0.076 z"
                 id="path728-70"
                 style="fill:url(#linearGradient3853-0)" />
              <path
                 d="m 142.574,3.329 -0.153,0.767 -0.114,0.767 -0.154,0.766 -0.116,0.689 -0.076,0.727 -0.114,0.689 -0.079,0.689 -0.115,0.689 -0.077,0.688 -0.117,0.689 -0.074,0.651 -0.118,0.689 -0.116,0.689 -0.115,0.689 -0.15,0.689 -0.157,0.727 -0.076,-0.842 -0.113,-0.805 -0.077,-0.843 -0.076,-0.841 -0.037,-0.807 -0.038,-0.805 0.039,-0.805 0.039,-0.764 0.076,-0.767 0.116,-0.688 0.194,-0.689 0.229,-0.651 0.269,-0.573 0.384,-0.537 0.422,-0.46 0.497,-0.421 z"
                 id="path730-4"
                 style="fill:url(#linearGradient3855-7)" />
              <path
                 d="m 146.674,2.071 0.692,0.648 0.416,0.729 0.189,0.766 0.04,0.805 -0.153,0.804 -0.307,0.843 -0.424,0.844 -0.498,0.841 -0.575,0.804 -0.611,0.805 -0.653,0.764 -0.65,0.689 -0.614,0.689 -0.534,0.572 -0.463,0.539 -0.383,0.418 0.077,-1.147 0.154,-0.995 0.191,-0.844 0.307,-0.764 0.306,-0.65 0.386,-0.574 0.382,-0.535 0.424,-0.501 0.383,-0.496 0.424,-0.495 0.382,-0.538 0.307,-0.613 0.307,-0.688 0.23,-0.766 0.194,-0.919 0.075,-1.032 z"
                 id="path732-1"
                 style="fill:url(#linearGradient3857-6)" />
              <path
                 d="m 141.763,14.319 v -0.805 l -0.039,-0.765 -0.034,-0.765 -0.04,-0.768 -0.036,-0.729 -0.077,-0.727 -0.076,-0.727 -0.073,-0.691 -0.117,-0.688 -0.114,-0.728 -0.189,-0.689 -0.152,-0.689 -0.196,-0.688 -0.268,-0.689 -0.229,-0.689 -0.306,-0.689 1.111,1.073 0.918,1.034 0.649,0.959 0.457,0.92 0.309,0.879 0.151,0.805 0.037,0.806 -0.077,0.727 -0.195,0.689 -0.187,0.651 -0.27,0.613 -0.271,0.533 -0.23,0.537 -0.229,0.459 -0.152,0.459 -0.078,0.383 z"
                 id="path734-0"
                 style="fill:url(#linearGradient3859-9)" />
              <path
                 d="m 152.982,16.97 -0.613,0.114 -0.614,0.116 -0.611,0.075 -0.613,0.075 -0.609,0.038 -0.616,0.037 h -0.613 -0.575 l -0.612,-0.039 h -0.574 l -0.613,-0.077 -0.573,-0.038 -0.613,-0.04 -0.575,-0.075 -0.612,-0.079 -0.574,-0.075 0.498,0.229 0.498,0.192 0.535,0.231 0.537,0.19 0.574,0.193 0.576,0.151 0.61,0.156 0.61,0.076 0.612,0.039 h 0.651 l 0.651,-0.039 0.654,-0.15 0.651,-0.191 0.651,-0.27 0.648,-0.381 0.654,-0.46 z"
                 id="path736-8"
                 style="fill:url(#linearGradient3861-9)" />
              <path
                 d="m 149.417,20.07 0.461,0.078 0.419,0.075 0.461,0.115 0.457,0.115 0.463,0.194 0.456,0.151 0.421,0.191 0.46,0.23 0.421,0.23 0.421,0.267 0.383,0.271 0.386,0.268 0.343,0.307 0.308,0.307 0.304,0.307 0.27,0.344 -0.269,-0.917 -0.422,-0.808 -0.494,-0.688 -0.615,-0.651 -0.688,-0.536 -0.768,-0.5 -0.841,-0.42 -0.882,-0.347 -0.919,-0.306 -0.919,-0.307 -0.955,-0.231 -0.958,-0.23 -0.957,-0.193 -0.919,-0.189 -0.843,-0.154 -0.842,-0.192 0.42,0.153 0.574,0.306 0.69,0.463 0.841,0.497 0.843,0.535 0.879,0.499 0.842,0.46 0.768,0.308 z"
                 id="path738-8"
                 style="fill:url(#linearGradient3863-3)" />
              <path
                 d="m 151.174,26.926 0.345,-0.881 0.117,-0.844 -0.116,-0.842 -0.307,-0.766 -0.457,-0.729 -0.612,-0.727 -0.728,-0.69 -0.804,-0.614 -0.843,-0.613 -0.879,-0.536 -0.919,-0.538 -0.884,-0.459 -0.801,-0.42 -0.767,-0.387 -0.651,-0.344 -0.496,-0.309 0.532,1.113 0.538,0.919 0.573,0.728 0.536,0.652 0.574,0.498 0.574,0.459 0.574,0.346 0.574,0.346 0.571,0.346 0.577,0.382 0.572,0.384 0.536,0.46 0.537,0.573 0.535,0.691 0.497,0.806 0.498,0.995 z"
                 id="path740-2"
                 style="fill:url(#linearGradient3865-3)" />
              <path
                 d="m 141.529,17.497 0.422,0.652 0.42,0.652 0.421,0.65 0.38,0.613 0.346,0.613 0.345,0.649 0.346,0.614 0.305,0.613 0.304,0.652 0.268,0.65 0.271,0.613 0.229,0.65 0.19,0.689 0.192,0.65 0.152,0.689 0.152,0.73 0.384,-1.455 0.191,-1.265 0.041,-1.149 -0.115,-0.994 -0.229,-0.844 -0.346,-0.766 -0.42,-0.652 -0.458,-0.537 -0.538,-0.499 -0.535,-0.421 -0.573,-0.346 -0.537,-0.306 -0.496,-0.306 -0.46,-0.268 -0.342,-0.307 -0.31,-0.271 z"
                 id="path742-5"
                 style="fill:url(#linearGradient3867-6)" />
            </g>
          </g>
        </g>
        <g
           transform="matrix(1.0394175,0,0,0.96207735,-22.857143,-470.71429)"
           id="text17899"
           style="font-size:32.17870712px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#b7b7b7;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;font-family:FreeSans;-inkscape-font-specification:FreeSans Bold">
          <g
             transform="scale(0.96207732,1.0394175)"
             id="text5115"
             style="font-size:32.71201324px;font-weight:normal;fill:#000000;stroke:#b7b7b7;font-family:Droid Sans;-inkscape-font-specification:Droid Sans">
            <text
               xml:space="preserve"
               style="font-size:36.87817764px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans Bold"
               x="571.70752"
               y="564.02405"
               id="text4246"
               sodipodi:linespacing="125%"
               transform="scale(1.0846523,0.92195444)"><tspan
                 sodipodi:role="line"
                 id="tspan4248"
                 x="571.70752"
                 y="564.02405">Powered by httpd 2.4</tspan></text>
          </g>
        </g>
        <g
           transform="matrix(1.2427237,0,0,0.80468409,-22.857143,-470.71429)"
           id="text17903"
           style="font-size:49.70895004px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#9c00ff;fill-opacity:1;stroke:none;font-family:Syncopate;-inkscape-font-specification:Syncopate Bold">
          <g
             transform="scale(0.99478937,1.0052379)"
             id="text4222"
             style="font-size:54.75603485px;font-weight:normal;fill:#000000;font-family:Droid Sans;-inkscape-font-specification:Droid Sans">
            <path
               d="m 240.06634,684.67398 -20.48004,0 -3.44899,6.95145 -11.06884,0 19.22343,-36.73574 11.06884,0 19.22344,36.73574 -11.06885,0 -3.44899,-6.95145 m -16.92411,-7.16534 13.42165,0 -6.68409,-13.52859 -6.73756,13.52859"
               id="path4227"
               style="font-weight:bold;fill:#2e00ff;fill-opacity:1;font-family:Syncopate;-inkscape-font-specification:Syncopate Bold" />
            <path
               d="m 301.88077,667.42903 c -5e-5,1.83592 -0.26741,3.52922 -0.80209,5.07991 -0.53477,1.5329 -1.39925,2.86081 -2.59343,3.98372 -1.17644,1.10511 -2.70932,1.96959 -4.59865,2.59342 -1.8894,0.62386 -4.18873,0.93579 -6.89797,0.93577 l -16.46959,0 0,11.60358 -9.91919,0 0,-36.73574 26.38878,0 c 2.70924,4e-5 5.00857,0.31196 6.89797,0.93577 1.88933,0.60606 3.42221,1.47053 4.59865,2.59343 1.19418,1.10513 2.05866,2.42412 2.59343,3.95698 0.53468,1.53291 0.80204,3.2173 0.80209,5.05316 m -10.02613,0.16042 c -4e-5,-0.85554 -0.12481,-1.58633 -0.37431,-2.19238 -0.23175,-0.62382 -0.62388,-1.13181 -1.1764,-1.52397 -0.55258,-0.3921 -1.27446,-0.67729 -2.16564,-0.85556 -0.89124,-0.19604 -1.98743,-0.29407 -3.28857,-0.2941 l -14.33068,0 0,9.46466 14.33068,0 c 1.30114,2e-5 2.39733,-0.0713 3.28857,-0.21389 0.89118,-0.16039 1.61306,-0.41885 2.16564,-0.77535 0.55252,-0.37429 0.94465,-0.85554 1.1764,-1.44376 0.2495,-0.58818 0.37427,-1.31006 0.37431,-2.16565"
               id="path4229"
               style="font-weight:bold;fill:#cb00c6;fill-opacity:1;font-family:Syncopate;-inkscape-font-specification:Syncopate Bold" />
            <path
               d="m 337.81442,684.67398 -20.48004,0 -3.44899,6.95145 -11.06885,0 19.22343,-36.73574 11.06885,0 19.22343,36.73574 -11.06884,0 -3.44899,-6.95145 m -16.92411,-7.16534 13.42165,0 -6.68409,-13.52859 -6.73756,13.52859"
               id="path4231"
               style="font-weight:bold;fill:#ff007e;fill-opacity:1;font-family:Syncopate;-inkscape-font-specification:Syncopate Bold" />
            <path
               d="m 398.29204,689.11221 c -1.28339,0.53473 -2.57565,1.01598 -3.87677,1.44376 -1.30121,0.42779 -2.64694,0.79318 -4.03719,1.09619 -1.39033,0.32084 -2.86083,0.56147 -4.4115,0.72188 -1.53291,0.16042 -3.18165,0.24063 -4.94622,0.24063 -3.74312,0 -7.1921,-0.40104 -10.34697,-1.20313 -3.13708,-0.80209 -5.84636,-2.00523 -8.12785,-3.60941 -2.26368,-1.622 -4.02828,-3.63614 -5.29379,-6.04241 -1.26553,-2.42409 -1.89829,-5.24922 -1.89828,-8.47543 -1e-5,-3.22616 0.63275,-6.04239 1.89828,-8.44868 1.26551,-2.42407 3.03011,-4.4382 5.29379,-6.04241 2.28149,-1.62198 4.99077,-2.83402 8.12785,-3.63615 3.15487,-0.80205 6.60385,-1.2031 10.34697,-1.20313 1.76457,3e-5 3.41331,0.0802 4.94622,0.24062 1.55067,0.16046 3.02117,0.40109 4.4115,0.72189 1.39025,0.30304 2.73598,0.66844 4.03719,1.09619 1.30112,0.42781 2.59338,0.90907 3.87677,1.44376 l 0,8.92994 c -1.01603,-0.55253 -2.08548,-1.09617 -3.20837,-1.63092 -1.12296,-0.55252 -2.36175,-1.04269 -3.71635,-1.4705 -1.35468,-0.44558 -2.843,-0.80206 -4.46497,-1.06945 -1.62203,-0.28516 -3.44902,-0.42775 -5.48095,-0.42778 -3.11926,3e-5 -5.71269,0.32086 -7.78027,0.9625 -2.04981,0.64171 -3.68964,1.49727 -4.91949,2.56669 -1.22989,1.06948 -2.09436,2.29935 -2.59343,3.68962 -0.49909,1.37249 -0.74863,2.79842 -0.74861,4.27781 -2e-5,0.98035 0.10693,1.95177 0.32083,2.91427 0.21388,0.94469 0.57036,1.84482 1.06946,2.70037 0.49906,0.83775 1.14964,1.6131 1.95175,2.32606 0.80207,0.71298 1.80023,1.32791 2.99447,1.84481 1.1942,0.51691 2.58449,0.92686 4.17087,1.22987 1.60415,0.28519 3.44896,0.42779 5.53442,0.42778 2.03193,10e-6 3.85892,-0.12476 5.48095,-0.37431 1.62197,-0.26735 3.11029,-0.61493 4.46497,-1.04272 1.3546,-0.42777 2.59339,-0.90902 3.71635,-1.44376 1.12289,-0.55254 2.19234,-1.114 3.20837,-1.68439 l 0,8.92994"
               id="path4233"
               style="font-weight:bold;fill:#ff1452;fill-opacity:1;font-family:Syncopate;-inkscape-font-specification:Syncopate Bold" />
            <path
               d="m 442.7011,691.62543 0,-15.31993 -25.23911,0 0,15.31993 -9.91918,0 0,-36.73574 9.91918,0 0,13.36817 25.23911,0 0,-13.36817 9.91919,0 0,36.73574 -9.91919,0"
               id="path4235"
               style="font-weight:bold;fill:#ff572c;fill-opacity:1;font-family:Syncopate;-inkscape-font-specification:Syncopate Bold" />
            <path
               d="m 462.56483,691.62543 0,-36.73574 37.19026,0 0,7.83375 -27.00371,0 0,6.06915 25.61342,0 0,7.83375 -25.61342,0 0,7.16534 27.37802,0 0,7.83375 -37.56457,0"
               id="path4237"
               style="font-weight:bold;fill:#ff940a;fill-opacity:1;font-family:Syncopate;-inkscape-font-specification:Syncopate Bold" />
          </g>
        </g>
      </g>
    </svg>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6odb.png�����������������������������������������������������������������0000664�0001751�0001751�00000002027�11141176336�016722� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��UPLTE&&&'''('''((((()))33333\\]\]]^^���0���tRNS�@f���bKGD�H���	pHYs�������NIDATc`GP~mް}LaEn
    kϟe?2KϘe!q4ׂ: u+pMgCnKpC�Hp,qj^ �Y))X]^�\x,~6NVyS'	W	DBgMlkgdNli/N7Uʧ'Fɻ@[k
    rSbBm 
    9!~n҂8@w{kyC`QNjBT(?.D($r#&D0%6"PO[]"΋A �`{����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6otf.png�����������������������������������������������������������������0000664�0001751�0001751�00000002072�11141176336�016746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��jPLTE!!!&&&'''(((33344455533\\]\]]^^���[A���tRNS�@f���bKGD�H���	pHYs�������\IDATc`E zھyUKgNppkm߼~El`: ]a,D0֎\+e٤{  up8͑eش~
    %$!59V(s(kenޠ4eBO[sMe9DpŋfNjk.ρ\6wΌI`heB͙9eb7dMKFBDp)m,Y	Qz;[k+DYDR }M5"BaA~f O`kcMq~0@p-D,-?ć"KM"Xjenl�dE Am4��box7����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6odc.png�����������������������������������������������������������������0000664�0001751�0001751�00000001750�11141176336�016725� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��.PLTE33333\\]\]]^^���rU���tRNS�@f���bKGD�H���	pHYs�������FIDATc`DPs!kW.[<q&Lq66&Vg1Nꅊ2nf[!٘cR[]e3IMAY͚( L8؁�,833gMEI^V2Lp^զ̤`mU%E)	>^d`wG`PM9H,N(]"$TZ,(d,LNr҇%
    iCs„<̅T B.ƆjJ
    x!d vq07PQ2�p10��R눳e����IENDB`������������������������httpd-2.4.64/docs/icons/odf6odp.png�����������������������������������������������������������������0000664�0001751�0001751�00000001722�11141176336�016741� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��.PLTE33333\\]\]]^^���rU���tRNS�@f���bKGD�H���	pHYs�������0IDATc`DPs!kW.[<q&Lq66&Vg1Nꅊ2nf[!٘cR[]e3IMAY͚( L8؁�,833gMEI^V2Lp^զ̤`mU%E)	>޶`wG`P@JsS⣂|!BH*!yi>6\d$*T2_[kcC]5%`P0J`x8DA
    00��i0P"7����IENDB`����������������������������������������������httpd-2.4.64/docs/icons/odf6odt.png�����������������������������������������������������������������0000664�0001751�0001751�00000001727�11141176336�016752� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��.PLTE33333\\]\]]^^���rU���tRNS�@f���bKGD�H���	pHYs�������5IDATc`DPs!kW.[<q&Lq66&Vg1Nꅊ2nf[!٘cR[]e3IMAY͚( L8؁�,833gMEI^V2Lp^զ̤`mU%E)	>޶`wG`26C3bݝm-M!@x`2K!!m`nFrTX
    D0U(Bl!+@#}]̍Ud .@1
    8DA
    00��MOɟf����IENDB`�����������������������������������������httpd-2.4.64/docs/icons/odf6odf.png�����������������������������������������������������������������0000664�0001751�0001751�00000002027�11141176336�016726� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��XPLTE&&&'''(((33333\\]\]]^^������tRNS�@f���bKGD�H���	pHYs�������KIDATc`APrIoٸe9L%NVkW,
    e9
    K̜e*i9,;,1 uOQ`CV5+HMW�F9VbZ[j�,v+xW[SME!Lp9't6Ԕd$B͟6b\r|Dp	]̢̱I}]5"iQ^	EB̂Q֖¼TA&~owg[`cMIanZ %D0#%^"XThbECܩLwsujPp�p10(�a&����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/index.png�������������������������������������������������������������������0000664�0001751�0001751�00000000514�10671421551�016504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEf333���VRL���tRNS�0J���bKGD�H���xIDAT[U
     azACC` @DJi4hǝA"(;'Y.mj䙹*NGszWt⛑R>>??A2;���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/compressed.png��������������������������������������������������������������0000664�0001751�0001751�00000002124�10664777241�017554� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4���PLTEf3�̙f3�f3�ffffff3f�3333f333�����f�3��f3�̙f3�̙̙̙̙f̙3̙�ffffff3f�3333f333�����f�3��̙f3�̙̙f3�̙f3�ff̙ffff3f�33̙33f333���̙��f�3��ffffff3f�fff̙fff3f�ffffff3f�fffffffffff3ff�f3f3f3f3ff33f3�f�f�f�f�ff�3f��3333f333�333̙3f333�3333f333�3f3f3f3ff3f33f�33333333f33333�3�3�3�3�f3�33������f�3�����̙�f�3������f�3���f�f�f�ff�f3�f��3�3�3�3f�33�3���������f��3����������w��U��D��"���������������w��U��D��"���������������w��U��D��"��ݻwwwUUUDDD"""������%tRNS�?BO���bKGD�H���oIDATm DQ
    #56BƠH=fѕi&"&EV|4p:U qP68x*DQ4FVdg"">7ІF:.
    i5;���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie2.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000306�10147723030�016207� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������E4X	q(fHi.2^7rA,@(#	e:Q)##Q��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/world1.gif������������������������������������������������������������������0000664�0001751�0001751�00000000344�10147723030�016562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�����3���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������c:훚ؚ[4LEe�fXGj*A(܎3|9L#"$Yv۰rSWv$,mtj)VoB ǃP��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/folder.open.gif�������������������������������������������������������������0000664�0001751�0001751�00000000362�10147723030�017565� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙f3333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������e(0Im&|`'g뺰#so	uaJ:|ZQzuf=W
    p/sFmC9*:5	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/xml.png���������������������������������������������������������������������0000664�0001751�0001751�00000002035�11141176336�016176� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��RPLTE33---.-....///0/0/0/000333������tRNS�@f���bKGD�H���	pHYs�������WIDATc@Pq{vnݴ~5R(ǑCvغqefBE9ݹmˆ>"ʱ{֍VX6DŽ(-׭^xI`ܼaeN�@57UqXuI:Za͚9IE4/=)"`IJlu,qQYJ%EcB!zY@bY)B^>ʂ촄(F>W`s,TNFrL #-DHY<!*"XY&,`cn,NIff䶷652ŢB\m,Mt ɱAn@1s:D
    00��n=����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6oti.png�����������������������������������������������������������������0000664�0001751�0001751�00000002123�11141176336�016746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��PLTE!!!+++,,,,,----33344455533\\]\]]^^���F*6���tRNS�@f���bKGD�H���	pHYs�������ZIDATc`C& ve>gW/rسcբ|`K `Cb(D/=9DمB@vn^*.4e"D[t-#.<`ĩQSkьl=;8Μ�ܺejEsgLn(nZlS'5UAW/]4w֔dsg fOԧάR,	1}B*lIx DpJ+r<t\4/DOU8;-1&2D
    "Tal4Avʢܴ�/7gK 
    `	20�sv^ŴeE����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6ott.png�����������������������������������������������������������������0000664�0001751�0001751�00000001776�11141176336�016776� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��FPLTE!!!33344455533\\]\]]^^������tRNS�@f���bKGD�H���	pHYs�������DIDATc`B t݉[7[|y3)rrȭ^xi\`
      Ed �Dp;'ܚsY  uKMd櫯`]x[oO;/3O1Dp,qV*n<%llb-
    UO3h*HNΝ5qBO[C]eanZR\$Dpڄގ?`<2@
    r3SbBܜl @27yy`eiAzr\X!DH>U>
    lBsR"C|]-5!)~@1S
    D0��`23S3����IENDB`��httpd-2.4.64/docs/icons/odf6odm.png�����������������������������������������������������������������0000664�0001751�0001751�00000002044�11141176336�016734� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��[PLTE---..../////33333\\]\]]^^��� 3���tRNS�@f���bKGD�H���	pHYs�������UIDATc`EPzC{vlݴuLQe.6NMV.e=rΚeŦy,Ǣ{ uYLUdC6N+JO Ml2$'rXpjiv6v"ಥsLc`NM.^0}N1|!&h;XDr ۚjr!;[j3 muELqaA>vҢt&�o^F+`MyQfjB#1D$/=)&<GAP"wSR4ՆG9ٚjAYQ�8��b\
    $����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6otg.png�����������������������������������������������������������������0000664�0001751�0001751�00000002122�11141176336�016743� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��PLTE!!!***+**+++++,,,,,,----33344455533\\]\]]^^���Yz���tRNS�@f���bKGD�H���	pHYs�������_IDATcDF ys%'ܷk֍kT/۵m*\`< [}
    2D�]z|ոU&C@o\¥8"xgMڼϒk3]ţ`^F:<&v57A7oZulyΦbKϟ9C0"r3&q4I'BΛ=mR/t8[NzbDp)z٪D!Ӧu6K秋FC'5KxC{:2S…Y<\ bl)Bb6#`d$Fy8YC9Q�'H
    00��atL����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6otp.png�����������������������������������������������������������������0000664�0001751�0001751�00000001771�11141176336�016765� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��FPLTE!!!33344455533\\]\]]^^������tRNS�@f���bKGD�H���	pHYs�������?IDATc`B t݉[7[|y3)rrȭ^xi\`
      Ed �Dp;'ܚsY  uKMd櫯`]x[oO;/3O1Dp,qV*n<%llb-
    UO3h*HNΝ5qBO[C]eanZR\$Dpڄގ?`|<xB{k+sb#] H*m U9	!~nJ$"@/;+c}]`|JM`JlD
    D0��Ja&!����IENDB`�������httpd-2.4.64/docs/icons/odf6odi.png�����������������������������������������������������������������0000664�0001751�0001751�00000002053�11141176336�016730� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��mPLTE+++,,,,,----33333\\]\]]^^���z
    ���tRNS�@f���bKGD�H���	pHYs�������JIDATc`EPzޱuLiM.6N[ֳ._e=*kV.5"zMmeYgN	eM۸n:+pm^Z}4u�	PeSZ!&;[6*Ml	Yx=uΞTY\4{ľ溊0̩{@bŹLa]mMRL"LL>:If	&a& u/`G4X_#DIE<;-.2ǝ"XTdn
    ,QGԄ0_g[K3c} +7
    �:``��fO����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6otc.png�����������������������������������������������������������������0000664�0001751�0001751�00000002020�11141176336�016734� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��FPLTE!!!33344455533\\]\]]^^������tRNS�@f���bKGD�H���	pHYs�������VIDATc`B t݉[7[|y3)rrȭ^xi\`
      Ed �Dp;'ܚsY  uKMd櫯`]x[oO;/3O1Dp,qV*n<%llb-
    UO3h*HNΝ5qBO[C]eanZR\$Dp|oGk}UY|VBLDO$-"	o,IOw6WfȻ@rZ- a>."Ԅ@/;+c}]`<2ЄF8Xi@P�HA
    00��*c=Wg����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6oth.png�����������������������������������������������������������������0000664�0001751�0001751�00000002046�11141176336�016751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��XPLTE!!!33344455533\\]\]]^^wwxxyxyyzz{{���l.B9���tRNS�@f���bKGD�H���	pHYs�������ZIDATc`B t黷oٸv%%ǎsrl\r9`j Ej8Dp/'ʦ$YęE  uLgimn`]rIBʬ
    dY'wv42@׮gcejk-+..[:wΖҼ4ӧMik//HΙ6/-)*"8eb_'H0ިr>VxVn_/`gGcMY1P0*	"PYVl.L"XQ`ijGE{9ڙCCb@1]- �
    `	20�Si����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6odg.png�����������������������������������������������������������������0000664�0001751�0001751�00000002060�11141176336�016724� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��mPLTE***+**+++++,,,,,,----33333\\]\]]^^���aar���tRNS�@f���bKGD�H���	pHYs�������OIDATc@PqޱcLiM^N[s,_8	*kVp,5"qSme9fN	H۸n:pn^Zk4u�	PTZ!);[6*rqrMl	YxRuΞ.^\4{ľ)
    V0̩{:%EXc!ښ$X3RY} =-ul9)1B,~^.
    qVfW`SmE>p\d�%D$W562(͉"XԄ0_g[K3c} 
    �:``��nfj,����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/odf6ods.png�����������������������������������������������������������������0000664�0001751�0001751�00000001713�11141176336�016744� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��.PLTE33333\\]\]]^^���rU���tRNS�@f���bKGD�H���	pHYs�������)IDATc`DPs!kW.[<q&Lq66&Vg1Nꅊ2nf[!٘cR[]e3IMAY͚( L8؁�,833gMEI^V2Lp^զ̤`mU%E)	>޶`wG`26	89
    CQTCҒ#m,!(*U B.BƆjB
    x2�oGsc=
    E9)q #;
    �``��lM<Ap����IENDB`�����������������������������������������������������httpd-2.4.64/docs/icons/odf6ots.png�����������������������������������������������������������������0000664�0001751�0001751�00000001762�11141176336�016770� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������L4��FPLTE!!!33344455533\\]\]]^^������tRNS�@f���bKGD�H���	pHYs�������8IDATc`B t݉[7[|y3)rrȭ^xi\`
      Ed �Dp;'ܚsY  uKMd櫯`]x[oO;/3O1Dp,qV*n<%llb-
    UO3h*HNΝ5qBO[C]eanZR\$Dpڄގ?`<27V'Fɻ@QT@rRC<- (*
    !E	QvV؈@?WkSC=mu 
    `	20ȣ�P]n'����IENDB`��������������httpd-2.4.64/docs/icons/pie0.png��������������������������������������������������������������������0000664�0001751�0001751�00000000403�10671421551�016227� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���8IDAT[cd*H60p21002D000L	@R'bL�Hso(���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie6.png��������������������������������������������������������������������0000664�0001751�0001751�00000000421�10671421551�016235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���FIDAT[u̡
    0E76$%:BE*̑'�&&EZJr+vxcT.BwZ/���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/ps.png����������������������������������������������������������������������0000664�0001751�0001751�00000000457�10671421551�016025� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���^IDAT[
     Eї0@`"vޯ#!D*.D$ԏ%`'IO]/8-h$d̓2^7\';
    1W���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/layout.png������������������������������������������������������������������0000664�0001751�0001751�00000000503�10671421551�016710� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333f3f333���_���tRNS�@*���bKGD�H���dIDAT[c(bccc `gG0ALvv0S0-(d%pTTTi@fGGc2ih NxQ84c�w,/A-���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/uuencoded.png���������������������������������������������������������������0000664�0001751�0001751�00000000450�10671421551�017347� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���WIDAT[΁	�!u @L_cLU@D4wC'<D}۶mt 兏Z5o},p՞���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/f.png�����������������������������������������������������������������������0000664�0001751�0001751�00000000450�10671421551�015621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���WIDAT[α
     W^1@ϔ7HeU7$zRŌd,sNit_L_Q#<RmG_ʒ)M���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/dvi.png���������������������������������������������������������������������0000664�0001751�0001751�00000000461�10671421551�016160� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���`IDAT[	 Уq �dz&ҖR}=SD4UE#4Fn YGd1;lLI}jc55?'w9ÊD���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/box2.png��������������������������������������������������������������������0000664�0001751�0001751�00000000520�10664777241�016260� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙333�3�f3������tRNS�0J���bKGD�H���vIDATE1
    0D)[Rh+VAHxDr}7&1zL5ؾVf͘NSgJ)e.Ȭ$qc]y:;664C
    L<ʩ(sFұRD&%=ɩ/c,$0
    J���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/box1.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000373�10147723030�016225� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙333�3�f3���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������n0#;D\iS1cuqk'�@׆iXp~%0BC�Պ9m1M:/<>n'W[2LL
    	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/diskimg.gif�����������������������������������������������������������������0000664�0001751�0001751�00000000247�10147723030�017003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a���333���!����,������@lh!)3(3
    ViR^(,:h,*_ݶ/CdC>E9Ԓ_4%*ZmU`"nz0>'dϪ8`Wb.-|j*t*	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/comp.blue.png���������������������������������������������������������������0000664�0001751�0001751�00000000512�10664777241�017273� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEffff333�f���B{���tRNS�0J���bKGD�H���pIDATu=
    0E:wЮ.]W^&A!T *P)h*Z'ˇK*3Kl<}{MGki9Q|X+6ī
    rC+'0���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/left.png��������������������������������������������������������������������0000664�0001751�0001751�00000000401�10671421551�016322� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���6IDAT[c8
    &00&*&d$Q	dd-0{3,^A���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/transfer.png����������������������������������������������������������������0000664�0001751�0001751�00000000516�10671421551�017223� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33f��333���\���tRNS�
    A���bKGD�H���vIDAT[M	@EG~^` /S@鿄,1ouvDZ~!!<ϛA^s1K�9+�(K6P)C!kZM�2�rS>qǣ:"W>	h\���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie5.png��������������������������������������������������������������������0000664�0001751�0001751�00000000425�10671421551�016240� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���JIDAT[u̱
    @Q/)S#S-}lhly狨H"|쏴;L[ 'aD+e���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/screw2.png������������������������������������������������������������������0000664�0001751�0001751�00000000515�10671421551�016603� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙333������tRNS�0J���bKGD�H���yIDAT[E1 a+pmv$̎WOdһ#D?BXc1,lhz.RY,R3Vؕ/P&0$;]?yÍ_=gO&!ij���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/bomb.png��������������������������������������������������������������������0000664�0001751�0001751�00000000567�10671421551�016324� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���!PLTE3̻fffUUU333���ٖ)���tRNS�
    A���bKGD�H���IDAT[Eα
    0/!$
    xT@c!X #(B*#dnJE|gĚ{	c\ںJLDT=`f؆ki
    %q;TV~ND>cR!*H+C$g/2-Z䓞5x9A0SU���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie3.png��������������������������������������������������������������������0000664�0001751�0001751�00000000424�10671421551�016235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���IIDAT[cd*H6hecZ$B L@2Ak*P/NK�$m���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/folder.png������������������������������������������������������������������0000664�0001751�0001751�00000000447�10671421551�016655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙f3333������tRNS�
    A���bKGD�H���RIDAT[cPP 0U 1ECCALC (j@pD™®TWUc0qeP
    q%Pp�~� yM���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/alert.red.png���������������������������������������������������������������0000664�0001751�0001751�00000000472�10671421551�017260� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33f��333���	���tRNS�@*���bKGD�H���^IDAT[m̻	@EыȘ[´`.l.,̖0O033K
     2H*QHKι+	lu?BggmRVk�!#B'���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/image2.png������������������������������������������������������������������0000664�0001751�0001751�00000000563�10671421551�016545� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���$PLTE33̙ffff��333��3�3f���̷Y���tRNS�
    A���bKGD�H���IDAT[E;
    @Wji
    Us.b"`la6G8ՁKǔ1+ѭ4@{?3PMsO‘cM"-EW-[y}ȯϤ<L]?4,,I+kL障P?Y:Kr���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pdf.png���������������������������������������������������������������������0000664�0001751�0001751�00000000460�10671421551�016146� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���_IDAT[m	 EGu Pgj)n5	-%#LvPxcʙ/(׀aƴӉw-|1ւBOn;HEK2l���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/patch.png�������������������������������������������������������������������0000664�0001751�0001751�00000000466�10671421551�016502� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEfff��333���+���tRNS�
    A���bKGD�H���^IDAT[α
    0DC8H+D`�)%
    =zraU7XȓacVk}ifX("@D4.;s^T<L?{#KHM*@|6���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/down.png��������������������������������������������������������������������0000664�0001751�0001751�00000000400�10671421551�016336� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���5IDAT1 �,$pP3ʋ0숣-v<+<g���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/comp.gray.png���������������������������������������������������������������0000664�0001751�0001751�00000000476�10671421551�017303� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEf333���VRL���tRNS�0J���bKGD�H���jIDAT[uQ
     ay�A#v]@_mZ1ظtiNBqO"ُ-ʋĵ3Xxh\P̀[n%U]Uz1J'.#!Ht���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie1.png��������������������������������������������������������������������0000664�0001751�0001751�00000000427�10671421551�016236� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���LIDAT[cd*H6hecZ0D2LeH``P
    `�SdNK�(N���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/uu.gif����������������������������������������������������������������������0000664�0001751�0001751�00000000354�10147723030�016004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������_80@#)0bAfhQ#Go@W5k((vxH<Ħ8:i:NUo1k^^;.|qy	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/portal.png������������������������������������������������������������������0000664�0001751�0001751�00000000477�10664777241�016722� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE3̙3333���|���tRNS�
    A���bKGD�H���dIDATu1
     L$WzZ,UВ7@:(-#" ʹ9/TkUoJm(<~}g82~Yh%Do6gb���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie4.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000301�10147723030�016204� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������@4X	q(fHi.2^7]r LI䒩D1rROI0
    �;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/screw2.gif������������������������������������������������������������������0000664�0001751�0001751�00000000407�10147723030�016557� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������zH0@$i;U"@TAW6,Aa@,N>H<JZ"gS7{i�3)bNvF;)\IW
    c
    #}�9/o@6(sUD3kk	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/dir.png���������������������������������������������������������������������0000664�0001751�0001751�00000000447�10671421551�016160� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙f3333������tRNS�
    A���bKGD�H���RIDAT[cPP 0U 1ECCALC (j@pD™®TWUc0qeP
    q%Pp�~� yM���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/world1.png������������������������������������������������������������������0000664�0001751�0001751�00000000514�10664777241�016621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���PLTE�3���,���tRNS�0J���bKGD�H���~IDATcWdݪ'825Z!kVEJJUM
    :4V3<XѱH6Rfxġ	D`ZšPj-C
    ]
    S\[hZ`�?-=3���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/diskimg.png�����������������������������������������������������������������0000664�0001751�0001751�00000000327�10664777241�017042� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���pW*���tRNS�@f���bKGDa���`IDAT}1
    0!+tv."iBhk%VHXǍ>&s.BqG$d@e=K^	-h$Vz03,����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie6.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000272�10147723030�016215� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������94X	q(fHi.2.TE%a<"0
    �;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/burst.png�������������������������������������������������������������������0000664�0001751�0001751�00000000525�10671421551�016536� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE3f�fff333���jgx���tRNS�
    A���bKGD�H���}IDAT[u	!д`À%lL%f\o#~HEiEpvofHܿfkVVjf`+
    N*wM
    r&s#=[Y^Z^/0x�7$zUV4���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/text.png��������������������������������������������������������������������0000664�0001751�0001751�00000000440�10671421551�016357� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���OIDAT[ȱ
     S`�d@)E}ZvmeKGDj3f*t(VF)�"`_���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/tex.gif���������������������������������������������������������������������0000664�0001751�0001751�00000000373�10147723030�016154� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������n80@#i)!�Ega5ny*u_;
    `y–x$$QD
    RRE'Ԗp38Zn׀x#~/}i{eGF:oZ	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/up.png����������������������������������������������������������������������0000664�0001751�0001751�00000000377�10671421551�016030� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���4IDAT[100�<BhT}KmhJ
    dot=C���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/screw1.png������������������������������������������������������������������0000664�0001751�0001751�00000000510�10671421551�016575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙333������tRNS�0J���bKGD�H���tIDAT[U1 DhURXʯ^!o0j܃F;2;;Ac$(Z>̂ͬyj]Lg1S%|;�k(`uBd<Y7{3���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/image1.png������������������������������������������������������������������0000664�0001751�0001751�00000000505�10671421551�016540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE3ff̙f�333���GH���tRNS�@*���bKGD�H���fIDAT[}+@XYY!8C@Wc#ǯL$\GJ=7XxEDdO@�`/
    AqXZ1+r1d���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sound2.png������������������������������������������������������������������0000664�0001751�0001751�00000000473�10671421551�016613� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙fff333���A���tRNS�0J���bKGD�H���dIDAT[M1
    0@NP#Ĥ*u!BY; 0.RD�Ta
    ~
    ½%2_�ug؛}e1J	')V6R���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/broken.png������������������������������������������������������������������0000664�0001751�0001751�00000000500�10671421551�016650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���oIDAT[M	 P] p7Cb#Q\$Qk3m꼘!braŋi,أGPcq6,K&ESOfb+x?PǔU���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie4.png��������������������������������������������������������������������0000664�0001751�0001751�00000000402�10671421551�016232� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���7IDAT[cd*H6hecZ$B 'bL�)'Gꊡ���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/ball.gray.png���������������������������������������������������������������0000664�0001751�0001751�00000000452�10671421551�017251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̻fffUUU333���j���tRNS�0J���bKGD�H���JIDAT[cR3g˜.n)La3sXD%tK2*N At۠L&�Ah���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie2.png��������������������������������������������������������������������0000664�0001751�0001751�00000000420�10671421551�016230� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������/T���	PLTE������tRNS�0J���bKGD�H���EIDAT[cd*H6hecZ$B d`P@r*c``	2a)|�1O!11!���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/generic.sec.png�������������������������������������������������������������0000664�0001751�0001751�00000000447�10671421551�017567� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE33f��333���\���tRNS�
    A���bKGD�H���OIDAT[c
    t
    
    RRRb`t`eE0LV(aiiiP&ɀd;3XPH4#����VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/forward.png�����������������������������������������������������������������0000664�0001751�0001751�00000000464�10671421551�017045� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTEfff333������tRNS�0J���bKGD�H���`IDAT[E	0DQ76&2ٲOO!@䐞VV]sW#d߅'m;wuswB
    YL37?`Q'8fL���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/uu.png����������������������������������������������������������������������0000664�0001751�0001751�00000000450�10671421551�016025� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE333���U3���tRNS�0J���bKGD�H���WIDAT[΁	�!u @L_cLU@D4wC'<D}۶mt 兏Z5o},p՞���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/hand.right.gif��������������������������������������������������������������0000664�0001751�0001751�00000000331�10147723030�017374� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙f3������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������L(0I;W'b%b0l)8tXi{sVc(t[(lVShJ�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/blank.gif�������������������������������������������������������������������0000664�0001751�0001751�00000000224�10147723030�016436� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������ڋ޼I�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/broken.gif������������������������������������������������������������������0000664�0001751�0001751�00000000367�10147723030�016637� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������j80@#i;U"(1RDmL	K:K
    |hJ$Y'.fľ'wV@ٛ6*[uiR7
    =</7?	�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/link.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000371�10147723030�016307� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33f��333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������lXP@%i;U"QRFmL
    K:KDz_sDV@T	N6#ma^k	+Ǻ}NzBD=</7?	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/layout.gif������������������������������������������������������������������0000664�0001751�0001751�00000000424�10147723030�016666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333f3f333������������������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������oIxGvm^IYq$l4aLr@kW HPh6=(Aa9(UBo\5&2Wv-/s8GM/;xpukt}{[RQ?pH�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/image2.gif������������������������������������������������������������������0000664�0001751�0001751�00000000465�10147723030�016522� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33̙ffff��333��3�3f���������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������IXGvm^IYv*:A,6k-Ő6KX5�T%8kVb4ji e,|y7W/+fz%~w
    %PO@IR�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/comp.gray.gif���������������������������������������������������������������0000664�0001751�0001751�00000000366�10147723030�017255� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����f333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������i0XaH 7+a˺ٌ`aHϧ 0A@Zдj`kV1-ϊ`0+?P]۷\�y5i']\	�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/transfer.gif����������������������������������������������������������������0000664�0001751�0001751�00000000362�10147723030�017176� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33f��333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������e(*ս0�-2J]}JXq뒝!|C>_@9BUCI`3"tJ]Fة♥Ox,~!-O軻1it-)44	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/bomb.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000464�10147723030�016274� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����3̻fffUUU333������������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������0IX$Ivm^I�
    v$}ئIvDpH
    %r[@-45oJ�V1z=b@X`8o,@ۅ�y_,UIJghABxCJepf%	UTBLW�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sound1.gif������������������������������������������������������������������0000664�0001751�0001751�00000000370�10147723030�016562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33̙f��333���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������k(06BaUq	h~
    rwi4[AHkwṄ
    O48fqz***oԜCT:3M*6$>}J{v,{	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/generic.sec.gif�������������������������������������������������������������0000664�0001751�0001751�00000000371�10147723030�017537� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33f��333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������lXZAIE=|e]C([cz`ڬFbBXB�%w"ƧuYmQw;`nXf6ޭ
    I#J:BC	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/patch.gif�������������������������������������������������������������������0000664�0001751�0001751�00000000373�10147723030�016453� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����fff��333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������nXP@%i;U"QRFmL
    K@(~B@\Z|t:}"JP@�-z⊗/,%bf<;j:#j=</7?	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pdf.gif���������������������������������������������������������������������0000664�0001751�0001751�00000000371�10147723030�016123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������l80@#IjU�hV&LwU'eH{h$$DeYS%l(L?.E&zEdU-~]GF8ZZ	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/f.gif�����������������������������������������������������������������������0000664�0001751�0001751�00000000354�10147723030�015600� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������_80@#i;U"QDĩ+:|7<
    @C	`ScV|(*Mvأ.93KD[ŷ5*<q	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/down.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000243�10147723030�016317� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������"4g{|"|(eULP�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/unknown.gif�����������������������������������������������������������������0000664�0001751�0001751�00000000365�10147723030�017054� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������h80@#i;a"Qyʵ.J70֧#$
    @*,K|'"-K<%$`[˓j%<?$8@A	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/p.gif�����������������������������������������������������������������������0000664�0001751�0001751�00000000355�10147723030�015613� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������`80@#i;GUE%M�+P@:aQ*!-DYV(szd;/9hFu,Wü^x	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie3.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000277�10147723030�016217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������>4X	q(fHi.2^7W6w-2:Q��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/a.gif�����������������������������������������������������������������������0000664�0001751�0001751�00000000366�10147723030�015576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������i80@#i;U"(|<ڮ:W!UJ:<<>,;IkX݂
    {mhڭuO[?>28V	�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/dir.gif���������������������������������������������������������������������0000664�0001751�0001751�00000000341�10147723030�016125� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙f3333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������T(0IYE}d)@zjC,+W<
    IEqg<N"4IRaVVxl<&z#,L;�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie1.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000306�10147723030�016206� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������E4X	qfhBRG=gR{݂DpH۱|6)srTQ��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/folder.gif������������������������������������������������������������������0000664�0001751�0001751�00000000341�10147723030�016622� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙f3333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������T(0IYE}d)@zjC,+W<
    IEqg<N"4IRaVVxl<&z#,L;�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/sphere2.gif�����������������������������������������������������������������0000664�0001751�0001751�00000000410�10147723030�016714� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33f��333���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������{hp@&i;U"aRGmru|O!@|<hOI#6PiRv8>c*{G�rp,@G|F	{Bxyj:63#JH=/7@	�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/c.gif�����������������������������������������������������������������������0000664�0001751�0001751�00000000362�10147723030�015574� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������e80@#i;UEqeM#Wk`( t
    (Q!uA!֋Jq9hRZ-fN0\pt@7l+	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/tar.gif���������������������������������������������������������������������0000664�0001751�0001751�00000000333�10147723030�016136� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����VVU777���������!DThis icon is in the public domain. 1995 Kevin Hughes, kevinh@eit.com�,�������`(0y;A|ș,#ж!؄FZ)Fb!FqN=
    94ydԙ];䌛Uz<^L=u{4҄TM	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/ps.gif����������������������������������������������������������������������0000664�0001751�0001751�00000000364�10147723030�015776� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������g80@#IjU�hV&LwU'eH{	;eAJ^X*zլrYDb8^7\(�7>F85	�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/hand.up.gif�����������������������������������������������������������������0000664�0001751�0001751�00000000337�10147723030�016711� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙f3������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������R(0
    B#cTH\m4Q꒑#ŹԷl#m_q	)"O1	`lB)uƒxO�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/screw1.gif������������������������������������������������������������������0000664�0001751�0001751�00000000402�10147723030�016551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������u0BlhaB(]@JTK/9?[\A@3$V(؉rR!v`Uʩ3u|iVf*{ǧ O~}(vp_?7O	�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/portal.gif������������������������������������������������������������������0000664�0001751�0001751�00000000376�10147723030�016660� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����3̙3333���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������qhP@&i;U"rAeᾇ'eGy
    npx|7B@x `Hy%$\N\[
    ^2֦=[-oGzp7FF2|:	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/left.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000254�10147723030�016304� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������+IXAo}N(JdDjh:)!yt]~md��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie5.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000275�10147723030�016217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������<4X	q(fHi.2^7rf<
    -(t1F�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/folder.sec.png��������������������������������������������������������������0000664�0001751�0001751�00000000471�10664777241�017437� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG
    
    ���
    IHDR���������2o5���PLTE̙33f3f��333���SV<���tRNS�@*���bKGD�H���]IDATc0r 0HI,1TJ@L'%Uq�EE
    \Lt*�Dd1
    neiiiIJie '�,<6���VtEXtcomment�This art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995v����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/compressed.gif��������������������������������������������������������������0000664�0001751�0001751�00000002016�10147723030�017514� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����f3�̙f3�f3�ffffff3f�3333f333�����f�3��f3�̙f3�̙̙̙̙f̙3̙�ffffff3f�3333f333�����f�3��̙f3�̙̙f3�̙f3�ff̙ffff3f�33̙33f333���̙��f�3��ffffff3f�fff̙fff3f�ffffff3f�fffffffffff3ff�f3f3f3f3ff33f3�f�f�f�f�ff�3f��3333f333�333̙3f333�3333f333�3f3f3f3ff3f33f�33333333f33333�3�3�3�3�f3�33������f�3�����̙�f�3������f�3���f�f�f�ff�f3�f��3�3�3�3f�33�3���������f��3����������w��U��D��"���������������w��U��D��"���������������w��U��D��"��ݻwwwUUUDDD"""���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!��$�,��������I$`d��CV
    #lСĄ+Z(0cC'NJI\G�VbZi/aƤ@75ICϟF983O@lh%QV9L4jϩ^:
    3؞K*gZ-mv}(ԧҔ%+2K$€�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/quill.gif�������������������������������������������������������������������0000664�0001751�0001751�00000000413�10147723030�016475� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����fff3333���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������~h0@&i;WGxp]BqHR/!:,CbV%H@�@d)6<1EY!~˺A=v,ipg�Zp[ys"	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/icon.sheet.gif��������������������������������������������������������������0000664�0001751�0001751�00000027311�10147723030�017414� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��̙3ff33̙3f3f�fffffff3f��UUU333��3�f�f3�3f���������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�����!dihlp,tmx|pH,Ȥrl:ШtJ6
    ֹuu
    _SXgyfpy.E]-:}vǾvk3dW@Ey$t^l|*j=z?(D8naZ{Lr`p~[rujpxµkeǙշlq͍¼~WѲ6{KУg܎ʬS烙AyƐCsn"HFP-x#Cf(O_ȥ1&"хhJ(62g J	XC<iwu+s+Z^WmV<BtQ%᪪M;c@-{I7Z:CEF
    (委3
    d:~5-F2DbjK1
    bڻalNLneNVN̵
    T=.'ez|G3Dѫ_Ͼ˟OϿ�(h&6F(VhUnD jabh"$D~0X�4h#0Xc >xdM$M$L8ɣ?N�Df7�9X%�_}UfJXl"ᦚpxNPRbV|Y9mJ'rH8A>[(*a%=RڨT¨櫴šfZ+}
    )_U`[Ȗ"ʾ0'+-m2Ot"wA
    nZImh7NEµ/�tꩿ|,P�0�L܂<
    1
    1o/�~|2<\F	��@˝_\@Q»-ˬ	30|&Z2jt	bց%IonmQ_Lj,RK10(-wobymcلDvwuƆ`O0Q۹n
    ]qt8xϮVC	9r{4ͺ/ӥw$gF촓8ƹ[OH??F\zң^ɓ#}B!1Q:P_5Ip!͏ZNvQw` (,-jQ5lxw@E	Xڋ4Psk &Є:ݝBU.T"
    ز
    QV@lEFIT"zg5)>[Y:2ЊS|v0:S}A$gd`(GI	Л%AQ#&Y.ND%MLke[z4IMF"xA!Ax"EY̥.w^0IbL2f:Ќ4IjZ̦6nz8IrL:v<Iz̧>@fu`X&&ӜJD3QdS"ꚇT/|e0j~ԡcюJQ:Y6	-2w((iT
    t0O$@™o5(q	<X85HQbSoe;GS֌1K[S+m+H`u.Q`ڔլ+}R'}gW(c#XUDQD֠j_.uOLQfJL^ĭ\YU2zeC*ܞԸdgU;6ue
    iSԴ6n\Qu.`0ӭ3F16V+4yYXKXɅ{e7oH7/2
    ާ'L
    [ΰ7{ GL⍱hH:1~L �rcɘJg̤ݸ1yM;2c%K蜑�)?2D̨�Nz/:IEiNTf6@5%ߌte,/.{nPlnW\(iLj#-Cy
    34-9kW,$pzFH&KTsȵkӳbK5fѴ�5xd^u]d	etEVۺ4m8cn{P66IYjr0b
    o7n{f5de|6ϝnuBVTnn`΀fUy6AL›=X45ЩDs4qsn5x'>BD1k�?y>ӛ=%_g#vN:Hft!ndUq75θ[;N:C])p[y0@Rt٪Gx}\/U^~YQ6纎E}z$`/6b9ɮz?[ҟ7~QOj=\ؿ<
    {MmGcw+W(тML{z	w/s#iCB&ss~Xc30kW*'wgV9EJp{p.C-ַ}1G=GkQĀivd0}`90{|sjJ/&xzAm3HJh5*W#"rIXFZ%\4: x'yVȄetUrisg"u]8Z7m( JtJz86mIx@z(c9J$}bKfKxDB`x+/"%8Xx؊8Xx؋8XxȘzOZpABPCYyF]8^sEdR$(Y-Qݘ/eCTU:gEVUxvST4%^
    Muz7Ca6UU0xK5c5T\@Xe]5[ZZ0Z[PV_e[uG	Y!E5,p7)4)\-QHEQ=|>>'+]ۅ\t9V͵·XtZ\QuvRxQÕbv}	Y#I_uU_[U鑱qSV<P^K9fy]5Ә�^襚18h|)CaQ)
    ™2`.%؉9Yy虞깞.b#rb%NBvh@FY(|e[dNhKdFgeXfEu	p
    ꠝ6BuV&CZ,xQ6'?
    Dv32	p8zV(3p#!JN^&{ckEAJ
    3`ГP�NZ6Tr?dضp\mHH#'vFY�Lhn-wHp)n334X>fZZx_zEN<bHMpf�ڨ76ov.gQw"$W17s<u�` 	2d50{owʨ:Q
    ,!F-!3-:꡸zFd
    Gڪ:QMzL3js*s.#=gdqDJz G r.i3?UX5;z+Brj%
    aS-jcxe`j2:724GkW;Y0+-C+?Pz3:Z؉ ;9A-%ˉ\'+!	<=ȂϚ:p
    5D}I+:�jv03+R+T4�F6p)ʵ`>~
    m+8t{@Ȅ'w*+oȴwUK`lh4B]7s)}Kh[q[8[b*Z1|kiS6[%K
    {Q汙<$wЉX6/ӋˋStJ_dʞ껾۾;[{ۿ�<\|
    
    XbYڈPT#5_@`؜vu#LTK(É	Ux8U	P;Zw%UA>ii3I\]Y
    	ŝyMl&U&HSUW5U1U0Ĥ~LY	^XX}嘉_|ls\SuY[TSlW@Tr%#E:ZUSuaɛ3YWjip	ŕ,LU3Y5ˀ\Y-ZA&E_9`Y\ʣUlʀ(̿%ּQ˘<ɽ|\΂9lZz,P)]ERϾyƮyW	y]\К1
    -A=ϓPy_1\7CA	=L7XK;*,,0XjT3m䘝@B=D]F}HJ4bN?P?Y""/cGYK�`b=0Kߴa͜!a]m_-vMedhdn%reZv}s�{
    ءp�F�h"q}}ؽc،M:f ʲv"B؞
    iϒӵ/ZLeُ'"J?0
    {
    jfiڵگMzҵMZC@
    ]nJ=-ܑG`Z`þb\6g=/0ꨃڬ=K;-oܓۈDSd-{ͬFݤJ42
    nP*=-;[l3Z9PذfBB^bG=]+LN~EPGФ6^{qhCn{QNik>Em>B*CWMTkR_1&9n-1p~_8+X|Tƣ$1Qr[MK}h>GKZVjjqqCGN^mwJN>25^w2>cNuN.~Q=v{ΤJp7~~gM"#>.KX>9.'^EZ>g9fӻ$!o~>!M35$RxDQx"IZ-Ã{unJJ-"j 
    HLnpr?t_vxz|~?_?T&Ol};~ˤ__LPLë8(Ǡo?0L`Sk&i_xT)ė9WOuE)Fu~b<T*}ɽǬpPiH;u_Dn)e `lHngY(i3Mpr-(X7S*N
    CRVg96Z3Ee⯰xMzs.%ؒܖ\  ]`"YUإb!%()YJפf*li*#\.+[UV]rY,k4Pwxx/9wz::pf<=3>? 	H~2+!Ĉ'Rh"ƌ7r#Ȑ"G,i$ʔ*Wl%̘2gҬi&Μ:w'РB-j(R42mӨKJuJӤN6Ÿ+؁
    fX�ڴjVxV-\n,ݵvy^敋/}x"庒1C|#pn8pԪS83dˏqtq=޹C0o
     ]x7	O`,}+N/4ΙF|ugi7Ak$ l�L``*`yIȠDh]H!G;ه~=BVB`X
    >h`vbqt_(l
    k:xGa圉 UVe�8NV�hUfFRיe)kJ"l_lb^]Yo|z~-`t-
    ۙi2m	ʙ)W1Yy@R|bŧZ=٩z#>	H"Ydw�
    g^XV-e
    {aZb$P
    jj0X",(: }
    3	VĂ6b71DuڨM"2'|Dm	\.
    _9u2Kr&2#l)>mվLyGP5_
    "]r~cpjX${,$^L7tɡ.u^]_~{7ن*uGoMHCuJo4
    j@z(]n>dK7+T\`K36zŷ;*G<ovV~=߳)Wo*_sO+'
    {֮垿?gN2E�q[g>9b $){
    ,
    %^O<'	Z|&$
    ?"FpnK@^q?B
    ؜#,J_|D%2w%[=HacX.,Qǘ9ұv#=~# )A<$"E2|$$#)IR$&3Mr$(C)Q<%*SU|%,c)YҲ%.s]Σr,0<(Ld&=90Nf)A0!%fCYx2ٸs$ǜɋkP�FRqh'49uȆ7	j&m,>abBh0+рb,EKf(
    qƀt;�
    Dl2Ja1OWjy3OoX
    Wl�q*Rk
    1s:}jKͫ5T|bU?*Tzu/]NSjղUrnJM4H[Wݫ%jf3e,8{3?)늪գ,f%:ꂫ�QT]-@Zc(}mkLN
    ]̒ڀd4.KQzc!B&wеn;{]^r.x+񒷼=/zӫ}x�~_ǼI}L6ca<#6p}/8Qta
    WQ8cq^f߉q7̥xr-V
    t`jCe\
    
    	%6͐}Ci{oMdyA7Fk99YfAft`(J0OWr\*@].<||L	a7βf4SyonH~3IqӏB-jQ33cYh:;ZV-MFO_9s6oggԢթ6}MҸX?|=Tq;Vfywm]zݘ'iZƯl|{pVnu[{𦓼k=k&uLln;ߐ8pt[nw?r:^1lQ9~ncҦaPoO*7sqXOfGrj9
    n螓Ni<]W:<i4V7qǙۓvY/%=3;Tt]#V8n>)a<599˕\jo+hx?xLIyӃ~=c/Ӿ=s=/?>3>/Sֿ>{>ufq4ijO[_#D6'4gˋڢ|na?%W�]C`WZ]h=FAVD	4* -^fr'(d} 
    j}$l`	z Im
    &^a`90J%V�Q Jidݠ#!DS
    Ug[9oQ.\a!U[i>PZ
    &I%<!aAY9bi!a"i asa%�bW9OAb/,b l!`hYkYU'm6:PV-b)>dkAB3" "f)Ve9!- u}0.r	 V82ġHveV4Ɩ0:D袐}#88#99#::#;Xȗ[c;]	>M#>nA飁Ouc<`d@@$?	(
    ~ՆT%mؒWEBEjBVaFCjLȈMc)�dFfPbCd%t-JE]xUXT&eP^KfVLƢKS^VǍ^Ul�@aDYy\qxWVMȉuȑq
     �`XR	=eW^$fX`F,։Snf^%c6fH=KkO%ff
    ]
    RY]^h~Hf4^jz[Fl
    $Aɩ٦ln�m^ږpE؜ޜmga8tbx5EکduJe$\i):őzN[%y6z�9geB'J&!{',Iy6xj*VxgrܣEXP%%70`0~YhO]tB
    ]vZgUKцr~gdKhI(gTϓy}2|أ(f~.%P5\bhzFhti{iZRfgޱ)qc\֩橌z\̚ھEs9⩉br(ihrzjYX@^	H`SjB(䅆F~#6>+FN+V^+fn+v~++++r!cz`;_&ao]!WC+1j1
    ]`Ńz2_0C&D8C@̉El2N.A.ઘBbi;~_J#
    ^lV̺+ʶj`ϊ,-2&,aT/l2"~dl"Z?b8I-2]-ZyҲlqTVbVm8
    Vm#pJ}-,JC$86m2mU.6	nB`!V"b]IQ9mIS-޾J"2-ᚠN4OY6b!,>3/nV .-&g--6fTBkjC. BRb/rop9o..J:#I\I5INc/zQo1j,/��0p|a)<WTY?d٧M#ГU0WFADvedPdۤ)	?XW
    �@jCvw(y؄Y0pƃWa�q qSk
    IJdHN:$ȅԴ�s1:
    ��@tc>	Oުu!!grfÙ0	1W81?r {=2|\K~&ejL+iX1p26� xrI
    ¦,fo>9dg,ђLr.n~bJ0&�m@++kZ15s3;+XJ:&GB6r%sjVxlv33&ހ)DHt<F>>6YY/#JuO$tꀙA#+燎^=t $EM>MPFs4?@(yl@Bt8s3"ТtntNkFwt~*&I7'T7Xks %5gU/U7&[DN
    <
    ^Ku4W#]@tH@8u-ک(ڵ}XdE˨Pgs?w	JP
    u"4bb\t64\w6?65`(%6&+_̳s
    dч
    uBS1\cP}.7$)v*3T6r~WG`oQ.@t{puV;Zp@(/
    z{p]+p^綗yetE8)a6~?*kĵjKvkojur%vv[WeCK8	j]8pgT餆x[x}P:"Oˌsx޸bCQx{7ڋ**Ҳ&!9)"O9W_9go9w9999yoբ84//N:aDV
    *:%gbj.[,;}lтllV"vaUW%lz
    m6N-"{v
    !֖m+,!~: !䲕 _m?nn&n(($._-Sa#Kz){.8::'a:z6<TQýb1=Qo5\҂"V/n:
    	zW;켲|O4Zם3O<B9<=}*YŎCpZCFkǰ䧆?;O1#h	kBQkhSZc3q=BJK
    aQګ=밽z۳w~=
    ?=Ŋ durݽ"0C䣓K>[>-y~}oF`g$A~۽~;,1R5C[Es]5<_?`=d�'�Y_GU>?Npkcw?KQ�?LEa扦V/L2zJ\*W|:�( xLM{T_{:|][D1w6$$E%uv6I	zGZJ*SRXt85{{uVj\[s{dH*9V|pWl:=
    (+qG"u'q`4}AV&By+7!ƌp8G~IJ*FMfj´3g:rwR_ț:gD)2^L12 J,58DxܖψZ?Ti(,ɑ*@cߖ+*cׯ`/Jkl܈f28i_XY!ߙeBϟ7ЭiZ(nykTRA?3W1;8
    Wؽ̋JyWV;K#){wś?>ۻ?B��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/alert.red.gif���������������������������������������������������������������0000664�0001751�0001751�00000000367�10147723030�017237� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33f��333���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������jhp@&i;WdB{^HaظjpnHP*VMW':Z+nek]G%1h~gNmg)c
    P7AK	�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie7.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000271�10147723030�016215� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������84X	qxpzȶHBjx~<2~(��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/movie.gif�������������������������������������������������������������������0000664�0001751�0001751�00000000363�10147723030�016472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙fff333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������fh4%^;1�.ch	^n^j&o\dh:`A3<"f|[zqU	6#xڣ֩"	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/generic.red.gif�������������������������������������������������������������0000664�0001751�0001751�00000000334�10147723030�017536� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����fff��333������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������OHpA%7yB#)VKxn6쮞OL	e<,1gJTc/&cAfz
    L��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/continued.gif���������������������������������������������������������������0000664�0001751�0001751�00000000326�10147723030�017342� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����fff333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������I0IؕvJ!` ɉ�*$;;ߧ0ȣi+
    !pLH%8RjvAj3xL.+�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/ball.gray.gif���������������������������������������������������������������0000664�0001751�0001751�00000000351�10147723030�017223� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̻fffUUU333���������������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������D0I8ͻI|	a#WBaiVH|&"9
    	
    _NgI %	&*T&xx,��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/comp.blue.gif���������������������������������������������������������������0000664�0001751�0001751�00000000373�10147723030�017240� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����ffff333�f���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������n0xaX 7ka˺ٌ`QaHϧ08IaaYW[UJWkVQ=`8A. ϸyz.ri'ED	�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/script.gif������������������������������������������������������������������0000664�0001751�0001751�00000000362�10147723030�016656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������e80@#i;U"U0MTq;`( T(9LR{lz5
    ^j,Fp5
    P;~3 C7sc	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/world2.gif������������������������������������������������������������������0000664�0001751�0001751�00000000405�10147723030�016561� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙�3�f3������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������x&"8(1bXWdׅ.zx7AiڰOaN 2:&|]C0wTr>xYq8Fn{=~q_K<4L#~x=	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/box2.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000414�10147723030�016222� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙333�3�f3���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������H0@$i;U"a,14``H~`x8(|F˦U^
    SDs(e]+m<=O~qzZ,d|=|`c{
    KD1;	�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/image3.gif������������������������������������������������������������������0000664�0001751�0001751�00000000436�10147723030�016521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33f��333��3�3f���������������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������yIXEvm^IYv*:vD,*DI/NnK  0ARFʤ#UAեr0dv* xZ0{fv*}stJQP>HS�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/alert.black.gif�������������������������������������������������������������0000664�0001751�0001751�00000000362�10147723030�017534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������e80@#i;W$֕xB.Qת5e>PHQfaQv5Aݒ\̴2`Iutz08<<	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/uuencoded.gif���������������������������������������������������������������0000664�0001751�0001751�00000000354�10147723030�017326� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����333������������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������_80@#)0bAfhQ#Go@W5k((vxH<Ħ8:i:NUo1k^^;.|qy	�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/folder.sec.gif��������������������������������������������������������������0000664�0001751�0001751�00000000363�10147723030�017377� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����̙33f3f��333���!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������f80Iٹ 
    
    PA;pD,3.CpLd7E0hsJYS4Fk~n^4o|~f?Z+~	�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie0.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000274�10147723030�016211� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������;4Xַ
    rBfy%6ϼ8ʐ=GyX�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/pie8.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000255�10147723030�016220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������,4hm*aTl+Hmߵ~c�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/ball.red.gif����������������������������������������������������������������0000664�0001751�0001751�00000000315�10147723030�017033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����33f�����������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������@80I]%[ adyO!%aN7/<�NCbQBU
    IeLsZجV��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/back.gif��������������������������������������������������������������������0000664�0001751�0001751�00000000330�10147723030�016245� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����fff333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������K#j3Si7Nvt7*EnXm/5FPxƤl(N ڌ:@VUϋ�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/icons/index.gif�������������������������������������������������������������������0000664�0001751�0001751�00000000414�10147723030�016457� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a����f333���������!NThis art is in the public domain. Kevin Hughes, kevinh@eit.com, September 1995�!���,�������H0@$i;U"hAREmr%F~2K0^#ChZ
    VyR2VkX(pIgÕ7VnEMOrZR9DQAG<9
    s/yy	�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/cgi-examples/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�016141� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/cgi-examples/printenv.vbs���������������������������������������������������������0000664�0001751�0001751�00000002062�12063711404�020507� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'
    
    ' To permit this cgi, replace ' on the first line above with the
    ' appropriate shebang, f.e. '!c:/windows/system32/cscript -nologo
    '
    ' ***** !!! WARNING !!! *****
    ' This script echoes the server environment variables and therefore
    ' leaks information - so NEVER use it in a live server environment!
    ' It is provided only for testing purpose.
    ' Also note that it is subject to cross site scripting attacks on
    ' MS IE and any other browser which fails to honor RFC2616. 
    
    ''
    ''  printenv -- demo CGI program which just prints its environment
    ''
    Option Explicit
    
    Dim objShell, objArray, str, envvar, envval
    Set objShell = CreateObject("WScript.Shell")
    Set objArray = CreateObject("System.Collections.ArrayList")
    
    WScript.StdOut.WriteLine "Content-type: text/plain; charset=iso-8859-1" & vbLF
    For Each str In objShell.Environment("PROCESS")
      objArray.Add str
    Next
    objArray.Sort()
    For Each str In objArray
      envvar = Left(str, InStr(str, "="))
      envval = Replace(Mid(str, InStr(str, "=") + 1), vbLF, "\n")
      WScript.StdOut.WriteLine envvar & Chr(34) & envval & Chr(34)
    Next
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/cgi-examples/printenv�������������������������������������������������������������0000664�0001751�0001751�00000001464�12063711404�017723� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    
    # To permit this cgi, replace # on the first line above with the
    # appropriate #!/path/to/perl shebang, and on Unix / Linux also
    # set this script executable with chmod 755.
    #
    # ***** !!! WARNING !!! *****
    # This script echoes the server environment variables and therefore
    # leaks information - so NEVER use it in a live server environment!
    # It is provided only for testing purpose.
    # Also note that it is subject to cross site scripting attacks on
    # MS IE and any other browser which fails to honor RFC2616. 
    
    ##
    ##  printenv -- demo CGI program which just prints its environment
    ##
    use strict;
    use warnings;
    
    print "Content-type: text/plain; charset=iso-8859-1\n\n";
    foreach my $var (sort(keys(%ENV))) {
        my $val = $ENV{$var};
        $val =~ s|\n|\\n|g;
        $val =~ s|"|\\"|g;
        print "${var}=\"${val}\"\n";
    }
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/cgi-examples/printenv.wsf���������������������������������������������������������0000664�0001751�0001751�00000002155�12063711404�020517� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'
    
    ' To permit this cgi, replace ' on the first line above with the
    ' appropriate shebang, f.e. '!c:/windows/system32/cscript -nologo
    '
    ' ***** !!! WARNING !!! *****
    ' This script echoes the server environment variables and therefore
    ' leaks information - so NEVER use it in a live server environment!
    ' It is provided only for testing purpose.
    ' Also note that it is subject to cross site scripting attacks on
    ' MS IE and any other browser which fails to honor RFC2616. 
    
    ''
    ''  printenv -- demo CGI program which just prints its environment
    ''
    <job>
    <script language="JScript">
      WScript.Echo("Content-type: text/plain; charset=iso-8859-1\n");
      var objShell = new ActiveXObject("WScript.Shell");
      var objArray = new Array();
      var e = new Enumerator(objShell.Environment("PROCESS"));
      for (;!e.atEnd();e.moveNext()) {
        var i = e.item().indexOf("=");
        var envvar = e.item().substring(0, i);
        var envval = e.item().substring(i + 1, e.item().length);
        envval = envval.replace("\n", "\\n");
        objArray.push(envvar + "=\"" + envval + "\"");
      }
      objArray.sort();
      WScript.Echo(objArray.join("\n"));
    </script>
    </job>
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/cgi-examples/test-cgi�������������������������������������������������������������0000664�0001751�0001751�00000002355�12063711404�017575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    
    # To permit this cgi, replace # on the first line above with the
    # appropriate #!/path/to/sh shebang, and set this script executable
    # with chmod 755.
    #
    # ***** !!! WARNING !!! *****
    # This script echoes the server environment variables and therefore
    # leaks information - so NEVER use it in a live server environment!
    # It is provided only for testing purpose.
    # Also note that it is subject to cross site scripting attacks on
    # MS IE and any other browser which fails to honor RFC2616. 
    
    # 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/docroot/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�015234� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/docroot/index.html����������������������������������������������������������������0000664�0001751�0001751�00000000055�10633315032�017214� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html><body><h1>It works!</h1></body></html>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/docs/doxygen.conf����������������������������������������������������������������������0000664�0001751�0001751�00000003423�11711771300�016076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PROJECT_NAME=Apache2
    
    # make the generated documentation searchable
    SEARCHENGINE=YES
    INPUT=.
    RECURSIVE=YES
    FILE_PATTERNS=*.h
    
    OUTPUT_DIRECTORY=docs/dox
    
    #EXTRACT_STATIC=YES
    EXTRACT_ALL=YES
    
    # add documentation for functions that are declared internal use only
    INTERNAL_DOCS=YES
    HAVE_DOT=YES
    CLASS_GRAPH=YES
    
    
    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;" \
           "APR_DECLARE_OPTIONAL_FN(ret,name,args)=ret name args;" \
           "APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args)= ret ns##_hook_##name args;" \
           "AP_DECLARE(x)=x" \
           "AP_DECLARE_NONSTD(x)=x" \
           AP_CORE_DECLARE(x)=x \
           "AP_CORE_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" \
    	"CACHE_DECLARE(x)=x" \
    	"PROXY_DECLARE(x)=x"
    	
    
    OPTIMIZE_OUTPUT_FOR_C=YES
    
    GENERATE_TREEVIEW=YES
    
    FULL_PATH_NAMES=YES
    # some autoconf guru needs to make configure set this correctly...
    #STRIP_FROM_PATH=/var/www/lxr/source
    
    #GENERATE_TAGFILE=docs/dox/httpd.tag
    #TAGFILES=../apr/docs/dox/apr.tag=/apr ../apr-util/docs/dox/apu.tag=/apr-util
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/�������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766625�014261� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_hooks.h���������������������������������������������������������������������0000664�0001751�0001751�00000013544�11637145452�016240� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ap_hooks.h
     * @brief ap hook functions and macros
     */
    
    #ifndef AP_HOOKS_H
    #define AP_HOOKS_H
    
    /* Although this file doesn't declare any hooks, declare the hook group here */
    /**
     * @defgroup hooks Apache Hooks
     * @ingroup  APACHE_CORE
     */
    
    #if defined(AP_HOOK_PROBES_ENABLED) && !defined(APR_HOOK_PROBES_ENABLED)
    #define APR_HOOK_PROBES_ENABLED 1
    #endif
    
    #ifdef APR_HOOK_PROBES_ENABLED
    #include "ap_hook_probes.h"
    #endif
    
    #include "apr.h"
    #include "apr_hooks.h"
    #include "apr_optional_hooks.h"
    
    #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 */
    
    /**
     * 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_<i>name</i>.
     *
     * @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_<i>name</i>.
     *
     * @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_<i>name</i>.
     *
     * @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)
    
    #endif /* AP_HOOKS_H */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_mutex.h�������������������������������������������������������������������0000664�0001751�0001751�00000022114�11644364553�016630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_mutex.h
     * @brief Apache Mutex support library
     *
     * @defgroup APACHE_CORE_MUTEX Mutex Library
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef UTIL_MUTEX_H
    #define UTIL_MUTEX_H
    
    #include "httpd.h"
    #include "http_config.h"
    #include "apr_global_mutex.h"
    
    #if APR_HAS_FLOCK_SERIALIZE
    # define AP_LIST_FLOCK_SERIALIZE ", 'flock:/path/to/file'"
    #else
    # define AP_LIST_FLOCK_SERIALIZE
    #endif
    #if APR_HAS_FCNTL_SERIALIZE
    # define AP_LIST_FCNTL_SERIALIZE ", 'fcntl:/path/to/file'"
    #else
    # define AP_LIST_FCNTL_SERIALIZE
    #endif
    #if APR_HAS_SYSVSEM_SERIALIZE
    # define AP_LIST_SYSVSEM_SERIALIZE ", 'sysvsem'"
    #else
    # define AP_LIST_SYSVSEM_SERIALIZE
    #endif
    #if APR_HAS_POSIXSEM_SERIALIZE
    # define AP_LIST_POSIXSEM_SERIALIZE ", 'posixsem'"
    #else
    # define AP_LIST_POSIXSEM_SERIALIZE
    #endif
    #if APR_HAS_PROC_PTHREAD_SERIALIZE
    # define AP_LIST_PTHREAD_SERIALIZE ", 'pthread'"
    #else
    # define AP_LIST_PTHREAD_SERIALIZE
    #endif
    #if APR_HAS_FLOCK_SERIALIZE || APR_HAS_FCNTL_SERIALIZE
    # define AP_LIST_FILE_SERIALIZE ", 'file:/path/to/file'"
    #else
    # define AP_LIST_FILE_SERIALIZE
    #endif
    #if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
    # define AP_LIST_SEM_SERIALIZE ", 'sem'"
    #else
    # define AP_LIST_SEM_SERIALIZE
    #endif
    
    #define AP_ALL_AVAILABLE_MUTEXES_STRING                  \
        "Mutex mechanisms are: 'none', 'default'"            \
        AP_LIST_FLOCK_SERIALIZE   AP_LIST_FCNTL_SERIALIZE    \
        AP_LIST_FILE_SERIALIZE    AP_LIST_PTHREAD_SERIALIZE  \
        AP_LIST_SYSVSEM_SERIALIZE AP_LIST_POSIXSEM_SERIALIZE \
        AP_LIST_SEM_SERIALIZE
    
    #define AP_AVAILABLE_MUTEXES_STRING                      \
        "Mutex mechanisms are: 'default'"                    \
        AP_LIST_FLOCK_SERIALIZE   AP_LIST_FCNTL_SERIALIZE    \
        AP_LIST_FILE_SERIALIZE    AP_LIST_PTHREAD_SERIALIZE  \
        AP_LIST_SYSVSEM_SERIALIZE AP_LIST_POSIXSEM_SERIALIZE \
        AP_LIST_SEM_SERIALIZE
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * Get Mutex config data and parse it
     * @param arg The mutex config string
     * @param pool The allocation pool
     * @param mutexmech The APR mutex locking mechanism
     * @param mutexfile The lockfile to use as required
     * @return APR status code
     * @fn apr_status_t ap_parse_mutex(const char *arg, apr_pool_t *pool,
                                            apr_lockmech_e *mutexmech,
                                            const char **mutexfile)
     */
    AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool,
                                            apr_lockmech_e *mutexmech,
                                            const char **mutexfile);
    
    /* private function to process the Mutex directive */
    AP_DECLARE_NONSTD(const char *) ap_set_mutex(cmd_parms *cmd, void *dummy,
                                                 const char *arg);
    
    /* private function to initialize Mutex infrastructure */
    AP_DECLARE_NONSTD(void) ap_mutex_init(apr_pool_t *p);
    
    /**
     * option flags for ap_mutex_register(), ap_global_mutex_create(), and
     * ap_proc_mutex_create()
     */
    #define AP_MUTEX_ALLOW_NONE    1 /* allow "none" as mutex implementation;
                                      * respected only on ap_mutex_register()
                                      */
    #define AP_MUTEX_DEFAULT_NONE  2 /* default to "none" for this mutex;
                                      * respected only on ap_mutex_register()
                                      */
    
    /**
     * Register a module's mutex type with core to allow configuration
     * with the Mutex directive.  This must be called in the pre_config
     * hook; otherwise, configuration directives referencing this mutex
     * type will be rejected.
     *
     * The default_dir and default_mech parameters allow a module to set
     * defaults for the lock file directory and mechanism.  These could
     * be based on compile-time settings.  These aren't required except
     * in special circumstances.
     *
     * The order of precedence for the choice of mechanism and lock file
     * directory is:
     *
     *   1. Mutex directive specifically for this mutex
     *      e.g., Mutex mpm-default flock:/tmp/mpmlocks
     *   2. Mutex directive for global default
     *      e.g., Mutex default flock:/tmp/httpdlocks
     *   3. Defaults for this mutex provided on the ap_mutex_register()
     *   4. Built-in defaults for all mutexes, which are
     *      APR_LOCK_DEFAULT and DEFAULT_REL_RUNTIMEDIR.
     *
     * @param pconf The pconf pool
     * @param type The type name of the mutex, used as the basename of the
     * file associated with the mutex, if any.  This must be unique among
     * all mutex types (mutex creation accommodates multi-instance mutex
     * types); mod_foo might have mutex  types "foo-pipe" and "foo-shm"
     * @param default_dir Default dir for any lock file required for this
     * lock, to override built-in defaults; should be NULL for most
     * modules, to respect built-in defaults
     * @param default_mech Default mechanism for this lock, to override
     * built-in defaults; should be APR_LOCK_DEFAULT for most modules, to
     * respect built-in defaults
     * or NULL if there are no defaults for this mutex.
     * @param options combination of AP_MUTEX_* constants, or 0 for defaults
     */
    AP_DECLARE(apr_status_t) ap_mutex_register(apr_pool_t *pconf,
                                               const char *type,
                                               const char *default_dir,
                                               apr_lockmech_e default_mech,
                                               apr_int32_t options);
    
    /**
     * Create an APR global mutex that has been registered previously with
     * ap_mutex_register().  Mutex files, permissions, and error logging will
     * be handled internally.
     * @param mutex The memory address where the newly created mutex will be
     * stored.  If this mutex is disabled, mutex will be set to NULL on
     * output.  (That is allowed only if the AP_MUTEX_ALLOW_NONE flag is
     * passed to ap_mutex_register().)
     * @param name The generated filename of the created mutex, or NULL if
     * no file was created.  Pass NULL if this result is not needed.
     * @param type The type name of the mutex, matching the type name passed
     * to ap_mutex_register().
     * @param instance_id A unique string to be used in the lock filename IFF
     * this mutex type is multi-instance, NULL otherwise.
     * @param server server_rec of main server
     * @param pool pool lifetime of the mutex
     * @param options combination of AP_MUTEX_* constants, or 0 for defaults
     * (currently none are defined for this function)
     */
    AP_DECLARE(apr_status_t) ap_global_mutex_create(apr_global_mutex_t **mutex,
                                                    const char **name,
                                                    const char *type,
                                                    const char *instance_id,
                                                    server_rec *server,
                                                    apr_pool_t *pool,
                                                    apr_int32_t options);
    
    /**
     * Create an APR proc mutex that has been registered previously with
     * ap_mutex_register().  Mutex files, permissions, and error logging will
     * be handled internally.
     * @param mutex The memory address where the newly created mutex will be
     * stored.  If this mutex is disabled, mutex will be set to NULL on
     * output.  (That is allowed only if the AP_MUTEX_ALLOW_NONE flag is
     * passed to ap_mutex_register().)
     * @param name The generated filename of the created mutex, or NULL if
     * no file was created.  Pass NULL if this result is not needed.
     * @param type The type name of the mutex, matching the type name passed
     * to ap_mutex_register().
     * @param instance_id A unique string to be used in the lock filename IFF
     * this mutex type is multi-instance, NULL otherwise.
     * @param server server_rec of main server
     * @param pool pool lifetime of the mutex
     * @param options combination of AP_MUTEX_* constants, or 0 for defaults
     * (currently none are defined for this function)
     */
    AP_DECLARE(apr_status_t) ap_proc_mutex_create(apr_proc_mutex_t **mutex,
                                                  const char **name,
                                                  const char *type,
                                                  const char *instance_id,
                                                  server_rec *server,
                                                  apr_pool_t *pool,
                                                  apr_int32_t options);
    
    AP_CORE_DECLARE(void) ap_dump_mutexes(apr_pool_t *p, server_rec *s, apr_file_t *out);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* UTIL_MUTEX_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_cfgtree.h�����������������������������������������������������������������0000664�0001751�0001751�00000006121�11637105701�017073� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_cfgtree.h
     * @brief Config Tree Package
     *
     * @defgroup APACHE_CORE_CONFIG_TREE Config Tree Package
     * @ingroup  APACHE_CORE_CONFIG
     * @{
     */
    
    #ifndef AP_CONFTREE_H
    #define AP_CONFTREE_H
    
    #include "ap_config.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    typedef struct ap_directive_t ap_directive_t;
    
    /**
     * @brief 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 &lt;Directory ...&gt; cause a sub-level
     * to be created, where the included directives are stored.  The closing
     * directive (&lt;/Directory&gt;) 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 */
        struct ap_directive_t *next;
        /** The first child node of this directive */
        struct ap_directive_t *first_child;
        /** The parent node of this directive */
        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;
    
        /** A short-cut towards the last directive node in the tree.
         *  The value may not always be up-to-date but it always points to
         *  somewhere in the tree, nearer to the tail.
         *  This value is only set in the first node
         */
        struct ap_directive_t *last;
    };
    
    /**
     * The root of the configuration tree
     */
    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);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_compat.h��������������������������������������������������������������������0000664�0001751�0001751�00000002063�10455005461�016362� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  ap_compat.h
     * @brief Redefine Apache 1.3 symbols
     */
    
    #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 */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/mod_request.h������������������������������������������������������������������0000664�0001751�0001751�00000003134�11527536437�016763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    
    /**
     * @file  mod_request.h
     * @brief mod_request private header file
     *
     * @defgroup MOD_REQUEST mod_request
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #ifndef MOD_REQUEST_H
    #define MOD_REQUEST_H
    
    #include "apr.h"
    #include "apr_buckets.h"
    #include "apr_optional.h"
    
    #include "httpd.h"
    #include "util_filter.h"
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    extern module AP_MODULE_DECLARE_DATA request_module;
    
    #define KEEP_BODY_FILTER "KEEP_BODY"
    #define KEPT_BODY_FILTER "KEPT_BODY"
    
    /**
     * Core per-directory configuration.
     */
    typedef struct {
        apr_off_t keep_body;
        int keep_body_set;
    } request_dir_conf;
    
    APR_DECLARE_OPTIONAL_FN(void, ap_request_insert_filter, (request_rec * r));
    
    APR_DECLARE_OPTIONAL_FN(void, ap_request_remove_filter, (request_rec * r));
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* !MOD_REQUEST_H */
    /** @} */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_release.h�������������������������������������������������������������������0000664�0001751�0001751�00000006110�15032765673�016532� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ap_release.h
     * @brief Version Release defines
     */
    
    #ifndef AP_RELEASE_H
    #define AP_RELEASE_H
    
    #define AP_SERVER_COPYRIGHT \
      "Copyright 2025 The Apache Software Foundation."
    
    /*
     * 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_BASEPROJECT "Apache HTTP Server"
    #define AP_SERVER_BASEPRODUCT "Apache"
    
    #define AP_SERVER_MAJORVERSION_NUMBER 2
    #define AP_SERVER_MINORVERSION_NUMBER 4
    #define AP_SERVER_PATCHLEVEL_NUMBER   64
    #define AP_SERVER_DEVBUILD_BOOLEAN    0
    
    /* Synchronize the above with docs/manual/style/version.ent */
    
    #if !AP_SERVER_DEVBUILD_BOOLEAN
    #define AP_SERVER_ADD_STRING          ""
    #else
    #ifndef AP_SERVER_ADD_STRING
    #define AP_SERVER_ADD_STRING          "-dev"
    #endif
    #endif
    
    /* APR_STRINGIFY is defined here, and also in apr_general.h, so wrap it */
    #ifndef APR_STRINGIFY
    /** Properly quote a value as a string in the C preprocessor */
    #define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
    /** Helper macro for APR_STRINGIFY */
    #define APR_STRINGIFY_HELPER(n) #n
    #endif
    
    /* keep old macros as well */
    #define AP_SERVER_MAJORVERSION  APR_STRINGIFY(AP_SERVER_MAJORVERSION_NUMBER)
    #define AP_SERVER_MINORVERSION  APR_STRINGIFY(AP_SERVER_MINORVERSION_NUMBER)
    #define AP_SERVER_PATCHLEVEL    APR_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
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/scoreboard.h�������������������������������������������������������������������0000664�0001751�0001751�00000023702�15017526033�016547� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  scoreboard.h
     * @brief Apache scoreboard library
     */
    
    #ifndef APACHE_SCOREBOARD_H
    #define APACHE_SCOREBOARD_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #if APR_HAVE_SYS_TIME_H
    #include <sys/time.h>
    #include <sys/times.h>
    #endif
    
    #include "ap_config.h"
    #include "http_config.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 indices.  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;
    
    /* stuff which is worker specific */
    typedef struct worker_score worker_score;
    struct worker_score {
    #if APR_HAS_THREADS
        apr_os_thread_t tid;
    #endif
        int thread_num;
        /* 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 short conn_count;
        apr_off_t     conn_bytes;
        unsigned long access_count;
        apr_off_t     bytes_served;
        unsigned long my_access_count;
        apr_off_t     my_bytes_served;
        apr_time_t start_time;
        apr_time_t stop_time;
        apr_time_t last_used;
    #ifdef HAVE_TIMES
        struct tms times;
    #endif
        char client[32];            /* DEPRECATED: Keep 'em small... */
        char request[64];           /* We just want an idea... */
        char vhost[32];             /* What virtual host is being accessed? */
        char protocol[16];          /* What protocol is used on the connection? */
        apr_time_t duration;
        char client64[64];
    };
    
    typedef struct {
        int             server_limit;
        int             thread_limit;
        ap_generation_t running_generation; /* the generation of children which
                                             * should still be serving requests.
                                             */
        apr_time_t restart_time;
    #ifdef HAVE_TIMES
        struct tms times;
    #endif
    } 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 */
        char quiescing;         /* the process whose pid is stored above is
                                 * going down gracefully
                                 */
        char not_accepting;     /* the process is busy and is not accepting more
                                 * connections (for async MPMs)
                                 */
        apr_uint32_t connections;       /* total connections (for async MPMs) */
        apr_uint32_t write_completion;  /* async connections in write completion */
        apr_uint32_t lingering_close;   /* async connections in lingering close */
        apr_uint32_t keep_alive;        /* async connections in keep alive */
        apr_uint32_t suspended;         /* connections suspended by some module */
        int bucket;  /* Listener bucket used by this child; this field is DEPRECATED
                      * and no longer updated by the MPMs (i.e. always zero).
                      */
        apr_uint32_t wait_io;           /* async connections waiting an IO in the MPM */
    };
    
    /* 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 indices into the (possibly relocated) shmem records.
     */
    typedef struct {
        global_score *global;
        process_score *parent;
        worker_score **servers;
    } scoreboard;
    
    typedef struct ap_sb_handle_t ap_sb_handle_t;
    
    /*
     * Creation and deletion (internal)
     */
    int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e t);
    apr_status_t ap_cleanup_scoreboard(void *d);
    
    /*
     * APIs for MPMs and other modules
     */
    AP_DECLARE(int) ap_exists_scoreboard_image(void);
    AP_DECLARE(void) ap_increment_counts(ap_sb_handle_t *sbh, request_rec *r);
    AP_DECLARE(void) ap_set_conn_count(ap_sb_handle_t *sb, request_rec *r, unsigned short conn_count);
    
    AP_DECLARE(apr_status_t) ap_reopen_scoreboard(apr_pool_t *p, apr_shm_t **shm, int detached);
    AP_DECLARE(void) ap_init_scoreboard(void *shared_score);
    AP_DECLARE(int) ap_calc_scoreboard_size(void);
    
    AP_DECLARE(void) ap_create_sb_handle(ap_sb_handle_t **new_sbh, apr_pool_t *p,
                                         int child_num, int thread_num);
    AP_DECLARE(void) ap_update_sb_handle(ap_sb_handle_t *sbh,
                                         int child_num, int thread_num);
    
    AP_DECLARE(int) ap_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);
    AP_DECLARE(int) ap_update_child_status_from_conn(ap_sb_handle_t *sbh, int status, conn_rec *c);
    AP_DECLARE(int) ap_update_child_status_from_server(ap_sb_handle_t *sbh, int status, 
                                                       conn_rec *c, server_rec *s);
    AP_DECLARE(int) ap_update_child_status_descr(ap_sb_handle_t *sbh, int status, const char *descr);
    
    AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status);
    AP_DECLARE(void) ap_set_time_process_request(ap_sb_handle_t* const sbh,
    		const apr_time_t timebeg,const apr_time_t timeend);
        
    AP_DECLARE(int) ap_update_global_status(void);
    
    AP_DECLARE(worker_score *) ap_get_scoreboard_worker(ap_sb_handle_t *sbh);
    
    /** Return a pointer to the worker_score for a given child, thread pair.
     * @param child_num The child number.
     * @param thread_num The thread number.
     * @return A pointer to the worker_score structure.
     * @deprecated This function is deprecated, use ap_copy_scoreboard_worker instead. */
    AP_DECLARE(worker_score *) ap_get_scoreboard_worker_from_indexes(int child_num,
                                                                    int thread_num);
    
    /** Copy the contents of a worker scoreboard entry.  The contents of
     * the worker_score structure are copied verbatim into the dest
     * structure.
     * @param dest Output parameter.
     * @param child_num The child number.
     * @param thread_num The thread number.
     */
    AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest,
                                               int child_num, int thread_num);
    
    AP_DECLARE(process_score *) ap_get_scoreboard_process(int x);
    AP_DECLARE(global_score *) ap_get_scoreboard_global(void);
    
    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 int ap_mod_status_reqtail;
    
    /*
     * Command handlers [internal]
     */
    const char *ap_set_scoreboard(cmd_parms *cmd, void *dummy, const char *arg);
    const char *ap_set_extended_status(cmd_parms *cmd, void *dummy, int arg);
    const char *ap_set_reqtail(cmd_parms *cmd, void *dummy, int arg);
    
    /* 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))
    
    /* for time_process_request() in http_main.c */
    #define START_PREQUEST 1
    #define STOP_PREQUEST  2
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_SCOREBOARD_H */
    ��������������������������������������������������������������httpd-2.4.64/include/ap_mmn.h�����������������������������������������������������������������������0000664�0001751�0001751�00000117032�15032733516�015676� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  ap_mmn.h
     * @brief Module Magic Number
     *
     * @defgroup APACHE_CORE_MMN Module Magic Number
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_AP_MMN_H
    #define APACHE_AP_MMN_H
    
    /*
     * 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 AP_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-deprecated 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.
     * 20050305.3 (2.1.5-dev)  added Protocol Framework.
     * 20050701.0 (2.1.7-dev)  Bump MODULE_MAGIC_COOKIE to "AP21"!
     * 20050701.1 (2.1.7-dev)  trace_enable member added to core server_config
     * 20050708.0 (2.1.7-dev)  Bump MODULE_MAGIC_COOKIE to "AP22"!
     * 20050708.1 (2.1.7-dev)  add proxy request_status hook (minor)
     * 20050919.0 (2.1.8-dev)  mod_ssl ssl_ext_list optional function added
     * 20051005.0 (2.1.8-dev)  NET_TIME filter eliminated
     * 20051005.0 (2.3.0-dev)  Bump MODULE_MAGIC_COOKIE to "AP24"!
     * 20051115.0 (2.3.0-dev)  Added use_canonical_phys_port to core_dir_config
     * 20060110.0 (2.3.0-dev)  Conversion of Authz to be provider based
     *                         addition of <SatisfyAll><SatisfyOne>
     *                         removal of Satisfy, Allow, Deny, Order
     * 20060110.1 (2.3.0-dev)  minex and minex_set members added to
     *                         cache_server_conf (minor)
     * 20060110.2 (2.3.0-dev)  flush_packets and flush_wait members added to
     *                         proxy_server (minor)
     * 20060110.3 (2.3.0-dev)  added inreslist member to proxy_conn_rec (minor)
     * 20060110.4 (2.3.0-dev)  Added server_scheme member to server_rec (minor)
     * 20060905.0 (2.3.0-dev)  Replaced ap_get_server_version() with
     *                         ap_get_server_banner() and ap_get_server_description()
     * 20060905.1 (2.3.0-dev)  Enable retry=0 for the worker (minor)
     * 20060905.2 (2.3.0-dev)  Added ap_all_available_mutexes_string,
     *                         ap_available_mutexes_string and
     *                         ap_parse_mutex()
     * 20060905.3 (2.3.0-dev)  Added conn_rec::clogging_input_filters.
     * 20060905.4 (2.3.0-dev)  Added proxy_balancer::sticky_path.
     * 20060905.5 (2.3.0-dev)  Added ap_mpm_safe_kill()
     * 20070823.0 (2.3.0-dev)  Removed ap_all_available_mutexes_string,
     *                         ap_available_mutexes_string for macros
     * 20070823.1 (2.3.0-dev)  add ap_send_interim_response()
     * 20071023.0 (2.3.0-dev)  add ap_get_scoreboard(sbh) split from the less
     *                         conventional ap_get_scoreboard(proc, thread)
     * 20071023.1 (2.3.0-dev)  Add flags field to struct proxy_alias
     * 20071023.2 (2.3.0-dev)  Add ap_mod_status_reqtail
     * 20071023.3 (2.3.0-dev)  Declare ap_time_process_request() as part of the
     *                         public scoreboard API.
     * 20071108.1 (2.3.0-dev)  Add the optional kept_body brigade to request_rec
     * 20071108.2 (2.3.0-dev)  Add st and keep fields to struct util_ldap_connection_t
     * 20071108.3 (2.3.0-dev)  Add API guarantee for adding connection filters
     *                         with non-NULL request_rec pointer (ap_add_*_filter*)
     * 20071108.4 (2.3.0-dev)  Add ap_proxy_ssl_connection_cleanup
     * 20071108.5 (2.3.0-dev)  Add *scpool to proxy_conn_rec structure
     * 20071108.6 (2.3.0-dev)  Add *r and need_flush to proxy_conn_rec structure
     * 20071108.7 (2.3.0-dev)  Add *ftp_directory_charset to proxy_dir_conf
     * 20071108.8 (2.3.0-dev)  Add optional function ap_logio_add_bytes_in() to mog_logio
     * 20071108.9 (2.3.0-dev)  Add chroot support to unixd_config
     * 20071108.10(2.3.0-dev)  Introduce new ap_expr API
     * 20071108.11(2.3.0-dev)  Revise/Expand new ap_expr API
     * 20071108.12(2.3.0-dev)  Remove ap_expr_clone from the API (same day it was added)
     * 20080403.0 (2.3.0-dev)  Add condition field to core dir config
     * 20080403.1 (2.3.0-dev)  Add authn/z hook and provider registration wrappers.
     * 20080403.2 (2.3.0-dev)  Add ap_escape_path_segment_buffer() and ap_unescape_all().
     * 20080407.0 (2.3.0-dev)  Remove ap_graceful_stop_signalled.
     * 20080407.1              Deprecate ap_cache_cacheable_hdrs_out and add two
     *                         generalized ap_cache_cacheable_headers_(in|out).
     * 20080528.0 (2.3.0-dev)  Switch order of ftp_directory_charset and
     *                         interpolate_env in proxy_dir_conf.
     *                         Rationale: see r661069.
     * 20080528.1 (2.3.0-dev)  add has_realm_hash() to authn_provider struct
     * 20080722.0 (2.3.0-dev)  remove has_realm_hash() from authn_provider struct
     * 20080722.1 (2.3.0-dev)  Add conn_timeout and conn_timeout_set to
     *                         proxy_worker struct.
     * 20080722.2 (2.3.0-dev)  Add scolonsep to proxy_balancer
     * 20080829.0 (2.3.0-dev)  Add cookie attributes when removing cookies
     * 20080830.0 (2.3.0-dev)  Cookies can be set on headers_out and err_headers_out
     * 20080920.0 (2.3.0-dev)  Add ap_mpm_register_timed_callback.
     * 20080920.1 (2.3.0-dev)  Export mod_rewrite.h in the public API.
     * 20080920.2 (2.3.0-dev)  Added ap_timeout_parameter_parse to util.c / httpd.h
     * 20081101.0 (2.3.0-dev)  Remove unused AUTHZ_GROUP_NOTE define.
     * 20081102.0 (2.3.0-dev)  Remove authz_provider_list, authz_request_state,
     *                         and AUTHZ_ACCESS_PASSED_NOTE.
     * 20081104.0 (2.3.0-dev)  Remove r and need_flush fields from proxy_conn_rec
     *                         as they are no longer used and add
     *                         ap_proxy_buckets_lifetime_transform to mod_proxy.h
     * 20081129.0 (2.3.0-dev)  Move AP_FILTER_ERROR and AP_NOBODY_READ|WROTE
     *                         from util_filter.h to httpd.h and change their
     *                         numeric values so they do not overlap with other
     *                         potential status codes
     * 20081201.0 (2.3.0-dev)  Rename several APIs to include ap_ prefix.
     * 20081201.1 (2.3.0-dev)  Added ap_args_to_table and ap_body_to_table.
     * 20081212.0 (2.3.0-dev)  Remove sb_type from process_score in scoreboard.h.
     * 20081231.0 (2.3.0-dev)  Switch ap_escape_html API: add ap_escape_html2,
     *                         and make ap_escape_html a macro for it.
     * 20090130.0 (2.3.2-dev)  Add ap_ prefix to unixd_setup_child().
     * 20090131.0 (2.3.2-dev)  Remove ap_default_type(), disable DefaultType
     * 20090208.0 (2.3.2-dev)  Add conn_rec::current_thread.
     * 20090208.1 (2.3.3-dev)  Add ap_retained_data_create()/ap_retained_data_get()
     * 20090401.0 (2.3.3-dev)  Remove ap_threads_per_child, ap_max_daemons_limit,
     *                         ap_my_generation, etc.  ap_mpm_query() can't be called
     *                         until after the register-hooks phase.
     * 20090401.1 (2.3.3-dev)  Protected log.c internals, http_log.h changes
     * 20090401.2 (2.3.3-dev)  Added tmp_flush_bb to core_output_filter_ctx_t
     * 20090401.3 (2.3.3-dev)  Added DAV options provider to mod_dav.h
     * 20090925.0 (2.3.3-dev)  Added server_rec::context and added *server_rec
     *                         param to ap_wait_or_timeout()
     * 20090925.1 (2.3.3-dev)  Add optional function ap_logio_get_last_bytes() to
     *                         mod_logio
     * 20091011.0 (2.3.3-dev)  Move preserve_host{,_set} from proxy_server_conf to
     *                         proxy_dir_conf
     * 20091011.1 (2.3.3-dev)  add debug_level to util_ldap_state_t
     * 20091031.0 (2.3.3-dev)  remove public LDAP referral-related macros
     * 20091119.0 (2.3.4-dev)  dav_error interface uses apr_status_t parm, not errno
     * 20091119.1 (2.3.4-dev)  ap_mutex_register(), ap_{proc,global}_mutex_create()
     * 20091229.0 (2.3.5-dev)  Move allowed_connect_ports from proxy_server_conf
     *                         to mod_proxy_connect
     * 20091230.0 (2.3.5-dev)  Move ftp_directory_charset from proxy_dir_conf
     *                         to proxy_ftp_dir_conf(mod_proxy_ftp)
     * 20091230.1 (2.3.5-dev)  add util_ldap_state_t.opTimeout
     * 20091230.2 (2.3.5-dev)  add ap_get_server_name_for_url()
     * 20091230.3 (2.3.6-dev)  add ap_parse_log_level()
     * 20091230.4 (2.3.6-dev)  export ap_process_request_after_handler() for mod_serf
     * 20100208.0 (2.3.6-dev)  ap_socache_provider_t API changes to store and iterate
     * 20100208.1 (2.3.6-dev)  Added forward member to proxy_conn_rec
     * 20100208.2 (2.3.6-dev)  Added ap_log_command_line().
     * 20100223.0 (2.3.6-dev)  LDAP client_certs per-server moved to per-dir
     * 20100223.1 (2.3.6-dev)  Added ap_process_fnmatch_configs().
     * 20100504.0 (2.3.6-dev)  Added name arg to ap_{proc,global}_mutex_create().
     * 20100604.0 (2.3.6-dev)  Remove unused core_dir_config::loglevel
     * 20100606.0 (2.3.6-dev)  Make ap_log_*error macro wrappers around
     *                         ap_log_*error_ to save argument preparation and
     *                         function call overhead.
     *                         Introduce per-module loglevels, including new APIs
     *                         APLOG_USE_MODULE() and AP_DECLARE_MODULE().
     * 20100606.1 (2.3.6-dev)  Added extended timestamp formatting via
     *                         ap_recent_ctime_ex().
     * 20100609.0 (2.3.6-dev)  Dropped ap_body_to_table due to missing constraints.
     * 20100609.1 (2.3.7-dev)  Introduce ap_log_cserror()
     * 20100609.2 (2.3.7-dev)  Add deferred write pool to core_output_filter_ctx
     * 20100625.0 (2.3.7-dev)  Add 'userctx' to socache iterator callback prototype
     * 20100630.0 (2.3.7-dev)  make module_levels vector of char instead of int
     * 20100701.0 (2.3.7-dev)  re-order struct members to improve alignment
     * 20100701.1 (2.3.7-dev)  add note_auth_failure hook
     * 20100701.2 (2.3.7-dev)  add ap_proxy_*_wid() functions
     * 20100714.0 (2.3.7-dev)  add access_checker_ex hook, add AUTHZ_DENIED_NO_USER
     *                         to authz_status, call authz providers twice to allow
     *                         authz without authenticated user
     * 20100719.0 (2.3.7-dev)  Add symbol name parameter to ap_add_module and
     *                         ap_add_loaded_module. Add ap_find_module_short_name
     * 20100723.0 (2.3.7-dev)  Remove ct_output_filters from core rec
     * 20100723.1 (2.3.7-dev)  Added ap_proxy_hashfunc() and hash elements to
     *                         proxy worker structs
     * 20100723.2 (2.3.7-dev)  Add ap_request_has_body()
     * 20100723.3 (2.3.8-dev)  Add ap_check_mpm()
     * 20100905.0 (2.3.9-dev)  Add log_id to conn and req recs. Add error log
     *                         format handlers. Support AP_CTIME_OPTION_COMPACT in
     *                         ap_recent_ctime_ex().
     * 20100905.1 (2.3.9-dev)  Add ap_cache_check_allowed()
     * 20100912.0 (2.3.9-dev)  Add an additional "out" brigade parameter to the
     *                         mod_cache store_body() provider function.
     * 20100916.0 (2.3.9-dev)  Add commit_entity() to the mod_cache provider
     *                         interface.
     * 20100918.0 (2.3.9-dev)  Move the request_rec within mod_include to be
     *                         exposed within include_ctx_t.
     * 20100919.0 (2.3.9-dev)  Authz providers: Add parsed_require_line parameter
     *                         to check_authorization() function. Add
     *                         parse_require_line() function.
     * 20100919.1 (2.3.9-dev)  Introduce ap_rxplus util/API
     * 20100921.0 (2.3.9-dev)  Add an apr_bucket_brigade to the create_entity
     *                         provider interface for mod_cache.h.
     * 20100922.0 (2.3.9-dev)  Move cache_* functions from mod_cache.h to a
     *                         private header file.
     * 20100923.0 (2.3.9-dev)  Remove MOD_CACHE_REQUEST_REC, remove deprecated
     *                         ap_cache_cacheable_hdrs_out, trim cache_object_t,
     *                         make ap_cache_accept_headers, ap_cache_accept_headers
     *                         ap_cache_try_lock, ap_cache_check_freshness,
     *                         cache_server_conf, cache_enable, cache_disable,
     *                         cache_request_rec and cache_provider_list private.
     * 20100923.1 (2.3.9-dev)  Add cache_status hook.
     * 20100923.2 (2.3.9-dev)  Add generate_log_id hook.
     *                         Make root parameter of ap_expr_eval() const.
     * 20100923.3 (2.3.9-dev)  Add "last" member to ap_directive_t
     * 20101012.0 (2.3.9-dev)  Add header to cache_status hook.
     * 20101016.0 (2.3.9-dev)  Remove ap_cache_check_allowed().
     * 20101017.0 (2.3.9-dev)  Make ap_cache_control() public, add cache_control_t
     *                         to mod_disk_cache format.
     * 20101106.0 (2.3.9-dev)  Replace the ap_expr parser derived from
     *                         mod_include's parser with one derived from
     *                         mod_ssl's parser. Clean up ap_expr's public
     *                         interface.
     * 20101106.1 (2.3.9-dev)  Add ap_pool_cleanup_set_null() generic cleanup
     * 20101106.2 (2.3.9-dev)  Add suexec_disabled_reason field to ap_unixd_config
     * 20101113.0 (2.3.9-dev)  Add source address to mod_proxy.h
     * 20101113.1 (2.3.9-dev)  Add ap_set_flag_slot_char()
     * 20101113.2 (2.3.9-dev)  Add ap_expr_exec_re()
     * 20101204.0 (2.3.10-dev) Add _t to ap_expr's typedef names
     * 20101223.0 (2.3.11-dev) Remove cleaned from proxy_conn_rec.
     * 20101223.1 (2.3.11-dev) Rework mod_proxy, et.al. Remove proxy_worker_stat
     *                         and replace w/ proxy_worker_shared; remove worker
     *                         info from scoreboard and use slotmem; Allow
     *                         dynamic growth of balancer members; Remove
     *                         BalancerNonce in favor of 'nonce' parameter.
     * 20110117.0 (2.3.11-dev) Merge <If> sections in separate step (ap_if_walk).
     *                         Add core_dir_config->sec_if. Add ap_add_if_conf().
     *                         Add pool argument to ap_add_file_conf().
     * 20110117.1 (2.3.11-dev) Add ap_pstr2_alnum() and ap_str2_alnum()
     * 20110203.0 (2.3.11-dev) Raise DYNAMIC_MODULE_LIMIT to 256
     * 20110203.1 (2.3.11-dev) Add ap_state_query()
     * 20110203.2 (2.3.11-dev) Add ap_run_pre_read_request() hook and
     *                         ap_parse_form_data() util
     * 20110312.0 (2.3.12-dev) remove uldap_connection_cleanup and add
                               util_ldap_state_t.connectionPoolTTL,
                               util_ldap_connection_t.freed, and
                               util_ldap_connection_t.rebind_pool.
     * 20110312.1 (2.3.12-dev) Add core_dir_config.decode_encoded_slashes.
     * 20110328.0 (2.3.12-dev) change type and name of connectionPoolTTL in util_ldap_state_t
                               connectionPoolTTL (connection_pool_ttl, int->apr_interval_t)
     * 20110329.0 (2.3.12-dev) Change single-bit signed fields to unsigned in
     *                         proxy and cache interfaces.
     *                         Change ap_configfile_t/ap_cfg_getline()/
     *                         ap_cfg_getc() API, add ap_pcfg_strerror()
     *                         Axe mpm_note_child_killed hook, change
     *                         ap_reclaim_child_process and ap_recover_child_process
     *                         interfaces.
     * 20110329.1 (2.3.12-dev) Add ap_reserve_module_slots()/ap_reserve_module_slots_directive()
     *                         change AP_CORE_DECLARE to AP_DECLARE: ap_create_request_config()
     *                         change AP_DECLARE to AP_CORE_DECLARE: ap_register_log_hooks()
     * 20110329.2 (2.3.12-dev) Add child_status and end_generation hooks.
     * 20110329.3 (2.3.12-dev) Add format field to ap_errorlog_info.
     * 20110329.4 (2.3.13-dev) bgrowth and max_balancers to proxy_server_conf.
     * 20110329.5 (2.3.13-dev) Add ap_regexec_len()
     * 20110329.6 (2.3.13-dev) Add AP_EXPR_FLAGS_RESTRICTED, ap_expr_eval_ctx_t->data,
     *                         ap_expr_exec_ctx()
     * 20110604.0 (2.3.13-dev) Make ap_rputs() inline
     * 20110605.0 (2.3.13-dev) add core_dir_config->condition_ifelse, change return
     *                         type of ap_add_if_conf().
     *                         Add members of core_request_config: document_root,
     *                         context_document_root, context_prefix.
     *                         Add ap_context_*(), ap_set_context_info(), ap_set_document_root()
     * 20110605.1 (2.3.13-dev) add ap_(get|set)_core_module_config()
     * 20110605.2 (2.3.13-dev) add ap_get_conn_socket()
     * 20110619.0 (2.3.13-dev) add async connection infos to process_score in scoreboard,
     *                         add ap_start_lingering_close(),
     *                         add conn_state_e:CONN_STATE_LINGER_NORMAL and CONN_STATE_LINGER_SHORT
     * 20110619.1 (2.3.13-dev) add ap_str_toupper()
     * 20110702.0 (2.3.14-dev) make ap_expr_parse_cmd() macro wrapper for new
     *                         ap_expr_parse_cmd_mi() function, add ap_expr_str_*() functions,
     *                         rename AP_EXPR_FLAGS_* -> AP_EXPR_FLAG_*
     * 20110702.1 (2.3.14-dev) Add ap_scan_script_header_err*_ex functions
     * 20110723.0 (2.3.14-dev) Revert addition of ap_ldap*
     * 20110724.0 (2.3.14-dev) Add override_list as parameter to ap_parse_htaccess
     *                         Add member override_list to cmd_parms_struct,
     *                         core_dir_config and htaccess_result
     * 20110724.1 (2.3.15-dev) add NOT_IN_HTACCESS
     * 20110724.2 (2.3.15-dev) retries and retry_delay in util_ldap_state_t
     * 20110724.3 (2.3.15-dev) add util_varbuf.h / ap_varbuf API
     * 20110724.4 (2.3.15-dev) add max_ranges to core_dir_config
     * 20110724.5 (2.3.15-dev) add ap_set_accept_ranges()
     * 20110724.6 (2.3.15-dev) add max_overlaps and max_reversals to core_dir_config
     * 20110724.7 (2.3.15-dev) add ap_random_insecure_bytes(), ap_random_pick()
     * 20110724.8 (2.3.15-dev) add ap_abort_on_oom(), ap_malloc(), ap_calloc(),
     *                         ap_realloc()
     * 20110724.9 (2.3.15-dev) add ap_varbuf_pdup() and ap_varbuf_regsub()
     * 20110724.10(2.3.15-dev) Export ap_max_mem_free
     * 20111009.0 (2.3.15-dev) Remove ap_proxy_removestr(),
     *                         add ap_unixd_config.group_name
     * 20111014.0 (2.3.15-dev) Remove cookie_path_str and cookie_domain_str from
     *                         proxy_dir_conf
     * 20111025.0 (2.3.15-dev) Add return value and maxlen to ap_varbuf_regsub(),
     *                         add ap_pregsub_ex()
     * 20111025.1 (2.3.15-dev) Add ap_escape_urlencoded(), ap_escape_urlencoded_buffer()
     *                         and ap_unescape_urlencoded().
     * 20111025.2 (2.3.15-dev) Add ap_lua_ssl_val to mod_lua
     * 20111025.3 (2.4.0-dev)  Add reclvl to ap_expr_eval_ctx_t
     * 20111122.0 (2.4.0-dev)  Remove parts of conn_state_t that are private to the MPM
     * 20111123.0 (2.4.0-dev)  Pass ap_errorlog_info struct to error_log hook,
     *                         add pool to ap_errorlog_info.
     * 20111130.0 (2.4.0-dev)  c->remote_ip becomes c->peer_ip and r->client_ip,
     *                         c->remote_addr becomes c->peer_addr and r->client_addr
     * 20111201.0 (2.4.0-dev)  Add invalidate_entity() to the cache provider.
     * 20111202.0 (2.4.0-dev)  Use apr_status_t across mod_session API.
     * 20111202.1 (2.4.0-dev)  add APLOGNO()
     * 20111203.0 (2.4.0-dev)  Optional ap_proxy_retry_worker(), remove
     *                         ap_proxy_string_read(), ap_cache_liststr(),
     *                         ap_proxy_buckets_lifetime_transform(),
     *                         ap_proxy_date_canon(), ap_proxy_is_ipaddr(),
     *                         ap_proxy_is_domainname(), ap_proxy_is_hostname(),
     *                         ap_proxy_is_word(), ap_proxy_hex2sec(),
     *                         ap_proxy_sec2hex(), ap_proxy_make_fake_req(),
     *                         ap_proxy_strmatch_path, ap_proxy_strmatch_domain,
     *                         ap_proxy_table_unmerge(), proxy_lb_workers.
     * 20120109.0 (2.4.1-dev)  Changes sizeof(overrides_t) in core config.
     * 20120109.1 (2.4.1-dev)  remove sb_type in global_score.
     * 20120109.2 (2.4.1-dev)  Make core_output_filter_ctx_t and core_ctx_t
     *                         private;
     *                         move core_net rec definition to http_core.h;
     *                         add insert_network_bucket hook, AP_DECLINED
     * 20120211.0 (2.4.1-dev)  Change re_nsub in ap_regex_t from apr_size_t to int.
     * 20120211.1 (2.4.2-dev)  Add AP_HAVE_C99
     * 20120211.2 (2.4.2-dev)  Add ap_runtime_dir_relative
     * 20120211.3 (2.4.2-dev)  Add forcerecovery to proxy_balancer_shared struct
     * 20120211.4 (2.4.3-dev)  Add ap_list_provider_groups()
     * 20120211.5 (2.4.3-dev)  Add missing HTTP status codes registered with IANA.
     * 20120211.6 (2.4.3-dev)  Add ap_proxy_checkproxyblock2.
     * 20120211.7 (2.4.3-dev)  Add ap_get_loadavg()
     * 20120211.8 (2.4.3-dev)  Add sticky_separator to proxy_balancer_shared struct.
     * 20120211.9 (2.4.4-dev)  Add fgrab() to ap_slotmem_provider_t.
     * 20120211.10 (2.4.4-dev) Add in bal_persist field to proxy_server_conf
     * 20120211.11 (2.4.4-dev) Add ap_bin2hex()
     * 20120211.12 (2.4.5-dev) Add ap_remove_input|output_filter_byhandle()
     * 20120211.13 (2.4.5-dev) Add ap_get_exec_line
     * 20120211.14 (2.4.5-dev) Add ppinherit and inherit to proxy_server_conf
     * 20120211.15 (2.4.5-dev) Add dav_join_error()
     * 20120211.16 (2.4.5-dev) Add cache_control_t.invalidated
     * 20120211.17 (2.4.5-dev) Add ap_find_etag_weak(), ap_find_etag_strong()
     * 20120211.18 (2.4.5-dev) Add ap_condition_e, ap_condition_if_match(),
     *                         ap_condition_if_unmodified_since(),
     *                         ap_condition_if_none_match(),
     *                         ap_condition_if_modified_since(),
     *                         ap_condition_if_range()
     * 20120211.19 (2.4.5-dev) Add post_perdir_config hook.
     * 20120211.20 (2.4.5-dev) Add dirwalk_stat hook.
     * 20120211.21 (2.4.5-dev) Add in ap_proxy_create_hdrbrgd() and
     *                         ap_proxy_pass_brigade()
     * 20120211.22 (2.4.5-dev) No longer prevent usage of strtoul()
     * 20120211.23 (2.4.5-dev) Add ap_proxy_clear_connection()
     * 20120211.24 (2.4.7-dev) add open_htaccess hook.
     * 20120211.25 (2.4.7-dev) Add conn_sense_e
     * 20120211.26 (2.4.7-dev) Add util_fcgi.h, FastCGI protocol support
     * 20120211.27 (2.4.7-dev) Add ap_podx_restart_t and ap_mpm_podx_*
     * 20120211.28 (2.4.7-dev) Add ap_regname
     * 20120211.29 (2.4.7-dev) Add uds_path to proxy_conn_rec and proxy_worker_shared.
     *                         The change to proxy_worker_shared is an
     *                         unintended API break, especially for balancer
     *                         lbmethod modules.
     * 20120211.30 (2.4.7-dev) REWRITE_REDIRECT_HANDLER_NAME in mod_rewrite.h
     * 20120211.31 (2.4.7-dev) Add ap_proxy_port_of_scheme()
     * 20120211.32 (2.4.10-dev) Add SSL reusable SNI to mod_proxy.h's proxy_conn_rec
     * 20120211.33 (2.4.10-dev) Add suspend_connection and resume_connection hooks
     * 20120211.34 (2.4.10-dev) AP_DEFAULT_HANDLER_NAME/AP_IS_DEFAULT_HANDLER_NAME
     * 20120211.35 (2.4.10-dev) Add "r", "must_rebind", and last_backend_conn
                                to util_ldap_connection_t
     * 20120211.36 (2.4.10-dev) Add ap_copy_scoreboard_worker()
     * 20120211.37 (2.4.11-dev) Add r->trailers_{in,out}
     * 20120211.38 (2.4.11-dev) Added ap_shutdown_conn().
     * 20120211.39 (2.4.11-dev) Add ap_proxy_connect_uds().
     * 20120211.40 (2.4.11-dev) Add ap_log_data(), ap_log_rdata(), etc.
     * 20120211.41 (2.4.11-dev) Add ap_proxy_de_socketfy to mod_proxy.h
     * 20120211.42 (2.4.13-dev) Add response_code_exprs to http_core.h
     * 20120211.43 (2.4.13-dev) Add keep_alive_timeout_set to server_rec
     * 20120211.44 (2.4.13-dev) Add cgi_pass_auth and AP_CGI_PASS_AUTH_* to
     *                          core_dir_config
     * 20120211.45 (2.4.13-dev) Add ap_proxy_connection_reusable()
     * 20120211.46 (2.4.13-dev) Add ap_map_http_request_error()
     * 20120211.47 (2.4.13-dev) Add ap_some_authn_required, ap_force_authn hook.
     *                          Deprecate broken ap_some_auth_required.
     * 20120211.48 (2.4.17-dev) Added ap_log_mpm_common().
     * 20120211.49 (2.4.17-dev) Add listener bucket in scoreboard.h's process_score.
     * 20120211.50 (2.4.17-dev) Add ap_set_listencbratio(), ap_close_listeners_ex(),
     *                          ap_duplicate_listeners(), ap_num_listen_buckets and
     *                          ap_have_so_reuseport to ap_listen.h.
     * 20120211.51 (2.4.17-dev) Add protocols and protocols_honor_order to
     *                          core_server_config. Add hooks protocol_propose
     *                          protocol_switch and protocol_get. Add
     *                          ap_select_protocol(), ap_switch_protocol(),
     *                          ap_get_protocol(). Add HTTP_MISDIRECTED_REQUEST.
     *                          Added ap_parse_token_list_strict() to httpd.h
     * 20120211.52 (2.4.17-dev) Add master conn_rec* member in conn_rec.
     * 20120211.53 (2.4.19-dev) Add expr_handler to core_dir_config.
     * 20120211.54 (2.4.19-dev) Add ap_proxy_buckets_lifetime_transform and
     *                          ap_proxy_transfer_between_connections to
     *                          mod_proxy.h
     * 20120211.55 (2.4.19-dev) Add new ap_update_child_status...() methods,
     *                          add protocol to worker_score in scoreboard.h,
     *                          Add pre_close connection hook and
     *                          ap_prep_lingering_close().
     * 20120211.56 (2.4.19-dev) Split useragent_host from the conn_rec into
     *                          the request_rec, with ap_get_useragent_host()
     * 20120211.57 (2.4.19-dev) Add mod_ssl_openssl.h and OpenSSL-specific hooks
     * 20120211.58 (2.4.21-dev) Add cgi_var_rules to core_dir_config.
     * 20120211.59 (2.4.21-dev) Add ap_getword_conf2[_nc](),
     *                          ap_proxy_is_socket_connected() and
     *                          extended proxy_worker_shared.
     * 20120211.60 (2.4.21-dev) Add dav_get_provider_name.
     * 20120211.61 (2.4.21-dev) Add ap_cstr_casecmp[n]() - placeholder of apr_ fns
     * 20120211.62 (2.4.24-dev) Add childtags to dav_error.
     * 20120211.63 (2.4.24-dev) Add dav_begin_multistatus, dav_send_one_response,
     *                          dav_finish_multistatus, dav_send_multistatus,
     *                          dav_handle_err, dav_failed_proppatch,
     *                          dav_success_proppatch.
     * 20120211.64 (2.4.24-dev) Add ap_proxy_check_backend(), and tmp_bb to struct
     *                          proxy_conn_rec.
     * 20120211.65 (2.4.24-dev) Add ap_check_pipeline().
     * 20120211.66 (2.4.24-dev) Rename ap_proxy_check_backend() to
     *                          ap_proxy_check_connection().
     * 20120211.67 (2.4.24-dev) Add http09_enable, http_conformance, and
     *                          http_methods to core_server_config
     *                          Add ap_scan_http_field_token(),
     *                          ap_scan_http_field_content(),
     *                          and ap_scan_vchar_obstext()
     *                          Replaced fold boolean with with multiple bit flags
     *                          to ap_[r]getline()
     * 20120211.68 (2.4.26-dev) Add ap_get_basic_auth_components() and deprecate
     *                          ap_get_basic_auth_pw()
     * 20120211.69 (2.4.30-dev) Add ap_update_sb_handle()
     * 20120211.70 (2.4.30-dev) Add flags field to module_struct and function
     *                          ap_get_module_flags()
     * 20120211.71 (2.4.30-dev) Add optional proxy_{hook,run}_section_post_config(),
     *                          ap_proxy_connection_create_ex() and section_config
     *                          to struct proxy_{worker,balancer} in mod_proxy.h,
     *                          and optional ssl_engine_set() to mod_ssl.h.
     * 20120211.72 (2.4.30-dev) Add NOT_IN_DIR_CONTEXT replacing NOT_IN_DIR_LOC_FILE
     *                          semantics
     * 20120211.73 (2.4.30-dev) Add failontimeout_set, growth_set and lbmethod_set
     *                          to proxy_balancer struct
     * 20120211.74 (2.4.30-dev) Add AP_REG_DOLLAR_ENDONLY, ap_regcomp_get_default_cflags
     *                          ap_regcomp_set_default_cflags and
     *                          ap_regcomp_default_cflag_by_name
     * 20120211.75 (2.4.30-dev) Add hostname_ex to proxy_worker_shared
     * 20120211.76 (2.4.30-dev) Add CONN_STATE_NUM to enum conn_state_e
     * 20120211.77 (2.4.34-dev) Add ap_exists_directive()
     * 20120211.78 (2.4.34-dev) Add response_field_size to proxy_worker_shared 
     * 20120211.79 (2.4.34-dev) Add AP_GETLINE_NOSPC_EOL flag to http_protocol.h
     * 20120211.80 (2.4.35-dev) Add new ap_update_global_status() method and
     *                          times field in the global_score structure in
     *                          scoreboard.h.
     * 20120211.81 (2.4.35-dev) Add new duration field to worker_score struct in
     *                          scoreboard.h
     * 20120211.82 (2.4.35-dev) Add optional function declaration for
     *                          ap_proxy_balancer_get_best_worker to mod_proxy.h.
     * 20120211.83 (2.4.35-dev) Add client64 field to worker_score struct
     * 20120211.84 (2.4.35-dev) Add ap_no2slash_ex() and merge_slashes to 
     *                          core_server_conf.
     * 20120211.85 (2.4.40-dev) add ap_set_conn_count().
     * 20120211.86 (2.4.40-dev) Add forward_100_continue{,_set} to proxy_dir_conf
     * 20120211.87 (2.4.40-dev) Add dav_popen_propdb
     * 20120211.88 (2.4.40-dev) Add ap_dir_nofnmatch() and ap_dir_fnmatch().
     * 20120211.89 (2.4.42-dev) Add add dns_pool to proxy_conn_pool and define
     *                          AP_VOLATILIZE_T.
     * 20120211.90 (2.4.42-dev) AP_REG_DEFAULT macro in ap_regex.h
     * 20120211.91 (2.4.42-dev) Add ap_is_chunked() in httpd.h
     * 20120211.92 (2.4.42-dev) AP_REG_NO_DEFAULT macro in ap_regex.h
     * 20120211.93 (2.4.44-dev) Add ap_parse_strict_length()
     * 20120211.94 (2.4.47-dev) Add ap_proxy_define_match_worker()
     * 20120211.95 (2.4.47-dev) Add proxy check_trans hook
     * 20120211.96 (2.4.47-dev) Add ap_get_status_line_ex()
     * 20120211.97 (2.4.47-dev) Add read_buf_size member to core_dir_config,
     *                          flush_max_threshold and flush_max_pipelined to
     *                          core_server_config, and ap_get_read_buf_size().
     * 20120211.98 (2.4.47-dev) Add ap_proxy_should_override to mod_proxy.h
     * 20120211.99 (2.4.47-dev) Add proxy_tunnel_rec, ap_proxy_tunnel_create()
     *                          and ap_proxy_tunnel_run() to proxy_util.
     * 20120211.99 (2.4.47-dev) Add ap_proxy_worker_can_upgrade()
     * 20120211.100 (2.4.47-dev) Add ap_proxy_prefetch_input(),
     *                           ap_proxy_spool_input() and
     *                           ap_proxy_read_input().
     * 20120211.101 (2.4.47-dev) ETAG_DIGEST in http_core.h. struct etag_rec,
     *                           ap_make_etag_ex() and ap_set_etag_fd() in
     *                           http_protocol.h. ap_request_bnotes_t,
     *                           AP_REQUEST_STRONG_ETAG, AP_REQUEST_GET_BNOTE,
     *                           AP_REQUEST_SET_BNOTE and AP_REQUEST_IS_STRONG_ETAG
     *                           in httpd.h.
     * 20120211.102 (2.4.47-dev) Add ap_ssl_conn_is_ssl()/ap_ssl_var_lookup() and hooks
     * 20120211.103 (2.4.47-dev) Add ap_ssl_add_cert_files, ap_ssl_add_fallback_cert_files
     *                           and ap_ssl_answer_challenge and hooks.
     * 20120211.104 (2.4.47-dev) Move ap_ssl_* into new http_ssl.h header file
     * 20120211.105 (2.4.47-dev) Add ap_ssl_ocsp* hooks and functions to http_ssl.h.
     * 20120211.106 (2.4.49-dev) Add ap_create_request().
     * 20120211.107 (2.4.49-dev) Add ap_parse_request_line() and
     *                           ap_check_request_header()
     * 20120211.108 (2.4.49-dev) Add ajp_handle_cping_cpong
     * 20120211.109 (2.4.49-dev) Add ap_normalize_path(),
     *                           pre_translate_name hook and
     *                           Add map_encoded_one and map_encoded_all bits to
     *                           proxy_server_conf.
     * 20120211.110 (2.4.49-dev) Add hook child_stopping to get informed that a child
     *                           is being shut down.
     * 20120211.111 (2.4.49-dev) Add dav_get_provider(), dav_open_lockdb(),
     *                           dav_close_lockdb() and dav_get_resource() to
     *                           mod_dav.h.
     * 20120211.112 (2.4.49-dev) Add deliver_report and gather_reports hooks.
     * 20120211.113 (2.4.49-dev) Add method_precondition hook.
     * 20120211.114 (2.4.49-dev) Add optional balancer_manage function.
     * 20120211.115 (2.4.49-dev) Add ap_proxy_get_worker_ex() and
     *                           ap_proxy_define_worker_ex() to mod_proxy.h
     * 20120211.116 (2.4.49-dev) add conn_rec->outgoing and ap_ssl_bind_outgoing()
     * 20120211.117 (2.4.50-dev) Add ap_pre_connection
     * 20120211.118 (2.4.51-dev) Add ap_unescape_url_ex() and deprecate
     *                           AP_NORMALIZE_DROP_PARAMETERS
     * 20120211.119 (2.4.51-dev) Add dav_validate_root_ns(), dav_find_child_ns(),
     *                           dav_find_next_ns(), dav_find_attr_ns() and
     *                           dav_find_attr().
     * 20120211.120 (2.4.51-dev) Add dav_liveprop_elem structure and
     *                           dav_get_liveprop_element().
     * 20120211.121 (2.4.51-dev) Add ap_post_read_request()
     * 20120211.122 (2.4.51-dev) Add ap_thread_create(), ap_thread_main_create()
     *                           and ap_thread_current()
     * 20120211.123 (2.4.51-dev) Added ap_pcre_version_string(), AP_REG_PCRE_COMPILED
     *                           and AP_REG_PCRE_LOADED to ap_regex.h.
     * 20120211.124 (2.4.51-dev) Add name_ex to struct proxy_worker_shared
     * 20120211.125 (2.4.55-dev) Export mod_http2.h as public header
     * 20120211.126 (2.4.55-dev) Add additional hcmethod_t enums and PROXY_WORKER_IS_ERROR
     * 20120211.127 (2.4.56-dev) Add ap_proxy_canonenc_ex
     * 20120211.128 (2.4.55-dev) Add AP_CTIME_OPTION_GMTOFF to util_time.h
     * 20120211.129 (2.4.58-dev) Add ap_get_pollfd_from_conn()
     * 20120211.130 (2.4.59-dev) Add ap_proxy_determine_address()
     * 20120211.131 (2.4.59-dev) Add DAV_WALKTYPE_TOLERANT
     * 20120211.132 (2.4.60-dev) Add ap_set_content_type_ex(), ap_filepath_merge(),
     *                           and AP_REQUEST_TRUSTED_CT BNOTE.
     * 20120211.133 (2.4.60-dev) Add ap_proxy_fixup_uds_filename()
     * 20120211.134 (2.4.60-dev) AP_SLASHES and AP_IS_SLASH
     * 20120211.135 (2.4.63-dev) Add CONN_STATE_ASYNC_WAITIO, CONN_STATE_KEEPALIVE
     *                           and CONN_STATE_PROCESSING
     * 20120211.136 (2.4.63-dev) Add wait_io field to struct process_score
     * 20120211.137 (2.4.63-dev) Add AP_MPMQ_CAN_WAITIO
     * 20120211.138 (2.4.63-dev) Add is_host_matchable to proxy_worker_shared
     * 20120211.139 (2.4.63-dev) Add dav_get_base_path() to mod_dav
     * 20120211.140 (2.4.64-dev) Add ap_set_time_process_request() to scoreboard.h
     * 20120211.141 (2.4.64-dev) add ap_stat_check() to httpd.h
     */
    
    #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
    
    #ifndef MODULE_MAGIC_NUMBER_MAJOR
    #define MODULE_MAGIC_NUMBER_MAJOR 20120211
    #endif
    #define MODULE_MAGIC_NUMBER_MINOR 141                 /* 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:
     *
     * \code
     * #if AP_MODULE_MAGIC_AT_LEAST(19980812,2)
     *     ... use apr_table_overlap()
     * #else
     *     ... alternative code which doesn't use apr_table_overlap()
     * #endif
     * \endcode
     *
     * @param major The major module magic number
     * @param minor The minor module magic number
     * @def 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 */
    /** @} */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_socache.h�������������������������������������������������������������������0000664�0001751�0001751�00000022270�14737240630�016514� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ap_socache.h
     * @brief Small object cache provider interface.
     *
     * @defgroup AP_SOCACHE ap_socache
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #ifndef AP_SOCACHE_H
    #define AP_SOCACHE_H
    
    #include "httpd.h"
    #include "ap_provider.h"
    #include "apr_pools.h"
    #include "apr_time.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /** If this flag is set, the store/retrieve/remove/status interfaces
     * of the provider are NOT safe to be called concurrently from
     * multiple processes or threads, and an external global mutex must be
     * used to serialize access to the provider.
     */
    /* XXX: Even if store/retrieve/remove is atomic, isn't it useful to note
     * independently that status and iterate may or may not be?
     */
    #define AP_SOCACHE_FLAG_NOTMPSAFE (0x0001)
    
    /** A cache instance. */
    typedef struct ap_socache_instance_t ap_socache_instance_t;
    
    /** Hints which may be passed to the init function; providers may
     * ignore some or all of these hints. */
    struct ap_socache_hints {
        /** Approximate average length of IDs: */
        apr_size_t avg_id_len;
        /** Approximate average size of objects: */
        apr_size_t avg_obj_size;
        /** Suggested interval between expiry cleanup runs; */
        apr_interval_time_t expiry_interval;
    };
    
    /**
     * Iterator callback prototype for the ap_socache_provider_t->iterate() method
     * @param instance The cache instance
     * @param s Associated server context (for logging)
     * @param userctx User defined pointer passed from the iterator call
     * @param id Unique ID for the object (binary blob)
     * with a trailing null char for convenience
     * @param idlen Length of id blob
     * @param data Output buffer to place retrieved data (binary blob)
     * with a trailing null char for convenience
     * @param datalen Length of data buffer
     * @param pool Pool for temporary allocations
     * @return APR status value; return APR_SUCCESS or the iteration will halt;
     * this value is returned to the ap_socache_provider_t->iterate() caller
     */
    typedef apr_status_t (ap_socache_iterator_t)(ap_socache_instance_t *instance,
                                                 server_rec *s,
                                                 void *userctx,
                                                 const unsigned char *id,
                                                 unsigned int idlen,
                                                 const unsigned char *data,
                                                 unsigned int datalen,
                                                 apr_pool_t *pool);
    
    /** A socache provider structure.  socache providers are registered
     * with the ap_provider.h interface using the AP_SOCACHE_PROVIDER_*
     * constants. */
    typedef struct ap_socache_provider_t {
        /** Canonical provider name. */
        const char *name;
    
        /** Bitmask of AP_SOCACHE_FLAG_* flags. */
        unsigned int flags;
    
        /**
         * Create a small object cache based on the given configuration
         * string.  The instance pointer returned in the instance
         * parameter will be passed as the first argument to subsequent
         * invocations.
         *
         * @param instance Output parameter to which instance object is written.
         * @param arg User-specified configuration string.  May be NULL to
         *        force use of defaults.
         * @param tmp Pool to be used for any temporary allocations
         * @param p Pool to be use for any allocations lasting as long as
         * the created instance
         * @return NULL on success, or an error string on failure.
         */
        const char *(*create)(ap_socache_instance_t **instance, const char *arg,
                              apr_pool_t *tmp, apr_pool_t *p);
    
        /**
         * Initialize the cache.  The cname must be of maximum length 16
         * characters, and uniquely identifies the consumer of the cache
         * within the server; using the module name is recommended, e.g.
         * "mod_ssl-sess".  This string may be used within a filesystem
         * path so use of only alphanumeric [a-z0-9_-] characters is
         * recommended.  If hints is non-NULL, it gives a set of hints for
         * the provider.  Returns APR error code.
         *
         * @param instance The cache instance
         * @param cname A unique string identifying the consumer of this API
         * @param hints Optional hints argument describing expected cache use
         * @param s Server structure to which the cache is associated
         * @param pool Pool for long-lived allocations
         * @return APR status value indicating success.
         */
        apr_status_t (*init)(ap_socache_instance_t *instance, const char *cname,
                             const struct ap_socache_hints *hints,
                             server_rec *s, apr_pool_t *pool);
    
        /**
         * Destroy a given cache instance object.
         * @param instance The cache instance to destroy.
         * @param s Associated server structure (for logging purposes)
         */
        void (*destroy)(ap_socache_instance_t *instance, server_rec *s);
    
        /**
         * Store an object in a cache instance.
         * @param instance The cache instance
         * @param s Associated server structure (for logging purposes)
         * @param id Unique ID for the object; binary blob
         * @param idlen Length of id blob
         * @param expiry Absolute time at which the object expires
         * @param data Data to store; binary blob
         * @param datalen Length of data blob
         * @param pool Pool for temporary allocations.
         * @return APR status value.
         */
        apr_status_t (*store)(ap_socache_instance_t *instance, server_rec *s,
                              const unsigned char *id, unsigned int idlen,
                              apr_time_t expiry,
                              unsigned char *data, unsigned int datalen,
                              apr_pool_t *pool);
    
        /**
         * Retrieve a cached object.
         * 
         * @param instance The cache instance
         * @param s Associated server structure (for logging purposes)
         * @param id Unique ID for the object; binary blob
         * @param idlen Length of id blob
         * @param data Output buffer to place retrievd data (binary blob)
         * @param datalen On entry, length of data buffer; on exit, the
         * number of bytes written to the data buffer.
         * @param pool Pool for temporary allocations.
         * @return APR status value; APR_NOTFOUND if the object was not
         * found
         */
        apr_status_t (*retrieve)(ap_socache_instance_t *instance, server_rec *s,
                                 const unsigned char *id, unsigned int idlen,
                                 unsigned char *data, unsigned int *datalen,
                                 apr_pool_t *pool);
    
        /**
         * Remove an object from the cache
         *
         * @param instance The cache instance
         * @param s Associated server structure (for logging purposes)
         * @param id Unique ID for the object; binary blob
         * @param idlen Length of id blob
         * @param pool Pool for temporary allocations.
         */
        apr_status_t (*remove)(ap_socache_instance_t *instance, server_rec *s,
                               const unsigned char *id, unsigned int idlen,
                               apr_pool_t *pool);
    
        /** 
         * Dump the status of a cache instance for mod_status.  Will use
         * the ap_r* interfaces to produce appropriate status output.
         * XXX: ap_r* are deprecated, bad dogfood
         *
         * @param instance The cache instance
         * @param r The request structure
         * @param flags The AP_STATUS_* constants used (see mod_status.h)
         */
        void (*status)(ap_socache_instance_t *instance, request_rec *r, int flags);
    
        /**
         * Dump all cached objects through an iterator callback.
         * @param instance The cache instance
         * @param s Associated server context (for processing and logging)
         * @param userctx User defined pointer passed through to the iterator
         * @param iterator The user provided callback function which will receive
         * individual calls for each unexpired id/data pair
         * @param pool Pool for temporary allocations.
         * @return APR status value; APR_NOTFOUND if the object was not
         * found
         */
        apr_status_t (*iterate)(ap_socache_instance_t *instance, server_rec *s,
                                void *userctx, ap_socache_iterator_t *iterator,
                                apr_pool_t *pool);
    
    } ap_socache_provider_t;
    
    /** The provider group used to register socache providers. */
    #define AP_SOCACHE_PROVIDER_GROUP "socache"
    /** The provider version used to register socache providers. */
    #define AP_SOCACHE_PROVIDER_VERSION "0"
    
    /** Default provider name. */
    #define AP_SOCACHE_DEFAULT_PROVIDER "default"
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* AP_SOCACHE_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_script.h������������������������������������������������������������������0000664�0001751�0001751�00000023204�14603243511�016757� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_script.h
     * @brief Apache script tools
     *
     * @defgroup APACHE_CORE_SCRIPT Script Tools
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_UTIL_SCRIPT_H
    #define APACHE_UTIL_SCRIPT_H
    
    #include "apr_buckets.h"
    #include "ap_config.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #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.
     * @fn 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
     * @fn 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
     * @fn 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
     * @fn 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
     * @fn 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 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.
     * @param module_index The module index to be used for logging
     * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
     */
    AP_DECLARE(int) ap_scan_script_header_err_ex(request_rec *r, apr_file_t *f,
                                                 char *buffer, int module_index);
    
    
    /**
     * 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
     * @fn 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 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.
     * @param module_index The module index to be used for logging
     * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
     */
    AP_DECLARE(int) ap_scan_script_header_err_brigade_ex(request_rec *r,
                                                         apr_bucket_brigade *bb,
                                                         char *buffer,
                                                         int module_index);
    
    /**
     * 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.
     *
     * The varargs are string arguments to parse consecutively for headers,
     * with a NULL argument to terminate the list.
     *
     * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
     */
    AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r,
                                                          char *buffer,
                                                          const char **termch,
                                                          int *termarg, ...)
                           AP_FN_ATTR_SENTINEL;
    
    /**
     * 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 module_index The module index to be used for logging
     * @param termch Pointer to the last character parsed.
     * @param termarg Pointer to an int to capture the last argument parsed.
     *
     * The varargs are string arguments to parse consecutively for headers,
     * with a NULL argument to terminate the list.
     *
     * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
     */
    AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs_ex(request_rec *r,
                                                             char *buffer,
                                                             int module_index,
                                                             const char **termch,
                                                             int *termarg, ...)
                           AP_FN_ATTR_SENTINEL;
    
    
    /**
     * 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
     */
    AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer,
                                                   int (*getsfunc) (char *, int, void *),
                                                   void *getsfunc_data);
    
    /**
     * 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
     * @param module_index The module index to be used for logging
     * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
     */
    AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer,
                                            int (*getsfunc) (char *, int, void *),
                                            void *getsfunc_data, int module_index);
    
    
    /**
     * Parse query args for the request and store in a new table allocated
     * from the request pool.
     * For args with no value, "1" will be used instead.
     * If no query args were specified, the table will be empty.
     * @param r The current request
     * @param table A new table on output.
     */
    AP_DECLARE(void) ap_args_to_table(request_rec *r, apr_table_t **table);
    
    #define AP_TRUST_CGILIKE_CL_ENVVAR "ap_trust_cgilike_cl"
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_UTIL_SCRIPT_H */
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_listen.h��������������������������������������������������������������������0000664�0001751�0001751�00000013674�15020012305�016373� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  ap_listen.h
     * @brief Apache Listeners Library
     *
     * @defgroup APACHE_CORE_LISTEN Apache Listeners Library
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef AP_LISTEN_H
    #define AP_LISTEN_H
    
    #include "apr_network_io.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "apr_optional.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    typedef struct ap_slave_t ap_slave_t;
    typedef struct ap_listen_rec ap_listen_rec;
    typedef apr_status_t (*accept_function)(void **csd, ap_listen_rec *lr, apr_pool_t *ptrans);
    
    /**
     * @brief 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;
        /**
         * The default protocol for this listening socket.
         */
        const char* protocol;
    
        ap_slave_t *slave;
    };
    
    /**
     * The global list of ap_listen_rec structures
     */
    AP_DECLARE_DATA extern ap_listen_rec *ap_listeners;
    AP_DECLARE_DATA extern int ap_num_listen_buckets;
    AP_DECLARE_DATA extern int ap_have_so_reuseport;
    
    /**
     * 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);
    
    /**
     * This function duplicates ap_listeners into multiple buckets when configured
     * to (see ListenCoresBucketsRatio) and the platform supports it (eg. number of
     * online CPU cores and SO_REUSEPORT available).
     * @param p The config pool
     * @param s The global server_rec
     * @param buckets The array of listeners buckets.
     * @param num_buckets The total number of listeners buckets (array size).
     * @remark If the given *num_buckets is 0 (input), it will be computed
     *         according to the platform capacities, otherwise (positive) it
     *         will be preserved. The number of listeners duplicated will
     *         always match *num_buckets, be it computed or given.
     */
    AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
                                                    ap_listen_rec ***buckets,
                                                    int *num_buckets);
    
    /**
     * Loop through the global ap_listen_rec list and close each of the sockets.
     */
    AP_DECLARE_NONSTD(void) ap_close_listeners(void);
    
    /**
     * Loop through the given ap_listen_rec list and close each of the sockets.
     * @param listeners The listener to close.
     */
    AP_DECLARE_NONSTD(void) ap_close_listeners_ex(ap_listen_rec *listeners);
    
    /**
     * FIXMEDOC
     */
    AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *);
    
    /* 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_listencbratio(cmd_parms *cmd, void *dummy, const char *arg);
    AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
                                                    int argc, char *const argv[]);
    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);
    
    #ifdef HAVE_SYSTEMD
    APR_DECLARE_OPTIONAL_FN(int,
                            ap_find_systemd_socket, (process_rec *, apr_port_t));
    
    APR_DECLARE_OPTIONAL_FN(int,
                            ap_systemd_listen_fds, (int));
    #endif
    
    
    #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("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF, \
      "Ratio between the number of CPU cores (online) and the number of listeners buckets"), \
    AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \
      "A port number or a numeric IP address and a port number, and an optional protocol"), \
    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")
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    /** @} */
    ��������������������������������������������������������������������httpd-2.4.64/include/http_protocol.h����������������������������������������������������������������0000664�0001751�0001751�00000122637�14636331332�017335� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  http_protocol.h
     * @brief HTTP protocol handling
     *
     * @defgroup APACHE_CORE_PROTO HTTP Protocol Handling
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_HTTP_PROTOCOL_H
    #define APACHE_HTTP_PROTOCOL_H
    
    #include "httpd.h"
    #include "apr_portable.h"
    #include "apr_mmap.h"
    #include "apr_buckets.h"
    #include "util_filter.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * 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 an empty request and set reasonable defaults.
     * @param c The current connection
     * @return The new request_rec
     */
    AP_DECLARE(request_rec *) ap_create_request(conn_rec *c);
    
    /**
     * 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);
    
    /**
     * Parse and validate the request line.
     * @param r The current request
     * @return 1 on success, 0 on failure
     */
    AP_DECLARE(int) ap_parse_request_line(request_rec *r);
    
    /**
     * Validate the request header and select vhost.
     * @param r The current request
     * @return 1 on success, 0 on failure
     */
    AP_DECLARE(int) ap_check_request_header(request_rec *r);
    
    /**
     * 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);
    
    /**
     * Run post_read_request hook and validate.
     * @param r The current request
     * @return OK or HTTP_...
     */
    AP_DECLARE(int) ap_post_read_request(request_rec *r);
    
    /* Finish up stuff after a request */
    
    /**
     * Called at completion of sending the response.  It sends the terminating
     * protocol information.
     * @param r The current request
     */
    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.
     */
    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
     */
    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
     */
    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.
     */
    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 or "", return NULL (do not set content-type).
     *    - 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
     * @param type The content type
     * @return The content-type
     */
    AP_DECLARE(const char *) ap_make_content_type(request_rec *r,
                                                  const char *type);
    
    /**
     * Precompile metadata structures used by ap_make_content_type()
     * @param pool The pool to use for allocations
     */
    AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool);
    
    /** A structure with the ingredients for a file based etag */
    typedef struct etag_rec etag_rec;
    
    /**
     * @brief A structure with the ingredients for a file based etag
     */
    struct etag_rec {
        /** Optional vary list validator */
        const char *vlist_validator;
        /** Time when the request started */
        apr_time_t request_time;
        /** finfo.protection (st_mode) set to zero if no such file */
        apr_finfo_t *finfo;
        /** File pathname used when generating a digest */
        const char *pathname;
        /** File descriptor used when generating a digest */
        apr_file_t *fd;
        /** Force a non-digest etag to be weak */
        int force_weak;
    };
    
    /**
     * 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
     */
    AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak);
    
    /**
     * Construct an entity tag from information provided in the etag_rec
     * structure.
     * @param r The current request
     * @param er The etag record, containing ingredients for the etag.
     */
    AP_DECLARE(char *) ap_make_etag_ex(request_rec *r, etag_rec *er);
    
    /**
     * Set the E-tag outgoing header
     * @param r The current request
     */
    AP_DECLARE(void) ap_set_etag(request_rec *r);
    
    /**
     * Set the E-tag outgoing header, with the option of forcing a strong ETag.
     * @param r The current request
     * @param fd The file descriptor
     */
    AP_DECLARE(void) ap_set_etag_fd(request_rec *r, apr_file_t *fd);
    
    /**
     * Set the last modified time for the file being sent
     * @param r The current request
     */
    AP_DECLARE(void) ap_set_last_modified(request_rec *r);
    
    typedef enum {
        AP_CONDITION_NONE,
        AP_CONDITION_NOMATCH,
        AP_CONDITION_WEAK,
        AP_CONDITION_STRONG
    } ap_condition_e;
    
    /**
     * Tests conditional request rules for the If-Match header.
     * @param r The current request
     * @param headers The response headers to check against
     * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
     *         if the header does not match, AP_CONDITION_STRONG for a strong
     *         match. Weak matches are not permitted for the If-Match header.
     */
    AP_DECLARE(ap_condition_e) ap_condition_if_match(request_rec *r,
            apr_table_t *headers);
    
    /**
     * Tests conditional request rules for the If-Unmodified-Since header.
     * @param r The current request
     * @param headers The response headers to check against
     * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
     *         if the header does not match, AP_CONDITION_WEAK if a weak match
     *         was present and allowed by RFC2616, AP_CONDITION_STRONG for a
     *         strong match.
     */
    AP_DECLARE(ap_condition_e) ap_condition_if_unmodified_since(request_rec *r,
            apr_table_t *headers);
    
    /**
     * Tests conditional request rules for the If-None-Match header.
     * @param r The current request
     * @param headers The response headers to check against
     * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
     *         if the header does not match, AP_CONDITION_WEAK if a weak match
     *         was present and allowed by RFC2616, AP_CONDITION_STRONG for a
     *         strong match.
     */
    AP_DECLARE(ap_condition_e) ap_condition_if_none_match(request_rec *r,
            apr_table_t *headers);
    
    /**
     * Tests conditional request rules for the If-Modified-Since header.
     * @param r The current request
     * @param headers The response headers to check against
     * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
     *         if the header does not match, AP_CONDITION_WEAK if a weak match
     *         was present and allowed by RFC2616, AP_CONDITION_STRONG for a
     *         strong match.
     */
    AP_DECLARE(ap_condition_e) ap_condition_if_modified_since(request_rec *r,
            apr_table_t *headers);
    
    /**
     * Tests conditional request rules for the If-Range header.
     * @param r The current request
     * @param headers The response headers to check against
     * @return AP_CONDITION_NONE if either the If-Range or Range header is
     *         missing, AP_CONDITION_NOMATCH if the header does not match,
     *         AP_CONDITION_STRONG for a strong match. Weak matches are not
     *         permitted for the If-Range header.
     */
    AP_DECLARE(ap_condition_e) ap_condition_if_range(request_rec *r,
            apr_table_t *headers);
    
    /**
     * 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
     */
    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
     */
    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
     */
    AP_DECLARE(apr_size_t) ap_send_mmap(apr_mmap_t *mm,
                                        request_rec *r,
                                        apr_size_t offset,
                                        apr_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         An 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.
     */
    AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts);
    
    
    /**
     * Copy a method list
     *
     * @param   dest List to copy to
     * @param   src  List to copy from
     */
    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 r->allowed_methods.
     * @return  1 if method is in the list, otherwise 0
     */
    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 r->allowed_methods.
     * @return  None.
     */
    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 r->allowed_methods.
     * @param   method  String containing the name of the method to remove.
     * @return  None.
     */
    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 r->allowed_methods.
     * @return  None.
     */
    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
     * @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);
    
    /**
     * Set the content type for this request (r->content_type).
     * @param r The current request
     * @param ct The new content type
     * @param trusted If non-zero, The content-type should come from a
     *        trusted source such as server configuration rather
     *        than application output.
     * for the AddOutputFilterByType directive to work correctly.
     */
    AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted);
    
    /**
     * Set the Accept-Ranges header for this response
     * @param r The current request
     */
    AP_DECLARE(void) ap_set_accept_ranges(request_rec *r);
    
    
    /* 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
     */
    AP_DECLARE(int) ap_rputc(int c, 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
     */
    AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, 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
     * @note ap_rputs may be implemented as macro or inline function
     */
    static APR_INLINE int ap_rputs(const char *str, request_rec *r)
    {
        apr_size_t len;
    
        len = strlen(str);
    
        for (;;) {
            if (len <= INT_MAX) {
                return ap_rwrite(str, (int)len, r);
            }
            else {
                int rc;
    
                rc = ap_rwrite(str, INT_MAX, r);
                if (rc < 0) {
                    return rc;
                }
                else {
                    str += INT_MAX;
                    len -= INT_MAX;
                }
            }
        }
    }
    
    /**
     * 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
     */
    AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r,...)
                           AP_FN_ATTR_SENTINEL;
    
    /**
     * 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
     */
    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
     */
    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 0 on success, -1 if an error occurred
     */
    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
     */
    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
     */
    AP_DECLARE(const char *) ap_get_status_line(int status);
    
    /**
     * Return the Status-Line for a given status code (excluding the
     * HTTP-Version field). If an invalid status code is passed,
     * "500 Internal Server Error" will be returned, whereas an unknown
     * status will be returned like "xxx Status xxx".
     * @param p The pool to allocate from when status is unknown
     * @param status The HTTP status code
     * @return The Status-Line
     */
    AP_DECLARE(const char *) ap_get_status_line_ex(apr_pool_t *p, 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: <pre>
     *    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.
     * </pre>
     * @return either OK or an error code
     */
    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
     */
    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
     */
    AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz);
    
    /**
     * Map specific APR codes returned by the filter stack to HTTP error
     * codes, or the default status code provided. Use it as follows:
     *
     * return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
     *
     * If the filter has already handled the error, AP_FILTER_ERROR will
     * be returned, which is cleanly passed through.
     *
     * These mappings imply that the filter stack is reading from the
     * downstream client, the proxy will map these codes differently.
     * @param rv APR status code
     * @param status Default HTTP code should the APR code not be recognised
     * @return Mapped HTTP status code
     */
    AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status);
    
    /**
     * 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
     */
    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.
     * @param r The current request
     */
    AP_DECLARE(void) ap_note_auth_failure(request_rec *r);
    
    /**
     * @deprecated @see ap_note_auth_failure
     */
    AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r);
    
    /**
     * @deprecated @see ap_note_auth_failure
     */
    AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r);
    
    /**
     * This hook allows modules to add support for a specific auth type to
     * ap_note_auth_failure
     * @param r the current request
     * @param auth_type the configured auth_type
     * @return OK, DECLINED
     */
    AP_DECLARE_HOOK(int, note_auth_failure, (request_rec *r, const char *auth_type))
    
    /**
     * Get the password from the request headers. This function has multiple side
     * effects due to its prior use in the old authentication framework.
     * ap_get_basic_auth_components() should be preferred.
     *
     * @deprecated @see ap_get_basic_auth_components
     * @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).
     */
    AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw);
    
    #define AP_GET_BASIC_AUTH_PW_NOTE "AP_GET_BASIC_AUTH_PW_NOTE"
    
    /**
     * Get the username and/or password from the request's Basic authentication
     * headers. Unlike ap_get_basic_auth_pw(), calling this function has no side
     * effects on the passed request_rec.
     *
     * @param r The current request
     * @param username If not NULL, set to the username sent by the client
     * @param password If not NULL, set to the password sent by the client
     * @return APR_SUCCESS if the credentials were successfully parsed and returned;
     *         APR_EINVAL if there was no authentication header sent or if the
     *         client was not using the Basic authentication scheme. username and
     *         password are unchanged on failure.
     */
    AP_DECLARE(apr_status_t) ap_get_basic_auth_components(const request_rec *r,
                                                          const char **username,
                                                          const char **password);
    
    /**
     * parse_uri: break apart the uri
     * @warning Side Effects:
     *    @li sets r->args to rest after '?' (or NULL if no '?')
     *    @li sets r->uri to request uri (without r->args part)
     *    @li sets r->hostname (if not set already) from request (scheme://host:port)
     * @param r The current request
     * @param uri The uri to break apart
     */
    AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri);
    
    #define AP_GETLINE_FOLD 1 /* Whether to merge continuation lines */
    #define AP_GETLINE_CRLF 2 /* Whether line ends must be in the form CR LF */
    #define AP_GETLINE_NOSPC_EOL 4 /* Whether to consume up to and including the
                                      end of line on APR_ENOSPC */
    
    /**
     * 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 flags Bit flag of multiple parsing options
     *              AP_GETLINE_FOLD Whether to merge continuation lines
     *              AP_GETLINE_CRLF Whether line ends must be in the form CR LF
     * @return The length of the line, if successful
     *         n, if the line is too big to fit in the buffer
     *         -1 for miscellaneous errors
     */
    AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int flags);
    
    /**
     * 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 flags Bit flag of multiple parsing options
     *              AP_GETLINE_FOLD Whether to merge continuation lines
     *              AP_GETLINE_CRLF Whether line ends must be in the form CR LF
     * @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 flags,
                                         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
    
    /** @see ap_rgetline */
    AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
                                              apr_size_t *read,
                                              request_rec *r, int flags,
                                              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 */
    /*
     * pre_read_request --- run right before read_request_line(),
     *                  and not run during any subrequests.
     */
    /**
     * This hook allows modules to affect the request or connection immediately before
     * the request has been read, and before any other phases have been processes.
     * @param r The current request of the soon-to-be-read request
     * @param c The connection
     * @return None/void
     */
    AP_DECLARE_HOOK(void,pre_read_request,(request_rec *r, conn_rec *c))
    
    /*
     * 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
     */
    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_...
     */
    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
     */
    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
     */
    AP_DECLARE_HOOK(apr_port_t,default_port,(const request_rec *r))
    
    
    #define AP_PROTOCOL_HTTP1        "http/1.1"
    
    /**
     * Determine the list of protocols available for a connection/request. This may
     * be collected with or without any request sent, in which case the request is 
     * NULL. Or it may be triggered by the request received, e.g. through the 
     * "Upgrade" header.
     *
     * This hook will be run whenever protocols are being negotiated (ALPN as
     * one example). It may also be invoked at other times, e.g. when the server
     * wants to advertise protocols it is capable of switching to.
     * 
     * The identifiers for protocols are taken from the TLS extension type ALPN:
     * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
     *
     * If no protocols are added to the proposals, the server not perform any
     * switch. If the protocol selected from the proposals is the protocol
     * already in place, also no protocol switch will be invoked.
     *
     * The client may already have announced the protocols it is willing to
     * accept. These will then be listed as offers. This parameter may also
     * be NULL, indicating that offers from the client are not known and
     * the hooks should propose all protocols that are valid for the
     * current connection/request.
     *
     * All hooks are run, unless one returns an error. Proposals may contain
     * duplicates. The order in which proposals are added is usually ignored.
     * 
     * @param c The current connection
     * @param r The current request or NULL
     * @param s The server/virtual host selected
     * @param offers A list of protocol identifiers offered by the client or
     *               NULL to indicated that the hooks are free to propose 
     * @param proposals The list of protocol identifiers proposed by the hooks
     * @return OK or DECLINED
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE_HOOK(int,protocol_propose,(conn_rec *c, request_rec *r,
                                          server_rec *s,
                                          const apr_array_header_t *offers,
                                          apr_array_header_t *proposals))
    
    /**
     * Perform a protocol switch on the connection. The exact requirements for
     * that depend on the protocol in place and the one switched to. The first 
     * protocol module to handle the switch is the last module run.
     * 
     * For a connection level switch (r == NULL), the handler must on return
     * leave the conn_rec in a state suitable for processing the switched
     * protocol, e.g. correct filters in place.
     *
     * For a request triggered switch (r != NULL), the protocol switch is done
     * before the response is sent out. When switching from "http/1.1" via Upgrade
     * header, the 101 intermediate response will have been sent. The
     * hook needs then to process the connection until it can be closed. Which
     * the server will enforce on hook return.
     * Any error the hook might encounter must already be sent by the hook itself
     * to the client in whatever form the new protocol requires.
     *
     * @param c The current connection
     * @param r The current request or NULL
     * @param s The server/virtual host selected
     * @param protocol The protocol identifier we try to switch to
     * @return OK or DECLINED
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE_HOOK(int,protocol_switch,(conn_rec *c, request_rec *r,
                                         server_rec *s,
                                         const char *protocol))
    
    /**
     * Return the protocol used on the connection. Modules implementing
     * protocol switching must register here and return the correct protocol
     * identifier for connections they switched.
     *
     * To find out the protocol for the current connection, better call
     * @see ap_get_protocol which internally uses this hook.
     *
     * @param c The current connection
     * @return The identifier of the protocol in place or NULL
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE_HOOK(const char *,protocol_get,(const conn_rec *c))
    
    /**
     * Get the protocols that the connection and optional request may
     * upgrade to - besides the protocol currently active on the connection. These
     * values may be used to announce to a client what choices it has.
     *
     * If report_all == 0, only protocols more preferable than the one currently
     * being used, are reported. Otherwise, all available protocols beside the
     * current one are being reported.
     *
     * @param c The current connection
     * @param r The current request or NULL
     * @param s The server/virtual host selected or NULL
     * @param report_all include also protocols less preferred than the current one
     * @param pupgrades on return, possible protocols to upgrade to in descending order 
     *                 of preference. Maybe NULL if none are available.    
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE(apr_status_t) ap_get_protocol_upgrades(conn_rec *c, request_rec *r, 
                                                      server_rec *s, int report_all, 
                                                      const apr_array_header_t **pupgrades);
                                                      
    /**
     * Select a protocol for the given connection and optional request. Will return
     * the protocol identifier selected which may be the protocol already in place
     * on the connection. The selected protocol will be NULL if non of the given
     * choices could be agreed upon (e.g. no proposal as made).
     *
     * A special case is where the choices itself is NULL (instead of empty). In
     * this case there are no restrictions imposed on protocol selection.
     *
     * @param c The current connection
     * @param r The current request or NULL
     * @param s The server/virtual host selected
     * @param choices A list of protocol identifiers, normally the clients whishes
     * @return The selected protocol or NULL if no protocol could be agreed upon
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE(const char *) ap_select_protocol(conn_rec *c, request_rec *r, 
                                                server_rec *s,
                                                const apr_array_header_t *choices);
    
    /**
     * Perform the actual protocol switch. The protocol given must have been
     * selected before on the very same connection and request pair.
     *
     * @param c The current connection
     * @param r The current request or NULL
     * @param s The server/virtual host selected
     * @param protocol the protocol to switch to
     * @return APR_SUCCESS, if caller may continue processing as usual
     *         APR_EOF,     if caller needs to stop processing the connection
     *         APR_EINVAL,  if the protocol is already in place
     *         APR_NOTIMPL, if no module performed the switch
     *         Other errors where appropriate
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE(apr_status_t) ap_switch_protocol(conn_rec *c, request_rec *r, 
                                                server_rec *s,
                                                const char *protocol);
    
    /**
     * Call the protocol_get hook to determine the protocol currently in use
     * for the given connection.
     *
     * Unless another protocol has been switch to, will default to
     * @see AP_PROTOCOL_HTTP1 and modules implementing a  new protocol must
     * report a switched connection via the protocol_get hook.
     *
     * @param c The connection to determine the protocol for
     * @return the protocol in use, never NULL
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE(const char *) ap_get_protocol(conn_rec *c);
    
    /**
     * Check if the given protocol is an allowed choice on the given
     * combination of connection, request and server. 
     *
     * When server is NULL, it is taken from request_rec, unless
     * request_rec is NULL. Then it is taken from the connection base
     * server.
     *
     * @param c The current connection
     * @param r The current request or NULL
     * @param s The server/virtual host selected or NULL
     * @param protocol the protocol to switch to
     * @return != 0 iff protocol is allowed
     * @bug This API or implementation and order of operations should be considered
     * experimental and will continue to evolve in future 2.4 releases, with
     * a corresponding minor module magic number (MMN) bump to indicate the
     * API revision level.
     */
    AP_DECLARE(int) ap_is_allowed_protocol(conn_rec *c, request_rec *r,
                                           server_rec *s, const char *protocol);
    
    /** @see ap_bucket_type_error */
    typedef struct ap_bucket_error ap_bucket_error;
    
    /**
     * @struct ap_bucket_error
     * @brief  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;
    };
    
    /** @see ap_bucket_type_error */
    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
     */
    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
     */
    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);
    
    /**
     * Sett up the protocol fields for subsidiary requests
     * @param rnew New Sub Request
     * @param r current request
     */
    AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r);
    
    /**
     * A wrapup function to keep the internal accounting straight.
     * Indicates that there is no more content coming.
     * @param sub_r Subrequest that is now compete
     */
    AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r);
    
    /**
     * Send an interim (HTTP 1xx) response immediately.
     * @param r The request
     * @param send_headers Whether to send&clear headers in r->headers_out
     */
    AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers);
    
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_PROTOCOL_H */
    /** @} */
    �������������������������������������������������������������������������������������������������httpd-2.4.64/include/http_core.h��������������������������������������������������������������������0000664�0001751�0001751�00000110357�14636331117�016421� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  http_core.h
     * @brief CORE HTTP Daemon
     *
     * @defgroup APACHE_CORE_HTTPD Core HTTP Daemon
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #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"
    #include "ap_expr.h"
    #include "apr_poll.h"
    #include "apr_tables.h"
    
    #include "http_config.h"
    
    #if APR_HAVE_STRUCT_RLIMIT
    #include <sys/time.h>
    #include <sys/resource.h>
    #endif
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* ****************************************************************
     *
     * 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).
     */
    
    /**
     * @defgroup APACHE_CORE_HTTPD_ACESSORS Acessors
     *
     * @brief File/Directory Accessor directives
     *
     * @{
     */
    
    /** No directives */
    #define OPT_NONE 0
    /** Indexes directive */
    #define OPT_INDEXES 1
    /** SSI is enabled without exec= permission  */
    #define OPT_INCLUDES 2
    /**  FollowSymLinks directive */
    #define OPT_SYM_LINKS 4
    /**  ExecCGI directive */
    #define OPT_EXECCGI 8
    /**  directive unset */
    #define OPT_UNSET 16
    /**  SSI exec= permission is permitted, iff OPT_INCLUDES is also set */
    #define OPT_INC_WITH_EXEC 32
    /** SymLinksIfOwnerMatch directive */
    #define OPT_SYM_OWNER 64
    /** MultiViews directive */
    #define OPT_MULTI 128
    /**  All directives */
    #define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_INC_WITH_EXEC|OPT_SYM_LINKS|OPT_EXECCGI)
    /** @} */
    
    /**
     * @defgroup get_remote_host Remote Host Resolution
     * @ingroup APACHE_CORE_HTTPD
     * @{
     */
    /** 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)
    
    /** @} // get_remote_host */
    
    /** all of the requirements must be met */
    #define SATISFY_ALL 0
    /**  any of the requirements must be met */
    #define SATISFY_ANY 1
    /** There are no applicable satisfy lines */
    #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
     */
    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
     */
    AP_DECLARE(int) ap_allow_overrides(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
     */
    AP_DECLARE(const char *) ap_document_root(request_rec *r);
    
    /**
     * Lookup the remote user agent's DNS name or IP address
     * @ingroup get_remote_host
     * @param req The current request
     * @param type The type of lookup to perform.  One of:
     * <pre>
     *     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.
     * </pre>
     * @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 (based on the request useragent_ip)
     */
    AP_DECLARE(const char *) ap_get_useragent_host(request_rec *req, int type,
                                                   int *str_is_ip);
    
    /**
     * Lookup the remote client's DNS name or IP address
     * @ingroup get_remote_host
     * @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:
     * <pre>
     *     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.
     * </pre>
     * @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 (based on the connection client_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
     */
    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
     */
    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
     */
    AP_DECLARE(const char *) ap_get_server_name(request_rec *r);
    
    /**
     * 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]").
     * @param r The current request
     * @return the server name
     */
    AP_DECLARE(const char *) ap_get_server_name_for_url(request_rec *r);
    
    /**
     * Get the current server port
     * @param r The current request
     * @return The server's port
     */
    AP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r);
    
    /**
     * Get the size of read buffers
     * @param r The current request
     * @return The read buffers size
     */
    AP_DECLARE(apr_size_t) ap_get_read_buf_size(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
     */
    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
     */
    AP_DECLARE(apr_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
     */
    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
     */
    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.
     */
    
    /** @see require_line */
    typedef struct require_line require_line;
    
    /**
     * @brief 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
     */
    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
     */
    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:
     * <pre>
     *      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
     * </pre>
     */
    AP_DECLARE(int) ap_satisfies(request_rec *r);
    
    /**
     * 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;
    
    /**
     * Accessor for core_module's specific data. Equivalent to
     * ap_get_module_config(cv, &core_module) but more efficient.
     * @param cv The vector in which the modules configuration is stored.
     *        usually r->per_dir_config or s->module_config
     * @return The module-specific data
     */
    AP_DECLARE(void *) ap_get_core_module_config(const ap_conf_vector_t *cv);
    
    /**
     * Accessor to set core_module's specific data. Equivalent to
     * ap_set_module_config(cv, &core_module, val) but more efficient.
     * @param cv The vector in which the modules configuration is stored.
     *        usually r->per_dir_config or s->module_config
     * @param val The module-specific data to set
     */
    AP_DECLARE(void) ap_set_core_module_config(ap_conf_vector_t *cv, void *val);
    
    /** Get the socket from the core network filter. This should be used instead of
     * accessing the core connection config directly.
     * @param c The connection record
     * @return The socket
     */
    AP_DECLARE(apr_socket_t *) ap_get_conn_socket(conn_rec *c);
    
    #ifndef AP_DEBUG
    #define AP_CORE_MODULE_INDEX  0
    #define ap_get_core_module_config(v) \
        (((void **)(v))[AP_CORE_MODULE_INDEX])
    #define ap_set_core_module_config(v, val) \
        ((((void **)(v))[AP_CORE_MODULE_INDEX]) = (val))
    #else
    #define AP_CORE_MODULE_INDEX  (AP_DEBUG_ASSERT(core_module.module_index == 0), 0)
    #endif
    
    /**
     * @brief  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;
    
        /** 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
                                       */
    
        /** per-request document root of the server. This allows mass vhosting
         * modules better compatibility with some scripts. Normally the
         * context_* info should be used instead */
        const char *document_root;
    
        /*
         * more fine-grained context information which is set by modules like
         * mod_alias and mod_userdir
         */
        /** the context root directory on disk for the current resource,
         *  without trailing slash
         */
        const char *context_document_root;
        /** the URI prefix that corresponds to the context_document_root directory,
         *  without trailing slash
         */
        const char *context_prefix;
    
        /** 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;
    
        /** 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_NOTE_IF_WALK        3
    #define AP_NUM_STD_NOTES       4
    
    /**
     * 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);
    
    
    typedef unsigned char allow_options_t;
    typedef unsigned int 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_DIGEST (1 << 4)
    #define ETAG_ALL    (ETAG_MTIME | ETAG_INODE | ETAG_SIZE)
    /* This is the default value used */
    #define ETAG_BACKWARD (ETAG_MTIME | ETAG_SIZE)
    
    /* Generic ON/OFF/UNSET for unsigned int foo :2 */
    #define AP_CORE_CONFIG_OFF   (0)
    #define AP_CORE_CONFIG_ON    (1)
    #define AP_CORE_CONFIG_UNSET (2)
    
    /* Generic merge of flag */
    #define AP_CORE_MERGE_FLAG(field, to, base, over) to->field = \
                   over->field != AP_CORE_CONFIG_UNSET            \
                   ? over->field                                  \
                   : base->field                                   
    
    /**
     * @brief Server Signature Enumeration
     */
    typedef enum {
        srv_sig_unset,
        srv_sig_off,
        srv_sig_on,
        srv_sig_withmail
    } server_signature_e;
    
    /**
     * @brief Per-directory configuration
     */
    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;
    
        /* Used to be the custom response config. No longer used. */
        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;
    
        unsigned 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;
    
        /* Access control */
        apr_array_header_t *sec_file;
        apr_array_header_t *sec_if;
        ap_regex_t *r;
    
        const char *mime_type;       /* forced with ForceType  */
        const char *handler;         /* forced by something other than SetHandler */
        const char *output_filters;  /* forced with SetOutputFilters */
        const char *input_filters;   /* forced with SetInputFilters */
        int accept_path_info;        /* forced with AcceptPathInfo */
    
        /*
         * 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 sendfile'ed */
    
    #define USE_CANONICAL_PHYS_PORT_OFF   (0)
    #define USE_CANONICAL_PHYS_PORT_ON    (1)
    #define USE_CANONICAL_PHYS_PORT_UNSET (2)
        unsigned int use_canonical_phys_port : 2;
    
        unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f w/o being
                                                 * pitched indiscriminately */
        unsigned int decode_encoded_slashes : 1; /* whether to decode encoded slashes in URLs */
    
    #define AP_CONDITION_IF        1
    #define AP_CONDITION_ELSE      2
    #define AP_CONDITION_ELSEIF    (AP_CONDITION_ELSE|AP_CONDITION_IF)
        unsigned int condition_ifelse : 2; /* is this an <If>, <ElseIf>, or <Else> */
    
        ap_expr_info_t *condition;   /* Conditionally merge <If> sections */
    
        /** per-dir log config */
        struct ap_logconf *log;
    
        /** Table of directives allowed per AllowOverrideList */
        apr_table_t *override_list;
    
    #define AP_MAXRANGES_UNSET     -1
    #define AP_MAXRANGES_DEFAULT   -2
    #define AP_MAXRANGES_UNLIMITED -3
    #define AP_MAXRANGES_NORANGES   0
        /** Number of Ranges before returning HTTP_OK. **/
        int max_ranges;
        /** Max number of Range overlaps (merges) allowed **/
        int max_overlaps;
        /** Max number of Range reversals (eg: 200-300, 100-125) allowed **/
        int max_reversals;
    
        /** Named back references */
        apr_array_header_t *refs;
    
        /** Custom response config with expression support. The hash table
         * contains compiled expressions keyed against the custom response
         * code.
         */
        apr_hash_t *response_code_exprs;
    
    #define AP_CGI_PASS_AUTH_OFF     (0)
    #define AP_CGI_PASS_AUTH_ON      (1)
    #define AP_CGI_PASS_AUTH_UNSET   (2)
        /** CGIPassAuth: Whether HTTP authorization headers will be passed to
         * scripts as CGI variables; affects all modules calling
         * ap_add_common_vars(), as well as any others using this field as 
         * advice
         */
        unsigned int cgi_pass_auth : 2;
        unsigned int qualify_redirect_url :2;
        ap_expr_info_t  *expr_handler;         /* forced with SetHandler */
    
        /** Table of rules for building CGI variables, NULL if none configured */
        apr_hash_t *cgi_var_rules;
    
        apr_size_t read_buf_size;
    } core_dir_config;
    
    /* macro to implement off by default behaviour */
    #define AP_SENDFILE_ENABLED(x) \
        ((x) == ENABLE_SENDFILE_ON ? APR_SENDFILE_ENABLED : 0)
    
    /* Per-server core configuration */
    
    typedef struct {
    
        char *gprof_dir;
    
        /* 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 */
    
        const char *protocol;
        apr_table_t *accf_map;
    
        /* array of ap_errorlog_format_item for error log format string */
        apr_array_header_t *error_log_format;
        /*
         * two arrays of arrays of ap_errorlog_format_item for additional information
         * logged to the error log once per connection/request
         */
        apr_array_header_t *error_log_conn;
        apr_array_header_t *error_log_req;
    
        /* TRACE control */
    #define AP_TRACE_UNSET    -1
    #define AP_TRACE_DISABLE   0
    #define AP_TRACE_ENABLE    1
    #define AP_TRACE_EXTENDED  2
        int trace_enable;
    #define AP_MERGE_TRAILERS_UNSET    0
    #define AP_MERGE_TRAILERS_ENABLE   1
    #define AP_MERGE_TRAILERS_DISABLE  2
        int merge_trailers;
    
        apr_array_header_t *protocols;
        int protocols_honor_order;
    
    #define AP_HTTP09_UNSET   0
    #define AP_HTTP09_ENABLE  1
    #define AP_HTTP09_DISABLE 2
        char http09_enable;
    
    #define AP_HTTP_CONFORMANCE_UNSET     0
    #define AP_HTTP_CONFORMANCE_UNSAFE    1
    #define AP_HTTP_CONFORMANCE_STRICT    2
        char http_conformance;
    
    #define AP_HTTP_METHODS_UNSET         0
    #define AP_HTTP_METHODS_LENIENT       1
    #define AP_HTTP_METHODS_REGISTERED    2
        char http_methods;
        unsigned int merge_slashes;
     
        apr_size_t   flush_max_threshold;
        apr_int32_t  flush_max_pipelined;
        unsigned int strict_host_check;
    #ifdef WIN32
        apr_array_header_t *unc_list;
    #endif
    } 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(apr_pool_t *p, core_dir_config *conf, void *url_config);
    AP_CORE_DECLARE(const char *) ap_add_if_conf(apr_pool_t *p, 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. */
    apr_status_t 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);
    
    
    AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s);
    AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto);
    
    typedef struct core_output_filter_ctx core_output_filter_ctx_t;
    typedef struct core_filter_ctx        core_ctx_t;
    
    struct core_filter_ctx {
        apr_bucket_brigade *b;
        apr_bucket_brigade *tmpbb;
    };
    
    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;
    
    /**
     * Insert the network bucket into the core input filter's input brigade.
     * This hook is intended for MPMs or protocol modules that need to do special
     * socket setup.
     * @param c The connection
     * @param bb The brigade to insert the bucket into
     * @param socket The socket to put into a bucket
     * @return AP_DECLINED if the current function does not handle this connection,
     *         APR_SUCCESS or an error otherwise.
     */
    AP_DECLARE_HOOK(apr_status_t, insert_network_bucket,
                    (conn_rec *c, apr_bucket_brigade *bb, apr_socket_t *socket))
    
    /* ----------------------------------------------------------------------
     *
     * 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 */
    AP_DECLARE_DATA extern ap_filter_rec_t *ap_subreq_core_filter_handle;
    AP_DECLARE_DATA extern ap_filter_rec_t *ap_core_output_filter_handle;
    AP_DECLARE_DATA extern ap_filter_rec_t *ap_content_length_filter_handle;
    AP_DECLARE_DATA extern 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));
    
    APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_in,
                            (conn_rec *c, apr_off_t bytes));
    
    APR_DECLARE_OPTIONAL_FN(apr_off_t, ap_logio_get_last_bytes, (conn_rec *c));
    
    /* ----------------------------------------------------------------------
     *
     * Error log formats
     */
    
    /**
     * The info structure passed to callback functions of errorlog handlers.
     * Not all information is available in all contexts. In particular, all
     * pointers may be NULL.
     */
    typedef struct ap_errorlog_info {
        /** current server_rec.
         *  Should be preferred over c->base_server and r->server
         */
        const server_rec *s;
    
        /** current conn_rec.
         *  Should be preferred over r->connection
         */
        const conn_rec *c;
    
        /** current request_rec. */
        const request_rec *r;
        /** r->main if r is a subrequest, otherwise equal to r */
        const request_rec *rmain;
    
        /** pool passed to ap_log_perror, NULL otherwise */
        apr_pool_t *pool;
    
        /** name of source file where the log message was produced, NULL if N/A. */
        const char *file;
        /** line number in the source file, 0 if N/A */
        int line;
    
        /** module index of module that produced the log message, APLOG_NO_MODULE if N/A. */
        int module_index;
        /** log level of error message (flags like APLOG_STARTUP have been removed), -1 if N/A */
        int level;
    
        /** apr error status related to the log message, 0 if no error */
        apr_status_t status;
    
        /** 1 if logging to syslog, 0 otherwise */
        int using_syslog;
        /** 1 if APLOG_STARTUP was set for the log message, 0 otherwise */
        int startup;
    
        /** message format */
        const char *format;
    } ap_errorlog_info;
    
    /**
     * callback function prototype for a external errorlog handler
     * @note To avoid unbounded memory usage, these functions must not allocate
     * memory from the server, connection, or request pools. If an errorlog
     * handler absolutely needs a pool to pass to other functions, it must create
     * and destroy a sub-pool.
     */
    typedef int ap_errorlog_handler_fn_t(const ap_errorlog_info *info,
                                         const char *arg, char *buf, int buflen);
    
    /**
     * Register external errorlog handler
     * @param p config pool to use
     * @param tag the new format specifier (i.e. the letter after the %)
     * @param handler the handler function
     * @param flags flags (reserved, set to 0)
     */
    AP_DECLARE(void) ap_register_errorlog_handler(apr_pool_t *p, char *tag,
                                                  ap_errorlog_handler_fn_t *handler,
                                                  int flags);
    
    typedef struct ap_errorlog_handler {
        ap_errorlog_handler_fn_t *func;
        int flags; /* for future extensions */
    } ap_errorlog_handler;
    
      /** item starts a new field */
    #define AP_ERRORLOG_FLAG_FIELD_SEP       1
      /** item is the actual error message */
    #define AP_ERRORLOG_FLAG_MESSAGE         2
      /** skip whole line if item is zero-length */
    #define AP_ERRORLOG_FLAG_REQUIRED        4
      /** log zero-length item as '-' */
    #define AP_ERRORLOG_FLAG_NULL_AS_HYPHEN  8
    
    typedef struct {
        /** ap_errorlog_handler function */
        ap_errorlog_handler_fn_t *func;
        /** argument passed to item in {} */
        const char *arg;
        /** a combination of the AP_ERRORLOG_* flags */
        unsigned int flags;
        /** only log item if the message's log level is higher than this */
        unsigned int min_loglevel;
    } ap_errorlog_format_item;
    
    /**
     * hook method to log error messages
     * @ingroup hooks
     * @param info pointer to ap_errorlog_info struct which contains all
     *        the details
     * @param errstr the (unformatted) message to log
     * @warning Allocating from the usual pools (pool, info->c->pool, info->p->pool)
     *          must be avoided because it can cause memory leaks.
     *          Use a subpool if necessary.
     */
    AP_DECLARE_HOOK(void, error_log, (const ap_errorlog_info *info,
                                      const char *errstr))
    
    AP_CORE_DECLARE(void) ap_register_log_hooks(apr_pool_t *p);
    AP_CORE_DECLARE(void) ap_register_config_hooks(apr_pool_t *p);
    
    /* ----------------------------------------------------------------------
     *
     * ident lookups with mod_ident
     */
    
    APR_DECLARE_OPTIONAL_FN(const char *, ap_ident_lookup,
                            (request_rec *r));
    
    /* ----------------------------------------------------------------------
     *
     * authorization values with mod_authz_core
     */
    
    APR_DECLARE_OPTIONAL_FN(int, authz_some_auth_required, (request_rec *r));
    APR_DECLARE_OPTIONAL_FN(const char *, authn_ap_auth_type, (request_rec *r));
    APR_DECLARE_OPTIONAL_FN(const char *, authn_ap_auth_name, (request_rec *r));
    
    /* ----------------------------------------------------------------------
     *
     * authorization values with mod_access_compat
     */
    
    APR_DECLARE_OPTIONAL_FN(int, access_compat_ap_satisfies, (request_rec *r));
    
    /* ---------------------------------------------------------------------- */
    
    /** Query the server for some state information
     * @param query_code Which information is requested
     * @return the requested state information
     */
    AP_DECLARE(int) ap_state_query(int query_code);
    
    /*
     * possible values for query_code in ap_state_query()
     */
    
      /** current status of the server */
    #define AP_SQ_MAIN_STATE        0
      /** are we going to serve requests or are we just testing/dumping config */
    #define AP_SQ_RUN_MODE          1
        /** generation of the top-level apache parent */
    #define AP_SQ_CONFIG_GEN        2
    
    /*
     * return values for ap_state_query()
     */
    
      /** return value for unknown query_code */
    #define AP_SQ_NOT_SUPPORTED       -1
    
    /* values returned for AP_SQ_MAIN_STATE */
      /** before the config preflight */
    #define AP_SQ_MS_INITIAL_STARTUP   1
      /** initial configuration run for setting up log config, etc. */
    #define AP_SQ_MS_CREATE_PRE_CONFIG 2
      /** tearing down configuration */
    #define AP_SQ_MS_DESTROY_CONFIG    3
      /** normal configuration run */
    #define AP_SQ_MS_CREATE_CONFIG     4
      /** running the MPM */
    #define AP_SQ_MS_RUN_MPM           5
      /** cleaning up for exit */
    #define AP_SQ_MS_EXITING           6
    
    /* values returned for AP_SQ_RUN_MODE */
      /** command line not yet parsed */
    #define AP_SQ_RM_UNKNOWN           1
      /** normal operation (server requests or signal server) */
    #define AP_SQ_RM_NORMAL            2
      /** config test only */
    #define AP_SQ_RM_CONFIG_TEST       3
      /** only dump some parts of the config */
    #define AP_SQ_RM_CONFIG_DUMP       4
    
    /** Get a apr_pollfd_t populated with descriptor and descriptor type
     * and the timeout to use for it.
     * @return APR_ENOTIMPL if not supported for a connection.
     */
    AP_DECLARE_HOOK(apr_status_t, get_pollfd_from_conn,
                    (conn_rec *c, struct apr_pollfd_t *pfd,
                     apr_interval_time_t *ptimeout))
    
    /**
     * Pass in a `struct apr_pollfd_t*` and get `desc_type` and `desc`
     * populated with a suitable value for polling connection input.
     * For primary connection (c->master == NULL), this will be the connection
     * socket. For secondary connections this may differ or not be available
     * at all.
     * Note that APR_NO_DESC may be set to indicate that the connection
     * input is already closed.
     *
     * @param pfd  the pollfd to set the descriptor in
     * @param ptimeout  != NULL to retrieve the timeout in effect
     * @return ARP_SUCCESS when the information was assigned.
     */
    AP_CORE_DECLARE(apr_status_t) ap_get_pollfd_from_conn(conn_rec *c,
                                          struct apr_pollfd_t *pfd,
                                          apr_interval_time_t *ptimeout);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_CORE_H */
    /** @} */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/http_ssl.h���������������������������������������������������������������������0000664�0001751�0001751�00000035177�14300512413�016264� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  http_ssl.h
     * @brief SSL protocol handling
     *
     * @defgroup APACHE_CORE_PROTO SSL Protocol Handling
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_HTTP_SSL_H
    #define APACHE_HTTP_SSL_H
    
    #include "httpd.h"
    #include "apr_portable.h"
    #include "apr_mmap.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    struct ap_conf_vector_t;
    
    /**
     * This hook allows modules that manage SSL connection to register their
     * inquiry function for checking if a connection is using SSL from them.
     * @param c The current connection
     * @return OK if the connection is using SSL, DECLINED if not.
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int,ssl_conn_is_ssl,(conn_rec *c))
    
    /**
     * Return != 0 iff the connection is encrypted with SSL.
     * @param c the connection
     */
    AP_DECLARE(int) ap_ssl_conn_is_ssl(conn_rec *c);
    
    /**
     * This hook declares a connection to be outgoing and the configuration that applies to it.
     * This hook can be called several times in the lifetime of an outgoing connection, e.g.
     * when it is re-used in different request contexts. It will at least be called after the
     * connection was created and before the pre-connection hooks is invoked.
     * All outgoing-connection hooks are run until one returns something other than DECLINE.
     * if enable_ssl != 0, a hook that sets up SSL for the connection needs to return OK
     * to prevent subsequent hooks from doing the same.
     *
     * @param c The connection on which requests/data are to be sent.
     * @param dir_conf The directory configuration in which this connection is being used.
     * @param enable_ssl If != 0, the SSL protocol should be enabled for this connection.
     * @return DECLINED, OK when ssl was enabled
     */
    AP_DECLARE_HOOK(int, ssl_bind_outgoing,
                   (conn_rec *c, struct ap_conf_vector_t *dir_conf, int enable_ssl))
    
    /**
     * Assures the connection is marked as outgoing and invokes the ssl_bind_outgoing hook.
     * This may be called several times on an outgoing connection with varying dir_conf
     * values. require_ssl is not allowed to change on the same connection.
     *
     * @param c The connection on which requests/data are to be sent.
     * @param dir_conf The directory configuration in which this connection is being used.
     * @param require_ssl != 0 iff this connection needs to be secured by SSL/TLS protocol.
     * @return OK iff ssl was required and is enabled, DECLINED otherwise
     */
    AP_DECLARE(int) ap_ssl_bind_outgoing(conn_rec *c, struct ap_conf_vector_t *dir_conf,
                                         int require_ssl);
    
    /**
     * Return != 0 iff handlers/hooks for outgoing connections are registered.
     */
    AP_DECLARE(int) ap_ssl_has_outgoing_handlers(void);
    
    /**
     * This hook allows modules to look up SSL related variables for a
     * server/connection/request, depending on what they inquire. Some
     * variables will only be available for a connection/request, for example.
     * @param p The pool to allocate a returned value in, MUST be provided
     * @param s The server to inquire a value for, maybe NULL
     * @param c The current connection, maybe NULL
     * @param r The current request, maybe NULL
     * @param name The name of the variable to retrieve, MUST be provided
     * @return value or the variable or NULL if not provided/available
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(const char *,ssl_var_lookup,
        (apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name))
    
    /**
     * Lookup an SSL related variable for the server/connection/request or a global
     * value when all those parameters are set to NULL. Pool and name must always be
     * provided and the returned value (if not NULL) will be allocated from the pool.
     * @param p The pool to allocate a returned value in, MUST be provided
     * @param s The server to inquire a value for, maybe NULL
     * @param c The current connection, maybe NULL
     * @param r The current request, maybe NULL
     * @param name The name of the variable to retrieve, MUST be provided
     * @return value or the variable or NULL if not provided/available
     */
    AP_DECLARE(const char *) ap_ssl_var_lookup(apr_pool_t *p, server_rec *s,
                                               conn_rec *c, request_rec *r,
                                               const char *name);
    
    /**
     * Register to provide certificate/key files for servers. Certificate files are
     * expected to contain the certificate chain, beginning with the server's certificate,
     * excluding the trust anchor, in PEM format.
     * They must be accompanied by a private key file, also in PEM format.
     *
     * @param s the server certificates are collected for
     * @param p the pool to use for allocations
     * @param cert_files an array of const char* with the path to the certificate chain
     * @param key_files an array of const char* with the path to the private key file
     * @return OK if files were added, DECLINED if not, or other for error.
     */
    
    AP_DECLARE_HOOK(int, ssl_add_cert_files, (server_rec *s, apr_pool_t *p,
                                              apr_array_header_t *cert_files,
                                              apr_array_header_t *key_files))
    
    /**
     * Collect certificate/key files from all providers registered. This includes
     * providers registered at the global 'ssl_add_cert_files', as well as those
     * installed in the OPTIONAL 'ssl_add_cert_files' hook as may be provided by
     * ssl modules.
     *
     * @param s the server certificates are collected for
     * @param p the pool to use for allocations
     * @param cert_files an array of const char* with the path to the certificate chain
     * @param key_files an array of const char* with the path to the private key file
     */
    AP_DECLARE(apr_status_t) ap_ssl_add_cert_files(server_rec *s, apr_pool_t *p,
                                                   apr_array_header_t *cert_files,
                                                   apr_array_header_t *key_files);
    
    
    /**
     * Register to provide 'fallback' certificates in case no 'real' certificates
     * have been configured/added by other providers. Modules using these certificates
     * are encouraged to answer requests to this server with a 503 response code.
     *
     * @param s the server certificates are collected for
     * @param p the pool to use for allocations
     * @param cert_files an array of const char* with the path to the certificate chain
     * @param key_files an array of const char* with the path to the private key file
     * @return OK if files were added, DECLINED if not, or other for error.
     */
    AP_DECLARE_HOOK(int, ssl_add_fallback_cert_files, (server_rec *s, apr_pool_t *p,
                                                       apr_array_header_t *cert_files,
                                                       apr_array_header_t *key_files))
    
    /**
     * Collect 'fallback' certificate/key files from all registered providers, either
     * in the global 'ssl_add_fallback_cert_files' hook or the optional one of similar
     * name as provided by mod_ssl and sorts.
     * Certificates obtained this way are commonly self signed, temporary crutches.
     * To be used to the time it takes to retrieve a 'read', trusted certificate.
     * A module using fallbacks is encouraged to answer all requests with a 503.
     *
     * @param s the server certificates are collected for
     * @param p the pool to use for allocations
     * @param cert_files an array of const char* with the path to the certificate chain
     * @param key_files an array of const char* with the path to the private key file
     */
    AP_DECLARE(apr_status_t) ap_ssl_add_fallback_cert_files(server_rec *s, apr_pool_t *p,
                                                            apr_array_header_t *cert_files,
                                                            apr_array_header_t *key_files);
    
    
    /**
     * On TLS connections that do not relate to a configured virtual host
     * allow modules to provide a certificate and key to be used on the connection.
     *
     * A Certificate PEM added must be accompanied by a private key PEM. The private
     * key PEM may be given by a NULL pointer, in which case it is expected to be found in
     * the certificate PEM string.
     */
    AP_DECLARE_HOOK(int, ssl_answer_challenge, (conn_rec *c, const char *server_name,
                                                const char **pcert_pem, const char **pkey_pem))
    
    /**
     * Returns != 0 iff the connection is a challenge to the server, for example
     * as defined in RFC 8555 for the 'tls-alpn-01' domain verification, and needs
     * a specific certificate as answer in the handshake.
     *
     * ALPN protocol negotiation via the hooks 'protocol_propose' and 'protocol_switch'
     * need to have run before this call is made.
     *
     * Certificate PEMs added must be accompanied by a private key PEM. The private
     * key PEM may be given by a NULL pointer, in which case it is expected to be found in
     * the certificate PEM string.
     *
     * A certificate provided this way needs to replace any other certificates selected
     * by configuration or 'ssl_add_cert_pems` on this connection.
     */
    AP_DECLARE(int) ap_ssl_answer_challenge(conn_rec *c, const char *server_name,
                                            const char **pcert_pem, const char **pkey_pem);
    
    
    /**
     * Setup optional functions for ssl related queries so that functions
     * registered by old-style SSL module functions are interrogated by the
     * the new ap_is_ssl() and friends. Installs own optional functions, so that
     * old modules looking for these find one and get the correct results (shadowing).
     *
     * Needs to run in core's very early POST_CONFIG hook.
     * Modules providing such functions register their own optionals during
     * register_hooks(). Modules using such functions retrieve them often
     * in their own post-config or in the even later retrieval hook. When shadowing
     * other modules functions, core's early post-config is a good time.
     * @param pool The pool to use for allocations
     */
    AP_DECLARE(void) ap_setup_ssl_optional_fns(apr_pool_t *pool);
    
    /**
     * Providers of OCSP status responses register at this hook. Installed hooks returning OK
     * are expected to provide later OCSP responses via a 'ap_ssl_ocsp_get_resp_hook'.
     * @param s     the server being configured
     * @params p    a memory pool to use
     * @param id    opaque data uniquely identifying the certificate, provided by caller
     * @param pem   PEM data of certificate first, followed by PEM of issuer cert
     * @return OK iff stapling is being provided
     */
    AP_DECLARE_HOOK(int, ssl_ocsp_prime_hook, (server_rec *s, apr_pool_t *p,
                                               const char *id, apr_size_t id_len,
                                               const char *pem))
    
    /**
     * Registering a certificate for Provisioning of OCSP responses. It is the caller's
     * responsibility to provide a global (apache instance) unique id for the certificate
     * that is then used later in retrieving the OCSP response.
     * A certificate can be primed this way more than once, however the same identifier
     * has to be provided each time (byte-wise same, not pointer same).
     * The memory pointed to by `id` and `pem` is only valid for the duration of the call.
     *
     * @param s     the server being configured
     * @params p    a memory pool to use
     * @param id    opaque data uniquely identifying the certificate, provided by caller
     * @param pem   PEM data of certificate first, followed by chain certs, at least the issuer
     * @return APR_SUCCESS iff OCSP responses will be provided.
     *         APR_ENOENT when no provided was found or took responsibility.
     */
    AP_DECLARE(apr_status_t) ap_ssl_ocsp_prime(server_rec *s, apr_pool_t *p,
                                               const char *id, apr_size_t id_len,
                                               const char *pem);
    
    /**
     * Callback to copy over the OCSP response data. If OCSP response data is not
     * available, this will be called with NULL, 0 parameters!
     *
     * Memory allocation methods and lifetime of data will vary per module and
     * SSL library used. The caller requesting OCSP data will need to make a copy
     * for his own use.
     * Any passed data may only be valid for the duration of the call.
     */
    typedef void ap_ssl_ocsp_copy_resp(const unsigned char *der, apr_size_t der_len, void *userdata);
    
    /**
     * Asking for OCSP response DER data for a certificate formerly primed.
     * @param s     the (SNI selected) server of the connection
     * @param c     the connection
     * @param id    identifier for the certifate, as used in ocsp_stapling_prime()
     * @param cb    callback to invoke when response data is available
     * @param userdata caller supplied data passed to callback
     * @return OK iff response data has been provided, DECLINED otherwise
     */
    AP_DECLARE_HOOK(int, ssl_ocsp_get_resp_hook,
                    (server_rec *s, conn_rec *c, const char *id, apr_size_t id_len,
                     ap_ssl_ocsp_copy_resp *cb, void *userdata))
    
    /**
     * Retrieve the OCSP response data for a previously primed certificate. The id needs
     * to be byte-wise identical to the one used on priming. If the call return ARP_SUCCESS,
     * the callback has been invoked with the OCSP response DER data.
     * Otherwise, a different status code must be returned. Callers in SSL connection
     * handshakes are encouraged to continue the handshake without OCSP data for
     * server reliability. The decision to accept or reject a handshake with missing
     * OCSP stapling data needs to be done by the client.
     * For similar reasons, providers of responses might return seemingly expired ones
     * if they were unable to refresh a response in time.
     *
     * The memory pointed to by `id` is only valid for the duration of the call.
     * Also, the DER data passed to the callback is only valid for the duration
     * of the call.
     *
     * @param s     the (SNI selected) server of the connection
     * @param c     the connection
     * @param id    identifier for the certifate, as used in ocsp_stapling_prime()
     * @param cb    callback to invoke when response data is available
     * @param userdata caller supplied data passed to callback
     * @return APR_SUCCESS iff data has been provided
     */
    AP_DECLARE(apr_status_t) ap_ssl_ocsp_get_resp(server_rec *s, conn_rec *c,
                                                  const char *id, apr_size_t id_len,
                                                  ap_ssl_ocsp_copy_resp *cb, void *userdata);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_SSL_H */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_ldap.h��������������������������������������������������������������������0000664�0001751�0001751�00000043707�14451777424�016425� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file util_ldap.h
     * @brief Apache LDAP library
     */
    
    #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_version.h"
    #if APR_MAJOR_VERSION < 2
    /* The LDAP API is currently only present in APR 1.x */
    #include "apr_ldap.h"
    #else
    #define APR_HAS_LDAP 0
    #endif
    
    #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
    
    #if defined(LDAP_UNAVAILABLE) || APR_HAS_MICROSOFT_LDAPSDK
    #define AP_LDAP_IS_SERVER_DOWN(s)                ((s) == LDAP_SERVER_DOWN \
                    ||(s) == LDAP_UNAVAILABLE)
    #else
    #define AP_LDAP_IS_SERVER_DOWN(s)                ((s) == LDAP_SERVER_DOWN)
    #endif
    
    /* 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
    
    #if APR_HAS_MICROSOFT_LDAPSDK
    #define timeval l_timeval
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #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
    
        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 bound;                          /* Flag to indicate whether this connection is bound yet */
    
        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;
        struct util_ldap_state_t *st;        /* The LDAP vhost config this connection belongs to */
        int keep;                            /* Will this connection be kept when it's unlocked */
    
        int ChaseReferrals;                 /* [on|off] (default = AP_LDAP_CHASEREFERRALS_ON)*/
        int ReferralHopLimit;               /* # of referral hops to follow (default = AP_LDAP_DEFAULT_HOPLIMIT) */
        apr_time_t freed;                   /* the time this conn was placed back in the pool */
        apr_pool_t *rebind_pool;            /* frequently cleared pool for rebind data */
        int must_rebind;                    /* The connection was last bound with other then binddn/bindpw */
        request_rec *r;                     /* request_rec used to find this util_ldap_connection_t */
        apr_time_t last_backend_conn;       /* the approximate time of the last backend LDAP request */
    } util_ldap_connection_t;
    
    typedef struct util_ldap_config_t {
        int ChaseReferrals;
        int ReferralHopLimit;
        apr_array_header_t *client_certs;  /* Client certificates */
    } util_ldap_config_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;
        apr_array_header_t *global_certs;  /* Global CA certificates */
        int   ssl_supported;
        int   secure;
        int   secure_set;
        int   verify_svr_cert;
    
    #if APR_HAS_SHARED_MEMORY
        apr_shm_t *cache_shm;
        apr_rmm_t *cache_rmm;
    #endif
    
        /* cache ald */
        void *util_ldap_cache;
    
        long  connectionTimeout;
        struct timeval *opTimeout;
    
        int debug_level;                    /* SDK debug level */
        apr_interval_time_t connection_pool_ttl;
        int retries;                        /* number of retries for failed bind/search/compare */
        apr_interval_time_t retry_delay;    /* delay between retries of failed bind/search/compare */
    } util_ldap_state_t;
    
    /* Used to store arrays of attribute labels/values. */
    struct mod_auth_ldap_groupattr_entry_t {
        char *name;
    };
    
    /**
     * 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.
     * @fn 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().
     * @fn 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.
     * @fn apr_status_t util_ldap_connection_unbind(util_ldap_connection_t *ldc)
     */
    APR_DECLARE_OPTIONAL_FN(apr_status_t,uldap_connection_unbind,(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.
     * @fn 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 comparison. 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.
     * @fn 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 top-level group
     *      membership.
     * @fn 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));
    
    /**
     * An LDAP function that checks if the specified user is a member of a subgroup.
     * @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 find subgroups to search within.
     * @param attrib The attribute within group objects that identify users.
     * @param value The user attribute value we are trying to compare for.
     * @param subgroupAttrs The attributes within group objects that identify subgroups.
     *                      Array of strings.
     * @param subgroupclasses The objectClass values used to identify groups (and
     *                      subgroups). apr_array_header_t *.
     * @param cur_subgroup_depth Current recursive depth during subgroup processing.
     * @param max_subgroup_depth Maximum depth of recursion allowed during subgroup
     *                           processing.
     * @tip Use this function to determine whether an attribute/value pair exists within a
     *      starting group object or one of its nested subgroups. Typically this would be
     *      used to determine LDAP nested group membership.
     * @deffunc int util_ldap_cache_check_subgroups(request_rec *r, util_ldap_connection_t
     *                                      *ldc, const char *url, const char *dn,
     *                                      const char *attrib, const char value,
     *                                      char **subgroupAttrs, apr_array_header_t
     *                                      *subgroupclasses, int cur_subgroup_depth, int
     *                                      max_subgroup_depth )
     */
    APR_DECLARE_OPTIONAL_FN(int,uldap_cache_check_subgroups,(request_rec *r, util_ldap_connection_t *ldc,
                                           const char *url, const char *dn, const char *attrib, const char *value,
                                           char **subgroupAttrs, apr_array_header_t *subgroupclasses,
                                           int cur_subgroup_depth, int max_subgroup_depth));
    
    /**
     * 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.
     * @fn 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.
     * @fn 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
     * @fn 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 segment to request. A size
     *                of zero requests the max size possible from
     *                apr_shmem_init()
     * @fn 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.
     * @fn 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);
    #ifdef __cplusplus
    }
    #endif
    #endif /* APR_HAS_LDAP */
    #endif /* UTIL_LDAP_H */
    ���������������������������������������������������������httpd-2.4.64/include/httpd.h������������������������������������������������������������������������0000664�0001751�0001751�00000275476�15032733516�015573� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file httpd.h
     * @brief HTTP Daemon routines
     *
     * @defgroup APACHE Apache HTTP Server
     *
     * Top level group of which all other groups are a member
     * @{
     *
     * @defgroup APACHE_MODS Loadable modules
     *           Top level group for modules
     * @defgroup APACHE_OS Operating System Specific
     * @defgroup APACHE_INTERNAL Internal interfaces
     * @defgroup APACHE_CORE Core routines
     * @{
     * @defgroup APACHE_CORE_DAEMON HTTP Daemon Routine
     * @{
     */
    
    #ifndef APACHE_HTTPD_H
    #define APACHE_HTTPD_H
    
    /* 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_version.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 "apr_thread_proc.h"
    
    #include "os.h"
    
    #include "ap_regex.h"
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    
    /* Note: apr_uri.h is also included, see below */
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* ----------------------------- 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 (NETWARE)
    /** Set the default for NetWare */
    #define HTTPD_ROOT "/apache"
    #else
    /** Set for all other OSs */
    #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
    /* Set default for non OS/2 file system */
    #define DOCUMENT_LOCATION  HTTPD_ROOT "/htdocs"
    #endif
    #endif /* DOCUMENT_LOCATION */
    
    /** Maximum number of dynamically loaded modules */
    #ifndef DYNAMIC_MODULE_LIMIT
    #define DYNAMIC_MODULE_LIMIT 256
    #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 60
    #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 or 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.
     */
    
    /** default limit on bytes in Request-Line (Method+URI+HTTP-version) */
    #ifndef DEFAULT_LIMIT_REQUEST_LINE
    #define DEFAULT_LIMIT_REQUEST_LINE 8190
    #endif
    /** default limit on bytes in any one header field  */
    #ifndef DEFAULT_LIMIT_REQUEST_FIELDSIZE
    #define DEFAULT_LIMIT_REQUEST_FIELDSIZE 8190
    #endif
    /** default limit on number of request header fields */
    #ifndef DEFAULT_LIMIT_REQUEST_FIELDS
    #define DEFAULT_LIMIT_REQUEST_FIELDS 100
    #endif
    /** default/hard limit on number of leading/trailing empty lines */
    #ifndef DEFAULT_LIMIT_BLANK_LINES
    #define DEFAULT_LIMIT_BLANK_LINES 10
    #endif
    
    /**
     * The default default character set name to add if AddDefaultCharset is
     * enabled.  Overridden with AddDefaultCharsetName.
     */
    #define DEFAULT_ADD_DEFAULT_CHARSET_NAME "iso-8859-1"
    
    /** 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
    
    /** 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  "<!DOCTYPE HTML PUBLIC \"-//IETF//" \
                              "DTD HTML 2.0//EN\">\n"
    /** HTML 3.2 Doctype */
    #define DOCTYPE_HTML_3_2  "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
                              "DTD HTML 3.2 Final//EN\">\n"
    /** HTML 4.0 Strict Doctype */
    #define DOCTYPE_HTML_4_0S "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
                              "DTD HTML 4.0//EN\"\n" \
                              "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
    /** HTML 4.0 Transitional Doctype */
    #define DOCTYPE_HTML_4_0T "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
                              "DTD HTML 4.0 Transitional//EN\"\n" \
                              "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"
    /** HTML 4.0 Frameset Doctype */
    #define DOCTYPE_HTML_4_0F "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
                              "DTD HTML 4.0 Frameset//EN\"\n" \
                              "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n"
    /** XHTML 1.0 Strict Doctype */
    #define DOCTYPE_XHTML_1_0S "<!DOCTYPE html PUBLIC \"-//W3C//" \
                               "DTD XHTML 1.0 Strict//EN\"\n" \
                               "\"http://www.w3.org/TR/xhtml1/DTD/" \
                               "xhtml1-strict.dtd\">\n"
    /** XHTML 1.0 Transitional Doctype */
    #define DOCTYPE_XHTML_1_0T "<!DOCTYPE html PUBLIC \"-//W3C//" \
                               "DTD XHTML 1.0 Transitional//EN\"\n" \
                               "\"http://www.w3.org/TR/xhtml1/DTD/" \
                               "xhtml1-transitional.dtd\">\n"
    /** XHTML 1.0 Frameset Doctype */
    #define DOCTYPE_XHTML_1_0F "<!DOCTYPE html PUBLIC \"-//W3C//" \
                               "DTD XHTML 1.0 Frameset//EN\"\n" \
                               "\"http://www.w3.org/TR/xhtml1/DTD/" \
                               "xhtml1-frameset.dtd\">"
    
    /** 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 length */
    #define MAX_STRING_LEN HUGE_STRING_LEN
    
    /** The length of a Huge string */
    #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 splitting sendfile into
     * multiple 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 */
    
    /**
     * MPM child process exit status values
     * The MPM parent process may check the status to see if special
     * error handling is required.
     */
    /** 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 accommodate 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 use functions marked AP_CORE_DECLARE
     */
    #ifndef AP_CORE_DECLARE
    # define AP_CORE_DECLARE        AP_DECLARE
    #endif
    
    /**
     * @internal
     * modules should not use functions marked AP_CORE_DECLARE_NONSTD
     */
    
    #ifndef AP_CORE_DECLARE_NONSTD
    # define AP_CORE_DECLARE_NONSTD AP_DECLARE_NONSTD
    #endif
    
    /**
     * @defgroup APACHE_APR_STATUS_T HTTPD specific values of apr_status_t
     * @{
     */
    #define AP_START_USERERR            (APR_OS_START_USERERR + 2000)
    #define AP_USERERR_LEN              1000
    
    /** The function declines to handle the request */
    #define AP_DECLINED                 (AP_START_USERERR + 0)
    
    /** @} */
    
    /**
     * @brief 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 banner in a form suitable for sending over the
     * network, with the level of information controlled by the
     * ServerTokens directive.
     * @return The server banner
     */
    AP_DECLARE(const char *) ap_get_server_banner(void);
    
    /**
     * Get the server description in a form suitable for local displays,
     * status reports, or logging.  This includes the detailed server
     * version and information about some modules.  It is not affected
     * by the ServerTokens directive.
     * @return The server description
     */
    AP_DECLARE(const char *) ap_get_server_description(void);
    
    /**
     * Add a component to the server description and banner strings
     * @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);
    
    /* non-HTTP status codes returned by hooks */
    
    #define OK           0  /**< Module has handled this stage. */
    #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 SUSPENDED   -3  /**< Module will handle the remainder of the request.
                             *   The core will never invoke the request again */
    
    /** Returned by the bottom-most filter if no data was written.
     *  @see ap_pass_brigade(). */
    #define AP_NOBODY_WROTE         -100
    /** Returned by the bottom-most filter if no data was read.
     *  @see ap_get_brigade(). */
    #define AP_NOBODY_READ          -101
    /** Returned by any filter if the filter chain encounters an error
     *  and has already dealt with the error response.
     */
    #define AP_FILTER_ERROR         -102
    
    /**
     * @defgroup HTTP_Status HTTP Status Codes
     * @{
     */
    /**
     * The size of the static status_lines array in http_protocol.c for
     * storing all of the potential response status-lines (a sparse table).
     * When adding a new code here add it to status_lines as well.
     * A future version should dynamically generate the apr_table_t at startup.
     */
    #define RESPONSE_CODES 103
    
    #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_ALREADY_REPORTED                208
    #define HTTP_IM_USED                         226
    #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_PERMANENT_REDIRECT              308
    #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_MISDIRECTED_REQUEST             421
    #define HTTP_UNPROCESSABLE_ENTITY            422
    #define HTTP_LOCKED                          423
    #define HTTP_FAILED_DEPENDENCY               424
    #define HTTP_UPGRADE_REQUIRED                426
    #define HTTP_PRECONDITION_REQUIRED           428
    #define HTTP_TOO_MANY_REQUESTS               429
    #define HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE 431
    #define HTTP_UNAVAILABLE_FOR_LEGAL_REASONS   451
    #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_LOOP_DETECTED                   508
    #define HTTP_NOT_EXTENDED                    510
    #define HTTP_NETWORK_AUTHENTICATION_REQUIRED 511
    
    /** 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))
    /** is the status code a (potentially) valid response code?  */
    #define ap_is_HTTP_VALID_RESPONSE(x) (((x) >= 100)&&((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))
    
    /** does the status imply header only response (i.e. never w/ a body)? */
    #define AP_STATUS_IS_HEADER_ONLY(x) ((x) == HTTP_NO_CONTENT || \
                                         (x) == HTTP_NOT_MODIFIED)
    /** @} */
    
    /**
     * @defgroup Methods List of Methods recognized by the server
     * @ingroup APACHE_CORE_DAEMON
     * @{
     *
     * @brief 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       /** RFC 5789: PATCH Method for HTTP */
    #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      /** no valid method */
    
    /**
     * 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)
    /** @} */
    
    
    /** @see ap_method_list_t */
    typedef struct ap_method_list_t ap_method_list_t;
    
    /**
     * @struct ap_method_list_t
     * @brief  Structure for handling HTTP methods.
     *
     * Methods known to the server are accessed via a bitmask shortcut;
     * extension methods are handled by an array.
     */
    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 bnotes Binary notes recognized by the server
     * @ingroup APACHE_CORE_DAEMON
     * @{
     *
     * @brief Binary notes recognized by the server.
     */
    
    /**
     * The type used for request binary notes.
     */
    typedef apr_uint64_t ap_request_bnotes_t;
    
    /**
     * These constants represent bitmasks for notes associated with this
     * request. There are space for 64 bits in the apr_uint64_t.
     *
     */
    #define AP_REQUEST_STRONG_ETAG 1 >> 0
    #define AP_REQUEST_TRUSTED_CT  1 << 1
    
    /**
     * This is a convenience macro to ease with getting specific request
     * binary notes.
     */
    #define AP_REQUEST_GET_BNOTE(r, mask) \
        ((mask) & ((r)->bnotes))
    
    /**
     * This is a convenience macro to ease with setting specific request
     * binary notes.
     */
    #define AP_REQUEST_SET_BNOTE(r, mask, val) \
        (r)->bnotes = (((r)->bnotes & ~(mask)) | (val))
    
    /**
     * Returns true if the strong etag flag is set for this request.
     */
    #define AP_REQUEST_IS_STRONG_ETAG(r) \
            AP_REQUEST_GET_BNOTE((r), AP_REQUEST_STRONG_ETAG)
    /** @} */
    
    /**
     * Returns true if the content-type field is from a trusted source
     */
    #define AP_REQUEST_IS_TRUSTED_CT(r) \
        (!!AP_REQUEST_GET_BNOTE((r), AP_REQUEST_TRUSTED_CT))
    /** @} */
    
    /**
     * @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"
    /** Default for r->handler if no content-type set by type_checker */
    #define AP_DEFAULT_HANDLER_NAME ""
    #define AP_IS_DEFAULT_HANDLER_NAME(x) (*x == '\0')
    
    /** @} */
    /* Just in case your linefeed isn't the one the other end is expecting. */
    #if !APR_CHARSET_EBCDIC
    /** linefeed */
    #define LF 10
    /** carriage return */
    #define CR 13
    /** carriage 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 */
    /** Useful for common code with either platform charset. */
    #define CRLF_ASCII "\015\012"
    
    /**
     * @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
    /** @} // values_request_rec_body */
    
    /**
     * @defgroup values_request_rec_used_path_info Possible values for request_rec.used_path_info
     * @ingroup APACHE_CORE_DAEMON
     * @{
     * 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
    
    /** @} // values_request_rec_used_path_info */
    
    
    /*
     * 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 have 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.
     */
    
    /**
     * @brief 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;
        /** Table of allowed directives for override */
        apr_table_t *override_list;
        /** 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"
    
    /**
     * @brief 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;
        /** The program name used to execute the program */
        const char *short_name;
        /** The command line arguments */
        const char * const *argv;
        /** Number of command line arguments passed to the program */
        int argc;
    };
    
    /**
     * @brief 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 version number of protocol; 1.1 = 1001 */
        int proto_num;
        /** Protocol string, as given to us, or HTTP/0.9 */
        char *protocol;
        /** Host, as set by full URI or Host: header.
         *  For literal IPv6 addresses, this does NOT include the surrounding [ ]
         */
        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.
         */
    
        /** M_GET, M_POST, etc. */
        int method_number;
        /** Request method (eg. GET, HEAD, POST, etc.) */
        const char *method;
    
        /**
         *  '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 */
    
        /** The Range: header */
        const char *range;
        /** The "real" content length */
        apr_off_t clength;
        /** sending chunked transfer-coding */
        int chunked;
    
        /** 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;
        /** The optional kept body of the request. */
        apr_bucket_brigade *kept_body;
        /** For ap_body_to_table(): parsed body */
        /* XXX: ap_body_to_table has been removed. Remove body_table too or
         * XXX: keep it to reintroduce ap_body_to_table without major bump? */
        apr_table_t *body_table;
        /** 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;
    
        /* 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;
    
        /* 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, or "/" if no path provided */
        char *uri;
        /** The filename on disk corresponding to this response */
        char *filename;
        /** The true filename stored in the filesystem, as in the true alpha case
         *  and alias correction, e.g. "Image.jpeg" not "IMAGE$1.JPE" on Windows.
         *  The core map_to_storage canonicalizes r->filename when they mismatch */
        char *canonical_filename;
        /** The PATH_INFO extracted from this request */
        char *path_info;
        /** The QUERY_ARGS extracted from this request */
        char *args;
    
        /**
         * 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;
    
        /** A flag to determine if the eos bucket has been sent yet */
        int eos_sent;
    
        /* 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;
    
        /** Optional request log level configuration. Will usually point
         *  to a server or per_dir config, i.e. must be copied before
         *  modifying */
        const struct ap_logconf *log;
    
        /** Id to identify request in access and error log. Set when the first
         *  error log entry for this request is generated.
         */
        const char *log_id;
    
        /**
         * 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;
    
        /** This response can not be cached */
        int no_cache;
        /** There is no local copy of this response */
        int no_local_copy;
    
        /** Mutex protect callbacks registered with ap_mpm_register_timed_callback
         * from being run before the original handler finishes running
         */
        apr_thread_mutex_t *invoke_mtx;
    
        /** A struct containing the components of URI */
        apr_uri_t parsed_uri;
        /**  finfo.protection (st_mode) set to zero if no such file */
        apr_finfo_t finfo;
    
        /** remote address information from conn_rec, can be overridden if
         * necessary by a module.
         * This is the address that originated the request.
         */
        apr_sockaddr_t *useragent_addr;
        char *useragent_ip;
    
        /** MIME trailer environment from the request */
        apr_table_t *trailers_in;
        /** MIME trailer environment from the response */
        apr_table_t *trailers_out;
    
        /** Originator'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
         *  ap_get_useragent_host() */
        char *useragent_host;
        /** have we done double-reverse DNS? -1 yes/failure, 0 not yet,
         *  1 yes/success
         */
        int double_reverse;
        /** Request flags associated with this request. Use
         * AP_REQUEST_GET_BNOTE() and AP_REQUEST_SET_BNOTE() to access
         * the elements of this field.
         */
        ap_request_bnotes_t bnotes;
    };
    
    /**
     * @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 */
    
    /* @} */
    
    /**
     * @brief Enumeration of connection keepalive options
     */
    typedef enum {
        AP_CONN_UNKNOWN,
        AP_CONN_CLOSE,
        AP_CONN_KEEPALIVE
    } ap_conn_keepalive_e;
    
    /**
     * @brief 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; this is the end-point of the next hop, for the address
         *  of the request creator, see useragent_addr in request_rec
         */
        apr_sockaddr_t *client_addr;
    
        /** Client's IP address; this is the end-point of the next hop, for the
         *  IP of the request creator, see useragent_ip in request_rec
         */
        char *client_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;
    
        /** 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; may be NULL if not used by MPM */
        conn_state_t *cs;
        /** Is there data pending in the input filters? */
        int data_in_input_filters;
        /** Is there data pending in the output filters? */
        int data_in_output_filters;
    
        /** Are there any filters that clogg/buffer the input stream, breaking
         *  the event mpm.
         */
        unsigned int clogging_input_filters:1;
    
        /** have we done double-reverse DNS? -1 yes/failure, 0 not yet,
         *  1 yes/success */
        signed int double_reverse:2;
    
        /** Are we still talking? */
        unsigned aborted;
    
        /** Are we going to keep the connection alive for another request?
         * @see ap_conn_keepalive_e */
        ap_conn_keepalive_e keepalive;
    
        /** How many times have we used it? */
        int keepalives;
    
        /** Optional connection log level configuration. May point to a server or
         *  per_dir config, i.e. must be copied before modifying */
        const struct ap_logconf *log;
    
        /** Id to identify this connection in error log. Set when the first
         *  error log entry for this connection is generated.
         */
        const char *log_id;
    
    
        /** This points to the current thread being used to process this request,
         * over the lifetime of a request, the value may change. Users of the connection
         * record should not rely upon it staying the same between calls that involve
         * the MPM.
         */
    #if APR_HAS_THREADS
        apr_thread_t *current_thread;
    #endif
    
        /** The "real" master connection. NULL if I am the master. */
        conn_rec *master;
    
        int outgoing;
    };
    
    /**
     * Enumeration of connection states
     * The two states CONN_STATE_LINGER_NORMAL and CONN_STATE_LINGER_SHORT may
     * only be set by the MPM. Use CONN_STATE_LINGER outside of the MPM.
     */
    typedef enum  {
        CONN_STATE_KEEPALIVE,           /* Kept alive in the MPM (using KeepAliveTimeout) */
        CONN_STATE_PROCESSING,          /* Processed by process_connection hooks */
        CONN_STATE_HANDLER,             /* Processed by the modules handlers */
        CONN_STATE_WRITE_COMPLETION,    /* Flushed by the MPM before entering CONN_STATE_KEEPALIVE */
        CONN_STATE_SUSPENDED,           /* Suspended in the MPM until ap_run_resume_suspended() */
        CONN_STATE_LINGER,              /* MPM flushes then closes the connection with lingering */
        CONN_STATE_LINGER_NORMAL,       /* MPM has started lingering close with normal timeout */
        CONN_STATE_LINGER_SHORT,        /* MPM has started lingering close with short timeout */
    
        CONN_STATE_ASYNC_WAITIO,        /* Returning this state to the MPM will make it wait for
                                         * the connection to be readable or writable according to
                                         * c->cs->sense (resp. CONN_SENSE_WANT_READ or _WRITE),
                                         * using the configured Timeout */
    
        CONN_STATE_NUM,                 /* Number of states (keep here before aliases) */
    
        /* Aliases (legacy) */
        CONN_STATE_CHECK_REQUEST_LINE_READABLE  = CONN_STATE_KEEPALIVE,
        CONN_STATE_READ_REQUEST_LINE            = CONN_STATE_PROCESSING,
    } conn_state_e;
    
    typedef enum  {
        CONN_SENSE_DEFAULT,
        CONN_SENSE_WANT_READ,       /* next event must be read */
        CONN_SENSE_WANT_WRITE       /* next event must be write */
    } conn_sense_e;
    
    /**
     * @brief A structure to contain connection state information
     */
    struct conn_state_t {
        /** Current state of the connection */
        conn_state_e state;
        /** Whether to read instead of write, or write instead of read */
        conn_sense_e sense;
    };
    
    /* 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
    
    
    /**
     * @struct server_addr_rec
     * @brief  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 name given in "<VirtualHost>" */
        char *virthost;
        /** The bound address, for this server */
        apr_sockaddr_t *host_addr;
        /** The bound port, for this server */
        apr_port_t host_port;
    };
    
    struct ap_logconf {
        /** The per-module log levels */
        signed char *module_levels;
    
        /** The log level for this server */
        int level;
    };
    /**
     * @brief 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;
    
        /* 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 configuration */
        struct ap_logconf log;
    
        /* Module-specific configuration for server, and defaults... */
    
        /** 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;
    
        /** The path to the config file that the server was defined in */
        const char *defn_name;
        /** The line of the config file that the server was defined on */
        unsigned defn_line_number;
        /** true if this is the virtual server */
        char is_virtual;
    
    
        /* Information for redirects */
    
        /** for redirects, etc. */
        apr_port_t port;
        /** The server request scheme for redirect responses */
        const char *server_scheme;
    
        /* Contact information */
    
        /** The admin's contact information */
        char *server_admin;
        /** The server hostname */
        char *server_hostname;
    
        /* 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;
    
        /** Normal names for ServerAlias servers */
        apr_array_header_t *names;
        /** Wildcarded names for ServerAlias servers */
        apr_array_header_t *wild_names;
    
        /** Pathname for ServerPath */
        const char *path;
        /** Length of path */
        int pathlen;
    
        /** 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;
    
        /** Opaque storage location */
        void *context;
    
        /** Whether the keepalive timeout is explicit (1) or
         *  inherited (0) from the base server (either first
         *  server on the same IP:port or main server) */
        unsigned int keep_alive_timeout_set:1;
    };
    
    /**
     * @struct ap_sload_t
     * @brief  A structure to hold server load params
     */
    typedef struct ap_sload_t ap_sload_t;
    struct ap_sload_t {
        /* percentage of process/threads ready/idle (0->100)*/
        int idle;
        /* percentage of process/threads busy (0->100) */
        int busy;
        /* total bytes served */
        apr_off_t bytes_served;
        /* total access count */
        unsigned long access_count;
    };
    
    /**
     * @struct ap_loadavg_t
     * @brief  A structure to hold various server loadavg
     */
    typedef struct ap_loadavg_t ap_loadavg_t;
    struct ap_loadavg_t {
        /* current loadavg, ala getloadavg() */
        float loadavg;
        /* 5 min loadavg */
        float loadavg5;
        /* 15 min loadavg */
        float loadavg15;
    };
    
    /**
     * Get the context_document_root for a request. This is a generalization of
     * the document root, which is too limited in the presence of mappers like
     * mod_userdir and mod_alias. The context_document_root is the directory
     * on disk that maps to the context_prefix URI prefix.
     * @param r The request
     * @note For resources that do not map to the file system or for very complex
     * mappings, this information may still be wrong.
     */
    AP_DECLARE(const char *) ap_context_document_root(request_rec *r);
    
    /**
     * Get the context_prefix for a request. The context_prefix URI prefix
     * maps to the context_document_root on disk.
     * @param r The request
     */
    AP_DECLARE(const char *) ap_context_prefix(request_rec *r);
    
    /** Set context_prefix and context_document_root for a request.
     * @param r The request
     * @param prefix the URI prefix, without trailing slash
     * @param document_root the corresponding directory on disk, without trailing
     * slash
     * @note If one of prefix of document_root is NULL, the corrsponding
     * property will not be changed.
     */
    AP_DECLARE(void) ap_set_context_info(request_rec *r, const char *prefix,
                                         const char *document_root);
    
    /** Set per-request document root. This is for mass virtual hosting modules
     * that want to provide the correct DOCUMENT_ROOT value to scripts.
     * @param r The request
     * @param document_root the document root for the request.
     */
    AP_DECLARE(void) ap_set_document_root(request_rec *r, const char *document_root);
    
    /**
     * 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 occurrence 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 occurrence 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 occurrence 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 characters after the first occurrence 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 occurrence 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 characters after the first occurrence 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);
    
    /**
     * Get the second word in the string paying attention to quoting,
     * with {...} supported as well as "..." and '...'
     * @param p The pool to allocate from
     * @param line The line to traverse
     * @return A copy of the string
     */
    AP_DECLARE(char *) ap_getword_conf2(apr_pool_t *p, const char **line);
    
    /**
     * Get the second word in the string paying attention to quoting,
     * with {...} supported as well as "..." and '...'
     * @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_conf2(), except it doesn't use const char **.
     */
    AP_DECLARE(char *) ap_getword_conf2_nc(apr_pool_t *p, char **line);
    
    /**
     * Check a string for any config define or environment variable construct
     * and replace each of them by the value of that variable, if it exists.
     * The default syntax of the constructs is ${ENV} but can be changed by
     * setting the define::* config defines. If the variable does not exist,
     * leave the ${ENV} construct alone but print a warning.
     * @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);
    
    /**
     * Do a weak ETag comparison 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_etag_weak(apr_pool_t *p, const char *line, const char *tok);
    
    /**
     * Do a strong ETag comparison 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_etag_strong(apr_pool_t *p, const char *line, const char *tok);
    
    /* Scan a string for field content chars, as defined by RFC7230 section 3.2
     * including VCHAR/obs-text, as well as HT and SP
     * @param ptr The string to scan
     * @return A pointer to the first (non-HT) ASCII ctrl character.
     * @note lws and trailing whitespace are scanned, the caller is responsible
     * for trimming leading and trailing whitespace
     */
    AP_DECLARE(const char *) ap_scan_http_field_content(const char *ptr);
    
    /* Scan a string for token characters, as defined by RFC7230 section 3.2.6 
     * @param ptr The string to scan
     * @return A pointer to the first non-token character.
     */
    AP_DECLARE(const char *) ap_scan_http_token(const char *ptr);
    
    /* Scan a string for visible ASCII (0x21-0x7E) or obstext (0x80+)
     * and return a pointer to the first SP/CTL/NUL character encountered.
     * @param ptr The string to scan
     * @return A pointer to the first SP/CTL character.
     */
    AP_DECLARE(const char *) ap_scan_vchar_obstext(const char *ptr);
    
    /**
     * Retrieve an array of tokens in the format "1#token" defined in RFC2616. Only
     * accepts ',' as a delimiter, does not accept quoted strings, and errors on
     * any separator.
     * @param p The pool to allocate from
     * @param tok The line to read tokens from
     * @param tokens Pointer to an array of tokens. If not NULL, must be an array
     *    of char*, otherwise it will be allocated on @a p when a token is found
     * @param skip_invalid If true, when an invalid separator is encountered, it
     *    will be ignored.
     * @return NULL on success, an error string otherwise.
     * @remark *tokens may be NULL on output if NULL in input and no token is found
     */
    AP_DECLARE(const char *) ap_parse_token_list_strict(apr_pool_t *p, const char *tok,
                                                        apr_array_header_t **tokens,
                                                        int skip_invalid);
    
    /**
     * 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 string
     * @param url The string to unescape
     * @return 0 on success, non-zero otherwise
     */
    AP_DECLARE(int) ap_unescape_all(char *url);
    
    /**
     * 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
     * @param decode_slashes Whether or not slashes should be decoded
     * @return 0 on success, non-zero otherwise
     */
    AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes);
    
    #define AP_UNESCAPE_URL_KEEP_UNRESERVED (1u << 0)
    #define AP_UNESCAPE_URL_FORBID_SLASHES  (1u << 1)
    #define AP_UNESCAPE_URL_KEEP_SLASHES    (1u << 2)
    
    /**
     * Unescape a URL, with options
     * @param url The url to unescape
     * @param flags Bitmask of AP_UNESCAPE_URL_* flags
     * @return 0 on success, non-zero otherwise
     */
    AP_DECLARE(int) ap_unescape_url_ex(char *url, unsigned int flags);
    
    /**
     * Unescape an application/x-www-form-urlencoded string
     * @param query The query to unescape
     * @return 0 on success, non-zero otherwise
     */
    AP_DECLARE(int) ap_unescape_urlencoded(char *query);
    
    /**
     * Convert all double slashes to single slashes, except where significant
     * to the filesystem on the current platform.
     * @param name The string to convert, assumed to be a filesystem path
     */
    AP_DECLARE(void) ap_no2slash(char *name);
    
    /**
     * Convert all double slashes to single slashes, except where significant
     * to the filesystem on the current platform.
     * @param name The string to convert
     * @param is_fs_path if set to 0, the significance of any double-slashes is 
     *        ignored.
     */
    AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path);
    
    #define AP_NORMALIZE_ALLOW_RELATIVE     (1u <<  0)
    #define AP_NORMALIZE_NOT_ABOVE_ROOT     (1u <<  1)
    #define AP_NORMALIZE_DECODE_UNRESERVED  (1u <<  2)
    #define AP_NORMALIZE_MERGE_SLASHES      (1u <<  3)
    #define AP_NORMALIZE_DROP_PARAMETERS    (0) /* deprecated */
    
    /**
     * Remove all ////, /./ and /xx/../ substrings from a path, and more
     * depending on passed in flags.
     * @param path The path to normalize
     * @param flags bitmask of AP_NORMALIZE_* flags
     * @return non-zero on success
     */
    AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags);
    
    /**
     * 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);
    
    /**
     * Escape a path segment, as defined in RFC 1808, to a preallocated buffer.
     * @param c The preallocated buffer to write to
     * @param s The path to convert
     * @return The converted URL (c)
     */
    AP_DECLARE(char *) ap_escape_path_segment_buffer(char *c, const char *s);
    
    /**
     * convert an OS path to a URL in an OS dependent 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 a string as application/x-www-form-urlencoded
     * @param p The pool to allocate from
     * @param s The path to convert
     * @return The converted URL
     */
    AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *s);
    
    /**
     * Escape a string as application/x-www-form-urlencoded, to a preallocated buffer
     * @param c The preallocated buffer to write to
     * @param s The path to convert
     * @return The converted URL (c)
     */
    AP_DECLARE(char *) ap_escape_urlencoded_buffer(char *c, const char *s);
    
    /**
     * Escape an html string
     * @param p The pool to allocate from
     * @param s The html to escape
     * @return The escaped string
     */
    #define ap_escape_html(p,s) ap_escape_html2(p,s,0)
    /**
     * Escape an html string
     * @param p The pool to allocate from
     * @param s The html to escape
     * @param toasc Whether to escape all non-ASCII chars to \&\#nnn;
     * @return The escaped string
     */
    AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc);
    
    /**
     * 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 single '/' 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
     * @note 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 absolute path.
     * @param p The pool to allocate from
     * @param dir The directory name
     * @note 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 pattern containing the wildcards '?' or '*'
     * @param str The string to check
     * @param expected The pattern to match against
     * @return 0 if the two strings match, 1 otherwise
     */
    AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected);
    
    /**
     * Determine if a string matches a pattern containing the wildcards '?' or '*',
     * ignoring case
     * @param str The string to check
     * @param expected The pattern to match against
     * @return 0 if the two strings match, 1 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 string 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. The regex is freed when
     * the pool is destroyed.
     * @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
     * @note This function is only necessary if the regex should be cleaned
     * up before the pool
     */
    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. This function is limited to
     * result strings of 64K. Consider using ap_pregsub_ex() instead.
     * @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
     * @return The substituted string, or NULL on error
     */
    AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input,
                                  const char *source, apr_size_t nmatch,
                                  ap_regmatch_t pmatch[]);
    
    /**
     * 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 result where to store the result, will be set to NULL on error
     * @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
     * @param maxlen the maximum string length to return, 0 for unlimited
     * @return APR_SUCCESS if successful, APR_ENOMEM or other error code otherwise.
     */
    AP_DECLARE(apr_status_t) ap_pregsub_ex(apr_pool_t *p, char **result,
                                           const char *input, const char *source,
                                           apr_size_t nmatch,
                                           ap_regmatch_t pmatch[],
                                           apr_size_t maxlen);
    
    /**
     * 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);
    
    /**
     * convert a string to all uppercase
     * @param s The string to convert to uppercase
     */
    AP_DECLARE(void) ap_str_toupper(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 &quot; with \\&quot; .
     * @param p The pool to allocate memory from
     * @param instring The string to search for &quot;
     * @return A copy of the string with escaped quotes
     */
    AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring);
    
    /**
     * Given a string, append the PID deliminated by delim.
     * Usually used to create a pid-appended filepath name
     * (eg: /a/b/foo -> /a/b/foo.6726). A function, and not
     * a macro, to avoid unistd.h dependency
     * @param p The pool to allocate memory from
     * @param string The string to append the PID to
     * @param delim The string to use to deliminate the string from the PID
     * @return A copy of the string with the PID appended
     */
    AP_DECLARE(char *) ap_append_pid(apr_pool_t *p, const char *string,
                                     const char *delim);
    
    /**
     * Parse a length string with decimal characters only, no leading sign nor
     * trailing character, like Content-Length or (Content-)Range headers.
     * @param len The parsed length (apr_off_t)
     * @param str The string to parse
     * @return 1 (success), 0 (failure)
     */
    AP_DECLARE(int) ap_parse_strict_length(apr_off_t *len, const char *str);
    
    /**
     * Parse a given timeout parameter string into an apr_interval_time_t value.
     * The unit of the time interval is given as postfix string to the numeric
     * string. Currently the following units are understood:
     *
     * ms    : milliseconds
     * s     : seconds
     * mi[n] : minutes
     * h     : hours
     *
     * If no unit is contained in the given timeout parameter the default_time_unit
     * will be used instead.
     * @param timeout_parameter The string containing the timeout parameter.
     * @param timeout The timeout value to be returned.
     * @param default_time_unit The default time unit to use if none is specified
     * in timeout_parameter.
     * @return Status value indicating whether the parsing was successful or not.
     */
    AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
                                                   const char *timeout_parameter,
                                                   apr_interval_time_t *timeout,
                                                   const char *default_time_unit);
    
    /**
     * Determine if a request has a request body or not.
     *
     * @param r the request_rec of the request
     * @return truth value
     */
    AP_DECLARE(int) ap_request_has_body(request_rec *r);
    
    /**
     * Cleanup a string (mainly to be filesystem safe)
     * We only allow '_' and alphanumeric chars. Non-printable
     * map to 'x' and all others map to '_'
     *
     * @param  p pool to use to allocate dest
     * @param  src string to clean up
     * @param  dest cleaned up, allocated string
     * @return Status value indicating whether the cleaning was successful or not.
     */
    AP_DECLARE(apr_status_t) ap_pstr2_alnum(apr_pool_t *p, const char *src,
                                            const char **dest);
    
    /**
     * Cleanup a string (mainly to be filesystem safe)
     * We only allow '_' and alphanumeric chars. Non-printable
     * map to 'x' and all others map to '_'
     *
     * @param  src string to clean up
     * @param  dest cleaned up, pre-allocated string
     * @return Status value indicating whether the cleaning was successful or not.
     */
    AP_DECLARE(apr_status_t) ap_str2_alnum(const char *src, char *dest);
    
    /**
     * Structure to store the contents of an HTTP form of the type
     * application/x-www-form-urlencoded.
     *
     * Currently it contains the name as a char* of maximum length
     * HUGE_STRING_LEN, and a value in the form of a bucket brigade
     * of arbitrary length.
     */
    typedef struct {
        const char *name;
        apr_bucket_brigade *value;
    } ap_form_pair_t;
    
    /**
     * Read the body and parse any form found, which must be of the
     * type application/x-www-form-urlencoded.
     * @param r request containing POSTed form data
     * @param f filter
     * @param ptr returned array of ap_form_pair_t
     * @param num max num of params or -1 for unlimited
     * @param size max size allowed for parsed data
     * @return OK or HTTP error
     */
    AP_DECLARE(int) ap_parse_form_data(request_rec *r, struct ap_filter_t *f,
                                       apr_array_header_t **ptr,
                                       apr_size_t num, apr_size_t size);
    
    /* 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 Internal Assert function
     */
    #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 server 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);
    
      /* 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 <string.h>
    
    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
    
    /**
     * Generate pseudo random bytes.
     * This is a convenience interface to apr_random. It is cheaper but less
     * secure than apr_generate_random_bytes().
     * @param buf where to store the bytes
     * @param size number of bytes to generate
     * @note ap_random_insecure_bytes() is thread-safe, it uses a mutex on
     *       threaded MPMs.
     */
    AP_DECLARE(void) ap_random_insecure_bytes(void *buf, apr_size_t size);
    
    /**
     * Get a pseudo random number in a range.
     * @param min low end of range
     * @param max high end of range
     * @return a number in the range
     */
    AP_DECLARE(apr_uint32_t) ap_random_pick(apr_uint32_t min, apr_uint32_t max);
    
    /**
     * Abort with a error message signifying out of memory
     */
    AP_DECLARE(void) ap_abort_on_oom(void) __attribute__((noreturn));
    
    /**
     * Wrapper for malloc() that calls ap_abort_on_oom() if out of memory
     * @param size size of the memory block
     * @return pointer to the allocated memory
     * @note ap_malloc may be implemented as a macro
     */
    AP_DECLARE(void *) ap_malloc(size_t size)
                        __attribute__((malloc))
                        AP_FN_ATTR_ALLOC_SIZE(1);
    
    /**
     * Wrapper for calloc() that calls ap_abort_on_oom() if out of memory
     * @param nelem number of elements to allocate memory for
     * @param size size of a single element
     * @return pointer to the allocated memory
     * @note ap_calloc may be implemented as a macro
     */
    AP_DECLARE(void *) ap_calloc(size_t nelem, size_t size)
                       __attribute__((malloc))
                       AP_FN_ATTR_ALLOC_SIZE2(1,2);
    
    /**
     * Wrapper for realloc() that calls ap_abort_on_oom() if out of memory
     * @param ptr pointer to the old memory block (or NULL)
     * @param size new size of the memory block
     * @return pointer to the reallocated memory
     * @note ap_realloc may be implemented as a macro
     */
    AP_DECLARE(void *) ap_realloc(void *ptr, size_t size)
                       AP_FN_ATTR_WARN_UNUSED_RESULT
                       AP_FN_ATTR_ALLOC_SIZE(2);
    
    #if APR_HAS_THREADS
    
    #if APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL)
    
    /**
     * APR 1.8+ implement those already.
     */
    #if APR_HAS_THREAD_LOCAL
    #define AP_HAS_THREAD_LOCAL 1
    #define AP_THREAD_LOCAL     APR_THREAD_LOCAL
    #else
    #define AP_HAS_THREAD_LOCAL 0
    #endif
    #define ap_thread_create                apr_thread_create
    #define ap_thread_current               apr_thread_current
    #define ap_thread_current_create        apr_thread_current_create
    #define ap_thread_current_after_fork    apr_thread_current_after_fork
    
    #else /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */
    
    #ifndef AP_NO_THREAD_LOCAL
    /**
     * AP_THREAD_LOCAL keyword mapping the compiler's.
     */
    #if defined(__cplusplus) && __cplusplus >= 201103L
    #define AP_THREAD_LOCAL thread_local
    #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112 && \
          (!defined(__GNUC__) || \
          __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
    #define AP_THREAD_LOCAL _Thread_local
    #elif defined(__GNUC__) /* works for clang too */
    #define AP_THREAD_LOCAL __thread
    #elif defined(WIN32) && defined(_MSC_VER)
    #define AP_THREAD_LOCAL __declspec(thread)
    #endif
    #endif /* ndef AP_NO_THREAD_LOCAL */
    
    #ifndef AP_THREAD_LOCAL
    #define AP_HAS_THREAD_LOCAL 0
    #define ap_thread_create apr_thread_create
    #else /* AP_THREAD_LOCAL */
    #define AP_HAS_THREAD_LOCAL 1
    AP_DECLARE(apr_status_t) ap_thread_create(apr_thread_t **thread, 
                                              apr_threadattr_t *attr, 
                                              apr_thread_start_t func, 
                                              void *data, apr_pool_t *pool);
    #endif /* AP_THREAD_LOCAL */
    
    AP_DECLARE(apr_status_t) ap_thread_current_create(apr_thread_t **current,
                                                      apr_threadattr_t *attr,
                                                      apr_pool_t *pool);
    AP_DECLARE(void) ap_thread_current_after_fork(void);
    AP_DECLARE(apr_thread_t *) ap_thread_current(void);
    
    #endif /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */
    
    AP_DECLARE(apr_status_t) ap_thread_main_create(apr_thread_t **thread,
                                                   apr_pool_t *pool);
    
    #else  /* APR_HAS_THREADS */
    
    #define AP_HAS_THREAD_LOCAL 0
    
    #endif /* APR_HAS_THREADS */
    
    /**
     * Get server load params
     * @param ld struct to populate: -1 in fields means error
     */
    AP_DECLARE(void) ap_get_sload(ap_sload_t *ld);
    
    /**
     * Get server load averages (ala getloadavg)
     * @param ld struct to populate: -1 in fields means error
     */
    AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld);
    
    /**
     * Convert binary data into a hex string
     * @param src pointer to the data
     * @param srclen length of the data
     * @param dest pointer to buffer of length (2 * srclen + 1). The resulting
     *        string will be NUL-terminated.
     */
    AP_DECLARE(void) ap_bin2hex(const void *src, apr_size_t srclen, char *dest);
    
    /**
     * Short function to execute a command and return the first line of
     * output minus \\r \\n. Useful for "obscuring" passwords via exec calls
     * @param p the pool to allocate from
     * @param cmd the command to execute
     * @param argv the arguments to pass to the cmd
     * @return ptr to characters or NULL on any error
     */
    AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p,
                                        const char *cmd,
                                        const char * const *argv);
    
    #define AP_NORESTART APR_OS_START_USEERR + 1
    
    /**
     * Get the first index of the string in the array or -1 if not found. Start
     * searching a start. 
     * @param array The array the check
     * @param s The string to find
     * @param start Start index for search. If start is out of bounds (negative or  
                    equal to array length or greater), -1 will be returned.
     * @return index of string in array or -1
     */
    AP_DECLARE(int) ap_array_str_index(const apr_array_header_t *array, 
                                       const char *s,
                                       int start);
    
    /**
     * Check if the string is member of the given array by strcmp.
     * @param array The array the check
     * @param s The string to find
     * @return !=0 iff string is member of array (via strcmp)
     */
    AP_DECLARE(int) ap_array_str_contains(const apr_array_header_t *array, 
                                          const char *s);
    
    /**
     * Perform a case-insensitive comparison of two strings @a str1 and @a str2,
     * treating upper and lower case values of the 26 standard C/POSIX alphabetic
     * characters as equivalent. Extended latin characters outside of this set
     * are treated as unique octets, irrespective of the current locale.
     *
     * Returns in integer greater than, equal to, or less than 0,
     * according to whether @a str1 is considered greater than, equal to,
     * or less than @a str2.
     *
     * @note Same code as apr_cstr_casecmp, which arrives in APR 1.6
     */
    AP_DECLARE(int) ap_cstr_casecmp(const char *s1, const char *s2);
    
    /**
     * Perform a case-insensitive comparison of two strings @a str1 and @a str2,
     * treating upper and lower case values of the 26 standard C/POSIX alphabetic
     * characters as equivalent. Extended latin characters outside of this set
     * are treated as unique octets, irrespective of the current locale.
     *
     * Returns in integer greater than, equal to, or less than 0,
     * according to whether @a str1 is considered greater than, equal to,
     * or less than @a str2.
     *
     * @note Same code as apr_cstr_casecmpn, which arrives in APR 1.6
     */
    AP_DECLARE(int) ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n);
    
    /**
     * Default flags for ap_dir_*fnmatch().
     */
    #define AP_DIR_FLAG_NONE      0
    
    /**
     * If set, wildcards that match no files or directories will be ignored, otherwise
     * an error is triggered.
     */
    #define AP_DIR_FLAG_OPTIONAL  1
    
    /**
     * If set, and the wildcard resolves to a directory, recursively find all files
     * below that directory, otherwise return the directory.
     */
    #define AP_DIR_FLAG_RECURSIVE 2
    
    /**
     * Structure to provide the state of a directory match.
     */
    typedef struct ap_dir_match_t ap_dir_match_t;
    
    /**
     * Concrete structure to provide the state of a directory match.
     */
    struct ap_dir_match_t {
        /** Pool to use for allocating the result */
        apr_pool_t *p;
        /** Temporary pool used for directory traversal */
        apr_pool_t *ptemp;
        /** Prefix for log messages */
        const char *prefix;
        /** Callback for each file found that matches the wildcard. Return NULL on success, an error string on error. */
        const char *(*cb)(ap_dir_match_t *w, const char *fname);
        /** Context for the callback */
        void *ctx;
        /** Flags to indicate whether optional or recursive */
        int flags;
        /** Recursion depth safety check */
        unsigned int depth;
    };
    
    /**
     * Search for files given a non wildcard filename with non native separators.
     *
     * If the provided filename points at a file, the callback within ap_dir_match_t is
     * triggered for that file, and this function returns the result of the callback.
     *
     * If the provided filename points at a directory, and recursive within ap_dir_match_t
     * is true, the callback will be triggered for every file found recursively beneath
     * that directory, otherwise the callback is triggered once for the directory itself.
     * This function returns the result of the callback.
     *
     * If the provided path points to neither a file nor a directory, and optional within
     * ap_dir_match_t is true, this function returns NULL. If optional within ap_dir_match_t
     * is false, this function will return an error string indicating that the path does not
     * exist.
     *
     * @param w Directory match structure containing callback and context.
     * @param fname The name of the file or directory, with non native separators.
     * @return NULL on success, or a string describing the error.
     */
    AP_DECLARE(const char *)ap_dir_nofnmatch(ap_dir_match_t *w, const char *fname)
            __attribute__((nonnull(1,2)));
    
    /**
     * Search for files given a wildcard filename with non native separators.
     *
     * If the filename contains a wildcard, all files and directories that match the wildcard
     * will be returned.
     *
     * ap_dir_nofnmatch() is called for each directory and file found, and the callback
     * within ap_dir_match_t triggered as described above.
     *
     * Wildcards may appear in both directory and file components in the path, and
     * wildcards may appear more than once.
     *
     * @param w Directory match structure containing callback and context.
     * @param path Path prefix for search, with non native separators and no wildcards.
     * @param fname The name of the file or directory, with non native separators and
     * optional wildcards.
     * @return NULL on success, or a string describing the error.
     */
    AP_DECLARE(const char *)ap_dir_fnmatch(ap_dir_match_t *w, const char *path,
            const char *fname) __attribute__((nonnull(1,3)));
    
    /**
     * Determine if the final Transfer-Encoding is "chunked".
     *
     * @param p The pool to allocate from
     * @param line the header field-value to scan
     * @return 1 if the last Transfer-Encoding is "chunked", else 0
     */
    AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line);
    
    
    /**
     * apr_filepath_merge with an allow-list
     * Merge additional file path onto the previously processed rootpath
     * @param newpath the merged paths returned
     * @param rootpath the root file path (NULL uses the current working path)
     * @param addpath the path to add to the root path
     * @param flags the desired APR_FILEPATH_ rules to apply when merging
     * @param p the pool to allocate the new path string from
     * @remark if the flag APR_FILEPATH_TRUENAME is given, and the addpath
     * contains wildcard characters ('*', '?') on platforms that don't support
     * such characters within filenames, the paths will be merged, but the
     * result code will be APR_EPATHWILD, and all further segments will not
     * reflect the true filenames including the wildcard and following segments.
     */
    AP_DECLARE(apr_status_t) ap_filepath_merge(char **newpath,
                                                 const char *rootpath,
                                                 const char *addpath,
                                                 apr_int32_t flags,
                                                 apr_pool_t *p);
    
    #ifdef WIN32
    #define apr_filepath_merge  ap_filepath_merge
    #endif
    
    /* Win32/NetWare/OS2 need to check for both forward and back slashes
     * in ap_normalize_path() and ap_escape_url().
     */
    #ifdef CASE_BLIND_FILESYSTEM
    #define AP_IS_SLASH(s) ((s == '/') || (s == '\\'))
    #define AP_SLASHES "/\\"
    #else
    #define AP_IS_SLASH(s) (s == '/')
    #define AP_SLASHES "/"
    #endif
    
    /**
     * Validates the path parameter is safe to pass to stat-like calls.
     * @param path The filesystem path to cehck
     * @param p a pool for temporary allocations
     * @return APR_SUCCESS if the stat-like call should be allowed
     */
    AP_DECLARE(apr_status_t) ap_stat_check(const char *path, apr_pool_t *pool);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTPD_H */
    
    /** @} //APACHE Daemon      */
    /** @} //APACHE Core        */
    /** @} //APACHE super group */
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_mpm.h�����������������������������������������������������������������������0000664�0001751�0001751�00000025014�14651200711�015666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  ap_mpm.h
     * @brief Apache Multi-Processing Module library
     *
     * @defgroup APACHE_CORE_MPM Multi-Processing Module library
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef AP_MPM_H
    #define AP_MPM_H
    
    #include "apr_thread_proc.h"
    #include "httpd.h"
    #include "scoreboard.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /*
        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
    */
    
    /**
     * Pass control to the MPM for steady-state processing.  It 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 DONE for shutdown OK otherwise.
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int, mpm, (apr_pool_t *pconf, apr_pool_t *plog, server_rec *server_conf))
    
    /**
     * 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 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);
    
    /** @defgroup mpmq MPM query
     * @{
     */
    
    /** @defgroup thrdfrk Subtypes/Values returned for AP_MPMQ_IS_THREADED and AP_MPMQ_IS_FORKED
     *  @ingroup mpmq
     *  @{
     */
    #define AP_MPMQ_NOT_SUPPORTED      0  /**< This value specifies that an
                                           * MPM is not capable of
                                           * threading or forking.        */
    #define AP_MPMQ_STATIC             1  /**< This value specifies that
                                           * an MPM is using a static
                                           * number of threads or daemons */
    #define AP_MPMQ_DYNAMIC            2  /**< This value specifies that
                                           * an MPM is using a dynamic
                                           * number of threads or daemons */
    /** @} */
    
    /** @defgroup qstate Values returned for AP_MPMQ_MPM_STATE
     *  @ingroup mpmq
     *  @{
     */
    #define AP_MPMQ_STARTING              0
    #define AP_MPMQ_RUNNING               1
    #define AP_MPMQ_STOPPING              2
    /** @} */
    
    /** @defgroup qcodes Query codes for ap_mpm_query()
     *  @ingroup mpmq
     *  @{
     */
    /** Max # of daemons used so far */
    #define AP_MPMQ_MAX_DAEMON_USED       1
    /** MPM can do threading         */
    #define AP_MPMQ_IS_THREADED           2
    /** MPM can do forking           */
    #define AP_MPMQ_IS_FORKED             3
    /** The compiled max # daemons   */
    #define AP_MPMQ_HARD_LIMIT_DAEMONS    4
    /** The compiled max # threads   */
    #define AP_MPMQ_HARD_LIMIT_THREADS    5
    /** \# of threads/child by config */
    #define AP_MPMQ_MAX_THREADS           6
    /** Min # of spare daemons       */
    #define AP_MPMQ_MIN_SPARE_DAEMONS     7
    /** Min # of spare threads       */
    #define AP_MPMQ_MIN_SPARE_THREADS     8
    /** Max # of spare daemons       */
    #define AP_MPMQ_MAX_SPARE_DAEMONS     9
    /** Max # of spare threads       */
    #define AP_MPMQ_MAX_SPARE_THREADS    10
    /** Max # of requests per daemon */
    #define AP_MPMQ_MAX_REQUESTS_DAEMON  11
    /** Max # of daemons by config   */
    #define AP_MPMQ_MAX_DAEMONS          12
    /** starting, running, stopping  */
    #define AP_MPMQ_MPM_STATE            13
    /** MPM can process async connections  */
    #define AP_MPMQ_IS_ASYNC             14
    /** MPM generation */
    #define AP_MPMQ_GENERATION           15
    /** MPM can drive serf internally  */
    #define AP_MPMQ_HAS_SERF             16
    /* 17-18 are trunk only */
    /** MPM supports CONN_STATE_ASYNC_WAITIO */
    #define AP_MPMQ_CAN_WAITIO           19
    /** @} */
    
    /**
     * Query a property of the current MPM.
     * @param query_code One of AP_MPMQ_*
     * @param result A location to place the result of the query
     * @return APR_EGENERAL if an mpm-query hook has not been registered;
     * APR_SUCCESS or APR_ENOTIMPL otherwise
     * @remark The MPM doesn't register the implementing hook until the
     * register_hooks hook is called, so modules cannot use ap_mpm_query()
     * until after that point.
     * @fn int ap_mpm_query(int query_code, int *result)
     */
    AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result);
    
    /** @} */
    
    typedef void (ap_mpm_callback_fn_t)(void *baton);
    
    /* only added support in the Event MPM....  check for APR_ENOTIMPL */
    AP_DECLARE(apr_status_t) ap_mpm_register_timed_callback(apr_time_t t,
                                                           ap_mpm_callback_fn_t *cbfn,
                                                           void *baton);
    
    typedef enum mpm_child_status {
        MPM_CHILD_STARTED,
        MPM_CHILD_EXITED,
        MPM_CHILD_LOST_SLOT
    } mpm_child_status;
    
    /**
     * Allow a module to remain aware of MPM child process state changes,
     * along with the generation and scoreboard slot of the process changing
     * state.
     *
     * With some MPMs (event and worker), an active MPM child process may lose
     * its scoreboard slot if the child process is exiting and the scoreboard
     * slot is needed by other processes.  When this occurs, the hook will be
     * called with the MPM_CHILD_LOST_SLOT state.
     *
     * @param s The main server_rec.
     * @param pid The id of the MPM child process.
     * @param gen The server generation of that child process.
     * @param slot The scoreboard slot number, or -1.  It will be -1 when an
     * MPM child process exits, and that child had previously lost its
     * scoreboard slot.
     * @param state One of the mpm_child_status values.  Modules should ignore
     * unrecognized values.
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(void,child_status,(server_rec *s, pid_t pid, ap_generation_t gen,
                                       int slot, mpm_child_status state))
    
    /**
     * Allow a module to be notified when the last child process of a generation
     * exits.
     *
     * @param s The main server_rec.
     * @param gen The server generation which is now completely finished.
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(void,end_generation,(server_rec *s, ap_generation_t gen))
    
    /* 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
    
    #ifdef AP_ENABLE_EXCEPTION_HOOK
    typedef struct ap_exception_info_t {
        int sig;
        pid_t pid;
    } ap_exception_info_t;
    
    /**
     * Run the fatal_exception hook for each module; this hook is run
     * from some MPMs in the event of a child process crash, if the
     * server was built with --enable-exception-hook and the
     * EnableExceptionHook directive is On.
     * @param ei information about the exception
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int,fatal_exception,(ap_exception_info_t *ei))
    #endif /*AP_ENABLE_EXCEPTION_HOOK*/
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_regex.h���������������������������������������������������������������������0000664�0001751�0001751�00000026215�14207134173�016220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 code is based on pcreposix.h from the PCRE Library distribution,
     * as originally written by Philip Hazel <ph10@cam.ac.uk>, and forked by
     * the Apache HTTP Server project to provide POSIX-style regex function
     * wrappers around underlying PCRE library functions for httpd.
     * 
     * The original source file pcreposix.h is copyright and licensed as follows;
    
                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.
    -----------------------------------------------------------------------------
    */
    
    /**
     * @file ap_regex.h
     * @brief Apache Regex defines
     */
    
    #ifndef AP_REGEX_H
    #define AP_REGEX_H
    
    #include "apr.h"
    
    /* Allow for C++ users */
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* Options for ap_regcomp, ap_regexec, and ap_rxplus versions: */
    
    #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 */
    
    #define AP_REG_MULTI 0x10    /* perl's /g (needs fixing) */
    #define AP_REG_NOMEM 0x20    /* nomem in our code */
    #define AP_REG_DOTALL 0x40   /* perl's /s flag */
    
    #define AP_REG_DOLLAR_ENDONLY 0x200 /* '$' matches at end of subject string only */
    
    #define AP_REG_NO_DEFAULT 0x400 /**< Don't implicitely add AP_REG_DEFAULT options */
    
    #define AP_REG_MATCH "MATCH_" /**< suggested prefix for ap_regname */
    
    #define AP_REG_DEFAULT (AP_REG_DOTALL|AP_REG_DOLLAR_ENDONLY)
    
    /* Arguments for ap_pcre_version_string */
    enum {
      AP_REG_PCRE_COMPILED = 0, /** PCRE version used during program compilation */
      AP_REG_PCRE_LOADED        /** PCRE version loaded at runtime */
    };
    
    /* 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;
        int 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 */
    
    /**
     * Return PCRE version string.
     * @param which Either AP_REG_PCRE_COMPILED (PCRE version used
     *              during program compilation) or AP_REG_PCRE_LOADED
     *              (PCRE version used at runtime)
     * @return The PCRE version string
     */
    AP_DECLARE(const char *) ap_pcre_version_string(int which);
    
    /**
     * Get default compile flags
     * @return Bitwise OR of AP_REG_* flags
     */
    AP_DECLARE(int) ap_regcomp_get_default_cflags(void);
    
    /**
     * Set default compile flags
     * @param cflags Bitwise OR of AP_REG_* flags
     */
    AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags);
    
    /**
     * Get the AP_REG_* corresponding to the string.
     * @param name The name (i.e. AP_REG_<name>)
     * @return The AP_REG_*, or zero if the string is unknown
     *
     */
    AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name);
    
    /**
     * Compile a regular expression.
     * @param preg Returned compiled regex
     * @param regex The regular expression string
     * @param cflags Bitwise OR of AP_REG_* flags (ICASE and NEWLINE supported,
     *                                             other flags are ignored)
     * @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 AP_REG_* flags (NOTBOL and NOTEOL supported,
     *                                             other flags are ignored)
     * @return 0 for successful match, \p AP_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);
    
    /**
     * Match a string with given length against a pre-compiled regex. The string
     * does not need to be NUL-terminated.
     * @param preg The pre-compiled regex
     * @param buff The string to match
     * @param len Length of 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 AP_REG_* flags (NOTBOL and NOTEOL supported,
     *                                             other flags are ignored)
     * @return 0 for successful match, AP_REG_NOMATCH otherwise
     */
    AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
                                   apr_size_t len, 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);
    
    /**
     * Return an array of named regex backreferences
     * @param preg The precompiled regex
     * @param names The array to which the names will be added
     * @param prefix An optional prefix to add to the returned names.  AP_REG_MATCH
     * is the recommended prefix.
     * @param upper If non zero, uppercase the names
     */
    AP_DECLARE(int) ap_regname(const ap_regex_t *preg,
                               apr_array_header_t *names, const char *prefix,
                               int upper);
    
    /** Destroy a pre-compiled regex.
     * @param preg The pre-compiled regex to free.
     */
    AP_DECLARE(void) ap_regfree(ap_regex_t *preg);
    
    /* ap_rxplus: higher-level regexps */
    
    typedef struct {
        ap_regex_t rx;
        apr_uint32_t flags;
        const char *subs;
        const char *match;
        apr_size_t nmatch;
        ap_regmatch_t *pmatch;
    } ap_rxplus_t;
    
    /**
     * Compile a pattern into a regexp.
     * supports perl-like formats
     *    match-string
     *    /match-string/flags
     *    s/match-string/replacement-string/flags
     *    Intended to support more perl-like stuff as and when round tuits happen
     * match-string is anything supported by ap_regcomp
     * replacement-string is a substitution string as supported in ap_pregsub
     * flags should correspond with perl syntax: treat failure to do so as a bug
     *                                           (documentation TBD)
     * @param pool Pool to allocate from
     * @param pattern Pattern to compile
     * @return Compiled regexp, or NULL in case of compile/syntax error
     */
    AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool, const char *pattern);
    /**
     * Apply a regexp operation to a string.
     * @param pool Pool to allocate from
     * @param rx The regex match to apply
     * @param pattern The string to apply it to
     *                NOTE: This MUST be kept in scope to use regexp memory
     * @param newpattern The modified string (ignored if the operation doesn't
     *                                        modify the string)
     * @return Number of times a match happens.  Normally 0 (no match) or 1
     *         (match found), but may be greater if a transforming pattern
     *         is applied with the 'g' flag.
     */
    AP_DECLARE(int) ap_rxplus_exec(apr_pool_t *pool, ap_rxplus_t *rx,
                                   const char *pattern, char **newpattern);
    #ifdef DOXYGEN
    /**
     * Number of matches in the regexp operation's memory
     * This may be 0 if no match is in memory, or up to nmatch from compilation
     * @param rx The regexp
     * @return Number of matches in memory
     */
    AP_DECLARE(int) ap_rxplus_nmatch(ap_rxplus_t *rx);
    #else
    #define ap_rxplus_nmatch(rx) (((rx)->match != NULL) ? (rx)->nmatch : 0)
    #endif
    /**
     * Get a pointer to a match from regex memory
     * NOTE: this relies on the match pattern from the last call to
     *       ap_rxplus_exec still being valid (i.e. not freed or out-of-scope)
     * @param rx The regexp
     * @param n The match number to retrieve (must be between 0 and nmatch)
     * @param len Returns the length of the match.
     * @param match Returns the match pattern
     */
    AP_DECLARE(void) ap_rxplus_match(ap_rxplus_t *rx, int n, int *len,
                                     const char **match);
    /**
     * Get a match from regex memory in a string copy
     * NOTE: this relies on the match pattern from the last call to
     *       ap_rxplus_exec still being valid (i.e. not freed or out-of-scope)
     * @param pool Pool to allocate from
     * @param rx The regexp
     * @param n The match number to retrieve (must be between 0 and nmatch)
     * @return The matched string
     */
    AP_DECLARE(char*) ap_rxplus_pmatch(apr_pool_t *pool, ap_rxplus_t *rx, int n);
    
    #ifdef __cplusplus
    }   /* extern "C" */
    #endif
    
    #endif /* AP_REGEX_T */
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/http_request.h�����������������������������������������������������������������0000664�0001751�0001751�00000063337�14104434146�017162� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file http_request.h
     * @brief Apache Request library
     *
     * @defgroup APACHE_CORE_REQ Apache Request Processing
     * @ingroup  APACHE_CORE
     * @{
     */
    
    /*
     * 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.
     */
    
    #ifndef APACHE_HTTP_REQUEST_H
    #define APACHE_HTTP_REQUEST_H
    
    #include "apr_optional.h"
    #include "util_filter.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define AP_SUBREQ_NO_ARGS 0
    #define AP_SUBREQ_MERGE_ARGS 1
    
    /**
     * 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
     */
    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
     */
    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;
     * <PRE>
     *      AP_SUBREQ_NO_ARGS     ignore r->args and r->path_info
     *      AP_SUBREQ_MERGE_ARGS  merge r->args and r->path_info
     * </PRE>
     * @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
     * @note 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
     */
    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
     * @return status code
     */
    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
     */
    AP_DECLARE(int) ap_run_sub_req(request_rec *r);
    
    /**
     * Free the memory associated with a subrequest
     * @param r The subrequest to finish
     */
    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
     */
    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
     */
    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
     * @note 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
     * @bug Behavior changed in 2.4.x refactoring, API no longer usable
     * @deprecated @see ap_some_authn_required()
     */
    AP_DECLARE(int) ap_some_auth_required(request_rec *r);
    
    /**
     * @defgroup APACHE_CORE_REQ_AUTH Access Control for Sub-Requests and
     *                                Internal Redirects
     * @ingroup  APACHE_CORE_REQ
     * @{
     */
    
    #define AP_AUTH_INTERNAL_PER_URI  0  /**< Run access control hooks on all
                                              internal requests with URIs
                                              distinct from that of initial
                                              request */
    #define AP_AUTH_INTERNAL_PER_CONF 1  /**< Run access control hooks only on
                                              internal requests with
                                              configurations distinct from
                                              that of initial request */
    #define AP_AUTH_INTERNAL_MASK     0x000F  /**< mask to extract internal request
                                                   processing mode */
    
    /**
     * Clear flag which determines when access control hooks will be run for
     * internal requests.
     */
    AP_DECLARE(void) ap_clear_auth_internal(void);
    
    /**
     * Determine whether access control hooks will be run for all internal
     * requests with URIs distinct from that of the initial request, or only
     * those for which different configurations apply than those which applied
     * to the initial request.  To accommodate legacy external modules which
     * may expect access control hooks to be run for all internal requests
     * with distinct URIs, this is the default behaviour unless all access
     * control hooks and authentication and authorization providers are
     * registered with AP_AUTH_INTERNAL_PER_CONF.
     * @param ptemp Pool used for temporary allocations
     */
    AP_DECLARE(void) ap_setup_auth_internal(apr_pool_t *ptemp);
    
    /**
     * Register an authentication or authorization 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
     * @param type Internal request processing mode, either
     *             AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
     * @return APR_SUCCESS if all went well
     */
    AP_DECLARE(apr_status_t) ap_register_auth_provider(apr_pool_t *pool,
                                                       const char *provider_group,
                                                       const char *provider_name,
                                                       const char *provider_version,
                                                       const void *provider,
                                                       int type);
    
    /** @} */
    
    /* Optional functions coming from mod_authn_core and mod_authz_core
     * that list all registered authn/z providers.
     */
    APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, authn_ap_list_provider_names,
                            (apr_pool_t *ptemp));
    APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, authz_ap_list_provider_names,
                            (apr_pool_t *ptemp));
    
    /**
     * 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
     */
    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_mtime Time to set the mtime to
     */
    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.
     */
    AP_DECLARE(void) ap_allow_methods(request_rec *r, int reset, ...)
                     AP_FN_ATTR_SENTINEL;
    
    /**
     * 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.
     */
    AP_DECLARE(void) ap_allow_standard_methods(request_rec *r, int reset, ...);
    
    #define MERGE_ALLOW 0
    #define REPLACE_ALLOW 1
    
    /**
     * Process a top-level request from a client, and synchronously write
     * the response to the client
     * @param r The current request
     */
    AP_DECLARE(void) ap_process_request(request_rec *r);
    
    /* For post-processing after a handler has finished with a request.
     * (Commonly used after it was suspended)
     */
    AP_DECLARE(void) ap_process_request_after_handler(request_rec *r);
    
    /**
     * Process a top-level request from a client, allowing some or all of
     * the response to remain buffered in the core output filter for later,
     * asynchronous write completion
     * @param r The current request
     */
    void ap_process_async_request(request_rec *r);
    
    /**
     * Kill the current request
     * @param type Why the request is dying
     * @param r The current request
     */
    AP_DECLARE(void) ap_die(int type, request_rec *r);
    
    /**
     * Check whether a connection is still established and has data available,
     * optionally consuming blank lines ([CR]LF).
     * @param c The current connection
     * @param bb The brigade to filter
     * @param max_blank_lines Max number of blank lines to consume, or zero
     *                        to consider them as data (single read).
     * @return APR_SUCCESS: connection established with data available,
     *         APR_EAGAIN: connection established and empty,
     *         APR_NOTFOUND: too much blank lines,
     *         APR_E*: connection/general error.
     */
    AP_DECLARE(apr_status_t) ap_check_pipeline(conn_rec *c, apr_bucket_brigade *bb,
                                               unsigned int max_blank_lines);
    
    /* 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, before URL decoding happens.
     * @param r The current request
     * @return DECLINED to let other modules handle the pre-translation,
     *         OK if it was handled and no other module should process it,
     *         DONE if no further transformation should happen on the URI,
     *         HTTP_... in case of error.
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int,pre_translate_name,(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 "<Proxy>" 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. This hook should be registered with
     * ap_hook_check_authn().
     *
     * @param r The current request
     * @return OK, DECLINED, or HTTP_...
     * @ingroup hooks
     * @see ap_hook_check_authn
     */
    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. This hook should be registered
     * with ap_hook_check_access().
     *
     * @param r the current request
     * @return OK, DECLINED, or HTTP_...
     * @ingroup hooks
     * @see ap_hook_check_access
     */
    AP_DECLARE_HOOK(int,access_checker,(request_rec *r))
    
    /**
     * This hook is used to apply additional access control and/or bypass
     * authentication for this resource. It runs *before* a user is authenticated,
     * but after the auth_checker hook.
     * This hook should be registered with ap_hook_check_access_ex().
     *
     * @param r the current request
     * @return OK (allow access), DECLINED (let later modules decide),
     *         or HTTP_... (deny access)
     * @ingroup hooks
     * @see ap_hook_check_access_ex
     */
    AP_DECLARE_HOOK(int,access_checker_ex,(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). This
     * hook should be registered with ap_hook_check_authz().
     *
     * @param r the current request
     * @return OK, DECLINED, or HTTP_...
     * @ingroup hooks
     * @see ap_hook_check_authz
     */
    AP_DECLARE_HOOK(int,auth_checker,(request_rec *r))
    
    /**
     * Register a hook function that will apply additional access control to
     * the current request.
     * @param pf An access_checker hook function
     * @param aszPre A NULL-terminated array of strings that name modules whose
     *               hooks should precede this one
     * @param aszSucc A NULL-terminated array of strings that name modules whose
     *                hooks should succeed this one
     * @param nOrder An integer determining order before honouring aszPre and
     *               aszSucc (for example, HOOK_MIDDLE)
     * @param type Internal request processing mode, either
     *             AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
     */
    AP_DECLARE(void) ap_hook_check_access(ap_HOOK_access_checker_t *pf,
                                          const char * const *aszPre,
                                          const char * const *aszSucc,
                                          int nOrder, int type);
    
    /**
     * Register a hook function that will apply additional access control
     * and/or bypass authentication for the current request.
     * @param pf An access_checker_ex hook function
     * @param aszPre A NULL-terminated array of strings that name modules whose
     *               hooks should precede this one
     * @param aszSucc A NULL-terminated array of strings that name modules whose
     *                hooks should succeed this one
     * @param nOrder An integer determining order before honouring aszPre and
     *               aszSucc (for example, HOOK_MIDDLE)
     * @param type Internal request processing mode, either
     *             AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
     */
    AP_DECLARE(void) ap_hook_check_access_ex(ap_HOOK_access_checker_ex_t *pf,
                                             const char * const *aszPre,
                                             const char * const *aszSucc,
                                             int nOrder, int type);
    
    
    /**
     * Register a hook function that will analyze the request headers,
     * authenticate the user, and set the user information in the request record.
     * @param pf A check_user_id hook function
     * @param aszPre A NULL-terminated array of strings that name modules whose
     *               hooks should precede this one
     * @param aszSucc A NULL-terminated array of strings that name modules whose
     *                hooks should succeed this one
     * @param nOrder An integer determining order before honouring aszPre and
     *               aszSucc (for example, HOOK_MIDDLE)
     * @param type Internal request processing mode, either
     *             AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
     */
    AP_DECLARE(void) ap_hook_check_authn(ap_HOOK_check_user_id_t *pf,
                                         const char * const *aszPre,
                                         const char * const *aszSucc,
                                         int nOrder, int type);
    
    /**
     * Register a hook function that determine if the resource being requested
     * is available for the currently authenticated user.
     * @param pf An auth_checker hook function
     * @param aszPre A NULL-terminated array of strings that name modules whose
     *               hooks should precede this one
     * @param aszSucc A NULL-terminated array of strings that name modules whose
     *                hooks should succeed this one
     * @param nOrder An integer determining order before honouring aszPre and
     *               aszSucc (for example, HOOK_MIDDLE)
     * @param type Internal request processing mode, either
     *             AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
     */
    AP_DECLARE(void) ap_hook_check_authz(ap_HOOK_auth_checker_t *pf,
                                         const char * const *aszPre,
                                         const char * const *aszSucc,
                                         int nOrder, int type);
    
    /**
     * 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))
    
    /**
     * This hook allows modules to affect the request immediately after the
     * per-directory configuration for the request has been generated.
     * @param r The current request
     * @return OK (allow access), DECLINED (let later modules decide),
     *         or HTTP_... (deny access)
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r))
    
    /**
     * This hook allows a module to force authn to be required when
     * processing a request.
     * This hook should be registered with ap_hook_force_authn().
     * @param r The current request
     * @return OK (force authn), DECLINED (let later modules decide)
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int,force_authn,(request_rec *r))
    
    /**
     * This hook allows modules to handle/emulate the apr_stat() calls
     * needed for directory walk.
     * @param finfo where to put the stat data
     * @param r The current request
     * @param wanted APR_FINFO_* flags to pass to apr_stat()
     * @return apr_status_t or AP_DECLINED (let later modules decide)
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(apr_status_t,dirwalk_stat,(apr_finfo_t *finfo, request_rec *r, apr_int32_t wanted))
    
    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);
    AP_DECLARE(int) ap_if_walk(request_rec *r);
    
    /** End Of REQUEST (EOR) bucket */
    AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_eor;
    
    /**
     * Determine if a bucket is an End Of REQUEST (EOR) bucket
     * @param e The bucket to inspect
     * @return true or false
     */
    #define AP_BUCKET_IS_EOR(e)         ((e)->type == &ap_bucket_type_eor)
    
    /**
     * Make the bucket passed in an End Of REQUEST (EOR) bucket
     * @param b The bucket to make into an EOR bucket
     * @param r The request to destroy when this bucket is destroyed
     * @return The new bucket, or NULL if allocation failed
     */
    AP_DECLARE(apr_bucket *) ap_bucket_eor_make(apr_bucket *b, request_rec *r);
    
    /**
     * Create a bucket referring to an End Of REQUEST (EOR). This bucket
     * holds a pointer to the request_rec, so that the request can be
     * destroyed right after all of the output has been sent to the client.
     *
     * @param list The freelist from which this bucket should be allocated
     * @param r The request to destroy when this bucket is destroyed
     * @return The new bucket, or NULL if allocation failed
     */
    AP_DECLARE(apr_bucket *) ap_bucket_eor_create(apr_bucket_alloc_t *list,
                                                  request_rec *r);
    
    /**
     * Can be used within any handler to determine if any authentication
     * is required for the current request.  Note that if used with an
     * access_checker hook, an access_checker_ex hook or an authz provider; the
     * caller should take steps to avoid a loop since this function is
     * implemented by calling these hooks.
     * @param r The current request
     * @return TRUE if authentication is required, FALSE otherwise
     */
    AP_DECLARE(int) ap_some_authn_required(request_rec *r);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_REQUEST_H */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_fcgi.h��������������������������������������������������������������������0000664�0001751�0001751�00000023400�13623622544�016371� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_fcgi.h
     * @brief FastCGI protocol definitions and support routines
     *
     * @defgroup APACHE_CORE_FASTCGI FastCGI Tools
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_UTIL_FCGI_H
    #define APACHE_UTIL_FCGI_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include "httpd.h"
    
    /**
     * @brief A structure that represents the fixed header fields
     * at the beginning of a "FastCGI record" (i.e., the data prior
     * to content data and padding).
     */
    typedef struct {
        /** See values for version, below */
        unsigned char version;
        /** See values for type, below */
        unsigned char type;
        /** request id, in two parts */
        unsigned char requestIdB1;
        unsigned char requestIdB0;
        /** content length, in two parts */
        unsigned char contentLengthB1;
        unsigned char contentLengthB0;
        /** padding length */
        unsigned char paddingLength;
        /** 8-bit reserved field */
        unsigned char reserved;
    } ap_fcgi_header;
    
    /*
     * Number of bytes in the header portion of a FastCGI record
     * (i.e., ap_fcgi_header structure).  Future versions of the
     * protocol may increase the size.
     */
    #define AP_FCGI_HEADER_LEN  8
    
    /*
     * Maximum number of bytes in the content portion of a FastCGI record.
     */
    #define AP_FCGI_MAX_CONTENT_LEN 65535
    
    /**
     * Possible values for the version field of ap_fcgi_header
     */
    #define AP_FCGI_VERSION_1 1
    
    /**
     * Possible values for the type field of ap_fcgi_header
     */
    #define AP_FCGI_BEGIN_REQUEST       1
    #define AP_FCGI_ABORT_REQUEST       2
    #define AP_FCGI_END_REQUEST         3
    #define AP_FCGI_PARAMS              4
    #define AP_FCGI_STDIN               5
    #define AP_FCGI_STDOUT              6
    #define AP_FCGI_STDERR              7
    #define AP_FCGI_DATA                8
    #define AP_FCGI_GET_VALUES          9
    #define AP_FCGI_GET_VALUES_RESULT  10
    #define AP_FCGI_UNKNOWN_TYPE       11
    #define AP_FCGI_MAXTYPE (AP_FCGI_UNKNOWN_TYPE)
    
    /**
     * Offsets of the various fields of ap_fcgi_header
     */
    #define AP_FCGI_HDR_VERSION_OFFSET         0
    #define AP_FCGI_HDR_TYPE_OFFSET            1
    #define AP_FCGI_HDR_REQUEST_ID_B1_OFFSET   2
    #define AP_FCGI_HDR_REQUEST_ID_B0_OFFSET   3
    #define AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET  4
    #define AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET  5
    #define AP_FCGI_HDR_PADDING_LEN_OFFSET     6
    #define AP_FCGI_HDR_RESERVED_OFFSET        7
    
    /**
     * @brief This represents the content data of the FastCGI record when
     * the type is AP_FCGI_BEGIN_REQUEST.
     */
    typedef struct {
        /**
         * role, in two parts
         * See values for role, below
         */
        unsigned char roleB1;
        unsigned char roleB0;
        /**
         * flags
         * See values for flags bits, below
         */
        unsigned char flags;
        /** reserved */
        unsigned char reserved[5];
    } ap_fcgi_begin_request_body;
    
    /*
     * Values for role component of ap_fcgi_begin_request_body
     */
    #define AP_FCGI_RESPONDER  1
    #define AP_FCGI_AUTHORIZER 2
    #define AP_FCGI_FILTER     3
    
    /*
     * Values for flags bits of ap_fcgi_begin_request_body
     */
    #define AP_FCGI_KEEP_CONN  1  /* otherwise the application closes */
    
    /**
     * Offsets of the various fields of ap_fcgi_begin_request_body
     */
    #define AP_FCGI_BRB_ROLEB1_OFFSET       0
    #define AP_FCGI_BRB_ROLEB0_OFFSET       1
    #define AP_FCGI_BRB_FLAGS_OFFSET        2
    #define AP_FCGI_BRB_RESERVED0_OFFSET    3
    #define AP_FCGI_BRB_RESERVED1_OFFSET    4
    #define AP_FCGI_BRB_RESERVED2_OFFSET    5
    #define AP_FCGI_BRB_RESERVED3_OFFSET    6
    #define AP_FCGI_BRB_RESERVED4_OFFSET    7
    
    /**
     * Pack ap_fcgi_header
     * @param h The header to read from
     * @param a The array to write to, of size AP_FCGI_HEADER_LEN
     */
    AP_DECLARE(void) ap_fcgi_header_to_array(ap_fcgi_header *h,
                                             unsigned char a[]);
    
    /**
     * Unpack header of FastCGI record into ap_fcgi_header
     * @param h The header to write to
     * @param a The array to read from, of size AP_FCGI_HEADER_LEN
     */
    AP_DECLARE(void) ap_fcgi_header_from_array(ap_fcgi_header *h,
                                               unsigned char a[]);
    
    /**
     * Unpack header of FastCGI record into individual fields
     * @param version The version, on output
     * @param type The type, on output
     * @param request_id The request id, on output
     * @param content_len The content length, on output
     * @param padding_len The amount of padding following the content, on output
     * @param a The array to read from, of size AP_FCGI_HEADER_LEN
     */
    AP_DECLARE(void) ap_fcgi_header_fields_from_array(unsigned char *version,
                                                      unsigned char *type,
                                                      apr_uint16_t *request_id,
                                                      apr_uint16_t *content_len,
                                                      unsigned char *padding_len,
                                                      unsigned char a[]);
    
    /**
     * Pack ap_fcgi_begin_request_body
     * @param h The begin-request body to read from
     * @param a The array to write to, of size AP_FCGI_HEADER_LEN
     */
    AP_DECLARE(void) ap_fcgi_begin_request_body_to_array(ap_fcgi_begin_request_body *h,
                                                         unsigned char a[]);
    
    /**
     * Fill in a FastCGI request header with the required field values.
     * @param header The header to fill in
     * @param type The type of record
     * @param request_id The request id
     * @param content_len The amount of content which follows the header
     * @param padding_len The amount of padding which follows the content
     *
     * The header array must be at least AP_FCGI_HEADER_LEN bytes long.
     */
    AP_DECLARE(void) ap_fcgi_fill_in_header(ap_fcgi_header *header,
                                            unsigned char type,
                                            apr_uint16_t request_id,
                                            apr_uint16_t content_len,
                                            unsigned char padding_len);
    
    /**
     * Fill in a FastCGI begin request body with the required field values.
     * @param brb The begin-request-body to fill in
     * @param role AP_FCGI_RESPONDER or other roles
     * @param flags 0 or a combination of flags like AP_FCGI_KEEP_CONN
     */
    AP_DECLARE(void) ap_fcgi_fill_in_request_body(ap_fcgi_begin_request_body *brb,
                                                  int role,
                                                  unsigned char flags);
    
    /**
     * Compute the buffer size needed to encode the next portion of
     * the provided environment table.
     * @param env The environment table
     * @param maxlen The maximum buffer size allowable, capped at 
     * AP_FCGI_MAX_CONTENT_LEN.
     * @param starting_elem On input, the next element of the table array
     * to process in this FastCGI record.  On output, the next element to
     * process on the *next* FastCGI record.
     * @return Size of buffer needed to encode the next part, or 0
     * if no more can be encoded.  When 0 is returned: If starting_elem
     * has reached the end of the table array, all has been encoded;
     * otherwise, the next envvar can't be encoded within the specified
     * limit.
     * @note If an envvar can't be encoded within the specified limit,
     * the caller can log a warning and increment starting_elem and try 
     * again or increase the limit or fail, as appropriate for the module.
     */
    AP_DECLARE(apr_size_t) ap_fcgi_encoded_env_len(apr_table_t *env,
                                                   apr_size_t maxlen,
                                                   int *starting_elem);
    
    /**
     * Encode the next portion of the provided environment table using
     * a buffer previously allocated.
     * @param r The request, for logging
     * @param env The environment table
     * @param buffer A buffer to contain the encoded environment table
     * @param buflen The length of the buffer, previously computed by
     * ap_fcgi_encoded_env_len().
     * @param starting_elem On input, the next element of the table array
     * to process in this FastCGI record.  On output, the next element to
     * process on the *next* FastCGI record.
     * @return APR_SUCCESS if a section could be encoded or APR_ENOSPC
     * otherwise.
     * @note The output starting_elem from ap_fcgi_encoded_env_len
     * shouldn't be used as input to ap_fcgi_encode_env when building the
     * same FastCGI record.
     */
    AP_DECLARE(apr_status_t) ap_fcgi_encode_env(request_rec *r,
                                                apr_table_t *env,
                                                void *buffer,
                                                apr_size_t buflen,
                                                int *starting_elem);
    
    /**
     * String forms for the value of the FCGI_ROLE envvar
     */
    #define AP_FCGI_RESPONDER_STR   "RESPONDER"
    #define AP_FCGI_AUTHORIZER_STR  "AUTHORIZER"
    #define AP_FCGI_FILTER_STR      "FILTER"
    
    /**
     * FastCGI implementations that implement the AUTHORIZER role
     * for Apache httpd and allow the application to participate in
     * any of the Apache httpd AAA phases typically set the variable
     * FCGI_APACHE_ROLE to one of these strings to indicate the
     * specific AAA phase.
     */
    #define AP_FCGI_APACHE_ROLE_AUTHENTICATOR_STR  "AUTHENTICATOR"
    #define AP_FCGI_APACHE_ROLE_AUTHORIZER_STR     "AUTHORIZER"
    #define AP_FCGI_APACHE_ROLE_ACCESS_CHECKER_STR "ACCESS_CHECKER"
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_UTIL_FCGI_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_varbuf.h������������������������������������������������������������������0000664�0001751�0001751�00000020136�12362524526�016751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file util_varbuf.h
     * @brief Apache resizable variable length buffer library
     *
     * @defgroup APACHE_CORE_VARBUF Variable length buffer library
     * @ingroup APACHE_CORE
     *
     * This set of functions provides resizable buffers. While the primary
     * usage is with NUL-terminated strings, most functions also work with
     * arbitrary binary data.
     * 
     * @{
     */
    
    #ifndef AP_VARBUF_H
    #define AP_VARBUF_H
    
    #include "apr.h"
    #include "apr_allocator.h"
    
    #include "httpd.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define AP_VARBUF_UNKNOWN APR_SIZE_MAX
    struct ap_varbuf_info;
    
    /** A resizable buffer. */
    struct ap_varbuf {
        /** The actual buffer; will point to a const '\\0' if avail == 0 and
         *  to memory of the same lifetime as the pool otherwise. */
        char *buf;
    
        /** Allocated size of the buffer (minus one for the final \\0);
         *  must only be changed using ap_varbuf_grow(). */
        apr_size_t avail;
    
        /** Length of string in buffer, or AP_VARBUF_UNKNOWN. This determines how
         *  much memory is copied by ap_varbuf_grow() and where
         *  ap_varbuf_strmemcat() will append to the buffer. */
        apr_size_t strlen;
    
        /** The pool for memory allocations and for registering the cleanup;
         *  the buffer memory will be released when this pool is cleared. */
        apr_pool_t *pool;
    
        /** Opaque info for memory allocation. */
        struct ap_varbuf_info *info;
    };
    
    /**
     * Initialize a resizable buffer. It is safe to re-initialize a previously
     * used ap_varbuf. The old buffer will be released when the corresponding
     * pool is cleared. The buffer remains usable until the pool is cleared,
     * even if the ap_varbuf was located on the stack and has gone out of scope.
     * @param   pool        The pool to allocate small buffers from and to register
     *                      the cleanup with
     * @param   vb          Pointer to the ap_varbuf struct
     * @param   init_size   The initial size of the buffer (see ap_varbuf_grow() for
     *                      details)
     */
    AP_DECLARE(void) ap_varbuf_init(apr_pool_t *pool, struct ap_varbuf *vb,
                                    apr_size_t init_size);
    
    /**
     * Grow a resizable buffer. If the vb->buf cannot be grown in place, it will
     * be reallocated and the first vb->strlen + 1 bytes of memory will be copied
     * to the new location. If vb->strlen == AP_VARBUF_UNKNOWN, the whole buffer
     * is copied.
     * @param   vb          Pointer to the ap_varbuf struct
     * @param   new_size    The minimum new size of the buffer
     * @note ap_varbuf_grow() will usually at least double vb->buf's size with
     *       every invocation in order to reduce reallocations.
     * @note ap_varbuf_grow() will use pool memory for small and allocator
     *       mem nodes for larger allocations.
     * @note ap_varbuf_grow() will call vb->pool's abort function if out of memory.
     */
    AP_DECLARE(void) ap_varbuf_grow(struct ap_varbuf *vb, apr_size_t new_size);
    
    /**
     * Release memory from a ap_varbuf immediately, if possible.
     * This allows to free large buffers before the corresponding pool is
     * cleared. Only larger allocations using mem nodes will be freed.
     * @param   vb          Pointer to the ap_varbuf struct
     * @note After ap_varbuf_free(), vb must not be used unless ap_varbuf_init()
     *       is called again.
     */
    AP_DECLARE(void) ap_varbuf_free(struct ap_varbuf *vb);
    
    /**
     * Concatenate a string to an ap_varbuf. vb->strlen determines where
     * the string is appended in the buffer. If vb->strlen == AP_VARBUF_UNKNOWN,
     * the string will be appended at the first NUL byte in the buffer.
     * If len == 0, ap_varbuf_strmemcat() does nothing.
     * @param   vb      Pointer to the ap_varbuf struct
     * @param   str     The string to append; must be at least len bytes long
     * @param   len     The number of characters of *str to concatenate to the buf
     * @note vb->strlen will be set to the length of the new string
     * @note if len != 0, vb->buf will always be NUL-terminated
     */
    AP_DECLARE(void) ap_varbuf_strmemcat(struct ap_varbuf *vb, const char *str,
                                         int len);
    
    /**
     * Duplicate an ap_varbuf's content into pool memory.
     * @param   p           The pool to allocate from
     * @param   vb          The ap_varbuf to copy from
     * @param   prepend     An optional buffer to prepend (may be NULL)
     * @param   prepend_len Length of prepend
     * @param   append      An optional buffer to append (may be NULL)
     * @param   append_len  Length of append
     * @param   new_len     Where to store the length of the resulting string
     *                      (may be NULL)
     * @return The new string
     * @note ap_varbuf_pdup() uses vb->strlen to determine how much memory to
     *       copy. It works even if 0-bytes are embedded in vb->buf, prepend, or
     *       append.
     * @note If vb->strlen equals AP_VARBUF_UNKNOWN, it will be set to
     *       strlen(vb->buf).
     */
    AP_DECLARE(char *) ap_varbuf_pdup(apr_pool_t *p, struct ap_varbuf *vb,
                                      const char *prepend, apr_size_t prepend_len,
                                      const char *append, apr_size_t append_len,
                                      apr_size_t *new_len);
    
    
    /**
     * Concatenate a string to an ap_varbuf.
     * @param   vb      Pointer to the ap_varbuf struct
     * @param   str     The string to append
     * @note vb->strlen will be set to the length of the new string
     */
    #define ap_varbuf_strcat(vb, str) ap_varbuf_strmemcat(vb, str, strlen(str))
    
    /**
     * Perform string substitutions based on regexp match, using an ap_varbuf.
     * This function behaves like ap_pregsub(), but appends to an ap_varbuf
     * instead of allocating the result from a pool.
     * @param   vb      The ap_varbuf to which the string will be appended
     * @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
     * @param   maxlen  The maximum string length to append to vb, 0 for unlimited
     * @return APR_SUCCESS if successful
     * @note Just like ap_pregsub(), this function does not copy the part of
     *       *source before the matching part (i.e. the first pmatch[0].rm_so
     *       characters).
     * @note If vb->strlen equals AP_VARBUF_UNKNOWN, it will be set to
     *       strlen(vb->buf) first.
     */
    AP_DECLARE(apr_status_t) ap_varbuf_regsub(struct ap_varbuf *vb,
                                              const char *input,
                                              const char *source,
                                              apr_size_t nmatch,
                                              ap_regmatch_t pmatch[],
                                              apr_size_t maxlen);
    
    /**
     * Read a line from an ap_configfile_t and append it to an ap_varbuf.
     * @param   vb      Pointer to the ap_varbuf struct
     * @param   cfp     Pointer to the ap_configfile_t
     * @param   max_len Maximum line length, including leading/trailing whitespace
     * @return See ap_cfg_getline()
     * @note vb->strlen will be set to the length of the line
     * @note If vb->strlen equals AP_VARBUF_UNKNOWN, it will be set to
     *       strlen(vb->buf) first.
     */
    AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb,
                                                   ap_configfile_t *cfp,
                                                   apr_size_t max_len);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !AP_VARBUF_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/mpm_common.h�������������������������������������������������������������������0000664�0001751�0001751�00000041657�14104436037�016576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
     */
    
    /**
     * @file  mpm_common.h
     * @brief Multi-Processing Modules functions
     *
     * @defgroup APACHE_MPM Multi-Processing Modules
     * @ingroup  APACHE
     * @{
     */
    
    #ifndef APACHE_MPM_COMMON_H
    #define APACHE_MPM_COMMON_H
    
    #include "ap_config.h"
    #include "ap_mpm.h"
    #include "scoreboard.h"
    
    #if APR_HAVE_NETINET_TCP_H
    #include <netinet/tcp.h>    /* for TCP_NODELAY */
    #endif
    
    #include "apr_proc_mutex.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* 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
    
    /* Signal used to gracefully restart */
    #define AP_SIG_GRACEFUL SIGUSR1
    
    /* Signal used to gracefully restart (without SIG prefix) */
    #define AP_SIG_GRACEFUL_SHORT USR1
    
    /* Signal used to gracefully restart (as a quoted string) */
    #define AP_SIG_GRACEFUL_STRING "SIGUSR1"
    
    /* Signal used to gracefully stop */
    #define AP_SIG_GRACEFUL_STOP SIGWINCH
    
    /* Signal used to gracefully stop (without SIG prefix) */
    #define AP_SIG_GRACEFUL_STOP_SHORT WINCH
    
    /* Signal used to gracefully stop (as a quoted string) */
    #define AP_SIG_GRACEFUL_STOP_STRING "SIGWINCH"
    
    /**
     * Callback function used for ap_reclaim_child_processes() and
     * ap_relieve_child_processes().  The callback function will be
     * called for each terminated child process.
     */
    typedef void ap_reclaim_callback_fn_t(int childnum, pid_t pid,
                                          ap_generation_t gen);
    
    #if (!defined(WIN32) && !defined(NETWARE)) || defined(DOXYGEN)
    /**
     * Make sure all child processes that have been spawned by the parent process
     * have died.  This includes process registered as "other_children".
     *
     * @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.
     * @param mpm_callback Callback invoked for each dead child process
     *
     * @note 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().
     */
    AP_DECLARE(void) ap_reclaim_child_processes(int terminate,
                                                ap_reclaim_callback_fn_t *mpm_callback);
    
    /**
     * Catch any child processes that have been spawned by the parent process
     * which have exited. This includes processes registered as "other_children".
     *
     * @param mpm_callback Callback invoked for each dead child process
    
     * @note The MPM child processes which are relieved are those listed
     * in the scoreboard as well as those currently registered via
     * ap_register_extra_mpm_process().
     */
    AP_DECLARE(void) ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callback);
    
    /**
     * Tell ap_reclaim_child_processes() and ap_relieve_child_processes() about
     * an MPM child process which has no entry in the scoreboard.
     * @param pid The process id of an MPM child process which should be
     * reclaimed when ap_reclaim_child_processes() is called.
     * @param gen The generation of this MPM child process.
     *
     * @note 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().
     */
    AP_DECLARE(void) ap_register_extra_mpm_process(pid_t pid, ap_generation_t gen);
    
    /**
     * Unregister an MPM child process which was previously registered by a
     * call to ap_register_extra_mpm_process().
     * @param pid The process id of an MPM child process which no longer needs to
     * be reclaimed.
     * @param old_gen Set to the server generation of the process, if found.
     * @return 1 if the process was found and removed, 0 otherwise
     */
    AP_DECLARE(int) ap_unregister_extra_mpm_process(pid_t pid, ap_generation_t *old_gen);
    
    /**
     * Safely signal an MPM child process, if the process is in the
     * current process group.  Otherwise fail.
     * @param pid the process id of a child process to signal
     * @param sig the signal number to send
     * @return APR_SUCCESS if signal is sent, otherwise an error as per kill(3);
     * APR_EINVAL is returned if passed either an invalid (< 1) pid, or if
     * the pid is not in the current process group
     */
    AP_DECLARE(apr_status_t) ap_mpm_safe_kill(pid_t pid, int sig);
    
    /**
     * 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 why The return code of the child process
     * @param status The status returned from ap_wait_or_timeout
     * @return 0 on success, APEXIT_CHILDFATAL if MPM should terminate
     */
    AP_DECLARE(int) ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status);
    
    AP_DECLARE(apr_status_t) ap_fatal_signal_setup(server_rec *s, apr_pool_t *in_pconf);
    AP_DECLARE(apr_status_t) ap_fatal_signal_child_setup(server_rec *s);
    
    #endif /* (!WIN32 && !NETWARE) || DOXYGEN */
    
    /**
     * Pool cleanup for end-generation hook implementation
     * (core httpd function)
     */
    apr_status_t ap_mpm_end_gen_helper(void *unused);
    
    /**
     * Run the monitor hook (once every ten calls), determine if any child
     * process has died and, if none died, sleep one second.
     * @param status The return code if a process has died
     * @param exitcode The returned exit status of the child, if a child process
     *                 dies, or the signal that caused the child to die.
     * @param ret The process id of the process that died
     * @param p The pool to allocate out of
     * @param s The server_rec to pass
     */
    AP_DECLARE(void) ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode,
                                        apr_proc_t *ret, apr_pool_t *p, 
                                        server_rec *s);
    
    #if defined(TCP_NODELAY)
    /**
     * 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
     * @fn 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
     * @fn gid_t ap_gname2id(const char *name)
     */
    AP_DECLARE(gid_t) ap_gname2id(const char *name);
    #endif
    
    #ifndef HAVE_INITGROUPS
    /**
     * The initgroups() function initializes the group access list by reading the
     * group database /etc/group and using all groups of which user is a member.
     * The additional group basegid is also added to the list.
     * @param name The user name - must be non-NULL
     * @param basegid The basegid to add
     * @return returns 0 on success
     * @fn int initgroups(const char *name, gid_t basegid)
     */
    int initgroups(const char *name, gid_t basegid);
    #endif
    
    #if (!defined(WIN32) && !defined(NETWARE)) || defined(DOXYGEN)
    
    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
     * @param pod the pipe-of-death that is created.
     */
    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
     *
     * @param pod the pipe-of-death to close.
     */
    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 pod the pipe-of-death to write to.
     */
    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 pod The pipe-of-death to write to.
     * @param num The number of child processes to kill
     */
    AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num);
    
    #define AP_MPM_PODX_RESTART_CHAR '$'
    #define AP_MPM_PODX_GRACEFUL_CHAR '!'
    
    typedef enum { AP_MPM_PODX_NORESTART, AP_MPM_PODX_RESTART, AP_MPM_PODX_GRACEFUL } ap_podx_restart_t;
    
    /**
     * Open the extended pipe-of-death.
     * @param p The pool to use for allocating the pipe
     * @param pod The pipe-of-death that is created.
     */
    AP_DECLARE(apr_status_t) ap_mpm_podx_open(apr_pool_t *p, ap_pod_t **pod);
    
    /**
     * Check the extended pipe to determine if the process has been signalled to die.
     */
    AP_DECLARE(int) ap_mpm_podx_check(ap_pod_t *pod);
    
    /**
     * Close the pipe-of-death
     *
     * @param pod The pipe-of-death to close.
     */
    AP_DECLARE(apr_status_t) ap_mpm_podx_close(ap_pod_t *pod);
    
    /**
     * Write data to the extended pipe-of-death, signalling that one child process
     * should die.
     * @param pod the pipe-of-death to write to.
     * @param graceful restart-type
     */
    AP_DECLARE(apr_status_t) ap_mpm_podx_signal(ap_pod_t *pod,
                                                ap_podx_restart_t graceful);
    
    /**
     * Write data to the extended pipe-of-death, signalling that all child process
     * should die.
     * @param pod The pipe-of-death to write to.
     * @param num The number of child processes to kill
     * @param graceful restart-type
     */
    AP_DECLARE(void) ap_mpm_podx_killpg(ap_pod_t *pod, int num,
                                        ap_podx_restart_t graceful);
    
    #endif /* (!WIN32 && !NETWARE) || DOXYGEN */
    
    /**
     * Check that exactly one MPM is loaded
     * Returns NULL if yes, error string if not.
     */
    AP_DECLARE(const char *) ap_check_mpm(void);
    
    /*
     * 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
     */
    AP_DECLARE_DATA extern int ap_max_requests_per_child;
    const char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy,
                                        const char *arg);
    
    /**
     * The filename used to store the process id.
     */
    AP_DECLARE_DATA extern const char *ap_pid_fname;
    const char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy,
                                   const char *arg);
    void ap_mpm_dump_pidfile(apr_pool_t *p, apr_file_t *out);
    
    /*
     * The directory that the server changes directory to dump core.
     */
    AP_DECLARE_DATA extern char ap_coredump_dir[MAX_STRING_LEN];
    AP_DECLARE_DATA extern int ap_coredumpdir_configured;
    const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy,
                                       const char *arg);
    
    /**
     * Set the timeout period for a graceful shutdown.
     */
    AP_DECLARE_DATA extern int ap_graceful_shutdown_timeout;
    AP_DECLARE(const char *)ap_mpm_set_graceful_shutdown(cmd_parms *cmd, void *dummy,
                                             const char *arg);
    #define AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND \
    AP_INIT_TAKE1("GracefulShutdownTimeout", ap_mpm_set_graceful_shutdown, NULL, \
                  RSRC_CONF, "Maximum time in seconds to wait for child "        \
                  "processes to complete transactions during shutdown")
    
    
    int ap_signal_server(int *, apr_pool_t *);
    void ap_mpm_rewrite_args(process_rec *);
    
    AP_DECLARE_DATA 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);
    
    AP_DECLARE_DATA extern apr_size_t ap_thread_stacksize;
    extern const char *ap_mpm_set_thread_stacksize(cmd_parms *cmd, void *dummy,
                                                   const char *arg);
    
    /* core's implementation of child_status hook */
    extern void ap_core_child_status(server_rec *s, pid_t pid, ap_generation_t gen,
                                     int slot, mpm_child_status status);
    
    #if defined(AP_ENABLE_EXCEPTION_HOOK) && AP_ENABLE_EXCEPTION_HOOK
    extern const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy,
                                                 const char *arg);
    #endif
    
    AP_DECLARE_HOOK(int,monitor,(apr_pool_t *p, server_rec *s))
    
    /* register modules that undertake to manage system security */
    AP_DECLARE(int) ap_sys_privileges_handlers(int inc);
    AP_DECLARE_HOOK(int, drop_privileges, (apr_pool_t * pchild, server_rec * s))
    
    /* implement the ap_mpm_query() function
     * The MPM should return OK+APR_ENOTIMPL for any unimplemented query codes;
     * modules which intercede for specific query codes should DECLINE for others.
     */
    AP_DECLARE_HOOK(int, mpm_query, (int query_code, int *result, apr_status_t *rv))
    
    /* register the specified callback */
    AP_DECLARE_HOOK(apr_status_t, mpm_register_timed_callback,
                    (apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton))
    
    /* get MPM name (e.g., "prefork" or "event") */
    AP_DECLARE_HOOK(const char *,mpm_get_name,(void))
    
    /**
     * Notification that connection handling is suspending (disassociating from the
     * current thread)
     * @param c The current connection
     * @param r The current request, or NULL if there is no active request
     * @ingroup hooks
     * @see ap_hook_resume_connection
     * @note This hook is not implemented by MPMs like Prefork and Worker which 
     * handle all processing of a particular connection on the same thread.
     * @note This hook will be called on the thread that was previously
     * processing the connection.
     * @note This hook is not called at the end of connection processing.  This
     * hook only notifies a module when processing of an active connection is
     * suspended.
     * @note Resumption and subsequent suspension of a connection solely to perform
     * I/O by the MPM, with no execution of non-MPM code, may not necessarily result
     * in a call to this hook.
     */
    AP_DECLARE_HOOK(void, suspend_connection,
                    (conn_rec *c, request_rec *r))
    
    /**
     * Notification that connection handling is resuming (associating with a thread)
     * @param c The current connection
     * @param r The current request, or NULL if there is no active request
     * @ingroup hooks
     * @see ap_hook_suspend_connection
     * @note This hook is not implemented by MPMs like Prefork and Worker which 
     * handle all processing of a particular connection on the same thread.
     * @note This hook will be called on the thread that will resume processing
     * the connection.
     * @note This hook is not called at the beginning of connection processing.
     * This hook only notifies a module when processing resumes for a
     * previously-suspended connection.
     * @note Resumption and subsequent suspension of a connection solely to perform
     * I/O by the MPM, with no execution of non-MPM code, may not necessarily result
     * in a call to this hook.
     */
    AP_DECLARE_HOOK(void, resume_connection,
                    (conn_rec *c, request_rec *r))
    
    /**
     * Notification that the child is stopping. If graceful, ongoing
     * requests will be served.
     * @param pchild The child pool
     * @param graceful != 0 iff this is a graceful shutdown.
     */
    AP_DECLARE_HOOK(void, child_stopping,
                    (apr_pool_t *pchild, int graceful))
    
    /* mutex type string for accept mutex, if any; MPMs should use the
     * same mutex type for ease of configuration
     */
    #define AP_ACCEPT_MUTEX_TYPE "mpm-accept"
    
    /* internal pre-config logic for MPM-related settings, callable only from
     * core's pre-config hook
     */
    void mpm_common_pre_config(apr_pool_t *pconf);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* !APACHE_MPM_COMMON_H */
    /** @} */
    ���������������������������������������������������������������������������������httpd-2.4.64/include/mod_auth.h���������������������������������������������������������������������0000664�0001751�0001751�00000010653�13623622544�016232� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mod_auth.h
     * @brief Authentication and Authorization Extension for Apache
     *
     * @defgroup MOD_AUTH mod_auth
     * @ingroup  APACHE_MODS
     */
    
    #ifndef APACHE_MOD_AUTH_H
    #define APACHE_MOD_AUTH_H
    
    #include "apr_pools.h"
    #include "apr_hash.h"
    #include "apr_optional.h"
    
    #include "httpd.h"
    #include "http_config.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define AUTHN_PROVIDER_GROUP "authn"
    #define AUTHZ_PROVIDER_GROUP "authz"
    #define AUTHN_PROVIDER_VERSION "0"
    #define AUTHZ_PROVIDER_VERSION "0"
    #define AUTHN_DEFAULT_PROVIDER "file"
    
    #define AUTHN_PROVIDER_NAME_NOTE "authn_provider_name"
    #define AUTHZ_PROVIDER_NAME_NOTE "authz_provider_name"
    
    #define AUTHN_PREFIX "AUTHENTICATE_"
    #define AUTHZ_PREFIX "AUTHORIZE_"
    
    /** all of the requirements must be met */
    #ifndef SATISFY_ALL
    #define SATISFY_ALL 0
    #endif
    /**  any of the requirements must be met */
    #ifndef SATISFY_ANY
    #define SATISFY_ANY 1
    #endif
    /** There are no applicable satisfy lines */
    #ifndef SATISFY_NOSPEC
    #define SATISFY_NOSPEC 2
    #endif
    
    typedef enum {
        AUTH_DENIED,
        AUTH_GRANTED,
        AUTH_USER_FOUND,
        AUTH_USER_NOT_FOUND,
        AUTH_GENERAL_ERROR
    } authn_status;
    
    typedef enum {
        AUTHZ_DENIED,
        AUTHZ_GRANTED,
        AUTHZ_NEUTRAL,
        AUTHZ_GENERAL_ERROR,
        AUTHZ_DENIED_NO_USER      /* denied because r->user == NULL */
    } authz_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 {
        /* Given a request_rec, expected to return AUTHZ_GRANTED
         * if we can authorize user access.
         * @param r the request record
         * @param require_line the argument to the authz provider
         * @param parsed_require_line the value set by parse_require_line(), if any
         */
        authz_status (*check_authorization)(request_rec *r,
                                            const char *require_line,
                                            const void *parsed_require_line);
    
        /** Check the syntax of a require line and optionally cache the parsed
         * line. This function may be NULL.
         * @param cmd the config directive
         * @param require_line the argument to the authz provider
         * @param parsed_require_line place to store parsed require_line for use by provider
         * @return Error message or NULL on success
         */
        const char *(*parse_require_line)(cmd_parms *cmd, const char *require_line,
                                          const void **parsed_require_line);
    } authz_provider;
    
    /* ap_authn_cache_store: Optional function for authn providers
     * to enable caching their lookups with mod_authn_cache
     * @param r The request rec
     * @param module Module identifier
     * @param user User name to authenticate
     * @param realm Digest authn realm (NULL for basic authn)
     * @param data The value looked up by the authn provider, to cache
     */
    APR_DECLARE_OPTIONAL_FN(void, ap_authn_cache_store,
                            (request_rec*, const char*, const char*,
                             const char*, const char*));
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    �������������������������������������������������������������������������������������httpd-2.4.64/include/util_ebcdic.h������������������������������������������������������������������0000664�0001751�0001751�00000005300�12425122625�016663� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_ebcdic.h
     * @brief Utilities for EBCDIC conversion
     *
     * @defgroup APACHE_CORE_EBCDIC Utilities for EBCDIC conversion
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #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"
    
    #if APR_CHARSET_EBCDIC || defined(DOXYGEN)
    
    /**
     * Setup all of the global translation handlers.
     * @param   pool    The pool to allocate out of.
     * @note On non-EBCDIC system, this function does <b>not</b> exist.
     * So, its use should be guarded by \#if APR_CHARSET_EBCDIC.
     */
    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.
     * @note On non-EBCDIC system, this function is replaced by an 
     * empty macro.
     */
    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.
     * @note On non-EBCDIC system, this function is replaced by an 
     * empty macro.
     */
    void ap_xlate_proto_from_ascii(char *buffer, apr_size_t len);
    
    /**
     * Convert protocol data from the implementation character
     * set to ASCII, then send it.
     * @param   r       The current request.
     * @param   ...     The strings to write, followed by a NULL pointer.
     * @note On non-EBCDIC system, this function is replaced by a call to
     * #ap_rvputs.
     */
    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 */
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/http_connection.h��������������������������������������������������������������0000664�0001751�0001751�00000015743�14124077612�017632� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  http_connection.h
     * @brief Apache connection library
     *
     * @defgroup APACHE_CORE_CONNECTION Connection Library
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_HTTP_CONNECTION_H
    #define APACHE_HTTP_CONNECTION_H
    
    #include "apr_network_io.h"
    #include "apr_buckets.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * 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.
     */
    AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, void *csd);
    
    /**
     * Shutdown the connection for writing.
     * @param c The connection to shutdown
     * @param flush Whether or not to flush pending data before
     * @return APR_SUCCESS or the underlying error
     */
    AP_CORE_DECLARE(apr_status_t) ap_shutdown_conn(conn_rec *c, int flush);
    
    /**
     * Flushes all remain data in the client send buffer
     * @param c The connection to flush
     * @remark calls ap_shutdown_conn(c, 1)
     */
    AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c);
    
    /**
     * This function is responsible for the following cases:
     * <pre>
     * 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://tools.ietf.org/html/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.
     * </pre>
     * @param c The connection we are closing
     */
    AP_DECLARE(void) ap_lingering_close(conn_rec *c);
    
    AP_DECLARE(int) ap_prep_lingering_close(conn_rec *c);
    
    AP_DECLARE(int) ap_start_lingering_close(conn_rec *c);
    
    /* 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 server The server record to create the connection too.
     * @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.
     * @param alloc The bucket allocator to use for all bucket/brigade creations
     * @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
     */
    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
     */
    AP_DECLARE_HOOK(int,process_connection,(conn_rec *c))
    
    /**
     * This hook implements different protocols.  Before a connection is closed,
     * protocols might have to perform some housekeeping actions, such as 
     * sending one last goodbye packet. The connection is, unless some other
     * error already happened before, still open and operational.
     * All pre-close-connection hooks are run until one returns something 
     * other than ok or decline
     * @param c The connection on which the request has been received.
     * @return OK or DECLINED
     */
    AP_DECLARE_HOOK(int,pre_close_connection,(conn_rec *c))
    
    /**
     * This is a wrapper around ap_run_pre_connection. In case that
     * ap_run_pre_connection returns an error it marks the connection as
     * aborted and ensures that the basic connection setup normally done
     * by the core module is done in case it was not done so far.
     * @param c The connection on which the request has been received.
     *          Same as for the pre_connection hook.
     * @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.
     *            Same as for the pre_connection hook.
     * @return The result of ap_run_pre_connection
     */
    AP_DECLARE(int) ap_pre_connection(conn_rec *c, void *csd);
    
    /** 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
     */
    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
     */
    AP_DECLARE(apr_bucket *) ap_bucket_eoc_create(apr_bucket_alloc_t *list);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_CONNECTION_H */
    /** @} */
    �����������������������������httpd-2.4.64/include/ap_expr.h����������������������������������������������������������������������0000664�0001751�0001751�00000033374�13623622544�016075� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ap_expr.h
     * @brief Expression parser
     *
     * @defgroup AP_EXPR Expression parser
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef AP_EXPR_H
    #define AP_EXPR_H
    
    #include "httpd.h"
    #include "http_config.h"
    #include "ap_regex.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /** A node in the expression parse tree */
    typedef struct ap_expr_node ap_expr_t;
    
    /** Struct describing a parsed expression */
    typedef struct {
        /** The root of the actual expression parse tree */
        ap_expr_t *root_node;
        /** The filename where the expression has been defined (for logging).
         *  May be NULL
         */
        const char *filename;
        /** The line number where the expression has been defined (for logging). */
        unsigned int line_number;
        /** Flags relevant for the expression, see AP_EXPR_FLAG_* */
        unsigned int flags;
        /** The module that is used for loglevel configuration */
        int module_index;
    } ap_expr_info_t;
    
    /** Use ssl_expr compatibility mode (changes the meaning of the comparison
     * operators)
     */
    #define AP_EXPR_FLAG_SSL_EXPR_COMPAT       1
    /** Don't add significant request headers to the Vary response header */
    #define AP_EXPR_FLAG_DONT_VARY             2
    /** Don't allow functions/vars that bypass the current request's access
     *  restrictions or would otherwise leak confidential information.
     *  Used by e.g. mod_include.
     */
    #define AP_EXPR_FLAG_RESTRICTED            4
    /** Expression evaluates to a string, not to a bool */
    #define AP_EXPR_FLAG_STRING_RESULT         8
    
    
    /**
     * Evaluate a parse tree, simple interface
     * @param r The current request
     * @param expr The expression to be evaluated
     * @param err Where an error message should be stored
     * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
     * @note err will be set to NULL on success, or to an error message on error
     * @note request headers used during evaluation will be added to the Vary:
     *       response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
     */
    AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *expr,
                                 const char **err);
    
    /**
     * Evaluate a parse tree, with access to regexp backreference
     * @param r The current request
     * @param expr The expression to be evaluated
     * @param nmatch size of the regex match vector pmatch
     * @param pmatch information about regex matches
     * @param source the string that pmatch applies to
     * @param err Where an error message should be stored
     * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
     * @note err will be set to NULL on success, or to an error message on error
     * @note nmatch/pmatch/source can be used both to make previous matches
     *       available to ap_expr_exec_re and to use ap_expr_exec_re's matches
     *       later on.
     * @note request headers used during evaluation will be added to the Vary:
     *       response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
     */
    AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *expr,
                                    apr_size_t nmatch, ap_regmatch_t *pmatch,
                                    const char **source, const char **err);
    
    /** Context used during evaluation of a parse tree, created by ap_expr_exec */
    typedef struct {
        /** the current request */
        request_rec *r;
        /** the current connection */
        conn_rec *c;
        /** the current virtual host */
        server_rec *s;
        /** the pool to use */
        apr_pool_t *p;
        /** where to store the error string */
        const char **err;
        /** ap_expr_info_t for the expression */
        const ap_expr_info_t *info;
        /** regex match information for back references */
        ap_regmatch_t *re_pmatch;
        /** size of the vector pointed to by re_pmatch */
        apr_size_t re_nmatch;
        /** the string corresponding to the re_pmatch */
        const char **re_source;
        /** A string where the comma separated names of headers are stored
         * to be later added to the Vary: header. If NULL, the caller is not
         * interested in this information.
         */
        const char **vary_this;
        /** where to store the result string */
        const char **result_string;
        /** Arbitrary context data provided by the caller for custom functions */
        void *data;
        /** The current recursion level */
        int reclvl;
    } ap_expr_eval_ctx_t;
    
    /**
     * Evaluate a parse tree, full featured version
     * @param ctx The evaluation context with all data filled in
     * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
     * @note *ctx->err will be set to NULL on success, or to an error message on
     *       error
     * @note request headers used during evaluation will be added to the Vary:
     *       response header if ctx->vary_this is set.
     */
    AP_DECLARE(int) ap_expr_exec_ctx(ap_expr_eval_ctx_t *ctx);
    
    /**
     * Evaluate a parse tree of a string valued expression
     * @param r The current request
     * @param expr The expression to be evaluated
     * @param err Where an error message should be stored
     * @return The result string, NULL on error
     * @note err will be set to NULL on success, or to an error message on error
     * @note request headers used during evaluation will be added to the Vary:
     *       response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
     */
    AP_DECLARE(const char *) ap_expr_str_exec(request_rec *r,
                                              const ap_expr_info_t *expr,
                                              const char **err);
    
    /**
     * Evaluate a parse tree of a string valued expression
     * @param r The current request
     * @param expr The expression to be evaluated
     * @param nmatch size of the regex match vector pmatch
     * @param pmatch information about regex matches
     * @param source the string that pmatch applies to
     * @param err Where an error message should be stored
     * @return The result string, NULL on error
     * @note err will be set to NULL on success, or to an error message on error
     * @note nmatch/pmatch/source can be used both to make previous matches
     *       available to ap_expr_exec_re and to use ap_expr_exec_re's matches
     *       later on.
     * @note request headers used during evaluation will be added to the Vary:
     *       response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
     */
    AP_DECLARE(const char *) ap_expr_str_exec_re(request_rec *r,
                                                 const ap_expr_info_t *expr,
                                                 apr_size_t nmatch,
                                                 ap_regmatch_t *pmatch,
                                                 const char **source,
                                                 const char **err);
    
    
    /**
     * The parser can be extended with variable lookup, functions, and
     * and operators.
     *
     * During parsing, the parser calls the lookup function to resolve a
     * name into a function pointer and an opaque context for the function.
     * If the argument to a function or operator is constant, the lookup function
     * may also parse that argument and store the parsed data in the context.
     *
     * The default lookup function is the hook ::ap_expr_lookup_default which just
     * calls ap_run_expr_lookup. Modules can use it to make functions and
     * variables generally available.
     *
     * An ap_expr consumer can also provide its own custom lookup function to
     * modify the set of variables and functions that are available. The custom
     * lookup function can in turn call 'ap_run_expr_lookup'.
     */
    
    /** Unary operator, takes one string argument and returns a bool value.
     * The name must have the form '-z' (one letter only).
     * @param ctx The evaluation context
     * @param data An opaque context provided by the lookup hook function
     * @param arg The (right) operand
     * @return 0 or 1
     */
    typedef int ap_expr_op_unary_t(ap_expr_eval_ctx_t *ctx, const void *data,
                                   const char *arg);
    
    /** Binary operator, takes two string arguments and returns a bool value.
     * The name must have the form '-cmp' (at least two letters).
     * @param ctx The evaluation context
     * @param data An opaque context provided by the lookup hook function
     * @param arg1 The left operand
     * @param arg2 The right operand
     * @return 0 or 1
     */
    typedef int ap_expr_op_binary_t(ap_expr_eval_ctx_t *ctx, const void *data,
                                    const char *arg1, const char *arg2);
    
    /** String valued function, takes a string argument and returns a string
     * @param ctx The evaluation context
     * @param data An opaque context provided by the lookup hook function
     * @param arg The argument
     * @return The functions result string, may be NULL for 'empty string'
     */
    typedef const char *(ap_expr_string_func_t)(ap_expr_eval_ctx_t *ctx,
                                                const void *data,
                                                const char *arg);
    
    /** List valued function, takes a string argument and returns a list of strings
     * Can currently only be called following the builtin '-in' operator.
     * @param ctx The evaluation context
     * @param data An opaque context provided by the lookup hook function
     * @param arg The argument
     * @return The functions result list of strings, may be NULL for 'empty array'
     */
    typedef apr_array_header_t *(ap_expr_list_func_t)(ap_expr_eval_ctx_t *ctx,
                                                      const void *data,
                                                      const char *arg);
    
    /** Variable lookup function, takes no argument and returns a string
     * @param ctx The evaluation context
     * @param data An opaque context provided by the lookup hook function
     * @return The expanded variable
     */
    typedef const char *(ap_expr_var_func_t)(ap_expr_eval_ctx_t *ctx,
                                             const void *data);
    
    /** parameter struct passed to the lookup hook functions */
    typedef struct {
        /** type of the looked up object */
        int type;
    #define AP_EXPR_FUNC_VAR        0
    #define AP_EXPR_FUNC_STRING     1
    #define AP_EXPR_FUNC_LIST       2
    #define AP_EXPR_FUNC_OP_UNARY   3
    #define AP_EXPR_FUNC_OP_BINARY  4
        /** name of the looked up object */
        const char *name;
    
        int flags;
    
        apr_pool_t *pool;
        apr_pool_t *ptemp;
    
        /** where to store the function pointer */
        const void **func;
        /** where to store the function's context */
        const void **data;
        /** where to store the error message (if any) */
        const char **err;
    
        /** arg for pre-parsing (only if a simple string).
         *  For binary ops, this is the right argument. */
        const char *arg;
    } ap_expr_lookup_parms;
    
    /** Function for looking up the provider function for a variable, operator
     *  or function in an expression.
     *  @param parms The parameter struct, also determines where the result is
     *               stored.
     *  @return OK on success,
     *          !OK on failure,
     *          DECLINED if the requested name is not handled by this function
     */
    typedef int (ap_expr_lookup_fn_t)(ap_expr_lookup_parms *parms);
    
    /** Default lookup function which just calls ap_run_expr_lookup().
     *  ap_run_expr_lookup cannot be used directly because it has the wrong
     *  calling convention under Windows.
     */
    AP_DECLARE_NONSTD(int) ap_expr_lookup_default(ap_expr_lookup_parms *parms);
    
    AP_DECLARE_HOOK(int, expr_lookup, (ap_expr_lookup_parms *parms))
    
    /**
     * Parse an expression into a parse tree
     * @param pool Pool
     * @param ptemp temp pool
     * @param info The ap_expr_info_t struct (with values filled in)
     * @param expr The expression string to parse
     * @param lookup_fn The lookup function to use, NULL for default
     * @return NULL on success, error message on error.
     *         A pointer to the resulting parse tree will be stored in
     *         info->root_node.
     */
    AP_DECLARE(const char *) ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp,
                                           ap_expr_info_t *info, const char *expr,
                                           ap_expr_lookup_fn_t *lookup_fn);
    
    /**
     * High level interface to ap_expr_parse that also creates ap_expr_info_t and
     * uses info from cmd_parms to fill in most of it.
     * @param cmd The cmd_parms struct
     * @param expr The expression string to parse
     * @param flags The flags to use, see AP_EXPR_FLAG_*
     * @param err Set to NULL on success, error message on error
     * @param lookup_fn The lookup function used to lookup vars, functions, and
     *        operators
     * @param module_index The module_index to set for the expression
     * @return The parsed expression
     * @note Usually ap_expr_parse_cmd() should be used
     */
    AP_DECLARE(ap_expr_info_t *) ap_expr_parse_cmd_mi(const cmd_parms *cmd,
                                                      const char *expr,
                                                      unsigned int flags,
                                                      const char **err,
                                                      ap_expr_lookup_fn_t *lookup_fn,
                                                      int module_index);
    
    /**
     * Convenience wrapper for ap_expr_parse_cmd_mi() that sets
     * module_index = APLOG_MODULE_INDEX
     */
    #define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn) \
            ap_expr_parse_cmd_mi(cmd, expr, flags, err, lookup_fn, APLOG_MODULE_INDEX)
    
     /**
      * Internal initialisation of ap_expr (for httpd internal use)
      */
    void ap_expr_init(apr_pool_t *pool);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* AP_EXPR_H */
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_charset.h�����������������������������������������������������������������0000664�0001751�0001751�00000004333�12425122625�017110� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_charset.h
     * @brief charset conversion
     *
     * @defgroup APACHE_CORE_CHARSET Charset Conversion
     * @ingroup  APACHE_CORE
     * 
     * 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.\n
     * For an ASCII machine, they are undefined.
     * 
     * @see ap_init_ebcdic()
     * @{
     */
    
    #ifndef APACHE_UTIL_CHARSET_H
    #define APACHE_UTIL_CHARSET_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include "apr.h"
    
    #if APR_CHARSET_EBCDIC || defined(DOXYGEN)
    
    #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.
     * @note On ASCII system, this variable does <b>not</b> exist.
     * So, its use should be guarded by \#if APR_CHARSET_EBCDIC.
     */
    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.
     * @note On ASCII system, this variable does <b>not</b> exist.
     * So, its use should be guarded by \#if APR_CHARSET_EBCDIC.
     */
    extern apr_xlate_t *ap_hdrs_from_ascii;
    
    #endif  /* APR_CHARSET_EBCDIC */
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_UTIL_CHARSET_H */
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_md5.h���������������������������������������������������������������������0000664�0001751�0001751�00000004167�12361574225�016157� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_md5.h
     * @brief Apache MD5 library
     *
     * @defgroup APACHE_CORE_MD5 MD5 Package Library
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_UTIL_MD5_H
    #define APACHE_UTIL_MD5_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #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
     */
    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
     */
    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
     */
    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
     */
    AP_DECLARE(char *) ap_md5digest(apr_pool_t *p, apr_file_t *infile);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_UTIL_MD5_H */
    /** @} */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_time.h��������������������������������������������������������������������0000664�0001751�0001751�00000010147�14455327713�016427� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_time.h
     * @brief Apache date-time handling functions
     *
     * @defgroup APACHE_CORE_TIME Date-time handling functions
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #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
    
    /* 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
    
    /* Options for ap_recent_ctime_ex */
    /* No extension */
    #define AP_CTIME_OPTION_NONE    0x0
    /* Add sub second timestamps with micro second resolution */
    #define AP_CTIME_OPTION_USEC    0x1
    /* Use more compact ISO 8601 format */
    #define AP_CTIME_OPTION_COMPACT 0x2
    /* Add timezone offset from GMT ([+-]hhmm) */
    #define AP_CTIME_OPTION_GMTOFF  0x4
    
    
    /**
     * 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
     * @note Consider using ap_recent_ctime_ex instead.
     * @return APR_SUCCESS iff successful
     */
    AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t);
    
    
    /**
     * format a recent timestamp in an extended ctime() format.
     * @param date_str String to write to.
     * @param t the time to convert
     * @param option Additional formatting options (AP_CTIME_OPTION_*).
     * @param len Pointer to an int containing the length of the provided buffer.
     *        On successful return it contains the number of bytes written to the
     *        buffer (including trailing NUL byte).
     * @return APR_SUCCESS iff successful, APR_ENOMEM if buffer was to short.
     */
    AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
                                                int option, int *len);
    
    
    /**
     * 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 */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/http_config.h������������������������������������������������������������������0000664�0001751�0001751�00000160566�14205443413�016740� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file http_config.h
     * @brief Apache Configuration
     *
     * @defgroup APACHE_CORE_CONFIG Configuration
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_HTTP_CONFIG_H
    #define APACHE_HTTP_CONFIG_H
    
    #include "util_cfgtree.h"
    #include "ap_config.h"
    #include "apr_tables.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /*
     * 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, occurring 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. &lt;/Directory&gt; */
        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 its own parsing of arguments*/
    # define AP_RAW_ARGS    func.raw_args
    /** This configuration directive will handle its 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
    
    /** mechanism for 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 }
    /** mechanism for 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 }
    /** mechanism for 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 }
    /** mechanism for declaring a directive which takes 1 argument */
    # define AP_INIT_TAKE1(directive, func, mconfig, where, help) \
        { directive, { .take1=func }, mconfig, where, TAKE1, help }
    /** mechanism for declaring a directive which takes multiple arguments */
    # define AP_INIT_ITERATE(directive, func, mconfig, where, help) \
        { directive, { .take1=func }, mconfig, where, ITERATE, help }
    /** mechanism for declaring a directive which takes 2 arguments */
    # define AP_INIT_TAKE2(directive, func, mconfig, where, help) \
        { directive, { .take2=func }, mconfig, where, TAKE2, help }
    /** mechanism for 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 }
    /** mechanism for declaring a directive which takes multiple 2 arguments */
    # define AP_INIT_ITERATE2(directive, func, mconfig, where, help) \
        { directive, { .take2=func }, mconfig, where, ITERATE2, help }
    /** mechanism for 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 }
    /** mechanism for 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 }
    /** mechanism for 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 }
    /** mechanism for declaring a directive which takes 3 arguments */
    # define AP_INIT_TAKE3(directive, func, mconfig, where, help) \
        { directive, { .take3=func }, mconfig, where, TAKE3, help }
    /** mechanism for declaring a directive which takes a flag (on/off) 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.  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 */
        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 &lt;Directory&gt; or &lt;Location&gt;
                                    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 &lt;Directory&gt; or &lt;Location&gt;
                                    and .htaccess when AllowOverride AuthConfig */
    #define OR_INDEXES 16        /**< *.conf anywhere
                                    and .htaccess when AllowOverride Indexes */
    #define OR_UNSET 32          /**< bit to indicate that AllowOverride has not been set */
    #define ACCESS_CONF 64       /**< *.conf inside &lt;Directory&gt; or &lt;Location&gt; */
    #define RSRC_CONF 128        /**< *.conf outside &lt;Directory&gt; or &lt;Location&gt; */
    #define EXEC_ON_READ 256     /**< force directive to execute a command
                    which would modify the configuration (like including another
                    file, or IFModule */
    /* Flags to determine whether syntax errors in .htaccess should be
     * treated as nonfatal (log and ignore errors)
     */
    #define NONFATAL_OVERRIDE 512    /* Violation of AllowOverride rule */
    #define NONFATAL_UNKNOWN 1024    /* Unrecognised directive */
    #define NONFATAL_ALL (NONFATAL_OVERRIDE|NONFATAL_UNKNOWN)
    
    #define PROXY_CONF 2048      /**< *.conf inside &lt;Proxy&gt; only */
    
    /** 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 {
        /**< an apr_file_getc()-like function */
        apr_status_t (*getch) (char *ch, void *param);
        /**< an apr_file_gets()-like function */
        apr_status_t (*getstr) (void *buf, apr_size_t bufsiz, void *param);
        /**< a close handler function */
        apr_status_t (*close) (void *param);
        /**< the argument passed to getch/getstr/close */
        void *param;
        /**< the filename / description */
        const char *name;
        /**< current line number, starting at 1 */
        unsigned line_number;
    };
    
    /**
     * 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 allow-override-opts bits are set */
        int override_opts;
        /** Table of directives allowed per AllowOverrideList */
        apr_table_t *override_list;
        /** Which methods are &lt;Limit&gt;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 existence of &lt;Files&gt;,
         * &lt;Location&gt; 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;
    
    };
    
    /**
     * Flags associated with a module.
     */
    #define AP_MODULE_FLAG_NONE         (0)
    #define AP_MODULE_FLAG_ALWAYS_MERGE (1 << 0)
    
    /**
     * 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
         *  @var 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);
    
        /** A bitmask of AP_MODULE_FLAG_* */
        int flags;
    };
    
    /**
     * The AP_MAYBE_UNUSED macro is used for variable declarations that
     * might potentially exhibit "unused var" warnings on some compilers if
     * left untreated.
     * Since static intializers are not part of the C language (C89), making
     * (void) usage is not possible. However many compiler have proprietary 
     * mechanism to suppress those warnings.  
     */
    #ifdef AP_MAYBE_UNUSED
    #elif defined(__GNUC__)
    # define AP_MAYBE_UNUSED(x) x __attribute__((unused)) 
    #elif defined(__LCLINT__)
    # define AP_MAYBE_UNUSED(x) /*@unused@*/ x  
    #else
    # define AP_MAYBE_UNUSED(x) x
    #endif
        
    /**
     * The APLOG_USE_MODULE macro is used choose which module a file belongs to.
     * This is necessary to allow per-module loglevel configuration.
     *
     * APLOG_USE_MODULE indirectly sets APLOG_MODULE_INDEX and APLOG_MARK.
     *
     * If a module should be backward compatible with versions before 2.3.6,
     * APLOG_USE_MODULE needs to be enclosed in a ifdef APLOG_USE_MODULE block.
     *
     * @param foo name of the module symbol of the current module, without the
     *            trailing "_module" part
     * @see APLOG_MARK
     */
    #define APLOG_USE_MODULE(foo) \
        extern module AP_MODULE_DECLARE_DATA foo##_module;                  \
        AP_MAYBE_UNUSED(static int * const aplog_module_index) = &(foo##_module.module_index)
    
    /**
     * AP_DECLARE_MODULE is a convenience macro that combines a call of
     * APLOG_USE_MODULE with the definition of the module symbol.
     *
     * If a module should be backward compatible with versions before 2.3.6,
     * APLOG_USE_MODULE should be used explicitly instead of AP_DECLARE_MODULE.
     */
    #define AP_DECLARE_MODULE(foo) \
        APLOG_USE_MODULE(foo);                         \
        module AP_MODULE_DECLARE_DATA foo##_module
    
    /**
     * @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 cv 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 their own module-specific
     * data
     * @param cv 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);
    
    /**
     * When module flags have been introduced, and a way to check this.
     */
    #define AP_MODULE_FLAGS_MMN_MAJOR 20120211
    #define AP_MODULE_FLAGS_MMN_MINOR 70
    #define AP_MODULE_HAS_FLAGS(m) \
            AP_MODULE_MAGIC_AT_LEAST(AP_MODULE_FLAGS_MMN_MAJOR, \
                                     AP_MODULE_FLAGS_MMN_MINOR)
    /**
     * Generic accessor for the module's flags
     * @param m The module to get the flags from.
     * @return The module-specific flags
     */
    AP_DECLARE(int) ap_get_module_flags(const module *m);
    
    #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 accessor for modules to get the module-specific loglevel
     * @param s The server from which to get the loglevel.
     * @param index The module_index of the module to get the loglevel for.
     * @return The module-specific loglevel
     */
    AP_DECLARE(int) ap_get_server_module_loglevel(const server_rec *s, int index);
    
    /**
     * Generic accessor for modules the module-specific loglevel
     * @param c The connection from which to get the loglevel.
     * @param index The module_index of the module to get the loglevel for.
     * @return The module-specific loglevel
     */
    AP_DECLARE(int) ap_get_conn_module_loglevel(const conn_rec *c, int index);
    
    /**
     * Generic accessor for modules the module-specific loglevel
     * @param c The connection from which to get the loglevel.
     * @param s The server from which to get the loglevel if c does not have a
     *          specific loglevel configuration.
     * @param index The module_index of the module to get the loglevel for.
     * @return The module-specific loglevel
     */
    AP_DECLARE(int) ap_get_conn_server_module_loglevel(const conn_rec *c,
                                                       const server_rec *s,
                                                       int index);
    
    /**
     * Generic accessor for modules to get the module-specific loglevel
     * @param r The request from which to get the loglevel.
     * @param index The module_index of the module to get the loglevel for.
     * @return The module-specific loglevel
     */
    AP_DECLARE(int) ap_get_request_module_loglevel(const request_rec *r, int index);
    
    /**
     * Accessor to set module-specific loglevel
     * @param p A pool
     * @param l The ap_logconf struct to modify.
     * @param index The module_index of the module to set the loglevel for.
     * @param level The new log level
     */
    AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *p, struct ap_logconf *l,
                                            int index, int level);
    
    #if !defined(AP_DEBUG)
    
    #define ap_get_conn_logconf(c)                     \
        ((c)->log             ? (c)->log             : \
         &(c)->base_server->log)
    
    #define ap_get_conn_server_logconf(c,s)                             \
        ( ( (c)->log != &(c)->base_server->log && (c)->log != NULL )  ? \
          (c)->log                                                    : \
          &(s)->log )
    
    #define ap_get_request_logconf(r)                  \
        ((r)->log             ? (r)->log             : \
         (r)->connection->log ? (r)->connection->log : \
         &(r)->server->log)
    
    #define ap_get_module_loglevel(l,i)                                     \
        (((i) < 0 || (l)->module_levels == NULL || (l)->module_levels[i] < 0) ?  \
         (l)->level :                                                         \
         (l)->module_levels[i])
    
    #define ap_get_server_module_loglevel(s,i)  \
        (ap_get_module_loglevel(&(s)->log,i))
    
    #define ap_get_conn_module_loglevel(c,i)  \
        (ap_get_module_loglevel(ap_get_conn_logconf(c),i))
    
    #define ap_get_conn_server_module_loglevel(c,s,i)  \
        (ap_get_module_loglevel(ap_get_conn_server_logconf(c,s),i))
    
    #define ap_get_request_module_loglevel(r,i)  \
        (ap_get_module_loglevel(ap_get_request_logconf(r),i))
    
    #endif /* AP_DEBUG */
    
    /**
     * Set all module-specific loglevels to val
     * @param l The log config for which to set the loglevels.
     * @param val the value to set all loglevels to
     */
    AP_DECLARE(void) ap_reset_module_loglevels(struct ap_logconf *l, int val);
    
    /**
     * 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);
    
    /**
     * Parsing function for log level
     * @param str The string to parse
     * @param val The parsed log level
     * @return An error string or NULL on success
     */
    AP_DECLARE(const char *) ap_parse_log_level(const char *str, int *val);
    
    /**
     * Return true if the specified method is limited by being listed in
     * a &lt;Limit&gt; container, or by *not* being listed in a &lt;LimitExcept&gt;
     * 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 stored in an int
     * @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 flags stored in a char
     * @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_char(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
     * @note This allows simple declarations such as:
     * @code
     *     AP_INIT_RAW_ARGS("Foo", ap_set_deprecated, NULL, OR_ALL,
     *         "The Foo directive is no longer supported, use Bar"),
     * @endcode
     */
    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);
    
    /**
     * Compute the name of a run-time file (e.g., shared memory "file") relative
     * to the appropriate run-time directory.  Absolute paths are returned as-is.
     * The run-time directory is configured via the DefaultRuntimeDir directive or
     * at build time.
     */
    AP_DECLARE(char *) ap_runtime_dir_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
     * @param s The module's symbol name (used for logging)
     */
    AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p,
                                           const char *s);
    
    /**
     * 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 mod The module structure of the module to add
     * @param p The pool with the same lifetime as the module
     * @param s The module's symbol name (used for logging)
     */
    AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p,
                                                  const char *s);
    /**
     * Remove a module from the chained modules list and the list of loaded modules
     * @param mod 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 the short name of the module identified by the specified module index
     * @param module_index The module index to get the name for
     * @return the name of the module, NULL if not found
     */
    AP_DECLARE(const char *) ap_find_module_short_name(int module_index);
    /**
     * 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,
        apr_status_t (*getc_func) (char *ch, void *param),
        apr_status_t (*gets_func) (void *buf, apr_size_t bufsiz, void *param),
        apr_status_t (*close_func) (void *param));
    
    /**
     * Read one line from open ap_configfile_t, strip leading and trailing
     * whitespace, increase line number
     * @param buf place to store the line read
     * @param bufsize size of the buffer
     * @param cfp File to read from
     * @return error status, APR_ENOSPC if bufsize is too small for the line
     */
    AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp);
    
    /**
     * Read one char from open configfile_t, increase line number upon LF
     * @param ch place to store the char read
     * @param cfp The file to read from
     * @return error status
     */
    AP_DECLARE(apr_status_t) ap_cfg_getc(char *ch, ap_configfile_t *cfp);
    
    /**
     * Detach from open ap_configfile_t, calling the close handler
     * @param cfp The file to close
     * @return 1 on success, 0 on failure
     */
    AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp);
    
    /**
     * Convert a return value from ap_cfg_getline or ap_cfg_getc to a user friendly
     * string.
     * @param p The pool to allocate the string from
     * @param cfp The config file
     * @param rc The return value to convert
     * @return The error string, NULL if rc == APR_SUCCESS
     */
    AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp,
                                              apr_status_t rc);
    
    /**
     * Read all data between the current &lt;foo&gt; and the matching &lt;/foo&gt;.  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
     * @note If cmd->pool == cmd->temp_pool, ap_soak_end_container() will assume
     *       .htaccess context and use a lower maximum line length.
     */
    AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive);
    
    /**
     * Read all data between the current &lt;foo&gt; and the matching &lt;/foo&gt; 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
     * @note If p == temp_pool, ap_build_cont_config() will assume .htaccess
     *       context and use a lower maximum line length.
    */
    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 error, NULL otherwise
     * @note If conf_pool == temp_pool, ap_build_config() will assume .htaccess
     *       context and use a lower maximum line length.
     */
    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);
    
    /**
     * Convenience function to create a ap_dir_match_t structure from a cmd_parms.
     *
     * @param cmd The command.
     * @param flags Flags to indicate whether optional or recursive.
     * @param cb Callback for each file found that matches the wildcard. Return NULL on
     *        success, an error string on error.
     * @param ctx Context for the callback.
     * @return Structure ap_dir_match_t with fields populated, allocated from the
     *         cmd->temp_pool.
     */
    AP_DECLARE(ap_dir_match_t *)ap_dir_cfgmatch(cmd_parms *cmd, int flags,
            const char *(*cb)(ap_dir_match_t *w, const char *fname), void *ctx)
            __attribute__((nonnull(1,3)));
    
    /**
     * @defgroup ap_check_cmd_context Check command 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 &lt;VirtualHost&gt; */
    #define  NOT_IN_LIMIT           0x02 /**< Forbidden in &lt;Limit&gt; */
    #define  NOT_IN_DIRECTORY       0x04 /**< Forbidden in &lt;Directory&gt; */
    #define  NOT_IN_LOCATION        0x08 /**< Forbidden in &lt;Location&gt; */
    #define  NOT_IN_FILES           0x10 /**< Forbidden in &lt;Files&gt; or &lt;If&gt;*/
    #define  NOT_IN_HTACCESS        0x20 /**< Forbidden in .htaccess files */
    #define  NOT_IN_PROXY           0x40 /**< Forbidden in &lt;Proxy&gt; */
    /** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;*/
    #define  NOT_IN_DIR_LOC_FILE    (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
    /** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;&lt;Proxy&gt;*/
    #define  NOT_IN_DIR_CONTEXT     (NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE|NOT_IN_PROXY)
    /** Forbidden in &lt;VirtualHost&gt;/&lt;Limit&gt;/&lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;/&lt;If&gt;&lt;Proxy&gt;*/
    #define  GLOBAL_ONLY            (NOT_IN_VIRTUALHOST|NOT_IN_DIR_CONTEXT)
    
    /** @} */
    
    /**
     * @brief 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
     * @var module *ap_top_module
     */
    AP_DECLARE_DATA extern module *ap_top_module;
    
    /**
     * Array of all statically linked modules
     * @var module *ap_prelinked_modules[]
     */
    AP_DECLARE_DATA extern module *ap_prelinked_modules[];
    /**
     * Array of all statically linked modulenames (symbols)
     * @var ap_module_symbol_t ap_prelinked_module_symbols[]
     */
    AP_DECLARE_DATA extern ap_module_symbol_t ap_prelinked_module_symbols[];
    /**
     * Array of all preloaded modules
     * @var module *ap_preloaded_modules[]
     */
    AP_DECLARE_DATA extern module *ap_preloaded_modules[];
    /**
     * Array of all loaded modules
     * @var 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);
    
    /**
     * Returns non-zero if a configuration directive of the given name has
     * been registered by a module at the time of calling.
     * @param p Pool for temporary allocations
     * @param name Directive name
     */
    AP_DECLARE(int) ap_exists_directive(apr_pool_t *p, const char *name);
    
    /**
     * 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 from
     * @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);
    
    /**
     * Reserve some modules slots for modules loaded by other means than
     * EXEC_ON_READ directives.
     * Relevant modules should call this in the pre_config stage.
     * @param count The number of slots to reserve.
     */
    AP_DECLARE(void) ap_reserve_module_slots(int count);
    
    /**
     * Reserve some modules slots for modules loaded by a specific
     * non-EXEC_ON_READ config directive.
     * This counts how often the given directive is used in the config and calls
     * ap_reserve_module_slots() accordingly.
     * @param directive The name of the directive
     */
    AP_DECLARE(void) ap_reserve_module_slots_directive(const char *directive);
    
    /* 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_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);
    
    /**
     * Allocate new ap_logconf and make (deep) copy of old ap_logconf
     * @param p The pool to alloc from
     * @param old The ap_logconf to copy (may be NULL)
     * @return The new ap_logconf struct
     */
    AP_DECLARE(struct ap_logconf *) ap_new_log_config(apr_pool_t *p,
                                                      const struct ap_logconf *old);
    
    /**
     * Merge old ap_logconf into new ap_logconf.
     * old and new must have the same life time.
     * @param old_conf The ap_logconf to merge from
     * @param new_conf The ap_logconf to merge into
     */
    AP_DECLARE(void) ap_merge_log_config(const struct ap_logconf *old_conf,
                                         struct ap_logconf *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... (&lt;Directory&gt; command and virtual hosts) */
    
    /**
     * parse an htaccess file
     * @param result htaccess_result
     * @param r The request currently being served
     * @param override Which overrides are active
     * @param override_opts Which allow-override-opts bits are set
     * @param override_list Table of directives allowed for override
     * @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,
                                           apr_table_t *override_list,
                                           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 a 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 ptemp 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 matching files as Apache configs
     * @param s The server rec to use for the command parms
     * @param fname The filename pattern of the config file
     * @param conftree The root node of the created config tree
     * @param p Pool for general allocation
     * @param ptemp Pool for temporary allocation
     * @param optional Whether a no-match wildcard is allowed
     * @see apr_fnmatch for pattern handling
     */
    AP_DECLARE(const char *) ap_process_fnmatch_configs(server_rec *s,
                                                        const char *fname,
                                                        ap_directive_t **conftree,
                                                        apr_pool_t *p,
                                                        apr_pool_t *ptemp,
                                                        int optional);
    
    /**
     * 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);
    
    /**
     * Store data which will be retained across unload/load of modules
     * @param key The unique key associated with this module's retained data
     * @param size in bytes of the retained data (to be allocated)
     * @return Address of new retained data structure, initially cleared
     */
    AP_DECLARE(void *) ap_retained_data_create(const char *key, apr_size_t size);
    
    /**
     * Retrieve data which was stored by ap_retained_data_create()
     * @param key The unique key associated with this module's retained data
     * @return Address of previously retained data structure, or NULL if not yet saved
     */
    AP_DECLARE(void *) ap_retained_data_get(const char *key);
    
    /* 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 of modules.
     * @param cmd_name The directive to search for
     * @param mod Pointer to the first module in the linked list; will be set to
     *            the module providing cmd_name
     * @return The directive definition of the specified directive.
     *         *mod will be changed to point to the module containing the
     *         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);
    
      /* Hooks */
    
    /**
     * Run the header parser functions for each module
     * @param r The current request
     * @return OK or DECLINED
     * @ingroup hooks
     */
    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
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int,pre_config,(apr_pool_t *pconf,apr_pool_t *plog,
                                    apr_pool_t *ptemp))
    
    /**
     * Run the check_config function for each module
     * @param pconf The config pool
     * @param plog The logging streams pool
     * @param ptemp The temporary pool
     * @param s the server to operate upon
     * @return OK or DECLINED on success anything else is a error
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(int,check_config,(apr_pool_t *pconf, apr_pool_t *plog,
                                      apr_pool_t *ptemp, server_rec *s))
    
    /**
     * 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
     * @note To avoid reordering problems due to different buffering, hook
     *       functions should only apr_file_*() to print to stdout/stderr and
     *       not simple printf()/fprintf().
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(void,test_config,(apr_pool_t *pconf, server_rec *s))
    
    /**
     * Run the post_config function for each module
     *
     * The function might be called multiple times.  @a pconf, @a plog, and
     * @a ptemp may be cleared and/or destroyed between calls.
     *
     * The function will be called zero or one times with the server's state being
     * #AP_SQ_MS_CREATE_PRE_CONFIG, and will be called one or more times with
     * the server's state being #AP_SQ_MS_CREATE_CONFIG.
     *
     * @see ap_state_query(), #AP_SQ_MAIN_STATE
     *
     * @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
     * @ingroup hooks
     */
    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
     * @ingroup hooks
     */
    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
     * @ingroup hooks
     */
    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
     * @ingroup hooks
     */
    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()
     * @ingroup hooks
     */
    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.
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(void,optional_fn_retrieve,(void))
    
    /**
     * Allow modules to open htaccess files or perform operations before doing so
     * @param r The current request
     * @param dir_name The directory for which the htaccess file should be opened
     * @param access_name The filename  for which the htaccess file should be opened
     * @param conffile Where the pointer to the opened ap_configfile_t must be
     *        stored
     * @param full_name Where the full file name of the htaccess file must be
     *        stored.
     * @return APR_SUCCESS on success,
     *         APR_ENOENT or APR_ENOTDIR if no htaccess file exists,
     *         AP_DECLINED to let later modules do the opening,
     *         any other error code on error.
     * @ingroup hooks
     */
    AP_DECLARE_HOOK(apr_status_t,open_htaccess,
                    (request_rec *r, const char *dir_name, const char *access_name,
                     ap_configfile_t **conffile, const char **full_name))
    
    /**
     * Core internal function, use ap_run_open_htaccess() instead.
     */
    apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name,
            const char *access_name, ap_configfile_t **conffile,
            const char **full_name);
    
    /**
     * A generic pool cleanup that will reset a pointer to NULL. For use with
     * apr_pool_cleanup_register.
     * @param data The address of the pointer
     * @return APR_SUCCESS
     */
    AP_DECLARE_NONSTD(apr_status_t) ap_pool_cleanup_set_null(void *data);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_CONFIG_H */
    /** @} */
    ������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/http_vhost.h�������������������������������������������������������������������0000664�0001751�0001751�00000010761�14053714705�016633� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  http_vhost.h
     * @brief Virtual Host package
     *
     * @defgroup APACHE_CORE_VHOST Virtual Host Package
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_HTTP_VHOST_H
    #define APACHE_HTTP_VHOST_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * 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
     */
    AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_server);
    
    /**
     * handle addresses in "<VirtualHost>" 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
     * @param cmd Command Parameters structure
     * @param dummy NOT USED
     * @param arg a host of the form "<address>[:port]"
     */
    AP_DECLARE_NONSTD(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);
    
    /**
     * Updates r->server with the best name-based virtual host match, within
     * the chain of matching virtual hosts selected by ap_update_vhost_given_ip.
     * @param r The current request
     * @param require_match 1 to return an HTTP error if the requested hostname is
     * not explicitly matched to a VirtualHost. 
     * @return return HTTP_OK unless require_match was specified and the requested
     * hostname did not match any ServerName, ServerAlias, or VirtualHost 
     * address-spec.
     */
    AP_DECLARE(int) ap_update_vhost_from_headers_ex(request_rec *r, int require_match);
    
    
    /**
     * 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
     */
    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 */
    /** @} */
    ���������������httpd-2.4.64/include/http_log.h���������������������������������������������������������������������0000664�0001751�0001751�00000110007�12757564422�016253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  http_log.h
     * @brief Apache Logging library
     *
     * @defgroup APACHE_CORE_LOG Logging library
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_HTTP_LOG_H
    #define APACHE_HTTP_LOG_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include "apr_thread_proc.h"
    #include "http_config.h"
    
    #ifdef HAVE_SYSLOG
    #include <syslog.h>
    
    #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_TRACE1   (LOG_DEBUG + 1)  /* trace-level 1 messages */
    #define APLOG_TRACE2   (LOG_DEBUG + 2)  /* trace-level 2 messages */
    #define APLOG_TRACE3   (LOG_DEBUG + 3)  /* trace-level 3 messages */
    #define APLOG_TRACE4   (LOG_DEBUG + 4)  /* trace-level 4 messages */
    #define APLOG_TRACE5   (LOG_DEBUG + 5)  /* trace-level 5 messages */
    #define APLOG_TRACE6   (LOG_DEBUG + 6)  /* trace-level 6 messages */
    #define APLOG_TRACE7   (LOG_DEBUG + 7)  /* trace-level 7 messages */
    #define APLOG_TRACE8   (LOG_DEBUG + 8)  /* trace-level 8 messages */
    
    #define APLOG_LEVELMASK 15     /* 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_TRACE1     8     /* trace-level 1 messages */
    #define APLOG_TRACE2     9     /* trace-level 2 messages */
    #define APLOG_TRACE3    10     /* trace-level 3 messages */
    #define APLOG_TRACE4    11     /* trace-level 4 messages */
    #define APLOG_TRACE5    12     /* trace-level 5 messages */
    #define APLOG_TRACE6    13     /* trace-level 6 messages */
    #define APLOG_TRACE7    14     /* trace-level 7 messages */
    #define APLOG_TRACE8    15     /* trace-level 8 messages */
    
    #define APLOG_LEVELMASK 15     /* 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
    
    /**
     * APLOGNO() should be used at the start of the format string passed
     * to ap_log_error() and friends. The argument must be a 5 digit decimal
     * number. It creates a tag of the form "AH02182: "
     * See docs/log-message-tags/README for details.
     */
    #define APLOGNO(n)              "AH" #n ": "
    
    /**
     * APLOG_NO_MODULE may be passed as module_index to ap_log_error() and related
     * functions if the module causing the log message is not known. Normally this
     * should not be used directly. Use ::APLOG_MARK or ::APLOG_MODULE_INDEX
     * instead.
     *
     * @see APLOG_MARK
     * @see APLOG_MODULE_INDEX
     * @see ap_log_error
     */
    #define APLOG_NO_MODULE         -1
    
    #ifdef __cplusplus
    /**
     * C++ modules must invoke ::APLOG_USE_MODULE or ::AP_DECLARE_MODULE in
     * every file which uses ap_log_* before the first use of ::APLOG_MARK
     * or ::APLOG_MODULE_INDEX.
     * (C modules *should* do that as well, to enable module-specific log
     * levels. C modules need not obey the ordering, though).
     */
    #else /* __cplusplus */
    /**
     * Constant to store module_index for the current file.
     * Objects with static storage duration are set to NULL if not
     * initialized explicitly. This means that if aplog_module_index
     * is not initialized using the ::APLOG_USE_MODULE or the
     * ::AP_DECLARE_MODULE macro, we can safely fall back to
     * use ::APLOG_NO_MODULE. This variable will usually be optimized away.
     */
    static int * const aplog_module_index;
    #endif /* __cplusplus */
    
    /**
     * APLOG_MODULE_INDEX contains the module_index of the current module if
     * it has been set via the ::APLOG_USE_MODULE or ::AP_DECLARE_MODULE macro.
     * Otherwise it contains ::APLOG_NO_MODULE (for example in unmodified httpd
     * 2.2 modules).
     *
     * If ::APLOG_MARK is used in ap_log_error() and related functions,
     * ::APLOG_MODULE_INDEX will be passed as module_index. In cases where
     * ::APLOG_MARK cannot be used, ::APLOG_MODULE_INDEX should normally be passed
     * as module_index.
     *
     * @see APLOG_MARK
     * @see ap_log_error
     */
    #ifdef __cplusplus
    #define APLOG_MODULE_INDEX (*aplog_module_index)
    #else /* __cplusplus */
    #define APLOG_MODULE_INDEX  \
        (aplog_module_index ? *aplog_module_index : APLOG_NO_MODULE)
    #endif /* __cplusplus */
    
    /**
     * APLOG_MAX_LOGLEVEL can be defined to remove logging above some
     * specified level at compile time.
     *
     * This requires a C99 compiler.
     */
    #ifdef DOXYGEN
    #define APLOG_MAX_LOGLEVEL
    #endif
    #ifndef APLOG_MAX_LOGLEVEL
    #define APLOG_MODULE_IS_LEVEL(s,module_index,level)              \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
                (s == NULL) ||                                       \
                (ap_get_server_module_loglevel(s, module_index)      \
                 >= ((level)&APLOG_LEVELMASK) ) )
    #define APLOG_C_MODULE_IS_LEVEL(c,module_index,level)            \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
                (ap_get_conn_module_loglevel(c, module_index)        \
                 >= ((level)&APLOG_LEVELMASK) ) )
    #define APLOG_CS_MODULE_IS_LEVEL(c,s,module_index,level)            \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||          \
                (ap_get_conn_server_module_loglevel(c, s, module_index) \
                 >= ((level)&APLOG_LEVELMASK) ) )
    #define APLOG_R_MODULE_IS_LEVEL(r,module_index,level)            \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
                (ap_get_request_module_loglevel(r, module_index)     \
                 >= ((level)&APLOG_LEVELMASK) ) )
    #else
    #define APLOG_MODULE_IS_LEVEL(s,module_index,level)              \
            ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) &&   \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
                (s == NULL) ||                                       \
                (ap_get_server_module_loglevel(s, module_index)      \
                 >= ((level)&APLOG_LEVELMASK) ) ) )
    #define APLOG_CS_MODULE_IS_LEVEL(c,s,module_index,level)            \
            ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) &&      \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||          \
                (ap_get_conn_server_module_loglevel(c, s, module_index) \
                 >= ((level)&APLOG_LEVELMASK) ) ) )
    #define APLOG_C_MODULE_IS_LEVEL(c,module_index,level)            \
            ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) &&   \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
                (ap_get_conn_module_loglevel(c, module_index)        \
                 >= ((level)&APLOG_LEVELMASK) ) ) )
    #define APLOG_R_MODULE_IS_LEVEL(r,module_index,level)            \
            ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) &&   \
              ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
                (ap_get_request_module_loglevel(r, module_index)     \
                 >= ((level)&APLOG_LEVELMASK) ) ) )
    #endif
    
    #define APLOG_IS_LEVEL(s,level)     \
        APLOG_MODULE_IS_LEVEL(s,APLOG_MODULE_INDEX,level)
    #define APLOG_C_IS_LEVEL(c,level)   \
        APLOG_C_MODULE_IS_LEVEL(c,APLOG_MODULE_INDEX,level)
    #define APLOG_CS_IS_LEVEL(c,s,level) \
        APLOG_CS_MODULE_IS_LEVEL(c,s,APLOG_MODULE_INDEX,level)
    #define APLOG_R_IS_LEVEL(r,level)   \
        APLOG_R_MODULE_IS_LEVEL(r,APLOG_MODULE_INDEX,level)
    
    
    #define APLOGinfo(s)                APLOG_IS_LEVEL(s,APLOG_INFO)
    #define APLOGdebug(s)               APLOG_IS_LEVEL(s,APLOG_DEBUG)
    #define APLOGtrace1(s)              APLOG_IS_LEVEL(s,APLOG_TRACE1)
    #define APLOGtrace2(s)              APLOG_IS_LEVEL(s,APLOG_TRACE2)
    #define APLOGtrace3(s)              APLOG_IS_LEVEL(s,APLOG_TRACE3)
    #define APLOGtrace4(s)              APLOG_IS_LEVEL(s,APLOG_TRACE4)
    #define APLOGtrace5(s)              APLOG_IS_LEVEL(s,APLOG_TRACE5)
    #define APLOGtrace6(s)              APLOG_IS_LEVEL(s,APLOG_TRACE6)
    #define APLOGtrace7(s)              APLOG_IS_LEVEL(s,APLOG_TRACE7)
    #define APLOGtrace8(s)              APLOG_IS_LEVEL(s,APLOG_TRACE8)
    
    #define APLOGrinfo(r)               APLOG_R_IS_LEVEL(r,APLOG_INFO)
    #define APLOGrdebug(r)              APLOG_R_IS_LEVEL(r,APLOG_DEBUG)
    #define APLOGrtrace1(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE1)
    #define APLOGrtrace2(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE2)
    #define APLOGrtrace3(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE3)
    #define APLOGrtrace4(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE4)
    #define APLOGrtrace5(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE5)
    #define APLOGrtrace6(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE6)
    #define APLOGrtrace7(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE7)
    #define APLOGrtrace8(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE8)
    
    #define APLOGcinfo(c)               APLOG_C_IS_LEVEL(c,APLOG_INFO)
    #define APLOGcdebug(c)              APLOG_C_IS_LEVEL(c,APLOG_DEBUG)
    #define APLOGctrace1(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE1)
    #define APLOGctrace2(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE2)
    #define APLOGctrace3(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE3)
    #define APLOGctrace4(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE4)
    #define APLOGctrace5(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE5)
    #define APLOGctrace6(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE6)
    #define APLOGctrace7(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE7)
    #define APLOGctrace8(c)             APLOG_C_IS_LEVEL(c,APLOG_TRACE8)
    
    AP_DECLARE_DATA extern int ap_default_loglevel;
    
    /**
     * APLOG_MARK is a convenience macro for use as the first three parameters in
     * ap_log_error() and related functions, i.e. file, line, and module_index.
     *
     * The module_index parameter was introduced in version 2.3.6. Before that
     * version, APLOG_MARK only replaced the file and line parameters.
     * This means that APLOG_MARK can be used with ap_log_*error in all versions
     * of Apache httpd.
     *
     * @see APLOG_MODULE_INDEX
     * @see ap_log_error
     * @see ap_log_cerror
     * @see ap_log_rerror
     * @see ap_log_cserror
     */
    #define APLOG_MARK     __FILE__,__LINE__,APLOG_MODULE_INDEX
    
    /**
     * 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
     * @note 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);
    
    /**
     * Perform special processing for piped loggers in MPM child
     * processes.
     * @param p Not used
     * @param s Not used
     * @note 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);
    
    /*
     * 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 module_index The module_index of the module generating this message
     * @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.
     * @note ap_log_error is implemented as a macro
     * @note Use APLOG_MARK to fill out file and line
     * @note 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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_error(const char *file, int line, int module_index,
                                  int level, apr_status_t status,
                                  const server_rec *s, const char *fmt, ...);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_error(...) ap_log_error__(__VA_ARGS__)
    /* need server_rec *sr = ... for the case if s is verbatim NULL */
    #define ap_log_error__(file, line, mi, level, status, s, ...)           \
        do { const server_rec *sr__ = s; if (APLOG_MODULE_IS_LEVEL(sr__, mi, level)) \
                 ap_log_error_(file, line, mi, level, status, sr__, __VA_ARGS__);    \
        } while(0)
    #else
    #define ap_log_error ap_log_error_
    #endif
    AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index,
                                   int level, apr_status_t status,
                                   const server_rec *s, const char *fmt, ...)
                                  __attribute__((format(printf,7,8)));
    #endif
    
    /**
     * 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 module_index ignored dummy value for use by APLOG_MARK
     * @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.
     * @note ap_log_perror is implemented as a macro
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_perror(const char *file, int line, int module_index,
                                   int level, apr_status_t status, apr_pool_t *p,
                                   const char *fmt, ...);
    #else
    #if defined(AP_HAVE_C99) && defined(APLOG_MAX_LOGLEVEL)
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_perror(...) ap_log_perror__(__VA_ARGS__)
    #define ap_log_perror__(file, line, mi, level, status, p, ...)            \
        do { if ((level) <= APLOG_MAX_LOGLEVEL )                              \
                 ap_log_perror_(file, line, mi, level, status, p,             \
                                __VA_ARGS__); } while(0)
    #else
    #define ap_log_perror ap_log_perror_
    #endif
    AP_DECLARE(void) ap_log_perror_(const char *file, int line, int module_index,
                                    int level, apr_status_t status, apr_pool_t *p,
                                    const char *fmt, ...)
                                   __attribute__((format(printf,7,8)));
    #endif
    
    /**
     * ap_log_rerror() - log messages which are related to a particular
     * request.  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 module_index The module_index of the module generating this message
     * @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.
     * @note ap_log_rerror is implemented as a macro
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_rerror(const char *file, int line, int module_index,
                                   int level, apr_status_t status,
                                   const request_rec *r, const char *fmt, ...);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_rerror(...) ap_log_rerror__(__VA_ARGS__)
    #define ap_log_rerror__(file, line, mi, level, status, r, ...)              \
        do { if (APLOG_R_MODULE_IS_LEVEL(r, mi, level))                         \
                 ap_log_rerror_(file, line, mi, level, status, r, __VA_ARGS__); \
        } while(0)
    #else
    #define ap_log_rerror ap_log_rerror_
    #endif
    AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
                                    int level, apr_status_t status,
                                    const request_rec *r, const char *fmt, ...)
                                    __attribute__((format(printf,7,8)));
    #endif
    
    /**
     * ap_log_cerror() - log messages which are related to a particular
     * 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 module_index The module_index of the module generating this 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.
     * @note ap_log_cerror is implemented as a macro
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @note 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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_cerror(const char *file, int line, int module_index,
                                   int level, apr_status_t status,
                                   const conn_rec *c, const char *fmt, ...);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_cerror(...) ap_log_cerror__(__VA_ARGS__)
    #define ap_log_cerror__(file, line, mi, level, status, c, ...)              \
        do { if (APLOG_C_MODULE_IS_LEVEL(c, mi, level))                         \
                 ap_log_cerror_(file, line, mi, level, status, c, __VA_ARGS__); \
        } while(0)
    #else
    #define ap_log_cerror ap_log_cerror_
    #endif
    AP_DECLARE(void) ap_log_cerror_(const char *file, int line, int module_index,
                                    int level, apr_status_t status,
                                    const conn_rec *c, const char *fmt, ...)
                                    __attribute__((format(printf,7,8)));
    #endif
    
    /**
     * ap_log_cserror() - log messages which are related to a particular
     * connection and to a vhost other than c->base_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 module_index The module_index of the module generating this message
     * @param status The status code from the previous command
     * @param c The connection which we are logging for
     * @param s The server which we are logging for
     * @param fmt The format string
     * @param ... The arguments to use to fill out fmt.
     * @note ap_log_cserror is implemented as a macro
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @note If a request_rec is available, use that with ap_log_rerror()
     * in preference to calling this function. This function is mainly useful for
     * modules like mod_ssl to use before the request_rec is created.
     * @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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_cserror(const char *file, int line, int module_index,
                                    int level, apr_status_t status,
                                    const conn_rec *c, const server_rec *s,
                                    const char *fmt, ...);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_cserror(...) ap_log_cserror__(__VA_ARGS__)
    #define ap_log_cserror__(file, line, mi, level, status, c, s, ...)  \
        do { if (APLOG_CS_MODULE_IS_LEVEL(c, s, mi, level))             \
                 ap_log_cserror_(file, line, mi, level, status, c, s,   \
                                 __VA_ARGS__);                          \
        } while(0)
    #else
    #define ap_log_cserror ap_log_cserror_
    #endif
    AP_DECLARE(void) ap_log_cserror_(const char *file, int line, int module_index,
                                     int level, apr_status_t status,
                                     const conn_rec *c, const server_rec *s,
                                     const char *fmt, ...)
                                 __attribute__((format(printf,8,9)));
    #endif
    
    /*
     * The buffer logging functions, ap_log_data, ap_log_rdata, ap_log_cdata,
     * and ap_log_csdata log a buffer in printable and hex format.  The exact
     * format is controlled by processing flags, described next.
     */
    
    /**
     * Processing flags for ap_log_data() et al
     *
     * AP_LOG_DATA_DEFAULT - default formatting, with printable chars and hex
     * AP_LOG_DATA_SHOW_OFFSET - prefix each line with hex offset from the start
     * of the buffer
     */
    #define AP_LOG_DATA_DEFAULT       0
    #define AP_LOG_DATA_SHOW_OFFSET   1
    
    /**
     * ap_log_data() - log buffers which are not related to a particular request
     * or connection.
     * @param file The file in which this function is called
     * @param line The line number on which this function is called
     * @param module_index The module_index of the module logging this buffer
     * @param level The log level
     * @param s The server on which we are logging
     * @param label A label for the buffer, to be logged preceding the buffer
     * @param data The buffer to be logged
     * @param len The length of the buffer
     * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
     * @note ap_log_data is implemented as a macro.
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @note If a request_rec is available, use that with ap_log_rdata()
     * in preference to calling this function.  Otherwise, if a conn_rec is
     * available, use that with ap_log_cdata() in preference to calling
     * this function.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_data(const char *file, int line, int module_index,
                                 int level, const server_rec *s, const char *label,
                                 const void *data, apr_size_t len, unsigned int flags);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_data(...) ap_log_data__(__VA_ARGS__)
    /* need server_rec *sr = ... for the case if s is verbatim NULL */
    #define ap_log_data__(file, line, mi, level, s, ...)           \
        do { const server_rec *sr__ = s; if (APLOG_MODULE_IS_LEVEL(sr__, mi, level)) \
                 ap_log_data_(file, line, mi, level, sr__, __VA_ARGS__);    \
        } while(0)
    #else
    #define ap_log_data ap_log_data_
    #endif
    AP_DECLARE(void) ap_log_data_(const char *file, int line, int module_index,
                                  int level, const server_rec *s, const char *label,
                                  const void *data, apr_size_t len, unsigned int flags);
    #endif
    
    /**
     * ap_log_rdata() - log buffers which are related to a particular request.
     * @param file The file in which this function is called
     * @param line The line number on which this function is called
     * @param module_index The module_index of the module logging this buffer
     * @param level The log level
     * @param r The request which we are logging for
     * @param label A label for the buffer, to be logged preceding the buffer
     * @param data The buffer to be logged
     * @param len The length of the buffer
     * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
     * @note ap_log_rdata is implemented as a macro.
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @note 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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_rdata(const char *file, int line, int module_index,
                                  int level, const request_rec *r, const char *label,
                                  const void *data, apr_size_t len, unsigned int flags);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_rdata(...) ap_log_rdata__(__VA_ARGS__)
    #define ap_log_rdata__(file, line, mi, level, r, ...)           \
        do { if (APLOG_R_MODULE_IS_LEVEL(r, mi, level)) \
                 ap_log_rdata_(file, line, mi, level, r, __VA_ARGS__);    \
        } while(0)
    #else
    #define ap_log_rdata ap_log_rdata_
    #endif
    AP_DECLARE(void) ap_log_rdata_(const char *file, int line, int module_index,
                                   int level, const request_rec *r, const char *label,
                                   const void *data, apr_size_t len, unsigned int flags);
    #endif
    
    /**
     * ap_log_cdata() - log buffers which are related to a particular connection.
     * @param file The file in which this function is called
     * @param line The line number on which this function is called
     * @param module_index The module_index of the module logging this buffer
     * @param level The log level
     * @param c The connection which we are logging for
     * @param label A label for the buffer, to be logged preceding the buffer
     * @param data The buffer to be logged
     * @param len The length of the buffer
     * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
     * @note ap_log_cdata is implemented as a macro
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @note 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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_cdata(const char *file, int line, int module_index,
                                  int level, const conn_rec *c, const char *label,
                                  const void *data, apr_size_t len, unsigned int flags);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_cdata(...) ap_log_cdata__(__VA_ARGS__)
    #define ap_log_cdata__(file, line, mi, level, c, ...)           \
        do { if (APLOG_C_MODULE_IS_LEVEL(c, mi, level)) \
                 ap_log_cdata_(file, line, mi, level, c, __VA_ARGS__);    \
        } while(0)
    #else
    #define ap_log_cdata ap_log_cdata_
    #endif
    AP_DECLARE(void) ap_log_cdata_(const char *file, int line, int module_index,
                                   int level, const conn_rec *c, const char *label,
                                   const void *data, apr_size_t len, unsigned int flags);
    #endif
    
    /**
     * ap_log_csdata() - log buffers which are related to a particular connection
     * and to a vhost other than c->base_server.
     * @param file The file in which this function is called
     * @param line The line number on which this function is called
     * @param module_index The module_index of the module logging this buffer
     * @param level The log level
     * @param c The connection which we are logging for
     * @param s The server which we are logging for
     * @param label A label for the buffer, to be logged preceding the buffer
     * @param data The buffer to be logged
     * @param len The length of the buffer
     * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
     * @note ap_log_csdata is implemented as a macro
     * @note Use APLOG_MARK to fill out file, line, and module_index
     * @note 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.
     */
    #ifdef DOXYGEN
    AP_DECLARE(void) ap_log_csdata(const char *file, int line, int module_index,
                                   int level, const conn_rec *c, const server_rec *s,
                                   const char *label, const void *data,
                                   apr_size_t len, unsigned int flags);
    #else
    #ifdef AP_HAVE_C99
    /* need additional step to expand APLOG_MARK first */
    #define ap_log_csdata(...) ap_log_csdata__(__VA_ARGS__)
    #define ap_log_csdata__(file, line, mi, level, c, s, ...)              \
        do { if (APLOG_CS_MODULE_IS_LEVEL(c, s, mi, level))                \
                 ap_log_csdata_(file, line, mi, level, c, s, __VA_ARGS__); \
        } while(0)
    #else
    #define ap_log_cdata ap_log_cdata_
    #endif
    AP_DECLARE(void) ap_log_csdata_(const char *file, int line, int module_index,
                                    int level, const conn_rec *c, const server_rec *s,
                                    const char *label, const void *data,
                                    apr_size_t len, unsigned int flags);
    #endif
    
    /**
     * Convert stderr to the error log
     * @param s The current server
     */
    AP_DECLARE(void) ap_error_log2stderr(server_rec *s);
    
    /**
     * Log the command line used to start the server.
     * @param p The pool to use for logging
     * @param s The server_rec whose process's command line we want to log.
     * The command line is logged to that server's error log.
     */
    AP_DECLARE(void) ap_log_command_line(apr_pool_t *p, server_rec *s);
    
    /**
     * Log common (various) MPM shared data at startup.
     * @param s The server_rec of the error log we want to log to.
     * Misc commonly logged data is logged to that server's error log.
     */
    AP_DECLARE(void) ap_log_mpm_common(server_rec *s);
    
    /**
     * Log the current pid of the parent process
     * @param p The pool to use for processing
     * @param fname The name of the file to log to.  If the filename is not
     * absolute then it is assumed to be relative to ServerRoot.
     */
    AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *fname);
    
    /**
     * Remove the pidfile.
     * @param p The pool to use for processing
     * @param fname The name of the pid file to remove.  If the filename is not
     * absolute then it is assumed to be relative to ServerRoot.
     */
    AP_DECLARE(void) ap_remove_pid(apr_pool_t *p, const char *fname);
    
    /**
     * Retrieve the pid from a pidfile.
     * @param p The pool to use for processing
     * @param filename The name of the file containing the pid.  If the filename is not
     * absolute then it is assumed to be relative to ServerRoot.
     * @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);
    
    /** @see piped_log */
    typedef struct piped_log piped_log;
    
    /**
     * 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
     * @note The log program is invoked as @p APR_PROGRAM_ENV,
     *      @see ap_open_piped_log_ex to modify this behavior
     */
    AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program);
    
    /**
     * Open the piped log process specifying the execution choice for program
     * @param p The pool to allocate out of
     * @param program The program to run in the logging process
     * @param cmdtype How to invoke program, e.g. APR_PROGRAM, APR_SHELLCMD_ENV, etc
     * @return The piped log structure
     */
    AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p,
                                                 const char *program,
                                                 apr_cmdtype_e cmdtype);
    
    /**
     * Close the piped log and kill the logging process
     * @param pl The piped log structure
     */
    AP_DECLARE(void) ap_close_piped_log(piped_log *pl);
    
    /**
     * A function to return the read side of the piped log pipe
     * @param pl The piped log structure
     * @return The native file descriptor
     */
    AP_DECLARE(apr_file_t *) ap_piped_log_read_fd(piped_log *pl);
    
    /**
     * A function to return the write side of the piped log pipe
     * @param pl The piped log structure
     * @return The native file descriptor
     */
    AP_DECLARE(apr_file_t *) ap_piped_log_write_fd(piped_log *pl);
    
    /**
     * hook method to generate unique id for connection or request
     * @ingroup hooks
     * @param c the conn_rec of the connections
     * @param r the request_req (may be NULL)
     * @param id the place where to store the unique id
     * @return OK or DECLINE
     */
    AP_DECLARE_HOOK(int, generate_log_id,
                    (const conn_rec *c, const request_rec *r, const char **id))
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_LOG_H */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/util_xml.h���������������������������������������������������������������������0000664�0001751�0001751�00000002475�12362524526�016272� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  util_xml.h
     * @brief Apache XML library
     *
     * @defgroup APACHE_CORE_XML XML Library
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef UTIL_XML_H
    #define UTIL_XML_H
    
    #include "apr_xml.h"
    
    #include "httpd.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * Get XML post data and parse it.
     * @param   r       The current request
     * @param   pdoc    The XML post data
     * @return HTTP status code
     */
    AP_DECLARE(int) ap_xml_parse_input(request_rec *r, apr_xml_doc **pdoc);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* UTIL_XML_H */
    /** @} */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/heartbeat.h��������������������������������������������������������������������0000664�0001751�0001751�00000003073�12350027455�016363� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  heartbeat.h
     * @brief commun structures for mod_heartmonitor.c and mod_lbmethod_heartbeat.c
     *
     * @defgroup HEARTBEAT heartbeat
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #ifndef HEARTBEAT_H
    #define HEARTBEAT_H
    
    #include "apr.h"
    #include "apr_time.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /*
     * Worse Case: IPv4-Mapped IPv6 Address
     * 0000:0000:0000:0000:0000:FFFF:255.255.255.255
     */
    #define MAXIPSIZE  46
    typedef struct hm_slot_server_t
    {
        char ip[MAXIPSIZE];
        int busy;
        int ready;
        apr_time_t seen;
        int id;
    } hm_slot_server_t;
    
    /* default name of heartbeat data file, created in the configured
     * runtime directory when mod_slotmem_shm is not available
     */
    #define DEFAULT_HEARTBEAT_STORAGE "hb.dat"
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* HEARTBEAT_H */
    /** @} */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_config.h��������������������������������������������������������������������0000664�0001751�0001751�00000014716�12012563134�016351� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ap_config.h
     * @brief Symbol export macros and hook functions
     */
    
    #ifndef AP_CONFIG_H
    #define AP_CONFIG_H
    
    #include "ap_hooks.h"
    
    /* Although this file doesn't declare any hooks, declare the exports group here */
    /**
     * @defgroup exports Apache exports
     * @ingroup  APACHE_CORE
     */
    
    #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
    
    #include "os.h"
    #if (!defined(WIN32) && !defined(NETWARE)) || defined(__MINGW32__)
    #include "ap_config_auto.h"
    #endif
    #include "ap_config_layout.h"
    
    /* Where the main/parent process's pid is logged */
    #ifndef DEFAULT_PIDLOG
    #define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid"
    #endif
    
    #if defined(NETWARE)
    #define AP_NONBLOCK_WHEN_MULTI_LISTEN 1
    #endif
    
    #if defined(AP_ENABLE_DTRACE) && HAVE_SYS_SDT_H
    #include <sys/sdt.h>
    #else
    #undef _DTRACE_VERSION
    #endif
    
    #ifdef _DTRACE_VERSION
    #include "apache_probes.h"
    #else
    #include "apache_noprobes.h"
    #endif
    
    /* If APR has OTHER_CHILD logic, use reliable piped logs. */
    #if APR_HAS_OTHER_CHILD
    #define AP_HAVE_RELIABLE_PIPED_LOGS TRUE
    #endif
    
    #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
    #define AP_HAVE_C99
    #endif
    
    /* Presume that the compiler supports C99-style designated
     * initializers if using GCC (but not G++), or for any other compiler
     * which claims C99 support. */
    #if (defined(__GNUC__) && !defined(__cplusplus)) || defined(AP_HAVE_C99)
    #define AP_HAVE_DESIGNATED_INITIALIZER
    #endif
    
    #ifndef __has_attribute         /* check for supported attributes on clang */
    #define __has_attribute(x) 0
    #endif
    #if (defined(__GNUC__) && __GNUC__ >= 4) || __has_attribute(sentinel)
    #define AP_FN_ATTR_SENTINEL __attribute__((sentinel))
    #else
    #define AP_FN_ATTR_SENTINEL
    #endif
    
    #if ( defined(__GNUC__) &&                                        \
          (__GNUC__ >= 4 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4))) \
        || __has_attribute(warn_unused_result)
    #define AP_FN_ATTR_WARN_UNUSED_RESULT   __attribute__((warn_unused_result))
    #else
    #define AP_FN_ATTR_WARN_UNUSED_RESULT
    #endif
    
    #if ( defined(__GNUC__) &&                                        \
          (__GNUC__ >= 4 && __GNUC_MINOR__ >= 3))                     \
        || __has_attribute(alloc_size)
    #define AP_FN_ATTR_ALLOC_SIZE(x)     __attribute__((alloc_size(x)))
    #define AP_FN_ATTR_ALLOC_SIZE2(x,y)  __attribute__((alloc_size(x,y)))
    #else
    #define AP_FN_ATTR_ALLOC_SIZE(x)
    #define AP_FN_ATTR_ALLOC_SIZE2(x,y)
    #endif
    
    #endif /* AP_CONFIG_H */
    ��������������������������������������������������httpd-2.4.64/include/util_cookies.h�����������������������������������������������������������������0000664�0001751�0001751�00000011541�11702564442�017116� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file util_cookies.h
     * @brief Apache cookie library
     */
    
    #ifndef UTIL_COOKIES_H
    #define UTIL_COOKIES_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * @defgroup APACHE_CORE_COOKIE Cookies
     * @ingroup  APACHE_CORE
     *
     * RFC2109 and RFC2965 compliant HTTP cookies can be read from and written
     * to using this set of functions.
     *
     * @{
     *
     */
    
    #include "apr_errno.h"
    #include "httpd.h"
    
    #define SET_COOKIE "Set-Cookie"
    #define SET_COOKIE2 "Set-Cookie2"
    #define DEFAULT_ATTRS "HttpOnly;Secure;Version=1"
    #define CLEAR_ATTRS "Version=1"
    
    typedef struct {
        request_rec *r;
        const char *name;
        const char *encoded;
        apr_table_t *new_cookies;
        int duplicated;
    } ap_cookie_do;
    
    /**
     * Write an RFC2109 compliant cookie.
     *
     * @param r The request
     * @param name The name of the cookie.
     * @param val The value to place in the cookie.
     * @param attrs The string containing additional cookie attributes. If NULL, the
     *              DEFAULT_ATTRS will be used.
     * @param maxage If non zero, a Max-Age header will be added to the cookie.
     * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
     *            to which the cookies should be added.
     */
    AP_DECLARE(apr_status_t) ap_cookie_write(request_rec * r, const char *name,
                                             const char *val, const char *attrs,
                                             long maxage, ...)
                             AP_FN_ATTR_SENTINEL;
    
    /**
     * Write an RFC2965 compliant cookie.
     *
     * @param r The request
     * @param name2 The name of the cookie.
     * @param val The value to place in the cookie.
     * @param attrs2 The string containing additional cookie attributes. If NULL, the
     *               DEFAULT_ATTRS will be used.
     * @param maxage If non zero, a Max-Age header will be added to the cookie.
     * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
     *            to which the cookies should be added.
     */
    AP_DECLARE(apr_status_t) ap_cookie_write2(request_rec * r, const char *name2,
                                              const char *val, const char *attrs2,
                                              long maxage, ...)
                             AP_FN_ATTR_SENTINEL;
    
    /**
     * Remove an RFC2109 compliant cookie.
     *
     * @param r The request
     * @param name The name of the cookie.
     * @param attrs The string containing additional cookie attributes. If NULL, the
     *              CLEAR_ATTRS will be used.
     * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
     *            to which the cookies should be added.
     */
    AP_DECLARE(apr_status_t) ap_cookie_remove(request_rec * r, const char *name,
                                              const char *attrs, ...)
                             AP_FN_ATTR_SENTINEL;
    
    /**
     * Remove an RFC2965 compliant cookie.
     *
     * @param r The request
     * @param name2 The name of the cookie.
     * @param attrs2 The string containing additional cookie attributes. If NULL, the
     *               CLEAR_ATTRS will be used.
     * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
     *            to which the cookies should be added.
     */
    AP_DECLARE(apr_status_t) ap_cookie_remove2(request_rec * r, const char *name2,
                                               const char *attrs2, ...)
                             AP_FN_ATTR_SENTINEL;
    
    /**
     * Read a cookie called name, placing its value in val.
     *
     * Both the Cookie and Cookie2 headers are scanned for the cookie.
     *
     * If the cookie is duplicated, this function returns APR_EGENERAL. If found,
     * and if remove is non zero, the cookie will be removed from the headers, and
     * thus kept private from the backend.
     */
    AP_DECLARE(apr_status_t) ap_cookie_read(request_rec * r, const char *name, const char **val,
                                            int remove);
    
    /**
     * Sanity check a given string that it exists, is not empty,
     * and does not contain the special characters '=', ';' and '&'.
     *
     * It is used to sanity check the cookie names.
     */
    AP_DECLARE(apr_status_t) ap_cookie_check_string(const char *string);
    
    /**
     * @}
     */
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* !UTIL_COOKIES_H */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/mod_core.h���������������������������������������������������������������������0000664�0001751�0001751�00000006516�12030026303�016202� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    
    /**
     * @file  mod_core.h
     * @brief mod_core private header file
     *
     * @defgroup MOD_CORE mod_core
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #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
    
    /* Handles for core filters */
    AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_input_filter_handle;
    AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_header_filter_handle;
    AP_DECLARE_DATA extern ap_filter_rec_t *ap_chunk_filter_handle;
    AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_outerror_filter_handle;
    AP_DECLARE_DATA extern 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);
    
    /* Filter to handle any error buckets on output */
    apr_status_t ap_http_outerror_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.
     * @fn 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
     * @note 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);
    
    /* Used for multipart/byteranges boundary string */
    AP_DECLARE_DATA extern const char *ap_multipart_boundary;
    
    /* Init RNG at startup */
    AP_CORE_DECLARE(void) ap_init_rng(apr_pool_t *p);
    /* Update RNG state in parent after fork */
    AP_CORE_DECLARE(void) ap_random_parent_after_fork(void);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !MOD_CORE_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/http_main.h��������������������������������������������������������������������0000664�0001751�0001751�00000006255�11733715415�016420� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  http_main.h
     * @brief Command line options
     *
     * @defgroup APACHE_CORE_MAIN Command line options
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef APACHE_HTTP_MAIN_H
    #define APACHE_HTTP_MAIN_H
    
    #include "httpd.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:vVlLtTSMh?X"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /** 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;
    /** The global server's DefaultRuntimeDir
     * This is not usable directly in the general case; use
     * ap_runtime_dir_relative() instead.
     */
    AP_DECLARE_DATA extern const char *ap_runtime_dir;
    /** The global server's server_rec */
    AP_DECLARE_DATA extern server_rec *ap_server_conf;
    /** global pool, for access prior to creation of server_rec */
    AP_DECLARE_DATA extern apr_pool_t *ap_pglobal;
    /** state of the server (startup, exiting, ...) */
    AP_DECLARE_DATA extern int ap_main_state;
    /** run mode (normal, config test, config dump, ...) */
    AP_DECLARE_DATA extern int ap_run_mode;
    /** run mode (normal, config test, config dump, ...) */
    AP_DECLARE_DATA extern int ap_config_generation;
    
    /* 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;
    /** Available integer for using the -T switch */
    AP_DECLARE_DATA extern int ap_document_root_check;
    
    /**
     * An optional function to send signal to server on presence of '-k'
     * command line argument.
     * @param status The exit status after sending signal
     * @param pool Memory pool to allocate from
     */
    APR_DECLARE_OPTIONAL_FN(int, ap_signal_server, (int *status, apr_pool_t *pool));
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !APACHE_HTTP_MAIN_H */
    /** @} */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_regkey.h��������������������������������������������������������������������0000664�0001751�0001751�00000021737�11637105701�016377� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ap_regkey.h
     * @brief APR-style Win32 Registry Manipulation
     */
    
    #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);
    
    /**
     * 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
     * <PRE>
     *           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
     * </PRE>
     * @param keyname The path of the key relative to the parent key
     * @param flags Or'ed value of:
     * <PRE>
     *           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
     * </PRE>
     * @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 parent The open registry key of the parent, or one of
     * <PRE>
     *           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
     * </PRE>
     * @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 resulttype Pointer to a variable to store the registry type of the 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
     */
    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 */
    ���������������������������������httpd-2.4.64/include/util_filter.h������������������������������������������������������������������0000664�0001751�0001751�00000063533�12132772247�016761� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file util_filter.h
     * @brief Apache filter library
     */
    
    #ifndef AP_FILTER_H
    #define AP_FILTER_H
    
    #include "apr.h"
    #include "apr_buckets.h"
    
    #include "httpd.h"
    
    #if APR_HAVE_STDARG_H
    #include <stdarg.h>
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * @brief 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 APACHE_CORE_FILTER Filter Chain
     * @ingroup  APACHE_CORE
     *
     * 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 brigade" 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 brigade always belongs to the caller, but the filter
     * is free to use the buckets within it as it sees fit. Normally,
     * the brigade will be returned empty. Buckets *may not* be retained
     * between successive calls to the filter unless they have been
     * "set aside" with a call apr_bucket_setaside. Typically this will
     * be done with ap_save_brigade(). Buckets removed from the brigade
     * become the responsibility of the filter, which must arrange for
     * them to be deleted, either by doing so directly or by inserting
     * them in a brigade which will subsequently be destroyed.
     *
     * 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;
    
    /**
     * @brief 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 directly before the handlers are invoked
         * for a request.  The init function is called once directly
         * before running the handlers for a request or subrequest.  The
         * init function is never called for a connection filter (with
         * ftype >= AP_FTYPE_CONNECTION).  Any use of this function for
         * filters for protocols other than HTTP is specified by the
         * module supported that protocol.
         */
        ap_init_filter_func filter_init_func;
    
        /** The next filter_rec in the list */
        struct ap_filter_rec_t *next;
    
        /** Providers for this filter */
        ap_filter_provider_t *providers;
    
        /** 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;
    
        /** Trace level for this filter */
        int debug;
    
        /** Protocol flags for this filter */
        unsigned int proto_flags;
    };
    
    /**
     * @brief 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 connection filters.
         */
        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.
     * @param filter The next filter in the chain
     * @param bucket The current bucket brigade
     *
     * @remark Ownership of the brigade is retained by the caller. On return,
     *         the contents of the brigade are UNDEFINED, and the caller must
     *         either call apr_brigade_cleanup or apr_brigade_destroy on
     *         the brigade.
     */
    AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *filter,
                                             apr_bucket_brigade *bucket);
    
    /**
     * Pass the current bucket brigade down to the next filter on the filter
     * stack checking for filter errors.  The filter returns an apr_status_t value.
     * Returns ::OK if the brigade is successfully passed
     *         ::AP_FILTER_ERROR on a filter error
     *         ::HTTP_INTERNAL_SERVER_ERROR on all other errors
     * @param r      The request rec
     * @param bucket The current bucket brigade
     * @param fmt The format string. If NULL defaults to "ap_pass_brigade returned"
     * @param ... The arguments to use to fill out the format string
     * @remark Ownership of the brigade is retained by the caller. On return,
     *         the contents of the brigade are UNDEFINED, and the caller must
     *         either call apr_brigade_cleanup or apr_brigade_destroy on
     *         the brigade.
     */
    AP_DECLARE(apr_status_t) ap_pass_brigade_fchk(request_rec *r,
                                                  apr_bucket_brigade *bucket,
                                                  const char *fmt,
                                                  ...)
                                                  __attribute__((format(printf,3,4)));
    
    /**
     * 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_SET 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);
    
    /** @deprecated @see ap_register_output_filter_protocol */
    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-?.? 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
     * directly to the filter chain by using ap_add_output_filter() and
     * simply specifying the name, or 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_SET or
     *              ::AP_FTYPE_CONNECTION
     * @param proto_flags Protocol flags: logical OR of AP_FILTER_PROTO_* bits
     * @return the filter rec
     * @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
     * @note If adding a connection-level output filter (i.e. where the type
     * is >= AP_FTYPE_CONNECTION) during processing of a request, the request
     * object r must be passed in to ensure the filter chains are modified
     * correctly.  f->r will still be initialized as NULL in the new filter.
     */
    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 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 the filter for
     * @note If adding a connection-level output filter (i.e. where the type
     * is >= AP_FTYPE_CONNECTION) during processing of a request, the request
     * object r must be passed in to ensure the filter chains are modified
     * correctly.  f->r will still be initialized as NULL in the new filter.
     */
    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);
    
    /**
     * Remove an input filter from either the request or connection stack
     * it is associated with.
     * @param next   The filter stack to search
     * @param handle The filter handle (name) to remove
     * @return APR_SUCCESS on removal or error
     */
    AP_DECLARE(apr_status_t) ap_remove_input_filter_byhandle(ap_filter_t *next,
                                                             const char *handle);
    /**
     * Remove an output filter from either the request or connection stack
     * it is associated with.
     * @param next   The filter stack to search
     * @param handle The filter handle (name) to remove
     * @return APR_SUCCESS on removal or error
     */
    AP_DECLARE(apr_status_t) ap_remove_output_filter_byhandle(ap_filter_t *next,
                                                              const char *handle);
    
    /* 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_write(bb, ap_filter_flush, f, str, strlen(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,
                                                ...)
                                    AP_FN_ATTR_SENTINEL;
    
    /**
     * 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 arguments 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 */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_slotmem.h�������������������������������������������������������������������0000664�0001751�0001751�00000016103�12242221264�016554� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 SLOTMEM_H
    #define SLOTMEM_H
    
    /* Memory handler for a shared memory divided in slot.
     */
    /**
     * @file  ap_slotmem.h
     * @brief Memory Slot Extension Storage Module for Apache
     *
     * @defgroup MEM mem
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "ap_provider.h"
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_pools.h"
    #include "apr_shm.h"
    #include "apr_global_mutex.h"
    #include "apr_file_io.h"
    #include "apr_md5.h"
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>         /* for getpid() */
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define AP_SLOTMEM_PROVIDER_GROUP "slotmem"
    #define AP_SLOTMEM_PROVIDER_VERSION "0"
    
    typedef unsigned int ap_slotmem_type_t;
    
    /*
     * Values for ap_slotmem_type_t::
     *
     * AP_SLOTMEM_TYPE_PERSIST: For transitory providers, persist
     *    the data on the file-system
     *
     * AP_SLOTMEM_TYPE_NOTMPSAFE:
     *
     * AP_SLOTMEM_TYPE_PREALLOC: Access to slots require they be grabbed 1st
     *
     * AP_SLOTMEM_TYPE_CLEARINUSE: If persisting, clear 'inuse' array before
     *    storing
     */
    #define AP_SLOTMEM_TYPE_PERSIST      (1 << 0)
    #define AP_SLOTMEM_TYPE_NOTMPSAFE    (1 << 1)
    #define AP_SLOTMEM_TYPE_PREGRAB      (1 << 2)
    #define AP_SLOTMEM_TYPE_CLEARINUSE   (1 << 3)
    
    typedef struct ap_slotmem_instance_t ap_slotmem_instance_t;
    
    /**
     * callback function used for slotmem doall.
     * @param mem is the memory associated with a worker.
     * @param data is what is passed to slotmem.
     * @param pool is pool used
     * @return APR_SUCCESS if all went well
     */
    typedef apr_status_t ap_slotmem_callback_fn_t(void* mem, void *data, apr_pool_t *pool);
    
    struct ap_slotmem_provider_t {
        /*
         * Name of the provider method
         */
        const char *name;
        /**
         * call the callback on all worker slots
         * @param s ap_slotmem_instance_t to use.
         * @param funct callback function to call for each element.
         * @param data parameter for the callback function.
         * @param pool is pool used
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* doall)(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool);
        /**
         * create a new slotmem with each item size is item_size.
         * This would create shared memory, basically.
         * @param inst where to store pointer to slotmem
         * @param name a key used for debugging and in mod_status output or allow another process to share this space.
         * @param item_size size of each item
         * @param item_num number of item to create.
         * @param type type of slotmem.
         * @param pool is pool used
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* create)(ap_slotmem_instance_t **inst, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool);
        /**
         * attach to an existing slotmem.
         * This would attach to  shared memory, basically.
         * @param inst where to store pointer to slotmem
         * @param name a key used for debugging and in mod_status output or allow another process to share this space.
         * @param item_size size of each item
         * @param item_num max number of item.
         * @param pool is pool to memory allocate.
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* attach)(ap_slotmem_instance_t **inst, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool);
        /**
         * get the memory ptr associated with this worker slot.
         * @param s ap_slotmem_instance_t to use.
         * @param item_id item to return for 0 to item_num
         * @param mem address to store the pointer to the slot
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* dptr)(ap_slotmem_instance_t *s, unsigned int item_id, void**mem);
        /**
         * get/read the data associated with this worker slot.
         * @param s ap_slotmem_instance_t to use.
         * @param item_id item to return for 0 to item_num
         * @param dest address to store the data
         * @param dest_len length of dataset to retrieve
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* get)(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len);
        /**
         * put/write the data associated with this worker slot.
         * @param s ap_slotmem_instance_t to use.
         * @param item_id item to return for 0 to item_num
         * @param src address of the data to store in the slot
         * @param src_len length of dataset to store in the slot
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* put)(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len);
        /**
         * return number of slots allocated for this entry.
         * @param s ap_slotmem_instance_t to use.
         * @return number of slots
         */
        unsigned int (* num_slots)(ap_slotmem_instance_t *s);
        /**
         * return number of free (not used) slots allocated for this entry.
         * Valid for slots which are AP_SLOTMEM_TYPE_PREGRAB as well as
         * any which use get/release.
         * @param s ap_slotmem_instance_t to use.
         * @return number of slots
         */
        unsigned int (* num_free_slots)(ap_slotmem_instance_t *s);
        /**
         * return slot size allocated for this entry.
         * @param s ap_slotmem_instance_t to use.
         * @return size of slot
         */
        apr_size_t (* slot_size)(ap_slotmem_instance_t *s);
        /**
         * grab (or alloc) a free slot
         * @param s ap_slotmem_instance_t to use.
         * @param item_id ptr to the available slot id and marked as in-use
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* grab)(ap_slotmem_instance_t *s, unsigned int *item_id);
        /**
         * release (or free) the slot associated with this item_id
         * @param s ap_slotmem_instance_t to use.
         * @param item_id slot id to free and mark as no longer in-use
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* release)(ap_slotmem_instance_t *s, unsigned int item_id);
        /**
         * forced grab (or alloc) a slot associated with this item_id
         * @param s ap_slotmem_instance_t to use.
         * @param item_id to the specified slot id and marked as in-use
         * @return APR_SUCCESS if all went well
         */
        apr_status_t (* fgrab)(ap_slotmem_instance_t *s, unsigned int item_id);
    };
    
    typedef struct ap_slotmem_provider_t ap_slotmem_provider_t;
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/apache_noprobes.h��������������������������������������������������������������0000664�0001751�0001751�00000037140�11737125415�017561� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_NOPROBES_H_
    #define _APACHE_NOPROBES_H_
    
    #define AP_ACCESS_CHECKER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_ACCESS_CHECKER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_ACCESS_CHECKER_DISPATCH_INVOKE(arg0)
    #define AP_ACCESS_CHECKER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_ACCESS_CHECKER_ENTRY()
    #define AP_ACCESS_CHECKER_ENTRY_ENABLED() (0)
    #define AP_ACCESS_CHECKER_RETURN(arg0)
    #define AP_ACCESS_CHECKER_RETURN_ENABLED() (0)
    #define AP_AUTH_CHECKER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_AUTH_CHECKER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_AUTH_CHECKER_DISPATCH_INVOKE(arg0)
    #define AP_AUTH_CHECKER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_AUTH_CHECKER_ENTRY()
    #define AP_AUTH_CHECKER_ENTRY_ENABLED() (0)
    #define AP_AUTH_CHECKER_RETURN(arg0)
    #define AP_AUTH_CHECKER_RETURN_ENABLED() (0)
    #define AP_CANON_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_CANON_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_CANON_HANDLER_DISPATCH_INVOKE(arg0)
    #define AP_CANON_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_CANON_HANDLER_ENTRY()
    #define AP_CANON_HANDLER_ENTRY_ENABLED() (0)
    #define AP_CANON_HANDLER_RETURN(arg0)
    #define AP_CANON_HANDLER_RETURN_ENABLED() (0)
    #define AP_CHECK_USER_ID_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_CHECK_USER_ID_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_CHECK_USER_ID_DISPATCH_INVOKE(arg0)
    #define AP_CHECK_USER_ID_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_CHECK_USER_ID_ENTRY()
    #define AP_CHECK_USER_ID_ENTRY_ENABLED() (0)
    #define AP_CHECK_USER_ID_RETURN(arg0)
    #define AP_CHECK_USER_ID_RETURN_ENABLED() (0)
    #define AP_CHILD_INIT_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_CHILD_INIT_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_CHILD_INIT_DISPATCH_INVOKE(arg0)
    #define AP_CHILD_INIT_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_CHILD_INIT_ENTRY()
    #define AP_CHILD_INIT_ENTRY_ENABLED() (0)
    #define AP_CHILD_INIT_RETURN(arg0)
    #define AP_CHILD_INIT_RETURN_ENABLED() (0)
    #define AP_CREATE_CONNECTION_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_CREATE_CONNECTION_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_CREATE_CONNECTION_DISPATCH_INVOKE(arg0)
    #define AP_CREATE_CONNECTION_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_CREATE_CONNECTION_ENTRY()
    #define AP_CREATE_CONNECTION_ENTRY_ENABLED() (0)
    #define AP_CREATE_CONNECTION_RETURN(arg0)
    #define AP_CREATE_CONNECTION_RETURN_ENABLED() (0)
    #define AP_CREATE_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_CREATE_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_CREATE_REQUEST_DISPATCH_INVOKE(arg0)
    #define AP_CREATE_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_CREATE_REQUEST_ENTRY()
    #define AP_CREATE_REQUEST_ENTRY_ENABLED() (0)
    #define AP_CREATE_REQUEST_RETURN(arg0)
    #define AP_CREATE_REQUEST_RETURN_ENABLED() (0)
    #define AP_DEFAULT_PORT_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_DEFAULT_PORT_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_DEFAULT_PORT_DISPATCH_INVOKE(arg0)
    #define AP_DEFAULT_PORT_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_DEFAULT_PORT_ENTRY()
    #define AP_DEFAULT_PORT_ENTRY_ENABLED() (0)
    #define AP_DEFAULT_PORT_RETURN(arg0)
    #define AP_DEFAULT_PORT_RETURN_ENABLED() (0)
    #define AP_ERROR_LOG_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_ERROR_LOG_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_ERROR_LOG_DISPATCH_INVOKE(arg0)
    #define AP_ERROR_LOG_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_ERROR_LOG_ENTRY()
    #define AP_ERROR_LOG_ENTRY_ENABLED() (0)
    #define AP_ERROR_LOG_RETURN(arg0)
    #define AP_ERROR_LOG_RETURN_ENABLED() (0)
    #define AP_FIND_LIVEPROP_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_FIND_LIVEPROP_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_FIND_LIVEPROP_DISPATCH_INVOKE(arg0)
    #define AP_FIND_LIVEPROP_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_FIND_LIVEPROP_ENTRY()
    #define AP_FIND_LIVEPROP_ENTRY_ENABLED() (0)
    #define AP_FIND_LIVEPROP_RETURN(arg0)
    #define AP_FIND_LIVEPROP_RETURN_ENABLED() (0)
    #define AP_FIXUPS_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_FIXUPS_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_FIXUPS_DISPATCH_INVOKE(arg0)
    #define AP_FIXUPS_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_FIXUPS_ENTRY()
    #define AP_FIXUPS_ENTRY_ENABLED() (0)
    #define AP_FIXUPS_RETURN(arg0)
    #define AP_FIXUPS_RETURN_ENABLED() (0)
    #define AP_GATHER_PROPSETS_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_GATHER_PROPSETS_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_GATHER_PROPSETS_DISPATCH_INVOKE(arg0)
    #define AP_GATHER_PROPSETS_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_GATHER_PROPSETS_ENTRY()
    #define AP_GATHER_PROPSETS_ENTRY_ENABLED() (0)
    #define AP_GATHER_PROPSETS_RETURN(arg0)
    #define AP_GATHER_PROPSETS_RETURN_ENABLED() (0)
    #define AP_GET_MGMT_ITEMS_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_GET_MGMT_ITEMS_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_GET_MGMT_ITEMS_DISPATCH_INVOKE(arg0)
    #define AP_GET_MGMT_ITEMS_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_GET_MGMT_ITEMS_ENTRY()
    #define AP_GET_MGMT_ITEMS_ENTRY_ENABLED() (0)
    #define AP_GET_MGMT_ITEMS_RETURN(arg0)
    #define AP_GET_MGMT_ITEMS_RETURN_ENABLED() (0)
    #define AP_GET_SUEXEC_IDENTITY_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_GET_SUEXEC_IDENTITY_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_GET_SUEXEC_IDENTITY_DISPATCH_INVOKE(arg0)
    #define AP_GET_SUEXEC_IDENTITY_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_GET_SUEXEC_IDENTITY_ENTRY()
    #define AP_GET_SUEXEC_IDENTITY_ENTRY_ENABLED() (0)
    #define AP_GET_SUEXEC_IDENTITY_RETURN(arg0)
    #define AP_GET_SUEXEC_IDENTITY_RETURN_ENABLED() (0)
    #define AP_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_HANDLER_DISPATCH_INVOKE(arg0)
    #define AP_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_HANDLER_ENTRY()
    #define AP_HANDLER_ENTRY_ENABLED() (0)
    #define AP_HANDLER_RETURN(arg0)
    #define AP_HANDLER_RETURN_ENABLED() (0)
    #define AP_HEADER_PARSER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_HEADER_PARSER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_HEADER_PARSER_DISPATCH_INVOKE(arg0)
    #define AP_HEADER_PARSER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_HEADER_PARSER_ENTRY()
    #define AP_HEADER_PARSER_ENTRY_ENABLED() (0)
    #define AP_HEADER_PARSER_RETURN(arg0)
    #define AP_HEADER_PARSER_RETURN_ENABLED() (0)
    #define AP_HTTP_SCHEME_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_HTTP_SCHEME_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_HTTP_SCHEME_DISPATCH_INVOKE(arg0)
    #define AP_HTTP_SCHEME_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_HTTP_SCHEME_ENTRY()
    #define AP_HTTP_SCHEME_ENTRY_ENABLED() (0)
    #define AP_HTTP_SCHEME_RETURN(arg0)
    #define AP_HTTP_SCHEME_RETURN_ENABLED() (0)
    #define AP_INSERT_ALL_LIVEPROPS_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_INSERT_ALL_LIVEPROPS_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_INSERT_ALL_LIVEPROPS_DISPATCH_INVOKE(arg0)
    #define AP_INSERT_ALL_LIVEPROPS_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_INSERT_ALL_LIVEPROPS_ENTRY()
    #define AP_INSERT_ALL_LIVEPROPS_ENTRY_ENABLED() (0)
    #define AP_INSERT_ALL_LIVEPROPS_RETURN(arg0)
    #define AP_INSERT_ALL_LIVEPROPS_RETURN_ENABLED() (0)
    #define AP_INSERT_ERROR_FILTER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_INSERT_ERROR_FILTER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_INSERT_ERROR_FILTER_DISPATCH_INVOKE(arg0)
    #define AP_INSERT_ERROR_FILTER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_INSERT_ERROR_FILTER_ENTRY()
    #define AP_INSERT_ERROR_FILTER_ENTRY_ENABLED() (0)
    #define AP_INSERT_ERROR_FILTER_RETURN(arg0)
    #define AP_INSERT_ERROR_FILTER_RETURN_ENABLED() (0)
    #define AP_INSERT_FILTER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_INSERT_FILTER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_INSERT_FILTER_DISPATCH_INVOKE(arg0)
    #define AP_INSERT_FILTER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_INSERT_FILTER_ENTRY()
    #define AP_INSERT_FILTER_ENTRY_ENABLED() (0)
    #define AP_INSERT_FILTER_RETURN(arg0)
    #define AP_INSERT_FILTER_RETURN_ENABLED() (0)
    #define AP_INTERNAL_REDIRECT(arg0, arg1)
    #define AP_INTERNAL_REDIRECT_ENABLED() (0)
    #define AP_LOG_TRANSACTION_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_LOG_TRANSACTION_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_LOG_TRANSACTION_DISPATCH_INVOKE(arg0)
    #define AP_LOG_TRANSACTION_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_LOG_TRANSACTION_ENTRY()
    #define AP_LOG_TRANSACTION_ENTRY_ENABLED() (0)
    #define AP_LOG_TRANSACTION_RETURN(arg0)
    #define AP_LOG_TRANSACTION_RETURN_ENABLED() (0)
    #define AP_MAP_TO_STORAGE_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_MAP_TO_STORAGE_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_MAP_TO_STORAGE_DISPATCH_INVOKE(arg0)
    #define AP_MAP_TO_STORAGE_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_MAP_TO_STORAGE_ENTRY()
    #define AP_MAP_TO_STORAGE_ENTRY_ENABLED() (0)
    #define AP_MAP_TO_STORAGE_RETURN(arg0)
    #define AP_MAP_TO_STORAGE_RETURN_ENABLED() (0)
    #define AP_MONITOR_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_MONITOR_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_MONITOR_DISPATCH_INVOKE(arg0)
    #define AP_MONITOR_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_MONITOR_ENTRY()
    #define AP_MONITOR_ENTRY_ENABLED() (0)
    #define AP_MONITOR_RETURN(arg0)
    #define AP_MONITOR_RETURN_ENABLED() (0)
    #define AP_OPEN_LOGS_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_OPEN_LOGS_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_OPEN_LOGS_DISPATCH_INVOKE(arg0)
    #define AP_OPEN_LOGS_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_OPEN_LOGS_ENTRY()
    #define AP_OPEN_LOGS_ENTRY_ENABLED() (0)
    #define AP_OPEN_LOGS_RETURN(arg0)
    #define AP_OPEN_LOGS_RETURN_ENABLED() (0)
    #define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_INVOKE(arg0)
    #define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_OPTIONAL_FN_RETRIEVE_ENTRY()
    #define AP_OPTIONAL_FN_RETRIEVE_ENTRY_ENABLED() (0)
    #define AP_OPTIONAL_FN_RETRIEVE_RETURN(arg0)
    #define AP_OPTIONAL_FN_RETRIEVE_RETURN_ENABLED() (0)
    #define AP_POST_CONFIG_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_POST_CONFIG_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_POST_CONFIG_DISPATCH_INVOKE(arg0)
    #define AP_POST_CONFIG_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_POST_CONFIG_ENTRY()
    #define AP_POST_CONFIG_ENTRY_ENABLED() (0)
    #define AP_POST_CONFIG_RETURN(arg0)
    #define AP_POST_CONFIG_RETURN_ENABLED() (0)
    #define AP_POST_READ_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_POST_READ_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_POST_READ_REQUEST_DISPATCH_INVOKE(arg0)
    #define AP_POST_READ_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_POST_READ_REQUEST_ENTRY()
    #define AP_POST_READ_REQUEST_ENTRY_ENABLED() (0)
    #define AP_POST_READ_REQUEST_RETURN(arg0)
    #define AP_POST_READ_REQUEST_RETURN_ENABLED() (0)
    #define AP_POST_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_POST_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_POST_REQUEST_DISPATCH_INVOKE(arg0)
    #define AP_POST_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_POST_REQUEST_ENTRY()
    #define AP_POST_REQUEST_ENTRY_ENABLED() (0)
    #define AP_POST_REQUEST_RETURN(arg0)
    #define AP_POST_REQUEST_RETURN_ENABLED() (0)
    #define AP_PRE_CONFIG_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_PRE_CONFIG_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_PRE_CONFIG_DISPATCH_INVOKE(arg0)
    #define AP_PRE_CONFIG_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_PRE_CONFIG_ENTRY()
    #define AP_PRE_CONFIG_ENTRY_ENABLED() (0)
    #define AP_PRE_CONFIG_RETURN(arg0)
    #define AP_PRE_CONFIG_RETURN_ENABLED() (0)
    #define AP_PRE_CONNECTION_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_PRE_CONNECTION_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_PRE_CONNECTION_DISPATCH_INVOKE(arg0)
    #define AP_PRE_CONNECTION_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_PRE_CONNECTION_ENTRY()
    #define AP_PRE_CONNECTION_ENTRY_ENABLED() (0)
    #define AP_PRE_CONNECTION_RETURN(arg0)
    #define AP_PRE_CONNECTION_RETURN_ENABLED() (0)
    #define AP_PRE_MPM_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_PRE_MPM_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_PRE_MPM_DISPATCH_INVOKE(arg0)
    #define AP_PRE_MPM_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_PRE_MPM_ENTRY()
    #define AP_PRE_MPM_ENTRY_ENABLED() (0)
    #define AP_PRE_MPM_RETURN(arg0)
    #define AP_PRE_MPM_RETURN_ENABLED() (0)
    #define AP_PRE_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_PRE_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_PRE_REQUEST_DISPATCH_INVOKE(arg0)
    #define AP_PRE_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_PRE_REQUEST_ENTRY()
    #define AP_PRE_REQUEST_ENTRY_ENABLED() (0)
    #define AP_PRE_REQUEST_RETURN(arg0)
    #define AP_PRE_REQUEST_RETURN_ENABLED() (0)
    #define AP_PROCESS_REQUEST_ENTRY(arg0, arg1)
    #define AP_PROCESS_REQUEST_ENTRY_ENABLED() (0)
    #define AP_PROCESS_REQUEST_RETURN(arg0, arg1, arg2)
    #define AP_PROCESS_REQUEST_RETURN_ENABLED() (0)
    #define AP_PROCESS_CONNECTION_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_PROCESS_CONNECTION_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_PROCESS_CONNECTION_DISPATCH_INVOKE(arg0)
    #define AP_PROCESS_CONNECTION_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_PROCESS_CONNECTION_ENTRY()
    #define AP_PROCESS_CONNECTION_ENTRY_ENABLED() (0)
    #define AP_PROCESS_CONNECTION_RETURN(arg0)
    #define AP_PROCESS_CONNECTION_RETURN_ENABLED() (0)
    #define AP_PROXY_RUN(arg0, arg1, arg2, arg3, arg4)
    #define AP_PROXY_RUN_ENABLED() (0)
    #define AP_PROXY_RUN_FINISHED(arg0, arg1, arg2)
    #define AP_PROXY_RUN_FINISHED_ENABLED() (0)
    #define AP_QUICK_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_QUICK_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_QUICK_HANDLER_DISPATCH_INVOKE(arg0)
    #define AP_QUICK_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_QUICK_HANDLER_ENTRY()
    #define AP_QUICK_HANDLER_ENTRY_ENABLED() (0)
    #define AP_QUICK_HANDLER_RETURN(arg0)
    #define AP_QUICK_HANDLER_RETURN_ENABLED() (0)
    #define AP_READ_REQUEST_ENTRY(arg0, arg1)
    #define AP_READ_REQUEST_ENTRY_ENABLED() (0)
    #define AP_READ_REQUEST_FAILURE(arg0)
    #define AP_READ_REQUEST_FAILURE_ENABLED() (0)
    #define AP_READ_REQUEST_SUCCESS(arg0, arg1, arg2, arg3, arg4)
    #define AP_READ_REQUEST_SUCCESS_ENABLED() (0)
    #define AP_REWRITE_LOG(arg0, arg1, arg2, arg3, arg4)
    #define AP_REWRITE_LOG_ENABLED() (0)
    #define AP_SCHEME_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_SCHEME_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_SCHEME_HANDLER_DISPATCH_INVOKE(arg0)
    #define AP_SCHEME_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_SCHEME_HANDLER_ENTRY()
    #define AP_SCHEME_HANDLER_ENTRY_ENABLED() (0)
    #define AP_SCHEME_HANDLER_RETURN(arg0)
    #define AP_SCHEME_HANDLER_RETURN_ENABLED() (0)
    #define AP_TEST_CONFIG_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_TEST_CONFIG_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_TEST_CONFIG_DISPATCH_INVOKE(arg0)
    #define AP_TEST_CONFIG_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_TEST_CONFIG_ENTRY()
    #define AP_TEST_CONFIG_ENTRY_ENABLED() (0)
    #define AP_TEST_CONFIG_RETURN(arg0)
    #define AP_TEST_CONFIG_RETURN_ENABLED() (0)
    #define AP_TRANSLATE_NAME_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_TRANSLATE_NAME_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_TRANSLATE_NAME_DISPATCH_INVOKE(arg0)
    #define AP_TRANSLATE_NAME_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_TRANSLATE_NAME_ENTRY()
    #define AP_TRANSLATE_NAME_ENTRY_ENABLED() (0)
    #define AP_TRANSLATE_NAME_RETURN(arg0)
    #define AP_TRANSLATE_NAME_RETURN_ENABLED() (0)
    #define AP_TYPE_CHECKER_DISPATCH_COMPLETE(arg0, arg1)
    #define AP_TYPE_CHECKER_DISPATCH_COMPLETE_ENABLED() (0)
    #define AP_TYPE_CHECKER_DISPATCH_INVOKE(arg0)
    #define AP_TYPE_CHECKER_DISPATCH_INVOKE_ENABLED() (0)
    #define AP_TYPE_CHECKER_ENTRY()
    #define AP_TYPE_CHECKER_ENTRY_ENABLED() (0)
    #define AP_TYPE_CHECKER_RETURN(arg0)
    #define AP_TYPE_CHECKER_RETURN_ENABLED() (0)
    
    #endif
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_provider.h������������������������������������������������������������������0000664�0001751�0001751�00000006721�11774644007�016750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  ap_provider.h
     * @brief Apache Provider API
     *
     * @defgroup APACHE_CORE_PROVIDER Provider API
     * @ingroup  APACHE_CORE
     * @{
     */
    
    #ifndef AP_PROVIDER_H
    #define AP_PROVIDER_H
    
    #include "ap_config.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    typedef struct {
        const char *provider_name;
    } ap_list_provider_names_t;
    
    typedef struct {
        const char *provider_group;
        const char *provider_version;
    } ap_list_provider_groups_t;
    
    /**
     * 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);
    
    /**
     * This function is used to retrieve a list (array) of provider
     * names from the specified group with the specified version.
     * @param pool The pool to create any storage from
     * @param provider_group The group to look for this provider in
     * @param provider_version The version for the provider
     * @return pointer to array of ap_list_provider_names_t of provider names (could be empty)
     */
    
    AP_DECLARE(apr_array_header_t *) ap_list_provider_names(apr_pool_t *pool,
                                                  const char *provider_group,
                                                  const char *provider_version);
    
    /**
     * This function is used to retrieve a list (array) of provider groups and versions
     * @param pool The pool to create any storage from
     * @return pointer to array of ap_list_provider_groups_t of provider groups
     *         and versions (could be empty)
     */
    
    AP_DECLARE(apr_array_header_t *) ap_list_provider_groups(apr_pool_t *pool);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    /** @} */
    �����������������������������������������������httpd-2.4.64/include/.indent.pro��������������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�016333� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_config_layout.h.in����������������������������������������������������������0000664�0001751�0001751�00000005340�10455010104�020335� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  ap_config_layout.h
     * @brief Apache Config Layout
     */
    
    #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 */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/include/ap_config_auto.h.in������������������������������������������������������������0000664�0001751�0001751�00000026740�15032766625�020025� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* include/ap_config_auto.h.in.  Generated from configure.in by autoheader.  */
    
    /* SuExec root directory */
    #undef AP_DOC_ROOT
    
    /* Enable DTrace probes */
    #undef AP_ENABLE_DTRACE
    
    /* Allow modules to run hook after a fatal exception */
    #undef AP_ENABLE_EXCEPTION_HOOK
    
    /* Allow IPv4 connections on IPv6 listening sockets */
    #undef AP_ENABLE_V4_MAPPED
    
    /* Minimum allowed GID */
    #undef AP_GID_MIN
    
    /* Enable the APR hook probes capability, reading from ap_hook_probes.h */
    #undef AP_HOOK_PROBES_ENABLED
    
    /* User allowed to call SuExec */
    #undef AP_HTTPD_USER
    
    /* SuExec log file */
    #undef AP_LOG_EXEC
    
    /* SuExec log to syslog */
    #undef AP_LOG_SYSLOG
    
    /* Listening sockets are non-blocking when there are more than 1 */
    #undef AP_NONBLOCK_WHEN_MULTI_LISTEN
    
    /* safe shell path for SuExec */
    #undef AP_SAFE_PATH
    
    /* Enable if suexec is installed with Linux capabilities, not setuid */
    #undef AP_SUEXEC_CAPABILITIES
    
    /* umask for suexec'd process */
    #undef AP_SUEXEC_UMASK
    
    /* Location of the MIME types config file, relative to the Apache root
       directory */
    #undef AP_TYPES_CONFIG_FILE
    
    /* Minimum allowed UID */
    #undef AP_UID_MIN
    
    /* User subdirectory */
    #undef AP_USERDIR_SUFFIX
    
    /* Using autoconf to configure Apache */
    #undef AP_USING_AUTOCONF
    
    /* Define as default argument for thread id in error logging */
    #undef DEFAULT_LOG_TID
    
    /* Define to 1 if you have the `arc4random_buf' function. */
    #undef HAVE_ARC4RANDOM_BUF
    
    /* Define to 1 if you have the `bindprocessor' function. */
    #undef HAVE_BINDPROCESSOR
    
    /* Define to 1 if you have the <bstring.h> header file. */
    #undef HAVE_BSTRING_H
    
    /* Enable FD passing support in mod_cgid */
    #undef HAVE_CGID_FDPASSING
    
    /* Define if crypt() supports SHA-2 hashes */
    #undef HAVE_CRYPT_SHA2
    
    /* Define if curl is available */
    #undef HAVE_CURL
    
    /* Define to 1 if you have the <curl/curl.h> header file. */
    #undef HAVE_CURL_CURL_H
    
    /* Define if distcache support is enabled */
    #undef HAVE_DISTCACHE
    
    /* Define to 1 if you have the <distcache/dc_client.h> header file. */
    #undef HAVE_DISTCACHE_DC_CLIENT_H
    
    /* Define to 1 if you have the `ENGINE_init' function. */
    #undef HAVE_ENGINE_INIT
    
    /* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
    #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
    
    /* Define to 1 if you have the `epoll_create' function. */
    #undef HAVE_EPOLL_CREATE
    
    /* Define to 1 if you have the `fopen64' function. */
    #undef HAVE_FOPEN64
    
    /* Define to 1 if you have the `getgrnam' function. */
    #undef HAVE_GETGRNAM
    
    /* Define to 1 if you have the `getloadavg' function. */
    #undef HAVE_GETLOADAVG
    
    /* Define to 1 if you have the `getpgid' function. */
    #undef HAVE_GETPGID
    
    /* Define to 1 if you have the `getpwnam' function. */
    #undef HAVE_GETPWNAM
    
    /* Define to 1 if you have the `gettid' function. */
    #undef HAVE_GETTID
    
    /* Define if struct tm has a tm_gmtoff field */
    #undef HAVE_GMTOFF
    
    /* Define to 1 if you have the <grp.h> header file. */
    #undef HAVE_GRP_H
    
    /* Define to 1 if you have the `initgroups' function. */
    #undef HAVE_INITGROUPS
    
    /* Define to 1 if you have the <inttypes.h> header file. */
    #undef HAVE_INTTYPES_H
    
    /* Define if jansson is available */
    #undef HAVE_JANSSON
    
    /* Define to 1 if you have the `killpg' function. */
    #undef HAVE_KILLPG
    
    /* Define to 1 if you have the `kqueue' function. */
    #undef HAVE_KQUEUE
    
    /* Define to 1 if you have the <limits.h> header file. */
    #undef HAVE_LIMITS_H
    
    /* Define to 1 if you have the <minix/config.h> header file. */
    #undef HAVE_MINIX_CONFIG_H
    
    /* Define if nghttp2 is available */
    #undef HAVE_NGHTTP2
    
    /* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
    #undef HAVE_NGHTTP2_NGHTTP2_H
    
    /* Define to 1 if you have the `nghttp2_option_set_no_closed_streams'
       function. */
    #undef HAVE_NGHTTP2_OPTION_SET_NO_CLOSED_STREAMS
    
    /* Define to 1 if you have the
       `nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation'
       function. */
    #undef HAVE_NGHTTP2_OPTION_SET_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION
    
    /* Define to 1 if you have the
       `nghttp2_session_callbacks_set_on_invalid_header_callback' function. */
    #undef HAVE_NGHTTP2_SESSION_CALLBACKS_SET_ON_INVALID_HEADER_CALLBACK
    
    /* Define to 1 if you have the `nghttp2_session_change_stream_priority'
       function. */
    #undef HAVE_NGHTTP2_SESSION_CHANGE_STREAM_PRIORITY
    
    /* Define to 1 if you have the `nghttp2_session_get_stream_local_window_size'
       function. */
    #undef HAVE_NGHTTP2_SESSION_GET_STREAM_LOCAL_WINDOW_SIZE
    
    /* Define to 1 if you have the `nghttp2_session_server_new2' function. */
    #undef HAVE_NGHTTP2_SESSION_SERVER_NEW2
    
    /* Define to 1 if you have the `nghttp2_stream_get_weight' function. */
    #undef HAVE_NGHTTP2_STREAM_GET_WEIGHT
    
    /* Define if OpenSSL is available */
    #undef HAVE_OPENSSL
    
    /* Define to 1 if you have the <openssl/engine.h> header file. */
    #undef HAVE_OPENSSL_ENGINE_H
    
    /* Define to 1 if you have the `OPENSSL_init_ssl' function. */
    #undef HAVE_OPENSSL_INIT_SSL
    
    /* Detected PCRE2 */
    #undef HAVE_PCRE2
    
    /* Define to 1 if you have the `port_create' function. */
    #undef HAVE_PORT_CREATE
    
    /* Define to 1 if you have the `prctl' function. */
    #undef HAVE_PRCTL
    
    /* Define to 1 if you have the <priv.h> header file. */
    #undef HAVE_PRIV_H
    
    /* Define to 1 if you have the `pthread_kill' function. */
    #undef HAVE_PTHREAD_KILL
    
    /* Define to 1 if you have the <pwd.h> header file. */
    #undef HAVE_PWD_H
    
    /* Define to 1 if you have the `RAND_egd' function. */
    #undef HAVE_RAND_EGD
    
    /* Defined if SELinux is supported */
    #undef HAVE_SELINUX
    
    /* Define to 1 if you have the `setsid' function. */
    #undef HAVE_SETSID
    
    /* Define to 1 if you have the `SSL_CTX_new' function. */
    #undef HAVE_SSL_CTX_NEW
    
    /* Define to 1 if you have the <stdint.h> header file. */
    #undef HAVE_STDINT_H
    
    /* Define to 1 if you have the <stdio.h> header file. */
    #undef HAVE_STDIO_H
    
    /* Define to 1 if you have the <stdlib.h> header file. */
    #undef HAVE_STDLIB_H
    
    /* Define to 1 if you have the <strings.h> header file. */
    #undef HAVE_STRINGS_H
    
    /* Define to 1 if you have the <string.h> header file. */
    #undef HAVE_STRING_H
    
    /* Define to 1 if you have the `syslog' function. */
    #undef HAVE_SYSLOG
    
    /* Define if systemd is supported */
    #undef HAVE_SYSTEMD
    
    /* Define to 1 if you have the <systemd/sd-daemon.h> header file. */
    #undef HAVE_SYSTEMD_SD_DAEMON_H
    
    /* Define if you have gettid() via syscall() */
    #undef HAVE_SYS_GETTID
    
    /* Define to 1 if you have the <sys/ipc.h> header file. */
    #undef HAVE_SYS_IPC_H
    
    /* Define to 1 if you have the <sys/loadavg.h> header file. */
    #undef HAVE_SYS_LOADAVG_H
    
    /* Define to 1 if you have the <sys/prctl.h> header file. */
    #undef HAVE_SYS_PRCTL_H
    
    /* Define to 1 if you have the <sys/processor.h> header file. */
    #undef HAVE_SYS_PROCESSOR_H
    
    /* Define to 1 if you have the <sys/resource.h> header file. */
    #undef HAVE_SYS_RESOURCE_H
    
    /* Define to 1 if you have the <sys/sdt.h> header file. */
    #undef HAVE_SYS_SDT_H
    
    /* Define to 1 if you have the <sys/sem.h> header file. */
    #undef HAVE_SYS_SEM_H
    
    /* Define to 1 if you have the <sys/socket.h> header file. */
    #undef HAVE_SYS_SOCKET_H
    
    /* Define to 1 if you have the <sys/stat.h> header file. */
    #undef HAVE_SYS_STAT_H
    
    /* Define to 1 if you have the <sys/times.h> header file. */
    #undef HAVE_SYS_TIMES_H
    
    /* Define to 1 if you have the <sys/time.h> header file. */
    #undef HAVE_SYS_TIME_H
    
    /* Define to 1 if you have the <sys/types.h> header file. */
    #undef HAVE_SYS_TYPES_H
    
    /* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
    #undef HAVE_SYS_WAIT_H
    
    /* Define to 1 if you have the `timegm' function. */
    #undef HAVE_TIMEGM
    
    /* Define to 1 if you have the `times' function. */
    #undef HAVE_TIMES
    
    /* Define to 1 if you have the <unistd.h> header file. */
    #undef HAVE_UNISTD_H
    
    /* Define to 1 if you have the `vsyslog' function. */
    #undef HAVE_VSYSLOG
    
    /* Define to 1 if you have the <wchar.h> header file. */
    #undef HAVE_WCHAR_H
    
    /* Root directory of the Apache install area */
    #undef HTTPD_ROOT
    
    /* Define to the address where bug reports for this package should be sent. */
    #undef PACKAGE_BUGREPORT
    
    /* Define to the full name of this package. */
    #undef PACKAGE_NAME
    
    /* Define to the full name and version of this package. */
    #undef PACKAGE_STRING
    
    /* Define to the one symbol short name of this package. */
    #undef PACKAGE_TARNAME
    
    /* Define to the home page for this package. */
    #undef PACKAGE_URL
    
    /* Define to the version of this package. */
    #undef PACKAGE_VERSION
    
    /* Location of the config file, relative to the Apache root directory */
    #undef SERVER_CONFIG_FILE
    
    /* This platform doesn't suffer from the thundering herd problem */
    #undef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
    
    /* Define to 1 if all of the C90 standard headers exist (not just the ones
       required in a freestanding environment). This macro is provided for
       backward compatibility; new code need not use it. */
    #undef STDC_HEADERS
    
    /* Path to suexec binary */
    #undef SUEXEC_BIN
    
    /* Enable extensions on AIX 3, Interix.  */
    #ifndef _ALL_SOURCE
    # undef _ALL_SOURCE
    #endif
    /* Enable general extensions on macOS.  */
    #ifndef _DARWIN_C_SOURCE
    # undef _DARWIN_C_SOURCE
    #endif
    /* Enable general extensions on Solaris.  */
    #ifndef __EXTENSIONS__
    # undef __EXTENSIONS__
    #endif
    /* Enable GNU extensions on systems that have them.  */
    #ifndef _GNU_SOURCE
    # undef _GNU_SOURCE
    #endif
    /* Enable X/Open compliant socket functions that do not require linking
       with -lxnet on HP-UX 11.11.  */
    #ifndef _HPUX_ALT_XOPEN_SOCKET_API
    # undef _HPUX_ALT_XOPEN_SOCKET_API
    #endif
    /* Identify the host operating system as Minix.
       This macro does not affect the system headers' behavior.
       A future release of Autoconf may stop defining this macro.  */
    #ifndef _MINIX
    # undef _MINIX
    #endif
    /* Enable general extensions on NetBSD.
       Enable NetBSD compatibility extensions on Minix.  */
    #ifndef _NETBSD_SOURCE
    # undef _NETBSD_SOURCE
    #endif
    /* Enable OpenBSD compatibility extensions on NetBSD.
       Oddly enough, this does nothing on OpenBSD.  */
    #ifndef _OPENBSD_SOURCE
    # undef _OPENBSD_SOURCE
    #endif
    /* Define to 1 if needed for POSIX-compatible behavior.  */
    #ifndef _POSIX_SOURCE
    # undef _POSIX_SOURCE
    #endif
    /* Define to 2 if needed for POSIX-compatible behavior.  */
    #ifndef _POSIX_1_SOURCE
    # undef _POSIX_1_SOURCE
    #endif
    /* Enable POSIX-compatible threading on Solaris.  */
    #ifndef _POSIX_PTHREAD_SEMANTICS
    # undef _POSIX_PTHREAD_SEMANTICS
    #endif
    /* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */
    #ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
    # undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
    #endif
    /* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */
    #ifndef __STDC_WANT_IEC_60559_BFP_EXT__
    # undef __STDC_WANT_IEC_60559_BFP_EXT__
    #endif
    /* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */
    #ifndef __STDC_WANT_IEC_60559_DFP_EXT__
    # undef __STDC_WANT_IEC_60559_DFP_EXT__
    #endif
    /* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */
    #ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
    # undef __STDC_WANT_IEC_60559_FUNCS_EXT__
    #endif
    /* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */
    #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
    # undef __STDC_WANT_IEC_60559_TYPES_EXT__
    #endif
    /* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */
    #ifndef __STDC_WANT_LIB_EXT2__
    # undef __STDC_WANT_LIB_EXT2__
    #endif
    /* Enable extensions specified by ISO/IEC 24747:2009.  */
    #ifndef __STDC_WANT_MATH_SPEC_FUNCS__
    # undef __STDC_WANT_MATH_SPEC_FUNCS__
    #endif
    /* Enable extensions on HP NonStop.  */
    #ifndef _TANDEM_SOURCE
    # undef _TANDEM_SOURCE
    #endif
    /* Enable X/Open extensions.  Define to 500 only if necessary
       to make mbstate_t available.  */
    #ifndef _XOPEN_SOURCE
    # undef _XOPEN_SOURCE
    #endif
    
    
    /* Define to empty if `const' does not conform to ANSI C. */
    #undef const
    
    /* Define to 'int' if <sys/resource.h> doesn't define it for us */
    #undef rlim_t
    ��������������������������������httpd-2.4.64/modules/�������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�014304� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�014703� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_tailscale.c��������������������������������������������������������������0000664�0001751�0001751�00000031117�14240433464�017466� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_hash.h>
    #include <apr_uri.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_http.h"
    #include "md_log.h"
    #include "md_result.h"
    #include "md_reg.h"
    #include "md_store.h"
    #include "md_util.h"
    
    #include "md_tailscale.h"
    
    typedef struct {
        apr_pool_t *pool;
        md_proto_driver_t *driver;
        const char *unix_socket_path;
        md_t *md;
        apr_array_header_t *chain;
        md_pkey_t *pkey;
    } ts_ctx_t;
    
    static apr_status_t ts_init(md_proto_driver_t *d, md_result_t *result)
    {
        ts_ctx_t *ts_ctx;
        apr_uri_t uri;
        const char *ca_url;
        apr_status_t rv = APR_SUCCESS;
    
        md_result_set(result, APR_SUCCESS, NULL);
        ts_ctx = apr_pcalloc(d->p, sizeof(*ts_ctx));
        ts_ctx->pool = d->p;
        ts_ctx->driver = d;
        ts_ctx->chain = apr_array_make(d->p, 5, sizeof(md_cert_t *));
    
        ca_url = (d->md->ca_urls && !apr_is_empty_array(d->md->ca_urls))?
                    APR_ARRAY_IDX(d->md->ca_urls, 0, const char*) : NULL;
        if (!ca_url) {
            ca_url = MD_TAILSCALE_DEF_URL;
        }
        rv = apr_uri_parse(d->p, ca_url, &uri);
        if (APR_SUCCESS != rv) {
            md_result_printf(result, rv, "error parsing CA URL `%s`", ca_url);
            goto leave;
        }
        if (uri.scheme && uri.scheme[0] && strcmp("file", uri.scheme)) {
            rv = APR_ENOTIMPL;
            md_result_printf(result, rv, "non `file` URLs not supported, CA URL is `%s`",
                             ca_url);
            goto leave;
        }
        if (uri.hostname && uri.hostname[0] && strcmp("localhost", uri.hostname)) {
            rv = APR_ENOTIMPL;
            md_result_printf(result, rv, "non `localhost` URLs not supported, CA URL is `%s`",
                             ca_url);
            goto leave;
        }
        ts_ctx->unix_socket_path = uri.path;
        d->baton = ts_ctx;
    
    leave:
        return rv;
    }
    
    static apr_status_t ts_preload_init(md_proto_driver_t *d, md_result_t *result)
    {
        return ts_init(d, result);
    }
    
    static apr_status_t ts_preload(md_proto_driver_t *d,
                                   md_store_group_t load_group, md_result_t *result)
    {
        apr_status_t rv;
        md_t *md;
        md_credentials_t *creds;
        md_pkey_spec_t *pkspec;
        apr_array_header_t *all_creds;
        const char *name;
        int i;
    
        name = d->md->name;
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: preload start", name);
        /* Load data from MD_SG_STAGING and save it into "load_group".
         */
        if (APR_SUCCESS != (rv = md_load(d->store, MD_SG_STAGING, name, &md, d->p))) {
            md_result_set(result, rv, "loading staged md.json");
            goto leave;
        }
    
         /* tailscale generates one cert+key with key specification being whatever
          * it chooses. Use the NULL spec here.
          */
        all_creds = apr_array_make(d->p, 5, sizeof(md_credentials_t*));
        pkspec = NULL;
        if (APR_SUCCESS != (rv = md_creds_load(d->store, MD_SG_STAGING, name, pkspec, &creds, d->p))) {
            md_result_printf(result, rv, "loading staged credentials");
            goto leave;
        }
        if (!creds->chain) {
            rv = APR_ENOENT;
            md_result_printf(result, rv, "no certificate in staged credentials");
            goto leave;
        }
        if (APR_SUCCESS != (rv = md_check_cert_and_pkey(creds->chain, creds->pkey))) {
            md_result_printf(result, rv, "certificate and private key do not match in staged credentials");
            goto leave;
        }
        APR_ARRAY_PUSH(all_creds, md_credentials_t*) = creds;
    
        md_result_activity_setn(result, "purging store tmp space");
        rv = md_store_purge(d->store, d->p, load_group, name);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, NULL);
            goto leave;
        }
    
        md_result_activity_setn(result, "saving staged md/privkey/pubcert");
        if (APR_SUCCESS != (rv = md_save(d->store, d->p, load_group, md, 1))) {
            md_result_set(result, rv, "writing md.json");
            goto leave;
        }
    
        for (i = 0; i < all_creds->nelts; ++i) {
            creds = APR_ARRAY_IDX(all_creds, i, md_credentials_t*);
            if (APR_SUCCESS != (rv = md_creds_save(d->store, d->p, load_group, name, creds, 1))) {
                md_result_printf(result, rv, "writing credentials #%d", i);
                goto leave;
            }
        }
    
        md_result_set(result, APR_SUCCESS, "saved staged data successfully");
    
    leave:
        md_result_log(result, MD_LOG_DEBUG);
        return rv;
    }
    
    static apr_status_t rv_of_response(const md_http_response_t *res)
    {
        switch (res->status) {
            case 200:
                return APR_SUCCESS;
            case 400:
                return APR_EINVAL;
            case 401: /* sectigo returns this instead of 403 */
            case 403:
                return APR_EACCES;
            case 404:
                return APR_ENOENT;
            default:
                return APR_EGENERAL;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t on_get_cert(const md_http_response_t *res, void *baton)
    {
        ts_ctx_t *ts_ctx = baton;
        apr_status_t rv;
    
        rv = rv_of_response(res);
        if (APR_SUCCESS != rv) goto leave;
        apr_array_clear(ts_ctx->chain);
        rv = md_cert_chain_read_http(ts_ctx->chain, ts_ctx->pool, res);
        if (APR_SUCCESS != rv) goto leave;
    
    leave:
        return rv;
    }
    
    static apr_status_t on_get_key(const md_http_response_t *res, void *baton)
    {
        ts_ctx_t *ts_ctx = baton;
        apr_status_t rv;
    
        rv = rv_of_response(res);
        if (APR_SUCCESS != rv) goto leave;
        rv = md_pkey_read_http(&ts_ctx->pkey, ts_ctx->pool, res);
        if (APR_SUCCESS != rv) goto leave;
    
    leave:
        return rv;
    }
    
    static apr_status_t ts_renew(md_proto_driver_t *d, md_result_t *result)
    {
        const char *name, *domain, *url;
        apr_status_t rv = APR_ENOENT;
        ts_ctx_t *ts_ctx = d->baton;
        md_http_t *http;
        const md_pubcert_t *pubcert;
        md_cert_t *old_cert, *new_cert;
        int reset_staging = d->reset;
    
        /* "renewing" the certificate from tailscale. Since tailscale has its
         * own ideas on when to do this, we can only inspect the certificate
         * it gives us and see if it is different from the current one we have.
         * (if we have any. first time, lacking a cert, any it gives us is
         *  considered as 'renewed'.)
         */
        name = d->md->name;
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: renewing cert", name);
    
        /* When not explicitly told to reset, we check the existing data. If
         * it is incomplete or old, we trigger the reset for a clean start. */
        if (!reset_staging) {
            md_result_activity_setn(result, "Checking staging area");
            rv = md_load(d->store, MD_SG_STAGING, d->md->name, &ts_ctx->md, d->p);
            if (APR_SUCCESS == rv) {
                /* So, we have a copy in staging, but is it a recent or an old one? */
                if (md_is_newer(d->store, MD_SG_DOMAINS, MD_SG_STAGING, d->md->name, d->p)) {
                    reset_staging = 1;
                }
            }
            else if (APR_STATUS_IS_ENOENT(rv)) {
                reset_staging = 1;
                rv = APR_SUCCESS;
            }
        }
    
        if (reset_staging) {
            md_result_activity_setn(result, "Resetting staging area");
            /* reset the staging area for this domain */
            rv = md_store_purge(d->store, d->p, MD_SG_STAGING, d->md->name);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, d->p,
                          "%s: reset staging area", d->md->name);
            if (APR_SUCCESS != rv && !APR_STATUS_IS_ENOENT(rv)) {
                md_result_printf(result, rv, "resetting staging area");
                goto leave;
            }
            rv = APR_SUCCESS;
            ts_ctx->md = NULL;
        }
    
        if (!ts_ctx->md || !md_array_str_eq(ts_ctx->md->ca_urls, d->md->ca_urls, 1)) {
            md_result_activity_printf(result, "Resetting staging for %s", d->md->name);
            /* re-initialize staging */
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: setup staging", d->md->name);
            md_store_purge(d->store, d->p, MD_SG_STAGING, d->md->name);
            ts_ctx->md = md_copy(d->p, d->md);
            rv = md_save(d->store, d->p, MD_SG_STAGING, ts_ctx->md, 0);
            if (APR_SUCCESS != rv) {
                md_result_printf(result, rv, "Saving MD information in staging area.");
                md_result_log(result, MD_LOG_ERR);
                goto leave;
            }
        }
    
        if (!ts_ctx->unix_socket_path) {
            rv = APR_ENOTIMPL;
            md_result_set(result, rv, "only unix sockets are supported for tailscale connections");
            goto leave;
        }
    
        rv = md_util_is_unix_socket(ts_ctx->unix_socket_path, d->p);
        if (APR_SUCCESS != rv) {
            md_result_printf(result, rv, "tailscale socket not available, may not be up: %s",
                             ts_ctx->unix_socket_path);
            goto leave;
        }
    
        rv = md_http_create(&http, d->p,
                            apr_psprintf(d->p, "Apache mod_md/%s", MOD_MD_VERSION),
                            NULL);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, "creating http context");
            goto leave;
        }
        md_http_set_unix_socket_path(http, ts_ctx->unix_socket_path);
    
        domain = (d->md->domains->nelts > 0)?
                  APR_ARRAY_IDX(d->md->domains, 0, const char*) : NULL;
        if (!domain) {
            rv = APR_EINVAL;
            md_result_set(result, rv, "no domain names available");
        }
    
        url = apr_psprintf(d->p, "http://localhost/localapi/v0/cert/%s?type=crt",
                           domain);
        rv = md_http_GET_perform(http, url, NULL, on_get_cert, ts_ctx);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, "retrieving certificate from tailscale");
            goto leave;
        }
        if (ts_ctx->chain->nelts <= 0) {
            rv = APR_ENOENT;
            md_result_set(result, rv, "tailscale returned no certificates");
            goto leave;
        }
    
        /* Got the key and the chain, is it new? */
        rv = md_reg_get_pubcert(&pubcert, d->reg,d->md, 0, d->p);
        if (APR_SUCCESS == rv) {
            old_cert = APR_ARRAY_IDX(pubcert->certs, 0, md_cert_t*);
            new_cert = APR_ARRAY_IDX(ts_ctx->chain, 0, md_cert_t*);
            if (md_certs_are_equal(old_cert, new_cert)) {
                /* tailscale has not renewed the certificate, yet */
                rv = APR_ENOENT;
                md_result_set(result, rv, "tailscale has not renewed the certificate yet");
                /* let's check this daily */
                md_result_delay_set(result, apr_time_now() + apr_time_from_sec(MD_SECS_PER_DAY));
                goto leave;
            }
        }
    
        /* We have a new certificate (or had none before).
         * Get the key and store both in STAGING.
         */
        url = apr_psprintf(d->p, "http://localhost/localapi/v0/cert/%s?type=key",
                           domain);
        rv = md_http_GET_perform(http, url, NULL, on_get_key, ts_ctx);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, "retrieving key from tailscale");
            goto leave;
        }
    
        rv = md_pkey_save(d->store, d->p, MD_SG_STAGING, name, NULL, ts_ctx->pkey, 1);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, "saving private key");
            goto leave;
        }
    
        rv = md_pubcert_save(d->store, d->p, MD_SG_STAGING, name,
                             NULL, ts_ctx->chain, 1);
        if (APR_SUCCESS != rv) {
            md_result_printf(result, rv, "saving new certificate chain.");
            goto leave;
        }
    
        md_result_set(result, APR_SUCCESS,
            "A new tailscale certificate has been retrieved successfully and can "
            "be used. A graceful server restart is recommended.");
    
    leave:
        md_result_log(result, MD_LOG_DEBUG);
        return rv;
    }
    
    static apr_status_t ts_complete_md(md_t *md, apr_pool_t *p)
    {
        (void)p;
        if (!md->ca_urls) {
            md->ca_urls = apr_array_make(p, 3, sizeof(const char *));
            APR_ARRAY_PUSH(md->ca_urls, const char*) = MD_TAILSCALE_DEF_URL;
        }
        return APR_SUCCESS;
    }
    
    
    static md_proto_t TAILSCALE_PROTO = {
        MD_PROTO_TAILSCALE, ts_init, ts_renew,
        ts_preload_init, ts_preload, ts_complete_md,
    };
    
    apr_status_t md_tailscale_protos_add(apr_hash_t *protos, apr_pool_t *p)
    {
        (void)p;
        apr_hash_set(protos, MD_PROTO_TAILSCALE, sizeof(MD_PROTO_TAILSCALE)-1, &TAILSCALE_PROTO);
        return APR_SUCCESS;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_event.c������������������������������������������������������������������0000664�0001751�0001751�00000004657�14046725222�016657� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
    * this work for additional information regarding copyright ownership.
    * The ASF licenses this file to You under the Apache License, Version 2.0
    * (the "License"); you may not use this file except in compliance with
    * the License.  You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT 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 <assert.h>
    #include <apr_optional.h>
    #include <apr_strings.h>
    
    #include "md.h"
    #include "md_event.h"
    
    
    typedef struct md_subscription {
        struct md_subscription *next;
        md_event_cb *cb;
        void *baton;
    } md_subscription;
    
    static struct {
        apr_pool_t *p;
        md_subscription *subs;
    } EVNT;
    
    static apr_status_t cleanup_setup(void *dummy)
    {
        (void)dummy;
        memset(&EVNT, 0, sizeof(EVNT));
        return APR_SUCCESS;
    }
    
    void md_event_init(apr_pool_t *p)
    {
        memset(&EVNT, 0, sizeof(EVNT));
        EVNT.p = p;
        apr_pool_cleanup_register(p, NULL, cleanup_setup, apr_pool_cleanup_null);
    }
    
    void md_event_subscribe(md_event_cb *cb, void *baton)
    {
        md_subscription *sub;
        
        sub = apr_pcalloc(EVNT.p, sizeof(*sub));
        sub->cb = cb;
        sub->baton = baton;
        sub->next = EVNT.subs;
        EVNT.subs = sub;
    } 
    
    apr_status_t md_event_raise(const char *event, 
                                const char *mdomain, 
                                struct md_job_t *job, 
                                struct md_result_t *result, 
                                apr_pool_t *p)
    {
        md_subscription *sub = EVNT.subs;
        apr_status_t rv;
    
        while (sub) {
            rv = sub->cb(event, mdomain, sub->baton, job, result, p);
            if (APR_SUCCESS != rv) return rv;
            sub = sub->next;
        }
        return APR_SUCCESS;
    }
    
    void md_event_holler(const char *event, 
                         const char *mdomain, 
                         struct md_job_t *job, 
                         struct md_result_t *result, 
                         apr_pool_t *p)
    {
        md_subscription *sub = EVNT.subs;
        while (sub) {
            sub->cb(event, mdomain, sub->baton, job, result, p);
            sub = sub->next;
        }
    }
    ���������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_result.h�����������������������������������������������������������������0000664�0001751�0001751�00000007014�14046725222�017047� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_result_h
    #define mod_md_md_result_h
    
    struct md_json_t;
    struct md_t;
    
    typedef struct md_result_t md_result_t;
    
    typedef void md_result_change_cb(md_result_t *result, void *data);
    typedef apr_status_t md_result_raise_cb(md_result_t *result, void *data, const char *event, apr_pool_t *p);
    typedef void md_result_holler_cb(md_result_t *result, void *data, const char *event, apr_pool_t *p);
    
    struct md_result_t {
        apr_pool_t *p;
        const char *md_name;
        apr_status_t status;
        const char *problem;
        const char *detail;
        const struct md_json_t *subproblems;
        const char *activity;
        apr_time_t ready_at;
        md_result_change_cb *on_change;
        void *on_change_data;
        md_result_raise_cb *on_raise;
        void *on_raise_data;
        md_result_holler_cb *on_holler;
        void *on_holler_data;
    };
    
    md_result_t *md_result_make(apr_pool_t *p, apr_status_t status);
    md_result_t *md_result_md_make(apr_pool_t *p, const char *md_name);
    void md_result_reset(md_result_t *result);
    
    void md_result_activity_set(md_result_t *result, const char *activity);
    void md_result_activity_setn(md_result_t *result, const char *activity);
    void md_result_activity_printf(md_result_t *result, const char *fmt, ...);
    
    void md_result_set(md_result_t *result, apr_status_t status, const char *detail);
    void md_result_problem_set(md_result_t *result, apr_status_t status, 
                               const char *problem, const char *detail, 
                               const struct md_json_t *subproblems);
    void md_result_problem_printf(md_result_t *result, apr_status_t status,
                                  const char *problem, const char *fmt, ...);
    
    #define MD_RESULT_LOG_ID(logno)       "urn:org:apache:httpd:log:"logno
    
    void md_result_printf(md_result_t *result, apr_status_t status, const char *fmt, ...);
    
    void md_result_delay_set(md_result_t *result, apr_time_t ready_at);
    
    md_result_t*md_result_from_json(const struct md_json_t *json, apr_pool_t *p);
    struct md_json_t *md_result_to_json(const md_result_t *result, apr_pool_t *p);
    
    int md_result_cmp(const md_result_t *r1, const md_result_t *r2);
    
    void md_result_assign(md_result_t *dest, const md_result_t *src);
    void md_result_dup(md_result_t *dest, const md_result_t *src);
    
    void md_result_log(md_result_t *result, unsigned int level);
    
    void md_result_on_change(md_result_t *result, md_result_change_cb *cb, void *data);
    
    /* events in the context of a result genesis */
    
    apr_status_t md_result_raise(md_result_t *result, const char *event, apr_pool_t *p);
    void md_result_holler(md_result_t *result, const char *event, apr_pool_t *p);
    
    void md_result_on_raise(md_result_t *result, md_result_raise_cb *cb, void *data);
    void md_result_on_holler(md_result_t *result, md_result_holler_cb *cb, void *data);
    
    #endif /* mod_md_md_result_h */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_ocsp.h���������������������������������������������������������������0000664�0001751�0001751�00000002470�14072773643�017346� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_ocsp_h
    #define mod_md_md_ocsp_h
    
    
    int md_ocsp_prime_status(server_rec *s, apr_pool_t *p,
                             const char *id, apr_size_t id_len, const char *pem);
    
    int md_ocsp_provide_status(server_rec *s, conn_rec *c, const char *id, apr_size_t id_len,
                               ap_ssl_ocsp_copy_resp *cb, void *userdata);
    
    /**
     * Start watchdog for retrieving/updating ocsp status.
     */
    apr_status_t md_ocsp_start_watching(struct md_mod_conf_t *mc, server_rec *s, apr_pool_t *p);
    
    
    #endif /* mod_md_md_ocsp_h */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_result.c�����������������������������������������������������������������0000664�0001751�0001751�00000021252�14046725222�017042� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_date.h>
    #include <apr_time.h>
    #include <apr_strings.h>
    
    #include "md.h"
    #include "md_json.h"
    #include "md_log.h"
    #include "md_result.h"
    
    static const char *dup_trim(apr_pool_t *p, const char *s)
    {
        char *d = apr_pstrdup(p, s);
        if (d) apr_collapse_spaces(d, d);
        return d;
    }
    
    md_result_t *md_result_make(apr_pool_t *p, apr_status_t status)
    {
        md_result_t *result;
        
        result = apr_pcalloc(p, sizeof(*result));
        result->p = p;
        result->md_name = MD_OTHER;
        result->status = status;
        return result;
    }
    
    md_result_t *md_result_md_make(apr_pool_t *p, const char *md_name)
    {
        md_result_t *result = md_result_make(p, APR_SUCCESS);
        result->md_name = md_name;
        return result;
    }
    
    void md_result_reset(md_result_t *result)
    {
        apr_pool_t *p = result->p;
        memset(result, 0, sizeof(*result));
        result->p = p;
    }
    
    static void on_change(md_result_t *result)
    {
        if (result->on_change) result->on_change(result, result->on_change_data);
    }
    
    void md_result_activity_set(md_result_t *result, const char *activity)
    {
        md_result_activity_setn(result, activity? apr_pstrdup(result->p, activity) : NULL);
    }
    
    void md_result_activity_setn(md_result_t *result, const char *activity)
    {
        result->activity = activity;
        result->problem = result->detail = NULL;
        result->subproblems = NULL;
        on_change(result);
    }
    
    void md_result_activity_printf(md_result_t *result, const char *fmt, ...)
    {
        va_list ap;
    
        va_start(ap, fmt);
        md_result_activity_setn(result, apr_pvsprintf(result->p, fmt, ap));
        va_end(ap);
    }
    
    void md_result_set(md_result_t *result, apr_status_t status, const char *detail)
    {
        result->status = status;
        result->problem = NULL;
        result->detail = detail? apr_pstrdup(result->p, detail) : NULL;
        result->subproblems = NULL;
        on_change(result);
    }
    
    void md_result_problem_set(md_result_t *result, apr_status_t status,
                               const char *problem, const char *detail, 
                               const md_json_t *subproblems)
    {
        result->status = status;
        result->problem = dup_trim(result->p, problem);
        result->detail = apr_pstrdup(result->p, detail);
        result->subproblems = subproblems? md_json_clone(result->p, subproblems) : NULL;
        on_change(result);
    }
    
    void md_result_problem_printf(md_result_t *result, apr_status_t status,
                                  const char *problem, const char *fmt, ...)
    {
        va_list ap;
    
        result->status = status;
        result->problem = dup_trim(result->p, problem);
    
        va_start(ap, fmt);
        result->detail = apr_pvsprintf(result->p, fmt, ap);
        va_end(ap);
        result->subproblems = NULL;
        on_change(result);
    }
    
    void md_result_printf(md_result_t *result, apr_status_t status, const char *fmt, ...)
    {
        va_list ap;
    
        result->status = status;
        va_start(ap, fmt);
        result->detail = apr_pvsprintf(result->p, fmt, ap);
        va_end(ap);
        result->subproblems = NULL;
        on_change(result);
    }
    
    void md_result_delay_set(md_result_t *result, apr_time_t ready_at)
    {
        result->ready_at = ready_at;
        on_change(result);
    }
    
    md_result_t*md_result_from_json(const struct md_json_t *json, apr_pool_t *p)
    {
        md_result_t *result;
        const char *s;
        
        result = md_result_make(p, APR_SUCCESS);
        result->status = (int)md_json_getl(json, MD_KEY_STATUS, NULL);
        result->problem = md_json_dups(p, json, MD_KEY_PROBLEM, NULL);
        result->detail = md_json_dups(p, json, MD_KEY_DETAIL, NULL);
        result->activity = md_json_dups(p, json, MD_KEY_ACTIVITY, NULL);
        s = md_json_dups(p, json, MD_KEY_VALID_FROM, NULL);
        if (s && *s) result->ready_at = apr_date_parse_rfc(s);
        result->subproblems = md_json_dupj(p, json, MD_KEY_SUBPROBLEMS, NULL);
        return result;
    }
    
    struct md_json_t *md_result_to_json(const md_result_t *result, apr_pool_t *p)
    {
        md_json_t *json;
        char ts[APR_RFC822_DATE_LEN];
       
        json = md_json_create(p);
        md_json_setl(result->status, json, MD_KEY_STATUS, NULL);
        if (result->status > 0) {
            char buffer[HUGE_STRING_LEN];
            apr_strerror(result->status, buffer, sizeof(buffer));
            md_json_sets(buffer, json, "status-description", NULL);
        }
        if (result->problem) md_json_sets(result->problem, json, MD_KEY_PROBLEM, NULL);
        if (result->detail) md_json_sets(result->detail, json, MD_KEY_DETAIL, NULL);
        if (result->activity) md_json_sets(result->activity, json, MD_KEY_ACTIVITY, NULL);
        if (result->ready_at > 0) {
            apr_rfc822_date(ts, result->ready_at);
            md_json_sets(ts, json, MD_KEY_VALID_FROM, NULL);
        }
        if (result->subproblems) {
            md_json_setj(result->subproblems, json, MD_KEY_SUBPROBLEMS, NULL);
        }
        return json;
    }
    
    static int str_cmp(const char *s1, const char *s2)
    {
        if (s1 == s2) return 0;
        if (!s1) return -1;
        if (!s2) return 1;
        return strcmp(s1, s2);
    }
    
    int md_result_cmp(const md_result_t *r1, const md_result_t *r2)
    {
        int n;
        if (r1 == r2) return 0;
        if (!r1) return -1;
        if (!r2) return 1;
        if ((n = r1->status - r2->status)) return n;
        if ((n = str_cmp(r1->problem, r2->problem))) return n;
        if ((n = str_cmp(r1->detail, r2->detail))) return n;
        if ((n = str_cmp(r1->activity, r2->activity))) return n;
        return (int)(r1->ready_at - r2->ready_at);
    }
    
    void md_result_assign(md_result_t *dest, const md_result_t *src)
    {
       dest->status = src->status;
       dest->problem = src->problem;
       dest->detail = src->detail;
       dest->activity = src->activity;
       dest->ready_at = src->ready_at;
       dest->subproblems = src->subproblems;
    }
    
    void md_result_dup(md_result_t *dest, const md_result_t *src)
    {
       dest->status = src->status;
       dest->problem = src->problem? dup_trim(dest->p, src->problem) : NULL; 
       dest->detail = src->detail? apr_pstrdup(dest->p, src->detail) : NULL; 
       dest->activity = src->activity? apr_pstrdup(dest->p, src->activity) : NULL; 
       dest->ready_at = src->ready_at;
       dest->subproblems = src->subproblems? md_json_clone(dest->p, src->subproblems) : NULL;
       on_change(dest);
    }
    
    void md_result_log(md_result_t *result, unsigned int level)
    {
        if (md_log_is_level(result->p, (md_log_level_t)level)) {
            const char *sep = "";
            const char *msg = "";
            
            if (result->md_name) {
                msg = apr_psprintf(result->p, "md[%s]", result->md_name);
                sep = " ";
            }
            if (result->activity) {
                msg = apr_psprintf(result->p, "%s%swhile[%s]", msg, sep, result->activity);
                sep = " ";
            }
            if (result->problem) {
                msg = apr_psprintf(result->p, "%s%sproblem[%s]", msg, sep, result->problem);
                sep = " ";
            }
            if (result->detail) {
                msg = apr_psprintf(result->p, "%s%sdetail[%s]", msg, sep, result->detail);
                sep = " ";
            }
            if (result->subproblems) {
                msg = apr_psprintf(result->p, "%s%ssubproblems[%s]", msg, sep, 
                    md_json_writep(result->subproblems, result->p, MD_JSON_FMT_COMPACT));
                sep = " ";
            }
            md_log_perror(MD_LOG_MARK, (md_log_level_t)level, result->status, result->p, "%s", msg);
        }
    }
    
    void md_result_on_change(md_result_t *result, md_result_change_cb *cb, void *data)
    {
        result->on_change = cb;
        result->on_change_data = data;
    }
    
    apr_status_t md_result_raise(md_result_t *result, const char *event, apr_pool_t *p)
    {
        if (result->on_raise) return result->on_raise(result, result->on_raise_data, event, p);
        return APR_SUCCESS;
    }
    
    void md_result_holler(md_result_t *result, const char *event, apr_pool_t *p)
    {
        if (result->on_holler) result->on_holler(result, result->on_holler_data, event, p);
    }
    
    void md_result_on_raise(md_result_t *result, md_result_raise_cb *cb, void *data)
    {
        result->on_raise = cb;
        result->on_raise_data = data;
    }
    
    void md_result_on_holler(md_result_t *result, md_result_holler_cb *cb, void *data)
    {
        result->on_holler = cb;
        result->on_holler_data = data;
    }
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_ocsp.c���������������������������������������������������������������0000664�0001751�0001751�00000024070�14072773643�017341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_optional.h>
    #include <apr_time.h>
    #include <apr_date.h>
    #include <apr_strings.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <http_ssl.h>
    
    #include "mod_watchdog.h"
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_http.h"
    #include "md_json.h"
    #include "md_ocsp.h"
    #include "md_store.h"
    #include "md_log.h"
    #include "md_reg.h"
    #include "md_time.h"
    #include "md_util.h"
    
    #include "mod_md.h"
    #include "mod_md_config.h"
    #include "mod_md_private.h"
    #include "mod_md_ocsp.h"
    
    static int staple_here(md_srv_conf_t *sc) 
    {
        if (!sc || !sc->mc->ocsp) return 0;
        if (sc->assigned 
            && sc->assigned->nelts == 1
            && APR_ARRAY_IDX(sc->assigned, 0, const md_t*)->stapling) return 1;
        return (md_config_geti(sc, MD_CONFIG_STAPLING) 
                && md_config_geti(sc, MD_CONFIG_STAPLE_OTHERS));
    }
    
    int md_ocsp_prime_status(server_rec *s, apr_pool_t *p,
                             const char *id, apr_size_t id_len, const char *pem)
    {
        md_srv_conf_t *sc;
        const md_t *md;
        apr_array_header_t *chain;
        apr_status_t rv = APR_ENOENT;
    
        sc = md_config_get(s);
        if (!staple_here(sc)) goto cleanup;
    
        md = ((sc->assigned && sc->assigned->nelts == 1)?
              APR_ARRAY_IDX(sc->assigned, 0, const md_t*) : NULL);
        chain = apr_array_make(p, 5, sizeof(md_cert_t*));
        rv = md_cert_read_chain(chain, p, pem, strlen(pem));
        if (APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10268) "init stapling for: %s, "
                         "unable to parse PEM data", md? md->name : s->server_hostname);
            goto cleanup;
        }
        else if (chain->nelts < 2) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10269) "init stapling for: %s, "
                         "need at least 2 certificates in PEM data", md? md->name : s->server_hostname);
            rv = APR_EINVAL;
            goto cleanup;
        }
    
        rv = md_ocsp_prime(sc->mc->ocsp, id, id_len,
                           APR_ARRAY_IDX(chain, 0, md_cert_t*),
                           APR_ARRAY_IDX(chain, 1, md_cert_t*), md);
        ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, s, "init stapling for: %s",
                     md? md->name : s->server_hostname);
    
    cleanup:
        return (APR_SUCCESS == rv)? OK : DECLINED;
    }
    
    typedef struct {
        unsigned char *der;
        apr_size_t der_len;
    } ocsp_copy_ctx_t;
    
    int md_ocsp_provide_status(server_rec *s, conn_rec *c,
                               const char *id, apr_size_t id_len,
                               ap_ssl_ocsp_copy_resp *cb, void *userdata)
    {
        md_srv_conf_t *sc;
        const md_t *md;
        apr_status_t rv;
    
        sc = md_config_get(s);
        if (!staple_here(sc)) goto declined;
    
        md = ((sc->assigned && sc->assigned->nelts == 1)?
              APR_ARRAY_IDX(sc->assigned, 0, const md_t*) : NULL);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "get stapling for: %s",
                      md? md->name : s->server_hostname);
    
        rv = md_ocsp_get_status(cb, userdata, sc->mc->ocsp, id, id_len, c->pool, md);
        if (APR_STATUS_IS_ENOENT(rv)) goto declined;
        return OK;
    
    declined:
        return DECLINED;
    }
    
    
    /**************************************************************************************************/
    /* watchdog based impl. */
    
    #define MD_OCSP_WATCHDOG_NAME   "_md_ocsp_"
    
    static APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *wd_get_instance;
    static APR_OPTIONAL_FN_TYPE(ap_watchdog_register_callback) *wd_register_callback;
    static APR_OPTIONAL_FN_TYPE(ap_watchdog_set_callback_interval) *wd_set_interval;
    
    typedef struct md_ocsp_ctx_t md_ocsp_ctx_t;
    
    struct md_ocsp_ctx_t {
        apr_pool_t *p;
        server_rec *s;
        md_mod_conf_t *mc;
        ap_watchdog_t *watchdog;
    };
    
    static apr_time_t next_run_default(void)
    {
        /* we'd like to run at least hourly */
        return apr_time_now() + apr_time_from_sec(MD_SECS_PER_HOUR);
    }
    
    static apr_status_t run_watchdog(int state, void *baton, apr_pool_t *ptemp)
    {
        md_ocsp_ctx_t *octx = baton;
        apr_time_t next_run, wait_time;
        
        /* mod_watchdog invoked us as a single thread inside the whole server (on this machine).
         * This might be a repeated run inside the same child (mod_watchdog keeps affinity as
         * long as the child lives) or another/new child.
         */
        switch (state) {
            case AP_WATCHDOG_STATE_STARTING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, octx->s, APLOGNO(10197)
                             "md ocsp watchdog start, ocsp stapling %d certificates", 
                             (int)md_ocsp_count(octx->mc->ocsp));
                break;
                
            case AP_WATCHDOG_STATE_RUNNING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, octx->s, APLOGNO(10198)
                             "md ocsp watchdog run, ocsp stapling %d certificates", 
                             (int)md_ocsp_count(octx->mc->ocsp));
                             
                /* Process all drive jobs. They will update their next_run property
                 * and we schedule ourself at the earliest of all. A job may specify 0
                 * as next_run to indicate that it wants to participate in the normal
                 * regular runs. */
                next_run = next_run_default();
                
                md_ocsp_renew(octx->mc->ocsp, octx->p, ptemp, &next_run);
                
                wait_time = next_run - apr_time_now();
                if (APLOGdebug(octx->s)) {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, octx->s, APLOGNO(10199)
                                 "md ocsp watchdog next run in %s", 
                                 md_duration_print(ptemp, wait_time));
                }
                wd_set_interval(octx->watchdog, wait_time, octx, run_watchdog);
                break;
                
            case AP_WATCHDOG_STATE_STOPPING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, octx->s, APLOGNO(10200)
                             "md ocsp watchdog stopping");
                break;
        }
        
        return APR_SUCCESS;
    }
    
    static apr_status_t ocsp_remove_old_responses(md_mod_conf_t *mc, apr_pool_t *p)
    {
        md_timeperiod_t keep_norm, keep;
        
        keep_norm.end = apr_time_now();
        keep_norm.start = keep_norm.end - MD_TIME_OCSP_KEEP_NORM;
        keep = md_timeperiod_slice_before_end(&keep_norm, mc->ocsp_keep_window);
        /* remove any ocsp response older than keep.start */
        return md_ocsp_remove_responses_older_than(mc->ocsp, p, keep.start);
    }
    
    apr_status_t md_ocsp_start_watching(md_mod_conf_t *mc, server_rec *s, apr_pool_t *p)
    {
        apr_allocator_t *allocator;
        md_ocsp_ctx_t *octx;
        apr_pool_t *octxp;
        apr_status_t rv;
        
        wd_get_instance = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_get_instance);
        wd_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback);
        wd_set_interval = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_set_callback_interval);
        
        if (!wd_get_instance || !wd_register_callback || !wd_set_interval) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(10201) 
                         "mod_watchdog is required for OCSP stapling");
            return APR_EGENERAL;
        }
        
        /* We want our own pool with own allocator to keep data across watchdog invocations.
         * Since we'll run in a single watchdog thread, using our own allocator will prevent 
         * any confusion in the parent pool. */
        apr_allocator_create(&allocator);
        apr_allocator_max_free_set(allocator, 1);
        rv = apr_pool_create_ex(&octxp, p, NULL, allocator);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10205) "md_ocsp_watchdog: create pool");
            return rv;
        }
        apr_allocator_owner_set(allocator, octxp);
        apr_pool_tag(octxp, "md_ocsp_watchdog");
    
        octx = apr_pcalloc(octxp, sizeof(*octx));
        octx->p = octxp;
        octx->s = s;
        octx->mc = mc;
        
        /* Time for some house keeping, before the server goes live (again):
         * - we store OCSP responses for each certificate individually by its SHA-1 id
         * - this means, as long as certificate do not change, the number of response
         *   files remains stable.
         * - But when a certificate changes (is replaced), the response is obsolete
         * - we do not get notified when a certificate is no longer used. An admin
         *   might just reconfigure or change the content of a file (backup/restore etc.)
         * - also, certificates might be added by some openssl config commands or other
         *   modules that we do not immediately see right at startup. We cannot assume
         *   that any OCSP response we cannot relate to a certificate RIGHT NOW, is no
         *   longer needed.
         * - since the response files are relatively small, we have no problem with
         *   keeping them around for a while. We just do not want an ever growing store. 
         * - The simplest and effective way seems to be to just remove files older
         *   a certain amount of time. Take a 7 day default and let the admin configure
         *   it for very special setups. 
         */ 
        ocsp_remove_old_responses(mc, octx->p);
        
        rv = wd_get_instance(&octx->watchdog, MD_OCSP_WATCHDOG_NAME, 0, 1, octx->p);
        if (APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(10202) 
                         "create md ocsp watchdog(%s)", MD_OCSP_WATCHDOG_NAME);
            return rv;
        }
        rv = wd_register_callback(octx->watchdog, 0, octx, run_watchdog);
        ap_log_error(APLOG_MARK, rv? APLOG_CRIT : APLOG_DEBUG, rv, s, APLOGNO(10203) 
                     "register md ocsp watchdog(%s)", MD_OCSP_WATCHDOG_NAME);
        return rv;
    }
    
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_json.h�������������������������������������������������������������������0000664�0001751�0001751�00000015077�14046725222�016512� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_json_h
    #define mod_md_md_json_h
    
    #include <apr_file_io.h>
    
    struct apr_bucket_brigade;
    struct apr_file_t;
    
    struct md_http_t;
    struct md_http_response_t;
    struct md_timeperiod_t;
    
    typedef struct md_json_t md_json_t;
    
    typedef enum {
        MD_JSON_TYPE_OBJECT,
        MD_JSON_TYPE_ARRAY,
        MD_JSON_TYPE_STRING,
        MD_JSON_TYPE_REAL,
        MD_JSON_TYPE_INT,
        MD_JSON_TYPE_BOOL,
        MD_JSON_TYPE_NULL,
    } md_json_type_t;
    
    
    typedef enum {
        MD_JSON_FMT_COMPACT,
        MD_JSON_FMT_INDENT,
    } md_json_fmt_t;
    
    md_json_t *md_json_create(apr_pool_t *pool);
    void md_json_destroy(md_json_t *json);
    
    md_json_t *md_json_copy(apr_pool_t *pool, const md_json_t *json);
    md_json_t *md_json_clone(apr_pool_t *pool, const md_json_t *json);
    
    
    int md_json_has_key(const md_json_t *json, ...);
    int md_json_is(const md_json_type_t type, md_json_t *json, ...);
    
    /* boolean manipulation */
    int md_json_getb(const md_json_t *json, ...);
    apr_status_t md_json_setb(int value, md_json_t *json, ...);
    
    /* number manipulation */
    double md_json_getn(const md_json_t *json, ...);
    apr_status_t md_json_setn(double value, md_json_t *json, ...);
    
    /* long manipulation */
    long md_json_getl(const md_json_t *json, ...);
    apr_status_t md_json_setl(long value, md_json_t *json, ...);
    
    /* string manipulation */
    md_json_t *md_json_create_s(apr_pool_t *pool, const char *s);
    const char *md_json_gets(const md_json_t *json, ...);
    const char *md_json_dups(apr_pool_t *p, const md_json_t *json, ...);
    apr_status_t md_json_sets(const char *s, md_json_t *json, ...);
    
    /* timestamp manipulation */
    apr_time_t md_json_get_time(const md_json_t *json, ...);
    apr_status_t md_json_set_time(apr_time_t value, md_json_t *json, ...);
    
    /* json manipulation */
    md_json_t *md_json_getj(md_json_t *json, ...);
    md_json_t *md_json_dupj(apr_pool_t *p, const md_json_t *json, ...);
    const md_json_t *md_json_getcj(const md_json_t *json, ...);
    apr_status_t md_json_setj(const md_json_t *value, md_json_t *json, ...);
    apr_status_t md_json_addj(const md_json_t *value, md_json_t *json, ...);
    apr_status_t md_json_insertj(md_json_t *value, size_t index, md_json_t *json, ...);
    
    /* Array/Object manipulation */
    apr_status_t md_json_clr(md_json_t *json, ...);
    apr_status_t md_json_del(md_json_t *json, ...);
    
    /* Remove all array elements beyond max_elements */ 
    apr_size_t md_json_limita(size_t max_elements, md_json_t *json, ...);
    
    /* conversion function from and to json */
    typedef apr_status_t md_json_to_cb(void *value, md_json_t *json, apr_pool_t *p, void *baton);
    typedef apr_status_t md_json_from_cb(void **pvalue, md_json_t *json, apr_pool_t *p, void *baton);
    
    /* identity pass through from json to json */
    apr_status_t md_json_pass_to(void *value, md_json_t *json, apr_pool_t *p, void *baton);
    apr_status_t md_json_pass_from(void **pvalue, md_json_t *json, apr_pool_t *p, void *baton);
    
    /* conversions from json to json in specified pool */
    apr_status_t md_json_clone_to(void *value, md_json_t *json, apr_pool_t *p, void *baton);
    apr_status_t md_json_clone_from(void **pvalue, const md_json_t *json, apr_pool_t *p, void *baton);
    
    /* Manipulating/Iteration on generic Arrays */
    apr_status_t md_json_geta(apr_array_header_t *a, md_json_from_cb *cb, 
                              void *baton, const md_json_t *json, ...);
    apr_status_t md_json_seta(apr_array_header_t *a, md_json_to_cb *cb, 
                              void *baton, md_json_t *json, ...);
    
    /* Called on each array element, aborts iteration when returning 0 */
    typedef int md_json_itera_cb(void *baton, size_t index, md_json_t *json);
    int md_json_itera(md_json_itera_cb *cb, void *baton, md_json_t *json, ...);
    
    /* Called on each object key, aborts iteration when returning 0 */
    typedef int md_json_iterkey_cb(void *baton, const char* key, md_json_t *json);
    int md_json_iterkey(md_json_iterkey_cb *cb, void *baton, md_json_t *json, ...);
    
    /* Manipulating Object String values */
    apr_status_t md_json_gets_dict(apr_table_t *dict, const md_json_t *json, ...);
    apr_status_t md_json_sets_dict(apr_table_t *dict, md_json_t *json, ...);
    
    /* Manipulating String Arrays */
    apr_status_t md_json_getsa(apr_array_header_t *a, const md_json_t *json, ...);
    apr_status_t md_json_dupsa(apr_array_header_t *a, apr_pool_t *p, md_json_t *json, ...);
    apr_status_t md_json_setsa(apr_array_header_t *a, md_json_t *json, ...);
    
    /* serialization & parsing */
    apr_status_t md_json_writeb(const md_json_t *json, md_json_fmt_t fmt, struct apr_bucket_brigade *bb);
    const char *md_json_writep(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt);
    apr_status_t md_json_writef(const md_json_t *json, apr_pool_t *p, 
                                md_json_fmt_t fmt, struct apr_file_t *f);
    apr_status_t md_json_fcreatex(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt, 
                                  const char *fpath, apr_fileperms_t perms);
    apr_status_t md_json_freplace(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt, 
                                  const char *fpath, apr_fileperms_t perms);
    
    apr_status_t md_json_readb(md_json_t **pjson, apr_pool_t *pool, struct apr_bucket_brigade *bb);
    apr_status_t md_json_readd(md_json_t **pjson, apr_pool_t *pool, const char *data, size_t data_len);
    apr_status_t md_json_readf(md_json_t **pjson, apr_pool_t *pool, const char *fpath);
    
    
    /* http retrieval */
    apr_status_t md_json_http_get(md_json_t **pjson, apr_pool_t *pool,
                                  struct md_http_t *http, const char *url);
    apr_status_t md_json_read_http(md_json_t **pjson, apr_pool_t *pool, 
                                   const struct md_http_response_t *res);
    
    apr_status_t md_json_copy_to(md_json_t *dest, const md_json_t *src, ...);
    
    const char *md_json_dump_state(const md_json_t *json, apr_pool_t *p);
    
    apr_status_t md_json_set_timeperiod(const struct md_timeperiod_t *tp, md_json_t *json, ...);
    apr_status_t md_json_get_timeperiod(struct md_timeperiod_t *tp, md_json_t *json, ...);
    
    #endif /* md_json_h */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md.h��������������������������������������������������������������������0000664�0001751�0001751�00000001556�14072773643�016326� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_mod_md_h
    #define mod_md_mod_md_h
    
    #endif /* mod_md_mod_md_h */
    ��������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_event.h������������������������������������������������������������������0000664�0001751�0001751�00000003352�14046725222�016653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
    * this work for additional information regarding copyright ownership.
    * The ASF licenses this file to You under the Apache License, Version 2.0
    * (the "License"); you may not use this file except in compliance with
    * the License.  You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT 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 md_event_h
    #define md_event_h
    
    struct md_job_t;
    struct md_result_t;
    
    typedef apr_status_t md_event_cb(const char *event, 
                                     const char *mdomain, 
                                     void *baton,
                                     struct md_job_t *job, 
                                     struct md_result_t *result, 
                                     apr_pool_t *p);
    
    void md_event_init(apr_pool_t *p); 
    
    void md_event_subscribe(md_event_cb *cb, void *baton); 
    
    apr_status_t md_event_raise(const char *event, 
                                const char *mdomain, 
                                struct md_job_t *job, 
                                struct md_result_t *result, 
                                apr_pool_t *p);
    
    void md_event_holler(const char *event, 
                         const char *mdomain, 
                         struct md_job_t *job, 
                         struct md_result_t *result, 
                         apr_pool_t *p);
    
    #endif /* md_event_h */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_time.c�������������������������������������������������������������������0000664�0001751�0001751�00000022135�14046725222�016463� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdio.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_time.h>
    
    #include "md.h"
    #include "md_time.h"
    
    apr_time_t md_timeperiod_length(const md_timeperiod_t *period)
    {
        return (period->start < period->end)? (period->end - period->start) : 0;
    }
    
    int md_timeperiod_contains(const md_timeperiod_t *period, apr_time_t time)
    {
        return md_timeperiod_has_started(period, time) 
            && !md_timeperiod_has_ended(period, time);
    }
    
    int md_timeperiod_has_started(const md_timeperiod_t *period, apr_time_t time)
    {
        return (time >= period->start);
    }
    
    int md_timeperiod_has_ended(const md_timeperiod_t *period, apr_time_t time)
    {
        return (time >= period->start) && (time <= period->end);
    }
    
    apr_interval_time_t md_timeperiod_remaining(const md_timeperiod_t *period, apr_time_t time)
    {
        if (time < period->start) return md_timeperiod_length(period);
        if (time < period->end) return period->end - time;
        return 0;
    }
    
    char *md_timeperiod_print(apr_pool_t *p, const md_timeperiod_t *period)
    {
        char tstart[APR_RFC822_DATE_LEN];
        char tend[APR_RFC822_DATE_LEN];
    
        apr_rfc822_date(tstart, period->start);
        apr_rfc822_date(tend, period->end);
        return apr_pstrcat(p, tstart, " - ", tend, NULL);
    }
    
    static const char *duration_print(apr_pool_t *p, int roughly, apr_interval_time_t duration)
    {
        const char *s = "", *sep = "";
        long days = (long)(apr_time_sec(duration) / MD_SECS_PER_DAY);
        int rem = (int)(apr_time_sec(duration) % MD_SECS_PER_DAY);
        
        s = roughly? "~" : "";
        if (days > 0) {
            s = apr_psprintf(p, "%s%ld days", s, days);
            if (roughly) return s;
            sep = " ";
        }
        if (rem > 0) {
            int hours = (rem / MD_SECS_PER_HOUR);
            rem = (rem % MD_SECS_PER_HOUR);
            if (hours > 0) {
                s = apr_psprintf(p, "%s%s%d hours", s, sep, hours); 
            if (roughly) return s;
                sep = " "; 
            }
            if (rem > 0) {
                int minutes = (rem / 60);
                rem = (rem % 60);
                if (minutes > 0) {
                    s = apr_psprintf(p, "%s%s%d minutes", s, sep, minutes); 
                    if (roughly) return s;
                    sep = " "; 
                }
                if (rem > 0) {
                    s = apr_psprintf(p, "%s%s%d seconds", s, sep, rem); 
                    if (roughly) return s;
                    sep = " "; 
                }
            }
        }
        else if (days == 0) {
            s = "0 seconds";
            if (duration != 0) {
                s = apr_psprintf(p, "%d ms", (int)apr_time_msec(duration));
            }
        }
        return s;
    }
    
    const char *md_duration_print(apr_pool_t *p, apr_interval_time_t duration)
    {
        return duration_print(p, 0, duration);
    }
    
    const char *md_duration_roughly(apr_pool_t *p, apr_interval_time_t duration)
    {
        return duration_print(p, 1, duration);
    }
    
    static const char *duration_format(apr_pool_t *p, apr_interval_time_t duration)
    {
        const char *s = "0";
        int units = (int)(apr_time_sec(duration) / MD_SECS_PER_DAY);
        int rem = (int)(apr_time_sec(duration) % MD_SECS_PER_DAY);
        
        if (rem == 0) {
            s = apr_psprintf(p, "%dd", units); 
        }
        else {
            units = (int)(apr_time_sec(duration) / MD_SECS_PER_HOUR);
            rem = (int)(apr_time_sec(duration) % MD_SECS_PER_HOUR);
            if (rem == 0) {
                s = apr_psprintf(p, "%dh", units); 
            }
            else {
                units = (int)(apr_time_sec(duration) / 60);
                rem = (int)(apr_time_sec(duration) % 60);
                if (rem == 0) {
                    s = apr_psprintf(p, "%dmi", units); 
                }
                else {
                    units = (int)(apr_time_sec(duration));
                    rem = (int)(apr_time_msec(duration) % 1000);
                    if (rem == 0) {
                        s = apr_psprintf(p, "%ds", units); 
                    }
                    else {
                        s = apr_psprintf(p, "%dms", (int)(apr_time_msec(duration))); 
                    }
                }
            }
        }
        return s;
    }
    
    const char *md_duration_format(apr_pool_t *p, apr_interval_time_t duration)
    {
        return duration_format(p, duration);
    }
    
    apr_status_t md_duration_parse(apr_interval_time_t *ptimeout, const char *value, 
                                   const char *def_unit)
    {
        char *endp;
        apr_int64_t n;
        
        n = apr_strtoi64(value, &endp, 10);
        if (errno) {
            return errno;
        }
        if (!endp || !*endp) {
            if (!def_unit) def_unit = "s";
        }
        else if (endp == value) {
            return APR_EINVAL;
        }
        else {
            def_unit = endp;
        }
        
        switch (*def_unit) {
        case 'D':
        case 'd':
            *ptimeout = apr_time_from_sec(n * MD_SECS_PER_DAY);
            break;
        case 's':
        case 'S':
            *ptimeout = (apr_interval_time_t) apr_time_from_sec(n);
            break;
        case 'h':
        case 'H':
            /* Time is in hours */
            *ptimeout = (apr_interval_time_t) apr_time_from_sec(n * MD_SECS_PER_HOUR);
            break;
        case 'm':
        case 'M':
            switch (*(++def_unit)) {
            /* Time is in milliseconds */
            case 's':
            case 'S':
                *ptimeout = (apr_interval_time_t) n * 1000;
                break;
            /* Time is in minutes */
            case 'i':
            case 'I':
                *ptimeout = (apr_interval_time_t) apr_time_from_sec(n * 60);
                break;
            default:
                return APR_EGENERAL;
            }
            break;
        default:
            return APR_EGENERAL;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t percentage_parse(const char *value, int *ppercent)
    {
        char *endp;
        apr_int64_t n;
        
        n = apr_strtoi64(value, &endp, 10);
        if (errno) {
            return errno;
        }
        if (*endp == '%') {
            if (n < 0) {
                return APR_BADARG;
            }
            *ppercent = (int)n;
            return APR_SUCCESS;
        }
        return APR_EINVAL;
    }
    
    apr_status_t md_timeslice_create(md_timeslice_t **pts, apr_pool_t *p,
                                     apr_interval_time_t norm, apr_interval_time_t len)
    {
        md_timeslice_t *ts;
    
        ts = apr_pcalloc(p, sizeof(*ts));
        ts->norm = norm;
        ts->len = len;
        *pts = ts;
        return APR_SUCCESS;
    }
    
    const char *md_timeslice_parse(md_timeslice_t **pts, apr_pool_t *p, 
                                   const char *val, apr_interval_time_t norm)
    {
        md_timeslice_t *ts;
        int percent = 0;
    
        *pts = NULL;
        if (!val) {
            return "cannot parse NULL value";
        }
    
        ts = apr_pcalloc(p, sizeof(*ts));
        if (md_duration_parse(&ts->len, val, "d") == APR_SUCCESS) {
            *pts = ts;
            return NULL;
        }
        else {
            switch (percentage_parse(val, &percent)) {
                case APR_SUCCESS:
                    ts->norm = norm;
                    ts->len = apr_time_from_sec((apr_time_sec(norm) * percent / 100L));
                    *pts = ts;
                    return NULL;
                case APR_BADARG:
                    return "percent must be less than 100";
            }
        }
        return "has unrecognized format";
    }
    
    const char *md_timeslice_format(const md_timeslice_t *ts, apr_pool_t *p) {
        if (ts->norm > 0) {
            int percent = (int)(((long)apr_time_sec(ts->len)) * 100L 
                                / ((long)apr_time_sec(ts->norm))); 
            return apr_psprintf(p, "%d%%", percent);
        }
        return duration_format(p, ts->len);
    }
    
    md_timeperiod_t md_timeperiod_slice_before_end(const md_timeperiod_t *period, 
                                                   const md_timeslice_t *ts)
    {
        md_timeperiod_t r;
        apr_time_t duration = ts->len;
        
        if (ts->norm > 0) {
            int percent = (int)(((long)apr_time_sec(ts->len)) * 100L 
                                / ((long)apr_time_sec(ts->norm))); 
            apr_time_t plen = md_timeperiod_length(period);
            if (apr_time_sec(plen) > 100) {
                duration = apr_time_from_sec(apr_time_sec(plen) * percent / 100);
            }
            else {
                duration = plen * percent / 100;
            }
        }
        r.start = period->end - duration;
        r.end = period->end;
        return r;
    }
    
    int md_timeslice_eq(const md_timeslice_t *ts1, const md_timeslice_t *ts2)
    {
        if (ts1 == ts2) return 1;
        if (!ts1 || !ts2) return 0;
        return (ts1->norm == ts2->norm) && (ts1->len == ts2->len);
    }
    
    md_timeperiod_t md_timeperiod_common(const md_timeperiod_t *a, const md_timeperiod_t *b)
    {
        md_timeperiod_t c;
        
        c.start = (a->start > b->start)? a->start : b->start;
        c.end = (a->end < b->end)? a->end : b->end;
        if (c.start > c.end) {
            c.start = c.end = 0;
        }
        return c;
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_drive.h��������������������������������������������������������������0000664�0001751�0001751�00000002244�13554574060�017506� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_drive_h
    #define mod_md_md_drive_h
    
    struct md_mod_conf_t;
    struct md_reg_t;
    
    typedef struct md_renew_ctx_t md_renew_ctx_t;
    
    int md_will_renew_cert(const md_t *md);
    
    /**
     * Start driving the certificate renewal for MDs marked with watched.
     */
    apr_status_t md_renew_start_watching(struct md_mod_conf_t *mc, server_rec *s, apr_pool_t *p);
    
    
    
    
    #endif /* mod_md_md_drive_h */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_curl.h�������������������������������������������������������������������0000664�0001751�0001751�00000001654�13234043402�016471� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 md_curl_h
    #define md_curl_h
    
    struct md_http_impl;
    
    struct md_http_impl_t * md_curl_get_impl(apr_pool_t *p);
    
    #endif /* md_curl_h */
    ������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md.dep������������������������������������������������������������������0000664�0001751�0001751�00000000225�13210057571�016623� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_md.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_os.c�����������������������������������������������������������������0000664�0001751�0001751�00000004722�13622523101�016776� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_strings.h>
    
    #include <mpm_common.h>
    #include <httpd.h>
    #include <http_log.h>
    #include <ap_mpm.h>
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if AP_NEED_SET_MUTEX_PERMS
    #include "unixd.h"
    #endif
    
    #include "md_util.h"
    #include "mod_md_os.h"
    
    apr_status_t md_try_chown(const char *fname, unsigned int uid, int gid, apr_pool_t *p)
    {
    #if AP_NEED_SET_MUTEX_PERMS && HAVE_UNISTD_H
        /* Since we only switch user when running as root, we only need to chown directories
         * in that case. Otherwise, the server will ignore any "user/group" directives and
         * child processes have the same privileges as the parent.
         */
        if (!geteuid()) {
            if (-1 == chown(fname, (uid_t)uid, (gid_t)gid)) {
                apr_status_t rv = APR_FROM_OS_ERROR(errno);
                if (!APR_STATUS_IS_ENOENT(rv)) {
                    ap_log_perror(APLOG_MARK, APLOG_ERR, rv, p, APLOGNO(10082)
                                  "Can't change owner of %s", fname);
                }
                return rv;
            }
        }
        return APR_SUCCESS;
    #else 
        return APR_ENOTIMPL;
    #endif
    }
    
    apr_status_t md_make_worker_accessible(const char *fname, apr_pool_t *p)
    {
    #ifdef WIN32
        return APR_ENOTIMPL;
    #else 
        return md_try_chown(fname, ap_unixd_config.user_id, -1, p);
    #endif
    }
    
    #ifdef WIN32
    
    apr_status_t md_server_graceful(apr_pool_t *p, server_rec *s)
    {
        return APR_ENOTIMPL;
    }
     
    #else
    
    apr_status_t md_server_graceful(apr_pool_t *p, server_rec *s)
    { 
        apr_status_t rv;
        
        (void)p;
        (void)s;
        rv = (kill(getppid(), AP_SIG_GRACEFUL) < 0)? APR_ENOTIMPL : APR_SUCCESS;
        ap_log_error(APLOG_MARK, APLOG_TRACE1, errno, NULL, "sent signal to parent");
        return rv;
    }
    
    #endif
    
    ����������������������������������������������httpd-2.4.64/modules/md/mod_md_private.h������������������������������������������������������������0000664�0001751�0001751�00000001650�13234043402�020031� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_private_h
    #define mod_md_md_private_h
    
    extern module AP_MODULE_DECLARE_DATA md_module;
    
    APLOG_USE_MODULE(md);
    
    #endif
    ����������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acmev2_drive.h�����������������������������������������������������������0000664�0001751�0001751�00000001703�13511051361�020066� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright 2019 greenbytes GmbH (https://www.greenbytes.de)
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 md_acmev2_drive_h
    #define md_acmev2_drive_h
    
    struct md_json_t;
    struct md_proto_driver_t;
    struct md_result_t;
    
    apr_status_t md_acmev2_drive_renew(struct md_acme_driver_t *ad, 
                                       struct md_proto_driver_t *d,
                                       struct md_result_t *result);
    
    #endif /* md_acmev2_drive_h */
    �������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_status.h�������������������������������������������������������������0000664�0001751�0001751�00000002065�13554574060�017721� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_status_h
    #define mod_md_md_status_h
    
    int md_http_cert_status(request_rec *r);
    
    int md_domains_status_hook(request_rec *r, int flags);
    int md_ocsp_status_hook(request_rec *r, int flags);
    
    int md_status_handler(request_rec *r);
    
    #endif /* mod_md_md_status_h */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/Makefile.in�����������������������������������������������������������������0000664�0001751�0001751�00000001515�13206766250�016750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_version.h����������������������������������������������������������������0000664�0001751�0001751�00000002772�15017530147�017223� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_version_h
    #define mod_md_md_version_h
    
    #undef PACKAGE_VERSION
    #undef PACKAGE_TARNAME
    #undef PACKAGE_STRING
    #undef PACKAGE_NAME
    #undef PACKAGE_BUGREPORT
    
    /**
     * @macro
     * Version number of the md module as c string
     */
    #define MOD_MD_VERSION "2.5.2"
    
    /**
     * @macro
     * Numerical representation of the version number of the md module
     * release. This is a 24 bit number with 8 bits for major number, 8 bits
     * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
     */
    #define MOD_MD_VERSION_NUM 0x020502
    
    #define MD_ACME_DEF_URL         "https://acme-v02.api.letsencrypt.org/directory"
    #define MD_TAILSCALE_DEF_URL    "file://localhost/var/run/tailscale/tailscaled.sock"
    
    #endif /* mod_md_md_version_h */
    ������httpd-2.4.64/modules/md/md_curl.c�������������������������������������������������������������������0000664�0001751�0001751�00000054350�15032765166�016505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include <curl/curl.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_buckets.h>
    
    #include "md_http.h"
    #include "md_log.h"
    #include "md_util.h"
    #include "md_curl.h"
    
    /**************************************************************************************************/
    /* md_http curl implementation */
    
    
    static apr_status_t curl_status(unsigned int curl_code)
    {
        switch (curl_code) {
            case CURLE_OK:                   return APR_SUCCESS;
            case CURLE_UNSUPPORTED_PROTOCOL: return APR_ENOTIMPL; 
            case CURLE_NOT_BUILT_IN:         return APR_ENOTIMPL; 
            case CURLE_URL_MALFORMAT:        return APR_EINVAL;
            case CURLE_COULDNT_RESOLVE_PROXY:return APR_ECONNREFUSED;
            case CURLE_COULDNT_RESOLVE_HOST: return APR_ECONNREFUSED;
            case CURLE_COULDNT_CONNECT:      return APR_ECONNREFUSED;
            case CURLE_REMOTE_ACCESS_DENIED: return APR_EACCES;
            case CURLE_OUT_OF_MEMORY:        return APR_ENOMEM;
            case CURLE_OPERATION_TIMEDOUT:   return APR_TIMEUP;
            case CURLE_SSL_CONNECT_ERROR:    return APR_ECONNABORTED;
            case CURLE_AGAIN:                return APR_EAGAIN;
            default:                         return APR_EGENERAL;
        }
    }
    
    typedef struct {
        CURL *curl;
        CURLM *curlm;
        struct curl_slist *req_hdrs;
        md_http_response_t *response;
        apr_status_t rv;
        int status_fired;
    } md_curl_internals_t;
    
    static size_t req_data_cb(void *data, size_t len, size_t nmemb, void *baton)
    {
        apr_bucket_brigade *body = baton;
        size_t blen, read_len = 0, max_len = len * nmemb;
        const char *bdata;
        char *rdata = data;
        apr_bucket *b;
        apr_status_t rv;
        
        while (body && !APR_BRIGADE_EMPTY(body) && max_len > 0) {
            b = APR_BRIGADE_FIRST(body);
            if (APR_BUCKET_IS_METADATA(b)) {
                if (APR_BUCKET_IS_EOS(b)) {
                    body = NULL;
                }
            }
            else {
                rv = apr_bucket_read(b, &bdata, &blen, APR_BLOCK_READ);
                if (rv == APR_SUCCESS) {
                    if (blen > max_len) {
                        apr_bucket_split(b, max_len);
                        blen = max_len;
                    }
                    memcpy(rdata, bdata, blen);
                    read_len += blen;
                    max_len -= blen;
                    rdata += blen;
                }
                else {
                    body = NULL;
                    if (!APR_STATUS_IS_EOF(rv)) {
                        /* everything beside EOF is an error */
                        read_len = CURL_READFUNC_ABORT;
                    }
                }
                
            }
            apr_bucket_delete(b);
        }
        
        return read_len;
    }
    
    static size_t resp_data_cb(void *data, size_t len, size_t nmemb, void *baton)
    {
        md_curl_internals_t *internals = baton;
        md_http_response_t *res = internals->response;
        size_t blen = len * nmemb;
        apr_status_t rv;
        
        if (res->body) {
            if (res->req->resp_limit) {
                apr_off_t body_len = 0;
                apr_brigade_length(res->body, 0, &body_len);
                if (body_len + (apr_off_t)blen > res->req->resp_limit) {
                    return 0; /* signal curl failure */
                }
            }
            rv = apr_brigade_write(res->body, NULL, NULL, (const char *)data, blen);
            if (rv != APR_SUCCESS) {
                /* returning anything != blen will make CURL fail this */
                return 0;
            }
        }
        return blen;
    }
    
    static size_t header_cb(void *buffer, size_t elen, size_t nmemb, void *baton)
    {
        md_curl_internals_t *internals = baton;
        md_http_response_t *res = internals->response;
        size_t len, clen = elen * nmemb;
        const char *name = NULL, *value = "", *b = buffer;
        apr_size_t i;
        
        len = (clen && b[clen-1] == '\n')? clen-1 : clen;
        len = (len && b[len-1] == '\r')? len-1 : len;
        for (i = 0; i < len; ++i) {
            if (b[i] == ':') {
                name = apr_pstrndup(res->req->pool, b, i);
                ++i;
                while (i < len && b[i] == ' ') {
                    ++i;
                }
                if (i < len) {
                    value = apr_pstrndup(res->req->pool, b+i, len - i);
                }
                break;
            }
        }
        
        if (name != NULL) {
            apr_table_add(res->headers, name, value);
        }
        return clen;
    }
    
    typedef struct {
        md_http_request_t *req;
        struct curl_slist *hdrs;
        apr_status_t rv;
    } curlify_hdrs_ctx;
    
    static int curlify_headers(void *baton, const char *key, const char *value)
    {
        curlify_hdrs_ctx *ctx = baton;
        const char *s;
        
        if (strchr(key, '\r') || strchr(key, '\n')
            || strchr(value, '\r') || strchr(value, '\n')) {
            ctx->rv = APR_EINVAL;
            return 0;
        }
        s = apr_psprintf(ctx->req->pool, "%s: %s", key, value);
        ctx->hdrs = curl_slist_append(ctx->hdrs, s);
        return 1;
    }
    
    /* Convert timeout values for curl. Since curl uses 0 to disable
     * timeout, return at least 1 if the apr_time_t value is non-zero. */
    static long timeout_msec(apr_time_t timeout)
    {
        long ms = (long)apr_time_as_msec(timeout);
        return ms? ms : (timeout? 1 : 0);
    }
    
    static long timeout_sec(apr_time_t timeout)
    {
        long s = (long)apr_time_sec(timeout);
        return s? s : (timeout? 1 : 0);
    }
    
    static int curl_debug_log(CURL *curl, curl_infotype type, char *data, size_t size, void *baton)
    {
        md_http_request_t *req = baton;
        
        (void)curl;
        switch (type) {
            case CURLINFO_TEXT:
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, req->pool, 
                              "req[%d]: info %s", req->id, apr_pstrndup(req->pool, data, size));
                break;
            case CURLINFO_HEADER_OUT:
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, req->pool, 
                              "req[%d]: header --> %s", req->id, apr_pstrndup(req->pool, data, size));
                break;
            case CURLINFO_HEADER_IN:
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, req->pool, 
                              "req[%d]: header <-- %s", req->id, apr_pstrndup(req->pool, data, size));
                break;
            case CURLINFO_DATA_OUT:
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, req->pool, 
                              "req[%d]: data --> %ld bytes", req->id, (long)size);
                if (md_log_is_level(req->pool, MD_LOG_TRACE5)) {
                    md_data_t d;
                    const char *s;
                    md_data_init(&d, data, size);
                    md_data_to_hex(&s, 0, req->pool, &d);
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE5, 0, req->pool, 
                                  "req[%d]: data(hex) -->  %s", req->id, s);
                }
                break;
            case CURLINFO_DATA_IN:
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, req->pool, 
                              "req[%d]: data <-- %ld bytes", req->id, (long)size);
                if (md_log_is_level(req->pool, MD_LOG_TRACE5)) {
                    md_data_t d;
                    const char *s;
                    md_data_init(&d, data, size);
                    md_data_to_hex(&s, 0, req->pool, &d);
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE5, 0, req->pool, 
                                  "req[%d]: data(hex) <-- %s", req->id, s);
                }
                break;
            default:
                break;
        }
        return 0;
    }
    
    static apr_status_t internals_setup(md_http_request_t *req)
    {
        md_curl_internals_t *internals;
        CURL *curl;
        apr_status_t rv = APR_SUCCESS;
        long ssl_options = 0;
    
        curl = md_http_get_impl_data(req->http);
        if (!curl) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, "creating curl instance");
            curl = curl_easy_init();
            if (!curl) {
                rv = APR_EGENERAL;
                goto leave;
            }
            curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
            curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL);
            curl_easy_setopt(curl, CURLOPT_READFUNCTION, req_data_cb);
            curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, resp_data_cb);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, "reusing curl instance from http");
        }
    
        internals = apr_pcalloc(req->pool, sizeof(*internals));
        internals->curl = curl;
            
        internals->response = apr_pcalloc(req->pool, sizeof(md_http_response_t));
        internals->response->req = req;
        internals->response->status = 400;
        internals->response->headers = apr_table_make(req->pool, 5);
        internals->response->body = apr_brigade_create(req->pool, req->bucket_alloc);
        
        curl_easy_setopt(curl, CURLOPT_URL, req->url);
        if (!apr_strnatcasecmp("GET", req->method)) {
            /* nop */
        }
        else if (!apr_strnatcasecmp("HEAD", req->method)) {
            curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
        }
        else if (!apr_strnatcasecmp("POST", req->method)) {
            curl_easy_setopt(curl, CURLOPT_POST, 1L);
        }
        else {
            curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, req->method);
        }
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, internals);
        curl_easy_setopt(curl, CURLOPT_READDATA, req->body);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, internals);
        
        if (req->timeout.overall > 0) {
            curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout_msec(req->timeout.overall));
        }
        if (req->timeout.connect > 0) {
            curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, timeout_msec(req->timeout.connect));
        }
        if (req->timeout.stalled > 0) {
            curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, req->timeout.stall_bytes_per_sec);
            curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, timeout_sec(req->timeout.stalled));
        }
        if (req->ca_file) {
            curl_easy_setopt(curl, CURLOPT_CAINFO, req->ca_file);
            /* for a custom CA, allow certificates checking to ignore the
             * Schannel error CRYPT_E_NO_REVOCATION_CHECK (could be a missing OCSP
             * responder URL in the certs???). See issue #361 */
    #ifdef CURLSSLOPT_NO_REVOKE
            ssl_options |= CURLSSLOPT_NO_REVOKE;
    #endif
        }
        if (req->unix_socket_path) {
            curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, req->unix_socket_path);
        }
    
        if (req->body_len >= 0) {
            /* set the Content-Length */
            curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)req->body_len);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)req->body_len);
        }
        
        if (req->user_agent) {
            curl_easy_setopt(curl, CURLOPT_USERAGENT, req->user_agent);
        }
        if (req->proxy_url) {
            curl_easy_setopt(curl, CURLOPT_PROXY, req->proxy_url);
        }
        if (!apr_is_empty_table(req->headers)) {
            curlify_hdrs_ctx ctx;
            
            ctx.req = req;
            ctx.hdrs = NULL;
            ctx.rv = APR_SUCCESS;
            apr_table_do(curlify_headers, &ctx, req->headers, NULL);
            internals->req_hdrs = ctx.hdrs;
            if (ctx.rv == APR_SUCCESS) {
                curl_easy_setopt(curl, CURLOPT_HTTPHEADER, internals->req_hdrs);
            }
        }
        
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, 
                      "req[%d]: %s %s", req->id, req->method, req->url);
        
        if (md_log_is_level(req->pool, MD_LOG_TRACE4)) {
            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
            curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_debug_log);
            curl_easy_setopt(curl, CURLOPT_DEBUGDATA, req);
        }
    
        if (ssl_options)
            curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, ssl_options);
    
    leave:
        req->internals = (APR_SUCCESS == rv)? internals : NULL;
        return rv;
    }
    
    static apr_status_t update_status(md_http_request_t *req)
    {
        md_curl_internals_t *internals = req->internals;
        long l;
        apr_status_t rv = APR_SUCCESS;
    
        if (internals) {
            rv = curl_status(curl_easy_getinfo(internals->curl, CURLINFO_RESPONSE_CODE, &l));
            if (APR_SUCCESS == rv) {
                internals->response->status = (int)l;
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, req->pool,
                              "req[%d]: http status is %d",
                              req->id, internals->response->status);
            }
        }
        return rv;
    }
    
    static void fire_status(md_http_request_t *req, apr_status_t rv)
    {
        md_curl_internals_t *internals = req->internals;
            
        if (internals && !internals->status_fired) {
            internals->status_fired = 1;
            
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, req->pool, 
                          "req[%d] fire callbacks", req->id);
            if ((APR_SUCCESS == rv) && req->cb.on_response) {
                rv = req->cb.on_response(internals->response, req->cb.on_response_data);
            }
        
            internals->rv = rv;
            if (req->cb.on_status) {
                req->cb.on_status(req, rv, req->cb.on_status_data);
            }
        }
    }
    
    static apr_status_t md_curl_perform(md_http_request_t *req)
    {
        apr_status_t rv = APR_SUCCESS;
        CURLcode curle;
        md_curl_internals_t *internals;
        long l;
    
        if (APR_SUCCESS != (rv = internals_setup(req))) goto leave;
        internals = req->internals;
        
        curle = curl_easy_perform(internals->curl);
        
        rv = curl_status(curle);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, req->pool, 
                          "request failed(%d): %s", curle, curl_easy_strerror(curle));
            goto leave;
        }
        
        rv = curl_status(curl_easy_getinfo(internals->curl, CURLINFO_RESPONSE_CODE, &l));
        if (APR_SUCCESS == rv) {
            internals->response->status = (int)l;
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, req->pool, "request <-- %d", 
                      internals->response->status);
        
        if (req->cb.on_response) {
            rv = req->cb.on_response(internals->response, req->cb.on_response_data);
            req->cb.on_response = NULL;
        }
        
    leave:
        fire_status(req, rv);
        md_http_req_destroy(req);
        return rv;
    }
    
    static md_http_request_t *find_curl_request(apr_array_header_t *requests, CURL *curl)
    {
        md_http_request_t *req;
        md_curl_internals_t *internals;
        int i;
        
        for (i = 0; i < requests->nelts; ++i) {
            req = APR_ARRAY_IDX(requests, i, md_http_request_t*);
            internals = req->internals;
            if (internals && internals->curl == curl) {
                return req;
            }
        }
        return NULL;
    }
    
    static void add_to_curlm(md_http_request_t *req, CURLM *curlm)
    {
        md_curl_internals_t *internals = req->internals;
        
        assert(curlm);
        assert(internals);
        if (internals->curlm == NULL) {
            internals->curlm = curlm;
        }
        assert(internals->curlm == curlm);
        curl_multi_add_handle(curlm, internals->curl);
    }
    
    static void remove_from_curlm_and_destroy(md_http_request_t *req, CURLM *curlm)
    {
        md_curl_internals_t *internals = req->internals;
    
        assert(curlm);
        assert(internals);
        assert(internals->curlm == curlm);
        curl_multi_remove_handle(curlm, internals->curl);
        internals->curlm = NULL;
        md_http_req_destroy(req);
    }
        
    static apr_status_t md_curl_multi_perform(md_http_t *http, apr_pool_t *p,
                                              md_http_next_req *nextreq, void *baton)
    {
        md_http_t *sub_http;
        md_http_request_t *req;
        CURLM *curlm = NULL;
        CURLMcode mc;
        struct CURLMsg *curlmsg;
        apr_array_header_t *http_spares;
        apr_array_header_t *requests;
        int i, running, numfds, slowdown, msgcount;
        apr_status_t rv;
        
        http_spares = apr_array_make(p, 10, sizeof(md_http_t*));
        requests = apr_array_make(p, 10, sizeof(md_http_request_t*));
        curlm = curl_multi_init();
        if (!curlm) {
            rv = APR_ENOMEM;
            goto leave;
        }
        
        running = 1;
        slowdown = 0;
        while(1) {
            while (1) {
                /* fetch as many requests as nextreq gives us */
                if (http_spares->nelts > 0) {
                    sub_http = *(md_http_t **)(apr_array_pop(http_spares));
                }
                else {
                    rv = md_http_clone(&sub_http, p, http);
                    if (APR_SUCCESS != rv) {
                        md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p,
                                      "multi_perform[%d reqs]: setup failed", requests->nelts);
                        goto leave;
                    }
                }
    
                rv = nextreq(&req, baton, sub_http, requests->nelts);
                if (APR_STATUS_IS_ENOENT(rv)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p,
                                  "multi_perform[%d reqs]: no more requests", requests->nelts);
                    if (!requests->nelts) {
                        goto leave;
                    }
                    break;
                }
                else if (APR_SUCCESS != rv) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p,
                                  "multi_perform[%d reqs]: nextreq() failed", requests->nelts);
                    APR_ARRAY_PUSH(http_spares, md_http_t*) = sub_http;
                    goto leave;
                }
    
                if (APR_SUCCESS != (rv = internals_setup(req))) {
                    if (req->cb.on_status) req->cb.on_status(req, rv, req->cb.on_status_data);
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p,
                                  "multi_perform[%d reqs]: setup failed", requests->nelts);
                    APR_ARRAY_PUSH(http_spares, md_http_t*) = sub_http;
                    goto leave;
                }
    
                APR_ARRAY_PUSH(requests, md_http_request_t*) = req;
                add_to_curlm(req, curlm);
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p,
                              "multi_perform[%d reqs]: added request", requests->nelts);
            }
        
            mc = curl_multi_perform(curlm, &running);
            if (CURLM_OK == mc) {
                mc = curl_multi_wait(curlm, NULL, 0, 1000, &numfds);
                if (numfds) slowdown = 0;
            }
            if (CURLM_OK != mc) {
                rv = APR_ECONNABORTED;
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, 
                              "multi_perform[%d reqs] failed(%d): %s", 
                              requests->nelts, mc, curl_multi_strerror(mc));
                goto leave;
            }
            if (!numfds) {
                /* no activity on any connection, timeout */
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p, 
                              "multi_perform[%d reqs]: slowdown %d", requests->nelts, slowdown);
                if (slowdown) apr_sleep(apr_time_from_msec(100));
                ++slowdown;
            }
    
            /* process status messages, e.g. that a request is done */
            while (running < requests->nelts) {
                curlmsg = curl_multi_info_read(curlm, &msgcount);
                if (!curlmsg) break;
                if (curlmsg->msg == CURLMSG_DONE) {
                    req = find_curl_request(requests, curlmsg->easy_handle);
                    if (req) {
                        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, p,
                                      "multi_perform[%d reqs]: req[%d] done", 
                                      requests->nelts, req->id);
                        update_status(req);
                        fire_status(req, curl_status(curlmsg->data.result));
                        md_array_remove(requests, req);
                        sub_http = req->http;
                        APR_ARRAY_PUSH(http_spares, md_http_t*) = sub_http;
                        remove_from_curlm_and_destroy(req, curlm);
                    }
                    else {
                        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                                      "multi_perform[%d reqs]: req done, but not found by handle", 
                                      requests->nelts);
                    }
                }
            }
        };
    
    leave:
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p, 
                      "multi_perform[%d reqs]: leaving", requests->nelts);
        for (i = 0; i < requests->nelts; ++i) {
            req = APR_ARRAY_IDX(requests, i, md_http_request_t*);
            fire_status(req, APR_SUCCESS);
            sub_http = req->http;
            APR_ARRAY_PUSH(http_spares, md_http_t*) = sub_http;
            remove_from_curlm_and_destroy(req, curlm);
        }
        if (curlm) curl_multi_cleanup(curlm);
        return rv;
    }
    
    static int initialized;
    
    static apr_status_t md_curl_init(void) {
        if (!initialized) {
            initialized = 1;
            curl_global_init(CURL_GLOBAL_DEFAULT);
        }
        return APR_SUCCESS;
    }
    
    static void md_curl_req_cleanup(md_http_request_t *req) 
    {
        md_curl_internals_t *internals = req->internals;
        if (internals) {
            if (internals->curl) {
                CURL *curl = md_http_get_impl_data(req->http);
                if (curl == internals->curl) {
                    /* NOP: we have this curl at the md_http_t already */
                }
                else if (!curl) {
                    /* no curl at the md_http_t yet, install this one */
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, "register curl instance at http");
                    md_http_set_impl_data(req->http, internals->curl);
                }
                else {
                    /* There already is a curl at the md_http_t and it's not this one. */
                    curl_easy_cleanup(internals->curl);
                }
            }
            if (internals->req_hdrs) curl_slist_free_all(internals->req_hdrs);
            req->internals = NULL;
        }
    }
    
    static void md_curl_cleanup(md_http_t *http, apr_pool_t *pool)
    {
        CURL *curl;
    
        curl = md_http_get_impl_data(http);
        if (curl) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, pool, "cleanup curl instance");
            md_http_set_impl_data(http, NULL);
            curl_easy_cleanup(curl);
        }
    }
    
    static md_http_impl_t impl = {
        md_curl_init,
        md_curl_req_cleanup,
        md_curl_perform,
        md_curl_multi_perform,
        md_curl_cleanup,
    };
    
    md_http_impl_t * md_curl_get_impl(apr_pool_t *p)
    {
        /* trigger early global curl init, before we are down a rabbit hole */
        (void)p;
        md_curl_init();
        return &impl;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acme.c�������������������������������������������������������������������0000664�0001751�0001751�00000071235�14750656217�016450� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_buckets.h>
    #include <apr_hash.h>
    #include <apr_uri.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_jws.h"
    #include "md_http.h"
    #include "md_log.h"
    #include "md_store.h"
    #include "md_result.h"
    #include "md_util.h"
    #include "md_version.h"
    
    #include "md_acme.h"
    #include "md_acme_acct.h"
    
    
    static const char *base_product= "-";
    
    typedef struct acme_problem_status_t acme_problem_status_t;
    
    struct acme_problem_status_t {
        const char *type; /* the ACME error string */
        apr_status_t rv;  /* what Apache status code we give it */
        int input_related; /* if error indicates wrong input value */
    };
    
    static acme_problem_status_t Problems[] = {
        { "acme:error:badCSR",                       APR_EINVAL,   1 },
        { "acme:error:badNonce",                     APR_EAGAIN,   0 },
        { "acme:error:badSignatureAlgorithm",        APR_EINVAL,   1 },
        { "acme:error:externalAccountRequired",      APR_EINVAL,   1 },
        { "acme:error:invalidContact",               APR_BADARG,   1 },
        { "acme:error:unsupportedContact",           APR_EGENERAL, 1 },
        { "acme:error:malformed",                    APR_EINVAL,   1 },
        { "acme:error:rateLimited",                  APR_BADARG,   0 },
        { "acme:error:rejectedIdentifier",           APR_BADARG,   1 },
        { "acme:error:serverInternal",               APR_EGENERAL, 0 },
        { "acme:error:unauthorized",                 APR_EACCES,   0 },
        { "acme:error:unsupportedIdentifier",        APR_BADARG,   1 },
        { "acme:error:userActionRequired",           APR_EAGAIN,   0 },
        { "acme:error:badRevocationReason",          APR_EINVAL,   1 },
        { "acme:error:caa",                          APR_EGENERAL, 0 },
        { "acme:error:dns",                          APR_EGENERAL, 0 },
        { "acme:error:connection",                   APR_EGENERAL, 0 },
        { "acme:error:tls",                          APR_EGENERAL, 0 },
        { "acme:error:incorrectResponse",            APR_EGENERAL, 0 },
    };
    
    static apr_status_t problem_status_get(const char *type) {
        size_t i;
    
        if (strstr(type, "urn:ietf:params:") == type) {
            type += strlen("urn:ietf:params:");
        }
        else if (strstr(type, "urn:") == type) {
            type += strlen("urn:");
        }
         
        for(i = 0; i < (sizeof(Problems)/sizeof(Problems[0])); ++i) {
            if (!apr_strnatcasecmp(type, Problems[i].type)) {
                return Problems[i].rv;
            }
        }
        return APR_EGENERAL;
    }
    
    int md_acme_problem_is_input_related(const char *problem) {
        size_t i;
    
        if (!problem) return 0;
        if (strstr(problem, "urn:ietf:params:") == problem) {
            problem += strlen("urn:ietf:params:");
        }
        else if (strstr(problem, "urn:") == problem) {
            problem += strlen("urn:");
        }
    
        for(i = 0; i < (sizeof(Problems)/sizeof(Problems[0])); ++i) {
            if (!apr_strnatcasecmp(problem, Problems[i].type)) {
                return Problems[i].input_related;
            }
        }
        return 0;
    }
    
    /**************************************************************************************************/
    /* acme requests */
    
    static void req_update_nonce(md_acme_t *acme, apr_table_t *hdrs)
    {
        if (hdrs) {
            const char *nonce = apr_table_get(hdrs, "Replay-Nonce");
            if (nonce) {
                acme->nonce = apr_pstrdup(acme->p, nonce);
            }
        }
    }
    
    static apr_status_t http_update_nonce(const md_http_response_t *res, void *data)
    {
        req_update_nonce(data, res->headers);
        return APR_SUCCESS;
    }
    
    static md_acme_req_t *md_acme_req_create(md_acme_t *acme, const char *method, const char *url)
    {
        apr_pool_t *pool;
        md_acme_req_t *req;
        apr_status_t rv;
        
        rv = apr_pool_create(&pool, acme->p);
        if (rv != APR_SUCCESS) {
            return NULL;
        }
        apr_pool_tag(pool, "md_acme_req");
        
        req = apr_pcalloc(pool, sizeof(*req));
        if (!req) {
            apr_pool_destroy(pool);
            return NULL;
        }
            
        req->acme = acme;
        req->p = pool;
        req->method = method;
        req->url = url;
        req->prot_fields = md_json_create(pool);
        req->max_retries = acme->max_retries;
        req->result = md_result_make(req->p, APR_SUCCESS);
        return req;
    }
     
    static apr_status_t acmev2_new_nonce(md_acme_t *acme)
    {
        return md_http_HEAD_perform(acme->http, acme->api.v2.new_nonce, NULL, http_update_nonce, acme);
    }
    
    
    apr_status_t md_acme_init(apr_pool_t *p, const char *base,  int init_ssl)
    {
        base_product = base;
        return init_ssl? md_crypt_init(p) : APR_SUCCESS;
    }
    
    static apr_status_t inspect_problem(md_acme_req_t *req, const md_http_response_t *res)
    {
        const char *ctype;
        md_json_t *problem = NULL;
        apr_status_t rv;
    
        ctype = apr_table_get(req->resp_hdrs, "content-type");
        ctype = md_util_parse_ct(res->req->pool, ctype);
        if (ctype && !strcmp(ctype, "application/problem+json")) {
            /* RFC 7807 */
            rv = md_json_read_http(&problem, req->p, res);
            if (rv == APR_SUCCESS && problem) {
                const char *ptype, *pdetail;
                
                req->resp_json = problem;
                ptype = md_json_gets(problem, MD_KEY_TYPE, NULL); 
                pdetail = md_json_gets(problem, MD_KEY_DETAIL, NULL);
                req->rv = problem_status_get(ptype);
                md_result_problem_set(req->result, req->rv, ptype, pdetail,
                                      md_json_getj(problem, MD_KEY_SUBPROBLEMS, NULL));
                
                
                
                if (APR_STATUS_IS_EAGAIN(req->rv)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, req->rv, req->p,
                                  "acme reports %s: %s", ptype, pdetail);
                }
                else {
                    md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, req->rv, req->p,
                                  "acme problem %s: %s", ptype, pdetail);
                }
                return req->rv;
            }
        }
        
        switch (res->status) {
            case 400:
                return APR_EINVAL;
            case 401: /* sectigo returns this instead of 403 */
            case 403:
                return APR_EACCES;
            case 404:
                return APR_ENOENT;
            default:
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, req->p,
                              "acme problem unknown: http status %d", res->status);
                md_result_printf(req->result, APR_EGENERAL, "unexpected http status: %d",
                                 res->status);
                return req->result->status;
        }
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* ACME requests with nonce handling */
    
    static apr_status_t acmev2_req_init(md_acme_req_t *req, md_json_t *jpayload)
    {
        md_data_t payload;
    
        md_data_null(&payload);
        if (!req->acme->acct) {
            return APR_EINVAL;
        }
        if (jpayload) {
            payload.data = md_json_writep(jpayload, req->p, MD_JSON_FMT_COMPACT);
            if (!payload.data) {
                return APR_EINVAL;
            }
        }
        else {
            payload.data = "";
        }
    
        payload.len = strlen(payload.data);
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, req->p, 
                      "acme payload(len=%" APR_SIZE_T_FMT "): %s", payload.len, payload.data);
        return md_jws_sign(&req->req_json, req->p, &payload,
                           req->prot_fields, req->acme->acct_key, req->acme->acct->url);
    }
    
    apr_status_t md_acme_req_body_init(md_acme_req_t *req, md_json_t *payload)
    {
        return req->acme->req_init_fn(req, payload);
    }
    
    static apr_status_t md_acme_req_done(md_acme_req_t *req, apr_status_t rv)
    {
        if (req->result->status != APR_SUCCESS) {
            if (req->on_err) {
                req->on_err(req, req->result, req->baton);
            }
        }
        /* An error in rv superceeds the result->status */
        if (APR_SUCCESS != rv) req->result->status = rv;
        rv = req->result->status;
        /* transfer results into the acme's central result for longer life and later inspection */
        md_result_dup(req->acme->last, req->result);
        if (req->p) {
            apr_pool_destroy(req->p);
        }
        return rv;
    }
    
    static apr_status_t on_response(const md_http_response_t *res, void *data)
    {
        md_acme_req_t *req = data;
        apr_status_t rv = APR_SUCCESS;
        
        req->resp_hdrs = apr_table_clone(req->p, res->headers);
        req_update_nonce(req->acme, res->headers);
        
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, req->p, "response: %d", res->status);
        if (res->status >= 200 && res->status < 300) {
            int processed = 0;
            
            if (req->on_json) {
                processed = 1;
                rv = md_json_read_http(&req->resp_json, req->p, res);
                if (APR_SUCCESS == rv) {
                    if (md_log_is_level(req->p, MD_LOG_TRACE2)) {
                        const char *s;
                        s = md_json_writep(req->resp_json, req->p, MD_JSON_FMT_INDENT);
                        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, req->p,
                                      "response: %s",
                                      s ? s : "<failed to serialize!>");
                    }
                    rv = req->on_json(req->acme, req->p, req->resp_hdrs, req->resp_json, req->baton);
                }        
                else if (APR_STATUS_IS_ENOENT(rv)) {
                    /* not JSON content, fall through */
                    processed = 0;
                }
                else {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, req->p, "parsing JSON body");
                }
            }
            
            if (!processed && req->on_res) {
                processed = 1;
                rv = req->on_res(req->acme, res, req->baton);
            }
            
            if (!processed) {
                rv = APR_EINVAL;
                md_result_printf(req->result, rv, "unable to process the response: "
                                 "http-status=%d, content-type=%s", 
                                 res->status, apr_table_get(res->headers, "Content-Type"));
                md_result_log(req->result, MD_LOG_ERR);
            }
        }
        else if (APR_EAGAIN == (rv = inspect_problem(req, res))) {
            /* leave req alive */
            return rv;
        }
    
        md_acme_req_done(req, rv);
        return rv;
    }
    
    static apr_status_t acmev2_GET_as_POST_init(md_acme_req_t *req, void *baton)
    {
        (void)baton;
        return md_acme_req_body_init(req, NULL);
    }
    
    static apr_status_t md_acme_req_send(md_acme_req_t *req)
    {
        apr_status_t rv;
        md_acme_t *acme = req->acme;
        md_data_t *body = NULL;
        md_result_t *result;
    
        assert(acme->url);
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, req->p, 
                      "sending req: %s %s", req->method, req->url);
        md_result_reset(req->acme->last);
        result = md_result_make(req->p, APR_SUCCESS);
        
        /* Whom are we talking to? */
        if (acme->version == MD_ACME_VERSION_UNKNOWN) {
            rv = md_acme_setup(acme, result);
            if (APR_SUCCESS != rv) goto leave;
        }
        
        if (!strcmp("GET", req->method) && !req->on_init && !req->req_json) {
            /* See <https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html#rfc.section.6.3>
             * and <https://mailarchive.ietf.org/arch/msg/acme/sotffSQ0OWV-qQJodLwWYWcEVKI>
             * and <https://community.letsencrypt.org/t/acme-v2-scheduled-deprecation-of-unauthenticated-resource-gets/74380>
             * We implement this change in ACMEv2 and higher as keeping the md_acme_GET() methods,
             * but switching them to POSTs with a empty, JWS signed, body when we call
             * our HTTP client. */
            req->method = "POST";
            req->on_init = acmev2_GET_as_POST_init;
            /*req->max_retries = 0;  don't do retries on these "GET"s */
        }
        
        /* Besides GET/HEAD, we always need a fresh nonce */
        if (strcmp("GET", req->method) && strcmp("HEAD", req->method)) {
            if (acme->version == MD_ACME_VERSION_UNKNOWN) {
                rv = md_acme_setup(acme, result);
                if (APR_SUCCESS != rv) goto leave;
            }
            if (!acme->nonce && (APR_SUCCESS != (rv = acme->new_nonce_fn(acme)))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, req->p, 
                              "error retrieving new nonce from ACME server");
                goto leave;
            }
    
            md_json_sets(acme->nonce, req->prot_fields, "nonce", NULL);
            md_json_sets(req->url, req->prot_fields, "url", NULL);
            acme->nonce = NULL;
        }
        
        rv = req->on_init? req->on_init(req, req->baton) : APR_SUCCESS;
        if (APR_SUCCESS != rv) goto leave;
        
        if (req->req_json) {
            body = apr_pcalloc(req->p, sizeof(*body));
            body->data = md_json_writep(req->req_json, req->p, MD_JSON_FMT_INDENT);
            body->len = strlen(body->data);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->p,
                          "sending JSON body: %s", body->data);
        }
    
        if (body && md_log_is_level(req->p, MD_LOG_TRACE4)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, req->p,
                          "req: %s %s, body:\n%s", req->method, req->url, body->data);
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, req->p, 
                          "req: %s %s", req->method, req->url);
        }
        
        if (!strcmp("GET", req->method)) {
            rv = md_http_GET_perform(req->acme->http, req->url, NULL, on_response, req);
        }
        else if (!strcmp("POST", req->method)) {
            rv = md_http_POSTd_perform(req->acme->http, req->url, NULL, "application/jose+json",  
                                       body, on_response, req);
        }
        else if (!strcmp("HEAD", req->method)) {
            rv = md_http_HEAD_perform(req->acme->http, req->url, NULL, on_response, req);
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, req->p, 
                          "HTTP method %s against: %s", req->method, req->url);
            rv = APR_ENOTIMPL;
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, req->p, "req sent");
        
        if (APR_EAGAIN == rv && req->max_retries > 0) {
            --req->max_retries;
            rv = md_acme_req_send(req);
        }
        req = NULL;
    
    leave:
        if (req) md_acme_req_done(req, rv);
        return rv;
    }
    
    apr_status_t md_acme_POST(md_acme_t *acme, const char *url,
                              md_acme_req_init_cb *on_init,
                              md_acme_req_json_cb *on_json,
                              md_acme_req_res_cb *on_res,
                              md_acme_req_err_cb *on_err,
                              void *baton)
    {
        md_acme_req_t *req;
        
        assert(url);
        assert(on_json || on_res);
    
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, acme->p, "add acme POST: %s", url);
        req = md_acme_req_create(acme, "POST", url);
        req->on_init = on_init;
        req->on_json = on_json;
        req->on_res = on_res;
        req->on_err = on_err;
        req->baton = baton;
        
        return md_acme_req_send(req);
    }
    
    apr_status_t md_acme_GET(md_acme_t *acme, const char *url,
                             md_acme_req_init_cb *on_init,
                             md_acme_req_json_cb *on_json,
                             md_acme_req_res_cb *on_res,
                              md_acme_req_err_cb *on_err,
                             void *baton)
    {
        md_acme_req_t *req;
        
        assert(url);
        assert(on_json || on_res);
    
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, acme->p, "add acme GET: %s", url);
        req = md_acme_req_create(acme, "GET", url);
        req->on_init = on_init;
        req->on_json = on_json;
        req->on_res = on_res;
        req->on_err = on_err;
        req->baton = baton;
        
        return md_acme_req_send(req);
    }
    
    void md_acme_report_result(md_acme_t *acme, apr_status_t rv, struct md_result_t *result)
    {
        if (acme->last->status == APR_SUCCESS) {
            md_result_set(result, rv, NULL);
        }
        else {
            md_result_problem_set(result, acme->last->status, acme->last->problem, 
                                  acme->last->detail, acme->last->subproblems);
        }
    }
    
    /**************************************************************************************************/
    /* GET JSON */
    
    typedef struct {
        apr_pool_t *pool;
        md_json_t *json;
    } json_ctx;
    
    static apr_status_t on_got_json(md_acme_t *acme, apr_pool_t *p, const apr_table_t *headers, 
                                    md_json_t *jbody, void *baton)
    {
        json_ctx *ctx = baton;
    
        (void)acme;
        (void)p;
        (void)headers;
        ctx->json = md_json_clone(ctx->pool, jbody);
        return APR_SUCCESS;
    }
    
    apr_status_t md_acme_get_json(struct md_json_t **pjson, md_acme_t *acme, 
                                  const char *url, apr_pool_t *p)
    {
        apr_status_t rv;
        json_ctx ctx;
        
        ctx.pool = p;
        ctx.json = NULL;
        
        rv = md_acme_GET(acme, url, NULL, on_got_json, NULL, NULL, &ctx);
        *pjson = (APR_SUCCESS == rv)? ctx.json : NULL;
        return rv;
    }
    
    /**************************************************************************************************/
    /* Generic ACME operations */
    
    void md_acme_clear_acct(md_acme_t *acme)
    {
        acme->acct_id = NULL;
        acme->acct = NULL;
        acme->acct_key = NULL;
    }
    
    const char *md_acme_acct_id_get(md_acme_t *acme)
    {
        return acme->acct_id;
    }
    
    const char *md_acme_acct_url_get(md_acme_t *acme)
    {
        return acme->acct? acme->acct->url : NULL;
    }
    
    apr_status_t md_acme_use_acct(md_acme_t *acme, md_store_t *store,
                                  apr_pool_t *p, const char *acct_id)
    {
        md_acme_acct_t *acct;
        md_pkey_t *pkey;
        apr_status_t rv;
    
        if (APR_SUCCESS == (rv = md_acme_acct_load(&acct, &pkey,
                                                   store, MD_SG_ACCOUNTS, acct_id, acme->p))) {
            if (md_acme_acct_matches_url(acct, acme->url)) {
                acme->acct_id = apr_pstrdup(p, acct_id);
                acme->acct = acct;
                acme->acct_key = pkey;
                rv = md_acme_acct_validate(acme, store, p);
            }
            else {
                /* account is from another server or, more likely, from another
                 * protocol endpoint on the same server */
                rv = APR_ENOENT;
            }
        }
        return rv;
    }
    
    apr_status_t md_acme_use_acct_for_md(md_acme_t *acme, struct md_store_t *store,
                                         apr_pool_t *p, const char *acct_id,
                                         const md_t *md)
    {
        md_acme_acct_t *acct;
        md_pkey_t *pkey;
        apr_status_t rv;
    
        if (APR_SUCCESS == (rv = md_acme_acct_load(&acct, &pkey,
                                                   store, MD_SG_ACCOUNTS, acct_id, acme->p))) {
            if (md_acme_acct_matches_md(acct, md)) {
                acme->acct_id = apr_pstrdup(p, acct_id);
                acme->acct = acct;
                acme->acct_key = pkey;
                rv = md_acme_acct_validate(acme, store, p);
            }
            else {
                /* account is from another server or, more likely, from another
                 * protocol endpoint on the same server */
                rv = APR_ENOENT;
            }
        }
        return rv;
    }
    
    apr_status_t md_acme_save_acct(md_acme_t *acme, apr_pool_t *p, md_store_t *store)
    {
        return md_acme_acct_save(store, p, acme, &acme->acct_id, acme->acct, acme->acct_key);
    }
    
    static apr_status_t acmev2_POST_new_account(md_acme_t *acme,
                                                md_acme_req_init_cb *on_init,
                                                md_acme_req_json_cb *on_json,
                                                md_acme_req_res_cb *on_res,
                                                md_acme_req_err_cb *on_err,
                                                void *baton)
    {
        return md_acme_POST(acme, acme->api.v2.new_account, on_init, on_json, on_res, on_err, baton);
    }
    
    apr_status_t md_acme_POST_new_account(md_acme_t *acme, 
                                          md_acme_req_init_cb *on_init,
                                          md_acme_req_json_cb *on_json,
                                          md_acme_req_res_cb *on_res,
                                          md_acme_req_err_cb *on_err,
                                          void *baton)
    {
        return acme->post_new_account_fn(acme, on_init, on_json, on_res, on_err, baton);
    }
    
    /**************************************************************************************************/
    /* ACME setup */
    
    apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url,
                                const char *proxy_url, const char *ca_file)
    {
        md_acme_t *acme;
        const char *err = NULL;
        apr_status_t rv;
        apr_uri_t uri_parsed;
        size_t len;
        
        if (!url) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, p, "create ACME without url");
            return APR_EINVAL;
        }
        
        if (APR_SUCCESS != (rv = md_util_abs_uri_check(p, url, &err))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "invalid ACME uri (%s): %s", err, url);
            return rv;
        }
        
        acme = apr_pcalloc(p, sizeof(*acme));
        acme->url = url;
        acme->p = p;
        acme->user_agent = apr_psprintf(p, "%s mod_md/%s", 
                                        base_product, MOD_MD_VERSION);
        acme->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL;
        acme->max_retries = 99;
        acme->ca_file = ca_file;
    
        if (APR_SUCCESS != (rv = apr_uri_parse(p, url, &uri_parsed))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "parsing ACME uri: %s", url);
            return APR_EINVAL;
        }
        
        len = strlen(uri_parsed.hostname);
        acme->sname = (len <= 16)? uri_parsed.hostname : apr_pstrdup(p, uri_parsed.hostname + len - 16);
        acme->version = MD_ACME_VERSION_UNKNOWN;
        acme->last = md_result_make(acme->p, APR_SUCCESS);
        
        *pacme = acme;
        return rv;
    }
    
    typedef struct {
        md_acme_t *acme;
        md_result_t *result;
    } update_dir_ctx;
    
    static int collect_profiles(void *baton, const char* key, md_json_t *json)
    {
        update_dir_ctx *ctx = baton;
        (void)json;
        APR_ARRAY_PUSH(ctx->acme->api.v2.profiles, const char *) =
            apr_pstrdup(ctx->acme->p, key);
        return 1;
    }
    
    static apr_status_t update_directory(const md_http_response_t *res, void *data)
    {
        md_http_request_t *req = res->req;
        md_acme_t *acme = ((update_dir_ctx *)data)->acme;
        md_result_t *result = ((update_dir_ctx *)data)->result;
        apr_status_t rv;
        md_json_t *json;
        const char *s;
        
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, req->pool, "directory lookup response: %d", res->status);
        if (res->status == 503) {
            md_result_printf(result, APR_EAGAIN,
                "The ACME server at <%s> reports that Service is Unavailable (503). This "
                "may happen during maintenance for short periods of time.", acme->url); 
            md_result_log(result, MD_LOG_INFO);
            rv = result->status;
            goto leave;
        }
        else if (res->status < 200 || res->status >= 300) {
            md_result_printf(result, APR_EAGAIN,
                "The ACME server at <%s> responded with HTTP status %d. This "
                "is unusual. Please verify that the URL is correct and that you can indeed "
                "make request from the server to it by other means, e.g. invoking curl/wget.", 
                acme->url, res->status);
            rv = result->status;
            goto leave;
        }
        
        rv = md_json_read_http(&json, req->pool, res);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, req->pool, "reading JSON body");
            goto leave;
        }
        
        if (md_log_is_level(acme->p, MD_LOG_TRACE2)) {
            s = md_json_writep(json, req->pool, MD_JSON_FMT_INDENT);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, req->pool,
                          "response: %s", s ? s : "<failed to serialize!>");
        }
        
        /* What have we got? */
        if ((s = md_json_dups(acme->p, json, "newAccount", NULL))) {
            acme->api.v2.new_account = s;
            acme->api.v2.new_order = md_json_dups(acme->p, json, "newOrder", NULL);
            acme->api.v2.revoke_cert = md_json_dups(acme->p, json, "revokeCert", NULL);
            acme->api.v2.key_change = md_json_dups(acme->p, json, "keyChange", NULL);
            acme->api.v2.new_nonce = md_json_dups(acme->p, json, "newNonce", NULL);
            /* RFC 8555 only requires "directory" and "newNonce" resources.
             * mod_md uses "newAccount" and "newOrder" so check for them.
             * But mod_md does not use the "revokeCert" or "keyChange"
             * resources, so tolerate the absence of those keys.  In the
             * future if mod_md implements revocation or key rollover then
             * the use of those features should be predicated on the
             * server's advertised capabilities. */
            if (acme->api.v2.new_account
                && acme->api.v2.new_order
                && acme->api.v2.new_nonce) {
                acme->version = MD_ACME_VERSION_2;
            }
            acme->ca_agreement = md_json_dups(acme->p, json, "meta", MD_KEY_TOS, NULL);
            acme->eab_required = md_json_getb(json, "meta", MD_KEY_EAB_REQUIRED, NULL);
            acme->new_nonce_fn = acmev2_new_nonce;
            acme->req_init_fn = acmev2_req_init;
            acme->post_new_account_fn = acmev2_POST_new_account;
    
            if (md_json_has_key(json, "meta", "profiles", NULL)) {
                acme->api.v2.profiles = apr_array_make(acme->p, 5, sizeof(const char*));
                md_json_iterkey(collect_profiles, data, json, "meta", "profiles", NULL);
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, req->pool,
                              "found %d profiles in ACME directory meta",
                              acme->api.v2.profiles->nelts);
            }
            else {
                acme->api.v2.profiles = NULL;
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, req->pool,
                              "no profiles in ACME directory meta");
    
            }
        }
        else if ((s = md_json_dups(acme->p, json, "new-authz", NULL))) {
            acme->api.v1.new_authz = s;
            acme->api.v1.new_cert = md_json_dups(acme->p, json, "new-cert", NULL);
            acme->api.v1.new_reg = md_json_dups(acme->p, json, "new-reg", NULL);
            acme->api.v1.revoke_cert = md_json_dups(acme->p, json, "revoke-cert", NULL);
            if (acme->api.v1.new_authz && acme->api.v1.new_cert
                && acme->api.v1.new_reg && acme->api.v1.revoke_cert) {
                acme->version = MD_ACME_VERSION_1;
            }
            acme->ca_agreement = md_json_dups(acme->p, json, "meta", "terms-of-service", NULL);
            /* we init that far, but will not use the v1 api */
        }
    
        if (MD_ACME_VERSION_UNKNOWN == acme->version) {
            md_result_printf(result, APR_EINVAL,
                "Unable to understand ACME server response from <%s>. "
                "Wrong ACME protocol version or link?", acme->url); 
            md_result_log(result, MD_LOG_WARNING);
            rv = result->status;
        }
    leave:
        return rv;
    }
    
    apr_status_t md_acme_setup(md_acme_t *acme, md_result_t *result)
    {
        apr_status_t rv;
        update_dir_ctx ctx;
       
        assert(acme->url);
        acme->version = MD_ACME_VERSION_UNKNOWN;
        
        if (!acme->http && APR_SUCCESS != (rv = md_http_create(&acme->http, acme->p,
                                                               acme->user_agent, acme->proxy_url))) {
            return rv;
        }
        /* TODO: maybe this should be configurable. Let's take some reasonable 
         * defaults for now that protect our client */
        md_http_set_response_limit(acme->http, 1024*1024);
        md_http_set_timeout_default(acme->http, apr_time_from_sec(10 * 60));
        md_http_set_connect_timeout_default(acme->http, apr_time_from_sec(30));
        md_http_set_stalling_default(acme->http, 10, apr_time_from_sec(30));
        md_http_set_ca_file(acme->http, acme->ca_file);
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, acme->p, "get directory from %s", acme->url);
        
        ctx.acme = acme;
        ctx.result = result;
        rv = md_http_GET_perform(acme->http, acme->url, NULL, update_directory, &ctx);
        
        if (APR_SUCCESS != rv && APR_SUCCESS == result->status) {
            /* If the result reports no error, we never got a response from the server */
            md_result_printf(result, rv, 
                "Unsuccessful in contacting ACME server at <%s>. If this problem persists, "
                "please check your network connectivity from your Apache server to the "
                "ACME server. Also, older servers might have trouble verifying the certificates "
                "of the ACME server. You can check if you are able to contact it manually via the "
                "curl command. Sometimes, the ACME server might be down for maintenance, "
                "so failing to contact it is not an immediate problem. Apache will "
                "continue retrying this.", acme->url);
            md_result_log(result, MD_LOG_WARNING);
        }
        return rv;
    }
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md.c��������������������������������������������������������������������0000664�0001751�0001751�00000170777�15017530147�016323� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_optional.h>
    #include <apr_strings.h>
    
    #include <mpm_common.h>
    #include <httpd.h>
    #include <http_core.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_ssl.h>
    #include <http_log.h>
    #include <http_vhost.h>
    #include <ap_listen.h>
    
    #include "mod_status.h"
    
    #include "md.h"
    #include "md_curl.h"
    #include "md_crypt.h"
    #include "md_event.h"
    #include "md_http.h"
    #include "md_json.h"
    #include "md_store.h"
    #include "md_store_fs.h"
    #include "md_log.h"
    #include "md_ocsp.h"
    #include "md_result.h"
    #include "md_reg.h"
    #include "md_status.h"
    #include "md_util.h"
    #include "md_version.h"
    #include "md_acme.h"
    #include "md_acme_authz.h"
    
    #include "mod_md.h"
    #include "mod_md_config.h"
    #include "mod_md_drive.h"
    #include "mod_md_ocsp.h"
    #include "mod_md_os.h"
    #include "mod_md_status.h"
    
    static void md_hooks(apr_pool_t *pool);
    
    AP_DECLARE_MODULE(md) = {
        STANDARD20_MODULE_STUFF,
        NULL,                 /* func to create per dir config */
        NULL,                 /* func to merge per dir config */
        md_config_create_svr, /* func to create per server config */
        md_config_merge_svr,  /* func to merge per server config */
        md_cmds,              /* command handlers */
        md_hooks,
    #if defined(AP_MODULE_FLAG_NONE)
        AP_MODULE_FLAG_ALWAYS_MERGE
    #endif
    };
    
    /**************************************************************************************************/
    /* logging setup */
    
    static server_rec *log_server;
    
    static int log_is_level(void *baton, apr_pool_t *p, md_log_level_t level)
    {
        (void)baton;
        (void)p;
        if (log_server) {
            return APLOG_IS_LEVEL(log_server, (int)level);
        }
        return level <= MD_LOG_INFO;
    }
    
    #define LOG_BUF_LEN 16*1024
    
    static void log_print(const char *file, int line, md_log_level_t level,
                          apr_status_t rv, void *baton, apr_pool_t *p, const char *fmt, va_list ap)
    {
        if (log_is_level(baton, p, level)) {
            char buffer[LOG_BUF_LEN];
    
            memset(buffer, 0, sizeof(buffer));
            apr_vsnprintf(buffer, LOG_BUF_LEN-1, fmt, ap);
            buffer[LOG_BUF_LEN-1] = '\0';
    
            if (log_server) {
                ap_log_error(file, line, APLOG_MODULE_INDEX, (int)level, rv, log_server, "%s", buffer);
            }
            else {
                ap_log_perror(file, line, APLOG_MODULE_INDEX, (int)level, rv, p, "%s", buffer);
            }
        }
    }
    
    /**************************************************************************************************/
    /* mod_ssl interface */
    
    static void init_ssl(void)
    {
        /* nop */
    }
    
    /**************************************************************************************************/
    /* lifecycle */
    
    static apr_status_t cleanup_setups(void *dummy)
    {
        (void)dummy;
        log_server = NULL;
        return APR_SUCCESS;
    }
    
    static void init_setups(apr_pool_t *p, server_rec *base_server)
    {
        log_server = base_server;
        apr_pool_cleanup_register(p, NULL, cleanup_setups, apr_pool_cleanup_null);
    }
    
    /**************************************************************************************************/
    /* notification handling */
    
    typedef struct {
        const char *reason;         /* what the notification is about */
        apr_time_t min_interim;     /* minimum time between notifying for this reason */
    } notify_rate;
    
    static notify_rate notify_rates[] = {
        { "renewing", apr_time_from_sec(MD_SECS_PER_HOUR) }, /* once per hour */
        { "renewed", apr_time_from_sec(MD_SECS_PER_DAY) }, /* once per day */
        { "installed", apr_time_from_sec(MD_SECS_PER_DAY) }, /* once per day */
        { "expiring", apr_time_from_sec(MD_SECS_PER_DAY) },     /* once per day */
        { "errored", apr_time_from_sec(MD_SECS_PER_HOUR) },     /* once per hour */
        { "ocsp-renewed", apr_time_from_sec(MD_SECS_PER_DAY) }, /* once per day */
        { "ocsp-errored", apr_time_from_sec(MD_SECS_PER_HOUR) }, /* once per hour */
    };
    
    static apr_status_t notify(md_job_t *job, const char *reason,
                               md_result_t *result, apr_pool_t *p, void *baton)
    {
        md_mod_conf_t *mc = baton;
        const char * const *argv;
        const char *cmdline;
        int exit_code;
        apr_status_t rv = APR_SUCCESS;
        apr_time_t min_interim = 0;
        md_timeperiod_t since_last;
        const char *log_msg_reason;
        int i;
    
        log_msg_reason = apr_psprintf(p, "message-%s", reason);
        for (i = 0; i < (int)(sizeof(notify_rates)/sizeof(notify_rates[0])); ++i) {
            if (!strcmp(reason, notify_rates[i].reason)) {
                min_interim = notify_rates[i].min_interim;
            }
        }
        if (min_interim > 0) {
            since_last.start = md_job_log_get_time_of_latest(job, log_msg_reason);
            since_last.end = apr_time_now();
            if (since_last.start > 0 && md_timeperiod_length(&since_last) < min_interim) {
                /* not enough time has passed since we sent the last notification
                 * for this reason. */
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, APLOGNO(10267)
                    "%s: rate limiting notification about '%s'", job->mdomain, reason);
                return APR_SUCCESS;
            }
        }
    
        if (!strcmp("renewed", reason)) {
            if (mc->notify_cmd) {
                cmdline = apr_psprintf(p, "%s %s", mc->notify_cmd, job->mdomain);
                apr_tokenize_to_argv(cmdline, (char***)&argv, p);
                rv = md_util_exec(p, argv[0], argv, &exit_code);
    
                if (APR_SUCCESS == rv && exit_code) rv = APR_EGENERAL;
                if (APR_SUCCESS != rv) {
                    md_result_problem_printf(result, rv, MD_RESULT_LOG_ID(APLOGNO(10108)),
                                             "MDNotifyCmd %s failed with exit code %d.",
                                             mc->notify_cmd, exit_code);
                    md_result_log(result, MD_LOG_ERR);
                    md_job_log_append(job, "notify-error", result->problem, result->detail);
                    return rv;
                }
            }
            md_log_perror(MD_LOG_MARK, MD_LOG_NOTICE, 0, p, APLOGNO(10059)
                         "The Managed Domain %s has been setup and changes "
                         "will be activated on next (graceful) server restart.", job->mdomain);
        }
        if (mc->message_cmd) {
            cmdline = apr_psprintf(p, "%s %s %s", mc->message_cmd, reason, job->mdomain);
            apr_tokenize_to_argv(cmdline, (char***)&argv, p);
            rv = md_util_exec(p, argv[0], argv, &exit_code);
    
            if (APR_SUCCESS == rv && exit_code) rv = APR_EGENERAL;
            if (APR_SUCCESS != rv) {
                md_result_problem_printf(result, rv, MD_RESULT_LOG_ID(APLOGNO(10109)),
                                         "MDMessageCmd %s failed with exit code %d.",
                                         mc->message_cmd, exit_code);
                md_result_log(result, MD_LOG_ERR);
                md_job_log_append(job, "message-error", reason, result->detail);
                return rv;
            }
        }
    
        md_job_log_append(job, log_msg_reason, NULL, NULL);
        return APR_SUCCESS;
    }
    
    static apr_status_t on_event(const char *event, const char *mdomain, void *baton, 
                                 md_job_t *job, md_result_t *result, apr_pool_t *p)
    {
        (void)mdomain;
        return notify(job, event, result, p, baton);
    }
    
    /**************************************************************************************************/
    /* store setup */
    
    static apr_status_t store_file_ev(void *baton, struct md_store_t *store,
                                        md_store_fs_ev_t ev, unsigned int group,
                                        const char *fname, apr_filetype_e ftype,
                                        apr_pool_t *p)
    {
        server_rec *s = baton;
        apr_status_t rv;
    
        (void)store;
        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "store event=%d on %s %s (group %d)",
                     ev, (ftype == APR_DIR)? "dir" : "file", fname, group);
    
        /* Directories in group CHALLENGES, STAGING and OCSP are written to
         * under a different user. Give her ownership.
         */
        if (ftype == APR_DIR) {
            switch (group) {
                case MD_SG_CHALLENGES:
                case MD_SG_STAGING:
                case MD_SG_OCSP:
                    rv = md_make_worker_accessible(fname, p);
                    if (APR_ENOTIMPL != rv) {
                        return rv;
                    }
                    break;
                default:
                    break;
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t check_group_dir(md_store_t *store, md_store_group_t group,
                                        apr_pool_t *p, server_rec *s)
    {
        const char *dir;
        apr_status_t rv;
    
        if (APR_SUCCESS == (rv = md_store_get_fname(&dir, store, group, NULL, NULL, p))
            && APR_SUCCESS == (rv = apr_dir_make_recursive(dir, MD_FPROT_D_UALL_GREAD, p))) {
            rv = store_file_ev(s, store, MD_S_FS_EV_CREATED, group, dir, APR_DIR, p);
        }
        return rv;
    }
    
    static apr_status_t setup_store(md_store_t **pstore, md_mod_conf_t *mc,
                                    apr_pool_t *p, server_rec *s)
    {
        const char *base_dir;
        apr_status_t rv;
    
        base_dir = ap_server_root_relative(p, mc->base_dir);
    
        if (APR_SUCCESS != (rv = md_store_fs_init(pstore, p, base_dir))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10046)"setup store for %s", base_dir);
            goto leave;
        }
    
        md_store_fs_set_event_cb(*pstore, store_file_ev, s);
        if (APR_SUCCESS != (rv = check_group_dir(*pstore, MD_SG_CHALLENGES, p, s))
            || APR_SUCCESS != (rv = check_group_dir(*pstore, MD_SG_STAGING, p, s))
            || APR_SUCCESS != (rv = check_group_dir(*pstore, MD_SG_ACCOUNTS, p, s))
            || APR_SUCCESS != (rv = check_group_dir(*pstore, MD_SG_OCSP, p, s))
            ) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10047)
                         "setup challenges directory");
            goto leave;
        }
    
    leave:
        return rv;
    }
    
    /**************************************************************************************************/
    /* post config handling */
    
    static void merge_srv_config(md_t *md, md_srv_conf_t *base_sc, apr_pool_t *p)
    {
        const char *contact;
    
        if (!md->sc) {
            md->sc = base_sc;
        }
    
        if (!md->ca_urls && md->sc->ca_urls) {
            md->ca_urls = apr_array_copy(p, md->sc->ca_urls);
        }
        if (!md->ca_proto) {
            md->ca_proto = md_config_gets(md->sc, MD_CONFIG_CA_PROTO);
        }
        if (!md->ca_agreement) {
            md->ca_agreement = md_config_gets(md->sc, MD_CONFIG_CA_AGREEMENT);
        }
        contact = md_config_gets(md->sc, MD_CONFIG_CA_CONTACT);
        if (md->contacts && md->contacts->nelts > 0) {
            /* set explicitly */
        }
        else if (contact && contact[0]) {
            apr_array_clear(md->contacts);
            APR_ARRAY_PUSH(md->contacts, const char *) =
            md_util_schemify(p, contact, "mailto");
        }
        else if( md->sc->s->server_admin && strcmp(DEFAULT_ADMIN, md->sc->s->server_admin)) {
            apr_array_clear(md->contacts);
            APR_ARRAY_PUSH(md->contacts, const char *) =
            md_util_schemify(p, md->sc->s->server_admin, "mailto");
        }
        if (md->renew_mode == MD_RENEW_DEFAULT) {
            md->renew_mode = md_config_geti(md->sc, MD_CONFIG_DRIVE_MODE);
        }
        if (!md->renew_window) md_config_get_timespan(&md->renew_window, md->sc, MD_CONFIG_RENEW_WINDOW);
        if (!md->warn_window) md_config_get_timespan(&md->warn_window, md->sc, MD_CONFIG_WARN_WINDOW);
        if (md->transitive < 0) {
            md->transitive = md_config_geti(md->sc, MD_CONFIG_TRANSITIVE);
        }
        if (!md->ca_challenges && md->sc->ca_challenges) {
            md->ca_challenges = apr_array_copy(p, md->sc->ca_challenges);
        }
        if (md_pkeys_spec_is_empty(md->pks)) {
            md->pks = md->sc->pks;
        }
        if (md->require_https < 0) {
            md->require_https = md_config_geti(md->sc, MD_CONFIG_REQUIRE_HTTPS);
        }
        if (!md->ca_eab_kid) {
            md->ca_eab_kid = md->sc->ca_eab_kid;
            md->ca_eab_hmac = md->sc->ca_eab_hmac;
        }
        if (md->must_staple < 0) {
            md->must_staple = md_config_geti(md->sc, MD_CONFIG_MUST_STAPLE);
        }
        if (md->stapling < 0) {
            md->stapling = md_config_geti(md->sc, MD_CONFIG_STAPLING);
        }
        if (!md->profile) {
            md->profile = md_config_gets(md->sc, MD_CONFIG_CA_PROFILE);
        }
        if (md->profile_mandatory < 0) {
            md->profile_mandatory = md_config_geti(md->sc, MD_CONFIG_CA_PROFILE_MANDATORY);
        }
    }
    
    static apr_status_t check_coverage(md_t *md, const char *domain, server_rec *s,
                                       int *pupdates, apr_pool_t *p)
    {
        if (md_contains(md, domain, 0)) {
            return APR_SUCCESS;
        }
        else if (md->transitive) {
            APR_ARRAY_PUSH(md->domains, const char*) = apr_pstrdup(p, domain);
            *pupdates |= MD_UPD_DOMAINS;
            return APR_SUCCESS;
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10040)
                         "Virtual Host %s:%d matches Managed Domain '%s', but the "
                         "name/alias %s itself is not managed. A requested MD certificate "
                         "will not match ServerName.",
                         s->server_hostname, s->port, md->name, domain);
            return APR_SUCCESS;
        }
    }
    
    static apr_status_t md_cover_server(md_t *md, server_rec *s, int *pupdates, apr_pool_t *p)
    {
        apr_status_t rv;
        const char *name;
        int i;
    
        if (APR_SUCCESS == (rv = check_coverage(md, s->server_hostname, s, pupdates, p))) {
            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
                         "md[%s]: auto add, covers name %s", md->name, s->server_hostname);
            for (i = 0; s->names && i < s->names->nelts; ++i) {
                name = APR_ARRAY_IDX(s->names, i, const char*);
                if (APR_SUCCESS != (rv = check_coverage(md, name, s, pupdates, p))) {
                    break;
                }
                ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
                             "md[%s]: auto add, covers alias %s", md->name, name);
            }
        }
        return rv;
    }
    
    static int uses_port(server_rec *s, int port)
    {
        server_addr_rec *sa;
        int match = 0;
        for (sa = s->addrs; sa; sa = sa->next) {
            if (sa->host_port == port) {
                /* host_addr might be general (0.0.0.0) or specific, we count this as match */
                match = 1;
            }
            else {
                /* uses other port/wildcard */
                return 0;
            }
        }
        return match;
    }
    
    static apr_status_t detect_supported_protocols(md_mod_conf_t *mc, server_rec *s,
                                                   apr_pool_t *p, int log_level)
    {
        ap_listen_rec *lr;
        apr_sockaddr_t *sa;
        int can_http, can_https;
    
        if (mc->can_http >= 0 && mc->can_https >= 0) goto set_and_leave;
    
        can_http = can_https = 0;
        for (lr = ap_listeners; lr; lr = lr->next) {
            for (sa = lr->bind_addr; sa; sa = sa->next) {
                if  (sa->port == mc->local_80
                     && (!lr->protocol || !strncmp("http", lr->protocol, 4))) {
                    can_http = 1;
                }
                else if (sa->port == mc->local_443
                         && (!lr->protocol || !strncmp("http", lr->protocol, 4))) {
                    can_https = 1;
                }
            }
        }
        if (mc->can_http < 0) mc->can_http = can_http;
        if (mc->can_https < 0) mc->can_https = can_https;
        ap_log_error(APLOG_MARK, log_level, 0, s, APLOGNO(10037)
                     "server seems%s reachable via http: and%s reachable via https:",
                     mc->can_http? "" : " not", mc->can_https? "" : " not");
    set_and_leave:
        return md_reg_set_props(mc->reg, p, mc->can_http, mc->can_https);
    }
    
    static server_rec *get_public_https_server(md_t *md, const char *domain, server_rec *base_server)
    {
        md_srv_conf_t *sc;
        md_mod_conf_t *mc;
        server_rec *s;
        server_rec *res = NULL;
        request_rec r;
        int i;
        int check_port = 1;
    
        sc = md_config_get(base_server);
        mc = sc->mc;
        memset(&r, 0, sizeof(r));
    
        if (md->ca_challenges && md->ca_challenges->nelts > 0) {
            /* skip the port check if "tls-alpn-01" is pre-configured */
            check_port = !(md_array_str_index(md->ca_challenges, MD_AUTHZ_TYPE_TLSALPN01, 0, 0) >= 0);
        }
    
        if (check_port && !mc->can_https) return NULL;
    
        /* find an ssl server matching domain from MD */
        for (s = base_server; s; s = s->next) {
            sc = md_config_get(s);
            if (!sc || !sc->is_ssl || !sc->assigned) continue;
            if (base_server == s && !mc->manage_base_server) continue;
            if (base_server != s && check_port && mc->local_443 > 0 && !uses_port(s, mc->local_443)) continue;
            for (i = 0; i < sc->assigned->nelts; ++i) {
                if (md == APR_ARRAY_IDX(sc->assigned, i, md_t*)) {
                    r.server = s;
                    if (ap_matches_request_vhost(&r, domain, s->port)) {
                        if (check_port) {
                            return s;
                        }
                        else {
                            /* there may be multiple matching servers because we ignore the port.
                               if possible, choose a server that supports the acme-tls/1 protocol */
                            if (ap_is_allowed_protocol(NULL, NULL, s, PROTO_ACME_TLS_1)) {
                                return s;
                            }
                            res = s;
                        }
                    }
                }
            }
        }
        return res;
    }
    
    static apr_status_t auto_add_domains(md_t *md, server_rec *base_server, apr_pool_t *p)
    {
        md_srv_conf_t *sc;
        server_rec *s;
        apr_status_t rv = APR_SUCCESS;
        int updates;
    
        /* Ad all domain names used in SSL VirtualHosts, if not already there */
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, base_server,
                     "md[%s]: auto add domains", md->name);
        updates = 0;
        for (s = base_server; s; s = s->next) {
            sc = md_config_get(s);
            if (!sc || !sc->is_ssl || !sc->assigned || sc->assigned->nelts != 1) continue;
            if (md != APR_ARRAY_IDX(sc->assigned, 0, md_t*)) continue;
            if (APR_SUCCESS != (rv = md_cover_server(md, s, &updates, p))) {
                return rv;
            }
        }
        return rv;
    }
    
    static void init_acme_tls_1_domains(md_t *md, server_rec *base_server)
    {
        md_srv_conf_t *sc;
        md_mod_conf_t *mc;
        server_rec *s;
        int i;
        const char *domain;
    
        /* Collect those domains that support the "acme-tls/1" protocol. This
         * is part of the MD (and not tested dynamically), since challenge selection
         * may be done outside the server, e.g. in the a2md command. */
        sc = md_config_get(base_server);
        mc = sc->mc;
        apr_array_clear(md->acme_tls_1_domains);
        for (i = 0; i < md->domains->nelts; ++i) {
            domain = APR_ARRAY_IDX(md->domains, i, const char*);
            s = get_public_https_server(md, domain, base_server);
            /* If we did not find a specific virtualhost for md and manage
             * the base_server, that one is inspected */
            if (NULL == s && mc->manage_base_server) s = base_server;
            if (NULL == s) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, base_server, APLOGNO(10168)
                             "%s: no https server_rec found for %s", md->name, domain);
                continue;
            }
            if (!ap_is_allowed_protocol(NULL, NULL, s, PROTO_ACME_TLS_1)) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, base_server, APLOGNO(10169)
                             "%s: https server_rec for %s does not have protocol %s enabled",
                             md->name, domain, PROTO_ACME_TLS_1);
                continue;
            }
            APR_ARRAY_PUSH(md->acme_tls_1_domains, const char*) = domain;
        }
    }
    
    static apr_status_t link_md_to_servers(md_mod_conf_t *mc, md_t *md, server_rec *base_server,
                                           apr_pool_t *p)
    {
        server_rec *s;
        request_rec r;
        md_srv_conf_t *sc;
        int i;
        const char *domain, *uri;
    
        sc = md_config_get(base_server);
    
        /* Assign the MD to all server_rec configs that it matches. If there already
         * is an assigned MD not equal this one, the configuration is in error.
         */
        memset(&r, 0, sizeof(r));
        for (s = base_server; s; s = s->next) {
            if (!mc->manage_base_server && s == base_server) {
                /* we shall not assign ourselves to the base server */
                continue;
            }
    
            r.server = s;
            for (i = 0; i < md->domains->nelts; ++i) {
                domain = APR_ARRAY_IDX(md->domains, i, const char*);
    
                if ((mc->match_mode == MD_MATCH_ALL &&
                     ap_matches_request_vhost(&r, domain, s->port))
                    || (((mc->match_mode == MD_MATCH_SERVERNAMES) || md_dns_is_wildcard(p, domain)) &&
                        md_dns_matches(domain, s->server_hostname))) {
                    /* Create a unique md_srv_conf_t record for this server, if there is none yet */
                    sc = md_config_get_unique(s, p);
                    if (!sc->assigned) sc->assigned = apr_array_make(p, 2, sizeof(md_t*));
                    if (sc->assigned->nelts == 1 && mc->match_mode == MD_MATCH_SERVERNAMES) {
                        /* there is already an MD assigned for this server. But in
                         * this match mode, wildcard matches are pre-empted by non-wildcards */
                        int existing_wild = md_is_wild_match(
                              APR_ARRAY_IDX(sc->assigned, 0, const md_t*)->domains,
                              s->server_hostname);
                        if (!existing_wild && md_dns_is_wildcard(p, domain))
                            continue;  /* do not add */
                        if (existing_wild && !md_dns_is_wildcard(p, domain))
                            sc->assigned->nelts = 0;  /* overwrite existing */
                    }
                    APR_ARRAY_PUSH(sc->assigned, md_t*) = md;
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, base_server, APLOGNO(10041)
                                 "Server %s:%d matches md %s (config %s, match-mode=%d) "
                                 "for domain %s, has now %d MDs",
                                 s->server_hostname, s->port, md->name, sc->name,
                                 mc->match_mode, domain, (int)sc->assigned->nelts);
    
                    if (md->contacts && md->contacts->nelts > 0) {
                        /* set explicitly */
                    }
                    else if (sc->ca_contact && sc->ca_contact[0]) {
                        uri = md_util_schemify(p, sc->ca_contact, "mailto");
                        if (md_array_str_index(md->contacts, uri, 0, 0) < 0) {
                            APR_ARRAY_PUSH(md->contacts, const char *) = uri;
                            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, base_server, APLOGNO(10044)
                                         "%s: added contact %s", md->name, uri);
                        }
                    }
                    else if (s->server_admin && strcmp(DEFAULT_ADMIN, s->server_admin)) {
                        uri = md_util_schemify(p, s->server_admin, "mailto");
                        if (md_array_str_index(md->contacts, uri, 0, 0) < 0) {
                            APR_ARRAY_PUSH(md->contacts, const char *) = uri;
                            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, base_server, APLOGNO(10237)
                                         "%s: added contact %s", md->name, uri);
                        }
                    }
                    break;
                }
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t link_mds_to_servers(md_mod_conf_t *mc, server_rec *s, apr_pool_t *p)
    {
        int i;
        md_t *md;
        apr_status_t rv = APR_SUCCESS;
    
        apr_array_clear(mc->unused_names);
        for (i = 0; i < mc->mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mc->mds, i, md_t*);
            if (APR_SUCCESS != (rv = link_md_to_servers(mc, md, s, p))) {
                goto leave;
            }
        }
    leave:
        return rv;
    }
    
    static apr_status_t merge_mds_with_conf(md_mod_conf_t *mc, apr_pool_t *p,
                                            server_rec *base_server, int log_level)
    {
        md_srv_conf_t *base_conf;
        md_t *md, *omd;
        const char *domain;
        md_timeslice_t *ts;
        apr_status_t rv = APR_SUCCESS;
        int i, j;
    
        /* The global module configuration 'mc' keeps a list of all configured MDomains
         * in the server. This list is collected during configuration processing and,
         * in the post config phase, get updated from all merged server configurations
         * before the server starts processing.
         */
        base_conf = md_config_get(base_server);
        md_config_get_timespan(&ts, base_conf, MD_CONFIG_RENEW_WINDOW);
        if (ts) md_reg_set_renew_window_default(mc->reg, ts);
        md_config_get_timespan(&ts, base_conf, MD_CONFIG_WARN_WINDOW);
        if (ts) md_reg_set_warn_window_default(mc->reg, ts);
    
        /* Complete the properties of the MDs, now that we have the complete, merged
         * server configurations.
         */
        for (i = 0; i < mc->mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mc->mds, i, md_t*);
            merge_srv_config(md, base_conf, p);
    
            if (mc->match_mode == MD_MATCH_ALL) {
              /* Check that we have no overlap with the MDs already completed */
              for (j = 0; j < i; ++j) {
                  omd = APR_ARRAY_IDX(mc->mds, j, md_t*);
                  if ((domain = md_common_name(md, omd)) != NULL) {
                      ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10038)
                                   "two Managed Domains have an overlap in domain '%s'"
                                   ", first definition in %s(line %d), second in %s(line %d)",
                                   domain, md->defn_name, md->defn_line_number,
                                   omd->defn_name, omd->defn_line_number);
                      return APR_EINVAL;
                  }
              }
            }
    
            if (md->cert_files && md->cert_files->nelts) {
                if (!md->pkey_files || (md->cert_files->nelts != md->pkey_files->nelts)) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10170)
                                 "The Managed Domain '%s' "
                                 "needs one MDCertificateKeyFile for each MDCertificateFile.",
                                 md->name);
                    return APR_EINVAL;
                }
            }
            else if (md->pkey_files && md->pkey_files->nelts 
                && (!md->cert_files || !md->cert_files->nelts)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10171)
                             "The Managed Domain '%s' "
                             "has MDCertificateKeyFile(s) but no MDCertificateFile.",
                             md->name);
                return APR_EINVAL;
            }
    
            if (APLOG_IS_LEVEL(base_server, log_level)) {
                ap_log_error(APLOG_MARK, log_level, 0, base_server, APLOGNO(10039)
                             "Completed MD[%s, CA=%s, Proto=%s, Agreement=%s, renew-mode=%d "
                             "renew_window=%s, warn_window=%s",
                             md->name, md->ca_effective, md->ca_proto, md->ca_agreement, md->renew_mode,
                             md->renew_window? md_timeslice_format(md->renew_window, p) : "unset",
                             md->warn_window? md_timeslice_format(md->warn_window, p) : "unset");
            }
        }
        return rv;
    }
    
    static apr_status_t check_invalid_duplicates(server_rec *base_server)
    {
        server_rec *s;
        md_srv_conf_t *sc;
    
        ap_log_error( APLOG_MARK, APLOG_TRACE1, 0, base_server,
                     "checking duplicate ssl assignments");
        for (s = base_server; s; s = s->next) {
            sc = md_config_get(s);
            if (!sc || !sc->assigned) continue;
    
            if (sc->assigned->nelts > 1 && sc->is_ssl) {
                /* duplicate assignment to SSL VirtualHost, not allowed */
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10042)
                             "conflict: %d MDs match to SSL VirtualHost %s, there can at most be one.",
                             (int)sc->assigned->nelts, s->server_hostname);
                return APR_EINVAL;
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t check_usage(md_mod_conf_t *mc, md_t *md, server_rec *base_server,
                                    apr_pool_t *p, apr_pool_t *ptemp)
    {
        server_rec *s;
        md_srv_conf_t *sc;
        apr_status_t rv = APR_SUCCESS;
        int i, has_ssl;
        apr_array_header_t *servers;
    
        (void)p;
        servers = apr_array_make(ptemp, 5, sizeof(server_rec*));
        has_ssl = 0;
        for (s = base_server; s; s = s->next) {
            sc = md_config_get(s);
            if (!sc || !sc->assigned) continue;
            for (i = 0; i < sc->assigned->nelts; ++i) {
                if (md == APR_ARRAY_IDX(sc->assigned, i, md_t*)) {
                    APR_ARRAY_PUSH(servers, server_rec*) = s;
                    if (sc->is_ssl) has_ssl = 1;
                }
            }
        }
    
        if (!has_ssl && md->require_https > MD_REQUIRE_OFF) {
            /* We require https for this MD, but do we have a SSL vhost? */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(10105)
                         "MD %s does not match any VirtualHost with 'SSLEngine on', "
                         "but is configured to require https. This cannot work.", md->name);
        }
        if (apr_is_empty_array(servers)) {
            if (md->renew_mode != MD_RENEW_ALWAYS) {
                /* Not an error, but looks suspicious */
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(10045)
                             "No VirtualHost matches Managed Domain %s", md->name);
                APR_ARRAY_PUSH(mc->unused_names, const char*)  = md->name;
            }
        }
        return rv;
    }
    
    static int init_cert_watch_status(md_mod_conf_t *mc, apr_pool_t *p, apr_pool_t *ptemp, server_rec *s)
    {
        md_t *md;
        md_result_t *result;
        int i, count;
    
        /* Calculate the list of MD names which we need to watch:
         * - all MDs that are used somewhere
         * - all MDs in drive mode 'AUTO' that are not in 'unused_names'
         */
        count = 0;
        result = md_result_make(ptemp, APR_SUCCESS);
        for (i = 0; i < mc->mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mc->mds, i, md_t*);
            md_result_set(result, APR_SUCCESS, NULL);
            md->watched = 0;
            if (md->state == MD_S_ERROR) {
                md_result_set(result, APR_EGENERAL,
                              "in error state, unable to drive forward. This "
                              "indicates an incomplete or inconsistent configuration. "
                              "Please check the log for warnings in this regard.");
                continue;
            }
    
            if (md->renew_mode == MD_RENEW_AUTO
                && md_array_str_index(mc->unused_names, md->name, 0, 0) >= 0) {
                /* This MD is not used in any virtualhost, do not watch */
                continue;
            }
    
            if (md_will_renew_cert(md)) {
                /* make a test init to detect early errors. */
                md_reg_test_init(mc->reg, md, mc->env, result, p);
                if (APR_SUCCESS != result->status && result->detail) {
                    apr_hash_set(mc->init_errors, md->name, APR_HASH_KEY_STRING, apr_pstrdup(p, result->detail));
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(10173)
                                 "md[%s]: %s", md->name, result->detail);
                }
            }
    
            md->watched = 1;
            ++count;
        }
        return count;
    }
    
    static apr_status_t md_post_config_before_ssl(apr_pool_t *p, apr_pool_t *plog,
                                                  apr_pool_t *ptemp, server_rec *s)
    {
        void *data = NULL;
        const char *mod_md_init_key = "mod_md_init_counter";
        md_srv_conf_t *sc;
        md_mod_conf_t *mc;
        apr_status_t rv = APR_SUCCESS;
        int dry_run = 0, log_level = APLOG_DEBUG;
        md_store_t *store;
    
        apr_pool_userdata_get(&data, mod_md_init_key, s->process->pool);
        if (data == NULL) {
            /* At the first start, httpd makes a config check dry run. It
             * runs all config hooks to check if it can. If so, it does
             * this all again and starts serving requests.
             *
             * On a dry run, we therefore do all the cheap config things we
             * need to do to find out if the settings are ok. More expensive
             * things we delay to the real run.
             */
            dry_run = 1;
            log_level = APLOG_TRACE1;
            ap_log_error( APLOG_MARK, log_level, 0, s, APLOGNO(10070)
                         "initializing post config dry run");
            apr_pool_userdata_set((const void *)1, mod_md_init_key,
                                  apr_pool_cleanup_null, s->process->pool);
        }
        else {
            ap_log_error( APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(10071)
                         "mod_md (v%s), initializing...", MOD_MD_VERSION);
        }
    
        (void)plog;
        init_setups(p, s);
        md_log_set(log_is_level, log_print, NULL);
    
        md_config_post_config(s, p);
        sc = md_config_get(s);
        mc = sc->mc;
        mc->dry_run = dry_run;
    
        md_event_init(p);
        md_event_subscribe(on_event, mc);
    
        rv = setup_store(&store, mc, p, s);
        if (APR_SUCCESS != rv) goto leave;
    
        rv = md_reg_create(&mc->reg, p, store, mc->proxy_url, mc->ca_certs,
                           mc->min_delay, mc->retry_failover,
                           mc->use_store_locks, mc->lock_wait_timeout);
        if (APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10072) "setup md registry");
            goto leave;
        }
    
        /* renew on 30% remaining /*/
        rv = md_ocsp_reg_make(&mc->ocsp, p, store, mc->ocsp_renew_window,
                              AP_SERVER_BASEVERSION, mc->proxy_url,
                              mc->min_delay);
        if (APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10196) "setup ocsp registry");
            goto leave;
        }
    
        init_ssl();
    
        /* How to bootstrap this module:
         * 1. find out if we know if http: and/or https: requests will arrive
         * 2. apply the now complete configuration settings to the MDs
         * 3. Link MDs to the server_recs they are used in. Detect unused MDs.
         * 4. Update the store with the MDs. Change domain names, create new MDs, etc.
         *    Basically all MD properties that are configured directly.
         *    WARNING: this may change the name of an MD. If an MD loses the first
         *    of its domain names, it first gets the new first one as name. The
         *    store will find the old settings and "recover" the previous name.
         * 5. Load any staged data from previous driving.
         * 6. on a dry run, this is all we do
         * 7. Read back the MD properties that reflect the existence and aspect of
         *    credentials that are in the store (or missing there).
         *    Expiry times, MD state, etc.
         * 8. Determine the list of MDs that need driving/supervision.
         * 9. Cleanup any left-overs in registry/store that are no longer needed for
         *    the list of MDs as we know it now.
         * 10. If this list is non-empty, setup a watchdog to run.
         */
        /*1*/
        if (APR_SUCCESS != (rv = detect_supported_protocols(mc, s, p, log_level))) goto leave;
        /*2*/
        if (APR_SUCCESS != (rv = merge_mds_with_conf(mc, p, s, log_level))) goto leave;
        /*3*/
        if (APR_SUCCESS != (rv = link_mds_to_servers(mc, s, p))) goto leave;
        /*4*/
        if (APR_SUCCESS != (rv = md_reg_lock_global(mc->reg, ptemp))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10398)
                         "unable to obtain global registry lock, "
                         "renewed certificates may remain inactive on "
                         "this httpd instance!");
            /* FIXME: or should we fail the server start/reload here? */
            rv = APR_SUCCESS;
            goto leave;
        }
        if (APR_SUCCESS != (rv = md_reg_sync_start(mc->reg, mc->mds, ptemp))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10073)
                         "syncing %d mds to registry", mc->mds->nelts);
            goto leave;
        }
        /*5*/
        md_reg_load_stagings(mc->reg, mc->mds, mc->env, p);
    leave:
        if (mc->reg)
            md_reg_unlock_global(mc->reg, ptemp);
        return rv;
    }
    
    static apr_status_t md_post_config_after_ssl(apr_pool_t *p, apr_pool_t *plog,
                                                 apr_pool_t *ptemp, server_rec *s)
    {
        md_srv_conf_t *sc;
        apr_status_t rv = APR_SUCCESS;
        md_mod_conf_t *mc;
        int watched, i;
        md_t *md;
    
        (void)ptemp;
        (void)plog;
        sc = md_config_get(s);
    
        /*6*/
        if (!sc || !sc->mc || sc->mc->dry_run) goto leave;
        mc = sc->mc;
    
        /*7*/
        if (APR_SUCCESS != (rv = check_invalid_duplicates(s))) {
            goto leave;
        }
        apr_array_clear(mc->unused_names);
        for (i = 0; i < mc->mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mc->mds, i, md_t *);
    
            ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "md{%s}: auto_add", md->name);
            if (APR_SUCCESS != (rv = auto_add_domains(md, s, p))) {
                goto leave;
            }
            init_acme_tls_1_domains(md, s);
            ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "md{%s}: check_usage", md->name);
            if (APR_SUCCESS != (rv = check_usage(mc, md, s, p, ptemp))) {
                goto leave;
            }
            ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "md{%s}: sync_finish", md->name);
            if (APR_SUCCESS != (rv = md_reg_sync_finish(mc->reg, md, p, ptemp))) {
                ap_log_error( APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10172)
                             "md[%s]: error syncing to store", md->name);
                goto leave;
            }
        }
        /*8*/
        ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "init_cert_watch");
        watched = init_cert_watch_status(mc, p, ptemp, s);
        /*9*/
        ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "cleanup challenges");
        md_reg_cleanup_challenges(mc->reg, p, ptemp, mc->mds);
    
        /* From here on, the domains in the registry are readonly
         * and only staging/challenges may be manipulated */
        md_reg_freeze_domains(mc->reg, mc->mds);
    
        if (watched) {
            /*10*/
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(10074)
                         "%d out of %d mds need watching", watched, mc->mds->nelts);
    
            md_http_use_implementation(md_curl_get_impl(p));
            rv = md_renew_start_watching(mc, s, p);
        }
        else {
            ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10075) "no mds to supervise");
        }
    
        if (!mc->ocsp || md_ocsp_count(mc->ocsp) == 0) {
            ap_log_error( APLOG_MARK, APLOG_TRACE1, 0, s, "no ocsp to manage");
            goto leave;
        }
    
        md_http_use_implementation(md_curl_get_impl(p));
        rv = md_ocsp_start_watching(mc, s, p);
    
    leave:
        ap_log_error( APLOG_MARK, APLOG_TRACE2, rv, s, "post_config done");
        return rv;
    }
    
    /**************************************************************************************************/
    /* connection context */
    
    typedef struct {
        const char *protocol;
    } md_conn_ctx;
    
    static const char *md_protocol_get(const conn_rec *c)
    {
        md_conn_ctx *ctx;
    
        ctx = (md_conn_ctx*)ap_get_module_config(c->conn_config, &md_module);
        return ctx? ctx->protocol : NULL;
    }
    
    /**************************************************************************************************/
    /* ALPN handling */
    
    static int md_protocol_propose(conn_rec *c, request_rec *r,
                                   server_rec *s,
                                   const apr_array_header_t *offers,
                                   apr_array_header_t *proposals)
    {
        (void)s;
        if (!r && offers && ap_ssl_conn_is_ssl(c)
            && ap_array_str_contains(offers, PROTO_ACME_TLS_1)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "proposing protocol '%s'", PROTO_ACME_TLS_1);
            APR_ARRAY_PUSH(proposals, const char*) = PROTO_ACME_TLS_1;
            return OK;
        }
        return DECLINED;
    }
    
    static int md_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
                                  const char *protocol)
    {
        md_conn_ctx *ctx;
    
        (void)s;
        if (!r && ap_ssl_conn_is_ssl(c) && !strcmp(PROTO_ACME_TLS_1, protocol)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "switching protocol '%s'", PROTO_ACME_TLS_1);
            ctx = apr_pcalloc(c->pool, sizeof(*ctx));
            ctx->protocol = PROTO_ACME_TLS_1;
            ap_set_module_config(c->conn_config, &md_module, ctx);
    
            c->keepalive = AP_CONN_CLOSE;
            return OK;
        }
        return DECLINED;
    }
    
    
    /**************************************************************************************************/
    /* Access API to other httpd components */
    
    static void fallback_fnames(apr_pool_t *p, md_pkey_spec_t *kspec, char **keyfn, char **certfn )
    {
        *keyfn  = apr_pstrcat(p, "fallback-", md_pkey_filename(kspec, p), NULL);
        *certfn = apr_pstrcat(p, "fallback-", md_chain_filename(kspec, p), NULL);
    }
    
    static apr_status_t make_fallback_cert(md_store_t *store, const md_t *md, md_pkey_spec_t *kspec,
                                           server_rec *s, apr_pool_t *p, char *keyfn, char *crtfn)
    {
        md_pkey_t *pkey;
        md_cert_t *cert;
        apr_status_t rv;
    
        if (APR_SUCCESS != (rv = md_pkey_gen(&pkey, p, kspec))
            || APR_SUCCESS != (rv = md_store_save(store, p, MD_SG_DOMAINS, md->name,
                                    keyfn, MD_SV_PKEY, (void*)pkey, 0))
            || APR_SUCCESS != (rv = md_cert_self_sign(&cert, "Apache Managed Domain Fallback",
                                        md->domains, pkey, apr_time_from_sec(14 * MD_SECS_PER_DAY), p))
            || APR_SUCCESS != (rv = md_store_save(store, p, MD_SG_DOMAINS, md->name,
                                    crtfn, MD_SV_CERT, (void*)cert, 0))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10174)
                         "%s: make fallback %s certificate", md->name, md_pkey_spec_name(kspec));
        }
        return rv;
    }
    
    static apr_status_t get_certificates(server_rec *s, apr_pool_t *p, int fallback,
                                         apr_array_header_t **pcert_files,
                                         apr_array_header_t **pkey_files)
    {
        apr_status_t rv = APR_ENOENT;
        md_srv_conf_t *sc;
        md_reg_t *reg;
        md_store_t *store;
        const md_t *md;
        apr_array_header_t *key_files, *chain_files;
        const char *keyfile, *chainfile;
        int i;
    
        *pkey_files = *pcert_files = NULL;
        key_files = apr_array_make(p, 5, sizeof(const char*));
        chain_files = apr_array_make(p, 5, sizeof(const char*));
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10113)
                     "get_certificates called for vhost %s.", s->server_hostname);
    
        sc = md_config_get(s);
        if (!sc) {
            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
                         "asked for certificate of server %s which has no md config",
                         s->server_hostname);
            return APR_ENOENT;
        }
    
        assert(sc->mc);
        reg = sc->mc->reg;
        assert(reg);
    
        sc->is_ssl = 1;
    
        if (!sc->assigned) {
            /* With the new hooks in mod_ssl, we are invoked for all server_rec. It is
             * therefore normal, when we have nothing to add here. */
            return APR_ENOENT;
        }
        else if (sc->assigned->nelts != 1) {
            if (!fallback) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(10238)
                             "conflict: %d MDs match Virtualhost %s which uses SSL, however "
                             "there can be at most 1.",
                             (int)sc->assigned->nelts, s->server_hostname);
            }
            return APR_EINVAL;
        }
        md = APR_ARRAY_IDX(sc->assigned, 0, const md_t*);
    
        if (md->cert_files && md->cert_files->nelts) {
            apr_array_cat(chain_files, md->cert_files);
            apr_array_cat(key_files, md->pkey_files);
            rv = APR_SUCCESS;
        }
        else {
            md_pkey_spec_t *spec;
            
            for (i = 0; i < md_cert_count(md); ++i) {
                spec = md_pkeys_spec_get(md->pks, i);
                rv = md_reg_get_cred_files(&keyfile, &chainfile, reg, MD_SG_DOMAINS, md, spec, p);
                if (APR_SUCCESS == rv) {
                    APR_ARRAY_PUSH(key_files, const char*) = keyfile;
                    APR_ARRAY_PUSH(chain_files, const char*) = chainfile;
                }
                else if (APR_STATUS_IS_ENOENT(rv)) {
                    /* certificate for this pkey is not available, others might
                     * if pkeys have been added for a running mdomain.
                     * see issue #260 */
                    rv = APR_SUCCESS;
                }
                else if (!APR_STATUS_IS_ENOENT(rv)) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10110)
                                 "retrieving credentials for MD %s (%s)",
                                 md->name, md_pkey_spec_name(spec));
                    return rv;
                }
            }
    
            if (md_array_is_empty(key_files)) {
                if (fallback) {
                    /* Provide temporary, self-signed certificate as fallback, so that
                     * clients do not get obscure TLS handshake errors or will see a fallback
                     * virtual host that is not intended to be served here. */
                    char *kfn, *cfn;
    
                    store = md_reg_store_get(reg);
                    assert(store);
    
                    for (i = 0; i < md_cert_count(md); ++i) {
                        spec = md_pkeys_spec_get(md->pks, i);
                        fallback_fnames(p, spec, &kfn, &cfn);
    
                        md_store_get_fname(&keyfile, store, MD_SG_DOMAINS, md->name, kfn, p);
                        md_store_get_fname(&chainfile, store, MD_SG_DOMAINS, md->name, cfn, p);
                        if (!md_file_exists(keyfile, p) || !md_file_exists(chainfile, p)) {
                            if (APR_SUCCESS != (rv = make_fallback_cert(store, md, spec, s, p, kfn, cfn))) {
                                return rv;
                            }
                        }
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10116)
                                     "%s: providing %s fallback certificate for server %s",
                                     md->name, md_pkey_spec_name(spec), s->server_hostname);
                        APR_ARRAY_PUSH(key_files, const char*) = keyfile;
                        APR_ARRAY_PUSH(chain_files, const char*) = chainfile;
                    }
                    rv = APR_EAGAIN;
                    goto leave;
                }
            }
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(10077)
                     "%s[state=%d]: providing certificates for server %s",
                     md->name, md->state, s->server_hostname);
    leave:
        if (!md_array_is_empty(key_files) && !md_array_is_empty(chain_files)) {
            *pkey_files = key_files;
            *pcert_files = chain_files;
        }
        else if (APR_SUCCESS == rv) {
            rv = APR_ENOENT;
        }
        return rv;
    }
    
    static int md_add_cert_files(server_rec *s, apr_pool_t *p,
                                 apr_array_header_t *cert_files,
                                 apr_array_header_t *key_files)
    {
        apr_array_header_t *md_cert_files;
        apr_array_header_t *md_key_files;
        apr_status_t rv;
    
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "hook ssl_add_cert_files for %s",
                     s->server_hostname);
        rv = get_certificates(s, p, 0, &md_cert_files, &md_key_files);
        if (APR_SUCCESS == rv) {
            if (!apr_is_empty_array(cert_files)) {
                /* downgraded fromm WARNING to DEBUG, since installing separate certificates
                 * may be a valid use case. */
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10084)
                             "host '%s' is covered by a Managed Domain, but "
                             "certificate/key files are already configured "
                             "for it (most likely via SSLCertificateFile).",
                             s->server_hostname);
            }
            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
                         "host '%s' is covered by a Managed Domain and "
                         "is being provided with %d key/certificate files.",
                         s->server_hostname, md_cert_files->nelts);
            apr_array_cat(cert_files, md_cert_files);
            apr_array_cat(key_files, md_key_files);
            return DONE;
        }
        return DECLINED;
    }
    
    static int md_add_fallback_cert_files(server_rec *s, apr_pool_t *p,
                                          apr_array_header_t *cert_files,
                                          apr_array_header_t *key_files)
    {
        apr_array_header_t *md_cert_files;
        apr_array_header_t *md_key_files;
        apr_status_t rv;
    
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "hook ssl_add_fallback_cert_files for %s",
                     s->server_hostname);
        rv = get_certificates(s, p, 1, &md_cert_files, &md_key_files);
        if (APR_EAGAIN == rv) {
            apr_array_cat(cert_files, md_cert_files);
            apr_array_cat(key_files, md_key_files);
            return DONE;
        }
        return DECLINED;
    }
    
    static int md_get_challenge_cert(conn_rec *c, const char *servername,
                                     md_srv_conf_t *sc,
                                     md_pkey_type_t key_type,
                                     const char **pcert_pem,
                                     const char **pkey_pem)
    {
        apr_status_t rv = APR_ENOENT;
        int i;
        char *cert_name, *pkey_name;
        const char *cert_pem, *key_pem;
        md_store_t *store = md_reg_store_get(sc->mc->reg);
        md_pkey_spec_t *key_spec;
    
        for (i = 0; i < md_pkeys_spec_count(sc->pks); i++) {
            key_spec = md_pkeys_spec_get(sc->pks, i);
            if (key_spec->type != key_type)
              continue;
    
            tls_alpn01_fnames(c->pool, key_spec, &pkey_name, &cert_name);
    
            rv = md_store_load(store, MD_SG_CHALLENGES, servername, cert_name, MD_SV_TEXT,
                               (void**)&cert_pem, c->pool);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
                          "Load challenge: cert %s", cert_name);
            if (APR_STATUS_IS_ENOENT(rv)) continue;
            if (APR_SUCCESS != rv) goto cleanup;
    
            rv = md_store_load(store, MD_SG_CHALLENGES, servername, pkey_name, MD_SV_TEXT,
                               (void**)&key_pem, c->pool);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
                          "Load challenge: key %s", pkey_name);
            if (APR_STATUS_IS_ENOENT(rv)) continue;
            if (APR_SUCCESS != rv) goto cleanup;
    
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "Found challenge: cert %s, key %s for %s",
                          cert_name, pkey_name, servername);
            *pcert_pem = cert_pem;
            *pkey_pem = key_pem;
            return OK;
        }
    cleanup:
        return DECLINED;
    }
    
    static int md_answer_challenge(conn_rec *c, const char *servername,
                                   const char **pcert_pem, const char **pkey_pem)
    {
        const char *protocol;
        int hook_rv = DECLINED;
        md_srv_conf_t *sc;
    
        *pcert_pem = *pkey_pem = NULL;
    
        if (!servername
            || !(protocol = md_protocol_get(c))
            || strcmp(PROTO_ACME_TLS_1, protocol)) {
            goto cleanup;
        }
        sc = md_config_get(c->base_server);
        if (!sc || !sc->mc->reg) goto cleanup;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                      "Answer challenge[tls-alpn-01] for %s", servername);
    
        /* A challenge for TLS-ALPN-01 used to have a single certificate,
         * overriding the single fallback certificate already installed in
         * the connections SSL* instance.
         * Since the addition of `MDPrivateKeys`, there can be more than one,
         * but the server API for a challenge cert can return only one. This
         * is a short coming of the API.
         * This means we cannot override all fallback certificates present, just
         * a single one. If there is an RSA cert in fallback, we need to override
         * that, because the ACME server has a preference for that (at least LE
         * has). So we look for an RSA challenge cert first.
         * The fallback is an EC cert and that works since without RSA challenges,
         * there should also be no RSA fallbacks.
         * Bit of a mess. */
        hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_DEFAULT,
                                        pcert_pem, pkey_pem);
        if (hook_rv == DECLINED)
          hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_RSA,
                                          pcert_pem, pkey_pem);
        if (hook_rv == DECLINED)
          hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_EC,
                                          pcert_pem, pkey_pem);
    
        if (DECLINED == hook_rv) {
            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(10080)
                          "%s: unknown tls-alpn-01 challenge host", servername);
        }
    
    cleanup:
        return hook_rv;
    }
    
    
    /**************************************************************************************************/
    /* ACME 'http-01' challenge responses */
    
    #define WELL_KNOWN_PREFIX           "/.well-known/"
    #define ACME_CHALLENGE_PREFIX       WELL_KNOWN_PREFIX"acme-challenge/"
    
    static int md_http_challenge_pr(request_rec *r)
    {
        apr_bucket_brigade *bb;
        const md_srv_conf_t *sc;
        const char *name, *data;
        md_reg_t *reg;
        const md_t *md;
        apr_status_t rv;
    
        if (r->parsed_uri.path
            && !strncmp(ACME_CHALLENGE_PREFIX, r->parsed_uri.path, sizeof(ACME_CHALLENGE_PREFIX)-1)) {
            sc = ap_get_module_config(r->server->module_config, &md_module);
            if (sc && sc->mc) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "access inside /.well-known/acme-challenge for %s%s",
                              r->hostname, r->parsed_uri.path);
                md = md_get_by_domain(sc->mc->mds, r->hostname);
                name = r->parsed_uri.path + sizeof(ACME_CHALLENGE_PREFIX)-1;
                reg = sc && sc->mc? sc->mc->reg : NULL;
    
                if (md && md->ca_challenges
                    && md_array_str_index(md->ca_challenges, MD_AUTHZ_CHA_HTTP_01, 0, 1) < 0) {
                    /* The MD this challenge is for does not allow http-01 challanges,
                     * we have to decline. See #279 for a setup example where this
                     * is necessary.
                     */
                    return DECLINED;
                }
    
                if (strlen(name) && !ap_strchr_c(name, '/') && reg) {
                    md_store_t *store = md_reg_store_get(reg);
    
                    rv = md_store_load(store, MD_SG_CHALLENGES, r->hostname,
                                       MD_FN_HTTP01, MD_SV_TEXT, (void**)&data, r->pool);
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,
                                  "loading challenge for %s (%s)", r->hostname, r->uri);
                    if (APR_SUCCESS == rv) {
                        apr_size_t len = strlen(data);
    
                        if (r->method_number != M_GET) {
                            return HTTP_NOT_IMPLEMENTED;
                        }
                        /* A GET on a challenge resource for a hostname we are
                         * configured for. Let's send the content back */
                        r->status = HTTP_OK;
                        apr_table_setn(r->headers_out, "Content-Length", apr_ltoa(r->pool, (long)len));
    
                        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
                        apr_brigade_write(bb, NULL, NULL, data, len);
                        ap_pass_brigade(r->output_filters, bb);
                        apr_brigade_cleanup(bb);
    
                        return DONE;
                    }
                    else if (!md || md->renew_mode == MD_RENEW_MANUAL
                        || (md->cert_files && md->cert_files->nelts
                            && md->renew_mode == MD_RENEW_AUTO)) {
                        /* The request hostname is not for a domain - or at least not for
                         * a domain that we renew ourselves. We are not
                         * the sole authority here for /.well-known/acme-challenge (see PR62189).
                         * So, we decline to handle this and give others a chance to provide
                         * the answer.
                         */
                        return DECLINED;
                    }
                    else if (APR_STATUS_IS_ENOENT(rv)) {
                        return HTTP_NOT_FOUND;
                    }
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10081)
                                  "loading challenge %s from store", name);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
        }
        return DECLINED;
    }
    
    /**************************************************************************************************/
    /* Require Https hook */
    
    static int md_require_https_maybe(request_rec *r)
    {
        const md_srv_conf_t *sc;
        apr_uri_t uri;
        const char *s, *host;
        const md_t *md;
        int status;
    
        /* Requests outside the /.well-known path are subject to possible
         * https: redirects or HSTS header additions.
         */
        sc = ap_get_module_config(r->server->module_config, &md_module);
        if (!sc || !sc->assigned || !sc->assigned->nelts || !r->parsed_uri.path
            || !strncmp(WELL_KNOWN_PREFIX, r->parsed_uri.path, sizeof(WELL_KNOWN_PREFIX)-1)) {
            goto declined;
        }
    
        host = ap_get_server_name_for_url(r);
        md = md_get_for_domain(r->server, host);
        if (!md) goto declined;
    
        if (ap_ssl_conn_is_ssl(r->connection)) {
            /* Using https:
             * if 'permanent' and no one else set a HSTS header already, do it */
            if (md->require_https == MD_REQUIRE_PERMANENT
                && sc->mc->hsts_header && !apr_table_get(r->headers_out, MD_HSTS_HEADER)) {
                apr_table_setn(r->headers_out, MD_HSTS_HEADER, sc->mc->hsts_header);
            }
        }
        else {
            if (md->require_https > MD_REQUIRE_OFF) {
                /* Not using https:, but require it. Redirect. */
                if (r->method_number == M_GET) {
                    /* safe to use the old-fashioned codes */
                    status = ((MD_REQUIRE_PERMANENT == md->require_https)?
                              HTTP_MOVED_PERMANENTLY : HTTP_MOVED_TEMPORARILY);
                }
                else {
                    /* these should keep the method unchanged on retry */
                    status = ((MD_REQUIRE_PERMANENT == md->require_https)?
                              HTTP_PERMANENT_REDIRECT : HTTP_TEMPORARY_REDIRECT);
                }
    
                s = ap_construct_url(r->pool, r->uri, r);
                if (APR_SUCCESS == apr_uri_parse(r->pool, s, &uri)) {
                    uri.scheme = (char*)"https";
                    uri.port = 443;
                    uri.port_str = (char*)"443";
                    uri.query = r->parsed_uri.query;
                    uri.fragment = r->parsed_uri.fragment;
                    s = apr_uri_unparse(r->pool, &uri, APR_URI_UNP_OMITUSERINFO);
                    if (s && *s) {
                        apr_table_setn(r->headers_out, "Location", s);
                        return status;
                    }
                }
            }
        }
    declined:
        return DECLINED;
    }
    
    /* Runs once per created child process. Perform any process
     * related initialization here.
     */
    static void md_child_init(apr_pool_t *pool, server_rec *s)
    {
        (void)pool;
        (void)s;
    }
    
    /* Install this module into the apache2 infrastructure.
     */
    static void md_hooks(apr_pool_t *pool)
    {
        static const char *const mod_ssl[] = { "mod_ssl.c", "mod_tls.c", NULL};
        static const char *const mod_wd[] = { "mod_watchdog.c", NULL};
    
        /* Leave the ssl initialization to mod_ssl or friends. */
        md_acme_init(pool, AP_SERVER_BASEVERSION, 0);
    
        ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");
    
        /* Run once after configuration is set, before mod_ssl.
         * Run again after mod_ssl is done.
         */
        ap_hook_post_config(md_post_config_before_ssl, NULL, mod_ssl, APR_HOOK_FIRST);
        ap_hook_post_config(md_post_config_after_ssl, mod_ssl, mod_wd, APR_HOOK_LAST);
    
        /* Run once after a child process has been created.
         */
        ap_hook_child_init(md_child_init, NULL, mod_ssl, APR_HOOK_MIDDLE);
    
        /* answer challenges *very* early, before any configured authentication may strike */
        ap_hook_post_read_request(md_require_https_maybe, mod_ssl, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_read_request(md_http_challenge_pr, NULL, NULL, APR_HOOK_MIDDLE);
    
        ap_hook_protocol_propose(md_protocol_propose, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_protocol_switch(md_protocol_switch, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_protocol_get(md_protocol_get, NULL, NULL, APR_HOOK_MIDDLE);
    
        /* Status request handlers and contributors */
        ap_hook_post_read_request(md_http_cert_status, NULL, mod_ssl, APR_HOOK_MIDDLE);
        APR_OPTIONAL_HOOK(ap, status_hook, md_domains_status_hook, NULL, NULL, APR_HOOK_MIDDLE);
        APR_OPTIONAL_HOOK(ap, status_hook, md_ocsp_status_hook, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(md_status_handler, NULL, NULL, APR_HOOK_MIDDLE);
    
        ap_hook_ssl_answer_challenge(md_answer_challenge, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_ssl_add_cert_files(md_add_cert_files, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_ssl_add_fallback_cert_files(md_add_fallback_cert_files, NULL, NULL, APR_HOOK_MIDDLE);
    
    #if AP_MODULE_MAGIC_AT_LEAST(20120211, 105)
        ap_hook_ssl_ocsp_prime_hook(md_ocsp_prime_status, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_ssl_ocsp_get_resp_hook(md_ocsp_provide_status, NULL, NULL, APR_HOOK_MIDDLE);
    #else
    #error "This version of mod_md requires Apache httpd 2.4.48 or newer."
    #endif /* AP_MODULE_MAGIC_AT_LEAST() */
    }
    
    �httpd-2.4.64/modules/md/md_acme_order.c�������������������������������������������������������������0000664�0001751�0001751�00000046620�14750656217�017643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    
    #include <apr_lib.h>
    #include <apr_buckets.h>
    #include <apr_file_info.h>
    #include <apr_file_io.h>
    #include <apr_fnmatch.h>
    #include <apr_hash.h>
    #include <apr_strings.h>
    #include <apr_tables.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_http.h"
    #include "md_log.h"
    #include "md_jws.h"
    #include "md_result.h"
    #include "md_store.h"
    #include "md_util.h"
    
    #include "md_acme.h"
    #include "md_acme_authz.h"
    #include "md_acme_order.h"
    
    
    md_acme_order_t *md_acme_order_create(apr_pool_t *p)
    {
        md_acme_order_t *order;
        
        order = apr_pcalloc(p, sizeof(*order));
        order->p = p;
        order->authz_urls = apr_array_make(p, 5, sizeof(const char *));
        order->challenge_setups = apr_array_make(p, 5, sizeof(const char *));
        
        return order;
    }
    
    /**************************************************************************************************/
    /* order conversion */
    
    #define MD_KEY_CHALLENGE_SETUPS   "challenge-setups"
    
    static md_acme_order_st order_st_from_str(const char *s) 
    {
        if (s) {
            if (!strcmp("valid", s)) {
                return MD_ACME_ORDER_ST_VALID;
            }
            else if (!strcmp("invalid", s)) {
                return MD_ACME_ORDER_ST_INVALID;
            }
            else if (!strcmp("ready", s)) {
                return MD_ACME_ORDER_ST_READY;
            }
            else if (!strcmp("pending", s)) {
                return MD_ACME_ORDER_ST_PENDING;
            }
            else if (!strcmp("processing", s)) {
                return MD_ACME_ORDER_ST_PROCESSING;
            }
        }
        return MD_ACME_ORDER_ST_PENDING;
    }
    
    static const char *order_st_to_str(md_acme_order_st status) 
    {
        switch (status) {
            case MD_ACME_ORDER_ST_PENDING:
                return "pending";
            case MD_ACME_ORDER_ST_READY:
                return "ready";
            case MD_ACME_ORDER_ST_PROCESSING:
                return "processing";
            case MD_ACME_ORDER_ST_VALID:
                return "valid";
            case MD_ACME_ORDER_ST_INVALID:
                return "invalid";
            default:
                return "invalid";
        }
    }
    
    md_json_t *md_acme_order_to_json(md_acme_order_t *order, apr_pool_t *p)
    {
        md_json_t *json = md_json_create(p);
    
        if (order->url) {
            md_json_sets(order->url, json, MD_KEY_URL, NULL);
        }
        md_json_sets(order_st_to_str(order->status), json, MD_KEY_STATUS, NULL);
        md_json_setsa(order->authz_urls, json, MD_KEY_AUTHORIZATIONS, NULL);
        md_json_setsa(order->challenge_setups, json, MD_KEY_CHALLENGE_SETUPS, NULL);
        if (order->finalize) {
            md_json_sets(order->finalize, json, MD_KEY_FINALIZE, NULL);
        }
        if (order->certificate) {
            md_json_sets(order->certificate, json, MD_KEY_CERTIFICATE, NULL);
        }
        return json;
    }
    
    static void order_update_from_json(md_acme_order_t *order, md_json_t *json, apr_pool_t *p)
    {
        if (!order->url && md_json_has_key(json, MD_KEY_URL, NULL)) {
            order->url = md_json_dups(p, json, MD_KEY_URL, NULL);
        }
        order->status = order_st_from_str(md_json_gets(json, MD_KEY_STATUS, NULL));
        if (md_json_has_key(json, MD_KEY_AUTHORIZATIONS, NULL)) {
            md_json_dupsa(order->authz_urls, p, json, MD_KEY_AUTHORIZATIONS, NULL);
        }
        if (md_json_has_key(json, MD_KEY_CHALLENGE_SETUPS, NULL)) {
            md_json_dupsa(order->challenge_setups, p, json, MD_KEY_CHALLENGE_SETUPS, NULL);
        }
        if (md_json_has_key(json, MD_KEY_FINALIZE, NULL)) {
            order->finalize = md_json_dups(p, json, MD_KEY_FINALIZE, NULL);
        }
        if (md_json_has_key(json, MD_KEY_CERTIFICATE, NULL)) {
            order->certificate = md_json_dups(p, json, MD_KEY_CERTIFICATE, NULL);
        }
    }
    
    md_acme_order_t *md_acme_order_from_json(md_json_t *json, apr_pool_t *p)
    {
        md_acme_order_t *order = md_acme_order_create(p);
    
        order_update_from_json(order, json, p);
        return order;
    }
    
    apr_status_t md_acme_order_add(md_acme_order_t *order, const char *authz_url)
    {
        assert(authz_url);
        if (md_array_str_index(order->authz_urls, authz_url, 0, 1) < 0) {
            APR_ARRAY_PUSH(order->authz_urls, const char*) = apr_pstrdup(order->p, authz_url);
        }
        return APR_SUCCESS;
    }
    
    apr_status_t md_acme_order_remove(md_acme_order_t *order, const char *authz_url)
    {
        int i;
        
        assert(authz_url);
        i = md_array_str_index(order->authz_urls, authz_url, 0, 1);
        if (i >= 0) {
            order->authz_urls = md_array_str_remove(order->p, order->authz_urls, authz_url, 1);
            return APR_SUCCESS;
        }
        return APR_ENOENT;
    }
    
    static apr_status_t add_setup_token(md_acme_order_t *order, const char *token)
    {
        if (md_array_str_index(order->challenge_setups, token, 0, 1) < 0) {
            APR_ARRAY_PUSH(order->challenge_setups, const char*) = apr_pstrdup(order->p, token);
        }
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* persistence */
    
    apr_status_t md_acme_order_load(struct md_store_t *store, md_store_group_t group, 
                                        const char *md_name, md_acme_order_t **pauthz_set, 
                                        apr_pool_t *p)
    {
        apr_status_t rv;
        md_json_t *json;
        md_acme_order_t *authz_set;
        
        rv = md_store_load_json(store, group, md_name, MD_FN_ORDER, &json, p);
        if (APR_SUCCESS == rv) {
            authz_set = md_acme_order_from_json(json, p);
        }
        *pauthz_set = (APR_SUCCESS == rv)? authz_set : NULL;
        return rv;  
    }
    
    static apr_status_t p_save(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_t *store = baton;
        md_json_t *json;
        md_store_group_t group;
        md_acme_order_t *set;
        const char *md_name;
        int create;
     
        (void)p;   
        group = (md_store_group_t)va_arg(ap, int);
        md_name = va_arg(ap, const char *);
        set = va_arg(ap, md_acme_order_t *);
        create = va_arg(ap, int);
    
        json = md_acme_order_to_json(set, ptemp);
        assert(json);
        return md_store_save_json(store, ptemp, group, md_name, MD_FN_ORDER, json, create);
    }
    
    apr_status_t md_acme_order_save(struct md_store_t *store, apr_pool_t *p,
                                        md_store_group_t group, const char *md_name, 
                                        md_acme_order_t *authz_set, int create)
    {
        return md_util_pool_vdo(p_save, store, p, group, md_name, authz_set, create, NULL);
    }
    
    static apr_status_t p_purge(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_t *store = baton;
        md_acme_order_t *order;
        md_store_group_t group;
        const md_t *md;
        const char *setup_token;
        apr_table_t *env;
        int i;
    
        group = (md_store_group_t)va_arg(ap, int);
        md = va_arg(ap, const md_t *);
        env = va_arg(ap, apr_table_t *);
    
        if (APR_SUCCESS == md_acme_order_load(store, group, md->name, &order, p)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "order loaded for %s", md->name);
            for (i = 0; i < order->challenge_setups->nelts; ++i) {
                setup_token = APR_ARRAY_IDX(order->challenge_setups, i, const char*);
                if (setup_token) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                                  "order teardown setup %s", setup_token);
                    md_acme_authz_teardown(store, setup_token, md, env, p);
                }
            }
        }
        return md_store_remove(store, group, md->name, MD_FN_ORDER, ptemp, 1);
    }
    
    apr_status_t md_acme_order_purge(md_store_t *store, apr_pool_t *p, md_store_group_t group,
                                     const md_t *md, apr_table_t *env)
    {
        return md_util_pool_vdo(p_purge, store, p, group, md, env, NULL);
    }
    
    /**************************************************************************************************/
    /* ACMEv2 order requests */
    
    typedef struct {
        apr_pool_t *p;
        md_acme_order_t *order;
        md_acme_t *acme;
        const char *name;
        const char *profile;
        apr_array_header_t *domains;
        md_result_t *result;
    } order_ctx_t;
    
    #define ORDER_CTX_INIT(ctx, p, o, a, n, d, pf, r) \
        (ctx)->p = (p); (ctx)->order = (o); (ctx)->acme = (a); \
        (ctx)->name = (n); (ctx)->domains = d; (ctx)->profile = pf; (ctx)->result = r
    
    static apr_status_t identifier_to_json(void *value, md_json_t *json, apr_pool_t *p, void *baton)
    {
        md_json_t *jid;
        
        (void)baton;
        jid = md_json_create(p);
        md_json_sets("dns", jid, "type", NULL);
        md_json_sets(value, jid, "value", NULL);
        return md_json_setj(jid, json, NULL);
    }
    
    static apr_status_t on_init_order_register(md_acme_req_t *req, void *baton)
    {
        order_ctx_t *ctx = baton;
        md_json_t *jpayload;
    
        jpayload = md_json_create(req->p);
        md_json_seta(ctx->domains, identifier_to_json, NULL, jpayload, "identifiers", NULL);
        if (ctx->profile)
          md_json_sets(ctx->profile, jpayload, "profile", NULL);
    
        return md_acme_req_body_init(req, jpayload);
    } 
    
    static apr_status_t on_order_upd(md_acme_t *acme, apr_pool_t *p, const apr_table_t *hdrs, 
                                     md_json_t *body, void *baton)
    {
        order_ctx_t *ctx = baton;
        const char *location = apr_table_get(hdrs, "location");
        apr_status_t rv = APR_SUCCESS;
        
        (void)acme;
        (void)p;
        if (!ctx->order) {
            if (location) {
                ctx->order = md_acme_order_create(ctx->p);
                ctx->order->url = apr_pstrdup(ctx->p, location);
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ctx->p, "new order at %s", location);
            }
            else {
                rv = APR_EINVAL;
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, ctx->p, "new order, no location header");
                goto out;
            }
        }
        
        order_update_from_json(ctx->order, body, ctx->p);
    out:
        return rv;
    }
    
    apr_status_t md_acme_order_register(md_acme_order_t **porder, md_acme_t *acme, apr_pool_t *p, 
                                        const char *name, apr_array_header_t *domains,
                                        const char *profile)
    {
        order_ctx_t ctx;
        apr_status_t rv;
        
        assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
        ORDER_CTX_INIT(&ctx, p, NULL, acme, name, domains, profile, NULL);
        rv = md_acme_POST(acme, acme->api.v2.new_order, on_init_order_register, on_order_upd, NULL, NULL, &ctx);
        *porder = (APR_SUCCESS == rv)? ctx.order : NULL;
        return rv;
    }
    
    apr_status_t md_acme_order_update(md_acme_order_t *order, md_acme_t *acme, 
                                      md_result_t *result, apr_pool_t *p)
    {
        order_ctx_t ctx;
        apr_status_t rv;
        
        assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
        ORDER_CTX_INIT(&ctx, p, order, acme, NULL, NULL, NULL, result);
        rv = md_acme_GET(acme, order->url, NULL, on_order_upd, NULL, NULL, &ctx);
        if (APR_SUCCESS != rv && APR_SUCCESS != acme->last->status) {
            md_result_dup(result, acme->last);
        }
        return rv;
    }
    
    static apr_status_t await_ready(void *baton, int attempt)
    {
        order_ctx_t *ctx = baton;
        apr_status_t rv = APR_SUCCESS;
        
        (void)attempt;
        if (APR_SUCCESS != (rv = md_acme_order_update(ctx->order, ctx->acme,
                                                      ctx->result, ctx->p))) goto out;
        switch (ctx->order->status) {
            case MD_ACME_ORDER_ST_READY:
            case MD_ACME_ORDER_ST_PROCESSING:
            case MD_ACME_ORDER_ST_VALID:
                break;
            case MD_ACME_ORDER_ST_PENDING:
                rv = APR_EAGAIN;
                break;
            default:
                rv = APR_EINVAL;
                break;
        }
    out:    
        return rv;
    }
    
    apr_status_t md_acme_order_await_ready(md_acme_order_t *order, md_acme_t *acme, 
                                           const md_t *md, apr_interval_time_t timeout, 
                                           md_result_t *result, apr_pool_t *p)
    {
        order_ctx_t ctx;
        apr_status_t rv;
        
        assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
        ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, NULL, result);
    
        md_result_activity_setn(result, "Waiting for order to become ready");
        rv = md_util_try(await_ready, &ctx, 0, timeout, 0, 0, 1);
        md_result_log(result, MD_LOG_DEBUG);
        return rv;
    }
    
    static apr_status_t await_valid(void *baton, int attempt)
    {
        order_ctx_t *ctx = baton;
        apr_status_t rv = APR_SUCCESS;
    
        (void)attempt;
        if (APR_SUCCESS != (rv = md_acme_order_update(ctx->order, ctx->acme, 
                                                      ctx->result, ctx->p))) goto out;
        switch (ctx->order->status) {
            case MD_ACME_ORDER_ST_VALID:
                md_result_set(ctx->result, APR_EINVAL, "ACME server order status is 'valid'.");
                break;
            case MD_ACME_ORDER_ST_PROCESSING:
                rv = APR_EAGAIN;
                break;
            case MD_ACME_ORDER_ST_INVALID:
                md_result_set(ctx->result, APR_EINVAL, "ACME server order status is 'invalid'.");
                rv = APR_EINVAL;
                break;
            default:
                rv = APR_EINVAL;
                break;
        }
    out:    
        return rv;
    }
    
    apr_status_t md_acme_order_await_valid(md_acme_order_t *order, md_acme_t *acme, 
                                           const md_t *md, apr_interval_time_t timeout, 
                                           md_result_t *result, apr_pool_t *p)
    {
        order_ctx_t ctx;
        apr_status_t rv;
        
        assert(MD_ACME_VERSION_MAJOR(acme->version) > 1);
        ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, NULL, result);
    
        md_result_activity_setn(result, "Waiting for finalized order to become valid");
        rv = md_util_try(await_valid, &ctx, 0, timeout, 0, 0, 1);
        md_result_log(result, MD_LOG_DEBUG);
        return rv;
    }
    
    /**************************************************************************************************/
    /* processing */
    
    apr_status_t md_acme_order_start_challenges(md_acme_order_t *order, md_acme_t *acme, 
                                                apr_array_header_t *challenge_types,
                                                md_store_t *store, const md_t *md, 
                                                apr_table_t *env, md_result_t *result, 
                                                apr_pool_t *p)
    {
        apr_status_t rv = APR_SUCCESS;
        md_acme_authz_t *authz;
        const char *url, *setup_token;
        int i;
        
        md_result_activity_printf(result, "Starting challenges for domains");
        for (i = 0; i < order->authz_urls->nelts; ++i) {
            url = APR_ARRAY_IDX(order->authz_urls, i, const char*);
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "%s: check AUTHZ at %s", md->name, url);
            
            if (APR_SUCCESS != (rv = md_acme_authz_retrieve(acme, p, url, &authz))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "%s: check authz for %s",
                              md->name, authz->domain);
                goto leave;
            }
    
            switch (authz->state) {
                case MD_ACME_AUTHZ_S_VALID:
                    break;
                    
                case MD_ACME_AUTHZ_S_PENDING:
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
                                  "%s: authorization pending for %s",
                                  md->name, authz->domain);
                    rv = md_acme_authz_respond(authz, acme, store, challenge_types,
                                               md->pks,
                                               md->acme_tls_1_domains, md,
                                               env, p, &setup_token, result);
                    if (APR_SUCCESS != rv) {
                        goto leave;
                    }
                    add_setup_token(order, setup_token);
                    md_acme_order_save(store, p, MD_SG_STAGING, md->name, order, 0);
                    break;
                    
                case MD_ACME_AUTHZ_S_INVALID:
                    rv = APR_EINVAL;
                    if (authz->error_type) {
                        md_result_problem_set(result, rv, authz->error_type, authz->error_detail, NULL);
                        goto leave;
                    }
                    /* fall through */
                default:
                    rv = APR_EINVAL;
                    md_result_printf(result, rv, "unexpected AUTHZ state %d for domain %s", 
                                     authz->state, authz->domain);
                    md_result_log(result, MD_LOG_ERR);
                    goto leave;
            }
        }
    leave:    
        return rv;
    }
    
    static apr_status_t check_challenges(void *baton, int attempt)
    {
        order_ctx_t *ctx = baton;
        const char *url;
        md_acme_authz_t *authz;
        apr_status_t rv = APR_SUCCESS;
        int i;
        
        for (i = 0; i < ctx->order->authz_urls->nelts; ++i) {
            url = APR_ARRAY_IDX(ctx->order->authz_urls, i, const char*);
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ctx->p, "%s: check AUTHZ at %s (attempt %d)", 
                          ctx->name, url, attempt);
            
            rv = md_acme_authz_retrieve(ctx->acme, ctx->p, url, &authz);
            if (APR_SUCCESS == rv) {
                switch (authz->state) {
                    case MD_ACME_AUTHZ_S_VALID:
                        md_result_printf(ctx->result, rv, 
                                         "domain authorization for %s is valid", authz->domain);
                        break;
                    case MD_ACME_AUTHZ_S_PENDING:
                        rv = APR_EAGAIN;
                        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ctx->p, 
                                      "%s: status pending at %s", authz->domain, authz->url);
                        goto leave;
                    case MD_ACME_AUTHZ_S_INVALID:
                        rv = APR_EINVAL;
                        md_result_printf(ctx->result, rv,
                                         "domain authorization for %s failed, CA considers "
                                         "answer to challenge invalid%s.",
                                         authz->domain, authz->error_type? "" : ", no error given");
                        md_result_log(ctx->result, MD_LOG_ERR);
                        goto leave;
                    default:
                        rv = APR_EINVAL;
                        md_result_printf(ctx->result, rv, 
                                         "domain authorization for %s failed with state %d", 
                                         authz->domain, authz->state);
                        md_result_log(ctx->result, MD_LOG_ERR);
                        goto leave;
                }
            }
            else {
                md_result_printf(ctx->result, rv, "authorization retrieval failed for %s on <%s>",
                                 ctx->name, url);
            }
        }
    leave:
        return rv;
    }
    
    apr_status_t md_acme_order_monitor_authzs(md_acme_order_t *order, md_acme_t *acme, 
                                              const md_t *md, apr_interval_time_t timeout, 
                                              md_result_t *result, apr_pool_t *p)
    {
        order_ctx_t ctx;
        apr_status_t rv;
        
        ORDER_CTX_INIT(&ctx, p, order, acme, md->name, NULL, NULL, result);
        
        md_result_activity_printf(result, "Monitoring challenge status for %s", md->name);
        rv = md_util_try(check_challenges, &ctx, 0, timeout, 0, 0, 1);
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "%s: checked authorizations", md->name);
        return rv;
    }
    
    ����������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acme.h�������������������������������������������������������������������0000664�0001751�0001751�00000030613�14750656217�016450� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_acme_h
    #define mod_md_md_acme_h
    
    struct apr_array_header_t;
    struct apr_bucket_brigade;
    struct md_http_response_t;
    struct apr_hash_t;
    struct md_http_t;
    struct md_json_t;
    struct md_pkey_t;
    struct md_t;
    struct md_acme_acct_t;
    struct md_acmev2_acct_t;
    struct md_store_t;
    struct md_result_t;
    
    #define MD_PROTO_ACME               "ACME"
    
    #define MD_AUTHZ_CHA_HTTP_01        "http-01"
    #define MD_AUTHZ_CHA_SNI_01         "tls-sni-01"
    
    #define MD_ACME_VERSION_UNKNOWN    0x0
    #define MD_ACME_VERSION_1          0x010000
    #define MD_ACME_VERSION_2          0x020000
    
    #define MD_ACME_VERSION_MAJOR(i)    (((i)&0xFF0000) >> 16)
    
    typedef enum {
        MD_ACME_S_UNKNOWN,              /* MD has not been analysed yet */
        MD_ACME_S_REGISTERED,           /* MD is registered at CA, but not more */
        MD_ACME_S_TOS_ACCEPTED,         /* Terms of Service were accepted by account holder */
        MD_ACME_S_CHALLENGED,           /* MD challenge information for all domains is known */
        MD_ACME_S_VALIDATED,            /* MD domains have been validated */
        MD_ACME_S_CERTIFIED,            /* MD has valid certificate */
        MD_ACME_S_DENIED,               /* MD domains (at least one) have been denied by CA */
    } md_acme_state_t;
    
    typedef struct md_acme_t md_acme_t;
    
    typedef struct md_acme_req_t md_acme_req_t;
    /**
     * Request callback on a successful HTTP response (status 2xx).
     */
    typedef apr_status_t md_acme_req_res_cb(md_acme_t *acme, 
                                            const struct md_http_response_t *res, void *baton);
    
    /**
     * Request callback to initialize before sending. May be invoked more than once in
     * case of retries.
     */
    typedef apr_status_t md_acme_req_init_cb(md_acme_req_t *req, void *baton);
    
    /**
     * Request callback on a successful response (HTTP response code 2xx) and content
     * type matching application/.*json.
     */
    typedef apr_status_t md_acme_req_json_cb(md_acme_t *acme, apr_pool_t *p, 
                                             const apr_table_t *headers, 
                                             struct md_json_t *jbody, void *baton);
    
    /**
     * Request callback on detected errors.
     */
    typedef apr_status_t md_acme_req_err_cb(md_acme_req_t *req, 
                                            const struct md_result_t *result, void *baton);
    
    
    typedef apr_status_t md_acme_new_nonce_fn(md_acme_t *acme);
    typedef apr_status_t md_acme_req_init_fn(md_acme_req_t *req, struct md_json_t *jpayload);
    
    typedef apr_status_t md_acme_post_fn(md_acme_t *acme, 
                                         md_acme_req_init_cb *on_init,
                                         md_acme_req_json_cb *on_json,
                                         md_acme_req_res_cb *on_res,
                                         md_acme_req_err_cb *on_err,
                                         void *baton);
    
    struct md_acme_t {
        const char *url;                /* directory url of the ACME service */
        const char *sname;              /* short name for the service, not necessarily unique */
        apr_pool_t *p;
        const char *user_agent;
        const char *proxy_url;
        const char *ca_file;
        
        const char *acct_id;            /* local storage id account was loaded from or NULL */
        struct md_acme_acct_t *acct;    /* account at ACME server to use for requests */
        struct md_pkey_t *acct_key;     /* private RSA key belonging to account */
        
        int version;                    /* as detected from the server */
        union {
            struct { /* obsolete */
                const char *new_authz;
                const char *new_cert;
                const char *new_reg;
                const char *revoke_cert;
                
            } v1;
            struct {
                const char *new_account;
                const char *new_order;
                const char *key_change;
                const char *revoke_cert;
                const char *new_nonce;
                struct apr_array_header_t *profiles;
            } v2;
        } api;
        const char *ca_agreement;
        const char *acct_name;
        int eab_required;
        
        md_acme_new_nonce_fn *new_nonce_fn;
        md_acme_req_init_fn *req_init_fn;
        md_acme_post_fn *post_new_account_fn;
        
        struct md_http_t *http;
        
        const char *nonce;
        int max_retries;
        struct md_result_t *last;      /* result of last request */
    };
    
    /**
     * Global init, call once at start up.
     */
    apr_status_t md_acme_init(apr_pool_t *pool, const char *base_version, int init_ssl);
    
    /**
     * Create a new ACME server instance. If path is not NULL, will use that directory
     * for persisting information. Will load any information persisted in earlier session.
     * url needs only be specified for instances where this has never been persisted before.
     *
     * @param pacme   will hold the ACME server instance on success
     * @param p       pool to used
     * @param url     url of the server, optional if known at path
     * @param proxy_url optional url of a HTTP(S) proxy to use
     */
    apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url,
                                const char *proxy_url, const char *ca_file);
    
    /**
     * Contact the ACME server and retrieve its directory information.
     * 
     * @param acme    the ACME server to contact
     */
    apr_status_t md_acme_setup(md_acme_t *acme, struct md_result_t *result);
    
    void md_acme_report_result(md_acme_t *acme, apr_status_t rv, struct md_result_t *result);
    
    /**************************************************************************************************/
    /* account handling */
    
    /**
     * Clear any existing account data from acme instance.
     */
    void md_acme_clear_acct(md_acme_t *acme);
    
    apr_status_t md_acme_POST_new_account(md_acme_t *acme, 
                                          md_acme_req_init_cb *on_init,
                                          md_acme_req_json_cb *on_json,
                                          md_acme_req_res_cb *on_res,
                                          md_acme_req_err_cb *on_err,
                                          void *baton);
    
    /**
     * Get the local name of the account currently used by the acme instance.
     * Will be NULL if no account has been setup successfully.
     */
    const char *md_acme_acct_id_get(md_acme_t *acme);
    const char *md_acme_acct_url_get(md_acme_t *acme);
    
    /** 
     * Specify the account to use by name in local store. On success, the account
     * is the "current" one used by the acme instance.
     * @param acme the acme instance to set the account for
     * @param store the store to load accounts from
     * @param p pool for allocations
     * @param acct_id name of the account to load
     */
    apr_status_t md_acme_use_acct(md_acme_t *acme, struct md_store_t *store, 
                                  apr_pool_t *p, const char *acct_id);
    
    /**
     * Specify the account to use for a specific MD by name in local store.
     * On success, the account is the "current" one used by the acme instance.
     * @param acme the acme instance to set the account for
     * @param store the store to load accounts from
     * @param p pool for allocations
     * @param acct_id name of the account to load
     * @param md the MD the account shall be used for
     */
    apr_status_t md_acme_use_acct_for_md(md_acme_t *acme, struct md_store_t *store,
                                         apr_pool_t *p, const char *acct_id,
                                         const md_t *md);
    
    /**
     * Get the local name of the account currently used by the acme instance.
     * Will be NULL if no account has been setup successfully.
     */
    const char *md_acme_acct_id_get(md_acme_t *acme);
    
    /**
     * Agree to the given Terms-of-Service url for the current account.
     */
    apr_status_t md_acme_agree(md_acme_t *acme, apr_pool_t *p, const char *tos);
    
    /**
     * Confirm with the server that the current account agrees to the Terms-of-Service
     * given in the agreement url.
     * If the known agreement is equal to this, nothing is done.
     * If it differs, the account is re-validated in the hope that the server
     * announces the Tos URL it wants. If this is equal to the agreement specified,
     * the server is notified of this. If the server requires a ToS that the account
     * thinks it has already given, it is resend.
     *
     * If an agreement is required, different from the current one, APR_INCOMPLETE is
     * returned and the agreement url is returned in the parameter.
     */
    apr_status_t md_acme_check_agreement(md_acme_t *acme, apr_pool_t *p, 
                                         const char *agreement, const char **prequired);
    
    apr_status_t md_acme_save_acct(md_acme_t *acme, apr_pool_t *p, struct md_store_t *store);
                                   
    /**
     * Deactivate the current account at the ACME server.. 
     */
    apr_status_t md_acme_acct_deactivate(md_acme_t *acme, apr_pool_t *p);
    
    /**************************************************************************************************/
    /* request handling */
    
    struct md_acme_req_t {
        md_acme_t *acme;               /* the ACME server to talk to */
        apr_pool_t *p;                 /* pool for the request duration */
        
        const char *url;               /* url to POST the request to */
        const char *method;            /* HTTP method to use */
        struct md_json_t *prot_fields; /* JWS protected fields */
        struct md_json_t *req_json;    /* JSON to be POSTed in request body */
    
        apr_table_t *resp_hdrs;        /* HTTP response headers */
        struct md_json_t *resp_json;   /* JSON response body received */
        
        apr_status_t rv;               /* status of request */
        
        md_acme_req_init_cb *on_init;  /* callback to initialize the request before submit */
        md_acme_req_json_cb *on_json;  /* callback on successful JSON response */
        md_acme_req_res_cb *on_res;    /* callback on generic HTTP response */
        md_acme_req_err_cb *on_err;    /* callback on encountered error */
        int max_retries;               /* how often this might be retried */
        void *baton;                   /* userdata for callbacks */
        struct md_result_t *result;    /* result of this request */
    };
    
    apr_status_t md_acme_req_body_init(md_acme_req_t *req, struct md_json_t *payload);
    
    apr_status_t md_acme_GET(md_acme_t *acme, const char *url,
                             md_acme_req_init_cb *on_init,
                             md_acme_req_json_cb *on_json,
                             md_acme_req_res_cb *on_res,
                             md_acme_req_err_cb *on_err,
                             void *baton);
    /**
     * Perform a POST against the ACME url. If a on_json callback is given and
     * the HTTP response is JSON, only this callback is invoked. Otherwise, on HTTP status
     * 2xx, the on_res callback is invoked. If no on_res is given, it is considered a
     * response error, since only JSON was expected.
     * At least one callback needs to be non-NULL.
     * 
     * @param acme        the ACME server to talk to
     * @param url         the url to send the request to
     * @param on_init     callback to initialize the request data
     * @param on_json     callback on successful JSON response
     * @param on_res      callback on successful HTTP response
     * @param baton       userdata for callbacks
     */
    apr_status_t md_acme_POST(md_acme_t *acme, const char *url,
                              md_acme_req_init_cb *on_init,
                              md_acme_req_json_cb *on_json,
                              md_acme_req_res_cb *on_res,
                              md_acme_req_err_cb *on_err,
                              void *baton);
    
    /**
     * Retrieve a JSON resource from the ACME server 
     */
    apr_status_t md_acme_get_json(struct md_json_t **pjson, md_acme_t *acme, 
                                  const char *url, apr_pool_t *p);
    
    
    apr_status_t md_acme_req_body_init(md_acme_req_t *req, struct md_json_t *jpayload);
    
    apr_status_t md_acme_protos_add(struct apr_hash_t *protos, apr_pool_t *p);
    
    /**
     * Return != 0 iff the given problem identifier is an ACME error string
     * indicating something is wrong with the input values, e.g. from our
     * configuration.
     */
    int md_acme_problem_is_input_related(const char *problem);
    
    #endif /* md_acme_h */
    ���������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_status.c�������������������������������������������������������������0000664�0001751�0001751�00000102747�15017530147�017716� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_optional.h>
    #include <apr_time.h>
    #include <apr_date.h>
    #include <apr_strings.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    
    #include "mod_status.h"
    
    #include "md.h"
    #include "md_curl.h"
    #include "md_crypt.h"
    #include "md_http.h"
    #include "md_ocsp.h"
    #include "md_json.h"
    #include "md_status.h"
    #include "md_store.h"
    #include "md_store_fs.h"
    #include "md_log.h"
    #include "md_reg.h"
    #include "md_util.h"
    #include "md_version.h"
    #include "md_acme.h"
    #include "md_acme_authz.h"
    
    #include "mod_md.h"
    #include "mod_md_private.h"
    #include "mod_md_config.h"
    #include "mod_md_drive.h"
    #include "mod_md_status.h"
    
    /**************************************************************************************************/
    /* Certificate status */
    
    #define APACHE_PREFIX               "/.httpd/"
    #define MD_STATUS_RESOURCE          APACHE_PREFIX"certificate-status"
    #define HTML_STATUS(X)              (!((X)->flags & AP_STATUS_SHORT))
    
    int md_http_cert_status(request_rec *r)
    {
        int i;
        md_json_t *resp, *mdj, *cj;
        const md_srv_conf_t *sc;
        const md_t *md;
        md_pkey_spec_t *spec;
        const char *keyname;
        apr_bucket_brigade *bb;
        apr_status_t rv;
    
        if (!r->parsed_uri.path || strcmp(MD_STATUS_RESOURCE, r->parsed_uri.path))
            return DECLINED;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                      "requesting status for: %s", r->hostname);
    
        /* We are looking for information about a staged certificate */
        sc = ap_get_module_config(r->server->module_config, &md_module);
        if (!sc || !sc->mc || !sc->mc->reg || !sc->mc->certificate_status_enabled) return DECLINED;
        md = md_get_by_domain(sc->mc->mds, r->hostname);
        if (!md) return DECLINED;
    
        if (r->method_number != M_GET) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                          "md(%s): status supports only GET", md->name);
            return HTTP_NOT_IMPLEMENTED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                      "requesting status for MD: %s", md->name);
    
        rv = md_status_get_md_json(&mdj, md, sc->mc->reg, sc->mc->ocsp, r->pool);
        if (APR_SUCCESS != rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10204)
                          "loading md status for %s", md->name);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                      "status for MD: %s is %s", md->name, md_json_writep(mdj, r->pool, MD_JSON_FMT_INDENT));
    
        resp = md_json_create(r->pool);
    
        if (md_json_has_key(mdj, MD_KEY_CERT, MD_KEY_VALID, NULL)) {
             md_json_setj(md_json_getj(mdj, MD_KEY_CERT, MD_KEY_VALID, NULL), resp, MD_KEY_VALID, NULL);
         }
    
        for (i = 0; i < md_cert_count(md); ++i) {
            spec = md_pkeys_spec_get(md->pks, i);
            keyname = md_pkey_spec_name(spec);
            cj = md_json_create(r->pool);
    
            if (md_json_has_key(mdj, MD_KEY_CERT, keyname, MD_KEY_VALID, NULL)) {
                md_json_setj(md_json_getj(mdj, MD_KEY_CERT, keyname, MD_KEY_VALID, NULL),
                             cj, MD_KEY_VALID, NULL);
            }
    
            if (md_json_has_key(mdj, MD_KEY_CERT, keyname, MD_KEY_SERIAL, NULL)) {
                md_json_sets(md_json_gets(mdj, MD_KEY_CERT, keyname, MD_KEY_SERIAL, NULL),
                             cj, MD_KEY_SERIAL, NULL);
            }
            if (md_json_has_key(mdj, MD_KEY_CERT, keyname, MD_KEY_SHA256_FINGERPRINT, NULL)) {
                md_json_sets(md_json_gets(mdj, MD_KEY_CERT, keyname, MD_KEY_SHA256_FINGERPRINT, NULL),
                             cj, MD_KEY_SHA256_FINGERPRINT, NULL);
            }
            md_json_setj(cj, resp, keyname, NULL );
        }
    
        if (md_json_has_key(mdj, MD_KEY_RENEWAL, NULL)) {
               /* copy over the information we want to make public about this:
                *  - when not finished, add an empty object to indicate something is going on
                *  - when a certificate is staged, add the information from that */
               cj = md_json_getj(mdj, MD_KEY_RENEWAL, MD_KEY_CERT, NULL);
               cj = cj? cj : md_json_create(r->pool);
               md_json_setj(cj, resp, MD_KEY_RENEWAL, MD_KEY_CERT, NULL);
         }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "md[%s]: sending status", md->name);
        apr_table_set(r->headers_out, "Content-Type", "application/json");
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        md_json_writeb(resp, MD_JSON_FMT_INDENT, bb);
        ap_pass_brigade(r->output_filters, bb);
        apr_brigade_cleanup(bb);
    
        return DONE;
    }
    
    /**************************************************************************************************/
    /* Status hook */
    
    typedef struct {
        apr_pool_t *p;
        const md_mod_conf_t *mc;
        apr_bucket_brigade *bb;
        int flags;
        const char *prefix;
        const char *separator;
    } status_ctx;
    
    typedef struct status_info status_info;
    
    static void add_json_val(status_ctx *ctx, md_json_t *j);
    
    typedef void add_status_fn(status_ctx *ctx, md_json_t *mdj, const status_info *info);
    
    struct status_info {
        const char *label;
        const char *key;
        add_status_fn *fn;
    };
    
    static void si_val_status(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        const char *s = "unknown";
        apr_time_t until;
        (void)info;
        switch (md_json_getl(mdj, info->key, NULL)) {
            case MD_S_INCOMPLETE:
                s = md_json_gets(mdj, MD_KEY_STATE_DESCR, NULL);
                s = s? apr_psprintf(ctx->p, "incomplete: %s", s) : "incomplete";
                break;
            case MD_S_EXPIRED_DEPRECATED:
            case MD_S_COMPLETE:
                until = md_json_get_time(mdj, MD_KEY_CERT, MD_KEY_VALID, MD_KEY_UNTIL, NULL);
                s = (!until || until > apr_time_now())? "good" : "expired";
                break;
            case MD_S_ERROR: s = "error"; break;
            case MD_S_MISSING_INFORMATION: s = "missing information"; break;
            default: break;
        }
        if (HTML_STATUS(ctx)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, s);
        }
        else {
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s%s: %s\n",
                               ctx->prefix, info->label, s);
        }
    }
    
    static void si_val_url(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        const char *url, *s;
    
        s = url = md_json_gets(mdj, info->key, NULL);
        if (!url) return;
        s = md_get_ca_name_from_url(ctx->p, url);
        if (HTML_STATUS(ctx)) {
            apr_brigade_printf(ctx->bb, NULL, NULL, "<a href='%s'>%s</a>",
                               ap_escape_html2(ctx->p, url, 1),
                               ap_escape_html2(ctx->p, s, 1));
        }
        else {
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s%sName: %s\n",
                               ctx->prefix, info->label, s);
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s%sURL: %s\n",
                               ctx->prefix, info->label, url);
        }
    }
    
    static void print_date(status_ctx *ctx, apr_time_t timestamp, const char *title)
    {
        apr_bucket_brigade *bb = ctx->bb;
        if (timestamp > 0) {
            char ts[128];
            char ts2[128];
            apr_time_exp_t texp;
            apr_size_t len;
    
            apr_time_exp_gmt(&texp, timestamp);
            apr_strftime(ts, &len, sizeof(ts2)-1, "%Y-%m-%d", &texp);
            ts[len] = '\0';
            if (!title) {
                apr_strftime(ts2, &len, sizeof(ts)-1, "%Y-%m-%dT%H:%M:%SZ", &texp);
                ts2[len] = '\0';
                title = ts2;
            }
            if (HTML_STATUS(ctx)) {
                apr_brigade_printf(bb, NULL, NULL,
                                   "<span title='%s' style='white-space: nowrap;'>%s</span>",
                                   ap_escape_html2(bb->p, title, 1), ts);
            }
            else {
                apr_brigade_printf(bb, NULL, NULL, "%s%s: %s\n",
                                   ctx->prefix, title, ts);
            }
        }
    }
    
    static void print_time(status_ctx *ctx, const char *label, apr_time_t t)
    {
        apr_bucket_brigade *bb = ctx->bb;
        apr_time_t now;
        const char *pre, *post, *sep;
        char ts[APR_RFC822_DATE_LEN];
        char ts2[128];
        apr_time_exp_t texp;
        apr_size_t len;
        apr_interval_time_t delta;
    
        if (t == 0) {
            /* timestamp is 0, we use that for "not set" */
            return;
        }
        apr_time_exp_gmt(&texp, t);
        now = apr_time_now();
        pre = post = "";
        sep = (label && strlen(label))? " " : "";
        delta = 0;
        if (HTML_STATUS(ctx)) {
            apr_rfc822_date(ts, t);
            if (t > now) {
                delta = t - now;
                pre = "in ";
            }
            else {
                delta = now - t;
                post = " ago";
            }
            if (delta >= (4 * apr_time_from_sec(MD_SECS_PER_DAY))) {
                apr_strftime(ts2, &len, sizeof(ts2)-1, "%Y-%m-%d", &texp);
                ts2[len] = '\0';
                apr_brigade_printf(bb, NULL, NULL, "%s%s<span title='%s' "
                                   "style='white-space: nowrap;'>%s</span>",
                                   label, sep, ts, ts2);
            }
            else {
                apr_brigade_printf(bb, NULL, NULL, "%s%s<span title='%s'>%s%s%s</span>",
                                   label, sep, ts, pre, md_duration_roughly(bb->p, delta), post);
            }
        }
        else {
            delta = t - now;
            apr_brigade_printf(bb, NULL, NULL, "%s%s: %" APR_TIME_T_FMT "\n",
                               ctx->prefix, label, apr_time_sec(delta));
        }
    }
    
    static void si_val_valid_time(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        const char *sfrom, *suntil, *sep, *title;
        apr_time_t from, until;
    
        sep = NULL;
        sfrom = md_json_gets(mdj, info->key, MD_KEY_FROM, NULL);
        from = sfrom? apr_date_parse_rfc(sfrom) : 0;
        suntil = md_json_gets(mdj, info->key, MD_KEY_UNTIL, NULL);
        until = suntil?apr_date_parse_rfc(suntil) : 0;
    
        if (HTML_STATUS(ctx)) {
            if (from > apr_time_now()) {
                apr_brigade_puts(ctx->bb, NULL, NULL, "from ");
                print_date(ctx, from, sfrom);
                sep = " ";
            }
            if (until) {
                if (sep) apr_brigade_puts(ctx->bb, NULL, NULL, sep);
                apr_brigade_puts(ctx->bb, NULL, NULL, "until ");
                title = sfrom? apr_psprintf(ctx->p, "%s - %s", sfrom, suntil) : suntil;
                print_date(ctx, until, title);
            }
        }
        else {
            if (from > apr_time_now()) {
                print_date(ctx, from,
                apr_pstrcat(ctx->p, info->label, "From", NULL));
            }
            if (until) {
                print_date(ctx, until,
                apr_pstrcat(ctx->p, info->label, "Until", NULL));
            }
        }
    }
    
    static void si_add_header(status_ctx *ctx, const status_info *info)
    {
        if (HTML_STATUS(ctx)) {
            const char *html = ap_escape_html2(ctx->p, info->label, 1);
            apr_brigade_printf(ctx->bb, NULL, NULL, "<th class=\"%s\">%s</th>", html, html);
        }
    }
    
    static void si_val_cert_valid_time(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        md_json_t *jcert;
        status_info sub = *info;
    
        sub.key = MD_KEY_VALID;
        jcert = md_json_getj(mdj, info->key, NULL);
        if (jcert) si_val_valid_time(ctx, jcert, &sub);
    }
    
    static void val_url_print(status_ctx *ctx, const status_info *info,
                              const char*url, const char *proto, int i)
    {
        const char *s;
    
        if (proto && !strcmp(proto, "tailscale")) {
            s = "tailscale";
        }
        else if (url) {
            s = md_get_ca_name_from_url(ctx->p, url);
        }
        else {
            return;
        }
        if (HTML_STATUS(ctx)) {
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s<a href='%s'>%s</a>",
                               i? " " : "",
                               ap_escape_html2(ctx->p, url, 1),
                               ap_escape_html2(ctx->p, s, 1));
        }
        else if (i == 0) {
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s%sName: %s\n",
                               ctx->prefix, info->label, s);
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s%sURL: %s\n",
                               ctx->prefix, info->label, url);
        }
        else {
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s%sName%d: %s\n",
                               ctx->prefix, info->label, i, s);
            apr_brigade_printf(ctx->bb, NULL, NULL, "%s%sURL%d: %s\n",
                               ctx->prefix, info->label, i, url);
        }
    }
    
    static void si_val_ca_urls(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        md_json_t *jcert;
        const char *proto, *url;
        apr_array_header_t *urls;
        int i;
    
        jcert = md_json_getj(mdj, info->key, NULL);
        if (!jcert) {
            return;
        }
    
        proto = md_json_gets(jcert, MD_KEY_PROTO, NULL);
        url = md_json_gets(jcert, MD_KEY_URL, NULL);
        if (url) {
            /* print the effective CA url used, if set */
            val_url_print(ctx, info, url, proto, 0);
        }
        else {
            /* print the available CA urls configured */
            urls = apr_array_make(ctx->p, 3, sizeof(const char*));
            md_json_getsa(urls, jcert, MD_KEY_URLS, NULL);
            for (i = 0; i < urls->nelts; ++i) {
                url = APR_ARRAY_IDX(urls, i, const char*);
                val_url_print(ctx, info, url, proto, i);
            }
        }
    }
    
    static int count_certs(void *baton, const char *key, md_json_t *json)
    {
        int *pcount = baton;
    
        (void)json;
        if (strcmp(key, MD_KEY_VALID)) {
            *pcount += 1;
        }
        return 1;
    }
    
    static void print_job_summary(status_ctx *ctx, md_json_t *mdj, const char *key,
                                  const char *separator)
    {
        apr_bucket_brigade *bb = ctx->bb;
        char buffer[HUGE_STRING_LEN];
        apr_status_t rv;
        int finished, errors, cert_count;
        apr_time_t t;
        const char *s, *line;
    
        if (!md_json_has_key(mdj, key, NULL)) {
            return;
        }
    
        finished = md_json_getb(mdj, key, MD_KEY_FINISHED, NULL);
        errors = (int)md_json_getl(mdj, key, MD_KEY_ERRORS, NULL);
        rv = (apr_status_t)md_json_getl(mdj, key, MD_KEY_LAST, MD_KEY_STATUS, NULL);
    
        line = separator? separator : "";
    
        if (rv != APR_SUCCESS) {
            char *errstr = apr_strerror(rv, buffer, sizeof(buffer));
            s = md_json_gets(mdj, key, MD_KEY_LAST, MD_KEY_PROBLEM, NULL);
            if (HTML_STATUS(ctx)) {
                line = apr_psprintf(bb->p, "%s Error[%s]: %s", line,
                                    errstr, s? s : "");
            }
            else {
                apr_brigade_printf(bb, NULL, NULL, "%sLastStatus: %s\n", ctx->prefix, errstr);
                apr_brigade_printf(bb, NULL, NULL, "%sLastProblem: %s\n", ctx->prefix, s);
            }
        }
    
        if (!HTML_STATUS(ctx)) {
            apr_brigade_printf(bb, NULL, NULL, "%sFinished: %s\n", ctx->prefix,
                               finished ? "yes" : "no");
        }
        if (finished) {
            cert_count = 0;
            md_json_iterkey(count_certs, &cert_count, mdj, key, MD_KEY_CERT, NULL);
            if (HTML_STATUS(ctx)) {
                if (cert_count > 0) {
                    line =apr_psprintf(bb->p, "%s  finished, %d new certificate%s staged.",
                                       line, cert_count, cert_count > 1? "s" : "");
                }
                else {
                    line = apr_psprintf(bb->p, "%s  finished successfully.", line);
                }
            }
            else {
                apr_brigade_printf(bb, NULL, NULL, "%sNewStaged: %d\n", ctx->prefix, cert_count);
            }
        }
        else {
            s = md_json_gets(mdj, key, MD_KEY_LAST, MD_KEY_DETAIL, NULL);
            if (s) {
                if (HTML_STATUS(ctx)) {
                    line = apr_psprintf(bb->p, "%s %s", line, s);
                }
                else {
                    apr_brigade_printf(bb, NULL, NULL, "%sLastDetail: %s\n", ctx->prefix, s);
                }
            }
        }
    
        errors = (int)md_json_getl(mdj, MD_KEY_ERRORS, NULL);
        if (errors > 0) {
            if (HTML_STATUS(ctx)) {
                line = apr_psprintf(bb->p, "%s (%d retr%s) ", line,
                                    errors, (errors > 1)? "y" : "ies");
            }
            else {
                apr_brigade_printf(bb, NULL, NULL, "%sRetries: %d\n", ctx->prefix, errors);
            }
        }
    
        if (HTML_STATUS(ctx)) {
            apr_brigade_puts(bb, NULL, NULL, line);
        }
    
        t = md_json_get_time(mdj, key, MD_KEY_NEXT_RUN, NULL);
        if (t > apr_time_now() && !finished) {
            print_time(ctx,
                       HTML_STATUS(ctx) ? "\nNext run" : "NextRun",
                       t);
        }
        else if (line[0] != '\0') {
            if (HTML_STATUS(ctx)) {
                apr_brigade_puts(bb, NULL, NULL, "\nOngoing...");
            }
            else {
                apr_brigade_printf(bb, NULL, NULL, "%s: Ongoing\n", ctx->prefix);
            }
        }
    }
    
    static void si_val_activity(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        apr_time_t t;
        const char *prefix = ctx->prefix;
    
        (void)info;
        if (!HTML_STATUS(ctx)) {
            ctx->prefix = apr_pstrcat(ctx->p, prefix, info->label, NULL);
        }
    
        if (md_json_has_key(mdj, MD_KEY_RENEWAL, NULL)) {
            print_job_summary(ctx, mdj, MD_KEY_RENEWAL, NULL);
            return;
        }
    
        t = md_json_get_time(mdj, MD_KEY_RENEW_AT, NULL);
        if (t > apr_time_now()) {
            print_time(ctx, "Renew", t);
        }
        else if (t) {
            if (HTML_STATUS(ctx)) {
                apr_brigade_puts(ctx->bb, NULL, NULL, "Pending");
            }
            else {
                apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Pending\n");
            }
        }
        else if (MD_RENEW_MANUAL == md_json_getl(mdj, MD_KEY_RENEW_MODE, NULL)) {
            if (HTML_STATUS(ctx)) {
                apr_brigade_puts(ctx->bb, NULL, NULL, "Manual renew");
            }
            else {
                apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Manual renew\n");
            }
        }
        if (!HTML_STATUS(ctx)) {
            ctx->prefix = prefix;
        }
    }
    
    static int cert_check_iter(void *baton, const char *key, md_json_t *json)
    {
        status_ctx *ctx = baton;
        const char *fingerprint;
    
        fingerprint = md_json_gets(json, MD_KEY_SHA256_FINGERPRINT, NULL);
        if (fingerprint) {
            if (HTML_STATUS(ctx)) {
                apr_brigade_printf(ctx->bb, NULL, NULL,
                                   "<a href=\"%s%s\">%s[%s]</a><br>",
                                   ctx->mc->cert_check_url, fingerprint,
                                   ctx->mc->cert_check_name, key);
            }
            else {
                apr_brigade_printf(ctx->bb, NULL, NULL,
                                   "%sType: %s\n",
                                   ctx->prefix,
                                   key);
                apr_brigade_printf(ctx->bb, NULL, NULL,
                                   "%sName: %s\n",
                                   ctx->prefix,
                                   ctx->mc->cert_check_name);
                apr_brigade_printf(ctx->bb, NULL, NULL,
                                   "%sURL: %s%s\n",
                                   ctx->prefix,
                                   ctx->mc->cert_check_url, fingerprint);
                apr_brigade_printf(ctx->bb, NULL, NULL,
                                   "%sFingerprint: %s\n",
                                   ctx->prefix,
                                   fingerprint);
            }
        }
        return 1;
    }
    
    static void si_val_remote_check(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        (void)info;
        if (ctx->mc->cert_check_name && ctx->mc->cert_check_url) {
            const char *prefix = ctx->prefix;
            if (!HTML_STATUS(ctx)) {
                ctx->prefix = apr_pstrcat(ctx->p, prefix, info->label, NULL);
            }
            md_json_iterkey(cert_check_iter, ctx, mdj, MD_KEY_CERT, NULL);
            if (!HTML_STATUS(ctx)) {
                ctx->prefix = prefix;
            }
        }
    }
    
    static void si_val_stapling(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        (void)info;
        if (!md_json_getb(mdj, MD_KEY_STAPLING, NULL)) return;
        if (HTML_STATUS(ctx)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, "on");
        }
        else {
            apr_brigade_printf(ctx->bb, NULL, NULL, "%sStapling: on\n", ctx->prefix);
        }
    }
    
    static int json_iter_val(void *data, size_t index, md_json_t *json)
    {
        status_ctx *ctx = data;
        const char *prefix = ctx->prefix;
        if (HTML_STATUS(ctx)) {
            if (index) apr_brigade_puts(ctx->bb, NULL, NULL, ctx->separator);
        }
        else {
            ctx->prefix = apr_pstrcat(ctx->p, prefix, apr_psprintf(ctx->p, "[%" APR_SIZE_T_FMT "]", index), NULL);
        }
        add_json_val(ctx, json);
        if (!HTML_STATUS(ctx)) {
            ctx->prefix = prefix;
        }
        return 1;
    }
    
    static void add_json_val(status_ctx *ctx, md_json_t *j)
    {
        if (!j) return;
        if (md_json_is(MD_JSON_TYPE_ARRAY, j, NULL)) {
            md_json_itera(json_iter_val, ctx, j, NULL);
            return;
        }
        if (!HTML_STATUS(ctx)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, ctx->prefix);
            apr_brigade_puts(ctx->bb, NULL, NULL, ": ");
        }
        if (md_json_is(MD_JSON_TYPE_INT, j, NULL)) {
            md_json_writeb(j, MD_JSON_FMT_COMPACT, ctx->bb);
        }
        else if (md_json_is(MD_JSON_TYPE_STRING, j, NULL)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, md_json_gets(j, NULL));
        }
        else if (md_json_is(MD_JSON_TYPE_OBJECT, j, NULL)) {
            md_json_writeb(j, MD_JSON_FMT_COMPACT, ctx->bb);
        }
        else if (md_json_is(MD_JSON_TYPE_BOOL, j, NULL)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, md_json_getb(j, NULL)? "on" : "off");
        }
        if (!HTML_STATUS(ctx)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, "\n");
        }
    }
    
    static void si_val_names(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        const char *prefix = ctx->prefix;
        if (HTML_STATUS(ctx)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, "<div style=\"max-width:400px;\">");
        }
        else {
            ctx->prefix = apr_pstrcat(ctx->p, prefix, info->label, NULL);
        }
        add_json_val(ctx, md_json_getj(mdj, info->key, NULL));
        if (HTML_STATUS(ctx)) {
            apr_brigade_puts(ctx->bb, NULL, NULL, "</div>");
        }
        else {
            ctx->prefix = prefix;
        }
    }
    
    static void add_status_cell(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        if (info->fn) {
            info->fn(ctx, mdj, info);
        }
        else {
            const char *prefix = ctx->prefix;
            if (!HTML_STATUS(ctx)) {
                ctx->prefix = apr_pstrcat(ctx->p, prefix, info->label, NULL);
            }
            add_json_val(ctx, md_json_getj(mdj, info->key, NULL));
            if (!HTML_STATUS(ctx)) {
                ctx->prefix = prefix;
            }
        }
    }
    
    static const status_info status_infos[] = {
        { "Domain", MD_KEY_NAME, NULL },
        { "Names", MD_KEY_DOMAINS, si_val_names },
        { "Status", MD_KEY_STATE, si_val_status },
        { "Valid", MD_KEY_CERT, si_val_cert_valid_time },
        { "CA", MD_KEY_CA, si_val_ca_urls },
        { "Stapling", MD_KEY_STAPLING, si_val_stapling },
        { "CheckAt", MD_KEY_SHA256_FINGERPRINT, si_val_remote_check },
        { "Activity", MD_KEY_NOTIFIED, si_val_activity },
    };
    
    static int add_md_row(void *baton, apr_size_t index, md_json_t *mdj)
    {
        status_ctx *ctx = baton;
        const char *prefix = ctx->prefix;
        int i;
    
        if (HTML_STATUS(ctx)) {
            apr_brigade_printf(ctx->bb, NULL, NULL, "<tr class=\"%s\">", (index % 2)? "odd" : "even");
            for (i = 0; i < (int)(sizeof(status_infos)/sizeof(status_infos[0])); ++i) {
                apr_brigade_puts(ctx->bb, NULL, NULL, "<td>");
                add_status_cell(ctx, mdj, &status_infos[i]);
                apr_brigade_puts(ctx->bb, NULL, NULL, "</td>");
            }
            apr_brigade_puts(ctx->bb, NULL, NULL, "</tr>");
        } else {
            for (i = 0; i < (int)(sizeof(status_infos)/sizeof(status_infos[0])); ++i) {
                ctx->prefix = apr_pstrcat(ctx->p, prefix, apr_psprintf(ctx->p, "[%" APR_SIZE_T_FMT "]", index), NULL);
                add_status_cell(ctx, mdj, &status_infos[i]);
                ctx->prefix = prefix;
            }
        }
        return 1;
    }
    
    static int md_name_cmp(const void *v1, const void *v2)
    {
        return strcmp((*(const md_t**)v1)->name, (*(const md_t**)v2)->name);
    }
    
    int md_domains_status_hook(request_rec *r, int flags)
    {
        const md_srv_conf_t *sc;
        const md_mod_conf_t *mc;
        int i;
        status_ctx ctx;
        apr_array_header_t *mds;
        md_json_t *jstatus, *jstock;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "server-status for managed domains, start");
        sc = ap_get_module_config(r->server->module_config, &md_module);
        if (!sc) return DECLINED;
        mc = sc->mc;
        if (!mc || !mc->server_status_enabled) return DECLINED;
    
        ctx.p = r->pool;
        ctx.mc = mc;
        ctx.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        ctx.flags = flags;
        ctx.prefix = "ManagedCertificates";
        ctx.separator = " ";
    
        mds = apr_array_copy(r->pool, mc->mds);
        qsort(mds->elts, (size_t)mds->nelts, sizeof(md_t *), md_name_cmp);
    
        if (!HTML_STATUS(&ctx)) {
            int total = 0, complete = 0, renewing = 0, errored = 0, ready = 0;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "no-html managed domain status summary");
            if (mc->mds->nelts > 0) {
                md_status_take_stock(&jstock, mds, mc->reg, r->pool);
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "got JSON managed domain status summary");
                total = (int)md_json_getl(jstock, MD_KEY_TOTAL, NULL);
                complete = (int)md_json_getl(jstock, MD_KEY_COMPLETE, NULL);
                renewing = (int)md_json_getl(jstock, MD_KEY_RENEWING, NULL);
                errored = (int)md_json_getl(jstock, MD_KEY_ERRORED, NULL);
                ready = (int)md_json_getl(jstock, MD_KEY_READY, NULL);
            }
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sTotal: %d\n", ctx.prefix, total);
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sOK: %d\n", ctx.prefix, complete);
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sRenew: %d\n", ctx.prefix, renewing);
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sErrored: %d\n", ctx.prefix, errored);
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sReady: %d\n", ctx.prefix, ready);
        }
        if (mc->mds->nelts > 0) {
            md_status_get_json(&jstatus, mds, mc->reg, mc->ocsp, r->pool);
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "got JSON managed domain status");
            if (HTML_STATUS(&ctx)) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "html managed domain status table");
                apr_brigade_puts(ctx.bb, NULL, NULL,
                                 "<hr>\n<h3>Managed Certificates</h3>\n<table class='md_status'><thead><tr>\n");
                for (i = 0; i < (int)(sizeof(status_infos)/sizeof(status_infos[0])); ++i) {
                    si_add_header(&ctx, &status_infos[i]);
                }
                apr_brigade_puts(ctx.bb, NULL, NULL, "</tr>\n</thead><tbody>");
            }
            else {
                ctx.prefix = "ManagedDomain";
            }
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "iterating JSON managed domain status");
            md_json_itera(add_md_row, &ctx, jstatus, MD_KEY_MDS, NULL);
            if (HTML_STATUS(&ctx)) {
                apr_brigade_puts(ctx.bb, NULL, NULL, "</td></tr>\n</tbody>\n</table>\n");
            }
        }
    
        ap_pass_brigade(r->output_filters, ctx.bb);
        apr_brigade_cleanup(ctx.bb);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "server-status for managed domains, end");
    
        return OK;
    }
    
    static void si_val_ocsp_activity(status_ctx *ctx, md_json_t *mdj, const status_info *info)
    {
        apr_time_t t;
        const char *prefix = ctx->prefix;
    
        (void)info;
        if (!HTML_STATUS(ctx)) {
            ctx->prefix = apr_pstrcat(ctx->p, prefix, info->label, NULL);
        }
        t = md_json_get_time(mdj, MD_KEY_RENEW_AT, NULL);
        print_time(ctx, "Refresh", t);
        print_job_summary(ctx, mdj, MD_KEY_RENEWAL, ": ");
        if (!HTML_STATUS(ctx)) {
            ctx->prefix = prefix;
        }
    }
    
    static const status_info ocsp_status_infos[] = {
        { "Domain", MD_KEY_DOMAIN, NULL },
        { "CertificateID", MD_KEY_ID, NULL },
        { "OCSPStatus", MD_KEY_STATUS, NULL },
        { "StaplingValid", MD_KEY_VALID, si_val_valid_time },
        { "Responder", MD_KEY_URL, si_val_url },
        { "Activity", MD_KEY_NOTIFIED, si_val_ocsp_activity },
    };
    
    static int add_ocsp_row(void *baton, apr_size_t index, md_json_t *mdj)
    {
        status_ctx *ctx = baton;
        const char *prefix = ctx->prefix;
        int i;
    
        if (HTML_STATUS(ctx)) {
            apr_brigade_printf(ctx->bb, NULL, NULL, "<tr class=\"%s\">", (index % 2)? "odd" : "even");
            for (i = 0; i < (int)(sizeof(ocsp_status_infos)/sizeof(ocsp_status_infos[0])); ++i) {
                apr_brigade_puts(ctx->bb, NULL, NULL, "<td>");
                add_status_cell(ctx, mdj, &ocsp_status_infos[i]);
                apr_brigade_puts(ctx->bb, NULL, NULL, "</td>");
            }
            apr_brigade_puts(ctx->bb, NULL, NULL, "</tr>");
        } else {
            for (i = 0; i < (int)(sizeof(ocsp_status_infos)/sizeof(ocsp_status_infos[0])); ++i) {
                ctx->prefix = apr_pstrcat(ctx->p, prefix, apr_psprintf(ctx->p, "[%" APR_SIZE_T_FMT "]", index), NULL);
                add_status_cell(ctx, mdj, &ocsp_status_infos[i]);
                ctx->prefix = prefix;
            }
        }
        return 1;
    }
    
    int md_ocsp_status_hook(request_rec *r, int flags)
    {
        const md_srv_conf_t *sc;
        const md_mod_conf_t *mc;
        int i;
        status_ctx ctx;
        md_json_t *jstatus, *jstock;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "server-status for ocsp stapling, start");
        sc = ap_get_module_config(r->server->module_config, &md_module);
        if (!sc) return DECLINED;
        mc = sc->mc;
        if (!mc || !mc->server_status_enabled) return DECLINED;
    
        ctx.p = r->pool;
        ctx.mc = mc;
        ctx.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        ctx.flags = flags;
        ctx.prefix = "ManagedStaplings";
        ctx.separator = " ";
    
        if (!HTML_STATUS(&ctx)) {
            int total = 0, good = 0, revoked = 0, unknown = 0;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "no-html ocsp stapling status summary");
            if (md_ocsp_count(mc->ocsp) > 0) {
                md_ocsp_get_summary(&jstock, mc->ocsp, r->pool);
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "got JSON ocsp stapling status summary");
                total = (int)md_json_getl(jstock, MD_KEY_TOTAL, NULL);
                good = (int)md_json_getl(jstock, MD_KEY_GOOD, NULL);
                revoked = (int)md_json_getl(jstock, MD_KEY_REVOKED, NULL);
                unknown = (int)md_json_getl(jstock, MD_KEY_UNKNOWN, NULL);
            }
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sTotal: %d\n", ctx.prefix, total);
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sOK: %d\n", ctx.prefix, good);
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sRenew: %d\n", ctx.prefix, revoked);
            apr_brigade_printf(ctx.bb, NULL, NULL, "%sErrored: %d\n", ctx.prefix, unknown);
        }
        if (md_ocsp_count(mc->ocsp) > 0) {
            md_ocsp_get_status_all(&jstatus, mc->ocsp, r->pool);
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "got JSON ocsp stapling status");
            if (HTML_STATUS(&ctx)) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "html ocsp stapling status table");
                apr_brigade_puts(ctx.bb, NULL, NULL,
                                 "<hr>\n<h3>Managed Staplings</h3>\n<table class='md_ocsp_status'><thead><tr>\n");
                for (i = 0; i < (int)(sizeof(ocsp_status_infos)/sizeof(ocsp_status_infos[0])); ++i) {
                    si_add_header(&ctx, &ocsp_status_infos[i]);
                }
                apr_brigade_puts(ctx.bb, NULL, NULL, "</tr>\n</thead><tbody>");
            }
            else {
                ctx.prefix = "ManagedStapling";
            }
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "iterating JSON ocsp stapling status");
            md_json_itera(add_ocsp_row, &ctx, jstatus, MD_KEY_OCSPS, NULL);
            if (HTML_STATUS(&ctx)) {
                apr_brigade_puts(ctx.bb, NULL, NULL, "</td></tr>\n</tbody>\n</table>\n");
            }
        }
    
        ap_pass_brigade(r->output_filters, ctx.bb);
        apr_brigade_cleanup(ctx.bb);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "server-status for ocsp stapling, end");
    
        return OK;
    }
    
    /**************************************************************************************************/
    /* Status handlers */
    
    int md_status_handler(request_rec *r)
    {
        const md_srv_conf_t *sc;
        const md_mod_conf_t *mc;
        apr_array_header_t *mds;
        md_json_t *jstatus;
        apr_bucket_brigade *bb;
        const md_t *md;
        const char *name;
    
        if (strcmp(r->handler, "md-status")) {
            return DECLINED;
        }
    
        sc = ap_get_module_config(r->server->module_config, &md_module);
        if (!sc) return DECLINED;
        mc = sc->mc;
        if (!mc) return DECLINED;
    
        if (r->method_number != M_GET) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "md-status supports only GET");
            return HTTP_NOT_IMPLEMENTED;
        }
    
        jstatus = NULL;
        md = NULL;
        if (r->path_info && r->path_info[0] == '/' && r->path_info[1] != '\0') {
            name = strrchr(r->path_info, '/') + 1;
            md = md_get_by_name(mc->mds, name);
            if (!md) md = md_get_by_domain(mc->mds, name);
        }
    
        if (md) {
            md_status_get_md_json(&jstatus, md, mc->reg, mc->ocsp, r->pool);
        }
        else {
            mds = apr_array_copy(r->pool, mc->mds);
            qsort(mds->elts, (size_t)mds->nelts, sizeof(md_t *), md_name_cmp);
            md_status_get_json(&jstatus, mds, mc->reg, mc->ocsp, r->pool);
        }
    
        if (jstatus) {
            apr_table_set(r->headers_out, "Content-Type", "application/json");
            bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
            md_json_writeb(jstatus, MD_JSON_FMT_INDENT, bb);
            ap_pass_brigade(r->output_filters, bb);
            apr_brigade_cleanup(bb);
    
            return DONE;
        }
        return DECLINED;
    }
    
    �������������������������httpd-2.4.64/modules/md/md_acme_order.h�������������������������������������������������������������0000664�0001751�0001751�00000007762�14750656217�017654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright 2019 greenbytes GmbH (https://www.greenbytes.de)
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 md_acme_order_h
    #define md_acme_order_h
    
    struct md_json_t;
    struct md_result_t;
    
    typedef struct md_acme_order_t md_acme_order_t;
    
    typedef enum {
        MD_ACME_ORDER_ST_PENDING,
        MD_ACME_ORDER_ST_READY,
        MD_ACME_ORDER_ST_PROCESSING,
        MD_ACME_ORDER_ST_VALID,
        MD_ACME_ORDER_ST_INVALID,
    } md_acme_order_st;
    
    struct md_acme_order_t {
        apr_pool_t *p;
        const char *url;
        md_acme_order_st status;
        struct apr_array_header_t *authz_urls;
        struct apr_array_header_t *challenge_setups;
        struct md_json_t *json;
        const char *finalize;
        const char *certificate;
    };
    
    #define MD_FN_ORDER             "order.json"
    
    /**************************************************************************************************/
    
    md_acme_order_t *md_acme_order_create(apr_pool_t *p);
    
    apr_status_t md_acme_order_add(md_acme_order_t *order, const char *authz_url);
    apr_status_t md_acme_order_remove(md_acme_order_t *order, const char *authz_url);
    
    struct md_json_t *md_acme_order_to_json(md_acme_order_t *set, apr_pool_t *p);
    md_acme_order_t *md_acme_order_from_json(struct md_json_t *json, apr_pool_t *p);
    
    apr_status_t md_acme_order_load(struct md_store_t *store, md_store_group_t group, 
                                        const char *md_name, md_acme_order_t **pauthz_set, 
                                        apr_pool_t *p);
    apr_status_t md_acme_order_save(struct md_store_t *store, apr_pool_t *p, 
                                        md_store_group_t group, const char *md_name, 
                                        md_acme_order_t *authz_set, int create);
    
    apr_status_t md_acme_order_purge(struct md_store_t *store, apr_pool_t *p, 
                                     md_store_group_t group, const md_t *md,
                                     apr_table_t *env);
    
    apr_status_t md_acme_order_start_challenges(md_acme_order_t *order, md_acme_t *acme,
                                                apr_array_header_t *challenge_types,
                                                md_store_t *store, const md_t *md, 
                                                apr_table_t *env, struct md_result_t *result,
                                                apr_pool_t *p);
    
    apr_status_t md_acme_order_monitor_authzs(md_acme_order_t *order, md_acme_t *acme, 
                                              const md_t *md, apr_interval_time_t timeout,
                                              struct md_result_t *result, apr_pool_t *p);
    
    /* ACMEv2 only ************************************************************************************/
    
    apr_status_t md_acme_order_register(md_acme_order_t **porder, md_acme_t *acme, apr_pool_t *p, 
                                        const char *name, struct apr_array_header_t *domains,
                                        const char *profile);
    
    apr_status_t md_acme_order_update(md_acme_order_t *order, md_acme_t *acme, 
                                      struct md_result_t *result, apr_pool_t *p);
    
    apr_status_t md_acme_order_await_ready(md_acme_order_t *order, md_acme_t *acme, 
                                           const md_t *md, apr_interval_time_t timeout, 
                                           struct md_result_t *result, apr_pool_t *p);
    apr_status_t md_acme_order_await_valid(md_acme_order_t *order, md_acme_t *acme, 
                                           const md_t *md, apr_interval_time_t timeout, 
                                           struct md_result_t *result, apr_pool_t *p);
    
    #endif /* md_acme_order_h */
    ��������������httpd-2.4.64/modules/md/md_crypt.h������������������������������������������������������������������0000664�0001751�0001751�00000023624�14750656217�016710� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_crypt_h
    #define mod_md_md_crypt_h
    
    #include <apr_file_io.h>
    
    struct apr_array_header_t;
    struct md_t;
    struct md_http_response_t;
    struct md_cert_t;
    struct md_pkey_t;
    struct md_data_t;
    struct md_timeperiod_t;
    
    /**************************************************************************************************/
    /* random */
    
    apr_status_t md_rand_bytes(unsigned char *buf, apr_size_t len, apr_pool_t *p);
    
    apr_time_t md_asn1_generalized_time_get(void *ASN1_GENERALIZEDTIME);
    
    /**************************************************************************************************/
    /* digests */
    apr_status_t md_crypt_sha256_digest64(const char **pdigest64, apr_pool_t *p, 
                                          const struct md_data_t *data);
    apr_status_t md_crypt_sha256_digest_hex(const char **pdigesthex, apr_pool_t *p, 
                                            const struct md_data_t *data);
    
    /**************************************************************************************************/
    /* private keys */
    
    typedef struct md_pkey_t md_pkey_t;
    
    typedef enum {
        MD_PKEY_TYPE_DEFAULT,
        MD_PKEY_TYPE_RSA,
        MD_PKEY_TYPE_EC,
    } md_pkey_type_t;
    
    typedef struct md_pkey_rsa_params_t {
        apr_uint32_t bits;
    } md_pkey_rsa_params_t;
    
    typedef struct md_pkey_ec_params_t {
        const char *curve;
    } md_pkey_ec_params_t;
    
    typedef struct md_pkey_spec_t {
        md_pkey_type_t type;
        union {
            md_pkey_rsa_params_t rsa;
            md_pkey_ec_params_t ec;
        } params;
    } md_pkey_spec_t;
    
    typedef struct md_pkeys_spec_t {
        apr_pool_t *p;
        struct apr_array_header_t *specs;
    } md_pkeys_spec_t;
    
    apr_status_t md_crypt_init(apr_pool_t *pool);
    
    const char *md_pkey_spec_name(const md_pkey_spec_t *spec);
    
    md_pkeys_spec_t *md_pkeys_spec_make(apr_pool_t *p);
    void md_pkeys_spec_add_default(md_pkeys_spec_t *pks);
    int md_pkeys_spec_contains_rsa(md_pkeys_spec_t *pks);
    void md_pkeys_spec_add_rsa(md_pkeys_spec_t *pks, unsigned int bits);
    int md_pkeys_spec_contains_ec(md_pkeys_spec_t *pks, const char *curve);
    void md_pkeys_spec_add_ec(md_pkeys_spec_t *pks, const char *curve);
    int md_pkeys_spec_eq(md_pkeys_spec_t *pks1, md_pkeys_spec_t *pks2);
    md_pkeys_spec_t *md_pkeys_spec_clone(apr_pool_t *p, const md_pkeys_spec_t *pks);
    int md_pkeys_spec_is_empty(const md_pkeys_spec_t *pks);
    md_pkey_spec_t *md_pkeys_spec_get(const md_pkeys_spec_t *pks, int index);
    int md_pkeys_spec_count(const md_pkeys_spec_t *pks);
    void md_pkeys_spec_add(md_pkeys_spec_t *pks, md_pkey_spec_t *spec);
    
    struct md_json_t *md_pkey_spec_to_json(const md_pkey_spec_t *spec, apr_pool_t *p);
    md_pkey_spec_t *md_pkey_spec_from_json(struct md_json_t *json, apr_pool_t *p);
    struct md_json_t *md_pkeys_spec_to_json(const md_pkeys_spec_t *pks, apr_pool_t *p);
    md_pkeys_spec_t *md_pkeys_spec_from_json(struct md_json_t *json, apr_pool_t *p);
    
    
    apr_status_t md_pkey_gen(md_pkey_t **ppkey, apr_pool_t *p, md_pkey_spec_t *key_props);
    void md_pkey_free(md_pkey_t *pkey);
    
    const char *md_pkey_get_rsa_e64(md_pkey_t *pkey, apr_pool_t *p);
    const char *md_pkey_get_rsa_n64(md_pkey_t *pkey, apr_pool_t *p);
    
    apr_status_t md_pkey_fload(md_pkey_t **ppkey, apr_pool_t *p, 
                               const char *pass_phrase, apr_size_t pass_len,
                               const char *fname);
    apr_status_t md_pkey_fsave(md_pkey_t *pkey, apr_pool_t *p, 
                               const char *pass_phrase, apr_size_t pass_len, 
                               const char *fname, apr_fileperms_t perms);
    
    apr_status_t md_crypt_sign64(const char **psign64, md_pkey_t *pkey, apr_pool_t *p, 
                                 const char *d, size_t dlen);
    
    void *md_pkey_get_EVP_PKEY(struct md_pkey_t *pkey);
    
    apr_status_t md_crypt_hmac64(const char **pmac64, const struct md_data_t *hmac_key,
                                 apr_pool_t *p, const char *d, size_t dlen);
    
    /**
     * Read a private key from a http response.
     */
    apr_status_t md_pkey_read_http(md_pkey_t **ppkey, apr_pool_t *pool,
                                   const struct md_http_response_t *res);
    
    /**************************************************************************************************/
    /* X509 certificates */
    
    typedef struct md_cert_t md_cert_t;
    
    typedef enum {
        MD_CERT_UNKNOWN,
        MD_CERT_VALID,
        MD_CERT_EXPIRED
    } md_cert_state_t;
    
    /**
     * Create a holder of the certificate that will free its memory when the
     * pool is destroyed.
     */
    md_cert_t *md_cert_make(apr_pool_t *p, void *x509);
    
    /**
     * Wrap a x509 certificate into our own structure, without taking ownership
     * of its memory. The caller remains responsible.
     */
    md_cert_t *md_cert_wrap(apr_pool_t *p, void *x509);
    
    void *md_cert_get_X509(const md_cert_t *cert);
    
    apr_status_t md_cert_fload(md_cert_t **pcert, apr_pool_t *p, const char *fname);
    apr_status_t md_cert_fsave(md_cert_t *cert, apr_pool_t *p, 
                               const char *fname, apr_fileperms_t perms);
    
    /**
     * Read a x509 certificate from a http response.
     * Will return APR_ENOENT if content-type is not recognized (currently
     * only "application/pkix-cert" is supported).
     */
    apr_status_t md_cert_read_http(md_cert_t **pcert, apr_pool_t *pool, 
                                   const struct md_http_response_t *res);
    
    /**
     * Read at least one certificate from the given PEM data.
     */
    apr_status_t md_cert_read_chain(apr_array_header_t *chain, apr_pool_t *p,
                                    const char *pem, apr_size_t pem_len);
    
    /**
     * Read one or even a chain of certificates from a http response.
     * Will return APR_ENOENT if content-type is not recognized (currently
     * supports only "application/pem-certificate-chain" and "application/pkix-cert").
     * @param chain    must be non-NULL, retrieved certificates will be added.
     */
    apr_status_t md_cert_chain_read_http(struct apr_array_header_t *chain,
                                         apr_pool_t *pool, const struct md_http_response_t *res);
    
    md_cert_state_t md_cert_state_get(const md_cert_t *cert);
    int md_cert_is_valid_now(const md_cert_t *cert);
    int md_cert_has_expired(const md_cert_t *cert);
    int md_cert_covers_domain(md_cert_t *cert, const char *domain_name);
    int md_cert_covers_md(md_cert_t *cert, const struct md_t *md);
    int md_cert_must_staple(const md_cert_t *cert);
    apr_time_t md_cert_get_not_after(const md_cert_t *cert);
    apr_time_t md_cert_get_not_before(const md_cert_t *cert);
    struct md_timeperiod_t md_cert_get_valid(const md_cert_t *cert);
    
    /**
     * Return != 0 iff the hash values of the certificates are equal.
     */
    int md_certs_are_equal(const md_cert_t *a, const md_cert_t *b);
    
    const char *md_cert_get_issuer_name(const md_cert_t *cert, apr_pool_t *p);
    apr_status_t md_cert_get_issuers_uri(const char **puri, const md_cert_t *cert, apr_pool_t *p);
    apr_status_t md_cert_get_alt_names(apr_array_header_t **pnames, const md_cert_t *cert, apr_pool_t *p);
    
    apr_status_t md_cert_to_base64url(const char **ps64, const md_cert_t *cert, apr_pool_t *p);
    apr_status_t md_cert_from_base64url(md_cert_t **pcert, const char *s64, apr_pool_t *p);
    
    apr_status_t md_cert_to_sha256_digest(struct md_data_t **pdigest, const md_cert_t *cert, apr_pool_t *p);
    apr_status_t md_cert_to_sha256_fingerprint(const char **pfinger, const md_cert_t *cert, apr_pool_t *p);
    
    const char *md_cert_get_serial_number(const md_cert_t *cert, apr_pool_t *p);
    
    apr_status_t md_chain_fload(struct apr_array_header_t **pcerts, 
                                apr_pool_t *p, const char *fname);
    apr_status_t md_chain_fsave(struct apr_array_header_t *certs, 
                                apr_pool_t *p, const char *fname, apr_fileperms_t perms);
    apr_status_t md_chain_fappend(struct apr_array_header_t *certs, 
                                  apr_pool_t *p, const char *fname);
    
    apr_status_t md_cert_req_create(const char **pcsr_der_64, const char *name,
                                    apr_array_header_t *domains, int must_staple, 
                                    md_pkey_t *pkey, apr_pool_t *p);
    
    /**
     * Create a self-signed cerftificate with the given cn, key and list
     * of alternate domain names.
     */
    apr_status_t md_cert_self_sign(md_cert_t **pcert, const char *cn, 
                                   struct apr_array_header_t *domains, md_pkey_t *pkey,
                                   apr_interval_time_t valid_for, apr_pool_t *p);
       
    /**
     * Create a certificate for answering "tls-alpn-01" ACME challenges 
     * (see <https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01>).
     */
    apr_status_t md_cert_make_tls_alpn_01(md_cert_t **pcert, const char *domain, 
                                          const char *acme_id, md_pkey_t *pkey, 
                                          apr_interval_time_t valid_for, apr_pool_t *p);
    
    apr_status_t md_cert_get_ct_scts(apr_array_header_t *scts, apr_pool_t *p, const md_cert_t *cert);
    
    apr_status_t md_cert_get_ocsp_responder_url(const char **purl, apr_pool_t *p, const md_cert_t *cert);
    
    apr_status_t md_check_cert_and_pkey(struct apr_array_header_t *certs, md_pkey_t *pkey);
    
    
    /**************************************************************************************************/
    /* X509 certificate transparency */
    
    const char *md_nid_get_sname(int nid);
    const char *md_nid_get_lname(int nid);
    
    typedef struct md_sct md_sct;
    struct md_sct {
        int version;
        apr_time_t timestamp;
        struct md_data_t *logid;
        int signature_type_nid;
        struct md_data_t *signature;
    };
    
    #endif /* md_crypt_h */
    ������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_crypt.c������������������������������������������������������������������0000664�0001751�0001751�00000202612�15017530147�016665� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_buckets.h>
    #include <apr_file_io.h>
    #include <apr_strings.h>
    #include <httpd.h>
    #include <http_core.h>
    
    #include <openssl/err.h>
    #include <openssl/evp.h>
    #include <openssl/hmac.h>
    #include <openssl/pem.h>
    #include <openssl/rand.h>
    #include <openssl/rsa.h>
    #include <openssl/x509v3.h>
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    #include <openssl/core_names.h>
    #endif
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_log.h"
    #include "md_http.h"
    #include "md_time.h"
    #include "md_util.h"
    
    /* getpid for *NIX */
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* getpid for Windows */
    #if APR_HAVE_PROCESS_H
    #include <process.h>
    #endif
    
    #if !defined(OPENSSL_NO_CT) \
        && OPENSSL_VERSION_NUMBER >= 0x10100000L \
        && (!defined(LIBRESSL_VERSION_NUMBER) \
            || LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
    /* Missing from LibreSSL < 3.5.0 and only available since OpenSSL v1.1.x */
    #include <openssl/ct.h>
    #define MD_HAVE_CT 1
    #endif
    #ifndef MD_HAVE_CT
    #define MD_HAVE_CT 0
    #endif
    
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
    #define MD_OPENSSL_10x
    #endif
    
    static int initialized;
    
    struct md_pkey_t {
        apr_pool_t *pool;
        EVP_PKEY   *pkey;
    };
    
    #ifdef MD_HAVE_ARC4RANDOM
    
    static void seed_RAND(int pid)
    {
        char seed[128];
        
        (void)pid;
        arc4random_buf(seed, sizeof(seed));
        RAND_seed(seed, sizeof(seed));
    }
    
    #else /* ifdef MD_HAVE_ARC4RANDOM */
    
    static int 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;
    }
    
    static void seed_RAND(int pid)
    {   
        unsigned char stackdata[256];
        /* stolen from mod_ssl/ssl_engine_rand.c */
        int n;
        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 = pid;
        
        RAND_seed((unsigned char *)&my_seed, sizeof(my_seed));
        
        /*
         * seed in some current state of the run-time stack (128 bytes)
         */
        n = rand_choosenum(0, sizeof(stackdata)-128-1);
        RAND_seed(stackdata+n, 128);
    }
    
    #endif /*ifdef MD_HAVE_ARC4RANDOM (else part) */
    
    
    apr_status_t md_crypt_init(apr_pool_t *pool)
    {
        (void)pool;
        
        if (!initialized) {
            int pid = getpid();
            
            ERR_load_crypto_strings();
            OpenSSL_add_all_algorithms();
            
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, pool, "initializing RAND"); 
            while (!RAND_status()) {
                seed_RAND(pid);
    	}
    
            initialized = 1;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t fwrite_buffer(void *baton, apr_file_t *f, apr_pool_t *p) 
    {
        md_data_t *buf = baton;
        apr_size_t wlen;
        
        (void)p;
        return apr_file_write_full(f, buf->data, buf->len, &wlen);
    }
    
    apr_status_t md_rand_bytes(unsigned char *buf, apr_size_t len, apr_pool_t *p)
    {
        apr_status_t rv;
        
        if (len > INT_MAX) {
            return APR_ENOTIMPL;
        }
        if (APR_SUCCESS == (rv = md_crypt_init(p))) {
            RAND_bytes((unsigned char*)buf, (int)len);
        }
        return rv;
    }
    
    typedef struct {
        const char *pass_phrase;
        int pass_len;
    } passwd_ctx;
    
    static int pem_passwd(char *buf, int size, int rwflag, void *baton)
    {
        passwd_ctx *ctx = baton;
        
        (void)rwflag;
        if (ctx->pass_len > 0) {
            if (ctx->pass_len < size) {
                size = (int)ctx->pass_len;
            }
            memcpy(buf, ctx->pass_phrase, (size_t)size);
        } else {
            return 0;
        }
        return size;
    }
    
    /**************************************************************************************************/
    /* date time things */
    
    /* Get the apr time (micro seconds, since 1970) from an ASN1 time, as stored in X509
     * certificates. OpenSSL now has a utility function, but other *SSL derivatives have
     * not caughts up yet or chose to ignore. An alternative is implemented, we prefer 
     * however the *SSL to maintain such things.
     */
    static apr_time_t md_asn1_time_get(const ASN1_TIME* time)
    {
    #if OPENSSL_VERSION_NUMBER < 0x10002000L || (defined(LIBRESSL_VERSION_NUMBER) && \
                                                 LIBRESSL_VERSION_NUMBER < 0x3060000fL)
        /* courtesy: https://stackoverflow.com/questions/10975542/asn1-time-to-time-t-conversion#11263731
         * all bugs are mine */
        apr_time_exp_t t;
        apr_time_t ts;
        const char* str = (const char*) time->data;
        apr_size_t i = 0;
    
        memset(&t, 0, sizeof(t));
    
        if (time->type == V_ASN1_UTCTIME) {/* two digit year */
            t.tm_year = (str[i++] - '0') * 10;
            t.tm_year += (str[i++] - '0');
            if (t.tm_year < 70)
                t.tm_year += 100;
        } 
        else if (time->type == V_ASN1_GENERALIZEDTIME) {/* four digit year */
            t.tm_year = (str[i++] - '0') * 1000;
            t.tm_year+= (str[i++] - '0') * 100;
            t.tm_year+= (str[i++] - '0') * 10;
            t.tm_year+= (str[i++] - '0');
            t.tm_year -= 1900;
        }
        t.tm_mon  = (str[i++] - '0') * 10;
        t.tm_mon += (str[i++] - '0') - 1; /* -1 since January is 0 not 1. */
        t.tm_mday = (str[i++] - '0') * 10;
        t.tm_mday+= (str[i++] - '0');
        t.tm_hour = (str[i++] - '0') * 10;
        t.tm_hour+= (str[i++] - '0');
        t.tm_min  = (str[i++] - '0') * 10;
        t.tm_min += (str[i++] - '0');
        t.tm_sec  = (str[i++] - '0') * 10;
        t.tm_sec += (str[i++] - '0');
        
        if (APR_SUCCESS == apr_time_exp_gmt_get(&ts, &t)) {
            return ts;
        }
        return 0;
    #else 
        int secs, days;
        apr_time_t ts = apr_time_now();
        
        if (ASN1_TIME_diff(&days, &secs, NULL, time)) {
            ts += apr_time_from_sec((days * MD_SECS_PER_DAY) + secs); 
        }
        return ts;
    #endif
    }
    
    apr_time_t md_asn1_generalized_time_get(void *asn1_gtime)
    {
        return md_asn1_time_get(asn1_gtime);
    }
    
    /**************************************************************************************************/
    /* OID/NID things */
    
    static int get_nid(const char *num, const char *sname, const char *lname)
    {
        /* Funny API, an OID for a feature might be configured or
         * maybe not. In the second case, we need to add it. But adding
         * when it already is there is an error... */
        int nid = OBJ_txt2nid(num);
        if (NID_undef == nid) {
            nid = OBJ_create(num, sname, lname);
        }
        return nid;
    }
    
    #define MD_GET_NID(x)  get_nid(MD_OID_##x##_NUM, MD_OID_##x##_SNAME, MD_OID_##x##_LNAME)
    
    /**************************************************************************************************/
    /* private keys */
    
    md_pkeys_spec_t *md_pkeys_spec_make(apr_pool_t *p)
    {
        md_pkeys_spec_t *pks;
        
        pks = apr_pcalloc(p, sizeof(*pks));
        pks->p = p;
        pks->specs = apr_array_make(p, 2, sizeof(md_pkey_spec_t*));
        return pks;
    }
    
    void md_pkeys_spec_add(md_pkeys_spec_t *pks, md_pkey_spec_t *spec)
    {
        APR_ARRAY_PUSH(pks->specs, md_pkey_spec_t*) = spec;
    }
    
    void md_pkeys_spec_add_default(md_pkeys_spec_t *pks)
    {
        md_pkey_spec_t *spec;
        
        spec = apr_pcalloc(pks->p, sizeof(*spec));
        spec->type = MD_PKEY_TYPE_DEFAULT;
        md_pkeys_spec_add(pks, spec);
    }
    
    int md_pkeys_spec_contains_rsa(md_pkeys_spec_t *pks)
    {
        md_pkey_spec_t *spec;
        int i;
        for (i = 0; i < pks->specs->nelts; ++i) {
            spec = APR_ARRAY_IDX(pks->specs, i, md_pkey_spec_t*);
            if (MD_PKEY_TYPE_RSA == spec->type) return 1;   
        }
        return 0;
    }
    
    void md_pkeys_spec_add_rsa(md_pkeys_spec_t *pks, unsigned int bits)
    {
        md_pkey_spec_t *spec;
        
        spec = apr_pcalloc(pks->p, sizeof(*spec));
        spec->type = MD_PKEY_TYPE_RSA;
        spec->params.rsa.bits = bits;
        md_pkeys_spec_add(pks, spec);
    }
    
    int md_pkeys_spec_contains_ec(md_pkeys_spec_t *pks, const char *curve)
    {
        md_pkey_spec_t *spec;
        int i;
        for (i = 0; i < pks->specs->nelts; ++i) {
            spec = APR_ARRAY_IDX(pks->specs, i, md_pkey_spec_t*);
            if (MD_PKEY_TYPE_EC == spec->type 
                && !apr_strnatcasecmp(curve, spec->params.ec.curve)) return 1;   
        }
        return 0;
    }
    
    void md_pkeys_spec_add_ec(md_pkeys_spec_t *pks, const char *curve)
    {
        md_pkey_spec_t *spec;
        
        spec = apr_pcalloc(pks->p, sizeof(*spec));
        spec->type = MD_PKEY_TYPE_EC;
        spec->params.ec.curve = apr_pstrdup(pks->p, curve);
        md_pkeys_spec_add(pks, spec);
    }
    
    md_json_t *md_pkey_spec_to_json(const md_pkey_spec_t *spec, apr_pool_t *p)
    {
        md_json_t *json = md_json_create(p);
        if (json) {
            switch (spec->type) {
                case MD_PKEY_TYPE_DEFAULT:
                    md_json_sets("Default", json, MD_KEY_TYPE, NULL);
                    break;
                case MD_PKEY_TYPE_RSA:
                    md_json_sets("RSA", json, MD_KEY_TYPE, NULL);
                    if (spec->params.rsa.bits >= MD_PKEY_RSA_BITS_MIN) {
                        md_json_setl((long)spec->params.rsa.bits, json, MD_KEY_BITS, NULL);
                    }
                    break;
                case MD_PKEY_TYPE_EC:
                    md_json_sets("EC", json, MD_KEY_TYPE, NULL);
                    if (spec->params.ec.curve) {
                        md_json_sets(spec->params.ec.curve, json, MD_KEY_CURVE, NULL);
                    }
                    break;
                default:
                    md_json_sets("Unsupported", json, MD_KEY_TYPE, NULL);
                    break;
            }
        }
        return json;    
    }
    
    static apr_status_t spec_to_json(void *value, md_json_t *json, apr_pool_t *p, void *baton)
    {
        md_json_t *jspec;
        
        (void)baton;
        jspec = md_pkey_spec_to_json((md_pkey_spec_t*)value, p);
        return md_json_setj(jspec, json, NULL);
    }
    
    md_json_t *md_pkeys_spec_to_json(const md_pkeys_spec_t *pks, apr_pool_t *p)
    {
        md_json_t *j;
        
        if (pks->specs->nelts == 1) {
            return md_pkey_spec_to_json(md_pkeys_spec_get(pks, 0), p);
        }
        j = md_json_create(p);
        md_json_seta(pks->specs, spec_to_json, (void*)pks, j, "specs", NULL);
        return md_json_getj(j, "specs", NULL);
    }
    
    md_pkey_spec_t *md_pkey_spec_from_json(struct md_json_t *json, apr_pool_t *p)
    {
        md_pkey_spec_t *spec = apr_pcalloc(p, sizeof(*spec));
        const char *s;
        long l;
        
        if (spec) {
            s = md_json_gets(json, MD_KEY_TYPE, NULL);
            if (!s || !apr_strnatcasecmp("Default", s)) {
                spec->type = MD_PKEY_TYPE_DEFAULT;
            }
            else if (!apr_strnatcasecmp("RSA", s)) {
                spec->type = MD_PKEY_TYPE_RSA;
                l = md_json_getl(json, MD_KEY_BITS, NULL);
                if (l >= MD_PKEY_RSA_BITS_MIN) {
                    spec->params.rsa.bits = (unsigned int)l;
                }
                else {
                    spec->params.rsa.bits = MD_PKEY_RSA_BITS_DEF;
                }
            }
            else if (!apr_strnatcasecmp("EC", s)) {
                spec->type = MD_PKEY_TYPE_EC;
                s = md_json_gets(json, MD_KEY_CURVE, NULL);
                if (s) {
                    spec->params.ec.curve = apr_pstrdup(p, s);
                }
                else {
                    spec->params.ec.curve = NULL;
                }
            }
        }
        return spec;
    }
    
    static apr_status_t spec_from_json(void **pvalue, md_json_t *json, apr_pool_t *p, void *baton)
    {
        (void)baton;
        *pvalue = md_pkey_spec_from_json(json, p);
        return APR_SUCCESS;
    }
    
    md_pkeys_spec_t *md_pkeys_spec_from_json(struct md_json_t *json, apr_pool_t *p)
    {
        md_pkeys_spec_t *pks;
        md_pkey_spec_t *spec;
        
        pks = md_pkeys_spec_make(p);
        if (md_json_is(MD_JSON_TYPE_ARRAY, json, NULL)) {
            md_json_geta(pks->specs, spec_from_json, pks, json, NULL);
        }
        else {
            spec = md_pkey_spec_from_json(json, p);
            md_pkeys_spec_add(pks, spec);
        }
        return pks;
    }
    
    static int pkey_spec_eq(md_pkey_spec_t *s1, md_pkey_spec_t *s2)
    {
        if (s1 == s2) {
            return 1;
        }
        if (s1 && s2 && s1->type == s2->type) {
            switch (s1->type) {
                case MD_PKEY_TYPE_DEFAULT:
                    return 1;
                case MD_PKEY_TYPE_RSA:
                    if (s1->params.rsa.bits == s2->params.rsa.bits) {
                        return 1;
                    }
                    break;
                case MD_PKEY_TYPE_EC:
                    if (s1->params.ec.curve == s2->params.ec.curve) {
                        return 1;
                    }
                    else if (!s1->params.ec.curve || !s2->params.ec.curve) {
                        return 0;
                    }
                    return !strcmp(s1->params.ec.curve, s2->params.ec.curve);
            }
        }
        return 0;
    }
    
    int md_pkeys_spec_eq(md_pkeys_spec_t *pks1, md_pkeys_spec_t *pks2)
    {
        int i;
        
        if (pks1 == pks2) {
            return 1;
        }
        if (pks1 && pks2 && pks1->specs->nelts == pks2->specs->nelts) {
            for(i = 0; i < pks1->specs->nelts; ++i) {
                if (!pkey_spec_eq(APR_ARRAY_IDX(pks1->specs, i, md_pkey_spec_t *),
                                  APR_ARRAY_IDX(pks2->specs, i, md_pkey_spec_t *))) {
                    return 0;
                }
            }
            return 1;
        }
        return 0;
    }
    
    static md_pkey_spec_t *pkey_spec_clone(apr_pool_t *p, md_pkey_spec_t *spec)
    {
        md_pkey_spec_t *nspec;
        
        nspec = apr_pcalloc(p, sizeof(*nspec));
        nspec->type = spec->type;
        switch (spec->type) {
            case MD_PKEY_TYPE_DEFAULT:
                break;
            case MD_PKEY_TYPE_RSA:
                nspec->params.rsa.bits = spec->params.rsa.bits;
                break;
            case MD_PKEY_TYPE_EC:
                nspec->params.ec.curve = apr_pstrdup(p, spec->params.ec.curve);
                break;
        }
        return nspec;
    }
    
    const char *md_pkey_spec_name(const md_pkey_spec_t *spec)
    {
        if (!spec) return "rsa";
        switch (spec->type) {
            case MD_PKEY_TYPE_DEFAULT:
            case MD_PKEY_TYPE_RSA:
                return "rsa";
            case MD_PKEY_TYPE_EC:
                return spec->params.ec.curve;
        }
        return "unknown";
    }
    
    int md_pkeys_spec_is_empty(const md_pkeys_spec_t *pks)
    {
        return NULL == pks || 0 == pks->specs->nelts;
    }
    
    md_pkeys_spec_t *md_pkeys_spec_clone(apr_pool_t *p, const md_pkeys_spec_t *pks)
    {
        md_pkeys_spec_t *npks = NULL;
        md_pkey_spec_t *spec;
        int i;
        
        if (pks && pks->specs->nelts > 0) {
            npks = apr_pcalloc(p, sizeof(*npks));
            npks->specs = apr_array_make(p, pks->specs->nelts, sizeof(md_pkey_spec_t*));
            for (i = 0; i < pks->specs->nelts; ++i) {
                spec = APR_ARRAY_IDX(pks->specs, i, md_pkey_spec_t*);
                APR_ARRAY_PUSH(npks->specs, md_pkey_spec_t*) = pkey_spec_clone(p, spec);
            }
        }
        return npks;
    }
    
    int md_pkeys_spec_count(const md_pkeys_spec_t *pks)
    {
        return md_pkeys_spec_is_empty(pks)? 1 : pks->specs->nelts;
    }
    
    static md_pkey_spec_t PkeySpecDef = { MD_PKEY_TYPE_DEFAULT, {{ 0 }} };
    
    md_pkey_spec_t *md_pkeys_spec_get(const md_pkeys_spec_t *pks, int index)
    {
        if (md_pkeys_spec_is_empty(pks)) {
            return index == 0? &PkeySpecDef : NULL;
        }
        else if (pks && index >= 0 && index < pks->specs->nelts) {
            return APR_ARRAY_IDX(pks->specs, index, md_pkey_spec_t*);
        }
        return NULL;
    }
    
    static md_pkey_t *make_pkey(apr_pool_t *p) 
    {
        md_pkey_t *pkey = apr_pcalloc(p, sizeof(*pkey));
        pkey->pool = p;
        return pkey;
    }
    
    static apr_status_t pkey_cleanup(void *data)
    {
        md_pkey_t *pkey = data;
        if (pkey->pkey) {
            EVP_PKEY_free(pkey->pkey);
            pkey->pkey = NULL;
        }
        return APR_SUCCESS;
    }
    
    void md_pkey_free(md_pkey_t *pkey)
    {
        pkey_cleanup(pkey);
    }
    
    void *md_pkey_get_EVP_PKEY(struct md_pkey_t *pkey)
    {
        return pkey->pkey;
    }
    
    apr_status_t md_pkey_fload(md_pkey_t **ppkey, apr_pool_t *p, 
                               const char *key, apr_size_t key_len,
                               const char *fname)
    {
        apr_status_t rv = APR_ENOENT;
        md_pkey_t *pkey;
        BIO *bf;
        passwd_ctx ctx;
        
        pkey =  make_pkey(p);
        if (NULL != (bf = BIO_new_file(fname, "r"))) {
            ctx.pass_phrase = key;
            ctx.pass_len = (int)key_len;
            
            ERR_clear_error();
            pkey->pkey = PEM_read_bio_PrivateKey(bf, NULL, pem_passwd, &ctx);
            BIO_free(bf);
            
            if (pkey->pkey != NULL) {
                rv = APR_SUCCESS;
                apr_pool_cleanup_register(p, pkey, pkey_cleanup, apr_pool_cleanup_null);
            }
            else {
                unsigned long err = ERR_get_error();
                rv = APR_EINVAL;
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, 
                              "error loading pkey %s: %s (pass phrase was %snull)", fname,
                              ERR_error_string(err, NULL), key? "not " : ""); 
            }
        }
        *ppkey = (APR_SUCCESS == rv)? pkey : NULL;
        return rv;
    }
    
    static apr_status_t pkey_to_buffer(md_data_t *buf, md_pkey_t *pkey, apr_pool_t *p,
                                       const char *pass, apr_size_t pass_len)
    {
        BIO *bio = BIO_new(BIO_s_mem());
        const EVP_CIPHER *cipher = NULL;
        pem_password_cb *cb = NULL;
        void *cb_baton = NULL;
        apr_status_t rv = APR_SUCCESS;
        passwd_ctx ctx;
        unsigned long err;
        int i;
        
        if (!bio) {
            return APR_ENOMEM;
        }
        if (pass_len > INT_MAX) {
            rv = APR_EINVAL;
            goto cleanup;
        }
        if (pass && pass_len > 0) {
            ctx.pass_phrase = pass;
            ctx.pass_len = (int)pass_len;
            cb = pem_passwd;
            cb_baton = &ctx;
            cipher = EVP_aes_256_cbc();
            if (!cipher) {
                rv = APR_ENOTIMPL;
                goto cleanup;
            }
        }
        
        ERR_clear_error();
    #if 1
        if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey->pkey, cipher, NULL, 0, cb, cb_baton)) {
    #else 
        if (!PEM_write_bio_PrivateKey(bio, pkey->pkey, cipher, NULL, 0, cb, cb_baton)) {
    #endif
            err = ERR_get_error();
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "PEM_write key: %ld %s", 
                          err, ERR_error_string(err, NULL)); 
            rv = APR_EINVAL;
            goto cleanup;
        }
    
        md_data_null(buf);
        i = BIO_pending(bio);
        if (i > 0) {
            buf->data = apr_palloc(p, (apr_size_t)i);
            i = BIO_read(bio, (char*)buf->data, i);
            buf->len = (apr_size_t)i;
        }
    
    cleanup:
        BIO_free(bio);
        return rv;
    }
    
    apr_status_t md_pkey_fsave(md_pkey_t *pkey, apr_pool_t *p, 
                               const char *pass_phrase, apr_size_t pass_len,
                               const char *fname, apr_fileperms_t perms)
    {
        md_data_t buffer;
        apr_status_t rv;
        
        if (APR_SUCCESS == (rv = pkey_to_buffer(&buffer, pkey, p, pass_phrase, pass_len))) {
            return md_util_freplace(fname, perms, p, fwrite_buffer, &buffer); 
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "save pkey %s (%s pass phrase, len=%d)",
                      fname, pass_len > 0? "with" : "without", (int)pass_len); 
        return rv;
    }
    
    apr_status_t md_pkey_read_http(md_pkey_t **ppkey, apr_pool_t *pool,
                                   const struct md_http_response_t *res)
    {
        apr_status_t rv;
        apr_off_t data_len;
        char *pem_data;
        apr_size_t pem_len;
        md_pkey_t *pkey;
        BIO *bf;
        passwd_ctx ctx;
    
        rv = apr_brigade_length(res->body, 1, &data_len);
        if (APR_SUCCESS != rv) goto leave;
        if (data_len > 1024*1024) { /* certs usually are <2k each */
            rv = APR_EINVAL;
            goto leave;
        }
        rv = apr_brigade_pflatten(res->body, &pem_data, &pem_len, res->req->pool);
        if (APR_SUCCESS != rv) goto leave;
    
        if (NULL == (bf = BIO_new_mem_buf(pem_data, (int)pem_len))) {
            rv = APR_ENOMEM;
            goto leave;
        }
        pkey = make_pkey(pool);
        ctx.pass_phrase = NULL;
        ctx.pass_len = 0;
        ERR_clear_error();
        pkey->pkey = PEM_read_bio_PrivateKey(bf, NULL, NULL, &ctx);
        BIO_free(bf);
    
        if (pkey->pkey == NULL) {
            unsigned long err = ERR_get_error();
            rv = APR_EINVAL;
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, pool,
                          "error loading pkey from http response: %s",
                          ERR_error_string(err, NULL));
            goto leave;
        }
        rv = APR_SUCCESS;
        apr_pool_cleanup_register(pool, pkey, pkey_cleanup, apr_pool_cleanup_null);
    
    leave:
        *ppkey = (APR_SUCCESS == rv)? pkey : NULL;
        return rv;
    }
    
    /* Determine the message digest used for signing with the given private key. 
     */
    static const EVP_MD *pkey_get_MD(md_pkey_t *pkey)
    {
        switch (EVP_PKEY_id(pkey->pkey)) {
    #ifdef NID_ED25519
        case NID_ED25519:
            return NULL;
    #endif
    #ifdef NID_ED448
        case NID_ED448:
            return NULL;
    #endif
        default:
            return EVP_sha256();
        }
    }
    
    static apr_status_t gen_rsa(md_pkey_t **ppkey, apr_pool_t *p, unsigned int bits)
    {
        EVP_PKEY_CTX *ctx = NULL;
        apr_status_t rv;
        
        *ppkey = make_pkey(p);
        ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
        if (ctx 
            && EVP_PKEY_keygen_init(ctx) >= 0
            && EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, (int)bits) >= 0
            && EVP_PKEY_keygen(ctx, &(*ppkey)->pkey) >= 0) {
            rv = APR_SUCCESS;
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, "error generate pkey RSA %d", bits); 
            *ppkey = NULL;
            rv = APR_EGENERAL;
        }
        
        if (ctx != NULL) {
            EVP_PKEY_CTX_free(ctx);
        }
        return rv;
    }
    
    static apr_status_t check_EC_curve(int nid, apr_pool_t *p) {
        EC_builtin_curve *curves = NULL;
        size_t nc, i;
        int rv = APR_ENOENT;
        
        nc = EC_get_builtin_curves(NULL, 0);
    #ifdef MD_OPENSSL_10x
        if (NULL == (curves = OPENSSL_malloc((int)(sizeof(*curves) * nc))) ||
    #else
        if (NULL == (curves = OPENSSL_malloc(sizeof(*curves) * nc)) ||
    #endif
            nc != EC_get_builtin_curves(curves, nc)) {
            rv = APR_EGENERAL;
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, 
                          "error looking up OpenSSL builtin EC curves"); 
            goto leave;
        }
        for (i = 0; i < nc; ++i) {
            if (nid == curves[i].nid) {
                rv = APR_SUCCESS;
                break;
            }
        }
    leave:
        OPENSSL_free(curves);
        return rv;
    }
    
    static apr_status_t gen_ec(md_pkey_t **ppkey, apr_pool_t *p, const char *curve)
    {
        EVP_PKEY_CTX *ctx = NULL;
        apr_status_t rv;
        int curve_nid = NID_undef;
    
        /* 1. Convert the cure into its registered identifier. Curves can be known under
         *    different names.
         * 2. Determine, if the curve is supported by OpenSSL (or whatever is linked).
         * 3. Generate the key, respecting the specific quirks some curves require.
         */
        curve_nid = EC_curve_nist2nid(curve);
        /* In case this fails, try some names from other standards, like SECG */
    #ifdef NID_secp384r1
        if (NID_undef == curve_nid && !apr_strnatcasecmp("secp384r1", curve)) {
            curve_nid = NID_secp384r1;
            curve = EC_curve_nid2nist(curve_nid);
        }
    #endif
    #ifdef NID_X9_62_prime256v1
        if (NID_undef == curve_nid && !apr_strnatcasecmp("secp256r1", curve)) {
            curve_nid = NID_X9_62_prime256v1;
            curve = EC_curve_nid2nist(curve_nid);
        }
    #endif
    #ifdef NID_X9_62_prime192v1
        if (NID_undef == curve_nid && !apr_strnatcasecmp("secp192r1", curve)) {
            curve_nid = NID_X9_62_prime192v1;
            curve = EC_curve_nid2nist(curve_nid);
        }
    #endif
    #if defined(NID_X25519) && (!defined(LIBRESSL_VERSION_NUMBER) || \
                                LIBRESSL_VERSION_NUMBER >= 0x3070000fL)
        if (NID_undef == curve_nid && !apr_strnatcasecmp("X25519", curve)) {
            curve_nid = NID_X25519;
            curve = EC_curve_nid2nist(curve_nid);
        }
    #endif
        if (NID_undef == curve_nid) {
            /* OpenSSL object/curve names */
            curve_nid = OBJ_sn2nid(curve);
        }
        if (NID_undef == curve_nid) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "ec curve unknown: %s", curve); 
            rv = APR_ENOTIMPL; goto leave;
        }
    
        *ppkey = make_pkey(p);
        switch (curve_nid) {
    
    #if defined(NID_X25519) && (!defined(LIBRESSL_VERSION_NUMBER) || \
                                LIBRESSL_VERSION_NUMBER >= 0x3070000fL)
        case NID_X25519:
            /* no parameters */
            if (NULL == (ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL))
                || EVP_PKEY_keygen_init(ctx) <= 0
                || EVP_PKEY_keygen(ctx, &(*ppkey)->pkey) <= 0) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, 
                              "error generate EC key for group: %s", curve); 
                rv = APR_EGENERAL; goto leave;
            }
            rv = APR_SUCCESS;
            break;
    #endif
    
    #if defined(NID_X448) && !defined(LIBRESSL_VERSION_NUMBER)
        case NID_X448:
            /* no parameters */
            if (NULL == (ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X448, NULL))
                || EVP_PKEY_keygen_init(ctx) <= 0
                || EVP_PKEY_keygen(ctx, &(*ppkey)->pkey) <= 0) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, 
                              "error generate EC key for group: %s", curve); 
                rv = APR_EGENERAL; goto leave;
            }
            rv = APR_SUCCESS;
            break;
    #endif
    
        default:
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
            if (APR_SUCCESS != (rv = check_EC_curve(curve_nid, p))) goto leave;
            if (NULL == (ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))
                || EVP_PKEY_paramgen_init(ctx) <= 0 
                || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve_nid) <= 0
                || EVP_PKEY_CTX_set_ec_param_enc(ctx, OPENSSL_EC_NAMED_CURVE) <= 0 
                || EVP_PKEY_keygen_init(ctx) <= 0
                || EVP_PKEY_keygen(ctx, &(*ppkey)->pkey) <= 0) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, 
                              "error generate EC key for group: %s", curve); 
                rv = APR_EGENERAL; goto leave;
            }
    #else
            if (APR_SUCCESS != (rv = check_EC_curve(curve_nid, p))) goto leave;
            if (NULL == (ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))
                || EVP_PKEY_keygen_init(ctx) <= 0
                || EVP_PKEY_CTX_ctrl_str(ctx, "ec_paramgen_curve", curve) <= 0
                || EVP_PKEY_keygen(ctx, &(*ppkey)->pkey) <= 0) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p,
                              "error generate EC key for group: %s", curve);
                rv = APR_EGENERAL; goto leave;
            }
    #endif
            rv = APR_SUCCESS;
            break;
        }
        
    leave:
        if (APR_SUCCESS != rv) *ppkey = NULL;
        EVP_PKEY_CTX_free(ctx);
        return rv;
    }
    
    apr_status_t md_pkey_gen(md_pkey_t **ppkey, apr_pool_t *p, md_pkey_spec_t *spec)
    {
        md_pkey_type_t ptype = spec? spec->type : MD_PKEY_TYPE_DEFAULT;
        switch (ptype) {
            case MD_PKEY_TYPE_DEFAULT:
                return gen_rsa(ppkey, p, MD_PKEY_RSA_BITS_DEF);
            case MD_PKEY_TYPE_RSA:
                return gen_rsa(ppkey, p, spec->params.rsa.bits);
            case MD_PKEY_TYPE_EC:
                return gen_ec(ppkey, p, spec->params.ec.curve);
            default:
                return APR_ENOTIMPL;
        }
    }
    
    #if OPENSSL_VERSION_NUMBER < 0x10100000L \
        || (defined(LIBRESSL_VERSION_NUMBER) \
            && LIBRESSL_VERSION_NUMBER < 0x2070000f)
    
    static void RSA_get0_key(const RSA *r,
                             const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
    {
        if (n != NULL)
            *n = r->n;
        if (e != NULL)
            *e = r->e;
        if (d != NULL)
            *d = r->d;
    }
    
    #endif
    
    static const char *bn64(const BIGNUM *b, apr_pool_t *p) 
    {
        if (b) {
            md_data_t buffer;
    
            md_data_pinit(&buffer, (apr_size_t)BN_num_bytes(b), p);
            if (buffer.data) {
                BN_bn2bin(b, (unsigned char *)buffer.data);
                return md_util_base64url_encode(&buffer, p);
            }
        }
        return NULL;
    }
    
    const char *md_pkey_get_rsa_e64(md_pkey_t *pkey, apr_pool_t *p)
    {
        const char *e64 = NULL;
    
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
    
    #if OPENSSL_VERSION_NUMBER < 0x10101000L
        RSA *rsa = EVP_PKEY_get1_RSA(pkey->pkey);
    #else
        const RSA *rsa = EVP_PKEY_get0_RSA(pkey->pkey);
    #endif
        if (rsa) {
            const BIGNUM *e;
            RSA_get0_key(rsa, NULL, &e, NULL);
            e64 = bn64(e, p);
    #if OPENSSL_VERSION_NUMBER < 0x10101000L
            RSA_free(rsa);
    #endif
        }
    
    #else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
        BIGNUM *e = NULL;
        if (EVP_PKEY_get_bn_param(pkey->pkey, OSSL_PKEY_PARAM_RSA_E, &e)) {
            e64 = bn64(e, p);
            BN_free(e);
        }
    #endif
    
        return e64;
    }
    
    const char *md_pkey_get_rsa_n64(md_pkey_t *pkey, apr_pool_t *p)
    {
        const char *n64 = NULL;
    
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
    
    #if OPENSSL_VERSION_NUMBER < 0x10101000L
        RSA *rsa = EVP_PKEY_get1_RSA(pkey->pkey);
    #else
        const RSA *rsa = EVP_PKEY_get0_RSA(pkey->pkey);
    #endif
        if (rsa) {
            const BIGNUM *n;
            RSA_get0_key(rsa, &n, NULL, NULL);
            n64 = bn64(n, p);
    #if OPENSSL_VERSION_NUMBER < 0x10101000L
            RSA_free(rsa);
    #endif
        }
    
    #else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
        BIGNUM *n = NULL;
        if (EVP_PKEY_get_bn_param(pkey->pkey, OSSL_PKEY_PARAM_RSA_N, &n)) {
            n64 = bn64(n, p);
            BN_free(n);
        }
    #endif
    
        return n64;
    }
    
    apr_status_t md_crypt_sign64(const char **psign64, md_pkey_t *pkey, apr_pool_t *p, 
                                 const char *d, size_t dlen)
    {
        EVP_MD_CTX *ctx = NULL;
        md_data_t buffer;
        unsigned int blen;
        const char *sign64 = NULL;
        apr_status_t rv = APR_ENOMEM;
    
        md_data_pinit(&buffer, (apr_size_t)EVP_PKEY_size(pkey->pkey), p);
        if (buffer.data) {
            ctx = EVP_MD_CTX_create();
            if (ctx) {
                rv = APR_ENOTIMPL;
                if (EVP_SignInit_ex(ctx, EVP_sha256(), NULL)) {
                    rv = APR_EGENERAL;
                    if (EVP_SignUpdate(ctx, d, dlen)) {
                        if (EVP_SignFinal(ctx, (unsigned char*)buffer.data, &blen, pkey->pkey)) {
                            buffer.len = blen;
                            sign64 = md_util_base64url_encode(&buffer, p);
                            if (sign64) {
                                rv = APR_SUCCESS;
                            }
                        }
                    }
                }
            }
            
            if (ctx) {
                EVP_MD_CTX_destroy(ctx);
            }
        }
        
        if (rv != APR_SUCCESS) {
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, "signing"); 
        }
        
        *psign64 = sign64;
        return rv;
    }
    
    static apr_status_t sha256_digest(md_data_t **pdigest, apr_pool_t *p, const md_data_t *buf)
    {
        EVP_MD_CTX *ctx = NULL;
        md_data_t *digest;
        apr_status_t rv = APR_ENOMEM;
        unsigned int dlen;
    
        digest = md_data_pmake(EVP_MAX_MD_SIZE, p);
        ctx = EVP_MD_CTX_create();
        if (ctx) {
            rv = APR_ENOTIMPL;
            if (EVP_DigestInit_ex(ctx, EVP_sha256(), NULL)) {
                rv = APR_EGENERAL;
                if (EVP_DigestUpdate(ctx, (unsigned char*)buf->data, buf->len)) {
                    if (EVP_DigestFinal(ctx, (unsigned char*)digest->data, &dlen)) {
                        digest->len = dlen;
                        rv = APR_SUCCESS;
                    }
                }
            }
        }
        if (ctx) {
            EVP_MD_CTX_destroy(ctx);
        }
        *pdigest = (APR_SUCCESS == rv)? digest : NULL;
        return rv;
    }
    
    apr_status_t md_crypt_sha256_digest64(const char **pdigest64, apr_pool_t *p, const md_data_t *d)
    {
        const char *digest64 = NULL;
        md_data_t *digest;
        apr_status_t rv;
        
        if (APR_SUCCESS == (rv = sha256_digest(&digest, p, d))) {
            if (NULL == (digest64 = md_util_base64url_encode(digest, p))) {
                rv = APR_EGENERAL;
            }
        }
        *pdigest64 = digest64;
        return rv;
    }
    
    apr_status_t md_crypt_sha256_digest_hex(const char **pdigesthex, apr_pool_t *p, 
                                            const md_data_t *data)
    {
        md_data_t *digest;
        apr_status_t rv;
        
        if (APR_SUCCESS == (rv = sha256_digest(&digest, p, data))) {
            return md_data_to_hex(pdigesthex, 0, p, digest);
        }
        *pdigesthex = NULL;
        return rv;
    }
    
    apr_status_t md_crypt_hmac64(const char **pmac64, const md_data_t *hmac_key,
                                 apr_pool_t *p, const char *d, size_t dlen)
    {
        const char *mac64 = NULL;
        unsigned char *s;
        unsigned int digest_len = 0;
        md_data_t *digest;
        apr_status_t rv = APR_SUCCESS;
    
        digest = md_data_pmake(EVP_MAX_MD_SIZE, p);
        s = HMAC(EVP_sha256(), (const unsigned char*)hmac_key->data, (int)hmac_key->len,
                 (const unsigned char*)d, (size_t)dlen,
                 (unsigned char*)digest->data, &digest_len);
        if (!s) {
            rv = APR_EINVAL;
            goto cleanup;
        }
        digest->len = digest_len;
        mac64 = md_util_base64url_encode(digest, p);
    
    cleanup:
        *pmac64 = (APR_SUCCESS == rv)? mac64 : NULL;
        return rv;
    }
    
    /**************************************************************************************************/
    /* certificates */
    
    struct md_cert_t {
        apr_pool_t *pool;
        X509 *x509;
        apr_array_header_t *alt_names;
    };
    
    static apr_status_t cert_cleanup(void *data)
    {
        md_cert_t *cert = data;
        if (cert->x509) {
            X509_free(cert->x509);
            cert->x509 = NULL;
        }
        return APR_SUCCESS;
    }
    
    md_cert_t *md_cert_wrap(apr_pool_t *p, void *x509) 
    {
        md_cert_t *cert = apr_pcalloc(p, sizeof(*cert));
        cert->pool = p;
        cert->x509 = x509;
        return cert;
    }
    
    md_cert_t *md_cert_make(apr_pool_t *p, void *x509) 
    {
        md_cert_t *cert = md_cert_wrap(p, x509);
        apr_pool_cleanup_register(p, cert, cert_cleanup, apr_pool_cleanup_null);
        return cert;
    }
    
    void *md_cert_get_X509(const md_cert_t *cert)
    {
        return cert->x509;
    }
    
    const char *md_cert_get_serial_number(const md_cert_t *cert, apr_pool_t *p)
    {
        const char *s = "";
        BIGNUM *bn; 
        const char *serial;
        const ASN1_INTEGER *ai = X509_get_serialNumber(cert->x509);
        if (ai) {
            bn = ASN1_INTEGER_to_BN(ai, NULL);
            serial = BN_bn2hex(bn);
            s = apr_pstrdup(p, serial);
            OPENSSL_free((void*)serial);
            OPENSSL_free((void*)bn);
        }
        return s;
    }
    
    int md_certs_are_equal(const md_cert_t *a, const md_cert_t *b)
    {
        return X509_cmp(a->x509, b->x509) == 0;
    }
    
    int md_cert_is_valid_now(const md_cert_t *cert)
    {
        return ((X509_cmp_current_time(X509_get_notBefore(cert->x509)) < 0)
                && (X509_cmp_current_time(X509_get_notAfter(cert->x509)) > 0));
    }
    
    int md_cert_has_expired(const md_cert_t *cert)
    {
        return (X509_cmp_current_time(X509_get_notAfter(cert->x509)) <= 0);
    }
    
    apr_time_t md_cert_get_not_after(const md_cert_t *cert)
    {
        return md_asn1_time_get(X509_get_notAfter(cert->x509));
    }
    
    apr_time_t md_cert_get_not_before(const md_cert_t *cert)
    {
        return md_asn1_time_get(X509_get_notBefore(cert->x509));
    }
    
    md_timeperiod_t md_cert_get_valid(const md_cert_t *cert)
    {
        md_timeperiod_t p;
        p.start = md_cert_get_not_before(cert);
        p.end = md_cert_get_not_after(cert);
        return p;
    }
    
    int md_cert_covers_domain(md_cert_t *cert, const char *domain_name)
    {
        apr_array_header_t *alt_names;
    
        md_cert_get_alt_names(&alt_names, cert, cert->pool);
        if (alt_names) {
            return md_array_str_index(alt_names, domain_name, 0, 0) >= 0;
        }
        return 0;
    }
    
    int md_cert_covers_md(md_cert_t *cert, const md_t *md)
    {
        const char *name;
        int i;
        
        if (!cert->alt_names) {
            md_cert_get_alt_names(&cert->alt_names, cert, cert->pool);
        }
        if (cert->alt_names) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, cert->pool, "cert has %d alt names",
                          cert->alt_names->nelts); 
            for (i = 0; i < md->domains->nelts; ++i) {
                name = APR_ARRAY_IDX(md->domains, i, const char *);
                if (!md_dns_domains_match(cert->alt_names, name)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, cert->pool, 
                                  "md domain %s not covered by cert", name);
                    return 0;
                }
            }
            return 1;
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, cert->pool, "cert has NO alt names");
        }
        return 0;
    }
    
    const char *md_cert_get_issuer_name(const md_cert_t *cert, apr_pool_t *p)
    {
        X509_NAME *xname = X509_get_issuer_name(cert->x509);
        if(xname) {
          char *name, *s = X509_NAME_oneline(xname, NULL, 0);
          name = apr_pstrdup(p, s);
          OPENSSL_free(s);
          return name;
        }
        return NULL;
    }
    
    apr_status_t md_cert_get_issuers_uri(const char **puri, const md_cert_t *cert, apr_pool_t *p)
    {
        apr_status_t rv = APR_ENOENT;
        STACK_OF(ACCESS_DESCRIPTION) *xinfos;
        const char *uri = NULL;
        unsigned char *buf;
        int i;
    
        xinfos = X509_get_ext_d2i(cert->x509, NID_info_access, NULL, NULL);
        if (xinfos) {
            for (i = 0; i < sk_ACCESS_DESCRIPTION_num(xinfos); i++) {
                ACCESS_DESCRIPTION *val = sk_ACCESS_DESCRIPTION_value(xinfos, i);
                if (OBJ_obj2nid(val->method) == NID_ad_ca_issuers
                        && val->location && val->location->type == GEN_URI) {
                    ASN1_STRING_to_UTF8(&buf, val->location->d.uniformResourceIdentifier);
                    uri = apr_pstrdup(p, (char *)buf);
                    OPENSSL_free(buf);
                    rv = APR_SUCCESS;
                    break;
                }
            }
            sk_ACCESS_DESCRIPTION_pop_free(xinfos, ACCESS_DESCRIPTION_free);
        } 
        *puri = (APR_SUCCESS == rv)? uri : NULL;
        return rv;
    }
    
    apr_status_t md_cert_get_alt_names(apr_array_header_t **pnames, const md_cert_t *cert, apr_pool_t *p)
    {
        apr_array_header_t *names;
        apr_status_t rv = APR_ENOENT;
        STACK_OF(GENERAL_NAME) *xalt_names;
        unsigned char *buf;
        int i;
    
        xalt_names = X509_get_ext_d2i(cert->x509, NID_subject_alt_name, NULL, NULL);
        if (xalt_names) {
            GENERAL_NAME *cval;
            const unsigned char *ip;
            int len;
            
            names = apr_array_make(p, sk_GENERAL_NAME_num(xalt_names), sizeof(char *));
            for (i = 0; i < sk_GENERAL_NAME_num(xalt_names); ++i) {
                cval = sk_GENERAL_NAME_value(xalt_names, i);
                switch (cval->type) {
                    case GEN_DNS:
                    case GEN_URI:
                        ASN1_STRING_to_UTF8(&buf, cval->d.ia5);
                        APR_ARRAY_PUSH(names, const char *) = apr_pstrdup(p, (char*)buf);
                        OPENSSL_free(buf);
                        break;
                    case GEN_IPADD:
                        len = ASN1_STRING_length(cval->d.iPAddress);
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
                        ip = ASN1_STRING_data(cval->d.iPAddress);
    #else
                        ip = ASN1_STRING_get0_data(cval->d.iPAddress);
    #endif
                        if (len ==  4)      /* IPv4 address */
                            APR_ARRAY_PUSH(names, const char *) = apr_psprintf(p, "%u.%u.%u.%u",
                                                                               ip[0], ip[1], ip[2], ip[3]);
                        else if (len == 16) /* IPv6 address */
                            APR_ARRAY_PUSH(names, const char *) = apr_psprintf(p, "%02x%02x%02x%02x:"
                                                                                  "%02x%02x%02x%02x:"
                                                                                  "%02x%02x%02x%02x:"
                                                                                  "%02x%02x%02x%02x",
                                                                               ip[0],  ip[1],  ip[2],  ip[3],
                                                                               ip[4],  ip[5],  ip[6],  ip[7],
                                                                               ip[8],  ip[9],  ip[10], ip[11],
                                                                               ip[12], ip[13], ip[14], ip[15]);
                        else {
                            ; /* Unknown address type - Log?  Assert? */
                        }
                        break;
                    default:
                        break;
                }
            }
            sk_GENERAL_NAME_pop_free(xalt_names, GENERAL_NAME_free);
            rv = APR_SUCCESS;
        }
        *pnames = (APR_SUCCESS == rv)? names : NULL;
        return rv;
    }
    
    apr_status_t md_cert_fload(md_cert_t **pcert, apr_pool_t *p, const char *fname)
    {
        FILE *f;
        apr_status_t rv;
        md_cert_t *cert;
        X509 *x509;
        
        rv = md_util_fopen(&f, fname, "r");
        if (rv == APR_SUCCESS) {
        
            x509 = PEM_read_X509(f, NULL, NULL, NULL);
            rv = fclose(f);
            if (x509 != NULL) {
                cert =  md_cert_make(p, x509);
            }
            else {
                rv = APR_EINVAL;
            }
        }
    
        *pcert = (APR_SUCCESS == rv)? cert : NULL;
        return rv;
    }
    
    static apr_status_t cert_to_buffer(md_data_t *buffer, const md_cert_t *cert, apr_pool_t *p)
    {
        BIO *bio = BIO_new(BIO_s_mem());
        int i;
        
        if (!bio) {
            return APR_ENOMEM;
        }
    
        ERR_clear_error();
        PEM_write_bio_X509(bio, cert->x509);
        if (ERR_get_error() > 0) {
            BIO_free(bio);
            return APR_EINVAL;
        }
    
        i = BIO_pending(bio);
        if (i > 0) {
            buffer->data = apr_palloc(p, (apr_size_t)i);
            i = BIO_read(bio, (char*)buffer->data, i);
            buffer->len = (apr_size_t)i;
        }
        BIO_free(bio);
        return APR_SUCCESS;
    }
    
    apr_status_t md_cert_fsave(md_cert_t *cert, apr_pool_t *p, 
                               const char *fname, apr_fileperms_t perms)
    {
        md_data_t buffer;
        apr_status_t rv;
    
        md_data_null(&buffer);
        if (APR_SUCCESS == (rv = cert_to_buffer(&buffer, cert, p))) {
            return md_util_freplace(fname, perms, p, fwrite_buffer, &buffer); 
        }
        return rv;
    }
    
    apr_status_t md_cert_to_base64url(const char **ps64, const md_cert_t *cert, apr_pool_t *p)
    {
        md_data_t buffer;
        apr_status_t rv;
    
        md_data_null(&buffer);
        if (APR_SUCCESS == (rv = cert_to_buffer(&buffer, cert, p))) {
            *ps64 = md_util_base64url_encode(&buffer, p);
            return APR_SUCCESS;
        }
        *ps64 = NULL;
        return rv;
    }
    
    apr_status_t md_cert_to_sha256_digest(md_data_t **pdigest, const md_cert_t *cert, apr_pool_t *p)
    {
        md_data_t *digest;
        unsigned int dlen;
    
        digest = md_data_pmake(EVP_MAX_MD_SIZE, p);
        X509_digest(cert->x509, EVP_sha256(), (unsigned char*)digest->data, &dlen);
        digest->len = dlen;
    
        *pdigest = digest;
        return APR_SUCCESS;
    }
    
    apr_status_t md_cert_to_sha256_fingerprint(const char **pfinger, const md_cert_t *cert, apr_pool_t *p)
    {
        md_data_t *digest;
        apr_status_t rv;
    
        rv = md_cert_to_sha256_digest(&digest, cert, p);
        if (APR_SUCCESS == rv) {
            return md_data_to_hex(pfinger, 0, p, digest);
        }
        *pfinger = NULL;
        return rv;
    }
    
    static int md_cert_read_pem(BIO *bf, apr_pool_t *p, md_cert_t **pcert)
    {
        md_cert_t *cert;
        X509 *x509;
        apr_status_t rv = APR_ENOENT;
        
        ERR_clear_error();
        x509 = PEM_read_bio_X509(bf, NULL, NULL, NULL);
        if (x509 == NULL) goto cleanup;
        cert = md_cert_make(p, x509);
        rv = APR_SUCCESS;
    cleanup:
        *pcert = (APR_SUCCESS == rv)? cert : NULL;
        return rv;
    }
    
    apr_status_t md_cert_read_chain(apr_array_header_t *chain, apr_pool_t *p,
                                    const char *pem, apr_size_t pem_len)
    {
        BIO *bf = NULL;
        apr_status_t rv = APR_SUCCESS;
        md_cert_t *cert;
        int added = 0;
    
    #ifdef MD_OPENSSL_10x
        if (NULL == (bf = BIO_new_mem_buf((char *)pem, (int)pem_len))) {
    #else
        if (NULL == (bf = BIO_new_mem_buf(pem, (int)pem_len))) {
    #endif
            rv = APR_ENOMEM;
            goto cleanup;
        }
        while (APR_SUCCESS == (rv = md_cert_read_pem(bf, chain->pool, &cert))) {
            APR_ARRAY_PUSH(chain, md_cert_t *) = cert;
            added = 1;
        }
        if (APR_ENOENT == rv && added) {
            rv = APR_SUCCESS;
        }
    
    cleanup:
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, p, "read chain with %d certs", chain->nelts);
        if (bf) BIO_free(bf);
        return rv;
    }
    
    apr_status_t md_cert_read_http(md_cert_t **pcert, apr_pool_t *p, 
                                   const md_http_response_t *res)
    {
        const char *ct;
        apr_off_t data_len;
        char *der;
        apr_size_t der_len;
        md_cert_t *cert = NULL;
        apr_status_t rv;
        
        ct = apr_table_get(res->headers, "Content-Type");
        ct = md_util_parse_ct(res->req->pool, ct);
        if (!res->body || !ct || strcmp("application/pkix-cert", ct)) {
            rv = APR_ENOENT;
            goto out;
        }
        
        if (APR_SUCCESS == (rv = apr_brigade_length(res->body, 1, &data_len))) {
            if (data_len > 1024*1024) { /* certs usually are <2k each */
                return APR_EINVAL;
            }
            if (APR_SUCCESS == (rv = apr_brigade_pflatten(res->body, &der, &der_len, res->req->pool))) {
                const unsigned char *bf = (const unsigned char*)der;
                X509 *x509;
                
                if (NULL == (x509 = d2i_X509(NULL, &bf, (long)der_len))) {
                    rv = APR_EINVAL;
                    goto out;
                }
                else {
                    cert = md_cert_make(p, x509);
                    rv = APR_SUCCESS;
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, p,
                        "parsing cert from content-type=%s, content-length=%ld", ct, (long)data_len);
                }
            }
        }
    out:
        *pcert = (APR_SUCCESS == rv)? cert : NULL;
        return rv;
    }
    
    apr_status_t md_cert_chain_read_http(struct apr_array_header_t *chain,
                                         apr_pool_t *p, const struct md_http_response_t *res)
    {
        const char *ct = NULL;
        apr_off_t blen;
        apr_size_t data_len = 0;
        char *data;
        md_cert_t *cert;
        apr_status_t rv = APR_ENOENT;
        
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, p,
            "chain_read, processing %d response", res->status);
        if (APR_SUCCESS != (rv = apr_brigade_length(res->body, 1, &blen))) goto cleanup;
        if (blen > 1024*1024) { /* certs usually are <2k each */
            rv = APR_EINVAL;
            goto cleanup;
        }
        
        data_len = (apr_size_t)blen;
        ct = apr_table_get(res->headers, "Content-Type");
        if (!res->body || !ct) goto cleanup;
        ct = md_util_parse_ct(res->req->pool, ct);
        if (!strcmp("application/pkix-cert", ct)) {
            rv = md_cert_read_http(&cert, p, res);
            if (APR_SUCCESS != rv) goto cleanup;
            APR_ARRAY_PUSH(chain, md_cert_t *) = cert;
        }
        else if (!strcmp("application/pem-certificate-chain", ct)
            || !strncmp("text/plain", ct, sizeof("text/plain")-1)) {
            /* Some servers seem to think 'text/plain' is sufficient, see #232 */
            rv = apr_brigade_pflatten(res->body, &data, &data_len, res->req->pool);
            if (APR_SUCCESS != rv) goto cleanup;
            rv = md_cert_read_chain(chain, res->req->pool, data, data_len);
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p,
                "attempting to parse certificates from unrecognized content-type: %s", ct);
            rv = apr_brigade_pflatten(res->body, &data, &data_len, res->req->pool);
            if (APR_SUCCESS != rv) goto cleanup;
            rv = md_cert_read_chain(chain, res->req->pool, data, data_len);
            if (APR_SUCCESS == rv && chain->nelts == 0) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p,
                    "certificate chain response did not contain any certificates "
                    "(suspicious content-type: %s)", ct);
                rv = APR_ENOENT;
            }
        }
    cleanup:
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, p,
            "parsed certs from content-type=%s, content-length=%ld", ct, (long)data_len);
        return rv;
    }
    
    md_cert_state_t md_cert_state_get(const md_cert_t *cert)
    {
        if (cert->x509) {
            return md_cert_is_valid_now(cert)? MD_CERT_VALID : MD_CERT_EXPIRED;
        }
        return MD_CERT_UNKNOWN;
    }
    
    apr_status_t md_chain_fappend(struct apr_array_header_t *certs, apr_pool_t *p, const char *fname)
    {
        FILE *f;
        apr_status_t rv;
        X509 *x509;
        md_cert_t *cert;
        unsigned long err;
        
        rv = md_util_fopen(&f, fname, "r");
        if (rv == APR_SUCCESS) {
            ERR_clear_error();
            while (NULL != (x509 = PEM_read_X509(f, NULL, NULL, NULL))) {
                cert = md_cert_make(p, x509);
                APR_ARRAY_PUSH(certs, md_cert_t *) = cert;
            }
            fclose(f);
            
            if (0 < (err =  ERR_get_error())
                && !(ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
                /* not the expected one when no more PEM encodings are found */
                rv = APR_EINVAL;
                goto out;
            }
            
            if (certs->nelts == 0) {
                /* Did not find any. This is acceptable unless the file has a certain size
                 * when we no longer accept it as empty chain file. Something seems to be
                 * wrong then. */
                apr_finfo_t info;
                if (APR_SUCCESS == apr_stat(&info, fname, APR_FINFO_SIZE, p) && info.size >= 1024) {
                    /* "Too big for a moon." */
                    rv = APR_EINVAL;
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, 
                                  "no certificates in non-empty chain %s", fname);
                    goto out;
                }
            }        
        }
    out:
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p, "read chain file %s, found %d certs", 
                      fname, certs? certs->nelts : 0);
        return rv;
    }
    
    apr_status_t md_chain_fload(apr_array_header_t **pcerts, apr_pool_t *p, const char *fname)
    {
        apr_array_header_t *certs;
        apr_status_t rv;
    
        certs = apr_array_make(p, 5, sizeof(md_cert_t *));
        rv = md_chain_fappend(certs, p, fname);
        *pcerts = (APR_SUCCESS == rv)? certs : NULL;
        return rv;
    }
    
    apr_status_t md_chain_fsave(apr_array_header_t *certs, apr_pool_t *p, 
                                const char *fname, apr_fileperms_t perms)
    {
        FILE *f;
        apr_status_t rv;
        const md_cert_t *cert;
        unsigned long err = 0;
        int i;
        
        (void)p;
        rv = md_util_fopen(&f, fname, "w");
        if (rv == APR_SUCCESS) {
            apr_file_perms_set(fname, perms);
            ERR_clear_error();
            for (i = 0; i < certs->nelts; ++i) {
                cert = APR_ARRAY_IDX(certs, i, const md_cert_t *);
                assert(cert->x509);
                
                PEM_write_X509(f, cert->x509);
                
                if (0 < (err = ERR_get_error())) {
                    break;
                }
                
            }
            rv = fclose(f);
            if (err) {
                rv = APR_EINVAL;
            }
        }
        return rv;
    }
    
    /**************************************************************************************************/
    /* certificate signing requests */
    
    static const char *alt_names(apr_array_header_t *domains, apr_pool_t *p)
    {
        const char *alts = "", *sep = "", *domain;
        int i;
        
        for (i = 0; i < domains->nelts; ++i) {
            domain = APR_ARRAY_IDX(domains, i, const char *);
            alts = apr_psprintf(p, "%s%sDNS:%s", alts, sep, domain);
            sep = ",";
        }
        return alts;
    }
    
    static apr_status_t add_ext(X509 *x, int nid, const char *value, apr_pool_t *p)
    {
        X509_EXTENSION *ext = NULL;
        X509V3_CTX ctx;
        apr_status_t rv;
    
        ERR_clear_error();
        X509V3_set_ctx_nodb(&ctx);
        X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
        if (NULL == (ext = X509V3_EXT_conf_nid(NULL, &ctx, nid, (char*)value))) {
            unsigned long err =  ERR_get_error();
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "add_ext, create, nid=%d value='%s' "
                          "(lib=%d, reason=%d)", nid, value, ERR_GET_LIB(err), ERR_GET_REASON(err)); 
            return APR_EGENERAL;
        }
        
        ERR_clear_error();
        rv = X509_add_ext(x, ext, -1)? APR_SUCCESS : APR_EINVAL;
        if (APR_SUCCESS != rv) {
            unsigned long err =  ERR_get_error();
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "add_ext, add, nid=%d value='%s' "
                          "(lib=%d, reason=%d)", nid, value, ERR_GET_LIB(err), ERR_GET_REASON(err)); 
        }
        X509_EXTENSION_free(ext);
        return rv;
    }
    
    static apr_status_t sk_add_alt_names(STACK_OF(X509_EXTENSION) *exts,
                                         apr_array_header_t *domains, apr_pool_t *p)
    {
        if (domains->nelts > 0) {
            X509_EXTENSION *x;
            
            x = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name, (char*)alt_names(domains, p));
            if (NULL == x) {
                return APR_EGENERAL;
            }
            sk_X509_EXTENSION_push(exts, x);
        }
        return APR_SUCCESS;
    }
    
    #define MD_OID_MUST_STAPLE_NUM          "1.3.6.1.5.5.7.1.24"
    #define MD_OID_MUST_STAPLE_SNAME        "tlsfeature"
    #define MD_OID_MUST_STAPLE_LNAME        "TLS Feature" 
    
    int md_cert_must_staple(const md_cert_t *cert)
    {
        /* In case we do not get the NID for it, we treat this as not set. */
        int nid = MD_GET_NID(MUST_STAPLE);
        return ((NID_undef != nid)) && X509_get_ext_by_NID(cert->x509, nid, -1) >= 0;
    }
    
    static apr_status_t add_must_staple(STACK_OF(X509_EXTENSION) *exts, const char *name, apr_pool_t *p)
    {
        X509_EXTENSION *x;
        int nid;
        
        nid = MD_GET_NID(MUST_STAPLE);
        if (NID_undef == nid) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, 
                          "%s: unable to get NID for v3 must-staple TLS feature", name);
            return APR_ENOTIMPL;
        }
        x = X509V3_EXT_conf_nid(NULL, NULL, nid, (char*)"DER:30:03:02:01:05");
        if (NULL == x) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, 
                          "%s: unable to create x509 extension for must-staple", name);
            return APR_EGENERAL;
        }
        sk_X509_EXTENSION_push(exts, x);
        return APR_SUCCESS;
    }
    
    apr_status_t md_cert_req_create(const char **pcsr_der_64, const char *name,
                                    apr_array_header_t *domains, int must_staple, 
                                    md_pkey_t *pkey, apr_pool_t *p)
    {
        const char *s, *csr_der_64 = NULL;
        const unsigned char *domain;
        X509_REQ *csr;
        X509_NAME *n = NULL;
        STACK_OF(X509_EXTENSION) *exts = NULL;
        apr_status_t rv;
        md_data_t csr_der;
        int csr_der_len;
        
        assert(domains->nelts > 0);
        md_data_null(&csr_der);
    
        if (NULL == (csr = X509_REQ_new()) 
            || NULL == (exts = sk_X509_EXTENSION_new_null())
            || NULL == (n = X509_NAME_new())) {
            rv = APR_ENOMEM;
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: openssl alloc X509 things", name);
            goto out; 
        }
    
        /* subject name == first domain */
        domain = APR_ARRAY_IDX(domains, 0, const unsigned char *);
        /* Do not set the domain in the CN if it is longer than 64 octets.
         * Instead, let the CA choose a 'proper' name. At the moment (2021-01), LE will
         * inspect all SAN names and use one < 64 chars if it can be found. It will fail
         * otherwise.
         * The reason we do not check this beforehand is that the restrictions on CNs
         * are in flux. They used to be authoritative, now browsers no longer do that, but
         * no one wants to hand out a cert with "google.com" as CN either. So, we leave
         * it for the CA to decide if and how it hands out a cert for this or fails.
         * This solves issue where the name is too long, see #227 */
        if (strlen((const char*)domain) < 64
            && (!X509_NAME_add_entry_by_txt(n, "CN", MBSTRING_ASC, domain, -1, -1, 0)
                || !X509_REQ_set_subject_name(csr, n))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "%s: REQ name add entry", name);
            rv = APR_EGENERAL; goto out;
        }
        /* collect extensions, such as alt names and must staple */
        if (APR_SUCCESS != (rv = sk_add_alt_names(exts, domains, p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: collecting alt names", name);
            rv = APR_EGENERAL; goto out;
        }
        if (must_staple && APR_SUCCESS != (rv = add_must_staple(exts, name, p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: you requested that a certificate "
                "is created with the 'must-staple' extension, however the SSL library was "
                "unable to initialized that extension. Please file a bug report on which platform "
                "and with which library this happens. To continue before this problem is resolved, "
                "configure 'MDMustStaple off' for your domains", name);
            rv = APR_EGENERAL; goto out;
        }
        /* add extensions to csr */
        if (sk_X509_EXTENSION_num(exts) > 0 && !X509_REQ_add_extensions(csr, exts)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: adding exts", name);
            rv = APR_EGENERAL; goto out;
        }
        /* add our key */
        if (!X509_REQ_set_pubkey(csr, pkey->pkey)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set pkey in csr", name);
            rv = APR_EGENERAL; goto out;
        }
        /* sign, der encode and base64url encode */
        if (!X509_REQ_sign(csr, pkey->pkey, pkey_get_MD(pkey))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: sign csr", name);
            rv = APR_EGENERAL; goto out;
        }
        if ((csr_der_len = i2d_X509_REQ(csr, NULL)) < 0) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: der length", name);
            rv = APR_EGENERAL; goto out;
        }
        csr_der.len = (apr_size_t)csr_der_len;
        s = csr_der.data = apr_pcalloc(p, csr_der.len + 1);
        if (i2d_X509_REQ(csr, (unsigned char**)&s) != csr_der_len) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: csr der enc", name);
            rv = APR_EGENERAL; goto out;
        }
        csr_der_64 = md_util_base64url_encode(&csr_der, p);
        rv = APR_SUCCESS;
        
    out:
        if (exts) {
            sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        }
        if (csr) {
            X509_REQ_free(csr);
        }
        if (n) {
            X509_NAME_free(n);
        }
        *pcsr_der_64 = (APR_SUCCESS == rv)? csr_der_64 : NULL;
        return rv;
    }
    
    static apr_status_t mk_x509(X509 **px, md_pkey_t *pkey, const char *cn,
                                apr_interval_time_t valid_for, apr_pool_t *p)
    {
        X509 *x = NULL;
        X509_NAME *n = NULL;
        BIGNUM *big_rnd = NULL;
        ASN1_INTEGER *asn1_rnd = NULL;
        unsigned char rnd[20];
        int days;
        apr_status_t rv;
        
        if (NULL == (x = X509_new()) 
            || NULL == (n = X509_NAME_new())) {
            rv = APR_ENOMEM;
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "%s: openssl alloc X509 things", cn);
            goto out; 
        }
    
        if (APR_SUCCESS != (rv = md_rand_bytes(rnd, sizeof(rnd), p))
            || !(big_rnd = BN_bin2bn(rnd, sizeof(rnd), NULL))
            || !(asn1_rnd = BN_to_ASN1_INTEGER(big_rnd, NULL))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "%s: setup random serial", cn);
            rv = APR_EGENERAL; goto out;
        }
        if (!X509_set_serialNumber(x, asn1_rnd)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "%s: set serial number", cn);
            rv = APR_EGENERAL; goto out;
        }
        if (1 != X509_set_version(x, 2L)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "%s: setting x.509v3", cn);
            rv = APR_EGENERAL; goto out;
        }
        /* set common name and issuer */
        if (!X509_NAME_add_entry_by_txt(n, "CN", MBSTRING_ASC, (const unsigned char*)cn, -1, -1, 0)
            || !X509_set_subject_name(x, n)
            || !X509_set_issuer_name(x, n)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "%s: name add entry", cn);
            rv = APR_EGENERAL; goto out;
        }
        /* cert are unconstrained (but not very trustworthy) */
        if (APR_SUCCESS != (rv = add_ext(x, NID_basic_constraints, "critical,CA:FALSE", p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set basic constraints ext", cn);
            goto out;
        }
        /* add our key */
        if (!X509_set_pubkey(x, pkey->pkey)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set pkey in x509", cn);
            rv = APR_EGENERAL; goto out;
        }
        /* validity */
        days = (int)((apr_time_sec(valid_for) + MD_SECS_PER_DAY - 1)/ MD_SECS_PER_DAY);
        if (!X509_set_notBefore(x, ASN1_TIME_set(NULL, time(NULL)))) {
            rv = APR_EGENERAL; goto out;
        }
        if (!X509_set_notAfter(x, ASN1_TIME_adj(NULL, time(NULL), days, 0))) {
            rv = APR_EGENERAL; goto out;
        }
    
    out:
        *px = (APR_SUCCESS == rv)? x : NULL;
        if (APR_SUCCESS != rv && x) X509_free(x);
        if (big_rnd) BN_free(big_rnd);
        if (asn1_rnd) ASN1_INTEGER_free(asn1_rnd);
        if (n) X509_NAME_free(n);
        return rv;
    }
    
    apr_status_t md_cert_self_sign(md_cert_t **pcert, const char *cn, 
                                   apr_array_header_t *domains, md_pkey_t *pkey,
                                   apr_interval_time_t valid_for, apr_pool_t *p)
    {
        X509 *x;
        md_cert_t *cert = NULL;
        apr_status_t rv;
        
        assert(domains);
    
        if (APR_SUCCESS != (rv = mk_x509(&x, pkey, cn, valid_for, p))) goto out;
        
        /* add the domain as alt name */
        if (APR_SUCCESS != (rv = add_ext(x, NID_subject_alt_name, alt_names(domains, p), p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set alt_name ext", cn);
            goto out;
        }
    
        /* keyUsage, ExtendedKeyUsage */
    
        if (APR_SUCCESS != (rv = add_ext(x, NID_key_usage, "critical,digitalSignature", p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set keyUsage", cn);
            goto out;
        }
        if (APR_SUCCESS != (rv = add_ext(x, NID_ext_key_usage, "serverAuth", p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set extKeyUsage", cn);
            goto out;
        }
    
        /* sign with same key */
        if (!X509_sign(x, pkey->pkey, pkey_get_MD(pkey))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: sign x509", cn);
            rv = APR_EGENERAL; goto out;
        }
    
        cert = md_cert_make(p, x);
        rv = APR_SUCCESS;
        
    out:
        *pcert = (APR_SUCCESS == rv)? cert : NULL;
        if (!cert && x) X509_free(x);
        return rv;
    }
    
    #define MD_OID_ACME_VALIDATION_NUM          "1.3.6.1.5.5.7.1.31"
    #define MD_OID_ACME_VALIDATION_SNAME        "pe-acmeIdentifier"
    #define MD_OID_ACME_VALIDATION_LNAME        "ACME Identifier" 
    
    static int get_acme_validation_nid(void)
    {
        int nid = OBJ_txt2nid(MD_OID_ACME_VALIDATION_NUM);
        if (NID_undef == nid) {
            nid = OBJ_create(MD_OID_ACME_VALIDATION_NUM, 
                             MD_OID_ACME_VALIDATION_SNAME, MD_OID_ACME_VALIDATION_LNAME);
        }
        return nid;
    }
    
    apr_status_t md_cert_make_tls_alpn_01(md_cert_t **pcert, const char *domain, 
                                          const char *acme_id, md_pkey_t *pkey, 
                                          apr_interval_time_t valid_for, apr_pool_t *p)
    {
        X509 *x;
        md_cert_t *cert = NULL;
        const char *alts;
        apr_status_t rv;
    
        if (APR_SUCCESS != (rv = mk_x509(&x, pkey, "tls-alpn-01-challenge", valid_for, p))) goto out;
        
        /* add the domain as alt name */
        alts = apr_psprintf(p, "DNS:%s", domain);
        if (APR_SUCCESS != (rv = add_ext(x, NID_subject_alt_name, alts, p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set alt_name ext", domain);
            goto out;
        }
    
        if (APR_SUCCESS != (rv = add_ext(x, get_acme_validation_nid(), acme_id, p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: set pe-acmeIdentifier", domain);
            goto out;
        }
    
        /* sign with same key */
        if (!X509_sign(x, pkey->pkey, pkey_get_MD(pkey))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: sign x509", domain);
            rv = APR_EGENERAL; goto out;
        }
    
        cert = md_cert_make(p, x);
        rv = APR_SUCCESS;
        
    out:
        if (!cert && x) {
            X509_free(x);
        }
        *pcert = (APR_SUCCESS == rv)? cert : NULL;
        return rv;
    }
    
    #if MD_HAVE_CT
    #define MD_OID_CT_SCTS_NUM          "1.3.6.1.4.1.11129.2.4.2"
    #define MD_OID_CT_SCTS_SNAME        "CT-SCTs"
    #define MD_OID_CT_SCTS_LNAME        "CT Certificate SCTs" 
    static int get_ct_scts_nid(void)
    {
        int nid = OBJ_txt2nid(MD_OID_CT_SCTS_NUM);
        if (NID_undef == nid) {
            nid = OBJ_create(MD_OID_CT_SCTS_NUM, 
                             MD_OID_CT_SCTS_SNAME, MD_OID_CT_SCTS_LNAME);
        }
        return nid;
    }
    #endif
    
    const char *md_nid_get_sname(int nid)
    {
        return OBJ_nid2sn(nid);
    }
    
    const char *md_nid_get_lname(int nid)
    {
        return OBJ_nid2ln(nid);
    }
    
    apr_status_t md_cert_get_ct_scts(apr_array_header_t *scts, apr_pool_t *p, const md_cert_t *cert)
    {
    #if MD_HAVE_CT
        int nid, i, idx, critical;
        STACK_OF(SCT) *sct_list;
        SCT *sct_handle;
        md_sct *sct;
        size_t len;
        const char *data;
        
        nid = get_ct_scts_nid();
        if (NID_undef == nid) return APR_ENOTIMPL;
    
        idx = -1;
        while (1) {
            sct_list = X509_get_ext_d2i(cert->x509, nid, &critical, &idx);
            if (sct_list) {
                for (i = 0; i < sk_SCT_num(sct_list); i++) {
                   sct_handle = sk_SCT_value(sct_list, i);
                    if (sct_handle) {
                        sct = apr_pcalloc(p, sizeof(*sct));
                        sct->version = SCT_get_version(sct_handle);
                        sct->timestamp = apr_time_from_msec(SCT_get_timestamp(sct_handle));
                        len = SCT_get0_log_id(sct_handle, (unsigned char**)&data);
                        sct->logid = md_data_make_pcopy(p, data, len);
                        sct->signature_type_nid = SCT_get_signature_nid(sct_handle);
                        len = SCT_get0_signature(sct_handle,  (unsigned char**)&data);
                        sct->signature = md_data_make_pcopy(p, data, len);
                        
                        APR_ARRAY_PUSH(scts, md_sct*) = sct;
                    }
                }
            }
            if (idx < 0) break;
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p, "ct_sct, found %d SCT extensions", scts->nelts);
        return APR_SUCCESS;
    #else
        (void)scts;
        (void)p;
        (void)cert;
        return APR_ENOTIMPL;
    #endif
    }
    
    apr_status_t md_cert_get_ocsp_responder_url(const char **purl, apr_pool_t *p, const md_cert_t *cert)
    {
        STACK_OF(OPENSSL_STRING) *ssk;
        apr_status_t rv = APR_SUCCESS;
        const char *url = NULL;
    
        ssk = X509_get1_ocsp(md_cert_get_X509(cert));
        if (!ssk) {
            rv = APR_ENOENT;
            goto cleanup;
        }
        url = apr_pstrdup(p, sk_OPENSSL_STRING_value(ssk, 0));
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, p, "ocsp responder found '%s'", url);
    
    cleanup:
        if (ssk) X509_email_free(ssk);
        *purl = url;
        return rv;
    }
    
    apr_status_t md_check_cert_and_pkey(struct apr_array_header_t *certs, md_pkey_t *pkey)
    {
        const md_cert_t *cert;
    
        if (certs->nelts == 0) {
            return APR_ENOENT;
        }
    
        cert = APR_ARRAY_IDX(certs, 0, const md_cert_t*);
    
        if (1 != X509_check_private_key(cert->x509, pkey->pkey)) {
            return APR_EGENERAL;
        }
    
        return APR_SUCCESS;
    }
    ����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md.h������������������������������������������������������������������������0000664�0001751�0001751�00000032313�14750656217�015462� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_h
    #define mod_md_md_h
    
    #include <apr_time.h>
    
    #include "md_time.h"
    #include "md_version.h"
    
    struct apr_array_header_t;
    struct apr_hash_t;
    struct md_json_t;
    struct md_cert_t;
    struct md_job_t;
    struct md_pkey_t;
    struct md_result_t;
    struct md_store_t;
    struct md_srv_conf_t;
    struct md_pkey_spec_t;
    
    #define MD_PKEY_RSA_BITS_MIN       2048
    #define MD_PKEY_RSA_BITS_DEF       2048
    
    /* Minimum age for the HSTS header (RFC 6797), considered appropriate by Mozilla Security */
    #define MD_HSTS_HEADER             "Strict-Transport-Security"
    #define MD_HSTS_MAX_AGE_DEFAULT    15768000
    
    #define PROTO_ACME_TLS_1        "acme-tls/1"
    
    #define MD_TIME_LIFE_NORM           (apr_time_from_sec(100 * MD_SECS_PER_DAY))
    #define MD_TIME_RENEW_WINDOW_DEF    (apr_time_from_sec(33 * MD_SECS_PER_DAY))
    #define MD_TIME_WARN_WINDOW_DEF     (apr_time_from_sec(10 * MD_SECS_PER_DAY))
    #define MD_TIME_OCSP_KEEP_NORM      (apr_time_from_sec(7 * MD_SECS_PER_DAY))
    
    #define MD_OTHER                "other"
    
    typedef enum {
        MD_S_UNKNOWN = 0,               /* MD has not been analysed yet */
        MD_S_INCOMPLETE = 1,            /* MD is missing necessary information, cannot go live */
        MD_S_COMPLETE = 2,              /* MD has all necessary information, can go live */
        MD_S_EXPIRED_DEPRECATED = 3,    /* deprecated */
        MD_S_ERROR = 4,                 /* MD data is flawed, unable to be processed as is */ 
        MD_S_MISSING_INFORMATION = 5,     /* User has not agreed to ToS */
    } md_state_t;
    
    typedef enum {
        MD_REQUIRE_UNSET = -1,
        MD_REQUIRE_OFF,
        MD_REQUIRE_TEMPORARY,
        MD_REQUIRE_PERMANENT,
    } md_require_t;
    
    typedef enum {
        MD_RENEW_DEFAULT = -1,          /* default value */
        MD_RENEW_MANUAL,                /* manually triggered renewal of certificate */
        MD_RENEW_AUTO,                  /* automatic process performed by httpd */
        MD_RENEW_ALWAYS,                /* always renewed by httpd, even if not necessary */
    } md_renew_mode_t;
    
    typedef struct md_t md_t;
    struct md_t {
        const char *name;               /* unique name of this MD */
        struct apr_array_header_t *domains; /* all DNS names this MD includes */
        struct apr_array_header_t *contacts;   /* list of contact uris, e.g. mailto:xxx */
    
        struct md_pkeys_spec_t *pks;    /* specification for generating private keys */
        md_timeslice_t *renew_window;   /* time before expiration that starts renewal */
        md_timeslice_t *warn_window;    /* time before expiration that warnings are sent out */
        
        const char *ca_proto;           /* protocol used vs CA (e.g. ACME) */
        struct apr_array_header_t *ca_urls; /* urls of CAs */
        const char *ca_effective;       /* url of CA used */
        const char *ca_account;         /* account used at CA */
        const char *ca_agreement;       /* accepted agreement uri between CA and user */
        struct apr_array_header_t *ca_challenges; /* challenge types configured for this MD */
        struct apr_array_header_t *cert_files; /* != NULL iff pubcerts explicitly configured */
        struct apr_array_header_t *pkey_files; /* != NULL iff privkeys explicitly configured */
        const char *ca_eab_kid;         /* optional KEYID for external account binding */
        const char *ca_eab_hmac;        /* optional HMAC for external account binding */
        const char *profile;            /* optional cert profile to order */
        int profile_mandatory;          /* if profile, when given, is mandatory */
    
        const char *state_descr;        /* description of state of NULL */
        
        struct apr_array_header_t *acme_tls_1_domains; /* domains supporting "acme-tls/1" protocol */
        const char *dns01_cmd;          /* DNS challenge command, override global command */
    
        const struct md_srv_conf_t *sc; /* server config where it was defined or NULL */
        const char *defn_name;          /* config file this MD was defined */
        unsigned defn_line_number;      /* line number of definition */
        const char *configured_name;    /* name this MD was configured with, if different */
    
        int renew_mode;                 /* mode of obtaining credentials */
        md_require_t require_https;     /* Iff https: is required for this MD */
        md_state_t state;               /* state of this MD */
        int transitive;                 /* != 0 iff VirtualHost names/aliases are auto-added */
        int must_staple;                /* certificates should set the OCSP Must Staple extension */
        int stapling;                   /* if OCSP stapling is enabled */
        int watched;                    /* if certificate is supervised (renew or expiration warning) */
    };
    
    #define MD_KEY_ACCOUNT          "account"
    #define MD_KEY_ACME_TLS_1       "acme-tls/1"
    #define MD_KEY_ACTIVATION_DELAY "activation-delay"
    #define MD_KEY_ACTIVITY         "activity"
    #define MD_KEY_AGREEMENT        "agreement"
    #define MD_KEY_AUTHORIZATIONS   "authorizations"
    #define MD_KEY_BITS             "bits"
    #define MD_KEY_CA               "ca"
    #define MD_KEY_CA_URL           "ca-url"
    #define MD_KEY_CERT             "cert"
    #define MD_KEY_CERT_FILES       "cert-files"
    #define MD_KEY_CERTIFICATE      "certificate"
    #define MD_KEY_CHALLENGE        "challenge"
    #define MD_KEY_CHALLENGES       "challenges"
    #define MD_KEY_CMD_DNS01        "cmd-dns-01"
    #define MD_KEY_DNS01_VERSION    "cmd-dns-01-version"
    #define MD_KEY_COMPLETE         "complete"
    #define MD_KEY_CONTACT          "contact"
    #define MD_KEY_CONTACTS         "contacts"
    #define MD_KEY_CSR              "csr"
    #define MD_KEY_CURVE            "curve"
    #define MD_KEY_DETAIL           "detail"
    #define MD_KEY_DISABLED         "disabled"
    #define MD_KEY_DIR              "dir"
    #define MD_KEY_DOMAIN           "domain"
    #define MD_KEY_DOMAINS          "domains"
    #define MD_KEY_EAB              "eab"
    #define MD_KEY_EAB_REQUIRED     "externalAccountRequired"
    #define MD_KEY_ENTRIES          "entries"
    #define MD_KEY_ERRORED          "errored"
    #define MD_KEY_ERROR            "error"
    #define MD_KEY_ERRORS           "errors"
    #define MD_KEY_EXPIRES          "expires"
    #define MD_KEY_FINALIZE         "finalize"
    #define MD_KEY_FINISHED         "finished"
    #define MD_KEY_FROM             "from"
    #define MD_KEY_GOOD             "good"
    #define MD_KEY_HMAC             "hmac"
    #define MD_KEY_HTTP             "http"
    #define MD_KEY_HTTPS            "https"
    #define MD_KEY_ID               "id"
    #define MD_KEY_IDENTIFIER       "identifier"
    #define MD_KEY_ISSUER_NAME      "issuer-name"
    #define MD_KEY_ISSUER_URI       "issuer-uri"
    #define MD_KEY_KEY              "key"
    #define MD_KEY_KID              "kid"
    #define MD_KEY_KEYAUTHZ         "keyAuthorization"
    #define MD_KEY_LAST             "last"
    #define MD_KEY_LAST_RUN         "last-run"
    #define MD_KEY_LOCATION         "location"
    #define MD_KEY_LOG              "log"
    #define MD_KEY_MDS              "managed-domains"
    #define MD_KEY_MESSAGE          "message"
    #define MD_KEY_MUST_STAPLE      "must-staple"
    #define MD_KEY_NAME             "name"
    #define MD_KEY_NEXT_RUN         "next-run"
    #define MD_KEY_NOTIFIED         "notified"
    #define MD_KEY_NOTIFIED_RENEWED "notified-renewed"
    #define MD_KEY_OCSP             "ocsp"
    #define MD_KEY_OCSPS            "ocsps"
    #define MD_KEY_ORDERS           "orders"
    #define MD_KEY_PERMANENT        "permanent"
    #define MD_KEY_PKEY             "privkey"
    #define MD_KEY_PKEY_FILES       "pkey-files"
    #define MD_KEY_PROBLEM          "problem"
    #define MD_KEY_PROFILE          "profile"
    #define MD_KEY_PROFILE_MANDATORY "profile-mandatory"
    #define MD_KEY_PROTO            "proto"
    #define MD_KEY_READY            "ready"
    #define MD_KEY_REGISTRATION     "registration"
    #define MD_KEY_RENEW            "renew"
    #define MD_KEY_RENEW_AT         "renew-at"
    #define MD_KEY_RENEW_MODE       "renew-mode"
    #define MD_KEY_RENEWAL          "renewal"
    #define MD_KEY_RENEWING         "renewing"
    #define MD_KEY_RENEW_WINDOW     "renew-window"
    #define MD_KEY_REQUIRE_HTTPS    "require-https"
    #define MD_KEY_RESOURCE         "resource"
    #define MD_KEY_RESPONSE         "response"
    #define MD_KEY_REVOKED          "revoked"
    #define MD_KEY_SERIAL           "serial"
    #define MD_KEY_SHA256_FINGERPRINT  "sha256-fingerprint"
    #define MD_KEY_STAPLING         "stapling"
    #define MD_KEY_STATE            "state"
    #define MD_KEY_STATE_DESCR      "state-descr"
    #define MD_KEY_STATUS           "status"
    #define MD_KEY_STORE            "store"
    #define MD_KEY_SUBPROBLEMS      "subproblems"
    #define MD_KEY_TEMPORARY        "temporary"
    #define MD_KEY_TOS              "termsOfService"
    #define MD_KEY_TOKEN            "token"
    #define MD_KEY_TOTAL            "total"
    #define MD_KEY_TRANSITIVE       "transitive"
    #define MD_KEY_TYPE             "type"
    #define MD_KEY_UNKNOWN          "unknown"
    #define MD_KEY_UNTIL            "until"
    #define MD_KEY_URL              "url"
    #define MD_KEY_URLS             "urls"
    #define MD_KEY_URI              "uri"
    #define MD_KEY_VALID            "valid"
    #define MD_KEY_VALID_FROM       "valid-from"
    #define MD_KEY_VALUE            "value"
    #define MD_KEY_VERSION          "version"
    #define MD_KEY_WATCHED          "watched"
    #define MD_KEY_WHEN             "when"
    #define MD_KEY_WARN_WINDOW      "warn-window"
    
    /* Check if a string member of a new MD (n) has 
     * a value and if it differs from the old MD o
     */
    #define MD_VAL_UPDATE(n,o,s)    ((n)->s != (o)->s)
    #define MD_SVAL_UPDATE(n,o,s)   ((n)->s && (!(o)->s || strcmp((n)->s, (o)->s)))
    
    /**
     * Determine if the Managed Domain contains a specific domain name.
     */
    int md_contains(const md_t *md, const char *domain, int case_sensitive);
    
    /**
     * Determine if the names of the two managed domains overlap.
     */
    int md_domains_overlap(const md_t *md1, const md_t *md2);
    
    /**
     * Determine if the domain names are equal.
     */
    int md_equal_domains(const md_t *md1, const md_t *md2, int case_sensitive);
    
    /**
     * Determine if the domains in md1 contain all domains of md2.
     */
    int md_contains_domains(const md_t *md1, const md_t *md2);
    
    /**
     * Get one common domain name of the two managed domains or NULL.
     */
    const char *md_common_name(const md_t *md1, const md_t *md2);
    
    /**
     * Get the number of common domains.
     */
    apr_size_t md_common_name_count(const md_t *md1, const md_t *md2);
    
    /**
     * Look up a managed domain by its name.
     */
    md_t *md_get_by_name(struct apr_array_header_t *mds, const char *name);
    
    /**
     * Look up a managed domain by a DNS name it contains.
     */
    md_t *md_get_by_domain(struct apr_array_header_t *mds, const char *domain);
    
    /**
     * Find a managed domain, different from the given one, that has overlaps
     * in the domain list.
     */
    md_t *md_get_by_dns_overlap(struct apr_array_header_t *mds, const md_t *md);
    
    /**
     * Create and empty md record, structures initialized.
     */
    md_t *md_create_empty(apr_pool_t *p);
    
    /**
     * Create a managed domain, given a list of domain names.
     */
    md_t *md_create(apr_pool_t *p, struct apr_array_header_t *domains);
    
    /**
     * Deep copy an md record into another pool.
     */
    md_t *md_clone(apr_pool_t *p, const md_t *src);
    
    /**
     * Shallow copy an md record into another pool.
     */
    md_t *md_copy(apr_pool_t *p, const md_t *src);
    
    /** 
     * Convert the managed domain into a JSON representation and vice versa. 
     *
     * This reads and writes the following information: name, domains, ca_url, ca_proto and state.
     */
    struct md_json_t *md_to_json(const md_t *md, apr_pool_t *p);
    md_t *md_from_json(struct md_json_t *json, apr_pool_t *p);
    
    /**
     * Same as md_to_json(), but with sensitive fields stripped.
     */
    struct md_json_t *md_to_public_json(const md_t *md, apr_pool_t *p);
    
    int md_is_covered_by_alt_names(const md_t *md, const struct apr_array_header_t* alt_names);
    
    /* how many certificates this domain has/will eventually have. */
    int md_cert_count(const md_t *md);
    
    const char *md_get_ca_name_from_url(apr_pool_t *p, const char *url);
    apr_status_t md_get_ca_url_from_name(const char **purl, apr_pool_t *p, const char *name);
    
    /**************************************************************************************************/
    /* notifications */
    
    typedef apr_status_t md_job_notify_cb(struct md_job_t *job, const char *reason, 
                                          struct md_result_t *result, apr_pool_t *p, void *baton);
    
    /**************************************************************************************************/
    /* domain credentials */
    
    typedef struct md_pubcert_t md_pubcert_t;
    struct md_pubcert_t {
        struct apr_array_header_t *certs;     /* chain of const md_cert*, leaf cert first */
        struct apr_array_header_t *alt_names; /* alt-names of leaf cert */
        const char *cert_file;                /* file path of chain */
        const char *key_file;                 /* file path of key for leaf cert */
    };
    
    #define MD_OK(c)                    (APR_SUCCESS == (rv = c))
    
    #endif /* mod_md_md_h */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acme_drive.h�������������������������������������������������������������0000664�0001751�0001751�00000003602�14750656217�017637� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright 2019 greenbytes GmbH (https://www.greenbytes.de)
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 md_acme_drive_h
    #define md_acme_drive_h
    
    struct apr_array_header_t;
    struct md_acme_order_t;
    struct md_credentials_t;
    struct md_result_t;
    
    typedef struct md_acme_driver_t {
        md_proto_driver_t *driver;
        void *sub_driver;
        
        md_acme_t *acme;
        md_t *md;
        struct apr_array_header_t *domains;
        apr_array_header_t *ca_challenges;
        const char *profile;
        int profile_mandatory;
        
        int complete;
        apr_array_header_t *creds;       /* the new md_credentials_t */
    
        struct md_credentials_t *cred;   /* credentials currently being processed */ 
        const char *chain_up_link;       /* Link header "up" from last chain retrieval,
                                            needs to be followed */
    
        struct md_acme_order_t *order;
        apr_interval_time_t authz_monitor_timeout;
        
        const char *csr_der_64;
        apr_interval_time_t cert_poll_timeout;
        
    } md_acme_driver_t;
    
    apr_status_t md_acme_drive_set_acct(struct md_proto_driver_t *d, 
                                        struct md_result_t *result);
    apr_status_t md_acme_drive_setup_cred_chain(struct md_proto_driver_t *d, 
                                                struct md_result_t *result);
    apr_status_t md_acme_drive_cert_poll(struct md_proto_driver_t *d, int only_once);
    
    #endif /* md_acme_drive_h */
    
    ������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_reg.c��������������������������������������������������������������������0000664�0001751�0001751�00000135422�14750656217�016317� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_hash.h>
    #include <apr_strings.h>
    #include <apr_uri.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_event.h"
    #include "md_log.h"
    #include "md_json.h"
    #include "md_result.h"
    #include "md_reg.h"
    #include "md_ocsp.h"
    #include "md_store.h"
    #include "md_status.h"
    #include "md_tailscale.h"
    #include "md_util.h"
    
    #include "md_acme.h"
    #include "md_acme_acct.h"
    
    struct md_reg_t {
        apr_pool_t *p;
        struct md_store_t *store;
        struct apr_hash_t *protos;
        struct apr_hash_t *certs;
        int can_http;
        int can_https;
        const char *proxy_url;
        const char *ca_file;
        int domains_frozen;
        md_timeslice_t *renew_window;
        md_timeslice_t *warn_window;
        md_job_notify_cb *notify;
        void *notify_ctx;
        apr_time_t min_delay;
        int retry_failover;
        int use_store_locks;
        apr_time_t lock_wait_timeout;
    };
    
    /**************************************************************************************************/
    /* life cycle */
    
    static apr_status_t load_props(md_reg_t *reg, apr_pool_t *p)
    {
        md_json_t *json;
        apr_status_t rv;
        
        rv = md_store_load(reg->store, MD_SG_NONE, NULL, MD_FN_HTTPD_JSON, 
                           MD_SV_JSON, (void**)&json, p);
        if (APR_SUCCESS == rv) {
            if (md_json_has_key(json, MD_KEY_PROTO, MD_KEY_HTTP, NULL)) {
                reg->can_http = md_json_getb(json, MD_KEY_PROTO, MD_KEY_HTTP, NULL);
            }
            if (md_json_has_key(json, MD_KEY_PROTO, MD_KEY_HTTPS, NULL)) {
                reg->can_https = md_json_getb(json, MD_KEY_PROTO, MD_KEY_HTTPS, NULL);
            }
        }
        else if (APR_STATUS_IS_ENOENT(rv)) {
            rv = APR_SUCCESS;
        }
        else {
            apr_status_t rv2;
            md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, p,
                          "removing md/%s on error loading it", MD_FN_HTTPD_JSON);
            rv2 = md_store_remove(reg->store, MD_SG_NONE, NULL, MD_FN_HTTPD_JSON,
                                  p, TRUE);
            if (rv2 != APR_SUCCESS)
              md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, p,
                            "error removing md/%s", MD_FN_HTTPD_JSON);
            else
              rv = APR_SUCCESS;
        }
        return rv;
    }
    
    apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *p, struct md_store_t *store,
                               const char *proxy_url, const char *ca_file,
                               apr_time_t min_delay, int retry_failover,
                               int use_store_locks, apr_time_t lock_wait_timeout)
    {
        md_reg_t *reg;
        apr_status_t rv;
        
        reg = apr_pcalloc(p, sizeof(*reg));
        reg->p = p;
        reg->store = store;
        reg->protos = apr_hash_make(p);
        reg->certs = apr_hash_make(p);
        reg->can_http = 1;
        reg->can_https = 1;
        reg->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL;
        reg->ca_file = (ca_file && apr_strnatcasecmp("none", ca_file))?
                        apr_pstrdup(p, ca_file) : NULL;
        reg->min_delay = min_delay;
        reg->retry_failover = retry_failover;
        reg->use_store_locks = use_store_locks;
        reg->lock_wait_timeout = lock_wait_timeout;
    
        md_timeslice_create(&reg->renew_window, p, MD_TIME_LIFE_NORM, MD_TIME_RENEW_WINDOW_DEF); 
        md_timeslice_create(&reg->warn_window, p, MD_TIME_LIFE_NORM, MD_TIME_WARN_WINDOW_DEF); 
        
        if (APR_SUCCESS == (rv = md_acme_protos_add(reg->protos, p))
            && APR_SUCCESS == (rv = md_tailscale_protos_add(reg->protos, p))) {
            rv = load_props(reg, p);
        }
        
        *preg = (rv == APR_SUCCESS)? reg : NULL;
        return rv;
    }
    
    struct md_store_t *md_reg_store_get(md_reg_t *reg)
    {
        return reg->store;
    }
    
    /**************************************************************************************************/
    /* checks */
    
    static apr_status_t check_values(md_reg_t *reg, apr_pool_t *p, const md_t *md, int fields)
    {
        apr_status_t rv = APR_SUCCESS;
        const char *err = NULL;
        
        if (MD_UPD_DOMAINS & fields) {
            const md_t *other;
            const char *domain;
            int i;
            
            if (!md->domains || md->domains->nelts <= 0) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, APR_EINVAL, p, 
                              "empty domain list: %s", md->name);
                return APR_EINVAL;
            }
            
            for (i = 0; i < md->domains->nelts; ++i) {
                domain = APR_ARRAY_IDX(md->domains, i, const char *);
                if (!md_dns_is_name(p, domain, 1) && !md_dns_is_wildcard(p, domain)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, p, 
                                  "md %s with invalid domain name: %s", md->name, domain);
                    return APR_EINVAL;
                }
            }
    
            if (NULL != (other = md_reg_find_overlap(reg, md, &domain, p))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, p, 
                              "md %s shares domain '%s' with md %s", 
                              md->name, domain, other->name);
                return APR_EINVAL;
            }
        }
        
        if (MD_UPD_CONTACTS & fields) {
            const char *contact;
            int i;
    
            for (i = 0; i < md->contacts->nelts && !err; ++i) {
                contact = APR_ARRAY_IDX(md->contacts, i, const char *);
                rv = md_util_abs_uri_check(p, contact, &err);
                
                if (err) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, p, 
                                  "contact for %s invalid (%s): %s", md->name, err, contact);
                    return APR_EINVAL;
                }
            }
        }
        
        if ((MD_UPD_CA_URL & fields) && md->ca_urls) { /* setting to empty is ok */
            int i;
            const char *url;
            for (i = 0; i < md->ca_urls->nelts; ++i) {
                url = APR_ARRAY_IDX(md->ca_urls, i, const char*);
                rv = md_util_abs_uri_check(p, url, &err);
                if (err) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, p,
                                  "CA url for %s invalid (%s): %s", md->name, err, url);
                    return APR_EINVAL;
                }
            }
        }
        
        if ((MD_UPD_CA_PROTO & fields) && md->ca_proto) { /* setting to empty is ok */
            /* Do we want to restrict this to "known" protocols? */
        }
        
        if ((MD_UPD_CA_ACCOUNT & fields) && md->ca_account) { /* setting to empty is ok */
            /* hmm, in case we know the protocol, some checks could be done */
        }
    
        if ((MD_UPD_AGREEMENT & fields) && md->ca_agreement
            && strcmp("accepted", md->ca_agreement)) { /* setting to empty is ok */
            rv = md_util_abs_uri_check(p, md->ca_agreement, &err);
            if (err) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, p, 
                              "CA url for %s invalid (%s): %s", md->name, err, md->ca_agreement);
                return APR_EINVAL;
            }
        }
    
        return rv;
    }
    
    /**************************************************************************************************/
    /* state assessment */
    
    static apr_status_t state_init(md_reg_t *reg, apr_pool_t *p, md_t *md)
    {
        md_state_t state = MD_S_COMPLETE;
        const char *state_descr = NULL;
        const md_pubcert_t *pub;
        const md_cert_t *cert;
        const md_pkey_spec_t *spec;
        apr_status_t rv = APR_SUCCESS;
        int i, is_static = (md->cert_files && md->cert_files->nelts);
    
        if (md->renew_window == NULL) md->renew_window = reg->renew_window;
        if (md->warn_window == NULL) md->warn_window = reg->warn_window;
    
        if(is_static) {
          if(md->renew_mode == MD_RENEW_AUTO)
            md->renew_mode = MD_RENEW_MANUAL;
        }
    
        if (md->domains && md->domains->pool != p) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p,
                          "md{%s}: state_init called with foreign pool", md->name);
        }
    
        for (i = 0; i < md_cert_count(md); ++i) {
            spec = md_pkeys_spec_get(md->pks, i);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, p,
                          "md{%s}: check cert %s", md->name, md_pkey_spec_name(spec));
            rv = md_reg_get_pubcert(&pub, reg, md, i, p);
            if (APR_SUCCESS == rv) {
                cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
                if (!md_is_covered_by_alt_names(md, pub->alt_names)) {
                    state = MD_S_INCOMPLETE;
                    state_descr = apr_psprintf(p, "certificate(%s) does not cover all domains.",
                                               md_pkey_spec_name(spec));
                    goto cleanup;
                }
                if (!md->must_staple != !md_cert_must_staple(cert)) {
                    state = MD_S_INCOMPLETE;
                    state_descr = apr_psprintf(p, "'must-staple' is%s requested, but "
                                  "certificate(%s) has it%s enabled.",
                                  md->must_staple? "" : " not",
                                  md_pkey_spec_name(spec),
                                  !md->must_staple? "" : " not");
                    goto cleanup;
                }
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "md{%s}: certificate(%d) is ok",
                              md->name, i);
            }
            else if (APR_STATUS_IS_ENOENT(rv)) {
                state = MD_S_INCOMPLETE;
                state_descr = apr_psprintf(p, "certificate(%s) is missing",
                                           md_pkey_spec_name(spec));
                rv = APR_SUCCESS;
                goto cleanup;
            }
            else {
                state = MD_S_ERROR;
                state_descr = "error initializing";
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, "md{%s}: error", md->name);
                goto cleanup;
            }
        }
    
    cleanup:
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, p, "md{%s}: state=%d, %s",
                      md->name, state, state_descr);
        md->state = state;
        md->state_descr = state_descr;
        return rv;
    }
    
    /**************************************************************************************************/
    /* iteration */
    
    typedef struct {
        md_reg_t *reg;
        md_reg_do_cb *cb;
        void *baton;
        const char *exclude;
        const void *result;
    } reg_do_ctx;
    
    static int reg_md_iter(void *baton, md_store_t *store, md_t *md, apr_pool_t *ptemp)
    {
        reg_do_ctx *ctx = baton;
        
        (void)store;
        if (!ctx->exclude || strcmp(ctx->exclude, md->name)) {
            state_init(ctx->reg, ptemp, (md_t*)md);
            return ctx->cb(ctx->baton, ctx->reg, md);
        }
        return 1;
    }
    
    static int reg_do(md_reg_do_cb *cb, void *baton, md_reg_t *reg, apr_pool_t *p, const char *exclude)
    {
        reg_do_ctx ctx;
        
        ctx.reg = reg;
        ctx.cb = cb;
        ctx.baton = baton;
        ctx.exclude = exclude;
        return md_store_md_iter(reg_md_iter, &ctx, reg->store, p, MD_SG_DOMAINS, "*");
    }
    
    
    int md_reg_do(md_reg_do_cb *cb, void *baton, md_reg_t *reg, apr_pool_t *p)
    {
        return reg_do(cb, baton, reg, p, NULL);
    }
    
    /**************************************************************************************************/
    /* lookup */
    
    md_t *md_reg_get(md_reg_t *reg, const char *name, apr_pool_t *p)
    {
        md_t *md;
        
        if (APR_SUCCESS == md_load(reg->store, MD_SG_DOMAINS, name, &md, p)) {
            state_init(reg, p, md);
            return md;
        }
        return NULL;
    }
    
    typedef struct {
        const char *domain;
        md_t *md;
    } find_domain_ctx;
    
    static int find_domain(void *baton, md_reg_t *reg, md_t *md)
    {
        find_domain_ctx *ctx = baton;
        
        (void)reg;
        if (md_contains(md, ctx->domain, 0)) {
            ctx->md = md;
            return 0;
        }
        return 1;
    }
    
    md_t *md_reg_find(md_reg_t *reg, const char *domain, apr_pool_t *p)
    {
        find_domain_ctx ctx;
    
        ctx.domain = domain;
        ctx.md = NULL;
        
        md_reg_do(find_domain, &ctx, reg, p);
        if (ctx.md) {
            state_init(reg, p, ctx.md);
        }
        return ctx.md;
    }
    
    typedef struct {
        const md_t *md_checked;
        md_t *md;
        const char *s;
    } find_overlap_ctx;
    
    static int find_overlap(void *baton, md_reg_t *reg, md_t *md)
    {
        find_overlap_ctx *ctx = baton;
        const char *overlap;
        
        (void)reg;
        if ((overlap = md_common_name(ctx->md_checked, md))) {
            ctx->md = md;
            ctx->s = overlap;
            return 0;
        }
        return 1;
    }
    
    md_t *md_reg_find_overlap(md_reg_t *reg, const md_t *md, const char **pdomain, apr_pool_t *p)
    {
        find_overlap_ctx ctx;
        
        ctx.md_checked = md;
        ctx.md = NULL;
        ctx.s = NULL;
        
        reg_do(find_overlap, &ctx, reg, p, md->name);
        if (pdomain && ctx.s) {
            *pdomain = ctx.s;
        }
        if (ctx.md) {
            state_init(reg, p, ctx.md);
        }
        return ctx.md;
    }
    
    /**************************************************************************************************/
    /* manipulation */
    
    static apr_status_t p_md_add(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_reg_t *reg = baton;
        apr_status_t rv = APR_SUCCESS;
        md_t *md, *mine;
        int do_check;
        
        md = va_arg(ap, md_t *);
        do_check = va_arg(ap, int);
    
        if (reg->domains_frozen) return APR_EACCES; 
        mine = md_clone(ptemp, md);
        if (do_check && APR_SUCCESS != (rv = check_values(reg, ptemp, md, MD_UPD_ALL))) goto leave;
        if (APR_SUCCESS != (rv = state_init(reg, ptemp, mine))) goto leave;
        rv = md_save(reg->store, p, MD_SG_DOMAINS, mine, 1);
    leave:
        return rv;
    }
    
    static apr_status_t add_md(md_reg_t *reg, md_t *md, apr_pool_t *p, int do_checks)
    {
        return md_util_pool_vdo(p_md_add, reg, p, md, do_checks, NULL);
    }
    
    apr_status_t md_reg_add(md_reg_t *reg, md_t *md, apr_pool_t *p)
    {
        return add_md(reg, md, p, 1);
    }
    
    static apr_status_t p_md_update(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_reg_t *reg = baton;
        apr_status_t rv = APR_SUCCESS;
        const char *name;
        const md_t *md, *updates;
        int fields, do_checks;
        md_t *nmd;
        
        name = va_arg(ap, const char *);
        updates = va_arg(ap, const md_t *);
        fields = va_arg(ap, int);
        do_checks = va_arg(ap, int);
        
        if (NULL == (md = md_reg_get(reg, name, ptemp))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, APR_ENOENT, ptemp, "md %s", name);
            return APR_ENOENT;
        }
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ptemp, "md[%s]: update store", name);
        
        if (do_checks && APR_SUCCESS != (rv = check_values(reg, ptemp, updates, fields))) {
            return rv;
        }
        
        if (reg->domains_frozen) return APR_EACCES; 
        nmd = md_copy(ptemp, md);
        if (MD_UPD_DOMAINS & fields) {
            nmd->domains = updates->domains;
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update domains: %s", name);
        }
        if (MD_UPD_CA_URL & fields) {
            nmd->ca_urls = (updates->ca_urls?
                            apr_array_copy(p, updates->ca_urls) : NULL);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update ca url: %s", name);
        }
        if (MD_UPD_CA_PROTO & fields) {
            nmd->ca_proto = updates->ca_proto;
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update ca protocol: %s", name);
        }
        if (MD_UPD_CA_ACCOUNT & fields) {
            nmd->ca_account = updates->ca_account;
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update account: %s", name);
        }
        if (MD_UPD_CONTACTS & fields) {
            nmd->contacts = updates->contacts;
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update contacts: %s", name);
        }
        if (MD_UPD_AGREEMENT & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update agreement: %s", name);
            nmd->ca_agreement = updates->ca_agreement;
        }
        if (MD_UPD_DRIVE_MODE & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update drive-mode: %s", name);
            nmd->renew_mode = updates->renew_mode;
        }
        if (MD_UPD_RENEW_WINDOW & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update renew-window: %s", name);
            *nmd->renew_window = *updates->renew_window;
        }
        if (MD_UPD_WARN_WINDOW & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update warn-window: %s", name);
            *nmd->warn_window = *updates->warn_window;
        }
        if (MD_UPD_CA_CHALLENGES & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update ca challenges: %s", name);
            nmd->ca_challenges = (updates->ca_challenges? 
                                  apr_array_copy(p, updates->ca_challenges) : NULL);
        }
        if (MD_UPD_PKEY_SPEC & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update pkey spec: %s", name);
            nmd->pks = md_pkeys_spec_clone(p, updates->pks);
        }
        if (MD_UPD_REQUIRE_HTTPS & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update require-https: %s", name);
            nmd->require_https = updates->require_https;
        }
        if (MD_UPD_TRANSITIVE & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update transitive: %s", name);
            nmd->transitive = updates->transitive;
        }
        if (MD_UPD_MUST_STAPLE & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update must-staple: %s", name);
            nmd->must_staple = updates->must_staple;
        }
        if (MD_UPD_PROTO & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update proto: %s", name);
            nmd->acme_tls_1_domains = updates->acme_tls_1_domains;
        }
        if (MD_UPD_STAPLING & fields) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "update stapling: %s", name);
            nmd->stapling = updates->stapling;
        }
        
        if (fields && APR_SUCCESS == (rv = md_save(reg->store, p, MD_SG_DOMAINS, nmd, 0))) {
            rv = state_init(reg, ptemp, nmd);
        }
        return rv;
    }
    
    apr_status_t md_reg_update(md_reg_t *reg, apr_pool_t *p, 
                               const char *name, const md_t *md, int fields, 
                               int do_checks)
    {
        return md_util_pool_vdo(p_md_update, reg, p, name, md, fields, do_checks, NULL);
    }
    
    apr_status_t md_reg_delete_acct(md_reg_t *reg, apr_pool_t *p, const char *acct_id) 
    {
        apr_status_t rv = APR_SUCCESS;
        
        rv = md_store_remove(reg->store, MD_SG_ACCOUNTS, acct_id, MD_FN_ACCOUNT, p, 1);
        if (APR_SUCCESS == rv) {
            md_store_remove(reg->store, MD_SG_ACCOUNTS, acct_id, MD_FN_ACCT_KEY, p, 1);
        }
        return rv;
    }
    
    /**************************************************************************************************/
    /* certificate related */
    
    static apr_status_t pubcert_load(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_reg_t *reg = baton;
        apr_array_header_t *certs;
        md_pubcert_t *pubcert, **ppubcert;
        const md_t *md;
        int index;
        const md_cert_t *cert;
        md_cert_state_t cert_state;
        md_store_group_t group;
        apr_status_t rv;
        
        ppubcert = va_arg(ap, md_pubcert_t **);
        group = (md_store_group_t)va_arg(ap, int);
        md = va_arg(ap, const md_t *);
        index = va_arg(ap, int);
        
        if (md->cert_files && md->cert_files->nelts) {
            rv = md_chain_fload(&certs, p, APR_ARRAY_IDX(md->cert_files, index, const char *));
        }
        else {
            md_pkey_spec_t *spec = md_pkeys_spec_get(md->pks, index);;
            rv = md_pubcert_load(reg->store, group, md->name, spec, &certs, p);
        }
        if (APR_SUCCESS != rv) goto leave;
        if (certs->nelts == 0) {
            rv = APR_ENOENT;
            goto leave;
        }
    
        pubcert = apr_pcalloc(p, sizeof(*pubcert));
        pubcert->certs = certs;
        cert = APR_ARRAY_IDX(certs, 0, const md_cert_t *);
        if (APR_SUCCESS != (rv = md_cert_get_alt_names(&pubcert->alt_names, cert, p))) goto leave;
        switch ((cert_state = md_cert_state_get(cert))) {
            case MD_CERT_VALID:
            case MD_CERT_EXPIRED:
                break;
            default:
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, ptemp, 
                              "md %s has unexpected cert state: %d", md->name, cert_state);
                rv = APR_ENOTIMPL;
                break;
        }
    leave:
        *ppubcert = (APR_SUCCESS == rv)? pubcert : NULL;
        return rv;
    }
    
    apr_status_t md_reg_get_pubcert(const md_pubcert_t **ppubcert, md_reg_t *reg, 
                                    const md_t *md, int i, apr_pool_t *p)
    {
        apr_status_t rv = APR_SUCCESS;
        const md_pubcert_t *pubcert;
        const char *name;
    
        name = apr_psprintf(p, "%s[%d]", md->name, i);
        pubcert = apr_hash_get(reg->certs, name, (apr_ssize_t)strlen(name));
        if (!pubcert && !reg->domains_frozen) {
            rv = md_util_pool_vdo(pubcert_load, reg, reg->p, &pubcert, MD_SG_DOMAINS, md, i, NULL);
            if (APR_STATUS_IS_ENOENT(rv)) {
                /* We cache it missing with an empty record */
                pubcert = apr_pcalloc(reg->p, sizeof(*pubcert));
            }
            else if (APR_SUCCESS != rv) goto leave;
            if (p != reg->p) name = apr_pstrdup(reg->p, name);
            apr_hash_set(reg->certs, name, (apr_ssize_t)strlen(name), pubcert);
        }
    leave:
        if (APR_SUCCESS == rv && (!pubcert || !pubcert->certs)) {
            rv = APR_ENOENT;
        }
        *ppubcert = (APR_SUCCESS == rv)? pubcert : NULL;
        return rv;
    }
    
    apr_status_t md_reg_get_cred_files(const char **pkeyfile, const char **pcertfile,
                                       md_reg_t *reg, md_store_group_t group, 
                                       const md_t *md, md_pkey_spec_t *spec, apr_pool_t *p)
    {
        apr_status_t rv;
        
        rv = md_store_get_fname(pkeyfile, reg->store, group, md->name, md_pkey_filename(spec, p), p);
        if (APR_SUCCESS != rv) return rv;
        if (!md_file_exists(*pkeyfile, p)) return APR_ENOENT;
        rv = md_store_get_fname(pcertfile, reg->store, group, md->name, md_chain_filename(spec, p), p);
        if (APR_SUCCESS != rv) return rv;
        if (!md_file_exists(*pcertfile, p)) return APR_ENOENT;
        return APR_SUCCESS;
    }
    
    apr_time_t md_reg_valid_until(md_reg_t *reg, const md_t *md, apr_pool_t *p)
    {
        const md_pubcert_t *pub;
        const md_cert_t *cert;
        int i;
        apr_time_t t, valid_until = 0;
        apr_status_t rv;
        
        for (i = 0; i < md_cert_count(md); ++i) {
            rv = md_reg_get_pubcert(&pub, reg, md, i, p);
            if (APR_SUCCESS == rv) {
                cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
                t = md_cert_get_not_after(cert);
                if (valid_until == 0 || t < valid_until) {
                    valid_until = t;
                }
            }
        }
        return valid_until;
    }
    
    apr_time_t md_reg_renew_at(md_reg_t *reg, const md_t *md, apr_pool_t *p)
    {
        const md_pubcert_t *pub;
        const md_cert_t *cert;
        md_timeperiod_t certlife, renewal;
        int i;
        apr_time_t renew_at = 0;
        apr_status_t rv;
        
        if (md->state == MD_S_INCOMPLETE) return apr_time_now();
        for (i = 0; i < md_cert_count(md); ++i) {
            rv = md_reg_get_pubcert(&pub, reg, md, i, p);
            if (APR_STATUS_IS_ENOENT(rv)) return apr_time_now();
            if (APR_SUCCESS == rv) {
                cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
                certlife.start = md_cert_get_not_before(cert);
                certlife.end = md_cert_get_not_after(cert);
    
                renewal = md_timeperiod_slice_before_end(&certlife, md->renew_window);
                if (md_log_is_level(p, MD_LOG_TRACE1)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, p, 
                                  "md[%s]: certificate(%d) valid[%s] renewal[%s]", 
                                  md->name, i,  
                                  md_timeperiod_print(p, &certlife),
                                  md_timeperiod_print(p, &renewal));
                }
                
                if (renew_at == 0 || renewal.start < renew_at) {
                    renew_at = renewal.start; 
                }
            }
        }
        return renew_at;
    }
    
    int md_reg_should_renew(md_reg_t *reg, const md_t *md, apr_pool_t *p) 
    {
        apr_time_t renew_at;
        
        renew_at = md_reg_renew_at(reg, md, p);
        return renew_at && (renew_at <= apr_time_now());
    }
    
    int md_reg_should_warn(md_reg_t *reg, const md_t *md, apr_pool_t *p)
    {
        const md_pubcert_t *pub;
        const md_cert_t *cert;
        md_timeperiod_t certlife, warn;
        int i;
        apr_status_t rv;
        
        if (md->state == MD_S_INCOMPLETE) return 0;
        for (i = 0; i < md_cert_count(md); ++i) {
            rv = md_reg_get_pubcert(&pub, reg, md, i, p);
            if (APR_STATUS_IS_ENOENT(rv)) return 0;
            if (APR_SUCCESS == rv) {
                cert = APR_ARRAY_IDX(pub->certs, 0, const md_cert_t*);
                certlife.start = md_cert_get_not_before(cert);
                certlife.end = md_cert_get_not_after(cert);
                
                warn = md_timeperiod_slice_before_end(&certlife, md->warn_window);
                if (md_log_is_level(p, MD_LOG_TRACE1)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, p, 
                                  "md[%s]: certificate(%d) life[%s] warn[%s]", 
                                  md->name, i,  
                                  md_timeperiod_print(p, &certlife),
                                  md_timeperiod_print(p, &warn));
                }
                if (md_timeperiod_has_started(&warn, apr_time_now())) {
                    return 1;
                }
            }
        }
        return 0;
    }
    
    /**************************************************************************************************/
    /* syncing */
    
    apr_status_t md_reg_set_props(md_reg_t *reg, apr_pool_t *p, int can_http, int can_https)
    {
        if (reg->can_http != can_http || reg->can_https != can_https) {
            md_json_t *json;
            
            if (reg->domains_frozen) return APR_EACCES; 
            reg->can_http = can_http;
            reg->can_https = can_https;
            
            json = md_json_create(p);
            md_json_setb(can_http, json, MD_KEY_PROTO, MD_KEY_HTTP, NULL);
            md_json_setb(can_https, json, MD_KEY_PROTO, MD_KEY_HTTPS, NULL);
            
            return md_store_save(reg->store, p, MD_SG_NONE, NULL, MD_FN_HTTPD_JSON, MD_SV_JSON, json, 0);
        }
        return APR_SUCCESS;
    }
    
    static md_t *find_closest_match(apr_array_header_t *mds, const md_t *md)
    {
        md_t *candidate, *m;
        apr_size_t cand_n, n;
        int i;
        
        candidate = md_get_by_name(mds, md->name);
        if (!candidate) {
            /* try to find an instance that contains all domain names from md */ 
            for (i = 0; i < mds->nelts; ++i) {
                m = APR_ARRAY_IDX(mds, i, md_t *);
                if (md_contains_domains(m, md)) {
                    return m;
                }
            }
            /* no matching name and no md in the list has all domains.
             * We consider that managed domain as closest match that contains at least one
             * domain name from md, ONLY if there is no other one that also has.
             */
            cand_n = 0;
            for (i = 0; i < mds->nelts; ++i) {
                m = APR_ARRAY_IDX(mds, i, md_t *);
                n = md_common_name_count(md, m);
                if (n > cand_n) {
                    candidate = m;
                    cand_n = n;
                }
            }
        }
        return candidate;
    }
    
    typedef struct {
        apr_pool_t *p;
        apr_array_header_t *master_mds;
        apr_array_header_t *store_names;
        apr_array_header_t *maybe_new_mds;
        apr_array_header_t *new_mds;
        apr_array_header_t *unassigned_mds;
    } sync_ctx_v2;
    
    static int iter_add_name(void *baton, const char *dir, const char *name, 
                             md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
    {
        sync_ctx_v2 *ctx = baton;
        
        (void)dir;
        (void)value;
        (void)ptemp;
        (void)vtype;
        APR_ARRAY_PUSH(ctx->store_names, const char*) = apr_pstrdup(ctx->p, name);
        return APR_SUCCESS;
    }
    
    /* A better scaling version:
     *  1. The consistency of the MDs in 'master_mds' has already been verified. E.g.
     *     that no domain lists overlap etc.
     *  2. All MD storage that exists will be overwritten by the settings we have.
     *     And "exists" meaning that "store/MD_SG_DOMAINS/name" exists.
     *  3. For MDs that have no directory in "store/MD_SG_DOMAINS", we load all MDs
     *     outside the list of known names from MD_SG_DOMAINS. In this list, we
     *     look for the MD with the most domain overlap. 
     *      - if we find it, we assume this is a rename and move the old MD to the new name.
     *      - if not, MD is completely new.
     *  4. Any MD in store that does not match the "master_mds" will just be left as is. 
     */
    apr_status_t md_reg_sync_start(md_reg_t *reg, apr_array_header_t *master_mds, apr_pool_t *p) 
    {
        sync_ctx_v2 ctx;
        apr_status_t rv;
        md_t *md, *oldmd;
        const char *name;
        int i, idx;
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "sync MDs, start");
         
        ctx.p = p;
        ctx.master_mds = master_mds;
        ctx.store_names = apr_array_make(p, master_mds->nelts + 100, sizeof(const char*));
        ctx.maybe_new_mds = apr_array_make(p, master_mds->nelts, sizeof(md_t*));
        ctx.new_mds = apr_array_make(p, master_mds->nelts, sizeof(md_t*));
        ctx.unassigned_mds = apr_array_make(p, master_mds->nelts, sizeof(md_t*));
        
        rv = md_store_iter_names(iter_add_name, &ctx, reg->store, p, MD_SG_DOMAINS, "*");
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "listing existing store MD names"); 
            goto leave;
        }
        
        /* Get all MDs that are not already present in store */
        for (i = 0; i < ctx.master_mds->nelts; ++i) {
            md = APR_ARRAY_IDX(ctx.master_mds, i, md_t*);
            idx = md_array_str_index(ctx.store_names, md->name, 0, 1);
            if (idx < 0) {
                APR_ARRAY_PUSH(ctx.maybe_new_mds, md_t*) = md;
            }
            else {
                md_array_remove_at(ctx.store_names, idx);
            }
        }
        
        if (ctx.maybe_new_mds->nelts == 0) {
            /* none new */
            goto leave;
        }
        if (ctx.store_names->nelts == 0) {
            /* all new */
            for (i = 0; i < ctx.maybe_new_mds->nelts; ++i) {
                md = APR_ARRAY_IDX(ctx.maybe_new_mds, i, md_t*);
                APR_ARRAY_PUSH(ctx.new_mds, md_t*) = md;
            }
            goto leave;
        }
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                      "sync MDs, %d potentially new MDs detected, looking for renames among "
                      "the %d unassigned store domains", (int)ctx.maybe_new_mds->nelts,
                      (int)ctx.store_names->nelts);
        for (i = 0; i < ctx.store_names->nelts; ++i) {
            name = APR_ARRAY_IDX(ctx.store_names, i, const char*);
            if (APR_SUCCESS == md_load(reg->store, MD_SG_DOMAINS, name, &md, p)) {
                APR_ARRAY_PUSH(ctx.unassigned_mds, md_t*) = md;
            } 
        }
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                      "sync MDs, %d MDs maybe new, checking store", (int)ctx.maybe_new_mds->nelts);
        for (i = 0; i < ctx.maybe_new_mds->nelts; ++i) {
            md = APR_ARRAY_IDX(ctx.maybe_new_mds, i, md_t*);
            oldmd = find_closest_match(ctx.unassigned_mds, md);
            if (oldmd) {
                /* found the rename, move the domains and possible staging directory */
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                              "sync MDs, found MD %s under previous name %s", md->name, oldmd->name);
                rv = md_store_rename(reg->store, p, MD_SG_DOMAINS, oldmd->name, md->name);
                if (APR_SUCCESS != rv) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, 
                                  "sync MDs, renaming MD %s to %s failed", oldmd->name, md->name);
                    /* ignore it? */
                }
                md_store_rename(reg->store, p, MD_SG_STAGING, oldmd->name, md->name);
                md_array_remove(ctx.unassigned_mds, oldmd);
            }
            else {
                APR_ARRAY_PUSH(ctx.new_mds, md_t*) = md;
            }
        }
    
    leave:
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                      "sync MDs, %d existing, %d moved, %d new.", 
                      (int)ctx.master_mds->nelts - ctx.maybe_new_mds->nelts,
                      (int)ctx.maybe_new_mds->nelts - ctx.new_mds->nelts,
                      (int)ctx.new_mds->nelts);
        return rv;
    }
    
    /** 
     * Finish syncing an MD with the store. 
     * 1. if there are changed properties (or if the MD is new), save it.
     * 2. read any existing certificate and init the state of the memory MD
     */
    apr_status_t md_reg_sync_finish(md_reg_t *reg, md_t *md, apr_pool_t *p, apr_pool_t *ptemp)
    {
        md_t *old;
        apr_status_t rv;
        int changed = 1;
        md_proto_t *proto;
        
        if (!md->ca_proto) {
            md->ca_proto = MD_PROTO_ACME;
        }
        proto = apr_hash_get(reg->protos, md->ca_proto, (apr_ssize_t)strlen(md->ca_proto));
        if (!proto) {
            rv = APR_ENOTIMPL;
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp,
                          "[%s] uses unknown CA protocol '%s'",
                          md->name, md->ca_proto);
            goto leave;
        }
        rv = proto->complete_md(md, p);
        if (APR_SUCCESS != rv) goto leave;
    
        rv = state_init(reg, p, md);
        if (APR_SUCCESS != rv) goto leave;
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "loading md %s", md->name);
        if (APR_SUCCESS == md_load(reg->store, MD_SG_DOMAINS, md->name, &old, ptemp)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "loaded md %s", md->name);
            /* Some parts are kept from old, lacking new values */
            if ((!md->contacts || apr_is_empty_array(md->contacts)) && old->contacts) {
                md->contacts = md_array_str_clone(p, old->contacts);
            } 
            if (md->ca_challenges && old->ca_challenges) {
                if (!md_array_str_eq(md->ca_challenges, old->ca_challenges, 0)) {
                    md->ca_challenges = md_array_str_compact(p, md->ca_challenges, 0);
                }
            }
            if (!md->ca_effective && old->ca_effective) {
                md->ca_effective = apr_pstrdup(p, old->ca_effective);
            }
            if (!md->ca_account && old->ca_account) {
                md->ca_account = apr_pstrdup(p, old->ca_account);
            }
            
            /* if everything remains the same, spare the write back */
            if (!MD_VAL_UPDATE(md, old, state)
                && md_array_str_eq(md->ca_urls, old->ca_urls, 0)
                && !MD_SVAL_UPDATE(md, old, ca_proto)
                && !MD_SVAL_UPDATE(md, old, ca_agreement)
                && !MD_VAL_UPDATE(md, old, transitive)
                && md_equal_domains(md, old, 1)
                && !MD_VAL_UPDATE(md, old, renew_mode)
                && md_timeslice_eq(md->renew_window, old->renew_window)
                && md_timeslice_eq(md->warn_window, old->warn_window)
                && md_pkeys_spec_eq(md->pks, old->pks)
                && !MD_VAL_UPDATE(md, old, require_https)
                && !MD_VAL_UPDATE(md, old, must_staple)
                && md_array_str_eq(md->acme_tls_1_domains, old->acme_tls_1_domains, 0)
                && !MD_VAL_UPDATE(md, old, stapling)
                && md_array_str_eq(md->contacts, old->contacts, 0)
                && md_array_str_eq(md->cert_files, old->cert_files, 0)
                && md_array_str_eq(md->pkey_files, old->pkey_files, 0)
                && md_array_str_eq(md->ca_challenges, old->ca_challenges, 0)) {
                changed = 0;
            }
        }
        if (changed) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "saving md %s", md->name);
            rv = md_save(reg->store, ptemp, MD_SG_DOMAINS, md, 0);
        }
    leave:
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "sync MDs, finish done");
        return rv;
    }
    
    apr_status_t md_reg_remove(md_reg_t *reg, apr_pool_t *p, const char *name, int archive)
    {
        if (reg->domains_frozen) return APR_EACCES; 
        return md_store_move(reg->store, p, MD_SG_DOMAINS, MD_SG_ARCHIVE, name, archive);
    }
    
    typedef struct {
        md_reg_t *reg;
        apr_pool_t *p;
        apr_array_header_t *mds;
    } cleanup_challenge_ctx;
     
    static apr_status_t cleanup_challenge_inspector(void *baton, const char *dir, const char *name, 
                                                    md_store_vtype_t vtype, void *value, 
                                                    apr_pool_t *ptemp)
    {
        cleanup_challenge_ctx *ctx = baton;
        const md_t *md;
        int i, used;
        apr_status_t rv;
        
        (void)value;
        (void)vtype;
        (void)dir;
        for (used = 0, i = 0; i < ctx->mds->nelts && !used; ++i) {
            md = APR_ARRAY_IDX(ctx->mds, i, const md_t *);
            used = !strcmp(name, md->name);
        }
        if (!used) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ptemp, 
                          "challenges/%s: not in use, purging", name);
            rv = md_store_purge(ctx->reg->store, ctx->p, MD_SG_CHALLENGES, name);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, ptemp, 
                              "challenges/%s: unable to purge", name);
            }
        }
        return APR_SUCCESS;
    }
    
    apr_status_t md_reg_cleanup_challenges(md_reg_t *reg, apr_pool_t *p, apr_pool_t *ptemp, 
                                           apr_array_header_t *mds)
    {
        apr_status_t rv;
        cleanup_challenge_ctx ctx;
    
        (void)p;
        ctx.reg = reg;
        ctx.p = ptemp;
        ctx.mds = mds;
        rv = md_store_iter_names(cleanup_challenge_inspector, &ctx, reg->store, ptemp, 
                                 MD_SG_CHALLENGES, "*");
        return rv;
    }
    
    
    /**************************************************************************************************/
    /* driving */
    
    static apr_status_t run_init(void *baton, apr_pool_t *p, ...)
    {
        va_list ap;
        md_reg_t *reg = baton;
        const md_t *md;
        md_proto_driver_t *driver, **pdriver;
        md_result_t *result;
        apr_table_t *env;
        const char *s;
        int preload;
        
        (void)p;
        va_start(ap, p);
        pdriver = va_arg(ap, md_proto_driver_t **);
        md = va_arg(ap, const md_t *);
        preload = va_arg(ap, int);
        env = va_arg(ap, apr_table_t *);
        result = va_arg(ap, md_result_t *); 
        va_end(ap);
        
        *pdriver = driver = apr_pcalloc(p, sizeof(*driver));
    
        driver->p = p;
        driver->env = env? apr_table_copy(p, env) : apr_table_make(p, 10);
        driver->reg = reg;
        driver->store = md_reg_store_get(reg);
        driver->proxy_url = reg->proxy_url;
        driver->ca_file = reg->ca_file;
        driver->md = md;
        driver->can_http = reg->can_http;
        driver->can_https = reg->can_https;
        
        s = apr_table_get(driver->env, MD_KEY_ACTIVATION_DELAY);
        if (!s || APR_SUCCESS != md_duration_parse(&driver->activation_delay, s, "d")) {
            driver->activation_delay = 0;
        }
    
        if (!md->ca_proto) {
            md_result_printf(result, APR_EGENERAL, "CA protocol is not defined"); 
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, "md[%s]: %s", md->name, result->detail);
            goto leave;
        }
        
        driver->proto = apr_hash_get(reg->protos, md->ca_proto, (apr_ssize_t)strlen(md->ca_proto));
        if (!driver->proto) {
            md_result_printf(result, APR_EGENERAL, "Unknown CA protocol '%s'", md->ca_proto); 
            goto leave;
        }
        
        if (preload) {
            result->status = driver->proto->init_preload(driver, result);
        }
        else {
            result->status = driver->proto->init(driver, result);
        }
    
    leave:
        if (APR_SUCCESS != result->status) {
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, result->status, p, "md[%s]: %s", md->name, 
                          result->detail? result->detail : "<see error log for details>");
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "%s: init done", md->name);
        }
        return result->status;
    }
    
    static apr_status_t run_test_init(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        const md_t *md;
        apr_table_t *env;
        md_result_t *result;
        md_proto_driver_t *driver;
        
        (void)p;
        md = va_arg(ap, const md_t *);
        env = va_arg(ap, apr_table_t *);
        result = va_arg(ap, md_result_t *); 
    
        return run_init(baton, ptemp, &driver, md, 0, env, result, NULL);
    }
    
    apr_status_t md_reg_test_init(md_reg_t *reg, const md_t *md, struct apr_table_t *env, 
                                  md_result_t *result, apr_pool_t *p)
    {
        return md_util_pool_vdo(run_test_init, reg, p, md, env, result, NULL);
    }
    
    static apr_status_t run_renew(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_reg_t *reg = baton;
        const md_t *md;
        int reset, attempt;
        md_proto_driver_t *driver;
        apr_table_t *env;
        apr_status_t rv;
        md_result_t *result;
        
        (void)p;
        md = va_arg(ap, const md_t *);
        env = va_arg(ap, apr_table_t *);
        reset = va_arg(ap, int); 
        attempt = va_arg(ap, int);
        result = va_arg(ap, md_result_t *);
    
        rv = run_init(reg, ptemp, &driver, md, 0, env, result, NULL);
        if (APR_SUCCESS == rv) { 
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ptemp, "%s: run staging", md->name);
            driver->reset = reset;
            driver->attempt = attempt;
            driver->retry_failover = reg->retry_failover;
            rv = driver->proto->renew(driver, result);
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "%s: staging done", md->name);
        return rv;
    }
    
    apr_status_t md_reg_renew(md_reg_t *reg, const md_t *md, apr_table_t *env, 
                              int reset, int attempt,
                              md_result_t *result, apr_pool_t *p)
    {
        return md_util_pool_vdo(run_renew, reg, p, md, env, reset, attempt, result, NULL);
    }
    
    static apr_status_t run_load_staging(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_reg_t *reg = baton;
        const md_t *md;
        md_proto_driver_t *driver;
        md_result_t *result;
        apr_table_t *env;
        md_job_t *job;
        apr_status_t rv;
        
        /* For the MD,  check if something is in the STAGING area. If none is there, 
         * return that status. Otherwise ask the protocol driver to preload it into
         * a new, temporary area. 
         * If that succeeds, we move the TEMP area over the DOMAINS (causing the 
         * existing one go to ARCHIVE).
         * Finally, we clean up the data from CHALLENGES and STAGING.
         */
        md = va_arg(ap, const md_t*);
        env =  va_arg(ap, apr_table_t*);
        result =  va_arg(ap, md_result_t*);
        
        if (APR_STATUS_IS_ENOENT(rv = md_load(reg->store, MD_SG_STAGING, md->name, NULL, ptemp))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ptemp, "%s: nothing staged", md->name);
            goto out;
        }
        
        rv = run_init(baton, ptemp, &driver, md, 1, env, result, NULL);
        if (APR_SUCCESS != rv) goto out;
        
        apr_hash_set(reg->certs, md->name, (apr_ssize_t)strlen(md->name), NULL);
        md_result_activity_setn(result, "preloading staged to tmp");
        rv = driver->proto->preload(driver, MD_SG_TMP, result);
        if (APR_SUCCESS != rv) goto out;
    
        /* If we had a job saved in STAGING, copy it over too */
        job = md_reg_job_make(reg, md->name, ptemp);
        if (APR_SUCCESS == md_job_load(job)) {
            md_job_set_group(job, MD_SG_TMP);
            md_job_save(job, NULL, ptemp);
        }
        
        /* swap */
        md_result_activity_setn(result, "moving tmp to become new domains");
        rv = md_store_move(reg->store, p, MD_SG_TMP, MD_SG_DOMAINS, md->name, 1);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, NULL);
            goto out;
        }
        
        md_store_purge(reg->store, p, MD_SG_STAGING, md->name);
        md_store_purge(reg->store, p, MD_SG_CHALLENGES, md->name);
        md_result_set(result, APR_SUCCESS, "new certificate successfully saved in domains");
        md_event_holler("installed", md->name, job, result, ptemp);
        if (job->dirty) md_job_save(job, result, ptemp);
        
    out:
        if (!APR_STATUS_IS_ENOENT(rv)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ptemp, "%s: load done", md->name);
        }
        return rv;
    }
    
    apr_status_t md_reg_load_staging(md_reg_t *reg, const md_t *md, apr_table_t *env, 
                                     md_result_t *result, apr_pool_t *p)
    {
        if (reg->domains_frozen) return APR_EACCES;
        return md_util_pool_vdo(run_load_staging, reg, p, md, env, result, NULL);
    }
    
    apr_status_t md_reg_load_stagings(md_reg_t *reg, apr_array_header_t *mds,
                                      apr_table_t *env, apr_pool_t *p)
    {
        apr_status_t rv = APR_SUCCESS;
        md_t *md;
        md_result_t *result;
        int i;
    
        for (i = 0; i < mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mds, i, md_t *);
            result = md_result_md_make(p, md->name);
            rv = md_reg_load_staging(reg, md, env, result, p);
            if (APR_SUCCESS == rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, p, APLOGNO(10068)
                              "%s: staged set activated", md->name);
            }
            else if (!APR_STATUS_IS_ENOENT(rv)) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, APLOGNO(10069)
                              "%s: error loading staged set, purging it", md->name);
                md_store_purge(reg->store, p, MD_SG_STAGING, md->name);
                md_store_purge(reg->store, p, MD_SG_CHALLENGES, md->name);
            }
        }
    
        return rv;
    }
    
    apr_status_t md_reg_lock_global(md_reg_t *reg, apr_pool_t *p)
    {
        apr_status_t rv = APR_SUCCESS;
    
        if (reg->use_store_locks) {
            rv = md_store_lock_global(reg->store, p, reg->lock_wait_timeout);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
                              "unable to acquire global store lock");
            }
        }
        return rv;
    }
    
    void md_reg_unlock_global(md_reg_t *reg, apr_pool_t *p)
    {
        if (reg->use_store_locks) {
            md_store_unlock_global(reg->store, p);
        }
    }
    
    apr_status_t md_reg_freeze_domains(md_reg_t *reg, apr_array_header_t *mds)
    {
        apr_status_t rv = APR_SUCCESS;
        md_t *md;
        const md_pubcert_t *pubcert;
        int i, j;
        
        assert(!reg->domains_frozen);
        /* prefill the certs cache for all mds */
        for (i = 0; i < mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mds, i, md_t*);
            for (j = 0; j < md_cert_count(md); ++j) {
                rv = md_reg_get_pubcert(&pubcert, reg, md, i, reg->p);
                if (APR_SUCCESS != rv && !APR_STATUS_IS_ENOENT(rv)) goto leave;
            }
        }
        reg->domains_frozen = 1;
    leave:
        return rv;
    }
    
    void md_reg_set_renew_window_default(md_reg_t *reg, md_timeslice_t *renew_window)
    {
        *reg->renew_window = *renew_window;
    }
    
    void md_reg_set_warn_window_default(md_reg_t *reg, md_timeslice_t *warn_window)
    {
        *reg->warn_window = *warn_window;
    }
    
    md_job_t *md_reg_job_make(md_reg_t *reg, const char *mdomain, apr_pool_t *p)
    {
        return md_job_make(p, reg->store, MD_SG_STAGING, mdomain, reg->min_delay);
    }
    
    static int get_cert_count(const md_t *md)
    {
        if (md->cert_files && md->cert_files->nelts) {
            return md->cert_files->nelts;
        }
        return md_pkeys_spec_count(md->pks);
    }
    
    int md_reg_has_revoked_certs(md_reg_t *reg, struct md_ocsp_reg_t *ocsp,
                                 const md_t *md, apr_pool_t *p)
    {
        const md_pubcert_t *pubcert;
        const md_cert_t *cert;
        md_timeperiod_t ocsp_valid;
        md_ocsp_cert_stat_t cert_stat;
        apr_status_t rv = APR_SUCCESS;
        int i;
    
        if (!md->stapling || !ocsp)
            return 0;
    
        for (i = 0; i < get_cert_count(md); ++i) {
            if (APR_SUCCESS != md_reg_get_pubcert(&pubcert, reg, md, i, p))
                continue;
            cert = APR_ARRAY_IDX(pubcert->certs, 0, const md_cert_t*);
            if(!cert)
                continue;
            rv = md_ocsp_get_meta(&cert_stat, &ocsp_valid, ocsp, cert, p, md);
            if (APR_SUCCESS == rv && cert_stat == MD_OCSP_CERT_ST_REVOKED) {
                return 1;
            }
        }
        return 0;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_config.h�������������������������������������������������������������0000664�0001751�0001751�00000016055�14750656217�017653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_config_h
    #define mod_md_md_config_h
    
    struct apr_hash_t;
    struct md_store_t;
    struct md_reg_t;
    struct md_ocsp_reg_t;
    struct md_pkeys_spec_t;
    
    typedef enum {
        MD_CONFIG_CA_CONTACT,
        MD_CONFIG_CA_PROTO,
        MD_CONFIG_BASE_DIR,
        MD_CONFIG_CA_AGREEMENT,
        MD_CONFIG_DRIVE_MODE,
        MD_CONFIG_RENEW_WINDOW,
        MD_CONFIG_WARN_WINDOW,
        MD_CONFIG_TRANSITIVE,
        MD_CONFIG_PROXY,
        MD_CONFIG_REQUIRE_HTTPS,
        MD_CONFIG_MUST_STAPLE,
        MD_CONFIG_NOTIFY_CMD,
        MD_CONFIG_MESSGE_CMD,
        MD_CONFIG_STAPLING,
        MD_CONFIG_STAPLE_OTHERS,
        MD_CONFIG_CA_PROFILE,
        MD_CONFIG_CA_PROFILE_MANDATORY,
    } md_config_var_t;
    
    typedef enum {
        MD_MATCH_ALL,
        MD_MATCH_SERVERNAMES,
    } md_match_mode_t;
    
    typedef struct md_mod_conf_t md_mod_conf_t;
    struct md_mod_conf_t {
        apr_array_header_t *mds;           /* all md_t* defined in the config, shared */
        const char *base_dir;              /* base dir for store */
        const char *proxy_url;             /* proxy url to use (or NULL) */
        struct md_reg_t *reg;              /* md registry instance */
        struct md_ocsp_reg_t *ocsp;        /* ocsp status registry */
    
        int local_80;                      /* On which port http:80 arrives */
        int local_443;                     /* On which port https:443 arrives */
        int can_http;                      /* Does someone listen to the local port 80 equivalent? */
        int can_https;                     /* Does someone listen to the local port 443 equivalent? */
        int manage_base_server;            /* If base server outside vhost may be managed */
        int hsts_max_age;                  /* max-age of HSTS (rfc6797) header */
        const char *hsts_header;           /* computed HTST header to use or NULL */
        apr_array_header_t *unused_names;  /* post config, names of all MDs not assigned to a vhost */
        struct apr_hash_t *init_errors;    /* init errors reported with MD name as key */
    
        const char *notify_cmd;            /* notification command to execute on signup/renew */
        const char *message_cmd;           /* message command to execute on signup/renew/warnings */
        struct apr_table_t *env;           /* environment for operation */
        int dry_run;                       /* != 0 iff config dry run */
        int server_status_enabled;         /* if module should add to server-status handler */
        int certificate_status_enabled;    /* if module should expose /.httpd/certificate-status */
        md_timeslice_t *ocsp_keep_window;  /* time that we keep ocsp responses around */
        md_timeslice_t *ocsp_renew_window; /* time before exp. that we start renewing ocsp resp. */
        const char *cert_check_name;       /* name of the linked certificate check site */
        const char *cert_check_url;        /* url "template for" checking a certificate */
        const char *ca_certs;              /* root certificates to use for connections */
        apr_time_t check_interval;         /* duration between cert renewal checks */
        apr_time_t min_delay;              /* minimum delay for retries */
        int retry_failover;                /* number of errors to trigger CA failover */
        int use_store_locks;               /* use locks when updating store */
        apr_time_t lock_wait_timeout;      /* fail after this time when unable to obtain lock */
        md_match_mode_t match_mode;        /* how dns names are match to vhosts */
    };
    
    typedef struct md_srv_conf_t {
        const char *name;
        const server_rec *s;               /* server this config belongs to */
        md_mod_conf_t *mc;                 /* global config settings */
        
        int transitive;                    /* != 0 iff VirtualHost names/aliases are auto-added */
        md_require_t require_https;        /* If MDs require https: access */
        int renew_mode;                    /* mode of obtaining credentials */
        int must_staple;                   /* certificates should set the OCSP Must Staple extension */
        struct md_pkeys_spec_t *pks;       /* specification for private keys */
        md_timeslice_t *renew_window;      /* time before expiration that starts renewal */
        md_timeslice_t *warn_window;       /* time before expiration that warning are sent out */
        
        struct apr_array_header_t *ca_urls; /* urls of CAs */
        const char *ca_contact;            /* contact email registered to account */
        const char *ca_proto;              /* protocol used vs CA (e.g. ACME) */
        const char *ca_agreement;          /* accepted agreement uri between CA and user */ 
        struct apr_array_header_t *ca_challenges; /* challenge types configured */
        const char *ca_eab_kid;            /* != NULL, external account binding keyid */
        const char *ca_eab_hmac;           /* != NULL, external account binding hmac */
        const char *profile;               /* != NULL, ACME order profile */
        int profile_mandatory;             /* if ACME profile, when set, is mandatory */
    
        int stapling;                      /* OCSP stapling enabled */
        int staple_others;                 /* Provide OCSP stapling for non-MD certificates */
    
        const char *dns01_cmd;             /* DNS challenge command, override global command */
    
        md_t *current;                     /* md currently defined in <MDomainSet xxx> section */
        struct apr_array_header_t *assigned; /* post_config: MDs that apply to this server */
        int is_ssl;                        /* SSLEngine is enabled here */
    } md_srv_conf_t;
    
    void *md_config_create_svr(apr_pool_t *pool, server_rec *s);
    void *md_config_merge_svr(apr_pool_t *pool, void *basev, void *addv);
    
    extern const command_rec md_cmds[];
    
    apr_status_t md_config_post_config(server_rec *s, apr_pool_t *p);
    
    /* Get the effective md configuration for the connection */
    md_srv_conf_t *md_config_cget(conn_rec *c);
    /* Get the effective md configuration for the server */
    md_srv_conf_t *md_config_get(server_rec *s);
    /* Get the effective md configuration for the server, but make it
     * unique to this server_rec, so that any changes only affect this server */
    md_srv_conf_t *md_config_get_unique(server_rec *s, apr_pool_t *p);
    
    const char *md_config_gets(const md_srv_conf_t *config, md_config_var_t var);
    int md_config_geti(const md_srv_conf_t *config, md_config_var_t var);
    
    void md_config_get_timespan(md_timeslice_t **pspan, const md_srv_conf_t *sc, md_config_var_t var);
    
    const md_t *md_get_for_domain(server_rec *s, const char *domain);
    
    #endif /* md_config_h */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_config.c�������������������������������������������������������������0000664�0001751�0001751�00000146555�14750656217�017657� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_log.h>
    #include <http_vhost.h>
    
    #include "md.h"
    #include "md_acme.h"
    #include "md_crypt.h"
    #include "md_log.h"
    #include "md_json.h"
    #include "md_util.h"
    #include "mod_md_private.h"
    #include "mod_md_config.h"
    
    #define MD_CMD_MD_SECTION     "<MDomainSet"
    #define MD_CMD_MD2_SECTION    "<MDomain"
    
    #define DEF_VAL     (-1)
    
    #ifndef MD_DEFAULT_BASE_DIR
    #define MD_DEFAULT_BASE_DIR "md"
    #endif
    
    static md_timeslice_t def_ocsp_keep_window = {
        0,
        MD_TIME_OCSP_KEEP_NORM,
    };
    
    static md_timeslice_t def_ocsp_renew_window = {
        MD_TIME_LIFE_NORM,
        MD_TIME_RENEW_WINDOW_DEF,
    };
    
    /* Default settings for the global conf */
    static md_mod_conf_t defmc = {
        NULL,                      /* list of mds */
    #if AP_MODULE_MAGIC_AT_LEAST(20180906, 2)
        NULL,                      /* base dirm by default state-dir-relative */
    #else
        MD_DEFAULT_BASE_DIR,
    #endif
        NULL,                      /* proxy url for outgoing http */
        NULL,                      /* md_reg_t */
        NULL,                      /* md_ocsp_reg_t */
        80,                        /* local http: port */
        443,                       /* local https: port */
        -1,                        /* can http: */
        -1,                        /* can https: */
        0,                         /* manage base server */
        MD_HSTS_MAX_AGE_DEFAULT,   /* hsts max-age */
        NULL,                      /* hsts headers */
        NULL,                      /* unused names */
        NULL,                      /* init errors hash */
        NULL,                      /* notify cmd */
        NULL,                      /* message cmd */
        NULL,                      /* env table */
        0,                         /* dry_run flag */
        1,                         /* server_status_enabled */
        1,                         /* certificate_status_enabled */
        &def_ocsp_keep_window,     /* default time to keep ocsp responses */
        &def_ocsp_renew_window,    /* default time to renew ocsp responses */
        "crt.sh",                  /* default cert checker site name */
        "https://crt.sh?q=",       /* default cert checker site url */
        NULL,                      /* CA cert file to use */
        apr_time_from_sec(MD_SECS_PER_DAY/2), /* default time between cert checks */
        apr_time_from_sec(5),      /* minimum delay for retries */
        13,                        /* retry_failover after 14 errors, with 5s delay ~ half a day */
        0,                         /* store locks, disabled by default */
        apr_time_from_sec(5),      /* max time to wait to obaint a store lock */
        MD_MATCH_ALL,              /* match vhost severname and aliases */
    };
    
    static md_timeslice_t def_renew_window = {
        MD_TIME_LIFE_NORM,
        MD_TIME_RENEW_WINDOW_DEF,
    };
    static md_timeslice_t def_warn_window = {
        MD_TIME_LIFE_NORM,
        MD_TIME_WARN_WINDOW_DEF,
    };
    
    /* Default server specific setting */
    static md_srv_conf_t defconf = {
        "default",                 /* name */
        NULL,                      /* server_rec */
        &defmc,                    /* mc */
        1,                         /* transitive */
        MD_REQUIRE_OFF,            /* require https */
        MD_RENEW_AUTO,             /* renew mode */
        0,                         /* must staple */
        NULL,                      /* pkey spec */
        &def_renew_window,         /* renew window */
        &def_warn_window,          /* warn window */
        NULL,                      /* ca urls */
        NULL,                      /* ca contact (email) */
        MD_PROTO_ACME,             /* ca protocol */
        NULL,                      /* ca agreemnent */
        NULL,                      /* ca challenges array */
        NULL,                      /* ca eab kid */
        NULL,                      /* ca eab hmac */
        NULL,                      /* ACME profile */
        0,                         /* ACME profile mandatory */
        0,                         /* stapling */
        1,                         /* staple others */
        NULL,                      /* dns01_cmd */
        NULL,                      /* currently defined md */
        NULL,                      /* assigned md, post config */
        0,                         /* is_ssl, set during mod_ssl post_config */
    };
    
    static md_mod_conf_t *mod_md_config;
    
    static apr_status_t cleanup_mod_config(void *dummy)
    {
        (void)dummy;
        mod_md_config = NULL;
        return APR_SUCCESS;
    }
    
    static md_mod_conf_t *md_mod_conf_get(apr_pool_t *pool, int create)
    {
        if (mod_md_config) {
            return mod_md_config; /* reused for lifetime of the pool */
        }
    
        if (create) {
            mod_md_config = apr_pcalloc(pool, sizeof(*mod_md_config));
            memcpy(mod_md_config, &defmc, sizeof(*mod_md_config));
            mod_md_config->mds = apr_array_make(pool, 5, sizeof(const md_t *));
            mod_md_config->unused_names = apr_array_make(pool, 5, sizeof(const md_t *));
            mod_md_config->env = apr_table_make(pool, 10);
            mod_md_config->init_errors = apr_hash_make(pool);
             
            apr_pool_cleanup_register(pool, NULL, cleanup_mod_config, apr_pool_cleanup_null);
        }
        
        return mod_md_config;
    }
    
    #define CONF_S_NAME(s)  (s && s->server_hostname? s->server_hostname : "default")
    
    static void srv_conf_props_clear(md_srv_conf_t *sc)
    {
        sc->transitive = DEF_VAL;
        sc->require_https = MD_REQUIRE_UNSET;
        sc->renew_mode = DEF_VAL;
        sc->must_staple = DEF_VAL;
        sc->pks = NULL;
        sc->renew_window = NULL;
        sc->warn_window = NULL;
        sc->ca_urls = NULL;
        sc->ca_contact = NULL;
        sc->ca_proto = NULL;
        sc->ca_agreement = NULL;
        sc->ca_challenges = NULL;
        sc->ca_eab_kid = NULL;
        sc->ca_eab_hmac = NULL;
        sc->profile = NULL;
        sc->profile_mandatory = DEF_VAL;
        sc->stapling = DEF_VAL;
        sc->staple_others = DEF_VAL;
        sc->dns01_cmd = NULL;
    }
    
    static void srv_conf_props_copy(md_srv_conf_t *to, const md_srv_conf_t *from)
    {
        to->transitive = from->transitive;
        to->require_https = from->require_https;
        to->renew_mode = from->renew_mode;
        to->must_staple = from->must_staple;
        to->pks = from->pks;
        to->warn_window = from->warn_window;
        to->renew_window = from->renew_window;
        to->ca_urls = from->ca_urls;
        to->ca_contact = from->ca_contact;
        to->ca_proto = from->ca_proto;
        to->ca_agreement = from->ca_agreement;
        to->ca_challenges = from->ca_challenges;
        to->ca_eab_kid = from->ca_eab_kid;
        to->ca_eab_hmac = from->ca_eab_hmac;
        to->profile = from->profile;
        to->profile_mandatory = from->profile_mandatory;
        to->stapling = from->stapling;
        to->staple_others = from->staple_others;
        to->dns01_cmd = from->dns01_cmd;
    }
    
    static void srv_conf_props_apply(md_t *md, const md_srv_conf_t *from, apr_pool_t *p)
    {
        if (from->require_https != MD_REQUIRE_UNSET) md->require_https = from->require_https;
        if (from->transitive != DEF_VAL) md->transitive = from->transitive;
        if (from->renew_mode != DEF_VAL) md->renew_mode = from->renew_mode;
        if (from->must_staple != DEF_VAL) md->must_staple = from->must_staple;
        if (from->pks) md->pks = md_pkeys_spec_clone(p, from->pks);
        if (from->renew_window) md->renew_window = from->renew_window;
        if (from->warn_window) md->warn_window = from->warn_window;
        if (from->ca_urls) md->ca_urls = apr_array_copy(p, from->ca_urls);
        if (from->ca_proto) md->ca_proto = from->ca_proto;
        if (from->ca_agreement) md->ca_agreement = from->ca_agreement;
        if (from->ca_contact) {
            apr_array_clear(md->contacts);
            APR_ARRAY_PUSH(md->contacts, const char *) =
                md_util_schemify(p, from->ca_contact, "mailto");
        }
        if (from->ca_challenges) md->ca_challenges = apr_array_copy(p, from->ca_challenges);
        if (from->ca_eab_kid) md->ca_eab_kid = from->ca_eab_kid;
        if (from->ca_eab_hmac) md->ca_eab_hmac = from->ca_eab_hmac;
        if (from->profile) md->profile = from->profile;
        if (from->profile_mandatory != DEF_VAL) md->profile_mandatory = from->profile_mandatory;
        if (from->stapling != DEF_VAL) md->stapling = from->stapling;
        if (from->dns01_cmd) md->dns01_cmd = from->dns01_cmd;
    }
    
    void *md_config_create_svr(apr_pool_t *pool, server_rec *s)
    {
        md_srv_conf_t *conf = (md_srv_conf_t *)apr_pcalloc(pool, sizeof(md_srv_conf_t));
    
        conf->name = apr_pstrcat(pool, "srv[", CONF_S_NAME(s), "]", NULL);
        conf->s = s;
        conf->mc = md_mod_conf_get(pool, 1);
    
        srv_conf_props_clear(conf);
        
        return conf;
    }
    
    static void *md_config_merge(apr_pool_t *pool, void *basev, void *addv)
    {
        md_srv_conf_t *base = (md_srv_conf_t *)basev;
        md_srv_conf_t *add = (md_srv_conf_t *)addv;
        md_srv_conf_t *nsc;
        char *name = apr_pstrcat(pool, "[", CONF_S_NAME(add->s), ", ", CONF_S_NAME(base->s), "]", NULL);
        
        nsc = (md_srv_conf_t *)apr_pcalloc(pool, sizeof(md_srv_conf_t));
        nsc->name = name;
        nsc->mc = add->mc? add->mc : base->mc;
    
        nsc->transitive = (add->transitive != DEF_VAL)? add->transitive : base->transitive;
        nsc->require_https = (add->require_https != MD_REQUIRE_UNSET)? add->require_https : base->require_https;
        nsc->renew_mode = (add->renew_mode != DEF_VAL)? add->renew_mode : base->renew_mode;
        nsc->must_staple = (add->must_staple != DEF_VAL)? add->must_staple : base->must_staple;
        nsc->pks = (!md_pkeys_spec_is_empty(add->pks))? add->pks : base->pks;
        nsc->renew_window = add->renew_window? add->renew_window : base->renew_window;
        nsc->warn_window = add->warn_window? add->warn_window : base->warn_window;
    
        nsc->ca_urls = add->ca_urls? apr_array_copy(pool, add->ca_urls)
                        : (base->ca_urls? apr_array_copy(pool, base->ca_urls) : NULL);
        nsc->ca_contact = add->ca_contact? add->ca_contact : base->ca_contact;
        nsc->ca_proto = add->ca_proto? add->ca_proto : base->ca_proto;
        nsc->ca_agreement = add->ca_agreement? add->ca_agreement : base->ca_agreement;
        nsc->ca_challenges = (add->ca_challenges? apr_array_copy(pool, add->ca_challenges) 
                        : (base->ca_challenges? apr_array_copy(pool, base->ca_challenges) : NULL));
        nsc->ca_eab_kid = add->ca_eab_kid? add->ca_eab_kid : base->ca_eab_kid;
        nsc->ca_eab_hmac = add->ca_eab_hmac? add->ca_eab_hmac : base->ca_eab_hmac;
        nsc->profile = add->profile? add->profile : base->profile;
        nsc->profile_mandatory = (add->profile_mandatory != DEF_VAL)? add->profile_mandatory : base->profile_mandatory;
        nsc->stapling = (add->stapling != DEF_VAL)? add->stapling : base->stapling;
        nsc->staple_others = (add->staple_others != DEF_VAL)? add->staple_others : base->staple_others;
        nsc->dns01_cmd = (add->dns01_cmd)? add->dns01_cmd : base->dns01_cmd;
        nsc->current = NULL;
        
        return nsc;
    }
    
    void *md_config_merge_svr(apr_pool_t *pool, void *basev, void *addv)
    {
        return md_config_merge(pool, basev, addv);
    }
    
    static int inside_section(cmd_parms *cmd, const char *section) {
        ap_directive_t *d;
        for (d = cmd->directive->parent; d; d = d->parent) {
           if (!ap_cstr_casecmp(d->directive, section)) {
               return 1;
           }
        }
        return 0; 
    }
    
    static int inside_md_section(cmd_parms *cmd) {
        return (inside_section(cmd, MD_CMD_MD_SECTION) || inside_section(cmd, MD_CMD_MD2_SECTION));
    }
    
    static const char *md_section_check(cmd_parms *cmd) {
        if (!inside_md_section(cmd)) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name, " is only valid inside a '",  
                               MD_CMD_MD_SECTION, "' context, not here", NULL);
        }
        return NULL;
    }
    
    #define MD_LOC_GLOBAL (0x01)
    #define MD_LOC_MD     (0x02)
    #define MD_LOC_ELSE   (0x04)
    #define MD_LOC_ALL    (0x07)
    #define MD_LOC_NOT_MD (0x102)
    
    static const char *md_conf_check_location(cmd_parms *cmd, int flags)
    {
        if (MD_LOC_GLOBAL == flags) {
            return ap_check_cmd_context(cmd, GLOBAL_ONLY);
        }
        if (MD_LOC_NOT_MD == flags && inside_md_section(cmd)) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name, " is not allowed inside an '",  
                               MD_CMD_MD_SECTION, "' context", NULL);
        }
        if (MD_LOC_MD == flags) {
            return md_section_check(cmd);
        }
        else if ((MD_LOC_MD & flags) && inside_md_section(cmd)) {
            return NULL;
        } 
        return ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_LOCATION);
    }
    
    static const char *set_on_off(int *pvalue, const char *s, apr_pool_t *p)
    {
        if (!apr_strnatcasecmp("off", s)) {
            *pvalue = 0;
        }
        else if (!apr_strnatcasecmp("on", s)) {
            *pvalue = 1;
        }
        else {
            return apr_pstrcat(p, "unknown '", s, 
                               "', supported parameter values are 'on' and 'off'", NULL);
        }
        return NULL;
    }
    
    
    static void add_domain_name(apr_array_header_t *domains, const char *name, apr_pool_t *p)
    {
        if (md_array_str_index(domains, name, 0, 0) < 0) {
            APR_ARRAY_PUSH(domains, char *) = md_util_str_tolower(apr_pstrdup(p, name));
        }
    }
    
    static const char *set_transitive(int *ptransitive, const char *value)
    {
        if (!apr_strnatcasecmp("auto", value)) {
            *ptransitive = 1;
            return NULL;
        }
        else if (!apr_strnatcasecmp("manual", value)) {
            *ptransitive = 0;
            return NULL;
        }
        return "unknown value, use \"auto|manual\"";
    }
    
    static const char *md_config_sec_start(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        md_srv_conf_t *sc;
        md_srv_conf_t save;
        const char *endp;
        const char *err, *name;
        apr_array_header_t *domains;
        md_t *md;
        int transitive = -1;
        
        (void)mconfig;
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
            
        sc = md_config_get(cmd->server);
        endp = ap_strrchr_c(arg, '>');
        if (endp == NULL) {
            return  MD_CMD_MD_SECTION "> directive missing closing '>'";
        }
    
        arg = apr_pstrndup(cmd->pool, arg, (apr_size_t)(endp-arg));
        if (!arg || !*arg) {
            return MD_CMD_MD_SECTION " > section must specify a unique domain name";
        }
    
        name = ap_getword_conf(cmd->pool, &arg);
        domains = apr_array_make(cmd->pool, 5, sizeof(const char *));
        add_domain_name(domains, name, cmd->pool);
        while (*arg != '\0') {
            name = ap_getword_conf(cmd->pool, &arg);
            if (NULL != set_transitive(&transitive, name)) {
                add_domain_name(domains, name, cmd->pool);
            }
        }
    
        if (domains->nelts == 0) {
            return "needs at least one domain name";
        }
        
        md = md_create(cmd->pool, domains);
        if (transitive >= 0) {
            md->transitive = transitive;
        }
        
        /* Save the current settings in this srv_conf and apply+restore at the
         * end of this section */
        memcpy(&save, sc, sizeof(save));
        srv_conf_props_clear(sc);
        sc->current = md;
        
        if (NULL == (err = ap_walk_config(cmd->directive->first_child, cmd, cmd->context))) {
            srv_conf_props_apply(md, sc, cmd->pool);
            APR_ARRAY_PUSH(sc->mc->mds, const md_t *) = md;
        }
        
        sc->current = NULL;
        srv_conf_props_copy(sc, &save);
        
        return err;
    }
    
    static const char *md_config_sec_add_members(cmd_parms *cmd, void *dc, 
                                                 int argc, char *const argv[])
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
        int i;
        
        (void)dc;
        if (NULL != (err = md_section_check(cmd))) {
            if (argc == 1) {
                /* only these values are allowed outside a section */
                return set_transitive(&sc->transitive, argv[0]);
            }
            return err;
        }
        
        assert(sc->current);
        for (i = 0; i < argc; ++i) {
            if (NULL != set_transitive(&sc->transitive, argv[i])) {
                add_domain_name(sc->current->domains, argv[i], cmd->pool);
            }
        }
        return NULL;
    }
    
    static const char *md_config_set_names(cmd_parms *cmd, void *dc, 
                                           int argc, char *const argv[])
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        apr_array_header_t *domains = apr_array_make(cmd->pool, 5, sizeof(const char *));
        const char *err;
        md_t *md;
        int i, transitive = -1;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
    
        for (i = 0; i < argc; ++i) {
            if (NULL != set_transitive(&transitive, argv[i])) {
                add_domain_name(domains, argv[i], cmd->pool);
            }
        }
        
        if (domains->nelts == 0) {
            return "needs at least one domain name";
        }
        md = md_create(cmd->pool, domains);
    
        if (transitive >= 0) {
            md->transitive = transitive;
        }
        
        if (cmd->config_file) {
            md->defn_name = cmd->config_file->name;
            md->defn_line_number = cmd->config_file->line_number;
        }
    
        APR_ARRAY_PUSH(sc->mc->mds, md_t *) = md;
    
        return NULL;
    }
    
    static const char *md_config_set_ca(cmd_parms *cmd, void *dc,
                                        int argc, char *const argv[])
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err, *url;
        int i;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        if (!sc->ca_urls) {
            sc->ca_urls = apr_array_make(cmd->pool, 3, sizeof(const char *));
        }
        else {
            apr_array_clear(sc->ca_urls);
        }
        for (i = 0; i < argc; ++i) {
            if (APR_SUCCESS != md_get_ca_url_from_name(&url, cmd->pool, argv[i])) {
                return url;
            }
            APR_ARRAY_PUSH(sc->ca_urls, const char *) = url;
        }
        return NULL;
    }
    
    static const char *md_config_set_contact(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        sc->ca_contact = value;
        return NULL;
    }
    
    static const char *md_config_set_ca_proto(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        config->ca_proto = value;
        return NULL;
    }
    
    static const char *md_config_set_agreement(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        config->ca_agreement = value;
        return NULL;
    }
    
    static const char *md_config_set_renew_mode(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
        md_renew_mode_t renew_mode;
    
        (void)dc;
        if (!apr_strnatcasecmp("auto", value) || !apr_strnatcasecmp("automatic", value)) {
            renew_mode = MD_RENEW_AUTO;
        }
        else if (!apr_strnatcasecmp("always", value)) {
            renew_mode = MD_RENEW_ALWAYS;
        }
        else if (!apr_strnatcasecmp("manual", value) || !apr_strnatcasecmp("stick", value)) {
            renew_mode = MD_RENEW_MANUAL;
        }
        else {
            return apr_pstrcat(cmd->pool, "unknown MDDriveMode ", value, NULL);
        }
        
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        config->renew_mode = renew_mode;
        return NULL;
    }
    
    static const char *md_config_set_profile(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        config->profile = value;
        return NULL;
    }
    
    static const char *md_config_set_profile_mandatory(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        return set_on_off(&config->profile_mandatory, value, cmd->pool);
    }
    
    static const char *md_config_set_must_staple(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        return set_on_off(&config->must_staple, value, cmd->pool);
    }
    
    static const char *md_config_set_stapling(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        return set_on_off(&config->stapling, value, cmd->pool);
    }
    
    static const char *md_config_set_staple_others(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        return set_on_off(&config->staple_others, value, cmd->pool);
    }
    
    static const char *md_config_set_base_server(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
    
        (void)dc;
        if (err) return err;
        return set_on_off(&config->mc->manage_base_server, value, cmd->pool);
    }
    
    static const char *md_config_set_check_interval(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
        apr_time_t interval;
    
        (void)dc;
        if (err) return err;
        if (md_duration_parse(&interval, value, "s") != APR_SUCCESS) {
            return "unrecognized duration format";
        }
        if (interval < apr_time_from_sec(1)) {
            return "check interval cannot be less than one second";
        }
        config->mc->check_interval = interval;
        return NULL;
    }
    
    static const char *md_config_set_min_delay(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
        apr_time_t delay;
    
        (void)dc;
        if (err) return err;
        if (md_duration_parse(&delay, value, "s") != APR_SUCCESS) {
            return "unrecognized duration format";
        }
        config->mc->min_delay = delay;
        return NULL;
    }
    
    static const char *md_config_set_retry_failover(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
        int retry_failover;
    
        (void)dc;
        if (err) return err;
        retry_failover = atoi(value);
        if (retry_failover <= 0) {
            return "invalid argument, must be a number > 0";
        }
        config->mc->retry_failover = retry_failover;
        return NULL;
    }
    
    static const char *md_config_set_store_locks(cmd_parms *cmd, void *dc, const char *s)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
        int use_store_locks;
        apr_time_t wait_time = 0;
    
        (void)dc;
        if (err) {
            return err;
        }
        else if (!apr_strnatcasecmp("off", s)) {
            use_store_locks = 0;
        }
        else if (!apr_strnatcasecmp("on", s)) {
            use_store_locks = 1;
        }
        else {
            if (md_duration_parse(&wait_time, s, "s") != APR_SUCCESS) {
                return "neither 'on', 'off' or a duration specified";
            }
            use_store_locks = (wait_time != 0);
        }
        config->mc->use_store_locks = use_store_locks;
        if (wait_time) {
            config->mc->lock_wait_timeout = wait_time;
        }
        return NULL;
    }
    
    static const char *md_config_set_match_mode(cmd_parms *cmd, void *dc, const char *s)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
    
        (void)dc;
        if (err) {
            return err;
        }
        else if (!apr_strnatcasecmp("all", s)) {
            config->mc->match_mode = MD_MATCH_ALL;
        }
        else if (!apr_strnatcasecmp("servernames", s)) {
            config->mc->match_mode = MD_MATCH_SERVERNAMES;
        }
        else {
            return "invalid argument, must be a 'all' or 'servernames'";
        }
        return NULL;
    }
    
    static const char *md_config_set_require_https(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
    
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        (void)dc;
        if (!apr_strnatcasecmp("off", value)) {
            config->require_https = MD_REQUIRE_OFF;
        }
        else if (!apr_strnatcasecmp(MD_KEY_TEMPORARY, value)) {
            config->require_https = MD_REQUIRE_TEMPORARY;
        }
        else if (!apr_strnatcasecmp(MD_KEY_PERMANENT, value)) {
            config->require_https = MD_REQUIRE_PERMANENT;
        }
        else {
            return apr_pstrcat(cmd->pool, "unknown '", value, 
                               "', supported parameter values are 'temporary' and 'permanent'", NULL);
        }
        return NULL;
    }
    
    static const char *md_config_set_renew_window(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
        
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        err = md_timeslice_parse(&config->renew_window, cmd->pool, value, MD_TIME_LIFE_NORM);
        if (!err && config->renew_window->norm 
            && (config->renew_window->len >= config->renew_window->norm)) {
            err = "a length of 100% or more is not allowed.";
        }
        if (err) return apr_psprintf(cmd->pool, "MDRenewWindow %s", err);
        return NULL;
    }
    
    static const char *md_config_set_warn_window(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err;
        
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        err = md_timeslice_parse(&config->warn_window, cmd->pool, value, MD_TIME_LIFE_NORM);
        if (!err && config->warn_window->norm 
            && (config->warn_window->len >= config->warn_window->norm)) {
            err = "a length of 100% or more is not allowed.";
        }
        if (err) return apr_psprintf(cmd->pool, "MDWarnWindow %s", err);
        return NULL;
    }
    
    static const char *md_config_set_proxy(cmd_parms *cmd, void *arg, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
        md_util_abs_http_uri_check(cmd->pool, value, &err);
        if (err) {
            return err;
        }
        sc->mc->proxy_url = value;
        (void)arg;
        return NULL;
    }
    
    static const char *md_config_set_store_dir(cmd_parms *cmd, void *arg, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
        sc->mc->base_dir = value;
        (void)arg;
        return NULL;
    }
    
    static const char *set_port_map(md_mod_conf_t *mc, const char *value)
    {
        int net_port, local_port;
        const char *endp;
    
        if (!strncmp("http:", value, sizeof("http:") - 1)) {
            net_port = 80; endp = value + sizeof("http") - 1; 
        }
        else if (!strncmp("https:", value, sizeof("https:") - 1)) {
            net_port = 443; endp = value + sizeof("https") - 1; 
        }
        else {
            net_port = (int)apr_strtoi64(value, (char**)&endp, 10);
            if (errno) {
                return "unable to parse first port number";
            }
        }
        if (!endp || *endp != ':') {
            return "no ':' after first port number";
        }
        ++endp;
        if (*endp == '-') {
            local_port = 0;
        }
        else {
            local_port = (int)apr_strtoi64(endp, (char**)&endp, 10);
            if (errno) {
                return "unable to parse second port number";
            }
            if (local_port <= 0 || local_port > 65535) {
                return "invalid number for port map, must be in ]0,65535]";
            }
        }
        switch (net_port) {
            case 80:
                mc->local_80 = local_port;
                break;
            case 443:
                mc->local_443 = local_port;
                break;
            default:
                return "mapped port number must be 80 or 443";
        }
        return NULL;
    }
    
    static const char *md_config_set_port_map(cmd_parms *cmd, void *arg, 
                                              const char *v1, const char *v2)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)arg;
        if (!(err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            err = set_port_map(sc->mc, v1);
        }
        if (!err && v2) {
            err = set_port_map(sc->mc, v2);
        }
        return err;
    }
    
    static const char *md_config_set_cha_tyes(cmd_parms *cmd, void *dc, 
                                              int argc, char *const argv[])
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        apr_array_header_t **pcha, *ca_challenges;
        const char *err;
        int i;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        pcha = &config->ca_challenges; 
        
        ca_challenges = *pcha;
        if (ca_challenges) {
            apr_array_clear(ca_challenges);
        }
        else {
            *pcha = ca_challenges = apr_array_make(cmd->pool, 5, sizeof(const char *));
        }
        for (i = 0; i < argc; ++i) {
            APR_ARRAY_PUSH(ca_challenges, const char *) = argv[i];
        }
        
        return NULL;
    }
    
    static const char *md_config_set_pkeys(cmd_parms *cmd, void *dc, 
                                           int argc, char *const argv[])
    {
        md_srv_conf_t *config = md_config_get(cmd->server);
        const char *err, *ptype;
        apr_int64_t bits;
        int i;
        
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        if (argc <= 0) {
            return "needs to specify the private key type";
        }
        
        config->pks = md_pkeys_spec_make(cmd->pool);
        for (i = 0; i < argc; ++i) {
            ptype = argv[i];
            if (!apr_strnatcasecmp("Default", ptype)) {
                if (argc > 1) {
                    return "'Default' allows no other parameter";
                }
                md_pkeys_spec_add_default(config->pks);
            }
            else if (strlen(ptype) > 3
                && (ptype[0] == 'R' || ptype[0] == 'r')
                && (ptype[1] == 'S' || ptype[1] == 's')
                && (ptype[2] == 'A' || ptype[2] == 'a')
                && isdigit(ptype[3])) {
                bits = (int)apr_atoi64(ptype+3);
                if (bits < MD_PKEY_RSA_BITS_MIN) {
                    return apr_psprintf(cmd->pool,
                                        "must be %d or higher in order to be considered safe.",
                                        MD_PKEY_RSA_BITS_MIN);
                }
                if (bits >= INT_MAX) {
                    return apr_psprintf(cmd->pool, "is too large for an RSA key length.");
                }
                if (md_pkeys_spec_contains_rsa(config->pks)) {
                    return "two keys of type 'RSA' are not possible.";
                }
                md_pkeys_spec_add_rsa(config->pks, (unsigned int)bits);
            }
            else if (!apr_strnatcasecmp("RSA", ptype)) {
                if (i+1 >= argc || !isdigit(argv[i+1][0])) {
                    bits = MD_PKEY_RSA_BITS_DEF;
                }
                else {
                    ++i;
                    bits = (int)apr_atoi64(argv[i]);
                    if (bits < MD_PKEY_RSA_BITS_MIN) {
                        return apr_psprintf(cmd->pool, 
                                            "must be %d or higher in order to be considered safe.", 
                                            MD_PKEY_RSA_BITS_MIN);
                    }
                    if (bits >= INT_MAX) {
                        return apr_psprintf(cmd->pool, "is too large for an RSA key length.");
                    }
                }
                if (md_pkeys_spec_contains_rsa(config->pks)) {
                    return "two keys of type 'RSA' are not possible.";
                }
                md_pkeys_spec_add_rsa(config->pks, (unsigned int)bits);
            }
            else {
                if (md_pkeys_spec_contains_ec(config->pks, argv[i])) {
                    return apr_psprintf(cmd->pool, "two keys of type '%s' are not possible.", argv[i]);
                }
                md_pkeys_spec_add_ec(config->pks, argv[i]);
            }
        }
        return NULL;
    }
    
    static const char *md_config_set_notify_cmd(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
        sc->mc->notify_cmd = arg;
        (void)mconfig;
        return NULL;
    }
    
    static const char *md_config_set_msg_cmd(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
        sc->mc->message_cmd = arg;
        (void)mconfig;
        return NULL;
    }
    
    static const char *md_config_set_dns01_cmd(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
    
        if (inside_md_section(cmd)) {
            sc->dns01_cmd = arg;
        } else {
            apr_table_set(sc->mc->env, MD_KEY_CMD_DNS01, arg);
        }
    
        (void)mconfig;
        return NULL;
    }
    
    static const char *md_config_set_dns01_version(cmd_parms *cmd, void *mconfig, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)mconfig;
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
        if (!strcmp("1", value) || !strcmp("2", value)) {
            apr_table_set(sc->mc->env, MD_KEY_DNS01_VERSION, value);
        }
        else {
            return "Only versions `1` and `2` are supported";
        }
        return NULL;
    }
    
    static const char *md_config_add_cert_file(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err, *fpath;
        
        (void)mconfig;
        if ((err = md_conf_check_location(cmd, MD_LOC_MD))) return err;
        assert(sc->current);
        fpath = ap_server_root_relative(cmd->pool, arg);
        if (!fpath) return apr_psprintf(cmd->pool, "certificate file not found: %s", arg);
        if (!sc->current->cert_files) {
            sc->current->cert_files = apr_array_make(cmd->pool, 3, sizeof(char*));
        }
        APR_ARRAY_PUSH(sc->current->cert_files, const char*) = fpath;
        return NULL;
    }
    
    static const char *md_config_add_key_file(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err, *fpath;
        
        (void)mconfig;
        if ((err = md_conf_check_location(cmd, MD_LOC_MD))) return err;
        assert(sc->current);
        fpath = ap_server_root_relative(cmd->pool, arg);
        if (!fpath) return apr_psprintf(cmd->pool, "certificate key file not found: %s", arg);
        if (!sc->current->pkey_files) {
            sc->current->pkey_files = apr_array_make(cmd->pool, 3, sizeof(char*));
        }
        APR_ARRAY_PUSH(sc->current->pkey_files, const char*) = fpath;
        return NULL;
    }
    
    static const char *md_config_set_server_status(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        return set_on_off(&sc->mc->server_status_enabled, value, cmd->pool);
    }
    
    static const char *md_config_set_certificate_status(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        return set_on_off(&sc->mc->certificate_status_enabled, value, cmd->pool);
    }
    
    static const char *md_config_set_ocsp_keep_window(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        err = md_timeslice_parse(&sc->mc->ocsp_keep_window, cmd->pool, value, MD_TIME_OCSP_KEEP_NORM);
        if (err) return apr_psprintf(cmd->pool, "MDStaplingKeepResponse %s", err);
        return NULL;
    }
    
    static const char *md_config_set_ocsp_renew_window(cmd_parms *cmd, void *dc, const char *value)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        err = md_timeslice_parse(&sc->mc->ocsp_renew_window, cmd->pool, value, MD_TIME_LIFE_NORM);
        if (!err && sc->mc->ocsp_renew_window->norm 
            && (sc->mc->ocsp_renew_window->len >= sc->mc->ocsp_renew_window->norm)) {
            err = "with a length of 100% or more is not allowed.";
        }
        if (err) return apr_psprintf(cmd->pool, "MDStaplingRenewWindow %s", err);
        return NULL;
    }
    
    static const char *md_config_set_cert_check(cmd_parms *cmd, void *dc, 
                                                const char *name, const char *url)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        sc->mc->cert_check_name = name;
        sc->mc->cert_check_url = url;
        return NULL;
    }
    
    static const char *md_config_set_activation_delay(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
        apr_interval_time_t delay;
    
        (void)mconfig;
        if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) {
            return err;
        }
        if (md_duration_parse(&delay, arg, "d") != APR_SUCCESS) {
            return "unrecognized duration format";
        }
        apr_table_set(sc->mc->env, MD_KEY_ACTIVATION_DELAY, md_duration_format(cmd->pool, delay));
        return NULL;
    }
    
    static const char *md_config_set_ca_certs(cmd_parms *cmd, void *dc, const char *path)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
    
        (void)dc;
        sc->mc->ca_certs = path;
        return NULL;
    }
    
    static const char *md_config_set_eab(cmd_parms *cmd, void *dc,
                                         const char *keyid, const char *hmac)
    {
        md_srv_conf_t *sc = md_config_get(cmd->server);
        const char *err;
    
        (void)dc;
        if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
            return err;
        }
        if (!hmac) {
            if (!apr_strnatcasecmp("None", keyid)) {
                keyid = "none";
            }
            else {
                /* a JSON file keeping keyid and hmac */
                const char *fpath;
                apr_status_t rv;
                md_json_t *json;
    
                /* If only dumping the config, don't verify the file */
                if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) {
                    goto leave;
                }
    
                fpath = ap_server_root_relative(cmd->pool, keyid);
                if (!fpath) {
                    return apr_pstrcat(cmd->pool, cmd->cmd->name,
                                       ": Invalid file path ", keyid, NULL);
                }
                if (!md_file_exists(fpath, cmd->pool)) {
                    return apr_pstrcat(cmd->pool, cmd->cmd->name,
                                       ": file not found: ", fpath, NULL);
                }
    
                rv = md_json_readf(&json, cmd->pool, fpath);
                if (APR_SUCCESS != rv) {
                    return apr_pstrcat(cmd->pool, cmd->cmd->name,
                                       ": error reading JSON file ", fpath, NULL);
                }
                keyid = md_json_gets(json, MD_KEY_KID, NULL);
                if (!keyid || !*keyid) {
                    return apr_pstrcat(cmd->pool, cmd->cmd->name,
                                       ": JSON does not contain '", MD_KEY_KID,
                                       "' element in file ", fpath, NULL);
                }
                hmac = md_json_gets(json, MD_KEY_HMAC, NULL);
                if (!hmac || !*hmac) {
                    return apr_pstrcat(cmd->pool, cmd->cmd->name,
                                       ": JSON does not contain '", MD_KEY_HMAC,
                                       "' element in file ", fpath, NULL);
                }
            }
        }
    leave:
        sc->ca_eab_kid = keyid;
        sc->ca_eab_hmac = hmac;
        return NULL;
    }
    
    const command_rec md_cmds[] = {
        AP_INIT_TAKE_ARGV("MDCertificateAuthority", md_config_set_ca, NULL, RSRC_CONF,
                          "URL(s) or known name(s) of CA issuing the certificates"),
        AP_INIT_TAKE1("MDCertificateAgreement", md_config_set_agreement, NULL, RSRC_CONF, 
                      "either 'accepted' or the URL of CA Terms-of-Service agreement you accept"),
        AP_INIT_TAKE_ARGV("MDCAChallenges", md_config_set_cha_tyes, NULL, RSRC_CONF, 
                          "A list of challenge types to be used."),
        AP_INIT_TAKE1("MDCertificateProtocol", md_config_set_ca_proto, NULL, RSRC_CONF, 
                      "Protocol used to obtain/renew certificates"),
        AP_INIT_TAKE1("MDContactEmail", md_config_set_contact, NULL, RSRC_CONF,
                      "Email address used for account registration"),
        AP_INIT_TAKE1("MDDriveMode", md_config_set_renew_mode, NULL, RSRC_CONF, 
                      "deprecated, older name for MDRenewMode"),
        AP_INIT_TAKE1("MDRenewMode", md_config_set_renew_mode, NULL, RSRC_CONF, 
                      "Controls how renewal of Managed Domain certificates shall be handled."),
        AP_INIT_TAKE_ARGV("MDomain", md_config_set_names, NULL, RSRC_CONF, 
                          "A group of server names with one certificate"),
        AP_INIT_RAW_ARGS(MD_CMD_MD_SECTION, md_config_sec_start, NULL, RSRC_CONF, 
                         "Container for a managed domain with common settings and certificate."),
        AP_INIT_RAW_ARGS(MD_CMD_MD2_SECTION, md_config_sec_start, NULL, RSRC_CONF, 
                         "Short form for <MDomainSet> container."),
        AP_INIT_TAKE_ARGV("MDMember", md_config_sec_add_members, NULL, RSRC_CONF, 
                          "Define domain name(s) part of the Managed Domain. Use 'auto' or "
                          "'manual' to enable/disable auto adding names from virtual hosts."),
        AP_INIT_TAKE_ARGV("MDMembers", md_config_sec_add_members, NULL, RSRC_CONF, 
                          "Define domain name(s) part of the Managed Domain. Use 'auto' or "
                          "'manual' to enable/disable auto adding names from virtual hosts."),
        AP_INIT_TAKE1("MDMustStaple", md_config_set_must_staple, NULL, RSRC_CONF, 
                      "Enable/Disable the Must-Staple flag for new certificates."),
        AP_INIT_TAKE12("MDPortMap", md_config_set_port_map, NULL, RSRC_CONF, 
                      "Declare the mapped ports 80 and 443 on the local server. E.g. 80:8000 "
                      "to indicate that the server port 8000 is reachable as port 80 from the "
                      "internet. Use 80:- to indicate that port 80 is not reachable from "
                      "the outside."),
        AP_INIT_TAKE_ARGV("MDPrivateKeys", md_config_set_pkeys, NULL, RSRC_CONF, 
                      "set the type and parameters for private key generation"),
        AP_INIT_TAKE1("MDHttpProxy", md_config_set_proxy, NULL, RSRC_CONF, 
                      "URL of a HTTP(S) proxy to use for outgoing connections"),
        AP_INIT_TAKE1("MDStoreDir", md_config_set_store_dir, NULL, RSRC_CONF, 
                      "the directory for file system storage of managed domain data."),
        AP_INIT_TAKE1("MDRenewWindow", md_config_set_renew_window, NULL, RSRC_CONF, 
                      "Time length for renewal before certificate expires (defaults to days)."),
        AP_INIT_TAKE1("MDRequireHttps", md_config_set_require_https, NULL, RSRC_CONF|OR_AUTHCFG, 
                      "Redirect non-secure requests to the https: equivalent."),
        AP_INIT_RAW_ARGS("MDNotifyCmd", md_config_set_notify_cmd, NULL, RSRC_CONF, 
                      "Set the command to run when signup/renew of domain is complete."),
        AP_INIT_TAKE1("MDBaseServer", md_config_set_base_server, NULL, RSRC_CONF, 
                      "Allow managing of base server outside virtual hosts."),
        AP_INIT_RAW_ARGS("MDChallengeDns01", md_config_set_dns01_cmd, NULL, RSRC_CONF, 
                      "Set the command for setup/teardown of dns-01 challenges"),
        AP_INIT_TAKE1("MDChallengeDns01Version", md_config_set_dns01_version, NULL, RSRC_CONF,
                      "Set the type of arguments to call `MDChallengeDns01` with"),
        AP_INIT_TAKE1("MDCertificateFile", md_config_add_cert_file, NULL, RSRC_CONF,
                      "set the static certificate (chain) file to use for this domain."),
        AP_INIT_TAKE1("MDCertificateKeyFile", md_config_add_key_file, NULL, RSRC_CONF, 
                      "set the static private key file to use for this domain."),
        AP_INIT_TAKE1("MDServerStatus", md_config_set_server_status, NULL, RSRC_CONF, 
                      "On to see Managed Domains in server-status."),
        AP_INIT_TAKE1("MDCertificateStatus", md_config_set_certificate_status, NULL, RSRC_CONF, 
                      "On to see Managed Domain expose /.httpd/certificate-status."),
        AP_INIT_TAKE1("MDWarnWindow", md_config_set_warn_window, NULL, RSRC_CONF, 
                      "When less time remains for a certificate, send our/log a warning (defaults to days)"),
        AP_INIT_RAW_ARGS("MDMessageCmd", md_config_set_msg_cmd, NULL, RSRC_CONF, 
                      "Set the command run when a message about a domain is issued."),
        AP_INIT_TAKE1("MDStapling", md_config_set_stapling, NULL, RSRC_CONF, 
                      "Enable/Disable OCSP Stapling for this/all Managed Domain(s)."),
        AP_INIT_TAKE1("MDStapleOthers", md_config_set_staple_others, NULL, RSRC_CONF, 
                      "Enable/Disable OCSP Stapling for certificates not in Managed Domains."),
        AP_INIT_TAKE1("MDStaplingKeepResponse", md_config_set_ocsp_keep_window, NULL, RSRC_CONF, 
                      "The amount of time to keep an OCSP response in the store."),
        AP_INIT_TAKE1("MDStaplingRenewWindow", md_config_set_ocsp_renew_window, NULL, RSRC_CONF, 
                      "Time length for renewal before OCSP responses expire (defaults to days)."),
        AP_INIT_TAKE2("MDCertificateCheck", md_config_set_cert_check, NULL, RSRC_CONF, 
                      "Set name and URL pattern for a certificate monitoring site."),
        AP_INIT_TAKE1("MDActivationDelay", md_config_set_activation_delay, NULL, RSRC_CONF, 
                      "How long to delay activation of new certificates"),
        AP_INIT_TAKE1("MDCACertificateFile", md_config_set_ca_certs, NULL, RSRC_CONF,
                      "Set the CA file to use for connections"),
        AP_INIT_TAKE12("MDExternalAccountBinding", md_config_set_eab, NULL, RSRC_CONF,
                      "Set the external account binding keyid and hmac values to use at CA"),
        AP_INIT_TAKE1("MDRetryDelay", md_config_set_min_delay, NULL, RSRC_CONF,
                      "Time length for first retry, doubled on every consecutive error."),
        AP_INIT_TAKE1("MDRetryFailover", md_config_set_retry_failover, NULL, RSRC_CONF,
                      "The number of errors before a failover to another CA is triggered."),
        AP_INIT_TAKE1("MDStoreLocks", md_config_set_store_locks, NULL, RSRC_CONF,
                      "Configure locking of store for updates."),
        AP_INIT_TAKE1("MDMatchNames", md_config_set_match_mode, NULL, RSRC_CONF,
                      "Determines how DNS names are matched to vhosts."),
        AP_INIT_TAKE1("MDCheckInterval", md_config_set_check_interval, NULL, RSRC_CONF,
                      "Time between certificate checks."),
        AP_INIT_TAKE1("MDProfile", md_config_set_profile, NULL, RSRC_CONF,
                      "The name of an CA profile to order certificates for."),
        AP_INIT_TAKE1("MDProfileMandatory", md_config_set_profile_mandatory, NULL, RSRC_CONF,
                      "Determines if a configured CA profile is mandatory."),
        AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
    };
    
    apr_status_t md_config_post_config(server_rec *s, apr_pool_t *p)
    {
        md_srv_conf_t *sc;
        md_mod_conf_t *mc;
    
        sc = md_config_get(s);
        mc = sc->mc;
    
        mc->hsts_header = NULL;
        if (mc->hsts_max_age > 0) {
            mc->hsts_header = apr_psprintf(p, "max-age=%d", mc->hsts_max_age);
        }
    
    #if AP_MODULE_MAGIC_AT_LEAST(20180906, 2)
        if (mc->base_dir == NULL) {
            mc->base_dir = ap_state_dir_relative(p, MD_DEFAULT_BASE_DIR);
        }
    #endif
        
        return APR_SUCCESS;
    }
    
    static md_srv_conf_t *config_get_int(server_rec *s, apr_pool_t *p)
    {
        md_srv_conf_t *sc = (md_srv_conf_t *)ap_get_module_config(s->module_config, &md_module);
        ap_assert(sc);
        if (sc->s != s && p) {
            sc = md_config_merge(p, &defconf, sc);
            sc->s = s;
            sc->name = apr_pstrcat(p, CONF_S_NAME(s), sc->name, NULL);
            sc->mc = md_mod_conf_get(p, 1);
            ap_set_module_config(s->module_config, &md_module, sc);
        }
        return sc;
    }
    
    md_srv_conf_t *md_config_get(server_rec *s)
    {
        return config_get_int(s, NULL);
    }
    
    md_srv_conf_t *md_config_get_unique(server_rec *s, apr_pool_t *p)
    {
        assert(p);
        return config_get_int(s, p);
    }
    
    md_srv_conf_t *md_config_cget(conn_rec *c)
    {
        return md_config_get(c->base_server);
    }
    
    const char *md_config_gets(const md_srv_conf_t *sc, md_config_var_t var)
    {
        switch (var) {
            case MD_CONFIG_CA_CONTACT:
                return sc->ca_contact? sc->ca_contact : defconf.ca_contact;
            case MD_CONFIG_CA_PROTO:
                return sc->ca_proto? sc->ca_proto : defconf.ca_proto;
            case MD_CONFIG_BASE_DIR:
                return sc->mc->base_dir;
            case MD_CONFIG_PROXY:
                return sc->mc->proxy_url;
            case MD_CONFIG_CA_AGREEMENT:
                return sc->ca_agreement? sc->ca_agreement : defconf.ca_agreement;
            case MD_CONFIG_NOTIFY_CMD:
                return sc->mc->notify_cmd;
            case MD_CONFIG_CA_PROFILE:
                return sc->profile? sc->profile : defconf.profile;
            default:
                return NULL;
        }
    }
    
    int md_config_geti(const md_srv_conf_t *sc, md_config_var_t var)
    {
        switch (var) {
            case MD_CONFIG_DRIVE_MODE:
                return (sc->renew_mode != DEF_VAL)? sc->renew_mode : defconf.renew_mode;
            case MD_CONFIG_TRANSITIVE:
                return (sc->transitive != DEF_VAL)? sc->transitive : defconf.transitive;
            case MD_CONFIG_REQUIRE_HTTPS:
                return (sc->require_https != MD_REQUIRE_UNSET)? sc->require_https : defconf.require_https;
            case MD_CONFIG_MUST_STAPLE:
                return (sc->must_staple != DEF_VAL)? sc->must_staple : defconf.must_staple;
            case MD_CONFIG_STAPLING:
                return (sc->stapling != DEF_VAL)? sc->stapling : defconf.stapling;
            case MD_CONFIG_STAPLE_OTHERS:
                return (sc->staple_others != DEF_VAL)? sc->staple_others : defconf.staple_others;
            case MD_CONFIG_CA_PROFILE_MANDATORY:
                return (sc->profile_mandatory != DEF_VAL)? sc->profile_mandatory : defconf.profile_mandatory;
            default:
                return 0;
        }
    }
    
    void md_config_get_timespan(md_timeslice_t **pspan, const md_srv_conf_t *sc, md_config_var_t var)
    {
        switch (var) {
            case MD_CONFIG_RENEW_WINDOW:
                *pspan = sc->renew_window? sc->renew_window : defconf.renew_window;
                break;
            case MD_CONFIG_WARN_WINDOW:
                *pspan = sc->warn_window? sc->warn_window : defconf.warn_window;
                break;
            default:
                break;
        }
    }
    
    const md_t *md_get_for_domain(server_rec *s, const char *domain)
    {
        md_srv_conf_t *sc;
        const md_t *md;
        int i;
        
        sc = md_config_get(s);
        for (i = 0; sc && sc->assigned && i < sc->assigned->nelts; ++i) {
            md = APR_ARRAY_IDX(sc->assigned, i, const md_t*);
            if (md_contains(md, domain, 0)) goto leave;
        }
        md = NULL;
    leave:
        return md;
    }
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_reg.h��������������������������������������������������������������������0000664�0001751�0001751�00000027276�14630343666�016331� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_reg_h
    #define mod_md_md_reg_h
    
    struct apr_hash_t;
    struct apr_array_header_t;
    struct md_pkey_t;
    struct md_cert_t;
    struct md_result_t;
    struct md_pkey_spec_t;
    struct md_ocsp_reg_t;
    
    #include "md_store.h"
    
    /**
     * A registry for managed domains with a md_store_t as persistence.
     *
     */
    typedef struct md_reg_t md_reg_t;
    
    /**
     * Create the MD registry, using the pool and store.
     * @param preg on APR_SUCCESS, the create md_reg_t
     * @param pm memory pool to use for creation
     * @param store the store to base on
     * @param proxy_url optional URL of a proxy to use for requests
     * @param ca_file  optioinal CA trust anchor file to use
     * @param min_delay minimum delay between renewal attempts for a domain
     * @param retry_failover numer of failed renewals attempt to fail over to alternate ACME ca
     */
    apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *pm, md_store_t *store,
                               const char *proxy_url, const char *ca_file,
                               apr_time_t min_delay, int retry_failover,
                               int use_store_locks, apr_time_t lock_wait_timeout);
    
    md_store_t *md_reg_store_get(md_reg_t *reg);
    
    apr_status_t md_reg_set_props(md_reg_t *reg, apr_pool_t *p, int can_http, int can_https);
    
    /**
     * Add a new md to the registry. This will check the name for uniqueness and
     * that domain names do not overlap with already existing mds.
     */
    apr_status_t md_reg_add(md_reg_t *reg, md_t *md, apr_pool_t *p);
    
    /**
     * Find the md, if any, that contains the given domain name. 
     * NULL if none found.
     */
    md_t *md_reg_find(md_reg_t *reg, const char *domain, apr_pool_t *p);
    
    /**
     * Find one md, which domain names overlap with the given md and that has a different
     * name. There may be more than one existing md that overlaps. It is not defined
     * which one will be returned. 
     */
    md_t *md_reg_find_overlap(md_reg_t *reg, const md_t *md, const char **pdomain, apr_pool_t *p);
    
    /**
     * Get the md with the given unique name. NULL if it does not exist.
     * Will update the md->state.
     */
    md_t *md_reg_get(md_reg_t *reg, const char *name, apr_pool_t *p);
    
    /**
     * Callback invoked for every md in the registry. If 0 is returned, iteration stops.
     */
    typedef int md_reg_do_cb(void *baton, md_reg_t *reg, md_t *md);
    
    /**
     * Invoke callback for all mds in this registry. Order is not guaranteed.
     * If the callback returns 0, iteration stops. Returns 0 if iteration was
     * aborted.
     */
    int md_reg_do(md_reg_do_cb *cb, void *baton, md_reg_t *reg, apr_pool_t *p);
    
    /**
     * Bitmask for fields that are updated.
     */
    #define MD_UPD_DOMAINS       0x00001
    #define MD_UPD_CA_URL        0x00002
    #define MD_UPD_CA_PROTO      0x00004
    #define MD_UPD_CA_ACCOUNT    0x00008
    #define MD_UPD_CONTACTS      0x00010
    #define MD_UPD_AGREEMENT     0x00020
    #define MD_UPD_DRIVE_MODE    0x00080
    #define MD_UPD_RENEW_WINDOW  0x00100
    #define MD_UPD_CA_CHALLENGES 0x00200
    #define MD_UPD_PKEY_SPEC     0x00400
    #define MD_UPD_REQUIRE_HTTPS 0x00800
    #define MD_UPD_TRANSITIVE    0x01000
    #define MD_UPD_MUST_STAPLE   0x02000
    #define MD_UPD_PROTO         0x04000
    #define MD_UPD_WARN_WINDOW   0x08000
    #define MD_UPD_STAPLING      0x10000
    #define MD_UPD_ALL           0x7FFFFFFF
    
    /**
     * Update the given fields for the managed domain. Take the new
     * values from the given md, all other values remain unchanged.
     */
    apr_status_t md_reg_update(md_reg_t *reg, apr_pool_t *p, 
                               const char *name, const md_t *md, 
                               int fields, int check_consistency);
    
    /**
     * Get the chain of public certificates of the managed domain md, starting with the cert
     * of the domain and going up the issuers. Returns APR_ENOENT when not available. 
     */
    apr_status_t md_reg_get_pubcert(const md_pubcert_t **ppubcert, md_reg_t *reg, 
                                    const md_t *md, int i, apr_pool_t *p);
    
    /**
     * Get the filenames of private key and pubcert of the MD - if they exist.
     * @return APR_ENOENT if one or both do not exist.
     */
    apr_status_t md_reg_get_cred_files(const char **pkeyfile, const char **pcertfile,
                                       md_reg_t *reg, md_store_group_t group, 
                                       const md_t *md, struct md_pkey_spec_t *spec, apr_pool_t *p);
    
    /**
     * Synchronize the given master mds with the store.
     */
    apr_status_t md_reg_sync_start(md_reg_t *reg, apr_array_header_t *master_mds, apr_pool_t *p);
    
    /**
     * Re-compute the state of the MD, given current store contents.
     */
    apr_status_t md_reg_sync_finish(md_reg_t *reg, md_t *md, apr_pool_t *p, apr_pool_t *ptemp);
    
    
    apr_status_t md_reg_remove(md_reg_t *reg, apr_pool_t *p, const char *name, int archive);
    
    /**
     * Delete the account from the local store.
     */
    apr_status_t md_reg_delete_acct(md_reg_t *reg, apr_pool_t *p, const char *acct_id);
    
    
    /**
     * Cleanup any challenges that are no longer in use.
     * 
     * @param reg   the registry
     * @param p     pool for permanent storage
     * @param ptemp pool for temporary storage
     * @param mds   the list of configured MDs
     */
    apr_status_t md_reg_cleanup_challenges(md_reg_t *reg, apr_pool_t *p, apr_pool_t *ptemp, 
                                           apr_array_header_t *mds);
    
    /**
     * Mark all information from group MD_SG_DOMAINS as readonly, deny future modifications 
     * (MD_SG_STAGING and MD_SG_CHALLENGES remain writeable). For the given MDs, cache
     * the public information (MDs themselves and their pubcerts or lack of).
     */
    apr_status_t md_reg_freeze_domains(md_reg_t *reg, apr_array_header_t *mds);
    
    /**
     * Return if the certificate of the MD should be renewed. This includes reaching
     * the renewal window of an otherwise valid certificate. It return also !0 iff
     * no certificate has been obtained yet.
     */
    int md_reg_should_renew(md_reg_t *reg, const md_t *md, apr_pool_t *p);
    
    /**
     * Return the timestamp when the certificate should be renewed. A value of 0
     * indicates that that renewal is not configured (see renew_mode).
     */
    apr_time_t md_reg_renew_at(md_reg_t *reg, const md_t *md, apr_pool_t *p);
    
    /**
     * Return the timestamp up to which *all* certificates for the MD can be used.
     * A value of 0 indicates that there is no certificate.
     */
    apr_time_t md_reg_valid_until(md_reg_t *reg, const md_t *md, apr_pool_t *p);
    
    /**
     * Return if a warning should be issued about the certificate expiration. 
     * This applies the configured warn window to the remaining lifetime of the 
     * current certiciate. If no certificate is present, this returns 0.
     */
    int md_reg_should_warn(md_reg_t *reg, const md_t *md, apr_pool_t *p);
    
    /**************************************************************************************************/
    /* protocol drivers */
    
    typedef struct md_proto_t md_proto_t;
    
    typedef struct md_proto_driver_t md_proto_driver_t;
    
    /** 
     * Operating environment for a protocol driver. This is valid only for the
     * duration of one run (init + renew, init + preload).
     */
    struct md_proto_driver_t {
        const md_proto_t *proto;
        apr_pool_t *p;
        void *baton;
        struct apr_table_t *env;
    
        md_reg_t *reg;
        md_store_t *store;
        const char *proxy_url;
        const char *ca_file;
        const md_t *md;
    
        int can_http;
        int can_https;
        int reset;
        int attempt;
        int retry_failover;
        apr_interval_time_t activation_delay;
    };
    
    typedef apr_status_t md_proto_init_cb(md_proto_driver_t *driver, struct md_result_t *result);
    typedef apr_status_t md_proto_renew_cb(md_proto_driver_t *driver, struct md_result_t *result);
    typedef apr_status_t md_proto_init_preload_cb(md_proto_driver_t *driver, struct md_result_t *result);
    typedef apr_status_t md_proto_preload_cb(md_proto_driver_t *driver, 
                                             md_store_group_t group, struct md_result_t *result);
    typedef apr_status_t md_proto_complete_md_cb(md_t *md, apr_pool_t *p);
    
    struct md_proto_t {
        const char *protocol;
        md_proto_init_cb *init;
        md_proto_renew_cb *renew;
        md_proto_init_preload_cb *init_preload;
        md_proto_preload_cb *preload;
        md_proto_complete_md_cb *complete_md;
    };
    
    /**
     * Run a test initialization of the renew protocol for the given MD. This verifies
     * basic parameter settings and is expected to return a description of encountered
     * problems in <pmessage> when != APR_SUCCESS.
     * A message return is allocated fromt the given pool.
     */
    apr_status_t md_reg_test_init(md_reg_t *reg, const md_t *md, struct apr_table_t *env, 
                                  struct md_result_t *result, apr_pool_t *p);
    
    /**
     * Obtain new credentials for the given managed domain in STAGING.
     * @param reg the registry instance
     * @param md the mdomain to renew
     * @param env global environment of settings
     * @param reset != 0 if any previous, partial information should be wiped
     * @param attempt the number of attempts made this far (for this md)
     * @param result for reporting results of the renewal
     * @param p the memory pool to use
     * @return APR_SUCCESS if new credentials have been staged successfully
     */
    apr_status_t md_reg_renew(md_reg_t *reg, const md_t *md, 
                              struct apr_table_t *env, int reset, int attempt,
                              struct md_result_t *result, apr_pool_t *p);
    
    /**
     * Load a new set of credentials for the managed domain from STAGING - if it exists. 
     * This will archive any existing credential data and make the staged set the new one
     * in DOMAINS.
     * If staging is incomplete or missing, the load will fail and all credentials remain
     * as they are.
     *
     * @return APR_SUCCESS on loading new data, APR_ENOENT when nothing is staged, error otherwise.
     */
    apr_status_t md_reg_load_staging(md_reg_t *reg, const md_t *md, struct apr_table_t *env, 
                                     struct md_result_t *result, apr_pool_t *p);
    
    /**
     * Check given MDomains for new data in staging areas and, if it exists, load
     * the new credentials. On encountering errors, leave the credentails as
     * they are.
     */
    apr_status_t md_reg_load_stagings(md_reg_t *reg, apr_array_header_t *mds,
                                      apr_table_t *env, apr_pool_t *p);
    
    void md_reg_set_renew_window_default(md_reg_t *reg, md_timeslice_t *renew_window);
    void md_reg_set_warn_window_default(md_reg_t *reg, md_timeslice_t *warn_window);
    
    struct md_job_t *md_reg_job_make(md_reg_t *reg, const char *mdomain, apr_pool_t *p);
    
    /**
     * Acquire a cooperative, global lock on registry modifications. Will
     * do nothing if locking is not configured.
     *
     * This will only prevent other children/processes/cluster nodes from
     * doing the same and does not protect individual store functions from
     * being called without it.
     * @param reg the registy
     * @param p memory pool to use
     * @param max_wait maximum time to wait in order to acquire
     * @return APR_SUCCESS when lock was obtained
     */
    apr_status_t md_reg_lock_global(md_reg_t *reg, apr_pool_t *p);
    
    /**
     * Realease the global registry lock. Will do nothing if there is no lock.
     */
    void md_reg_unlock_global(md_reg_t *reg, apr_pool_t *p);
    
    /**
     * @return != 0 iff `md` has any certificates known to be REVOKED.
     */
    int md_reg_has_revoked_certs(md_reg_t *reg, struct md_ocsp_reg_t *ocsp,
                                 const md_t *md, apr_pool_t *p);
    
    #endif /* mod_md_md_reg_h */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acme_authz.h�������������������������������������������������������������0000664�0001751�0001751�00000005770�14401065506�017655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_acme_authz_h
    #define mod_md_md_acme_authz_h
    
    struct apr_array_header_t;
    struct apr_table_t;
    struct md_acme_t;
    struct md_acme_acct_t;
    struct md_json_t;
    struct md_store_t;
    struct md_pkey_spec_t;
    struct md_result_t;
    
    typedef struct md_acme_challenge_t md_acme_challenge_t;
    
    /**************************************************************************************************/
    /* authorization request for a specific domain name */
    
    #define MD_AUTHZ_TYPE_DNS01         "dns-01"
    #define MD_AUTHZ_TYPE_HTTP01        "http-01"
    #define MD_AUTHZ_TYPE_TLSALPN01     "tls-alpn-01"
    
    typedef enum {
        MD_ACME_AUTHZ_S_UNKNOWN,
        MD_ACME_AUTHZ_S_PENDING,
        MD_ACME_AUTHZ_S_VALID,
        MD_ACME_AUTHZ_S_INVALID,
    } md_acme_authz_state_t;
    
    typedef struct md_acme_authz_t md_acme_authz_t;
    
    struct md_acme_authz_t {
        const char *domain;
        const char *url;
        md_acme_authz_state_t state;
        apr_time_t expires;
        const char *error_type;
        const char *error_detail;
        const struct md_json_t *error_subproblems;
        struct md_json_t *resource;
    };
    
    #define MD_FN_HTTP01            "acme-http-01.txt"
    
    void tls_alpn01_fnames(apr_pool_t *p, struct md_pkey_spec_t *kspec, char **keyfn, char **certfn );
    
    md_acme_authz_t *md_acme_authz_create(apr_pool_t *p);
    
    apr_status_t md_acme_authz_retrieve(md_acme_t *acme, apr_pool_t *p, const char *url,
                                        md_acme_authz_t **pauthz);
    apr_status_t md_acme_authz_update(md_acme_authz_t *authz, struct md_acme_t *acme, apr_pool_t *p);
    
    apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, struct md_acme_t *acme, 
                                       struct md_store_t *store, apr_array_header_t *challenges, 
                                       struct md_pkeys_spec_t *key_spec,
                                       apr_array_header_t *acme_tls_1_domains, const md_t *md,
                                       struct apr_table_t *env,
                                       apr_pool_t *p, const char **setup_token,
                                       struct md_result_t *result);
    
    apr_status_t md_acme_authz_teardown(struct md_store_t *store, const char *setup_token, 
                                        const md_t *md, struct apr_table_t *env, apr_pool_t *p);
    
    #endif /* md_acme_authz_h */
    ��������httpd-2.4.64/modules/md/md_store.c������������������������������������������������������������������0000664�0001751�0001751�00000031000�14301701440�016636� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_file_info.h>
    #include <apr_file_io.h>
    #include <apr_fnmatch.h>
    #include <apr_hash.h>
    #include <apr_strings.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_log.h"
    #include "md_json.h"
    #include "md_store.h"
    #include "md_util.h"
    
    /**************************************************************************************************/
    /* generic callback handling */
    
    #define ASPECT_MD           "md.json"
    #define ASPECT_CERT         "cert.pem"
    #define ASPECT_PKEY         "key.pem"
    #define ASPECT_CHAIN        "chain.pem"
    
    #define GNAME_ACCOUNTS     
    #define GNAME_CHALLENGES   
    #define GNAME_DOMAINS      
    #define GNAME_STAGING      
    #define GNAME_ARCHIVE      
    
    static const char *GROUP_NAME[] = {
        "none",
        "accounts",
        "challenges",
        "domains",
        "staging",
        "archive",
        "tmp",
        "ocsp",
        NULL
    };
    
    const char *md_store_group_name(unsigned int group)
    {
        if (group < sizeof(GROUP_NAME)/sizeof(GROUP_NAME[0])) {
            return GROUP_NAME[group];
        }
        return "UNKNOWN";
    }
    
    apr_status_t md_store_load(md_store_t *store, md_store_group_t group, 
                               const char *name, const char *aspect, 
                               md_store_vtype_t vtype, void **pdata, 
                               apr_pool_t *p)
    {
        return store->load(store, group, name, aspect, vtype, pdata, p);
    }
    
    apr_status_t md_store_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                               const char *name, const char *aspect, 
                               md_store_vtype_t vtype, void *data, 
                               int create)
    {
        return store->save(store, p, group, name, aspect, vtype, data, create);
    }
    
    apr_status_t md_store_remove(md_store_t *store, md_store_group_t group, 
                                 const char *name, const char *aspect, 
                                 apr_pool_t *p, int force)
    {
        return store->remove(store, group, name, aspect, p, force);
    }
    
    apr_status_t md_store_purge(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                 const char *name)
    {
        return store->purge(store, p, group, name);
    }
    
    apr_status_t md_store_iter(md_store_inspect *inspect, void *baton, md_store_t *store, 
                               apr_pool_t *p, md_store_group_t group, const char *pattern, 
                               const char *aspect, md_store_vtype_t vtype)
    {
        return store->iterate(inspect, baton, store, p, group, pattern, aspect, vtype);
    }
    
    apr_status_t md_store_load_json(md_store_t *store, md_store_group_t group, 
                                    const char *name, const char *aspect, 
                                    struct md_json_t **pdata, apr_pool_t *p)
    {
        return md_store_load(store, group, name, aspect, MD_SV_JSON, (void**)pdata, p);
    }
    
    apr_status_t md_store_save_json(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                    const char *name, const char *aspect, 
                                    struct md_json_t *data, int create)
    {
        return md_store_save(store, p, group, name, aspect, MD_SV_JSON, (void*)data, create);
    }
    
    apr_status_t md_store_move(md_store_t *store, apr_pool_t *p, 
                               md_store_group_t from, md_store_group_t to,
                               const char *name, int archive)
    {
        return store->move(store, p, from, to, name, archive);
    }
    
    apr_status_t md_store_get_fname(const char **pfname, 
                                    md_store_t *store, md_store_group_t group, 
                                    const char *name, const char *aspect, 
                                    apr_pool_t *p)
    {
        if (store->get_fname) {
            return store->get_fname(pfname, store, group, name, aspect, p);
        }
        return APR_ENOTIMPL;
    }
    
    int md_store_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
                          const char *name, const char *aspect, apr_pool_t *p)
    {
        return store->is_newer(store, group1, group2, name, aspect, p);
    }
    
    apr_time_t md_store_get_modified(md_store_t *store, md_store_group_t group,  
                                     const char *name, const char *aspect, apr_pool_t *p)
    {
        return store->get_modified(store, group, name, aspect, p);
    }
    
    apr_status_t md_store_iter_names(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                     apr_pool_t *p, md_store_group_t group, const char *pattern)
    {
        return store->iterate_names(inspect, baton, store, p, group, pattern);
    }
    
    apr_status_t md_store_remove_not_modified_since(md_store_t *store, apr_pool_t *p, 
                                                    apr_time_t modified,
                                                    md_store_group_t group, 
                                                    const char *name, 
                                                    const char *aspect)
    {
        return store->remove_nms(store, p, modified, group, name, aspect);
    }
    
    apr_status_t md_store_rename(md_store_t *store, apr_pool_t *p,
                                 md_store_group_t group, const char *name, const char *to)
    {
        return store->rename(store, p, group, name, to);
    }
    
    /**************************************************************************************************/
    /* convenience */
    
    typedef struct {
        md_store_t *store;
        md_store_group_t group;
    } md_group_ctx;
    
    apr_status_t md_load(md_store_t *store, md_store_group_t group, 
                         const char *name, md_t **pmd, apr_pool_t *p)
    {
        md_json_t *json;
        apr_status_t rv;
        
        rv = md_store_load_json(store, group, name, MD_FN_MD, pmd? &json : NULL, p);
        if (APR_SUCCESS == rv) {
            if (pmd) {
                *pmd = md_from_json(json, p);
            }
            return APR_SUCCESS;
        }
        return rv;
    }
    
    static apr_status_t p_save(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_group_ctx *ctx = baton;
        md_json_t *json;
        md_t *md;
        int create;
        
        md = va_arg(ap, md_t *);
        create = va_arg(ap, int);
    
        json = md_to_json(md, ptemp);
        assert(json);
        assert(md->name);
        return md_store_save_json(ctx->store, p, ctx->group, md->name, MD_FN_MD, json, create);
    }
    
    apr_status_t md_save(md_store_t *store, apr_pool_t *p, 
                         md_store_group_t group, md_t *md, int create)
    {
        md_group_ctx ctx;
        
        ctx.store = store;
        ctx.group = group;
        return md_util_pool_vdo(p_save, &ctx, p, md, create, NULL);
    }
    
    static apr_status_t p_remove(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_group_ctx *ctx = baton;
        const char *name;
        int force;
        
        (void)p;
        name = va_arg(ap, const char *);
        force = va_arg(ap, int);
    
        assert(name);
        return md_store_remove(ctx->store, ctx->group, name, MD_FN_MD, ptemp, force);
    }
    
    apr_status_t md_remove(md_store_t *store, apr_pool_t *p, 
                           md_store_group_t group, const char *name, int force)
    {
        md_group_ctx ctx;
        
        ctx.store = store;
        ctx.group = group;
        return md_util_pool_vdo(p_remove, &ctx, p, name, force, NULL);
    }
    
    int md_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
                          const char *name, apr_pool_t *p)
    {
        return md_store_is_newer(store, group1, group2, name, MD_FN_MD, p);
    }
    
    
    typedef struct {
        apr_pool_t *p;
        apr_array_header_t *mds;
    } md_load_ctx;
    
    static const char *pk_filename(const char *keyname, const char *base, apr_pool_t *p)
    {
        char *s, *t;
        /* We also run on various filesystems with difference upper/lower preserve matching
         * rules. Normalize the names we use, since private key specifications are basically
         * user input. */
        s = (keyname && apr_strnatcasecmp("rsa", keyname))?
            apr_pstrcat(p, base, ".", keyname, ".pem", NULL)
            : apr_pstrcat(p, base, ".pem", NULL);
        for (t = s; *t; t++ )
            *t = (char)apr_tolower(*t);
        return s;
    }
    
    const char *md_pkey_filename(md_pkey_spec_t *spec, apr_pool_t *p)
    {
        return pk_filename(md_pkey_spec_name(spec), "privkey", p);
    }
    
    const char *md_chain_filename(md_pkey_spec_t *spec, apr_pool_t *p)
    {
        return pk_filename(md_pkey_spec_name(spec), "pubcert", p);
    }
    
    apr_status_t md_pkey_load(md_store_t *store, md_store_group_t group, const char *name, 
                              md_pkey_spec_t *spec, md_pkey_t **ppkey, apr_pool_t *p)
    {
        const char *fname = md_pkey_filename(spec, p);
        return md_store_load(store, group, name, fname, MD_SV_PKEY, (void**)ppkey, p);
    }
    
    apr_status_t md_pkey_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, 
                              md_pkey_spec_t *spec, struct md_pkey_t *pkey, int create)
    {
        const char *fname = md_pkey_filename(spec, p);
        return md_store_save(store, p, group, name, fname, MD_SV_PKEY, pkey, create);
    }
    
    apr_status_t md_pubcert_load(md_store_t *store, md_store_group_t group, const char *name, 
                                 md_pkey_spec_t *spec, struct apr_array_header_t **ppubcert, 
                                 apr_pool_t *p)
    {
        const char *fname = md_chain_filename(spec, p);
        return md_store_load(store, group, name, fname, MD_SV_CHAIN, (void**)ppubcert, p);
    }
    
    apr_status_t md_pubcert_save(md_store_t *store, apr_pool_t *p, 
                                 md_store_group_t group, const char *name, 
                                 md_pkey_spec_t *spec, struct apr_array_header_t *pubcert, int create)
    {
        const char *fname = md_chain_filename(spec, p);
        return md_store_save(store, p, group, name, fname, MD_SV_CHAIN, pubcert, create);
    }
    
    apr_status_t md_creds_load(md_store_t *store, md_store_group_t group, const char *name, 
                               md_pkey_spec_t *spec, md_credentials_t **pcreds, apr_pool_t *p)
    {
        md_credentials_t *creds = apr_pcalloc(p, sizeof(*creds));
        apr_status_t rv;
        
        creds->spec = spec;
        if (APR_SUCCESS != (rv = md_pkey_load(store, group, name, spec, &creds->pkey, p))) {
            goto leave;
        }
        /* chain is optional */
        rv = md_pubcert_load(store, group, name, spec, &creds->chain, p);
        if (APR_STATUS_IS_ENOENT(rv)) rv = APR_SUCCESS;
    leave:
        *pcreds = (APR_SUCCESS == rv)? creds : NULL;
        return rv;
    }
    
    apr_status_t md_creds_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                               const char *name, md_credentials_t *creds, int create)
    {
        apr_status_t rv;
    
        if (APR_SUCCESS != (rv = md_pkey_save(store, p, group, name, creds->spec, creds->pkey, create))) {
            goto leave;
        }
        rv = md_pubcert_save(store, p, group, name, creds->spec, creds->chain, create);
    leave:
        return rv;
    }
    
    typedef struct {
        md_store_t *store;
        md_store_group_t group;
        const char *pattern;
        const char *aspect;
        md_store_md_inspect *inspect;
        void *baton;
    } inspect_md_ctx;
    
    static int insp_md(void *baton, const char *name, const char *aspect, 
                       md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
    {
        inspect_md_ctx *ctx = baton;
        
        if (!strcmp(MD_FN_MD, aspect) && vtype == MD_SV_JSON) {
            md_t *md = md_from_json(value, ptemp);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting md at: %s", name);
            return ctx->inspect(ctx->baton, ctx->store, md, ptemp);
        }
        return 1;
    }
    
    apr_status_t md_store_md_iter(md_store_md_inspect *inspect, void *baton, md_store_t *store, 
                                  apr_pool_t *p, md_store_group_t group, const char *pattern)
    {
        inspect_md_ctx ctx;
        
        ctx.store = store;
        ctx.group = group;
        ctx.inspect = inspect;
        ctx.baton = baton;
        
        return md_store_iter(insp_md, &ctx, store, p, group, pattern, MD_FN_MD, MD_SV_JSON);
    }
    
    apr_status_t md_store_lock_global(md_store_t *store, apr_pool_t *p, apr_time_t max_wait)
    {
        return store->lock_global(store, p, max_wait);
    }
    
    void md_store_unlock_global(md_store_t *store, apr_pool_t *p)
    {
        store->unlock_global(store, p);
    }
    httpd-2.4.64/modules/md/md_ocsp.h�������������������������������������������������������������������0000664�0001751�0001751�00000005627�14240433464�016505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 md_ocsp_h
    #define md_ocsp_h
    
    struct md_data_t;
    struct md_job_t;
    struct md_json_t;
    struct md_result_t;
    struct md_store_t;
    struct md_timeslice_t;
    
    typedef enum {
        MD_OCSP_CERT_ST_UNKNOWN,
        MD_OCSP_CERT_ST_GOOD,
        MD_OCSP_CERT_ST_REVOKED,
    } md_ocsp_cert_stat_t;
    
    const char *md_ocsp_cert_stat_name(md_ocsp_cert_stat_t stat);
    md_ocsp_cert_stat_t md_ocsp_cert_stat_value(const char *name);
    
    typedef struct md_ocsp_reg_t md_ocsp_reg_t;
    
    apr_status_t md_ocsp_reg_make(md_ocsp_reg_t **preg, apr_pool_t *p,
                                  struct md_store_t *store, 
                                  const md_timeslice_t *renew_window,
                                  const char *user_agent, const char *proxy_url,
                                  apr_time_t min_delay);
    
    apr_status_t md_ocsp_init_id(struct md_data_t *id, apr_pool_t *p, const md_cert_t *cert);
    
    apr_status_t md_ocsp_prime(md_ocsp_reg_t *reg, const char *ext_id, apr_size_t ext_id_len,
                               md_cert_t *x, md_cert_t *issuer, const md_t *md);
    
    typedef void md_ocsp_copy_der(const unsigned char *der, apr_size_t der_len, void *userdata);
    
    apr_status_t md_ocsp_get_status(md_ocsp_copy_der *cb, void *userdata, md_ocsp_reg_t *reg,
                                    const char *ext_id, apr_size_t ext_id_len,
                                    apr_pool_t *p, const md_t *md);
    
    apr_status_t md_ocsp_get_meta(md_ocsp_cert_stat_t *pstat, md_timeperiod_t *pvalid,
                                  md_ocsp_reg_t *reg, const md_cert_t *cert,
                                  apr_pool_t *p, const md_t *md);
    
    apr_size_t md_ocsp_count(md_ocsp_reg_t *reg);
    
    void md_ocsp_renew(md_ocsp_reg_t *reg, apr_pool_t *p, apr_pool_t *ptemp, apr_time_t *pnext_run);
    
    apr_status_t md_ocsp_remove_responses_older_than(md_ocsp_reg_t *reg, apr_pool_t *p, 
                                                     apr_time_t timestamp);
    
    void md_ocsp_get_summary(struct md_json_t **pjson, md_ocsp_reg_t *reg, apr_pool_t *p);
    void md_ocsp_get_status_all(struct md_json_t **pjson, md_ocsp_reg_t *reg, apr_pool_t *p);
    
    struct md_job_t *md_ocsp_job_make(md_ocsp_reg_t *ocsp, const char *mdomain, apr_pool_t *p);
    
    #endif /* md_ocsp_h */
    ���������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acme_drive.c�������������������������������������������������������������0000664�0001751�0001751�00000126350�14750656217�017640� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_buckets.h>
    #include <apr_hash.h>
    #include <apr_uri.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_jws.h"
    #include "md_http.h"
    #include "md_log.h"
    #include "md_result.h"
    #include "md_reg.h"
    #include "md_store.h"
    #include "md_util.h"
    
    #include "md_acme.h"
    #include "md_acme_acct.h"
    #include "md_acme_authz.h"
    #include "md_acme_order.h"
    
    #include "md_acme_drive.h"
    #include "md_acmev2_drive.h"
    
    /**************************************************************************************************/
    /* account setup */
    
    static apr_status_t use_staged_acct(md_acme_t *acme, struct md_store_t *store,
                                        const md_t *md, apr_pool_t *p)
    {
        md_acme_acct_t *acct;
        md_pkey_t *pkey;
        apr_status_t rv;
        
        if (APR_SUCCESS == (rv = md_acme_acct_load(&acct, &pkey, store, 
                                                   MD_SG_STAGING, md->name, acme->p))) {
            acme->acct_id = NULL;
            acme->acct = acct;
            acme->acct_key = pkey;
            rv = md_acme_acct_validate(acme, NULL, p);
        }
        return rv;
    }
    
    static apr_status_t save_acct_staged(md_acme_t *acme, md_store_t *store, 
                                         const char *md_name, apr_pool_t *p)
    {
        md_json_t *jacct;
        apr_status_t rv;
        
        jacct = md_acme_acct_to_json(acme->acct, p);
        
        rv = md_store_save(store, p, MD_SG_STAGING, md_name, MD_FN_ACCOUNT, MD_SV_JSON, jacct, 0);
        if (APR_SUCCESS == rv) {
            rv = md_store_save(store, p, MD_SG_STAGING, md_name, MD_FN_ACCT_KEY, 
                               MD_SV_PKEY, acme->acct_key, 0);
        }
        return rv;
    }
    
    apr_status_t md_acme_drive_set_acct(md_proto_driver_t *d, md_result_t *result) 
    {
        md_acme_driver_t *ad = d->baton;
        md_t *md = ad->md;
        apr_status_t rv = APR_SUCCESS;
        int update_md = 0, update_acct = 0;
        
        md_result_activity_printf(result, "Selecting account to use for %s", d->md->name);
        md_acme_clear_acct(ad->acme);
        
        /* Do we have a staged (modified) account? */
        if (APR_SUCCESS == (rv = use_staged_acct(ad->acme, d->store, md, d->p))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "re-using staged account");
        }
        else if (!APR_STATUS_IS_ENOENT(rv)) {
            goto leave;
        }
        
        /* Get an account for the ACME server for this MD */
        if (!ad->acme->acct && md->ca_account) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "re-use account '%s'", md->ca_account);
            rv = md_acme_use_acct_for_md(ad->acme, d->store, d->p, md->ca_account, md);
            if (APR_STATUS_IS_ENOENT(rv) || APR_STATUS_IS_EINVAL(rv)) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "rejected %s", md->ca_account);
                md->ca_account = NULL;
                update_md = 1;
            }
            else if (APR_SUCCESS != rv) {
                goto leave;
            }
        }
    
        if (!ad->acme->acct && !md->ca_account) {
            /* Find a local account for server, store at MD */ 
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%s: looking at existing accounts",
                          d->proto->protocol);
            if (APR_SUCCESS == (rv = md_acme_find_acct_for_md(ad->acme, d->store, md))) {
                md->ca_account = md_acme_acct_id_get(ad->acme);
                update_md = 1;
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%s: using account %s (id=%s)",
                              d->proto->protocol, ad->acme->acct->url, md->ca_account);
            }
        }
        
        if (!ad->acme->acct) {
            /* No account staged, no suitable found in store, register a new one */
            md_result_activity_printf(result, "Creating new ACME account for %s", d->md->name);
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%s: creating new account", 
                          d->proto->protocol);
            
            if (!ad->md->contacts || apr_is_empty_array(md->contacts)) {
                rv = APR_EINVAL;
                md_result_printf(result, rv, "No contact information is available for MD %s. "
                                 "Configure one using the MDContactEmail or ServerAdmin directive.", md->name);            
                md_result_log(result, MD_LOG_ERR);
                goto leave;
            }
            
            /* ACMEv1 allowed registration of accounts without accepted Terms-of-Service.
             * ACMEv2 requires it. Fail early in this case with a meaningful error message.
             */ 
            if (!md->ca_agreement) {
                md_result_printf(result, APR_EINVAL,
                      "the CA requires you to accept the terms-of-service "
                      "as specified in <%s>. "
                      "Please read the document that you find at that URL and, "
                      "if you agree to the conditions, configure "
                      "\"MDCertificateAgreement accepted\" "
                      "in your Apache. Then (graceful) restart the server to activate.", 
                      ad->acme->ca_agreement);
                md_result_log(result, MD_LOG_ERR);
                rv = result->status;
                goto leave;
            }
        
            if (ad->acme->eab_required && (!md->ca_eab_kid || !strcmp("none", md->ca_eab_kid))) {
                md_result_printf(result, APR_EINVAL,
                      "the CA requires 'External Account Binding' which is not "
                      "configured. This means you need to obtain a 'Key ID' and a "
                      "'HMAC' from the CA and configure that using the "
                      "MDExternalAccountBinding directive in your config. "
                      "The creation of a new ACME account will most likely fail, "
                      "but an attempt is made anyway.",
                      ad->acme->ca_agreement);
                md_result_log(result, MD_LOG_INFO);
            }
    
            rv = md_acme_acct_register(ad->acme, d->store, md, d->p);
            if (APR_SUCCESS != rv) {
                if (APR_SUCCESS != ad->acme->last->status) {
                    md_result_dup(result, ad->acme->last);
                    md_result_log(result, MD_LOG_ERR);
                }
                goto leave;
            }
    
            md->ca_account = NULL;
            update_md = 1;
            update_acct = 1;
        }
        
    leave:
        /* Persist MD changes in STAGING, so we pick them up on next run */
        if (APR_SUCCESS == rv && update_md) {
            rv = md_save(d->store, d->p, MD_SG_STAGING, ad->md, 0);
        }
        /* Persist account changes in STAGING, so we pick them up on next run */
        if (APR_SUCCESS == rv && update_acct) {
            rv = save_acct_staged(ad->acme, d->store, md->name, d->p);
        }
        return rv;
    }
    
    /**************************************************************************************************/
    /* poll cert */
    
    static void get_up_link(md_proto_driver_t *d, apr_table_t *headers)
    {
        md_acme_driver_t *ad = d->baton;
    
        ad->chain_up_link = md_link_find_relation(headers, d->p, "up");
        if (ad->chain_up_link) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, 
                          "server reports up link as %s", ad->chain_up_link);
        }
    } 
    
    static apr_status_t add_http_certs(apr_array_header_t *chain, apr_pool_t *p,
                                       const md_http_response_t *res)
    {
        apr_status_t rv = APR_SUCCESS;
        const char *ct;
        
        ct = apr_table_get(res->headers, "Content-Type");
        ct = md_util_parse_ct(res->req->pool, ct);
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, p,
                      "parse certs from %s -> %d (%s)", res->req->url, res->status, ct);
        if (ct && !strcmp("application/x-pkcs7-mime", ct)) {
            /* this looks like a root cert and we do not want those in our chain */
            goto out; 
        }
    
        /* Lets try to read one or more certificates */
        if (APR_SUCCESS != (rv = md_cert_chain_read_http(chain, p, res))
            && APR_STATUS_IS_ENOENT(rv)) {
            rv = APR_EAGAIN;
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, 
                          "cert not in response from %s", res->req->url);
        }
    out:
        return rv;
    }
    
    static apr_status_t on_add_cert(md_acme_t *acme, const md_http_response_t *res, void *baton)
    {
        md_proto_driver_t *d = baton;
        md_acme_driver_t *ad = d->baton;
        apr_status_t rv = APR_SUCCESS;
        int count;
        
        (void)acme;
        count = ad->cred->chain->nelts;
        if (APR_SUCCESS == (rv = add_http_certs(ad->cred->chain, d->p, res))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%d certs parsed", 
                          ad->cred->chain->nelts - count);
            get_up_link(d, res->headers);
        }
        return rv;
    }
    
    static apr_status_t get_cert(void *baton, int attempt)
    {
        md_proto_driver_t *d = baton;
        md_acme_driver_t *ad = d->baton;
        
        (void)attempt;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, d->p, "retrieving cert from %s",
                      ad->order->certificate);
        return md_acme_GET(ad->acme, ad->order->certificate, NULL, NULL, on_add_cert, NULL, d);
    }
    
    apr_status_t md_acme_drive_cert_poll(md_proto_driver_t *d, int only_once)
    {
        md_acme_driver_t *ad = d->baton;
        apr_status_t rv;
        
        assert(ad->md);
        assert(ad->acme);
        assert(ad->order);
        assert(ad->order->certificate);
        
        if (only_once) {
            rv = get_cert(d, 0);
        }
        else {
            rv = md_util_try(get_cert, d, 1, ad->cert_poll_timeout, 0, 0, 1);
        }
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "poll for cert at %s", ad->order->certificate);
        return rv;
    }
    
    /**************************************************************************************************/
    /* order finalization */
    
    static apr_status_t on_init_csr_req(md_acme_req_t *req, void *baton)
    {
        md_proto_driver_t *d = baton;
        md_acme_driver_t *ad = d->baton;
        md_json_t *jpayload;
    
        jpayload = md_json_create(req->p);
        md_json_sets(ad->csr_der_64, jpayload, MD_KEY_CSR, NULL);
        
        return md_acme_req_body_init(req, jpayload);
    } 
    
    static apr_status_t csr_req(md_acme_t *acme, const md_http_response_t *res, void *baton)
    {
        md_proto_driver_t *d = baton;
        md_acme_driver_t *ad = d->baton;
        const char *location;
        md_cert_t *cert;
        apr_status_t rv = APR_SUCCESS;
        
        (void)acme;
        location = apr_table_get(res->headers, "location");
        if (!location)
          return rv;
    
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p,
                      "cert created with location header (old ACMEv1 style)");
        ad->order->certificate = apr_pstrdup(d->p, location);
        if (APR_SUCCESS != (rv = md_acme_order_save(d->store, d->p, MD_SG_STAGING, 
                                                    d->md->name, ad->order, 0))) { 
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, APR_EINVAL, d->p, 
                          "%s: saving cert url %s", d->md->name, location);
            return rv;
        }
        
        /* Check if it already was sent with this response */
        ad->chain_up_link = NULL;
        if (APR_SUCCESS == (rv = md_cert_read_http(&cert, d->p, res))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "cert parsed");
            apr_array_clear(ad->cred->chain);
            APR_ARRAY_PUSH(ad->cred->chain, md_cert_t*) = cert;
            get_up_link(d, res->headers);
        }
        else if (APR_STATUS_IS_ENOENT(rv)) {
            rv = APR_SUCCESS;
            if (location) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, 
                              "cert not in response, need to poll %s", location);
            }
        }
        
        return rv;
    }
    
    /**
     * Pre-Req: all domains have been validated by the ACME server, e.g. all have AUTHZ
     * resources that have status 'valid'
     *  - acme_driver->cred keeps the credentials to setup (key spec) 
     * - Setup private key, if not already there
     * - Generate a CSR with org, contact, etc
     * - Optionally enable must-staple OCSP extension
     * - Submit CSR, expect 201 with location
     * - POLL location for certificate
     * - store certificate
     * - retrieve cert chain information from cert
     * - GET cert chain
     * - store cert chain
     */
    apr_status_t md_acme_drive_setup_cred_chain(md_proto_driver_t *d, md_result_t *result)
    {
        md_acme_driver_t *ad = d->baton;
        md_pkey_spec_t *spec;
        md_pkey_t *privkey;
        apr_status_t rv;
    
        md_result_activity_printf(result, "Finalizing order for %s", ad->md->name);
    
        assert(ad->cred);
        spec = ad->cred->spec;
            
        rv = md_pkey_load(d->store, MD_SG_STAGING, d->md->name, spec, &privkey, d->p);
        if (APR_STATUS_IS_ENOENT(rv)) {
            if (APR_SUCCESS == (rv = md_pkey_gen(&privkey, d->p, spec))) {
                rv = md_pkey_save(d->store, d->p, MD_SG_STAGING, d->md->name, spec, privkey, 1);
            }
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, 
                          "%s: generate %s privkey", d->md->name, md_pkey_spec_name(spec));
        }
        if (APR_SUCCESS != rv) goto leave;
        
        md_result_activity_printf(result, "Creating %s CSR", md_pkey_spec_name(spec));
        rv = md_cert_req_create(&ad->csr_der_64, d->md->name, ad->domains, 
                                ad->md->must_staple, privkey, d->p);
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%s: create %s CSR", 
                      d->md->name, md_pkey_spec_name(spec));
        if (APR_SUCCESS != rv) goto leave;
        
        md_result_activity_printf(result, "Submitting %s CSR to CA", md_pkey_spec_name(spec));
        assert(ad->order->finalize);
        rv = md_acme_POST(ad->acme, ad->order->finalize, on_init_csr_req, NULL, csr_req, NULL, d);
    
    leave:
        md_acme_report_result(ad->acme, rv, result);
        return rv;
    }
    
    /**************************************************************************************************/
    /* cert chain retrieval */
    
    static apr_status_t on_add_chain(md_acme_t *acme, const md_http_response_t *res, void *baton)
    {
        md_proto_driver_t *d = baton;
        md_acme_driver_t *ad = d->baton;
        apr_status_t rv = APR_SUCCESS;
        const char *ct;
        
        (void)acme;
        ct = apr_table_get(res->headers, "Content-Type");
        ct = md_util_parse_ct(res->req->pool, ct);
        if (ct && !strcmp("application/x-pkcs7-mime", ct)) {
            /* root cert most likely, end it here */
            return APR_SUCCESS;
        }
        
        if (APR_SUCCESS == (rv = add_http_certs(ad->cred->chain, d->p, res))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "chain cert parsed");
            get_up_link(d, res->headers);
        }
        return rv;
    }
    
    static apr_status_t get_chain(void *baton, int attempt)
    {
        md_proto_driver_t *d = baton;
        md_acme_driver_t *ad = d->baton;
        const char *prev_link = NULL;
        apr_status_t rv = APR_SUCCESS;
    
        while (APR_SUCCESS == rv && ad->cred->chain->nelts < 10) {
            int nelts = ad->cred->chain->nelts;
            
            if (ad->chain_up_link && (!prev_link || strcmp(prev_link, ad->chain_up_link))) {
                prev_link = ad->chain_up_link;
    
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, 
                              "next chain cert at  %s", ad->chain_up_link);
                rv = md_acme_GET(ad->acme, ad->chain_up_link, NULL, NULL, on_add_chain, NULL, d);
                
                if (APR_SUCCESS == rv && nelts == ad->cred->chain->nelts) {
                    break;
                }
                else if (APR_SUCCESS != rv) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p,
                                  "error retrieving certificate from %s", ad->chain_up_link);
                    return rv;
                }
            }
            else if (ad->cred->chain->nelts <= 1) {
                /* This cannot be the complete chain (no one signs new web certs with their root)
                 * and we did not see a "Link: ...rel=up", so we do not know how to continue. */
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, 
                              "no link header 'up' for new certificate, unable to retrieve chain");
                rv = APR_EINVAL;
                break;
            }
            else {
                rv = APR_SUCCESS;
                break;
            }
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, d->p, 
                      "got chain with %d certs (%d. attempt)", ad->cred->chain->nelts, attempt);
        return rv;
    }
    
    static apr_status_t ad_chain_retrieve(md_proto_driver_t *d)
    {
        md_acme_driver_t *ad = d->baton;
        apr_status_t rv;
        
        /* This may be called repeatedly and needs to progress. The relevant state is in
         * ad->cred->chain          the certificate chain, starting with the new cert for the md
         * ad->order->certificate   the url where ACME offers us the new md certificate. This may
         *                          be a single one or even the complete chain
         * ad->chain_up_link         in case the last certificate retrieval did not end the chain,
         *                          the link header with relation "up" gives us the location
         *                          for the next cert in the chain
         */
        if (md_array_is_empty(ad->cred->chain)) {
            /* Need to start at the order */
            ad->chain_up_link = NULL;
            if (!ad->order) {
                rv = APR_EGENERAL;
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, 
                    "%s: asked to retrieve chain, but no order in context", d->md->name);
                goto out;
            }
            if (!ad->order->certificate) {
                rv = APR_EGENERAL;
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, 
                    "%s: asked to retrieve chain, but no certificate url part of order", d->md->name);
                goto out;
            }
            
            if (APR_SUCCESS != (rv = md_acme_drive_cert_poll(d, 0))) {
                goto out;
            }
        }
        
        rv = md_util_try(get_chain, d, 0, ad->cert_poll_timeout, 0, 0, 0);
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "chain retrieved");
        
    out:
        return rv;
    }
    
    /**************************************************************************************************/
    /* ACME driver init */
    
    static apr_status_t acme_driver_preload_init(md_proto_driver_t *d, md_result_t *result)
    {
        md_acme_driver_t *ad;
        md_credentials_t *cred;
        int i;
        
        md_result_set(result, APR_SUCCESS, NULL);
        
        ad = apr_pcalloc(d->p, sizeof(*ad));
        
        d->baton = ad;
        
        ad->driver = d;
        ad->authz_monitor_timeout = apr_time_from_sec(300);
        ad->cert_poll_timeout = apr_time_from_sec(300);
        ad->ca_challenges = apr_array_make(d->p, 3, sizeof(const char*));
        
        /* We want to obtain credentials (key+certificate) for every key spec in this MD */
        ad->creds = apr_array_make(d->p, md_pkeys_spec_count(d->md->pks), sizeof(md_credentials_t*));
        for (i = 0; i < md_pkeys_spec_count(d->md->pks); ++i) {
            cred = apr_pcalloc(d->p, sizeof(*cred));
            cred->spec = md_pkeys_spec_get(d->md->pks, i);
            cred->chain = apr_array_make(d->p, 5, sizeof(md_cert_t*));
            APR_ARRAY_PUSH(ad->creds, md_credentials_t*) = cred;
        }
        
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, result->status, d->p, 
                      "%s: init_base driver", d->md->name);
        return result->status;
    }
    
    static apr_status_t acme_driver_init(md_proto_driver_t *d, md_result_t *result)
    {
        md_acme_driver_t *ad;
        int dis_http, dis_https, dis_alpn_acme, dis_dns;
        const char *challenge;
    
        acme_driver_preload_init(d, result);
        md_result_set(result, APR_SUCCESS, NULL);
        if (APR_SUCCESS != result->status) goto leave;
        
        ad = d->baton;
    
        /* We can only support challenges if the server is reachable from the outside
         * via port 80 and/or 443. These ports might be mapped for httpd to something
         * else, but a mapping needs to exist. */
        challenge = apr_table_get(d->env, MD_KEY_CHALLENGE); 
        if (challenge) {
            APR_ARRAY_PUSH(ad->ca_challenges, const char*) = apr_pstrdup(d->p, challenge);
        }
        else if (d->md->ca_challenges && d->md->ca_challenges->nelts > 0) {
            /* pre-configured set for this managed domain */
            apr_array_cat(ad->ca_challenges, d->md->ca_challenges);
        }
        else {
            /* free to chose. Add all we support and see what we get offered */
            APR_ARRAY_PUSH(ad->ca_challenges, const char*) = MD_AUTHZ_TYPE_TLSALPN01;
            APR_ARRAY_PUSH(ad->ca_challenges, const char*) = MD_AUTHZ_TYPE_HTTP01;
            APR_ARRAY_PUSH(ad->ca_challenges, const char*) = MD_AUTHZ_TYPE_DNS01;
    
            if (!d->can_http && !d->can_https 
                && md_array_str_index(ad->ca_challenges, MD_AUTHZ_TYPE_DNS01, 0, 0) < 0) {
                md_result_printf(result, APR_EGENERAL,
                                 "the server seems neither reachable via http (port 80) nor https (port 443). "
                                 "Please look at the MDPortMap configuration directive on how to correct this. "
                                 "The ACME protocol needs at least one of those so the CA can talk to the server "
                                 "and verify a domain ownership. Alternatively, you may configure support "
                                 "for the %s challenge directive.", MD_AUTHZ_TYPE_DNS01);
                goto leave;
            }
    
            dis_http = dis_https = dis_alpn_acme = dis_dns = 0;
            if (!d->can_http && md_array_str_index(ad->ca_challenges, MD_AUTHZ_TYPE_HTTP01, 0, 1) >= 0) {
                ad->ca_challenges = md_array_str_remove(d->p, ad->ca_challenges, MD_AUTHZ_TYPE_HTTP01, 0);
                dis_http = 1;
            }
            if (!d->can_https && md_array_str_index(ad->ca_challenges, MD_AUTHZ_TYPE_TLSALPN01, 0, 1) >= 0) {
                ad->ca_challenges = md_array_str_remove(d->p, ad->ca_challenges, MD_AUTHZ_TYPE_TLSALPN01, 0);
                dis_https = 1;
            }
            if (apr_is_empty_array(d->md->acme_tls_1_domains)
                && md_array_str_index(ad->ca_challenges, MD_AUTHZ_TYPE_TLSALPN01, 0, 1) >= 0) {
                ad->ca_challenges = md_array_str_remove(d->p, ad->ca_challenges, MD_AUTHZ_TYPE_TLSALPN01, 0);
                dis_alpn_acme = 1;
            }
            if (!apr_table_get(d->env, MD_KEY_CMD_DNS01)
                && NULL == d->md->dns01_cmd
                && md_array_str_index(ad->ca_challenges, MD_AUTHZ_TYPE_DNS01, 0, 1) >= 0) {
                ad->ca_challenges = md_array_str_remove(d->p, ad->ca_challenges, MD_AUTHZ_TYPE_DNS01, 0);
                dis_dns = 1;
            }
    
            if (apr_is_empty_array(ad->ca_challenges)) {
                md_result_printf(result, APR_EGENERAL, 
                                 "None of the ACME challenge methods configured for this domain are suitable.%s%s%s%s",
                                 dis_http? " The http: challenge 'http-01' is disabled because the server seems not reachable on public port 80." : "",
                                 dis_https? " The https: challenge 'tls-alpn-01' is disabled because the server seems not reachable on public port 443." : "",
                                 dis_alpn_acme? " The https: challenge 'tls-alpn-01' is disabled because the Protocols configuration does not include the 'acme-tls/1' protocol." : "",
                                 dis_dns? " The DNS challenge 'dns-01' is disabled because the directive 'MDChallengeDns01' is not configured." : ""
                                 );
                goto leave;
            }
        }
    
        md_result_printf(result, 0, "MDomain %s initialized with support for ACME challenges %s",
                  d->md->name, apr_array_pstrcat(d->p, ad->ca_challenges, ' '));
    
    leave:    
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, result->status, d->p, "%s: init driver", d->md->name);
        return result->status;
    }
    
    /**************************************************************************************************/
    /* ACME staging */
    
    static apr_status_t load_missing_creds(md_proto_driver_t *d)
    {
        md_acme_driver_t *ad = d->baton;
        md_credentials_t *cred;
        apr_array_header_t *chain;
        int i, complete;
        apr_status_t rv;
        
        complete = 1;
        for (i = 0; i < ad->creds->nelts; ++i) {
            rv = APR_SUCCESS;
            cred = APR_ARRAY_IDX(ad->creds, i, md_credentials_t*);
            if (!cred->pkey) {
                rv = md_pkey_load(d->store, MD_SG_STAGING, d->md->name, cred->spec, &cred->pkey, d->p);
            }
            if (APR_SUCCESS == rv && md_array_is_empty(cred->chain)) {
                rv = md_pubcert_load(d->store, MD_SG_STAGING, d->md->name, cred->spec, &chain, d->p);
                if (APR_SUCCESS == rv) {
                    apr_array_cat(cred->chain, chain);
                }
            }
            if (APR_SUCCESS == rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, d->p, "%s: credentials staged for %s certificate", 
                              d->md->name, md_pkey_spec_name(cred->spec));
            }
            else {
                complete = 0;
            }
        }
        return complete? APR_SUCCESS : APR_EAGAIN;
    }
    
    static apr_status_t acme_renew(md_proto_driver_t *d, md_result_t *result)
    {
        md_acme_driver_t *ad = d->baton;
        int reset_staging = d->reset;
        apr_status_t rv = APR_SUCCESS;
        apr_time_t now, t, t2;
        md_credentials_t *cred;
        const char *ca_effective = NULL;
        char ts[APR_RFC822_DATE_LEN];
        int i, first = 0;
    
        if (!d->md->ca_urls || d->md->ca_urls->nelts <= 0) {
            /* No CA defined? This is checked in several other places, but lets be sure */
            md_result_printf(result, APR_INCOMPLETE,
                "The managed domain %s is missing MDCertificateAuthority", d->md->name);
            goto out;
        }
    
        /* When not explicitly told to reset, we check the existing data. If
         * it is incomplete or old, we trigger the reset for a clean start. */
        if (!reset_staging) {
            md_result_activity_setn(result, "Checking staging area");
            rv = md_load(d->store, MD_SG_STAGING, d->md->name, &ad->md, d->p);
            if (APR_SUCCESS == rv) {
                /* So, we have a copy in staging, but is it a recent or an old one? */
                if (md_is_newer(d->store, MD_SG_DOMAINS, MD_SG_STAGING, d->md->name, d->p)) {
                    reset_staging = 1;
                }
            }
            else if (APR_STATUS_IS_ENOENT(rv)) {
                reset_staging = 1;
                rv = APR_SUCCESS;
            }
        }
    
        /* What CA are we using this time? */
        if (ad->md && ad->md->ca_effective) {
            /* There was one chosen on the previous run. Do we stick to it? */
            ca_effective = ad->md->ca_effective;
            if (d->md->ca_urls->nelts > 1 && d->attempt >= d->retry_failover) {
                /* We have more than one CA to choose from and this is the (at least)
                 * third attempt with the same CA. Let's switch to the next one. */
                int last_idx = md_array_str_index(d->md->ca_urls, ca_effective, 0, 1);
                if (last_idx >= 0) {
                    int next_idx = (last_idx+1) % d->md->ca_urls->nelts;
                    ca_effective = APR_ARRAY_IDX(d->md->ca_urls, next_idx, const char*);
                }
                else {
                    /* not part of current configuration? */
                    ca_effective = NULL;
                }
                /* switching CA means we need to wipe the staging area */
                reset_staging = 1;
            }
        }
    
        if (!ca_effective) {
            /* None chosen yet, pick the first one configured */
            ca_effective = APR_ARRAY_IDX(d->md->ca_urls, 0, const char*);
        }
    
        if (md_log_is_level(d->p, MD_LOG_DEBUG)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: staging started, "
                          "state=%d, attempt=%d, acme=%s, challenges='%s'",
                          d->md->name, d->md->state, d->attempt, ca_effective,
                          apr_array_pstrcat(d->p, ad->ca_challenges, ' '));
        }
    
        if (reset_staging) {
            md_result_activity_setn(result, "Resetting staging area");
            /* reset the staging area for this domain */
            rv = md_store_purge(d->store, d->p, MD_SG_STAGING, d->md->name);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, d->p, 
                          "%s: reset staging area", d->md->name);
            if (APR_SUCCESS != rv && !APR_STATUS_IS_ENOENT(rv)) {
                md_result_printf(result, rv, "resetting staging area");
                goto out;
            }
            rv = APR_SUCCESS;
            ad->md = NULL;
            ad->order = NULL;
        }
        
        md_result_activity_setn(result, "Assessing current status");
        if (ad->md && ad->md->state == MD_S_MISSING_INFORMATION) {
            /* ToS agreement is missing. It makes no sense to drive this MD further */
            md_result_printf(result, APR_INCOMPLETE, 
                "The managed domain %s is missing required information", d->md->name);
            goto out;
        }
        
        if (ad->md && APR_SUCCESS == load_missing_creds(d)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: all credentials staged", d->md->name);
            goto ready;
        }
        
        /* Need to renew */
        if (!ad->md || !md_array_str_eq(ad->md->ca_urls, d->md->ca_urls, 1)) {
            md_result_activity_printf(result, "Resetting staging for %s", d->md->name);
            /* re-initialize staging */
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: setup staging", d->md->name);
            md_store_purge(d->store, d->p, MD_SG_STAGING, d->md->name);
            ad->md = md_copy(d->p, d->md);
            ad->md->ca_effective = ca_effective;
            ad->md->ca_account = NULL;
            ad->order = NULL;
            rv = md_save(d->store, d->p, MD_SG_STAGING, ad->md, 0);
            if (APR_SUCCESS != rv) {
                md_result_printf(result, rv, "Saving MD information in staging area.");
                md_result_log(result, MD_LOG_ERR);
                goto out;
            }
        }
        if (!ad->domains) {
            ad->domains = md_dns_make_minimal(d->p, ad->md->domains);
        }
        ad->profile = ad->md->profile;
        ad->profile_mandatory = ad->md->profile_mandatory;
    
        md_result_activity_printf(result, "Contacting ACME server for %s at %s",
                                  d->md->name, ca_effective);
        if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, ca_effective,
                                                d->proxy_url, d->ca_file))) {
            md_result_printf(result, rv, "setup ACME communications");
            md_result_log(result, MD_LOG_ERR);
            goto out;
        }
        if (APR_SUCCESS != (rv = md_acme_setup(ad->acme, result))) {
            md_result_log(result, MD_LOG_ERR);
            goto out;
        }
    
        if (APR_SUCCESS != load_missing_creds(d)) {
            for (i = 0; i < ad->creds->nelts; ++i) {
                ad->cred = APR_ARRAY_IDX(ad->creds, i, md_credentials_t*);
                if (!ad->cred->pkey || md_array_is_empty(ad->cred->chain)) {
                    md_result_activity_printf(result, "Driving ACME to renew %s certificate for %s", 
                                              md_pkey_spec_name(ad->cred->spec),d->md->name);
                    /* The process of setting up challenges and verifying domain
                     * names differs between ACME versions. */
                    switch (MD_ACME_VERSION_MAJOR(ad->acme->version)) {
                        case 1:
                            md_result_printf(result, APR_EINVAL,
                                "ACME server speaks version 1, an obsolete version of the ACME "
                                "protocol that is no longer supported.");
                            rv = result->status;
                            break;
                        default:
                            /* In principle, we only know ACME version 2. But we assume
                            that a new protocol which announces a directory with all members
                            from version 2 will act backward compatible.
                            This is, of course, an assumption...
                            */
                            rv = md_acmev2_drive_renew(ad, d, result);
                            break;
                    }
                    if (APR_SUCCESS != rv) goto out;
                    
                    if (md_array_is_empty(ad->cred->chain) || ad->chain_up_link) {
                        md_result_activity_printf(result, "Retrieving %s certificate chain for %s", 
                                                  md_pkey_spec_name(ad->cred->spec), d->md->name);
                        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, 
                                      "%s: retrieving %s certificate chain", 
                                      d->md->name, md_pkey_spec_name(ad->cred->spec));
                        rv = ad_chain_retrieve(d);
                        if (APR_SUCCESS != rv) {
                            md_result_printf(result, rv, "Unable to retrieve %s certificate chain.", 
                                             md_pkey_spec_name(ad->cred->spec));
                            goto out;
                        }
                        
                        if (!md_array_is_empty(ad->cred->chain)) {
    
                            if (!ad->cred->pkey) {
                                rv = md_pkey_load(d->store, MD_SG_STAGING, d->md->name, ad->cred->spec, &ad->cred->pkey, d->p);
                                if (APR_SUCCESS != rv) {
                                    md_result_printf(result, rv, "Loading the private key.");
                                    goto out;
                                }
                            }
    
                            if (ad->cred->pkey) {
                                rv = md_check_cert_and_pkey(ad->cred->chain, ad->cred->pkey);
                                if (APR_SUCCESS != rv) {
                                    md_result_printf(result, rv, "Certificate and private key do not match.");
    
                                    /* Delete the order */
                                    md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
    
                                    goto out;
                                }
                            }
    
                            rv = md_pubcert_save(d->store, d->p, MD_SG_STAGING, d->md->name, 
                                                 ad->cred->spec, ad->cred->chain, 0);
                            if (APR_SUCCESS != rv) {
                                md_result_printf(result, rv, "Saving new %s certificate chain.", 
                                                 md_pkey_spec_name(ad->cred->spec));
                                goto out;
                            }
                        }
                    }
                    
                    /* Clean up the order, so the next pkey spec sets up a new one */
                    md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
                }
            }
        }
        
        
        /* As last step, cleanup any order we created so that challenge data
         * may be removed asap. */
        md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
        
        /* first time this job ran through */
        first = 1;    
    ready:
        md_result_activity_setn(result, NULL);
        /* we should have the complete cert chain now */
        assert(APR_SUCCESS == load_missing_creds(d));
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, d->p, 
                      "%s: certificates ready, activation delay set to %s", 
                      d->md->name, md_duration_format(d->p, d->activation_delay));
        
        /* determine when it should be activated */
        t = apr_time_now();
        for (i = 0; i < ad->creds->nelts; ++i) {
            cred = APR_ARRAY_IDX(ad->creds, i, md_credentials_t*);
            t2 = md_cert_get_not_before(APR_ARRAY_IDX(cred->chain, 0, md_cert_t*));
            if (t2 > t) t = t2;
        }
        md_result_delay_set(result, t);
    
        /* If the existing MD is complete and un-expired, delay the activation
         * to 24 hours after new cert is valid (if there is enough time left), so
         * that cients with skewed clocks do not see a problem. */
        now = apr_time_now();
        if (d->md->state == MD_S_COMPLETE) {
            apr_time_t valid_until, delay_activation;
            
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, d->p, 
                          "%s: state is COMPLETE, checking existing certificates", d->md->name);
            valid_until = md_reg_valid_until(d->reg, d->md, d->p);
            if (d->activation_delay < 0) {
                /* special simulation for test case */
                if (first) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, 
                                  "%s: delay ready_at to now+1s", d->md->name);
                    md_result_delay_set(result, apr_time_now() + apr_time_from_sec(1));
                }
            }
            else if (valid_until > now) {            
                delay_activation = d->activation_delay;
                if (delay_activation > (valid_until - now)) {
                    delay_activation = (valid_until - now);
                }
                md_result_delay_set(result, result->ready_at + delay_activation);
            }
        }
        
        /* There is a full set staged, to be loaded */
        apr_rfc822_date(ts, result->ready_at);
        if (result->ready_at > now) {
            md_result_printf(result, APR_SUCCESS, 
                "The certificate for the managed domain has been renewed successfully and can "
                "be used from %s on.", ts);
        }
        else {
            md_result_printf(result, APR_SUCCESS, 
                "The certificate for the managed domain has been renewed successfully and can "
                "be used (valid since %s). A graceful server restart now is recommended.", ts);
        }
    
    out:
        return rv;
    }
    
    static apr_status_t acme_driver_renew(md_proto_driver_t *d, md_result_t *result)
    {
        apr_status_t rv;
    
        rv = acme_renew(d, result);
        md_result_log(result, MD_LOG_DEBUG);
        return rv;
    }
    
    /**************************************************************************************************/
    /* ACME preload */
    
    static apr_status_t acme_preload(md_proto_driver_t *d, md_store_group_t load_group, 
                                     const char *name, md_result_t *result) 
    {
        apr_status_t rv;
        md_pkey_t *acct_key;
        md_t *md;
        md_pkey_spec_t *pkspec;
        md_credentials_t *creds;
        apr_array_header_t *all_creds;
        struct md_acme_acct_t *acct;
        const char *id;
        int i;
    
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: preload start", name);
        /* Load data from MD_SG_STAGING and save it into "load_group".
         * This serves several purposes:
         *  1. It's a format check on the input data. 
         *  2. We write back what we read, creating data with our own access permissions
         *  3. We ignore any other accumulated data in STAGING
         *  4. Once "load_group" is complete an ok, we can swap/archive groups with a rename
         *  5. Reading/Writing the data will apply/remove any group specific data encryption.
         */
        if (APR_SUCCESS != (rv = md_load(d->store, MD_SG_STAGING, name, &md, d->p))) {
            md_result_set(result, rv, "loading staged md.json");
            goto leave;
        }
        if (!md->ca_effective) {
            rv = APR_ENOENT;
            md_result_set(result, rv, "effective CA url not set");
            goto leave;
        }
    
        all_creds = apr_array_make(d->p, 5, sizeof(md_credentials_t*));
        for (i = 0; i < md_pkeys_spec_count(md->pks); ++i) {
            pkspec = md_pkeys_spec_get(md->pks, i);
            if (APR_SUCCESS != (rv = md_creds_load(d->store, MD_SG_STAGING, name, pkspec, &creds, d->p))) {
                md_result_printf(result, rv, "loading staged credentials #%d", i);
                goto leave;
            }
            if (!creds->chain) {
                rv = APR_ENOENT;
                md_result_printf(result, rv, "no certificate in staged credentials #%d", i);
                goto leave;
            }
            if (APR_SUCCESS != (rv = md_check_cert_and_pkey(creds->chain, creds->pkey))) {
                md_result_printf(result, rv, "certificate and private key do not match in staged credentials #%d", i);
                goto leave;
            }
            APR_ARRAY_PUSH(all_creds, md_credentials_t*) = creds;
        }
        
        /* See if staging holds a new or modified account data */
        rv = md_acme_acct_load(&acct, &acct_key, d->store, MD_SG_STAGING, name, d->p);
        if (APR_STATUS_IS_ENOENT(rv)) {
            acct = NULL;
            acct_key = NULL;
            rv = APR_SUCCESS;
        }
        else if (APR_SUCCESS != rv) {
            md_result_set(result, rv, "loading staged account");
            goto leave;
        }
    
        md_result_activity_setn(result, "purging order information");
        md_acme_order_purge(d->store, d->p, MD_SG_STAGING, md, d->env);
    
        md_result_activity_setn(result, "purging store tmp space");
        rv = md_store_purge(d->store, d->p, load_group, name);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, NULL);
            goto leave;
        }
        
        if (acct) {
            md_acme_t *acme;
    
            /* We may have STAGED the same account several times. This happens when
             * several MDs are renewed at once and need a new account. They will all store
             * the new account in their own STAGING area. By checking for accounts with
             * the same url, we save them all into a single one.
             */
            md_result_activity_setn(result, "saving staged account");
            id = md->ca_account;
            if (!id) {
                rv = md_acme_acct_id_for_md(&id, d->store, MD_SG_ACCOUNTS, md, d->p);
                if (APR_STATUS_IS_ENOENT(rv)) {
                    id = NULL;
                }
                else if (APR_SUCCESS != rv) {
                    md_result_set(result, rv, "error searching for existing account by url");
                    goto leave;
                }
            }
            
            if (APR_SUCCESS != (rv = md_acme_create(&acme, d->p, md->ca_effective,
                                                    d->proxy_url, d->ca_file))) {
                md_result_set(result, rv, "error setting up acme");
                goto leave;
            }
            
            if (APR_SUCCESS != (rv = md_acme_acct_save(d->store, d->p, acme, &id, acct, acct_key))) {
                md_result_set(result, rv, "error saving account");
                goto leave;
            }
            md->ca_account = id;
        }
        else if (!md->ca_account) {
            /* staging reused another account and did not create a new one. find
             * the account, if it is already there */
            rv = md_acme_acct_id_for_md(&id, d->store, MD_SG_ACCOUNTS, md, d->p);
            if (APR_SUCCESS == rv) {
                md->ca_account = id;
            }
        }
        
        md_result_activity_setn(result, "saving staged md/privkey/pubcert");
        if (APR_SUCCESS != (rv = md_save(d->store, d->p, load_group, md, 1))) {
            md_result_set(result, rv, "writing md.json");
            goto leave;
        }
    
        for (i = 0; i < all_creds->nelts; ++i) {
            creds = APR_ARRAY_IDX(all_creds, i, md_credentials_t*);
            if (APR_SUCCESS != (rv = md_creds_save(d->store, d->p, load_group, name, creds, 1))) {
                md_result_printf(result, rv, "writing credentials #%d", i);
                goto leave;
            }
        }
        
        md_result_set(result, APR_SUCCESS, "saved staged data successfully");
        
    leave:
        md_result_log(result, MD_LOG_DEBUG);
        return rv;
    }
    
    static apr_status_t acme_driver_preload(md_proto_driver_t *d, 
                                            md_store_group_t group, md_result_t *result)
    {
        apr_status_t rv;
    
        rv = acme_preload(d, group, d->md->name, result);
        md_result_log(result, MD_LOG_DEBUG);
        return rv;
    }
    
    static apr_status_t acme_complete_md(md_t *md, apr_pool_t *p)
    {
        (void)p;
        if (!md->ca_urls || apr_is_empty_array(md->ca_urls)) {
            md->ca_urls = apr_array_make(p, 3, sizeof(const char *));
            APR_ARRAY_PUSH(md->ca_urls, const char*) = MD_ACME_DEF_URL;
        }
        return APR_SUCCESS;
    }
    
    static md_proto_t ACME_PROTO = {
        MD_PROTO_ACME, acme_driver_init, acme_driver_renew, 
        acme_driver_preload_init, acme_driver_preload,
        acme_complete_md,
    };
     
    apr_status_t md_acme_protos_add(apr_hash_t *protos, apr_pool_t *p)
    {
        (void)p;
        apr_hash_set(protos, MD_PROTO_ACME, sizeof(MD_PROTO_ACME)-1, &ACME_PROTO);
        return APR_SUCCESS;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acmev2_drive.c�����������������������������������������������������������0000664�0001751�0001751�00000016774�14750656217�020120� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_buckets.h>
    #include <apr_hash.h>
    #include <apr_uri.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_jws.h"
    #include "md_http.h"
    #include "md_log.h"
    #include "md_result.h"
    #include "md_reg.h"
    #include "md_store.h"
    #include "md_util.h"
    
    #include "md_acme.h"
    #include "md_acme_acct.h"
    #include "md_acme_authz.h"
    #include "md_acme_order.h"
    
    #include "md_acme_drive.h"
    #include "md_acmev2_drive.h"
    
    
    
    /**************************************************************************************************/
    /* order setup */
    
    /**
     * Either we have an order stored in the STAGING area, or we need to create a 
     * new one at the ACME server.
     */
    static apr_status_t ad_setup_order(md_proto_driver_t *d, md_result_t *result, int *pis_new)
    {
        md_acme_driver_t *ad = d->baton;
        apr_status_t rv;
        md_t *md = ad->md;
        const char *profile = NULL;
        
        assert(ad->md);
        assert(ad->acme);
    
        /* For each domain in MD: AUTHZ setup
         * if an AUTHZ resource is known, check if it is still valid
         * if known AUTHZ resource is not valid, remove, goto 4.1.1
         * if no AUTHZ available, create a new one for the domain, store it
         */
        if (pis_new) *pis_new = 0;
        rv = md_acme_order_load(d->store, MD_SG_STAGING, md->name, &ad->order, d->p);
        if (APR_SUCCESS == rv) {
            md_result_activity_setn(result, "Loaded order from staging");
            goto leave;
        }
        else if (!APR_STATUS_IS_ENOENT(rv)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%s: loading order", md->name);
            md_acme_order_purge(d->store, d->p, MD_SG_STAGING, md, d->env);
        }
        
        md_result_activity_setn(result, "Creating new order");
        if (ad->profile) {
            if(ad->acme->api.v2.profiles) {
                int i;
                for (i = 0; !profile && i < ad->acme->api.v2.profiles->nelts; ++i) {
                    const char *s = APR_ARRAY_IDX(ad->acme->api.v2.profiles, i, const char*);
                    if (!apr_strnatcasecmp(s, ad->profile))
                       profile = s;
                }
            }
            if (profile)
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p,
                              "%s: ordering ACME profile '%s'", md->name, profile);
            else if (ad->profile_mandatory) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p,
                              "%s: mandatory ACME profile '%s' is not offered by CA",
                              md->name, ad->profile);
                rv = APR_EINVAL;
                goto leave;
            }
            else {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p,
                              "%s: ACME profile '%s' is not offered by CA, continuing without",
                              md->name, ad->profile);
            }
        }
    
        rv = md_acme_order_register(&ad->order, ad->acme, d->p, d->md->name, ad->domains, profile);
        if (APR_SUCCESS !=rv) goto leave;
        rv = md_acme_order_save(d->store, d->p, MD_SG_STAGING, d->md->name, ad->order, 0);
        if (APR_SUCCESS != rv) {
            md_result_set(result, rv, "saving order in staging");
        }
        if (pis_new) *pis_new = 1;
    
    leave:
        md_acme_report_result(ad->acme, rv, result);
        return rv;
    }
    
    /**************************************************************************************************/
    /* ACMEv2 renewal */
    
    apr_status_t md_acmev2_drive_renew(md_acme_driver_t *ad, md_proto_driver_t *d, md_result_t *result)
    {
        apr_status_t rv = APR_SUCCESS;
        int is_new_order = 0;
    
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: (ACMEv2) need certificate", d->md->name);
        
        /* Chose (or create) and ACME account to use */
        rv = md_acme_drive_set_acct(d, result);
        if (APR_SUCCESS != rv) goto leave;
    
        if (!md_array_is_empty(ad->cred->chain)) goto leave;
            
        /* ACMEv2 strategy:
         * 1. load an md_acme_order_t from STAGING, if present
         * 2. if no order found, register a new order at ACME server
         * 3. update the order from the server
         * 4. Switch order state:
         *   * PENDING: process authz challenges
         *   * READY: finalize the order
         *   * PROCESSING: wait and re-assses later
         *   * VALID: retrieve certificate
         *   * COMPLETE: all done, return success
         *   * INVALID and otherwise: fail renewal, delete local order
         */
        if (APR_SUCCESS != (rv = ad_setup_order(d, result, &is_new_order))) {
            goto leave;
        }
        
        rv = md_acme_order_update(ad->order, ad->acme, result, d->p);
        if (APR_STATUS_IS_ENOENT(rv)
            || APR_STATUS_IS_EACCES(rv)
            || MD_ACME_ORDER_ST_INVALID == ad->order->status) {
            /* order is invalid or no longer known at the ACME server */
            ad->order = NULL;
            md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
        }
        else if (APR_SUCCESS != rv) {
            goto leave;
        }
    
    retry:
        if (!ad->order) {
            rv = ad_setup_order(d, result, &is_new_order);
            if (APR_SUCCESS != rv) goto leave;
        }
        
        rv = md_acme_order_start_challenges(ad->order, ad->acme, ad->ca_challenges,
                                            d->store, d->md, d->env, result, d->p);
        if (!is_new_order && APR_STATUS_IS_EINVAL(rv)) {
            /* found 'invalid' domains in previous order, need to start over */
            ad->order = NULL;
            md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md, d->env);
            goto retry;
        }
        if (APR_SUCCESS != rv) goto leave;
        
        rv = md_acme_order_monitor_authzs(ad->order, ad->acme, d->md,
                                          ad->authz_monitor_timeout, result, d->p);
        if (APR_SUCCESS != rv) {
          md_result_set(result, rv, "Error waiting on domain names to be validated");
          goto leave;
        }
    
        rv = md_acme_order_await_ready(ad->order, ad->acme, d->md,
                                       ad->authz_monitor_timeout, result, d->p);
        if (APR_SUCCESS != rv) {
          md_result_set(result, rv, "Error waiting for order to become ready");
          goto leave;
        }
    
        if (MD_ACME_ORDER_ST_READY == ad->order->status) {
            rv = md_acme_drive_setup_cred_chain(d, result);
            if (APR_SUCCESS != rv) goto leave;
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, d->p, "%s: finalized order", d->md->name);
        }
    
        rv = md_acme_order_await_valid(ad->order, ad->acme, d->md, 
                                       ad->authz_monitor_timeout, result, d->p);
        if (APR_SUCCESS != rv) {
          md_result_set(result, rv, "Error waiting for order to become valid.");
          goto leave;
        }
        
        if (!ad->order->certificate) {
            md_result_set(result, APR_EINVAL, "Order valid, but certificate url is missing.");
            goto leave;
        }
        md_result_set(result, APR_SUCCESS, NULL);
    
    leave:    
        md_result_log(result, MD_LOG_DEBUG);
        return result->status;
    }
    
    ����httpd-2.4.64/modules/md/md_status.c�����������������������������������������������������������������0000664�0001751�0001751�00000053670�14750656217�017071� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_tables.h>
    #include <apr_time.h>
    #include <apr_date.h>
    
    #include "md_json.h"
    #include "md.h"
    #include "md_acme.h"
    #include "md_crypt.h"
    #include "md_event.h"
    #include "md_log.h"
    #include "md_ocsp.h"
    #include "md_store.h"
    #include "md_result.h"
    #include "md_reg.h"
    #include "md_util.h"
    #include "md_status.h"
    
    #define MD_STATUS_WITH_SCTS     0
    
    /**************************************************************************************************/
    /* certificate status information */
    
    static apr_status_t status_get_cert_json(md_json_t **pjson, const md_cert_t *cert, apr_pool_t *p)
    {
        const char *finger;
        apr_status_t rv = APR_SUCCESS;
        md_timeperiod_t valid;
        md_json_t *json;
        const char *issuer_uri, *issuer_name;
    
    
        json = md_json_create(p);
        issuer_name = md_cert_get_issuer_name(cert, p);
        if (issuer_name)
          md_json_sets(issuer_name, json, MD_KEY_ISSUER_NAME, NULL);
        rv = md_cert_get_issuers_uri(&issuer_uri, cert, p);
        if(rv == APR_SUCCESS && issuer_uri)
          md_json_sets(issuer_uri, json, MD_KEY_ISSUER_URI, NULL);
        valid.start = md_cert_get_not_before(cert);
        valid.end = md_cert_get_not_after(cert);
        md_json_set_timeperiod(&valid, json, MD_KEY_VALID, NULL);
        md_json_sets(md_cert_get_serial_number(cert, p), json, MD_KEY_SERIAL, NULL);
        md_json_sets(md_cert_get_serial_number(cert, p), json, MD_KEY_SERIAL, NULL);
        if (APR_SUCCESS != (rv = md_cert_to_sha256_fingerprint(&finger, cert, p))) goto leave;
        md_json_sets(finger, json, MD_KEY_SHA256_FINGERPRINT, NULL);
    
    #if MD_STATUS_WITH_SCTS
        do {
            apr_array_header_t *scts;
            const char *hex;
            const md_sct *sct;
            md_json_t *sctj;
            int i;
            
            scts = apr_array_make(p, 5, sizeof(const md_sct*));
            if (APR_SUCCESS == md_cert_get_ct_scts(scts, p, cert)) {
                for (i = 0; i < scts->nelts; ++i) {
                    sct = APR_ARRAY_IDX(scts, i, const md_sct*);
                    sctj = md_json_create(p);
                    
                    apr_rfc822_date(ts, sct->timestamp);
                    md_json_sets(ts, sctj, "signed", NULL);
                    md_json_setl(sct->version, sctj, MD_KEY_VERSION, NULL);
                    md_data_to_hex(&hex, 0, p, sct->logid);
                    md_json_sets(hex, sctj, "logid", NULL);
                    md_data_to_hex(&hex, 0, p, sct->signature);
                    md_json_sets(hex, sctj, "signature", NULL);
                    md_json_sets(md_nid_get_sname(sct->signature_type_nid), sctj, "signature-type", NULL);
                    md_json_addj(sctj, json, "scts", NULL);
                }
            }
        while (0);
    #endif
    leave:
        *pjson = (APR_SUCCESS == rv)? json : NULL;
        return rv;
    }
    
    static apr_status_t job_loadj(md_json_t **pjson, md_store_group_t group, const char *name,
                                  struct md_reg_t *reg, int with_log, apr_pool_t *p)
    {
        apr_status_t rv;
    
        md_store_t *store = md_reg_store_get(reg);
        rv = md_store_load_json(store, group, name, MD_FN_JOB, pjson, p);
        if (APR_SUCCESS == rv && !with_log) md_json_del(*pjson, MD_KEY_LOG, NULL);
        return rv;
    }
    
    static apr_status_t status_get_cert_json_ex(
        md_json_t **pjson,
        const md_cert_t *cert,
        const md_t *md,
        md_reg_t *reg,
        md_ocsp_reg_t *ocsp,
        int with_logs,
        apr_pool_t *p)
    {
        md_json_t *certj, *jobj;
        md_timeperiod_t ocsp_valid;
        md_ocsp_cert_stat_t cert_stat;
        apr_status_t rv;
    
        if (APR_SUCCESS != (rv = status_get_cert_json(&certj, cert, p))) goto leave;
        if (md->stapling && ocsp) {
            rv = md_ocsp_get_meta(&cert_stat, &ocsp_valid, ocsp, cert, p, md);
            if (APR_SUCCESS == rv) {
                md_json_sets(md_ocsp_cert_stat_name(cert_stat), certj, MD_KEY_OCSP, MD_KEY_STATUS, NULL);
                md_json_set_timeperiod(&ocsp_valid, certj, MD_KEY_OCSP, MD_KEY_VALID, NULL);
            }
            else if (!APR_STATUS_IS_ENOENT(rv)) goto leave;
            rv = APR_SUCCESS;
            if (APR_SUCCESS == job_loadj(&jobj, MD_SG_OCSP, md->name, reg, with_logs, p)) {
                md_json_setj(jobj, certj, MD_KEY_OCSP, MD_KEY_RENEWAL, NULL);
            }
        }
    leave:
        *pjson = (APR_SUCCESS == rv)? certj : NULL;
        return rv;
    }
    
    static int get_cert_count(const md_t *md, int from_staging)
    {
        if (!from_staging && md->cert_files && md->cert_files->nelts) {
            return md->cert_files->nelts;
        }
        return md_pkeys_spec_count(md->pks);
    }
    
    static const char *get_cert_name(const md_t *md, int i, int from_staging, apr_pool_t *p)
    {
        if (!from_staging && md->cert_files && md->cert_files->nelts) {
            /* static files configured, not from staging, used index names */
            return apr_psprintf(p, "%d", i);
        }
        return md_pkey_spec_name(md_pkeys_spec_get(md->pks, i));
    }
    
    static apr_status_t status_get_certs_json(md_json_t **pjson, apr_array_header_t *certs,
                                              int from_staging,
                                              const md_t *md, md_reg_t *reg,  
                                              md_ocsp_reg_t *ocsp, int with_logs,
                                              apr_pool_t *p)
    {
        md_json_t *json, *certj;
        md_timeperiod_t certs_valid = {0, 0}, valid;
        md_cert_t *cert;
        int i;
        apr_status_t rv = APR_SUCCESS;   
        
        json = md_json_create(p);
        for (i = 0; i < get_cert_count(md, from_staging); ++i) {
            cert = APR_ARRAY_IDX(certs, i, md_cert_t*);
            if (!cert) continue;
    
            rv = status_get_cert_json_ex(&certj, cert, md, reg, ocsp, with_logs, p);
            if (APR_SUCCESS != rv) goto leave;
            valid = md_cert_get_valid(cert);
            certs_valid = i? md_timeperiod_common(&certs_valid, &valid) : valid;
            md_json_setj(certj, json, get_cert_name(md, i, from_staging, p), NULL);
        }
        
        if (certs_valid.start) {
            md_json_set_timeperiod(&certs_valid, json, MD_KEY_VALID, NULL);
        }
    leave:
        *pjson = (APR_SUCCESS == rv)? json : NULL;
        return rv;
    }
    
    static apr_status_t get_staging_certs_json(md_json_t **pjson, const md_t *md, 
                                               md_reg_t *reg, apr_pool_t *p)
    { 
        md_pkey_spec_t *spec;
        int i;
        apr_array_header_t *chain, *certs;
        const md_cert_t *cert;
        apr_status_t rv;
        
        certs = apr_array_make(p, 5, sizeof(md_cert_t*));
        for (i = 0; i < get_cert_count(md, 1); ++i) {
            spec = md_pkeys_spec_get(md->pks, i);
            cert = NULL;
            rv = md_pubcert_load(md_reg_store_get(reg), MD_SG_STAGING, md->name, spec, &chain, p);
            if (APR_SUCCESS == rv) {
                cert = APR_ARRAY_IDX(chain, 0, const md_cert_t*);
            }
            APR_ARRAY_PUSH(certs, const md_cert_t*) = cert;
        }
        return status_get_certs_json(pjson, certs, 1, md, reg, NULL, 0, p);
    }
    
    static apr_status_t status_get_md_json(md_json_t **pjson, const md_t *md, 
                                           md_reg_t *reg, md_ocsp_reg_t *ocsp, 
                                           int with_logs, apr_pool_t *p)
    {
        md_json_t *mdj, *certsj, *jobj;
        int renew;
        const md_pubcert_t *pubcert;
        const md_cert_t *cert = NULL;
        apr_array_header_t *certs;
        apr_status_t rv = APR_SUCCESS;
        apr_time_t renew_at;
        int i;
    
        mdj = md_to_public_json(md, p);
        certs = apr_array_make(p, 5, sizeof(md_cert_t*));
        for (i = 0; i < get_cert_count(md, 0); ++i) {
            cert = NULL;
            if (APR_SUCCESS == md_reg_get_pubcert(&pubcert, reg, md, i, p)) {
                cert = APR_ARRAY_IDX(pubcert->certs, 0, const md_cert_t*);
            }
            APR_ARRAY_PUSH(certs, const md_cert_t*) = cert;
        }
        
        rv = status_get_certs_json(&certsj, certs, 0, md, reg, ocsp, with_logs, p);
        if (APR_SUCCESS != rv) goto leave;
        md_json_setj(certsj, mdj, MD_KEY_CERT, NULL);
        
        renew_at = md_reg_renew_at(reg, md, p);
        if (renew_at > 0) {
            md_json_set_time(renew_at, mdj, MD_KEY_RENEW_AT, NULL);
        }
        
        md_json_setb(md->stapling, mdj, MD_KEY_STAPLING, NULL);
        md_json_setb(md->watched, mdj, MD_KEY_WATCHED, NULL);
        renew = md_reg_should_renew(reg, md, p);
        if (renew) {
            md_json_setb(renew, mdj, MD_KEY_RENEW, NULL);
            rv = job_loadj(&jobj, MD_SG_STAGING, md->name, reg, with_logs, p);
            if (APR_SUCCESS == rv) {
                if (APR_SUCCESS == get_staging_certs_json(&certsj, md, reg, p)) {
                    md_json_setj(certsj, jobj, MD_KEY_CERT, NULL);
                }
                md_json_setj(jobj, mdj, MD_KEY_RENEWAL, NULL);
            }
            else if (APR_STATUS_IS_ENOENT(rv)) rv = APR_SUCCESS;
            else goto leave;
        }
        
    leave:
        if (APR_SUCCESS != rv) {
            md_json_setl(rv, mdj, MD_KEY_ERROR, NULL);
        }
        *pjson = mdj;
        return rv;
    }
    
    apr_status_t md_status_get_md_json(md_json_t **pjson, const md_t *md, 
                                       md_reg_t *reg, md_ocsp_reg_t *ocsp, apr_pool_t *p)
    {
        return status_get_md_json(pjson, md, reg, ocsp, 1, p);
    }
    
    apr_status_t md_status_get_json(md_json_t **pjson, apr_array_header_t *mds, 
                                    md_reg_t *reg, md_ocsp_reg_t *ocsp, apr_pool_t *p) 
    {
        md_json_t *json, *mdj;
        const md_t *md;
        int i;
        
        json = md_json_create(p);
        md_json_sets(MOD_MD_VERSION, json, MD_KEY_VERSION, NULL);
        for (i = 0; i < mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mds, i, const md_t *);
            status_get_md_json(&mdj, md, reg, ocsp, 0, p);
            md_json_addj(mdj, json, MD_KEY_MDS, NULL);
        }
        *pjson = json;
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* drive job persistence */
    
    md_job_t *md_job_make(apr_pool_t *p, md_store_t *store,
                          md_store_group_t group, const char *name,
                          apr_time_t min_delay)
    {
        md_job_t *job = apr_pcalloc(p, sizeof(*job));
        job->group = group;
        job->mdomain = apr_pstrdup(p, name);
        job->store = store;
        job->p = p;
        job->max_log = 128;
        job->min_delay = min_delay;
        return job;
    }
    
    void md_job_set_group(md_job_t *job, md_store_group_t group)
    {
        job->group = group;
    }
    
    static void md_job_from_json(md_job_t *job, md_json_t *json, apr_pool_t *p)
    {
        const char *s;
        
        /* not good, this is malloced from a temp pool */
        /*job->mdomain = md_json_gets(json, MD_KEY_NAME, NULL);*/
        job->finished = md_json_getb(json, MD_KEY_FINISHED, NULL);
        job->notified = md_json_getb(json, MD_KEY_NOTIFIED, NULL);
        job->notified_renewed = md_json_getb(json, MD_KEY_NOTIFIED_RENEWED, NULL);
        s = md_json_dups(p, json, MD_KEY_NEXT_RUN, NULL);
        if (s && *s) job->next_run = apr_date_parse_rfc(s);
        s = md_json_dups(p, json, MD_KEY_LAST_RUN, NULL);
        if (s && *s) job->last_run = apr_date_parse_rfc(s);
        s = md_json_dups(p, json, MD_KEY_VALID_FROM, NULL);
        if (s && *s) job->valid_from = apr_date_parse_rfc(s);
        job->error_runs = (int)md_json_getl(json, MD_KEY_ERRORS, NULL);
        if (md_json_has_key(json, MD_KEY_LAST, NULL)) {
            job->last_result = md_result_from_json(md_json_getcj(json, MD_KEY_LAST, NULL), p);
        }
        job->log = md_json_getj(json, MD_KEY_LOG, NULL);
    }
    
    static void job_to_json(md_json_t *json, const md_job_t *job, 
                            md_result_t *result, apr_pool_t *p)
    {
        char ts[APR_RFC822_DATE_LEN];
    
        md_json_sets(job->mdomain, json, MD_KEY_NAME, NULL);
        md_json_setb(job->finished, json, MD_KEY_FINISHED, NULL);
        md_json_setb(job->notified, json, MD_KEY_NOTIFIED, NULL);
        md_json_setb(job->notified_renewed, json, MD_KEY_NOTIFIED_RENEWED, NULL);
        if (job->next_run > 0) {
            apr_rfc822_date(ts, job->next_run);
            md_json_sets(ts, json, MD_KEY_NEXT_RUN, NULL);
        }
        if (job->last_run > 0) {
            apr_rfc822_date(ts, job->last_run);
            md_json_sets(ts, json, MD_KEY_LAST_RUN, NULL);
        }
        if (job->valid_from > 0) {
            apr_rfc822_date(ts, job->valid_from);
            md_json_sets(ts, json, MD_KEY_VALID_FROM, NULL);
        }
        md_json_setl(job->error_runs, json, MD_KEY_ERRORS, NULL);
        if (!result) result = job->last_result;
        if (result) {
            md_json_setj(md_result_to_json(result, p), json, MD_KEY_LAST, NULL);
        }
        if (job->log) md_json_setj(job->log, json, MD_KEY_LOG, NULL);
    }
    
    apr_status_t md_job_load(md_job_t *job)
    {
        md_json_t *jprops;
        apr_status_t rv;
        
        rv = md_store_load_json(job->store, job->group, job->mdomain, MD_FN_JOB, &jprops, job->p);
        if (APR_SUCCESS == rv) {
            md_job_from_json(job, jprops, job->p);
        }
        return rv;
    }
    
    apr_status_t md_job_save(md_job_t *job, md_result_t *result, apr_pool_t *p)
    {
        md_json_t *jprops;
        apr_status_t rv;
        
        jprops = md_json_create(p);
        job_to_json(jprops, job, result, p);
        rv = md_store_save_json(job->store, p, job->group, job->mdomain, MD_FN_JOB, jprops, 0);
        if (APR_SUCCESS == rv) job->dirty = 0;
        return rv;
    }
    
    void md_job_log_append(md_job_t *job, const char *type, 
                           const char *status, const char *detail)
    {
        md_json_t *entry;
        char ts[APR_RFC822_DATE_LEN];
        
        entry = md_json_create(job->p);
        apr_rfc822_date(ts, apr_time_now());
        md_json_sets(ts, entry, MD_KEY_WHEN, NULL);
        md_json_sets(type, entry, MD_KEY_TYPE, NULL);
        if (status) md_json_sets(status, entry, MD_KEY_STATUS, NULL);
        if (detail) md_json_sets(detail, entry, MD_KEY_DETAIL, NULL);
        if (!job->log) job->log = md_json_create(job->p);
        md_json_insertj(entry, 0, job->log, MD_KEY_ENTRIES, NULL);
        md_json_limita(job->max_log, job->log, MD_KEY_ENTRIES, NULL);
        job->dirty = 1;
    }
    
    typedef struct {
        md_job_t *job;
        const char *type;
        md_json_t *entry;
        size_t index;
    } log_find_ctx;
    
    static int find_first_log_entry(void *baton, size_t index, md_json_t *entry)
    {
        log_find_ctx *ctx = baton;
        const char *etype;
        
        etype = md_json_gets(entry, MD_KEY_TYPE, NULL);
        if (etype == ctx->type || (etype && ctx->type && !strcmp(etype, ctx->type))) {
            ctx->entry = entry;
            ctx->index = index;
            return 0;
        }
        return 1;
    }
    
    md_json_t *md_job_log_get_latest(md_job_t *job, const char *type)
    
    {
        log_find_ctx ctx;
    
        memset(&ctx, 0, sizeof(ctx));
        ctx.job = job;
        ctx.type = type;
        if (job->log) md_json_itera(find_first_log_entry, &ctx, job->log, MD_KEY_ENTRIES, NULL);
        return ctx.entry;
    }
    
    apr_time_t md_job_log_get_time_of_latest(md_job_t *job, const char *type)
    {
        md_json_t *entry;
        const char *s;
        
        entry = md_job_log_get_latest(job, type);
        if (entry) {
            s = md_json_gets(entry, MD_KEY_WHEN, NULL);
            if (s) return apr_date_parse_rfc(s);
        }
        return 0;
    }
    
    void  md_status_take_stock(md_json_t **pjson, apr_array_header_t *mds, 
                               md_reg_t *reg, apr_pool_t *p)
    {
        const md_t *md;
        md_job_t *job;
        int i, complete, renewing, errored, ready, total;
        md_json_t *json;
    
        json = md_json_create(p);
        complete = renewing = errored = ready = total = 0;
        for (i = 0; i < mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mds, i, const md_t *);
            ++total;
            switch (md->state) {
                case MD_S_COMPLETE: ++complete; /* fall through */
                case MD_S_INCOMPLETE:
                    if (md_reg_should_renew(reg, md, p)) {
                        ++renewing;
                        job = md_reg_job_make(reg, md->name, p);
                        if (APR_SUCCESS == md_job_load(job)) {
                            if (job->error_runs > 0 
                                || (job->last_result && job->last_result->status != APR_SUCCESS)) {
                                ++errored;
                            }
                            else if (job->finished) {
                                ++ready;
                            }
                        }
                    }
                    break;
                default: ++errored; break;
            }
        }
        md_json_setl(total, json, MD_KEY_TOTAL, NULL);
        md_json_setl(complete, json, MD_KEY_COMPLETE, NULL);
        md_json_setl(renewing, json, MD_KEY_RENEWING, NULL);
        md_json_setl(errored, json, MD_KEY_ERRORED, NULL);
        md_json_setl(ready, json, MD_KEY_READY, NULL);
        *pjson = json;
    }
    
    typedef struct {
        apr_pool_t *p;
        md_job_t *job;
        md_store_t *store;
        md_result_t *last;
        apr_time_t last_save;
    } md_job_result_ctx;
    
    static void job_result_update(md_result_t *result, void *data)
    {
        md_job_result_ctx *ctx = data;
        apr_time_t now;
        const char *msg, *sep;
        
        if (md_result_cmp(ctx->last, result)) {
            now = apr_time_now();
            md_result_assign(ctx->last, result);
            if (result->activity || result->problem || result->detail) {
                msg = sep = "";
                if (result->activity) {
                    msg = apr_psprintf(result->p, "%s", result->activity);
                    sep = ": ";
                }
                if (result->detail) {
                    msg = apr_psprintf(result->p, "%s%s%s", msg, sep, result->detail);
                    sep = ", ";
                }
                if (result->problem) {
                    msg = apr_psprintf(result->p, "%s%sproblem: %s", msg, sep, result->problem);
                    sep = " ";
                }
                md_job_log_append(ctx->job, "progress", NULL, msg);
    
                if (ctx->store && apr_time_as_msec(now - ctx->last_save) > 500) {
                    md_job_save(ctx->job, result, ctx->p);
                    ctx->last_save = now;
                }
            }
        }
    }
    
    static apr_status_t job_result_raise(md_result_t *result, void *data, const char *event, apr_pool_t *p)
    {
        md_job_result_ctx *ctx = data;
        (void)p;
        if (result == ctx->job->observing) {
            return md_job_notify(ctx->job, event, result);
        }
        return APR_SUCCESS;
    }
    
    static void job_result_holler(md_result_t *result, void *data, const char *event, apr_pool_t *p)
    {
        md_job_result_ctx *ctx = data;
        if (result == ctx->job->observing) {
            md_event_holler(event, ctx->job->mdomain, ctx->job, result, p);
        }
    }
    
    static void job_observation_start(md_job_t *job, md_result_t *result, md_store_t *store)
    {
        md_job_result_ctx *ctx;
    
        if (job->observing) md_result_on_change(job->observing, NULL, NULL);
        job->observing = result;
        
        ctx = apr_pcalloc(result->p, sizeof(*ctx));
        ctx->p = result->p;
        ctx->job = job;
        ctx->store = store;
        ctx->last = md_result_md_make(result->p, APR_SUCCESS);
        md_result_assign(ctx->last, result);
        md_result_on_change(result, job_result_update, ctx);
        md_result_on_raise(result, job_result_raise, ctx);
        md_result_on_holler(result, job_result_holler, ctx);
    }
    
    static void job_observation_end(md_job_t *job)
    {
        if (job->observing) md_result_on_change(job->observing, NULL, NULL);
        job->observing = NULL; 
    } 
    
    void md_job_start_run(md_job_t *job, md_result_t *result, md_store_t *store)
    {
        job->fatal_error = 0;
        job->last_run = apr_time_now();
        job_observation_start(job, result, store);
        md_job_log_append(job, "starting", NULL, NULL);
    }
    
    apr_time_t md_job_delay_on_errors(md_job_t *job, int err_count, const char *last_problem)
    {
        apr_time_t delay = 0, max_delay = apr_time_from_sec(24*60*60); /* daily */
        unsigned char c;
    
        if (last_problem && md_acme_problem_is_input_related(last_problem)) {
            /* If ACME server reported a problem and that problem indicates that our
             * input values, e.g. our configuration, has something wrong, we always
             * go to max delay as frequent retries are unlikely to resolve the situation.
             * However, we should nevertheless retry daily, bc. it might be that there
             * is a bug in the server. Unlikely, but... */
            delay = max_delay;
        }
        else if (err_count > 0) {
            /* back off duration, depending on the errors we encounter in a row */
            delay = job->min_delay << (err_count - 1);
            if (delay > max_delay) {
                delay = max_delay;
            }
        }
        if (delay > 0) {
            /* jitter the delay by +/- 0-50%.
             * Background: we see retries of jobs being too regular (e.g. all at midnight),
             * possibly cumulating from many installations that restart their Apache at a
             * fixed hour. This can contribute to an overload at the CA and a continuation
             * of failure.
             */
            md_rand_bytes(&c, sizeof(c), job->p);
            delay += apr_time_from_sec((apr_time_sec(delay) * (c - 128)) / 256);
        }
        return delay;
    }
    
    void md_job_end_run(md_job_t *job, md_result_t *result)
    {
        if (APR_SUCCESS == result->status) {
            job->finished = 1;
            job->valid_from = result->ready_at;
            job->error_runs = 0;
            job->dirty = 1;
            md_job_log_append(job, "finished", NULL, NULL);
        }
        else {
            ++job->error_runs;
            job->dirty = 1;
            job->next_run = apr_time_now() + md_job_delay_on_errors(job, job->error_runs, result->problem);
        }
        job_observation_end(job);
    }
    
    void md_job_retry_at(md_job_t *job, apr_time_t later)
    {
        job->next_run = later;
        job->dirty = 1;
    }
    
    apr_status_t md_job_notify(md_job_t *job, const char *reason, md_result_t *result)
    {
        apr_status_t rv;
        
        md_result_set(result, APR_SUCCESS, NULL);
        rv = md_event_raise(reason, job->mdomain, job, result, job->p);
        job->dirty = 1;
        if (APR_SUCCESS == rv && APR_SUCCESS == result->status) {
            job->notified = 1;
            if (!strcmp("renewed", reason)) {
                job->notified_renewed = 1;
            }
        }
        else {
            ++job->error_runs;
            job->next_run = apr_time_now() + md_job_delay_on_errors(job, job->error_runs, result->problem);
        }
        return result->status;
    }
    
    ������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_drive.c��������������������������������������������������������������0000664�0001751�0001751�00000033305�14630343666�017505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_optional.h>
    #include <apr_hash.h>
    #include <apr_strings.h>
    #include <apr_date.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    
    #include "mod_watchdog.h"
    
    #include "md.h"
    #include "md_curl.h"
    #include "md_crypt.h"
    #include "md_event.h"
    #include "md_http.h"
    #include "md_json.h"
    #include "md_status.h"
    #include "md_store.h"
    #include "md_store_fs.h"
    #include "md_log.h"
    #include "md_result.h"
    #include "md_reg.h"
    #include "md_util.h"
    #include "md_version.h"
    #include "md_acme.h"
    #include "md_acme_authz.h"
    
    #include "mod_md.h"
    #include "mod_md_private.h"
    #include "mod_md_config.h"
    #include "mod_md_status.h"
    #include "mod_md_drive.h"
    
    /**************************************************************************************************/
    /* watchdog based impl. */
    
    #define MD_RENEW_WATCHDOG_NAME   "_md_renew_"
    
    static APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *wd_get_instance;
    static APR_OPTIONAL_FN_TYPE(ap_watchdog_register_callback) *wd_register_callback;
    static APR_OPTIONAL_FN_TYPE(ap_watchdog_set_callback_interval) *wd_set_interval;
    
    struct md_renew_ctx_t {
        apr_pool_t *p;
        server_rec *s;
        md_mod_conf_t *mc;
        ap_watchdog_t *watchdog;
        
        apr_array_header_t *jobs;
    };
    
    static void process_drive_job(md_renew_ctx_t *dctx, md_job_t *job, apr_pool_t *ptemp)
    {
        const md_t *md;
        md_result_t *result = NULL;
        apr_status_t rv;
        
        md_job_load(job);
        /* Evaluate again on loaded value. Values will change when watchdog switches child process */
        if (apr_time_now() < job->next_run) return;
        
        job->next_run = 0;
        if (job->finished && job->notified_renewed) {
            /* finished and notification handled, nothing to do. */
            goto leave;
        }
        
        md = md_get_by_name(dctx->mc->mds, job->mdomain);
        AP_DEBUG_ASSERT(md);
    
        result = md_result_md_make(ptemp, md->name);
        if (job->last_result) md_result_assign(result, job->last_result);
        
        if (md->state == MD_S_MISSING_INFORMATION) {
            /* Missing information, this will not change until configuration
             * is changed and server reloaded. */
            job->fatal_error = 1;
            job->next_run = 0;
            goto leave;
        }
        
        if (md_will_renew_cert(md)) {
            /* Renew the MDs credentials in a STAGING area. Might be invoked repeatedly
             * without discarding previous/intermediate results.
             * Only returns SUCCESS when the renewal is complete, e.g. STAGING has a
             * complete set of new credentials.
             */
            ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10052) 
                         "md(%s): state=%d, driving", job->mdomain, md->state);
    
            if (md->stapling && dctx->mc->ocsp &&
                md_reg_has_revoked_certs(dctx->mc->reg, dctx->mc->ocsp, md, dctx->p)) {
                ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10500)
                             "md(%s): has revoked certificates", job->mdomain);
            }
            else if (!md_reg_should_renew(dctx->mc->reg, md, dctx->p)) {
                ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10053) 
                             "md(%s): no need to renew", job->mdomain);
                goto expiry;
            }
        
            /* The (possibly configured) event handler may veto renewals. This
             * is used in cluster installtations, see #233. */
            rv = md_event_raise("renewing", md->name, job, result, ptemp);
            if (APR_SUCCESS != rv) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0, dctx->s, APLOGNO(10060)
                                 "%s: event-handler for 'renewing' returned %d, preventing renewal to proceed.",
                                 job->mdomain, rv);
                    goto leave;
            }
    
            md_job_start_run(job, result, md_reg_store_get(dctx->mc->reg));
            md_reg_renew(dctx->mc->reg, md, dctx->mc->env, 0, job->error_runs, result, ptemp);
            md_job_end_run(job, result);
            
            if (APR_SUCCESS == result->status) {
                /* Finished jobs might take a while before the results become valid.
                 * If that is in the future, request to run then */
                if (apr_time_now() < result->ready_at) {
                    md_job_retry_at(job, result->ready_at);
                    goto leave;
                }
                
                if (!job->notified_renewed) {
                    md_job_save(job, result, ptemp);
                    md_job_notify(job, "renewed", result);
                }
            }
            else {
                ap_log_error( APLOG_MARK, APLOG_ERR, result->status, dctx->s, APLOGNO(10056) 
                             "processing %s: %s", job->mdomain, result->detail);
                md_job_log_append(job, "renewal-error", result->problem, result->detail);
                md_event_holler("errored", job->mdomain, job, result, ptemp);
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, dctx->s, APLOGNO(10057) 
                             "%s: encountered error for the %d. time, next run in %s",
                             job->mdomain, job->error_runs, 
                             md_duration_print(ptemp, job->next_run - apr_time_now()));
            }
        }
    
    expiry:
        if (!job->finished && md_reg_should_warn(dctx->mc->reg, md, dctx->p)) {
            ap_log_error( APLOG_MARK, APLOG_TRACE1, 0, dctx->s,
                         "md(%s): warn about expiration", md->name);
            md_job_start_run(job, result, md_reg_store_get(dctx->mc->reg));
            md_job_notify(job, "expiring", result);
            md_job_end_run(job, result);
        }
    
    leave:
        if (job->dirty && result) {
            rv = md_job_save(job, result, ptemp);
            ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, dctx->s, "%s: saving job props", job->mdomain);
        }
    }
    
    int md_will_renew_cert(const md_t *md)
    {
        if (md->renew_mode == MD_RENEW_MANUAL) {
            return 0;
        }
        else if (md->renew_mode == MD_RENEW_AUTO && md->cert_files && md->cert_files->nelts) {
            return 0;
        } 
        return 1;
    }
    
    static apr_time_t next_run_default(md_renew_ctx_t *dctx)
    {
        unsigned char c;
        apr_time_t delay = dctx->mc->check_interval;
    
        md_rand_bytes(&c, sizeof(c), dctx->p);
        return apr_time_now() + delay + (delay * (c - 128) / 256);
    }
    
    static apr_status_t run_watchdog(int state, void *baton, apr_pool_t *ptemp)
    {
        md_renew_ctx_t *dctx = baton;
        md_job_t *job;
        apr_time_t next_run, wait_time;
        int i;
        
        /* mod_watchdog invoked us as a single thread inside the whole server (on this machine).
         * This might be a repeated run inside the same child (mod_watchdog keeps affinity as
         * long as the child lives) or another/new child.
         */
        switch (state) {
            case AP_WATCHDOG_STATE_STARTING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10054)
                             "md watchdog start, auto drive %d mds", dctx->jobs->nelts);
                break;
                
            case AP_WATCHDOG_STATE_RUNNING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10055)
                             "md watchdog run, auto drive %d mds", dctx->jobs->nelts);
                             
                /* Process all drive jobs. They will update their next_run property
                 * and we schedule ourself at the earliest of all. A job may specify 0
                 * as next_run to indicate that it wants to participate in the normal
                 * regular runs. */
                next_run = next_run_default(dctx);
                for (i = 0; i < dctx->jobs->nelts; ++i) {
                    job = APR_ARRAY_IDX(dctx->jobs, i, md_job_t *);
                    
                    if (apr_time_now() >= job->next_run) {
                        process_drive_job(dctx, job, ptemp);
                    }
                    
                    if (job->next_run && job->next_run < next_run) {
                        next_run = job->next_run;
                    }
                }
    
                wait_time = next_run - apr_time_now();
                if (APLOGdebug(dctx->s)) {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10107)
                                 "next run in %s", md_duration_print(ptemp, wait_time));
                }
                wd_set_interval(dctx->watchdog, wait_time, dctx, run_watchdog);
                break;
                
            case AP_WATCHDOG_STATE_STOPPING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10058)
                             "md watchdog stopping");
                break;
        }
        
        return APR_SUCCESS;
    }
    
    apr_status_t md_renew_start_watching(md_mod_conf_t *mc, server_rec *s, apr_pool_t *p)
    {
        apr_allocator_t *allocator;
        md_renew_ctx_t *dctx;
        apr_pool_t *dctxp;
        apr_status_t rv;
        md_t *md;
        md_job_t *job;
        int i;
        
        /* We use mod_watchdog to run a single thread in one of the child processes
         * to monitor the MDs marked as watched, using the const data in the list
         * mc->mds of our MD structures.
         *
         * The data in mc cannot be changed, as we may spawn copies in new child processes
         * of the original data at any time. The child which hosts the watchdog thread
         * may also die or be recycled, which causes a new watchdog thread to run
         * in another process with the original data.
         * 
         * Instead, we use our store to persist changes in group STAGING. This is
         * kept writable to child processes, but the data stored there is not live.
         * However, mod_watchdog makes sure that we only ever have a single thread in
         * our server (on this machine) that writes there. Other processes, e.g. informing
         * the user about progress, only read from there.
         *
         * All changes during driving an MD are stored as files in MG_SG_STAGING/<MD.name>.
         * All will have "md.json" and "job.json". There may be a range of other files used
         * by the protocol obtaining the certificate/keys.
         * 
         * 
         */
        wd_get_instance = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_get_instance);
        wd_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback);
        wd_set_interval = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_set_callback_interval);
        
        if (!wd_get_instance || !wd_register_callback || !wd_set_interval) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(10061) "mod_watchdog is required");
            return !OK;
        }
        
        /* We want our own pool with own allocator to keep data across watchdog invocations.
         * Since we'll run in a single watchdog thread, using our own allocator will prevent 
         * any confusion in the parent pool. */
        apr_allocator_create(&allocator);
        apr_allocator_max_free_set(allocator, 1);
        rv = apr_pool_create_ex(&dctxp, p, NULL, allocator);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10062) "md_renew_watchdog: create pool");
            return rv;
        }
        apr_allocator_owner_set(allocator, dctxp);
        apr_pool_tag(dctxp, "md_renew_watchdog");
    
        dctx = apr_pcalloc(dctxp, sizeof(*dctx));
        dctx->p = dctxp;
        dctx->s = s;
        dctx->mc = mc;
        
        dctx->jobs = apr_array_make(dctx->p, mc->mds->nelts, sizeof(md_job_t *));
        for (i = 0; i < mc->mds->nelts; ++i) {
            md = APR_ARRAY_IDX(mc->mds, i, md_t*);
            if (!md || !md->watched) continue;
            
            job = md_reg_job_make(mc->reg, md->name, p);
            APR_ARRAY_PUSH(dctx->jobs, md_job_t*) = job;
            ap_log_error( APLOG_MARK, APLOG_TRACE1, 0, dctx->s,  
                         "md(%s): state=%d, created drive job", md->name, md->state);
            
            md_job_load(job);
            if (job->error_runs) {
                /* Server has just restarted. If we encounter an MD job with errors
                 * on a previous driving, we purge its STAGING area.
                 * This will reset the driving for the MD. It may run into the same
                 * error again, or in case of race/confusion/our error/CA error, it
                 * might allow the MD to succeed by a fresh start.
                 */
                ap_log_error( APLOG_MARK, APLOG_NOTICE, 0, dctx->s, APLOGNO(10064) 
                             "md(%s): previous drive job showed %d errors, purging STAGING "
                             "area to reset.", md->name, job->error_runs);
                md_store_purge(md_reg_store_get(dctx->mc->reg), p, MD_SG_STAGING, md->name);
                md_store_purge(md_reg_store_get(dctx->mc->reg), p, MD_SG_CHALLENGES, md->name);
                job->error_runs = 0;
            }
        }
    
        if (!dctx->jobs->nelts) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10065)
                         "no managed domain to drive, no watchdog needed.");
            apr_pool_destroy(dctx->p);
            return APR_SUCCESS;
        }
        
        if (APR_SUCCESS != (rv = wd_get_instance(&dctx->watchdog, MD_RENEW_WATCHDOG_NAME, 0, 1, dctx->p))) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(10066) 
                         "create md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME);
            return rv;
        }
        rv = wd_register_callback(dctx->watchdog, 0, dctx, run_watchdog);
        ap_log_error(APLOG_MARK, rv? APLOG_CRIT : APLOG_DEBUG, rv, s, APLOGNO(10067) 
                     "register md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME);
        return rv;
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_http.c�������������������������������������������������������������������0000664�0001751�0001751�00000027171�14301701440�016477� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_buckets.h>
    
    #include "md_http.h"
    #include "md_log.h"
    #include "md_util.h"
    
    struct md_http_t {
        apr_pool_t *pool;
        apr_bucket_alloc_t *bucket_alloc;
        int next_id;
        apr_off_t resp_limit;
        md_http_impl_t *impl;
        void *impl_data;         /* to be used by the implementation */
        const char *user_agent;
        const char *proxy_url;
        const char *unix_socket_path;
        md_http_timeouts_t timeout;
        const char *ca_file;
    };
    
    static md_http_impl_t *cur_impl;
    static int cur_init_done;
    
    void md_http_use_implementation(md_http_impl_t *impl)
    {
        if (cur_impl != impl) {
            cur_impl = impl;
            cur_init_done = 0;
        }
    }
    
    static apr_status_t http_cleanup(void *data)
    {
        md_http_t *http = data;
        if (http && http->impl && http->impl->cleanup) {
            http->impl->cleanup(http, http->pool);
        }
        return APR_SUCCESS;
    }
    
    apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent,
                                const char *proxy_url)
    {
        md_http_t *http;
        apr_status_t rv = APR_SUCCESS;
    
        if (!cur_impl) {
            *phttp = NULL;
            return APR_ENOTIMPL;
        }
        
        if (!cur_init_done) {
            if (APR_SUCCESS == (rv = cur_impl->init())) {
                cur_init_done = 1;
            }
            else {
                return rv;
            }
        }
        
        http = apr_pcalloc(p, sizeof(*http));
        http->pool = p;
        http->impl = cur_impl;
        http->user_agent = apr_pstrdup(p, user_agent);
        http->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL;
        http->bucket_alloc = apr_bucket_alloc_create(p);
        if (!http->bucket_alloc) {
            return APR_EGENERAL;
        }
        apr_pool_cleanup_register(p, http, http_cleanup, apr_pool_cleanup_null);
        *phttp = http;
        return APR_SUCCESS;
    }
    
    apr_status_t md_http_clone(md_http_t **phttp,
                               apr_pool_t *p, md_http_t *source_http)
    {
        apr_status_t rv;
    
        rv = md_http_create(phttp, p, source_http->user_agent, source_http->proxy_url);
        if (APR_SUCCESS == rv) {
            (*phttp)->resp_limit = source_http->resp_limit;
            (*phttp)->timeout = source_http->timeout;
            if (source_http->unix_socket_path) {
                (*phttp)->unix_socket_path = apr_pstrdup(p, source_http->unix_socket_path);
            }
            if (source_http->ca_file) {
                (*phttp)->ca_file = apr_pstrdup(p, source_http->ca_file);
            }
        }
        return rv;
    }
    
    void md_http_set_impl_data(md_http_t *http, void *data)
    {
        http->impl_data = data;
    }
    
    void *md_http_get_impl_data(md_http_t *http)
    {
        return http->impl_data;
    }
    
    void md_http_set_response_limit(md_http_t *http, apr_off_t resp_limit)
    {
        http->resp_limit = resp_limit;
    }
    
    void md_http_set_timeout_default(md_http_t *http, apr_time_t timeout)
    {
        http->timeout.overall = timeout;
    }
    
    void md_http_set_timeout(md_http_request_t *req, apr_time_t timeout)
    {
        req->timeout.overall = timeout;
    }
    
    void md_http_set_connect_timeout_default(md_http_t *http, apr_time_t timeout)
    {
        http->timeout.connect = timeout;
    }
    
    void md_http_set_connect_timeout(md_http_request_t *req, apr_time_t timeout)
    {
        req->timeout.connect = timeout;
    }
    
    void md_http_set_stalling_default(md_http_t *http, long bytes_per_sec, apr_time_t timeout)
    {
        http->timeout.stall_bytes_per_sec = bytes_per_sec;
        http->timeout.stalled = timeout;
    }
    
    void md_http_set_stalling(md_http_request_t *req, long bytes_per_sec, apr_time_t timeout)
    {
        req->timeout.stall_bytes_per_sec = bytes_per_sec;
        req->timeout.stalled = timeout;
    }
    
    void md_http_set_ca_file(md_http_t *http, const char *ca_file)
    {
        http->ca_file = ca_file;
    }
    
    void md_http_set_unix_socket_path(md_http_t *http, const char *path)
    {
        http->unix_socket_path = path;
    }
    
    static apr_status_t req_set_body(md_http_request_t *req, const char *content_type,
                                     apr_bucket_brigade *body, apr_off_t body_len,
                                     int detect_len)
    {
        apr_status_t rv = APR_SUCCESS;
        
        if (body && detect_len) {
            rv = apr_brigade_length(body, 1, &body_len);
            if (rv != APR_SUCCESS) {
                return rv;
            }
        }
    
        req->body = body;
        req->body_len = body? body_len : 0;
        if (content_type) {
            apr_table_set(req->headers, "Content-Type", content_type); 
        }
        else {
            apr_table_unset(req->headers, "Content-Type"); 
        }
        return rv;
    }
    
    static apr_status_t req_set_body_data(md_http_request_t *req, const char *content_type,
                                          const md_data_t *body)
    {
        apr_bucket_brigade *bbody = NULL;
        apr_status_t rv;
        
        if (body && body->len > 0) {
            bbody = apr_brigade_create(req->pool, req->http->bucket_alloc);
            rv = apr_brigade_write(bbody, NULL, NULL, body->data, body->len);
            if (rv != APR_SUCCESS) {
                return rv;
            }
        }
        return req_set_body(req, content_type, bbody, body? (apr_off_t)body->len : 0, 0);
    }
    
    static apr_status_t req_create(md_http_request_t **preq, md_http_t *http, 
                                   const char *method, const char *url, 
                                   struct apr_table_t *headers)
    {
        md_http_request_t *req;
        apr_pool_t *pool;
        apr_status_t rv;
        
        rv = apr_pool_create(&pool, http->pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        apr_pool_tag(pool, "md_http_req");
        
        req = apr_pcalloc(pool, sizeof(*req));
        req->pool = pool;
        req->id = http->next_id++;
        req->bucket_alloc = http->bucket_alloc;
        req->http = http;
        req->method = method;
        req->url = url;
        req->headers = headers? apr_table_copy(req->pool, headers) : apr_table_make(req->pool, 5);
        req->resp_limit = http->resp_limit;
        req->user_agent = http->user_agent;
        req->proxy_url = http->proxy_url;
        req->timeout = http->timeout;
        req->ca_file = http->ca_file;
        req->unix_socket_path = http->unix_socket_path;
        *preq = req;
        return rv;
    }
    
    void md_http_req_destroy(md_http_request_t *req) 
    {
        if (req->internals) {
            req->http->impl->req_cleanup(req);
            req->internals = NULL;
        }
        apr_pool_destroy(req->pool);
    }
    
    void md_http_set_on_status_cb(md_http_request_t *req, md_http_status_cb *cb, void *baton)
    {
        req->cb.on_status = cb;
        req->cb.on_status_data = baton;
    }
    
    void md_http_set_on_response_cb(md_http_request_t *req, md_http_response_cb *cb, void *baton)
    {
        req->cb.on_response = cb;
        req->cb.on_response_data = baton;
    }
    
    apr_status_t md_http_perform(md_http_request_t *req)
    {
        return req->http->impl->perform(req);
    }
    
    typedef struct {
        md_http_next_req *nextreq;
        void *baton;
    } nextreq_proxy_t;
    
    static apr_status_t proxy_nextreq(md_http_request_t **preq, void *baton, 
                                          md_http_t *http, int in_flight)
    {
        nextreq_proxy_t *proxy = baton;
        
        return proxy->nextreq(preq, proxy->baton, http, in_flight);
    }
    
    apr_status_t md_http_multi_perform(md_http_t *http, md_http_next_req *nextreq, void *baton)
    {
        nextreq_proxy_t proxy;
        
        proxy.nextreq = nextreq;
        proxy.baton = baton;
        return http->impl->multi_perform(http, http->pool, proxy_nextreq, &proxy);
    }
    
    apr_status_t md_http_GET_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                    struct apr_table_t *headers)
    {
        md_http_request_t *req;
        apr_status_t rv;
        
        rv = req_create(&req, http, "GET", url, headers);
        *preq = (APR_SUCCESS == rv)? req : NULL;
        return rv;
    }
    
    apr_status_t md_http_HEAD_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                     struct apr_table_t *headers)
    {
        md_http_request_t *req;
        apr_status_t rv;
        
        rv = req_create(&req, http, "HEAD", url, headers);
        *preq = (APR_SUCCESS == rv)? req : NULL;
        return rv;
    }
    
    apr_status_t md_http_POST_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                     struct apr_table_t *headers, const char *content_type, 
                                     struct apr_bucket_brigade *body, int detect_len)
    {
        md_http_request_t *req;
        apr_status_t rv;
        
        rv = req_create(&req, http, "POST", url, headers);
        if (APR_SUCCESS == rv) {
            rv = req_set_body(req, content_type, body, -1, detect_len);
        }
        *preq = (APR_SUCCESS == rv)? req : NULL;
        return rv;
    }
    
    apr_status_t md_http_POSTd_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                      struct apr_table_t *headers, const char *content_type, 
                                      const struct md_data_t *body)
    {
        md_http_request_t *req;
        apr_status_t rv;
        
        rv = req_create(&req, http, "POST", url, headers);
        if (APR_SUCCESS != rv) goto cleanup;
        rv = req_set_body_data(req, content_type, body);
    cleanup:
        if (APR_SUCCESS == rv) {
            *preq = req;
        }
        else {
            *preq = NULL;
            if (req) md_http_req_destroy(req);
        }
        return rv;
    }
    
    apr_status_t md_http_GET_perform(struct md_http_t *http, 
                                     const char *url, struct apr_table_t *headers,
                                     md_http_response_cb *cb, void *baton)
    {
        md_http_request_t *req;
        apr_status_t rv;
    
        rv = md_http_GET_create(&req, http, url, headers);
        if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
        return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
    }
    
    apr_status_t md_http_HEAD_perform(struct md_http_t *http, 
                                      const char *url, struct apr_table_t *headers,
                                      md_http_response_cb *cb, void *baton)
    {
        md_http_request_t *req;
        apr_status_t rv;
    
        rv = md_http_HEAD_create(&req, http, url, headers);
        if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
        return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
    }
    
    apr_status_t md_http_POST_perform(struct md_http_t *http, const char *url, 
                                      struct apr_table_t *headers, const char *content_type, 
                                      apr_bucket_brigade *body, int detect_len, 
                                      md_http_response_cb *cb, void *baton)
    {
        md_http_request_t *req;
        apr_status_t rv;
    
        rv = md_http_POST_create(&req, http, url, headers, content_type, body, detect_len);
        if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
        return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
    }
    
    apr_status_t md_http_POSTd_perform(md_http_t *http, const char *url, 
                                       struct apr_table_t *headers, const char *content_type, 
                                       const md_data_t *body, 
                                       md_http_response_cb *cb, void *baton)
    {
        md_http_request_t *req;
        apr_status_t rv;
    
        rv = md_http_POSTd_create(&req, http, url, headers, content_type, body);
        if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
        return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_store.h������������������������������������������������������������������0000664�0001751�0001751�00000036622�14301701440�016662� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_store_h
    #define mod_md_md_store_h
    
    struct apr_array_header_t;
    struct md_cert_t;
    struct md_pkey_t;
    struct md_pkey_spec_t;
    
    const char *md_store_group_name(unsigned int group);
    
    typedef struct md_store_t md_store_t;
    
    /**
     * A store for domain related data.
     *
     * The Key for a piece of data is the set of 3 items
     *   <group> + <domain> + <aspect>
     *
     * Examples:
     * "domains" + "greenbytes.de" + "pubcert.pem"
     * "ocsp" + "greenbytes.de" + "ocsp-XXXXX.json"
     *
     * Storage groups are pre-defined, domain and aspect names can be freely chosen.
     *
     * Groups reflect use cases and come with security restrictions. The groups 
     * DOMAINS, ARCHIVE and NONE are only accessible during the startup 
     * phase of httpd.
     *
     * Private key are stored unencrypted only in restricted groups. Meaning that certificate
     * keys in group DOMAINS are not encrypted, but only readable at httpd start/reload.
     * Keys in unrestricted groups are encrypted using a pass phrase generated once and stored
     * in NONE.
     */
    
    /** Value types handled by a store */
    typedef enum {
        MD_SV_TEXT,         /* plain text, value is (char*) */
        MD_SV_JSON,         /* JSON serialization, value is (md_json_t*) */
        MD_SV_CERT,         /* PEM x509 certificate, value is (md_cert_t*) */
        MD_SV_PKEY,         /* PEM private key, value is (md_pkey_t*) */
        MD_SV_CHAIN,        /* list of PEM x509 certificates, value is 
                               (apr_array_header_t*) of (md_cert*) */
    } md_store_vtype_t;
    
    /** Store storage groups */
    typedef enum {
        MD_SG_NONE,         /* top level of store, name MUST be NULL in calls */
        MD_SG_ACCOUNTS,     /* ACME accounts */
        MD_SG_CHALLENGES,   /* challenge response data for a domain */ 
        MD_SG_DOMAINS,      /* live certificates and settings for a domain */
        MD_SG_STAGING,      /* staged set of certificate and settings, maybe incomplete */
        MD_SG_ARCHIVE,      /* Archived live sets of a domain */
        MD_SG_TMP,          /* temporary domain storage */
        MD_SG_OCSP,         /* OCSP stapling related domain data */
        MD_SG_COUNT,        /* number of storage groups, used in setups */
    } md_store_group_t;
    
    #define MD_FN_MD                "md.json"
    #define MD_FN_JOB               "job.json"
    #define MD_FN_HTTPD_JSON        "httpd.json"
    
    /* The corresponding names for current cert & key files are constructed
     * in md_store and md_crypt.
     */
    
    /* These three legacy filenames are only used in md_store_fs to
     * upgrade 1.0 directories.  They should not be used for any other
     * purpose.
     */
    #define MD_FN_PRIVKEY           "privkey.pem"
    #define MD_FN_PUBCERT           "pubcert.pem"
    #define MD_FN_CERT              "cert.pem"
    
    /**
     * Load the JSON value at key "group/name/aspect", allocated from pool p.
     * @return APR_ENOENT if there is no such value
     */
    apr_status_t md_store_load_json(md_store_t *store, md_store_group_t group, 
                                    const char *name, const char *aspect, 
                                    struct md_json_t **pdata, apr_pool_t *p);
    /**
     * Save the JSON value at key "group/name/aspect". If create != 0, fail if there
     * already is a value for this key.
     */
    apr_status_t md_store_save_json(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                    const char *name, const char *aspect, 
                                    struct md_json_t *data, int create);
    
    /**
     * Load the value of type at key "group/name/aspect", allocated from pool p. Usually, the
     * type is expected to be the same as used in saving the value. Some conversions will work,
     * others will fail the format.
     * @return APR_ENOENT if there is no such value
     */
    apr_status_t md_store_load(md_store_t *store, md_store_group_t group, 
                               const char *name, const char *aspect, 
                               md_store_vtype_t vtype, void **pdata, 
                               apr_pool_t *p);
    /**
     * Save the JSON value at key "group/name/aspect". If create != 0, fail if there
     * already is a value for this key. The provided data MUST be of the correct type.
     */
    apr_status_t md_store_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                               const char *name, const char *aspect, 
                               md_store_vtype_t vtype, void *data, 
                               int create);
    
    /**
     * Remove the value stored at key "group/name/aspect". Unless force != 0, a missing
     * value will cause the call to fail with APR_ENOENT.
     */ 
    apr_status_t md_store_remove(md_store_t *store, md_store_group_t group, 
                                 const char *name, const char *aspect, 
                                 apr_pool_t *p, int force);
    /**
     * Remove everything matching key "group/name".
     */ 
    apr_status_t md_store_purge(md_store_t *store, apr_pool_t *p, 
                                md_store_group_t group, const char *name);
    
    /**
     * Remove all items matching the name/aspect patterns that have not been
     * modified since the given timestamp.
     */
    apr_status_t md_store_remove_not_modified_since(md_store_t *store, apr_pool_t *p, 
                                                    apr_time_t modified,
                                                    md_store_group_t group, 
                                                    const char *name, 
                                                    const char *aspect);
    
    /**
     * inspect callback function. Invoked for each matched value. Values allocated from
     * ptemp may disappear any time after the call returned. If this function returns
     * 0, the iteration is aborted. 
     */
    typedef int md_store_inspect(void *baton, const char *name, const char *aspect, 
                                 md_store_vtype_t vtype, void *value, apr_pool_t *ptemp);
    
    /**
     * Iterator over all existing values matching the name pattern. Patterns are evaluated
     * using apr_fnmatch() without flags.
     */
    apr_status_t md_store_iter(md_store_inspect *inspect, void *baton, md_store_t *store, 
                               apr_pool_t *p, md_store_group_t group, const char *pattern, 
                               const char *aspect, md_store_vtype_t vtype);
    
    /**
     * Move everything matching key "from/name" from one group to another. If archive != 0,
     * move any existing "to/name" into a new "archive/new_name" location.
     */
    apr_status_t md_store_move(md_store_t *store, apr_pool_t *p,
                               md_store_group_t from, md_store_group_t to,
                               const char *name, int archive);
    
    /**
     * Rename a group member.
     */
    apr_status_t md_store_rename(md_store_t *store, apr_pool_t *p,
                                 md_store_group_t group, const char *name, const char *to);
    
    /**
     * Get the filename of an item stored in "group/name/aspect". The item does
     * not have to exist.
     */
    apr_status_t md_store_get_fname(const char **pfname, 
                                    md_store_t *store, md_store_group_t group, 
                                    const char *name, const char *aspect, 
                                    apr_pool_t *p);
    
    /**
     * Make a compare on the modification time of "group1/name/aspect" vs. "group2/name/aspect".
     */
    int md_store_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
                          const char *name, const char *aspect, apr_pool_t *p);
    
    /**
     * Iterate over all names that exist in a group, e.g. there are items matching
     * "group/pattern". The inspect function is called with the name and NULL aspect
     * and value.
     */
    apr_status_t md_store_iter_names(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                     apr_pool_t *p, md_store_group_t group, const char *pattern);
    
    /**
     * Get the modification time of the item store under "group/name/aspect".
     * @return modification time or 0 if the item does not exist.
     */
    apr_time_t md_store_get_modified(md_store_t *store, md_store_group_t group,  
                                     const char *name, const char *aspect, apr_pool_t *p);
    
    /**
     * Acquire a cooperative, global lock on store modifications.
    
     * This will only prevent other children/processes/cluster nodes from
     * doing the same and does not protect individual store functions from
     * being called without it.
     * @param store the store
     * @param p memory pool to use
     * @param max_wait maximum time to wait in order to acquire
     * @return APR_SUCCESS when lock was obtained
     */
    apr_status_t md_store_lock_global(md_store_t *store, apr_pool_t *p, apr_time_t max_wait);
    
    /**
     * Realease the global store lock. Will do nothing if there is no lock.
     */
    void md_store_unlock_global(md_store_t *store, apr_pool_t *p);
    
    /**************************************************************************************************/
    /* Storage handling utils */
    
    apr_status_t md_load(md_store_t *store, md_store_group_t group, 
                         const char *name, md_t **pmd, apr_pool_t *p);
    apr_status_t md_save(struct md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                         md_t *md, int create);
    apr_status_t md_remove(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                         const char *name, int force);
    
    int md_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
                    const char *name, apr_pool_t *p);
    
    typedef int md_store_md_inspect(void *baton, md_store_t *store, md_t *md, apr_pool_t *ptemp);
    
    apr_status_t md_store_md_iter(md_store_md_inspect *inspect, void *baton, md_store_t *store, 
                                  apr_pool_t *p, md_store_group_t group, const char *pattern);
    
    
    const char *md_pkey_filename(struct md_pkey_spec_t *spec, apr_pool_t *p);
    const char *md_chain_filename(struct md_pkey_spec_t *spec, apr_pool_t *p);
    
    apr_status_t md_pkey_load(md_store_t *store, md_store_group_t group, 
                              const char *name, struct md_pkey_spec_t *spec,
                              struct md_pkey_t **ppkey, apr_pool_t *p);
    apr_status_t md_pkey_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                              const char *name, struct md_pkey_spec_t *spec,
                              struct md_pkey_t *pkey, int create);
    
    apr_status_t md_pubcert_load(md_store_t *store, md_store_group_t group, const char *name, 
                                 struct md_pkey_spec_t *spec, struct apr_array_header_t **ppubcert, 
                                 apr_pool_t *p);
    apr_status_t md_pubcert_save(md_store_t *store, apr_pool_t *p, 
                                 md_store_group_t group, const char *name, 
                                 struct md_pkey_spec_t *spec, 
                                 struct apr_array_header_t *pubcert, int create);
    
    /**************************************************************************************************/
    /* X509 complete credentials */
    
    typedef struct md_credentials_t md_credentials_t;
    struct md_credentials_t {
        struct md_pkey_spec_t *spec;
        struct md_pkey_t *pkey;
        struct apr_array_header_t *chain;
    };
    
    apr_status_t md_creds_load(md_store_t *store, md_store_group_t group, const char *name, 
                               struct md_pkey_spec_t *spec, md_credentials_t **pcreds, apr_pool_t *p);
    apr_status_t md_creds_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                               const char *name, md_credentials_t *creds, int create);
    
    /**************************************************************************************************/
    /* implementation interface */
    
    typedef apr_status_t md_store_load_cb(md_store_t *store, md_store_group_t group, 
                                          const char *name, const char *aspect, 
                                          md_store_vtype_t vtype, void **pvalue, 
                                          apr_pool_t *p);
    typedef apr_status_t md_store_save_cb(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                          const char *name, const char *aspect, 
                                          md_store_vtype_t vtype, void *value, 
                                          int create);
    typedef apr_status_t md_store_remove_cb(md_store_t *store, md_store_group_t group, 
                                            const char *name, const char *aspect,  
                                            apr_pool_t *p, int force);
    typedef apr_status_t md_store_purge_cb(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                            const char *name);
    
    typedef apr_status_t md_store_iter_cb(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                          apr_pool_t *p, md_store_group_t group, const char *pattern,
                                          const char *aspect, md_store_vtype_t vtype);
    
    typedef apr_status_t md_store_names_iter_cb(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                                apr_pool_t *p, md_store_group_t group, const char *pattern);
    
    typedef apr_status_t md_store_move_cb(md_store_t *store, apr_pool_t *p, md_store_group_t from, 
                                          md_store_group_t to, const char *name, int archive);
    
    typedef apr_status_t md_store_rename_cb(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                            const char *from, const char *to);
    
    typedef apr_status_t md_store_get_fname_cb(const char **pfname, 
                                               md_store_t *store, md_store_group_t group, 
                                               const char *name, const char *aspect, 
                                               apr_pool_t *p);
    
    typedef int md_store_is_newer_cb(md_store_t *store, 
                                     md_store_group_t group1, md_store_group_t group2,  
                                     const char *name, const char *aspect, apr_pool_t *p);
    
    typedef apr_time_t md_store_get_modified_cb(md_store_t *store, md_store_group_t group,  
                                                const char *name, const char *aspect, apr_pool_t *p);
    
    typedef apr_status_t md_store_remove_nms_cb(md_store_t *store, apr_pool_t *p, 
                                                apr_time_t modified, md_store_group_t group, 
                                                const char *name, const char *aspect);
    typedef apr_status_t md_store_lock_global_cb(md_store_t *store, apr_pool_t *p, apr_time_t max_wait);
    typedef void md_store_unlock_global_cb(md_store_t *store, apr_pool_t *p);
    
    struct md_store_t {
        md_store_save_cb *save;
        md_store_load_cb *load;
        md_store_remove_cb *remove;
        md_store_move_cb *move;
        md_store_rename_cb *rename;
        md_store_iter_cb *iterate;
        md_store_names_iter_cb *iterate_names;
        md_store_purge_cb *purge;
        md_store_get_fname_cb *get_fname;
        md_store_is_newer_cb *is_newer;
        md_store_get_modified_cb *get_modified;
        md_store_remove_nms_cb *remove_nms;
        md_store_lock_global_cb *lock_global;
        md_store_unlock_global_cb *unlock_global;
    };
    
    
    #endif /* mod_md_md_store_h */
    ��������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_status.h�����������������������������������������������������������������0000664�0001751�0001751�00000011524�14240433464�017055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 md_status_h
    #define md_status_h
    
    struct md_json_t;
    struct md_reg_t;
    struct md_result_t;
    struct md_ocsp_reg_t;
    
    #include "md_store.h"
    
    /** 
     * Get a JSON summary of the MD and its status (certificates, jobs, etc.).
     */
    apr_status_t md_status_get_md_json(struct md_json_t **pjson, const md_t *md, 
                                       struct md_reg_t *reg, struct md_ocsp_reg_t *ocsp,
                                       apr_pool_t *p);
    
    /** 
     * Get a JSON summary of all MDs and their status.
     */
    apr_status_t md_status_get_json(struct md_json_t **pjson, apr_array_header_t *mds, 
                                    struct md_reg_t *reg, struct md_ocsp_reg_t *ocsp,
                                    apr_pool_t *p);
    
    /**
     * Take stock of all MDs given for a short overview. The JSON returned
     * will carry integers for MD_KEY_COMPLETE, MD_KEY_RENEWING, 
     * MD_KEY_ERRORED, MD_KEY_READY and MD_KEY_TOTAL.
     */
    void  md_status_take_stock(struct md_json_t **pjson, apr_array_header_t *mds, 
                               struct md_reg_t *reg, apr_pool_t *p);
    
    
    typedef struct md_job_t md_job_t;
    
    struct md_job_t {
        md_store_group_t group;/* group where job is persisted */
        const char *mdomain;   /* Name of the MD this job is about */
        md_store_t *store;     /* store where it is persisted */
        apr_pool_t *p;     
        apr_time_t next_run;   /* Time this job wants to be processed next */
        apr_time_t last_run;   /* Time this job ran last (or 0) */
        struct md_result_t *last_result; /* Result from last run */
        int finished;          /* true iff the job finished successfully */
        int notified;          /* true iff notifications were handled successfully */
        int notified_renewed;  /* true iff a 'renewed' notification was handled successfully */
        apr_time_t valid_from; /* at which time the finished job results become valid, 0 if immediate */
        int error_runs;        /* Number of errored runs of an unfinished job */
        int fatal_error;       /* a fatal error is remedied by retrying */
        md_json_t *log;        /* array of log objects with minimum fields
                                  MD_KEY_WHEN (timestamp) and MD_KEY_TYPE (string) */
        apr_size_t max_log;    /* max number of log entries, new ones replace oldest */
        int dirty;
        struct md_result_t *observing;
        apr_time_t min_delay;  /* smallest delay a repeated attempt should have */
    };
    
    /**
     * Create a new job instance for the given MD name. 
     * Job load/save will work using the name.
     */
    md_job_t *md_job_make(apr_pool_t *p, md_store_t *store, 
                          md_store_group_t group, const char *name,
                          apr_time_t min_delay);
    
    void md_job_set_group(md_job_t *job, md_store_group_t group);
    
    /**
     * Update the job from storage in <group>/job->mdomain.
     */
    apr_status_t md_job_load(md_job_t *job);
    
    /**
     * Update storage from job in <group>/job->mdomain.
     */
    apr_status_t md_job_save(md_job_t *job, struct md_result_t *result, apr_pool_t *p);
    
    /**
     * Append to the job's log. Timestamp is automatically added.
     * @param type          type of log entry
     * @param status        status of entry (maybe NULL)
     * @param detail        description of what happened
     */
    void md_job_log_append(md_job_t *job, const char *type, 
                           const char *status, const char *detail);
    
    /**
     * Retrieve the latest log entry of a certain type.
     */
    md_json_t *md_job_log_get_latest(md_job_t *job, const char *type);
    
    /**
     * Get the time the latest log entry of the given type happened, or 0 if
     * none is found.
     */
    apr_time_t md_job_log_get_time_of_latest(md_job_t *job, const char *type);
    
    void md_job_start_run(md_job_t *job, struct md_result_t *result, md_store_t *store);
    void md_job_end_run(md_job_t *job, struct md_result_t *result);
    void md_job_retry_at(md_job_t *job, apr_time_t later);
    
    /**
     * Given the number of errors and the last problem encountered,
     * recommend a delay for the next attempt of job
     */
    apr_time_t md_job_delay_on_errors(md_job_t *job, int err_count, const char *last_problem);
    
    apr_status_t md_job_notify(md_job_t *job, const char *reason, struct md_result_t *result);
    
    #endif /* md_status_h */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_tailscale.h��������������������������������������������������������������0000664�0001751�0001751�00000001777�14232231062�017473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_tailscale_h
    #define mod_md_md_tailscale_h
    
    #define MD_PROTO_TAILSCALE      "tailscale"
    
    apr_status_t md_tailscale_protos_add(struct apr_hash_t *protos, apr_pool_t *p);
    
    #endif /* mod_md_md_tailscale_h */
    
    �httpd-2.4.64/modules/md/md_jws.h��������������������������������������������������������������������0000664�0001751�0001751�00000003637�14147416411�016342� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_jws_h
    #define mod_md_md_jws_h
    
    struct apr_table_t;
    struct md_json_t;
    struct md_pkey_t;
    struct md_data_t;
    
    /**
     * Get the JSON value of the 'jwk' field for the given key.
     */
    apr_status_t md_jws_get_jwk(md_json_t **pjwk, apr_pool_t *p, struct md_pkey_t *pkey);
    
    /**
     * Get the JWS key signed JSON message with given payload and protected fields, signed
     * using the given key and optional key_id.
     */
    apr_status_t md_jws_sign(md_json_t **pmsg, apr_pool_t *p,
                             struct md_data_t *payload, md_json_t *prot_fields,
                             struct md_pkey_t *pkey, const char *key_id);
    /**
     * Get the 'Thumbprint' as defined in RFC8555 for the given key in
     * base64 encoding.
     */
    apr_status_t md_jws_pkey_thumb(const char **pthumb64, apr_pool_t *p, struct md_pkey_t *pkey);
    
    /**
     * Get the JWS HS256 signed message for given payload and protected fields,
     * using the base64 encoded MAC key.
     */
    apr_status_t md_jws_hmac(md_json_t **pmsg, apr_pool_t *p,
                             struct md_data_t *payload, md_json_t *prot_fields,
                             const struct md_data_t *hmac_key);
    
    
    #endif /* md_jws_h */
    �������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_json.c�������������������������������������������������������������������0000664�0001751�0001751�00000075417�14232231062�016500� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_buckets.h>
    #include <apr_date.h>
    
    #include "md_json.h"
    #include "md_log.h"
    #include "md_http.h"
    #include "md_time.h"
    #include "md_util.h"
    
    /* jansson thinks everyone compiles with the platform's cc in its fullest capabilities
     * when undefining their INLINEs, we get static, unused functions, arg 
     */
    #if defined(__GNUC__)
    #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
    #pragma GCC diagnostic push
    #endif
    #pragma GCC diagnostic ignored "-Wunused-function"
    #pragma GCC diagnostic ignored "-Wunreachable-code"
    #elif defined(__clang__)
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wunused-function"
    #endif
    
    #include <jansson_config.h>
    #undef  JSON_INLINE
    #define JSON_INLINE 
    #include <jansson.h>
    
    #if defined(__GNUC__)
    #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
    #pragma GCC diagnostic pop
    #endif
    #elif defined(__clang__)
    #pragma clang diagnostic pop
    #endif
    
    struct md_json_t {
        apr_pool_t *p;
        json_t *j;
    };
    
    /**************************************************************************************************/
    /* lifecycle */
    
    static apr_status_t json_pool_cleanup(void *data)
    {
        md_json_t *json = data;
        if (json) {
            md_json_destroy(json);
        }
        return APR_SUCCESS;
    }
    
    static md_json_t *json_create(apr_pool_t *pool, json_t *j)
    {
        md_json_t *json;
        
        if (!j) {
            apr_abortfunc_t abfn = apr_pool_abort_get(pool);
            if (abfn) {
                abfn(APR_ENOMEM);
            }
            assert(j != NULL); /* failsafe in case abort is unset */
        }
        json = apr_pcalloc(pool, sizeof(*json));
        json->p = pool;
        json->j = j;
        apr_pool_cleanup_register(pool, json, json_pool_cleanup, apr_pool_cleanup_null);
            
        return json;
    }
    
    md_json_t *md_json_create(apr_pool_t *pool)
    {
        return json_create(pool, json_object());
    }
    
    md_json_t *md_json_create_s(apr_pool_t *pool, const char *s)
    {
        return json_create(pool, json_string(s));
    }
    
    void md_json_destroy(md_json_t *json)
    {
        if (json && json->j) {
            assert(json->j->refcount > 0);
            json_decref(json->j);
            json->j = NULL;
        }
    }
    
    md_json_t *md_json_copy(apr_pool_t *pool, const md_json_t *json)
    {
        return json_create(pool, json_copy(json->j));
    }
    
    md_json_t *md_json_clone(apr_pool_t *pool, const md_json_t *json)
    {
        return json_create(pool, json_deep_copy(json->j));
    }
    
    /**************************************************************************************************/
    /* selectors */
    
    
    static json_t *jselect(const md_json_t *json, va_list ap)
    {
        json_t *j;
        const char *key;
        
        j = json->j;
        key = va_arg(ap, char *);
        while (key && j) {
            j = json_object_get(j, key);
            key = va_arg(ap, char *);
        }
        return j;
    }
    
    static json_t *jselect_parent(const char **child_key, int create, md_json_t *json, va_list ap)
    {
        const char *key, *next;
        json_t *j, *jn;
        
        *child_key = NULL;
        j = json->j;
        key = va_arg(ap, char *);
        while (key && j) {
            next = va_arg(ap, char *);
            if (next) {
                jn = json_object_get(j, key);
                if (!jn && create) {
                    jn = json_object();
                    json_object_set_new(j, key, jn);
                }
                j = jn;
            }
            else {
                *child_key = key;
            }
            key = next;
        }
        return j;
    }
    
    static apr_status_t jselect_add(json_t *val, md_json_t *json, va_list ap)
    {
        const char *key;
        json_t *j, *aj;
        
        j = jselect_parent(&key, 1, json, ap);
        
        if (!j || !json_is_object(j)) {
            return APR_EINVAL;
        }
        
        aj = json_object_get(j, key);
        if (!aj) {
            aj = json_array();
            json_object_set_new(j, key, aj);
        }
        
        if (!json_is_array(aj)) {
            return APR_EINVAL;
        }
    
        json_array_append(aj, val);
        return APR_SUCCESS;
    }
    
    static apr_status_t jselect_insert(json_t *val, size_t index, md_json_t *json, va_list ap)
    {
        const char *key;
        json_t *j, *aj;
        
        j = jselect_parent(&key, 1, json, ap);
        
        if (!j || !json_is_object(j)) {
            json_decref(val);
            return APR_EINVAL;
        }
        
        aj = json_object_get(j, key);
        if (!aj) {
            aj = json_array();
            json_object_set_new(j, key, aj);
        }
        
        if (!json_is_array(aj)) {
            json_decref(val);
            return APR_EINVAL;
        }
    
        if (json_array_size(aj) <= index) {
            json_array_append(aj, val);
        }
        else {
            json_array_insert(aj, index, val);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t jselect_set(json_t *val, md_json_t *json, va_list ap)
    {
        const char *key;
        json_t *j;
        
        j = jselect_parent(&key, 1, json, ap);
        
        if (!j) {
            return APR_EINVAL;
        }
        
        if (key) {
            if (!json_is_object(j)) {
                return APR_EINVAL;
            }
            json_object_set(j, key, val);
        }
        else {
            /* replace */
            if (json->j) {
                json_decref(json->j);
            }
            json_incref(val);
            json->j = val;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t jselect_set_new(json_t *val, md_json_t *json, va_list ap)
    {
        const char *key;
        json_t *j;
        
        j = jselect_parent(&key, 1, json, ap);
        
        if (!j) {
            json_decref(val);
            return APR_EINVAL;
        }
        
        if (key) {
            if (!json_is_object(j)) {
                json_decref(val);
                return APR_EINVAL;
            }
            json_object_set_new(j, key, val);
        }
        else {
            /* replace */
            if (json->j) {
                json_decref(json->j);
            }
            json->j = val;
        }
        return APR_SUCCESS;
    }
    
    int md_json_has_key(const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        return j != NULL;
    }
    
    /**************************************************************************************************/
    /* type things */
    
    int md_json_is(const md_json_type_t jtype, md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        switch (jtype) {
            case MD_JSON_TYPE_OBJECT: return (j && json_is_object(j));
            case MD_JSON_TYPE_ARRAY: return (j && json_is_array(j));
            case MD_JSON_TYPE_STRING: return (j && json_is_string(j));
            case MD_JSON_TYPE_REAL: return (j && json_is_real(j));
            case MD_JSON_TYPE_INT: return (j && json_is_integer(j));
            case MD_JSON_TYPE_BOOL: return (j && (json_is_true(j) || json_is_false(j)));
            case MD_JSON_TYPE_NULL: return (j == NULL);
        }
        return 0;
    }
    
    static const char *md_json_type_name(const md_json_t *json)
    {
        json_t *j = json->j;
        if (json_is_object(j)) return "object";
        if (json_is_array(j)) return "array";
        if (json_is_string(j)) return "string";
        if (json_is_real(j)) return "real";
        if (json_is_integer(j)) return "integer";
        if (json_is_true(j)) return "true";
        if (json_is_false(j)) return "false";
        return "unknown";
    }
    
    /**************************************************************************************************/
    /* booleans */
    
    int md_json_getb(const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        return j? json_is_true(j) : 0;
    }
    
    apr_status_t md_json_setb(int value, md_json_t *json, ...)
    {
        va_list ap;
        apr_status_t rv;
        
        va_start(ap, json);
        rv = jselect_set_new(json_boolean(value), json, ap);
        va_end(ap);
        return rv;
    }
    
    /**************************************************************************************************/
    /* numbers */
    
    double md_json_getn(const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        return (j && json_is_number(j))? json_number_value(j) : 0.0;
    }
    
    apr_status_t md_json_setn(double value, md_json_t *json, ...)
    {
        va_list ap;
        apr_status_t rv;
        
        va_start(ap, json);
        rv = jselect_set_new(json_real(value), json, ap);
        va_end(ap);
        return rv;
    }
    
    /**************************************************************************************************/
    /* longs */
    
    long md_json_getl(const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        return (long)((j && json_is_number(j))? json_integer_value(j) : 0L);
    }
    
    apr_status_t md_json_setl(long value, md_json_t *json, ...)
    {
        va_list ap;
        apr_status_t rv;
        
        va_start(ap, json);
        rv = jselect_set_new(json_integer(value), json, ap);
        va_end(ap);
        return rv;
    }
    
    /**************************************************************************************************/
    /* strings */
    
    const char *md_json_gets(const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        return (j && json_is_string(j))? json_string_value(j) : NULL;
    }
    
    const char *md_json_dups(apr_pool_t *p, const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        return (j && json_is_string(j))? apr_pstrdup(p, json_string_value(j)) : NULL;
    }
    
    apr_status_t md_json_sets(const char *value, md_json_t *json, ...)
    {
        va_list ap;
        apr_status_t rv;
        
        va_start(ap, json);
        rv = jselect_set_new(json_string(value), json, ap);
        va_end(ap);
        return rv;
    }
    
    /**************************************************************************************************/
    /* time */
    
    apr_time_t md_json_get_time(const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        if (!j || !json_is_string(j)) return 0;
        return apr_date_parse_rfc(json_string_value(j));
    }
    
    apr_status_t md_json_set_time(apr_time_t value, md_json_t *json, ...)
    {
        char ts[APR_RFC822_DATE_LEN];
        va_list ap;
        apr_status_t rv;
        
        apr_rfc822_date(ts, value);
        va_start(ap, json);
        rv = jselect_set_new(json_string(ts), json, ap);
        va_end(ap);
        return rv;
    }
    
    /**************************************************************************************************/
    /* json itself */
    
    md_json_t *md_json_getj(md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (j) {
            if (j == json->j) {
                return json;
            }
            json_incref(j);
            return json_create(json->p, j);
        }
        return NULL;
    }
    
    md_json_t *md_json_dupj(apr_pool_t *p, const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (j) {
            json_incref(j);
            return json_create(p, j);
        }
        return NULL;
    }
    
    const md_json_t *md_json_getcj(const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (j) {
            if (j == json->j) {
                return json;
            }
            json_incref(j);
            return json_create(json->p, j);
        }
        return NULL;
    }
    
    apr_status_t md_json_setj(const md_json_t *value, md_json_t *json, ...)
    {
        va_list ap;
        apr_status_t rv;
        const char *key;
        json_t *j;
        
        if (value) {
            va_start(ap, json);
            rv = jselect_set(value->j, json, ap);
            va_end(ap);
        }
        else {
            va_start(ap, json);
            j = jselect_parent(&key, 1, json, ap);
            va_end(ap);
            
            if (key && j && !json_is_object(j)) {
                json_object_del(j, key);
                rv = APR_SUCCESS;
            }
            else {
                rv = APR_EINVAL;
            }
        }
        return rv;
    }
    
    apr_status_t md_json_addj(const md_json_t *value, md_json_t *json, ...)
    {
        va_list ap;
        apr_status_t rv;
        
        va_start(ap, json);
        rv = jselect_add(value->j, json, ap);
        va_end(ap);
        return rv;
    }
    
    apr_status_t md_json_insertj(md_json_t *value, size_t index, md_json_t *json, ...)
    {
        va_list ap;
        apr_status_t rv;
        
        va_start(ap, json);
        rv = jselect_insert(value->j, index, json, ap);
        va_end(ap);
        return rv;
    }
    
    apr_size_t md_json_limita(size_t max_elements, md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        apr_size_t n = 0;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        if (j && json_is_array(j)) {
            n = json_array_size(j);
            while (n > max_elements) {
                json_array_remove(j, n-1);
                n = json_array_size(j);
            }
        }
        return n;
    }
    
    /**************************************************************************************************/
    /* arrays / objects */
    
    apr_status_t md_json_clr(md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        if (j && json_is_object(j)) {
            json_object_clear(j);
        }
        else if (j && json_is_array(j)) {
            json_array_clear(j);
        }
        return APR_SUCCESS;
    }
    
    apr_status_t md_json_del(md_json_t *json, ...)
    {
        const char *key;
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect_parent(&key, 0, json, ap);
        va_end(ap);
        
        if (key && j && json_is_object(j)) {
            json_object_del(j, key);
        }
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* object strings */
    
    apr_status_t md_json_gets_dict(apr_table_t *dict, const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        if (j && json_is_object(j)) {
            const char *key;
            json_t *val;
            
            json_object_foreach(j, key, val) {
                if (json_is_string(val)) {
                    apr_table_set(dict, key, json_string_value(val));
                }
            }
            return APR_SUCCESS;
        }
        return APR_ENOENT;
    }
    
    static int object_set(void *data, const char *key, const char *val)
    {
        json_t *j = data, *nj = json_string(val);
        json_object_set(j, key, nj);
        json_decref(nj);
        return 1;
    }
     
    apr_status_t md_json_sets_dict(apr_table_t *dict, md_json_t *json, ...)
    {
        json_t *nj, *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (!j || !json_is_object(j)) {
            const char *key;
            
            va_start(ap, json);
            j = jselect_parent(&key, 1, json, ap);
            va_end(ap);
            
            if (!key || !j || !json_is_object(j)) {
                return APR_EINVAL;
            }
            nj = json_object();
            json_object_set_new(j, key, nj);
            j = nj; 
        }
        
        apr_table_do(object_set, j, dict, NULL);
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* conversions */
    
    apr_status_t md_json_pass_to(void *value, md_json_t *json, apr_pool_t *p, void *baton)
    {
        (void)p;
        (void)baton;
        return md_json_setj(value, json, NULL);
    }
    
    apr_status_t md_json_pass_from(void **pvalue, md_json_t *json, apr_pool_t *p, void *baton)
    {
        (void)p;
        (void)baton;
        *pvalue = json;
        return APR_SUCCESS;
    }
    
    apr_status_t md_json_clone_to(void *value, md_json_t *json, apr_pool_t *p, void *baton)
    {
        (void)baton;
        return md_json_setj(md_json_clone(p, value), json, NULL);
    }
    
    apr_status_t md_json_clone_from(void **pvalue, const md_json_t *json, apr_pool_t *p, void *baton)
    {
        (void)baton;
        *pvalue = md_json_clone(p, json);
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* array generic */
    
    apr_status_t md_json_geta(apr_array_header_t *a, md_json_from_cb *cb, void *baton,
                              const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        apr_status_t rv = APR_SUCCESS;
        size_t index;
        json_t *val;
        md_json_t wrap;
        void *element;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (!j || !json_is_array(j)) {
            return APR_ENOENT;
        }
            
        wrap.p = a->pool;
        json_array_foreach(j, index, val) {
            wrap.j = val;
            if (APR_SUCCESS == (rv = cb(&element, &wrap, wrap.p, baton))) {
                if (element) {
                    APR_ARRAY_PUSH(a, void*) = element;
                }
            }
            else if (APR_ENOENT == rv) {
                rv = APR_SUCCESS;
            }
            else {
                break;
            }
        }
        return rv;
    }
    
    apr_status_t md_json_seta(apr_array_header_t *a, md_json_to_cb *cb, void *baton, 
                              md_json_t *json, ...)
    {
        json_t *j, *nj;
        md_json_t wrap;
        apr_status_t rv = APR_SUCCESS;
        va_list ap;
        int i;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (!j || !json_is_array(j)) {
            const char *key;
            
            va_start(ap, json);
            j = jselect_parent(&key, 1, json, ap);
            va_end(ap);
            
            if (!key || !j || !json_is_object(j)) {
                return APR_EINVAL;
            }
            nj = json_array();
            json_object_set_new(j, key, nj);
            j = nj; 
        }
        
        json_array_clear(j);
        wrap.p = json->p;
        for (i = 0; i < a->nelts; ++i) {
            if (!cb) {
                return APR_EINVAL;
            }    
            wrap.j = json_string("");
            if (APR_SUCCESS == (rv = cb(APR_ARRAY_IDX(a, i, void*), &wrap, json->p, baton))) {
                json_array_append_new(j, wrap.j);
            }
        }
        return rv;
    }
    
    int md_json_itera(md_json_itera_cb *cb, void *baton, md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        size_t index;
        json_t *val;
        md_json_t wrap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (!j || !json_is_array(j)) {
            return 0;
        }
            
        wrap.p = json->p;
        json_array_foreach(j, index, val) {
            wrap.j = val;
            if (!cb(baton, index, &wrap)) {
                return 0;
            }
        }
        return 1;
    }
    
    int md_json_iterkey(md_json_iterkey_cb *cb, void *baton, md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        const char *key;
        json_t *val;
        md_json_t wrap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (!j || !json_is_object(j)) {
            return 0;
        }
            
        wrap.p = json->p;
        json_object_foreach(j, key, val) {
            wrap.j = val;
            if (!cb(baton, key, &wrap)) {
                return 0;
            }
        }
        return 1;
    }
    
    /**************************************************************************************************/
    /* array strings */
    
    apr_status_t md_json_getsa(apr_array_header_t *a, const md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        if (j && json_is_array(j)) {
            size_t index;
            json_t *val;
            
            json_array_foreach(j, index, val) {
                if (json_is_string(val)) {
                    APR_ARRAY_PUSH(a, const char *) = json_string_value(val);
                }
            }
            return APR_SUCCESS;
        }
        return APR_ENOENT;
    }
    
    apr_status_t md_json_dupsa(apr_array_header_t *a, apr_pool_t *p, md_json_t *json, ...)
    {
        json_t *j;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
    
        if (j && json_is_array(j)) {
            size_t index;
            json_t *val;
            
            apr_array_clear(a);
            json_array_foreach(j, index, val) {
                if (json_is_string(val)) {
                    APR_ARRAY_PUSH(a, const char *) = apr_pstrdup(p, json_string_value(val));
                }
            }
            return APR_SUCCESS;
        }
        return APR_ENOENT;
    }
    
    apr_status_t md_json_setsa(apr_array_header_t *a, md_json_t *json, ...)
    {
        json_t *nj, *j;
        va_list ap;
        int i;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        if (!j || !json_is_array(j)) {
            const char *key;
            
            va_start(ap, json);
            j = jselect_parent(&key, 1, json, ap);
            va_end(ap);
            
            if (!key || !j || !json_is_object(j)) {
                return APR_EINVAL;
            }
            nj = json_array();
            json_object_set_new(j, key, nj);
            j = nj; 
        }
        
        json_array_clear(j);
        for (i = 0; i < a->nelts; ++i) {
            json_array_append_new(j, json_string(APR_ARRAY_IDX(a, i, const char*)));
        }
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* formatting, parsing */
    
    typedef struct {
        const md_json_t *json;
        md_json_fmt_t fmt;
        const char *fname;
        apr_file_t *f;
    } j_write_ctx;
    
    /* Convert from md_json_fmt_t to the Jansson json_dumpX flags. */
    static size_t fmt_to_flags(md_json_fmt_t fmt)
    {
        /* NOTE: JSON_PRESERVE_ORDER is off by default before Jansson 2.8. It
         * doesn't have any semantic effect on the protocol, but it does let the
         * md_json_writeX unit tests run deterministically. */
        return JSON_PRESERVE_ORDER |
               ((fmt == MD_JSON_FMT_COMPACT) ? JSON_COMPACT : JSON_INDENT(2)); 
    }
    
    static int dump_cb(const char *buffer, size_t len, void *baton)
    {
        apr_bucket_brigade *bb = baton;
        apr_status_t rv;
        
        rv = apr_brigade_write(bb, NULL, NULL, buffer, len);
        return (rv == APR_SUCCESS)? 0 : -1;
    }
    
    apr_status_t md_json_writeb(const md_json_t *json, md_json_fmt_t fmt, apr_bucket_brigade *bb)
    {
        int rv = json_dump_callback(json->j, dump_cb, bb, fmt_to_flags(fmt));
        return rv? APR_EGENERAL : APR_SUCCESS;
    }
    
    static int chunk_cb(const char *buffer, size_t len, void *baton)
    {
        apr_array_header_t *chunks = baton;
        char *chunk;
        
        if (len > 0) {
            chunk = apr_palloc(chunks->pool, len+1);
            memcpy(chunk, buffer, len);
            chunk[len] = '\0';
            APR_ARRAY_PUSH(chunks, const char*) = chunk;
        }
        return 0;
    }
    
    const char *md_json_writep(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt)
    {
        apr_array_header_t *chunks;
        int rv;
    
        chunks = apr_array_make(p, 10, sizeof(char *));
        rv = json_dump_callback(json->j, chunk_cb, chunks, fmt_to_flags(fmt));
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p,
                          "md_json_writep failed to dump JSON");
            return NULL;
        }
    
        switch (chunks->nelts) {
            case 0:
                return "";
            case 1:
                return APR_ARRAY_IDX(chunks, 0, const char*);
            default:
                return apr_array_pstrcat(p, chunks, 0);
        }
    }
    
    apr_status_t md_json_writef(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt, apr_file_t *f)
    {
        apr_status_t rv;
        const char *s;
        
        if ((s = md_json_writep(json, p, fmt))) {
            rv = apr_file_write_full(f, s, strlen(s), NULL);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, json->p, "md_json_writef: error writing file");
            }
        }
        else {
            rv = APR_EINVAL;
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, json->p, 
                          "md_json_writef: error dumping json (%s)", md_json_dump_state(json, p));
        }
        return rv;
    }
    
    apr_status_t md_json_fcreatex(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt, 
                                  const char *fpath, apr_fileperms_t perms)
    {
        apr_status_t rv;
        apr_file_t *f;
        
        rv = md_util_fcreatex(&f, fpath, perms, p);
        if (APR_SUCCESS == rv) {
            rv = md_json_writef(json, p, fmt, f);
            apr_file_close(f);
        }
        return rv;
    }
    
    static apr_status_t write_json(void *baton, apr_file_t *f, apr_pool_t *p)
    {
        j_write_ctx *ctx = baton;
        apr_status_t rv = md_json_writef(ctx->json, p, ctx->fmt, f);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "freplace json in %s", ctx->fname);
        }
        return rv;
    }
    
    apr_status_t md_json_freplace(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt, 
                                  const char *fpath, apr_fileperms_t perms)
    {
        j_write_ctx ctx;
        ctx.json = json;
        ctx.fmt = fmt;
        ctx.fname = fpath;
        return md_util_freplace(fpath, perms, p, write_json, &ctx);
    }
    
    apr_status_t md_json_readd(md_json_t **pjson, apr_pool_t *pool, const char *data, size_t data_len)
    {
        json_error_t error;
        json_t *j;
        
        j = json_loadb(data, data_len, 0, &error);
        if (!j) {
            return APR_EINVAL;
        }
        *pjson = json_create(pool, j);
        return APR_SUCCESS;
    }
    
    static size_t load_cb(void *data, size_t max_len, void *baton)
    {
        apr_bucket_brigade *body = baton;
        size_t blen, read_len = 0;
        const char *bdata;
        char *dest = data;
        apr_bucket *b;
        apr_status_t rv;
        
        while (body && !APR_BRIGADE_EMPTY(body) && max_len > 0) {
            b = APR_BRIGADE_FIRST(body);
            if (APR_BUCKET_IS_METADATA(b)) {
                if (APR_BUCKET_IS_EOS(b)) {
                    body = NULL;
                }
            }
            else {
                rv = apr_bucket_read(b, &bdata, &blen, APR_BLOCK_READ);
                if (rv == APR_SUCCESS) {
                    if (blen > max_len) {
                        apr_bucket_split(b, max_len);
                        blen = max_len;
                    }
                    memcpy(dest, bdata, blen);
                    read_len += blen;
                    max_len -= blen;
                    dest += blen;
                }
                else {
                    body = NULL;
                    if (!APR_STATUS_IS_EOF(rv)) {
                        /* everything beside EOF is an error */
                        read_len = (size_t)-1;
                    }
                }
            }
            APR_BUCKET_REMOVE(b);
            apr_bucket_delete(b);
        }
        
        return read_len;
    }
    
    apr_status_t md_json_readb(md_json_t **pjson, apr_pool_t *pool, apr_bucket_brigade *bb)
    {
        json_error_t error;
        json_t *j;
        
        j = json_load_callback(load_cb, bb, 0, &error);
        if (j) {
            *pjson = json_create(pool, j);
        } else {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, pool,
                          "failed to load JSON file: %s (line %d:%d)",
                          error.text, error.line, error.column);
        }
        return (j && *pjson) ? APR_SUCCESS : APR_EINVAL;
    }
    
    static size_t load_file_cb(void *data, size_t max_len, void *baton)
    {
        apr_file_t *f = baton;
        apr_size_t len = max_len;
        apr_status_t rv;
        
        rv = apr_file_read(f, data, &len);
        if (APR_SUCCESS == rv) {
            return len;
        }
        else if (APR_EOF == rv) {
            return 0;
        }
        return (size_t)-1;
    }
    
    apr_status_t md_json_readf(md_json_t **pjson, apr_pool_t *p, const char *fpath)
    {
        apr_file_t *f;
        json_t *j;
        apr_status_t rv;
        json_error_t error;
        
        rv = apr_file_open(&f, fpath, APR_FOPEN_READ, 0, p);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        j = json_load_callback(load_file_cb, f, 0, &error);
        if (j) {
            *pjson = json_create(p, j);
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p,
                          "failed to load JSON file %s: %s (line %d:%d)",
                          fpath, error.text, error.line, error.column);
        }
    
        apr_file_close(f);
        return (j && *pjson) ? APR_SUCCESS : APR_EINVAL;
    }
    
    /**************************************************************************************************/
    /* http get */
    
    apr_status_t md_json_read_http(md_json_t **pjson, apr_pool_t *pool, const md_http_response_t *res)
    {
        apr_status_t rv = APR_ENOENT;
        const char *ctype, *p;
    
        *pjson = NULL;
        if (!res->body) goto cleanup;
        ctype = md_util_parse_ct(res->req->pool, apr_table_get(res->headers, "content-type"));
        if (!ctype) goto cleanup;
        p = ctype + strlen(ctype) +1;
        if (!strcmp(p - sizeof("/json"), "/json")
            || !strcmp(p - sizeof("+json"), "+json")) {
            rv = md_json_readb(pjson, pool, res->body);
        }
    cleanup:
        return rv;
    }
    
    typedef struct {
        apr_status_t rv;
        apr_pool_t *pool;
        md_json_t *json;
    } resp_data;
    
    static apr_status_t json_resp_cb(const md_http_response_t *res, void *data)
    {
        resp_data *resp = data;
        return md_json_read_http(&resp->json, resp->pool, res);
    }
    
    apr_status_t md_json_http_get(md_json_t **pjson, apr_pool_t *pool,
                                  struct md_http_t *http, const char *url)
    {
        apr_status_t rv;
        resp_data resp;
        
        memset(&resp, 0, sizeof(resp));
        resp.pool = pool;
        
        rv = md_http_GET_perform(http, url, NULL, json_resp_cb, &resp);
        
        if (rv == APR_SUCCESS) {
            *pjson = resp.json;
            return resp.rv;
        }
        *pjson = NULL;
        return rv;
    }
    
    
    apr_status_t md_json_copy_to(md_json_t *dest, const md_json_t *src, ...)
    {
        json_t *j;
        va_list ap;
        apr_status_t rv = APR_SUCCESS;
        
        va_start(ap, src);
        j = jselect(src, ap);
        va_end(ap);
    
        if (j) {
            va_start(ap, src);
            rv = jselect_set(j, dest, ap);
            va_end(ap);
        }
        return rv;
    }
    
    const char *md_json_dump_state(const md_json_t *json, apr_pool_t *p)
    {
        if (!json) return "NULL";
        return apr_psprintf(p, "%s, refc=%ld", md_json_type_name(json), (long)json->j->refcount);
    }
    
    apr_status_t md_json_set_timeperiod(const md_timeperiod_t *tp, md_json_t *json, ...)
    {
        char ts[APR_RFC822_DATE_LEN];
        json_t *jn, *j;
        va_list ap;
        const char *key;
        apr_status_t rv;
        
        if (tp && tp->start && tp->end) {
            jn = json_object();
            apr_rfc822_date(ts, tp->start);
            json_object_set_new(jn, "from", json_string(ts));
            apr_rfc822_date(ts, tp->end);
            json_object_set_new(jn, "until", json_string(ts));
            
            va_start(ap, json);
            rv = jselect_set_new(jn, json, ap);
            va_end(ap);
            return rv;
        }
        else {
            va_start(ap, json);
            j = jselect_parent(&key, 0, json, ap);
            va_end(ap);
            
            if (key && j && json_is_object(j)) {
                json_object_del(j, key);
            }
            return APR_SUCCESS;
        }
    }
    
    apr_status_t md_json_get_timeperiod(md_timeperiod_t *tp, md_json_t *json, ...)
    {
        json_t *j, *jts;
        va_list ap;
        
        va_start(ap, json);
        j = jselect(json, ap);
        va_end(ap);
        
        memset(tp, 0, sizeof(*tp));
        if (!j) goto not_found;
        jts = json_object_get(j, "from");
        if (!jts || !json_is_string(jts)) goto not_found;
        tp->start = apr_date_parse_rfc(json_string_value(jts)); 
        jts = json_object_get(j, "until");
        if (!jts || !json_is_string(jts)) goto not_found;
        tp->end = apr_date_parse_rfc(json_string_value(jts)); 
        return APR_SUCCESS;
    not_found:
        return APR_ENOENT;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_jws.c��������������������������������������������������������������������0000664�0001751�0001751�00000011267�14147416411�016333� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_lib.h>
    #include <apr_strings.h>
    #include <apr_tables.h>
    #include <apr_buckets.h>
    
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_jws.h"
    #include "md_log.h"
    #include "md_util.h"
    
    apr_status_t md_jws_get_jwk(md_json_t **pjwk, apr_pool_t *p, struct md_pkey_t *pkey)
    {
        md_json_t *jwk;
    
        if (!pkey) return APR_EINVAL;
    
        jwk = md_json_create(p);
        md_json_sets(md_pkey_get_rsa_e64(pkey, p), jwk, "e", NULL);
        md_json_sets("RSA", jwk, "kty", NULL);
        md_json_sets(md_pkey_get_rsa_n64(pkey, p), jwk, "n", NULL);
        *pjwk = jwk;
        return APR_SUCCESS;
    }
    
    apr_status_t md_jws_sign(md_json_t **pmsg, apr_pool_t *p,
                             md_data_t *payload, md_json_t *prot_fields,
                             struct md_pkey_t *pkey, const char *key_id)
    {
        md_json_t *msg, *jprotected, *jwk;
        const char *prot64, *pay64, *sign64, *sign, *prot;
        md_data_t data;
        apr_status_t rv;
    
        msg = md_json_create(p);
        jprotected = md_json_clone(p, prot_fields);
        md_json_sets("RS256", jprotected, "alg", NULL);
        if (key_id) {
            md_json_sets(key_id, jprotected, "kid", NULL);
        }
        else {
            rv = md_jws_get_jwk(&jwk, p, pkey);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, "get jwk");
                goto cleanup;
            }
            md_json_setj(jwk, jprotected, "jwk", NULL);
        }
    
        prot = md_json_writep(jprotected, p, MD_JSON_FMT_COMPACT);
        if (!prot) {
            rv = APR_EINVAL;
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, "serialize protected");
            goto cleanup;
        }
    
        md_data_init(&data, prot, strlen(prot));
        prot64 = md_util_base64url_encode(&data, p);
        md_json_sets(prot64, msg, "protected", NULL);
    
        pay64 = md_util_base64url_encode(payload, p);
        md_json_sets(pay64, msg, "payload", NULL);
        sign = apr_psprintf(p, "%s.%s", prot64, pay64);
    
        rv = md_crypt_sign64(&sign64, pkey, p, sign, strlen(sign));
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, "jwk signed message");
            goto cleanup;
        }
        md_json_sets(sign64, msg, "signature", NULL);
    
    cleanup:
        *pmsg = (APR_SUCCESS == rv)? msg : NULL;
        return rv;
    }
    
    apr_status_t md_jws_pkey_thumb(const char **pthumb, apr_pool_t *p, struct md_pkey_t *pkey)
    {
        const char *e64, *n64, *s;
        md_data_t data;
        apr_status_t rv;
        
        e64 = md_pkey_get_rsa_e64(pkey, p);
        n64 = md_pkey_get_rsa_n64(pkey, p);
        if (!e64 || !n64) {
            return APR_EINVAL;
        }
    
        /* whitespace and order is relevant, since we hand out a digest of this */
        s = apr_psprintf(p, "{\"e\":\"%s\",\"kty\":\"RSA\",\"n\":\"%s\"}", e64, n64);
        md_data_init_str(&data, s);
        rv = md_crypt_sha256_digest64(pthumb, p, &data);
        return rv;
    }
    
    apr_status_t md_jws_hmac(md_json_t **pmsg, apr_pool_t *p,
                             md_data_t *payload, md_json_t *prot_fields,
                             const md_data_t *hmac_key)
    {
        md_json_t *msg, *jprotected;
        const char *prot64, *pay64, *mac64, *sign, *prot;
        md_data_t data;
        apr_status_t rv;
    
        msg = md_json_create(p);
        jprotected = md_json_clone(p, prot_fields);
        md_json_sets("HS256", jprotected, "alg", NULL);
        prot = md_json_writep(jprotected, p, MD_JSON_FMT_COMPACT);
        if (!prot) {
            rv = APR_EINVAL;
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, "serialize protected");
            goto cleanup;
        }
    
        md_data_init(&data, prot, strlen(prot));
        prot64 = md_util_base64url_encode(&data, p);
        md_json_sets(prot64, msg, "protected", NULL);
    
        pay64 = md_util_base64url_encode(payload, p);
        md_json_sets(pay64, msg, "payload", NULL);
        sign = apr_psprintf(p, "%s.%s", prot64, pay64);
    
        rv = md_crypt_hmac64(&mac64, hmac_key, p, sign, strlen(sign));
        if (APR_SUCCESS != rv) {
            goto cleanup;
        }
        md_json_sets(mac64, msg, "signature", NULL);
    
    cleanup:
        *pmsg = (APR_SUCCESS == rv)? msg : NULL;
        return rv;
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_core.c�������������������������������������������������������������������0000664�0001751�0001751�00000041254�14750656217�016471� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_uri.h>
    #include <apr_tables.h>
    #include <apr_time.h>
    #include <apr_date.h>
    
    #include "md_json.h"
    #include "md.h"
    #include "md_crypt.h"
    #include "md_log.h"
    #include "md_store.h"
    #include "md_util.h"
    
    
    int md_contains(const md_t *md, const char *domain, int case_sensitive)
    {
        if (md_array_str_index(md->domains, domain, 0, case_sensitive) >= 0) {
            return 1;
        }
        return md_dns_domains_match(md->domains, domain);
    }
    
    const char *md_common_name(const md_t *md1, const md_t *md2)
    {
        int i;
        
        if (md1 == NULL || md1->domains == NULL
            || md2 == NULL || md2->domains == NULL) {
            return NULL;
        }
        
        for (i = 0; i < md1->domains->nelts; ++i) {
            const char *name1 = APR_ARRAY_IDX(md1->domains, i, const char*);
            if (md_contains(md2, name1, 0)) {
                return name1;
            }
        }
        return NULL;
    }
    
    int md_domains_overlap(const md_t *md1, const md_t *md2)
    {
        return md_common_name(md1, md2) != NULL;
    }
    
    apr_size_t md_common_name_count(const md_t *md1, const md_t *md2)
    {
        int i;
        apr_size_t hits;
        
        if (md1 == NULL || md1->domains == NULL
            || md2 == NULL || md2->domains == NULL) {
            return 0;
        }
        
        hits = 0;
        for (i = 0; i < md1->domains->nelts; ++i) {
            const char *name1 = APR_ARRAY_IDX(md1->domains, i, const char*);
            if (md_contains(md2, name1, 0)) {
                ++hits;
            }
        }
        return hits;
    }
    
    int md_is_covered_by_alt_names(const md_t *md, const struct apr_array_header_t* alt_names)
    {
        const char *name;
        int i;
        
        if (alt_names) {
            for (i = 0; i < md->domains->nelts; ++i) {
                name = APR_ARRAY_IDX(md->domains, i, const char *);
                if (!md_dns_domains_match(alt_names, name)) {
                    return 0;
                }
            }
            return 1;
        }
        return 0;
    }
    
    md_t *md_create_empty(apr_pool_t *p)
    {
        md_t *md = apr_pcalloc(p, sizeof(*md));
        if (md) {
            md->domains = apr_array_make(p, 5, sizeof(const char *));
            md->contacts = apr_array_make(p, 5, sizeof(const char *));
            md->renew_mode = MD_RENEW_DEFAULT;
            md->require_https = MD_REQUIRE_UNSET;
            md->must_staple = -1;
            md->transitive = -1;
            md->acme_tls_1_domains = apr_array_make(p, 5, sizeof(const char *));
            md->stapling = -1;
            md->defn_name = "unknown";
            md->defn_line_number = 0;
        }
        return md;
    }
    
    int md_equal_domains(const md_t *md1, const md_t *md2, int case_sensitive)
    {
        int i;
        if (md1->domains->nelts == md2->domains->nelts) {
            for (i = 0; i < md1->domains->nelts; ++i) {
                const char *name1 = APR_ARRAY_IDX(md1->domains, i, const char*);
                if (!md_contains(md2, name1, case_sensitive)) {
                    return 0;
                }
            }
            return 1;
        }
        return 0;
    }
    
    int md_contains_domains(const md_t *md1, const md_t *md2)
    {
        int i;
        if (md1->domains->nelts >= md2->domains->nelts) {
            for (i = 0; i < md2->domains->nelts; ++i) {
                const char *name2 = APR_ARRAY_IDX(md2->domains, i, const char*);
                if (!md_contains(md1, name2, 0)) {
                    return 0;
                }
            }
            return 1;
        }
        return 0;
    }
    
    md_t *md_get_by_name(struct apr_array_header_t *mds, const char *name)
    {
        int i;
        for (i = 0; i < mds->nelts; ++i) {
            md_t *md = APR_ARRAY_IDX(mds, i, md_t *);
            if (!strcmp(name, md->name)) {
                return md;
            }
        }
        return NULL;
    }
    
    md_t *md_get_by_domain(struct apr_array_header_t *mds, const char *domain)
    {
        int i;
        for (i = 0; i < mds->nelts; ++i) {
            md_t *md = APR_ARRAY_IDX(mds, i, md_t *);
            if (md_contains(md, domain, 0)) {
                return md;
            }
        }
        return NULL;
    }
    
    md_t *md_get_by_dns_overlap(struct apr_array_header_t *mds, const md_t *md)
    {
        int i;
        for (i = 0; i < mds->nelts; ++i) {
            md_t *o = APR_ARRAY_IDX(mds, i, md_t *);
            if (strcmp(o->name, md->name) && md_common_name(o, md)) {
                return o;
            }
        }
        return NULL;
    }
    
    int md_cert_count(const md_t *md)
    {
        /* cert are defined as a list of static files or a list of private key specs */
        if (md->cert_files && md->cert_files->nelts) {
            return md->cert_files->nelts;
        }
        return md_pkeys_spec_count(md->pks);
    }
    
    md_t *md_create(apr_pool_t *p, apr_array_header_t *domains)
    {
        md_t *md;
        
        md = md_create_empty(p);
        md->domains = md_array_str_compact(p, domains, 0);
        md->name = APR_ARRAY_IDX(md->domains, 0, const char *);
        
        return md;
    }
    
    /**************************************************************************************************/
    /* lifetime */
    
    md_t *md_copy(apr_pool_t *p, const md_t *src)
    {
        md_t *md;
        
        md = apr_pcalloc(p, sizeof(*md));
        if (md) {
            memcpy(md, src, sizeof(*md));
            md->domains = apr_array_copy(p, src->domains);
            md->contacts = apr_array_copy(p, src->contacts);
            if (src->ca_challenges) {
                md->ca_challenges = apr_array_copy(p, src->ca_challenges);
            }
            md->acme_tls_1_domains = apr_array_copy(p, src->acme_tls_1_domains);
            md->pks = md_pkeys_spec_clone(p, src->pks);
        }    
        return md;   
    }
    
    md_t *md_clone(apr_pool_t *p, const md_t *src)
    {
        md_t *md;
        
        md = apr_pcalloc(p, sizeof(*md));
        if (md) {
            md->state = src->state;
            md->name = apr_pstrdup(p, src->name);
            md->require_https = src->require_https;
            md->must_staple = src->must_staple;
            md->renew_mode = src->renew_mode;
            md->domains = md_array_str_compact(p, src->domains, 0);
            md->pks = md_pkeys_spec_clone(p, src->pks);
            md->renew_window = src->renew_window;
            md->warn_window = src->warn_window;
            md->contacts = md_array_str_clone(p, src->contacts);
            if (src->ca_proto) md->ca_proto = apr_pstrdup(p, src->ca_proto);
            if (src->ca_urls) {
                md->ca_urls = md_array_str_clone(p, src->ca_urls);
            }
            if (src->ca_effective) md->ca_effective = apr_pstrdup(p, src->ca_effective);
            if (src->ca_account) md->ca_account = apr_pstrdup(p, src->ca_account);
            if (src->ca_agreement) md->ca_agreement = apr_pstrdup(p, src->ca_agreement);
            if (src->defn_name) md->defn_name = apr_pstrdup(p, src->defn_name);
            md->defn_line_number = src->defn_line_number;
            if (src->ca_challenges) {
                md->ca_challenges = md_array_str_clone(p, src->ca_challenges);
            }
            md->acme_tls_1_domains = md_array_str_compact(p, src->acme_tls_1_domains, 0);
            md->stapling = src->stapling;
            if (src->dns01_cmd) md->dns01_cmd = apr_pstrdup(p, src->dns01_cmd);
            if (src->cert_files) md->cert_files = md_array_str_clone(p, src->cert_files);
            if (src->pkey_files) md->pkey_files = md_array_str_clone(p, src->pkey_files);
        }    
        return md;   
    }
    
    /**************************************************************************************************/
    /* format conversion */
    
    md_json_t *md_to_json(const md_t *md, apr_pool_t *p)
    {
        md_json_t *json = md_json_create(p);
        if (json) {
            apr_array_header_t *domains = md_array_str_compact(p, md->domains, 0);
            md_json_sets(md->name, json, MD_KEY_NAME, NULL);
            md_json_setsa(domains, json, MD_KEY_DOMAINS, NULL);
            md_json_setsa(md->contacts, json, MD_KEY_CONTACTS, NULL);
            md_json_setl(md->transitive, json, MD_KEY_TRANSITIVE, NULL);
            md_json_sets(md->ca_account, json, MD_KEY_CA, MD_KEY_ACCOUNT, NULL);
            md_json_sets(md->ca_proto, json, MD_KEY_CA, MD_KEY_PROTO, NULL);
            md_json_sets(md->ca_effective, json, MD_KEY_CA, MD_KEY_URL, NULL);
            if (md->ca_urls && !apr_is_empty_array(md->ca_urls)) {
                md_json_setsa(md->ca_urls, json, MD_KEY_CA, MD_KEY_URLS, NULL);
            }
            md_json_sets(md->ca_agreement, json, MD_KEY_CA, MD_KEY_AGREEMENT, NULL);
            if (!md_pkeys_spec_is_empty(md->pks)) {
                md_json_setj(md_pkeys_spec_to_json(md->pks, p), json, MD_KEY_PKEY, NULL);
            }
            md_json_setl(md->state, json, MD_KEY_STATE, NULL);
            if (md->state_descr)
                md_json_sets(md->state_descr, json, MD_KEY_STATE_DESCR, NULL);
            md_json_setl(md->renew_mode, json, MD_KEY_RENEW_MODE, NULL);
            if (md->renew_window)
                md_json_sets(md_timeslice_format(md->renew_window, p), json, MD_KEY_RENEW_WINDOW, NULL);
            if (md->warn_window)
                md_json_sets(md_timeslice_format(md->warn_window, p), json, MD_KEY_WARN_WINDOW, NULL);
            if (md->ca_challenges && md->ca_challenges->nelts > 0) {
                apr_array_header_t *na;
                na = md_array_str_compact(p, md->ca_challenges, 0);
                md_json_setsa(na, json, MD_KEY_CA, MD_KEY_CHALLENGES, NULL);
            }
            switch (md->require_https) {
                case MD_REQUIRE_TEMPORARY:
                    md_json_sets(MD_KEY_TEMPORARY, json, MD_KEY_REQUIRE_HTTPS, NULL);
                    break;
                case MD_REQUIRE_PERMANENT:
                    md_json_sets(MD_KEY_PERMANENT, json, MD_KEY_REQUIRE_HTTPS, NULL);
                    break;
                default:
                    break;
            }
            md_json_setb(md->must_staple > 0, json, MD_KEY_MUST_STAPLE, NULL);
            md_json_setsa(md->acme_tls_1_domains, json, MD_KEY_PROTO, MD_KEY_ACME_TLS_1, NULL);
            if (md->cert_files) md_json_setsa(md->cert_files, json, MD_KEY_CERT_FILES, NULL);
            if (md->pkey_files) md_json_setsa(md->pkey_files, json, MD_KEY_PKEY_FILES, NULL);
            md_json_setb(md->stapling > 0, json, MD_KEY_STAPLING, NULL);
            if (md->dns01_cmd) md_json_sets(md->dns01_cmd, json, MD_KEY_CMD_DNS01, NULL);
            if (md->ca_eab_kid && strcmp("none", md->ca_eab_kid)) {
                md_json_sets(md->ca_eab_kid, json, MD_KEY_EAB, MD_KEY_KID, NULL);
                if (md->ca_eab_hmac) md_json_sets(md->ca_eab_hmac, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
            }
            if (md->profile) md_json_sets(md->profile, json, MD_KEY_PROFILE, NULL);
            md_json_setb(md->profile_mandatory > 0, json, MD_KEY_PROFILE_MANDATORY, NULL);
            return json;
        }
        return NULL;
    }
    
    md_t *md_from_json(md_json_t *json, apr_pool_t *p)
    {
        const char *s;
        md_t *md = md_create_empty(p);
        if (md) {
            md->name = md_json_dups(p, json, MD_KEY_NAME, NULL);            
            md_json_dupsa(md->domains, p, json, MD_KEY_DOMAINS, NULL);
            md_json_dupsa(md->contacts, p, json, MD_KEY_CONTACTS, NULL);
            md->ca_account = md_json_dups(p, json, MD_KEY_CA, MD_KEY_ACCOUNT, NULL);
            md->ca_proto = md_json_dups(p, json, MD_KEY_CA, MD_KEY_PROTO, NULL);
            md->ca_effective = md_json_dups(p, json, MD_KEY_CA, MD_KEY_URL, NULL);
            if (md_json_has_key(json, MD_KEY_CA, MD_KEY_URLS, NULL)) {
                md->ca_urls = apr_array_make(p, 5, sizeof(const char*));
                md_json_dupsa(md->ca_urls, p, json, MD_KEY_CA, MD_KEY_URLS, NULL);
            }
            else if (md->ca_effective) {
                /* compat for old format where we had only a single url */
                md->ca_urls = apr_array_make(p, 5, sizeof(const char*));
                APR_ARRAY_PUSH(md->ca_urls, const char*) = md->ca_effective;
            }
            md->ca_agreement = md_json_dups(p, json, MD_KEY_CA, MD_KEY_AGREEMENT, NULL);
            if (md_json_has_key(json, MD_KEY_PKEY, NULL)) {
                md->pks = md_pkeys_spec_from_json(md_json_getj(json, MD_KEY_PKEY, NULL), p);
            }
            md->state = (md_state_t)md_json_getl(json, MD_KEY_STATE, NULL);
            md->state_descr = md_json_dups(p, json, MD_KEY_STATE_DESCR, NULL);
            if (MD_S_EXPIRED_DEPRECATED == md->state) md->state = MD_S_COMPLETE;
            md->renew_mode = (int)md_json_getl(json, MD_KEY_RENEW_MODE, NULL);
            md->domains = md_array_str_compact(p, md->domains, 0);
            md->transitive = (int)md_json_getl(json, MD_KEY_TRANSITIVE, NULL);
            s = md_json_gets(json, MD_KEY_RENEW_WINDOW, NULL);
            md_timeslice_parse(&md->renew_window, p, s, MD_TIME_LIFE_NORM);
            s = md_json_gets(json, MD_KEY_WARN_WINDOW, NULL);
            md_timeslice_parse(&md->warn_window, p, s, MD_TIME_LIFE_NORM);
            if (md_json_has_key(json, MD_KEY_CA, MD_KEY_CHALLENGES, NULL)) {
                md->ca_challenges = apr_array_make(p, 5, sizeof(const char*));
                md_json_dupsa(md->ca_challenges, p, json, MD_KEY_CA, MD_KEY_CHALLENGES, NULL);
            }
            md->require_https = MD_REQUIRE_OFF;
            s = md_json_gets(json, MD_KEY_REQUIRE_HTTPS, NULL);
            if (s && !strcmp(MD_KEY_TEMPORARY, s)) {
                md->require_https = MD_REQUIRE_TEMPORARY;
            }
            else if (s && !strcmp(MD_KEY_PERMANENT, s)) {
                md->require_https = MD_REQUIRE_PERMANENT;
            }
            md->must_staple = (int)md_json_getb(json, MD_KEY_MUST_STAPLE, NULL);
            md_json_dupsa(md->acme_tls_1_domains, p, json, MD_KEY_PROTO, MD_KEY_ACME_TLS_1, NULL);
                
            if (md_json_has_key(json, MD_KEY_CERT_FILES, NULL)) {
                md->cert_files = apr_array_make(p, 3, sizeof(char*));
                md->pkey_files = apr_array_make(p, 3, sizeof(char*));
                md_json_dupsa(md->cert_files, p, json, MD_KEY_CERT_FILES, NULL);
                md_json_dupsa(md->pkey_files, p, json, MD_KEY_PKEY_FILES, NULL);
            }
            md->stapling = (int)md_json_getb(json, MD_KEY_STAPLING, NULL);
            md->dns01_cmd = md_json_dups(p, json, MD_KEY_CMD_DNS01, NULL);
            if (md_json_has_key(json, MD_KEY_EAB, NULL)) {
                md->ca_eab_kid = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_KID, NULL);
                md->ca_eab_hmac = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
            }
    
            md->profile_mandatory = (int)md_json_getb(json, MD_KEY_PROFILE_MANDATORY, NULL);
            if (md_json_has_key(json, MD_KEY_PROFILE, NULL))
                md->profile = md_json_dups(p, json, MD_KEY_PROFILE, NULL);
            return md;
        }
        return NULL;
    }
    
    md_json_t *md_to_public_json(const md_t *md, apr_pool_t *p)
    {
        md_json_t *json = md_to_json(md, p);
        if (md_json_has_key(json, MD_KEY_EAB, MD_KEY_HMAC, NULL)) {
            md_json_sets("***", json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
        }
        return json;
    }
    
    typedef struct {
        const char *name;
        const char *url;
    } md_ca_t;
    
    #define LE_ACMEv2_PROD      "https://acme-v02.api.letsencrypt.org/directory"
    #define LE_ACMEv2_STAGING   "https://acme-staging-v02.api.letsencrypt.org/directory"
    #define BUYPASS_ACME        "https://api.buypass.com/acme/directory"
    #define BUYPASS_ACME_TEST   "https://api.test4.buypass.no/acme/directory"
    
    static md_ca_t KNOWN_CAs[] = {
        { "LetsEncrypt", LE_ACMEv2_PROD },
        { "LetsEncrypt-Test", LE_ACMEv2_STAGING },
        { "Buypass", BUYPASS_ACME },
        { "Buypass-Test", BUYPASS_ACME_TEST },
    };
    
    const char *md_get_ca_name_from_url(apr_pool_t *p, const char *url)
    {
        apr_uri_t uri_parsed;
        unsigned int i;
    
        for (i = 0; i < sizeof(KNOWN_CAs)/sizeof(KNOWN_CAs[0]); ++i) {
            if (!apr_strnatcasecmp(KNOWN_CAs[i].url, url)) {
                return KNOWN_CAs[i].name;
            }
        }
        if (APR_SUCCESS == apr_uri_parse(p, url, &uri_parsed)) {
            return uri_parsed.hostname;
        }
        return apr_pstrdup(p, url);
    }
    
    apr_status_t md_get_ca_url_from_name(const char **purl, apr_pool_t *p, const char *name)
    {
        const char *err;
        unsigned int i;
        apr_status_t rv = APR_SUCCESS;
    
        *purl = NULL;
        for (i = 0; i < sizeof(KNOWN_CAs)/sizeof(KNOWN_CAs[0]); ++i) {
            if (!apr_strnatcasecmp(KNOWN_CAs[i].name, name)) {
                *purl = KNOWN_CAs[i].url;
                goto leave;
            }
        }
        *purl = name;
        rv = md_util_abs_uri_check(p, name, &err);
        if (APR_SUCCESS != rv) {
            apr_array_header_t *names;
    
            names = apr_array_make(p, 10, sizeof(const char*));
            for (i = 0; i < sizeof(KNOWN_CAs)/sizeof(KNOWN_CAs[0]); ++i) {
                APR_ARRAY_PUSH(names, const char *) = KNOWN_CAs[i].name;
            }
            *purl = apr_psprintf(p,
                "The CA name '%s' is not known and it is not a URL either (%s). "
                "Known CA names are: %s.",
                name, err, apr_array_pstrcat(p, names, ' '));
        }
    leave:
        return rv;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_store_fs.c���������������������������������������������������������������0000664�0001751�0001751�00000122100�14750656217�017353� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_file_info.h>
    #include <apr_file_io.h>
    #include <apr_fnmatch.h>
    #include <apr_hash.h>
    #include <apr_strings.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_log.h"
    #include "md_store.h"
    #include "md_store_fs.h"
    #include "md_util.h"
    #include "md_version.h"
    
    /**************************************************************************************************/
    /* file system based implementation of md_store_t */
    
    #define MD_STORE_VERSION        3
    #define MD_FS_LOCK_NAME         "store.lock"
    
    typedef struct {
        apr_fileperms_t dir;
        apr_fileperms_t file;
    } perms_t;
    
    typedef struct md_store_fs_t md_store_fs_t;
    struct md_store_fs_t {
        md_store_t s;
        
        const char *base;       /* base directory of store */
        perms_t def_perms;
        perms_t group_perms[MD_SG_COUNT];
        md_store_fs_cb *event_cb;
        void *event_baton;
        
        md_data_t key;
        int plain_pkey[MD_SG_COUNT];
        
        int port_80;
        int port_443;
    
        apr_file_t *global_lock;
    };
    
    #define FS_STORE(store)     (md_store_fs_t*)(((char*)store)-offsetof(md_store_fs_t, s))
    #define FS_STORE_JSON       "md_store.json"
    #define FS_STORE_KLEN       48
    
    static apr_status_t fs_load(md_store_t *store, md_store_group_t group, 
                                const char *name, const char *aspect,  
                                md_store_vtype_t vtype, void **pvalue, apr_pool_t *p);
    static apr_status_t fs_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                const char *name, const char *aspect,  
                                md_store_vtype_t vtype, void *value, int create);
    static apr_status_t fs_remove(md_store_t *store, md_store_group_t group, 
                                  const char *name, const char *aspect, 
                                  apr_pool_t *p, int force);
    static apr_status_t fs_purge(md_store_t *store, apr_pool_t *p, 
                                 md_store_group_t group, const char *name);
    static apr_status_t fs_remove_nms(md_store_t *store, apr_pool_t *p, 
                                      apr_time_t modified, md_store_group_t group, 
                                      const char *name, const char *aspect);
    static apr_status_t fs_move(md_store_t *store, apr_pool_t *p, 
                                md_store_group_t from, md_store_group_t to, 
                                const char *name, int archive);
    static apr_status_t fs_rename(md_store_t *store, apr_pool_t *p, 
                                md_store_group_t group, const char *from, const char *to);
    static apr_status_t fs_iterate(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                   apr_pool_t *p, md_store_group_t group,  const char *pattern,
                                   const char *aspect, md_store_vtype_t vtype);
    static apr_status_t fs_iterate_names(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                         apr_pool_t *p, md_store_group_t group, const char *pattern);
    
    static apr_status_t fs_get_fname(const char **pfname, 
                                     md_store_t *store, md_store_group_t group, 
                                     const char *name, const char *aspect, 
                                     apr_pool_t *p);
    static int fs_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
                           const char *name, const char *aspect, apr_pool_t *p);
    
    static apr_time_t fs_get_modified(md_store_t *store, md_store_group_t group,  
                                      const char *name, const char *aspect, apr_pool_t *p);
    
    static apr_status_t fs_lock_global(md_store_t *store, apr_pool_t *p, apr_time_t max_wait);
    static void fs_unlock_global(md_store_t *store, apr_pool_t *p);
    
    static apr_status_t init_store_file(md_store_fs_t *s_fs, const char *fname, 
                                        apr_pool_t *p, apr_pool_t *ptemp)
    {
        md_json_t *json = md_json_create(p);
        const char *key64;
        apr_status_t rv;
        
        md_json_setn(MD_STORE_VERSION, json, MD_KEY_STORE, MD_KEY_VERSION, NULL);
    
        md_data_pinit(&s_fs->key, FS_STORE_KLEN, p);
        if (APR_SUCCESS != (rv = md_rand_bytes((unsigned char*)s_fs->key.data, s_fs->key.len, p))) {
            return rv;
        }
            
        key64 = md_util_base64url_encode(&s_fs->key, ptemp);
        md_json_sets(key64, json, MD_KEY_KEY, NULL);
        rv = md_json_fcreatex(json, ptemp, MD_JSON_FMT_INDENT, fname, MD_FPROT_F_UONLY);
        memset((char*)key64, 0, strlen(key64));
    
        return rv;
    }
    
    static apr_status_t rename_pkey(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                                    const char *dir, const char *name, 
                                    apr_filetype_e ftype)
    {
        const char *from, *to;
        apr_status_t rv = APR_SUCCESS;
        
        (void)baton;
        (void)ftype;
        if (   MD_OK(md_util_path_merge(&from, ptemp, dir, name, NULL))
            && MD_OK(md_util_path_merge(&to, ptemp, dir, MD_FN_PRIVKEY, NULL))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p, "renaming %s/%s to %s", 
                          dir, name, MD_FN_PRIVKEY);
            return apr_file_rename(from, to, ptemp);
        }
        return rv;
    }
    
    static apr_status_t mk_pubcert(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                                   const char *dir, const char *name, 
                                   apr_filetype_e ftype)
    {
        md_cert_t *cert;
        apr_array_header_t *chain, *pubcert;
        const char *fname, *fpubcert;
        apr_status_t rv = APR_SUCCESS;
        
        (void)baton;
        (void)ftype;
        (void)p;
        if (   MD_OK(md_util_path_merge(&fpubcert, ptemp, dir, MD_FN_PUBCERT, NULL))
            && APR_STATUS_IS_ENOENT(rv = md_chain_fload(&pubcert, ptemp, fpubcert))
            && MD_OK(md_util_path_merge(&fname, ptemp, dir, name, NULL))
            && MD_OK(md_cert_fload(&cert, ptemp, fname))
            && MD_OK(md_util_path_merge(&fname, ptemp, dir, "chain.pem", NULL))) {
            
            rv = md_chain_fload(&chain, ptemp, fname);
            if (APR_STATUS_IS_ENOENT(rv)) {
                chain = apr_array_make(ptemp, 1, sizeof(md_cert_t*));
                rv = APR_SUCCESS;
            }
            if (APR_SUCCESS == rv) {
                pubcert = apr_array_make(ptemp, chain->nelts + 1, sizeof(md_cert_t*));
                APR_ARRAY_PUSH(pubcert, md_cert_t *) = cert;
                apr_array_cat(pubcert, chain);
                rv = md_chain_fsave(pubcert, ptemp, fpubcert, MD_FPROT_F_UONLY);
            }
        }
        return rv;
    }
    
    static apr_status_t upgrade_from_1_0(md_store_fs_t *s_fs, apr_pool_t *p, apr_pool_t *ptemp)
    {
        md_store_group_t g;
        apr_status_t rv = APR_SUCCESS;
        
        (void)ptemp;
        /* Migrate pkey.pem -> privkey.pem */
        for (g = MD_SG_NONE; g < MD_SG_COUNT && APR_SUCCESS == rv; ++g) {
            rv = md_util_files_do(rename_pkey, s_fs, p, s_fs->base, 
                                  md_store_group_name(g), "*", "pkey.pem", NULL);
        }
        /* Generate fullcert.pem from cert.pem and chain.pem where missing */
        rv = md_util_files_do(mk_pubcert, s_fs, p, s_fs->base, 
                              md_store_group_name(MD_SG_DOMAINS), "*", MD_FN_CERT, NULL);
        rv = md_util_files_do(mk_pubcert, s_fs, p, s_fs->base, 
                              md_store_group_name(MD_SG_ARCHIVE), "*", MD_FN_CERT, NULL);
        
        return rv;
    }
    
    static apr_status_t read_store_file(md_store_fs_t *s_fs, const char *fname, 
                                        apr_pool_t *p, apr_pool_t *ptemp)
    {
        md_json_t *json;
        const char *key64;
        apr_status_t rv;
        double store_version;
        
        if (MD_OK(md_json_readf(&json, p, fname))) {
            store_version = md_json_getn(json, MD_KEY_STORE, MD_KEY_VERSION, NULL);
            if (store_version <= 0.0) {
                /* ok, an old one, compatible to 1.0 */
                store_version = 1.0;
            }
            if (store_version > MD_STORE_VERSION) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "version too new: %f", store_version);
                return APR_EINVAL;
            }
    
            key64 = md_json_dups(p, json, MD_KEY_KEY, NULL);
            if (!key64) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "missing key: %s", MD_KEY_KEY);
                return APR_EINVAL;
            }
            
            md_util_base64url_decode(&s_fs->key, key64, p);
            if (s_fs->key.len != FS_STORE_KLEN) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "key length unexpected: %" APR_SIZE_T_FMT, 
                              s_fs->key.len);
                return APR_EINVAL;
            }
    
            /* Need to migrate format? */
            if (store_version < MD_STORE_VERSION) {
                if (store_version <= 1.0) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "migrating store v1 -> v2");
                    rv = upgrade_from_1_0(s_fs, p, ptemp);
                }
                if (store_version <= 2.0) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "migrating store v2 -> v3");
                    md_json_del(json, MD_KEY_VERSION, NULL);
                }
                
                if (APR_SUCCESS == rv) {
                    md_json_setn(MD_STORE_VERSION, json, MD_KEY_STORE, MD_KEY_VERSION, NULL);
                    rv = md_json_freplace(json, ptemp, MD_JSON_FMT_INDENT, fname, MD_FPROT_F_UONLY);
                }
                md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, p, "migrated store");
            } 
        }
        return rv;
    }
    
    static apr_status_t setup_store_file(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *fname;
        apr_status_t rv;
    
        (void)ap;
        s_fs->plain_pkey[MD_SG_DOMAINS] = 1;
        /* Added: the encryption of tls-alpn-01 certificate keys is not a security issue
         * for these self-signed, short-lived certificates. Having them unencrypted let's
         * use pass around the files insteak of an *SSL implementation dependent PKEY_something.
         */
        s_fs->plain_pkey[MD_SG_CHALLENGES] = 1;
        s_fs->plain_pkey[MD_SG_TMP] = 1;
        
        if (!MD_OK(md_util_path_merge(&fname, ptemp, s_fs->base, FS_STORE_JSON, NULL))) {
            return rv;
        }
        
    read:
        if (MD_OK(md_util_is_file(fname, ptemp))) {
            rv = read_store_file(s_fs, fname, p, ptemp);
            if (rv != APR_SUCCESS) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p,
                "The central store file md/md_store.json seems to exist, but "
                "its content are not readable as JSON. Either it got somehow corrupted "
                "or the store directory was configured for a location with a foreign "
                "md_store.json file. Either way, it is unclear how to proceeed. "
                "You should either restore the correct file/location or clean the directory "
                "so it gets initialized again.");
            }
        }
        else if (APR_STATUS_IS_ENOENT(rv)
            && APR_STATUS_IS_EEXIST(rv = init_store_file(s_fs, fname, p, ptemp))) {
            goto read;
        }
        return rv;
    }
    
    apr_status_t md_store_fs_init(md_store_t **pstore, apr_pool_t *p, const char *path)
    {
        md_store_fs_t *s_fs;
        apr_status_t rv = APR_SUCCESS;
        
        s_fs = apr_pcalloc(p, sizeof(*s_fs));
    
        s_fs->s.load = fs_load;
        s_fs->s.save = fs_save;
        s_fs->s.remove = fs_remove;
        s_fs->s.move = fs_move;
        s_fs->s.rename = fs_rename;
        s_fs->s.purge = fs_purge;
        s_fs->s.iterate = fs_iterate;
        s_fs->s.iterate_names = fs_iterate_names;
        s_fs->s.get_fname = fs_get_fname;
        s_fs->s.is_newer = fs_is_newer;
        s_fs->s.get_modified = fs_get_modified;
        s_fs->s.remove_nms = fs_remove_nms;
        s_fs->s.lock_global = fs_lock_global;
        s_fs->s.unlock_global = fs_unlock_global;
    
        /* by default, everything is only readable by the current user */ 
        s_fs->def_perms.dir = MD_FPROT_D_UONLY;
        s_fs->def_perms.file = MD_FPROT_F_UONLY;
    
        /* Account information needs to be accessible to httpd child processes.
         * private keys are, similar to staging, encrypted. */
        s_fs->group_perms[MD_SG_ACCOUNTS].dir = MD_FPROT_D_UALL_WREAD;
        s_fs->group_perms[MD_SG_ACCOUNTS].file = MD_FPROT_F_UALL_WREAD;
        s_fs->group_perms[MD_SG_STAGING].dir = MD_FPROT_D_UALL_WREAD;
        s_fs->group_perms[MD_SG_STAGING].file = MD_FPROT_F_UALL_WREAD;
        /* challenges dir and files are readable by all, no secrets involved */ 
        s_fs->group_perms[MD_SG_CHALLENGES].dir = MD_FPROT_D_UALL_WREAD;
        s_fs->group_perms[MD_SG_CHALLENGES].file = MD_FPROT_F_UALL_WREAD;
        /* OCSP data is readable by all, no secrets involved */ 
        s_fs->group_perms[MD_SG_OCSP].dir = MD_FPROT_D_UALL_WREAD;
        s_fs->group_perms[MD_SG_OCSP].file = MD_FPROT_F_UALL_WREAD;
    
        s_fs->base = apr_pstrdup(p, path);
    
        rv = md_util_is_dir(s_fs->base, p);
        if (APR_STATUS_IS_ENOENT(rv)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, p,
                "store directory does not exist, creating %s", s_fs->base);
            rv = apr_dir_make_recursive(s_fs->base, s_fs->def_perms.dir, p);
            if (APR_SUCCESS != rv) goto cleanup;
            rv = apr_file_perms_set(s_fs->base, MD_FPROT_D_UALL_WREAD);
            if (APR_STATUS_IS_ENOTIMPL(rv)) {
                rv = APR_SUCCESS;
            }
            if (APR_SUCCESS != rv) goto cleanup;
        }
        else if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
                "not a plain directory, maybe a symlink? %s", s_fs->base);
        }
    
        rv = md_util_pool_vdo(setup_store_file, s_fs, p, NULL);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "init fs store at %s", s_fs->base);
        }
    cleanup:
        *pstore = (rv == APR_SUCCESS)? &(s_fs->s) : NULL;
        return rv;
    }
    
    apr_status_t md_store_fs_default_perms_set(md_store_t *store, 
                                               apr_fileperms_t file_perms,
                                               apr_fileperms_t dir_perms)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        
        s_fs->def_perms.file = file_perms;
        s_fs->def_perms.dir = dir_perms;
        return APR_SUCCESS;
    }
    
    apr_status_t md_store_fs_group_perms_set(md_store_t *store, md_store_group_t group, 
                                             apr_fileperms_t file_perms,
                                             apr_fileperms_t dir_perms)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        
        if (group >= (sizeof(s_fs->group_perms)/sizeof(s_fs->group_perms[0]))) {
            return APR_ENOTIMPL;
        }
        s_fs->group_perms[group].file = file_perms;
        s_fs->group_perms[group].dir = dir_perms;
        return APR_SUCCESS;
    }
    
    apr_status_t md_store_fs_set_event_cb(struct md_store_t *store, md_store_fs_cb *cb, void *baton)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        
        s_fs->event_cb = cb;
        s_fs->event_baton = baton;
        return APR_SUCCESS;
    }
    
    static const perms_t *gperms(md_store_fs_t *s_fs, md_store_group_t group)
    {
        if (group >= (sizeof(s_fs->group_perms)/sizeof(s_fs->group_perms[0]))
            || !s_fs->group_perms[group].dir) {
            return &s_fs->def_perms;
        }
        return &s_fs->group_perms[group];
    }
    
    static apr_status_t fs_get_fname(const char **pfname, 
                                     md_store_t *store, md_store_group_t group, 
                                     const char *name, const char *aspect, 
                                     apr_pool_t *p)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        if (group == MD_SG_NONE) {
            return md_util_path_merge(pfname, p, s_fs->base, aspect, NULL);
        }
        return md_util_path_merge(pfname, p, 
                                  s_fs->base, md_store_group_name(group), name, aspect, NULL);
    }
    
    static apr_status_t fs_get_dname(const char **pdname, 
                                     md_store_t *store, md_store_group_t group, 
                                     const char *name, apr_pool_t *p)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        if (group == MD_SG_NONE) {
            *pdname = s_fs->base;
            return APR_SUCCESS;
        }
        return md_util_path_merge(pdname, p, s_fs->base, md_store_group_name(group), name, NULL);
    }
    
    static void get_pass(const char **ppass, apr_size_t *plen, 
                         md_store_fs_t *s_fs, md_store_group_t group)
    {
        if (s_fs->plain_pkey[group]) {
            *ppass = NULL;
            *plen = 0;
        }
        else {
            *ppass = (const char *)s_fs->key.data;
            *plen = s_fs->key.len;
        }
    }
     
    static apr_status_t fs_fload(void **pvalue, md_store_fs_t *s_fs, const char *fpath, 
                                 md_store_group_t group, md_store_vtype_t vtype, 
                                 apr_pool_t *p, apr_pool_t *ptemp)
    {
        apr_status_t rv;
        const char *pass;
        apr_size_t pass_len;
        
        if (pvalue != NULL) {
            switch (vtype) {
                case MD_SV_TEXT:
                    rv = md_text_fread8k((const char **)pvalue, p, fpath);
                    break;
                case MD_SV_JSON:
                    rv = md_json_readf((md_json_t **)pvalue, p, fpath);
                    break;
                case MD_SV_CERT:
                    rv = md_cert_fload((md_cert_t **)pvalue, p, fpath);
                    break;
                case MD_SV_PKEY:
                    get_pass(&pass, &pass_len, s_fs, group);
                    rv = md_pkey_fload((md_pkey_t **)pvalue, p, pass, pass_len, fpath);
                    break;
                case MD_SV_CHAIN:
                    rv = md_chain_fload((apr_array_header_t **)pvalue, p, fpath);
                    break;
                default:
                    rv = APR_ENOTIMPL;
                    break;
            }
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, ptemp, 
                          "loading type %d from %s", vtype, fpath);
        }
        else { /* check for existence only */
            rv = md_util_is_file(fpath, p);
        }
        return rv;
    }
    
    static apr_status_t pfs_load(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *fpath, *name, *aspect;
        md_store_vtype_t vtype;
        md_store_group_t group;
        void **pvalue;
        apr_status_t rv;
        
        group = (md_store_group_t)va_arg(ap, int);
        name = va_arg(ap, const char *);
        aspect = va_arg(ap, const char *);
        vtype = (md_store_vtype_t)va_arg(ap, int);
        pvalue= va_arg(ap, void **);
            
        if (MD_OK(fs_get_fname(&fpath, &s_fs->s, group, name, aspect, ptemp))) {
            rv = fs_fload(pvalue, s_fs, fpath, group, vtype, p, ptemp);
        }
        return rv;
    }
    
    static apr_status_t dispatch(md_store_fs_t *s_fs, md_store_fs_ev_t ev, unsigned int group, 
                                 const char *fname, apr_filetype_e ftype, apr_pool_t *p)
    {
        (void)ev;
        if (s_fs->event_cb) {
            return s_fs->event_cb(s_fs->event_baton, &s_fs->s, MD_S_FS_EV_CREATED, 
                                  group, fname, ftype, p);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t mk_group_dir(const char **pdir, md_store_fs_t *s_fs, 
                                     md_store_group_t group, const char *name,
                                     apr_pool_t *p)
    {
        const perms_t *perms;
        apr_status_t rv;
        
        perms = gperms(s_fs, group);
    
        rv = fs_get_dname(pdir, &s_fs->s, group, name, p);
        if ((APR_SUCCESS != rv) || (MD_SG_NONE == group)) goto cleanup;
    
        rv = md_util_is_dir(*pdir, p);
        if (APR_STATUS_IS_ENOENT(rv)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p, "not a directory, creating %s", *pdir);
            rv = apr_dir_make_recursive(*pdir, perms->dir, p);
            if (APR_SUCCESS != rv) goto cleanup;
            dispatch(s_fs, MD_S_FS_EV_CREATED, group, *pdir, APR_DIR, p);
        }
    
        rv = apr_file_perms_set(*pdir, perms->dir);
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p, "mk_group_dir %s perm set", *pdir);
        if (APR_STATUS_IS_ENOTIMPL(rv)) {
            rv = APR_SUCCESS;
        }
    cleanup:
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "mk_group_dir %d %s",
                          group, (*pdir? *pdir : (name? name : "(null)")));
        }
        return rv;
    }
    
    static apr_status_t pfs_is_newer(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *fname1, *fname2, *name, *aspect;
        md_store_group_t group1, group2;
        apr_finfo_t inf1, inf2;
        int *pnewer;
        apr_status_t rv;
        
        (void)p;
        group1 = (md_store_group_t)va_arg(ap, int);
        group2 = (md_store_group_t)va_arg(ap, int);
        name = va_arg(ap, const char*);
        aspect = va_arg(ap, const char*);
        pnewer = va_arg(ap, int*);
        
        *pnewer = 0;
        if (   MD_OK(fs_get_fname(&fname1, &s_fs->s, group1, name, aspect, ptemp))
            && MD_OK(fs_get_fname(&fname2, &s_fs->s, group2, name, aspect, ptemp))
            && MD_OK(apr_stat(&inf1, fname1, APR_FINFO_MTIME, ptemp))
            && MD_OK(apr_stat(&inf2, fname2, APR_FINFO_MTIME, ptemp))) {
            *pnewer = inf1.mtime > inf2.mtime;
        }
    
        return rv;
    }
    
    static int fs_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
                           const char *name, const char *aspect, apr_pool_t *p)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        int newer = 0;
        apr_status_t rv;
        
        rv = md_util_pool_vdo(pfs_is_newer, s_fs, p, group1, group2, name, aspect, &newer, NULL);
        if (APR_SUCCESS == rv) {
            return newer;
        }
        return 0;
    }
    
    static apr_status_t pfs_get_modified(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *fname, *name, *aspect;
        md_store_group_t group;
        apr_finfo_t inf;
        apr_time_t *pmtime;
        apr_status_t rv;
        
        (void)p;
        group = (md_store_group_t)va_arg(ap, int);
        name = va_arg(ap, const char*);
        aspect = va_arg(ap, const char*);
        pmtime = va_arg(ap, apr_time_t*);
        
        *pmtime = 0;
        if (   MD_OK(fs_get_fname(&fname, &s_fs->s, group, name, aspect, ptemp))
            && MD_OK(apr_stat(&inf, fname, APR_FINFO_MTIME, ptemp))) {
            *pmtime = inf.mtime;
        }
    
        return rv;
    }
    
    static apr_time_t fs_get_modified(md_store_t *store, md_store_group_t group,  
                                      const char *name, const char *aspect, apr_pool_t *p)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        apr_time_t mtime;
        apr_status_t rv;
        
        rv = md_util_pool_vdo(pfs_get_modified, s_fs, p, group, name, aspect, &mtime, NULL);
        if (APR_SUCCESS == rv) {
            return mtime;
        }
        return 0;
    }
     
    static apr_status_t pfs_save(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *gdir, *dir, *fpath, *name, *aspect;
        md_store_vtype_t vtype;
        md_store_group_t group;
        void *value;
        int create;
        apr_status_t rv;
        const perms_t *perms;
        const char *pass;
        apr_size_t pass_len;
        
        group = (md_store_group_t)va_arg(ap, int);
        name = va_arg(ap, const char*);
        aspect = va_arg(ap, const char*);
        vtype = (md_store_vtype_t)va_arg(ap, int);
        value = va_arg(ap, void *);
        create = va_arg(ap, int);
        
        perms = gperms(s_fs, group);
        
        if (   MD_OK(mk_group_dir(&gdir, s_fs, group, NULL, p)) 
            && MD_OK(mk_group_dir(&dir, s_fs, group, name, p))
            && MD_OK(md_util_path_merge(&fpath, ptemp, dir, aspect, NULL))) {
            
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, ptemp, "storing in %s", fpath);
            switch (vtype) {
                case MD_SV_TEXT:
                    rv = (create? md_text_fcreatex(fpath, perms->file, p, value)
                          : md_text_freplace(fpath, perms->file, p, value));
                    break;
                case MD_SV_JSON:
                    rv = (create? md_json_fcreatex((md_json_t *)value, p, MD_JSON_FMT_INDENT, 
                                                   fpath, perms->file)
                          : md_json_freplace((md_json_t *)value, p, MD_JSON_FMT_INDENT, 
                                             fpath, perms->file));
                    break;
                case MD_SV_CERT:
                    rv = md_cert_fsave((md_cert_t *)value, ptemp, fpath, perms->file);
                    break;
                case MD_SV_PKEY:
                    /* Take care that we write private key with access only to the user,
                     * unless we write the key encrypted */
                    get_pass(&pass, &pass_len, s_fs, group);
                    rv = md_pkey_fsave((md_pkey_t *)value, ptemp, pass, pass_len, 
                                       fpath, (pass && pass_len)? perms->file : MD_FPROT_F_UONLY);
                    break;
                case MD_SV_CHAIN:
                    rv = md_chain_fsave((apr_array_header_t*)value, ptemp, fpath, perms->file);
                    break;
                default:
                    return APR_ENOTIMPL;
            }
            if (APR_SUCCESS == rv) {
                rv = dispatch(s_fs, MD_S_FS_EV_CREATED, group, fpath, APR_REG, p);
            }
        }
        return rv;
    }
    
    static apr_status_t pfs_remove(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *dir, *name, *fpath, *groupname, *aspect;
        apr_status_t rv;
        int force;
        apr_finfo_t info;
        md_store_group_t group;
        
        (void)p;
        group = (md_store_group_t)va_arg(ap, int);
        name = va_arg(ap, const char*);
        aspect = va_arg(ap, const char *);
        force = va_arg(ap, int);
        
        groupname = md_store_group_name(group);
        
        if (   MD_OK(md_util_path_merge(&dir, ptemp, s_fs->base, groupname, name, NULL))
            && MD_OK(md_util_path_merge(&fpath, ptemp, dir, aspect, NULL))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "start remove of md %s/%s/%s", 
                          groupname, name, aspect);
    
            if (!MD_OK(apr_stat(&info, dir, APR_FINFO_TYPE, ptemp))) {
                if (APR_ENOENT == rv && force) {
                    return APR_SUCCESS;
                }
                return rv;
            }
        
            rv = apr_file_remove(fpath, ptemp);
            if (APR_ENOENT == rv && force) {
                rv = APR_SUCCESS;
            }
        }
        return rv;
    }
    
    static apr_status_t fs_load(md_store_t *store, md_store_group_t group, 
                                const char *name, const char *aspect,  
                                md_store_vtype_t vtype, void **pvalue, apr_pool_t *p)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        return md_util_pool_vdo(pfs_load, s_fs, p, group, name, aspect, vtype, pvalue, NULL);
    }
    
    static apr_status_t fs_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                                const char *name, const char *aspect,  
                                md_store_vtype_t vtype, void *value, int create)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        return md_util_pool_vdo(pfs_save, s_fs, p, group, name, aspect, 
                                vtype, value, create, NULL);
    }
    
    static apr_status_t fs_remove(md_store_t *store, md_store_group_t group, 
                                  const char *name, const char *aspect, 
                                  apr_pool_t *p, int force)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        return md_util_pool_vdo(pfs_remove, s_fs, p, group, name, aspect, force, NULL);
    }
    
    static apr_status_t pfs_purge(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *dir, *name, *groupname;
        md_store_group_t group;
        apr_status_t rv;
        
        (void)p;
        group = (md_store_group_t)va_arg(ap, int);
        name = va_arg(ap, const char*);
        
        groupname = md_store_group_name(group);
    
        if (MD_OK(md_util_path_merge(&dir, ptemp, s_fs->base, groupname, name, NULL))) {
            /* Remove all files in dir, there should be no sub-dirs */
            rv = md_util_rm_recursive(dir, ptemp, 1);
        }
        if (!APR_STATUS_IS_ENOENT(rv)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, ptemp, "purge %s/%s (%s)", groupname, name, dir);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t fs_purge(md_store_t *store, apr_pool_t *p, 
                                 md_store_group_t group, const char *name)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        return md_util_pool_vdo(pfs_purge, s_fs, p, group, name, NULL);
    }
    
    /**************************************************************************************************/
    /* iteration */
    
    typedef struct {
        md_store_fs_t *s_fs;
        md_store_group_t group;
        const char *pattern;
        const char *aspect;
        md_store_vtype_t vtype;
        md_store_inspect *inspect;
        const char *dirname;
        void *baton;
        apr_time_t ts;
    } inspect_ctx;
    
    static apr_status_t insp(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                             const char *dir, const char *name, apr_filetype_e ftype)
    {
        inspect_ctx *ctx = baton;
        apr_status_t rv;
        void *value;
        const char *fpath;
     
        (void)ftype;   
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting value at: %s/%s", dir, name);
        if (APR_SUCCESS == (rv = md_util_path_merge(&fpath, ptemp, dir, name, NULL))) {
            rv = fs_fload(&value, ctx->s_fs, fpath, ctx->group, ctx->vtype, p, ptemp);
            if (APR_SUCCESS == rv 
                && !ctx->inspect(ctx->baton, ctx->dirname, name, ctx->vtype, value, p)) {
                return APR_EOF;
            }
            else if (APR_STATUS_IS_ENOENT(rv)) {
                rv = APR_SUCCESS;
            }
        } 
        return rv;
    }
    
    static apr_status_t insp_dir(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                                 const char *dir, const char *name, apr_filetype_e ftype)
    {
        inspect_ctx *ctx = baton;
        apr_status_t rv;
        const char *fpath;
     
        (void)ftype;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting dir at: %s/%s", dir, name);
        if (MD_OK(md_util_path_merge(&fpath, p, dir, name, NULL))) {
            ctx->dirname = name;
            rv = md_util_files_do(insp, ctx, p, fpath, ctx->aspect, NULL);
            if (APR_STATUS_IS_ENOENT(rv)) {
                rv = APR_SUCCESS;
            }
        } 
        return rv;
    }
    
    static apr_status_t fs_iterate(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                   apr_pool_t *p, md_store_group_t group, const char *pattern, 
                                   const char *aspect, md_store_vtype_t vtype)
    {
        const char *groupname;
        apr_status_t rv;
        inspect_ctx ctx;
        
        ctx.s_fs = FS_STORE(store);
        ctx.group = group;
        ctx.pattern = pattern;
        ctx.aspect = aspect;
        ctx.vtype = vtype;
        ctx.inspect = inspect;
        ctx.baton = baton;
        groupname = md_store_group_name(group);
    
        rv = md_util_files_do(insp_dir, &ctx, p, ctx.s_fs->base, groupname, pattern, NULL);
        
        return rv;
    }
    
    static apr_status_t insp_name(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                                  const char *dir, const char *name, apr_filetype_e ftype)
    {
        inspect_ctx *ctx = baton;
        
        (void)ftype;
        (void)p;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting name at: %s/%s", dir, name);
        return ctx->inspect(ctx->baton, dir, name, 0, NULL, ptemp);
    }
    
    static apr_status_t fs_iterate_names(md_store_inspect *inspect, void *baton, md_store_t *store, 
                                         apr_pool_t *p, md_store_group_t group, const char *pattern)
    {
        const char *groupname;
        apr_status_t rv;
        inspect_ctx ctx;
        
        ctx.s_fs = FS_STORE(store);
        ctx.group = group;
        ctx.pattern = pattern;
        ctx.inspect = inspect;
        ctx.baton = baton;
        groupname = md_store_group_name(group);
    
        rv = md_util_files_do(insp_name, &ctx, p, ctx.s_fs->base, groupname, pattern, NULL);
        
        return rv;
    }
    
    static apr_status_t remove_nms_file(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                                        const char *dir, const char *name, apr_filetype_e ftype)
    {
        inspect_ctx *ctx = baton;
        const char *fname;
        apr_finfo_t inf;
        apr_status_t rv = APR_SUCCESS;
    
        (void)p;
        if (APR_DIR == ftype) goto leave;
        if (APR_SUCCESS != (rv = md_util_path_merge(&fname, ptemp, dir, name, NULL))) goto leave;
        if (APR_SUCCESS != (rv = apr_stat(&inf, fname, APR_FINFO_MTIME, ptemp))) goto leave;
        if (inf.mtime >= ctx->ts) goto leave;
    
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "remove_nms file: %s/%s", dir, name);
        rv = apr_file_remove(fname, ptemp);
    
    leave:
        return rv;
    }
    
    static apr_status_t remove_nms_dir(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                                       const char *dir, const char *name, apr_filetype_e ftype)
    {
        inspect_ctx *ctx = baton;
        apr_status_t rv;
        const char *fpath;
     
        (void)ftype;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "remove_nms dir at: %s/%s", dir, name);
        if (MD_OK(md_util_path_merge(&fpath, p, dir, name, NULL))) {
            ctx->dirname = name;
            rv = md_util_files_do(remove_nms_file, ctx, p, fpath, ctx->aspect, NULL);
            if (APR_STATUS_IS_ENOENT(rv)) {
                rv = APR_SUCCESS;
            }
        } 
        return rv;
    }
    
    static apr_status_t fs_remove_nms(md_store_t *store, apr_pool_t *p, 
                                      apr_time_t modified, md_store_group_t group, 
                                      const char *name, const char *aspect)
    {
        const char *groupname;
        apr_status_t rv;
        inspect_ctx ctx;
        
        ctx.s_fs = FS_STORE(store);
        ctx.group = group;
        ctx.pattern = name;
        ctx.aspect = aspect;
        ctx.ts = modified;
        groupname = md_store_group_name(group);
    
        rv = md_util_files_do(remove_nms_dir, &ctx, p, ctx.s_fs->base, groupname, name, NULL);
        
        return rv;
    }
    
    /**************************************************************************************************/
    /* moving */
    
    static apr_status_t pfs_move(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *name, *from_group, *to_group, *from_dir, *to_dir, *arch_dir, *dir;
        md_store_group_t from, to;
        int archive;
        apr_status_t rv;
        
        (void)p;
        from = (md_store_group_t)va_arg(ap, int);
        to = (md_store_group_t)va_arg(ap, int);
        name = va_arg(ap, const char*);
        archive = va_arg(ap, int);
        
        from_group = md_store_group_name(from);
        to_group = md_store_group_name(to);
        if (!strcmp(from_group, to_group)) {
            return APR_EINVAL;
        }
    
        if (   !MD_OK(md_util_path_merge(&from_dir, ptemp, s_fs->base, from_group, name, NULL))
            || !MD_OK(md_util_path_merge(&to_dir, ptemp, s_fs->base, to_group, name, NULL))) {
            goto out;
        }
        
        if (!MD_OK(md_util_is_dir(from_dir, ptemp))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "source is no dir: %s", from_dir);
            goto out;
        }
        
        if (MD_OK(archive? md_util_is_dir(to_dir, ptemp) : APR_ENOENT)) {
            int n = 1;
            const char *narch_dir;
    
            if (    !MD_OK(md_util_path_merge(&dir, ptemp, s_fs->base, 
                                              md_store_group_name(MD_SG_ARCHIVE), NULL))
                || !MD_OK(apr_dir_make_recursive(dir, MD_FPROT_D_UONLY, ptemp))
                || !MD_OK(md_util_path_merge(&arch_dir, ptemp, dir, name, NULL))) {
                goto out;
            }
            
    #ifdef WIN32
            /* WIN32 and handling of files/dirs. What can one say? */
            
            while (n < 1000) {
                narch_dir = apr_psprintf(ptemp, "%s.%d", arch_dir, n);
                rv = md_util_is_dir(narch_dir, ptemp);
                if (APR_STATUS_IS_ENOENT(rv)) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ptemp, "using archive dir: %s", 
                                  narch_dir);
                    break;
                }
                else {
                    ++n;
                    narch_dir = NULL;
                }
            }
    
    #else   /* ifdef WIN32 */
    
            while (n < 1000) {
                narch_dir = apr_psprintf(ptemp, "%s.%d", arch_dir, n);
                if (MD_OK(apr_dir_make(narch_dir, MD_FPROT_D_UONLY, ptemp))) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ptemp, "using archive dir: %s", 
                                  narch_dir);
                    break;
                }
                else if (APR_EEXIST == rv) {
                    ++n;
                    narch_dir = NULL;
                }
                else {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "creating archive dir: %s", 
                                  narch_dir);
                    goto out;
                }
            }
             
    #endif   /* ifdef WIN32 (else part) */
            
            if (!narch_dir) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "ran out of numbers less than 1000 "
                              "while looking for an available one in %s to archive the data "
                              "from %s. Either something is generally wrong or you need to "
                              "clean up some of those directories.", arch_dir, from_dir);
                rv = APR_EGENERAL;
                goto out;
            }
            
            if (!MD_OK(apr_file_rename(to_dir, narch_dir, ptemp))) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
                                  to_dir, narch_dir);
                    goto out;
            }
            if (!MD_OK(apr_file_rename(from_dir, to_dir, ptemp))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
                              from_dir, to_dir);
                apr_file_rename(narch_dir, to_dir, ptemp);
                goto out;
            }
            if (MD_OK(dispatch(s_fs, MD_S_FS_EV_MOVED, to, to_dir, APR_DIR, ptemp))) {
                rv = dispatch(s_fs, MD_S_FS_EV_MOVED, MD_SG_ARCHIVE, narch_dir, APR_DIR, ptemp);
            }
        }
        else if (APR_STATUS_IS_ENOENT(rv)) {
            if (APR_SUCCESS != (rv = apr_file_rename(from_dir, to_dir, ptemp))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
                              from_dir, to_dir);
                goto out;
            }
        }
        else {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "target is no dir: %s", to_dir);
            goto out;
        }
        
    out:
        return rv;
    }
    
    static apr_status_t fs_move(md_store_t *store, apr_pool_t *p, 
                                md_store_group_t from, md_store_group_t to, 
                                const char *name, int archive)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        return md_util_pool_vdo(pfs_move, s_fs, p, from, to, name, archive, NULL);
    }
    
    static apr_status_t pfs_rename(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_store_fs_t *s_fs = baton;
        const char *group_name, *from_dir, *to_dir;
        md_store_group_t group;
        const char *from, *to;
        apr_status_t rv;
        
        (void)p;
        group = (md_store_group_t)va_arg(ap, int);
        from = va_arg(ap, const char*);
        to = va_arg(ap, const char*);
        
        group_name = md_store_group_name(group);
        if (   !MD_OK(md_util_path_merge(&from_dir, ptemp, s_fs->base, group_name, from, NULL))
            || !MD_OK(md_util_path_merge(&to_dir, ptemp, s_fs->base, group_name, to, NULL))) {
            goto out;
        }
        
        if (APR_SUCCESS != (rv = apr_file_rename(from_dir, to_dir, ptemp))
            && !APR_STATUS_IS_ENOENT(rv)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
                          from_dir, to_dir);
            goto out;
        }
    out:
        return rv;
    }
    
    static apr_status_t fs_rename(md_store_t *store, apr_pool_t *p, 
                                md_store_group_t group, const char *from, const char *to)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        return md_util_pool_vdo(pfs_rename, s_fs, p, group, from, to, NULL);
    }
    
    static apr_status_t fs_lock_global(md_store_t *store, apr_pool_t *p, apr_time_t max_wait)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
        apr_status_t rv;
        const char *lpath;
        apr_time_t end;
    
        if (s_fs->global_lock) {
            rv = APR_EEXIST;
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "already locked globally");
            goto cleanup;
        }
    
        rv = md_util_path_merge(&lpath, p, s_fs->base, MD_FS_LOCK_NAME, NULL);
        if (APR_SUCCESS != rv) goto cleanup;
        end = apr_time_now() + max_wait;
    
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p,
                      "acquire global lock: %s", lpath);
        while (apr_time_now() < end) {
            rv = apr_file_open(&s_fs->global_lock, lpath,
                               (APR_FOPEN_WRITE|APR_FOPEN_CREATE),
                               MD_FPROT_F_UALL_GREAD, p);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, p,
                              "unable to create/open lock file: %s",
                              lpath);
                goto next_try;
            }
            rv = apr_file_lock(s_fs->global_lock,
                               APR_FLOCK_EXCLUSIVE|APR_FLOCK_NONBLOCK);
            if (APR_SUCCESS == rv) {
                goto cleanup;
            }
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, p,
                          "unable to obtain lock on: %s",
                          lpath);
    
        next_try:
            if (s_fs->global_lock) {
                apr_file_close(s_fs->global_lock);
                s_fs->global_lock = NULL;
            }
            apr_sleep(apr_time_from_msec(100));
        }
        rv = APR_EGENERAL;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, p,
                      "acquire global lock: %s", lpath);
    
    cleanup:
        return rv;
    }
    
    static void fs_unlock_global(md_store_t *store, apr_pool_t *p)
    {
        md_store_fs_t *s_fs = FS_STORE(store);
    
        (void)p;
        if (s_fs->global_lock) {
            apr_file_close(s_fs->global_lock);
            s_fs->global_lock = NULL;
        }
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acme_authz.c�������������������������������������������������������������0000664�0001751�0001751�00000065054�14723553222�017655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    
    #include <apr_lib.h>
    #include <apr_buckets.h>
    #include <apr_file_info.h>
    #include <apr_file_io.h>
    #include <apr_fnmatch.h>
    #include <apr_hash.h>
    #include <apr_strings.h>
    #include <apr_tables.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_http.h"
    #include "md_log.h"
    #include "md_jws.h"
    #include "md_result.h"
    #include "md_store.h"
    #include "md_util.h"
    
    #include "md_acme.h"
    #include "md_acme_authz.h"
    
    md_acme_authz_t *md_acme_authz_create(apr_pool_t *p)
    {
        md_acme_authz_t *authz;
        authz = apr_pcalloc(p, sizeof(*authz));
        
        return authz;
    }
    
    /**************************************************************************************************/
    /* Register a new authorization */
    
    typedef struct {
        size_t index;
        const char *type;
        const char *uri;
        const char *token;
        const char *key_authz;
    } md_acme_authz_cha_t;
    
    typedef struct {
        apr_pool_t *p;
        md_acme_t *acme;
        const char *domain;
        md_acme_authz_t *authz;
        md_acme_authz_cha_t *challenge;
    } authz_req_ctx;
    
    static void authz_req_ctx_init(authz_req_ctx *ctx, md_acme_t *acme, 
                                   const char *domain, md_acme_authz_t *authz, apr_pool_t *p)
    {
        memset(ctx, 0, sizeof(*ctx));
        ctx->p = p;
        ctx->acme = acme;
        ctx->domain = domain;
        ctx->authz = authz;
    }
    
    /**************************************************************************************************/
    /* Update an existing authorization */
    
    apr_status_t md_acme_authz_retrieve(md_acme_t *acme, apr_pool_t *p, const char *url, 
                                        md_acme_authz_t **pauthz)
    {
        md_acme_authz_t *authz;
        apr_status_t rv;
        
        authz = apr_pcalloc(p, sizeof(*authz));
        authz->url = apr_pstrdup(p, url);
        rv = md_acme_authz_update(authz, acme, p);
        
        *pauthz = (APR_SUCCESS == rv)? authz : NULL;
        return rv;
    }
    
    typedef struct {
        apr_pool_t *p;
        md_acme_authz_t *authz;
    } error_ctx_t;
    
    static int copy_challenge_error(void *baton, size_t index, md_json_t *json)
    {
        error_ctx_t *ctx = baton;
        
        (void)index;
        if (md_json_has_key(json, MD_KEY_ERROR, NULL)) {
            ctx->authz->error_type = md_json_dups(ctx->p, json, MD_KEY_ERROR, MD_KEY_TYPE, NULL);
            ctx->authz->error_detail = md_json_dups(ctx->p, json, MD_KEY_ERROR, MD_KEY_DETAIL, NULL);
            ctx->authz->error_subproblems = md_json_dupj(ctx->p, json, MD_KEY_ERROR, MD_KEY_SUBPROBLEMS, NULL);
        }
        return 1;
    }
    
    apr_status_t md_acme_authz_update(md_acme_authz_t *authz, md_acme_t *acme, apr_pool_t *p)
    {
        md_json_t *json;
        const char *s, *err;
        md_log_level_t log_level;
        apr_status_t rv;
        error_ctx_t ctx;
        
        assert(acme);
        assert(acme->http);
        assert(authz);
        assert(authz->url);
    
        authz->state = MD_ACME_AUTHZ_S_UNKNOWN;
        json = NULL;
        authz->error_type = authz->error_detail = NULL;
        authz->error_subproblems = NULL;
        err = "unable to parse response";
        log_level = MD_LOG_ERR;
        
        if (APR_SUCCESS == (rv = md_acme_get_json(&json, acme, authz->url, p))
            && (s = md_json_gets(json, MD_KEY_STATUS, NULL))) {
                
            authz->domain = md_json_gets(json, MD_KEY_IDENTIFIER, MD_KEY_VALUE, NULL); 
            authz->resource = json;
            if (!strcmp(s, "pending")) {
                authz->state = MD_ACME_AUTHZ_S_PENDING;
                err = "challenge 'pending'";
                log_level = MD_LOG_DEBUG;
            }
            else if (!strcmp(s, "valid")) {
                authz->state = MD_ACME_AUTHZ_S_VALID;
                err = "challenge 'valid'";
                log_level = MD_LOG_DEBUG;
            }
            else if (!strcmp(s, "invalid")) {
                ctx.p = p;
                ctx.authz = authz;
                authz->state = MD_ACME_AUTHZ_S_INVALID;
                md_json_itera(copy_challenge_error, &ctx, json, MD_KEY_CHALLENGES, NULL);
                err = "challenge 'invalid'";
            }
        }
    
        if (json && authz->state == MD_ACME_AUTHZ_S_UNKNOWN) {
            err = "unable to understand response";
            rv = APR_EINVAL;
        }
        
        if (md_log_is_level(p, log_level)) {
            md_log_perror(MD_LOG_MARK, log_level, rv, p, "ACME server authz: %s for %s at %s. "
                          "Exact response was: %s", err, authz->domain, authz->url,
                          json? md_json_writep(json, p, MD_JSON_FMT_COMPACT) : "not available");
        }
        
        return rv;
    }
    
    /**************************************************************************************************/
    /* response to a challenge */
    
    static md_acme_authz_cha_t *cha_from_json(apr_pool_t *p, size_t index, md_json_t *json)
    {
        md_acme_authz_cha_t * cha;
        
        cha = apr_pcalloc(p, sizeof(*cha));
        cha->index = index;
        cha->type = md_json_dups(p, json, MD_KEY_TYPE, NULL);
        if (md_json_has_key(json, MD_KEY_URL, NULL)) { /* ACMEv2 */
            cha->uri = md_json_dups(p, json, MD_KEY_URL, NULL);
        }
        else {                                         /* ACMEv1 */
            cha->uri = md_json_dups(p, json, MD_KEY_URI, NULL);
        }
        cha->token = md_json_dups(p, json, MD_KEY_TOKEN, NULL);
        cha->key_authz = md_json_dups(p, json, MD_KEY_KEYAUTHZ, NULL);
    
        return cha;
    }
    
    static apr_status_t on_init_authz_resp(md_acme_req_t *req, void *baton)
    {
        md_json_t *jpayload;
    
        (void)baton;
        jpayload = md_json_create(req->p);
        return md_acme_req_body_init(req, jpayload);
    } 
    
    static apr_status_t authz_http_set(md_acme_t *acme, apr_pool_t *p, const apr_table_t *hdrs, 
                                       md_json_t *body, void *baton)
    {
        authz_req_ctx *ctx = baton;
        
        (void)acme;
        (void)p;
        (void)hdrs;
        (void)body;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ctx->p, "updated authz %s", ctx->authz->url);
        return APR_SUCCESS;
    }
    
    static apr_status_t setup_key_authz(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
                                        md_acme_t *acme, apr_pool_t *p, int *pchanged)
    {
        const char *thumb64, *key_authz;
        apr_status_t rv;
        
        (void)authz;
        assert(cha);
        assert(cha->token);
        
        *pchanged = 0;
        if (APR_SUCCESS == (rv = md_jws_pkey_thumb(&thumb64, p, acme->acct_key))) {
            key_authz = apr_psprintf(p, "%s.%s", cha->token, thumb64);
            if (cha->key_authz) {
                if (strcmp(key_authz, cha->key_authz)) {
                    /* Hu? Did the account change key? */
                    cha->key_authz = NULL;
                }
            }
            if (!cha->key_authz) {
                cha->key_authz = key_authz;
                *pchanged = 1;
            }
        }
        return rv;
    }
    
    static apr_status_t cha_http_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
                                          md_acme_t *acme, md_store_t *store, 
                                          md_pkeys_spec_t *key_specs,
                                          apr_array_header_t *acme_tls_1_domains, const md_t *md,
                                          apr_table_t *env, md_result_t *result,
                                          const char **psetup_token, apr_pool_t *p)
    {
        const char *data;
        apr_status_t rv;
        int notify_server;
        
        (void)key_specs;
        (void)env;
        (void)acme_tls_1_domains;
        (void)md;
    
        if (APR_SUCCESS != (rv = setup_key_authz(cha, authz, acme, p, &notify_server))) {
            goto out;
        }
        
        rv = md_store_load(store, MD_SG_CHALLENGES, authz->domain, MD_FN_HTTP01,
                           MD_SV_TEXT, (void**)&data, p);
        if ((APR_SUCCESS == rv && strcmp(cha->key_authz, data)) || APR_STATUS_IS_ENOENT(rv)) {
            rv = md_store_save(store, p, MD_SG_CHALLENGES, authz->domain, MD_FN_HTTP01,
                               MD_SV_TEXT, (void*)cha->key_authz, 0);
            notify_server = 1;
        }
        
        if (APR_SUCCESS == rv && notify_server) {
            authz_req_ctx ctx;
            const char *event;
    
            /* Raise event that challenge data has been set up before we tell the
               ACME server. Clusters might want to distribute it. */
            event = apr_psprintf(p, "challenge-setup:%s:%s", MD_AUTHZ_TYPE_HTTP01, authz->domain);
            rv = md_result_raise(result, event, p);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
                              "%s: event '%s' failed. aborting challenge setup",
                              authz->domain, event);
                goto out;
            }
            /* challenge is setup or was changed from previous data, tell ACME server
             * so it may (re)try verification */        
            authz_req_ctx_init(&ctx, acme, NULL, authz, p);
            ctx.challenge = cha;
            rv = md_acme_POST(acme, cha->uri, on_init_authz_resp, authz_http_set, NULL, NULL, &ctx);
        }
    out:
        *psetup_token = (APR_SUCCESS == rv)?
            apr_psprintf(p, "%s:%s", MD_AUTHZ_TYPE_HTTP01, authz->domain) : NULL;
        return rv;
    }
    
    void tls_alpn01_fnames(apr_pool_t *p, md_pkey_spec_t *kspec, char **keyfn, char **certfn )
    {
        *keyfn  = apr_pstrcat(p, "acme-tls-alpn-01-", md_pkey_filename(kspec, p), NULL);
        *certfn = apr_pstrcat(p, "acme-tls-alpn-01-", md_chain_filename(kspec, p), NULL);
    }
    
    static apr_status_t cha_tls_alpn_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz, 
                                              md_acme_t *acme, md_store_t *store, 
                                              md_pkeys_spec_t *key_specs,
                                              apr_array_header_t *acme_tls_1_domains, const md_t *md,
                                              apr_table_t *env, md_result_t *result,
                                              const char **psetup_token, apr_pool_t *p)
    {
        const char *acme_id, *token;
        apr_status_t rv;
        int notify_server;
        md_data_t data;
        int i;
    
        (void)env;
        (void)md;
        if (md_array_str_index(acme_tls_1_domains, authz->domain, 0, 0) < 0) {
            rv = APR_ENOTIMPL;
            if (acme_tls_1_domains->nelts) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p,
                              "%s: protocol 'acme-tls/1' seems not enabled for this domain, "
                              "but is enabled for other associated domains. "
                              "Continuing with fingers crossed.", authz->domain);
            }
            else {
                md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, p,
                              "%s: protocol 'acme-tls/1' seems not enabled for this or "
                              "any other associated domain. Not attempting challenge "
                              "type tls-alpn-01.", authz->domain);
                goto out;
            }
        }
        if (APR_SUCCESS != (rv = setup_key_authz(cha, authz, acme, p, &notify_server))) {
            goto out;
        }
    
        /* Create a "tls-alpn-01" certificate for the domain we want to authenticate.
         * The server will need to answer a TLS connection with SNI == authz->domain
         * and ALPN protocol "acme-tls/1" with this certificate.
         */
        md_data_init_str(&data, cha->key_authz);
        rv = md_crypt_sha256_digest_hex(&token, p, &data);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create tls-alpn-01 validation token",
                          authz->domain);
            goto out;
        }
        acme_id = apr_psprintf(p, "critical,DER:04:20:%s", token);
    
        /* Each configured key type must be generated to ensure:
         * that any fallback certs already given to mod_ssl are replaced.
         * We expect that the validation client (at the CA) can deal with at
         * least one of them.
         */
    
        for (i = 0; i < md_pkeys_spec_count(key_specs); ++i) {
            char *kfn, *cfn;
            md_cert_t *cha_cert;
            md_pkey_t *cha_key;
            md_pkey_spec_t *key_spec;
    
            key_spec = md_pkeys_spec_get(key_specs, i);
            tls_alpn01_fnames(p, key_spec, &kfn, &cfn);
    
            rv = md_store_load(store, MD_SG_CHALLENGES, authz->domain, cfn,
                               MD_SV_CERT, (void**)&cha_cert, p);
            if ((APR_SUCCESS == rv && !md_cert_covers_domain(cha_cert, authz->domain))
                || APR_STATUS_IS_ENOENT(rv)) {
                if (APR_SUCCESS != (rv = md_pkey_gen(&cha_key, p, key_spec))) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create tls-alpn-01 %s challenge key",
                                  authz->domain, md_pkey_spec_name(key_spec));
                    goto out;
                }
    
                if (APR_SUCCESS != (rv = md_cert_make_tls_alpn_01(&cha_cert, authz->domain, acme_id, cha_key,
                                                                  apr_time_from_sec(7 * MD_SECS_PER_DAY), p))) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create tls-alpn-01 %s challenge cert",
                                  authz->domain, md_pkey_spec_name(key_spec));
                    goto out;
                }
            
                if (APR_SUCCESS == (rv = md_store_save(store, p, MD_SG_CHALLENGES, authz->domain, kfn,
                                                       MD_SV_PKEY, (void*)cha_key, 0))) {
                    rv = md_store_save(store, p, MD_SG_CHALLENGES, authz->domain, cfn,
                                       MD_SV_CERT, (void*)cha_cert, 0);
                }
                ++notify_server;
            }
        }
        
        if (APR_SUCCESS == rv && notify_server) {
            authz_req_ctx ctx;
            const char *event;
    
            /* Raise event that challenge data has been set up before we tell the
               ACME server. Clusters might want to distribute it. */
            event = apr_psprintf(p, "challenge-setup:%s:%s", MD_AUTHZ_TYPE_TLSALPN01, authz->domain);
            rv = md_result_raise(result, event, p);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
                              "%s: event '%s' failed. aborting challenge setup",
                              authz->domain, event);
                goto out;
            }
            /* challenge is setup or was changed from previous data, tell ACME server
             * so it may (re)try verification */        
            authz_req_ctx_init(&ctx, acme, NULL, authz, p);
            ctx.challenge = cha;
            rv = md_acme_POST(acme, cha->uri, on_init_authz_resp, authz_http_set, NULL, NULL, &ctx);
        }
    out:    
        *psetup_token = (APR_SUCCESS == rv)?
            apr_psprintf(p, "%s:%s", MD_AUTHZ_TYPE_TLSALPN01, authz->domain) : NULL;
        return rv;
    }
    
    static apr_status_t cha_dns_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz, 
                                         md_acme_t *acme, md_store_t *store, 
                                         md_pkeys_spec_t *key_specs,
                                         apr_array_header_t *acme_tls_1_domains, const md_t *md,
                                         apr_table_t *env, md_result_t *result,
                                         const char **psetup_token, apr_pool_t *p)
    {
        const char *token;
        const char * const *argv;
        const char *cmdline, *dns01_cmd;
        apr_status_t rv;
        int exit_code, notify_server;
        authz_req_ctx ctx;
        md_data_t data;
        const char *event;
    
        (void)store;
        (void)key_specs;
        (void)acme_tls_1_domains;
    
        dns01_cmd = md->dns01_cmd;
        if (!dns01_cmd)
          dns01_cmd = apr_table_get(env, MD_KEY_CMD_DNS01);
        if (!dns01_cmd) {
            rv = APR_ENOTIMPL;
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "%s: dns-01 command not set", 
                          authz->domain);
            goto out;
        }
        
        if (APR_SUCCESS != (rv = setup_key_authz(cha, authz, acme, p, &notify_server))) {
            goto out;
        }
        
        md_data_init_str(&data, cha->key_authz);
        rv = md_crypt_sha256_digest64(&token, p, &data);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create dns-01 token for %s",
                          md->name, authz->domain);
            goto out;
        }
    
        cmdline = apr_psprintf(p, "%s setup %s %s", dns01_cmd, authz->domain, token); 
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                      "%s: dns-01 setup command: %s", authz->domain, cmdline);
    
        apr_tokenize_to_argv(cmdline, (char***)&argv, p);
        if (APR_SUCCESS != (rv = md_util_exec(p, argv[0], argv, &exit_code))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, 
                          "%s: dns-01 setup command failed to execute for %s", md->name, authz->domain);
            goto out;
        }
        if (exit_code) {
            rv = APR_EGENERAL;
            md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, p, 
                          "%s: dns-01 setup command returns %d for %s", md->name, exit_code, authz->domain);
            goto out;
        }
        
        /* Raise event that challenge data has been set up before we tell the
           ACME server. Clusters might want to distribute it. */
        event = apr_psprintf(p, "challenge-setup:%s:%s", MD_AUTHZ_TYPE_DNS01, authz->domain);
        rv = md_result_raise(result, event, p);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
                          "%s: event '%s' failed. aborting challenge setup",
                          authz->domain, event);
            goto out;
        }
        /* challenge is setup, tell ACME server so it may (re)try verification */
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "%s: dns-01 setup succeeded for %s",
           md->name, authz->domain);
        authz_req_ctx_init(&ctx, acme, NULL, authz, p);
        ctx.challenge = cha;
        rv = md_acme_POST(acme, cha->uri, on_init_authz_resp, authz_http_set, NULL, NULL, &ctx);
        
    out:    
        *psetup_token = (APR_SUCCESS == rv)?
            apr_psprintf(p, "%s:%s %s", MD_AUTHZ_TYPE_DNS01, authz->domain, token) : NULL;
        return rv;
    }
    
    static apr_status_t cha_dns_01_teardown(md_store_t *store, const char *domain, const md_t *md,
                                            apr_table_t *env, apr_pool_t *p)
    {
        const char * const *argv;
        const char *cmdline, *dns01_cmd, *dns01v;
        char *tmp, *s;
        apr_status_t rv;
        int exit_code;
        
        (void)store;
    
        dns01_cmd = md->dns01_cmd;
        if (!dns01_cmd)
          dns01_cmd = apr_table_get(env, MD_KEY_CMD_DNS01);
        if (!dns01_cmd) {
            rv = APR_ENOTIMPL;
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "%s: dns-01 command not set for %s",
                md->name, domain);
            goto out;
        }
        dns01v = apr_table_get(env, MD_KEY_DNS01_VERSION);
        if (!dns01v || strcmp(dns01v, "2")) {
            /* use older version of teardown args with only domain, remove token */
            tmp = apr_pstrdup(p, domain);
            s = strchr(tmp, ' ');
            if (s) {
                *s = '\0';
                domain = tmp;
            }
        }
    
        cmdline = apr_psprintf(p, "%s teardown %s", dns01_cmd, domain); 
        apr_tokenize_to_argv(cmdline, (char***)&argv, p);
        if (APR_SUCCESS != (rv = md_util_exec(p, argv[0], argv, &exit_code)) || exit_code) {
            md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, p, 
                          "%s: dns-01 teardown command failed (exit code=%d) for %s",
                          md->name, exit_code, domain);
        }
    out:    
        return rv;
    }
    
    static apr_status_t cha_teardown_dir(md_store_t *store, const char *domain, const md_t *md,
                                         apr_table_t *env, apr_pool_t *p)
    {
        (void)md;
        (void)env;
        return md_store_purge(store, p, MD_SG_CHALLENGES, domain);
    }
    
    typedef apr_status_t cha_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz, 
                                   md_acme_t *acme, md_store_t *store, 
                                   md_pkeys_spec_t *key_specs,
                                   apr_array_header_t *acme_tls_1_domains, const md_t *md,
                                   apr_table_t *env, md_result_t *result,
                                   const char **psetup_token, apr_pool_t *p);
                                   
    typedef apr_status_t cha_teardown(md_store_t *store, const char *domain, const md_t *md,
                                      apr_table_t *env, apr_pool_t *p);
                                     
    typedef struct {
        const char *name;
        cha_setup *setup;
        cha_teardown *teardown;
    } cha_type;
    
    static const cha_type CHA_TYPES[] = {
        { MD_AUTHZ_TYPE_HTTP01,     cha_http_01_setup,      cha_teardown_dir },
        { MD_AUTHZ_TYPE_TLSALPN01,  cha_tls_alpn_01_setup,  cha_teardown_dir },
        { MD_AUTHZ_TYPE_DNS01,      cha_dns_01_setup,       cha_dns_01_teardown },
    };
    static const apr_size_t CHA_TYPES_LEN = (sizeof(CHA_TYPES)/sizeof(CHA_TYPES[0]));
    
    typedef struct {
        apr_pool_t *p;
        const char *type;
        md_acme_authz_cha_t *accepted;
        apr_array_header_t *offered;
    } cha_find_ctx;
    
    static apr_status_t collect_offered(void *baton, size_t index, md_json_t *json)
    {
        cha_find_ctx *ctx = baton;
        const char *ctype;
        
        (void)index;
        if ((ctype = md_json_gets(json, MD_KEY_TYPE, NULL))) {
            APR_ARRAY_PUSH(ctx->offered, const char*) = apr_pstrdup(ctx->p, ctype);
        }
        return 1;
    }
    
    static apr_status_t find_type(void *baton, size_t index, md_json_t *json)
    {
        cha_find_ctx *ctx = baton;
        
        const char *ctype = md_json_gets(json, MD_KEY_TYPE, NULL);
        if (ctype && !apr_strnatcasecmp(ctx->type, ctype)) {
            ctx->accepted = cha_from_json(ctx->p, index, json);
            return 0;
        }
        return 1;
    }
    
    apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, md_acme_t *acme, md_store_t *store, 
                                       apr_array_header_t *challenges, md_pkeys_spec_t *key_specs,
                                       apr_array_header_t *acme_tls_1_domains, const md_t *md,
                                       apr_table_t *env, apr_pool_t *p, const char **psetup_token,
                                       md_result_t *result)
    {
        apr_status_t rv;
        int i, j;
        cha_find_ctx fctx;
    
        assert(acme);
        assert(authz);
        assert(authz->resource);
    
        fctx.p = p;
        fctx.accepted = NULL;
        
        /* Look in the order challenge types are defined:
         * - if they are offered by the CA, try to set it up
         * - if setup was successful, we are done and the CA will evaluate us
         * - if setup failed, continue to look for another supported challenge type
         * - if there is no overlap in types, tell the user that she has to configure
         *   either more types (dns, tls-alpn-01), make ports available or refrain
         *   from using wildcard domains when dns is not available. etc.
         * - if there was an overlap, but no setup was successful, report that. We
         *   will retry this, maybe the failure is temporary (e.g. command to setup DNS
         */
         md_result_printf(result, 0, "%s: selecting suitable authorization challenge "
                          "type, this domain supports %s",
                          authz->domain, apr_array_pstrcat(p, challenges, ' '));
        rv = APR_ENOTIMPL;
        *psetup_token = NULL;
        for (i = 0; i < challenges->nelts; ++i) {
            fctx.type = APR_ARRAY_IDX(challenges, i, const char *);
            fctx.accepted = NULL;
            md_json_itera(find_type, &fctx, authz->resource, MD_KEY_CHALLENGES, NULL);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p,
                          "%s: challenge type '%s' for %s: %s",
                          authz->domain, fctx.type, md->name,
                          fctx.accepted? "maybe acceptable" : "not applicable");
    
            if (fctx.accepted) {
                for (j = 0; j < (int)CHA_TYPES_LEN; ++j) {
                    if (!apr_strnatcasecmp(CHA_TYPES[j].name, fctx.accepted->type)) {
                        md_result_activity_printf(result, "Setting up challenge '%s' for domain %s", 
                                                  fctx.accepted->type, authz->domain);
                        rv = CHA_TYPES[j].setup(fctx.accepted, authz, acme, store, key_specs,
                                                acme_tls_1_domains, md, env, result,
                                                psetup_token, p);
                        if (APR_SUCCESS == rv) {
                            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, 
                                          "%s: set up challenge '%s' for %s", 
                                          authz->domain, fctx.accepted->type, md->name);
                            goto out;
                        }
                        md_result_printf(result, rv, "error setting up challenge '%s' for %s, "
                                         "for domain %s, looking for other option",
                                         fctx.accepted->type, authz->domain, md->name);
                        md_result_log(result, MD_LOG_INFO);
                    }
                }
            }
        }
        
    out:
        if (!fctx.accepted || APR_ENOTIMPL == rv) {
            rv = APR_EINVAL;
            fctx.offered = apr_array_make(p, 5, sizeof(const char*));
            md_json_itera(collect_offered, &fctx, authz->resource, MD_KEY_CHALLENGES, NULL);
            md_result_printf(result, rv, "None of offered challenge types for domain %s are supported. "
                          "The server offered '%s' and available are: '%s'.",
                          authz->domain, 
                          apr_array_pstrcat(p, fctx.offered, ' '),
                          apr_array_pstrcat(p, challenges, ' '));
            result->problem = "challenge-mismatch";
            md_result_log(result, MD_LOG_ERR);
        }
        else if (APR_SUCCESS != rv) {
            fctx.offered = apr_array_make(p, 5, sizeof(const char*));
            md_json_itera(collect_offered, &fctx, authz->resource, MD_KEY_CHALLENGES, NULL);
            md_result_printf(result, rv, "None of the offered challenge types %s offered "
                             "for domain %s could be setup successfully. Please check the "
                             "log for errors.", authz->domain, 
                             apr_array_pstrcat(p, fctx.offered, ' '));
            result->problem = "challenge-setup-failure";
            md_result_log(result, MD_LOG_ERR);
        }
        return rv;
    }
    
    apr_status_t md_acme_authz_teardown(struct md_store_t *store, const char *token,
                                        const md_t *md, apr_table_t *env, apr_pool_t *p)
    {
        char *challenge, *domain;
        int i;
        
        if (strchr(token, ':')) {
            challenge = apr_pstrdup(p, token);
            domain = strchr(challenge, ':');
            *domain = '\0'; domain++;
            for (i = 0; i < (int)CHA_TYPES_LEN; ++i) {
                if (!apr_strnatcasecmp(CHA_TYPES[i].name, challenge)) {
                    if (CHA_TYPES[i].teardown) {
                        return CHA_TYPES[i].teardown(store, domain, md, env, p);
                    }
                    break;
                }
            }
        }
        return APR_SUCCESS;
    }
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_util.h�������������������������������������������������������������������0000664�0001751�0001751�00000024065�14467135273�016523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_util_h
    #define mod_md_md_util_h
    
    #include <stdio.h>
    #include <apr_file_io.h>
    
    struct apr_array_header_t;
    struct apr_table_t;
    
    /**************************************************************************************************/
    /* pool utils */
    
    typedef apr_status_t md_util_action(void *baton, apr_pool_t *p, apr_pool_t *ptemp);
    typedef apr_status_t md_util_vaction(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap);
    
    apr_status_t md_util_pool_do(md_util_action *cb, void *baton, apr_pool_t *p); 
    apr_status_t md_util_pool_vdo(md_util_vaction *cb, void *baton, apr_pool_t *p, ...); 
    
    /**************************************************************************************************/
    /* data chunks */
    
    typedef void md_data_free_fn(void *data);
    
    typedef struct md_data_t md_data_t;
    struct md_data_t {
        const char *data;
        apr_size_t len;
        md_data_free_fn *free_data;
    };
    
    /**
     * Init the data to empty, overwriting any content.
     */
    void md_data_null(md_data_t *d);
    
    /**
     * Create a new md_data_t, providing `len` bytes allocated from pool `p`.
     */
    md_data_t *md_data_pmake(apr_size_t len, apr_pool_t *p);
    /**
     * Initialize md_data_t 'd', providing `len` bytes allocated from pool `p`.
     */
    void md_data_pinit(md_data_t *d, apr_size_t len, apr_pool_t *p);
    /**
     * Initialize md_data_t 'd', by borrowing 'len' bytes in `data` without copying.
     * `d` will not take ownership.
     */
    void md_data_init(md_data_t *d, const char *data, apr_size_t len);
    
    /**
     * Initialize md_data_t 'd', by borrowing the NUL-terminated `str`.
     * `d` will not take ownership.
     */
    void md_data_init_str(md_data_t *d, const char *str);
    
    /**
     * Free any present data and clear (NULL) it. Passing NULL is permitted.
     */
    void md_data_clear(md_data_t *d);
    
    md_data_t *md_data_make_pcopy(apr_pool_t *p, const char *data, apr_size_t len);
    
    apr_status_t md_data_assign_copy(md_data_t *dest, const char *src, apr_size_t src_len);
    void md_data_assign_pcopy(md_data_t *dest, const char *src, apr_size_t src_len, apr_pool_t *p);
    
    apr_status_t md_data_to_hex(const char **phex, char separator,
                                apr_pool_t *p, const md_data_t *data);
    
    /**************************************************************************************************/
    /* generic arrays */
    
    /**
     * In an array of pointers, remove all entries == elem. Returns the number
     * of entries removed.
     */
    int md_array_remove(struct apr_array_header_t *a, void *elem);
    
    /* 
     * Remove the ith entry from the array.
     * @return != 0 iff an entry was removed, e.g. idx was not outside range 
     */
    int md_array_remove_at(struct apr_array_header_t *a, int idx);
    
    /**************************************************************************************************/
    /* string related */
    char *md_util_str_tolower(char *s);
    
    /**
     * Return != 0 iff array is either NULL or empty 
     */ 
    int md_array_is_empty(const struct apr_array_header_t *array);
    
    int md_array_str_index(const struct apr_array_header_t *array, const char *s, 
                           int start, int case_sensitive);
    
    int md_array_str_eq(const struct apr_array_header_t *a1, 
                        const struct apr_array_header_t *a2, int case_sensitive);
    
    struct apr_array_header_t *md_array_str_clone(apr_pool_t *p, struct apr_array_header_t *array);
    
    /**
     * Create a new array with duplicates removed.
     */
    struct apr_array_header_t *md_array_str_compact(apr_pool_t *p, struct apr_array_header_t *src,
                                                    int case_sensitive);
    
    /**
     * Create a new array with all occurrences of <exclude> removed.
     */
    struct apr_array_header_t *md_array_str_remove(apr_pool_t *p, struct apr_array_header_t *src, 
                                                   const char *exclude, int case_sensitive);
    
    int md_array_str_add_missing(struct apr_array_header_t *dest, 
                                 struct apr_array_header_t *src, int case_sensitive);
    
    /**************************************************************************************************/
    /* process execution */
    
    apr_status_t md_util_exec(apr_pool_t *p, const char *cmd, const char * const *argv,
                              int *exit_code);
    
    /**************************************************************************************************/
    /* dns name check */
    
    /**
     * Is a host/domain name using allowed characters. Not a wildcard.
     * @param domain     name to check
     * @param need_fqdn  iff != 0, check that domain contains '.'
     * @return != 0 iff domain looks like  a non-wildcard, legal DNS domain name.
     */
    int md_dns_is_name(apr_pool_t *p, const char *domain, int need_fqdn);
    
    /**
     * Check if the given domain is a valid wildcard DNS name, e.g. *.example.org
     * @param domain    name to check
     * @return != 0 iff domain is a DNS wildcard.
     */
    int md_dns_is_wildcard(apr_pool_t *p, const char *domain);
    
    /**
     * Determine iff pattern matches domain, including case-ignore and wildcard domains.
     * It is assumed that both names follow dns syntax.
     * @return != 0 iff pattern matches domain
     */ 
    int md_dns_matches(const char *pattern, const char *domain);
    
    /**
     * Create a new array with the minimal set out of the given domain names that match all
     * of them. If none of the domains is a wildcard, only duplicates are removed.
     * If domains contain a wildcard, any name matching the wildcard will be removed.
     */
    struct apr_array_header_t *md_dns_make_minimal(apr_pool_t *p, 
                                                   struct apr_array_header_t *domains);
    
    /**
     * Determine if the given domains cover the name, including wildcard matching.
     * @return != 0 iff name is matched by list of domains
     */
    int md_dns_domains_match(const apr_array_header_t *domains, const char *name);
    
    /**
     * @return != 0 iff `name` is matched by a wildcard pattern in `domains`
     */
    int md_is_wild_match(const apr_array_header_t *domains, const char *name);
    
    /**************************************************************************************************/
    /* file system related */
    
    struct apr_file_t;
    struct apr_finfo_t;
    
    apr_status_t md_util_fopen(FILE **pf, const char *fn, const char *mode);
    
    apr_status_t md_util_fcreatex(struct apr_file_t **pf, const char *fn, 
                                  apr_fileperms_t perms, apr_pool_t *p);
    
    apr_status_t md_util_path_merge(const char **ppath, apr_pool_t *p, ...);
    
    apr_status_t md_util_is_dir(const char *path, apr_pool_t *pool);
    apr_status_t md_util_is_file(const char *path, apr_pool_t *pool);
    apr_status_t md_util_is_unix_socket(const char *path, apr_pool_t *pool);
    int md_file_exists(const char *fname, apr_pool_t *p);
    
    typedef apr_status_t md_util_file_cb(void *baton, struct apr_file_t *f, apr_pool_t *p);
    
    apr_status_t md_util_freplace(const char *fpath, apr_fileperms_t perms, apr_pool_t *p, 
                                  md_util_file_cb *write, void *baton);
    
    /** 
     * Remove a file/directory and all files/directories contain up to max_level. If max_level == 0,
     * only an empty directory or a file can be removed.
     */
    apr_status_t md_util_rm_recursive(const char *fpath, apr_pool_t *p, int max_level);
    
    typedef apr_status_t md_util_fdo_cb(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                                             const char *dir, const char *name, 
                                             apr_filetype_e ftype);
                                             
    apr_status_t md_util_files_do(md_util_fdo_cb *cb, void *baton, apr_pool_t *p, 
                                  const char *path, ...);
    
    /**
     * Depth first traversal of directory tree starting at path.
     */
    apr_status_t md_util_tree_do(md_util_fdo_cb *cb, void *baton, apr_pool_t *p, 
                                 const char *path, int follow_links);
    
    apr_status_t md_util_ftree_remove(const char *path, apr_pool_t *p);
    
    apr_status_t md_text_fread8k(const char **ptext, apr_pool_t *p, const char *fpath);
    apr_status_t md_text_fcreatex(const char *fpath, apr_fileperms_t 
                                  perms, apr_pool_t *p, const char *text);
    apr_status_t md_text_freplace(const char *fpath, apr_fileperms_t perms, 
                                  apr_pool_t *p, const char *text); 
    
    /**************************************************************************************************/
    /* base64 url encodings */
    const char *md_util_base64url_encode(const md_data_t *data, apr_pool_t *pool);
    apr_size_t md_util_base64url_decode(md_data_t *decoded, const char *encoded, 
                                        apr_pool_t *pool);
    
    /**************************************************************************************************/
    /* http/url related */
    const char *md_util_schemify(apr_pool_t *p, const char *s, const char *def_scheme);
    
    apr_status_t md_util_abs_uri_check(apr_pool_t *p, const char *s, const char **perr);
    apr_status_t md_util_abs_http_uri_check(apr_pool_t *p, const char *uri, const char **perr);
    
    const char *md_link_find_relation(const struct apr_table_t *headers, 
                                      apr_pool_t *pool, const char *relation);
    
    const char *md_util_parse_ct(apr_pool_t *pool, const char *cth);
    /**************************************************************************************************/
    /* retry logic */
    
    typedef apr_status_t md_util_try_fn(void *baton, int i);
    
    apr_status_t md_util_try(md_util_try_fn *fn, void *baton, int ignore_errs,  
                             apr_interval_time_t timeout, apr_interval_time_t start_delay, 
                             apr_interval_time_t max_delay, int backoff);
    
    #endif /* md_util_h */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_log.h��������������������������������������������������������������������0000664�0001751�0001751�00000003704�14301701440�016302� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_log_h
    #define mod_md_md_log_h
    
    typedef enum {
        MD_LOG_EMERG,
        MD_LOG_ALERT,
        MD_LOG_CRIT,
        MD_LOG_ERR, 
        MD_LOG_WARNING, 
        MD_LOG_NOTICE, 
        MD_LOG_INFO, 
        MD_LOG_DEBUG, 
        MD_LOG_TRACE1, 
        MD_LOG_TRACE2, 
        MD_LOG_TRACE3, 
        MD_LOG_TRACE4, 
        MD_LOG_TRACE5, 
        MD_LOG_TRACE6, 
        MD_LOG_TRACE7, 
        MD_LOG_TRACE8, 
    } md_log_level_t;
    
    #define MD_LOG_MARK     __FILE__,__LINE__
    
    #ifndef APLOGNO
    #define APLOGNO(n)              "AH" #n ": "
    #endif
    
    const char *md_log_level_name(md_log_level_t level);
    
    int md_log_is_level(apr_pool_t *p, md_log_level_t level);
    
    void md_log_perror(const char *file, int line, md_log_level_t level, 
                       apr_status_t rv, apr_pool_t *p, const char *fmt, ...)
                                    __attribute__((format(printf,6,7)));
    
    typedef int md_log_level_cb(void *baton, apr_pool_t *p, md_log_level_t level);
    
    typedef void md_log_print_cb(const char *file, int line, md_log_level_t level, 
                    apr_status_t rv, void *baton, apr_pool_t *p, const char *fmt, va_list ap);
    
    void md_log_set(md_log_level_cb *level_cb, md_log_print_cb *print_cb, void *baton);
    
    #endif /* md_log_h */
    ������������������������������������������������������������httpd-2.4.64/modules/md/md_acme_acct.c��������������������������������������������������������������0000664�0001751�0001751�00000061441�14240433464�017427� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    
    #include <apr_lib.h>
    #include <apr_file_info.h>
    #include <apr_file_io.h>
    #include <apr_fnmatch.h>
    #include <apr_hash.h>
    #include <apr_strings.h>
    #include <apr_tables.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_json.h"
    #include "md_jws.h"
    #include "md_log.h"
    #include "md_result.h"
    #include "md_store.h"
    #include "md_util.h"
    #include "md_version.h"
    
    #include "md_acme.h"
    #include "md_acme_acct.h"
    
    static apr_status_t acct_make(md_acme_acct_t **pacct, apr_pool_t *p, 
                                  const char *ca_url, apr_array_header_t *contacts)
    {
        md_acme_acct_t *acct;
        
        acct = apr_pcalloc(p, sizeof(*acct));
        acct->ca_url = ca_url;
        if (!contacts || apr_is_empty_array(contacts)) {
            acct->contacts = apr_array_make(p, 5, sizeof(const char *));
        }
        else {
            acct->contacts = apr_array_copy(p, contacts);
        }
        
        *pacct = acct;
        return APR_SUCCESS;
    }
    
    
    static const char *mk_acct_id(apr_pool_t *p, md_acme_t *acme, int i)
    {
        return apr_psprintf(p, "ACME-%s-%04d", acme->sname, i);
    }
    
    static const char *mk_acct_pattern(apr_pool_t *p, md_acme_t *acme)
    {
        return apr_psprintf(p, "ACME-%s-*", acme->sname);
    }
     
    /**************************************************************************************************/
    /* json load/save */
    
    static md_acme_acct_st acct_st_from_str(const char *s) 
    {
        if (s) {
            if (!strcmp("valid", s)) {
                return MD_ACME_ACCT_ST_VALID;
            }
            else if (!strcmp("deactivated", s)) {
                return MD_ACME_ACCT_ST_DEACTIVATED;
            }
            else if (!strcmp("revoked", s)) {
                return MD_ACME_ACCT_ST_REVOKED;
            }
        }
        return MD_ACME_ACCT_ST_UNKNOWN;
    }
    
    md_json_t *md_acme_acct_to_json(md_acme_acct_t *acct, apr_pool_t *p)
    {
        md_json_t *jacct;
        const char *s;
    
        assert(acct);
        jacct = md_json_create(p);
        switch (acct->status) {
            case MD_ACME_ACCT_ST_VALID:
                s = "valid";
                break;
            case MD_ACME_ACCT_ST_DEACTIVATED:
                s = "deactivated";
                break;
            case MD_ACME_ACCT_ST_REVOKED:
                s = "revoked";
                break;
            default:
                s = NULL;
                break;
        }    
        if (s) md_json_sets(s, jacct, MD_KEY_STATUS, NULL);
        if (acct->url) md_json_sets(acct->url, jacct, MD_KEY_URL, NULL);
        if (acct->ca_url) md_json_sets(acct->ca_url, jacct, MD_KEY_CA_URL, NULL);
        if (acct->contacts) md_json_setsa(acct->contacts, jacct, MD_KEY_CONTACT, NULL);
        if (acct->registration) md_json_setj(acct->registration, jacct, MD_KEY_REGISTRATION, NULL);
        if (acct->agreement) md_json_sets(acct->agreement, jacct, MD_KEY_AGREEMENT, NULL);
        if (acct->orders) md_json_sets(acct->orders, jacct, MD_KEY_ORDERS, NULL);
        if (acct->eab_kid) md_json_sets(acct->eab_kid, jacct, MD_KEY_EAB, MD_KEY_KID, NULL);
        if (acct->eab_hmac) md_json_sets(acct->eab_hmac, jacct, MD_KEY_EAB, MD_KEY_HMAC, NULL);
    
        return jacct;
    }
    
    apr_status_t md_acme_acct_from_json(md_acme_acct_t **pacct, md_json_t *json, apr_pool_t *p)
    {
        apr_status_t rv = APR_EINVAL;
        md_acme_acct_t *acct;
        md_acme_acct_st status = MD_ACME_ACCT_ST_UNKNOWN;
        const char *ca_url, *url;
        apr_array_header_t *contacts;
        
        if (md_json_has_key(json, MD_KEY_STATUS, NULL)) {
            status = acct_st_from_str(md_json_gets(json, MD_KEY_STATUS, NULL));
        }
    
        url = md_json_gets(json, MD_KEY_URL, NULL);
        if (!url) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "account has no url");
            goto leave;
        }
    
        ca_url = md_json_gets(json, MD_KEY_CA_URL, NULL);
        if (!ca_url) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "account has no CA url: %s", url);
            goto leave;
        }
        
        contacts = apr_array_make(p, 5, sizeof(const char *));
        if (md_json_has_key(json, MD_KEY_CONTACT, NULL)) {
            md_json_getsa(contacts, json, MD_KEY_CONTACT, NULL);
        }
        else {
            md_json_getsa(contacts, json, MD_KEY_REGISTRATION, MD_KEY_CONTACT, NULL);
        }
        rv = acct_make(&acct, p, ca_url, contacts);
        if (APR_SUCCESS != rv) goto leave;
    
        acct->status = status;
        acct->url = url;
        acct->agreement = md_json_gets(json, MD_KEY_AGREEMENT, NULL);
        if (!acct->agreement) {
            /* backward compatible check */
            acct->agreement = md_json_gets(json, "terms-of-service", NULL);
        }
        acct->orders = md_json_gets(json, MD_KEY_ORDERS, NULL);
        if (md_json_has_key(json, MD_KEY_EAB, MD_KEY_KID, NULL)
            && md_json_has_key(json, MD_KEY_EAB, MD_KEY_HMAC, NULL)) {
            acct->eab_kid = md_json_gets(json, MD_KEY_EAB, MD_KEY_KID, NULL);
            acct->eab_hmac = md_json_gets(json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
        }
    
    leave:
        *pacct = (APR_SUCCESS == rv)? acct : NULL;
        return rv;
    }
    
    apr_status_t md_acme_acct_save(md_store_t *store, apr_pool_t *p, md_acme_t *acme, 
                                   const char **pid, md_acme_acct_t *acct, md_pkey_t *acct_key)
    {
        md_json_t *jacct;
        apr_status_t rv;
        int i;
        const char *id = pid? *pid : NULL;
        
        jacct = md_acme_acct_to_json(acct, p);
        if (id) {
            rv = md_store_save(store, p, MD_SG_ACCOUNTS, id, MD_FN_ACCOUNT, MD_SV_JSON, jacct, 0);
        }
        else {
            rv = APR_EAGAIN;
            for (i = 0; i < 1000 && APR_SUCCESS != rv; ++i) {
                id = mk_acct_id(p, acme, i);
                rv = md_store_save(store, p, MD_SG_ACCOUNTS, id, MD_FN_ACCOUNT, MD_SV_JSON, jacct, 1);
            }
        }
        if (APR_SUCCESS == rv) {
            if (pid) *pid = id;
            rv = md_store_save(store, p, MD_SG_ACCOUNTS, id, MD_FN_ACCT_KEY, MD_SV_PKEY, acct_key, 0);
        }
        return rv;
    }
    
    apr_status_t md_acme_acct_load(md_acme_acct_t **pacct, md_pkey_t **ppkey,
                                   md_store_t *store, md_store_group_t group, 
                                   const char *name, apr_pool_t *p)
    {
        md_json_t *json;
        apr_status_t rv;
    
        rv = md_store_load_json(store, group, name, MD_FN_ACCOUNT, &json, p);
        if (APR_STATUS_IS_ENOENT(rv)) {
            goto out;
        }
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "error reading account: %s", name);
            goto out;
        }
        
        rv = md_acme_acct_from_json(pacct, json, p);
        if (APR_SUCCESS == rv) {
            rv = md_store_load(store, group, name, MD_FN_ACCT_KEY, MD_SV_PKEY, (void**)ppkey, p);
            if (APR_SUCCESS != rv) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "loading key: %s", name);
                goto out;
            }
        }
    out:
        if (APR_SUCCESS != rv) {
            *pacct = NULL;
            *ppkey = NULL;
        } 
        return rv;
    }
    
    /**************************************************************************************************/
    /* Lookup */
    
    int md_acme_acct_matches_url(md_acme_acct_t *acct, const char *url)
    {
        /* The ACME url must match exactly */
        if (!url || !acct->ca_url || strcmp(acct->ca_url, url)) return 0;
        return 1;
    }
    
    int md_acme_acct_matches_md(md_acme_acct_t *acct, const md_t *md)
    {
        if (!md_acme_acct_matches_url(acct, md->ca_effective)) return 0;
        /* if eab values are not mentioned, we match an account regardless
         * if it was registered with eab or not */
        if (!md->ca_eab_kid || !md->ca_eab_hmac) {
            /* No eab only acceptable when no eab is asked for.
             * This prevents someone that has no external account binding
             * to re-use an account from another MDomain that was created
             * with a binding. */
            return !acct->eab_kid || !acct->eab_hmac;
        }
        /* But of eab is asked for, we need an acct that matches exactly.
         * When someone configures a new EAB and we need
         * to created a new account for it. */
        if (!acct->eab_kid || !acct->eab_hmac) return 0;
        return !strcmp(acct->eab_kid, md->ca_eab_kid)
               && !strcmp(acct->eab_hmac, md->ca_eab_hmac);
    }
    
    typedef struct {
        apr_pool_t *p;
        const md_t *md;
        const char *id;
    } find_ctx;
    
    static int find_acct(void *baton, const char *name, const char *aspect,
                         md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
    {
        find_ctx *ctx = baton;
        md_acme_acct_t *acct;
        apr_status_t rv;
    
        (void)aspect;
        (void)ptemp;
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ctx->p, "account candidate %s/%s", name, aspect); 
        if (MD_SV_JSON == vtype) {
            rv = md_acme_acct_from_json(&acct, (md_json_t*)value, ptemp);
            if (APR_SUCCESS != rv) goto cleanup;
    
            if (MD_ACME_ACCT_ST_VALID == acct->status
                && (!ctx->md || md_acme_acct_matches_md(acct, ctx->md))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ctx->p, 
                              "found account %s for %s: %s, status=%d",
                              acct->id, ctx->md->ca_effective, aspect, acct->status);
                ctx->id = apr_pstrdup(ctx->p, name);
                return 0;
            }
        }
    cleanup:
        return 1;
    }
    
    static apr_status_t acct_find(const char **pid, md_acme_acct_t **pacct, md_pkey_t **ppkey, 
                                  md_store_t *store, md_store_group_t group,
                                  const char *name_pattern,
                                  const md_t *md, apr_pool_t *p)
    {
        apr_status_t rv;
        find_ctx ctx;
    
        memset(&ctx, 0, sizeof(ctx));
        ctx.p = p;
        ctx.md = md;
    
        rv = md_store_iter(find_acct, &ctx, store, p, group, name_pattern, MD_FN_ACCOUNT, MD_SV_JSON);
        if (ctx.id) {
            *pid = ctx.id;
            rv = md_acme_acct_load(pacct, ppkey, store, group, ctx.id, p);
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "acct_find: got account %s", ctx.id);
        }
        else {
            *pacct = NULL;
            rv = APR_ENOENT;
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p, "acct_find: none found"); 
        }
        return rv;
    }
    
    static apr_status_t acct_find_and_verify(md_store_t *store, md_store_group_t group, 
                                             const char *name_pattern,
                                             md_acme_t *acme, const md_t *md,
                                             apr_pool_t *p)
    {
        md_acme_acct_t *acct;
        md_pkey_t *pkey;
        const char *id;
        apr_status_t rv;
    
        rv = acct_find(&id, &acct, &pkey, store, group, name_pattern, md, p);
        if (APR_SUCCESS == rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p, "acct_find_and_verify: found %s",
                          id);
            acme->acct_id = (MD_SG_STAGING == group)? NULL : id;
            acme->acct = acct;
            acme->acct_key = pkey;
            rv = md_acme_acct_validate(acme, (MD_SG_STAGING == group)? NULL : store, p);
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, p, "acct_find_and_verify: verified %s",
                          id);
    
            if (APR_SUCCESS != rv) {
                acme->acct_id = NULL;
                acme->acct = NULL;
                acme->acct_key = NULL;
                if (APR_STATUS_IS_ENOENT(rv)) {
                    /* verification failed and account has been disabled.
                       Indicate to caller that he may try again. */
                    rv = APR_EAGAIN;
                }
            }
        }
        return rv;
    }
    
    apr_status_t md_acme_find_acct_for_md(md_acme_t *acme, md_store_t *store, const md_t *md)
    {
        apr_status_t rv;
        
        while (APR_EAGAIN == (rv = acct_find_and_verify(store, MD_SG_ACCOUNTS, 
                                                        mk_acct_pattern(acme->p, acme), 
                                                        acme, md, acme->p))) {
            /* nop */
        }
        
        if (APR_STATUS_IS_ENOENT(rv)) {
            /* No suitable account found in MD_SG_ACCOUNTS. Maybe a new account
             * can already be found in MD_SG_STAGING? */
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, acme->p, 
                          "no account found, looking in STAGING");
            rv = acct_find_and_verify(store, MD_SG_STAGING, "*", acme, md, acme->p);
            if (APR_EAGAIN == rv) {
                rv = APR_ENOENT;
            }
        }
        return rv;
    }
    
    apr_status_t md_acme_acct_id_for_md(const char **pid, md_store_t *store,
                                        md_store_group_t group, const md_t *md,
                                        apr_pool_t *p)
    {
        apr_status_t rv;
        find_ctx ctx;
    
        memset(&ctx, 0, sizeof(ctx));
        ctx.p = p;
        ctx.md = md;
    
        rv = md_store_iter(find_acct, &ctx, store, p, group, "*", MD_FN_ACCOUNT, MD_SV_JSON);
        if (ctx.id) {
            *pid = ctx.id;
            rv = APR_SUCCESS;
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "acct_id_for_md %s -> %s", md->name, *pid);
        return rv;
    }
    
    /**************************************************************************************************/
    /* acct operation context */
    typedef struct {
        md_acme_t *acme;
        apr_pool_t *p;
        const char *agreement;
        const char *eab_kid;
        const char *eab_hmac;
    } acct_ctx_t;
    
    /**************************************************************************************************/
    /* acct update */
    
    static apr_status_t on_init_acct_upd(md_acme_req_t *req, void *baton)
    {
        (void)baton;
        return md_acme_req_body_init(req, NULL);
    } 
    
    static apr_status_t acct_upd(md_acme_t *acme, apr_pool_t *p, 
                                 const apr_table_t *hdrs, md_json_t *body, void *baton)
    {
        acct_ctx_t *ctx = baton;
        apr_status_t rv = APR_SUCCESS;
        md_acme_acct_t *acct = acme->acct;
    
        if (md_log_is_level(p, MD_LOG_TRACE2)) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, acme->p, "acct update response: %s",
                          md_json_writep(body, p, MD_JSON_FMT_COMPACT));
        }
    
        if (!acct->url) {
            const char *location = apr_table_get(hdrs, "location");
            if (!location) {
                md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, APR_EINVAL, p, "new acct without location");
                return APR_EINVAL;
            }
            acct->url = apr_pstrdup(ctx->p, location);
        }
        
        apr_array_clear(acct->contacts);
        md_json_dupsa(acct->contacts, acme->p, body, MD_KEY_CONTACT, NULL);
        if (md_json_has_key(body, MD_KEY_STATUS, NULL)) {
            acct->status = acct_st_from_str(md_json_gets(body, MD_KEY_STATUS, NULL));
        }
        if (md_json_has_key(body, MD_KEY_AGREEMENT, NULL)) {
            acct->agreement = md_json_dups(acme->p, body, MD_KEY_AGREEMENT, NULL);
        }
        if (md_json_has_key(body, MD_KEY_ORDERS, NULL)) {
            acct->orders = md_json_dups(acme->p, body, MD_KEY_ORDERS, NULL);
        }
        if (ctx->eab_kid && ctx->eab_hmac) {
            acct->eab_kid = ctx->eab_kid;
            acct->eab_hmac = ctx->eab_hmac;
        }
        acct->registration = md_json_clone(ctx->p, body);
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "updated acct %s", acct->url);
        return rv;
    }
    
    apr_status_t md_acme_acct_update(md_acme_t *acme)
    {
        acct_ctx_t ctx;
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, acme->p, "acct update");
        if (!acme->acct) {
            return APR_EINVAL;
        }
        memset(&ctx, 0, sizeof(ctx));
        ctx.acme = acme;
        ctx.p = acme->p;
        return md_acme_POST(acme, acme->acct->url, on_init_acct_upd, acct_upd, NULL, NULL, &ctx);
    }
    
    apr_status_t md_acme_acct_validate(md_acme_t *acme, md_store_t *store, apr_pool_t *p)
    {
        apr_status_t rv;
        
        if (APR_SUCCESS != (rv = md_acme_acct_update(acme))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, acme->p,
                          "acct update failed for %s", acme->acct->url);
            if (APR_EINVAL == rv && (acme->acct->agreement || !acme->ca_agreement)) {
                /* Sadly, some proprietary ACME servers choke on empty POSTs
                 * on accounts. Try a faked ToS agreement. */
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, acme->p,
                              "trying acct update via ToS agreement");
                rv = md_acme_agree(acme, p, "accepted");
            }
            if (acme->acct && (APR_ENOENT == rv || APR_EACCES == rv || APR_EINVAL == rv)) {
                if (MD_ACME_ACCT_ST_VALID == acme->acct->status) {
                    acme->acct->status = MD_ACME_ACCT_ST_UNKNOWN;
                    if (store) {
                        md_acme_acct_save(store, p, acme, &acme->acct_id, acme->acct, acme->acct_key); 
                    }
                }
                acme->acct = NULL;
                acme->acct_key = NULL;
                rv = APR_ENOENT;
            }
        }
        return rv;
    }
    
    /**************************************************************************************************/
    /* Register a new account */
    
    static apr_status_t get_eab(md_json_t **peab, md_acme_req_t *req, const char *kid,
                                const char *hmac64, md_pkey_t *account_key,
                                const char *url)
    {
        md_json_t *eab, *prot_fields, *jwk;
        md_data_t payload, hmac_key;
        apr_status_t rv;
    
        prot_fields = md_json_create(req->p);
        md_json_sets(url, prot_fields, "url", NULL);
        md_json_sets(kid, prot_fields, "kid", NULL);
    
        rv = md_jws_get_jwk(&jwk, req->p, account_key);
        if (APR_SUCCESS != rv) goto cleanup;
    
        md_data_null(&payload);
        payload.data = md_json_writep(jwk, req->p, MD_JSON_FMT_COMPACT);
        if (!payload.data) {
            rv = APR_EINVAL;
            goto cleanup;
        }
        payload.len = strlen(payload.data);
    
        md_util_base64url_decode(&hmac_key, hmac64, req->p);
        if (!hmac_key.len) {
            rv = APR_EINVAL;
            md_result_problem_set(req->result, rv, "apache:eab-hmac-invalid",
                                  "external account binding HMAC value is not valid base64", NULL);
            goto cleanup;
        }
    
        rv = md_jws_hmac(&eab, req->p, &payload, prot_fields, &hmac_key);
        if (APR_SUCCESS != rv) {
            md_result_problem_set(req->result, rv, "apache:eab-hmac-fail",
                                  "external account binding MAC could not be computed", NULL);
        }
    
    cleanup:
        *peab = (APR_SUCCESS == rv)? eab : NULL;
        return rv;
    }
    
    static apr_status_t on_init_acct_new(md_acme_req_t *req, void *baton)
    {
        acct_ctx_t *ctx = baton;
        md_json_t *jpayload, *jeab;
        apr_status_t rv;
    
        jpayload = md_json_create(req->p);
        md_json_setsa(ctx->acme->acct->contacts, jpayload, MD_KEY_CONTACT, NULL);
        if (ctx->agreement) {
            md_json_setb(1, jpayload, "termsOfServiceAgreed", NULL);
        }
        if (ctx->eab_kid && ctx->eab_hmac) {
            rv = get_eab(&jeab, req, ctx->eab_kid, ctx->eab_hmac,
                         req->acme->acct_key, req->url);
            if (APR_SUCCESS != rv) goto cleanup;
            md_json_setj(jeab, jpayload, "externalAccountBinding", NULL);
        }
        rv = md_acme_req_body_init(req, jpayload);
    
    cleanup:
        return rv;
    } 
    
    apr_status_t md_acme_acct_register(md_acme_t *acme, md_store_t *store,
                                       const md_t *md, apr_pool_t *p)
    {
        apr_status_t rv;
        md_pkey_t *pkey;
        const char *err = NULL, *uri;
        md_pkey_spec_t spec;
        int i;
        acct_ctx_t ctx;
        
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "create new account");
    
        memset(&ctx, 0, sizeof(ctx));
        ctx.acme = acme;
        ctx.p = p;
        /* The agreement URL is submitted when the ACME server announces Terms-of-Service
         * in its directory meta data. The magic value "accepted" will always use the
         * advertised URL. */
        ctx.agreement = NULL;
        if (acme->ca_agreement && md->ca_agreement) {
            ctx.agreement = !strcmp("accepted", md->ca_agreement)?
                acme->ca_agreement : md->ca_agreement;
        }
        
        if (ctx.agreement) {
            if (APR_SUCCESS != (rv = md_util_abs_uri_check(acme->p, ctx.agreement, &err))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, 
                              "invalid agreement uri (%s): %s", err, ctx.agreement);
                goto out;
            }
        }
        ctx.eab_kid = md->ca_eab_kid;
        ctx.eab_hmac = md->ca_eab_hmac;
        
        for (i = 0; i < md->contacts->nelts; ++i) {
            uri = APR_ARRAY_IDX(md->contacts, i, const char *);
            if (APR_SUCCESS != (rv = md_util_abs_uri_check(acme->p, uri, &err))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, 
                              "invalid contact uri (%s): %s", err, uri);
                goto out;
            }
        }
        
        /* If there is no key selected yet, try to find an existing one for the same host. 
         * Let's Encrypt identifies accounts by their key for their ACMEv1 and v2 services.
         * Although the account appears on both services with different urls, it is 
         * internally the same one.
         * I think this is beneficial if someone migrates from ACMEv1 to v2 and not a leak
         * of identifying information.
         */
        if (!acme->acct_key) {
            find_ctx fctx;
    
            memset(&fctx, 0, sizeof(fctx));
            fctx.p = p;
            fctx.md = md;
    
            md_store_iter(find_acct, &fctx, store, p, MD_SG_ACCOUNTS, 
                          mk_acct_pattern(p, acme), MD_FN_ACCOUNT, MD_SV_JSON);
            if (fctx.id) {
                rv = md_store_load(store, MD_SG_ACCOUNTS, fctx.id, MD_FN_ACCT_KEY, MD_SV_PKEY,
                                   (void**)&acme->acct_key, p);
                if (APR_SUCCESS == rv) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
                                  "reusing key from account %s", fctx.id);
                }
                else {
                    acme->acct_key = NULL;
                }
            }
        }
        
        /* If we still have no key, generate a new one */
        if (!acme->acct_key) {
            spec.type = MD_PKEY_TYPE_RSA;
            spec.params.rsa.bits = MD_ACME_ACCT_PKEY_BITS;
            
            if (APR_SUCCESS != (rv = md_pkey_gen(&pkey, acme->p, &spec))) goto out;
            acme->acct_key = pkey;
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "created new account key");
        }
        
        if (APR_SUCCESS != (rv = acct_make(&acme->acct,  p, acme->url, md->contacts))) goto out;
        rv = md_acme_POST_new_account(acme,  on_init_acct_new, acct_upd, NULL, NULL, &ctx);
        if (APR_SUCCESS == rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, p, 
                          "registered new account %s", acme->acct->url);
        }
    
    out:    
        if (APR_SUCCESS != rv && acme->acct) {
            acme->acct = NULL;
        }
        return rv;
    }
    
    /**************************************************************************************************/
    /* Deactivate the account */
    
    static apr_status_t on_init_acct_del(md_acme_req_t *req, void *baton)
    {
        md_json_t *jpayload;
    
        (void)baton;
        jpayload = md_json_create(req->p);
        md_json_sets("deactivated", jpayload, MD_KEY_STATUS, NULL);
        return md_acme_req_body_init(req, jpayload);
    } 
    
    apr_status_t md_acme_acct_deactivate(md_acme_t *acme, apr_pool_t *p)
    {
        md_acme_acct_t *acct = acme->acct;
        acct_ctx_t ctx;
        
        (void)p;
        if (!acct) {
            return APR_EINVAL;
        }
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, acme->p, "delete account %s from %s", 
                      acct->url, acct->ca_url);
        memset(&ctx, 0, sizeof(ctx));
        ctx.acme = acme;
        ctx.p = p;
        return md_acme_POST(acme, acct->url, on_init_acct_del, acct_upd, NULL, NULL, &ctx);
    }
    
    /**************************************************************************************************/
    /* terms-of-service */
    
    static apr_status_t on_init_agree_tos(md_acme_req_t *req, void *baton)
    {
        acct_ctx_t *ctx = baton;
        md_json_t *jpayload;
    
        jpayload = md_json_create(req->p);
        if (ctx->acme->acct->agreement) {
            md_json_setb(1, jpayload, "termsOfServiceAgreed", NULL);
        }
        return md_acme_req_body_init(req, jpayload);
    } 
    
    apr_status_t md_acme_agree(md_acme_t *acme, apr_pool_t *p, const char *agreement)
    {
        acct_ctx_t ctx;
        
        acme->acct->agreement = agreement;
        if (!strcmp("accepted", agreement) && acme->ca_agreement) {
            acme->acct->agreement = acme->ca_agreement;
        }
        
        memset(&ctx, 0, sizeof(ctx));
        ctx.acme = acme;
        ctx.p = p;
        return md_acme_POST(acme, acme->acct->url, on_init_agree_tos, acct_upd, NULL, NULL, &ctx);
    }
    
    apr_status_t md_acme_check_agreement(md_acme_t *acme, apr_pool_t *p, 
                                         const char *agreement, const char **prequired)
    {
        apr_status_t rv = APR_SUCCESS;
        
        /* We used to really check if the account agreement and the one indicated in meta
         * are the very same. However, LE is happy if the account has agreed to a ToS in 
         * the past and does not require a renewed acceptance.
         */
        *prequired = NULL;
        if (!acme->acct->agreement && acme->ca_agreement) {
            if (agreement) {
                rv = md_acme_agree(acme, p, acme->ca_agreement);
            }
            else {
                *prequired = acme->ca_agreement;
                rv = APR_INCOMPLETE;
            }
        }
        return rv;
    }        
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/config2.m4������������������������������������������������������������������0000664�0001751�0001751�00000026145�14232231062�016466� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl Licensed to the Apache Software Foundation (ASF) under one or more
    dnl contributor license agreements.  See the NOTICE file distributed with
    dnl this work for additional information regarding copyright ownership.
    dnl The ASF licenses this file to You under the Apache License, Version 2.0
    dnl (the "License"); you may not use this file except in compliance with
    dnl the License.  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.
    
    dnl
    dnl APACHE_CHECK_CURL
    dnl
    dnl Configure for libcurl, giving preference to
    dnl "--with-curl=<path>" if it was specified.
    dnl
    AC_DEFUN([APACHE_CHECK_CURL],[
      AC_CACHE_CHECK([for curl], [ac_cv_curl], [
        dnl initialise the variables we use
        ac_cv_curl=no
        ap_curl_found=""
        ap_curl_base=""
        ap_curl_libs=""
    
        dnl Determine the curl base directory, if any
        AC_MSG_CHECKING([for user-provided curl base directory])
        AC_ARG_WITH(curl, APACHE_HELP_STRING(--with-curl=PATH, curl installation directory), [
          dnl If --with-curl specifies a directory, we use that directory
          if test "x$withval" != "xyes" -a "x$withval" != "x"; then
            dnl This ensures $withval is actually a directory and that it is absolute
            ap_curl_base="`cd $withval ; pwd`"
          fi
        ])
        if test "x$ap_curl_base" = "x"; then
          AC_MSG_RESULT(none)
        else
          AC_MSG_RESULT($ap_curl_base)
        fi
    
        dnl Run header and version checks
        saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
        dnl Before doing anything else, load in pkg-config variables
        if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          AC_MSG_CHECKING([for pkg-config along $PKG_CONFIG_PATH])
          if test "x$ap_curl_base" != "x" ; then
            if test -f "${ap_curl_base}/lib/pkgconfig/libcurl.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system libcurl.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_curl_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_curl_base}/lib64/pkgconfig/libcurl.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system libcurl.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_curl_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          AC_ARG_ENABLE(curl-staticlib-deps,APACHE_HELP_STRING(--enable-curl-staticlib-deps,[link mod_md with dependencies of libcurl's static libraries (as indicated by "pkg-config --static"). Must be specified in addition to --enable-md.]), [
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
          ])
          ap_curl_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libcurl`"
          if test $? -eq 0; then
            ap_curl_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I libcurl`"
            APR_ADDTO(CPPFLAGS, [$pkglookup])
            APR_ADDTO(MOD_CFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libcurl`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libcurl`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
        dnl fall back to the user-supplied directory if not found via pkg-config
        if test "x$ap_curl_base" != "x" -a "x$ap_curl_found" = "x"; then
          APR_ADDTO(CPPFLAGS, [-I$ap_curl_base/include])
          APR_ADDTO(MOD_CFLAGS, [-I$ap_curl_base/include])
          APR_ADDTO(LDFLAGS, [-L$ap_curl_base/lib])
          APR_ADDTO(MOD_LDFLAGS, [-L$ap_curl_base/lib])
          if test "x$ap_platform_runtime_link_flag" != "x"; then
            APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_curl_base/lib])
            APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_curl_base/lib])
          fi
        fi
    
        AC_CHECK_HEADERS([curl/curl.h])
    
        AC_MSG_CHECKING([for curl version >= 7.29])
        AC_TRY_COMPILE([#include <curl/curlver.h>],[
    #if !defined(LIBCURL_VERSION_MAJOR)
    #error "Missing libcurl version"
    #endif
    #if LIBCURL_VERSION_MAJOR < 7
    #error "Unsupported libcurl version " LIBCURL_VERSION
    #endif
    #if LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR < 29
    #error "Unsupported libcurl version " LIBCURL_VERSION
    #endif],
          [AC_MSG_RESULT(OK)
           ac_cv_curl=yes],
          [AC_MSG_RESULT(FAILED)])
    
        if test "x$ac_cv_curl" = "xyes"; then
          ap_curl_libs="${ap_curl_libs:--lcurl} `$apr_config --libs`"
          APR_ADDTO(MOD_LDFLAGS, [$ap_curl_libs])
          APR_ADDTO(LIBS, [$ap_curl_libs])
        fi
    
        dnl restore
        CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
      ])
      if test "x$ac_cv_curl" = "xyes"; then
        AC_DEFINE(HAVE_CURL, 1, [Define if curl is available])
      fi
    ])
    
    
    dnl
    dnl APACHE_CHECK_JANSSON
    dnl
    dnl Configure for libjansson, giving preference to
    dnl "--with-jansson=<path>" if it was specified.
    dnl
    AC_DEFUN([APACHE_CHECK_JANSSON],[
      AC_CACHE_CHECK([for jansson], [ac_cv_jansson], [
        dnl initialise the variables we use
        ac_cv_jansson=no
        ap_jansson_found=""
        ap_jansson_base=""
        ap_jansson_libs=""
    
        dnl Determine the jansson base directory, if any
        AC_MSG_CHECKING([for user-provided jansson base directory])
        AC_ARG_WITH(jansson, APACHE_HELP_STRING(--with-jansson=PATH, jansson installation directory), [
          dnl If --with-jansson specifies a directory, we use that directory
          if test "x$withval" != "xyes" -a "x$withval" != "x"; then
            dnl This ensures $withval is actually a directory and that it is absolute
            ap_jansson_base="`cd $withval ; pwd`"
          fi
        ])
        if test "x$ap_jansson_base" = "x"; then
          AC_MSG_RESULT(none)
        else
          AC_MSG_RESULT($ap_jansson_base)
        fi
    
        dnl Run header and version checks
        saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
        dnl Before doing anything else, load in pkg-config variables
        if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          AC_MSG_CHECKING([for pkg-config along $PKG_CONFIG_PATH])
          if test "x$ap_jansson_base" != "x" ; then
            if test -f "${ap_jansson_base}/lib/pkgconfig/libjansson.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system libjansson.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_jansson_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_jansson_base}/lib64/pkgconfig/libjansson.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system libjansson.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_jansson_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          AC_ARG_ENABLE(jansson-staticlib-deps,APACHE_HELP_STRING(--enable-jansson-staticlib-deps,[link mod_md with dependencies of libjansson's static libraries (as indicated by "pkg-config --static"). Must be specified in addition to --enable-md.]), [
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
          ])
          ap_jansson_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libjansson`"
          if test $? -eq 0; then
            ap_jansson_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I libjansson`"
            APR_ADDTO(CPPFLAGS, [$pkglookup])
            APR_ADDTO(MOD_CFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libjansson`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libjansson`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
        dnl fall back to the user-supplied directory if not found via pkg-config
        if test "x$ap_jansson_base" != "x" -a "x$ap_jansson_found" = "x"; then
          APR_ADDTO(CPPFLAGS, [-I$ap_jansson_base/include])
          APR_ADDTO(MOD_CFLAGS, [-I$ap_jansson_base/include])
          APR_ADDTO(LDFLAGS, [-L$ap_jansson_base/lib])
          APR_ADDTO(MOD_LDFLAGS, [-L$ap_jansson_base/lib])
          if test "x$ap_platform_runtime_link_flag" != "x"; then
            APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_jansson_base/lib])
            APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_jansson_base/lib])
          fi
        fi
    
        # attempts to include jansson.h fail me. So lets make sure we can at least
        # include its other header file
        AC_TRY_COMPILE([#include <jansson_config.h>],[],
          [AC_MSG_RESULT(OK) 
           ac_cv_jansson=yes], 
           [AC_MSG_RESULT(FAILED)])
    
        if test "x$ac_cv_jansson" = "xyes"; then
          ap_jansson_libs="${ap_jansson_libs:--ljansson} `$apr_config --libs`"
          APR_ADDTO(MOD_LDFLAGS, [$ap_jansson_libs])
          APR_ADDTO(LIBS, [$ap_jansson_libs])
        fi
    
        dnl restore
        CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
      ])
      if test "x$ac_cv_jansson" = "xyes"; then
        AC_DEFINE(HAVE_JANSSON, 1, [Define if jansson is available])
      fi
    ])
    
    
    dnl #  start of module specific part
    APACHE_MODPATH_INIT(md)
    
    dnl #  list of module object files
    md_objs="dnl
    md_acme.lo dnl
    md_acme_acct.lo dnl
    md_acme_authz.lo dnl
    md_acme_drive.lo dnl
    md_acmev2_drive.lo dnl
    md_acme_order.lo dnl
    md_core.lo dnl
    md_curl.lo dnl
    md_crypt.lo dnl
    md_event.lo dnl
    md_http.lo dnl
    md_json.lo dnl
    md_jws.lo dnl
    md_log.lo dnl
    md_ocsp.lo dnl
    md_result.lo dnl
    md_reg.lo dnl
    md_status.lo dnl
    md_store.lo dnl
    md_store_fs.lo dnl
    md_tailscale.lo dnl
    md_time.lo dnl
    md_util.lo dnl
    mod_md.lo dnl
    mod_md_config.lo dnl
    mod_md_drive.lo dnl
    mod_md_ocsp.lo dnl
    mod_md_os.lo dnl
    mod_md_status.lo dnl
    "
    
    # Ensure that other modules can pick up mod_md.h
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    dnl # hook module into the Autoconf mechanism (--enable-md)
    APACHE_MODULE(md, [Managed Domain handling], $md_objs, , most, [
        APACHE_CHECK_OPENSSL
        if test "x$ac_cv_openssl" = "xno" ; then
            AC_MSG_WARN([libssl (or compatible) not found])
            enable_md=no
        fi
        
        APACHE_CHECK_JANSSON
        if test "x$ac_cv_jansson" != "xyes" ; then
            AC_MSG_WARN([libjansson not found])
            enable_md=no
        fi
    
        APACHE_CHECK_CURL
        if test "x$ac_cv_curl" != "xyes" ; then
            AC_MSG_WARN([libcurl not found])
            enable_md=no
        fi
        
        AC_CHECK_FUNCS([arc4random_buf], 
            [APR_ADDTO(MOD_CPPFLAGS, ["-DMD_HAVE_ARC4RANDOM"])], [])
    
        if test "x$enable_md" = "xshared"; then
           APR_ADDTO(MOD_MD_LDADD, [-export-symbols-regex md_module])
        fi
    ])
    
    dnl #  end of module specific part
    APACHE_MODPATH_FINISH
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_acme_acct.h��������������������������������������������������������������0000664�0001751�0001751�00000013173�14147416411�017432� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_acme_acct_h
    #define mod_md_md_acme_acct_h
    
    struct md_acme_req;
    struct md_json_t;
    struct md_pkey_t;
    
    #include "md_store.h"
    
    /** 
     * An ACME account at an ACME server.
     */
    typedef struct md_acme_acct_t md_acme_acct_t;
    
    typedef enum {
        MD_ACME_ACCT_ST_UNKNOWN,
        MD_ACME_ACCT_ST_VALID,
        MD_ACME_ACCT_ST_DEACTIVATED,
        MD_ACME_ACCT_ST_REVOKED,
    } md_acme_acct_st;
    
    struct md_acme_acct_t {
        const char *id;                 /* short, unique id for the account */
        const char *url;                /* url of the account, once registered */
        const char *ca_url;             /* url of the ACME protocol endpoint */
        md_acme_acct_st status;         /* status of this account */
        apr_array_header_t *contacts;   /* list of contact uris, e.g. mailto:xxx */
        const char *tos_required;       /* terms of service asked for by CA */
        const char *agreement;          /* terms of service agreed to by user */
        const char *orders;             /* URL where certificate orders are found (ACMEv2) */
        const char *eab_kid;            /* external account binding keyid used or NULL */
        const char *eab_hmac;           /* external account binding hmac used or NULL */
        struct md_json_t *registration; /* data from server registration */
    };
    
    #define MD_FN_ACCOUNT           "account.json"
    #define MD_FN_ACCT_KEY          "account.pem"
    
    /* ACME account private keys are always RSA and have that many bits. Since accounts
     * are expected to live long, better err on the safe side. */
    #define MD_ACME_ACCT_PKEY_BITS  3072
    
    #define MD_ACME_ACCT_STAGED     "staged"
    
    /**
     * Convert an ACME account form/to JSON.
     */
    struct md_json_t *md_acme_acct_to_json(md_acme_acct_t *acct, apr_pool_t *p);
    apr_status_t md_acme_acct_from_json(md_acme_acct_t **pacct, struct md_json_t *json, apr_pool_t *p);
    
    /**
     * Update the account from the ACME server.
     * - Will update acme->acct structure from server on success
     * - Will return error status when request failed or account is not known.
     */
    apr_status_t md_acme_acct_update(md_acme_t *acme);
    
    /**
     * Update the account and persist changes in the store, if given (and not NULL).
     */
    apr_status_t md_acme_acct_validate(md_acme_t *acme, md_store_t *store, apr_pool_t *p);
    
    /**
     * Agree to the given Terms-of-Service url for the current account.
     */
    apr_status_t md_acme_agree(md_acme_t *acme, apr_pool_t *p, const char *tos);
    
    /**
     * Confirm with the server that the current account agrees to the Terms-of-Service
     * given in the agreement url.
     * If the known agreement is equal to this, nothing is done.
     * If it differs, the account is re-validated in the hope that the server
     * announces the Tos URL it wants. If this is equal to the agreement specified,
     * the server is notified of this. If the server requires a ToS that the account
     * thinks it has already given, it is resend.
     *
     * If an agreement is required, different from the current one, APR_INCOMPLETE is
     * returned and the agreement url is returned in the parameter.
     */
    apr_status_t md_acme_check_agreement(md_acme_t *acme, apr_pool_t *p, 
                                         const char *agreement, const char **prequired);
    
    /**
     * Get the ToS agreement for current account.
     */
    const char *md_acme_get_agreement(md_acme_t *acme);
    
    
    /** 
     * Find an existing account in the local store. On APR_SUCCESS, the acme
     * instance will have a current, validated account to use.
     */ 
    apr_status_t md_acme_find_acct_for_md(md_acme_t *acme, md_store_t *store, const md_t *md);
    
    /**
     * Find the account id for a given md.
     */
    apr_status_t md_acme_acct_id_for_md(const char **pid, md_store_t *store,
                                        md_store_group_t group, const md_t *md, apr_pool_t *p);
    
    /**
     * Create a new account at the ACME server for an MD. The
     * new account is the one used by the acme instance afterwards, on success.
     */
    apr_status_t md_acme_acct_register(md_acme_t *acme, md_store_t *store, 
                                       const md_t *md, apr_pool_t *p);
    
    apr_status_t md_acme_acct_save(md_store_t *store, apr_pool_t *p, md_acme_t *acme,  
                                   const char **pid, struct md_acme_acct_t *acct, 
                                   struct md_pkey_t *acct_key);
                                   
    /**
     * Deactivate the current account at the ACME server. 
     */
    apr_status_t md_acme_acct_deactivate(md_acme_t *acme, apr_pool_t *p);
    
    apr_status_t md_acme_acct_load(struct md_acme_acct_t **pacct, struct md_pkey_t **ppkey,
                                   md_store_t *store, md_store_group_t group, 
                                   const char *name, apr_pool_t *p);
    
    /*
     * Return != 0 iff the account can be used for the ACME url.
     */
    int md_acme_acct_matches_url(md_acme_acct_t *acct, const char *url);
    
    /*
     * Return != 0 iff the account can be used for the MD, including
     * its CA url and EAB settings.
     */
    int md_acme_acct_matches_md(md_acme_acct_t *acct, const md_t *md);
    
    #endif /* md_acme_acct_h */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_ocsp.c�������������������������������������������������������������������0000664�0001751�0001751�00000107461�14726304510�016475� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <apr_lib.h>
    #include <apr_buckets.h>
    #include <apr_hash.h>
    #include <apr_time.h>
    #include <apr_date.h>
    #include <apr_strings.h>
    #include <apr_thread_mutex.h>
    
    #include <openssl/err.h>
    #include <openssl/evp.h>
    #include <openssl/ocsp.h>
    #include <openssl/pem.h>
    #include <openssl/x509v3.h>
    
    #include "md.h"
    #include "md_crypt.h"
    #include "md_event.h"
    #include "md_json.h"
    #include "md_log.h"
    #include "md_http.h"
    #include "md_json.h"
    #include "md_result.h"
    #include "md_status.h"
    #include "md_store.h"
    #include "md_util.h"
    #include "md_ocsp.h"
    
    #define MD_OCSP_ID_LENGTH   SHA_DIGEST_LENGTH
       
    struct md_ocsp_reg_t {
        apr_pool_t *p;
        md_store_t *store;
        const char *user_agent;
        const char *proxy_url;
        apr_hash_t *id_by_external_id;
        apr_hash_t *ostat_by_id;
        apr_thread_mutex_t *mutex;
        md_timeslice_t renew_window;
        md_job_notify_cb *notify;
        void *notify_ctx;
        apr_time_t min_delay;
    };
    
    typedef struct md_ocsp_status_t md_ocsp_status_t; 
    struct md_ocsp_status_t {
        md_data_t id;
        const char *hexid;
        const char *hex_sha256;
        OCSP_CERTID *certid;
        const char *responder_url;
        
        apr_time_t next_run;      /* when the responder shall be asked again */
        int errors;               /* consecutive failed attempts */
    
        md_ocsp_cert_stat_t resp_stat;
        md_data_t resp_der;
        md_timeperiod_t resp_valid;
        
        md_data_t req_der;
        OCSP_REQUEST *ocsp_req;
        md_ocsp_reg_t *reg;
    
        const char *md_name;
        const char *file_name;
        
        apr_time_t resp_mtime;
        apr_time_t resp_last_check;
    };
    
    typedef struct md_ocsp_id_map_t md_ocsp_id_map_t;
    struct md_ocsp_id_map_t {
        md_data_t id;
        md_data_t external_id;
    };
    
    static void md_openssl_free(void *d)
    {
        OPENSSL_free(d);
    }
    
    const char *md_ocsp_cert_stat_name(md_ocsp_cert_stat_t stat)
    {
        switch (stat) {
            case MD_OCSP_CERT_ST_GOOD: return "good";
            case MD_OCSP_CERT_ST_REVOKED: return "revoked";
            default: return "unknown";
        }
    }
    
    md_ocsp_cert_stat_t md_ocsp_cert_stat_value(const char *name)
    {
        if (name && !strcmp("good", name)) return MD_OCSP_CERT_ST_GOOD;
        if (name && !strcmp("revoked", name)) return MD_OCSP_CERT_ST_REVOKED;
        return MD_OCSP_CERT_ST_UNKNOWN;
    }
    
    apr_status_t md_ocsp_init_id(md_data_t *id, apr_pool_t *p, const md_cert_t *cert)
    {
        unsigned char iddata[SHA_DIGEST_LENGTH];
        X509 *x = md_cert_get_X509(cert);
        unsigned int ulen = 0;
        
        md_data_null(id);
        if (X509_digest(x, EVP_sha1(), iddata, &ulen) != 1) {
            return APR_EGENERAL;
        }
        md_data_assign_pcopy(id, (const char*)iddata, ulen, p);
        return APR_SUCCESS;
    }
    
    static void ostat_req_cleanup(md_ocsp_status_t *ostat)
    {
        if (ostat->ocsp_req) {
            OCSP_REQUEST_free(ostat->ocsp_req);
            ostat->ocsp_req = NULL;
        }
        md_data_clear(&ostat->req_der);
    }
    
    static int ostat_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val)
    {
        md_ocsp_reg_t *reg = ctx;
        md_ocsp_status_t *ostat = (md_ocsp_status_t *)val;
        
        (void)reg;
        (void)key;
        (void)klen;
        ostat_req_cleanup(ostat);
        if (ostat->certid) {
            OCSP_CERTID_free(ostat->certid);
            ostat->certid = NULL;
        }
        md_data_clear(&ostat->resp_der);
        return 1;
    }
    
    static int ostat_should_renew(md_ocsp_status_t *ostat) 
    {
        md_timeperiod_t renewal;
        
        renewal = md_timeperiod_slice_before_end(&ostat->resp_valid, &ostat->reg->renew_window);
        return md_timeperiod_has_started(&renewal, apr_time_now());
    }  
    
    static apr_status_t ostat_set(md_ocsp_status_t *ostat, md_ocsp_cert_stat_t stat,
                                  md_data_t *der, md_timeperiod_t *valid, apr_time_t mtime)
    {
        apr_status_t rv;
    
        rv = md_data_assign_copy(&ostat->resp_der, der->data, der->len);
        if (APR_SUCCESS != rv) goto cleanup;
    
        ostat->resp_stat = stat;
        ostat->resp_valid = *valid;
        ostat->resp_mtime = mtime;
        
        ostat->errors = 0;
        ostat->next_run = md_timeperiod_slice_before_end(
            &ostat->resp_valid, &ostat->reg->renew_window).start;
        
    cleanup:
        return rv;
    }
    
    static apr_status_t ostat_from_json(md_ocsp_cert_stat_t *pstat, 
                                        md_data_t *resp_der, md_timeperiod_t *resp_valid, 
                                        md_json_t *json, apr_pool_t *p)
    {
        const char *s;
        md_timeperiod_t valid;
        apr_status_t rv = APR_ENOENT;
        
        memset(resp_der, 0, sizeof(*resp_der));
        memset(resp_valid, 0, sizeof(*resp_valid));
        s = md_json_dups(p, json, MD_KEY_VALID, MD_KEY_FROM, NULL);
        if (s && *s) valid.start = apr_date_parse_rfc(s);
        s = md_json_dups(p, json, MD_KEY_VALID, MD_KEY_UNTIL, NULL);
        if (s && *s) valid.end = apr_date_parse_rfc(s);
        s = md_json_dups(p, json, MD_KEY_RESPONSE, NULL);
        if (!s || !*s) goto cleanup;
        md_util_base64url_decode(resp_der, s, p);
        *pstat = md_ocsp_cert_stat_value(md_json_gets(json, MD_KEY_STATUS, NULL));
        *resp_valid = valid;
        rv = APR_SUCCESS;
    cleanup:
        return rv;
    }
    
    static void ostat_to_json(md_json_t *json, md_ocsp_cert_stat_t stat,
                              const md_data_t *resp_der, const md_timeperiod_t *resp_valid, 
                              apr_pool_t *p)
    {
        const char *s = NULL;
    
        if (resp_der->len > 0) {
            md_json_sets(md_util_base64url_encode(resp_der, p), json, MD_KEY_RESPONSE, NULL);
            s = md_ocsp_cert_stat_name(stat);
            if (s) md_json_sets(s, json, MD_KEY_STATUS, NULL);
            md_json_set_timeperiod(resp_valid, json, MD_KEY_VALID, NULL);
        }
    }
    
    static apr_status_t ocsp_status_refresh(md_ocsp_status_t *ostat, apr_pool_t *ptemp)
    {
        md_store_t *store = ostat->reg->store;
        md_json_t *jprops;
        apr_time_t mtime;
        apr_status_t rv = APR_EAGAIN;
        md_data_t resp_der;
        md_timeperiod_t resp_valid;
        md_ocsp_cert_stat_t resp_stat;
        /* Check if the store holds a newer response than the one we have */
        mtime = md_store_get_modified(store, MD_SG_OCSP, ostat->md_name, ostat->file_name, ptemp);
        if (mtime <= ostat->resp_mtime) goto cleanup;
        rv = md_store_load_json(store, MD_SG_OCSP, ostat->md_name, ostat->file_name, &jprops, ptemp);
        if (APR_SUCCESS != rv) goto cleanup;
        rv = ostat_from_json(&resp_stat, &resp_der, &resp_valid, jprops, ptemp);
        if (APR_SUCCESS != rv) goto cleanup;
        rv = ostat_set(ostat, resp_stat, &resp_der, &resp_valid, mtime);
        if (APR_SUCCESS != rv) goto cleanup;
    cleanup:
        return rv;
    }
    
    
    static apr_status_t ocsp_status_save(md_ocsp_cert_stat_t stat, const md_data_t *resp_der, 
                                         const md_timeperiod_t *resp_valid,
                                         md_ocsp_status_t *ostat, apr_pool_t *ptemp)
    {
        md_store_t *store = ostat->reg->store;
        md_json_t *jprops;
        apr_time_t mtime;
        apr_status_t rv;
        
        jprops = md_json_create(ptemp);
        ostat_to_json(jprops, stat, resp_der, resp_valid, ptemp);
        rv = md_store_save_json(store, ptemp, MD_SG_OCSP, ostat->md_name, ostat->file_name, jprops, 0);
        if (APR_SUCCESS != rv) goto cleanup;
        mtime = md_store_get_modified(store, MD_SG_OCSP, ostat->md_name, ostat->file_name, ptemp);
        if (mtime) ostat->resp_mtime = mtime;
    cleanup:
        return rv;
    }
    
    static apr_status_t ocsp_reg_cleanup(void *data)
    {
        md_ocsp_reg_t *reg = data;
        
        /* free all OpenSSL structures that we hold */
        apr_hash_do(ostat_cleanup, reg, reg->ostat_by_id);
        return APR_SUCCESS;
    }
    
    apr_status_t md_ocsp_reg_make(md_ocsp_reg_t **preg, apr_pool_t *p, md_store_t *store, 
                                  const md_timeslice_t *renew_window,
                                  const char *user_agent, const char *proxy_url,
                                  apr_time_t min_delay)
    {
        md_ocsp_reg_t *reg;
        apr_status_t rv = APR_SUCCESS;
        
        reg = apr_palloc(p, sizeof(*reg));
        if (!reg) {
            rv = APR_ENOMEM;
            goto cleanup;
        }
        reg->p = p;
        reg->store = store;
        reg->user_agent = user_agent;
        reg->proxy_url = proxy_url;
        reg->id_by_external_id = apr_hash_make(p);
        reg->ostat_by_id = apr_hash_make(p);
        reg->renew_window = *renew_window;
        reg->min_delay = min_delay;
        
        rv = apr_thread_mutex_create(&reg->mutex, APR_THREAD_MUTEX_NESTED, p);
        if (APR_SUCCESS != rv) goto cleanup;
    
        apr_pool_cleanup_register(p, reg, ocsp_reg_cleanup, apr_pool_cleanup_null);
    cleanup:
        *preg = (APR_SUCCESS == rv)? reg : NULL;
        return rv;
    }
    
    apr_status_t md_ocsp_prime(md_ocsp_reg_t *reg, const char *ext_id, apr_size_t ext_id_len,
                               md_cert_t *cert, md_cert_t *issuer, const md_t *md)
    {
        md_ocsp_status_t *ostat;
        const char *name;
        md_data_t id;
        apr_status_t rv = APR_SUCCESS;
        
        /* Called during post_config. no mutex protection needed */
        name = md? md->name : MD_OTHER;
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, reg->p,
                      "md[%s]: priming OCSP status", name);
    
        rv = md_ocsp_init_id(&id, reg->p, cert);
        if (APR_SUCCESS != rv) goto cleanup;
    
        ostat = apr_hash_get(reg->ostat_by_id, id.data, (apr_ssize_t)id.len);
        if (ostat) goto cleanup; /* already seen it, cert is used in >1 server_rec */
    
        ostat = apr_pcalloc(reg->p, sizeof(*ostat));
        ostat->id = id;
        ostat->reg = reg;
        ostat->md_name = name;
        md_data_to_hex(&ostat->hexid, 0, reg->p, &ostat->id);
        ostat->file_name = apr_psprintf(reg->p, "ocsp-%s.json", ostat->hexid);
        rv = md_cert_to_sha256_fingerprint(&ostat->hex_sha256, cert, reg->p); 
        if (APR_SUCCESS != rv) goto cleanup;
    
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, 
                      "md[%s]: getting ocsp responder from cert", name);
        rv = md_cert_get_ocsp_responder_url(&ostat->responder_url, reg->p, cert);
        if (APR_SUCCESS != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, reg->p,
                          "md[%s]: certificate with serial %s has no OCSP responder URL",
                          name, md_cert_get_serial_number(cert, reg->p));
            goto cleanup;
        }
    
        ostat->certid = OCSP_cert_to_id(NULL, md_cert_get_X509(cert), md_cert_get_X509(issuer));
        if (!ostat->certid) {
            rv = APR_EGENERAL;
            md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, reg->p, 
                          "md[%s]: unable to create OCSP certid for certificate with serial %s", 
                          name, md_cert_get_serial_number(cert, reg->p));
            goto cleanup;
        }
        
        /* See, if we have something in store */
        ocsp_status_refresh(ostat, reg->p);
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, reg->p, 
                      "md[%s]: adding ocsp info (responder=%s)", 
                      name, ostat->responder_url);
        apr_hash_set(reg->ostat_by_id, ostat->id.data, (apr_ssize_t)ostat->id.len, ostat);
        if (ext_id) {
            md_ocsp_id_map_t *id_map;
    
            id_map = apr_pcalloc(reg->p, sizeof(*id_map));
            id_map->id = id;
            md_data_assign_pcopy(&id_map->external_id, ext_id, ext_id_len, reg->p);
            /* check for collision/uniqness? */
            apr_hash_set(reg->id_by_external_id, id_map->external_id.data,
                         (apr_ssize_t)id_map->external_id.len, id_map);
        }
        rv = APR_SUCCESS;
    cleanup:
        return rv;
    }
    
    apr_status_t md_ocsp_get_status(md_ocsp_copy_der *cb, void *userdata, md_ocsp_reg_t *reg,
                                    const char *ext_id, apr_size_t ext_id_len,
                                    apr_pool_t *p, const md_t *md)
    {
        md_ocsp_status_t *ostat;
        const char *name;
        apr_status_t rv = APR_SUCCESS;
        md_ocsp_id_map_t *id_map;
        const char *id;
        apr_size_t id_len;
        int locked = 0;
    
        (void)p;
        (void)md;
        name = md? md->name : MD_OTHER;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, 
                      "md[%s]: OCSP, get_status", name);
    
        id_map = apr_hash_get(reg->id_by_external_id, ext_id, (apr_ssize_t)ext_id_len);
        id = id_map? id_map->id.data : ext_id;
        id_len = id_map? id_map->id.len : ext_id_len;
        ostat = apr_hash_get(reg->ostat_by_id, id, (apr_ssize_t)id_len);
        if (!ostat) {
            rv = APR_ENOENT;
            goto cleanup;
        }
        
        /* While the ostat instance itself always exists, the response data it holds
         * may vary over time and we need locked access to make a copy. */
        apr_thread_mutex_lock(reg->mutex);
        locked = 1;
        
        if (ostat->resp_der.len <= 0) {
            /* No response known, check store for new response. */
            ocsp_status_refresh(ostat, p);
            if (ostat->resp_der.len <= 0) {
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, 
                              "md[%s]: OCSP, no response available", name);
                cb(NULL, 0, userdata);
                goto cleanup;
            }
        }
        /* We have a response */
        if (ostat_should_renew(ostat)) {
            /* But it is up for renewal. A watchdog should be busy with
             * retrieving a new one. In case of outages, this might take
             * a while, however. Pace the frequency of checks with the
             * urgency of a new response based on the remaining time. */
            long secs = (long)apr_time_sec(md_timeperiod_remaining(&ostat->resp_valid, apr_time_now()));
            apr_time_t waiting_time; 
            
            /* every hour, every minute, every second */
            waiting_time = ((secs >= MD_SECS_PER_DAY)?
                            apr_time_from_sec(60 * 60) : ((secs >= 60)? 
                            apr_time_from_sec(60) : apr_time_from_sec(1)));
            if ((apr_time_now() - ostat->resp_last_check) >= waiting_time) {
                ostat->resp_last_check = apr_time_now();
                ocsp_status_refresh(ostat, p);
            }
        }
    
        cb((const unsigned char*)ostat->resp_der.data, ostat->resp_der.len, userdata);
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p,
                      "md[%s]: OCSP, provided %ld bytes of response",
                      name, (long)ostat->resp_der.len);
    cleanup:
        if (locked) apr_thread_mutex_unlock(reg->mutex);
        return rv;
    }
    
    static void ocsp_get_meta(md_ocsp_cert_stat_t *pstat, md_timeperiod_t *pvalid, 
                              md_ocsp_reg_t *reg, md_ocsp_status_t *ostat, apr_pool_t *p)
    {
        apr_thread_mutex_lock(reg->mutex);
        if (ostat->resp_der.len <= 0) {
            /* No response known, check the store if out watchdog retrieved one 
             * in the meantime. */
            ocsp_status_refresh(ostat, p);
        }
        *pvalid = ostat->resp_valid;
        *pstat = ostat->resp_stat;
        apr_thread_mutex_unlock(reg->mutex);
    }
    
    apr_status_t md_ocsp_get_meta(md_ocsp_cert_stat_t *pstat, md_timeperiod_t *pvalid,
                                  md_ocsp_reg_t *reg, const md_cert_t *cert,
                                  apr_pool_t *p, const md_t *md)
    {
        md_ocsp_status_t *ostat;
        const char *name;
        apr_status_t rv;
        md_timeperiod_t valid;
        md_ocsp_cert_stat_t stat;
        md_data_t id;
        
        (void)p;
        (void)md;
        name = md? md->name : MD_OTHER;
        memset(&valid, 0, sizeof(valid));
        stat = MD_OCSP_CERT_ST_UNKNOWN;
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, 
                      "md[%s]: OCSP, get_status", name);
        
        rv = md_ocsp_init_id(&id, p, cert);
        if (APR_SUCCESS != rv) goto cleanup;
        
        ostat = apr_hash_get(reg->ostat_by_id, id.data, (apr_ssize_t)id.len);
        if (!ostat) {
            rv = APR_ENOENT;
            goto cleanup;
        }
        ocsp_get_meta(&stat, &valid, reg, ostat, p);
    cleanup:
        *pstat = stat;
        *pvalid = valid;  
        return rv;
    }
    
    apr_size_t md_ocsp_count(md_ocsp_reg_t *reg)
    {
        return apr_hash_count(reg->ostat_by_id);
    }
    
    static const char *certid_as_hex(const OCSP_CERTID *certid, apr_pool_t *p)
    {
        md_data_t der;
        const char *hex;
        
        memset(&der, 0, sizeof(der));
        der.len = (apr_size_t)i2d_OCSP_CERTID((OCSP_CERTID*)certid, (unsigned char**)&der.data);
        der.free_data = md_openssl_free;
        md_data_to_hex(&hex, 0, p, &der);
        md_data_clear(&der);
        return hex;
    }
    
    static const char *certid_summary(const OCSP_CERTID *certid, apr_pool_t *p)
    {
        const char *serial, *issuer, *key, *s;
        ASN1_INTEGER *aserial;
        ASN1_OCTET_STRING *aname_hash, *akey_hash;
        ASN1_OBJECT *amd_nid;
        BIGNUM *bn; 
        md_data_t data;
        
        serial = issuer = key = "???";
        OCSP_id_get0_info(&aname_hash, &amd_nid, &akey_hash, &aserial, (OCSP_CERTID*)certid);
        if (aname_hash) {
            data.len = (apr_size_t)aname_hash->length;
            data.data = (const char*)aname_hash->data;
            md_data_to_hex(&issuer, 0, p, &data);
        }
        if (akey_hash) {
            data.len = (apr_size_t)akey_hash->length;
            data.data = (const char*)akey_hash->data;
            md_data_to_hex(&key, 0, p, &data);
        }
        if (aserial) {
            bn = ASN1_INTEGER_to_BN(aserial, NULL);
            s = BN_bn2hex(bn);
            serial = apr_pstrdup(p, s);
            OPENSSL_free((void*)bn);
            OPENSSL_free((void*)s);
        }
        return apr_psprintf(p, "certid[der=%s, issuer=%s, key=%s, serial=%s]",
                            certid_as_hex(certid, p), issuer, key, serial);
    }
    
    static const char *certstatus_string(int status)
    {
        switch (status) {
            case V_OCSP_CERTSTATUS_GOOD: return "good";
            case V_OCSP_CERTSTATUS_REVOKED: return "revoked";
            case V_OCSP_CERTSTATUS_UNKNOWN: return "unknown";
            default: return "???";
        }
    
    }
    
    static const char *single_resp_summary(OCSP_SINGLERESP* resp, apr_pool_t *p)
    {
        const OCSP_CERTID *certid;
        int status, reason = 0;
        ASN1_GENERALIZEDTIME *bup = NULL, *bnextup = NULL;
        md_timeperiod_t valid;
        
    #if OPENSSL_VERSION_NUMBER < 0x10100000L \
        || (defined(LIBRESSL_VERSION_NUMBER) \
            && LIBRESSL_VERSION_NUMBER < 0x2070000f)
        certid = resp->certId;
    #else
        certid = OCSP_SINGLERESP_get0_id(resp);
    #endif
        status = OCSP_single_get0_status(resp, &reason, NULL, &bup, &bnextup);
        valid.start = bup? md_asn1_generalized_time_get(bup) : apr_time_now();
        valid.end = md_asn1_generalized_time_get(bnextup);
    
        return apr_psprintf(p, "ocsp-single-resp[%s, status=%s, reason=%d, valid=%s]",
                            certid_summary(certid, p),
                            certstatus_string(status), reason,
                            md_timeperiod_print(p, &valid));
    }
    
    typedef struct {
        apr_pool_t *p;
        md_ocsp_status_t *ostat;
        md_result_t *result;
        md_job_t *job;
    } md_ocsp_update_t;
    
    static apr_status_t ostat_on_resp(const md_http_response_t *resp, void *baton)
    {
        md_ocsp_update_t *update = baton;
        md_ocsp_status_t *ostat = update->ostat;
        md_http_request_t *req = resp->req;
        OCSP_RESPONSE *ocsp_resp = NULL;
        OCSP_BASICRESP *basic_resp = NULL;
        OCSP_SINGLERESP *single_resp;
        apr_status_t rv = APR_SUCCESS;
        int n, breason = 0, bstatus;
        ASN1_GENERALIZEDTIME *bup = NULL, *bnextup = NULL;
        md_data_t der, new_der;
        md_timeperiod_t valid;
        md_ocsp_cert_stat_t nstat;
        
        der.data = new_der.data = NULL;
        der.len  = new_der.len = 0;
    
        md_result_activity_printf(update->result, "status of certid %s, reading response", 
                                  ostat->hexid);
        if (APR_SUCCESS != (rv = apr_brigade_pflatten(resp->body, (char**)&der.data, 
                                                      &der.len, req->pool))) {
            goto cleanup;
        }
        if (NULL == (ocsp_resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char**)&der.data, 
                                                   (long)der.len))) {
            rv = APR_EINVAL;
    
            md_result_set(update->result, rv,
                          apr_psprintf(req->pool, "req[%d] response body does not parse as "
                                       "OCSP response, status=%d, body brigade length=%ld",
                                       resp->req->id, resp->status, (long)der.len));
            md_result_log(update->result, MD_LOG_DEBUG);
            goto cleanup;
        }
        /* got a response! but what does it say? */
        n = OCSP_response_status(ocsp_resp);
        if (OCSP_RESPONSE_STATUS_SUCCESSFUL != n) {
            rv = APR_EINVAL;
            md_result_printf(update->result, rv, "OCSP response status is, unsuccessfully, %d", n);
            md_result_log(update->result, MD_LOG_DEBUG);
            goto cleanup;
        }
        basic_resp = OCSP_response_get1_basic(ocsp_resp);
        if (!basic_resp) {
            rv = APR_EINVAL;
            md_result_set(update->result, rv, "OCSP response has no basicresponse");
            md_result_log(update->result, MD_LOG_DEBUG);
            goto cleanup;
        }
        /* The notion of nonce enabled freshness in OCSP responses, e.g. that the response
         * contains the signed nonce we sent to the responder, does not scale well. Responders
         * like to return cached response bytes and therefore do not add a nonce to it.
         * So, in reality, we can only detect a mismatch when present and otherwise have
         * to accept it. */
        switch ((n = OCSP_check_nonce(ostat->ocsp_req, basic_resp))) {
            case 1:
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool,
                              "req[%d]: OCSP response nonce does match", req->id);
                break;
            case 0:
                rv = APR_EINVAL;
                md_result_printf(update->result, rv, "OCSP nonce mismatch in response", n);
                md_result_log(update->result, MD_LOG_WARNING);
                goto cleanup;
                
            case -1:
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool,
                              "req[%d]: OCSP response did not return the nonce", req->id);
                break;
            default:
                break;
        }
        
        if (!OCSP_resp_find_status(basic_resp, ostat->certid, &bstatus,
                                   &breason, NULL, &bup, &bnextup)) {
            const char *prefix, *slist = "", *sep = "";
            int i;
            
            rv = APR_EINVAL;
            prefix = apr_psprintf(req->pool, "OCSP response, no matching status reported for  %s",
                                  certid_summary(ostat->certid, req->pool));
            for (i = 0; i < OCSP_resp_count(basic_resp); ++i) {
                single_resp = OCSP_resp_get0(basic_resp, i);
                slist = apr_psprintf(req->pool, "%s%s%s", slist, sep, 
                                     single_resp_summary(single_resp, req->pool));
                sep = ", ";
            }
            md_result_printf(update->result, rv, "%s, status list [%s]", prefix, slist);
            md_result_log(update->result, MD_LOG_DEBUG);
            goto cleanup;
        }
        if (V_OCSP_CERTSTATUS_UNKNOWN == bstatus) {
            rv = APR_ENOENT;
            md_result_set(update->result, rv, "OCSP basicresponse says cert is unknown");
            md_result_log(update->result, MD_LOG_DEBUG);
            goto cleanup;
        }
        
        /* Coming here, we have a response for our certid and it is either GOOD
         * or REVOKED. Both cases we want to remember and use in stapling. */
        n = i2d_OCSP_RESPONSE(ocsp_resp, (unsigned char**)&new_der.data);
        if (n <= 0) {
            rv = APR_EGENERAL;
            md_result_set(update->result, rv, "error DER encoding OCSP response");
            md_result_log(update->result, MD_LOG_WARNING);
            goto cleanup;
        }
        new_der.len = (apr_size_t)n;
        new_der.free_data = md_openssl_free;
        nstat = (bstatus == V_OCSP_CERTSTATUS_GOOD)? MD_OCSP_CERT_ST_GOOD : MD_OCSP_CERT_ST_REVOKED;
        valid.start = bup? md_asn1_generalized_time_get(bup) : apr_time_now();
        if (bnextup) {
            valid.end = md_asn1_generalized_time_get(bnextup);
        }
        else {
            /* nextUpdate not set; default to 12 hours.
             * Refresh attempts will be started some time earlier. */
            valid.end = valid.start + apr_time_from_sec(MD_SECS_PER_DAY / 2);
        }
        
        /* First, update the instance with a copy */
        apr_thread_mutex_lock(ostat->reg->mutex);
        ostat_set(ostat, nstat, &new_der, &valid, apr_time_now());
        apr_thread_mutex_unlock(ostat->reg->mutex);
        
        /* Next, save the original response */
        rv = ocsp_status_save(nstat, &new_der, &valid, ostat, req->pool); 
        if (APR_SUCCESS != rv) {
            md_result_set(update->result, rv, "error saving OCSP status");
            md_result_log(update->result, MD_LOG_ERR);
            goto cleanup;
        }
        
        md_result_printf(update->result, rv, "certificate status is %s, status valid %s", 
                         (nstat == MD_OCSP_CERT_ST_GOOD)? "GOOD" : "REVOKED",
                         md_timeperiod_print(req->pool, &ostat->resp_valid));
        md_result_log(update->result, MD_LOG_DEBUG);
    
    cleanup:
        md_data_clear(&new_der);
        if (basic_resp) OCSP_BASICRESP_free(basic_resp);
        if (ocsp_resp) OCSP_RESPONSE_free(ocsp_resp);
        return rv;
    }
    
    static apr_status_t ostat_on_req_status(const md_http_request_t *req, apr_status_t status, 
                                            void *baton)
    {
        md_ocsp_update_t *update = baton;
        md_ocsp_status_t *ostat = update->ostat;
    
        (void)req;
        md_job_end_run(update->job, update->result);
        if (APR_SUCCESS != status) {
            ++ostat->errors;
            ostat->next_run = apr_time_now() + md_job_delay_on_errors(update->job, ostat->errors, NULL);
            md_result_printf(update->result, status, "OCSP status update failed (%d. time)",  
                             ostat->errors);
            md_result_log(update->result, MD_LOG_DEBUG);
            md_job_log_append(update->job, "ocsp-error", 
                              update->result->problem, update->result->detail);
            md_event_holler("ocsp-errored", update->job->mdomain, update->job, update->result, update->p);
            goto cleanup;
        }
        md_event_holler("ocsp-renewed", update->job->mdomain, update->job, update->result, update->p);
    
    cleanup:
        md_job_save(update->job, update->result, update->p);
        ostat_req_cleanup(ostat);
        return APR_SUCCESS;
    }
    
    typedef struct {
        md_ocsp_reg_t *reg;
        apr_array_header_t *todos;
        apr_pool_t *ptemp;
        apr_time_t time;
        int max_parallel;
    } md_ocsp_todo_ctx_t;
    
    static apr_status_t ocsp_req_make(OCSP_REQUEST **pocsp_req, OCSP_CERTID *certid)
    {
        OCSP_REQUEST *req = NULL;
        OCSP_CERTID *id_copy = NULL;
        apr_status_t rv = APR_ENOMEM;
    
        req = OCSP_REQUEST_new();
        if (!req) goto cleanup;
        id_copy = OCSP_CERTID_dup(certid);
        if (!id_copy) goto cleanup;
        if (!OCSP_request_add0_id(req, id_copy)) goto cleanup;
        id_copy = NULL;
        OCSP_request_add1_nonce(req, 0, -1);
        rv = APR_SUCCESS;
    cleanup:
        if (id_copy) OCSP_CERTID_free(id_copy);
        if (APR_SUCCESS != rv && req) {
            OCSP_REQUEST_free(req);
            req = NULL;
        }
        *pocsp_req = req;
        return rv;
    }
    
    static apr_status_t ocsp_req_assign_der(md_data_t *d, OCSP_REQUEST *ocsp_req)
    {
        int len;
    
        md_data_clear(d);
        len = i2d_OCSP_REQUEST(ocsp_req, (unsigned char**)&d->data);
        if (len < 0) return APR_ENOMEM;
        d->len = (apr_size_t)len;
        d->free_data = md_openssl_free;
        return APR_SUCCESS;
    }
    
    static apr_status_t next_todo(md_http_request_t **preq, void *baton, 
                                  md_http_t *http, int in_flight)
    {
        md_ocsp_todo_ctx_t *ctx = baton;
        md_ocsp_update_t *update, **pupdate;    
        md_ocsp_status_t *ostat;
        md_http_request_t *req = NULL;
        apr_status_t rv = APR_ENOENT;
        apr_table_t *headers;
    
        if (in_flight < ctx->max_parallel) {
            pupdate = apr_array_pop(ctx->todos);
            if (pupdate) {
                update = *pupdate;
                ostat = update->ostat;
                
                update->job = md_ocsp_job_make(ctx->reg, ostat->md_name, update->p);
                md_job_load(update->job);
                md_job_start_run(update->job, update->result, ctx->reg->store);
                 
                if (!ostat->ocsp_req) {
                    rv = ocsp_req_make(&ostat->ocsp_req, ostat->certid);
                    if (APR_SUCCESS != rv) goto cleanup;
                }
                if (0 == ostat->req_der.len) {
                    rv = ocsp_req_assign_der(&ostat->req_der, ostat->ocsp_req);
                    if (APR_SUCCESS != rv) goto cleanup;
                }
                md_result_activity_printf(update->result, "status of certid %s, "
                                          "contacting %s", ostat->hexid, ostat->responder_url);
                headers = apr_table_make(ctx->ptemp, 5);
                apr_table_set(headers, "Expect", "");
                rv = md_http_POSTd_create(&req, http, ostat->responder_url, headers, 
                                          "application/ocsp-request", &ostat->req_der);
                if (APR_SUCCESS != rv) goto cleanup;
                md_http_set_on_status_cb(req, ostat_on_req_status, update);
                md_http_set_on_response_cb(req, ostat_on_resp, update);
                rv = APR_SUCCESS;
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, req->pool,
                              "scheduling OCSP request[%d] for %s, %d request in flight",
                              req->id, ostat->md_name, in_flight);
            }
        }
    cleanup:
        *preq = (APR_SUCCESS == rv)? req : NULL;
        return rv;
    }
    
    static int select_updates(void *baton, const void *key, apr_ssize_t klen, const void *val)
    {
        md_ocsp_todo_ctx_t *ctx = baton;
        md_ocsp_status_t *ostat = (md_ocsp_status_t *)val;
        md_ocsp_update_t *update;
        
        (void)key;
        (void)klen;
        if (ostat->next_run <= ctx->time) {
            update = apr_pcalloc(ctx->ptemp, sizeof(*update));
            update->p = ctx->ptemp;
            update->ostat = ostat;
            update->result = md_result_md_make(update->p, ostat->md_name);
            update->job = NULL;
            APR_ARRAY_PUSH(ctx->todos, md_ocsp_update_t*) = update;
        }
        return 1;
    }
    
    static int select_next_run(void *baton, const void *key, apr_ssize_t klen, const void *val)
    {
        md_ocsp_todo_ctx_t *ctx = baton;
        md_ocsp_status_t *ostat = (md_ocsp_status_t *)val;
        
        (void)key;
        (void)klen;
        if (ostat->next_run < ctx->time && ostat->next_run > apr_time_now()) {
            ctx->time = ostat->next_run;
        }
        return 1;
    }
    
    void md_ocsp_renew(md_ocsp_reg_t *reg, apr_pool_t *p, apr_pool_t *ptemp, apr_time_t *pnext_run)
    {
        md_ocsp_todo_ctx_t ctx;
        md_http_t *http;
        apr_status_t rv = APR_SUCCESS;
        
        (void)p;
        (void)pnext_run;
        
        ctx.reg = reg;
        ctx.ptemp = ptemp;
        ctx.todos = apr_array_make(ptemp, (int)md_ocsp_count(reg), sizeof(md_ocsp_status_t*));
        ctx.max_parallel = 6; /* the magic number in HTTP */
        
        /* Create a list of update tasks that are needed now or in the next minute */
        ctx.time = apr_time_now() + apr_time_from_sec(60);;
        apr_hash_do(select_updates, &ctx, reg->ostat_by_id);
        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, 
                      "OCSP status updates due: %d",  ctx.todos->nelts);
        if (!ctx.todos->nelts) goto cleanup;
        
        rv = md_http_create(&http, ptemp, reg->user_agent, reg->proxy_url);
        if (APR_SUCCESS != rv) goto cleanup;
        
        rv = md_http_multi_perform(http, next_todo, &ctx);
    
    cleanup:
        /* When do we need to run next? *pnext_run contains the planned schedule from
         * the watchdog. We can make that earlier if we need it. */
        ctx.time = *pnext_run;
        apr_hash_do(select_next_run, &ctx, reg->ostat_by_id);
    
        /* sanity check and return */
        if (ctx.time < apr_time_now()) ctx.time = apr_time_now() + apr_time_from_sec(1);
        *pnext_run = ctx.time;
    
        if (APR_SUCCESS != rv && APR_ENOENT != rv) {
            md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "ocsp_renew done");
        }
        return;
    }
    
    apr_status_t md_ocsp_remove_responses_older_than(md_ocsp_reg_t *reg, apr_pool_t *p, 
                                                     apr_time_t timestamp)
    {
        return md_store_remove_not_modified_since(reg->store, p, timestamp, 
                                                  MD_SG_OCSP, "*", "ocsp*.json");
    }
    
    typedef struct {
        apr_pool_t *p;
        md_ocsp_reg_t *reg;
        int good;
        int revoked;
        int unknown;
    } ocsp_summary_ctx_t;
    
    static int add_to_summary(void *baton, const void *key, apr_ssize_t klen, const void *val)
    {
        ocsp_summary_ctx_t *ctx = baton;
        md_ocsp_status_t *ostat = (md_ocsp_status_t *)val;
        md_ocsp_cert_stat_t stat;
        md_timeperiod_t valid;
        
        (void)key;
        (void)klen;
        ocsp_get_meta(&stat, &valid, ctx->reg, ostat, ctx->p);
        switch (stat) {
            case MD_OCSP_CERT_ST_GOOD: ++ctx->good; break;
            case MD_OCSP_CERT_ST_REVOKED: ++ctx->revoked; break;
            case MD_OCSP_CERT_ST_UNKNOWN: ++ctx->unknown; break;
        }
        return 1;
    }
    
    void  md_ocsp_get_summary(md_json_t **pjson, md_ocsp_reg_t *reg, apr_pool_t *p)
    {
        md_json_t *json;
        ocsp_summary_ctx_t ctx;
        
        memset(&ctx, 0, sizeof(ctx));
        ctx.p = p;
        ctx.reg = reg;
        apr_hash_do(add_to_summary, &ctx, reg->ostat_by_id);
    
        json = md_json_create(p);
        md_json_setl(ctx.good+ctx.revoked+ctx.unknown, json, MD_KEY_TOTAL, NULL);
        md_json_setl(ctx.good, json, MD_KEY_GOOD, NULL);
        md_json_setl(ctx.revoked, json, MD_KEY_REVOKED, NULL);
        md_json_setl(ctx.unknown, json, MD_KEY_UNKNOWN, NULL);
        *pjson = json;
    }
    
    static apr_status_t job_loadj(md_json_t **pjson, const char *name, 
                                  md_ocsp_reg_t *reg, apr_pool_t *p)
    {
        return md_store_load_json(reg->store, MD_SG_OCSP, name, MD_FN_JOB, pjson, p);
    }
    
    typedef struct {
        apr_pool_t *p;
        md_ocsp_reg_t *reg;
        apr_array_header_t *ostats;
    } ocsp_status_ctx_t;
    
    static md_json_t *mk_jstat(md_ocsp_status_t *ostat, md_ocsp_reg_t *reg, apr_pool_t *p)
    {
        md_ocsp_cert_stat_t stat;
        md_timeperiod_t valid, renewal;
        md_json_t *json, *jobj;
        apr_status_t rv;
        
        json = md_json_create(p);
        md_json_sets(ostat->md_name, json, MD_KEY_DOMAIN, NULL);
        md_json_sets(ostat->hexid, json, MD_KEY_ID, NULL);
        ocsp_get_meta(&stat, &valid, reg, ostat, p);
        md_json_sets(md_ocsp_cert_stat_name(stat), json, MD_KEY_STATUS, NULL);
        md_json_sets(ostat->hex_sha256, json, MD_KEY_CERT, MD_KEY_SHA256_FINGERPRINT, NULL);
        md_json_sets(ostat->responder_url, json, MD_KEY_URL, NULL);
        md_json_set_timeperiod(&valid, json, MD_KEY_VALID, NULL);
        renewal = md_timeperiod_slice_before_end(&valid, &reg->renew_window);
        md_json_set_time(renewal.start, json, MD_KEY_RENEW_AT, NULL);
        if ((MD_OCSP_CERT_ST_UNKNOWN == stat) || renewal.start < apr_time_now()) {
            /* We have no answer yet, or it should be in renew now. Add job information */
            rv = job_loadj(&jobj, ostat->md_name, reg, p);
            if (APR_SUCCESS == rv) {
                md_json_setj(jobj, json, MD_KEY_RENEWAL, NULL);
            }
        }
        return json;
    }
    
    static int add_ostat(void *baton, const void *key, apr_ssize_t klen, const void *val)
    {
        ocsp_status_ctx_t *ctx = baton;
        const md_ocsp_status_t *ostat = val;
        
        (void)key;
        (void)klen;
        APR_ARRAY_PUSH(ctx->ostats, const md_ocsp_status_t*) = ostat;
        return 1;
    }
    
    static int md_ostat_cmp(const void *v1, const void *v2)
    {
        int n;
        n = strcmp((*(md_ocsp_status_t**)v1)->md_name, (*(md_ocsp_status_t**)v2)->md_name);
        if (!n) {
            n = strcmp((*(md_ocsp_status_t**)v1)->hexid, (*(md_ocsp_status_t**)v2)->hexid);
        }
        return n;
    }
    
    void md_ocsp_get_status_all(md_json_t **pjson, md_ocsp_reg_t *reg, apr_pool_t *p)
    {
        md_json_t *json;
        ocsp_status_ctx_t ctx;
        md_ocsp_status_t *ostat;
        int i;
        
        memset(&ctx, 0, sizeof(ctx));
        ctx.p = p;
        ctx.reg = reg;
        ctx.ostats = apr_array_make(p, (int)apr_hash_count(reg->ostat_by_id), sizeof(md_ocsp_status_t*));
        json = md_json_create(p);
        
        apr_hash_do(add_ostat, &ctx, reg->ostat_by_id);
        qsort(ctx.ostats->elts, (size_t)ctx.ostats->nelts, sizeof(md_json_t*), md_ostat_cmp);
        
        for (i = 0; i < ctx.ostats->nelts; ++i) {
            ostat = APR_ARRAY_IDX(ctx.ostats, i, md_ocsp_status_t*);
            md_json_addj(mk_jstat(ostat, reg, p), json, MD_KEY_OCSPS, NULL);
        }
        *pjson = json;
    }
    
    md_job_t *md_ocsp_job_make(md_ocsp_reg_t *ocsp, const char *mdomain, apr_pool_t *p)
    {
        return md_job_make(p, ocsp->store, MD_SG_OCSP, mdomain, ocsp->min_delay);
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_util.c�������������������������������������������������������������������0000664�0001751�0001751�00000133717�14467135273�016523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_portable.h>
    #include <apr_file_info.h>
    #include <apr_fnmatch.h>
    #include <apr_tables.h>
    #include <apr_uri.h>
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    
    #include "md.h"
    #include "md_log.h"
    #include "md_util.h"
    
    /**************************************************************************************************/
    /* pool utils */
    
    apr_status_t md_util_pool_do(md_util_action *cb, void *baton, apr_pool_t *p)
    {
        apr_pool_t *ptemp;
        apr_status_t rv = apr_pool_create(&ptemp, p);
        if (APR_SUCCESS == rv) {
            apr_pool_tag(ptemp, "md_pool_do");
            rv = cb(baton, p, ptemp);
            apr_pool_destroy(ptemp);
        }
        return rv;
    }
     
    static apr_status_t pool_vado(md_util_vaction *cb, void *baton, apr_pool_t *p, va_list ap)
    {
        apr_pool_t *ptemp;
        apr_status_t rv;
        
        rv = apr_pool_create(&ptemp, p);
        if (APR_SUCCESS == rv) {
            apr_pool_tag(ptemp, "md_pool_vado");
            rv = cb(baton, p, ptemp, ap);
            apr_pool_destroy(ptemp);
        }
        return rv;
    }
     
    apr_status_t md_util_pool_vdo(md_util_vaction *cb, void *baton, apr_pool_t *p, ...)
    {
        va_list ap;
        apr_status_t rv;
        
        va_start(ap, p);
        rv = pool_vado(cb, baton, p, ap);
        va_end(ap);
        return rv;
    }
     
    /**************************************************************************************************/
    /* data chunks */
    
    void md_data_pinit(md_data_t *d, apr_size_t len, apr_pool_t *p)
    {
        md_data_null(d);
        d->data = apr_pcalloc(p, len);
        d->len = len;
    }
    
    md_data_t *md_data_pmake(apr_size_t len, apr_pool_t *p)
    {
        md_data_t *d;
        
        d = apr_palloc(p, sizeof(*d));
        md_data_pinit(d, len, p);
        return d;
    }
    
    void md_data_init(md_data_t *d, const char *data, apr_size_t len)
    {
        md_data_null(d);
        d->len = len;
        d->data = data;
    }
    
    void md_data_init_str(md_data_t *d, const char *str)
    {
        md_data_init(d, str, strlen(str));
    }
    
    void md_data_null(md_data_t *d)
    {
        memset(d, 0, sizeof(*d));
    }
    
    void md_data_clear(md_data_t *d)
    {
        if (d) {
            if (d->data && d->free_data) d->free_data((void*)d->data);
            memset(d, 0, sizeof(*d));
        }
    }
    
    md_data_t *md_data_make_pcopy(apr_pool_t *p, const char *data, apr_size_t len)
    {
        md_data_t *d;
    
        d = apr_palloc(p, sizeof(*d));
        d->len = len;
        d->data = len? apr_pmemdup(p, data, len) : NULL;
        return d;
    }
    
    apr_status_t md_data_assign_copy(md_data_t *dest, const char *src, apr_size_t src_len)
    {
        md_data_clear(dest);
        if (src && src_len) {
            dest->data = malloc(src_len);
            if (!dest->data) return APR_ENOMEM;
            memcpy((void*)dest->data, src, src_len);
            dest->len = src_len;
            dest->free_data = free;
        }
        return APR_SUCCESS;
    }
    
    void md_data_assign_pcopy(md_data_t *dest, const char *src, apr_size_t src_len, apr_pool_t *p)
    {
        md_data_clear(dest);
        dest->data = (src && src_len)? apr_pmemdup(p, src, src_len) : NULL;
        dest->len = dest->data? src_len : 0;
    }
    
    static const char * const hex_const[] = {
        "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", 
        "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", 
        "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", 
        "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", 
        "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", 
        "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", 
        "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", 
        "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", 
        "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", 
        "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", 
        "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", 
        "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", 
        "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", 
        "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", 
        "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", 
        "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff", 
    };
    
    apr_status_t md_data_to_hex(const char **phex, char separator,
                                apr_pool_t *p, const md_data_t *data)
    {
        char *hex, *cp;
        const char * x;
        unsigned int i;
        
        cp = hex = apr_pcalloc(p, ((separator? 3 : 2) * data->len) + 1);
        if (!hex) {
            *phex = NULL;
            return APR_ENOMEM;
        }
        for (i = 0; i < data->len; ++i) {
            x = hex_const[(unsigned char)data->data[i]];
            if (i && separator) *cp++ = separator;
            *cp++ = x[0];
            *cp++ = x[1];
        }
        *phex = hex;
        return APR_SUCCESS;
    }
    
    /**************************************************************************************************/
    /* generic arrays */
    
    int md_array_remove_at(struct apr_array_header_t *a, int idx)
    {
        char *ps, *pe;
    
        if (idx < 0 || idx >= a->nelts) return 0;
        if (idx+1 == a->nelts) {
            --a->nelts;
        }
        else {
            ps = (a->elts + (idx * a->elt_size));
            pe = ps + a->elt_size;
            memmove(ps, pe, (size_t)((a->nelts - (idx+1)) * a->elt_size));
            --a->nelts;
        }
        return 1;
    }
    
    int md_array_remove(struct apr_array_header_t *a, void *elem)
    {
        int i, n, m;
        void **pe;
        
        assert(sizeof(void*) == a->elt_size);
        n = i = 0;
        while (i < a->nelts) {
            pe = &APR_ARRAY_IDX(a, i, void*);
            if (*pe == elem) {
                m = a->nelts - (i+1);
                if (m > 0) memmove(pe, pe+1, (unsigned)m*sizeof(void*));
                a->nelts--;
                n++;
                continue;
            }
            ++i;
        }
        return n;
    }
    
    /**************************************************************************************************/
    /* string related */
    
    int md_array_is_empty(const struct apr_array_header_t *array)
    {
        return (array == NULL) || (array->nelts == 0);
    }
    
    char *md_util_str_tolower(char *s)
    {
        char *orig = s;
        while (*s) {
            *s = (char)apr_tolower(*s);
            ++s;
        }
        return orig;
    }
    
    int md_array_str_index(const apr_array_header_t *array, const char *s, 
                           int start, int case_sensitive)
    {
        if (start >= 0) {
            int i;
            
            for (i = start; i < array->nelts; i++) {
                const char *p = APR_ARRAY_IDX(array, i, const char *);
                if ((case_sensitive && !strcmp(p, s))
                    || (!case_sensitive && !apr_strnatcasecmp(p, s))) {
                    return i;
                }
            }
        }
        
        return -1;
    }
    
    int md_array_str_eq(const struct apr_array_header_t *a1, 
                        const struct apr_array_header_t *a2, int case_sensitive)
    {
        int i;
        const char *s1, *s2;
        
        if (a1 == a2) return 1;
        if (!a1 || !a2) return 0;
        if (a1->nelts != a2->nelts) return 0;
        for (i = 0; i < a1->nelts; ++i) {
            s1 = APR_ARRAY_IDX(a1, i, const char *);
            s2 = APR_ARRAY_IDX(a2, i, const char *);
            if ((case_sensitive && strcmp(s1, s2))
                || (!case_sensitive && apr_strnatcasecmp(s1, s2))) {
                return 0;
            }
        }
        return 1;
    }
    
    apr_array_header_t *md_array_str_clone(apr_pool_t *p, apr_array_header_t *src)
    {
        apr_array_header_t *dest = apr_array_make(p, src->nelts, sizeof(const char*));
        if (dest) {
            int i;
            for (i = 0; i < src->nelts; i++) {
                const char *s = APR_ARRAY_IDX(src, i, const char *);
                APR_ARRAY_PUSH(dest, const char *) = apr_pstrdup(p, s); 
            }
        }
        return dest;
    }
    
    struct apr_array_header_t *md_array_str_compact(apr_pool_t *p, struct apr_array_header_t *src,
                                                    int case_sensitive)
    {
        apr_array_header_t *dest = apr_array_make(p, src->nelts, sizeof(const char*));
        if (dest) {
            const char *s;
            int i;
            for (i = 0; i < src->nelts; ++i) {
                s = APR_ARRAY_IDX(src, i, const char *);
                if (md_array_str_index(dest, s, 0, case_sensitive) < 0) {
                    APR_ARRAY_PUSH(dest, char *) = md_util_str_tolower(apr_pstrdup(p, s));
                }
            }
        }
        return dest;
    }
    
    apr_array_header_t *md_array_str_remove(apr_pool_t *p, apr_array_header_t *src, 
                                            const char *exclude, int case_sensitive)
    {
        apr_array_header_t *dest = apr_array_make(p, src->nelts, sizeof(const char*));
        if (dest) {
            int i;
            for (i = 0; i < src->nelts; i++) {
                const char *s = APR_ARRAY_IDX(src, i, const char *);
                if (!exclude 
                    || (case_sensitive && strcmp(exclude, s))
                    || (!case_sensitive && apr_strnatcasecmp(exclude, s))) {
                    APR_ARRAY_PUSH(dest, const char *) = apr_pstrdup(p, s); 
                }
            }
        }
        return dest;
    }
    
    int md_array_str_add_missing(apr_array_header_t *dest, apr_array_header_t *src, int case_sensitive)
    {
        int i, added = 0;
        for (i = 0; i < src->nelts; i++) {
            const char *s = APR_ARRAY_IDX(src, i, const char *);
            if (md_array_str_index(dest, s, 0, case_sensitive) < 0) {
                APR_ARRAY_PUSH(dest, const char *) = s;
                ++added; 
            }
        }
        return added;
    }
    
    /**************************************************************************************************/
    /* file system related */
    
    apr_status_t md_util_fopen(FILE **pf, const char *fn, const char *mode)
    {
        *pf = fopen(fn, mode);
        if (*pf == NULL) {
            return errno;
        }
    
        return APR_SUCCESS;
    }
    
    apr_status_t md_util_fcreatex(apr_file_t **pf, const char *fn, 
                                  apr_fileperms_t perms, apr_pool_t *p)
    {
        apr_status_t rv;
        rv = apr_file_open(pf, fn, (APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_EXCL),
                           perms, p);
        if (APR_SUCCESS == rv) {
            /* See <https://github.com/icing/mod_md/issues/117>
             * Some people set umask 007 to deny all world read/writability to files
             * created by apache. While this is a noble effort, we need the store files
             * to have the permissions as specified. */
            rv = apr_file_perms_set(fn, perms);
            if (APR_STATUS_IS_ENOTIMPL(rv)) {
                rv = APR_SUCCESS;
            }
        }
        return rv;
    }
    
    apr_status_t md_util_is_dir(const char *path, apr_pool_t *pool)
    {
        apr_finfo_t info;
        apr_status_t rv = apr_stat(&info, path, APR_FINFO_TYPE, pool);
        if (rv == APR_SUCCESS) {
            rv = (info.filetype == APR_DIR)? APR_SUCCESS : APR_EINVAL;
        }
        return rv;
    }
    
    apr_status_t md_util_is_file(const char *path, apr_pool_t *pool)
    {
        apr_finfo_t info;
        apr_status_t rv = apr_stat(&info, path, APR_FINFO_TYPE, pool);
        if (rv == APR_SUCCESS) {
            rv = (info.filetype == APR_REG)? APR_SUCCESS : APR_EINVAL;
        }
        return rv;
    }
    
    apr_status_t md_util_is_unix_socket(const char *path, apr_pool_t *pool)
    {
        apr_finfo_t info;
        apr_status_t rv = apr_stat(&info, path, APR_FINFO_TYPE, pool);
        if (rv == APR_SUCCESS) {
            rv = (info.filetype == APR_SOCK)? APR_SUCCESS : APR_EINVAL;
        }
        return rv;
    }
    
    int md_file_exists(const char *fname, apr_pool_t *p)
    {
        return (fname && *fname && APR_SUCCESS == md_util_is_file(fname, p));
    }
    
    apr_status_t md_util_path_merge(const char **ppath, apr_pool_t *p, ...)
    {
        const char *segment, *path;
        va_list ap;
        apr_status_t rv = APR_SUCCESS;
        
        va_start(ap, p);
        path = va_arg(ap, char *);
        while (path && APR_SUCCESS == rv && (segment = va_arg(ap, char *))) {
            rv = apr_filepath_merge((char **)&path, path, segment, APR_FILEPATH_SECUREROOT , p);
        }
        va_end(ap);
        
        *ppath = (APR_SUCCESS == rv)? (path? path : "") : NULL;
        return rv;
    }
    
    apr_status_t md_util_freplace(const char *fpath, apr_fileperms_t perms, apr_pool_t *p, 
                                  md_util_file_cb *write_cb, void *baton)
    {
        apr_status_t rv = APR_EEXIST;
        apr_file_t *f;
        const char *tmp;
        int i, max;
        
        tmp = apr_psprintf(p, "%s.tmp", fpath);
        i = 0; max = 20;
    creat:
        while (i < max && APR_EEXIST == (rv = md_util_fcreatex(&f, tmp, perms, p))) {
            ++i;
            apr_sleep(apr_time_from_msec(50));
        } 
        if (APR_EEXIST == rv 
            && APR_SUCCESS == (rv = apr_file_remove(tmp, p))
            && max <= 20) {
            max *= 2;
            goto creat;
        }
        
        if (APR_SUCCESS == rv) {
            rv = write_cb(baton, f, p);
            apr_file_close(f);
            
            if (APR_SUCCESS == rv) {
                rv = apr_file_rename(tmp, fpath, p);
                if (APR_SUCCESS != rv) {
                    apr_file_remove(tmp, p);
                }
            }
        }
        return rv;
    }                            
    
    /**************************************************************************************************/
    /* text files */
    
    apr_status_t md_text_fread8k(const char **ptext, apr_pool_t *p, const char *fpath)
    {
        apr_status_t rv;
        apr_file_t *f;
        char buffer[8 * 1024];
    
        *ptext = NULL;
        if (APR_SUCCESS == (rv = apr_file_open(&f, fpath, APR_FOPEN_READ, 0, p))) {
            apr_size_t blen = sizeof(buffer)/sizeof(buffer[0]) - 1;
            rv = apr_file_read_full(f, buffer, blen, &blen);
            if (APR_SUCCESS == rv || APR_STATUS_IS_EOF(rv)) {
                *ptext = apr_pstrndup(p, buffer, blen);
                rv = APR_SUCCESS;
            }
            apr_file_close(f);
        }
        return rv;
    }
    
    static apr_status_t write_text(void *baton, struct apr_file_t *f, apr_pool_t *p)
    {
        const char *text = baton;
        apr_size_t len = strlen(text);
        
        (void)p;
        return apr_file_write_full(f, text, len, &len);
    }
    
    apr_status_t md_text_fcreatex(const char *fpath, apr_fileperms_t perms, 
                                  apr_pool_t *p, const char *text)
    {
        apr_status_t rv;
        apr_file_t *f;
        
        rv = md_util_fcreatex(&f, fpath, perms, p);
        if (APR_SUCCESS == rv) {
            rv = write_text((void*)text, f, p);
            apr_file_close(f);
            /* See <https://github.com/icing/mod_md/issues/117>: when a umask
             * is set, files need to be assigned permissions explicitly.
             * Otherwise, as in the issues reported, it will break our access model. */
            rv = apr_file_perms_set(fpath, perms);
            if (APR_STATUS_IS_ENOTIMPL(rv)) {
                rv = APR_SUCCESS;
            }
        }
        return rv;
    }
    
    apr_status_t md_text_freplace(const char *fpath, apr_fileperms_t perms, 
                                  apr_pool_t *p, const char *text)
    {
        return md_util_freplace(fpath, perms, p, write_text, (void*)text);
    }
    
    typedef struct {
        const char *path;
        apr_array_header_t *patterns;
        int follow_links;
        void *baton;
        md_util_fdo_cb *cb;
    } md_util_fwalk_t;
    
    static apr_status_t rm_recursive(const char *fpath, apr_pool_t *p, int max_level)
    {
        apr_finfo_t info;
        apr_status_t rv;
        const char *npath;
        
        if (APR_SUCCESS != (rv = apr_stat(&info, fpath, (APR_FINFO_TYPE|APR_FINFO_LINK), p))) {
            return rv;
        }
        
        if (info.filetype == APR_DIR) {
            if (max_level > 0) {
                apr_dir_t *d;
                
                if (APR_SUCCESS == (rv = apr_dir_open(&d, fpath, p))) {
                
                    while (APR_SUCCESS == rv && 
                           APR_SUCCESS == (rv = apr_dir_read(&info, APR_FINFO_TYPE, d))) {
                        if (!strcmp(".", info.name) || !strcmp("..", info.name)) {
                            continue;
                        }
                        
                        rv = md_util_path_merge(&npath, p, fpath, info.name, NULL);
                        if (APR_SUCCESS == rv) {
                            rv = rm_recursive(npath, p, max_level - 1);
                        }
                    }
                    apr_dir_close(d);
                    if (APR_STATUS_IS_ENOENT(rv)) {
                        rv = APR_SUCCESS;
                    }
                }
            }
            if (APR_SUCCESS == rv) {
                rv = apr_dir_remove(fpath, p);
            }
        }
        else {
            rv = apr_file_remove(fpath, p);
        }
        return rv;
    }
    
    static apr_status_t prm_recursive(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        int max_level = va_arg(ap, int);
        
        (void)p;
        return rm_recursive(baton, ptemp, max_level); 
    }
    
    apr_status_t md_util_rm_recursive(const char *fpath, apr_pool_t *p, int max_level)
    {
        return md_util_pool_vdo(prm_recursive, (void*)fpath, p, max_level, NULL);
    }
    
    static apr_status_t match_and_do(md_util_fwalk_t *ctx, const char *path, int depth, 
                                     apr_pool_t *p, apr_pool_t *ptemp)
    {
        apr_status_t rv = APR_SUCCESS;
        const char *pattern, *npath;
        apr_dir_t *d;
        apr_finfo_t finfo;
        int ndepth = depth + 1;
        apr_int32_t wanted = (APR_FINFO_TYPE);
    
        if (depth >= ctx->patterns->nelts) {
            return APR_SUCCESS;
        }
        pattern = APR_ARRAY_IDX(ctx->patterns, depth, const char *);
        
        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
                      "path=%s depth=%d pattern=%s", path, depth, pattern);
        rv = apr_dir_open(&d, path, ptemp);
        if (APR_SUCCESS != rv) {
            return rv;
        }
        
        while (APR_SUCCESS == (rv = apr_dir_read(&finfo, wanted, d))) {
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
                          "candidate=%s", finfo.name);
            if (!strcmp(".", finfo.name) || !strcmp("..", finfo.name)) {
                continue;
            } 
            if (APR_SUCCESS == apr_fnmatch(pattern, finfo.name, 0)) {
                md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
                              "candidate=%s matches pattern", finfo.name);
                if (ndepth < ctx->patterns->nelts) {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
                                  "need to go deeper");
                    if (APR_DIR == finfo.filetype) { 
                        /* deeper and deeper, irgendwo in der tiefe leuchtet ein licht */
                        rv = md_util_path_merge(&npath, ptemp, path, finfo.name, NULL);
                        if (APR_SUCCESS == rv) {
                            rv = match_and_do(ctx, npath, ndepth, p, ptemp);
                        }
                    }
                }
                else {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
                                  "invoking inspector on name=%s", finfo.name);
                    rv = ctx->cb(ctx->baton, p, ptemp, path, finfo.name, finfo.filetype);
                }
            }
            if (APR_SUCCESS != rv) {
                break;
            }
        }
    
        if (APR_STATUS_IS_ENOENT(rv)) {
            rv = APR_SUCCESS;
        }
    
        apr_dir_close(d);
        return rv;
    }
    
    static apr_status_t files_do_start(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
    {
        md_util_fwalk_t *ctx = baton;
        const char *segment;
    
        ctx->patterns = apr_array_make(ptemp, 5, sizeof(const char*));
        
        segment = va_arg(ap, char *);
        while (segment) {
            APR_ARRAY_PUSH(ctx->patterns, const char *) = segment;
            segment = va_arg(ap, char *);
        }
        
        return match_and_do(ctx, ctx->path, 0, p, ptemp);
    }
    
    apr_status_t md_util_files_do(md_util_fdo_cb *cb, void *baton, apr_pool_t *p,
                                  const char *path, ...)
    {
        apr_status_t rv;
        va_list ap;
        md_util_fwalk_t ctx;
    
        memset(&ctx, 0, sizeof(ctx));
        ctx.path = path;
        ctx.follow_links = 1;
        ctx.cb = cb;
        ctx.baton = baton;
        
        va_start(ap, path);
        rv = pool_vado(files_do_start, &ctx, p, ap);
        va_end(ap);
        
        return rv;
    }
    
    static apr_status_t tree_do(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *path)
    {
        md_util_fwalk_t *ctx = baton;
    
        apr_status_t rv = APR_SUCCESS;
        const char *name, *fpath;
        apr_filetype_e ftype;
        apr_dir_t *d;
        apr_int32_t wanted = APR_FINFO_TYPE;
        apr_finfo_t finfo;
    
        if (APR_SUCCESS == (rv = apr_dir_open(&d, path, ptemp))) {
            while (APR_SUCCESS == (rv = apr_dir_read(&finfo, wanted, d))) {
                name = finfo.name;
                if (!strcmp(".", name) || !strcmp("..", name)) {
                    continue;
                }
    
                fpath = NULL;
                ftype = finfo.filetype;
                
                if (APR_LNK == ftype && ctx->follow_links) {
                    rv = md_util_path_merge(&fpath, ptemp, path, name, NULL);
                    if (APR_SUCCESS == rv) {
                        rv = apr_stat(&finfo, ctx->path, wanted, ptemp);
                    }
                }
                
                if (APR_DIR == finfo.filetype) {
                    if (!fpath) {
                        rv = md_util_path_merge(&fpath, ptemp, path, name, NULL);
                    }
                    if (APR_SUCCESS == rv) {
                        rv = tree_do(ctx, p, ptemp, fpath);
                        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, ptemp, "dir cb(%s/%s)", 
                                      path, name);
                        rv = ctx->cb(ctx->baton, p, ptemp, path, name, ftype);
                    }
                }
                else {
                    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, ptemp, "file cb(%s/%s)", 
                                  path, name);
                    rv = ctx->cb(ctx->baton, p, ptemp, path, name, finfo.filetype);
                }
            }
    
            apr_dir_close(d);
            
            if (APR_STATUS_IS_ENOENT(rv)) {
                rv = APR_SUCCESS;
            }
        }
        return rv;
    }
    
    static apr_status_t tree_start_do(void *baton, apr_pool_t *p, apr_pool_t *ptemp)
    {
        md_util_fwalk_t *ctx = baton;
        apr_finfo_t info;
        apr_status_t rv;
        apr_int32_t wanted = ctx->follow_links? APR_FINFO_TYPE : (APR_FINFO_TYPE|APR_FINFO_LINK);
        
        rv = apr_stat(&info, ctx->path, wanted, ptemp);
        if (rv == APR_SUCCESS) {
            switch (info.filetype) {
                case APR_DIR:
                    rv = tree_do(ctx, p, ptemp, ctx->path);
                    break;
                default:
                    rv = APR_EINVAL;
            }
        }
        return rv;
    }
    
    apr_status_t md_util_tree_do(md_util_fdo_cb *cb, void *baton, apr_pool_t *p, 
                                 const char *path, int follow_links)
    {
        apr_status_t rv;
        md_util_fwalk_t ctx;
    
        memset(&ctx, 0, sizeof(ctx));
        ctx.path = path;
        ctx.follow_links = follow_links;
        ctx.cb = cb;
        ctx.baton = baton;
        
        rv = md_util_pool_do(tree_start_do, &ctx, p);
        
        return rv;
    }
    
    static apr_status_t rm_cb(void *baton, apr_pool_t *p, apr_pool_t *ptemp, 
                              const char *path, const char *name, apr_filetype_e ftype)
    {
        apr_status_t rv;
        const char *fpath;
        
        (void)baton;
        (void)p;
        rv = md_util_path_merge(&fpath, ptemp, path, name, NULL);
        if (APR_SUCCESS == rv) {
            if (APR_DIR == ftype) {
                rv = apr_dir_remove(fpath, ptemp);
            }
            else {
                rv = apr_file_remove(fpath, ptemp);
            }
        }
        return rv;
    }
    
    apr_status_t md_util_ftree_remove(const char *path, apr_pool_t *p)
    {
        apr_status_t rv = md_util_tree_do(rm_cb, NULL, p, path, 0);
        if (APR_SUCCESS == rv) {
            rv = apr_dir_remove(path, p);
        }
        return rv;
    }
    
    /* DNS name checks ********************************************************************************/
    
    int md_dns_is_name(apr_pool_t *p, const char *hostname, int need_fqdn)
    {
        char c, last = 0;
        const char *cp = hostname;
        int dots = 0;
        
        /* Since we use the names in certificates, we need pure ASCII domain names
         * and IDN need to be converted to unicode. */
        while ((c = *cp++)) {
            switch (c) {
                case '.':
                    if (last == '.') {
                        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p, "dns name with ..: %s", 
                                      hostname);
                        return 0;
                    }
                    ++dots;
                    break;
                case '-':
                    break;
                default:
                    if (!apr_isalnum(c)) {
                        md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p, "dns invalid char %c: %s", 
                                      c, hostname);
                        return 0;
                    }
                    break;
            }
            last = c;
        }
        
        if (last == '.') { /* DNS names may end with '.' */
            --dots;
        }
        if (need_fqdn && dots <= 0) { /* do not accept just top level domains */
            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p, "not a FQDN: %s", hostname);
            return 0;
        }
        return 1; /* empty string not allowed */
    }
    
    int md_dns_is_wildcard(apr_pool_t *p, const char *domain)
    {
        if (domain[0] != '*' || domain[1] != '.') return 0;
        return md_dns_is_name(p, domain+2, 1);
    }
    
    int md_dns_matches(const char *pattern, const char *domain)
    {
        const char *s;
        
        if (!apr_strnatcasecmp(pattern, domain)) return 1;
        if (pattern[0] == '*' && pattern[1] == '.') {
            s = strchr(domain, '.');
            if (s && !apr_strnatcasecmp(pattern+1, s)) return 1;
        }
        return 0;
    }
    
    apr_array_header_t *md_dns_make_minimal(apr_pool_t *p, apr_array_header_t *domains)
    {
        apr_array_header_t *minimal;
        const char *domain, *pattern;
        int i, j, duplicate;
        
        minimal = apr_array_make(p, domains->nelts, sizeof(const char *));
        for (i = 0; i < domains->nelts; ++i) {
            domain = APR_ARRAY_IDX(domains, i, const char*);
            duplicate = 0;
            /* is it matched in minimal already? */
            for (j = 0; j < minimal->nelts; ++j) {
                pattern = APR_ARRAY_IDX(minimal, j, const char*);
                if (md_dns_matches(pattern, domain)) {
                    duplicate = 1;
                    break;
                }
            }
            if (!duplicate) {
                if (!md_dns_is_wildcard(p, domain)) {
                    /* plain name, will we see a wildcard that replaces it? */
                    for (j = i+1; j < domains->nelts; ++j) {
                        pattern = APR_ARRAY_IDX(domains, j, const char*);
                        if (md_dns_is_wildcard(p, pattern) && md_dns_matches(pattern, domain)) {
                            duplicate = 1;
                            break;
                        }
                    }
                }
                if (!duplicate) {
                    APR_ARRAY_PUSH(minimal, const char *) = domain; 
                }
            }
        }
        return minimal;
    }
    
    int md_dns_domains_match(const apr_array_header_t *domains, const char *name)
    {
        const char *domain;
        int i;
        
        for (i = 0; i < domains->nelts; ++i) {
            domain = APR_ARRAY_IDX(domains, i, const char*);
            if (md_dns_matches(domain, name)) return 1;
        }
        return 0;
    }
    
    int md_is_wild_match(const apr_array_header_t *domains, const char *name)
    {
        const char *domain;
        int i;
    
        for (i = 0; i < domains->nelts; ++i) {
            domain = APR_ARRAY_IDX(domains, i, const char*);
            if (md_dns_matches(domain, name))
                return (domain[0] == '*' && domain[1] == '.');
        }
        return 0;
    }
    
    const char *md_util_schemify(apr_pool_t *p, const char *s, const char *def_scheme)
    {
        const char *cp = s;
        while (*cp) {
            if (*cp == ':') {
                /* could be an url scheme, leave unchanged */
                return s;
            }
            else if (!apr_isalnum(*cp)) {
                break;
            }
            ++cp;
        }
        return apr_psprintf(p, "%s:%s", def_scheme, s);
    }
    
    static apr_status_t uri_check(apr_uri_t *uri_parsed, apr_pool_t *p, 
                                  const char *uri, const char **perr)
    {
        const char *s, *err = NULL;
        apr_status_t rv;
        
        if (APR_SUCCESS != (rv = apr_uri_parse(p, uri, uri_parsed))) {
            err = "not an uri";
        }
        else if (uri_parsed->scheme) {
            if (strlen(uri_parsed->scheme) + 1 >= strlen(uri)) {
                err = "missing uri identifier";
            }
            else if (!strncmp("http", uri_parsed->scheme, 4)) {
                if (!uri_parsed->hostname) {
                    err = "missing hostname";
                }
                else if (!md_dns_is_name(p, uri_parsed->hostname, 0)) {
                    err = "invalid hostname";
                }
                if (uri_parsed->port_str 
                    && (!apr_isdigit(uri_parsed->port_str[0])
                    || uri_parsed->port == 0
                    || uri_parsed->port > 65353)) {
                    err = "invalid port";
                }
            }
            else if (!strcmp("mailto", uri_parsed->scheme)) {
                s = strchr(uri, '@');
                if (!s) {
                    err = "missing @";
                }
                else if (strchr(s+1, '@')) {
                    err = "duplicate @";
                }
                else if (s == uri + strlen(uri_parsed->scheme) + 1) {
                    err = "missing local part";
                }
                else if (s == (uri + strlen(uri)-1)) {
                    err = "missing hostname";
                }
                else if (strstr(uri, "..")) {
                    err = "double period";
                }
            }
        }
        if (strchr(uri, ' ') || strchr(uri, '\t') ) {
            err = "whitespace in uri";
        }
        
        if (err) {
            rv = APR_EINVAL;
        }
        *perr = err;
        return rv;
    }
    
    apr_status_t md_util_abs_uri_check(apr_pool_t *p, const char *uri, const char **perr)
    {
        apr_uri_t uri_parsed;
        apr_status_t rv;
    
        if (APR_SUCCESS == (rv = uri_check(&uri_parsed, p, uri, perr))) {
            if (!uri_parsed.scheme) {
                *perr = "missing uri scheme";
                return APR_EINVAL;
            }
        }
        return rv;
    }
    
    apr_status_t md_util_abs_http_uri_check(apr_pool_t *p, const char *uri, const char **perr)
    {
        apr_uri_t uri_parsed;
        apr_status_t rv;
    
        if (APR_SUCCESS == (rv = uri_check(&uri_parsed, p, uri, perr))) {
            if (!uri_parsed.scheme) {
                *perr = "missing uri scheme";
                return APR_EINVAL;
            }
            if (apr_strnatcasecmp("http", uri_parsed.scheme) 
                && apr_strnatcasecmp("https", uri_parsed.scheme)) {
                *perr = "uri scheme must be http or https";
                return APR_EINVAL;
            }
        }
        return rv;
    }
    
    /* try and retry for a while **********************************************************************/
    
    apr_status_t md_util_try(md_util_try_fn *fn, void *baton, int ignore_errs, 
                             apr_interval_time_t timeout, apr_interval_time_t start_delay, 
                             apr_interval_time_t max_delay, int backoff)
    {
        apr_status_t rv;
        apr_time_t now = apr_time_now();
        apr_time_t giveup = now + timeout;
        apr_interval_time_t nap_duration = start_delay? start_delay : apr_time_from_msec(100);
        apr_interval_time_t nap_max = max_delay? max_delay : apr_time_from_sec(10);
        apr_interval_time_t left;
        int i = 0;
        
        while (1) {
            if (APR_SUCCESS == (rv = fn(baton, i++))) {
                break;
            }
            else if (!APR_STATUS_IS_EAGAIN(rv) && !ignore_errs) {
                break;
            }
            
            now = apr_time_now();
            if (now > giveup) {
                rv = APR_TIMEUP;
                break;
            }
            
            left = giveup - now;
            if (nap_duration > left) {
                nap_duration = left;
            }
            if (nap_duration > nap_max) {
                nap_duration = nap_max;
            }
            
            apr_sleep(nap_duration);
            if (backoff) {
                nap_duration *= 2;
            } 
        }
        return rv;
    }
    
    /* execute process ********************************************************************************/
    
    apr_status_t md_util_exec(apr_pool_t *p, const char *cmd,
                              const char * const *argv, int *exit_code)
    {
        apr_status_t rv;
        apr_procattr_t *procattr;
        apr_proc_t *proc;
        apr_exit_why_e ewhy;
        char buffer[1024];
        
        *exit_code = 0;
        if (!(proc = apr_pcalloc(p, sizeof(*proc)))) {
            return APR_ENOMEM;
        }
        if (   APR_SUCCESS == (rv = apr_procattr_create(&procattr, p))
            && APR_SUCCESS == (rv = apr_procattr_io_set(procattr, APR_NO_FILE, 
                                                        APR_NO_PIPE, APR_FULL_BLOCK))
            && APR_SUCCESS == (rv = apr_procattr_cmdtype_set(procattr, APR_PROGRAM_ENV))
            && APR_SUCCESS == (rv = apr_proc_create(proc, cmd, argv, NULL, procattr, p))) {
            
            /* read stderr and log on INFO for possible fault analysis. */
            while(APR_SUCCESS == (rv = apr_file_gets(buffer, sizeof(buffer)-1, proc->err))) {
                md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, p, "cmd(%s) stderr: %s", cmd, buffer);
            }
            if (!APR_STATUS_IS_EOF(rv)) goto out;
            apr_file_close(proc->err);
            
            if (APR_CHILD_DONE == (rv = apr_proc_wait(proc, exit_code, &ewhy, APR_WAIT))) {
                /* let's not dwell on exit stati, but core should signal something's bad */
                if (*exit_code > 127 || APR_PROC_SIGNAL_CORE == ewhy) {
                    return APR_EINCOMPLETE;
                }
                return APR_SUCCESS;
            }
        }
    out:
        return rv;
    }
    
    /* base64 url encoding ****************************************************************************/
    
    #define N6 (unsigned int)-1
    
    static const unsigned int BASE64URL_UINT6[] = {
    /*   0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f        */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  0 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  1 */ 
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, 62, N6, N6, /*  2 */
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, N6, N6, N6, N6, N6, N6, /*  3 */ 
        N6, 0,  1,  2,  3,  4,  5,  6,   7,  8,  9, 10, 11, 12, 13, 14, /*  4 */
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, N6, N6, N6, N6, 63, /*  5 */
        N6, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /*  6 */
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, N6, N6, N6, N6, N6, /*  7 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  8 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  9 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  a */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  b */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  c */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  d */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  e */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6  /*  f */
    };
    static const unsigned char BASE64URL_CHARS[] = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /*  0 -  9 */
        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10 - 19 */
        'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20 - 29 */
        'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30 - 39 */
        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40 - 49 */
        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50 - 59 */
        '8', '9', '-', '_', ' ', ' ', ' ', ' ', ' ', ' ', /* 60 - 69 */
    };
    
    #define BASE64URL_CHAR(x)    BASE64URL_CHARS[ (unsigned int)(x) & 0x3fu ]
       
    apr_size_t md_util_base64url_decode(md_data_t *decoded, const char *encoded, 
                                        apr_pool_t *pool)
    {
        const unsigned char *e = (const unsigned char *)encoded;
        const unsigned char *p = e;
        unsigned char *d;
        unsigned int n;
        long len, mlen, remain, i;
        
        while (*p && BASE64URL_UINT6[ *p ] != N6) {
            ++p;
        }
        len = (int)(p - e);
        mlen = (len/4)*4;
        decoded->data = apr_pcalloc(pool, (apr_size_t)len + 1);
        
        i = 0;
        d = (unsigned char*)decoded->data;
        for (; i < mlen; i += 4) {
            n = ((BASE64URL_UINT6[ e[i+0] ] << 18) +
                 (BASE64URL_UINT6[ e[i+1] ] << 12) +
                 (BASE64URL_UINT6[ e[i+2] ] << 6) +
                 (BASE64URL_UINT6[ e[i+3] ]));
            *d++ = (unsigned char)(n >> 16);
            *d++ = (unsigned char)(n >> 8 & 0xffu);
            *d++ = (unsigned char)(n & 0xffu);
        }
        remain = len - mlen;
        switch (remain) {
            case 2:
                n = ((BASE64URL_UINT6[ e[mlen+0] ] << 18) +
                     (BASE64URL_UINT6[ e[mlen+1] ] << 12));
                *d++ = (unsigned char)(n >> 16);
                remain = 1;
                break;
            case 3:
                n = ((BASE64URL_UINT6[ e[mlen+0] ] << 18) +
                     (BASE64URL_UINT6[ e[mlen+1] ] << 12) +
                     (BASE64URL_UINT6[ e[mlen+2] ] << 6));
                *d++ = (unsigned char)(n >> 16);
                *d++ = (unsigned char)(n >> 8 & 0xffu);
                remain = 2;
                break;
            default: /* do nothing */
                break;
        }
        decoded->len = (apr_size_t)(mlen/4*3 + remain);
        return decoded->len; 
    }
    
    const char *md_util_base64url_encode(const md_data_t *data, apr_pool_t *pool)
    {
        int i, len = (int)data->len;
        apr_size_t slen = ((data->len+2)/3)*4 + 1; /* 0 terminated */
        const unsigned char *udata = (const unsigned char*)data->data;
        unsigned char *enc, *p = apr_pcalloc(pool, slen);
        
        enc = p;
        for (i = 0; i < len-2; i+= 3) {
            *p++ = BASE64URL_CHAR( (udata[i]   >> 2) );
            *p++ = BASE64URL_CHAR( (udata[i]   << 4) + (udata[i+1] >> 4) );
            *p++ = BASE64URL_CHAR( (udata[i+1] << 2) + (udata[i+2] >> 6) );
            *p++ = BASE64URL_CHAR( (udata[i+2]) );
        }
        
        if (i < len) {
            *p++ = BASE64URL_CHAR( (udata[i] >> 2) );
            if (i == (len - 1)) {
                *p++ = BASE64URL_CHARS[ ((unsigned int)udata[i] << 4) & 0x3fu ];
            }
            else {
                *p++ = BASE64URL_CHAR( (udata[i] << 4) + (udata[i+1] >> 4) );
                *p++ = BASE64URL_CHAR( (udata[i+1] << 2) );
            }
        }
        *p++ = '\0';
        return (char *)enc;
    }
    
    /*******************************************************************************
     * link header handling 
     ******************************************************************************/
    
    typedef struct {
        const char *s;
        apr_size_t slen;
        apr_size_t i;
        apr_size_t link_start;
        apr_size_t link_len;
        apr_size_t pn_start;
        apr_size_t pn_len;
        apr_size_t pv_start;
        apr_size_t pv_len;
    } link_ctx;
    
    static int attr_char(char c) 
    {
        switch (c) {
            case '!':
            case '#':
            case '$':
            case '&':
            case '+':
            case '-':
            case '.':
            case '^':
            case '_':
            case '`':
            case '|':
            case '~':
                return 1;
            default:
                return apr_isalnum(c);
        }
    }
    
    static int ptoken_char(char c) 
    {
        switch (c) {
            case '!':
            case '#':
            case '$':
            case '&':
            case '\'':
            case '(':
            case ')':
            case '*':
            case '+':
            case '-':
            case '.':
            case '/':
            case ':':
            case '<':
            case '=':
            case '>':
            case '?':
            case '@':
            case '[':
            case ']':
            case '^':
            case '_':
            case '`':
            case '{':
            case '|':
            case '}':
            case '~':
                return 1;
            default:
                return apr_isalnum(c);
        }
    }
    
    static int skip_ws(link_ctx *ctx)
    {
        char c;
        while (ctx->i < ctx->slen 
               && (((c = ctx->s[ctx->i]) == ' ') || (c == '\t'))) {
            ++ctx->i;
        }
        return (ctx->i < ctx->slen);
    }
    
    static int skip_nonws(link_ctx *ctx)
    {
        char c;
        while (ctx->i < ctx->slen 
               && (((c = ctx->s[ctx->i]) != ' ') && (c != '\t'))) {
            ++ctx->i;
        }
        return (ctx->i < ctx->slen);
    }
    
    static unsigned int find_chr(link_ctx *ctx, char c, apr_size_t *pidx)
    {
        apr_size_t j;
        for (j = ctx->i; j < ctx->slen; ++j) {
            if (ctx->s[j] == c) {
                *pidx = j;
                return 1;
            }
        } 
        return 0;
    }
    
    static int read_chr(link_ctx *ctx, char c)
    {
        if (ctx->i < ctx->slen && ctx->s[ctx->i] == c) {
            ++ctx->i;
            return 1;
        }
        return 0;
    }
    
    static int skip_qstring(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, '\"')) {
            apr_size_t end;
            if (find_chr(ctx, '\"', &end)) {
                ctx->i = end + 1;
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_ptoken(link_ctx *ctx)
    {
        if (skip_ws(ctx)) {
            apr_size_t i;
            for (i = ctx->i; i < ctx->slen && ptoken_char(ctx->s[i]); ++i) {
                /* nop */
            }
            if (i > ctx->i) {
                ctx->i = i;
                return 1;
            }
        }
        return 0;
    }
    
    
    static int read_link(link_ctx *ctx)
    {
        ctx->link_start = ctx->link_len = 0;
        if (skip_ws(ctx) && read_chr(ctx, '<')) {
            apr_size_t end;
            if (find_chr(ctx, '>', &end)) {
                ctx->link_start = ctx->i;
                ctx->link_len = end - ctx->link_start;
                ctx->i = end + 1;
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_pname(link_ctx *ctx)
    {
        if (skip_ws(ctx)) {
            apr_size_t i;
            for (i = ctx->i; i < ctx->slen && attr_char(ctx->s[i]); ++i) {
                /* nop */
            }
            if (i > ctx->i) {
                ctx->i = i;
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_pvalue(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, '=')) {
            ctx->pv_start = ctx->i;
            if (skip_qstring(ctx) || skip_ptoken(ctx)) {
                ctx->pv_len = ctx->i - ctx->pv_start;
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_param(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, ';')) {
            ctx->pn_start = ctx->i;
            ctx->pn_len = 0;
            if (skip_pname(ctx)) {
                ctx->pn_len = ctx->i - ctx->pn_start;
                ctx->pv_len = 0;
                skip_pvalue(ctx); /* value is optional */
                return 1;
            }
        }
        return 0;
    }
    
    static int pv_contains(link_ctx *ctx, const char *s)
    {
        apr_size_t pvstart = ctx->pv_start;
        apr_size_t pvlen = ctx->pv_len;
        
        if (ctx->s[pvstart] == '\"' && pvlen > 1) {
            ++pvstart;
            pvlen -= 2;
        }
        if (pvlen > 0) {
            apr_size_t slen = strlen(s);
            link_ctx pvctx;
            apr_size_t i;
            
            memset(&pvctx, 0, sizeof(pvctx));
            pvctx.s = ctx->s + pvstart;
            pvctx.slen = pvlen;
    
            for (i = 0; i < pvctx.slen; i = pvctx.i) {
                skip_nonws(&pvctx);
                if ((pvctx.i - i) == slen && !strncmp(s, pvctx.s + i, slen)) {
                    return 1;
                }
                skip_ws(&pvctx);
            }
        }
        return 0;
    }
    
    /* RFC 5988 <https://tools.ietf.org/html/rfc5988#section-6.2.1>
      Link           = "Link" ":" #link-value
      link-value     = "<" URI-Reference ">" *( ";" link-param )
      link-param     = ( ( "rel" "=" relation-types )
                     | ( "anchor" "=" <"> URI-Reference <"> )
                     | ( "rev" "=" relation-types )
                     | ( "hreflang" "=" Language-Tag )
                     | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) )
                     | ( "title" "=" quoted-string )
                     | ( "title*" "=" ext-value )
                     | ( "type" "=" ( media-type | quoted-mt ) )
                     | ( link-extension ) )
      link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] )
                     | ( ext-name-star "=" ext-value )
      ext-name-star  = parmname "*" ; reserved for RFC2231-profiled
                                    ; extensions.  Whitespace NOT
                                    ; allowed in between.
      ptoken         = 1*ptokenchar
      ptokenchar     = "!" | "#" | "$" | "%" | "&" | "'" | "("
                     | ")" | "*" | "+" | "-" | "." | "/" | DIGIT
                     | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA
                     | "[" | "]" | "^" | "_" | "`" | "{" | "|"
                     | "}" | "~"
      media-type     = type-name "/" subtype-name
      quoted-mt      = <"> media-type <">
      relation-types = relation-type
                     | <"> relation-type *( 1*SP relation-type ) <">
      relation-type  = reg-rel-type | ext-rel-type
      reg-rel-type   = LOALPHA *( LOALPHA | DIGIT | "." | "-" )
      ext-rel-type   = URI
      
      and from <https://tools.ietf.org/html/rfc5987>
      parmname      = 1*attr-char
      attr-char     = ALPHA / DIGIT
                       / "!" / "#" / "$" / "&" / "+" / "-" / "."
                       / "^" / "_" / "`" / "|" / "~"
     */
    
    typedef struct {
        apr_pool_t *pool;
        const char *relation;
        const char *url;
    } find_ctx;
    
    static int find_url(void *baton, const char *key, const char *value)
    {
        find_ctx *outer = baton;
        
        if (!apr_strnatcasecmp("link", key)) {
            link_ctx ctx;
            
            memset(&ctx, 0, sizeof(ctx));
            ctx.s = value;
            ctx.slen = strlen(value);
            
            while (read_link(&ctx)) {
                while (skip_param(&ctx)) {
                    if (ctx.pn_len == 3 && !strncmp("rel", ctx.s + ctx.pn_start, 3)
                        && pv_contains(&ctx, outer->relation)) {
                        /* this is the link relation we are looking for */
                        outer->url = apr_pstrndup(outer->pool, ctx.s + ctx.link_start, ctx.link_len);
                        return 0;
                    }
                }
            }
        }
        return 1;
    }
    
    const char *md_link_find_relation(const apr_table_t *headers, 
                                      apr_pool_t *pool, const char *relation)
    {
        find_ctx ctx;
        
        memset(&ctx, 0, sizeof(ctx));
        ctx.pool = pool;
        ctx.relation = relation;
        
        apr_table_do(find_url, &ctx, headers, NULL);
        
        return ctx.url;
    }
    
    const char *md_util_parse_ct(apr_pool_t *pool, const char *cth)
    {
        char       *type;
        const char *p;
        apr_size_t  hlen;
    
        if (!cth) return NULL;
    
        for( p = cth; *p && *p != ' ' && *p != ';'; ++p)
            ;
        hlen = (apr_size_t)(p - cth);
        type = apr_pcalloc( pool, hlen + 1 );
        assert(type);
        memcpy(type, cth, hlen);
        type[hlen] = '\0';
    
        return type;
        /* Could parse and return parameters here, but we don't need any at present.
         */
    }
    �������������������������������������������������httpd-2.4.64/modules/md/md_http.h�������������������������������������������������������������������0000664�0001751�0001751�00000024340�14301701440�016477� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_http_h
    #define mod_md_md_http_h
    
    struct apr_table_t;
    struct apr_bucket_brigade;
    struct apr_bucket_alloc_t;
    struct md_data_t;
    
    typedef struct md_http_t md_http_t;
    
    typedef struct md_http_request_t md_http_request_t;
    typedef struct md_http_response_t md_http_response_t;
    
    /**
     * Callback invoked once per request, either when an error was encountered
     * or when everything succeeded and the request is about to be released. Only
     * in the last case will the status be APR_SUCCESS.
     */
    typedef apr_status_t md_http_status_cb(const md_http_request_t *req, apr_status_t status, void *data);
    
    /**
     * Callback invoked when the complete response has been received.
     */
    typedef apr_status_t md_http_response_cb(const md_http_response_t *res, void *data);
    
    typedef struct md_http_callbacks_t md_http_callbacks_t;
    struct md_http_callbacks_t {
        md_http_status_cb *on_status;
        void *on_status_data;
        md_http_response_cb *on_response;
        void *on_response_data;
    };
    
    typedef struct md_http_timeouts_t md_http_timeouts_t;
    struct md_http_timeouts_t {
        apr_time_t overall;
        apr_time_t connect;
        long stall_bytes_per_sec;
        apr_time_t stalled;
    };
    
    struct md_http_request_t {
        md_http_t *http;
        apr_pool_t *pool;
        int id;
        struct apr_bucket_alloc_t *bucket_alloc;
        const char *method;
        const char *url;
        const char *user_agent;
        const char *proxy_url;
        const char *ca_file;
        const char *unix_socket_path;
        apr_table_t *headers;
        struct apr_bucket_brigade *body;
        apr_off_t body_len;
        apr_off_t resp_limit;
        md_http_timeouts_t timeout;
        md_http_callbacks_t cb;
        void *internals;
    };
    
    struct md_http_response_t {
        md_http_request_t *req;
        int status;
        apr_table_t *headers;
        struct apr_bucket_brigade *body;
    };
    
    apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent,
                                const char *proxy_url);
    
    void md_http_set_response_limit(md_http_t *http, apr_off_t resp_limit);
    
    /**
     * Clone a http instance, inheriting all settings from source_http.
     * The cloned instance is not tied in any way to the source.
     */
    apr_status_t md_http_clone(md_http_t **phttp,
                               apr_pool_t *p, md_http_t *source_http);
    
    /**
     * Set the timeout for the complete request. This needs to take everything from
     * DNS looksups, to conntects, to transfer of all data into account and should
     * be sufficiently large.
     * Set to 0 the have no timeout for this.
     */
    void md_http_set_timeout_default(md_http_t *http, apr_time_t timeout);
    void md_http_set_timeout(md_http_request_t *req, apr_time_t timeout);
    
    /**
     * Set the timeout for establishing a connection. 
     * Set to 0 the have no special timeout for this.
     */
    void md_http_set_connect_timeout_default(md_http_t *http, apr_time_t timeout);
    void md_http_set_connect_timeout(md_http_request_t *req, apr_time_t timeout);
    
    /**
     * Set the condition for when a transfer is considered "stalled", e.g. does not
     * progress at a sufficient rate and will be aborted.
     * Set to 0 the have no stall detection in place.
     */
    void md_http_set_stalling_default(md_http_t *http, long bytes_per_sec, apr_time_t timeout);
    void md_http_set_stalling(md_http_request_t *req, long bytes_per_sec, apr_time_t timeout);
    
    /**
     * Set a CA file (in PERM format) to use for root certificates when
     * verifying SSL connections. If not set (or set to NULL), the systems
     * certificate store will be used.
     */
    void md_http_set_ca_file(md_http_t *http, const char *ca_file);
    
    /**
     * Set the path of a unix domain socket for use instead of TCP
     * in a connection. Disable by providing NULL as path.
     */
    void md_http_set_unix_socket_path(md_http_t *http, const char *path);
    
    /**
     * Perform the request. Then this function returns, the request and
     * all its memory has been freed and must no longer be used.
     */
    apr_status_t md_http_perform(md_http_request_t *request);
    
    /**
     * Set the callback to be invoked once the status of a request is known.
     * @param req       the request
     * @param cb        the callback to invoke on the response
     * @param baton     data passed to the callback    
     */
    void md_http_set_on_status_cb(md_http_request_t *req, md_http_status_cb *cb, void *baton);
    
    /**
     * Set the callback to be invoked when the complete 
     * response has been successfully received. The HTTP status may
     * be 500, however.
     * @param req       the request
     * @param cb        the callback to invoke on the response
     * @param baton     data passed to the callback    
     */
    void md_http_set_on_response_cb(md_http_request_t *req, md_http_response_cb *cb, void *baton);
    
    /**
     * Create a GET request.
     * @param preq      the created request after success
     * @param http      the md_http instance 
     * @param url       the url to GET
     * @param headers   request headers
     */
    apr_status_t md_http_GET_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                    struct apr_table_t *headers);
    
    /**
     * Create a HEAD request.
     * @param preq      the created request after success
     * @param http      the md_http instance 
     * @param url       the url to GET
     * @param headers   request headers
     */
    apr_status_t md_http_HEAD_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                     struct apr_table_t *headers);
    
    /**
     * Create a POST request with a bucket brigade as request body.
     * @param preq      the created request after success
     * @param http      the md_http instance 
     * @param url       the url to GET
     * @param headers   request headers
     * @param content_type the content_type of the body or NULL
     * @param body      the body of the request or NULL
     * @param detect_len scan the body to detect its length
     */
    apr_status_t md_http_POST_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                     struct apr_table_t *headers, const char *content_type, 
                                     struct apr_bucket_brigade *body, int detect_len);
    
    /**
     * Create a POST request with known request body data.
     * @param preq      the created request after success
     * @param http      the md_http instance 
     * @param url       the url to GET
     * @param headers   request headers
     * @param content_type the content_type of the body or NULL
     * @param body      the body of the request or NULL
     */
    apr_status_t md_http_POSTd_create(md_http_request_t **preq, md_http_t *http, const char *url, 
                                      struct apr_table_t *headers, const char *content_type, 
                                      const struct md_data_t *body);
    
    /*
     * Convenience functions for create+perform.
     */
    apr_status_t md_http_GET_perform(md_http_t *http, const char *url, 
                                     struct apr_table_t *headers,
                                     md_http_response_cb *cb, void *baton);
    apr_status_t md_http_HEAD_perform(md_http_t *http, const char *url, 
                                      struct apr_table_t *headers,
                                      md_http_response_cb *cb, void *baton);
    apr_status_t md_http_POST_perform(md_http_t *http, const char *url, 
                                      struct apr_table_t *headers, const char *content_type, 
                                      struct apr_bucket_brigade *body, int detect_len, 
                                      md_http_response_cb *cb, void *baton);
    apr_status_t md_http_POSTd_perform(md_http_t *http, const char *url, 
                                       struct apr_table_t *headers, const char *content_type, 
                                       const struct md_data_t *body, 
                                       md_http_response_cb *cb, void *baton);
    
    void md_http_req_destroy(md_http_request_t *req);
    
    /** Return the next request for processing on APR_SUCCESS. Return ARP_ENOENT
     * when no request is available. Anything else is an error.
     */
    typedef apr_status_t md_http_next_req(md_http_request_t **preq, void *baton, 
                                          md_http_t *http, int in_flight);
    
    /**
     * Perform requests in parallel as retrieved from the nextreq function.
     * There are as many requests in flight as the nextreq functions provides. 
     *
     * To limit the number of parallel requests, nextreq should return APR_ENOENT when the limit
     * is reached. It will be called again when the number of in_flight requests changes.
     * 
     * When all requests are done, nextreq will be called one more time. Should it not
     * return anything, this function returns.
     */
    apr_status_t md_http_multi_perform(md_http_t *http, md_http_next_req *nextreq, void *baton);
    
    /**************************************************************************************************/
    /* interface to implementation */
    
    typedef apr_status_t md_http_init_cb(void);
    typedef void md_http_cleanup_cb(md_http_t *req, apr_pool_t *p);
    typedef void md_http_req_cleanup_cb(md_http_request_t *req);
    typedef apr_status_t md_http_perform_cb(md_http_request_t *req);
    typedef apr_status_t md_http_multi_perform_cb(md_http_t *http, apr_pool_t *p, 
                                                  md_http_next_req *nextreq, void *baton);
    
    typedef struct md_http_impl_t md_http_impl_t;
    struct md_http_impl_t {
        md_http_init_cb *init;
        md_http_req_cleanup_cb *req_cleanup;
        md_http_perform_cb *perform;
        md_http_multi_perform_cb *multi_perform;
        md_http_cleanup_cb *cleanup;
    };
    
    void md_http_use_implementation(md_http_impl_t *impl);
    
    /**
     * get/set data the implementation wants to remember between requests
     * in the same md_http_t instance.
     */
    void md_http_set_impl_data(md_http_t *http, void *data);
    void *md_http_get_impl_data(md_http_t *http);
    
    
    #endif /* md_http_h */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md.mak������������������������������������������������������������������0000664�0001751�0001751�00000041054�14246471025�016634� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_md.dsp
    !IF "$(CFG)" == ""
    CFG=mod_md - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_md - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_md - Win32 Release" && "$(CFG)" != "mod_md - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_md.mak" CFG="mod_md - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_md - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_md - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF "$(_HAVE_OSSL110)" == "1"
    SSLCRP=libcrypto
    SSLLIB=libssl
    SSLINC=/I ../../srclib/openssl/include
    SSLBIN=/libpath:../../srclib/openssl
    !ELSE 
    SSLCRP=libeay32
    SSLLIB=ssleay32
    SSLINC=/I ../../srclib/openssl/inc32
    SSLBIN=/libpath:../../srclib/openssl/out32dll
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_md - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_md.so"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_md.so"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\md_acme.obj"
    	-@erase "$(INTDIR)\md_acme_acct.obj"
    	-@erase "$(INTDIR)\md_acme_authz.obj"
    	-@erase "$(INTDIR)\md_acme_drive.obj"
    	-@erase "$(INTDIR)\md_acme_order.obj"
    	-@erase "$(INTDIR)\md_acmev2_drive.obj"
    	-@erase "$(INTDIR)\md_core.obj"
    	-@erase "$(INTDIR)\md_crypt.obj"
    	-@erase "$(INTDIR)\md_curl.obj"
    	-@erase "$(INTDIR)\md_event.obj"
    	-@erase "$(INTDIR)\md_http.obj"
    	-@erase "$(INTDIR)\md_json.obj"
    	-@erase "$(INTDIR)\md_jws.obj"
    	-@erase "$(INTDIR)\md_log.obj"
    	-@erase "$(INTDIR)\md_ocsp.obj"
    	-@erase "$(INTDIR)\md_reg.obj"
    	-@erase "$(INTDIR)\md_result.obj"
    	-@erase "$(INTDIR)\md_status.obj"
    	-@erase "$(INTDIR)\md_store.obj"
    	-@erase "$(INTDIR)\md_store_fs.obj"
    	-@erase "$(INTDIR)\md_tailscale.obj"
    	-@erase "$(INTDIR)\md_time.obj"
    	-@erase "$(INTDIR)\md_util.obj"
    	-@erase "$(INTDIR)\mod_md.obj"
    	-@erase "$(INTDIR)\mod_md.res"
    	-@erase "$(INTDIR)\mod_md_config.obj"
    	-@erase "$(INTDIR)\mod_md_drive.obj"
    	-@erase "$(INTDIR)\mod_md_status.obj"
    	-@erase "$(INTDIR)\mod_md_ocsp.obj"
    	-@erase "$(INTDIR)\mod_md_os.obj"
    	-@erase "$(INTDIR)\mod_md_src.idb"
    	-@erase "$(INTDIR)\mod_md_src.pdb"
    	-@erase "$(OUTDIR)\mod_md.exp"
    	-@erase "$(OUTDIR)\mod_md.lib"
    	-@erase "$(OUTDIR)\mod_md.pdb"
    	-@erase "$(OUTDIR)\mod_md.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../server/mpm/winnt" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" $(SSLINC) /I "../../srclib/jansson/include" /I "../../srclib/curl/include" /I "../ssl" /I "../core" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D ssize_t=long /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_md_src" /FD /I " ../ssl" /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_md.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME=mod_md.so /d LONG_NAME=Letsencrypt module for Apache 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_md.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib $(SSLCRP).lib $(SSLLIB).lib jansson.lib libcurl.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_md.pdb" /debug  /out:"$(OUTDIR)\mod_md.so" /implib:"$(OUTDIR)\mod_md.lib" /libpath:"../../srclib/apr/Release" /libpath:"../../srclib/apr-util/Release" /libpath:"../../Release/" $(SSLBIN) /libpath:"../../srclib/jansson/lib" /libpath:"../../srclib/curl/lib" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_md.obj" \
    	"$(INTDIR)\mod_md_config.obj" \
    	"$(INTDIR)\mod_md_drive.obj" \
    	"$(INTDIR)\mod_md_ocsp.obj" \
    	"$(INTDIR)\mod_md_os.obj" \
    	"$(INTDIR)\mod_md_status.obj" \
    	"$(INTDIR)\md_core.obj" \
    	"$(INTDIR)\md_crypt.obj" \
    	"$(INTDIR)\md_curl.obj" \
    	"$(INTDIR)\md_event.obj" \
    	"$(INTDIR)\md_http.obj" \
    	"$(INTDIR)\md_json.obj" \
    	"$(INTDIR)\md_jws.obj" \
    	"$(INTDIR)\md_log.obj" \
    	"$(INTDIR)\md_ocsp.obj" \
    	"$(INTDIR)\md_reg.obj" \
    	"$(INTDIR)\md_result.obj" \
    	"$(INTDIR)\md_status.obj" \
    	"$(INTDIR)\md_store.obj" \
    	"$(INTDIR)\md_store_fs.obj" \
    	"$(INTDIR)\md_tailscale.obj" \
    	"$(INTDIR)\md_time.obj" \
    	"$(INTDIR)\md_util.obj" \
    	"$(INTDIR)\md_acme.obj" \
    	"$(INTDIR)\md_acme_acct.obj" \
    	"$(INTDIR)\md_acme_authz.obj" \
    	"$(INTDIR)\md_acme_drive.obj" \
    	"$(INTDIR)\md_acme_order.obj" \
    	"$(INTDIR)\md_acmev2_drive.obj" \
    	"$(INTDIR)\mod_md.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_md.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_md.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    ALL : $(DS_POSTBUILD_DEP)
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    $(DS_POSTBUILD_DEP) : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_md.so"
       if exist .\Release\mod_md.so.manifest mt.exe -manifest .\Release\mod_md.so.manifest -outputresource:.\Release\mod_md.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_md - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_md.so"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_md.so"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\md_acme.obj"
    	-@erase "$(INTDIR)\md_acme_acct.obj"
    	-@erase "$(INTDIR)\md_acme_authz.obj"
    	-@erase "$(INTDIR)\md_acme_drive.obj"
    	-@erase "$(INTDIR)\md_acme_order.obj"
    	-@erase "$(INTDIR)\md_acmev2_drive.obj"
    	-@erase "$(INTDIR)\md_core.obj"
    	-@erase "$(INTDIR)\md_crypt.obj"
    	-@erase "$(INTDIR)\md_curl.obj"
    	-@erase "$(INTDIR)\md_event.obj"
    	-@erase "$(INTDIR)\md_http.obj"
    	-@erase "$(INTDIR)\md_json.obj"
    	-@erase "$(INTDIR)\md_jws.obj"
    	-@erase "$(INTDIR)\md_log.obj"
    	-@erase "$(INTDIR)\md_ocsp.obj"
    	-@erase "$(INTDIR)\md_reg.obj"
    	-@erase "$(INTDIR)\md_result.obj"
    	-@erase "$(INTDIR)\md_status.obj"
    	-@erase "$(INTDIR)\md_store.obj"
    	-@erase "$(INTDIR)\md_store_fs.obj"
    	-@erase "$(INTDIR)\md_tailscale.obj"
    	-@erase "$(INTDIR)\md_time.obj"
    	-@erase "$(INTDIR)\md_util.obj"
    	-@erase "$(INTDIR)\mod_md.obj"
    	-@erase "$(INTDIR)\mod_md.res"
    	-@erase "$(INTDIR)\mod_md_config.obj"
    	-@erase "$(INTDIR)\mod_md_drive.obj"
    	-@erase "$(INTDIR)\mod_md_status.obj"
    	-@erase "$(INTDIR)\mod_md_ocsp.obj"
    	-@erase "$(INTDIR)\mod_md_os.obj"
    	-@erase "$(INTDIR)\mod_md_src.idb"
    	-@erase "$(INTDIR)\mod_md_src.pdb"
    	-@erase "$(OUTDIR)\mod_md.exp"
    	-@erase "$(OUTDIR)\mod_md.lib"
    	-@erase "$(OUTDIR)\mod_md.pdb"
    	-@erase "$(OUTDIR)\mod_md.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" $(SSLINC) /I "../../srclib/jansson/include" /I "../../srclib/curl/include" /I "../core" /I "../generators" /I "../ssl" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D ssize_t=long /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_md_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_md.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME=mod_md.so /d LONG_NAME=http2_module for Apache 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_md.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib $(SSLCRP).lib $(SSLLIB).lib jansson_d.lib libcurl_debug.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_md.pdb" /debug  /out:"$(OUTDIR)\mod_md.so" /implib:"$(OUTDIR)\mod_md.lib" $(SSLBIN) /libpath:"../../srclib/jansson/lib" /libpath:"../../srclib/curl/lib" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_md.obj" \
    	"$(INTDIR)\mod_md_config.obj" \
    	"$(INTDIR)\mod_md_drive.obj" \
    	"$(INTDIR)\mod_md_ocsp.obj" \
    	"$(INTDIR)\mod_md_os.obj" \
    	"$(INTDIR)\mod_md_status.obj" \
    	"$(INTDIR)\md_core.obj" \
    	"$(INTDIR)\md_crypt.obj" \
    	"$(INTDIR)\md_curl.obj" \
    	"$(INTDIR)\md_event.obj" \
    	"$(INTDIR)\md_http.obj" \
    	"$(INTDIR)\md_json.obj" \
    	"$(INTDIR)\md_jws.obj" \
    	"$(INTDIR)\md_log.obj" \
    	"$(INTDIR)\md_ocsp.obj" \
    	"$(INTDIR)\md_reg.obj" \
    	"$(INTDIR)\md_result.obj" \
    	"$(INTDIR)\md_status.obj" \
    	"$(INTDIR)\md_store.obj" \
    	"$(INTDIR)\md_store_fs.obj" \
    	"$(INTDIR)\md_tailscale.obj" \
    	"$(INTDIR)\md_time.obj" \
    	"$(INTDIR)\md_util.obj" \
    	"$(INTDIR)\md_acme.obj" \
    	"$(INTDIR)\md_acme_acct.obj" \
    	"$(INTDIR)\md_acme_authz.obj" \
    	"$(INTDIR)\md_acme_drive.obj" \
    	"$(INTDIR)\md_acme_order.obj" \
    	"$(INTDIR)\md_acmev2_drive.obj" \
    	"$(INTDIR)\mod_md.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_md.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_md.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    ALL : $(DS_POSTBUILD_DEP)
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    $(DS_POSTBUILD_DEP) : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_md.so"
       if exist .\Debug\mod_md.so.manifest mt.exe -manifest .\Debug\mod_md.so.manifest -outputresource:.\Debug\mod_md.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_md.dep")
    !INCLUDE "mod_md.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_md.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_md - Win32 Release" || "$(CFG)" == "mod_md - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_md - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd "..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\md"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd "..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\md"
    
    !ELSEIF  "$(CFG)" == "mod_md - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd "..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\md"
    
    "libapr - Win32 DebugCLEAN" : 
       cd "..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\md"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_md - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd "..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\md"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd "..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\md"
    
    !ELSEIF  "$(CFG)" == "mod_md - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd "..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\md"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd "..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\md"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_md - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd "..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\md"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd "..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\md"
    
    !ELSEIF  "$(CFG)" == "mod_md - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd "..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\md"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd "..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\md"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_md - Win32 Release"
    
    
    "$(INTDIR)\mod_md.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_md.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_md.so" /d LONG_NAME="md_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_md - Win32 Debug"
    
    
    "$(INTDIR)\mod_md.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_md.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_md.so" /d LONG_NAME="md_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=./md_acme.c
    
    "$(INTDIR)\md_acme.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_acme_acct.c
    
    "$(INTDIR)\md_acme_acct.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_acme_authz.c
    
    "$(INTDIR)\md_acme_authz.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_acme_drive.c
    
    "$(INTDIR)\md_acme_drive.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_acme_order.c
    
    "$(INTDIR)\md_acme_order.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_acmev2_drive.c
    
    "$(INTDIR)\md_acmev2_drive.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_core.c
    
    "$(INTDIR)\md_core.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_crypt.c
    
    "$(INTDIR)\md_crypt.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_curl.c
    
    "$(INTDIR)\md_curl.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_event.c
    
    "$(INTDIR)\md_event.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_http.c
    
    "$(INTDIR)\md_http.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_json.c
    
    "$(INTDIR)\md_json.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_jws.c
    
    "$(INTDIR)\md_jws.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_log.c
    
    "$(INTDIR)\md_log.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_ocsp.c
    
    "$(INTDIR)\md_ocsp.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_reg.c
    
    "$(INTDIR)\md_reg.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_result.c
    
    "$(INTDIR)\md_result.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_status.c
    
    "$(INTDIR)\md_status.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_store.c
    
    "$(INTDIR)\md_store.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_store_fs.c
    
    "$(INTDIR)\md_store_fs.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_tailscale.c
    
    "$(INTDIR)\md_tailscale.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_time.c
    
    "$(INTDIR)\md_time.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./md_util.c
    
    "$(INTDIR)\md_util.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./mod_md.c
    
    "$(INTDIR)\mod_md.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./mod_md_config.c
    
    "$(INTDIR)\mod_md_config.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./mod_md_drive.c
    
    "$(INTDIR)\mod_md_drive.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./mod_md_ocsp.c
    
    "$(INTDIR)\mod_md_ocsp.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./mod_md_os.c
    
    "$(INTDIR)\mod_md_os.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./mod_md_status.c
    
    "$(INTDIR)\mod_md_status.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md.dsp������������������������������������������������������������������0000664�0001751�0001751�00000016011�14232231062�016633� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_md" - 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_md - 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_md.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_md.mak" CFG="mod_md - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_md - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_md - 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_md - 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 "ssize_t=long" /FD /c
    # ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../server/mpm/winnt" "/I ../ssl" /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /I "../../srclib/jansson/include" /I "../../srclib/curl/include" /I "../core"   /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ssize_t=long" /Fd"Release\mod_md_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 /fo"Release/mod_md.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d "BIN_NAME=mod_md.so" /d "LONG_NAME=Letsencrypt module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_md.so" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so
    # ADD LINK32 kernel32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib ssleay32.lib libeay32.lib jansson.lib libcurl.lib /libpath:"../../srclib/apr/Release" /libpath:"../../srclib/apr-util/Release" /libpath:"../../Release/" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/jansson/lib" /libpath:"../../srclib/curl/lib" /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_md.so" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_md.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_md - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "ssize_t=long" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../generators" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /I "../../srclib/jansson/include" /I "../../srclib/curl/include" /I "../core" /src" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ssize_t=long" /Fd"Debug\mod_md_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 /fo"Debug/mod_md.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d "BIN_NAME=mod_md.so" /d "LONG_NAME=md_module for Apache"
    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 /out:".\Debug\mod_md.so" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so
    # ADD LINK32 kernel32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib ssleay32.lib libeay32.lib jansson_d.lib libcurl_debug.lib /nologo /subsystem:windows /dll /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/jansson/lib" /libpath:"../../srclib/curl/lib" /incremental:no /debug /out:".\Debug\mod_md.so" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_md.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_md - Win32 Release"
    # Name "mod_md - Win32 Debug"
    # Begin Source File
    
    SOURCE=./mod_md.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_md_config.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_md_drive.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_md_ocsp.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_md_os.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_md_status.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_acme.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_acme_acct.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_acme_authz.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_acme_drive.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_acme_order.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_acmev2_drive.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_core.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_crypt.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_curl.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_http.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_event.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_json.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_jws.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_log.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_ocsp.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_reg.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_result.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_status.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_store.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_store_fs.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_tailscale.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_time.c
    # End Source File
    # Begin Source File
    
    SOURCE=./md_util.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_store_fs.h���������������������������������������������������������������0000664�0001751�0001751�00000005227�13511051361�017351� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_store_fs_h
    #define mod_md_md_store_fs_h
    
    struct md_store_t;
    
    /** 
     * Default file permissions set by the store, user only read/write(/exec),
     * if so supported by the apr. 
     */
    #define MD_FPROT_F_UONLY      (APR_FPROT_UREAD|APR_FPROT_UWRITE)
    #define MD_FPROT_D_UONLY      (MD_FPROT_F_UONLY|APR_FPROT_UEXECUTE)
    
    /**
     * User has all permission, group can read, other none
     */
    #define MD_FPROT_F_UALL_GREAD (MD_FPROT_F_UONLY|APR_FPROT_GREAD)
    #define MD_FPROT_D_UALL_GREAD (MD_FPROT_D_UONLY|APR_FPROT_GREAD|APR_FPROT_GEXECUTE)
    
    /**
     * User has all permission, group and others can read
     */
    #define MD_FPROT_F_UALL_WREAD (MD_FPROT_F_UALL_GREAD|APR_FPROT_WREAD)
    #define MD_FPROT_D_UALL_WREAD (MD_FPROT_D_UALL_GREAD|APR_FPROT_WREAD|APR_FPROT_WEXECUTE)
    
    apr_status_t md_store_fs_init(struct md_store_t **pstore, apr_pool_t *p, 
                                  const char *path);
    
    
    apr_status_t md_store_fs_default_perms_set(struct md_store_t *store, 
                                               apr_fileperms_t file_perms,
                                               apr_fileperms_t dir_perms);
    apr_status_t md_store_fs_group_perms_set(struct md_store_t *store, 
                                             md_store_group_t group, 
                                             apr_fileperms_t file_perms,
                                             apr_fileperms_t dir_perms);
    
    typedef enum {
        MD_S_FS_EV_CREATED,
        MD_S_FS_EV_MOVED,
    } md_store_fs_ev_t; 
    
    typedef apr_status_t md_store_fs_cb(void *baton, struct md_store_t *store,
                                        md_store_fs_ev_t ev, unsigned int group, 
                                        const char *fname, apr_filetype_e ftype,  
                                        apr_pool_t *p);
                                        
    apr_status_t md_store_fs_set_event_cb(struct md_store_t *store, md_store_fs_cb *cb, void *baton);
    
    #endif /* mod_md_md_store_fs_h */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_time.h�������������������������������������������������������������������0000664�0001751�0001751�00000006105�14046725222�016467� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_time_h
    #define mod_md_md_time_h
    
    #include <stdio.h>
    
    #define MD_SECS_PER_HOUR      (60*60)
    #define MD_SECS_PER_DAY       (24*MD_SECS_PER_HOUR)
    
    typedef struct md_timeperiod_t md_timeperiod_t;
    
    struct md_timeperiod_t {
        apr_time_t start;
        apr_time_t end;
    };
    
    apr_time_t md_timeperiod_length(const md_timeperiod_t *period);
    
    int md_timeperiod_contains(const md_timeperiod_t *period, apr_time_t time);
    int md_timeperiod_has_started(const md_timeperiod_t *period, apr_time_t time);
    int md_timeperiod_has_ended(const md_timeperiod_t *period, apr_time_t time);
    apr_interval_time_t md_timeperiod_remaining(const md_timeperiod_t *period, apr_time_t time);
    
    /**
     * Return the timeperiod common between a and b. If both do not overlap, return {0,0}.
     */
    md_timeperiod_t md_timeperiod_common(const md_timeperiod_t *a, const md_timeperiod_t *b);
    
    char *md_timeperiod_print(apr_pool_t *p, const md_timeperiod_t *period);
    
    /**
     * Print a human readable form of the give duration in days/hours/min/sec 
     */
    const char *md_duration_print(apr_pool_t *p, apr_interval_time_t duration);
    const char *md_duration_roughly(apr_pool_t *p, apr_interval_time_t duration);
    
    /**
     * Parse a machine readable string duration in the form of NN[unit], where
     * unit is d/h/mi/s/ms with the default given should the unit not be specified.
     */
    apr_status_t md_duration_parse(apr_interval_time_t *ptimeout, const char *value, 
                                   const char *def_unit);
    const char *md_duration_format(apr_pool_t *p, apr_interval_time_t duration);
    
    typedef struct {
        apr_interval_time_t norm; /* if > 0, normalized base length */
        apr_interval_time_t len;  /* length of the timespan */
    } md_timeslice_t;
    
    apr_status_t md_timeslice_create(md_timeslice_t **pts, apr_pool_t *p,
                                     apr_interval_time_t norm, apr_interval_time_t len); 
    
    int md_timeslice_eq(const md_timeslice_t *ts1, const md_timeslice_t *ts2);
    
    const char *md_timeslice_parse(md_timeslice_t **pts, apr_pool_t *p, 
                                  const char *val, apr_interval_time_t defnorm);
    const char *md_timeslice_format(const md_timeslice_t *ts, apr_pool_t *p);
    
    md_timeperiod_t md_timeperiod_slice_before_end(const md_timeperiod_t *period, 
                                                   const md_timeslice_t *ts);
    
    #endif /* md_util_h */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/mod_md_os.h�����������������������������������������������������������������0000664�0001751�0001751�00000002644�13234043402�017004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_md_md_os_h
    #define mod_md_md_os_h
    
    /**
     * Try chown'ing the file/directory. Give id -1 to not change uid/gid.
     * Will return APR_ENOTIMPL on platforms not supporting this operation.
     */
    apr_status_t md_try_chown(const char *fname, unsigned int uid, int gid, apr_pool_t *p);
    
    /**
     * Make a file or directory read/write(/searchable) by httpd workers.
     */
    apr_status_t md_make_worker_accessible(const char *fname, apr_pool_t *p);
    
    /**
     * Trigger a graceful restart of the server. Depending on the architecture, may
     * return APR_ENOTIMPL.
     */
    apr_status_t md_server_graceful(apr_pool_t *p, server_rec *s);
    
    #endif /* mod_md_md_os_h */
    ��������������������������������������������������������������������������������������������httpd-2.4.64/modules/md/md_log.c��������������������������������������������������������������������0000664�0001751�0001751�00000003674�13234043402�016304� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_lib.h>
    #include <apr_strings.h>
    #include <apr_buckets.h>
    
    #include "md_log.h"
    
    #define LOG_BUFFER_LEN  1024
    
    static const char *level_names[] = {
        "emergency",
        "alert",
        "crit",
        "err",
        "warning",
        "notice",
        "info",
        "debug",
        "trace1",
        "trace2",
        "trace3",
        "trace4",
        "trace5",
        "trace6",
        "trace7",
        "trace8",
    };
    
    const char *md_log_level_name(md_log_level_t level)
    {
        return level_names[level];
    }
    
    static md_log_print_cb *log_printv;
    static md_log_level_cb *log_level;
    static void *log_baton;
    
    void md_log_set(md_log_level_cb *level_cb, md_log_print_cb *print_cb, void *baton)
    {
        log_printv = print_cb;
        log_level = level_cb;
        log_baton = baton;
    }
    
    int md_log_is_level(apr_pool_t *p, md_log_level_t level)
    {
        if (!log_level) {
            return 0;
        }
        return log_level(log_baton, p, level);
    }
    
    void md_log_perror(const char *file, int line, md_log_level_t level, 
                       apr_status_t rv, apr_pool_t *p, const char *fmt, ...)
    {
        va_list ap;
    
        va_start(ap, fmt);
        if (log_printv) {
            log_printv(file, line, level, rv, log_baton, p, fmt, ap);
        }
        va_end(ap);
    }
    ��������������������������������������������������������������������httpd-2.4.64/modules/http2/�������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�015344� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_bucket_beam.h���������������������������������������������������������0000664�0001751�0001751�00000023252�14473316336�020354� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 h2_bucket_beam_h
    #define h2_bucket_beam_h
    
    #include "h2_conn_ctx.h"
    
    struct apr_thread_mutex_t;
    struct apr_thread_cond_t;
    
    /**
     * A h2_bucket_beam solves the task of transferring buckets, esp. their data,
     * across threads with as little copying as possible.
     */
    
    typedef struct h2_bucket_beam h2_bucket_beam;
    
    typedef void h2_beam_io_callback(void *ctx, h2_bucket_beam *beam,
                                     apr_off_t bytes);
    typedef void h2_beam_ev_callback(void *ctx, h2_bucket_beam *beam);
    
    /**
     * h2_blist can hold a list of buckets just like apr_bucket_brigade, but
     * does not to any allocations or related features.
     */
    typedef struct {
        APR_RING_HEAD(h2_bucket_list, apr_bucket) list;
    } h2_blist;
    
    struct h2_bucket_beam {
        int id;
        const char *name;
        conn_rec *from;
        apr_pool_t *pool;
        h2_blist buckets_to_send;
        h2_blist buckets_consumed;
        h2_blist buckets_eor;
    
        apr_size_t max_buf_size;
        apr_interval_time_t timeout;
    
        int aborted;
        int closed;
        int tx_mem_limits; /* only memory size counts on transfers */
        int copy_files;
    
        struct apr_thread_mutex_t *lock;
        struct apr_thread_cond_t *change;
        
        h2_beam_ev_callback *was_empty_cb; /* event: beam changed to non-empty in h2_beam_send() */
        void *was_empty_ctx;
        h2_beam_ev_callback *recv_cb;      /* event: buckets were transfered in h2_beam_receive() */
        void *recv_ctx;
        h2_beam_ev_callback *send_cb;      /* event: buckets were added in h2_beam_send() */
        void *send_ctx;
        h2_beam_ev_callback *eagain_cb;    /* event: a receive results in ARP_EAGAIN */
        void *eagain_ctx;
    
        apr_off_t recv_bytes;             /* amount of bytes transferred in h2_beam_receive() */
        apr_off_t recv_bytes_reported;    /* amount of bytes reported as received via callback */
        h2_beam_io_callback *cons_io_cb;  /* report: recv_bytes deltas for sender */
        void *cons_ctx;
    };
    
    /**
     * Creates a new bucket beam for transfer of buckets across threads.
     *
     * The pool the beam is created with will be protected by the given 
     * mutex and will be used in multiple threads. It needs a pool allocator
     * that is only used inside that same mutex.
     *
     * @param pbeam         will hold the created beam on return
     * @param c_from        connection from which buchets are sent
     * @param pool          pool owning the beam, beam will cleanup when pool released
     * @param id            identifier of the beam
     * @param tag           tag identifying beam for logging
     * @param buffer_size   maximum memory footprint of buckets buffered in beam, or
     *                      0 for no limitation
     * @param timeout       timeout for blocking operations
     */
    apr_status_t h2_beam_create(h2_bucket_beam **pbeam,
                                conn_rec *from,
                                apr_pool_t *pool, 
                                int id, const char *tag,
                                apr_size_t buffer_size,
                                apr_interval_time_t timeout);
    
    /**
     * Destroys the beam immediately without cleanup.
     */ 
    apr_status_t h2_beam_destroy(h2_bucket_beam *beam, conn_rec *c);
    
    /**
     * Switch copying of file buckets on/off.
     */
    void h2_beam_set_copy_files(h2_bucket_beam * beam, int enabled);
    
    /**
     * Send buckets from the given brigade through the beam.
     * This can block of the amount of bucket data is above the buffer limit.
     * @param beam the beam to add buckets to
     * @param from the connection the sender operates on, must be the same as
     *             used to create the beam
     * @param bb the brigade to take buckets from
     * @param block if the sending should block when the buffer is full
     * @param pwritten on return, contains the number of data bytes sent
     * @return APR_SUCCESS when buckets were added to the beam. This can be
     *                     a partial transfer and other buckets may still remain in bb
     *         APR_EAGAIN on non-blocking send when the buffer is full
     *         APR_TIMEUP on blocking semd that time out
     *         APR_ECONNABORTED when beam has been aborted
     */
    apr_status_t h2_beam_send(h2_bucket_beam *beam, conn_rec *from,
                              apr_bucket_brigade *bb, 
                              apr_read_type_e block,
                              apr_off_t *pwritten);
    
    /**
     * Receive buckets from the beam into the given brigade. The caller is
     * operating on connection `to`.
     * @param beam the beam to receive buckets from
     * @param to the connection the receiver is working with
     * @param bb the bucket brigade to append to
     * @param block if the read should block when buckets are unavailable
     * @param readbytes the amount of data the receiver wants
     * @return APR_SUCCESS when buckets were appended
     *         APR_EAGAIN on non-blocking read when no buckets are available
     *         APR_TIMEUP on blocking reads that time out
     *         APR_ECONNABORTED when beam has been aborted
     */
    apr_status_t h2_beam_receive(h2_bucket_beam *beam, conn_rec *to,
                                 apr_bucket_brigade *bb,
                                 apr_read_type_e block,
                                 apr_off_t readbytes);
    
    /**
     * Determine if beam is empty. 
     */
    int h2_beam_empty(h2_bucket_beam *beam);
    
    /**
     * Abort the beam, either from receiving or sending side.
     *
     * @param beam the beam to abort
     * @param c the connection the caller is working with
     */
    void h2_beam_abort(h2_bucket_beam *beam, conn_rec *c);
    
    /**
     * Close the beam. Make certain an EOS is sent.
     *
     * @param beam the beam to abort
     * @param c the connection the caller is working with
     */
    void h2_beam_close(h2_bucket_beam *beam, conn_rec *c);
    
    /**
     * Set/get the timeout for blocking sebd/receive operations.
     */
    void h2_beam_timeout_set(h2_bucket_beam *beam, 
                             apr_interval_time_t timeout);
    
    apr_interval_time_t h2_beam_timeout_get(h2_bucket_beam *beam);
    
    /**
     * Set/get the maximum buffer size for beam data (memory footprint).
     */
    void h2_beam_buffer_size_set(h2_bucket_beam *beam, 
                                 apr_size_t buffer_size);
    apr_size_t h2_beam_buffer_size_get(h2_bucket_beam *beam);
    
    /**
     * Register a callback to be invoked on the sender side with the
     * amount of bytes that have been consumed by the receiver, since the
     * last callback invocation or reset.
     * @param beam the beam to set the callback on
     * @param io_cb the callback or NULL, called on sender with bytes consumed
     * @param ctx  the context to use in callback invocation
     * 
     * Call from the sender side, io callbacks invoked on sender side, ev callback
     * from any side.
     */
    void h2_beam_on_consumed(h2_bucket_beam *beam, 
                             h2_beam_io_callback *io_cb, void *ctx);
    
    /**
     * Register a callback to be invoked on the receiver side whenever
     * buckets have been transfered in a h2_beam_receive() call.
     * @param beam the beam to set the callback on
     * @param recv_cb the callback or NULL, called when buckets are received
     * @param ctx  the context to use in callback invocation
     */
    void h2_beam_on_received(h2_bucket_beam *beam,
                             h2_beam_ev_callback *recv_cb, void *ctx);
    
    /**
     * Register a callback to be invoked on the receiver side whenever
     * APR_EAGAIN is being returned in h2_beam_receive().
     * @param beam the beam to set the callback on
     * @param egain_cb the callback or NULL, called before APR_EAGAIN is returned
     * @param ctx  the context to use in callback invocation
     */
    void h2_beam_on_eagain(h2_bucket_beam *beam,
                           h2_beam_ev_callback *eagain_cb, void *ctx);
    
    /**
     * Register a call back from the sender side to be invoked when send
     * has added buckets to the beam.
     * Unregister by passing a NULL on_send_cb.
     * @param beam the beam to set the callback on
     * @param on_send_cb the callback to invoke after buckets were added
     * @param ctx  the context to use in callback invocation
     */
    void h2_beam_on_send(h2_bucket_beam *beam,
                         h2_beam_ev_callback *on_send_cb, void *ctx);
    
    /**
     * Register a call back from the sender side to be invoked when send
     * has added to a previously empty beam.
     * Unregister by passing a NULL was_empty_cb.
     * @param beam the beam to set the callback on
     * @param was_empty_cb the callback to invoke on blocked send
     * @param ctx  the context to use in callback invocation
     */
    void h2_beam_on_was_empty(h2_bucket_beam *beam,
                              h2_beam_ev_callback *was_empty_cb, void *ctx);
    
    /**
     * Call any registered consumed handler, if any changes have happened
     * since the last invocation. 
     * @return !=0 iff a handler has been called
     *
     * Needs to be invoked from the sending side.
     */
    int h2_beam_report_consumption(h2_bucket_beam *beam);
    
    /**
     * Get the amount of bytes currently buffered in the beam (unread).
     */
    apr_off_t h2_beam_get_buffered(h2_bucket_beam *beam);
    
    /**
     * Get the memory used by the buffered buckets, approximately.
     */
    apr_off_t h2_beam_get_mem_used(h2_bucket_beam *beam);
    
    /**
     * @return != 0 iff beam has been closed or has an EOS bucket buffered
     *                  waiting to be received.
     */
    int h2_beam_is_complete(h2_bucket_beam *beam);
    
    #endif /* h2_bucket_beam_h */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_push.c����������������������������������������������������������������0000664�0001751�0001751�00000062727�14473316336�017077� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_hash.h>
    #include <apr_time.h>
    
    #ifdef H2_OPENSSL
    #include <openssl/evp.h>
    #endif
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <http_protocol.h>
    
    #include "h2_private.h"
    #include "h2_protocol.h"
    #include "h2_util.h"
    #include "h2_push.h"
    #include "h2_request.h"
    #include "h2_session.h"
    #include "h2_stream.h"
    
    /*******************************************************************************
     * link header handling 
     ******************************************************************************/
    
    static const char *policy_str(h2_push_policy policy)
    {
        switch (policy) {
            case H2_PUSH_NONE:
                return "none";
            case H2_PUSH_FAST_LOAD:
                return "fast-load";
            case H2_PUSH_HEAD:
                return "head";
            default:
                return "default";
        }
    }
    
    typedef struct {
        const h2_request *req;
        apr_uint32_t push_policy;
        apr_pool_t *pool;
        apr_array_header_t *pushes;
        const char *s;
        size_t slen;
        size_t i;
        
        const char *link;
        apr_table_t *params;
        char b[4096];
    } link_ctx;
    
    static int attr_char(char c) 
    {
        switch (c) {
            case '!':
            case '#':
            case '$':
            case '&':
            case '+':
            case '-':
            case '.':
            case '^':
            case '_':
            case '`':
            case '|':
            case '~':
                return 1;
            default:
                return apr_isalnum(c);
        }
    }
    
    static int ptoken_char(char c) 
    {
        switch (c) {
            case '!':
            case '#':
            case '$':
            case '&':
            case '\'':
            case '(':
            case ')':
            case '*':
            case '+':
            case '-':
            case '.':
            case '/':
            case ':':
            case '<':
            case '=':
            case '>':
            case '?':
            case '@':
            case '[':
            case ']':
            case '^':
            case '_':
            case '`':
            case '{':
            case '|':
            case '}':
            case '~':
                return 1;
            default:
                return apr_isalnum(c);
        }
    }
    
    static int skip_ws(link_ctx *ctx)
    {
        char c;
        while (ctx->i < ctx->slen 
               && (((c = ctx->s[ctx->i]) == ' ') || (c == '\t'))) {
            ++ctx->i;
        }
        return (ctx->i < ctx->slen);
    }
    
    static int find_chr(link_ctx *ctx, char c, size_t *pidx)
    {
        size_t j;
        for (j = ctx->i; j < ctx->slen; ++j) {
            if (ctx->s[j] == c) {
                *pidx = j;
                return 1;
            }
        } 
        return 0;
    }
    
    static int read_chr(link_ctx *ctx, char c)
    {
        if (ctx->i < ctx->slen && ctx->s[ctx->i] == c) {
            ++ctx->i;
            return 1;
        }
        return 0;
    }
    
    static char *mk_str(link_ctx *ctx, size_t end) 
    {
        if (ctx->i < end) {
            return apr_pstrndup(ctx->pool, ctx->s + ctx->i, end - ctx->i);
        }
        return (char*)"";
    }
    
    static int read_qstring(link_ctx *ctx, const char **ps)
    {
        if (skip_ws(ctx) && read_chr(ctx, '\"')) {
            size_t end;
            if (find_chr(ctx, '\"', &end)) {
                *ps = mk_str(ctx, end);
                ctx->i = end + 1;
                return 1;
            }
        }
        return 0;
    }
    
    static int read_ptoken(link_ctx *ctx, const char **ps)
    {
        if (skip_ws(ctx)) {
            size_t i;
            for (i = ctx->i; i < ctx->slen && ptoken_char(ctx->s[i]); ++i) {
                /* nop */
            }
            if (i > ctx->i) {
                *ps = mk_str(ctx, i);
                ctx->i = i;
                return 1;
            }
        }
        return 0;
    }
    
    
    static int read_link(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, '<')) {
            size_t end;
            if (find_chr(ctx, '>', &end)) {
                ctx->link = mk_str(ctx, end);
                ctx->i = end + 1;
                return 1;
            }
        }
        return 0;
    }
    
    static int read_pname(link_ctx *ctx, const char **pname)
    {
        if (skip_ws(ctx)) {
            size_t i;
            for (i = ctx->i; i < ctx->slen && attr_char(ctx->s[i]); ++i) {
                /* nop */
            }
            if (i > ctx->i) {
                *pname = mk_str(ctx, i);
                ctx->i = i;
                return 1;
            }
        }
        return 0;
    }
    
    static int read_pvalue(link_ctx *ctx, const char **pvalue)
    {
        if (skip_ws(ctx) && read_chr(ctx, '=')) {
            if (read_qstring(ctx, pvalue) || read_ptoken(ctx, pvalue)) {
                return 1;
            }
        }
        return 0;
    }
    
    static int read_param(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, ';')) {
            const char *name, *value = "";
            if (read_pname(ctx, &name)) {
                read_pvalue(ctx, &value); /* value is optional */
                apr_table_setn(ctx->params, name, value);
                return 1;
            }
        }
        return 0;
    }
    
    static int read_sep(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, ',')) {
            return 1;
        }
        return 0;
    }
    
    static void init_params(link_ctx *ctx) 
    {
        if (!ctx->params) {
            ctx->params = apr_table_make(ctx->pool, 5);
        }
        else {
            apr_table_clear(ctx->params);
        }
    }
    
    static int same_authority(const h2_request *req, const apr_uri_t *uri)
    {
        if (uri->scheme != NULL && strcmp(uri->scheme, req->scheme)) {
            return 0;
        }
        if (uri->hostinfo != NULL && strcmp(uri->hostinfo, req->authority)) {
            return 0;
        }
        return 1;
    }
    
    static int set_push_header(void *ctx, const char *key, const char *value) 
    {
        size_t klen = strlen(key);
        if (H2_HD_MATCH_LIT("User-Agent", key, klen)
            || H2_HD_MATCH_LIT("Accept", key, klen)
            || H2_HD_MATCH_LIT("Accept-Encoding", key, klen)
            || H2_HD_MATCH_LIT("Accept-Language", key, klen)
            || H2_HD_MATCH_LIT("Cache-Control", key, klen)) {
            apr_table_setn(ctx, key, value);
        }
        return 1;
    }
    
    static int has_param(link_ctx *ctx, const char *param)
    {
        const char *p = apr_table_get(ctx->params, param);
        return !!p;
    }
    
    static int has_relation(link_ctx *ctx, const char *rel)
    {
        const char *s, *val = apr_table_get(ctx->params, "rel");
        if (val) {
            if (!strcmp(rel, val)) {
                return 1;
            }
            s = ap_strstr_c(val, rel);
            if (s && (s == val || s[-1] == ' ')) {
                s += strlen(rel);
                if (!*s || *s == ' ') {
                    return 1;
                }
            }
        }
        return 0;
    }
    
    static int add_push(link_ctx *ctx)
    {
        /* so, we have read a Link header and need to decide
         * if we transform it into a push.
         */
        if (has_relation(ctx, "preload") && !has_param(ctx, "nopush")) {
            apr_uri_t uri;
            if (apr_uri_parse(ctx->pool, ctx->link, &uri) == APR_SUCCESS) {
                if (uri.path && same_authority(ctx->req, &uri)) {
                    char *path;
                    const char *method;
                    apr_table_t *headers;
                    h2_request *req;
                    h2_push *push;
                    
                    /* We only want to generate pushes for resources in the
                     * same authority than the original request.
                     * icing: i think that is wise, otherwise we really need to
                     * check that the vhost/server is available and uses the same
                     * TLS (if any) parameters.
                     */
                    path = apr_uri_unparse(ctx->pool, &uri, APR_URI_UNP_OMITSITEPART);
                    push = apr_pcalloc(ctx->pool, sizeof(*push));
                    switch (ctx->push_policy) {
                        case H2_PUSH_HEAD:
                            method = "HEAD";
                            break;
                        default:
                            method = "GET";
                            break;
                    }
                    headers = apr_table_make(ctx->pool, 5);
                    apr_table_do(set_push_header, headers, ctx->req->headers, NULL);
                    req = h2_request_create(0, ctx->pool, method, ctx->req->scheme,
                                            ctx->req->authority, path, headers);
                    /* atm, we do not push on pushes */
                    h2_request_end_headers(req, ctx->pool, 0);
                    push->req = req;
                    if (has_param(ctx, "critical")) {
                        h2_priority *prio = apr_pcalloc(ctx->pool, sizeof(*prio));
                        prio->dependency = H2_DEPENDANT_BEFORE;
                        push->priority = prio;
                    }
                    if (!ctx->pushes) {
                        ctx->pushes = apr_array_make(ctx->pool, 5, sizeof(h2_push*));
                    }
                    APR_ARRAY_PUSH(ctx->pushes, h2_push*) = push;
                }
            }
        }
        return 0;
    }
    
    static void inspect_link(link_ctx *ctx, const char *s, size_t slen)
    {
        /* RFC 5988 <https://tools.ietf.org/html/rfc5988#section-6.2.1>
          Link           = "Link" ":" #link-value
          link-value     = "<" URI-Reference ">" *( ";" link-param )
          link-param     = ( ( "rel" "=" relation-types )
                         | ( "anchor" "=" <"> URI-Reference <"> )
                         | ( "rev" "=" relation-types )
                         | ( "hreflang" "=" Language-Tag )
                         | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) )
                         | ( "title" "=" quoted-string )
                         | ( "title*" "=" ext-value )
                         | ( "type" "=" ( media-type | quoted-mt ) )
                         | ( link-extension ) )
          link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] )
                         | ( ext-name-star "=" ext-value )
          ext-name-star  = parmname "*" ; reserved for RFC2231-profiled
                                        ; extensions.  Whitespace NOT
                                        ; allowed in between.
          ptoken         = 1*ptokenchar
          ptokenchar     = "!" | "#" | "$" | "%" | "&" | "'" | "("
                         | ")" | "*" | "+" | "-" | "." | "/" | DIGIT
                         | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA
                         | "[" | "]" | "^" | "_" | "`" | "{" | "|"
                         | "}" | "~"
          media-type     = type-name "/" subtype-name
          quoted-mt      = <"> media-type <">
          relation-types = relation-type
                         | <"> relation-type *( 1*SP relation-type ) <">
          relation-type  = reg-rel-type | ext-rel-type
          reg-rel-type   = LOALPHA *( LOALPHA | DIGIT | "." | "-" )
          ext-rel-type   = URI
          
          and from <https://tools.ietf.org/html/rfc5987>
          parmname      = 1*attr-char
          attr-char     = ALPHA / DIGIT
                           / "!" / "#" / "$" / "&" / "+" / "-" / "."
                           / "^" / "_" / "`" / "|" / "~"
         */
    
         ctx->s = s;
         ctx->slen = slen;
         ctx->i = 0;
         
         while (read_link(ctx)) {
            init_params(ctx);
            while (read_param(ctx)) {
                /* nop */
            }
            add_push(ctx);
            if (!read_sep(ctx)) {
                break;
            }
         }
    }
    
    static int head_iter(void *ctx, const char *key, const char *value) 
    {
        if (!ap_cstr_casecmp("link", key)) {
            inspect_link(ctx, value, strlen(value));
        }
        return 1;
    }
    
    #if AP_HAS_RESPONSE_BUCKETS
    apr_array_header_t *h2_push_collect(apr_pool_t *p,
                                        const struct h2_request *req,
                                        apr_uint32_t push_policy,
                                        const ap_bucket_response *res)
    #else
    apr_array_header_t *h2_push_collect(apr_pool_t *p,
                                        const struct h2_request *req,
                                        apr_uint32_t push_policy,
                                        const struct h2_headers *res)
    #endif
    {
        if (req && push_policy != H2_PUSH_NONE) {
            /* Collect push candidates from the request/response pair.
             * 
             * One source for pushes are "rel=preload" link headers
             * in the response.
             * 
             * TODO: This may be extended in the future by hooks or callbacks
             * where other modules can provide push information directly.
             */
            if (res->headers) {
                link_ctx ctx;
                
                memset(&ctx, 0, sizeof(ctx));
                ctx.req = req;
                ctx.push_policy = push_policy;
                ctx.pool = p;
                
                apr_table_do(head_iter, &ctx, res->headers, NULL);
                if (ctx.pushes) {
                    apr_table_setn(res->headers, "push-policy", 
                                   policy_str(push_policy));
                }
                return ctx.pushes;
            }
        }
        return NULL;
    }
    
    #define GCSLOG_LEVEL   APLOG_TRACE1
    
    typedef struct h2_push_diary_entry {
        apr_uint64_t hash;
    } h2_push_diary_entry;
    
    
    #ifdef H2_OPENSSL
    static void sha256_update(EVP_MD_CTX *ctx, const char *s)
    {
        EVP_DigestUpdate(ctx, s, strlen(s));
    }
    
    static void calc_sha256_hash(h2_push_diary *diary, apr_uint64_t *phash, h2_push *push) 
    {
        EVP_MD_CTX *md;
        apr_uint64_t val;
        unsigned char hash[EVP_MAX_MD_SIZE];
        unsigned len, i;
    
        md = EVP_MD_CTX_create();
        ap_assert(md != NULL);
    
        i = EVP_DigestInit_ex(md, EVP_sha256(), NULL);
        ap_assert(i == 1);
        sha256_update(md, push->req->scheme);
        sha256_update(md, "://");
        sha256_update(md, push->req->authority);
        sha256_update(md, push->req->path);
        EVP_DigestFinal(md, hash, &len);
        EVP_MD_CTX_destroy(md);
    
        val = 0;
        for (i = 0; i != len; ++i)
            val = val * 256 + hash[i];
        *phash = val >> (64 - diary->mask_bits);
    }
    #endif
    
    
    static unsigned int val_apr_hash(const char *str) 
    {
        apr_ssize_t len = (apr_ssize_t)strlen(str);
        return apr_hashfunc_default(str, &len);
    }
    
    static void calc_apr_hash(h2_push_diary *diary, apr_uint64_t *phash, h2_push *push) 
    {
        apr_uint64_t val;
        (void)diary;
    #if APR_UINT64_MAX > UINT_MAX
        val = ((apr_uint64_t)(val_apr_hash(push->req->scheme)) << 32);
        val ^= ((apr_uint64_t)(val_apr_hash(push->req->authority)) << 16);
        val ^= val_apr_hash(push->req->path);
    #else
        val = val_apr_hash(push->req->scheme);
        val ^= val_apr_hash(push->req->authority);
        val ^= val_apr_hash(push->req->path);
    #endif
        *phash = val;
    }
    
    static apr_int32_t ceil_power_of_2(apr_int32_t n)
    {
        if (n <= 2) return 2;
        --n;
        n |= n >> 1;
        n |= n >> 2;
        n |= n >> 4;
        n |= n >> 8;
        n |= n >> 16;
        return ++n;
    }
    
    static h2_push_diary *diary_create(apr_pool_t *p, h2_push_digest_type dtype, 
                                       int N)
    {
        h2_push_diary *diary = NULL;
        
        if (N > 0) {
            diary = apr_pcalloc(p, sizeof(*diary));
            
            diary->NMax        = ceil_power_of_2(N);
            diary->N           = diary->NMax;
            /* the mask we use in value comparison depends on where we got
             * the values from. If we calculate them ourselves, we can use
             * the full 64 bits.
             * If we set the diary via a compressed golomb set, we have less
             * relevant bits and need to use a smaller mask. */
            diary->mask_bits   = 64;
            /* grows by doubling, start with a power of 2 */
            diary->entries     = apr_array_make(p, 16, sizeof(h2_push_diary_entry));
            
            switch (dtype) {
    #ifdef H2_OPENSSL
                case H2_PUSH_DIGEST_SHA256:
                    diary->dtype       = H2_PUSH_DIGEST_SHA256;
                    diary->dcalc       = calc_sha256_hash;
                    break;
    #endif /* ifdef H2_OPENSSL */
                default:
                    diary->dtype       = H2_PUSH_DIGEST_APR_HASH;
                    diary->dcalc       = calc_apr_hash;
                    break;
            }
        }
        
        return diary;
    }
    
    h2_push_diary *h2_push_diary_create(apr_pool_t *p, int N)
    {
        return diary_create(p, H2_PUSH_DIGEST_SHA256, N);
    }
    
    static int h2_push_diary_find(h2_push_diary *diary, apr_uint64_t hash)
    {
        if (diary) {
            h2_push_diary_entry *e;
            int i;
    
            /* search from the end, where the last accessed digests are */
            for (i = diary->entries->nelts-1; i >= 0; --i) {
                e = &APR_ARRAY_IDX(diary->entries, i, h2_push_diary_entry);
                if (e->hash == hash) {
                    return i;
                }
            }
        }
        return -1;
    }
    
    static void move_to_last(h2_push_diary *diary, apr_size_t idx)
    {
        h2_push_diary_entry *entries = (h2_push_diary_entry*)diary->entries->elts;
        h2_push_diary_entry e;
        apr_size_t lastidx;
        
        /* Move an existing entry to the last place */
        if (diary->entries->nelts <= 0)
            return;
    
        /* move entry[idx] to the end */
        lastidx = diary->entries->nelts - 1;
        if (idx < lastidx) {
            e =  entries[idx];
            memmove(entries+idx, entries+idx+1, sizeof(h2_push_diary_entry) * (lastidx - idx));
            entries[lastidx] = e;
        }
    }
    
    static void remove_first(h2_push_diary *diary)
    {
        h2_push_diary_entry *entries = (h2_push_diary_entry*)diary->entries->elts;
        int lastidx;
        
        /* move remaining entries to index 0 */
        lastidx = diary->entries->nelts - 1;
        if (lastidx > 0) {
            --diary->entries->nelts;
            memmove(entries, entries+1, sizeof(h2_push_diary_entry) * diary->entries->nelts);
        }
    }
    
    static void h2_push_diary_append(h2_push_diary *diary, h2_push_diary_entry *e)
    {
        while (diary->entries->nelts >= diary->N) {
            remove_first(diary);
        }
        /* append a new diary entry at the end */
        APR_ARRAY_PUSH(diary->entries, h2_push_diary_entry) = *e;
        /* Intentional no APLOGNO */
        ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, diary->entries->pool,
                      "push_diary_append: %"APR_UINT64_T_HEX_FMT, e->hash);
    }
    
    apr_array_header_t *h2_push_diary_update(h2_session *session, apr_array_header_t *pushes)
    {
        apr_array_header_t *npushes = pushes;
        h2_push_diary_entry e;
        int i, idx;
        
        if (session->push_diary && pushes) {
            npushes = NULL;
            
            for (i = 0; i < pushes->nelts; ++i) {
                h2_push *push;
                
                push = APR_ARRAY_IDX(pushes, i, h2_push*);
                session->push_diary->dcalc(session->push_diary, &e.hash, push);
                idx = h2_push_diary_find(session->push_diary, e.hash);
                if (idx >= 0) {
                    /* Intentional no APLOGNO */
                    ap_log_cerror(APLOG_MARK, GCSLOG_LEVEL, 0, session->c1,
                                  "push_diary_update: already there PUSH %s", push->req->path);
                    move_to_last(session->push_diary, (apr_size_t)idx);
                }
                else {
                    /* Intentional no APLOGNO */
                    ap_log_cerror(APLOG_MARK, GCSLOG_LEVEL, 0, session->c1,
                                  "push_diary_update: adding PUSH %s", push->req->path);
                    if (!npushes) {
                        npushes = apr_array_make(pushes->pool, 5, sizeof(h2_push_diary_entry*));
                    }
                    APR_ARRAY_PUSH(npushes, h2_push*) = push;
                    h2_push_diary_append(session->push_diary, &e);
                }
            }
        }
        return npushes;
    }
        
    #if AP_HAS_RESPONSE_BUCKETS
    apr_array_header_t *h2_push_collect_update(struct h2_stream *stream,
                                               const struct h2_request *req,
                                               const ap_bucket_response *res)
    #else
    apr_array_header_t *h2_push_collect_update(struct h2_stream *stream,
                                               const struct h2_request *req,
                                               const struct h2_headers *res)
    #endif
    {
        apr_array_header_t *pushes;
        
        pushes = h2_push_collect(stream->pool, req, stream->push_policy, res);
        return h2_push_diary_update(stream->session, pushes);
    }
    
    typedef struct {
        h2_push_diary *diary;
        unsigned char log2p;
        int mask_bits;
        int delta_bits;
        int fixed_bits;
        apr_uint64_t fixed_mask;
        apr_pool_t *pool;
        unsigned char *data;
        apr_size_t datalen;
        apr_size_t offset;
        unsigned int bit;
        apr_uint64_t last;
    } gset_encoder;
    
    static int cmp_puint64(const void *p1, const void *p2)
    {
        const apr_uint64_t *pu1 = p1, *pu2 = p2;
        return (*pu1 > *pu2)? 1 : ((*pu1 == *pu2)? 0 : -1);
    }
    
    /* in golomb bit stream encoding, bit 0 is the 8th of the first char, or
     * more generally: 
     *      char(bit/8) & cbit_mask[(bit % 8)]
     */
    static unsigned char cbit_mask[] = {
        0x80u,
        0x40u,
        0x20u,
        0x10u,
        0x08u,
        0x04u,
        0x02u,
        0x01u,
    };
    
    static apr_status_t gset_encode_bit(gset_encoder *encoder, int bit)
    {
        if (++encoder->bit >= 8) {
            if (++encoder->offset >= encoder->datalen) {
                apr_size_t nlen = encoder->datalen*2;
                unsigned char *ndata = apr_pcalloc(encoder->pool, nlen);
                if (!ndata) {
                    return APR_ENOMEM;
                }
                memcpy(ndata, encoder->data, encoder->datalen);
                encoder->data = ndata;
                encoder->datalen = nlen;
            }
            encoder->bit = 0;
            encoder->data[encoder->offset] = 0xffu;
        }
        if (!bit) {
            encoder->data[encoder->offset] &= ~cbit_mask[encoder->bit];
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t gset_encode_next(gset_encoder *encoder, apr_uint64_t pval)
    {
        apr_uint64_t delta, flex_bits;
        apr_status_t status = APR_SUCCESS;
        int i;
        
        delta = pval - encoder->last;
        encoder->last = pval;
        flex_bits = (delta >> encoder->fixed_bits);
        /* Intentional no APLOGNO */
        ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, encoder->pool,
                      "h2_push_diary_enc: val=%"APR_UINT64_T_HEX_FMT", delta=%"
                      APR_UINT64_T_HEX_FMT" flex_bits=%"APR_UINT64_T_FMT", "
                      ", fixed_bits=%d, fixed_val=%"APR_UINT64_T_HEX_FMT, 
                      pval, delta, flex_bits, encoder->fixed_bits, delta&encoder->fixed_mask);
        for (; flex_bits != 0; --flex_bits) {
            status = gset_encode_bit(encoder, 1);
            if (status != APR_SUCCESS) {
                return status;
            }
        }
        status = gset_encode_bit(encoder, 0);
        if (status != APR_SUCCESS) {
            return status;
        }
    
        for (i = encoder->fixed_bits-1; i >= 0; --i) {
            status = gset_encode_bit(encoder, (delta >> i) & 1);
            if (status != APR_SUCCESS) {
                return status;
            }
        }
        return APR_SUCCESS;
    }
    
    /**
     * Get a cache digest as described in 
     * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/
     * from the contents of the push diary.
     * 
     * @param diary the diary to calculdate the digest from
     * @param p the pool to use
     * @param pdata on successful return, the binary cache digest
     * @param plen on successful return, the length of the binary data
     */
    apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *pool, 
                                          int maxP, const char *authority, 
                                          const char **pdata, apr_size_t *plen)
    {
        int nelts, N;
        unsigned char log2n, log2pmax;
        gset_encoder encoder;
        apr_uint64_t *hashes;
        apr_size_t hash_count, i;
        
        nelts = diary->entries->nelts;
        N = ceil_power_of_2(nelts);
        log2n = h2_log2(N);
        
        /* Now log2p is the max number of relevant bits, so that
         * log2p + log2n == mask_bits. We can use a lower log2p
         * and have a shorter set encoding...
         */
        log2pmax = h2_log2(ceil_power_of_2(maxP));
        
        memset(&encoder, 0, sizeof(encoder));
        encoder.diary = diary;
        encoder.log2p = H2MIN(diary->mask_bits - log2n, log2pmax);
        encoder.mask_bits = log2n + encoder.log2p;
        encoder.delta_bits = diary->mask_bits - encoder.mask_bits;
        encoder.fixed_bits = encoder.log2p;
        encoder.fixed_mask = 1;
        encoder.fixed_mask = (encoder.fixed_mask << encoder.fixed_bits) - 1;
        encoder.pool = pool;
        encoder.datalen = 512;
        encoder.data = apr_pcalloc(encoder.pool, encoder.datalen);
        
        encoder.data[0] = log2n;
        encoder.data[1] = encoder.log2p;
        encoder.offset = 1;
        encoder.bit = 8;
        encoder.last = 0;
        
        /* Intentional no APLOGNO */
        ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool,
                      "h2_push_diary_digest_get: %d entries, N=%d, log2n=%d, "
                      "mask_bits=%d, enc.mask_bits=%d, delta_bits=%d, enc.log2p=%d, authority=%s", 
                      (int)nelts, (int)N, (int)log2n, diary->mask_bits, 
                      (int)encoder.mask_bits, (int)encoder.delta_bits, 
                      (int)encoder.log2p, authority);
                      
        if (!authority || !diary->authority 
            || !strcmp("*", authority) || !strcmp(diary->authority, authority)) {
            hash_count = diary->entries->nelts;
            hashes = apr_pcalloc(encoder.pool, hash_count);
            for (i = 0; i < hash_count; ++i) {
                hashes[i] = ((&APR_ARRAY_IDX(diary->entries, i, h2_push_diary_entry))->hash 
                             >> encoder.delta_bits);
            }
            
            qsort(hashes, hash_count, sizeof(apr_uint64_t), cmp_puint64);
            for (i = 0; i < hash_count; ++i) {
                if (!i || (hashes[i] != hashes[i-1])) {
                    gset_encode_next(&encoder, hashes[i]);
                }
            }
            /* Intentional no APLOGNO */
            ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool,
                          "h2_push_diary_digest_get: golomb compressed hashes, %d bytes",
                          (int)encoder.offset + 1);
        }
        *pdata = (const char *)encoder.data;
        *plen = encoder.offset + 1;
        
        return APR_SUCCESS;
    }
    
    �����������������������������������������httpd-2.4.64/modules/http2/mod_http2.h��������������������������������������������������������������0000664�0001751�0001751�00000011130�14473316336�017412� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_HTTP2_H__
    #define __MOD_HTTP2_H__
    
    /** The http2_var_lookup() optional function retrieves HTTP2 environment
     * variables. */
    APR_DECLARE_OPTIONAL_FN(char *, 
                            http2_var_lookup, (apr_pool_t *, server_rec *,
                                               conn_rec *, request_rec *,  char *));
    
    /** An optional function which returns non-zero if the given connection
     * or its master connection is using HTTP/2. */
    APR_DECLARE_OPTIONAL_FN(int, 
                            http2_is_h2, (conn_rec *));
    
    APR_DECLARE_OPTIONAL_FN(void,
                            http2_get_num_workers, (server_rec *s,
                                                    int *minw, int *max));
    
    #define AP_HTTP2_HAS_GET_POLLFD
    
    /**
     * Get a apr_pollfd_t populated for a h2 connection where
     * (c->master != NULL) is true and pipes are supported.
     * To be used in Apache modules implementing WebSockets in Apache httpd
     * versions that do not support the corresponding `ap_get_pollfd_from_conn()`
     * function.
     * When available, use `ap_get_pollfd_from_conn()` instead of this function.
     *
     * How it works: pass in a `apr_pollfd_t` which gets populated for
     * monitoring the input of connection `c`. If `c` is not a HTTP/2
     * stream connection, the function will return `APR_ENOTIMPL`.
     * `ptimeout` is optional and, if passed, will get the timeout in effect
     *
     * On platforms without support for pipes (e.g. Windows), this function
     * will return `APR_ENOTIMPL`.
     */
    APR_DECLARE_OPTIONAL_FN(apr_status_t,
                            http2_get_pollfd_from_conn,
                            (conn_rec *c, struct apr_pollfd_t *pfd,
                             apr_interval_time_t *ptimeout));
    
    /*******************************************************************************
     * START HTTP/2 request engines (DEPRECATED)
     ******************************************************************************/
    
    /* The following functions were introduced for the experimental mod_proxy_http2
     * support, but have been abandoned since.
     * They are still declared here for backward compatibility, in case someone
     * tries to build an old mod_proxy_http2 against it, but will disappear
     * completely sometime in the future.
     */ 
     
    struct apr_thread_cond_t;
    typedef struct h2_req_engine h2_req_engine;
    typedef void http2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed);
    
    typedef apr_status_t http2_req_engine_init(h2_req_engine *engine, 
                                               const char *id, 
                                               const char *type,
                                               apr_pool_t *pool, 
                                               apr_size_t req_buffer_size,
                                               request_rec *r,
                                               http2_output_consumed **pconsumed,
                                               void **pbaton);
    
    APR_DECLARE_OPTIONAL_FN(apr_status_t, 
                            http2_req_engine_push, (const char *engine_type, 
                                                    request_rec *r,
                                                    http2_req_engine_init *einit));
    
    APR_DECLARE_OPTIONAL_FN(apr_status_t, 
                            http2_req_engine_pull, (h2_req_engine *engine, 
                                                    apr_read_type_e block,
                                                    int capacity,
                                                    request_rec **pr));
    APR_DECLARE_OPTIONAL_FN(void, 
                            http2_req_engine_done, (h2_req_engine *engine, 
                                                    conn_rec *rconn,
                                                    apr_status_t status));
    
    
    /*******************************************************************************
     * END HTTP/2 request engines (DEPRECATED)
     ******************************************************************************/
    
    #endif
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_bucket_eos.c����������������������������������������������������������0000664�0001751�0001751�00000005674�14356741666�020251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_connection.h>
    #include <http_log.h>
    #include <http_protocol.h>
    
    #include "h2_private.h"
    #include "h2.h"
    #include "h2_mplx.h"
    #include "h2_stream.h"
    #include "h2_bucket_eos.h"
    
    typedef struct {
        apr_bucket_refcount refcount;
        h2_stream *stream;
    } h2_bucket_eos;
    
    static apr_status_t bucket_cleanup(void *data)
    {
        h2_stream **pstream = data;
    
        if (*pstream) {
            /* If bucket_destroy is called after us, this prevents
             * bucket_destroy from trying to destroy the stream again. */
            *pstream = NULL;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t bucket_read(apr_bucket *b, const char **str,
                                    apr_size_t *len, apr_read_type_e block)
    {
        (void)b;
        (void)block;
        *str = NULL;
        *len = 0;
        return APR_SUCCESS;
    }
    
    apr_bucket *h2_bucket_eos_make(apr_bucket *b, h2_stream *stream)
    {
        h2_bucket_eos *h;
    
        h = apr_bucket_alloc(sizeof(*h), b->list);
        h->stream = stream;
    
        b = apr_bucket_shared_make(b, h, 0, 0);
        b->type = &h2_bucket_type_eos;
        
        return b;
    }
    
    apr_bucket *h2_bucket_eos_create(apr_bucket_alloc_t *list,
                                     h2_stream *stream)
    {
        apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
    
        APR_BUCKET_INIT(b);
        b->free = apr_bucket_free;
        b->list = list;
        b = h2_bucket_eos_make(b, stream);
        if (stream) {
            h2_bucket_eos *h = b->data;
            apr_pool_pre_cleanup_register(stream->pool, &h->stream, bucket_cleanup);
        }
        return b;
    }
    
    static void bucket_destroy(void *data)
    {
        h2_bucket_eos *h = data;
    
        if (apr_bucket_shared_destroy(h)) {
            h2_stream *stream = h->stream;
            if (stream && stream->pool) {
                apr_pool_cleanup_kill(stream->pool, &h->stream, bucket_cleanup);
            }
            apr_bucket_free(h);
            if (stream) {
                h2_stream_dispatch(stream, H2_SEV_EOS_SENT);
            }
        }
    }
    
    const apr_bucket_type_t h2_bucket_type_eos = {
        "H2EOS", 5, APR_BUCKET_METADATA,
        bucket_destroy,
        bucket_read,
        apr_bucket_setaside_noop,
        apr_bucket_split_notimpl,
        apr_bucket_shared_copy
    };
    
    ��������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_conn_ctx.c������������������������������������������������������������0000664�0001751�0001751�00000007400�14356741666�017726� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_strings.h>
    #include <apr_atomic.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_log.h>
    #include <http_protocol.h>
    
    #include "h2_private.h"
    #include "h2_session.h"
    #include "h2_bucket_beam.h"
    #include "h2_c2.h"
    #include "h2_mplx.h"
    #include "h2_stream.h"
    #include "h2_util.h"
    #include "h2_conn_ctx.h"
    
    
    void h2_conn_ctx_detach(conn_rec *c)
    {
        ap_set_module_config(c->conn_config, &http2_module, NULL);
    }
    
    static h2_conn_ctx_t *ctx_create(conn_rec *c, const char *id)
    {
        h2_conn_ctx_t *conn_ctx = apr_pcalloc(c->pool, sizeof(*conn_ctx));
        conn_ctx->id = id;
        conn_ctx->server = c->base_server;
        apr_atomic_set32(&conn_ctx->started, 1);
        conn_ctx->started_at = apr_time_now();
    
        ap_set_module_config(c->conn_config, &http2_module, conn_ctx);
        return conn_ctx;
    }
    
    h2_conn_ctx_t *h2_conn_ctx_create_for_c1(conn_rec *c1, server_rec *s, const char *protocol)
    {
        h2_conn_ctx_t *ctx;
    
        ctx = ctx_create(c1, apr_psprintf(c1->pool, "%ld", c1->id));
        ctx->server = s;
        ctx->protocol = apr_pstrdup(c1->pool, protocol);
    
        ctx->pfd.desc_type = APR_POLL_SOCKET;
        ctx->pfd.desc.s = ap_get_conn_socket(c1);
        ctx->pfd.reqevents = APR_POLLIN | APR_POLLERR | APR_POLLHUP;
        ctx->pfd.client_data = ctx;
        apr_socket_opt_set(ctx->pfd.desc.s, APR_SO_NONBLOCK, 1);
    
        return ctx;
    }
    
    void h2_conn_ctx_assign_session(h2_conn_ctx_t *ctx, struct h2_session *session)
    {
        ctx->session = session;
        ctx->id = apr_psprintf(session->pool, "%d-%lu", session->child_num, (unsigned long)session->id);
    }
    
    apr_status_t h2_conn_ctx_init_for_c2(h2_conn_ctx_t **pctx, conn_rec *c2,
                                         struct h2_mplx *mplx, struct h2_stream *stream,
                                         struct h2_c2_transit *transit)
    {
        h2_conn_ctx_t *conn_ctx;
        apr_status_t rv = APR_SUCCESS;
    
        ap_assert(c2->master);
        conn_ctx = h2_conn_ctx_get(c2);
        if (!conn_ctx) {
            h2_conn_ctx_t *c1_ctx;
    
            c1_ctx = h2_conn_ctx_get(c2->master);
            ap_assert(c1_ctx);
            ap_assert(c1_ctx->session);
    
            conn_ctx = ctx_create(c2, c1_ctx->id);
            conn_ctx->server = c2->master->base_server;
        }
    
        conn_ctx->mplx = mplx;
        conn_ctx->transit = transit;
        conn_ctx->stream_id = stream->id;
        apr_pool_create(&conn_ctx->req_pool, c2->pool);
        apr_pool_tag(conn_ctx->req_pool, "H2_C2_REQ");
        conn_ctx->request = stream->request;
        apr_atomic_set32(&conn_ctx->started, 1);
        conn_ctx->started_at = apr_time_now();
        conn_ctx->done = 0;
        conn_ctx->done_at = 0;
    
        *pctx = conn_ctx;
        return rv;
    }
    
    void h2_conn_ctx_set_timeout(h2_conn_ctx_t *conn_ctx, apr_interval_time_t timeout)
    {
        if (conn_ctx->beam_out) {
            h2_beam_timeout_set(conn_ctx->beam_out, timeout);
        }
        if (conn_ctx->beam_in) {
            h2_beam_timeout_set(conn_ctx->beam_in, timeout);
        }
        if (conn_ctx->pipe_in[H2_PIPE_OUT]) {
            apr_file_pipe_timeout_set(conn_ctx->pipe_in[H2_PIPE_OUT], timeout);
        }
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_proxy_util.c����������������������������������������������������������0000664�0001751�0001751�00000111550�14356741666�020333� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_lib.h>
    #include <apr_strings.h>
    #include <apr_thread_mutex.h>
    #include <apr_thread_cond.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <http_request.h>
    #include <mod_proxy.h>
    
    #include <nghttp2/nghttp2.h>
    
    #include "h2.h"
    #include "h2_proxy_util.h"
    
    APLOG_USE_MODULE(proxy_http2);
    
    /* h2_log2(n) iff n is a power of 2 */
    unsigned char h2_proxy_log2(int n)
    {
        int lz = 0;
        if (!n) {
            return 0;
        }
        if (!(n & 0xffff0000u)) {
            lz += 16;
            n = (n << 16);
        }
        if (!(n & 0xff000000u)) {
            lz += 8;
            n = (n << 8);
        }
        if (!(n & 0xf0000000u)) {
            lz += 4;
            n = (n << 4);
        }
        if (!(n & 0xc0000000u)) {
            lz += 2;
            n = (n << 2);
        }
        if (!(n & 0x80000000u)) {
            lz += 1;
        }
        
        return 31 - lz;
    }
    
    /*******************************************************************************
     * ihash - hash for structs with int identifier
     ******************************************************************************/
    struct h2_proxy_ihash_t {
        apr_hash_t *hash;
        size_t ioff;
    };
    
    static unsigned int ihash(const char *key, apr_ssize_t *klen)
    {
        return (unsigned int)(*((int*)key));
    }
    
    h2_proxy_ihash_t *h2_proxy_ihash_create(apr_pool_t *pool, size_t offset_of_int)
    {
        h2_proxy_ihash_t *ih = apr_pcalloc(pool, sizeof(h2_proxy_ihash_t));
        ih->hash = apr_hash_make_custom(pool, ihash);
        ih->ioff = offset_of_int;
        return ih;
    }
    
    size_t h2_proxy_ihash_count(h2_proxy_ihash_t *ih)
    {
        return apr_hash_count(ih->hash);
    }
    
    int h2_proxy_ihash_empty(h2_proxy_ihash_t *ih)
    {
        return apr_hash_count(ih->hash) == 0;
    }
    
    void *h2_proxy_ihash_get(h2_proxy_ihash_t *ih, int id)
    {
        return apr_hash_get(ih->hash, &id, sizeof(id));
    }
    
    typedef struct {
        h2_proxy_ihash_iter_t *iter;
        void *ctx;
    } iter_ctx;
    
    static int ihash_iter(void *ctx, const void *key, apr_ssize_t klen, 
                         const void *val)
    {
        iter_ctx *ictx = ctx;
        return ictx->iter(ictx->ctx, (void*)val); /* why is this passed const?*/
    }
    
    int h2_proxy_ihash_iter(h2_proxy_ihash_t *ih, h2_proxy_ihash_iter_t *fn, void *ctx)
    {
        iter_ctx ictx;
        ictx.iter = fn;
        ictx.ctx = ctx;
        return apr_hash_do(ihash_iter, &ictx, ih->hash);
    }
    
    void h2_proxy_ihash_add(h2_proxy_ihash_t *ih, void *val)
    {
        apr_hash_set(ih->hash, ((char *)val + ih->ioff), sizeof(int), val);
    }
    
    void h2_proxy_ihash_remove(h2_proxy_ihash_t *ih, int id)
    {
        apr_hash_set(ih->hash, &id, sizeof(id), NULL);
    }
    
    void h2_proxy_ihash_remove_val(h2_proxy_ihash_t *ih, void *val)
    {
        int id = *((int*)((char *)val + ih->ioff));
        apr_hash_set(ih->hash, &id, sizeof(id), NULL);
    }
    
    
    void h2_proxy_ihash_clear(h2_proxy_ihash_t *ih)
    {
        apr_hash_clear(ih->hash);
    }
    
    typedef struct {
        h2_proxy_ihash_t *ih;
        void **buffer;
        size_t max;
        size_t len;
    } collect_ctx;
    
    static int collect_iter(void *x, void *val)
    {
        collect_ctx *ctx = x;
        if (ctx->len < ctx->max) {
            ctx->buffer[ctx->len++] = val;
            return 1;
        }
        return 0;
    }
    
    size_t h2_proxy_ihash_shift(h2_proxy_ihash_t *ih, void **buffer, size_t max)
    {
        collect_ctx ctx;
        size_t i;
        
        ctx.ih = ih;
        ctx.buffer = buffer;
        ctx.max = max;
        ctx.len = 0;
        h2_proxy_ihash_iter(ih, collect_iter, &ctx);
        for (i = 0; i < ctx.len; ++i) {
            h2_proxy_ihash_remove_val(ih, buffer[i]);
        }
        return ctx.len;
    }
    
    typedef struct {
        h2_proxy_ihash_t *ih;
        int *buffer;
        size_t max;
        size_t len;
    } icollect_ctx;
    
    static int icollect_iter(void *x, void *val)
    {
        icollect_ctx *ctx = x;
        if (ctx->len < ctx->max) {
            ctx->buffer[ctx->len++] = *((int*)((char *)val + ctx->ih->ioff));
            return 1;
        }
        return 0;
    }
    
    size_t h2_proxy_ihash_ishift(h2_proxy_ihash_t *ih, int *buffer, size_t max)
    {
        icollect_ctx ctx;
        size_t i;
        
        ctx.ih = ih;
        ctx.buffer = buffer;
        ctx.max = max;
        ctx.len = 0;
        h2_proxy_ihash_iter(ih, icollect_iter, &ctx);
        for (i = 0; i < ctx.len; ++i) {
            h2_proxy_ihash_remove(ih, buffer[i]);
        }
        return ctx.len;
    }
    
    /*******************************************************************************
     * iqueue - sorted list of int
     ******************************************************************************/
    
    static void iq_grow(h2_proxy_iqueue *q, int nlen);
    static void iq_swap(h2_proxy_iqueue *q, int i, int j);
    static int iq_bubble_up(h2_proxy_iqueue *q, int i, int top, 
                            h2_proxy_iq_cmp *cmp, void *ctx);
    static int iq_bubble_down(h2_proxy_iqueue *q, int i, int bottom, 
                              h2_proxy_iq_cmp *cmp, void *ctx);
    
    h2_proxy_iqueue *h2_proxy_iq_create(apr_pool_t *pool, int capacity)
    {
        h2_proxy_iqueue *q = apr_pcalloc(pool, sizeof(h2_proxy_iqueue));
        if (q) {
            q->pool = pool;
            iq_grow(q, capacity);
            q->nelts = 0;
        }
        return q;
    }
    
    int h2_proxy_iq_empty(h2_proxy_iqueue *q)
    {
        return q->nelts == 0;
    }
    
    int h2_proxy_iq_count(h2_proxy_iqueue *q)
    {
        return q->nelts;
    }
    
    
    void h2_proxy_iq_add(h2_proxy_iqueue *q, int sid, h2_proxy_iq_cmp *cmp, void *ctx)
    {
        int i;
        
        if (q->nelts >= q->nalloc) {
            iq_grow(q, q->nalloc * 2);
        }
        
        i = (q->head + q->nelts) % q->nalloc;
        q->elts[i] = sid;
        ++q->nelts;
        
        if (cmp) {
            /* bubble it to the front of the queue */
            iq_bubble_up(q, i, q->head, cmp, ctx);
        }
    }
    
    int h2_proxy_iq_remove(h2_proxy_iqueue *q, int sid)
    {
        int i;
        for (i = 0; i < q->nelts; ++i) {
            if (sid == q->elts[(q->head + i) % q->nalloc]) {
                break;
            }
        }
        
        if (i < q->nelts) {
            ++i;
            for (; i < q->nelts; ++i) {
                q->elts[(q->head+i-1)%q->nalloc] = q->elts[(q->head+i)%q->nalloc];
            }
            --q->nelts;
            return 1;
        }
        return 0;
    }
    
    void h2_proxy_iq_clear(h2_proxy_iqueue *q)
    {
        q->nelts = 0;
    }
    
    void h2_proxy_iq_sort(h2_proxy_iqueue *q, h2_proxy_iq_cmp *cmp, void *ctx)
    {
        /* Assume that changes in ordering are minimal. This needs,
         * best case, q->nelts - 1 comparisons to check that nothing
         * changed.
         */
        if (q->nelts > 0) {
            int i, ni, prev, last;
            
            /* Start at the end of the queue and create a tail of sorted
             * entries. Make that tail one element longer in each iteration.
             */
            last = i = (q->head + q->nelts - 1) % q->nalloc;
            while (i != q->head) {
                prev = (q->nalloc + i - 1) % q->nalloc;
                
                ni = iq_bubble_up(q, i, prev, cmp, ctx);
                if (ni == prev) {
                    /* i bubbled one up, bubble the new i down, which
                     * keeps all tasks below i sorted. */
                    iq_bubble_down(q, i, last, cmp, ctx);
                }
                i = prev;
            };
        }
    }
    
    
    int h2_proxy_iq_shift(h2_proxy_iqueue *q)
    {
        int sid;
        
        if (q->nelts <= 0) {
            return 0;
        }
        
        sid = q->elts[q->head];
        q->head = (q->head + 1) % q->nalloc;
        q->nelts--;
        
        return sid;
    }
    
    static void iq_grow(h2_proxy_iqueue *q, int nlen)
    {
        if (nlen > q->nalloc) {
            int *nq = apr_pcalloc(q->pool, sizeof(int) * nlen);
            if (q->nelts > 0) {
                int l = ((q->head + q->nelts) % q->nalloc) - q->head;
                
                memmove(nq, q->elts + q->head, sizeof(int) * l);
                if (l < q->nelts) {
                    /* elts wrapped, append elts in [0, remain] to nq */
                    int remain = q->nelts - l;
                    memmove(nq + l, q->elts, sizeof(int) * remain);
                }
            }
            q->elts = nq;
            q->nalloc = nlen;
            q->head = 0;
        }
    }
    
    static void iq_swap(h2_proxy_iqueue *q, int i, int j)
    {
        int x = q->elts[i];
        q->elts[i] = q->elts[j];
        q->elts[j] = x;
    }
    
    static int iq_bubble_up(h2_proxy_iqueue *q, int i, int top, 
                            h2_proxy_iq_cmp *cmp, void *ctx) 
    {
        int prev;
        while (((prev = (q->nalloc + i - 1) % q->nalloc), i != top) 
               && (*cmp)(q->elts[i], q->elts[prev], ctx) < 0) {
            iq_swap(q, prev, i);
            i = prev;
        }
        return i;
    }
    
    static int iq_bubble_down(h2_proxy_iqueue *q, int i, int bottom, 
                              h2_proxy_iq_cmp *cmp, void *ctx)
    {
        int next;
        while (((next = (q->nalloc + i + 1) % q->nalloc), i != bottom) 
               && (*cmp)(q->elts[i], q->elts[next], ctx) > 0) {
            iq_swap(q, next, i);
            i = next;
        }
        return i;
    }
    
    /*******************************************************************************
     * h2_proxy_ngheader
     ******************************************************************************/
    #define H2_HD_MATCH_LIT_CS(l, name)  \
        ((strlen(name) == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
    
    static int h2_util_ignore_header(const char *name) 
    {
        /* never forward, ch. 8.1.2.2 */
        return (H2_HD_MATCH_LIT_CS("connection", name)
                || H2_HD_MATCH_LIT_CS("proxy-connection", name)
                || H2_HD_MATCH_LIT_CS("upgrade", name)
                || H2_HD_MATCH_LIT_CS("keep-alive", name)
                || H2_HD_MATCH_LIT_CS("transfer-encoding", name));
    }
    
    static int count_header(void *ctx, const char *key, const char *value)
    {
        if (!h2_util_ignore_header(key)) {
            (*((size_t*)ctx))++;
        }
        return 1;
    }
    
    #define NV_ADD_LIT_CS(nv, k, v)     add_header(nv, k, sizeof(k) - 1, v, strlen(v))
    #define NV_ADD_CS_CS(nv, k, v)      add_header(nv, k, strlen(k), v, strlen(v))
    
    static int add_header(h2_proxy_ngheader *ngh, 
                          const char *key, size_t key_len,
                          const char *value, size_t val_len)
    {
        nghttp2_nv *nv = &ngh->nv[ngh->nvlen++];
        
        nv->name = (uint8_t*)key;
        nv->namelen = key_len;
        nv->value = (uint8_t*)value;
        nv->valuelen = val_len;
        return 1;
    }
    
    static int add_table_header(void *ctx, const char *key, const char *value)
    {
        if (!h2_util_ignore_header(key)) {
            add_header(ctx, key, strlen(key), value, strlen(value));
        }
        return 1;
    }
    
    h2_proxy_ngheader *h2_proxy_util_nghd_make_req(apr_pool_t *p, 
                                                   const h2_proxy_request *req)
    {
        
        h2_proxy_ngheader *ngh;
        size_t n;
        
        ap_assert(req);
        ap_assert(req->scheme);
        ap_assert(req->authority);
        ap_assert(req->path);
        ap_assert(req->method);
    
        n = 4;
        apr_table_do(count_header, &n, req->headers, NULL);
        
        ngh = apr_pcalloc(p, sizeof(h2_proxy_ngheader));
        ngh->nv =  apr_pcalloc(p, n * sizeof(nghttp2_nv));
        NV_ADD_LIT_CS(ngh, ":scheme", req->scheme);
        NV_ADD_LIT_CS(ngh, ":authority", req->authority);
        NV_ADD_LIT_CS(ngh, ":path", req->path);
        NV_ADD_LIT_CS(ngh, ":method", req->method);
        apr_table_do(add_table_header, ngh, req->headers, NULL);
    
        return ngh;
    }
    
    h2_proxy_ngheader *h2_proxy_util_nghd_make(apr_pool_t *p, apr_table_t *headers)
    {
        
        h2_proxy_ngheader *ngh;
        size_t n;
        
        n = 0;
        apr_table_do(count_header, &n, headers, NULL);
        
        ngh = apr_pcalloc(p, sizeof(h2_proxy_ngheader));
        ngh->nv =  apr_pcalloc(p, n * sizeof(nghttp2_nv));
        apr_table_do(add_table_header, ngh, headers, NULL);
    
        return ngh;
    }
    
    /*******************************************************************************
     * header HTTP/1 <-> HTTP/2 conversions
     ******************************************************************************/
     
    typedef struct {
        const char *name;
        size_t len;
    } literal;
    
    #define H2_DEF_LITERAL(n)   { (n), (sizeof(n)-1) }
    #define H2_LIT_ARGS(a)      (a),H2_ALEN(a)
    
    static literal IgnoredRequestHeaders[] = {
        H2_DEF_LITERAL("upgrade"),
        H2_DEF_LITERAL("connection"),
        H2_DEF_LITERAL("keep-alive"),
        H2_DEF_LITERAL("http2-settings"),
        H2_DEF_LITERAL("proxy-connection"),
        H2_DEF_LITERAL("transfer-encoding"),
    };
    static literal IgnoredProxyRespHds[] = {
        H2_DEF_LITERAL("alt-svc"),
    };
    
    static int ignore_header(const literal *lits, size_t llen,
                             const char *name, size_t nlen)
    {
        const literal *lit;
        size_t i;
        
        for (i = 0; i < llen; ++i) {
            lit = &lits[i];
            if (lit->len == nlen && !apr_strnatcasecmp(lit->name, name)) {
                return 1;
            }
        }
        return 0;
    }
    
    static int h2_proxy_req_ignore_header(const char *name, size_t len)
    {
        return ignore_header(H2_LIT_ARGS(IgnoredRequestHeaders), name, len);
    }
    
    int h2_proxy_res_ignore_header(const char *name, size_t len)
    {
        return (h2_proxy_req_ignore_header(name, len) 
                || ignore_header(H2_LIT_ARGS(IgnoredProxyRespHds), name, len));
    }
    
    void h2_proxy_util_camel_case_header(char *s, size_t len)
    {
        size_t start = 1;
        size_t i;
        for (i = 0; i < len; ++i) {
            if (start) {
                if (s[i] >= 'a' && s[i] <= 'z') {
                    s[i] -= 'a' - 'A';
                }
                
                start = 0;
            }
            else if (s[i] == '-') {
                start = 1;
            }
        }
    }
    
    /*******************************************************************************
     * h2 request handling
     ******************************************************************************/
    
    /** Match a header value against a string constance, case insensitive */
    #define H2_HD_MATCH_LIT(l, name, nlen)  \
        ((nlen == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
    
    static apr_status_t h2_headers_add_h1(apr_table_t *headers, apr_pool_t *pool, 
                                          const char *name, size_t nlen,
                                          const char *value, size_t vlen)
    {
        char *hname, *hvalue;
        
        if (h2_proxy_req_ignore_header(name, nlen)) {
            return APR_SUCCESS;
        }
        else if (H2_HD_MATCH_LIT("cookie", name, nlen)) {
            const char *existing = apr_table_get(headers, "cookie");
            if (existing) {
                char *nval;
                
                /* Cookie header come separately in HTTP/2, but need
                 * to be merged by "; " (instead of default ", ")
                 */
                hvalue = apr_pstrndup(pool, value, vlen);
                nval = apr_psprintf(pool, "%s; %s", existing, hvalue);
                apr_table_setn(headers, "Cookie", nval);
                return APR_SUCCESS;
            }
        }
        else if (H2_HD_MATCH_LIT("host", name, nlen)) {
            if (apr_table_get(headers, "Host")) {
                return APR_SUCCESS; /* ignore duplicate */
            }
        }
        
        hname = apr_pstrndup(pool, name, nlen);
        hvalue = apr_pstrndup(pool, value, vlen);
        h2_proxy_util_camel_case_header(hname, nlen);
        apr_table_mergen(headers, hname, hvalue);
        
        return APR_SUCCESS;
    }
    
    static h2_proxy_request *h2_proxy_req_createn(int id, apr_pool_t *pool, const char *method, 
                                      const char *scheme, const char *authority, 
                                      const char *path, apr_table_t *header)
    {
        h2_proxy_request *req = apr_pcalloc(pool, sizeof(h2_proxy_request));
        
        req->method         = method;
        req->scheme         = scheme;
        req->authority      = authority;
        req->path           = path;
        req->headers        = header? header : apr_table_make(pool, 10);
        req->request_time   = apr_time_now();
    
        return req;
    }
    
    h2_proxy_request *h2_proxy_req_create(int id, apr_pool_t *pool)
    {
        return h2_proxy_req_createn(id, pool, NULL, NULL, NULL, NULL, NULL);
    }
    
    typedef struct {
        apr_table_t *headers;
        apr_pool_t *pool;
    } h1_ctx;
    
    static int set_h1_header(void *ctx, const char *key, const char *value)
    {
        h1_ctx *x = ctx;
        size_t klen = strlen(key);
        if (!h2_proxy_req_ignore_header(key, klen)) {
            h2_headers_add_h1(x->headers, x->pool, key, klen, value, strlen(value));
        }
        return 1;
    }
    
    apr_status_t h2_proxy_req_make(h2_proxy_request *req, apr_pool_t *pool,
                             const char *method, const char *scheme, 
                             const char *authority, const char *path, 
                             apr_table_t *headers)
    {
        h1_ctx x;
        const char *val;
    
        req->method    = method;
        req->scheme    = scheme;
        req->authority = authority;
        req->path      = path;
    
        ap_assert(req->scheme);
        ap_assert(req->authority);
        ap_assert(req->path);
        ap_assert(req->method);
    
        x.pool = pool;
        x.headers = req->headers;
        apr_table_do(set_h1_header, &x, headers, NULL);
        if ((val = apr_table_get(headers, "TE")) && ap_find_token(pool, val, "trailers")) {
            /* client accepts trailers, forward this information */
            apr_table_addn(req->headers, "TE", "trailers");
        }
        apr_table_setn(req->headers, "te", "trailers");
        return APR_SUCCESS;
    }
    
    /*******************************************************************************
     * frame logging
     ******************************************************************************/
    
    int h2_proxy_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen)
    {
        char scratch[128];
        size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
        
        switch (frame->hd.type) {
            case NGHTTP2_DATA: {
                return apr_snprintf(buffer, maxlen,
                                    "DATA[length=%d, flags=%d, stream=%d, padlen=%d]",
                                    (int)frame->hd.length, frame->hd.flags,
                                    frame->hd.stream_id, (int)frame->data.padlen);
            }
            case NGHTTP2_HEADERS: {
                return apr_snprintf(buffer, maxlen,
                                    "HEADERS[length=%d, hend=%d, stream=%d, eos=%d]",
                                    (int)frame->hd.length,
                                    !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
                                    frame->hd.stream_id,
                                    !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
            }
            case NGHTTP2_PRIORITY: {
                return apr_snprintf(buffer, maxlen,
                                    "PRIORITY[length=%d, flags=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    frame->hd.flags, frame->hd.stream_id);
            }
            case NGHTTP2_RST_STREAM: {
                return apr_snprintf(buffer, maxlen,
                                    "RST_STREAM[length=%d, flags=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    frame->hd.flags, frame->hd.stream_id);
            }
            case NGHTTP2_SETTINGS: {
                if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
                    return apr_snprintf(buffer, maxlen,
                                        "SETTINGS[ack=1, stream=%d]",
                                        frame->hd.stream_id);
                }
                return apr_snprintf(buffer, maxlen,
                                    "SETTINGS[length=%d, stream=%d]",
                                    (int)frame->hd.length, frame->hd.stream_id);
            }
            case NGHTTP2_PUSH_PROMISE: {
                return apr_snprintf(buffer, maxlen,
                                    "PUSH_PROMISE[length=%d, hend=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
                                    frame->hd.stream_id);
            }
            case NGHTTP2_PING: {
                return apr_snprintf(buffer, maxlen,
                                    "PING[length=%d, ack=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    frame->hd.flags&NGHTTP2_FLAG_ACK,
                                    frame->hd.stream_id);
            }
            case NGHTTP2_GOAWAY: {
                size_t len = (frame->goaway.opaque_data_len < s_len)?
                    frame->goaway.opaque_data_len : s_len-1;
                memcpy(scratch, frame->goaway.opaque_data, len);
                scratch[len] = '\0';
                return apr_snprintf(buffer, maxlen, "GOAWAY[error=%d, reason='%s', "
                                    "last_stream=%d]", frame->goaway.error_code, 
                                    scratch, frame->goaway.last_stream_id);
            }
            case NGHTTP2_WINDOW_UPDATE: {
                return apr_snprintf(buffer, maxlen,
                                    "WINDOW_UPDATE[stream=%d, incr=%d]",
                                    frame->hd.stream_id, 
                                    frame->window_update.window_size_increment);
            }
            default:
                return apr_snprintf(buffer, maxlen,
                                    "type=%d[length=%d, flags=%d, stream=%d]",
                                    frame->hd.type, (int)frame->hd.length,
                                    frame->hd.flags, frame->hd.stream_id);
        }
    }
    
    /*******************************************************************************
     * link header handling 
     ******************************************************************************/
    
    typedef struct {
        apr_pool_t *pool;
        request_rec *r;
        proxy_dir_conf *conf;
        const char *s;
        int slen;
        int i;
        const char *server_uri;
        int su_len;
        const char *real_backend_uri;
        int rbu_len;
        const char *p_server_uri;
        int psu_len;
        int link_start;
        int link_end;
    } link_ctx;
    
    static int attr_char(char c) 
    {
        switch (c) {
            case '!':
            case '#':
            case '$':
            case '&':
            case '+':
            case '-':
            case '.':
            case '^':
            case '_':
            case '`':
            case '|':
            case '~':
                return 1;
            default:
                return apr_isalnum(c);
        }
    }
    
    static int ptoken_char(char c) 
    {
        switch (c) {
            case '!':
            case '#':
            case '$':
            case '&':
            case '\'':
            case '(':
            case ')':
            case '*':
            case '+':
            case '-':
            case '.':
            case '/':
            case ':':
            case '<':
            case '=':
            case '>':
            case '?':
            case '@':
            case '[':
            case ']':
            case '^':
            case '_':
            case '`':
            case '{':
            case '|':
            case '}':
            case '~':
                return 1;
            default:
                return apr_isalnum(c);
        }
    }
    
    static int skip_ws(link_ctx *ctx)
    {
        char c;
        while (ctx->i < ctx->slen 
               && (((c = ctx->s[ctx->i]) == ' ') || (c == '\t'))) {
            ++ctx->i;
        }
        return (ctx->i < ctx->slen);
    }
    
    static int find_chr(link_ctx *ctx, char c, int *pidx)
    {
        int j;
        for (j = ctx->i; j < ctx->slen; ++j) {
            if (ctx->s[j] == c) {
                *pidx = j;
                return 1;
            }
        } 
        return 0;
    }
    
    static int read_chr(link_ctx *ctx, char c)
    {
        if (ctx->i < ctx->slen && ctx->s[ctx->i] == c) {
            ++ctx->i;
            return 1;
        }
        return 0;
    }
    
    static int skip_qstring(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, '\"')) {
            int end;
            if (find_chr(ctx, '\"', &end)) {
                ctx->i = end + 1;
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_ptoken(link_ctx *ctx)
    {
        if (skip_ws(ctx)) {
            int i;
            for (i = ctx->i; i < ctx->slen && ptoken_char(ctx->s[i]); ++i) {
                /* nop */
            }
            if (i > ctx->i) {
                ctx->i = i;
                return 1;
            }
        }
        return 0;
    }
    
    
    static int read_link(link_ctx *ctx)
    {
        ctx->link_start = ctx->link_end = 0;
        if (skip_ws(ctx) && read_chr(ctx, '<')) {
            int end;
            if (find_chr(ctx, '>', &end)) {
                ctx->link_start = ctx->i;
                ctx->link_end = end;
                ctx->i = end + 1;
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_pname(link_ctx *ctx)
    {
        if (skip_ws(ctx)) {
            int i;
            for (i = ctx->i; i < ctx->slen && attr_char(ctx->s[i]); ++i) {
                /* nop */
            }
            if (i > ctx->i) {
                ctx->i = i;
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_pvalue(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, '=')) {
            if (skip_qstring(ctx) || skip_ptoken(ctx)) {
                return 1;
            }
        }
        return 0;
    }
    
    static int skip_param(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, ';')) {
            if (skip_pname(ctx)) {
                skip_pvalue(ctx); /* value is optional */
                return 1;
            }
        }
        return 0;
    }
    
    static int read_sep(link_ctx *ctx)
    {
        if (skip_ws(ctx) && read_chr(ctx, ',')) {
            return 1;
        }
        return 0;
    }
    
    static size_t subst_str(link_ctx *ctx, int start, int end, const char *ns)
    {
        int olen, nlen, plen;
        int delta;
        char *p;
        
        olen = end - start;
        nlen = (int)strlen(ns);
        delta = nlen - olen;
        plen = ctx->slen + delta + 1;
        p = apr_palloc(ctx->pool, plen);
        memcpy(p, ctx->s, start);
        memcpy(p + start, ns, nlen);
        strcpy(p + start + nlen, ctx->s + end);
        ctx->s = p;
        ctx->slen = plen - 1;   /* (int)strlen(p) */
        if (ctx->i >= end) {
            ctx->i += delta;
        }
        return nlen; 
    }
    
    static void map_link(link_ctx *ctx) 
    {
        if (ctx->link_start < ctx->link_end) {
            char buffer[HUGE_STRING_LEN];
            size_t need_len, link_len, buffer_len, prepend_p_server;
            const char *mapped;
            
            buffer[0] = '\0';
            buffer_len = 0;
            link_len = ctx->link_end - ctx->link_start;
            need_len = link_len + 1;
            prepend_p_server = (ctx->s[ctx->link_start] == '/'); 
            if (prepend_p_server) {
                /* common to use relative uris in link header, for mappings
                 * to work need to prefix the backend server uri */
                need_len += ctx->psu_len;
                apr_cpystrn(buffer, ctx->p_server_uri, sizeof(buffer));
                buffer_len = ctx->psu_len;
            }
            if (need_len > sizeof(buffer)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, ctx->r, APLOGNO(03482) 
                              "link_reverse_map uri too long, skipped: %s", ctx->s);
                return;
            }
            apr_cpystrn(buffer + buffer_len, ctx->s + ctx->link_start, link_len + 1);
            if (!prepend_p_server
                && strcmp(ctx->real_backend_uri, ctx->p_server_uri)
                && !strncmp(buffer, ctx->real_backend_uri, ctx->rbu_len)) {
                /* the server uri and our local proxy uri we use differ, for mapping
                 * to work, we need to use the proxy uri */
                int path_start = ctx->link_start + ctx->rbu_len;
                link_len -= ctx->rbu_len;
                memcpy(buffer, ctx->p_server_uri, ctx->psu_len);
                memcpy(buffer + ctx->psu_len, ctx->s + path_start, link_len);
                buffer_len = ctx->psu_len + link_len;
                buffer[buffer_len] = '\0';            
            }
            mapped = ap_proxy_location_reverse_map(ctx->r, ctx->conf, buffer);
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, ctx->r, 
                          "reverse_map[%s] %s --> %s", ctx->p_server_uri, buffer, mapped);
            if (mapped != buffer) {
                if (prepend_p_server) {
                    if (ctx->server_uri == NULL) {
                        ctx->server_uri = ap_construct_url(ctx->pool, "", ctx->r);
                        ctx->su_len = (int)strlen(ctx->server_uri);
                    }
                    if (!strncmp(mapped, ctx->server_uri, ctx->su_len)) {
                        mapped += ctx->su_len;
                    }
                }
                subst_str(ctx, ctx->link_start, ctx->link_end, mapped);
            }
        }
    }
    
    /* RFC 5988 <https://tools.ietf.org/html/rfc5988#section-6.2.1>
      Link           = "Link" ":" #link-value
      link-value     = "<" URI-Reference ">" *( ";" link-param )
      link-param     = ( ( "rel" "=" relation-types )
                     | ( "anchor" "=" <"> URI-Reference <"> )
                     | ( "rev" "=" relation-types )
                     | ( "hreflang" "=" Language-Tag )
                     | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) )
                     | ( "title" "=" quoted-string )
                     | ( "title*" "=" ext-value )
                     | ( "type" "=" ( media-type | quoted-mt ) )
                     | ( link-extension ) )
      link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] )
                     | ( ext-name-star "=" ext-value )
      ext-name-star  = parmname "*" ; reserved for RFC2231-profiled
                                    ; extensions.  Whitespace NOT
                                    ; allowed in between.
      ptoken         = 1*ptokenchar
      ptokenchar     = "!" | "#" | "$" | "%" | "&" | "'" | "("
                     | ")" | "*" | "+" | "-" | "." | "/" | DIGIT
                     | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA
                     | "[" | "]" | "^" | "_" | "`" | "{" | "|"
                     | "}" | "~"
      media-type     = type-name "/" subtype-name
      quoted-mt      = <"> media-type <">
      relation-types = relation-type
                     | <"> relation-type *( 1*SP relation-type ) <">
      relation-type  = reg-rel-type | ext-rel-type
      reg-rel-type   = LOALPHA *( LOALPHA | DIGIT | "." | "-" )
      ext-rel-type   = URI
      
      and from <https://tools.ietf.org/html/rfc5987>
      parmname      = 1*attr-char
      attr-char     = ALPHA / DIGIT
                       / "!" / "#" / "$" / "&" / "+" / "-" / "."
                       / "^" / "_" / "`" / "|" / "~"
     */
    
    const char *h2_proxy_link_reverse_map(request_rec *r,
                                          proxy_dir_conf *conf, 
                                          const char *real_backend_uri,
                                          const char *proxy_server_uri,
                                          const char *s)
    {
        link_ctx ctx;
        
        if (r->proxyreq != PROXYREQ_REVERSE) {
            return s;
        }
        memset(&ctx, 0, sizeof(ctx));
        ctx.r = r;
        ctx.pool = r->pool;
        ctx.conf = conf;
        ctx.real_backend_uri = real_backend_uri;
        ctx.rbu_len = (int)strlen(ctx.real_backend_uri);
        ctx.p_server_uri = proxy_server_uri;
        ctx.psu_len = (int)strlen(ctx.p_server_uri);
        ctx.s = s;
        ctx.slen = (int)strlen(s);
        while (read_link(&ctx)) {
            while (skip_param(&ctx)) {
                /* nop */
            }
            map_link(&ctx);
            if (!read_sep(&ctx)) {
                break;
            }
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, 
                      "link_reverse_map %s --> %s", s, ctx.s);
        return ctx.s;
    }
    
    /*******************************************************************************
     * FIFO queue
     ******************************************************************************/
    
    struct h2_proxy_fifo {
        void **elems;
        int nelems;
        int set;
        int head;
        int count;
        int aborted;
        apr_thread_mutex_t *lock;
        apr_thread_cond_t  *not_empty;
        apr_thread_cond_t  *not_full;
    };
    
    static int nth_index(h2_proxy_fifo *fifo, int n) 
    {
        return (fifo->head + n) % fifo->nelems;
    }
    
    static apr_status_t fifo_destroy(void *data) 
    {
        h2_proxy_fifo *fifo = data;
    
        apr_thread_cond_destroy(fifo->not_empty);
        apr_thread_cond_destroy(fifo->not_full);
        apr_thread_mutex_destroy(fifo->lock);
    
        return APR_SUCCESS;
    }
    
    static int index_of(h2_proxy_fifo *fifo, void *elem)
    {
        int i;
        
        for (i = 0; i < fifo->count; ++i) {
            if (elem == fifo->elems[nth_index(fifo, i)]) {
                return i;
            }
        }
        return -1;
    }
    
    static apr_status_t create_int(h2_proxy_fifo **pfifo, apr_pool_t *pool, 
                                   int capacity, int as_set)
    {
        apr_status_t rv;
        h2_proxy_fifo *fifo;
        
        fifo = apr_pcalloc(pool, sizeof(*fifo));
        if (fifo == NULL) {
            return APR_ENOMEM;
        }
    
        rv = apr_thread_mutex_create(&fifo->lock,
                                     APR_THREAD_MUTEX_UNNESTED, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_thread_cond_create(&fifo->not_empty, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_thread_cond_create(&fifo->not_full, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        fifo->elems = apr_pcalloc(pool, capacity * sizeof(void*));
        if (fifo->elems == NULL) {
            return APR_ENOMEM;
        }
        fifo->nelems = capacity;
        fifo->set = as_set;
        
        *pfifo = fifo;
        apr_pool_cleanup_register(pool, fifo, fifo_destroy, apr_pool_cleanup_null);
    
        return APR_SUCCESS;
    }
    
    apr_status_t h2_proxy_fifo_create(h2_proxy_fifo **pfifo, apr_pool_t *pool, int capacity)
    {
        return create_int(pfifo, pool, capacity, 0);
    }
    
    apr_status_t h2_proxy_fifo_set_create(h2_proxy_fifo **pfifo, apr_pool_t *pool, int capacity)
    {
        return create_int(pfifo, pool, capacity, 1);
    }
    
    apr_status_t h2_proxy_fifo_term(h2_proxy_fifo *fifo)
    {
        apr_status_t rv;
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            fifo->aborted = 1;
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_proxy_fifo_interrupt(h2_proxy_fifo *fifo)
    {
        apr_status_t rv;
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            apr_thread_cond_broadcast(fifo->not_empty);
            apr_thread_cond_broadcast(fifo->not_full);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    int h2_proxy_fifo_count(h2_proxy_fifo *fifo)
    {
        return fifo->count;
    }
    
    int h2_proxy_fifo_capacity(h2_proxy_fifo *fifo)
    {
        return fifo->nelems;
    }
    
    static apr_status_t check_not_empty(h2_proxy_fifo *fifo, int block)
    {
        if (fifo->count == 0) {
            if (!block) {
                return APR_EAGAIN;
            }
            while (fifo->count == 0) {
                if (fifo->aborted) {
                    return APR_EOF;
                }
                apr_thread_cond_wait(fifo->not_empty, fifo->lock);
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t fifo_push(h2_proxy_fifo *fifo, void *elem, int block)
    {
        apr_status_t rv;
        
        if (fifo->aborted) {
            return APR_EOF;
        }
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            if (fifo->set && index_of(fifo, elem) >= 0) {
                /* set mode, elem already member */
                apr_thread_mutex_unlock(fifo->lock);
                return APR_EEXIST;
            }
            else if (fifo->count == fifo->nelems) {
                if (block) {
                    while (fifo->count == fifo->nelems) {
                        if (fifo->aborted) {
                            apr_thread_mutex_unlock(fifo->lock);
                            return APR_EOF;
                        }
                        apr_thread_cond_wait(fifo->not_full, fifo->lock);
                    }
                }
                else {
                    apr_thread_mutex_unlock(fifo->lock);
                    return APR_EAGAIN;
                }
            }
            
            ap_assert(fifo->count < fifo->nelems);
            fifo->elems[nth_index(fifo, fifo->count)] = elem;
            ++fifo->count;
            if (fifo->count == 1) {
                apr_thread_cond_broadcast(fifo->not_empty);
            }
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_proxy_fifo_push(h2_proxy_fifo *fifo, void *elem)
    {
        return fifo_push(fifo, elem, 1);
    }
    
    apr_status_t h2_proxy_fifo_try_push(h2_proxy_fifo *fifo, void *elem)
    {
        return fifo_push(fifo, elem, 0);
    }
    
    static void *pull_head(h2_proxy_fifo *fifo)
    {
        void *elem;
        
        ap_assert(fifo->count > 0);
        elem = fifo->elems[fifo->head];
        --fifo->count;
        if (fifo->count > 0) {
            fifo->head = nth_index(fifo, 1);
            if (fifo->count+1 == fifo->nelems) {
                apr_thread_cond_broadcast(fifo->not_full);
            }
        }
        return elem;
    }
    
    static apr_status_t fifo_pull(h2_proxy_fifo *fifo, void **pelem, int block)
    {
        apr_status_t rv;
        
        if (fifo->aborted) {
            return APR_EOF;
        }
        
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
                apr_thread_mutex_unlock(fifo->lock);
                *pelem = NULL;
                return rv;
            }
    
            ap_assert(fifo->count > 0);
            *pelem = pull_head(fifo);
    
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_proxy_fifo_pull(h2_proxy_fifo *fifo, void **pelem)
    {
        return fifo_pull(fifo, pelem, 1);
    }
    
    apr_status_t h2_proxy_fifo_try_pull(h2_proxy_fifo *fifo, void **pelem)
    {
        return fifo_pull(fifo, pelem, 0);
    }
    
    apr_status_t h2_proxy_fifo_remove(h2_proxy_fifo *fifo, void *elem)
    {
        apr_status_t rv;
        
        if (fifo->aborted) {
            return APR_EOF;
        }
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            int i, rc;
            void *e;
            
            rc = 0;
            for (i = 0; i < fifo->count; ++i) {
                e = fifo->elems[nth_index(fifo, i)];
                if (e == elem) {
                    ++rc;
                }
                else if (rc) {
                    fifo->elems[nth_index(fifo, i-rc)] = e;
                }
            }
            if (rc) {
                fifo->count -= rc;
                if (fifo->count + rc == fifo->nelems) {
                    apr_thread_cond_broadcast(fifo->not_full);
                }
                rv = APR_SUCCESS;
            }
            else {
                rv = APR_EAGAIN;
            }
            
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_workers.h�������������������������������������������������������������0000664�0001751�0001751�00000011716�14356741666�017621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_workers__
    #define __mod_h2__h2_workers__
    
    /* Thread pool specific to executing secondary connections.
     * Has a minimum and maximum number of workers it creates.
     * Starts with minimum workers and adds some on load,
     * reduces the number again when idle.
     */
    struct apr_thread_mutex_t;
    struct apr_thread_cond_t;
    struct h2_mplx;
    struct h2_request;
    struct h2_fifo;
    
    typedef struct h2_workers h2_workers;
    
    
    /**
     * Create a worker set with a maximum number of 'slots', e.g. worker
     * threads to run. Always keep `min_active` workers running. Shutdown
     * any additional workers after `idle_secs` seconds of doing nothing.
     *
     * @oaram s the base server
     * @param pool for allocations
     * @param min_active minimum number of workers to run
     * @param max_slots maximum number of worker slots
     * @param idle_limit upper duration of idle after a non-minimal slots shuts down
     */
    h2_workers *h2_workers_create(server_rec *s, apr_pool_t *pool,
                                  int max_slots, int min_active, apr_time_t idle_limit);
    
    /**
     *  Shut down processing.
     */
    void h2_workers_shutdown(h2_workers *workers, int graceful);
    
    /**
     * Get the maximum number of workers.
     */
    apr_uint32_t h2_workers_get_max_workers(h2_workers *workers);
    
    /**
     * ap_conn_producer_t is the source of connections (conn_rec*) to run.
     *
     * Active producers are queried by idle workers for connections.
     * If they do not hand one back, they become inactive and are not
     * queried further. `h2_workers_activate()` places them on the active
     * list again.
     *
     * A producer finishing MUST call `h2_workers_join()` which removes
     * it completely from workers processing and waits for all ongoing
     * work for this producer to be done.
     */
    typedef struct ap_conn_producer_t ap_conn_producer_t;
    
    /**
     * Ask a producer for the next connection to process.
     * @param baton value from producer registration
     * @param pconn holds the connection to process on return
     * @param pmore if the producer has more connections that may be retrieved
     * @return APR_SUCCESS for a connection to process, APR_EAGAIN for no
     *         connection being available at the time.
     */
    typedef conn_rec *ap_conn_producer_next(void *baton, int *pmore);
    
    /**
     * Tell the producer that processing the connection is done.
     * @param baton value from producer registration
     * @param conn the connection that has been processed.
     */
    typedef void ap_conn_producer_done(void *baton, conn_rec *conn);
    
    /**
     * Tell the producer that the workers are shutting down.
     * @param baton value from producer registration
     * @param graceful != 0 iff shutdown is graceful
     */
    typedef void ap_conn_producer_shutdown(void *baton, int graceful);
    
    /**
     * Register a new producer with the given `baton` and callback functions.
     * Will allocate internal structures from the given pool (but make no use
     * of the pool after registration).
     * Producers are inactive on registration. See `h2_workers_activate()`.
     * @param producer_pool to allocate the producer from
     * @param name descriptive name of the producer, must not be unique
     * @param fn_next callback for retrieving connections to process
     * @param fn_done callback for processed connections
     * @param baton provided value passed on in callbacks
     * @return the producer instance created
     */
    ap_conn_producer_t *h2_workers_register(h2_workers *workers,
                                            apr_pool_t *producer_pool,
                                            const char *name,
                                            ap_conn_producer_next *fn_next,
                                            ap_conn_producer_done *fn_done,
                                            ap_conn_producer_shutdown *fn_shutdown,
                                            void *baton);
    
    /**
     * Stop retrieving more connection from the producer and wait
     * for all ongoing for from that producer to be done.
     */
    apr_status_t h2_workers_join(h2_workers *workers, ap_conn_producer_t *producer);
    
    /**
     * Activate a producer. A worker will query the producer for a connection
     * to process, once a worker is available.
     * This may be called, irregardless of the producers active/inactive.
     */
    apr_status_t h2_workers_activate(h2_workers *workers, ap_conn_producer_t *producer);
    
    #endif /* defined(__mod_h2__h2_workers__) */
    ��������������������������������������������������httpd-2.4.64/modules/http2/h2_bucket_eos.h����������������������������������������������������������0000664�0001751�0001751�00000002432�13237611704�020225� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_http2_h2_bucket_stream_eos_h
    #define mod_http2_h2_bucket_stream_eos_h
    
    struct h2_stream;
    
    /** End Of HTTP/2 STREAM (H2EOS) bucket */
    extern const apr_bucket_type_t h2_bucket_type_eos;
    
    #define H2_BUCKET_IS_H2EOS(e)     (e->type == &h2_bucket_type_eos)
    
    apr_bucket *h2_bucket_eos_make(apr_bucket *b, struct h2_stream *stream);
    
    apr_bucket *h2_bucket_eos_create(apr_bucket_alloc_t *list, 
                                     struct h2_stream *stream);
    
    #endif /* mod_http2_h2_bucket_stream_eos_h */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_protocol.c������������������������������������������������������������0000664�0001751�0001751�00000067432�14356741666�017767� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include <apr_strings.h>
    #include <apr_optional.h>
    #include <apr_optional_hooks.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_ssl.h>
    #include <http_log.h>
    
    #include "mod_http2.h"
    #include "h2_private.h"
    
    #include "h2_bucket_beam.h"
    #include "h2_stream.h"
    #include "h2_c2.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_c1.h"
    #include "h2_request.h"
    #include "h2_headers.h"
    #include "h2_session.h"
    #include "h2_util.h"
    #include "h2_protocol.h"
    #include "mod_http2.h"
    
    const char *h2_protocol_ids_tls[] = {
        "h2", NULL
    };
    
    const char *h2_protocol_ids_clear[] = {
        "h2c", NULL
    };
    
    const char *H2_MAGIC_TOKEN = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
    
    /*******************************************************************************
     * HTTP/2 error stuff
     */
    static const char *h2_err_descr[] = {
        "no error",                    /* 0x0 */
        "protocol error",
        "internal error",
        "flow control error",
        "settings timeout",
        "stream closed",               /* 0x5 */
        "frame size error",
        "refused stream",
        "cancel",
        "compression error",
        "connect error",               /* 0xa */
        "enhance your calm",
        "inadequate security",
        "http/1.1 required",
    };
    
    const char *h2_protocol_err_description(unsigned int h2_error)
    {
        if (h2_error < (sizeof(h2_err_descr)/sizeof(h2_err_descr[0]))) {
            return h2_err_descr[h2_error];
        }
        return "unknown http/2 error code";
    }
    
    /*******************************************************************************
     * Check connection security requirements of RFC 7540
     */
    
    /*
     * Black Listed Ciphers from RFC 7549 Appendix A
     *
     */
    static const char *RFC7540_names[] = {
        /* ciphers with NULL encrpytion */
        "NULL-MD5",                         /* TLS_NULL_WITH_NULL_NULL */
        /* same */                          /* TLS_RSA_WITH_NULL_MD5 */
        "NULL-SHA",                         /* TLS_RSA_WITH_NULL_SHA */
        "NULL-SHA256",                      /* TLS_RSA_WITH_NULL_SHA256 */
        "PSK-NULL-SHA",                     /* TLS_PSK_WITH_NULL_SHA */
        "DHE-PSK-NULL-SHA",                 /* TLS_DHE_PSK_WITH_NULL_SHA */
        "RSA-PSK-NULL-SHA",                 /* TLS_RSA_PSK_WITH_NULL_SHA */
        "PSK-NULL-SHA256",                  /* TLS_PSK_WITH_NULL_SHA256 */
        "PSK-NULL-SHA384",                  /* TLS_PSK_WITH_NULL_SHA384 */
        "DHE-PSK-NULL-SHA256",              /* TLS_DHE_PSK_WITH_NULL_SHA256 */
        "DHE-PSK-NULL-SHA384",              /* TLS_DHE_PSK_WITH_NULL_SHA384 */
        "RSA-PSK-NULL-SHA256",              /* TLS_RSA_PSK_WITH_NULL_SHA256 */
        "RSA-PSK-NULL-SHA384",              /* TLS_RSA_PSK_WITH_NULL_SHA384 */
        "ECDH-ECDSA-NULL-SHA",              /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
        "ECDHE-ECDSA-NULL-SHA",             /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
        "ECDH-RSA-NULL-SHA",                /* TLS_ECDH_RSA_WITH_NULL_SHA */
        "ECDHE-RSA-NULL-SHA",               /* TLS_ECDHE_RSA_WITH_NULL_SHA */
        "AECDH-NULL-SHA",                   /* TLS_ECDH_anon_WITH_NULL_SHA */
        "ECDHE-PSK-NULL-SHA",               /* TLS_ECDHE_PSK_WITH_NULL_SHA */
        "ECDHE-PSK-NULL-SHA256",            /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
        "ECDHE-PSK-NULL-SHA384",            /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
        
        /* DES/3DES ciphers */
        "PSK-3DES-EDE-CBC-SHA",             /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
        "DHE-PSK-3DES-EDE-CBC-SHA",         /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
        "RSA-PSK-3DES-EDE-CBC-SHA",         /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
        "ECDH-ECDSA-DES-CBC3-SHA",          /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
        "ECDHE-ECDSA-DES-CBC3-SHA",         /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
        "ECDH-RSA-DES-CBC3-SHA",            /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
        "ECDHE-RSA-DES-CBC3-SHA",           /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
        "AECDH-DES-CBC3-SHA",               /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
        "SRP-3DES-EDE-CBC-SHA",             /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
        "SRP-RSA-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
        "SRP-DSS-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
        "ECDHE-PSK-3DES-EDE-CBC-SHA",       /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
        "DES-CBC-SHA",                      /* TLS_RSA_WITH_DES_CBC_SHA */
        "DES-CBC3-SHA",                     /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
        "DHE-DSS-DES-CBC3-SHA",             /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
        "DHE-RSA-DES-CBC-SHA",              /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
        "DHE-RSA-DES-CBC3-SHA",             /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
        "ADH-DES-CBC-SHA",                  /* TLS_DH_anon_WITH_DES_CBC_SHA */
        "ADH-DES-CBC3-SHA",                 /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
        "EXP-DH-DSS-DES-CBC-SHA",           /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
        "DH-DSS-DES-CBC-SHA",               /* TLS_DH_DSS_WITH_DES_CBC_SHA */
        "DH-DSS-DES-CBC3-SHA",              /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
        "EXP-DH-RSA-DES-CBC-SHA",           /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
        "DH-RSA-DES-CBC-SHA",               /* TLS_DH_RSA_WITH_DES_CBC_SHA */
        "DH-RSA-DES-CBC3-SHA",              /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
    
        /* blacklisted EXPORT ciphers */
        "EXP-RC4-MD5",                      /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
        "EXP-RC2-CBC-MD5",                  /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
        "EXP-DES-CBC-SHA",                  /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
        "EXP-DHE-DSS-DES-CBC-SHA",          /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
        "EXP-DHE-RSA-DES-CBC-SHA",          /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
        "EXP-ADH-DES-CBC-SHA",              /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
        "EXP-ADH-RC4-MD5",                  /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
    
        /* blacklisted RC4 encryption */
        "RC4-MD5",                          /* TLS_RSA_WITH_RC4_128_MD5 */
        "RC4-SHA",                          /* TLS_RSA_WITH_RC4_128_SHA */
        "ADH-RC4-MD5",                      /* TLS_DH_anon_WITH_RC4_128_MD5 */
        "KRB5-RC4-SHA",                     /* TLS_KRB5_WITH_RC4_128_SHA */
        "KRB5-RC4-MD5",                     /* TLS_KRB5_WITH_RC4_128_MD5 */
        "EXP-KRB5-RC4-SHA",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
        "EXP-KRB5-RC4-MD5",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
        "PSK-RC4-SHA",                      /* TLS_PSK_WITH_RC4_128_SHA */
        "DHE-PSK-RC4-SHA",                  /* TLS_DHE_PSK_WITH_RC4_128_SHA */
        "RSA-PSK-RC4-SHA",                  /* TLS_RSA_PSK_WITH_RC4_128_SHA */
        "ECDH-ECDSA-RC4-SHA",               /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
        "ECDHE-ECDSA-RC4-SHA",              /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
        "ECDH-RSA-RC4-SHA",                 /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
        "ECDHE-RSA-RC4-SHA",                /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
        "AECDH-RC4-SHA",                    /* TLS_ECDH_anon_WITH_RC4_128_SHA */
        "ECDHE-PSK-RC4-SHA",                /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
    
        /* blacklisted AES128 encrpytion ciphers */
        "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA */
        "DH-DSS-AES128-SHA",                /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
        "DH-RSA-AES128-SHA",                /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
        "DHE-DSS-AES128-SHA",               /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
        "DHE-RSA-AES128-SHA",               /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
        "ADH-AES128-SHA",                   /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
        "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
        "DH-DSS-AES128-SHA256",             /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
        "DH-RSA-AES128-SHA256",             /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
        "DHE-DSS-AES128-SHA256",            /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
        "DHE-RSA-AES128-SHA256",            /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
        "ECDH-ECDSA-AES128-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
        "ECDHE-ECDSA-AES128-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
        "ECDH-RSA-AES128-SHA",              /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
        "ECDHE-RSA-AES128-SHA",             /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
        "AECDH-AES128-SHA",                 /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
        "ECDHE-ECDSA-AES128-SHA256",        /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
        "ECDH-ECDSA-AES128-SHA256",         /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
        "ECDHE-RSA-AES128-SHA256",          /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
        "ECDH-RSA-AES128-SHA256",           /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
        "ADH-AES128-SHA256",                /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
        "PSK-AES128-CBC-SHA",               /* TLS_PSK_WITH_AES_128_CBC_SHA */
        "DHE-PSK-AES128-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
        "RSA-PSK-AES128-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
        "PSK-AES128-CBC-SHA256",            /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
        "DHE-PSK-AES128-CBC-SHA256",        /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
        "RSA-PSK-AES128-CBC-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
        "ECDHE-PSK-AES128-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
        "ECDHE-PSK-AES128-CBC-SHA256",      /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
        "AES128-CCM",                       /* TLS_RSA_WITH_AES_128_CCM */
        "AES128-CCM8",                      /* TLS_RSA_WITH_AES_128_CCM_8 */
        "PSK-AES128-CCM",                   /* TLS_PSK_WITH_AES_128_CCM */
        "PSK-AES128-CCM8",                  /* TLS_PSK_WITH_AES_128_CCM_8 */
        "AES128-GCM-SHA256",                /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
        "DH-RSA-AES128-GCM-SHA256",         /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
        "DH-DSS-AES128-GCM-SHA256",         /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
        "ADH-AES128-GCM-SHA256",            /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
        "PSK-AES128-GCM-SHA256",            /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
        "RSA-PSK-AES128-GCM-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
        "ECDH-ECDSA-AES128-GCM-SHA256",     /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
        "ECDH-RSA-AES128-GCM-SHA256",       /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
        "SRP-AES-128-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
        "SRP-RSA-AES-128-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
        "SRP-DSS-AES-128-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
        
        /* blacklisted AES256 encrpytion ciphers */
        "AES256-SHA",                       /* TLS_RSA_WITH_AES_256_CBC_SHA */
        "DH-DSS-AES256-SHA",                /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
        "DH-RSA-AES256-SHA",                /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
        "DHE-DSS-AES256-SHA",               /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
        "DHE-RSA-AES256-SHA",               /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
        "ADH-AES256-SHA",                   /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
        "AES256-SHA256",                    /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
        "DH-DSS-AES256-SHA256",             /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
        "DH-RSA-AES256-SHA256",             /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
        "DHE-DSS-AES256-SHA256",            /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
        "DHE-RSA-AES256-SHA256",            /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
        "ADH-AES256-SHA256",                /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
        "ECDH-ECDSA-AES256-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
        "ECDHE-ECDSA-AES256-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
        "ECDH-RSA-AES256-SHA",              /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
        "ECDHE-RSA-AES256-SHA",             /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
        "AECDH-AES256-SHA",                 /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
        "ECDHE-ECDSA-AES256-SHA384",        /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
        "ECDH-ECDSA-AES256-SHA384",         /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
        "ECDHE-RSA-AES256-SHA384",          /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
        "ECDH-RSA-AES256-SHA384",           /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
        "PSK-AES256-CBC-SHA",               /* TLS_PSK_WITH_AES_256_CBC_SHA */
        "DHE-PSK-AES256-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
        "RSA-PSK-AES256-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
        "PSK-AES256-CBC-SHA384",            /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
        "DHE-PSK-AES256-CBC-SHA384",        /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
        "RSA-PSK-AES256-CBC-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
        "ECDHE-PSK-AES256-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
        "ECDHE-PSK-AES256-CBC-SHA384",      /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
        "SRP-AES-256-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
        "SRP-RSA-AES-256-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
        "SRP-DSS-AES-256-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
        "AES256-CCM",                       /* TLS_RSA_WITH_AES_256_CCM */
        "AES256-CCM8",                      /* TLS_RSA_WITH_AES_256_CCM_8 */
        "PSK-AES256-CCM",                   /* TLS_PSK_WITH_AES_256_CCM */
        "PSK-AES256-CCM8",                  /* TLS_PSK_WITH_AES_256_CCM_8 */
        "AES256-GCM-SHA384",                /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
        "DH-RSA-AES256-GCM-SHA384",         /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
        "DH-DSS-AES256-GCM-SHA384",         /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
        "ADH-AES256-GCM-SHA384",            /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
        "PSK-AES256-GCM-SHA384",            /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
        "RSA-PSK-AES256-GCM-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
        "ECDH-ECDSA-AES256-GCM-SHA384",     /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
        "ECDH-RSA-AES256-GCM-SHA384",       /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
        
        /* blacklisted CAMELLIA128 encrpytion ciphers */
        "CAMELLIA128-SHA",                  /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
        "DH-DSS-CAMELLIA128-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
        "DH-RSA-CAMELLIA128-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
        "DHE-DSS-CAMELLIA128-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
        "DHE-RSA-CAMELLIA128-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
        "ADH-CAMELLIA128-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
        "ECDHE-ECDSA-CAMELLIA128-SHA256",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
        "ECDH-ECDSA-CAMELLIA128-SHA256",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
        "ECDHE-RSA-CAMELLIA128-SHA256",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
        "ECDH-RSA-CAMELLIA128-SHA256",      /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
        "PSK-CAMELLIA128-SHA256",           /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
        "DHE-PSK-CAMELLIA128-SHA256",       /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
        "RSA-PSK-CAMELLIA128-SHA256",       /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
        "ECDHE-PSK-CAMELLIA128-SHA256",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
        "CAMELLIA128-GCM-SHA256",           /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
        "DH-RSA-CAMELLIA128-GCM-SHA256",    /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
        "DH-DSS-CAMELLIA128-GCM-SHA256",    /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
        "ADH-CAMELLIA128-GCM-SHA256",       /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
        "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
        "ECDH-RSA-CAMELLIA128-GCM-SHA256",  /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
        "PSK-CAMELLIA128-GCM-SHA256",       /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
        "RSA-PSK-CAMELLIA128-GCM-SHA256",   /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
        "CAMELLIA128-SHA256",               /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
        "DH-DSS-CAMELLIA128-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
        "DH-RSA-CAMELLIA128-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
        "DHE-DSS-CAMELLIA128-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
        "DHE-RSA-CAMELLIA128-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
        "ADH-CAMELLIA128-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
        
        /* blacklisted CAMELLIA256 encrpytion ciphers */
        "CAMELLIA256-SHA",                  /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
        "DH-RSA-CAMELLIA256-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
        "DH-DSS-CAMELLIA256-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
        "DHE-DSS-CAMELLIA256-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
        "DHE-RSA-CAMELLIA256-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
        "ADH-CAMELLIA256-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
        "ECDHE-ECDSA-CAMELLIA256-SHA384",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
        "ECDH-ECDSA-CAMELLIA256-SHA384",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
        "ECDHE-RSA-CAMELLIA256-SHA384",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
        "ECDH-RSA-CAMELLIA256-SHA384",      /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
        "PSK-CAMELLIA256-SHA384",           /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
        "DHE-PSK-CAMELLIA256-SHA384",       /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
        "RSA-PSK-CAMELLIA256-SHA384",       /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
        "ECDHE-PSK-CAMELLIA256-SHA384",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
        "CAMELLIA256-SHA256",               /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
        "DH-DSS-CAMELLIA256-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
        "DH-RSA-CAMELLIA256-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
        "DHE-DSS-CAMELLIA256-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
        "DHE-RSA-CAMELLIA256-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
        "ADH-CAMELLIA256-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
        "CAMELLIA256-GCM-SHA384",           /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
        "DH-RSA-CAMELLIA256-GCM-SHA384",    /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
        "DH-DSS-CAMELLIA256-GCM-SHA384",    /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
        "ADH-CAMELLIA256-GCM-SHA384",       /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
        "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
        "ECDH-RSA-CAMELLIA256-GCM-SHA384",  /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
        "PSK-CAMELLIA256-GCM-SHA384",       /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
        "RSA-PSK-CAMELLIA256-GCM-SHA384",   /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
        
        /* The blacklisted ARIA encrpytion ciphers */
        "ARIA128-SHA256",                   /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
        "ARIA256-SHA384",                   /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
        "DH-DSS-ARIA128-SHA256",            /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
        "DH-DSS-ARIA256-SHA384",            /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
        "DH-RSA-ARIA128-SHA256",            /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
        "DH-RSA-ARIA256-SHA384",            /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
        "DHE-DSS-ARIA128-SHA256",           /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
        "DHE-DSS-ARIA256-SHA384",           /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
        "DHE-RSA-ARIA128-SHA256",           /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
        "DHE-RSA-ARIA256-SHA384",           /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
        "ADH-ARIA128-SHA256",               /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
        "ADH-ARIA256-SHA384",               /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
        "ECDHE-ECDSA-ARIA128-SHA256",       /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
        "ECDHE-ECDSA-ARIA256-SHA384",       /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
        "ECDH-ECDSA-ARIA128-SHA256",        /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
        "ECDH-ECDSA-ARIA256-SHA384",        /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
        "ECDHE-RSA-ARIA128-SHA256",         /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
        "ECDHE-RSA-ARIA256-SHA384",         /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
        "ECDH-RSA-ARIA128-SHA256",          /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
        "ECDH-RSA-ARIA256-SHA384",          /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
        "ARIA128-GCM-SHA256",               /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
        "ARIA256-GCM-SHA384",               /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
        "DH-DSS-ARIA128-GCM-SHA256",        /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
        "DH-DSS-ARIA256-GCM-SHA384",        /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
        "DH-RSA-ARIA128-GCM-SHA256",        /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
        "DH-RSA-ARIA256-GCM-SHA384",        /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
        "ADH-ARIA128-GCM-SHA256",           /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
        "ADH-ARIA256-GCM-SHA384",           /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
        "ECDH-ECDSA-ARIA128-GCM-SHA256",    /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
        "ECDH-ECDSA-ARIA256-GCM-SHA384",    /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
        "ECDH-RSA-ARIA128-GCM-SHA256",      /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
        "ECDH-RSA-ARIA256-GCM-SHA384",      /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
        "PSK-ARIA128-SHA256",               /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
        "PSK-ARIA256-SHA384",               /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
        "DHE-PSK-ARIA128-SHA256",           /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
        "DHE-PSK-ARIA256-SHA384",           /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
        "RSA-PSK-ARIA128-SHA256",           /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
        "RSA-PSK-ARIA256-SHA384",           /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
        "ARIA128-GCM-SHA256",               /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
        "ARIA256-GCM-SHA384",               /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
        "RSA-PSK-ARIA128-GCM-SHA256",       /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
        "RSA-PSK-ARIA256-GCM-SHA384",       /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
        "ECDHE-PSK-ARIA128-SHA256",         /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
        "ECDHE-PSK-ARIA256-SHA384",         /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
    
        /* blacklisted SEED encryptions */
        "SEED-SHA",                         /*TLS_RSA_WITH_SEED_CBC_SHA */
        "DH-DSS-SEED-SHA",                  /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
        "DH-RSA-SEED-SHA",                  /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
        "DHE-DSS-SEED-SHA",                 /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
        "DHE-RSA-SEED-SHA",                 /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */               
        "ADH-SEED-SHA",                     /* TLS_DH_anon_WITH_SEED_CBC_SHA */
    
        /* blacklisted KRB5 ciphers */
        "KRB5-DES-CBC-SHA",                 /* TLS_KRB5_WITH_DES_CBC_SHA */
        "KRB5-DES-CBC3-SHA",                /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
        "KRB5-IDEA-CBC-SHA",                /* TLS_KRB5_WITH_IDEA_CBC_SHA */
        "KRB5-DES-CBC-MD5",                 /* TLS_KRB5_WITH_DES_CBC_MD5 */
        "KRB5-DES-CBC3-MD5",                /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
        "KRB5-IDEA-CBC-MD5",                /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
        "EXP-KRB5-DES-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
        "EXP-KRB5-DES-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
        "EXP-KRB5-RC2-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
        "EXP-KRB5-RC2-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
      
        /* blacklisted exoticas */
        "DHE-DSS-CBC-SHA",                  /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
        "IDEA-CBC-SHA",                     /* TLS_RSA_WITH_IDEA_CBC_SHA */
        
        /* not really sure if the following names are correct */
        "SSL3_CK_SCSV",                     /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
        "SSL3_CK_FALLBACK_SCSV"
    };
    static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
    
    
    static apr_hash_t *BLCNames;
    
    static void cipher_init(apr_pool_t *pool)
    {
        apr_hash_t *hash = apr_hash_make(pool);
        const char *source;
        unsigned int i;
        
        source = "rfc7540";
        for (i = 0; i < RFC7540_names_LEN; ++i) {
            apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
        }
        
        BLCNames = hash;
    }
    
    static int cipher_is_blacklisted(const char *cipher, const char **psource)
    {   
        *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
        return !!*psource;
    }
    
    apr_status_t h2_protocol_init(apr_pool_t *pool, server_rec *s)
    {
        (void)pool;
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_h2, child_init");
        cipher_init(pool);
        
        return APR_SUCCESS;
    }
    
    int h2_protocol_is_acceptable_c1(conn_rec *c, request_rec *r, int require_all)
    {
        int is_tls = ap_ssl_conn_is_ssl(c);
    
        if (is_tls && h2_config_cgeti(c, H2_CONF_MODERN_TLS_ONLY) > 0) {
            /* Check TLS connection for modern TLS parameters, as defined in
             * RFC 7540 and https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
             */
            apr_pool_t *pool = c->pool;
            server_rec *s = c->base_server;
            const char *val;
    
            /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
             */
            val = ap_ssl_var_lookup(pool, s, c, NULL, "SSL_PROTOCOL");
            if (val && *val) {
                if (strncmp("TLS", val, 3) 
                    || !strcmp("TLSv1", val) 
                    || !strcmp("TLSv1.1", val)) {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03050)
                                  "h2_h2(%ld): tls protocol not suitable: %s", 
                                  (long)c->id, val);
                    return 0;
                }
            }
            else if (require_all) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03051)
                              "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
                return 0;
            }
    
            if (val && !strcmp("TLSv1.2", val)) {
                /* Check TLS cipher blacklist, defined pre-TLSv1.3, so only
                 * checking for 1.2 */
                val = ap_ssl_var_lookup(pool, s, c, NULL, "SSL_CIPHER");
                if (val && *val) {
                    const char *source;
                    if (cipher_is_blacklisted(val, &source)) {
                        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03052)
                                      "h2_h2(%ld): tls cipher %s blacklisted by %s",
                                      (long)c->id, val, source);
                        return 0;
                    }
                }
                else if (require_all) {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03053)
                                  "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
                    return 0;
                }
            }
        }
        return 1;
    }
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_push.h����������������������������������������������������������������0000664�0001751�0001751�00000014365�14356741666�017107� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_push__
    #define __mod_h2__h2_push__
    
    #include <http_protocol.h>
    
    #include "h2.h"
    #include "h2_headers.h"
    
    struct h2_request;
    struct h2_ngheader;
    struct h2_session;
    struct h2_stream;
    
    typedef struct h2_push {
        const struct h2_request *req;
        h2_priority *priority;
    } h2_push;
    
    typedef enum {
        H2_PUSH_DIGEST_APR_HASH,
        H2_PUSH_DIGEST_SHA256
    } h2_push_digest_type;
    
    /*******************************************************************************
     * push diary 
     *
     * - The push diary keeps track of resources already PUSHed via HTTP/2 on this
     *   connection. It records a hash value from the absolute URL of the resource
     *   pushed.
     * - Lacking openssl, 
     * - with openssl, it uses SHA256 to calculate the hash value, otherwise it
     *   falls back to apr_hashfunc_default()
     * - whatever the method to generate the hash, the diary keeps a maximum of 64
     *   bits per hash, limiting the memory consumption to about 
     *      H2PushDiarySize * 8 
     *   bytes. Entries are sorted by most recently used and oldest entries are
     *   forgotten first.
     * - While useful by itself to avoid duplicated PUSHes on the same connection,
     *   the original idea was that clients provided a 'Cache-Digest' header with
     *   the values of *their own* cached resources. This was described in
     *   <https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/> 
     *   and some subsequent revisions that tweaked values but kept the overall idea.
     * - The draft was abandoned by the IETF http-wg, as support from major clients,
     *   e.g. browsers, was lacking for various reasons.
     * - For these reasons, mod_h2 abandoned its support for client supplied values
     *   but keeps the diary. It seems to provide value for applications using PUSH,
     *   is configurable in size and defaults to a very moderate amount of memory
     *   used.
     * - The cache digest header is a Golomb Coded Set of hash values, but it may
     *   limit the amount of bits per hash value even further. For a good description
     *   of GCS, read here:
     *   <http://giovanni.bajo.it/post/47119962313/golomb-coded-sets-smaller-than-bloom-filters>
     ******************************************************************************/
     
     
    /*
     * The push diary is based on the abandoned draft 
     * <https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/>
     * that describes how to use golomb filters.
     */
    
    typedef struct h2_push_diary h2_push_diary;
    
    typedef void h2_push_digest_calc(h2_push_diary *diary, apr_uint64_t *phash, h2_push *push);
    
    struct h2_push_diary {
        apr_array_header_t  *entries;
        int         NMax; /* Maximum for N, should size change be necessary */
        int         N;    /* Current maximum number of entries, power of 2 */
        apr_uint64_t         mask; /* mask for relevant bits */
        unsigned int         mask_bits; /* number of relevant bits */
        const char          *authority;
        h2_push_digest_type  dtype;
        h2_push_digest_calc *dcalc;
    };
    
    /**
     * Determine the list of h2_push'es to send to the client on behalf of
     * the given request/response pair.
     *
     * @param p the pool to use
     * @param req the requst from the client
     * @param res the response from the server
     * @return array of h2_push addresses or NULL
     */
    #if AP_HAS_RESPONSE_BUCKETS
    apr_array_header_t *h2_push_collect(apr_pool_t *p,
                                        const struct h2_request *req,
                                        apr_uint32_t push_policy,
                                        const ap_bucket_response *res);
    #else
    apr_array_header_t *h2_push_collect(apr_pool_t *p,
                                        const struct h2_request *req,
                                        apr_uint32_t push_policy,
                                        const struct h2_headers *res);
    #endif
    
    /**
     * Create a new push diary for the given maximum number of entries.
     *
     * @param p the pool to use
     * @param N the max number of entries, rounded up to 2^x
     * @return the created diary, might be NULL of max_entries is 0
     */
    h2_push_diary *h2_push_diary_create(apr_pool_t *p, int N);
    
    /**
     * Filters the given pushes against the diary and returns only those pushes
     * that were newly entered in the diary.
     */
    apr_array_header_t *h2_push_diary_update(struct h2_session *session, apr_array_header_t *pushes);
    
    /**
     * Collect pushes for the given request/response pair, enter them into the
     * diary and return those pushes newly entered.
     */
    #if AP_HAS_RESPONSE_BUCKETS
    apr_array_header_t *h2_push_collect_update(struct h2_stream *stream,
                                               const struct h2_request *req,
                                               const ap_bucket_response *res);
    #else
    apr_array_header_t *h2_push_collect_update(struct h2_stream *stream,
                                               const struct h2_request *req,
                                               const struct h2_headers *res);
    #endif
    
    /**
     * Get a cache digest as described in 
     * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/
     * from the contents of the push diary.
     *
     * @param diary the diary to calculdate the digest from
     * @param p the pool to use
     * @param authority the authority to get the data for, use NULL/"*" for all
     * @param pdata on successful return, the binary cache digest
     * @param plen on successful return, the length of the binary data
     */
    apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *p, 
                                          int maxP, const char *authority, 
                                          const char **pdata, apr_size_t *plen);
    
    #endif /* defined(__mod_h2__h2_push__) */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_http2.mak������������������������������������������������������������0000664�0001751�0001751�00000033454�13442347205�017742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_http2.dsp
    !IF "$(CFG)" == ""
    CFG=mod_http2 - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_http2 - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_http2 - Win32 Release" && "$(CFG)" != "mod_http2 - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_http2.mak" CFG="mod_http2 - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_http2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_http2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_http2 - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\h2_alt_svc.obj"
    	-@erase "$(INTDIR)\h2_bucket_beam.obj"
    	-@erase "$(INTDIR)\h2_bucket_eos.obj"
    	-@erase "$(INTDIR)\h2_config.obj"
    	-@erase "$(INTDIR)\h2_conn.obj"
    	-@erase "$(INTDIR)\h2_conn_io.obj"
    	-@erase "$(INTDIR)\h2_ctx.obj"
    	-@erase "$(INTDIR)\h2_filter.obj"
    	-@erase "$(INTDIR)\h2_from_h1.obj"
    	-@erase "$(INTDIR)\h2_h2.obj"
    	-@erase "$(INTDIR)\h2_headers.obj"
    	-@erase "$(INTDIR)\h2_mplx.obj"
    	-@erase "$(INTDIR)\h2_push.obj"
    	-@erase "$(INTDIR)\h2_request.obj"
    	-@erase "$(INTDIR)\h2_session.obj"
    	-@erase "$(INTDIR)\h2_stream.obj"
    	-@erase "$(INTDIR)\h2_switch.obj"
    	-@erase "$(INTDIR)\h2_task.obj"
    	-@erase "$(INTDIR)\h2_util.obj"
    	-@erase "$(INTDIR)\h2_workers.obj"
    	-@erase "$(INTDIR)\mod_http2.obj"
    	-@erase "$(INTDIR)\mod_http2.res"
    	-@erase "$(INTDIR)\mod_http2_src.idb"
    	-@erase "$(INTDIR)\mod_http2_src.pdb"
    	-@erase "$(OUTDIR)\mod_http2.exp"
    	-@erase "$(OUTDIR)\mod_http2.lib"
    	-@erase "$(OUTDIR)\mod_http2.pdb"
    	-@erase "$(OUTDIR)\mod_http2.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D ssize_t=long /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_http2_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_http2.so" /d LONG_NAME="http2_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_http2.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib nghttp2.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_http2.pdb" /debug /out:"$(OUTDIR)\mod_http2.so" /implib:"$(OUTDIR)\mod_http2.lib" /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /base:@..\..\os\win32\BaseAddr.ref,mod_http2.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\h2_alt_svc.obj" \
    	"$(INTDIR)\h2_bucket_beam.obj" \
    	"$(INTDIR)\h2_bucket_eos.obj" \
    	"$(INTDIR)\h2_config.obj" \
    	"$(INTDIR)\h2_conn.obj" \
    	"$(INTDIR)\h2_conn_io.obj" \
    	"$(INTDIR)\h2_ctx.obj" \
    	"$(INTDIR)\h2_filter.obj" \
    	"$(INTDIR)\h2_from_h1.obj" \
    	"$(INTDIR)\h2_h2.obj" \
    	"$(INTDIR)\h2_headers.obj" \
    	"$(INTDIR)\h2_mplx.obj" \
    	"$(INTDIR)\h2_push.obj" \
    	"$(INTDIR)\h2_request.obj" \
    	"$(INTDIR)\h2_session.obj" \
    	"$(INTDIR)\h2_stream.obj" \
    	"$(INTDIR)\h2_switch.obj" \
    	"$(INTDIR)\h2_task.obj" \
    	"$(INTDIR)\h2_util.obj" \
    	"$(INTDIR)\h2_workers.obj" \
    	"$(INTDIR)\mod_http2.obj" \
    	"$(INTDIR)\mod_http2.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_http2.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_http2.so"
       if exist .\Release\mod_http2.so.manifest mt.exe -manifest .\Release\mod_http2.so.manifest -outputresource:.\Release\mod_http2.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_http2 - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\h2_alt_svc.obj"
    	-@erase "$(INTDIR)\h2_bucket_beam.obj"
    	-@erase "$(INTDIR)\h2_bucket_eos.obj"
    	-@erase "$(INTDIR)\h2_config.obj"
    	-@erase "$(INTDIR)\h2_conn.obj"
    	-@erase "$(INTDIR)\h2_conn_io.obj"
    	-@erase "$(INTDIR)\h2_ctx.obj"
    	-@erase "$(INTDIR)\h2_filter.obj"
    	-@erase "$(INTDIR)\h2_from_h1.obj"
    	-@erase "$(INTDIR)\h2_h2.obj"
    	-@erase "$(INTDIR)\h2_headers.obj"
    	-@erase "$(INTDIR)\h2_mplx.obj"
    	-@erase "$(INTDIR)\h2_push.obj"
    	-@erase "$(INTDIR)\h2_request.obj"
    	-@erase "$(INTDIR)\h2_session.obj"
    	-@erase "$(INTDIR)\h2_stream.obj"
    	-@erase "$(INTDIR)\h2_switch.obj"
    	-@erase "$(INTDIR)\h2_task.obj"
    	-@erase "$(INTDIR)\h2_util.obj"
    	-@erase "$(INTDIR)\h2_workers.obj"
    	-@erase "$(INTDIR)\mod_http2.obj"
    	-@erase "$(INTDIR)\mod_http2.res"
    	-@erase "$(INTDIR)\mod_http2_src.idb"
    	-@erase "$(INTDIR)\mod_http2_src.pdb"
    	-@erase "$(OUTDIR)\mod_http2.exp"
    	-@erase "$(OUTDIR)\mod_http2.lib"
    	-@erase "$(OUTDIR)\mod_http2.pdb"
    	-@erase "$(OUTDIR)\mod_http2.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D ssize_t=long /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_http2_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_http2.so" /d LONG_NAME="http2_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_http2.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib nghttp2d.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_http2.pdb" /debug /out:"$(OUTDIR)\mod_http2.so" /implib:"$(OUTDIR)\mod_http2.lib" /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /base:@..\..\os\win32\BaseAddr.ref,mod_http2.so 
    LINK32_OBJS= \
    	"$(INTDIR)\h2_alt_svc.obj" \
    	"$(INTDIR)\h2_bucket_beam.obj" \
    	"$(INTDIR)\h2_bucket_eos.obj" \
    	"$(INTDIR)\h2_config.obj" \
    	"$(INTDIR)\h2_conn.obj" \
    	"$(INTDIR)\h2_conn_io.obj" \
    	"$(INTDIR)\h2_ctx.obj" \
    	"$(INTDIR)\h2_filter.obj" \
    	"$(INTDIR)\h2_from_h1.obj" \
    	"$(INTDIR)\h2_h2.obj" \
    	"$(INTDIR)\h2_headers.obj" \
    	"$(INTDIR)\h2_mplx.obj" \
    	"$(INTDIR)\h2_push.obj" \
    	"$(INTDIR)\h2_request.obj" \
    	"$(INTDIR)\h2_session.obj" \
    	"$(INTDIR)\h2_stream.obj" \
    	"$(INTDIR)\h2_switch.obj" \
    	"$(INTDIR)\h2_task.obj" \
    	"$(INTDIR)\h2_util.obj" \
    	"$(INTDIR)\h2_workers.obj" \
    	"$(INTDIR)\mod_http2.obj" \
    	"$(INTDIR)\mod_http2.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_http2.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_http2.so"
       if exist .\Debug\mod_http2.so.manifest mt.exe -manifest .\Debug\mod_http2.so.manifest -outputresource:.\Debug\mod_http2.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_http2.dep")
    !INCLUDE "mod_http2.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_http2.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_http2 - Win32 Release" || "$(CFG)" == "mod_http2 - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_http2 - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\http2"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ELSEIF  "$(CFG)" == "mod_http2 - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\http2"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_http2 - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\http2"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ELSEIF  "$(CFG)" == "mod_http2 - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\http2"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_http2 - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\http2"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\http2"
    
    !ELSEIF  "$(CFG)" == "mod_http2 - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\http2"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\http2"
    
    !ENDIF 
    
    SOURCE=./h2_alt_svc.c
    
    "$(INTDIR)\h2_alt_svc.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_bucket_beam.c
    
    "$(INTDIR)/h2_bucket_beam.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_bucket_eos.c
    
    "$(INTDIR)\h2_bucket_eos.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_config.c
    
    "$(INTDIR)\h2_config.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_conn.c
    
    "$(INTDIR)\h2_conn.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_conn_io.c
    
    "$(INTDIR)\h2_conn_io.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_ctx.c
    
    "$(INTDIR)\h2_ctx.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_filter.c
    
    "$(INTDIR)\h2_filter.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_from_h1.c
    
    "$(INTDIR)\h2_from_h1.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_h2.c
    
    "$(INTDIR)\h2_h2.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_headers.c
    
    "$(INTDIR)\h2_headers.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_mplx.c
    
    "$(INTDIR)\h2_mplx.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_push.c
    
    "$(INTDIR)\h2_push.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_request.c
    
    "$(INTDIR)\h2_request.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_session.c
    
    "$(INTDIR)\h2_session.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_stream.c
    
    "$(INTDIR)\h2_stream.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_switch.c
    
    "$(INTDIR)\h2_switch.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_task.c
    
    "$(INTDIR)\h2_task.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_util.c
    
    "$(INTDIR)\h2_util.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_workers.c
    
    "$(INTDIR)\h2_workers.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_http2 - Win32 Release"
    
    
    "$(INTDIR)\mod_http2.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_http2.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_http2.so" /d LONG_NAME="http2_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_http2 - Win32 Debug"
    
    
    "$(INTDIR)\mod_http2.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_http2.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_http2.so" /d LONG_NAME="http2_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=./mod_http2.c
    
    "$(INTDIR)\mod_http2.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_http2.dep������������������������������������������������������������0000664�0001751�0001751�00000135447�13442347205�017747� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_http2.mak
    
    ./h2_alt_svc.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2_alt_svc.h"\
    	".\h2_config.h"\
    	".\h2_ctx.h"\
    	".\h2_h2.h"\
    	".\h2_private.h"\
    	".\h2_util.h"\
    	
    
    ./h2_bucket_eos.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_bucket_eos.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_stream.h"\
    	
    
    ./h2_config.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_vhost.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_alt_svc.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_ctx.h"\
    	".\h2_h2.h"\
    	".\h2_private.h"\
    	
    
    ./h2_conn.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_filter.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_version.h"\
    	".\h2_workers.h"\
    	
    
    ./h2_conn_io.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_bucket_eos.h"\
    	".\h2_config.h"\
    	".\h2_conn_io.h"\
    	".\h2_h2.h"\
    	".\h2_private.h"\
    	".\h2_session.h"\
    	".\h2_util.h"\
    	
    
    ./h2_ctx.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_private.h"\
    	".\h2_session.h"\
    	".\h2_task.h"\
    	
    
    ./h2_filter.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_filter.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_push.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	".\h2_version.h"\
    	
    
    ./h2_from_h1.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_time.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_from_h1.h"\
    	".\h2_private.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	
    
    ./h2_h2.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\ssl\mod_ssl.h"\
    	".\h2.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_h2.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	".\mod_http2.h"\
    	
    
    ./h2_int_queue.c : \
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    
    ./h2_io.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_cond.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	
    
    ./h2_io_set.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2_io_set.h"\
    	".\h2_private.h"\
    	
    
    ./h2_mplx.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_cond.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_ctx.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	".\h2_workers.h"\
    	".\mod_http2.h"\
    	
    
    ./h2_ngn_shed.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_cond.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_ctx.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	".\mod_http2.h"\
    	
    
    ./h2_push.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_conn_io.h"\
    	".\h2_h2.h"\
    	".\h2_private.h"\
    	".\h2_push.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_util.h"\
    	
    
    ./h2_request.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\http_vhost.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_private.h"\
    	".\h2_push.h"\
    	".\h2_request.h"\
    	".\h2_util.h"\
    	
    
    ./h2_session.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_cond.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_bucket_eos.h"\
    	".\h2_config.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_filter.h"\
    	".\h2_from_h1.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_push.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	".\h2_version.h"\
    	".\h2_workers.h"\
    	
    
    ./h2_stream.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_filter.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_push.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	
    
    ./h2_switch.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_ctx.h"\
    	".\h2_h2.h"\
    	".\h2_private.h"\
    	".\h2_switch.h"\
    	
    
    ./h2_task.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\http_vhost.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_atomic.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_cond.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_from_h1.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	
    
    ./h2_task_input.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_conn.h"\
    	".\h2_conn_io.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	
    
    ./h2_task_output.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_cond.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_conn.h"\
    	".\h2_conn_io.h"\
    	".\h2_from_h1.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_task.h"\
    	".\h2_util.h"\
    	
    
    ./h2_util.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_private.h"\
    	".\h2_request.h"\
    	".\h2_util.h"\
    	
    
    ./h2_workers.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mpm_common.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_atomic.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_cond.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_mplx.h"\
    	".\h2_private.h"\
    	".\h2_task.h"\
    	".\h2_workers.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    ./mod_http2.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_queue.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\h2.h"\
    	".\h2_alt_svc.h"\
    	".\h2_config.h"\
    	".\h2_conn.h"\
    	".\h2_conn_io.h"\
    	".\h2_ctx.h"\
    	".\h2_filter.h"\
    	".\h2_h2.h"\
    	".\h2_mplx.h"\
    	".\h2_push.h"\
    	".\h2_request.h"\
    	".\h2_session.h"\
    	".\h2_stream.h"\
    	".\h2_switch.h"\
    	".\h2_task.h"\
    	".\h2_version.h"\
    	".\mod_http2.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_private.h�������������������������������������������������������������0000664�0001751�0001751�00000001743�13237611704�017560� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2_h2_private_h
    #define mod_h2_h2_private_h
    
    #include <apr_time.h>
    
    #include <nghttp2/nghttp2.h>
    
    extern module AP_MODULE_DECLARE_DATA http2_module;
    
    APLOG_USE_MODULE(http2);
    
    #endif
    �����������������������������httpd-2.4.64/modules/http2/NWGNUproxyht2������������������������������������������������������������0000664�0001751�0001751�00000012050�12761517777�017716� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # This Makefile requires the environment var NGH2SRC
    # pointing to the base directory of nghttp2 source tree.
    #
    
    #
    # 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 \
    			$(SRC)/include \
    			$(NGH2SRC)/lib/includes \
    			$(STDMOD)/proxy \
    			$(SERVER)/mpm/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		+= \
    			-L$(OBJDIR) \
    			$(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	= proxyht2
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) HTTP2 Proxy module
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_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	= 65536
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_proxy_http2.o \
    	$(OBJDIR)/h2_proxy_session.o \
    	$(OBJDIR)/h2_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 = \
    	$(PRELUDE) \
    	$(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 \
    	Apache2 \
    	mod_proxy \
    	mod_http2 \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_http2.imp \
    	ap_proxy_acquire_connection \
    	ap_proxy_canon_netloc \
    	ap_proxy_canonenc \
    	ap_proxy_connect_backend \
    	ap_proxy_connection_create \
    	ap_proxy_cookie_reverse_map \
    	ap_proxy_determine_connection \
    	ap_proxy_location_reverse_map \
    	ap_proxy_port_of_scheme \
    	ap_proxy_release_connection \
    	ap_proxy_ssl_connection_cleanup \
    	ap_sock_disable_nagle \
    	proxy_hook_canon_handler \
    	proxy_hook_scheme_handler \
    	proxy_module \
    	proxy_run_detach_backend \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	proxy_http2_module \
    	$(EOLIST)
    
    #
    # These are the OBJ files needed to create the LIB target above.
    # Paths must all use the '/' character
    #
    FILES_lib_objs :=
    #
    # 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
    	$(call COPY,$(OBJDIR)/*.nlm,        $(INSTALLBASE)/modules/)
    
    clean ::
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_proxy_http2.mak������������������������������������������������������0000664�0001751�0001751�00000031130�12733263444�021174� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_http2.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_http2 - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_http2 - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_http2 - Win32 Release" && "$(CFG)" != "mod_proxy_http2 - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_http2.mak" CFG="mod_proxy_http2 - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_http2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_http2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http2 - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "mod_http2 - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_http2 - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\h2_proxy_session.obj"
    	-@erase "$(INTDIR)\h2_proxy_util.obj"
    	-@erase "$(INTDIR)\mod_proxy_http2.obj"
    	-@erase "$(INTDIR)\mod_proxy_http2.res"
    	-@erase "$(INTDIR)\mod_proxy_http2_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_http2_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http2.exp"
    	-@erase "$(OUTDIR)\mod_proxy_http2.lib"
    	-@erase "$(OUTDIR)\mod_proxy_http2.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http2.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D ssize_t=long /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_http2_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_http2.so" /d LONG_NAME="http2_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_http2.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib nghttp2.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_http2.pdb" /debug /out:"$(OUTDIR)\mod_proxy_http2.so" /implib:"$(OUTDIR)\mod_proxy_http2.lib" /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http2.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\h2_proxy_session.obj" \
    	"$(INTDIR)\h2_proxy_util.obj" \
    	"$(INTDIR)\mod_proxy_http2.obj" \
    	"$(INTDIR)\mod_proxy_http2.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_http2.lib" \
    	"..\proxy\Release\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_http2.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_http2.so"
       if exist .\Release\mod_proxy_http2.so.manifest mt.exe -manifest .\Release\mod_proxy_http2.so.manifest -outputresource:.\Release\mod_proxy_http2.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "mod_http2 - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_http2.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_http2 - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\h2_proxy_session.obj"
    	-@erase "$(INTDIR)\h2_proxy_util.obj"
    	-@erase "$(INTDIR)\mod_proxy_http2.obj"
    	-@erase "$(INTDIR)\mod_proxy_http2.res"
    	-@erase "$(INTDIR)\mod_proxy_http2_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_http2_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http2.exp"
    	-@erase "$(OUTDIR)\mod_proxy_http2.lib"
    	-@erase "$(OUTDIR)\mod_proxy_http2.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http2.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D ssize_t=long /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_http2_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_http2.so" /d LONG_NAME="http2_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_http2.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib nghttp2d.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_http2.pdb" /debug /out:"$(OUTDIR)\mod_proxy_http2.so" /implib:"$(OUTDIR)\mod_proxy_http2.lib" /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http2.so 
    LINK32_OBJS= \
    	"$(INTDIR)\h2_proxy_session.obj" \
    	"$(INTDIR)\h2_proxy_util.obj" \
    	"$(INTDIR)\mod_proxy_http2.obj" \
    	"$(INTDIR)\mod_proxy_http2.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_http2.lib" \
    	"..\proxy\Debug\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_http2.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_http2.so"
       if exist .\Debug\mod_proxy_http2.so.manifest mt.exe -manifest .\Debug\mod_proxy_http2.so.manifest -outputresource:.\Debug\mod_proxy_http2.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_http2.dep")
    !INCLUDE "mod_proxy_http2.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_http2.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_http2 - Win32 Release" || "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_proxy_http2 - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\http2"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\http2"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http2 - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\http2"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\http2"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\http2"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http2 - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\http2"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\http2"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\http2"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\http2"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http2 - Win32 Release"
    
    "mod_http2 - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_http2.mak" CFG="mod_http2 - Win32 Release" 
       cd "."
    
    "mod_http2 - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_http2.mak" CFG="mod_http2 - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    "mod_http2 - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_http2.mak" CFG="mod_http2 - Win32 Debug" 
       cd "."
    
    "mod_http2 - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_http2.mak" CFG="mod_http2 - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http2 - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd ".\..\proxy"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "..\http2"
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd ".\..\proxy"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "..\http2"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd ".\..\proxy"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "..\http2"
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd ".\..\proxy"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\http2"
    
    !ENDIF 
    
    SOURCE=./h2_proxy_session.c
    
    "$(INTDIR)\h2_proxy_session.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=./h2_proxy_util.c
    
    "$(INTDIR)\h2_proxy_util.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_http2 - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_http2.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_http2.res" /i "../../include" /i "../../srclib/apr/include" /i "\Build11\httpd-2.4.21-dev-mph2\build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_http2.so" /d LONG_NAME="http2_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_http2.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_http2.res" /i "../../include" /i "../../srclib/apr/include" /i "\Build11\httpd-2.4.21-dev-mph2\build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_http2.so" /d LONG_NAME="http2_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=./mod_proxy_http2.c
    
    "$(INTDIR)\mod_proxy_http2.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_switch.h��������������������������������������������������������������0000664�0001751�0001751�00000002123�13237611704�017400� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_switch__
    #define __mod_h2__h2_switch__
    
    /*
     * One time, post config initialization.
     */
    apr_status_t h2_switch_init(apr_pool_t *pool, server_rec *s);
    
    /* Register apache hooks for protocol switching
     */
    void h2_switch_register_hooks(void);
    
    
    #endif /* defined(__mod_h2__h2_switch__) */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_proxy_http2.dep������������������������������������������������������0000664�0001751�0001751�00000016553�12733263444�021210� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_http2.mak
    
    ./h2_proxy_session.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_proxy.h"\
    	"..\..\include\mpm_common.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\..\srclib\nghttp2\lib\includes\nghttp2\nghttp2.h"\
    	"..\..\srclib\nghttp2\lib\includes\nghttp2\nghttp2ver.h"\
    	".\h2.h"\
    	".\h2_proxy_session.h"\
    	".\h2_proxy_util.h"\
    	".\mod_http2.h"\
    	
    
    ./h2_proxy_util.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\..\srclib\nghttp2\lib\includes\nghttp2\nghttp2.h"\
    	"..\..\srclib\nghttp2\lib\includes\nghttp2\nghttp2ver.h"\
    	".\h2.h"\
    	".\h2_proxy_util.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    ./mod_proxy_http2.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_proxy.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\..\srclib\nghttp2\lib\includes\nghttp2\nghttp2.h"\
    	"..\..\srclib\nghttp2\lib\includes\nghttp2\nghttp2ver.h"\
    	".\h2.h"\
    	".\h2_proxy_session.h"\
    	".\h2_request.h"\
    	".\h2_proxy_util.h"\
    	".\h2_version.h"\
    	".\mod_http2.h"\
    	".\mod_proxy_http2.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/Makefile.in��������������������������������������������������������������0000664�0001751�0001751�00000001515�12573345517�017416� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_request.h�������������������������������������������������������������0000664�0001751�0001751�00000005112�15032734701�017566� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_request__
    #define __mod_h2__h2_request__
    
    #include "h2.h"
    
    struct h2_hd_scratch;
    
    h2_request *h2_request_create(int id, apr_pool_t *pool, const char *method,
                                  const char *scheme, const char *authority,
                                  const char *path, apr_table_t *header);
    
    apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
                                    request_rec *r,
                                    struct h2_hd_scratch *scratch);
    
    apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
                                       const char *name, size_t nlen,
                                       const char *value, size_t vlen,
                                       struct h2_hd_scratch *scratch,
                                       int *pwas_added);
    
    apr_status_t h2_request_add_trailer(h2_request *req, apr_pool_t *pool,
                                        const char *name, size_t nlen,
                                        const char *value, size_t vlen);
    
    apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool,
                                         size_t raw_bytes);
    
    h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src);
    
    /**
     * Create a request_rec representing the h2_request to be
     * processed on the given connection.
     *
     * @param req the h2 request to process
     * @param conn the connection to process the request on
     * @param no_body != 0 iff the request is known to have no body
     * @return the request_rec representing the request
     */
    request_rec *h2_create_request_rec(const h2_request *req, conn_rec *conn,
                                       int no_body);
    
    #if AP_HAS_RESPONSE_BUCKETS
    apr_bucket *h2_request_create_bucket(const h2_request *req, request_rec *r);
    #endif
    
    #endif /* defined(__mod_h2__h2_request__) */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_session.h�������������������������������������������������������������0000664�0001751�0001751�00000021300�15032734701�017556� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_session__
    #define __mod_h2__h2_session__
    
    #include "h2_c1_io.h"
    
    /**
     * A HTTP/2 connection, a session with a specific client.
     * 
     * h2_session sits on top of a httpd conn_rec* instance and takes complete
     * control of the connection data. It receives protocol frames from the
     * client. For new HTTP/2 streams it creates secondary connections
     * to execute the requests in h2 workers.
     */
    
    #include "h2.h"
    #include "h2_util.h"
    
    struct apr_thread_mutext_t;
    struct apr_thread_cond_t;
    struct h2_ctx;
    struct h2_config;
    struct h2_ihash_t;
    struct h2_mplx;
    struct h2_priority;
    struct h2_push;
    struct h2_push_diary;
    struct h2_session;
    struct h2_stream;
    struct h2_stream_monitor;
    struct h2_workers;
    
    struct nghttp2_session;
    
    typedef enum {
        H2_SESSION_EV_INIT,             /* session was initialized */
        H2_SESSION_EV_INPUT_PENDING,    /* c1 input may have data pending */
        H2_SESSION_EV_INPUT_EXHAUSTED,  /* c1 input exhausted */
        H2_SESSION_EV_LOCAL_GOAWAY,     /* we send a GOAWAY */
        H2_SESSION_EV_REMOTE_GOAWAY,    /* remote send us a GOAWAY */
        H2_SESSION_EV_CONN_ERROR,       /* connection error */
        H2_SESSION_EV_PROTO_ERROR,      /* protocol error */
        H2_SESSION_EV_CONN_TIMEOUT,     /* connection timeout */
        H2_SESSION_EV_NGH2_DONE,        /* nghttp2 wants neither read nor write anything */
        H2_SESSION_EV_MPM_STOPPING,     /* the process is stopping */
        H2_SESSION_EV_PRE_CLOSE,        /* connection will close after this */
        H2_SESSION_EV_NO_MORE_STREAMS,  /* no more streams to process */
    } h2_session_event_t;
    
    typedef struct h2_session {
        int child_num;                  /* child number this session runs in */
        apr_uint32_t id;                /* identifier of this session, unique per child */
        conn_rec *c1;                   /* the main connection this session serves */
        request_rec *r;                 /* the request that started this in case
                                         * of 'h2c', NULL otherwise */
        server_rec *s;                  /* server/vhost we're starting on */
        apr_pool_t *pool;               /* pool to use in session */
        struct h2_mplx *mplx;           /* multiplexer for stream data */
        struct h2_workers *workers;     /* for executing streams */
        struct h2_c1_io_in_ctx_t *cin;  /* connection input filter context */
        h2_c1_io io;                    /* io on httpd conn filters */
        unsigned int padding_max;       /* max number of padding bytes */
        int padding_always;             /* padding has precedence over I/O optimizations */
        struct nghttp2_session *ngh2;   /* the nghttp2 session (internal use) */
    
        h2_session_state state;         /* state session is in */
        
        h2_session_props local;         /* properties of local session */
        h2_session_props remote;        /* properites of remote session */
        
        unsigned int reprioritize  : 1; /* scheduled streams priority changed */
        unsigned int flush         : 1; /* flushing output necessary */
        apr_interval_time_t  wait_us;   /* timeout during BUSY_WAIT state, micro secs */
        
        struct h2_push_diary *push_diary; /* remember pushes, avoid duplicates */
        
        struct h2_stream_monitor *monitor;/* monitor callbacks for streams */
        unsigned int open_streams;      /* number of streams processing */
    
        unsigned int streams_done;      /* number of http/2 streams handled */
        unsigned int responses_submitted; /* number of http/2 responses submitted */
        unsigned int streams_reset;     /* number of http/2 streams reset by client */
        unsigned int pushes_promised;   /* number of http/2 push promises submitted */
        unsigned int pushes_submitted;  /* number of http/2 pushed responses submitted */
        unsigned int pushes_reset;      /* number of http/2 pushed reset by client */
        
        apr_size_t frames_received;     /* number of http/2 frames received */
        apr_size_t frames_sent;         /* number of http/2 frames sent */
        
        apr_size_t max_stream_count;    /* max number of open streams */
        apr_size_t max_stream_mem;      /* max buffer memory for a single stream */
        apr_size_t max_data_frame_len;  /* max amount of bytes for a single DATA frame */
    
        apr_size_t idle_frames;         /* number of rcvd frames that kept session in idle state */
        apr_interval_time_t idle_delay; /* Time we delay processing rcvd frames in idle state */
        
        apr_bucket_brigade *bbtmp;      /* brigade for keeping temporary data */
    
        char status[64];                /* status message for scoreboard */
        int last_status_code;           /* the one already reported */
        const char *last_status_msg;    /* the one already reported */
    
        int input_flushed;              /* stream input was flushed */
        struct h2_iqueue *out_c1_blocked;  /* all streams with output blocked on c1 buffer full */
        struct h2_iqueue *ready_to_process;  /* all streams ready for processing */
    
        h2_hd_scratch hd_scratch;
    
    } h2_session;
    
    const char *h2_session_state_str(h2_session_state state);
    
    /**
     * Create a new h2_session for the given connection.
     * The session will apply the configured parameter.
     * @param psession pointer receiving the created session on success or NULL
     * @param c       the connection to work on
     * @param r       optional request when protocol was upgraded
     * @param cfg     the module config to apply
     * @param workers the worker pool to use
     * @return the created session
     */
    apr_status_t h2_session_create(h2_session **psession,
                                   conn_rec *c, request_rec *r, server_rec *, 
                                   struct h2_workers *workers);
    
    void h2_session_event(h2_session *session, h2_session_event_t ev, 
                          int err, const char *msg);
    
    /**
     * Process the given HTTP/2 session until it is ended or a fatal
     * error occurred.
     *
     * @param session the sessionm to process
     * @param async if mpm is async
     * @param pkeepalive on return, != 0 if connection to be put into keepalive
     *                   behaviour and timouts
     */
    apr_status_t h2_session_process(h2_session *session, int async, int *pkeepalive);
    
    /**
     * Last chance to do anything before the connection is closed.
     */
    apr_status_t h2_session_pre_close(h2_session *session, int async);
    
    /**
     * Called when a serious error occurred and the session needs to terminate
     * without further connection io.
     * @param session the session to abort
     * @param reason  the apache status that caused the abort
     */
    void h2_session_abort(h2_session *session, apr_status_t reason);
    
    /**
     * Returns if client settings have push enabled.
     * @param != 0 iff push is enabled in client settings
     */
    int h2_session_push_enabled(h2_session *session);
    
    /**
     * Submit a push promise on the stream and schedule the new steam for
     * processing..
     * 
     * @param session the session to work in
     * @param is the stream initiating the push
     * @param push the push to promise
     * @return the new promised stream or NULL
     */
    struct h2_stream *h2_session_push(h2_session *session, 
                                      struct h2_stream *is, struct h2_push *push);
    
    apr_status_t h2_session_set_prio(h2_session *session, 
                                     struct h2_stream *stream, 
                                     const struct h2_priority *prio);
    
    /**
     * Dispatch a event happending during session processing.
     * @param session the sessiont
     * @param ev the event that happened
     * @param arg integer argument (event type dependant)
     * @param msg destriptive message
     */
    void h2_session_dispatch_event(h2_session *session, h2_session_event_t ev,
                                   int arg, const char *msg);
    
    
    #define H2_SSSN_MSG(s, msg)     \
        "h2_session(%d-%lu,%s,%d): "msg, s->child_num, (unsigned long)s->id, \
                                h2_session_state_str(s->state), \
                                s->open_streams
    
    #define H2_SSSN_LOG(aplogno, s, msg)    aplogno H2_SSSN_MSG(s, msg)
    
    #define H2_SSSN_STRM_MSG(s, stream_id, msg)     \
        "h2_stream(%d-%lu-%d): "msg, s->child_num, (unsigned long)s->id, stream_id
    
    #endif /* defined(__mod_h2__h2_session__) */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_request.c�������������������������������������������������������������0000664�0001751�0001751�00000052645�15032734701�017576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_lib.h"
    #include "apr_strmatch.h"
    
    #include <ap_mmn.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    #include <http_ssl.h>
    #include <http_vhost.h>
    #include <util_filter.h>
    #include <ap_mpm.h>
    #include <mod_core.h>
    #include <scoreboard.h>
    
    #include "h2_private.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_push.h"
    #include "h2_request.h"
    #include "h2_util.h"
    
    
    h2_request *h2_request_create(int id, apr_pool_t *pool, const char *method,
                                  const char *scheme, const char *authority,
                                  const char *path, apr_table_t *header)
    {
        h2_request *req = apr_pcalloc(pool, sizeof(h2_request));
    
        req->method         = method;
        req->scheme         = scheme;
        req->authority      = authority;
        req->path           = path;
        req->headers        = header? header : apr_table_make(pool, 10);
        req->request_time   = apr_time_now();
    
        return req;
    }
    
    typedef struct {
        apr_table_t *headers;
        apr_pool_t *pool;
        apr_status_t status;
        h2_hd_scratch *scratch;
    } h1_ctx;
    
    static int set_h1_header(void *ctx, const char *key, const char *value)
    {
        h1_ctx *x = ctx;
        int was_added;
        h2_req_add_header(x->headers, x->pool, key, strlen(key),
                          value, strlen(value), x->scratch, &was_added);
        return 1;
    }
    
    apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool, 
                                    request_rec *r, h2_hd_scratch *scratch)
    {
        h2_request *req;
        const char *scheme, *authority, *path;
        h1_ctx x;
        
        *preq = NULL;
        scheme = apr_pstrdup(pool, r->parsed_uri.scheme? r->parsed_uri.scheme
                  : ap_http_scheme(r));
        authority = apr_pstrdup(pool, r->hostname);
        path = apr_uri_unparse(pool, &r->parsed_uri, APR_URI_UNP_OMITSITEPART);
        
        if (!r->method || !scheme || !r->hostname || !path) {
            return APR_EINVAL;
        }
    
        /* The authority we carry in h2_request is the 'authority' part of
         * the URL for the request. r->hostname has stripped any port info that
         * might have been present. Do we need to add it?
         */
        if (!ap_strchr_c(authority, ':')) {
            if (r->parsed_uri.port_str) {
                /* Yes, it was there, add it again. */
                authority = apr_pstrcat(pool, authority, ":", r->parsed_uri.port_str, NULL);
            }
            else if (!r->parsed_uri.hostname && r->server && r->server->port) {
                /* If there was no hostname in the parsed URL, the URL was relative.
                 * In that case, we restore port from our server->port, if it
                 * is known and not the default port for the scheme. */
                apr_port_t defport = apr_uri_port_of_scheme(scheme);
                if (defport != r->server->port) {
                    /* port info missing and port is not default for scheme: append */
                    authority = apr_psprintf(pool, "%s:%d", authority,
                                             (int)r->server->port);
                }
            }
        }
    
        req = apr_pcalloc(pool, sizeof(*req));
        req->method      = apr_pstrdup(pool, r->method);
        req->scheme      = scheme;
        req->authority   = authority;
        req->path        = path;
        req->headers     = apr_table_make(pool, 10);
        req->http_status = H2_HTTP_STATUS_UNSET;
        req->request_time = apr_time_now();
    
        x.pool = pool;
        x.headers = req->headers;
        x.status = APR_SUCCESS;
        x.scratch = scratch;
        apr_table_do(set_h1_header, &x, r->headers_in, NULL);
    
        *preq = req;
        return x.status;
    }
    
    apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
                                       const char *name, size_t nlen,
                                       const char *value, size_t vlen,
                                       struct h2_hd_scratch *scratch,
                                       int *pwas_added)
    {
        apr_status_t status = APR_SUCCESS;
    
        *pwas_added = 0;
        if (nlen <= 0) {
            return status;
        }
    
        if (name[0] == ':') {
            /* pseudo header, see ch. 8.1.2.3, always should come first */
            if (!apr_is_empty_table(req->headers)) {
                ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool,
                              APLOGNO(02917)
                              "h2_request: pseudo header after request start");
                return APR_EGENERAL;
            }
    
            if (H2_HEADER_METHOD_LEN == nlen
                && !strncmp(H2_HEADER_METHOD, name, nlen)) {
                req->method = apr_pstrndup(pool, value, vlen);
            }
            else if (H2_HEADER_SCHEME_LEN == nlen
                     && !strncmp(H2_HEADER_SCHEME, name, nlen)) {
                req->scheme = apr_pstrndup(pool, value, vlen);
            }
            else if (H2_HEADER_PATH_LEN == nlen
                     && !strncmp(H2_HEADER_PATH, name, nlen)) {
                req->path = apr_pstrndup(pool, value, vlen);
            }
            else if (H2_HEADER_AUTH_LEN == nlen
                     && !strncmp(H2_HEADER_AUTH, name, nlen)) {
                req->authority = apr_pstrndup(pool, value, vlen);
            }
            else if (H2_HEADER_PROTO_LEN == nlen
                     && !strncmp(H2_HEADER_PROTO, name, nlen)) {
                req->protocol = apr_pstrndup(pool, value, vlen);
            }
            else {
                char buffer[32];
                memset(buffer, 0, 32);
                strncpy(buffer, name, (nlen > 31)? 31 : nlen);
                ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, pool,
                              APLOGNO(02954)
                              "h2_request: ignoring unknown pseudo header %s",
                              buffer);
            }
        }
        else {
            /* non-pseudo header, add to table */
            status = h2_req_add_header(req->headers, pool, name, nlen, value, vlen,
                                       scratch, pwas_added);
        }
    
        return status;
    }
    
    apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool,
                                        size_t raw_bytes)
    {
        /* rfc7540, ch. 8.1.2.3: without :authority, Host: must be there */
        if (req->authority && !strlen(req->authority)) {
            req->authority = NULL;
        }
        if (!req->authority) {
            const char *host = apr_table_get(req->headers, "Host");
            if (!host) {
                return APR_BADARG;
            }
            req->authority = host;
        }
        else {
            apr_table_setn(req->headers, "Host", req->authority);
        }
        req->raw_bytes += raw_bytes;
    
        return APR_SUCCESS;
    }
    
    h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src)
    {
        h2_request *dst = apr_pmemdup(p, src, sizeof(*dst));
        dst->method       = apr_pstrdup(p, src->method);
        dst->scheme       = apr_pstrdup(p, src->scheme);
        dst->authority    = apr_pstrdup(p, src->authority);
        dst->path         = apr_pstrdup(p, src->path);
        dst->protocol     = apr_pstrdup(p, src->protocol);
        dst->headers      = apr_table_clone(p, src->headers);
        return dst;
    }
    
    #if !AP_MODULE_MAGIC_AT_LEAST(20120211, 106)
    static request_rec *my_ap_create_request(conn_rec *c)
    {
        apr_pool_t *p;
        request_rec *r;
    
        apr_pool_create(&p, c->pool);
        apr_pool_tag(p, "request");
        r = apr_pcalloc(p, sizeof(request_rec));
        AP_READ_REQUEST_ENTRY((intptr_t)r, (uintptr_t)c);
        r->pool            = p;
        r->connection      = c;
        r->server          = c->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, 5);
        r->trailers_in     = apr_table_make(r->pool, 5);
        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->trailers_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 = c->output_filters;
        r->output_filters  = r->proto_output_filters;
        r->proto_input_filters = c->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_OK;  /* Until further notice */
        r->header_only     = 0;
        r->the_request     = NULL;
    
        /* 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;
    
        r->useragent_addr = c->client_addr;
        r->useragent_ip = c->client_ip;
        return r;
    }
    #endif
    
    #if AP_HAS_RESPONSE_BUCKETS
    apr_bucket *h2_request_create_bucket(const h2_request *req, request_rec *r)
    {
        conn_rec *c = r->connection;
        apr_table_t *headers = apr_table_clone(r->pool, req->headers);
        const char *uri = req->path;
    
        AP_DEBUG_ASSERT(req->method);
        AP_DEBUG_ASSERT(req->authority);
        if (!ap_cstr_casecmp("CONNECT", req->method))  {
            uri = req->authority;
        }
        else if (h2_config_cgeti(c, H2_CONF_PROXY_REQUESTS)) {
            /* Forward proxying: always absolute uris */
            uri = apr_psprintf(r->pool, "%s://%s%s",
                               req->scheme, req->authority,
                               req->path ? req->path : "");
        }
        else if (req->scheme && ap_cstr_casecmp(req->scheme, "http")
                 && ap_cstr_casecmp(req->scheme, "https")) {
            /* Client sent a non-http ':scheme', use an absolute URI */
            uri = apr_psprintf(r->pool, "%s://%s%s",
                               req->scheme, req->authority, req->path ? req->path : "");
        }
    
        return ap_bucket_request_create(req->method, uri, "HTTP/2.0", headers,
                                        r->pool, c->bucket_alloc);
    }
    #endif
    
    static void assign_headers(request_rec *r, const h2_request *req,
                               int no_body, int is_connect)
    {
        const char *cl;
    
        r->headers_in = apr_table_clone(r->pool, req->headers);
    
        if (req->authority && !is_connect) {
            /* for internal handling, we have to simulate that :authority
             * came in as Host:, RFC 9113 ch. says that mismatches between
             * :authority and Host: SHOULD be rejected as malformed. However,
             * we are more lenient and just replace any Host: if we have
             * an :authority.
             */
            const char *orig_host = apr_table_get(req->headers, "Host");
            if (orig_host && strcmp(req->authority, orig_host)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10401)
                              "overwriting 'Host: %s' with :authority: %s'",
                              orig_host, req->authority);
                apr_table_setn(r->subprocess_env, "H2_ORIGINAL_HOST", orig_host);
            }
            apr_table_setn(r->headers_in, "Host", req->authority);
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "set 'Host: %s' from :authority", req->authority);
        }
    
        /* Unless we open a byte stream via CONNECT, apply content-length guards. */
        if (!is_connect) {
            cl = apr_table_get(req->headers, "Content-Length");
            if (no_body) {
                if (!cl && apr_table_get(req->headers, "Content-Type")) {
                    /* If we have a content-type, but already seen eos, no more
                     * data will come. Signal a zero content length explicitly.
                     */
                    apr_table_setn(req->headers, "Content-Length", "0");
                }
            }
    #if !AP_HAS_RESPONSE_BUCKETS
            else if (!cl) {
                /* there may be a body and we have internal HTTP/1.1 processing.
                 * If the Content-Length is unspecified, we MUST simulate
                 * chunked Transfer-Encoding.
                 *
                 * HTTP/2 does not need a Content-Length for framing. Ideally
                 * all clients set the EOS flag on the header frame if they
                 * do not intent to send a body. However, forwarding proxies
                 * might just no know at the time and send an empty DATA
                 * frame with EOS much later.
                 */
                apr_table_mergen(r->headers_in, "Transfer-Encoding", "chunked");
            }
    #endif /* else AP_HAS_RESPONSE_BUCKETS */
      }
    }
    
    request_rec *h2_create_request_rec(const h2_request *req, conn_rec *c,
                                       int no_body)
    {
        int access_status = HTTP_OK;
        int is_connect = !ap_cstr_casecmp("CONNECT", req->method);
    
    #if AP_MODULE_MAGIC_AT_LEAST(20120211, 106)
        request_rec *r = ap_create_request(c);
    #else
        request_rec *r = my_ap_create_request(c);
    #endif
    
    #if AP_MODULE_MAGIC_AT_LEAST(20120211, 107)
        assign_headers(r, req, no_body, is_connect);
        ap_run_pre_read_request(r, c);
    
        /* Time to populate r with the data we have. */
        r->request_time = req->request_time;
        AP_DEBUG_ASSERT(req->authority);
        if (req->http_status != H2_HTTP_STATUS_UNSET) {
            access_status = req->http_status;
            goto die;
        }
        else if (is_connect) {
          /* CONNECT MUST NOT have scheme or path */
            r->the_request = apr_psprintf(r->pool, "%s %s HTTP/2.0",
                                          req->method, req->authority);
            if (req->scheme) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10458)
                              "':scheme: %s' header present in CONNECT request",
                              req->scheme);
                access_status = HTTP_BAD_REQUEST;
                goto die;
            }
            else if (req->path) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10459)
                              "':path: %s' header present in CONNECT request",
                              req->path);
                access_status = HTTP_BAD_REQUEST;
                goto die;
            }
        }
        else if (req->protocol) {
          ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10470)
                        "':protocol: %s' header present in %s request",
                        req->protocol, req->method);
          access_status = HTTP_BAD_REQUEST;
          goto die;
        }
        else if (h2_config_cgeti(c, H2_CONF_PROXY_REQUESTS)) {
            if (!req->scheme) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10468)
                              "H2ProxyRequests on, but request misses :scheme");
                access_status = HTTP_BAD_REQUEST;
                goto die;
            }
            if (!req->authority) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10469)
                              "H2ProxyRequests on, but request misses :authority");
                access_status = HTTP_BAD_REQUEST;
                goto die;
            }
            r->the_request = apr_psprintf(r->pool, "%s %s://%s%s HTTP/2.0",
                                          req->method, req->scheme, req->authority,
                                          req->path ? req->path : "");
        }
        else if (req->scheme && ap_cstr_casecmp(req->scheme, "http")
                 && ap_cstr_casecmp(req->scheme, "https")) {
            /* Client sent a ':scheme' pseudo header for something else
             * than what we have on this connection. Make an absolute URI. */
            r->the_request = apr_psprintf(r->pool, "%s %s://%s%s HTTP/2.0",
                                          req->method, req->scheme, req->authority,
                                          req->path ? req->path : "");
        }
        else if (req->path) {
            r->the_request = apr_psprintf(r->pool, "%s %s HTTP/2.0",
                                          req->method, req->path);
        }
        else {
            /* We should only come here on a request that is errored already.
             * create a request line that passes parsing, we'll die anyway.
             */
            AP_DEBUG_ASSERT(req->http_status != H2_HTTP_STATUS_UNSET);
            r->the_request = apr_psprintf(r->pool, "%s / HTTP/2.0", req->method);
        }
    
        /* Start with r->hostname = NULL, ap_check_request_header() will get it
         * form Host: header, otherwise we get complains about port numbers.
         */
        r->hostname = NULL;
    
        /* Validate HTTP/1 request and select vhost. */
        if (!ap_parse_request_line(r) || !ap_check_request_header(r)) {
            /* we may have switched to another server still */
            r->per_dir_config = r->server->lookup_defaults;
            if (req->http_status != H2_HTTP_STATUS_UNSET) {
                access_status = req->http_status;
                /* Be safe and close the connection */
                c->keepalive = AP_CONN_CLOSE;
            }
            else {
                access_status = r->status;
            }
            r->status = HTTP_OK;
            goto die;
        }
    #else
        {
            const char *s;
    
            assign_headers(r, req, no_body, is_connect);
            ap_run_pre_read_request(r, c);
    
            /* Time to populate r with the data we have. */
            r->request_time = req->request_time;
            r->method = apr_pstrdup(r->pool, req->method);
            /* 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, req->path ? req->path : "");
            r->protocol = (char*)"HTTP/2.0";
            r->proto_num = HTTP_VERSION(2, 0);
            r->the_request = apr_psprintf(r->pool, "%s %s HTTP/2.0",
                                          r->method, req->path ? req->path : "");
    
            /* Start with r->hostname = NULL, ap_check_request_header() will get it
             * form Host: header, otherwise we get complains about port numbers.
             */
            r->hostname = NULL;
            ap_update_vhost_from_headers(r);
    
             /* we may have switched to another server */
             r->per_dir_config = r->server->lookup_defaults;
    
             s = apr_table_get(r->headers_in, "Expect");
             if (s && s[0]) {
                if (ap_cstr_casecmp(s, "100-continue") == 0) {
                    r->expecting_100 = 1;
                }
                else {
                    r->status = HTTP_EXPECTATION_FAILED;
                    access_status = r->status;
                    goto die;
                }
             }
        }
    #endif
    
        /* we may have switched to another server */
        r->per_dir_config = r->server->lookup_defaults;
    
        if (req->http_status != H2_HTTP_STATUS_UNSET) {
            access_status = req->http_status;
            r->status = HTTP_OK;
            /* Be safe and close the connection */
            c->keepalive = AP_CONN_CLOSE;
            goto die;
        }
    
        /*
         * Add the HTTP_IN filter here to ensure that ap_discard_request_body
         * called by ap_die and by ap_send_error_response works correctly on
         * status codes that do not cause the connection to be dropped and
         * in situations where the connection should be kept alive.
         */
        ap_add_input_filter_handle(ap_http_input_filter_handle,
                                   NULL, r, r->connection);
    
        if ((access_status = ap_post_read_request(r))) {
            /* Request check post hooks failed. An example of this would be a
             * request for a vhost where h2 is disabled --> 421.
             */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03367)
                          "h2_request: access_status=%d, request_create failed",
                          access_status);
            goto die;
        }
    
        AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method,
                                (char *)r->uri, (char *)r->server->defn_name,
                                r->status);
        return r;
    
    die:
        if (!r->method) {
            /* if we fail early, `r` is not properly initialized for error
             * processing which accesses fields in message generation.
             * Make a best effort. */
            if (!r->the_request) {
                    r->the_request = apr_psprintf(r->pool, "%s %s HTTP/2.0",
                                          req->method, req->path);
            }
            ap_parse_request_line(r);
        }
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "ap_die(%d) for %s", access_status, r->the_request);
        ap_die(access_status, r);
    
        /* ap_die() sent the response through the output filters, we must now
         * end the request with an EOR bucket for stream/pipeline accounting.
         */
        {
            apr_bucket_brigade *eor_bb;
    #if AP_MODULE_MAGIC_AT_LEAST(20180905, 1)
            eor_bb = ap_acquire_brigade(c);
            APR_BRIGADE_INSERT_TAIL(eor_bb,
                                    ap_bucket_eor_create(c->bucket_alloc, r));
            ap_pass_brigade(c->output_filters, eor_bb);
            ap_release_brigade(c, eor_bb);
    #else
            eor_bb = apr_brigade_create(c->pool, c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(eor_bb,
                                    ap_bucket_eor_create(c->bucket_alloc, r));
            ap_pass_brigade(c->output_filters, eor_bb);
            apr_brigade_destroy(eor_bb);
    #endif
        }
    
        r = NULL;
        AP_READ_REQUEST_FAILURE((uintptr_t)r);
        return NULL;
    }
    �������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_util.c����������������������������������������������������������������0000664�0001751�0001751�00000152555�15032734701�017064� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_strings.h>
    #include <apr_thread_mutex.h>
    #include <apr_thread_cond.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <http_protocol.h>
    #include <http_request.h>
    
    #include <nghttp2/nghttp2.h>
    
    #include "h2.h"
    #include "h2_headers.h"
    #include "h2_util.h"
    
    /* h2_log2(n) iff n is a power of 2 */
    unsigned char h2_log2(int n)
    {
        int lz = 0;
        if (!n) {
            return 0;
        }
        if (!(n & 0xffff0000u)) {
            lz += 16;
            n = (n << 16);
        }
        if (!(n & 0xff000000u)) {
            lz += 8;
            n = (n << 8);
        }
        if (!(n & 0xf0000000u)) {
            lz += 4;
            n = (n << 4);
        }
        if (!(n & 0xc0000000u)) {
            lz += 2;
            n = (n << 2);
        }
        if (!(n & 0x80000000u)) {
            lz += 1;
        }
    
        return 31 - lz;
    }
    
    size_t h2_util_hex_dump(char *buffer, size_t maxlen,
                            const char *data, size_t datalen)
    {
        size_t offset = 0;
        size_t maxoffset = (maxlen-4);
        size_t i;
        for (i = 0; i < datalen && offset < maxoffset; ++i) {
            const char *sep = (i && i % 16 == 0)? "\n" : " ";
            int n = apr_snprintf(buffer+offset, maxoffset-offset,
                                 "%2x%s", ((unsigned int)data[i]&0xff), sep);
            offset += n;
        }
        strcpy(buffer+offset, (i<datalen)? "..." : "");
        return strlen(buffer);
    }
    
    void h2_util_camel_case_header(char *s, size_t len)
    {
        size_t start = 1;
        size_t i;
        for (i = 0; i < len; ++i) {
            if (start) {
                if (s[i] >= 'a' && s[i] <= 'z') {
                    s[i] -= 'a' - 'A';
                }
    
                start = 0;
            }
            else if (s[i] == '-') {
                start = 1;
            }
        }
    }
    
    /* base64 url encoding */
    
    #define N6 (unsigned int)-1
    
    static const unsigned int BASE64URL_UINT6[] = {
    /*   0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f        */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  0 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  1 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, 62, N6, N6, /*  2 */
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, N6, N6, N6, N6, N6, N6, /*  3 */
        N6, 0,  1,  2,  3,  4,  5,  6,   7,  8,  9, 10, 11, 12, 13, 14, /*  4 */
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, N6, N6, N6, N6, 63, /*  5 */
        N6, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /*  6 */
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, N6, N6, N6, N6, N6, /*  7 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  8 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  9 */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  a */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  b */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  c */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  d */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, /*  e */
        N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6, N6  /*  f */
    };
    static const unsigned char BASE64URL_CHARS[] = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /*  0 -  9 */
        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10 - 19 */
        'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20 - 29 */
        'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30 - 39 */
        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40 - 49 */
        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50 - 59 */
        '8', '9', '-', '_', ' ', ' ', ' ', ' ', ' ', ' ', /* 60 - 69 */
    };
    
    #define BASE64URL_CHAR(x)    BASE64URL_CHARS[ (unsigned int)(x) & 0x3fu ]
    
    apr_size_t h2_util_base64url_decode(const char **decoded, const char *encoded,
                                        apr_pool_t *pool)
    {
        const unsigned char *e = (const unsigned char *)encoded;
        const unsigned char *p = e;
        unsigned char *d;
        unsigned int n;
        long len, mlen, remain, i;
    
        while (*p && BASE64URL_UINT6[ *p ] != N6) {
            ++p;
        }
        len = (int)(p - e);
        mlen = (len/4)*4;
        *decoded = apr_pcalloc(pool, (apr_size_t)len + 1);
    
        i = 0;
        d = (unsigned char*)*decoded;
        for (; i < mlen; i += 4) {
            n = ((BASE64URL_UINT6[ e[i+0] ] << 18) +
                 (BASE64URL_UINT6[ e[i+1] ] << 12) +
                 (BASE64URL_UINT6[ e[i+2] ] << 6) +
                 (BASE64URL_UINT6[ e[i+3] ]));
            *d++ = (unsigned char)(n >> 16);
            *d++ = (unsigned char)(n >> 8 & 0xffu);
            *d++ = (unsigned char)(n & 0xffu);
        }
        remain = len - mlen;
        switch (remain) {
            case 2:
                n = ((BASE64URL_UINT6[ e[mlen+0] ] << 18) +
                     (BASE64URL_UINT6[ e[mlen+1] ] << 12));
                *d++ = (unsigned char)(n >> 16);
                remain = 1;
                break;
            case 3:
                n = ((BASE64URL_UINT6[ e[mlen+0] ] << 18) +
                     (BASE64URL_UINT6[ e[mlen+1] ] << 12) +
                     (BASE64URL_UINT6[ e[mlen+2] ] << 6));
                *d++ = (unsigned char)(n >> 16);
                *d++ = (unsigned char)(n >> 8 & 0xffu);
                remain = 2;
                break;
            default: /* do nothing */
                break;
        }
        return (apr_size_t)(mlen/4*3 + remain);
    }
    
    const char *h2_util_base64url_encode(const char *data,
                                         apr_size_t dlen, apr_pool_t *pool)
    {
        int i, len = (int)dlen;
        apr_size_t slen = ((dlen+2)/3)*4 + 1; /* 0 terminated */
        const unsigned char *udata = (const unsigned char*)data;
        unsigned char *enc, *p = apr_pcalloc(pool, slen);
    
        enc = p;
        for (i = 0; i < len-2; i+= 3) {
            *p++ = BASE64URL_CHAR( (udata[i]   >> 2) );
            *p++ = BASE64URL_CHAR( (udata[i]   << 4) + (udata[i+1] >> 4) );
            *p++ = BASE64URL_CHAR( (udata[i+1] << 2) + (udata[i+2] >> 6) );
            *p++ = BASE64URL_CHAR( (udata[i+2]) );
        }
    
        if (i < len) {
            *p++ = BASE64URL_CHAR( (udata[i] >> 2) );
            if (i == (len - 1)) {
                *p++ = BASE64URL_CHARS[ ((unsigned int)udata[i] << 4) & 0x3fu ];
            }
            else {
                *p++ = BASE64URL_CHAR( (udata[i] << 4) + (udata[i+1] >> 4) );
                *p++ = BASE64URL_CHAR( (udata[i+1] << 2) );
            }
        }
        *p++ = '\0';
        return (char *)enc;
    }
    
    /*******************************************************************************
     * ihash - hash for structs with int identifier
     ******************************************************************************/
    struct h2_ihash_t {
        apr_hash_t *hash;
        size_t ioff;
    };
    
    static unsigned int ihash(const char *key, apr_ssize_t *klen)
    {
        return (unsigned int)(*((int*)key));
    }
    
    h2_ihash_t *h2_ihash_create(apr_pool_t *pool, size_t offset_of_int)
    {
        h2_ihash_t *ih = apr_pcalloc(pool, sizeof(h2_ihash_t));
        ih->hash = apr_hash_make_custom(pool, ihash);
        ih->ioff = offset_of_int;
        return ih;
    }
    
    unsigned int h2_ihash_count(h2_ihash_t *ih)
    {
        return apr_hash_count(ih->hash);
    }
    
    int h2_ihash_empty(h2_ihash_t *ih)
    {
        return apr_hash_count(ih->hash) == 0;
    }
    
    void *h2_ihash_get(h2_ihash_t *ih, int id)
    {
        return apr_hash_get(ih->hash, &id, sizeof(id));
    }
    
    typedef struct {
        h2_ihash_iter_t *iter;
        void *ctx;
    } iter_ctx;
    
    static int ihash_iter(void *ctx, const void *key, apr_ssize_t klen,
                         const void *val)
    {
        iter_ctx *ictx = ctx;
        return ictx->iter(ictx->ctx, (void*)val); /* why is this passed const?*/
    }
    
    int h2_ihash_iter(h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx)
    {
        iter_ctx ictx;
        ictx.iter = fn;
        ictx.ctx = ctx;
        return apr_hash_do(ihash_iter, &ictx, ih->hash);
    }
    
    void h2_ihash_add(h2_ihash_t *ih, void *val)
    {
        apr_hash_set(ih->hash, ((char *)val + ih->ioff), sizeof(int), val);
    }
    
    void h2_ihash_remove(h2_ihash_t *ih, int id)
    {
        apr_hash_set(ih->hash, &id, sizeof(id), NULL);
    }
    
    void h2_ihash_remove_val(h2_ihash_t *ih, void *val)
    {
        int id = *((int*)((char *)val + ih->ioff));
        apr_hash_set(ih->hash, &id, sizeof(id), NULL);
    }
    
    
    void h2_ihash_clear(h2_ihash_t *ih)
    {
        apr_hash_clear(ih->hash);
    }
    
    typedef struct {
        h2_ihash_t *ih;
        void **buffer;
        size_t max;
        size_t len;
    } collect_ctx;
    
    static int collect_iter(void *x, void *val)
    {
        collect_ctx *ctx = x;
        if (ctx->len < ctx->max) {
            ctx->buffer[ctx->len++] = val;
            return 1;
        }
        return 0;
    }
    
    size_t h2_ihash_shift(h2_ihash_t *ih, void **buffer, size_t max)
    {
        collect_ctx ctx;
        size_t i;
    
        ctx.ih = ih;
        ctx.buffer = buffer;
        ctx.max = max;
        ctx.len = 0;
        h2_ihash_iter(ih, collect_iter, &ctx);
        for (i = 0; i < ctx.len; ++i) {
            h2_ihash_remove_val(ih, buffer[i]);
        }
        return ctx.len;
    }
    
    /*******************************************************************************
     * iqueue - sorted list of int
     ******************************************************************************/
    
    static void iq_grow(h2_iqueue *q, int nlen);
    static void iq_swap(h2_iqueue *q, int i, int j);
    static int iq_bubble_up(h2_iqueue *q, int i, int top,
                            h2_iq_cmp *cmp, void *ctx);
    static int iq_bubble_down(h2_iqueue *q, int i, int bottom,
                              h2_iq_cmp *cmp, void *ctx);
    
    h2_iqueue *h2_iq_create(apr_pool_t *pool, int capacity)
    {
        h2_iqueue *q = apr_pcalloc(pool, sizeof(h2_iqueue));
        q->pool = pool;
        iq_grow(q, capacity);
        q->nelts = 0;
        return q;
    }
    
    int h2_iq_empty(h2_iqueue *q)
    {
        return q->nelts == 0;
    }
    
    int h2_iq_count(h2_iqueue *q)
    {
        return q->nelts;
    }
    
    
    int h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx)
    {
        int i;
    
        if (h2_iq_contains(q, sid)) {
            return 0;
        }
        if (q->nelts >= q->nalloc) {
            iq_grow(q, q->nalloc * 2);
        }
        i = (q->head + q->nelts) % q->nalloc;
        q->elts[i] = sid;
        ++q->nelts;
    
        if (cmp) {
            /* bubble it to the front of the queue */
            iq_bubble_up(q, i, q->head, cmp, ctx);
        }
        return 1;
    }
    
    int h2_iq_append(h2_iqueue *q, int sid)
    {
        return h2_iq_add(q, sid, NULL, NULL);
    }
    
    int h2_iq_remove(h2_iqueue *q, int sid)
    {
        int i;
        for (i = 0; i < q->nelts; ++i) {
            if (sid == q->elts[(q->head + i) % q->nalloc]) {
                break;
            }
        }
    
        if (i < q->nelts) {
            ++i;
            for (; i < q->nelts; ++i) {
                q->elts[(q->head+i-1)%q->nalloc] = q->elts[(q->head+i)%q->nalloc];
            }
            --q->nelts;
            return 1;
        }
        return 0;
    }
    
    void h2_iq_clear(h2_iqueue *q)
    {
        q->nelts = 0;
    }
    
    void h2_iq_sort(h2_iqueue *q, h2_iq_cmp *cmp, void *ctx)
    {
        /* Assume that changes in ordering are minimal. This needs,
         * best case, q->nelts - 1 comparisons to check that nothing
         * changed.
         */
        if (q->nelts > 0) {
            int i, ni, prev, last;
    
            /* Start at the end of the queue and create a tail of sorted
             * entries. Make that tail one element longer in each iteration.
             */
            last = i = (q->head + q->nelts - 1) % q->nalloc;
            while (i != q->head) {
                prev = (q->nalloc + i - 1) % q->nalloc;
    
                ni = iq_bubble_up(q, i, prev, cmp, ctx);
                if (ni == prev) {
                    /* i bubbled one up, bubble the new i down, which
                     * keeps all ints below i sorted. */
                    iq_bubble_down(q, i, last, cmp, ctx);
                }
                i = prev;
            };
        }
    }
    
    
    int h2_iq_shift(h2_iqueue *q)
    {
        int sid;
    
        if (q->nelts <= 0) {
            return 0;
        }
    
        sid = q->elts[q->head];
        q->head = (q->head + 1) % q->nalloc;
        q->nelts--;
    
        return sid;
    }
    
    size_t h2_iq_mshift(h2_iqueue *q, int *pint, size_t max)
    {
        size_t i;
        for (i = 0; i < max; ++i) {
            pint[i] = h2_iq_shift(q);
            if (pint[i] == 0) {
                break;
            }
        }
        return i;
    }
    
    static void iq_grow(h2_iqueue *q, int nlen)
    {
        if (nlen > q->nalloc) {
            int *nq = apr_pcalloc(q->pool, sizeof(int) * nlen);
            if (q->nelts > 0) {
                int l = ((q->head + q->nelts) % q->nalloc) - q->head;
    
                memmove(nq, q->elts + q->head, sizeof(int) * l);
                if (l < q->nelts) {
                    /* elts wrapped, append elts in [0, remain] to nq */
                    int remain = q->nelts - l;
                    memmove(nq + l, q->elts, sizeof(int) * remain);
                }
            }
            q->elts = nq;
            q->nalloc = nlen;
            q->head = 0;
        }
    }
    
    static void iq_swap(h2_iqueue *q, int i, int j)
    {
        int x = q->elts[i];
        q->elts[i] = q->elts[j];
        q->elts[j] = x;
    }
    
    static int iq_bubble_up(h2_iqueue *q, int i, int top,
                            h2_iq_cmp *cmp, void *ctx)
    {
        int prev;
        while (((prev = (q->nalloc + i - 1) % q->nalloc), i != top)
               && (*cmp)(q->elts[i], q->elts[prev], ctx) < 0) {
            iq_swap(q, prev, i);
            i = prev;
        }
        return i;
    }
    
    static int iq_bubble_down(h2_iqueue *q, int i, int bottom,
                              h2_iq_cmp *cmp, void *ctx)
    {
        int next;
        while (((next = (q->nalloc + i + 1) % q->nalloc), i != bottom)
               && (*cmp)(q->elts[i], q->elts[next], ctx) > 0) {
            iq_swap(q, next, i);
            i = next;
        }
        return i;
    }
    
    int h2_iq_contains(h2_iqueue *q, int sid)
    {
        int i;
        for (i = 0; i < q->nelts; ++i) {
            if (sid == q->elts[(q->head + i) % q->nalloc]) {
                return 1;
            }
        }
        return 0;
    }
    
    /*******************************************************************************
     * FIFO queue
     ******************************************************************************/
    
    struct h2_fifo {
        void **elems;
        int capacity;
        int set;
        int in;
        int out;
        int count;
        int aborted;
        apr_thread_mutex_t *lock;
        apr_thread_cond_t  *not_empty;
        apr_thread_cond_t  *not_full;
    };
    
    static apr_status_t fifo_destroy(void *data)
    {
        h2_fifo *fifo = data;
    
        apr_thread_cond_destroy(fifo->not_empty);
        apr_thread_cond_destroy(fifo->not_full);
        apr_thread_mutex_destroy(fifo->lock);
    
        return APR_SUCCESS;
    }
    
    static int index_of(h2_fifo *fifo, void *elem)
    {
        int i;
    
        for (i = fifo->out; i != fifo->in; i = (i + 1) % fifo->capacity) {
            if (elem == fifo->elems[i]) {
                return i;
            }
        }
        return -1;
    }
    
    static apr_status_t create_int(h2_fifo **pfifo, apr_pool_t *pool,
                                   int capacity, int as_set)
    {
        apr_status_t rv;
        h2_fifo *fifo;
    
        fifo = apr_pcalloc(pool, sizeof(*fifo));
        if (fifo == NULL) {
            return APR_ENOMEM;
        }
    
        rv = apr_thread_mutex_create(&fifo->lock,
                                     APR_THREAD_MUTEX_UNNESTED, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_thread_cond_create(&fifo->not_empty, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_thread_cond_create(&fifo->not_full, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        fifo->elems = apr_pcalloc(pool, capacity * sizeof(void*));
        if (fifo->elems == NULL) {
            return APR_ENOMEM;
        }
        fifo->capacity = capacity;
        fifo->set = as_set;
    
        *pfifo = fifo;
        apr_pool_cleanup_register(pool, fifo, fifo_destroy, apr_pool_cleanup_null);
    
        return APR_SUCCESS;
    }
    
    apr_status_t h2_fifo_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity)
    {
        return create_int(pfifo, pool, capacity, 0);
    }
    
    apr_status_t h2_fifo_set_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity)
    {
        return create_int(pfifo, pool, capacity, 1);
    }
    
    apr_status_t h2_fifo_term(h2_fifo *fifo)
    {
        apr_status_t rv;
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            fifo->aborted = 1;
            apr_thread_cond_broadcast(fifo->not_empty);
            apr_thread_cond_broadcast(fifo->not_full);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    int h2_fifo_count(h2_fifo *fifo)
    {
        int n;
    
        apr_thread_mutex_lock(fifo->lock);
        n = fifo->count;
        apr_thread_mutex_unlock(fifo->lock);
        return n;
    }
    
    static apr_status_t check_not_empty(h2_fifo *fifo, int block)
    {
        while (fifo->count == 0) {
            if (!block) {
                return APR_EAGAIN;
            }
            if (fifo->aborted) {
                return APR_EOF;
            }
            apr_thread_cond_wait(fifo->not_empty, fifo->lock);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t fifo_push_int(h2_fifo *fifo, void *elem, int block)
    {
        if (fifo->aborted) {
            return APR_EOF;
        }
    
        if (fifo->set && index_of(fifo, elem) >= 0) {
            /* set mode, elem already member */
            return APR_EEXIST;
        }
        else if (fifo->count == fifo->capacity) {
            if (block) {
                while (fifo->count == fifo->capacity) {
                    if (fifo->aborted) {
                        return APR_EOF;
                    }
                    apr_thread_cond_wait(fifo->not_full, fifo->lock);
                }
            }
            else {
                return APR_EAGAIN;
            }
        }
    
        fifo->elems[fifo->in++] = elem;
        if (fifo->in >= fifo->capacity) {
            fifo->in -= fifo->capacity;
        }
        ++fifo->count;
        if (fifo->count == 1) {
            apr_thread_cond_signal(fifo->not_empty);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t fifo_push(h2_fifo *fifo, void *elem, int block)
    {
        apr_status_t rv;
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            rv = fifo_push_int(fifo, elem, block);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_fifo_push(h2_fifo *fifo, void *elem)
    {
        return fifo_push(fifo, elem, 1);
    }
    
    apr_status_t h2_fifo_try_push(h2_fifo *fifo, void *elem)
    {
        return fifo_push(fifo, elem, 0);
    }
    
    static apr_status_t pull_head(h2_fifo *fifo, void **pelem, int block)
    {
        apr_status_t rv;
        int was_full;
    
        if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
            *pelem = NULL;
            return rv;
        }
        *pelem = fifo->elems[fifo->out++];
        if (fifo->out >= fifo->capacity) {
            fifo->out -= fifo->capacity;
        }
        was_full = (fifo->count == fifo->capacity);
        --fifo->count;
        if (was_full) {
            apr_thread_cond_broadcast(fifo->not_full);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t fifo_pull(h2_fifo *fifo, void **pelem, int block)
    {
        apr_status_t rv;
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            rv = pull_head(fifo, pelem, block);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_fifo_pull(h2_fifo *fifo, void **pelem)
    {
        return fifo_pull(fifo, pelem, 1);
    }
    
    apr_status_t h2_fifo_try_pull(h2_fifo *fifo, void **pelem)
    {
        return fifo_pull(fifo, pelem, 0);
    }
    
    static apr_status_t fifo_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx, int block)
    {
        apr_status_t rv;
        void *elem;
    
        if (fifo->aborted) {
            return APR_EOF;
        }
    
        if (APR_SUCCESS == (rv = apr_thread_mutex_lock(fifo->lock))) {
            if (APR_SUCCESS == (rv = pull_head(fifo, &elem, block))) {
                switch (fn(elem, ctx)) {
                    case H2_FIFO_OP_PULL:
                        break;
                    case H2_FIFO_OP_REPUSH:
                        rv = fifo_push_int(fifo, elem, block);
                        break;
                }
            }
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_fifo_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx)
    {
        return fifo_peek(fifo, fn, ctx, 1);
    }
    
    apr_status_t h2_fifo_try_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx)
    {
        return fifo_peek(fifo, fn, ctx, 0);
    }
    
    apr_status_t h2_fifo_remove(h2_fifo *fifo, void *elem)
    {
        apr_status_t rv;
    
        if (fifo->aborted) {
            return APR_EOF;
        }
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            int i, last_count = fifo->count;
    
            for (i = fifo->out; i != fifo->in; i = (i + 1) % fifo->capacity) {
                if (fifo->elems[i] == elem) {
                    --fifo->count;
                    if (fifo->count == 0) {
                        fifo->out = fifo->in = 0;
                    }
                    else if (i == fifo->out) {
                        /* first element */
                        ++fifo->out;
                        if (fifo->out >= fifo->capacity) {
                            fifo->out -= fifo->capacity;
                        }
                    }
                    else if (((i + 1) % fifo->capacity) == fifo->in) {
                        /* last element */
                        --fifo->in;
                        if (fifo->in < 0) {
                            fifo->in += fifo->capacity;
                        }
                    }
                    else if (i > fifo->out) {
                        /* between out and in/capacity, move elements below up */
                        memmove(&fifo->elems[fifo->out+1], &fifo->elems[fifo->out],
                                (i - fifo->out) * sizeof(void*));
                        ++fifo->out;
                        if (fifo->out >= fifo->capacity) {
                            fifo->out -= fifo->capacity;
                        }
                    }
                    else {
                        /* we wrapped around, move elements above down */
                        AP_DEBUG_ASSERT((fifo->in - i - 1) > 0);
                        AP_DEBUG_ASSERT((fifo->in - i - 1) < fifo->capacity);
                        memmove(&fifo->elems[i], &fifo->elems[i + 1],
                                (fifo->in - i - 1) * sizeof(void*));
                        --fifo->in;
                        if (fifo->in < 0) {
                            fifo->in += fifo->capacity;
                        }
                    }
                }
            }
            if (fifo->count != last_count) {
                if (last_count == fifo->capacity) {
                    apr_thread_cond_broadcast(fifo->not_full);
                }
                rv = APR_SUCCESS;
            }
            else {
                rv = APR_EAGAIN;
            }
    
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    /*******************************************************************************
     * FIFO int queue
     ******************************************************************************/
    
    struct h2_ififo {
        int *elems;
        int capacity;
        int set;
        int head;
        int count;
        int aborted;
        apr_thread_mutex_t *lock;
        apr_thread_cond_t  *not_empty;
        apr_thread_cond_t  *not_full;
    };
    
    static int inth_index(h2_ififo *fifo, int n)
    {
        return (fifo->head + n) % fifo->capacity;
    }
    
    static apr_status_t ififo_destroy(void *data)
    {
        h2_ififo *fifo = data;
    
        apr_thread_cond_destroy(fifo->not_empty);
        apr_thread_cond_destroy(fifo->not_full);
        apr_thread_mutex_destroy(fifo->lock);
    
        return APR_SUCCESS;
    }
    
    static int iindex_of(h2_ififo *fifo, int id)
    {
        int i;
    
        for (i = 0; i < fifo->count; ++i) {
            if (id == fifo->elems[inth_index(fifo, i)]) {
                return i;
            }
        }
        return -1;
    }
    
    static apr_status_t icreate_int(h2_ififo **pfifo, apr_pool_t *pool,
                                    int capacity, int as_set)
    {
        apr_status_t rv;
        h2_ififo *fifo;
    
        fifo = apr_pcalloc(pool, sizeof(*fifo));
        if (fifo == NULL) {
            return APR_ENOMEM;
        }
    
        rv = apr_thread_mutex_create(&fifo->lock,
                                     APR_THREAD_MUTEX_UNNESTED, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_thread_cond_create(&fifo->not_empty, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_thread_cond_create(&fifo->not_full, pool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        fifo->elems = apr_pcalloc(pool, capacity * sizeof(int));
        if (fifo->elems == NULL) {
            return APR_ENOMEM;
        }
        fifo->capacity = capacity;
        fifo->set = as_set;
    
        *pfifo = fifo;
        apr_pool_cleanup_register(pool, fifo, ififo_destroy, apr_pool_cleanup_null);
    
        return APR_SUCCESS;
    }
    
    apr_status_t h2_ififo_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity)
    {
        return icreate_int(pfifo, pool, capacity, 0);
    }
    
    apr_status_t h2_ififo_set_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity)
    {
        return icreate_int(pfifo, pool, capacity, 1);
    }
    
    apr_status_t h2_ififo_term(h2_ififo *fifo)
    {
        apr_status_t rv;
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            fifo->aborted = 1;
            apr_thread_cond_broadcast(fifo->not_empty);
            apr_thread_cond_broadcast(fifo->not_full);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    int h2_ififo_count(h2_ififo *fifo)
    {
        return fifo->count;
    }
    
    static apr_status_t icheck_not_empty(h2_ififo *fifo, int block)
    {
        while (fifo->count == 0) {
            if (!block) {
                return APR_EAGAIN;
            }
            if (fifo->aborted) {
                return APR_EOF;
            }
            apr_thread_cond_wait(fifo->not_empty, fifo->lock);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t ififo_push_int(h2_ififo *fifo, int id, int block)
    {
        if (fifo->aborted) {
            return APR_EOF;
        }
    
        if (fifo->set && iindex_of(fifo, id) >= 0) {
            /* set mode, elem already member */
            return APR_EEXIST;
        }
        else if (fifo->count == fifo->capacity) {
            if (block) {
                while (fifo->count == fifo->capacity) {
                    if (fifo->aborted) {
                        return APR_EOF;
                    }
                    apr_thread_cond_wait(fifo->not_full, fifo->lock);
                }
            }
            else {
                return APR_EAGAIN;
            }
        }
    
        ap_assert(fifo->count < fifo->capacity);
        fifo->elems[inth_index(fifo, fifo->count)] = id;
        ++fifo->count;
        if (fifo->count == 1) {
            apr_thread_cond_broadcast(fifo->not_empty);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t ififo_push(h2_ififo *fifo, int id, int block)
    {
        apr_status_t rv;
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            rv = ififo_push_int(fifo, id, block);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_ififo_push(h2_ififo *fifo, int id)
    {
        return ififo_push(fifo, id, 1);
    }
    
    apr_status_t h2_ififo_try_push(h2_ififo *fifo, int id)
    {
        return ififo_push(fifo, id, 0);
    }
    
    static apr_status_t ipull_head(h2_ififo *fifo, int *pi, int block)
    {
        apr_status_t rv;
    
        if ((rv = icheck_not_empty(fifo, block)) != APR_SUCCESS) {
            *pi = 0;
            return rv;
        }
        *pi = fifo->elems[fifo->head];
        --fifo->count;
        if (fifo->count > 0) {
            fifo->head = inth_index(fifo, 1);
            if (fifo->count+1 == fifo->capacity) {
                apr_thread_cond_broadcast(fifo->not_full);
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t ififo_pull(h2_ififo *fifo, int *pi, int block)
    {
        apr_status_t rv;
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            rv = ipull_head(fifo, pi, block);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_ififo_pull(h2_ififo *fifo, int *pi)
    {
        return ififo_pull(fifo, pi, 1);
    }
    
    apr_status_t h2_ififo_try_pull(h2_ififo *fifo, int *pi)
    {
        return ififo_pull(fifo, pi, 0);
    }
    
    static apr_status_t ififo_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx, int block)
    {
        apr_status_t rv;
        int id;
    
        if (APR_SUCCESS == (rv = apr_thread_mutex_lock(fifo->lock))) {
            if (APR_SUCCESS == (rv = ipull_head(fifo, &id, block))) {
                switch (fn(id, ctx)) {
                    case H2_FIFO_OP_PULL:
                        break;
                    case H2_FIFO_OP_REPUSH:
                        rv = ififo_push_int(fifo, id, block);
                        break;
                }
            }
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    apr_status_t h2_ififo_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx)
    {
        return ififo_peek(fifo, fn, ctx, 1);
    }
    
    apr_status_t h2_ififo_try_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx)
    {
        return ififo_peek(fifo, fn, ctx, 0);
    }
    
    static apr_status_t ififo_remove(h2_ififo *fifo, int id)
    {
        int rc, i;
    
        if (fifo->aborted) {
            return APR_EOF;
        }
    
        rc = 0;
        for (i = 0; i < fifo->count; ++i) {
            int e = fifo->elems[inth_index(fifo, i)];
            if (e == id) {
                ++rc;
            }
            else if (rc) {
                fifo->elems[inth_index(fifo, i-rc)] = e;
            }
        }
        if (!rc) {
            return APR_EAGAIN;
        }
        fifo->count -= rc;
        if (fifo->count + rc == fifo->capacity) {
            apr_thread_cond_broadcast(fifo->not_full);
        }
        return APR_SUCCESS;
    }
    
    apr_status_t h2_ififo_remove(h2_ififo *fifo, int id)
    {
        apr_status_t rv;
    
        if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
            rv = ififo_remove(fifo, id);
            apr_thread_mutex_unlock(fifo->lock);
        }
        return rv;
    }
    
    /*******************************************************************************
     * h2_util for apt_table_t
     ******************************************************************************/
    
    typedef struct {
        apr_size_t bytes;
        apr_size_t pair_extra;
    } table_bytes_ctx;
    
    static int count_bytes(void *x, const char *key, const char *value)
    {
        table_bytes_ctx *ctx = x;
        if (key) {
            ctx->bytes += strlen(key);
        }
        if (value) {
            ctx->bytes += strlen(value);
        }
        ctx->bytes += ctx->pair_extra;
        return 1;
    }
    
    apr_size_t h2_util_table_bytes(apr_table_t *t, apr_size_t pair_extra)
    {
        table_bytes_ctx ctx;
    
        ctx.bytes = 0;
        ctx.pair_extra = pair_extra;
        apr_table_do(count_bytes, &ctx, t, NULL);
        return ctx.bytes;
    }
    
    
    /*******************************************************************************
     * h2_util for bucket brigades
     ******************************************************************************/
    
    static void fit_bucket_into(apr_bucket *b, apr_off_t *plen)
    {
        /* signed apr_off_t is at least as large as unsigned apr_size_t.
         * Problems may arise when they are both the same size. Then
         * the bucket length *may* be larger than a value we can hold
         * in apr_off_t. Before casting b->length to apr_off_t we must
         * check the limitations.
         * After we resized the bucket, it is safe to cast and substract.
         */
        if ((sizeof(apr_off_t) == sizeof(apr_int64_t)
             && b->length > APR_INT64_MAX)
           || (sizeof(apr_off_t) == sizeof(apr_int32_t)
               && b->length > APR_INT32_MAX)
           || *plen < (apr_off_t)b->length) {
            /* bucket is longer the *plen */
            apr_bucket_split(b, *plen);
        }
        *plen -= (apr_off_t)b->length;
    }
    
    apr_status_t h2_brigade_concat_length(apr_bucket_brigade *dest,
                                          apr_bucket_brigade *src,
                                          apr_off_t length)
    {
        apr_bucket *b;
        apr_off_t remain = length;
        apr_status_t status = APR_SUCCESS;
    
        while (!APR_BRIGADE_EMPTY(src)) {
            b = APR_BRIGADE_FIRST(src);
    
            if (APR_BUCKET_IS_METADATA(b)) {
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(dest, b);
            }
            else {
                if (remain <= 0) {
                    return status;
                }
                if (b->length == ((apr_size_t)-1)) {
                    const char *ign;
                    apr_size_t ilen;
                    status = apr_bucket_read(b, &ign, &ilen, APR_BLOCK_READ);
                    if (status != APR_SUCCESS) {
                        return status;
                    }
                }
                fit_bucket_into(b, &remain);
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(dest, b);
            }
        }
        return status;
    }
    
    apr_status_t h2_brigade_copy_length(apr_bucket_brigade *dest,
                                        apr_bucket_brigade *src,
                                        apr_off_t length)
    {
        apr_bucket *b, *next;
        apr_off_t remain = length;
        apr_status_t status = APR_SUCCESS;
    
        for (b = APR_BRIGADE_FIRST(src);
             b != APR_BRIGADE_SENTINEL(src);
             b = next) {
            next = APR_BUCKET_NEXT(b);
    
            if (APR_BUCKET_IS_METADATA(b)) {
                /* fall through */
            }
            else {
                if (remain <= 0) {
                    return status;
                }
                if (b->length == ((apr_size_t)-1)) {
                    const char *ign;
                    apr_size_t ilen;
                    status = apr_bucket_read(b, &ign, &ilen, APR_BLOCK_READ);
                    if (status != APR_SUCCESS) {
                        return status;
                    }
                }
                fit_bucket_into(b, &remain);
            }
            status = apr_bucket_copy(b, &b);
            if (status != APR_SUCCESS) {
                return status;
            }
            APR_BRIGADE_INSERT_TAIL(dest, b);
        }
        return status;
    }
    
    apr_size_t h2_util_bucket_print(char *buffer, apr_size_t bmax,
                                    apr_bucket *b, const char *sep)
    {
        apr_size_t off = 0;
        if (sep && *sep) {
            off += apr_snprintf(buffer+off, bmax-off, "%s", sep);
        }
    
        if (bmax <= off) {
            return off;
        }
        else if (APR_BUCKET_IS_METADATA(b)) {
            off += apr_snprintf(buffer+off, bmax-off, "%s", b->type->name);
        }
        else if (bmax > off) {
            off += apr_snprintf(buffer+off, bmax-off, "%s[%ld]",
                                b->type->name,
                                (b->length == ((apr_size_t)-1)?
                                       -1 : (long)b->length));
        }
        return off;
    }
    
    apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax,
                                const char *tag, const char *sep,
                                apr_bucket_brigade *bb)
    {
        apr_size_t off = 0;
        const char *sp = "";
        apr_bucket *b;
    
        if (bmax > 1) {
            if (bb) {
                memset(buffer, 0, bmax--);
                off += apr_snprintf(buffer+off, bmax-off, "%s(", tag);
                for (b = APR_BRIGADE_FIRST(bb);
                     (bmax > off) && (b != APR_BRIGADE_SENTINEL(bb));
                     b = APR_BUCKET_NEXT(b)) {
    
                    off += h2_util_bucket_print(buffer+off, bmax-off, b, sp);
                    sp = " ";
                }
                if (bmax > off) {
                    off += apr_snprintf(buffer+off, bmax-off, ")%s", sep);
                }
            }
            else {
                off += apr_snprintf(buffer+off, bmax-off, "%s(null)%s", tag, sep);
            }
        }
        return off;
    }
    
    apr_status_t h2_append_brigade(apr_bucket_brigade *to,
                                   apr_bucket_brigade *from,
                                   apr_off_t *plen,
                                   int *peos,
                                   h2_bucket_gate *should_append)
    {
        apr_bucket *e;
        apr_off_t start, remain;
        apr_status_t rv;
    
        *peos = 0;
        start = remain = *plen;
    
        while (!APR_BRIGADE_EMPTY(from)) {
            e = APR_BRIGADE_FIRST(from);
    
            if (!should_append(e)) {
                goto leave;
            }
            else if (APR_BUCKET_IS_METADATA(e)) {
                if (APR_BUCKET_IS_EOS(e)) {
                    *peos = 1;
                    apr_bucket_delete(e);
                    continue;
                }
            }
            else {
                if (remain <= 0) {
                    goto leave;
                }
                if (e->length == ((apr_size_t)-1)) {
                    const char *ign;
                    apr_size_t ilen;
                    rv = apr_bucket_read(e, &ign, &ilen, APR_BLOCK_READ);
                    if (rv != APR_SUCCESS) {
                        return rv;
                    }
                }
                fit_bucket_into(e, &remain);
            }
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(to, e);
        }
    leave:
        *plen = start - remain;
        return APR_SUCCESS;
    }
    
    apr_off_t h2_brigade_mem_size(apr_bucket_brigade *bb)
    {
        apr_bucket *b;
        apr_off_t total = 0;
    
        for (b = APR_BRIGADE_FIRST(bb);
             b != APR_BRIGADE_SENTINEL(bb);
             b = APR_BUCKET_NEXT(b))
        {
            total += sizeof(*b);
            if (b->length > 0) {
                if (APR_BUCKET_IS_HEAP(b)
                    || APR_BUCKET_IS_POOL(b)) {
                    total += b->length;
                }
            }
        }
        return total;
    }
    
    
    /*******************************************************************************
     * h2_ngheader
     ******************************************************************************/
    
    static int count_header(void *ctx, const char *key, const char *value)
    {
        if (!h2_util_ignore_resp_header(key)) {
            (*((size_t*)ctx))++;
        }
        return 1;
    }
    
    static const char *inv_field_name_chr(const char *token)
    {
        const char *p = ap_scan_http_token(token);
        if (p == token && *p == ':') {
            p = ap_scan_http_token(++p);
        }
        return (p && *p)? p : NULL;
    }
    
    static const char *inv_field_value_chr(const char *token)
    {
        const char *p = ap_scan_http_field_content(token);
        return (p && *p)? p : NULL;
    }
    
    static void strip_field_value_ws(nghttp2_nv *nv)
    {
        while(nv->valuelen && (nv->value[0] == ' ' || nv->value[0] == '\t')) {
            nv->value++; nv->valuelen--;
        }
        while(nv->valuelen && (nv->value[nv->valuelen-1] == ' '
                               || nv->value[nv->valuelen-1] == '\t')) {
            nv->valuelen--;
        }
    }
    
    typedef struct ngh_ctx {
        apr_pool_t *p;
        int unsafe;
        h2_ngheader *ngh;
        apr_status_t status;
    } ngh_ctx;
    
    static int add_header(ngh_ctx *ctx, const char *key, const char *value)
    {
        nghttp2_nv *nv = &(ctx->ngh)->nv[(ctx->ngh)->nvlen++];
        const char *p;
    
        if (!ctx->unsafe) {
            if ((p = inv_field_name_chr(key))) {
                ap_log_perror(APLOG_MARK, APLOG_TRACE1, APR_EINVAL, ctx->p,
                              "h2_request: head field '%s: %s' has invalid char %s",
                              key, value, p);
                ctx->status = APR_EINVAL;
                return 0;
            }
            if ((p = inv_field_value_chr(value))) {
                ap_log_perror(APLOG_MARK, APLOG_TRACE1, APR_EINVAL, ctx->p,
                              "h2_request: head field '%s: %s' has invalid char %s",
                              key, value, p);
                ctx->status = APR_EINVAL;
                return 0;
            }
        }
        nv->name = (uint8_t*)key;
        nv->namelen = strlen(key);
        nv->value = (uint8_t*)value;
        nv->valuelen = strlen(value);
        strip_field_value_ws(nv);
    
        return 1;
    }
    
    static int add_table_header(void *ctx, const char *key, const char *value)
    {
        if (!h2_util_ignore_resp_header(key)) {
            add_header(ctx, key, value);
        }
        return 1;
    }
    
    static apr_status_t ngheader_create(h2_ngheader **ph, apr_pool_t *p,
                                        int unsafe, size_t key_count,
                                        const char *keys[], const char *values[],
                                        apr_table_t *headers)
    {
        ngh_ctx ctx;
        size_t n, i;
    
        ctx.p = p;
        ctx.unsafe = unsafe;
    
        n = key_count;
        apr_table_do(count_header, &n, headers, NULL);
    
        *ph = ctx.ngh = apr_pcalloc(p, sizeof(h2_ngheader));
        if (!ctx.ngh) {
            return APR_ENOMEM;
        }
    
        ctx.ngh->nv = apr_pcalloc(p, n * sizeof(nghttp2_nv));
        if (!ctx.ngh->nv) {
            return APR_ENOMEM;
        }
    
        ctx.status = APR_SUCCESS;
        for (i = 0; i < key_count; ++i) {
            if (!add_header(&ctx, keys[i], values[i])) {
                return ctx.status;
            }
        }
    
        apr_table_do(add_table_header, &ctx, headers, NULL);
    
        return ctx.status;
    }
    
    #if AP_HAS_RESPONSE_BUCKETS
    
    static int is_unsafe(ap_bucket_response *h)
    {
        const char *v = h->notes? apr_table_get(h->notes, H2_HDR_CONFORMANCE) : NULL;
        return (v && !strcmp(v, H2_HDR_CONFORMANCE_UNSAFE));
    }
    
    apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p,
                                        ap_bucket_headers *headers)
    {
        return ngheader_create(ph, p, 0,
                               0, NULL, NULL, headers->headers);
    }
    
    apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                        ap_bucket_response *response)
    {
        const char *keys[] = {
            ":status"
        };
        const char *values[] = {
            apr_psprintf(p, "%d", response->status)
        };
        return ngheader_create(ph, p, is_unsafe(response),
                               H2_ALEN(keys), keys, values, response->headers);
    }
    
    #else /* AP_HAS_RESPONSE_BUCKETS */
    
    static int is_unsafe(h2_headers *h)
    {
        const char *v = h->notes? apr_table_get(h->notes, H2_HDR_CONFORMANCE) : NULL;
        return (v && !strcmp(v, H2_HDR_CONFORMANCE_UNSAFE));
    }
    
    apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p,
                                        h2_headers *headers)
    {
        return ngheader_create(ph, p, is_unsafe(headers),
                               0, NULL, NULL, headers->headers);
    }
    
    apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                        h2_headers *headers)
    {
        const char *keys[] = {
            ":status"
        };
        const char *values[] = {
            apr_psprintf(p, "%d", headers->status)
        };
        return ngheader_create(ph, p, is_unsafe(headers),
                               H2_ALEN(keys), keys, values, headers->headers);
    }
    
    #endif /* else AP_HAS_RESPONSE_BUCKETS */
    
    apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                        const struct h2_request *req)
    {
    
        const char *keys[] = {
            ":scheme",
            ":authority",
            ":path",
            ":method",
        };
        const char *values[] = {
            req->scheme,
            req->authority,
            req->path,
            req->method,
        };
    
        ap_assert(req->scheme);
        ap_assert(req->authority);
        ap_assert(req->path);
        ap_assert(req->method);
    
        return ngheader_create(ph, p, 0, H2_ALEN(keys), keys, values, req->headers);
    }
    
    /*******************************************************************************
     * header HTTP/1 <-> HTTP/2 conversions
     ******************************************************************************/
    
    
    typedef struct {
        const char *name;
        size_t len;
    } literal;
    
    #define H2_DEF_LITERAL(n)   { (n), (sizeof(n)-1) }
    #define H2_LIT_ARGS(a)      (a),H2_ALEN(a)
    
    static literal IgnoredRequestHeaders[] = {
        H2_DEF_LITERAL("upgrade"),
        H2_DEF_LITERAL("connection"),
        H2_DEF_LITERAL("keep-alive"),
        H2_DEF_LITERAL("http2-settings"),
        H2_DEF_LITERAL("proxy-connection"),
        H2_DEF_LITERAL("transfer-encoding"),
    };
    static literal IgnoredRequestTrailers[] = { /* Ignore, see rfc7230, ch. 4.1.2 */
        H2_DEF_LITERAL("te"),
        H2_DEF_LITERAL("host"),
        H2_DEF_LITERAL("range"),
        H2_DEF_LITERAL("cookie"),
        H2_DEF_LITERAL("expect"),
        H2_DEF_LITERAL("pragma"),
        H2_DEF_LITERAL("max-forwards"),
        H2_DEF_LITERAL("cache-control"),
        H2_DEF_LITERAL("authorization"),
        H2_DEF_LITERAL("content-length"),
        H2_DEF_LITERAL("proxy-authorization"),
    };
    static literal IgnoredResponseHeaders[] = {
        H2_DEF_LITERAL("upgrade"),
        H2_DEF_LITERAL("connection"),
        H2_DEF_LITERAL("keep-alive"),
        H2_DEF_LITERAL("transfer-encoding"),
    };
    static literal IgnoredResponseTrailers[] = {
        H2_DEF_LITERAL("age"),
        H2_DEF_LITERAL("date"),
        H2_DEF_LITERAL("vary"),
        H2_DEF_LITERAL("cookie"),
        H2_DEF_LITERAL("expires"),
        H2_DEF_LITERAL("warning"),
        H2_DEF_LITERAL("location"),
        H2_DEF_LITERAL("retry-after"),
        H2_DEF_LITERAL("cache-control"),
        H2_DEF_LITERAL("www-authenticate"),
        H2_DEF_LITERAL("proxy-authenticate"),
    };
    
    static int contains_name(const literal *lits, size_t llen, nghttp2_nv *nv)
    {
        const literal *lit;
        size_t i;
    
        for (i = 0; i < llen; ++i) {
            lit = &lits[i];
            if (lit->len == nv->namelen
                && !ap_cstr_casecmp(lit->name, (const char *)nv->name)) {
                return 1;
            }
        }
        return 0;
    }
    
    int h2_util_ignore_resp_header(const char *name)
    {
        nghttp2_nv nv;
    
        nv.name = (uint8_t*)name;
        nv.namelen = strlen(name);
        return contains_name(H2_LIT_ARGS(IgnoredResponseHeaders), &nv);
    }
    
    
    static int h2_req_ignore_header(nghttp2_nv *nv)
    {
        return contains_name(H2_LIT_ARGS(IgnoredRequestHeaders), nv);
    }
    
    int h2_ignore_req_trailer(const char *name, size_t len)
    {
        nghttp2_nv nv;
    
        nv.name = (uint8_t*)name;
        nv.namelen = strlen(name);
        return (h2_req_ignore_header(&nv)
                || contains_name(H2_LIT_ARGS(IgnoredRequestTrailers), &nv));
    }
    
    int h2_ignore_resp_trailer(const char *name, size_t len)
    {
        nghttp2_nv nv;
    
        nv.name = (uint8_t*)name;
        nv.namelen = strlen(name);
        return (contains_name(H2_LIT_ARGS(IgnoredResponseHeaders), &nv)
                || contains_name(H2_LIT_ARGS(IgnoredResponseTrailers), &nv));
    }
    
    static apr_status_t req_add_header(apr_table_t *headers, apr_pool_t *pool,
                                       nghttp2_nv *nv, h2_hd_scratch *scratch,
                                       int *pwas_added)
    {
        const char *existing;
    
        *pwas_added = 0;
        strip_field_value_ws(nv);
    
        if (h2_req_ignore_header(nv)) {
            return APR_SUCCESS;
        }
        else if (nv->namelen == sizeof("cookie")-1
                 && !ap_cstr_casecmp("cookie", (const char *)nv->name)) {
            existing = apr_table_get(headers, "cookie");
            if (existing) {
                /* Cookie header come separately in HTTP/2, but need
                 * to be merged by "; " (instead of default ", ")
                 */
                if ((strlen(existing) + nv->valuelen + nv->namelen + 4)
                       > scratch->max_len) {
                    /* "key: oldval, nval" is too long */
                    return APR_EINVAL;
                }
                apr_table_setn(headers, "Cookie",
                               apr_psprintf(pool, "%s; %.*s", existing,
                                            (int)nv->valuelen, nv->value));
                return APR_SUCCESS;
            }
        }
        else if (nv->namelen == sizeof("host")-1
                 && !ap_cstr_casecmp("host", (const char *)nv->name)) {
            if (apr_table_get(headers, "Host")) {
                return APR_SUCCESS; /* ignore duplicate */
            }
        }
    
        if (((nv->namelen + nv->valuelen + 2) > scratch->max_len))
            return APR_EINVAL;
    
        /* We need 0-terminated strings to operate on apr_table */
        AP_DEBUG_ASSERT(nv->namelen < scratch->max_len);
        memcpy(scratch->name, nv->name, nv->namelen);
        scratch->name[nv->namelen] = 0;
        AP_DEBUG_ASSERT(nv->valuelen < scratch->max_len);
        memcpy(scratch->value, nv->value, nv->valuelen);
        scratch->value[nv->valuelen] = 0;
    
        *pwas_added = 1;
        existing = apr_table_get(headers, scratch->name);
        if (existing) {
            if (!nv->valuelen) /* not adding a 0-length value to existing */
                return APR_SUCCESS;
            if ((strlen(existing) + 2 + nv->valuelen + nv->namelen + 2)
                > scratch->max_len) {
                /* "name: existing, value" is too long */
                return APR_EINVAL;
            }
            apr_table_merge(headers, scratch->name, scratch->value);
        }
        else {
            h2_util_camel_case_header(scratch->name, nv->namelen);
            apr_table_set(headers, scratch->name, scratch->value);
        }
        return APR_SUCCESS;
    }
    
    apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
                                  const char *name, size_t nlen,
                                  const char *value, size_t vlen,
                                  h2_hd_scratch *scratch, int *pwas_added)
    {
        nghttp2_nv nv;
    
        nv.name = (uint8_t*)name;
        nv.namelen = nlen;
        nv.value = (uint8_t*)value;
        nv.valuelen = vlen;
        return req_add_header(headers, pool, &nv, scratch, pwas_added);
    }
    
    /*******************************************************************************
     * frame logging
     ******************************************************************************/
    
    int h2_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen)
    {
        char scratch[128];
        size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
    
        switch (frame->hd.type) {
            case NGHTTP2_DATA: {
                return apr_snprintf(buffer, maxlen,
                                    "DATA[length=%d, flags=%d, stream=%d, padlen=%d]",
                                    (int)frame->hd.length, frame->hd.flags,
                                    frame->hd.stream_id, (int)frame->data.padlen);
            }
            case NGHTTP2_HEADERS: {
                return apr_snprintf(buffer, maxlen,
                                    "HEADERS[length=%d, hend=%d, stream=%d, eos=%d]",
                                    (int)frame->hd.length,
                                    !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
                                    frame->hd.stream_id,
                                    !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
            }
            case NGHTTP2_PRIORITY: {
                return apr_snprintf(buffer, maxlen,
                                    "PRIORITY[length=%d, flags=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    frame->hd.flags, frame->hd.stream_id);
            }
            case NGHTTP2_RST_STREAM: {
                return apr_snprintf(buffer, maxlen,
                                    "RST_STREAM[length=%d, flags=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    frame->hd.flags, frame->hd.stream_id);
            }
            case NGHTTP2_SETTINGS: {
                if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
                    return apr_snprintf(buffer, maxlen,
                                        "SETTINGS[ack=1, stream=%d]",
                                        frame->hd.stream_id);
                }
                return apr_snprintf(buffer, maxlen,
                                    "SETTINGS[length=%d, stream=%d]",
                                    (int)frame->hd.length, frame->hd.stream_id);
            }
            case NGHTTP2_PUSH_PROMISE: {
                return apr_snprintf(buffer, maxlen,
                                    "PUSH_PROMISE[length=%d, hend=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
                                    frame->hd.stream_id);
            }
            case NGHTTP2_PING: {
                return apr_snprintf(buffer, maxlen,
                                    "PING[length=%d, ack=%d, stream=%d]",
                                    (int)frame->hd.length,
                                    frame->hd.flags&NGHTTP2_FLAG_ACK,
                                    frame->hd.stream_id);
            }
            case NGHTTP2_GOAWAY: {
                size_t len = (frame->goaway.opaque_data_len < s_len)?
                    frame->goaway.opaque_data_len : s_len-1;
                if (len)
                    memcpy(scratch, frame->goaway.opaque_data, len);
                scratch[len] = '\0';
                return apr_snprintf(buffer, maxlen, "GOAWAY[error=%d, reason='%s', "
                                    "last_stream=%d]", frame->goaway.error_code,
                                    scratch, frame->goaway.last_stream_id);
            }
            case NGHTTP2_WINDOW_UPDATE: {
                return apr_snprintf(buffer, maxlen,
                                    "WINDOW_UPDATE[stream=%d, incr=%d]",
                                    frame->hd.stream_id,
                                    frame->window_update.window_size_increment);
            }
            default:
                return apr_snprintf(buffer, maxlen,
                                    "type=%d[length=%d, flags=%d, stream=%d]",
                                    frame->hd.type, (int)frame->hd.length,
                                    frame->hd.flags, frame->hd.stream_id);
        }
    }
    
    /*******************************************************************************
     * push policy
     ******************************************************************************/
    int h2_push_policy_determine(apr_table_t *headers, apr_pool_t *p, int push_enabled)
    {
        h2_push_policy policy = H2_PUSH_NONE;
        if (push_enabled) {
            const char *val = apr_table_get(headers, "accept-push-policy");
            if (val) {
                if (ap_find_token(p, val, "fast-load")) {
                    policy = H2_PUSH_FAST_LOAD;
                }
                else if (ap_find_token(p, val, "head")) {
                    policy = H2_PUSH_HEAD;
                }
                else if (ap_find_token(p, val, "default")) {
                    policy = H2_PUSH_DEFAULT;
                }
                else if (ap_find_token(p, val, "none")) {
                    policy = H2_PUSH_NONE;
                }
                else {
                    /* nothing known found in this header, go by default */
                    policy = H2_PUSH_DEFAULT;
                }
            }
            else {
                policy = H2_PUSH_DEFAULT;
            }
        }
        return policy;
    }
    
    void h2_util_drain_pipe(apr_file_t *pipe)
    {
        char rb[512];
        apr_size_t nr = sizeof(rb);
        apr_interval_time_t timeout;
        apr_status_t trv;
    
        /* Make the pipe non-blocking if we can */
        trv = apr_file_pipe_timeout_get(pipe, &timeout);
        if (trv == APR_SUCCESS)
          apr_file_pipe_timeout_set(pipe, 0);
    
        while (apr_file_read(pipe, rb, &nr) == APR_SUCCESS) {
            /* Although we write just one byte to the other end of the pipe
             * during wakeup, multiple threads could call the wakeup.
             * So simply drain out from the input side of the pipe all
             * the data.
             */
            if (nr != sizeof(rb))
                break;
        }
        if (trv == APR_SUCCESS)
          apr_file_pipe_timeout_set(pipe, timeout);
    }
    
    apr_status_t h2_util_wait_on_pipe(apr_file_t *pipe)
    {
        char rb[512];
        apr_size_t nr = sizeof(rb);
    
        return apr_file_read(pipe, rb, &nr);
    }
    
    #if AP_HAS_RESPONSE_BUCKETS
    
    static int add_header_lengths(void *ctx, const char *name, const char *value)
    {
        apr_size_t *plen = ctx;
        *plen += strlen(name) + strlen(value);
        return 1;
    }
    
    apr_size_t headers_length_estimate(ap_bucket_headers *hdrs)
    {
        apr_size_t len = 0;
        apr_table_do(add_header_lengths, &len, hdrs->headers, NULL);
        return len;
    }
    
    apr_size_t response_length_estimate(ap_bucket_response *resp)
    {
        apr_size_t len = 3 + 1 + 8 + (resp->reason? strlen(resp->reason) : 10);
        apr_table_do(add_header_lengths, &len, resp->headers, NULL);
        return len;
    }
    
    #endif /* AP_HAS_RESPONSE_BUCKETS */
    ���������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_version.h�������������������������������������������������������������0000664�0001751�0001751�00000002541�15017526503�017570� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2_h2_version_h
    #define mod_h2_h2_version_h
    
    #undef PACKAGE_VERSION
    #undef PACKAGE_TARNAME
    #undef PACKAGE_STRING
    #undef PACKAGE_NAME
    #undef PACKAGE_BUGREPORT
    
    /**
     * @macro
     * Version number of the http2 module as c string
     */
    #define MOD_HTTP2_VERSION "2.0.32"
    
    /**
     * @macro
     * Numerical representation of the version number of the http2 module
     * release. This is a 24 bit number with 8 bits for major number, 8 bits
     * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
     */
    #define MOD_HTTP2_VERSION_NUM 0x020020
    
    
    #endif /* mod_h2_h2_version_h */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_ws.c������������������������������������������������������������������0000664�0001751�0001751�00000032176�14737240630�016540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_lib.h"
    #include "apr_sha1.h"
    #include "apr_strmatch.h"
    
    #include <ap_mmn.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    #include <http_ssl.h>
    #include <http_vhost.h>
    #include <util_filter.h>
    #include <ap_mpm.h>
    
    #include "h2_private.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_headers.h"
    #include "h2_request.h"
    #include "h2_ws.h"
    
    #if H2_USE_WEBSOCKETS
    
    #include "apr_encode.h" /* H2_USE_WEBSOCKETS is conditional on APR 1.7+ */
    
    static ap_filter_rec_t *c2_ws_out_filter_handle;
    
    struct ws_filter_ctx {
        const char *ws_accept_base64;
        int has_final_response;
        int override_body;
    };
    
    /**
     * Generate the "Sec-WebSocket-Accept" header field for the given key
     * (base64 encoded) as defined in RFC 6455 ch. 4.2.2 step 5.3
     */
    static const char *gen_ws_accept(conn_rec *c, const char *key_base64)
    {
        apr_byte_t dgst[APR_SHA1_DIGESTSIZE];
        const char ws_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        apr_sha1_ctx_t sha1_ctx;
    
        apr_sha1_init(&sha1_ctx);
        apr_sha1_update(&sha1_ctx, key_base64, (unsigned int)strlen(key_base64));
        apr_sha1_update(&sha1_ctx, ws_guid, (unsigned int)strlen(ws_guid));
        apr_sha1_final(dgst, &sha1_ctx);
    
        return apr_pencode_base64_binary(c->pool, dgst, sizeof(dgst),
                                         APR_ENCODE_NONE, NULL);
    }
    
    const h2_request *h2_ws_rewrite_request(const h2_request *req,
                                            conn_rec *c2, int no_body)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c2);
        h2_request *wsreq;
        unsigned char key_raw[16];
        const char *key_base64, *accept_base64;
        struct ws_filter_ctx *ws_ctx;
        apr_status_t rv;
    
        if (!conn_ctx || !req->protocol || strcmp("websocket", req->protocol))
            return req;
    
        if (ap_cstr_casecmp("CONNECT", req->method)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                          "h2_c2(%s-%d): websocket request with method %s",
                          conn_ctx->id, conn_ctx->stream_id, req->method);
            return req;
        }
        if (!req->scheme) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                          "h2_c2(%s-%d): websocket CONNECT without :scheme",
                          conn_ctx->id, conn_ctx->stream_id);
            return req;
        }
        if (!req->path) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                          "h2_c2(%s-%d): websocket CONNECT without :path",
                          conn_ctx->id, conn_ctx->stream_id);
            return req;
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                      "h2_c2(%s-%d): websocket CONNECT for %s",
                      conn_ctx->id, conn_ctx->stream_id, req->path);
        /* Transform the HTTP/2 extended CONNECT to an internal GET using
         * the HTTP/1.1 version of websocket connection setup. */
        wsreq = h2_request_clone(c2->pool, req);
        wsreq->method = "GET";
        wsreq->protocol = NULL;
        apr_table_set(wsreq->headers, "Upgrade", "websocket");
        apr_table_add(wsreq->headers, "Connection", "Upgrade");
        /* add Sec-WebSocket-Key header */
        rv = apr_generate_random_bytes(key_raw, sizeof(key_raw));
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(10461)
                         "error generating secret");
            return NULL;
        }
        key_base64 = apr_pencode_base64_binary(c2->pool, key_raw, sizeof(key_raw),
                                               APR_ENCODE_NONE, NULL);
        apr_table_set(wsreq->headers, "Sec-WebSocket-Key", key_base64);
        /* This is now the request to process internally */
    
        /* When this request gets processed and delivers a 101 response,
         * we expect it to carry a "Sec-WebSocket-Accept" header with
         * exactly the following value, as per RFC 6455. */
        accept_base64 = gen_ws_accept(c2, key_base64);
        /* Add an output filter that intercepts generated responses:
         * - if a valid WebSocket negotiation happens, transform the
         *   101 response to a 200
         * - if a 2xx response happens, that does not pass the Accept test,
         *   return a 502 indicating that the URI seems not support the websocket
         *   protocol (RFC 8441 does not define this, but it seems the best
         *   choice)
         * - if a 3xx, 4xx or 5xx response happens, forward this unchanged.
         */
        ws_ctx = apr_pcalloc(c2->pool, sizeof(*ws_ctx));
        ws_ctx->ws_accept_base64 = accept_base64;
        /* insert our filter just before the C2 core filter */
        ap_remove_output_filter_byhandle(c2->output_filters, "H2_C2_NET_OUT");
        ap_add_output_filter("H2_C2_WS_OUT", ws_ctx, NULL, c2);
        ap_add_output_filter("H2_C2_NET_OUT", NULL, NULL, c2);
        /* Mark the connection as being an Upgrade, with some special handling
         * since the request needs an EOS, without the stream being closed  */
        conn_ctx->is_upgrade = 1;
    
        return wsreq;
    }
    
    static apr_bucket *make_valid_resp(conn_rec *c2, int status,
                                       apr_table_t *headers, apr_table_t *notes)
    {
        apr_table_t *nheaders, *nnotes;
    
        ap_assert(headers);
        nheaders = apr_table_clone(c2->pool, headers);
        apr_table_unset(nheaders, "Connection");
        apr_table_unset(nheaders, "Upgrade");
        apr_table_unset(nheaders, "Sec-WebSocket-Accept");
        nnotes = notes? apr_table_clone(c2->pool, notes) :
                        apr_table_make(c2->pool, 10);
    #if AP_HAS_RESPONSE_BUCKETS
        return ap_bucket_response_create(status, NULL, nheaders, nnotes,
                                         c2->pool, c2->bucket_alloc);
    #else
        return h2_bucket_headers_create(c2->bucket_alloc,
                                        h2_headers_create(status, nheaders,
                                                          nnotes, 0, c2->pool));
    #endif
    }
    
    static apr_bucket *make_invalid_resp(conn_rec *c2, int status,
                                         apr_table_t *notes)
    {
        apr_table_t *nheaders, *nnotes;
    
        nheaders = apr_table_make(c2->pool, 10);
        apr_table_setn(nheaders, "Content-Length", "0");
        nnotes = notes? apr_table_clone(c2->pool, notes) :
                        apr_table_make(c2->pool, 10);
    #if AP_HAS_RESPONSE_BUCKETS
        return ap_bucket_response_create(status, NULL, nheaders, nnotes,
                                         c2->pool, c2->bucket_alloc);
    #else
        return h2_bucket_headers_create(c2->bucket_alloc,
                                        h2_headers_create(status, nheaders,
                                                          nnotes, 0, c2->pool));
    #endif
    }
    
    static void ws_handle_resp(conn_rec *c2, h2_conn_ctx_t *conn_ctx,
                               struct ws_filter_ctx *ws_ctx, apr_bucket *b)
    {
    #if AP_HAS_RESPONSE_BUCKETS
        ap_bucket_response *resp = b->data;
    #else /* AP_HAS_RESPONSE_BUCKETS */
        h2_headers *resp = h2_bucket_headers_get(b);
    #endif /* !AP_HAS_RESPONSE_BUCKETS */
        apr_bucket *b_override = NULL;
        int is_final = 0;
        int override_body = 0;
    
        if (ws_ctx->has_final_response) {
            /* already did, nop */
            return;
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2,
                      "h2_c2(%s-%d): H2_C2_WS_OUT inspecting response %d",
                      conn_ctx->id, conn_ctx->stream_id, resp->status);
        if (resp->status == HTTP_SWITCHING_PROTOCOLS) {
            /* The resource agreed to switch protocol. But this is only valid
             * if it send back the correct Sec-WebSocket-Accept header value */
            const char *hd = apr_table_get(resp->headers, "Sec-WebSocket-Accept");
            if (hd && !strcmp(ws_ctx->ws_accept_base64, hd)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                              "h2_c2(%s-%d): websocket CONNECT, valid 101 Upgrade"
                              ", converting to 200 response",
                              conn_ctx->id, conn_ctx->stream_id);
                b_override = make_valid_resp(c2, HTTP_OK, resp->headers, resp->notes);
                is_final = 1;
            }
            else {
                if (!hd) {
                    /* This points to someone being confused */
                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c2, APLOGNO(10462)
                                  "h2_c2(%s-%d): websocket CONNECT, got 101 response "
                                  "without Sec-WebSocket-Accept header",
                                  conn_ctx->id, conn_ctx->stream_id);
                }
                else {
                    /* This points to a bug, either in our WebSockets negotiation
                     * or in the request processings implementation of WebSockets */
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c2, APLOGNO(10463)
                                  "h2_c2(%s-%d): websocket CONNECT, 101 response "
                                  "with 'Sec-WebSocket-Accept: %s' but expected %s",
                                  conn_ctx->id, conn_ctx->stream_id, hd,
                                  ws_ctx->ws_accept_base64);
                }
                b_override = make_invalid_resp(c2, HTTP_BAD_GATEWAY, resp->notes);
                override_body = is_final = 1;
            }
        }
        else if (resp->status < 200) {
            /* other intermediate response, pass through */
        }
        else if (resp->status < 300) {
            /* Failure, we might be talking to a plain http resource */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                          "h2_c2(%s-%d): websocket CONNECT, invalid response %d",
                          conn_ctx->id, conn_ctx->stream_id, resp->status);
            b_override = make_invalid_resp(c2, HTTP_BAD_GATEWAY, resp->notes);
            override_body = is_final = 1;
        }
        else {
            /* error response, pass through. */
            ws_ctx->has_final_response = 1;
        }
    
        if (b_override) {
            APR_BUCKET_INSERT_BEFORE(b, b_override);
            apr_bucket_delete(b);
            b = b_override;
        }
        if (override_body) {
            APR_BUCKET_INSERT_AFTER(b, apr_bucket_eos_create(c2->bucket_alloc));
            ws_ctx->override_body = 1;
        }
        if (is_final) {
            ws_ctx->has_final_response = 1;
            conn_ctx->has_final_response = 1;
        }
    }
    
    static apr_status_t h2_c2_ws_filter_out(ap_filter_t* f, apr_bucket_brigade* bb)
    {
        struct ws_filter_ctx *ws_ctx = f->ctx;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
        apr_bucket *b, *bnext;
    
        ap_assert(conn_ctx);
        if (ws_ctx->override_body) {
            /* We have overridden the original response and also its body.
             * If this filter is called again, we signal a hard abort to
             * allow processing to terminate at the earliest. */
            f->c->aborted = 1;
            return APR_ECONNABORTED;
        }
    
        /* Inspect the brigade, looking for RESPONSE/HEADER buckets.
         * Remember, this filter is only active for client websocket CONNECT
         * requests that we translated to an internal GET with websocket
         * headers.
         * We inspect the repsone to see if the internal resource actually
         * agrees to talk websocket or is "just" a normal HTTP resource that
         * ignored the websocket request headers. */
        for (b = APR_BRIGADE_FIRST(bb);
             b != APR_BRIGADE_SENTINEL(bb);
             b = bnext)
        {
            bnext = APR_BUCKET_NEXT(b);
            if (APR_BUCKET_IS_METADATA(b)) {
    #if AP_HAS_RESPONSE_BUCKETS
                if (AP_BUCKET_IS_RESPONSE(b)) {
    #else
                if (H2_BUCKET_IS_HEADERS(b)) {
    #endif /* !AP_HAS_RESPONSE_BUCKETS */
                    ws_handle_resp(f->c, conn_ctx, ws_ctx, b);
                    continue;
                }
            }
            else if (ws_ctx->override_body) {
                apr_bucket_delete(b);
            }
        }
        return ap_pass_brigade(f->next, bb);
    }
    
    static int ws_post_read(request_rec *r)
    {
    
        if (r->connection->master) {
            h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(r->connection);
            if (conn_ctx && conn_ctx->is_upgrade &&
                !h2_config_sgeti(r->server, H2_CONF_WEBSOCKETS)) {
                return HTTP_NOT_IMPLEMENTED;
            }
        }
        return DECLINED;
    }
    
    void h2_ws_register_hooks(void)
    {
        ap_hook_post_read_request(ws_post_read, NULL, NULL, APR_HOOK_MIDDLE);
        c2_ws_out_filter_handle =
            ap_register_output_filter("H2_C2_WS_OUT", h2_c2_ws_filter_out,
                                      NULL, AP_FTYPE_NETWORK);
    }
    
    #else /* H2_USE_WEBSOCKETS */
    
    const h2_request *h2_ws_rewrite_request(const h2_request *req,
                                            conn_rec *c2, int no_body)
    {
        (void)c2;
        (void)no_body;
        /* no rewriting */
        return req;
    }
    
    void h2_ws_register_hooks(void)
    {
        /*  NOP */
    }
    
    #endif /* H2_USE_WEBSOCKETS (else part) */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_session.c�������������������������������������������������������������0000664�0001751�0001751�00000235434�15032734701�017570� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    #include <apr_thread_cond.h>
    #include <apr_atomic.h>
    #include <apr_base64.h>
    #include <apr_strings.h>
    
    #include <ap_mpm.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_log.h>
    #include <http_protocol.h>
    #include <scoreboard.h>
    
    #include <mpm_common.h>
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>         /* for getpid() */
    #endif
    
    #include "h2_private.h"
    #include "h2.h"
    #include "h2_bucket_beam.h"
    #include "h2_bucket_eos.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_protocol.h"
    #include "h2_mplx.h"
    #include "h2_push.h"
    #include "h2_request.h"
    #include "h2_headers.h"
    #include "h2_stream.h"
    #include "h2_c2.h"
    #include "h2_session.h"
    #include "h2_util.h"
    #include "h2_version.h"
    #include "h2_workers.h"
    
    
    static void transit(h2_session *session, const char *action,
                        h2_session_state nstate);
    
    static void on_stream_state_enter(void *ctx, h2_stream *stream);
    static void on_stream_state_event(void *ctx, h2_stream *stream, h2_stream_event_t ev);
    static void on_stream_event(void *ctx, h2_stream *stream, h2_stream_event_t ev);
    
    static int h2_session_status_from_apr_status(apr_status_t rv)
    {
        if (rv == APR_SUCCESS) {
            return NGHTTP2_NO_ERROR;
        }
        else if (APR_STATUS_IS_EAGAIN(rv)) {
            return NGHTTP2_ERR_WOULDBLOCK;
        }
        else if (APR_STATUS_IS_EOF(rv)) {
            return NGHTTP2_ERR_EOF;
        }
        return NGHTTP2_ERR_PROTO;
    }
    
    static h2_stream *get_stream(h2_session *session, int stream_id)
    {
        return nghttp2_session_get_stream_user_data(session->ngh2, stream_id);
    }
    
    void h2_session_event(h2_session *session, h2_session_event_t ev,
                                 int err, const char *msg)
    {
        h2_session_dispatch_event(session, ev, err, msg);
    }
    
    static int rst_unprocessed_stream(h2_stream *stream, void *ctx)
    {
        int unprocessed = (!h2_stream_is_at_or_past(stream, H2_SS_CLOSED)
                           && (H2_STREAM_CLIENT_INITIATED(stream->id)? 
                               (!stream->session->local.accepting
                                && stream->id > stream->session->local.accepted_max)
                                : 
                               (!stream->session->remote.accepting
                                && stream->id > stream->session->remote.accepted_max))
                           ); 
        if (unprocessed) {
            h2_stream_rst(stream, H2_ERR_NO_ERROR);
            return 0;
        }
        return 1;
    }
    
    static void cleanup_unprocessed_streams(h2_session *session)
    {
        h2_mplx_c1_streams_do(session->mplx, rst_unprocessed_stream, session);
    }
    
    /* APR callback invoked if allocation fails. */
    static int abort_on_oom(int retcode)
    {
        ap_abort_on_oom();
        return retcode; /* unreachable, hopefully. */
    }
    
    static h2_stream *h2_session_open_stream(h2_session *session, int stream_id,
                                             int initiated_on)
    {
        h2_stream * stream;
        apr_allocator_t *allocator;
        apr_pool_t *stream_pool;
        apr_status_t rv;
        
        rv = apr_allocator_create(&allocator);
        if (rv != APR_SUCCESS)
          return NULL;
    
        apr_allocator_max_free_set(allocator, ap_max_mem_free);
        apr_pool_create_ex(&stream_pool, session->pool, NULL, allocator);
        apr_allocator_owner_set(allocator, stream_pool);
        apr_pool_abort_set(abort_on_oom, stream_pool);
        apr_pool_tag(stream_pool, "h2_stream");
        
        stream = h2_stream_create(stream_id, stream_pool, session, 
                                  session->monitor, initiated_on);
        if (stream) {
            nghttp2_session_set_stream_user_data(session->ngh2, stream_id, stream);
        }
        return stream;
    }
    
    /**
     * Determine the priority order of streams.
     * - if both stream depend on the same one, compare weights
     * - if one stream is closer to the root, prioritize that one
     * - if both are on the same level, use the weight of their root
     *   level ancestors
     */
    static int spri_cmp(int sid1, nghttp2_stream *s1, 
                        int sid2, nghttp2_stream *s2, h2_session *session)
    {
        nghttp2_stream *p1, *p2;
        
        p1 = nghttp2_stream_get_parent(s1);
        p2 = nghttp2_stream_get_parent(s2);
        
        if (p1 == p2) {
            int32_t w1, w2;
            
            w1 = nghttp2_stream_get_weight(s1);
            w2 = nghttp2_stream_get_weight(s2);
            return w2 - w1;
        }
        else if (!p1) {
            /* stream 1 closer to root */
            return -1;
        }
        else if (!p2) {
            /* stream 2 closer to root */
            return 1;
        }
        return spri_cmp(sid1, p1, sid2, p2, session);
    }
    
    static int stream_pri_cmp(int sid1, int sid2, void *ctx)
    {
        h2_session *session = ctx;
        nghttp2_stream *s1, *s2;
        
        s1 = nghttp2_session_find_stream(session->ngh2, sid1);
        s2 = nghttp2_session_find_stream(session->ngh2, sid2);
    
        if (s1 == s2) {
            return 0;
        }
        else if (!s1) {
            return 1;
        }
        else if (!s2) {
            return -1;
        }
        return spri_cmp(sid1, s1, sid2, s2, session);
    }
    
    /*
     * Callback when nghttp2 wants to send bytes back to the client.
     */
    static ssize_t send_cb(nghttp2_session *ngh2,
                           const uint8_t *data, size_t length,
                           int flags, void *userp)
    {
        h2_session *session = (h2_session *)userp;
        apr_status_t rv;
        (void)ngh2;
        (void)flags;
    
        if (h2_c1_io_needs_flush(&session->io)) {
            return NGHTTP2_ERR_WOULDBLOCK;
        }
    
        rv = h2_c1_io_add_data(&session->io, (const char *)data, length);
        if (APR_SUCCESS == rv) {
            return length;
        }
        else if (APR_STATUS_IS_EAGAIN(rv)) {
            return NGHTTP2_ERR_WOULDBLOCK;
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, session->c1,
                          APLOGNO(03062) "h2_session: send error");
            return h2_session_status_from_apr_status(rv);
        }
    }
    
    static int on_invalid_frame_recv_cb(nghttp2_session *ngh2,
                                        const nghttp2_frame *frame,
                                        int error, void *userp)
    {
        h2_session *session = (h2_session *)userp;
        (void)ngh2;
        
        if (APLOGcdebug(session->c1)) {
            char buffer[256];
            
            h2_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                          H2_SSSN_LOG(APLOGNO(03063), session, 
                          "recv invalid FRAME[%s], frames=%ld/%ld (r/s)"),
                          buffer, (long)session->frames_received,
                         (long)session->frames_sent);
        }
        return 0;
    }
    
    static int on_data_chunk_recv_cb(nghttp2_session *ngh2, uint8_t flags,
                                     int32_t stream_id,
                                     const uint8_t *data, size_t len, void *userp)
    {
        h2_session *session = (h2_session *)userp;
        apr_status_t status = APR_EINVAL;
        h2_stream * stream;
        int rv = 0;
        
        stream = get_stream(session, stream_id);
        if (stream) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                          H2_SSSN_STRM_MSG(session, stream_id, "write %ld bytes of DATA"),
                          (long)len);
            status = h2_stream_recv_DATA(stream, flags, data, len);
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1, APLOGNO(03064)
                          H2_SSSN_STRM_MSG(session, stream_id,
                          "on_data_chunk for unknown stream"));
            rv = NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        
        if (status != APR_SUCCESS) {
            /* count this as consumed explicitly as no one will read it */
            nghttp2_session_consume(session->ngh2, stream_id, len);
        }
        return rv;
    }
    
    static int on_stream_close_cb(nghttp2_session *ngh2, int32_t stream_id,
                                  uint32_t error_code, void *userp)
    {
        h2_session *session = (h2_session *)userp;
        h2_stream *stream;
        
        (void)ngh2;
        stream = get_stream(session, stream_id);
        if (stream) {
            if (error_code) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                              H2_STRM_LOG(APLOGNO(03065), stream, 
                              "closing with err=%d %s"), 
                              (int)error_code, h2_protocol_err_description(error_code));
                h2_stream_rst(stream, error_code);
            }
        }
        return 0;
    }
    
    static int on_begin_headers_cb(nghttp2_session *ngh2,
                                   const nghttp2_frame *frame, void *userp)
    {
        h2_session *session = (h2_session *)userp;
        h2_stream *s = NULL;
        
        /* We may see HEADERs at the start of a stream or after all DATA
         * streams to carry trailers. */
        (void)ngh2;
        s = get_stream(session, frame->hd.stream_id);
        if (s) {
            /* nop */
        }
        else if (session->local.accepting) {
            s = h2_session_open_stream(userp, frame->hd.stream_id, 0);
        }
        return s? 0 : NGHTTP2_ERR_START_STREAM_NOT_ALLOWED;
    }
    
    static int on_header_cb(nghttp2_session *ngh2, const nghttp2_frame *frame,
                            const uint8_t *name, size_t namelen,
                            const uint8_t *value, size_t valuelen,
                            uint8_t flags,
                            void *userp)
    {
        h2_session *session = (h2_session *)userp;
        h2_stream * stream;
        apr_status_t status;
        
        (void)flags;
        stream = get_stream(session, frame->hd.stream_id);
        if (!stream) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1, APLOGNO(02920)
                          H2_SSSN_STRM_MSG(session, frame->hd.stream_id,
                          "on_header unknown stream"));
            return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
        }
        
        status = h2_stream_add_header(stream, (const char *)name, namelen,
                                      (const char *)value, valuelen);
        if (status != APR_SUCCESS &&
            (!stream->rtmp ||
             stream->rtmp->http_status == H2_HTTP_STATUS_UNSET ||
             /* We accept a certain amount of failures in order to reply
              * with an informative HTTP error response like 413. But of the
              * client is too wrong, we RESET the stream */
             stream->request_headers_failed > 100)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c1,
                          H2_SSSN_STRM_MSG(session, frame->hd.stream_id,
                          "RST stream, header failures: %d"),
                          (int)stream->request_headers_failed);
            return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
        }
        return 0;
    }
    
    /**
     * nghttp2 session has received a complete frame. Most are used by nghttp2
     * for processing of internal state. Some, like HEADER and DATA frames,
     * we need to act on.
     */
    static int on_frame_recv_cb(nghttp2_session *ng2s,
                                const nghttp2_frame *frame,
                                void *userp)
    {
        h2_session *session = (h2_session *)userp;
        h2_stream *stream;
        apr_status_t rv = APR_SUCCESS;
        
        stream = frame->hd.stream_id? get_stream(session, frame->hd.stream_id) : NULL;
        if (APLOGcdebug(session->c1)) {
            char buffer[256];
    
            h2_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
            if (stream) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                              H2_STRM_LOG(APLOGNO(10302), stream,
                              "recv FRAME[%s], frames=%ld/%ld (r/s)"),
                              buffer, (long)session->frames_received,
                             (long)session->frames_sent);
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                              H2_SSSN_LOG(APLOGNO(03066), session,
                              "recv FRAME[%s], frames=%ld/%ld (r/s), "
                              "remote.emitted=%d"),
                              buffer, (long)session->frames_received,
                             (long)session->frames_sent,
                             (int)session->remote.emitted_count);
            }
        }
    
        ++session->frames_received;
        switch (frame->hd.type) {
            case NGHTTP2_HEADERS:
                /* This can be HEADERS for a new stream, defining the request,
                 * or HEADER may come after DATA at the end of a stream as in
                 * trailers */
                if (stream) {
                    rv = h2_stream_recv_frame(stream, NGHTTP2_HEADERS, frame->hd.flags, 
                        frame->hd.length + H2_FRAME_HDR_LEN);
                }
                break;
            case NGHTTP2_DATA:
                if (stream) {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                                  H2_STRM_LOG(APLOGNO(02923), stream, 
                                  "DATA, len=%ld, flags=%d"), 
                                  (long)frame->hd.length, frame->hd.flags);
                    rv = h2_stream_recv_frame(stream, NGHTTP2_DATA, frame->hd.flags, 
                        frame->hd.length + H2_FRAME_HDR_LEN);
                }
                break;
            case NGHTTP2_PRIORITY:
                session->reprioritize = 1;
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                              H2_SSSN_STRM_MSG(session, frame->hd.stream_id, "PRIORITY frame "
                              " weight=%d, dependsOn=%d, exclusive=%d"),
                              frame->priority.pri_spec.weight,
                              frame->priority.pri_spec.stream_id,
                              frame->priority.pri_spec.exclusive);
                break;
            case NGHTTP2_WINDOW_UPDATE:
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                              H2_SSSN_STRM_MSG(session, frame->hd.stream_id,
                              "WINDOW_UPDATE incr=%d"),
                              frame->window_update.window_size_increment);
                break;
            case NGHTTP2_RST_STREAM:
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1, APLOGNO(03067)
                              H2_SSSN_STRM_MSG(session, frame->hd.stream_id,
                              "RST_STREAM by client, error=%d"),
                              (int)frame->rst_stream.error_code);
                if (stream) {
                    rv = h2_stream_recv_frame(stream, NGHTTP2_RST_STREAM, frame->hd.flags,
                        frame->hd.length + H2_FRAME_HDR_LEN);
                }
                if (stream && stream->initiated_on) {
                    /* A stream reset on a request we sent it. Normal, when the
                     * client does not want it. */
                    ++session->pushes_reset;
                }
                else {
                    /* A stream reset on a request it sent us. Could happen in a browser
                     * when the user navigates away or cancels loading - maybe. */
                    h2_mplx_c1_client_rst(session->mplx, frame->hd.stream_id,
                                          stream);
                }
                ++session->streams_reset;
                break;
            case NGHTTP2_GOAWAY:
                if (frame->goaway.error_code == 0 
                    && frame->goaway.last_stream_id == ((1u << 31) - 1)) {
                    /* shutdown notice. Should not come from a client... */
                    session->remote.accepting = 0;
                }
                else {
                    session->remote.accepted_max = frame->goaway.last_stream_id;
                    h2_session_dispatch_event(session, H2_SESSION_EV_REMOTE_GOAWAY,
                                   frame->goaway.error_code, NULL);
                }
                break;
            case NGHTTP2_SETTINGS:
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                              H2_SSSN_MSG(session, "SETTINGS, len=%ld"), (long)frame->hd.length);
                break;
            default:
                if (APLOGctrace2(session->c1)) {
                    char buffer[256];
                    
                    h2_util_frame_print(frame, buffer,
                                        sizeof(buffer)/sizeof(buffer[0]));
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                                  H2_SSSN_MSG(session, "on_frame_rcv %s"), buffer);
                }
                break;
        }
        
        if (session->state == H2_SESSION_ST_IDLE) {
            /* We received a frame, but session is in state IDLE. That means the frame
             * did not really progress any of the (possibly) open streams. It was a meta
             * frame, e.g. SETTINGS/WINDOW_UPDATE/unknown/etc.
             * Remember: IDLE means we cannot send because either there are no streams open or
             * all open streams are blocked on exhausted WINDOWs for outgoing data.
             * The more frames we receive that do not change this, the less interested we
             * become in serving this connection. This is expressed in increasing "idle_delays".
             * Eventually, the connection will timeout and we'll close it. */
            session->idle_frames = H2MIN(session->idle_frames + 1, session->frames_received);
                ap_log_cerror( APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                              H2_SSSN_MSG(session, "session has %ld idle frames"), 
                              (long)session->idle_frames);
            if (session->idle_frames > 10) {
                apr_size_t busy_frames = H2MAX(session->frames_received - session->idle_frames, 1);
                int idle_ratio = (int)(session->idle_frames / busy_frames); 
                if (idle_ratio > 100) {
                    session->idle_delay = apr_time_from_msec(H2MIN(1000, idle_ratio));
                }
                else if (idle_ratio > 10) {
                    session->idle_delay = apr_time_from_msec(10);
                }
                else if (idle_ratio > 1) {
                    session->idle_delay = apr_time_from_msec(1);
                }
                else {
                    session->idle_delay = 0;
                }
            }
        }
        
        if (APR_SUCCESS != rv) return NGHTTP2_ERR_PROTO;
        return 0;
    }
    
    static char immortal_zeros[H2_MAX_PADLEN];
    
    static int on_send_data_cb(nghttp2_session *ngh2, 
                               nghttp2_frame *frame, 
                               const uint8_t *framehd, 
                               size_t length, 
                               nghttp2_data_source *source, 
                               void *userp)
    {
        apr_status_t status = APR_SUCCESS;
        h2_session *session = (h2_session *)userp;
        int stream_id = (int)frame->hd.stream_id;
        unsigned char padlen;
        int eos;
        h2_stream *stream;
        apr_bucket *b;
        apr_off_t len = length;
        
        (void)ngh2;
        (void)source;
        ap_assert(frame->data.padlen <= (H2_MAX_PADLEN+1));
        padlen = (unsigned char)frame->data.padlen;
        
        stream = get_stream(session, stream_id);
        if (!stream) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_NOTFOUND, session->c1,
                          APLOGNO(02924) 
                          H2_SSSN_STRM_MSG(session, stream_id, "send_data, stream not found"));
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                      H2_STRM_MSG(stream, "send_data_cb for %ld bytes"),
                      (long)length);
                      
        status = h2_c1_io_add_data(&session->io, (const char *)framehd, H2_FRAME_HDR_LEN);
        if (padlen && status == APR_SUCCESS) {
            --padlen;
            status = h2_c1_io_add_data(&session->io, (const char *)&padlen, 1);
        }
        
        if (status != APR_SUCCESS) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, session->c1,
                          H2_STRM_MSG(stream, "writing frame header"));
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        
        status = h2_stream_read_to(stream, session->bbtmp, &len, &eos);
        if (status != APR_SUCCESS) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, session->c1,
                          H2_STRM_MSG(stream, "send_data_cb, reading stream"));
            apr_brigade_cleanup(session->bbtmp);
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        else if (len != (apr_off_t)length) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, session->c1,
                          H2_STRM_MSG(stream, "send_data_cb, wanted %ld bytes, "
                          "got %ld from stream"), (long)length, (long)len);
            apr_brigade_cleanup(session->bbtmp);
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        
        if (padlen) {
            b = apr_bucket_immortal_create(immortal_zeros, padlen, 
                                           session->c1->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(session->bbtmp, b);
        }
        
        status = h2_c1_io_append(&session->io, session->bbtmp);
        apr_brigade_cleanup(session->bbtmp);
        
        if (status == APR_SUCCESS) {
            stream->out_data_frames++;
            stream->out_data_octets += length;
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                          H2_STRM_MSG(stream, "sent data length=%ld, total=%ld"),
                          (long)length, (long)stream->out_data_octets);
            return 0;
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c1,
                          H2_STRM_LOG(APLOGNO(02925), stream, "failed send_data_cb"));
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
    }
    
    static int on_frame_send_cb(nghttp2_session *ngh2, 
                                const nghttp2_frame *frame,
                                void *user_data)
    {
        h2_session *session = user_data;
        h2_stream *stream;
        int stream_id = frame->hd.stream_id;
        
        ++session->frames_sent;
        switch (frame->hd.type) {
            case NGHTTP2_PUSH_PROMISE:
                /* PUSH_PROMISE we report on the promised stream */
                stream_id = frame->push_promise.promised_stream_id;
                break;
            default:    
                break;
        }
        
        stream = get_stream(session, stream_id);
        if (APLOGcdebug(session->c1)) {
            char buffer[256];
            
            h2_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
            if (stream) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                              H2_STRM_LOG(APLOGNO(10303), stream,
                              "sent FRAME[%s], frames=%ld/%ld (r/s)"),
                              buffer, (long)session->frames_received,
                             (long)session->frames_sent);
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                              H2_SSSN_LOG(APLOGNO(03068), session,
                              "sent FRAME[%s], frames=%ld/%ld (r/s)"),
                              buffer, (long)session->frames_received,
                             (long)session->frames_sent);
            }
        }
        
        if (stream) {
            h2_stream_send_frame(stream, frame->hd.type, frame->hd.flags, 
                frame->hd.length + H2_FRAME_HDR_LEN);
        }
        return 0;
    }
    
    static int on_frame_not_send_cb(nghttp2_session *ngh2,
                                const nghttp2_frame *frame,
                                int ngh2_err,
                                void *user_data)
    {
        h2_session *session = user_data;
        int stream_id = frame->hd.stream_id;
        h2_stream *stream;
        char buffer[256];
    
        stream = get_stream(session, stream_id);
        h2_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, session->c1,
                      H2_SSSN_LOG(APLOGNO(10509), session,
                      "not sent FRAME[%s], error %d: %s"),
                      buffer, ngh2_err, nghttp2_strerror(ngh2_err));
        if(stream) {
            h2_stream_rst(stream, NGHTTP2_PROTOCOL_ERROR);
            return 0;
        }
        return NGHTTP2_ERR_CALLBACK_FAILURE;
    }
    
    #ifdef H2_NG2_INVALID_HEADER_CB
    static int on_invalid_header_cb(nghttp2_session *ngh2,
                                    const nghttp2_frame *frame, 
                                    const uint8_t *name, size_t namelen, 
                                    const uint8_t *value, size_t valuelen, 
                                    uint8_t flags, void *user_data)
    {
        h2_session *session = user_data;
        h2_stream *stream;
        
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1, APLOGNO(03456)
                      H2_SSSN_STRM_MSG(session, frame->hd.stream_id,
                      "invalid header '%.*s: %.*s'"),
                      (int)namelen, name, (int)valuelen, value);
        stream = get_stream(session, frame->hd.stream_id);
        if (stream) {
            h2_stream_rst(stream, NGHTTP2_PROTOCOL_ERROR);
        }
        return 0;
    }
    #endif
    
    static ssize_t select_padding_cb(nghttp2_session *ngh2, 
                                     const nghttp2_frame *frame, 
                                     size_t max_payloadlen, void *user_data)
    {
        h2_session *session = user_data;
        size_t frame_len = frame->hd.length + H2_FRAME_HDR_LEN; /* the total length without padding */
        size_t padded_len = frame_len;
    
        /* Determine # of padding bytes to append to frame. Unless session->padding_always
         * the number my be capped by the ui.write_size that currently applies. 
         */
        if (session->padding_max) {
            int n = ap_random_pick(0, session->padding_max);
            padded_len = H2MIN(max_payloadlen + H2_FRAME_HDR_LEN, frame_len + n); 
        }
    
        if (padded_len != frame_len) {
            if (!session->padding_always && session->io.write_size 
                && (padded_len > session->io.write_size)
                && (frame_len <= session->io.write_size)) {
                padded_len = session->io.write_size;
            }
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                          "select padding from [%d, %d]: %d (frame length: 0x%04x, write size: %d)",
                          (int)frame_len, (int)max_payloadlen+H2_FRAME_HDR_LEN,
                          (int)(padded_len - frame_len), (int)padded_len, (int)session->io.write_size);
            return padded_len - H2_FRAME_HDR_LEN;
        }
        return frame->hd.length;
    }
    
    #define NGH2_SET_CALLBACK(callbacks, name, fn)\
    nghttp2_session_callbacks_set_##name##_callback(callbacks, fn)
    
    static apr_status_t init_callbacks(conn_rec *c, nghttp2_session_callbacks **pcb)
    {
        int rv = nghttp2_session_callbacks_new(pcb);
        if (rv != 0) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
                          APLOGNO(02926) "nghttp2_session_callbacks_new: %s",
                          nghttp2_strerror(rv));
            return APR_EGENERAL;
        }
        
        NGH2_SET_CALLBACK(*pcb, send, send_cb);
        NGH2_SET_CALLBACK(*pcb, on_frame_recv, on_frame_recv_cb);
        NGH2_SET_CALLBACK(*pcb, on_invalid_frame_recv, on_invalid_frame_recv_cb);
        NGH2_SET_CALLBACK(*pcb, on_data_chunk_recv, on_data_chunk_recv_cb);
        NGH2_SET_CALLBACK(*pcb, on_stream_close, on_stream_close_cb);
        NGH2_SET_CALLBACK(*pcb, on_begin_headers, on_begin_headers_cb);
        NGH2_SET_CALLBACK(*pcb, on_header, on_header_cb);
        NGH2_SET_CALLBACK(*pcb, send_data, on_send_data_cb);
        NGH2_SET_CALLBACK(*pcb, on_frame_send, on_frame_send_cb);
        NGH2_SET_CALLBACK(*pcb, on_frame_not_send, on_frame_not_send_cb);
    #ifdef H2_NG2_INVALID_HEADER_CB
        NGH2_SET_CALLBACK(*pcb, on_invalid_header, on_invalid_header_cb);
    #endif
        NGH2_SET_CALLBACK(*pcb, select_padding, select_padding_cb);
        return APR_SUCCESS;
    }
    
    static void update_child_status(h2_session *session, int status,
                                    const char *msg, const h2_stream *stream)
    {
        /* Assume that we also change code/msg when something really happened and
         * avoid updating the scoreboard in between */
        if (session->last_status_code != status
            || session->last_status_msg != msg) {
            char sbuffer[1024];
            sbuffer[0] = '\0';
            if (stream) {
                apr_snprintf(sbuffer, sizeof(sbuffer),
                             ": stream %d, %s %s",
                             stream->id,
                             stream->request? stream->request->method : "",
                             stream->request? stream->request->path : "");
            }
            apr_snprintf(session->status, sizeof(session->status),
                         "[%d/%d] %s%s",
                         (int)(session->remote.emitted_count + session->pushes_submitted),
                         (int)session->streams_done,
                         msg? msg : "-", sbuffer);
            ap_update_child_status_from_server(session->c1->sbh, status,
                                               session->c1, session->s);
            ap_update_child_status_descr(session->c1->sbh, status, session->status);
        }
    }
    
    static apr_status_t h2_session_shutdown_notice(h2_session *session)
    {
        apr_status_t status;
        
        ap_assert(session);
        if (!session->local.accepting) {
            return APR_SUCCESS;
        }
        
        nghttp2_submit_shutdown_notice(session->ngh2);
        session->local.accepting = 0;
        status = nghttp2_session_send(session->ngh2);
        if (status == APR_SUCCESS) {
            status = h2_c1_io_assure_flushed(&session->io);
        }
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                      H2_SSSN_LOG(APLOGNO(03457), session, "sent shutdown notice"));
        return status;
    }
    
    static apr_status_t h2_session_shutdown(h2_session *session, int error, 
                                            const char *msg, int force_close)
    {
        apr_status_t status = APR_SUCCESS;
        
        ap_assert(session);
        if (session->local.shutdown) {
            return APR_SUCCESS;
        }
    
        if (error && !msg) {
            if (APR_STATUS_IS_EPIPE(error)) {
                msg = "remote close";
            }
        }
    
        if (error || force_close) {
            /* not a graceful shutdown, we want to leave... 
             * Do not start further streams that are waiting to be scheduled. 
             * Find out the max stream id that we habe been processed or
             * are still actively working on.
             * Remove all streams greater than this number without submitting
             * a RST_STREAM frame, since that should be clear from the GOAWAY
             * we send. */
            session->local.accepted_max = h2_mplx_c1_shutdown(session->mplx);
            session->local.error = error;
            session->local.error_msg = msg;
        }
        else {
            /* graceful shutdown. we will continue processing all streams
             * we have, but no longer accept new ones. Report the max stream
             * we have received and discard all new ones. */
        }
        
        session->local.accepting = 0;
        session->local.shutdown = 1;
        if (!session->c1->aborted) {
            nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, 
                                  session->local.accepted_max, 
                                  error, (uint8_t*)msg, msg? strlen(msg):0);
            status = nghttp2_session_send(session->ngh2);
            if (status == APR_SUCCESS) {
                status = h2_c1_io_assure_flushed(&session->io);
            }
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                          H2_SSSN_LOG(APLOGNO(03069), session, 
                                      "sent GOAWAY, err=%d, msg=%s"), error, msg? msg : "");
        }
        h2_session_dispatch_event(session, H2_SESSION_EV_LOCAL_GOAWAY, error, msg);
        return status;
    }
    
    static apr_status_t session_cleanup(h2_session *session, const char *trigger)
    {
        conn_rec *c = session->c1;
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                      H2_SSSN_MSG(session, "pool_cleanup"));
        
        if (session->state != H2_SESSION_ST_DONE
            && session->state != H2_SESSION_ST_INIT) {
            /* Not good. The connection is being torn down and we have
             * not sent a goaway. This is considered a protocol error and
             * the client has to assume that any streams "in flight" may have
             * been processed and are not safe to retry.
             * As clients with idle connection may only learn about a closed
             * connection when sending the next request, this has the effect
             * that at least this one request will fail.
             */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
                          H2_SSSN_LOG(APLOGNO(03199), session, 
                          "connection disappeared without proper "
                          "goodbye, clients will be confused, should not happen"));
        }
    
        if (!h2_iq_empty(session->ready_to_process)) {
            int sid;
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
                          H2_SSSN_LOG(APLOGNO(10485), session,
                          "cleanup, resetting %d streams in ready-to-process"),
                          h2_iq_count(session->ready_to_process));
            while ((sid = h2_iq_shift(session->ready_to_process)) > 0) {
              h2_mplx_c1_client_rst(session->mplx, sid, get_stream(session, sid));
            }
        }
    
        transit(session, trigger, H2_SESSION_ST_CLEANUP);
        h2_mplx_c1_destroy(session->mplx);
        session->mplx = NULL;
    
        ap_assert(session->ngh2);
        nghttp2_session_del(session->ngh2);
        session->ngh2 = NULL;
        h2_conn_ctx_detach(c);
    
        return APR_SUCCESS;
    }
    
    static apr_status_t session_pool_cleanup(void *data)
    {
        conn_rec *c = data;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
        h2_session *session = conn_ctx? conn_ctx->session : NULL;
    
        if (session) {
            int mpm_state = 0;
            int level;
    
            ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state);
            level = (AP_MPMQ_STOPPING == mpm_state)? APLOG_DEBUG : APLOG_WARNING;
            /* if the session is still there, now is the last chance
             * to perform cleanup. Normally, cleanup should have happened
             * earlier in the connection pre_close.
             * However, when the server is stopping, it may shutdown connections
             * without running the pre_close hooks. Do not want about that. */
            ap_log_cerror(APLOG_MARK, level, 0, c,
                          H2_SSSN_LOG(APLOGNO(10020), session,
                          "session cleanup triggered by pool cleanup. "
                          "this should have happened earlier already."));
            return session_cleanup(session, "pool cleanup");
        }
        return APR_SUCCESS;
    }
    
    static /* atomic */ apr_uint32_t next_id;
    
    apr_status_t h2_session_create(h2_session **psession, conn_rec *c, request_rec *r,
                                   server_rec *s, h2_workers *workers)
    {
        nghttp2_session_callbacks *callbacks = NULL;
        nghttp2_option *options = NULL;
        uint32_t n;
        int thread_num;
        apr_pool_t *pool = NULL;
        h2_session *session;
        h2_stream *stream0;
        apr_status_t status;
        int rv;
    
        *psession = NULL;
        apr_pool_create(&pool, c->pool);
        apr_pool_tag(pool, "h2_session");
        session = apr_pcalloc(pool, sizeof(h2_session));
        if (!session) {
            return APR_ENOMEM;
        }
        
        *psession = session;
        /* c->id does not give a unique id for the lifetime of the session.
         * mpms like event change c->id when re-activating a keepalive
         * connection based on the child_num+thread_num of the worker
         * processing it.
         * We'd like to have an id that remains constant and unique bc
         * h2 streams can live through keepalive periods. While double id
         * will not lead to processing failures, it will confuse log analysis.
         */
    #if AP_MODULE_MAGIC_AT_LEAST(20211221, 8)
        ap_sb_get_child_thread(c->sbh, &session->child_num, &thread_num);
    #else
        (void)thread_num;
        session->child_num = (int)getpid();
    #endif
        session->id = apr_atomic_inc32(&next_id);
        session->c1 = c;
        session->r = r;
        session->s = s;
        session->pool = pool;
        session->workers = workers;
        
        session->state = H2_SESSION_ST_INIT;
        session->local.accepting = 1;
        session->remote.accepting = 1;
        
        session->max_stream_count = h2_config_sgeti(s, H2_CONF_MAX_STREAMS);
        session->max_stream_mem = h2_config_sgeti(s, H2_CONF_STREAM_MAX_MEM);
        session->max_data_frame_len = h2_config_sgeti(s, H2_CONF_MAX_DATA_FRAME_LEN);
    
        session->out_c1_blocked = h2_iq_create(session->pool, (int)session->max_stream_count);
        session->ready_to_process = h2_iq_create(session->pool, (int)session->max_stream_count);
    
        session->monitor = apr_pcalloc(pool, sizeof(h2_stream_monitor));
        session->monitor->ctx = session;
        session->monitor->on_state_enter = on_stream_state_enter;
        session->monitor->on_state_event = on_stream_state_event;
        session->monitor->on_event = on_stream_event;
    
        stream0 = h2_stream_create(0, session->pool, session, NULL, 0);
        stream0->c2 = session->c1;  /* stream0's connection is the main connection */
        session->mplx = h2_mplx_c1_create(session->child_num, session->id,
                                          stream0, s, session->pool, workers);
        if (!session->mplx) {
            apr_pool_destroy(pool);
            return APR_ENOTIMPL;
        }
    
        h2_c1_io_init(&session->io, session);
        /* setup request header scratch buffers */
        session->hd_scratch.max_len = session->s->limit_req_fieldsize?
            session->s->limit_req_fieldsize : 8190;
        session->hd_scratch.name =
            apr_pcalloc(session->pool, session->hd_scratch.max_len + 1);
        session->hd_scratch.value =
            apr_pcalloc(session->pool, session->hd_scratch.max_len + 1);
    
        session->padding_max = h2_config_sgeti(s, H2_CONF_PADDING_BITS);
        if (session->padding_max) {
            session->padding_max = (0x01 << session->padding_max) - 1; 
        }
        session->padding_always = h2_config_sgeti(s, H2_CONF_PADDING_ALWAYS);
        session->bbtmp = apr_brigade_create(session->pool, c->bucket_alloc);
        
        status = init_callbacks(c, &callbacks);
        if (status != APR_SUCCESS) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, status, c, APLOGNO(02927) 
                          "nghttp2: error in init_callbacks");
            apr_pool_destroy(pool);
            return status;
        }
        
        rv = nghttp2_option_new(&options);
        if (rv != 0) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c,
                          APLOGNO(02928) "nghttp2_option_new: %s", 
                          nghttp2_strerror(rv));
            apr_pool_destroy(pool);
            return status;
        }
        nghttp2_option_set_peer_max_concurrent_streams(options, (uint32_t)session->max_stream_count);
        /* We need to handle window updates ourself, otherwise we
         * get flooded by nghttp2. */
        nghttp2_option_set_no_auto_window_update(options, 1);
    #ifdef H2_NG2_NO_CLOSED_STREAMS
        /* We do not want nghttp2 to keep information about closed streams as
         * that accumulates memory on long connections. This makes PRIORITY
         * setting in relation to older streams non-working. */
        nghttp2_option_set_no_closed_streams(options, 1);
    #endif
    #ifdef H2_NG2_RFC9113_STRICTNESS
        /* nghttp2 v1.50.0 introduces the strictness checks on leading/trailing
         * whitespace of RFC 9113 for fields. But, by default, it RST streams
         * carrying such. We do not want that. We want to strip the ws and
         * handle them, just like the HTTP/1.1 parser does. */
        nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(options, 1);
    #endif
    
        if(h2_config_sgeti(s, H2_CONF_MAX_HEADER_BLOCK_LEN) > 0)
            nghttp2_option_set_max_send_header_block_length(options,
                h2_config_sgeti(s, H2_CONF_MAX_HEADER_BLOCK_LEN));
    
        rv = nghttp2_session_server_new2(&session->ngh2, callbacks,
                                         session, options);
        nghttp2_session_callbacks_del(callbacks);
        nghttp2_option_del(options);
        
        if (rv != 0) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c,
                          APLOGNO(02929) "nghttp2_session_server_new: %s",
                          nghttp2_strerror(rv));
            apr_pool_destroy(pool);
            return APR_ENOMEM;
        }
        
        n = h2_config_sgeti(s, H2_CONF_PUSH_DIARY_SIZE);
        session->push_diary = h2_push_diary_create(session->pool, n);
    
        if (APLOGcdebug(c)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, 
                          H2_SSSN_LOG(APLOGNO(03200), session, 
                                      "created, max_streams=%d, stream_mem=%d, "
                                      "workers_limit=%d, workers_max=%d, "
                                      "push_diary(type=%d,N=%d), "
                                      "max_data_frame_len=%d"),
                          (int)session->max_stream_count, 
                          (int)session->max_stream_mem,
                          session->mplx->processing_limit,
                          session->mplx->processing_max,
                          session->push_diary->dtype, 
                          (int)session->push_diary->N,
                          (int)session->max_data_frame_len);
        }
        
        apr_pool_pre_cleanup_register(pool, c, session_pool_cleanup);
            
        return APR_SUCCESS;
    }
    
    static apr_status_t h2_session_start(h2_session *session, int *rv)
    {
        apr_status_t status = APR_SUCCESS;
        nghttp2_settings_entry settings[4];
        size_t slen;
        int win_size;
        
        ap_assert(session);
        /* Start the conversation by submitting our SETTINGS frame */
        *rv = 0;
        if (session->r) {
            const char *s, *cs;
            apr_size_t dlen; 
            h2_stream * stream;
    
            /* 'h2c' mode: we should have a 'HTTP2-Settings' header with
             * base64 encoded client settings. */
            s = apr_table_get(session->r->headers_in, "HTTP2-Settings");
            if (!s) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EINVAL, session->r,
                              APLOGNO(02931) 
                              "HTTP2-Settings header missing in request");
                return APR_EINVAL;
            }
            cs = NULL;
            dlen = h2_util_base64url_decode(&cs, s, session->pool);
            
            if (APLOGrdebug(session->r)) {
                char buffer[128];
                h2_util_hex_dump(buffer, 128, (char*)cs, dlen);
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, session->r, APLOGNO(03070)
                              "upgrading h2c session with HTTP2-Settings: %s -> %s (%d)",
                              s, buffer, (int)dlen);
            }
            
            *rv = nghttp2_session_upgrade(session->ngh2, (uint8_t*)cs, dlen, NULL);
            if (*rv != 0) {
                status = APR_EINVAL;
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, session->r,
                              APLOGNO(02932) "nghttp2_session_upgrade: %s", 
                              nghttp2_strerror(*rv));
                return status;
            }
            
            /* Now we need to auto-open stream 1 for the request we got. */
            stream = h2_session_open_stream(session, 1, 0);
            if (!stream) {
                status = APR_EGENERAL;
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, session->r,
                              APLOGNO(02933) "open stream 1: %s", 
                              nghttp2_strerror(*rv));
                return status;
            }
            
            status = h2_stream_set_request_rec(stream, session->r, 1);
            if (status != APR_SUCCESS) {
                return status;
            }
        }
    
        slen = 0;
        settings[slen].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
        settings[slen].value = (uint32_t)session->max_stream_count;
        ++slen;
        win_size = h2_config_sgeti(session->s, H2_CONF_WIN_SIZE);
        if (win_size != H2_INITIAL_WINDOW_SIZE) {
            settings[slen].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
            settings[slen].value = win_size;
            ++slen;
        }
    #if H2_USE_WEBSOCKETS
        if (h2_config_sgeti(session->s, H2_CONF_WEBSOCKETS)) {
          settings[slen].settings_id = NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL;
          settings[slen].value = 1;
          ++slen;
        }
    #endif
    
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c1,
                      H2_SSSN_LOG(APLOGNO(03201), session, 
                      "start, INITIAL_WINDOW_SIZE=%ld, MAX_CONCURRENT_STREAMS=%d"), 
                      (long)win_size, (int)session->max_stream_count);
        *rv = nghttp2_submit_settings(session->ngh2, NGHTTP2_FLAG_NONE,
                                      settings, slen);
        if (*rv != 0) {
            status = APR_EGENERAL;
            ap_log_cerror(APLOG_MARK, APLOG_ERR, status, session->c1,
                          H2_SSSN_LOG(APLOGNO(02935), session, 
                          "nghttp2_submit_settings: %s"), nghttp2_strerror(*rv));
        }
        else {
            /* use maximum possible value for connection window size. We are only
             * interested in per stream flow control. which have the initial window
             * size configured above.
             * Therefore, for our use, the connection window can only get in the
             * way. Example: if we allow 100 streams with a 32KB window each, we
             * buffer up to 3.2 MB of data. Unless we do separate connection window
             * interim updates, any smaller connection window will lead to blocking
             * in DATA flow.
             */
            *rv = nghttp2_session_set_local_window_size(
                session->ngh2, NGHTTP2_FLAG_NONE, 0, NGHTTP2_MAX_WINDOW_SIZE);
            if (*rv != 0) {
                status = APR_EGENERAL;
                ap_log_cerror(APLOG_MARK, APLOG_ERR, status, session->c1,
                              H2_SSSN_LOG(APLOGNO(02970), session,
                              "nghttp2_session_set_local_window_size: %s"),
                              nghttp2_strerror(*rv));        
            }
        }
        
        return status;
    }
    
    struct h2_stream *h2_session_push(h2_session *session, h2_stream *is,
                                      h2_push *push)
    {
        h2_stream *stream;
        h2_ngheader *ngh;
        apr_status_t status;
        int nid = 0;
        
        status = h2_req_create_ngheader(&ngh, is->pool, push->req);
        if (status == APR_SUCCESS) {
            nid = nghttp2_submit_push_promise(session->ngh2, 0, is->id, 
                                              ngh->nv, ngh->nvlen, NULL);
        }
        if (status != APR_SUCCESS || nid <= 0) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c1,
                          H2_STRM_LOG(APLOGNO(03075), is, 
                          "submitting push promise fail: %s"), nghttp2_strerror(nid));
            return NULL;
        }
        ++session->pushes_promised;
        
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                      H2_STRM_LOG(APLOGNO(03076), is, "SERVER_PUSH %d for %s %s on %d"),
                      nid, push->req->method, push->req->path, is->id);
                      
        stream = h2_session_open_stream(session, nid, is->id);
        if (!stream) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                          H2_STRM_LOG(APLOGNO(03077), is,
                          "failed to create stream obj %d"), nid);
            /* kill the push_promise */
            nghttp2_submit_rst_stream(session->ngh2, NGHTTP2_FLAG_NONE, nid,
                                      NGHTTP2_INTERNAL_ERROR);
            return NULL;
        }
        
        h2_session_set_prio(session, stream, push->priority);
        h2_stream_set_request(stream, push->req);
        return stream;
    }
    
    static int valid_weight(float f) 
    {
        int w = (int)f;
        return (w < NGHTTP2_MIN_WEIGHT? NGHTTP2_MIN_WEIGHT : 
                (w > NGHTTP2_MAX_WEIGHT)? NGHTTP2_MAX_WEIGHT : w);
    }
    
    apr_status_t h2_session_set_prio(h2_session *session, h2_stream *stream, 
                                     const h2_priority *prio)
    {
        apr_status_t status = APR_SUCCESS;
        nghttp2_stream *s_grandpa, *s_parent, *s;
        
        if (prio == NULL) {
            /* we treat this as a NOP */
            return APR_SUCCESS;
        }
        s = nghttp2_session_find_stream(session->ngh2, stream->id);
        if (!s) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c1,
                          H2_STRM_MSG(stream, "lookup of nghttp2_stream failed"));
            return APR_EINVAL;
        }
        
        s_parent = nghttp2_stream_get_parent(s);
        if (s_parent) {
            nghttp2_priority_spec ps;
            int id_parent, id_grandpa, w_parent, w;
            int rv = 0;
            const char *ptype = "AFTER";
            h2_dependency dep = prio->dependency;
            
            id_parent = nghttp2_stream_get_stream_id(s_parent);
            s_grandpa = nghttp2_stream_get_parent(s_parent);
            if (s_grandpa) {
                id_grandpa = nghttp2_stream_get_stream_id(s_grandpa);
            }
            else {
                /* parent of parent does not exist, 
                 * only possible if parent == root */
                dep = H2_DEPENDANT_AFTER;
            }
            
            switch (dep) {
                case H2_DEPENDANT_INTERLEAVED:
                    /* PUSHed stream is to be interleaved with initiating stream.
                     * It is made a sibling of the initiating stream and gets a
                     * proportional weight [1, MAX_WEIGHT] of the initiaing
                     * stream weight.
                     */
                    ptype = "INTERLEAVED";
                    w_parent = nghttp2_stream_get_weight(s_parent);
                    w = valid_weight(w_parent * ((float)prio->weight / NGHTTP2_MAX_WEIGHT));
                    nghttp2_priority_spec_init(&ps, id_grandpa, w, 0);
                    break;
                    
                case H2_DEPENDANT_BEFORE:
                    /* PUSHed stream os to be sent BEFORE the initiating stream.
                     * It gets the same weight as the initiating stream, replaces
                     * that stream in the dependency tree and has the initiating
                     * stream as child.
                     */
                    ptype = "BEFORE";
                    w = w_parent = nghttp2_stream_get_weight(s_parent);
                    nghttp2_priority_spec_init(&ps, stream->id, w_parent, 0);
                    id_grandpa = nghttp2_stream_get_stream_id(s_grandpa);
                    rv = nghttp2_session_change_stream_priority(session->ngh2, id_parent, &ps);
                    if (rv < 0) {
                        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1, APLOGNO(03202)
                                      H2_SSSN_STRM_MSG(session, id_parent,
                                      "PUSH BEFORE, weight=%d, depends=%d, returned=%d"),
                                      ps.weight, ps.stream_id, rv);
                        return APR_EGENERAL;
                    }
                    nghttp2_priority_spec_init(&ps, id_grandpa, w, 0);
                    break;
                    
                case H2_DEPENDANT_AFTER:
                    /* The PUSHed stream is to be sent after the initiating stream.
                     * Give if the specified weight and let it depend on the intiating
                     * stream.
                     */
                    /* fall through, it's the default */
                default:
                    nghttp2_priority_spec_init(&ps, id_parent, valid_weight(prio->weight), 0);
                    break;
            }
    
    
            rv = nghttp2_session_change_stream_priority(session->ngh2, stream->id, &ps);
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                          H2_STRM_LOG(APLOGNO(03203), stream, 
                          "PUSH %s, weight=%d, depends=%d, returned=%d"),
                          ptype, ps.weight, ps.stream_id, rv);
            status = (rv < 0)? APR_EGENERAL : APR_SUCCESS;
        }
    
        return status;
    }
    
    int h2_session_push_enabled(h2_session *session)
    {
        /* iff we can and they can and want */
        return (session->remote.accepting /* remote GOAWAY received */
                && h2_config_sgeti(session->s, H2_CONF_PUSH)
                && nghttp2_session_get_remote_settings(session->ngh2, 
                       NGHTTP2_SETTINGS_ENABLE_PUSH));
    }
    
    static int h2_session_want_send(h2_session *session)
    {
        return nghttp2_session_want_write(session->ngh2)
            || h2_c1_io_pending(&session->io);
    }
    
    static apr_status_t h2_session_send(h2_session *session)
    {
        int ngrv, pending = 0;
        apr_status_t rv = APR_SUCCESS;
    
        while (nghttp2_session_want_write(session->ngh2)) {
            ngrv = nghttp2_session_send(session->ngh2);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                          "nghttp2_session_send: %d", (int)ngrv);
            pending = 1;
            if (ngrv != 0 && ngrv != NGHTTP2_ERR_WOULDBLOCK) {
                if (nghttp2_is_fatal(ngrv)) {
                    h2_session_dispatch_event(session, H2_SESSION_EV_PROTO_ERROR,
                                   ngrv, nghttp2_strerror(ngrv));
                    rv = APR_EGENERAL;
                    goto cleanup;
                }
            }
            if (h2_c1_io_needs_flush(&session->io) ||
                ngrv == NGHTTP2_ERR_WOULDBLOCK) {
                rv = h2_c1_io_assure_flushed(&session->io);
                if (rv != APR_SUCCESS)
                    goto cleanup;
                pending = 0;
            }
        }
        if (pending) {
            rv = h2_c1_io_pass(&session->io);
        }
    cleanup:
        if (rv != APR_SUCCESS) {
            h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, rv, NULL);
        }
        return rv;
    }
    
    /**
     * A streams input state has changed.
     */
    static void on_stream_input(void *ctx, h2_stream *stream)
    {
        h2_session *session = ctx;
    
        ap_assert(stream);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                      H2_STRM_MSG(stream, "on_input change"));
        update_child_status(session, SERVER_BUSY_READ, "read", stream);
        if (stream->id == 0) {
            /* input on primary connection available? read */
            h2_c1_read(session);
        }
        else {
            h2_stream_on_input_change(stream);
        }
    }
    
    /**
     * A streams output state has changed.
     */
    static void on_stream_output(void *ctx, h2_stream *stream)
    {
        h2_session *session = ctx;
    
        ap_assert(stream);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                      H2_STRM_MSG(stream, "on_output change"));
        if (stream->id != 0) {
            update_child_status(session, SERVER_BUSY_WRITE, "write", stream);
            h2_stream_on_output_change(stream);
        }
    }
    
    
    static const char *StateNames[] = {
        "INIT",      /* H2_SESSION_ST_INIT */
        "DONE",      /* H2_SESSION_ST_DONE */
        "IDLE",      /* H2_SESSION_ST_IDLE */
        "BUSY",      /* H2_SESSION_ST_BUSY */
        "WAIT",      /* H2_SESSION_ST_WAIT */
        "CLEANUP",   /* H2_SESSION_ST_CLEANUP */
    };
    
    const char *h2_session_state_str(h2_session_state state)
    {
        if (state >= (sizeof(StateNames)/sizeof(StateNames[0]))) {
            return "unknown";
        }
        return StateNames[state];
    }
    
    static void transit(h2_session *session, const char *action, h2_session_state nstate)
    {
        int ostate;
    
        if (session->state != nstate) {
            ostate = session->state;
    
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                          H2_SSSN_LOG(APLOGNO(03078), session, 
                          "transit [%s] -- %s --> [%s]"), 
                          h2_session_state_str(ostate), action, 
                          h2_session_state_str(nstate));
            
            switch (session->state) {
                case H2_SESSION_ST_IDLE:
                    if (!session->remote.emitted_count) {
                        /* on fresh connections, with async mpm, do not return
                         * to mpm for a second. This gives the first request a better
                         * chance to arrive (und connection leaving IDLE state).
                         * If we return to mpm right away, this connection has the
                         * same chance of being cleaned up by the mpm as connections
                         * that already served requests - not fair. */
                        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c1,
                                      H2_SSSN_LOG("", session, "enter idle"));
                    }
                    else {
                        /* normal keepalive setup */
                        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c1,
                                      H2_SSSN_LOG("", session, "enter keepalive"));
                    }
                    session->state = nstate;
                    break;
                case H2_SESSION_ST_DONE:
                    break;
                default:
                    /* nop */
                    session->state = nstate;
                    break;
            }
        }
    }
    
    static void h2_session_ev_init(h2_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_SESSION_ST_INIT:
                transit(session, "init", H2_SESSION_ST_BUSY);
                break;
            default:
                /* nop */
                break;
        }
    }
    
    static void h2_session_ev_input_pending(h2_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_SESSION_ST_INIT:
            case H2_SESSION_ST_IDLE:
            case H2_SESSION_ST_WAIT:
                transit(session, "input read", H2_SESSION_ST_BUSY);
                break;
            default:
                break;
        }
    }
    
    static void h2_session_ev_input_exhausted(h2_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_SESSION_ST_BUSY:
                if (!h2_session_want_send(session)) {
                    if (session->open_streams == 0) {
                        transit(session, "input exhausted, no streams", H2_SESSION_ST_IDLE);
                    }
                    else {
                        transit(session, "input exhausted", H2_SESSION_ST_WAIT);
                    }
                }
                break;
            case H2_SESSION_ST_WAIT:
                if (session->open_streams == 0) {
                    transit(session, "input exhausted, no streams", H2_SESSION_ST_IDLE);
                }
                break;
            default:
                break;
        }
    }
    
    static void h2_session_ev_local_goaway(h2_session *session, int arg, const char *msg)
    {
        cleanup_unprocessed_streams(session);
        transit(session, "local goaway", H2_SESSION_ST_DONE);
    }
    
    static void h2_session_ev_remote_goaway(h2_session *session, int arg, const char *msg)
    {
        if (!session->remote.shutdown) {
            session->remote.error = arg;
            session->remote.accepting = 0;
            session->remote.shutdown = 1;
            cleanup_unprocessed_streams(session);
            transit(session, "remote goaway", H2_SESSION_ST_DONE);
        }
    }
    
    static void h2_session_ev_conn_error(h2_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_SESSION_ST_INIT:
            case H2_SESSION_ST_DONE:
                /* just leave */
                transit(session, "conn error", H2_SESSION_ST_DONE);
                break;
            
            default:
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                              H2_SSSN_LOG(APLOGNO(03401), session, 
                              "conn error -> shutdown, remote.emitted=%d"),
                              (int)session->remote.emitted_count);
                h2_session_shutdown(session, arg, msg, 0);
                break;
        }
    }
    
    static void h2_session_ev_proto_error(h2_session *session, int arg, const char *msg)
    {
        if (!session->local.shutdown) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                          H2_SSSN_LOG(APLOGNO(03402), session, 
                          "proto error -> shutdown"));
            h2_session_shutdown(session, arg, msg, 0);
        }
    }
    
    static void h2_session_ev_conn_timeout(h2_session *session, int arg, const char *msg)
    {
        transit(session, msg, H2_SESSION_ST_DONE);
        if (!session->local.shutdown) {
            h2_session_shutdown(session, arg, msg, 1);
        }
    }
    
    static void h2_session_ev_ngh2_done(h2_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_SESSION_ST_DONE:
                /* nop */
                break;
            default:
                transit(session, "nghttp2 done", H2_SESSION_ST_DONE);
                break;
        }
    }
    
    static void h2_session_ev_mpm_stopping(h2_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_SESSION_ST_DONE:
                /* nop */
                break;
            default:
                h2_session_shutdown_notice(session);
    #if !AP_MODULE_MAGIC_AT_LEAST(20120211, 110)
                h2_workers_graceful_shutdown(session->workers);
    #endif
                break;
        }
    }
    
    static void h2_session_ev_pre_close(h2_session *session, int arg, const char *msg)
    {
        h2_session_shutdown(session, arg, msg, 1);
    }
    
    static void h2_session_ev_no_more_streams(h2_session *session)
    {
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                      H2_SSSN_LOG(APLOGNO(10304), session, "no more streams"));
        switch (session->state) {
            case H2_SESSION_ST_BUSY:
            case H2_SESSION_ST_WAIT:
                if (!h2_session_want_send(session)) {
                    if (session->local.accepting) {
                        /* We wait for new frames on c1 only. */
                        transit(session, "all streams done", H2_SESSION_ST_IDLE);
                    }
                    else {
                        /* We are no longer accepting new streams.
                         * Time to leave. */
                        h2_session_shutdown(session, 0, "done", 0);
                        transit(session, "c1 done after goaway", H2_SESSION_ST_DONE);
                    }
                }
                else {
                    transit(session, "no more streams", H2_SESSION_ST_WAIT);
                }
                break;
            default:
                /* nop */
                break;
        }
    }
    
    static void ev_stream_created(h2_session *session, h2_stream *stream)
    {
        /* nop */
    }
    
    static void ev_stream_open(h2_session *session, h2_stream *stream)
    {
        if (H2_STREAM_CLIENT_INITIATED(stream->id)) {
            if (stream->id > session->remote.accepted_max) {
                session->local.accepted_max = stream->id;
            }
        }
        else {
            if (stream->id > session->local.emitted_max) {
                ++session->local.emitted_count;
                session->remote.emitted_max = stream->id;
            }
        }
        /* Stream state OPEN means we have received all request headers
         * and can start processing the stream. */
        h2_iq_append(session->ready_to_process, stream->id);
        update_child_status(session, SERVER_BUSY_READ, "schedule", stream);
    }
    
    static void ev_stream_closed(h2_session *session, h2_stream *stream)
    {
        apr_bucket *b;
        
        if (H2_STREAM_CLIENT_INITIATED(stream->id)
            && (stream->id > session->local.completed_max)) {
            session->local.completed_max = stream->id;
        }
        /* The stream might have data in the buffers of the main connection.
         * We can only free the allocated resources once all had been written.
         * Send a special buckets on the connection that gets destroyed when
         * all preceding data has been handled. On its destruction, it is safe
         * to purge all resources of the stream. */
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                      H2_STRM_MSG(stream, "adding h2_eos to c1 out"));
        b = h2_bucket_eos_create(session->c1->bucket_alloc, stream);
        APR_BRIGADE_INSERT_TAIL(session->bbtmp, b);
        h2_c1_io_append(&session->io, session->bbtmp);
        apr_brigade_cleanup(session->bbtmp);
    }
    
    static void on_stream_state_enter(void *ctx, h2_stream *stream)
    {
        h2_session *session = ctx;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                      H2_STRM_MSG(stream, "entered state"));
        switch (stream->state) {
            case H2_SS_IDLE: /* stream was created */
                ev_stream_created(session, stream);
                break;
            case H2_SS_OPEN: /* stream has request headers */
            case H2_SS_RSVD_L:
                ev_stream_open(session, stream);
                break;
            case H2_SS_CLOSED_L: /* stream output was closed, but remote end is not */
                /* If the stream is still being processed, it could still be reading
                 * its input (theoretically, http request hangling does not normally).
                 * But when processing is done, we need to cancel the stream as no
                 * one is consuming the input any longer.
                 * This happens, for example, on a large POST when the response
                 * is ready early due to the POST being denied. */
                if (!h2_mplx_c1_stream_is_running(session->mplx, stream)) {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                                  H2_STRM_LOG(APLOGNO(10305), stream, "remote close missing"));
                    nghttp2_submit_rst_stream(session->ngh2, NGHTTP2_FLAG_NONE,
                                              stream->id, H2_ERR_NO_ERROR);
                }
                break;
            case H2_SS_CLOSED_R: /* stream input was closed */
                break;
            case H2_SS_CLOSED: /* stream in+out were closed */
                ev_stream_closed(session, stream);
                break;
            case H2_SS_CLEANUP:
                nghttp2_session_set_stream_user_data(session->ngh2, stream->id, NULL);
                update_child_status(session, SERVER_BUSY_WRITE, "done", stream);
                h2_mplx_c1_stream_cleanup(session->mplx, stream, &session->open_streams);
                stream = NULL;
                ++session->streams_done;
                break;
            default:
                break;
        }
    }
    
    static void on_stream_event(void *ctx, h2_stream *stream, h2_stream_event_t ev)
    {
        h2_session *session = ctx;
        switch (ev) {
            case H2_SEV_IN_DATA_PENDING:
                session->input_flushed = 1;
                break;
            case H2_SEV_OUT_C1_BLOCK:
                h2_iq_append(session->out_c1_blocked, stream->id);
                break;
            default:
                /* NOP */
                break;
        }
    }
    
    static void on_stream_state_event(void *ctx, h2_stream *stream, 
                                      h2_stream_event_t ev)
    {
        h2_session *session = ctx;
        switch (ev) {
            case H2_SEV_CANCELLED:
                if (session->state != H2_SESSION_ST_DONE) {
                    nghttp2_submit_rst_stream(session->ngh2, NGHTTP2_FLAG_NONE, 
                                              stream->id, stream->rst_error);
                }
                break;
            default:
                /* NOP */
                break;
        }
    }
    
    void h2_session_dispatch_event(h2_session *session, h2_session_event_t ev,
                                   apr_status_t arg, const char *msg)
    {
        switch (ev) {
            case H2_SESSION_EV_INIT:
                h2_session_ev_init(session, arg, msg);
                break;            
            case H2_SESSION_EV_INPUT_PENDING:
                h2_session_ev_input_pending(session, arg, msg);
                break;
            case H2_SESSION_EV_INPUT_EXHAUSTED:
                h2_session_ev_input_exhausted(session, arg, msg);
                break;
            case H2_SESSION_EV_LOCAL_GOAWAY:
                h2_session_ev_local_goaway(session, arg, msg);
                break;
            case H2_SESSION_EV_REMOTE_GOAWAY:
                h2_session_ev_remote_goaway(session, arg, msg);
                break;
            case H2_SESSION_EV_CONN_ERROR:
                h2_session_ev_conn_error(session, arg, msg);
                break;
            case H2_SESSION_EV_PROTO_ERROR:
                h2_session_ev_proto_error(session, arg, msg);
                break;
            case H2_SESSION_EV_CONN_TIMEOUT:
                h2_session_ev_conn_timeout(session, arg, msg);
                break;
            case H2_SESSION_EV_NGH2_DONE:
                h2_session_ev_ngh2_done(session, arg, msg);
                break;
            case H2_SESSION_EV_MPM_STOPPING:
                h2_session_ev_mpm_stopping(session, arg, msg);
                break;
            case H2_SESSION_EV_PRE_CLOSE:
                h2_session_ev_pre_close(session, arg, msg);
                break;
            case H2_SESSION_EV_NO_MORE_STREAMS:
                h2_session_ev_no_more_streams(session);
                break;
            default:
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c1,
                              H2_SSSN_MSG(session, "unknown event %d"), ev);
                break;
        }
    }
    
    static void unblock_c1_out(h2_session *session) {
        int sid;
    
        while ((sid = h2_iq_shift(session->out_c1_blocked)) > 0) {
            nghttp2_session_resume_data(session->ngh2, sid);
        }
    }
    
    static int h2_send_flow_blocked(h2_session *session)
    {
        /* We are completely send blocked if either the connection window
         * is 0 or all stream flow windows are 0. */
        return ((nghttp2_session_get_remote_window_size(session->ngh2) <= 0) ||
                 h2_mplx_c1_all_streams_send_win_exhausted(session->mplx));
    }
    
    apr_status_t h2_session_process(h2_session *session, int async,
                                    int *pkeepalive)
    {
        apr_status_t status = APR_SUCCESS;
        conn_rec *c = session->c1;
        int rv, mpm_state, trace = APLOGctrace3(c);
    
        *pkeepalive = 0;
        if (trace) {
            ap_log_cerror( APLOG_MARK, APLOG_TRACE3, status, c,
                          H2_SSSN_MSG(session, "process start, async=%d"), async);
        }
    
        if (H2_SESSION_ST_INIT == session->state) {
            if (!h2_protocol_is_acceptable_c1(c, session->r, 1)) {
                const char *msg = nghttp2_strerror(NGHTTP2_INADEQUATE_SECURITY);
                update_child_status(session, SERVER_BUSY_READ, msg, NULL);
                h2_session_shutdown(session, APR_EINVAL, msg, 1);
            }
            else {
                update_child_status(session, SERVER_BUSY_READ, "init", NULL);
                status = h2_session_start(session, &rv);
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
                              H2_SSSN_LOG(APLOGNO(03079), session,
                              "started on %s:%d"),
                              session->s->server_hostname,
                              c->local_addr->port);
                if (status != APR_SUCCESS) {
                    h2_session_dispatch_event(session,
                                   H2_SESSION_EV_CONN_ERROR, status, NULL);
                }
                else {
                    h2_session_dispatch_event(session, H2_SESSION_EV_INIT, 0, NULL);
                }
            }
        }
    
        while (session->state != H2_SESSION_ST_DONE) {
    
            /* PR65731: we may get a new connection to process while the
             * MPM already is stopping. For example due to having reached
             * MaxRequestsPerChild limit.
             * Since this is supposed to handle things gracefully, we need to:
             * a) fully initialize the session before GOAWAYing
             * b) give the client the chance to submit at least one request
             */
            if (session->state != H2_SESSION_ST_INIT /* no longer intializing */
                && session->local.accepted_max > 0   /* have gotten at least one stream */
                && session->local.accepting          /* have not already locally shut down */
                && !ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
                if (mpm_state == AP_MPMQ_STOPPING) {
                    h2_session_dispatch_event(session, H2_SESSION_EV_MPM_STOPPING, 0, NULL);
                }
            }
    
            session->status[0] = '\0';
            
            if (h2_session_want_send(session)) {
                h2_session_send(session);
            }
            else if (!nghttp2_session_want_read(session->ngh2)) {
                h2_session_dispatch_event(session, H2_SESSION_EV_NGH2_DONE, 0, NULL);
            }
    
            if (!h2_iq_empty(session->ready_to_process)) {
                h2_mplx_c1_process(session->mplx, session->ready_to_process,
                                   get_stream, stream_pri_cmp, session,
                                   &session->open_streams);
                transit(session, "scheduled stream", H2_SESSION_ST_BUSY);
            }
    
            if (session->input_flushed) {
                transit(session, "forwarded input", H2_SESSION_ST_BUSY);
                session->input_flushed = 0;
            }
    
            if (!h2_iq_empty(session->out_c1_blocked)) {
                unblock_c1_out(session);
                transit(session, "unblocked output", H2_SESSION_ST_BUSY);
            }
    
            if (session->reprioritize) {
                h2_mplx_c1_reprioritize(session->mplx, stream_pri_cmp, session);
                session->reprioritize = 0;
            }
    
            if (h2_session_want_send(session)) {
                h2_session_send(session);
            }
    
            status = h2_c1_io_assure_flushed(&session->io);
            if (APR_SUCCESS != status) {
                h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, status, NULL);
            }
    
            switch (session->state) {
            case H2_SESSION_ST_INIT:
                ap_assert(0);
                h2_c1_read(session);
                break;
    
            case H2_SESSION_ST_IDLE:
                ap_assert(session->open_streams == 0);
                ap_assert(nghttp2_session_want_read(session->ngh2));
                if (!h2_session_want_send(session)) {
                    /* Give any new incoming request a short grace period to
                     * arrive while we are still hot and return to the mpm
                     * connection handling when nothing really happened. */
                    h2_c1_read(session);
                    if (H2_SESSION_ST_IDLE == session->state) {
                        if (async) {
                            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
                                          H2_SSSN_LOG(APLOGNO(10306), session,
                                          "returning to mpm c1 monitoring"));
                            goto leaving;
                        }
                        else {
                            /* Not an async mpm, we must continue waiting
                             * for client data to arrive until the configured
                             * server Timeout/KeepAliveTimeout happens */
                            apr_time_t timeout = ((session->open_streams == 0) &&
                                                  session->remote.emitted_count)?
                                session->s->keep_alive_timeout :
                                session->s->timeout;
                            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, c,
                                          H2_SSSN_MSG(session, "polling timeout=%d"),
                                          (int)apr_time_sec(timeout));
                            status = h2_mplx_c1_poll(session->mplx, timeout,
                                                     on_stream_input,
                                                     on_stream_output, session);
                            if (APR_STATUS_IS_TIMEUP(status)) {
                                if (session->open_streams == 0) {
                                    h2_session_dispatch_event(session,
                                        H2_SESSION_EV_CONN_TIMEOUT, status, NULL);
                                    break;
                                }
                            }
                            else if (APR_SUCCESS != status) {
                                h2_session_dispatch_event(session,
                                    H2_SESSION_EV_CONN_ERROR, status, NULL);
                                break;
                            }
                        }
                    }
                }
                else {
                    transit(session, "c1 io pending", H2_SESSION_ST_BUSY);
                }
                break;
    
            case H2_SESSION_ST_BUSY:
                /* IO happening in and out. Make sure we react to c2 events
                 * inbetween send and receive. */
                status = h2_mplx_c1_poll(session->mplx, 0,
                                         on_stream_input, on_stream_output, session);
                if (APR_SUCCESS != status && !APR_STATUS_IS_TIMEUP(status)) {
                    h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, status, NULL);
                    break;
                }
                h2_c1_read(session);
                break;
    
            case H2_SESSION_ST_WAIT:
                /* In this state, we might have returned processing to the MPM
                 * before. On a connection socket event, we are invoked again and
                 * need to process any input before proceeding. */
                h2_c1_read(session);
                if (session->state != H2_SESSION_ST_WAIT) {
                    break;
                }
    
                status = h2_c1_io_assure_flushed(&session->io);
                if (APR_SUCCESS != status) {
                    h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, status, NULL);
                    break;
                }
                if (session->open_streams == 0) {
                    h2_session_dispatch_event(session, H2_SESSION_EV_NO_MORE_STREAMS,
                                              0, "streams really done");
                    if (session->state != H2_SESSION_ST_WAIT) {
                        break;
                    }
                }
                else if (async && h2_send_flow_blocked(session)) {
                    /* By returning to the MPM, we do not block a worker
                     * and async wait for the client send window updates. */
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
                                  H2_SSSN_LOG(APLOGNO(10502), session,
                                  "BLOCKED, return to mpm c1 monitoring"));
                    goto leaving;
                }
    
                /* No IO happening and input is exhausted. Wait with
                 * the c1 connection timeout for sth to happen in our c1/c2 sockets/pipes */
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, c,
                              H2_SSSN_MSG(session, "polling timeout=%d, open_streams=%d"),
                              (int)apr_time_sec(session->s->timeout), session->open_streams);
                status = h2_mplx_c1_poll(session->mplx, session->s->timeout,
                                         on_stream_input, on_stream_output, session);
                if (APR_STATUS_IS_TIMEUP(status)) {
                    /* If we timeout without streams open, no new request from client
                     * arrived.
                     * If we timeout without nghttp2 wanting to write something, but
                     * all open streams have something to send, it means we are
                     * blocked on HTTP/2 flow control and the client did not send
                     * WINDOW_UPDATEs to us. */
                    if (session->open_streams == 0 ||
                        (!h2_session_want_send(session) &&
                         h2_mplx_c1_all_streams_want_send_data(session->mplx))) {
                        h2_session_dispatch_event(session, H2_SESSION_EV_CONN_TIMEOUT, status, NULL);
                        break;
                    }
                }
                else if (APR_SUCCESS != status) {
                    h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, status, NULL);
                    break;
                }
                break;
    
            case H2_SESSION_ST_DONE:
                h2_c1_read(session);
                break;
    
            default:
                ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c,
                              H2_SSSN_LOG(APLOGNO(03080), session,
                              "unknown state"));
                h2_session_dispatch_event(session, H2_SESSION_EV_PROTO_ERROR, APR_EGENERAL, NULL);
                break;
            }
        }
    
    leaving:
        /* entering KeepAlive timing when we have no more open streams AND
         * we have processed at least one stream. */
        *pkeepalive = (session->open_streams == 0 && session->remote.emitted_count);
        if (trace) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, c,
                          H2_SSSN_MSG(session, "process returns, keepalive=%d"),
                          *pkeepalive);
        }
        h2_mplx_c1_going_keepalive(session->mplx);
    
        if (session->state == H2_SESSION_ST_DONE) {
            if (session->local.error) {
                char buffer[128];
                const char *msg;
                if (session->local.error_msg) {
                    msg = session->local.error_msg;
                }
                else {
                    msg = apr_strerror(session->local.error, buffer, sizeof(buffer));
                }
                update_child_status(session, SERVER_CLOSING, msg, NULL);
            }
            else {
                update_child_status(session, SERVER_CLOSING, "done", NULL);
            }
        }
        else if (APR_STATUS_IS_EOF(status)
                || APR_STATUS_IS_ECONNRESET(status) 
                || APR_STATUS_IS_ECONNABORTED(status)) {
            h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, status, NULL);
            update_child_status(session, SERVER_CLOSING, "error", NULL);
        }
    
        return (session->state == H2_SESSION_ST_DONE)? APR_EOF : APR_SUCCESS;
    }
    
    apr_status_t h2_session_pre_close(h2_session *session, int async)
    {
        apr_status_t status;
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c1,
                      H2_SSSN_MSG(session, "pre_close"));
        h2_session_dispatch_event(session, H2_SESSION_EV_PRE_CLOSE, 0,
            (session->state == H2_SESSION_ST_IDLE)? "timeout" : NULL);
        status = session_cleanup(session, "pre_close");
        if (status == APR_SUCCESS) {
            /* no one should hold a reference to this session any longer and
             * the h2_conn_ctx_twas removed from the connection.
             * Take the pool (and thus all subpools etc. down now, instead of
             * during cleanup of main connection pool. */
            apr_pool_destroy(session->pool);
        }
        return status;
    }
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_util.h����������������������������������������������������������������0000664�0001751�0001751�00000044274�15032734701�017067� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_util__
    #define __mod_h2__h2_util__
    
    #include <nghttp2/nghttp2.h>
    #include <http_protocol.h>
    
    #include "h2.h"
    #include "h2_headers.h"
    
    /*******************************************************************************
     * some debugging/format helpers
     ******************************************************************************/
    struct h2_request;
    struct nghttp2_frame;
    
    size_t h2_util_hex_dump(char *buffer, size_t maxlen,
                            const char *data, size_t datalen);
    
    void h2_util_camel_case_header(char *s, size_t len);
    
    int h2_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen);
    
    /*******************************************************************************
     * ihash - hash for structs with int identifier
     ******************************************************************************/
    typedef struct h2_ihash_t h2_ihash_t;
    typedef int h2_ihash_iter_t(void *ctx, void *val);
    
    /**
     * Create a hash for structures that have an identifying int member.
     * @param pool the pool to use
     * @param offset_of_int the offsetof() the int member in the struct
     */
    h2_ihash_t *h2_ihash_create(apr_pool_t *pool, size_t offset_of_int);
    
    unsigned int h2_ihash_count(h2_ihash_t *ih);
    int h2_ihash_empty(h2_ihash_t *ih);
    void *h2_ihash_get(h2_ihash_t *ih, int id);
    
    /**
     * Iterate over the hash members (without defined order) and invoke
     * fn for each member until 0 is returned.
     * @param ih the hash to iterate over
     * @param fn the function to invoke on each member
     * @param ctx user supplied data passed into each iteration call
     * @return 0 if one iteration returned 0, otherwise != 0
     */
    int h2_ihash_iter(h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx);
    
    void h2_ihash_add(h2_ihash_t *ih, void *val);
    void h2_ihash_remove(h2_ihash_t *ih, int id);
    void h2_ihash_remove_val(h2_ihash_t *ih, void *val);
    void h2_ihash_clear(h2_ihash_t *ih);
    
    size_t h2_ihash_shift(h2_ihash_t *ih, void **buffer, size_t max);
    
    /*******************************************************************************
     * iqueue - sorted list of int with user defined ordering
     ******************************************************************************/
    typedef struct h2_iqueue {
        int *elts;
        int head;
        int nelts;
        int nalloc;
        apr_pool_t *pool;
    } h2_iqueue;
    
    /**
     * Comparator for two int to determine their order.
     *
     * @param i1 first int to compare
     * @param i2 second int to compare
     * @param ctx provided user data
     * @return value is the same as for strcmp() and has the effect:
     *    == 0: s1 and s2 are treated equal in ordering
     *     < 0: s1 should be sorted before s2
     *     > 0: s2 should be sorted before s1
     */
    typedef int h2_iq_cmp(int i1, int i2, void *ctx);
    
    /**
     * Allocate a new queue from the pool and initialize.
     * @param pool the memory pool
     * @param capacity the initial capacity of the queue
     */
    h2_iqueue *h2_iq_create(apr_pool_t *pool, int capacity);
    
    /**
     * Return != 0 iff there are no ints in the queue.
     * @param q the queue to check
     */
    int h2_iq_empty(h2_iqueue *q);
    
    /**
     * Return the number of int in the queue.
     * @param q the queue to get size on
     */
    int h2_iq_count(h2_iqueue *q);
    
    /**
     * Add a stream id to the queue. 
     *
     * @param q the queue to append the id to
     * @param sid the stream id to add
     * @param cmp the comparator for sorting
     * @param ctx user data for comparator
     * @return != 0 iff id was not already there 
     */
    int h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx);
    
    /**
     * Append the id to the queue if not already present. 
     *
     * @param q the queue to append the id to
     * @param sid the id to append
     * @return != 0 iff id was not already there 
     */
    int h2_iq_append(h2_iqueue *q, int sid);
    
    /**
     * Remove the int from the queue. Return != 0 iff it was found.
     * @param q the queue
     * @param sid the stream id to remove
     * @return != 0 iff int was found in queue
     */
    int h2_iq_remove(h2_iqueue *q, int sid);
    
    /**
     * Remove all entries in the queue.
     */
    void h2_iq_clear(h2_iqueue *q);
    
    /**
     * Sort the stream idqueue again. Call if the int ordering
     * has changed.
     *
     * @param q the queue to sort
     * @param cmp the comparator for sorting
     * @param ctx user data for the comparator 
     */
    void h2_iq_sort(h2_iqueue *q, h2_iq_cmp *cmp, void *ctx);
    
    /**
     * Get the first id from the queue or 0 if the queue is empty. 
     * The id is being removed.
     *
     * @param q the queue to get the first id from
     * @return the first id of the queue, 0 if empty
     */
    int h2_iq_shift(h2_iqueue *q);
    
    /**
     * Get the first max ids from the queue. All these ids will be removed.
     *
     * @param q the queue to get the first ids from
     * @param pint the int array to receive the values
     * @param max the maximum number of ids to shift
     * @return the actual number of ids shifted
     */
    size_t h2_iq_mshift(h2_iqueue *q, int *pint, size_t max);
    
    /**
     * Determine if int is in the queue already
     *
     * @param q the queue
     * @param sid the integer id to check for
     * @return != 0 iff sid is already in the queue
     */
    int h2_iq_contains(h2_iqueue *q, int sid);
    
    /*******************************************************************************
     * FIFO queue (void* elements)
     ******************************************************************************/
    
    /**
     * A thread-safe FIFO queue with some extra bells and whistles, if you
     * do not need anything special, better use 'apr_queue'.
     */
    typedef struct h2_fifo h2_fifo;
    
    /**
     * Create a FIFO queue that can hold up to capacity elements. Elements can
     * appear several times.
     */
    apr_status_t h2_fifo_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity);
    
    /**
     * Create a FIFO set that can hold up to capacity elements. Elements only
     * appear once. Pushing an element already present does not change the
     * queue and is successful.
     */
    apr_status_t h2_fifo_set_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity);
    
    apr_status_t h2_fifo_term(h2_fifo *fifo);
    
    int h2_fifo_count(h2_fifo *fifo);
    
    /**
     * Push en element into the queue. Blocks if there is no capacity left.
     * 
     * @param fifo the FIFO queue
     * @param elem the element to push
     * @return APR_SUCCESS on push, APR_EAGAIN on try_push on a full queue,
     *         APR_EEXIST when in set mode and elem already there.
     */
    apr_status_t h2_fifo_push(h2_fifo *fifo, void *elem);
    apr_status_t h2_fifo_try_push(h2_fifo *fifo, void *elem);
    
    apr_status_t h2_fifo_pull(h2_fifo *fifo, void **pelem);
    apr_status_t h2_fifo_try_pull(h2_fifo *fifo, void **pelem);
    
    typedef enum {
        H2_FIFO_OP_PULL,   /* pull the element from the queue, ie discard it */
        H2_FIFO_OP_REPUSH, /* pull and immediately re-push it */
    } h2_fifo_op_t;
    
    typedef h2_fifo_op_t h2_fifo_peek_fn(void *head, void *ctx);
    
    /**
     * Call given function on the head of the queue, once it exists, and
     * perform the returned operation on it. The queue will hold its lock during
     * this time, so no other operations on the queue are possible.
     * @param fifo the queue to peek at
     * @param fn   the function to call on the head, once available
     * @param ctx  context to pass in call to function
     */
    apr_status_t h2_fifo_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx);
    
    /**
     * Non-blocking version of h2_fifo_peek.
     */
    apr_status_t h2_fifo_try_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx);
    
    /**
     * Remove the elem from the queue, will remove multiple appearances.
     * @param elem  the element to remove
     * @return APR_SUCCESS iff > 0 elems were removed, APR_EAGAIN otherwise.
     */
    apr_status_t h2_fifo_remove(h2_fifo *fifo, void *elem);
    
    /*******************************************************************************
     * iFIFO queue (int elements)
     ******************************************************************************/
    
    /**
     * A thread-safe FIFO queue with some extra bells and whistles, if you
     * do not need anything special, better use 'apr_queue'.
     */
    typedef struct h2_ififo h2_ififo;
    
    /**
     * Create a FIFO queue that can hold up to capacity int. ints can
     * appear several times.
     */
    apr_status_t h2_ififo_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity);
    
    /**
     * Create a FIFO set that can hold up to capacity integers. Ints only
     * appear once. Pushing an int already present does not change the
     * queue and is successful.
     */
    apr_status_t h2_ififo_set_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity);
    
    apr_status_t h2_ififo_term(h2_ififo *fifo);
    
    int h2_ififo_count(h2_ififo *fifo);
    
    /**
     * Push an int into the queue. Blocks if there is no capacity left.
     * 
     * @param fifo the FIFO queue
     * @param id  the int to push
     * @return APR_SUCCESS on push, APR_EAGAIN on try_push on a full queue,
     *         APR_EEXIST when in set mode and elem already there.
     */
    apr_status_t h2_ififo_push(h2_ififo *fifo, int id);
    apr_status_t h2_ififo_try_push(h2_ififo *fifo, int id);
    
    apr_status_t h2_ififo_pull(h2_ififo *fifo, int *pi);
    apr_status_t h2_ififo_try_pull(h2_ififo *fifo, int *pi);
    
    typedef h2_fifo_op_t h2_ififo_peek_fn(int head, void *ctx);
    
    /**
     * Call given function on the head of the queue, once it exists, and
     * perform the returned operation on it. The queue will hold its lock during
     * this time, so no other operations on the queue are possible.
     * @param fifo the queue to peek at
     * @param fn   the function to call on the head, once available
     * @param ctx  context to pass in call to function
     */
    apr_status_t h2_ififo_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx);
    
    /**
     * Non-blocking version of h2_fifo_peek.
     */
    apr_status_t h2_ififo_try_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx);
    
    /**
     * Remove the integer from the queue, will remove multiple appearances.
     * @param id  the integer to remove
     * @return APR_SUCCESS iff > 0 ints were removed, APR_EAGAIN otherwise.
     */
    apr_status_t h2_ififo_remove(h2_ififo *fifo, int id);
    
    /*******************************************************************************
     * common helpers
     ******************************************************************************/
    /* h2_log2(n) iff n is a power of 2 */
    unsigned char h2_log2(int n);
    
    /**
     * Count the bytes that all key/value pairs in a table have
     * in length (exlucding terminating 0s), plus additional extra per pair.
     *
     * @param t the table to inspect
     * @param pair_extra the extra amount to add per pair
     * @return the number of bytes all key/value pairs have
     */
    apr_size_t h2_util_table_bytes(apr_table_t *t, apr_size_t pair_extra);
    
    /** Match a header value against a string constance, case insensitive */
    #define H2_HD_MATCH_LIT(l, name, nlen)  \
        ((nlen == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
    
    /*******************************************************************************
     * HTTP/2 header helpers
     ******************************************************************************/
    int h2_ignore_req_trailer(const char *name, size_t len);
    int h2_ignore_resp_trailer(const char *name, size_t len);
    
    /**
     * Set the push policy for the given request. Takes request headers into 
     * account, see draft https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00
     * for details.
     * 
     * @param headers the http headers to inspect
     * @param p the pool to use
     * @param push_enabled if HTTP/2 server push is generally enabled for this request
     * @return the push policy desired
     */
    int h2_push_policy_determine(apr_table_t *headers, apr_pool_t *p, int push_enabled);
    
    /*******************************************************************************
     * base64 url encoding, different table from normal base64
     ******************************************************************************/
    /**
     * I always wanted to write my own base64url decoder...not. See 
     * https://tools.ietf.org/html/rfc4648#section-5 for description.
     */
    apr_size_t h2_util_base64url_decode(const char **decoded, 
                                        const char *encoded, 
                                        apr_pool_t *pool);
    const char *h2_util_base64url_encode(const char *data, 
                                         apr_size_t len, apr_pool_t *pool);
    
    /*******************************************************************************
     * nghttp2 helpers
     ******************************************************************************/
    
    int h2_util_ignore_resp_header(const char *name);
    
    typedef struct h2_ngheader {
        nghttp2_nv *nv;
        apr_size_t nvlen;
    } h2_ngheader;
    
    #if AP_HAS_RESPONSE_BUCKETS
    apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p,
                                         ap_bucket_headers *headers);
    apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                        ap_bucket_response *response);
    apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                        const struct h2_request *req);
    #else
    apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p, 
                                         struct h2_headers *headers); 
    apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p, 
                                        struct h2_headers *headers); 
    apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p, 
                                        const struct h2_request *req);
    #endif
    
    typedef struct h2_hd_scratch {
        size_t max_len; /* header field size name + ': ' + value */
        char *name;     /* max_len+1 sized */
        char *value;    /* max_len+1 sized */
    
    } h2_hd_scratch;
    
    /**
     * Add a HTTP/2 header and return the table key if it really was added
     * and not ignored.
     */
    apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
                                   const char *name, size_t nlen,
                                   const char *value, size_t vlen,
                                   h2_hd_scratch *scratch, int *pwas_added);
    
    /*******************************************************************************
     * apr brigade helpers
     ******************************************************************************/
    
    /**
     * Concatenate at most length bytes from src to dest brigade, splitting
     * buckets if necessary and reading buckets of indeterminate length.
     */
    apr_status_t h2_brigade_concat_length(apr_bucket_brigade *dest, 
                                          apr_bucket_brigade *src,
                                          apr_off_t length);
                                    
    /**
     * Copy at most length bytes from src to dest brigade, splitting
     * buckets if necessary and reading buckets of indeterminate length.
     */
    apr_status_t h2_brigade_copy_length(apr_bucket_brigade *dest, 
                                        apr_bucket_brigade *src,
                                        apr_off_t length);
                                    
    typedef apr_status_t h2_util_pass_cb(void *ctx,
                                         const char *data, apr_off_t len);
    
    /**
     * Print a bucket's meta data (type and length) to the buffer.
     * @return number of characters printed
     */
    apr_size_t h2_util_bucket_print(char *buffer, apr_size_t bmax, 
                                    apr_bucket *b, const char *sep);
                                    
    /**
     * Prints the brigade bucket types and lengths into the given buffer
     * up to bmax.
     * @return number of characters printed
     */
    apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax, 
                                const char *tag, const char *sep, 
                                apr_bucket_brigade *bb);
    /**
     * Logs the bucket brigade (which bucket types with what length)
     * to the log at the given level.
     * @param c the connection to log for
     * @param sid the stream identifier this brigade belongs to
     * @param level the log level (as in APLOG_*)
     * @param tag a short message text about the context
     * @param bb the brigade to log
     */
    #define h2_util_bb_log(c, sid, level, tag, bb) \
    if (APLOG_C_IS_LEVEL(c, level)) { \
        do { \
            char buffer[4 * 1024]; \
            const char *line = "(null)"; \
            apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \
            len = h2_util_bb_print(buffer, bmax, (tag), "", (bb)); \
            ap_log_cerror(APLOG_MARK, level, 0, (c), "bb_dump(%ld): %s", \
                ((c)->master? (c)->master->id : (c)->id), (len? buffer : line)); \
        } while(0); \
    }
    
    
    typedef int h2_bucket_gate(apr_bucket *b);
    /**
     * Transfer buckets from one brigade to another with a limit on the 
     * maximum amount of bytes transferred. Does no setaside magic, lifetime
     * of brigades must fit. 
     * @param to   brigade to transfer buckets to
     * @param from brigades to remove buckets from
     * @param plen maximum bytes to transfer, actual bytes transferred
     * @param peos if an EOS bucket was transferred
     */
    apr_status_t h2_append_brigade(apr_bucket_brigade *to,
                                   apr_bucket_brigade *from, 
                                   apr_off_t *plen,
                                   int *peos,
                                   h2_bucket_gate *should_append);
    
    /**
     * Get an approximnation of the memory footprint of the given
     * brigade. This varies from apr_brigade_length as
     * - no buckets are ever read
     * - only buckets known to allocate memory (HEAP+POOL) are counted
     * - the bucket struct itself is counted
     */
    apr_off_t h2_brigade_mem_size(apr_bucket_brigade *bb);
    
    /**
     * Drain a pipe used for notification.
     */
    void h2_util_drain_pipe(apr_file_t *pipe);
    
    /**
     * Wait on data arriving on a pipe.
     */
    apr_status_t h2_util_wait_on_pipe(apr_file_t *pipe);
    
    
    #if AP_HAS_RESPONSE_BUCKETS
    /**
     * Give an estimate of the length of the header fields,
     * without compression or other formatting decorations.
     */
    apr_size_t headers_length_estimate(ap_bucket_headers *hdrs);
    
    /**
     * Give an estimate of the length of the response meta data size,
     * without compression or other formatting decorations.
     */
    apr_size_t response_length_estimate(ap_bucket_response *resp);
    #endif /* AP_HAS_RESPONSE_BUCKETS */
    
    #endif /* defined(__mod_h2__h2_util__) */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_proxy_http2.c��������������������������������������������������������0000664�0001751�0001751�00000041276�15017524270�020655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <nghttp2/nghttp2.h>
    
    #include <ap_mmn.h>
    #include <httpd.h>
    #include <mod_proxy.h>
    #include "mod_http2.h"
    
    
    #include "mod_proxy_http2.h"
    #include "h2.h"
    #include "h2_proxy_util.h"
    #include "h2_version.h"
    #include "h2_proxy_session.h"
    
    #define H2MIN(x,y) ((x) < (y) ? (x) : (y))
    
    static void register_hook(apr_pool_t *p);
    
    AP_DECLARE_MODULE(proxy_http2) = {
        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_hook,     /* register hooks */
    #if defined(AP_MODULE_FLAG_NONE)
        AP_MODULE_FLAG_ALWAYS_MERGE
    #endif
    };
    
    /* Optional functions from mod_http2 */
    static int (*is_h2)(conn_rec *c);
    
    typedef struct h2_proxy_ctx {
        const char *id;
        conn_rec *cfront;
        apr_pool_t *pool;
        server_rec *server;
        const char *proxy_func;
        char server_portstr[32];
        proxy_conn_rec *p_conn;
        proxy_worker *worker;
        proxy_server_conf *conf;
        
        apr_size_t req_buffer_size;
        int capacity;
        
        unsigned is_ssl : 1;
        
        request_rec *r;            /* the request processed in this ctx */
        apr_status_t r_status;     /* status of request work */
        int r_done;                /* request was processed, not necessarily successfully */
        int r_may_retry;           /* request may be retried */
        int has_reusable_session;  /* http2 session is live and clean */
    } h2_proxy_ctx;
    
    static int h2_proxy_post_config(apr_pool_t *p, apr_pool_t *plog,
                                    apr_pool_t *ptemp, server_rec *s)
    {
        void *data = NULL;
        const char *init_key = "mod_proxy_http2_init_counter";
        nghttp2_info *ngh2;
        apr_status_t status = APR_SUCCESS;
        (void)plog;(void)ptemp;
        
        apr_pool_userdata_get(&data, init_key, s->process->pool);
        if ( data == NULL ) {
            apr_pool_userdata_set((const void *)1, init_key,
                                  apr_pool_cleanup_null, s->process->pool);
            return APR_SUCCESS;
        }
        
        ngh2 = nghttp2_version(0);
        ap_log_error( APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(03349)
                     "mod_proxy_http2 (v%s, nghttp2 %s), initializing...",
                     MOD_HTTP2_VERSION, ngh2? ngh2->version_str : "unknown");
        
        is_h2 = APR_RETRIEVE_OPTIONAL_FN(http2_is_h2);
        
        return status;
    }
    
    /**
     * canonicalize the url into the request, if it is meant for us.
     * slightly modified copy from mod_http
     */
    static int proxy_http2_canon(request_rec *r, char *url)
    {
        char *host, *path, sport[7];
        char *search = NULL;
        const char *err;
        const char *scheme;
        const char *http_scheme;
        apr_port_t port, def_port;
    
        /* ap_port_of_scheme() */
        if (ap_cstr_casecmpn(url, "h2c:", 4) == 0) {
            url += 4;
            scheme = "h2c";
            http_scheme = "http";
        }
        else if (ap_cstr_casecmpn(url, "h2:", 3) == 0) {
            url += 3;
            scheme = "h2";
            http_scheme = "https";
        }
        else {
            return DECLINED;
        }
        port = def_port = ap_proxy_port_of_scheme(http_scheme);
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "HTTP2: 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, APLOGNO(03350)
                          "error parsing URL %s: %s", url, err);
            return HTTP_BAD_REQUEST;
        }
    
        /*
         * now parse path/search args, according to rfc1738:
         * process the path.
         *
         * In a reverse proxy, our URL has been processed, so canonicalise
         * unless proxy-nocanon is set to say it's raw
         * In a forward proxy, we have and MUST NOT MANGLE the original.
         */
        switch (r->proxyreq) {
        default: /* wtf are we doing here? */
        case PROXYREQ_REVERSE:
            if (apr_table_get(r->notes, "proxy-nocanon")) {
                path = url;   /* this is the raw path */
            }
            else if (apr_table_get(r->notes, "proxy-noencode")) {
                path = url;   /* this is the encoded path already */
                search = r->args;
            }
            else {
    #ifdef PROXY_CANONENC_NOENCODEDSLASHENCODING
                core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
                int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
                path = ap_proxy_canonenc_ex(r->pool, url, (int)strlen(url),
                                            enc_path, flags, r->proxyreq);
    #else
                path = ap_proxy_canonenc(r->pool, url, (int)strlen(url),
                                         enc_path, 0, r->proxyreq);
    #endif
                if (!path) {
                    return HTTP_BAD_REQUEST;
                }
                search = r->args;
            }
            break;
        case PROXYREQ_PROXY:
            path = url;
            break;
        }
        /*
         * If we have a raw control character or a ' ' in nocanon path or
         * r->args, correct encoding was missed.
         */
        if (path == url && *ap_scan_vchar_obstext(path)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10420)
                          "To be forwarded path contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
        if (search && *ap_scan_vchar_obstext(search)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10412)
                          "To be forwarded query string contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
    
        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;
    }
    
    static apr_status_t add_request(h2_proxy_session *session, request_rec *r)
    {
        h2_proxy_ctx *ctx = session->user_data;
        const char *url;
        apr_status_t status;
    
        url = apr_table_get(r->notes, H2_PROXY_REQ_URL_NOTE);
        apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
                       ctx->p_conn->connection->local_addr->port));
        status = h2_proxy_session_submit(session, url, r, 1);
        if (status != APR_SUCCESS) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, status, r->connection, APLOGNO(03351)
                          "pass request body failed to %pI (%s) from %s (%s)",
                          ctx->p_conn->addr, ctx->p_conn->hostname ? 
                          ctx->p_conn->hostname: "", session->c->client_ip, 
                          session->c->remote_host ? session->c->remote_host: "");
        }
        return status;
    }
    
    static void request_done(h2_proxy_ctx *ctx, request_rec *r,
                             apr_status_t status, int touched, int error_code)
    {   
        if (r == ctx->r) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, r->connection, 
                          "h2_proxy_session(%s): request done, touched=%d, error=%d",
                          ctx->id, touched, error_code);
            ctx->r_done = 1;
            if (touched) ctx->r_may_retry = 0;
            ctx->r_status = error_code? HTTP_BAD_GATEWAY :
                ((status == APR_SUCCESS)? OK :
                 ap_map_http_request_error(status, HTTP_SERVICE_UNAVAILABLE));
        }
    }    
    
    static void session_req_done(h2_proxy_session *session, request_rec *r,
                                 apr_status_t status, int touched, int error_code)
    {
        request_done(session->user_data, r, status, touched, error_code);
    }
    
    static apr_status_t ctx_run(h2_proxy_ctx *ctx) {
        apr_status_t status = OK;
        h2_proxy_session *session;
        int h2_front;
        
        /* Step Four: Send the Request in a new HTTP/2 stream and
         * loop until we got the response or encounter errors.
         */
        ctx->has_reusable_session = 0; /* don't know yet */
        h2_front = is_h2? is_h2(ctx->cfront) : 0;
        session = h2_proxy_session_setup(ctx->id, ctx->p_conn, ctx->conf,
                                         h2_front, 30,
                                         h2_proxy_log2((int)ctx->req_buffer_size),
                                         session_req_done);
        if (!session) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->cfront,
                          APLOGNO(03372) "session unavailable");
            return HTTP_SERVICE_UNAVAILABLE;
        }
        
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->cfront, APLOGNO(03373)
                      "eng(%s): run session %s", ctx->id, session->id);
        session->user_data = ctx;
        
        ctx->r_done = 0;
        add_request(session, ctx->r);
        
        while (!ctx->cfront->aborted && !ctx->r_done) {
        
            status = h2_proxy_session_process(session);
            if (status != APR_SUCCESS) {
                /* Encountered an error during session processing */
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->cfront,
                              APLOGNO(03375) "eng(%s): end of session %s", 
                              ctx->id, session->id);
                /* Any open stream of that session needs to
                 * a) be reopened on the new session iff safe to do so
                 * b) reported as done (failed) otherwise
                 */
                h2_proxy_session_cleanup(session, session_req_done);
                goto out;
            }
        }
        
    out:
        if (ctx->cfront->aborted) {
            /* master connection gone */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->cfront,
                          APLOGNO(03374) "eng(%s): master connection gone", ctx->id);
            /* cancel all ongoing requests */
            h2_proxy_session_cancel_all(session);
            h2_proxy_session_process(session);
        }
        ctx->has_reusable_session = h2_proxy_session_is_reusable(session);
        session->user_data = NULL;
        return status;
    }
    
    static int proxy_http2_handler(request_rec *r, 
                                   proxy_worker *worker,
                                   proxy_server_conf *conf,
                                   char *url, 
                                   const char *proxyname,
                                   apr_port_t proxyport)
    {
        const char *proxy_func;
        char *locurl, *u;
        apr_size_t slen;
        int is_ssl = 0;
        apr_status_t status;
        h2_proxy_ctx *ctx;
        apr_uri_t uri;
        int reconnects = 0;
        
        /* find the scheme */
        if ((url[0] != 'h' && url[0] != 'H') || url[1] != '2') {
           return DECLINED;
        }
        u = strchr(url, ':');
        if (u == NULL || u[1] != '/' || u[2] != '/' || u[3] == '\0') {
           return DECLINED;
        }
        slen = (u - url);
        switch(slen) {
            case 2:
                proxy_func = "H2";
                is_ssl = 1;
                break;
            case 3:
                if (url[2] != 'c' && url[2] != 'C') {
                    return DECLINED;
                }
                proxy_func = "H2C";
                break;
            default:
                return DECLINED;
        }
    
        ctx = apr_pcalloc(r->pool, sizeof(*ctx));
        ctx->id = apr_psprintf(r->pool, "%ld", (long)r->connection->id);
        ctx->cfront = r->connection;
        ctx->pool = r->pool;
        ctx->server = r->server;
        ctx->proxy_func = proxy_func;
        ctx->is_ssl = is_ssl;
        ctx->worker = worker;
        ctx->conf = conf;
        ctx->req_buffer_size = (32*1024);
        ctx->r = r;
        ctx->r_status = status = HTTP_SERVICE_UNAVAILABLE;
        ctx->r_done = 0;
        ctx->r_may_retry =  1;
        
        ap_set_module_config(ctx->cfront->conn_config, &proxy_http2_module, ctx);
    
        /* scheme says, this is for us. */
        apr_table_setn(ctx->r->notes, H2_PROXY_REQ_URL_NOTE, url);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->r, 
                      "H2: serving URL %s", url);
        
    run_connect:    
        if (ctx->cfront->aborted) goto cleanup;
    
        /* Get a proxy_conn_rec from the worker, might be a new one, might
         * be one still open from another request, or it might fail if the
         * worker is stopped or in error. */
        if ((status = ap_proxy_acquire_connection(ctx->proxy_func, &ctx->p_conn,
                                                  ctx->worker, ctx->server)) != OK) {
            goto cleanup;
        }
    
        locurl = url;
        ctx->p_conn->is_ssl = ctx->is_ssl;
    
        /* Step One: Determine the URL to connect to (might be a proxy),
         * initialize the backend accordingly and determine the server 
         * port string we can expect in responses. */
        if ((status = ap_proxy_determine_connection(ctx->pool, ctx->r, conf, worker, 
                                                    ctx->p_conn, &uri, &locurl, 
                                                    proxyname, proxyport, 
                                                    ctx->server_portstr,
                                                    sizeof(ctx->server_portstr))) != OK) {
            goto cleanup;
        }
        
        /* Step Two: Make the Connection (or check that an already existing
         * socket is still usable). On success, we have a socket connected to
         * backend->hostname. */
        if (ap_proxy_connect_backend(ctx->proxy_func, ctx->p_conn, ctx->worker, 
                                     ctx->server)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->cfront, APLOGNO(03352)
                          "H2: failed to make connection to backend: %s",
                          ctx->p_conn->hostname);
            goto cleanup;
        }
        
        /* Step Three: Create conn_rec for the socket we have open now. */
        status = ap_proxy_connection_create_ex(ctx->proxy_func, ctx->p_conn, ctx->r);
        if (status != OK) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->cfront, APLOGNO(03353)
                          "setup new connection: is_ssl=%d %s %s %s", 
                          ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, 
                          locurl, ctx->p_conn->hostname);
            ctx->r_status = status;
            goto cleanup;
        }
        
        if (!ctx->p_conn->data && ctx->is_ssl) {
            /* New SSL connection: set a note on the connection about what
             * protocol we need. */
            apr_table_setn(ctx->p_conn->connection->notes,
                           "proxy-request-alpn-protos", "h2");
        }
    
        if (ctx->cfront->aborted) goto cleanup;
        status = ctx_run(ctx);
    
        if (ctx->r_status != APR_SUCCESS && ctx->r_may_retry && !ctx->cfront->aborted) {
            /* Not successfully processed, but may retry, tear down old conn and start over */
            if (ctx->p_conn) {
                ctx->p_conn->close = 1;
    #if AP_MODULE_MAGIC_AT_LEAST(20140207, 2)
                proxy_run_detach_backend(r, ctx->p_conn);
    #endif
                ap_proxy_release_connection(ctx->proxy_func, ctx->p_conn, ctx->server);
                ctx->p_conn = NULL;
            }
            ++reconnects;
            if (reconnects < 2) {
                goto run_connect;
            } 
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->cfront, APLOGNO(10023)
                          "giving up after %d reconnects, request-done=%d",
                          reconnects, ctx->r_done);
        }
        
    cleanup:
        if (ctx->p_conn) {
            if (status != APR_SUCCESS || !ctx->has_reusable_session) {
                /* close socket when errors happened or session is not "clean",
                 * meaning in a working condition with no open streams */
                ctx->p_conn->close = 1;
            }
    #if AP_MODULE_MAGIC_AT_LEAST(20140207, 2)
            proxy_run_detach_backend(ctx->r, ctx->p_conn);
    #endif
            ap_proxy_release_connection(ctx->proxy_func, ctx->p_conn, ctx->server);
            ctx->p_conn = NULL;
        }
    
        ap_set_module_config(ctx->cfront->conn_config, &proxy_http2_module, NULL);
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->cfront,
                      APLOGNO(03377) "leaving handler");
        return ctx->r_status;
    }
    
    static void register_hook(apr_pool_t *p)
    {
        ap_hook_post_config(h2_proxy_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    
        proxy_hook_scheme_handler(proxy_http2_handler, NULL, NULL, APR_HOOK_FIRST);
        proxy_hook_canon_handler(proxy_http2_canon, NULL, NULL, APR_HOOK_FIRST);
    }
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c1.c������������������������������������������������������������������0000664�0001751�0001751�00000026772�14651200711�016406� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_strings.h>
    
    #include <ap_mpm.h>
    #include <ap_mmn.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_log.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_ssl.h>
    
    #include <mpm_common.h>
    
    #include "h2_private.h"
    #include "h2.h"
    #include "h2_bucket_beam.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_mplx.h"
    #include "h2_session.h"
    #include "h2_stream.h"
    #include "h2_protocol.h"
    #include "h2_workers.h"
    #include "h2_c1.h"
    #include "h2_version.h"
    #include "h2_util.h"
    
    static struct h2_workers *workers;
    
    static int async_mpm, mpm_can_waitio;
    
    APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_in) *h2_c_logio_add_bytes_in;
    APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *h2_c_logio_add_bytes_out;
    
    apr_status_t h2_c1_child_init(apr_pool_t *pool, server_rec *s)
    {
        int minw, maxw;
        apr_time_t idle_limit;
    
        if (ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm)) {
            /* some MPMs do not implemnent this */
            async_mpm = 0;
        }
    #ifdef AP_MPMQ_CAN_WAITIO
        if (!async_mpm || ap_mpm_query(AP_MPMQ_CAN_WAITIO, &mpm_can_waitio)) {
            mpm_can_waitio = 0;
        }
    #endif
    
        h2_config_init(pool);
    
        h2_get_workers_config(s, &minw, &maxw, &idle_limit);
        workers = h2_workers_create(s, pool, maxw, minw, idle_limit);
     
        h2_c_logio_add_bytes_in = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_in);
        h2_c_logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out);
    
        return h2_mplx_c1_child_init(pool, s);
    }
    
    void h2_c1_child_stopping(apr_pool_t *pool, int graceful)
    {
        if (workers) {
            h2_workers_shutdown(workers, graceful);
        }
    }
    
    
    apr_status_t h2_c1_setup(conn_rec *c, request_rec *r, server_rec *s)
    {
        h2_session *session;
        h2_conn_ctx_t *ctx;
        apr_status_t rv;
        
        if (!workers) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02911) 
                          "workers not initialized");
            rv = APR_EGENERAL;
            goto cleanup;
        }
    
        rv = h2_session_create(&session, c, r, s, workers);
        if (APR_SUCCESS != rv) goto cleanup;
    
        ctx = h2_conn_ctx_get(c);
        ap_assert(ctx);
        h2_conn_ctx_assign_session(ctx, session);
        /* remove the input filter of mod_reqtimeout, now that the connection
         * is established and we have switched to h2. reqtimeout has supervised
         * possibly configured handshake timeouts and needs to get out of the way
         * now since the rest of its state handling assumes http/1.x to take place. */
        ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout");
    
    cleanup:
        return rv;
    }
    
    int h2_c1_run(conn_rec *c)
    {
        apr_status_t status;
        int mpm_state = 0, keepalive = 0;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
        
        ap_assert(conn_ctx);
        ap_assert(conn_ctx->session);
        c->clogging_input_filters = 0;
        do {
            if (c->cs) {
                c->cs->state = CONN_STATE_HANDLER;
            }
        
            status = h2_session_process(conn_ctx->session, async_mpm, &keepalive);
            if (status != APR_SUCCESS) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, 
                              H2_SSSN_LOG(APLOGNO(03045), conn_ctx->session,
                              "process, closing conn"));
                c->keepalive = AP_CONN_CLOSE;
            }
            else {
                c->keepalive = AP_CONN_KEEPALIVE;
            }
            
            if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
                break;
            }
        } while (!async_mpm
                 && c->keepalive == AP_CONN_KEEPALIVE 
                 && mpm_state != AP_MPMQ_STOPPING);
    
        if (c->cs) {
            switch (conn_ctx->session->state) {
                case H2_SESSION_ST_INIT:
                case H2_SESSION_ST_IDLE:
                case H2_SESSION_ST_BUSY:
                case H2_SESSION_ST_WAIT:
                    if (keepalive) {
                        /* Flush then keep-alive */
                        c->cs->sense = CONN_SENSE_DEFAULT;
                        c->cs->state = CONN_STATE_WRITE_COMPLETION;
                    }
                    else {
                        /* Let the MPM know that we are not done and want to wait
                         * for read using Timeout instead of KeepAliveTimeout.
                         * See PR 63534. 
                         */
                        c->cs->sense = CONN_SENSE_WANT_READ;
    #ifdef AP_MPMQ_CAN_WAITIO
                        if (mpm_can_waitio) {
                            /* This tells the MPM to wait for the connection to be
                             * readable (CONN_SENSE_WANT_READ) within the configured
                             * Timeout and then come back to the process_connection()
                             * hooks again when ready.
                             */
                            c->cs->state = CONN_STATE_ASYNC_WAITIO;
                        }
                        else
    #endif
                        {
                            /* This is a compat workaround to do the same using the
                             * CONN_STATE_WRITE_COMPLETION state but with both
                             * CONN_SENSE_WANT_READ to wait for readability rather
                             * than writing and c->clogging_input_filters to force
                             * reentering the process_connection() hooks from any
                             * state when ready. This somehow will use Timeout too.
                             */
                            c->cs->state = CONN_STATE_WRITE_COMPLETION;
                            c->clogging_input_filters = 1;
                        }
                    }
                    break;
    
                case H2_SESSION_ST_CLEANUP:
                case H2_SESSION_ST_DONE:
                default:
                    c->cs->state = CONN_STATE_LINGER;
                    break;
            }
        }
    
        return OK;
    }
    
    apr_status_t h2_c1_pre_close(struct h2_conn_ctx_t *ctx, conn_rec *c)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
    
        if (conn_ctx && conn_ctx->session) {
            apr_status_t status = h2_session_pre_close(conn_ctx->session, async_mpm);
            return (status == APR_SUCCESS)? DONE : status;
        }
        return DONE;
    }
    
    int h2_c1_allows_direct(conn_rec *c)
    {
        if (!c->master) {
            int is_tls = ap_ssl_conn_is_ssl(c);
            const char *needed_protocol = is_tls? "h2" : "h2c";
            int h2_direct = h2_config_cgeti(c, H2_CONF_DIRECT);
    
            if (h2_direct < 0) {
                h2_direct = is_tls? 0 : 1;
            }
            return (h2_direct && ap_is_allowed_protocol(c, NULL, NULL, needed_protocol));
        }
        return 0;
    }
    
    int h2_c1_can_upgrade(request_rec *r)
    {
        if (!r->connection->master) {
            int h2_upgrade = h2_config_rgeti(r, H2_CONF_UPGRADE);
            return h2_upgrade > 0 || (h2_upgrade < 0 && !ap_ssl_conn_is_ssl(r->connection));
        }
        return 0;
    }
    
    static int h2_c1_hook_process_connection(conn_rec* c)
    {
        apr_status_t status;
        h2_conn_ctx_t *ctx;
    
        if (c->master) goto declined;
        ctx = h2_conn_ctx_get(c);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
        if (!ctx && c->keepalives == 0) {
            const char *proto = ap_get_protocol(c);
    
            if (APLOGctrace1(c)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn, "
                              "new connection using protocol '%s', direct=%d, "
                              "tls acceptable=%d", proto, h2_c1_allows_direct(c),
                              h2_protocol_is_acceptable_c1(c, NULL, 1));
            }
    
            if (!strcmp(AP_PROTOCOL_HTTP1, proto)
                && h2_c1_allows_direct(c)
                && h2_protocol_is_acceptable_c1(c, NULL, 1)) {
                /* Fresh connection still is on http/1.1 and H2Direct is enabled.
                 * Otherwise connection is in a fully acceptable state.
                 * -> peek at the first 24 incoming bytes
                 */
                apr_bucket_brigade *temp;
                char *peek = NULL;
                apr_size_t peeklen;
    
                temp = apr_brigade_create(c->pool, c->bucket_alloc);
                status = ap_get_brigade(c->input_filters, temp,
                                        AP_MODE_SPECULATIVE, APR_BLOCK_READ, 24);
    
                if (status != APR_SUCCESS) {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, APLOGNO(03054)
                                  "h2_h2, error reading 24 bytes speculative");
                    apr_brigade_destroy(temp);
                    return DECLINED;
                }
    
                apr_brigade_pflatten(temp, &peek, &peeklen, c->pool);
                if ((peeklen >= 24) && !memcmp(H2_MAGIC_TOKEN, peek, 24)) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                                  "h2_h2, direct mode detected");
                    ctx = h2_conn_ctx_create_for_c1(c, c->base_server,
                                                    ap_ssl_conn_is_ssl(c)? "h2" : "h2c");
                }
                else if (APLOGctrace2(c)) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                                  "h2_h2, not detected in %d bytes(base64): %s",
                                  (int)peeklen, h2_util_base64url_encode(peek, peeklen, c->pool));
                }
                apr_brigade_destroy(temp);
            }
        }
    
        if (!ctx) goto declined;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "process_conn");
        if (!ctx->session) {
            status = h2_c1_setup(c, NULL, ctx->server? ctx->server : c->base_server);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, c, "conn_setup");
            if (status != APR_SUCCESS) {
                h2_conn_ctx_detach(c);
                return !OK;
            }
        }
        return h2_c1_run(c);
    
    declined:
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
        return DECLINED;
    }
    
    static int h2_c1_hook_pre_close(conn_rec *c)
    {
        h2_conn_ctx_t *ctx;
    
        /* secondary connection? */
        if (c->master) {
            return DECLINED;
        }
    
        ctx = h2_conn_ctx_get(c);
        if (ctx) {
            /* If the session has been closed correctly already, we will not
             * find a h2_conn_ctx_there. The presence indicates that the session
             * is still ongoing. */
            return h2_c1_pre_close(ctx, c);
        }
        return DECLINED;
    }
    
    static const char* const mod_ssl[]        = { "mod_ssl.c", NULL};
    static const char* const mod_reqtimeout[] = { "mod_ssl.c", "mod_reqtimeout.c", NULL};
    
    void h2_c1_register_hooks(void)
    {
        /* Our main processing needs to run quite late. Definitely after mod_ssl,
         * as we need its connection filters, but also before reqtimeout as its
         * method of timeouts is specific to HTTP/1.1 (as of now).
         * The core HTTP/1 processing run as REALLY_LAST, so we will have
         * a chance to take over before it.
         */
        ap_hook_process_connection(h2_c1_hook_process_connection,
                                   mod_reqtimeout, NULL, APR_HOOK_LAST);
    
        /* One last chance to properly say goodbye if we have not done so
         * already. */
        ap_hook_pre_close_connection(h2_c1_hook_pre_close, NULL, mod_ssl, APR_HOOK_LAST);
    }
    
    ������httpd-2.4.64/modules/http2/h2_headers.c�������������������������������������������������������������0000664�0001751�0001751�00000015217�14576247350�017526� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    
    #include <apr_strings.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <util_time.h>
    
    #include <nghttp2/nghttp2.h>
    
    #include "h2_private.h"
    #include "h2_protocol.h"
    #include "h2_config.h"
    #include "h2_util.h"
    #include "h2_request.h"
    #include "h2_headers.h"
    
    #if !AP_HAS_RESPONSE_BUCKETS
    
    static int is_unsafe(server_rec *s) 
    {
        core_server_config *conf = ap_get_core_module_config(s->module_config);
        return (conf->http_conformance == AP_HTTP_CONFORMANCE_UNSAFE);
    }
    
    typedef struct {
        apr_bucket_refcount refcount;
        h2_headers *headers;
    } h2_bucket_headers;
     
    static apr_status_t bucket_read(apr_bucket *b, const char **str,
                                    apr_size_t *len, apr_read_type_e block)
    {
        (void)b;
        (void)block;
        *str = NULL;
        *len = 0;
        return APR_SUCCESS;
    }
    
    apr_bucket * h2_bucket_headers_make(apr_bucket *b, h2_headers *r)
    {
        h2_bucket_headers *br;
    
        br = apr_bucket_alloc(sizeof(*br), b->list);
        br->headers = r;
    
        b = apr_bucket_shared_make(b, br, 0, 0);
        b->type = &h2_bucket_type_headers;
        b->length = 0;
        
        return b;
    } 
    
    apr_bucket * h2_bucket_headers_create(apr_bucket_alloc_t *list, 
                                           h2_headers *r)
    {
        apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
    
        APR_BUCKET_INIT(b);
        b->free = apr_bucket_free;
        b->list = list;
        b = h2_bucket_headers_make(b, r);
        return b;
    }
                                           
    h2_headers *h2_bucket_headers_get(apr_bucket *b)
    {
        if (H2_BUCKET_IS_HEADERS(b)) {
            return ((h2_bucket_headers *)b->data)->headers;
        }
        return NULL;
    }
    
    static void bucket_destroy(void *data)
    {
        h2_bucket_headers *h = data;
    
        if (apr_bucket_shared_destroy(h)) {
            apr_bucket_free(h);
        }
    }
    
    const apr_bucket_type_t h2_bucket_type_headers = {
        "H2HEADERS", 5, APR_BUCKET_METADATA,
        bucket_destroy,
        bucket_read,
        apr_bucket_setaside_noop,
        apr_bucket_split_notimpl,
        apr_bucket_shared_copy
    };
    
    apr_bucket *h2_bucket_headers_clone(apr_bucket *b, apr_pool_t *pool,
                                        apr_bucket_alloc_t *list)
    {
        h2_headers *hdrs = ((h2_bucket_headers *)b->data)->headers;
        return h2_bucket_headers_create(list, h2_headers_clone(pool, hdrs));
    }
    
    
    h2_headers *h2_headers_create(int status, const apr_table_t *headers_in, 
                                  const apr_table_t *notes, apr_off_t raw_bytes,
                                  apr_pool_t *pool)
    {
        h2_headers *headers = apr_pcalloc(pool, sizeof(h2_headers));
        headers->status    = status;
        headers->headers   = (headers_in? apr_table_clone(pool, headers_in)
                               : apr_table_make(pool, 5));
        headers->notes     = (notes? apr_table_clone(pool, notes)
                               : apr_table_make(pool, 5));
        return headers;
    }
    
    static int add_header_lengths(void *ctx, const char *name, const char *value) 
    {
        apr_size_t *plen = ctx;
        *plen += strlen(name) + strlen(value); 
        return 1;
    }
    
    apr_size_t h2_headers_length(h2_headers *headers)
    {
        apr_size_t len = 0;
        apr_table_do(add_header_lengths, &len, headers->headers, NULL);
        return len;
    }
    
    apr_size_t h2_bucket_headers_headers_length(apr_bucket *b)
    {
        h2_headers *h = h2_bucket_headers_get(b);
        return h? h2_headers_length(h) : 0;
    }
    
    h2_headers *h2_headers_rcreate(request_rec *r, int status,
                                   const apr_table_t *header, apr_pool_t *pool)
    {
        h2_headers *headers = h2_headers_create(status, header, r->notes, 0, pool);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, headers->status, r,
                      "h2_headers_rcreate(%ld): status=%d",
                      (long)r->connection->id, status);
        if (headers->status == HTTP_FORBIDDEN) {
            request_rec *r_prev;
            for (r_prev = r; r_prev != NULL; r_prev = r_prev->prev) {
                const char *cause = apr_table_get(r_prev->notes, "ssl-renegotiate-forbidden");
                if (cause) {
                    /* This request triggered a TLS renegotiation that is not allowed
                     * in HTTP/2. Tell the client that it should use HTTP/1.1 for this.
                     */
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, headers->status, r,
                                  APLOGNO(10399)
                                  "h2_headers(%ld): renegotiate forbidden, cause: %s",
                                  (long)r->connection->id, cause);
                    headers->status = H2_ERR_HTTP_1_1_REQUIRED;
                    break;
                }
            }
        }
        if (is_unsafe(r->server)) {
            apr_table_setn(headers->notes, H2_HDR_CONFORMANCE, H2_HDR_CONFORMANCE_UNSAFE);
        }
        if (h2_config_rgeti(r, H2_CONF_PUSH) == 0 && h2_config_sgeti(r->server, H2_CONF_PUSH) != 0) {
            apr_table_setn(headers->notes, H2_PUSH_MODE_NOTE, "0");
        }
        return headers;
    }
    
    h2_headers *h2_headers_copy(apr_pool_t *pool, h2_headers *h)
    {
        return h2_headers_create(h->status, h->headers, h->notes, h->raw_bytes, pool);
    }
    
    h2_headers *h2_headers_clone(apr_pool_t *pool, h2_headers *h)
    {
        return h2_headers_create(h->status, h->headers, h->notes, h->raw_bytes, pool);
    }
    
    h2_headers *h2_headers_die(apr_status_t type,
                                 const h2_request *req, apr_pool_t *pool)
    {
        h2_headers *headers;
        char *date;
        
        headers = apr_pcalloc(pool, sizeof(h2_headers));
        headers->status    = (type >= 200 && type < 600)? type : 500;
        headers->headers        = apr_table_make(pool, 5);
        headers->notes          = apr_table_make(pool, 5);
    
        date = apr_palloc(pool, APR_RFC822_DATE_LEN);
        ap_recent_rfc822_date(date, req? req->request_time : apr_time_now());
        apr_table_setn(headers->headers, "Date", date);
        apr_table_setn(headers->headers, "Server", ap_get_server_banner());
        
        return headers;
    }
    
    int h2_headers_are_final_response(h2_headers *headers)
    {
        return headers->status >= 200;
    }
    
    #endif /* !AP_HAS_RESPONSE_BUCKETS */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_stream.h��������������������������������������������������������������0000664�0001751�0001751�00000030157�14603243707�017404� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_stream__
    #define __mod_h2__h2_stream__
    
    #include <http_protocol.h>
    
    #include "h2.h"
    #include "h2_headers.h"
    
    /**
     * A HTTP/2 stream, e.g. a client request+response in HTTP/1.1 terms.
     * 
     * A stream always belongs to a h2_session, the one managing the
     * connection to the client. The h2_session writes to the h2_stream,
     * adding HEADERS and DATA and finally an EOS. When headers are done,
     * h2_stream is scheduled for handling, which is expected to produce
     * h2_headers/RESPONSE buckets.
     *
     * The h2_headers may be followed by more h2_headers (interim responses) and
     * by DATA frames read from the h2_stream until EOS is reached. Trailers
     * are send when a last h2_headers is received. This always closes the stream
     * output.
     */
    
    struct h2_mplx;
    struct h2_priority;
    struct h2_request;
    struct h2_session;
    struct h2_bucket_beam;
    
    typedef struct h2_stream h2_stream;
    
    typedef void h2_stream_state_cb(void *ctx, h2_stream *stream);
    typedef void h2_stream_event_cb(void *ctx, h2_stream *stream, 
                                    h2_stream_event_t ev);
    
    /**
     * Callback structure for events and stream state transisitions
     */
    typedef struct h2_stream_monitor {
        void *ctx;
        h2_stream_state_cb *on_state_enter;   /* called when a state is entered */
        h2_stream_state_cb *on_state_invalid; /* called when an invalid state change
                                                 was detected */
        h2_stream_event_cb *on_state_event;   /* called right before the given event
                                                 result in a new stream state */
        h2_stream_event_cb *on_event;         /* called for events that do not 
                                                 trigger a state change */
    } h2_stream_monitor;
    
    #ifdef AP_DEBUG
    #define H2_STRM_MAGIC_OK     0x5354524d
    #define H2_STRM_MAGIC_SDEL   0x5344454c
    #define H2_STRM_MAGIC_PDEL   0x5044454c
    
    #define H2_STRM_ASSIGN_MAGIC(s,m)  ((s)->magic = m)
    #define H2_STRM_ASSERT_MAGIC(s,m)  ap_assert((s)->magic == m)
    #else
    #define H2_STRM_ASSIGN_MAGIC(s,m)  ((void)0)
    #define H2_STRM_ASSERT_MAGIC(s,m)  ((void)0)
    #endif
    
    struct h2_stream {
    #ifdef AP_DEBUG
        uint32_t magic;
    #endif
        int id;                     /* http2 stream identifier */
        int initiated_on;           /* initiating stream id (PUSH) or 0 */
        apr_pool_t *pool;           /* the memory pool for this stream */
        struct h2_session *session; /* the session this stream belongs to */
        h2_stream_state_t state;    /* state of this stream */
        
        apr_time_t created;         /* when stream was created */
        
        const struct h2_request *request; /* the request made in this stream */
        struct h2_request *rtmp;    /* request being assembled */
        apr_table_t *trailers_in;   /* optional, incoming trailers */
        int request_headers_added;  /* number of request headers added */
        int request_headers_failed; /* number of request headers failed to add */
    
    #if AP_HAS_RESPONSE_BUCKETS
        ap_bucket_response *response; /* the final, non-interim response or NULL */
    #else
        struct h2_headers *response; /* the final, non-interim response or NULL */
    #endif
    
        struct h2_bucket_beam *input;
        apr_bucket_brigade *in_buffer;
        int in_window_size;
        apr_time_t in_last_write;
        
        struct h2_bucket_beam *output;
        apr_bucket_brigade *out_buffer;
    
        int rst_error;              /* stream error for RST_STREAM */
        unsigned int aborted   : 1; /* was aborted */
        unsigned int scheduled : 1; /* stream has been scheduled */
        unsigned int input_closed : 1; /* no more request data/trailers coming */
        unsigned int push_policy;   /* which push policy to use for this request */
        unsigned int sent_trailers : 1; /* trailers have been submitted */
        unsigned int output_eos : 1; /* output EOS in buffer/sent */
    
        conn_rec *c2;               /* connection processing stream */
        
        const h2_priority *pref_priority; /* preferred priority for this stream */
        apr_off_t out_frames;       /* # of frames sent out */
        apr_off_t out_frame_octets; /* # of RAW frame octets sent out */
        apr_off_t out_data_frames;  /* # of DATA frames sent */
        apr_off_t out_data_octets;  /* # of DATA octets (payload) sent */
        apr_off_t in_data_frames;   /* # of DATA frames received */
        apr_off_t in_data_octets;   /* # of DATA octets (payload) received */
        apr_off_t in_trailer_octets; /* # of HEADER octets (payload) received in trailers */
        
        h2_stream_monitor *monitor; /* optional monitor for stream states */
    };
    
    
    #define H2_STREAM_RST(s, def)    (s->rst_error? s->rst_error : (def))
    
    /**
     * Create a stream in H2_SS_IDLE state.
     * @param id      the stream identifier
     * @param pool    the memory pool to use for this stream
     * @param session the session this stream belongs to
     * @param monitor an optional monitor to be called for events and 
     *                state transisitions
     * @param initiated_on the id of the stream this one was initiated on (PUSH)
     *
     * @return the newly opened stream
     */
    h2_stream *h2_stream_create(int id, apr_pool_t *pool, 
                                struct h2_session *session,
                                h2_stream_monitor *monitor,
                                int initiated_on);
    
    /**
     * Destroy memory pool if still owned by the stream.
     */
    void h2_stream_destroy(h2_stream *stream);
    
    /**
     * Perform any late initialization before stream starts processing.
     */
    apr_status_t h2_stream_prepare_processing(h2_stream *stream);
    
    /*
     * Set a new monitor for this stream, replacing any existing one. Can
     * be called with NULL to have no monitor installed.
     */
    void h2_stream_set_monitor(h2_stream *stream, h2_stream_monitor *monitor);
    
    /**
     * Dispatch (handle) an event on the given stream.
     * @param stream  the streama the event happened on
     * @param ev      the type of event
     */
    void h2_stream_dispatch(h2_stream *stream, h2_stream_event_t ev);
    
    /**
     * Determine if stream is at given state.
     * @param stream the stream to check
     * @param state the state to look for
     * @return != 0 iff stream is at given state.
     */
    int h2_stream_is_at(const h2_stream *stream, h2_stream_state_t state);
    
    /**
     * Determine if stream is reached given state or is past this state.
     * @param stream the stream to check
     * @param state the state to look for
     * @return != 0 iff stream is at or past given state.
     */
    int h2_stream_is_at_or_past(const h2_stream *stream, h2_stream_state_t state);
    
    /**
     * Cleanup references into requst processing.
     *
     * @param stream the stream to cleanup
     */
    void h2_stream_cleanup(h2_stream *stream);
    
    /**
     * Notify the stream that amount bytes have been consumed of its input
     * since the last invocation of this method (delta amount).
     */
    apr_status_t h2_stream_in_consumed(h2_stream *stream, apr_off_t amount);
    
    /**
     * Set complete stream headers from given h2_request.
     * 
     * @param stream stream to write request to
     * @param r the request with all the meta data
     * @param eos != 0 iff stream input is closed
     */
    void h2_stream_set_request(h2_stream *stream, const h2_request *r);
    
    /**
     * Set complete stream header from given request_rec.
     * 
     * @param stream stream to write request to
     * @param r the request with all the meta data
     * @param eos != 0 iff stream input is closed
     */
    apr_status_t h2_stream_set_request_rec(h2_stream *stream, 
                                           request_rec *r, int eos);
    
    /*
     * Add a HTTP/2 header (including pseudo headers) or trailer 
     * to the given stream, depending on stream state.
     *
     * @param stream stream to write the header to
     * @param name the name of the HTTP/2 header
     * @param nlen the number of characters in name
     * @param value the header value
     * @param vlen the number of characters in value
     */
    apr_status_t h2_stream_add_header(h2_stream *stream,
                                      const char *name, size_t nlen,
                                      const char *value, size_t vlen);
                                      
    /* End the construction of request headers */
    apr_status_t h2_stream_end_headers(h2_stream *stream, int eos, size_t raw_bytes);
    
    
    apr_status_t h2_stream_send_frame(h2_stream *stream, int frame_type, int flags, size_t frame_len);
    apr_status_t h2_stream_recv_frame(h2_stream *stream, int frame_type, int flags, size_t frame_len);
    
    /*
     * Process a frame of received DATA.
     *
     * @param stream stream to write the data to
     * @param flags the frame flags
     * @param data the beginning of the bytes to write
     * @param len the number of bytes to write
     */
    apr_status_t h2_stream_recv_DATA(h2_stream *stream, uint8_t flags,
                                     const uint8_t *data, size_t len);
    
    /**
     * Reset the stream. Stream write/reads will return errors afterwards.
     *
     * @param stream the stream to reset
     * @param error_code the HTTP/2 error code
     */
    void h2_stream_rst(h2_stream *stream, int error_code);
    
    /**
     * Stream input signals change. Take necessary actions.
     * @param stream the stream to read output for
     */
    void h2_stream_on_input_change(h2_stream *stream);
    
    /**
     * Stream output signals change. Take necessary actions.
     * @param stream the stream to read output for
     */
    void h2_stream_on_output_change(h2_stream *stream);
    
    /**
     * Read a maximum number of bytes into the bucket brigade.
     * 
     * @param stream the stream to read from
     * @param bb the brigade to append output to
     * @param plen (in-/out) max. number of bytes to append and on return actual
     *        number of bytes appended to brigade
     * @param peos (out) != 0 iff end of stream has been reached while reading
     * @return APR_SUCCESS if out information was computed successfully.
     *         APR_EAGAIN if not data is available and end of stream has not been
     *         reached yet.
     */
    apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb, 
                                   apr_off_t *plen, int *peos);
    
    /**
     * Get optional trailers for this stream, may be NULL. Meaningful
     * results can only be expected when the end of the response body has
     * been reached.
     *
     * @param stream to ask for trailers
     * @return trailers for NULL
     */
    apr_table_t *h2_stream_get_trailers(h2_stream *stream);
    
    /**
     * Submit any server push promises on this stream and schedule
     * the streams for these.
     *
     * @param stream the stream for which to submit
     */
    #if AP_HAS_RESPONSE_BUCKETS
    apr_status_t h2_stream_submit_pushes(h2_stream *stream,
                                         ap_bucket_response *response);
    #else
    apr_status_t h2_stream_submit_pushes(h2_stream *stream,
                                         struct h2_headers *response);
    #endif
    
    /**
     * Get priority information set for this stream.
     */
    #if AP_HAS_RESPONSE_BUCKETS
    const struct h2_priority *h2_stream_get_priority(h2_stream *stream,
                                                     ap_bucket_response *response);
    #else
    const struct h2_priority *h2_stream_get_priority(h2_stream *stream,
                                                     struct h2_headers *response);
    #endif
    
    /**
     * Return a textual representation of the stream state as in RFC 7540
     * nomenclator, all caps, underscores.
     */
    const char *h2_stream_state_str(const h2_stream *stream);
    
    /**
     * Determine if stream is ready for submitting a response or a RST
     * @param stream the stream to check
     */
    int h2_stream_is_ready(h2_stream *stream);
    
    int h2_stream_wants_send_data(h2_stream *stream);
    
    #define H2_STRM_MSG(s, msg)     \
        "h2_stream(%d-%lu-%d,%s): "msg, s->session->child_num, \
        (unsigned long)s->session->id, s->id, h2_stream_state_str(s)
    
    #define H2_STRM_LOG(aplogno, s, msg)    aplogno H2_STRM_MSG(s, msg)
    
    #endif /* defined(__mod_h2__h2_stream__) */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_bucket_beam.c���������������������������������������������������������0000664�0001751�0001751�00000065267�14473316336�020363� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_lib.h>
    #include <apr_atomic.h>
    #include <apr_strings.h>
    #include <apr_time.h>
    #include <apr_buckets.h>
    #include <apr_thread_mutex.h>
    #include <apr_thread_cond.h>
    
    #include <httpd.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    
    #include "h2_private.h"
    #include "h2_conn_ctx.h"
    #include "h2_headers.h"
    #include "h2_util.h"
    #include "h2_bucket_beam.h"
    
    
    #define H2_BLIST_INIT(b)        APR_RING_INIT(&(b)->list, apr_bucket, link);
    #define H2_BLIST_SENTINEL(b)    APR_RING_SENTINEL(&(b)->list, apr_bucket, link)
    #define H2_BLIST_EMPTY(b)       APR_RING_EMPTY(&(b)->list, apr_bucket, link)
    #define H2_BLIST_FIRST(b)       APR_RING_FIRST(&(b)->list)
    #define H2_BLIST_LAST(b)	APR_RING_LAST(&(b)->list)
    #define H2_BLIST_INSERT_HEAD(b, e) do {				\
    	apr_bucket *ap__b = (e);                                        \
    	APR_RING_INSERT_HEAD(&(b)->list, ap__b, apr_bucket, link);	\
        } while (0)
    #define H2_BLIST_INSERT_TAIL(b, e) do {				\
    	apr_bucket *ap__b = (e);					\
    	APR_RING_INSERT_TAIL(&(b)->list, ap__b, apr_bucket, link);	\
        } while (0)
    #define H2_BLIST_CONCAT(a, b) do {					\
            APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link);	\
        } while (0)
    #define H2_BLIST_PREPEND(a, b) do {					\
            APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link);	\
        } while (0)
    
    
    static int buffer_is_empty(h2_bucket_beam *beam);
    static apr_off_t get_buffered_data_len(h2_bucket_beam *beam);
    
    static int h2_blist_count(h2_blist *blist)
    {
        apr_bucket *b;
        int count = 0;
    
        for (b = H2_BLIST_FIRST(blist); b != H2_BLIST_SENTINEL(blist);
             b = APR_BUCKET_NEXT(b)) {
            ++count;
        }
        return count;
    }
    
    #define H2_BEAM_LOG(beam, c, level, rv, msg, bb) \
        do { \
            if (APLOG_C_IS_LEVEL((c),(level))) { \
                char buffer[4 * 1024]; \
                apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \
                len = bb? h2_util_bb_print(buffer, bmax, "", "", bb) : 0; \
                ap_log_cerror(APLOG_MARK, (level), rv, (c), \
                              "BEAM[%s,%s%sdata=%ld,buckets(send/consumed)=%d/%d]: %s %s", \
                              (beam)->name, \
                              (beam)->aborted? "aborted," : "", \
                              buffer_is_empty(beam)? "empty," : "", \
                              (long)get_buffered_data_len(beam), \
                              h2_blist_count(&(beam)->buckets_to_send), \
                              h2_blist_count(&(beam)->buckets_consumed), \
                              (msg), len? buffer : ""); \
            } \
        } while (0)
    
    
    static int bucket_is_mmap(apr_bucket *b)
    {
    #if APR_HAS_MMAP
        return APR_BUCKET_IS_MMAP(b);
    #else
        /* if it is not defined as enabled, it should always be no */
        return 0;
    #endif
    }
    
    static apr_off_t bucket_mem_used(apr_bucket *b)
    {
        if (APR_BUCKET_IS_FILE(b) || bucket_is_mmap(b)) {
            return 0;
        }
        else {
            /* should all have determinate length */
            return (apr_off_t)b->length;
        }
    }
    
    static int report_consumption(h2_bucket_beam *beam, int locked)
    {
        int rv = 0;
        apr_off_t len = beam->recv_bytes - beam->recv_bytes_reported;
        h2_beam_io_callback *cb = beam->cons_io_cb;
         
        if (len > 0) {
            if (cb) {
                void *ctx = beam->cons_ctx;
                
                if (locked) apr_thread_mutex_unlock(beam->lock);
                cb(ctx, beam, len);
                if (locked) apr_thread_mutex_lock(beam->lock);
                rv = 1;
            }
            beam->recv_bytes_reported += len;
        }
        return rv;
    }
    
    static apr_size_t calc_buffered(h2_bucket_beam *beam)
    {
        apr_size_t len = 0;
        apr_bucket *b;
        for (b = H2_BLIST_FIRST(&beam->buckets_to_send);
             b != H2_BLIST_SENTINEL(&beam->buckets_to_send);
             b = APR_BUCKET_NEXT(b)) {
            if (b->length == ((apr_size_t)-1)) {
                /* do not count */
            }
            else if (APR_BUCKET_IS_FILE(b) || bucket_is_mmap(b)) {
                /* if unread, has no real mem footprint. */
            }
            else {
                len += b->length;
            }
        }
        return len;
    }
    
    static void purge_consumed_buckets(h2_bucket_beam *beam)
    {
        apr_bucket *b;
        /* delete all sender buckets in purge brigade, needs to be called
         * from sender thread only */
        while (!H2_BLIST_EMPTY(&beam->buckets_consumed)) {
            b = H2_BLIST_FIRST(&beam->buckets_consumed);
            if(AP_BUCKET_IS_EOR(b)) {
              APR_BUCKET_REMOVE(b);
              H2_BLIST_INSERT_TAIL(&beam->buckets_eor, b);
            }
            else {
              apr_bucket_delete(b);
            }
        }
    }
    
    static void purge_eor_buckets(h2_bucket_beam *beam)
    {
        apr_bucket *b;
        /* delete all sender buckets in purge brigade, needs to be called
         * from sender thread only */
        while (!H2_BLIST_EMPTY(&beam->buckets_eor)) {
            b = H2_BLIST_FIRST(&beam->buckets_eor);
            apr_bucket_delete(b);
        }
    }
    
    static apr_size_t calc_space_left(h2_bucket_beam *beam)
    {
        if (beam->max_buf_size > 0) {
            apr_size_t len = calc_buffered(beam);
            return (beam->max_buf_size > len? (beam->max_buf_size - len) : 0);
        }
        return APR_SIZE_MAX;
    }
    
    static int buffer_is_empty(h2_bucket_beam *beam)
    {
        return H2_BLIST_EMPTY(&beam->buckets_to_send);
    }
    
    static apr_status_t wait_not_empty(h2_bucket_beam *beam, conn_rec *c, apr_read_type_e block)
    {
        apr_status_t rv = APR_SUCCESS;
        
        while (buffer_is_empty(beam) && APR_SUCCESS == rv) {
            if (beam->aborted) {
                rv = APR_ECONNABORTED;
            }
            else if (beam->closed) {
                rv = APR_EOF;
            }
            else if (APR_BLOCK_READ != block) {
                rv = APR_EAGAIN;
            }
            else if (beam->timeout > 0) {
                H2_BEAM_LOG(beam, c, APLOG_TRACE2, rv, "wait_not_empty, timeout", NULL);
                rv = apr_thread_cond_timedwait(beam->change, beam->lock, beam->timeout);
            }
            else {
                H2_BEAM_LOG(beam, c, APLOG_TRACE2, rv, "wait_not_empty, forever", NULL);
                rv = apr_thread_cond_wait(beam->change, beam->lock);
            }
        }
        return rv;
    }
    
    static apr_status_t wait_not_full(h2_bucket_beam *beam, conn_rec *c,
                                      apr_read_type_e block,
                                      apr_size_t *pspace_left)
    {
        apr_status_t rv = APR_SUCCESS;
        apr_size_t left;
        
        while (0 == (left = calc_space_left(beam)) && APR_SUCCESS == rv) {
            if (beam->aborted) {
                rv = APR_ECONNABORTED;
            }
            else if (block != APR_BLOCK_READ) {
                rv = APR_EAGAIN;
            }
            else {
                if (beam->timeout > 0) {
                    H2_BEAM_LOG(beam, c, APLOG_TRACE2, rv, "wait_not_full, timeout", NULL);
                    rv = apr_thread_cond_timedwait(beam->change, beam->lock, beam->timeout);
                }
                else {
                    H2_BEAM_LOG(beam, c, APLOG_TRACE2, rv, "wait_not_full, forever", NULL);
                    rv = apr_thread_cond_wait(beam->change, beam->lock);
                }
            }
        }
        *pspace_left = left;
        return rv;
    }
    
    static void h2_blist_cleanup(h2_blist *bl)
    {
        apr_bucket *e;
    
        while (!H2_BLIST_EMPTY(bl)) {
            e = H2_BLIST_FIRST(bl);
            apr_bucket_delete(e);
        }
    }
    
    static void beam_shutdown(h2_bucket_beam *beam, apr_shutdown_how_e how)
    {
        if (!beam->pool) {
            /* pool being cleared already */
            return;
        }
    
        /* shutdown both receiver and sender? */
        if (how == APR_SHUTDOWN_READWRITE) {
            beam->cons_io_cb = NULL;
            beam->recv_cb = NULL;
            beam->eagain_cb = NULL;
        }
    
        /* shutdown sender (or both)? */
        if (how != APR_SHUTDOWN_READ) {
            purge_consumed_buckets(beam);
            h2_blist_cleanup(&beam->buckets_to_send);
        }
    }
    
    static apr_status_t beam_cleanup(void *data)
    {
        h2_bucket_beam *beam = data;
        beam_shutdown(beam, APR_SHUTDOWN_READWRITE);
        purge_eor_buckets(beam);
        beam->pool = NULL; /* the pool is clearing now */
        return APR_SUCCESS;
    }
    
    apr_status_t h2_beam_destroy(h2_bucket_beam *beam, conn_rec *c)
    {
        if (beam->pool) {
            H2_BEAM_LOG(beam, c, APLOG_TRACE2, 0, "destroy", NULL);
            apr_pool_cleanup_run(beam->pool, beam, beam_cleanup);
        }
        H2_BEAM_LOG(beam, c, APLOG_TRACE2, 0, "destroyed", NULL);
        return APR_SUCCESS;
    }
    
    apr_status_t h2_beam_create(h2_bucket_beam **pbeam, conn_rec *from,
                                apr_pool_t *pool, int id, const char *tag,
                                apr_size_t max_buf_size,
                                apr_interval_time_t timeout)
    {
        h2_bucket_beam *beam;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(from);
        apr_status_t rv;
        
        beam = apr_pcalloc(pool, sizeof(*beam));
        beam->pool = pool;
        beam->from = from;
        beam->id = id;
        beam->name = apr_psprintf(pool, "%s-%d-%s",
                                  conn_ctx->id, id, tag);
    
        H2_BLIST_INIT(&beam->buckets_to_send);
        H2_BLIST_INIT(&beam->buckets_consumed);
        H2_BLIST_INIT(&beam->buckets_eor);
        beam->tx_mem_limits = 1;
        beam->max_buf_size = max_buf_size;
        beam->timeout = timeout;
    
        rv = apr_thread_mutex_create(&beam->lock, APR_THREAD_MUTEX_DEFAULT, pool);
        if (APR_SUCCESS != rv) goto cleanup;
        rv = apr_thread_cond_create(&beam->change, pool);
        if (APR_SUCCESS != rv) goto cleanup;
        apr_pool_pre_cleanup_register(pool, beam, beam_cleanup);
    
    cleanup:
        H2_BEAM_LOG(beam, from, APLOG_TRACE2, rv, "created", NULL);
        *pbeam = (APR_SUCCESS == rv)? beam : NULL;
        return rv;
    }
    
    void h2_beam_buffer_size_set(h2_bucket_beam *beam, apr_size_t buffer_size)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->max_buf_size = buffer_size;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    void h2_beam_set_copy_files(h2_bucket_beam * beam, int enabled)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->copy_files = enabled;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    apr_size_t h2_beam_buffer_size_get(h2_bucket_beam *beam)
    {
        apr_size_t buffer_size = 0;
        
        apr_thread_mutex_lock(beam->lock);
        buffer_size = beam->max_buf_size;
        apr_thread_mutex_unlock(beam->lock);
        return buffer_size;
    }
    
    apr_interval_time_t h2_beam_timeout_get(h2_bucket_beam *beam)
    {
        apr_interval_time_t timeout;
    
        apr_thread_mutex_lock(beam->lock);
        timeout = beam->timeout;
        apr_thread_mutex_unlock(beam->lock);
        return timeout;
    }
    
    void h2_beam_timeout_set(h2_bucket_beam *beam, apr_interval_time_t timeout)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->timeout = timeout;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    void h2_beam_abort(h2_bucket_beam *beam, conn_rec *c)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->aborted = 1;
        if (c == beam->from) {
            /* sender aborts */
            if (beam->send_cb) {
                beam->send_cb(beam->send_ctx, beam);
            }
            if (beam->was_empty_cb && buffer_is_empty(beam)) {
                beam->was_empty_cb(beam->was_empty_ctx, beam);
            }
            /* no more consumption reporting to sender */
            report_consumption(beam, 1);
            beam->cons_ctx = NULL;
    
            beam_shutdown(beam, APR_SHUTDOWN_WRITE);
        }
        else {
            /* receiver aborts */
            beam_shutdown(beam, APR_SHUTDOWN_READ);
        }
        apr_thread_cond_broadcast(beam->change);
        apr_thread_mutex_unlock(beam->lock);
    }
    
    void h2_beam_close(h2_bucket_beam *beam, conn_rec *c)
    {
        apr_thread_mutex_lock(beam->lock);
        if (!beam->closed) {
            /* should only be called from sender */
            ap_assert(c == beam->from);
            beam->closed = 1;
            if (beam->send_cb) {
                beam->send_cb(beam->send_ctx, beam);
            }
            if (beam->was_empty_cb && buffer_is_empty(beam)) {
                beam->was_empty_cb(beam->was_empty_ctx, beam);
            }
            apr_thread_cond_broadcast(beam->change);
        }
        apr_thread_mutex_unlock(beam->lock);
    }
    
    static apr_status_t append_bucket(h2_bucket_beam *beam,
                                      apr_bucket_brigade *bb,
                                      apr_read_type_e block,
                                      apr_size_t *pspace_left,
                                      apr_off_t *pwritten)
    {
        apr_bucket *b;
        const char *data;
        apr_size_t len;
        apr_status_t rv = APR_SUCCESS;
        int can_beam = 0;
        
        (void)block;
        if (beam->aborted) {
            rv = APR_ECONNABORTED;
            goto cleanup;
        }
    
        ap_assert(beam->pool);
    
        b = APR_BRIGADE_FIRST(bb);
        if (APR_BUCKET_IS_METADATA(b)) {
            APR_BUCKET_REMOVE(b);
            apr_bucket_setaside(b, beam->pool);
            H2_BLIST_INSERT_TAIL(&beam->buckets_to_send, b);
            goto cleanup;
        }
        /* non meta bucket */
    
        /* in case of indeterminate length, we need to read the bucket,
         * so that it transforms itself into something stable. */
        if (b->length == ((apr_size_t)-1)) {
            rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) goto cleanup;
        }
    
        if (APR_BUCKET_IS_FILE(b)) {
            /* For file buckets the problem is their internal readpool that
             * is used on the first read to allocate buffer/mmap.
             * Since setting aside a file bucket will de-register the
             * file cleanup function from the previous pool, we need to
             * call that only from the sender thread.
             *
             * Currently, we do not handle file bucket with refcount > 1 as
             * the beam is then not in complete control of the file's lifetime.
             * Which results in the bug that a file get closed by the receiver
             * while the sender or the beam still have buckets using it. 
             * 
             * Additionally, we allow callbacks to prevent beaming file
             * handles across. The use case for this is to limit the number 
             * of open file handles and rather use a less efficient beam
             * transport. */
            apr_bucket_file *bf = b->data;
            can_beam = !beam->copy_files && (bf->refcount.refcount == 1);
        }
        else if (bucket_is_mmap(b)) {
            can_beam = !beam->copy_files;
        }
    
        if (b->length == 0) {
            apr_bucket_delete(b);
            rv = APR_SUCCESS;
            goto cleanup;
        }
    
        if (!*pspace_left) {
            rv = APR_EAGAIN;
            goto cleanup;
        }
    
        /* bucket is accepted and added to beam->buckets_to_send */
        if (APR_BUCKET_IS_HEAP(b)) {
            /* For heap buckets, a read from a receiver thread is fine. The
             * data will be there and live until the bucket itself is
             * destroyed. */
            rv = apr_bucket_setaside(b, beam->pool);
            if (rv != APR_SUCCESS) goto cleanup;
        }
        else if (can_beam && (APR_BUCKET_IS_FILE(b) || bucket_is_mmap(b))) {
            rv = apr_bucket_setaside(b, beam->pool);
            if (rv != APR_SUCCESS) goto cleanup;
        }
        else {
            /* we know of no special shortcut to transfer the bucket to
             * another pool without copying. So we make it a heap bucket. */
            apr_bucket *b2;
    
            rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) goto cleanup;
            /* this allocates and copies data */
            b2 = apr_bucket_heap_create(data, len, NULL, bb->bucket_alloc);
            apr_bucket_delete(b);
            b = b2;
            APR_BRIGADE_INSERT_HEAD(bb, b);
        }
        
        APR_BUCKET_REMOVE(b);
        H2_BLIST_INSERT_TAIL(&beam->buckets_to_send, b);
        *pwritten += (apr_off_t)b->length;
        if (b->length > *pspace_left) {
            *pspace_left = 0;
        }
        else {
            *pspace_left -= b->length;
        }
    
    cleanup:
        return rv;
    }
    
    apr_status_t h2_beam_send(h2_bucket_beam *beam, conn_rec *from,
                              apr_bucket_brigade *sender_bb, 
                              apr_read_type_e block,
                              apr_off_t *pwritten)
    {
        apr_status_t rv = APR_SUCCESS;
        apr_size_t space_left = 0;
        int was_empty;
    
        ap_assert(beam->pool);
    
        /* Called from the sender thread to add buckets to the beam */
        apr_thread_mutex_lock(beam->lock);
        ap_assert(beam->from == from);
        ap_assert(sender_bb);
        H2_BEAM_LOG(beam, from, APLOG_TRACE2, rv, "start send", sender_bb);
        purge_consumed_buckets(beam);
        *pwritten = 0;
        was_empty = buffer_is_empty(beam);
    
        space_left = calc_space_left(beam);
        while (!APR_BRIGADE_EMPTY(sender_bb) && APR_SUCCESS == rv) {
            rv = append_bucket(beam, sender_bb, block, &space_left, pwritten);
            if (beam->aborted) {
                goto cleanup;
            }
            else if (APR_EAGAIN == rv) {
                /* bucket was not added, as beam buffer has no space left.
                 * Trigger event callbacks, so receiver can know there is something
                 * to receive before we do a conditional wait. */
                purge_consumed_buckets(beam);
                if (beam->send_cb) {
                    beam->send_cb(beam->send_ctx, beam);
                }
                if (was_empty && beam->was_empty_cb) {
                    beam->was_empty_cb(beam->was_empty_ctx, beam);
                }
                rv = wait_not_full(beam, from, block, &space_left);
                if (APR_SUCCESS != rv) {
                    break;
                }
                was_empty = buffer_is_empty(beam);
            }
        }
    
    cleanup:
        if (beam->send_cb && !buffer_is_empty(beam)) {
            beam->send_cb(beam->send_ctx, beam);
        }
        if (was_empty && beam->was_empty_cb && !buffer_is_empty(beam)) {
            beam->was_empty_cb(beam->was_empty_ctx, beam);
        }
        apr_thread_cond_broadcast(beam->change);
    
        report_consumption(beam, 1);
        if (beam->aborted) {
            rv = APR_ECONNABORTED;
        }
        H2_BEAM_LOG(beam, from, APLOG_TRACE2, rv, "end send", sender_bb);
        if(rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv) && sender_bb != NULL) {
            apr_brigade_cleanup(sender_bb);
        }
        apr_thread_mutex_unlock(beam->lock);
        return rv;
    }
    
    apr_status_t h2_beam_receive(h2_bucket_beam *beam,
                                 conn_rec *to,
                                 apr_bucket_brigade *bb, 
                                 apr_read_type_e block,
                                 apr_off_t readbytes)
    {
        apr_bucket *bsender, *brecv, *ng;
        int transferred = 0;
        apr_status_t rv = APR_SUCCESS;
        apr_off_t remain;
        int consumed_buckets = 0;
    
        apr_thread_mutex_lock(beam->lock);
        H2_BEAM_LOG(beam, to, APLOG_TRACE2, 0, "start receive", bb);
        if (readbytes <= 0) {
            readbytes = (apr_off_t)APR_SIZE_MAX;
        }
        remain = readbytes;
    
    transfer:
        if (beam->aborted) {
            beam_shutdown(beam, APR_SHUTDOWN_READ);
            rv = APR_ECONNABORTED;
            goto leave;
        }
    
        ap_assert(beam->pool);
    
        /* transfer from our sender brigade, transforming sender buckets to
         * receiver ones until we have enough */
        while (remain >= 0 && !H2_BLIST_EMPTY(&beam->buckets_to_send)) {
    
            brecv = NULL;
            bsender = H2_BLIST_FIRST(&beam->buckets_to_send);
            if (bsender->length > 0 && remain <= 0) {
                break;
            }
    
            if (APR_BUCKET_IS_METADATA(bsender)) {
                /* we need a real copy into the receivers bucket_alloc */
                if (APR_BUCKET_IS_EOS(bsender)) {
                    /* this closes the beam */
                    beam->closed = 1;
                    brecv = apr_bucket_eos_create(bb->bucket_alloc);
                }
                else if (APR_BUCKET_IS_FLUSH(bsender)) {
                    brecv = apr_bucket_flush_create(bb->bucket_alloc);
                }
    #if AP_HAS_RESPONSE_BUCKETS
                else if (AP_BUCKET_IS_RESPONSE(bsender)) {
                    brecv = ap_bucket_response_clone(bsender, bb->p, bb->bucket_alloc);
                }
                else if (AP_BUCKET_IS_REQUEST(bsender)) {
                    brecv = ap_bucket_request_clone(bsender, bb->p, bb->bucket_alloc);
                }
                else if (AP_BUCKET_IS_HEADERS(bsender)) {
                    brecv = ap_bucket_headers_clone(bsender, bb->p, bb->bucket_alloc);
                }
    #else
                else if (H2_BUCKET_IS_HEADERS(bsender)) {
                    brecv = h2_bucket_headers_clone(bsender, bb->p, bb->bucket_alloc);
                }
    #endif /* AP_HAS_RESPONSE_BUCKETS */
                else if (AP_BUCKET_IS_ERROR(bsender)) {
                    ap_bucket_error *eb = bsender->data;
                    brecv = ap_bucket_error_create(eb->status, eb->data,
                                                   bb->p, bb->bucket_alloc);
                }
            }
            else if (bsender->length == 0) {
                /* nop */
            }
    #if APR_HAS_MMAP
            else if (APR_BUCKET_IS_MMAP(bsender)) {
                apr_bucket_mmap *bmmap = bsender->data;
                apr_mmap_t *mmap;
                rv = apr_mmap_dup(&mmap, bmmap->mmap, bb->p);
                if (rv != APR_SUCCESS) goto leave;
                brecv = apr_bucket_mmap_create(mmap, bsender->start, bsender->length, bb->bucket_alloc);
            }
    #endif
            else if (APR_BUCKET_IS_FILE(bsender)) {
                /* This is setaside into the target brigade pool so that
                 * any read operation messes with that pool and not
                 * the sender one. */
                apr_bucket_file *f = (apr_bucket_file *)bsender->data;
                apr_file_t *fd = f->fd;
                int setaside = (f->readpool != bb->p);
    
                if (setaside) {
                    rv = apr_file_setaside(&fd, fd, bb->p);
                    if (rv != APR_SUCCESS) goto leave;
                }
                ng = apr_brigade_insert_file(bb, fd, bsender->start, (apr_off_t)bsender->length,
                                             bb->p);
    #if APR_HAS_MMAP
                /* disable mmap handling as this leads to segfaults when
                 * the underlying file is changed while memory pointer has
                 * been handed out. See also PR 59348 */
                apr_bucket_file_enable_mmap(ng, 0);
    #endif
                remain -= bsender->length;
                ++transferred;
            }
            else {
                const char *data;
                apr_size_t dlen;
                /* we did that when the bucket was added, so this should
                 * give us the same data as before without changing the bucket
                 * or anything (pool) connected to it. */
                rv = apr_bucket_read(bsender, &data, &dlen, APR_BLOCK_READ);
                if (rv != APR_SUCCESS) goto leave;
                rv = apr_brigade_write(bb, NULL, NULL, data, dlen);
                if (rv != APR_SUCCESS) goto leave;
    
                remain -= dlen;
                ++transferred;
            }
    
            if (brecv) {
                /* we have a proxy that we can give the receiver */
                APR_BRIGADE_INSERT_TAIL(bb, brecv);
                remain -= brecv->length;
                ++transferred;
            }
            APR_BUCKET_REMOVE(bsender);
            H2_BLIST_INSERT_TAIL(&beam->buckets_consumed, bsender);
            beam->recv_bytes += bsender->length;
            ++consumed_buckets;
        }
    
        if (beam->recv_cb && consumed_buckets > 0) {
            beam->recv_cb(beam->recv_ctx, beam);
        }
    
        if (transferred) {
            apr_thread_cond_broadcast(beam->change);
            rv = APR_SUCCESS;
        }
        else if (beam->aborted) {
            rv = APR_ECONNABORTED;
        }
        else if (beam->closed) {
            rv = APR_EOF;
        }
        else {
            rv = wait_not_empty(beam, to, block);
            if (rv != APR_SUCCESS) {
                goto leave;
            }
            goto transfer;
        }
    
    leave:
        H2_BEAM_LOG(beam, to, APLOG_TRACE2, rv, "end receive", bb);
        if (rv == APR_EAGAIN && beam->eagain_cb) {
            beam->eagain_cb(beam->eagain_ctx, beam);
        }
        apr_thread_mutex_unlock(beam->lock);
        return rv;
    }
    
    void h2_beam_on_consumed(h2_bucket_beam *beam, 
                             h2_beam_io_callback *io_cb, void *ctx)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->cons_io_cb = io_cb;
        beam->cons_ctx = ctx;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    void h2_beam_on_received(h2_bucket_beam *beam,
                             h2_beam_ev_callback *recv_cb, void *ctx)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->recv_cb = recv_cb;
        beam->recv_ctx = ctx;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    void h2_beam_on_eagain(h2_bucket_beam *beam,
                           h2_beam_ev_callback *eagain_cb, void *ctx)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->eagain_cb = eagain_cb;
        beam->eagain_ctx = ctx;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    void h2_beam_on_send(h2_bucket_beam *beam,
                         h2_beam_ev_callback *send_cb, void *ctx)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->send_cb = send_cb;
        beam->send_ctx = ctx;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    void h2_beam_on_was_empty(h2_bucket_beam *beam,
                              h2_beam_ev_callback *was_empty_cb, void *ctx)
    {
        apr_thread_mutex_lock(beam->lock);
        beam->was_empty_cb = was_empty_cb;
        beam->was_empty_ctx = ctx;
        apr_thread_mutex_unlock(beam->lock);
    }
    
    
    static apr_off_t get_buffered_data_len(h2_bucket_beam *beam)
    {
        apr_bucket *b;
        apr_off_t l = 0;
    
        for (b = H2_BLIST_FIRST(&beam->buckets_to_send);
            b != H2_BLIST_SENTINEL(&beam->buckets_to_send);
            b = APR_BUCKET_NEXT(b)) {
            /* should all have determinate length */
            l += b->length;
        }
        return l;
    }
    
    apr_off_t h2_beam_get_buffered(h2_bucket_beam *beam)
    {
        apr_off_t l = 0;
    
        apr_thread_mutex_lock(beam->lock);
        l = get_buffered_data_len(beam);
        apr_thread_mutex_unlock(beam->lock);
        return l;
    }
    
    apr_off_t h2_beam_get_mem_used(h2_bucket_beam *beam)
    {
        apr_bucket *b;
        apr_off_t l = 0;
    
        apr_thread_mutex_lock(beam->lock);
        for (b = H2_BLIST_FIRST(&beam->buckets_to_send);
            b != H2_BLIST_SENTINEL(&beam->buckets_to_send);
            b = APR_BUCKET_NEXT(b)) {
            l += bucket_mem_used(b);
        }
        apr_thread_mutex_unlock(beam->lock);
        return l;
    }
    
    int h2_beam_empty(h2_bucket_beam *beam)
    {
        int empty = 1;
    
        apr_thread_mutex_lock(beam->lock);
        empty = buffer_is_empty(beam);
        apr_thread_mutex_unlock(beam->lock);
        return empty;
    }
    
    int h2_beam_report_consumption(h2_bucket_beam *beam)
    {
        int rv = 0;
    
        apr_thread_mutex_lock(beam->lock);
        rv = report_consumption(beam, 1);
        apr_thread_mutex_unlock(beam->lock);
        return rv;
    }
    
    int h2_beam_is_complete(h2_bucket_beam *beam)
    {
        int rv = 0;
    
        apr_thread_mutex_lock(beam->lock);
        if (beam->closed)
            rv = 1;
        else {
            apr_bucket *b;
            for (b = H2_BLIST_FIRST(&beam->buckets_to_send);
                 b != H2_BLIST_SENTINEL(&beam->buckets_to_send);
                 b = APR_BUCKET_NEXT(b)) {
                if (APR_BUCKET_IS_EOS(b)) {
                    rv = 1;
                    break;
                }
            }
        }
        apr_thread_mutex_unlock(beam->lock);
        return rv;
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_conn_ctx.h������������������������������������������������������������0000664�0001751�0001751�00000010166�14473316336�017726� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_conn_ctx__
    #define __mod_h2__h2_conn_ctx__
    
    #include "h2.h"
    
    struct h2_session;
    struct h2_stream;
    struct h2_mplx;
    struct h2_bucket_beam;
    struct h2_response_parser;
    struct h2_c2_transit;
    
    #define H2_PIPE_OUT     0
    #define H2_PIPE_IN      1
    
    /**
     * The h2 module context associated with a connection.
     *
     * It keeps track of the different types of connections:
     * - those from clients that use HTTP/2 protocol
     * - those from clients that do not use HTTP/2
     * - those created by ourself to perform work on HTTP/2 streams
     */
    struct h2_conn_ctx_t {
        const char *id;                 /* c*: our identifier of this connection */
        server_rec *server;             /* c*: httpd server selected. */
        const char *protocol;           /* c1: the protocol negotiated */
        struct h2_session *session;     /* c1: the h2 session established */
        struct h2_mplx *mplx;           /* c2: the multiplexer */
        struct h2_c2_transit *transit;  /* c2: transit pool and bucket_alloc */
    
    #if !AP_HAS_RESPONSE_BUCKETS
        int pre_conn_done;               /* has pre_connection setup run? */
    #endif
        int stream_id;                  /* c1: 0, c2: stream id processed */
        apr_pool_t *req_pool;            /* c2: a c2 child pool for a request */
        const struct h2_request *request; /* c2: the request to process */
        struct h2_bucket_beam *beam_out; /* c2: data out, created from req_pool */
        struct h2_bucket_beam *beam_in;  /* c2: data in or NULL, borrowed from request stream */
        unsigned input_chunked:1;        /* c2: if input needs HTTP/1.1 chunking applied */
        unsigned is_upgrade:1;           /* c2: if requst is a HTTP Upgrade */
    
        apr_file_t *pipe_in[2];          /* c2: input produced notification pipe */
        apr_pollfd_t pfd;                /* c1: poll socket input, c2: NUL */
    
        int has_final_response;          /* final HTTP response passed on out */
        apr_status_t last_err;           /* APR_SUCCES or last error encountered in filters */
    
        apr_off_t bytes_sent;            /* c2: bytes acutaly sent via c1 */
        /* atomic */ apr_uint32_t started; /* c2: processing was started */
        apr_time_t started_at;           /* c2: when processing started */
        /* atomic */ apr_uint32_t done;  /* c2: processing has finished */
        apr_time_t done_at;              /* c2: when processing was done */
    };
    typedef struct h2_conn_ctx_t h2_conn_ctx_t;
    
    /**
     * Get the h2 connection context.
     * @param c the connection to look at
     * @return h2 context of this connection
     */
    #define h2_conn_ctx_get(c) \
        ((c)? (h2_conn_ctx_t*)ap_get_module_config((c)->conn_config, &http2_module) : NULL)
    
    /**
     * Create the h2 connection context.
     * @param c the connection to create it at
     * @param s the server in use
     * @param protocol the protocol selected
     * @return created h2 context of this connection
     */
    h2_conn_ctx_t *h2_conn_ctx_create_for_c1(conn_rec *c, server_rec *s, const char *protocol);
    
    void h2_conn_ctx_assign_session(h2_conn_ctx_t *ctx, struct h2_session *session);
    
    apr_status_t h2_conn_ctx_init_for_c2(h2_conn_ctx_t **pctx, conn_rec *c,
                                         struct h2_mplx *mplx, struct h2_stream *stream,
                                         struct h2_c2_transit *transit);
    
    void h2_conn_ctx_detach(conn_rec *c);
    
    void h2_conn_ctx_set_timeout(h2_conn_ctx_t *conn_ctx, apr_interval_time_t timeout);
    
    #endif /* defined(__mod_h2__h2_conn_ctx__) */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_http2.dsp������������������������������������������������������������0000664�0001751�0001751�00000013632�14473316336�017762� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_http2" - 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_http2 - 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_http2.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_http2.mak" CFG="mod_http2 - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_http2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_http2 - 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_http2 - 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 "ssize_t=long" /FD /c
    # ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ssize_t=long" /Fd"Release\mod_http2_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 /fo"Release/mod_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_http2.so" /d LONG_NAME="http2_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib nghttp2.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /out:".\Release\mod_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_http2.so
    # ADD LINK32 kernel32.lib nghttp2.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /incremental:no /debug /out:".\Release\mod_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_http2.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_http2 - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "ssize_t=long" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ssize_t=long" /Fd"Debug\mod_http2_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 /fo"Debug/mod_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_http2.so" /d LONG_NAME="http2_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib nghttp2d.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /incremental:no /debug /out:".\Debug\mod_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_http2.so
    # ADD LINK32 kernel32.lib nghttp2d.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /incremental:no /debug /out:".\Debug\mod_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_http2.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_http2 - Win32 Release"
    # Name "mod_http2 - Win32 Debug"
    # Begin Source File
    
    SOURCE=./h2_bucket_beam.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_bucket_eos.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_c1.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_c1_io.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_c2.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_c2_filter.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_config.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_conn_ctx.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_headers.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_mplx.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_protocol.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_push.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_request.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_session.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_stream.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_switch.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_util.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_workers.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_ws.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_http2.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_http2.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_switch.c��������������������������������������������������������������0000664�0001751�0001751�00000016471�14447501300�017400� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include <apr_strings.h>
    #include <apr_optional.h>
    #include <apr_optional_hooks.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_ssl.h>
    #include <http_log.h>
    
    #include "h2_private.h"
    #include "h2.h"
    
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_c1.h"
    #include "h2_c2.h"
    #include "h2_protocol.h"
    #include "h2_switch.h"
    
    /*******************************************************************************
     * Once per lifetime init, retrieve optional functions
     */
    apr_status_t h2_switch_init(apr_pool_t *pool, server_rec *s)
    {
        (void)pool;
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_switch init");
    
        return APR_SUCCESS;
    }
    
    static int h2_protocol_propose(conn_rec *c, request_rec *r,
                                   server_rec *s,
                                   const apr_array_header_t *offers,
                                   apr_array_header_t *proposals)
    {
        int proposed = 0;
        int is_tls = ap_ssl_conn_is_ssl(c);
        const char **protos = is_tls? h2_protocol_ids_tls : h2_protocol_ids_clear;
        
        if (!h2_mpm_supported()) {
            return DECLINED;
        }
        
        if (strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
            /* We do not know how to switch from anything else but http/1.1.
             */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03083)
                          "protocol switch: current proto != http/1.1, declined");
            return DECLINED;
        }
        
        if (!h2_protocol_is_acceptable_c1(c, r, 0)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03084)
                          "protocol propose: connection requirements not met");
            return DECLINED;
        }
        
        if (r) {
            /* So far, this indicates an HTTP/1 Upgrade header initiated
             * protocol switch. For that, the HTTP2-Settings header needs
             * to be present and valid for the connection.
             */
            const char *p;
            
            if (!h2_c1_can_upgrade(r)) {
                return DECLINED;
            }
             
            p = apr_table_get(r->headers_in, "HTTP2-Settings");
            if (!p) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03085)
                              "upgrade without HTTP2-Settings declined");
                return DECLINED;
            }
            
            p = apr_table_get(r->headers_in, "Connection");
            if (!ap_find_token(r->pool, p, "http2-settings")) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03086)
                              "upgrade without HTTP2-Settings declined");
                return DECLINED;
            }
            
            /* We also allow switching only for requests that have no body.
             */
            p = apr_table_get(r->headers_in, "Content-Length");
            if ((p && strcmp(p, "0"))
                || (!p && apr_table_get(r->headers_in, "Transfer-Encoding"))) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03087)
                              "upgrade with body declined");
                return DECLINED;
            }
        }
        
        while (*protos) {
            /* Add all protocols we know (tls or clear) and that
             * are part of the offerings (if there have been any). 
             */
            if (!offers || ap_array_str_contains(offers, *protos)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                              "proposing protocol '%s'", *protos);
                APR_ARRAY_PUSH(proposals, const char*) = *protos;
                proposed = 1;
            }
            ++protos;
        }
        return proposed? DECLINED : OK;
    }
    
    #if AP_HAS_RESPONSE_BUCKETS
    static void remove_output_filters_below(ap_filter_t *f, ap_filter_type ftype)
    {
        ap_filter_t *fnext;
    
        while (f && f->frec->ftype < ftype) {
            fnext = f->next;
            ap_remove_output_filter(f);
            f = fnext;
        }
    }
    
    static void remove_input_filters_below(ap_filter_t *f, ap_filter_type ftype)
    {
        ap_filter_t *fnext;
    
        while (f && f->frec->ftype < ftype) {
            fnext = f->next;
            ap_remove_input_filter(f);
            f = fnext;
        }
    }
    #endif
    
    static int h2_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
                                  const char *protocol)
    {
        int found = 0;
        const char **protos = ap_ssl_conn_is_ssl(c)? h2_protocol_ids_tls : h2_protocol_ids_clear;
        const char **p = protos;
        
        (void)s;
        if (!h2_mpm_supported()) {
            return DECLINED;
        }
    
        while (*p) {
            if (!strcmp(*p, protocol)) {
                found = 1;
                break;
            }
            p++;
        }
        
        if (found) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "switching protocol to '%s'", protocol);
            h2_conn_ctx_create_for_c1(c, s, protocol);
    
            if (r != NULL) {
                apr_status_t status;
    #if AP_HAS_RESPONSE_BUCKETS
                /* Switching in the middle of a request means that
                 * we have to send out the response to this one in h2
                 * format. So we need to take over the connection
                 * and remove all old filters with type up to the
                 * CONNEDCTION/NETWORK ones.
                 */
                remove_input_filters_below(r->input_filters, AP_FTYPE_CONNECTION);
                remove_output_filters_below(r->output_filters, AP_FTYPE_CONNECTION);
    #else
                /* Switching in the middle of a request means that
                 * we have to send out the response to this one in h2
                 * format. So we need to take over the connection
                 * right away.
                 */
                ap_remove_input_filter_byhandle(r->input_filters, "http_in");
                ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
    #endif
                /* Ok, start an h2_conn on this one. */
                status = h2_c1_setup(c, r, s);
                
                if (status != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03088)
                                  "session setup");
                    h2_conn_ctx_detach(c);
                    return !OK;
                }
                
                h2_c1_run(c);
            }
            return OK;
        }
        
        return DECLINED;
    }
    
    static const char *h2_protocol_get(const conn_rec *c)
    {
        h2_conn_ctx_t *ctx;
    
        if (c->master) {
            c = c->master;
        }
        ctx = h2_conn_ctx_get(c);
        return ctx? ctx->protocol : NULL;
    }
    
    void h2_switch_register_hooks(void)
    {
        ap_hook_protocol_propose(h2_protocol_propose, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_protocol_switch(h2_protocol_switch, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_protocol_get(h2_protocol_get, NULL, NULL, APR_HOOK_MIDDLE);
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c2_filter.h�����������������������������������������������������������0000664�0001751�0001751�00000005061�14356741666�017772� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_c2_filter__
    #define __mod_h2__h2_c2_filter__
    
    #include "h2.h"
    
    /**
     * Input filter on secondary connections that insert the REQUEST bucket
     * with the request to perform and then removes itself.
     */
    apr_status_t h2_c2_filter_request_in(ap_filter_t *f,
                                         apr_bucket_brigade *bb,
                                         ap_input_mode_t mode,
                                         apr_read_type_e block,
                                         apr_off_t readbytes);
    
    #if AP_HAS_RESPONSE_BUCKETS
    
    /**
     * Output filter that inspects the request_rec->notes of the request
     * itself and possible internal redirects to detect conditions that
     * merit specific HTTP/2 response codes, such as 421.
     */
    apr_status_t h2_c2_filter_notes_out(ap_filter_t *f, apr_bucket_brigade *bb);
    
    #else /* AP_HAS_RESPONSE_BUCKETS */
    
    /**
     * h2_from_h1 parses a HTTP/1.1 response into
     * - response status
     * - a list of header values
     * - a series of bytes that represent the response body alone, without
     *   any meta data, such as inserted by chunked transfer encoding.
     *
     * All data is allocated from the stream memory pool.
     *
     * Again, see comments in h2_request: ideally we would take the headers
     * and status from the httpd structures instead of parsing them here, but
     * we need to have all handlers and filters involved in request/response
     * processing, so this seems to be the way for now.
     */
    struct h2_headers;
    struct h2_response_parser;
    
    apr_status_t h2_c2_filter_catch_h1_out(ap_filter_t* f, apr_bucket_brigade* bb);
    
    apr_status_t h2_c2_filter_response_out(ap_filter_t *f, apr_bucket_brigade *bb);
    
    apr_status_t h2_c2_filter_trailers_out(ap_filter_t *f, apr_bucket_brigade *bb);
    
    #endif /* else AP_HAS_RESPONSE_BUCKETS */
    
    #endif /* defined(__mod_h2__h2_c2_filter__) */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_protocol.h������������������������������������������������������������0000664�0001751�0001751�00000003761�14356741666�017767� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_protocol__
    #define __mod_h2__h2_protocol__
    
    /**
     * List of protocol identifiers that we support in cleartext
     * negotiations. NULL terminated.
     */
    extern const char *h2_protocol_ids_clear[];
    
    /**
     * List of protocol identifiers that we support in TLS encrypted
     * negotiations (ALPN). NULL terminated.
     */
    extern const char *h2_protocol_ids_tls[];
    
    /**
     * Provide a user readable description of the HTTP/2 error code-
     * @param h2_error http/2 error code, as in rfc 7540, ch. 7
     * @return textual description of code or that it is unknown.
     */
    const char *h2_protocol_err_description(unsigned int h2_error);
    
    /*
     * One time, post config initialization.
     */
    apr_status_t h2_protocol_init(apr_pool_t *pool, server_rec *s);
    
    /**
     * Check if the given primary connection fulfills the protocol
     * requirements for HTTP/2.
     * @param c the connection
     * @param require_all != 0 iff any missing connection properties make
     *    the test fail. For example, a cipher might not have been selected while
     *    the handshake is still ongoing.
     * @return != 0 iff protocol requirements are met
     */
    int h2_protocol_is_acceptable_c1(conn_rec *c, request_rec *r, int require_all);
    
    
    #endif /* defined(__mod_h2__h2_protocol__) */
    ���������������httpd-2.4.64/modules/http2/h2_stream.c��������������������������������������������������������������0000664�0001751�0001751�00000203073�15032734701�017372� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_lib.h"
    #include "apr_strmatch.h"
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_connection.h>
    #include <http_log.h>
    #include <http_protocol.h>
    #include <http_ssl.h>
    
    #include <nghttp2/nghttp2.h>
    
    #include "h2_private.h"
    #include "h2.h"
    #include "h2_bucket_beam.h"
    #include "h2_c1.h"
    #include "h2_config.h"
    #include "h2_protocol.h"
    #include "h2_mplx.h"
    #include "h2_push.h"
    #include "h2_request.h"
    #include "h2_headers.h"
    #include "h2_session.h"
    #include "h2_stream.h"
    #include "h2_c2.h"
    #include "h2_conn_ctx.h"
    #include "h2_c2.h"
    #include "h2_util.h"
    
    
    static const char *h2_ss_str(const h2_stream_state_t state)
    {
        switch (state) {
            case H2_SS_IDLE:
                return "IDLE";
            case H2_SS_RSVD_L:
                return "RESERVED_LOCAL";
            case H2_SS_RSVD_R:
                return "RESERVED_REMOTE";
            case H2_SS_OPEN:
                return "OPEN";
            case H2_SS_CLOSED_L:
                return "HALF_CLOSED_LOCAL";
            case H2_SS_CLOSED_R:
                return "HALF_CLOSED_REMOTE";
            case H2_SS_CLOSED:
                return "CLOSED";
            case H2_SS_CLEANUP:
                return "CLEANUP";
            default:
                return "UNKNOWN";
        }
    }
    
    const char *h2_stream_state_str(const h2_stream *stream)
    {
        return h2_ss_str(stream->state);
    }
    
    /* Abbreviations for stream transit tables */
    #define S_XXX     (-2)                      /* Programming Error */
    #define S_ERR     (-1)                      /* Protocol Error */
    #define S_NOP     (0)                       /* No Change */
    #define S_IDL     (H2_SS_IDL + 1)
    #define S_RS_L    (H2_SS_RSVD_L + 1)
    #define S_RS_R    (H2_SS_RSVD_R + 1)
    #define S_OPEN    (H2_SS_OPEN + 1)
    #define S_CL_L    (H2_SS_CLOSED_L + 1)
    #define S_CL_R    (H2_SS_CLOSED_R + 1)
    #define S_CLS     (H2_SS_CLOSED + 1)
    #define S_CLN     (H2_SS_CLEANUP + 1)
    
    /* state transisitions when certain frame types are sent */
    static int trans_on_send[][H2_SS_MAX] = {
    /*S_IDLE,S_RS_R, S_RS_L, S_OPEN, S_CL_R, S_CL_L, S_CLS,  S_CLN, */        
    { S_ERR, S_ERR,  S_ERR,  S_NOP,  S_NOP,  S_ERR,  S_NOP,  S_NOP, },/* DATA */ 
    { S_ERR, S_ERR,  S_CL_R, S_NOP,  S_NOP,  S_ERR,  S_NOP,  S_NOP, },/* HEADERS */ 
    { S_NOP, S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP, },/* PRIORITY */    
    { S_CLS, S_CLS,  S_CLS,  S_CLS,  S_CLS,  S_CLS,  S_NOP,  S_NOP, },/* RST_STREAM */ 
    { S_ERR, S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* SETTINGS */ 
    { S_RS_L,S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* PUSH_PROMISE */  
    { S_ERR, S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* PING */ 
    { S_ERR, S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* GOAWAY */ 
    { S_NOP, S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP, },/* WINDOW_UPDATE */ 
    { S_NOP, S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP, },/* CONT */ 
    };
    /* state transisitions when certain frame types are received */
    static int trans_on_recv[][H2_SS_MAX] = {
    /*S_IDLE,S_RS_R, S_RS_L, S_OPEN, S_CL_R, S_CL_L, S_CLS,  S_CLN, */        
    { S_ERR, S_ERR,  S_ERR,  S_NOP,  S_ERR,  S_NOP,  S_NOP,  S_NOP, },/* DATA */ 
    { S_OPEN,S_CL_L, S_ERR,  S_NOP,  S_ERR,  S_NOP,  S_NOP,  S_NOP, },/* HEADERS */ 
    { S_NOP, S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP, },/* PRIORITY */    
    { S_ERR, S_CLS,  S_CLS,  S_CLS,  S_CLS,  S_CLS,  S_NOP,  S_NOP, },/* RST_STREAM */ 
    { S_ERR, S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* SETTINGS */ 
    { S_RS_R,S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* PUSH_PROMISE */  
    { S_ERR, S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* PING */ 
    { S_ERR, S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR,  S_ERR, },/* GOAWAY */ 
    { S_NOP, S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP, },/* WINDOW_UPDATE */ 
    { S_NOP, S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP,  S_NOP, },/* CONT */ 
    };
    /* state transisitions when certain events happen */
    static int trans_on_event[][H2_SS_MAX] = {
    /*S_IDLE,S_RS_R, S_RS_L, S_OPEN, S_CL_R, S_CL_L, S_CLS,  S_CLN, */        
    { S_XXX, S_ERR,  S_ERR,  S_CL_L, S_CLS,  S_XXX,  S_XXX,  S_XXX, },/* EV_CLOSED_L*/
    { S_ERR, S_ERR,  S_ERR,  S_CL_R, S_ERR,  S_CLS,  S_NOP,  S_NOP, },/* EV_CLOSED_R*/
    { S_CLS, S_CLS,  S_CLS,  S_CLS,  S_CLS,  S_CLS,  S_NOP,  S_NOP, },/* EV_CANCELLED*/
    { S_NOP, S_XXX,  S_XXX,  S_XXX,  S_XXX,  S_CLS,  S_CLN,  S_NOP, },/* EV_EOS_SENT*/
    { S_NOP, S_XXX,  S_CLS,  S_XXX,  S_XXX,  S_CLS,  S_XXX,  S_XXX, },/* EV_IN_ERROR*/
    };
    
    static int on_map(h2_stream_state_t state, int map[H2_SS_MAX])
    {
        int op = map[state];
        switch (op) {
            case S_XXX:
            case S_ERR:
                return op;
            case S_NOP:
                return state;
            default:
                return op-1;
        }
    }
    
    static int on_frame(h2_stream_state_t state, int frame_type, 
                        int frame_map[][H2_SS_MAX], apr_size_t maxlen)
    {
        ap_assert(frame_type >= 0);
        ap_assert(state >= 0);
        if ((apr_size_t)frame_type >= maxlen) {
            return state; /* NOP, ignore unknown frame types */
        }
        return on_map(state, frame_map[frame_type]);
    }
    
    static int on_frame_send(h2_stream_state_t state, int frame_type)
    {
        return on_frame(state, frame_type, trans_on_send, H2_ALEN(trans_on_send));
    }
    
    static int on_frame_recv(h2_stream_state_t state, int frame_type)
    {
        return on_frame(state, frame_type, trans_on_recv, H2_ALEN(trans_on_recv));
    }
    
    static int on_event(h2_stream* stream, h2_stream_event_t ev)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (stream->monitor && stream->monitor->on_event) {
            stream->monitor->on_event(stream->monitor->ctx, stream, ev);
        }
        if (ev < H2_ALEN(trans_on_event)) {
            return on_map(stream->state, trans_on_event[ev]);
        }
        return stream->state;
    }
    
    static ssize_t stream_data_cb(nghttp2_session *ng2s,
                                  int32_t stream_id,
                                  uint8_t *buf,
                                  size_t length,
                                  uint32_t *data_flags,
                                  nghttp2_data_source *source,
                                  void *puser);
    
    static void H2_STREAM_OUT_LOG(int lvl, h2_stream *s, const char *tag)
    {
        if (APLOG_C_IS_LEVEL(s->session->c1, lvl)) {
            conn_rec *c = s->session->c1;
            char buffer[4 * 1024];
            apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]);
            
            len = h2_util_bb_print(buffer, bmax, tag, "", s->out_buffer);
            ap_log_cerror(APLOG_MARK, lvl, 0, c, 
                          H2_STRM_MSG(s, "out-buffer(%s)"), len? buffer : "empty");
        }
    }
    
    static void stream_setup_input(h2_stream *stream)
    {
        if (stream->input != NULL) return;
        ap_assert(!stream->input_closed);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "setup input beam"));
        h2_beam_create(&stream->input, stream->session->c1,
                       stream->pool, stream->id,
                       "input", 0, stream->session->s->timeout);
    }
    
    apr_status_t h2_stream_prepare_processing(h2_stream *stream)
    {
        /* Right before processing starts, last chance to decide if
         * there is need to an input beam. */
        if (!stream->input_closed) {
            stream_setup_input(stream);
        }
        return APR_SUCCESS;
    }
    
    static int input_buffer_is_empty(h2_stream *stream)
    {
        return !stream->in_buffer || APR_BRIGADE_EMPTY(stream->in_buffer);
    }
    
    static apr_status_t input_flush(h2_stream *stream)
    {
        apr_status_t status = APR_SUCCESS;
        apr_off_t written;
    
        if (input_buffer_is_empty(stream)) goto cleanup;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "flush input"));
        status = h2_beam_send(stream->input, stream->session->c1,
                              stream->in_buffer, APR_BLOCK_READ, &written);
        stream->in_last_write = apr_time_now();
        if (APR_SUCCESS != status && h2_stream_is_at(stream, H2_SS_CLOSED_L)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, stream->session->c1,
                          H2_STRM_MSG(stream, "send input error"));
            h2_stream_dispatch(stream, H2_SEV_IN_ERROR);
        }
    cleanup:
        return status;
    }
    
    static void input_append_bucket(h2_stream *stream, apr_bucket *b)
    {
        if (!stream->in_buffer) {
            stream_setup_input(stream);
            stream->in_buffer = apr_brigade_create(
                stream->pool, stream->session->c1->bucket_alloc);
        }
        APR_BRIGADE_INSERT_TAIL(stream->in_buffer, b);
    }
    
    static void input_append_data(h2_stream *stream, const char *data, apr_size_t len)
    {
        if (!stream->in_buffer) {
            stream_setup_input(stream);
            stream->in_buffer = apr_brigade_create(
                stream->pool, stream->session->c1->bucket_alloc);
        }
        apr_brigade_write(stream->in_buffer, NULL, NULL, data, len);
    }
    
    
    static apr_status_t close_input(h2_stream *stream)
    {
        conn_rec *c = stream->session->c1;
        apr_status_t rv = APR_SUCCESS;
        apr_bucket *b;
    
        if (stream->input_closed) goto cleanup;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "closing input"));
        if (!stream->rst_error
            && stream->trailers_in
            && !apr_is_empty_table(stream->trailers_in)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "adding trailers"));
    #if AP_HAS_RESPONSE_BUCKETS
            b = ap_bucket_headers_create(stream->trailers_in,
                                         stream->pool, c->bucket_alloc);
    #else
            b = h2_bucket_headers_create(c->bucket_alloc,
                h2_headers_create(HTTP_OK, stream->trailers_in, NULL,
                                  stream->in_trailer_octets, stream->pool));
    #endif
            input_append_bucket(stream, b);
            stream->trailers_in = NULL;
        }
    
        stream->input_closed = 1;
        if (stream->input) {
            b = apr_bucket_eos_create(c->bucket_alloc);
            input_append_bucket(stream, b);
            input_flush(stream);
            h2_stream_dispatch(stream, H2_SEV_IN_DATA_PENDING);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "input flush + EOS"));
        }
    
    cleanup:
        return rv;
    }
    
    static void on_state_enter(h2_stream *stream)
    {
        if (stream->monitor && stream->monitor->on_state_enter) {
            stream->monitor->on_state_enter(stream->monitor->ctx, stream);
        }
    }
    
    static void on_state_event(h2_stream *stream, h2_stream_event_t ev) 
    {
        if (stream->monitor && stream->monitor->on_state_event) {
            stream->monitor->on_state_event(stream->monitor->ctx, stream, ev);
        }
    }
    
    static void on_state_invalid(h2_stream *stream) 
    {
        if (stream->monitor && stream->monitor->on_state_invalid) {
            stream->monitor->on_state_invalid(stream->monitor->ctx, stream);
        }
        /* stream got an event/frame invalid in its state */
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "invalid state event")); 
        switch (stream->state) {
            case H2_SS_OPEN:
            case H2_SS_RSVD_L:
            case H2_SS_RSVD_R:
            case H2_SS_CLOSED_L:
            case H2_SS_CLOSED_R:
                h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
                break;
            default:
                break;
        }
    }
    
    static apr_status_t transit(h2_stream *stream, int new_state)
    {
        if ((h2_stream_state_t)new_state == stream->state) {
            return APR_SUCCESS;
        }
        else if (new_state < 0) {
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, stream->session->c1,
                          H2_STRM_LOG(APLOGNO(03081), stream, "invalid transition"));
            on_state_invalid(stream);
            return APR_EINVAL;
        }
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "transit to [%s]"), h2_ss_str(new_state));
        stream->state = new_state;
        switch (new_state) {
            case H2_SS_IDLE:
                break;
            case H2_SS_RSVD_L:
                close_input(stream);
                break;
            case H2_SS_RSVD_R:
                break;
            case H2_SS_OPEN:
                break;
            case H2_SS_CLOSED_L:
                break;
            case H2_SS_CLOSED_R:
                close_input(stream);
                break;
            case H2_SS_CLOSED:
                close_input(stream);
                if (stream->out_buffer) {
                    apr_brigade_cleanup(stream->out_buffer);
                }
                break;
            case H2_SS_CLEANUP:
                break;
        }
        on_state_enter(stream);
        return APR_SUCCESS;
    }
    
    void h2_stream_set_monitor(h2_stream *stream, h2_stream_monitor *monitor)
    {
        stream->monitor = monitor;
    }
    
    void h2_stream_dispatch(h2_stream *stream, h2_stream_event_t ev)
    {
        int new_state;
        
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "dispatch event %d"), ev);
        new_state = on_event(stream, ev);
        if (new_state < 0) {
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, stream->session->c1,
                          H2_STRM_LOG(APLOGNO(10002), stream, "invalid event %d"), ev);
            on_state_invalid(stream);
            AP_DEBUG_ASSERT(new_state > S_XXX);
            return;
        }
        else if ((h2_stream_state_t)new_state == stream->state) {
            /* nop */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "non-state event %d"), ev);
            return;
        }
        else {
            on_state_event(stream, ev);
            transit(stream, new_state);
        }
    }
    
    static void set_policy_for(h2_stream *stream, h2_request *r) 
    {
        int enabled = h2_session_push_enabled(stream->session);
        stream->push_policy = h2_push_policy_determine(r->headers, stream->pool, enabled);
    }
    
    apr_status_t h2_stream_send_frame(h2_stream *stream, int ftype, int flags, size_t frame_len)
    {
        apr_status_t status = APR_SUCCESS;
        int new_state, eos = 0;
    
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        new_state = on_frame_send(stream->state, ftype);
        if (new_state < 0) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "invalid frame %d send"), ftype);
            AP_DEBUG_ASSERT(new_state > S_XXX);
            return transit(stream, new_state);
        }
    
        ++stream->out_frames;
        stream->out_frame_octets += frame_len;
        if(stream->c2) {
          h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(stream->c2);
          if(conn_ctx)
            conn_ctx->bytes_sent = stream->out_frame_octets;
        }
    
        switch (ftype) {
            case NGHTTP2_DATA:
                eos = (flags & NGHTTP2_FLAG_END_STREAM);
                break;
                
            case NGHTTP2_HEADERS:
                eos = (flags & NGHTTP2_FLAG_END_STREAM);
                break;
                
            case NGHTTP2_PUSH_PROMISE:
                    /* start pushed stream */
                    ap_assert(stream->request == NULL);
                    ap_assert(stream->rtmp != NULL);
                    status = h2_stream_end_headers(stream, 1, 0);
                    if (status != APR_SUCCESS) goto leave;
                break;
                
            default:
                break;
        }
        status = transit(stream, new_state);
        if (status == APR_SUCCESS && eos) {
            status = transit(stream, on_event(stream, H2_SEV_CLOSED_L));
        }
    leave:
        return status;
    }
    
    apr_status_t h2_stream_recv_frame(h2_stream *stream, int ftype, int flags, size_t frame_len)
    {
        apr_status_t status = APR_SUCCESS;
        int new_state, eos = 0;
    
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        new_state = on_frame_recv(stream->state, ftype);
        if (new_state < 0) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "invalid frame %d recv"), ftype);
            AP_DEBUG_ASSERT(new_state > S_XXX);
            return transit(stream, new_state);
        }
        
        switch (ftype) {
            case NGHTTP2_DATA:
                eos = (flags & NGHTTP2_FLAG_END_STREAM);
                break;
                
            case NGHTTP2_HEADERS:
                eos = (flags & NGHTTP2_FLAG_END_STREAM);
                if (h2_stream_is_at_or_past(stream, H2_SS_OPEN)) {
                    /* trailer HEADER */
                    if (!eos) {
                        h2_stream_rst(stream, H2_ERR_PROTOCOL_ERROR);
                    }
                    stream->in_trailer_octets += frame_len;
                }
                else {
                    /* request HEADER */
                    ap_assert(stream->request == NULL);
                    if (stream->rtmp == NULL) {
                        /* This can only happen, if the stream has received no header
                         * name/value pairs at all. The latest nghttp2 version have become
                         * pretty good at detecting this early. In any case, we have
                         * to abort the connection here, since this is clearly a protocol error */
                        return APR_EINVAL;
                    }
                    status = h2_stream_end_headers(stream, eos, frame_len);
                    if (status != APR_SUCCESS) goto leave;
                }
                break;
                
            default:
                break;
        }
        status = transit(stream, new_state);
        if (status == APR_SUCCESS && eos) {
            status = transit(stream, on_event(stream, H2_SEV_CLOSED_R));
        }
    leave:
        return status;
    }
    
    apr_status_t h2_stream_recv_DATA(h2_stream *stream, uint8_t flags,
                                        const uint8_t *data, size_t len)
    {
        h2_session *session = stream->session;
        apr_status_t status = APR_SUCCESS;
        
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        stream->in_data_frames++;
        if (len > 0) {
            if (APLOGctrace3(session->c1)) {
                const char *load = apr_pstrndup(stream->pool, (const char *)data, len);
                ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, session->c1,
                              H2_STRM_MSG(stream, "recv DATA, len=%d: -->%s<--"), 
                              (int)len, load);
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, session->c1,
                              H2_STRM_MSG(stream, "recv DATA, len=%d"), (int)len);
            }
            stream->in_data_octets += len;
            input_append_data(stream, (const char*)data, len);
            input_flush(stream);
            h2_stream_dispatch(stream, H2_SEV_IN_DATA_PENDING);
        }
        return status;
    }
    
    #ifdef AP_DEBUG
    static apr_status_t stream_pool_destroy(void *data)
    {
        h2_stream *stream = data;
        switch (stream->magic) {
        case H2_STRM_MAGIC_OK:
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "was not destroyed explicitly"));
            AP_DEBUG_ASSERT(0);
            break;
        case H2_STRM_MAGIC_SDEL:
            /* stream has been explicitly destroyed, as it should */
            H2_STRM_ASSIGN_MAGIC(stream, H2_STRM_MAGIC_PDEL);
            break;
        case H2_STRM_MAGIC_PDEL:
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "already pool destroyed"));
            AP_DEBUG_ASSERT(0);
            break;
        default:
            AP_DEBUG_ASSERT(0);
        }
        return APR_SUCCESS;
    }
    #endif
    
    h2_stream *h2_stream_create(int id, apr_pool_t *pool, h2_session *session,
                                h2_stream_monitor *monitor, int initiated_on)
    {
        h2_stream *stream = apr_pcalloc(pool, sizeof(h2_stream));
    
        H2_STRM_ASSIGN_MAGIC(stream, H2_STRM_MAGIC_OK);
        stream->id           = id;
        stream->initiated_on = initiated_on;
        stream->created      = apr_time_now();
        stream->state        = H2_SS_IDLE;
        stream->pool         = pool;
        stream->session      = session;
        stream->monitor      = monitor;
    #ifdef AP_DEBUG
        if (id) { /* stream 0 has special lifetime */
            apr_pool_cleanup_register(pool, stream, stream_pool_destroy,
                                      apr_pool_cleanup_null);
        }
    #endif
    
    #ifdef H2_NG2_LOCAL_WIN_SIZE
        if (id) {
            stream->in_window_size =
                nghttp2_session_get_stream_local_window_size(
                    stream->session->ngh2, stream->id);
        }
    #endif
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1,
                      H2_STRM_LOG(APLOGNO(03082), stream, "created"));
        on_state_enter(stream);
        return stream;
    }
    
    void h2_stream_cleanup(h2_stream *stream)
    {
        /* Stream is done on c1. There might still be processing on a c2
         * going on. The input/output beams get aborted and the stream's
         * end of the in/out notifications get closed.
         */
        ap_assert(stream);
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (stream->out_buffer) {
            apr_brigade_cleanup(stream->out_buffer);
        }
    }
    
    void h2_stream_destroy(h2_stream *stream)
    {
        ap_assert(stream);
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "destroy"));
        H2_STRM_ASSIGN_MAGIC(stream, H2_STRM_MAGIC_SDEL);
        apr_pool_destroy(stream->pool);
    }
    
    void h2_stream_rst(h2_stream *stream, int error_code)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        stream->rst_error = error_code;
        if (stream->c2) {
            h2_c2_abort(stream->c2, stream->session->c1);
        }
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "reset, error=%d"), error_code);
        h2_stream_dispatch(stream, H2_SEV_CANCELLED);
    }
    
    apr_status_t h2_stream_set_request_rec(h2_stream *stream, 
                                           request_rec *r, int eos)
    {
        h2_request *req;
        apr_status_t status;
    
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        ap_assert(stream->request == NULL);
        ap_assert(stream->rtmp == NULL);
        if (stream->rst_error) {
            return APR_ECONNRESET;
        }
        status = h2_request_rcreate(&req, stream->pool, r,
                                    &stream->session->hd_scratch);
        if (status == APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, 
                          H2_STRM_LOG(APLOGNO(03058), stream, 
                          "set_request_rec %s host=%s://%s%s"),
                          req->method, req->scheme, req->authority, req->path);
            stream->rtmp = req;
            /* simulate the frames that led to this */
            return h2_stream_recv_frame(stream, NGHTTP2_HEADERS, 
                                        NGHTTP2_FLAG_END_STREAM, 0);
        }
        return status;
    }
    
    void h2_stream_set_request(h2_stream *stream, const h2_request *r)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        ap_assert(stream->request == NULL);
        ap_assert(stream->rtmp == NULL);
        stream->rtmp = h2_request_clone(stream->pool, r);
    }
    
    static void set_error_response(h2_stream *stream, int http_status)
    {
        if (!h2_stream_is_ready(stream) && stream->rtmp) {
            stream->rtmp->http_status = http_status;
        }
    }
    
    static apr_status_t add_trailer(h2_stream *stream,
                                    const char *name, size_t nlen,
                                    const char *value, size_t vlen,
                                    h2_hd_scratch *scratch)
    {
        conn_rec *c = stream->session->c1;
        const char *existing;
    
        if (nlen == 0 || name[0] == ':') {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EINVAL, c, 
                          H2_STRM_LOG(APLOGNO(03060), stream, 
                          "pseudo header in trailer"));
            return APR_EINVAL;
        }
        if (h2_ignore_req_trailer(name, nlen)) {
            return APR_SUCCESS;
        }
        if (!stream->trailers_in) {
            stream->trailers_in = apr_table_make(stream->pool, 5);
        }
    
        if (((nlen + vlen + 2) > scratch->max_len))
            return APR_EINVAL;
    
        /* We need 0-terminated strings to operate on apr_table */
        AP_DEBUG_ASSERT(nlen < scratch->max_len);
        memcpy(scratch->name, name, nlen);
        scratch->name[nlen] = 0;
        AP_DEBUG_ASSERT(vlen < scratch->max_len);
        memcpy(scratch->value, value, vlen);
        scratch->value[vlen] = 0;
    
        existing = apr_table_get(stream->trailers_in, scratch->name);
        if(existing) {
          if (!vlen) /* not adding a 0-length value to existing */
              return APR_SUCCESS;
          if ((strlen(existing) + 2 + vlen + nlen + 2 > scratch->max_len)) {
              /* "name: existing, value" is too long */
              return APR_EINVAL;
          }
          apr_table_merge(stream->trailers_in, scratch->name, scratch->value);
        }
        else {
            h2_util_camel_case_header(scratch->name, nlen);
            apr_table_set(stream->trailers_in, scratch->name, scratch->value);
        }
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      H2_STRM_MSG(stream, "added trailer '%s: %s'"),
                      scratch->name, scratch->value);
        return APR_SUCCESS;
    }
    
    apr_status_t h2_stream_add_header(h2_stream *stream,
                                      const char *name, size_t nlen,
                                      const char *value, size_t vlen)
    {
        h2_session *session = stream->session;
        int error = 0;
        apr_status_t status = APR_SUCCESS;
        
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (stream->response) {
            return APR_EINVAL;    
        }
    
        if (name[0] == ':') {
            if (vlen > APR_INT32_MAX || (int)vlen > session->s->limit_req_line) {
                /* pseudo header: approximation of request line size check */
                if (!h2_stream_is_ready(stream)) {
                    ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c1,
                                  H2_STRM_LOG(APLOGNO(10178), stream,
                                              "Request pseudo header exceeds "
                                              "LimitRequestFieldSize: %s"), name);
                }
                error = HTTP_REQUEST_URI_TOO_LARGE;
                goto cleanup;
            }
        }
        
        if (session->s->limit_req_fields > 0 
            && stream->request_headers_added > session->s->limit_req_fields) {
            /* already over limit, count this attempt, but do not take it in */
            ++stream->request_headers_added;
        }
        else if (H2_SS_IDLE == stream->state) {
            int was_added;
            if (!stream->rtmp) {
                if (H2_STREAM_CLIENT_INITIATED(stream->id)) {
                    ++stream->session->remote.emitted_count;
                  if (stream->id > stream->session->remote.emitted_max)
                      session->remote.emitted_max = stream->id;
                }
                stream->rtmp = h2_request_create(stream->id, stream->pool,
                                                 NULL, NULL, NULL, NULL, NULL);
            }
            status = h2_request_add_header(stream->rtmp, stream->pool,
                                           name, nlen, value, vlen,
                                           &session->hd_scratch, &was_added);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, session->c1,
                          H2_STRM_MSG(stream, "add_header: '%.*s: %.*s"),
                          (int)nlen, name, (int)vlen, value);
            if (was_added) ++stream->request_headers_added;
        }
        else if (H2_SS_OPEN == stream->state) {
            status = add_trailer(stream, name, nlen, value, vlen,
                                 &session->hd_scratch);
            if (!status) ++stream->request_headers_added;
        }
        else {
            status = APR_EINVAL;
            goto cleanup;
        }
        
        if (APR_EINVAL == status) {
            /* header too long */
            if (!h2_stream_is_ready(stream) && !stream->request_headers_failed) {
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c1,
                              H2_STRM_LOG(APLOGNO(10180), stream,
                              "Request header exceeds LimitRequestFieldSize(%d): %.*s"),
                              (int)session->hd_scratch.max_len,
                              (int)H2MIN(nlen, 80), name);
            }
            error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE;
            goto cleanup;
        }
    
        if (session->s->limit_req_fields > 0 
            && stream->request_headers_added > session->s->limit_req_fields) {
            /* too many header lines */
            if (stream->request_headers_added > session->s->limit_req_fields + 100) {
                /* yeah, right, this request is way over the limit, say goodbye */
                h2_stream_rst(stream, H2_ERR_ENHANCE_YOUR_CALM);
                return APR_ECONNRESET;
            }
            if (!h2_stream_is_ready(stream)) {
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c1,
                              H2_STRM_LOG(APLOGNO(10181), stream, "Number of request headers "
                                          "exceeds LimitRequestFields(%d)"),
                                          (int)session->s->limit_req_fields);
            }
            error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE;
            goto cleanup;
        }
    
    cleanup:
        if (error) {
            ++stream->request_headers_failed;
            set_error_response(stream, error);
            return APR_EINVAL; 
        }
        else if (status != APR_SUCCESS) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c1,
                          H2_STRM_MSG(stream, "header %s not accepted"), name);
            h2_stream_dispatch(stream, H2_SEV_CANCELLED);
        }
        return status;
    }
    
    typedef struct {
        apr_size_t maxlen;
        const char *failed_key;
    } val_len_check_ctx;
    
    static int table_check_val_len(void *baton, const char *key, const char *value)
    {
        val_len_check_ctx *ctx = baton;
    
        if (strlen(value) <= ctx->maxlen) return 1;
        ctx->failed_key = key;
        return 0;
    }
    
    apr_status_t h2_stream_end_headers(h2_stream *stream, int eos, size_t raw_bytes)
    {
        apr_status_t status;
        val_len_check_ctx ctx;
        int is_http_or_https;
        h2_request *req = stream->rtmp;
    
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        status = h2_request_end_headers(req, stream->pool, raw_bytes);
        if (APR_SUCCESS != status || req->http_status != H2_HTTP_STATUS_UNSET) {
            goto cleanup;
        }
    
        /* keep on returning APR_SUCCESS for error responses, so that we
         * send it and do not RST the stream.
         */
        set_policy_for(stream, req);
    
        ctx.maxlen = stream->session->s->limit_req_fieldsize;
        ctx.failed_key = NULL;
        apr_table_do(table_check_val_len, &ctx, req->headers, NULL);
        if (ctx.failed_key) {
            if (!h2_stream_is_ready(stream)) {
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c1,
                              H2_STRM_LOG(APLOGNO(10230), stream,"Request header exceeds "
                                          "LimitRequestFieldSize: %.*s"),
                              (int)H2MIN(strlen(ctx.failed_key), 80), ctx.failed_key);
            }
            set_error_response(stream, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
            goto cleanup;
        }
    
        /* http(s) scheme. rfc7540, ch. 8.1.2.3:
         * This [:path] pseudo-header field MUST NOT be empty for "http" or "https"
         * URIs; "http" or "https" URIs that do not contain a path component
         * MUST include a value of '/'.  The exception to this rule is an
         * OPTIONS request for an "http" or "https" URI that does not include
         * a path component; these MUST include a ":path" pseudo-header field
         * with a value of '*'
         *
         * All HTTP/2 requests MUST include exactly one valid value for the
         * ":method", ":scheme", and ":path" pseudo-header fields, unless it is
         * a CONNECT request.
         */
        is_http_or_https = (!req->scheme
                || !(ap_cstr_casecmpn(req->scheme, "http", 4) != 0
                     || (req->scheme[4] != '\0'
                         && (apr_tolower(req->scheme[4]) != 's'
                             || req->scheme[5] != '\0'))));
    
        /* CONNECT. rfc7540, ch. 8.3:
         * In HTTP/2, the CONNECT method is used to establish a tunnel over a
         * single HTTP/2 stream to a remote host for similar purposes.  The HTTP
         * header field mapping works as defined in Section 8.1.2.3 ("Request
         * Pseudo-Header Fields"), with a few differences.  Specifically:
         *   o  The ":method" pseudo-header field is set to "CONNECT".
         *   o  The ":scheme" and ":path" pseudo-header fields MUST be omitted.
         *   o  The ":authority" pseudo-header field contains the host and port to
         *      connect to (equivalent to the authority-form of the request-target
         *      of CONNECT requests (see [RFC7230], Section 5.3)).
         */
        if (!ap_cstr_casecmp(req->method, "CONNECT")) {
            if (req->protocol) {
                if (!strcmp("websocket", req->protocol)) {
                    if (!req->scheme || !req->path) {
                        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c1,
                                      H2_STRM_LOG(APLOGNO(10457), stream, "Request to websocket CONNECT "
                                      "without :scheme or :path, sending 400 answer"));
                        set_error_response(stream, HTTP_BAD_REQUEST);
                        goto cleanup;
                    }
                }
                else {
                    /* do not know that protocol */
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, stream->session->c1, APLOGNO(10460)
                                  "':protocol: %s' header present in %s request",
                                  req->protocol, req->method);
                    set_error_response(stream, HTTP_NOT_IMPLEMENTED);
                    goto cleanup;
                }
            }
            else if (req->scheme || req->path) {
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c1,
                              H2_STRM_LOG(APLOGNO(10384), stream, "Request to CONNECT "
                              "with :scheme or :path specified, sending 400 answer"));
                set_error_response(stream, HTTP_BAD_REQUEST);
                goto cleanup;
            }
        }
        else if (is_http_or_https) {
            if (!req->path) {
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c1,
                              H2_STRM_LOG(APLOGNO(10385), stream, "Request for http(s) "
                              "resource without :path, sending 400 answer"));
                set_error_response(stream, HTTP_BAD_REQUEST);
                goto cleanup;
            }
            if (!req->scheme) {
                req->scheme = ap_ssl_conn_is_ssl(stream->session->c1)? "https" : "http";
            }
        }
    
        if (req->scheme && (req->path && req->path[0] != '/')) {
            /* We still have a scheme, which means we need to pass an absolute URI into
             * our HTTP protocol handling and the missing '/' at the start will prevent
             * us from doing so (as it then confuses path and authority). */
            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c1,
                          H2_STRM_LOG(APLOGNO(10379), stream, "Request :scheme '%s' and "
                          "path '%s' do not allow creating an absolute URL. Failing "
                          "request with 400."), req->scheme, req->path);
            set_error_response(stream, HTTP_BAD_REQUEST);
            goto cleanup;
        }
    
    cleanup:
        if (APR_SUCCESS == status) {
            stream->request = req;
            stream->rtmp = NULL;
    
            if (APLOGctrace4(stream->session->c1)) {
                int i;
                const apr_array_header_t *t_h = apr_table_elts(req->headers);
                const apr_table_entry_t *t_elt = (apr_table_entry_t *)t_h->elts;
                ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, stream->session->c1,
                              H2_STRM_MSG(stream,"headers received from client:"));
                for (i = 0; i < t_h->nelts; i++, t_elt++) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, stream->session->c1,
                                  H2_STRM_MSG(stream, "  %s: %s"),
                                  ap_escape_logitem(stream->pool, t_elt->key),
                                  ap_escape_logitem(stream->pool, t_elt->val));
                }
            }
        }
        return status;
    }
    
    static apr_bucket *get_first_response_bucket(apr_bucket_brigade *bb)
    {
        if (bb) {
            apr_bucket *b = APR_BRIGADE_FIRST(bb);
            while (b != APR_BRIGADE_SENTINEL(bb)) {
    #if AP_HAS_RESPONSE_BUCKETS
                if (AP_BUCKET_IS_RESPONSE(b)) {
                    return b;
                }
    #else
                if (H2_BUCKET_IS_HEADERS(b)) {
                    return b;
                }
    #endif
                b = APR_BUCKET_NEXT(b);
            }
        }
        return NULL;
    }
    
    static void stream_do_error_bucket(h2_stream *stream, apr_bucket *b)
    {
        int err = ((ap_bucket_error *)(b->data))->status;
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                      H2_STRM_MSG(stream, "error bucket received, err=%d"), err);
        if (err >= 500) {
            err = NGHTTP2_INTERNAL_ERROR;
        }
        else if (err >= 400) {
            err = NGHTTP2_STREAM_CLOSED;
        }
        else {
            err = NGHTTP2_PROTOCOL_ERROR;
        }
        h2_stream_rst(stream, err);
    }
    
    static apr_status_t buffer_output_receive(h2_stream *stream)
    {
        apr_status_t rv = APR_EAGAIN;
        apr_off_t buf_len;
        conn_rec *c1 = stream->session->c1;
        apr_bucket *b, *e;
    
        if (!stream->output) {
            goto cleanup;
        }
        if (stream->rst_error) {
            rv = APR_ECONNRESET;
            goto cleanup;
        }
    
        if (!stream->out_buffer) {
            stream->out_buffer = apr_brigade_create(stream->pool, c1->bucket_alloc);
            buf_len = 0;
        }
        else {
            /* if the brigade contains a file bucket, its normal report length
             * might be megabytes, but the memory used is tiny. For buffering,
             * we are only interested in the memory footprint. */
            buf_len = h2_brigade_mem_size(stream->out_buffer);
        }
    
        if (buf_len > APR_INT32_MAX
            || (apr_size_t)buf_len >= stream->session->max_stream_mem) {
            /* we have buffered enough. No need to read more.
             * However, we have now output pending for which we may not
             * receive another poll event. We need to make sure that this
             * stream is not suspended so we keep on processing output.
             */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c1,
                          H2_STRM_MSG(stream, "out_buffer, already has %ld length"),
                          (long)buf_len);
            rv = APR_SUCCESS;
            goto cleanup;
        }
    
        if (stream->output_eos) {
            rv = APR_BRIGADE_EMPTY(stream->out_buffer)? APR_EOF : APR_SUCCESS;
        }
        else {
            H2_STREAM_OUT_LOG(APLOG_TRACE2, stream, "pre");
            rv = h2_beam_receive(stream->output, stream->session->c1, stream->out_buffer,
                                 APR_NONBLOCK_READ, stream->session->max_stream_mem - buf_len);
            if (APR_SUCCESS != rv) {
                if (APR_EAGAIN != rv) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c1,
                                  H2_STRM_MSG(stream, "out_buffer, receive unsuccessful"));
                }
            }
        }
    
        /* get rid of buckets we have no need for */
        if (!APR_BRIGADE_EMPTY(stream->out_buffer)) {
            b = APR_BRIGADE_FIRST(stream->out_buffer);
            while (b != APR_BRIGADE_SENTINEL(stream->out_buffer)) {
                e = APR_BUCKET_NEXT(b);
                if (APR_BUCKET_IS_METADATA(b)) {
                    if (APR_BUCKET_IS_FLUSH(b)) {  /* we flush any c1 data already */
                        APR_BUCKET_REMOVE(b);
                        apr_bucket_destroy(b);
                    }
                    else if (APR_BUCKET_IS_EOS(b)) {
                        stream->output_eos = 1;
                    }
                    else if (AP_BUCKET_IS_ERROR(b)) {
                        stream_do_error_bucket(stream, b);
                        break;
                    }
                }
                else if (b->length == 0) {  /* zero length data */
                    APR_BUCKET_REMOVE(b);
                    apr_bucket_destroy(b);
                }
                b = e;
            }
        }
        H2_STREAM_OUT_LOG(APLOG_TRACE2, stream, "out_buffer, after receive");
    
    cleanup:
        return rv;
    }
    
    static int bucket_pass_to_c1(apr_bucket *b)
    {
    #if AP_HAS_RESPONSE_BUCKETS
        return !AP_BUCKET_IS_RESPONSE(b)
               && !AP_BUCKET_IS_HEADERS(b)
               && !APR_BUCKET_IS_EOS(b);
    #else
        return !H2_BUCKET_IS_HEADERS(b) && !APR_BUCKET_IS_EOS(b);
    #endif
    }
    
    apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb, 
                                   apr_off_t *plen, int *peos)
    {
        apr_status_t rv = APR_SUCCESS;
    
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (stream->rst_error) {
            return APR_ECONNRESET;
        }
        rv = h2_append_brigade(bb, stream->out_buffer, plen, peos, bucket_pass_to_c1);
        if (APR_SUCCESS  == rv && !*peos && !*plen) {
            rv = APR_EAGAIN;
        }
        return rv;
    }
    
    static apr_status_t stream_do_trailers(h2_stream *stream)
    {
        conn_rec *c1 = stream->session->c1;
        int ngrv;
        h2_ngheader *nh = NULL;
        apr_bucket *b, *e;
    #if AP_HAS_RESPONSE_BUCKETS
        ap_bucket_headers *headers = NULL;
    #else
        h2_headers *headers = NULL;
    #endif
        apr_status_t rv;
    
        ap_assert(stream->response);
        ap_assert(stream->out_buffer);
    
        b = APR_BRIGADE_FIRST(stream->out_buffer);
        while (b != APR_BRIGADE_SENTINEL(stream->out_buffer)) {
            e = APR_BUCKET_NEXT(b);
            if (APR_BUCKET_IS_METADATA(b)) {
    #if AP_HAS_RESPONSE_BUCKETS
                if (AP_BUCKET_IS_HEADERS(b)) {
                    headers = b->data;
    #else /* AP_HAS_RESPONSE_BUCKETS */
                if (H2_BUCKET_IS_HEADERS(b)) {
                    headers = h2_bucket_headers_get(b);
    #endif /* else AP_HAS_RESPONSE_BUCKETS */
                    APR_BUCKET_REMOVE(b);
                    apr_bucket_destroy(b);
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c1,
                                  H2_STRM_MSG(stream, "process trailers"));
                    break;
                }
                else if (APR_BUCKET_IS_EOS(b)) {
                    break;
                }
            }
            else {
                break;
            }
            b = e;
        }
    
        if (!headers) {
            rv = APR_EAGAIN;
            goto cleanup;
        }
    
        rv = h2_res_create_ngtrailer(&nh, stream->pool, headers);
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c1,
                      H2_STRM_LOG(APLOGNO(03072), stream, "submit %d trailers"),
                      (int)nh->nvlen);
        if (APR_SUCCESS != rv) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c1,
                          H2_STRM_LOG(APLOGNO(10024), stream, "invalid trailers"));
            h2_stream_rst(stream, NGHTTP2_PROTOCOL_ERROR);
            goto cleanup;
        }
    
        ngrv = nghttp2_submit_trailer(stream->session->ngh2, stream->id, nh->nv, nh->nvlen);
        if (nghttp2_is_fatal(ngrv)) {
            rv = APR_EGENERAL;
            h2_session_dispatch_event(stream->session,
                                     H2_SESSION_EV_PROTO_ERROR, ngrv, nghttp2_strerror(rv));
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c1,
                          APLOGNO(02940) "submit_response: %s",
                          nghttp2_strerror(rv));
        }
        stream->sent_trailers = 1;
    
    cleanup:
        return rv;
    }
    
    #if AP_HAS_RESPONSE_BUCKETS
    apr_status_t h2_stream_submit_pushes(h2_stream *stream, ap_bucket_response *response)
    #else
    apr_status_t h2_stream_submit_pushes(h2_stream *stream, h2_headers *response)
    #endif
    {
        apr_status_t status = APR_SUCCESS;
        apr_array_header_t *pushes;
        int i;
        
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        pushes = h2_push_collect_update(stream, stream->request, response);
        if (pushes && !apr_is_empty_array(pushes)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c1,
                          H2_STRM_MSG(stream, "found %d push candidates"),
                          pushes->nelts);
            for (i = 0; i < pushes->nelts; ++i) {
                h2_push *push = APR_ARRAY_IDX(pushes, i, h2_push*);
                h2_stream *s = h2_session_push(stream->session, stream, push);
                if (!s) {
                    status = APR_ECONNRESET;
                    break;
                }
            }
        }
        return status;
    }
    
    apr_table_t *h2_stream_get_trailers(h2_stream *stream)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        return NULL;
    }
    
    #if AP_HAS_RESPONSE_BUCKETS
    const h2_priority *h2_stream_get_priority(h2_stream *stream,
                                              ap_bucket_response *response)
    #else
    const h2_priority *h2_stream_get_priority(h2_stream *stream,
                                              h2_headers *response)
    #endif
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (response && stream->initiated_on) {
            const char *ctype = apr_table_get(response->headers, "content-type");
            if (ctype) {
                /* FIXME: Not good enough, config needs to come from request->server */
                return h2_cconfig_get_priority(stream->session->c1, ctype);
            }
        }
        return NULL;
    }
    
    int h2_stream_is_ready(h2_stream *stream)
    {
        /* Have we sent a response or do we have the response in our buffer? */
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (stream->response) {
            return 1;
        }
        else if (stream->out_buffer && get_first_response_bucket(stream->out_buffer)) {
            return 1;
        }
        return 0;
    }
    
    int h2_stream_wants_send_data(h2_stream *stream)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        return h2_stream_is_ready(stream) &&
               ((stream->out_buffer && !APR_BRIGADE_EMPTY(stream->out_buffer)) ||
                (stream->output && !h2_beam_empty(stream->output)));
    }
    
    int h2_stream_is_at(const h2_stream *stream, h2_stream_state_t state)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        return stream->state == state;
    }
    
    int h2_stream_is_at_or_past(const h2_stream *stream, h2_stream_state_t state)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        switch (state) {
            case H2_SS_IDLE:
                return 1; /* by definition */
            case H2_SS_RSVD_R: /*fall through*/
            case H2_SS_RSVD_L: /*fall through*/
            case H2_SS_OPEN:
                return stream->state == state || stream->state >= H2_SS_OPEN;
            case H2_SS_CLOSED_R: /*fall through*/
            case H2_SS_CLOSED_L: /*fall through*/
            case H2_SS_CLOSED:
                return stream->state == state || stream->state >= H2_SS_CLOSED;
            case H2_SS_CLEANUP:
                return stream->state == state;
            default:
                return 0;
        }
    }
    
    apr_status_t h2_stream_in_consumed(h2_stream *stream, apr_off_t amount)
    {
        h2_session *session = stream->session;
        
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (amount > 0) {
            apr_off_t consumed = amount;
            
            while (consumed > 0) {
                int len = (consumed > INT_MAX)? INT_MAX : (int)consumed;
                nghttp2_session_consume(session->ngh2, stream->id, len);
                consumed -= len;
            }
    
    #ifdef H2_NG2_LOCAL_WIN_SIZE
            if (1) {
                int cur_size = nghttp2_session_get_stream_local_window_size(
                    session->ngh2, stream->id);
                int win = stream->in_window_size;
                int thigh = win * 8/10;
                int tlow = win * 2/10;
                const int win_max = 2*1024*1024;
                const int win_min = 32*1024;
                
                /* Work in progress, probably should add directives for these
                 * values once this stabilizes somewhat. The general idea is
                 * to adapt stream window sizes if the input window changes
                 * a) very quickly (< good RTT) from full to empty
                 * b) only a little bit (> bad RTT)
                 * where in a) it grows and in b) it shrinks again.
                 */
                if (cur_size > thigh && amount > thigh && win < win_max) {
                    /* almost empty again with one reported consumption, how
                     * long did this take? */
                    long ms = apr_time_msec(apr_time_now() - stream->in_last_write);
                    if (ms < 40) {
                        win = H2MIN(win_max, win + (64*1024));
                    }
                }
                else if (cur_size < tlow && amount < tlow && win > win_min) {
                    /* staying full, for how long already? */
                    long ms = apr_time_msec(apr_time_now() - stream->in_last_write);
                    if (ms > 700) {
                        win = H2MAX(win_min, win - (32*1024));
                    }
                }
                
                if (win != stream->in_window_size) {
                    stream->in_window_size = win;
                    nghttp2_session_set_local_window_size(session->ngh2, 
                            NGHTTP2_FLAG_NONE, stream->id, win);
                } 
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                              H2_STRM_MSG(stream, "consumed %ld bytes, window now %d/%d"),
                              (long)amount, cur_size, stream->in_window_size);
            }
    #endif /* #ifdef H2_NG2_LOCAL_WIN_SIZE */
        }
        return APR_SUCCESS;   
    }
    
    static apr_off_t output_data_buffered(h2_stream *stream, int *peos, int *pheader_blocked)
    {
        /* How much data do we have in our buffers that we can write? */
        apr_off_t buf_len = 0;
        apr_bucket *b;
    
        *peos = *pheader_blocked = 0;
        if (stream->out_buffer) {
            b = APR_BRIGADE_FIRST(stream->out_buffer);
            while (b != APR_BRIGADE_SENTINEL(stream->out_buffer)) {
                if (APR_BUCKET_IS_METADATA(b)) {
                    if (APR_BUCKET_IS_EOS(b)) {
                        *peos = 1;
                        break;
                    }
    #if AP_HAS_RESPONSE_BUCKETS
                    else if (AP_BUCKET_IS_RESPONSE(b)) {
                        break;
                    }
                    else if (AP_BUCKET_IS_HEADERS(b)) {
                        *pheader_blocked = 1;
                        break;
                    }
    #else
                    else if (H2_BUCKET_IS_HEADERS(b)) {
                        *pheader_blocked = 1;
                        break;
                    }
    #endif
                }
                else {
                    buf_len += b->length;
                }
                b = APR_BUCKET_NEXT(b);
            }
        }
        return buf_len;
    }
    
    static ssize_t stream_data_cb(nghttp2_session *ng2s,
                                  int32_t stream_id,
                                  uint8_t *buf,
                                  size_t length,
                                  uint32_t *data_flags,
                                  nghttp2_data_source *source,
                                  void *puser)
    {
        h2_session *session = (h2_session *)puser;
        conn_rec *c1 = session->c1;
        apr_off_t buf_len;
        int eos, header_blocked;
        apr_status_t rv;
        h2_stream *stream;
    
        /* nghttp2 wants to send more DATA for the stream.
         * we should have submitted the final response at this time
         * after receiving output via stream_do_responses() */
        ap_assert(session);
        (void)ng2s;
        (void)buf;
        (void)source;
        stream = nghttp2_session_get_stream_user_data(session->ngh2, stream_id);
    
        if (!stream) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c1,
                          APLOGNO(02937)
                          H2_SSSN_STRM_MSG(session, stream_id, "data_cb, stream not found"));
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (!stream->output || !stream->response || !stream->out_buffer) {
            return NGHTTP2_ERR_DEFERRED;
        }
        if (stream->rst_error) {
            return NGHTTP2_ERR_DEFERRED;
        }
        if (h2_c1_io_needs_flush(&session->io)) {
            rv = h2_c1_io_pass(&session->io);
            if (APR_STATUS_IS_EAGAIN(rv)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c1,
                              H2_SSSN_STRM_MSG(session, stream_id, "suspending on c1 out needs flush"));
                h2_stream_dispatch(stream, H2_SEV_OUT_C1_BLOCK);
                return NGHTTP2_ERR_DEFERRED;
            }
            else if (rv) {
                h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, rv, NULL);
                return NGHTTP2_ERR_CALLBACK_FAILURE;
            }
        }
    
        /* determine how much we'd like to send. We cannot send more than
         * is requested. But we can reduce the size in case the master
         * connection operates in smaller chunks. (TSL warmup) */
        if (stream->session->io.write_size > 0) {
            apr_size_t chunk_len = stream->session->io.write_size - H2_FRAME_HDR_LEN;
            if (length > chunk_len) {
                length = chunk_len;
            }
        }
        /* We allow configurable max DATA frame length. */
        if (stream->session->max_data_frame_len > 0
            && length > stream->session->max_data_frame_len) {
          length = stream->session->max_data_frame_len;
        }
    
        /* How much data do we have in our buffers that we can write?
         * if not enough, receive more. */
        buf_len = output_data_buffered(stream, &eos, &header_blocked);
        if (buf_len < (apr_off_t)length && !eos
               && !header_blocked && !stream->rst_error) {
            /* read more? */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c1,
                          H2_SSSN_STRM_MSG(session, stream_id,
                          "need more (read len=%ld, %ld in buffer)"),
                          (long)length, (long)buf_len);
            rv = buffer_output_receive(stream);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c1,
                          H2_SSSN_STRM_MSG(session, stream_id,
                          "buffer_output_received"));
            if (APR_STATUS_IS_EAGAIN(rv)) {
                /* currently, no more is available */
            }
            else if (APR_SUCCESS == rv) {
                /* got some, re-assess */
                buf_len = output_data_buffered(stream, &eos, &header_blocked);
            }
            else if (APR_EOF == rv) {
                if (!stream->output_eos) {
                    /* Seeing APR_EOF without an EOS bucket received before indicates
                     * that stream output is incomplete. Commonly, we expect to see
                     * an ERROR bucket to have been generated. But faulty handlers
                     * may not have generated one.
                     * We need to RST the stream bc otherwise the client thinks
                     * it is all fine. */
                     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c1,
                                   H2_SSSN_STRM_MSG(session, stream_id, "rst stream"));
                     h2_stream_rst(stream, H2_ERR_STREAM_CLOSED);
                     return NGHTTP2_ERR_DEFERRED;
                }
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c1,
                              H2_SSSN_STRM_MSG(session, stream_id,
                              "eof on receive (read len=%ld, %ld in buffer)"),
                              (long)length, (long)buf_len);
                eos = 1;
                rv = APR_SUCCESS;
            }
            else if (APR_ECONNRESET == rv || APR_ECONNABORTED == rv) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c1,
                              H2_STRM_LOG(APLOGNO(10471), stream, "data_cb, reading data"));
                h2_stream_rst(stream, H2_ERR_STREAM_CLOSED);
                return NGHTTP2_ERR_DEFERRED;
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c1,
                              H2_STRM_LOG(APLOGNO(02938), stream, "data_cb, reading data"));
                h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
                return NGHTTP2_ERR_DEFERRED;
            }
        }
    
        if (stream->rst_error) {
            return NGHTTP2_ERR_DEFERRED;
        }
    
        if (buf_len == 0 && header_blocked) {
            rv = stream_do_trailers(stream);
            if (APR_SUCCESS != rv && !APR_STATUS_IS_EAGAIN(rv)) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c1,
                              H2_STRM_LOG(APLOGNO(10300), stream,
                              "data_cb, error processing trailers"));
                return NGHTTP2_ERR_CALLBACK_FAILURE;
            }
            length = 0;
            eos = 0;
        }
        else if (buf_len > (apr_off_t)length) {
            eos = 0;  /* Any EOS we have in the buffer does not apply yet */
        }
        else {
            length = (size_t)buf_len;
        }
    
        if (length) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c1,
                          H2_STRM_MSG(stream, "data_cb, sending len=%ld, eos=%d"),
                          (long)length, eos);
            *data_flags |=  NGHTTP2_DATA_FLAG_NO_COPY;
        }
        else if (!eos && !stream->sent_trailers) {
            /* We have not reached the end of DATA yet, DEFER sending */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c1,
                          H2_STRM_LOG(APLOGNO(03071), stream, "data_cb, suspending"));
            return NGHTTP2_ERR_DEFERRED;
        }
    
        if (eos) {
            *data_flags |= NGHTTP2_DATA_FLAG_EOF;
        }
        return length;
    }
    
    static apr_status_t stream_do_response(h2_stream *stream)
    {
        conn_rec *c1 = stream->session->c1;
        apr_status_t rv = APR_EAGAIN;
        int ngrv, is_empty = 0;
        h2_ngheader *nh = NULL;
        apr_bucket *b, *e;
    #if AP_HAS_RESPONSE_BUCKETS
        ap_bucket_response *resp = NULL;
    #else
        h2_headers *resp = NULL;
    #endif
        nghttp2_data_provider provider, *pprovider = NULL;
    
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        ap_assert(!stream->response);
        ap_assert(stream->out_buffer);
    
        b = APR_BRIGADE_FIRST(stream->out_buffer);
        while (b != APR_BRIGADE_SENTINEL(stream->out_buffer)) {
            e = APR_BUCKET_NEXT(b);
            if (APR_BUCKET_IS_METADATA(b)) {
    #if AP_HAS_RESPONSE_BUCKETS
                if (AP_BUCKET_IS_RESPONSE(b)) {
                    resp = b->data;
    #else /* AP_HAS_RESPONSE_BUCKETS */
                if (H2_BUCKET_IS_HEADERS(b)) {
                    resp = h2_bucket_headers_get(b);
    #endif /* else AP_HAS_RESPONSE_BUCKETS */
                    APR_BUCKET_REMOVE(b);
                    apr_bucket_destroy(b);
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c1,
                                  H2_STRM_MSG(stream, "process response %d"),
                                  resp->status);
                    is_empty = (e != APR_BRIGADE_SENTINEL(stream->out_buffer)
                                && APR_BUCKET_IS_EOS(e));
                    break;
                }
                else if (APR_BUCKET_IS_EOS(b)) {
                    h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
                    rv = APR_EINVAL;
                    goto cleanup;
                }
                else if (AP_BUCKET_IS_ERROR(b)) {
                    stream_do_error_bucket(stream, b);
                    rv = APR_EINVAL;
                    goto cleanup;
                }
            }
            else {
                /* data buckets before response headers, an error */
                h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
                rv = APR_EINVAL;
                goto cleanup;
            }
            b = e;
        }
    
        if (!resp) {
            rv = APR_EAGAIN;
            goto cleanup;
        }
    
        if (resp->status < 100) {
            h2_stream_rst(stream, resp->status);
            goto cleanup;
        }
    
        if (resp->status == HTTP_FORBIDDEN && resp->notes) {
            const char *cause = apr_table_get(resp->notes, "ssl-renegotiate-forbidden");
            if (cause) {
                /* This request triggered a TLS renegotiation that is not allowed
                 * in HTTP/2. Tell the client that it should use HTTP/1.1 for this.
                 */
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, resp->status, c1,
                              H2_STRM_LOG(APLOGNO(03061), stream,
                              "renegotiate forbidden, cause: %s"), cause);
                h2_stream_rst(stream, H2_ERR_HTTP_1_1_REQUIRED);
                goto cleanup;
            }
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c1,
                      H2_STRM_LOG(APLOGNO(03073), stream,
                      "submit response %d"), resp->status);
    
        /* If this stream is not a pushed one itself,
         * and HTTP/2 server push is enabled here,
         * and the response HTTP status is not sth >= 400,
         * and the remote side has pushing enabled,
         * -> find and perform any pushes on this stream
         *    *before* we submit the stream response itself.
         *    This helps clients avoid opening new streams on Link
         *    resp that get pushed right afterwards.
         *
         * *) the response code is relevant, as we do not want to
         *    make pushes on 401 or 403 codes and friends.
         *    And if we see a 304, we do not push either
         *    as the client, having this resource in its cache, might
         *    also have the pushed ones as well.
         */
        if (!stream->initiated_on
            && !stream->response
            && stream->request && stream->request->method
            && !strcmp("GET", stream->request->method)
            && (resp->status < 400)
            && (resp->status != 304)
            && h2_session_push_enabled(stream->session)) {
            /* PUSH is possible and enabled on server, unless the request
             * denies it, submit resources to push */
            const char *s = apr_table_get(resp->notes, H2_PUSH_MODE_NOTE);
            if (!s || strcmp(s, "0")) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c1,
                              H2_STRM_MSG(stream, "submit pushes, note=%s"), s);
                h2_stream_submit_pushes(stream, resp);
            }
        }
    
        if (!stream->pref_priority) {
            stream->pref_priority = h2_stream_get_priority(stream, resp);
        }
        h2_session_set_prio(stream->session, stream, stream->pref_priority);
    
        if (resp->status == 103
            && !h2_config_sgeti(stream->session->s, H2_CONF_EARLY_HINTS)) {
            /* suppress sending this to the client, it might have triggered
             * pushes and served its purpose nevertheless */
            rv = APR_SUCCESS;
            goto cleanup;
        }
        if (resp->status >= 200) {
            stream->response = resp;
        }
    
        if (!is_empty) {
            memset(&provider, 0, sizeof(provider));
            provider.source.fd = stream->id;
            provider.read_callback = stream_data_cb;
            pprovider = &provider;
        }
    
        rv = h2_res_create_ngheader(&nh, stream->pool, resp);
        if (APR_SUCCESS != rv) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c1,
                          H2_STRM_LOG(APLOGNO(10025), stream, "invalid response"));
            h2_stream_rst(stream, NGHTTP2_PROTOCOL_ERROR);
            goto cleanup;
        }
    
        ngrv = nghttp2_submit_response(stream->session->ngh2, stream->id,
                                       nh->nv, nh->nvlen, pprovider);
        if (nghttp2_is_fatal(ngrv)) {
            rv = APR_EGENERAL;
            h2_session_dispatch_event(stream->session,
                                     H2_SESSION_EV_PROTO_ERROR, ngrv, nghttp2_strerror(ngrv));
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c1,
                          APLOGNO(10402) "submit_response: %s",
                          nghttp2_strerror(ngrv));
            goto cleanup;
        }
    
        if (stream->initiated_on) {
            ++stream->session->pushes_submitted;
        }
        else {
            ++stream->session->responses_submitted;
        }
    
    cleanup:
        return rv;
    }
    
    static void stream_do_responses(h2_stream *stream)
    {
        h2_session *session = stream->session;
        conn_rec *c1 = session->c1;
        apr_status_t rv;
    
        ap_assert(!stream->response);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c1,
                      H2_STRM_MSG(stream, "do_response"));
        rv = buffer_output_receive(stream);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c1,
                      H2_SSSN_STRM_MSG(session, stream->id,
                      "buffer_output_received2"));
        if (APR_SUCCESS != rv && APR_EAGAIN != rv) {
            h2_stream_rst(stream, NGHTTP2_PROTOCOL_ERROR);
        }
        else {
            /* process all headers sitting at the buffer head. */
            do {
                rv = stream_do_response(stream);
            } while (APR_SUCCESS == rv
                     && !stream->rst_error
                     && !stream->response);
        }
    }
    
    void h2_stream_on_output_change(h2_stream *stream)
    {
        conn_rec *c1 = stream->session->c1;
        apr_status_t rv = APR_EAGAIN;
    
        /* stream->pout_recv_write signalled a change. Check what has happend, read
         * from it and act on seeing a response/data. */
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        if (!stream->output) {
            /* c2 has not assigned the output beam to the stream (yet). */
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c1,
                          H2_STRM_MSG(stream, "read_output, no output beam registered"));
        }
        else if (h2_stream_is_at_or_past(stream, H2_SS_CLOSED)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c1,
                          H2_STRM_LOG(APLOGNO(10301), stream, "already closed"));
        }
        else if (h2_stream_is_at(stream, H2_SS_CLOSED_L)) {
            /* We have delivered a response to a stream that was not closed
             * by the client. This could be a POST with body that we negate
             * and we need to RST_STREAM to end if. */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c1,
                          H2_STRM_LOG(APLOGNO(10313), stream, "remote close missing"));
            h2_stream_rst(stream, H2_ERR_NO_ERROR);
        }
        else {
            /* stream is not closed, a change in output happened. There are
             * two modes of operation here:
             * 1) the final response has been submitted. nghttp2 is invoking
             *    stream_data_cb() to progress the stream. This handles DATA,
             *    trailers, EOS and ERRORs.
             *    When stream_data_cb() runs out of things to send, it returns
             *    NGHTTP2_ERR_DEFERRED and nghttp2 *suspends* further processing
             *    until we tell it to resume.
             * 2) We have not seen the *final* response yet. The stream can not
             *    send any response DATA. The nghttp2 stream_data_cb() is not
             *    invoked. We need to receive output, expecting not DATA but
             *    RESPONSEs (intermediate may arrive) and submit those. On
             *    the final response, nghttp2 will start calling stream_data_cb().
             */
            if (stream->response) {
                nghttp2_session_resume_data(stream->session->ngh2, stream->id);
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c1,
                              H2_STRM_MSG(stream, "resumed"));
            }
            else {
                stream_do_responses(stream);
                if (!stream->rst_error) {
                    nghttp2_session_resume_data(stream->session->ngh2, stream->id);
                }
            }
        }
    }
    
    void h2_stream_on_input_change(h2_stream *stream)
    {
        H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
        ap_assert(stream->input);
        h2_beam_report_consumption(stream->input);
        if (h2_stream_is_at(stream, H2_SS_CLOSED_L)
            && !h2_mplx_c1_stream_is_running(stream->session->mplx, stream)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, stream->session->c1,
                          H2_STRM_LOG(APLOGNO(10026), stream, "remote close missing"));
            h2_stream_rst(stream, H2_ERR_NO_ERROR);
        }
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_mplx.c����������������������������������������������������������������0000664�0001751�0001751�00000124237�15017526503�017065� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    #include <stdlib.h>
    
    #include <apr_atomic.h>
    #include <apr_thread_mutex.h>
    #include <apr_thread_cond.h>
    #include <apr_strings.h>
    #include <apr_time.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_connection.h>
    #include <http_log.h>
    #include <http_protocol.h>
    #include <scoreboard.h>
    
    #include <mpm_common.h>
    
    #include "mod_http2.h"
    
    #include "h2.h"
    #include "h2_private.h"
    #include "h2_bucket_beam.h"
    #include "h2_config.h"
    #include "h2_c1.h"
    #include "h2_conn_ctx.h"
    #include "h2_protocol.h"
    #include "h2_mplx.h"
    #include "h2_request.h"
    #include "h2_stream.h"
    #include "h2_session.h"
    #include "h2_c2.h"
    #include "h2_workers.h"
    #include "h2_util.h"
    
    
    /* utility for iterating over ihash stream sets */
    typedef struct {
        h2_mplx *m;
        h2_stream *stream;
        apr_time_t now;
        apr_size_t count;
    } stream_iter_ctx;
    
    static conn_rec *c2_prod_next(void *baton, int *phas_more);
    static void c2_prod_done(void *baton, conn_rec *c2);
    static void workers_shutdown(void *baton, int graceful);
    
    static void s_mplx_be_happy(h2_mplx *m, conn_rec *c, h2_conn_ctx_t *conn_ctx);
    static void m_be_annoyed(h2_mplx *m);
    
    static apr_status_t mplx_pollset_create(h2_mplx *m);
    static apr_status_t mplx_pollset_poll(h2_mplx *m, apr_interval_time_t timeout,
                                stream_ev_callback *on_stream_input,
                                stream_ev_callback *on_stream_output,
                                void *on_ctx);
    
    static apr_pool_t *pchild;
    
    /* APR callback invoked if allocation fails. */
    static int abort_on_oom(int retcode)
    {
        ap_abort_on_oom();
        return retcode; /* unreachable, hopefully. */
    }
    
    apr_status_t h2_mplx_c1_child_init(apr_pool_t *pool, server_rec *s)
    {
        pchild = pool;
        return APR_SUCCESS;
    }
    
    #define H2_MPLX_ENTER(m)    \
        do { apr_status_t rv_lock; if ((rv_lock = apr_thread_mutex_lock(m->lock)) != APR_SUCCESS) {\
            return rv_lock;\
        } } while(0)
    
    #define H2_MPLX_LEAVE(m)    \
        apr_thread_mutex_unlock(m->lock)
     
    #define H2_MPLX_ENTER_ALWAYS(m)    \
        apr_thread_mutex_lock(m->lock)
    
    #define H2_MPLX_ENTER_MAYBE(m, dolock)    \
        if (dolock) apr_thread_mutex_lock(m->lock)
    
    #define H2_MPLX_LEAVE_MAYBE(m, dolock)    \
        if (dolock) apr_thread_mutex_unlock(m->lock)
    
    static void c1_input_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length)
    {
        h2_stream_in_consumed(ctx, length);
    }
    
    static int stream_is_running(h2_stream *stream)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(stream->c2);
        return conn_ctx && apr_atomic_read32(&conn_ctx->started) != 0
            && apr_atomic_read32(&conn_ctx->done) == 0;
    }
    
    int h2_mplx_c1_stream_is_running(h2_mplx *m, h2_stream *stream)
    {
        int rv;
    
        H2_MPLX_ENTER(m);
        rv = stream_is_running(stream);
        H2_MPLX_LEAVE(m);
        return rv;
    }
    
    static void c1c2_stream_joined(h2_mplx *m, h2_stream *stream)
    {
        ap_assert(!stream_is_running(stream));
        
        h2_ihash_remove(m->shold, stream->id);
        APR_ARRAY_PUSH(m->spurge, h2_stream *) = stream;
    }
    
    static void m_stream_cleanup(h2_mplx *m, h2_stream *stream)
    {
        h2_conn_ctx_t *c2_ctx = h2_conn_ctx_get(stream->c2);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                      H2_STRM_MSG(stream, "cleanup, unsubscribing from beam events"));
        if (c2_ctx) {
            if (c2_ctx->beam_out) {
                h2_beam_on_was_empty(c2_ctx->beam_out, NULL, NULL);
            }
            if (c2_ctx->beam_in) {
                h2_beam_on_send(c2_ctx->beam_in, NULL, NULL);
                h2_beam_on_received(c2_ctx->beam_in, NULL, NULL);
                h2_beam_on_eagain(c2_ctx->beam_in, NULL, NULL);
                h2_beam_on_consumed(c2_ctx->beam_in, NULL, NULL);
            }
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                      H2_STRM_MSG(stream, "cleanup, removing from registries"));
        ap_assert(stream->state == H2_SS_CLEANUP);
        h2_stream_cleanup(stream);
        h2_ihash_remove(m->streams, stream->id);
        h2_iq_remove(m->q, stream->id);
    
        if (c2_ctx) {
            if (!stream_is_running(stream)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                              H2_STRM_MSG(stream, "cleanup, c2 is done, move to spurge"));
                /* processing has finished */
                APR_ARRAY_PUSH(m->spurge, h2_stream *) = stream;
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                              H2_STRM_MSG(stream, "cleanup, c2 is running, abort"));
                /* c2 is still running */
                h2_c2_abort(stream->c2, m->c1);
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                              H2_STRM_MSG(stream, "cleanup, c2 is done, move to shold"));
                h2_ihash_add(m->shold, stream);
            }
        }
        else {
            /* never started */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                          H2_STRM_MSG(stream, "cleanup, never started, move to spurge"));
            APR_ARRAY_PUSH(m->spurge, h2_stream *) = stream;
        }
    }
    
    static h2_c2_transit *c2_transit_create(h2_mplx *m)
    {
        apr_allocator_t *allocator;
        apr_pool_t *ptrans;
        h2_c2_transit *transit;
        apr_status_t rv;
    
        /* We create a pool with its own allocator to be used for
         * processing a request. This is the only way to have the processing
         * independent of its parent pool in the sense that it can work in
         * another thread.
         */
    
        rv = apr_allocator_create(&allocator);
        if (rv == APR_SUCCESS) {
            apr_allocator_max_free_set(allocator, ap_max_mem_free);
            rv = apr_pool_create_ex(&ptrans, m->pool, NULL, allocator);
        }
        if (rv != APR_SUCCESS) {
            /* maybe the log goes through, maybe not. */
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, m->c1,
                          APLOGNO(10004) "h2_mplx: create transit pool");
            ap_abort_on_oom();
            return NULL; /* should never be reached. */
        }
    
        apr_allocator_owner_set(allocator, ptrans);
        apr_pool_abort_set(abort_on_oom, ptrans);
        apr_pool_tag(ptrans, "h2_c2_transit");
    
        transit = apr_pcalloc(ptrans, sizeof(*transit));
        transit->pool = ptrans;
        transit->bucket_alloc = apr_bucket_alloc_create(ptrans);
        return transit;
    }
    
    static void c2_transit_destroy(h2_c2_transit *transit)
    {
        apr_pool_destroy(transit->pool);
    }
    
    static h2_c2_transit *c2_transit_get(h2_mplx *m)
    {
        h2_c2_transit **ptransit = apr_array_pop(m->c2_transits);
        if (ptransit) {
            return *ptransit;
        }
        return c2_transit_create(m);
    }
    
    static void c2_transit_recycle(h2_mplx *m, h2_c2_transit *transit)
    {
        if (m->c2_transits->nelts >= APR_INT32_MAX ||
            (apr_uint32_t)m->c2_transits->nelts >= m->max_spare_transits) {
            c2_transit_destroy(transit);
        }
        else {
            APR_ARRAY_PUSH(m->c2_transits, h2_c2_transit*) = transit;
        }
    }
    
    /**
     * A h2_mplx needs to be thread-safe *and* if will be called by
     * the h2_session thread *and* the h2_worker threads. Therefore:
     * - calls are protected by a mutex lock, m->lock
     * - the pool needs its own allocator, since apr_allocator_t are 
     *   not re-entrant. The separate allocator works without a 
     *   separate lock since we already protect h2_mplx itself.
     *   Since HTTP/2 connections can be expected to live longer than
     *   their HTTP/1 cousins, the separate allocator seems to work better
     *   than protecting a shared h2_session one with an own lock.
     */
    h2_mplx *h2_mplx_c1_create(int child_num, apr_uint32_t id, h2_stream *stream0,
                               server_rec *s, apr_pool_t *parent,
                               h2_workers *workers)
    {
        h2_conn_ctx_t *conn_ctx;
        apr_status_t status = APR_SUCCESS;
        apr_allocator_t *allocator;
        apr_thread_mutex_t *mutex = NULL;
        h2_mplx *m = NULL;
        
        m = apr_pcalloc(parent, sizeof(h2_mplx));
        m->stream0 = stream0;
        m->c1 = stream0->c2;
        m->s = s;
        m->child_num = child_num;
        m->id = id;
    
        /* We create a pool with its own allocator to be used for
         * processing secondary connections. This is the only way to have the
         * processing independent of its parent pool in the sense that it
         * can work in another thread. Also, the new allocator needs its own
         * mutex to synchronize sub-pools.
         */
        status = apr_allocator_create(&allocator);
        if (status != APR_SUCCESS) {
            allocator = NULL;
            goto failure;
        }
    
        apr_allocator_max_free_set(allocator, ap_max_mem_free);
        apr_pool_create_ex(&m->pool, parent, NULL, allocator);
        if (!m->pool) goto failure;
    
        apr_pool_tag(m->pool, "h2_mplx");
        apr_allocator_owner_set(allocator, m->pool);
    
        status = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT,
                                         m->pool);
        if (APR_SUCCESS != status) goto failure;
        apr_allocator_mutex_set(allocator, mutex);
    
        status = apr_thread_mutex_create(&m->lock, APR_THREAD_MUTEX_DEFAULT,
                                         m->pool);
        if (APR_SUCCESS != status) goto failure;
    
        m->max_streams = h2_config_sgeti(s, H2_CONF_MAX_STREAMS);
        m->stream_max_mem = h2_config_sgeti(s, H2_CONF_STREAM_MAX_MEM);
    
        m->streams = h2_ihash_create(m->pool, offsetof(h2_stream,id));
        m->shold = h2_ihash_create(m->pool, offsetof(h2_stream,id));
        m->spurge = apr_array_make(m->pool, 10, sizeof(h2_stream*));
        m->q = h2_iq_create(m->pool, m->max_streams);
    
        m->workers = workers;
        m->processing_max = H2MIN(h2_workers_get_max_workers(workers), m->max_streams);
        m->processing_limit = 6; /* the original h1 max parallel connections */
        m->last_mood_change = apr_time_now();
        m->mood_update_interval = apr_time_from_msec(100);
    
        status = mplx_pollset_create(m);
        if (APR_SUCCESS != status) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, status, m->c1, APLOGNO(10308)
                          "nghttp2: could not create pollset");
            goto failure;
        }
        m->streams_ev_in = apr_array_make(m->pool, 10, sizeof(h2_stream*));
        m->streams_ev_out = apr_array_make(m->pool, 10, sizeof(h2_stream*));
    
        m->streams_input_read = h2_iq_create(m->pool, 10);
        m->streams_output_written = h2_iq_create(m->pool, 10);
        status = apr_thread_mutex_create(&m->poll_lock, APR_THREAD_MUTEX_DEFAULT,
                                         m->pool);
        if (APR_SUCCESS != status) goto failure;
    
        conn_ctx = h2_conn_ctx_get(m->c1);
        if (conn_ctx->pfd.reqevents) {
            apr_pollset_add(m->pollset, &conn_ctx->pfd);
        }
    
        m->max_spare_transits = 3;
        m->c2_transits = apr_array_make(m->pool, (int)m->max_spare_transits,
                                        sizeof(h2_c2_transit*));
    
        m->producer = h2_workers_register(workers, m->pool,
                                          apr_psprintf(m->pool, "h2-%u",
                                          (unsigned int)m->id),
                                          c2_prod_next, c2_prod_done,
                                          workers_shutdown, m);
        return m;
    
    failure:
        if (m->pool) {
            apr_pool_destroy(m->pool);
        }
        else if (allocator) {
            apr_allocator_destroy(allocator);
        }
        return NULL;
    }
    
    int h2_mplx_c1_shutdown(h2_mplx *m)
    {
        int max_stream_id_started = 0;
        
        H2_MPLX_ENTER(m);
    
        max_stream_id_started = m->max_stream_id_started;
        /* Clear schedule queue, disabling existing streams from starting */ 
        h2_iq_clear(m->q);
    
        H2_MPLX_LEAVE(m);
        return max_stream_id_started;
    }
    
    typedef struct {
        h2_mplx_stream_cb *cb;
        void *ctx;
    } stream_iter_ctx_t;
    
    static int m_stream_iter_wrap(void *ctx, void *stream)
    {
        stream_iter_ctx_t *x = ctx;
        return x->cb(stream, x->ctx);
    }
    
    apr_status_t h2_mplx_c1_streams_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx)
    {
        stream_iter_ctx_t x;
        
        H2_MPLX_ENTER(m);
    
        x.cb = cb;
        x.ctx = ctx;
        h2_ihash_iter(m->streams, m_stream_iter_wrap, &x);
            
        H2_MPLX_LEAVE(m);
        return APR_SUCCESS;
    }
    
    typedef struct {
        int stream_count;
        int stream_want_send;
        int stream_send_win_exhausted;
    } stream_iter_aws_t;
    
    static int m_stream_want_send_data(void *ctx, void *stream)
    {
        stream_iter_aws_t *x = ctx;
        ++x->stream_count;
        if (h2_stream_wants_send_data(stream))
          ++x->stream_want_send;
        return 1;
    }
    
    int h2_mplx_c1_all_streams_want_send_data(h2_mplx *m)
    {
        stream_iter_aws_t x;
        x.stream_count = 0;
        x.stream_want_send = 0;
        H2_MPLX_ENTER(m);
        h2_ihash_iter(m->streams, m_stream_want_send_data, &x);
        H2_MPLX_LEAVE(m);
        return x.stream_count && (x.stream_count == x.stream_want_send);
    }
    
    static int m_stream_send_win_exh(void *ctx, void *s)
    {
        h2_stream *stream = s;
        int win;
        stream_iter_aws_t *x = ctx;
        ++x->stream_count;
        win = nghttp2_session_get_stream_remote_window_size(stream->session->ngh2, stream->id);
        if (win == 0)
          ++x->stream_send_win_exhausted;
        return 1;
    }
    
    int h2_mplx_c1_all_streams_send_win_exhausted(h2_mplx *m)
    {
        stream_iter_aws_t x;
        x.stream_count = 0;
        x.stream_send_win_exhausted = 0;
        H2_MPLX_ENTER(m);
        h2_ihash_iter(m->streams, m_stream_send_win_exh, &x);
        H2_MPLX_LEAVE(m);
        return x.stream_count && (x.stream_count == x.stream_send_win_exhausted);
    }
    
    static int m_report_stream_iter(void *ctx, void *val) {
        h2_mplx *m = ctx;
        h2_stream *stream = val;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(stream->c2);
        ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c1,
                      H2_STRM_MSG(stream, "started=%d, scheduled=%d, ready=%d, out_buffer=%ld"),
                      !!stream->c2, stream->scheduled, h2_stream_is_ready(stream),
                      (long)(stream->output? h2_beam_get_buffered(stream->output) : -1));
        if (conn_ctx) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c1, /* NO APLOGNO */
                          H2_STRM_MSG(stream, "->03198: %s %s %s"
                          "[started=%u/done=%u]"),
                          conn_ctx->request->method, conn_ctx->request->authority,
                          conn_ctx->request->path,
                          apr_atomic_read32(&conn_ctx->started),
                          apr_atomic_read32(&conn_ctx->done));
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c1, /* NO APLOGNO */
                          H2_STRM_MSG(stream, "->03198: not started"));
        }
        return 1;
    }
    
    static int m_unexpected_stream_iter(void *ctx, void *val) {
        h2_mplx *m = ctx;
        h2_stream *stream = val;
        ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c1, /* NO APLOGNO */
                      H2_STRM_MSG(stream, "unexpected, started=%d, scheduled=%d, ready=%d"), 
                      !!stream->c2, stream->scheduled, h2_stream_is_ready(stream));
        return 1;
    }
    
    static int m_stream_cancel_iter(void *ctx, void *val) {
        h2_mplx *m = ctx;
        h2_stream *stream = val;
    
        /* take over event monitoring */
        h2_stream_set_monitor(stream, NULL);
        /* Reset, should transit to CLOSED state */
        h2_stream_rst(stream, H2_ERR_NO_ERROR);
        /* All connection data has been sent, simulate cleanup */
        h2_stream_dispatch(stream, H2_SEV_EOS_SENT);
        m_stream_cleanup(m, stream);  
        return 0;
    }
    
    static void c1_purge_streams(h2_mplx *m);
    
    void h2_mplx_c1_destroy(h2_mplx *m)
    {
        apr_status_t status;
        unsigned int i, wait_secs = 60;
        int old_aborted;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                      H2_MPLX_MSG(m, "start release"));
        /* How to shut down a h2 connection:
         * 0. abort and tell the workers that no more work will come from us */
        m->shutdown = m->aborted = 1;
    
        H2_MPLX_ENTER_ALWAYS(m);
    
        /* While really terminating any c2 connections, treat the master
         * connection as aborted. It's not as if we could send any more data
         * at this point. */
        old_aborted = m->c1->aborted;
        m->c1->aborted = 1;
    
        /* How to shut down a h2 connection:
         * 1. cancel all streams still active */
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                      H2_MPLX_MSG(m, "release, %u/%u/%d streams (total/hold/purge), %d streams"),
                      h2_ihash_count(m->streams),
                      h2_ihash_count(m->shold),
                      m->spurge->nelts, m->processing_count);
        while (!h2_ihash_iter(m->streams, m_stream_cancel_iter, m)) {
            /* until empty */
        }
        
        /* 2. no more streams should be scheduled or in the active set */
        ap_assert(h2_ihash_empty(m->streams));
        ap_assert(h2_iq_empty(m->q));
        
        /* 3. while workers are busy on this connection, meaning they
         *    are processing streams from this connection, wait on them finishing
         *    in order to wake us and let us check again. 
         *    Eventually, this has to succeed. */
        if (!m->join_wait) {
            apr_thread_cond_create(&m->join_wait, m->pool);
        }
    
        for (i = 0; h2_ihash_count(m->shold) > 0; ++i) {
            status = apr_thread_cond_timedwait(m->join_wait, m->lock, apr_time_from_sec(wait_secs));
            
            if (APR_STATUS_IS_TIMEUP(status)) {
                /* This can happen if we have very long running requests
                 * that do not time out on IO. */
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c1, APLOGNO(03198)
                              H2_MPLX_MSG(m, "waited %u sec for %u streams"),
                              i*wait_secs, h2_ihash_count(m->shold));
                h2_ihash_iter(m->shold, m_report_stream_iter, m);
            }
        }
    
        H2_MPLX_LEAVE(m);
        h2_workers_join(m->workers, m->producer);
        H2_MPLX_ENTER_ALWAYS(m);
    
        /* 4. With all workers done, all streams should be in spurge */
        ap_assert(m->processing_count == 0);
        if (!h2_ihash_empty(m->shold)) {
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c1, APLOGNO(03516)
                          H2_MPLX_MSG(m, "unexpected %u streams in hold"),
                          h2_ihash_count(m->shold));
            h2_ihash_iter(m->shold, m_unexpected_stream_iter, m);
        }
    
        c1_purge_streams(m);
    
        m->c1->aborted = old_aborted;
        H2_MPLX_LEAVE(m);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                      H2_MPLX_MSG(m, "released"));
    }
    
    apr_status_t h2_mplx_c1_stream_cleanup(h2_mplx *m, h2_stream *stream,
                                           unsigned int *pstream_count)
    {
        H2_MPLX_ENTER(m);
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                      H2_STRM_MSG(stream, "cleanup"));
        m_stream_cleanup(m, stream);
        *pstream_count = h2_ihash_count(m->streams);
        H2_MPLX_LEAVE(m);
        return APR_SUCCESS;
    }
    
    const h2_stream *h2_mplx_c2_stream_get(h2_mplx *m, int stream_id)
    {
        h2_stream *s = NULL;
        
        H2_MPLX_ENTER_ALWAYS(m);
        s = h2_ihash_get(m->streams, stream_id);
        H2_MPLX_LEAVE(m);
    
        return s;
    }
    
    
    static void c1_purge_streams(h2_mplx *m)
    {
        h2_stream *stream;
        int i;
    
        for (i = 0; i < m->spurge->nelts; ++i) {
            stream = APR_ARRAY_IDX(m->spurge, i, h2_stream*);
            ap_assert(stream->state == H2_SS_CLEANUP);
    
            if (stream->input) {
                h2_beam_destroy(stream->input, m->c1);
                stream->input = NULL;
            }
            if (stream->c2) {
                conn_rec *c2 = stream->c2;
                h2_conn_ctx_t *c2_ctx = h2_conn_ctx_get(c2);
                h2_c2_transit *transit;
    
                stream->c2 = NULL;
                ap_assert(c2_ctx);
                transit = c2_ctx->transit;
                h2_c2_destroy(c2);  /* c2_ctx is gone as well */
                if (transit) {
                    c2_transit_recycle(m, transit);
                }
            }
            h2_stream_destroy(stream);
        }
        apr_array_clear(m->spurge);
    }
    
    void h2_mplx_c1_going_keepalive(h2_mplx *m)
    {
        H2_MPLX_ENTER_ALWAYS(m);
        if (m->spurge->nelts) {
            c1_purge_streams(m);
        }
        H2_MPLX_LEAVE(m);
    }
    
    apr_status_t h2_mplx_c1_poll(h2_mplx *m, apr_interval_time_t timeout,
                                stream_ev_callback *on_stream_input,
                                stream_ev_callback *on_stream_output,
                                void *on_ctx)
    {
        apr_status_t rv;
    
        H2_MPLX_ENTER(m);
    
        if (m->aborted) {
            rv = APR_ECONNABORTED;
            goto cleanup;
        }
        /* Purge (destroy) streams outside of pollset processing.
         * Streams that are registered in the pollset, will be removed
         * when they are destroyed, but the pollset works on copies
         * of these registrations. So, if we destroy streams while
         * processing pollset events, we might access freed memory.
         */
        if (m->spurge->nelts) {
            c1_purge_streams(m);
        }
        rv = mplx_pollset_poll(m, timeout, on_stream_input, on_stream_output, on_ctx);
    
    cleanup:
        H2_MPLX_LEAVE(m);
        return rv;
    }
    
    apr_status_t h2_mplx_c1_reprioritize(h2_mplx *m, h2_stream_pri_cmp_fn *cmp,
                                        h2_session *session)
    {
        apr_status_t status;
        
        H2_MPLX_ENTER(m);
    
        if (m->aborted) {
            status = APR_ECONNABORTED;
        }
        else {
            h2_iq_sort(m->q, cmp, session);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                          H2_MPLX_MSG(m, "reprioritize streams"));
            status = APR_SUCCESS;
        }
    
        H2_MPLX_LEAVE(m);
        return status;
    }
    
    static apr_status_t c1_process_stream(h2_mplx *m,
                                          h2_stream *stream,
                                          h2_stream_pri_cmp_fn *cmp,
                                          h2_session *session)
    {
        apr_status_t rv = APR_SUCCESS;
    
        if (m->aborted) {
            rv = APR_ECONNABORTED;
            goto cleanup;
        }
        if (!stream->request) {
            rv = APR_EINVAL;
            goto cleanup;
        }
        if (APLOGctrace1(m->c1)) {
            const h2_request *r = stream->request;
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                          H2_STRM_MSG(stream, "process %s%s%s %s%s%s%s"),
                          r->protocol? r->protocol : "",
                          r->protocol? " " : "",
                          r->method, r->scheme? r->scheme : "",
                          r->scheme? "://" : "",
                          r->authority, r->path? r->path: "");
        }
    
        stream->scheduled = 1;
        h2_ihash_add(m->streams, stream);
        if (h2_stream_is_ready(stream)) {
            /* already have a response */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                          H2_STRM_MSG(stream, "process, ready already"));
        }
        else {
            /* last chance to set anything up before stream is processed
             * by worker threads. */
            rv = h2_stream_prepare_processing(stream);
            if (APR_SUCCESS != rv) goto cleanup;
            h2_iq_add(m->q, stream->id, cmp, session);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                          H2_STRM_MSG(stream, "process, added to q"));
        }
    
    cleanup:
        return rv;
    }
    
    void h2_mplx_c1_process(h2_mplx *m,
                            h2_iqueue *ready_to_process,
                            h2_stream_get_fn *get_stream,
                            h2_stream_pri_cmp_fn *stream_pri_cmp,
                            h2_session *session,
                            unsigned int *pstream_count)
    {
        apr_status_t rv;
        int sid;
    
        H2_MPLX_ENTER_ALWAYS(m);
    
        while ((sid = h2_iq_shift(ready_to_process)) > 0) {
            h2_stream *stream = get_stream(session, sid);
            if (stream) {
                ap_assert(!stream->scheduled);
                rv = c1_process_stream(session->mplx, stream, stream_pri_cmp, session);
                if (APR_SUCCESS != rv) {
                    h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
                }
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                              H2_MPLX_MSG(m, "stream %d not found to process"), sid);
            }
        }
        if ((m->processing_count < m->processing_limit) && !h2_iq_empty(m->q)) {
            H2_MPLX_LEAVE(m);
            rv = h2_workers_activate(m->workers, m->producer);
            H2_MPLX_ENTER_ALWAYS(m);
            if (rv != APR_SUCCESS) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, m->c1, APLOGNO(10021)
                              H2_MPLX_MSG(m, "activate at workers"));
            }
        }
        *pstream_count = h2_ihash_count(m->streams);
    
    #if APR_POOL_DEBUG
        do {
            apr_size_t mem_g, mem_m, mem_s, mem_c1;
    
            mem_g = pchild? apr_pool_num_bytes(pchild, 1) : 0;
            mem_m = apr_pool_num_bytes(m->pool, 1);
            mem_s = apr_pool_num_bytes(session->pool, 1);
            mem_c1 = apr_pool_num_bytes(m->c1->pool, 1);
            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, m->c1,
                          H2_MPLX_MSG(m, "child mem=%ld, mplx mem=%ld, session mem=%ld, c1=%ld"),
                          (long)mem_g, (long)mem_m, (long)mem_s, (long)mem_c1);
    
        } while (0);
    #endif
    
        H2_MPLX_LEAVE(m);
    }
    
    static void c2_beam_input_write_notify(void *ctx, h2_bucket_beam *beam)
    {
        conn_rec *c = ctx;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
    
        (void)beam;
        if (conn_ctx && conn_ctx->stream_id && conn_ctx->pipe_in[H2_PIPE_IN]) {
            apr_file_putc(1, conn_ctx->pipe_in[H2_PIPE_IN]);
        }
    }
    
    static void add_stream_poll_event(h2_mplx *m, int stream_id, h2_iqueue *q)
    {
        apr_thread_mutex_lock(m->poll_lock);
        if (h2_iq_append(q, stream_id) && h2_iq_count(q) == 1) {
            /* newly added first */
            apr_pollset_wakeup(m->pollset);
        }
        apr_thread_mutex_unlock(m->poll_lock);
    }
    
    static void c2_beam_input_read_notify(void *ctx, h2_bucket_beam *beam)
    {
        conn_rec *c = ctx;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
    
        if (conn_ctx && conn_ctx->stream_id) {
            add_stream_poll_event(conn_ctx->mplx, conn_ctx->stream_id,
                                  conn_ctx->mplx->streams_input_read);
        }
    }
    
    static void c2_beam_input_read_eagain(void *ctx, h2_bucket_beam *beam)
    {
        conn_rec *c = ctx;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
        /* installed in the input bucket beams when we use pipes.
         * Drain the pipe just before the beam returns APR_EAGAIN.
         * A clean state for allowing polling on the pipe to rest
         * when the beam is empty */
        if (conn_ctx && conn_ctx->pipe_in[H2_PIPE_OUT]) {
            h2_util_drain_pipe(conn_ctx->pipe_in[H2_PIPE_OUT]);
        }
    }
    
    static void c2_beam_output_write_notify(void *ctx, h2_bucket_beam *beam)
    {
        conn_rec *c = ctx;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
    
        if (conn_ctx && conn_ctx->stream_id) {
            add_stream_poll_event(conn_ctx->mplx, conn_ctx->stream_id,
                                  conn_ctx->mplx->streams_output_written);
        }
    }
    
    static apr_status_t c2_setup_io(h2_mplx *m, conn_rec *c2, h2_stream *stream, h2_c2_transit *transit)
    {
        h2_conn_ctx_t *conn_ctx;
        apr_status_t rv = APR_SUCCESS;
        const char *action = "init";
    
        rv = h2_conn_ctx_init_for_c2(&conn_ctx, c2, m, stream, transit);
        if (APR_SUCCESS != rv) goto cleanup;
    
        if (!conn_ctx->beam_out) {
            action = "create output beam";
            rv = h2_beam_create(&conn_ctx->beam_out, c2, conn_ctx->req_pool,
                                stream->id, "output", 0, c2->base_server->timeout);
            if (APR_SUCCESS != rv) goto cleanup;
    
            h2_beam_buffer_size_set(conn_ctx->beam_out, m->stream_max_mem);
            h2_beam_on_was_empty(conn_ctx->beam_out, c2_beam_output_write_notify, c2);
        }
    
        memset(&conn_ctx->pipe_in, 0, sizeof(conn_ctx->pipe_in));
        if (stream->input) {
            conn_ctx->beam_in = stream->input;
            h2_beam_on_send(stream->input, c2_beam_input_write_notify, c2);
            h2_beam_on_received(stream->input, c2_beam_input_read_notify, c2);
            h2_beam_on_consumed(stream->input, c1_input_consumed, stream);
    #if H2_USE_PIPES
            action = "create input write pipe";
            rv = apr_file_pipe_create_pools(&conn_ctx->pipe_in[H2_PIPE_OUT],
                                            &conn_ctx->pipe_in[H2_PIPE_IN],
                                            APR_READ_BLOCK,
                                            c2->pool, c2->pool);
            if (APR_SUCCESS != rv) goto cleanup;
    #endif
            h2_beam_on_eagain(stream->input, c2_beam_input_read_eagain, c2);
            if (!h2_beam_empty(stream->input))
                c2_beam_input_write_notify(c2, stream->input);
        }
    
    cleanup:
        stream->output = (APR_SUCCESS == rv)? conn_ctx->beam_out : NULL;
        if (APR_SUCCESS != rv) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c2,
                          H2_STRM_LOG(APLOGNO(10309), stream,
                          "error %s"), action);
        }
        return rv;
    }
    
    static conn_rec *s_next_c2(h2_mplx *m)
    {
        h2_stream *stream = NULL;
        apr_status_t rv = APR_SUCCESS;
        apr_uint32_t sid;
        conn_rec *c2 = NULL;
        h2_c2_transit *transit = NULL;
    
        while (!m->aborted && !stream && (m->processing_count < m->processing_limit)
               && (sid = h2_iq_shift(m->q)) > 0) {
            stream = h2_ihash_get(m->streams, sid);
        }
    
        if (!stream) {
            if (m->processing_count >= m->processing_limit && !h2_iq_empty(m->q)) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c1,
                              H2_MPLX_MSG(m, "delaying request processing. "
                              "Current limit is %d and %d workers are in use."),
                              m->processing_limit, m->processing_count);
            }
            goto cleanup;
        }
    
        if (sid > m->max_stream_id_started) {
            m->max_stream_id_started = sid;
        }
    
        transit = c2_transit_get(m);
    #if AP_HAS_RESPONSE_BUCKETS
        c2 = ap_create_secondary_connection(transit->pool, m->c1, transit->bucket_alloc);
    #else
        c2 = h2_c2_create(m->c1, transit->pool, transit->bucket_alloc);
    #endif
        if (!c2) goto cleanup;
        ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, m->c1,
                      H2_STRM_MSG(stream, "created new c2"));
    
        rv = c2_setup_io(m, c2, stream, transit);
        if (APR_SUCCESS != rv) goto cleanup;
    
        stream->c2 = c2;
        ++m->processing_count;
    
    cleanup:
        if (APR_SUCCESS != rv && c2) {
            h2_c2_destroy(c2);
            c2 = NULL;
        }
        if (transit && !c2) {
            c2_transit_recycle(m, transit);
        }
        return c2;
    }
    
    static conn_rec *c2_prod_next(void *baton, int *phas_more)
    {
        h2_mplx *m = baton;
        conn_rec *c = NULL;
    
        H2_MPLX_ENTER_ALWAYS(m);
        if (!m->aborted) {
            c = s_next_c2(m);
            *phas_more = (c != NULL && !h2_iq_empty(m->q));
        }
        H2_MPLX_LEAVE(m);
        return c;
    }
    
    static void s_c2_done(h2_mplx *m, conn_rec *c2, h2_conn_ctx_t *conn_ctx)
    {
        h2_stream *stream;
    
        ap_assert(conn_ctx);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                      "h2_mplx(%s-%d): c2 done", conn_ctx->id, conn_ctx->stream_id);
    
        AP_DEBUG_ASSERT(apr_atomic_read32(&conn_ctx->done) == 0);
        apr_atomic_set32(&conn_ctx->done, 1);
        conn_ctx->done_at = apr_time_now();
        ++c2->keepalives;
        /* From here on, the final handling of c2 is done by c1 processing.
         * Which means we can give it c1's scoreboard handle for updates. */
        c2->sbh = m->c1->sbh;
    #if AP_MODULE_MAGIC_AT_LEAST(20211221, 29)
        ap_set_time_process_request(c2->sbh,conn_ctx->started_at,conn_ctx->done_at);
    #endif
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2,
                      "h2_mplx(%s-%d): request done, %f ms elapsed",
                      conn_ctx->id, conn_ctx->stream_id,
                      (conn_ctx->done_at - conn_ctx->started_at) / 1000.0);
        
        if (!conn_ctx->has_final_response) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, conn_ctx->last_err, c2,
                          "h2_c2(%s-%d): processing finished without final response",
                          conn_ctx->id, conn_ctx->stream_id);
            c2->aborted = 1;
            if (conn_ctx->beam_out)
              h2_beam_abort(conn_ctx->beam_out, c2);
        }
        else if (!conn_ctx->beam_out || !h2_beam_is_complete(conn_ctx->beam_out)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, conn_ctx->last_err, c2,
                          "h2_c2(%s-%d): processing finished with incomplete output",
                          conn_ctx->id, conn_ctx->stream_id);
            c2->aborted = 1;
            h2_beam_abort(conn_ctx->beam_out, c2);
        }
        else if (!c2->aborted) {
            s_mplx_be_happy(m, c2, conn_ctx);
        }
        
        stream = h2_ihash_get(m->streams, conn_ctx->stream_id);
        if (stream) {
            /* stream not done yet. trigger a potential polling on the output
             * since nothing more will happening here. */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2,
                          H2_STRM_MSG(stream, "c2_done, stream open"));
            c2_beam_output_write_notify(c2, NULL);
        }
        else if ((stream = h2_ihash_get(m->shold, conn_ctx->stream_id)) != NULL) {
            /* stream is done, was just waiting for this. */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2,
                          H2_STRM_MSG(stream, "c2_done, in hold"));
            c1c2_stream_joined(m, stream);
        }
        else {
            int i;
    
            for (i = 0; i < m->spurge->nelts; ++i) {
                if (stream == APR_ARRAY_IDX(m->spurge, i, h2_stream*)) {
                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c2,
                                  H2_STRM_LOG(APLOGNO(03517), stream, "already in spurge"));
                    ap_assert("stream should not be in spurge" == NULL);
                    return;
                }
            }
    
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c2, APLOGNO(03518)
                          "h2_mplx(%s-%d): c2_done, stream not found",
                          conn_ctx->id, conn_ctx->stream_id);
            ap_assert("stream should still be available" == NULL);
        }
    }
    
    static void c2_prod_done(void *baton, conn_rec *c2)
    {
        h2_mplx *m = baton;
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c2);
    
        AP_DEBUG_ASSERT(conn_ctx);
        H2_MPLX_ENTER_ALWAYS(m);
    
        --m->processing_count;
        s_c2_done(m, c2, conn_ctx);
        if (m->join_wait) apr_thread_cond_signal(m->join_wait);
    
        H2_MPLX_LEAVE(m);
    }
    
    static void workers_shutdown(void *baton, int graceful)
    {
        h2_mplx *m = baton;
    
        apr_thread_mutex_lock(m->poll_lock);
        /* time to wakeup and assess what to do */
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                      H2_MPLX_MSG(m, "workers shutdown, waking pollset"));
        m->shutdown = 1;
        if (!graceful) {
            m->aborted = 1;
        }
        apr_pollset_wakeup(m->pollset);
        apr_thread_mutex_unlock(m->poll_lock);
    }
    
    /*******************************************************************************
     * h2_mplx DoS protection
     ******************************************************************************/
    
    static void s_mplx_be_happy(h2_mplx *m, conn_rec *c, h2_conn_ctx_t *conn_ctx)
    {
        apr_time_t now;            
    
        if (m->processing_limit < m->processing_max
            && conn_ctx->started_at > m->last_mood_change) {
            --m->irritations_since;
            if (m->processing_limit < m->processing_max
                && ((now = apr_time_now()) - m->last_mood_change >= m->mood_update_interval
                    || m->irritations_since < -m->processing_limit)) {
                m->processing_limit = H2MIN(m->processing_limit * 2, m->processing_max);
                m->last_mood_change = now;
                m->irritations_since = 0;
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                              H2_MPLX_MSG(m, "mood update, increasing worker limit to %d"),
                              m->processing_limit);
            }
        }
    }
    
    static void m_be_annoyed(h2_mplx *m)
    {
        apr_time_t now;
    
        if (m->processing_limit > 2) {
            ++m->irritations_since;
            if (((now = apr_time_now()) - m->last_mood_change >= m->mood_update_interval)
                || (m->irritations_since >= m->processing_limit)) {
    
                if (m->processing_limit > 16) {
                    m->processing_limit = 16;
                }
                else if (m->processing_limit > 8) {
                    m->processing_limit = 8;
                }
                else if (m->processing_limit > 4) {
                    m->processing_limit = 4;
                }
                else if (m->processing_limit > 2) {
                    m->processing_limit = 2;
                }
                m->last_mood_change = now;
                m->irritations_since = 0;
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c1,
                              H2_MPLX_MSG(m, "mood update, decreasing worker limit to %d"),
                              m->processing_limit);
            }
        }
    }
    
    /*******************************************************************************
     * mplx master events dispatching
     ******************************************************************************/
    
    static int reset_is_acceptable(h2_stream *stream)
    {
        /* client may terminate a stream via H2 RST_STREAM message at any time.
         * This is annyoing when we have committed resources (e.g. worker threads)
         * to it, so our mood (e.g. willingness to commit resources on this
         * connection in the future) goes down.
         *
         * This is a DoS protection. We do not want to make it too easy for
         * a client to eat up server resources.
         *
         * However: there are cases where a RST_STREAM is the only way to end
         * a request. This includes websockets and server-side-event streams (SSEs).
         * The responses to such requests continue forever otherwise.
         *
         */
        if (!stream_is_running(stream)) return 1;
        if (!(stream->id & 0x01)) return 1; /* stream initiated by us. acceptable. */
        if (!stream->response) return 0; /* no response headers produced yet. bad. */
        if (!stream->out_data_frames) return 0; /* no response body data sent yet. bad. */
        return 1; /* otherwise, be forgiving */
    }
    
    apr_status_t h2_mplx_c1_client_rst(h2_mplx *m, int stream_id, h2_stream *stream)
    {
        apr_status_t status = APR_SUCCESS;
        int registered;
    
        H2_MPLX_ENTER_ALWAYS(m);
        registered = (h2_ihash_get(m->streams, stream_id) != NULL);
        if (!stream) {
          /* a RST might arrive so late, we have already forgotten
           * about it. Seems ok. */
          ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c1,
                        H2_MPLX_MSG(m, "RST on unknown stream %d"), stream_id);
          AP_DEBUG_ASSERT(!registered);
        }
        else if (!registered) {
          /* a RST on a stream that mplx has not been told about, but
           * which the session knows. Very early and annoying. */
          ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c1,
                        H2_STRM_MSG(stream, "very early RST, drop"));
          h2_stream_set_monitor(stream, NULL);
          h2_stream_rst(stream, H2_ERR_STREAM_CLOSED);
          h2_stream_dispatch(stream, H2_SEV_EOS_SENT);
          m_stream_cleanup(m, stream);
          m_be_annoyed(m);
        }
        else if (!reset_is_acceptable(stream)) {
            m_be_annoyed(m);
        }
        H2_MPLX_LEAVE(m);
        return status;
    }
    
    static apr_status_t mplx_pollset_create(h2_mplx *m)
    {
        /* stream0 output only */
        return apr_pollset_create(&m->pollset, 1, m->pool,
                                  APR_POLLSET_WAKEABLE);
    }
    
    static apr_status_t mplx_pollset_poll(h2_mplx *m, apr_interval_time_t timeout,
                                stream_ev_callback *on_stream_input,
                                stream_ev_callback *on_stream_output,
                                void *on_ctx)
    {
        apr_status_t rv;
        const apr_pollfd_t *results, *pfd;
        apr_int32_t nresults, i;
        h2_conn_ctx_t *conn_ctx;
        h2_stream *stream;
    
        /* Make sure we are not called recursively. */
        ap_assert(!m->polling);
        m->polling = 1;
        do {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                          H2_MPLX_MSG(m, "enter polling timeout=%d"),
                          (int)apr_time_sec(timeout));
    
            apr_array_clear(m->streams_ev_in);
            apr_array_clear(m->streams_ev_out);
    
            do {
                /* add streams we started processing in the meantime */
                apr_thread_mutex_lock(m->poll_lock);
                if (!h2_iq_empty(m->streams_input_read)
                    || !h2_iq_empty(m->streams_output_written)) {
                    while ((i = h2_iq_shift(m->streams_input_read))) {
                        stream = h2_ihash_get(m->streams, i);
                        if (stream) {
                            APR_ARRAY_PUSH(m->streams_ev_in, h2_stream*) = stream;
                        }
                    }
                    while ((i = h2_iq_shift(m->streams_output_written))) {
                        stream = h2_ihash_get(m->streams, i);
                        if (stream) {
                            APR_ARRAY_PUSH(m->streams_ev_out, h2_stream*) = stream;
                        }
                    }
                    nresults = 0;
                    rv = APR_SUCCESS;
                    apr_thread_mutex_unlock(m->poll_lock);
                    break;
                }
                apr_thread_mutex_unlock(m->poll_lock);
    
                H2_MPLX_LEAVE(m);
                rv = apr_pollset_poll(m->pollset, timeout >= 0? timeout : -1, &nresults, &results);
                H2_MPLX_ENTER_ALWAYS(m);
                if (APR_STATUS_IS_EINTR(rv) && m->shutdown) {
                    if (!m->aborted) {
                        rv = APR_SUCCESS;
                    }
                    goto cleanup;
                }
            } while (APR_STATUS_IS_EINTR(rv));
    
            if (APR_SUCCESS != rv) {
                if (APR_STATUS_IS_TIMEUP(rv)) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
                                  H2_MPLX_MSG(m, "polling timed out "));
                }
                else {
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, m->c1, APLOGNO(10310) \
                                  H2_MPLX_MSG(m, "polling failed"));
                }
                goto cleanup;
            }
    
            for (i = 0; i < nresults; i++) {
                pfd = &results[i];
                conn_ctx = pfd->client_data;
    
                AP_DEBUG_ASSERT(conn_ctx);
                if (conn_ctx->stream_id == 0) {
                    if (on_stream_input) {
                        APR_ARRAY_PUSH(m->streams_ev_in, h2_stream*) = m->stream0;
                    }
                    break;
                }
            }
    
            if (on_stream_input && m->streams_ev_in->nelts) {
                H2_MPLX_LEAVE(m);
                for (i = 0; i < m->streams_ev_in->nelts; ++i) {
                    on_stream_input(on_ctx, APR_ARRAY_IDX(m->streams_ev_in, i, h2_stream*));
                }
                H2_MPLX_ENTER_ALWAYS(m);
            }
            if (on_stream_output && m->streams_ev_out->nelts) {
                H2_MPLX_LEAVE(m);
                for (i = 0; i < m->streams_ev_out->nelts; ++i) {
                    on_stream_output(on_ctx, APR_ARRAY_IDX(m->streams_ev_out, i, h2_stream*));
                }
                H2_MPLX_ENTER_ALWAYS(m);
            }
            break;
        } while(1);
    
    cleanup:
        m->polling = 0;
        return rv;
    }
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_config.h��������������������������������������������������������������0000664�0001751�0001751�00000006406�15017523400�017345� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_config_h__
    #define __mod_h2__h2_config_h__
    
    #undef PACKAGE_VERSION
    #undef PACKAGE_TARNAME
    #undef PACKAGE_STRING
    #undef PACKAGE_NAME
    #undef PACKAGE_BUGREPORT
    
    typedef enum {
        H2_CONF_MAX_STREAMS,
        H2_CONF_WIN_SIZE,
        H2_CONF_MIN_WORKERS,
        H2_CONF_MAX_WORKERS,
        H2_CONF_MAX_WORKER_IDLE_LIMIT,
        H2_CONF_STREAM_MAX_MEM,
        H2_CONF_DIRECT,
        H2_CONF_MODERN_TLS_ONLY,
        H2_CONF_UPGRADE,
        H2_CONF_TLS_WARMUP_SIZE,
        H2_CONF_TLS_COOLDOWN_SECS,
        H2_CONF_PUSH,
        H2_CONF_PUSH_DIARY_SIZE,
        H2_CONF_COPY_FILES,
        H2_CONF_EARLY_HINTS,
        H2_CONF_PADDING_BITS,
        H2_CONF_PADDING_ALWAYS,
        H2_CONF_OUTPUT_BUFFER,
        H2_CONF_STREAM_TIMEOUT,
        H2_CONF_MAX_DATA_FRAME_LEN,
        H2_CONF_PROXY_REQUESTS,
        H2_CONF_WEBSOCKETS,
        H2_CONF_MAX_HEADER_BLOCK_LEN,
    } h2_config_var_t;
    
    struct apr_hash_t;
    struct h2_priority;
    struct h2_push_res;
    
    typedef struct h2_push_res {
        const char *uri_ref;
        int critical;
    } h2_push_res;
    
    
    void *h2_config_create_dir(apr_pool_t *pool, char *x);
    void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv);
    void *h2_config_create_svr(apr_pool_t *pool, server_rec *s);
    void *h2_config_merge_svr(apr_pool_t *pool, void *basev, void *addv);
    
    extern const command_rec h2_cmds[];
    
    int h2_config_geti(request_rec *r, server_rec *s, h2_config_var_t var);
    apr_int64_t h2_config_geti64(request_rec *r, server_rec *s, h2_config_var_t var);
    
    /** 
     * Get the configured value for variable <var> at the given connection.
     */
    int h2_config_cgeti(conn_rec *c, h2_config_var_t var);
    apr_int64_t h2_config_cgeti64(conn_rec *c, h2_config_var_t var);
    
    /** 
     * Get the configured value for variable <var> at the given server.
     */
    int h2_config_sgeti(server_rec *s, h2_config_var_t var);
    apr_int64_t h2_config_sgeti64(server_rec *s, h2_config_var_t var);
    
    /** 
     * Get the configured value for variable <var> at the given request,
     * if configured for the request location. 
     * Fallback to request server config otherwise.
     */
    int h2_config_rgeti(request_rec *r, h2_config_var_t var);
    apr_int64_t h2_config_rgeti64(request_rec *r, h2_config_var_t var);
    
    apr_array_header_t *h2_config_push_list(request_rec *r);
    apr_table_t *h2_config_early_headers(request_rec *r);
    
    
    void h2_get_workers_config(server_rec *s, int *pminw, int *pmaxw,
                               apr_time_t *pidle_limit);
    void h2_config_init(apr_pool_t *pool);
    
    const struct h2_priority *h2_cconfig_get_priority(conn_rec *c, const char *content_type);
           
    #endif /* __mod_h2__h2_config_h__ */
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c2.c������������������������������������������������������������������0000664�0001751�0001751�00000101361�14636331056�016405� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stddef.h>
    
    #include <apr_atomic.h>
    #include <apr_strings.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    #include <http_vhost.h>
    #include <util_filter.h>
    #include <ap_mmn.h>
    #include <ap_mpm.h>
    #include <mpm_common.h>
    #include <mod_core.h>
    #include <scoreboard.h>
    
    #include "h2_private.h"
    #include "h2.h"
    #include "h2_bucket_beam.h"
    #include "h2_c1.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_c2_filter.h"
    #include "h2_protocol.h"
    #include "h2_mplx.h"
    #include "h2_request.h"
    #include "h2_headers.h"
    #include "h2_session.h"
    #include "h2_stream.h"
    #include "h2_ws.h"
    #include "h2_c2.h"
    #include "h2_util.h"
    #include "mod_http2.h"
    
    
    static module *mpm_module;
    static int mpm_supported = 1;
    static apr_socket_t *dummy_socket;
    
    #if AP_HAS_RESPONSE_BUCKETS
    
    static ap_filter_rec_t *c2_net_in_filter_handle;
    static ap_filter_rec_t *c2_net_out_filter_handle;
    static ap_filter_rec_t *c2_request_in_filter_handle;
    static ap_filter_rec_t *c2_notes_out_filter_handle;
    
    #endif /* AP_HAS_RESPONSE_BUCKETS */
    
    static void check_modules(int force)
    {
        static int checked = 0;
        int i;
    
        if (force || !checked) {
            for (i = 0; ap_loaded_modules[i]; ++i) {
                module *m = ap_loaded_modules[i];
    
                if (!strcmp("event.c", m->name)) {
                    mpm_module = m;
                    break;
                }
                else if (!strcmp("motorz.c", m->name)) {
                    mpm_module = m;
                    break;
                }
                else if (!strcmp("mpm_netware.c", m->name)) {
                    mpm_module = m;
                    break;
                }
                else if (!strcmp("prefork.c", m->name)) {
                    mpm_module = m;
                    /* While http2 can work really well on prefork, it collides
                     * today's use case for prefork: running single-thread app engines
                     * like php. If we restrict h2_workers to 1 per process, php will
                     * work fine, but browser will be limited to 1 active request at a
                     * time. */
                    mpm_supported = 0;
                    break;
                }
                else if (!strcmp("simple_api.c", m->name)) {
                    mpm_module = m;
                    mpm_supported = 0;
                    break;
                }
                else if (!strcmp("mpm_winnt.c", m->name)) {
                    mpm_module = m;
                    break;
                }
                else if (!strcmp("worker.c", m->name)) {
                    mpm_module = m;
                    break;
                }
            }
            checked = 1;
        }
    }
    
    const char *h2_conn_mpm_name(void)
    {
        check_modules(0);
        return mpm_module? mpm_module->name : "unknown";
    }
    
    int h2_mpm_supported(void)
    {
        check_modules(0);
        return mpm_supported;
    }
    
    apr_status_t h2_c2_child_init(apr_pool_t *pool, server_rec *s)
    {
        check_modules(1);
        return apr_socket_create(&dummy_socket, APR_INET, SOCK_STREAM,
                                 APR_PROTO_TCP, pool);
    }
    
    static void h2_c2_log_io(conn_rec *c2, apr_off_t bytes_sent)
    {
        if (bytes_sent && h2_c_logio_add_bytes_out) {
            h2_c_logio_add_bytes_out(c2, bytes_sent);
        }
    }
    
    void h2_c2_destroy(conn_rec *c2)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c2);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c2,
                      "h2_c2(%s): destroy", c2->log_id);
        if(!c2->aborted && conn_ctx && conn_ctx->bytes_sent) {
          h2_c2_log_io(c2, conn_ctx->bytes_sent);
        }
        apr_pool_destroy(c2->pool);
    }
    
    void h2_c2_abort(conn_rec *c2, conn_rec *from)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c2);
    
        AP_DEBUG_ASSERT(conn_ctx);
        AP_DEBUG_ASSERT(conn_ctx->stream_id);
        if(!c2->aborted && conn_ctx->bytes_sent) {
          h2_c2_log_io(c2, conn_ctx->bytes_sent);
        }
    
        if (conn_ctx->beam_in) {
            h2_beam_abort(conn_ctx->beam_in, from);
        }
        if (conn_ctx->beam_out) {
            h2_beam_abort(conn_ctx->beam_out, from);
        }
        c2->aborted = 1;
    }
    
    typedef struct {
        apr_bucket_brigade *bb;       /* c2: data in holding area */
        unsigned did_upgrade_eos:1;   /* for Upgrade, we added an extra EOS */
    } h2_c2_fctx_in_t;
    
    static apr_status_t h2_c2_filter_in(ap_filter_t* f,
                                               apr_bucket_brigade* bb,
                                               ap_input_mode_t mode,
                                               apr_read_type_e block,
                                               apr_off_t readbytes)
    {
        h2_conn_ctx_t *conn_ctx;
        h2_c2_fctx_in_t *fctx = f->ctx;
        apr_status_t status = APR_SUCCESS;
        apr_bucket *b;
        apr_off_t bblen;
        apr_size_t rmax = (readbytes < APR_INT32_MAX)?
                           (apr_size_t)readbytes : APR_INT32_MAX;
        
        conn_ctx = h2_conn_ctx_get(f->c);
        AP_DEBUG_ASSERT(conn_ctx);
    
        if (mode == AP_MODE_INIT) {
            return ap_get_brigade(f->c->input_filters, bb, mode, block, readbytes);
        }
        
        if (f->c->aborted) {
            return APR_ECONNABORTED;
        }
        
        if (APLOGctrace3(f->c)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, f->c,
                          "h2_c2_in(%s-%d): read, mode=%d, block=%d, readbytes=%ld",
                          conn_ctx->id, conn_ctx->stream_id, mode, block,
                          (long)readbytes);
        }
    
        if (!fctx) {
            fctx = apr_pcalloc(f->c->pool, sizeof(*fctx));
            f->ctx = fctx;
            fctx->bb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
            if (!conn_ctx->beam_in) {
                b = apr_bucket_eos_create(f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(fctx->bb, b);
            }
        }
    
        /* If this is a HTTP Upgrade, it means the request we process
         * has not Content, although the stream is not necessarily closed.
         * On first read, we insert an EOS to signal processing that it
         * has the complete body. */
        if (conn_ctx->is_upgrade && !fctx->did_upgrade_eos) {
            b = apr_bucket_eos_create(f->c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(fctx->bb, b);
            fctx->did_upgrade_eos = 1;
        }
    
        while (APR_BRIGADE_EMPTY(fctx->bb)) {
            /* Get more input data for our request. */
            if (APLOGctrace2(f->c)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, f->c,
                              "h2_c2_in(%s-%d): get more data from mplx, block=%d, "
                              "readbytes=%ld",
                              conn_ctx->id, conn_ctx->stream_id, block, (long)readbytes);
            }
            if (conn_ctx->beam_in) {
                if (conn_ctx->pipe_in[H2_PIPE_OUT]) {
    receive:
                    status = h2_beam_receive(conn_ctx->beam_in, f->c, fctx->bb, APR_NONBLOCK_READ,
                                             conn_ctx->mplx->stream_max_mem);
                    if (APR_STATUS_IS_EAGAIN(status) && APR_BLOCK_READ == block) {
                        status = h2_util_wait_on_pipe(conn_ctx->pipe_in[H2_PIPE_OUT]);
                        if (APR_SUCCESS == status) {
                            goto receive;
                        }
                    }
                }
                else {
                    status = h2_beam_receive(conn_ctx->beam_in, f->c, fctx->bb, block,
                                             conn_ctx->mplx->stream_max_mem);
                }
            }
            else {
                status = APR_EOF;
            }
            
            if (APLOGctrace3(f->c)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, f->c,
                              "h2_c2_in(%s-%d): read returned",
                              conn_ctx->id, conn_ctx->stream_id);
            }
            if (APR_STATUS_IS_EAGAIN(status) 
                && (mode == AP_MODE_GETLINE || block == APR_BLOCK_READ)) {
                /* chunked input handling does not seem to like it if we
                 * return with APR_EAGAIN from a GETLINE read... 
                 * upload 100k test on test-ser.example.org hangs */
                status = APR_SUCCESS;
            }
            else if (APR_STATUS_IS_EOF(status)) {
                break;
            }
            else if (status != APR_SUCCESS) {
                conn_ctx->last_err = status;
                return status;
            }
    
            if (APLOGctrace3(f->c)) {
                h2_util_bb_log(f->c, conn_ctx->stream_id, APLOG_TRACE3,
                            "c2 input recv raw", fctx->bb);
            }
            if (h2_c_logio_add_bytes_in) {
                apr_brigade_length(bb, 0, &bblen);
                h2_c_logio_add_bytes_in(f->c, bblen);
            }
        }
        
        /* Nothing there, no more data to get. Return. */
        if (status == APR_EOF && APR_BRIGADE_EMPTY(fctx->bb)) {
            return status;
        }
    
        if (APLOGctrace3(f->c)) {
            h2_util_bb_log(f->c, conn_ctx->stream_id, APLOG_TRACE3,
                        "c2 input.bb", fctx->bb);
        }
               
        if (APR_BRIGADE_EMPTY(fctx->bb)) {
            if (APLOGctrace3(f->c)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, f->c,
                              "h2_c2_in(%s-%d): no data",
                              conn_ctx->id, conn_ctx->stream_id);
            }
            return (block == APR_NONBLOCK_READ)? APR_EAGAIN : APR_EOF;
        }
        
        if (mode == AP_MODE_EXHAUSTIVE) {
            /* return all we have */
            APR_BRIGADE_CONCAT(bb, fctx->bb);
        }
        else if (mode == AP_MODE_READBYTES) {
            status = h2_brigade_concat_length(bb, fctx->bb, rmax);
        }
        else if (mode == AP_MODE_SPECULATIVE) {
            status = h2_brigade_copy_length(bb, fctx->bb, rmax);
        }
        else if (mode == AP_MODE_GETLINE) {
            /* we are reading a single LF line, e.g. the HTTP headers. 
             * this has the nasty side effect to split the bucket, even
             * though it ends with CRLF and creates a 0 length bucket */
            status = apr_brigade_split_line(bb, fctx->bb, block,
                                            HUGE_STRING_LEN);
            if (APLOGctrace3(f->c)) {
                char buffer[1024];
                apr_size_t len = sizeof(buffer)-1;
                apr_brigade_flatten(bb, buffer, &len);
                buffer[len] = 0;
                ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, f->c,
                              "h2_c2_in(%s-%d): getline: %s",
                              conn_ctx->id, conn_ctx->stream_id, buffer);
            }
        }
        else {
            /* Hmm, well. There is mode AP_MODE_EATCRLF, but we chose not
             * to support it. Seems to work. */
            ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOTIMPL, f->c,
                          APLOGNO(03472) 
                          "h2_c2_in(%s-%d), unsupported READ mode %d",
                          conn_ctx->id, conn_ctx->stream_id, mode);
            status = APR_ENOTIMPL;
        }
        
        if (APLOGctrace3(f->c)) {
            apr_brigade_length(bb, 0, &bblen);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, f->c,
                          "h2_c2_in(%s-%d): %ld data bytes",
                          conn_ctx->id, conn_ctx->stream_id, (long)bblen);
        }
        return status;
    }
    
    static apr_status_t beam_out(conn_rec *c2, h2_conn_ctx_t *conn_ctx, apr_bucket_brigade* bb)
    {
        apr_off_t written = 0;
        apr_status_t rv;
    
        rv = h2_beam_send(conn_ctx->beam_out, c2, bb, APR_BLOCK_READ, &written);
        if (APR_STATUS_IS_EAGAIN(rv)) {
            rv = APR_SUCCESS;
        }
        return rv;
    }
    
    static apr_status_t h2_c2_filter_out(ap_filter_t* f, apr_bucket_brigade* bb)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
        apr_status_t rv;
    
       if (bb == NULL) {
    #if !AP_MODULE_MAGIC_AT_LEAST(20180720, 1)
            f->c->data_in_output_filters = 0;
    #endif
            return APR_SUCCESS;
        }
    
        ap_assert(conn_ctx);
    #if AP_HAS_RESPONSE_BUCKETS
        if (!conn_ctx->has_final_response) {
            apr_bucket *e;
    
            for (e = APR_BRIGADE_FIRST(bb);
                 e != APR_BRIGADE_SENTINEL(bb);
                 e = APR_BUCKET_NEXT(e))
            {
                if (AP_BUCKET_IS_RESPONSE(e)) {
                    ap_bucket_response *resp = e->data;
                    if (resp->status >= 200) {
                        conn_ctx->has_final_response = 1;
                        break;
                    }
                }
                if (APR_BUCKET_IS_EOS(e)) {
                    break;
                }
            }
        }
    #endif /* AP_HAS_RESPONSE_BUCKETS */
        rv = beam_out(f->c, conn_ctx, bb);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, f->c,
                      "h2_c2(%s-%d): output leave",
                      conn_ctx->id, conn_ctx->stream_id);
        if (APR_SUCCESS != rv) {
            h2_c2_abort(f->c, f->c);
        }
        return rv;
    }
    
    static int addn_headers(void *udata, const char *name, const char *value)
    {
        apr_table_t *dest = udata;
        apr_table_addn(dest, name, value);
        return 1;
    }
    
    static void check_early_hints(request_rec *r, const char *tag)
    {
        apr_array_header_t *push_list = h2_config_push_list(r);
        apr_table_t *early_headers = h2_config_early_headers(r);
    
        if (!r->expecting_100 &&
            ((push_list && push_list->nelts > 0) ||
             (early_headers && !apr_is_empty_table(early_headers)))) {
            int have_hints = 0, i;
    
            if (push_list && push_list->nelts > 0) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "%s, early announcing %d resources for push",
                              tag, push_list->nelts);
                for (i = 0; i < push_list->nelts; ++i) {
                    h2_push_res *push = &APR_ARRAY_IDX(push_list, i, h2_push_res);
                    apr_table_add(r->headers_out, "Link",
                                   apr_psprintf(r->pool, "<%s>; rel=preload%s",
                                                push->uri_ref, push->critical? "; critical" : ""));
                }
                have_hints = 1;
            }
            if (early_headers && !apr_is_empty_table(early_headers)) {
                apr_table_do(addn_headers, r->headers_out, early_headers, NULL);
                have_hints = 1;
            }
    
            if (have_hints) {
              int old_status;
              const char *old_line;
    
              if (h2_config_rgeti(r, H2_CONF_PUSH) == 0 &&
                  h2_config_sgeti(r->server, H2_CONF_PUSH) != 0) {
                  apr_table_setn(r->connection->notes, H2_PUSH_MODE_NOTE, "0");
              }
              old_status = r->status;
              old_line = r->status_line;
              r->status = 103;
              r->status_line = "103 Early Hints";
              ap_send_interim_response(r, 1);
              r->status = old_status;
              r->status_line = old_line;
            }
        }
    }
    
    static int c2_hook_fixups(request_rec *r)
    {
        conn_rec *c2 = r->connection;
        h2_conn_ctx_t *conn_ctx;
    
        if (!c2->master || !(conn_ctx = h2_conn_ctx_get(c2)) || !conn_ctx->stream_id) {
            return DECLINED;
        }
    
        check_early_hints(r, "late_fixup");
    
        return DECLINED;
    }
    
    static apr_status_t http2_get_pollfd_from_conn(conn_rec *c,
                                                   struct apr_pollfd_t *pfd,
                                                   apr_interval_time_t *ptimeout)
    {
    #if H2_USE_PIPES
        if (c->master) {
            h2_conn_ctx_t *ctx = h2_conn_ctx_get(c);
            if (ctx) {
                if (ctx->beam_in && ctx->pipe_in[H2_PIPE_OUT]) {
                    pfd->desc_type = APR_POLL_FILE;
                    pfd->desc.f = ctx->pipe_in[H2_PIPE_OUT];
                    if (ptimeout)
                        *ptimeout = h2_beam_timeout_get(ctx->beam_in);
                }
                else {
                    /* no input */
                    pfd->desc_type = APR_NO_DESC;
                    if (ptimeout)
                        *ptimeout = -1;
                }
                return APR_SUCCESS;
            }
        }
    #else
        (void)c;
        (void)pfd;
        (void)ptimeout;
    #endif /* H2_USE_PIPES */
        return APR_ENOTIMPL;
    }
    
    #if AP_HAS_RESPONSE_BUCKETS
    
    static void c2_pre_read_request(request_rec *r, conn_rec *c2)
    {
        h2_conn_ctx_t *conn_ctx;
    
        if (!c2->master || !(conn_ctx = h2_conn_ctx_get(c2)) || !conn_ctx->stream_id) {
            return;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                      "h2_c2(%s-%d): adding request filters",
                      conn_ctx->id, conn_ctx->stream_id);
        ap_add_input_filter_handle(c2_request_in_filter_handle, NULL, r, r->connection);
        ap_add_output_filter_handle(c2_notes_out_filter_handle, NULL, r, r->connection);
    }
    
    static int c2_post_read_request(request_rec *r)
    {
        h2_conn_ctx_t *conn_ctx;
        conn_rec *c2 = r->connection;
        apr_time_t timeout;
    
        if (!c2->master || !(conn_ctx = h2_conn_ctx_get(c2)) || !conn_ctx->stream_id) {
            return DECLINED;
        }
        /* Now that the request_rec is fully initialized, set relevant params */
        conn_ctx->server = r->server;
        timeout = h2_config_geti64(r, r->server, H2_CONF_STREAM_TIMEOUT);
        if (timeout <= 0) {
            timeout = r->server->timeout;
        }
        h2_conn_ctx_set_timeout(conn_ctx, timeout);
        /* We only handle this one request on the connection and tell everyone
         * that there is no need to keep it "clean" if something fails. Also,
         * this prevents mod_reqtimeout from doing funny business with monitoring
         * keepalive timeouts.
         */
        r->connection->keepalive = AP_CONN_CLOSE;
    
        if (conn_ctx->beam_in && !apr_table_get(r->headers_in, "Content-Length")) {
            r->body_indeterminate = 1;
        }
    
        if (h2_config_sgeti(conn_ctx->server, H2_CONF_COPY_FILES)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "h2_mplx(%s-%d): copy_files in output",
                          conn_ctx->id, conn_ctx->stream_id);
            h2_beam_set_copy_files(conn_ctx->beam_out, 1);
        }
    
        /* Add the raw bytes of the request (e.g. header frame lengths to
         * the logio for this request. */
        if (conn_ctx->request->raw_bytes && h2_c_logio_add_bytes_in) {
            h2_c_logio_add_bytes_in(c2, conn_ctx->request->raw_bytes);
        }
        return OK;
    }
    
    static int c2_hook_pre_connection(conn_rec *c2, void *csd)
    {
        h2_conn_ctx_t *conn_ctx;
    
        if (!c2->master || !(conn_ctx = h2_conn_ctx_get(c2)) || !conn_ctx->stream_id) {
            return DECLINED;
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2,
                      "h2_c2(%s-%d), adding filters",
                      conn_ctx->id, conn_ctx->stream_id);
        ap_add_input_filter_handle(c2_net_in_filter_handle, NULL, NULL, c2);
        ap_add_output_filter_handle(c2_net_out_filter_handle, NULL, NULL, c2);
        if (c2->keepalives == 0) {
            /* Simulate that we had already a request on this connection. Some
             * hooks trigger special behaviour when keepalives is 0.
             * (Not necessarily in pre_connection, but later. Set it here, so it
             * is in place.) */
            c2->keepalives = 1;
            /* We signal that this connection will be closed after the request.
             * Which is true in that sense that we throw away all traffic data
             * on this c2 connection after each requests. Although we might
             * reuse internal structures like memory pools.
             * The wanted effect of this is that httpd does not try to clean up
             * any dangling data on this connection when a request is done. Which
             * is unnecessary on a h2 stream.
             */
            c2->keepalive = AP_CONN_CLOSE;
        }
        return OK;
    }
    
    void h2_c2_register_hooks(void)
    {
        /* When the connection processing actually starts, we might
         * take over, if the connection is for a h2 stream.
         */
        ap_hook_pre_connection(c2_hook_pre_connection,
                               NULL, NULL, APR_HOOK_MIDDLE);
    
        /* We need to manipulate the standard HTTP/1.1 protocol filters and
         * install our own. This needs to be done very early. */
        ap_hook_pre_read_request(c2_pre_read_request, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_read_request(c2_post_read_request, NULL, NULL,
                                  APR_HOOK_REALLY_FIRST);
        ap_hook_fixups(c2_hook_fixups, NULL, NULL, APR_HOOK_LAST);
    #if H2_USE_POLLFD_FROM_CONN
        ap_hook_get_pollfd_from_conn(http2_get_pollfd_from_conn, NULL, NULL,
                                     APR_HOOK_MIDDLE);
    #endif
        APR_REGISTER_OPTIONAL_FN(http2_get_pollfd_from_conn);
    
        c2_net_in_filter_handle =
            ap_register_input_filter("H2_C2_NET_IN", h2_c2_filter_in,
                                     NULL, AP_FTYPE_NETWORK);
        c2_net_out_filter_handle =
            ap_register_output_filter("H2_C2_NET_OUT", h2_c2_filter_out,
                                      NULL, AP_FTYPE_NETWORK);
        c2_request_in_filter_handle =
            ap_register_input_filter("H2_C2_REQUEST_IN", h2_c2_filter_request_in,
                                     NULL, AP_FTYPE_PROTOCOL);
        c2_notes_out_filter_handle =
            ap_register_output_filter("H2_C2_NOTES_OUT", h2_c2_filter_notes_out,
                                      NULL, AP_FTYPE_PROTOCOL);
    }
    
    #else /* AP_HAS_RESPONSE_BUCKETS */
    
    static apr_status_t c2_run_pre_connection(conn_rec *c2, apr_socket_t *csd)
    {
        if (c2->keepalives == 0) {
            /* Simulate that we had already a request on this connection. Some
             * hooks trigger special behaviour when keepalives is 0.
             * (Not necessarily in pre_connection, but later. Set it here, so it
             * is in place.) */
            c2->keepalives = 1;
            /* We signal that this connection will be closed after the request.
             * Which is true in that sense that we throw away all traffic data
             * on this c2 connection after each requests. Although we might
             * reuse internal structures like memory pools.
             * The wanted effect of this is that httpd does not try to clean up
             * any dangling data on this connection when a request is done. Which
             * is unnecessary on a h2 stream.
             */
            c2->keepalive = AP_CONN_CLOSE;
            return ap_run_pre_connection(c2, csd);
        }
        ap_assert(c2->output_filters);
        return APR_SUCCESS;
    }
    
    apr_status_t h2_c2_process(conn_rec *c2, apr_thread_t *thread, int worker_id)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c2);
    
        ap_assert(conn_ctx);
        ap_assert(conn_ctx->mplx);
    
        /* See the discussion at <https://github.com/icing/mod_h2/issues/195>
         *
         * Each conn_rec->id is supposed to be unique at a point in time. Since
         * some modules (and maybe external code) uses this id as an identifier
         * for the request_rec they handle, it needs to be unique for secondary
         * connections also.
         *
         * The MPM module assigns the connection ids and mod_unique_id is using
         * that one to generate identifier for requests. While the implementation
         * works for HTTP/1.x, the parallel execution of several requests per
         * connection will generate duplicate identifiers on load.
         *
         * The original implementation for secondary connection identifiers used
         * to shift the master connection id up and assign the stream id to the
         * lower bits. This was cramped on 32 bit systems, but on 64bit there was
         * enough space.
         *
         * As issue 195 showed, mod_unique_id only uses the lower 32 bit of the
         * connection id, even on 64bit systems. Therefore collisions in request ids.
         *
         * The way master connection ids are generated, there is some space "at the
         * top" of the lower 32 bits on allmost all systems. If you have a setup
         * with 64k threads per child and 255 child processes, you live on the edge.
         *
         * The new implementation shifts 8 bits and XORs in the worker
         * id. This will experience collisions with > 256 h2 workers and heavy
         * load still. There seems to be no way to solve this in all possible
         * configurations by mod_h2 alone.
         */
        c2->id = (c2->master->id << 8)^worker_id;
    
        if (!conn_ctx->pre_conn_done) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2,
                          "h2_c2(%s-%d), adding filters",
                          conn_ctx->id, conn_ctx->stream_id);
            ap_add_input_filter("H2_C2_NET_IN", NULL, NULL, c2);
            ap_add_output_filter("H2_C2_NET_CATCH_H1", NULL, NULL, c2);
            ap_add_output_filter("H2_C2_NET_OUT", NULL, NULL, c2);
    
            c2_run_pre_connection(c2, ap_get_conn_socket(c2));
            conn_ctx->pre_conn_done = 1;
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                      "h2_c2(%s-%d): process connection",
                      conn_ctx->id, conn_ctx->stream_id);
    
        c2->current_thread = thread;
        ap_run_process_connection(c2);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2,
                      "h2_c2(%s-%d): processing done",
                      conn_ctx->id, conn_ctx->stream_id);
    
        return APR_SUCCESS;
    }
    
    static apr_status_t c2_process(h2_conn_ctx_t *conn_ctx, conn_rec *c)
    {
        const h2_request *req = conn_ctx->request;
        conn_state_t *cs = c->cs;
        request_rec *r = NULL;
        const char *tenc;
        apr_time_t timeout;
        apr_status_t rv = APR_SUCCESS;
    
        if (req->protocol && !strcmp("websocket", req->protocol)) {
            req = h2_ws_rewrite_request(req, c, conn_ctx->beam_in == NULL);
            if (!req) {
                rv = APR_EGENERAL;
                goto cleanup;
            }
        }
    
        r = h2_create_request_rec(req, c, conn_ctx->beam_in == NULL);
    
        if (!r) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "h2_c2(%s-%d): create request_rec failed, r=NULL",
                          conn_ctx->id, conn_ctx->stream_id);
            goto cleanup;
        }
        if (r->status != HTTP_OK) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "h2_c2(%s-%d): create request_rec failed, r->status=%d",
                          conn_ctx->id, conn_ctx->stream_id, r->status);
            goto cleanup;
        }
    
        tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
        conn_ctx->input_chunked = tenc && ap_is_chunked(r->pool, tenc);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                      "h2_c2(%s-%d): created request_rec for %s",
                      conn_ctx->id, conn_ctx->stream_id, r->the_request);
        conn_ctx->server = r->server;
        timeout = h2_config_geti64(r, r->server, H2_CONF_STREAM_TIMEOUT);
        if (timeout <= 0) {
            timeout = r->server->timeout;
        }
        h2_conn_ctx_set_timeout(conn_ctx, timeout);
    
        if (h2_config_sgeti(conn_ctx->server, H2_CONF_COPY_FILES)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "h2_mplx(%s-%d): copy_files in output",
                          conn_ctx->id, conn_ctx->stream_id);
            h2_beam_set_copy_files(conn_ctx->beam_out, 1);
        }
    
        ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
        if (cs) {
            cs->state = CONN_STATE_HANDLER;
        }
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                      "h2_c2(%s-%d): start process_request",
                      conn_ctx->id, conn_ctx->stream_id);
    
        /* Add the raw bytes of the request (e.g. header frame lengths to
         * the logio for this request. */
        if (req->raw_bytes && h2_c_logio_add_bytes_in) {
            h2_c_logio_add_bytes_in(c, req->raw_bytes);
        }
    
        ap_process_request(r);
        /* After the call to ap_process_request, the
         * request pool may have been deleted. */
        r = NULL;
        if (conn_ctx->beam_out) {
            h2_beam_close(conn_ctx->beam_out, c);
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                      "h2_c2(%s-%d): process_request done",
                      conn_ctx->id, conn_ctx->stream_id);
        if (cs)
            cs->state = CONN_STATE_WRITE_COMPLETION;
    
    cleanup:
        return rv;
    }
    
    conn_rec *h2_c2_create(conn_rec *c1, apr_pool_t *parent,
                           apr_bucket_alloc_t *buckt_alloc)
    {
        apr_pool_t *pool;
        conn_rec *c2;
        void *cfg;
    
        ap_assert(c1);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c1,
                      "h2_c2: create for c1(%ld)", c1->id);
    
        /* We create a pool with its own allocator to be used for
         * processing a request. This is the only way to have the processing
         * independent of its parent pool in the sense that it can work in
         * another thread.
         */
        apr_pool_create(&pool, parent);
        apr_pool_tag(pool, "h2_c2_conn");
    
        c2 = (conn_rec *) apr_palloc(pool, sizeof(conn_rec));
        memcpy(c2, c1, sizeof(conn_rec));
    
        c2->master                 = c1;
        c2->pool                   = pool;
        c2->conn_config            = ap_create_conn_config(pool);
        c2->notes                  = apr_table_make(pool, 5);
        c2->input_filters          = NULL;
        c2->output_filters         = NULL;
        c2->keepalives             = 0;
    #if AP_MODULE_MAGIC_AT_LEAST(20180903, 1)
        c2->filter_conn_ctx        = NULL;
    #endif
        c2->bucket_alloc           = apr_bucket_alloc_create(pool);
    #if !AP_MODULE_MAGIC_AT_LEAST(20180720, 1)
        c2->data_in_input_filters  = 0;
        c2->data_in_output_filters = 0;
    #endif
        /* prevent mpm_event from making wrong assumptions about this connection,
         * like e.g. using its socket for an async read check. */
        c2->clogging_input_filters = 1;
        c2->log                    = NULL;
        c2->aborted                = 0;
        /* We cannot install the master connection socket on the secondary, as
         * modules mess with timeouts/blocking of the socket, with
         * unwanted side effects to the master connection processing.
         * Fortunately, since we never use the secondary socket, we can just install
         * a single, process-wide dummy and everyone is happy.
         */
        ap_set_module_config(c2->conn_config, &core_module, dummy_socket);
        /* TODO: these should be unique to this thread */
        c2->sbh = NULL; /*c1->sbh;*/
        /* TODO: not all mpm modules have learned about secondary connections yet.
         * copy their config from master to secondary.
         */
        if (mpm_module) {
            cfg = ap_get_module_config(c1->conn_config, mpm_module);
            ap_set_module_config(c2->conn_config, mpm_module, cfg);
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c2,
                      "h2_c2(%s): created", c2->log_id);
        return c2;
    }
    
    static int h2_c2_hook_post_read_request(request_rec *r)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(r->connection);
    
        if (conn_ctx && conn_ctx->stream_id && ap_is_initial_req(r)) {
    
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "h2_c2(%s-%d): adding request filters",
                          conn_ctx->id, conn_ctx->stream_id);
    
            /* setup the correct filters to process the request for h2 */
            ap_add_input_filter("H2_C2_REQUEST_IN", NULL, r, r->connection);
    
            /* replace the core http filter that formats response headers
             * in HTTP/1 with our own that collects status and headers */
            ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
    
            ap_add_output_filter("H2_C2_RESPONSE_OUT", NULL, r, r->connection);
            ap_add_output_filter("H2_C2_TRAILERS_OUT", NULL, r, r->connection);
        }
        return DECLINED;
    }
    
    static int h2_c2_hook_process(conn_rec* c)
    {
        h2_conn_ctx_t *ctx;
    
        if (!c->master) {
            return DECLINED;
        }
    
        ctx = h2_conn_ctx_get(c);
        if (ctx->stream_id) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "h2_h2, processing request directly");
            c2_process(ctx, c);
            return DONE;
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                          "secondary_conn(%ld): no h2 stream assing?", c->id);
        }
        return DECLINED;
    }
    
    void h2_c2_register_hooks(void)
    {
        /* When the connection processing actually starts, we might
         * take over, if the connection is for a h2 stream.
         */
        ap_hook_process_connection(h2_c2_hook_process,
                                   NULL, NULL, APR_HOOK_FIRST);
        /* We need to manipulate the standard HTTP/1.1 protocol filters and
         * install our own. This needs to be done very early. */
        ap_hook_post_read_request(h2_c2_hook_post_read_request, NULL, NULL, APR_HOOK_REALLY_FIRST);
        ap_hook_fixups(c2_hook_fixups, NULL, NULL, APR_HOOK_LAST);
    #if H2_USE_POLLFD_FROM_CONN
        ap_hook_get_pollfd_from_conn(http2_get_pollfd_from_conn, NULL, NULL,
                                     APR_HOOK_MIDDLE);
    #endif
        APR_REGISTER_OPTIONAL_FN(http2_get_pollfd_from_conn);
    
        ap_register_input_filter("H2_C2_NET_IN", h2_c2_filter_in,
                                 NULL, AP_FTYPE_NETWORK);
        ap_register_output_filter("H2_C2_NET_OUT", h2_c2_filter_out,
                                  NULL, AP_FTYPE_NETWORK);
        ap_register_output_filter("H2_C2_NET_CATCH_H1", h2_c2_filter_catch_h1_out,
                                  NULL, AP_FTYPE_NETWORK);
    
        ap_register_input_filter("H2_C2_REQUEST_IN", h2_c2_filter_request_in,
                                 NULL, AP_FTYPE_PROTOCOL);
        ap_register_output_filter("H2_C2_RESPONSE_OUT", h2_c2_filter_response_out,
                                  NULL, AP_FTYPE_PROTOCOL);
        ap_register_output_filter("H2_C2_TRAILERS_OUT", h2_c2_filter_trailers_out,
                                  NULL, AP_FTYPE_PROTOCOL);
    }
    
    #endif /* else AP_HAS_RESPONSE_BUCKETS */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/config2.m4���������������������������������������������������������������0000664�0001751�0001751�00000022161�14473316336�017140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl Licensed to the Apache Software Foundation (ASF) under one or more
    dnl contributor license agreements.  See the NOTICE file distributed with
    dnl this work for additional information regarding copyright ownership.
    dnl The ASF licenses this file to You under the Apache License, Version 2.0
    dnl (the "License"); you may not use this file except in compliance with
    dnl the License.  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.
    
    dnl #  start of module specific part
    APACHE_MODPATH_INIT(http2)
    
    dnl #  list of module object files
    http2_objs="dnl
    mod_http2.lo dnl
    h2_bucket_beam.lo dnl
    h2_bucket_eos.lo dnl
    h2_c1.lo dnl
    h2_c1_io.lo dnl
    h2_c2.lo dnl
    h2_c2_filter.lo dnl
    h2_config.lo dnl
    h2_conn_ctx.lo dnl
    h2_headers.lo dnl
    h2_mplx.lo dnl
    h2_protocol.lo dnl
    h2_push.lo dnl
    h2_request.lo dnl
    h2_session.lo dnl
    h2_stream.lo dnl
    h2_switch.lo dnl
    h2_util.lo dnl
    h2_workers.lo dnl
    h2_ws.lo dnl
    "
    
    dnl
    dnl APACHE_CHECK_NGHTTP2
    dnl
    dnl Configure for nghttp2, giving preference to
    dnl "--with-nghttp2=<path>" if it was specified.
    dnl
    AC_DEFUN([APACHE_CHECK_NGHTTP2],[
      AC_CACHE_CHECK([for nghttp2], [ac_cv_nghttp2], [
        dnl initialise the variables we use
        ac_cv_nghttp2=no
        ap_nghttp2_found=""
        ap_nghttp2_base=""
        ap_nghttp2_libs=""
    
        dnl Determine the nghttp2 base directory, if any
        AC_MSG_CHECKING([for user-provided nghttp2 base directory])
        AC_ARG_WITH(nghttp2, APACHE_HELP_STRING(--with-nghttp2=PATH, nghttp2 installation directory), [
          dnl If --with-nghttp2 specifies a directory, we use that directory
          if test "x$withval" != "xyes" -a "x$withval" != "x"; then
            dnl This ensures $withval is actually a directory and that it is absolute
            ap_nghttp2_base="`cd $withval ; pwd`"
          fi
        ])
        if test "x$ap_nghttp2_base" = "x"; then
          AC_MSG_RESULT(none)
        else
          AC_MSG_RESULT($ap_nghttp2_base)
        fi
    
        dnl Run header and version checks
        saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
        dnl Before doing anything else, load in pkg-config variables
        if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          AC_MSG_CHECKING([for pkg-config along $PKG_CONFIG_PATH])
          if test "x$ap_nghttp2_base" != "x" ; then
            if test -f "${ap_nghttp2_base}/lib/pkgconfig/libnghttp2.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system libnghttp2.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_nghttp2_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_nghttp2_base}/lib64/pkgconfig/libnghttp2.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system libnghttp2.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_nghttp2_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          AC_ARG_ENABLE(nghttp2-staticlib-deps,APACHE_HELP_STRING(--enable-nghttp2-staticlib-deps,[link mod_http2 with dependencies of libnghttp2's static libraries (as indicated by "pkg-config --static"). Must be specified in addition to --enable-http2.]), [
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
          ])
          ap_nghttp2_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libnghttp2`"
          if test $? -eq 0; then
            ap_nghttp2_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I libnghttp2`"
            APR_ADDTO(CPPFLAGS, [$pkglookup])
            APR_ADDTO(MOD_CFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libnghttp2`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libnghttp2`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
        dnl fall back to the user-supplied directory if not found via pkg-config
        if test "x$ap_nghttp2_base" != "x" -a "x$ap_nghttp2_found" = "x"; then
          APR_ADDTO(CPPFLAGS, [-I$ap_nghttp2_base/include])
          APR_ADDTO(MOD_CFLAGS, [-I$ap_nghttp2_base/include])
          APR_ADDTO(LDFLAGS, [-L$ap_nghttp2_base/lib])
          APR_ADDTO(MOD_LDFLAGS, [-L$ap_nghttp2_base/lib])
          if test "x$ap_platform_runtime_link_flag" != "x"; then
            APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_nghttp2_base/lib])
            APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_nghttp2_base/lib])
          fi
        fi
    
        AC_MSG_CHECKING([for nghttp2 version >= 1.2.1])
        AC_TRY_COMPILE([#include <nghttp2/nghttp2ver.h>],[
    #if !defined(NGHTTP2_VERSION_NUM)
    #error "Missing nghttp2 version"
    #endif
    #if NGHTTP2_VERSION_NUM < 0x010201
    #error "Unsupported nghttp2 version " NGHTTP2_VERSION_TEXT
    #endif],
          [AC_MSG_RESULT(OK)
           ac_cv_nghttp2=yes],
          [AC_MSG_RESULT(FAILED)])
    
        if test "x$ac_cv_nghttp2" = "xyes"; then
          ap_nghttp2_libs="${ap_nghttp2_libs:--lnghttp2} `$apr_config --libs`"
          APR_ADDTO(MOD_LDFLAGS, [$ap_nghttp2_libs])
          APR_ADDTO(LIBS, [$ap_nghttp2_libs])
    
          dnl Run library and function checks
          liberrors=""
          AC_CHECK_HEADERS([nghttp2/nghttp2.h])
          AC_CHECK_FUNCS([nghttp2_session_server_new2], [], [liberrors="yes"])
          if test "x$liberrors" != "x"; then
            AC_MSG_WARN([nghttp2 library is unusable])
          fi
    dnl # nghttp2 >= 1.3.0: access to stream weights
          AC_CHECK_FUNCS([nghttp2_stream_get_weight], [], [liberrors="yes"])
          if test "x$liberrors" != "x"; then
            AC_MSG_WARN([nghttp2 version >= 1.3.0 is required])
          fi
    dnl # nghttp2 >= 1.5.0: changing stream priorities
          AC_CHECK_FUNCS([nghttp2_session_change_stream_priority], 
            [APR_ADDTO(MOD_CPPFLAGS, ["-DH2_NG2_CHANGE_PRIO"])], [])
    dnl # nghttp2 >= 1.14.0: invalid header callback
          AC_CHECK_FUNCS([nghttp2_session_callbacks_set_on_invalid_header_callback], 
            [APR_ADDTO(MOD_CPPFLAGS, ["-DH2_NG2_INVALID_HEADER_CB"])], [])
    dnl # nghttp2 >= 1.15.0: get/set stream window sizes
          AC_CHECK_FUNCS([nghttp2_session_get_stream_local_window_size], 
            [APR_ADDTO(MOD_CPPFLAGS, ["-DH2_NG2_LOCAL_WIN_SIZE"])], [])
    dnl # nghttp2 >= 1.15.0: don't keep info on closed streams
          AC_CHECK_FUNCS([nghttp2_option_set_no_closed_streams],
            [APR_ADDTO(MOD_CPPFLAGS, ["-DH2_NG2_NO_CLOSED_STREAMS"])], [])
    dnl # nghttp2 >= 1.50.0: rfc9113 leading/trailing whitespec strictness
          AC_CHECK_FUNCS([nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation],
            [APR_ADDTO(MOD_CPPFLAGS, ["-DH2_NG2_RFC9113_STRICTNESS"])], [])
        else
          AC_MSG_WARN([nghttp2 version is too old])
        fi
    
        dnl restore
        CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
      ])
      if test "x$ac_cv_nghttp2" = "xyes"; then
        AC_DEFINE(HAVE_NGHTTP2, 1, [Define if nghttp2 is available])
      fi
    ])
    
    
    dnl # hook module into the Autoconf mechanism (--enable-http2)
    APACHE_MODULE(http2, [HTTP/2 protocol handling in addition to HTTP protocol 
    handling. Implemented by mod_http2. This module requires a libnghttp2 installation. 
    See --with-nghttp2 on how to manage non-standard locations. This module
    is usually linked shared and requires loading. ], $http2_objs, , most, [
        APACHE_CHECK_OPENSSL
        if test "$ac_cv_openssl" = "yes" ; then
            APR_ADDTO(MOD_CPPFLAGS, ["-DH2_OPENSSL"])
        fi
    
        APACHE_CHECK_NGHTTP2
        if test "$ac_cv_nghttp2" = "yes" ; then
            if test "x$enable_http2" = "xshared"; then
               # The only symbol which needs to be exported is the module
               # structure, so ask libtool to hide everything else:
               APR_ADDTO(MOD_HTTP2_LDADD, [-export-symbols-regex http2_module])
            fi
        else
            enable_http2=no
        fi
    ])
    
    # Ensure that other modules can pick up mod_http2.h
    # icing: hold back for now until it is more stable
    #APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    
    
    dnl #  list of module object files
    proxy_http2_objs="dnl
    mod_proxy_http2.lo dnl
    h2_proxy_session.lo dnl
    h2_proxy_util.lo dnl
    "
    
    dnl # hook module into the Autoconf mechanism (--enable-proxy_http2)
    APACHE_MODULE(proxy_http2, [HTTP/2 proxy module. This module requires a libnghttp2 installation. 
    See --with-nghttp2 on how to manage non-standard locations. Also requires --enable-proxy.], $proxy_http2_objs, , no, [
        APACHE_CHECK_NGHTTP2
        if test "$ac_cv_nghttp2" = "yes" ; then
            if test "x$enable_http2" = "xshared"; then
               # The only symbol which needs to be exported is the module
               # structure, so ask libtool to hide everything else:
               APR_ADDTO(MOD_PROXY_HTTP2_LDADD, [-export-symbols-regex proxy_http2_module])
            fi
        else
            enable_proxy_http2=no
        fi
    ], proxy)
    
    
    dnl #  end of module specific part
    APACHE_MODPATH_FINISH
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c2_filter.c�����������������������������������������������������������0000664�0001751�0001751�00000115422�14473316336�017760� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <stdio.h>
    
    #include <apr_date.h>
    #include <apr_lib.h>
    #include <apr_strings.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <util_time.h>
    
    #include "h2_private.h"
    #include "h2.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_headers.h"
    #include "h2_c1.h"
    #include "h2_c2_filter.h"
    #include "h2_c2.h"
    #include "h2_mplx.h"
    #include "h2_request.h"
    #include "h2_ws.h"
    #include "h2_util.h"
    
    
    #if AP_HAS_RESPONSE_BUCKETS
    
    apr_status_t h2_c2_filter_notes_out(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        apr_bucket *b;
        request_rec *r_prev;
        ap_bucket_response *resp;
        const char *err;
    
        if (!f->r) {
            goto pass;
        }
    
        for (b = APR_BRIGADE_FIRST(bb);
             b != APR_BRIGADE_SENTINEL(bb);
             b = APR_BUCKET_NEXT(b))
        {
            if (AP_BUCKET_IS_RESPONSE(b)) {
                resp = b->data;
                if (resp->status >= 400 && f->r->prev) {
                    /* Error responses are commonly handled via internal
                     * redirects to error documents. That creates a new
                     * request_rec with 'prev' set to the original.
                     * Each of these has its onw 'notes'.
                     * We'd like to copy interesting ones into the current 'r->notes'
                     * as we reset HTTP/2 stream with H2 specific error codes then.
                     */
                    for (r_prev = f->r; r_prev != NULL; r_prev = r_prev->prev) {
                        if ((err = apr_table_get(r_prev->notes, "ssl-renegotiate-forbidden"))) {
                            if (r_prev != f->r) {
                                apr_table_setn(resp->notes, "ssl-renegotiate-forbidden", err);
                            }
                            break;
                        }
                    }
                }
                else if (h2_config_rgeti(f->r, H2_CONF_PUSH) == 0
                         && h2_config_sgeti(f->r->server, H2_CONF_PUSH) != 0) {
                    /* location configuration turns off H2 PUSH handling */
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, f->c,
                                  "h2_c2_filter_notes_out, turning PUSH off");
                    apr_table_setn(resp->notes, H2_PUSH_MODE_NOTE, "0");
                }
            }
        }
    pass:
        return ap_pass_brigade(f->next, bb);
    }
    
    apr_status_t h2_c2_filter_request_in(ap_filter_t *f,
                                         apr_bucket_brigade *bb,
                                         ap_input_mode_t mode,
                                         apr_read_type_e block,
                                         apr_off_t readbytes)
    {
        h2_conn_ctx_t *conn_ctx;
        apr_bucket *b;
    
        /* just get out of the way for things we don't want to handle. */
        if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
            return ap_get_brigade(f->next, bb, mode, block, readbytes);
        }
    
        /* This filter is a one-time wonder */
        ap_remove_input_filter(f);
    
        if (f->c->master && (conn_ctx = h2_conn_ctx_get(f->c)) &&
            conn_ctx->stream_id) {
            const h2_request *req = conn_ctx->request;
    
            if (req->http_status == H2_HTTP_STATUS_UNSET &&
                req->protocol && !strcmp("websocket", req->protocol)) {
                req = h2_ws_rewrite_request(req, f->c, conn_ctx->beam_in == NULL);
                if (!req)
                    return APR_EGENERAL;
            }
    
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, f->c,
                          "h2_c2_filter_request_in(%s): adding request bucket",
                          conn_ctx->id);
            b = h2_request_create_bucket(req, f->r);
            APR_BRIGADE_INSERT_TAIL(bb, b);
    
            if (req->http_status != H2_HTTP_STATUS_UNSET) {
                /* error was encountered preparing this request */
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, f->c,
                              "h2_c2_filter_request_in(%s): adding error bucket %d",
                              conn_ctx->id, req->http_status);
                b = ap_bucket_error_create(req->http_status, NULL, f->r->pool,
                                           f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, b);
                return APR_SUCCESS;
            }
    
            if (!conn_ctx->beam_in) {
                b = apr_bucket_eos_create(f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, b);
            }
    
            return APR_SUCCESS;
        }
    
        return ap_get_brigade(f->next, bb, mode, block, readbytes);
    }
    
    #else /* AP_HAS_RESPONSE_BUCKETS */
    
    #define H2_FILTER_LOG(name, c, level, rv, msg, bb) \
        do { \
            if (APLOG_C_IS_LEVEL((c),(level))) { \
                char buffer[4 * 1024]; \
                apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \
                len = h2_util_bb_print(buffer, bmax, "", "", (bb)); \
                ap_log_cerror(APLOG_MARK, (level), rv, (c), \
                              "FILTER[%s]: %s %s", \
                              (name), (msg), len? buffer : ""); \
            } \
        } while (0)
    
    
    /* 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;
    
        (void)key;
        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 && apr_strnatcasecmp(*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 fix_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(uniq_field_values, 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, ','));
        }
    }
    
    static h2_headers *create_response(request_rec *r)
    {
        const char *clheader;
        const char *ctype;
    
        /*
         * 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);
            apr_table_clear(r->err_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.
         */
        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_setn(r->subprocess_env, "force-response-1.0", "1");
        }
        else {
            fix_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. */
        ap_set_keepalive(r);
    
        if (AP_STATUS_IS_HEADER_ONLY(r->status)) {
            apr_table_unset(r->headers_out, "Transfer-Encoding");
            apr_table_unset(r->headers_out, "Content-Length");
            r->content_type = r->content_encoding = NULL;
            r->content_languages = NULL;
            r->clength = r->chunked = 0;
        }
        else if (r->chunked) {
            apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
            apr_table_unset(r->headers_out, "Content-Length");
        }
    
        ctype = ap_make_content_type(r, r->content_type);
        if (ctype) {
            apr_table_setn(r->headers_out, "Content-Type", ctype);
        }
    
        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 *token;
            char **languages = (char **)(r->content_languages->elts);
            const char *field = apr_table_get(r->headers_out, "Content-Language");
    
            while (field && (token = ap_get_list_item(r->pool, &field)) != NULL) {
                for (i = 0; i < r->content_languages->nelts; ++i) {
                    if (!apr_strnatcasecmp(token, languages[i]))
                        break;
                }
                if (i == r->content_languages->nelts) {
                    *((char **) apr_array_push(r->content_languages)) = token;
                }
            }
    
            field = apr_array_pstrcat(r->pool, r->content_languages, ',');
            apr_table_setn(r->headers_out, "Content-Language", field);
        }
    
        /*
         * 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_add(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");
        }
    
        /*
         * keep the set-by-proxy server and date headers, otherwise
         * generate a new server header / date header
         */
        if (r->proxyreq == PROXYREQ_NONE
            || !apr_table_get(r->headers_out, "Date")) {
            char *date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
            ap_recent_rfc822_date(date, r->request_time);
            apr_table_setn(r->headers_out, "Date", date );
        }
        if (r->proxyreq == PROXYREQ_NONE
            || !apr_table_get(r->headers_out, "Server")) {
            const char *us = ap_get_server_banner();
            if (us && *us) {
                apr_table_setn(r->headers_out, "Server", us);
            }
        }
    
        return h2_headers_rcreate(r, r->status, r->headers_out, r->pool);
    }
    
    typedef enum {
        H2_RP_STATUS_LINE,
        H2_RP_HEADER_LINE,
        H2_RP_DONE
    } h2_rp_state_t;
    
    typedef struct h2_response_parser h2_response_parser;
    struct h2_response_parser {
        const char *id;
        h2_rp_state_t state;
        conn_rec *c;
        apr_pool_t *pool;
        int http_status;
        apr_array_header_t *hlines;
        apr_bucket_brigade *tmp;
        apr_bucket_brigade *saveto;
    };
    
    static apr_status_t parse_header(h2_response_parser *parser, char *line) {
        const char *hline;
        if (line[0] == ' ' || line[0] == '\t') {
            char **plast;
            /* continuation line from the header before this */
            while (line[0] == ' ' || line[0] == '\t') {
                ++line;
            }
    
            plast = apr_array_pop(parser->hlines);
            if (plast == NULL) {
                /* not well formed */
                return APR_EINVAL;
            }
            hline = apr_psprintf(parser->pool, "%s %s", *plast, line);
        }
        else {
            /* new header line */
            hline = apr_pstrdup(parser->pool, line);
        }
        APR_ARRAY_PUSH(parser->hlines, const char*) = hline;
        return APR_SUCCESS;
    }
    
    static apr_status_t get_line(h2_response_parser *parser, apr_bucket_brigade *bb,
                                 char *line, apr_size_t len)
    {
        apr_status_t status;
    
        if (!parser->tmp) {
            parser->tmp = apr_brigade_create(parser->pool, parser->c->bucket_alloc);
        }
        status = apr_brigade_split_line(parser->tmp, bb, APR_BLOCK_READ,
                                        len);
        if (status == APR_SUCCESS) {
            --len;
            status = apr_brigade_flatten(parser->tmp, line, &len);
            if (status == APR_SUCCESS) {
                /* we assume a non-0 containing line and remove trailing crlf. */
                line[len] = '\0';
                /*
                 * XXX: What to do if there is an LF but no CRLF?
                 *      Should we error out?
                 */
                if (len >= 2 && !strcmp(H2_CRLF, line + len - 2)) {
                    len -= 2;
                    line[len] = '\0';
                    apr_brigade_cleanup(parser->tmp);
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, parser->c,
                                  "h2_c2(%s): read response line: %s",
                                  parser->id, line);
                }
                else {
                    apr_off_t brigade_length;
    
                    /*
                     * If the brigade parser->tmp becomes longer than our buffer
                     * for flattening we never have a chance to get a complete
                     * line. This can happen if we are called multiple times after
                     * previous calls did not find a H2_CRLF and we returned
                     * APR_EAGAIN. In this case parser->tmp (correctly) grows
                     * with each call to apr_brigade_split_line.
                     *
                     * XXX: Currently a stack based buffer of HUGE_STRING_LEN is
                     * used. This means we cannot cope with lines larger than
                     * HUGE_STRING_LEN which might be an issue.
                     */
                    status = apr_brigade_length(parser->tmp, 0, &brigade_length);
                    if ((status != APR_SUCCESS) || (brigade_length > (apr_off_t)len)) {
                        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, parser->c, APLOGNO(10257)
                                      "h2_c2(%s): read response, line too long",
                                      parser->id);
                        return APR_ENOSPC;
                    }
                    /* this does not look like a complete line yet */
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, parser->c,
                                  "h2_c2(%s): read response, incomplete line: %s",
                                  parser->id, line);
                    if (!parser->saveto) {
                        parser->saveto = apr_brigade_create(parser->pool,
                                                            parser->c->bucket_alloc);
                    }
                    /*
                     * Be on the save side and save the parser->tmp brigade
                     * as it could contain transient buckets which could be
                     * invalid next time we are here.
                     *
                     * NULL for the filter parameter is ok since we
                     * provide our own brigade as second parameter
                     * and ap_save_brigade does not need to create one.
                     */
                    ap_save_brigade(NULL, &(parser->saveto), &(parser->tmp),
                                    parser->tmp->p);
                    APR_BRIGADE_CONCAT(parser->tmp, parser->saveto);
                    return APR_EAGAIN;
                }
            }
        }
        apr_brigade_cleanup(parser->tmp);
        return status;
    }
    
    static apr_table_t *make_table(h2_response_parser *parser)
    {
        apr_array_header_t *hlines = parser->hlines;
        if (hlines) {
            apr_table_t *headers = apr_table_make(parser->pool, hlines->nelts);
            int i;
    
            for (i = 0; i < hlines->nelts; ++i) {
                char *hline = ((char **)hlines->elts)[i];
                char *sep = ap_strchr(hline, ':');
                if (!sep) {
                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, APR_EINVAL, parser->c,
                                  APLOGNO(02955) "h2_c2(%s): invalid header[%d] '%s'",
                                  parser->id, i, (char*)hline);
                    /* not valid format, abort */
                    return NULL;
                }
                (*sep++) = '\0';
                while (*sep == ' ' || *sep == '\t') {
                    ++sep;
                }
    
                if (!h2_util_ignore_resp_header(hline)) {
                    apr_table_merge(headers, hline, sep);
                }
            }
            return headers;
        }
        else {
            return apr_table_make(parser->pool, 0);
        }
    }
    
    static apr_status_t pass_response(h2_conn_ctx_t *conn_ctx, ap_filter_t *f,
                                      h2_response_parser *parser)
    {
        apr_bucket *b;
        apr_status_t status;
        h2_headers *response = h2_headers_create(parser->http_status,
                                                 make_table(parser),
                                                 parser->c->notes,
                                                 0, parser->pool);
        apr_brigade_cleanup(parser->tmp);
        b = h2_bucket_headers_create(parser->c->bucket_alloc, response);
        APR_BRIGADE_INSERT_TAIL(parser->tmp, b);
        b = apr_bucket_flush_create(parser->c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(parser->tmp, b);
        status = ap_pass_brigade(f->next, parser->tmp);
        apr_brigade_cleanup(parser->tmp);
    
        /* reset parser for possible next response */
        parser->state = H2_RP_STATUS_LINE;
        apr_array_clear(parser->hlines);
    
        if (response->status >= 200) {
            conn_ctx->has_final_response = 1;
        }
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, parser->c,
                      APLOGNO(03197) "h2_c2(%s): passed response %d",
                      parser->id, response->status);
        return status;
    }
    
    static apr_status_t parse_status(h2_response_parser *parser, char *line)
    {
        int sindex = (apr_date_checkmask(line, "HTTP/#.# ###*")? 9 :
                      (apr_date_checkmask(line, "HTTP/# ###*")? 7 : 0));
        if (sindex > 0) {
            int k = sindex + 3;
            char keepchar = line[k];
            line[k] = '\0';
            parser->http_status = atoi(&line[sindex]);
            line[k] = keepchar;
            parser->state = H2_RP_HEADER_LINE;
    
            return APR_SUCCESS;
        }
        /* Seems like there is garbage on the connection. May be a leftover
         * from a previous proxy request.
         * This should only happen if the H2_RESPONSE filter is not yet in
         * place (post_read_request has not been reached and the handler wants
         * to write something. Probably just the interim response we are
         * waiting for. But if there is other data hanging around before
         * that, this needs to fail. */
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, parser->c, APLOGNO(03467)
                      "h2_c2(%s): unable to parse status line: %s",
                      parser->id, line);
        return APR_EINVAL;
    }
    
    static apr_status_t parse_response(h2_response_parser *parser,
                                       h2_conn_ctx_t *conn_ctx,
                                       ap_filter_t* f, apr_bucket_brigade *bb)
    {
        char line[HUGE_STRING_LEN];
        apr_status_t status = APR_SUCCESS;
    
        while (!APR_BRIGADE_EMPTY(bb) && status == APR_SUCCESS) {
            switch (parser->state) {
                case H2_RP_STATUS_LINE:
                case H2_RP_HEADER_LINE:
                    status = get_line(parser, bb, line, sizeof(line));
                    if (status == APR_EAGAIN) {
                        /* need more data */
                        return APR_SUCCESS;
                    }
                    else if (status != APR_SUCCESS) {
                        return status;
                    }
                    if (parser->state == H2_RP_STATUS_LINE) {
                        /* instead of parsing, just take it directly */
                        status = parse_status(parser, line);
                    }
                    else if (line[0] == '\0') {
                        /* end of headers, pass response onward */
                        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, parser->c,
                                      "h2_c2(%s): end of response", parser->id);
                        return pass_response(conn_ctx, f, parser);
                    }
                    else {
                        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, parser->c,
                                      "h2_c2(%s): response header %s", parser->id, line);
                        status = parse_header(parser, line);
                    }
                    break;
    
                default:
                    return status;
            }
        }
        return status;
    }
    
    apr_status_t h2_c2_filter_catch_h1_out(ap_filter_t* f, apr_bucket_brigade* bb)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
        h2_response_parser *parser = f->ctx;
        apr_status_t rv;
    
        ap_assert(conn_ctx);
        H2_FILTER_LOG("c2_catch_h1_out", f->c, APLOG_TRACE2, 0, "check", bb);
    
        if (!f->c->aborted && !conn_ctx->has_final_response) {
            if (!parser) {
                parser = apr_pcalloc(f->c->pool, sizeof(*parser));
                parser->id = apr_psprintf(f->c->pool, "%s-%d", conn_ctx->id, conn_ctx->stream_id);
                parser->pool = f->c->pool;
                parser->c = f->c;
                parser->state = H2_RP_STATUS_LINE;
                parser->hlines = apr_array_make(parser->pool, 10, sizeof(char *));
                f->ctx = parser;
            }
    
            if (!APR_BRIGADE_EMPTY(bb)) {
                apr_bucket *b = APR_BRIGADE_FIRST(bb);
                if (AP_BUCKET_IS_EOR(b)) {
                    /* TODO: Yikes, this happens when errors are encountered on input
                     * before anything from the repsonse has been processed. The
                     * ap_die_r() call will do nothing in certain conditions.
                     */
                    int result = ap_map_http_request_error(conn_ctx->last_err,
                                                           HTTP_INTERNAL_SERVER_ERROR);
                    request_rec *r = h2_create_request_rec(conn_ctx->request, f->c, 1);
                    if (r) {
                        ap_die((result >= 400)? result : HTTP_INTERNAL_SERVER_ERROR, r);
                        b = ap_bucket_eor_create(f->c->bucket_alloc, r);
                        APR_BRIGADE_INSERT_TAIL(bb, b);
                    }
                }
            }
            /* There are cases where we need to parse a serialized http/1.1 response.
             * One example is a 100-continue answer via a mod_proxy setup. */
            while (bb && !f->c->aborted && !conn_ctx->has_final_response) {
                rv = parse_response(parser, conn_ctx, f, bb);
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, f->c,
                              "h2_c2(%s): parsed response", parser->id);
                if (APR_BRIGADE_EMPTY(bb) || APR_SUCCESS != rv) {
                    return rv;
                }
            }
        }
    
        return ap_pass_brigade(f->next, bb);
    }
    
    apr_status_t h2_c2_filter_response_out(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
        request_rec *r = f->r;
        apr_bucket *b, *bresp, *body_bucket = NULL, *next;
        ap_bucket_error *eb = NULL;
        h2_headers *response = NULL;
        int headers_passing = 0;
    
        H2_FILTER_LOG("c2_response_out", f->c, APLOG_TRACE1, 0, "called with", bb);
    
        if (f->c->aborted || !conn_ctx || conn_ctx->has_final_response) {
            return ap_pass_brigade(f->next, bb);
        }
    
        if (!conn_ctx->has_final_response) {
            /* check, if we need to send the response now. Until we actually
             * see a DATA bucket or some EOS/EOR, we do not do so. */
            for (b = APR_BRIGADE_FIRST(bb);
                 b != APR_BRIGADE_SENTINEL(bb);
                 b = APR_BUCKET_NEXT(b))
            {
                if (AP_BUCKET_IS_ERROR(b) && !eb) {
                    eb = b->data;
                }
                else if (AP_BUCKET_IS_EOC(b)) {
                    /* If we see an EOC bucket it is a signal that we should get out
                     * of the way doing nothing.
                     */
                    ap_remove_output_filter(f);
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, f->c,
                                  "h2_c2(%s): eoc bucket passed", conn_ctx->id);
                    return ap_pass_brigade(f->next, bb);
                }
                else if (H2_BUCKET_IS_HEADERS(b)) {
                    headers_passing = 1;
                }
                else if (!APR_BUCKET_IS_FLUSH(b)) {
                    body_bucket = b;
                    break;
                }
            }
    
            if (eb) {
                int st = eb->status;
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03047)
                              "h2_c2(%s): err bucket status=%d",
                              conn_ctx->id, st);
                /* throw everything away and replace it with the error response
                 * generated by ap_die() */
                apr_brigade_cleanup(bb);
                ap_die(st, r);
                return AP_FILTER_ERROR;
            }
    
            if (body_bucket || !headers_passing) {
                /* time to insert the response bucket before the body or if
                 * no h2_headers is passed, e.g. the response is empty */
                response = create_response(r);
                if (response == NULL) {
                    ap_log_cerror(APLOG_MARK, APLOG_NOTICE, 0, f->c, APLOGNO(03048)
                                  "h2_c2(%s): unable to create response", conn_ctx->id);
                    return APR_ENOMEM;
                }
    
                bresp = h2_bucket_headers_create(f->c->bucket_alloc, response);
                if (body_bucket) {
                    APR_BUCKET_INSERT_BEFORE(body_bucket, bresp);
                }
                else {
                    APR_BRIGADE_INSERT_HEAD(bb, bresp);
                }
                conn_ctx->has_final_response = 1;
                r->sent_bodyct = 1;
                ap_remove_output_filter_byhandle(f->r->output_filters, "H2_C2_NET_CATCH_H1");
            }
        }
    
        if (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
                          "h2_c2(%s): headers only, cleanup output brigade", conn_ctx->id);
            b = body_bucket? body_bucket : APR_BRIGADE_FIRST(bb);
            while (b != APR_BRIGADE_SENTINEL(bb)) {
                next = APR_BUCKET_NEXT(b);
                if (APR_BUCKET_IS_EOS(b) || AP_BUCKET_IS_EOR(b)) {
                    break;
                }
                if (!H2_BUCKET_IS_HEADERS(b)) {
                    APR_BUCKET_REMOVE(b);
                    apr_bucket_destroy(b);
                }
                b = next;
            }
        }
        if (conn_ctx->has_final_response) {
            /* lets get out of the way, our task is done */
            ap_remove_output_filter(f);
        }
        return ap_pass_brigade(f->next, bb);
    }
    
    
    struct h2_chunk_filter_t {
        const char *id;
        int eos_chunk_added;
        apr_bucket_brigade *bbchunk;
        apr_off_t chunked_total;
    };
    typedef struct h2_chunk_filter_t h2_chunk_filter_t;
    
    
    static void make_chunk(conn_rec *c, h2_chunk_filter_t *fctx, apr_bucket_brigade *bb,
                           apr_bucket *first, apr_off_t chunk_len,
                           apr_bucket *tail)
    {
        /* Surround the buckets [first, tail[ with new buckets carrying the
         * HTTP/1.1 chunked encoding format. If tail is NULL, the chunk extends
         * to the end of the brigade. */
        char buffer[128];
        apr_bucket *b;
        apr_size_t len;
    
        len = (apr_size_t)apr_snprintf(buffer, H2_ALEN(buffer),
                                       "%"APR_UINT64_T_HEX_FMT"\r\n", (apr_uint64_t)chunk_len);
        b = apr_bucket_heap_create(buffer, len, NULL, bb->bucket_alloc);
        APR_BUCKET_INSERT_BEFORE(first, b);
        b = apr_bucket_immortal_create("\r\n", 2, bb->bucket_alloc);
        if (tail) {
            APR_BUCKET_INSERT_BEFORE(tail, b);
        }
        else {
            APR_BRIGADE_INSERT_TAIL(bb, b);
        }
        fctx->chunked_total += chunk_len;
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "h2_c2(%s): added chunk %ld, total %ld",
                      fctx->id, (long)chunk_len, (long)fctx->chunked_total);
    }
    
    static int ser_header(void *ctx, const char *name, const char *value)
    {
        apr_bucket_brigade *bb = ctx;
        apr_brigade_printf(bb, NULL, NULL, "%s: %s\r\n", name, value);
        return 1;
    }
    
    static apr_status_t read_and_chunk(ap_filter_t *f, h2_conn_ctx_t *conn_ctx,
                                       apr_read_type_e block) {
        h2_chunk_filter_t *fctx = f->ctx;
        request_rec *r = f->r;
        apr_status_t status = APR_SUCCESS;
    
        if (!fctx->bbchunk) {
            fctx->bbchunk = apr_brigade_create(r->pool, f->c->bucket_alloc);
        }
    
        if (APR_BRIGADE_EMPTY(fctx->bbchunk)) {
            apr_bucket *b, *next, *first_data = NULL;
            apr_bucket_brigade *tmp;
            apr_off_t bblen = 0;
    
            /* get more data from the lower layer filters. Always do this
             * in larger pieces, since we handle the read modes ourself. */
            status = ap_get_brigade(f->next, fctx->bbchunk,
                                    AP_MODE_READBYTES, block, conn_ctx->mplx->stream_max_mem);
            if (status != APR_SUCCESS) {
                return status;
            }
    
            for (b = APR_BRIGADE_FIRST(fctx->bbchunk);
                 b != APR_BRIGADE_SENTINEL(fctx->bbchunk);
                 b = next) {
                next = APR_BUCKET_NEXT(b);
                if (APR_BUCKET_IS_METADATA(b)) {
                    if (first_data) {
                        make_chunk(f->c, fctx, fctx->bbchunk, first_data, bblen, b);
                        first_data = NULL;
                    }
    
                    if (H2_BUCKET_IS_HEADERS(b)) {
                        h2_headers *headers = h2_bucket_headers_get(b);
    
                        ap_assert(headers);
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                                      "h2_c2(%s-%d): receiving trailers",
                                      conn_ctx->id, conn_ctx->stream_id);
                        tmp = apr_brigade_split_ex(fctx->bbchunk, b, NULL);
                        if (!apr_is_empty_table(headers->headers)) {
                            status = apr_brigade_puts(fctx->bbchunk, NULL, NULL, "0\r\n");
                            apr_table_do(ser_header, fctx->bbchunk, headers->headers, NULL);
                            status = apr_brigade_puts(fctx->bbchunk, NULL, NULL, "\r\n");
                        }
                        else {
                            status = apr_brigade_puts(fctx->bbchunk, NULL, NULL, "0\r\n\r\n");
                        }
                        r->trailers_in = apr_table_clone(r->pool, headers->headers);
                        APR_BUCKET_REMOVE(b);
                        apr_bucket_destroy(b);
                        APR_BRIGADE_CONCAT(fctx->bbchunk, tmp);
                        apr_brigade_destroy(tmp);
                        fctx->eos_chunk_added = 1;
                    }
                    else if (APR_BUCKET_IS_EOS(b)) {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                                      "h2_c2(%s-%d): receiving eos",
                                      conn_ctx->id, conn_ctx->stream_id);
                        if (!fctx->eos_chunk_added) {
                            tmp = apr_brigade_split_ex(fctx->bbchunk, b, NULL);
                            status = apr_brigade_puts(fctx->bbchunk, NULL, NULL, "0\r\n\r\n");
                            APR_BRIGADE_CONCAT(fctx->bbchunk, tmp);
                            apr_brigade_destroy(tmp);
                        }
                        fctx->eos_chunk_added = 0;
                    }
                }
                else if (b->length == 0) {
                    APR_BUCKET_REMOVE(b);
                    apr_bucket_destroy(b);
                }
                else {
                    if (!first_data) {
                        first_data = b;
                        bblen = 0;
                    }
                    bblen += b->length;
                }
            }
    
            if (first_data) {
                make_chunk(f->c, fctx, fctx->bbchunk, first_data, bblen, NULL);
            }
        }
        return status;
    }
    
    apr_status_t h2_c2_filter_request_in(ap_filter_t* f,
                                         apr_bucket_brigade* bb,
                                         ap_input_mode_t mode,
                                         apr_read_type_e block,
                                         apr_off_t readbytes)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
        h2_chunk_filter_t *fctx = f->ctx;
        request_rec *r = f->r;
        apr_status_t status = APR_SUCCESS;
        apr_bucket *b, *next;
        core_server_config *conf =
            (core_server_config *) ap_get_module_config(r->server->module_config,
                                                        &core_module);
        ap_assert(conn_ctx);
    
        if (!fctx) {
            fctx = apr_pcalloc(r->pool, sizeof(*fctx));
            fctx->id = apr_psprintf(r->pool, "%s-%d", conn_ctx->id, conn_ctx->stream_id);
            f->ctx = fctx;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, f->r,
                      "h2_c2(%s-%d): request input, mode=%d, block=%d, "
                      "readbytes=%ld, exp=%d",
                      conn_ctx->id, conn_ctx->stream_id, mode, block,
                      (long)readbytes, r->expecting_100);
        if (!conn_ctx->input_chunked) {
            status = ap_get_brigade(f->next, bb, mode, block, readbytes);
            /* pipe data through, just take care of trailers */
            for (b = APR_BRIGADE_FIRST(bb);
                 b != APR_BRIGADE_SENTINEL(bb); b = next) {
                next = APR_BUCKET_NEXT(b);
                if (H2_BUCKET_IS_HEADERS(b)) {
                    h2_headers *headers = h2_bucket_headers_get(b);
                    ap_assert(headers);
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                                  "h2_c2(%s-%d): receiving trailers",
                                  conn_ctx->id, conn_ctx->stream_id);
                    r->trailers_in = headers->headers;
                    if (conf && conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE) {
                        r->headers_in = apr_table_overlay(r->pool, r->headers_in,
                                                          r->trailers_in);
                    }
                    APR_BUCKET_REMOVE(b);
                    apr_bucket_destroy(b);
                    ap_remove_input_filter(f);
    
                    if (headers->raw_bytes && h2_c_logio_add_bytes_in) {
                        h2_c_logio_add_bytes_in(f->c, headers->raw_bytes);
                    }
                    break;
                }
            }
            return status;
        }
    
        /* Things are more complicated. The standard HTTP input filter, which
         * does a lot what we do not want to duplicate, also cares about chunked
         * transfer encoding and trailers.
         * We need to simulate chunked encoding for it to be happy.
         */
        if ((status = read_and_chunk(f, conn_ctx, block)) != APR_SUCCESS) {
            return status;
        }
    
        if (mode == AP_MODE_EXHAUSTIVE) {
            /* return all we have */
            APR_BRIGADE_CONCAT(bb, fctx->bbchunk);
        }
        else if (mode == AP_MODE_READBYTES) {
            status = h2_brigade_concat_length(bb, fctx->bbchunk, readbytes);
        }
        else if (mode == AP_MODE_SPECULATIVE) {
            status = h2_brigade_copy_length(bb, fctx->bbchunk, readbytes);
        }
        else if (mode == AP_MODE_GETLINE) {
            /* we are reading a single LF line, e.g. the HTTP headers.
             * this has the nasty side effect to split the bucket, even
             * though it ends with CRLF and creates a 0 length bucket */
            status = apr_brigade_split_line(bb, fctx->bbchunk, block, HUGE_STRING_LEN);
            if (APLOGctrace1(f->c)) {
                char buffer[1024];
                apr_size_t len = sizeof(buffer)-1;
                apr_brigade_flatten(bb, buffer, &len);
                buffer[len] = 0;
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
                              "h2_c2(%s-%d): getline: %s",
                              conn_ctx->id, conn_ctx->stream_id, buffer);
            }
        }
        else {
            /* Hmm, well. There is mode AP_MODE_EATCRLF, but we chose not
             * to support it. Seems to work. */
            ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOTIMPL, f->c,
                          APLOGNO(02942)
                          "h2_c2, unsupported READ mode %d", mode);
            status = APR_ENOTIMPL;
        }
    
        h2_util_bb_log(f->c, conn_ctx->stream_id, APLOG_TRACE2, "returning input", bb);
        return status;
    }
    
    apr_status_t h2_c2_filter_trailers_out(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
        request_rec *r = f->r;
        apr_bucket *b, *e;
    
        if (conn_ctx && r) {
            /* Detect the EOS/EOR bucket and forward any trailers that may have
             * been set to our h2_headers.
             */
            for (b = APR_BRIGADE_FIRST(bb);
                 b != APR_BRIGADE_SENTINEL(bb);
                 b = APR_BUCKET_NEXT(b))
            {
                if ((APR_BUCKET_IS_EOS(b) || AP_BUCKET_IS_EOR(b))
                    && r->trailers_out && !apr_is_empty_table(r->trailers_out)) {
                    h2_headers *headers;
                    apr_table_t *trailers;
    
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03049)
                                  "h2_c2(%s-%d): sending trailers",
                                  conn_ctx->id, conn_ctx->stream_id);
                    trailers = apr_table_clone(r->pool, r->trailers_out);
                    headers = h2_headers_rcreate(r, HTTP_OK, trailers, r->pool);
                    e = h2_bucket_headers_create(bb->bucket_alloc, headers);
                    APR_BUCKET_INSERT_BEFORE(b, e);
                    apr_table_clear(r->trailers_out);
                    ap_remove_output_filter(f);
                    break;
                }
            }
        }
    
        return ap_pass_brigade(f->next, bb);
    }
    
    #endif /* else #if AP_HAS_RESPONSE_BUCKETS */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_http2.c��������������������������������������������������������������0000664�0001751�0001751�00000026371�14473316336�017422� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <apr_optional_hooks.h>
    #include <apr_strings.h>
    #include <apr_time.h>
    #include <apr_want.h>
    
    #include <httpd.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    #include <mpm_common.h>
    
    #include "mod_http2.h"
    
    #include <nghttp2/nghttp2.h>
    #include "h2_stream.h"
    #include "h2_c1.h"
    #include "h2_c2.h"
    #include "h2_session.h"
    #include "h2_config.h"
    #include "h2_conn_ctx.h"
    #include "h2_protocol.h"
    #include "h2_mplx.h"
    #include "h2_push.h"
    #include "h2_request.h"
    #include "h2_switch.h"
    #include "h2_version.h"
    #include "h2_bucket_beam.h"
    #include "h2_ws.h"
    
    
    static void h2_hooks(apr_pool_t *pool);
    
    AP_DECLARE_MODULE(http2) = {
        STANDARD20_MODULE_STUFF,
        h2_config_create_dir, /* func to create per dir config */
        h2_config_merge_dir,  /* func to merge per dir config */
        h2_config_create_svr, /* func to create per server config */
        h2_config_merge_svr,  /* func to merge per server config */
        h2_cmds,              /* command handlers */
        h2_hooks,
    #if defined(AP_MODULE_FLAG_NONE)
        AP_MODULE_FLAG_ALWAYS_MERGE
    #endif
    };
    
    static int h2_h2_fixups(request_rec *r);
    
    typedef struct {
        unsigned int change_prio : 1;
        unsigned int sha256 : 1;
        unsigned int inv_headers : 1;
        unsigned int dyn_windows : 1;
    } features;
    
    static features myfeats;
    static int mpm_warned;
    
    /* The module initialization. Called once as apache hook, before any multi
     * processing (threaded or not) happens. It is typically at least called twice, 
     * see
     * http://wiki.apache.org/httpd/ModuleLife
     * Since the first run is just a "practise" run, we want to initialize for real
     * only on the second try. This defeats the purpose of the first dry run a bit, 
     * since apache wants to verify that a new configuration actually will work. 
     * So if we have trouble with the configuration, this will only be detected 
     * when the server has already switched.
     * On the other hand, when we initialize lib nghttp2, all possible crazy things 
     * might happen and this might even eat threads. So, better init on the real 
     * invocation, for now at least.
     */
    static int h2_post_config(apr_pool_t *p, apr_pool_t *plog,
                              apr_pool_t *ptemp, server_rec *s)
    {
        void *data = NULL;
        const char *mod_h2_init_key = "mod_http2_init_counter";
        nghttp2_info *ngh2;
        apr_status_t status;
        
        (void)plog;(void)ptemp;
    #ifdef H2_NG2_CHANGE_PRIO
        myfeats.change_prio = 1;
    #endif
    #ifdef H2_OPENSSL
        myfeats.sha256 = 1;
    #endif
    #ifdef H2_NG2_INVALID_HEADER_CB
        myfeats.inv_headers = 1;
    #endif
    #ifdef H2_NG2_LOCAL_WIN_SIZE
        myfeats.dyn_windows = 1;
    #endif
        
        apr_pool_userdata_get(&data, mod_h2_init_key, s->process->pool);
        if ( data == NULL ) {
            ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03089)
                         "initializing post config dry run");
            apr_pool_userdata_set((const void *)1, mod_h2_init_key,
                                  apr_pool_cleanup_null, s->process->pool);
            return APR_SUCCESS;
        }
        
        ngh2 = nghttp2_version(0);
        ap_log_error( APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(03090)
                     "mod_http2 (v%s, feats=%s%s%s%s, nghttp2 %s), initializing...",
                     MOD_HTTP2_VERSION, 
                     myfeats.change_prio? "CHPRIO"  : "", 
                     myfeats.sha256?      "+SHA256" : "",
                     myfeats.inv_headers? "+INVHD"  : "",
                     myfeats.dyn_windows? "+DWINS"  : "",
                     ngh2?                ngh2->version_str : "unknown");
        
        if (!h2_mpm_supported() && !mpm_warned) {
            mpm_warned = 1;
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10034)
                         "The mpm module (%s) is not supported by mod_http2. The mpm determines "
                         "how things are processed in your server. HTTP/2 has more demands in "
                         "this regard and the currently selected mpm will just not do. "
                         "This is an advisory warning. Your server will continue to work, but "
                         "the HTTP/2 protocol will be inactive.", 
                         h2_conn_mpm_name());
        }
        
        status = h2_protocol_init(p, s);
        if (status == APR_SUCCESS) {
            status = h2_switch_init(p, s);
        }
    
        return status;
    }
    
    static char *http2_var_lookup(apr_pool_t *, server_rec *,
                             conn_rec *, request_rec *, char *name);
    static int http2_is_h2(conn_rec *);
    
    static void http2_get_num_workers(server_rec *s, int *minw, int *maxw)
    {
        apr_time_t tdummy;
    
        h2_get_workers_config(s, minw, maxw, &tdummy);
    }
    
    /* Runs once per created child process. Perform any process 
     * related initionalization here.
     */
    static void h2_child_init(apr_pool_t *pchild, server_rec *s)
    {
        apr_status_t rv;
    
        /* Set up our connection processing */
        rv = h2_c1_child_init(pchild, s);
        if (APR_SUCCESS == rv) {
            rv = h2_c2_child_init(pchild, s);
        }
        if (APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                         APLOGNO(02949) "initializing connection handling");
        }
    }
    
    /* Install this module into the apache2 infrastructure.
     */
    static void h2_hooks(apr_pool_t *pool)
    {
        static const char *const mod_ssl[] = { "mod_ssl.c", NULL};
        
        APR_REGISTER_OPTIONAL_FN(http2_is_h2);
        APR_REGISTER_OPTIONAL_FN(http2_var_lookup);
        APR_REGISTER_OPTIONAL_FN(http2_get_num_workers);
    
        ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");
        
        /* Run once after configuration is set, but before mpm children initialize.
         */
        ap_hook_post_config(h2_post_config, mod_ssl, NULL, APR_HOOK_MIDDLE);
        
        /* Run once after a child process has been created.
         */
        ap_hook_child_init(h2_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    #if AP_MODULE_MAGIC_AT_LEAST(20120211, 110)
        ap_hook_child_stopping(h2_c1_child_stopping, NULL, NULL, APR_HOOK_MIDDLE);
    #endif
    
        h2_c1_register_hooks();
        h2_switch_register_hooks();
        h2_c2_register_hooks();
        h2_ws_register_hooks();
    
        /* Setup subprocess env for certain variables
         */
        ap_hook_fixups(h2_h2_fixups, NULL,NULL, APR_HOOK_MIDDLE);
    }
    
    static const char *val_HTTP2(apr_pool_t *p, server_rec *s,
                                 conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
    {
        return ctx? "on" : "off";
    }
    
    static const char *val_H2_PUSH(apr_pool_t *p, server_rec *s,
                                   conn_rec *c, request_rec *r,
                                   h2_conn_ctx_t *conn_ctx)
    {
        if (conn_ctx) {
            if (r) {
                if (conn_ctx->stream_id) {
                    const h2_stream *stream = h2_mplx_c2_stream_get(conn_ctx->mplx, conn_ctx->stream_id);
                    if (stream && stream->push_policy != H2_PUSH_NONE) {
                        return "on";
                    }
                }
            }
            else if (c && h2_session_push_enabled(conn_ctx->session)) {
                return "on";
            }
        }
        else if (s) {
            if (h2_config_geti(r, s, H2_CONF_PUSH)) {
                return "on";
            }
        }
        return "off";
    }
    
    static const char *val_H2_PUSHED(apr_pool_t *p, server_rec *s,
                                     conn_rec *c, request_rec *r,
                                     h2_conn_ctx_t *conn_ctx)
    {
        if (conn_ctx) {
            if (conn_ctx->stream_id && !H2_STREAM_CLIENT_INITIATED(conn_ctx->stream_id)) {
                return "PUSHED";
            }
        }
        return "";
    }
    
    static const char *val_H2_PUSHED_ON(apr_pool_t *p, server_rec *s,
                                        conn_rec *c, request_rec *r,
                                        h2_conn_ctx_t *conn_ctx)
    {
        if (conn_ctx) {
            if (conn_ctx->stream_id && !H2_STREAM_CLIENT_INITIATED(conn_ctx->stream_id)) {
                const h2_stream *stream = h2_mplx_c2_stream_get(conn_ctx->mplx, conn_ctx->stream_id);
                if (stream) {
                    return apr_itoa(p, stream->initiated_on);
                }
            }
        }
        return "";
    }
    
    static const char *val_H2_STREAM_TAG(apr_pool_t *p, server_rec *s,
                                         conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
    {
        if (c) {
            h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
            if (conn_ctx) {
                return conn_ctx->stream_id == 0? conn_ctx->id
                   : apr_psprintf(p, "%s-%d", conn_ctx->id, conn_ctx->stream_id);
            }
        }
        return "";
    }
    
    static const char *val_H2_STREAM_ID(apr_pool_t *p, server_rec *s,
                                        conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
    {
        const char *cp = val_H2_STREAM_TAG(p, s, c, r, ctx);
        if (cp && (cp = ap_strrchr_c(cp, '-'))) {
            return ++cp;
        }
        return NULL;
    }
    
    typedef const char *h2_var_lookup(apr_pool_t *p, server_rec *s,
                                      conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx);
    typedef struct h2_var_def {
        const char *name;
        h2_var_lookup *lookup;
        unsigned int  subprocess : 1;    /* should be set in r->subprocess_env */
    } h2_var_def;
    
    static h2_var_def H2_VARS[] = {
        { "HTTP2",               val_HTTP2,  1 },
        { "H2PUSH",              val_H2_PUSH, 1 },
        { "H2_PUSH",             val_H2_PUSH, 1 },
        { "H2_PUSHED",           val_H2_PUSHED, 1 },
        { "H2_PUSHED_ON",        val_H2_PUSHED_ON, 1 },
        { "H2_STREAM_ID",        val_H2_STREAM_ID, 1 },
        { "H2_STREAM_TAG",       val_H2_STREAM_TAG, 1 },
    };
    
    #ifndef H2_ALEN
    #define H2_ALEN(a)          (sizeof(a)/sizeof((a)[0]))
    #endif
    
    
    static int http2_is_h2(conn_rec *c)
    {
        return h2_conn_ctx_get(c->master? c->master : c) != NULL;
    }
    
    static char *http2_var_lookup(apr_pool_t *p, server_rec *s,
                                  conn_rec *c, request_rec *r, char *name)
    {
        unsigned int i;
        /* If the # of vars grow, we need to put definitions in a hash */
        for (i = 0; i < H2_ALEN(H2_VARS); ++i) {
            h2_var_def *vdef = &H2_VARS[i];
            if (!strcmp(vdef->name, name)) {
                h2_conn_ctx_t *ctx = (r? h2_conn_ctx_get(c) :
                               h2_conn_ctx_get(c->master? c->master : c));
                return (char *)vdef->lookup(p, s, c, r, ctx);
            }
        }
        return (char*)"";
    }
    
    static int h2_h2_fixups(request_rec *r)
    {
        if (r->connection->master) {
            h2_conn_ctx_t *ctx = h2_conn_ctx_get(r->connection);
            unsigned int i;
    
            for (i = 0; ctx && i < H2_ALEN(H2_VARS); ++i) {
                h2_var_def *vdef = &H2_VARS[i];
                if (vdef->subprocess) {
                    apr_table_setn(r->subprocess_env, vdef->name, 
                                   vdef->lookup(r->pool, r->server, r->connection, 
                                                r, ctx));
                }
            }
        }
        return DECLINED;
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_proxy_session.h�������������������������������������������������������0000664�0001751�0001751�00000012427�14447501300�021025� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 h2_proxy_session_h
    #define h2_proxy_session_h
    
    #define H2_ALEN(a)          (sizeof(a)/sizeof((a)[0]))
    
    #include <nghttp2/nghttp2.h>
    
    struct h2_proxy_iqueue;
    struct h2_proxy_ihash_t;
    
    typedef enum {
        H2_STREAM_ST_IDLE,
        H2_STREAM_ST_OPEN,
        H2_STREAM_ST_RESV_LOCAL,
        H2_STREAM_ST_RESV_REMOTE,
        H2_STREAM_ST_CLOSED_INPUT,
        H2_STREAM_ST_CLOSED_OUTPUT,
        H2_STREAM_ST_CLOSED,
    } h2_proxy_stream_state_t;
    
    typedef enum {
        H2_PROXYS_ST_INIT,             /* send initial SETTINGS, etc. */
        H2_PROXYS_ST_DONE,             /* finished, connection close */
        H2_PROXYS_ST_IDLE,             /* no streams to process */
        H2_PROXYS_ST_BUSY,             /* read/write without stop */
        H2_PROXYS_ST_WAIT,             /* waiting for tasks reporting back */
        H2_PROXYS_ST_LOCAL_SHUTDOWN,   /* we announced GOAWAY */
        H2_PROXYS_ST_REMOTE_SHUTDOWN,  /* client announced GOAWAY */
    } h2_proxys_state;
    
    typedef enum {
        H2_PROXYS_EV_INIT,             /* session was initialized */
        H2_PROXYS_EV_LOCAL_GOAWAY,     /* we send a GOAWAY */
        H2_PROXYS_EV_REMOTE_GOAWAY,    /* remote send us a GOAWAY */
        H2_PROXYS_EV_CONN_ERROR,       /* connection error */
        H2_PROXYS_EV_PROTO_ERROR,      /* protocol error */
        H2_PROXYS_EV_CONN_TIMEOUT,     /* connection timeout */
        H2_PROXYS_EV_NO_IO,            /* nothing has been read or written */
        H2_PROXYS_EV_STREAM_SUBMITTED, /* stream has been submitted */
        H2_PROXYS_EV_STREAM_DONE,      /* stream has been finished */
        H2_PROXYS_EV_STREAM_RESUMED,   /* stream signalled availability of headers/data */
        H2_PROXYS_EV_DATA_READ,        /* connection data has been read */
        H2_PROXYS_EV_NGH2_DONE,        /* nghttp2 wants neither read nor write anything */
        H2_PROXYS_EV_PRE_CLOSE,        /* connection will close after this */
    } h2_proxys_event_t;
    
    typedef enum {
        H2_PING_ST_NONE,               /* normal connection mode, ProxyTimeout rules */
        H2_PING_ST_AWAIT_ANY,          /* waiting for any frame from backend */
        H2_PING_ST_AWAIT_PING,         /* waiting for PING frame from backend */
    } h2_ping_state_t;
    
    typedef struct h2_proxy_session h2_proxy_session;
    typedef void h2_proxy_request_done(h2_proxy_session *s, request_rec *r,
                                       apr_status_t status, int touched,
                                       int error_code);
    
    struct h2_proxy_session {
        const char *id;
        conn_rec *c;
        proxy_conn_rec *p_conn;
        proxy_server_conf *conf;
        apr_pool_t *pool;
        nghttp2_session *ngh2;   /* the nghttp2 session itself */
        
        unsigned int aborted : 1;
        unsigned int h2_front : 1; /* if front-end connection is HTTP/2 */
    
        h2_proxy_request_done *done;
        void *user_data;
        
        unsigned char window_bits_stream;
        unsigned char window_bits_connection;
    
        h2_proxys_state state;
        apr_interval_time_t wait_timeout;
    
        struct h2_proxy_ihash_t *streams;
        struct h2_proxy_iqueue *suspended;
        apr_size_t remote_max_concurrent;
        int last_stream_id;     /* last stream id processed by backend, or 0 */
        apr_time_t last_frame_received;
        
        apr_bucket_brigade *input;
        apr_bucket_brigade *output;
    
        h2_ping_state_t ping_state;
        apr_time_t ping_timeout;
        apr_time_t save_timeout;
    };
    
    h2_proxy_session *h2_proxy_session_setup(const char *id, proxy_conn_rec *p_conn,
                                             proxy_server_conf *conf,
                                             int h2_front, 
                                             unsigned char window_bits_connection,
                                             unsigned char window_bits_stream,
                                             h2_proxy_request_done *done);
    
    apr_status_t h2_proxy_session_submit(h2_proxy_session *s, const char *url,
                                         request_rec *r, int standalone);
                           
    /** 
     * Perform a step in processing the proxy session. Will return aftert
     * one read/write cycle and indicate session status by status code.
     * @param s the session to process
     * @return APR_EAGAIN  when processing needs to be invoked again
     *         APR_SUCCESS when all streams have been processed, session still live
     *         APR_EOF     when the session has been terminated
     */
    apr_status_t h2_proxy_session_process(h2_proxy_session *s);
    
    void h2_proxy_session_cancel_all(h2_proxy_session *s);
    
    void h2_proxy_session_cleanup(h2_proxy_session *s, h2_proxy_request_done *done);
    
    #define H2_PROXY_REQ_URL_NOTE   "h2-proxy-req-url"
    
    int h2_proxy_session_is_reusable(h2_proxy_session *s);
    
    #endif /* h2_proxy_session_h */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_proxy_session.c�������������������������������������������������������0000664�0001751�0001751�00000177500�15032734035�021030� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stddef.h>
    #include <apr_strings.h>
    #include <nghttp2/nghttp2.h>
    
    #include <mpm_common.h>
    #include <httpd.h>
    #include <http_protocol.h>
    #include <mod_proxy.h>
    
    #include "mod_http2.h"
    #include "h2.h"
    #include "h2_proxy_util.h"
    #include "h2_proxy_session.h"
    
    APLOG_USE_MODULE(proxy_http2);
    
    typedef struct h2_proxy_stream {
        int id;
        apr_pool_t *pool;
        h2_proxy_session *session;
    
        const char *url;
        request_rec *r;
        conn_rec *cfront;
        h2_proxy_request *req;
        const char *real_server_uri;
        const char *p_server_uri;
        int standalone;
    
        h2_proxy_stream_state_t state;
        unsigned int suspended : 1;
        unsigned int waiting_on_100 : 1;
        unsigned int waiting_on_ping : 1;
        unsigned int headers_ended : 1;
        uint32_t error_code;
    
        apr_bucket_brigade *input;
        apr_off_t data_sent;
        apr_bucket_brigade *output;
        apr_off_t data_received;
        
        apr_table_t *saves;
    } h2_proxy_stream;
    
    
    static void dispatch_event(h2_proxy_session *session, h2_proxys_event_t ev, 
                               int arg, const char *msg);
    static void ping_arrived(h2_proxy_session *session);
    static apr_status_t check_suspended(h2_proxy_session *session);
    static void stream_resume(h2_proxy_stream *stream);
    static apr_status_t submit_trailers(h2_proxy_stream *stream);
    
    /*
     * The H2_PING connection sub-state: a state independant of the H2_SESSION state
     * of the connection:
     * - H2_PING_ST_NONE: no interference with request handling, ProxyTimeout in effect.
     *   When entered, all suspended streams are unsuspended again.
     * - H2_PING_ST_AWAIT_ANY: new requests are suspended, a possibly configured "ping"
     *   timeout is in effect. Any frame received transits to H2_PING_ST_NONE.
     * - H2_PING_ST_AWAIT_PING: same as above, but only a PING frame transits 
     *   to H2_PING_ST_NONE.
     *
     * An AWAIT state is entered on a new connection or when re-using a connection and
     * the last frame received has been some time ago. The latter sends a PING frame
     * and insists on an answer, the former is satisfied by any frame received from the
     * backend.
     *
     * This works for new connections as there is always at least one SETTINGS frame
     * that the backend sends. When re-using connection, we send a PING and insist on
     * receiving one back, as there might be frames in our connection buffers from
     * some time ago. Since some servers have protections against PING flooding, we
     * only ever have one PING unanswered.
     *
     * Requests are suspended while in a PING state, as we do not want to send data
     * before we can be reasonably sure that the connection is working (at least on
     * the h2 protocol level). This also means that the session can do blocking reads
     * when expecting PING answers.
     */
    static void set_ping_timeout(h2_proxy_session *session)
    {
        if (session->ping_timeout != -1 && session->save_timeout == -1) {
            apr_socket_t *socket = NULL;
    
            socket = ap_get_conn_socket(session->c);
            if (socket) {
                apr_socket_timeout_get(socket, &session->save_timeout);
                apr_socket_timeout_set(socket, session->ping_timeout);
            }
        }
    }
    
    static void unset_ping_timeout(h2_proxy_session *session)
    {
        if (session->save_timeout != -1) {
            apr_socket_t *socket = NULL;
    
            socket = ap_get_conn_socket(session->c);
            if (socket) {
                apr_socket_timeout_set(socket, session->save_timeout);
                session->save_timeout = -1;
            }
        }
    }
    
    static void enter_ping_state(h2_proxy_session *session, h2_ping_state_t state)
    {
        if (session->ping_state == state) return;
        switch (session->ping_state) {
        case H2_PING_ST_NONE:
            /* leaving NONE, enforce timeout, send frame maybe */
            if (H2_PING_ST_AWAIT_PING == state) {
                unset_ping_timeout(session);
                nghttp2_submit_ping(session->ngh2, 0, (const uint8_t *)"nevergonnagiveyouup");
            }
            set_ping_timeout(session);
            session->ping_state = state;
            break;
        default:
            /* no switching between the != NONE states */
            if (H2_PING_ST_NONE == state) {
                session->ping_state = state;
                unset_ping_timeout(session);
                ping_arrived(session);
            }
            break;
        }
    }
    
    static void ping_new_session(h2_proxy_session *session, proxy_conn_rec *p_conn)
    {
        session->save_timeout = -1;
        session->ping_timeout = (p_conn->worker->s->ping_timeout_set?
                                 p_conn->worker->s->ping_timeout : -1);
        session->ping_state = H2_PING_ST_NONE;
        enter_ping_state(session, H2_PING_ST_AWAIT_ANY);
    }
    
    static void ping_reuse_session(h2_proxy_session *session)
    {
        if (H2_PING_ST_NONE == session->ping_state) {
            apr_interval_time_t age = apr_time_now() - session->last_frame_received;
            if (age > apr_time_from_sec(1)) {
                enter_ping_state(session, H2_PING_ST_AWAIT_PING);
            }
        }
    }
    
    static void ping_ev_frame_received(h2_proxy_session *session, const nghttp2_frame *frame)
    {
        session->last_frame_received = apr_time_now();
        switch (session->ping_state) {
        case H2_PING_ST_NONE:
            /* nop */
            break;
        case H2_PING_ST_AWAIT_ANY:
            enter_ping_state(session, H2_PING_ST_NONE);
            break;
        case H2_PING_ST_AWAIT_PING:
            if (NGHTTP2_PING == frame->hd.type) {
                enter_ping_state(session, H2_PING_ST_NONE);
            }
            /* we may receive many other frames while we are waiting for the
             * PING answer. They may come all from our connection buffers and
             * say nothing about the current state of the backend. */
            break;
        }
    }
    
    static apr_status_t proxy_session_pre_close(void *theconn)
    {
        proxy_conn_rec *p_conn = (proxy_conn_rec *)theconn;
        h2_proxy_session *session = p_conn->data;
    
        if (session && session->ngh2) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, 
                          "proxy_session(%s): pool cleanup, state=%d, streams=%d",
                          session->id, session->state, 
                          (int)h2_proxy_ihash_count(session->streams));
            session->aborted = 1;
            dispatch_event(session, H2_PROXYS_EV_PRE_CLOSE, 0, NULL);
            nghttp2_session_del(session->ngh2);
            session->ngh2 = NULL;
            p_conn->data = NULL;
        }
        return APR_SUCCESS;
    }
    
    static int proxy_pass_brigade(apr_bucket_alloc_t *bucket_alloc,
                                  proxy_conn_rec *p_conn,
                                  conn_rec *origin, apr_bucket_brigade *bb,
                                  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(bb, e);
        }
        apr_brigade_length(bb, 0, &transferred);
        if (transferred != -1)
            p_conn->worker->s->transferred += transferred;
        status = ap_pass_brigade(origin->output_filters, bb);
        /* Cleanup the brigade now to avoid buckets lifetime
         * issues in case of error returned below. */
        apr_brigade_cleanup(bb);
        if (status != APR_SUCCESS) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, origin, APLOGNO(03357)
                          "pass output failed to %pI (%s)",
                          p_conn->addr, p_conn->hostname);
        }
        return status;
    }
    
    static ssize_t raw_send(nghttp2_session *ngh2, const uint8_t *data,
                            size_t length, int flags, void *user_data)
    {
        h2_proxy_session *session = user_data;
        apr_bucket *b;
        apr_status_t status;
        int flush = 1;
    
        if (data) {
            b = apr_bucket_transient_create((const char*)data, length, 
                                            session->c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(session->output, b);
        }
    
        status = proxy_pass_brigade(session->c->bucket_alloc,  
                                    session->p_conn, session->c, 
                                    session->output, flush);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, session->c, 
                      "h2_proxy_sesssion(%s): raw_send %d bytes, flush=%d", 
                      session->id, (int)length, flush);
        if (status != APR_SUCCESS) {
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        return length;
    }
    
    static int on_frame_recv(nghttp2_session *ngh2, const nghttp2_frame *frame,
                             void *user_data) 
    {
        h2_proxy_session *session = user_data;
        h2_proxy_stream *stream;
        request_rec *r;
        int n;
        
        if (APLOGcdebug(session->c)) {
            char buffer[256];
            
            h2_proxy_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03341)
                          "h2_proxy_session(%s): recv FRAME[%s]",
                          session->id, buffer);
        }
    
        ping_ev_frame_received(session, frame);
        /* Action for frame types: */
        switch (frame->hd.type) {
            case NGHTTP2_HEADERS:
                stream = nghttp2_session_get_stream_user_data(ngh2, frame->hd.stream_id);
                if (!stream) {
                    return NGHTTP2_ERR_CALLBACK_FAILURE;
                }
                r = stream->r;
                if (r->status >= 100 && r->status < 200) {
                    /* By default, we will forward all interim responses when
                     * we are sitting on a HTTP/2 connection to the client */
                    int forward = session->h2_front;
                    switch(r->status) {
                        case 100:
                            if (stream->waiting_on_100) {
                                stream->waiting_on_100 = 0;
                                r->status_line = ap_get_status_line(r->status);
                                forward = 1;
                            } 
                            break;
                        case 103:
                            /* workaround until we get this into http protocol base
                             * parts. without this, unknown codes are converted to
                             * 500... */
                            r->status_line = "103 Early Hints";
                            break;
                        default:
                            r->status_line = ap_get_status_line(r->status);
                            break;
                    }
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03487) 
                                  "h2_proxy_session(%s): got interim HEADERS, "
                                  "status=%d, will forward=%d",
                                  session->id, r->status, forward);
                    if (forward) {
                        ap_send_interim_response(r, 1);
                    }
                }
                stream_resume(stream);
                break;
            case NGHTTP2_PING:
                break;
            case NGHTTP2_PUSH_PROMISE:
                break;
            case NGHTTP2_SETTINGS:
                if (frame->settings.niv > 0) {
                    n = nghttp2_session_get_remote_settings(ngh2, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
                    if (n > 0) {
                        session->remote_max_concurrent = n;
                    }
                }
                break;
            case NGHTTP2_GOAWAY:
                /* we expect the remote server to tell us the highest stream id
                 * that it has started processing. */
                session->last_stream_id = frame->goaway.last_stream_id;
                dispatch_event(session, H2_PROXYS_EV_REMOTE_GOAWAY, 0, NULL);
                break;
            default:
                break;
        }
        return 0;
    }
    
    static int before_frame_send(nghttp2_session *ngh2,
                                 const nghttp2_frame *frame, void *user_data)
    {
        h2_proxy_session *session = user_data;
        if (APLOGcdebug(session->c)) {
            char buffer[256];
    
            h2_proxy_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03343)
                          "h2_proxy_session(%s): sent FRAME[%s]",
                          session->id, buffer);
        }
        return 0;
    }
    
    static int add_header(void *table, const char *n, const char *v)
    {
        apr_table_add(table, n, v);
        return 1;
    }
    
    static void process_proxy_header(apr_table_t *headers, h2_proxy_stream *stream, 
                                     const char *n, const char *v)
    {
        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 }
        };
        request_rec *r = stream->r;
        proxy_dir_conf *dconf;
        int i;
        
        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
        if (!dconf->preserve_host) {
            for (i = 0; transform_hdrs[i].name; ++i) {
                if (!ap_cstr_casecmp(transform_hdrs[i].name, n)) {
                    apr_table_add(headers, n, (*transform_hdrs[i].func)(r, dconf, v));
                    return;
                }
            }
            if (!ap_cstr_casecmp("Link", n)) {
                dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
                apr_table_add(headers, n, h2_proxy_link_reverse_map(r, dconf, 
                                stream->real_server_uri, stream->p_server_uri, v));
                return;
            }
        }
        apr_table_add(headers, n, v);
    }
    
    static apr_status_t h2_proxy_stream_add_header_out(h2_proxy_stream *stream,
                                                       const char *n, apr_size_t nlen,
                                                       const char *v, apr_size_t vlen)
    {
        if (n[0] == ':') {
            if (!stream->data_received && !strncmp(":status", n, nlen)) {
                char *s = apr_pstrndup(stream->r->pool, v, vlen);
                
                apr_table_setn(stream->r->notes, "proxy-status", s);
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->cfront,
                              "h2_proxy_stream(%s-%d): got status %s", 
                              stream->session->id, stream->id, s);
                stream->r->status = (int)apr_atoi64(s);
                if (stream->r->status <= 0) {
                    stream->r->status = 500;
                    return APR_EGENERAL;
                }
            }
            return APR_SUCCESS;
        }
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->cfront,
                      "h2_proxy_stream(%s-%d): on_header %s: %s", 
                      stream->session->id, stream->id, n, v);
        if (!h2_proxy_res_ignore_header(n, nlen)) {
            char *hname, *hvalue;
            apr_table_t *headers = (stream->headers_ended? 
                                   stream->r->trailers_out : stream->r->headers_out);
        
            hname = apr_pstrndup(stream->pool, n, nlen);
            h2_proxy_util_camel_case_header(hname, nlen);
            hvalue = apr_pstrndup(stream->pool, v, vlen);
            
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->cfront,
                          "h2_proxy_stream(%s-%d): got header %s: %s", 
                          stream->session->id, stream->id, hname, hvalue);
            process_proxy_header(headers, stream, hname, hvalue);
        }
        return APR_SUCCESS;
    }
    
    static int log_header(void *ctx, const char *key, const char *value)
    {
        h2_proxy_stream *stream = ctx;
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, stream->r, 
                      "h2_proxy_stream(%s-%d), header_out %s: %s", 
                      stream->session->id, stream->id, key, value);
        return 1;
    }
    
    static void h2_proxy_stream_end_headers_out(h2_proxy_stream *stream) 
    {
        h2_proxy_session *session = stream->session;
        request_rec *r = stream->r;
        apr_pool_t *p = r->pool;
        const char *buf;
        
        /* Now, add in the cookies from the response to the ones already saved */
        apr_table_do(add_header, stream->saves, r->headers_out, "Set-Cookie", NULL);
        
        /* and now load 'em all in */
        if (!apr_is_empty_table(stream->saves)) {
            apr_table_unset(r->headers_out, "Set-Cookie");
            r->headers_out = apr_table_overlay(p, r->headers_out, stream->saves);
        }
    
        if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
            ap_set_content_type(r, apr_pstrdup(p, buf));
        }
        
        /* handle Via header in response */
        if (session->conf->viaopt != via_off 
            && session->conf->viaopt != via_block) {
            const char *server_name = ap_get_server_name(stream->r);
            apr_port_t port = ap_get_server_port(stream->r);
            char portstr[32];
            
            /* 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 doesn't make sense with Via: headers)
             * so we use the proxy vhost's name instead.
             */
            if (server_name == stream->r->hostname) {
                server_name = stream->r->server->server_hostname;
            }
            if (ap_is_default_port(port, stream->r)) {
                portstr[0] = '\0';
            }
            else {
                apr_snprintf(portstr, sizeof(portstr), ":%d", port);
            }
    
            /* create a "Via:" response header entry and merge it */
            apr_table_add(r->headers_out, "Via",
                           (session->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, 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, portstr)
                           );
        }
        if (r->status >= 200) stream->headers_ended = 1;
        
        if (APLOGrtrace2(stream->r)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, stream->r, 
                          "h2_proxy_stream(%s-%d), header_out after merging", 
                          stream->session->id, stream->id);
            apr_table_do(log_header, stream, stream->r->headers_out, NULL);
        }
    }
    
    static int stream_response_data(nghttp2_session *ngh2, uint8_t flags,
                                    int32_t stream_id, const uint8_t *data,
                                    size_t len, void *user_data) 
    {
        h2_proxy_session *session = user_data;
        h2_proxy_stream *stream;
        apr_bucket *b;
        apr_status_t status;
        
        stream = nghttp2_session_get_stream_user_data(ngh2, stream_id);
        if (!stream) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03358)
                         "h2_proxy_session(%s): recv data chunk for "
                         "unknown stream %d, ignored", 
                         session->id, stream_id);
            return 0;
        }
        
        if (!stream->data_received) {
            /* last chance to manipulate response headers.
             * after this, only trailers */
            h2_proxy_stream_end_headers_out(stream);
        }
        stream->data_received += len;
        b = apr_bucket_transient_create((const char*)data, len,
                                        stream->cfront->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(stream->output, b);
        /* always flush after a DATA frame, as we have no other indication
         * of buffer use */
        b = apr_bucket_flush_create(stream->cfront->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(stream->output, b);
    
        status = ap_pass_brigade(stream->r->output_filters, stream->output);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(03359)
                      "h2_proxy_session(%s): stream=%d, response DATA %ld, %ld"
                      " total", session->id, stream_id, (long)len,
                      (long)stream->data_received);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(03344)
                          "h2_proxy_session(%s): passing output on stream %d", 
                          session->id, stream->id);
            nghttp2_submit_rst_stream(ngh2, NGHTTP2_FLAG_NONE,
                                      stream_id, NGHTTP2_STREAM_CLOSED);
            return NGHTTP2_ERR_STREAM_CLOSING;
        }
        return 0;
    }
    
    static int on_stream_close(nghttp2_session *ngh2, int32_t stream_id,
                               uint32_t error_code, void *user_data) 
    {
        h2_proxy_session *session = user_data;
        h2_proxy_stream *stream;
        if (!session->aborted) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03360)
                          "h2_proxy_session(%s): stream=%d, closed, err=%d", 
                          session->id, stream_id, error_code);
            stream = h2_proxy_ihash_get(session->streams, stream_id);
            if (stream) {
                stream->error_code = error_code;
            }
            dispatch_event(session, H2_PROXYS_EV_STREAM_DONE, stream_id, NULL);
        }
        return 0;
    }
    
    static int on_header(nghttp2_session *ngh2, const nghttp2_frame *frame,
                         const uint8_t *namearg, size_t nlen,
                         const uint8_t *valuearg, size_t vlen, uint8_t flags,
                         void *user_data) 
    {
        h2_proxy_session *session = user_data;
        h2_proxy_stream *stream;
        const char *n = (const char*)namearg;
        const char *v = (const char*)valuearg;
        
        (void)session;
        if (frame->hd.type == NGHTTP2_HEADERS && nlen) {
            stream = nghttp2_session_get_stream_user_data(ngh2, frame->hd.stream_id);
            if (stream) {
                if (h2_proxy_stream_add_header_out(stream, n, nlen, v, vlen)) {
                    return NGHTTP2_ERR_CALLBACK_FAILURE;
                }
            }
        }
        else if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
        }
        
        return 0;
    }
    
    static ssize_t stream_request_data(nghttp2_session *ngh2, int32_t stream_id, 
                                       uint8_t *buf, size_t length,
                                       uint32_t *data_flags, 
                                       nghttp2_data_source *source, void *user_data)
    {
        h2_proxy_stream *stream;
        apr_status_t status = APR_SUCCESS;
        
        *data_flags = 0;
        stream = nghttp2_session_get_stream_user_data(ngh2, stream_id);
        if (!stream) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03361)
                         "h2_proxy_stream(NULL): data_read, stream %d not found", 
                         stream_id);
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        
        if (stream->session->ping_state != H2_PING_ST_NONE) {
            /* suspend until we hear from the other side */
            stream->waiting_on_ping = 1;
            status = APR_EAGAIN;
        }
        else if (stream->r->expecting_100) {
            /* suspend until the answer comes */
            stream->waiting_on_100 = 1;
            status = APR_EAGAIN;
        }
        else if (APR_BRIGADE_EMPTY(stream->input)) {
            status = ap_get_brigade(stream->r->input_filters, stream->input,
                                    AP_MODE_READBYTES, APR_NONBLOCK_READ,
                                    H2MAX(APR_BUCKET_BUFF_SIZE, length));
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, status, stream->r, 
                          "h2_proxy_stream(%s-%d): request body read", 
                          stream->session->id, stream->id);
        }
    
        if (status == APR_SUCCESS) {
            size_t readlen = 0;
            while (status == APR_SUCCESS 
                   && (readlen < length)
                   && !APR_BRIGADE_EMPTY(stream->input)) {
                apr_bucket* b = APR_BRIGADE_FIRST(stream->input);
                if (APR_BUCKET_IS_METADATA(b)) {
                    if (APR_BUCKET_IS_EOS(b)) {
                        *data_flags |= NGHTTP2_DATA_FLAG_EOF;
                    }
                    else {
                        /* we do nothing more regarding any meta here */
                    }
                }
                else {
                    const char *bdata = NULL;
                    apr_size_t blen = 0;
                    status = apr_bucket_read(b, &bdata, &blen, APR_BLOCK_READ);
                    
                    if (status == APR_SUCCESS && blen > 0) {
                        size_t copylen = H2MIN(length - readlen, blen);
                        memcpy(buf, bdata, copylen);
                        buf += copylen;
                        readlen += copylen;
                        if (copylen < blen) {
                            /* We have data left in the bucket. Split it. */
                            status = apr_bucket_split(b, copylen);
                        }
                    }
                }
                apr_bucket_delete(b);
            }
    
            stream->data_sent += readlen;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(03468) 
                          "h2_proxy_stream(%d): request DATA %ld, %ld"
                          " total, flags=%d", stream->id, (long)readlen, (long)stream->data_sent,
                          (int)*data_flags);
            if ((*data_flags & NGHTTP2_DATA_FLAG_EOF) && !apr_is_empty_table(stream->r->trailers_in)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(10179) 
                              "h2_proxy_stream(%d): submit trailers", stream->id);
                *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
                submit_trailers(stream);
            } 
            return readlen;
        }
        else if (APR_STATUS_IS_EAGAIN(status)) {
            /* suspended stream, needs to be re-awakened */
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, status, stream->r, 
                          "h2_proxy_stream(%s-%d): suspending", 
                          stream->session->id, stream_id);
            stream->suspended = 1;
            h2_proxy_iq_add(stream->session->suspended, stream->id, NULL, NULL);
            return NGHTTP2_ERR_DEFERRED;
        }
        else {
            nghttp2_submit_rst_stream(ngh2, NGHTTP2_FLAG_NONE, 
                                      stream_id, NGHTTP2_STREAM_CLOSED);
            return NGHTTP2_ERR_STREAM_CLOSING;
        }
    }
    
    #ifdef H2_NG2_INVALID_HEADER_CB
    static int on_invalid_header_cb(nghttp2_session *ngh2,
                                    const nghttp2_frame *frame, 
                                    const uint8_t *name, size_t namelen, 
                                    const uint8_t *value, size_t valuelen, 
                                    uint8_t flags, void *user_data)
    {
        h2_proxy_session *session = user_data;
        if (APLOGcdebug(session->c)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03469)
                          "h2_proxy_session(%s-%d): denying stream with invalid header "
                          "'%s: %s'", session->id, (int)frame->hd.stream_id,
                          apr_pstrndup(session->pool, (const char *)name, namelen),
                          apr_pstrndup(session->pool, (const char *)value, valuelen));
        }
        return nghttp2_submit_rst_stream(session->ngh2, NGHTTP2_FLAG_NONE,
                                         frame->hd.stream_id, 
                                         NGHTTP2_PROTOCOL_ERROR);
    }
    #endif
    
    h2_proxy_session *h2_proxy_session_setup(const char *id, proxy_conn_rec *p_conn,
                                             proxy_server_conf *conf,
                                             int h2_front, 
                                             unsigned char window_bits_connection,
                                             unsigned char window_bits_stream,
                                             h2_proxy_request_done *done)
    {
        if (!p_conn->data) {
            apr_pool_t *pool = p_conn->scpool;
            h2_proxy_session *session;
            nghttp2_session_callbacks *cbs;
            nghttp2_option *option;
    
            session = apr_pcalloc(pool, sizeof(*session));
            apr_pool_pre_cleanup_register(pool, p_conn, proxy_session_pre_close);
            p_conn->data = session;
            
            session->id = apr_pstrdup(p_conn->scpool, id);
            session->c = p_conn->connection;
            session->p_conn = p_conn;
            session->conf = conf;
            session->pool = p_conn->scpool;
            session->state = H2_PROXYS_ST_INIT;
            session->h2_front = h2_front;
            session->window_bits_stream = window_bits_stream;
            session->window_bits_connection = window_bits_connection;
            session->streams = h2_proxy_ihash_create(pool, offsetof(h2_proxy_stream, id));
            session->suspended = h2_proxy_iq_create(pool, 5);
            session->done = done;
        
            session->input = apr_brigade_create(session->pool, session->c->bucket_alloc);
            session->output = apr_brigade_create(session->pool, session->c->bucket_alloc);
        
            nghttp2_session_callbacks_new(&cbs);
            nghttp2_session_callbacks_set_on_frame_recv_callback(cbs, on_frame_recv);
            nghttp2_session_callbacks_set_on_data_chunk_recv_callback(cbs, stream_response_data);
            nghttp2_session_callbacks_set_on_stream_close_callback(cbs, on_stream_close);
            nghttp2_session_callbacks_set_on_header_callback(cbs, on_header);
            nghttp2_session_callbacks_set_before_frame_send_callback(cbs, before_frame_send);
            nghttp2_session_callbacks_set_send_callback(cbs, raw_send);
    #ifdef H2_NG2_INVALID_HEADER_CB
            nghttp2_session_callbacks_set_on_invalid_header_callback(cbs, on_invalid_header_cb);
    #endif
            nghttp2_option_new(&option);
            nghttp2_option_set_peer_max_concurrent_streams(option, 100);
            nghttp2_option_set_no_auto_window_update(option, 0);
            
            nghttp2_session_client_new2(&session->ngh2, cbs, session, option);
            
            nghttp2_option_del(option);
            nghttp2_session_callbacks_del(cbs);
    
            ping_new_session(session, p_conn);
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03362)
                          "setup session for %s", p_conn->hostname);
        }
        else {
            h2_proxy_session *session = p_conn->data;
            ping_reuse_session(session);
        }
        return p_conn->data;
    }
    
    static apr_status_t session_start(h2_proxy_session *session) 
    {
        nghttp2_settings_entry settings[2];
        int rv, add_conn_window;
        apr_socket_t *s;
        
        s = ap_get_conn_socket(session->c);
    #if !defined(WIN32) && !defined(NETWARE)
        if (s) {
            ap_sock_disable_nagle(s);
        }
    #endif
        
        settings[0].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
        settings[0].value = 0;
        settings[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
        settings[1].value = (1 << session->window_bits_stream) - 1;
        
        rv = nghttp2_submit_settings(session->ngh2, NGHTTP2_FLAG_NONE, settings, 
                                     H2_ALEN(settings));
        
        /* If the connection window is larger than our default, trigger a WINDOW_UPDATE */
        add_conn_window = ((1 << session->window_bits_connection) - 1 -
                           NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE);
        if (!rv && add_conn_window != 0) {
            rv = nghttp2_submit_window_update(session->ngh2, NGHTTP2_FLAG_NONE, 0, add_conn_window);
        }
        return rv? APR_EGENERAL : APR_SUCCESS;
    }
    
    static apr_status_t open_stream(h2_proxy_session *session, const char *url,
                                    request_rec *r, int standalone,
                                    h2_proxy_stream **pstream)
    {
        h2_proxy_stream *stream;
        apr_uri_t puri;
        const char *authority, *scheme, *path, *orig_host;
        apr_status_t status;
        proxy_dir_conf *dconf;
    
        stream = apr_pcalloc(r->pool, sizeof(*stream));
    
        stream->pool = r->pool;
        stream->url = url;
        stream->r = r;
        stream->cfront = r->connection;
        stream->standalone = standalone;
        stream->session = session;
        stream->state = H2_STREAM_ST_IDLE;
        
        stream->input = apr_brigade_create(stream->pool, stream->cfront->bucket_alloc);
        stream->output = apr_brigade_create(stream->pool, stream->cfront->bucket_alloc);
        
        stream->req = h2_proxy_req_create(1, stream->pool);
    
        status = apr_uri_parse(stream->pool, url, &puri);
        if (status != APR_SUCCESS)
            return status;
        
        scheme = (strcmp(puri.scheme, "h2")? "http" : "https");
        orig_host = apr_table_get(r->headers_in, "Host");
        if (orig_host == NULL) {
            orig_host = r->hostname;
        }
    
        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
        if (dconf->preserve_host) {
            authority = orig_host;
            if (!authority) {
                /* Duplicate mod_proxy behaviour if ProxyPreserveHost is
                 * used but an "HTTP/0.9" request is received without a
                 * Host: header */
                authority = r->server->server_hostname;
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10511)
                              "HTTP/0.9 request (with no host line) "
                              "on incoming request and preserve host set "
                              "forcing hostname to be %s for uri %s",
                              authority, r->uri);
                apr_table_setn(r->headers_in, "Host", authority);
            }
        }
        else {
            authority = puri.hostname;
            if (!ap_strchr_c(authority, ':') && puri.port
                && apr_uri_port_of_scheme(scheme) != puri.port) {
                /* port info missing and port is not default for scheme: append */
                authority = apr_psprintf(stream->pool, "%s:%d", authority, puri.port);
            }
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->cfront,
                          "authority=%s from uri.hostname=%s and uri.port=%d",
                          authority, puri.hostname, puri.port);
        }
        /* See #235, we use only :authority when available and remove Host:
         * since differing values are not acceptable, see RFC 9113 ch. 8.3.1 */
        if (authority && strlen(authority)) {
            apr_table_unset(r->headers_in, "Host");
        }
    
        /* we need this for mapping relative uris in headers ("Link") back
         * to local uris */
        stream->real_server_uri = apr_psprintf(stream->pool, "%s://%s", scheme, authority); 
        stream->p_server_uri = apr_psprintf(stream->pool, "%s://%s", puri.scheme, authority); 
        path = apr_uri_unparse(stream->pool, &puri, APR_URI_UNP_OMITSITEPART);
    
        h2_proxy_req_make(stream->req, stream->pool, r->method, scheme,
                    authority, path, r->headers_in);
    
        if (dconf->add_forwarded_headers) {
            if (PROXYREQ_REVERSE == r->proxyreq) {
                /* Add X-Forwarded-For: so that the upstream has a chance to
                 * determine, where the original request came from.
                 */
                apr_table_mergen(stream->req->headers, "X-Forwarded-For",
                                 r->useragent_ip);
    
                /* Add X-Forwarded-Host: so that upstream knows what the
                 * original request hostname was.
                 */
                if (orig_host) {
                    apr_table_mergen(stream->req->headers, "X-Forwarded-Host",
                                     orig_host);
                }
    
                /* 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(stream->req->headers, "X-Forwarded-Server",
                                 r->server->server_hostname);
            }
        }
    
        /* Tuck away all already existing cookies */
        stream->saves = apr_table_make(r->pool, 2);
        apr_table_do(add_header, stream->saves, r->headers_out, "Set-Cookie", NULL);
    
        *pstream = stream;
        
        return APR_SUCCESS;
    }
    
    static apr_status_t submit_stream(h2_proxy_session *session, h2_proxy_stream *stream)
    {
        h2_proxy_ngheader *hd;
        nghttp2_data_provider *pp = NULL;
        nghttp2_data_provider provider;
        int rv, may_have_request_body = 1;
        apr_status_t status;
    
        hd = h2_proxy_util_nghd_make_req(stream->pool, stream->req);
        
        /* If we expect a 100-continue response, we must refrain from reading
           any input until we get it. Reading the input will possibly trigger
           HTTP_IN filter to generate the 100-continue itself. */
        if (stream->waiting_on_100 || stream->waiting_on_ping) {
            /* make a small test if we get an EOF/EOS immediately */
            status = ap_get_brigade(stream->r->input_filters, stream->input,
                                    AP_MODE_READBYTES, APR_NONBLOCK_READ,
                                    APR_BUCKET_BUFF_SIZE);
            may_have_request_body = APR_STATUS_IS_EAGAIN(status)
                                    || (status == APR_SUCCESS 
                                        && !APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(stream->input)));
        }
        
        if (may_have_request_body) {
            provider.source.fd = 0;
            provider.source.ptr = NULL;
            provider.read_callback = stream_request_data;
            pp = &provider;
        }
    
        rv = nghttp2_submit_request(session->ngh2, NULL, 
                                    hd->nv, hd->nvlen, pp, stream);
                                    
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, stream->cfront, APLOGNO(03363)
                      "h2_proxy_session(%s): submit %s%s -> %d", 
                      session->id, stream->req->authority, stream->req->path,
                      rv);
        if (rv > 0) {
            stream->id = rv;
            stream->state = H2_STREAM_ST_OPEN;
            h2_proxy_ihash_add(session->streams, stream);
            dispatch_event(session, H2_PROXYS_EV_STREAM_SUBMITTED, rv, NULL);
            
            return APR_SUCCESS;
        }
        return APR_EGENERAL;
    }
    
    static apr_status_t submit_trailers(h2_proxy_stream *stream)
    {
        h2_proxy_ngheader *hd;
        int rv;
    
        hd = h2_proxy_util_nghd_make(stream->pool, stream->r->trailers_in);
        rv = nghttp2_submit_trailer(stream->session->ngh2, stream->id, hd->nv, hd->nvlen);
        return rv == 0? APR_SUCCESS: APR_EGENERAL;
    }
    
    static apr_status_t feed_brigade(h2_proxy_session *session, apr_bucket_brigade *bb)
    {
        apr_status_t status = APR_SUCCESS;
        apr_size_t readlen = 0;
        ssize_t n;
    
        while (status == APR_SUCCESS && !APR_BRIGADE_EMPTY(bb)) {
            apr_bucket* b = APR_BRIGADE_FIRST(bb);
            
            if (APR_BUCKET_IS_METADATA(b)) {
                /* nop */
            }
            else {
                const char *bdata = NULL;
                apr_size_t blen = 0;
                
                status = apr_bucket_read(b, &bdata, &blen, APR_BLOCK_READ);
                if (status == APR_SUCCESS && blen > 0) {
                    n = nghttp2_session_mem_recv(session->ngh2, (const uint8_t *)bdata, blen);
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, 
                                  "h2_proxy_session(%s): feeding %ld bytes -> %ld", 
                                  session->id, (long)blen, (long)n);
                    if (n < 0) {
                        if (nghttp2_is_fatal((int)n)) {
                            status = APR_EGENERAL;
                        }
                    }
                    else {
                        size_t rlen = (size_t)n;
                        readlen += rlen;
                        if (rlen < blen) {
                            apr_bucket_split(b, rlen);
                        }
                    }
                }
            }
            apr_bucket_delete(b);
        }
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, session->c, 
                      "h2_proxy_session(%s): fed %ld bytes of input to session", 
                      session->id, (long)readlen);
        if (readlen == 0 && status == APR_SUCCESS) {
            return APR_EAGAIN;
        }
        return status;
    }
    
    static apr_status_t h2_proxy_session_read(h2_proxy_session *session, int block, 
                                              apr_interval_time_t timeout)
    {
        apr_status_t status = APR_SUCCESS;
        
        if (APR_BRIGADE_EMPTY(session->input)) {
            apr_socket_t *socket = NULL;
            apr_time_t save_timeout = -1;
            
            if (block && timeout > 0) {
                socket = ap_get_conn_socket(session->c);
                if (socket) {
                    apr_socket_timeout_get(socket, &save_timeout);
                    apr_socket_timeout_set(socket, timeout);
                }
                else {
                    /* cannot block on timeout */
                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, session->c, APLOGNO(03379)
                                  "h2_proxy_session(%s): unable to get conn socket", 
                                  session->id);
                    return APR_ENOTIMPL;
                }
            }
            
            status = ap_get_brigade(session->c->input_filters, session->input, 
                                    AP_MODE_READBYTES, 
                                    block? APR_BLOCK_READ : APR_NONBLOCK_READ, 
                                    64 * 1024);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, session->c, 
                          "h2_proxy_session(%s): read from conn", session->id);
            if (socket && save_timeout != -1) {
                apr_socket_timeout_set(socket, save_timeout);
            }
        }
        
        if (status == APR_SUCCESS) {
            status = feed_brigade(session, session->input);
        }
        else if (APR_STATUS_IS_TIMEUP(status)) {
            /* nop */
        }
        else if (!APR_STATUS_IS_EAGAIN(status)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c, APLOGNO(03380)
                          "h2_proxy_session(%s): read error", session->id);
            dispatch_event(session, H2_PROXYS_EV_CONN_ERROR, status, NULL);
        }
    
        return status;
    }
    
    apr_status_t h2_proxy_session_submit(h2_proxy_session *session, 
                                         const char *url, request_rec *r,
                                         int standalone)
    {
        h2_proxy_stream *stream;
        apr_status_t status;
        
        status = open_stream(session, url, r, standalone, &stream);
        if (status == APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03381)
                          "process stream(%d): %s %s%s, original: %s", 
                          stream->id, stream->req->method, 
                          stream->req->authority, stream->req->path, 
                          r->the_request);
            status = submit_stream(session, stream);
        }
        return status;
    }
    
    static void stream_resume(h2_proxy_stream *stream)
    {
        h2_proxy_session *session = stream->session;
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->cfront,
                      "h2_proxy_stream(%s-%d): resuming", 
                      session->id, stream->id);
        stream->suspended = 0;
        h2_proxy_iq_remove(session->suspended, stream->id);
        nghttp2_session_resume_data(session->ngh2, stream->id);
        dispatch_event(session, H2_PROXYS_EV_STREAM_RESUMED, 0, NULL);
    }
    
    static int is_waiting_for_backend(h2_proxy_session *session)
    {
        return ((session->ping_state != H2_PING_ST_NONE) 
                || ((session->suspended->nelts <= 0)
                    && !nghttp2_session_want_write(session->ngh2)
                    && nghttp2_session_want_read(session->ngh2)));
    }
    
    static apr_status_t check_suspended(h2_proxy_session *session)
    {
        h2_proxy_stream *stream;
        int i, stream_id;
        apr_status_t status;
        
        for (i = 0; i < session->suspended->nelts; ++i) {
            stream_id = session->suspended->elts[i];
            stream = nghttp2_session_get_stream_user_data(session->ngh2, stream_id);
            if (stream) {
                if (stream->waiting_on_100 || stream->waiting_on_ping) {
                    status = APR_EAGAIN;
                }
                else {
                    status = ap_get_brigade(stream->r->input_filters, stream->input,
                                            AP_MODE_READBYTES, APR_NONBLOCK_READ,
                                            APR_BUCKET_BUFF_SIZE);
                }
                if (status == APR_SUCCESS && !APR_BRIGADE_EMPTY(stream->input)) {
                    stream_resume(stream);
                    check_suspended(session);
                    return APR_SUCCESS;
                }
                else if (status != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(status)) {
                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, status, stream->cfront,
                                  APLOGNO(03382) "h2_proxy_stream(%s-%d): check input", 
                                  session->id, stream_id);
                    stream_resume(stream);
                    check_suspended(session);
                    return APR_SUCCESS;
                }
            }
            else {
                /* gone? */
                h2_proxy_iq_remove(session->suspended, stream_id);
                check_suspended(session);
                return APR_SUCCESS;
            }
        }
        return APR_EAGAIN;
    }
    
    static apr_status_t session_shutdown(h2_proxy_session *session, int reason, 
                                         const char *msg)
    {
        apr_status_t status = APR_SUCCESS;
        const char *err = msg;
        
        ap_assert(session);
        if (!err && reason) {
            err = nghttp2_strerror(reason);
        }
        nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, 0,
                              reason, (uint8_t*)err, err? strlen(err):0);
        status = nghttp2_session_send(session->ngh2);
        dispatch_event(session, H2_PROXYS_EV_LOCAL_GOAWAY, reason, err);
        return status;
    }
    
    
    static const char *StateNames[] = {
        "INIT",      /* H2_PROXYS_ST_INIT */
        "DONE",      /* H2_PROXYS_ST_DONE */
        "IDLE",      /* H2_PROXYS_ST_IDLE */
        "BUSY",      /* H2_PROXYS_ST_BUSY */
        "WAIT",      /* H2_PROXYS_ST_WAIT */
        "LSHUTDOWN", /* H2_PROXYS_ST_LOCAL_SHUTDOWN */
        "RSHUTDOWN", /* H2_PROXYS_ST_REMOTE_SHUTDOWN */
    };
    
    static const char *state_name(h2_proxys_state state)
    {
        if (state >= (sizeof(StateNames)/sizeof(StateNames[0]))) {
            return "unknown";
        }
        return StateNames[state];
    }
    
    static int is_accepting_streams(h2_proxy_session *session)
    {
        switch (session->state) {
            case H2_PROXYS_ST_IDLE:
            case H2_PROXYS_ST_BUSY:
            case H2_PROXYS_ST_WAIT:
                return 1;
            default:
                return 0;
        }
    }
    
    static void transit(h2_proxy_session *session, const char *action, 
                        h2_proxys_state nstate)
    {
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03345)
                      "h2_proxy_session(%s): transit [%s] -- %s --> [%s]", session->id,
                      state_name(session->state), action, state_name(nstate));
        session->state = nstate;
    }
    
    static void ev_init(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_INIT:
                if (h2_proxy_ihash_empty(session->streams)) {
                    transit(session, "init", H2_PROXYS_ST_IDLE);
                }
                else {
                    transit(session, "init", H2_PROXYS_ST_BUSY);
                }
                break;
    
            default:
                /* nop */
                break;
        }
    }
    
    static void ev_local_goaway(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
                /* already did that? */
                break;
            case H2_PROXYS_ST_IDLE:
            case H2_PROXYS_ST_REMOTE_SHUTDOWN:
                /* all done */
                transit(session, "local goaway", H2_PROXYS_ST_DONE);
                break;
            default:
                transit(session, "local goaway", H2_PROXYS_ST_LOCAL_SHUTDOWN);
                break;
        }
    }
    
    static void ev_remote_goaway(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_REMOTE_SHUTDOWN:
                /* already received that? */
                break;
            case H2_PROXYS_ST_IDLE:
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
                /* all done */
                transit(session, "remote goaway", H2_PROXYS_ST_DONE);
                break;
            default:
                transit(session, "remote goaway", H2_PROXYS_ST_REMOTE_SHUTDOWN);
                break;
        }
    }
    
    static void ev_conn_error(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_INIT:
            case H2_PROXYS_ST_DONE:
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
                /* just leave */
                transit(session, "conn error", H2_PROXYS_ST_DONE);
                break;
            
            default:
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, arg, session->c,
                              "h2_proxy_session(%s): conn error -> shutdown", session->id);
                session_shutdown(session, arg, msg);
                break;
        }
    }
    
    static void ev_proto_error(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_DONE:
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
                /* just leave */
                transit(session, "proto error", H2_PROXYS_ST_DONE);
                break;
            
            default:
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
                              "h2_proxy_session(%s): proto error -> shutdown", session->id);
                session_shutdown(session, arg, msg);
                break;
        }
    }
    
    static void ev_conn_timeout(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
                transit(session, "conn timeout", H2_PROXYS_ST_DONE);
                break;
            default:
                session_shutdown(session, arg, msg);
                transit(session, "conn timeout", H2_PROXYS_ST_DONE);
                break;
        }
    }
    
    static void ev_no_io(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_BUSY:
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
            case H2_PROXYS_ST_REMOTE_SHUTDOWN:
                /* nothing for input and output to do. If we remain
                 * in this state, we go into a tight loop and suck up
                 * CPU cycles. Ideally, we'd like to do a blocking read, but that
                 * is not possible if we have scheduled tasks and wait
                 * for them to produce something. */
                if (h2_proxy_ihash_empty(session->streams)) {
                    if (!is_accepting_streams(session)) {
                        /* We are no longer accepting new streams and have
                         * finished processing existing ones. Time to leave. */
                        session_shutdown(session, arg, msg);
                        transit(session, "no io", H2_PROXYS_ST_DONE);
                    }
                    else {
                        /* When we have no streams, no task events are possible,
                         * switch to blocking reads */
                        transit(session, "no io", H2_PROXYS_ST_IDLE);
                    }
                }
                else {
                    /* Unable to do blocking reads, as we wait on events from
                     * task processing in other threads. Do a busy wait with
                     * backoff timer. */
                    transit(session, "no io", H2_PROXYS_ST_WAIT);
                }
                break;
            default:
                /* nop */
                break;
        }
    }
    
    static void ev_stream_submitted(h2_proxy_session *session, int stream_id, 
                                    const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_IDLE:
            case H2_PROXYS_ST_WAIT:
                transit(session, "stream submitted", H2_PROXYS_ST_BUSY);
                break;
            default:
                /* nop */
                break;
        }
    }
    
    static void ev_stream_done(h2_proxy_session *session, int stream_id, 
                               const char *msg)
    {
        h2_proxy_stream *stream;
        apr_bucket *b;
    
        stream = nghttp2_session_get_stream_user_data(session->ngh2, stream_id);
        if (stream) {
            /* if the stream's connection is aborted, do not send anything
             * more on it. */
            apr_status_t status = (stream->error_code == 0)? APR_SUCCESS : APR_EINVAL;
            int touched = (stream->data_sent || stream->data_received ||
                           stream_id <= session->last_stream_id);
            if (!stream->cfront->aborted) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, stream->cfront, APLOGNO(03364)
                              "h2_proxy_sesssion(%s): stream(%d) closed "
                              "(touched=%d, error=%d)",
                              session->id, stream_id, touched, stream->error_code);
    
                if (status != APR_SUCCESS) {
                  /* stream failed. If we have received (and forwarded) response
                   * data already, we need to append an error buckt to inform
                   * consumers.
                   * Otherwise, we have an early fail on the connection and may
                   * retry this request on a new one. In that case, keep the
                   * output virgin so that a new attempt can be made. */
                  if (stream->data_received) {
                    int http_status = ap_map_http_request_error(status, HTTP_BAD_REQUEST);
                    b = ap_bucket_error_create(http_status, NULL, stream->r->pool,
                                               stream->cfront->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(stream->output, b);
                    b = apr_bucket_eos_create(stream->cfront->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(stream->output, b);
                    ap_pass_brigade(stream->r->output_filters, stream->output);
                  }
                }
                else if (!stream->data_received) {
                    /* if the response had no body, this is the time to flush
                     * an empty brigade which will also write the response headers */
                    h2_proxy_stream_end_headers_out(stream);
                    stream->data_received = 1;
                    b = apr_bucket_flush_create(stream->cfront->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(stream->output, b);
                    b = apr_bucket_eos_create(stream->cfront->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(stream->output, b);
                    ap_pass_brigade(stream->r->output_filters, stream->output);
                }
            }
    
            stream->state = H2_STREAM_ST_CLOSED;
            h2_proxy_ihash_remove(session->streams, stream_id);
            h2_proxy_iq_remove(session->suspended, stream_id);
            if (session->done) {
                session->done(session, stream->r, status, touched, stream->error_code);
            }
        }
        
        switch (session->state) {
            default:
                /* nop */
                break;
        }
    }
    
    static void ev_stream_resumed(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_WAIT:
                transit(session, "stream resumed", H2_PROXYS_ST_BUSY);
                break;
            default:
                /* nop */
                break;
        }
    }
    
    static void ev_data_read(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_IDLE:
            case H2_PROXYS_ST_WAIT:
                transit(session, "data read", H2_PROXYS_ST_BUSY);
                break;
            default:
                /* nop */
                break;
        }
    }
    
    static void ev_ngh2_done(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_DONE:
                /* nop */
                break;
            default:
                transit(session, "nghttp2 done", H2_PROXYS_ST_DONE);
                break;
        }
    }
    
    static void ev_pre_close(h2_proxy_session *session, int arg, const char *msg)
    {
        switch (session->state) {
            case H2_PROXYS_ST_DONE:
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
                /* nop */
                break;
            default:
                session_shutdown(session, arg, msg);
                break;
        }
    }
    
    static void dispatch_event(h2_proxy_session *session, h2_proxys_event_t ev, 
                               int arg, const char *msg)
    {
        switch (ev) {
            case H2_PROXYS_EV_INIT:
                ev_init(session, arg, msg);
                break;            
            case H2_PROXYS_EV_LOCAL_GOAWAY:
                ev_local_goaway(session, arg, msg);
                break;
            case H2_PROXYS_EV_REMOTE_GOAWAY:
                ev_remote_goaway(session, arg, msg);
                break;
            case H2_PROXYS_EV_CONN_ERROR:
                ev_conn_error(session, arg, msg);
                break;
            case H2_PROXYS_EV_PROTO_ERROR:
                ev_proto_error(session, arg, msg);
                break;
            case H2_PROXYS_EV_CONN_TIMEOUT:
                ev_conn_timeout(session, arg, msg);
                break;
            case H2_PROXYS_EV_NO_IO:
                ev_no_io(session, arg, msg);
                break;
            case H2_PROXYS_EV_STREAM_SUBMITTED:
                ev_stream_submitted(session, arg, msg);
                break;
            case H2_PROXYS_EV_STREAM_DONE:
                ev_stream_done(session, arg, msg);
                break;
            case H2_PROXYS_EV_STREAM_RESUMED:
                ev_stream_resumed(session, arg, msg);
                break;
            case H2_PROXYS_EV_DATA_READ:
                ev_data_read(session, arg, msg);
                break;
            case H2_PROXYS_EV_NGH2_DONE:
                ev_ngh2_done(session, arg, msg);
                break;
            case H2_PROXYS_EV_PRE_CLOSE:
                ev_pre_close(session, arg, msg);
                break;
            default:
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
                              "h2_proxy_session(%s): unknown event %d", 
                              session->id, ev);
                break;
        }
    }
    
    static int send_loop(h2_proxy_session *session)
    {
        while (nghttp2_session_want_write(session->ngh2)) {
            int rv = nghttp2_session_send(session->ngh2);
            if (rv < 0 && nghttp2_is_fatal(rv)) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c, 
                              "h2_proxy_session(%s): write, rv=%d", session->id, rv);
                dispatch_event(session, H2_PROXYS_EV_CONN_ERROR, rv, NULL);
                break;
            }
            return 1;
        }
        return 0;
    }
    
    apr_status_t h2_proxy_session_process(h2_proxy_session *session)
    {
        apr_status_t status;
        int have_written = 0, have_read = 0;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c, 
                      "h2_proxy_session(%s): process", session->id);
               
    run_loop:
        switch (session->state) {
            case H2_PROXYS_ST_INIT:
                status = session_start(session);
                if (status == APR_SUCCESS) {
                    dispatch_event(session, H2_PROXYS_EV_INIT, 0, NULL);
                    goto run_loop;
                }
                else {
                    dispatch_event(session, H2_PROXYS_EV_CONN_ERROR, status, NULL);
                }
                break;
                
            case H2_PROXYS_ST_BUSY:
            case H2_PROXYS_ST_LOCAL_SHUTDOWN:
            case H2_PROXYS_ST_REMOTE_SHUTDOWN:
                have_written = send_loop(session);
                
                if (nghttp2_session_want_read(session->ngh2)) {
                    status = h2_proxy_session_read(session, 0, 0);
                    if (status == APR_SUCCESS) {
                        have_read = 1;
                    }
                }
                
                if (!have_written && !have_read 
                    && !nghttp2_session_want_write(session->ngh2)) {
                    dispatch_event(session, H2_PROXYS_EV_NO_IO, 0, NULL);
                    goto run_loop;
                }
                break;
                
            case H2_PROXYS_ST_WAIT:
                if (is_waiting_for_backend(session)) {
                    /* we can do a blocking read with the default timeout (as
                     * configured via ProxyTimeout in our socket. There is
                     * nothing we want to send or check until we get more data
                     * from the backend. */
                    status = h2_proxy_session_read(session, 1, 0);
                    if (status == APR_SUCCESS) {
                        have_read = 1;
                        dispatch_event(session, H2_PROXYS_EV_DATA_READ, 0, NULL);
                    }
                    else {
                        dispatch_event(session, H2_PROXYS_EV_CONN_ERROR, status, NULL);
                        return status;
                    }
                }
                else if (check_suspended(session) == APR_EAGAIN) {
                    /* no stream has become resumed. Do a blocking read with
                     * ever increasing timeouts... */
                    if (session->wait_timeout < 25) {
                        session->wait_timeout = 25;
                    }
                    else {
                        session->wait_timeout = H2MIN(apr_time_from_msec(100), 
                                                      2*session->wait_timeout);
                    }
                    
                    status = h2_proxy_session_read(session, 1, session->wait_timeout);
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, session->c, 
                                  APLOGNO(03365)
                                  "h2_proxy_session(%s): WAIT read, timeout=%fms", 
                                  session->id, session->wait_timeout/1000.0);
                    if (status == APR_SUCCESS) {
                        have_read = 1;
                        dispatch_event(session, H2_PROXYS_EV_DATA_READ, 0, NULL);
                    }
                    else if (APR_STATUS_IS_TIMEUP(status)
                        || APR_STATUS_IS_EAGAIN(status)) {
                        /* go back to checking all inputs again */
                        transit(session, "wait cycle", H2_PROXYS_ST_BUSY);
                    }
                }
                break;
                
            case H2_PROXYS_ST_IDLE:
                break;
    
            case H2_PROXYS_ST_DONE: /* done, session terminated */
                return APR_EOF;
                
            default:
                ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, session->c,
                              APLOGNO(03346)"h2_proxy_session(%s): unknown state %d", 
                              session->id, session->state);
                dispatch_event(session, H2_PROXYS_EV_PROTO_ERROR, 0, NULL);
                break;
        }
    
    
        if (have_read || have_written) {
            session->wait_timeout = 0;
        }
        
        if (!nghttp2_session_want_read(session->ngh2)
            && !nghttp2_session_want_write(session->ngh2)) {
            dispatch_event(session, H2_PROXYS_EV_NGH2_DONE, 0, NULL);
        }
        
        return APR_SUCCESS; /* needs to be called again */
    }
    
    typedef struct {
        h2_proxy_session *session;
        h2_proxy_request_done *done;
    } cleanup_iter_ctx;
    
    static int cancel_iter(void *udata, void *val)
    {
        cleanup_iter_ctx *ctx = udata;
        h2_proxy_stream *stream = val;
        nghttp2_submit_rst_stream(ctx->session->ngh2, NGHTTP2_FLAG_NONE,
                                  stream->id, 0);
        return 1;
    }
    
    void h2_proxy_session_cancel_all(h2_proxy_session *session)
    {
        if (!h2_proxy_ihash_empty(session->streams)) {
            cleanup_iter_ctx ctx;
            ctx.session = session;
            ctx.done = session->done;
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03366)
                          "h2_proxy_session(%s): cancel  %d streams",
                          session->id, (int)h2_proxy_ihash_count(session->streams));
            h2_proxy_ihash_iter(session->streams, cancel_iter, &ctx);
            session_shutdown(session, 0, NULL);
        }
    }
    
    static int done_iter(void *udata, void *val)
    {
        cleanup_iter_ctx *ctx = udata;
        h2_proxy_stream *stream = val;
        int touched = (stream->data_sent || stream->data_received ||
                       stream->id <= ctx->session->last_stream_id);
        ctx->done(ctx->session, stream->r, APR_ECONNABORTED, touched, stream->error_code);
        return 1;
    }
    
    void h2_proxy_session_cleanup(h2_proxy_session *session, 
                                  h2_proxy_request_done *done)
    {
        if (!h2_proxy_ihash_empty(session->streams)) {
            cleanup_iter_ctx ctx;
            ctx.session = session;
            ctx.done = done;
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03519)
                          "h2_proxy_session(%s): terminated, %d streams unfinished",
                          session->id, (int)h2_proxy_ihash_count(session->streams));
            h2_proxy_ihash_iter(session->streams, done_iter, &ctx);
            h2_proxy_ihash_clear(session->streams);
        }
    }
    
    int h2_proxy_session_is_reusable(h2_proxy_session *session)
    {
        return (session->state != H2_PROXYS_ST_DONE) &&
               h2_proxy_ihash_empty(session->streams);
    }
    
    static int ping_arrived_iter(void *udata, void *val)
    {
        h2_proxy_stream *stream = val;
        if (stream->waiting_on_ping) {
            stream->waiting_on_ping = 0;
            stream_resume(stream);
        }
        return 1;
    }
    
    static void ping_arrived(h2_proxy_session *session)
    {
        if (!h2_proxy_ihash_empty(session->streams)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03470)
                          "h2_proxy_session(%s): ping arrived, unblocking streams",
                          session->id);
            h2_proxy_ihash_iter(session->streams, ping_arrived_iter, &session);
        }
    }
    
    typedef struct {
        h2_proxy_session *session;
        conn_rec *c;
        apr_off_t bytes;
        int updated;
    } win_update_ctx;
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_config.c��������������������������������������������������������������0000664�0001751�0001751�00000116113�15017523400�017335� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    
    #include <apr_hash.h>
    #include <apr_lib.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_config.h>
    #include <http_log.h>
    #include <http_vhost.h>
    
    #include <ap_mpm.h>
    
    #include <apr_strings.h>
    
    #include "h2.h"
    #include "h2_conn_ctx.h"
    #include "h2_c1.h"
    #include "h2_config.h"
    #include "h2_protocol.h"
    #include "h2_private.h"
    
    #define DEF_VAL     (-1)
    
    #define H2_CONFIG_GET(a, b, n) \
        (((a)->n == DEF_VAL)? (b) : (a))->n
    
    #define H2_CONFIG_SET(a, n, v) \
        ((a)->n = v)
    
    #define CONFIG_CMD_SET(cmd,dir,var,val) \
        h2_config_seti(((cmd)->path? (dir) : NULL), h2_config_sget((cmd)->server), var, val)
    
    #define CONFIG_CMD_SET64(cmd,dir,var,val) \
        h2_config_seti64(((cmd)->path? (dir) : NULL), h2_config_sget((cmd)->server), var, val)
    
    /* Apache httpd module configuration for h2. */
    typedef struct h2_config {
        const char *name;
        int h2_max_streams;              /* max concurrent # streams (http2) */
        int h2_window_size;              /* stream window size (http2) */
        int min_workers;                 /* min # of worker threads/child */
        int max_workers;                 /* max # of worker threads/child */
        apr_interval_time_t idle_limit;  /* max duration for idle workers */
        int stream_max_mem_size;         /* max # bytes held in memory/stream */
        int h2_direct;                   /* if mod_h2 is active directly */
        int modern_tls_only;             /* Accept only modern TLS in HTTP/2 connections */  
        int h2_upgrade;                  /* Allow HTTP/1 upgrade to h2/h2c */
        apr_int64_t tls_warmup_size;     /* Amount of TLS data to send before going full write size */
        int tls_cooldown_secs;           /* Seconds of idle time before going back to small TLS records */
        int h2_push;                     /* if HTTP/2 server push is enabled */
        struct apr_hash_t *priorities;   /* map of content-type to h2_priority records */
        
        int push_diary_size;             /* # of entries in push diary */
        int copy_files;                  /* if files shall be copied vs setaside on output */
        apr_array_header_t *push_list;   /* list of h2_push_res configurations */
        apr_table_t *early_headers;      /* HTTP headers for a 103 response */
        int early_hints;                 /* support status code 103 */
        int padding_bits;
        int padding_always;
        int output_buffered;
        apr_interval_time_t stream_timeout;/* beam timeout */
        int max_data_frame_len;          /* max # bytes in a single h2 DATA frame */
        int max_hd_block_len;            /* max # bytes in a response header block */
        int proxy_requests;              /* act as forward proxy */
        int h2_websockets;               /* if mod_h2 negotiating WebSockets */
    } h2_config;
    
    typedef struct h2_dir_config {
        const char *name;
        int h2_upgrade;                  /* Allow HTTP/1 upgrade to h2/h2c */
        int h2_push;                     /* if HTTP/2 server push is enabled */
        apr_array_header_t *push_list;   /* list of h2_push_res configurations */
        apr_table_t *early_headers;      /* HTTP headers for a 103 response */
        int early_hints;                 /* support status code 103 */
        apr_interval_time_t stream_timeout;/* beam timeout */
    } h2_dir_config;
    
    
    static h2_config defconf = {
        "default",
        100,                    /* max_streams */
        H2_INITIAL_WINDOW_SIZE, /* window_size */
        -1,                     /* min workers */
        -1,                     /* max workers */
        apr_time_from_sec(10 * 60), /* workers idle limit */
        32 * 1024,              /* stream max mem size */
        -1,                     /* h2 direct mode */
        1,                      /* modern TLS only */
        -1,                     /* HTTP/1 Upgrade support */
        1024*1024,              /* TLS warmup size */
        1,                      /* TLS cooldown secs */
        1,                      /* HTTP/2 server push enabled */
        NULL,                   /* map of content-type to priorities */
        256,                    /* push diary size */
        0,                      /* copy files across threads */
        NULL,                   /* push list */
        NULL,                   /* early headers */
        0,                      /* early hints, http status 103 */
        0,                      /* padding bits */
        1,                      /* padding always */
        1,                      /* stream output buffered */
        -1,                     /* beam timeout */
        0,                      /* max DATA frame len, 0 == no extra limit */
        0,                      /* max header block len, 0 == no extra limit */
        0,                      /* forward proxy */
        0,                      /* WebSockets negotiation, enabled */
    };
    
    static h2_dir_config defdconf = {
        "default",
        -1,                     /* HTTP/1 Upgrade support */
        -1,                     /* HTTP/2 server push enabled */
        NULL,                   /* push list */
        NULL,                   /* early headers */
        -1,                     /* early hints, http status 103 */
        -1,                     /* beam timeout */
    };
    
    void h2_config_init(apr_pool_t *pool)
    {
        (void)pool;
    }
    
    void *h2_config_create_svr(apr_pool_t *pool, server_rec *s)
    {
        h2_config *conf = (h2_config *)apr_pcalloc(pool, sizeof(h2_config));
        char *name = apr_pstrcat(pool, "srv[", s->defn_name, "]", NULL);
        
        conf->name                 = name;
        conf->h2_max_streams       = DEF_VAL;
        conf->h2_window_size       = DEF_VAL;
        conf->min_workers          = DEF_VAL;
        conf->max_workers          = DEF_VAL;
        conf->idle_limit           = DEF_VAL;
        conf->stream_max_mem_size  = DEF_VAL;
        conf->h2_direct            = DEF_VAL;
        conf->modern_tls_only      = DEF_VAL;
        conf->h2_upgrade           = DEF_VAL;
        conf->tls_warmup_size      = DEF_VAL;
        conf->tls_cooldown_secs    = DEF_VAL;
        conf->h2_push              = DEF_VAL;
        conf->priorities           = NULL;
        conf->push_diary_size      = DEF_VAL;
        conf->copy_files           = DEF_VAL;
        conf->push_list            = NULL;
        conf->early_headers        = NULL;
        conf->early_hints          = DEF_VAL;
        conf->padding_bits         = DEF_VAL;
        conf->padding_always       = DEF_VAL;
        conf->output_buffered      = DEF_VAL;
        conf->stream_timeout       = DEF_VAL;
        conf->max_data_frame_len   = DEF_VAL;
        conf->max_hd_block_len     = DEF_VAL;
        conf->proxy_requests       = DEF_VAL;
        conf->h2_websockets        = DEF_VAL;
        return conf;
    }
    
    static void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv)
    {
        h2_config *base = (h2_config *)basev;
        h2_config *add = (h2_config *)addv;
        h2_config *n = (h2_config *)apr_pcalloc(pool, sizeof(h2_config));
        char *name = apr_pstrcat(pool, "merged[", add->name, ", ", base->name, "]", NULL);
        n->name = name;
    
        n->h2_max_streams       = H2_CONFIG_GET(add, base, h2_max_streams);
        n->h2_window_size       = H2_CONFIG_GET(add, base, h2_window_size);
        n->min_workers          = H2_CONFIG_GET(add, base, min_workers);
        n->max_workers          = H2_CONFIG_GET(add, base, max_workers);
        n->idle_limit           = H2_CONFIG_GET(add, base, idle_limit);
        n->stream_max_mem_size  = H2_CONFIG_GET(add, base, stream_max_mem_size);
        n->h2_direct            = H2_CONFIG_GET(add, base, h2_direct);
        n->modern_tls_only      = H2_CONFIG_GET(add, base, modern_tls_only);
        n->h2_upgrade           = H2_CONFIG_GET(add, base, h2_upgrade);
        n->tls_warmup_size      = H2_CONFIG_GET(add, base, tls_warmup_size);
        n->tls_cooldown_secs    = H2_CONFIG_GET(add, base, tls_cooldown_secs);
        n->h2_push              = H2_CONFIG_GET(add, base, h2_push);
        if (add->priorities && base->priorities) {
            n->priorities       = apr_hash_overlay(pool, add->priorities, base->priorities);
        }
        else {
            n->priorities       = add->priorities? add->priorities : base->priorities;
        }
        n->push_diary_size      = H2_CONFIG_GET(add, base, push_diary_size);
        n->copy_files           = H2_CONFIG_GET(add, base, copy_files);
        n->output_buffered      = H2_CONFIG_GET(add, base, output_buffered);
        if (add->push_list && base->push_list) {
            n->push_list        = apr_array_append(pool, base->push_list, add->push_list);
        }
        else {
            n->push_list        = add->push_list? add->push_list : base->push_list;
        }
        if (add->early_headers && base->early_headers) {
            n->early_headers    = apr_table_overlay(pool, add->early_headers, base->early_headers);
        }
        else {
            n->early_headers    = add->early_headers? add->early_headers : base->early_headers;
        }
        n->early_hints          = H2_CONFIG_GET(add, base, early_hints);
        n->padding_bits         = H2_CONFIG_GET(add, base, padding_bits);
        n->padding_always       = H2_CONFIG_GET(add, base, padding_always);
        n->stream_timeout       = H2_CONFIG_GET(add, base, stream_timeout);
        n->max_data_frame_len   = H2_CONFIG_GET(add, base, max_data_frame_len);
        n->max_hd_block_len     = H2_CONFIG_GET(add, base, max_hd_block_len);
        n->proxy_requests       = H2_CONFIG_GET(add, base, proxy_requests);
        n->h2_websockets        = H2_CONFIG_GET(add, base, h2_websockets);
        return n;
    }
    
    void *h2_config_merge_svr(apr_pool_t *pool, void *basev, void *addv)
    {
        return h2_config_merge(pool, basev, addv);
    }
    
    void *h2_config_create_dir(apr_pool_t *pool, char *x)
    {
        h2_dir_config *conf = (h2_dir_config *)apr_pcalloc(pool, sizeof(h2_dir_config));
        const char *s = x? x : "unknown";
        char *name = apr_pstrcat(pool, "dir[", s, "]", NULL);
        
        conf->name                 = name;
        conf->h2_upgrade           = DEF_VAL;
        conf->h2_push              = DEF_VAL;
        conf->early_hints          = DEF_VAL;
        conf->stream_timeout         = DEF_VAL;
        return conf;
    }
    
    void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv)
    {
        h2_dir_config *base = (h2_dir_config *)basev;
        h2_dir_config *add = (h2_dir_config *)addv;
        h2_dir_config *n = (h2_dir_config *)apr_pcalloc(pool, sizeof(h2_dir_config));
    
        n->name = apr_pstrcat(pool, "merged[", add->name, ", ", base->name, "]", NULL);
        n->h2_upgrade           = H2_CONFIG_GET(add, base, h2_upgrade);
        n->h2_push              = H2_CONFIG_GET(add, base, h2_push);
        if (add->push_list && base->push_list) {
            n->push_list        = apr_array_append(pool, base->push_list, add->push_list);
        }
        else {
            n->push_list        = add->push_list? add->push_list : base->push_list;
        }
        if (add->early_headers && base->early_headers) {
            n->early_headers    = apr_table_overlay(pool, add->early_headers, base->early_headers);
        }
        else {
            n->early_headers    = add->early_headers? add->early_headers : base->early_headers;
        }
        n->early_hints          = H2_CONFIG_GET(add, base, early_hints);
        n->stream_timeout         = H2_CONFIG_GET(add, base, stream_timeout);
        return n;
    }
    
    static apr_int64_t h2_srv_config_geti64(const h2_config *conf, h2_config_var_t var)
    {
        switch(var) {
            case H2_CONF_MAX_STREAMS:
                return H2_CONFIG_GET(conf, &defconf, h2_max_streams);
            case H2_CONF_WIN_SIZE:
                return H2_CONFIG_GET(conf, &defconf, h2_window_size);
            case H2_CONF_MIN_WORKERS:
                return H2_CONFIG_GET(conf, &defconf, min_workers);
            case H2_CONF_MAX_WORKERS:
                return H2_CONFIG_GET(conf, &defconf, max_workers);
            case H2_CONF_MAX_WORKER_IDLE_LIMIT:
                return H2_CONFIG_GET(conf, &defconf, idle_limit);
            case H2_CONF_STREAM_MAX_MEM:
                return H2_CONFIG_GET(conf, &defconf, stream_max_mem_size);
            case H2_CONF_MODERN_TLS_ONLY:
                return H2_CONFIG_GET(conf, &defconf, modern_tls_only);
            case H2_CONF_UPGRADE:
                return H2_CONFIG_GET(conf, &defconf, h2_upgrade);
            case H2_CONF_DIRECT:
                return H2_CONFIG_GET(conf, &defconf, h2_direct);
            case H2_CONF_TLS_WARMUP_SIZE:
                return H2_CONFIG_GET(conf, &defconf, tls_warmup_size);
            case H2_CONF_TLS_COOLDOWN_SECS:
                return H2_CONFIG_GET(conf, &defconf, tls_cooldown_secs);
            case H2_CONF_PUSH:
                return H2_CONFIG_GET(conf, &defconf, h2_push);
            case H2_CONF_PUSH_DIARY_SIZE:
                return H2_CONFIG_GET(conf, &defconf, push_diary_size);
            case H2_CONF_COPY_FILES:
                return H2_CONFIG_GET(conf, &defconf, copy_files);
            case H2_CONF_EARLY_HINTS:
                return H2_CONFIG_GET(conf, &defconf, early_hints);
            case H2_CONF_PADDING_BITS:
                return H2_CONFIG_GET(conf, &defconf, padding_bits);
            case H2_CONF_PADDING_ALWAYS:
                return H2_CONFIG_GET(conf, &defconf, padding_always);
            case H2_CONF_OUTPUT_BUFFER:
                return H2_CONFIG_GET(conf, &defconf, output_buffered);
            case H2_CONF_STREAM_TIMEOUT:
                return H2_CONFIG_GET(conf, &defconf, stream_timeout);
            case H2_CONF_MAX_DATA_FRAME_LEN:
                return H2_CONFIG_GET(conf, &defconf, max_data_frame_len);
            case H2_CONF_PROXY_REQUESTS:
                return H2_CONFIG_GET(conf, &defconf, proxy_requests);
            case H2_CONF_WEBSOCKETS:
                return H2_CONFIG_GET(conf, &defconf, h2_websockets);
            case H2_CONF_MAX_HEADER_BLOCK_LEN:
                return H2_CONFIG_GET(conf, &defconf, max_hd_block_len);
            default:
                return DEF_VAL;
        }
    }
    
    static void h2_srv_config_seti(h2_config *conf, h2_config_var_t var, int val)
    {
        switch(var) {
            case H2_CONF_MAX_STREAMS:
                H2_CONFIG_SET(conf, h2_max_streams, val);
                break;
            case H2_CONF_WIN_SIZE:
                H2_CONFIG_SET(conf, h2_window_size, val);
                break;
            case H2_CONF_MIN_WORKERS:
                H2_CONFIG_SET(conf, min_workers, val);
                break;
            case H2_CONF_MAX_WORKERS:
                H2_CONFIG_SET(conf, max_workers, val);
                break;
            case H2_CONF_STREAM_MAX_MEM:
                H2_CONFIG_SET(conf, stream_max_mem_size, val);
                break;
            case H2_CONF_MODERN_TLS_ONLY:
                H2_CONFIG_SET(conf, modern_tls_only, val);
                break;
            case H2_CONF_UPGRADE:
                H2_CONFIG_SET(conf, h2_upgrade, val);
                break;
            case H2_CONF_DIRECT:
                H2_CONFIG_SET(conf, h2_direct, val);
                break;
            case H2_CONF_TLS_WARMUP_SIZE:
                H2_CONFIG_SET(conf, tls_warmup_size, val);
                break;
            case H2_CONF_TLS_COOLDOWN_SECS:
                H2_CONFIG_SET(conf, tls_cooldown_secs, val);
                break;
            case H2_CONF_PUSH:
                H2_CONFIG_SET(conf, h2_push, val);
                break;
            case H2_CONF_PUSH_DIARY_SIZE:
                H2_CONFIG_SET(conf, push_diary_size, val);
                break;
            case H2_CONF_COPY_FILES:
                H2_CONFIG_SET(conf, copy_files, val);
                break;
            case H2_CONF_EARLY_HINTS:
                H2_CONFIG_SET(conf, early_hints, val);
                break;
            case H2_CONF_PADDING_BITS:
                H2_CONFIG_SET(conf, padding_bits, val);
                break;
            case H2_CONF_PADDING_ALWAYS:
                H2_CONFIG_SET(conf, padding_always, val);
                break;
            case H2_CONF_OUTPUT_BUFFER:
                H2_CONFIG_SET(conf, output_buffered, val);
                break;
            case H2_CONF_MAX_DATA_FRAME_LEN:
                H2_CONFIG_SET(conf, max_data_frame_len, val);
                break;
            case H2_CONF_PROXY_REQUESTS:
                H2_CONFIG_SET(conf, proxy_requests, val);
                break;
            case H2_CONF_WEBSOCKETS:
                H2_CONFIG_SET(conf, h2_websockets, val);
                break;
            case H2_CONF_MAX_HEADER_BLOCK_LEN:
                H2_CONFIG_SET(conf, max_hd_block_len, val);
            default:
                break;
        }
    }
    
    static void h2_srv_config_seti64(h2_config *conf, h2_config_var_t var, apr_int64_t val)
    {
        switch(var) {
            case H2_CONF_TLS_WARMUP_SIZE:
                H2_CONFIG_SET(conf, tls_warmup_size, val);
                break;
            case H2_CONF_STREAM_TIMEOUT:
                H2_CONFIG_SET(conf, stream_timeout, val);
                break;
            case H2_CONF_MAX_WORKER_IDLE_LIMIT:
                H2_CONFIG_SET(conf, idle_limit, val);
                break;
            default:
                h2_srv_config_seti(conf, var, (int)val);
                break;
        }
    }
    
    static h2_config *h2_config_sget(server_rec *s)
    {
        h2_config *cfg = (h2_config *)ap_get_module_config(s->module_config, 
                                                           &http2_module);
        ap_assert(cfg);
        return cfg;
    }
    
    static const h2_dir_config *h2_config_rget(request_rec *r)
    {
        h2_dir_config *cfg = (h2_dir_config *)ap_get_module_config(r->per_dir_config, 
                                                                   &http2_module);
        ap_assert(cfg);
        return cfg;
    }
    
    static apr_int64_t h2_dir_config_geti64(const h2_dir_config *conf, h2_config_var_t var)
    {
        switch(var) {
            case H2_CONF_UPGRADE:
                return H2_CONFIG_GET(conf, &defdconf, h2_upgrade);
            case H2_CONF_PUSH:
                return H2_CONFIG_GET(conf, &defdconf, h2_push);
            case H2_CONF_EARLY_HINTS:
                return H2_CONFIG_GET(conf, &defdconf, early_hints);
            case H2_CONF_STREAM_TIMEOUT:
                return H2_CONFIG_GET(conf, &defdconf, stream_timeout);
    
            default:
                return DEF_VAL;
        }
    }
    
    static void h2_config_seti(h2_dir_config *dconf, h2_config *conf, h2_config_var_t var, int val)
    {
        int set_srv = !dconf;
        if (dconf) {
            switch(var) {
                case H2_CONF_UPGRADE:
                    H2_CONFIG_SET(dconf, h2_upgrade, val);
                    break;
                case H2_CONF_PUSH:
                    H2_CONFIG_SET(dconf, h2_push, val);
                    break;
                case H2_CONF_EARLY_HINTS:
                    H2_CONFIG_SET(dconf, early_hints, val);
                    break;
                default:
                    /* not handled in dir_conf */
                    set_srv = 1;
                    break;
            }
        }
    
        if (set_srv) {
            h2_srv_config_seti(conf, var, val);
        }
    }
    
    static void h2_config_seti64(h2_dir_config *dconf, h2_config *conf, h2_config_var_t var, apr_int64_t val)
    {
        int set_srv = !dconf;
        if (dconf) {
            switch(var) {
                case H2_CONF_STREAM_TIMEOUT:
                    H2_CONFIG_SET(dconf, stream_timeout, val);
                    break;
                default:
                    /* not handled in dir_conf */
                    set_srv = 1;
                    break;
            }
        }
    
        if (set_srv) {
            h2_srv_config_seti64(conf, var, val);
        }
    }
    
    static const h2_config *h2_config_get(conn_rec *c)
    {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
        
        if (conn_ctx && conn_ctx->server) {
            return h2_config_sget(conn_ctx->server);
        }
        return h2_config_sget(c->base_server);
    }
    
    int h2_config_cgeti(conn_rec *c, h2_config_var_t var)
    {
        return (int)h2_srv_config_geti64(h2_config_get(c), var);
    }
    
    apr_int64_t h2_config_cgeti64(conn_rec *c, h2_config_var_t var)
    {
        return h2_srv_config_geti64(h2_config_get(c), var);
    }
    
    int h2_config_sgeti(server_rec *s, h2_config_var_t var)
    {
        return (int)h2_srv_config_geti64(h2_config_sget(s), var);
    }
    
    apr_int64_t h2_config_sgeti64(server_rec *s, h2_config_var_t var)
    {
        return h2_srv_config_geti64(h2_config_sget(s), var);
    }
    
    int h2_config_geti(request_rec *r, server_rec *s, h2_config_var_t var)
    {
        return (int)h2_config_geti64(r, s, var);
    }
    
    apr_int64_t h2_config_geti64(request_rec *r, server_rec *s, h2_config_var_t var)
    {
        apr_int64_t mode = r? (int)h2_dir_config_geti64(h2_config_rget(r), var) : DEF_VAL;
        return (mode != DEF_VAL)? mode : h2_config_sgeti64(s, var);
    }
    
    int h2_config_rgeti(request_rec *r, h2_config_var_t var)
    {
        return h2_config_geti(r, r->server, var);
    }
    
    apr_int64_t h2_config_rgeti64(request_rec *r, h2_config_var_t var)
    {
        return h2_config_geti64(r, r->server, var);
    }
    
    apr_array_header_t *h2_config_push_list(request_rec *r)
    {
        const h2_config *sconf;
        const h2_dir_config *conf = h2_config_rget(r);
        
        if (conf && conf->push_list) {
            return conf->push_list;
        }
        sconf = h2_config_sget(r->server); 
        return sconf? sconf->push_list : NULL;
    }
    
    apr_table_t *h2_config_early_headers(request_rec *r)
    {
        const h2_config *sconf;
        const h2_dir_config *conf = h2_config_rget(r);
    
        if (conf && conf->early_headers) {
            return conf->early_headers;
        }
        sconf = h2_config_sget(r->server);
        return sconf? sconf->early_headers : NULL;
    }
    
    const struct h2_priority *h2_cconfig_get_priority(conn_rec *c, const char *content_type)
    {
        const h2_config *conf = h2_config_get(c);
        if (content_type && conf->priorities) {
            apr_ssize_t len = (apr_ssize_t)strcspn(content_type, "; \t");
            h2_priority *prio = apr_hash_get(conf->priorities, content_type, len);
            return prio? prio : apr_hash_get(conf->priorities, "*", 1);
        }
        return NULL;
    }
    
    static const char *h2_conf_set_max_streams(cmd_parms *cmd,
                                               void *dirconf, const char *value)
    {
        apr_int64_t ival = (int)apr_atoi64(value);
        if (ival < 1) {
            return "value must be > 0";
        }
        CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_MAX_STREAMS, ival);
        return NULL;
    }
    
    static const char *h2_conf_set_window_size(cmd_parms *cmd,
                                               void *dirconf, const char *value)
    {
        int val = (int)apr_atoi64(value);
        if (val < 1024) {
            return "value must be >= 1024";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_WIN_SIZE, val);
        return NULL;
    }
    
    static const char *h2_conf_set_min_workers(cmd_parms *cmd,
                                               void *dirconf, const char *value)
    {
        int val = (int)apr_atoi64(value);
        if (val < 1) {
            return "value must be > 0";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MIN_WORKERS, val);
        return NULL;
    }
    
    static const char *h2_conf_set_max_workers(cmd_parms *cmd,
                                               void *dirconf, const char *value)
    {
        int val = (int)apr_atoi64(value);
        if (val < 1) {
            return "value must be > 0";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MAX_WORKERS, val);
        return NULL;
    }
    
    static const char *h2_conf_set_max_worker_idle_limit(cmd_parms *cmd,
                                                         void *dirconf, const char *value)
    {
        apr_interval_time_t timeout;
        apr_status_t rv = ap_timeout_parameter_parse(value, &timeout, "s");
        if (rv != APR_SUCCESS) {
            return "Invalid idle limit value";
        }
        if (timeout <= 0) {
            timeout = DEF_VAL;
        }
        CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_MAX_WORKER_IDLE_LIMIT, timeout);
        return NULL;
    }
    
    static const char *h2_conf_set_stream_max_mem_size(cmd_parms *cmd,
                                                       void *dirconf, const char *value)
    {
        int val = (int)apr_atoi64(value);
        if (val < 1024) {
            return "value must be >= 1024";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_STREAM_MAX_MEM, val);
        return NULL;
    }
    
    static const char *h2_conf_set_max_data_frame_len(cmd_parms *cmd,
                                                      void *dirconf, const char *value)
    {
        int val = (int)apr_atoi64(value);
        if (val < 0) {
            return "value must be 0 or larger";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MAX_DATA_FRAME_LEN, val);
        return NULL;
    }
    
    static const char *h2_conf_set_max_hd_block_len(cmd_parms *cmd,
                                                    void *dirconf, const char *value)
    {
        int val = (int)apr_atoi64(value);
        if (val < 0) {
            return "value must be 0 or larger";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MAX_HEADER_BLOCK_LEN, val);
        return NULL;
    }
    
    static const char *h2_conf_set_session_extra_files(cmd_parms *cmd,
                                                       void *dirconf, const char *value)
    {
        /* deprecated, ignore */
        (void)dirconf;
        (void)value;
        ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool, /* NO LOGNO */
                      "H2SessionExtraFiles is obsolete and will be ignored");
        return NULL;
    }
    
    static const char *h2_conf_set_serialize_headers(cmd_parms *parms,
                                                     void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, parms->server, APLOGNO(10307)
                         "%s: this feature has been disabled and the directive "
                         "to enable it is ignored.", parms->cmd->name);
        }
        return NULL;
    }
    
    static const char *h2_conf_set_direct(cmd_parms *cmd,
                                          void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_DIRECT, 1);
            return NULL;
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_DIRECT, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    static const char *h2_conf_set_push(cmd_parms *cmd, void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH, 1);
            return NULL;
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    static const char *h2_conf_set_websockets(cmd_parms *cmd,
                                              void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
    #if H2_USE_WEBSOCKETS
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_WEBSOCKETS, 1);
            return NULL;
    #elif !H2_USE_PIPES
            return "HTTP/2 WebSockets are not supported on this platform";
    #else
            return "HTTP/2 WebSockets are not supported in this server version";
    #endif
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_WEBSOCKETS, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    static const char *h2_conf_add_push_priority(cmd_parms *cmd, void *_cfg,
                                                 const char *ctype, const char *sdependency,
                                                 const char *sweight)
    {
        h2_config *cfg = (h2_config *)h2_config_sget(cmd->server);
        const char *sdefweight = "16";         /* default AFTER weight */
        h2_dependency dependency;
        h2_priority *priority;
        int weight;
     
        (void)_cfg;
        if (!*ctype) {
            return "1st argument must be a mime-type, like 'text/css' or '*'";
        }
        
        if (!sweight) {
            /* 2 args only, but which one? */
            if (apr_isdigit(sdependency[0])) {
                sweight = sdependency;
                sdependency = "AFTER";        /* default dependency */
            }
        }
        
        if (!strcasecmp("AFTER", sdependency)) {
            dependency = H2_DEPENDANT_AFTER;
        } 
        else if (!strcasecmp("BEFORE", sdependency)) {
            dependency = H2_DEPENDANT_BEFORE;
            if (sweight) {
                return "dependency 'Before' does not allow a weight";
            }
        } 
        else if (!strcasecmp("INTERLEAVED", sdependency)) {
            dependency = H2_DEPENDANT_INTERLEAVED;
            sdefweight = "256";        /* default INTERLEAVED weight */
        }
        else {
            return "dependency must be one of 'After', 'Before' or 'Interleaved'";
        }
        
        weight = (int)apr_atoi64(sweight? sweight : sdefweight);
        if (weight < NGHTTP2_MIN_WEIGHT) {
            return apr_psprintf(cmd->pool, "weight must be a number >= %d",
                                NGHTTP2_MIN_WEIGHT);
        }
        
        priority = apr_pcalloc(cmd->pool, sizeof(*priority));
        priority->dependency = dependency;
        priority->weight = weight;
        
        if (!cfg->priorities) {
            cfg->priorities = apr_hash_make(cmd->pool);
        }
        apr_hash_set(cfg->priorities, ctype, (apr_ssize_t)strlen(ctype), priority);
        return NULL;
    }
    
    static const char *h2_conf_set_modern_tls_only(cmd_parms *cmd,
                                                   void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MODERN_TLS_ONLY, 1);
            return NULL;
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MODERN_TLS_ONLY, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    static const char *h2_conf_set_upgrade(cmd_parms *cmd,
                                           void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_UPGRADE, 1);
            return NULL;
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_UPGRADE, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    static const char *h2_conf_set_tls_warmup_size(cmd_parms *cmd,
                                                   void *dirconf, const char *value)
    {
        apr_int64_t val = apr_atoi64(value);
        CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_TLS_WARMUP_SIZE, val);
        return NULL;
    }
    
    static const char *h2_conf_set_tls_cooldown_secs(cmd_parms *cmd,
                                                     void *dirconf, const char *value)
    {
        apr_int64_t val = (int)apr_atoi64(value);
        CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_TLS_COOLDOWN_SECS, val);
        return NULL;
    }
    
    static const char *h2_conf_set_push_diary_size(cmd_parms *cmd,
                                                   void *dirconf, const char *value)
    {
        int val = (int)apr_atoi64(value);
        if (val < 0) {
            return "value must be >= 0";
        }
        if (val > 0 && (val & (val-1))) {
            return "value must a power of 2";
        }
        if (val > (1 << 15)) {
            return "value must <= 65536";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH_DIARY_SIZE, val);
        return NULL;
    }
    
    static const char *h2_conf_set_copy_files(cmd_parms *cmd,
                                              void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_COPY_FILES, 1);
            return NULL;
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_COPY_FILES, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    static void add_push(apr_array_header_t **plist, apr_pool_t *pool, h2_push_res *push)
    {
        h2_push_res *new;
        if (!*plist) {
            *plist = apr_array_make(pool, 10, sizeof(*push));
        }
        new = apr_array_push(*plist);
        new->uri_ref = push->uri_ref;
        new->critical = push->critical;
    }
    
    static const char *h2_conf_add_push_res(cmd_parms *cmd, void *dirconf,
                                            const char *arg1, const char *arg2,
                                            const char *arg3)
    {
        h2_push_res push;
        const char *last = arg3;
        
        memset(&push, 0, sizeof(push));
        if (!strcasecmp("add", arg1)) {
            push.uri_ref = arg2;
        }
        else {
            push.uri_ref = arg1;
            last = arg2;
            if (arg3) {
                return "too many parameter";
            }
        }
        
        if (last) {
            if (!strcasecmp("critical", last)) {
                push.critical = 1;
            }
            else {
                return "unknown last parameter";
            }
        }
    
        if (cmd->path) {
            add_push(&(((h2_dir_config*)dirconf)->push_list), cmd->pool, &push);
        }
        else {
            add_push(&(h2_config_sget(cmd->server)->push_list), cmd->pool, &push);
        }
        return NULL;
    }
    
    static const char *h2_conf_add_early_hint(cmd_parms *cmd, void *dirconf,
                                              const char *name, const char *value)
    {
        apr_table_t *hds, **phds;
    
        if(!name || !*name)
          return "Early Hint header name must not be empty";
        if(!value)
          return "Early Hint header value must not be empty";
        while (apr_isspace(*value))
            ++value;
        if(!*value)
          return "Early Hint header value must not be empty/only space";
        if (*ap_scan_http_field_content(value))
          return "Early Hint header value contains invalid characters";
    
        if (cmd->path) {
            phds = &((h2_dir_config*)dirconf)->early_headers;
        }
        else {
            phds = &(h2_config_sget(cmd->server))->early_headers;
        }
        hds = *phds;
        if (!hds) {
          *phds = hds = apr_table_make(cmd->pool, 10);
        }
        apr_table_add(hds, name, value);
    
        return NULL;
    }
    
    static const char *h2_conf_set_early_hints(cmd_parms *cmd,
                                               void *dirconf, const char *value)
    {
        int val;
    
        if (!strcasecmp(value, "On")) val = 1;
        else if (!strcasecmp(value, "Off")) val = 0;
        else return "value must be On or Off";
        
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_EARLY_HINTS, val);
        if (cmd->path) {
            ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool, 
                                "H2EarlyHints = %d on path %s", val, cmd->path);
        }
        return NULL;
    }
    
    static const char *h2_conf_set_padding(cmd_parms *cmd, void *dirconf, const char *value)
    {
        int val;
        
        val = (int)apr_atoi64(value);
        if (val < 0) {
            return "number of bits must be >= 0";
        }
        if (val > 8) {
            return "number of bits must be <= 8";
        }
        CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PADDING_BITS, val);
        return NULL;
    }
    
    static const char *h2_conf_set_output_buffer(cmd_parms *cmd,
                                          void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_OUTPUT_BUFFER, 1);
            return NULL;
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_OUTPUT_BUFFER, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    static const char *h2_conf_set_stream_timeout(cmd_parms *cmd,
                                                void *dirconf, const char *value)
    {
        apr_status_t rv;
        apr_interval_time_t timeout;
    
        rv = ap_timeout_parameter_parse(value, &timeout, "s");
        if (rv != APR_SUCCESS) {
            return "Invalid timeout value";
        }
        CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_STREAM_TIMEOUT, timeout);
        return NULL;
    }
    
    static const char *h2_conf_set_proxy_requests(cmd_parms *cmd,
                                                  void *dirconf, const char *value)
    {
        if (!strcasecmp(value, "On")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PROXY_REQUESTS, 1);
            return NULL;
        }
        else if (!strcasecmp(value, "Off")) {
            CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PROXY_REQUESTS, 0);
            return NULL;
        }
        return "value must be On or Off";
    }
    
    void h2_get_workers_config(server_rec *s, int *pminw, int *pmaxw,
                               apr_time_t *pidle_limit)
    {
        int threads_per_child = 0;
    
        *pminw = h2_config_sgeti(s, H2_CONF_MIN_WORKERS);
        *pmaxw = h2_config_sgeti(s, H2_CONF_MAX_WORKERS);
    
        ap_mpm_query(AP_MPMQ_MAX_THREADS, &threads_per_child);
        if (*pminw <= 0) {
            *pminw = threads_per_child;
        }
        if (*pmaxw <= 0) {
            *pmaxw = H2MAX(4, 3 * (*pminw) / 2);
        }
        *pidle_limit = h2_config_sgeti64(s, H2_CONF_MAX_WORKER_IDLE_LIMIT);
    }
    
    #define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
    
    const command_rec h2_cmds[] = {
        AP_INIT_TAKE1("H2MaxSessionStreams", h2_conf_set_max_streams, NULL,
                      RSRC_CONF, "maximum number of open streams per session"),
        AP_INIT_TAKE1("H2WindowSize", h2_conf_set_window_size, NULL,
                      RSRC_CONF, "window size on client DATA"),
        AP_INIT_TAKE1("H2MinWorkers", h2_conf_set_min_workers, NULL,
                      RSRC_CONF, "minimum number of worker threads per child"),
        AP_INIT_TAKE1("H2MaxWorkers", h2_conf_set_max_workers, NULL,
                      RSRC_CONF, "maximum number of worker threads per child"),
        AP_INIT_TAKE1("H2MaxWorkerIdleSeconds", h2_conf_set_max_worker_idle_limit, NULL,
                      RSRC_CONF, "maximum number of idle seconds before a worker shuts down"),
        AP_INIT_TAKE1("H2StreamMaxMemSize", h2_conf_set_stream_max_mem_size, NULL,
                      RSRC_CONF, "maximum number of bytes buffered in memory for a stream"),
        AP_INIT_TAKE1("H2SerializeHeaders", h2_conf_set_serialize_headers, NULL,
                      RSRC_CONF, "disabled, this directive has no longer an effect."),
        AP_INIT_TAKE1("H2ModernTLSOnly", h2_conf_set_modern_tls_only, NULL,
                      RSRC_CONF, "off to not impose RFC 7540 restrictions on TLS"),
        AP_INIT_TAKE1("H2Upgrade", h2_conf_set_upgrade, NULL,
                      RSRC_CONF|OR_AUTHCFG, "on to allow HTTP/1 Upgrades to h2/h2c"),
        AP_INIT_TAKE1("H2Direct", h2_conf_set_direct, NULL,
                      RSRC_CONF, "on to enable direct HTTP/2 mode"),
        AP_INIT_TAKE1("H2SessionExtraFiles", h2_conf_set_session_extra_files, NULL,
                      RSRC_CONF, "number of extra file a session might keep open (obsolete)"),
        AP_INIT_TAKE1("H2TLSWarmUpSize", h2_conf_set_tls_warmup_size, NULL,
                      RSRC_CONF, "number of bytes on TLS connection before doing max writes"),
        AP_INIT_TAKE1("H2TLSCoolDownSecs", h2_conf_set_tls_cooldown_secs, NULL,
                      RSRC_CONF, "seconds of idle time on TLS before shrinking writes"),
        AP_INIT_TAKE1("H2Push", h2_conf_set_push, NULL,
                      RSRC_CONF|OR_AUTHCFG, "off to disable HTTP/2 server push"),
        AP_INIT_TAKE23("H2PushPriority", h2_conf_add_push_priority, NULL,
                      RSRC_CONF, "define priority of PUSHed resources per content type"),
        AP_INIT_TAKE1("H2PushDiarySize", h2_conf_set_push_diary_size, NULL,
                      RSRC_CONF, "size of push diary"),
        AP_INIT_TAKE1("H2CopyFiles", h2_conf_set_copy_files, NULL,
                      OR_FILEINFO, "on to perform copy of file data"),
        AP_INIT_TAKE123("H2PushResource", h2_conf_add_push_res, NULL,
                       OR_FILEINFO|OR_AUTHCFG, "add a resource to be pushed in this location/on this server."),
        AP_INIT_TAKE1("H2EarlyHints", h2_conf_set_early_hints, NULL,
                      RSRC_CONF, "on to enable interim status 103 responses"),
        AP_INIT_TAKE1("H2Padding", h2_conf_set_padding, NULL,
                      RSRC_CONF, "set payload padding"),
        AP_INIT_TAKE1("H2OutputBuffering", h2_conf_set_output_buffer, NULL,
                      RSRC_CONF, "set stream output buffer on/off"),
        AP_INIT_TAKE1("H2StreamTimeout", h2_conf_set_stream_timeout, NULL,
                      RSRC_CONF, "set stream timeout"),
        AP_INIT_TAKE1("H2MaxDataFrameLen", h2_conf_set_max_data_frame_len, NULL,
                      RSRC_CONF, "maximum number of bytes in a single HTTP/2 DATA frame"),
        AP_INIT_TAKE1("H2MaxHeaderBlockLen", h2_conf_set_max_hd_block_len, NULL,
                      RSRC_CONF, "maximum number of bytes in a response header block"),
        AP_INIT_TAKE2("H2EarlyHint", h2_conf_add_early_hint, NULL,
                       OR_FILEINFO|OR_AUTHCFG, "add a a 'Link:' header for a 103 Early Hints response."),
        AP_INIT_TAKE1("H2ProxyRequests", h2_conf_set_proxy_requests, NULL,
                      OR_FILEINFO, "Enables forward proxy requests via HTTP/2"),
        AP_INIT_TAKE1("H2WebSockets", h2_conf_set_websockets, NULL,
                      RSRC_CONF, "off to disable WebSockets over HTTP/2"),
        AP_END_CMD
    };
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_mplx.h����������������������������������������������������������������0000664�0001751�0001751�00000020636�14651200711�017061� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_mplx__
    #define __mod_h2__h2_mplx__
    
    /**
     * The stream multiplexer. It performs communication between the
     * primary HTTP/2 connection (c1) to the secondary connections (c2)
     * that process the requests, aka. HTTP/2 streams.
     *
     * There is one h2_mplx instance for each h2_session.
     *
     * Naming Convention:
     * "h2_mplx_c1_" are methods only to be called by the primary connection
     * "h2_mplx_c2_" are methods only to be called by a secondary connection
     * "h2_mplx_worker_" are methods only to be called by a h2 worker thread
     */
    
    struct apr_pool_t;
    struct apr_thread_mutex_t;
    struct apr_thread_cond_t;
    struct h2_bucket_beam;
    struct h2_config;
    struct h2_ihash_t;
    struct h2_stream;
    struct h2_request;
    struct apr_thread_cond_t;
    struct h2_workers;
    struct h2_iqueue;
    
    #include <apr_queue.h>
    
    #include "h2_workers.h"
    
    typedef struct h2_c2_transit h2_c2_transit;
    
    struct h2_c2_transit {
        apr_pool_t *pool;
        apr_bucket_alloc_t *bucket_alloc;
    };
    
    typedef struct h2_mplx h2_mplx;
    
    struct h2_mplx {
        int child_num;                  /* child this runs in */
        apr_uint32_t id;                /* id unique per child */
        conn_rec *c1;                   /* the main connection */
        apr_pool_t *pool;
        struct h2_stream *stream0;      /* HTTP/2's stream 0 */
        server_rec *s;                  /* server for master conn */
    
        int shutdown;                   /* we are shutting down */
        int aborted;                    /* we need to get out of here asap */
        int polling;                    /* is waiting/processing pollset events */
        ap_conn_producer_t *producer;   /* registered producer at h2_workers */
    
        struct h2_ihash_t *streams;     /* all streams active */
        struct h2_ihash_t *shold;       /* all streams done with c2 processing ongoing */
        apr_array_header_t *spurge;     /* all streams done, ready for destroy */
        
        struct h2_iqueue *q;            /* all stream ids that need to be started */
    
        apr_size_t stream_max_mem;      /* max memory to buffer for a stream */
        apr_uint32_t max_streams;       /* max # of concurrent streams */
        apr_uint32_t max_stream_id_started; /* highest stream id that started processing */
    
        apr_uint32_t processing_count;  /* # of c2 working for this mplx */
        apr_uint32_t processing_limit;  /* current limit on processing c2s, dynamic */
        apr_uint32_t processing_max;    /* max, hard limit of processing c2s */
        
        apr_time_t last_mood_change;    /* last time, processing limit changed */
        apr_interval_time_t mood_update_interval; /* how frequent we update at most */
        apr_uint32_t irritations_since; /* irritations (>0) or happy events (<0) since last mood change */
    
        apr_thread_mutex_t *lock;
        struct apr_thread_cond_t *join_wait;
        
        apr_pollset_t *pollset;         /* pollset for c1/c2 IO events */
        apr_array_header_t *streams_ev_in;
        apr_array_header_t *streams_ev_out;
    
        apr_thread_mutex_t *poll_lock; /* protect modifications of queues below */
        struct h2_iqueue *streams_input_read;  /* streams whose input has been read from */
        struct h2_iqueue *streams_output_written; /* streams whose output has been written to */
    
        struct h2_workers *workers;     /* h2 workers process wide instance */
    
        apr_uint32_t max_spare_transits; /* max number of transit pools idling */
        apr_array_header_t *c2_transits; /* base pools for running c2 connections */
    };
    
    apr_status_t h2_mplx_c1_child_init(apr_pool_t *pool, server_rec *s);
    
    /**
     * Create the multiplexer for the given HTTP2 session. 
     * Implicitly has reference count 1.
     */
    h2_mplx *h2_mplx_c1_create(int child_id, apr_uint32_t id,
                               struct h2_stream *stream0,
                               server_rec *s, apr_pool_t *master,
                               struct h2_workers *workers);
    
    /**
     * Destroy the mplx, shutting down all ongoing processing.
     * @param m the mplx destroyed
     * @param wait condition var to wait on for ref counter == 0
     */ 
    void h2_mplx_c1_destroy(h2_mplx *m);
    
    /**
     * Shut down the multiplexer gracefully. Will no longer schedule new streams
     * but let the ongoing ones finish normally.
     * @return the highest stream id being/been processed
     */
    int h2_mplx_c1_shutdown(h2_mplx *m);
    
    /**
     * Notifies mplx that a stream has been completely handled on the main
     * connection and is ready for cleanup.
     * 
     * @param m the mplx itself
     * @param stream the stream ready for cleanup
     * @param pstream_count return the number of streams active
     */
    apr_status_t h2_mplx_c1_stream_cleanup(h2_mplx *m, struct h2_stream *stream,
                                           unsigned int *pstream_count);
    
    int h2_mplx_c1_stream_is_running(h2_mplx *m, struct h2_stream *stream);
    
    /**
     * Process a stream request.
     * 
     * @param m the multiplexer
     * @param read_to_process
     * @param input_pending
     * @param cmp the stream priority compare function
     * @param pstream_count on return the number of streams active in mplx
     */
    void h2_mplx_c1_process(h2_mplx *m,
                            struct h2_iqueue *read_to_process,
                            h2_stream_get_fn *get_stream,
                            h2_stream_pri_cmp_fn *cmp,
                            struct h2_session *session,
                            unsigned int *pstream_count);
    
    /**
     * Stream priorities have changed, reschedule pending requests.
     * 
     * @param m the multiplexer
     * @param cmp the stream priority compare function
     * @param ctx context data for the compare function
     */
    apr_status_t h2_mplx_c1_reprioritize(h2_mplx *m, h2_stream_pri_cmp_fn *cmp,
                                        struct h2_session *session);
    
    typedef void stream_ev_callback(void *ctx, struct h2_stream *stream);
    
    /**
     * Poll the primary connection for input and the active streams for output.
     * Invoke the callback for any stream where an event happened.
     */
    apr_status_t h2_mplx_c1_poll(h2_mplx *m, apr_interval_time_t timeout,
                                stream_ev_callback *on_stream_input,
                                stream_ev_callback *on_stream_output,
                                void *on_ctx);
    
    void h2_mplx_c2_input_read(h2_mplx *m, conn_rec *c2);
    void h2_mplx_c2_output_written(h2_mplx *m, conn_rec *c2);
    
    typedef int h2_mplx_stream_cb(struct h2_stream *s, void *userdata);
    
    /**
     * Iterate over all streams known to mplx from the primary connection.
     * @param m the mplx
     * @param cb the callback to invoke on each stream
     * @param ctx userdata passed to the callback
     */
    apr_status_t h2_mplx_c1_streams_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx);
    
    /**
     * Return != 0 iff all open streams want to send data
     */
    int h2_mplx_c1_all_streams_want_send_data(h2_mplx *m);
    
    /**
     * Return != 0 iff all open streams have send window exhausted
     */
    int h2_mplx_c1_all_streams_send_win_exhausted(h2_mplx *m);
    
    /**
     * A stream has been RST_STREAM by the client. Abort
     * any processing going on and remove from processing
     * queue.
     */
    apr_status_t h2_mplx_c1_client_rst(h2_mplx *m, int stream_id,
                                       struct h2_stream *stream);
    
    /**
     * Get readonly access to a stream for a secondary connection.
     */
    const struct h2_stream *h2_mplx_c2_stream_get(h2_mplx *m, int stream_id);
    
    /**
     * A h2 worker asks for a secondary connection to process.
     * @param out_c2 non-NULL, a pointer where to reveive the next
     *               secondary connection to process.
     */
    apr_status_t h2_mplx_worker_pop_c2(h2_mplx *m, conn_rec **out_c2);
    
    
    /**
     * Session processing is entering KEEPALIVE, e.g. giving control
     * to the MPM for monitoring incoming socket events only.
     * Last chance for maintenance work before losing control.
     */
    void h2_mplx_c1_going_keepalive(h2_mplx *m);
    
    #define H2_MPLX_MSG(m, msg)     \
        "h2_mplx(%d-%lu): "msg, m->child_num, (unsigned long)m->id
    
    #endif /* defined(__mod_h2__h2_mplx__) */
    ��������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2.h���������������������������������������������������������������������0000664�0001751�0001751�00000015632�14513234341�016024� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2__
    #define __mod_h2__h2__
    
    #include <apr_version.h>
    #include <ap_mmn.h>
    
    #include <nghttp2/nghttp2ver.h>
    
    struct h2_session;
    struct h2_stream;
    
    /*
     * When apr pollsets can poll file descriptors (e.g. pipes),
     * we use it for polling stream input/output.
     */
    #ifdef H2_NO_PIPES
    #define H2_USE_PIPES            0
    #else
    #define H2_USE_PIPES            (APR_FILES_AS_SOCKETS && APR_VERSION_AT_LEAST(1,6,0))
    #endif
    
    #if AP_MODULE_MAGIC_AT_LEAST(20120211, 129)
    #define H2_USE_POLLFD_FROM_CONN 1
    #else
    #define H2_USE_POLLFD_FROM_CONN 0
    #endif
    
    /* WebSockets support requires apr 1.7.0 for apr_encode.h, plus the
     * WebSockets features of nghttp2 1.34.0 and later. */
    #if H2_USE_PIPES && defined(NGHTTP2_VERSION_NUM) && NGHTTP2_VERSION_NUM >= 0x012200 && APR_VERSION_AT_LEAST(1,7,0)
    #define H2_USE_WEBSOCKETS       1
    #else
    #define H2_USE_WEBSOCKETS       0
    #endif
    
    /**
     * The magic PRIamble of RFC 7540 that is always sent when starting
     * a h2 communication.
     */
    extern const char *H2_MAGIC_TOKEN;
    
    #define H2_ERR_NO_ERROR             (0x00)
    #define H2_ERR_PROTOCOL_ERROR       (0x01)
    #define H2_ERR_INTERNAL_ERROR       (0x02)
    #define H2_ERR_FLOW_CONTROL_ERROR   (0x03)
    #define H2_ERR_SETTINGS_TIMEOUT     (0x04)
    #define H2_ERR_STREAM_CLOSED        (0x05)
    #define H2_ERR_FRAME_SIZE_ERROR     (0x06)
    #define H2_ERR_REFUSED_STREAM       (0x07)
    #define H2_ERR_CANCEL               (0x08)
    #define H2_ERR_COMPRESSION_ERROR    (0x09)
    #define H2_ERR_CONNECT_ERROR        (0x0a)
    #define H2_ERR_ENHANCE_YOUR_CALM    (0x0b)
    #define H2_ERR_INADEQUATE_SECURITY  (0x0c)
    #define H2_ERR_HTTP_1_1_REQUIRED    (0x0d)
    
    #define H2_HEADER_METHOD     ":method"
    #define H2_HEADER_METHOD_LEN 7
    #define H2_HEADER_SCHEME     ":scheme"
    #define H2_HEADER_SCHEME_LEN 7
    #define H2_HEADER_AUTH       ":authority"
    #define H2_HEADER_AUTH_LEN   10
    #define H2_HEADER_PATH       ":path"
    #define H2_HEADER_PATH_LEN   5
    #define H2_HEADER_PROTO      ":protocol"
    #define H2_HEADER_PROTO_LEN  9
    #define H2_CRLF             "\r\n"
    
    /* Size of the frame header itself in HTTP/2 */
    #define H2_FRAME_HDR_LEN            9
     
    /* Max data size to write so it fits inside a TLS record */
    #define H2_DATA_CHUNK_SIZE          ((16*1024) - 100 - H2_FRAME_HDR_LEN) 
    
    /* Maximum number of padding bytes in a frame, rfc7540 */
    #define H2_MAX_PADLEN               256
    /* Initial default window size, RFC 7540 ch. 6.5.2 */
    #define H2_INITIAL_WINDOW_SIZE      ((64*1024)-1)
    
    #define H2_STREAM_CLIENT_INITIATED(id)      (id&0x01)
    
    #define H2_ALEN(a)          (sizeof(a)/sizeof((a)[0]))
    
    #define H2MAX(x,y) ((x) > (y) ? (x) : (y))
    #define H2MIN(x,y) ((x) < (y) ? (x) : (y))
    
    typedef enum {
        H2_DEPENDANT_AFTER,
        H2_DEPENDANT_INTERLEAVED,
        H2_DEPENDANT_BEFORE,
    } h2_dependency;
    
    typedef struct h2_priority {
        h2_dependency dependency;
        int           weight;
    } h2_priority;
    
    typedef enum {
        H2_PUSH_NONE,
        H2_PUSH_DEFAULT,
        H2_PUSH_HEAD,
        H2_PUSH_FAST_LOAD,
    } h2_push_policy;
    
    typedef enum {
        H2_SESSION_ST_INIT,             /* send initial SETTINGS, etc. */
        H2_SESSION_ST_DONE,             /* finished, connection close */
        H2_SESSION_ST_IDLE,             /* nothing to write, expecting data inc */
        H2_SESSION_ST_BUSY,             /* read/write without stop */
        H2_SESSION_ST_WAIT,             /* waiting for c1 incoming + c2s output */
        H2_SESSION_ST_CLEANUP,          /* pool is being cleaned up */
    } h2_session_state;
    
    typedef struct h2_session_props {
        int accepted_max;      /* the highest remote stream id was/will be handled */
        int completed_max;     /* the highest remote stream completed */
        int emitted_count;     /* the number of local streams sent */
        int emitted_max;       /* the highest local stream id sent */
        int error;             /* the last session error encountered */
        const char *error_msg; /* the short message given on the error */
        unsigned int accepting : 1;     /* if the session is accepting new streams */
        unsigned int shutdown : 1;      /* if the final GOAWAY has been sent */
    } h2_session_props;
    
    typedef enum h2_stream_state_t {
        H2_SS_IDLE,
        H2_SS_RSVD_R,
        H2_SS_RSVD_L,
        H2_SS_OPEN,
        H2_SS_CLOSED_R,
        H2_SS_CLOSED_L,
        H2_SS_CLOSED,
        H2_SS_CLEANUP,
        H2_SS_MAX
    } h2_stream_state_t;
    
    typedef enum {
        H2_SEV_CLOSED_L,
        H2_SEV_CLOSED_R,
        H2_SEV_CANCELLED,
        H2_SEV_EOS_SENT,
        H2_SEV_IN_ERROR,
        H2_SEV_IN_DATA_PENDING,
        H2_SEV_OUT_C1_BLOCK,
    } h2_stream_event_t;
    
    
    /* h2_request is the transformer of HTTP2 streams into HTTP/1.1 internal
     * format that will be fed to various httpd input filters to finally
     * become a request_rec to be handled by soemone.
     */
    typedef struct h2_request h2_request;
    struct h2_request {
        const char *method; /* pseudo header values, see ch. 8.1.2.3 */
        const char *scheme;
        const char *authority;
        const char *path;
        const char *protocol;
        apr_table_t *headers;
    
        apr_time_t request_time;
        apr_off_t raw_bytes;        /* RAW network bytes that generated this request - if known. */
        int http_status;            /* Store a possible HTTP status code that gets
                                     * defined before creating the dummy HTTP/1.1
                                     * request e.g. due to an error already
                                     * detected.
                                     */
    };
    
    /*
     * A possible HTTP status code is not defined yet. See the http_status field
     * in struct h2_request above for further explanation.
     */
    #define H2_HTTP_STATUS_UNSET (0)
    
    typedef apr_status_t h2_io_data_cb(void *ctx, const char *data, apr_off_t len);
    
    typedef int h2_stream_pri_cmp_fn(int stream_id1, int stream_id2, void *session);
    typedef struct h2_stream *h2_stream_get_fn(struct h2_session *session, int stream_id);
    
    /* Note key to attach stream id to conn_rec/request_rec instances */
    #define H2_HDR_CONFORMANCE      "http2-hdr-conformance"
    #define H2_HDR_CONFORMANCE_UNSAFE      "unsafe"
    #define H2_PUSH_MODE_NOTE       "http2-push-mode"
    
    
    #if AP_MODULE_MAGIC_AT_LEAST(20211221, 6)
    #define AP_HAS_RESPONSE_BUCKETS     1
    
    #else /* AP_MODULE_MAGIC_AT_LEAST(20211221, 6) */
    #define AP_HAS_RESPONSE_BUCKETS     0
    
    #endif /* else AP_MODULE_MAGIC_AT_LEAST(20211221, 6) */
    
    #endif /* defined(__mod_h2__h2__) */
    ������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c1_io.c���������������������������������������������������������������0000664�0001751�0001751�00000043756�14473316336�017113� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_strings.h>
    #include <ap_mpm.h>
    #include <mpm_common.h>
    
    #include <httpd.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <http_connection.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_ssl.h>
    
    #include "h2_private.h"
    #include "h2_bucket_eos.h"
    #include "h2_config.h"
    #include "h2_c1.h"
    #include "h2_c1_io.h"
    #include "h2_protocol.h"
    #include "h2_session.h"
    #include "h2_util.h"
    
    #define TLS_DATA_MAX          (16*1024) 
    
    /* Calculated like this: assuming MTU 1500 bytes
     * 1500 - 40 (IP) - 20 (TCP) - 40 (TCP options) 
     *      - TLS overhead (60-100) 
     * ~= 1300 bytes */
    #define WRITE_SIZE_INITIAL    1300
    
    /* The maximum we'd like to write in one chunk is
     * the max size of a TLS record. When pushing
     * many frames down the h2 connection, this might
     * align differently because of headers and other
     * frames or simply as not sufficient data is
     * in a response body.
     * However keeping frames at or below this limit
     * should make optimizations at the layer that writes
     * to TLS easier.
     */
    #define WRITE_SIZE_MAX        (TLS_DATA_MAX) 
    
    #define BUF_REMAIN            ((apr_size_t)(bmax-off))
    
    static void h2_c1_io_bb_log(conn_rec *c, int stream_id, int level,
                                const char *tag, apr_bucket_brigade *bb)
    {
        char buffer[16 * 1024];
        const char *line = "(null)";
        int bmax = sizeof(buffer)/sizeof(buffer[0]);
        int off = 0;
        apr_bucket *b;
        
        (void)stream_id;
        if (bb) {
            memset(buffer, 0, bmax--);
            for (b = APR_BRIGADE_FIRST(bb); 
                 bmax && (b != APR_BRIGADE_SENTINEL(bb));
                 b = APR_BUCKET_NEXT(b)) {
                
                if (APR_BUCKET_IS_METADATA(b)) {
                    if (APR_BUCKET_IS_EOS(b)) {
                        off += apr_snprintf(buffer+off, BUF_REMAIN, "eos ");
                    }
                    else if (APR_BUCKET_IS_FLUSH(b)) {
                        off += apr_snprintf(buffer+off, BUF_REMAIN, "flush ");
                    }
                    else if (AP_BUCKET_IS_EOR(b)) {
                        off += apr_snprintf(buffer+off, BUF_REMAIN, "eor ");
                    }
                    else if (H2_BUCKET_IS_H2EOS(b)) {
                        off += apr_snprintf(buffer+off, BUF_REMAIN, "h2eos ");
                    }
                    else {
                        off += apr_snprintf(buffer+off, BUF_REMAIN, "meta(unknown) ");
                    }
                }
                else {
                    const char *btype = "data";
                    if (APR_BUCKET_IS_FILE(b)) {
                        btype = "file";
                    }
                    else if (APR_BUCKET_IS_PIPE(b)) {
                        btype = "pipe";
                    }
                    else if (APR_BUCKET_IS_SOCKET(b)) {
                        btype = "socket";
                    }
                    else if (APR_BUCKET_IS_HEAP(b)) {
                        btype = "heap";
                    }
                    else if (APR_BUCKET_IS_TRANSIENT(b)) {
                        btype = "transient";
                    }
                    else if (APR_BUCKET_IS_IMMORTAL(b)) {
                        btype = "immortal";
                    }
    #if APR_HAS_MMAP
                    else if (APR_BUCKET_IS_MMAP(b)) {
                        btype = "mmap";
                    }
    #endif
                    else if (APR_BUCKET_IS_POOL(b)) {
                        btype = "pool";
                    }
                    
                    off += apr_snprintf(buffer+off, BUF_REMAIN, "%s[%ld] ", 
                                        btype, 
                                        (long)(b->length == ((apr_size_t)-1)? -1UL : b->length));
                }
            }
            line = *buffer? buffer : "(empty)";
        }
        /* Intentional no APLOGNO */
        ap_log_cerror(APLOG_MARK, level, 0, c, "h2_session(%ld)-%s: %s", 
                      c->id, tag, line);
    
    }
    #define C1_IO_BB_LOG(c, stream_id, level, tag, bb) \
        if (APLOG_C_IS_LEVEL(c, level)) { \
            h2_c1_io_bb_log((c), (stream_id), (level), (tag), (bb)); \
        }
    
    
    apr_status_t h2_c1_io_init(h2_c1_io *io, h2_session *session)
    {
        conn_rec *c = session->c1;
    
        io->session = session;
        io->output = apr_brigade_create(c->pool, c->bucket_alloc);
        io->is_tls = ap_ssl_conn_is_ssl(session->c1);
        io->buffer_output  = io->is_tls;
        io->flush_threshold = 4 * (apr_size_t)h2_config_sgeti64(session->s, H2_CONF_STREAM_MAX_MEM);
    
        if (io->buffer_output) {
            /* This is what we start with, 
             * see https://issues.apache.org/jira/browse/TS-2503 
             */
            io->warmup_size = h2_config_sgeti64(session->s, H2_CONF_TLS_WARMUP_SIZE);
            io->cooldown_usecs = (h2_config_sgeti(session->s, H2_CONF_TLS_COOLDOWN_SECS)
                                  * APR_USEC_PER_SEC);
            io->cooldown_usecs = 0;
            io->write_size = (io->cooldown_usecs > 0?
                              WRITE_SIZE_INITIAL : WRITE_SIZE_MAX);
        }
        else {
            io->warmup_size = 0;
            io->cooldown_usecs = 0;
            io->write_size = 0;
        }
    
        if (APLOGctrace1(c)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, c,
                          "h2_c1_io(%ld): init, buffering=%d, warmup_size=%ld, "
                          "cd_secs=%f", c->id, io->buffer_output,
                          (long)io->warmup_size,
                          ((double)io->cooldown_usecs/APR_USEC_PER_SEC));
        }
    
        return APR_SUCCESS;
    }
    
    static void append_scratch(h2_c1_io *io)
    {
        if (io->scratch && io->slen > 0) {
            apr_bucket *b = apr_bucket_heap_create(io->scratch, io->slen,
                                                   apr_bucket_free,
                                                   io->session->c1->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(io->output, b);
            io->buffered_len += io->slen;
            io->scratch = NULL;
            io->slen = io->ssize = 0;
        }
    }
    
    static apr_size_t assure_scratch_space(h2_c1_io *io) {
        apr_size_t remain = io->ssize - io->slen; 
        if (io->scratch && remain == 0) {
            append_scratch(io);
        }
        if (!io->scratch) {
            /* we control the size and it is larger than what buckets usually
             * allocate. */
            io->scratch = apr_bucket_alloc(io->write_size, io->session->c1->bucket_alloc);
            io->ssize = io->write_size;
            io->slen = 0;
            remain = io->ssize;
        }
        return remain;
    }
        
    static apr_status_t read_to_scratch(h2_c1_io *io, apr_bucket *b)
    {
        apr_status_t status;
        const char *data;
        apr_size_t len;
        
        if (!b->length) {
            return APR_SUCCESS;
        }
        
        ap_assert(b->length <= (io->ssize - io->slen));
        if (APR_BUCKET_IS_FILE(b)) {
            apr_bucket_file *f = (apr_bucket_file *)b->data;
            apr_file_t *fd = f->fd;
            apr_off_t offset = b->start;
            
            len = b->length;
            /* file buckets will read 8000 byte chunks and split
             * themselves. However, we do know *exactly* how many
             * bytes we need where. So we read the file directly to
             * where we need it.
             */
            status = apr_file_seek(fd, APR_SET, &offset);
            if (status != APR_SUCCESS) {
                return status;
            }
            status = apr_file_read(fd, io->scratch + io->slen, &len);
            if (status != APR_SUCCESS && status != APR_EOF) {
                return status;
            }
            io->slen += len;
        }
        else if (APR_BUCKET_IS_MMAP(b)) {
            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, io->session->c1,
                          "h2_c1_io(%ld): seeing mmap bucket of size %ld, scratch remain=%ld",
                          io->session->c1->id, (long)b->length, (long)(io->ssize - io->slen));
            status = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
            if (status == APR_SUCCESS) {
                memcpy(io->scratch+io->slen, data, len);
                io->slen += len;
            }
        }
        else {
            status = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
            if (status == APR_SUCCESS) {
                memcpy(io->scratch+io->slen, data, len);
                io->slen += len;
            }
        }
        return status;
    }
    
    static apr_status_t pass_output(h2_c1_io *io, int flush)
    {
        conn_rec *c = io->session->c1;
        apr_off_t bblen = 0;
        apr_status_t rv;
    
        if (io->is_passing) {
            /* recursive call, may be triggered by an H2EOS bucket
             * being destroyed and triggering sending more data? */
            AP_DEBUG_ASSERT(0);
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10456)
                          "h2_c1_io(%ld): recursive call of h2_c1_io_pass. "
                          "Denied to prevent output corruption. This "
                          "points to a bug in the HTTP/2 implementation.",
                          c->id);
            return APR_EGENERAL;
        }
        io->is_passing = 1;
    
        append_scratch(io);
        if (flush) {
            if (!APR_BUCKET_IS_FLUSH(APR_BRIGADE_LAST(io->output))) {
                apr_bucket *b = apr_bucket_flush_create(c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(io->output, b);
            }
        }
        if (APR_BRIGADE_EMPTY(io->output)) {
            rv = APR_SUCCESS;
            goto cleanup;
        }
    
        io->unflushed = !APR_BUCKET_IS_FLUSH(APR_BRIGADE_LAST(io->output));
        apr_brigade_length(io->output, 0, &bblen);
        C1_IO_BB_LOG(c, 0, APLOG_TRACE2, "out", io->output);
    
        rv = ap_pass_brigade(c->output_filters, io->output);
        if (APR_SUCCESS != rv) goto cleanup;
        io->bytes_written += (apr_size_t)bblen;
    
        if (io->write_size < WRITE_SIZE_MAX
             && io->bytes_written >= io->warmup_size) {
            /* connection is hot, use max size */
            io->write_size = WRITE_SIZE_MAX;
        }
        else if (io->cooldown_usecs > 0
                 && io->write_size > WRITE_SIZE_INITIAL) {
            apr_time_t now = apr_time_now();
            if ((now - io->last_write) >= io->cooldown_usecs) {
                /* long time not written, reset write size */
                io->write_size = WRITE_SIZE_INITIAL;
                io->bytes_written = 0;
            }
            else {
                io->last_write = now;
            }
        }
    
    cleanup:
        if (APR_SUCCESS != rv) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(03044)
                          "h2_c1_io(%ld): pass_out brigade %ld bytes",
                          c->id, (long)bblen);
        }
        apr_brigade_cleanup(io->output);
        io->buffered_len = 0;
        io->is_passing = 0;
        return rv;
    }
    
    int h2_c1_io_needs_flush(h2_c1_io *io)
    {
        return io->buffered_len >= io->flush_threshold;
    }
    
    int h2_c1_io_pending(h2_c1_io *io)
    {
        return !APR_BRIGADE_EMPTY(io->output) || (io->scratch && io->slen > 0);
    }
    
    apr_status_t h2_c1_io_pass(h2_c1_io *io)
    {
        apr_status_t rv = APR_SUCCESS;
    
        if (h2_c1_io_pending(io)) {
            rv = pass_output(io, 0);
        }
        return rv;
    }
    
    apr_status_t h2_c1_io_assure_flushed(h2_c1_io *io)
    {
        apr_status_t rv = APR_SUCCESS;
    
        if (h2_c1_io_pending(io) || io->unflushed) {
            rv = pass_output(io, 1);
            if (APR_SUCCESS != rv) goto cleanup;
        }
    cleanup:
        return rv;
    }
    
    apr_status_t h2_c1_io_add_data(h2_c1_io *io, const char *data, size_t length)
    {
        apr_status_t status = APR_SUCCESS;
        apr_size_t remain;
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, io->session->c1,
                      "h2_c1_io(%ld): adding %ld data bytes",
                      io->session->c1->id, (long)length);
        if (io->buffer_output) {
            while (length > 0) {
                remain = assure_scratch_space(io);
                if (remain >= length) {
                    memcpy(io->scratch + io->slen, data, length);
                    io->slen += length;
                    length = 0;
                }
                else {
                    memcpy(io->scratch + io->slen, data, remain);
                    io->slen += remain;
                    data += remain;
                    length -= remain;
                }
            }
        }
        else {
            status = apr_brigade_write(io->output, NULL, NULL, data, length);
            io->buffered_len += length;
        }
        return status;
    }
    
    apr_status_t h2_c1_io_append(h2_c1_io *io, apr_bucket_brigade *bb)
    {
        apr_bucket *b;
        apr_status_t rv = APR_SUCCESS;
    
        while (!APR_BRIGADE_EMPTY(bb)) {
            b = APR_BRIGADE_FIRST(bb);
            if (APR_BUCKET_IS_METADATA(b) || APR_BUCKET_IS_MMAP(b)) {
                /* need to finish any open scratch bucket, as meta data
                 * needs to be forward "in order". */
                append_scratch(io);
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(io->output, b);
            }
            else if (io->buffer_output) {
                apr_size_t remain = assure_scratch_space(io);
                if (b->length > remain) {
                    apr_bucket_split(b, remain);
                    if (io->slen == 0) {
                        /* complete write_size bucket, append unchanged */
                        APR_BUCKET_REMOVE(b);
                        APR_BRIGADE_INSERT_TAIL(io->output, b);
                        io->buffered_len += b->length;
                        continue;
                    }
                }
                else {
                    /* bucket fits in remain, copy to scratch */
                    rv = read_to_scratch(io, b);
                    apr_bucket_delete(b);
                    if (APR_SUCCESS != rv) goto cleanup;
                    continue;
                }
            }
            else {
                /* no buffering, forward buckets setaside on flush */
                apr_bucket_setaside(b, io->session->c1->pool);
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(io->output, b);
                io->buffered_len += b->length;
            }
        }
    cleanup:
        return rv;
    }
    
    static apr_status_t c1_in_feed_bucket(h2_session *session,
                                          apr_bucket *b, apr_ssize_t *inout_len)
    {
        apr_status_t rv = APR_SUCCESS;
        apr_size_t len;
        const char *data;
        ssize_t n;
    
        rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
        while (APR_SUCCESS == rv && len > 0) {
            n = nghttp2_session_mem_recv(session->ngh2, (const uint8_t *)data, len);
    
            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, session->c1,
                          H2_SSSN_MSG(session, "fed %ld bytes to nghttp2, %ld read"),
                          (long)len, (long)n);
            if (n < 0) {
                if (nghttp2_is_fatal((int)n)) {
                    h2_session_event(session, H2_SESSION_EV_PROTO_ERROR,
                                     (int)n, nghttp2_strerror((int)n));
                    rv = APR_EGENERAL;
                }
            }
            else {
                *inout_len += n;
                if ((apr_ssize_t)len <= n) {
                    break;
                }
                len -= (apr_size_t)n;
                data += n;
            }
        }
    
        return rv;
    }
    
    static apr_status_t c1_in_feed_brigade(h2_session *session,
                                           apr_bucket_brigade *bb,
                                           apr_ssize_t *inout_len)
    {
        apr_status_t rv = APR_SUCCESS;
        apr_bucket* b;
    
        *inout_len = 0;
        while (!APR_BRIGADE_EMPTY(bb)) {
            b = APR_BRIGADE_FIRST(bb);
            if (!APR_BUCKET_IS_METADATA(b)) {
                rv = c1_in_feed_bucket(session, b, inout_len);
                if (APR_SUCCESS != rv) goto cleanup;
            }
            apr_bucket_delete(b);
        }
    cleanup:
        apr_brigade_cleanup(bb);
        return rv;
    }
    
    static apr_status_t read_and_feed(h2_session *session)
    {
        apr_ssize_t bytes_fed, bytes_requested;
        apr_status_t rv;
    
        bytes_requested = H2MAX(APR_BUCKET_BUFF_SIZE, session->max_stream_mem * 4);
        rv = ap_get_brigade(session->c1->input_filters,
                            session->bbtmp, AP_MODE_READBYTES,
                            APR_NONBLOCK_READ, bytes_requested);
    
        if (APR_SUCCESS == rv) {
            if (!APR_BRIGADE_EMPTY(session->bbtmp)) {
                h2_util_bb_log(session->c1, session->id, APLOG_TRACE2, "c1 in",
                               session->bbtmp);
                rv = c1_in_feed_brigade(session, session->bbtmp, &bytes_fed);
                session->io.bytes_read += bytes_fed;
            }
            else {
                rv = APR_EAGAIN;
            }
        }
        return rv;
    }
    
    apr_status_t h2_c1_read(h2_session *session)
    {
        apr_status_t rv;
    
        /* H2_IN filter handles all incoming data against the session.
         * We just pull at the filter chain to make it happen */
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
                      H2_SSSN_MSG(session, "session_read start"));
        rv = read_and_feed(session);
    
        if (APR_SUCCESS == rv) {
            h2_session_dispatch_event(session, H2_SESSION_EV_INPUT_PENDING, 0, NULL);
        }
        else if (APR_STATUS_IS_EAGAIN(rv)) {
            /* Signal that we have exhausted the input momentarily.
             * This might switch to polling the socket */
            h2_session_dispatch_event(session, H2_SESSION_EV_INPUT_EXHAUSTED, 0, NULL);
        }
        else if (APR_SUCCESS != rv) {
            if (APR_STATUS_IS_ETIMEDOUT(rv)
                || APR_STATUS_IS_ECONNABORTED(rv)
                || APR_STATUS_IS_ECONNRESET(rv)
                || APR_STATUS_IS_EOF(rv)
                || APR_STATUS_IS_EBADF(rv)) {
                /* common status for a client that has left */
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, session->c1,
                              H2_SSSN_MSG(session, "input gone"));
            }
            else {
                /* uncommon status, log on INFO so that we see this */
                ap_log_cerror( APLOG_MARK, APLOG_DEBUG, rv, session->c1,
                              H2_SSSN_LOG(APLOGNO(02950), session,
                              "error reading, terminating"));
            }
            h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, 0, NULL);
        }
    
        apr_brigade_cleanup(session->bbtmp);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, session->c1,
                      H2_SSSN_MSG(session, "session_read done"));
        return rv;
    }
    ������������������httpd-2.4.64/modules/http2/h2_ws.h������������������������������������������������������������������0000664�0001751�0001751�00000002462�14473316336�016544� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_ws__
    #define __mod_h2__h2_ws__
    
    #include "h2.h"
    
    /**
     * Rewrite a websocket request.
     *
     * @param req the h2 request to rewrite
     * @param c2 the connection to process the request on
     * @param no_body != 0 iff the request is known to have no body
     * @return the websocket request for internal submit
     */
    const h2_request *h2_ws_rewrite_request(const h2_request *req,
                                            conn_rec *c2, int no_body);
    
    void h2_ws_register_hooks(void);
    
    #endif /* defined(__mod_h2__h2_ws__) */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c1_io.h���������������������������������������������������������������0000664�0001751�0001751�00000005606�14447501300�017074� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_c1_io__
    #define __mod_h2__h2_c1_io__
    
    struct h2_config;
    struct h2_session;
    
    /* h2_io is the basic handler of a httpd connection. It keeps two brigades,
     * one for input, one for output and works with the installed connection
     * filters.
     * The read is done via a callback function, so that input can be processed
     * directly without copying.
     */
    typedef struct {
        struct h2_session *session;
        apr_bucket_brigade *output;
    
        int is_tls;
        int unflushed;
        apr_time_t cooldown_usecs;
        apr_int64_t warmup_size;
        
        apr_size_t write_size;
        apr_time_t last_write;
        apr_int64_t bytes_read;
        apr_int64_t bytes_written;
        
        int buffer_output;
        apr_off_t buffered_len;
        apr_off_t flush_threshold;
        unsigned int is_flushed : 1;
        unsigned int is_passing : 1;
    
        char *scratch;
        apr_size_t ssize;
        apr_size_t slen;
    } h2_c1_io;
    
    apr_status_t h2_c1_io_init(h2_c1_io *io, struct h2_session *session);
    
    /**
     * Append data to the buffered output.
     * @param buf the data to append
     * @param length the length of the data to append
     */
    apr_status_t h2_c1_io_add_data(h2_c1_io *io,
                             const char *buf,
                             size_t length);
    
    apr_status_t h2_c1_io_add(h2_c1_io *io, apr_bucket *b);
    
    apr_status_t h2_c1_io_append(h2_c1_io *io, apr_bucket_brigade *bb);
    
    /**
     * Pass any buffered data on to the connection output filters.
     * @param io the connection io
     */
    apr_status_t h2_c1_io_pass(h2_c1_io *io);
    
    /**
     * if there is any data pendiong or was any data send
     * since the last FLUSH, send out a FLUSH now.
     */
    apr_status_t h2_c1_io_assure_flushed(h2_c1_io *io);
    
    /**
     * Check if the buffered amount of data needs flushing.
     */
    int h2_c1_io_needs_flush(h2_c1_io *io);
    
    /**
     * Check if we have output pending.
     */
    int h2_c1_io_pending(h2_c1_io *io);
    
    struct h2_session;
    
    /**
     * Read c1 input and pass it on to nghttp2.
     * @param session the session
     * @param when_pending != 0 if only pending input (sitting in filters)
     *                     needs to be read
     */
    apr_status_t h2_c1_read(struct h2_session *session);
    
    #endif /* defined(__mod_h2__h2_c1_io__) */
    ��������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c1.h������������������������������������������������������������������0000664�0001751�0001751�00000005421�14356741666�016424� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_c1__
    #define __mod_h2__h2_c1__
    
    #include <http_core.h>
    
    struct h2_conn_ctx_t;
    
    extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_in) *h2_c_logio_add_bytes_in;
    extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *h2_c_logio_add_bytes_out;
    
    /* Initialize this child process for h2 primary connection work,
     * to be called once during child init before multi processing
     * starts.
     */
    apr_status_t h2_c1_child_init(apr_pool_t *pool, server_rec *s);
    
    /**
     * Setup the primary connection and our context for HTTP/2 processing
     *
     * @param c the connection HTTP/2 is starting on
     * @param r the upgrade request that still awaits an answer, optional
     * @param s the server selected for this connection (can be != c->base_server)
     */
    apr_status_t h2_c1_setup(conn_rec *c, request_rec *r, server_rec *s);
    
    /**
     * Run the HTTP/2 primary connection in synchronous fashion.
     * Return when the HTTP/2 session is done
     * and the connection will close or a fatal error occurred.
     *
     * @param c the http2 connection to run
     * @return APR_SUCCESS when session is done.
     */
    apr_status_t h2_c1_run(conn_rec *c);
    
    /**
     * The primary connection is about to close. If we have not send a GOAWAY
     * yet, this is the last chance.
     */
    apr_status_t h2_c1_pre_close(struct h2_conn_ctx_t *ctx, conn_rec *c);
    
    /**
     * Check if the connection allows a direct detection of HTTPP/2,
     * as configurable by the H2Direct directive.
     * @param c the connection to check on
     * @return != 0 if direct detection is enabled
     */
    int h2_c1_allows_direct(conn_rec *c);
    
    /**
     * Check if the "Upgrade" HTTP/1.1 mode of protocol switching is enabled
     * for the given request.
     * @param r the request to check
     * @return != 0 iff Upgrade switching is enabled
     */
    int h2_c1_can_upgrade(request_rec *r);
    
    /* Register hooks for h2 handling on primary connections.
     */
    void h2_c1_register_hooks(void);
    
    /**
     * Child is about to be stopped, release unused resources
     */
    void h2_c1_child_stopping(apr_pool_t *pool, int graceful);
    
    #endif /* defined(__mod_h2__h2_c1__) */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_headers.h�������������������������������������������������������������0000664�0001751�0001751�00000007032�14356741666�017534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_headers__
    #define __mod_h2__h2_headers__
    
    #include "h2.h"
    
    #if !AP_HAS_RESPONSE_BUCKETS
    
    struct h2_bucket_beam;
    
    typedef struct h2_headers h2_headers;
    struct h2_headers {
        int         status;
        apr_table_t *headers;
        apr_table_t *notes;
        apr_off_t   raw_bytes;      /* RAW network bytes that generated this request - if known. */
    };
    
    
    extern const apr_bucket_type_t h2_bucket_type_headers;
    
    #define H2_BUCKET_IS_HEADERS(e)     (e->type == &h2_bucket_type_headers)
    
    apr_bucket * h2_bucket_headers_make(apr_bucket *b, h2_headers *r); 
    
    apr_bucket * h2_bucket_headers_create(apr_bucket_alloc_t *list, 
                                           h2_headers *r);
                                           
    h2_headers *h2_bucket_headers_get(apr_bucket *b);
    
    /**
     * Create the headers from the given status and headers
     * @param status the headers status
     * @param header the headers of the headers
     * @param notes  the notes carried by the headers
     * @param raw_bytes the raw network bytes (if known) used to transmit these
     * @param pool the memory pool to use
     */
    h2_headers *h2_headers_create(int status, const apr_table_t *header,
                                  const apr_table_t *notes, apr_off_t raw_bytes,
                                  apr_pool_t *pool);
    
    /**
     * Create the headers from the given request_rec.
     * @param r the request record which was processed
     * @param status the headers status
     * @param header the headers of the headers
     * @param pool the memory pool to use
     */
    h2_headers *h2_headers_rcreate(request_rec *r, int status, 
                                   const apr_table_t *header, apr_pool_t *pool);
    
    /**
     * Copy the headers into another pool. This will not copy any
     * header strings.
     */
    h2_headers *h2_headers_copy(apr_pool_t *pool, h2_headers *h);
    
    /**
     * Clone the headers into another pool. This will also clone any
     * header strings.
     */
    h2_headers *h2_headers_clone(apr_pool_t *pool, h2_headers *h);
    
    /**
     * Create the headers for the given error.
     * @param type the error code
     * @param req the original h2_request
     * @param pool the memory pool to use
     */
    h2_headers *h2_headers_die(apr_status_t type,
                               const struct h2_request *req, apr_pool_t *pool);
    
    int h2_headers_are_final_response(h2_headers *headers);
    
    /**
     * Give the number of bytes of all contained header strings.
     */
    apr_size_t h2_headers_length(h2_headers *headers);
    
    /**
     * For H2HEADER buckets, return the length of all contained header strings.
     * For all other buckets, return 0.
     */
    apr_size_t h2_bucket_headers_headers_length(apr_bucket *b);
    
    apr_bucket *h2_bucket_headers_clone(apr_bucket *b, apr_pool_t *pool,
                                        apr_bucket_alloc_t *list);
    
    #endif /* !AP_HAS_RESPONSE_BUCKETS */
    
    #endif /* defined(__mod_h2__h2_headers__) */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_proxy_util.h����������������������������������������������������������0000664�0001751�0001751�00000022514�14356741666�020341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_proxy_util__
    #define __mod_h2__h2_proxy_util__
    
    /*******************************************************************************
     * some debugging/format helpers
     ******************************************************************************/
    struct h2_proxy_request;
    struct nghttp2_frame;
    
    int h2_proxy_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen);
    
    /*******************************************************************************
     * ihash - hash for structs with int identifier
     ******************************************************************************/
    typedef struct h2_proxy_ihash_t h2_proxy_ihash_t;
    typedef int h2_proxy_ihash_iter_t(void *ctx, void *val);
    
    /**
     * Create a hash for structures that have an identifying int member.
     * @param pool the pool to use
     * @param offset_of_int the offsetof() the int member in the struct
     */
    h2_proxy_ihash_t *h2_proxy_ihash_create(apr_pool_t *pool, size_t offset_of_int);
    
    size_t h2_proxy_ihash_count(h2_proxy_ihash_t *ih);
    int h2_proxy_ihash_empty(h2_proxy_ihash_t *ih);
    void *h2_proxy_ihash_get(h2_proxy_ihash_t *ih, int id);
    
    /**
     * Iterate over the hash members (without defined order) and invoke
     * fn for each member until 0 is returned.
     * @param ih the hash to iterate over
     * @param fn the function to invoke on each member
     * @param ctx user supplied data passed into each iteration call
     * @return 0 if one iteration returned 0, otherwise != 0
     */
    int h2_proxy_ihash_iter(h2_proxy_ihash_t *ih, h2_proxy_ihash_iter_t *fn, void *ctx);
    
    void h2_proxy_ihash_add(h2_proxy_ihash_t *ih, void *val);
    void h2_proxy_ihash_remove(h2_proxy_ihash_t *ih, int id);
    void h2_proxy_ihash_remove_val(h2_proxy_ihash_t *ih, void *val);
    void h2_proxy_ihash_clear(h2_proxy_ihash_t *ih);
    
    size_t h2_proxy_ihash_shift(h2_proxy_ihash_t *ih, void **buffer, size_t max);
    size_t h2_proxy_ihash_ishift(h2_proxy_ihash_t *ih, int *buffer, size_t max);
    
    /*******************************************************************************
     * iqueue - sorted list of int with user defined ordering
     ******************************************************************************/
    typedef struct h2_proxy_iqueue {
        int *elts;
        int head;
        int nelts;
        int nalloc;
        apr_pool_t *pool;
    } h2_proxy_iqueue;
    
    /**
     * Comparator for two int to determine their order.
     *
     * @param i1 first int to compare
     * @param i2 second int to compare
     * @param ctx provided user data
     * @return value is the same as for strcmp() and has the effect:
     *    == 0: s1 and s2 are treated equal in ordering
     *     < 0: s1 should be sorted before s2
     *     > 0: s2 should be sorted before s1
     */
    typedef int h2_proxy_iq_cmp(int i1, int i2, void *ctx);
    
    /**
     * Allocate a new queue from the pool and initialize.
     * @param id the identifier of the queue
     * @param pool the memory pool
     */
    h2_proxy_iqueue *h2_proxy_iq_create(apr_pool_t *pool, int capacity);
    
    /**
     * Return != 0 iff there are no tasks in the queue.
     * @param q the queue to check
     */
    int h2_proxy_iq_empty(h2_proxy_iqueue *q);
    
    /**
     * Return the number of int in the queue.
     * @param q the queue to get size on
     */
    int h2_proxy_iq_count(h2_proxy_iqueue *q);
    
    /**
     * Add a stream id to the queue. 
     *
     * @param q the queue to append the task to
     * @param sid the stream id to add
     * @param cmp the comparator for sorting
     * @param ctx user data for comparator 
     */
    void h2_proxy_iq_add(h2_proxy_iqueue *q, int sid, h2_proxy_iq_cmp *cmp, void *ctx);
    
    /**
     * Remove the stream id from the queue. Return != 0 iff task
     * was found in queue.
     * @param q the task queue
     * @param sid the stream id to remove
     * @return != 0 iff task was found in queue
     */
    int h2_proxy_iq_remove(h2_proxy_iqueue *q, int sid);
    
    /**
     * Remove all entries in the queue.
     */
    void h2_proxy_iq_clear(h2_proxy_iqueue *q);
    
    /**
     * Sort the stream idqueue again. Call if the task ordering
     * has changed.
     *
     * @param q the queue to sort
     * @param cmp the comparator for sorting
     * @param ctx user data for the comparator 
     */
    void h2_proxy_iq_sort(h2_proxy_iqueue *q, h2_proxy_iq_cmp *cmp, void *ctx);
    
    /**
     * Get the first stream id from the queue or NULL if the queue is empty. 
     * The task will be removed.
     *
     * @param q the queue to get the first task from
     * @return the first stream id of the queue, 0 if empty
     */
    int h2_proxy_iq_shift(h2_proxy_iqueue *q);
    
    /*******************************************************************************
     * common helpers
     ******************************************************************************/
    /* h2_proxy_log2(n) iff n is a power of 2 */
    unsigned char h2_proxy_log2(int n);
    
    /*******************************************************************************
     * HTTP/2 header helpers
     ******************************************************************************/
    void h2_proxy_util_camel_case_header(char *s, size_t len);
    int h2_proxy_res_ignore_header(const char *name, size_t len);
    
    /*******************************************************************************
     * nghttp2 helpers
     ******************************************************************************/
    typedef struct h2_proxy_ngheader {
        nghttp2_nv *nv;
        apr_size_t nvlen;
    } h2_proxy_ngheader;
    h2_proxy_ngheader *h2_proxy_util_nghd_make_req(apr_pool_t *p, 
                                                   const struct h2_proxy_request *req);
    
    h2_proxy_ngheader *h2_proxy_util_nghd_make(apr_pool_t *p, apr_table_t *headers);
    
    /*******************************************************************************
     * h2_proxy_request helpers
     ******************************************************************************/
    typedef struct h2_proxy_request h2_proxy_request;
    
    struct h2_proxy_request {
        const char *method; /* pseudo header values, see ch. 8.1.2.3 */
        const char *scheme;
        const char *authority;
        const char *path;
        
        apr_table_t *headers;
        
        apr_time_t request_time;
        
        int chunked;   /* iff request body needs to be forwarded as chunked */
    };
    
    h2_proxy_request *h2_proxy_req_create(int id, apr_pool_t *pool);
    apr_status_t h2_proxy_req_make(h2_proxy_request *req, apr_pool_t *pool,
                                   const char *method, const char *scheme, 
                                   const char *authority, const char *path, 
                                   apr_table_t *headers);
    
    /*******************************************************************************
     * reverse mapping for link headers
     ******************************************************************************/
    const char *h2_proxy_link_reverse_map(request_rec *r,
                                          proxy_dir_conf *conf, 
                                          const char *real_server_uri,
                                          const char *proxy_server_uri,
                                          const char *s);
    
    /*******************************************************************************
     * FIFO queue
     ******************************************************************************/
    
    /**
     * A thread-safe FIFO queue with some extra bells and whistles, if you
     * do not need anything special, better use 'apr_queue'.
     */
    typedef struct h2_proxy_fifo h2_proxy_fifo;
    
    /**
     * Create a FIFO queue that can hold up to capacity elements. Elements can
     * appear several times.
     */
    apr_status_t h2_proxy_fifo_create(h2_proxy_fifo **pfifo, apr_pool_t *pool, int capacity);
    
    /**
     * Create a FIFO set that can hold up to capacity elements. Elements only
     * appear once. Pushing an element already present does not change the
     * queue and is successful.
     */
    apr_status_t h2_proxy_fifo_set_create(h2_proxy_fifo **pfifo, apr_pool_t *pool, int capacity);
    
    apr_status_t h2_proxy_fifo_term(h2_proxy_fifo *fifo);
    apr_status_t h2_proxy_fifo_interrupt(h2_proxy_fifo *fifo);
    
    int h2_proxy_fifo_capacity(h2_proxy_fifo *fifo);
    int h2_proxy_fifo_count(h2_proxy_fifo *fifo);
    
    /**
     * Push en element into the queue. Blocks if there is no capacity left.
     * 
     * @param fifo the FIFO queue
     * @param elem the element to push
     * @return APR_SUCCESS on push, APR_EAGAIN on try_push on a full queue,
     *         APR_EEXIST when in set mode and elem already there.
     */
    apr_status_t h2_proxy_fifo_push(h2_proxy_fifo *fifo, void *elem);
    apr_status_t h2_proxy_fifo_try_push(h2_proxy_fifo *fifo, void *elem);
    
    apr_status_t h2_proxy_fifo_pull(h2_proxy_fifo *fifo, void **pelem);
    apr_status_t h2_proxy_fifo_try_pull(h2_proxy_fifo *fifo, void **pelem);
    
    /**
     * Remove the elem from the queue, will remove multiple appearances.
     * @param elem  the element to remove
     * @return APR_SUCCESS iff > 0 elems were removed, APR_EAGAIN otherwise.
     */
    apr_status_t h2_proxy_fifo_remove(h2_proxy_fifo *fifo, void *elem);
    
    
    #endif /* defined(__mod_h2__h2_proxy_util__) */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_workers.c�������������������������������������������������������������0000664�0001751�0001751�00000052136�14356741666�017615� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <apr_ring.h>
    #include <apr_thread_mutex.h>
    #include <apr_thread_cond.h>
    
    #include <mpm_common.h>
    #include <httpd.h>
    #include <http_connection.h>
    #include <http_core.h>
    #include <http_log.h>
    #include <http_protocol.h>
    
    #include "h2.h"
    #include "h2_private.h"
    #include "h2_mplx.h"
    #include "h2_c2.h"
    #include "h2_workers.h"
    #include "h2_util.h"
    
    typedef enum {
        PROD_IDLE,
        PROD_ACTIVE,
        PROD_JOINED,
    } prod_state_t;
    
    struct ap_conn_producer_t {
        APR_RING_ENTRY(ap_conn_producer_t) link;
        const char *name;
        void *baton;
        ap_conn_producer_next *fn_next;
        ap_conn_producer_done *fn_done;
        ap_conn_producer_shutdown *fn_shutdown;
        volatile prod_state_t state;
        volatile int conns_active;
    };
    
    
    typedef enum {
        H2_SLOT_FREE,
        H2_SLOT_RUN,
        H2_SLOT_ZOMBIE,
    } h2_slot_state_t;
    
    typedef struct h2_slot h2_slot;
    struct h2_slot {
        APR_RING_ENTRY(h2_slot) link;
        apr_uint32_t id;
        apr_pool_t *pool;
        h2_slot_state_t state;
        volatile int should_shutdown;
        volatile int is_idle;
        h2_workers *workers;
        ap_conn_producer_t *prod;
        apr_thread_t *thread;
        struct apr_thread_cond_t *more_work;
        int activations;
    };
    
    struct h2_workers {
        server_rec *s;
        apr_pool_t *pool;
    
        apr_uint32_t max_slots;
        apr_uint32_t min_active;
        volatile apr_time_t idle_limit;
        volatile int aborted;
        volatile int shutdown;
        int dynamic;
    
        volatile apr_uint32_t active_slots;
        volatile apr_uint32_t idle_slots;
    
        apr_threadattr_t *thread_attr;
        h2_slot *slots;
    
        APR_RING_HEAD(h2_slots_free, h2_slot) free;
        APR_RING_HEAD(h2_slots_idle, h2_slot) idle;
        APR_RING_HEAD(h2_slots_busy, h2_slot) busy;
        APR_RING_HEAD(h2_slots_zombie, h2_slot) zombie;
    
        APR_RING_HEAD(ap_conn_producer_active, ap_conn_producer_t) prod_active;
        APR_RING_HEAD(ap_conn_producer_idle, ap_conn_producer_t) prod_idle;
    
        struct apr_thread_mutex_t *lock;
        struct apr_thread_cond_t *prod_done;
        struct apr_thread_cond_t *all_done;
    };
    
    
    static void* APR_THREAD_FUNC slot_run(apr_thread_t *thread, void *wctx);
    
    static apr_status_t activate_slot(h2_workers *workers)
    {
        h2_slot *slot;
        apr_pool_t *pool;
        apr_status_t rv;
    
        if (APR_RING_EMPTY(&workers->free, h2_slot, link)) {
            return APR_EAGAIN;
        }
        slot = APR_RING_FIRST(&workers->free);
        ap_assert(slot->state == H2_SLOT_FREE);
        APR_RING_REMOVE(slot, link);
    
        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, workers->s,
                     "h2_workers: activate slot %d", slot->id);
    
        slot->state = H2_SLOT_RUN;
        slot->should_shutdown = 0;
        slot->is_idle = 0;
        slot->pool = NULL;
        ++workers->active_slots;
        rv = apr_pool_create(&pool, workers->pool);
        if (APR_SUCCESS != rv) goto cleanup;
        apr_pool_tag(pool, "h2_worker_slot");
        slot->pool = pool;
    
        rv = ap_thread_create(&slot->thread, workers->thread_attr,
                              slot_run, slot, slot->pool);
    
    cleanup:
        if (rv != APR_SUCCESS) {
            AP_DEBUG_ASSERT(0);
            slot->state = H2_SLOT_FREE;
            if (slot->pool) {
                apr_pool_destroy(slot->pool);
                slot->pool = NULL;
            }
            APR_RING_INSERT_TAIL(&workers->free, slot, h2_slot, link);
            --workers->active_slots;
        }
        return rv;
    }
    
    static void join_zombies(h2_workers *workers)
    {
        h2_slot *slot;
        apr_status_t status;
    
        while (!APR_RING_EMPTY(&workers->zombie, h2_slot, link)) {
            slot = APR_RING_FIRST(&workers->zombie);
            APR_RING_REMOVE(slot, link);
            ap_assert(slot->state == H2_SLOT_ZOMBIE);
            ap_assert(slot->thread != NULL);
    
            apr_thread_mutex_unlock(workers->lock);
            apr_thread_join(&status, slot->thread);
            apr_thread_mutex_lock(workers->lock);
    
            slot->thread = NULL;
            slot->state = H2_SLOT_FREE;
            if (slot->pool) {
                apr_pool_destroy(slot->pool);
                slot->pool = NULL;
            }
            APR_RING_INSERT_TAIL(&workers->free, slot, h2_slot, link);
        }
    }
    
    static void wake_idle_worker(h2_workers *workers, ap_conn_producer_t *prod)
    {
        if (!APR_RING_EMPTY(&workers->idle, h2_slot, link)) {
            h2_slot *slot;
            for (slot = APR_RING_FIRST(&workers->idle);
                 slot != APR_RING_SENTINEL(&workers->idle, h2_slot, link);
                 slot = APR_RING_NEXT(slot, link)) {
                 if (slot->is_idle && !slot->should_shutdown) {
                    apr_thread_cond_signal(slot->more_work);
                    slot->is_idle = 0;
                    return;
                 }
            }
        }
        if (workers->dynamic && !workers->shutdown
            && (workers->active_slots < workers->max_slots)) {
            activate_slot(workers);
        }
    }
    
    /**
     * Get the next connection to work on.
     */
    static conn_rec *get_next(h2_slot *slot)
    {
        h2_workers *workers = slot->workers;
        conn_rec *c = NULL;
        ap_conn_producer_t *prod;
        int has_more;
    
        slot->prod = NULL;
        if (!APR_RING_EMPTY(&workers->prod_active, ap_conn_producer_t, link)) {
            slot->prod = prod = APR_RING_FIRST(&workers->prod_active);
            APR_RING_REMOVE(prod, link);
            AP_DEBUG_ASSERT(PROD_ACTIVE == prod->state);
    
            c = prod->fn_next(prod->baton, &has_more);
            if (c && has_more) {
                APR_RING_INSERT_TAIL(&workers->prod_active, prod, ap_conn_producer_t, link);
                wake_idle_worker(workers, slot->prod);
            }
            else {
                prod->state = PROD_IDLE;
                APR_RING_INSERT_TAIL(&workers->prod_idle, prod, ap_conn_producer_t, link);
            }
            if (c) {
                ++prod->conns_active;
            }
        }
    
        return c;
    }
    
    static void* APR_THREAD_FUNC slot_run(apr_thread_t *thread, void *wctx)
    {
        h2_slot *slot = wctx;
        h2_workers *workers = slot->workers;
        conn_rec *c;
        apr_status_t rv;
    
        apr_thread_mutex_lock(workers->lock);
        slot->state = H2_SLOT_RUN;
        ++slot->activations;
        APR_RING_ELEM_INIT(slot, link);
        for(;;) {
            if (APR_RING_NEXT(slot, link) != slot) {
                /* slot is part of the idle ring from the last loop */
                APR_RING_REMOVE(slot, link);
                --workers->idle_slots;
            }
            slot->is_idle = 0;
    
            if (!workers->aborted && !slot->should_shutdown) {
                APR_RING_INSERT_TAIL(&workers->busy, slot, h2_slot, link);
                do {
                    c = get_next(slot);
                    if (!c) {
                        break;
                    }
                    apr_thread_mutex_unlock(workers->lock);
                    /* See the discussion at <https://github.com/icing/mod_h2/issues/195>
                     *
                     * Each conn_rec->id is supposed to be unique at a point in time. Since
                     * some modules (and maybe external code) uses this id as an identifier
                     * for the request_rec they handle, it needs to be unique for secondary
                     * connections also.
                     *
                     * The MPM module assigns the connection ids and mod_unique_id is using
                     * that one to generate identifier for requests. While the implementation
                     * works for HTTP/1.x, the parallel execution of several requests per
                     * connection will generate duplicate identifiers on load.
                     *
                     * The original implementation for secondary connection identifiers used
                     * to shift the master connection id up and assign the stream id to the
                     * lower bits. This was cramped on 32 bit systems, but on 64bit there was
                     * enough space.
                     *
                     * As issue 195 showed, mod_unique_id only uses the lower 32 bit of the
                     * connection id, even on 64bit systems. Therefore collisions in request ids.
                     *
                     * The way master connection ids are generated, there is some space "at the
                     * top" of the lower 32 bits on allmost all systems. If you have a setup
                     * with 64k threads per child and 255 child processes, you live on the edge.
                     *
                     * The new implementation shifts 8 bits and XORs in the worker
                     * id. This will experience collisions with > 256 h2 workers and heavy
                     * load still. There seems to be no way to solve this in all possible
                     * configurations by mod_h2 alone.
                     */
                    if (c->master) {
                        c->id = (c->master->id << 8)^slot->id;
                    }
                    c->current_thread = thread;
                    AP_DEBUG_ASSERT(slot->prod);
    
    #if AP_HAS_RESPONSE_BUCKETS
                    ap_process_connection(c, ap_get_conn_socket(c));
    #else
                    h2_c2_process(c, thread, slot->id);
    #endif
                    slot->prod->fn_done(slot->prod->baton, c);
    
                    apr_thread_mutex_lock(workers->lock);
                    if (--slot->prod->conns_active <= 0) {
                        apr_thread_cond_broadcast(workers->prod_done);
                    }
                    if (slot->prod->state == PROD_IDLE) {
                        APR_RING_REMOVE(slot->prod, link);
                        slot->prod->state = PROD_ACTIVE;
                        APR_RING_INSERT_TAIL(&workers->prod_active, slot->prod, ap_conn_producer_t, link);
                    }
    
                } while (!workers->aborted && !slot->should_shutdown);
                APR_RING_REMOVE(slot, link); /* no longer busy */
            }
    
            if (workers->aborted || slot->should_shutdown) {
                break;
            }
    
            join_zombies(workers);
    
            /* we are idle */
            APR_RING_INSERT_TAIL(&workers->idle, slot, h2_slot, link);
            ++workers->idle_slots;
            slot->is_idle = 1;
            if (slot->id >= workers->min_active && workers->idle_limit > 0) {
                rv = apr_thread_cond_timedwait(slot->more_work, workers->lock,
                                               workers->idle_limit);
                if (APR_TIMEUP == rv) {
                    APR_RING_REMOVE(slot, link);
                    --workers->idle_slots;
                    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, workers->s,
                                 "h2_workers: idle timeout slot %d in state %d (%d activations)",
                                 slot->id, slot->state, slot->activations);
                    break;
                }
            }
            else {
                apr_thread_cond_wait(slot->more_work, workers->lock);
            }
        }
    
        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, workers->s,
                     "h2_workers: terminate slot %d in state %d (%d activations)",
                     slot->id, slot->state, slot->activations);
        slot->is_idle = 0;
        slot->state = H2_SLOT_ZOMBIE;
        slot->should_shutdown = 0;
        APR_RING_INSERT_TAIL(&workers->zombie, slot, h2_slot, link);
        --workers->active_slots;
        if (workers->active_slots <= 0) {
            apr_thread_cond_broadcast(workers->all_done);
        }
        apr_thread_mutex_unlock(workers->lock);
    
        apr_thread_exit(thread, APR_SUCCESS);
        return NULL;
    }
    
    static void wake_all_idles(h2_workers *workers)
    {
        h2_slot *slot;
        for (slot = APR_RING_FIRST(&workers->idle);
             slot != APR_RING_SENTINEL(&workers->idle, h2_slot, link);
             slot = APR_RING_NEXT(slot, link))
        {
            apr_thread_cond_signal(slot->more_work);
        }
    }
    
    static apr_status_t workers_pool_cleanup(void *data)
    {
        h2_workers *workers = data;
        apr_time_t end, timeout = apr_time_from_sec(1);
        apr_status_t rv;
        int n = 0, wait_sec = 5;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, workers->s,
                     "h2_workers: cleanup %d workers (%d idle)",
                     workers->active_slots, workers->idle_slots);
        apr_thread_mutex_lock(workers->lock);
        workers->shutdown = 1;
        workers->aborted = 1;
        wake_all_idles(workers);
        apr_thread_mutex_unlock(workers->lock);
    
        /* wait for all the workers to become zombies and join them.
         * this gets called after the mpm shuts down and all connections
         * have either been handled (graceful) or we are forced exiting
         * (ungrateful). Either way, we show limited patience. */
        end = apr_time_now() + apr_time_from_sec(wait_sec);
        while (apr_time_now() < end) {
            apr_thread_mutex_lock(workers->lock);
            if (!(n = workers->active_slots)) {
                apr_thread_mutex_unlock(workers->lock);
                break;
            }
            wake_all_idles(workers);
            rv = apr_thread_cond_timedwait(workers->all_done, workers->lock, timeout);
            apr_thread_mutex_unlock(workers->lock);
    
            if (APR_TIMEUP == rv) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, workers->s,
                             APLOGNO(10290) "h2_workers: waiting for workers to close, "
                             "still seeing %d workers (%d idle) living",
                             workers->active_slots, workers->idle_slots);
            }
        }
        if (n) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, workers->s,
                         APLOGNO(10291) "h2_workers: cleanup, %d workers (%d idle) "
                         "did not exit after %d seconds.",
                         n, workers->idle_slots, wait_sec);
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, workers->s,
                     "h2_workers: cleanup all workers terminated");
        apr_thread_mutex_lock(workers->lock);
        join_zombies(workers);
        apr_thread_mutex_unlock(workers->lock);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, workers->s,
                     "h2_workers: cleanup zombie workers joined");
    
        return APR_SUCCESS;
    }
    
    h2_workers *h2_workers_create(server_rec *s, apr_pool_t *pchild,
                                  int max_slots, int min_active,
                                  apr_time_t idle_limit)
    {
        apr_status_t rv;
        h2_workers *workers;
        apr_pool_t *pool;
        apr_allocator_t *allocator;
        int locked = 0;
        apr_uint32_t i;
    
        ap_assert(s);
        ap_assert(pchild);
        ap_assert(idle_limit > 0);
    
        /* let's have our own pool that will be parent to all h2_worker
         * instances we create. This happens in various threads, but always
         * guarded by our lock. Without this pool, all subpool creations would
         * happen on the pool handed to us, which we do not guard.
         */
        rv = apr_allocator_create(&allocator);
        if (rv != APR_SUCCESS) {
            goto cleanup;
        }
        rv = apr_pool_create_ex(&pool, pchild, NULL, allocator);
        if (rv != APR_SUCCESS) {
            apr_allocator_destroy(allocator);
            goto cleanup;
        }
        apr_allocator_owner_set(allocator, pool);
        apr_pool_tag(pool, "h2_workers");
        workers = apr_pcalloc(pool, sizeof(h2_workers));
        if (!workers) {
            return NULL;
        }
        
        workers->s = s;
        workers->pool = pool;
        workers->min_active = min_active;
        workers->max_slots = max_slots;
        workers->idle_limit = idle_limit;
        workers->dynamic = (workers->min_active < workers->max_slots);
    
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
                     "h2_workers: created with min=%d max=%d idle_ms=%d",
                     workers->min_active, workers->max_slots,
                     (int)apr_time_as_msec(idle_limit));
    
        APR_RING_INIT(&workers->idle, h2_slot, link);
        APR_RING_INIT(&workers->busy, h2_slot, link);
        APR_RING_INIT(&workers->free, h2_slot, link);
        APR_RING_INIT(&workers->zombie, h2_slot, link);
    
        APR_RING_INIT(&workers->prod_active, ap_conn_producer_t, link);
        APR_RING_INIT(&workers->prod_idle, ap_conn_producer_t, link);
    
        rv = apr_threadattr_create(&workers->thread_attr, workers->pool);
        if (rv != APR_SUCCESS) goto cleanup;
    
        if (ap_thread_stacksize != 0) {
            apr_threadattr_stacksize_set(workers->thread_attr,
                                         ap_thread_stacksize);
            ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
                         "h2_workers: using stacksize=%ld", 
                         (long)ap_thread_stacksize);
        }
        
        rv = apr_thread_mutex_create(&workers->lock,
                                     APR_THREAD_MUTEX_DEFAULT,
                                     workers->pool);
        if (rv != APR_SUCCESS) goto cleanup;
        rv = apr_thread_cond_create(&workers->all_done, workers->pool);
        if (rv != APR_SUCCESS) goto cleanup;
        rv = apr_thread_cond_create(&workers->prod_done, workers->pool);
        if (rv != APR_SUCCESS) goto cleanup;
    
        apr_thread_mutex_lock(workers->lock);
        locked = 1;
    
        /* create the slots and put them on the free list */
        workers->slots = apr_pcalloc(workers->pool, workers->max_slots * sizeof(h2_slot));
    
        for (i = 0; i < workers->max_slots; ++i) {
            workers->slots[i].id = i;
            workers->slots[i].state = H2_SLOT_FREE;
            workers->slots[i].workers = workers;
            APR_RING_ELEM_INIT(&workers->slots[i], link);
            APR_RING_INSERT_TAIL(&workers->free, &workers->slots[i], h2_slot, link);
            rv = apr_thread_cond_create(&workers->slots[i].more_work, workers->pool);
            if (rv != APR_SUCCESS) goto cleanup;
        }
    
        /* activate the min amount of workers */
        for (i = 0; i < workers->min_active; ++i) {
            rv = activate_slot(workers);
            if (rv != APR_SUCCESS) goto cleanup;
        }
    
    cleanup:
        if (locked) {
            apr_thread_mutex_unlock(workers->lock);
        }
        if (rv == APR_SUCCESS) {
            /* Stop/join the workers threads when the MPM child exits (pchild is
             * destroyed), and as a pre_cleanup of pchild thus before the threads
             * pools (children of workers->pool) so that they are not destroyed
             * before/under us.
             */
            apr_pool_pre_cleanup_register(pchild, workers, workers_pool_cleanup);    
            return workers;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
                     "h2_workers: errors initializing");
        return NULL;
    }
    
    apr_uint32_t h2_workers_get_max_workers(h2_workers *workers)
    {
        return workers->max_slots;
    }
    
    void h2_workers_shutdown(h2_workers *workers, int graceful)
    {
        ap_conn_producer_t *prod;
    
        apr_thread_mutex_lock(workers->lock);
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, workers->s,
                     "h2_workers: shutdown graceful=%d", graceful);
        workers->shutdown = 1;
        workers->idle_limit = apr_time_from_sec(1);
        wake_all_idles(workers);
        for (prod = APR_RING_FIRST(&workers->prod_idle);
            prod != APR_RING_SENTINEL(&workers->prod_idle, ap_conn_producer_t, link);
            prod = APR_RING_NEXT(prod, link)) {
            if (prod->fn_shutdown) {
                prod->fn_shutdown(prod->baton, graceful);
            }
        }
        apr_thread_mutex_unlock(workers->lock);
    }
    
    ap_conn_producer_t *h2_workers_register(h2_workers *workers,
                                            apr_pool_t *producer_pool,
                                            const char *name,
                                            ap_conn_producer_next *fn_next,
                                            ap_conn_producer_done *fn_done,
                                            ap_conn_producer_shutdown *fn_shutdown,
                                            void *baton)
    {
        ap_conn_producer_t *prod;
    
        prod = apr_pcalloc(producer_pool, sizeof(*prod));
        APR_RING_ELEM_INIT(prod, link);
        prod->name = name;
        prod->fn_next = fn_next;
        prod->fn_done = fn_done;
        prod->fn_shutdown = fn_shutdown;
        prod->baton = baton;
    
        apr_thread_mutex_lock(workers->lock);
        prod->state = PROD_IDLE;
        APR_RING_INSERT_TAIL(&workers->prod_idle, prod, ap_conn_producer_t, link);
        apr_thread_mutex_unlock(workers->lock);
    
        return prod;
    }
    
    apr_status_t h2_workers_join(h2_workers *workers, ap_conn_producer_t *prod)
    {
        apr_status_t rv = APR_SUCCESS;
    
        apr_thread_mutex_lock(workers->lock);
        if (PROD_JOINED == prod->state) {
            AP_DEBUG_ASSERT(APR_RING_NEXT(prod, link) == prod); /* should be in no ring */
            rv = APR_EINVAL;
        }
        else {
            AP_DEBUG_ASSERT(PROD_ACTIVE == prod->state || PROD_IDLE == prod->state);
            APR_RING_REMOVE(prod, link);
            prod->state = PROD_JOINED; /* prevent further activations */
            while (prod->conns_active > 0) {
                apr_thread_cond_wait(workers->prod_done, workers->lock);
            }
            APR_RING_ELEM_INIT(prod, link); /* make it link to itself */
        }
        apr_thread_mutex_unlock(workers->lock);
        return rv;
    }
    
    apr_status_t h2_workers_activate(h2_workers *workers, ap_conn_producer_t *prod)
    {
        apr_status_t rv = APR_SUCCESS;
        apr_thread_mutex_lock(workers->lock);
        if (PROD_IDLE == prod->state) {
            APR_RING_REMOVE(prod, link);
            prod->state = PROD_ACTIVE;
            APR_RING_INSERT_TAIL(&workers->prod_active, prod, ap_conn_producer_t, link);
            wake_idle_worker(workers, prod);
        }
        else if (PROD_JOINED == prod->state) {
            rv = APR_EINVAL;
        }
        apr_thread_mutex_unlock(workers->lock);
        return rv;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/h2_c2.h������������������������������������������������������������������0000664�0001751�0001751�00000003541�14356741666�016426� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_h2__h2_c2__
    #define __mod_h2__h2_c2__
    
    #include <http_core.h>
    
    #include "h2.h"
    
    const char *h2_conn_mpm_name(void);
    int h2_mpm_supported(void);
    
    /* Initialize this child process for h2 secondary connection work,
     * to be called once during child init before multi processing
     * starts.
     */
    apr_status_t h2_c2_child_init(apr_pool_t *pool, server_rec *s);
    
    #if !AP_HAS_RESPONSE_BUCKETS
    
    conn_rec *h2_c2_create(conn_rec *c1, apr_pool_t *parent,
                           apr_bucket_alloc_t *buckt_alloc);
    
    /**
     * Process a secondary connection for a HTTP/2 stream request.
     */
    apr_status_t h2_c2_process(conn_rec *c, apr_thread_t *thread, int worker_id);
    
    #endif /* !AP_HAS_RESPONSE_BUCKETS */
    
    void h2_c2_destroy(conn_rec *c2);
    
    /**
     * Abort the I/O processing of a secondary connection. And
     * in-/output beams will return errors and c2->aborted is set.
     * @param c2 the secondary connection to abort
     * @param from the connection this is invoked from
     */
    void h2_c2_abort(conn_rec *c2, conn_rec *from);
    
    void h2_c2_register_hooks(void);
    
    #endif /* defined(__mod_h2__h2_c2__) */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_proxy_http2.dsp������������������������������������������������������0000664�0001751�0001751�00000012024�12727742623�021217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_http2" - 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_http2 - 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_http2.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_http2.mak" CFG="mod_proxy_http2 - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_http2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_http2 - 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_http2 - 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 "ssize_t=long" /FD /c
    # ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ssize_t=long" /Fd"Release\mod_proxy_http2_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 /fo"Release/mod_proxy_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_http2.so" /d LONG_NAME="http2_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib nghttp2.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /out:".\Release\mod_proxy_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http2.so
    # ADD LINK32 kernel32.lib nghttp2.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /incremental:no /debug /out:".\Release\mod_proxy_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http2.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http2 - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "ssize_t=long" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/nghttp2/lib/includes" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ssize_t=long" /Fd"Debug\mod_proxy_http2_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 /fo"Debug/mod_proxy_http2.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_http2.so" /d LONG_NAME="http2_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib nghttp2d.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /incremental:no /debug /out:".\Debug\mod_proxy_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http2.so
    # ADD LINK32 kernel32.lib nghttp2d.lib /nologo /subsystem:windows /dll /libpath:"..\..\srclib\nghttp2\lib\MSVC_obj" /incremental:no /debug /out:".\Debug\mod_proxy_http2.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http2.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_http2.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_http2 - Win32 Release"
    # Name "mod_proxy_http2 - Win32 Debug"
    # Begin Source File
    
    SOURCE=./h2_proxy_session.c
    # End Source File
    # Begin Source File
    
    SOURCE=./h2_proxy_util.c
    # End Source File
    # Begin Source File
    
    SOURCE=./mod_proxy_http2.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/NWGNUmod_http2�����������������������������������������������������������0000664�0001751�0001751�00000022465�13067530315�020011� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # This Makefile requires the environment var NGH2SRC
    # pointing to the base directory of nghttp2 source tree.
    #
    
    #
    # 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 \
    			$(SRC)/include \
    			$(NGH2SRC)/lib/ \
    			$(NGH2SRC)/lib/includes \
    			$(SERVER)/mpm/NetWare \
    			$(STDMOD)/ssl \
    			$(NWOS) \
    			$(EOLIST)
    
    #
    # These flags will come after CFLAGS
    #
    XCFLAGS		+= \
    			$(EOLIST)
    
    #
    # These defines will come after DEFINES
    #
    XDEFINES	+= \
    			-DHAVE_CONFIG_H \
    			$(EOLIST)
    
    #
    # These flags will be added to the link.opt file
    #
    XLFLAGS		+= \
    			-L$(OBJDIR) \
    			$(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_http2
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) HTTP2 Support module (w/ NGHTTP2 Lib)
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_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	= 65536
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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 = \
    	$(OBJDIR)/nghttp2.lib \
    	$(EOLIST)
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/h2_alt_svc.o \
    	$(OBJDIR)/h2_bucket_beam.o \
    	$(OBJDIR)/h2_bucket_eos.o \
    	$(OBJDIR)/h2_config.o \
    	$(OBJDIR)/h2_conn.o \
    	$(OBJDIR)/h2_conn_io.o \
    	$(OBJDIR)/h2_ctx.o \
    	$(OBJDIR)/h2_filter.o \
    	$(OBJDIR)/h2_from_h1.o \
    	$(OBJDIR)/h2_h2.o \
    	$(OBJDIR)/h2_mplx.o \
    	$(OBJDIR)/h2_ngn_shed.o \
    	$(OBJDIR)/h2_push.o \
    	$(OBJDIR)/h2_request.o \
    	$(OBJDIR)/h2_headers.o \
    	$(OBJDIR)/h2_session.o \
    	$(OBJDIR)/h2_stream.o \
    	$(OBJDIR)/h2_switch.o \
    	$(OBJDIR)/h2_task.o \
    	$(OBJDIR)/h2_util.o \
    	$(OBJDIR)/h2_workers.o \
    	$(OBJDIR)/mod_http2.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 = \
    	$(PRELUDE) \
    	$(OBJDIR)/nghttp2.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 = \
    	Libc \
    	Apache2 \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	@$(OBJDIR)/mod_http2.imp \
    	$(EOLIST)
    
    #
    # These are the OBJ files needed to create the LIB target above.
    # Paths must all use the '/' character
    #
    FILES_lib_objs := $(sort $(patsubst $(NGH2SRC)/lib/%.c,$(OBJDIR)/%.o,$(wildcard $(NGH2SRC)/lib/*.c)))
    #
    # implement targets and dependancies (leave this section alone)
    #
    
    libs :: $(OBJDIR) $(NGH2SRC)/lib/config.h $(TARGET_lib)
    
    nlms :: libs $(OBJDIR)/mod_http2.imp $(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
    	$(call COPY,$(OBJDIR)/*.nlm,        $(INSTALLBASE)/modules/)
    
    clean ::
    	$(call DEL,$(NGH2SRC)/lib/config.h)
    #
    # Any specialized rules here
    #
    vpath %.c $(NGH2SRC)/lib
    
    $(NGH2SRC)/lib/config.h : NWGNUmod_http2
    	@-$(RM) $@
    	@echo $(DL)GEN  $@$(DL)
    	@echo $(DL)/* For NetWare target.$(DL) > $@
    	@echo $(DL)** Do not edit - created by Make!$(DL) >> $@
    	@echo $(DL)*/$(DL) >> $@
    	@echo $(DL)#ifndef NGH2_CONFIG_H$(DL) >> $@
    	@echo $(DL)#define NGH2_CONFIG_H$(DL) >> $@
    	@echo #define HAVE_ARPA_INET_H 1 >> $@
    	@echo #define HAVE_CHOWN 1 >> $@
    	@echo #define HAVE_DECL_STRERROR_R 1 >> $@
    	@echo #define HAVE_DLFCN_H 1 >> $@
    	@echo #define HAVE_DUP2 1 >> $@
    	@echo #define HAVE_FCNTL_H 1 >> $@
    	@echo #define HAVE_GETCWD 1 >> $@
    	@echo #define HAVE_INTTYPES_H 1 >> $@
    	@echo #define HAVE_LIMITS_H 1 >> $@
    	@echo #define HAVE_LOCALTIME_R 1 >> $@
    	@echo #define HAVE_MALLOC 1 >> $@
    	@echo #define HAVE_MEMCHR 1 >> $@
    	@echo #define HAVE_MEMMOVE 1 >> $@
    	@echo #define HAVE_MEMORY_H 1 >> $@
    	@echo #define HAVE_MEMSET 1 >> $@
    	@echo #define HAVE_NETDB_H 1 >> $@
    	@echo #define HAVE_NETINET_IN_H 1 >> $@
    	@echo #define HAVE_PTRDIFF_T 1 >> $@
    	@echo #define HAVE_PWD_H 1 >> $@
    	@echo #define HAVE_SOCKET 1 >> $@
    	@echo #define HAVE_SQRT 1 >> $@
    	@echo #define HAVE_STDDEF_H 1 >> $@
    	@echo #define HAVE_STDINT_H 1 >> $@
    	@echo #define HAVE_STDLIB_H 1 >> $@
    	@echo #define HAVE_STRCHR 1 >> $@
    	@echo #define HAVE_STRDUP 1 >> $@
    	@echo #define HAVE_STRERROR 1 >> $@
    	@echo #define HAVE_STRERROR_R 1 >> $@
    	@echo #define HAVE_STRINGS_H 1 >> $@
    	@echo #define HAVE_STRING_H 1 >> $@
    	@echo #define HAVE_STRSTR 1 >> $@
    	@echo #define HAVE_STRTOL 1 >> $@
    	@echo #define HAVE_STRTOUL 1 >> $@
    	@echo #define HAVE_SYSLOG_H 1 >> $@
    	@echo #define HAVE_SYS_SOCKET_H 1 >> $@
    	@echo #define HAVE_SYS_STAT_H 1 >> $@
    	@echo #define HAVE_SYS_TIME_H 1 >> $@
    	@echo #define HAVE_SYS_TYPES_H 1 >> $@
    	@echo #define HAVE_TIME_H 1 >> $@
    	@echo #define HAVE_UNISTD_H 1 >> $@
    
    	@echo #define SIZEOF_INT_P 4 >> $@
    	@echo #define STDC_HEADERS 1 >> $@
    	@echo #define STRERROR_R_CHAR_P 4 >> $@
    
    # Hint to compiler a function parameter is not used
    	@echo #define _U_ >> $@
    
    	@echo #ifndef __cplusplus >> $@
    	@echo #define inline __inline >> $@
    	@echo #endif >> $@
    
    	@echo $(DL)#endif /* NGH2_CONFIG_H */$(DL) >> $@
    
    #
    # Exports from mod_http2 for mod_proxy_http2
    $(OBJDIR)/mod_http2.imp : NWGNUmod_http2
    	@-$(RM) $@
    	@echo $(DL)GEN  $@$(DL)
    	@echo $(DL) (HTTP2)$(DL) > $@
    	@echo $(DL) http2_module,$(DL) >> $@
    	@echo $(DL) nghttp2_is_fatal,$(DL) >> $@
    	@echo $(DL) nghttp2_option_del,$(DL) >> $@
    	@echo $(DL) nghttp2_option_new,$(DL) >> $@
    	@echo $(DL) nghttp2_option_set_no_auto_window_update,$(DL) >> $@
    	@echo $(DL) nghttp2_option_set_peer_max_concurrent_streams,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_del,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_new,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_set_before_frame_send_callback,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_set_on_data_chunk_recv_callback,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_set_on_frame_recv_callback,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_set_on_header_callback,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_set_on_stream_close_callback,$(DL) >> $@
    	@echo $(DL) nghttp2_session_callbacks_set_send_callback,$(DL) >> $@
    	@echo $(DL) nghttp2_session_client_new2,$(DL) >> $@
    	@echo $(DL) nghttp2_session_consume,$(DL) >> $@
    	@echo $(DL) nghttp2_session_consume_connection,$(DL) >> $@
    	@echo $(DL) nghttp2_session_del,$(DL) >> $@
    	@echo $(DL) nghttp2_session_get_remote_settings,$(DL) >> $@
    	@echo $(DL) nghttp2_session_get_stream_user_data,$(DL) >> $@
    	@echo $(DL) nghttp2_session_mem_recv,$(DL) >> $@
    	@echo $(DL) nghttp2_session_resume_data,$(DL) >> $@
    	@echo $(DL) nghttp2_session_send,$(DL) >> $@
    	@echo $(DL) nghttp2_session_want_read,$(DL) >> $@
    	@echo $(DL) nghttp2_session_want_write,$(DL) >> $@
    	@echo $(DL) nghttp2_strerror,$(DL) >> $@
    	@echo $(DL) nghttp2_submit_goaway,$(DL) >> $@
    	@echo $(DL) nghttp2_submit_ping,$(DL) >> $@
    	@echo $(DL) nghttp2_submit_request,$(DL) >> $@
    	@echo $(DL) nghttp2_submit_rst_stream,$(DL) >> $@
    	@echo $(DL) nghttp2_submit_settings,$(DL) >> $@
    	@echo $(DL) nghttp2_submit_window_update,$(DL) >> $@
    	@echo $(DL) nghttp2_version$(DL) >> $@
    
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/README.h2����������������������������������������������������������������0000664�0001751�0001751�00000004135�12757564422�016544� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������The http2 module adds support for the HTTP/2 protocol to the server.
    
    Specifically, it supports the protocols "h2" (HTTP2 over TLS) and "h2c" 
    (HTTP2 over plain HTTP connections via Upgrade). Additionally it offers
    the "direct" mode for both encrypted and unencrypted connections.
    
    You may enable it for the whole server or specific virtual hosts only. 
    
    
    BUILD
    
    If you have libnghttp2 (https://nghttp2.org) installed on your system, simply
    add 
    
        --enable-http2
    
    to your httpd ./configure invocation. Should libnghttp2 reside in a unusual
    location, add
    
        --with-nghttp2=<path>
    
    to ./configure. <path> is expected to be the installation prefix, so there
    should be a <path>/lib/libnghttp2.*. If your system support pkg-config,
    <path>/lib/pkgconfig/libnghttp2.pc will be inspected.
    
    If you want to link nghttp2 statically into the mod_http2 module, you may
    similarly to mod_ssl add
    
        --enable-nghttp2-staticlib-deps
    
    For this, the lib directory should only contain the libnghttp2.a, not its
    shared cousins.
    
    
    CONFIGURATION
    
    If mod_http2 is enabled for a site or not depends on the new "Protocols"
    directive. This directive list all protocols enabled for a server or
    virtual host.
    
    If you do not specify "Protocols" all available protocols are enabled. For
    sites using TLS, the protocol supported by mod_http2 is "h2". For cleartext
    http:, the offered protocol is "h2c".
    
    The following is an example of a server that only supports http/1.1 in
    general and offers h2 for a specific virtual host.
    
        ...
        Protocols http/1.1
        <virtualhost *:443>
            Protocols h2 http/1.1
            ...
        </virtualhost>
    
    Please see the documentation of mod_http2 for a complete list and explanation 
    of all options.
    
    
    TLS CONFIGURATION
    
    If you want to use HTTP/2 with a browser, most modern browsers will support
    it without further configuration. However, browsers so far only support
    HTTP/2 over TLS and are especially picky about the certificate and
    encryption ciphers used.
    
    Server admins may look for up-to-date information about "modern" TLS
    compatibility under: 
    
      https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/mod_proxy_http2.h��������������������������������������������������������0000664�0001751�0001751�00000001545�13237611704�020656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_HTTP2_H__
    #define __MOD_PROXY_HTTP2_H__
    
    
    #endif
    �����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http2/NWGNUmakefile������������������������������������������������������������0000664�0001751�0001751�00000007752�12715172671�017676� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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_http2.nlm \
    	$(OBJDIR)/proxyht2.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������httpd-2.4.64/modules/ssl/���������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�015104� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_config.c��������������������������������������������������������0000664�0001751�0001751�00000175013�15032734372�020727� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "util_mutex.h"
    #include "ap_provider.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->sesscache_mode         = SSL_SESS_CACHE_OFF;
        mc->sesscache              = 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);
    #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
        mc->szCryptoDevice         = NULL;
    #endif
    #ifdef HAVE_OCSP_STAPLING
        mc->stapling_cache         = NULL;
        mc->stapling_cache_mutex   = NULL;
        mc->stapling_refresh_mutex = NULL;
    #endif
    
    #ifdef HAVE_OPENSSL_KEYLOG
        mc->keylog_file = NULL;
    #endif
    #ifdef HAVE_FIPS
        mc->fips = UNSET;
    #endif
    
        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
    **  _________________________________________________________________
    */
    
    #ifdef HAVE_SSL_CONF_CMD
    static apr_status_t modssl_ctx_config_cleanup(void *ctx)
    {
        SSL_CONF_CTX_free(ctx);
        return APR_SUCCESS;
    }
    #endif
    
    static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
    {
        mctx->sc                  = NULL; /* set during module init */
    
        mctx->ssl_ctx             = NULL; /* set during module init */
    
        mctx->pks                 = NULL;
        mctx->pkp                 = NULL;
    
    #ifdef HAVE_TLS_SESSION_TICKETS
        mctx->ticket_key          = NULL;
    #endif
    
        mctx->protocol            = SSL_PROTOCOL_DEFAULT;
        mctx->protocol_set        = 0;
    
        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_check_mask      = UNSET;
    
        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;
        mctx->auth.tls13_ciphers = NULL;
    
        mctx->ocsp_mask           = UNSET;
        mctx->ocsp_force_default  = UNSET;
        mctx->ocsp_responder      = NULL;
        mctx->ocsp_resptime_skew  = UNSET;
        mctx->ocsp_resp_maxage    = UNSET;
        mctx->ocsp_responder_timeout = UNSET;
        mctx->ocsp_use_request_nonce = UNSET;
        mctx->proxy_uri              = NULL;
    
    /* Set OCSP Responder Certificate Verification variable */
        mctx->ocsp_noverify       = UNSET;
    /* Set OCSP Responder File variables */
        mctx->ocsp_verify_flags   = 0;
        mctx->ocsp_certs_file     = NULL;
        mctx->ocsp_certs          = NULL;
    
    #ifdef HAVE_OCSP_STAPLING
        mctx->stapling_enabled           = UNSET;
        mctx->stapling_resptime_skew     = UNSET;
        mctx->stapling_resp_maxage       = UNSET;
        mctx->stapling_cache_timeout     = UNSET;
        mctx->stapling_return_errors     = UNSET;
        mctx->stapling_fake_trylater     = UNSET;
        mctx->stapling_errcache_timeout  = UNSET;
        mctx->stapling_responder_timeout = UNSET;
        mctx->stapling_force_url         = NULL;
    #endif
    
    #ifdef HAVE_SRP
        mctx->srp_vfile =             NULL;
        mctx->srp_unknown_user_seed = NULL;
        mctx->srp_vbase =             NULL;
    #endif
    #ifdef HAVE_SSL_CONF_CMD
        mctx->ssl_ctx_config = SSL_CONF_CTX_new();
        apr_pool_cleanup_register(p, mctx->ssl_ctx_config,
                                  modssl_ctx_config_cleanup,
                                  apr_pool_cleanup_null);
        SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_FILE);
        SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_SERVER);
        SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_CERTIFICATE);
        mctx->ssl_ctx_param = apr_array_make(p, 5, sizeof(ssl_ctx_param_t));
    #endif
    
        mctx->ssl_check_peer_cn     = UNSET;
        mctx->ssl_check_peer_name   = UNSET;
        mctx->ssl_check_peer_expire = UNSET;
    }
    
    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, p);
    
        mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks));
    
        mctx->pks->cert_files = apr_array_make(p, 3, sizeof(char *));
        mctx->pks->key_files  = apr_array_make(p, 3, sizeof(char *));
    
    #ifdef HAVE_TLS_SESSION_TICKETS
        mctx->ticket_key = apr_pcalloc(p, sizeof(*mctx->ticket_key));
    #endif
    }
    
    static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
    {
        SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
    
        sc->mc                     = NULL;
        sc->enabled                = SSL_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;
        sc->insecure_reneg         = UNSET;
    #ifdef HAVE_TLSEXT
        sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
    #endif
    #ifndef OPENSSL_NO_COMP
        sc->compression            = UNSET;
    #endif
        sc->session_tickets        = UNSET;
    
        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, base->el, add->el)
    #define cfgMergeString(el)  cfgMerge(el, NULL)
    #define cfgMergeBool(el)    cfgMerge(el, UNSET)
    #define cfgMergeInt(el)     cfgMerge(el, UNSET)
    
    /*
     *  Merge per-server SSL configurations
     */
    
    static void modssl_ctx_cfg_merge(apr_pool_t *p,
                                     modssl_ctx_t *base,
                                     modssl_ctx_t *add,
                                     modssl_ctx_t *mrg)
    {
        if (add->protocol_set) {
            mrg->protocol_set = 1;
            mrg->protocol = add->protocol;
        }
        else {
            mrg->protocol_set = base->protocol_set;
            mrg->protocol = base->protocol;
        }
    
        cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
        cfgMergeString(pphrase_dialog_path);
    
        cfgMergeString(cert_chain);
    
        cfgMerge(crl_path, NULL);
        cfgMerge(crl_file, NULL);
        cfgMergeInt(crl_check_mask);
    
        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);
        cfgMergeString(auth.tls13_ciphers);
    
        cfgMergeInt(ocsp_mask);
        cfgMergeBool(ocsp_force_default);
        cfgMerge(ocsp_responder, NULL);
        cfgMergeInt(ocsp_resptime_skew);
        cfgMergeInt(ocsp_resp_maxage);
        cfgMergeInt(ocsp_responder_timeout);
        cfgMergeBool(ocsp_use_request_nonce);
        cfgMerge(proxy_uri, NULL);
    
    /* Set OCSP Responder Certificate Verification directive */
        cfgMergeBool(ocsp_noverify);  
    /* Set OCSP Responder File directive for importing */
        cfgMerge(ocsp_certs_file, NULL);
    
    #ifdef HAVE_OCSP_STAPLING
        cfgMergeBool(stapling_enabled);
        cfgMergeInt(stapling_resptime_skew);
        cfgMergeInt(stapling_resp_maxage);
        cfgMergeInt(stapling_cache_timeout);
        cfgMergeBool(stapling_return_errors);
        cfgMergeBool(stapling_fake_trylater);
        cfgMergeInt(stapling_errcache_timeout);
        cfgMergeInt(stapling_responder_timeout);
        cfgMerge(stapling_force_url, NULL);
    #endif
    
    #ifdef HAVE_SRP
        cfgMergeString(srp_vfile);
        cfgMergeString(srp_unknown_user_seed);
    #endif
    
    #ifdef HAVE_SSL_CONF_CMD
        cfgMergeArray(ssl_ctx_param);
    #endif
    
        cfgMergeBool(ssl_check_peer_cn);
        cfgMergeBool(ssl_check_peer_name);
        cfgMergeBool(ssl_check_peer_expire);
    }
    
    static void modssl_ctx_cfg_merge_certkeys_array(apr_pool_t *p,
                                                    apr_array_header_t *base,
                                                    apr_array_header_t *add,
                                                    apr_array_header_t *mrg)
    {
        int i;
    
        /*
         * pick up to CERTKEYS_IDX_MAX+1 entries from "add" (in which case they
         * they "knock out" their corresponding entries in "base", emulating
         * the behavior with cfgMergeString in releases up to 2.4.7)
         */
        for (i = 0; i < add->nelts && i <= CERTKEYS_IDX_MAX; i++) {
            APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(add, i, const char *);
        }
    
        /* add remaining ones from "base" */
        while (i < base->nelts) {
            APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(base, i, const char *);
            i++;
        }
    
        /* and finally, append the rest of "add" (if there are any) */
        for (i = CERTKEYS_IDX_MAX+1; i < add->nelts; i++) {
            APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(add, i, const char *);
        }
    }
    
    static void modssl_ctx_cfg_merge_server(apr_pool_t *p,
                                            modssl_ctx_t *base,
                                            modssl_ctx_t *add,
                                            modssl_ctx_t *mrg)
    {
        modssl_ctx_cfg_merge(p, base, add, mrg);
    
        /*
         * For better backwards compatibility with releases up to 2.4.7,
         * merging global and vhost-level SSLCertificateFile and
         * SSLCertificateKeyFile directives needs special treatment.
         * See also PR 56306 and 56353.
         */
        modssl_ctx_cfg_merge_certkeys_array(p, base->pks->cert_files,
                                            add->pks->cert_files,
                                            mrg->pks->cert_files);
        modssl_ctx_cfg_merge_certkeys_array(p, base->pks->key_files,
                                            add->pks->key_files,
                                            mrg->pks->key_files);
    
        cfgMergeString(pks->ca_name_path);
        cfgMergeString(pks->ca_name_file);
    
    #ifdef HAVE_TLS_SESSION_TICKETS
        cfgMergeString(ticket_key->file_path);
    #endif
    }
    
    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);
        cfgMergeInt(session_cache_timeout);
        cfgMergeBool(cipher_server_pref);
        cfgMergeBool(insecure_reneg);
    #ifdef HAVE_TLSEXT
        cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
    #endif
    #ifndef OPENSSL_NO_COMP
        cfgMergeBool(compression);
    #endif
        cfgMergeBool(session_tickets);
    
        modssl_ctx_cfg_merge_server(p, base->server, add->server, mrg->server);
    
        return mrg;
    }
    
    /*
     *  Create per-directory SSL configuration
     */
    
    static void modssl_ctx_init_proxy(SSLDirConfigRec *dc,
                                      apr_pool_t *p)
    {
        modssl_ctx_t *mctx;
    
        mctx = dc->proxy = apr_palloc(p, sizeof(*dc->proxy));
    
        modssl_ctx_init(mctx, p);
    
        mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
    
        mctx->pkp->cert_file = NULL;
        mctx->pkp->cert_path = NULL;
        mctx->pkp->ca_cert_file = NULL;
        mctx->pkp->certs     = NULL;
        mctx->pkp->ca_certs  = NULL;
    }
    
    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->szUserName             = NULL;
    
        dc->nRenegBufferSize = UNSET;
    
        dc->proxy_enabled = UNSET;
        modssl_ctx_init_proxy(dc, p);
        dc->proxy_post_config = FALSE;
    
        return dc;
    }
    
    /*
     *  Merge per-directory SSL configurations
     */
    
    static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p,
                                           modssl_ctx_t *base,
                                           modssl_ctx_t *add,
                                           modssl_ctx_t *mrg)
    {
        modssl_ctx_cfg_merge(p, base, add, mrg);
    
        cfgMergeString(pkp->cert_file);
        cfgMergeString(pkp->cert_path);
        cfgMergeString(pkp->ca_cert_file);
        cfgMergeString(pkp->certs);
        cfgMergeString(pkp->ca_certs);
    }
    
    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(szUserName);
    
        cfgMergeInt(nRenegBufferSize);
    
        mrg->proxy_post_config = add->proxy_post_config;
        if (!mrg->proxy_post_config) {
            cfgMergeBool(proxy_enabled);
            modssl_ctx_init_proxy(mrg, p);
            modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy);
    
            /* Since ssl_proxy_section_post_config() hook won't be called if there
             * is no SSLProxy* in this dir config, the ssl_ctx may still be NULL
             * here at runtime. Merging it is either a no-op (NULL => NULL) because
             * we are still before post config, or we really want to reuse the one
             * from the upper/server context (outside of <Proxy> sections).
             */
            cfgMerge(proxy->ssl_ctx, NULL);
        }
        else {
            /* The post_config hook has already merged and initialized the
             * proxy context, use it.
             */
            mrg->proxy_enabled = add->proxy_enabled;
            mrg->proxy = add->proxy;
        }
    
        return mrg;
    }
    
    /* Simply merge conf with base into conf, no third party. */
    void ssl_config_proxy_merge(apr_pool_t *p,
                                SSLDirConfigRec *base,
                                SSLDirConfigRec *conf)
    {
        if (conf->proxy_enabled == UNSET) {
            conf->proxy_enabled = base->proxy_enabled;
        }
        modssl_ctx_cfg_merge_proxy(p, base->proxy, conf->proxy, conf->proxy);
    }
    
    /*
     *  Configuration functions for particular directives
     */
    
    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;
    }
    
    const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
                                        void *dcfg,
                                        const char *arg)
    {
        SSLModConfigRec *mc = myModConfig(cmd->server);
        const char *err;
    #if MODSSL_HAVE_ENGINE_API
        ENGINE *e;
    #endif
    
        if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
            return err;
        }
    
        if (strcEQ(arg, "builtin")) {
            mc->szCryptoDevice = NULL;
        }
    #if MODSSL_HAVE_ENGINE_API
        else if ((e = ENGINE_by_id(arg))) {
            mc->szCryptoDevice = arg;
            ENGINE_free(e);
        }
    #endif
        else {
            err = "SSLCryptoDevice: Invalid argument; must be one of: "
                  "'builtin' (none)";
    #if MODSSL_HAVE_ENGINE_API
            e = ENGINE_get_first();
            while (e) {
                err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e),
                                             "' (", ENGINE_get_name(e), ")", NULL);
                /* Iterate; this call implicitly decrements the refcount
                 * on the 'old' e, per the docs in engine.h. */
                e = ENGINE_get_next(e);
            }
    #endif
            return err;
        }
    
        return NULL;
    }
    
    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_RAND_EGD
            seed->nSrc   = SSL_RSSRC_EGD;
            seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
    #else
            return apr_pstrcat(cmd->pool, "Invalid SSLRandomSeed entropy source `",
                               arg2, "': This version of " MODSSL_LIBRARY_NAME
                               " does not support the Entropy Gathering Daemon "
                               "(EGD).", NULL);
    #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_FALSE;
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, APLOGNO(10510)
                         "'SSLEngine optional' is no longer supported");
            return NULL;
        }
    
        return "Argument must be On or Off";
    }
    
    const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
    {
    #ifdef HAVE_FIPS
        SSLModConfigRec *mc = myModConfig(cmd->server);
    #endif
        const char *err;
    
        if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
            return err;
        }
    
    #ifdef HAVE_FIPS
        if ((mc->fips != UNSET) && (mc->fips != (BOOL)(flag ? TRUE : FALSE)))
            return "Conflicting SSLFIPS options, cannot be both On and Off";
        mc->fips = flag ? TRUE : FALSE;
    #else
        if (flag)
            return "SSLFIPS invalid, rebuild httpd and openssl compiled for FIPS";
    #endif
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
                                       void *dcfg,
                                       const char *arg1, const char *arg2)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
        if (arg2 == NULL) {
            arg2 = arg1;
            arg1 = "SSL";
        }
        
        if (!strcmp("SSL", arg1)) {
            /* always disable null and export ciphers */
            arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
            if (cmd->path) {
                dc->szCipherSuite = arg2;
            }
            else {
                sc->server->auth.cipher_suite = arg2;
            }
            return NULL;
        }
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        else if (!strcmp("TLSv1.3", arg1)) {
            if (cmd->path) {
                return "TLSv1.3 ciphers cannot be set inside a directory context";
            }
            sc->server->auth.tls13_ciphers = arg2;
            return NULL;
        }
    #endif
        return apr_pstrcat(cmd->pool, "protocol '", arg1, "' not supported", 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;
    
        /* If only dumping the config, don't verify the paths */
        if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) {
            return NULL;
        }
    
        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_SSLCompression(cmd_parms *cmd, void *dcfg, int flag)
    {
    #if !defined(OPENSSL_NO_COMP)
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    #ifndef SSL_OP_NO_COMPRESSION
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err)
            return "This version of OpenSSL does not support enabling "
                   "SSLCompression within <VirtualHost> sections.";
    #endif
        if (flag) {
            /* Some (packaged) versions of OpenSSL do not support
             * compression by default.  Enabling this directive would not
             * have the desired effect, so fail with an error. */
            STACK_OF(SSL_COMP) *meths = SSL_COMP_get_compression_methods();
    
            if (sk_SSL_COMP_num(meths) == 0) {
                return "This version of OpenSSL does not have any compression methods "
                    "available, cannot enable SSLCompression.";
            }
        }
        sc->compression = flag ? TRUE : FALSE;
    #else
        if (flag) {
            return "Setting Compression mode unsupported; not implemented by the SSL library";
        }
    #endif
        return 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 "SSLHonorCipherOrder unsupported; not implemented by the SSL library";
    #endif
    }
    
    const char *ssl_cmd_SSLSessionTickets(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    #ifndef SSL_OP_NO_TICKET
        return "This version of OpenSSL does not support using "
               "SSLSessionTickets.";
    #endif
        sc->session_tickets = flag ? TRUE : FALSE;
        return NULL;
    }
    
    const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag)
    {
    #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->insecure_reneg = flag?TRUE:FALSE;
        return NULL;
    #else
        return "The SSLInsecureRenegotiation directive is not available "
            "with this 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);
    
    }
    
    const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
                                           void *dcfg,
                                           const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        const char *err;
    
        /* Only check for non-ENGINE based certs. */
        if (!modssl_is_engine_id(arg)
            && (err = ssl_cmd_check_file(cmd, &arg))) {
            return err;
        }
    
        *(const char **)apr_array_push(sc->server->pks->cert_files) = arg;
        
        return NULL;
    }
    
    const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
                                              void *dcfg,
                                              const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        const char *err;
    
        /* Check keyfile exists for non-ENGINE keys. */
        if (!modssl_is_engine_id(arg)
            && (err = ssl_cmd_check_file(cmd, &arg))) {
            return err;
        }
    
        *(const char **)apr_array_push(sc->server->pks->key_files) = arg;
    
        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;
    }
    
    #ifdef HAVE_TLS_SESSION_TICKETS
    const char *ssl_cmd_SSLSessionTicketKeyFile(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->ticket_key->file_path = arg;
    
        return NULL;
    }
    #endif
    
    #define NO_PER_DIR_SSL_CA \
        "Your SSL library does not have support for per-directory CA"
    
    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;
        }
    
        if (cmd->path) {
            return NO_PER_DIR_SSL_CA;
        }
    
        /* 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;
        }
    
        if (cmd->path) {
            return NO_PER_DIR_SSL_CA;
        }
    
        /* 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_crlcheck_parse(cmd_parms *parms,
                                              const char *arg,
                                              int *mask)
    {
        const char *w;
    
        w = ap_getword_conf(parms->temp_pool, &arg);
        if (strcEQ(w, "none")) {
            *mask = SSL_CRLCHECK_NONE;
        }
        else if (strcEQ(w, "leaf")) {
            *mask = SSL_CRLCHECK_LEAF;
        }
        else if (strcEQ(w, "chain")) {
            *mask = SSL_CRLCHECK_CHAIN;
        }
        else {
            return apr_pstrcat(parms->temp_pool, parms->cmd->name,
                               ": Invalid argument '", w, "'",
                               NULL);
        }
    
        while (*arg) {
            w = ap_getword_conf(parms->temp_pool, &arg);
            if (strcEQ(w, "no_crl_for_cert_ok")) {
                *mask |= SSL_CRLCHECK_NO_CRL_FOR_CERT_OK;
            }
            else {
                return apr_pstrcat(parms->temp_pool, parms->cmd->name,
                                   ": Invalid argument '", w, "'",
                                   NULL);
            }
        }
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd,
                                             void *dcfg,
                                             const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
        return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mask);
    }
    
    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 = SSL_CVERIFY_NONE;
        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;
    }
    
    const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
                                        void *dcfg,
                                        const char *arg)
    {
        SSLModConfigRec *mc = myModConfig(cmd->server);
        const char *err, *sep, *name;
        long enabled_flags;
    
        if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
            return err;
        }
    
        /* The OpenSSL session cache mode must have both the flags
         * SSL_SESS_CACHE_SERVER and SSL_SESS_CACHE_NO_INTERNAL set if a
         * session cache is configured; NO_INTERNAL prevents the
         * OpenSSL-internal session cache being used in addition to the
         * "external" (mod_ssl-provided) cache, which otherwise causes
         * additional memory consumption. */
        enabled_flags = SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL;
    
        if (strcEQ(arg, "none")) {
            /* Nothing to do; session cache will be off. */
        }
        else if (strcEQ(arg, "nonenotnull")) {
            /* ### Having a separate mode for this seems logically
             * unnecessary; the stated purpose of sending non-empty
             * session IDs would be better fixed in OpenSSL or simply
             * doing it by default if "none" is used. */
            mc->sesscache_mode = enabled_flags;
        }
        else {
            /* Argument is of form 'name:args' or just 'name'. */
            sep = ap_strchr_c(arg, ':');
            if (sep) {
                name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
                sep++;
            }
            else {
                name = arg;
            }
    
            /* Find the provider of given name. */
            mc->sesscache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
                                               name,
                                               AP_SOCACHE_PROVIDER_VERSION);
            if (mc->sesscache) {
                /* Cache found; create it, passing anything beyond the colon. */
                mc->sesscache_mode = enabled_flags;
                err = mc->sesscache->create(&mc->sesscache_context, sep,
                                            cmd->temp_pool, cmd->pool);
            }
            else {
                apr_array_header_t *name_list;
                const char *all_names;
    
                /* Build a comma-separated list of all registered provider
                 * names: */
                name_list = ap_list_provider_names(cmd->pool,
                                                   AP_SOCACHE_PROVIDER_GROUP,
                                                   AP_SOCACHE_PROVIDER_VERSION);
                all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
    
                err = apr_psprintf(cmd->pool, "'%s' session cache not supported "
                                   "(known names: %s). Maybe you need to load the "
                                   "appropriate socache module (mod_socache_%s?).",
                                   name, all_names, name);
            }
        }
    
        if (err) {
            return apr_psprintf(cmd->pool, "SSLSessionCache: %s", err);
        }
    
        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->temp_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 if (strcEQ(w, "LegacyDNStringFormat")) {
                opt = SSL_OPT_LEGACYDNFORMAT;
            }
            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;
        ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
        ssl_require_t *require;
        const char *errstring;
    
        info->flags = AP_EXPR_FLAG_SSL_EXPR_COMPAT;
        info->filename = cmd->directive->filename;
        info->line_number = cmd->directive->line_num;
        info->module_index = APLOG_MODULE_INDEX;
        errstring = ap_expr_parse(cmd->pool, cmd->temp_pool, info, arg, NULL);
        if (errstring) {
            return apr_pstrcat(cmd->pool, "SSLRequire: ", errstring, NULL);
        }
    
        require = apr_array_push(dc->aRequirement);
        require->cpExpr = arg;
        require->mpExpr = info;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg)
    {
        SSLDirConfigRec *dc = dcfg;
        int val;
    
        val = atoi(arg);
        if (val < 0) {
            return apr_pstrcat(cmd->pool, "Invalid size for SSLRenegBufferSize: ",
                               arg, NULL);
        }
        dc->nRenegBufferSize = val;
    
        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")) {
                if (action == '-') {
                    continue;
                }
                else {
                    return "SSLProtocol: SSLv2 is no longer supported";
                }
            }
            else if (strcEQ(w, "SSLv3")) {
    #ifdef OPENSSL_NO_SSL3
                if (action != '-') {
                    return "SSLv3 not supported by this version of OpenSSL";
                }
                /* Nothing to do, the flag is not present to be toggled */
                continue;
    #else
                thisopt = SSL_PROTOCOL_SSLV3;
    #endif
            }
            else if (strcEQ(w, "TLSv1")) {
                thisopt = SSL_PROTOCOL_TLSV1;
            }
    #ifdef HAVE_TLSV1_X
            else if (strcEQ(w, "TLSv1.1")) {
                thisopt = SSL_PROTOCOL_TLSV1_1;
            }
            else if (strcEQ(w, "TLSv1.2")) {
                thisopt = SSL_PROTOCOL_TLSV1_2;
            }
            else if (SSL_HAVE_PROTOCOL_TLSV1_3 && strcEQ(w, "TLSv1.3")) {
                thisopt = SSL_PROTOCOL_TLSV1_3;
            }
    #endif
            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 {
                if (*options != SSL_PROTOCOL_NONE) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, parms->server, APLOGNO(02532)
                                 "%s: Protocol '%s' overrides already set parameter(s). "
                                 "Check if a +/- prefix is missing.",
                                 parms->cmd->name, w);
                }
                *options = thisopt;
            }
        }
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
                                    void *dcfg,
                                    const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
        sc->server->protocol_set = 1;
        return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
    }
    
    const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
        dc->proxy_enabled = flag ? TRUE : FALSE;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,
                                         void *dcfg,
                                         const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
        dc->proxy->protocol_set = 1;
        return ssl_cmd_protocol_parse(cmd, arg, &dc->proxy->protocol);
    }
    
    const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
                                            void *dcfg,
                                            const char *arg1, const char *arg2)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        
        if (arg2 == NULL) {
            arg2 = arg1;
            arg1 = "SSL";
        }
        
        if (!strcmp("SSL", arg1)) {
            /* always disable null and export ciphers */
            arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
            dc->proxy->auth.cipher_suite = arg2;
            return NULL;
        }
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        else if (!strcmp("TLSv1.3", arg1)) {
            dc->proxy->auth.tls13_ciphers = arg2;
            return NULL;
        }
    #endif
        return apr_pstrcat(cmd->pool, "protocol '", arg1, "' not supported", NULL);
    }
    
    const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
                                       void *dcfg,
                                       const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        ssl_verify_t mode = SSL_CVERIFY_NONE;
        const char *err;
    
        if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
            return err;
        }
    
        dc->proxy->auth.verify_mode = mode;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
                                            void *dcfg,
                                            const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        int depth;
        const char *err;
    
        if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
            return err;
        }
    
        dc->proxy->auth.verify_depth = depth;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
                                                  void *dcfg,
                                                  const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        const char *err;
    
        if ((err = ssl_cmd_check_file(cmd, &arg))) {
            return err;
        }
    
        dc->proxy->auth.ca_cert_file = arg;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
                                                  void *dcfg,
                                                  const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        const char *err;
    
        if ((err = ssl_cmd_check_dir(cmd, &arg))) {
            return err;
        }
    
        dc->proxy->auth.ca_cert_path = arg;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
                                                 void *dcfg,
                                                 const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        const char *err;
    
        if ((err = ssl_cmd_check_dir(cmd, &arg))) {
            return err;
        }
    
        dc->proxy->crl_path = arg;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
                                                 void *dcfg,
                                                 const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        const char *err;
    
        if ((err = ssl_cmd_check_file(cmd, &arg))) {
            return err;
        }
    
        dc->proxy->crl_file = arg;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd,
                                                  void *dcfg,
                                                  const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
        return ssl_cmd_crlcheck_parse(cmd, arg, &dc->proxy->crl_check_mask);
    }
    
    const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
                                                       void *dcfg,
                                                       const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        const char *err;
    
        if ((err = ssl_cmd_check_file(cmd, &arg))) {
            return err;
        }
    
        dc->proxy->pkp->cert_file = arg;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
                                                       void *dcfg,
                                                       const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        const char *err;
    
        if ((err = ssl_cmd_check_dir(cmd, &arg))) {
            return err;
        }
    
        dc->proxy->pkp->cert_path = arg;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *cmd,
                                                       void *dcfg,
                                                       const char *arg)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
        const char *err;
    
        if ((err = ssl_cmd_check_file(cmd, &arg))) {
            return err;
        }
    
        dc->proxy->pkp->ca_cert_file = 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;
    }
    
    static const char *ssl_cmd_ocspcheck_parse(cmd_parms *parms,
                                               const char *arg,
                                               int *mask)
    {
        const char *w;
    
        w = ap_getword_conf(parms->temp_pool, &arg);
        if (strcEQ(w, "off")) {
            *mask = SSL_OCSPCHECK_NONE;
        }
        else if (strcEQ(w, "leaf")) {
            *mask = SSL_OCSPCHECK_LEAF;
        }
        else if (strcEQ(w, "on")) {
            *mask = SSL_OCSPCHECK_CHAIN;
        }
        else {
            return apr_pstrcat(parms->temp_pool, parms->cmd->name,
                               ": Invalid argument '", w, "'",
                               NULL);
        }
    
        while (*arg) {
            w = ap_getword_conf(parms->temp_pool, &arg);
            if (strcEQ(w, "no_ocsp_for_cert_ok")) {
                *mask |= SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK;
            }
            else {
                return apr_pstrcat(parms->temp_pool, parms->cmd->name,
                                   ": Invalid argument '", w, "'",
                                   NULL);
            }
        }
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
    #ifdef OPENSSL_NO_OCSP
        if (flag) {
            return "OCSP support disabled in SSL library; cannot enable "
                "OCSP validation";
        }
    #endif
    
        return ssl_cmd_ocspcheck_parse(cmd, arg, &sc->server->ocsp_mask);
    }
    
    const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
        sc->server->ocsp_force_default = flag ? TRUE : FALSE;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
        sc->server->ocsp_responder = arg;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->ocsp_resptime_skew = atoi(arg);
        if (sc->server->ocsp_resptime_skew < 0) {
            return "SSLOCSPResponseTimeSkew: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->ocsp_resp_maxage = atoi(arg);
        if (sc->server->ocsp_resp_maxage < 0) {
            return "SSLOCSPResponseMaxAge: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->ocsp_responder_timeout = apr_time_from_sec(atoi(arg));
        if (sc->server->ocsp_responder_timeout < 0) {
            return "SSLOCSPResponderTimeout: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLOCSPUseRequestNonce(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
        sc->server->ocsp_use_request_nonce = flag ? TRUE : FALSE;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd, void *dcfg,
                                        const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->proxy_uri = apr_palloc(cmd->pool, sizeof(apr_uri_t));
        if (apr_uri_parse(cmd->pool, arg, sc->server->proxy_uri) != APR_SUCCESS) {
            return apr_psprintf(cmd->pool,
                                "SSLOCSPProxyURL: Cannot parse URL %s", arg);
        }
        return NULL;
    }
    
    /* Set OCSP responder certificate verification directive */
    const char *ssl_cmd_SSLOCSPNoVerify(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
        sc->server->ocsp_noverify = flag ? TRUE : FALSE;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
        dc->proxy->ssl_check_peer_expire = flag ? TRUE : FALSE;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
        dc->proxy->ssl_check_peer_cn = flag ? TRUE : FALSE;
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLProxyCheckPeerName(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
        dc->proxy->ssl_check_peer_name = flag ? TRUE : FALSE;
    
        return NULL;
    }
    
    const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag)
    {
    #ifdef HAVE_TLSEXT
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    
        sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
    
        return NULL;
    #else
        return "SSLStrictSNIVHostCheck failed; OpenSSL is not built with support "
               "for TLS extensions and SNI indication. Refer to the "
               "documentation, and build a compatible version of OpenSSL.";
    #endif
    }
    
    #ifdef HAVE_OCSP_STAPLING
    
    const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd,
                                        void *dcfg,
                                        const char *arg)
    {
        SSLModConfigRec *mc = myModConfig(cmd->server);
        const char *err, *sep, *name;
    
        if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
            return err;
        }
    
        /* Argument is of form 'name:args' or just 'name'. */
        sep = ap_strchr_c(arg, ':');
        if (sep) {
            name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
            sep++;
        }
        else {
            name = arg;
        }
    
        /* Find the provider of given name. */
        mc->stapling_cache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
                                                name,
                                                AP_SOCACHE_PROVIDER_VERSION);
        if (mc->stapling_cache) {
            /* Cache found; create it, passing anything beyond the colon. */
            err = mc->stapling_cache->create(&mc->stapling_cache_context,
                                             sep, cmd->temp_pool,
                                             cmd->pool);
        }
        else {
            apr_array_header_t *name_list;
            const char *all_names;
    
            /* Build a comma-separated list of all registered provider
             * names: */
            name_list = ap_list_provider_names(cmd->pool,
                                               AP_SOCACHE_PROVIDER_GROUP,
                                               AP_SOCACHE_PROVIDER_VERSION);
            all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
    
            err = apr_psprintf(cmd->pool, "'%s' stapling cache not supported "
                               "(known names: %s) Maybe you need to load the "
                               "appropriate socache module (mod_socache_%s?)",
                               name, all_names, name);
        }
    
        if (err) {
            return apr_psprintf(cmd->pool, "SSLStaplingCache: %s", err);
        }
    
        return NULL;
    }
    
    const char *ssl_cmd_SSLUseStapling(cmd_parms *cmd, void *dcfg, int flag)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_enabled = flag ? TRUE : FALSE;
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *cmd, void *dcfg,
                                                        const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_resptime_skew = atoi(arg);
        if (sc->server->stapling_resptime_skew < 0) {
            return "SSLStaplingResponseTimeSkew: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingResponseMaxAge(cmd_parms *cmd, void *dcfg,
                                                        const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_resp_maxage = atoi(arg);
        if (sc->server->stapling_resp_maxage < 0) {
            return "SSLStaplingResponseMaxAge: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingStandardCacheTimeout(cmd_parms *cmd, void *dcfg,
                                                        const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_cache_timeout = atoi(arg);
        if (sc->server->stapling_cache_timeout < 0) {
            return "SSLStaplingStandardCacheTimeout: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *cmd, void *dcfg,
                                                     const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_errcache_timeout = atoi(arg);
        if (sc->server->stapling_errcache_timeout < 0) {
            return "SSLStaplingErrorCacheTimeout: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *cmd,
                                                         void *dcfg, int flag)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_return_errors = flag ? TRUE : FALSE;
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *cmd,
                                                void *dcfg, int flag)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_fake_trylater = flag ? TRUE : FALSE;
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *cmd, void *dcfg,
                                                    const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_responder_timeout = atoi(arg);
        sc->server->stapling_responder_timeout *= APR_USEC_PER_SEC;
        if (sc->server->stapling_responder_timeout < 0) {
            return "SSLStaplingResponderTimeout: invalid argument";
        }
        return NULL;
    }
    
    const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg,
                                            const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        sc->server->stapling_force_url = arg;
        return NULL;
    }
    
    #endif /* HAVE_OCSP_STAPLING */
    
    #ifdef HAVE_SSL_CONF_CMD
    const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg,
                                          const char *arg1, const char *arg2)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config;
        int value_type = SSL_CONF_cmd_value_type(cctx, arg1);
        const char *err;
        ssl_ctx_param_t *param;
    
        if (value_type == SSL_CONF_TYPE_UNKNOWN) {
            return apr_psprintf(cmd->pool,
                                "'%s': invalid OpenSSL configuration command",
                                arg1);
        }
    
        if (value_type == SSL_CONF_TYPE_FILE) {
            if ((err = ssl_cmd_check_file(cmd, &arg2)))
                return err;
        }
        else if (value_type == SSL_CONF_TYPE_DIR) {
            if ((err = ssl_cmd_check_dir(cmd, &arg2)))
                return err;
        }
    
        if (strcEQ(arg1, "CipherString")) {
            /* always disable null and export ciphers */
            arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
        }
    
        param = apr_array_push(sc->server->ssl_ctx_param);
        param->name = arg1;
        param->value = arg2;
        return NULL;
    }
    #endif
    
    #ifdef HAVE_SRP
    
    const char *ssl_cmd_SSLSRPVerifierFile(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;
        /* SRP_VBASE_init takes char*, not const char*  */
        sc->server->srp_vfile = apr_pstrdup(cmd->pool, arg);
        return NULL;
    }
    
    const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg,
                                              const char *arg)
    {
        SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
        /* SRP_VBASE_new takes char*, not const char*  */
        sc->server->srp_unknown_user_seed = apr_pstrdup(cmd->pool, arg);
        return NULL;
    }
    
    #endif /* HAVE_SRP */
    
    /* OCSP Responder File Function to read in value */
    const char *ssl_cmd_SSLOCSPResponderCertificateFile(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->ocsp_certs_file = arg;
        return NULL;
    }
    
    void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
    {
        apr_file_t *out = NULL;
        if (!ap_exists_config_define("DUMP_CERTS")) {
            return;
        }
        apr_file_open_stdout(&out, pconf);
        apr_file_printf(out, "Server certificates:\n");
    
        /* 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 < pks->cert_files->nelts) &&
                            APR_ARRAY_IDX(pks->cert_files, i, const char *);
                     i++) {
                    apr_file_printf(out, "  %s\n",
                                    APR_ARRAY_IDX(pks->cert_files,
                                                  i, const char *));
                }
            }
    
            s = s->next;
        }
    
    }
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_init.c����������������������������������������������������������0000664�0001751�0001751�00000237004�15032734372�020424� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "mpm_common.h"
    #include "mod_md.h"
    
    static apr_status_t ssl_init_ca_cert_path(server_rec *, apr_pool_t *, const char *,
                                              STACK_OF(X509_NAME) *, STACK_OF(X509_INFO) *);
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server,
                                        (server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx),
                                        (s,p,is_proxy,ctx), OK, DECLINED)
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, add_cert_files,
                                        (server_rec *s, apr_pool_t *p, 
                                        apr_array_header_t *cert_files, apr_array_header_t *key_files),
                                        (s, p, cert_files, key_files),
                                        OK, DECLINED)
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, add_fallback_cert_files,
                                        (server_rec *s, apr_pool_t *p, 
                                        apr_array_header_t *cert_files, apr_array_header_t *key_files),
                                        (s, p, cert_files, key_files),
                                        OK, DECLINED)
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, answer_challenge,
                                        (conn_rec *c, const char *server_name, 
                                        X509 **pcert, EVP_PKEY **pkey),
                                        (c, server_name, pcert, pkey),
                                        DECLINED, DECLINED)
    
    
    /*  _________________________________________________________________
    **
    **  Module Initialization
    **  _________________________________________________________________
    */
    
    #ifdef HAVE_ECC
    #define KEYTYPES "RSA, DSA or ECC"
    #else 
    #define KEYTYPES "RSA or DSA"
    #endif
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    /* OpenSSL Pre-1.1.0 compatibility */
    /* Taken from OpenSSL 1.1.0 snapshot 20160410 */
    static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
    {
        /* q is optional */
        if (p == NULL || g == NULL)
            return 0;
        BN_free(dh->p);
        BN_free(dh->q);
        BN_free(dh->g);
        dh->p = p;
        dh->q = q;
        dh->g = g;
    
        if (q != NULL) {
            dh->length = BN_num_bits(q);
        }
    
        return 1;
    }
    
    /*
     * Grab well-defined DH parameters from OpenSSL, see the BN_get_rfc*
     * functions in <openssl/bn.h> for all available primes.
     */
    static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *))
    {
        DH *dh = DH_new();
        BIGNUM *p, *g;
    
        if (!dh) {
            return NULL;
        }
        p = prime(NULL);
        g = BN_new();
        if (g != NULL) {
            BN_set_word(g, 2);
        }
        if (!p || !g || !DH_set0_pqg(dh, p, NULL, g)) {
            DH_free(dh);
            BN_free(p);
            BN_free(g);
            return NULL;
        }
        return dh;
    }
    
    /* Storage and initialization for DH parameters. */
    static struct dhparam {
        BIGNUM *(*const prime)(BIGNUM *); /* function to generate... */
        DH *dh;                           /* ...this, used for keys.... */
        const unsigned int min;           /* ...of length >= this. */
    } dhparams[] = {
        { BN_get_rfc3526_prime_8192, NULL, 6145 },
        { BN_get_rfc3526_prime_6144, NULL, 4097 },
        { BN_get_rfc3526_prime_4096, NULL, 3073 },
        { BN_get_rfc3526_prime_3072, NULL, 2049 },
        { BN_get_rfc3526_prime_2048, NULL, 1025 },
        { BN_get_rfc2409_prime_1024, NULL, 0 }
    };
    
    static void init_dh_params(void)
    {
        unsigned n;
    
        for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++)
            dhparams[n].dh = make_dh_params(dhparams[n].prime);
    }
    
    static void free_dh_params(void)
    {
        unsigned n;
    
        /* DH_free() is a noop for a NULL parameter, so these are harmless
         * in the (unexpected) case where these variables are already
         * NULL. */
        for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) {
            DH_free(dhparams[n].dh);
            dhparams[n].dh = NULL;
        }
    }
    
    /* Hand out the same DH structure though once generated as we leak
     * memory otherwise and freeing the structure up after use would be
     * hard to track and in fact is not needed at all as it is safe to
     * use the same parameters over and over again security wise (in
     * contrast to the keys itself) and code safe as the returned structure
     * is duplicated by OpenSSL anyway. Hence no modification happens
     * to our copy. */
    DH *modssl_get_dh_params(unsigned keylen)
    {
        unsigned n;
    
        for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++)
            if (keylen >= dhparams[n].min)
                return dhparams[n].dh;
            
        return NULL; /* impossible to reach. */
    }
    #endif
    
    static void ssl_add_version_components(apr_pool_t *ptemp, apr_pool_t *pconf,
                                           server_rec *s)
    {
        char *modver = ssl_var_lookup(ptemp, s, NULL, NULL, "SSL_VERSION_INTERFACE");
        char *libver = ssl_var_lookup(ptemp, s, NULL, NULL, "SSL_VERSION_LIBRARY");
        char *incver = ssl_var_lookup(ptemp, s, NULL, NULL,
                                      "SSL_VERSION_LIBRARY_INTERFACE");
    
        ap_add_version_component(pconf, libver);
    
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01876)
                     "%s compiled against Server: %s, Library: %s",
                     modver, AP_SERVER_BASEVERSION, incver);
    }
    
    /*  _________________________________________________________________
    **
    **  Let other answer special connection attempts. 
    **  Used in ACME challenge handling by mod_md.
    **  _________________________________________________________________
    */
    
    int ssl_is_challenge(conn_rec *c, const char *servername, 
                         X509 **pcert, EVP_PKEY **pkey,
                         const char **pcert_pem, const char **pkey_pem)
    {
        *pcert = NULL;
        *pkey = NULL;
        *pcert_pem = *pkey_pem = NULL;
        if (ap_ssl_answer_challenge(c, servername, pcert_pem, pkey_pem)) {
            return 1;
        }
        else if (OK == ssl_run_answer_challenge(c, servername, pcert, pkey)) {
            return 1;
        }
        return 0;
    }
    
    #ifdef HAVE_FIPS
    static apr_status_t modssl_fips_cleanup(void *data)
    {
        modssl_fips_enable(0);
        return APR_SUCCESS;
    }
    #endif
    
    static APR_INLINE unsigned long modssl_runtime_lib_version(void)
    {
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        return SSLeay();
    #else
        return OpenSSL_version_num();
    #endif
    }
    
    
    /*
     *  Per-module initialization
     */
    apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
                                 apr_pool_t *ptemp,
                                 server_rec *base_server)
    {
        unsigned long runtime_lib_version = modssl_runtime_lib_version();
        SSLModConfigRec *mc = myModConfig(base_server);
        SSLSrvConfigRec *sc;
        server_rec *s;
        apr_status_t rv;
        apr_array_header_t *pphrases;
    
        AP_DEBUG_ASSERT(mc);
    
        if (runtime_lib_version < MODSSL_LIBRARY_VERSION) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01882)
                         "Init: this version of mod_ssl was compiled against "
                         "a newer library (%s (%s), version currently loaded is 0x%lX)"
                         " - may result in undefined or erroneous behavior",
                        MODSSL_LIBRARY_TEXT, MODSSL_LIBRARY_DYNTEXT,
                        runtime_lib_version);
        }
    
        /* 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 exits
         */
        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;
            }
    
            /*
             * Create the server host:port string because we need it a lot
             */
            if (sc->vhost_id) {
                /* already set. This should only happen if this config rec is
                 * shared with another server. Argh! */
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10104) 
                             "%s, SSLSrvConfigRec shared from %s", 
                             ssl_util_vhostid(p, s), sc->vhost_id);
            }
            sc->vhost_id = ssl_util_vhostid(p, s);
            sc->vhost_id_len = strlen(sc->vhost_id);
    
            /* Default to enabled if SSLEngine is not set explicitly, and
             * the protocol is https. */
            if (ap_get_server_protocol(s) 
                && strcmp("https", ap_get_server_protocol(s)) == 0
                && sc->enabled == SSL_ENABLED_UNSET
                && (!apr_is_empty_array(sc->server->pks->cert_files))) {
                sc->enabled = SSL_ENABLED_TRUE;
            }
    
            /* Fix up stuff that may not have been set.  If sc->enabled is
             * UNSET, then SSL is disabled on this vhost.  */
            if (sc->enabled == SSL_ENABLED_UNSET) {
                sc->enabled = SSL_ENABLED_FALSE;
            }
    
            if (sc->session_cache_timeout == UNSET) {
                sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
            }
    
            if (sc->server && sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
                sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
            }
        }
    
    #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
        ssl_util_thread_setup(p);
    #endif
    
        /*
         * SSL external crypto device ("engine") support
         */
        if ((rv = ssl_init_Engine(base_server, p)) != APR_SUCCESS) {
            return rv;
        }
    
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, APLOGNO(01883)
                     "Init: Initialized %s library", MODSSL_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: ");
    
    #ifdef HAVE_FIPS
        if (!modssl_fips_is_enabled() && mc->fips == TRUE) {
            if (!modssl_fips_enable(1)) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, base_server, APLOGNO(01885)
                             "Could not enable FIPS mode");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, base_server);
                return ssl_die(base_server);
            }
    
            apr_pool_cleanup_register(p, NULL, modssl_fips_cleanup,
                                      apr_pool_cleanup_null);
        }
    
        /* Log actual FIPS mode which the SSL library is operating under,
         * which may have been set outside of the mod_ssl
         * configuration. */
        if (modssl_fips_is_enabled()) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, base_server, APLOGNO(01884)
                         MODSSL_LIBRARY_NAME " has FIPS mode enabled");
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, base_server, APLOGNO(01886)
                         MODSSL_LIBRARY_NAME " has FIPS mode disabled");
        }
    #endif
    
        /*
         * initialize the mutex handling
         */
        if (!ssl_mutex_init(base_server, p)) {
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    #ifdef HAVE_OCSP_STAPLING
        ssl_stapling_certinfo_hash_init(p);
    #endif
    
        /*
         * initialize session caching
         */
        if ((rv = ssl_scache_init(base_server, p)) != APR_SUCCESS) {
            return rv;
        }
    
        pphrases = apr_array_make(ptemp, 2, sizeof(char *));
    
        /*
         *  initialize servers
         */
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, APLOGNO(01887)
                     "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
             */
            if ((rv = ssl_init_ConfigureServer(s, p, ptemp, sc, pphrases))
                != APR_SUCCESS) {
                return rv;
            }
        }
    
        if (pphrases->nelts > 0) {
            memset(pphrases->elts, 0, pphrases->elt_size * pphrases->nelts);
            pphrases->nelts = 0;
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02560)
                         "Init: Wiped out the queried pass phrases from memory");
        }
    
        /*
         * Configuration consistency checks
         */
        if ((rv = ssl_init_CheckServers(base_server, ptemp)) != APR_SUCCESS) {
            return rv;
        }
    
        for (s = base_server; s; s = s->next) {
            SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
                                                        &ssl_module);
    
            sc = mySrvConfig(s);
            if (sc->enabled == SSL_ENABLED_TRUE) {
                if ((rv = ssl_run_init_server(s, p, 0, sc->server->ssl_ctx)) != APR_SUCCESS) {
                    return rv;
                }
            }
    
            if (sdc->proxy_enabled) {
                rv = ssl_run_init_server(s, p, 1, sdc->proxy->ssl_ctx);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
            }
        }
    
        /*
         *  Announce mod_ssl and SSL library in HTTP Server field
         *  as ``mod_ssl/X.X.X OpenSSL/X.X.X''
         */
        ssl_add_version_components(ptemp, p, base_server);
    
        modssl_init_app_data2_idx(); /* for modssl_get_app_data2() at request time */
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        init_dh_params();
    #else
        init_bio_methods();
    #endif
    
    #ifdef HAVE_OPENSSL_KEYLOG
        {
            const char *logfn = getenv("SSLKEYLOGFILE");
    
            if (logfn) {
                rv = apr_file_open(&mc->keylog_file, logfn,
                                   APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_APPEND|APR_FOPEN_LARGEFILE,
                                   APR_FPROT_UREAD|APR_FPROT_UWRITE,
                                   mc->pPool);
                if (rv) {
                    ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s, APLOGNO(10226)
                                 "Could not open log file '%s' configured via SSLKEYLOGFILE",
                                 logfn);
                    return rv;
                }
    
                ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(10227)
                             "Init: Logging SSL private key material to %s", logfn);
            }
        }
    #endif
        
        return OK;
    }
    
    /*
     * Support for external a Crypto Device ("engine"), usually
     * a hardware accelerator card for crypto operations.
     */
    apr_status_t ssl_init_Engine(server_rec *s, apr_pool_t *p)
    {
    #if MODSSL_HAVE_ENGINE_API
        SSLModConfigRec *mc = myModConfig(s);
        ENGINE *e;
    
        if (mc->szCryptoDevice) {
            if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01888)
                             "Init: Failed to load Crypto Device API `%s'",
                             mc->szCryptoDevice);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
            }
    
    #ifdef ENGINE_CTRL_CHIL_SET_FORKCHECK
            if (strEQ(mc->szCryptoDevice, "chil")) {
                ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
            }
    #endif
    
            if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01889)
                             "Init: Failed to enable Crypto Device API `%s'",
                             mc->szCryptoDevice);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
            }
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01890)
                         "Init: loaded Crypto Device API `%s'",
                         mc->szCryptoDevice);
    
            ENGINE_free(e);
        }
    #endif
        return APR_SUCCESS;
    }
    
    #ifdef HAVE_TLSEXT
    static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
                                                    apr_pool_t *p,
                                                    apr_pool_t *ptemp,
                                                    modssl_ctx_t *mctx)
    {
        apr_status_t rv;
    
        /*
         * Configure TLS extensions support
         */
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01893)
                     "Configuring TLS extension handling");
    
        /*
         * The Server Name Indication (SNI) provided by the ClientHello can be
         * used to select the right (name-based-)vhost and its SSL configuration
         * before the handshake takes place.
         */
        if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
                              ssl_callback_ServerNameIndication) ||
            !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01894)
                         "Unable to initialize TLS servername extension "
                         "callback (incompatible OpenSSL version?)");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
    #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
        /*
         * The ClientHello callback also allows to retrieve the SNI, but since it
         * runs at the earliest possible connection stage we can even set the TLS
         * protocol version(s) according to the selected (name-based-)vhost, which
         * is not possible at the SNI callback stage (due to OpenSSL internals).
         */
        SSL_CTX_set_client_hello_cb(mctx->ssl_ctx, ssl_callback_ClientHello, NULL);
    #endif
    
    #ifdef HAVE_OCSP_STAPLING
        /*
         * OCSP Stapling support, status_request extension
         */
        if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) {
            if ((rv = modssl_init_stapling(s, p, ptemp, mctx)) != APR_SUCCESS) {
                return rv;
            }
        }
    #endif
    
    #ifdef HAVE_SRP
        /*
         * TLS-SRP support
         */
        if (mctx->srp_vfile != NULL) {
            int err;
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02308)
                         "Using SRP verifier file [%s]", mctx->srp_vfile);
    
            if (!(mctx->srp_vbase = SRP_VBASE_new(mctx->srp_unknown_user_seed))) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02309)
                             "Unable to initialize SRP verifier structure "
                             "[%s seed]",
                             mctx->srp_unknown_user_seed ? "with" : "without");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
            }
    
            err = SRP_VBASE_init(mctx->srp_vbase, mctx->srp_vfile);
            if (err != SRP_NO_ERROR) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02310)
                             "Unable to load SRP verifier file [error %d]", err);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
            }
    
            SSL_CTX_set_srp_username_callback(mctx->ssl_ctx,
                                              ssl_callback_SRPServerParams);
            SSL_CTX_set_srp_cb_arg(mctx->ssl_ctx, mctx);
        }
    #endif
        return APR_SUCCESS;
    }
    #endif
    
    static apr_status_t ssl_init_ctx_protocol(server_rec *s,
                                              apr_pool_t *p,
                                              apr_pool_t *ptemp,
                                              modssl_ctx_t *mctx)
    {
        SSL_CTX *ctx = NULL;
        MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL;
        char *cp;
        int protocol = mctx->protocol;
        SSLSrvConfigRec *sc = mySrvConfig(s);
    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
        /* default is highest supported version, will be overridden below */
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        int prot = TLS1_3_VERSION;
    #else
        int prot = TLS1_2_VERSION;
    #endif
    #endif
    
        /*
         *  Create the new per-server SSL context
         */
        if (protocol == SSL_PROTOCOL_NONE) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
                    "No SSL protocols available [hint: SSLProtocol]");
            return ssl_die(s);
        }
    
        cp = apr_pstrcat(p,
    #ifndef OPENSSL_NO_SSL3
                         (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
    #endif
                         (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
    #ifdef HAVE_TLSV1_X
                         (protocol & SSL_PROTOCOL_TLSV1_1 ? "TLSv1.1, " : ""),
                         (protocol & SSL_PROTOCOL_TLSV1_2 ? "TLSv1.2, " : ""),
    #if SSL_HAVE_PROTOCOL_TLSV1_3
                         (protocol & SSL_PROTOCOL_TLSV1_3 ? "TLSv1.3, " : ""),
    #endif
    #endif
                         NULL);
        cp[strlen(cp)-2] = NUL;
    
        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
                     "Creating new SSL context (protocols: %s)", cp);
    
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
    #ifndef OPENSSL_NO_SSL3
        if (protocol == SSL_PROTOCOL_SSLV3) {
            method = mctx->pkp ?
                SSLv3_client_method() : /* proxy */
                SSLv3_server_method();  /* server */
        }
        else
    #endif
        if (protocol == SSL_PROTOCOL_TLSV1) {
            method = mctx->pkp ?
                TLSv1_client_method() : /* proxy */
                TLSv1_server_method();  /* server */
        }
    #ifdef HAVE_TLSV1_X
        else if (protocol == SSL_PROTOCOL_TLSV1_1) {
            method = mctx->pkp ?
                TLSv1_1_client_method() : /* proxy */
                TLSv1_1_server_method();  /* server */
        }
        else if (protocol == SSL_PROTOCOL_TLSV1_2) {
            method = mctx->pkp ?
                TLSv1_2_client_method() : /* proxy */
                TLSv1_2_server_method();  /* server */
        }
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        else if (protocol == SSL_PROTOCOL_TLSV1_3) {
            method = mctx->pkp ?
                TLSv1_3_client_method() : /* proxy */
                TLSv1_3_server_method();  /* server */
        }
    #endif
    #endif
        else { /* For multiple protocols, we need a flexible method */
            method = mctx->pkp ?
                SSLv23_client_method() : /* proxy */
                SSLv23_server_method();  /* server */
        }
    #else
        method = mctx->pkp ?
            TLS_client_method() : /* proxy */
            TLS_server_method();  /* server */
    #endif
        ctx = SSL_CTX_new(method);
        if (ctx == NULL) {
            /* Can fail for some system/install mis-configuration. */
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
        mctx->ssl_ctx = ctx;
    
        SSL_CTX_set_options(ctx, SSL_OP_ALL);
    
    #if OPENSSL_VERSION_NUMBER < 0x10100000L  || \
    	(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L)
        /* always disable SSLv2, as per RFC 6176 */
        SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
    
    #ifndef OPENSSL_NO_SSL3
        if (!(protocol & SSL_PROTOCOL_SSLV3)) {
            SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
        }
    #endif
    
        if (!(protocol & SSL_PROTOCOL_TLSV1)) {
            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
        }
    
    #ifdef HAVE_TLSV1_X
        if (!(protocol & SSL_PROTOCOL_TLSV1_1)) {
            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
        }
    
        if (!(protocol & SSL_PROTOCOL_TLSV1_2)) {
            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
        }
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1_3,
                                    protocol & SSL_PROTOCOL_TLSV1_3, "TLSv1.3");
    #endif
    #endif
    
    #else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
        /* We first determine the maximum protocol version we should provide */
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        if (protocol & SSL_PROTOCOL_TLSV1_3) {
            prot = TLS1_3_VERSION;
        } else
    #endif
        if (protocol & SSL_PROTOCOL_TLSV1_2) {
            prot = TLS1_2_VERSION;
        } else if (protocol & SSL_PROTOCOL_TLSV1_1) {
            prot = TLS1_1_VERSION;
        } else if (protocol & SSL_PROTOCOL_TLSV1) {
            prot = TLS1_VERSION;
    #ifndef OPENSSL_NO_SSL3
        } else if (protocol & SSL_PROTOCOL_SSLV3) {
            prot = SSL3_VERSION;
    #endif
        } else {
            SSL_CTX_free(ctx);
            mctx->ssl_ctx = NULL;
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(03378)
                    "No SSL protocols available [hint: SSLProtocol]");
            return ssl_die(s);
        }
        SSL_CTX_set_max_proto_version(ctx, prot);
    
        /* Next we scan for the minimal protocol version we should provide,
         * but we do not allow holes between max and min */
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        if (prot == TLS1_3_VERSION && protocol & SSL_PROTOCOL_TLSV1_2) {
            prot = TLS1_2_VERSION;
        }
    #endif
        if (prot == TLS1_2_VERSION && protocol & SSL_PROTOCOL_TLSV1_1) {
            prot = TLS1_1_VERSION;
        }
        if (prot == TLS1_1_VERSION && protocol & SSL_PROTOCOL_TLSV1) {
            prot = TLS1_VERSION;
        }
    #ifndef OPENSSL_NO_SSL3
        if (prot == TLS1_VERSION && protocol & SSL_PROTOCOL_SSLV3) {
            prot = SSL3_VERSION;
        }
    #endif
        SSL_CTX_set_min_proto_version(ctx, prot);
    #endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L */
    
    #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
        if (sc->cipher_server_pref == TRUE) {
            SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
        }
    #endif
    
    
    #ifndef OPENSSL_NO_COMP
        if (sc->compression != TRUE) {
    #ifdef SSL_OP_NO_COMPRESSION
            /* OpenSSL >= 1.0 only */
            SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
    #else
            sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
    #endif
        }
    #endif
    
    #ifdef SSL_OP_NO_TICKET
        /*
         * Configure using RFC 5077 TLS session tickets
         * for session resumption.
         */
        if (sc->session_tickets == FALSE) {
            SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
        }
    #endif
    
    #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
        if (sc->insecure_reneg == TRUE) {
            SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
        }
    #endif
    
        SSL_CTX_set_app_data(ctx, s);
    
        /*
         * Configure additional context ingredients
         */
        SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
    #ifdef HAVE_ECC
        SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
    #endif
    
    #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
    
    #ifdef SSL_MODE_RELEASE_BUFFERS
        /* If httpd is configured to reduce mem usage, ask openssl to do so, too */
        if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED)
            SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
    #endif
    
    #if OPENSSL_VERSION_NUMBER >= 0x1010100fL
        /* For OpenSSL >=1.1.1, disable auto-retry mode so it's possible
         * to consume handshake records without blocking for app-data.
         * https://github.com/openssl/openssl/issues/7178 */
        SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
    #endif
    
    #ifdef HAVE_OPENSSL_KEYLOG
        if (mctx->sc->mc->keylog_file) {
            SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
        }
    #endif
    
    #ifdef SSL_OP_NO_RENEGOTIATION
        /* For server-side SSL_CTX, disable renegotiation by default.. */
        if (!mctx->pkp) {
            SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
        }
    #endif
    
    #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
        /* For server-side SSL_CTX, enable ignoring unexpected EOF */
        /* (OpenSSL 1.1.1 behavioural compatibility).. */
        if (!mctx->pkp) {
            SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
        }
    #endif
        
        return APR_SUCCESS;
    }
    
    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);
    
        SSL_CTX_set_session_cache_mode(ctx, mc->sesscache_mode);
    
        if (mc->sesscache) {
            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);
        }
    }
    
    #ifdef SSL_OP_NO_RENEGOTIATION
    /* OpenSSL-level renegotiation protection. */
    #define MODSSL_BLOCKS_RENEG (0)
    #else
    /* mod_ssl-level renegotiation protection. */
    #define MODSSL_BLOCKS_RENEG (1)
    #endif
    
    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;
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        /* Note that for OpenSSL>=1.1, auto selection is enabled via
         * SSL_CTX_set_dh_auto(,1) if no parameter is configured. */
        SSL_CTX_set_tmp_dh_callback(ctx,  ssl_callback_TmpDH);
    #endif
    
        /* The info callback is used for debug-level tracing.  For OpenSSL
         * versions where SSL_OP_NO_RENEGOTIATION is not available, the
         * callback is also used to prevent use of client-initiated
         * renegotiation.  Enable it in either case. */
        if (APLOGdebug(s) || MODSSL_BLOCKS_RENEG) {
            SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
        }
    
    #ifdef HAVE_TLS_ALPN
        SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL);
    #endif
    }
    
    static APR_INLINE
    int modssl_CTX_load_verify_locations(SSL_CTX *ctx,
                                         const char *file,
                                         const char *path)
    {
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
        if (!SSL_CTX_load_verify_locations(ctx, file, path))
            return 0;
    #else
        if (file && !SSL_CTX_load_verify_file(ctx, file))
            return 0;
        if (path && !SSL_CTX_load_verify_dir(ctx, path))
            return 0;
    #endif
        return 1;
    }
    
    static apr_status_t 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_TRACE1, 0, s,
                         "Configuring client authentication");
    
            if (!modssl_CTX_load_verify_locations(ctx, mctx->auth.ca_cert_file,
                                                       mctx->auth.ca_cert_path)) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01895)
                        "Unable to configure verify locations "
                        "for client authentication");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
            }
    
            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 (sk_X509_NAME_num(ca_list) <= 0) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896)
                        "Unable to determine list of acceptable "
                        "CA certificates for client authentication");
                return ssl_die(s);
            }
    
            SSL_CTX_set_client_CA_list(ctx, 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 = SSL_CTX_get_client_CA_list(ctx);
    
            if (sk_X509_NAME_num(ca_list) == 0) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01897)
                             "Init: Oops, you want to request client "
                             "authentication, but no CAs are known for "
                             "verification!?  [Hint: SSLCACertificate*]");
            }
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t 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;
    
        /*
         *  Configure SSL Cipher Suite. Always disable NULL and export ciphers,
         *  see also ssl_engine_config.c:ssl_cmd_SSLCipherSuite().
         *  OpenSSL's SSL_DEFAULT_CIPHER_LIST includes !aNULL:!eNULL from 0.9.8f,
         *  and !EXP from 0.9.8zf/1.0.1m/1.0.2a, so append them while we support
         *  earlier versions.
         */
        suite = mctx->auth.cipher_suite ? mctx->auth.cipher_suite :
                apr_pstrcat(ptemp, SSL_DEFAULT_CIPHER_LIST, ":!aNULL:!eNULL:!EXP",
                            NULL);
    
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
                     "Configuring permitted SSL ciphers [%s]",
                     suite);
    
        if (!SSL_CTX_set_cipher_list(ctx, suite)) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01898)
                    "Unable to configure permitted SSL ciphers");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        if (mctx->auth.tls13_ciphers 
            && !SSL_CTX_set_ciphersuites(ctx, mctx->auth.tls13_ciphers)) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10127)
                    "Unable to configure permitted TLSv1.3 ciphers");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    #endif
        return APR_SUCCESS;
    }
    
    static APR_INLINE
    int modssl_X509_STORE_load_locations(X509_STORE *store,
                                         const char *file,
                                         const char *path)
    {
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
        if (!X509_STORE_load_locations(store, file, path))
            return 0;
    #else
        if (file && !X509_STORE_load_file(store, file))
            return 0;
        if (path && !X509_STORE_load_path(store, path))
            return 0;
    #endif
        return 1;
    }
    
    static apr_status_t ssl_init_ctx_crl(server_rec *s,
                                         apr_pool_t *p,
                                         apr_pool_t *ptemp,
                                         modssl_ctx_t *mctx)
    {
        X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
        unsigned long crlflags = 0;
        char *cfgp = mctx->pkp ? "SSLProxy" : "SSL";
        int crl_check_mode;
    
        if (mctx->ocsp_mask == UNSET) {
            mctx->ocsp_mask = SSL_OCSPCHECK_NONE;
        }
    
        if (mctx->crl_check_mask == UNSET) {
            mctx->crl_check_mask = SSL_CRLCHECK_NONE;
        }
        crl_check_mode = mctx->crl_check_mask & ~SSL_CRLCHECK_FLAGS;
    
        /*
         * Configure Certificate Revocation List (CRL) Details
         */
    
        if (!(mctx->crl_file || mctx->crl_path)) {
            if (crl_check_mode == SSL_CRLCHECK_LEAF ||
                crl_check_mode == SSL_CRLCHECK_CHAIN) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01899)
                             "Host %s: CRL checking has been enabled, but "
                             "neither %sCARevocationFile nor %sCARevocationPath "
                             "is configured", mctx->sc->vhost_id, cfgp, cfgp);
                return ssl_die(s);
            }
            return APR_SUCCESS;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01900)
                     "Configuring certificate revocation facility");
    
        if (!store || !modssl_X509_STORE_load_locations(store, mctx->crl_file,
                                                               mctx->crl_path)) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01901)
                         "Host %s: unable to configure X.509 CRL storage "
                         "for certificate revocation", mctx->sc->vhost_id);
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
        switch (crl_check_mode) {
           case SSL_CRLCHECK_LEAF:
               crlflags = X509_V_FLAG_CRL_CHECK;
               break;
           case SSL_CRLCHECK_CHAIN:
               crlflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
               break;
           default:
               crlflags = 0;
        }
    
        if (crlflags) {
            X509_STORE_set_flags(store, crlflags);
        } else {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01902)
                         "Host %s: X.509 CRL storage locations configured, "
                         "but CRL checking (%sCARevocationCheck) is not "
                         "enabled", mctx->sc->vhost_id, cfgp);
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * 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.
     */
    static int use_certificate_chain(
        SSL_CTX *ctx, char *file, int skipfirst, pem_password_cb *cb)
    {
        BIO *bio;
        X509 *x509;
        unsigned long err;
        int n;
    
        if ((bio = BIO_new(BIO_s_file())) == 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 = PEM_read_bio_X509(bio, NULL, cb, NULL)) == NULL) {
                BIO_free(bio);
                return -1;
            }
            X509_free(x509);
        }
        /* free a perhaps already configured extra chain */
    #ifdef OPENSSL_NO_SSL_INTERN
        SSL_CTX_clear_extra_chain_certs(ctx);
    #else
        if (ctx->extra_certs != NULL) {
            sk_X509_pop_free((STACK_OF(X509) *)ctx->extra_certs, X509_free);
            ctx->extra_certs = NULL;
        }
    #endif
    
        /* create new extra chain by loading the certs */
        n = 0;
        ERR_clear_error();
        while ((x509 = 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;
    }
    
    static apr_status_t 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 explicitly configure CA certificates which are
         * used only for the server certificate chain.
         */
        if (!chain) {
            return APR_SUCCESS;
        }
    
        for (i = 0; (i < mctx->pks->cert_files->nelts) &&
             APR_ARRAY_IDX(mctx->pks->cert_files, i, const char *); i++) {
            if (strEQ(APR_ARRAY_IDX(mctx->pks->cert_files, i, const char *), chain)) {
                skip_first = TRUE;
                break;
            }
        }
    
        n = use_certificate_chain(mctx->ssl_ctx, (char *)chain, skip_first, NULL);
        if (n < 0) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
                    "Failed to configure CA certificate chain!");
            return ssl_die(s);
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01904)
                     "Configuring server certificate chain "
                     "(%d CA certificate%s)",
                     n, n == 1 ? "" : "s");
    
        return APR_SUCCESS;
    }
    
    static apr_status_t ssl_init_ctx(server_rec *s,
                                     apr_pool_t *p,
                                     apr_pool_t *ptemp,
                                     modssl_ctx_t *mctx)
    {
        apr_status_t rv;
    
        if ((rv = ssl_init_ctx_protocol(s, p, ptemp, mctx)) != APR_SUCCESS) {
            return rv;
        }
    
        ssl_init_ctx_session_cache(s, p, ptemp, mctx);
    
        ssl_init_ctx_callbacks(s, p, ptemp, mctx);
    
        if ((rv = ssl_init_ctx_verify(s, p, ptemp, mctx)) != APR_SUCCESS) {
            return rv;
        }
    
        if ((rv = ssl_init_ctx_cipher_suite(s, p, ptemp, mctx)) != APR_SUCCESS) {
            return rv;
        }
    
        if ((rv = ssl_init_ctx_crl(s, p, ptemp, mctx)) != APR_SUCCESS) {
            return rv;
        }
    
        if (mctx->pks) {
            /* XXX: proxy support? */
            if ((rv = ssl_init_ctx_cert_chain(s, p, ptemp, mctx)) != APR_SUCCESS) {
                return rv;
            }
    #ifdef HAVE_TLSEXT
            if ((rv = ssl_init_ctx_tls_extensions(s, p, ptemp, mctx)) !=
                APR_SUCCESS) {
                return rv;
            }
    #endif
        }
    
        return APR_SUCCESS;
    }
    
    static void ssl_check_public_cert(server_rec *s,
                                      apr_pool_t *ptemp,
                                      X509 *cert,
                                      const char *key_id)
    {
        int is_ca, pathlen;
    
        if (!cert) {
            return;
        }
    
        /*
         * Some information about the certificate(s)
         */
    
        if (modssl_X509_getBC(cert, &is_ca, &pathlen)) {
            if (is_ca) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01906)
                             "%s server certificate is a CA certificate "
                             "(BasicConstraints: CA == TRUE !?)", key_id);
            }
    
            if (pathlen > 0) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01907)
                             "%s server certificate is not a leaf certificate "
                             "(BasicConstraints: pathlen == %d > 0 !?)",
                             key_id, pathlen);
            }
        }
    
        if (modssl_X509_match_name(ptemp, cert, (const char *)s->server_hostname,
                                   TRUE, s) == FALSE) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01909)
                         "%s server certificate does NOT include an ID "
                         "which matches the server name", key_id);
        }
    }
    
    /* prevent OpenSSL from showing its "Enter PEM pass phrase:" prompt */
    static int ssl_no_passwd_prompt_cb(char *buf, int size, int rwflag,
                                       void *userdata) {
       return 0;
    }
    
    /* SSL_CTX_use_PrivateKey_file() can fail either because the private
     * key was encrypted, or due to a mismatch between an already-loaded
     * cert and the key - a common misconfiguration - from calling
     * X509_check_private_key().  This macro is passed the last error code
     * off the OpenSSL stack and evaluates to true only for the first
     * case.  With OpenSSL < 3 the second case is identifiable by the
     * function code, but function codes are not used from 3.0. */
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
    #define CHECK_PRIVKEY_ERROR(ec) (ERR_GET_FUNC(ec) != X509_F_X509_CHECK_PRIVATE_KEY)
    #else
    #define CHECK_PRIVKEY_ERROR(ec) (ERR_GET_LIB(ec) != ERR_LIB_X509            \
                                     || (ERR_GET_REASON(ec) != X509_R_KEY_TYPE_MISMATCH \
                                         && ERR_GET_REASON(ec) != X509_R_KEY_VALUES_MISMATCH \
                                         && ERR_GET_REASON(ec) != X509_R_UNKNOWN_KEY_TYPE))
    #endif
    
    static apr_status_t ssl_init_server_certs(server_rec *s,
                                              apr_pool_t *p,
                                              apr_pool_t *ptemp,
                                              modssl_ctx_t *mctx,
                                              apr_array_header_t *pphrases)
    {
        SSLModConfigRec *mc = myModConfig(s);
        const char *vhost_id = mctx->sc->vhost_id, *key_id, *certfile, *keyfile;
        int i;
        EVP_PKEY *pkey;
        int custom_dh_done = 0;
    #ifdef HAVE_ECC
        EC_GROUP *ecgroup = NULL;
        int curve_nid = 0;
    #endif
    
        /* no OpenSSL default prompts for any of the SSL_CTX_use_* calls, please */
        SSL_CTX_set_default_passwd_cb(mctx->ssl_ctx, ssl_no_passwd_prompt_cb);
    
        /* Iterate over the SSLCertificateFile array */
        for (i = 0; (i < mctx->pks->cert_files->nelts) &&
                    (certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i,
                                              const char *));
             i++) {
            X509 *cert = NULL;
            const char *engine_certfile = NULL;
    
            key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i);
    
            ERR_clear_error();
    
            /* first the certificate (public key) */
            if (modssl_is_engine_id(certfile)) {
                engine_certfile = certfile;
            }
            else if (mctx->cert_chain) {
                if ((SSL_CTX_use_certificate_file(mctx->ssl_ctx, certfile,
                                                  SSL_FILETYPE_PEM) < 1)) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02561)
                                 "Failed to configure certificate %s, check %s",
                                 key_id, certfile);
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                    return APR_EGENERAL;
                }
            } else {
                if ((SSL_CTX_use_certificate_chain_file(mctx->ssl_ctx,
                                                        certfile) < 1)) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02562)
                                 "Failed to configure certificate %s (with chain),"
                                 " check %s", key_id, certfile);
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                    return APR_EGENERAL;
                }
            }
    
            /* and second, the private key */
            if (i < mctx->pks->key_files->nelts) {
                keyfile = APR_ARRAY_IDX(mctx->pks->key_files, i, const char *);
            } else {
                keyfile = certfile;
            }
    
            ERR_clear_error();
    
            if (modssl_is_engine_id(keyfile)) {
                apr_status_t rv;
    
                if ((rv = modssl_load_engine_keypair(s, p, ptemp, vhost_id,
                                                     engine_certfile, keyfile,
                                                     &cert, &pkey))) {
                    return rv;
                }
    
                if (cert) {
                    if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) {
                        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10137)
                                     "Failed to configure certificate %s from %s, check %s",
                                     key_id, mc->szCryptoDevice ?
                                                 mc->szCryptoDevice : "provider",
                                     certfile);
                        ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                        return APR_EGENERAL;
                    }
    
                    /* SSL_CTX now owns the cert. */
                    X509_free(cert);
                }                    
                
                if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130)
                                 "Failed to configure private key %s from %s",
                                 keyfile, mc->szCryptoDevice ?
                                              mc->szCryptoDevice : "provider");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                    return APR_EGENERAL;
                }
    
                /* SSL_CTX now owns the key */
                EVP_PKEY_free(pkey);
            }
            else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
                                                  SSL_FILETYPE_PEM) < 1)
                     && CHECK_PRIVKEY_ERROR(ERR_peek_last_error())) {
                ssl_asn1_t *asn1;
                const unsigned char *ptr;
    
                ERR_clear_error();
    
                /* perhaps it's an encrypted private key, so try again */
                ssl_load_encrypted_pkey(s, ptemp, i, keyfile, &pphrases);
    
                if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id)) ||
                    !(ptr = asn1->cpData) ||
                    !(pkey = d2i_AutoPrivateKey(NULL, &ptr, asn1->nData)) ||
                    (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1)) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02564)
                                 "Failed to configure encrypted (?) private key %s,"
                                 " check %s", key_id, keyfile);
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                    return APR_EGENERAL;
                }
            }
    
            if (SSL_CTX_check_private_key(mctx->ssl_ctx) < 1) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02565)
                             "Certificate and private key %s from %s and %s "
                             "do not match", key_id, certfile, keyfile);
                return APR_EGENERAL;
            }
    
    #ifdef HAVE_SSL_CONF_CMD
            /* 
             * workaround for those OpenSSL versions where SSL_CTX_get0_certificate
             * is not yet available: create an SSL struct which we dispose of
             * as soon as we no longer need access to the cert. (Strictly speaking,
             * SSL_CTX_get0_certificate does not depend on the SSL_CONF stuff,
             * but there's no reliable way to check for its existence, so we
             * assume that if SSL_CONF is available, it's OpenSSL 1.0.2 or later,
             * and SSL_CTX_get0_certificate is implemented.)
             */
            cert = SSL_CTX_get0_certificate(mctx->ssl_ctx);
    #else
            {
                SSL *ssl = SSL_new(mctx->ssl_ctx);
                if (ssl) {
                    /* Workaround bug in SSL_get_certificate in OpenSSL 0.9.8y */
                    SSL_set_connect_state(ssl);
                    cert = SSL_get_certificate(ssl);
                    SSL_free(ssl);
                }
            }
    #endif
            if (!cert) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02566)
                             "Unable to retrieve certificate %s", key_id);
                return APR_EGENERAL;
            }
    
            /* warn about potential cert issues */
            ssl_check_public_cert(s, ptemp, cert, key_id);
    
    #if defined(HAVE_OCSP_STAPLING) && !defined(SSL_CTRL_SET_CURRENT_CERT)
            /* 
             * OpenSSL up to 1.0.1: configure stapling as we go. In 1.0.2
             * and later, there's SSL_CTX_set_current_cert, which allows
             * iterating over all certs in an SSL_CTX (including those possibly
             * loaded via SSLOpenSSLConfCmd Certificate), so for 1.0.2 and
             * later, we defer to the code in ssl_init_server_ctx.
             */
            if (!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567)
                             "Unable to configure certificate %s for stapling",
                             key_id);
            }
    #endif
    
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02568)
                         "Certificate and private key %s configured from %s and %s",
                         key_id, certfile, keyfile);
        }
    
        /*
         * Try to read DH parameters from the (first) SSLCertificateFile
         */
        certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *);
        if (certfile && !modssl_is_engine_id(certfile)) {
            int num_bits = 0;
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
            DH *dh = modssl_dh_from_file(certfile);
            if (dh) {
                num_bits = DH_bits(dh);
                SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dh);
                DH_free(dh);
                custom_dh_done = 1;
            }
    #else
            pkey = modssl_dh_pkey_from_file(certfile);
            if (pkey) {
                num_bits = EVP_PKEY_get_bits(pkey);
                if (!SSL_CTX_set0_tmp_dh_pkey(mctx->ssl_ctx, pkey)) {
                    EVP_PKEY_free(pkey);
                }
                else {
                    custom_dh_done = 1;
                }
            }
    #endif
            if (custom_dh_done) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540)
                             "Custom DH parameters (%d bits) for %s loaded from %s",
                             num_bits, vhost_id, certfile);
            }
        }
    #if !MODSSL_USE_OPENSSL_PRE_1_1_API
        if (!custom_dh_done) {
            /* If no parameter is manually configured, enable auto
             * selection. */
            SSL_CTX_set_dh_auto(mctx->ssl_ctx, 1);
        }
    #endif
    
    #ifdef HAVE_ECC
        /*
         * Similarly, try to read the ECDH curve name from SSLCertificateFile...
         */
        if (certfile && !modssl_is_engine_id(certfile)
            && (ecgroup = modssl_ec_group_from_file(certfile))
            && (curve_nid = EC_GROUP_get_curve_name(ecgroup))) {
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
            EC_KEY *eckey = EC_KEY_new_by_curve_name(curve_nid);
            if (eckey) {
                SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
                EC_KEY_free(eckey);
            }
            else {
                curve_nid = 0;
            }
    #else
            if (!SSL_CTX_set1_curves(mctx->ssl_ctx, &curve_nid, 1)) {
                curve_nid = 0;
            }
    #endif
            if (curve_nid) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02541)
                             "ECDH curve %s for %s specified in %s",
                             OBJ_nid2sn(curve_nid), vhost_id, certfile);
            }
        }
        /*
         * ...otherwise, enable auto curve selection (OpenSSL 1.0.2)
         * or configure NIST P-256 (required to enable ECDHE for earlier versions)
         * ECDH is always enabled in 1.1.0 unless excluded from SSLCipherList
         */
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        if (!curve_nid) {
    #if defined(SSL_CTX_set_ecdh_auto)
            SSL_CTX_set_ecdh_auto(mctx->ssl_ctx, 1);
    #else
            EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
            if (eckey) {
                SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
                EC_KEY_free(eckey);
            }
    #endif
        }
    #endif
        /* OpenSSL assures us that _free() is NULL-safe */
        EC_GROUP_free(ecgroup);
    #endif
    
        return APR_SUCCESS;
    }
    
    #ifdef HAVE_TLS_SESSION_TICKETS
    static apr_status_t ssl_init_ticket_key(server_rec *s,
                                            apr_pool_t *p,
                                            apr_pool_t *ptemp,
                                            modssl_ctx_t *mctx)
    {
        apr_status_t rv;
        apr_file_t *fp;
        apr_size_t len;
        char buf[TLSEXT_TICKET_KEY_LEN];
        char *path;
        modssl_ticket_key_t *ticket_key = mctx->ticket_key;
        int res;
    
        if (!ticket_key->file_path) {
            return APR_SUCCESS;
        }
    
        path = ap_server_root_relative(p, ticket_key->file_path);
    
        rv = apr_file_open(&fp, path, APR_READ|APR_BINARY,
                           APR_OS_DEFAULT, ptemp);
    
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02286)
                         "Failed to open ticket key file %s: (%d) %pm",
                         path, rv, &rv);
            return ssl_die(s);
        }
    
        rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEY_LEN, &len);
    
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02287)
                         "Failed to read %d bytes from %s: (%d) %pm",
                         TLSEXT_TICKET_KEY_LEN, path, rv, &rv);
            return ssl_die(s);
        }
    
        memcpy(ticket_key->key_name, buf, 16);
        memcpy(ticket_key->aes_key, buf + 32, 16);
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
        memcpy(ticket_key->hmac_secret, buf + 16, 16);
        res = SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx,
                                               ssl_callback_SessionTicket);
    #else
        ticket_key->mac_params[0] =
            OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, buf + 16, 16);
        ticket_key->mac_params[1] =
            OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "sha256", 0);
        ticket_key->mac_params[2] =
            OSSL_PARAM_construct_end();
        res = SSL_CTX_set_tlsext_ticket_key_evp_cb(mctx->ssl_ctx,
                                                   ssl_callback_SessionTicket);
    #endif
        if (!res) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01913)
                         "Unable to initialize TLS session ticket key callback "
                         "(incompatible OpenSSL version?)");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02288)
                     "TLS session ticket key for %s successfully loaded from %s",
                     (mySrvConfig(s))->vhost_id, path);
    
        return APR_SUCCESS;
    }
    #endif
    
    static BOOL load_x509_info(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, filename) <= 0) {
            BIO_free(in);
            return FALSE;
        }
    
        ERR_clear_error();
    
        PEM_X509_INFO_read_bio(in, sk, NULL, NULL);
    
        BIO_free(in);
    
        return TRUE;
    }
    
    static apr_status_t 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;
        STACK_OF(X509) *chain;
        X509_STORE_CTX *sctx;
        X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
        int addl_chain = 0; /* non-zero if additional chain certs were
                             * added to store */
    
        ap_assert(store != NULL); /* safe to assume always non-NULL? */
    
    #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER)
        /* For OpenSSL >=1.1.1, turn on client cert support which is
         * otherwise turned off by default (by design).
         * https://github.com/openssl/openssl/issues/6933 */
        SSL_CTX_set_post_handshake_auth(mctx->ssl_ctx, 1);
    #endif
        
        SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
                                   ssl_callback_proxy_cert);
    
        if (!(pkp->cert_file || pkp->cert_path)) {
            return APR_SUCCESS;
        }
    
        sk = sk_X509_INFO_new_null();
    
        if (pkp->cert_file) {
            load_x509_info(ptemp, sk, pkp->cert_file);
        }
    
        if (pkp->cert_path) {
            ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk);
        }
    
        /* Check that all client certs have got certificates and private
         * keys.  Note the number of certs in the stack may decrease
         * during the loop. */
        for (n = 0; n < sk_X509_INFO_num(sk); n++) {
            X509_INFO *inf = sk_X509_INFO_value(sk, n);
            int has_privkey = inf->x_pkey && inf->x_pkey->dec_pkey;
    
            /* For a lone certificate in the file, trust it as a
             * CA/intermediate certificate. */
            if (inf->x509 && !has_privkey && !inf->enc_data) {
                ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
                               APLOGNO(10261) "Trusting non-leaf certificate");
                X509_STORE_add_cert(store, inf->x509); /* increments inf->x509 */
                /* Delete from the stack and iterate again. */
                X509_INFO_free(inf);
                sk_X509_INFO_delete(sk, n);
                n--;
                addl_chain = 1;
                continue;
            }
    
            if (!has_privkey || inf->enc_data) {
                sk_X509_INFO_free(sk);
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
                             "incomplete client cert configured for SSL proxy "
                             "(missing or encrypted private key?)");
                return ssl_die(s);
            }
            
            if (X509_check_private_key(inf->x509, inf->x_pkey->dec_pkey) != 1) {
                ssl_log_xerror(SSLLOG_MARK, APLOG_STARTUP, 0, ptemp, s, inf->x509,
                               APLOGNO(02326) "proxy client certificate and "
                               "private key do not match");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
                return ssl_die(s);
            }
        }
    
        if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
            sk_X509_INFO_free(sk);
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
                         "no client certs found for SSL proxy");
            return APR_SUCCESS;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207)
                     "loaded %d client certs for SSL proxy",
                     ncerts);
        pkp->certs = sk;
    
        /* If any chain certs are configured, build the ->ca_certs chains
         * corresponding to the loaded keypairs. */
        if (!pkp->ca_cert_file && !addl_chain) {
            return APR_SUCCESS;
        }
    
        /* If SSLProxyMachineCertificateChainFile is configured, load all
         * the CA certs and have OpenSSL attempt to construct a full chain
         * from each configured end-entity cert up to a root.  This will
         * allow selection of the correct cert given a list of root CA
         * names in the certificate request from the server.  */
        pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(sk));
        sctx = X509_STORE_CTX_new();
    
        if (!sctx) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02208)
                         "SSL proxy client cert initialization failed");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            sk_X509_INFO_free(sk);
            return ssl_die(s);
        }
    
        modssl_X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);
    
        for (n = 0; n < ncerts; n++) {
            int i;
    
            X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
            if (!X509_STORE_CTX_init(sctx, store, inf->x509, NULL)) {
                sk_X509_INFO_free(sk);
                X509_STORE_CTX_free(sctx);
                return ssl_die(s);
            }
    
            /* Attempt to verify the client cert */
            if (X509_verify_cert(sctx) != 1) {
                int err = X509_STORE_CTX_get_error(sctx);
                ssl_log_xerror(SSLLOG_MARK, APLOG_WARNING, 0, ptemp, s, inf->x509,
                               APLOGNO(02270) "SSL proxy client cert chain "
                               "verification failed: %s :",
                               X509_verify_cert_error_string(err));
            }
    
            /* Clear X509_verify_cert errors */
            ERR_clear_error();
    
            /* Obtain a copy of the verified chain */
            chain = X509_STORE_CTX_get1_chain(sctx);
    
            if (chain != NULL) {
                /* Discard end entity cert from the chain */
                X509_free(sk_X509_shift(chain));
    
                if ((i = sk_X509_num(chain)) > 0) {
                    /* Store the chain for later use */
                    pkp->ca_certs[n] = chain;
                }
                else {
                    /* Discard empty chain */
                    sk_X509_pop_free(chain, X509_free);
                    pkp->ca_certs[n] = NULL;
                }
    
                ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
                               APLOGNO(02271)
                               "loaded %i intermediate CA%s for cert %i: ",
                               i, i == 1 ? "" : "s", n);
                if (i > 0) {
                    int j;
                    for (j = 0; j < i; j++) {
                        ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s,
                                       sk_X509_value(chain, j), APLOGNO(03039)
                                       "%i:", j);
                    }
                }
            }
    
            /* get ready for next X509_STORE_CTX_init */
            X509_STORE_CTX_cleanup(sctx);
        }
    
        X509_STORE_CTX_free(sctx);
    
        return APR_SUCCESS;
    }
    
    #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(SSL_CTX_free, mctx->ssl_ctx);
    
    #ifdef HAVE_SRP
        if (mctx->srp_vbase != NULL) {
            SRP_VBASE_free(mctx->srp_vbase);
            mctx->srp_vbase = NULL;
        }
    #endif
    }
    
    static apr_status_t ssl_cleanup_proxy_ctx(void *data)
    {
        modssl_ctx_t *mctx = data;
    
        ssl_init_ctx_cleanup(mctx);
    
        if (mctx->pkp->certs) {
            int i = 0;
            int ncerts = sk_X509_INFO_num(mctx->pkp->certs);
    
            if (mctx->pkp->ca_certs) {
                for (i = 0; i < ncerts; i++) {
                    if (mctx->pkp->ca_certs[i] != NULL) {
                        sk_X509_pop_free(mctx->pkp->ca_certs[i], X509_free);
                    }
                }
            }
    
            sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
            mctx->pkp->certs = NULL;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t ssl_init_proxy_ctx(server_rec *s,
                                           apr_pool_t *p,
                                           apr_pool_t *ptemp,
                                           modssl_ctx_t *proxy)
    {
        apr_status_t rv;
    
        if (proxy->ssl_ctx) {
            /* Merged/initialized already */
            return APR_SUCCESS;
        }
    
        apr_pool_cleanup_register(p, proxy,
                                  ssl_cleanup_proxy_ctx,
                                  apr_pool_cleanup_null);
    
        if ((rv = ssl_init_ctx(s, p, ptemp, proxy)) != APR_SUCCESS) {
            return rv;
        }
    
        if ((rv = ssl_init_proxy_certs(s, p, ptemp, proxy)) != APR_SUCCESS) {
            return rv;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t ssl_init_server_ctx(server_rec *s,
                                            apr_pool_t *p,
                                            apr_pool_t *ptemp,
                                            SSLSrvConfigRec *sc,
                                            apr_array_header_t *pphrases)
    {
        apr_status_t rv;
        modssl_pk_server_t *pks;
    #ifdef HAVE_SSL_CONF_CMD
        ssl_ctx_param_t *param = (ssl_ctx_param_t *)sc->server->ssl_ctx_param->elts;
        SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config;
        int i;
    #endif
        int n;
    
        /*
         *  Check for problematic re-initializations
         */
        if (sc->server->ssl_ctx) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02569)
                         "Illegal attempt to re-initialise SSL for server "
                         "(SSLEngine On should go in the VirtualHost, not in global scope.)");
            return APR_EGENERAL;
        }
    
        /* Allow others to provide certificate files */
        pks = sc->server->pks;
        n = pks->cert_files->nelts;
        ap_ssl_add_cert_files(s, p, pks->cert_files, pks->key_files);
        ssl_run_add_cert_files(s, p, pks->cert_files, pks->key_files);
    
        if (apr_is_empty_array(pks->cert_files)) {
            /* does someone propose a certiciate to fall back on here? */
            ap_ssl_add_fallback_cert_files(s, p, pks->cert_files, pks->key_files);
            ssl_run_add_fallback_cert_files(s, p, pks->cert_files, pks->key_files);
            if (n < pks->cert_files->nelts) {
                pks->service_unavailable = 1;
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085)
                             "Init: %s will respond with '503 Service Unavailable' for now. There "
                             "are no SSL certificates configured and no other module contributed any.",
                             ssl_util_vhostid(p, s));
            }
        }
        
        if (n < pks->cert_files->nelts) {
            /* additionally installed certs overrides any old chain configuration */
            sc->server->cert_chain = NULL;
        }
        
        if ((rv = ssl_init_ctx(s, p, ptemp, sc->server)) != APR_SUCCESS) {
            return rv;
        }
    
        if ((rv = ssl_init_server_certs(s, p, ptemp, sc->server, pphrases))
            != APR_SUCCESS) {
            return rv;
        }
    
    #ifdef HAVE_SSL_CONF_CMD
        SSL_CONF_CTX_set_ssl_ctx(cctx, sc->server->ssl_ctx);
        for (i = 0; i < sc->server->ssl_ctx_param->nelts; i++, param++) {
            ERR_clear_error();
            if (SSL_CONF_cmd(cctx, param->name, param->value) <= 0) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02407)
                             "\"SSLOpenSSLConfCmd %s %s\" failed for %s",
                             param->name, param->value, sc->vhost_id);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
            } else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02556)
                             "\"SSLOpenSSLConfCmd %s %s\" applied to %s",
                             param->name, param->value, sc->vhost_id);
            }
        }
    
        if (SSL_CONF_CTX_finish(cctx) == 0) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02547)
                             "SSL_CONF_CTX_finish() failed");
                SSL_CONF_CTX_free(cctx);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
        }
    #endif
    
        if (SSL_CTX_check_private_key(sc->server->ssl_ctx) != 1) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02572)
                         "Failed to configure at least one certificate and key "
                         "for %s", sc->vhost_id);
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
    #if defined(HAVE_OCSP_STAPLING) && defined(SSL_CTRL_SET_CURRENT_CERT)
        /*
         * OpenSSL 1.0.2 and later allows iterating over all SSL_CTX certs
         * by means of SSL_CTX_set_current_cert. Enabling stapling at this
         * (late) point makes sure that we catch both certificates loaded
         * via SSLCertificateFile and SSLOpenSSLConfCmd Certificate.
         */
        do {
            X509 *cert;
            int i = 0;
            int ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx,
                                               SSL_CERT_SET_FIRST);
            while (ret) {
                cert = SSL_CTX_get0_certificate(sc->server->ssl_ctx);
                if (!cert || !ssl_stapling_init_cert(s, p, ptemp, sc->server,
                                                     cert)) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02604)
                                 "Unable to configure certificate %s:%d "
                                 "for stapling", sc->vhost_id, i);
                }
                ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx,
                                               SSL_CERT_SET_NEXT);
                i++;
            }
        } while(0);
    #endif
    
    #ifdef HAVE_TLS_SESSION_TICKETS
        if ((rv = ssl_init_ticket_key(s, p, ptemp, sc->server)) != APR_SUCCESS) {
            return rv;
        }
    #endif
    
        SSL_CTX_set_timeout(sc->server->ssl_ctx,
                            sc->session_cache_timeout == UNSET ?
                            SSL_SESSION_CACHE_TIMEOUT : sc->session_cache_timeout);
    
        return APR_SUCCESS;
    }
    
    /*
     * Configure a particular server
     */
    apr_status_t ssl_init_ConfigureServer(server_rec *s,
                                          apr_pool_t *p,
                                          apr_pool_t *ptemp,
                                          SSLSrvConfigRec *sc,
                                          apr_array_header_t *pphrases)
    {
        SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
                                                    &ssl_module);
        apr_status_t rv;
    
        /* Initialize the server if SSL is enabled.
         */
        if (sc->enabled == SSL_ENABLED_TRUE) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01914)
                         "Configuring server %s for SSL protocol", sc->vhost_id);
            if ((rv = ssl_init_server_ctx(s, p, ptemp, sc, pphrases))
                != APR_SUCCESS) {
                return rv;
            }
    
    	/* Initialize OCSP Responder certificate if OCSP enabled */
    	#ifndef OPENSSL_NO_OCSP
            	ssl_init_ocsp_certificates(s, sc->server);
    	#endif
    
        }
    
        sdc->proxy->sc = sc;
        if (sdc->proxy_enabled == TRUE) {
            rv = ssl_init_proxy_ctx(s, p, ptemp, sdc->proxy);
            if (rv != APR_SUCCESS) {
                return rv;
            }
        }
        else {
            sdc->proxy_enabled = FALSE;
        }
        sdc->proxy_post_config = 1;
    
        return APR_SUCCESS;
    }
    
    apr_status_t ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
    {
        server_rec *s;
        SSLSrvConfigRec *sc;
    #ifndef HAVE_TLSEXT
        server_rec *ps;
        apr_hash_t *table;
        const char *key;
        apr_ssize_t klen;
    
        BOOL conflict = FALSE;
    #endif
    
        /*
         * 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, APLOGNO(01915)
                             "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, APLOGNO(01916)
                             "Init: (%s) You configured HTTP(%d) "
                             "on the standard HTTPS(%d) port!",
                             ssl_util_vhostid(p, s),
                             DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT);
            }
        }
    
    #ifndef HAVE_TLSEXT
        /*
         * Give out warnings when more than one SSL-aware virtual server uses the
         * same IP:port and an OpenSSL version without support for TLS extensions
         * (SNI in particular) is used.
         */
        table = apr_hash_make(p);
    
        for (s = base_server; s; s = s->next) {
            char *addr;
    
            sc = mySrvConfig(s);
    
            if (!((sc->enabled == SSL_ENABLED_TRUE) && s->addrs)) {
                continue;
            }
    
            apr_sockaddr_ip_get(&addr, s->addrs->host_addr);
            key = apr_psprintf(p, "%s:%u", 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, APLOGNO(02662)
                             "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, APLOGNO(01917)
                         "Init: Name-based SSL virtual hosts require "
                         "an OpenSSL version with support for TLS extensions "
                         "(RFC 6066 - Server Name Indication / SNI), "
                         "but the currently used library version (%s) is "
                         "lacking this feature", MODSSL_LIBRARY_DYNTEXT);
        }
    #endif
    
        return APR_SUCCESS;
    }
    
    int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
                                      apr_pool_t *ptemp, server_rec *s,
                                      ap_conf_vector_t *section_config)
    {
        SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
                                                    &ssl_module);
        SSLDirConfigRec *pdc = ap_get_module_config(section_config,
                                                    &ssl_module);
        if (pdc) {
            pdc->proxy->sc = mySrvConfig(s);
            ssl_config_proxy_merge(p, sdc, pdc);
            if (pdc->proxy_enabled) {
                apr_status_t rv;
    
                rv = ssl_init_proxy_ctx(s, p, ptemp, pdc->proxy);
                if (rv != APR_SUCCESS) {
                    return !OK;
                }
    
                rv = ssl_run_init_server(s, p, 1, pdc->proxy->ssl_ctx);
                if (rv != APR_SUCCESS) {
                    return !OK;
                }
            }
            pdc->proxy_post_config = 1;
        }
        return OK;
    }
    
    static apr_status_t ssl_init_ca_cert_path(server_rec *s,
                                              apr_pool_t *ptemp,
                                              const char *path,
                                              STACK_OF(X509_NAME) *ca_list,
                                              STACK_OF(X509_INFO) *xi_list)
    {
        apr_dir_t *dir;
        apr_finfo_t direntry;
        apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME;
    
        if (!path || (!ca_list && !xi_list) ||
            (apr_dir_open(&dir, path, ptemp) != APR_SUCCESS)) {
            return APR_EGENERAL;
        }
    
        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, path, "/", direntry.name, NULL);
            if (ca_list) {
                SSL_add_file_cert_subjects_to_stack(ca_list, file);
            }
            if (xi_list) {
                load_x509_info(ptemp, xi_list, file);
            }
        }
    
        apr_dir_close(dir);
    
        return APR_SUCCESS;
    }
    
    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 = sk_X509_NAME_new_null();;
    
        /*
         * Process CA certificate bundle file
         */
        if (ca_file) {
            SSL_add_file_cert_subjects_to_stack(ca_list, ca_file);
            /*
             * If ca_list is still empty after trying to load ca_file
             * then the file failed to load, and users should hear about that.
             */
            if (sk_X509_NAME_num(ca_list) == 0) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02210)
                        "Failed to load SSLCACertificateFile: %s", ca_file);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
            }
        }
    
        /*
         * Process CA certificate path files
         */
        if (ca_path &&
            ssl_init_ca_cert_path(s, ptemp,
                                  ca_path, ca_list, NULL) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02211)
                         "Failed to open Certificate Path `%s'", ca_path);
            sk_X509_NAME_pop_free(ca_list, X509_NAME_free);
            return 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);
    #ifdef HAVE_OCSP_STAPLING
        ssl_stapling_mutex_reinit(s, p);
    #endif
    }
    
    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);
    
        /*
         * 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(sc->server);
    
    	/* Not Sure but possibly clear X509 trusted cert file */
    	#ifndef OPENSSL_NO_OCSP
    		sk_X509_pop_free(sc->server->ocsp_certs, X509_free);
    	#endif
    
        }
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        free_dh_params();
    #else
        free_bio_methods();
    #endif
    
        return APR_SUCCESS;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_pphrase.c�������������������������������������������������������0000664�0001751�0001751�00000110356�14721076620�021122� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include <openssl/ui.h>
    #if MODSSL_HAVE_OPENSSL_STORE
    #include <openssl/store.h>
    #endif
    
    typedef struct {
        server_rec         *s;
        apr_pool_t         *p;
        apr_array_header_t *aPassPhrase;
        int                 nPassPhraseCur;
        char               *cpPassPhraseCur;
        int                 nPassPhraseDialog;
        int                 nPassPhraseDialogCur;
        BOOL                bPassPhraseDialogOnce;
        const char         *key_id;
        const char         *pkey_file;
    } pphrase_cb_arg_t;
    
    #ifdef HAVE_ECC
    static const char *key_types[] = {"RSA", "DSA", "ECC"};
    #else
    static const char *key_types[] = {"RSA", "DSA"};
    #endif
    
    /*
     * Return true if the named file exists and is readable
     */
    
    static apr_status_t exists_and_readable(const 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 const char *asn1_table_vhost_key(SSLModConfigRec *mc, apr_pool_t *p,
                                      const char *id, int i)
    {
        /* 'p' pool used here is cleared on restarts (or sooner) */
        char *key = apr_psprintf(p, "%s:%d", id, i);
        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;
    
    int ssl_pphrase_Handle_CB(char *, int, int, void *);
    
    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];
    }
    
    apr_status_t ssl_load_encrypted_pkey(server_rec *s, apr_pool_t *p, int idx,
                                         const char *pkey_file,
                                         apr_array_header_t **pphrases)
    {
        SSLModConfigRec *mc = myModConfig(s);
        SSLSrvConfigRec *sc = mySrvConfig(s);
        const char *key_id = asn1_table_vhost_key(mc, p, sc->vhost_id, idx);
        EVP_PKEY *pPrivateKey = NULL;
        ssl_asn1_t *asn1;
        int nPassPhrase = (*pphrases)->nelts;
        int nPassPhraseRetry = 0;
        apr_time_t pkey_mtime = 0;
        apr_status_t rv;
        pphrase_cb_arg_t ppcb_arg;
    
        if (!pkey_file) {
             ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02573)
                          "Init: No private key specified for %s", key_id);
             return ssl_die(s);
        }
        else if ((rv = exists_and_readable(pkey_file, p, &pkey_mtime))
                 != APR_SUCCESS ) {
             ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02574)
                          "Init: Can't open server private key file %s", pkey_file);
             return ssl_die(s);
        }
    
        ppcb_arg.s                     = s;
        ppcb_arg.p                     = p;
        ppcb_arg.aPassPhrase           = *pphrases;
        ppcb_arg.nPassPhraseCur        = 0;
        ppcb_arg.cpPassPhraseCur       = NULL;
        ppcb_arg.nPassPhraseDialog     = 0;
        ppcb_arg.nPassPhraseDialogCur  = 0;
        ppcb_arg.bPassPhraseDialogOnce = TRUE;
        ppcb_arg.key_id                = key_id;
        ppcb_arg.pkey_file             = pkey_file;
    
        /*
         * 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) {
            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, s, APLOGNO(02575)
                             "Reusing existing private key from %s on restart",
                             ppcb_arg.pkey_file);
                return APR_SUCCESS;
            }
        }
    
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02576)
                     "Attempting to load encrypted (?) private key %s", key_id);
    
        for (;;) {
            /*
             * Try to read the private key file with the help of
             * the callback function which serves the pass
             * phrases to OpenSSL
             */
    
            ppcb_arg.cpPassPhraseCur = NULL;
    
            /* Ensure that the error stack is empty; some SSL
             * functions will fail spuriously if the error stack
             * is not empty. */
            ERR_clear_error();
    
            pPrivateKey = modssl_read_privatekey(ppcb_arg.pkey_file,
                                                 ssl_pphrase_Handle_CB, &ppcb_arg);
            /* If the private key was successfully read, nothing more to
               do here. */
            if (pPrivateKey != NULL)
                break;
    
            /*
             * when we have more remembered pass phrases
             * try to reuse these first.
             */
            if (ppcb_arg.nPassPhraseCur < nPassPhrase) {
                ppcb_arg.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
                && ppcb_arg.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_EMERG, 0, s, APLOGNO(02577)
                             "Init: SSLPassPhraseDialog builtin is not "
                             "supported on Win32 (key file "
                             "%s)", ppcb_arg.pkey_file);
                return ssl_die(s);
            }
    #endif /* WIN32 */
    
            /*
             * Ok, anything else now means a fatal error.
             */
            if (ppcb_arg.cpPassPhraseCur == NULL) {
                if (ppcb_arg.nPassPhraseDialogCur && pkey_mtime &&
                    !isatty(fileno(stdout))) /* XXX: apr_isatty() */
                {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                                 s, APLOGNO(02578)
                                 "Init: Unable to read pass phrase "
                                 "[Hint: key introduced or changed "
                                 "before restart?]");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
                }
                else {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                                 s, APLOGNO(02579) "Init: Private key not found");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
                }
                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_EMERG, 0, s, APLOGNO(02580)
                             "Init: Pass phrase incorrect for key %s",
                             key_id);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
    
                if (writetty) {
                    apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase incorrect.\n");
                    apr_file_printf(writetty, "**Stopped\n");
                }
            }
            return ssl_die(s);
        }
    
        if (pPrivateKey == NULL) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02581)
                         "Init: Unable to read server private key from file %s",
                         ppcb_arg.pkey_file);
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
        /*
         * Log the type of reading
         */
        if (ppcb_arg.nPassPhraseDialogCur == 0) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02582)
                         "unencrypted %s private key - pass phrase not "
                         "required", key_id);
        }
        else {
            if (ppcb_arg.cpPassPhraseCur != NULL) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
                             s, APLOGNO(02583)
                             "encrypted %s private key - pass phrase "
                             "requested", key_id);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
                             s, APLOGNO(02584)
                             "encrypted %s private key - pass phrase"
                             " reused", key_id);
            }
        }
    
        /*
         * Ok, when we have one more pass phrase store it
         */
        if (ppcb_arg.cpPassPhraseCur != NULL) {
            *(const char **)apr_array_push(ppcb_arg.aPassPhrase) =
                ppcb_arg.cpPassPhraseCur;
            nPassPhrase++;
        }
    
        /* Cache the private key in the global module configuration so it
         * can be used after subsequent reloads. */
        asn1 = ssl_asn1_table_set(mc->tPrivateKey, key_id, pPrivateKey);
    
        if (ppcb_arg.nPassPhraseDialogCur != 0) {
            /* remember mtime of encrypted keys */
            asn1->source_mtime = pkey_mtime;
        }
    
        /*
         * Free the private key structure
         */
        EVP_PKEY_free(pPrivateKey);
    
        /*
         * Let the user know when we're successful.
         */
        if ((ppcb_arg.nPassPhraseDialog > 0) &&
            (ppcb_arg.cpPassPhraseCur != NULL)) {
            if (writetty) {
                apr_file_printf(writetty, "\n"
                                "OK: Pass Phrase Dialog successful.\n");
            }
        }
    
        /* Close the pipes if they were opened
         */
        if (readtty) {
            apr_file_close(readtty);
            apr_file_close(writetty);
            readtty = writetty = NULL;
        }
    
        return APR_SUCCESS;
    }
    
    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;
    
            apr_tokenize_to_argv(progname, &args, p);
            procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew));
            rc = apr_proc_create(procnew, args[0], (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;
    }
    
    int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
    {
        pphrase_cb_arg_t *ppcb_arg = (pphrase_cb_arg_t *)srv;
        SSLSrvConfigRec *sc = mySrvConfig(ppcb_arg->s);
        char *cpp;
        int len = -1;
    
        ppcb_arg->nPassPhraseDialog++;
        ppcb_arg->nPassPhraseDialogCur++;
    
        /*
         * When remembered pass phrases are available use them...
         */
        if ((cpp = pphrase_array_get(ppcb_arg->aPassPhrase,
                                     ppcb_arg->nPassPhraseCur)) != 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, ppcb_arg->s,
                                 APLOGNO(01965)
                                 "Init: Creating pass phrase dialog pipe child "
                                 "'%s'", sc->server->pphrase_dialog_path);
                    if (ssl_pipe_child_create(ppcb_arg->p,
                                              sc->server->pphrase_dialog_path)
                            != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb_arg->s,
                                     APLOGNO(01966)
                                     "Init: Failed to create pass phrase pipe '%s'",
                                     sc->server->pphrase_dialog_path);
                        PEMerr(PEM_F_PEM_DEF_CALLBACK,
                               PEM_R_PROBLEMS_GETTING_PASSWORD);
                        memset(buf, 0, (unsigned int)bufsize);
                        return (-1);
                    }
                }
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb_arg->s, APLOGNO(01967)
                             "Init: Requesting pass phrase via piped dialog");
            }
            else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
    #ifdef WIN32
                PEMerr(PEM_F_PEM_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, ppcb_arg->p);
    
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb_arg->s, APLOGNO(01968)
                             "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 (ppcb_arg->nPassPhraseDialog == 1) {
                apr_file_printf(writetty, "%s mod_ssl (Pass Phrase Dialog)\n",
                                AP_SERVER_BASEVERSION);
                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 (ppcb_arg->bPassPhraseDialogOnce) {
                ppcb_arg->bPassPhraseDialogOnce = FALSE;
                apr_file_printf(writetty, "\n");
                apr_file_printf(writetty, "Private key %s (%s)\n",
                                ppcb_arg->key_id, ppcb_arg->pkey_file);
            }
    
            /*
             * 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_PEM_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(ppcb_arg->p, sizeof(char *) * 4);
            const char *idx = ap_strrchr_c(ppcb_arg->key_id, ':') + 1;
            char *result;
            int i;
    
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb_arg->s, APLOGNO(01969)
                         "Init: Requesting pass phrase from dialog filter "
                         "program (%s)", cmd);
    
            argv[0] = cmd;
            argv[1] = apr_pstrndup(ppcb_arg->p, ppcb_arg->key_id,
                                   idx-1 - ppcb_arg->key_id);
            if ((i = atoi(idx)) < CERTKEYS_IDX_MAX+1) {
                /*
                 * For compatibility with existing 2.4.x configurations, use
                 * "RSA", "DSA" and "ECC" strings for the first two/three keys
                 */
                argv[2] = key_types[i];
            } else {
                /* Four and above: use the integer index */
                argv[2] = apr_pstrdup(ppcb_arg->p, idx);
            }
            argv[3] = NULL;
    
            result = ssl_util_readfilter(ppcb_arg->s, ppcb_arg->p, cmd, argv);
            apr_cpystrn(buf, result, bufsize);
            len = strlen(buf);
        }
    
        /*
         * Ok, we now have the pass phrase, so give it back
         */
        ppcb_arg->cpPassPhraseCur = apr_pstrdup(ppcb_arg->p, buf);
    
        /*
         * And return its length to OpenSSL...
         */
        return (len);
    }
    
    #if MODSSL_HAVE_ENGINE_API || MODSSL_HAVE_OPENSSL_STORE
    
    /* OpenSSL UI implementation for passphrase entry; largely duplicated
     * from ssl_pphrase_Handle_CB but adjusted for UI API. TODO: Might be
     * worth trying to shift pphrase handling over to the UI API
     * completely. */
    static int passphrase_ui_open(UI *ui)
    {
        pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
        SSLSrvConfigRec *sc = mySrvConfig(ppcb->s);
    
        ppcb->nPassPhraseDialog++;
        ppcb->nPassPhraseDialogCur++;
    
        /*
         * Builtin or Pipe dialog
         */
        if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
            || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
            if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
                if (!readtty) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s,
                                 APLOGNO(10143)
                                 "Init: Creating pass phrase dialog pipe child "
                                 "'%s'", sc->server->pphrase_dialog_path);
                    if (ssl_pipe_child_create(ppcb->p,
                                sc->server->pphrase_dialog_path)
                            != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s,
                                     APLOGNO(10144)
                                     "Init: Failed to create pass phrase pipe '%s'",
                                     sc->server->pphrase_dialog_path);
                        return 0;
                    }
                }
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10145)
                             "Init: Requesting pass phrase via piped dialog");
            }
            else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
    #ifdef WIN32
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s, APLOGNO(10146)
                             "Init: Failed to create pass phrase pipe '%s'",
                             sc->server->pphrase_dialog_path);
                return 0;
    #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, ppcb->p);
    
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10147)
                             "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 (ppcb->nPassPhraseDialog == 1) {
                apr_file_printf(writetty, "%s mod_ssl (Pass Phrase Dialog)\n",
                                AP_SERVER_BASEVERSION);
                apr_file_printf(writetty,
                                "A pass phrase is required to access the private key.\n");
            }
            if (ppcb->bPassPhraseDialogOnce) {
                ppcb->bPassPhraseDialogOnce = FALSE;
                apr_file_printf(writetty, "\n");
                apr_file_printf(writetty, "Private key %s (%s)\n",
                                ppcb->key_id, ppcb->pkey_file);
            }
        }
    
        return 1;
    }
    
    static int passphrase_ui_read(UI *ui, UI_STRING *uis)
    {
        pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
        SSLSrvConfigRec *sc = mySrvConfig(ppcb->s);
        const char *prompt;
        int i;
        int bufsize;
        int len;
        char *buf;
    
        prompt = UI_get0_output_string(uis);
        if (prompt == NULL) {
            prompt = "Enter pass phrase:";
        }
    
        /*
         * Get the maximum expected size and allocate the buffer
         */
        bufsize = UI_get_result_maxsize(uis);
        buf = apr_pcalloc(ppcb->p, bufsize);
    
        if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
            || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
            /*
             * Get the pass phrase through a callback.
             * Empty input is not accepted.
             */
            for (;;) {
                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) {
                    OPENSSL_cleanse(buf, bufsize);
                    return 0;
                }
                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");
                    apr_file_puts(prompt, writetty);
                }
                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(ppcb->p, sizeof(char *) * 3);
            char *result;
    
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10148)
                         "Init: Requesting pass phrase from dialog filter "
                         "program (%s)", cmd);
    
            argv[0] = cmd;
            argv[1] = ppcb->key_id;
            argv[2] = NULL;
    
            result = ssl_util_readfilter(ppcb->s, ppcb->p, cmd, argv);
            apr_cpystrn(buf, result, bufsize);
            len = strlen(buf);
        }
    
        /*
         * Ok, we now have the pass phrase, so give it back
         */
        ppcb->cpPassPhraseCur = apr_pstrdup(ppcb->p, buf);
        UI_set_result(ui, uis, buf);
    
        /* Clear sensitive data. */
        OPENSSL_cleanse(buf, bufsize);
        return 1;
    }
    
    static int passphrase_ui_write(UI *ui, UI_STRING *uis)
    {
        pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
        SSLSrvConfigRec *sc;
        const char *prompt;
    
        sc = mySrvConfig(ppcb->s);
    
        if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
            || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
            prompt = UI_get0_output_string(uis);
            apr_file_puts(prompt, writetty);
        }
    
        return 1;
    }
    
    static int passphrase_ui_close(UI *ui)
    {
        /*
         * Close the pipes if they were opened
         */
        if (readtty) {
            apr_file_close(readtty);
            apr_file_close(writetty);
            readtty = writetty = NULL;
        }
        return 1;
    }
    
    static apr_status_t pp_ui_method_cleanup(void *uip)
    {
        UI_METHOD *uim = uip;
        
        UI_destroy_method(uim);
    
        return APR_SUCCESS;
    }
    
    static UI_METHOD *get_passphrase_ui(apr_pool_t *p)
    {
        UI_METHOD *ui_method = UI_create_method("Passphrase UI");
    
        UI_method_set_opener(ui_method, passphrase_ui_open);
        UI_method_set_reader(ui_method, passphrase_ui_read);
        UI_method_set_writer(ui_method, passphrase_ui_write);
        UI_method_set_closer(ui_method, passphrase_ui_close);
    
        apr_pool_cleanup_register(p, ui_method, pp_ui_method_cleanup,
                                  pp_ui_method_cleanup);
        
        return ui_method;
    }
    #endif
    
    #if MODSSL_HAVE_ENGINE_API
    static apr_status_t modssl_engine_cleanup(void *engine)
    {
        ENGINE *e = engine;
    
        ENGINE_finish(e);
    
        return APR_SUCCESS;
    }
    
    /* Tries to load the key and optionally certificate via the ENGINE
     * API. Returns APR_ENOTIMPL if an ENGINE could not be identified
     * loaded from the key name. */
    static apr_status_t modssl_load_keypair_engine(server_rec *s, apr_pool_t *pconf,
                                                   apr_pool_t *ptemp,
                                                   const char *vhostid,
                                                   const char *certid,
                                                   const char *keyid,
                                                   X509 **pubkey,
                                                   EVP_PKEY **privkey)
    {
        const char *c, *scheme;
        ENGINE *e;
        UI_METHOD *ui_method = get_passphrase_ui(ptemp);
        pphrase_cb_arg_t ppcb;
    
        memset(&ppcb, 0, sizeof ppcb);
        ppcb.s = s;
        ppcb.p = ptemp;
        ppcb.bPassPhraseDialogOnce = TRUE;
        ppcb.key_id = vhostid;
        ppcb.pkey_file = keyid;
    
        c = ap_strchr_c(keyid, ':');
        if (!c || c == keyid) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(10131)
                         "Init: Unrecognized private key identifier `%s'",
                         keyid);
            return APR_ENOTIMPL;
        }
    
        scheme = apr_pstrmemdup(ptemp, keyid, c - keyid);
        if (!(e = ENGINE_by_id(scheme))) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(10132)
                         "Init: Failed to load engine for private key %s",
                         keyid);
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_NOTICE, s);
            return APR_ENOTIMPL;
        }
    
        if (!ENGINE_init(e)) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10149)
                         "Init: Failed to initialize engine %s for private key %s",
                         scheme, keyid);
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 
                     "Init: Initialized engine %s for private key %s",
                     scheme, keyid);
    
        if (APLOGdebug(s)) {
            ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0);
        }
    
        if (certid) {
            struct {
                const char *cert_id;
                X509 *cert;
            } params = { certid, NULL };
    
            if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &params, NULL, 1)) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10136)
                             "Init: Unable to get the certificate");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
                return ssl_die(s);
            }
    
            *pubkey = params.cert;
        }
    
        *privkey = ENGINE_load_private_key(e, keyid, ui_method, &ppcb);
        if (*privkey == NULL) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133)
                         "Init: Unable to get the private key");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
            return ssl_die(s);
        }
    
        /* Release the functional reference obtained by ENGINE_init() only
         * when after the ENGINE is no longer used. */
        apr_pool_cleanup_register(pconf, e, modssl_engine_cleanup, modssl_engine_cleanup);
    
        /* Release the structural reference obtained by ENGINE_by_id()
         * immediately. */
        ENGINE_free(e);
    
        return APR_SUCCESS;
    }
    #endif
    
    #if MODSSL_HAVE_OPENSSL_STORE
    static OSSL_STORE_INFO *modssl_load_store_uri(server_rec *s, apr_pool_t *p,
                                                  const char *vhostid,
                                                  const char *uri, int info_type)
    {
        OSSL_STORE_CTX *sctx;
        UI_METHOD *ui_method = get_passphrase_ui(p);
        pphrase_cb_arg_t ppcb;
        OSSL_STORE_INFO *info = NULL;
    
        memset(&ppcb, 0, sizeof ppcb);
        ppcb.s = s;
        ppcb.p = p;
        ppcb.bPassPhraseDialogOnce = TRUE;
        ppcb.key_id = vhostid;
        ppcb.pkey_file = uri;
    
        sctx = OSSL_STORE_open(uri, ui_method, &ppcb, NULL, NULL);
        if (!sctx) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(10491)
                         "Init: OSSL_STORE_open failed for PKCS#11 URI `%s'",
                         uri);
            return NULL;
        }
    
        while (!OSSL_STORE_eof(sctx)) {
            info = OSSL_STORE_load(sctx);
            if (!info)
                break;
    
            if (OSSL_STORE_INFO_get_type(info) == info_type)
                break;
    
            OSSL_STORE_INFO_free(info);
            info = NULL;
        }
    
        OSSL_STORE_close(sctx);
    
        return info;
    }
    
    static apr_status_t modssl_load_keypair_store(server_rec *s, apr_pool_t *p,
                                                  const char *vhostid,
                                                  const char *certid,
                                                  const char *keyid,
                                                  X509 **pubkey,
                                                  EVP_PKEY **privkey)
    {
        OSSL_STORE_INFO *info = NULL;
    
        *privkey = NULL;
        *pubkey = NULL;
    
        info = modssl_load_store_uri(s, p, vhostid, keyid, OSSL_STORE_INFO_PKEY);
        if (!info) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10492)
                         "Init: OSSL_STORE_INFO_PKEY lookup failed for private key identifier `%s'",
                         keyid);
            return ssl_die(s);
        }
    
        *privkey = OSSL_STORE_INFO_get1_PKEY(info);
        OSSL_STORE_INFO_free(info);
        if (!*privkey) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10493)
                         "Init: OSSL_STORE_INFO_PKEY lookup failed for private key identifier `%s'",
                         keyid);
            return ssl_die(s);
        }
    
        if (certid) {
            info = modssl_load_store_uri(s, p, vhostid, certid, OSSL_STORE_INFO_CERT);
            if (!info) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10494)
                             "Init: OSSL_STORE_INFO_CERT lookup failed for certificate identifier `%s'",
                             keyid);
                return ssl_die(s);
            }
    
            *pubkey = OSSL_STORE_INFO_get1_CERT(info);
            OSSL_STORE_INFO_free(info);
            if (!*pubkey) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10495)
                         "Init: OSSL_STORE_INFO_CERT lookup failed for certificate identifier `%s'",
                         certid);
                return ssl_die(s);
            }
        }
    
        return APR_SUCCESS;
    }
    #endif
    
    apr_status_t modssl_load_engine_keypair(server_rec *s,
                                            apr_pool_t *pconf, apr_pool_t *ptemp,
                                            const char *vhostid,
                                            const char *certid, const char *keyid,
                                            X509 **pubkey, EVP_PKEY **privkey)
    {
    #if MODSSL_HAVE_ENGINE_API 
        apr_status_t rv;
    
        rv = modssl_load_keypair_engine(s, pconf, ptemp,
                                        vhostid, certid, keyid,
                                        pubkey, privkey);
        if (rv == APR_SUCCESS) {
            return rv;
        }
        /* If STORE support is not present, all errors are fatal here; if
         * STORE is present and the ENGINE could not be loaded, ignore the
         * error and fall through to try loading via the STORE API. */
        else if (!MODSSL_HAVE_OPENSSL_STORE || rv != APR_ENOTIMPL) {
            return ssl_die(s);
        }
    
    #endif
    #if MODSSL_HAVE_OPENSSL_STORE
        return modssl_load_keypair_store(s, ptemp, vhostid, certid, keyid,
                                         pubkey, privkey);
    #else
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10496)
                     "Init: no method for loading keypair for %s (%s | %s)",
                     vhostid, certid ? certid : "no cert", keyid);
        return APR_ENOTIMPL;
    #endif
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_vars.c����������������������������������������������������������0000664�0001751�0001751�00000116537�15032733636�020445� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "ap_expr.h"
    
    #include "apr_time.h"
    
    /*  _________________________________________________________________
    **
    **  Variable Lookup
    **  _________________________________________________________________
    */
    
    static char *ssl_var_lookup_ssl(apr_pool_t *p, SSLConnRec *sslconn, request_rec *r, char *var);
    static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs, char *var);
    static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, const char *var);
    static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var);
    static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm);
    static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_TIME *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_rfc4523_cea(apr_pool_t *p, SSL *ssl);
    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, SSLConnRec *sslconn);
    static char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, SSLConnRec *sslconn, 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 char *ssl_var_lookup_ssl_compress_meth(SSL *ssl);
    
    static SSLConnRec *ssl_get_effective_config(conn_rec *c)
    {
        SSLConnRec *sslconn = myConnConfig(c);
        if (!(sslconn && sslconn->ssl) && c->master) {
            /* use master connection if no SSL defined here */
            sslconn = myConnConfig(c->master);
        }
        return sslconn;
    }
    
    static int ssl_conn_is_ssl(conn_rec *c)
    {
        const SSLConnRec *sslconn = ssl_get_effective_config(c);
        return (sslconn && sslconn->ssl)? OK : DECLINED;
    }
    
    static const char var_interface[] = "mod_ssl/" AP_SERVER_BASEREVISION;
    static char var_library_interface[] = MODSSL_LIBRARY_TEXT;
    static char *var_library = NULL;
    
    static apr_array_header_t *expr_peer_ext_list_fn(ap_expr_eval_ctx_t *ctx,
                                                     const void *dummy,
                                                     const char *arg)
    {
        return ssl_ext_list(ctx->p, ctx->c, 1, arg);
    }
    
    static const char *expr_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
    {
        char *var = (char *)data;
        SSLConnRec *sslconn = ssl_get_effective_config(ctx->c);
    
        return sslconn ? ssl_var_lookup_ssl(ctx->p, sslconn, ctx->r, var) : NULL;
    }
    
    static const char *expr_func_fn(ap_expr_eval_ctx_t *ctx, const void *data,
                                    const char *arg)
    {
        char *var = (char *)arg;
    
        return var ? ssl_var_lookup(ctx->p, ctx->s, ctx->c, ctx->r, var) : NULL;
    }
    
    static int ssl_expr_lookup(ap_expr_lookup_parms *parms)
    {
        switch (parms->type) {
        case AP_EXPR_FUNC_VAR:
            /* for now, we just handle everything that starts with SSL_, but
             * register our hook as APR_HOOK_LAST
             * XXX: This can be optimized
             */
            if (strcEQn(parms->name, "SSL_", 4)) {
                *parms->func = expr_var_fn;
                *parms->data = parms->name + 4;
                return OK;
            }
            break;
        case AP_EXPR_FUNC_STRING:
            /* Function SSL() is implemented by us.
             */
            if (strcEQ(parms->name, "SSL")) {
                *parms->func = expr_func_fn;
                *parms->data = NULL;
                return OK;
            }
            break;
        case AP_EXPR_FUNC_LIST:
            if (strcEQ(parms->name, "PeerExtList")) {
                *parms->func = expr_peer_ext_list_fn;
                *parms->data = "PeerExtList";
                return OK;
            }
            break;
        }
        return DECLINED;
    }
    
    
    void ssl_var_register(apr_pool_t *p)
    {
        char *cp, *cp2;
    
        ap_hook_ssl_conn_is_ssl(ssl_conn_is_ssl, NULL, NULL, APR_HOOK_MIDDLE);
        APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
        APR_REGISTER_OPTIONAL_FN(ssl_ext_list);
    
        /* Perform once-per-process library version determination: */
        var_library = apr_pstrdup(p, MODSSL_LIBRARY_DYNTEXT);
    
        if ((cp = strchr(var_library, ' ')) != NULL) {
            *cp = '/';
            if ((cp2 = strchr(cp, ' ')) != NULL)
                *cp2 = NUL;
        }
    
        if ((cp = strchr(var_library_interface, ' ')) != NULL) {
            *cp = '/';
            if ((cp2 = strchr(cp, ' ')) != NULL)
                *cp2 = NUL;
        }
    
        ap_hook_expr_lookup(ssl_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    /* 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_ADDR"))
                    result = r->useragent_ip;
                else if (strcEQ(var, "REMOTE_HOST"))
                    result = ap_get_useragent_host(r, 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_for_url(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;
                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);
                }
                break;
            }
        }
    
        /*
         * Connection stuff
         */
        if (result == NULL && c != NULL) {
            SSLConnRec *sslconn = ssl_get_effective_config(c);
            if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
                && sslconn && sslconn->ssl)
                result = ssl_var_lookup_ssl(p, sslconn, r, var+4);
            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_banner();
            else if (strcEQ(var, "API_VERSION")) {
                result = apr_itoa(p, MODULE_MAGIC_NUMBER_MAJOR);
                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 = 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, SSLConnRec *sslconn, 
                                    request_rec *r, char *var)
    {
        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[MODSSL_SESSION_ID_STRING_LEN];
            SSL_SESSION *pSession = SSL_get_session(ssl);
            if (pSession) {
                IDCONST unsigned char *id;
                unsigned int idlen;
    
    #ifdef OPENSSL_NO_SSL_INTERN
                id = (unsigned char *)SSL_SESSION_get_id(pSession, &idlen);
    #else
                id = pSession->session_id;
                idlen = pSession->session_id_length;
    #endif
    
                result = apr_pstrdup(p, modssl_SSL_SESSION_id2sz(id, idlen,
                                                                 buf, sizeof(buf)));
            }
        }
        else if(ssl != NULL && strcEQ(var, "SESSION_RESUMED")) {
            if (SSL_session_reused(ssl) == 1)
                result = "Resumed";
            else
                result = "Initial";
        }
        else if (ssl != NULL && strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) {
            result = ssl_var_lookup_ssl_cipher(p, sslconn, 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_CERT_RFC4523_CEA")) {
            result = ssl_var_lookup_ssl_cert_rfc4523_cea(p, ssl);
        }
        else if (ssl != NULL && strcEQ(var, "CLIENT_VERIFY")) {
            result = ssl_var_lookup_ssl_cert_verify(p, sslconn);
        }
        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, r, 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, r, xs, var+7);
                /* SSL_get_certificate is different from SSL_get_peer_certificate.
                 * No need to X509_free(xs).
                 */
            }
        }
        else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) {
            result = ssl_var_lookup_ssl_compress_meth(ssl);
        }
    #ifdef HAVE_TLSEXT
        else if (ssl != NULL && strcEQ(var, "TLS_SNI")) {
            result = apr_pstrdup(p, SSL_get_servername(ssl,
                                                       TLSEXT_NAMETYPE_host_name));
        }
    #endif
        else if (ssl != NULL && strcEQ(var, "SECURE_RENEG")) {
            int flag = 0;
    #ifdef SSL_get_secure_renegotiation_support
            flag = SSL_get_secure_renegotiation_support(ssl);
    #endif
            result = apr_pstrdup(p, flag ? "true" : "false");
        }
    #ifdef HAVE_SRP
        else if (ssl != NULL && strcEQ(var, "SRP_USER")) {
            if ((result = SSL_get_srp_username(ssl)) != NULL) {
                result = apr_pstrdup(p, result);
            }
        }
        else if (ssl != NULL && strcEQ(var, "SRP_USERINFO")) {
            if ((result = SSL_get_srp_userinfo(ssl)) != NULL) {
                result = apr_pstrdup(p, result);
            }
        }
    #endif
    
        return result;
    }
    
    static char *ssl_var_lookup_ssl_cert_dn_oneline(apr_pool_t *p, request_rec *r,
                                                    X509_NAME *xsname)
    {
        char *result = NULL;
        SSLDirConfigRec *dc;
        int legacy_format = 0;
        if (r) {
            dc = myDirConfig(r);
            legacy_format = dc->nOptions & SSL_OPT_LEGACYDNFORMAT;
        }
        if (legacy_format) {
            char *cp = X509_NAME_oneline(xsname, NULL, 0);
            result = apr_pstrdup(p, cp);
            OPENSSL_free(cp);
        }
        else {
            BIO* bio;
            unsigned long flags = XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB;
    
            if ((bio = BIO_new(BIO_s_mem())) == NULL)
                return NULL;
            X509_NAME_print_ex(bio, xsname, 0, flags);
    
            result = modssl_bio_free_read(p, bio);
        }
        return result;
    }
    
    static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs,
                                         char *var)
    {
        char *result;
        BOOL resdup;
        X509_NAME *xsname;
        int nid;
    
        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 (*var && strcEQ(var+1, "_DN")) {
            if (*var == 'S')
                xsname = X509_get_subject_name(xs);
            else if (*var == 'I')
                xsname = X509_get_issuer_name(xs);
            else
                return NULL;
            result = ssl_var_lookup_ssl_cert_dn_oneline(p, r, xsname);
            resdup = FALSE;
        }
        else if (strlen(var) > 5 && strcEQn(var+1, "_DN_", 4)) {
            if (*var == 'S')
                xsname = X509_get_subject_name(xs);
            else if (*var == 'I')
                xsname = X509_get_issuer_name(xs);
            else
                return NULL;
            result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5);
            resdup = FALSE;
        }
        else if (strlen(var) > 4 && strcEQn(var, "SAN_", 4)) {
            result = ssl_var_lookup_ssl_cert_san(p, xs, var+4);
            resdup = FALSE;
        }
        else if (strcEQ(var, "A_SIG")) {
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
            nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->signature->algorithm));
    #else
            const ASN1_OBJECT *paobj;
            X509_ALGOR_get0(&paobj, NULL, NULL, X509_get0_tbs_sigalg(xs));
            nid = OBJ_obj2nid(paobj);
    #endif
            result = apr_pstrdup(p,
                                 (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
            resdup = FALSE;
        }
        else if (strcEQ(var, "A_KEY")) {
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
            nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->key->algor->algorithm));
    #else
            ASN1_OBJECT *paobj;
            X509_PUBKEY_get0_param(&paobj, NULL, 0, NULL, X509_get_X509_PUBKEY(xs));
            nid = OBJ_obj2nid(paobj);
    #endif
            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 (resdup)
            result = apr_pstrdup(p, result);
        return result;
    }
    
    /* In this table, .extract is non-zero if RDNs using the NID should be
     * extracted to for the SSL_{CLIENT,SERVER}_{I,S}_DN_* environment
     * variables. */
    static const struct {
        char *name;
        int   nid;
        int   extract;
    } ssl_var_lookup_ssl_cert_dn_rec[] = {
        { "C",     NID_countryName,            1 },
        { "ST",    NID_stateOrProvinceName,    1 }, /* officially    (RFC2156) */
        { "SP",    NID_stateOrProvinceName,    0 }, /* compatibility (SSLeay)  */
        { "L",     NID_localityName,           1 },
        { "O",     NID_organizationName,       1 },
        { "OU",    NID_organizationalUnitName, 1 },
        { "CN",    NID_commonName,             1 },
        { "T",     NID_title,                  1 },
        { "I",     NID_initials,               1 },
        { "G",     NID_givenName,              1 },
        { "S",     NID_surname,                1 },
        { "D",     NID_description,            1 },
    #ifdef NID_userId
        { "UID",   NID_userId,                 1 },
    #endif
        { "Email", NID_pkcs9_emailAddress,     1 },
        { NULL,    0,                          0 }
    };
    
    static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname,
                                            const char *var)
    {
        const char *ptr;
        char *result;
        X509_NAME_ENTRY *xsne;
        int i, j, n, idx = 0, raw = 0;
        apr_size_t varlen;
    
        ptr = ap_strrchr_c(var, '_');
        if (ptr && ptr > var && strcmp(ptr + 1, "RAW") == 0) {
            var = apr_pstrmemdup(p, var, ptr - var);
            raw = 1;
        }
        
        /* if an _N suffix is used, find the Nth attribute of given name */
        ptr = ap_strchr_c(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 < X509_NAME_entry_count(xsname); j++) {
                    xsne = X509_NAME_get_entry(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 = modssl_X509_NAME_ENTRY_to_string(p, xsne, raw);
                        break;
                    }
                }
                break;
            }
        }
        return result;
    }
    
    static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var)
    {
        int type;
        apr_size_t numlen;
        const char *onf = NULL;
        apr_array_header_t *entries;
    
        if (strcEQn(var, "Email_", 6)) {
            type = GEN_EMAIL;
            var += 6;
        }
        else if (strcEQn(var, "DNS_", 4)) {
            type = GEN_DNS;
            var += 4;
        }
        else if (strcEQn(var, "OTHER_", 6)) {
            type = GEN_OTHERNAME;
            var += 6;
            if (strEQn(var, "msUPN_", 6)) {
                var += 6;
                onf = "msUPN";
            }
            else if (strEQn(var, "dnsSRV_", 7)) {
                var += 7;
                onf = "id-on-dnsSRV";
            }
            else
               return NULL;
        }
        else
            return NULL;
    
        /* sanity check: number must be between 1 and 4 digits */
        numlen = strspn(var, "0123456789");
        if ((numlen < 1) || (numlen > 4) || (numlen != strlen(var)))
            return NULL;
    
        if (modssl_X509_getSAN(p, xs, type, onf, atoi(var), &entries))
            /* return the first entry from this 1-element array */
            return APR_ARRAY_IDX(entries, 0, char *);
        else
            return NULL;
    }
    
    static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm)
    {
        BIO* bio;
    
        if ((bio = BIO_new(BIO_s_mem())) == NULL)
            return NULL;
        ASN1_TIME_print(bio, tm);
    
        return modssl_bio_free_read(p, bio);
    }
    
    #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_TIME *tm)
    {
        apr_time_t then, now = apr_time_now();
        apr_time_exp_t exp = {0};
        long diff;
        unsigned char *dp;
    
        /* Fail if the time isn't a valid ASN.1 TIME; RFC3280 mandates
         * that the seconds digits are present even though ASN.1
         * doesn't. */
        if ((tm->type == V_ASN1_UTCTIME && tm->length < 11) ||
            (tm->type == V_ASN1_GENERALIZEDTIME && tm->length < 13) ||
            !ASN1_TIME_check(tm)) {
            return apr_pstrdup(p, "0");
        }
    
        if (tm->type == V_ASN1_UTCTIME) {
            exp.tm_year = DIGIT2NUM(tm->data);
            if (exp.tm_year <= 50) exp.tm_year += 100;
            dp = tm->data + 2;
        } else {
            exp.tm_year = DIGIT2NUM(tm->data) * 100 + DIGIT2NUM(tm->data + 2) - 1900;
            dp = tm->data + 4;
        }
    
        exp.tm_mon = DIGIT2NUM(dp) - 1;
        exp.tm_mday = DIGIT2NUM(dp + 2) + 1;
        exp.tm_hour = DIGIT2NUM(dp + 4);
        exp.tm_min = DIGIT2NUM(dp + 6);
        exp.tm_sec = DIGIT2NUM(dp + 8);
    
        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)
    {
        BIO *bio;
    
        if ((bio = BIO_new(BIO_s_mem())) == NULL)
            return NULL;
        i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs));
    
        return modssl_bio_free_read(p, bio);
    }
    
    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_rfc4523_cea(apr_pool_t *p, SSL *ssl)
    {
        char *result;
        X509 *xs;
    
        ASN1_INTEGER *serialNumber;
    
        if (!(xs = SSL_get_peer_certificate(ssl))) {
            return NULL;
        }
    
        result = NULL;
    
        serialNumber = X509_get_serialNumber(xs);
        if (serialNumber) {
            X509_NAME *issuer = X509_get_issuer_name(xs);
            if (issuer) {
                BIGNUM *bn = ASN1_INTEGER_to_BN(serialNumber, NULL);
                char *decimal = BN_bn2dec(bn);
                result = apr_pstrcat(p, "{ serialNumber ", decimal,
                        ", issuer rdnSequence:\"",
                        modssl_X509_NAME_to_string(p, issuer, 0), "\" }", NULL);
                OPENSSL_free(decimal);
                BN_free(bn);
            }
        }
    
        X509_free(xs);
        return result;
    }
    
    static char *ssl_var_lookup_ssl_cert_PEM(apr_pool_t *p, X509 *xs)
    {
        BIO *bio;
    
        if ((bio = BIO_new(BIO_s_mem())) == NULL)
            return NULL;
        PEM_write_bio_X509(bio, xs);
    
        return modssl_bio_free_read(p, bio);
    }
    
    static char *ssl_var_lookup_ssl_cert_verify(apr_pool_t *p, SSLConnRec *sslconn)
    {
        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 && 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 ? verr : X509_verify_cert_error_string(vrc));
    
        if (xs)
            X509_free(xs);
        return result;
    }
    
    static char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, SSLConnRec *sslconn, char *var)
    {
        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, "")) {
            MODSSL_SSL_CIPHER_CONST 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)
    {
        MODSSL_SSL_CIPHER_CONST 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)
    {
        if (strEQ(var, "INTERFACE")) {
            return apr_pstrdup(p, var_interface);
        }
        else if (strEQ(var, "LIBRARY_INTERFACE")) {
            return apr_pstrdup(p, var_library_interface);
        }
        else if (strEQ(var, "LIBRARY")) {
            return apr_pstrdup(p, var_library);
        }
        return NULL;
    }
    
    /* Add each RDN in 'xn' to the table 't' where the NID is present in
     * 'nids', using key prefix 'pfx'.  */
    static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
                           X509_NAME *xn, apr_pool_t *p)
    {
        X509_NAME_ENTRY *xsne;
        apr_hash_t *count;
        int i, nid;
    
        /* Hash of (int) NID -> (int *) counter to count each time an RDN
         * with the given NID has been seen. */
        count = apr_hash_make(p);
    
        /* For each RDN... */
        for (i = 0; i < X509_NAME_entry_count(xn); i++) {
             const char *tag;
             xsne = X509_NAME_get_entry(xn, i);
    
             /* Retrieve the nid, and check whether this is one of the nids
              * which are to be extracted. */
             nid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
    
             tag = apr_hash_get(nids, &nid, sizeof nid);
             if (tag) {
                 const char *key;
                 int *dup;
                 char *value;
    
                 /* Check whether a variable with this nid was already
                  * been used; if so, use the foo_N=bar syntax. */
                 dup = apr_hash_get(count, &nid, sizeof nid);
                 if (dup) {
                     key = apr_psprintf(p, "%s%s_%d", pfx, tag, ++(*dup));
                 }
                 else {
                     /* Otherwise, use the plain foo=bar syntax. */
                     dup = apr_pcalloc(p, sizeof *dup);
                     apr_hash_set(count, &nid, sizeof nid, dup);
                     key = apr_pstrcat(p, pfx, tag, NULL);
                 }
                 value = modssl_X509_NAME_ENTRY_to_string(p, xsne, 0);
                 apr_table_setn(t, key, value);
             }
        }
    }
    
    void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p)
    {
        apr_hash_t *nids;
        unsigned n;
        X509 *xs;
    
        /* Build up a hash table of (int *)NID->(char *)short-name for all
         * the tags which are to be extracted: */
        nids = apr_hash_make(p);
        for (n = 0; ssl_var_lookup_ssl_cert_dn_rec[n].name; n++) {
            if (ssl_var_lookup_ssl_cert_dn_rec[n].extract) {
                apr_hash_set(nids, &ssl_var_lookup_ssl_cert_dn_rec[n].nid,
                             sizeof(ssl_var_lookup_ssl_cert_dn_rec[0].nid),
                             ssl_var_lookup_ssl_cert_dn_rec[n].name);
            }
        }
    
        /* Extract the server cert DNS -- note that the refcount does NOT
         * increase: */
        xs = SSL_get_certificate(ssl);
        if (xs) {
            extract_dn(t, nids, "SSL_SERVER_S_DN_", X509_get_subject_name(xs), p);
            extract_dn(t, nids, "SSL_SERVER_I_DN_", X509_get_issuer_name(xs), p);
        }
    
        /* Extract the client cert DNs -- note that the refcount DOES
         * increase: */
        xs = SSL_get_peer_certificate(ssl);
        if (xs) {
            extract_dn(t, nids, "SSL_CLIENT_S_DN_", X509_get_subject_name(xs), p);
            extract_dn(t, nids, "SSL_CLIENT_I_DN_", X509_get_issuer_name(xs), p);
            X509_free(xs);
        }
    }
    
    static void extract_san_array(apr_table_t *t, const char *pfx,
                                  apr_array_header_t *entries, apr_pool_t *p)
    {
        int i;
    
        for (i = 0; i < entries->nelts; i++) {
            const char *key = apr_psprintf(p, "%s_%d", pfx, i);
            apr_table_setn(t, key, APR_ARRAY_IDX(entries, i, const char *));
        }
    }
    
    void modssl_var_extract_san_entries(apr_table_t *t, SSL *ssl, apr_pool_t *p)
    {
        X509 *xs;
        apr_array_header_t *entries;
    
        /* subjectAltName entries of the server certificate */
        xs = SSL_get_certificate(ssl);
        if (xs) {
            if (modssl_X509_getSAN(p, xs, GEN_EMAIL, NULL, -1, &entries)) {
                extract_san_array(t, "SSL_SERVER_SAN_Email", entries, p);
            }
            if (modssl_X509_getSAN(p, xs, GEN_DNS, NULL, -1, &entries)) {
                extract_san_array(t, "SSL_SERVER_SAN_DNS", entries, p);
            }
            if (modssl_X509_getSAN(p, xs, GEN_OTHERNAME, "id-on-dnsSRV", -1,
                                   &entries)) {
                extract_san_array(t, "SSL_SERVER_SAN_OTHER_dnsSRV", entries, p);
            }
            /* no need to free xs (refcount does not increase) */
        }
    
        /* subjectAltName entries of the client certificate */
        xs = SSL_get_peer_certificate(ssl);
        if (xs) {
            if (modssl_X509_getSAN(p, xs, GEN_EMAIL, NULL, -1, &entries)) {
                extract_san_array(t, "SSL_CLIENT_SAN_Email", entries, p);
            }
            if (modssl_X509_getSAN(p, xs, GEN_DNS, NULL, -1, &entries)) {
                extract_san_array(t, "SSL_CLIENT_SAN_DNS", entries, p);
            }
            if (modssl_X509_getSAN(p, xs, GEN_OTHERNAME, "msUPN", -1, &entries)) {
                extract_san_array(t, "SSL_CLIENT_SAN_OTHER_msUPN", entries, p);
            }
            X509_free(xs);
        }
    }
    
    /* For an extension type which OpenSSL does not recognize, attempt to
     * parse the extension type as a primitive string.  This will fail for
     * any structured extension type per the docs.  Returns non-zero on
     * success and writes the string to the given bio. */
    static int dump_extn_value(BIO *bio, ASN1_OCTET_STRING *str)
    {
        const unsigned char *pp = str->data;
        ASN1_STRING *ret = ASN1_STRING_new();
        int rv = 0;
    
        /* This allows UTF8String, IA5String, VisibleString, or BMPString;
         * conversion to UTF-8 is forced. */
        if (d2i_DISPLAYTEXT(&ret, &pp, str->length)) {
            ASN1_STRING_print_ex(bio, ret, ASN1_STRFLGS_UTF8_CONVERT);
            rv = 1;
        }
    
        ASN1_STRING_free(ret);
        return rv;
    }
    
    apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer,
                                     const char *extension)
    {
        SSLConnRec *sslconn = ssl_get_effective_config(c);
        SSL *ssl = NULL;
        apr_array_header_t *array = NULL;
        X509 *xs = NULL;
        ASN1_OBJECT *oid = NULL;
        int count = 0, j;
    
        if (!sslconn || !sslconn->ssl || !extension) {
            return NULL;
        }
        ssl = sslconn->ssl;
    
        /* We accept the "extension" string to be converted as
         * a long name (nsComment), short name (DN) or
         * numeric OID (1.2.3.4).
         */
        oid = OBJ_txt2obj(extension, 0);
        if (!oid) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01970)
                          "could not parse OID '%s'", extension);
            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);
        /* Create an array large enough to accommodate every extension. This is
         * likely overkill, but safe.
         */
        array = apr_array_make(p, count, sizeof(char *));
        for (j = 0; j < count; j++) {
            X509_EXTENSION *ext = X509_get_ext(xs, j);
    
            if (OBJ_cmp(X509_EXTENSION_get_object(ext), oid) == 0) {
                BIO *bio = BIO_new(BIO_s_mem());
    
                /* We want to obtain a string representation of the extensions
                 * value and add it to the array we're building.
                 * X509V3_EXT_print() doesn't know about all the possible
                 * data types, but the value is stored as an ASN1_OCTET_STRING
                 * allowing us a fallback in case of X509V3_EXT_print
                 * not knowing how to handle the data.
                 */
                if (X509V3_EXT_print(bio, ext, 0, 0) == 1 ||
                    dump_extn_value(bio, X509_EXTENSION_get_data(ext)) == 1) {
                    BUF_MEM *buf;
                    char **ptr = apr_array_push(array);
                    BIO_get_mem_ptr(bio, &buf);
                    *ptr = apr_pstrmemdup(p, buf->data, buf->length);
                } else {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01971)
                                  "Found an extension '%s', but failed to "
                                  "create a string from it", extension);
                }
                BIO_vfree(bio);
            }
        }
    
        if (array->nelts == 0)
            array = NULL;
    
        if (peer) {
            /* only SSL_get_peer_certificate raises the refcount */
            X509_free(xs);
        }
    
        ASN1_OBJECT_free(oid);
        ERR_clear_error();
        return array;
    }
    
    static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl)
    {
        char *result = "NULL";
    #ifndef OPENSSL_NO_COMP
        SSL_SESSION *pSession = SSL_get_session(ssl);
    
        if (pSession) {
    #ifdef OPENSSL_NO_SSL_INTERN
            switch (SSL_SESSION_get_compress_id(pSession)) {
    #else
            switch (pSession->compress_meth) {
    #endif
            case 0:
                /* default "NULL" already set */
                break;
    
                /* Defined by RFC 3749, deflate is coded by "1" */
            case 1:
                result = "DEFLATE";
                break;
    
                /* IANA assigned compression number for LZS */
            case 0x40:
                result = "LZS";
                break;
    
            default:
                result = "UNKNOWN";
                break;
            }
        }
    #endif
        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)
    {
        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 = ssl_get_effective_config(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) {
            result = *result ? ap_escape_logitem(r->pool, 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) {
            result = *result ? ap_escape_logitem(r->pool, result) : NULL;
        }
        return result;
    }
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_util_ssl.c�������������������������������������������������������������0000664�0001751�0001751�00000044763�14635307011�017774� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 app_data2_idx = -1;
    
    void modssl_init_app_data2_idx(void)
    {
        int i;
    
        if (app_data2_idx > -1) {
            return;
        }
    
        /* we _do_ need to call this twice */
        for (i = 0; i <= 1; i++) {
            app_data2_idx =
                SSL_get_ex_new_index(0,
                                     "Second Application Data for SSL",
                                     NULL, NULL, NULL);
        }
    }
    
    void *modssl_get_app_data2(SSL *ssl)
    {
        return (void *)SSL_get_ex_data(ssl, app_data2_idx);
    }
    
    void modssl_set_app_data2(SSL *ssl, void *arg)
    {
        SSL_set_ex_data(ssl, app_data2_idx, (char *)arg);
        return;
    }
    
    /*  _________________________________________________________________
    **
    **  High-Level Private Key Loading
    **  _________________________________________________________________
    */
    
    EVP_PKEY *modssl_read_privatekey(const char *filename, pem_password_cb *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 = PEM_read_bio_PrivateKey(bioS, NULL, 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);
            }
        }
        return rc;
    }
    
    /*  _________________________________________________________________
    **
    **  Smart shutdown
    **  _________________________________________________________________
    */
    
    int modssl_smart_shutdown(SSL *ssl)
    {
        int i;
        int rc;
        int flush;
    
        /*
         * Repeat the calls, because SSL_shutdown internally dispatches through a
         * little state machine. Usually only one or two iterations 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;
        flush = !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN);
        for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) {
            rc = SSL_shutdown(ssl);
            if (rc >= 0 && flush && (SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
                /* Once the close notify is sent through the output filters,
                 * ensure it is flushed through the socket.
                 */
                if (BIO_flush(SSL_get_wbio(ssl)) <= 0) {
                    rc = -1;
                    break;
                }
                flush = 0;
            }
            if (rc != 0)
                break;
        }
        return rc;
    }
    
    /*  _________________________________________________________________
    **
    **  Certificate Checks
    **  _________________________________________________________________
    */
    
    /* retrieve basic constraints ingredients */
    BOOL modssl_X509_getBC(X509 *cert, int *ca, int *pathlen)
    {
        BASIC_CONSTRAINTS *bc;
        BIGNUM *bn = NULL;
        char *cp;
    
        bc = X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
        if (bc == NULL)
            return FALSE;
        *ca = bc->ca;
        *pathlen = -1 /* unlimited */;
        if (bc->pathlen != NULL) {
            if ((bn = ASN1_INTEGER_to_BN(bc->pathlen, NULL)) == NULL) {
                BASIC_CONSTRAINTS_free(bc);
                return FALSE;
            }
            if ((cp = BN_bn2dec(bn)) == NULL) {
                BN_free(bn);
                BASIC_CONSTRAINTS_free(bc);
                return FALSE;
            }
            *pathlen = atoi(cp);
            OPENSSL_free(cp);
            BN_free(bn);
        }
        BASIC_CONSTRAINTS_free(bc);
        return TRUE;
    }
    
    char *modssl_bio_free_read(apr_pool_t *p, BIO *bio)
    {
        int len = BIO_pending(bio);
        char *result = NULL;
    
        if (len > 0) {
            result = apr_palloc(p, len+1);
            len = BIO_read(bio, result, len);
            result[len] = NUL;
        }
        BIO_free(bio);
        return result;
    }
    
    /* Convert ASN.1 string to a pool-allocated char * string, escaping
     * control characters.  If raw is zero, convert to UTF-8, otherwise
     * unchanged from the character set. */
    static char *asn1_string_convert(apr_pool_t *p, ASN1_STRING *asn1str, int raw)
    {
        BIO *bio;
        int flags = ASN1_STRFLGS_ESC_CTRL;
    
        if ((bio = BIO_new(BIO_s_mem())) == NULL)
            return NULL;
    
        if (!raw) flags |= ASN1_STRFLGS_UTF8_CONVERT;
        
        ASN1_STRING_print_ex(bio, asn1str, flags);
    
        return modssl_bio_free_read(p, bio);
    }
    
    #define asn1_string_to_utf8(p, a) asn1_string_convert(p, a, 0)
    
    /* convert a NAME_ENTRY to UTF8 string */
    char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne,
                                           int raw)
    {
        char *result = asn1_string_convert(p, X509_NAME_ENTRY_get_data(xsne), raw);
        ap_xlate_proto_from_ascii(result, len);
        return result;
    }
    
    /*
     * convert an X509_NAME to an RFC 2253 formatted string, optionally truncated
     * to maxlen characters (specify a maxlen of 0 for no length limit)
     */
    char *modssl_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, int maxlen)
    {
        char *result = NULL;
        BIO *bio;
        int len;
    
        if ((bio = BIO_new(BIO_s_mem())) == NULL)
            return NULL;
        X509_NAME_print_ex(bio, dn, 0, XN_FLAG_RFC2253);
        len = BIO_pending(bio);
        if (len > 0) {
            result = apr_palloc(p, (maxlen > 0) ? maxlen+1 : len+1);
            if (maxlen > 0 && maxlen < len) {
                len = BIO_read(bio, result, maxlen);
                if (maxlen > 2) {
                    /* insert trailing ellipsis if there's enough space */
                    apr_snprintf(result + maxlen - 3, 4, "...");
                }
            } else {
                len = BIO_read(bio, result, len);
            }
            result[len] = NUL;
        }
        BIO_free(bio);
    
        return result;
    }
    
    static void parse_otherName_value(apr_pool_t *p, ASN1_TYPE *value,
                                      const char *onf, apr_array_header_t **entries)
    {
        const char *str;
        int nid = onf ? OBJ_txt2nid(onf) : NID_undef;
    
        if (!value || (nid == NID_undef) || !*entries)
           return;
    
        /* 
         * Currently supported otherName forms (values for "onf"):
         * "msUPN" (1.3.6.1.4.1.311.20.2.3): Microsoft User Principal Name
         * "id-on-dnsSRV" (1.3.6.1.5.5.7.8.7): SRVName, as specified in RFC 4985
         */
        if ((nid == NID_ms_upn) && (value->type == V_ASN1_UTF8STRING) &&
            (str = asn1_string_to_utf8(p, value->value.utf8string))) {
            APR_ARRAY_PUSH(*entries, const char *) = str;
        } else if (strEQ(onf, "id-on-dnsSRV") &&
                   (value->type == V_ASN1_IA5STRING) &&
                   (str = asn1_string_to_utf8(p, value->value.ia5string))) {
            APR_ARRAY_PUSH(*entries, const char *) = str;
        }
    }
    
    /* 
     * Return an array of subjectAltName entries of type "type". If idx is -1,
     * return all entries of the given type, otherwise return an array consisting
     * of the n-th occurrence of that type only. Currently supported types:
     * GEN_EMAIL (rfc822Name)
     * GEN_DNS (dNSName)
     * GEN_OTHERNAME (requires the otherName form ["onf"] argument to be supplied,
     *                see parse_otherName_value for the currently supported forms)
     */
    BOOL modssl_X509_getSAN(apr_pool_t *p, X509 *x509, int type, const char *onf,
                            int idx, apr_array_header_t **entries)
    {
        STACK_OF(GENERAL_NAME) *names;
        int nid = onf ? OBJ_txt2nid(onf) : NID_undef;
    
        if (!x509 || (type < GEN_OTHERNAME) ||
            ((type == GEN_OTHERNAME) && (nid == NID_undef)) ||
            (type > GEN_RID) || (idx < -1) ||
            !(*entries = apr_array_make(p, 0, sizeof(char *)))) {
            *entries = NULL;
            return FALSE;
        }
    
        if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL))) {
            int i, n = 0;
            GENERAL_NAME *name;
            const char *utf8str;
    
            for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
                name = sk_GENERAL_NAME_value(names, i);
    
                if (name->type != type)
                    continue;
    
                switch (type) {
                case GEN_EMAIL:
                case GEN_DNS:
                    if (((idx == -1) || (n == idx)) &&
                        (utf8str = asn1_string_to_utf8(p, name->d.ia5))) {
                        APR_ARRAY_PUSH(*entries, const char *) = utf8str;
                    }
                    n++;
                    break;
                case GEN_OTHERNAME:
                    if (OBJ_obj2nid(name->d.otherName->type_id) == nid) {
                        if (((idx == -1) || (n == idx))) {
                            parse_otherName_value(p, name->d.otherName->value,
                                                  onf, entries);
                        }
                        n++;
                    }
                    break;
                default:
                    /*
                     * Not implemented right now:
                     * GEN_X400 (x400Address)
                     * GEN_DIRNAME (directoryName)
                     * GEN_EDIPARTY (ediPartyName)
                     * GEN_URI (uniformResourceIdentifier)
                     * GEN_IPADD (iPAddress)
                     * GEN_RID (registeredID)
                     */
                    break;
                }
    
                if ((idx != -1) && (n > idx))
                   break;
            }
    
            sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
        }
    
        return apr_is_empty_array(*entries) ? FALSE : TRUE;
    }
    
    /* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */
    static BOOL getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)
    {
        X509_NAME *subj;
        int i = -1;
    
        /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
        if (!x509 ||
            (modssl_X509_getSAN(p, x509, GEN_DNS, NULL, -1, ids) == FALSE && !*ids)) {
            *ids = NULL;
            return FALSE;
        }
    
        /* Second, the CN-IDs (commonName attributes in the subject DN) */
        subj = X509_get_subject_name(x509);
        while ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, i)) != -1) {
            APR_ARRAY_PUSH(*ids, const char *) = 
                modssl_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i), 0);
        }
    
        return apr_is_empty_array(*ids) ? FALSE : TRUE;
    }
    
    /* 
     * Check if a certificate matches for a particular name, by iterating over its
     * DNS-IDs and CN-IDs (RFC 6125), optionally with basic wildcard matching.
     * If server_rec is non-NULL, some (debug/trace) logging is enabled.
     */
    BOOL modssl_X509_match_name(apr_pool_t *p, X509 *x509, const char *name,
                                BOOL allow_wildcard, server_rec *s)
    {
        BOOL matched = FALSE;
        apr_array_header_t *ids;
    
        /*
         * At some day in the future, this might be replaced with X509_check_host()
         * (available in OpenSSL 1.0.2 and later), but two points should be noted:
         * 1) wildcard matching in X509_check_host() might yield different
         *    results (by default, it supports a broader set of patterns, e.g.
         *    wildcards in non-initial positions);
         * 2) we lose the option of logging each DNS- and CN-ID (until a match
         *    is found).
         */
    
        if (getIDs(p, x509, &ids)) {
            const char *cp;
            int i;
            char **id = (char **)ids->elts;
            BOOL is_wildcard;
    
            for (i = 0; i < ids->nelts; i++) {
                if (!id[i])
                    continue;
    
                /*
                 * Determine if it is a wildcard ID - we're restrictive
                 * in the sense that we require the wildcard character to be
                 * THE left-most label (i.e., the ID must start with "*.")
                 */
                is_wildcard = (*id[i] == '*' && *(id[i]+1) == '.') ? TRUE : FALSE;
    
                /*
                 * If the ID includes a wildcard character (and the caller is
                 * allowing wildcards), check if it matches for the left-most
                 * DNS label - i.e., the wildcard character is not allowed
                 * to match a dot. Otherwise, try a simple string compare.
                 */
                if ((allow_wildcard == TRUE && is_wildcard == TRUE &&
                     (cp = ap_strchr_c(name, '.')) && !strcasecmp(id[i]+1, cp)) ||
                    !strcasecmp(id[i], name)) {
                    matched = TRUE;
                }
    
                if (s) {
                    ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
                                 "[%s] modssl_X509_match_name: expecting name '%s', "
                                 "%smatched by ID '%s'",
                                 (mySrvConfig(s))->vhost_id, name,
                                 matched == TRUE ? "" : "NOT ", id[i]);
                }
    
                if (matched == TRUE) {
                    break;
                }
            }
    
        }
    
        if (s) {
            ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, p, s, x509,
                           APLOGNO(02412) "[%s] Cert %s for name '%s'",
                           (mySrvConfig(s))->vhost_id,
                           matched == TRUE ? "matches" : "does not match",
                           name);
        }
    
        return matched;
    }
    
    /*  _________________________________________________________________
    **
    **  Custom (EC)DH parameter support
    **  _________________________________________________________________
    */
    
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
    DH *modssl_dh_from_file(const char *file)
    {
        DH *dh;
        BIO *bio;
    
        if ((bio = BIO_new_file(file, "r")) == NULL)
            return NULL;
        dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
        BIO_free(bio);
    
        return dh;
    }
    #else
    EVP_PKEY *modssl_dh_pkey_from_file(const char *file)
    {
        EVP_PKEY *pkey;
        BIO *bio;
    
        if ((bio = BIO_new_file(file, "r")) == NULL)
            return NULL;
        pkey = PEM_read_bio_Parameters(bio, NULL);
        BIO_free(bio);
    
        return pkey;
    }
    #endif
    
    #ifdef HAVE_ECC
    EC_GROUP *modssl_ec_group_from_file(const char *file)
    {
        EC_GROUP *group;
        BIO *bio;
    
        if ((bio = BIO_new_file(file, "r")) == NULL)
            return NULL;
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
        group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
    #else
        group = PEM_ASN1_read_bio((void *)d2i_ECPKParameters,
                                  PEM_STRING_ECPARAMETERS, bio,
                                  NULL, NULL, NULL);
    #endif
        BIO_free(bio);
    
        return group;
    }
    #endif
    
    /*  _________________________________________________________________
    **
    **  Session Stuff
    **  _________________________________________________________________
    */
    
    char *modssl_SSL_SESSION_id2sz(IDCONST unsigned char *id, int idlen,
                                   char *str, int strsize)
    {
        if (idlen > SSL_MAX_SSL_SESSION_ID_LENGTH)
            idlen = SSL_MAX_SSL_SESSION_ID_LENGTH;
            
        /* We must ensure not to process more than what would fit in the
         * destination buffer, including terminating NULL */
        if (idlen > (strsize-1) / 2)
            idlen = (strsize-1) / 2;
    
        ap_bin2hex(id, idlen, str);
    
        return str;
    }
    
    /*  _________________________________________________________________
    **
    **  Certificate/Key Stuff
    **  _________________________________________________________________
    */
    
    apr_status_t modssl_read_cert(apr_pool_t *p, 
                                  const char *cert_pem, const char *key_pem,
                                  pem_password_cb *cb, void *ud,
                                  X509 **pcert, EVP_PKEY **pkey)
    {
        BIO *in;
        X509 *x = NULL;
        EVP_PKEY *key = NULL;
        apr_status_t rv = APR_SUCCESS;
    
        in = BIO_new_mem_buf(cert_pem, -1);
        if (in == NULL) {
            rv = APR_ENOMEM;
            goto cleanup;
        }
        
        x = PEM_read_bio_X509(in, NULL, cb, ud);
        if (x == NULL) {
            rv = APR_ENOENT;
            goto cleanup;
        }
        
        BIO_free(in);
        in = BIO_new_mem_buf(key_pem? key_pem : cert_pem, -1);
        if (in == NULL) {
            rv = APR_ENOMEM;
            goto cleanup;
        }
        key = PEM_read_bio_PrivateKey(in, NULL, cb, ud);
        if (key == NULL) {
            rv = APR_ENOENT;
            goto cleanup;
        }
        
    cleanup:
        if (rv == APR_SUCCESS) {
            *pcert = x;
            *pkey = key;
        }
        else {
            *pcert = NULL;
            *pkey = NULL;
            if (x) X509_free(x);
            if (key) EVP_PKEY_free(key);
        }
        if (in != NULL) BIO_free(in);
        return rv;
    }
    
    apr_status_t modssl_cert_get_pem(apr_pool_t *p,
                                     X509 *cert1, X509 *cert2,
                                     const char **ppem)
    {
        apr_status_t rv = APR_ENOMEM;
        BIO *bio;
    
        if ((bio = BIO_new(BIO_s_mem())) == NULL) goto cleanup;
        if (PEM_write_bio_X509(bio, cert1) != 1) goto cleanup;
        if (cert2 && PEM_write_bio_X509(bio, cert2) != 1) goto cleanup;
        rv = APR_SUCCESS;
    
    cleanup:
        if (rv != APR_SUCCESS) {
            *ppem = NULL;
            if (bio) BIO_free(bio);
        }
        else {
            *ppem = modssl_bio_free_read(p, bio);
        }
        return rv;
    }
    
    void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state)
    {
    #ifdef SSL_OP_NO_RENEGOTIATION
        switch (state) {
        case RENEG_ALLOW:
            SSL_clear_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
            break;
        default:
            SSL_set_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
            break;
        }
    #else
        sslconn->reneg_state = state;
    #endif
    }
    �������������httpd-2.4.64/modules/ssl/ssl_util_ocsp.c������������������������������������������������������������0000664�0001751�0001751�00000032626�14526116756�020147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 implements an OCSP client including a toy HTTP/1.0
     * client.  Once httpd depends on a real HTTP client library, most of
     * this can be thrown away. */
    
    #include "ssl_private.h"
    
    #ifndef OPENSSL_NO_OCSP
    
    #include "apr_buckets.h"
    #include "apr_uri.h"
    
    /* Serialize an OCSP request which will be sent to the responder at
     * given URI to a memory BIO object, which is returned. */
    static BIO *serialize_request(OCSP_REQUEST *req, const apr_uri_t *uri,
                                  const apr_uri_t *proxy_uri)
    {
        BIO *bio;
        int len;
    
        len = i2d_OCSP_REQUEST(req, NULL);
    
        bio = BIO_new(BIO_s_mem());
    
        BIO_printf(bio, "POST ");
        /* Use full URL instead of URI in case of a request through a proxy */
        if (proxy_uri) {
            BIO_printf(bio, "http://%s:%d",
                       uri->hostname, uri->port);
        }
        BIO_printf(bio, "%s%s%s HTTP/1.0\r\n"
                   "Host: %s:%d\r\n"
                   "Content-Type: application/ocsp-request\r\n"
                   "Connection: close\r\n"
                   "Content-Length: %d\r\n"
                   "\r\n",
                   uri->path ? uri->path : "/",
                   uri->query ? "?" : "", uri->query ? uri->query : "",
                   uri->hostname, uri->port, len);
    
        if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
            BIO_free(bio);
            return NULL;
        }
    
        return bio;
    }
    
    /* Send the OCSP request serialized into BIO 'request' to the
     * responder at given server given by URI.  Returns socket object or
     * NULL on error. */
    static apr_socket_t *send_request(BIO *request, const apr_uri_t *uri,
                                      apr_interval_time_t timeout,
                                      conn_rec *c, apr_pool_t *p,
                                      const apr_uri_t *proxy_uri)
    {
        apr_status_t rv;
        apr_sockaddr_t *sa;
        apr_socket_t *sd;
        char buf[HUGE_STRING_LEN];
        int len;
        const apr_uri_t *next_hop_uri;
    
        if (proxy_uri) {
            next_hop_uri = proxy_uri;
        }
        else {
            next_hop_uri = uri;
        }
    
        rv = apr_sockaddr_info_get(&sa, next_hop_uri->hostname, APR_UNSPEC,
                                   next_hop_uri->port, 0, p);
        if (rv) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01972)
                          "could not resolve address of %s %s",
                          proxy_uri ? "proxy" : "OCSP responder",
                          next_hop_uri->hostinfo);
            return NULL;
        }
    
        /* establish a connection to the OCSP responder */
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01973)
                      "connecting to %s '%s'",
                      proxy_uri ? "proxy" : "OCSP responder",
                      uri->hostinfo);
    
        /* Cycle through address until a connect() succeeds. */
        for (; sa; sa = sa->next) {
            rv = apr_socket_create(&sd, sa->family, SOCK_STREAM, APR_PROTO_TCP, p);
            if (rv == APR_SUCCESS) {
                apr_socket_timeout_set(sd, timeout);
    
                rv = apr_socket_connect(sd, sa);
                if (rv == APR_SUCCESS) {
                    break;
                }
                apr_socket_close(sd);
            }
        }
    
        if (sa == NULL) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01974)
                          "could not connect to %s '%s'",
                          proxy_uri ? "proxy" : "OCSP responder",
                          next_hop_uri->hostinfo);
            return NULL;
        }
    
        /* send the request and get a response */
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01975)
                     "sending request to OCSP responder");
    
        while ((len = BIO_read(request, buf, sizeof buf)) > 0) {
            char *wbuf = buf;
            apr_size_t remain = len;
    
            do {
                apr_size_t wlen = remain;
    
                rv = apr_socket_send(sd, wbuf, &wlen);
                wbuf += remain;
                remain -= wlen;
            } while (rv == APR_SUCCESS && remain > 0);
    
            if (rv) {
                apr_socket_close(sd);
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01976)
                              "failed to send request to OCSP responder '%s'",
                              uri->hostinfo);
                return NULL;
            }
        }
    
        return sd;
    }
    
    /* Return a pool-allocated NUL-terminated line, with CRLF stripped,
     * read from brigade 'bbin' using 'bbout' as temporary storage. */
    static char *get_line(apr_bucket_brigade *bbout, apr_bucket_brigade *bbin,
                          conn_rec *c, apr_pool_t *p)
    {
        apr_status_t rv;
        apr_size_t len;
        char *line;
    
        apr_brigade_cleanup(bbout);
    
        rv = apr_brigade_split_line(bbout, bbin, APR_BLOCK_READ, 8192);
        if (rv) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01977)
                          "failed reading line from OCSP server");
            return NULL;
        }
    
        rv = apr_brigade_pflatten(bbout, &line, &len, p);
        if (rv) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01978)
                          "failed reading line from OCSP server");
            return NULL;
        }
    
        if (len == 0) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02321)
                          "empty response from OCSP server");
            return NULL;
        }
    
        if (line[len-1] != APR_ASCII_LF) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01979)
                          "response header line too long from OCSP server");
            return NULL;
        }
    
        line[len-1] = '\0';
        if (len > 1 && line[len-2] == APR_ASCII_CR) {
            line[len-2] = '\0';
        }
    
        return line;
    }
    
    /* Maximum values to prevent eating RAM forever. */
    #define MAX_HEADERS (256)
    #define MAX_CONTENT (2048 * 1024)
    
    /* Read the OCSP response from the socket 'sd', using temporary memory
     * BIO 'bio', and return the decoded OCSP response object, or NULL on
     * error. */
    static OCSP_RESPONSE *read_response(apr_socket_t *sd, BIO *bio, conn_rec *c,
                                        apr_pool_t *p)
    {
        apr_bucket_brigade *bb, *tmpbb;
        OCSP_RESPONSE *response;
        char *line;
        apr_size_t count;
        apr_int64_t code;
    
        /* Using brigades for response parsing is much simpler than using
         * apr_socket_* directly. */
        bb = apr_brigade_create(p, c->bucket_alloc);
        tmpbb = apr_brigade_create(p, c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_socket_create(sd, c->bucket_alloc));
    
        line = get_line(tmpbb, bb, c, p);
        if (!line || strncmp(line, "HTTP/", 5)
            || (line = ap_strchr(line, ' ')) == NULL
            || (code = apr_atoi64(++line)) < 200 || code > 299) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01980)
                          "bad response from OCSP server: %s",
                          line ? line : "(none)");
            return NULL;
        }
    
        /* Read till end of headers; don't have to even bother parsing the
         * Content-Length since the server is obliged to close the
         * connection after the response anyway for HTTP/1.0. */
        count = 0;
        while ((line = get_line(tmpbb, bb, c, p)) != NULL && line[0]
               && ++count < MAX_HEADERS) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01981)
                          "OCSP response header: %s", line);
        }
    
        if (count == MAX_HEADERS) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01982)
                          "could not read response headers from OCSP server, "
                          "exceeded maximum count (%u)", MAX_HEADERS);
            return NULL;
        }
        else if (!line) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01983)
                          "could not read response header from OCSP server");
            return NULL;
        }
    
        /* Read the response body into the memory BIO. */
        count = 0;
        while (!APR_BRIGADE_EMPTY(bb)) {
            const char *data;
            apr_size_t len;
            apr_status_t rv;
            apr_bucket *e = APR_BRIGADE_FIRST(bb);
    
            rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
            if (rv == APR_EOF) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01984)
                              "OCSP response: got EOF");
                break;
            }
            if (rv != APR_SUCCESS) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01985)
                              "error reading response from OCSP server");
                return NULL;
            }
            if (len == 0) {
                /* Ignore zero-length buckets (possible side-effect of
                 * line splitting). */
                apr_bucket_delete(e);
                continue;
            }
            count += len;
            if (count > MAX_CONTENT) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01986)
                              "OCSP response size exceeds %u byte limit",
                              MAX_CONTENT);
                return NULL;
            }
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01987)
                          "OCSP response: got %" APR_SIZE_T_FMT
                          " bytes, %" APR_SIZE_T_FMT " total", len, count);
    
            BIO_write(bio, data, (int)len);
            apr_bucket_delete(e);
        }
    
        apr_brigade_destroy(bb);
        apr_brigade_destroy(tmpbb);
    
        /* Finally decode the OCSP response from what's stored in the
         * bio. */
        response = d2i_OCSP_RESPONSE_bio(bio, NULL);
        if (response == NULL) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01988)
                          "failed to decode OCSP response data");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, mySrvFromConn(c));
        }
    
        return response;
    }
    
    OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri,
                                                apr_interval_time_t timeout,
                                                OCSP_REQUEST *request,
                                                conn_rec *c, apr_pool_t *p)
    {
        OCSP_RESPONSE *response = NULL;
        apr_socket_t *sd;
        BIO *bio;
        const apr_uri_t *proxy_uri;
    
        proxy_uri = (mySrvConfigFromConn(c))->server->proxy_uri;
        bio = serialize_request(request, uri, proxy_uri);
        if (bio == NULL) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01989)
                          "could not serialize OCSP request");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, mySrvFromConn(c));
            return NULL;
        }
    
        sd = send_request(bio, uri, timeout, c, p, proxy_uri);
        if (sd == NULL) {
            /* Errors already logged. */
            BIO_free(bio);
            return NULL;
        }
    
        /* Clear the BIO contents, ready for the response. */
        (void)BIO_reset(bio);
    
        response = read_response(sd, bio, c, p);
    
        apr_socket_close(sd);
        BIO_free(bio);
    
        return response;
    }
    
    /*  _________________________________________________________________
    **
    **  OCSP other certificate support
    **  _________________________________________________________________
    */
    
    /*
     * Read a file that contains certificates in PEM format and
     * return as a STACK.
     */
    
    static STACK_OF(X509) *modssl_read_ocsp_certificates(const char *file)
    {
        BIO *bio;
        X509 *x509;
        unsigned long err;
        STACK_OF(X509) *other_certs = NULL;
    
        if ((bio = BIO_new(BIO_s_file())) == NULL)
            return NULL;
        if (BIO_read_filename(bio, file) <= 0) {
            BIO_free(bio);
            return NULL;
        }
    
        /* create new extra chain by loading the certs */
        ERR_clear_error();
        while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
            if (!other_certs) {
                    other_certs = sk_X509_new_null();
                    if (!other_certs) {
                            X509_free(x509);
                            BIO_free(bio);
                            return NULL;
                    }
            }
                    
            if (!sk_X509_push(other_certs, x509)) {
                X509_free(x509);
                sk_X509_pop_free(other_certs, X509_free);
                BIO_free(bio);
                return NULL;
            }
        }
        /* 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);
                sk_X509_pop_free(other_certs, X509_free);
                return NULL;
            }
            while (ERR_get_error() > 0) ;
        }
        BIO_free(bio);
        return other_certs;
    }
    
    void ssl_init_ocsp_certificates(server_rec *s, modssl_ctx_t *mctx)
    {
        /*
         * Configure Trusted OCSP certificates.
         */
    
        if (!mctx->ocsp_certs_file) {
            return;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     "Configuring Trusted OCSP certificates");
    
        mctx->ocsp_certs = modssl_read_ocsp_certificates(mctx->ocsp_certs_file);
    
        if (!mctx->ocsp_certs) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                    "Unable to configure OCSP Trusted Certificates");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
            ssl_die(s);
        }
        mctx->ocsp_verify_flags |= OCSP_TRUSTOTHER;
    }
    
    #endif /* HAVE_OCSP */
    ����������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_scache.c���������������������������������������������������������������0000664�0001751�0001751�00000016462�13701124562�017360� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
    **  _________________________________________________________________
    */
    
    apr_status_t ssl_scache_init(server_rec *s, apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
        apr_status_t rv;
        struct ap_socache_hints hints;
    
        /* The very first invocation of this function will be the
         * post_config invocation during server startup; do nothing for
         * this first (and only the first) time through, since the pool
         * will be immediately cleared anyway.  For every subsequent
         * invocation, initialize the configured cache. */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
            return APR_SUCCESS;
    
    #ifdef HAVE_OCSP_STAPLING
        if (mc->stapling_cache) {
            memset(&hints, 0, sizeof hints);
            hints.avg_obj_size = 1500;
            hints.avg_id_len = 20;
            hints.expiry_interval = 300;
    
            rv = mc->stapling_cache->init(mc->stapling_cache_context,
                                         "mod_ssl-staple", &hints, s, p);
            if (rv) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01872)
                             "Could not initialize stapling cache. Exiting.");
                return ssl_die(s);
            }
        }
    #endif
    
        /*
         * Warn the user that he should use the session cache.
         * But we can operate without it, of course.
         */
        if (mc->sesscache == NULL) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01873)
                         "Init: Session Cache is not configured "
                         "[hint: SSLSessionCache]");
            return APR_SUCCESS;
        }
    
        memset(&hints, 0, sizeof hints);
        hints.avg_obj_size = 150;
        hints.avg_id_len = 30;
        hints.expiry_interval = 30;
    
        rv = mc->sesscache->init(mc->sesscache_context, "mod_ssl-sess", &hints, s, p);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01874)
                         "Could not initialize session cache. Exiting.");
            return ssl_die(s);
        }
    
        return APR_SUCCESS;
    }
    
    void ssl_scache_kill(server_rec *s)
    {
        SSLModConfigRec *mc = myModConfig(s);
    
        if (mc->sesscache) {
            mc->sesscache->destroy(mc->sesscache_context, s);
        }
    
    #ifdef HAVE_OCSP_STAPLING
        if (mc->stapling_cache) {
            mc->stapling_cache->destroy(mc->stapling_cache_context, s);
        }
    #endif
    
    }
    
    BOOL ssl_scache_store(server_rec *s, IDCONST UCHAR *id, int idlen,
                          apr_time_t expiry, SSL_SESSION *sess,
                          apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
        unsigned char encoded[MODSSL_SESSION_MAX_DER], *ptr;
        unsigned int len;
        apr_status_t rv;
    
        /* Serialise the session. */
        len = i2d_SSL_SESSION(sess, NULL);
        if (len > sizeof encoded) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01875)
                         "session is too big (%u bytes)", len);
            return FALSE;
        }
    
        ptr = encoded;
        len = i2d_SSL_SESSION(sess, &ptr);
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_on(s);
        }
    
        rv = mc->sesscache->store(mc->sesscache_context, s, id, idlen,
                                  expiry, encoded, len, p);
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_off(s);
        }
    
        return rv == APR_SUCCESS ? TRUE : FALSE;
    }
    
    SSL_SESSION *ssl_scache_retrieve(server_rec *s, IDCONST UCHAR *id, int idlen,
                                     apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
        unsigned char dest[MODSSL_SESSION_MAX_DER];
        unsigned int destlen = MODSSL_SESSION_MAX_DER;
        const unsigned char *ptr;
        apr_status_t rv;
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_on(s);
        }
    
        rv = mc->sesscache->retrieve(mc->sesscache_context, s, id, idlen,
                                     dest, &destlen, p);
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_off(s);
        }
    
        if (rv != APR_SUCCESS) {
            return NULL;
        }
    
        ptr = dest;
    
        return d2i_SSL_SESSION(NULL, &ptr, destlen);
    }
    
    void ssl_scache_remove(server_rec *s, IDCONST UCHAR *id, int idlen,
                           apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_on(s);
        }
    
        mc->sesscache->remove(mc->sesscache_context, s, id, idlen, p);
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_off(s);
        }
    }
    
    /*  _________________________________________________________________
    **
    **  SSL Extension to mod_status
    **  _________________________________________________________________
    */
    static int ssl_ext_status_hook(request_rec *r, int flags)
    {
        SSLModConfigRec *mc = myModConfig(r->server);
    
        if (mc == NULL || mc->sesscache == NULL)
            return OK;
    
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rputs("<hr>\n", r);
            ap_rputs("<table cellspacing=0 cellpadding=0>\n", r);
            ap_rputs("<tr><td bgcolor=\"#000000\">\n", r);
            ap_rputs("<b><font color=\"#ffffff\" face=\"Arial,Helvetica\">SSL/TLS Session Cache Status:</font></b>\r", r);
            ap_rputs("</td></tr>\n", r);
            ap_rputs("<tr><td bgcolor=\"#ffffff\">\n", r);
        }
        else {
            ap_rputs("TLSSessionCacheStatus\n", r);
        }
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_on(r->server);
        }
    
        mc->sesscache->status(mc->sesscache_context, r, flags);
    
        if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            ssl_mutex_off(r->server);
        }
    
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rputs("</td></tr>\n", r);
            ap_rputs("</table>\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);
    }
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/README���������������������������������������������������������������������0000664�0001751�0001751�00000011263�12757564422�015774� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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 
     <http://www.modssl.org/>.
    
    SOURCES
    
     See the top-level LAYOUT file 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 specifying 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 <IfDefine> 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 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 Persistent 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 the ssl_engine_{ds,ext}.c source files are obsolete and no longer
       exist
    
    TODO
    
     See the top-level STATUS file for current efforts and goals.
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_private.h��������������������������������������������������������������0000664�0001751�0001751�00000125163�15032734372�017615� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
    
    /**
     * @file  ssl_private.h
     * @brief Internal interfaces private to mod_ssl.
     *
     * @defgroup MOD_SSL_PRIVATE Private
     * @ingroup MOD_SSL
     * @{
     */
    
    /** Apache headers */
    #include "ap_config.h"
    #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 "http_ssl.h"
    #include "http_vhost.h"
    #include "util_script.h"
    #include "util_filter.h"
    #include "util_ebcdic.h"
    #include "util_mutex.h"
    #include "apr.h"
    #include "apr_strings.h"
    #define APR_WANT_STRFUNC
    #define APR_WANT_MEMFUNC
    #include "apr_want.h"
    #include "apr_tables.h"
    #include "apr_lib.h"
    #include "apr_fnmatch.h"
    #include "apr_strings.h"
    #include "apr_global_mutex.h"
    #include "apr_optional.h"
    #include "ap_socache.h"
    #include "mod_auth.h"
    
    /* The #ifdef macros are only defined AFTER including the above
     * therefore we cannot include these system files at the top  :-(
     */
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_SYS_TIME_H
    #include <sys/time.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h> /* needed for STDIN_FILENO et.al., at least on FreeBSD */
    #endif
    
    #ifndef FALSE
    #define FALSE 0
    #endif
    
    #ifndef TRUE
    #define TRUE !FALSE
    #endif
    
    #ifndef BOOL
    #define BOOL unsigned int
    #endif
    
    #include "ap_expr.h"
    
    /* keep first for compat API */
    #ifndef OPENSSL_API_COMPAT
    #define OPENSSL_API_COMPAT 0x10101000 /* for ENGINE_ API */
    #endif
    #include "mod_ssl_openssl.h"
    
    /* OpenSSL headers */
    #include <openssl/err.h>
    #include <openssl/x509.h>
    #include <openssl/pem.h>
    #include <openssl/crypto.h>
    #include <openssl/evp.h>
    #include <openssl/rand.h>
    #include <openssl/x509v3.h>
    #include <openssl/x509_vfy.h>
    #include <openssl/ocsp.h>
    #include <openssl/dh.h>
    #if OPENSSL_VERSION_NUMBER >= 0x30000000
    #include <openssl/core_names.h>
    #endif
    
    /* 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) \
        && (OPENSSL_VERSION_NUMBER < 0x30000000 \
            || (defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL < 30000)) \
        && !defined(OPENSSL_NO_ENGINE)
    #include <openssl/engine.h>
    #define MODSSL_HAVE_ENGINE_API 1
    #endif
    #ifndef MODSSL_HAVE_ENGINE_API
    #define MODSSL_HAVE_ENGINE_API 0
    #endif
    
    /* Use OpenSSL 3.x STORE for loading URI keys and certificates starting with
     * OpenSSL 3.0
     */
    #if OPENSSL_VERSION_NUMBER >= 0x30000000
    #define MODSSL_HAVE_OPENSSL_STORE 1
    #else
    #define MODSSL_HAVE_OPENSSL_STORE 0
    #endif
    
    #if (OPENSSL_VERSION_NUMBER < 0x0090801f)
    #error mod_ssl requires OpenSSL 0.9.8a or later
    #endif
    
    /**
     * ...shifting sands of OpenSSL...
     * Note: when adding support for new OpenSSL features, avoid explicit
     * version number checks whenever possible, and use "feature-based"
     * detection instead (check for definitions of constants or functions)
     */
    #if (OPENSSL_VERSION_NUMBER >= 0x10000000)
    #define MODSSL_SSL_CIPHER_CONST const
    #define MODSSL_SSL_METHOD_CONST const
    #else
    #define MODSSL_SSL_CIPHER_CONST
    #define MODSSL_SSL_METHOD_CONST
    #endif
    
    #if defined(LIBRESSL_VERSION_NUMBER)
    /* Missing from LibreSSL */
    #if LIBRESSL_VERSION_NUMBER < 0x2060000f
    #define SSL_CTRL_SET_MIN_PROTO_VERSION          123
    #define SSL_CTRL_SET_MAX_PROTO_VERSION          124
    #define SSL_CTX_set_min_proto_version(ctx, version) \
            SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
    #define SSL_CTX_set_max_proto_version(ctx, version) \
            SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
    #endif /* LIBRESSL_VERSION_NUMBER < 0x2060000f */
    /* LibreSSL before 2.7 declares OPENSSL_VERSION_NUMBER == 2.0 but does not
     * include most changes from OpenSSL >= 1.1 (new functions, macros, 
     * deprecations, ...), so we have to work around this...
     */
    #if LIBRESSL_VERSION_NUMBER < 0x2070000f
    #define MODSSL_USE_OPENSSL_PRE_1_1_API 1
    #else
    #define MODSSL_USE_OPENSSL_PRE_1_1_API 0
    #endif
    #else /* defined(LIBRESSL_VERSION_NUMBER) */
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
    #define MODSSL_USE_OPENSSL_PRE_1_1_API 1
    #else
    #define MODSSL_USE_OPENSSL_PRE_1_1_API 0
    #endif
    #endif /* defined(LIBRESSL_VERSION_NUMBER) */
    
    #if defined(OPENSSL_FIPS) || OPENSSL_VERSION_NUMBER >= 0x30000000L
    #define HAVE_FIPS
    #endif
    
    #if defined(SSL_OP_NO_TLSv1_2)
    #define HAVE_TLSV1_X
    #endif
    
    #if defined(SSL_CONF_FLAG_FILE)
    #define HAVE_SSL_CONF_CMD
    #endif
    
    /* session id constness */
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    #define IDCONST
    #else
    #define IDCONST const
    #endif
    
    /**
      * The following features all depend on TLS extension support.
      * Within this block, check again for features (not version numbers).
      */
    #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_set_tlsext_host_name)
    
    #define HAVE_TLSEXT
    
    /* ECC: make sure we have at least 1.0.0 */
    #if !defined(OPENSSL_NO_EC) && defined(TLSEXT_ECPOINTFORMAT_uncompressed)
    #define HAVE_ECC
    #endif
    
    /* OCSP stapling */
    #if !defined(OPENSSL_NO_OCSP) && defined(SSL_CTX_set_tlsext_status_cb)
    #define HAVE_OCSP_STAPLING
    /* All exist but are no longer macros since OpenSSL 1.1.0 */
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
    /* backward compatibility with OpenSSL < 1.0 */
    #ifndef sk_OPENSSL_STRING_num
    #define sk_OPENSSL_STRING_num sk_num
    #endif
    #ifndef sk_OPENSSL_STRING_value
    #define sk_OPENSSL_STRING_value sk_value
    #endif
    #ifndef sk_OPENSSL_STRING_pop
    #define sk_OPENSSL_STRING_pop sk_pop
    #endif
    #endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L */
    #endif /* if !defined(OPENSSL_NO_OCSP) && defined(SSL_CTX_set_tlsext_status_cb) */
    
    /* TLS session tickets */
    #if defined(SSL_CTX_set_tlsext_ticket_key_cb)
    #define HAVE_TLS_SESSION_TICKETS
    #define TLSEXT_TICKET_KEY_LEN 48
    #ifndef tlsext_tick_md
    #ifdef OPENSSL_NO_SHA256
    #define tlsext_tick_md EVP_sha1
    #else
    #define tlsext_tick_md EVP_sha256
    #endif
    #endif
    #endif
    
    /* Secure Remote Password */
    #if !defined(OPENSSL_NO_SRP) \
        && (OPENSSL_VERSION_NUMBER < 0x30000000L \
            || (defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL < 30000)) \
        && defined(SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB)
    #define HAVE_SRP
    #include <openssl/srp.h>
    #endif
    
    /* ALPN Protocol Negotiation */
    #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
    #define HAVE_TLS_ALPN
    #endif
    
    #endif /* !defined(OPENSSL_NO_TLSEXT) && defined(SSL_set_tlsext_host_name) */
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    #define BN_get_rfc2409_prime_768   get_rfc2409_prime_768
    #define BN_get_rfc2409_prime_1024  get_rfc2409_prime_1024
    #define BN_get_rfc3526_prime_1536  get_rfc3526_prime_1536
    #define BN_get_rfc3526_prime_2048  get_rfc3526_prime_2048
    #define BN_get_rfc3526_prime_3072  get_rfc3526_prime_3072
    #define BN_get_rfc3526_prime_4096  get_rfc3526_prime_4096
    #define BN_get_rfc3526_prime_6144  get_rfc3526_prime_6144
    #define BN_get_rfc3526_prime_8192  get_rfc3526_prime_8192
    #define BIO_set_init(x,v)          (x->init=v)
    #define BIO_get_data(x)            (x->ptr)
    #define BIO_set_data(x,v)          (x->ptr=v)
    #define BIO_get_shutdown(x)        (x->shutdown)
    #define BIO_set_shutdown(x,v)      (x->shutdown=v)
    #define DH_bits(x)                 (BN_num_bits(x->p))
    #else
    void init_bio_methods(void);
    void free_bio_methods(void);
    #endif
    
    #if OPENSSL_VERSION_NUMBER < 0x10002000L || \
    	(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000f)
    #define X509_STORE_CTX_get0_store(x) (x->ctx)
    #endif
    
    #if OPENSSL_VERSION_NUMBER < 0x10000000L
    #ifndef X509_STORE_CTX_get0_current_issuer
    #define X509_STORE_CTX_get0_current_issuer(x) (x->current_issuer)
    #endif
    #endif
    
    /* those may be deprecated */
    #ifndef X509_get_notBefore
    #define X509_get_notBefore  X509_getm_notBefore
    #endif
    #ifndef X509_get_notAfter
    #define X509_get_notAfter   X509_getm_notAfter
    #endif
    
    /* The SSL_CTX_set_keylog_callback() API is present in 1.1.1+.
     * 
     * OpenSSL 3.5+ also provides optional native handling of
     * $SSLKEYLOGFILE inside libssl, which duplicates the mod_ssl support.
     * The mod_ssl support is hence disabled for 3.5+, unless that OpenSSL
     * feature is itself disabled (and OPENSSL_NO_SSLKEYLOG is defined).
     */
    #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) \
        && (OPENSSL_VERSION_NUMBER <= 0x30500000L || defined(OPENSSL_NO_SSLKEYLOG))
    #define HAVE_OPENSSL_KEYLOG 
    #endif
    
    #ifdef HAVE_FIPS
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    #define modssl_fips_is_enabled() EVP_default_properties_is_fips_enabled(NULL)
    #define modssl_fips_enable(to)   EVP_default_properties_enable_fips(NULL, (to))
    #else
    #define modssl_fips_is_enabled() FIPS_mode()
    #define modssl_fips_enable(to)   FIPS_mode_set((to))
    #endif
    #endif /* HAVE_FIPS */
    
    /* mod_ssl headers */
    #include "ssl_util_ssl.h"
    
    APLOG_USE_MODULE(ssl);
    
    /*
     * Provide reasonable default for some defines
     */
    #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 <limits.h>
    #define RAND_MAX INT_MAX
    #endif
    
    /**
     * Provide reasonable defines for some types
     */
    #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 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 myConnCtxConfig(c, sc) \
        (c->outgoing ? myConnConfig(c)->dc->proxy : sc->server)
    #define myModConfig(srv) mySrvConfig((srv))->mc
    #define mySrvFromConn(c) myConnConfig(c)->server
    #define myDirConfigFromConn(c) myConnConfig(c)->dc
    #define mySrvConfigFromConn(c) mySrvConfig(mySrvFromConn(c))
    #define myModConfigFromConn(c) myModConfig(mySrvFromConn(c))
    
    /**
     * Defaults for the configuration
     */
    #ifndef SSL_SESSION_CACHE_TIMEOUT
    #define SSL_SESSION_CACHE_TIMEOUT  300
    #endif
    
    /* Default setting for per-dir reneg buffer. */
    #ifndef DEFAULT_RENEG_BUFFER_SIZE
    #define DEFAULT_RENEG_BUFFER_SIZE (128 * 1024)
    #endif
    
    /* Default for OCSP response validity */
    #ifndef DEFAULT_OCSP_MAX_SKEW
    #define DEFAULT_OCSP_MAX_SKEW (60 * 5)
    #endif
    
    /* Default timeout for OCSP queries */
    #ifndef DEFAULT_OCSP_TIMEOUT
    #define DEFAULT_OCSP_TIMEOUT 10
    #endif
    
    /*
     * For better backwards compatibility with the SSLCertificate[Key]File
     * and SSLPassPhraseDialog ("exec" type) directives in 2.4.7 and earlier
     */
    #ifdef HAVE_ECC
    #define CERTKEYS_IDX_MAX 2
    #else
    #define CERTKEYS_IDX_MAX 1
    #endif
    
    /**
     * 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_LEGACYDNFORMAT (1<<7)
    typedef int ssl_opt_t;
    
    /**
     * Define the SSL Protocol options
     */
    #define SSL_PROTOCOL_NONE  (0)
    #ifndef OPENSSL_NO_SSL3
    #define SSL_PROTOCOL_SSLV3 (1<<1)
    #endif
    #define SSL_PROTOCOL_TLSV1 (1<<2)
    #ifndef OPENSSL_NO_SSL3
    #define SSL_PROTOCOL_BASIC (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
    #else
    #define SSL_PROTOCOL_BASIC (SSL_PROTOCOL_TLSV1)
    #endif
    #ifdef HAVE_TLSV1_X
    #define SSL_PROTOCOL_TLSV1_1 (1<<3)
    #define SSL_PROTOCOL_TLSV1_2 (1<<4)
    #define SSL_PROTOCOL_TLSV1_3 (1<<5)
    
    #ifdef SSL_OP_NO_TLSv1_3
    #define SSL_HAVE_PROTOCOL_TLSV1_3   (1)
    #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_BASIC| \
                                SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2|SSL_PROTOCOL_TLSV1_3)
    #else
    #define SSL_HAVE_PROTOCOL_TLSV1_3   (0)
    #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_BASIC| \
                                SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2)
    #endif
    #else
    #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_BASIC)
    #endif
    #ifndef OPENSSL_NO_SSL3
    #define SSL_PROTOCOL_DEFAULT (SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_SSLV3)
    #else
    #define SSL_PROTOCOL_DEFAULT (SSL_PROTOCOL_ALL)
    #endif
    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)
    
    #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))
    
    /**
      * CRL checking mask (mode | flags)
      */
    typedef enum {
        SSL_CRLCHECK_NONE  = (0),
        SSL_CRLCHECK_LEAF  = (1 << 0),
        SSL_CRLCHECK_CHAIN = (1 << 1),
    
    #define SSL_CRLCHECK_FLAGS (~0x3)
        SSL_CRLCHECK_NO_CRL_FOR_CERT_OK = (1 << 2)
    } ssl_crlcheck_t;
    
    /**
      * OCSP checking mask (mode | flags)
      */
    typedef enum {
        SSL_OCSPCHECK_NONE  = (0),
        SSL_OCSPCHECK_LEAF  = (1 << 0),
        SSL_OCSPCHECK_CHAIN = (1 << 1),
        SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK = (1 << 2)
    } ssl_ocspcheck_t;
    
    /**
     * 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 enabled state
     */
    typedef enum {
        SSL_ENABLED_UNSET    = UNSET,
        SSL_ENABLED_FALSE    = 0,
        SSL_ENABLED_TRUE     = 1,
    } ssl_enabled_t;
    
    /**
     * Define the SSL requirement structure
     */
    typedef struct {
        const char     *cpExpr;
        ap_expr_info_t *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;
    
    typedef enum {
        RENEG_INIT = 0, /* Before initial handshake */
        RENEG_REJECT,   /* After initial handshake; any client-initiated
                         * renegotiation should be rejected */
        RENEG_ALLOW,    /* A server-initiated renegotiation is taking
                         * place (as dictated by configuration) */
        RENEG_ABORT     /* Renegotiation initiated by client, abort the
                         * connection */
    } modssl_reneg_state;
    
    /**
     * Define the mod_ssl per-module configuration structure
     * (i.e. the global configuration for each httpd process)
     */
    
    typedef struct SSLSrvConfigRec SSLSrvConfigRec;
    typedef struct SSLDirConfigRec SSLDirConfigRec;
    
    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 disabled;
        enum {
            NON_SSL_OK = 0,        /* is SSL request, or error handling completed */
            NON_SSL_SEND_REQLINE,  /* Need to send the fake request line */
            NON_SSL_SEND_HDR_SEP,  /* Need to send the header separator */
            NON_SSL_SET_ERROR_MSG  /* Need to set the error message */
        } non_ssl_request;
    
    #ifndef SSL_OP_NO_RENEGOTIATION
        /* For OpenSSL < 1.1.1, track the handshake/renegotiation state
         * for the connection to block client-initiated renegotiations.
         * For OpenSSL >=1.1.1, the SSL_OP_NO_RENEGOTIATION flag is used in
         * the SSL * options state with equivalent effect. */
        modssl_reneg_state reneg_state;
    #endif
    
        server_rec *server;
        SSLDirConfigRec *dc;
        
        const char *cipher_suite; /* cipher suite used in last reneg */
        int service_unavailable;  /* thouugh we negotiate SSL, no requests will be served */
        int vhost_found;          /* whether we found vhost from SNI already */
    } SSLConnRec;
    
    /* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
     * allocated out of the "process" pool and only a single such
     * structure is created and used for the lifetime of the process.
     * (The process pool is s->process->pool and is stored in the .pPool
     * field.)  Most members of this structure are likewise allocated out
     * of the process pool, but notably sesscache and sesscache_context
     * are not.
     *
     * The structure is treated as mostly immutable after a single config
     * parse has completed; the post_config hook (ssl_init_Module) flips
     * the bFixed flag to true and subsequent invocations of the config
     * callbacks hence do nothing.
     *
     * This odd lifetime strategy is used so that encrypted private keys
     * can be decrypted once at startup and continue to be used across
     * subsequent server reloads where the interactive password prompt is
     * not possible.
    
     * It is really an ABI nightmare waiting to happen since DSOs are
     * reloaded across restarts, and nothing prevents the struct type
     * changing across such reloads, yet the cached structure will be
     * assumed to match regardless.
     *
     * This should really be fixed using a smaller structure which only
     * stores that which is absolutely necessary (the private keys, maybe
     * the random seed), and have that structure be strictly ABI-versioned
     * for safety.
     */
    typedef struct {
        pid_t           pid;
        apr_pool_t     *pPool;
        BOOL            bFixed;
    
        /* OpenSSL SSL_SESS_CACHE_* flags: */
        long            sesscache_mode;
    
        /* The configured provider, and associated private data
         * structure. */
        const ap_socache_provider_t *sesscache;
        ap_socache_instance_t *sesscache_context;
    
        apr_global_mutex_t   *pMutex;
        apr_array_header_t   *aRandSeed;
        apr_hash_t     *tVHostKeys;
    
        /* A hash table of pointers to ssl_asn1_t structures.  The structures
         * are used to store private keys in raw DER format (serialized OpenSSL
         * PrivateKey structures).  The table is indexed by (vhost-id,
         * index), for example the string "vhost.example.com:443:0". */
        apr_hash_t     *tPrivateKey;
    
        const char     *szCryptoDevice; /* ENGINE device (if available) */
    
    #ifdef HAVE_OCSP_STAPLING
        const ap_socache_provider_t *stapling_cache;
        ap_socache_instance_t *stapling_cache_context;
        apr_global_mutex_t   *stapling_cache_mutex;
        apr_global_mutex_t   *stapling_refresh_mutex;
    #endif
    #ifdef HAVE_OPENSSL_KEYLOG
        /* Used for logging if SSLKEYLOGFILE is set at startup. */
        apr_file_t      *keylog_file;
    #endif
    
    #ifdef HAVE_FIPS
        BOOL             fips;
    #endif
    } SSLModConfigRec;
    
    /** Structure representing configured filenames for certs and keys for
     * a given vhost */
    typedef struct {
        /* Lists of configured certs and keys for this server */
        apr_array_header_t *cert_files;
        apr_array_header_t *key_files;
    
        /** 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;
        
        /* TLS service for this server is suspended */
        int service_unavailable;
    } modssl_pk_server_t;
    
    typedef struct {
        /** proxy can have any number of cert/key pairs */
        const char  *cert_file;
        const char  *cert_path;
        const char  *ca_cert_file;
        /* certs is a stack of configured cert, key pairs. */
        STACK_OF(X509_INFO) *certs;
        /* ca_certs contains ONLY chain certs for each item in certs.
         * ca_certs[n] is a pointer to the (STACK_OF(X509) *) stack which
         * holds the cert chain for the 'n'th cert in the certs stack, or
         * NULL if no chain is configured. */
        STACK_OF(X509) **ca_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;
    
        /** TLSv1.3 has its separate cipher list, separate from the
         settings for older TLS protocol versions. Since which one takes
         effect is a matter of negotiation, we need separate settings */
        const char  *tls13_ciphers;
    } modssl_auth_ctx_t;
    
    #ifdef HAVE_TLS_SESSION_TICKETS
    typedef struct {
        const char *file_path;
        unsigned char key_name[16];
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
        unsigned char hmac_secret[16];
    #else
        OSSL_PARAM mac_params[3];
    #endif
        unsigned char aes_key[16];
    } modssl_ticket_key_t;
    #endif
    
    #ifdef HAVE_SSL_CONF_CMD
    typedef struct {
        const char *name;
        const char *value;
    } ssl_ctx_param_t;
    #endif
    
    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;
    
    #ifdef HAVE_TLS_SESSION_TICKETS
        modssl_ticket_key_t *ticket_key;
    #endif
    
        ssl_proto_t  protocol;
        int protocol_set;
    
        /** 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;
        int            crl_check_mask;
    
    #ifdef HAVE_OCSP_STAPLING
        /** OCSP stapling options */
        BOOL        stapling_enabled;
        long        stapling_resptime_skew;
        long        stapling_resp_maxage;
        int         stapling_cache_timeout;
        BOOL        stapling_return_errors;
        BOOL        stapling_fake_trylater;
        int         stapling_errcache_timeout;
        apr_interval_time_t stapling_responder_timeout;
        const char *stapling_force_url;
    #endif
    
    #ifdef HAVE_SRP
        char *srp_vfile;
        char *srp_unknown_user_seed;
        SRP_VBASE  *srp_vbase;
    #endif
    
        modssl_auth_ctx_t auth;
    
        int ocsp_mask;
        BOOL ocsp_force_default; /* true if the default responder URL is
                                  * used regardless of per-cert URL */
        const char *ocsp_responder; /* default responder URL */
        long ocsp_resptime_skew;
        long ocsp_resp_maxage;
        apr_interval_time_t ocsp_responder_timeout;
        BOOL ocsp_use_request_nonce;
        apr_uri_t *proxy_uri;
    
        BOOL ocsp_noverify; /* true if skipping OCSP certification verification like openssl -noverify */
        /* Declare variables for using OCSP Responder Certs for OCSP verification */
        int ocsp_verify_flags; /* Flags to use when verifying OCSP response */
        const char *ocsp_certs_file; /* OCSP other certificates filename */
        STACK_OF(X509) *ocsp_certs; /* OCSP other certificates */
    
    #ifdef HAVE_SSL_CONF_CMD
        SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */
        apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */
    #endif
    
        BOOL ssl_check_peer_cn;
        BOOL ssl_check_peer_name;
        BOOL ssl_check_peer_expire;
    } modssl_ctx_t;
    
    struct SSLSrvConfigRec {
        SSLModConfigRec *mc;
        ssl_enabled_t    enabled;
        const char      *vhost_id;
        int              vhost_id_len;
        int              session_cache_timeout;
        BOOL             cipher_server_pref;
        BOOL             insecure_reneg;
        modssl_ctx_t    *server;
    #ifdef HAVE_TLSEXT
        ssl_enabled_t    strict_sni_vhost_check;
    #endif
    #ifndef OPENSSL_NO_COMP
        BOOL             compression;
    #endif
        BOOL             session_tickets;
    };
    
    /**
     * Define the mod_ssl per-directory configuration structure
     * (i.e. the local configuration for all &lt;Directory>
     *  and .htaccess contexts)
     */
    struct SSLDirConfigRec {
        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   *szUserName;
        apr_size_t    nRenegBufferSize;
    
        modssl_ctx_t *proxy;
        BOOL          proxy_enabled;
        BOOL          proxy_post_config;
    };
    
    /**
     *  function prototypes
     */
    
    /**  API glue structures  */
    extern module AP_MODULE_DECLARE_DATA ssl_module;
    
    /**  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 *);
    void         ssl_config_proxy_merge(apr_pool_t *,
                                        SSLDirConfigRec *, SSLDirConfigRec *);
    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 *);
    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_SSLCARevocationCheck(cmd_parms *, void *, const char *);
    const char  *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag);
    const char  *ssl_cmd_SSLCompression(cmd_parms *, void *, int flag);
    const char  *ssl_cmd_SSLSessionTickets(cmd_parms *, void *, 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_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg);
    const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag);
    const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag);
    
    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 *);
    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_SSLProxyCARevocationCheck(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 *);
    const char  *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *, void *, const char *);
    #ifdef HAVE_TLS_SESSION_TICKETS
    const char *ssl_cmd_SSLSessionTicketKeyFile(cmd_parms *cmd, void *dcfg, const char *arg);
    #endif
    const char  *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag);
    const char  *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
    const char  *ssl_cmd_SSLProxyCheckPeerName(cmd_parms *cmd, void *dcfg, int flag);
    
    const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag);
    const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg);
    const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg);
    const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg);
    const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg);
    const char *ssl_cmd_SSLOCSPUseRequestNonce(cmd_parms *cmd, void *dcfg, int flag);
    const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *arg);
    const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd, void *dcfg, const char *arg);
    
    /* Declare OCSP Responder Certificate Verification Directive */
    const char *ssl_cmd_SSLOCSPNoVerify(cmd_parms *cmd, void *dcfg, int flag);
    /* Declare OCSP Responder Certificate File Directive */
    const char *ssl_cmd_SSLOCSPResponderCertificateFile(cmd_parms *cmd, void *dcfg, const char *arg);
    
    #ifdef HAVE_SSL_CONF_CMD
    const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg, const char *arg1, const char *arg2);
    #endif
    
    #ifdef HAVE_SRP
    const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, const char *arg);
    const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg, const char *arg);
    #endif
    
    const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag);
    
    /**  module initialization  */
    apr_status_t ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *);
    apr_status_t ssl_init_Engine(server_rec *, apr_pool_t *);
    apr_status_t ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *,
                                          apr_array_header_t *);
    apr_status_t ssl_init_CheckServers(server_rec *, apr_pool_t *);
    int          ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
                                               apr_pool_t *ptemp, server_rec *s,
                                               ap_conf_vector_t *section_config);
    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);
    
    /** Apache authz provisders */
    extern const authz_provider ssl_authz_provider_require_ssl;
    extern const authz_provider ssl_authz_provider_verify_client;
    
    /**  OpenSSL callbacks */
    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, X509 **x509, EVP_PKEY **pkey);
    int          ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *);
    SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, IDCONST unsigned char *, int, int *);
    void         ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
    void         ssl_callback_Info(const SSL *, int, int);
    #ifdef HAVE_TLSEXT
    int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
    #endif
    #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
    int          ssl_callback_ClientHello(SSL *, int *, void *);
    #endif
    #ifdef HAVE_TLS_SESSION_TICKETS
    int ssl_callback_SessionTicket(SSL *ssl,
                                   unsigned char *keyname,
                                   unsigned char *iv,
                                   EVP_CIPHER_CTX *cipher_ctx,
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
                                   HMAC_CTX *hmac_ctx,
    #else
                                   EVP_MAC_CTX *mac_ctx,
    #endif
                                   int mode);
    #endif
    
    #ifdef HAVE_TLS_ALPN
    int ssl_callback_alpn_select(SSL *ssl, const unsigned char **out,
                                 unsigned char *outlen, const unsigned char *in,
                                 unsigned int inlen, void *arg);
    #endif
    
    /**  Session Cache Support  */
    apr_status_t 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 *, IDCONST UCHAR *, int,
                                  apr_time_t, SSL_SESSION *, apr_pool_t *);
    SSL_SESSION *ssl_scache_retrieve(server_rec *, IDCONST UCHAR *, int, apr_pool_t *);
    void         ssl_scache_remove(server_rec *, IDCONST UCHAR *, int,
                                   apr_pool_t *);
    
    /** OCSP Stapling Support */
    #ifdef HAVE_OCSP_STAPLING
    const char *ssl_cmd_SSLStaplingCache(cmd_parms *, void *, const char *);
    const char *ssl_cmd_SSLUseStapling(cmd_parms *, void *, int);
    const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *, void *, const char *);
    const char *ssl_cmd_SSLStaplingResponseMaxAge(cmd_parms *, void *, const char *);
    const char *ssl_cmd_SSLStaplingStandardCacheTimeout(cmd_parms *, void *, const char *);
    const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *, void *, const char *);
    const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *, void *, int);
    const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *, void *, int);
    const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *, void *, const char *);
    const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *);
    apr_status_t modssl_init_stapling(server_rec *, apr_pool_t *, apr_pool_t *, modssl_ctx_t *);
    void         ssl_stapling_certinfo_hash_init(apr_pool_t *);
    int          ssl_stapling_init_cert(server_rec *, apr_pool_t *, apr_pool_t *,
                                        modssl_ctx_t *, X509 *);
    #endif
    #ifdef HAVE_SRP
    int          ssl_callback_SRPServerParams(SSL *, int *, void *);
    #endif
    
    #ifdef HAVE_OPENSSL_KEYLOG
    /* Callback used with SSL_CTX_set_keylog_callback. */
    void         modssl_callback_keylog(const SSL *ssl, const char *line);
    #endif
    
    /**  I/O  */
    void         ssl_io_filter_init(conn_rec *, request_rec *r, SSL *);
    void         ssl_io_filter_register(apr_pool_t *);
    void         modssl_set_io_callbacks(SSL *ssl, conn_rec *c, server_rec *s);
    
    /* ssl_io_buffer_fill fills the setaside buffering of the HTTP request
     * to allow an SSL renegotiation to take place. */
    int          ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen);
    
    /**  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 *);
    #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
    void         ssl_util_thread_setup(apr_pool_t *);
    void         ssl_util_thread_id_setup(apr_pool_t *);
    #endif
    int          ssl_init_ssl_connection(conn_rec *c, request_rec *r);
    
    BOOL         ssl_util_vhost_matches(const char *servername, server_rec *s);
    
    /**  Pass Phrase Support  */
    apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int,
                                         const char *, apr_array_header_t **);
    
    /* Load public and/or private key from the configured ENGINE. Private
     * key returned as *pkey.  certid can be NULL, in which case *pubkey
     * is not altered.  Errors logged on failure. */
    apr_status_t modssl_load_engine_keypair(server_rec *s,
                                            apr_pool_t *pconf, apr_pool_t *ptemp,
                                            const char *vhostid,
                                            const char *certid, const char *keyid,
                                            X509 **pubkey, EVP_PKEY **privkey);
    
    /**  Diffie-Hellman Parameter Support  */
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
    DH           *modssl_dh_from_file(const char *);
    #else
    EVP_PKEY     *modssl_dh_pkey_from_file(const char *);
    #endif
    #ifdef HAVE_ECC
    EC_GROUP     *modssl_ec_group_from_file(const char *);
    #endif
    
    /* Store the EVP_PKEY key (serialized into DER) in the hash table with
     * key, returning the ssl_asn1_t structure pointer. */
    ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
                                   EVP_PKEY *pkey);
    /* Retrieve the ssl_asn1_t structure with given key from the hash. */
    ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, const char *key);
    /* Remove and free the ssl_asn1_t structure with given key. */
    void ssl_asn1_table_unset(apr_hash_t *table, const char *key);
    
    /**  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 *);
    
    int          ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *);
    
    /* mutex type names for Mutex directive */
    #define SSL_CACHE_MUTEX_TYPE    "ssl-cache"
    #define SSL_STAPLING_CACHE_MUTEX_TYPE "ssl-stapling"
    #define SSL_STAPLING_REFRESH_MUTEX_TYPE "ssl-stapling-refresh"
    
    apr_status_t ssl_die(server_rec *);
    
    /**  Logfile Support  */
    void         ssl_log_ssl_error(const char *, int, int, server_rec *);
    
    /* ssl_log_xerror, ssl_log_cxerror and ssl_log_rxerror are wrappers for the
     * respective ap_log_*error functions and take a certificate as an
     * additional argument (whose details are appended to the log message).
     * The other arguments are interpreted exactly as with their ap_log_*error
     * counterparts. */
    void ssl_log_xerror(const char *file, int line, int level,
                        apr_status_t rv, apr_pool_t *p, server_rec *s,
                        X509 *cert, const char *format, ...)
        __attribute__((format(printf,8,9)));
    
    void ssl_log_cxerror(const char *file, int line, int level,
                         apr_status_t rv, conn_rec *c, X509 *cert,
                         const char *format, ...)
        __attribute__((format(printf,7,8)));
    
    void ssl_log_rxerror(const char *file, int line, int level,
                         apr_status_t rv, request_rec *r, X509 *cert,
                         const char *format, ...)
        __attribute__((format(printf,7,8)));
    
    #define SSLLOG_MARK              __FILE__,__LINE__
    
    /**  Variables  */
    
    /* Register variables for the lifetime of the process pool 'p'. */
    void         ssl_var_register(apr_pool_t *p);
    char        *ssl_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *);
    apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, const char *extension);
    
    void         ssl_var_log_config_register(apr_pool_t *p);
    
    /* Extract SSL_*_DN_* variables into table 't' from SSL object 'ssl',
     * allocating from 'p': */
    void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p);
    
    /* Extract SSL_*_SAN_* variables (subjectAltName entries) into table 't'
     * from SSL object 'ssl', allocating from 'p'. */
    void modssl_var_extract_san_entries(apr_table_t *t, SSL *ssl, apr_pool_t *p);
    
    #ifndef OPENSSL_NO_OCSP
    /* Perform OCSP validation of the current cert in the given context.
     * Returns non-zero on success or zero on failure.  On failure, the
     * context error code is set. */
    int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc,
                           server_rec *s, conn_rec *c, apr_pool_t *pool);
    
    /* OCSP helper interface; dispatches the given OCSP request to the
     * responder at the given URI.  Returns the decoded OCSP response
     * object, or NULL on error (in which case, errors will have been
     * logged).  Pool 'p' is used for temporary allocations. */
    OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri,
                                                apr_interval_time_t timeout,
                                                OCSP_REQUEST *request,
                                                conn_rec *c, apr_pool_t *p);
    
    /* Initialize OCSP trusted certificate list */
    void ssl_init_ocsp_certificates(server_rec *s, modssl_ctx_t *mctx);
    
    #endif
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    /* Retrieve DH parameters for given key length.  Return value should
     * be treated as unmutable, since it is stored in process-global
     * memory. */
    DH *modssl_get_dh_params(unsigned keylen);
    #endif
    
    /* Returns non-zero if the request was made over SSL/TLS.  If sslconn
     * is non-NULL and the request is using SSL/TLS, sets *sslconn to the
     * corresponding SSLConnRec structure for the connection. */
    int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn);
    
    int ssl_is_challenge(conn_rec *c, const char *servername, 
                         X509 **pcert, EVP_PKEY **pkey,
                        const char **pcert_file, const char **pkey_file);
    
    /* Returns non-zero if the cert/key filename should be handled through
     * the configured ENGINE. */
    int modssl_is_engine_id(const char *name);
    
    /* Set the renegotation state for connection. */
    void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state);
    
    #endif /* SSL_PRIVATE_H */
    /** @} */
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_io.c������������������������������������������������������������0000664�0001751�0001751�00000257317�14641543231�020076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "apr_date.h"
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, proxy_post_handshake,
                                        (conn_rec *c,SSL *ssl),
                                        (c,ssl),OK,DECLINED);
    
    /*  _________________________________________________________________
    **
    **  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;
        SSLConnRec         *config;
    } ssl_filter_ctx_t;
    
    typedef struct {
        ssl_filter_ctx_t *filter_ctx;
        conn_rec *c;
        apr_bucket_brigade *bb;    /* Brigade used as a buffer. */
        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);
    
        return outctx;
    }
    
    /* Pass an output brigade down the filter stack; returns 1 on success
     * or -1 on failure. */
    static int bio_filter_out_pass(bio_filter_out_ctx_t *outctx)
    {
        AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(outctx->bb));
    
        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;
    }
    
    /* Send a FLUSH bucket down the output filter stack; returns 1 on
     * success, -1 on failure. */
    static int bio_filter_out_flush(BIO *bio)
    {
        bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio);
        apr_bucket *e;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c,
                      "bio_filter_out_write: flush");
    
        AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(outctx->bb));
    
        e = apr_bucket_flush_create(outctx->bb->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(outctx->bb, e);
    
        return bio_filter_out_pass(outctx);
    }
    
    static int bio_filter_create(BIO *bio)
    {
        BIO_set_shutdown(bio, 1);
        BIO_set_init(bio, 1);
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        /* No setter method for OpenSSL 1.1.0 available,
         * but I can't find any functional use of the
         * "num" field there either.
         */
        bio->num = -1;
    #endif
        BIO_set_data(bio, 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 */
        bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c,
                      "BUG: %s() should not be called", "bio_filter_out_read");
        AP_DEBUG_ASSERT(0);
        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_get_data(bio);
        apr_bucket *e;
        int need_flush;
    
        BIO_clear_retry_flags(bio);
    
    #ifndef SSL_OP_NO_RENEGOTIATION
        /* Abort early if the client has initiated a renegotiation. */
        if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
            outctx->rc = APR_ECONNABORTED;
            return -1;
        }
    #endif
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c,
                      "bio_filter_out_write: %i bytes", inl);
    
        /* Use a transient bucket for the output data - any downstream
         * filter must setaside if necessary. */
        e = apr_bucket_transient_create(in, inl, outctx->bb->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(outctx->bb, e);
    
        /* In theory, OpenSSL should flush as necessary, but it is known
         * not to do so correctly in some cases (< 0.9.8m; see PR 46952),
         * or on the proxy/client side (after ssl23_client_hello(), e.g.
         * ssl/proxy.t test suite).
         *
         * Historically, this flush call was performed only for an SSLv2
         * connection or for a proxy connection.  Calling _out_flush can
         * be expensive in cases where requests/responses are pipelined,
         * so limit the performance impact to handshake time.
         */
    #if OPENSSL_VERSION_NUMBER < 0x0009080df
         need_flush = !SSL_is_init_finished(outctx->filter_ctx->pssl);
    #else
         need_flush = SSL_in_connect_init(outctx->filter_ctx->pssl);
    #endif
        if (need_flush) {
            e = apr_bucket_flush_create(outctx->bb->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(outctx->bb, e);
        }
    
        if (bio_filter_out_pass(outctx) < 0) {
            return -1;
        }
    
        return inl;
    }
    
    static long bio_filter_out_ctrl(BIO *bio, int cmd, long num, void *ptr)
    {
        long ret = 1;
        bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio);
    
        switch (cmd) {
        case BIO_CTRL_RESET:
        case BIO_CTRL_EOF:
        case BIO_C_SET_BUF_MEM_EOF_RETURN:
            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, outctx->c,
                          "output bio: unhandled control %d", cmd);
            ret = 0;
            break;
        case BIO_CTRL_WPENDING:
        case BIO_CTRL_PENDING:
        case BIO_CTRL_INFO:
            ret = 0;
            break;
        case BIO_CTRL_GET_CLOSE:
            ret = (long)BIO_get_shutdown(bio);
            break;
          case BIO_CTRL_SET_CLOSE:
            BIO_set_shutdown(bio, (int)num);
            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 */
        bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c,
                      "BUG: %s() should not be called", "bio_filter_out_gets");
        AP_DEBUG_ASSERT(0);
        return -1;
    }
    
    static int bio_filter_out_puts(BIO *bio, const char *str)
    {
        /* this is never called */
        bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c,
                      "BUG: %s() should not be called", "bio_filter_out_puts");
        AP_DEBUG_ASSERT(0);
        return -1;
    }
    
    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.
     */
    
    /* Copy up to INL bytes from the char_buffer BUFFER into IN.  Note
     * that due to the strange way this API is designed/used, the
     * char_buffer object is used to cache a segment of inctx->buffer, and
     * then this function called to copy (part of) that segment to the
     * beginning of inctx->buffer.  So the segments to copy cannot be
     * presumed to be non-overlapping, and memmove must be used. */
    static int char_buffer_read(char_buffer_t *buffer, char *in, int inl)
    {
        if (!buffer->length) {
            return 0;
        }
    
        if (buffer->length > inl) {
            /* we have enough to fill the caller's buffer */
            memmove(in, buffer->value, inl);
            buffer->value += inl;
            buffer->length -= inl;
        }
        else {
            /* swallow remainder of the buffer */
            memmove(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_get_data(bio);
        apr_read_type_e block = inctx->block;
    
        inctx->rc = APR_SUCCESS;
    
        /* OpenSSL catches this case, so should we. */
        if (!in)
            return 0;
    
        BIO_clear_retry_flags(bio);
    
    #ifndef SSL_OP_NO_RENEGOTIATION
        /* Abort early if the client has initiated a renegotiation. */
        if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
            inctx->rc = APR_ECONNABORTED;
            return -1;
        }
    #endif
    
        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 (block == APR_BLOCK_READ 
                && APR_STATUS_IS_TIMEUP(inctx->rc)
                && APR_BRIGADE_EMPTY(inctx->bb)) {
                /* don't give up, just return the timeout */
                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 int bio_filter_in_write(BIO *bio, const char *in, int inl)
    {
        bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c,
                      "BUG: %s() should not be called", "bio_filter_in_write");
        AP_DEBUG_ASSERT(0);
        return -1;
    }
    
    static int bio_filter_in_puts(BIO *bio, const char *str)
    {
        bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c,
                      "BUG: %s() should not be called", "bio_filter_in_puts");
        AP_DEBUG_ASSERT(0);
        return -1;
    }
    
    static int bio_filter_in_gets(BIO *bio, char *buf, int size)
    {
        bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c,
                      "BUG: %s() should not be called", "bio_filter_in_gets");
        AP_DEBUG_ASSERT(0);
        return -1;
    }
    
    static long bio_filter_in_ctrl(BIO *bio, int cmd, long num, void *ptr)
    {
        bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio);
        switch (cmd) {
    #ifdef BIO_CTRL_EOF
        case BIO_CTRL_EOF:
            return inctx->rc == APR_EOF;
    #endif
        default:
            break;
        }
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c,
                      "BUG: bio_filter_in_ctrl() should not be called with cmd=%i",
                      cmd);
        return 0;
    }
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
            
    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,
        NULL
    };
    
    static BIO_METHOD bio_filter_in_method = {
        BIO_TYPE_MEM,
        "APR input filter",
        bio_filter_in_write,        /* write is never called */
        bio_filter_in_read,
        bio_filter_in_puts,         /* puts is never called */
        bio_filter_in_gets,         /* gets is never called */
        bio_filter_in_ctrl,         /* ctrl is called for EOF check */
        bio_filter_create,
        bio_filter_destroy,
        NULL
    };
    
    #else
    
    static BIO_METHOD *bio_filter_out_method = NULL;
    static BIO_METHOD *bio_filter_in_method = NULL;
    
    void init_bio_methods(void)
    {
        bio_filter_out_method = BIO_meth_new(BIO_TYPE_MEM, "APR output filter");
        BIO_meth_set_write(bio_filter_out_method, &bio_filter_out_write);
        BIO_meth_set_read(bio_filter_out_method, &bio_filter_out_read); /* read is never called */
        BIO_meth_set_puts(bio_filter_out_method, &bio_filter_out_puts); /* puts is never called */
        BIO_meth_set_gets(bio_filter_out_method, &bio_filter_out_gets); /* gets is never called */
        BIO_meth_set_ctrl(bio_filter_out_method, &bio_filter_out_ctrl);
        BIO_meth_set_create(bio_filter_out_method, &bio_filter_create);
        BIO_meth_set_destroy(bio_filter_out_method, &bio_filter_destroy);
    
        bio_filter_in_method = BIO_meth_new(BIO_TYPE_MEM, "APR input filter");
        BIO_meth_set_write(bio_filter_in_method, &bio_filter_in_write); /* write is never called */
        BIO_meth_set_read(bio_filter_in_method, &bio_filter_in_read);
        BIO_meth_set_puts(bio_filter_in_method, &bio_filter_in_puts);   /* puts is never called */
        BIO_meth_set_gets(bio_filter_in_method, &bio_filter_in_gets);   /* gets is never called */
        BIO_meth_set_ctrl(bio_filter_in_method, &bio_filter_in_ctrl);   /* ctrl is never called */
        BIO_meth_set_create(bio_filter_in_method, &bio_filter_create);
        BIO_meth_set_destroy(bio_filter_in_method, &bio_filter_destroy);
    }
    
    void free_bio_methods(void)
    {
        BIO_meth_free(bio_filter_out_method);
        BIO_meth_free(bio_filter_in_method);
    }
    #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;
            }
    
            /* We rely on SSL_get_error() after the read, which requires an empty
             * error queue before the read in order to work properly.
             */
            ERR_clear_error();
    
            /* 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 /* (rc <= 0) */ {
                int ssl_err;
                conn_rec *c;
                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;
                            break;
                        }
                    }
                }
                ssl_err = SSL_get_error(inctx->filter_ctx->pssl, rc);
                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
                     * renegotiation 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 if (APR_STATUS_IS_TIMEUP(inctx->rc)) {
                        /* just return it, the calling layer might be fine with it,
                           and we do not want to bloat the log. */
                    }
                    else {
                        ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c, APLOGNO(01991)
                                      "SSL input filter read failed.");
                    }
                }
                else if (rc == 0 && ssl_err == SSL_ERROR_ZERO_RETURN) {
                    inctx->rc = APR_EOF;
                    break;
                }
                else /* if (ssl_err == SSL_ERROR_SSL) */ {
                    /*
                     * Log SSL errors and any unexpected conditions.
                     */
                    ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c, APLOGNO(01992)
                                  "SSL library error %d reading data", ssl_err);
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, mySrvFromConn(c));
    
                }
                if (rc == 0) {
                    inctx->rc = APR_EOF;
                    break;
                }
                if (inctx->rc == APR_SUCCESS) {
                    inctx->rc = APR_EGENERAL;
                }
                break;
            }
        }
        return inctx->rc;
    }
    
    /* Read a line of input from the SSL input layer into buffer BUF of
     * length *LEN; updating *len to reflect the length of the line
     * including the LF character. */
    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) {
                if (APR_STATUS_IS_EAGAIN(status) && (*len > 0)) {
                    /* Save the part of the line we already got */
                    char_buffer_write(&inctx->cbuf, buf, *len);
                }
                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;
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, f->c,
                      "ssl_filter_write: %"APR_SIZE_T_FMT" bytes", len);
    
        /* We rely on SSL_get_error() after the write, which requires an empty error
         * queue before the write in order to work properly.
         */
        ERR_clear_error();
    
        outctx = (bio_filter_out_ctx_t *)BIO_get_data(filter_ctx->pbioWrite);
        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
                 * renegotiation which is handled implicitly by OpenSSL.)
                 */
                outctx->rc = APR_EAGAIN;
            }
            else if (ssl_err == SSL_ERROR_WANT_READ) {
                /*
                 * If OpenSSL wants to read during write, and we were
                 * nonblocking, set the sense explicitly to read and
                 * report as an EAGAIN.
                 *
                 * (This is usually the case when the client forces an SSL
                 * renegotiation which is handled implicitly by OpenSSL.)
                 */
                outctx->c->cs->sense = CONN_SENSE_WANT_READ;
                outctx->rc = APR_EAGAIN;
                ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c,
                              "Want read during nonblocking write");
            }
            else if (ssl_err == SSL_ERROR_SYSCALL) {
                ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, APLOGNO(01993)
                              "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, APLOGNO(01994)
                              "SSL library error %d writing data", ssl_err);
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, mySrvFromConn(c));
            }
            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, APLOGNO(01995)
                          "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.
     * Since we use an HTTP/1.x request, we also have to inject the empty line
     * that terminates the headers, or the core will read more data from the
     * socket.
     */
    #define HTTP_ON_HTTPS_PORT \
        "GET / HTTP/1.0" CRLF
    
    #define HTTP_ON_HTTPS_PORT_BUCKET(alloc) \
        apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \
                                   sizeof(HTTP_ON_HTTPS_PORT) - 1, \
                                   alloc)
    
    /* Custom apr_status_t error code, used when a plain HTTP request is
     * received on an SSL port. */
    #define MODSSL_ERROR_HTTP_ON_HTTPS (APR_OS_START_USERERR + 0)
    
    /* Custom apr_status_t error code, used when the proxy cannot
     * establish an outgoing SSL connection. */
    #define MODSSL_ERROR_BAD_GATEWAY (APR_OS_START_USERERR + 1)
    
    static void ssl_io_filter_disable(SSLConnRec *sslconn,
                                      bio_filter_in_ctx_t *inctx)
    {
        SSL_free(inctx->ssl);
        sslconn->ssl = NULL;
        inctx->ssl = NULL;
        inctx->filter_ctx->pssl = NULL;
    }
    
    static apr_status_t ssl_io_filter_error(bio_filter_in_ctx_t *inctx,
                                            apr_bucket_brigade *bb,
                                            apr_status_t status,
                                            int is_init)
    {
        ap_filter_t *f = inctx->f;
        SSLConnRec *sslconn = myConnConfig(f->c);
        apr_bucket *bucket;
        int send_eos = 1;
    
        switch (status) {
        case MODSSL_ERROR_HTTP_ON_HTTPS:
                /* log the situation */
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, APLOGNO(01996)
                             "SSL handshake failed: HTTP spoken on HTTPS port; "
                             "trying to send HTML error page");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sslconn->server);
    
                ssl_io_filter_disable(sslconn, inctx);
                f->c->keepalive = AP_CONN_CLOSE;
                if (is_init) {
                    sslconn->non_ssl_request = NON_SSL_SEND_REQLINE;
                    return APR_EGENERAL;
                }
                sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP;
    
                /* fake the request line */
                bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
                send_eos = 0;
                break;
    
        case MODSSL_ERROR_BAD_GATEWAY:
            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, APLOGNO(01997)
                          "SSL handshake failed: sending 502");
            f->c->aborted = 1;
            return APR_EGENERAL;
    
        default:
            return status;
        }
    
        APR_BRIGADE_INSERT_TAIL(bb, bucket);
        if (send_eos) {
            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";
    static const char ssl_io_buffer[] = "SSL/TLS Buffer";
    static const char ssl_io_coalesce[] = "SSL/TLS Coalescing Filter";
    
    /*
     *  Close the SSL part of the socket connection
     *  (called immediately _before_ the socket is closed)
     *  or called with
     */
    static void 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;
        int loglevel = APLOG_DEBUG;
        const char *logno;
    
        if (!ssl) {
            return;
        }
    
        /*
         * 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";
            logno = APLOGNO(01998);
            loglevel = APLOG_INFO;
        }
        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";
            logno = APLOGNO(01999);
            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";
            logno = APLOGNO(02000);
            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";
            logno = APLOGNO(02001);
            break;
        }
    
        SSL_set_shutdown(ssl, shutdown_type);
        modssl_smart_shutdown(ssl);
    
        /* and finally log the fact that we've closed the connection */
        if (APLOG_CS_IS_LEVEL(c, mySrvFromConn(c), loglevel)) {
            /* Intentional no APLOGNO */
            /* logno provides APLOGNO */
            ap_log_cserror(APLOG_MARK, loglevel, 0, c, mySrvFromConn(c),
                           "%sConnection closed to child %ld with %s shutdown "
                           "(server %s)",
                           logno, c->id, type,
                           ssl_util_vhostid(c->pool, mySrvFromConn(c)));
        }
    
        /* 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;
        }
    }
    
    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.
     */
    
    /* Perform the SSL handshake (whether in client or server mode), if
     * necessary, for the given connection. */
    static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
    {
        conn_rec *c         = (conn_rec *)SSL_get_app_data(filter_ctx->pssl);
        SSLConnRec *sslconn = myConnConfig(c);
        SSLSrvConfigRec *sc;
        X509 *cert;
        int n;
        int ssl_err;
        long verify_result;
        server_rec *server;
    
        if (SSL_is_init_finished(filter_ctx->pssl)) {
            return APR_SUCCESS;
        }
    
        server = sslconn->server;
        if (c->outgoing) {
    #ifdef HAVE_TLSEXT
            apr_ipsubnet_t *ip;
    #ifdef HAVE_TLS_ALPN
            const char *alpn_note;
            apr_array_header_t *alpn_proposed = NULL;
            int alpn_empty_ok = 1;
    #endif
    #endif
            const char *hostname_note = apr_table_get(c->notes,
                                                      "proxy-request-hostname");
            BOOL proxy_ssl_check_peer_ok = TRUE;
            int post_handshake_rc = OK;
            SSLDirConfigRec *dc;
    
            dc = sslconn->dc;
            sc = mySrvConfig(server);
    
    #ifdef HAVE_TLSEXT
    #ifdef HAVE_TLS_ALPN
            alpn_note = apr_table_get(c->notes, "proxy-request-alpn-protos");
            if (alpn_note) {
                char *protos, *s, *p, *last, *proto;
                apr_size_t len;
    
                /* Transform the note into a protocol formatted byte array:
                 * (len-byte proto-char+)*
                 * We need the remote server to agree on one of these, unless 'http/1.1'
                 * is also among our proposals. Because pre-ALPN remotes will speak this.
                 */
                alpn_proposed = apr_array_make(c->pool, 3, sizeof(const char*));
                alpn_empty_ok = 0;
                s = protos = apr_pcalloc(c->pool, strlen(alpn_note)+1);
                p = apr_pstrdup(c->pool, alpn_note);
                while ((p = apr_strtok(p, ", ", &last))) {
                    len = last - p - (*last? 1 : 0); 
                    if (len > 255) {
                        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03309)
                                      "ALPN proxy protocol identifier too long: %s",
                                      p);
                        ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
                        return APR_EGENERAL;
                    }
                    proto = apr_pstrndup(c->pool, p, len);
                    APR_ARRAY_PUSH(alpn_proposed, const char*) = proto;
                    if (!strcmp("http/1.1", proto)) {
                        alpn_empty_ok = 1;
                    }
                    *s++ = (unsigned char)len;
                    while (len--) {
                        *s++ = *p++;
                    }
                    p = NULL;
                }
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, 
                              "setting alpn protos from '%s', protolen=%d", 
                              alpn_note, (int)(s - protos));
                if (protos != s && SSL_set_alpn_protos(filter_ctx->pssl, 
                                                       (unsigned char *)protos, 
                                                       s - protos)) {
                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(03310)
                                  "error setting alpn protos from '%s'", alpn_note);
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_WARNING, server);
                    /* If ALPN was requested and we cannot do it, we must fail */
                    return MODSSL_ERROR_BAD_GATEWAY;
                }
            }
    #endif /* defined HAVE_TLS_ALPN */
            /*
             * Enable SNI for backend requests. Make sure we don't do it for
             * pure SSLv3 connections, and also prevent IP addresses
             * from being included in the SNI extension. (OpenSSL would simply
             * pass them on, but RFC 6066 is quite clear on this: "Literal
             * IPv4 and IPv6 addresses are not permitted".)
             */
            if (hostname_note &&
    #ifndef OPENSSL_NO_SSL3
                dc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&
    #endif
                apr_ipsubnet_create(&ip, hostname_note, NULL,
                                    c->pool) != APR_SUCCESS) {
                if (SSL_set_tlsext_host_name(filter_ctx->pssl, hostname_note)) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                                  "SNI extension for SSL Proxy request set to '%s'",
                                  hostname_note);
                } else {
                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(02002)
                                  "Failed to set SNI extension for SSL Proxy "
                                  "request to '%s'", hostname_note);
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_WARNING, server);
                }
            }
    #endif /* defined HAVE_TLSEXT */
    
            if ((n = SSL_connect(filter_ctx->pssl)) <= 0) {
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02003)
                              "SSL Proxy connect failed");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
                /* ensure that the SSL structures etc are freed, etc: */
                ssl_filter_io_shutdown(filter_ctx, c, 1);
                apr_table_setn(c->notes, "SSL_connect_rv", "err");
                return MODSSL_ERROR_BAD_GATEWAY;
            }
    
            cert = SSL_get_peer_certificate(filter_ctx->pssl);
    
            if (dc->proxy->ssl_check_peer_expire != FALSE) {
                if (!cert
                    || (X509_cmp_current_time(
                         X509_get_notBefore(cert)) >= 0)
                    || (X509_cmp_current_time(
                         X509_get_notAfter(cert)) <= 0)) {
                    proxy_ssl_check_peer_ok = FALSE;
                    ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02004)
                                  "SSL Proxy: Peer certificate is expired");
                }
            }
            if ((dc->proxy->ssl_check_peer_name != FALSE) &&
                ((dc->proxy->ssl_check_peer_cn != FALSE) ||
                 (dc->proxy->ssl_check_peer_name == TRUE)) &&
                hostname_note) {
                if (!cert
                    || modssl_X509_match_name(c->pool, cert, hostname_note,
                                              TRUE, server) == FALSE) {
                    proxy_ssl_check_peer_ok = FALSE;
                    ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02411)
                                  "SSL Proxy: Peer certificate does not match "
                                  "for hostname %s", hostname_note);
                }
            }
            else if ((dc->proxy->ssl_check_peer_cn == TRUE) &&
                hostname_note) {
                const char *hostname;
                int match = 0;
    
                hostname = ssl_var_lookup(NULL, server, c, NULL,
                                          "SSL_CLIENT_S_DN_CN");
    
                /* Do string match or simplest wildcard match if that
                 * fails. */
                match = strcasecmp(hostname, hostname_note) == 0;
                if (!match && strncmp(hostname, "*.", 2) == 0) {
                    const char *p = ap_strchr_c(hostname_note, '.');
                    
                    match = p && strcasecmp(p, hostname + 1) == 0;
                }
    
                if (!match) {
                    proxy_ssl_check_peer_ok = FALSE;
                    ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02005)
                                  "SSL Proxy: Peer certificate CN mismatch:"
                                  " Certificate CN: %s Requested hostname: %s",
                                  hostname, hostname_note);
                }
            }
    
    #ifdef HAVE_TLS_ALPN
            /* If we proposed ALPN protocol(s), we need to check if the server
             * agreed to one of them. While <https://www.rfc-editor.org/rfc/rfc7301.txt>
             * chapter 3.2 says the server SHALL error the handshake in such a case,
             * the reality is that some servers fall back to their default, e.g. http/1.1.
             * (we also do this right now)
             * We need to treat this as an error for security reasons.
             */
            if (alpn_proposed && alpn_proposed->nelts > 0) {
                const char *selected;
                unsigned int slen;
    
                SSL_get0_alpn_selected(filter_ctx->pssl, (const unsigned char**)&selected, &slen);
                if (!selected || !slen) {
                    /* No ALPN selection reported by the remote server. This could mean
                     * it does not support ALPN (old server) or that it does not support
                     * any of our proposals (Apache itself up to 2.4.48 at least did that). */
                   if (!alpn_empty_ok) {
                        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(10273)
                                      "SSL Proxy: Peer did not select any of our ALPN protocols [%s].",
                                      alpn_note);
                        proxy_ssl_check_peer_ok = FALSE;
                   }
                }
                else {
                    const char *proto;
                    int i, found = 0;
                    for (i = 0; !found && i < alpn_proposed->nelts; ++i) {
                        proto = APR_ARRAY_IDX(alpn_proposed, i, const char *);
                        found = !strncmp(selected, proto, slen);
                    }
                    if (!found) {
                        /* From a conforming peer, this should never happen,
                         * but life always finds a way... */
                        proto = apr_pstrndup(c->pool, selected, slen);
                        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(10274)
                                      "SSL Proxy: Peer proposed ALPN protocol %s which is none "
                                      "of our proposals [%s].", proto, alpn_note);
                        proxy_ssl_check_peer_ok = FALSE;
                    }
                }
            }
    #endif
    
            if (proxy_ssl_check_peer_ok == TRUE) {
                /* another chance to fail */
                post_handshake_rc = ssl_run_proxy_post_handshake(c, filter_ctx->pssl);
            }
    
            if (cert) {
                X509_free(cert);
            }
    
            if (proxy_ssl_check_peer_ok != TRUE
                || (post_handshake_rc != OK && post_handshake_rc != DECLINED)) {
                /* ensure that the SSL structures etc are freed, etc: */
                ssl_filter_io_shutdown(filter_ctx, c, 1);
                apr_table_setn(c->notes, "SSL_connect_rv", "err");
                return MODSSL_ERROR_BAD_GATEWAY;
            }
    
            apr_table_setn(c->notes, "SSL_connect_rv", "ok");
            return APR_SUCCESS;
        }
    
        /* We rely on SSL_get_error() after the accept, which requires an empty
         * error queue before the accept in order to work properly.
         */
        ERR_clear_error();
    
        if ((n = SSL_accept(filter_ctx->pssl)) <= 0) {
            bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)
                                         BIO_get_data(filter_ctx->pbioRead);
            bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)
                                           BIO_get_data(filter_ctx->pbioWrite);
            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, APLOGNO(02006)
                             "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 APR_EAGAIN;
            }
            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 MODSSL_ERROR_HTTP_ON_HTTPS;
            }
            else if (ssl_err == SSL_ERROR_SYSCALL) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rc, c, APLOGNO(02007)
                              "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, APLOGNO(02008)
                              "SSL library error %d in handshake "
                              "(server %s)", ssl_err,
                              ssl_util_vhostid(c->pool, server));
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
    
            }
            if (inctx->rc == APR_SUCCESS) {
                inctx->rc = APR_EGENERAL;
            }
    
            ssl_filter_io_shutdown(filter_ctx, c, 1);
            return inctx->rc;
        }
        sc = mySrvConfig(sslconn->server);
    
        /*
         * 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, APLOGNO(02009)
                              "SSL client authentication failed, "
                              "accepting certificate based on "
                              "\"SSLVerifyClient optional_no_ca\" "
                              "configuration");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, 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, APLOGNO(02010)
                             "SSL client authentication failed: %s",
                             error ? error : "unknown");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
    
                ssl_filter_io_shutdown(filter_ctx, c, 1);
                return APR_ECONNABORTED;
            }
        }
    
        /*
         * 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, APLOGNO(02011)
                          "No acceptable peer certificate available");
    
            ssl_filter_io_shutdown(filter_ctx, c, 1);
            return APR_ECONNABORTED;
        }
    
        return APR_SUCCESS;
    }
    
    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;
        const char *start = inctx->buffer; /* start of block to return */
        apr_size_t len = sizeof(inctx->buffer); /* length of block to return */
        int is_init = (mode == AP_MODE_INIT);
        apr_bucket *bucket;
    
        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.
             */
            bucket = apr_bucket_eos_create(f->c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, bucket);
            return APR_ECONNABORTED;
        }
    
        if (!inctx->ssl) {
            SSLConnRec *sslconn = myConnConfig(f->c);
            if (sslconn->non_ssl_request == NON_SSL_SEND_REQLINE) {
                bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, bucket);
                if (mode != AP_MODE_SPECULATIVE) {
                    sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP;
                }
                return APR_SUCCESS;
            }
            if (sslconn->non_ssl_request == NON_SSL_SEND_HDR_SEP) {
                bucket = apr_bucket_immortal_create(CRLF, 2, f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, bucket);
                if (mode != AP_MODE_SPECULATIVE) {
                    sslconn->non_ssl_request = NON_SSL_SET_ERROR_MSG;
                }
                return APR_SUCCESS;
            }
            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_handshake 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_handshake(inctx->filter_ctx)) != APR_SUCCESS) {
            return ssl_io_filter_error(inctx, bb, status, is_init);
        }
    
        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) {
            const char *pos;
    
            /* Satisfy the read directly out of the buffer if possible;
             * invoking ssl_io_input_getline will mean the entire buffer
             * is copied once (unnecessarily) for each GETLINE call. */
            if (inctx->cbuf.length
                && (pos = memchr(inctx->cbuf.value, APR_ASCII_LF,
                                 inctx->cbuf.length)) != NULL) {
                start = inctx->cbuf.value;
                len = 1 + pos - start; /* +1 to include LF */
                /* Buffer contents now consumed. */
                inctx->cbuf.value += len;
                inctx->cbuf.length -= len;
                status = APR_SUCCESS;
            }
            else {
                /* Otherwise fall back to the hard way. */
                status = ssl_io_input_getline(inctx, inctx->buffer, &len);
            }
        }
        else {
            /* We have no idea what you are talking about, so return an error. */
            status = APR_ENOTIMPL;
        }
    
        /* It is possible for mod_ssl's BIO to be used outside of the
         * direct control of mod_ssl's input or output filter -- notably,
         * when mod_ssl initiates a renegotiation.  Switching the BIO mode
         * back to "blocking" here ensures such operations don't fail with
         * SSL_ERROR_WANT_READ. */
        inctx->block = APR_BLOCK_READ;
    
        /* Handle custom errors. */
        if (status != APR_SUCCESS) {
            return ssl_io_filter_error(inctx, bb, status, 0);
        }
    
        /* Create a transient bucket out of the decrypted data. */
        if (len > 0) {
            bucket =
                apr_bucket_transient_create(start, len, f->c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, bucket);
        }
    
        return APR_SUCCESS;
    }
    
    
    /* ssl_io_filter_output() produces one SSL/TLS record per bucket
     * passed down the output filter stack.  This results in a high
     * overhead (more network packets & TLS processing) for any output
     * comprising many small buckets.  SSI output passed through the HTTP
     * chunk filter, for example, may produce many brigades containing
     * small buckets - [chunk-size CRLF] [chunk-data] [CRLF].
     *
     * Sending HTTP response headers as a separate TLS record to the
     * response body also reveals information to a network observer (the
     * size of headers) which can be significant.
     *
     * The coalescing filter merges data buckets with the aim of producing
     * fewer, larger TLS records - without copying/buffering all content
     * and introducing unnecessary overhead.
     *
     * ### This buffering could be probably be done more comprehensively
     * ### in ssl_io_filter_output itself. 
     * 
     * ### Another possible performance optimisation in particular for the
     * ### [HEAP] [FILE] HTTP response case is using a brigade rather than
     * ### a char array to buffer; using apr_brigade_write() to append
     * ### will use already-allocated memory from the HEAP, reducing # of
     * ### copies.
     */
    
    #define COALESCE_BYTES (AP_IOBUFSIZE)
    
    struct coalesce_ctx {
        char buffer[COALESCE_BYTES];
        apr_size_t bytes; /* number of bytes of buffer used. */
    };
    
    static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
                                               apr_bucket_brigade *bb)
    {
        apr_bucket *e, *upto;
        apr_size_t bytes = 0;
        struct coalesce_ctx *ctx = f->ctx;
        apr_size_t buffered = ctx ? ctx->bytes : 0; /* space used on entry */
        unsigned count = 0;
    
        /* The brigade consists of zero-or-more small data buckets which
         * can be coalesced (referred to as the "prefix"), followed by the
         * remainder of the brigade.
         *
         * Find the last bucket - if any - of that prefix.  count gives
         * the number of buckets in the prefix.  The "prefix" must contain
         * only data buckets with known length, and must be of a total
         * size which fits into the buffer.
         *
         * N.B.: The process here could be repeated throughout the brigade
         * (coalesce any run of consecutive data buckets) but this would
         * add significant complexity, particularly to memory
         * management. */
        for (e = APR_BRIGADE_FIRST(bb);
             e != APR_BRIGADE_SENTINEL(bb)
                 && !APR_BUCKET_IS_METADATA(e)
                 && e->length != (apr_size_t)-1
                 && e->length <= COALESCE_BYTES
                 && (buffered + bytes + e->length) <= COALESCE_BYTES;
             e = APR_BUCKET_NEXT(e)) {
            /* don't count zero-length buckets */
            if (e->length) {
                bytes += e->length;
                count++;
            }
        }
    
        /* If there is room remaining and the next bucket is a data
         * bucket, try to include it in the prefix to coalesce.  For a
         * typical [HEAP] [FILE] HTTP response brigade, this handles
         * merging the headers and the start of the body into a single TLS
         * record. */
        if (bytes + buffered > 0
            && bytes + buffered < COALESCE_BYTES
            && e != APR_BRIGADE_SENTINEL(bb)
            && !APR_BUCKET_IS_METADATA(e)) {
            apr_status_t rv = APR_SUCCESS;
    
            /* For an indeterminate length bucket (PIPE/CGI/...), try a
             * non-blocking read to have it morph into a HEAP.  If the
             * read fails with EAGAIN, it is harmless to try a split
             * anyway, split is ENOTIMPL for most PIPE-like buckets. */
            if (e->length == (apr_size_t)-1) {
                const char *discard;
                apr_size_t ignore;
    
                rv = apr_bucket_read(e, &discard, &ignore, APR_NONBLOCK_READ);
                if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10232)
                                  "coalesce failed to read from %s bucket",
                                  e->type->name);
                    return AP_FILTER_ERROR;
                }
            }
    
            if (rv == APR_SUCCESS) {
                /* If the read above made the bucket morph, it may now fit
                 * entirely within the buffer.  Otherwise, split it so it does
                 * fit. */
                if (e->length > COALESCE_BYTES
                    || e->length + buffered + bytes > COALESCE_BYTES) {
                    rv = apr_bucket_split(e, COALESCE_BYTES - (buffered + bytes));
                }
    
                if (rv == APR_SUCCESS && e->length == 0) {
                    /* As above, don't count in the prefix if the bucket is
                     * now zero-length. */
                }
                else if (rv == APR_SUCCESS) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
                                  "coalesce: adding %" APR_SIZE_T_FMT " bytes "
                                  "from split %s bucket, total %" APR_SIZE_T_FMT,
                                  e->length, e->type->name, bytes + buffered);
    
                    count++;
                    bytes += e->length;
                    e = APR_BUCKET_NEXT(e);
                }
                else if (rv != APR_ENOTIMPL) {
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10233)
                                  "coalesce: failed to split data bucket");
                    return AP_FILTER_ERROR;
                }
            }
        }
    
        /* The prefix is zero or more buckets.  upto now points to the
         * bucket AFTER the end of the prefix, which may be the brigade
         * sentinel. */
        upto = e;
    
        /* Coalesce the prefix, if any of the following are true:
         * 
         * a) the prefix is more than one bucket
         * OR
         * b) the prefix is the entire brigade, which is a single bucket
         *    AND the prefix length is smaller than the buffer size,
         * OR
         * c) the prefix is a single bucket
         *    AND there is buffered data from a previous pass.
         * 
         * The aim with (b) is to buffer a small bucket so it can be
         * coalesced with future invocations of this filter.  e.g.  three
         * calls each with a single 100 byte HEAP bucket should get
         * coalesced together.  But an invocation with a 8192 byte HEAP
         * should pass through untouched.
         */
        if (bytes > 0
            && (count > 1
                || (upto == APR_BRIGADE_SENTINEL(bb)
                    && bytes < COALESCE_BYTES)
                || (ctx && ctx->bytes > 0))) {
            /* If coalescing some bytes, ensure a context has been
             * created. */
            if (!ctx) {
                f->ctx = ctx = apr_palloc(f->c->pool, sizeof *ctx);
                ctx->bytes = 0;
            }
    
            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
                          "coalesce: have %" APR_SIZE_T_FMT " bytes, "
                          "adding %" APR_SIZE_T_FMT " more (buckets=%u)",
                          ctx->bytes, bytes, count);
    
            /* Iterate through the prefix segment.  For non-fatal errors
             * in this loop it is safe to break out and fall back to the
             * normal path of sending the buffer + remaining buckets in
             * brigade.  */
            e = APR_BRIGADE_FIRST(bb);
            while (e != upto) {
                apr_size_t len;
                const char *data;
                apr_bucket *next;
    
                if (APR_BUCKET_IS_METADATA(e)
                    || e->length == (apr_size_t)-1) {
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(02012)
                                  "unexpected %s bucket during coalesce",
                                  e->type->name);
                    break; /* non-fatal error; break out */
                }
    
                if (e->length) {
                    apr_status_t rv;
    
                    /* A blocking read should be fine here for a
                     * known-length data bucket, rather than the usual
                     * non-block/flush/block.  */
                    rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
                    if (rv) {
                        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(02013)
                                      "coalesce failed to read from data bucket");
                        return AP_FILTER_ERROR;
                    }
    
                    /* Be paranoid. */
                    if (len > sizeof ctx->buffer
                        || (len + ctx->bytes > sizeof ctx->buffer)) {
                        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(02014)
                                      "unexpected coalesced bucket data length");
                        break; /* non-fatal error; break out */
                    }
    
                    memcpy(ctx->buffer + ctx->bytes, data, len);
                    ctx->bytes += len;
                }
    
                next = APR_BUCKET_NEXT(e);
                apr_bucket_delete(e);
                e = next;
            }
        }
    
        if (APR_BRIGADE_EMPTY(bb)) {
            /* If the brigade is now empty, our work here is done. */
            return APR_SUCCESS;
        }
    
        /* If anything remains in the brigade, it must now be passed down
         * the filter stack, first prepending anything that has been
         * coalesced. */
        if (ctx && ctx->bytes) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
                          "coalesce: passing on %" APR_SIZE_T_FMT " bytes", ctx->bytes);
    
            e = apr_bucket_transient_create(ctx->buffer, ctx->bytes, bb->bucket_alloc);
            APR_BRIGADE_INSERT_HEAD(bb, e);
            ctx->bytes = 0; /* buffer now emptied. */
        }
    
        return ap_pass_brigade(f->next, bb);
    }
    
    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 *)BIO_get_data(filter_ctx->pbioRead);
        outctx = (bio_filter_out_ctx_t *)BIO_get_data(filter_ctx->pbioWrite);
    
        /* 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_handshake(filter_ctx)) != APR_SUCCESS) {
            return ssl_io_filter_error(inctx, bb, status, 0);
        }
    
        while (!APR_BRIGADE_EMPTY(bb) && status == APR_SUCCESS) {
            apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
    
            if (APR_BUCKET_IS_METADATA(bucket)) {
                /* Pass through metadata buckets untouched.  EOC is
                 * special; terminate the SSL layer first. */
                if (AP_BUCKET_IS_EOC(bucket)) {
                    ssl_filter_io_shutdown(filter_ctx, f->c, 0);
                }
                AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(outctx->bb));
    
                /* Metadata buckets are passed one per brigade; it might
                 * be more efficient (but also more complex) to use
                 * outctx->bb as a true buffer and interleave these with
                 * data buckets. */
                APR_BUCKET_REMOVE(bucket);
                APR_BRIGADE_INSERT_HEAD(outctx->bb, bucket);
                status = ap_pass_brigade(f->next, outctx->bb);
                if (status == APR_SUCCESS && f->c->aborted)
                    status = APR_ECONNRESET;
                apr_brigade_cleanup(outctx->bb);
            }
            else {
                /* Filter a data bucket. */
                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;
                    /* and try again with a blocking read. */
                    status = APR_SUCCESS;
                    continue;
                }
    
                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);
            }
    
        }
    
        return status;
    }
    
    struct modssl_buffer_ctx {
        apr_bucket_brigade *bb;
    };
    
    int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen)
    {
        conn_rec *c = r->connection;
        struct modssl_buffer_ctx *ctx;
        apr_bucket_brigade *tempb;
        apr_off_t total = 0; /* total length buffered */
        int eos = 0; /* non-zero once EOS is seen */
    
        /* Create the context which will be passed to the input filter;
         * containing a setaside pool and a brigade which constrain the
         * lifetime of the buffered data. */
        ctx = apr_palloc(r->pool, sizeof *ctx);
        ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
    
        /* ... and a temporary brigade. */
        tempb = apr_brigade_create(r->pool, c->bucket_alloc);
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, c, "filling buffer, max size "
                      "%" APR_SIZE_T_FMT " bytes", maxlen);
    
        do {
            apr_status_t rv;
            apr_bucket *e, *next;
    
            /* The request body is read from the protocol-level input
             * filters; the buffering filter will reinject it from that
             * level, allowing content/resource filters to run later, if
             * necessary. */
    
            rv = ap_get_brigade(r->proto_input_filters, tempb, AP_MODE_READBYTES,
                                APR_BLOCK_READ, 8192);
            if (rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02015)
                              "could not read request body for SSL buffer");
                return ap_map_http_request_error(rv, HTTP_INTERNAL_SERVER_ERROR);
            }
    
            /* Iterate through the returned brigade: setaside each bucket
             * into the context's pool and move it into the brigade. */
            for (e = APR_BRIGADE_FIRST(tempb);
                 e != APR_BRIGADE_SENTINEL(tempb) && !eos; e = next) {
                const char *data;
                apr_size_t len;
    
                next = APR_BUCKET_NEXT(e);
    
                if (APR_BUCKET_IS_EOS(e)) {
                    eos = 1;
                } else if (!APR_BUCKET_IS_METADATA(e)) {
                    rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02016)
                                      "could not read bucket for SSL buffer");
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                    total += len;
                }
    
                rv = apr_bucket_setaside(e, r->pool);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02017)
                                  "could not setaside bucket for SSL buffer");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
            }
    
            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, c,
                          "total of %" APR_OFF_T_FMT " bytes in buffer, eos=%d",
                          total, eos);
    
            /* Fail if this exceeds the maximum buffer size. */
            if (total > maxlen) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02018)
                              "request body exceeds maximum size (%" APR_SIZE_T_FMT
                              ") for SSL buffer", maxlen);
                return HTTP_REQUEST_ENTITY_TOO_LARGE;
            }
    
        } while (!eos);
    
        apr_brigade_destroy(tempb);
    
        /* After consuming all protocol-level input, remove all protocol-level
         * filters.  It should strictly only be necessary to remove filters
         * at exactly ftype == AP_FTYPE_PROTOCOL, since this filter will
         * precede all > AP_FTYPE_PROTOCOL anyway. */
        while (r->proto_input_filters->frec->ftype < AP_FTYPE_CONNECTION) {
            ap_remove_input_filter(r->proto_input_filters);
        }
    
        /* Insert the filter which will supply the buffered content. */
        ap_add_input_filter(ssl_io_buffer, ctx, r, c);
    
        return 0;
    }
    
    /* This input filter supplies the buffered request body to the caller
     * from the brigade stored in f->ctx.  Note that the placement of this
     * filter in the filter stack is important; it must be the first
     * r->proto_input_filter; lower-typed filters will not be preserved
     * across internal redirects (see PR 43738).  */
    static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
                                             apr_bucket_brigade *bb,
                                             ap_input_mode_t mode,
                                             apr_read_type_e block,
                                             apr_off_t bytes)
    {
        struct modssl_buffer_ctx *ctx = f->ctx;
        apr_status_t rv;
        apr_bucket *e, *d;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
                      "read from buffered SSL brigade, mode %d, "
                      "%" APR_OFF_T_FMT " bytes",
                      mode, bytes);
    
        if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
            return APR_ENOTIMPL;
        }
    
        if (APR_BRIGADE_EMPTY(ctx->bb)) {
            /* Surprisingly (and perhaps, wrongly), the request body can be
             * pulled from the input filter stack more than once; a
             * handler may read it, and ap_discard_request_body() will
             * attempt to do so again after *every* request.  So input
             * filters must be prepared to give up an EOS if invoked after
             * initially reading the request. The HTTP_IN filter does this
             * with its ->eos_sent flag. */
    
            APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_eos_create(f->c->bucket_alloc));
            return APR_SUCCESS;
        }
    
        if (mode == AP_MODE_READBYTES) {
            /* Partition the buffered brigade. */
            rv = apr_brigade_partition(ctx->bb, bytes, &e);
            if (rv && rv != APR_INCOMPLETE) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(02019)
                              "could not partition buffered SSL brigade");
                ap_remove_input_filter(f);
                return rv;
            }
    
            /* If the buffered brigade contains less then the requested
             * length, just pass it all back. */
            if (rv == APR_INCOMPLETE) {
                APR_BRIGADE_CONCAT(bb, ctx->bb);
            } else {
                d = APR_BRIGADE_FIRST(ctx->bb);
    
                e = APR_BUCKET_PREV(e);
    
                /* Unsplice the partitioned segment and move it into the
                 * passed-in brigade; no convenient way to do this with
                 * the APR_BRIGADE_* macros. */
                APR_RING_UNSPLICE(d, e, link);
                APR_RING_SPLICE_HEAD(&bb->list, d, e, apr_bucket, link);
    
                APR_BRIGADE_CHECK_CONSISTENCY(bb);
                APR_BRIGADE_CHECK_CONSISTENCY(ctx->bb);
            }
        }
        else {
            /* Split a line into the passed-in brigade. */
            rv = apr_brigade_split_line(bb, ctx->bb, block, bytes);
    
            if (rv) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(02020)
                              "could not split line from buffered SSL brigade");
                ap_remove_input_filter(f);
                return rv;
            }
        }
    
        if (APR_BRIGADE_EMPTY(ctx->bb)) {
            e = APR_BRIGADE_LAST(bb);
    
            /* Ensure that the brigade is terminated by an EOS if the
             * buffered request body has been entirely consumed. */
            if (e == APR_BRIGADE_SENTINEL(bb) || !APR_BUCKET_IS_EOS(e)) {
                e = apr_bucket_eos_create(f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, e);
            }
    
            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
                          "buffered SSL brigade exhausted");
            /* Note that the filter must *not* be removed here; it may be
             * invoked again, see comment above. */
        }
    
        return APR_SUCCESS;
    }
    
    /* The request_rec pointer is passed in here only to ensure that the
     * filter chain is modified correctly when doing a TLS upgrade.  It
     * must *not* be used otherwise. */
    static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c,
                                        request_rec *r, 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, r, c);
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        filter_ctx->pbioRead = BIO_new(&bio_filter_in_method);
    #else
        filter_ctx->pbioRead = BIO_new(bio_filter_in_method);
    #endif
        BIO_set_data(filter_ctx->pbioRead, (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;
    }
    
    /* The request_rec pointer is passed in here only to ensure that the
     * filter chain is modified correctly when doing a TLS upgrade.  It
     * must *not* be used otherwise. */
    void ssl_io_filter_init(conn_rec *c, request_rec *r, SSL *ssl)
    {
        ssl_filter_ctx_t *filter_ctx;
    
        filter_ctx = apr_palloc(c->pool, sizeof(ssl_filter_ctx_t));
    
        filter_ctx->config          = myConnConfig(c);
    
        ap_add_output_filter(ssl_io_coalesce, NULL, r, c);
    
        filter_ctx->pOutputFilter   = ap_add_output_filter(ssl_io_filter,
                                                           filter_ctx, r, c);
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
        filter_ctx->pbioWrite       = BIO_new(&bio_filter_out_method);
    #else
        filter_ctx->pbioWrite       = BIO_new(bio_filter_out_method);
    #endif
        BIO_set_data(filter_ctx->pbioWrite, (void *)bio_filter_out_ctx_new(filter_ctx, c));
    
        /* write is non blocking for the benefit of async mpm */
        if (c->cs) {
            BIO_set_nbio(filter_ctx->pbioWrite, 1);
            ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, c,
                          "Enabling non-blocking writes");
        }
    
        ssl_io_input_add_filter(filter_ctx, c, r, 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);
    
        modssl_set_io_callbacks(ssl, c, mySrvFromConn(c));
    
        return;
    }
    
    void ssl_io_filter_register(apr_pool_t *p)
    {
        ap_register_input_filter  (ssl_io_filter, ssl_io_filter_input,  NULL, AP_FTYPE_CONNECTION + 5);
        ap_register_output_filter (ssl_io_coalesce, ssl_io_filter_coalesce, NULL, AP_FTYPE_CONNECTION + 4);
        ap_register_output_filter (ssl_io_filter, ssl_io_filter_output, NULL, AP_FTYPE_CONNECTION + 5);
    
        ap_register_input_filter  (ssl_io_buffer, ssl_io_filter_buffer, NULL, AP_FTYPE_PROTOCOL);
    
        return;
    }
    
    /*  _________________________________________________________________
    **
    **  I/O Data Debugging
    **  _________________________________________________________________
    */
    
    #define DUMP_WIDTH 16
    
    static void ssl_io_data_dump(conn_rec *c, server_rec *s,
                                 const char *b, int len)
    {
        char buf[256];
        int i, j, rows, trunc, pos;
        unsigned char ch;
    
        trunc = 0;
        for (; (len > 0) && ((b[len-1] == ' ') || (b[len-1] == '\0')); len--)
            trunc++;
        rows = (len / DUMP_WIDTH);
        if ((rows * DUMP_WIDTH) < len)
            rows++;
        ap_log_cserror(APLOG_MARK, APLOG_TRACE7, 0, c, s,
                "+-------------------------------------------------------------------------+");
        for (i = 0 ; i < rows; i++) {
    #if APR_CHARSET_EBCDIC
            char ebcdic_text[DUMP_WIDTH];
            j = DUMP_WIDTH;
            if ((i * DUMP_WIDTH + j) > len)
                j = len % DUMP_WIDTH;
            if (j == 0)
                j = DUMP_WIDTH;
            memcpy(ebcdic_text,(char *)(b) + i * DUMP_WIDTH, j);
            ap_xlate_proto_from_ascii(ebcdic_text, j);
    #endif /* APR_CHARSET_EBCDIC */
            pos = 0;
            pos += apr_snprintf(buf, sizeof(buf)-pos, "| %04x: ", i * DUMP_WIDTH);
            for (j = 0; j < DUMP_WIDTH; j++) {
                if (((i * DUMP_WIDTH) + j) >= len)
                    pos += apr_snprintf(buf+pos, sizeof(buf)-pos, "   ");
                else {
                    ch = ((unsigned char)*((char *)(b) + i * DUMP_WIDTH + j)) & 0xff;
                    pos += apr_snprintf(buf+pos, sizeof(buf)-pos, "%02x%c", ch , j==7 ? '-' : ' ');
                }
            }
            pos += apr_snprintf(buf+pos, sizeof(buf)-pos, " ");
            for (j = 0; j < DUMP_WIDTH; j++) {
                if (((i * DUMP_WIDTH) + j) >= len)
                    pos += apr_snprintf(buf+pos, sizeof(buf)-pos, " ");
                else {
                    ch = ((unsigned char)*((char *)(b) + i * DUMP_WIDTH + j)) & 0xff;
    #if APR_CHARSET_EBCDIC
                    pos += apr_snprintf(buf+pos, sizeof(buf)-pos, "%c", (ch >= 0x20 && ch <= 0x7F) ? ebcdic_text[j] : '.');
    #else /* APR_CHARSET_EBCDIC */
                    pos += apr_snprintf(buf+pos, sizeof(buf)-pos, "%c", ((ch >= ' ') && (ch <= '~')) ? ch : '.');
    #endif /* APR_CHARSET_EBCDIC */
                }
            }
            pos += apr_snprintf(buf+pos, sizeof(buf)-pos, " |");
            ap_log_cserror(APLOG_MARK, APLOG_TRACE7, 0, c, s, "%s", buf);
        }
        if (trunc > 0)
            ap_log_cserror(APLOG_MARK, APLOG_TRACE7, 0, c, s,
                    "| %04d - <SPACES/NULS>", len + trunc);
        ap_log_cserror(APLOG_MARK, APLOG_TRACE7, 0, c, s,
                "+-------------------------------------------------------------------------+");
    }
    
    #define MODSSL_IO_DUMP_MAX APR_UINT16_MAX
    
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    static long modssl_io_cb(BIO *bio, int cmd, const char *argp,
                             size_t len, int argi, long argl, int rc,
                             size_t *processed)
    #else
    static long modssl_io_cb(BIO *bio, int cmd, const char *argp,
                             int argi, long argl, long rc)
    #endif
    {
        SSL *ssl;
        conn_rec *c;
        server_rec *s;
    
        /* unused */
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
        (void)argi;
    #endif
        (void)argl;
    
        if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL)
            return rc;
        if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
            return rc;
        s = mySrvFromConn(c);
    
        if (   cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
            || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
            apr_size_t requested_len = len;
            /*
             * On OpenSSL >= 3 rc uses the meaning of the BIO_read_ex and
             * BIO_write_ex functions return value and not the one of
             * BIO_read and BIO_write. Hence 0 indicates an error.
             */
            int ok = (rc > 0);
    #else
            apr_size_t requested_len = (apr_size_t)argi;
            int ok = (rc >= 0);
    #endif
            if (ok) {
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
                apr_size_t actual_len = *processed;
    #else
                apr_size_t actual_len = (apr_size_t)rc;
    #endif
                const char *dump = "";
                if (APLOG_CS_IS_LEVEL(c, s, APLOG_TRACE7)) {
                    if (argp == NULL)
                        dump = "(Oops, no memory buffer?)";
                    else if (actual_len > MODSSL_IO_DUMP_MAX)
                        dump = "(BIO dump follows, truncated to "
                                 APR_STRINGIFY(MODSSL_IO_DUMP_MAX) ")";
                    else
                        dump = "(BIO dump follows)";
                }
                ap_log_cserror(APLOG_MARK, APLOG_TRACE4, 0, c, s,
                        "%s: %s %" APR_SIZE_T_FMT "/%" APR_SIZE_T_FMT 
                        " bytes %s BIO#%pp [mem: %pp] %s",
                        MODSSL_LIBRARY_NAME,
                        (cmd & BIO_CB_WRITE) ? "write" : "read",
                        actual_len, requested_len,
                        (cmd & BIO_CB_WRITE) ? "to" : "from",
                        bio, argp, dump);
                /*
                 * *dump will only be != '\0' if
                 * APLOG_CS_IS_LEVEL(c, s, APLOG_TRACE7)
                 */
                if (*dump != '\0' && argp != NULL) {
                    int dump_len = (actual_len >= MODSSL_IO_DUMP_MAX
                                           ? MODSSL_IO_DUMP_MAX
                                           : actual_len);
                    ssl_io_data_dump(c, s, argp, dump_len);
                }
            }
            else {
                ap_log_cserror(APLOG_MARK, APLOG_TRACE4, 0, c, s,
                        "%s: I/O error, %" APR_SIZE_T_FMT 
                        " bytes expected to %s on BIO#%pp [mem: %pp]",
                        MODSSL_LIBRARY_NAME, requested_len,
                        (cmd & BIO_CB_WRITE) ? "write" : "read",
                        bio, argp);
            }
        }
        return rc;
    }
    
    static APR_INLINE void set_bio_callback(BIO *bio, void *arg)
    {
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
        BIO_set_callback_ex(bio, modssl_io_cb);
    #else
        BIO_set_callback(bio, modssl_io_cb);
    #endif
        BIO_set_callback_arg(bio, arg);
    }
    
    void modssl_set_io_callbacks(SSL *ssl, conn_rec *c, server_rec *s)
    {
        BIO *rbio, *wbio;
    
        if (!APLOG_CS_IS_LEVEL(c, s, APLOG_TRACE4))
            return;
    
        rbio = SSL_get_rbio(ssl);
        wbio = SSL_get_wbio(ssl);
        if (rbio) {
            set_bio_callback(rbio, ssl);
        }
        if (wbio && wbio != rbio) {
            set_bio_callback(wbio, ssl);
        }
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/mod_ssl.c������������������������������������������������������������������0000664�0001751�0001751�00000070302�14526120464�016705� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "util_md5.h"
    #include "util_mutex.h"
    #include "ap_provider.h"
    #include "http_config.h"
    
    #include "mod_proxy.h" /* for proxy_hook_section_post_config() */
    
    #include <assert.h>
    
    static int modssl_running_statically = 0;
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, pre_handshake,
                                        (conn_rec *c,SSL *ssl,int is_proxy),
                                        (c,ssl,is_proxy), OK, DECLINED);
    
    /*
     *  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_PXY(name, args, desc) \
            AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
                           NULL, RSRC_CONF|PROXY_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 }
    
    static const command_rec ssl_config_cmds[] = {
        /*
         * Global (main-server) context configuration directives
         */
        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', 'nonenotnull', 'dbm:/path/to/file')")
        SSL_CMD_SRV(CryptoDevice, TAKE1,
                    "SSL external Crypto Device usage "
                    "('builtin', '...')")
        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_SRV(FIPS, FLAG,
                    "Enable FIPS-140 mode "
                    "(`on', `off')")
        SSL_CMD_ALL(CipherSuite, TAKE12,
                    "Colon-delimited list of permitted SSL Ciphers, optional preceded "
                    "by protocol identifier ('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)")
    #ifdef HAVE_TLS_SESSION_TICKETS
        SSL_CMD_SRV(SessionTicketKeyFile, TAKE1,
                    "TLS session ticket encryption/decryption key file (RFC 5077) "
                    "('/path/to/file' - file with 48 bytes of random data)")
    #endif
        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_SRV(CARevocationCheck, RAW_ARGS,
                    "SSL CA Certificate Revocation List (CRL) checking mode")
        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)")
    #ifdef OPENSSL_NO_SSL3
    #define SSLv3_PROTO_PREFIX ""
    #else
    #define SSLv3_PROTO_PREFIX "SSLv3|"
    #endif
    #ifdef HAVE_TLSV1_X
    #define SSL_PROTOCOLS SSLv3_PROTO_PREFIX "TLSv1|TLSv1.1|TLSv1.2"
    #else
    #define SSL_PROTOCOLS SSLv3_PROTO_PREFIX "TLSv1"
    #endif
        SSL_CMD_SRV(Protocol, RAW_ARGS,
                    "Enable or disable various SSL protocols "
                    "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
        SSL_CMD_SRV(HonorCipherOrder, FLAG,
                    "Use the server's cipher ordering preference")
        SSL_CMD_SRV(Compression, FLAG,
                    "Enable SSL level compression "
                    "(`on', `off')")
        SSL_CMD_SRV(SessionTickets, FLAG,
                    "Enable or disable TLS session tickets"
                    "(`on', `off')")
        SSL_CMD_SRV(InsecureRenegotiation, FLAG,
                    "Enable support for insecure renegotiation")
        SSL_CMD_ALL(UserName, TAKE1,
                    "Set user name to SSL variable value")
        SSL_CMD_SRV(StrictSNIVHostCheck, FLAG,
                    "Strict SNI virtual host checking")
    
    #ifdef HAVE_SRP
        SSL_CMD_SRV(SRPVerifierFile, TAKE1,
                    "SRP verifier file "
                    "('/path/to/file' - created by srptool)")
        SSL_CMD_SRV(SRPUnknownUserSeed, TAKE1,
                    "SRP seed for unknown users (to avoid leaking a user's existence) "
                    "('some secret text')")
    #endif
    
        /*
         * Proxy configuration for remote SSL connections
         */
        SSL_CMD_PXY(ProxyEngine, FLAG,
                    "SSL switch for the proxy protocol engine "
                    "('on', 'off')")
        SSL_CMD_PXY(ProxyProtocol, RAW_ARGS,
                   "SSL Proxy: enable or disable SSL protocol flavors "
                    "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
        SSL_CMD_PXY(ProxyCipherSuite, TAKE12,
                   "SSL Proxy: colon-delimited list of permitted SSL ciphers "
                   ", optionally preceded by protocol specifier ('XXX:...:XXX' - see manual)")
        SSL_CMD_PXY(ProxyVerify, TAKE1,
                   "SSL Proxy: whether to verify the remote certificate "
                   "('on' or 'off')")
        SSL_CMD_PXY(ProxyVerifyDepth, TAKE1,
                   "SSL Proxy: maximum certificate verification depth "
                   "('N' - number of intermediate certificates)")
        SSL_CMD_PXY(ProxyCACertificateFile, TAKE1,
                   "SSL Proxy: file containing server certificates "
                   "('/path/to/file' - PEM encoded certificates)")
        SSL_CMD_PXY(ProxyCACertificatePath, TAKE1,
                   "SSL Proxy: directory containing server certificates "
                   "('/path/to/dir' - contains PEM encoded certificates)")
        SSL_CMD_PXY(ProxyCARevocationPath, TAKE1,
                    "SSL Proxy: CA Certificate Revocation List (CRL) path "
                    "('/path/to/dir' - contains PEM encoded files)")
        SSL_CMD_PXY(ProxyCARevocationFile, TAKE1,
                    "SSL Proxy: CA Certificate Revocation List (CRL) file "
                    "('/path/to/file' - PEM encoded)")
        SSL_CMD_PXY(ProxyCARevocationCheck, RAW_ARGS,
                    "SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
        SSL_CMD_PXY(ProxyMachineCertificateFile, TAKE1,
                   "SSL Proxy: file containing client certificates "
                   "('/path/to/file' - PEM encoded certificates)")
        SSL_CMD_PXY(ProxyMachineCertificatePath, TAKE1,
                   "SSL Proxy: directory containing client certificates "
                   "('/path/to/dir' - contains PEM encoded certificates)")
        SSL_CMD_PXY(ProxyMachineCertificateChainFile, TAKE1,
                   "SSL Proxy: file containing issuing certificates "
                   "of the client certificate "
                   "(`/path/to/file' - PEM encoded certificates)")
        SSL_CMD_PXY(ProxyCheckPeerExpire, FLAG,
                    "SSL Proxy: check the peer certificate's expiration date")
        SSL_CMD_PXY(ProxyCheckPeerCN, FLAG,
                    "SSL Proxy: check the peer certificate's CN")
        SSL_CMD_PXY(ProxyCheckPeerName, FLAG,
                    "SSL Proxy: check the peer certificate's name "
                    "(must be present in subjectAltName extension or CN")
    
        /*
         * 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)")
        SSL_CMD_DIR(RenegBufferSize, AUTHCFG, TAKE1,
                    "Configure the amount of memory that will be used for buffering the "
                    "request body if a per-location SSL renegotiation is required due to "
                    "changed access control requirements")
    
        SSL_CMD_SRV(OCSPEnable, RAW_ARGS,
                   "Enable use of OCSP to verify certificate revocation mode ('on', 'leaf', 'off')")
        SSL_CMD_SRV(OCSPDefaultResponder, TAKE1,
                   "URL of the default OCSP Responder")
        SSL_CMD_SRV(OCSPOverrideResponder, FLAG,
                   "Force use of the default responder URL ('on', 'off')")
        SSL_CMD_SRV(OCSPResponseTimeSkew, TAKE1,
                    "Maximum time difference in OCSP responses")
        SSL_CMD_SRV(OCSPResponseMaxAge, TAKE1,
                    "Maximum age of OCSP responses")
        SSL_CMD_SRV(OCSPResponderTimeout, TAKE1,
                    "OCSP responder query timeout")
        SSL_CMD_SRV(OCSPUseRequestNonce, FLAG,
                    "Whether OCSP queries use a nonce or not ('on', 'off')")
        SSL_CMD_SRV(OCSPProxyURL, TAKE1,
                    "Proxy URL to use for OCSP requests")
    
    /* Define OCSP Responder Certificate Verification Directive */
        SSL_CMD_SRV(OCSPNoVerify, FLAG,
                    "Do not verify OCSP Responder certificate ('on', 'off')")
    /* Define OCSP Responder File Configuration Directive */
        SSL_CMD_SRV(OCSPResponderCertificateFile, TAKE1,
                   "Trusted OCSP responder certificates"
                   "(`/path/to/file' - PEM encoded certificates)")
    
    #ifdef HAVE_OCSP_STAPLING
        /*
         * OCSP Stapling options
         */
        SSL_CMD_SRV(StaplingCache, TAKE1,
                    "SSL Stapling Response Cache storage "
                    "(`dbm:/path/to/file')")
        SSL_CMD_SRV(UseStapling, FLAG,
                    "SSL switch for the OCSP Stapling protocol " "(`on', `off')")
        SSL_CMD_SRV(StaplingResponseTimeSkew, TAKE1,
                    "SSL stapling option for maximum time difference in OCSP responses")
        SSL_CMD_SRV(StaplingResponderTimeout, TAKE1,
                    "SSL stapling option for OCSP responder timeout")
        SSL_CMD_SRV(StaplingResponseMaxAge, TAKE1,
                    "SSL stapling option for maximum age of OCSP responses")
        SSL_CMD_SRV(StaplingStandardCacheTimeout, TAKE1,
                    "SSL stapling option for normal OCSP Response Cache Lifetime")
        SSL_CMD_SRV(StaplingReturnResponderErrors, FLAG,
                    "SSL stapling switch to return Status Errors Back to Client"
                    "(`on', `off')")
        SSL_CMD_SRV(StaplingFakeTryLater, FLAG,
                    "SSL stapling switch to send tryLater response to client on error "
                    "(`on', `off')")
        SSL_CMD_SRV(StaplingErrorCacheTimeout, TAKE1,
                    "SSL stapling option for OCSP Response Error Cache Lifetime")
        SSL_CMD_SRV(StaplingForceURL, TAKE1,
                    "SSL stapling option to Force the OCSP Stapling URL")
    #endif
    
    #ifdef HAVE_SSL_CONF_CMD
        SSL_CMD_SRV(OpenSSLConfCmd, TAKE2,
                    "OpenSSL configuration command")
    #endif
    
        /* 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 int modssl_is_prelinked(void)
    {
        apr_size_t i = 0;
        const module *mod;
        while ((mod = ap_prelinked_modules[i++])) {
            if (strcmp(mod->name, "mod_ssl.c") == 0) {
                return 1;
            }
        }
        return 0;
    }
    
    static apr_status_t ssl_cleanup_pre_config(void *data)
    {
    #if HAVE_OPENSSL_INIT_SSL || (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
                                  !defined(LIBRESSL_VERSION_NUMBER))
        /* Openssl v1.1+ handles all termination automatically from
         * OPENSSL_init_ssl(). Do nothing in this case.
         */
    
    #else
        /* Termination below is for legacy Openssl versions v1.0.x and
         * older.
         */
    
        /* Corresponds to OBJ_create()s */
        OBJ_cleanup();
        /* Corresponds to OPENSSL_load_builtin_modules() */
        CONF_modules_free();
        /* Corresponds to SSL_library_init: */
        EVP_cleanup();
    #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
        ENGINE_cleanup();
    #endif
    #if OPENSSL_VERSION_NUMBER >= 0x1000200fL
    #ifndef OPENSSL_NO_COMP
        SSL_COMP_free_compression_methods();
    #endif
    #endif
    
        /* Usually needed per thread, but this parent process is single-threaded */
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
        ERR_remove_thread_state(NULL);
    #else
        ERR_remove_state(0);
    #endif
    #endif
    
        /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only
         * actually loaded the error strings once per process due to static
         * variable abuse in OpenSSL. */
    #if (OPENSSL_VERSION_NUMBER >= 0x00090805f)
        ERR_free_strings();
    #endif
    
        /* Also don't call CRYPTO_cleanup_all_ex_data when linked statically here;
         * any registered ex_data indices may have been cached in static variables
         * in OpenSSL; removing them may cause havoc.  Notably, with OpenSSL
         * versions >= 0.9.8f, COMP_CTX cleanups would not be run, which
         * could result in a per-connection memory leak (!). */
        if (!modssl_running_statically) {
            CRYPTO_cleanup_all_ex_data();
        }
    #endif
    
        /*
         * 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)
    {
        modssl_running_statically = modssl_is_prelinked();
    
    #if HAVE_OPENSSL_INIT_SSL || (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
                                  !defined(LIBRESSL_VERSION_NUMBER))
        /* Openssl v1.1+ handles all initialisation automatically, apart
         * from hints as to how we want to use the library.
         *
         * We tell openssl we want to include engine support.
         */
        OPENSSL_init_ssl(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL);
    
    #else
        /* Configuration below is for legacy versions Openssl v1.0 and
         * older.
         */
    
    #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
        ssl_util_thread_id_setup(pconf);
    #endif
    #if MODSSL_USE_OPENSSL_PRE_1_1_API || defined(LIBRESSL_VERSION_NUMBER)
        (void)CRYPTO_malloc_init();
    #else
        OPENSSL_malloc_init();
    #endif
        ERR_load_crypto_strings();
        SSL_load_error_strings();
        SSL_library_init();
    #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
        ENGINE_load_builtin_engines();
    #endif
        OpenSSL_add_all_algorithms();
        OPENSSL_load_builtin_modules();
    #endif
    
        if (OBJ_txt2nid("id-on-dnsSRV") == NID_undef) {
            (void)OBJ_create("1.3.6.1.5.5.7.8.7", "id-on-dnsSRV",
                             "SRVName otherName form");
        }
    
        /* Start w/o errors (e.g. OBJ_txt2nid() above) */
        ERR_clear_error();
    
        /*
         * 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);
    
        /* Register mutex type names so they can be configured with Mutex */
        ap_mutex_register(pconf, SSL_CACHE_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
    #ifdef HAVE_OCSP_STAPLING
        ap_mutex_register(pconf, SSL_STAPLING_CACHE_MUTEX_TYPE, NULL,
                          APR_LOCK_DEFAULT, 0);
        ap_mutex_register(pconf, SSL_STAPLING_REFRESH_MUTEX_TYPE, NULL,
                          APR_LOCK_DEFAULT, 0);
    #endif
    
        return OK;
    }
    
    static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
                                               ap_conf_vector_t *per_dir_config,
                                               int reinit)
    {
        SSLConnRec *sslconn = myConnConfig(c);
        int need_setup = 0;
    
        /* mod_proxy's (r->)per_dir_config has the lifetime of the request, thus
         * it uses ssl_engine_set() to reset sslconn->dc when reusing SSL backend
         * connections, so we must fall through here. But in the case where we are
         * called from ssl_init_ssl_connection() with no per_dir_config (which also
         * includes mod_proxy's later run_pre_connection call), sslconn->dc should
         * be preserved if it's already set.
         */
        if (!sslconn) {
            sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
            need_setup = 1;
        }
        else if (!reinit) {
            return sslconn;
        }
    
        /* Reinit dc in any case because it may be r->per_dir_config scoped
         * and thus a caller like mod_proxy needs to update it per request.
         */
        if (per_dir_config) {
            sslconn->dc = ap_get_module_config(per_dir_config, &ssl_module);
        }
        else {
            sslconn->dc = ap_get_module_config(c->base_server->lookup_defaults,
                                               &ssl_module);
        }
    
        if (need_setup) {
            sslconn->server = c->base_server;
            sslconn->verify_depth = UNSET;
            if (c->outgoing) {
                sslconn->cipher_suite = sslconn->dc->proxy->auth.cipher_suite;
            }
            else {
                SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
                sslconn->cipher_suite = sc->server->auth.cipher_suite;
            }
    
            myConnConfigSet(c, sslconn);
        }
    
        return sslconn;
    }
    
    static int ssl_engine_status(conn_rec *c, SSLConnRec *sslconn)
    {
        if (c->master) {
            return DECLINED;
        }
        if (sslconn) {
            /* This connection has already been configured. Check what applies. */
            if (sslconn->disabled) {
                return SUSPENDED;
            }
            if (c->outgoing) {
                if (!sslconn->dc->proxy_enabled) {
                    return DECLINED;
                }
            }
            else {
                if (mySrvConfig(sslconn->server)->enabled != SSL_ENABLED_TRUE) {
                    return DECLINED;
                }
            }
        }
        else {
            /* we decline by default for outgoing connections and for incoming
             * where the base_server is not enabled. */
            if (c->outgoing || mySrvConfig(c->base_server)->enabled != SSL_ENABLED_TRUE) {
                return DECLINED;
            }
        }
        return OK;
    }
    
    static int ssl_hook_ssl_bind_outgoing(conn_rec *c,
                                     ap_conf_vector_t *per_dir_config,
                                     int enable_ssl)
    {
        SSLConnRec *sslconn;
        int status;
    
        sslconn = ssl_init_connection_ctx(c, per_dir_config, 1);
        if (sslconn->ssl) {
            /* we are already bound to this connection. We have rebound
             * or removed the reference to a previous per_dir_config,
             * there is nothing more to do. */
            return OK;
        }
    
        status = ssl_engine_status(c, sslconn);
        if (enable_ssl) {
            if (status != OK) {
                SSLSrvConfigRec *sc = mySrvConfig(sslconn->server);
                sslconn->disabled = 1;
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10272)
                              "SSL Proxy requested for %s but not enabled for us.",
                              sc->vhost_id);
            }
            else {
                sslconn->disabled = 0;
                return OK;
            }
        }
        else {
            sslconn->disabled = 1;
        }
        return DECLINED;
    }
    
    int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
    {
        SSLSrvConfigRec *sc;
        SSL *ssl;
        SSLConnRec *sslconn;
        char *vhost_md5;
        int rc;
        modssl_ctx_t *mctx;
        server_rec *server;
    
        /*
         * Create or retrieve SSL context
         */
        sslconn = ssl_init_connection_ctx(c, r ? r->per_dir_config : NULL, 0);
        server = sslconn->server;
        sc = mySrvConfig(server);
    
        /*
         * Seed the Pseudo Random Number Generator (PRNG)
         */
        ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT,
                      c->outgoing ? "Proxy: " : "Server: ");
    
        mctx = myConnCtxConfig(c, sc);
    
        /*
         * 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 (!(sslconn->ssl = ssl = SSL_new(mctx->ssl_ctx))) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01962)
                          "Unable to create a new SSL connection from the SSL "
                          "context");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
    
            c->aborted = 1;
    
            return DECLINED; /* XXX */
        }
    
        rc = ssl_run_pre_handshake(c, ssl, c->outgoing ? 1 : 0);
        if (rc != OK && rc != DECLINED) {
            return rc;
        }
    
        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, APLOGNO(01963)
                          "Unable to set session id context to '%s'", vhost_md5);
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
    
            c->aborted = 1;
    
            return DECLINED; /* XXX */
        }
    
        SSL_set_app_data(ssl, c);
        modssl_set_app_data2(ssl, NULL); /* will be request_rec */
    
        SSL_set_verify_result(ssl, X509_V_OK);
    
        ssl_io_filter_init(c, r, ssl);
    
        return APR_SUCCESS;
    }
    
    static const char *ssl_hook_http_scheme(const request_rec *r)
    {
        return modssl_request_is_tls(r, NULL) ? "https" : NULL;
    }
    
    static apr_port_t ssl_hook_default_port(const request_rec *r)
    {
        return modssl_request_is_tls(r, NULL) ? 443 : 0;
    }
    
    static int ssl_hook_pre_connection(conn_rec *c, void *csd)
    {
        SSLSrvConfigRec *sc;
        SSLConnRec *sslconn = myConnConfig(c);
    
        /*
         * Immediately stop processing if SSL is disabled for this connection
         */
        if (ssl_engine_status(c, sslconn) != OK) {
            return DECLINED;
        }
    
        if (sslconn) {
            sc = mySrvConfig(sslconn->server);
        }
        else {
            sc = mySrvConfig(c->base_server);
        }
    
        /*
         * Remember the connection information for
         * later access inside callback functions
         */
    
        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(01964)
                      "Connection to child %ld established "
                      "(server %s)", c->id, sc->vhost_id);
    
        return ssl_init_ssl_connection(c, NULL);
    }
    
    static int ssl_hook_process_connection(conn_rec* c)
    {
        SSLConnRec *sslconn = myConnConfig(c);
    
        if (sslconn && !sslconn->disabled) {
            /* On an active SSL connection, let the input filters initialize
             * themselves which triggers the handshake, which again triggers
             * all kinds of useful things such as SNI and ALPN.
             */
            apr_bucket_brigade* temp;
    
            temp = apr_brigade_create(c->pool, c->bucket_alloc);
            ap_get_brigade(c->input_filters, temp,
                           AP_MODE_INIT, APR_BLOCK_READ, 0);
            apr_brigade_destroy(temp);
        }
        
        return DECLINED;
    }
    
    /*
     *  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 };
        /* The ssl_init_Module post_config hook should run before mod_proxy's
         * for the ssl proxy main configs to be merged with vhosts' before being
         * themselves merged with mod_proxy's in proxy_hook_section_post_config.
         */
        static const char *b_pc[] = { "mod_proxy.c", NULL};
    
    
        ssl_io_filter_register(p);
    
        ap_hook_pre_connection(ssl_hook_pre_connection,NULL,NULL, APR_HOOK_MIDDLE);
        ap_hook_process_connection(ssl_hook_process_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,b_pc, 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_authn   (ssl_hook_UserCheck,     NULL,NULL, APR_HOOK_FIRST,
                               AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_fixups        (ssl_hook_Fixup,         NULL,NULL, APR_HOOK_MIDDLE);
        ap_hook_check_access  (ssl_hook_Access,        NULL,NULL, APR_HOOK_MIDDLE,
                               AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_check_authz   (ssl_hook_Auth,          NULL,NULL, APR_HOOK_MIDDLE,
                               AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_post_read_request(ssl_hook_ReadReq, pre_prr,NULL, APR_HOOK_MIDDLE);
    
        APR_OPTIONAL_HOOK(proxy, section_post_config,
                          ssl_proxy_section_post_config, NULL, NULL,
                          APR_HOOK_MIDDLE);
    
        ssl_var_register(p);
        ap_hook_ssl_bind_outgoing  (ssl_hook_ssl_bind_outgoing, NULL, NULL, APR_HOOK_MIDDLE);
    
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
                                  AUTHZ_PROVIDER_VERSION,
                                  &ssl_authz_provider_require_ssl,
                                  AP_AUTH_INTERNAL_PER_CONF);
    
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-verify-client",
                                  AUTHZ_PROVIDER_VERSION,
                                  &ssl_authz_provider_verify_client,
                                  AP_AUTH_INTERNAL_PER_CONF);
    }
    
    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 */
    #if defined(AP_MODULE_HAS_FLAGS)
       ,AP_MODULE_FLAG_ALWAYS_MERGE /* flags */
    #endif
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_log.c�����������������������������������������������������������0000664�0001751�0001751�00000021250�14155617767�020251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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;
    }
    
    apr_status_t ssl_die(server_rec *s)
    {
        if (s != NULL && s->is_virtual && s->error_fname != NULL)
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02311)
                         "Fatal error initialising mod_ssl, exiting. "
                         "See %s for more information",
                         ap_server_root_relative(s->process->pool,
                                                 s->error_fname));
        else
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02312)
                         "Fatal error initialising mod_ssl, exiting.");
    
        return APR_EGENERAL;
    }
    
    static APR_INLINE
    unsigned long modssl_ERR_peek_error_data(const char **data, int *flags)
    {
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
        return ERR_peek_error_line_data(NULL, NULL, data, flags);
    #else
        return ERR_peek_error_data(data, flags);
    #endif
    }
    
    /*
     * Prints the SSL library error information.
     */
    void ssl_log_ssl_error(const char *file, int line, int level, server_rec *s)
    {
        unsigned long e;
        const char *data;
        int flags;
    
        while ((e = modssl_ERR_peek_error_data(&data, &flags))) {
            const char *annotation;
            char err[256];
    
            if (!(flags & ERR_TXT_STRING)) {
                data = NULL;
            }
    
            ERR_error_string_n(e, err, sizeof err);
            annotation = ssl_log_annotation(err);
    
            ap_log_error(file, line, APLOG_MODULE_INDEX, level, 0, s,
                         "SSL Library Error: %s%s%s%s%s%s",
                         /* %s */
                         err,
                         /* %s%s%s */
                         data ? " (" : "", data ? data : "", data ? ")" : "",
                         /* %s%s */
                         annotation ? " -- " : "",
                         annotation ? annotation : "");
    
            /* Pop the error off the stack: */
            ERR_get_error();
        }
    }
    
    static void ssl_log_cert_error(const char *file, int line, int level,
                                   apr_status_t rv, const server_rec *s,
                                   const conn_rec *c, const request_rec *r,
                                   apr_pool_t *p, X509 *cert, const char *format,
                                   va_list ap)
    {
        char buf[HUGE_STRING_LEN];
        int msglen, n;
        char *name;
    
        msglen = apr_vsnprintf(buf, sizeof buf, format, ap);
        
        if (cert) {
            BIO *bio = BIO_new(BIO_s_mem());
    
            if (bio) {
                /*
                 * Limit the maximum length of the subject and issuer DN strings
                 * in the log message. 300 characters should always be sufficient
                 * for holding both the timestamp, module name, pid etc. stuff
                 * at the beginning of the line and the trailing information about
                 * serial, notbefore and notafter.
                 */
                int maxdnlen = (HUGE_STRING_LEN - msglen - 300) / 2;
    
                BIO_puts(bio, " [subject: ");
                name = modssl_X509_NAME_to_string(p, X509_get_subject_name(cert),
                                                  maxdnlen);
                if (!strIsEmpty(name)) {
                    BIO_puts(bio, name);
                } else {
                    BIO_puts(bio, "-empty-");
                }
    
                BIO_puts(bio, " / issuer: ");
                name = modssl_X509_NAME_to_string(p, X509_get_issuer_name(cert),
                                                  maxdnlen);
                if (!strIsEmpty(name)) {
                    BIO_puts(bio, name);
                } else {
                    BIO_puts(bio, "-empty-");
                }
    
                BIO_puts(bio, " / serial: ");
                if (i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert)) == -1)
                    BIO_puts(bio, "(ERROR)");
    
                BIO_puts(bio, " / notbefore: ");
                ASN1_TIME_print(bio, X509_get_notBefore(cert));
    
                BIO_puts(bio, " / notafter: ");
                ASN1_TIME_print(bio, X509_get_notAfter(cert));
    
                BIO_puts(bio, "]");
    
                n = BIO_read(bio, buf + msglen, sizeof buf - msglen - 1);
                if (n > 0)
                   buf[msglen + n] = '\0';
    
                BIO_free(bio);
            }
        }
        else {
            apr_snprintf(buf + msglen, sizeof buf - msglen,
                         " [certificate: -not available-]");
        }
    
        if (r) {
            ap_log_rerror(file, line, APLOG_MODULE_INDEX, level, rv, r, "%s", buf);
        }
        else if (c) {
            ap_log_cerror(file, line, APLOG_MODULE_INDEX, level, rv, c, "%s", buf);
        }
        else if (s) {
            ap_log_error(file, line, APLOG_MODULE_INDEX, level, rv, s, "%s", buf);
        }
    
    }
    
    /*
     * Wrappers for ap_log_error/ap_log_cerror/ap_log_rerror which log additional
     * details of the X509 cert. For ssl_log_xerror, a pool needs to be passed in
     * as well (for temporary allocation of the cert's subject/issuer name strings,
     * in the other cases we use the connection and request pool, respectively).
     */
    void ssl_log_xerror(const char *file, int line, int level, apr_status_t rv,
                        apr_pool_t *ptemp, server_rec *s, X509 *cert,
                        const char *fmt, ...)
    {
        if (APLOG_IS_LEVEL(s,level)) {
           va_list ap;
           va_start(ap, fmt);
           ssl_log_cert_error(file, line, level, rv, s, NULL, NULL, ptemp,
                              cert, fmt, ap);
           va_end(ap);
        }
    }
    
    void ssl_log_cxerror(const char *file, int line, int level, apr_status_t rv,
                         conn_rec *c, X509 *cert, const char *fmt, ...)
    {
        if (APLOG_IS_LEVEL(mySrvFromConn(c),level)) {
           va_list ap;
           va_start(ap, fmt);
           ssl_log_cert_error(file, line, level, rv, NULL, c, NULL, c->pool,
                              cert, fmt, ap);
           va_end(ap);
        }
    }
    
    void ssl_log_rxerror(const char *file, int line, int level, apr_status_t rv,
                         request_rec *r, X509 *cert, const char *fmt, ...)
    {
        if (APLOG_R_IS_LEVEL(r,level)) {
           va_list ap;
           va_start(ap, fmt);
           ssl_log_cert_error(file, line, level, rv, NULL, NULL, r, r->pool,
                              cert, fmt, ap);
           va_end(ap);
        }
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/mod_ssl.h������������������������������������������������������������������0000664�0001751�0001751�00000011575�13520024310�016703� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_ssl.h
     * @brief SSL extension module for Apache
     *
     * @defgroup MOD_SSL mod_ssl
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #ifndef __MOD_SSL_H__
    #define __MOD_SSL_H__
    
    #include "httpd.h"
    #include "http_config.h"
    #include "apr_optional.h"
    #include "apr_tables.h" /* for apr_array_header_t */
    
    /* Create a set of SSL_DECLARE(type), SSL_DECLARE_NONSTD(type) and
     * SSL_DECLARE_DATA with appropriate export and import tags for the platform
     */
    #if !defined(WIN32)
    #define SSL_DECLARE(type)            type
    #define SSL_DECLARE_NONSTD(type)     type
    #define SSL_DECLARE_DATA
    #elif defined(SSL_DECLARE_STATIC)
    #define SSL_DECLARE(type)            type __stdcall
    #define SSL_DECLARE_NONSTD(type)     type
    #define SSL_DECLARE_DATA
    #elif defined(SSL_DECLARE_EXPORT)
    #define SSL_DECLARE(type)            __declspec(dllexport) type __stdcall
    #define SSL_DECLARE_NONSTD(type)     __declspec(dllexport) type
    #define SSL_DECLARE_DATA             __declspec(dllexport)
    #else
    #define SSL_DECLARE(type)            __declspec(dllimport) type __stdcall
    #define SSL_DECLARE_NONSTD(type)     __declspec(dllimport) type
    #define SSL_DECLARE_DATA             __declspec(dllimport)
    #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 *));
    
    /** The ssl_ext_list() optional function attempts to build an array
     * of all the values contained in the named X.509 extension. The
     * returned array will be created in the supplied pool.
     * The client certificate is used if peer is non-zero; the server
     * certificate is used otherwise.
     * Extension specifies the extensions to use as a string. This can be
     * one of the "known" long or short names, or a numeric OID,
     * e.g. "1.2.3.4", 'nsComment' and 'DN' are all valid.
     * A pointer to an apr_array_header_t structure is returned if at
     * least one matching extension is found, NULL otherwise.
     */
    APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ssl_ext_list,
                            (apr_pool_t *p, conn_rec *c, int peer,
                             const char *extension));
    
    /** 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_{set,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 *));
    APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *,
                                                  ap_conf_vector_t *,
                                                  int proxy, int enable));
                                                  
    /* Check for availability of new hooks */
    #define SSL_CERT_HOOKS
    #ifdef SSL_CERT_HOOKS
    
    /** Lets others add certificate and key files to the given server.
     * For each cert a key must also be added.
     * @param cert_file and array of const char* with the path to the certificate chain
     * @param key_file and array of const char* with the path to the private key file
     */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_cert_files,
                              (server_rec *s, apr_pool_t *p, 
                               apr_array_header_t *cert_files,
                               apr_array_header_t *key_files))
    
    /** In case no certificates are available for a server, this
     * lets other modules add a fallback certificate for the time
     * being. Regular requests against this server will be answered
     * with a 503. 
     * @param cert_file and array of const char* with the path to the certificate chain
     * @param key_file and array of const char* with the path to the private key file
     */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_fallback_cert_files,
                              (server_rec *s, apr_pool_t *p, 
                               apr_array_header_t *cert_files,
                               apr_array_header_t *key_files))
    
    #endif /* SSL_CERT_HOOKS */
    
    #endif /* __MOD_SSL_H__ */
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/mod_ssl.dep����������������������������������������������������������������0000664�0001751�0001751�00000113617�12674411515�017244� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_ssl.mak
    
    .\mod_ssl.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_md5.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_ssl.h"\
    	".\mod_ssl_openssl.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_config.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_init.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\mpm_common.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_ssl.h"\
    	".\mod_ssl_openssl.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_io.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_ssl.h"\
    	".\mod_ssl_openssl.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_kernel.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_md5.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_ssl.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_log.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_mutex.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_ocsp.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_pphrase.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_rand.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_engine_vars.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\loggers\mod_log_config.h"\
    	".\mod_ssl.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_scache.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\generators\mod_status.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_util.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_util_ocsp.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_util_ssl.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    .\ssl_util_stapling.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ssl_private.h"\
    	".\ssl_util_ssl.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    �����������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/config.m4������������������������������������������������������������������0000664�0001751�0001751�00000003644�12241452212�016604� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl Licensed to the Apache Software Foundation (ASF) under one or more
    dnl contributor license agreements.  See the NOTICE file distributed with
    dnl this work for additional information regarding copyright ownership.
    dnl The ASF licenses this file to You under the Apache License, Version 2.0
    dnl (the "License"); you may not use this file except in compliance with
    dnl the License.  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.
    
    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_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_scache.lo dnl
    ssl_util_stapling.lo dnl
    ssl_util.lo dnl
    ssl_util_ssl.lo dnl
    ssl_engine_ocsp.lo dnl
    ssl_util_ocsp.lo dnl
    "
    dnl #  hook module into the Autoconf mechanism (--enable-ssl option)
    APACHE_MODULE(ssl, [SSL/TLS support (mod_ssl)], $ssl_objs, , most, [
        APACHE_CHECK_OPENSSL
        if test "$ac_cv_openssl" = "yes" ; then
            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
        else
            enable_ssl=no
        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
    
    ��������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_rand.c����������������������������������������������������������0000664�0001751�0001751�00000013174�12524644015�020402� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 nDone;
        apr_file_t *fp;
        int i, n, l;
    
        mc = myModConfig(s);
        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) {
                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_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_TRACE2, 0, s,
                     "%sSeeding PRNG with %d bytes of entropy", prefix, nDone);
    
        if (RAND_status() == 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01990)
                         "%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;
    }
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/Makefile.in����������������������������������������������������������������0000664�0001751�0001751�00000001515�11465263264�017153� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_kernel.c��������������������������������������������������������0000664�0001751�0001751�00000306000�15032734372�020732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "mod_ssl.h"
    #include "util_md5.h"
    #include "scoreboard.h"
    
    static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
    #ifdef HAVE_TLSEXT
    static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s);
    #endif
    
    /* Perform a speculative (and non-blocking) read from the connection
     * filters for the given request, to determine whether there is any
     * pending data to read.  Return non-zero if there is, else zero. */
    static int has_buffered_data(request_rec *r)
    {
        apr_bucket_brigade *bb;
        apr_off_t len;
        apr_status_t rv;
        int result;
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        rv = ap_get_brigade(r->connection->input_filters, bb, AP_MODE_SPECULATIVE,
                            APR_NONBLOCK_READ, 1);
        result = rv == APR_SUCCESS
            && apr_brigade_length(bb, 1, &len) == APR_SUCCESS
            && len > 0;
    
        apr_brigade_destroy(bb);
    
        return result;
    }
    
    /* If a renegotiation is required for the location, and the request
     * includes a message body (and the client has not requested a "100
     * Continue" response), then the client will be streaming the request
     * body over the wire already.  In that case, it is not possible to
     * stop and perform a new SSL handshake immediately; once the SSL
     * library moves to the "accept" state, it will reject the SSL packets
     * which the client is sending for the request body.
     *
     * To allow authentication to complete in the hook, the solution used
     * here is to fill a (bounded) buffer with the request body, and then
     * to reinject that request body later.
     *
     * This function is called to fill the renegotiation buffer for the
     * location as required, or fail.  Returns zero on success or HTTP_
     * error code on failure.
     */
    static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc)
    {
        int rv;
        apr_size_t rsize;
    
        /* ### this is HTTP/1.1 specific, special case for protocol? */
        if (r->expecting_100 || !ap_request_has_body(r)) {
            return 0;
        }
    
        rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE : dc->nRenegBufferSize;
        if (rsize > 0) {
            /* Fill the I/O buffer with the request body if possible. */
            rv = ssl_io_buffer_fill(r, rsize);
        }
        else {
            /* If the reneg buffer size is set to zero, just fail. */
            rv = HTTP_REQUEST_ENTITY_TOO_LARGE;
        }
    
        return rv;
    }
    
    #ifdef HAVE_TLSEXT
    static int ap_array_same_str_set(apr_array_header_t *s1, apr_array_header_t *s2)
    {
        int i;
        const char *c;
        
        if (s1 == s2) {
            return 1;
        }
        else if (!s1 || !s2 || (s1->nelts != s2->nelts)) {
            return 0;
        }
        
        for (i = 0; i < s1->nelts; i++) {
            c = APR_ARRAY_IDX(s1, i, const char *);
            if (!c || !ap_array_str_contains(s2, c)) {
                return 0;
            }
        }
        return 1;
    }
    
    static int ssl_pk_server_compatible(modssl_pk_server_t *pks1, 
                                        modssl_pk_server_t *pks2) 
    {
        if (!pks1 || !pks2) {
            return 0;
        }
        /* both have the same certificates? */
        if ((pks1->ca_name_path != pks2->ca_name_path)
            && (!pks1->ca_name_path || !pks2->ca_name_path 
                || strcmp(pks1->ca_name_path, pks2->ca_name_path))) {
            return 0;
        }
        if ((pks1->ca_name_file != pks2->ca_name_file)
            && (!pks1->ca_name_file || !pks2->ca_name_file 
                || strcmp(pks1->ca_name_file, pks2->ca_name_file))) {
            return 0;
        }
        if (!ap_array_same_str_set(pks1->cert_files, pks2->cert_files)
            || !ap_array_same_str_set(pks1->key_files, pks2->key_files)) {
            return 0;
        }
        return 1;
    }
    
    static int ssl_auth_compatible(modssl_auth_ctx_t *a1, 
                                   modssl_auth_ctx_t *a2) 
    {
        if (!a1 || !a2) {
            return 0;
        }
        /* both have the same verification */
        if ((a1->verify_depth != a2->verify_depth)
            || (a1->verify_mode != a2->verify_mode)) {
            return 0;
        }
        /* both have the same ca path/file */
        if ((a1->ca_cert_path != a2->ca_cert_path)
            && (!a1->ca_cert_path || !a2->ca_cert_path 
                || strcmp(a1->ca_cert_path, a2->ca_cert_path))) {
            return 0;
        }
        if ((a1->ca_cert_file != a2->ca_cert_file)
            && (!a1->ca_cert_file || !a2->ca_cert_file 
                || strcmp(a1->ca_cert_file, a2->ca_cert_file))) {
            return 0;
        }
        /* both have the same ca cipher suite string */
        if ((a1->cipher_suite != a2->cipher_suite)
            && (!a1->cipher_suite || !a2->cipher_suite 
                || strcmp(a1->cipher_suite, a2->cipher_suite))) {
            return 0;
        }
        /* both have the same ca cipher suite string */
        if ((a1->tls13_ciphers != a2->tls13_ciphers)
            && (!a1->tls13_ciphers || !a2->tls13_ciphers 
                || strcmp(a1->tls13_ciphers, a2->tls13_ciphers))) {
            return 0;
        }
        return 1;
    }
    
    static int ssl_ctx_compatible(modssl_ctx_t *ctx1, 
                                  modssl_ctx_t *ctx2) 
    {
        if (!ctx1 || !ctx2 
            || (ctx1->protocol != ctx2->protocol)
            || !ssl_auth_compatible(&ctx1->auth, &ctx2->auth)
            || !ssl_pk_server_compatible(ctx1->pks, ctx2->pks)) {
            return 0;
        }
        return 1;
    }
    
    static int ssl_server_compatible(server_rec *s1, server_rec *s2)
    {
        SSLSrvConfigRec *sc1 = s1? mySrvConfig(s1) : NULL;
        SSLSrvConfigRec *sc2 = s2? mySrvConfig(s2) : NULL;
    
        /* both use the same TLS protocol? */
        if (!sc1 || !sc2 
            || !ssl_ctx_compatible(sc1->server, sc2->server)) {
            return 0;
        }
        
        return 1;
    }
    #endif
    
    /*
     *  Post Read Request Handler
     */
    int ssl_hook_ReadReq(request_rec *r)
    {
        SSLSrvConfigRec *sc = mySrvConfig(r->server);
        SSLConnRec *sslconn;
    #ifdef HAVE_TLSEXT
        const char *servername;
    #endif
        SSL *ssl;
    
        /* If we are on a slave connection, we do not expect to have an SSLConnRec,
         * but our master connection might. */
        sslconn = myConnConfig(r->connection);
        if (!(sslconn && sslconn->ssl) && r->connection->master) {
            sslconn = myConnConfig(r->connection->master);
        }
    
        if (!sslconn) {
            return DECLINED;
        }
    
        if (sslconn->service_unavailable) {
            /* This is set when the SSL properties of this connection are
             * incomplete or if this connection was made to challenge a 
             * particular hostname (ACME). We never serve any request on 
             * such a connection. */
             /* TODO: a retry-after indicator would be nice here */
            return HTTP_SERVICE_UNAVAILABLE;
        }
    
        if (sslconn->non_ssl_request == NON_SSL_SET_ERROR_MSG) {
            apr_table_setn(r->notes, "error-notes",
                           "Reason: You're speaking plain HTTP to an SSL-enabled "
                           "server port.<br />\n Instead use the HTTPS scheme to "
                           "access this URL, please.<br />\n");
    
            /* Now that we have caught this error, forget it. we are done
             * with using SSL on this request.
             */
            sslconn->non_ssl_request = NON_SSL_OK;
    
            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;
        }
    #ifdef HAVE_TLSEXT
        /*
         * Perform SNI checks only on the initial request.  In particular,
         * if these checks detect a problem, the checks shouldn't return an
         * error again when processing an ErrorDocument redirect for the
         * original problem.
         */
        if (r->proxyreq != PROXYREQ_PROXY && ap_is_initial_req(r)) {
            server_rec *handshakeserver = sslconn->server;
            SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver);
    
            if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
                /*
                 * The SNI extension supplied a hostname. So don't accept requests
                 * with either no hostname or a hostname that selected a different
                 * virtual host than the one used for the handshake, causing
                 * different SSL parameters to be applied, such as SSLProtocol,
                 * SSLCACertificateFile/Path and SSLCADNRequestFile/Path which
                 * cannot be renegotiated (SSLCA* due to current limitations in
                 * OpenSSL, see:
                 * http://mail-archives.apache.org/mod_mbox/httpd-dev/200806.mbox/%3C48592955.2090303@velox.ch%3E
                 * and
                 * http://mail-archives.apache.org/mod_mbox/httpd-dev/201312.mbox/%3CCAKQ1sVNpOrdiBm-UPw1hEdSN7YQXRRjeaT-MCWbW_7mN%3DuFiOw%40mail.gmail.com%3E
                 * )
                 */
                if (!r->hostname) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02031)
                                "Hostname %s provided via SNI, but no hostname"
                                " provided in HTTP request", servername);
                    return HTTP_BAD_REQUEST;
                }
            }
            else if (((sc->strict_sni_vhost_check == SSL_ENABLED_TRUE)
                      || hssc->strict_sni_vhost_check == SSL_ENABLED_TRUE)
                     && r->connection->vhost_lookup_data) {
                /*
                 * We are using a name based configuration here, but no hostname was
                 * provided via SNI. Don't allow that if are requested to do strict
                 * checking. Check whether this strict checking was set up either in the
                 * server config we used for handshaking or in our current server.
                 * This should avoid insecure configuration by accident.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02033)
                             "No hostname was provided via SNI for a name based"
                             " virtual host");
                apr_table_setn(r->notes, "error-notes",
                               "Reason: The client software did not provide a "
                               "hostname using Server Name Indication (SNI), "
                               "which is required to access this server.<br />\n");
                return HTTP_FORBIDDEN;
            }
            if (r->server != handshakeserver
                && !ssl_server_compatible(sslconn->server, r->server)) {
                /*
                 * The request does not select the virtual host that was
                 * selected for handshaking and its SSL parameters are different
                 */
    
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02032)
                             "Hostname %s %s and hostname %s provided"
                             " via HTTP have no compatible SSL setup",
                             servername ? servername : handshakeserver->server_hostname,
                             servername ? "provided via SNI" : "(default host as no SNI was provided)",
                             r->hostname);
                return HTTP_MISDIRECTED_REQUEST;
            }
        }
    #endif
        modssl_set_app_data2(ssl, r);
    
        /*
         * Log information about incoming HTTPS requests
         */
        if (APLOGrinfo(r) && ap_is_initial_req(r)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02034)
                         "%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;
            }
        }
    }
    
    static int ssl_check_post_client_verify(request_rec *r, SSLSrvConfigRec *sc, 
                                            SSLDirConfigRec *dc, SSLConnRec *sslconn,
                                            SSL *ssl)
    {
        X509 *cert;
        
        /*
         * 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) ||
            (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) {
            BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
                              (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE));
    
            if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02262)
                              "Re-negotiation handshake failed: "
                              "Client verification failed");
    
                return HTTP_FORBIDDEN;
            }
    
            if (do_verify) {
                if (cert == NULL) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02263)
                                  "Re-negotiation handshake failed: "
                                  "Client certificate missing");
    
                    return HTTP_FORBIDDEN;
                }
            }
        }
        return OK;
    }
    
    /*
     *  Access Handler, classic flavour, for SSL/TLS up to v1.2 
     *  where everything can be renegotiated and no one is happy.
     */
    static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirConfigRec *dc,
                                       SSLConnRec *sslconn, SSL *ssl)
    {
        server_rec *handshakeserver = sslconn ? sslconn->server : NULL;
        SSLSrvConfigRec *hssc       = handshakeserver? mySrvConfig(handshakeserver) : NULL;
        SSL_CTX *ctx = ssl ? SSL_get_SSL_CTX(ssl) : NULL;
        BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
        X509 *peercert;
        X509_STORE *cert_store = NULL;
        X509_STORE_CTX *cert_store_ctx;
        STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;
        const SSL_CIPHER *cipher = NULL;
        int depth, verify_old, verify, n, rc;
        const char *ncipher_suite;
    
    #ifdef HAVE_SRP
        /*
         * Support for per-directory reconfigured SSL connection parameters
         *
         * We do not force any renegotiation if the user is already authenticated
         * via SRP.
         *
         */
        if (SSL_get_srp_username(ssl)) {
            return DECLINED;
        }
    #endif
    
        /*
         * 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.
         */     
        ncipher_suite = (dc->szCipherSuite? 
                         dc->szCipherSuite : (r->server != handshakeserver)?
                         sc->server->auth.cipher_suite : NULL);
        
        if (ncipher_suite && (!sslconn->cipher_suite 
                              || strcmp(ncipher_suite, sslconn->cipher_suite))) {
            /* 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 (r->connection->master) {
                /* TODO: this categorically fails changed cipher suite settings
                 * on slave connections. We could do better by
                 * - create a new SSL* from our SSL_CTX and set cipher suite there,
                 *   and retrieve ciphers, free afterwards
                 * Modifying the SSL on a slave connection is no good.
                 */
                apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "cipher-suite");
                return HTTP_FORBIDDEN;
            }
    
            if (!SSL_set_cipher_list(ssl, ncipher_suite)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02253)
                              "Unable to reconfigure (per-directory) "
                              "permitted SSL ciphers");
                ssl_log_ssl_error(SSLLOG_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++)
                    {
                        const 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++)
                    {
                        const 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);
            }
    
            if (renegotiate) {
                if (r->connection->master) {
                    /* The request causes renegotiation on a slave connection.
                     * This is not allowed since we might have concurrent requests
                     * on this connection.
                     */
                    apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "cipher-suite");
                    return HTTP_FORBIDDEN;
                }
                
    #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
                if (sc->cipher_server_pref == TRUE) {
                    SSL_set_options(ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
                }
    #endif
                /* tracing */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02220)
                             "Reconfigured cipher suite 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 renegotiation
         * handshake.
         */
        if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) ||
            (sc->server->auth.verify_mode != 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) ||
                (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) {
                verify |= SSL_VERIFY_PEER_STRICT;
            }
    
            if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) ||
                (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) ||
                (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
                (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
            {
                verify |= SSL_VERIFY_PEER;
            }
    
            /* TODO: this seems premature since we do not know if there
             *       are any changes required.
             */
            SSL_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_FAIL_IF_NO_PEER_CERT) &&
                      (verify     & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)))
                {
                    renegotiate = TRUE;
                    if (r->connection->master) {
                        /* The request causes renegotiation on a slave connection.
                         * This is not allowed since we might have concurrent requests
                         * on this connection.
                         */
                        apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "verify-client");
                        SSL_set_verify(ssl, verify_old, ssl_callback_SSLVerify);
                        return HTTP_FORBIDDEN;
                    }
                    /* 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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02255)
                                  "Changed client verification type will force "
                                  "%srenegotiation",
                                  renegotiate_quick ? "quick " : "");
                }
                else if (verify != SSL_VERIFY_NONE) {
                    /*
                     * 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
                     * SSLConnRec 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).
                     */
                    n = (sslconn->verify_depth != UNSET)
                        ? sslconn->verify_depth
                        : hssc->server->auth.verify_depth;
                    /* determine the new depth */
                    sslconn->verify_depth = (dc->nVerifyDepth != UNSET)
                                            ? dc->nVerifyDepth
                                            : sc->server->auth.verify_depth;
                    if (sslconn->verify_depth < n) {
                        renegotiate = TRUE;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02254)
                                      "Reduced client verification depth will "
                                      "force renegotiation");
                    }
                }
            }
            /* If we're handling a request for a vhost other than the default one,
             * then we need to make sure that client authentication is properly
             * enforced. For clients supplying an SNI extension, the peer
             * certificate verification has happened in the handshake already
             * (and r->server == handshakeserver). For non-SNI requests,
             * an additional check is needed here. If client authentication
             * is configured as mandatory, then we can only proceed if the
             * CA list doesn't have to be changed (OpenSSL doesn't provide
             * an option to change the list for an existing session).
             */
            if ((r->server != handshakeserver)
                && renegotiate
                && ((verify & SSL_VERIFY_PEER) ||
                    (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
    #define MODSSL_CFG_CA_NE(f, sc1, sc2) \
                (sc1->server->auth.f && \
                 (!sc2->server->auth.f || \
                  strNE(sc1->server->auth.f, sc2->server->auth.f)))
    
                if (MODSSL_CFG_CA_NE(ca_cert_file, sc, hssc) ||
                    MODSSL_CFG_CA_NE(ca_cert_path, sc, hssc)) {
                    if (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02256)
                             "Non-default virtual host with SSLVerify set to "
                             "'require' and VirtualHost-specific CA certificate "
                             "list is only available to clients with TLS server "
                             "name indication (SNI) support");
                        SSL_set_verify(ssl, verify_old, NULL);
                        return HTTP_FORBIDDEN;
                    } else
                        /* let it pass, possibly with an "incorrect" peer cert,
                         * so make sure the SSL_CLIENT_VERIFY environment variable
                         * will indicate partial success only, later on.
                         */
                        sslconn->verify_info = "GENEROUS";
                }
            }
        }
    
        /* Fill reneg buffer if required. */
        if (renegotiate && !renegotiate_quick) {
            rc = fill_reneg_buffer(r, dc);
            if (rc) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02257)
                              "could not buffer message body to allow "
                              "SSL renegotiation to proceed");
                return rc;
            }
        }
    
        /*
         * now do the renegotiation if anything was actually reconfigured
         */
        if (renegotiate) {
            /*
             * Now we force the SSL renegotiation 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_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02221)
                          "Requesting connection re-negotiation");
    
            if (renegotiate_quick) {
                STACK_OF(X509) *cert_stack;
                X509 *cert;
    
                /* perform just a manual re-verification of the peer */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02258)
                             "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 || (sk_X509_num(cert_stack) == 0)) {
                    if (!cert) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02222)
                                      "Cannot find peer certificate chain");
    
                        return HTTP_FORBIDDEN;
                    }
    
                    /* 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_X509_new_null();
                    sk_X509_push(cert_stack, cert);
                }
    
                if (!(cert_store ||
                      (cert_store = SSL_CTX_get_cert_store(ctx))))
                {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02223)
                                  "Cannot find certificate storage");
    
                    return HTTP_FORBIDDEN;
                }
    
                if (!cert) {
                    cert = sk_X509_value(cert_stack, 0);
                }
    
                cert_store_ctx = X509_STORE_CTX_new();
                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 (!X509_verify_cert(cert_store_ctx)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02224)
                                  "Re-negotiation verification step failed");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
                }
    
                SSL_set_verify_result(ssl, X509_STORE_CTX_get_error(cert_store_ctx));
                X509_STORE_CTX_cleanup(cert_store_ctx);
                X509_STORE_CTX_free(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 {
                char peekbuf[1];
                const char *reneg_support;
                request_rec *id = r->main ? r->main : r;
    
                /* Additional mitigation for CVE-2009-3555: At this point,
                 * before renegotiating, an (entire) request has been read
                 * from the connection.  An attacker may have sent further
                 * data to "prefix" any subsequent request by the victim's
                 * client after the renegotiation; this data may already
                 * have been read and buffered.  Forcing a connection
                 * closure after the response ensures such data will be
                 * discarded.  Legimately pipelined HTTP requests will be
                 * retried anyway with this approach. */
                if (has_buffered_data(r)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02259)
                                  "insecure SSL re-negotiation required, but "
                                  "a pipelined request is present; keepalive "
                                  "disabled");
                    r->connection->keepalive = AP_CONN_CLOSE;
                }
    
    #if defined(SSL_get_secure_renegotiation_support)
                reneg_support = SSL_get_secure_renegotiation_support(ssl) ?
                                "client does" : "client does not";
    #else
                reneg_support = "server does not";
    #endif
                /* Perform a full renegotiation. */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02260)
                              "Performing full renegotiation: complete handshake "
                              "protocol (%s support secure renegotiation)",
                              reneg_support);
    
                SSL_set_session_id_context(ssl,
                                           (unsigned char *)&id,
                                           sizeof(id));
    
                /* Toggle the renegotiation state to allow the new
                 * handshake to proceed. */
                modssl_set_reneg_state(sslconn, RENEG_ALLOW);
    
                SSL_renegotiate(ssl);
                SSL_do_handshake(ssl);
    
                if (!SSL_is_init_finished(ssl)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02225)
                                  "Re-negotiation request failed");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
    
                    r->connection->keepalive = AP_CONN_CLOSE;
                    return HTTP_FORBIDDEN;
                }
    
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02226)
                              "Awaiting re-negotiation handshake");
    
                /* XXX: Should replace setting state with SSL_renegotiate(ssl);
                 * However, this causes failures in perl-framework currently,
                 * perhaps pre-test if we have already negotiated?
                 */
                /* Need to trigger renegotiation handshake by reading.
                 * Peeking 0 bytes actually works.
                 * See: http://marc.info/?t=145493359200002&r=1&w=2
                 */
                SSL_peek(ssl, peekbuf, 0);
    
                modssl_set_reneg_state(sslconn, RENEG_REJECT);
    
                if (!SSL_is_init_finished(ssl)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261)
                                  "Re-negotiation handshake failed");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
    
                    r->connection->keepalive = AP_CONN_CLOSE;
                    return HTTP_FORBIDDEN;
                }
    
                /* Full renegotiation successful, we now have handshaken with
                 * this server's parameters.
                 */
                sslconn->server = r->server;
            }
    
            /*
             * Finally check for acceptable renegotiation results
             */
            if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, sslconn, ssl))) {
                return rc;
            }
    
            /*
             * 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, APLOGNO(02264)
                                 "SSL cipher suite not renegotiated: "
                                 "access to %s denied using cipher %s",
                                  r->filename,
                                  SSL_CIPHER_get_name(cipher));
                    return HTTP_FORBIDDEN;
                }
            }
            /* remember any new cipher suite used in renegotiation */
            if (ncipher_suite) {
                sslconn->cipher_suite = ncipher_suite;
            }
        }
    
        return DECLINED;
    }
    
    #if SSL_HAVE_PROTOCOL_TLSV1_3
    /*
     *  Access Handler, modern flavour, for SSL/TLS v1.3 and onward. 
     *  Only client certificates can be requested, everything else stays.
     */
    static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirConfigRec *dc,
                                      SSLConnRec *sslconn, SSL *ssl)
    {
        if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) ||
            (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
            int vmode_inplace, vmode_needed;
            int change_vmode = FALSE;
            int n, rc;
    
            vmode_inplace = SSL_get_verify_mode(ssl);
            vmode_needed = SSL_VERIFY_NONE;
    
            if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
                (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) {
                vmode_needed |= SSL_VERIFY_PEER_STRICT;
            }
    
            if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) ||
                (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) ||
                (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
                (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
            {
                vmode_needed |= SSL_VERIFY_PEER;
            }
    
            if (vmode_needed == SSL_VERIFY_NONE) {
                return DECLINED;
            }
    
            vmode_needed |= SSL_VERIFY_CLIENT_ONCE;
            if (vmode_inplace != vmode_needed) {
                /* Need to change, if new setting is more restrictive than existing one */
    
                if ((vmode_inplace == SSL_VERIFY_NONE)
                    || (!(vmode_inplace   & SSL_VERIFY_PEER) 
                        && (vmode_needed  & SSL_VERIFY_PEER))
                    || (!(vmode_inplace   & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) 
                        && (vmode_needed & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
                    /* need to change the effective verify mode */
                    change_vmode = TRUE;
                }
                else {
                    /* FIXME: does this work with TLSv1.3? Is this more than re-inspecting
                     * the certificate we should already have? */
                    /*
                     * 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
                     * SSLConnRec 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).
                     */
                    n = (sslconn->verify_depth != UNSET)? 
                        sslconn->verify_depth : sc->server->auth.verify_depth;
                    /* determine the new depth */
                    sslconn->verify_depth = (dc->nVerifyDepth != UNSET)
                                            ? dc->nVerifyDepth
                                            : sc->server->auth.verify_depth;
                    if (sslconn->verify_depth < n) {
                        change_vmode = TRUE;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10128)
                                      "Reduced client verification depth will "
                                      "force renegotiation");
                    }
                }
            }
    
            /* Fill reneg buffer if required. */
            if (change_vmode) {
                char peekbuf[1];
    
                if (r->connection->master) {
                    /* FIXME: modifying the SSL on a slave connection is no good.
                     * We would need to push this back to the master connection
                     * somehow.
                     */
                    apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "verify-client");
                    return HTTP_FORBIDDEN;
                }
    
                rc = fill_reneg_buffer(r, dc);
                if (rc) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10228)
                                  "could not buffer message body to allow "
                                  "TLS Post-Handshake Authentication to proceed");
                    return rc;
                }
                
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10129)
                              "verify client post handshake");
    
                SSL_set_verify(ssl, vmode_needed, ssl_callback_SSLVerify);
    
                if (SSL_verify_client_post_handshake(ssl) != 1) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10158)
                                  "cannot perform post-handshake authentication");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
                    apr_table_setn(r->notes, "error-notes",
                                   "Reason: Cannot perform Post-Handshake Authentication.<br />");
                    SSL_set_verify(ssl, vmode_inplace, NULL);
                    return HTTP_FORBIDDEN;
                }
                
                modssl_set_app_data2(ssl, r);
    
                SSL_do_handshake(ssl);
                /* Need to trigger renegotiation handshake by reading.
                 * Peeking 0 bytes actually works.
                 * See: http://marc.info/?t=145493359200002&r=1&w=2
                 */
                SSL_peek(ssl, peekbuf, 0);
    
                modssl_set_app_data2(ssl, NULL);
    
                /*
                 * Finally check for acceptable renegotiation results
                 */
                if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, sslconn, ssl))) {
                    SSL_set_verify(ssl, vmode_inplace, NULL);
                    return rc;
                }
            }
        }
    
        return DECLINED;
    }
    #endif
    
    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;
        apr_array_header_t *requires;
        ssl_require_t *ssl_requires;
        int ok, i, ret;
    
        /* On a slave connection, we do not expect to have an SSLConnRec, but
         * our master connection might have one. */
        if (!(sslconn && ssl) && r->connection->master) {
            sslconn         = myConnConfig(r->connection->master);
            ssl             = sslconn ? sslconn->ssl : NULL;
        }
    
        /*
         * We should have handshaken here, otherwise we are being 
         * redirected (ErrorDocument) from a renegotiation failure below. 
         * The access is still forbidden in the latter case, let ap_die() handle
         * this recursive (same) error.
         */
        if (ssl && !SSL_is_init_finished(ssl)) {
            return HTTP_FORBIDDEN;
        }
    
        /*
         * Support for SSLRequireSSL directive
         */
        if (dc->bSSLRequired && !ssl) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219)
                          "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 whether SSL is in use; if it's not, then no
         * further access control checks are relevant.  (the test for
         * sc->enabled is probably strictly unnecessary)
         */
        if (sc->enabled == SSL_ENABLED_FALSE || !ssl) {
            return DECLINED;
        }
    
    #if SSL_HAVE_PROTOCOL_TLSV1_3
        /* TLSv1.3+ is less complicated here. Branch off into a new codeline
         * and avoid messing with the past. */
        if (SSL_version(ssl) >= TLS1_3_VERSION) {
            ret = ssl_hook_Access_modern(r, sc, dc, sslconn, ssl);
        }
        else
    #endif
        {
            ret = ssl_hook_Access_classic(r, sc, dc, sslconn, ssl);
        }
    
        if (ret != DECLINED) {
            return ret;
        }
    
        /* 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;
            else
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02227)
                              "Failed to set r->user to '%s'", dc->szUserName);
        }
    
        /*
         * 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];
            const char *errstring;
            ok = ap_expr_exec(r, req->mpExpr, &errstring);
    
            if (ok < 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02265)
                              "access to %s failed, reason: Failed to execute "
                              "SSL requirement expression: %s",
                              r->filename, errstring);
    
                /* remember forbidden access for strict require option */
                apr_table_setn(r->notes, "ssl-access-forbidden", "1");
    
                return HTTP_FORBIDDEN;
            }
    
            if (ok != 1) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02266)
                              "Access to %s denied for %s "
                              "(requirement expression not fulfilled)",
                              r->filename, r->useragent_ip);
    
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02228)
                              "Failed expression: %s", req->cpExpr);
    
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02229)
                              "access to %s failed, reason: %s",
                              r->filename,
                              "SSL requirement expression not fulfilled");
    
                /* 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
     *  occurring, 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;
        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, APLOGNO(02035)
                        "Encountered FakeBasicAuth spoof: %s", username);
                    return HTTP_FORBIDDEN;
                }
            }
        }
    
        /*
         * We decline operation in various situations...
         * - TLS not enabled
         * - client did not present a certificate
         * - SSLOptions +FakeBasicAuth not configured
         * - r->user already authenticated
         */
        if (!modssl_request_is_tls(r, &sslconn)
            || !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);
            OPENSSL_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_setn(r->headers_in, "Authorization", auth_line);
    
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02036)
                      "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 *const ssl_hook_Fixup_vars[] = {
        "SSL_VERSION_INTERFACE",
        "SSL_VERSION_LIBRARY",
        "SSL_PROTOCOL",
        "SSL_SECURE_RENEG",
        "SSL_COMPRESS_METHOD",
        "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_I_DN",
        "SSL_CLIENT_A_KEY",
        "SSL_CLIENT_A_SIG",
        "SSL_CLIENT_CERT_RFC4523_CEA",
        "SSL_SERVER_M_VERSION",
        "SSL_SERVER_M_SERIAL",
        "SSL_SERVER_V_START",
        "SSL_SERVER_V_END",
        "SSL_SERVER_S_DN",
        "SSL_SERVER_I_DN",
        "SSL_SERVER_A_KEY",
        "SSL_SERVER_A_SIG",
        "SSL_SESSION_ID",
        "SSL_SESSION_RESUMED",
    #ifdef HAVE_SRP
        "SSL_SRP_USER",
        "SSL_SRP_USERINFO",
    #endif
        NULL
    };
    
    int ssl_hook_Fixup(request_rec *r)
    {
        SSLDirConfigRec *dc = myDirConfig(r);
        apr_table_t *env = r->subprocess_env;
        char *var, *val = "";
    #ifdef HAVE_TLSEXT
        const char *servername;
    #endif
        STACK_OF(X509) *peer_certs;
        SSLConnRec *sslconn;
        SSL *ssl;
        int i;
    
        if (!modssl_request_is_tls(r, &sslconn)) {
            return DECLINED;
        }
        ssl = sslconn->ssl;
    
        /*
         * Annotate the SSI/CGI environment with standard SSL information
         */
        /* the always present HTTPS (=HTTP over SSL) flag! */
        apr_table_setn(env, "HTTPS", "on");
    
    #ifdef HAVE_TLSEXT
        /* add content of SNI TLS extension (if supplied with ClientHello) */
        if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
            apr_table_set(env, "SSL_TLS_SNI", servername);
        }
    #endif
    
        /* standard SSL environment variables */
        if (dc->nOptions & SSL_OPT_STDENVVARS) {
            modssl_var_extract_dns(env, ssl, r->pool);
            modssl_var_extract_san_entries(env, ssl, r->pool);
    
            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);
                    }
                }
            }
        }
    
    
    #ifdef SSL_get_secure_renegotiation_support
        apr_table_setn(r->notes, "ssl-secure-reneg",
                       SSL_get_secure_renegotiation_support(ssl) ? "1" : "0");
    #endif
    
        return DECLINED;
    }
    
    /*  _________________________________________________________________
    **
    **  Authz providers for use with mod_authz_core
    **  _________________________________________________________________
    */
    
    static authz_status ssl_authz_require_ssl_check(request_rec *r,
                                                    const char *require_line,
                                                    const void *parsed)
    {
        if (modssl_request_is_tls(r, NULL))
            return AUTHZ_GRANTED;
        else
            return AUTHZ_DENIED;
    }
    
    static const char *ssl_authz_require_ssl_parse(cmd_parms *cmd,
                                                   const char *require_line,
                                                   const void **parsed)
    {
        if (require_line && require_line[0])
            return "'Require ssl' does not take arguments";
    
        return NULL;
    }
    
    const authz_provider ssl_authz_provider_require_ssl =
    {
        &ssl_authz_require_ssl_check,
        &ssl_authz_require_ssl_parse,
    };
    
    static authz_status ssl_authz_verify_client_check(request_rec *r,
                                                      const char *require_line,
                                                      const void *parsed)
    {
        SSLConnRec *sslconn = myConnConfig(r->connection);
        SSL *ssl = sslconn ? sslconn->ssl : NULL;
    
        if (!ssl)
            return AUTHZ_DENIED;
    
        if (sslconn->verify_error == NULL &&
            sslconn->verify_info == NULL &&
            SSL_get_verify_result(ssl) == X509_V_OK)
        {
            X509 *xs = SSL_get_peer_certificate(ssl);
    
            if (xs) {
                X509_free(xs);
                return AUTHZ_GRANTED;
            }
            else {
                X509_free(xs);
            }
        }
    
        return AUTHZ_DENIED;
    }
    
    static const char *ssl_authz_verify_client_parse(cmd_parms *cmd,
                                                     const char *require_line,
                                                     const void **parsed)
    {
        if (require_line && require_line[0])
            return "'Require ssl-verify-client' does not take arguments";
    
        return NULL;
    }
    
    const authz_provider ssl_authz_provider_verify_client =
    {
        &ssl_authz_verify_client_check,
        &ssl_authz_verify_client_parse,
    };
    
    
    
    /*  _________________________________________________________________
    **
    **  OpenSSL Callback Functions
    **  _________________________________________________________________
    */
    
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    /*
     * Hand out standard DH parameters, based on the authentication strength
     */
    DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
    {
        conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
        EVP_PKEY *pkey;
        int type;
    
    #ifdef SSL_CERT_SET_SERVER
        /*
         * When multiple certs/keys are configured for the SSL_CTX: make sure
         * that we get the private key which is indeed used for the current
         * SSL connection (available in OpenSSL 1.0.2 or later only)
         */
        SSL_set_current_cert(ssl, SSL_CERT_SET_SERVER);
    #endif
        pkey = SSL_get_privatekey(ssl);
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
        type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
    #else
        type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
    #endif
    
        /*
         * OpenSSL will call us with either keylen == 512 or keylen == 1024
         * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
         * Adjust the DH parameter length according to the size of the
         * RSA/DSA private key used for the current connection, and always
         * use at least 1024-bit parameters.
         * Note: This may cause interoperability issues with implementations
         * which limit their DH support to 1024 bit - e.g. Java 7 and earlier.
         * In this case, SSLCertificateFile can be used to specify fixed
         * 1024-bit DH parameters (with the effect that OpenSSL skips this
         * callback).
         */
        if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
            keylen = EVP_PKEY_bits(pkey);
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "handing out built-in DH parameters for %d-bit authenticated connection", keylen);
    
        return modssl_get_dh_params(keylen);
    }
    #endif
    
    /*
     * 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);
        request_rec *r      = (request_rec *)modssl_get_app_data2(ssl);
        server_rec *s       = r ? r->server : mySrvFromConn(conn);
    
        SSLSrvConfigRec *sc = mySrvConfig(s);
        SSLConnRec *sslconn = myConnConfig(conn);
        SSLDirConfigRec *dc = r ? myDirConfig(r) : sslconn->dc;
        modssl_ctx_t *mctx  = myConnCtxConfig(conn, sc);
        int crl_check_mode  = mctx->crl_check_mask & ~SSL_CRLCHECK_FLAGS;
    
        /* Get verify ingredients */
        int errnum   = X509_STORE_CTX_get_error(ctx);
        int errdepth = X509_STORE_CTX_get_error_depth(ctx);
        int depth = UNSET;
        int verify = SSL_CVERIFY_UNSET;
    
        /*
         * Log verification information
         */
        ssl_log_cxerror(SSLLOG_MARK, APLOG_DEBUG, 0, conn,
                        X509_STORE_CTX_get_current_cert(ctx), APLOGNO(02275)
                        "Certificate Verification, depth %d, "
                        "CRL checking mode: %s (%x)", errdepth,
                        crl_check_mode == SSL_CRLCHECK_CHAIN ? "chain" :
                        crl_check_mode == SSL_CRLCHECK_LEAF  ? "leaf"  : "none",
                        mctx->crl_check_mask);
    
        /*
         * Check for optionally acceptable non-verifiable issuer situation
         */
        if (dc) {
            if (conn->outgoing) {
                verify = dc->proxy->auth.verify_mode;
            }
            else {
                verify = dc->nVerifyClient;
            }
        }
        if (!dc || (verify == SSL_CVERIFY_UNSET)) {
            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_cerror(APLOG_MARK, APLOG_DEBUG, 0, conn, APLOGNO(02037)
                          "Certificate Verification: Verifiable Issuer is "
                          "configured as optional, therefore we're accepting "
                          "the certificate");
    
            sslconn->verify_info = "GENEROUS";
            ok = TRUE;
        }
    
        /*
         * Expired certificates vs. "expired" CRLs: by default, OpenSSL
         * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
         * SSL alert, but that's not really the message we should convey to the
         * peer (at the very least, it's confusing, and in many cases, it's also
         * inaccurate, as the certificate itself may very well not have expired
         * yet). We set the X509_STORE_CTX error to something which OpenSSL's
         * s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
         * i.e. the peer will receive a "certificate_unknown(46)" alert.
         * We do not touch errnum, though, so that later on we will still log
         * the "real" error, as returned by OpenSSL.
         */
        if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
            X509_STORE_CTX_set_error(ctx, -1);
        }
    
        if (!ok && errnum == X509_V_ERR_UNABLE_TO_GET_CRL
                && (mctx->crl_check_mask & SSL_CRLCHECK_NO_CRL_FOR_CERT_OK)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, conn,
                          "Certificate Verification: Temporary error (%d): %s: "
                          "optional therefore we're accepting the certificate",
                          errnum, X509_verify_cert_error_string(errnum));
            X509_STORE_CTX_set_error(ctx, X509_V_OK);
            errnum = X509_V_OK;
            ok = TRUE;
        }
    
    #ifndef OPENSSL_NO_OCSP
        /*
         * Perform OCSP-based revocation checks
         */
        if (ok && ((mctx->ocsp_mask & SSL_OCSPCHECK_CHAIN) ||
             (errdepth == 0 && (mctx->ocsp_mask & SSL_OCSPCHECK_LEAF)))) {     
            /* If there was an optional verification error, it's not
             * possible to perform OCSP validation since the issuer may be
             * missing/untrusted.  Fail in that case. */
            if (ssl_verify_error_is_optional(errnum)) {
                X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
                errnum = X509_V_ERR_APPLICATION_VERIFICATION;
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn, APLOGNO(02038)
                              "cannot perform OCSP validation for cert "
                              "if issuer has not been verified "
                              "(optional_no_ca configured)");
                ok = FALSE;
            } else {
                ok = modssl_verify_ocsp(ctx, sc, s, conn, conn->pool);
                if (!ok) {
                    errnum = X509_STORE_CTX_get_error(ctx);
                }
            }
        }
    #endif
    
        /*
         * If we already know it's not ok, log the real reason
         */
        if (!ok) {
            if (APLOGcinfo(conn)) {
                ssl_log_cxerror(SSLLOG_MARK, APLOG_INFO, 0, conn,
                                X509_STORE_CTX_get_current_cert(ctx), APLOGNO(02276)
                                "Certificate Verification: Error (%d): %s",
                                errnum, X509_verify_cert_error_string(errnum));
            } else {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn, APLOGNO(02039)
                              "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) {
            if (conn->outgoing) {
                depth = dc->proxy->auth.verify_depth;
            }
            else {
                depth = dc->nVerifyDepth;
            }
        }
        if (!dc || (depth == UNSET)) {
            depth = mctx->auth.verify_depth;
        }
    
        if (errdepth > depth) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn, APLOGNO(02040)
                          "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;
    }
    
    #define SSLPROXY_CERT_CB_LOG_FMT \
       "Proxy client certificate callback: (%s) "
    
    static void modssl_proxy_info_log(conn_rec *c,
                                      X509_INFO *info,
                                      const char *msg)
    {
        ssl_log_cxerror(SSLLOG_MARK, APLOG_DEBUG, 0, c, info->x509, APLOGNO(02277)
                        SSLPROXY_CERT_CB_LOG_FMT "%s, sending",
                        (mySrvConfigFromConn(c))->vhost_id, msg);
    }
    
    /*
     * caller will decrement the cert and key reference
     * so we need to increment here to prevent them from
     * being freed.
     */
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    #define modssl_set_cert_info(info, cert, pkey) \
        *cert = info->x509; \
        CRYPTO_add(&(*cert)->references, +1, CRYPTO_LOCK_X509); \
        *pkey = info->x_pkey->dec_pkey; \
        CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_EVP_PKEY)
    #else
    #define modssl_set_cert_info(info, cert, pkey) \
        *cert = info->x509; \
        X509_up_ref(*cert); \
        *pkey = info->x_pkey->dec_pkey; \
        EVP_PKEY_up_ref(*pkey);
    #endif
    
    int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
    {
        conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
        server_rec *s = mySrvFromConn(c);
        SSLSrvConfigRec *sc = mySrvConfig(s);
        SSLDirConfigRec *dc = myDirConfigFromConn(c);
        X509_NAME *ca_name, *issuer, *ca_issuer;
        X509_INFO *info;
        X509 *ca_cert;
        STACK_OF(X509_NAME) *ca_list;
        STACK_OF(X509_INFO) *certs;
        STACK_OF(X509) *ca_certs;
        STACK_OF(X509) **ca_cert_chains;
        int i, j, k;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02267)
                     SSLPROXY_CERT_CB_LOG_FMT "entered",
                     sc->vhost_id);
    
        certs = (dc && dc->proxy) ? dc->proxy->pkp->certs : NULL;
        if (!certs || (sk_X509_INFO_num(certs) <= 0)) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02268)
                         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(c, info, APLOGNO(02278) "no acceptable CA list");
    
            modssl_set_cert_info(info, x509, pkey);
    
            return TRUE;
        }
    
        ca_cert_chains = dc->proxy->pkp->ca_certs;
        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);
    
                /* Search certs (by issuer name) one by one*/
                if (X509_NAME_cmp(issuer, ca_name) == 0) {
                    modssl_proxy_info_log(c, info, APLOGNO(02279)
                                          "found acceptable cert");
    
                    modssl_set_cert_info(info, x509, pkey);
    
                    return TRUE;
                }
    
                if (ca_cert_chains) {
                    /*
                     * Failed to find direct issuer - search intermediates
                     * (by issuer name), if provided.
                     */
                    ca_certs = ca_cert_chains[j];
                    for (k = 0; k < sk_X509_num(ca_certs); k++) {
                        ca_cert = sk_X509_value(ca_certs, k);
                        ca_issuer = X509_get_issuer_name(ca_cert);
    
                        if(X509_NAME_cmp(ca_issuer, ca_name) == 0 ) {
                            modssl_proxy_info_log(c, info, APLOGNO(02280)
                                                  "found acceptable cert by intermediate CA");
    
                            modssl_set_cert_info(info, x509, pkey);
    
                            return TRUE;
                        }
                    } /* end loop through chained certs */
                }
            } /* end loop through available certs */
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02269)
                     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,
                                IDCONST unsigned char *id,
                                unsigned int idlen,
                                const char *status,
                                const char *result,
                                long timeout)
    {
        char buf[MODSSL_SESSION_ID_STRING_LEN];
        char timeout_str[56] = {'\0'};
    
        if (!APLOGdebug(s)) {
            return;
        }
    
        if (timeout) {
            apr_snprintf(timeout_str, sizeof(timeout_str),
                         "timeout=%lds ", timeout);
        }
    
        ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
                     "Inter-Process Session Cache: "
                     "request=%s status=%s id=%s %s(session %s)",
                     request, status,
                     modssl_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       = mySrvFromConn(conn);
        SSLSrvConfigRec *sc = mySrvConfig(s);
        long timeout        = sc->session_cache_timeout;
        BOOL rc;
        IDCONST 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.
         */
    #ifdef OPENSSL_NO_SSL_INTERN
        id = (unsigned char *)SSL_SESSION_get_id(session, &idlen);
    #else
        id = session->session_id;
        idlen = session->session_id_length;
    #endif
    
        rc = ssl_scache_store(s, id, idlen,
                              apr_time_from_sec(SSL_SESSION_get_time(session)
                                              + timeout),
                              session, conn->pool);
    
        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,
                                                   IDCONST 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  = mySrvFromConn(conn);
        SSL_SESSION *session;
    
        /*
         * Try to retrieve the SSL_SESSION from the inter-process cache
         */
        session = ssl_scache_retrieve(s, id, idlen, conn->pool);
    
        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 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;
        IDCONST 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
         */
    #ifdef OPENSSL_NO_SSL_INTERN
        id = (unsigned char *)SSL_SESSION_get_id(session, &idlen);
    #else
        id = session->session_id;
        idlen = session->session_id_length;
    #endif
    
        /* TODO: Do we need a temp pool here, or are we always shutting down? */
        ssl_scache_remove(s, id, idlen, sc->mc->pPool);
    
        ssl_session_log(s, "REM", id, idlen,
                        "OK", "dead", 0);
    
        return;
    }
    
    /* Dump debugginfo trace to the log file. */
    static void log_tracing_state(const SSL *ssl, conn_rec *c,
                                  server_rec *s, int where, int rc)
    {
        /*
         * create the various trace messages
         */
        if (where & SSL_CB_HANDSHAKE_START) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                          "%s: Handshake: start", MODSSL_LIBRARY_NAME);
        }
        else if (where & SSL_CB_HANDSHAKE_DONE) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                          "%s: Handshake: done", MODSSL_LIBRARY_NAME);
        }
        else if (where & SSL_CB_LOOP) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                          "%s: Loop: %s",
                          MODSSL_LIBRARY_NAME, SSL_state_string_long(ssl));
        }
        else if (where & SSL_CB_READ) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                          "%s: Read: %s",
                          MODSSL_LIBRARY_NAME, SSL_state_string_long(ssl));
        }
        else if (where & SSL_CB_WRITE) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                          "%s: Write: %s",
                          MODSSL_LIBRARY_NAME, SSL_state_string_long(ssl));
        }
        else if (where & SSL_CB_ALERT) {
            char *str = (where & SSL_CB_READ) ? "read" : "write";
            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                          "%s: Alert: %s:%s:%s",
                          MODSSL_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_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                              "%s: Exit: failed in %s",
                              MODSSL_LIBRARY_NAME, SSL_state_string_long(ssl));
            }
            else if (rc < 0) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
                              "%s: Exit: error in %s",
                              MODSSL_LIBRARY_NAME, SSL_state_string_long(ssl));
            }
        }
    
        /*
         * Because SSL renegotiations 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_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02041)
                          "Protocol: %s, Cipher: %s (%s/%s bits)",
                          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"));
        }
    }
    
    /*
     * This callback function is executed while OpenSSL processes the SSL
     * handshake and does SSL record layer stuff.  It's used to trap
     * client-initiated renegotiations (where SSL_OP_NO_RENEGOTIATION is
     * not available), and for dumping everything to the log.
     */
    void ssl_callback_Info(const SSL *ssl, int where, int rc)
    {
        conn_rec *c;
        server_rec *s;
    
        /* Retrieve the conn_rec and the associated SSLConnRec. */
        if ((c = (conn_rec *)SSL_get_app_data((SSL *)ssl)) == NULL) {
            return;
        }
    
    #ifndef SSL_OP_NO_RENEGOTIATION
        /* With OpenSSL < 1.1.1 (implying TLS v1.2 or earlier), this
         * callback is used to block client-initiated renegotiation.  With
         * TLSv1.3 it is unnecessary since renegotiation is forbidden at
         * protocol level.  Otherwise (TLSv1.2 with OpenSSL >=1.1.1),
         * SSL_OP_NO_RENEGOTIATION is used to block renegotiation. */
        {
            SSLConnRec *sslconn;
    
            if ((sslconn = myConnConfig(c)) == NULL) {
                return;
            }
    
            /* If the reneg state is to reject renegotiations, check the SSL
             * state machine and move to ABORT if a Client Hello is being
             * read. */
            if (!c->outgoing &&
                    (where & SSL_CB_HANDSHAKE_START) &&
                    sslconn->reneg_state == RENEG_REJECT) {
                sslconn->reneg_state = RENEG_ABORT;
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02042)
                              "rejecting client initiated renegotiation");
            }
            /* If the first handshake is complete, change state to reject any
             * subsequent client-initiated renegotiation. */
            else if ((where & SSL_CB_HANDSHAKE_DONE)
                     && sslconn->reneg_state == RENEG_INIT) {
                sslconn->reneg_state = RENEG_REJECT;
            }
        }
    #endif
    
        s = mySrvFromConn(c);
        if (s && APLOGdebug(s)) {
            log_tracing_state(ssl, c, s, where, rc);
        }
    }
    
    #ifdef HAVE_TLSEXT
    
    static apr_status_t set_challenge_creds(conn_rec *c, const char *servername,
                                            SSL *ssl, X509 *cert, EVP_PKEY *key,
                                            const char *cert_pem, const char *key_pem)
    {
        SSLConnRec *sslcon = myConnConfig(c);
        apr_status_t rv = APR_SUCCESS;
        int our_data = 0;
        
        sslcon->service_unavailable = 1;
        if (cert_pem) {
            cert = NULL;
            key = NULL;
            our_data = 1;
            
            rv = modssl_read_cert(c->pool, cert_pem, key_pem, NULL, NULL, &cert, &key);
            if (rv != APR_SUCCESS) {
                ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10266)
                              "Failed to parse PEM of challenge certificate %s",
                              servername);
                goto cleanup;
            }
        }
        
        if ((SSL_use_certificate(ssl, cert) < 1)) {
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086)
                          "Failed to configure challenge certificate %s",
                          servername);
            rv = APR_EGENERAL;
            goto cleanup;
        }
        
        if (!SSL_use_PrivateKey(ssl, key)) {
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087)
                          "error '%s' using Challenge key: %s",
                          ERR_error_string(ERR_peek_last_error(), NULL), 
                          servername);
            rv = APR_EGENERAL;
            goto cleanup;
        }
        
        if (SSL_check_private_key(ssl) < 1) {
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088)
                          "Challenge certificate and private key %s "
                          "do not match", servername);
            rv = APR_EGENERAL;
            goto cleanup;
        }
        
    cleanup:
        if (our_data && cert) X509_free(cert);
        if (our_data && key) EVP_PKEY_free(key);
        return APR_SUCCESS;
    }
      
    /*
     * This function sets the virtual host from an extended
     * client hello with a server name indication extension ("SNI", cf. RFC 6066).
     */
    static apr_status_t init_vhost(conn_rec *c, SSL *ssl, const char *servername)
    {
        if (c) {
            SSLConnRec *sslcon = myConnConfig(c);
    
            if (sslcon->vhost_found) {
                /* already found the vhost? */
                return sslcon->vhost_found > 0 ? APR_SUCCESS : APR_NOTFOUND;
            }
            sslcon->vhost_found = -1;
            
            if (!servername) {
                servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
            }
            if (servername) {
                if (ap_vhost_iterate_given_conn(c, ssl_find_vhost,
                                                (void *)servername)) {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043)
                                  "SSL virtual host for servername %s found",
                                  servername);
    
                    sslcon->vhost_found = +1;
                    return APR_SUCCESS;
                }
                else {
                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02044)
                                  "No matching SSL virtual host for servername "
                                  "%s found (using default/first virtual host)",
                                  servername);
                    /*
                     * RFC 6066 section 3 says "It is NOT RECOMMENDED to send
                     * a warning-level unrecognized_name(112) alert, because
                     * the client's behavior in response to warning-level alerts
                     * is unpredictable."
                     *
                     * To maintain backwards compatibility in mod_ssl, we
                     * no longer send any alert (neither warning- nor fatal-level),
                     * i.e. we take the second action suggested in RFC 6066:
                     * "If the server understood the ClientHello extension but
                     * does not recognize the server name, the server SHOULD take
                     * one of two actions: either abort the handshake by sending
                     * a fatal-level unrecognized_name(112) alert or continue
                     * the handshake."
                     */
                }
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02645)
                              "Server name not provided via TLS extension "
                              "(using default/first virtual host)");
            }
        }
        
        return APR_NOTFOUND;
    }
    
    /*
     * This callback function is executed when OpenSSL encounters an extended
     * client hello with a server name indication extension ("SNI", cf. RFC 6066).
     */
    int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
    {
        conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
        apr_status_t status = init_vhost(c, ssl, NULL);
        
        return (status == APR_SUCCESS)? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK;
    }
    
    #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
    /*
     * This callback function is called when the ClientHello is received.
     */
    int ssl_callback_ClientHello(SSL *ssl, int *al, void *arg)
    {
        char *servername = NULL;
        conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
        const unsigned char *pos;
        size_t len, remaining;
        (void)arg;
     
        /* We can't use SSL_get_servername() at this earliest OpenSSL connection
         * stage, and there is no SSL_client_hello_get0_servername() provided as
         * of OpenSSL 1.1.1. So the code below, that extracts the SNI from the
         * ClientHello's TLS extensions, is taken from some test code in OpenSSL,
         * i.e. client_hello_select_server_ctx() in "test/handshake_helper.c".
         */
    
        /*
         * The server_name extension was given too much extensibility when it
         * was written, so parsing the normal case is a bit complex.
         */
        if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &pos,
                                       &remaining)
                || remaining <= 2) 
            goto give_up;
    
        /* Extract the length of the supplied list of names. */
        len = (*(pos++) << 8);
        len += *(pos++);
        if (len + 2 != remaining)
            goto give_up;
        remaining = len;
    
        /*
         * The list in practice only has a single element, so we only consider
         * the first one.
         */
        if (remaining <= 3 || *pos++ != TLSEXT_NAMETYPE_host_name)
            goto give_up;
        remaining--;
    
        /* Now we can finally pull out the byte array with the actual hostname. */
        len = (*(pos++) << 8);
        len += *(pos++);
        if (len + 2 != remaining)
            goto give_up;
    
        /* Use the SNI to switch to the relevant vhost, should it differ from
         * c->base_server.
         */
        servername = apr_pstrmemdup(c->pool, (const char *)pos, len);
    
    give_up:
        init_vhost(c, ssl, servername);
        return SSL_CLIENT_HELLO_SUCCESS;
    }
    #endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
    
    /*
     * Find a (name-based) SSL virtual host where either the ServerName
     * or one of the ServerAliases matches the supplied name (to be used
     * with ap_vhost_iterate_given_conn())
     */
    static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
    {
        SSLSrvConfigRec *sc;
        SSL *ssl;
        BOOL found;
        SSLConnRec *sslcon;
    
        found = ssl_util_vhost_matches(servername, s);
    
        /* set SSL_CTX (if matched) */
        sslcon = myConnConfig(c);
        if (found && (ssl = sslcon->ssl) &&
            (sc = mySrvConfig(s))) {
            SSL_CTX *ctx = SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
    
            /*
             * SSL_set_SSL_CTX() only deals with the server cert,
             * so we need to duplicate a few additional settings
             * from the ctx by hand
             */
            SSL_set_options(ssl, SSL_CTX_get_options(ctx));
    #if OPENSSL_VERSION_NUMBER >= 0x1010007fL \
            && (!defined(LIBRESSL_VERSION_NUMBER) \
                || LIBRESSL_VERSION_NUMBER >= 0x20800000L)
            /*
             * Don't switch the protocol if none is configured for this vhost,
             * the default in this case is still the base server's SSLProtocol.
             */
            if (myConnCtxConfig(c, sc)->protocol_set) {
                SSL_set_min_proto_version(ssl, SSL_CTX_get_min_proto_version(ctx));
                SSL_set_max_proto_version(ssl, SSL_CTX_get_max_proto_version(ctx));
            }
    #endif
            if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) ||
                (SSL_num_renegotiations(ssl) == 0)) {
               /*
                * Only initialize the verification settings from the ctx
                * if they are not yet set, or if we're called when a new
                * SSL connection is set up (num_renegotiations == 0).
                * Otherwise, we would possibly reset a per-directory
                * configuration which was put into effect by ssl_hook_Access.
                */
                SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx),
                               SSL_CTX_get_verify_callback(ctx));
            }
    
            /*
             * Adjust the session id context. ssl_init_ssl_connection()
             * always picks the configuration of the first vhost when
             * calling SSL_new(), but we want to tie the session to the
             * vhost we have just switched to. Again, we have to make sure
             * that we're not overwriting a session id context which was
             * possibly set in ssl_hook_Access(), before triggering
             * a renegotiation.
             */
            if (SSL_num_renegotiations(ssl) == 0) {
                unsigned char *sid_ctx =
                    (unsigned char *)ap_md5_binary(c->pool,
                                                   (unsigned char *)sc->vhost_id,
                                                   sc->vhost_id_len);
                SSL_set_session_id_context(ssl, sid_ctx, APR_MD5_DIGESTSIZE*2);
            }
    
            /*
             * Save the found server into our SSLConnRec for later
             * retrieval
             */
            sslcon->server = s;
            sslcon->cipher_suite = sc->server->auth.cipher_suite;
            sslcon->service_unavailable = sc->server->pks? 
                sc->server->pks->service_unavailable : 0; 
            
            ap_update_child_status_from_server(c->sbh, SERVER_BUSY_READ, c, s);
    
            /*
             * There is one special filter callback, which is set
             * very early depending on the base_server's log level.
             * If this is not the first vhost we're now selecting
             * (and the first vhost doesn't use APLOG_TRACE4), then
             * we need to set that callback here.
             */
            modssl_set_io_callbacks(ssl, c, s);
    
            return 1;
        }
    
        return 0;
    }
    #endif /* HAVE_TLSEXT */
    
    #ifdef HAVE_TLS_SESSION_TICKETS
    /*
     * This callback function is executed when OpenSSL needs a key for encrypting/
     * decrypting a TLS session ticket (RFC 5077) and a ticket key file has been
     * configured through SSLSessionTicketKeyFile.
     */
    int ssl_callback_SessionTicket(SSL *ssl,
                                   unsigned char *keyname,
                                   unsigned char *iv,
                                   EVP_CIPHER_CTX *cipher_ctx,
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
                                   HMAC_CTX *hmac_ctx,
    #else
                                   EVP_MAC_CTX *mac_ctx,
    #endif
                                   int mode)
    {
        conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
        server_rec *s = mySrvFromConn(c);
        SSLSrvConfigRec *sc = mySrvConfig(s);
        modssl_ctx_t *mctx = myConnCtxConfig(c, sc);
        modssl_ticket_key_t *ticket_key = mctx->ticket_key;
    
        if (mode == 1) {
            /* 
             * OpenSSL is asking for a key for encrypting a ticket,
             * see s3_srvr.c:ssl3_send_newsession_ticket()
             */
    
            if (ticket_key == NULL) {
                /* should never happen, but better safe than sorry */
                return -1;
            }
    
            memcpy(keyname, ticket_key->key_name, 16);
            if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) != 1) {
                return -1;
            }
            EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL,
                               ticket_key->aes_key, iv);
    
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
            HMAC_Init_ex(hmac_ctx, ticket_key->hmac_secret, 16,
                         tlsext_tick_md(), NULL);
    #else
            EVP_MAC_CTX_set_params(mac_ctx, ticket_key->mac_params);
    #endif
    
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02289)
                          "TLS session ticket key for %s successfully set, "
                          "creating new session ticket", sc->vhost_id);
    
            return 1;
        }
        else if (mode == 0) {
            /* 
             * OpenSSL is asking for the decryption key,
             * see t1_lib.c:tls_decrypt_ticket()
             */
    
            /* check key name */
            if (ticket_key == NULL || memcmp(keyname, ticket_key->key_name, 16)) {
                return 0;
            }
    
            EVP_DecryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL,
                               ticket_key->aes_key, iv);
    
    #if OPENSSL_VERSION_NUMBER < 0x30000000L
            HMAC_Init_ex(hmac_ctx, ticket_key->hmac_secret, 16,
                         tlsext_tick_md(), NULL);
    #else
            EVP_MAC_CTX_set_params(mac_ctx, ticket_key->mac_params);
    #endif
    
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02290)
                          "TLS session ticket key for %s successfully set, "
                          "decrypting existing session ticket", sc->vhost_id);
    
            return 1;
        }
    
        /* OpenSSL is not expected to call us with modes other than 1 or 0 */
        return -1;
    }
    #endif /* HAVE_TLS_SESSION_TICKETS */
    
    #ifdef HAVE_TLS_ALPN
    
    /*
     * This callback function is executed when the TLS Application-Layer
     * Protocol Negotiation Extension (ALPN, RFC 7301) is triggered by the Client
     * Hello, giving a list of desired protocol names (in descending preference) 
     * to the server.
     * The callback has to select a protocol name or return an error if none of
     * the clients preferences is supported.
     * The selected protocol does not have to be on the client list, according
     * to RFC 7301, so no checks are performed.
     * The client protocol list is serialized as length byte followed by ASCII
     * characters (not null-terminated), followed by the next protocol name.
     */
    int ssl_callback_alpn_select(SSL *ssl,
                                 const unsigned char **out, unsigned char *outlen,
                                 const unsigned char *in, unsigned int inlen,
                                 void *arg)
    {
        conn_rec *c = (conn_rec*)SSL_get_app_data(ssl);
        SSLConnRec *sslconn;
        apr_array_header_t *client_protos;
        const char *proposed;
        size_t len;
        int i;
    
        /* If the connection object is not available,
         * then there's nothing for us to do. */
        if (c == NULL) {
            return SSL_TLSEXT_ERR_OK;
        }
        sslconn = myConnConfig(c);
    
        if (inlen == 0) {
            /* someone tries to trick us? */
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02837)
                          "ALPN client protocol list empty");
            return SSL_TLSEXT_ERR_ALERT_FATAL;
        }
    
        client_protos = apr_array_make(c->pool, 0, sizeof(char *));
        for (i = 0; i < inlen; /**/) {
            unsigned int plen = in[i++];
            if (plen + i > inlen) {
                /* someone tries to trick us? */
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02838)
                              "ALPN protocol identifier too long");
                return SSL_TLSEXT_ERR_ALERT_FATAL;
            }
            APR_ARRAY_PUSH(client_protos, char *) =
                apr_pstrndup(c->pool, (const char *)in+i, plen);
            i += plen;
        }
    
        /* The order the callbacks are invoked from TLS extensions is, unfortunately
         * not defined and older openssl versions do call ALPN selection before
         * they callback the SNI. We need to make sure that we know which vhost
         * we are dealing with so we respect the correct protocols.
         */
        init_vhost(c, ssl, NULL);
        
        proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos);
        if (!proposed) {
            proposed = ap_get_protocol(c);
        }
        
        len = strlen(proposed);
        if (len > 255) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02840)
                          "ALPN negotiated protocol name too long");
            return SSL_TLSEXT_ERR_ALERT_FATAL;
        }
        *out = (const unsigned char *)proposed;
        *outlen = (unsigned char)len;
            
        if (strcmp(proposed, ap_get_protocol(c))) {
            apr_status_t status;
            
            status = ap_switch_protocol(c, NULL, sslconn->server, proposed);
            if (status != APR_SUCCESS) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, status, c,
                              APLOGNO(02908) "protocol switch to '%s' failed",
                              proposed);
                return SSL_TLSEXT_ERR_ALERT_FATAL;
            }
            
            /* protocol was switched, this could be a challenge protocol such as "acme-tls/1".
             * For that to work, we need to allow overrides to our ssl certificate. 
             * However, exclude challenge checks on our best known traffic protocol.
             * (http/1.1 is the default, we never switch to it anyway.)
             */
            if (strcmp("h2", proposed)) {
                const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
                X509 *cert;
                EVP_PKEY *key;
                const char *cert_pem, *key_pem;
    
                if (ssl_is_challenge(c, servername, &cert, &key, &cert_pem, &key_pem)) {
                    if (set_challenge_creds(c, servername, ssl, cert, key, 
                                            cert_pem, key_pem) != APR_SUCCESS) {
                        return SSL_TLSEXT_ERR_ALERT_FATAL;
                    }
                    SSL_set_verify(ssl, SSL_VERIFY_NONE, ssl_callback_SSLVerify);
                }
            }
        }
    
        return SSL_TLSEXT_ERR_OK;
    }
    #endif /* HAVE_TLS_ALPN */
    
    #ifdef HAVE_SRP
    
    int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg)
    {
        modssl_ctx_t *mctx = (modssl_ctx_t *)arg;
        char *username = SSL_get_srp_username(ssl);
        SRP_user_pwd *u;
    
        if (username == NULL
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
            || (u = SRP_VBASE_get_by_user(mctx->srp_vbase, username)) == NULL) {
    #else
            || (u = SRP_VBASE_get1_by_user(mctx->srp_vbase, username)) == NULL) {
    #endif
            *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
            return SSL3_AL_FATAL;
        }
    
        if (SSL_set_srp_server_param(ssl, u->N, u->g, u->s, u->v, u->info) < 0) {
    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
            SRP_user_pwd_free(u);
    #endif
            *ad = SSL_AD_INTERNAL_ERROR;
            return SSL3_AL_FATAL;
        }
    
        /* reset all other options */
    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
        SRP_user_pwd_free(u);
    #endif
        SSL_set_verify(ssl, SSL_VERIFY_NONE,  ssl_callback_SSLVerify);
        return SSL_ERROR_NONE;
    }
    
    #endif /* HAVE_SRP */
    
    
    #ifdef HAVE_OPENSSL_KEYLOG
    /* Callback used with SSL_CTX_set_keylog_callback. */
    void modssl_callback_keylog(const SSL *ssl, const char *line)
    {
        conn_rec *conn = SSL_get_app_data(ssl);
        SSLSrvConfigRec *sc = mySrvConfig(conn->base_server);
    
        if (sc && sc->mc->keylog_file) {
            apr_file_printf(sc->mc->keylog_file, "%s\n", line);
        }
    }
    #endif
    httpd-2.4.64/modules/ssl/ssl_util.c�����������������������������������������������������������������0000664�0001751�0001751�00000034056�14643704665�017124� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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)
    {
        SSLSrvConfigRec *sc;
        apr_port_t port;
    
        if (s->port != 0)
            port = s->port;
        else {
            sc = mySrvConfig(s);
            port = sc->enabled == TRUE ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;
        }
    
        return apr_psprintf(p, "%s:%lu", s->server_hostname, (unsigned long)port);
    }
    
    /*
     * Return TRUE iff the given servername matches the server record when
     * selecting virtual hosts.
     */
    BOOL ssl_util_vhost_matches(const char *servername, server_rec *s)
    {
        apr_array_header_t *names;
        int i;
        
        /* check ServerName */
        if (!strcasecmp(servername, s->server_hostname)) {
            return TRUE;
        }
        
        /*
         * if not matched yet, check ServerAlias entries
         * (adapted from vhost.c:matches_aliases())
         */
        names = s->names;
        if (names) {
            char **name = (char **)names->elts;
            for (i = 0; i < names->nelts; ++i) {
                if (!name[i])
                    continue;
                if (!strcasecmp(servername, name[i])) {
                    return TRUE;
                }
            }
        }
        
        /* if still no match, check ServerAlias entries with wildcards */
        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(servername, name[i])) {
                    return TRUE;
                }
            }
        }
        
        return FALSE;
    }
    
    int modssl_request_is_tls(const request_rec *r, SSLConnRec **scout)
    {
        SSLConnRec *sslconn = myConnConfig(r->connection);
        SSLSrvConfigRec *sc = mySrvConfig(r->server);
    
        if (!(sslconn && sslconn->ssl) && r->connection->master) {
            sslconn = myConnConfig(r->connection->master);
        }
    
        if (sc->enabled == SSL_ENABLED_FALSE || !sslconn || !sslconn->ssl)
            return 0;
        
        if (scout) *scout = sslconn;
    
        return 1;
    }
    
    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;
        proc = apr_pcalloc(p, sizeof(apr_proc_t));
        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;
        AP_DEBUG_ASSERT((pcm & SSL_PCM_EXISTS) ||
                        !(pcm & (SSL_PCM_ISREG|SSL_PCM_ISDIR|SSL_PCM_ISNONZERO)));
        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;
    }
    
    /* Decrypted private keys are cached to survive restarts.  The cached
     * data must have lifetime of the process (hence malloc/free rather
     * than pools), and uses raw DER since the EVP_PKEY structure
     * internals may not survive across a module reload. */
    ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
                                   EVP_PKEY *pkey)
    {
        apr_ssize_t klen = strlen(key);
        ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
        apr_size_t length = i2d_PrivateKey(pkey, NULL);
        unsigned char *p;
    
        /* Re-use structure if cached previously. */
        if (asn1) {
            if (asn1->nData != length) {
                asn1->cpData = ap_realloc(asn1->cpData, length);
            }
        }
        else {
            asn1 = ap_malloc(sizeof(*asn1));
            asn1->source_mtime = 0; /* used as a note for encrypted private keys */
            asn1->cpData = ap_malloc(length);
    
            apr_hash_set(table, key, klen, asn1);
        }
    
        asn1->nData = length;
        p = asn1->cpData;
        i2d_PrivateKey(pkey, &p); /* increases p by length */
    
        return asn1;
    }
    
    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);
    }
    
    #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
    
    /*
     * To ensure thread-safetyness in OpenSSL - work in progress
     */
    
    static apr_thread_mutex_t **lock_cs;
    static int                  lock_num_locks;
    
    static void ssl_util_thr_lock(int mode, int type,
                                  const char *file, int line)
    {
        if (type < lock_num_locks) {
            if (mode & CRYPTO_LOCK) {
                apr_thread_mutex_lock(lock_cs[type]);
            }
            else {
                apr_thread_mutex_unlock(lock_cs[type]);
            }
        }
    }
    
    /* Dynamic lock structure */
    struct CRYPTO_dynlock_value {
        apr_pool_t *pool;
        const char* file;
        int line;
        apr_thread_mutex_t *mutex;
    };
    
    /* Global reference to the pool passed into ssl_util_thread_setup() */
    apr_pool_t *dynlockpool = NULL;
    
    /*
     * Dynamic lock creation callback
     */
    static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
                                                         int line)
    {
        struct CRYPTO_dynlock_value *value;
        apr_pool_t *p;
        apr_status_t rv;
    
        /*
         * We need a pool to allocate our mutex.  Since we can't clear
         * allocated memory from a pool, create a subpool that we can blow
         * away in the destruction callback.
         */
        apr_pool_create(&p, dynlockpool);
        apr_pool_tag(p, "modssl_dynlock_value");
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
                      "Creating dynamic lock");
    
        value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value));
        value->pool = p;
        /* Keep our own copy of the place from which we were created,
           using our own pool. */
        value->file = apr_pstrdup(p, file);
        value->line = line;
        rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
                                    p);
        if (rv != APR_SUCCESS) {
            ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, p, APLOGNO(02186)
                          "Failed to create thread mutex for dynamic lock");
            apr_pool_destroy(p);
            return NULL;
        }
        return value;
    }
    
    /*
     * Dynamic locking and unlocking function
     */
    
    static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
                               const char *file, int line)
    {
        apr_status_t rv;
    
        if (mode & CRYPTO_LOCK) {
            ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
                          "Acquiring mutex %s:%d", l->file, l->line);
            rv = apr_thread_mutex_lock(l->mutex);
            ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
                          "Mutex %s:%d acquired!", l->file, l->line);
        }
        else {
            ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
                          "Releasing mutex %s:%d", l->file, l->line);
            rv = apr_thread_mutex_unlock(l->mutex);
            ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
                          "Mutex %s:%d released!", l->file, l->line);
        }
    }
    
    /*
     * Dynamic lock destruction callback
     */
    static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
                              const char *file, int line)
    {
        apr_status_t rv;
    
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, l->pool,
                      "Destroying dynamic lock %s:%d", l->file, l->line);
        rv = apr_thread_mutex_destroy(l->mutex);
        if (rv != APR_SUCCESS) {
            ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, l->pool,
                          APLOGNO(02192) "Failed to destroy mutex for dynamic "
                          "lock %s:%d", l->file, l->line);
        }
    
        /* Trust that whomever owned the CRYPTO_dynlock_value we were
         * passed has no future use for it...
         */
        apr_pool_destroy(l->pool);
    }
    
    #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    
    static void ssl_util_thr_id(CRYPTO_THREADID *id)
    {
        /* 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]; /* PSATOLD is at offset 540 in the PSA */
            unsigned long PSATOLD;
        } *psaptr = 0; /* PSA is at address 0 */
    
        CRYPTO_THREADID_set_numeric(id, psaptr->PSATOLD);
    #else
        CRYPTO_THREADID_set_numeric(id, (unsigned long) apr_os_thread_current());
    #endif
    }
    
    static apr_status_t ssl_util_thr_id_cleanup(void *old)
    {
        CRYPTO_THREADID_set_callback(old);
        return APR_SUCCESS;
    }
    
    #else
    
    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_thr_id_cleanup(void *old)
    {
        CRYPTO_set_id_callback(old);
        return APR_SUCCESS;
    }
    
    #endif
    
    static apr_status_t ssl_util_thread_cleanup(void *data)
    {
        CRYPTO_set_locking_callback(NULL);
    
        CRYPTO_set_dynlock_create_callback(NULL);
        CRYPTO_set_dynlock_lock_callback(NULL);
        CRYPTO_set_dynlock_destroy_callback(NULL);
    
        dynlockpool = 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_locking_callback(ssl_util_thr_lock);
    
        /* Set up dynamic locking scaffolding for OpenSSL to use at its
         * convenience.
         */
        dynlockpool = p;
        CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
        CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
        CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
    
        apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
                                           apr_pool_cleanup_null);
    }
    
    void ssl_util_thread_id_setup(apr_pool_t *p)
    {
    #if OPENSSL_VERSION_NUMBER >= 0x10000000L
        CRYPTO_THREADID_set_callback(ssl_util_thr_id);
    #else
        CRYPTO_set_id_callback(ssl_util_thr_id);
    #endif
        apr_pool_cleanup_register(p, NULL, ssl_util_thr_id_cleanup,
                                           apr_pool_cleanup_null);
    }
    
    #endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */
    
    int modssl_is_engine_id(const char *name)
    {
    #if MODSSL_HAVE_ENGINE_API || MODSSL_HAVE_OPENSSL_STORE
        /* ### Can handle any other special ENGINE key names here? */
        return strncmp(name, "pkcs11:", 7) == 0;
    #else
        return 0;
    #endif
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/mod_ssl_openssl.h����������������������������������������������������������0000664�0001751�0001751�00000011457�14526120464�020463� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_ssl_openssl.h
     * @brief Interface to OpenSSL-specific APIs provided by mod_ssl
     *
     * @defgroup MOD_SSL mod_ssl_openssl
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #ifndef __MOD_SSL_OPENSSL_H__
    #define __MOD_SSL_OPENSSL_H__
    
    #include "mod_ssl.h"
    
    /* OpenSSL headers */
    
    #include <openssl/opensslv.h>
    #if OPENSSL_VERSION_NUMBER >= 0x30000000
    #include <openssl/macros.h> /* for OPENSSL_API_LEVEL */
    #endif
    #if OPENSSL_VERSION_NUMBER >= 0x10001000
    /* must be defined before including ssl.h */
    #define OPENSSL_NO_SSL_INTERN
    #endif
    #include <openssl/ssl.h>
    #include <openssl/evp.h>
    #include <openssl/x509.h>
    
    /**
     * init_server hook -- allow SSL_CTX-specific initialization to be performed by
     * a module for each SSL-enabled server (one at a time)
     * @param s SSL-enabled [virtual] server
     * @param p pconf pool
     * @param is_proxy 1 if this server supports backend connections
     * over SSL/TLS, 0 if it supports client connections over SSL/TLS
     * @param ctx OpenSSL SSL Context for the server
     */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, init_server,
                              (server_rec *s, apr_pool_t *p, int is_proxy, SSL_CTX *ctx))
    
    /**
     * pre_handshake hook
     * @param c conn_rec for new connection from client or to backend server
     * @param ssl OpenSSL SSL Connection for the client or backend server
     * @param is_proxy 1 if this handshake is for a backend connection, 0 otherwise
     */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, pre_handshake,
                              (conn_rec *c, SSL *ssl, int is_proxy))
    
    /**
     * proxy_post_handshake hook -- allow module to abort after successful
     * handshake with backend server and subsequent peer checks
     * @param c conn_rec for connection to backend server
     * @param ssl OpenSSL SSL Connection for the client or backend server
     */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, proxy_post_handshake,
                              (conn_rec *c, SSL *ssl))
    
    /** On TLS connections that do not relate to a configured virtual host,
     * allow other modules to provide a X509 certificate and EVP_PKEY to
     * be used on the connection. This first hook which does not
     * return DECLINED will determine the outcome. */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, answer_challenge,
                              (conn_rec *c, const char *server_name, 
                              X509 **pcert, EVP_PKEY **pkey))
    
    /** During post_config phase, ask around if someone wants to provide
     * OCSP stapling status information for the given cert (with the also
     * provided issuer certificate). The first hook which does not
     * return DECLINED promises to take responsibility (and respond
     * in later calls via hook ssl_get_stapling_status).
     * If no hook takes over, mod_ssl's own stapling implementation will
     * be applied (if configured).
     */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, init_stapling_status,
                              (server_rec *s, apr_pool_t *p, 
                              X509 *cert, X509 *issuer))
    
    /** Anyone answering positive to ssl_init_stapling_status for a 
     * certificate, needs to register here and supply the actual OCSP stapling
     * status data (OCSP_RESP) for a new connection.
     * A hook supplying the response data must return APR_SUCCESS.
     * The data is returned in DER encoded bytes via pder and pderlen. The
     * returned pointer may be NULL, which indicates that data is (currently)
     * unavailable.
     * If DER data is returned, it MUST come from a response with
     * status OCSP_RESPONSE_STATUS_SUCCESSFUL and V_OCSP_CERTSTATUS_GOOD
     * or V_OCSP_CERTSTATUS_REVOKED, not V_OCSP_CERTSTATUS_UNKNOWN. This means
     * errors in OCSP retrieval are to be handled/logged by the hook and
     * are not done by mod_ssl.
     * Any DER bytes returned MUST be allocated via malloc() and ownership
     * passes to mod_ssl. Meaning, the hook must return a malloced copy of
     * the data it has. mod_ssl (or OpenSSL) will free it. 
     */
    APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, get_stapling_status,
                              (unsigned char **pder, int *pderlen, 
                              conn_rec *c, server_rec *s, X509 *cert))
                              
    #endif /* __MOD_SSL_OPENSSL_H__ */
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_util_ssl.h�������������������������������������������������������������0000664�0001751�0001751�00000010072�14046725222�017767� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @verbatim
                            _             _
        _ __ ___   ___   __| |    ___ ___| |  mod_ssl
       | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
       | | | | | | (_) | (_| |   \__ \__ \ |
       |_| |_| |_|\___/ \__,_|___|___/___/_|
                            |_____|
       @endverbatim
     * @file  ssl_util_ssl.h
     * @brief Additional Utility Functions for OpenSSL
     *
     * @defgroup MOD_SSL_UTIL Utilities
     * @ingroup MOD_SSL
     * @{
     */
    
    #ifndef __SSL_UTIL_SSL_H__
    #define __SSL_UTIL_SSL_H__
    
    /**
     * SSL library version number
     */
    
    #define MODSSL_LIBRARY_VERSION OPENSSL_VERSION_NUMBER
    #define MODSSL_LIBRARY_NAME    "OpenSSL"
    #define MODSSL_LIBRARY_TEXT    OPENSSL_VERSION_TEXT
    #if MODSSL_USE_OPENSSL_PRE_1_1_API
    #define MODSSL_LIBRARY_DYNTEXT SSLeay_version(SSLEAY_VERSION)
    #else
    #define MODSSL_LIBRARY_DYNTEXT OpenSSL_version(OPENSSL_VERSION)
    #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 MODSSL_SESSION_MAX_DER 1024*10
    
    /** max length for modssl_SSL_SESSION_id2sz */
    #define MODSSL_SESSION_ID_STRING_LEN \
        ((SSL_MAX_SSL_SESSION_ID_LENGTH + 1) * 2)
    
    /**
     *  Additional Functions
     */
    void        modssl_init_app_data2_idx(void);
    void       *modssl_get_app_data2(SSL *);
    void        modssl_set_app_data2(SSL *, void *);
    
    /* Read private key from filename in either PEM or raw base64(DER)
     * format, using password entry callback cb and userdata. */
    EVP_PKEY   *modssl_read_privatekey(const char *filename, pem_password_cb *cb, void *ud);
    
    int         modssl_smart_shutdown(SSL *ssl);
    BOOL        modssl_X509_getBC(X509 *, int *, int *);
    char       *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne,
                                                 int raw);
    char       *modssl_X509_NAME_to_string(apr_pool_t *, X509_NAME *, int);
    BOOL        modssl_X509_getSAN(apr_pool_t *, X509 *, int, const char *, int, apr_array_header_t **);
    BOOL        modssl_X509_match_name(apr_pool_t *, X509 *, const char *, BOOL, server_rec *);
    char       *modssl_SSL_SESSION_id2sz(IDCONST unsigned char *, int, char *, int);
    
    /* Reads the remaining data in BIO, if not empty, and copies it into a
     * pool-allocated string.  If empty, returns NULL.  BIO_free(bio) is
     * called for both cases. */
    char *modssl_bio_free_read(apr_pool_t *p, BIO *bio);
    
    /* Read a single certificate and its private key from the given string in PEM format.
     * If `key_pem` is NULL, it will expect the key in `cert_pem`.
     */
    apr_status_t modssl_read_cert(apr_pool_t *p, 
                                  const char *cert_pem, const char *key_pem,
                                  pem_password_cb *cb, void *ud, 
                                  X509 **pcert, EVP_PKEY **pkey);
    
    /* Convert a certificate (and optionally a second) into a PEM string.
     * @param p pool for allocations
     * @param cert1 the certificate to convert
     * @param cert2 a second cert to add to the PEM afterwards or NULL.
     * @param ppem the certificate(s) in PEM format, NUL-terminated.
     * @return APR_SUCCESS if ppem is valid.
     */
    apr_status_t modssl_cert_get_pem(apr_pool_t *p,
                                     X509 *cert1, X509 *cert2,
                                     const char **ppem);
    
    #endif /* __SSL_UTIL_SSL_H__ */
    /** @} */
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/mod_ssl.dsp����������������������������������������������������������������0000664�0001751�0001751�00000015300�13226637151�017250� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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" /I "../md" /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" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /D "SSL_DECLARE_EXPORT" /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 /fo"Release/mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_ssl.so" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_ssl.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /I "../md" /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" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /D "SSL_DECLARE_EXPORT" /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 /fo"Debug/mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache"
    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 /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 /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
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_ssl.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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_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_engine_ocsp.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\ssl_util_ocsp.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\ssl_scache.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\ssl_util_stapling.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_private.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 Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/README.dsov.fig������������������������������������������������������������0000664�0001751�0001751�00000032012�12602744037�017474� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#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 modssl_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
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_mutex.c���������������������������������������������������������0000664�0001751�0001751�00000007164�11667005541�020624� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    int ssl_mutex_init(server_rec *s, apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
        apr_status_t rv;
    
        /* A mutex is only needed if a session cache is configured, and
         * the provider used is not internally multi-process/thread
         * safe. */
        if (!mc->sesscache
            || (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) == 0) {
            return TRUE;
        }
    
        if (mc->pMutex) {
            return TRUE;
        }
    
        if ((rv = ap_global_mutex_create(&mc->pMutex, NULL, SSL_CACHE_MUTEX_TYPE,
                                         NULL, s, s->process->pool, 0))
                != APR_SUCCESS) {
            return FALSE;
        }
    
        return TRUE;
    }
    
    int ssl_mutex_reinit(server_rec *s, apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
        apr_status_t rv;
        const char *lockfile;
    
        if (mc->pMutex == NULL || !mc->sesscache
            || (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) == 0) {
            return TRUE;
        }
    
        lockfile = apr_global_mutex_lockfile(mc->pMutex);
        if ((rv = apr_global_mutex_child_init(&mc->pMutex,
                                              lockfile,
                                              p)) != APR_SUCCESS) {
            if (lockfile)
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02024)
                             "Cannot reinit %s mutex with file `%s'",
                             SSL_CACHE_MUTEX_TYPE, lockfile);
            else
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(02025)
                             "Cannot reinit %s mutex", SSL_CACHE_MUTEX_TYPE);
            return FALSE;
        }
        return TRUE;
    }
    
    int ssl_mutex_on(server_rec *s)
    {
        SSLModConfigRec *mc = myModConfig(s);
        apr_status_t rv;
    
        if ((rv = apr_global_mutex_lock(mc->pMutex)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(02026)
                         "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 ((rv = apr_global_mutex_unlock(mc->pMutex)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(02027)
                         "Failed to release SSL session cache lock");
            return FALSE;
        }
        return TRUE;
    }
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_util_stapling.c��������������������������������������������������������0000664�0001751�0001751�00000101126�14526120464�021003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_stapling.c
     *  OCSP Stapling Support
     */
                                 /* ``Where's the spoons?
                                      Where's the spoons?
                                      Where's the bloody spoons?''
                                                -- Alexei Sayle          */
    
    #include "ssl_private.h"
    
    #include "ap_mpm.h"
    #include "apr_thread_mutex.h"
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_stapling_status,
                                        (server_rec *s, apr_pool_t *p, 
                                         X509 *cert, X509 *issuer),
                                         (s, p, cert, issuer),
                                        DECLINED, DECLINED)
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, get_stapling_status,
                                        (unsigned char **pder, int *pderlen, 
                                         conn_rec *c, server_rec *s, X509 *cert),
                                         (pder, pderlen, c, s, cert), 
                                        DECLINED, DECLINED)
                             
    
    #ifdef HAVE_OCSP_STAPLING
    
    static int stapling_cache_mutex_on(server_rec *s);
    static int stapling_cache_mutex_off(server_rec *s);
    
    static int stapling_cb(SSL *ssl, void *arg);
    
    /**
     * Maximum OCSP stapling response size. This should be the response for a
     * single certificate and will typically include the responder certificate chain
     * so 10K should be more than enough.
     *
     */
    
    #define MAX_STAPLING_DER 10240
    
    /* Cached info stored in the global stapling_certinfo hash. */
    typedef struct {
        /* Index in session cache (SHA-1 digest of DER encoded certificate) */
        UCHAR idx[SHA_DIGEST_LENGTH];
        /* Certificate ID for OCSP request */
        OCSP_CERTID *cid;
        /* URI of the OCSP responder */
        char *uri;
    } certinfo;
    
    static apr_status_t ssl_stapling_certid_free(void *data)
    {
        OCSP_CERTID *cid = data;
    
        if (cid) {
            OCSP_CERTID_free(cid);
        }
    
        return APR_SUCCESS;
    }
    
    static apr_hash_t *stapling_certinfo;
    
    void ssl_stapling_certinfo_hash_init(apr_pool_t *p)
    {
        stapling_certinfo = apr_hash_make(p);
    }
    
    static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x)
    {
        X509 *issuer = NULL;
        int i;
        X509_STORE *st = SSL_CTX_get_cert_store(mctx->ssl_ctx);
        X509_STORE_CTX *inctx;
        STACK_OF(X509) *extra_certs = NULL;
    
    #ifdef OPENSSL_NO_SSL_INTERN
        SSL_CTX_get_extra_chain_certs(mctx->ssl_ctx, &extra_certs);
    #else
        extra_certs = mctx->ssl_ctx->extra_certs;
    #endif
    
        for (i = 0; i < sk_X509_num(extra_certs); i++) {
            issuer = sk_X509_value(extra_certs, i);
            if (X509_check_issued(issuer, x) == X509_V_OK) {
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
                CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509);
    #else
                X509_up_ref(issuer);
    #endif
                return issuer;
            }
        }
    
        inctx = X509_STORE_CTX_new();
        if (!X509_STORE_CTX_init(inctx, st, NULL, NULL)) {
            X509_STORE_CTX_free(inctx);
            return 0;
        }
        if (X509_STORE_CTX_get1_issuer(&issuer, inctx, x) <= 0)
            issuer = NULL;
        X509_STORE_CTX_cleanup(inctx);
        X509_STORE_CTX_free(inctx);
        return issuer;
    }
    
    int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
                               modssl_ctx_t *mctx, X509 *x)
    {
        UCHAR idx[SHA_DIGEST_LENGTH];
        certinfo *cinf = NULL;
        X509 *issuer = NULL;
        OCSP_CERTID *cid = NULL;
        STACK_OF(OPENSSL_STRING) *aia = NULL;
        const char *pem = NULL;
        int rv = 1; /* until further notice */
    
        if (x == NULL)
            return 0;
    
        if (!(issuer = stapling_get_issuer(mctx, x))) {
            /* In Apache pre 2.4.40, we use to come here only when mod_ssl stapling
             * was enabled. With the new hooks, we give other modules the chance
             * to provide stapling status. However, we do not want to log ssl errors
             * where we did not do so in the past. */
            if (mctx->stapling_enabled == TRUE) {
                ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217)
                               "ssl_stapling_init_cert: can't retrieve issuer "
                               "certificate!");
                return 0;
            }
            return 1;
        }
    
        if (X509_digest(x, EVP_sha1(), idx, NULL) != 1) {
            rv = 0;
            goto cleanup;
        }
    
        if (modssl_cert_get_pem(ptemp, x, issuer, &pem) != APR_SUCCESS) {
            rv = 0;
            goto cleanup;
        }
    
        if (ap_ssl_ocsp_prime(s, p, (const char*)idx, sizeof(idx), pem) == APR_SUCCESS
            || ssl_run_init_stapling_status(s, p, x, issuer) == OK) {
            /* Someone's taken over or mod_ssl's own implementation is not enabled */
            if (mctx->stapling_enabled != TRUE) {
                SSL_CTX_set_tlsext_status_cb(mctx->ssl_ctx, stapling_cb);
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10177) "OCSP stapling added via hook");
            }
            goto cleanup;
        }
        
        if (mctx->stapling_enabled != TRUE) {
            /* mod_ssl's own implementation is not enabled */
            goto cleanup;
        }
        
        cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
        if (cinf) {
            /* 
             * We already parsed the certificate, and no OCSP URI was found.
             * The certificate might be used for multiple vhosts, though,
             * so we check for a ForceURL for this vhost.
             */
            if (!cinf->uri && !mctx->stapling_force_url) {
                ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x,
                               APLOGNO(02814) "ssl_stapling_init_cert: no OCSP URI "
                               "in certificate and no SSLStaplingForceURL "
                               "configured for server %s", mctx->sc->vhost_id);
                rv = 0;
            }
            goto cleanup;
        }
    
        cid = OCSP_cert_to_id(NULL, x, issuer);
        if (!cid) {
            ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02815)
                           "ssl_stapling_init_cert: can't create CertID "
                           "for OCSP request");
            rv = 0;
            goto cleanup;
        }
    
        aia = X509_get1_ocsp(x);
        if (!aia && !mctx->stapling_force_url) {
            OCSP_CERTID_free(cid);
            ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x,
                           APLOGNO(02218) "ssl_stapling_init_cert: no OCSP URI "
                           "in certificate and no SSLStaplingForceURL set");
            rv = 0;
            goto cleanup;
        }
    
        /* At this point, we have determined that there's something to store */
        cinf = apr_pcalloc(p, sizeof(certinfo));
        memcpy (cinf->idx, idx, sizeof(idx));
        cinf->cid = cid;
        /* make sure cid is also freed at pool cleanup */
        apr_pool_cleanup_register(p, cid, ssl_stapling_certid_free,
                                  apr_pool_cleanup_null);
        if (aia) {
           /* allocate uri from the pconf pool */
           cinf->uri = apr_pstrdup(p, sk_OPENSSL_STRING_value(aia, 0));
           X509_email_free(aia);
        }
    
        ssl_log_xerror(SSLLOG_MARK, APLOG_TRACE1, 0, ptemp, s, x,
                       "ssl_stapling_init_cert: storing certinfo for server %s",
                       mctx->sc->vhost_id);
    
        apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf);
    
    cleanup:
        X509_free(issuer);
        return rv;
    }
    
    static certinfo *stapling_get_certinfo(server_rec *s, UCHAR *idx, apr_size_t idx_len,
                                           modssl_ctx_t *mctx, SSL *ssl)
    {
        certinfo *cinf;
        cinf = apr_hash_get(stapling_certinfo, idx, idx_len);
        if (cinf && cinf->cid)
            return cinf;
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01926)
                     "stapling_get_certinfo: stapling not supported for certificate");
        return NULL;
    }
    
    /*
     * OCSP response caching code. The response is preceded by a flag value
     * which indicates whether the response was invalid when it was stored.
     * the purpose of this flag is to avoid repeated queries to a server
     * which has given an invalid response while allowing a response which
     * has subsequently become invalid to be retried immediately.
     *
     * The key for the cache is the hash of the certificate the response
     * is for.
     */
    static BOOL stapling_cache_response(server_rec *s, modssl_ctx_t *mctx,
                                        OCSP_RESPONSE *rsp, certinfo *cinf,
                                        BOOL ok, apr_pool_t *pool)
    {
        SSLModConfigRec *mc = myModConfig(s);
        unsigned char resp_der[MAX_STAPLING_DER]; /* includes one-byte flag + response */
        unsigned char *p;
        int resp_derlen, stored_len;
        BOOL rv;
        apr_time_t expiry;
    
        resp_derlen = i2d_OCSP_RESPONSE(rsp, NULL);
    
        if (resp_derlen <= 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01927)
                         "OCSP stapling response encode error??");
            return FALSE;
        }
    
        stored_len = resp_derlen + 1; /* response + ok flag */
        if (stored_len > sizeof resp_der) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01928)
                         "OCSP stapling response too big (%u bytes)", resp_derlen);
            return FALSE;
        }
    
        p = resp_der;
    
        /* TODO: potential optimization; _timeout members as apr_interval_time_t */
        if (ok == TRUE) {
            *p++ = 1;
            expiry = apr_time_from_sec(mctx->stapling_cache_timeout);
        }
        else {
            *p++ = 0;
            expiry = apr_time_from_sec(mctx->stapling_errcache_timeout);
        }
    
        expiry += apr_time_now();
    
        i2d_OCSP_RESPONSE(rsp, &p);
    
        if (mc->stapling_cache->flags & AP_SOCACHE_FLAG_NOTMPSAFE)
            stapling_cache_mutex_on(s);
        rv = mc->stapling_cache->store(mc->stapling_cache_context, s,
                                       cinf->idx, sizeof(cinf->idx),
                                       expiry, resp_der, stored_len, pool);
        if (mc->stapling_cache->flags & AP_SOCACHE_FLAG_NOTMPSAFE)
            stapling_cache_mutex_off(s);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01929)
                         "stapling_cache_response: OCSP response session store error!");
            return FALSE;
        }
    
        return TRUE;
    }
    
    static void stapling_get_cached_response(server_rec *s, OCSP_RESPONSE **prsp,
                                             BOOL *pok, certinfo *cinf,
                                             apr_pool_t *pool)
    {
        SSLModConfigRec *mc = myModConfig(s);
        apr_status_t rv;
        OCSP_RESPONSE *rsp;
        unsigned char resp_der[MAX_STAPLING_DER];
        const unsigned char *p;
        unsigned int resp_derlen = MAX_STAPLING_DER;
    
        if (mc->stapling_cache->flags & AP_SOCACHE_FLAG_NOTMPSAFE)
            stapling_cache_mutex_on(s);
        rv = mc->stapling_cache->retrieve(mc->stapling_cache_context, s,
                                          cinf->idx, sizeof(cinf->idx),
                                          resp_der, &resp_derlen, pool);
        if (mc->stapling_cache->flags & AP_SOCACHE_FLAG_NOTMPSAFE)
            stapling_cache_mutex_off(s);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01930)
                         "stapling_get_cached_response: cache miss");
            return;
        }
        if (resp_derlen <= 1) {
            /* should-not-occur; must have at least valid-when-stored flag +
             * OCSPResponseStatus
             */
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01931)
                         "stapling_get_cached_response: response length invalid??");
            return;
        }
        p = resp_der;
        if (*p) /* valid when stored */
            *pok = TRUE;
        else
            *pok = FALSE;
        p++;
        resp_derlen--;
        rsp = d2i_OCSP_RESPONSE(NULL, &p, resp_derlen);
        if (!rsp) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01932)
                         "stapling_get_cached_response: response parse error??");
            return;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01933)
                     "stapling_get_cached_response: cache hit");
    
        *prsp = rsp;
    }
    
    static int stapling_set_response(SSL *ssl, OCSP_RESPONSE *rsp)
    {
        int rspderlen;
        unsigned char *rspder = NULL;
    
        rspderlen = i2d_OCSP_RESPONSE(rsp, &rspder);
        if (rspderlen <= 0)
            return 0;
        SSL_set_tlsext_status_ocsp_resp(ssl, rspder, rspderlen);
        return 1;
    }
    
    static int stapling_check_response(server_rec *s, modssl_ctx_t *mctx,
                                       certinfo *cinf, OCSP_RESPONSE *rsp,
                                       BOOL *pok)
    {
        int status = V_OCSP_CERTSTATUS_UNKNOWN;
        int reason = OCSP_REVOKED_STATUS_NOSTATUS;
        OCSP_BASICRESP *bs = NULL;
        ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
        int response_status = OCSP_response_status(rsp);
        int rv = SSL_TLSEXT_ERR_OK;
    
        if (pok)
            *pok = FALSE;
        /* Check to see if response is an error. If so we automatically accept
         * it because it would have expired from the cache if it was time to
         * retry.
         */
        if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
            if (mctx->stapling_return_errors)
                return SSL_TLSEXT_ERR_OK;
            else
                return SSL_TLSEXT_ERR_NOACK;
        }
    
        bs = OCSP_response_get1_basic(rsp);
        if (bs == NULL) {
            /* If we can't parse response just pass it to client */
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01934)
                         "stapling_check_response: Error Parsing Response!");
            return SSL_TLSEXT_ERR_OK;
        }
    
        if (!OCSP_resp_find_status(bs, cinf->cid, &status, &reason, &rev,
                                   &thisupd, &nextupd)) {
            /* If ID not present pass back to client (if configured so) */
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01935)
                         "stapling_check_response: certificate ID not present in response!");
            if (mctx->stapling_return_errors == FALSE)
                rv = SSL_TLSEXT_ERR_NOACK;
        }
        else {
            if (OCSP_check_validity(thisupd, nextupd,
                                    mctx->stapling_resptime_skew,
                                    mctx->stapling_resp_maxage)) {
                if (pok)
                    *pok = TRUE;
            }
            else {
                /* If pok is not NULL response was direct from a responder and
                 * the times should be valide. If pok is NULL the response was
                 * retrieved from cache and it is expected to subsequently expire
                 */
                if (pok) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01936)
                                 "stapling_check_response: response times invalid");
                }
                else {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01937)
                                 "stapling_check_response: cached response expired");
                }
    
                rv = SSL_TLSEXT_ERR_NOACK;
            }
    
            if (status != V_OCSP_CERTSTATUS_GOOD && pok) {
                char snum[MAX_STRING_LEN] = { '\0' };
                BIO *bio = BIO_new(BIO_s_mem());
    
                if (bio) {
                    int n;
                    ASN1_INTEGER *pserial;
                    OCSP_id_get0_info(NULL, NULL, NULL, &pserial, cinf->cid);
                    if ((i2a_ASN1_INTEGER(bio, pserial) != -1) &&
                        ((n = BIO_read(bio, snum, sizeof snum - 1)) > 0))
                        snum[n] = '\0';
                    BIO_free(bio);
                }
    
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02969)
                             "stapling_check_response: response has certificate "
                             "status %s (reason: %s) for serial number %s",
                             OCSP_cert_status_str(status),
                             (reason != OCSP_REVOKED_STATUS_NOSTATUS) ?
                             OCSP_crl_reason_str(reason) : "n/a",
                             snum[0] ? snum : "[n/a]");
            }
        }
    
        OCSP_BASICRESP_free(bs);
    
        return rv;
    }
    
    static BOOL stapling_renew_response(server_rec *s, modssl_ctx_t *mctx, SSL *ssl,
                                        certinfo *cinf, OCSP_RESPONSE **prsp,
                                        BOOL *pok, apr_pool_t *pool)
    {
        conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);
        apr_pool_t *vpool;
        OCSP_REQUEST *req = NULL;
        OCSP_CERTID *id = NULL;
        STACK_OF(X509_EXTENSION) *exts;
        int i;
        BOOL rv = TRUE;
        const char *ocspuri;
        apr_uri_t uri;
    
        *prsp = NULL;
        /* Build up OCSP query from server certificate info */
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01938)
                     "stapling_renew_response: querying responder");
    
        req = OCSP_REQUEST_new();
        if (!req)
            goto err;
        id = OCSP_CERTID_dup(cinf->cid);
        if (!id)
            goto err;
        if (!OCSP_request_add0_id(req, id))
            goto err;
        id = NULL;
        /* Add any extensions to the request */
        SSL_get_tlsext_status_exts(ssl, &exts);
        for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
            X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
            if (!OCSP_REQUEST_add_ext(req, ext, -1))
                goto err;
        }
    
        if (mctx->stapling_force_url)
            ocspuri = mctx->stapling_force_url;
        else
            ocspuri = cinf->uri;
    
        if (!ocspuri) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02621)
                         "stapling_renew_response: no uri for responder");
            rv = FALSE;
            goto done;
        }
    
        /* Create a temporary pool to constrain memory use */
        apr_pool_create(&vpool, conn->pool);
        apr_pool_tag(vpool, "modssl_stapling_renew");
    
        if (apr_uri_parse(vpool, ocspuri, &uri) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01939)
                         "stapling_renew_response: Error parsing uri %s",
                          ocspuri);
            rv = FALSE;
            goto done;
        }
        else if (strcmp(uri.scheme, "http")) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01940)
                         "stapling_renew_response: Unsupported uri %s", ocspuri);
            rv = FALSE;
            goto done;
        }
    
        if (!uri.port) {
            uri.port = apr_uri_port_of_scheme(uri.scheme);
        }
    
        *prsp = modssl_dispatch_ocsp_request(&uri, mctx->stapling_responder_timeout,
                                             req, conn, vpool);
    
        apr_pool_destroy(vpool);
    
        if (!*prsp) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01941)
                         "stapling_renew_response: responder error");
            if (mctx->stapling_fake_trylater) {
                *prsp = OCSP_response_create(OCSP_RESPONSE_STATUS_TRYLATER, NULL);
            }
            else {
                goto done;
            }
        }
        else {
            int response_status = OCSP_response_status(*prsp);
    
            if (response_status == OCSP_RESPONSE_STATUS_SUCCESSFUL) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01942)
                            "stapling_renew_response: query response received");
                stapling_check_response(s, mctx, cinf, *prsp, pok);
                if (*pok == FALSE) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01943)
                                 "stapling_renew_response: error in retrieved response!");
                }
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01944)
                             "stapling_renew_response: responder error %s",
                             OCSP_response_status_str(response_status));
                *pok = FALSE;
            }
        }
        if (stapling_cache_response(s, mctx, *prsp, cinf, *pok, pool) == FALSE) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01945)
                         "stapling_renew_response: error caching response!");
        }
    
    done:
        if (id)
            OCSP_CERTID_free(id);
        if (req)
            OCSP_REQUEST_free(req);
        return rv;
    err:
        rv = FALSE;
        goto done;
    }
    
    /*
     * SSL stapling mutex operations. Similar to SSL mutex except mutexes are
     * mandatory if stapling is enabled.
     */
    static int ssl_stapling_mutex_init(server_rec *s, apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
        SSLSrvConfigRec *sc = mySrvConfig(s);
        apr_status_t rv;
    
        /* already init or stapling not enabled? */
        if (mc->stapling_refresh_mutex || sc->server->stapling_enabled != TRUE) {
            return TRUE;
        }
    
        /* need a cache mutex? */
        if (mc->stapling_cache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
            if ((rv = ap_global_mutex_create(&mc->stapling_cache_mutex, NULL,
                                             SSL_STAPLING_CACHE_MUTEX_TYPE, NULL, s,
                                             s->process->pool, 0)) != APR_SUCCESS) {
                return FALSE;
            }
        }
    
        /* always need stapling_refresh_mutex */
        if ((rv = ap_global_mutex_create(&mc->stapling_refresh_mutex, NULL,
                                         SSL_STAPLING_REFRESH_MUTEX_TYPE, NULL, s,
                                         s->process->pool, 0)) != APR_SUCCESS) {
            return FALSE;
        }
    
        return TRUE;
    }
    
    static int stapling_mutex_reinit_helper(server_rec *s, apr_pool_t *p, 
                                            apr_global_mutex_t **mutex,
                                            const char *type)
    {
        apr_status_t rv;
        const char *lockfile;
    
        lockfile = apr_global_mutex_lockfile(*mutex);
        if ((rv = apr_global_mutex_child_init(mutex,
                                              lockfile, p)) != APR_SUCCESS) {
            if (lockfile) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01946)
                             "Cannot reinit %s mutex with file `%s'",
                             type, lockfile);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01947)
                             "Cannot reinit %s mutex", type);
            }
            return FALSE;
        }
        return TRUE;
    }
    
    int ssl_stapling_mutex_reinit(server_rec *s, apr_pool_t *p)
    {
        SSLModConfigRec *mc = myModConfig(s);
    
        if (mc->stapling_cache_mutex != NULL
            && stapling_mutex_reinit_helper(s, p, &mc->stapling_cache_mutex,
                                            SSL_STAPLING_CACHE_MUTEX_TYPE) == FALSE) {
            return FALSE;
        }
    
        if (mc->stapling_refresh_mutex != NULL
            && stapling_mutex_reinit_helper(s, p, &mc->stapling_refresh_mutex,
                                            SSL_STAPLING_REFRESH_MUTEX_TYPE) == FALSE) {
            return FALSE;
        }
    
        return TRUE;
    }
    
    static int stapling_mutex_on(server_rec *s, apr_global_mutex_t *mutex,
                                 const char *name)
    {
        apr_status_t rv;
    
        if ((rv = apr_global_mutex_lock(mutex)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01948)
                         "Failed to acquire OCSP %s lock", name);
            return FALSE;
        }
        return TRUE;
    }
    
    static int stapling_mutex_off(server_rec *s, apr_global_mutex_t *mutex,
                                  const char *name)
    {
        apr_status_t rv;
    
        if ((rv = apr_global_mutex_unlock(mutex)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01949)
                         "Failed to release OCSP %s lock", name);
            return FALSE;
        }
        return TRUE;
    }
    
    static int stapling_cache_mutex_on(server_rec *s)
    {
        SSLModConfigRec *mc = myModConfig(s);
    
        return stapling_mutex_on(s, mc->stapling_cache_mutex,
                                 SSL_STAPLING_CACHE_MUTEX_TYPE);
    }
    
    static int stapling_cache_mutex_off(server_rec *s)
    {
        SSLModConfigRec *mc = myModConfig(s);
    
        return stapling_mutex_off(s, mc->stapling_cache_mutex,
                                  SSL_STAPLING_CACHE_MUTEX_TYPE);
    }
    
    static int stapling_refresh_mutex_on(server_rec *s)
    {
        SSLModConfigRec *mc = myModConfig(s);
    
        return stapling_mutex_on(s, mc->stapling_refresh_mutex,
                                 SSL_STAPLING_REFRESH_MUTEX_TYPE);
    }
    
    static int stapling_refresh_mutex_off(server_rec *s)
    {
        SSLModConfigRec *mc = myModConfig(s);
    
        return stapling_mutex_off(s, mc->stapling_refresh_mutex,
                                  SSL_STAPLING_REFRESH_MUTEX_TYPE);
    }
    
    static int get_and_check_cached_response(server_rec *s, modssl_ctx_t *mctx,
                                             OCSP_RESPONSE **rsp, BOOL *pok,
                                             certinfo *cinf, apr_pool_t *p)
    {
        BOOL ok = FALSE;
        int rv;
    
        AP_DEBUG_ASSERT(*rsp == NULL);
    
        /* Check to see if we already have a response for this certificate */
        stapling_get_cached_response(s, rsp, &ok, cinf, p);
    
        if (*rsp) {
            /* see if response is acceptable */
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01953)
                         "stapling_cb: retrieved cached response");
            rv = stapling_check_response(s, mctx, cinf, *rsp, NULL);
            if (rv == SSL_TLSEXT_ERR_ALERT_FATAL) {
                OCSP_RESPONSE_free(*rsp);
                *rsp = NULL;
                return SSL_TLSEXT_ERR_ALERT_FATAL;
            }
            else if (rv == SSL_TLSEXT_ERR_NOACK) {
                /* Error in response. If this error was not present when it was
                 * stored (i.e. response no longer valid) then it can be
                 * renewed straight away.
                 *
                 * If the error *was* present at the time it was stored then we
                 * don't renew the response straight away; we just wait for the
                 * cached response to expire.
                 */
                if (ok) {
                    OCSP_RESPONSE_free(*rsp);
                    *rsp = NULL;
                }
                else if (!mctx->stapling_return_errors) {
                    OCSP_RESPONSE_free(*rsp);
                    *rsp = NULL;
                    *pok = FALSE;
                    return SSL_TLSEXT_ERR_NOACK;
                }
            }
        }
        return 0;
    }
    
    typedef struct {
        unsigned char *data;
        apr_size_t len;
    } ocsp_resp;
    
    static void copy_ocsp_resp(const unsigned char *der, apr_size_t der_len, void *userdata)
    {
        ocsp_resp *resp = userdata;
    
        resp->len = 0;
        resp->data = der? OPENSSL_malloc(der_len) : NULL;
        if (resp->data) {
            memcpy(resp->data, der, der_len);
            resp->len = der_len;
        }
    }
    
    /* Certificate Status callback. This is called when a client includes a
     * certificate status request extension.
     *
     * Check for cached responses in session cache. If valid send back to
     * client.  If absent or no longer valid, query responder and update
     * cache.
     */
    static int stapling_cb(SSL *ssl, void *arg)
    {
        conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);
        server_rec *s       = mySrvFromConn(conn);
        SSLSrvConfigRec *sc = mySrvConfig(s);
        modssl_ctx_t *mctx  = myConnCtxConfig(conn, sc);
        UCHAR idx[SHA_DIGEST_LENGTH];
        ocsp_resp resp;
        certinfo *cinf = NULL;
        OCSP_RESPONSE *rsp = NULL;
        int rv;
        BOOL ok = TRUE;
        X509 *x;
        int rspderlen, provided = 0;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
                     "stapling_cb: OCSP Stapling callback called");
    
        x = SSL_get_certificate(ssl);
        if (x == NULL) {
            return SSL_TLSEXT_ERR_NOACK;
        }
    
        if (X509_digest(x, EVP_sha1(), idx, NULL) != 1) {
            return SSL_TLSEXT_ERR_NOACK;
        }
    
        if (ap_ssl_ocsp_get_resp(s, conn, (const char*)idx, sizeof(idx),
                                 copy_ocsp_resp, &resp) == APR_SUCCESS) {
            provided = 1;
        }
        else if (ssl_run_get_stapling_status(&resp.data, &rspderlen, conn, s, x) == APR_SUCCESS) {
            resp.len = (apr_size_t)rspderlen;
            provided = 1;
        }
    
        if (provided) {
            /* a hook handles stapling for this certificate and determines the response */
            if (resp.data == NULL || resp.len == 0) {
                return SSL_TLSEXT_ERR_NOACK;
            }
            SSL_set_tlsext_status_ocsp_resp(ssl, resp.data, (int)resp.len);
            return SSL_TLSEXT_ERR_OK;
        }
        
        if (sc->server->stapling_enabled != TRUE) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01950)
                         "stapling_cb: OCSP Stapling disabled");
            return SSL_TLSEXT_ERR_NOACK;
        }
    
        if ((cinf = stapling_get_certinfo(s, idx, sizeof(idx), mctx, ssl)) == NULL) {
            return SSL_TLSEXT_ERR_NOACK;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01952)
                     "stapling_cb: retrieved cached certificate data");
    
        rv = get_and_check_cached_response(s, mctx, &rsp, &ok, cinf, conn->pool);
        if (rv != 0) {
            return rv;
        }
    
        if (rsp == NULL) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01954)
                         "stapling_cb: renewing cached response");
            stapling_refresh_mutex_on(s);
            /* Maybe another request refreshed the OCSP response while this
             * thread waited for the mutex.  Check again.
             */
            rv = get_and_check_cached_response(s, mctx, &rsp, &ok, cinf,
                                               conn->pool);
            if (rv != 0) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03236)
                             "stapling_cb: error checking for cached response "
                             "after obtaining refresh mutex");
                stapling_refresh_mutex_off(s);
                return rv;
            }
            else if (rsp) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03237)
                             "stapling_cb: don't need to refresh cached response "
                             "after obtaining refresh mutex");
                stapling_refresh_mutex_off(s);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03238)
                             "stapling_cb: still must refresh cached response "
                             "after obtaining refresh mutex");
                rv = stapling_renew_response(s, mctx, ssl, cinf, &rsp, &ok,
                                             conn->pool);
                stapling_refresh_mutex_off(s);
    
                if (rv == TRUE) {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03040)
                                 "stapling_cb: success renewing response");
                }
                else {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01955)
                                 "stapling_cb: fatal error renewing response");
                    return SSL_TLSEXT_ERR_ALERT_FATAL;
                }
            }
        }
    
        if (rsp && ((ok == TRUE) || (mctx->stapling_return_errors == TRUE))) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01956)
                         "stapling_cb: setting response");
            if (!stapling_set_response(ssl, rsp)) {
                rv = SSL_TLSEXT_ERR_ALERT_FATAL;
            }
            else {
                rv = SSL_TLSEXT_ERR_OK;
            }
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01957)
                         "stapling_cb: no suitable response available");
            rv = SSL_TLSEXT_ERR_NOACK;
        }
        OCSP_RESPONSE_free(rsp); /* NULL safe */
    
        return rv;
    }
    
    apr_status_t modssl_init_stapling(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);
    
        if (mc->stapling_cache == NULL) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01958)
                         "SSLStapling: no stapling cache available");
            return ssl_die(s);
        }
        if (ssl_stapling_mutex_init(s, ptemp) == FALSE) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01959)
                         "SSLStapling: cannot initialise stapling mutex");
            return ssl_die(s);
        }
        /* Set some default values for parameters if they are not set */
        if (mctx->stapling_resptime_skew == UNSET) {
            mctx->stapling_resptime_skew = 60 * 5;
        }
        if (mctx->stapling_cache_timeout == UNSET) {
            mctx->stapling_cache_timeout = 3600;
        }
        if (mctx->stapling_return_errors == UNSET) {
            mctx->stapling_return_errors = TRUE;
        }
        if (mctx->stapling_fake_trylater == UNSET) {
            mctx->stapling_fake_trylater = TRUE;
        }
        if (mctx->stapling_errcache_timeout == UNSET) {
            mctx->stapling_errcache_timeout = 600;
        }
        if (mctx->stapling_responder_timeout == UNSET) {
            mctx->stapling_responder_timeout = 10 * APR_USEC_PER_SEC;
        }
    
        SSL_CTX_set_tlsext_status_cb(ctx, stapling_cb);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01960) "OCSP stapling initialized");
        
        return APR_SUCCESS;
    }
    
    #endif
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/ssl_engine_ocsp.c����������������������������������������������������������0000664�0001751�0001751�00000026456�14037102164�020424� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "ssl_private.h"
    
    #ifndef OPENSSL_NO_OCSP
    #include "apr_base64.h"
    
    /* Return the responder URI specified in the given certificate, or
     * NULL if none specified. */
    static const char *extract_responder_uri(X509 *cert, apr_pool_t *pool)
    {
        STACK_OF(ACCESS_DESCRIPTION) *values;
        char *result = NULL;
        int j;
    
        values = X509_get_ext_d2i(cert, NID_info_access, NULL, NULL);
        if (!values) {
            return NULL;
        }
    
        for (j = 0; j < sk_ACCESS_DESCRIPTION_num(values) && !result; j++) {
            ACCESS_DESCRIPTION *value = sk_ACCESS_DESCRIPTION_value(values, j);
    
            /* Name found in extension, and is a URI: */
            if (OBJ_obj2nid(value->method) == NID_ad_OCSP
                && value->location->type == GEN_URI) {
                result = apr_pstrdup(pool,
                                     (char *)value->location->d.uniformResourceIdentifier->data);
            }
        }
    
        AUTHORITY_INFO_ACCESS_free(values);
    
        return result;
    }
    
    /* Return the responder URI object which should be used in the given
     * configuration for the given certificate, or NULL if none can be
     * determined. */
    static apr_uri_t *determine_responder_uri(SSLSrvConfigRec *sc, X509 *cert,
                                              conn_rec *c, apr_pool_t *p)
    {
        apr_uri_t *u = apr_palloc(p, sizeof *u);
        const char *s;
        apr_status_t rv;
    
        /* Use default responder URL if forced by configuration, else use
         * certificate-specified responder, falling back to default if
         * necessary and possible. */
        if (sc->server->ocsp_force_default == TRUE) {
            s = sc->server->ocsp_responder;
        }
        else {
            s = extract_responder_uri(cert, p);
    
            if (s == NULL && sc->server->ocsp_responder) {
                s = sc->server->ocsp_responder;
            }
        }
    
        if (s == NULL) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01918)
                          "no OCSP responder specified in certificate and "
                          "no default configured");
            return NULL;
        }
    
        rv = apr_uri_parse(p, s, u);
        if (rv || !u->hostname) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01919)
                          "failed to parse OCSP responder URI '%s'", s);
            return NULL;
        }
    
        if (ap_cstr_casecmp(u->scheme, "http") != 0) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01920)
                          "cannot handle OCSP responder URI '%s'", s);
            return NULL;
        }
    
        if (!u->port) {
            u->port = apr_uri_port_of_scheme(u->scheme);
        }
    
        return u;
    }
    
    /* Create an OCSP request for the given certificate; returning the
     * certificate ID in *certid and *issuer on success.  Returns the
     * request object on success, or NULL on error. */
    static OCSP_REQUEST *create_request(X509_STORE_CTX *ctx, X509 *cert,
                                        OCSP_CERTID **certid,
                                        server_rec *s, apr_pool_t *p,
                                        SSLSrvConfigRec *sc)
    {
        OCSP_REQUEST *req = OCSP_REQUEST_new();
    
        *certid = OCSP_cert_to_id(NULL, cert, X509_STORE_CTX_get0_current_issuer(ctx));
        if (!*certid || !OCSP_request_add0_id(req, *certid)) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01921)
                         "could not retrieve certificate id");
            ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
            return NULL;
        }
    
        if (sc->server->ocsp_use_request_nonce != FALSE) {
            OCSP_request_add1_nonce(req, 0, -1);
        }
    
        return req;
    }
    
    /* Verify the OCSP status of given certificate.  Returns
     * V_OCSP_CERTSTATUS_* result code. */
    static int verify_ocsp_status(X509 *cert, X509_STORE_CTX *ctx, conn_rec *c,
                                  SSLSrvConfigRec *sc, server_rec *s,
                                  apr_pool_t *pool)
    {
        int rc = V_OCSP_CERTSTATUS_GOOD;
        OCSP_RESPONSE *response = NULL;
        OCSP_BASICRESP *basicResponse = NULL;
        OCSP_REQUEST *request = NULL;
        OCSP_CERTID *certID = NULL;
        apr_uri_t *ruri;
    
        ruri = determine_responder_uri(sc, cert, c, pool);
        if (!ruri) {
            if (sc->server->ocsp_mask & SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, 
                              "Skipping OCSP check for certificate cos no OCSP URL"
                              " found and no_ocsp_for_cert_ok is set");
                return V_OCSP_CERTSTATUS_GOOD;
            } else {
                return V_OCSP_CERTSTATUS_UNKNOWN;
            }
        }
    
        request = create_request(ctx, cert, &certID, s, pool, sc);
        if (request) {
            apr_interval_time_t to = sc->server->ocsp_responder_timeout == UNSET ?
                                     apr_time_from_sec(DEFAULT_OCSP_TIMEOUT) :
                                     sc->server->ocsp_responder_timeout;
            response = modssl_dispatch_ocsp_request(ruri, to, request, c, pool);
        }
    
        if (!request || !response) {
            rc = V_OCSP_CERTSTATUS_UNKNOWN;
        }
    
        if (rc == V_OCSP_CERTSTATUS_GOOD) {
            int r = OCSP_response_status(response);
    
            if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01922)
                             "OCSP response not successful: %d", r);
                rc = V_OCSP_CERTSTATUS_UNKNOWN;
            }
        }
    
        if (rc == V_OCSP_CERTSTATUS_GOOD) {
            basicResponse = OCSP_response_get1_basic(response);
            if (!basicResponse) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01923)
                              "could not retrieve OCSP basic response");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
                rc = V_OCSP_CERTSTATUS_UNKNOWN;
            }
        }
    
        if (rc == V_OCSP_CERTSTATUS_GOOD &&
                sc->server->ocsp_use_request_nonce != FALSE &&
                OCSP_check_nonce(request, basicResponse) != 1) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01924)
                        "Bad OCSP responder answer (bad nonce)");
            rc = V_OCSP_CERTSTATUS_UNKNOWN;
        }
    
        if (rc == V_OCSP_CERTSTATUS_GOOD) {
            /* Check if OCSP certificate verification required */
            if (sc->server->ocsp_noverify != TRUE) {
                /* Modify OCSP response verification to include OCSP Responder cert */
                if (OCSP_basic_verify(basicResponse, sc->server->ocsp_certs, X509_STORE_CTX_get0_store(ctx),
                                      sc->server->ocsp_verify_flags) != 1) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01925)
                                "failed to verify the OCSP response");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
                    rc = V_OCSP_CERTSTATUS_UNKNOWN;
                }
            }
        }
    
        if (rc == V_OCSP_CERTSTATUS_GOOD) {
            int reason = -1, status;
            ASN1_GENERALIZEDTIME *thisup = NULL, *nextup = NULL;
    
            rc = OCSP_resp_find_status(basicResponse, certID, &status,
                                       &reason, NULL, &thisup, &nextup);
            if (rc != 1) {
                ssl_log_cxerror(SSLLOG_MARK, APLOG_ERR, 0, c, cert, APLOGNO(02272)
                                "failed to retrieve OCSP response status");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
                rc = V_OCSP_CERTSTATUS_UNKNOWN;
            }
            else {
                rc = status;
            }
    
            /* Check whether the response is inside the defined validity
             * period; otherwise fail.  */
            if (rc != V_OCSP_CERTSTATUS_UNKNOWN) {
                long resptime_skew = sc->server->ocsp_resptime_skew == UNSET ?
                                     DEFAULT_OCSP_MAX_SKEW : sc->server->ocsp_resptime_skew;
                /* oscp_resp_maxage can be passed verbatim - UNSET (-1) means
                 * that responses can be of any age as long as nextup is in the
                 * future. */
                int vrc  = OCSP_check_validity(thisup, nextup, resptime_skew,
                                               sc->server->ocsp_resp_maxage);
                if (vrc != 1) {
                    ssl_log_cxerror(SSLLOG_MARK, APLOG_ERR, 0, c, cert, APLOGNO(02273)
                                    "OCSP response outside validity period");
                    ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
                    rc = V_OCSP_CERTSTATUS_UNKNOWN;
                }
            }
    
            {
                int level =
                    (status == V_OCSP_CERTSTATUS_GOOD) ? APLOG_INFO : APLOG_ERR;
                const char *result =
                    status == V_OCSP_CERTSTATUS_GOOD ? "good" :
                    (status == V_OCSP_CERTSTATUS_REVOKED ? "revoked" : "unknown");
    
                ssl_log_cxerror(SSLLOG_MARK, level, 0, c, cert, APLOGNO(03239)
                                "OCSP validation completed, "
                                "certificate status: %s (%d, %d)",
                                result, status, reason);
            }
        }
    
        if (request) OCSP_REQUEST_free(request);
        if (response) OCSP_RESPONSE_free(response);
        if (basicResponse) OCSP_BASICRESP_free(basicResponse);
        /* certID is freed when the request is freed */
    
        return rc;
    }
    
    int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc,
                           server_rec *s, conn_rec *c, apr_pool_t *pool)
    {
        X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
        apr_pool_t *vpool;
        int rv;
    
        if (!cert) {
            /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
             * may yield NULL. Return early, but leave the ctx error as is. */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                          "No cert available to check with OCSP");
            return 1;
        }
        else if (X509_check_issued(cert,cert) == X509_V_OK) {
            /* don't do OCSP checking for valid self-issued certs */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                          "Skipping OCSP check for valid self-issued cert");
            X509_STORE_CTX_set_error(ctx, X509_V_OK);
            return 1;
        }
    
        /* Create a temporary pool to constrain memory use (the passed-in
         * pool may be e.g. a connection pool). */
        apr_pool_create(&vpool, pool);
        apr_pool_tag(vpool, "modssl_verify_ocsp");
    
        rv = verify_ocsp_status(cert, ctx, c, sc, s, vpool);
    
        apr_pool_destroy(vpool);
    
        /* Propagate the verification status back to the passed-in
         * context. */
        switch (rv) {
        case V_OCSP_CERTSTATUS_GOOD:
            X509_STORE_CTX_set_error(ctx, X509_V_OK);
            break;
    
        case V_OCSP_CERTSTATUS_REVOKED:
            X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
            break;
    
        case V_OCSP_CERTSTATUS_UNKNOWN:
            /* correct error code for application errors? */
            X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
            break;
        }
    
        return rv == V_OCSP_CERTSTATUS_GOOD;
    }
    #endif /* HAVE_OCSP */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/mod_ssl.mak����������������������������������������������������������������0000664�0001751�0001751�00000034144�13226637151�017241� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_ssl.dsp
    !IF "$(CFG)" == ""
    CFG=mod_ssl - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_ssl - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_ssl - Win32 Release" && "$(CFG)" != "mod_ssl - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF "$(_HAVE_OSSL110)" == "1"
    SSLCRP=libcrypto
    SSLLIB=libssl
    SSLINC=/I ../../srclib/openssl/include
    SSLBIN=../../srclib/openssl
    !ELSE 
    SSLCRP=libeay32
    SSLLIB=ssleay32
    SSLINC=/I ../../srclib/openssl/inc32
    SSLBIN=../../srclib/openssl/out32dll
    !ENDIF 
    
    
    !IF  "$(CFG)" == "mod_ssl - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ssl.obj"
    	-@erase "$(INTDIR)\mod_ssl.res"
    	-@erase "$(INTDIR)\mod_ssl_src.idb"
    	-@erase "$(INTDIR)\mod_ssl_src.pdb"
    	-@erase "$(INTDIR)\ssl_engine_config.obj"
    	-@erase "$(INTDIR)\ssl_engine_init.obj"
    	-@erase "$(INTDIR)\ssl_engine_io.obj"
    	-@erase "$(INTDIR)\ssl_engine_kernel.obj"
    	-@erase "$(INTDIR)\ssl_engine_log.obj"
    	-@erase "$(INTDIR)\ssl_engine_mutex.obj"
    	-@erase "$(INTDIR)\ssl_engine_ocsp.obj"
    	-@erase "$(INTDIR)\ssl_engine_pphrase.obj"
    	-@erase "$(INTDIR)\ssl_engine_rand.obj"
    	-@erase "$(INTDIR)\ssl_engine_vars.obj"
    	-@erase "$(INTDIR)\ssl_scache.obj"
    	-@erase "$(INTDIR)\ssl_util.obj"
    	-@erase "$(INTDIR)\ssl_util_ocsp.obj"
    	-@erase "$(INTDIR)\ssl_util_ssl.obj"
    	-@erase "$(INTDIR)\ssl_util_stapling.obj"
    	-@erase "$(OUTDIR)\mod_ssl.exp"
    	-@erase "$(OUTDIR)\mod_ssl.lib"
    	-@erase "$(OUTDIR)\mod_ssl.pdb"
    	-@erase "$(OUTDIR)\mod_ssl.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../md" $(SSLINC) /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" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /D "SSL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ssl_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ssl.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib $(SSLCRP).lib $(SSLLIB).lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ssl.pdb" /debug /out:"$(OUTDIR)\mod_ssl.so" /implib:"$(OUTDIR)\mod_ssl.lib" /libpath:"$(SSLBIN)" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ssl.obj" \
    	"$(INTDIR)\ssl_engine_config.obj" \
    	"$(INTDIR)\ssl_engine_init.obj" \
    	"$(INTDIR)\ssl_engine_io.obj" \
    	"$(INTDIR)\ssl_engine_kernel.obj" \
    	"$(INTDIR)\ssl_engine_log.obj" \
    	"$(INTDIR)\ssl_engine_mutex.obj" \
    	"$(INTDIR)\ssl_engine_pphrase.obj" \
    	"$(INTDIR)\ssl_engine_rand.obj" \
    	"$(INTDIR)\ssl_engine_vars.obj" \
    	"$(INTDIR)\ssl_engine_ocsp.obj" \
    	"$(INTDIR)\ssl_util_ocsp.obj" \
    	"$(INTDIR)\ssl_scache.obj" \
    	"$(INTDIR)\ssl_util_stapling.obj" \
    	"$(INTDIR)\ssl_util.obj" \
    	"$(INTDIR)\ssl_util_ssl.obj" \
    	"$(INTDIR)\mod_ssl.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_ssl.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_ssl.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ssl.so"
       if exist .\Release\mod_ssl.so.manifest mt.exe -manifest .\Release\mod_ssl.so.manifest -outputresource:.\Release\mod_ssl.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_ssl - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ssl.obj"
    	-@erase "$(INTDIR)\mod_ssl.res"
    	-@erase "$(INTDIR)\mod_ssl_src.idb"
    	-@erase "$(INTDIR)\mod_ssl_src.pdb"
    	-@erase "$(INTDIR)\ssl_engine_config.obj"
    	-@erase "$(INTDIR)\ssl_engine_init.obj"
    	-@erase "$(INTDIR)\ssl_engine_io.obj"
    	-@erase "$(INTDIR)\ssl_engine_kernel.obj"
    	-@erase "$(INTDIR)\ssl_engine_log.obj"
    	-@erase "$(INTDIR)\ssl_engine_mutex.obj"
    	-@erase "$(INTDIR)\ssl_engine_ocsp.obj"
    	-@erase "$(INTDIR)\ssl_engine_pphrase.obj"
    	-@erase "$(INTDIR)\ssl_engine_rand.obj"
    	-@erase "$(INTDIR)\ssl_engine_vars.obj"
    	-@erase "$(INTDIR)\ssl_scache.obj"
    	-@erase "$(INTDIR)\ssl_util.obj"
    	-@erase "$(INTDIR)\ssl_util_ocsp.obj"
    	-@erase "$(INTDIR)\ssl_util_ssl.obj"
    	-@erase "$(INTDIR)\ssl_util_stapling.obj"
    	-@erase "$(OUTDIR)\mod_ssl.exp"
    	-@erase "$(OUTDIR)\mod_ssl.lib"
    	-@erase "$(OUTDIR)\mod_ssl.pdb"
    	-@erase "$(OUTDIR)\mod_ssl.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../md" $(SSLINC) /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" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /D "SSL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ssl_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ssl.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib $(SSLCRP).lib $(SSLLIB).lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ssl.pdb" /debug /out:"$(OUTDIR)\mod_ssl.so" /implib:"$(OUTDIR)\mod_ssl.lib" /libpath:"../../srclib/openssl/out32dll.dbg" /libpath:"../../srclib/openssl/out32.dbg" /libpath:"$(SSLBIN)" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ssl.obj" \
    	"$(INTDIR)\ssl_engine_config.obj" \
    	"$(INTDIR)\ssl_engine_init.obj" \
    	"$(INTDIR)\ssl_engine_io.obj" \
    	"$(INTDIR)\ssl_engine_kernel.obj" \
    	"$(INTDIR)\ssl_engine_log.obj" \
    	"$(INTDIR)\ssl_engine_mutex.obj" \
    	"$(INTDIR)\ssl_engine_pphrase.obj" \
    	"$(INTDIR)\ssl_engine_rand.obj" \
    	"$(INTDIR)\ssl_engine_vars.obj" \
    	"$(INTDIR)\ssl_engine_ocsp.obj" \
    	"$(INTDIR)\ssl_util_ocsp.obj" \
    	"$(INTDIR)\ssl_scache.obj" \
    	"$(INTDIR)\ssl_util_stapling.obj" \
    	"$(INTDIR)\ssl_util.obj" \
    	"$(INTDIR)\ssl_util_ssl.obj" \
    	"$(INTDIR)\mod_ssl.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_ssl.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_ssl.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ssl.so"
       if exist .\Debug\mod_ssl.so.manifest mt.exe -manifest .\Debug\mod_ssl.so.manifest -outputresource:.\Debug\mod_ssl.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_ssl.dep")
    !INCLUDE "mod_ssl.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_ssl.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_ssl - Win32 Release" || "$(CFG)" == "mod_ssl - Win32 Debug"
    SOURCE=.\mod_ssl.c
    
    "$(INTDIR)\mod_ssl.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_config.c
    
    "$(INTDIR)\ssl_engine_config.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_init.c
    
    "$(INTDIR)\ssl_engine_init.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_io.c
    
    "$(INTDIR)\ssl_engine_io.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_kernel.c
    
    "$(INTDIR)\ssl_engine_kernel.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_log.c
    
    "$(INTDIR)\ssl_engine_log.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_mutex.c
    
    "$(INTDIR)\ssl_engine_mutex.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_ocsp.c
    
    "$(INTDIR)\ssl_engine_ocsp.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_pphrase.c
    
    "$(INTDIR)\ssl_engine_pphrase.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_rand.c
    
    "$(INTDIR)\ssl_engine_rand.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_engine_vars.c
    
    "$(INTDIR)\ssl_engine_vars.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_scache.c
    
    "$(INTDIR)\ssl_scache.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_util.c
    
    "$(INTDIR)\ssl_util.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_util_ocsp.c
    
    "$(INTDIR)\ssl_util_ocsp.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_util_ssl.c
    
    "$(INTDIR)\ssl_util_ssl.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ssl_util_stapling.c
    
    "$(INTDIR)\ssl_util_stapling.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_ssl - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\ssl"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\ssl"
    
    !ELSEIF  "$(CFG)" == "mod_ssl - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\ssl"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\ssl"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ssl - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\ssl"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\ssl"
    
    !ELSEIF  "$(CFG)" == "mod_ssl - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\ssl"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\ssl"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ssl - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\ssl"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\ssl"
    
    !ELSEIF  "$(CFG)" == "mod_ssl - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\ssl"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\ssl"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_ssl - Win32 Release"
    
    
    "$(INTDIR)\mod_ssl.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_ssl - Win32 Debug"
    
    
    "$(INTDIR)\mod_ssl.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ssl/README.dsov.ps�������������������������������������������������������������0000664�0001751�0001751�00000126714�12602744037�017366� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%!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 (modssl_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
    ����������������������������������������������������httpd-2.4.64/modules/ssl/NWGNUmakefile��������������������������������������������������������������0000664�0001751�0001751�00000013746�11640464273�017434� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # This Makefile requires the environment var OSSLSDK
    # pointing to the base directory of your OpenSSL SDK.
    # If you want to use the Novell NTLS SDK instead then
    # define NTLSSDK pointing to the base directory of the
    # SDK, and also set USE_NTLS=1
    #
    
    #
    # 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
    #
    
    ifeq "$(USE_NTLS)" "1"
    SSL_INC = $(NTLSSDK)/inc
    SSL_LIB = $(NTLSSDK)/imp
    SSL_BIN = $(NTLSSDK)/bin
    SSL_APP = $(NTLSSDK)/apps
    ifneq "$(wildcard $(SSL_INC)/openssl/opensslv.h)" "$(SSL_INC)/openssl/opensslv.h"
    $(error '$(NTLSSDK)' does NOT point to a valid NTLS SDK!)
    endif
    else
    SSL_INC = $(OSSLSDK)/outinc_nw_libc
    SSL_LIB = $(OSSLSDK)/out_nw_libc
    SSL_BIN = $(OSSLSDK)/out_nw_libc
    SSL_APP = $(OSSLSDK)/apps
    ifneq "$(wildcard $(SSL_INC)/openssl/opensslv.h)" "$(SSL_INC)/openssl/opensslv.h"
    $(error '$(OSSLSDK)' does NOT point to a valid OpenSSL SDK!)
    endif
    endif
    
    #
    # These directories will be at the beginning of the include list, followed by
    # INCDIRS
    #
    XINCDIRS	+= \
    			$(SSL_INC) \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/cache \
    			$(AP_WORK)/modules/generators \
    			$(AP_WORK)/server/mpm/NetWare \
    			$(NWOS) \
    			$(EOLIST)
    
    #
    # These flags will come after CFLAGS
    #
    XCFLAGS		+= \
    			$(EOLIST)
    
    #
    # These defines will come after DEFINES
    #
    XDEFINES	+= \
    			-DHAVE_OPENSSL \
    			$(EOLIST)
    
    #
    # These flags will be added to the link.opt file
    #
    XLFLAGS		+= \
    			-l $(SSL_LIB) \
    			$(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.
    #
    ifeq "$(USE_NTLS)" "1"
    NLM_DESCRIPTION	= Apache $(VERSION_STR) SSL module (NTLS)
    else
    NLM_DESCRIPTION	= Apache $(VERSION_STR) SSL module (OpenSSL)
    endif
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_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	= 8192
    
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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 := $(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 = \
    	$(PRELUDE) \
    	$(EOLIST)
    
    ifneq "$(USE_NTLS)" "1"
    FILES_nlm_libs += \
    	$(SSL_LIB)/crypto.lib \
    	$(SSL_LIB)/ssl.lib \
    	$(EOLIST)
    endif
    
    #
    # 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)
    
    ifeq "$(USE_NTLS)" "1"
    FILES_nlm_modules += ntls \
    	$(EOLIST)
    endif
    
    #
    # 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 \
    	@aprlib.imp \
    	@httpd.imp \
    	$(EOLIST)
    
    # Don't link with Winsock if standard sockets are being used
    ifneq "$(USE_STDSOCKETS)" "1"
    FILES_nlm_Ximports += @ws2nlm.imp \
    	$(EOLIST)
    endif
    
    ifeq "$(USE_NTLS)" "1"
    FILES_nlm_Ximports += @ntls.imp \
    	$(EOLIST)
    else
    FILES_nlm_Ximports += \
    	GetProcessSwitchCount \
    	RunningProcess \
    	GetSuperHighResolutionTimer \
    	$(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
    	$(call COPY,$(OBJDIR)/*.nlm,        $(INSTALLBASE)/modules/)
    	$(call COPY,$(SSL_BIN)/openssl.nlm, $(INSTALLBASE)/bin/)
    	$(call COPY,$(SSL_APP)/openssl.cnf, $(INSTALLBASE)/bin/)
    
    #
    # 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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������httpd-2.4.64/modules/mappers/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766613�015752� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/NWGNUspeling�����������������������������������������������������������0000664�0001751�0001751�00000010143�11540546347�020154� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/NWGNUrewrite�����������������������������������������������������������0000664�0001751�0001751�00000010240�11540546347�020172� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/database \
    			$(AP_WORK)/modules/ssl \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/NWGNUactions�����������������������������������������������������������0000664�0001751�0001751�00000010143�11540546347�020153� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/NWGNUimagemap����������������������������������������������������������0000664�0001751�0001751�00000010210�11540546347�020266� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/NWGNUvhost�������������������������������������������������������������0000664�0001751�0001751�00000010214�11540546347�017655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_actions.dsp��������������������������������������������������������0000664�0001751�0001751�00000010621�10551346420�020750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_actions.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_actions.so" /d LONG_NAME="actions_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_actions.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_actions.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_actions.so" /d LONG_NAME="actions_module for Apache"
    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 /out:".\Debug\mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_actions.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_userdir.dsp��������������������������������������������������������0000664�0001751�0001751�00000010621�10551346420�020765� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_userdir.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_userdir.so" /d LONG_NAME="userdir_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_userdir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_userdir.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_userdir.so" /d LONG_NAME="userdir_module for Apache"
    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 /out:".\Debug\mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_userdir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_vhost_alias.exp����������������������������������������������������0000664�0001751�0001751�00000000023�10150161574�021625� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vhost_alias_module
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_dir.exp������������������������������������������������������������0000664�0001751�0001751�00000000013�10150161574�020066� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dir_module
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_negotiation.exp����������������������������������������������������0000664�0001751�0001751�00000000023�10150161574�021631� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������negotiation_module
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_imagemap.c���������������������������������������������������������0000664�0001751�0001751�00000072426�14640775605�020555� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    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_palloc(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; numverts < MAXVERTS && pgon[numverts][X] != -1;
            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 const char *imap_url(request_rec *r, const char *base, const char *value)
    {
    /* translates a value into a URL. */
        apr_size_t 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 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, APLOGNO(00677)
                        "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, APLOGNO(00678)
                            "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, const 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_ex(r, "text/html; charset=ISO-8859-1", 1);
    
        ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ",
                  ap_escape_html(r->pool, r->uri),
                  "</title>\n</head><body>\n", NULL);
    
        if (!strcasecmp(menu, "formatted")) {
            ap_rvputs(r, "<h1>Menu for ",
                      ap_escape_html(r->pool, r->uri),
                      "</h1>\n<hr />\n\n", NULL);
        }
    }
    
    static void menu_blank(request_rec *r, char *menu)
    {
        if (!strcasecmp(menu, "formatted")) {
            ap_rputs("\n", r);
        }
        else if (!strcasecmp(menu, "semiformatted")) {
            ap_rputs("<br />\n", r);
        }
        else if (!strcasecmp(menu, "unformatted")) {
            ap_rputs("\n", r);
        }
    }
    
    static void menu_comment(request_rec *r, char *menu, char *comment)
    {
        /* comments are ignored in the 'formatted' form */
        if (!strcasecmp(menu, "formatted")) {
            ap_rputs("\n", r);         /* print just a newline if 'formatted' */
        }
        else if (!strcasecmp(menu, "semiformatted") && *comment) {
            ap_rvputs(r, comment, "\n", NULL);
        }
        else if (!strcasecmp(menu, "unformatted") && *comment) {
            ap_rvputs(r, comment, "\n", NULL);
        }
    }
    
    static void menu_default(request_rec *r, const char *menu, const char *href, const char *text)
    {
        char *ehref, *etext;
        if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
            return;                 /* don't print such lines, these aren't
                                       really href's */
        }
    
        ehref = ap_escape_uri(r->pool, href);
        etext = ap_escape_html(r->pool, text);
    
        if (!strcasecmp(menu, "formatted")) {
            ap_rvputs(r, "<pre>(Default) <a href=\"", ehref, "\">", etext,
                         "</a></pre>\n", NULL);
        }
        else if (!strcasecmp(menu, "semiformatted")) {
            ap_rvputs(r, "<pre>(Default) <a href=\"", ehref, "\">", etext,
                   "</a></pre>\n", NULL);
        }
        else if (!strcasecmp(menu, "unformatted")) {
            ap_rvputs(r, "<a href=\"", ehref, "\">", etext, "</a>", NULL);
        }
    }
    
    static void menu_directive(request_rec *r, const char *menu, const char *href, const char *text)
    {
        char *ehref, *etext;
        if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
            return;                 /* don't print such lines, as this isn't
                                       really an href */
        }
    
        ehref = ap_escape_uri(r->pool, href);
        etext = ap_escape_html(r->pool, text);
    
        if (!strcasecmp(menu, "formatted")) {
            ap_rvputs(r, "<pre>          <a href=\"", ehref, "\">", etext,
                   "</a></pre>\n", NULL);
        }
        else if (!strcasecmp(menu, "semiformatted")) {
            ap_rvputs(r, "<pre>          <a href=\"", ehref, "\">", etext,
                   "</a></pre>\n", NULL);
        }
        else if (!strcasecmp(menu, "unformatted")) {
            ap_rvputs(r, "<a href=\"", ehref, "\">", etext, "</a>", NULL);
        }
    }
    
    static void menu_footer(request_rec *r)
    {
        ap_rputs("\n\n</body>\n</html>\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;
        const char *base;
        const char *redirect;
        const 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 (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, APLOGNO(00679)
                    "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);
    }
    
    AP_DECLARE_MODULE(imagemap) =
    {
        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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/config9.m4�������������������������������������������������������������0000664�0001751�0001751�00000001710�14451777615�017561� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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, , , most)
    APACHE_MODULE(dir, directory request handling, , , yes)
    APACHE_MODULE(imagemap, server-side imagemaps, , , no)
    APACHE_MODULE(actions, Action triggering on requests, , , most)
    APACHE_MODULE(speling, correct common URL misspellings, , , most)
    APACHE_MODULE(userdir, mapping of requests to user-specific directories, , , most)
    APACHE_MODULE(alias, mapping of requests to different filesystem parts, , , yes)
    APACHE_MODULE(rewrite, rule based URL manipulation, , , most)
    
    if test "x$enable_rewrite" != "xno"; then
        # mod_rewrite needs test_char.h
        APR_ADDTO(INCLUDES, [-I\$(top_builddir)/server])
    fi
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    ��������������������������������������������������������httpd-2.4.64/modules/mappers/mod_dir.c��������������������������������������������������������������0000664�0001751�0001751�00000033471�13066765661�017552� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "apr_lib.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_rewrite.h"
    
    module AP_MODULE_DECLARE_DATA dir_module;
    
    typedef enum {
        MODDIR_OFF = 0,
        MODDIR_ON,
        MODDIR_UNSET
    } moddir_cfg;
    
    #define REDIRECT_OFF   0
    #define REDIRECT_UNSET 1
    
    typedef struct dir_config_struct {
        apr_array_header_t *index_names;
        moddir_cfg do_slash;
        moddir_cfg checkhandler;
        int redirect_index;
        const char *dflt;
    } 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;
        const char *t, *w;
        int count = 0;
    
        if (!d->index_names) {
            d->index_names = apr_array_make(cmd->pool, 2, sizeof(char *));
        }
    
        t = arg;
        while ((w = ap_getword_conf(cmd->pool, &t)) && w[0]) {
            if (count == 0 && !strcasecmp(w, "disabled")) {
                /* peek to see if "disabled" is first in a series of arguments */
                const char *tt = t;
                const char *ww = ap_getword_conf(cmd->temp_pool, &tt);
                if (ww[0] == '\0') {
                   /* "disabled" is first, and alone */
                   apr_array_clear(d->index_names); 
                   break;
                }
            }
            *(const char **)apr_array_push(d->index_names) = w;
            count++;
        }
    
        return NULL;
    }
    
    static const char *configure_slash(cmd_parms *cmd, void *d_, int arg)
    {
        dir_config_rec *d = d_;
    
        d->do_slash = arg ? MODDIR_ON : MODDIR_OFF;
        return NULL;
    }
    static const char *configure_checkhandler(cmd_parms *cmd, void *d_, int arg)
    {
        dir_config_rec *d = d_;
    
        d->checkhandler = arg ? MODDIR_ON : MODDIR_OFF;
        return NULL;
    }
    static const char *configure_redirect(cmd_parms *cmd, void *d_, const char *arg1)
    {
        dir_config_rec *d = d_;
        int status;
    
        if (!strcasecmp(arg1, "ON"))
            status = HTTP_MOVED_TEMPORARILY;
        else if (!strcasecmp(arg1, "OFF"))
            status = REDIRECT_OFF;
        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);
            if (!ap_is_HTTP_REDIRECT(status)) {
                return "DirectoryIndexRedirect only accepts values between 300 and 399";
            }
        }
        else {
            return "DirectoryIndexRedirect ON|OFF|permanent|temp|seeother|3xx";
        }
    
        d->redirect_index = status;
        return NULL;
    }
    static const command_rec dir_cmds[] =
    {
        AP_INIT_TAKE1("FallbackResource", ap_set_string_slot,
                      (void*)APR_OFFSETOF(dir_config_rec, dflt),
                      DIR_CMD_PERMS, "Set a default handler"),
        AP_INIT_RAW_ARGS("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"),
        AP_INIT_FLAG("DirectoryCheckHandler", configure_checkhandler, NULL, DIR_CMD_PERMS,
                     "On or Off"),
        AP_INIT_TAKE1("DirectoryIndexRedirect", configure_redirect,
                       NULL, DIR_CMD_PERMS, "On, Off, or a 3xx status code."),
    
        {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 = MODDIR_UNSET;
        new->checkhandler = MODDIR_UNSET;
        new->redirect_index = REDIRECT_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 == MODDIR_UNSET) ? base->do_slash : add->do_slash;
        new->checkhandler =
            (add->checkhandler == MODDIR_UNSET) ? base->checkhandler : add->checkhandler;
        new->redirect_index=
            (add->redirect_index == REDIRECT_UNSET) ? base->redirect_index : add->redirect_index;
        new->dflt = add->dflt ? add->dflt : base->dflt;
        return new;
    }
    
    static int fixup_dflt(request_rec *r)
    {
        dir_config_rec *d = ap_get_module_config(r->per_dir_config, &dir_module);
        const char *name_ptr;
        request_rec *rr;
        int error_notfound = 0;
    
        name_ptr = d->dflt;
        if ((name_ptr == NULL) || !(strcasecmp(name_ptr,"disabled"))){
            return DECLINED;
        }
        /* XXX: if FallbackResource points to something that doesn't exist,
         * this may recurse until it hits the limit for internal redirects
         * before returning an Internal Server Error.
         */
    
        /* The logic of this function is basically cloned and simplified
         * from fixup_dir below.  See the comments there.
         */
        if (r->args != NULL) {
            name_ptr = apr_pstrcat(r->pool, name_ptr, "?", r->args, NULL);
        }
        rr = ap_sub_req_lookup_uri(name_ptr, r, r->output_filters);
        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;
        }
        else if (ap_is_HTTP_REDIRECT(rr->status)) {
    
            apr_pool_join(r->pool, rr->pool);
            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);
            error_notfound = rr->status;
        }
        else 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 int fixup_dir(request_rec *r)
    {
        dir_config_rec *d;
        char *dummy_ptr[1];
        char **names_ptr;
        int num_names;
        int error_notfound = 0;
    
        /* 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;
        }
    
        /* we're running between mod_rewrites fixup and its internal redirect handler, step aside */
        if (!strcmp(r->handler, REWRITE_REDIRECT_HANDLER_NAME)) { 
            /* Prevent DIR_MAGIC_TYPE from leaking out when someone has taken over */
            if (!strcmp(r->content_type, DIR_MAGIC_TYPE)) { 
                r->content_type = NULL;
            }
            return DECLINED;
        }
    
        if (d->checkhandler == MODDIR_ON && strcmp(r->handler, DIR_MAGIC_TYPE)) {
            /* Prevent DIR_MAGIC_TYPE from leaking out when someone has taken over */
            if (!strcmp(r->content_type, DIR_MAGIC_TYPE)) { 
                r->content_type = NULL;
            }
            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, r->output_filters);
    
            /* The sub request lookup is very liberal, and the core map_to_storage
             * handler will almost always result in HTTP_OK as /foo/index.html
             * may be /foo with PATH_INFO="/index.html", or even / with
             * PATH_INFO="/foo/index.html". To get around this we insist that the
             * the index be a regular filetype.
             *
             * Another reason is that the core handler also makes the assumption
             * that if r->finfo is still NULL by the time it gets called, the
             * file does not exist.
             */
            if (rr->status == HTTP_OK
                && (   (rr->handler && !strcmp(rr->handler, "proxy-server"))
                    || rr->finfo.filetype == APR_REG)) {
    
                if (ap_is_HTTP_REDIRECT(d->redirect_index)) {
                    apr_table_setn(r->headers_out, "Location", ap_construct_url(r->pool, rr->uri, r));
                    return d->redirect_index;
                }
    
                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;
        }
    
        /* record what we tried, mostly for the benefit of mod_autoindex */
        apr_table_setn(r->notes, "dir-index-names",
                       d->index_names ?
                           apr_array_pstrcat(r->pool, d->index_names, ',') :
                           AP_DEFAULT_INDEX);
    
        /* nothing for us to do, pass on through */
        return DECLINED;
    }
    
    static int dir_fixups(request_rec *r)
    {
        if (r->finfo.filetype == APR_DIR) {
            /* serve up a directory */
            return fixup_dir(r);
        }
        else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) {
            /* No handler and nothing in the filesystem - use fallback */
            return fixup_dflt(r);
        }
        return DECLINED;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_fixups(dir_fixups,NULL,NULL,APR_HOOK_LAST);
    }
    
    AP_DECLARE_MODULE(dir) = {
        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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_actions.exp��������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�020754� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actions_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_vhost_alias.dsp����������������������������������������������������0000664�0001751�0001751�00000011011�10551346420�021616� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_vhost_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_vhost_alias.so" /d LONG_NAME="vhost_alias_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_vhost_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_vhost_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_vhost_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_vhost_alias.so" /d LONG_NAME="vhost_alias_module for Apache"
    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 /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 /out:".\Debug\mod_vhost_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_vhost_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_speling.dsp��������������������������������������������������������0000664�0001751�0001751�00000010621�10551346420�020751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_speling.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_speling.so" /d LONG_NAME="speling_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_speling.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_speling.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_speling.so" /d LONG_NAME="speling_module for Apache"
    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 /out:".\Debug\mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_speling.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/Makefile.in������������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�020002� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/.indent.pro������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�020027� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_imagemap.exp�������������������������������������������������������0000664�0001751�0001751�00000000014�10225112423�021061� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������imap_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_rewrite.c����������������������������������������������������������0000664�0001751�0001751�00000560165�15032733516�020447� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_dbd.h"
    
    #include "apr_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    #include "mod_dbd.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 <unistd.h>
    #endif
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #if APR_HAVE_STDARG_H
    #include <stdarg.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_CTYPE_H
    #include <ctype.h>
    #endif
    #if APR_HAVE_NETINET_IN_H
    #include <netinet/in.h>
    #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_ssl.h"
    #include "http_vhost.h"
    #include "util_mutex.h"
    
    #include "mod_rewrite.h"
    #include "ap_expr.h"
    
    #include "test_char.h"
    
    static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL;
    static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
    static const char* really_last_key = "rewrite_really_last";
    
    /*
     * 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.
     */
    /* If logging is limited to APLOG_DEBUG or lower, disable rewrite log, too */
    #ifdef  APLOG_MAX_LOGLEVEL
    #if     APLOG_MAX_LOGLEVEL < APLOG_TRACE1
    #ifndef REWRITELOG_DISABLED
    #define REWRITELOG_DISABLED
    #endif
    #endif
    #endif
    
    #ifndef REWRITELOG_DISABLED
    #ifdef AP_HAVE_C99
    #define rewritelog(...) do_rewritelog(__LINE__, __VA_ARGS__)
    #else
    #define rewritelog do_rewritelog
    #endif
    #define REWRITELOG_MODE  ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
    #define REWRITELOG_FLAGS ( APR_WRITE | APR_APPEND | APR_CREATE )
    
    #else /* !REWRITELOG_DISABLED */
    
    #ifdef AP_HAVE_C99
    #define rewritelog(...)
    #else
    #define rewritelog do_rewritelog
    #endif
    #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 CONDFLAG_NOVARY             (1<<4)
    
    #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)
    #define RULEFLAG_ESCAPEBACKREF      (1<<14)
    #define RULEFLAG_DISCARDPATHINFO    (1<<15)
    #define RULEFLAG_QSDISCARD          (1<<16)
    #define RULEFLAG_END                (1<<17)
    #define RULEFLAG_ESCAPENOPLUS       (1<<18)
    #define RULEFLAG_QSLAST             (1<<19)
    #define RULEFLAG_QSNONE             (1<<20) /* programattic only */
    #define RULEFLAG_ESCAPECTLS         (1<<21)
    #define RULEFLAG_UNSAFE_PREFIX_STAT (1<<22)
    #define RULEFLAG_UNSAFE_ALLOW3F     (1<<23)
    #define RULEFLAG_UNC                (1<<24)
    
    /* 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 ACTION_STATUS_SET           (1<<3)
    
    #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 MAPTYPE_DBD                 (1<<5)
    #define MAPTYPE_DBD_CACHE           (1<<6)
    
    #define ENGINE_DISABLED             (1<<0)
    #define ENGINE_ENABLED              (1<<1)
    
    #define OPTION_NONE                 (1<<0)
    #define OPTION_INHERIT              (1<<1)
    #define OPTION_INHERIT_BEFORE       (1<<2)
    #define OPTION_NOSLASH              (1<<3)
    #define OPTION_ANYURI               (1<<4)
    #define OPTION_MERGEBASE            (1<<5)
    #define OPTION_INHERIT_DOWN         (1<<6)
    #define OPTION_INHERIT_DOWN_BEFORE  (1<<7)
    #define OPTION_IGNORE_INHERIT       (1<<8)
    #define OPTION_IGNORE_CONTEXT_INFO  (1<<9)
    #define OPTION_LEGACY_PREFIX_DOCROOT (1<<10)
    #define OPTION_UNSAFE_PREFIX_STAT   (1<<12)
    
    #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)))
    
    #ifndef REWRITE_MAX_ROUNDS
    #define REWRITE_MAX_ROUNDS 32000
    #endif
    
    /*
     * +-------------------------------------------------------+
     * |                                                       |
     * |                 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    */
        const char *dbdq;              /* SQL SELECT statement for rewritemap */
        const char *checkfile2;        /* filename to check for map existence
                                          NULL if only one file               */
        const char *user;              /* run RewriteMap program as this user */
        const char *group;             /* run RewriteMap program as this group */
    } 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_LT,
        CONDPAT_STR_LE,
        CONDPAT_STR_EQ,
        CONDPAT_STR_GT,
        CONDPAT_STR_GE,
        CONDPAT_INT_LT,
        CONDPAT_INT_LE,
        CONDPAT_INT_EQ,
        CONDPAT_INT_GT,
        CONDPAT_INT_GE,
        CONDPAT_AP_EXPR
    } pattern_type;
    
    typedef enum {
      RULE_RC_NOMATCH = 0,      /* the rule didn't match                        */
      RULE_RC_MATCH = 1,        /* a matching rule w/ substitution              */
      RULE_RC_NOSUB = 2,        /* a matching rule w/ no substitution           */
      RULE_RC_STATUS_SET = 3    /* a matching rule that has set an HTTP error
                                   to be returned in r->status */
    } rule_return_type;
    
    typedef enum {
      COND_RC_NOMATCH = 0,      /* the cond didn't match                        */
      COND_RC_MATCH = 1,        /* the cond matched                             */
      COND_RC_STATUS_SET = 3    /* The condition eval set a final r->status     */
    } cond_return_type;
    
    typedef struct {
        char           *input;   /* Input string of RewriteCond   */
        char           *pattern; /* the RegExp pattern string     */
        ap_regex_t     *regexp;  /* the precompiled regexp        */
        ap_expr_info_t *expr;    /* the compiled ap_expr          */
        int             flags;   /* Flags which control the match */
        pattern_type    ptype;   /* pattern type                  */
        int             pskip;   /* back-index to display pattern */
    } 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          */
        int        maxrounds;            /* limit on number of loops with N flag  */
        const char *escapes;             /* specific backref escapes              */
        const char *noescapes;           /* specific backref chars not to escape  */
    } rewriterule_entry;
    
    typedef struct {
        int           state;              /* the RewriteEngine state            */
        int           options;            /* the RewriteOption state            */
        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 */
        unsigned int state_set:1;
        unsigned int options_set:1;
    } 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    */
        unsigned int state_set:1;
        unsigned int options_set:1;
        unsigned int baseurl_set:1;
    } 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 {
        const char *source;
        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;
    
    /* Locks/Mutexes */
    static int rewrite_lock_needed = 0;
    static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL;
    static const char *rewritemap_mutex_type = "rewrite-map";
    
    /* Optional functions imported from mod_ssl when loaded: */
    static char *escape_backref(apr_pool_t *p, const char *path,
                                const char *escapeme, const char *noescapeme,
                                int flags);
    
    /*
     * +-------------------------------------------------------+
     * |                                                       |
     * |              rewriting logfile support
     * |                                                       |
     * +-------------------------------------------------------+
     */
    
    /* Slightly complicated definitions follow here to support
     * compile-time choice of enabled/disabled of rewritelog both with or
     * without C99 support, where varargs macros are only available with
     * C99.
     * 
     * do_rewritelog is defined for (rewritelog enabled) or (rewritelog
     * disabled AND no C99 support) but is an noop for the latter case and
     * should get optimized away.
     *
     * For the (rewritelog disabled) case the function is defined
     * differently for C99/non-C99. For C99, the rewritelog() macro passes
     * __LINE__, allowing accurate logging of line numbers. For non-C99
     * the line number used for rewritelog() tracing is always
     * constant. */
    
    #if !defined(REWRITELOG_DISABLED) || !defined(AP_HAVE_C99)
    
    #ifdef AP_HAVE_C99
    static void do_rewritelog(int line,
                              request_rec *r, int level, char *perdir,
                              const char *fmt, ...)
            __attribute__((format(printf,5,6)));
    #else
    static void do_rewritelog(request_rec *r, int level, char *perdir,
                              const char *fmt, ...)
            __attribute__((format(printf,4,5)));
    #endif
    
    static void do_rewritelog(
    #ifdef AP_HAVE_C99
                              int line,
    #endif
                              request_rec *r, int level, char *perdir,
                              const char *fmt, ...)
    {
    #ifndef REWRITELOG_DISABLED
        char *logline, *text;
        const char *rhost, *rname;
        int redir;
        request_rec *req;
        va_list ap;
    
        if (!APLOG_R_IS_LEVEL(r, APLOG_DEBUG + level))
            return;
    
        rhost = ap_get_useragent_host(r, 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/sid#%pp][rid#%pp/%s%s%s] "
                                        "%s%s%s%s",
                               rhost ? rhost : "UNKNOWN-HOST",
                               rname ? rname : "-",
                               r->user ? (*r->user ? r->user : "\"\"") : "-",
                               ap_get_server_name(r),
                               (void *)(r->server),
                               (void *)r,
                               r->main ? "subreq" : "initial",
                               redir ? "/redir#" : "",
                               redir ? apr_itoa(r->pool, redir) : "",
                               perdir ? "[perdir " : "",
                               perdir ? perdir : "",
                               perdir ? "] ": "",
                               text);
    
        AP_REWRITE_LOG((uintptr_t)r, level, r->main ? 0 : 1, (char *)ap_get_server_name(r), logline);
    
        /* Intentional no APLOGNO */
    #ifdef AP_HAVE_C99
        ap_log_rerror(__FILE__, line, APLOG_MODULE_INDEX, APLOG_DEBUG + level, 0, r, "%s", logline);
    #else
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG + level, 0, r, "%s", logline);
    #endif
        
    #endif /* !REWRITELOG_DISABLED */
    }
    #endif /* !defined(REWRITELOG_DISABLED) || !defined(AP_HAVE_C99) */
    
    
    /*
     * +-------------------------------------------------------+
     * |                                                       |
     * |                URI and path functions
     * |                                                       |
     * +-------------------------------------------------------+
     */
    
    /* return number of chars of the scheme (incl. '://')
     * if the URI is absolute (includes a scheme etc.)
     * otherwise 0.
     * If supportqs is not NULL, we return a whether or not
     * the scheme supports a query string or not.
     *
     * 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, int *supportsqs)
    {
        int dummy, *sqs;
    
        sqs = (supportsqs ? supportsqs : &dummy);
        *sqs = 0;
        /* fast exit */
        if (*uri == '/' || strlen(uri) <= 5) {
            return 0;
        }
    
        switch (*uri++) {
        case 'a':
        case 'A':
            if (!ap_cstr_casecmpn(uri, "jp://", 5)) {        /* ajp://    */
              *sqs = 1;
              return 6;
            }
            break;
    
        case 'b':
        case 'B':
            if (!ap_cstr_casecmpn(uri, "alancer://", 10)) {   /* balancer:// */
              *sqs = 1;
              return 11;
            }
            break;
    
        case 'f':
        case 'F':
            if (!ap_cstr_casecmpn(uri, "tp://", 5)) {        /* ftp://    */
                return 6;
            }
            if (!ap_cstr_casecmpn(uri, "cgi://", 6)) {       /* fcgi://   */
                *sqs = 1;
                return 7;
            }
            break;
    
        case 'g':
        case 'G':
            if (!ap_cstr_casecmpn(uri, "opher://", 8)) {     /* gopher:// */
                return 9;
            }
            break;
    
        case 'h':
        case 'H':
            if (!ap_cstr_casecmpn(uri, "ttp://", 6)) {       /* http://   */
                *sqs = 1;
                return 7;
            }
            else if (!ap_cstr_casecmpn(uri, "ttps://", 7)) { /* https://  */
                *sqs = 1;
                return 8;
            }
            else if (!ap_cstr_casecmpn(uri, "2://", 4)) {    /* h2://     */
                *sqs = 1;
                return 5;
            }
            else if (!ap_cstr_casecmpn(uri, "2c://", 5)) {   /* h2c://    */
                *sqs = 1;
                return 6;
            }
            break;
    
        case 'l':
        case 'L':
            if (!ap_cstr_casecmpn(uri, "dap://", 6)) {       /* ldap://   */
                return 7;
            }
            break;
    
        case 'm':
        case 'M':
            if (!ap_cstr_casecmpn(uri, "ailto:", 6)) {       /* mailto:   */
                *sqs = 1;
                return 7;
            }
            break;
    
        case 'n':
        case 'N':
            if (!ap_cstr_casecmpn(uri, "ews:", 4)) {         /* news:     */
                return 5;
            }
            else if (!ap_cstr_casecmpn(uri, "ntp://", 6)) {  /* nntp://   */
                return 7;
            }
            break;
    
        case 's':
        case 'S':
            if (!ap_cstr_casecmpn(uri, "cgi://", 6)) {       /* scgi://   */
                *sqs = 1;
                return 7;
            }
            break;
    
        case 'w':
        case 'W':
            if (!ap_cstr_casecmpn(uri, "s://", 4)) {        /* ws://     */
                *sqs = 1;
                return 5;
            }
            else if (!ap_cstr_casecmpn(uri, "ss://", 5)) {  /* wss://    */
                *sqs = 1;
                return 6;
            }
            break;
    
        case 'u':
        case 'U':
            if (!ap_cstr_casecmpn(uri, "nix:", 4)) {        /* unix:     */
                *sqs = 1;
                return (uri[4] == '/' && uri[5] == '/') ? 7 : 5;
            }
        }
    
        return 0;
    }
    
    static int is_absolute_path(const char *path)
    {
    #ifndef CASE_BLIND_FILESYSTEM
        return (path[0] == '/');
    #else
        return ((AP_IS_SLASH(path[0]) && path[1] == path[0])
                || (apr_isalpha(path[0]) && path[1] == ':' && AP_IS_SLASH(path[2])));
    #endif
    }
    
    static const char c2x_table[] = "0123456789abcdef";
    
    static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
                                         unsigned char *where)
    {
    #if APR_CHARSET_EBCDIC
        what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what);
    #endif /*APR_CHARSET_EBCDIC*/
        *where++ = prefix;
        *where++ = c2x_table[what >> 4];
        *where++ = c2x_table[what & 0xf];
        return where;
    }
    
    /*
     * Escapes a backreference in a similar way as php's urlencode does.
     * Based on ap_os_escape_path in server/util.c
     */
    static char *escape_backref(apr_pool_t *p, const char *path,
                                const char *escapeme, const char *noescapeme,
                                int flags)
    {
        char *copy = apr_palloc(p, 3 * strlen(path) + 1);
        const unsigned char *s = (const unsigned char *)path;
        unsigned char *d = (unsigned char *)copy;
        int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0;
        int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0;
        unsigned char c;
    
        while ((c = *s)) {
            if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
                 || (escapeme && ap_strchr_c(escapeme, c)))
                && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
                if (apr_isalnum(c) || c == '_') {
                    *d++ = c;
                }
                else if (c == ' ' && !noplus) {
                    *d++ = '+';
                }
                else {
                    d = c2x(c, '%', d);
                }
            }
            else {
                *d++ = c;
            }
            ++s;
        }
        *d = '\0';
        return copy;
    }
    
    /*
     * 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 (!ap_cstr_casecmpn(uri, "ldap", 4)) {
                char *token[5];
                int c = 0;
    
                token[0] = cp = apr_pstrdup(p, cp);
                while (*cp && c < 4) {
                    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 flags)
    {
        char *q;
        int split, skip;
        int qsappend = flags & RULEFLAG_QSAPPEND;
        int qsdiscard = flags & RULEFLAG_QSDISCARD;
        int qslast = flags & RULEFLAG_QSLAST;
    
        if (flags & RULEFLAG_QSNONE) {
            rewritelog(r, 2, NULL, "discarding query string, no parse from substitution");
            r->args = NULL;
            return;
        }
    
        /* don't touch, unless it's a scheme for which a query string makes sense.
         * See RFC 1738 and RFC 2368.
         */
        if ((skip = is_absolute_uri(r->filename, &split))
            && !split) {
            r->args = NULL; /* forget the query that's still flying around */
            return;
        }
    
        if (qsdiscard) {
            r->args = NULL; /* Discard query string */
            rewritelog(r, 2, NULL, "discarding query string");
        }
    
        q = qslast ? ap_strrchr(r->filename + skip, '?') : ap_strchr(r->filename + skip, '?');
    
        if (q != NULL) {
            char *olduri;
            apr_size_t len;
    
            olduri = apr_pstrdup(r->pool, r->filename);
            *q++ = '\0';
            if (qsappend) {
                if (*q) {
                    r->args = apr_pstrcat(r->pool, q, "&" , r->args, NULL);
                }
            }
            else {
                r->args = apr_pstrdup(r->pool, q);
            }
    
            if (r->args) {
               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 : "<none>");
        }
    }
    
    /*
     * 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
            && ap_cstr_casecmpn(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)) {
                rewrite_server_conf *conf = 
                    ap_get_module_config(r->server->module_config, &rewrite_module);
                rewritelog(r, 3, NULL, "reduce %s -> %s", r->filename, url);
                r->filename = apr_pstrdup(r->pool, url);
    
                /* remember that the uri was reduced */
                if(!(conf->options & OPTION_LEGACY_PREFIX_DOCROOT)) {
                    apr_table_setn(r->notes, "mod_rewrite_uri_reduced", "true");
                }
            }
        }
    
        return;
    }
    
    /*
     * add 'http[s]://ourhost[:ourport]/' to URI
     * if URI is still not fully qualified
     */
    static void fully_qualify_uri(request_rec *r)
    {
        if (r->method_number == M_CONNECT) {
            return;
        }
        else if (!is_absolute_uri(r->filename, NULL)) {
            const char *thisserver;
            char *thisport;
            int port;
    
            thisserver = ap_get_server_name_for_url(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;
    }
    
    static int startsWith(request_rec *r, const char *haystack, const char *needle) {
        int rc = (ap_strstr_c(haystack, needle) == haystack);
        rewritelog(r, 5, NULL, "prefix_stat startsWith(%s, %s) %d", haystack, needle, rc);
        return rc;
    }
    /*
     * stat() only the first segment of a path, and only if it matches the output of the last matching rule
     */
    static int prefix_stat(request_rec *r, const char *path, apr_pool_t *pool, rewriterule_entry *lastsub)
    {
        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) {
                if (!lastsub) {
                    rewritelog(r, 3, NULL, "prefix_stat no lastsub subst prefix %s", statpath);
                    return 1;
                }
    
                rewritelog(r, 3, NULL, "prefix_stat compare statpath %s and lastsub output %s STATOK %d ",
                        statpath, lastsub->output, lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT);
                if (lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT) {
                    return 1;
                }
                else {
                    const char *docroot = ap_document_root(r);
                    const char *context_docroot = ap_context_document_root(r);
                    /*
                     * As an example, path (r->filename) is /var/foo/bar/baz.html
                     * even if the flag is not set,  we can accept a rule that
                     * began with a literal /var (stapath), or if the entire path
                     * starts with the docroot or context document root
                     */
                    if (startsWith(r, lastsub->output, statpath) ||
                            startsWith(r, path, docroot) ||
                            ((docroot != context_docroot) &&
                              startsWith(r, path, context_docroot))) {
                        return 1;
                    }
                }
            }
        }
    
        /* prefix will be added */
        return 0;
    }
    
    /*
     * substitute the prefix path 'match' in 'input' with 'subst' (RewriteBase)
     */
    static char *subst_prefix_path(request_rec *r, char *input, const 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;
                }
                apr_pool_tag(p, "rewrite_cachedmap");
    
                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;
        }
        apr_pool_tag(cachep->pool, "rewrite_cachep");
    
        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)
    {
        ap_str_toupper(key);
    
        return key;
    }
    
    static char *rewrite_mapfunc_tolower(request_rec *r, char *key)
    {
        ap_str_tolower(key);
    
        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) {
            n = ap_random_pick(1, n);
    
            /* 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, APLOGNO(00653) "%s", desc);
    }
    
    static apr_status_t rewritemap_program_child(apr_pool_t *p,
                                                 const char *progname, char **argv,
                                                 const char *user, const char *group,
                                                 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])))
            && (!user || APR_SUCCESS == (rc=apr_procattr_user_set(procattr, user, "")))
            && (!group || APR_SUCCESS == (rc=apr_procattr_group_set(procattr, group)))
            && 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;
    
        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;
            }
    
            rc = rewritemap_program_child(p, map->argv[0], map->argv,
                                          map->user, map->group,
                                          &fpout, &fpin);
            if (rc != APR_SUCCESS || fpin == NULL || fpout == NULL) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, APLOGNO(00654)
                             "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;
        apr_status_t rv;
    
        if ((rv = apr_file_open(&fp, file, APR_READ|APR_BUFFERED, APR_OS_DEFAULT,
                                r->pool)) != APR_SUCCESS)
        {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00655)
                          "mod_rewrite: can't open text RewriteMap file %s", file);
            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 (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)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *dbmfp = NULL;
        apr_datum_t dbmkey;
        apr_datum_t dbmval;
        char *value;
        apr_status_t rv;
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, dbmtype, &err,
                r->pool)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10287)
                    "mod_rewrite: can't load DBM library '%s': %s",
                         err->reason, err->msg);
            return NULL;
        }
        if ((rv = apr_dbm_open2(&dbmfp, driver, file, APR_DBM_READONLY,
                                  APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00656)
                          "mod_rewrite: can't open DBM RewriteMap %s", file);
            return NULL;
        }
    #else
        if ((rv = apr_dbm_open_ex(&dbmfp, dbmtype, file, APR_DBM_READONLY,
                                  APR_OS_DEFAULT, r->pool)) != APR_SUCCESS)
        {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00656)
                          "mod_rewrite: can't open DBM RewriteMap %s", file);
            return NULL;
        }
    #endif
    
        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_dbd(request_rec *r, char *key, const char *label)
    {
        apr_status_t rv;
        apr_dbd_prepared_t *stmt;
        const char *errmsg;
        apr_dbd_results_t *res = NULL;
        apr_dbd_row_t *row = NULL;
        char *ret = NULL;
        int n = 0;
        ap_dbd_t *db = dbd_acquire(r);
        
        if (db == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02963)
                          "rewritemap: No db handle available! "
                          "Check your database access");
            return NULL;
       }
    
        stmt = apr_hash_get(db->prepared, label, APR_HASH_KEY_STRING);
    
        rv = apr_dbd_pvselect(db->driver, r->pool, db->handle, &res,
                              stmt, 0, key, NULL);
        if (rv != 0) {
            errmsg = apr_dbd_error(db->driver, db->handle, rv);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00657)
                          "rewritemap: error %s querying for %s", errmsg, key);
            return NULL;
        }
        while ((rv = apr_dbd_get_row(db->driver, r->pool, res, &row, -1)) == 0) {
            ++n;
            if (ret == NULL) {
                ret = apr_pstrdup(r->pool,
                                  apr_dbd_get_entry(db->driver, row, 0));
            }
            else {
                /* randomise crudely amongst multiple results */
                if ((double)rand() < (double)RAND_MAX/(double)n) {
                    ret = apr_pstrdup(r->pool,
                                      apr_dbd_get_entry(db->driver, row, 0));
                }
            }
        }
        if (rv != -1) {
            errmsg = apr_dbd_error(db->driver, db->handle, rv);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00658)
                          "rewritemap: error %s looking up %s", errmsg, key);
        }
        switch (n) {
        case 0:
            return NULL;
        case 1:
            return ret;
        default:
            /* what's a fair rewritelog level for this? */
            rewritelog(r, 3, NULL, "Multiple values found for %s", key);
            return ret;
        }
    }
    
    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, APLOGNO(00659)
                              "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);
        /* XXX: error handling */
        apr_file_write_full(fpin, key, nbytes, NULL);
        nbytes = 1;
        apr_file_write_full(fpin, "\n", nbytes, NULL);
    #else
        iova[0].iov_base = key;
        iova[0].iov_len = strlen(key);
        iova[1].iov_base = "\n";
        iova[1].iov_len = 1;
    
        niov = 2;
        /* XXX: error handling */
        apr_file_writev_full(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) {
                    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, APLOGNO(00660)
                              "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, APLOGNO(00661)
                              "mod_rewrite: can't access text RewriteMap file %s",
                              s->checkfile);
                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, APLOGNO(00662)
                              "mod_rewrite: can't access DBM RewriteMap file %s",
                              s->checkfile);
            }
            else if(s->checkfile2 != NULL) {
                apr_finfo_t st2;
    
                rv = apr_stat(&st2, s->checkfile2, APR_FINFO_MIN, r->pool);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00663)
                                  "mod_rewrite: can't access DBM RewriteMap "
                                  "file %s", s->checkfile2);
                }
                else if(st2.mtime > st.mtime) {
                    st.mtime = st2.mtime;
                }
            }
            if(rv != APR_SUCCESS) {
                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;
    
        /*
         * SQL map without cache
         */
        case MAPTYPE_DBD:
            value = lookup_map_dbd(r, key, s->dbdq);
            if (!value) {
                rewritelog(r, 5, NULL, "SQL map lookup FAILED: map %s key=%s",
                           name, key);
                return NULL;
            }
    
            rewritelog(r, 5, NULL, "SQL map lookup OK: map %s key=%s, val=%s",
                       name, key, value);
    
            return value;
    
        /*
         * SQL map with cache
         */
        case MAPTYPE_DBD_CACHE:
            value = get_cache_value(s->cachename, 0, key, r->pool);
            if (!value) {
                rewritelog(r, 6, NULL,
                           "cache lookup FAILED, forcing new map lookup");
    
                value = lookup_map_dbd(r, key, s->dbdq);
                if (!value) {
                    rewritelog(r, 5, NULL, "SQL map lookup FAILED: map %s key=%s",
                               name, key);
                    set_cache_value(s->cachename, 0, key, "");
                    return NULL;
                }
    
                rewritelog(r, 5, NULL, "SQL map lookup OK: map %s key=%s, val=%s",
                           name, key, value);
    
                set_cache_value(s->cachename, 0, key, value);
                return value;
            }
    
            rewritelog(r, 5, NULL, "cache lookup OK: map=%s[SQL] 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);
    
        /* Skip the 'Vary: Host' header combination
         * as indicated in rfc7231 section-7.1.4
         */
        if (val && strcasecmp(name, "Host") != 0) {
            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 "";
        }
    
        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)) {
                result = ap_ssl_var_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 {
            apr_time_exp_t tm;
    
            /* can't do this above, because of the getenv call */
            ap_str_toupper(var);
    
            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;
                }
                else if (!strcmp(var, "IPV6")) {
                    int flag = FALSE;
    #if APR_HAVE_IPV6
                    apr_sockaddr_t *addr = r->useragent_addr;
                    flag = (addr->family == AF_INET6 &&
                            !IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr));
                    rewritelog(r, 1, ctx->perdir, "IPV6='%s'", flag ? "on" : "off");
    #else
                    rewritelog(r, 1, ctx->perdir, "IPV6='off' (IPv6 is not enabled)");
    #endif
                    result = (flag ? "on" : "off");
                }
                break;
    
            case  5:
                if (!strcmp(var, "HTTPS")) {
                    int flag = ap_ssl_conn_is_ssl(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_for_url(r);
                    }
                    break;
    
                case 'D':
                    if (*var == 'R' && !strcmp(var, "REMOTE_ADDR")) {
                        result = r->useragent_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->useragent_addr->port);
                    }
                    break;
    
                case 'S':
                    if (*var == 'R' && !strcmp(var, "REMOTE_USER")) {
                        result = r->user;
                    }
                    else if (!strcmp(var, "SCRIPT_USER")) {
                        result = "<unknown>";
                        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 = "<unknown>";
                        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 (*var == 'C' && !strcmp(var, "CONTEXT_PREFIX")) {
                    result = ap_context_prefix(r);
                }
                else if (var[8] == 'M' && !strcmp(var, "REQUEST_METHOD")) {
                    result = r->method;
                }
                else if (!strcmp(var, "REQUEST_SCHEME")) {
                    result = ap_http_scheme(r);
                }
                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_banner();
                    }
                    break;
                }
                break;
    
            case 16:
                if (*var == 'C' && !strcmp(var, "CONN_REMOTE_ADDR")) {
                    result = r->connection->client_ip;
                }
                else 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);
                }
                else if (!strcmp(var, "CONTEXT_DOCUMENT_ROOT")) {
                    result = ap_context_document_root(r);
                }
                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.
     *
     * unsafe_qmark if not NULL will be set to 1 or 0 if a question mark
     * is found respectively in a literal or in a lookup/expansion (whether
     * it's the first or last qmark depends on [QSL]). Should be initialized
     * to -1 and remains so if no qmark is found.
     */
    static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry,
                           int *unsafe_qmark)
    {
    #define EXPAND_SPECIALS "\\$%"
        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;
    
        inputlen = strlen(input);
        if (!unsafe_qmark) {
            span = strcspn(input, EXPAND_SPECIALS);
        }
        else {
            span = strcspn(input, EXPAND_SPECIALS "?");
            if (input[span] == '?') {
                /* this qmark is not from an expansion thus safe */
                *unsafe_qmark = 0;
    
                /* keep tracking only if interested in the last qmark */
                if (!entry || !(entry->flags & RULEFLAG_QSLAST)) {
                    unsafe_qmark = NULL;
                }
    
                /* find the next real special char, any (last) qmark up to
                 * there is safe too
                 */
                span += strcspn(input + span, EXPAND_SPECIALS);
            }
        }
    
        /* fast path (no specials) */
        if (span >= inputlen) {
            return apr_pstrmemdup(pool, input, inputlen);
        }
    
        /* 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 {
            int expanded = 0;
    
            /* 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;
    
                    expanded = 1;
                    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, entry, NULL));
                        if (!key && dflt && *dflt) {
                            key = do_expand(dflt, ctx, entry, NULL);
                        }
                        if (key && *key) {
                            span = strlen(key);
                            current->len = span;
                            current->string = key;
                            outlen += span;
                        }
    
                        expanded = 1;
                        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;
                    if (entry && (entry->flags & RULEFLAG_ESCAPEBACKREF)) {
                        /* escape the backreference */
                        char *tmp2, *tmp;
                        tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
                        tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
                                              entry->flags);
                        rewritelog(ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
                                tmp, tmp2);
    
                        current->len = span = strlen(tmp2);
                        current->string = tmp2;
                    } else {
                        current->len = span;
                        current->string = bri->source + bri->regmatch[n].rm_so;
                    }
                    outlen += span;
    
                    expanded = 1;
                }
    
                p += 2;
            }
    
            /* not for us, just copy it */
            else {
                current->len = 1;
                current->string = p++;
                ++outlen;
            }
    
            if (unsafe_qmark && expanded && current->len
                && memchr(current->string, '?', current->len)) {
                /* this qmark is from an expansion thus unsafe */
                *unsafe_qmark = 1;
    
                /* keep tracking only if interested in the last qmark */
                if (!entry || !(entry->flags & RULEFLAG_QSLAST)) {
                    unsafe_qmark = NULL;
                }
            }
    
            /* check the remainder */
            if (!unsafe_qmark) {
                span = strcspn(p, EXPAND_SPECIALS);
            }
            else {
                span = strcspn(p, EXPAND_SPECIALS "?");
                if (p[span] == '?') {
                    /* this qmark is not from an expansion thus safe */
                    *unsafe_qmark = 0;
    
                    /* keep tracking only if interested in the last qmark */
                    if (!entry || !(entry->flags & RULEFLAG_QSLAST)) {
                        unsafe_qmark = NULL;
                    }
    
                    /* find the next real special char, any (last) qmark up to
                     * there is safe too
                     */
                    span += strcspn(p + span, EXPAND_SPECIALS);
                }
            }
            if (span > 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, NULL, NULL);
            if (*name == '!') {
                name++;
                apr_table_unset(ctx->r->subprocess_env, name);
                rewritelog(ctx->r, 5, NULL, "unsetting env variable '%s'", name);
            }
            else {
                if ((val = ap_strchr(name, ':')) != NULL) {
                    *val++ = '\0';
                } else {
                    val = "";
                }
    
                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 *secure;
        char *httponly;
        char *samesite;
    
        char *tok_cntx;
        char *cookie;
        /* long-standing default, but can't use ':' in a cookie */
        const char *sep = ":"; 
    
        /* opt-in to ; separator if first character is a ; */
        if (s && *s == ';') { 
            sep = ";"; 
            s++;
        }
    
        var = apr_strtok(s, sep, &tok_cntx);
        val = apr_strtok(NULL, sep, &tok_cntx);
        domain = apr_strtok(NULL, sep, &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, sep, &tok_cntx);
                path = expires ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
                secure = path ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
                httponly = secure ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
                samesite = httponly ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
    
                if (expires) {
                    apr_time_exp_t tms;
                    long exp_min;
    
                    exp_min = atol(expires);
                    if (exp_min) {
                        apr_time_exp_gmt(&tms, r->request_time
                                         + apr_time_from_sec((60 * exp_min)));
                        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 ? (exp_time ? "; expires=" : "")
                                     : NULL,
                                     expires ? (exp_time ? exp_time : "")
                                     : NULL,
                                     (secure && (!ap_cstr_casecmp(secure, "true")
                                                 || !strcmp(secure, "1")
                                                 || !ap_cstr_casecmp(secure,
                                                                "secure"))) ?
                                      "; secure" : NULL,
                                     (httponly && (!ap_cstr_casecmp(httponly, "true")
                                                   || !strcmp(httponly, "1")
                                                   || !ap_cstr_casecmp(httponly,
                                                                  "HttpOnly"))) ?
                                      "; HttpOnly" : NULL,
                                     NULL);
    
                if (samesite && strcmp(samesite, "0") && ap_cstr_casecmp(samesite,"false")) { 
                    cookie = apr_pstrcat(rmain->pool, cookie, "; SameSite=", 
                                         samesite, 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, NULL, NULL));
            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;
    
        /* create the lockfile */
        rc = ap_global_mutex_create(&rewrite_mapr_lock_acquire, NULL,
                                    rewritemap_mutex_type, NULL, s, p, 0);
        if (rc != APR_SUCCESS) {
            return rc;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t rewritelock_remove(void *data)
    {
        /* destroy the rewritelock */
        if (rewrite_mapr_lock_acquire) {
            apr_global_mutex_destroy(rewrite_mapr_lock_acquire);
            rewrite_mapr_lock_acquire = NULL;
        }
        return APR_SUCCESS;
    }
    
    
    /*
     * +-------------------------------------------------------+
     * |                                                       |
     * |           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 **a2_end, 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 */
            *a2_end = str;
            return 0;
        }
        *a2_end = str;
        *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;
        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_set == 0) ? base->state : overrides->state;
        a->state_set = overrides->state_set || base->state_set;
        a->options = (overrides->options_set == 0) ? base->options : overrides->options;
        a->options_set = overrides->options_set || base->options_set;
    
        a->server  = overrides->server;
    
        if (a->options & OPTION_INHERIT ||
                (base->options & OPTION_INHERIT_DOWN &&
                 !(a->options & OPTION_IGNORE_INHERIT))) {
            /*
             *  local directives override
             *  and anything else is inherited
             */
            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 if (a->options & OPTION_INHERIT_BEFORE || 
                (base->options & OPTION_INHERIT_DOWN_BEFORE &&
                 !(a->options & OPTION_IGNORE_INHERIT))) {
            /*
             *  local directives override
             *  and anything else is inherited (preserving order)
             */
            a->rewritemaps     = apr_hash_overlay(p, base->rewritemaps,
                                                  overrides->rewritemaps);
            a->rewriteconds    = apr_array_append(p, base->rewriteconds,
                                                  overrides->rewriteconds);
            a->rewriterules    = apr_array_append(p, base->rewriterules,
                                                  overrides->rewriterules);
        }
        else {
            /*
             *  local directives override
             *  and anything else gets defaults
             */
            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_set == 0) ? base->state : overrides->state;
        a->state_set = overrides->state_set || base->state_set;
        a->options = (overrides->options_set == 0) ? base->options : overrides->options;
        a->options_set = overrides->options_set || base->options_set;
    
        if (a->options & OPTION_MERGEBASE) { 
            a->baseurl = (overrides->baseurl_set == 0) ? base->baseurl : overrides->baseurl;
            a->baseurl_set = overrides->baseurl_set || base->baseurl_set;
        }
        else { 
            a->baseurl = overrides->baseurl;
        }
    
        a->directory  = overrides->directory;
    
        if (a->options & OPTION_INHERIT ||
                (base->options & OPTION_INHERIT_DOWN &&
                 !(a->options & OPTION_IGNORE_INHERIT))) {
            a->rewriteconds = apr_array_append(p, overrides->rewriteconds,
                                               base->rewriteconds);
            a->rewriterules = apr_array_append(p, overrides->rewriterules,
                                               base->rewriterules);
        }
        else if (a->options & OPTION_INHERIT_BEFORE || 
                (base->options & OPTION_INHERIT_DOWN_BEFORE &&
                 !(a->options & OPTION_IGNORE_INHERIT))) {
            a->rewriteconds    = apr_array_append(p, base->rewriteconds,
                                                  overrides->rewriteconds);
            a->rewriterules    = apr_array_append(p, base->rewriterules,
                                                  overrides->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);
    
        /* server command? set both global scope and base directory scope */
        if (cmd->path == NULL) {
            sconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
            sconf->state_set = 1;
            dconf->state = sconf->state;
            dconf->state_set = 1;
        }
        /* directory command? set directory scope only */
        else {
            dconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
            dconf->state_set = 1;
        }
    
        return NULL;
    }
    
    static const char *cmd_rewriteoptions(cmd_parms *cmd,
                                          void *in_dconf, const char *option)
    {
        int options = 0;
    
        while (*option) {
            char *w = ap_getword_conf(cmd->temp_pool, &option);
    
            if (!strcasecmp(w, "inherit")) {
                options |= OPTION_INHERIT;
            }
            else if (!strcasecmp(w, "inheritbefore")) {
                options |= OPTION_INHERIT_BEFORE;
            }
            else if (!strcasecmp(w, "inheritdown")) {
                options |= OPTION_INHERIT_DOWN;
            }
            else if(!strcasecmp(w, "inheritdownbefore")) {
                options |= OPTION_INHERIT_DOWN_BEFORE;
            }
            else if (!strcasecmp(w, "ignoreinherit")) {
                options |= OPTION_IGNORE_INHERIT;
            }
            else if (!strcasecmp(w, "allownoslash")) {
                options |= OPTION_NOSLASH;
            }
            else if (!strncasecmp(w, "MaxRedirects=", 13)) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00664)
                             "RewriteOptions: MaxRedirects option has been "
                             "removed in favor of the global "
                             "LimitInternalRecursion directive and will be "
                             "ignored.");
            }
            else if (!strcasecmp(w, "allowanyuri")) {
                options |= OPTION_ANYURI;
            }
            else if (!strcasecmp(w, "mergebase")) {
                options |= OPTION_MERGEBASE;
            }
            else if (!strcasecmp(w, "ignorecontextinfo")) {
                options |= OPTION_IGNORE_CONTEXT_INFO;
            }
            else if (!strcasecmp(w, "legacyprefixdocroot")) {
                options |= OPTION_LEGACY_PREFIX_DOCROOT;
            }
            else if (!strcasecmp(w, "UnsafePrefixStat")) {
                options |= OPTION_UNSAFE_PREFIX_STAT;
            }
            else {
                return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '",
                                   w, "'", NULL);
            }
        }
    
        /* server command? set both global scope and base directory scope */
        if (cmd->path == NULL) { /* is server command */
            rewrite_perdir_conf *dconf = in_dconf;
            rewrite_server_conf *sconf =
                ap_get_module_config(cmd->server->module_config,
                                     &rewrite_module);
    
            sconf->options |= options;
            sconf->options_set = 1;
            dconf->options |= options;
            dconf->options_set = 1;
        }
        /* directory command? set directory scope only */
        else {                  /* is per-directory command */
            rewrite_perdir_conf *dconf = in_dconf;
    
            dconf->options |= options;
            dconf->options_set = 1;
        }
    
        return NULL;
    }
    
    static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1,
                                      const char *a2, const char *a3)
    {
        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_pcalloc(cmd->pool, sizeof(rewritemap_entry));
    
        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) {
            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,
                                          &newmap->checkfile2);
            if (rv != APR_SUCCESS) {
                return apr_pstrcat(cmd->pool, "RewriteMap: dbm type ",
                                   newmap->dbmtype, " is invalid", NULL);
            }
        }
        else if ((strncasecmp(a2, "dbd:", 4) == 0)
                 || (strncasecmp(a2, "fastdbd:", 8) == 0)) {
            if (dbd_prepare == NULL) {
                return "RewriteMap types dbd and fastdbd require mod_dbd!";
            }
            if ((a2[0] == 'd') || (a2[0] == 'D')) {
                newmap->type = MAPTYPE_DBD;
                fname = a2+4;
            }
            else {
                newmap->type = MAPTYPE_DBD_CACHE;
                fname = a2+8;
                newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s",
                                                 (void *)cmd->server, a1);
            }
            newmap->dbdq = a1;
            dbd_prepare(cmd->server, fname, newmap->dbdq);
        }
        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->checkfile = newmap->argv[0];
            rewrite_lock_needed = 1;
    
            if (a3) {
                char *tok_cntx;
                newmap->user = apr_strtok(apr_pstrdup(cmd->pool, a3), ":", &tok_cntx);
                newmap->group = apr_strtok(NULL, ":", &tok_cntx);
            }
        }
        else if (strncasecmp(a2, "int:", 4) == 0) {
            newmap->type      = MAPTYPE_INT;
            newmap->func      = (char *(*)(request_rec *,char *))
                                apr_hash_get(mapfunc_hash, a2+4, strlen(a2+4));
            if (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);
        }
    
        if (newmap->checkfile
            && (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_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;
        dconf->baseurl_set = 1;
    
        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 "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 if (   strcasecmp(key, "novary") == 0
                 || strcasecmp(key, "NV") == 0    ) {
            cfg->flags |= CONDFLAG_NOVARY;
        }
        else {
            return apr_pstrcat(p, "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 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
        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, &a2_end, &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 apr_pstrcat(cmd->pool, "RewriteCond: ", err, NULL);
            }
        }
    
        /* arg2: the pattern */
        newcond->pattern = a2;
        if (*a2 == '!') {
            newcond->flags |= CONDFLAG_NOTMATCH;
            ++a2;
        }
    
        /* determine the pattern type */
        newcond->ptype = CONDPAT_REGEX;
        if (strcasecmp(a1, "expr") == 0) {
            newcond->ptype = CONDPAT_AP_EXPR;
        }
        else if (*a2 && a2[1]) {
            if (*a2 == '-') {
                if (!a2[2]) {
                    switch (a2[1]) {
                    case 'f': newcond->ptype = CONDPAT_FILE_EXISTS; break;
                    case 's': newcond->ptype = CONDPAT_FILE_SIZE;   break;
                    case 'd': newcond->ptype = CONDPAT_FILE_DIR;    break;
                    case 'x': newcond->ptype = CONDPAT_FILE_XBIT;   break;
                    case 'h': newcond->ptype = CONDPAT_FILE_LINK;   break;
                    case 'L': newcond->ptype = CONDPAT_FILE_LINK;   break;
                    case 'l': newcond->ptype = CONDPAT_FILE_LINK;   break;
                    case 'U': newcond->ptype = CONDPAT_LU_URL;      break;
                    case 'F': newcond->ptype = CONDPAT_LU_FILE;     break;
                    }
                }
                else if (a2[3]) {
                    switch (a2[1]) {
                    case 'l':
                        if (a2[2] == 't') {
                            a2 += 3;
                            newcond->ptype = CONDPAT_INT_LT;
                        }
                        else if (a2[2] == 'e') {
                            a2 += 3;
                            newcond->ptype = CONDPAT_INT_LE;
                        }
                        break;
    
                    case 'g':
                        if (a2[2] == 't') {
                            a2 += 3;
                            newcond->ptype = CONDPAT_INT_GT;
                        }
                        else if (a2[2] == 'e') {
                            a2 += 3;
                            newcond->ptype = CONDPAT_INT_GE;
                        }
                        break;
    
                    case 'e':
                        if (a2[2] == 'q') {
                            a2 += 3;
                            newcond->ptype = CONDPAT_INT_EQ;
                        }
                        break;
    
                    case 'n':
                        if (a2[2] == 'e') {
                            /* Inversion, ensure !-ne == -eq */
                            a2 += 3;
                            newcond->ptype = CONDPAT_INT_EQ;
                            newcond->flags ^= CONDFLAG_NOTMATCH;
                        }
                        break;
                    }
                }
            }
            else {
                switch (*a2) {
                case '>': if (*++a2 == '=')
                              ++a2, newcond->ptype = CONDPAT_STR_GE;
                          else
                              newcond->ptype = CONDPAT_STR_GT;
                          break;
    
                case '<': if (*++a2 == '=')
                              ++a2, newcond->ptype = CONDPAT_STR_LE;
                          else
                              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 != CONDPAT_REGEX) &&
            (newcond->ptype < CONDPAT_STR_LT || newcond->ptype > CONDPAT_STR_GE) &&
            (newcond->flags & CONDFLAG_NOCASE)) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00665)
                         "RewriteCond: NoCase option for non-regex pattern '%s' "
                         "is not supported and will be ignored. (%s:%d)", a2,
                         cmd->directive->filename, cmd->directive->line_num);
            newcond->flags &= ~CONDFLAG_NOCASE;
        }
    
        newcond->pskip = a2 - newcond->pattern;
        newcond->pattern += newcond->pskip;
    
        if (newcond->ptype == CONDPAT_REGEX) {
            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;
        }
        else if (newcond->ptype == CONDPAT_AP_EXPR) {
            unsigned int flags = newcond->flags & CONDFLAG_NOVARY ?
                                 AP_EXPR_FLAG_DONT_VARY : 0;
            newcond->expr = ap_expr_parse_cmd(cmd, a2, flags, &err, NULL);
            if (err)
                return apr_psprintf(cmd->pool, "RewriteCond: cannot compile "
                                    "expression \"%s\": %s", a2, err);
        }
    
        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 'b':
        case 'B':
            if (!*key || !strcasecmp(key, "ackrefescaping")) {
                cfg->flags |= RULEFLAG_ESCAPEBACKREF;
                if (val && *val) {
                    cfg->escapes = val;
                }
            }
            else if (!strcasecmp(key, "NE")) {
                if (val && *val) {
                    cfg->noescapes = val;
                }
                else {
                    return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
                }
            }
            else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) { 
                cfg->flags |= RULEFLAG_ESCAPENOPLUS;
            }
            else if (!strcasecmp(key, "CTLS")) {
                cfg->flags |= RULEFLAG_ESCAPECTLS|RULEFLAG_ESCAPEBACKREF;
            }
            else {
                ++error;
            }
            break;
        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 'd':
        case 'D':
            if (!*key || !strcasecmp(key, "PI") || !strcasecmp(key,"iscardpath")) {
                cfg->flags |= (RULEFLAG_DISCARDPATHINFO);
            }
            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 if (!strcasecmp(key, "nd")) {                /* end */
                cfg->flags |= RULEFLAG_END;
            }
            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;
                if (val && *val) { 
                    cfg->maxrounds = atoi(val);
                }
    
            }
            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 if ( !strcasecmp(key, "SD")
                    || !strcasecmp(key, "sdiscard") ) {       /* qsdiscard */
                cfg->flags |= RULEFLAG_QSDISCARD;
            } else if ( !strcasecmp(key, "SL")
                    || !strcasecmp(key, "slast") ) {          /* qslast */
                cfg->flags |= RULEFLAG_QSLAST;
            }
            else {
                ++error;
            }
            break;
    
        case 'r':
        case 'R':
            if (!*key || !strcasecmp(key, "edirect")) {        /* redirect */
                int status = 0;
    
                cfg->flags |= RULEFLAG_FORCEREDIRECT;
                if (*val) {
                    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, "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;
        case 'u':
        case 'U':
            if (!strcasecmp(key, "nsafePrefixStat")){
                cfg->flags |= (RULEFLAG_UNSAFE_PREFIX_STAT);
            }
            else if(!strcasecmp(key, "nsafeAllow3F")) {
                cfg->flags |= RULEFLAG_UNSAFE_ALLOW3F;
            }
            else if(!strcasecmp(key, "NC")) {
                cfg->flags |= RULEFLAG_UNC;
            }
            else {
                ++error;
            }
            break;
        default:
            ++error;
            break;
        }
    
        if (error) {
            return apr_pstrcat(p, "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 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
        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, &a2_end, &a3)) {
            return apr_pstrcat(cmd->pool, "RewriteRule: bad argument line '", str,
                               "'", NULL);
        }
    
        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;
        newrule->maxrounds = REWRITE_MAX_ROUNDS;
        newrule->escapes = newrule->noescapes = NULL;
    
        /* arg3: optional flags field */
        if (a3 != NULL) {
            if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
                                          cmd_rewriterule_setflag)) != NULL) {
                return apr_pstrcat(cmd->pool, "RewriteRule: ", err, NULL);
            }
        }
    
        /* 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;
        }
    
        if (*(a2_end-1) == '?') {
            /* a literal ? at the end of the unsubstituted rewrite rule */
            if (newrule->flags & RULEFLAG_QSAPPEND) {
               /* with QSA, splitout_queryargs will safely handle it if RULEFLAG_QSLAST is set */
               newrule->flags |= RULEFLAG_QSLAST;
            }
            else {
                /* avoid getting a query string via inadvertent capture */
                newrule->flags |= RULEFLAG_QSNONE;
                /* trailing ? has done its job, but splitout_queryargs will not chop it off */
                *(a2_end-1) = '\0';
           }
        }
        else if (newrule->flags & RULEFLAG_QSDISCARD) {
            if (NULL == ap_strchr(newrule->output, '?')) {
                newrule->flags |= RULEFLAG_QSNONE;
            }
        }
    
        /* 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 cond_return_type apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
    {
        char *input = NULL;
        apr_finfo_t sb;
        request_rec *rsub, *r = ctx->r;
        ap_regmatch_t regmatch[AP_MAX_REG_MATCH];
        int rc = COND_RC_NOMATCH;
        int basis;
    
        if (p->ptype != CONDPAT_AP_EXPR)
            input = do_expand(p->input, ctx, NULL, NULL);
    
        switch (p->ptype) {
        case CONDPAT_FILE_EXISTS:
            if (APR_SUCCESS != ap_stat_check(input, r->pool)) {
                r->status = HTTP_FORBIDDEN;
                rewritelog(r, 4, ctx->perdir, "RewriteCond: refusing to stat input='%s'", input);
                return COND_RC_STATUS_SET;
            }
            if (   apr_stat(&sb, input, APR_FINFO_MIN, r->pool) == APR_SUCCESS
                && sb.filetype == APR_REG) {
                rc = COND_RC_MATCH;
            }
            break;
    
        case CONDPAT_FILE_SIZE:
            if (APR_SUCCESS != ap_stat_check(input, r->pool)) {
                r->status = HTTP_FORBIDDEN;
                rewritelog(r, 4, ctx->perdir, "RewriteCond: refusing to stat input='%s'", input);
                return COND_RC_STATUS_SET;
            }
            if (   apr_stat(&sb, input, APR_FINFO_MIN, r->pool) == APR_SUCCESS
                && sb.filetype == APR_REG && sb.size > 0) {
                rc = COND_RC_MATCH;
            }
            break;
    
        case CONDPAT_FILE_LINK:
            if (APR_SUCCESS != ap_stat_check(input, r->pool)) {
                r->status = HTTP_FORBIDDEN;
                rewritelog(r, 4, ctx->perdir, "RewriteCond: refusing to stat input='%s'", input);
                return COND_RC_STATUS_SET;
            }
    #if !defined(OS2)
            if (   apr_stat(&sb, input, APR_FINFO_MIN | APR_FINFO_LINK,
                            r->pool) == APR_SUCCESS
                && sb.filetype == APR_LNK) {
                rc = COND_RC_MATCH;
            }
    #endif
            break;
    
        case CONDPAT_FILE_DIR:
            if (APR_SUCCESS != ap_stat_check(input, r->pool)) {
                r->status = HTTP_FORBIDDEN;
                rewritelog(r, 4, ctx->perdir, "RewriteCond: refusing to stat input='%s'", input);
                return COND_RC_STATUS_SET;
            }
            if (   apr_stat(&sb, input, APR_FINFO_MIN, r->pool) == APR_SUCCESS
                && sb.filetype == APR_DIR) {
                rc = COND_RC_MATCH;
            }
            break;
    
        case CONDPAT_FILE_XBIT:
            if (APR_SUCCESS != ap_stat_check(input, r->pool)) {
                r->status = HTTP_FORBIDDEN;
                rewritelog(r, 4, ctx->perdir, "RewriteCond: refusing to stat input='%s'", input);
                return COND_RC_STATUS_SET;
            }
            if (   apr_stat(&sb, input, APR_FINFO_PROT, r->pool) == APR_SUCCESS
                && (sb.protection & (APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE))) {
                rc = COND_RC_MATCH;
            }
            break;
    
        case CONDPAT_LU_URL:
            if (*input && subreq_ok(r)) {
                rsub = ap_sub_req_lookup_uri(input, r, NULL);
                if (rsub->status < 400) {
                    rc = COND_RC_MATCH;
                }
                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)) {
                if (APR_SUCCESS != ap_stat_check(input, r->pool)) {
                    r->status = HTTP_FORBIDDEN;
                    rewritelog(r, 4, ctx->perdir, "RewriteCond: refusing to stat input='%s'", input);
                    return COND_RC_STATUS_SET;
                }
                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 = COND_RC_MATCH;
                }
                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_GE:
            basis = 0;
            goto test_str_g;
        case CONDPAT_STR_GT:
            basis = 1;
    test_str_g:
            if (p->flags & CONDFLAG_NOCASE) {
                rc = (strcasecmp(input, p->pattern) >= basis) ? COND_RC_MATCH : COND_RC_NOMATCH;
            }
            else {
                rc = (compare_lexicography(input, p->pattern) >= basis) ? COND_RC_MATCH : COND_RC_NOMATCH;
            }
            break;
    
        case CONDPAT_STR_LE:
            basis = 0;
            goto test_str_l;
        case CONDPAT_STR_LT:
            basis = -1;
    test_str_l:
            if (p->flags & CONDFLAG_NOCASE) {
                rc = (strcasecmp(input, p->pattern) <= basis) ? COND_RC_MATCH : COND_RC_NOMATCH;
            }
            else {
                rc = (compare_lexicography(input, p->pattern) <= basis) ? COND_RC_MATCH : COND_RC_NOMATCH;
            }
            break;
    
        case CONDPAT_STR_EQ:
            /* Note: the only type where the operator is dropped from p->pattern */
            if (p->flags & CONDFLAG_NOCASE) {
                rc = !strcasecmp(input, p->pattern);
            }
            else {
                rc = !strcmp(input, p->pattern);
            }
            break;
    
        case CONDPAT_INT_GE: rc = (atoi(input) >= atoi(p->pattern)); break;
        case CONDPAT_INT_GT: rc = (atoi(input) > atoi(p->pattern));  break;
    
        case CONDPAT_INT_LE: rc = (atoi(input) <= atoi(p->pattern)); break;
        case CONDPAT_INT_LT: rc = (atoi(input) < atoi(p->pattern));  break;
    
        case CONDPAT_INT_EQ: rc = (atoi(input) == atoi(p->pattern)); break;
    
        case CONDPAT_AP_EXPR:
            {
                const char *err, *source;
                rc = ap_expr_exec_re(r, p->expr, AP_MAX_REG_MATCH, regmatch,
                                     &source, &err);
                if (rc < 0 || err) {
                    rewritelog(r, 1, ctx->perdir,
                                "RewriteCond: expr='%s' evaluation failed: %s",
                                p->pattern - p->pskip, err);
                    rc = COND_RC_NOMATCH;
                }
                else {
                    rc = COND_RC_MATCH;
                }
                /* update briRC backref info */
                if (rc && !(p->flags & CONDFLAG_NOTMATCH)) {
                    ctx->briRC.source = source;
                    memcpy(ctx->briRC.regmatch, regmatch, sizeof(regmatch));
                }
            }
            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;
                memcpy(ctx->briRC.regmatch, regmatch, sizeof(regmatch));
            }
            break;
        }
    
        if (p->flags & CONDFLAG_NOTMATCH && rc <= COND_RC_MATCH) {
            rc = !rc;
        }
    
        rewritelog(r, 4, ctx->perdir, "RewriteCond: input='%s' pattern='%s'%s "
                   "=> %s", input, p->pattern - p->pskip,
                   (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, p, NULL);
    
            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, p, NULL);
    
            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 rule_return_type 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;
        int prefix_added = 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 underlying 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 RULE_RC_NOMATCH;
        }
    
        /* 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);
            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 unnecessary 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);
    
            /* Error while evaluating cond, r->status set */
            if (COND_RC_STATUS_SET == rc) {
                return RULE_RC_STATUS_SET;
            }
    
            /*
             * Reset vary_this if the novary flag is set for this condition.
             */
            if (c->flags & CONDFLAG_NOVARY) {
                ctx->vary_this = NULL;
            }
            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];
                    }
                }
            }
            else if (!rc) {
                return RULE_RC_NOMATCH;
            }
    
            /* 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)) {
            int unsafe_qmark = -1;
    
            if (p->flags & RULEFLAG_UNSAFE_ALLOW3F) {
                newuri = do_expand(p->output, ctx, p, NULL);
            }
            else {
                newuri = do_expand(p->output, ctx, p, &unsafe_qmark);
            }
            rewritelog(r, 2, ctx->perdir, "rewrite '%s' -> '%s'", ctx->uri,
                       newuri);
    
            if (unsafe_qmark > 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10508)
                        "Unsafe URL with %%3f URL rewritten without "
                        "UnsafeAllow3F");
                r->status = HTTP_FORBIDDEN;
                return RULE_RC_STATUS_SET;
            }
        }
    
        /* expand [E=var:val] and [CO=<cookie>] */
        do_expand_env(p->env, ctx);
        do_expand_cookie(p->cookie, ctx);
    
        /* non-substitution rules ('RewriteRule <pat> -') 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 RULE_RC_NOSUB;
        }
    
        /* 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 (!is_proxyreq
            && !is_absolute_path(newuri)
            && !AP_IS_SLASH(*newuri)
            && !is_absolute_uri(newuri, NULL)) {
            if (ctx->perdir) {
                rewritelog(r, 3, ctx->perdir, "add per-dir prefix: %s -> %s%s",
                           newuri, ctx->perdir, newuri);
    
                newuri = apr_pstrcat(r->pool, ctx->perdir, newuri, NULL);
                prefix_added = 1;
            }
            else if (!(p->flags & (RULEFLAG_PROXY | RULEFLAG_FORCEREDIRECT))) {
                /* Not an absolute URI-path and the scheme (if any) is unknown,
                 * and it won't be passed to fully_qualify_uri() below either,
                 * so add an implicit '/' prefix. This avoids potentially a common
                 * rule like "RewriteRule ^/some/path(.*) $1" that is given a path
                 * like "/some/pathscheme:..." to produce the fully qualified URL
                 * "scheme:..." which could be misinterpreted later.
                 */
                rewritelog(r, 3, ctx->perdir, "add root prefix: %s -> /%s",
                           newuri, newuri);
    
                newuri = apr_pstrcat(r->pool, "/", newuri, NULL);
                prefix_added = 1;
            }
        }
    
        /* Now adjust API's knowledge about r->filename and r->args */
        r->filename = newuri;
    
        if (ctx->perdir && (p->flags & RULEFLAG_DISCARDPATHINFO)) {
            r->path_info = NULL;
        }
    
        splitout_queryargs(r, p->flags);
    
        /* 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 RULE_RC_MATCH;
        }
    
        /* 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 RULE_RC_MATCH;
        }
    
        /* Special Rewriting Feature: Self-Reduction
         * We reduce the URL by stripping a possible
         * http[s]://<ourhost>[:<port>] 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 .. <scheme>://...') then
         * directly force an external HTTP redirect.
         */
        if (is_absolute_uri(r->filename, NULL)) {
            rewritelog(r, 2, ctx->perdir, "implicitly forcing redirect (rc=%d "
                       "with %s", p->forced_responsecode, r->filename);
    
            r->status = p->forced_responsecode;
            return RULE_RC_MATCH;
        }
    
        if (!((p->flags & RULEFLAG_UNC) || prefix_added)) {
            /* merge leading slashes, unless they were literals in the sub */
            if (!AP_IS_SLASH(p->output[0]) || !AP_IS_SLASH(p->output[1])) {
                while (AP_IS_SLASH(r->filename[0]) &&
                       AP_IS_SLASH(r->filename[1])) {
                    r->filename++;
                }
            }
        }
    
        /* 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 RULE_RC_MATCH;
    }
    
    /*
     * 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 **lastsub)
    {
        rewriterule_entry *entries;
        rewriterule_entry *p;
        int i;
        int changed;
        rule_return_type rc;
        int s;
        rewrite_ctx *ctx;
        int round = 1;
    
        ctx = apr_palloc(r->pool, sizeof(*ctx));
        ctx->perdir = perdir;
        ctx->r = r;
        *lastsub = NULL;
    
        /*
         *  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 != RULE_RC_NOMATCH) {
    
                if (!(p->flags & RULEFLAG_NOSUB)) {
                    rewritelog(r, 2, perdir, "setting lastsub to rule with output %s", p->output);
                    *lastsub = p;
                }
    
                /* Catch looping rules with pathinfo growing unbounded */
                if ( strlen( r->filename ) > 2*r->server->limit_req_line ) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                  "RewriteRule '%s' and URI '%s' "
                                  "exceeded maximum length (%d)", 
                                  p->pattern, r->uri, 2*r->server->limit_req_line );
                    r->status = HTTP_INTERNAL_SERVER_ERROR;
                    return ACTION_STATUS;
                }
    
                /* 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);
                }
    
    
                /* Error while evaluating rule, r->status set */
                if (RULE_RC_STATUS_SET == rc) {
                    return ACTION_STATUS_SET;
                }
    
                /*
                 * 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 != RULE_RC_NOSUB) {
                    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;
                }
    
                if (p->flags & RULEFLAG_END) {
                    rewritelog(r, 8, perdir, "Rule has END flag, no further rewriting for this request");
                    apr_pool_userdata_set("1", really_last_key, apr_pool_cleanup_null, r->pool);
                    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) {
                    if (++round >= p->maxrounds) { 
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02596)
                                      "RewriteRule '%s' and URI '%s' exceeded "
                                      "maximum number of rounds (%d) via the [N] flag", 
                                      p->pattern, r->uri, p->maxrounds);
    
                        r->status = HTTP_INTERNAL_SERVER_ERROR;
                        return ACTION_STATUS; 
                    }
                    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++;
                        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;
    
        rewrite_lock_needed = 0; 
        ap_mutex_register(pconf, rewritemap_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
    
        /* register int: rewritemap handlers */
        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);
        }
        dbd_acquire = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
        dbd_prepare = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
        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;
    
        /* check if proxy module is available */
        proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);
    
        if (rewrite_lock_needed) {
            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);
        }
    
        /* if we are not doing the initial config, step through the servers and
         * open the RewriteMap prg:xxx programs,
         */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_CONFIG) {
            for (; s; s = s->next) {
                if (run_rewritemap_programs(s, p) != APR_SUCCESS) {
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
        }
    
        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 (rewrite_mapr_lock_acquire) {
            rv = apr_global_mutex_child_init(&rewrite_mapr_lock_acquire,
                     apr_global_mutex_lockfile(rewrite_mapr_lock_acquire), p);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00666)
                             "mod_rewrite: could not init rewrite_mapr_lock_acquire"
                             " in child");
            }
        }
    
        /* create the lookup cache */
        if (!init_cache(p)) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00667)
                         "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_perdir_conf *dconf;
        rewrite_server_conf *conf;
        const char *saved_rulestatus;
        const char *var;
        const char *thisserver;
        char *thisport;
        const char *thisurl;
        unsigned int port;
        int rulestatus;
        void *skipdata;
        const char *oargs;
        rewriterule_entry *lastsub = NULL;
    
        /*
         *  retrieve the config structures
         */
        conf = ap_get_module_config(r->server->module_config, &rewrite_module);
    
        dconf = (rewrite_perdir_conf *)ap_get_module_config(r->per_dir_config,
                                                            &rewrite_module);
    
        /*
         *  only do something under runtime if the engine is really enabled,
         *  else return immediately!
         */
        if (!dconf || dconf->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;
        }
    
        /* END flag was used as a RewriteRule flag on this request */
        apr_pool_userdata_get(&skipdata, really_last_key, r->pool);
        if (skipdata != NULL) {
            rewritelog(r, 8, NULL, "Declining, no further rewriting due to END flag");
            return DECLINED;
        }
    
        /* Unless the anyuri option is set, ensure that the input to the
         * first rule really is a URL-path, avoiding security issues with
         * poorly configured rules.  See CVE-2011-3368, CVE-2011-4317. */
        if ((dconf->options & OPTION_ANYURI) == 0
            && ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0')
                || !r->uri || r->uri[0] != '/')) {
            rewritelog(r, 8, NULL, "Declining, request-URI '%s' is not a URL-path. "
                        "Consult the manual entry for the RewriteOptions directive "
                        "for options and caveats about matching other strings.",
                       r->uri);
            return DECLINED;
        }
    
        /*
         *  remember the original query string for later check, since we don't
         *  want to apply URL-escaping when no substitution has changed it.
         */
        oargs = r->args;
    
        /*
         *  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_for_url(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, &lastsub);
            apr_table_setn(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) {
            apr_size_t flen =  r->filename ? strlen(r->filename) : 0;
            unsigned skip_absolute = flen ? is_absolute_uri(r->filename, NULL) : 0;
            int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
            int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
    
            if (r->args
                    && !will_escape
                    && *(ap_scan_vchar_obstext(r->args))) {
                /*
                 * We have a raw control character or a ' ' in r->args.
                 * Correct encoding was missed.
                 * Correct encoding was missed and we're not going to escape
                 * it before returning.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410)
                              "Rewritten query string contains control "
                              "characters or spaces");
                return HTTP_FORBIDDEN;
            }
    
            if (ACTION_STATUS == rulestatus) {
                int n = r->status;
    
                r->status = HTTP_OK;
                return n;
            }
            else if (ACTION_STATUS_SET == rulestatus) {
                return r->status;
            }
    
            if (to_proxyreq) {
                /* 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, APLOGNO(00669)
                                  "attempt to make remote request from mod_rewrite "
                                  "without proxy enabled: %s", r->filename);
                    return HTTP_FORBIDDEN;
                }
    
                if (rulestatus == ACTION_NOESCAPE) {
                    apr_table_setn(r->notes, "proxy-nocanon", "1");
                }
    
                /* 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->proxyreq == PROXYREQ_PROXY)
                        || apr_table_get(r->notes, "proxy-nocanon"))) {
                    /* 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_absolute > 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_absolute);
                }
    
                /* append the QUERY_STRING part */
                if (r->args) {
                    char *escaped_args = NULL;
                    int noescape = (rulestatus == ACTION_NOESCAPE ||
                                    (oargs && !strcmp(r->args, oargs)));
    
                    r->filename = apr_pstrcat(r->pool, r->filename, "?",
                                              noescape
                                                ? r->args
                                                : (escaped_args =
                                                   ap_escape_uri(r->pool, r->args)),
                                              NULL);
    
                    rewritelog(r, 1, NULL, "%s %s to query string for redirect %s",
                               noescape ? "copying" : "escaping",
                               r->args ,
                               noescape ? "" : escaped_args);
                }
    
                /* 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 */
                const char *uri_reduced = NULL;
    
                /* 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;
                }
    
                /* We have r->filename as a path in a server-context rewrite without
                 * the PT flag. The historical behavior is to treat it as a verbatim
                 * filesystem path iff the first component of the path exists and is
                 * readable by httpd. Otherwise, it is interpreted as DocumentRoot
                 * relative.
                 *
                 * NOTICE:
                 * We cannot leave out the prefix_stat because
                 * - If we always prefix with document_root
                 *   then no absolute path can could ever be used in
                 *   a substitution. e.g. emulating an Alias.
                 * - If we never 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.
                 *   - Later addition: This part is questionable.
                 *     If we had never prefixed, users would just 
                 *     need %{DOCUMENT_ROOT} in substitutions or the 
                 *     [PT] flag.
                 *
                 * BUT:
                 * Under real Unix systems this is no perf problem,
                 * because we only do stat() on the first directory
                 * and this gets cached by the kernel for along time!
                 */
    
                if(!(conf->options & OPTION_LEGACY_PREFIX_DOCROOT)) {
                    uri_reduced = apr_table_get(r->notes, "mod_rewrite_uri_reduced");
                }
    
                if (!prefix_stat(r, r->filename, r->pool,
                                 conf->options & OPTION_UNSAFE_PREFIX_STAT ? NULL : lastsub)
                    || uri_reduced != NULL) {
                    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, *oargs;
        int is_proxyreq;
        void *skipdata;
        rewriterule_entry *lastsub;
    
        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;
        }
    
        /*
         * only do something under runtime if the engine is really enabled,
         * for this directory, else return immediately!
         */
        if (dconf->state == ENGINE_DISABLED) {
            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, allowing mod_dir to direct the client to the
         *  canonical URL. This can be controlled with the AllowNoSlash option.
         */
        if (!is_proxyreq && !(dconf->options & OPTION_NOSLASH)) {
            l = strlen(dconf->directory) - 1;
            if (r->filename && strlen(r->filename) == l &&
                (dconf->directory)[l] == '/' &&
                !strncmp(r->filename, dconf->directory, l)) {
                return DECLINED;
            }
        }
    
        /* END flag was used as a RewriteRule flag on this request */
        apr_pool_userdata_get(&skipdata, really_last_key, r->pool);
        if (skipdata != NULL) {
            rewritelog(r, 8, dconf->directory, "Declining, no further rewriting due to END flag");
            return DECLINED;
        }
    
        /*
         *  Do the Options check after engine check, so
         *  the user is able to explicitly 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, APLOGNO(00670)
                         "Options FollowSymLinks and SymLinksIfOwnerMatch are both off, "
                         "so the RewriteRule directive is also forbidden "
                         "due to its similar ability to circumvent directory restrictions : "
                         "%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 initial one.
         *  also, we'll restore original r->filename if we decline this
         *  request
         */
        ofilename = r->filename;
        oargs = r->args;
    
        if (r->filename == NULL) {
            r->filename = apr_pstrdup(r->pool, r->uri);
            rewritelog(r, 2, dconf->directory, "init rewrite engine with"
                       " requested uri %s", r->filename);
        }
    
        /*
         *  now apply the rules ...
         */
        rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory, &lastsub);
        if (rulestatus) {
            unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
            int to_proxyreq = 0;
            int will_escape = 0;
    
            l = strlen(r->filename);
            to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0;
            will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
    
            if (r->args
                   && !will_escape
                   &&  *(ap_scan_vchar_obstext(r->args))) {
                /*
                 * We have a raw control character or a ' ' in r->args.
                 * Correct encoding was missed.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10411)
                              "Rewritten query string contains control "
                              "characters or spaces");
                return HTTP_FORBIDDEN;
            }
    
            if (ACTION_STATUS == rulestatus) {
                int n = r->status;
    
                r->status = HTTP_OK;
                return n;
            }
            else if (ACTION_STATUS_SET == rulestatus) {
                return r->status;
            }
    
            if (to_proxyreq) {
                /* it should 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, APLOGNO(10160)
                                  "attempt to make remote request from mod_rewrite "
                                  "without proxy enabled: %s", r->filename);
                    return HTTP_FORBIDDEN;
                }
    
                if (rulestatus == ACTION_NOESCAPE) {
                    apr_table_setn(r->notes, "proxy-nocanon", "1");
                }
    
                /* make sure the QUERY_STRING gets incorporated in the case
                 * [NE] was specified on the Proxy rule. We are preventing
                 * mod_proxy canon handler from incorporating r->args as well
                 * as escaping the URL.
                 * (r->path_info was already appended by the
                 * rewriting engine because of the per-dir context!)
                 */
                if ((r->args != NULL) && apr_table_get(r->notes, "proxy-nocanon")) {
                    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_absolute > 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_absolute;
    
                    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_absolute);
                }
    
                /* append the QUERY_STRING part */
                if (r->args) {
                    char *escaped_args = NULL;
                    int noescape = (rulestatus == ACTION_NOESCAPE ||
                                    (oargs && !strcmp(r->args, oargs)));
    
                    r->filename = apr_pstrcat(r->pool, r->filename, "?",
                                              noescape
                                                ? r->args
                                                : (escaped_args = ap_escape_uri(r->pool, r->args)),
                                              NULL);
    
                    rewritelog(r, 1, dconf->directory, "%s %s to query string for redirect %s",
                               noescape ? "copying" : "escaping",
                               r->args ,
                               noescape ? "" : escaped_args);
                }
    
                /* 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 {
                const char *tmpfilename = NULL;
                /* 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;
                }
    
                tmpfilename = r->filename;
    
                /* 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);
                        }
                    }
                }
    
                /* No base URL, or r->filename wasn't still under dconf->directory
                 * or, r->filename wasn't still under the document root. 
                 * If there's a context document root AND a context prefix, and 
                 * the context document root is a prefix of r->filename, replace.
                 * This allows a relative substitution on a path found by mod_userdir 
                 * or mod_alias without baking in a RewriteBase.
                 */
                if (tmpfilename == r->filename && 
                    !(dconf->options & OPTION_IGNORE_CONTEXT_INFO)) { 
                    if ((ccp = ap_context_document_root(r)) != NULL) { 
                        const char *prefix = ap_context_prefix(r);
                        if (prefix != NULL) { 
                            rewritelog(r, 2, dconf->directory, "trying to replace "
                                        "context docroot %s with context prefix %s",
                                       ccp, prefix);
                            r->filename = subst_prefix_path(r, r->filename,
                                    ccp, prefix);
                        }
                    }
                }
    
                apr_table_setn(r->notes, "redirect-keeps-vary", "");
    
                /* 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 = REWRITE_REDIRECT_HANDLER_NAME;
                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_ex(r, t, 1);
        }
    
        /* 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, REWRITE_REDIRECT_HANDLER_NAME)) {
            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
     * |                                                       |
     * +-------------------------------------------------------+
     */
    
    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_TAKE23(   "RewriteMap",      cmd_rewritemap,      NULL, RSRC_CONF,
                         "a mapname and a filename and options"),
        { 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)
    {
        static const char * const aszModProxy[] = { "mod_proxy.c", NULL };
    
        /* make the hashtable before registering the function, so that
         * other modules are prevented from accessing uninitialized memory.
         */
        mapfunc_hash = apr_hash_make(p);
        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);
        
        /* allow to change the uri before mod_proxy takes over it */
        ap_hook_translate_name(hook_uri2file, NULL, aszModProxy, APR_HOOK_FIRST);
        /* fixup before mod_proxy so that a [P] URL gets fixed up there */
        ap_hook_fixups(hook_fixup, NULL, aszModProxy, APR_HOOK_FIRST);
        ap_hook_fixups(hook_mimetype, NULL, NULL, APR_HOOK_LAST);
    }
    
        /* the main config structure */
    AP_DECLARE_MODULE(rewrite) = {
       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*/
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_alias.c������������������������������������������������������������0000664�0001751�0001751�00000064436�14513220676�020060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "ap_expr.h"
    
    
    #define ALIAS_FLAG_DEFAULT -1
    #define ALIAS_FLAG_OFF 0
    #define ALIAS_FLAG_ON  1
    
    #define ALIAS_PRESERVE_PATH_DEFAULT 0
    
    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 {
        unsigned int alias_set:1;
        unsigned int redirect_set:1;
        apr_array_header_t *redirects;
        const ap_expr_info_t *alias;
        const char *alias_fake;
        char *handler;
        const ap_expr_info_t *redirect;
        int redirect_status;                /* 301, 302, 303, 410, etc */
        int allow_relative;                 /* skip ap_construct_url() */
        int alias_preserve_path;            /* map full path */
    } alias_dir_conf;
    
    module AP_MODULE_DECLARE_DATA alias_module;
    
    static char magic_error_value;
    #define PREGSUB_ERROR      (&magic_error_value)
    
    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));
        a->allow_relative = ALIAS_FLAG_DEFAULT;
        a->alias_preserve_path = ALIAS_FLAG_DEFAULT;
        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);
    
        a->alias = (overrides->alias_set == 0) ? base->alias : overrides->alias;
        a->alias_fake = (overrides->alias_set == 0) ? base->alias_fake : overrides->alias_fake;
        a->handler = (overrides->alias_set == 0) ? base->handler : overrides->handler;
        a->alias_set = overrides->alias_set || base->alias_set;
    
        a->redirect = (overrides->redirect_set == 0) ? base->redirect : overrides->redirect;
        a->redirect_status = (overrides->redirect_set == 0) ? base->redirect_status : overrides->redirect_status;
        a->redirect_set = overrides->redirect_set || base->redirect_set;
        a->allow_relative = (overrides->allow_relative != ALIAS_FLAG_DEFAULT)
                                      ? overrides->allow_relative 
                                      : base->allow_relative;
        a->alias_preserve_path = (overrides->alias_preserve_path != ALIAS_FLAG_DEFAULT)
                                      ? overrides->alias_preserve_path
                                      : base->alias_preserve_path;
    
        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 *fake, const char *real,
                                          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;
    
        /* XXX: real can NOT be relative to DocumentRoot here... compat bug. */
    
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
    
        if (err != NULL) {
            return err;
        }
    
        if (use_regex) {
            new->regexp = ap_pregcomp(cmd->pool, fake, AP_REG_EXTENDED);
            if (new->regexp == NULL)
                return "Regular expression could not be compiled.";
            new->real = real;
        }
        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 = real;
        }
        new->fake = fake;
        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 *alias = &entries[i];
    
                if (  (!alias->regexp &&  alias_matches(fake, alias->fake) > 0)
                    || (alias->regexp && !ap_regexec(alias->regexp, fake, 0, NULL, 0))) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00671)
                                 "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,
                                 alias->handler ? "Script" : "",
                                 alias->regexp ? "Match" : "");
    
                    break; /* one warning per alias should be sufficient */
                }
            }
        }
    
        return NULL;
    }
    
    static const char *add_alias(cmd_parms *cmd, void *dummy, const char *fake,
            const char *real)
    {
        if (real) {
    
            return add_alias_internal(cmd, dummy, fake, real, 0);
    
        }
        else {
            alias_dir_conf *dirconf = (alias_dir_conf *) dummy;
    
            const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES);
    
            if (err != NULL) {
                return err;
            }
    
            if (!cmd->path) {
                return "Alias must have two arguments when used globally";
            }
    
            dirconf->alias =
                    ap_expr_parse_cmd(cmd, fake, AP_EXPR_FLAG_STRING_RESULT,
                            &err, NULL);
            if (err) {
                return apr_pstrcat(cmd->temp_pool,
                        "Cannot parse alias expression '", fake, "': ", err,
                        NULL);
            }
    
            dirconf->alias_fake = cmd->path;
            dirconf->handler = cmd->info;
            dirconf->alias_set = 1;
    
            return NULL;
    
        }
    }
    
    static const char *add_alias_regex(cmd_parms *cmd, void *dummy,
                                       const char *fake, const char *real)
    {
        return add_alias_internal(cmd, dummy, fake, real, 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;
        int grokarg1 = 1;
        ap_regex_t *regex = NULL;
        const char *fake = arg2;
        const char *url = arg3;
    
        /*
         * Logic flow:
         *   Go ahead and try to grok the 1st arg, in case it is a
         *   Redirect status. Now if we have 3 args, we expect that
         *   we were able to understand that 1st argument (it's something
         *   we expected, so if not, then we bail
         */
        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 (!strcasecmp(arg1, "gone")) {
            status = HTTP_GONE;
            grokarg1 = -1;
        }
        else if (apr_isdigit(*arg1)) {
            status = atoi(arg1);
            if (!ap_is_HTTP_REDIRECT(status)) {
                grokarg1 = -1;
            }
        }
        else {
            grokarg1 = 0;
        }
    
        if (arg3 && !grokarg1)
            return "Redirect: invalid first argument (of three)";
    
        /*
         * if we have the 2nd arg and we understand the 1st one as a redirect
         * status (3xx, but not things like 404 /robots.txt), or if we have the
         * 1st arg but don't understand it, we use the expression syntax assuming
         * a path from the location.
         *
         * if we understand the first arg but have no second arg, we are dealing
         * with a status like "GONE" or a non-redirect status (e.g. 404, 503).
         */
        if (!cmd->path) {
            /* <Location> context only for now */
            ;
        }
        else if ((grokarg1 > 0 && arg2 && !arg3) || (!grokarg1 && !arg2)) {
            const char *expr_err = NULL;
    
            url = grokarg1 ? arg2 : arg1;
            dirconf->redirect =
                    ap_expr_parse_cmd(cmd, url, AP_EXPR_FLAG_STRING_RESULT,
                            &expr_err, NULL);
            if (expr_err) {
                return apr_pstrcat(cmd->temp_pool,
                        "Cannot parse redirect expression '", url, "': ", expr_err,
                        NULL);
            }
    
            dirconf->redirect_status = status;
            dirconf->redirect_set = 1;
    
            return NULL;
    
        }
        else if (grokarg1 < 0 && !arg2) {
    
            dirconf->redirect_status = status;
            dirconf->redirect_set = 1;
    
            return NULL;
    
        }
    
        /*
         * if we don't have the 3rd arg and we didn't understand the 1st
         * one, then assume URL-path URL. This also handles case, eg, GONE
         * we even though we don't have a 3rd arg, we did understand the 1st
         * one, so we don't want to re-arrange
         */
        if (!arg3 && !grokarg1) {
            fake = arg1;
            url = arg2;
        }
    
        if (use_regex) {
            regex = ap_pregcomp(cmd->pool, fake, AP_REG_EXTENDED);
            if (regex == NULL)
                return "Regular expression could not be compiled.";
        }
    
        if (ap_is_HTTP_REDIRECT(status)) {
            if (!url)
                return "URL to redirect to is missing";
            /* PR#35314: we can allow path components here;
             * they get correctly resolved to full URLs.
             */
            if (!use_regex && !ap_is_url(url) && (url[0] != '/'))
                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 = fake;
        new->real = url;
        new->regexp = regex;
        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 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(request_rec *r)
    {
        alias_dir_conf *dirconf =
                (alias_dir_conf *) ap_get_module_config(r->per_dir_config, &alias_module);
    
        if (dirconf->alias) {
            const char *err = NULL;
    
            char *found = apr_pstrdup(r->pool,
                    ap_expr_str_exec(r, dirconf->alias, &err));
            if (err) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02825)
                              "Can't evaluate alias expression: %s", err);
                return PREGSUB_ERROR;
            }
    
            if (dirconf->alias_fake && dirconf->alias_preserve_path == ALIAS_FLAG_ON) {
                int l;
    
                l = alias_matches(r->uri, dirconf->alias_fake);
    
                if (l > 0) {
                    ap_set_context_info(r, dirconf->alias_fake, found);
                    found = apr_pstrcat(r->pool, found, r->uri + l, NULL);
                }
            }
    
            if (dirconf->handler) { /* Set handler, and leave a note for mod_cgi */
                r->handler = dirconf->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.
             */
            found = ap_server_root_relative(r->pool, found);
            return found;
    
        }
    
        return NULL;
    }
    
    static char *try_redirect(request_rec *r, int *status)
    {
        alias_dir_conf *dirconf =
                (alias_dir_conf *) ap_get_module_config(r->per_dir_config, &alias_module);
    
        if (dirconf->redirect_set) {
            apr_uri_t uri;
            const char *err = NULL;
            char *found = "";
    
            if (dirconf->redirect) {
    
                found = apr_pstrdup(r->pool,
                        ap_expr_str_exec(r, dirconf->redirect, &err));
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02826)
                                  "Can't evaluate redirect expression: %s", err);
                    return PREGSUB_ERROR;
                }
    
                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);
                }
    
            }
    
            *status = dirconf->redirect_status;
            return found;
    
        }
    
        return NULL;
    }
    
    static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
                                int is_redir, 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 *alias = &entries[i];
            int l;
    
            if (alias->regexp) {
                if (!ap_regexec(alias->regexp, r->uri, AP_MAX_REG_MATCH, regm, 0)) {
                    if (alias->real) {
                        found = ap_pregsub(r->pool, alias->real, r->uri,
                                           AP_MAX_REG_MATCH, regm);
                        if (found) {
                           if (is_redir) {
                                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 {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00672)
                                          "Regex substitution in '%s' failed. "
                                          "Replacement too long?", alias->real);
                            return PREGSUB_ERROR;
                        }
                    }
                    else {
                        /* need something non-null */
                        found = "";
                    }
                }
            }
            else {
                l = alias_matches(r->uri, alias->fake);
    
                if (l > 0) {
                    ap_set_context_info(r, alias->fake, alias->real);
                    if (is_redir) {
                        char *escurl;
                        escurl = ap_os_escape_path(r->pool, r->uri + l, 1);
    
                        found = apr_pstrcat(r->pool, alias->real, escurl, NULL);
                    }
                    else
                        found = apr_pstrcat(r->pool, alias->real, r->uri + l, NULL);
                }
            }
    
            if (found) {
                if (alias->handler) {    /* Set handler, and leave a note for mod_cgi */
                    r->handler = alias->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 (!is_redir) {
                    found = ap_server_root_relative(r->pool, found);
                }
                if (found) {
                    *status = alias->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_redirect(r, &status)) != NULL
                || (ret = try_alias_list(r, serverconf->redirects, 1, &status))
                        != NULL) {
            if (ret == PREGSUB_ERROR)
                return HTTP_INTERNAL_SERVER_ERROR;
            if (ap_is_HTTP_REDIRECT(status)) {
                alias_dir_conf *dirconf = (alias_dir_conf *) 
                    ap_get_module_config(r->per_dir_config, &alias_module);
                if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') {
                    if (ret[0] == '/') {
                        char *orig_target = ret;
    
                        ret = ap_construct_url(r->pool, ret, r);
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00673)
                                      "incomplete redirection target of '%s' for "
                                      "URI '%s' modified to '%s'",
                                      orig_target, r->uri, ret);
                    }
                    if (!ap_is_url(ret)) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00674)
                                      "cannot redirect '%s' to '%s'; "
                                      "target is not a valid absoluteURI or abs_path",
                                      r->uri, ret);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                }
                /* 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;
        }
    
        if ((ret = try_alias(r)) != NULL
                || (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_redirect(r, &status)) != NULL
                || (ret = try_alias_list(r, dirconf->redirects, 1, &status))
                        != NULL) {
            if (ret == PREGSUB_ERROR)
                return HTTP_INTERNAL_SERVER_ERROR;
            if (ap_is_HTTP_REDIRECT(status)) {
                if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') {
                    if (ret[0] == '/') {
                        char *orig_target = ret;
    
                        ret = ap_construct_url(r->pool, ret, r);
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00675)
                                      "incomplete redirection target of '%s' for "
                                      "URI '%s' modified to '%s'",
                                      orig_target, r->uri, ret);
                    }
                    if (!ap_is_url(ret)) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00676)
                                      "cannot redirect '%s' to '%s'; "
                                      "target is not a valid absoluteURI or abs_path",
                                      r->uri, ret);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                }
                /* 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 const command_rec alias_cmds[] =
    {
        AP_INIT_TAKE12("Alias", add_alias, NULL, RSRC_CONF | ACCESS_CONF,
                      "a fakename and a realname, or a realname in a Location"),
        AP_INIT_TAKE12("ScriptAlias", add_alias, "cgi-script", RSRC_CONF | ACCESS_CONF,
                      "a fakename and a realname, or a realname in a Location"),
        AP_INIT_TAKE123("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"),
        AP_INIT_FLAG("RedirectRelative", ap_set_flag_slot,
                      (void*)APR_OFFSETOF(alias_dir_conf, allow_relative), OR_FILEINFO,
                      "Set to ON to allow relative redirect targets to be issued as-is"),
        AP_INIT_FLAG("AliasPreservePath", ap_set_flag_slot,
                      (void*)APR_OFFSETOF(alias_dir_conf, alias_preserve_path), OR_FILEINFO,
                      "Set to ON to map the full path after the fakename to the realname."),
    
        {NULL}
    };
    
    
    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);
    }
    
    AP_DECLARE_MODULE(alias) =
    {
        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 */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_vhost_alias.c������������������������������������������������������0000664�0001751�0001751�00000031673�14001631447�021272� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <fanf@demon.net> <dot@dotat.at>.
     *
     * 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 <jrg@blodwen.demon.co.uk>.
     */
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "ap_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 (ap_cstr_casecmp(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;
        const char *docroot;
    
        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;
        while (*map) {
            if (*map != '%') {
                /* normal characters */
                vhost_alias_checkspace(r, buf, &dest, 1);
                *dest++ = *map++;
                continue;
            }
            /* we are in a format specifier */
            ++map;
            /* %% -> % */
            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 */
            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);
            }
        }
        /* no double slashes */
        if (dest - buf > 0 && dest[-1] == '/') {
            --dest;
        }
        *dest = '\0';
    
        if (r->filename)
            docroot = apr_pstrcat(r->pool, r->filename, buf, NULL);
        else
            docroot = apr_pstrdup(r->pool, buf);
        r->filename = apr_pstrcat(r->pool, docroot, uri, NULL);
        ap_set_context_info(r, NULL, docroot);
        ap_set_document_root(r, docroot);
    }
    
    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);
            ap_set_context_info(r, "/cgi-bin", NULL);
        }
    
        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);
    }
    
    AP_DECLARE_MODULE(vhost_alias) =
    {
        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 */
    };
    
    ���������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_negotiation.c������������������������������������������������������0000664�0001751�0001751�00000331442�14636331332�021277� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 (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 (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, APLOGNO(00680)
                "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; 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 (!ap_cstr_casecmpn(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;
        apr_size_t bodylen;
        apr_off_t pos;
    
    
        /* 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
         */
        --*len; /* Reserve space for '\0' */
        if (apr_file_read(map, buffer, len) != APR_SUCCESS) {
            return -1;
        }
        buffer[*len] = '\0';
    
        endbody = ap_strstr(buffer, tag);
        if (!endbody) {
            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, APLOGNO(00681)
                          "Syntax error in type map, no ':' in %s for header %s",
                          r->filename, header);
            return NULL;
        }
    
        do {
            ++cp;
        } while (apr_isspace(*cp));
    
        if (!*cp) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00682)
                          "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, APLOGNO(00683)
                          "cannot access type map file: %s", rr->filename);
            if (APR_STATUS_IS_ENOTDIR(status) || APR_STATUS_IS_ENOENT(status)) {
                return HTTP_NOT_FOUND;
            }
            else {
                return 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)) {
                    apr_off_t clen;
    
                    body1 = ap_get_token(neg->pool, &body, 0);
                    if (!ap_parse_strict_length(&clen, body1)) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00684)
                                      "Parse error in type map, Content-Length: "
                                      "'%s' in %s is invalid.",
                                      body1, r->filename);
                        break;
                    }
                    mime_info.bytes = clen;
                    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, APLOGNO(00685)
                                      "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, APLOGNO(00686)
                        "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.
             */
            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) {
                /* XXX sub req not destroyed -- may be a bug/unintentional ? */
                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_ex(sub_req, CGI_MAGIC_TYPE, 1);
            }
    
            /*
             * 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;
                }
            }
    
            /*
             * 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, APLOGNO(00687)
                          "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 ((len == 1 && accept_type[0] == '*')
                || (len == 3 && !strncmp(accept_type, "*/*", 3))) {
            /* Anything matches star or star/star */
            if (avail->mime_stars < 1) {
                avail->mime_stars = 1;
            }
            return 1;
        }
        else if (len > 2 && accept_type[len - 2] == '/'
                         && accept_type[len - 1] == '*'
                         && !strncmp(accept_type, avail_type, len - 2)
                         && avail_type[len - 2] == '/') {
            /* Any subtype matches for type/star */
            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 (!ap_cstr_casecmpn(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;
            }
            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;
    
                    /* 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;
    
                /* 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;
                    }
                }
            }
        }
    }
    
    /* 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, APLOGNO(00688)
               "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, APLOGNO(00689)
               "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)
    {
        /* fast exit */
        if (   !lang
            || !variant->content_languages) {
            return 0;
        }
    
        if (ap_array_str_contains(variant->content_languages, lang)) {
            return 1;
        }
    
        return 0;
    }
    
    /* check for environment variables 'no-gzip' and
     * 'gzip-only-text/html' to get a behaviour similar
     * 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)) = ap_escape_path_segment(r->pool, 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_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<ul>\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)) = "<li><a href=\"";
            *((const char **) apr_array_push(arr)) = ap_escape_path_segment(r->pool, filename);
            *((const char **) apr_array_push(arr)) = "\">";
            *((const char **) apr_array_push(arr)) = ap_escape_html(r->pool, filename);
            *((const char **) apr_array_push(arr)) = "</a> ";
            *((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)) = "</li>\n";
        }
        *((const char **) apr_array_push(arr)) = "</ul>\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, r->output_filters);
            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 cacheable.  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",
                      ap_escape_path_segment(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 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, APLOGNO(00690)
                              "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: <now> 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 <now>, 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: <now> when it
         * forwards the response.
         *
         * XXX: TODO: Find out if the 1.1 spec requires proxies and
         * tunnels to add Expires: <now> 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: <now> is not added by proxies then we need to always
         * include Expires: <now> 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;
        const char *new_req;
    
        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);
             */
            ap_set_accept_ranges(r);
            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_ex(r, apr_pstrcat(r->pool,
                                                       best->mime_type,
                                                       "; charset=",
                                                       best->content_charset,
                                                       NULL), 1);
                }
                else {
                    ap_set_content_type_ex(r, apr_pstrdup(r->pool, best->mime_type), 1);
                }
            }
    
            /* 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);
    
            apr_brigade_insert_file(bb, map, best->body, best->bytes, r->pool);
    
            e = apr_bucket_eos_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, e);
    
            return ap_pass_brigade_fchk(r, bb, NULL);
        }
    
        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);
        if (r->args) {
            if (r->path_info) {
                new_req = apr_pstrcat(r->pool, udir, best->file_name,
                                      r->path_info, "?", r->args, NULL);
            }
            else {
                new_req = apr_pstrcat(r->pool, udir, best->file_name,
                                      "?", r->args, NULL);
            }
        }
        else {
            new_req = apr_pstrcat(r->pool, udir, best->file_name,
                                  r->path_info, NULL);
        }
        ap_internal_redirect(new_req, 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, r->output_filters);
            if (sub_req->status != HTTP_OK) {
                res = sub_req->status;
                ap_destroy_sub_req(sub_req);
                goto return_from_multi;
            }
        }
        if (sub_req->args == NULL) {
            sub_req->args = r->args;
        }
    
        /* 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 among 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);
    }
    
    AP_DECLARE_MODULE(negotiation) =
    {
        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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_speling.c����������������������������������������������������������0000664�0001751�0001751�00000045035�14124070165�020414� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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 <akosut@organic.com> 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.
     *
     * Sep-1999 Hugo Haas <hugo@w3.org>
     * o Added a CheckCaseOnly option to check only miscapitalized words.
     *
     * 08-Aug-1997 <Martin.Kraemer@Mch.SNI.De>
     * 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;
        int check_case_only;
        int check_basename_match;
    } 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;
        cfg->check_case_only = 0;
        cfg->check_basename_match = 1;
        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);
    }
    
    /*
     * 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", ap_set_flag_slot,
                      (void*)APR_OFFSETOF(spconfig, enabled), OR_OPTIONS,
                     "whether or not to fix miscapitalized/misspelled requests"),
        AP_INIT_FLAG("CheckCaseOnly", ap_set_flag_slot,
                      (void*)APR_OFFSETOF(spconfig, check_case_only), OR_OPTIONS,
                     "whether or not to fix only miscapitalized requests"),
        AP_INIT_FLAG("CheckBasenameMatch", ap_set_flag_slot,
                      (void*)APR_OFFSETOF(spconfig, check_basename_match), OR_OPTIONS,
                     "whether or not to fix files with the same base name"),
        { 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->finfo.filetype != APR_NOFILE) {
            return DECLINED;
        }
    
        /* Not a file request */
        if (r->proxyreq || !r->filename) {
            return DECLINED;
        }
    
        /* This is a sub request - don't mess with it */
        if (r->main) {
            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 ((cfg->check_case_only == 0)
                     && ((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).
             *
             * If you're using MultiViews, and have a file named foobar.html,
             * which you refer to as "foobar", and someone tried to access
             * "Foobar", without CheckBasenameMatch, mod_speling won't find it,
             * because it won't find anything matching that spelling.
             * With the extension-munging, it would locate "foobar.html".
             */
            else if (cfg->check_basename_match == 1) {
                /*
                 * 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;
                }
            }
        }
        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 ? APLOGNO(03224) "Fixed spelling: %s to %s from %s"
                                  : APLOGNO(03225) "Fixed spelling: %s to %s%s",
                              r->uri, nuri,
                              (ref ? 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;
                apr_pool_tag(sub_pool, "speling_sub");
    
                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 (<code>";
                *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, r->uri);
                *(const char **)apr_array_push(t) =
                               "</code>) could not be found on this server.\n"
                               "However, we found documents with names similar "
                               "to the one you requested.<p>"
                               "Available documents:\n<ul>\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) = "<li><a href=\"";
                    *(const char **)apr_array_push(t) = ap_escape_uri(sub_pool, vuri);
                    *(const char **)apr_array_push(t) = "\">";
                    *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, vuri);
                    *(const char **)apr_array_push(t) = "</a> (";
                    *(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) =
                                       "</ul>\nFurthermore, the following related "
                                       "documents were found:\n<ul>\n";
                    }
                }
                *(const char **)apr_array_push(t) = "</ul>\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 <tt>";
                    *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, ref);
                    *(const char **)apr_array_push(t) =
                                   "</tt> 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 ? APLOGNO(03226) "Spelling fix: %s: %d candidates from %s"
                                 : APLOGNO(03227) "Spelling fix: %s: %d candidates%s",
                             r->uri, candidates->nelts,
                             (ref ? 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);
    }
    
    AP_DECLARE_MODULE(speling) =
    {
        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 */
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_actions.mak��������������������������������������������������������0000664�0001751�0001751�00000023471�12701473373�020750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_actions.dsp
    !IF "$(CFG)" == ""
    CFG=mod_actions - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_actions - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_actions - Win32 Release" && "$(CFG)" != "mod_actions - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_actions - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_actions.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_actions.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_actions.obj"
    	-@erase "$(INTDIR)\mod_actions.res"
    	-@erase "$(INTDIR)\mod_actions_src.idb"
    	-@erase "$(INTDIR)\mod_actions_src.pdb"
    	-@erase "$(OUTDIR)\mod_actions.exp"
    	-@erase "$(OUTDIR)\mod_actions.lib"
    	-@erase "$(OUTDIR)\mod_actions.pdb"
    	-@erase "$(OUTDIR)\mod_actions.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_actions_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_actions.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_actions.so" /d LONG_NAME="actions_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_actions.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_actions.pdb" /debug /out:"$(OUTDIR)\mod_actions.so" /implib:"$(OUTDIR)\mod_actions.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_actions.obj" \
    	"$(INTDIR)\mod_actions.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_actions.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_actions.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_actions.so"
       if exist .\Release\mod_actions.so.manifest mt.exe -manifest .\Release\mod_actions.so.manifest -outputresource:.\Release\mod_actions.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_actions - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_actions.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_actions.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_actions.obj"
    	-@erase "$(INTDIR)\mod_actions.res"
    	-@erase "$(INTDIR)\mod_actions_src.idb"
    	-@erase "$(INTDIR)\mod_actions_src.pdb"
    	-@erase "$(OUTDIR)\mod_actions.exp"
    	-@erase "$(OUTDIR)\mod_actions.lib"
    	-@erase "$(OUTDIR)\mod_actions.pdb"
    	-@erase "$(OUTDIR)\mod_actions.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_actions_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_actions.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_actions.so" /d LONG_NAME="actions_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_actions.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_actions.pdb" /debug /out:"$(OUTDIR)\mod_actions.so" /implib:"$(OUTDIR)\mod_actions.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_actions.obj" \
    	"$(INTDIR)\mod_actions.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_actions.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_actions.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_actions.so"
       if exist .\Debug\mod_actions.so.manifest mt.exe -manifest .\Debug\mod_actions.so.manifest -outputresource:.\Debug\mod_actions.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_actions.dep")
    !INCLUDE "mod_actions.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_actions.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_actions - Win32 Release" || "$(CFG)" == "mod_actions - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_actions - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_actions - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_actions - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_actions - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_actions - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_actions - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_actions - Win32 Release"
    
    
    "$(INTDIR)\mod_actions.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_actions.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_actions.so" /d LONG_NAME="actions_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_actions - Win32 Debug"
    
    
    "$(INTDIR)\mod_actions.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_actions.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_actions.so" /d LONG_NAME="actions_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_actions.c
    
    "$(INTDIR)\mod_actions.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_negotiation.mak����������������������������������������������������0000664�0001751�0001751�00000024231�12701473373�021623� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_negotiation.dsp
    !IF "$(CFG)" == ""
    CFG=mod_negotiation - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_negotiation - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_negotiation - Win32 Release" && "$(CFG)" != "mod_negotiation - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_negotiation - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_negotiation.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_negotiation.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_negotiation.obj"
    	-@erase "$(INTDIR)\mod_negotiation.res"
    	-@erase "$(INTDIR)\mod_negotiation_src.idb"
    	-@erase "$(INTDIR)\mod_negotiation_src.pdb"
    	-@erase "$(OUTDIR)\mod_negotiation.exp"
    	-@erase "$(OUTDIR)\mod_negotiation.lib"
    	-@erase "$(OUTDIR)\mod_negotiation.pdb"
    	-@erase "$(OUTDIR)\mod_negotiation.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_negotiation_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_negotiation.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_negotiation.so" /d LONG_NAME="negotiation_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_negotiation.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_negotiation.pdb" /debug /out:"$(OUTDIR)\mod_negotiation.so" /implib:"$(OUTDIR)\mod_negotiation.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_negotiation.obj" \
    	"$(INTDIR)\mod_negotiation.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_negotiation.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_negotiation.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_negotiation.so"
       if exist .\Release\mod_negotiation.so.manifest mt.exe -manifest .\Release\mod_negotiation.so.manifest -outputresource:.\Release\mod_negotiation.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_negotiation - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_negotiation.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_negotiation.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_negotiation.obj"
    	-@erase "$(INTDIR)\mod_negotiation.res"
    	-@erase "$(INTDIR)\mod_negotiation_src.idb"
    	-@erase "$(INTDIR)\mod_negotiation_src.pdb"
    	-@erase "$(OUTDIR)\mod_negotiation.exp"
    	-@erase "$(OUTDIR)\mod_negotiation.lib"
    	-@erase "$(OUTDIR)\mod_negotiation.pdb"
    	-@erase "$(OUTDIR)\mod_negotiation.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_negotiation_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_negotiation.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_negotiation.so" /d LONG_NAME="negotiation_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_negotiation.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_negotiation.pdb" /debug /out:"$(OUTDIR)\mod_negotiation.so" /implib:"$(OUTDIR)\mod_negotiation.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_negotiation.obj" \
    	"$(INTDIR)\mod_negotiation.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_negotiation.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_negotiation.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_negotiation.so"
       if exist .\Debug\mod_negotiation.so.manifest mt.exe -manifest .\Debug\mod_negotiation.so.manifest -outputresource:.\Debug\mod_negotiation.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_negotiation.dep")
    !INCLUDE "mod_negotiation.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_negotiation.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_negotiation - Win32 Release" || "$(CFG)" == "mod_negotiation - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_negotiation - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_negotiation - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_negotiation - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_negotiation - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_negotiation - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_negotiation - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_negotiation - Win32 Release"
    
    
    "$(INTDIR)\mod_negotiation.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_negotiation.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_negotiation.so" /d LONG_NAME="negotiation_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_negotiation - Win32 Debug"
    
    
    "$(INTDIR)\mod_negotiation.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_negotiation.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_negotiation.so" /d LONG_NAME="negotiation_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_negotiation.c
    
    "$(INTDIR)\mod_negotiation.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_actions.dep��������������������������������������������������������0000664�0001751�0001751�00000004055�12674411515�020744� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_actions.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_actions.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_negotiation.dep����������������������������������������������������0000664�0001751�0001751�00000004076�12674411515�021627� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_negotiation.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_negotiation.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_rewrite.exp��������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�020775� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������rewrite_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_alias.mak����������������������������������������������������������0000664�0001751�0001751�00000023211�12701473373�020371� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_alias.dsp
    !IF "$(CFG)" == ""
    CFG=mod_alias - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_alias - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_alias - Win32 Release" && "$(CFG)" != "mod_alias - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_alias - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_alias.obj"
    	-@erase "$(INTDIR)\mod_alias.res"
    	-@erase "$(INTDIR)\mod_alias_src.idb"
    	-@erase "$(INTDIR)\mod_alias_src.pdb"
    	-@erase "$(OUTDIR)\mod_alias.exp"
    	-@erase "$(OUTDIR)\mod_alias.lib"
    	-@erase "$(OUTDIR)\mod_alias.pdb"
    	-@erase "$(OUTDIR)\mod_alias.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_alias_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_alias.so" /d LONG_NAME="alias_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_alias.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_alias.pdb" /debug /out:"$(OUTDIR)\mod_alias.so" /implib:"$(OUTDIR)\mod_alias.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_alias.obj" \
    	"$(INTDIR)\mod_alias.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_alias.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_alias.so"
       if exist .\Release\mod_alias.so.manifest mt.exe -manifest .\Release\mod_alias.so.manifest -outputresource:.\Release\mod_alias.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_alias - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_alias.obj"
    	-@erase "$(INTDIR)\mod_alias.res"
    	-@erase "$(INTDIR)\mod_alias_src.idb"
    	-@erase "$(INTDIR)\mod_alias_src.pdb"
    	-@erase "$(OUTDIR)\mod_alias.exp"
    	-@erase "$(OUTDIR)\mod_alias.lib"
    	-@erase "$(OUTDIR)\mod_alias.pdb"
    	-@erase "$(OUTDIR)\mod_alias.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_alias_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_alias.so" /d LONG_NAME="alias_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_alias.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_alias.pdb" /debug /out:"$(OUTDIR)\mod_alias.so" /implib:"$(OUTDIR)\mod_alias.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_alias.obj" \
    	"$(INTDIR)\mod_alias.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_alias.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_alias.so"
       if exist .\Debug\mod_alias.so.manifest mt.exe -manifest .\Debug\mod_alias.so.manifest -outputresource:.\Debug\mod_alias.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_alias.dep")
    !INCLUDE "mod_alias.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_alias.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_alias - Win32 Release" || "$(CFG)" == "mod_alias - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_alias - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_alias - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_alias - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_alias - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_alias - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_alias - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_alias - Win32 Release"
    
    
    "$(INTDIR)\mod_alias.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_alias.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_alias.so" /d LONG_NAME="alias_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_alias - Win32 Debug"
    
    
    "$(INTDIR)\mod_alias.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_alias.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_alias.so" /d LONG_NAME="alias_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_alias.c
    
    "$(INTDIR)\mod_alias.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_speling.mak��������������������������������������������������������0000664�0001751�0001751�00000023471�12701473373�020751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_speling.dsp
    !IF "$(CFG)" == ""
    CFG=mod_speling - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_speling - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_speling - Win32 Release" && "$(CFG)" != "mod_speling - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_speling - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_speling.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_speling.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_speling.obj"
    	-@erase "$(INTDIR)\mod_speling.res"
    	-@erase "$(INTDIR)\mod_speling_src.idb"
    	-@erase "$(INTDIR)\mod_speling_src.pdb"
    	-@erase "$(OUTDIR)\mod_speling.exp"
    	-@erase "$(OUTDIR)\mod_speling.lib"
    	-@erase "$(OUTDIR)\mod_speling.pdb"
    	-@erase "$(OUTDIR)\mod_speling.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_speling_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_speling.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_speling.so" /d LONG_NAME="speling_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_speling.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_speling.pdb" /debug /out:"$(OUTDIR)\mod_speling.so" /implib:"$(OUTDIR)\mod_speling.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_speling.obj" \
    	"$(INTDIR)\mod_speling.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_speling.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_speling.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_speling.so"
       if exist .\Release\mod_speling.so.manifest mt.exe -manifest .\Release\mod_speling.so.manifest -outputresource:.\Release\mod_speling.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_speling - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_speling.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_speling.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_speling.obj"
    	-@erase "$(INTDIR)\mod_speling.res"
    	-@erase "$(INTDIR)\mod_speling_src.idb"
    	-@erase "$(INTDIR)\mod_speling_src.pdb"
    	-@erase "$(OUTDIR)\mod_speling.exp"
    	-@erase "$(OUTDIR)\mod_speling.lib"
    	-@erase "$(OUTDIR)\mod_speling.pdb"
    	-@erase "$(OUTDIR)\mod_speling.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_speling_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_speling.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_speling.so" /d LONG_NAME="speling_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_speling.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_speling.pdb" /debug /out:"$(OUTDIR)\mod_speling.so" /implib:"$(OUTDIR)\mod_speling.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_speling.obj" \
    	"$(INTDIR)\mod_speling.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_speling.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_speling.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_speling.so"
       if exist .\Debug\mod_speling.so.manifest mt.exe -manifest .\Debug\mod_speling.so.manifest -outputresource:.\Debug\mod_speling.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_speling.dep")
    !INCLUDE "mod_speling.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_speling.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_speling - Win32 Release" || "$(CFG)" == "mod_speling - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_speling - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_speling - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_speling - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_speling - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_speling - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_speling - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_speling - Win32 Release"
    
    
    "$(INTDIR)\mod_speling.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_speling.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_speling.so" /d LONG_NAME="speling_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_speling - Win32 Debug"
    
    
    "$(INTDIR)\mod_speling.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_speling.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_speling.so" /d LONG_NAME="speling_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_speling.c
    
    "$(INTDIR)\mod_speling.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_alias.dep����������������������������������������������������������0000664�0001751�0001751�00000003430�12674411515�020371� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_alias.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_alias.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_actions.c����������������������������������������������������������0000664�0001751�0001751�00000016714�14636331332�020421� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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;
        int methnum;
        if (cmd->pool == cmd->temp_pool) {
            /* In .htaccess, we can't globally register new methods. */
            methnum = ap_method_number_of(method);
        }
        else {
            /* ap_method_register recognizes already registered methods,
             * so don't bother to check its previous existence explicitly.
             */
            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;
        if (!action && AP_REQUEST_IS_TRUSTED_CT(r)) {
            action = ap_field_noparam(r->pool, r->content_type);
        }
    
        if (action && (t = apr_table_get(conf->action_types, action))) {
            int virtual = (*t++ == '0' ? 0 : 1);
            if (!virtual && r->finfo.filetype == APR_NOFILE) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00652)
                              "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 (virtual) {
                apr_table_setn(r->notes, "virtual_script", "1");
            }
        }
    
        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);
    }
    
    AP_DECLARE_MODULE(actions) =
    {
        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 */
    };
    ����������������������������������������������������httpd-2.4.64/modules/mappers/mod_rewrite.mak��������������������������������������������������������0000664�0001751�0001751�00000023627�14415176545�021001� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_rewrite.dsp
    !IF "$(CFG)" == ""
    CFG=mod_rewrite - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_rewrite - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_rewrite - Win32 Release" && "$(CFG)" != "mod_rewrite - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_rewrite - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_rewrite.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_rewrite.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_rewrite.obj"
    	-@erase "$(INTDIR)\mod_rewrite.res"
    	-@erase "$(INTDIR)\mod_rewrite_src.idb"
    	-@erase "$(INTDIR)\mod_rewrite_src.pdb"
    	-@erase "$(OUTDIR)\mod_rewrite.exp"
    	-@erase "$(OUTDIR)\mod_rewrite.lib"
    	-@erase "$(OUTDIR)\mod_rewrite.pdb"
    	-@erase "$(OUTDIR)\mod_rewrite.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_rewrite.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_rewrite.so" /d LONG_NAME="rewrite_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_rewrite.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_rewrite.pdb" /debug /out:"$(OUTDIR)\mod_rewrite.so" /implib:"$(OUTDIR)\mod_rewrite.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_rewrite.obj" \
    	"$(INTDIR)\mod_rewrite.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_rewrite.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_rewrite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_rewrite.so"
       if exist .\Release\mod_rewrite.so.manifest mt.exe -manifest .\Release\mod_rewrite.so.manifest -outputresource:.\Release\mod_rewrite.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_rewrite - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_rewrite.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_rewrite.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_rewrite.obj"
    	-@erase "$(INTDIR)\mod_rewrite.res"
    	-@erase "$(INTDIR)\mod_rewrite_src.idb"
    	-@erase "$(INTDIR)\mod_rewrite_src.pdb"
    	-@erase "$(OUTDIR)\mod_rewrite.exp"
    	-@erase "$(OUTDIR)\mod_rewrite.lib"
    	-@erase "$(OUTDIR)\mod_rewrite.pdb"
    	-@erase "$(OUTDIR)\mod_rewrite.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_rewrite.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_rewrite.so" /d LONG_NAME="rewrite_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_rewrite.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_rewrite.pdb" /debug /out:"$(OUTDIR)\mod_rewrite.so" /implib:"$(OUTDIR)\mod_rewrite.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_rewrite.obj" \
    	"$(INTDIR)\mod_rewrite.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_rewrite.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_rewrite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_rewrite.so"
       if exist .\Debug\mod_rewrite.so.manifest mt.exe -manifest .\Debug\mod_rewrite.so.manifest -outputresource:.\Debug\mod_rewrite.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_rewrite.dep")
    !INCLUDE "mod_rewrite.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_rewrite.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_rewrite - Win32 Release" || "$(CFG)" == "mod_rewrite - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_rewrite - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_rewrite - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_rewrite - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_rewrite - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_rewrite - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_rewrite - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_rewrite - Win32 Release"
    
    
    "$(INTDIR)\mod_rewrite.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_rewrite.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_rewrite.so" /d LONG_NAME="rewrite_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_rewrite - Win32 Debug"
    
    
    "$(INTDIR)\mod_rewrite.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_rewrite.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_rewrite.so" /d LONG_NAME="rewrite_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_rewrite.c
    
    "$(INTDIR)\mod_rewrite.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_userdir.c����������������������������������������������������������0000664�0001751�0001751�00000031245�12727637664�020452� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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* ~<username> 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 <unistd.h>
    #endif
    
    #include "ap_config.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "http_request.h"
    
    #if !defined(WIN32) && !defined(OS2) && !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
    
    #define O_DEFAULT 0
    #define O_ENABLE 1
    #define O_DISABLE 2
    
    module AP_MODULE_DECLARE_DATA userdir_module;
    
    typedef struct {
        int globally_disabled;
        const 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 = O_DEFAULT;
        newcfg->userdir = DEFAULT_USER_DIR;
        newcfg->enabled_users = apr_table_make(p, 4);
        newcfg->disabled_users = apr_table_make(p, 4);
    
        return newcfg;
    }
    
    static void *merge_userdir_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        userdir_config *cfg = apr_pcalloc(p, sizeof(userdir_config));
        userdir_config *base = basev, *overrides = overridesv;
    
        cfg->globally_disabled = (overrides->globally_disabled != O_DEFAULT) ?
                                 overrides->globally_disabled :
                                 base->globally_disabled;
        cfg->userdir = (overrides->userdir != DEFAULT_USER_DIR) ?
                       overrides->userdir : base->userdir;
    
        /* not merged */
        cfg->enabled_users = overrides->enabled_users;
        cfg->disabled_users = overrides->disabled_users;
    
        return cfg;
    }
    
    
    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->temp_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 (!*usernames) {
                s_cfg->globally_disabled = O_DISABLE;
                return NULL;
            }
            usertable = s_cfg->disabled_users;
        }
        else if ((!strcasecmp(kw, "enable")) || (!strcasecmp(kw, "enabled"))) {
            if (!*usernames) {
                s_cfg->globally_disabled = O_ENABLE;
                return NULL;
            }
            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 = 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, "1");
        }
        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;
        const char *userdirs;
        const char *user, *dname;
        char *redirect;
        apr_finfo_t statbuf;
    
        /*
         * If the URI doesn't match our basic pattern, we've nothing to do with
         * it.
         */
        if (r->uri[0] != '/' || r->uri[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 = r->uri + 2;
        user = 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 (user[0] == '\0' ||
            (user[1] == '.' && (user[2] == '\0' ||
                                (user[2] == '.' && user[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, user) != 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 == O_DISABLE
            && apr_table_get(s_cfg->enabled_users, user) == 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, *prefix = NULL;
            apr_status_t rv;
            int is_absolute = ap_os_is_path_absolute(r->pool, userdir);
    
            if (ap_strchr_c(userdir, '*'))
                prefix = ap_getword(r->pool, &userdir, '*');
    
            if (userdir[0] == '\0' || is_absolute) {
                if (prefix) {
    #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(prefix + 2, ':'))
    #else
                    if (strchr(prefix, ':') && !is_absolute)
    #endif /* HAVE_DRIVE_LETTERS */
                    {
                        redirect = apr_pstrcat(r->pool, prefix, user, userdir,
                                               dname, NULL);
                        apr_table_setn(r->headers_out, "Location", redirect);
                        return HTTP_MOVED_TEMPORARILY;
                    }
                    else
                        filename = apr_pstrcat(r->pool, prefix, user, userdir,
                                               NULL);
                }
                else
                    filename = apr_pstrcat(r->pool, userdir, "/", user, NULL);
            }
            else if (prefix && ap_strchr_c(prefix, ':')) {
                redirect = apr_pstrcat(r->pool, prefix, user, 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, user, 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);
                ap_set_context_info(r, apr_pstrmemdup(r->pool, r->uri,
                                                      dname - r->uri),
                                    filename);
                /* 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", user);
    
                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
    }
    
    AP_DECLARE_MODULE(userdir) = {
        STANDARD20_MODULE_STUFF,
        NULL,                       /* dir config creater */
        NULL,                       /* dir merger --- default is to override */
        create_userdir_config,      /* server config */
        merge_userdir_config,       /* merge server config */
        userdir_cmds,               /* command apr_table_t */
        register_hooks              /* register hooks */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_imagemap.mak�������������������������������������������������������0000664�0001751�0001751�00000023621�12701473373�021065� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_imagemap.dsp
    !IF "$(CFG)" == ""
    CFG=mod_imagemap - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_imagemap - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_imagemap - Win32 Release" && "$(CFG)" != "mod_imagemap - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_imagemap - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_imagemap.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_imagemap.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_imagemap.obj"
    	-@erase "$(INTDIR)\mod_imagemap.res"
    	-@erase "$(INTDIR)\mod_imagemap_src.idb"
    	-@erase "$(INTDIR)\mod_imagemap_src.pdb"
    	-@erase "$(OUTDIR)\mod_imagemap.exp"
    	-@erase "$(OUTDIR)\mod_imagemap.lib"
    	-@erase "$(OUTDIR)\mod_imagemap.pdb"
    	-@erase "$(OUTDIR)\mod_imagemap.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_imagemap_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_imagemap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_imagemap.so" /d LONG_NAME="imagemap_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_imagemap.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_imagemap.pdb" /debug /out:"$(OUTDIR)\mod_imagemap.so" /implib:"$(OUTDIR)\mod_imagemap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_imagemap.obj" \
    	"$(INTDIR)\mod_imagemap.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_imagemap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_imagemap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_imagemap.so"
       if exist .\Release\mod_imagemap.so.manifest mt.exe -manifest .\Release\mod_imagemap.so.manifest -outputresource:.\Release\mod_imagemap.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_imagemap - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_imagemap.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_imagemap.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_imagemap.obj"
    	-@erase "$(INTDIR)\mod_imagemap.res"
    	-@erase "$(INTDIR)\mod_imagemap_src.idb"
    	-@erase "$(INTDIR)\mod_imagemap_src.pdb"
    	-@erase "$(OUTDIR)\mod_imagemap.exp"
    	-@erase "$(OUTDIR)\mod_imagemap.lib"
    	-@erase "$(OUTDIR)\mod_imagemap.pdb"
    	-@erase "$(OUTDIR)\mod_imagemap.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_imagemap_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_imagemap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_imagemap.so" /d LONG_NAME="imagemap_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_imagemap.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_imagemap.pdb" /debug /out:"$(OUTDIR)\mod_imagemap.so" /implib:"$(OUTDIR)\mod_imagemap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_imagemap.obj" \
    	"$(INTDIR)\mod_imagemap.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_imagemap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_imagemap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_imagemap.so"
       if exist .\Debug\mod_imagemap.so.manifest mt.exe -manifest .\Debug\mod_imagemap.so.manifest -outputresource:.\Debug\mod_imagemap.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_imagemap.dep")
    !INCLUDE "mod_imagemap.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_imagemap.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_imagemap - Win32 Release" || "$(CFG)" == "mod_imagemap - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_imagemap - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_imagemap - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_imagemap - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_imagemap - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_imagemap - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_imagemap - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_imagemap - Win32 Release"
    
    
    "$(INTDIR)\mod_imagemap.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_imagemap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_imagemap.so" /d LONG_NAME="imagemap_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_imagemap - Win32 Debug"
    
    
    "$(INTDIR)\mod_imagemap.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_imagemap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_imagemap.so" /d LONG_NAME="imagemap_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_imagemap.c
    
    "$(INTDIR)\mod_imagemap.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_vhost_alias.mak����������������������������������������������������0000664�0001751�0001751�00000024231�12701473373�021617� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_vhost_alias.dsp
    !IF "$(CFG)" == ""
    CFG=mod_vhost_alias - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_vhost_alias - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_vhost_alias - Win32 Release" && "$(CFG)" != "mod_vhost_alias - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_vhost_alias - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_vhost_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_vhost_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_vhost_alias.obj"
    	-@erase "$(INTDIR)\mod_vhost_alias.res"
    	-@erase "$(INTDIR)\mod_vhost_alias_src.idb"
    	-@erase "$(INTDIR)\mod_vhost_alias_src.pdb"
    	-@erase "$(OUTDIR)\mod_vhost_alias.exp"
    	-@erase "$(OUTDIR)\mod_vhost_alias.lib"
    	-@erase "$(OUTDIR)\mod_vhost_alias.pdb"
    	-@erase "$(OUTDIR)\mod_vhost_alias.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_vhost_alias_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_vhost_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_vhost_alias.so" /d LONG_NAME="vhost_alias_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_vhost_alias.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_vhost_alias.pdb" /debug /out:"$(OUTDIR)\mod_vhost_alias.so" /implib:"$(OUTDIR)\mod_vhost_alias.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_vhost_alias.obj" \
    	"$(INTDIR)\mod_vhost_alias.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_vhost_alias.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_vhost_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_vhost_alias.so"
       if exist .\Release\mod_vhost_alias.so.manifest mt.exe -manifest .\Release\mod_vhost_alias.so.manifest -outputresource:.\Release\mod_vhost_alias.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_vhost_alias - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_vhost_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_vhost_alias.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_vhost_alias.obj"
    	-@erase "$(INTDIR)\mod_vhost_alias.res"
    	-@erase "$(INTDIR)\mod_vhost_alias_src.idb"
    	-@erase "$(INTDIR)\mod_vhost_alias_src.pdb"
    	-@erase "$(OUTDIR)\mod_vhost_alias.exp"
    	-@erase "$(OUTDIR)\mod_vhost_alias.lib"
    	-@erase "$(OUTDIR)\mod_vhost_alias.pdb"
    	-@erase "$(OUTDIR)\mod_vhost_alias.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_vhost_alias_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_vhost_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_vhost_alias.so" /d LONG_NAME="vhost_alias_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_vhost_alias.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_vhost_alias.pdb" /debug /out:"$(OUTDIR)\mod_vhost_alias.so" /implib:"$(OUTDIR)\mod_vhost_alias.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_vhost_alias.obj" \
    	"$(INTDIR)\mod_vhost_alias.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_vhost_alias.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_vhost_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_vhost_alias.so"
       if exist .\Debug\mod_vhost_alias.so.manifest mt.exe -manifest .\Debug\mod_vhost_alias.so.manifest -outputresource:.\Debug\mod_vhost_alias.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_vhost_alias.dep")
    !INCLUDE "mod_vhost_alias.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_vhost_alias.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_vhost_alias - Win32 Release" || "$(CFG)" == "mod_vhost_alias - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_vhost_alias - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_vhost_alias - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_vhost_alias - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_vhost_alias - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_vhost_alias - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_vhost_alias - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_vhost_alias - Win32 Release"
    
    
    "$(INTDIR)\mod_vhost_alias.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_vhost_alias.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_vhost_alias.so" /d LONG_NAME="vhost_alias_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_vhost_alias - Win32 Debug"
    
    
    "$(INTDIR)\mod_vhost_alias.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_vhost_alias.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_vhost_alias.so" /d LONG_NAME="vhost_alias_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_vhost_alias.c
    
    "$(INTDIR)\mod_vhost_alias.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_imagemap.dep�������������������������������������������������������0000664�0001751�0001751�00000004163�12674411515�021064� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_imagemap.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_imagemap.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_dir.mak������������������������������������������������������������0000664�0001751�0001751�00000022731�12701473373�020064� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_dir.dsp
    !IF "$(CFG)" == ""
    CFG=mod_dir - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_dir - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_dir - Win32 Release" && "$(CFG)" != "mod_dir - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dir - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dir.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_dir.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_dir.obj"
    	-@erase "$(INTDIR)\mod_dir.res"
    	-@erase "$(INTDIR)\mod_dir_src.idb"
    	-@erase "$(INTDIR)\mod_dir_src.pdb"
    	-@erase "$(OUTDIR)\mod_dir.exp"
    	-@erase "$(OUTDIR)\mod_dir.lib"
    	-@erase "$(OUTDIR)\mod_dir.pdb"
    	-@erase "$(OUTDIR)\mod_dir.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dir_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dir.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dir.so" /d LONG_NAME="dir_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dir.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dir.pdb" /debug /out:"$(OUTDIR)\mod_dir.so" /implib:"$(OUTDIR)\mod_dir.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_dir.obj" \
    	"$(INTDIR)\mod_dir.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_dir.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_dir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dir.so"
       if exist .\Release\mod_dir.so.manifest mt.exe -manifest .\Release\mod_dir.so.manifest -outputresource:.\Release\mod_dir.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_dir - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dir.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_dir.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_dir.obj"
    	-@erase "$(INTDIR)\mod_dir.res"
    	-@erase "$(INTDIR)\mod_dir_src.idb"
    	-@erase "$(INTDIR)\mod_dir_src.pdb"
    	-@erase "$(OUTDIR)\mod_dir.exp"
    	-@erase "$(OUTDIR)\mod_dir.lib"
    	-@erase "$(OUTDIR)\mod_dir.pdb"
    	-@erase "$(OUTDIR)\mod_dir.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dir_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dir.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dir.so" /d LONG_NAME="dir_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dir.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dir.pdb" /debug /out:"$(OUTDIR)\mod_dir.so" /implib:"$(OUTDIR)\mod_dir.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_dir.obj" \
    	"$(INTDIR)\mod_dir.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_dir.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_dir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dir.so"
       if exist .\Debug\mod_dir.so.manifest mt.exe -manifest .\Debug\mod_dir.so.manifest -outputresource:.\Debug\mod_dir.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_dir.dep")
    !INCLUDE "mod_dir.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_dir.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_dir - Win32 Release" || "$(CFG)" == "mod_dir - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_dir - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_dir - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dir - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_dir - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dir - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_dir - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_dir - Win32 Release"
    
    
    "$(INTDIR)\mod_dir.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dir.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_dir.so" /d LONG_NAME="dir_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_dir - Win32 Debug"
    
    
    "$(INTDIR)\mod_dir.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dir.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_dir.so" /d LONG_NAME="dir_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_dir.c
    
    "$(INTDIR)\mod_dir.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������httpd-2.4.64/modules/mappers/mod_userdir.mak��������������������������������������������������������0000664�0001751�0001751�00000023471�12701473373�020765� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_userdir.dsp
    !IF "$(CFG)" == ""
    CFG=mod_userdir - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_userdir - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_userdir - Win32 Release" && "$(CFG)" != "mod_userdir - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_userdir - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_userdir.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_userdir.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_userdir.obj"
    	-@erase "$(INTDIR)\mod_userdir.res"
    	-@erase "$(INTDIR)\mod_userdir_src.idb"
    	-@erase "$(INTDIR)\mod_userdir_src.pdb"
    	-@erase "$(OUTDIR)\mod_userdir.exp"
    	-@erase "$(OUTDIR)\mod_userdir.lib"
    	-@erase "$(OUTDIR)\mod_userdir.pdb"
    	-@erase "$(OUTDIR)\mod_userdir.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_userdir_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_userdir.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_userdir.so" /d LONG_NAME="userdir_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_userdir.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_userdir.pdb" /debug /out:"$(OUTDIR)\mod_userdir.so" /implib:"$(OUTDIR)\mod_userdir.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_userdir.obj" \
    	"$(INTDIR)\mod_userdir.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_userdir.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_userdir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_userdir.so"
       if exist .\Release\mod_userdir.so.manifest mt.exe -manifest .\Release\mod_userdir.so.manifest -outputresource:.\Release\mod_userdir.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_userdir - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_userdir.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_userdir.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_userdir.obj"
    	-@erase "$(INTDIR)\mod_userdir.res"
    	-@erase "$(INTDIR)\mod_userdir_src.idb"
    	-@erase "$(INTDIR)\mod_userdir_src.pdb"
    	-@erase "$(OUTDIR)\mod_userdir.exp"
    	-@erase "$(OUTDIR)\mod_userdir.lib"
    	-@erase "$(OUTDIR)\mod_userdir.pdb"
    	-@erase "$(OUTDIR)\mod_userdir.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_userdir_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_userdir.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_userdir.so" /d LONG_NAME="userdir_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_userdir.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_userdir.pdb" /debug /out:"$(OUTDIR)\mod_userdir.so" /implib:"$(OUTDIR)\mod_userdir.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_userdir.obj" \
    	"$(INTDIR)\mod_userdir.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_userdir.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_userdir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_userdir.so"
       if exist .\Debug\mod_userdir.so.manifest mt.exe -manifest .\Debug\mod_userdir.so.manifest -outputresource:.\Debug\mod_userdir.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_userdir.dep")
    !INCLUDE "mod_userdir.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_userdir.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_userdir - Win32 Release" || "$(CFG)" == "mod_userdir - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_userdir - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_userdir - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_userdir - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_userdir - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\mappers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\mappers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_userdir - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ELSEIF  "$(CFG)" == "mod_userdir - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\mappers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\mappers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_userdir - Win32 Release"
    
    
    "$(INTDIR)\mod_userdir.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_userdir.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_userdir.so" /d LONG_NAME="userdir_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_userdir - Win32 Debug"
    
    
    "$(INTDIR)\mod_userdir.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_userdir.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_userdir.so" /d LONG_NAME="userdir_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_userdir.c
    
    "$(INTDIR)\mod_userdir.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_dir.dep������������������������������������������������������������0000664�0001751�0001751�00000004140�12674411515�020055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_dir.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_dir.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_rewrite.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_rewrite.dep��������������������������������������������������������0000664�0001751�0001751�00000004431�12674411515�020763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_rewrite.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_rewrite.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\http_vhost.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbd.h"\
    	"..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_signal.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\database\mod_dbd.h"\
    	"..\ssl\mod_ssl.h"\
    	".\mod_rewrite.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_rewrite.h����������������������������������������������������������0000664�0001751�0001751�00000002565�12270224045�020440� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mod_rewrite.h
     * @brief Rewrite Extension module for Apache
     *
     * @defgroup MOD_REWRITE mod_rewrite
     * @ingroup APACHE_MODS
     * @{
     */
    
    #ifndef MOD_REWRITE_H
    #define MOD_REWRITE_H 1
    
    #include "apr_optional.h"
    #include "httpd.h"
    
    #define REWRITE_REDIRECT_HANDLER_NAME "redirect-handler"
    
    /* 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 */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/NWGNUuserdir�����������������������������������������������������������0000664�0001751�0001751�00000010201�11540546347�020163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_dir.dsp������������������������������������������������������������0000664�0001751�0001751�00000010431�10551346420�020065� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_dir.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dir.so" /d LONG_NAME="dir_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_dir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_dir.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dir.so" /d LONG_NAME="dir_module for Apache"
    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 /out:".\Debug\mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_dir.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_alias.dsp����������������������������������������������������������0000664�0001751�0001751�00000010525�10551346420�020404� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_alias.so" /d LONG_NAME="alias_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_alias.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_alias.so" /d LONG_NAME="alias_module for Apache"
    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 /out:".\Debug\mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_alias.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_vhost_alias.dep����������������������������������������������������0000664�0001751�0001751�00000003407�12674411515�021620� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_vhost_alias.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_vhost_alias.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_rewrite.dsp��������������������������������������������������������0000664�0001751�0001751�00000010713�10551346420�020773� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 "../database" /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 /fo"Release/mod_rewrite.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_rewrite.so" /d LONG_NAME="rewrite_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_rewrite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../database" /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 /fo"Debug/mod_rewrite.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_rewrite.so" /d LONG_NAME="rewrite_module for Apache"
    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 /out:".\Debug\mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_rewrite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������httpd-2.4.64/modules/mappers/mod_userdir.dep��������������������������������������������������������0000664�0001751�0001751�00000003166�12674411515�020763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_userdir.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_userdir.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_speling.dep��������������������������������������������������������0000664�0001751�0001751�00000003434�12674411515�020745� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_speling.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_speling.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/NWGNUmakefile����������������������������������������������������������0000664�0001751�0001751�00000010112�11540562746�020265� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_negotiation.dsp����������������������������������������������������0000664�0001751�0001751�00000011011�10551346420�021622� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_negotiation.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_negotiation.so" /d LONG_NAME="negotiation_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_negotiation.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_negotiation.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_negotiation.so" /d LONG_NAME="negotiation_module for Apache"
    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 /out:".\Debug\mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_negotiation.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_userdir.exp��������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�020771� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������userdir_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_alias.exp����������������������������������������������������������0000664�0001751�0001751�00000000015�10150161574�020403� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������alias_module
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_imagemap.dsp�������������������������������������������������������0000664�0001751�0001751�00000010657�10551346420�021101� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_imagemap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_imagemap.so" /d LONG_NAME="imagemap_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_imagemap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_imagemap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_imagemap.so" /d LONG_NAME="imagemap_module for Apache"
    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 /out:".\Debug\mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_imagemap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������httpd-2.4.64/modules/mappers/mod_speling.exp��������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�020755� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������speling_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016064� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_usertrack.dep�����������������������������������������������������0000664�0001751�0001751�00000003440�12674411515�021415� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_usertrack.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_usertrack.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/config.m4�������������������������������������������������������������0000664�0001751�0001751�00000001642�11657335760�017601� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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, , , no)
    APACHE_MODULE(expires, Expires header control, , , most)
    APACHE_MODULE(headers, HTTP header control, , , yes)
    APACHE_MODULE(ident, RFC 1413 identity check, , , no)
    
    APACHE_MODULE(usertrack, user-session tracking, , , , [
      AC_CHECK_HEADERS(sys/times.h)
      AC_CHECK_FUNCS(times)
    ])
    
    APACHE_MODULE(unique_id, per-request unique ids, , , most)
    APACHE_MODULE(setenvif, basing ENV vars on headers, , , yes)
    APACHE_MODULE(version, determining httpd version in config files, , , yes)
    APACHE_MODULE(remoteip, translate header contents to an apparent client remote_ip, , , most)
    
    APACHE_MODPATH_FINISH
    ����������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_setenvif.mak������������������������������������������������������0000664�0001751�0001751�00000023665�12701473373�021251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_setenvif.dsp
    !IF "$(CFG)" == ""
    CFG=mod_setenvif - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_setenvif - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_setenvif - Win32 Release" && "$(CFG)" != "mod_setenvif - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_setenvif - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_setenvif.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_setenvif.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_setenvif.obj"
    	-@erase "$(INTDIR)\mod_setenvif.res"
    	-@erase "$(INTDIR)\mod_setenvif_src.idb"
    	-@erase "$(INTDIR)\mod_setenvif_src.pdb"
    	-@erase "$(OUTDIR)\mod_setenvif.exp"
    	-@erase "$(OUTDIR)\mod_setenvif.lib"
    	-@erase "$(OUTDIR)\mod_setenvif.pdb"
    	-@erase "$(OUTDIR)\mod_setenvif.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../ssl" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_setenvif_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_setenvif.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_setenvif.so" /d LONG_NAME="setenvif_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_setenvif.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_setenvif.pdb" /debug /out:"$(OUTDIR)\mod_setenvif.so" /implib:"$(OUTDIR)\mod_setenvif.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_setenvif.obj" \
    	"$(INTDIR)\mod_setenvif.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_setenvif.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_setenvif.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_setenvif.so"
       if exist .\Release\mod_setenvif.so.manifest mt.exe -manifest .\Release\mod_setenvif.so.manifest -outputresource:.\Release\mod_setenvif.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_setenvif - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_setenvif.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_setenvif.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_setenvif.obj"
    	-@erase "$(INTDIR)\mod_setenvif.res"
    	-@erase "$(INTDIR)\mod_setenvif_src.idb"
    	-@erase "$(INTDIR)\mod_setenvif_src.pdb"
    	-@erase "$(OUTDIR)\mod_setenvif.exp"
    	-@erase "$(OUTDIR)\mod_setenvif.lib"
    	-@erase "$(OUTDIR)\mod_setenvif.pdb"
    	-@erase "$(OUTDIR)\mod_setenvif.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../ssl" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_setenvif_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_setenvif.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_setenvif.so" /d LONG_NAME="setenvif_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_setenvif.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_setenvif.pdb" /debug /out:"$(OUTDIR)\mod_setenvif.so" /implib:"$(OUTDIR)\mod_setenvif.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_setenvif.obj" \
    	"$(INTDIR)\mod_setenvif.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_setenvif.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_setenvif.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_setenvif.so"
       if exist .\Debug\mod_setenvif.so.manifest mt.exe -manifest .\Debug\mod_setenvif.so.manifest -outputresource:.\Debug\mod_setenvif.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_setenvif.dep")
    !INCLUDE "mod_setenvif.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_setenvif.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_setenvif - Win32 Release" || "$(CFG)" == "mod_setenvif - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_setenvif - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_setenvif - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_setenvif - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_setenvif - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_setenvif - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_setenvif - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_setenvif - Win32 Release"
    
    
    "$(INTDIR)\mod_setenvif.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_setenvif.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_setenvif.so" /d LONG_NAME="setenvif_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_setenvif - Win32 Debug"
    
    
    "$(INTDIR)\mod_setenvif.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_setenvif.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_setenvif.so" /d LONG_NAME="setenvif_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_setenvif.c
    
    "$(INTDIR)\mod_setenvif.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_cern_meta.dep�����������������������������������������������������0000664�0001751�0001751�00000003730�12674411515�021351� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_cern_meta.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_cern_meta.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������httpd-2.4.64/modules/metadata/mod_ident.dep���������������������������������������������������������0000664�0001751�0001751�00000003477�12674411515�020527� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_ident.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_ident.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_unique_id.dep�����������������������������������������������������0000664�0001751�0001751�00000003424�12674411515�021376� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_unique_id.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_unique_id.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_ident.c�����������������������������������������������������������0000664�0001751�0001751�00000025402�12604740124�020163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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, APLOGNO(01492)
                         "rfc1413: apr_sockaddr_info_get(%s) failed",
                         conn->local_ip);
            return rv;
        }
    
        if ((rv = apr_sockaddr_info_get(&destsa, conn->client_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, APLOGNO(01493)
                         "rfc1413: apr_sockaddr_info_get(%s) failed",
                         conn->client_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, APLOGNO(01494)
                         "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, APLOGNO(01495)
                         "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, APLOGNO(01496)
                         "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->client_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, APLOGNO(01497)
                             "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, APLOGNO(01498)
                             "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_;
    
        d->do_rfc1413 = arg ? 1 : 0;
        return NULL;
    }
    
    static const char *set_timeout(cmd_parms *cmd, void *d_, const char *arg)
    {
        ident_config_rec *d = d_;
    
        d->timeout = apr_time_from_sec(atoi(arg));
        d->timeout_unset = 0;
        return NULL;
    }
    
    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 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);
    }
    
    AP_DECLARE_MODULE(ident) =
    {
        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 */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUexpires����������������������������������������������������������0000664�0001751�0001751�00000010143�11540546347�020303� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUmimemagi���������������������������������������������������������0000664�0001751�0001751�00000010160�11540546347�020410� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_ident.dsp���������������������������������������������������������0000664�0001751�0001751�00000010525�10551346420�020527� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_ident.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ident.so" /d LONG_NAME="ident_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_ident.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_ident.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ident.so" /d LONG_NAME="ident_module for Apache"
    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 /out:".\Debug\mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_ident.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_env.exp�����������������������������������������������������������0000664�0001751�0001751�00000000013�10150161574�020211� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������env_module
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/.indent.pro�����������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�020140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_unique_id.exp�����������������������������������������������������0000664�0001751�0001751�00000000021�10150161574�021402� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������unique_id_module
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_mime_magic.exp����������������������������������������������������0000664�0001751�0001751�00000000022�10150161574�021510� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mime_magic_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUmodident���������������������������������������������������������0000664�0001751�0001751�00000010160�11540546347�020426� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUusertrk����������������������������������������������������������0000664�0001751�0001751�00000010155�11540546347�020326� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_unique_id.dsp�����������������������������������������������������0000664�0001751�0001751�00000010771�10551346420�021411� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_unique_id.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_unique_id.so" /d LONG_NAME="unique_id_module for Apache"
    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 /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 /out:".\Release\mod_unique_id.so" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_unique_id.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_unique_id.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_unique_id.so" /d LONG_NAME="unique_id_module for Apache"
    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 /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 /out:".\Debug\mod_unique_id.so" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_unique_id.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������httpd-2.4.64/modules/metadata/mod_version.exp�������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�021112� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������version_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_headers.dsp�������������������������������������������������������0000664�0001751�0001751�00000010631�10551346420�021035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_headers.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_headers.so" /d LONG_NAME="headers_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /debug /out:".\Release\mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_headers.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_headers.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_headers.so" /d LONG_NAME="headers_module for Apache"
    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 /out:".\Debug\mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_headers.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_ident.exp���������������������������������������������������������0000664�0001751�0001751�00000000015�10150161574�020526� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ident_module
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_cern_meta.c�������������������������������������������������������0000664�0001751�0001751�00000026672�14001631447�021027� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <Andrew.Wilson@cm.cf.ac.uk> 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 <on|off>
     *
     *    turns on|off meta file processing for any directory.
     *    Default value is off
     *
     *        # turn on MetaFiles in this directory
     *        MetaFiles on
     *
     *  MetaDir <directory name>
     *
     *    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 <meta file suffix>
     *
     *    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 <on|off> 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 <sys/types.h>
    #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, APLOGNO(01560)
                    "malformed header in meta file: %s", r->filename);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            *l++ = '\0';
            while (apr_isspace(*l))
                ++l;
    
            if (!ap_cstr_casecmp(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 (!ap_cstr_casecmp(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 == APR_NOFILE) {
            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, APLOGNO(01561)
                "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 <Location > blocks are never run
         * against sub_req_lookup_file, the meta can be somewhat protected by
         * either masking it with a <Location > 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, APLOGNO(01562)
                "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);
    }
    
    AP_DECLARE_MODULE(cern_meta) =
    {
        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 */
    };
    ����������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_setenvif.dsp������������������������������������������������������0000664�0001751�0001751�00000010707�10551346420�021251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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" /I "../ssl" /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 /fo"Release/mod_setenvif.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_setenvif.so" /d LONG_NAME="setenvif_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_setenvif.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../ssl" /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 /fo"Debug/mod_setenvif.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_setenvif.so" /d LONG_NAME="setenvif_module for Apache"
    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 /out:".\Debug\mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_setenvif.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������httpd-2.4.64/modules/metadata/mod_usertrack.dsp�����������������������������������������������������0000664�0001751�0001751�00000010715�10551346420�021430� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_usertrack.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_usertrack.so" /d LONG_NAME="usertrack_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_usertrack.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_usertrack.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_usertrack.so" /d LONG_NAME="usertrack_module for Apache"
    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 /out:".\Debug\mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_usertrack.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������httpd-2.4.64/modules/metadata/mod_cern_meta.dsp�����������������������������������������������������0000664�0001751�0001751�00000010715�10551346420�021362� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_cern_meta.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cern_meta.so" /d LONG_NAME="cern_meta_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_cern_meta.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_cern_meta.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_cern_meta.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cern_meta.so" /d LONG_NAME="cern_meta_module for Apache"
    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 /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 /out:".\Debug\mod_cern_meta.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_cern_meta.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������httpd-2.4.64/modules/metadata/mod_headers.c���������������������������������������������������������0000664�0001751�0001751�00000077725�15032733376�020523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
     *     merge  - merge this text onto any existing header of this same,
     *              avoiding duplicate values
     *     unset  - remove this header
     *      edit  - transform the header value according to a regexp
     *
     * 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 <Directory> sections (working downwards
     * from the root dir), then an <Location> sections (working down from
     * shortest URL component), the any <File> 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_ssl.h"
    #include "http_log.h"
    #include "util_filter.h"
    #include "http_protocol.h"
    #include "ap_expr.h"
    
    /* 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_merge = 'g',            /* merge (merge, but avoid duplicates) */
        hdr_unset = 'u',            /* unset header */
        hdr_echo = 'e',             /* echo headers from request to response */
        hdr_edit = 'r',             /* change value by regexp, match once */
        hdr_edit_r = 'R',           /* change value by regexp, everymatch */
        hdr_setifempty = 'i',       /* set value if header not already present*/
        hdr_note = 'n'              /* set value of header in a note */
    } hdr_actions;
    
    /*
     * magic cmd->info values
     */
    static char hdr_in  = '0';  /* RequestHeader */
    static char hdr_out_onsuccess = '1';  /* Header onsuccess */
    static char hdr_out_always = '2';  /* Header always */
    
    /* Callback function type. */
    typedef const char *format_tag_fn(request_rec *r, char *a);
    
    /*
     * There is an array of struct format_tag per Header/RequestHeader
     * config directive
     */
    typedef struct {
        format_tag_fn *func;
        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;
        const char *subs;
        ap_expr_info_t *expr;
        ap_expr_info_t *expr_out;
    } 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;
    
    /* edit_do is used for Header edit to iterate through the request headers */
    typedef struct {
        request_rec *r;
        header_entry *hdr;
        apr_table_t *t;
    } edit_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;
    
    /*
     * 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)
    {
        const char *val = ap_ssl_var_lookup(r->pool, r->server,
                                            r->connection, r, name);
        if (val && val[0])
            return unwrap_header(r->pool, val);
        else
            return "(null)";
    }
    
    static const char *header_request_loadavg(request_rec *r, char *a)
    {
        ap_loadavg_t t;
        ap_get_loadavg(&t);
        return apr_psprintf(r->pool, "l=%.2f/%.2f/%.2f", t.loadavg,
                            t.loadavg5, t.loadavg15);
    }
    
    static const char *header_request_idle(request_rec *r, char *a)
    {
        ap_sload_t t;
        ap_get_sload(&t);
        return apr_psprintf(r->pool, "i=%d", t.idle);
    }
    
    static const char *header_request_busy(request_rec *r, char *a)
    {
        ap_sload_t t;
        ap_get_sload(&t);
        return apr_psprintf(r->pool, "b=%d", t.busy);
    }
    
    /*
     * 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 %% or % at end of string as % */
        if ((*s == '%') || (*s == '\0')) {
            tag->func = constant_item;
            tag->arg = "%";
            if (*s)
                s++;
            *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(cmd_parms *cmd, header_entry *hdr, const char *s)
    {
        apr_pool_t *p = cmd->pool;
        char *res;
    
        /* No string to parse with unset and echo commands */
        if (hdr->action == hdr_unset || hdr->action == hdr_echo) {
            return NULL;
        }
        /* Tags are in the replacement value for edit */
        else if (hdr->action == hdr_edit || hdr->action == hdr_edit_r ) {
            s = hdr->subs;
        }
    
        if (!strncmp(s, "expr=", 5)) { 
            const char *err;
            hdr->expr_out = ap_expr_parse_cmd(cmd, s+5, 
                                              AP_EXPR_FLAG_STRING_RESULT,
                                              &err, NULL);
            if (err) {
                return apr_pstrcat(cmd->pool,
                        "Can't parse value expression : ", err, NULL);
            }
            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 *subs,
                                                   const char *envclause)
    {
        headers_conf *dirconf = indirconf;
        const char *condition_var = NULL;
        const char *colon;
        header_entry *new;
        ap_expr_info_t *expr = NULL;
    
        apr_array_header_t *fixup = (cmd->info == &hdr_in)
            ? dirconf->fixup_in   : (cmd->info == &hdr_out_always)
            ? 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, "setifempty"))
            new->action = hdr_setifempty;
        else if (!strcasecmp(action, "add"))
            new->action = hdr_add;
        else if (!strcasecmp(action, "append"))
            new->action = hdr_append;
        else if (!strcasecmp(action, "merge"))
            new->action = hdr_merge;
        else if (!strcasecmp(action, "unset"))
            new->action = hdr_unset;
        else if (!strcasecmp(action, "echo"))
            new->action = hdr_echo;
        else if (!strcasecmp(action, "edit"))
            new->action = hdr_edit;
        else if (!strcasecmp(action, "edit*"))
            new->action = hdr_edit_r;
        else if (!strcasecmp(action, "note"))
            new->action = hdr_note;
        else
            return "first argument must be 'add', 'set', 'setifempty', 'append', 'merge', "
                   "'unset', 'echo', 'note', 'edit', or 'edit*'.";
    
        if (new->action == hdr_edit || new->action == hdr_edit_r) {
            if (subs == NULL) {
                return "Header edit requires a match and a substitution";
            }
            new->regex = ap_pregcomp(cmd->pool, value, AP_REG_EXTENDED);
            if (new->regex == NULL) {
                return "Header edit regex could not be compiled";
            }
            new->subs = subs;
        }
        else {
            /* there's no subs, so envclause is really that argument */
            if (envclause != NULL) {
                return "Too many arguments to directive";
            }
            envclause = subs;
        }
        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_onsuccess && cmd->info != &hdr_out_always)
                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) {
                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;
            }
            else if (strncasecmp(envclause, "expr=", 5) == 0) {
                const char *err = NULL;
                expr = ap_expr_parse_cmd(cmd, envclause + 5, 0, &err, NULL);
                if (err) {
                    return apr_pstrcat(cmd->pool,
                                       "Can't parse envclause/expression: ", err,
                                       NULL);
                }
            }
            else {
                return apr_pstrcat(cmd->pool, "Unknown parameter: ", envclause,
                                   NULL);
            }
        }
    
        if ((colon = ap_strchr_c(hdr, ':'))) {
            hdr = apr_pstrmemdup(cmd->pool, hdr, colon-hdr);
        }
    
        new->header = hdr;
        new->condition_var = condition_var;
        new->expr = expr;
    
        return parse_format_string(cmd, 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;
        const char *subs;
    
        action = ap_getword_conf(cmd->temp_pool, &args);
        if (cmd->info == &hdr_out_onsuccess) {
            if (!strcasecmp(action, "always")) {
                cmd->info = &hdr_out_always;
                action = ap_getword_conf(cmd->temp_pool, &args);
            }
            else if (!strcasecmp(action, "onsuccess")) {
                action = ap_getword_conf(cmd->temp_pool, &args);
            }
        }
        hdr = ap_getword_conf(cmd->pool, &args);
        val = *args ? ap_getword_conf(cmd->pool, &args) : NULL;
        subs = *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, subs, 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.
     * If the original value was prefixed with "expr=", processing is
     * handled instead by ap_expr.
     */
    static char* process_tags(header_entry *hdr, request_rec *r)
    {
        int i;
        const char *s;
        char *str = NULL;
        format_tag *tag = NULL;
    
        if (hdr->expr_out) { 
            const char *err;
            const char *val;
            val = ap_expr_str_exec(r, hdr->expr_out, &err);
            if (err) { 
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02557)
                              "Can't evaluate value expression: %s", err);
                return "";
            }
            return apr_pstrdup(r->pool, val);
        }
    
        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 const char *process_regexp(header_entry *hdr, const char *value,
                                      request_rec *r)
    {
        ap_regmatch_t pmatch[AP_MAX_REG_MATCH];
        const char *subs;
        const char *remainder;
        char *ret;
        int diffsz;
        if (ap_regexec(hdr->regex, value, AP_MAX_REG_MATCH, pmatch, 0)) {
            /* no match, nothing to do */
            return value;
        }
        /* Process tags in the input string rather than the resulting
           * substitution to avoid surprises
           */
        subs = ap_pregsub(r->pool, process_tags(hdr, r), value, AP_MAX_REG_MATCH, pmatch);
        if (subs == NULL)
            return NULL;
        diffsz = strlen(subs) - (pmatch[0].rm_eo - pmatch[0].rm_so);
        if (hdr->action == hdr_edit) {
            remainder = value + pmatch[0].rm_eo;
        }
        else { /* recurse to edit multiple matches if applicable */
            remainder = process_regexp(hdr, value + pmatch[0].rm_eo, r);
            if (remainder == NULL)
                return NULL;
            diffsz += strlen(remainder) - strlen(value + pmatch[0].rm_eo);
        }
        ret = apr_palloc(r->pool, strlen(value) + 1 + diffsz);
        memcpy(ret, value, pmatch[0].rm_so);
        strcpy(ret + pmatch[0].rm_so, subs);
        strcat(ret, remainder);
        return ret;
    }
    
    static int echo_header(void *v, const char *key, const char *val)
    {
        echo_do *ed = (echo_do *)v;
    
        /* If the input header (key) matches the regex, echo it intact to
         * r->headers_out.
         */
        if (!ap_regexec(ed->hdr->regex, key, 0, NULL, 0)) {
            apr_table_add(ed->r->headers_out, key, val);
        }
    
        return 1;
    }
    
    static int edit_header(void *v, const char *key, const char *val)
    {
        edit_do *ed = (edit_do *)v;
        const char *repl = process_regexp(ed->hdr, val, ed->r);
        if (repl == NULL)
            return 0;
    
        apr_table_addn(ed->t, key, repl);
        return 1;
    }
    
    static int add_them_all(void *v, const char *key, const char *val)
    {
        apr_table_t *headers = (apr_table_t *)v;
    
        apr_table_addn(headers, key, val);
        return 1;
    }
    
    static int do_headers_fixup(request_rec *r, apr_table_t *headers,
                                 apr_array_header_t *fixup, int early)
    {
        echo_do v;
        int i;
        const char *val;
    
        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;
            }
            /* Do we have an expression to evaluate? */
            else if (hdr->expr != NULL) {
                const char *err = NULL;
                int eval = ap_expr_exec(r, hdr->expr, &err);
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01501)
                                  "Failed to evaluate expression (%s) - ignoring",
                                  err);
                }
                else if (!eval) {
                    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_merge:
                val = apr_table_get(headers, hdr->header);
                if (val == NULL) {
                    apr_table_addn(headers, hdr->header, process_tags(hdr, r));
                } else {
                    char *new_val = process_tags(hdr, r);
                    apr_size_t new_val_len = strlen(new_val);
                    int tok_found = 0;
    
                    /* modified version of logic in ap_get_token() */
                    while (*val) {
                        const char *tok_start;
    
                        while (apr_isspace(*val))
                            ++val;
    
                        tok_start = val;
    
                        while (*val && *val != ',') {
                            if (*val++ == '"')
                                while (*val)
                                    if (*val++ == '"')
                                        break;
                        }
    
                        if (new_val_len == (apr_size_t)(val - tok_start)
                            && !strncmp(tok_start, new_val, new_val_len)) {
                            tok_found = 1;
                            break;
                        }
    
                        if (*val)
                            ++val;
                    }
    
                    if (!tok_found) {
                        apr_table_mergen(headers, hdr->header, new_val);
                    }
                }
                break;
            case hdr_set:
                if (r->headers_in != headers &&
                    !ap_cstr_casecmp(hdr->header, "Content-Type")) {
                     ap_set_content_type(r, process_tags(hdr, r));
                }
                apr_table_setn(headers, hdr->header, process_tags(hdr, r));
                break;
            case hdr_setifempty:
                if (NULL == apr_table_get(headers, hdr->header)) {
                    if (r->headers_in != headers &&
                        !ap_cstr_casecmp(hdr->header, "Content-Type")) {
                        ap_set_content_type(r, process_tags(hdr, r));
                    }
                    apr_table_setn(headers, hdr->header, process_tags(hdr, r));
                }
                break;
            case hdr_unset:
                apr_table_unset(headers, hdr->header);
                if (r->headers_in != headers &&
                    !ap_cstr_casecmp(hdr->header, "Content-Type")) {
                    ap_set_content_type(r, NULL);
                }
                break;
            case hdr_echo:
                v.r = r;
                v.hdr = hdr;
                apr_table_do(echo_header, &v, r->headers_in, NULL);
                break;
            case hdr_edit:
            case hdr_edit_r:
                if (!ap_cstr_casecmp(hdr->header, "Content-Type") && r->content_type) {
                    const char *repl = process_regexp(hdr, r->content_type, r);
                    if (repl == NULL)
                        return 0;
                    if (r->headers_in != headers) ap_set_content_type_ex(r, repl, 1);
                }
                if (apr_table_get(headers, hdr->header)) {
                    edit_do ed;
    
                    ed.r = r;
                    ed.hdr = hdr;
                    ed.t = apr_table_make(r->pool, 5);
                    if (!apr_table_do(edit_header, (void *) &ed, headers,
                                      hdr->header, NULL))
                        return 0;
                    apr_table_unset(headers, hdr->header);
                    apr_table_do(add_them_all, (void *) headers, ed.t, NULL);
                }
                break;
            case hdr_note:
                apr_table_setn(r->notes, process_tags(hdr, r), apr_table_get(headers, hdr->header));
                break;
     
            }
        }
        return 1;
    }
    
    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_TRACE2, 0, f->r->server, APLOGNO(01502)
                     "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, APLOGNO(01503)
                     "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) {
            if (!do_headers_fixup(r, r->headers_in, dirconf->fixup_in, 1))
                goto err;
        }
        if (dirconf->fixup_err->nelts) {
            if (!do_headers_fixup(r, r->err_headers_out, dirconf->fixup_err, 1))
                goto err;
        }
        if (dirconf->fixup_out->nelts) {
            if (!do_headers_fixup(r, r->headers_out, dirconf->fixup_out, 1))
                goto err;
        }
    
        return DECLINED;
    err:
        ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01504)
                      "Regular expression replacement failed (replacement too long?)");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    
    static const command_rec headers_cmds[] =
    {
        AP_INIT_RAW_ARGS("Header", header_cmd, &hdr_out_onsuccess, 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,
                                            format_tag_fn *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", header_request_duration);
        register_format_tag_handler("t", header_request_time);
        register_format_tag_handler("e", header_request_env_var);
        register_format_tag_handler("s", header_request_ssl_var);
        register_format_tag_handler("l", header_request_loadavg);
        register_format_tag_handler("i", header_request_idle);
        register_format_tag_handler("b", header_request_busy);
    
        return OK;
    }
    
    static int header_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                  apr_pool_t *ptemp, server_rec *s)
    {
        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);
    }
    
    AP_DECLARE_MODULE(headers) =
    {
        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 */
    };
    �������������������������������������������httpd-2.4.64/modules/metadata/mod_unique_id.c�������������������������������������������������������0000664�0001751�0001751�00000031022�14116072352�021036� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #ifdef APR_HAS_THREADS
    #include "apr_atomic.h"     /* for apr_atomic_inc32 */
    #include "mpm_common.h"     /* for ap_mpm_query */
    #endif
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_protocol.h"  /* for ap_hook_post_read_request */
    
    #define ROOT_SIZE 10
    
    typedef struct {
        unsigned int stamp;
        char root[ROOT_SIZE];
        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".
     *
     * The root is 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 root.  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 144-bits of unique_id_rec are encoded using the alphabet
     * [A-Za-z0-9@-], resulting in 24 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, 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.)
     *
     * Note: previous implementations used 32-bits of IP address plus pid
     * in place of the PRNG output in the "root" field.  This was
     * insufficient for IPv6-only hosts, required working DNS to determine
     * a unique IP address (fragile), and needed a [0, 1) second sleep
     * call at startup to avoid pid reuse.  Use of the PRNG avoids all
     * these issues.
     */
    
    /*
     * Sun Jun  7 05:43:49 CEST 1998 -- Alvaro
     * More comments:
     * 1) The UUencoding procedure 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.
     */
    
    /*
     * XXX: We should have a per-thread counter and not use cur_unique_id.counter
     * XXX: in all threads, because this is bad for performance on multi-processor
     * XXX: systems: Writing to the same address from several CPUs causes cache
     * XXX: thrashing.
     */
    static unique_id_rec cur_unique_id;
    static apr_uint32_t cur_unique_counter;
    #ifdef APR_HAS_THREADS
    static int is_threaded_mpm;
    #endif
    
    /*
     * Number of elements in the structure unique_id_rec.
     */
    #define UNIQUE_ID_REC_MAX 4
    
    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)
    {
        /*
         * 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, root);
        unique_id_rec_size[1] = sizeof(cur_unique_id.root);
        unique_id_rec_offset[2] = APR_OFFSETOF(unique_id_rec, counter);
        unique_id_rec_size[2] = sizeof(cur_unique_id.counter);
        unique_id_rec_offset[3] = APR_OFFSETOF(unique_id_rec, thread_index);
        unique_id_rec_size[3] = 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];
    
        /*
         * Calculate the size of the structure when encoded.
         */
        unique_id_rec_size_uu = (unique_id_rec_total_size*8+5)/6;
    
        return OK;
    }
    
    static void unique_id_child_init(apr_pool_t *p, server_rec *s)
    {
    #ifdef APR_HAS_THREADS
        is_threaded_mpm = 0;
        ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded_mpm);
    #endif
    
        ap_random_insecure_bytes(&cur_unique_id.root,
                                 sizeof(cur_unique_id.root));
    
        /*
         * 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.
         */
        ap_random_insecure_bytes(&cur_unique_counter,
                                 sizeof(cur_unique_counter));
    }
    
    /* Use the base64url encoding per RFC 4648, avoiding characters which
     * are not safe in URLs.  ### TODO: can switch to apr_encode_*. */
    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', '-', '_',
    };
    
    #ifndef APR_UINT16_MAX
    #define APR_UINT16_MAX 0xffffu
    #endif
    
    static const char *gen_unique_id(const request_rec *r)
    {
        char *str;
        /*
         * Buffer padded with two final bytes, used to copy the unique_id_rec
         * 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;
        apr_uint32_t counter;
        unsigned char *x,*y;
        int i,j,k;
    
        memcpy(&new_unique_id.root, &cur_unique_id.root, ROOT_SIZE);
        new_unique_id.stamp = htonl((unsigned int)apr_time_sec(r->request_time));
        new_unique_id.thread_index = htonl((unsigned int)r->connection->id);
    #ifdef APR_HAS_THREADS
        if (is_threaded_mpm)
            counter = apr_atomic_inc32(&cur_unique_counter);
        else
    #endif
            counter = cur_unique_counter++;
    
        /* The counter is two bytes for the uuencoded unique id, in network
         * byte order.
         */
        new_unique_id.counter = htons(counter % APR_UINT16_MAX);
    
        /* we'll use a temporal buffer to avoid uuencoding the possible internal
         * paddings of the original structure */
        x = (unsigned char *) &paddedbuf;
        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';
    
        return str;
    }
    
    /*
     * There are two ways the generation of a unique id can be triggered:
     *
     * - from the post_read_request hook which calls set_unique_id()
     * - from error logging via the generate_log_id hook which calls
     *   generate_log_id(). This may happen before or after set_unique_id()
     *   has been called, or not at all.
     */
    
    static int generate_log_id(const conn_rec *c, const request_rec *r,
                               const char **id)
    {
        /* we do not care about connection ids */
        if (r == NULL)
            return DECLINED;
    
        /* XXX: do we need special handling for internal redirects? */
    
        /* if set_unique_id() has been called for this request, use it */
        *id = apr_table_get(r->subprocess_env, "UNIQUE_ID");
    
        if (!*id)
            *id = gen_unique_id(r);
        return OK;
    }
    
    static int set_unique_id(request_rec *r)
    {
        const char *id = NULL;
        /* 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) {
           id = apr_table_get(r->subprocess_env, "REDIRECT_UNIQUE_ID");
        }
    
        if (!id) {
            /* if we have a log id, it was set by our generate_log_id() function
             * and we should reuse the same id
             */
            id = r->log_id;
        }
    
        if (!id) {
            id = gen_unique_id(r);
        }
    
        /* set the environment variable */
        apr_table_setn(r->subprocess_env, "UNIQUE_ID", id);
    
        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(set_unique_id, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_generate_log_id(generate_log_id, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(unique_id) = {
        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 */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_setenvif.c��������������������������������������������������������0000664�0001751�0001751�00000055254�13376023213�020713� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "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 environment 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 */
        ap_expr_info_t *expr;       /* parsed expression */
        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 ap_regex_t *is_header_regex_regex;
    
    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.
         */
        if (ap_regexec(is_header_regex_regex, 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_envvars(cmd_parms *cmd, const char *args, sei_entry *new)
    {
        const char *feature;
        int beenhere = 0;
        char *var;
    
        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_core(cmd_parms *cmd, void *mconfig,
                                         char *fname, const char *args)
    {
        char *regex;
        const char *simple_pattern;
        sei_cfg_rec *sconf;
        sei_entry *new;
        sei_entry *entries;
        int i;
        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 (new->name && !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->temp_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];
        }
    
        return add_envvars(cmd, args, new);
    }
    
    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);
    }
    
    static const char *add_setenvifexpr(cmd_parms *cmd, void *mconfig,
                                        const char *args)
    {
        char *expr;
        sei_cfg_rec *sconf;
        sei_entry *new;
        const char *err;
    
        /*
         * 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);
        /* get expr */
        expr = ap_getword_conf(cmd->pool, &args);
        if (!*expr) {
            return apr_pstrcat(cmd->pool, "Missing expression for ",
                               cmd->cmd->name, NULL);
        }
    
        new = apr_array_push(sconf->conditionals);
        new->features = apr_table_make(cmd->pool, 2);
        new->name = NULL;
        new->regex = NULL;
        new->pattern = NULL;
        new->preg = NULL;
        new->expr = ap_expr_parse_cmd(cmd, expr, 0, &err, NULL);
        if (err)
            return apr_psprintf(cmd->pool, "Could not parse expression \"%s\": %s",
                                expr, err);
    
        return add_envvars(cmd, args, new);
    }
    
    /*
     * 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("SetEnvIfExpr", add_setenvifexpr, NULL, OR_FILEINFO,
                         "an expression 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, *err;
        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];
    
            if (!b->expr) {
                /* 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->useragent_ip;
                        break;
                    case SPECIAL_SERVER_ADDR:
                        val = r->connection->local_ip;
                        break;
                    case SPECIAL_REMOTE_HOST:
                        val = ap_get_useragent_host(r, 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. This is also necessary to make
             * ap_pregsub work after evaluating an ap_expr_t which does set the
             * regexp backref data.
             */
            if (val == NULL) {
                val = "";
                val_len = 0;
            }
    
            if ((b->pattern && apr_strmatch(b->pattern, val, val_len)) ||
                (b->preg && !ap_regexec(b->preg, val, AP_MAX_REG_MATCH, regm, 0)) ||
                (b->expr && ap_expr_exec_re(r, b->expr, AP_MAX_REG_MATCH, regm, &val, &err) > 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 {
                        /*
                         * Do regex replacement, if we did not use a pattern, so
                         * either a regex or an expression and if we have a val
                         * or at least we did not use an expression.
                         * Background: We can have expressions that become true
                         * if a regex pattern in the expression does NOT match.
                         * In this case val is NULL and we should just set the
                         * value for the environment variable like in the pattern
                         * case.
                         */
                        if (!b->pattern && (val || !b->expr)) {
                            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 {
                                ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01505)
                                              "Regular expression replacement "
                                              "failed for '%s', value too long?",
                                              elts[j].key);
                                return HTTP_INTERNAL_SERVER_ERROR;
                            }
                        }
                        else {
                            apr_table_setn(r->subprocess_env, elts[j].key,
                                           elts[j].val);
                        }
                    }
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "Setting %s",
                                  elts[j].key);
                }
            }
        }
    
        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);
    
        is_header_regex_regex = ap_pregcomp(p, "^[-A-Za-z0-9_]*$",
                                            (AP_REG_EXTENDED | AP_REG_NOSUB ));
        ap_assert(is_header_regex_regex != NULL);
    }
    
    AP_DECLARE_MODULE(setenvif) =
    {
        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 */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_usertrack.c�������������������������������������������������������0000664�0001751�0001751�00000041014�13650305302�021055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "http_log.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;
        const char *cookie_name;
        const 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 */
        int is_secure;
        int is_httponly;
        const char *samesite;
    } 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);
        char cookiebuf[2 * (sizeof(apr_uint64_t) + sizeof(int)) + 2];
        unsigned int random;
        apr_time_t now = r->request_time ? r->request_time : apr_time_now();
        char *new_cookie;
        cookie_dir_rec *dcfg;
    
        ap_random_insecure_bytes(&random, sizeof(random));
        apr_snprintf(cookiebuf, sizeof(cookiebuf), "%x.%" APR_UINT64_T_HEX_FMT,
                     random, (apr_uint64_t)now);
        dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module);
        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);
        }
        if (dcfg->samesite != NULL) {
            new_cookie = apr_pstrcat(r->pool, new_cookie, "; ",
                                     dcfg->samesite,
                                     NULL);
        }
        if (dcfg->is_secure) {
            new_cookie = apr_pstrcat(r->pool, new_cookie, "; Secure",
                                     NULL);
        }
        if (dcfg->is_httponly) {
            new_cookie = apr_pstrcat(r->pool, new_cookie, "; HttpOnly",
                                     NULL);
        }
    
    
    
        apr_table_addn(r->err_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 */
    }
    
    /* 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;
                int err = 0;
                /* 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 (cookieval == NULL)
                        err = 1;
                }
                if (regm[2].rm_so != -1) {
                    cookieval = ap_pregsub(r->pool, "$2", cookie_header,
                                           NUM_SUBS, regm);
                    if (cookieval == NULL)
                        err = 1;
                }
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01499)
                                  "Failed to extract cookie value (out of mem?)");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                /* 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->style = CT_UNSET;
        /* calloc'ed to disabled: enabled, cookie_domain, samesite, is_secure,
         * is_httponly */
    
        /* 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_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->temp_pool, &arg);
        if (!strncasecmp(word, "plus", 1)) {
            word = ap_getword_conf(parms->temp_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->temp_pool, &arg);
            if (!word[0])
                return "bad expires code, missing <type>";
    
            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->temp_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 = 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 (!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 = 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;
    }
    
    /* 
     * SameSite enabled disabled 
     */ 
    
    static const char *set_samesite_value(cmd_parms *cmd, void *mconfig,
                                        const char *name)
    {
        cookie_dir_rec *dcfg;
    
        dcfg = (cookie_dir_rec *) mconfig;
    
        if (strcasecmp(name, "strict") == 0) {
            dcfg->samesite = "SameSite=Strict"; 
        } else if (strcasecmp(name, "lax") == 0) {
            dcfg->samesite = "SameSite=Lax"; 
        } else if (strcasecmp(name, "none") == 0) {
            dcfg->samesite = "SameSite=None"; 
        } else {
            return "CookieSameSite accepts 'Strict', 'Lax', or 'None'";
        }
    
        
        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", ap_set_flag_slot,
                     (void *)APR_OFFSETOF(cookie_dir_rec, enabled), OR_FILEINFO,
                     "whether or not to enable cookies"),
        AP_INIT_TAKE1("CookieName", set_cookie_name, NULL, OR_FILEINFO,
                      "name of the tracking cookie"),
        AP_INIT_TAKE1("CookieSameSite", set_samesite_value, NULL, OR_FILEINFO,
                      "SameSite setting"),
        AP_INIT_FLAG("CookieSecure", ap_set_flag_slot, 
                     (void *)APR_OFFSETOF(cookie_dir_rec, is_secure), OR_FILEINFO,
                     "is cookie secure"),
        AP_INIT_FLAG("CookieHttpOnly", ap_set_flag_slot, 
                     (void *)APR_OFFSETOF(cookie_dir_rec, is_httponly),OR_FILEINFO,
                     "is cookie http only"),
    
        {NULL}
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_fixups(spot_cookie,NULL,NULL,APR_HOOK_REALLY_FIRST);
    }
    
    AP_DECLARE_MODULE(usertrack) = {
        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 */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_env.c�������������������������������������������������������������0000664�0001751�0001751�00000013234�13316417514�017655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdlib.h>
    #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 preceded 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, APLOGNO(01506)
                         "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_;
    
        if (ap_strchr_c(name, '=')) {
            char *env, *plast;
    
            env = apr_strtok(apr_pstrdup(cmd->temp_pool, name), "=", &plast);
    
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(10032)
                         "Spurious usage of '=' in an environment variable name. "
                         "'%s %s %s' expected instead?", cmd->cmd->name, env, plast);
        }
    
        /* 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)
    {
        env_dir_config_rec *sconf = ap_get_module_config(r->per_dir_config,
                                                         &env_module);
    
        if (apr_is_empty_table(sconf->vars)) {
            return DECLINED;
        }
    
        r->subprocess_env = apr_table_overlay(r->pool, r->subprocess_env,
                sconf->vars);
    
        return OK;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_fixups(fixup_env_module, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(env) =
    {
        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 */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_cern_meta.mak�����������������������������������������������������0000664�0001751�0001751�00000023765�12701473373�021364� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_cern_meta.dsp
    !IF "$(CFG)" == ""
    CFG=mod_cern_meta - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_cern_meta - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_cern_meta - Win32 Release" && "$(CFG)" != "mod_cern_meta - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cern_meta - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cern_meta.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_cern_meta.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cern_meta.obj"
    	-@erase "$(INTDIR)\mod_cern_meta.res"
    	-@erase "$(INTDIR)\mod_cern_meta_src.idb"
    	-@erase "$(INTDIR)\mod_cern_meta_src.pdb"
    	-@erase "$(OUTDIR)\mod_cern_meta.exp"
    	-@erase "$(OUTDIR)\mod_cern_meta.lib"
    	-@erase "$(OUTDIR)\mod_cern_meta.pdb"
    	-@erase "$(OUTDIR)\mod_cern_meta.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cern_meta_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cern_meta.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cern_meta.so" /d LONG_NAME="cern_meta_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cern_meta.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cern_meta.pdb" /debug /out:"$(OUTDIR)\mod_cern_meta.so" /implib:"$(OUTDIR)\mod_cern_meta.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cern_meta.obj" \
    	"$(INTDIR)\mod_cern_meta.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_cern_meta.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_cern_meta.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cern_meta.so"
       if exist .\Release\mod_cern_meta.so.manifest mt.exe -manifest .\Release\mod_cern_meta.so.manifest -outputresource:.\Release\mod_cern_meta.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_cern_meta - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cern_meta.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_cern_meta.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cern_meta.obj"
    	-@erase "$(INTDIR)\mod_cern_meta.res"
    	-@erase "$(INTDIR)\mod_cern_meta_src.idb"
    	-@erase "$(INTDIR)\mod_cern_meta_src.pdb"
    	-@erase "$(OUTDIR)\mod_cern_meta.exp"
    	-@erase "$(OUTDIR)\mod_cern_meta.lib"
    	-@erase "$(OUTDIR)\mod_cern_meta.pdb"
    	-@erase "$(OUTDIR)\mod_cern_meta.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cern_meta_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cern_meta.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cern_meta.so" /d LONG_NAME="cern_meta_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cern_meta.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cern_meta.pdb" /debug /out:"$(OUTDIR)\mod_cern_meta.so" /implib:"$(OUTDIR)\mod_cern_meta.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cern_meta.obj" \
    	"$(INTDIR)\mod_cern_meta.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_cern_meta.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_cern_meta.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cern_meta.so"
       if exist .\Debug\mod_cern_meta.so.manifest mt.exe -manifest .\Debug\mod_cern_meta.so.manifest -outputresource:.\Debug\mod_cern_meta.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_cern_meta.dep")
    !INCLUDE "mod_cern_meta.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_cern_meta.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_cern_meta - Win32 Release" || "$(CFG)" == "mod_cern_meta - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_cern_meta - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_cern_meta - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cern_meta - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_cern_meta - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cern_meta - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_cern_meta - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_cern_meta - Win32 Release"
    
    
    "$(INTDIR)\mod_cern_meta.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cern_meta.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_cern_meta.so" /d LONG_NAME="cern_meta_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_cern_meta - Win32 Debug"
    
    
    "$(INTDIR)\mod_cern_meta.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cern_meta.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_cern_meta.so" /d LONG_NAME="cern_meta_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_cern_meta.c
    
    "$(INTDIR)\mod_cern_meta.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������httpd-2.4.64/modules/metadata/mod_ident.mak���������������������������������������������������������0000664�0001751�0001751�00000023225�12701473373�020521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_ident.dsp
    !IF "$(CFG)" == ""
    CFG=mod_ident - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_ident - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_ident - Win32 Release" && "$(CFG)" != "mod_ident - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ident - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ident.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_ident.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ident.obj"
    	-@erase "$(INTDIR)\mod_ident.res"
    	-@erase "$(INTDIR)\mod_ident_src.idb"
    	-@erase "$(INTDIR)\mod_ident_src.pdb"
    	-@erase "$(OUTDIR)\mod_ident.exp"
    	-@erase "$(OUTDIR)\mod_ident.lib"
    	-@erase "$(OUTDIR)\mod_ident.pdb"
    	-@erase "$(OUTDIR)\mod_ident.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ident_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ident.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ident.so" /d LONG_NAME="ident_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ident.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ident.pdb" /debug /out:"$(OUTDIR)\mod_ident.so" /implib:"$(OUTDIR)\mod_ident.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ident.obj" \
    	"$(INTDIR)\mod_ident.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_ident.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_ident.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ident.so"
       if exist .\Release\mod_ident.so.manifest mt.exe -manifest .\Release\mod_ident.so.manifest -outputresource:.\Release\mod_ident.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_ident - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ident.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_ident.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ident.obj"
    	-@erase "$(INTDIR)\mod_ident.res"
    	-@erase "$(INTDIR)\mod_ident_src.idb"
    	-@erase "$(INTDIR)\mod_ident_src.pdb"
    	-@erase "$(OUTDIR)\mod_ident.exp"
    	-@erase "$(OUTDIR)\mod_ident.lib"
    	-@erase "$(OUTDIR)\mod_ident.pdb"
    	-@erase "$(OUTDIR)\mod_ident.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ident_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ident.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ident.so" /d LONG_NAME="ident_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ident.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ident.pdb" /debug /out:"$(OUTDIR)\mod_ident.so" /implib:"$(OUTDIR)\mod_ident.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ident.obj" \
    	"$(INTDIR)\mod_ident.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_ident.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_ident.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ident.so"
       if exist .\Debug\mod_ident.so.manifest mt.exe -manifest .\Debug\mod_ident.so.manifest -outputresource:.\Debug\mod_ident.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_ident.dep")
    !INCLUDE "mod_ident.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_ident.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_ident - Win32 Release" || "$(CFG)" == "mod_ident - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_ident - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_ident - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ident - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_ident - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ident - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_ident - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_ident - Win32 Release"
    
    
    "$(INTDIR)\mod_ident.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ident.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_ident.so" /d LONG_NAME="ident_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_ident - Win32 Debug"
    
    
    "$(INTDIR)\mod_ident.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ident.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_ident.so" /d LONG_NAME="ident_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_ident.c
    
    "$(INTDIR)\mod_ident.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_usertrack.mak�����������������������������������������������������0000664�0001751�0001751�00000023765�12701473373�021432� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_usertrack.dsp
    !IF "$(CFG)" == ""
    CFG=mod_usertrack - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_usertrack - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_usertrack - Win32 Release" && "$(CFG)" != "mod_usertrack - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_usertrack - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_usertrack.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_usertrack.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_usertrack.obj"
    	-@erase "$(INTDIR)\mod_usertrack.res"
    	-@erase "$(INTDIR)\mod_usertrack_src.idb"
    	-@erase "$(INTDIR)\mod_usertrack_src.pdb"
    	-@erase "$(OUTDIR)\mod_usertrack.exp"
    	-@erase "$(OUTDIR)\mod_usertrack.lib"
    	-@erase "$(OUTDIR)\mod_usertrack.pdb"
    	-@erase "$(OUTDIR)\mod_usertrack.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_usertrack_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_usertrack.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_usertrack.so" /d LONG_NAME="usertrack_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_usertrack.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_usertrack.pdb" /debug /out:"$(OUTDIR)\mod_usertrack.so" /implib:"$(OUTDIR)\mod_usertrack.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_usertrack.obj" \
    	"$(INTDIR)\mod_usertrack.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_usertrack.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_usertrack.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_usertrack.so"
       if exist .\Release\mod_usertrack.so.manifest mt.exe -manifest .\Release\mod_usertrack.so.manifest -outputresource:.\Release\mod_usertrack.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_usertrack - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_usertrack.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_usertrack.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_usertrack.obj"
    	-@erase "$(INTDIR)\mod_usertrack.res"
    	-@erase "$(INTDIR)\mod_usertrack_src.idb"
    	-@erase "$(INTDIR)\mod_usertrack_src.pdb"
    	-@erase "$(OUTDIR)\mod_usertrack.exp"
    	-@erase "$(OUTDIR)\mod_usertrack.lib"
    	-@erase "$(OUTDIR)\mod_usertrack.pdb"
    	-@erase "$(OUTDIR)\mod_usertrack.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_usertrack_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_usertrack.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_usertrack.so" /d LONG_NAME="usertrack_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_usertrack.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_usertrack.pdb" /debug /out:"$(OUTDIR)\mod_usertrack.so" /implib:"$(OUTDIR)\mod_usertrack.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_usertrack.obj" \
    	"$(INTDIR)\mod_usertrack.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_usertrack.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_usertrack.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_usertrack.so"
       if exist .\Debug\mod_usertrack.so.manifest mt.exe -manifest .\Debug\mod_usertrack.so.manifest -outputresource:.\Debug\mod_usertrack.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_usertrack.dep")
    !INCLUDE "mod_usertrack.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_usertrack.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_usertrack - Win32 Release" || "$(CFG)" == "mod_usertrack - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_usertrack - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_usertrack - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_usertrack - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_usertrack - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_usertrack - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_usertrack - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_usertrack - Win32 Release"
    
    
    "$(INTDIR)\mod_usertrack.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_usertrack.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_usertrack.so" /d LONG_NAME="usertrack_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_usertrack - Win32 Debug"
    
    
    "$(INTDIR)\mod_usertrack.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_usertrack.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_usertrack.so" /d LONG_NAME="usertrack_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_usertrack.c
    
    "$(INTDIR)\mod_usertrack.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������httpd-2.4.64/modules/metadata/mod_mime_magic.c������������������������������������������������������0000664�0001751�0001751�00000220474�14636331332�021161� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <ikluft@cisco.com>
     * 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 <unistd.h>
    #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 <utime.h>
    #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;             /* suppress 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 const char *const 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 const struct names {
        const char *name;
        short type;
    } names[] = {
    
        /* These must be sorted by eye for optimal hit rate */
        /* Add to this list only after substantial meditation */
        {
            "<html>", L_HTML
        },
        {
            "<HTML>", L_HTML
        },
        {
            "<head>", L_HTML
        },
        {
            "<HEAD>", L_HTML
        },
        {
            "<title>", 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 {
        const 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;
    } 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, const 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, APLOGNO(01507)
                        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, const 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, apr_pstrdup(r->pool, 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, APLOGNO(01508)
                 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 */
    
        char *tmp;
        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, APLOGNO(01509)
                                    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, APLOGNO(01510)
                                    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 */
        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_ex(r, tmp, 1);
    
        if (state == rsl_encoding) {
            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, APLOGNO(01511)
                          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, APLOGNO(01512)
                        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, APLOGNO(01513)
                        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, APLOGNO(01514)
                         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, APLOGNO(01515)
                         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 since an
                                                   * "empty" line contains a '\n'
                                                   */
    
            /* delete newline and any other trailing whitespace */
            while (last >= line
                   && apr_isspace(*last)) {
                *last = '\0';
                --last;
            }
    
            /* 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, APLOGNO(01516)
                    MODNAME ": apprentice conf=%pp 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, APLOGNO(01517)
                    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, APLOGNO(01518)
                    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, APLOGNO(01519)
                            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, APLOGNO(01520)
                            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, APLOGNO(01521)
                        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, APLOGNO(01522)
                            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, APLOGNO(01523)
                            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, APLOGNO(01524)
                        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;
        apr_cpystrn(m->desc, l, sizeof(m->desc));
    
    #if MIME_MAGIC_DEBUG
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, serv, APLOGNO(01525)
                    MODNAME ": parse line=%d m=%pp next=%pp 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, APLOGNO(01526)
                            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, APLOGNO(01527)
                        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, APLOGNO(01528)
                          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, APLOGNO(01529)
                    MODNAME ": match conf=%pp 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, APLOGNO(01530)
                            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, APLOGNO(01531)
                        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, APLOGNO(01532)
                            MODNAME ": line=%d mc=%pp mc->next=%pp 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, APLOGNO(01533)
                        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, APLOGNO(01534)
                            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, APLOGNO(01535)
                        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, APLOGNO(01536)
                    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, APLOGNO(01537)
                        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, APLOGNO(01538)
                        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, APLOGNO(01539)
                        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, APLOGNO(01540)
                        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, APLOGNO(01541)
                        "%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, APLOGNO(01542)
                        "%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, APLOGNO(01543)
                        "%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, APLOGNO(01544)
                            "%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, APLOGNO(01545)
                            "%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, APLOGNO(01546)
                            "%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, APLOGNO(01547)
                            "%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, APLOGNO(01548)
                        "((%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, APLOGNO(01549)
                        "((%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, APLOGNO(01550)
                        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[SMALL_HOWMANY + 1];  /* one extra for terminating '\0' */
        char *token;
        const 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 const struct {
        const char *magic;
        apr_size_t maglen;
        const char *argv[3];
        int silent;
        const 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"
        },
    };
    
    #define 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, HOWMANY)) > 0) {
            /* set encoding type in the request record */
            r->content_encoding = compr[i].encoding;
    
            newbuf[newsize-1] = '\0';  /* null-terminate uncompressed data */
            /* Try to detect the content type of the uncompressed data */
            if (tryit(r, newbuf, newsize, 0) != OK) {
                return 0;
            }
        }
        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];
        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?
         */
    
        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,
                                  ap_make_dirstr_parent(r->pool, r->filename)) != APR_SUCCESS) ||
            (apr_procattr_cmdtype_set(procattr, APR_PROGRAM_PATH) != APR_SUCCESS)) {
            /* Something bad happened, tell the world. */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOPROC, r, APLOGNO(01551)
                   "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, NULL, 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, APLOGNO(01552)
                              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 indices with mod_autoindex)
         * where we would end up with LOTS of zombies.
         */
        if (apr_pool_create(&sub_context, r->pool) != APR_SUCCESS)
            return -1;
        apr_pool_tag(sub_context, "magic_uncompress");
    
        if ((rv = create_uncompress_child(&parm, sub_context, &pipe_out)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01553)
                        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, APLOGNO(01554)
                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, APLOGNO(01555)
                    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, APLOGNO(01556)
                    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_ex(r, apr_pstrdup(r->pool, sub->content_type), 1);
    #if MIME_MAGIC_DEBUG
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01557)
                        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, APLOGNO(01558)
                            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, APLOGNO(01559)
                                    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 == APR_NOFILE || !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
     */
    
    AP_DECLARE_MODULE(mime_magic) =
    {
        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 */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_remoteip.c��������������������������������������������������������0000664�0001751�0001751�00000127052�13607376315�020723� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     *
     * Portions of the input filter code for PROXY protocol support is
     * Copyright 2014 Cloudzilla Inc.
     */
    
    #include "ap_config.h"
    #include "ap_mmn.h"
    #include "ap_listen.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "http_connection.h"
    #include "http_protocol.h"
    #include "http_log.h"
    #include "http_main.h"
    #include "apr_strings.h"
    #include "apr_lib.h"
    #define APR_WANT_BYTEFUNC
    #include "apr_want.h"
    #include "apr_network_io.h"
    #include "apr_version.h"
    
    module AP_MODULE_DECLARE_DATA remoteip_module;
    
    typedef struct {
        /** A proxy IP mask to match */
        apr_ipsubnet_t *ip;
        /** Flagged if internal, otherwise an external trusted proxy */
        void  *internal;
    } remoteip_proxymatch_t;
    
    typedef struct remoteip_addr_info {
        struct remoteip_addr_info *next;
        apr_sockaddr_t *addr;
        server_rec *source;
    } remoteip_addr_info;
    
    typedef struct {
        /** The header to retrieve a proxy-via IP list */
        const char *header_name;
        /** A header to record the proxied IP's
         * (removed as the physical connection and
         * from the proxy-via IP header value list)
         */
        const char *proxies_header_name;
        /** A list of trusted proxies, ideally configured
         *  with the most commonly encountered listed first
         */
        apr_array_header_t *proxymatch_ip;
    
        remoteip_addr_info *proxy_protocol_enabled;
        remoteip_addr_info *proxy_protocol_disabled;
    
        apr_array_header_t *disabled_subnets;
        apr_pool_t *pool;
    } remoteip_config_t;
    
    typedef struct {
        apr_sockaddr_t *useragent_addr;
        char *useragent_ip;
        /** The list of proxy IP's ignored as remote IP's */
        const char *proxy_ips;
        /** The remaining list of untrusted proxied remote IP's */
        const char *proxied_remote;
    } remoteip_req_t;
    
    /* For PROXY protocol processing */
    static ap_filter_rec_t *remoteip_filter;
    
    typedef struct {
        char line[108];
    } proxy_v1;
    
    typedef union {
        struct {        /* for TCP/UDP over IPv4, len = 12 */
            apr_uint32_t src_addr;
            apr_uint32_t dst_addr;
            apr_uint16_t src_port;
            apr_uint16_t dst_port;
        } ip4;
        struct {        /* for TCP/UDP over IPv6, len = 36 */
             apr_byte_t  src_addr[16];
             apr_byte_t  dst_addr[16];
             apr_uint16_t src_port;
             apr_uint16_t dst_port;
        } ip6;
        struct {        /* for AF_UNIX sockets, len = 216 */
             apr_byte_t src_addr[108];
             apr_byte_t dst_addr[108];
        } unx;
    } proxy_v2_addr;
    
    typedef struct {
        apr_byte_t  sig[12];  /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */
        apr_byte_t  ver_cmd;  /* protocol version and command */
        apr_byte_t  fam;      /* protocol family and address */
        apr_uint16_t len;     /* number of following bytes part of the header */
        proxy_v2_addr addr;
    } proxy_v2;
    
    typedef union {
            proxy_v1 v1;
            proxy_v2 v2;
    } proxy_header;
    
    static const char v2sig[12] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A";
    #define MIN_V1_HDR_LEN 15
    #define MIN_V2_HDR_LEN 16
    #define MIN_HDR_LEN MIN_V1_HDR_LEN
    
    /* XXX: Unsure if this is needed if v6 support is not available on
       this platform */
    #ifndef INET6_ADDRSTRLEN
    #define INET6_ADDRSTRLEN 46
    #endif
    
    typedef struct {
        char header[sizeof(proxy_header)];
        apr_size_t rcvd;
        apr_size_t need;
        int version;
        ap_input_mode_t mode;
        apr_bucket_brigade *bb;
        int done;
    } remoteip_filter_context;
    
    /** Holds the resolved proxy info for this connection and any additional
      configurable parameters
    */
    typedef struct {
        /** The parsed client address in native format */
        apr_sockaddr_t *client_addr;
        /** Character representation of the client */
        char *client_ip;
    } remoteip_conn_config_t;
    
    typedef enum { HDR_DONE, HDR_ERROR, HDR_NEED_MORE } remoteip_parse_status_t;
    
    static void *create_remoteip_server_config(apr_pool_t *p, server_rec *s)
    {
        remoteip_config_t *config = apr_pcalloc(p, sizeof(*config));
        config->disabled_subnets = apr_array_make(p, 1, sizeof(apr_ipsubnet_t *));
        /* config->header_name = NULL;
         * config->proxies_header_name = NULL;
         * config->proxy_protocol_enabled = NULL;
         * config->proxy_protocol_disabled = NULL;
         */
        config->pool = p;
        return config;
    }
    
    static void *merge_remoteip_server_config(apr_pool_t *p, void *globalv,
                                              void *serverv)
    {
        remoteip_config_t *global = (remoteip_config_t *) globalv;
        remoteip_config_t *server = (remoteip_config_t *) serverv;
        remoteip_config_t *config;
    
        config = (remoteip_config_t *) apr_palloc(p, sizeof(*config));
        config->header_name = server->header_name
                            ? server->header_name
                            : global->header_name;
        config->proxies_header_name = server->proxies_header_name
                                    ? server->proxies_header_name
                                    : global->proxies_header_name;
        config->proxymatch_ip = server->proxymatch_ip
                              ? server->proxymatch_ip
                              : global->proxymatch_ip;
        return config;
    }
    
    static const char *header_name_set(cmd_parms *cmd, void *dummy,
                                       const char *arg)
    {
        remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
                                                         &remoteip_module);
        config->header_name = arg;
        return NULL;
    }
    
    static const char *proxies_header_name_set(cmd_parms *cmd, void *dummy,
                                               const char *arg)
    {
        remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
                                                         &remoteip_module);
        config->proxies_header_name = arg;
        return NULL;
    }
    
    /* Would be quite nice if APR exported this */
    /* apr:network_io/unix/sockaddr.c */
    static int looks_like_ip(const char *ipstr)
    {
        if (ap_strchr_c(ipstr, ':')) {
            /* definitely not a hostname; assume it is intended to be an IPv6 address */
            return 1;
        }
    
        /* simple IPv4 address string check */
        while ((*ipstr == '.') || apr_isdigit(*ipstr))
            ipstr++;
        return (*ipstr == '\0');
    }
    
    static const char *proxies_set(cmd_parms *cmd, void *cfg,
                                   const char *arg)
    {
        remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
                                                         &remoteip_module);
        remoteip_proxymatch_t *match;
        apr_status_t rv;
        char *ip = apr_pstrdup(cmd->temp_pool, arg);
        char *s = ap_strchr(ip, '/');
        if (s) {
            *s++ = '\0';
        }
    
        if (!config->proxymatch_ip) {
            config->proxymatch_ip = apr_array_make(cmd->pool, 1, sizeof(*match));
        }
        match = (remoteip_proxymatch_t *) apr_array_push(config->proxymatch_ip);
        match->internal = cmd->info;
    
        if (looks_like_ip(ip)) {
            /* Note s may be null, that's fine (explicit host) */
            rv = apr_ipsubnet_create(&match->ip, ip, s, cmd->pool);
        }
        else
        {
            apr_sockaddr_t *temp_sa;
    
            if (s) {
                return apr_pstrcat(cmd->pool, "RemoteIP: Error parsing IP ", arg,
                                   " the subnet /", s, " is invalid for ",
                                   cmd->cmd->name, NULL);
            }
    
            rv = apr_sockaddr_info_get(&temp_sa,  ip, APR_UNSPEC, 0,
                                       APR_IPV4_ADDR_OK, cmd->temp_pool);
            while (rv == APR_SUCCESS)
            {
                apr_sockaddr_ip_get(&ip, temp_sa);
                rv = apr_ipsubnet_create(&match->ip, ip, NULL, cmd->pool);
                if (!(temp_sa = temp_sa->next)) {
                    break;
                }
                match = (remoteip_proxymatch_t *)
                        apr_array_push(config->proxymatch_ip);
                match->internal = cmd->info;
            }
        }
    
        if (rv != APR_SUCCESS) {
            return apr_psprintf(cmd->pool,
                                "RemoteIP: Error parsing IP %s (%pm error) for %s",
                                arg, &rv, cmd->cmd->name);
        }
    
        return NULL;
    }
    
    static const char *proxylist_read(cmd_parms *cmd, void *cfg,
                                      const char *filename)
    {
        char lbuf[MAX_STRING_LEN];
        char *arg;
        const char *args;
        const char *errmsg;
        ap_configfile_t *cfp;
        apr_status_t rv;
    
        filename = ap_server_root_relative(cmd->temp_pool, filename);
        rv = ap_pcfg_openfile(&cfp, cmd->temp_pool, filename);
        if (rv != APR_SUCCESS) {
            return apr_psprintf(cmd->pool, "%s: Could not open file %s: %pm",
                                cmd->cmd->name, filename, &rv);
        }
    
        while (!(ap_cfg_getline(lbuf, MAX_STRING_LEN, cfp))) {
            args = lbuf;
            while (*(arg = ap_getword_conf(cmd->temp_pool, &args)) != '\0') {
                if (*arg == '#') {
                    break;
                }
                errmsg = proxies_set(cmd, cfg, arg);
                if (errmsg) {
                    ap_cfg_closefile(cfp);
                    errmsg = apr_psprintf(cmd->pool, "%s at line %d of %s",
                                          errmsg, cfp->line_number, filename);
                    return errmsg;
                }
            }
        }
    
        ap_cfg_closefile(cfp);
        return NULL;
    }
    
    /** Similar to apr_sockaddr_equal, except that it compares ports too. */
    static int remoteip_sockaddr_equal(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2)
    {
        return (addr1->port == addr2->port && apr_sockaddr_equal(addr1, addr2));
    }
    
    #if !APR_VERSION_AT_LEAST(1,5,0)
    #define apr_sockaddr_is_wildcard sockaddr_is_wildcard
    /* XXX: temp build fix from apr 1.5.x */
    static int sockaddr_is_wildcard(const apr_sockaddr_t *addr)
    {
        static const char inaddr_any[
    #if APR_HAVE_IPV6
            sizeof(struct in6_addr)
    #else
            sizeof(struct in_addr)
    #endif
        ] = {0};
    
        if (addr->ipaddr_ptr /* IP address initialized */
            && addr->ipaddr_len <= sizeof inaddr_any) { /* else bug elsewhere? */
            if (!memcmp(inaddr_any, addr->ipaddr_ptr, addr->ipaddr_len)) {
                return 1;
            }
    #if APR_HAVE_IPV6
        if (addr->family == AF_INET6
            && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr)) {
            struct in_addr *v4 = (struct in_addr *)&((apr_uint32_t *)addr->ipaddr_ptr)[3];
    
            if (!memcmp(inaddr_any, v4, sizeof *v4)) {
                return 1;
            }
        }
    #endif
        }
        return 0;
    }
    #endif
    
    
    /** Similar to remoteip_sockaddr_equal, except that it handles wildcard addresses
     *  and ports too.
     */
    static int remoteip_sockaddr_compat(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2)
    {
        /* test exact address equality */
        if (apr_sockaddr_equal(addr1, addr2) &&
            (addr1->port == addr2->port || addr1->port == 0 || addr2->port == 0)) {
            return 1;
        }
    
        /* test address wildcards */
        if (apr_sockaddr_is_wildcard(addr1) &&
            (addr1->port == 0 || addr1->port == addr2->port)) {
            return 1;
        }
    
        if (apr_sockaddr_is_wildcard(addr2) &&
            (addr2->port == 0 || addr2->port == addr1->port)) {
            return 1;
        }
    
        return 0;
    }
    
    static int remoteip_addr_in_list(remoteip_addr_info *list, apr_sockaddr_t *addr)
    {
        for (; list; list = list->next) {
            if (remoteip_sockaddr_compat(list->addr, addr)) {
                return 1;
            }
        }
    
        return 0;
    }
    
    static void remoteip_warn_enable_conflict(remoteip_addr_info *prev, server_rec *new, int flag)
    {
        char buf[INET6_ADDRSTRLEN];
    
        apr_sockaddr_ip_getbuf(buf, sizeof(buf), prev->addr);
    
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, new, APLOGNO(03491)
                     "RemoteIPProxyProtocol: previous setting for %s:%hu from virtual "
                     "host {%s:%hu in %s} is being overridden by virtual host "
                     "{%s:%hu in %s}; new setting is '%s'",
                     buf, prev->addr->port, prev->source->server_hostname,
                     prev->source->addrs->host_port, prev->source->defn_name,
                     new->server_hostname, new->addrs->host_port, new->defn_name,
                     flag ? "On" : "Off");
    }
    
    static const char *remoteip_enable_proxy_protocol(cmd_parms *cmd, void *config,
                                                      int flag)
    {
        remoteip_config_t *conf;
        server_addr_rec *addr;
        remoteip_addr_info **add;
        remoteip_addr_info **rem;
        remoteip_addr_info *list;
    
        conf = ap_get_module_config(ap_server_conf->module_config,
                                    &remoteip_module);
    
        if (flag) {
            add = &conf->proxy_protocol_enabled;
            rem = &conf->proxy_protocol_disabled;
        }
        else {
            add = &conf->proxy_protocol_disabled;
            rem = &conf->proxy_protocol_enabled;
        }
    
        for (addr = cmd->server->addrs; addr; addr = addr->next) {
            /* remove address from opposite list */
            if (*rem) {
                if (remoteip_sockaddr_equal((*rem)->addr, addr->host_addr)) {
                    remoteip_warn_enable_conflict(*rem, cmd->server, flag);
                    *rem = (*rem)->next;
                }
                else {
                    for (list = *rem; list->next; list = list->next) {
                        if (remoteip_sockaddr_equal(list->next->addr, addr->host_addr)) {
                            remoteip_warn_enable_conflict(list->next, cmd->server, flag);
                            list->next = list->next->next;
                            break;
                        }
                    }
                }
            }
    
            /* add address to desired list */
            if (!remoteip_addr_in_list(*add, addr->host_addr)) {
                remoteip_addr_info *info = apr_palloc(conf->pool, sizeof(*info));
                info->addr = addr->host_addr;
                info->source = cmd->server;
                info->next = *add;
                *add = info;
            }
        }
    
        return NULL;
    }
    
    static const char *remoteip_disable_networks(cmd_parms *cmd, void *d,
                                                 int argc, char *const argv[])
    {
        int i;
        apr_pool_t *ptemp = cmd->temp_pool;
        apr_pool_t *p = cmd->pool;
        remoteip_config_t *conf = ap_get_module_config(ap_server_conf->module_config,
                                    &remoteip_module);
    
        if (argc == 0)
            return apr_pstrcat(p, cmd->cmd->name, " requires an argument", NULL);
    
    
        for (i=0; i<argc; i++) {
            char *addr = apr_pstrdup(ptemp, argv[i]);
            char *mask;
            apr_status_t rv;
            apr_ipsubnet_t **ip = apr_pcalloc(p, sizeof(apr_ipsubnet_t *));
    
            if ((mask = ap_strchr(addr, '/')))
                *mask++ = '\0';
    
            rv = apr_ipsubnet_create(ip, addr, mask, p);
    
            if (APR_STATUS_IS_EINVAL(rv)) {
                /* looked nothing like an IP address */
                return apr_psprintf(p, "ip address '%s' appears to be invalid", addr);
            }
            else if (rv != APR_SUCCESS) {
                return apr_psprintf(p, "ip address '%s' appears to be invalid: %pm",
                                    addr, &rv);
            }
    
            *(apr_ipsubnet_t**)apr_array_push(conf->disabled_subnets) = *ip;
        }
    
        return NULL;
    }
    
    static int remoteip_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                   apr_pool_t *ptemp, server_rec *s)
    {
        remoteip_config_t *conf;
        remoteip_addr_info *info;
        char buf[INET6_ADDRSTRLEN];
    
        conf = ap_get_module_config(ap_server_conf->module_config,
                                    &remoteip_module);
    
        for (info = conf->proxy_protocol_enabled; info; info = info->next) {
            apr_sockaddr_ip_getbuf(buf, sizeof(buf), info->addr);
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(03492)
                         "RemoteIPProxyProtocol: enabled on %s:%hu", buf, info->addr->port);
        }
        for (info = conf->proxy_protocol_disabled; info; info = info->next) {
            apr_sockaddr_ip_getbuf(buf, sizeof(buf), info->addr);
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(03494)
                         "RemoteIPProxyProtocol: disabled on %s:%hu", buf, info->addr->port);
        }
    
        return OK;
    }
    
    static int remoteip_modify_request(request_rec *r)
    {
        conn_rec *c = r->connection;
        remoteip_config_t *config = (remoteip_config_t *)
            ap_get_module_config(r->server->module_config, &remoteip_module);
        remoteip_conn_config_t *conn_config = (remoteip_conn_config_t *)
            ap_get_module_config(r->connection->conn_config, &remoteip_module);
    
        remoteip_req_t *req = NULL;
        apr_sockaddr_t *temp_sa;
    
        apr_status_t rv;
        char *remote;
        char *proxy_ips = NULL;
        char *parse_remote;
        char *eos;
        unsigned char *addrbyte;
    
        /* If no RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy
           or RemoteIPTrustedProxyList directive is configured,
           all proxies will be considered as external trusted proxies.
         */
        void *internal = NULL;
    
        /* No header defined or results from our input filter */
        if (!config->header_name && !conn_config) {
            return DECLINED;
        }
     
        /* Easy parsing case - just position the data we already have from PROXY
           protocol handling allowing it to take precedence and return
        */
        if (conn_config) {
            if (!conn_config->client_addr) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03496)
                              "RemoteIPProxyProtocol data is missing, but required! Aborting request.");
                return HTTP_BAD_REQUEST;
            }
    
            r->useragent_addr = conn_config->client_addr;
            r->useragent_ip = conn_config->client_ip;
    
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "Using %s as client's IP from PROXY protocol", r->useragent_ip);
            return OK;
        }
    
        if (config->proxymatch_ip) {
            /* This indicates that a RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy
               or RemoteIPTrustedProxyList directive is configured.
               In this case, default to internal proxy.
             */
            internal = (void *) 1;
        }
    
        remote = (char *) apr_table_get(r->headers_in, config->header_name);
        if (!remote) {
            return OK;
        }
        remote = apr_pstrdup(r->pool, remote);
    
        temp_sa = r->useragent_addr ? r->useragent_addr : c->client_addr;
    
        while (remote) {
    
            /* verify user agent IP against the trusted proxy list
             */
            if (config->proxymatch_ip) {
                int i;
                remoteip_proxymatch_t *match;
                match = (remoteip_proxymatch_t *)config->proxymatch_ip->elts;
                for (i = 0; i < config->proxymatch_ip->nelts; ++i) {
                    if (apr_ipsubnet_test(match[i].ip, temp_sa)) {
                        if (internal) {
                            /* Allow an internal proxy to present an external proxy,
                               but do not allow an external proxy to present an internal proxy.
                               In this case, the presented internal proxy will be considered external.
                             */
                            internal = match[i].internal;
                        }
                        break;
                    }
                }
                if (i && i >= config->proxymatch_ip->nelts) {
                    break;
                }
            }
    
            if ((parse_remote = strrchr(remote, ',')) == NULL) {
                parse_remote = remote;
                remote = NULL;
            }
            else {
                *(parse_remote++) = '\0';
            }
    
            while (*parse_remote == ' ') {
                ++parse_remote;
            }
    
            eos = parse_remote + strlen(parse_remote) - 1;
            while (eos >= parse_remote && *eos == ' ') {
                *(eos--) = '\0';
            }
    
            if (eos < parse_remote) {
                if (remote) {
                    *(remote + strlen(remote)) = ',';
                }
                else {
                    remote = parse_remote;
                }
                break;
            }
    
            /* We map as IPv4 rather than IPv6 for equivalent host names
             * or IPV4OVERIPV6
             */
            rv = apr_sockaddr_info_get(&temp_sa,  parse_remote,
                                       APR_UNSPEC, temp_sa->port,
                                       APR_IPV4_ADDR_OK, r->pool);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG,  rv, r, APLOGNO(01568)
                              "RemoteIP: Header %s value of %s cannot be parsed "
                              "as a client IP",
                              config->header_name, parse_remote);
    
                if (remote) {
                    *(remote + strlen(remote)) = ',';
                }
                else {
                    remote = parse_remote;
                }
                break;
            }
    
            addrbyte = (unsigned char *) &temp_sa->sa.sin.sin_addr;
    
            /* For intranet (Internal proxies) ignore all restrictions below */
            if (!internal
                  && ((temp_sa->family == APR_INET
                       /* For internet (non-Internal proxies) deny all
                        * RFC3330 designated local/private subnets:
                        * 10.0.0.0/8   169.254.0.0/16  192.168.0.0/16
                        * 127.0.0.0/8  172.16.0.0/12
                        */
                          && (addrbyte[0] == 10
                           || addrbyte[0] == 127
                           || (addrbyte[0] == 169 && addrbyte[1] == 254)
                           || (addrbyte[0] == 172 && (addrbyte[1] & 0xf0) == 16)
                           || (addrbyte[0] == 192 && addrbyte[1] == 168)))
    #if APR_HAVE_IPV6
                   || (temp_sa->family == APR_INET6
                       /* For internet (non-Internal proxies) we translated
                        * IPv4-over-IPv6-mapped addresses as IPv4, above.
                        * Accept only Global Unicast 2000::/3 defined by RFC4291
                        */
                          && ((temp_sa->sa.sin6.sin6_addr.s6_addr[0] & 0xe0) != 0x20))
    #endif
            )) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG,  rv, r, APLOGNO(01569)
                              "RemoteIP: Header %s value of %s appears to be "
                              "a private IP or nonsensical.  Ignored",
                              config->header_name, parse_remote);
                if (remote) {
                    *(remote + strlen(remote)) = ',';
                }
                else {
                    remote = parse_remote;
                }
    
                break;
            }
    
            /* save away our results */
            if (!req) {
                req = (remoteip_req_t *) apr_palloc(r->pool, sizeof(remoteip_req_t));
                req->useragent_ip = r->useragent_ip;
            }
    
            /* Set useragent_ip string */
            if (!internal) {
                if (proxy_ips) {
                    proxy_ips = apr_pstrcat(r->pool, proxy_ips, ", ",
                                            req->useragent_ip, NULL);
                }
                else {
                    proxy_ips = req->useragent_ip;
                }
            }
    
            req->useragent_addr = temp_sa;
            apr_sockaddr_ip_get(&req->useragent_ip, req->useragent_addr);
        }
    
        /* Nothing happened? */
        if (!req) {
            return OK;
        }
    
        /* Port is not known so set it to zero; otherwise it can be misleading */
        req->useragent_addr->port = 0;
    
        req->proxied_remote = remote;
        req->proxy_ips = proxy_ips;
    
        if (req->proxied_remote) {
            apr_table_setn(r->headers_in, config->header_name,
                           req->proxied_remote);
        }
        else {
            apr_table_unset(r->headers_in, config->header_name);
        }
        if (req->proxy_ips) {
            apr_table_setn(r->notes, "remoteip-proxy-ip-list", req->proxy_ips);
            if (config->proxies_header_name) {
                apr_table_setn(r->headers_in, config->proxies_header_name,
                               req->proxy_ips);
            }
        }
    
        r->useragent_addr = req->useragent_addr;
        r->useragent_ip = req->useragent_ip;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      req->proxy_ips
                          ? "Using %s as client's IP by proxies %s"
                          : "Using %s as client's IP by internal proxies%s",
                      req->useragent_ip,
                      (req->proxy_ips ? req->proxy_ips : ""));
        return OK;
    }
    
    static int remoteip_is_server_port(apr_port_t port)
    {
        ap_listen_rec *lr;
    
        for (lr = ap_listeners; lr; lr = lr->next) {
            if (lr->bind_addr && lr->bind_addr->port == port) {
                return 1;
            }
        }
    
        return 0;
    }
    
    /*
     * Human readable format:
     * PROXY {TCP4|TCP6|UNKNOWN} <client-ip-addr> <dest-ip-addr> <client-port> <dest-port><CR><LF>
     */
    static remoteip_parse_status_t remoteip_process_v1_header(conn_rec *c,
                                                              remoteip_conn_config_t *conn_conf,
                                                              proxy_header *hdr, apr_size_t len,
                                                              apr_size_t *hdr_len)
    {
        char *end, *word, *host, *valid_addr_chars, *saveptr;
        char buf[sizeof(hdr->v1.line)];
        apr_port_t port;
        apr_status_t ret;
        apr_int32_t family;
    
    #define GET_NEXT_WORD(field) \
        word = apr_strtok(NULL, " ", &saveptr); \
        if (!word) { \
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03497) \
                          "RemoteIPProxyProtocol: no " field " found in header '%s'", \
                          hdr->v1.line); \
            return HDR_ERROR; \
        }
    
        end = memchr(hdr->v1.line, '\r', len - 1);
        if (!end || end[1] != '\n') {
            return HDR_NEED_MORE; /* partial or invalid header */
        }
    
        *end = '\0';
        *hdr_len = end + 2 - hdr->v1.line; /* skip header + CRLF */
    
        /* parse in separate buffer so have the original for error messages */
        strcpy(buf, hdr->v1.line);
    
        apr_strtok(buf, " ", &saveptr);
    
        /* parse family */
        GET_NEXT_WORD("family")
        if (strcmp(word, "UNKNOWN") == 0) {
            conn_conf->client_addr = c->client_addr;
            conn_conf->client_ip = c->client_ip;
            return HDR_DONE;
        }
        else if (strcmp(word, "TCP4") == 0) {
            family = APR_INET;
            valid_addr_chars = "0123456789.";
        }
        else if (strcmp(word, "TCP6") == 0) {
    #if APR_HAVE_IPV6
            family = APR_INET6;
            valid_addr_chars = "0123456789abcdefABCDEF:";
    #else
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03498)
                          "RemoteIPProxyProtocol: Unable to parse v6 address - APR is not compiled with IPv6 support");
            return HDR_ERROR;
    #endif
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03499)
                          "RemoteIPProxyProtocol: unknown family '%s' in header '%s'",
                          word, hdr->v1.line);
            return HDR_ERROR;
        }
    
        /* parse client-addr */
        GET_NEXT_WORD("client-address")
    
        if (strspn(word, valid_addr_chars) != strlen(word)) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03500)
                          "RemoteIPProxyProtocol: invalid client-address '%s' found in "
                          "header '%s'", word, hdr->v1.line);
            return HDR_ERROR;
        }
    
        host = word;
    
        /* parse dest-addr */
        GET_NEXT_WORD("destination-address")
    
        /* parse client-port */
        GET_NEXT_WORD("client-port")
        if (sscanf(word, "%hu", &port) != 1) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03501)
                          "RemoteIPProxyProtocol: error parsing port '%s' in header '%s'",
                          word, hdr->v1.line);
            return HDR_ERROR;
        }
    
        /* parse dest-port */
        /* GET_NEXT_WORD("destination-port") - no-op since we don't care about it */
    
        /* create a socketaddr from the info */
        ret = apr_sockaddr_info_get(&conn_conf->client_addr, host, family, port, 0,
                                    c->pool);
        if (ret != APR_SUCCESS) {
            conn_conf->client_addr = NULL;
            ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03502)
                          "RemoteIPProxyProtocol: error converting family '%d', host '%s',"
                          " and port '%hu' to sockaddr; header was '%s'",
                          family, host, port, hdr->v1.line);
            return HDR_ERROR;
        }
    
        conn_conf->client_ip = apr_pstrdup(c->pool, host);
    
        return HDR_DONE;
    }
    
    /** Add our filter to the connection if it is requested
     */
    static int remoteip_hook_pre_connection(conn_rec *c, void *csd)
    {
        remoteip_config_t *conf;
        remoteip_conn_config_t *conn_conf;
        int i;
    
        /* Establish master config in slave connections, so that request processing
         * finds it. */
        if (c->master != NULL) {
            conn_conf = ap_get_module_config(c->master->conn_config, &remoteip_module);
            if (conn_conf) {
                ap_set_module_config(c->conn_config, &remoteip_module, conn_conf);
            }
            return DECLINED;
        }
    
        conf = ap_get_module_config(ap_server_conf->module_config,
                                    &remoteip_module);
    
        /* check if we're enabled for this connection */
        if (!remoteip_addr_in_list(conf->proxy_protocol_enabled, c->local_addr)
            || remoteip_addr_in_list(conf->proxy_protocol_disabled, c->local_addr)) {
    
            return DECLINED;
        }
    
        /* We are enabled for this IP/port, but check that we aren't
           explicitly disabled */
        for (i = 0; i < conf->disabled_subnets->nelts; i++) {
            apr_ipsubnet_t *ip = ((apr_ipsubnet_t**)conf->disabled_subnets->elts)[i];
    
            if (ip && apr_ipsubnet_test(ip, c->client_addr))
                return DECLINED;
        }
    
        /* mod_proxy creates outgoing connections - we don't want those */
        if (!remoteip_is_server_port(c->local_addr->port)) {
            return DECLINED;
        }
    
        /* add our filter */
        if (!ap_add_input_filter_handle(remoteip_filter, NULL, NULL, c)) {
            /* XXX: Shouldn't this WARN in log? */
            return DECLINED;
        }
    
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03503)
                      "RemoteIPProxyProtocol: enabled on connection to %s:%hu",
                      c->local_ip, c->local_addr->port);
    
        /* this holds the resolved proxy info for this connection */
        conn_conf = apr_pcalloc(c->pool, sizeof(*conn_conf));
    
        ap_set_module_config(c->conn_config, &remoteip_module, conn_conf);
    
        return OK;
    }
    
    /* Binary format:
     * <sig><cmd><proto><addr-len><addr>
     * sig = \x0D \x0A \x0D \x0A \x00 \x0D \x0A \x51 \x55 \x49 \x54 \x0A
     * cmd = <4-bits-version><4-bits-command>
     * 4-bits-version = \x02
     * 4-bits-command = {\x00|\x01}  (\x00 = LOCAL: discard con info; \x01 = PROXY)
     * proto = <4-bits-family><4-bits-protocol>
     * 4-bits-family = {\x00|\x01|\x02|\x03}  (AF_UNSPEC, AF_INET, AF_INET6, AF_UNIX)
     * 4-bits-protocol = {\x00|\x01|\x02}  (UNSPEC, STREAM, DGRAM)
     */
    static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c,
                                                  remoteip_conn_config_t *conn_conf,
                                                  proxy_header *hdr)
    {
        apr_status_t ret;
    
        switch (hdr->v2.ver_cmd & 0xF) {
            case 0x01: /* PROXY command */
                switch (hdr->v2.fam) {
                    case 0x11:  /* TCPv4 */
                        ret = apr_sockaddr_info_get(&conn_conf->client_addr, NULL,
                                                    APR_INET,
                                                    ntohs(hdr->v2.addr.ip4.src_port),
                                                    0, c->pool);
                        if (ret != APR_SUCCESS) {
                            conn_conf->client_addr = NULL;
                            ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03504)
                                          "RemoteIPPProxyProtocol: error creating sockaddr");
                            return HDR_ERROR;
                        }
    
                        conn_conf->client_addr->sa.sin.sin_addr.s_addr =
                                hdr->v2.addr.ip4.src_addr;
                        break;
    
                    case 0x21:  /* TCPv6 */
    #if APR_HAVE_IPV6
                        ret = apr_sockaddr_info_get(&conn_conf->client_addr, NULL,
                                                    APR_INET6,
                                                    ntohs(hdr->v2.addr.ip6.src_port),
                                                    0, c->pool);
                        if (ret != APR_SUCCESS) {
                            conn_conf->client_addr = NULL;
                            ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03505)
                                          "RemoteIPProxyProtocol: error creating sockaddr");
                            return HDR_ERROR;
                        }
                        memcpy(&conn_conf->client_addr->sa.sin6.sin6_addr.s6_addr,
                               hdr->v2.addr.ip6.src_addr, 16);
                        break;
    #else
                        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03506)
                                      "RemoteIPProxyProtocol: APR is not compiled with IPv6 support");
                        return HDR_ERROR;
    #endif
                    default:
                        /* unsupported protocol */
                        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10183)
                                      "RemoteIPProxyProtocol: unsupported protocol %.2hx",
                                      (unsigned short)hdr->v2.fam);
                        return HDR_ERROR;
                }
                break;  /* we got a sockaddr now */
            default:
                /* not a supported command */
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03507)
                              "RemoteIPProxyProtocol: unsupported command %.2hx",
                              (unsigned short)hdr->v2.ver_cmd);
                return HDR_ERROR;
        }
    
        /* got address - compute the client_ip from it */
        ret = apr_sockaddr_ip_get(&conn_conf->client_ip, conn_conf->client_addr);
        if (ret != APR_SUCCESS) {
            conn_conf->client_addr = NULL;
            ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03508)
                          "RemoteIPProxyProtocol: error converting address to string");
            return HDR_ERROR;
        }
    
        return HDR_DONE;
    }
    
    /** Return length for a v2 protocol header. */
    static apr_size_t remoteip_get_v2_len(proxy_header *hdr)
    {
        return ntohs(hdr->v2.len);
    }
    
    /** Determine if this is a v1 or v2 PROXY header.
     */
    static int remoteip_determine_version(conn_rec *c, const char *ptr)
    {
        proxy_header *hdr = (proxy_header *) ptr;
    
        /* assert len >= 14 */
    
        if (memcmp(&hdr->v2, v2sig, sizeof(v2sig)) == 0 &&
            (hdr->v2.ver_cmd & 0xF0) == 0x20) {
            return 2;
        }
        else if (memcmp(hdr->v1.line, "PROXY ", 6) == 0) {
            return 1;
        }
        else {
            return -1;
        }
    }
    
    /* Capture the first bytes on the protocol and parse the PROXY protocol header.
     * Removes itself when the header is complete.
     */
    static apr_status_t remoteip_input_filter(ap_filter_t *f,
                                        apr_bucket_brigade *bb_out,
                                        ap_input_mode_t mode,
                                        apr_read_type_e block,
                                        apr_off_t readbytes)
    {
        apr_status_t ret;
        remoteip_filter_context *ctx = f->ctx;
        remoteip_conn_config_t *conn_conf;
        apr_bucket *b;
        remoteip_parse_status_t psts = HDR_NEED_MORE;
        const char *ptr;
        apr_size_t len;
    
        if (f->c->aborted) {
            return APR_ECONNABORTED;
        }
    
        /* allocate/retrieve the context that holds our header */
        if (!ctx) {
            ctx = f->ctx = apr_palloc(f->c->pool, sizeof(*ctx));
            ctx->rcvd = 0;
            ctx->need = MIN_HDR_LEN;
            ctx->version = 0;
            ctx->mode = AP_MODE_READBYTES;
            ctx->bb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
            ctx->done = 0;
        }
    
        if (ctx->done) {
            /* Note: because we're a connection filter we can't remove ourselves
             * when we're done, so we have to stay in the chain and just go into
             * passthrough mode.
             */
            return ap_get_brigade(f->next, bb_out, mode, block, readbytes);
        }
    
        conn_conf = ap_get_module_config(f->c->conn_config, &remoteip_module);
    
        /* try to read a header's worth of data */
        while (!ctx->done) {
            if (APR_BRIGADE_EMPTY(ctx->bb)) {
                apr_off_t got, want = ctx->need - ctx->rcvd;
    
                ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, want);
                if (ret != APR_SUCCESS) {
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10184)
                                  "failed reading input");
                    return ret;
                }
    
                ret = apr_brigade_length(ctx->bb, 1, &got);
                if (ret || got > want) {
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10185)
                                  "RemoteIPProxyProtocol header too long, "
                                  "got %" APR_OFF_T_FMT " expected %" APR_OFF_T_FMT,
                                  got, want);
                    f->c->aborted = 1;
                    return APR_ECONNABORTED;
                }
            }
            if (APR_BRIGADE_EMPTY(ctx->bb)) {
                return block == APR_NONBLOCK_READ ? APR_SUCCESS : APR_EOF;
            }
    
            while (!ctx->done && !APR_BRIGADE_EMPTY(ctx->bb)) {
                b = APR_BRIGADE_FIRST(ctx->bb);
    
                ret = apr_bucket_read(b, &ptr, &len, block);
                if (APR_STATUS_IS_EAGAIN(ret) && block == APR_NONBLOCK_READ) {
                    return APR_SUCCESS;
                }
                if (ret != APR_SUCCESS) {
                    return ret;
                }
    
                memcpy(ctx->header + ctx->rcvd, ptr, len);
                ctx->rcvd += len;
    
                apr_bucket_delete(b);
                psts = HDR_NEED_MORE;
    
                if (ctx->version == 0) {
                    /* reading initial chunk */
                    if (ctx->rcvd >= MIN_HDR_LEN) {
                        ctx->version = remoteip_determine_version(f->c, ctx->header);
                        if (ctx->version < 0) {
                            psts = HDR_ERROR;
                        }
                        else if (ctx->version == 1) {
                            ctx->mode = AP_MODE_GETLINE;
                            ctx->need = sizeof(proxy_v1);
                        }
                        else if (ctx->version == 2) {
                            ctx->need = MIN_V2_HDR_LEN;
                        }
                    }
                }
                else if (ctx->version == 1) {
                    psts = remoteip_process_v1_header(f->c, conn_conf,
                                                (proxy_header *) ctx->header,
                                                ctx->rcvd, &ctx->need);
                }
                else if (ctx->version == 2) {
                    if (ctx->rcvd >= MIN_V2_HDR_LEN) {
                        ctx->need = MIN_V2_HDR_LEN +
                            remoteip_get_v2_len((proxy_header *) ctx->header);
                        if (ctx->need > sizeof(proxy_v2)) {
                            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(10186)
                                          "RemoteIPProxyProtocol protocol header length too long");
                            f->c->aborted = 1;
                            apr_brigade_destroy(ctx->bb);
                            return APR_ECONNABORTED;
                        }
                    }
                    if (ctx->rcvd >= ctx->need) {
                        psts = remoteip_process_v2_header(f->c, conn_conf,
                                                    (proxy_header *) ctx->header);
                    }
                }
                else {
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(03509)
                                  "RemoteIPProxyProtocol: internal error: unknown version "
                                  "%d", ctx->version);
                    f->c->aborted = 1;
                    apr_brigade_destroy(ctx->bb);
                    return APR_ECONNABORTED;
                }
    
                switch (psts) {
                    case HDR_ERROR:
                        f->c->aborted = 1;
                        apr_brigade_destroy(ctx->bb);
                        return APR_ECONNABORTED;
    
                    case HDR_DONE:
                        ctx->done = 1;
                        break;
    
                    case HDR_NEED_MORE:
                        break;
                }
            }
        }
    
        /* we only get here when done == 1 */
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03511)
                      "RemoteIPProxyProtocol: received valid PROXY header: %s:%hu",
                      conn_conf->client_ip, conn_conf->client_addr->port);
    
        if (ctx->rcvd > ctx->need || !APR_BRIGADE_EMPTY(ctx->bb)) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(03513)
                          "RemoteIPProxyProtocol: internal error: have data left over; "
                          " need=%" APR_SIZE_T_FMT ", rcvd=%" APR_SIZE_T_FMT
                          ", brigade-empty=%d", ctx->need, ctx->rcvd,
                          APR_BRIGADE_EMPTY(ctx->bb));
            f->c->aborted = 1;
            apr_brigade_destroy(ctx->bb);
            return APR_ECONNABORTED;
        }
    
        /* clean up */
        apr_brigade_destroy(ctx->bb);
        ctx->bb = NULL;
    
        /* now do the real read for the upper layer */
        return ap_get_brigade(f->next, bb_out, mode, block, readbytes);
    }
    
    static const command_rec remoteip_cmds[] =
    {
        AP_INIT_TAKE1("RemoteIPHeader", header_name_set, NULL, RSRC_CONF,
                      "Specifies a request header to trust as the client IP, "
                      "e.g. X-Forwarded-For"),
        AP_INIT_TAKE1("RemoteIPProxiesHeader", proxies_header_name_set,
                      NULL, RSRC_CONF,
                      "Specifies a request header to record proxy IP's, "
                      "e.g. X-Forwarded-By; if not given then do not record"),
        AP_INIT_ITERATE("RemoteIPTrustedProxy", proxies_set, 0, RSRC_CONF,
                        "Specifies one or more proxies which are trusted "
                        "to present IP headers"),
        AP_INIT_ITERATE("RemoteIPInternalProxy", proxies_set, (void*)1, RSRC_CONF,
                        "Specifies one or more internal (transparent) proxies "
                        "which are trusted to present IP headers"),
        AP_INIT_TAKE1("RemoteIPTrustedProxyList", proxylist_read, 0,
                      RSRC_CONF | EXEC_ON_READ,
                      "The filename to read the list of trusted proxies, "
                      "see the RemoteIPTrustedProxy directive"),
        AP_INIT_TAKE1("RemoteIPInternalProxyList", proxylist_read, (void*)1,
                      RSRC_CONF | EXEC_ON_READ,
                      "The filename to read the list of internal proxies, "
                      "see the RemoteIPInternalProxy directive"),
        AP_INIT_FLAG("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL,
                      RSRC_CONF, "Enable PROXY protocol handling ('on', 'off')"),
        AP_INIT_TAKE_ARGV("RemoteIPProxyProtocolExceptions",
                      remoteip_disable_networks, NULL, RSRC_CONF, "Disable PROXY "
                      "protocol handling for this list of networks in CIDR format"),
        { NULL }
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        /* mod_ssl is CONNECTION + 5, so we want something higher (earlier);
         * mod_reqtimeout is CONNECTION + 8, so we want something lower (later) */
        remoteip_filter = 
            ap_register_input_filter("REMOTEIP_INPUT", remoteip_input_filter, NULL,
                                     AP_FTYPE_CONNECTION + 7);
    
        ap_hook_post_config(remoteip_hook_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_pre_connection(remoteip_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_read_request(remoteip_modify_request, NULL, NULL, APR_HOOK_FIRST);
    }
    
    AP_DECLARE_MODULE(remoteip) = {
        STANDARD20_MODULE_STUFF,
        NULL,                          /* create per-directory config structure */
        NULL,                          /* merge per-directory config structures */
        create_remoteip_server_config, /* create per-server config structure */
        merge_remoteip_server_config,  /* merge per-server config structures */
        remoteip_cmds,                 /* command apr_table_t */
        register_hooks                 /* register hooks */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_remoteip.dsp������������������������������������������������������0000664�0001751�0001751�00000010733�13242365145�021256� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_remoteip" - 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_remoteip - 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_remoteip.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_remoteip.mak" CFG="mod_remoteip - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_remoteip - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_remoteip - 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_remoteip - 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_remoteip_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 /fo"Release/mod_remoteip.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_remoteip.so" /d LONG_NAME="remoteip_module for Apache"
    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 /out:".\Release\mod_remoteip.so" /base:@..\..\os\win32\BaseAddr.ref,mod_remoteip.so
    # ADD LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_remoteip.so" /base:@..\..\os\win32\BaseAddr.ref,mod_remoteip.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_remoteip.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_remoteip - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_remoteip_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 /fo"Debug/mod_remoteip.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_remoteip.so" /d LONG_NAME="remoteip_module for Apache"
    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 /out:".\Debug\mod_remoteip.so" /base:@..\..\os\win32\BaseAddr.ref,mod_remoteip.so
    # ADD LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_remoteip.so" /base:@..\..\os\win32\BaseAddr.ref,mod_remoteip.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_remoteip.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_remoteip - Win32 Release"
    # Name "mod_remoteip - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_remoteip.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������httpd-2.4.64/modules/metadata/mod_expires.mak�������������������������������������������������������0000664�0001751�0001751�00000023505�12701473373�021076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_expires.dsp
    !IF "$(CFG)" == ""
    CFG=mod_expires - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_expires - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_expires - Win32 Release" && "$(CFG)" != "mod_expires - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_expires - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_expires.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_expires.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_expires.obj"
    	-@erase "$(INTDIR)\mod_expires.res"
    	-@erase "$(INTDIR)\mod_expires_src.idb"
    	-@erase "$(INTDIR)\mod_expires_src.pdb"
    	-@erase "$(OUTDIR)\mod_expires.exp"
    	-@erase "$(OUTDIR)\mod_expires.lib"
    	-@erase "$(OUTDIR)\mod_expires.pdb"
    	-@erase "$(OUTDIR)\mod_expires.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_expires_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_expires.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_expires.so" /d LONG_NAME="expires_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_expires.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_expires.pdb" /debug /out:"$(OUTDIR)\mod_expires.so" /implib:"$(OUTDIR)\mod_expires.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_expires.obj" \
    	"$(INTDIR)\mod_expires.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_expires.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_expires.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_expires.so"
       if exist .\Release\mod_expires.so.manifest mt.exe -manifest .\Release\mod_expires.so.manifest -outputresource:.\Release\mod_expires.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_expires - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_expires.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_expires.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_expires.obj"
    	-@erase "$(INTDIR)\mod_expires.res"
    	-@erase "$(INTDIR)\mod_expires_src.idb"
    	-@erase "$(INTDIR)\mod_expires_src.pdb"
    	-@erase "$(OUTDIR)\mod_expires.exp"
    	-@erase "$(OUTDIR)\mod_expires.lib"
    	-@erase "$(OUTDIR)\mod_expires.pdb"
    	-@erase "$(OUTDIR)\mod_expires.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_expires_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_expires.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_expires.so" /d LONG_NAME="expires_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_expires.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_expires.pdb" /debug /out:"$(OUTDIR)\mod_expires.so" /implib:"$(OUTDIR)\mod_expires.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_expires.obj" \
    	"$(INTDIR)\mod_expires.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_expires.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_expires.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_expires.so"
       if exist .\Debug\mod_expires.so.manifest mt.exe -manifest .\Debug\mod_expires.so.manifest -outputresource:.\Debug\mod_expires.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_expires.dep")
    !INCLUDE "mod_expires.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_expires.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_expires - Win32 Release" || "$(CFG)" == "mod_expires - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_expires - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_expires - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_expires - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_expires - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_expires - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_expires - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_expires - Win32 Release"
    
    
    "$(INTDIR)\mod_expires.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_expires.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_expires.so" /d LONG_NAME="expires_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_expires - Win32 Debug"
    
    
    "$(INTDIR)\mod_expires.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_expires.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_expires.so" /d LONG_NAME="expires_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_expires.c
    
    "$(INTDIR)\mod_expires.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_env.dsp�����������������������������������������������������������0000664�0001751�0001751�00000010431�10551346420�020210� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_env.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_env.so" /d LONG_NAME="env_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_env.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_env.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_env.so" /d LONG_NAME="env_module for Apache"
    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 /out:".\Debug\mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_env.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_cern_meta.exp�����������������������������������������������������0000664�0001751�0001751�00000000021�10150161574�021355� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cern_meta_module
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_expires.exp�������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�021104� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������expires_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_usertrack.exp�����������������������������������������������������0000664�0001751�0001751�00000000021�10150161574�021423� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usertrack_module
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_setenvif.exp������������������������������������������������������0000664�0001751�0001751�00000000020�10150161574�021242� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������setenvif_module
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_remoteip.mak������������������������������������������������������0000664�0001751�0001751�00000023663�13242645471�021251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_remoteip.dsp
    !IF "$(CFG)" == ""
    CFG=mod_remoteip - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_remoteip - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_remoteip - Win32 Release" && "$(CFG)" != "mod_remoteip - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_remoteip.mak" CFG="mod_remoteip - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_remoteip - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_remoteip - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_remoteip - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_remoteip.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_remoteip.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_remoteip.obj"
    	-@erase "$(INTDIR)\mod_remoteip.res"
    	-@erase "$(INTDIR)\mod_remoteip_src.idb"
    	-@erase "$(INTDIR)\mod_remoteip_src.pdb"
    	-@erase "$(OUTDIR)\mod_remoteip.exp"
    	-@erase "$(OUTDIR)\mod_remoteip.lib"
    	-@erase "$(OUTDIR)\mod_remoteip.pdb"
    	-@erase "$(OUTDIR)\mod_remoteip.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_remoteip_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_remoteip.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_remoteip.so" /d LONG_NAME="remoteip_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_remoteip.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_remoteip.pdb" /debug /out:"$(OUTDIR)\mod_remoteip.so" /implib:"$(OUTDIR)\mod_remoteip.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_remoteip.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_remoteip.obj" \
    	"$(INTDIR)\mod_remoteip.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_remoteip.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_remoteip.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_remoteip.so"
       if exist .\Release\mod_remoteip.so.manifest mt.exe -manifest .\Release\mod_remoteip.so.manifest -outputresource:.\Release\mod_remoteip.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_remoteip - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_remoteip.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_remoteip.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_remoteip.obj"
    	-@erase "$(INTDIR)\mod_remoteip.res"
    	-@erase "$(INTDIR)\mod_remoteip_src.idb"
    	-@erase "$(INTDIR)\mod_remoteip_src.pdb"
    	-@erase "$(OUTDIR)\mod_remoteip.exp"
    	-@erase "$(OUTDIR)\mod_remoteip.lib"
    	-@erase "$(OUTDIR)\mod_remoteip.pdb"
    	-@erase "$(OUTDIR)\mod_remoteip.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_remoteip_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_remoteip.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_remoteip.so" /d LONG_NAME="remoteip_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_remoteip.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_remoteip.pdb" /debug /out:"$(OUTDIR)\mod_remoteip.so" /implib:"$(OUTDIR)\mod_remoteip.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_remoteip.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_remoteip.obj" \
    	"$(INTDIR)\mod_remoteip.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_remoteip.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_remoteip.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_remoteip.so"
       if exist .\Debug\mod_remoteip.so.manifest mt.exe -manifest .\Debug\mod_remoteip.so.manifest -outputresource:.\Debug\mod_remoteip.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_remoteip.dep")
    !INCLUDE "mod_remoteip.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_remoteip.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_remoteip - Win32 Release" || "$(CFG)" == "mod_remoteip - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_remoteip - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_remoteip - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_remoteip - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_remoteip - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_remoteip - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_remoteip - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_remoteip - Win32 Release"
    
    
    "$(INTDIR)\mod_remoteip.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_remoteip.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_remoteip.so" /d LONG_NAME="remoteip_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_remoteip - Win32 Debug"
    
    
    "$(INTDIR)\mod_remoteip.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_remoteip.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_remoteip.so" /d LONG_NAME="remoteip_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_remoteip.c
    
    "$(INTDIR)\mod_remoteip.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_env.mak�����������������������������������������������������������0000664�0001751�0001751�00000022745�12701473373�020214� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_env.dsp
    !IF "$(CFG)" == ""
    CFG=mod_env - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_env - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_env - Win32 Release" && "$(CFG)" != "mod_env - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_env - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_env.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_env.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_env.obj"
    	-@erase "$(INTDIR)\mod_env.res"
    	-@erase "$(INTDIR)\mod_env_src.idb"
    	-@erase "$(INTDIR)\mod_env_src.pdb"
    	-@erase "$(OUTDIR)\mod_env.exp"
    	-@erase "$(OUTDIR)\mod_env.lib"
    	-@erase "$(OUTDIR)\mod_env.pdb"
    	-@erase "$(OUTDIR)\mod_env.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_env_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_env.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_env.so" /d LONG_NAME="env_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_env.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_env.pdb" /debug /out:"$(OUTDIR)\mod_env.so" /implib:"$(OUTDIR)\mod_env.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_env.obj" \
    	"$(INTDIR)\mod_env.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_env.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_env.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_env.so"
       if exist .\Release\mod_env.so.manifest mt.exe -manifest .\Release\mod_env.so.manifest -outputresource:.\Release\mod_env.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_env - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_env.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_env.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_env.obj"
    	-@erase "$(INTDIR)\mod_env.res"
    	-@erase "$(INTDIR)\mod_env_src.idb"
    	-@erase "$(INTDIR)\mod_env_src.pdb"
    	-@erase "$(OUTDIR)\mod_env.exp"
    	-@erase "$(OUTDIR)\mod_env.lib"
    	-@erase "$(OUTDIR)\mod_env.pdb"
    	-@erase "$(OUTDIR)\mod_env.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_env_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_env.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_env.so" /d LONG_NAME="env_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_env.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_env.pdb" /debug /out:"$(OUTDIR)\mod_env.so" /implib:"$(OUTDIR)\mod_env.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_env.obj" \
    	"$(INTDIR)\mod_env.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_env.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_env.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_env.so"
       if exist .\Debug\mod_env.so.manifest mt.exe -manifest .\Debug\mod_env.so.manifest -outputresource:.\Debug\mod_env.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_env.dep")
    !INCLUDE "mod_env.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_env.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_env - Win32 Release" || "$(CFG)" == "mod_env - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_env - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_env - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_env - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_env - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_env - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_env - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_env - Win32 Release"
    
    
    "$(INTDIR)\mod_env.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_env.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_env.so" /d LONG_NAME="env_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_env - Win32 Debug"
    
    
    "$(INTDIR)\mod_env.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_env.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_env.so" /d LONG_NAME="env_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_env.c
    
    "$(INTDIR)\mod_env.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������httpd-2.4.64/modules/metadata/mod_mime_magic.mak����������������������������������������������������0000664�0001751�0001751�00000024143�12701473373�021505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_mime_magic.dsp
    !IF "$(CFG)" == ""
    CFG=mod_mime_magic - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_mime_magic - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_mime_magic - Win32 Release" && "$(CFG)" != "mod_mime_magic - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_mime_magic - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_mime_magic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_mime_magic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_mime_magic.obj"
    	-@erase "$(INTDIR)\mod_mime_magic.res"
    	-@erase "$(INTDIR)\mod_mime_magic_src.idb"
    	-@erase "$(INTDIR)\mod_mime_magic_src.pdb"
    	-@erase "$(OUTDIR)\mod_mime_magic.exp"
    	-@erase "$(OUTDIR)\mod_mime_magic.lib"
    	-@erase "$(OUTDIR)\mod_mime_magic.pdb"
    	-@erase "$(OUTDIR)\mod_mime_magic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_mime_magic_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_mime_magic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_mime_magic.so" /d LONG_NAME="mime_magic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_mime_magic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_mime_magic.pdb" /debug /out:"$(OUTDIR)\mod_mime_magic.so" /implib:"$(OUTDIR)\mod_mime_magic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_mime_magic.obj" \
    	"$(INTDIR)\mod_mime_magic.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_mime_magic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_mime_magic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_mime_magic.so"
       if exist .\Release\mod_mime_magic.so.manifest mt.exe -manifest .\Release\mod_mime_magic.so.manifest -outputresource:.\Release\mod_mime_magic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_mime_magic - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_mime_magic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_mime_magic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_mime_magic.obj"
    	-@erase "$(INTDIR)\mod_mime_magic.res"
    	-@erase "$(INTDIR)\mod_mime_magic_src.idb"
    	-@erase "$(INTDIR)\mod_mime_magic_src.pdb"
    	-@erase "$(OUTDIR)\mod_mime_magic.exp"
    	-@erase "$(OUTDIR)\mod_mime_magic.lib"
    	-@erase "$(OUTDIR)\mod_mime_magic.pdb"
    	-@erase "$(OUTDIR)\mod_mime_magic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_mime_magic_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_mime_magic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_mime_magic.so" /d LONG_NAME="mime_magic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_mime_magic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_mime_magic.pdb" /debug /out:"$(OUTDIR)\mod_mime_magic.so" /implib:"$(OUTDIR)\mod_mime_magic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_mime_magic.obj" \
    	"$(INTDIR)\mod_mime_magic.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_mime_magic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_mime_magic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_mime_magic.so"
       if exist .\Debug\mod_mime_magic.so.manifest mt.exe -manifest .\Debug\mod_mime_magic.so.manifest -outputresource:.\Debug\mod_mime_magic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_mime_magic.dep")
    !INCLUDE "mod_mime_magic.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_mime_magic.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_mime_magic - Win32 Release" || "$(CFG)" == "mod_mime_magic - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_mime_magic - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_mime_magic - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_mime_magic - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_mime_magic - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_mime_magic - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_mime_magic - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_mime_magic - Win32 Release"
    
    
    "$(INTDIR)\mod_mime_magic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_mime_magic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_mime_magic.so" /d LONG_NAME="mime_magic_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_mime_magic - Win32 Debug"
    
    
    "$(INTDIR)\mod_mime_magic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_mime_magic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_mime_magic.so" /d LONG_NAME="mime_magic_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_mime_magic.c
    
    "$(INTDIR)\mod_mime_magic.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_version.mak�������������������������������������������������������0000664�0001751�0001751�00000023505�12701473373�021104� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_version.dsp
    !IF "$(CFG)" == ""
    CFG=mod_version - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_version - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_version - Win32 Release" && "$(CFG)" != "mod_version - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_version - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_version.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_version.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_version.obj"
    	-@erase "$(INTDIR)\mod_version.res"
    	-@erase "$(INTDIR)\mod_version_src.idb"
    	-@erase "$(INTDIR)\mod_version_src.pdb"
    	-@erase "$(OUTDIR)\mod_version.exp"
    	-@erase "$(OUTDIR)\mod_version.lib"
    	-@erase "$(OUTDIR)\mod_version.pdb"
    	-@erase "$(OUTDIR)\mod_version.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_version_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_version.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_version.so" /d LONG_NAME="version_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_version.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_version.pdb" /debug /out:"$(OUTDIR)\mod_version.so" /implib:"$(OUTDIR)\mod_version.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_version.obj" \
    	"$(INTDIR)\mod_version.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_version.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_version.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_version.so"
       if exist .\Release\mod_version.so.manifest mt.exe -manifest .\Release\mod_version.so.manifest -outputresource:.\Release\mod_version.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_version - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_version.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_version.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_version.obj"
    	-@erase "$(INTDIR)\mod_version.res"
    	-@erase "$(INTDIR)\mod_version_src.idb"
    	-@erase "$(INTDIR)\mod_version_src.pdb"
    	-@erase "$(OUTDIR)\mod_version.exp"
    	-@erase "$(OUTDIR)\mod_version.lib"
    	-@erase "$(OUTDIR)\mod_version.pdb"
    	-@erase "$(OUTDIR)\mod_version.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_version_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_version.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_version.so" /d LONG_NAME="version_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_version.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_version.pdb" /debug /out:"$(OUTDIR)\mod_version.so" /implib:"$(OUTDIR)\mod_version.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_version.obj" \
    	"$(INTDIR)\mod_version.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_version.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_version.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_version.so"
       if exist .\Debug\mod_version.so.manifest mt.exe -manifest .\Debug\mod_version.so.manifest -outputresource:.\Debug\mod_version.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_version.dep")
    !INCLUDE "mod_version.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_version.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_version - Win32 Release" || "$(CFG)" == "mod_version - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_version - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_version - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_version - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_version - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_version - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_version - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_version - Win32 Release"
    
    
    "$(INTDIR)\mod_version.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_version.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_version.so" /d LONG_NAME="version_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_version - Win32 Debug"
    
    
    "$(INTDIR)\mod_version.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_version.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_version.so" /d LONG_NAME="version_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_version.c
    
    "$(INTDIR)\mod_version.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_headers.dep�������������������������������������������������������0000664�0001751�0001751�00000004015�12674411515�021024� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_headers.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_headers.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\ssl\mod_ssl.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_setenvif.dep������������������������������������������������������0000664�0001751�0001751�00000004001�12674411515�021227� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_setenvif.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_setenvif.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_expires.c���������������������������������������������������������0000664�0001751�0001751�00000043721�12640532101�020535� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <Andrew.Wilson@cm.cf.ac.uk> 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 <code><seconds>
     *     ExpiresByType type/encoding <code><seconds>
     *
     * Valid values for <code> are:
     *
     *     'M'      expires header shows file modification date + <seconds>
     *     'A'      expires header shows access time + <seconds>
     *
     *              [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]
     *
     * <seconds> should be an integer value [acceptable to atoi()]
     *
     * There is NO space between the <code> and <seconds>.
     *
     * 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 "<base> [plus] {<num> <type>}*"
     *     ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"
     *
     * where <base> is one of:
     *      access
     *      now             equivalent to 'access'
     *      modification
     *
     * where the 'plus' keyword is optional
     *
     * where <num> should be an integer value [acceptable to atoi()]
     *
     * where <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"
     *
     * ---
     *
     * 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.4 compatibility?
         */
        if ((code[0] == 'A') || (code[0] == 'M')) {
            *real_code = (char *)code;
            return NULL;
        }
    
        /* <base> [plus] {<num> <type>}*
         */
    
        /* <base>
         */
        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 <base> '",
                           word, "'", NULL);
        }
    
        /* [plus]
         */
        word = ap_getword_conf(p, &code);
        if (!strncasecmp(word, "plus", 1)) {
            word = ap_getword_conf(p, &code);
        }
    
        /* {<num> <type>}*
         */
        while (word[0]) {
            /* <num>
             */
            if (apr_isdigit(word[0])) {
                num = atoi(word);
            }
            else {
                return apr_pstrcat(p, "bad expires code, numeric value expected <num> '",
                               word, "'", NULL);
            }
    
            /* <type>
             */
            word = ap_getword_conf(p, &code);
            if (word[0] == '\0') {
                return apr_pstrcat(p, "bad expires code, missing <type>", NULL);
            }
    
            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 <type>",
                               "'", word, "'", NULL);
            }
    
            modifier = modifier + factor * num;
    
            /* next <num>
             */
            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 (check == NULL) {
            return "Invalid mimetype: should contain a slash";
        }
        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 == APR_NOFILE) {
                /* 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, APLOGNO(01500)
                        "internal error: bad expires code: %s", r->filename);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        expires = base + additional;
        if (expires < r->request_time) {
            expires = r->request_time;
        }
        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;
    
        /* Don't add Expires headers to errors */
        if (ap_is_HTTP_ERROR(f->r->status)) {
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, b);
        }
    
        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);
    }
    
    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);
    }
    
    AP_DECLARE_MODULE(expires) =
    {
        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 */
    };
    �����������������������������������������������httpd-2.4.64/modules/metadata/NWGNUheaders����������������������������������������������������������0000664�0001751�0001751�00000010177�11540546347�020246� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/ssl \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_expires.dep�������������������������������������������������������0000664�0001751�0001751�00000003664�12674411515�021101� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_expires.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_expires.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_remoteip.dep������������������������������������������������������0000664�0001751�0001751�00000003610�12674411515�021235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_remoteip.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_remoteip.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_version.dep�������������������������������������������������������0000664�0001751�0001751�00000003110�12674411515�021071� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_version.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_version.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUmakefile���������������������������������������������������������0000664�0001751�0001751�00000010237�11540562746�020406� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    	$(OBJDIR)/remoteip.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUremoteip���������������������������������������������������������0000664�0001751�0001751�00000010154�11540546347�020452� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= remoteip
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) RemoteIP Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= RemoteIP 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	=
    
    #
    # 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)/$(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_remoteip.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	remoteip_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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUcernmeta���������������������������������������������������������0000664�0001751�0001751�00000010160�11540546347�020421� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_version.c���������������������������������������������������������0000664�0001751�0001751�00000020677�12757564422�020574� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 preceded 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->temp_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->temp_pool,
                                      apr_pstrmemdup(cmd->temp_pool, arg2,
                                                     endp-arg2),
                                      &error);
                if (error) {
                    return error;
                }
                break;
    
            case '<':
                compare = compare_version(apr_pstrmemdup(cmd->temp_pool, arg2,
                                                         endp-arg2),
                                          &error);
                if (error) {
                    return error;
                }
    
                match = ((-1 == compare) || (*p && !compare));
                break;
    
            case '>':
                compare = compare_version(apr_pstrmemdup(cmd->temp_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,
                                          &current, &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 }
    };
    
    AP_DECLARE_MODULE(version) =
    {
        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 */
    };
    �����������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_headers.mak�������������������������������������������������������0000664�0001751�0001751�00000023535�12701473373�021035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_headers.dsp
    !IF "$(CFG)" == ""
    CFG=mod_headers - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_headers - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_headers - Win32 Release" && "$(CFG)" != "mod_headers - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_headers - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_headers.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_headers.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_headers.obj"
    	-@erase "$(INTDIR)\mod_headers.res"
    	-@erase "$(INTDIR)\mod_headers_src.idb"
    	-@erase "$(INTDIR)\mod_headers_src.pdb"
    	-@erase "$(OUTDIR)\mod_headers.exp"
    	-@erase "$(OUTDIR)\mod_headers.lib"
    	-@erase "$(OUTDIR)\mod_headers.pdb"
    	-@erase "$(OUTDIR)\mod_headers.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_headers_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_headers.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_headers.so" /d LONG_NAME="headers_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_headers.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_headers.pdb" /debug /out:"$(OUTDIR)\mod_headers.so" /implib:"$(OUTDIR)\mod_headers.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_headers.obj" \
    	"$(INTDIR)\mod_headers.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_headers.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_headers.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_headers.so"
       if exist .\Release\mod_headers.so.manifest mt.exe -manifest .\Release\mod_headers.so.manifest -outputresource:.\Release\mod_headers.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_headers - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_headers.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_headers.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_headers.obj"
    	-@erase "$(INTDIR)\mod_headers.res"
    	-@erase "$(INTDIR)\mod_headers_src.idb"
    	-@erase "$(INTDIR)\mod_headers_src.pdb"
    	-@erase "$(OUTDIR)\mod_headers.exp"
    	-@erase "$(OUTDIR)\mod_headers.lib"
    	-@erase "$(OUTDIR)\mod_headers.pdb"
    	-@erase "$(OUTDIR)\mod_headers.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_headers_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_headers.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_headers.so" /d LONG_NAME="headers_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_headers.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_headers.pdb" /debug /out:"$(OUTDIR)\mod_headers.so" /implib:"$(OUTDIR)\mod_headers.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_headers.obj" \
    	"$(INTDIR)\mod_headers.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_headers.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_headers.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_headers.so"
       if exist .\Debug\mod_headers.so.manifest mt.exe -manifest .\Debug\mod_headers.so.manifest -outputresource:.\Debug\mod_headers.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_headers.dep")
    !INCLUDE "mod_headers.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_headers.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_headers - Win32 Release" || "$(CFG)" == "mod_headers - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_headers - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_headers - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_headers - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_headers - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_headers - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_headers - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_headers - Win32 Release"
    
    
    "$(INTDIR)\mod_headers.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_headers.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_headers.so" /d LONG_NAME="headers_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_headers - Win32 Debug"
    
    
    "$(INTDIR)\mod_headers.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_headers.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_headers.so" /d LONG_NAME="headers_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_headers.c
    
    "$(INTDIR)\mod_headers.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_unique_id.mak�����������������������������������������������������0000664�0001751�0001751�00000024013�12701473373�021374� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_unique_id.dsp
    !IF "$(CFG)" == ""
    CFG=mod_unique_id - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_unique_id - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_unique_id - Win32 Release" && "$(CFG)" != "mod_unique_id - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_unique_id - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_unique_id.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_unique_id.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_unique_id.obj"
    	-@erase "$(INTDIR)\mod_unique_id.res"
    	-@erase "$(INTDIR)\mod_unique_id_src.idb"
    	-@erase "$(INTDIR)\mod_unique_id_src.pdb"
    	-@erase "$(OUTDIR)\mod_unique_id.exp"
    	-@erase "$(OUTDIR)\mod_unique_id.lib"
    	-@erase "$(OUTDIR)\mod_unique_id.pdb"
    	-@erase "$(OUTDIR)\mod_unique_id.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_unique_id_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_unique_id.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_unique_id.so" /d LONG_NAME="unique_id_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_unique_id.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_unique_id.pdb" /debug /out:"$(OUTDIR)\mod_unique_id.so" /implib:"$(OUTDIR)\mod_unique_id.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_unique_id.obj" \
    	"$(INTDIR)\mod_unique_id.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_unique_id.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_unique_id.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_unique_id.so"
       if exist .\Release\mod_unique_id.so.manifest mt.exe -manifest .\Release\mod_unique_id.so.manifest -outputresource:.\Release\mod_unique_id.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_unique_id - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_unique_id.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_unique_id.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_unique_id.obj"
    	-@erase "$(INTDIR)\mod_unique_id.res"
    	-@erase "$(INTDIR)\mod_unique_id_src.idb"
    	-@erase "$(INTDIR)\mod_unique_id_src.pdb"
    	-@erase "$(OUTDIR)\mod_unique_id.exp"
    	-@erase "$(OUTDIR)\mod_unique_id.lib"
    	-@erase "$(OUTDIR)\mod_unique_id.pdb"
    	-@erase "$(OUTDIR)\mod_unique_id.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_unique_id_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_unique_id.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_unique_id.so" /d LONG_NAME="unique_id_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_unique_id.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_unique_id.pdb" /debug /out:"$(OUTDIR)\mod_unique_id.so" /implib:"$(OUTDIR)\mod_unique_id.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_unique_id.obj" \
    	"$(INTDIR)\mod_unique_id.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_unique_id.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_unique_id.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_unique_id.so"
       if exist .\Debug\mod_unique_id.so.manifest mt.exe -manifest .\Debug\mod_unique_id.so.manifest -outputresource:.\Debug\mod_unique_id.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_unique_id.dep")
    !INCLUDE "mod_unique_id.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_unique_id.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_unique_id - Win32 Release" || "$(CFG)" == "mod_unique_id - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_unique_id - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_unique_id - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_unique_id - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_unique_id - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\metadata"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\metadata"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_unique_id - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ELSEIF  "$(CFG)" == "mod_unique_id - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\metadata"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\metadata"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_unique_id - Win32 Release"
    
    
    "$(INTDIR)\mod_unique_id.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_unique_id.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_unique_id.so" /d LONG_NAME="unique_id_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_unique_id - Win32 Debug"
    
    
    "$(INTDIR)\mod_unique_id.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_unique_id.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_unique_id.so" /d LONG_NAME="unique_id_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_unique_id.c
    
    "$(INTDIR)\mod_unique_id.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_env.dep�����������������������������������������������������������0000664�0001751�0001751�00000003213�12674411515�020200� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_env.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_env.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_mime_magic.dep����������������������������������������������������0000664�0001751�0001751�00000004074�12674411515�021505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_mime_magic.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_mime_magic.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUuniqueid���������������������������������������������������������0000664�0001751�0001751�00000010451�11540546347�020451� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/NWGNUmodversion�������������������������������������������������������0000664�0001751�0001751�00000010152�11540546347�021011� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_version.dsp�������������������������������������������������������0000664�0001751�0001751�00000010621�10551346420�021106� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_version.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_version.so" /d LONG_NAME="version_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_version.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_version.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_version.so" /d LONG_NAME="version_module for Apache"
    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 /out:".\Debug\mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_version.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/Makefile.in�����������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�020113� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_expires.dsp�������������������������������������������������������0000664�0001751�0001751�00000010621�10551346420�021100� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_expires.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_expires.so" /d LONG_NAME="expires_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_expires.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_expires.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_expires.so" /d LONG_NAME="expires_module for Apache"
    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 /out:".\Debug\mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_expires.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_mime_magic.dsp����������������������������������������������������0000664�0001751�0001751�00000011027�10551346420�021511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_mime_magic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_mime_magic.so" /d LONG_NAME="mime_magic_module for Apache"
    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 /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 /out:".\Release\mod_mime_magic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_mime_magic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_mime_magic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_mime_magic.so" /d LONG_NAME="mime_magic_module for Apache"
    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 /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 /out:".\Debug\mod_mime_magic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_mime_magic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/metadata/mod_headers.exp�������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�021040� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������headers_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015263� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/byterange_filter.c��������������������������������������������������������0000664�0001751�0001751�00000043603�14675527312�020764� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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 <stdarg.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    #ifndef AP_DEFAULT_MAX_RANGES
    #define AP_DEFAULT_MAX_RANGES 200
    #endif
    #ifndef AP_DEFAULT_MAX_OVERLAPS
    #define AP_DEFAULT_MAX_OVERLAPS 20
    #endif
    #ifndef AP_DEFAULT_MAX_REVERSALS
    #define AP_DEFAULT_MAX_REVERSALS 20
    #endif
    
    #define MAX_PREALLOC_RANGES 100
    
    APLOG_USE_MODULE(http);
    
    typedef struct indexes_t {
        apr_off_t start;
        apr_off_t end;
    } indexes_t;
    
    /*
     * Returns: number of ranges (merged) or -1 for no-good
     */
    static int ap_set_byterange(request_rec *r, apr_off_t clength,
                                apr_array_header_t **indexes,
                                int *overlaps, int *reversals)
    {
        const char *range;
        const char *ct;
        char *cur;
        apr_array_header_t *merged;
        int num_ranges = 0, unsatisfiable = 0;
        apr_off_t ostart = 0, oend = 0, sum_lengths = 0;
        int in_merge = 0;
        indexes_t *idx;
        int ranges = 1;
        int i;
        const char *it;
    
        *overlaps = 0;
        *reversals = 0;
    
        if (r->assbackwards) {
            return 0;
        }
    
        range = apr_table_get(r->headers_in, "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) == 0) {
                return 0;
        }
    
        /*
         * Check the If-Range header for Etag or Date.
         */
        if (AP_CONDITION_NOMATCH == ap_condition_if_range(r, r->headers_out)) {
            return 0;
        }
    
        range += 6;
        it = range;
        while (*it) {
            if (*it++ == ',') {
                ranges++;
            }
        }
        it = range;
        if (ranges > MAX_PREALLOC_RANGES) {
            ranges = MAX_PREALLOC_RANGES;
        }
        *indexes = apr_array_make(r->pool, ranges, sizeof(indexes_t));
        while ((cur = ap_getword(r->pool, &range, ','))) {
            char *dash;
            apr_off_t number, start, end;
    
            if (!*cur)
                break;
    
            /*
             * Per RFC 2616 14.35.1: If there is at least one syntactically invalid
             * byte-range-spec, we must ignore the whole header.
             */
    
            if (!(dash = strchr(cur, '-'))) {
                return 0;
            }
    
            if (dash == cur) {
                /* In the form "-5" */
                if (!ap_parse_strict_length(&number, dash+1)) {
                    return 0;
                }
                if (number < 1) {
                    return 0;
                }
                start = clength - number;
                end = clength - 1;
            }
            else {
                *dash++ = '\0';
                if (!ap_parse_strict_length(&number, cur)) {
                    return 0;
                }
                start = number;
                if (*dash) {
                    if (!ap_parse_strict_length(&number, dash)) {
                        return 0;
                    }
                    end = number;
                    if (start > end) {
                        return 0;
                    }
                }
                else {                  /* "5-" */
                    end = clength - 1;
                    /*
                     * special case: 0-
                     *   ignore all other ranges provided
                     *   return as a single range: 0-
                     */
                    if (start == 0) {
                        num_ranges = 0;
                        sum_lengths = 0;
                        in_merge = 1;
                        oend = end;
                        ostart = start;
                        apr_array_clear(*indexes);
                        break;
                    }
                }
            }
    
            if (start < 0) {
                start = 0;
            }
            if (start >= clength) {
                unsatisfiable = 1;
                continue;
            }
            if (end >= clength) {
                end = clength - 1;
            }
    
            if (!in_merge) {
                /* new set */
                ostart = start;
                oend = end;
                in_merge = 1;
                continue;
            }
            in_merge = 0;
    
            if (start >= ostart && end <= oend) {
                in_merge = 1;
            }
    
            if (start < ostart && end >= ostart-1) {
                ostart = start;
                ++*reversals;
                in_merge = 1;
            }
            if (end >= oend && start <= oend+1 ) {
                oend = end;
                in_merge = 1;
            }
    
            if (in_merge) {
                ++*overlaps;
                continue;
            } else {
                idx = (indexes_t *)apr_array_push(*indexes);
                idx->start = ostart;
                idx->end = oend;
                sum_lengths += oend - ostart + 1;
                /* new set again */
                in_merge = 1;
                ostart = start;
                oend = end;
                num_ranges++;
            }
        }
    
        if (in_merge) {
            idx = (indexes_t *)apr_array_push(*indexes);
            idx->start = ostart;
            idx->end = oend;
            sum_lengths += oend - ostart + 1;
            num_ranges++;
        }
        else if (num_ranges == 0 && unsatisfiable) {
            /* If all ranges are unsatisfiable, we should return 416 */
            return -1;
        }
        if (sum_lengths > clength) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "Sum of ranges larger than file, ignoring.");
            return 0;
        }
    
        /*
         * create the merged table now, now that we know we need it
         */
        merged = apr_array_make(r->pool, num_ranges, sizeof(char *));
        idx = (indexes_t *)(*indexes)->elts;
        for (i = 0; i < (*indexes)->nelts; i++, idx++) {
            char **new = (char **)apr_array_push(merged);
            *new = apr_psprintf(r->pool, "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT,
                                idx->start, idx->end);
        }
    
        r->status = HTTP_PARTIAL_CONTENT;
        r->range = apr_array_pstrcat(r->pool, merged, ',');
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01583)
                      "Range: %s | %s (%d : %d : %"APR_OFF_T_FMT")",
                      it, r->range, *overlaps, *reversals, clength);
    
        return num_ranges;
    }
    
    #define BYTERANGE_FMT "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT "/%" APR_OFF_T_FMT
    
    static apr_status_t copy_brigade_range(apr_bucket_brigade *bb,
                                           apr_bucket_brigade *bbout,
                                           apr_off_t start,
                                           apr_off_t end)
    {
        apr_bucket *first = NULL, *last = NULL, *out_first = NULL, *e;
        apr_uint64_t pos = 0, off_first = 0, off_last = 0;
        apr_status_t rv;
        apr_uint64_t start64, end64;
        apr_off_t pofft = 0;
    
        /*
         * Once we know that start and end are >= 0 convert everything to apr_uint64_t.
         * See the comments in apr_brigade_partition why.
         * In short apr_off_t (for values >= 0)and apr_size_t fit into apr_uint64_t.
         */
        start64 = (apr_uint64_t)start;
        end64 = (apr_uint64_t)end;
    
        if (start < 0 || end < 0 || start64 > end64)
            return APR_EINVAL;
    
        for (e = APR_BRIGADE_FIRST(bb);
             e != APR_BRIGADE_SENTINEL(bb);
             e = APR_BUCKET_NEXT(e))
        {
            apr_uint64_t elen64;
            /* we know that no bucket has undefined length (-1) */
            AP_DEBUG_ASSERT(e->length != (apr_size_t)(-1));
            elen64 = (apr_uint64_t)e->length;
            if (!first && (elen64 + pos > start64)) {
                first = e;
                off_first = pos;
            }
            if (elen64 + pos > end64) {
                last = e;
                off_last = pos;
                break;
            }
            pos += elen64;
        }
        if (!first || !last)
            return APR_EINVAL;
    
        e = first;
        while (1)
        {
            apr_bucket *copy;
            AP_DEBUG_ASSERT(e != APR_BRIGADE_SENTINEL(bb));
            rv = apr_bucket_copy(e, &copy);
            if (rv != APR_SUCCESS) {
                apr_brigade_cleanup(bbout);
                return rv;
            }
    
            APR_BRIGADE_INSERT_TAIL(bbout, copy);
            if (e == first) {
                if (off_first != start64) {
                    rv = apr_bucket_split(copy, (apr_size_t)(start64 - off_first));
                    if (rv != APR_SUCCESS) {
                        apr_brigade_cleanup(bbout);
                        return rv;
                    }
                    out_first = APR_BUCKET_NEXT(copy);
                    apr_bucket_delete(copy);
                }
                else {
                    out_first = copy;
                }
            }
            if (e == last) {
                if (e == first) {
                    off_last += start64 - off_first;
                    copy = out_first;
                }
                if (end64 - off_last != (apr_uint64_t)e->length) {
                    rv = apr_bucket_split(copy, (apr_size_t)(end64 + 1 - off_last));
                    if (rv != APR_SUCCESS) {
                        apr_brigade_cleanup(bbout);
                        return rv;
                    }
                    copy = APR_BUCKET_NEXT(copy);
                    if (copy != APR_BRIGADE_SENTINEL(bbout)) {
                        apr_bucket_delete(copy);
                    }
                }
                break;
            }
            e = APR_BUCKET_NEXT(e);
        }
    
        AP_DEBUG_ASSERT(APR_SUCCESS == apr_brigade_length(bbout, 1, &pofft));
        pos = (apr_uint64_t)pofft;
        AP_DEBUG_ASSERT(pos == end64 - start64 + 1);
        return APR_SUCCESS;
    }
    
    static apr_status_t send_416(ap_filter_t *f, apr_bucket_brigade *tmpbb)
    {
        apr_bucket *e;
        conn_rec *c = f->r->connection;
        ap_remove_output_filter(f);
        f->r->status = HTTP_OK;
        e = ap_bucket_error_create(HTTP_RANGE_NOT_SATISFIABLE, NULL,
                                   f->r->pool, c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(tmpbb, e);
        e = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(tmpbb, e);
        return ap_pass_brigade(f->next, tmpbb);
    }
    
    AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f,
                                                             apr_bucket_brigade *bb)
    {
        request_rec *r = f->r;
        conn_rec *c = r->connection;
        apr_bucket *e;
        apr_bucket_brigade *bsend;
        apr_bucket_brigade *tmpbb;
        apr_off_t range_start;
        apr_off_t range_end;
        apr_off_t clength = 0;
        apr_status_t rv;
        int found = 0;
        int num_ranges;
        char *bound_head = NULL;
        apr_array_header_t *indexes;
        indexes_t *idx;
        int i;
        int original_status;
        int max_ranges, max_overlaps, max_reversals;
        int overlaps = 0, reversals = 0;
        core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config);
    
        max_ranges = ( (core_conf->max_ranges >= 0 || core_conf->max_ranges == AP_MAXRANGES_UNLIMITED)
                       ? core_conf->max_ranges
                       : AP_DEFAULT_MAX_RANGES );
        max_overlaps = ( (core_conf->max_overlaps >= 0 || core_conf->max_overlaps == AP_MAXRANGES_UNLIMITED)
                      ? core_conf->max_overlaps
                      : AP_DEFAULT_MAX_OVERLAPS );
        max_reversals = ( (core_conf->max_reversals >= 0 || core_conf->max_reversals == AP_MAXRANGES_UNLIMITED)
                      ? core_conf->max_reversals
                      : AP_DEFAULT_MAX_REVERSALS );
        /*
         * 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);
        }
    
        original_status = r->status;
        num_ranges = ap_set_byterange(r, clength, &indexes, &overlaps, &reversals);
    
        /* No Ranges or we hit a limit? We have nothing to do, get out of the way. */
        if (num_ranges == 0 ||
            (max_ranges >= 0 && num_ranges > max_ranges) ||
            (max_overlaps >= 0 && overlaps > max_overlaps) ||
            (max_reversals >= 0 && reversals > max_reversals)) {
            r->status = original_status;
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, bb);
        }
    
        /* this brigade holds what we will be sending */
        bsend = apr_brigade_create(r->pool, c->bucket_alloc);
    
        if (num_ranges < 0)
            return send_416(f, bsend);
    
        if (num_ranges > 1) {
            /* Is ap_make_content_type required here? */
            const char *orig_ct = ap_make_content_type(r, r->content_type);
    
            ap_set_content_type_ex(r, apr_pstrcat(r->pool,
                                               "multipart/byteranges; boundary=",
                                               ap_multipart_boundary, NULL), 1);
    
            if (orig_ct) {
                bound_head = apr_pstrcat(r->pool,
                                         CRLF "--", ap_multipart_boundary,
                                         CRLF "Content-type: ",
                                         orig_ct,
                                         CRLF "Content-range: bytes ",
                                         NULL);
            }
            else {
                /* if we have no type for the content, do our best */
                bound_head = apr_pstrcat(r->pool,
                                         CRLF "--", ap_multipart_boundary,
                                         CRLF "Content-range: bytes ",
                                         NULL);
            }
            ap_xlate_proto_to_ascii(bound_head, strlen(bound_head));
        }
    
        tmpbb = apr_brigade_create(r->pool, c->bucket_alloc);
    
        idx = (indexes_t *)indexes->elts;
        for (i = 0; i < indexes->nelts; i++, idx++) {
            range_start = idx->start;
            range_end = idx->end;
    
            rv = copy_brigade_range(bb, tmpbb, range_start, range_end);
            if (rv != APR_SUCCESS ) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01584)
                              "copy_brigade_range() failed [%" APR_OFF_T_FMT
                              "-%" APR_OFF_T_FMT ",%" APR_OFF_T_FMT "]",
                              range_start, range_end, clength);
                continue;
            }
            found = 1;
    
            /*
             * For single range requests, we must produce Content-Range header.
             * Otherwise, we need to produce the multipart boundaries.
             */
            if (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(bound_head, strlen(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);
            }
    
            APR_BRIGADE_CONCAT(bsend, tmpbb);
            if (i && !(i & 0x1F)) {
                /*
                 * Every now and then, pass what we have down the filter chain.
                 * In this case, the content-length filter cannot calculate and
                 * set the content length and we must remove any Content-Length
                 * header already present.
                 */
                apr_table_unset(r->headers_out, "Content-Length");
                if ((rv = ap_pass_brigade(f->next, bsend)) != APR_SUCCESS)
                    return rv;
                apr_brigade_cleanup(bsend);
            }
        }
    
        if (found == 0) {
            /* bsend is assumed to be empty if we get here. */
            return send_416(f, bsend);
        }
    
        if (num_ranges > 1) {
            char *end;
    
            /* add the final boundary */
            end = apr_pstrcat(r->pool, CRLF "--", ap_multipart_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_cleanup(bb);
        apr_brigade_destroy(tmpbb);
    
        /* send our multipart output */
        return ap_pass_brigade(f->next, bsend);
    }
    �����������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/http_request.c������������������������������������������������������������0000664�0001751�0001751�00000073174�14675527312�020174� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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 <stdarg.h>
    #endif
    
    APLOG_USE_MODULE(http);
    
    /*****************************************************************
     *
     * 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;
        }
    }
    
    static void ap_die_r(int type, request_rec *r, int recursive_error)
    {
        char *custom_response;
        request_rec *r_1st_err = r;
    
        if (type == OK || type == DONE) {
            ap_finalize_request_protocol(r);
            return;
        }
    
        if (!ap_is_HTTP_VALID_RESPONSE(type)) {
            ap_filter_t *next;
    
            /*
             * Check if we still have the ap_http_header_filter in place. If
             * this is the case we should not ignore the error here because
             * it means that we have not sent any response at all and never
             * will. This is bad. Sent an internal server error instead.
             */
            next = r->output_filters;
            while (next && (next->frec != ap_http_header_filter_handle)) {
                   next = next->next;
            }
    
            /*
             * If next != NULL then we left the while above because of
             * next->frec == ap_http_header_filter
             */
            if (next) {
                if (type != AP_FILTER_ERROR) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01579)
                                  "Invalid response status %i", type);
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02831)
                                  "Response from AP_FILTER_ERROR");
                }
                type = HTTP_INTERNAL_SERVER_ERROR;
            }
            else {
                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 (recursive_error != HTTP_OK) {
            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! */
        }
        else {
            int error_index = ap_index_of_response(type);
            custom_response = ap_response_code_string(r, error_index);
            recursive_error = 0;
        }
    
        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, *original_method;
                int original_method_number;
                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);
                }
                original_method = r->method;
                original_method_number = r->method_number;
                r->method = "GET";
                r->method_number = M_GET;
                ap_internal_redirect(custom_response, r);
                /* preserve ability to see %<m in the access log */
                r->method = original_method;
                r->method_number = original_method_number;
                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, APLOGNO(01580)
                            "Invalid error redirection directive: %s",
                            custom_response);
            }
        }
        ap_send_error_response(r_1st_err, recursive_error);
    }
    
    AP_DECLARE(void) ap_die(int type, request_rec *r)
    {
        ap_die_r(type, r, r->status);
    }
    
    AP_DECLARE(apr_status_t) ap_check_pipeline(conn_rec *c, apr_bucket_brigade *bb,
                                               unsigned int max_blank_lines)
    {
        apr_status_t rv = APR_EOF;
        ap_input_mode_t mode = AP_MODE_SPECULATIVE;
        unsigned int num_blank_lines = 0;
        apr_size_t cr = 0;
        char buf[2];
    
        while (c->keepalive != AP_CONN_CLOSE && !c->aborted) {
            apr_size_t len = cr + 1;
    
            apr_brigade_cleanup(bb);
            rv = ap_get_brigade(c->input_filters, bb, mode,
                                APR_NONBLOCK_READ, len);
            if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
                if (mode == AP_MODE_READBYTES) {
                    /* Unexpected error, stop with this connection */
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02967)
                                  "Can't consume pipelined empty lines");
                    c->keepalive = AP_CONN_CLOSE;
                    rv = APR_EGENERAL;
                }
                else if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
                    /* Pipe is dead */
                    c->keepalive = AP_CONN_CLOSE;
                }
                else {
                    /* Pipe is up and empty */
                    rv = APR_EAGAIN;
                }
                break;
            }
            if (!max_blank_lines) {
                apr_off_t n = 0;
                /* Single read asked, (non-meta-)data available? */
                rv = apr_brigade_length(bb, 0, &n);
                if (rv == APR_SUCCESS && n <= 0) {
                    rv = APR_EAGAIN;
                }
                break;
            }
    
            /* Lookup and consume blank lines */
            rv = apr_brigade_flatten(bb, buf, &len);
            if (rv != APR_SUCCESS || len != cr + 1) {
                int log_level;
                if (mode == AP_MODE_READBYTES) {
                    /* Unexpected error, stop with this connection */
                    c->keepalive = AP_CONN_CLOSE;
                    log_level = APLOG_ERR;
                    rv = APR_EGENERAL;
                }
                else {
                    /* Let outside (non-speculative/blocking) read determine
                     * where this possible failure comes from (metadata,
                     * morphed EOF socket, ...). Debug only here.
                     */
                    log_level = APLOG_DEBUG;
                    rv = APR_SUCCESS;
                }
                ap_log_cerror(APLOG_MARK, log_level, rv, c, APLOGNO(02968)
                              "Can't check pipelined data");
                break;
            }
    
            if (mode == AP_MODE_READBYTES) {
                /* [CR]LF consumed, try next */
                mode = AP_MODE_SPECULATIVE;
                cr = 0;
            }
            else if (cr) {
                AP_DEBUG_ASSERT(len == 2 && buf[0] == APR_ASCII_CR);
                if (buf[1] == APR_ASCII_LF) {
                    /* consume this CRLF */
                    mode = AP_MODE_READBYTES;
                    num_blank_lines++;
                }
                else {
                    /* CR(?!LF) is data */
                    break;
                }
            }
            else {
                if (buf[0] == APR_ASCII_LF) {
                    /* consume this LF */
                    mode = AP_MODE_READBYTES;
                    num_blank_lines++;
                }
                else if (buf[0] == APR_ASCII_CR) {
                    cr = 1;
                }
                else {
                    /* Not [CR]LF, some data */
                    break;
                }
            }
            if (num_blank_lines > max_blank_lines) {
                /* Enough blank lines with this connection,
                 * stop and don't recycle it.
                 */
                c->keepalive = AP_CONN_CLOSE;
                rv = APR_NOTFOUND;
                break;
            }
        }
    
        return rv;
    }
    
    #define RETRIEVE_BRIGADE_FROM_POOL(bb, key, pool, allocator) do {       \
        apr_pool_userdata_get((void **)&bb, key, pool);                     \
        if (bb == NULL) {                                                   \
            bb = apr_brigade_create(pool, allocator);                       \
            apr_pool_userdata_setn((const void *)bb, key, NULL, pool);      \
        }                                                                   \
        else {                                                              \
            apr_brigade_cleanup(bb);                                        \
        }                                                                   \
    } while(0)
    
    AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
    {
        apr_bucket_brigade *bb;
        apr_bucket *b;
        conn_rec *c = r->connection;
        apr_status_t rv;
    
        /* Send an EOR bucket through the output filter chain.  When
         * this bucket is destroyed, the request will be logged and
         * its pool will be freed
         */
        RETRIEVE_BRIGADE_FROM_POOL(bb, "ap_process_request_after_handler_brigade",
                                   c->pool, c->bucket_alloc);
        b = ap_bucket_eor_create(c->bucket_alloc, r);
        APR_BRIGADE_INSERT_HEAD(bb, b);
    
        ap_pass_brigade(c->output_filters, bb);
        
        /* The EOR bucket has either been handled by an output filter (eg.
         * deleted or moved to a buffered_bb => no more in bb), or an error
         * occured before that (eg. c->aborted => still in bb) and we ought
         * to destroy it now. So cleanup any remaining bucket along with
         * the orphan request (if any).
         */
        apr_brigade_cleanup(bb);
    
        /* From here onward, it is no longer safe to reference r
         * or r->pool, because r->pool may have been destroyed
         * already by the EOR bucket's cleanup function.
         */
    
        /* Check pipeline consuming blank lines, they must not be interpreted as
         * the next pipelined request, otherwise we would block on the next read
         * without flushing data, and hence possibly delay pending response(s)
         * until the next/real request comes in or the keepalive timeout expires.
         */
        rv = ap_check_pipeline(c, bb, DEFAULT_LIMIT_BLANK_LINES);
        c->data_in_input_filters = (rv == APR_SUCCESS);
        apr_brigade_cleanup(bb);
    
        if (c->cs)
            c->cs->state = (c->aborted) ? CONN_STATE_LINGER
                                        : CONN_STATE_WRITE_COMPLETION;
        AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status);
        if (ap_extended_status) {
            ap_time_process_request(c->sbh, STOP_PREQUEST);
        }
    }
    
    void ap_process_async_request(request_rec *r)
    {
        conn_rec *c = r->connection;
        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.
         */
        AP_PROCESS_REQUEST_ENTRY((uintptr_t)r, r->uri);
        if (ap_extended_status) {
            ap_time_process_request(r->connection->sbh, START_PREQUEST);
        }
    
        if (APLOGrtrace4(r)) {
            int i;
            const apr_array_header_t *t_h = apr_table_elts(r->headers_in);
            const apr_table_entry_t *t_elt = (apr_table_entry_t *)t_h->elts;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                          "Headers received from client:");
            for (i = 0; i < t_h->nelts; i++, t_elt++) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "  %s: %s",
                              ap_escape_logitem(r->pool, t_elt->key),
                              ap_escape_logitem(r->pool, t_elt->val));
            }
        }
    
    #if APR_HAS_THREADS
        apr_thread_mutex_create(&r->invoke_mtx, APR_THREAD_MUTEX_DEFAULT, r->pool);
        apr_thread_mutex_lock(r->invoke_mtx);
    #endif
        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 == SUSPENDED) {
            /* TODO: Should move these steps into a generic function, so modules
             * working on a suspended request can also call _ENTRY again.
             */
            AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, access_status);
            if (ap_extended_status) {
                ap_time_process_request(c->sbh, STOP_PREQUEST);
            }
            if (c->cs)
                c->cs->state = CONN_STATE_SUSPENDED;
    #if APR_HAS_THREADS
            apr_thread_mutex_unlock(r->invoke_mtx);
    #endif
            return;
        }
    #if APR_HAS_THREADS
        apr_thread_mutex_unlock(r->invoke_mtx);
    #endif
    
        ap_die_r(access_status, r, HTTP_OK);
    
        ap_process_request_after_handler(r);
    }
    
    AP_DECLARE(void) ap_process_request(request_rec *r)
    {
        apr_bucket_brigade *bb;
        apr_bucket *b;
        conn_rec *c = r->connection;
        apr_status_t rv;
    
        ap_process_async_request(r);
    
        if (!c->data_in_input_filters) {
            RETRIEVE_BRIGADE_FROM_POOL(bb, "ap_process_request_brigade", 
                                       c->pool, c->bucket_alloc);
            b = apr_bucket_flush_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_HEAD(bb, b);
            rv = ap_pass_brigade(c->output_filters, bb);
            if (APR_STATUS_IS_TIMEUP(rv)) {
                /*
                 * Notice a timeout as an error message. This might be
                 * valuable for detecting clients with broken network
                 * connections or possible DoS attacks.
                 */
                ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, c, APLOGNO(01581)
                              "flushing data to the client");
            }
            apr_brigade_cleanup(bb);
        }
        if (ap_extended_status) {
            ap_time_process_request(c->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;
        const char *vary_header;
    
        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->parsed_uri.port_str = r->parsed_uri.port_str;
        new->parsed_uri.port = r->parsed_uri.port;
    
        new->request_config = ap_create_request_config(r->pool);
    
        new->per_dir_config = r->server->lookup_defaults;
    
        new->prev = r;
        r->next   = new;
    
        new->useragent_addr = r->useragent_addr;
        new->useragent_ip = r->useragent_ip;
    
        /* 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->trailers_in     = r->trailers_in;
        new->headers_out     = apr_table_make(r->pool, 12);
        if (ap_is_HTTP_REDIRECT(new->status)) {
            const char *location = apr_table_get(r->headers_out, "Location");
            if (location)
                apr_table_setn(new->headers_out, "Location", location);
        }
    
        /* A module (like mod_rewrite) can force an internal redirect
         * to carry over the Vary header (if present).
         */
        if (apr_table_get(r->notes, "redirect-keeps-vary")) {
            if((vary_header = apr_table_get(r->headers_out, "Vary"))) {
                apr_table_setn(new->headers_out, "Vary", vary_header);
            }
        }
    
        new->err_headers_out = r->err_headers_out;
        new->trailers_out    = apr_table_make(r->pool, 5);
        new->subprocess_env  = rename_original_env(r->pool, r->subprocess_env);
        new->notes           = apr_table_make(r->pool, 5);
    
        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->input_filters   = new->proto_input_filters;
    
        if (new->main) {
            ap_filter_t *f, *nextf;
    
            /* If this is a subrequest, the filter chain may contain a
             * mixture of filters specific to the old request (r), and
             * some inherited from r->main.  Here, inherit that filter
             * chain, and remove all those which are specific to the old
             * request; ensuring the subreq filter is left in place. */
            new->output_filters = r->output_filters;
    
            f = new->output_filters;
            do {
                nextf = f->next;
    
                if (f->r == r && f->frec != ap_subreq_core_filter_handle) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01582)
                                  "dropping filter '%s' in internal redirect from %s to %s",
                                  f->frec->name, r->unparsed_uri, new_uri);
    
                    /* To remove the filter, first set f->r to the *new*
                     * request_rec, so that ->output_filters on 'new' is
                     * changed (if necessary) when removing the filter. */
                    f->r = new;
                    ap_remove_output_filter(f);
                }
    
                f = nextf;
    
                /* Stop at the protocol filters.  If a protocol filter has
                 * been newly installed for this resource, better leave it
                 * in place, though it's probably a misconfiguration or
                 * filter bug to get into this state. */
            } while (f && f != new->proto_output_filters);
        }
        else {
            /* If this is not a subrequest, clear out all
             * resource-specific filters. */
            new->output_filters  = new->proto_output_filters;
        }
    
        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));
    
        /* Begin by presuming any module can make its own path_info assumptions,
         * until some module interjects and changes the value.
         */
        new->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
    
    #if APR_HAS_THREADS
        new->invoke_mtx = r->invoke_mtx;
    #endif
    
        /*
         * 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_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_ex(r, rr->content_type, AP_REQUEST_IS_TRUSTED_CT(rr));
        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->trailers_out = apr_table_overlay(r->pool, rr->trailers_out,
                                               r->trailers_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 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);
    
        if (r->main) {
            ap_filter_t *next = r->output_filters;
            while (next && (next != r->proto_output_filters)) {
                if (next->frec == ap_subreq_core_filter_handle) {
                    break;
                }
                next = next->next;
            }
            if (!next || next == r->proto_output_filters) {
                ap_add_output_filter_handle(ap_subreq_core_filter_handle,
                                            NULL, r, r->connection);
            }
        }
        else {
            /*
             * We need to check if we now have the SUBREQ_CORE filter in our filter
             * chain. If this is the case we need to remove it since we are NO
             * subrequest. But we need to keep in mind that the SUBREQ_CORE filter
             * does not necessarily need to be the first filter in our chain. So we
             * need to go through the chain. But we only need to walk up the chain
             * until the proto_output_filters as the SUBREQ_CORE filter is below the
             * protocol filters.
             */
            ap_filter_t *next;
    
            next = r->output_filters;
            while (next && (next->frec != ap_subreq_core_filter_handle)
                   && (next != r->proto_output_filters)) {
                    next = next->next;
            }
            if (next && (next->frec == ap_subreq_core_filter_handle)) {
                ap_remove_output_filter(next);
            }
        }
    }
    
    AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
    {
        int access_status;
        request_rec *new = internal_internal_redirect(new_uri, r);
    
        AP_INTERNAL_REDIRECT(r->uri, new_uri);
    
        /* 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);
            }
        }
        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_ex(new, r->content_type, AP_REQUEST_IS_TRUSTED_CT(r));
        access_status = ap_process_request_internal(new);
        if (access_status == OK) {
            access_status = ap_invoke_handler(new);
        }
        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);
        }
        va_end(methods);
    }
    
    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;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/http_etag.c���������������������������������������������������������������0000664�0001751�0001751�00000027051�14021735472�017406� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 */
    #include "apr_sha1.h"
    #include "apr_base64.h"
    #include "apr_buckets.h"
    
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_connection.h"
    #include "http_core.h"
    #include "http_log.h"
    #include "http_protocol.h"   /* For index_of_response().  Grump. */
    #include "http_request.h"
    
    #if APR_HAS_MMAP
    #include "apr_mmap.h"
    #endif /* APR_HAS_MMAP */
    
    #define SHA1_DIGEST_BASE64_LEN 4*(APR_SHA1_DIGESTSIZE/3)
    
    /* Generate the human-readable hex representation of an apr_uint64_t
     * (basically a faster version of 'sprintf("%llx")')
     */
    #define HEX_DIGITS "0123456789abcdef"
    static char *etag_uint64_to_hex(char *next, apr_uint64_t u)
    {
        int printing = 0;
        int shift = sizeof(apr_uint64_t) * 8 - 4;
        do {
            unsigned short next_digit = (unsigned short)
                                        ((u >> shift) & (apr_uint64_t)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 & (apr_uint64_t)0xf];
        return next;
    }
    
    #define ETAG_WEAK "W/"
    #define CHARS_PER_UINT64 (sizeof(apr_uint64_t) * 2)
    
    static void etag_start(char *etag, const char *weak, char **next)
    {
        if (weak) {
            while (*weak) {
                *etag++ = *weak++;
            }
        }
        *etag++ = '"';
    
        *next = etag;
    }
    
    static void etag_end(char *next, const char *vlv, apr_size_t vlv_len)
    {
        if (vlv) {
            *next++ = ';';
            apr_cpystrn(next, vlv, vlv_len);
        }
        else {
            *next++ = '"';
            *next = '\0';
        }
    }
    
    /*
     * Construct a strong ETag by creating a SHA1 hash across the file content.
     */
    static char *make_digest_etag(request_rec *r, etag_rec *er, char *vlv,
            apr_size_t vlv_len, char *weak, apr_size_t weak_len)
    {
        apr_sha1_ctx_t context;
        unsigned char digest[APR_SHA1_DIGESTSIZE];
        apr_file_t *fd = NULL;
        core_dir_config *cfg;
        char *etag, *next;
        apr_bucket_brigade *bb;
        apr_bucket *e;
    
        apr_size_t nbytes;
        apr_off_t offset = 0, zero = 0, len = 0;
        apr_status_t status;
    
        cfg = (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
    
        if (er->fd) {
            fd = er->fd;
        }
        else if (er->pathname) {
            if ((status = apr_file_open(&fd, er->pathname, APR_READ | APR_BINARY,
                    0, r->pool)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(10251)
                              "Make etag: could not open %s", er->pathname);
                return "";
            }
        }
        if (!fd) {
            return "";
        }
    
        if ((status = apr_file_seek(fd, APR_CUR, &offset)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(10252)
                          "Make etag: could not seek");
            if (er->pathname) {
                apr_file_close(fd);
            }
            return "";
        }
    
        if ((status = apr_file_seek(fd, APR_END, &len)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(10258)
                          "Make etag: could not seek");
            if (er->pathname) {
                apr_file_close(fd);
            }
            return "";
        }
    
        if ((status = apr_file_seek(fd, APR_SET, &zero)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(10253)
                          "Make etag: could not seek");
            if (er->pathname) {
                apr_file_close(fd);
            }
            return "";
        }
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        e = apr_brigade_insert_file(bb, fd, 0, len, r->pool);
    
    #if APR_HAS_MMAP
        if (cfg->enable_mmap == ENABLE_MMAP_OFF) {
            (void)apr_bucket_file_enable_mmap(e, 0);
        }
    #endif
    
        apr_sha1_init(&context);
        while (!APR_BRIGADE_EMPTY(bb))
        {
            const char *str;
    
            e = APR_BRIGADE_FIRST(bb);
    
            if ((status = apr_bucket_read(e, &str, &nbytes, APR_BLOCK_READ)) != APR_SUCCESS) {
            	apr_brigade_destroy(bb);
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(10254)
                              "Make etag: could not read");
                if (er->pathname) {
                    apr_file_close(fd);
                }
                return "";
            }
    
            apr_sha1_update(&context, str, nbytes);
            apr_bucket_delete(e);
        }
    
        if ((status = apr_file_seek(fd, APR_SET, &offset)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(10255)
                          "Make etag: could not seek");
            if (er->pathname) {
                apr_file_close(fd);
            }
            return "";
        }
        apr_sha1_final(digest, &context);
    
        etag = apr_palloc(r->pool, weak_len + sizeof("\"\"") +
                SHA1_DIGEST_BASE64_LEN + vlv_len + 4);
    
        etag_start(etag, weak, &next);
        next += apr_base64_encode_binary(next, digest, APR_SHA1_DIGESTSIZE) - 1;
        etag_end(next, vlv, vlv_len);
    
        if (er->pathname) {
            apr_file_close(fd);
        }
    
        return etag;
    }
    
    /*
     * 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.
     */
    AP_DECLARE(char *) ap_make_etag_ex(request_rec *r, etag_rec *er)
    {
        char *weak = NULL;
        apr_size_t weak_len = 0, vlv_len = 0;
        char *etag, *next, *vlv;
        core_dir_config *cfg;
        etag_components_t etag_bits;
        etag_components_t bits_added;
    
        cfg = (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
        etag_bits = (cfg->etag_bits & (~ cfg->etag_remove)) | cfg->etag_add;
    
        if (er->force_weak) {
            weak = ETAG_WEAK;
            weak_len = sizeof(ETAG_WEAK);
        }
    
        if (r->vlist_validator) {
    
            /* 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;
            if (vlv[0] == 'W') {
                vlv += 3;
                weak = ETAG_WEAK;
                weak_len = sizeof(ETAG_WEAK);
            }
            else {
                vlv++;
            }
            vlv_len = strlen(vlv);
    
        }
        else {
            vlv = NULL;
            vlv_len = 0;
        }
    
        /*
         * Did a module flag the need for a strong etag, or did the
         * configuration tell us to generate a digest?
         */
        if (er->finfo->filetype == APR_REG &&
                (AP_REQUEST_IS_STRONG_ETAG(r) || (etag_bits & ETAG_DIGEST))) {
    
            return make_digest_etag(r, er, vlv, vlv_len, weak, weak_len);
        }
    
        /*
         * 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) {
            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 ((er->request_time - er->finfo->mtime < (1 * APR_USEC_PER_SEC))) {
            weak = ETAG_WEAK;
            weak_len = sizeof(ETAG_WEAK);
        }
    
        if (er->finfo->filetype != APR_NOFILE) {
            /*
             * ETag gets set to [W/]"inode-size-mtime", modulo any
             * FileETag keywords.
             */
            etag = apr_palloc(r->pool, weak_len + sizeof("\"--\"") +
                              3 * CHARS_PER_UINT64 + vlv_len + 2);
    
            etag_start(etag, weak, &next);
    
            bits_added = 0;
            if (etag_bits & ETAG_INODE) {
                next = etag_uint64_to_hex(next, er->finfo->inode);
                bits_added |= ETAG_INODE;
            }
            if (etag_bits & ETAG_SIZE) {
                if (bits_added != 0) {
                    *next++ = '-';
                }
                next = etag_uint64_to_hex(next, er->finfo->size);
                bits_added |= ETAG_SIZE;
            }
            if (etag_bits & ETAG_MTIME) {
                if (bits_added != 0) {
                    *next++ = '-';
                }
                next = etag_uint64_to_hex(next, er->finfo->mtime);
            }
    
            etag_end(next, vlv, vlv_len);
    
        }
        else {
            /*
             * Not a file document, so just use the mtime: [W/]"mtime"
             */
            etag = apr_palloc(r->pool, weak_len + sizeof("\"\"") +
                              CHARS_PER_UINT64 + vlv_len + 2);
    
            etag_start(etag, weak, &next);
            next = etag_uint64_to_hex(next, er->finfo->mtime);
            etag_end(next, vlv, vlv_len);
    
        }
    
        return etag;
    }
    
    AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak)
    {
        etag_rec er;
    
        er.vlist_validator = NULL;
        er.request_time = r->request_time;
        er.finfo = &r->finfo;
        er.pathname = r->filename;
        er.fd = NULL;
        er.force_weak = force_weak;
    
        return ap_make_etag_ex(r, &er);
    }
    
    AP_DECLARE(void) ap_set_etag(request_rec *r)
    {
        char *etag;
    
        etag_rec er;
    
        er.vlist_validator = r->vlist_validator;
        er.request_time = r->request_time;
        er.finfo = &r->finfo;
        er.pathname = r->filename;
        er.fd = NULL;
        er.force_weak = 0;
    
        etag = ap_make_etag_ex(r, &er);
    
        if (etag && etag[0]) {
            apr_table_setn(r->headers_out, "ETag", etag);
        }
        else {
            apr_table_setn(r->notes, "no-etag", "omit");
        }
    
    }
    
    AP_DECLARE(void) ap_set_etag_fd(request_rec *r, apr_file_t *fd)
    {
        char *etag;
    
        etag_rec er;
    
        er.vlist_validator = r->vlist_validator;
        er.request_time = r->request_time;
        er.finfo = &r->finfo;
        er.pathname = NULL;
        er.fd = fd;
        er.force_weak = 0;
    
        etag = ap_make_etag_ex(r, &er);
    
        if (etag && etag[0]) {
            apr_table_setn(r->headers_out, "ETag", etag);
        }
        else {
            apr_table_setn(r->notes, "no-etag", "omit");
        }
    
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/config.m4�����������������������������������������������������������������0000664�0001751�0001751�00000002160�11465233725�016767� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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.  The http module is a basic one that enables 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.], $http_objects, , static)
    APACHE_MODULE(mime, mapping of file-extension to MIME.  Disabling this module is normally not recommended., , , yes)
    
    APACHE_MODPATH_FINISH
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/mod_mime.c����������������������������������������������������������������0000664�0001751�0001751�00000106027�14636331332�017215� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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)
    {
        const extension_info *overlay_info = (const extension_info *)overlay_val;
        const extension_info *base_info = (const extension_info *)base_val;
        extension_info *new_info = apr_pmemdup(p, 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 = apr_pmemdup(p, copyinfo, sizeof(*exinfo));
                apr_hash_set(mappings, suffix[i].name,
                             APR_HASH_KEY_STRING, 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;
    }
    
    /*
     * As RemoveType should also override the info from TypesConfig, we add an
     * empty string as type instead of actually removing the type.
     */
    static const char *remove_extension_type(cmd_parms *cmd, void *m_,
                                             const char *ext)
    {
        return add_extension_info(cmd, m_, "", ext);
    }
    
    /*
     * 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_;
        const char *errmsg;
    
        errmsg = ap_check_cmd_context(cmd, NOT_IN_LOCATION);
        if (errmsg != NULL) {
            return errmsg;
        }
    
        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_type,
            (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, APLOGNO(01596)
                         "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, APLOGNO(01597)
                         "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 == '\\') {
            c = (int) *(s + 1);
            if (c && 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, APLOGNO(01598)
                         "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, APLOGNO(01599)
                         "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, APLOGNO(01600)
                         "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, APLOGNO(01601)
                         "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, APLOGNO(01602)
                         "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, APLOGNO(01603)
                                     "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, APLOGNO(01604)
                                     "Cannot get media parameter.");
                        return (NULL);
                    }
                    mp = cp;
                    continue;
                }
                else {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, APLOGNO(01605)
                                 "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, APLOGNO(01606)
                                             "Cannot get media parameter.");
                                return(NULL);
                            }
                            quoted = 0;
                        }
                        else {
                            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, APLOGNO(01607)
                                         "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, APLOGNO(01608)
                                         "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, APLOGNO(01609)
                                 "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, *fntmp, *type, *charset = NULL, *resource_name, *qm;
        int found_metadata = 0;
    
        if (r->finfo.filetype == APR_DIR) {
            ap_set_content_type_ex(r, DIR_MAGIC_TYPE, 1);
            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);
        }
        /*
         * In the reverse proxy case r->filename might contain a query string if
         * the nocanon option was used with ProxyPass.
         * If this is the case cut off the query string as the last parameter in
         * this query string might end up on an extension we take care about, but
         * we only want to match against path components not against query
         * parameters.
         */
        else if ((r->proxyreq == PROXYREQ_REVERSE)
                 && (apr_table_get(r->notes, "proxy-nocanon"))
                 && ((qm = ap_strchr_c(r->filename, '?')) != NULL)) {
            resource_name = apr_pstrmemdup(r->pool, r->filename, qm - r->filename);
        }
        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).
         * Leading dots are considered to be part of the base name (a file named
         * ".png" is likely not a png file but just a hidden file called png).
         */
        fntmp = fn;
        while (*fntmp == '.')
            fntmp++;
        fntmp = ap_strchr_c(fntmp, '.');
        if (fntmp) {
            ext = apr_pstrmemdup(r->pool, fn, fntmp - fn);
            fn = fntmp + 1;
        }
        else {
            ext = apr_pstrdup(r->pool, fn);
            fn += strlen(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;
            char *extcase;
    
            if (*ext == '\0') {  /* ignore empty extensions "bad..html" */
                continue;
            }
    
            found = 0;
    
            /* Save the ext in extcase before converting it to lower case.
             */
            extcase = apr_pstrdup(r->pool, ext);
            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_ex(r, (char*) type, 1);
                    found = 1;
                }
            }
    
            if (exinfo != NULL) {
    
                /* empty string is treated as special case for RemoveType */
                if (exinfo->forced_type && *exinfo->forced_type) {
                    ap_set_content_type_ex(r, exinfo->forced_type, 1);
                    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 negotiation, 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) {
                    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) {
                    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)) = extcase;
            }
        }
    
        /*
         * 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_ex(r, base_content_type, AP_REQUEST_IS_TRUSTED_CT(r));
                while (pp != NULL) {
                    if (charset && !strcmp(pp->attr, "charset")) {
                        if (!override) {
                            ap_set_content_type_ex(r,
                                                apr_pstrcat(r->pool,
                                                            r->content_type,
                                                            "; charset=",
                                                            charset,
                                                            NULL), AP_REQUEST_IS_TRUSTED_CT(r));
                            override = 1;
                        }
                    }
                    else {
                        ap_set_content_type_ex(r,
                                            apr_pstrcat(r->pool,
                                                        r->content_type,
                                                        "; ", pp->attr,
                                                        "=", pp->val,
                                                        NULL), AP_REQUEST_IS_TRUSTED_CT(r));
                    }
                    pp = pp->next;
                }
                if (charset && !override) {
                    ap_set_content_type_ex(r, apr_pstrcat(r->pool, r->content_type,
                                                       "; charset=", charset,
                                                       NULL), AP_REQUEST_IS_TRUSTED_CT(r));
                }
            }
        }
    
        /* 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;
    
            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);
         */
    }
    
    AP_DECLARE_MODULE(mime) = {
        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 */
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/mod_mime.dep��������������������������������������������������������������0000664�0001751�0001751�00000003726�12674411515�017547� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_mime.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_mime.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������httpd-2.4.64/modules/http/Makefile.in���������������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�017312� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/http_filters.c������������������������������������������������������������0000664�0001751�0001751�00000200074�15032733252�020131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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_connection.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 <stdarg.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    APLOG_USE_MODULE(http);
    
    typedef struct http_filter_ctx
    {
        apr_off_t remaining;
        apr_off_t limit;
        apr_off_t limit_used;
        apr_int32_t chunk_used;
        apr_int32_t chunk_bws;
        apr_int32_t chunkbits;
        enum
        {
            BODY_NONE, /* streamed data */
            BODY_LENGTH, /* data constrained by content length */
            BODY_CHUNK, /* chunk expected */
            BODY_CHUNK_PART, /* chunk digits */
            BODY_CHUNK_EXT, /* chunk extension */
            BODY_CHUNK_CR, /* got space(s) after digits, expect [CR]LF or ext */
            BODY_CHUNK_LF, /* got CR after digits or ext, expect LF */
            BODY_CHUNK_DATA, /* data constrained by chunked encoding */
            BODY_CHUNK_END, /* chunked data terminating CRLF */
            BODY_CHUNK_END_LF, /* got CR after data, expect LF */
            BODY_CHUNK_TRAILER /* trailers */
        } state;
        unsigned int eos_sent :1,
                     seen_data:1;
        apr_bucket_brigade *bb;
    } http_ctx_t;
    
    /* bail out if some error in the HTTP input filter happens */
    static apr_status_t bail_out_on_error(http_ctx_t *ctx,
                                          ap_filter_t *f,
                                          int http_error)
    {
        apr_bucket *e;
        apr_bucket_brigade *bb = ctx->bb;
    
        apr_brigade_cleanup(bb);
    
        if (f->r->proxyreq == PROXYREQ_RESPONSE) {
            switch (http_error) {
            case HTTP_REQUEST_ENTITY_TOO_LARGE:
                return APR_ENOSPC;
    
            case HTTP_REQUEST_TIME_OUT:
                return APR_INCOMPLETE;
    
            case HTTP_NOT_IMPLEMENTED:
                return APR_ENOTIMPL;
    
            default:
                return APR_EGENERAL;
            }
        }
    
        e = ap_bucket_error_create(http_error,
                                   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;
        /* If chunked encoding / content-length are corrupt, we may treat parts
         * of this request's body as the next one's headers.
         * To be safe, disable keep-alive.
         */
        f->r->connection->keepalive = AP_CONN_CLOSE;
        return ap_pass_brigade(f->r->output_filters, bb);
    }
    
    /**
     * Parse a chunk line with optional extension, detect overflow.
     * There are several error cases:
     *  1) If the chunk link is misformatted, APR_EINVAL is returned.
     *  2) If the conversion would require too many bits, APR_EGENERAL is returned.
     *  3) If the conversion used the correct number of bits, but an overflow
     *     caused only the sign bit to flip, then APR_ENOSPC is returned.
     * A negative chunk length always indicates an overflow error.
     */
    static apr_status_t parse_chunk_size(http_ctx_t *ctx, const char *buffer,
                                         apr_size_t len, int linelimit, int strict)
    {
        apr_size_t i = 0;
    
        while (i < len) {
            char c = buffer[i];
    
            ap_xlate_proto_from_ascii(&c, 1);
    
            /* handle CRLF after the chunk */
            if (ctx->state == BODY_CHUNK_END
                    || ctx->state == BODY_CHUNK_END_LF) {
                if (c == LF) {
                    if (strict && (ctx->state != BODY_CHUNK_END_LF)) {
                        /*
                         * CR missing before LF.
                         */
                        return APR_EINVAL;
                    }
                    ctx->state = BODY_CHUNK;
                }
                else if (c == CR && ctx->state == BODY_CHUNK_END) {
                    ctx->state = BODY_CHUNK_END_LF;
                }
                else {
                    /*
                     * CRLF expected.
                     */
                    return APR_EINVAL;
                }
                i++;
                continue;
            }
    
            /* handle start of the chunk */
            if (ctx->state == BODY_CHUNK) {
                if (!apr_isxdigit(c)) {
                    /*
                     * Detect invalid character at beginning. This also works for
                     * empty chunk size lines.
                     */
                    return APR_EINVAL;
                }
                else {
                    ctx->state = BODY_CHUNK_PART;
                }
                ctx->remaining = 0;
                ctx->chunkbits = sizeof(apr_off_t) * 8;
                ctx->chunk_used = 0;
                ctx->chunk_bws = 0;
            }
    
            if (c == LF) {
                if (strict && (ctx->state != BODY_CHUNK_LF)) {
                    /*
                     * CR missing before LF.
                     */
                    return APR_EINVAL;
                }
                if (ctx->remaining) {
                    ctx->state = BODY_CHUNK_DATA;
                }
                else {
                    ctx->state = BODY_CHUNK_TRAILER;
                }
            }
            else if (ctx->state == BODY_CHUNK_LF) {
                /*
                 * LF expected.
                 */
                return APR_EINVAL;
            }
            else if (c == CR) {
                ctx->state = BODY_CHUNK_LF;
            }
            else if (c == ';') {
                ctx->state = BODY_CHUNK_EXT;
            }
            else if (ctx->state == BODY_CHUNK_EXT) {
                /*
                 * Control chars (excluding tabs) are invalid.
                 * TODO: more precisely limit input
                 */
                if (c != '\t' && apr_iscntrl(c)) {
                    return APR_EINVAL;
                }
            }
            else if (c == ' ' || c == '\t') {
                /* Be lenient up to 10 implied *LWS, a legacy of RFC 2616,
                 * and noted as errata to RFC7230;
                 * https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4667
                 */
                ctx->state = BODY_CHUNK_CR;
                if (++ctx->chunk_bws > 10) {
                    return APR_EINVAL;
                }
            }
            else if (ctx->state == BODY_CHUNK_CR) {
                /*
                 * ';', CR or LF expected.
                 */
                return APR_EINVAL;
            }
            else if (ctx->state == BODY_CHUNK_PART) {
                int xvalue;
    
                /* ignore leading zeros */
                if (!ctx->remaining && c == '0') {
                    i++;
                    continue;
                }
    
                ctx->chunkbits -= 4;
                if (ctx->chunkbits < 0) {
                    /* overflow */
                    return APR_ENOSPC;
                }
    
                if (c >= '0' && c <= '9') {
                    xvalue = c - '0';
                }
                else if (c >= 'A' && c <= 'F') {
                    xvalue = c - 'A' + 0xa;
                }
                else if (c >= 'a' && c <= 'f') {
                    xvalue = c - 'a' + 0xa;
                }
                else {
                    /* bogus character */
                    return APR_EINVAL;
                }
    
                ctx->remaining = (ctx->remaining << 4) | xvalue;
                if (ctx->remaining < 0) {
                    /* overflow */
                    return APR_ENOSPC;
                }
            }
            else {
                /* Should not happen */
                return APR_EGENERAL;
            }
    
            i++;
        }
    
        /* sanity check */
        ctx->chunk_used += len;
        if (ctx->chunk_used < 0 || ctx->chunk_used > linelimit) {
            return APR_ENOSPC;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f,
                                              apr_bucket_brigade *b, int merge)
    {
        int rv;
        apr_bucket *e;
        request_rec *r = f->r;
        apr_table_t *saved_headers_in = r->headers_in;
        int saved_status = r->status;
    
        r->status = HTTP_OK;
        r->headers_in = r->trailers_in;
        apr_table_clear(r->headers_in);
        ap_get_mime_headers(r);
    
        if(r->status == HTTP_OK) {
            r->status = saved_status;
            e = apr_bucket_eos_create(f->c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(b, e);
            ctx->eos_sent = 1;
            rv = APR_SUCCESS;
        }
        else {
            const char *error_notes = apr_table_get(r->notes,
                                                    "error-notes");
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02656)
                          "Error while reading HTTP trailer: %i%s%s",
                          r->status, error_notes ? ": " : "",
                          error_notes ? error_notes : "");
            rv = APR_EINVAL;
        }
    
        if(!merge) {
            r->headers_in = saved_headers_in;
        }
        else {
            r->headers_in = apr_table_overlay(r->pool, saved_headers_in,
                    r->trailers_in);
        }
    
        return rv;
    }
    
    /* 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)
    {
        core_server_config *conf =
            (core_server_config *) ap_get_module_config(f->r->server->module_config,
                                                        &core_module);
        int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
        apr_bucket *e;
        http_ctx_t *ctx = f->ctx;
        apr_status_t rv;
        int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
        int again;
    
        /* 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_pcalloc(f->r->pool, sizeof(*ctx));
            ctx->state = BODY_NONE;
            ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
    
            /* 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 (ap_is_chunked(f->r->pool, tenc)) {
                    ctx->state = BODY_CHUNK;
                }
                else if (f->r->proxyreq == PROXYREQ_RESPONSE) {
                    /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23
                     * Section 3.3.3.3: "If a Transfer-Encoding header field is
                     * present in a response and the chunked transfer coding is not
                     * the final encoding, the message body length is determined by
                     * reading the connection until it is closed by the server."
                     */
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(02555)
                                  "Unknown Transfer-Encoding: %s; "
                                  "using read-until-close", tenc);
                    tenc = NULL;
                }
                else {
                    /* Something that isn't a HTTP request, unless some future
                     * edition defines new transfer encodings, is unsupported.
                     */
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01585)
                                  "Unknown Transfer-Encoding: %s", tenc);
                    return bail_out_on_error(ctx, f, HTTP_BAD_REQUEST);
                }
                lenp = NULL;
            }
            if (lenp) {
                ctx->state = BODY_LENGTH;
    
                /* Protects against over/underflow, non-digit chars in the
                 * string, leading plus/minus signs, trailing characters and
                 * a negative number.
                 */
                if (!ap_parse_strict_length(&ctx->remaining, lenp)) {
                    ctx->remaining = 0;
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01587)
                                  "Invalid Content-Length");
    
                    return bail_out_on_error(ctx, f, HTTP_BAD_REQUEST);
                }
    
                /* 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) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01588)
                              "Requested content-length of %" APR_OFF_T_FMT
                              " is larger than the configured limit"
                              " of %" APR_OFF_T_FMT, ctx->remaining, ctx->limit);
                    return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
                }
            }
    
            /* 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 the read is to be nonblocking though, the caller may not want to
         * handle this just now (e.g. mod_proxy_http), and is prepared to read
         * nothing if the client really waits for 100 continue, so we don't
         * send it now and wait for later blocking read.
         *
         * In any case, even if r->expecting remains set at the end of the
         * request handling, ap_set_keepalive() will finally do the right
         * thing (i.e. "Connection: close" the connection).
         */
        if (block == APR_BLOCK_READ
                && (ctx->state == BODY_CHUNK
                    || (ctx->state == BODY_LENGTH && ctx->remaining > 0))
                && f->r->expecting_100 && f->r->proto_num >= HTTP_VERSION(1,1)
                && !(ctx->eos_sent || f->r->eos_sent || f->r->bytes_sent)) {
            if (!ap_is_HTTP_SUCCESS(f->r->status)) {
                ctx->state = BODY_NONE;
                ctx->eos_sent = 1; /* send EOS below */
            }
            else if (!ctx->seen_data) {
                int saved_status = f->r->status;
                const char *saved_status_line = f->r->status_line;
                f->r->status = HTTP_CONTINUE;
                f->r->status_line = NULL;
                ap_send_interim_response(f->r, 0);
                AP_DEBUG_ASSERT(!f->r->expecting_100);
                f->r->status_line = saved_status_line;
                f->r->status = saved_status;
            }
            else {
                /* https://tools.ietf.org/html/rfc7231#section-5.1.1
                 *   A server MAY omit sending a 100 (Continue) response if it
                 *   has already received some or all of the message body for
                 *   the corresponding request [...]
                 */
                f->r->expecting_100 = 0;
            }
        }
    
        /* sanity check in case we're read twice */
        if (ctx->eos_sent) {
            e = apr_bucket_eos_create(f->c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(b, e);
            return APR_SUCCESS;
        }
    
        do {
            apr_brigade_cleanup(b);
            again = 0; /* until further notice */
    
            /* read and handle the brigade */
            switch (ctx->state) {
            case BODY_CHUNK:
            case BODY_CHUNK_PART:
            case BODY_CHUNK_EXT:
            case BODY_CHUNK_CR:
            case BODY_CHUNK_LF:
            case BODY_CHUNK_END:
            case BODY_CHUNK_END_LF: {
    
                rv = ap_get_brigade(f->next, b, AP_MODE_GETLINE, block, 0);
    
                /* for timeout */
                if (block == APR_NONBLOCK_READ
                        && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b))
                                || (APR_STATUS_IS_EAGAIN(rv)))) {
                    return APR_EAGAIN;
                }
    
                if (rv == APR_EOF) {
                    return APR_INCOMPLETE;
                }
    
                if (rv != APR_SUCCESS) {
                    return rv;
                }
    
                e = APR_BRIGADE_FIRST(b);
                while (e != APR_BRIGADE_SENTINEL(b)) {
                    const char *buffer;
                    apr_size_t len;
    
                    if (!APR_BUCKET_IS_METADATA(e)) {
                        int parsing = 0;
    
                        rv = apr_bucket_read(e, &buffer, &len, APR_BLOCK_READ);
                        if (rv == APR_SUCCESS) {
                            parsing = 1;
                            if (len > 0) {
                                ctx->seen_data = 1;
                            }
                            rv = parse_chunk_size(ctx, buffer, len,
                                    f->r->server->limit_req_fieldsize, strict);
                        }
                        if (rv != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01590)
                                          "Error reading/parsing chunk %s ",
                                          (APR_ENOSPC == rv) ? "(overflow)" : "");
                            if (parsing) {
                                if (rv != APR_ENOSPC) {
                                    http_error = HTTP_BAD_REQUEST;
                                }
                                return bail_out_on_error(ctx, f, http_error);
                            }
                            return rv;
                        }
                    }
    
                    apr_bucket_delete(e);
                    e = APR_BRIGADE_FIRST(b);
                }
                again = 1; /* come around again */
    
                if (ctx->state == BODY_CHUNK_TRAILER) {
                    /* Treat UNSET as DISABLE - trailers aren't merged by default */
                    return read_chunked_trailers(ctx, f, b,
                                conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE);
                }
    
                break;
            }
            case BODY_NONE:
            case BODY_LENGTH:
            case BODY_CHUNK_DATA: {
    
                /* Ensure that the caller can not go over our boundary point. */
                if (ctx->state != BODY_NONE && ctx->remaining < readbytes) {
                    readbytes = ctx->remaining;
                }
                if (readbytes > 0) {
                    apr_off_t totalread;
    
                    rv = ap_get_brigade(f->next, b, mode, block, readbytes);
    
                    /* for timeout */
                    if (block == APR_NONBLOCK_READ
                            && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b))
                                    || (APR_STATUS_IS_EAGAIN(rv)))) {
                        return APR_EAGAIN;
                    }
    
                    if (rv == APR_EOF && ctx->state != BODY_NONE
                            && ctx->remaining > 0) {
                        return APR_INCOMPLETE;
                    }
    
                    if (rv != APR_SUCCESS) {
                        return rv;
                    }
    
                    /* How many bytes did we just read? */
                    apr_brigade_length(b, 0, &totalread);
                    if (totalread > 0) {
                        ctx->seen_data = 1;
                    }
    
                    /* 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 (ctx->remaining > 0) {
                            e = APR_BRIGADE_LAST(b);
                            if (APR_BUCKET_IS_EOS(e)) {
                                apr_bucket_delete(e);
                                return APR_INCOMPLETE;
                            }
                        }
                        else if (ctx->state == BODY_CHUNK_DATA) {
                            /* next chunk please */
                            ctx->state = BODY_CHUNK_END;
                            ctx->chunk_used = 0;
                        }
                    }
    
                    /* 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) {
                            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r,
                                          APLOGNO(01591) "Read content length of "
                                          "%" APR_OFF_T_FMT " is larger than the "
                                          "configured limit of %" APR_OFF_T_FMT,
                                          ctx->limit_used, ctx->limit);
                            return bail_out_on_error(ctx, f,
                                                     HTTP_REQUEST_ENTITY_TOO_LARGE);
                        }
                    }
                }
    
                /* If we have no more bytes remaining on a C-L request,
                 * save the caller a round trip 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);
                    ctx->eos_sent = 1;
                }
    
                break;
            }
            case BODY_CHUNK_TRAILER: {
    
                rv = ap_get_brigade(f->next, b, mode, block, readbytes);
    
                /* for timeout */
                if (block == APR_NONBLOCK_READ
                        && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b))
                                || (APR_STATUS_IS_EAGAIN(rv)))) {
                    return APR_EAGAIN;
                }
    
                if (rv != APR_SUCCESS) {
                    return rv;
                }
    
                break;
            }
            default: {
                /* Should not happen */
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(02901)
                              "Unexpected body state (%i)", (int)ctx->state);
                return APR_EGENERAL;
            }
            }
    
        } while (again);
    
        return APR_SUCCESS;
    }
    
    struct check_header_ctx {
        request_rec *r;
        int strict;
    };
    
    /* check a single header, to be used with apr_table_do() */
    static int check_header(struct check_header_ctx *ctx,
                            const char *name, const char **val)
    {
        const char *pos, *end;
        char *dst = NULL;
    
        if (name[0] == '\0') {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02428)
                          "Empty response header name, aborting request");
            return 0;
        }
    
        if (ctx->strict) { 
            end = ap_scan_http_token(name);
        }
        else {
            end = ap_scan_vchar_obstext(name);
        }
        if (*end) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02429)
                          "Response header name '%s' contains invalid "
                          "characters, aborting request",
                          name);
            return 0;
        }
    
        for (pos = *val; *pos; pos = end) {
            end = ap_scan_http_field_content(pos);
            if (*end) {
                if (end[0] != CR || end[1] != LF || (end[2] != ' ' &&
                                                     end[2] != '\t')) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02430)
                                  "Response header '%s' value of '%s' contains "
                                  "invalid characters, aborting request",
                                  name, pos);
                    return 0;
                }
                if (!dst) {
                    *val = dst = apr_palloc(ctx->r->pool, strlen(*val) + 1);
                }
            }
            if (dst) {
                memcpy(dst, pos, end - pos);
                dst += end - pos;
                if (*end) {
                    /* skip folding and replace with a single space */
                    end += 3 + strspn(end + 3, "\t ");
                    *dst++ = ' ';
                }
            }
        }
        if (dst) {
            *dst = '\0';
        }
        return 1;
    }
    
    static int check_headers_table(apr_table_t *t, struct check_header_ctx *ctx)
    {
        const apr_array_header_t *headers = apr_table_elts(t);
        apr_table_entry_t *header;
        int i;
    
        for (i = 0; i < headers->nelts; ++i) {
            header = &APR_ARRAY_IDX(headers, i, apr_table_entry_t);
            if (!header->key) {
                continue;
            }
            if (!check_header(ctx, header->key, (const char **)&header->val)) {
                return 0;
            }
        }
        return 1;
    }
    
    /**
     * Check headers for HTTP conformance
     * @return 1 if ok, 0 if bad
     */
    static APR_INLINE int check_headers(request_rec *r)
    {
        struct check_header_ctx ctx;
        core_server_config *conf =
                ap_get_core_module_config(r->server->module_config);
        const char *val;
     
        if ((val = apr_table_get(r->headers_out, "Transfer-Encoding"))) {
            if (apr_table_get(r->headers_out, "Content-Length")) {
                apr_table_unset(r->headers_out, "Content-Length");
                r->connection->keepalive = AP_CONN_CLOSE;
            }
            if (!ap_is_chunked(r->pool, val)) {
                r->connection->keepalive = AP_CONN_CLOSE;
                return 0;
            }
        }
    
        ctx.r = r;
        ctx.strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
        return check_headers_table(r->headers_out, &ctx) &&
               check_headers_table(r->err_headers_out, &ctx);
    }
    
    static int check_headers_recursion(request_rec *r)
    {
        void *check = NULL;
        apr_pool_userdata_get(&check, "check_headers_recursion", r->pool);
        if (check) {
            return 1;
        }
        apr_pool_userdata_setn("true", "check_headers_recursion", NULL, r->pool);
        return 0;
    }
    
    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 apr_table_do(), so don't change its interface.
     * 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;
    
        headfield = apr_pstrcat(h->pool, fieldname, ": ", fieldval, CRLF, NULL);
        len = strlen(headfield);
    
        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 && ap_cstr_casecmp(*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(uniq_field_values, 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 (APLOGrtrace4(r)) {
            t_elt = (const apr_table_entry_t *)(elts->elts);
            do {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "  %s: %s",
                              ap_escape_logitem(r->pool, t_elt->key),
                              ap_escape_logitem(r->pool, t_elt->val));
                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
    }
    
    /* Confirm that the status line is well-formed and matches r->status.
     * If they don't match, a filter may have negated the status line set by a
     * handler.
     * Zap r->status_line if bad.
     */
    static apr_status_t validate_status_line(request_rec *r)
    {
        char *end;
    
        if (r->status_line) {
            int len = strlen(r->status_line);
            if (len < 3
                || apr_strtoi64(r->status_line, &end, 10) != r->status
                || (end - 3) != r->status_line
                || (len >= 4 && ! apr_isspace(r->status_line[3]))) {
                r->status_line = NULL;
                return APR_EGENERAL;
            }
            /* Since we passed the above check, we know that length three
             * is equivalent to only a 3 digit numeric http status.
             * RFC2616 mandates a trailing space, let's add it.
             */
            if (len == 3) {
                r->status_line = apr_pstrcat(r->pool, r->status_line, " ", NULL);
                return APR_EGENERAL;
            }
            return APR_SUCCESS;
        }
        return APR_EGENERAL;
    }
    
    /*
     * 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)
    {
        apr_status_t rv;
    
        if (r->assbackwards) {
            /* no such thing as a response protocol */
            return;
        }
    
        rv = validate_status_line(r);
    
        if (!r->status_line) {
            r->status_line = ap_get_status_line(r->status);
        } else if (rv != APR_SUCCESS) {
            /* Status line is OK but our own reason phrase
             * would be preferred if defined
             */
            const char *tmp = ap_get_status_line(r->status);
            if (!strncmp(tmp, r->status_line, 3)) {
                r->status_line = tmp;
            }
        }
    
        /* 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 = NULL;
        const char *proxy_date = NULL;
        const char *server = NULL;
        const char *us = ap_get_server_banner();
        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
    
        h.pool = r->pool;
        h.bb = bb;
    
        /*
         * keep the set-by-proxy server and date headers, otherwise
         * generate a new server header / date header
         */
        if (r->proxyreq != PROXYREQ_NONE) {
            proxy_date = apr_table_get(r->headers_out, "Date");
            if (!proxy_date) {
                /*
                 * proxy_date needs to be const. So use date for the creation of
                 * our own Date header and pass it over to proxy_date later to
                 * avoid a compiler warning.
                 */
                date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
                ap_recent_rfc822_date(date, r->request_time);
            }
            server = apr_table_get(r->headers_out, "Server");
        }
        else {
            date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
            ap_recent_rfc822_date(date, r->request_time);
        }
    
        form_header_field(&h, "Date", proxy_date ? proxy_date : date );
    
        if (!server && *us)
            server = us;
        if (server)
            form_header_field(&h, "Server", server);
    
        if (APLOGrtrace3(r)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "Response sent with status %d%s",
                          r->status,
                          APLOGrtrace4(r) ? ", headers:" : "");
    
            /*
             * Date and Server are less interesting, use TRACE5 for them while
             * using TRACE4 for the other headers.
             */
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "  Date: %s",
                          proxy_date ? proxy_date : date );
            if (server)
                ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "  Server: %s",
                              server);
        }
    
    
        /* unset so we don't send them again */
        apr_table_unset(r->headers_out, "Date");        /* Avoid bogosity */
        if (server) {
            apr_table_unset(r->headers_out, "Server");
        }
    }
    
    AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
    {
        const char *protocol = NULL;
    
        basic_http_header_check(r, &protocol);
        basic_http_header(r, bb, protocol);
    }
    
    static void terminate_header(apr_bucket_brigade *bb)
    {
        char crlf[] = CRLF;
        apr_size_t 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)
    {
        core_server_config *conf;
        int rv;
        apr_bucket_brigade *bb;
        header_struct h;
        apr_bucket *b;
        int body;
        char *bodyread = NULL, *bodyoff;
        apr_size_t bodylen = 0;
        apr_size_t bodybuf;
        long res = -1; /* init to avoid gcc -Wall warning */
    
        if (r->method_number != M_TRACE) {
            return DECLINED;
        }
    
        /* Get the original request */
        while (r->prev) {
            r = r->prev;
        }
        conf = ap_get_core_module_config(r->server->module_config);
    
        if (conf->trace_enable == AP_TRACE_DISABLE) {
            apr_table_setn(r->notes, "error-notes",
                          "TRACE denied by server configuration");
            return HTTP_METHOD_NOT_ALLOWED;
        }
    
        if (conf->trace_enable == AP_TRACE_EXTENDED)
            /* XXX: should be = REQUEST_CHUNKED_PASS */
            body = REQUEST_CHUNKED_DECHUNK;
        else
            body = REQUEST_NO_BODY;
    
        if ((rv = ap_setup_client_block(r, body))) {
            if (rv == HTTP_REQUEST_ENTITY_TOO_LARGE)
                apr_table_setn(r->notes, "error-notes",
                              "TRACE with a request body is not allowed");
            return rv;
        }
    
        if (ap_should_client_block(r)) {
    
            if (r->remaining > 0) {
                if (r->remaining > 65536) {
                    apr_table_setn(r->notes, "error-notes",
                           "Extended TRACE request bodies cannot exceed 64k\n");
                    return HTTP_REQUEST_ENTITY_TOO_LARGE;
                }
                /* always 32 extra bytes to catch chunk header exceptions */
                bodybuf = (apr_size_t)r->remaining + 32;
            }
            else {
                /* Add an extra 8192 for chunk headers */
                bodybuf = 73730;
            }
    
            bodyoff = bodyread = apr_palloc(r->pool, bodybuf);
    
            /* only while we have enough for a chunked header */
            while ((!bodylen || bodybuf >= 32) &&
                   (res = ap_get_client_block(r, bodyoff, bodybuf)) > 0) {
                bodylen += res;
                bodybuf -= res;
                bodyoff += res;
            }
            if (res > 0 && bodybuf < 32) {
                /* discard_rest_of_request_body into our buffer */
                while (ap_get_client_block(r, bodyread, bodylen) > 0)
                    ;
                apr_table_setn(r->notes, "error-notes",
                       "Extended TRACE request bodies cannot exceed 64k\n");
                return HTTP_REQUEST_ENTITY_TOO_LARGE;
            }
    
            if (res < 0) {
                return HTTP_BAD_REQUEST;
            }
        }
    
        ap_set_content_type_ex(r, "message/http", 1);
    
        /* Now we recreate the request, and echo it back */
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    #if APR_CHARSET_EBCDIC
        {
            char *tmp;
            apr_size_t len;
            len = strlen(r->the_request);
            tmp = apr_pmemdup(r->pool, r->the_request, len);
            ap_xlate_proto_to_ascii(tmp, len);
            apr_brigade_putstrs(bb, NULL, NULL, tmp, CRLF_ASCII, NULL);
        }
    #else
        apr_brigade_putstrs(bb, NULL, NULL, r->the_request, CRLF, NULL);
    #endif
        h.pool = r->pool;
        h.bb = bb;
        apr_table_do((int (*) (void *, const char *, const char *))
                     form_header_field, (void *) &h, r->headers_in, NULL);
        apr_brigade_puts(bb, NULL, NULL, CRLF_ASCII);
    
        /* If configured to accept a body, echo the body */
        if (bodylen) {
            b = apr_bucket_pool_create(bodyread, bodylen,
                                       r->pool, bb->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, b);
        }
    
        ap_pass_brigade(r->output_filters,  bb);
    
        return DONE;
    }
    
    typedef struct header_filter_ctx {
        int headers_sent;
    } header_filter_ctx;
    
    static void merge_response_headers(request_rec *r, const char **protocol)
    {
        const char *ctype = NULL;
        const char *clheader = NULL;
    
        /*
         * 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);
            apr_table_clear(r->err_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_setn(r->subprocess_env, "force-response-1.0", "1");
        }
        else {
            fixup_vary(r);
        }
    
        /* determine the protocol and whether we should use keepalives. */
        basic_http_header_check(r, protocol);
        ap_set_keepalive(r);
    
        /*
         * Control cachability for non-cacheable 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);
        }
    
        /*
         * 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");
        }
    
        /* 204/304 responses don't have content related headers */
        if (AP_STATUS_IS_HEADER_ONLY(r->status)) {
            apr_table_unset(r->headers_out, "Transfer-Encoding");
            apr_table_unset(r->headers_out, "Content-Length");
            r->content_type = r->content_encoding = NULL;
            r->content_languages = NULL;
            r->clength = r->chunked = 0;
        }
        else if (r->chunked) {
            apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
            apr_table_unset(r->headers_out, "Content-Length");
        }
    
        ctype = ap_make_content_type(r, r->content_type);
        if (ctype) {
            apr_table_setn(r->headers_out, "Content-Type", ctype);
        }
    
        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 *token;
            char **languages = (char **)(r->content_languages->elts);
            const char *field = apr_table_get(r->headers_out, "Content-Language");
    
            while (field && (token = ap_get_list_item(r->pool, &field)) != NULL) {
                for (i = 0; i < r->content_languages->nelts; ++i) {
                    if (!ap_cstr_casecmp(token, languages[i]))
                        break;
                }
                if (i == r->content_languages->nelts) {
                    *((char **) apr_array_push(r->content_languages)) = token;
                }
            }
    
            field = apr_array_pstrcat(r->pool, r->content_languages, ',');
            apr_table_setn(r->headers_out, "Content-Language", field);
        }
    
        /* 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");
        }
    }
    
    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;
        int header_only = (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status));
        apr_bucket *e;
        apr_bucket_brigade *b2;
        header_struct h;
        header_filter_ctx *ctx = f->ctx;
        ap_bucket_error *eb = NULL;
        apr_status_t rv = APR_SUCCESS;
        int recursive_error = 0;
        const char *protocol;
    
        AP_DEBUG_ASSERT(!r->main);
    
        if (!ctx) {
            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
        }
        else if (ctx->headers_sent) {
            /* Eat body if response must not have one. */
            if (header_only) {
                /* Still next filters may be waiting for EOS, so pass it (alone)
                 * when encountered and be done with this filter.
                 */
                e = APR_BRIGADE_LAST(b);
                if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
                    APR_BUCKET_REMOVE(e);
                    apr_brigade_cleanup(b);
                    APR_BRIGADE_INSERT_HEAD(b, e);
                    ap_remove_output_filter(f);
                    rv = ap_pass_brigade(f->next, b);
                }
                apr_brigade_cleanup(b);
                return rv;
            }
        }
    
        for (e = APR_BRIGADE_FIRST(b);
             e != APR_BRIGADE_SENTINEL(b);
             e = APR_BUCKET_NEXT(e))
        {
            if (AP_BUCKET_IS_ERROR(e) && !eb) {
                eb = e->data;
                continue;
            }
            /*
             * If we see an EOC bucket it is a signal that we should get out
             * of the way doing nothing.
             */
            if (AP_BUCKET_IS_EOC(e)) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, b);
            }
        }
    
        if (!ctx->headers_sent) {
            merge_response_headers(r, &protocol);
            if (!check_headers(r)) {
                /* We may come back here from ap_die() below,
                 * so clear anything from this response.
                 */
                apr_table_clear(r->headers_out);
                apr_table_clear(r->err_headers_out);
                r->content_type = r->content_encoding = NULL;
                r->content_languages = NULL;
                r->clength = r->chunked = 0;
                apr_brigade_cleanup(b);
    
                /* Don't recall ap_die() if we come back here (from its own internal
                 * redirect or error response), otherwise we can end up in infinite
                 * recursion; better fall through with 500, minimal headers and an
                 * empty body (EOS only).
                 */
                if (!check_headers_recursion(r)) {
                    ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
                    return AP_FILTER_ERROR;
                }
                r->status = HTTP_INTERNAL_SERVER_ERROR;
                e = ap_bucket_eoc_create(c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(b, e);
                e = apr_bucket_eos_create(c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(b, e);
                ap_set_content_length(r, 0);
                recursive_error = 1;
            }
            else if (eb) {
                int status;
                status = eb->status;
                apr_brigade_cleanup(b);
                ap_die(status, r);
                return AP_FILTER_ERROR;
            }
        }
    
        if (r->assbackwards) {
            r->sent_bodyct = 1;
            ap_remove_output_filter(f);
            rv = ap_pass_brigade(f->next, b);
            goto out;
        }
    
        if (!ctx->headers_sent) {
            b2 = apr_brigade_create(r->pool, c->bucket_alloc);
            basic_http_header(r, b2, protocol);
    
            h.pool = r->pool;
            h.bb = b2;
    
            send_all_header_fields(&h, r);
    
            terminate_header(b2);
    
            if (header_only) {
                e = APR_BRIGADE_LAST(b);
                if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
                    APR_BUCKET_REMOVE(e);
                    APR_BRIGADE_INSERT_TAIL(b2, e);
                    ap_remove_output_filter(f);
                }
                apr_brigade_cleanup(b);
            }
    
            rv = ap_pass_brigade(f->next, b2);
            apr_brigade_cleanup(b2);
            ctx->headers_sent = 1;
        }
    
        if (rv != APR_SUCCESS || header_only) {
            goto out;
        }
    
        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);
        rv = ap_pass_brigade(f->next, b);
    out:
        if (recursive_error) {
            return AP_FILTER_ERROR;
        }
        return rv;
    }
    
    /*
     * Map specific APR codes returned by the filter stack to HTTP error
     * codes, or the default status code provided. Use it as follows:
     *
     * return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
     *
     * If the filter has already handled the error, AP_FILTER_ERROR will
     * be returned, which is cleanly passed through.
     *
     * These mappings imply that the filter stack is reading from the
     * downstream client, the proxy will map these codes differently.
     */
    AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status)
    {
        switch (rv) {
        case AP_FILTER_ERROR:
            return AP_FILTER_ERROR;
    
        case APR_ENOSPC:
            return HTTP_REQUEST_ENTITY_TOO_LARGE;
    
        case APR_ENOTIMPL:
            return HTTP_NOT_IMPLEMENTED;
    
        case APR_TIMEUP:
        case APR_ETIMEDOUT:
            return HTTP_REQUEST_TIME_OUT;
    
        default:
            return status;
        }
    }
    
    /* 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)
    {
        int rc = OK;
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb;
    
        /* 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 || c->keepalive == AP_CONN_CLOSE) {
            return OK;
        }
        if (ap_status_drops_connection(r->status)) {
            c->keepalive = AP_CONN_CLOSE;
            return OK;
        }
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        for (;;) {
            apr_status_t rv;
    
            rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
                                APR_BLOCK_READ, HUGE_STRING_LEN);
            if (rv != APR_SUCCESS) {
                rc = ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
                goto cleanup;
            }
    
            while (!APR_BRIGADE_EMPTY(bb)) {
                apr_bucket *b = APR_BRIGADE_FIRST(bb);
    
                if (APR_BUCKET_IS_EOS(b)) {
                    goto cleanup;
                }
    
                /* There is no need to read empty or metadata buckets or
                 * buckets of known length, but we MUST read buckets of
                 * unknown length in order to exhaust them.
                 */
                if (b->length == (apr_size_t)-1) {
                    apr_size_t len;
                    const char *data;
    
                    rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
                    if (rv != APR_SUCCESS) {
                        rc = HTTP_BAD_REQUEST;
                        goto cleanup;
                    }
                }
    
                apr_bucket_delete(b);
            }
        }
    
    cleanup:
        apr_brigade_cleanup(bb);
        if (rc != OK) {
            c->keepalive = AP_CONN_CLOSE;
        }
        return rc;
    }
    
    /* 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.
     *    REQUEST_CHUNKED_PASS     If chunked, pass the chunk headers with body.
     *
     *    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");
        apr_off_t limit_req_body = ap_get_limit_req_body(r);
    
        r->read_body = read_policy;
        r->read_chunked = 0;
        r->remaining = 0;
    
        if (tenc) {
            if (ap_cstr_casecmp(tenc, "chunked")) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01592)
                              "Unknown Transfer-Encoding %s", tenc);
                return HTTP_NOT_IMPLEMENTED;
            }
            if (r->read_body == REQUEST_CHUNKED_ERROR) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01593)
                              "chunked Transfer-Encoding forbidden: %s", r->uri);
                return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
            }
    
            r->read_chunked = 1;
        }
        else if (lenp) {
            if (!ap_parse_strict_length(&r->remaining, lenp)) {
                r->remaining = 0;
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01594)
                              "Invalid Content-Length '%s'", lenp);
                return HTTP_BAD_REQUEST;
            }
        }
    
        if ((r->read_body == REQUEST_NO_BODY)
            && (r->read_chunked || (r->remaining > 0))) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01595)
                          "%s with body is not allowed for %s", r->method, r->uri);
            return HTTP_REQUEST_ENTITY_TOO_LARGE;
        }
    
        if (limit_req_body > 0 && (r->remaining > limit_req_body)) {
            /* will be logged when the body is discarded */
            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_core_module_config(r->request_config);
            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 == AP_FILTER_ERROR) {
            /* AP_FILTER_ERROR means a filter has responded already,
             * we are DONE.
             */
            apr_brigade_destroy(bb);
            return -1;
        }
        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;
    }
    
    /* Context struct for ap_http_outerror_filter */
    typedef struct {
        int seen_eoc;
        int first_error;
    } outerror_filter_ctx_t;
    
    /* Filter to handle any error buckets on output */
    apr_status_t ap_http_outerror_filter(ap_filter_t *f,
                                         apr_bucket_brigade *b)
    {
        request_rec *r = f->r;
        outerror_filter_ctx_t *ctx = (outerror_filter_ctx_t *)(f->ctx);
        apr_bucket *e;
    
        /* Create context if none is present */
        if (!ctx) {
            ctx = apr_pcalloc(r->pool, sizeof(outerror_filter_ctx_t));
            f->ctx = ctx;
        }
        for (e = APR_BRIGADE_FIRST(b);
             e != APR_BRIGADE_SENTINEL(b);
             e = APR_BUCKET_NEXT(e))
        {
            if (AP_BUCKET_IS_ERROR(e)) {
                /*
                 * Start of error handling state tree. Just one condition
                 * right now :)
                 */
                if (((ap_bucket_error *)(e->data))->status == HTTP_BAD_GATEWAY) {
                    /* stream aborted and we have not ended it yet */
                    r->connection->keepalive = AP_CONN_CLOSE;
                }
                /*
                 * Memorize the status code of the first error bucket for possible
                 * later use.
                 */
                if (!ctx->first_error) {
                    ctx->first_error = ((ap_bucket_error *)(e->data))->status;
                }
                continue;
            }
            /* Detect EOC buckets and memorize this in the context. */
            if (AP_BUCKET_IS_EOC(e)) {
                r->connection->keepalive = AP_CONN_CLOSE;
                ctx->seen_eoc = 1;
            }
        }
        /*
         * Remove all data buckets that are in a brigade after an EOC bucket
         * was seen, as an EOC bucket tells us that no (further) resource
         * and protocol data should go out to the client. OTOH meta buckets
         * are still welcome as they might trigger needed actions down in
         * the chain (e.g. in network filters like SSL).
         * Remark 1: It is needed to dump ALL data buckets in the brigade
         *           since an filter in between might have inserted data
         *           buckets BEFORE the EOC bucket sent by the original
         *           sender and we do NOT want this data to be sent.
         * Remark 2: Dumping all data buckets here does not necessarily mean
         *           that no further data is send to the client as:
         *           1. Network filters like SSL can still be triggered via
         *              meta buckets to talk with the client e.g. for a
         *              clean shutdown.
         *           2. There could be still data that was buffered before
         *              down in the chain that gets flushed by a FLUSH or an
         *              EOS bucket.
         */
        if (ctx->seen_eoc) {
            /*
             * Set the request status to the status of the first error bucket.
             * This should ensure that we log an appropriate status code in
             * the access log.
             * We need to set r->status on each call after we noticed an EOC as
             * data bucket generators like ap_die might have changed the status
             * code. But we know better in this case and insist on the status
             * code that we have seen in the error bucket.
             */
            if (ctx->first_error) {
                r->status = ctx->first_error;
            }
            for (e = APR_BRIGADE_FIRST(b);
                 e != APR_BRIGADE_SENTINEL(b);
                 e = APR_BUCKET_NEXT(e))
            {
                if (!APR_BUCKET_IS_METADATA(e)) {
                    APR_BUCKET_REMOVE(e);
                }
            }
        }
    
        return ap_pass_brigade(f->next,  b);
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/http_protocol.c�����������������������������������������������������������0000664�0001751�0001751�00000163103�14640775605�020337� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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 "ap_mpm.h"
    
    #include "mod_core.h"
    
    #if APR_HAVE_STDARG_H
    #include <stdarg.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    APLOG_USE_MODULE(http);
    
    /* New Apache routine to map status codes into array indices
     *  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.
     * No gaps are allowed between X00 and the largest Xnn
     * for any X (see ap_index_of_response).
     * When adding a new code here, add a define to httpd.h
     * as well.
     */
    
    static const char * const status_lines[RESPONSE_CODES] =
    {
        "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",
        "208 Already Reported",
        NULL, /* 209 */
        NULL, /* 210 */
        NULL, /* 211 */
        NULL, /* 212 */
        NULL, /* 213 */
        NULL, /* 214 */
        NULL, /* 215 */
        NULL, /* 216 */
        NULL, /* 217 */
        NULL, /* 218 */
        NULL, /* 219 */
        NULL, /* 220 */
        NULL, /* 221 */
        NULL, /* 222 */
        NULL, /* 223 */
        NULL, /* 224 */
        NULL, /* 225 */
        "226 IM Used",
    #define LEVEL_300 30
        "300 Multiple Choices",
        "301 Moved Permanently",
        "302 Found",
        "303 See Other",
        "304 Not Modified",
        "305 Use Proxy",
        NULL, /* 306 */
        "307 Temporary Redirect",
        "308 Permanent Redirect",
    #define LEVEL_400 39
        "400 Bad Request",
        "401 Unauthorized",
        "402 Payment Required",
        "403 Forbidden",
        "404 Not Found",
        "405 Method Not Allowed",
        "406 Not Acceptable",
        "407 Proxy Authentication Required",
        "408 Request Timeout",
        "409 Conflict",
        "410 Gone",
        "411 Length Required",
        "412 Precondition Failed",
        "413 Request Entity Too Large",
        "414 Request-URI Too Long",
        "415 Unsupported Media Type",
        "416 Requested Range Not Satisfiable",
        "417 Expectation Failed",
        NULL, /* 418 */
        NULL, /* 419 */
        NULL, /* 420 */
        "421 Misdirected Request",
        "422 Unprocessable Entity",
        "423 Locked",
        "424 Failed Dependency",
        NULL, /* 425 */
        "426 Upgrade Required",
        NULL, /* 427 */
        "428 Precondition Required",
        "429 Too Many Requests",
        NULL, /* 430 */
        "431 Request Header Fields Too Large",
        NULL, /* 432 */
        NULL, /* 433 */
        NULL, /* 434 */
        NULL, /* 435 */
        NULL, /* 436 */
        NULL, /* 437 */
        NULL, /* 438 */
        NULL, /* 439 */
        NULL, /* 440 */
        NULL, /* 441 */
        NULL, /* 442 */
        NULL, /* 443 */
        NULL, /* 444 */
        NULL, /* 445 */
        NULL, /* 446 */
        NULL, /* 447 */
        NULL, /* 448 */
        NULL, /* 449 */
        NULL, /* 450 */
        "451 Unavailable For Legal Reasons",
    #define LEVEL_500 91
        "500 Internal Server Error",
        "501 Not Implemented",
        "502 Bad Gateway",
        "503 Service Unavailable",
        "504 Gateway Timeout",
        "505 HTTP Version Not Supported",
        "506 Variant Also Negotiates",
        "507 Insufficient Storage",
        "508 Loop Detected",
        NULL, /* 509 */
        "510 Not Extended",
        "511 Network Authentication Required"
    };
    
    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
    
    static int is_mpm_running(void)
    {
        int mpm_state = 0;
    
        if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
          return 0;
        }
    
        if (mpm_state == AP_MPMQ_STOPPING) {
          return 0;
        }
    
        return 1;
    }
    
    
    AP_DECLARE(int) ap_set_keepalive(request_rec *r)
    {
        int ka_sent = 0;
        int left = r->server->keep_alive_max - r->connection->keepalives;
        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 client isn't expecting 100-continue (PR47087 - more
         *       input here could be the client continuing when we're
         *       closing the request).
         *   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);
         *   and this MPM process is not already exiting
         *   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->expecting_100
            && (r->header_only
                || AP_STATUS_IS_HEADER_ONLY(r->status)
                || apr_table_get(r->headers_out, "Content-Length")
                || ap_is_chunked(r->pool,
                                      apr_table_get(r->headers_out,
                                                    "Transfer-Encoding"))
                || ((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)
                || (left > 0))
            && !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)))
            && is_mpm_running()) {
    
            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");
        }
    
        /*
         * If we had previously been a keepalive connection and this
         * is the last one, then bump up the number of keepalives
         * we've had
         */
        if ((r->connection->keepalive != AP_CONN_CLOSE)
            && r->server->keep_alive_max
            && !left) {
            r->connection->keepalives++;
        }
        r->connection->keepalive = AP_CONN_CLOSE;
    
        return 0;
    }
    
    AP_DECLARE(ap_condition_e) ap_condition_if_match(request_rec *r,
            apr_table_t *headers)
    {
        const char *if_match, *etag;
    
        /* A server MUST use the strong comparison function (see section 13.3.3)
         * to compare the entity tags in If-Match.
         */
        if ((if_match = apr_table_get(r->headers_in, "If-Match")) != NULL) {
            if (if_match[0] == '*'
                    || ((etag = apr_table_get(headers, "ETag")) != NULL
                            && ap_find_etag_strong(r->pool, if_match, etag))) {
                return AP_CONDITION_STRONG;
            }
            else {
                return AP_CONDITION_NOMATCH;
            }
        }
    
        return AP_CONDITION_NONE;
    }
    
    AP_DECLARE(ap_condition_e) ap_condition_if_unmodified_since(request_rec *r,
            apr_table_t *headers)
    {
        const char *if_unmodified;
    
        if_unmodified = apr_table_get(r->headers_in, "If-Unmodified-Since");
        if (if_unmodified) {
            apr_int64_t mtime, reqtime;
    
            apr_time_t ius = apr_time_sec(apr_date_parse_http(if_unmodified));
    
            /* All of our comparisons must be in seconds, because that's the
             * highest time resolution the HTTP specification allows.
             */
            mtime = apr_time_sec(apr_date_parse_http(
                            apr_table_get(headers, "Last-Modified")));
            if (mtime == APR_DATE_BAD) {
                mtime = apr_time_sec(r->mtime ? r->mtime : apr_time_now());
            }
    
            reqtime = apr_time_sec(apr_date_parse_http(
                            apr_table_get(headers, "Date")));
            if (!reqtime) {
                reqtime = apr_time_sec(r->request_time);
            }
    
            if ((ius != APR_DATE_BAD) && (mtime > ius)) {
                if (reqtime < mtime + 60) {
                    if (apr_table_get(r->headers_in, "Range")) {
                        /* weak matches not allowed with Range requests */
                        return AP_CONDITION_NOMATCH;
                    }
                    else {
                        return AP_CONDITION_WEAK;
                    }
                }
                else {
                    return AP_CONDITION_STRONG;
                }
            }
            else {
                return AP_CONDITION_NOMATCH;
            }
        }
    
        return AP_CONDITION_NONE;
    }
    
    AP_DECLARE(ap_condition_e) ap_condition_if_none_match(request_rec *r,
            apr_table_t *headers)
    {
        const char *if_nonematch, *etag;
    
        if_nonematch = apr_table_get(r->headers_in, "If-None-Match");
        if (if_nonematch != NULL) {
    
            if (if_nonematch[0] == '*') {
                return AP_CONDITION_STRONG;
            }
    
            /* See section 13.3.3 for rules on how to determine if two entities tags
             * match. The weak comparison function can only be used with GET or HEAD
             * requests.
             */
            if (r->method_number == M_GET) {
                if ((etag = apr_table_get(headers, "ETag")) != NULL) {
                    if (apr_table_get(r->headers_in, "Range")) {
                        if (ap_find_etag_strong(r->pool, if_nonematch, etag)) {
                            return AP_CONDITION_STRONG;
                        }
                    }
                    else {
                        if (ap_find_etag_weak(r->pool, if_nonematch, etag)) {
                            return AP_CONDITION_WEAK;
                        }
                    }
                }
            }
    
            else if ((etag = apr_table_get(headers, "ETag")) != NULL
                    && ap_find_etag_strong(r->pool, if_nonematch, etag)) {
                return AP_CONDITION_STRONG;
            }
            return AP_CONDITION_NOMATCH;
        }
    
        return AP_CONDITION_NONE;
    }
    
    AP_DECLARE(ap_condition_e) ap_condition_if_modified_since(request_rec *r,
            apr_table_t *headers)
    {
        const char *if_modified_since;
    
        if ((if_modified_since = apr_table_get(r->headers_in, "If-Modified-Since"))
                != NULL) {
            apr_int64_t mtime;
            apr_int64_t ims, reqtime;
    
            /* All of our comparisons must be in seconds, because that's the
             * highest time resolution the HTTP specification allows.
             */
    
            mtime = apr_time_sec(apr_date_parse_http(
                            apr_table_get(headers, "Last-Modified")));
            if (mtime == APR_DATE_BAD) {
                mtime = apr_time_sec(r->mtime ? r->mtime : apr_time_now());
            }
    
            reqtime = apr_time_sec(apr_date_parse_http(
                            apr_table_get(headers, "Date")));
            if (!reqtime) {
                reqtime = apr_time_sec(r->request_time);
            }
    
            ims = apr_time_sec(apr_date_parse_http(if_modified_since));
    
            if (ims >= mtime && ims <= reqtime) {
                if (reqtime < mtime + 60) {
                    if (apr_table_get(r->headers_in, "Range")) {
                        /* weak matches not allowed with Range requests */
                        return AP_CONDITION_NOMATCH;
                    }
                    else {
                        return AP_CONDITION_WEAK;
                    }
                }
                else {
                    return AP_CONDITION_STRONG;
                }
            }
            else {
                return AP_CONDITION_NOMATCH;
            }
        }
    
        return AP_CONDITION_NONE;
    }
    
    AP_DECLARE(ap_condition_e) ap_condition_if_range(request_rec *r,
            apr_table_t *headers)
    {
        const char *if_range, *etag;
    
        if ((if_range = apr_table_get(r->headers_in, "If-Range"))
                && apr_table_get(r->headers_in, "Range")) {
            if (if_range[0] == '"') {
    
                if ((etag = apr_table_get(headers, "ETag"))
                        && !strcmp(if_range, etag)) {
                    return AP_CONDITION_STRONG;
                }
                else {
                    return AP_CONDITION_NOMATCH;
                }
    
            }
            else {
                apr_int64_t mtime;
                apr_int64_t rtime, reqtime;
    
                /* All of our comparisons must be in seconds, because that's the
                 * highest time resolution the HTTP specification allows.
                 */
    
                mtime = apr_time_sec(apr_date_parse_http(
                                apr_table_get(headers, "Last-Modified")));
                if (mtime == APR_DATE_BAD) {
                    mtime = apr_time_sec(r->mtime ? r->mtime : apr_time_now());
                }
    
                reqtime = apr_time_sec(apr_date_parse_http(
                                apr_table_get(headers, "Date")));
                if (!reqtime) {
                    reqtime = apr_time_sec(r->request_time);
                }
    
                rtime = apr_time_sec(apr_date_parse_http(if_range));
    
                if (rtime == mtime) {
                    if (reqtime < mtime + 60) {
                        /* weak matches not allowed with Range requests */
                        return AP_CONDITION_NOMATCH;
                    }
                    else {
                        return AP_CONDITION_STRONG;
                    }
                }
                else {
                    return AP_CONDITION_NOMATCH;
                }
            }
        }
    
        return AP_CONDITION_NONE;
    }
    
    AP_DECLARE(int) ap_meets_conditions(request_rec *r)
    {
        int not_modified = -1; /* unset by default */
        ap_condition_e cond;
    
        /* 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;
        }
    
        /* 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).
         */
        cond = ap_condition_if_match(r, r->headers_out);
        if (AP_CONDITION_NOMATCH == cond) {
            return HTTP_PRECONDITION_FAILED;
        }
    
        /* 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).
         */
        cond = ap_condition_if_unmodified_since(r, r->headers_out);
        if (AP_CONDITION_NOMATCH == cond) {
            not_modified = 0;
        }
        else if (cond >= AP_CONDITION_WEAK) {
            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.
         */
        cond = ap_condition_if_none_match(r, r->headers_out);
        if (AP_CONDITION_NOMATCH == cond) {
            not_modified = 0;
        }
        else if (cond >= AP_CONDITION_WEAK) {
            if (r->method_number == M_GET) {
                if (not_modified) {
                    not_modified = 1;
                }
            }
            else {
                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.
         */
        cond = ap_condition_if_modified_since(r, r->headers_out);
        if (AP_CONDITION_NOMATCH == cond) {
            not_modified = 0;
        }
        else if (cond >= AP_CONDITION_WEAK) {
            if (r->method_number == M_GET) {
                if (not_modified) {
                    not_modified = 1;
                }
            }
        }
    
        /* If an If-Range and an Range header is present, we must return
         * 200 OK. The byterange filter will convert it to a range response.
         */
        cond = ap_condition_if_range(r, r->headers_out);
        if (cond > AP_CONDITION_NONE) {
            return OK;
        }
    
        if (not_modified == 1) {
            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 <Limit GET MYGET>
     * 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
         * HEAD is a special-instance of the GET method and shares the same ID
         */
        register_one_method(p, "GET", M_GET);
        register_one_method(p, "HEAD", 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, APLOGNO(01610)
                          "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];
     * or use NULL to fill the gaps.
     */
    static int 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 -1;
        }
        if (status > 999) {     /* Above 999 is also illegal for HTTP status */
            return -1;
        }
    
        for (i = 0; i < 5; i++) {
            status -= 100;
            if (status < 100) {
                pos = (status + shortcut[i]);
                if (pos < shortcut[i + 1] && status_lines[pos] != NULL) {
                    return pos;
                }
                else {
                    break;
                }
            }
        }
        return -2;              /* Status unknown (falls in gap) or above 600 */
    }
    
    AP_DECLARE(int) ap_index_of_response(int status)
    {
        int index = index_of_response(status);
        return (index < 0) ? LEVEL_500 : index;
    }
    
    AP_DECLARE(const char *) ap_get_status_line_ex(apr_pool_t *p, int status)
    {
        int index = index_of_response(status);
        if (index >= 0) {
            return status_lines[index];
        }
        else if (index == -2) {
            return apr_psprintf(p, "%i Status %i", status, status);
        }
        return status_lines[LEVEL_500];
    }
    
    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.
     */
    static char *make_allow(request_rec *r)
    {
        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);
        /* For TRACE below */
        core_server_config *conf =
            ap_get_core_module_config(r->server->module_config);
    
        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) {
                APR_ARRAY_PUSH(allow, const char *) = key;
            }
        }
    
        /* TRACE is tested on a per-server basis */
        if (conf->trace_enable != AP_TRACE_DISABLE)
            *(const char **)apr_array_push(allow) = "TRACE";
    
        /* ### 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)) {
            apr_array_cat(allow, r->allowed_methods->method_list);
        }
    
        return apr_array_pstrcat(r->pool, allow, ',');
    }
    
    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;
            AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, 0);
        }
    }
    AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted)
    {
        ap_set_content_type(r, ct);
        AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, trusted ? AP_REQUEST_TRUSTED_CT : 0);
    }
    
    AP_DECLARE(void) ap_set_accept_ranges(request_rec *r)
    {
        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
        apr_table_setn(r->headers_out, "Accept-Ranges",
                      (d->max_ranges == AP_MAXRANGES_NORANGES) ? "none"
                                                               : "bytes");
    }
    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:
        case HTTP_PERMANENT_REDIRECT:
            return(apr_pstrcat(p,
                               "<p>The document has moved <a href=\"",
                               ap_escape_html(r->pool, location),
                               "\">here</a>.</p>\n",
                               NULL));
        case HTTP_SEE_OTHER:
            return(apr_pstrcat(p,
                               "<p>The answer to your request is located "
                               "<a href=\"",
                               ap_escape_html(r->pool, location),
                               "\">here</a>.</p>\n",
                               NULL));
        case HTTP_USE_PROXY:
            return("<p>This resource is only accessible "
                   "through the proxy\n"
                   "<br />\nYou will need to configure "
                   "your client to use that proxy.</p>\n");
        case HTTP_PROXY_AUTHENTICATION_REQUIRED:
        case HTTP_UNAUTHORIZED:
            return("<p>This server could not verify that you\n"
                   "are authorized to access the document\n"
                   "requested.  Either you supplied the wrong\n"
                   "credentials (e.g., bad password), or your\n"
                   "browser doesn't understand how to supply\n"
                   "the credentials required.</p>\n");
        case HTTP_BAD_REQUEST:
            return(add_optional_notes(r,
                                      "<p>Your browser sent a request that "
                                      "this server could not understand.<br />\n",
                                      "error-notes",
                                      "</p>\n"));
        case HTTP_FORBIDDEN:
            return(add_optional_notes(r, "<p>You don't have permission to access this resource.", "error-notes", "</p>\n"));
        case HTTP_NOT_FOUND:
            return("<p>The requested URL was not found on this server.</p>\n");
        case HTTP_METHOD_NOT_ALLOWED:
            return(apr_pstrcat(p,
                               "<p>The requested method ",
                               ap_escape_html(r->pool, r->method),
                               " is not allowed for this URL.</p>\n",
                               NULL));
        case HTTP_NOT_ACCEPTABLE:
            return(add_optional_notes(r, 
                "<p>An appropriate representation of the requested resource "
                "could not be found on this server.</p>\n",
                "variant-list", ""));
        case HTTP_MULTIPLE_CHOICES:
            return(add_optional_notes(r, "", "variant-list", ""));
        case HTTP_LENGTH_REQUIRED:
            s1 = apr_pstrcat(p,
                             "<p>A request of the requested method ",
                             ap_escape_html(r->pool, r->method),
                             " requires a valid Content-length.<br />\n",
                             NULL);
            return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
        case HTTP_PRECONDITION_FAILED:
            return("<p>The precondition on the request "
                   "for this URL evaluated to false.</p>\n");
        case HTTP_NOT_IMPLEMENTED:
            s1 = apr_pstrcat(p,
                             "<p>",
                             ap_escape_html(r->pool, r->method),
                             " not supported for current URL.<br />\n",
                             NULL);
            return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
        case HTTP_BAD_GATEWAY:
            s1 = "<p>The proxy server received an invalid" CRLF
                "response from an upstream server.<br />" CRLF;
            return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
        case HTTP_VARIANT_ALSO_VARIES:
            return("<p>A variant for the requested "
                   "resource\n<pre>\n"
                   "\n</pre>\nis itself a negotiable resource. "
                   "This indicates a configuration error.</p>\n");
        case HTTP_REQUEST_TIME_OUT:
            return("<p>Server timeout waiting for the HTTP request from the client.</p>\n");
        case HTTP_GONE:
            return("<p>The requested resource is no longer available on this server"
                   " and there is no forwarding address.\n"
                   "Please remove all references to this resource.</p>\n");
        case HTTP_REQUEST_ENTITY_TOO_LARGE:
            return(apr_pstrcat(p,
                               "The requested resource does not allow request data with ",
                               ap_escape_html(r->pool, 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 = "<p>The requested URL's length exceeds the capacity\n"
                 "limit for this server.<br />\n";
            return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
        case HTTP_UNSUPPORTED_MEDIA_TYPE:
            return("<p>The supplied request data is not in a format\n"
                   "acceptable for processing by this resource.</p>\n");
        case HTTP_RANGE_NOT_SATISFIABLE:
            return("<p>None of the range-specifier values in the Range\n"
                   "request-header field overlap the current extent\n"
                   "of the selected resource.</p>\n");
        case HTTP_EXPECTATION_FAILED:
            s1 = apr_table_get(r->headers_in, "Expect");
            if (s1)
                s1 = apr_pstrcat(p,
                         "<p>The expectation given in the Expect request-header\n"
                         "field could not be met by this server.\n"
                         "The client sent<pre>\n    Expect: ",
                         ap_escape_html(r->pool, s1), "\n</pre>\n",
                         NULL);
            else
                s1 = "<p>No expectation was seen, the Expect request-header \n"
                     "field was not presented by the client.\n";
            return add_optional_notes(r, s1, "error-notes", "</p>"
                       "<p>Only the 100-continue expectation is supported.</p>\n");
        case HTTP_UNPROCESSABLE_ENTITY:
            return("<p>The server understands the media type of the\n"
                   "request entity, but was unable to process the\n"
                   "contained instructions.</p>\n");
        case HTTP_LOCKED:
            return("<p>The requested resource is currently locked.\n"
                   "The lock must be released or proper identification\n"
                   "given before the method can be applied.</p>\n");
        case HTTP_FAILED_DEPENDENCY:
            return("<p>The method could not be performed on the resource\n"
                   "because the requested action depended on another\n"
                   "action and that other action failed.</p>\n");
        case HTTP_UPGRADE_REQUIRED:
            return("<p>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_PRECONDITION_REQUIRED:
            return("<p>The request is required to be conditional.</p>\n");
        case HTTP_TOO_MANY_REQUESTS:
            return("<p>The user has sent too many requests\n"
                   "in a given amount of time.</p>\n");
        case HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE:
            return("<p>The server refused this request because\n"
                   "the request header fields are too large.</p>\n");
        case HTTP_INSUFFICIENT_STORAGE:
            return("<p>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.</p>\n");
        case HTTP_SERVICE_UNAVAILABLE:
            return("<p>The server is temporarily unable to service your\n"
                   "request due to maintenance downtime or capacity\n"
                   "problems. Please try again later.</p>\n");
        case HTTP_GATEWAY_TIME_OUT:
            return("<p>The gateway did not receive a timely response\n"
                   "from the upstream server or application.</p>\n");
        case HTTP_LOOP_DETECTED:
            return("<p>The server terminated an operation because\n"
                   "it encountered an infinite loop.</p>\n");
        case HTTP_NOT_EXTENDED:
            return("<p>A mandatory extension policy in the request is not\n"
                   "accepted by the server for this resource.</p>\n");
        case HTTP_NETWORK_AUTHENTICATION_REQUIRED:
            return("<p>The client needs to authenticate to gain\n"
                   "network access.</p>\n");
        case HTTP_MISDIRECTED_REQUEST:
            return("<p>The client needs a new connection for this\n"
                   "request as the requested host name does not match\n"
                   "the Server Name Indication (SNI) in use for this\n"
                   "connection.</p>\n");
        case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
            return(add_optional_notes(r, 
                   "<p>Access to this URL has been denied for legal reasons.<br />\n",
                   "error-notes", "</p>\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, "<p />\n", NULL));
            }
            else {
                return(apr_pstrcat(p,
                                   "<p>The server encountered an internal "
                                   "error or\n"
                                   "misconfiguration and was unable to complete\n"
                                   "your request.</p>\n"
                                   "<p>Please contact the server "
                                   "administrator at \n ",
                                   ap_escape_html(r->pool,
                                                  r->server->server_admin),
                                   " to inform them of the time this "
                                   "error occurred,\n"
                                   " and the actions you performed just before "
                                   "this error.</p>\n"
                                   "<p>More information about this error "
                                   "may be available\n"
                                   "in the server error log.</p>\n",
                                   NULL));
            }
            /*
             * It would be nice to give the user the information they need to
             * fix the problem directly since many users don't have access to
             * 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, "<p />\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);
    
        /* 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 (AP_STATUS_IS_HEADER_ONLY(status)) {
            ap_finalize_request_protocol(r);
            return;
        }
    
        /*
         * 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");
        }
    
        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_core_module_config(r->request_config);
                request_conf->suppress_charset = 1; /* avoid adding default
                                                     * charset later
                                                     */
                ap_set_content_type_ex(r, "text/html", 1);
            }
            else {
                ap_set_content_type_ex(r, "text/html; charset=iso-8859-1", 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 correct 3 digit status code
             */
            if (r->status_line) {
                char *end;
                int len = strlen(r->status_line);
                if (len >= 3
                    && apr_strtoi64(r->status_line, &end, 10) == r->status
                    && (end - 3) == r->status_line
                    && (len < 4 || apr_isspace(r->status_line[3]))
                    && (len < 5 || apr_isalnum(r->status_line[4]))) {
                    /* Since we passed the above check, we know that length three
                     * is equivalent to only a 3 digit numeric http status.
                     * RFC2616 mandates a trailing space, let's add it.
                     * If we have an empty reason phrase, we also add "Unknown Reason".
                     */
                    if (len == 3) {
                        r->status_line = apr_pstrcat(r->pool, r->status_line, " Unknown Reason", NULL);
                    } else if (len == 4) {
                        r->status_line = apr_pstrcat(r->pool, r->status_line, "Unknown Reason", NULL);
                    }
                    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
                      "<html><head>\n<title>", title,
                      "</title>\n</head><body>\n<h1>", h1, "</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, "<p>Additionally, a ",
                          status_lines[ap_index_of_response(recursive_error)],
                          "\nerror was encountered while trying to use an "
                          "ErrorDocument to handle the request.</p>\n", NULL);
            }
            ap_rvputs_proto_in_ascii(r, ap_psignature("<hr>\n", r), NULL);
            ap_rvputs_proto_in_ascii(r, "</body></html>\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;
    
        /*
         * 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 of string names.
         */
        if ((l->method_list == NULL) || (l->method_list->nelts == 0)) {
            return 0;
        }
    
        return ap_array_str_contains(l->method_list, method);
    }
    
    /*
     * 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;
        const char **xmethod;
    
        /*
         * If it's one of our known methods, use the shortcut and use the
         * bitmask.
         */
        methnum = ap_method_number_of(method);
        if (methnum != M_INVALID) {
            l->method_mask |= (AP_METHOD_BIT << methnum);
            return;
        }
        /*
         * Otherwise, see if the method name is in the array of string names.
         */
        if (ap_array_str_contains(l->method_list, method)) {
            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);
        if (methnum != M_INVALID) {
            l->method_mask &= ~(AP_METHOD_BIT << methnum);
            return;
        }
        /*
         * Otherwise, see if the method name is in the array of string names.
         */
        if (l->method_list->nelts != 0) {
            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;
    }
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/mod_mime.mak��������������������������������������������������������������0000664�0001751�0001751�00000023015�12701473373�017541� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_mime.dsp
    !IF "$(CFG)" == ""
    CFG=mod_mime - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_mime - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_mime - Win32 Release" && "$(CFG)" != "mod_mime - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_mime - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_mime.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_mime.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_mime.obj"
    	-@erase "$(INTDIR)\mod_mime.res"
    	-@erase "$(INTDIR)\mod_mime_src.idb"
    	-@erase "$(INTDIR)\mod_mime_src.pdb"
    	-@erase "$(OUTDIR)\mod_mime.exp"
    	-@erase "$(OUTDIR)\mod_mime.lib"
    	-@erase "$(OUTDIR)\mod_mime.pdb"
    	-@erase "$(OUTDIR)\mod_mime.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_mime_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_mime.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_mime.so" /d LONG_NAME="mime_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_mime.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_mime.pdb" /debug /out:"$(OUTDIR)\mod_mime.so" /implib:"$(OUTDIR)\mod_mime.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_mime.obj" \
    	"$(INTDIR)\mod_mime.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_mime.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_mime.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_mime.so"
       if exist .\Release\mod_mime.so.manifest mt.exe -manifest .\Release\mod_mime.so.manifest -outputresource:.\Release\mod_mime.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_mime - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_mime.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_mime.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_mime.obj"
    	-@erase "$(INTDIR)\mod_mime.res"
    	-@erase "$(INTDIR)\mod_mime_src.idb"
    	-@erase "$(INTDIR)\mod_mime_src.pdb"
    	-@erase "$(OUTDIR)\mod_mime.exp"
    	-@erase "$(OUTDIR)\mod_mime.lib"
    	-@erase "$(OUTDIR)\mod_mime.pdb"
    	-@erase "$(OUTDIR)\mod_mime.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_mime_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_mime.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_mime.so" /d LONG_NAME="mime_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_mime.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_mime.pdb" /debug /out:"$(OUTDIR)\mod_mime.so" /implib:"$(OUTDIR)\mod_mime.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_mime.obj" \
    	"$(INTDIR)\mod_mime.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_mime.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_mime.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_mime.so"
       if exist .\Debug\mod_mime.so.manifest mt.exe -manifest .\Debug\mod_mime.so.manifest -outputresource:.\Debug\mod_mime.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_mime.dep")
    !INCLUDE "mod_mime.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_mime.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_mime - Win32 Release" || "$(CFG)" == "mod_mime - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_mime - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\http"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\http"
    
    !ELSEIF  "$(CFG)" == "mod_mime - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\http"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\http"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_mime - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\http"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\http"
    
    !ELSEIF  "$(CFG)" == "mod_mime - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\http"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\http"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_mime - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\http"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\http"
    
    !ELSEIF  "$(CFG)" == "mod_mime - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\http"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\http"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_mime - Win32 Release"
    
    
    "$(INTDIR)\mod_mime.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_mime.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_mime.so" /d LONG_NAME="mime_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_mime - Win32 Debug"
    
    
    "$(INTDIR)\mod_mime.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_mime.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_mime.so" /d LONG_NAME="mime_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_mime.c
    
    "$(INTDIR)\mod_mime.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/mod_mime.exp��������������������������������������������������������������0000664�0001751�0001751�00000000014�10150161574�017550� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mime_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/http_core.c���������������������������������������������������������������0000664�0001751�0001751�00000026265�14651200711�017414� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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_http_outerror_filter_handle;
    AP_DECLARE_DATA ap_filter_rec_t *ap_byterange_filter_handle;
    
    AP_DECLARE_DATA const char *ap_multipart_boundary;
    
    /* If we are using an MPM That Supports Async Connections,
     * use a different processing function
     */
    static int async_mpm = 0;
    
    static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy,
                                              const char *arg)
    {
        apr_interval_time_t timeout;
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        if (err != NULL) {
            return err;
        }
    
        /* Stolen from mod_proxy.c */
        if (ap_timeout_parameter_parse(arg, &timeout, "s") != APR_SUCCESS)
            return "KeepAliveTimeout has wrong format";
        cmd->server->keep_alive_timeout = timeout;
    
        /* We don't want to take into account whether or not KeepAliveTimeout is
         * set for the main server, because if no http_module directive is used
         * for a vhost, it will inherit the http_srv_cfg from the main server.
         * However keep_alive_timeout_set helps determine whether the vhost should
         * use its own configured timeout or the one from the vhost declared first
         * on the same IP:port (ie. c->base_server, and the legacy behaviour).
         */
        if (cmd->server->is_virtual) {
            cmd->server->keep_alive_timeout_set = 1;
        }
        return NULL;
    }
    
    static const char *set_keep_alive(cmd_parms *cmd, void *dummy,
                                      int arg)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        if (err != NULL) {
            return err;
        }
    
        cmd->server->keep_alive = arg;
        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_CONTEXT);
        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_FLAG("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)
    {
        /*
         * The http module shouldn't return anything other than
         * "http" (the default) or "https".
         */
        if (r->server->server_scheme &&
            (strcmp(r->server->server_scheme, "https") == 0))
            return "https";
    
        return "http";
    }
    
    static apr_port_t http_port(const request_rec *r)
    {
        if (r->server->server_scheme &&
            (strcmp(r->server->server_scheme, "https") == 0))
            return DEFAULT_HTTPS_PORT;
    
        return DEFAULT_HTTP_PORT;
    }
    
    static int ap_process_http_async_connection(conn_rec *c)
    {
        request_rec *r = NULL;
        conn_state_t *cs = c->cs;
    
        AP_DEBUG_ASSERT(cs != NULL);
        AP_DEBUG_ASSERT(cs->state == CONN_STATE_PROCESSING);
    
        if (cs->state == CONN_STATE_PROCESSING) {
            ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
            if (ap_extended_status) {
                ap_set_conn_count(c->sbh, r, c->keepalives);
            }
            if ((r = ap_read_request(c))) {
                if (r->status == HTTP_OK) {
                    cs->state = CONN_STATE_HANDLER;
                    if (ap_extended_status) {
                        ap_set_conn_count(c->sbh, r, c->keepalives + 1);
                    }
                    ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
                    ap_process_async_request(r);
                    /* After the call to ap_process_request, the
                     * request pool may have been deleted.  We set
                     * r=NULL here to ensure that any dereference
                     * of r that might be added later in this function
                     * will result in a segfault immediately instead
                     * of nondeterministic failures later.
                     */
                    r = NULL;
                }
    
                if (cs->state != CONN_STATE_WRITE_COMPLETION &&
                    cs->state != CONN_STATE_SUSPENDED) {
                    /* Something went wrong; close the connection */
                    cs->state = CONN_STATE_LINGER;
                }
            }
            else {   /* ap_read_request failed - client may have closed */
                cs->state = CONN_STATE_LINGER;
            }
        }
    
        return OK;
    }
    
    static int ap_process_http_sync_connection(conn_rec *c)
    {
        request_rec *r;
        conn_state_t *cs = c->cs;
        apr_socket_t *csd = NULL;
        int mpm_state = 0;
    
        /*
         * Read and process each request found on our connection
         * until no requests are left or we decide to close.
         */
    
        ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
        while ((r = ap_read_request(c)) != NULL) {
            apr_interval_time_t keep_alive_timeout = r->server->keep_alive_timeout;
    
            /* To preserve legacy behaviour, use the keepalive timeout from the
             * base server (first on this IP:port) when none is explicitly
             * configured on this server.
             */
            if (!r->server->keep_alive_timeout_set) {
                keep_alive_timeout = c->base_server->keep_alive_timeout;
            }
    
            if (r->status == HTTP_OK) {
                if (cs)
                    cs->state = CONN_STATE_HANDLER;
                ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
                ap_process_request(r);
                /* After the call to ap_process_request, the
                 * request pool will have been deleted.  We set
                 * r=NULL here to ensure that any dereference
                 * of r that might be added later in this function
                 * will result in a segfault immediately instead
                 * of nondeterministic failures later.
                 */
                r = NULL;
            }
    
            if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted)
                break;
    
            ap_update_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, NULL);
    
            if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
                break;
            }
    
            if (mpm_state == AP_MPMQ_STOPPING) {
              break;
            }
    
            if (!csd) {
                csd = ap_get_conn_socket(c);
            }
            apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
            apr_socket_timeout_set(csd, keep_alive_timeout);
            /* Go straight to select() to wait for the next request */
        }
    
        return OK;
    }
    
    static int ap_process_http_connection(conn_rec *c)
    {
        if (async_mpm && !c->clogging_input_filters) {
            return ap_process_http_async_connection(c);
        }
        else {
            return ap_process_http_sync_connection(c);
        }
    }
    
    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);
            ap_add_output_filter_handle(ap_http_outerror_filter_handle,
                                        NULL, r, r->connection);
        }
    
        return OK;
    }
    
    static int http_send_options(request_rec *r)
    {
        if ((r->method_number == M_OPTIONS) && r->uri && (r->uri[0] == '*') &&
             (r->uri[1] == '\0')) {
            return DONE;           /* Send HTTP pong, without Allow header */
        }
        return DECLINED;
    }
    
    static int http_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
    {
        apr_uint64_t val;
        if (ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm) != APR_SUCCESS) {
            async_mpm = 0;
        }
        ap_random_insecure_bytes(&val, sizeof(val));
        ap_multipart_boundary = apr_psprintf(p, "%0" APR_UINT64_T_HEX_FMT, val);
    
        return OK;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_post_config(http_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        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_map_to_storage(http_send_options,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_http_outerror_filter_handle =
            ap_register_output_filter("HTTP_OUTERROR", ap_http_outerror_filter,
                                      NULL, AP_FTYPE_PROTOCOL);
        ap_byterange_filter_handle =
            ap_register_output_filter("BYTERANGE", ap_byterange_filter,
                                      NULL, AP_FTYPE_PROTOCOL);
        ap_method_registry_init(p);
    }
    
    AP_DECLARE_MODULE(http) = {
        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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/chunk_filter.c������������������������������������������������������������0000664�0001751�0001751�00000015763�13341325553�020112� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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"
    
    /*
     * A pointer to this is used to memorize in the filter context that a bad
     * gateway error bucket had been seen. It is used as an invented unique pointer.
     */
    static char bad_gateway_seen;
    
    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, *tmp;
        apr_bucket *e;
        apr_status_t rv;
    
        for (more = tmp = 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 */
                    ap_remove_output_filter(f);
                    eos = e;
                    break;
                }
                if (AP_BUCKET_IS_ERROR(e)
                    && (((ap_bucket_error *)(e->data))->status
                        == HTTP_BAD_GATEWAY)) {
                    /*
                     * We had a broken backend. Memorize this in the filter
                     * context.
                     */
                    f->ctx = &bad_gateway_seen;
                    continue;
                }
                if (APR_BUCKET_IS_FLUSH(e)) {
                    flush = e;
                    if (e != APR_BRIGADE_LAST(b)) {
                        more = apr_brigade_split_ex(b, APR_BUCKET_NEXT(e), tmp);
                    }
                    break;
                }
                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_ex(b, APR_BUCKET_NEXT(e), tmp);
                        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
             *
             * We only do this if we have not seen an error bucket with
             * status HTTP_BAD_GATEWAY. We have memorized an
             * error bucket that we had seen in the filter context.
             * The error bucket with status HTTP_BAD_GATEWAY indicates that the
             * connection to the backend (mod_proxy) broke in the middle of the
             * response. In order to signal the client that something went wrong
             * we do not create the last-chunk marker and set c->keepalive to
             * AP_CONN_CLOSE in the core output filter.
             *
             * 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 && !f->ctx) {
                /* XXX: (2) trailers ... does not yet exist */
                e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF
                                               /* <trailers> */
                                               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);
            apr_brigade_cleanup(b);
            if (rv != APR_SUCCESS || eos != NULL) {
                return rv;
            }
            tmp = b;
        }
        return APR_SUCCESS;
    }
    �������������httpd-2.4.64/modules/http/mod_mime.dsp��������������������������������������������������������������0000664�0001751�0001751�00000010467�10551346420�017557� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_mime.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_mime.so" /d LONG_NAME="mime_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_mime.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_mime.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_mime.so" /d LONG_NAME="mime_module for Apache"
    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 /out:".\Debug\mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_mime.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/http/.indent.pro���������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�017337� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/�������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015465� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxyftp������������������������������������������������������������0000664�0001751�0001751�00000010557�11546111464�020123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.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_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_http.mak�������������������������������������������������������0000664�0001751�0001751�00000025645�12701473373�021247� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_http.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_http - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_http - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_http - Win32 Release" && "$(CFG)" != "mod_proxy_http - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_http.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_http.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_http.obj"
    	-@erase "$(INTDIR)\mod_proxy_http.res"
    	-@erase "$(INTDIR)\mod_proxy_http_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_http_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http.exp"
    	-@erase "$(OUTDIR)\mod_proxy_http.lib"
    	-@erase "$(OUTDIR)\mod_proxy_http.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_http_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_http.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_http.so" /d LONG_NAME="proxy_http_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_http.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_http.pdb" /debug /out:"$(OUTDIR)\mod_proxy_http.so" /implib:"$(OUTDIR)\mod_proxy_http.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_http.obj" \
    	"$(INTDIR)\mod_proxy_http.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_http.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_http.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_http.so"
       if exist .\Release\mod_proxy_http.so.manifest mt.exe -manifest .\Release\mod_proxy_http.so.manifest -outputresource:.\Release\mod_proxy_http.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_http.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_http.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_http.obj"
    	-@erase "$(INTDIR)\mod_proxy_http.res"
    	-@erase "$(INTDIR)\mod_proxy_http_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_http_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http.exp"
    	-@erase "$(OUTDIR)\mod_proxy_http.lib"
    	-@erase "$(OUTDIR)\mod_proxy_http.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_http.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_http_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_http.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_http.so" /d LONG_NAME="proxy_http_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_http.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_http.pdb" /debug /out:"$(OUTDIR)\mod_proxy_http.so" /implib:"$(OUTDIR)\mod_proxy_http.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_http.obj" \
    	"$(INTDIR)\mod_proxy_http.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_http.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_http.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_http.so"
       if exist .\Debug\mod_proxy_http.so.manifest mt.exe -manifest .\Debug\mod_proxy_http.so.manifest -outputresource:.\Debug\mod_proxy_http.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_http.dep")
    !INCLUDE "mod_proxy_http.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_http.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_http - Win32 Release" || "$(CFG)" == "mod_proxy_http - Win32 Debug"
    SOURCE=.\mod_proxy_http.c
    
    "$(INTDIR)\mod_proxy_http.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_http - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_http - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_http - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_http.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_http.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_http.so" /d LONG_NAME="proxy_http_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_http - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_http.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_http.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_http.so" /d LONG_NAME="proxy_http_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxycon������������������������������������������������������������0000664�0001751�0001751�00000010303�11546111464�020076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.imp \
    	@libc.imp \
    	$(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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/���������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017417� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bybusyness.c��������������������������������������0000664�0001751�0001751�00000007535�13345726637�024526� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "scoreboard.h"
    #include "ap_mpm.h"
    #include "apr_version.h"
    #include "ap_hooks.h"
    
    module AP_MODULE_DECLARE_DATA lbmethod_bybusyness_module;
    
    static APR_OPTIONAL_FN_TYPE(proxy_balancer_get_best_worker)
                                *ap_proxy_balancer_get_best_worker_fn = NULL;
    
    static int is_best_bybusyness(proxy_worker *current, proxy_worker *prev_best, void *baton)
    {
        int *total_factor = (int *)baton;
    
        current->s->lbstatus += current->s->lbfactor;
        *total_factor += current->s->lbfactor;
    
        return (
            !prev_best
            || (current->s->busy < prev_best->s->busy)
            || (
                (current->s->busy == prev_best->s->busy)
                && (current->s->lbstatus > prev_best->s->lbstatus)
            )
        );
    }
    
    static proxy_worker *find_best_bybusyness(proxy_balancer *balancer,
                                              request_rec *r)
    {
        int total_factor = 0;
        proxy_worker *worker =
            ap_proxy_balancer_get_best_worker_fn(balancer, r, is_best_bybusyness,
                                              &total_factor);
    
        if (worker) {
            worker->s->lbstatus -= total_factor;
        }
    
        return worker;
    }
    
    /* assumed to be mutex protected by caller */
    static apr_status_t reset(proxy_balancer *balancer, server_rec *s)
    {
        int i;
        proxy_worker **worker;
        worker = (proxy_worker **)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
            (*worker)->s->lbstatus = 0;
            (*worker)->s->busy = 0;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t age(proxy_balancer *balancer, server_rec *s)
    {
        return APR_SUCCESS;
    }
    
    static const proxy_balancer_method bybusyness =
    {
        "bybusyness",
        &find_best_bybusyness,
        NULL,
        &reset,
        &age,
        NULL
    };
    
    /* post_config hook: */
    static int lbmethod_bybusyness_post_config(apr_pool_t *pconf, apr_pool_t *plog,
            apr_pool_t *ptemp, server_rec *s)
    {
    
        /* lbmethod_bybusyness_post_config() will be called twice during startup.  So, don't
         * set up the static data the 1st time through. */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
    
        ap_proxy_balancer_get_best_worker_fn =
                     APR_RETRIEVE_OPTIONAL_FN(proxy_balancer_get_best_worker);
        if (!ap_proxy_balancer_get_best_worker_fn) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10151)
                         "mod_proxy must be loaded for mod_lbmethod_bybusyness");
            return !OK;
        }
    
        return OK;
    }
    
    static void register_hook(apr_pool_t *p)
    {
        ap_register_provider(p, PROXY_LBMETHOD, "bybusyness", "0", &bybusyness);
        ap_hook_post_config(lbmethod_bybusyness_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(lbmethod_bybusyness) = {
        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_hook /* register hooks */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_byrequests.mak������������������������������������0000664�0001751�0001751�00000032061�12701473373�025033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_lbmethod_byrequests.dsp
    !IF "$(CFG)" == ""
    CFG=mod_lbmethod_byrequests - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_lbmethod_byrequests - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_lbmethod_byrequests - Win32 Release" && "$(CFG)" != "mod_lbmethod_byrequests - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_lbmethod_byrequests.mak" CFG="mod_lbmethod_byrequests - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_byrequests - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_byrequests - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_byrequests.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Release" "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_lbmethod_byrequests.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" "mod_proxy_balancer - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests.res"
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_byrequests_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_byrequests.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_byrequests.so" /d LONG_NAME="lbmethod_byrequests_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_byrequests.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_byrequests.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_byrequests.so" /implib:"$(OUTDIR)\mod_lbmethod_byrequests.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_byrequests.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_byrequests.obj" \
    	"$(INTDIR)\mod_lbmethod_byrequests.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib" \
    	"..\Release\mod_proxy.lib" \
    	"..\Release\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_byrequests.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_lbmethod_byrequests.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_byrequests.so"
       if exist .\Release\mod_lbmethod_byrequests.so.manifest mt.exe -manifest .\Release\mod_lbmethod_byrequests.so.manifest -outputresource:.\Release\mod_lbmethod_byrequests.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_byrequests.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Debug" "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_lbmethod_byrequests.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" "mod_proxy_balancer - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests.res"
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_byrequests_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_byrequests.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_byrequests_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_byrequests.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_byrequests.so" /d LONG_NAME="lbmethod_byrequests_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_byrequests.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_byrequests.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_byrequests.so" /implib:"$(OUTDIR)\mod_lbmethod_byrequests.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_byrequests.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_byrequests.obj" \
    	"$(INTDIR)\mod_lbmethod_byrequests.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib" \
    	"..\Debug\mod_proxy.lib" \
    	"..\Debug\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_byrequests.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_lbmethod_byrequests.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_byrequests.so"
       if exist .\Debug\mod_lbmethod_byrequests.so.manifest mt.exe -manifest .\Debug\mod_lbmethod_byrequests.so.manifest -outputresource:.\Debug\mod_lbmethod_byrequests.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_lbmethod_byrequests.dep")
    !INCLUDE "mod_lbmethod_byrequests.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_lbmethod_byrequests.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release" || "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    SOURCE=.\mod_lbmethod_byrequests.c
    
    "$(INTDIR)\mod_lbmethod_byrequests.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release"
    
    "mod_proxy_balancer - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    
    "mod_proxy_balancer - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Release"
    
    
    "$(INTDIR)\mod_lbmethod_byrequests.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_byrequests.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_byrequests.so" /d LONG_NAME="lbmethod_byrequests_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - Win32 Debug"
    
    
    "$(INTDIR)\mod_lbmethod_byrequests.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_byrequests.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_byrequests.so" /d LONG_NAME="lbmethod_byrequests_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_byrequests.dep������������������������������������0000664�0001751�0001751�00000005665�12674411515�025044� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_lbmethod_byrequests.mak
    
    .\mod_lbmethod_byrequests.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_expr.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_mpm.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\ap_slotmem.h"\
    	"..\..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\scoreboard.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_charset.h"\
    	"..\..\..\include\util_ebcdic.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_mutex.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_version.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	"..\mod_proxy.h"\
    	
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    ���������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bybusyness.dsp������������������������������������0000664�0001751�0001751�00000012175�11177743604�025060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_lbmethod_bybusyness" - 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_lbmethod_bybusyness - 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_lbmethod_bybusyness.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_lbmethod_bybusyness.mak" CFG="mod_lbmethod_bybusyness - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_bybusyness - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_bybusyness - 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_lbmethod_bybusyness - 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 ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_lbmethod_bybusyness_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 0x409 /fo"Release/mod_lbmethod_bybusyness.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_bybusyness.so" /d LONG_NAME="lbmethod_bybusyness_module for Apache"
    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 /out:".\Release\mod_lbmethod_bybusyness.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bybusyness.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_lbmethod_bybusyness.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bybusyness.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_lbmethod_bybusyness.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_lbmethod_bybusyness_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 0x409 /fo"Debug/mod_lbmethod_bybusyness.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_bybusyness.so" /d LONG_NAME="lbmethod_bybusyness_module for Apache"
    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 /out:".\Debug\mod_lbmethod_bybusyness.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bybusyness.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lbmethod_bybusyness.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bybusyness.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_lbmethod_bybusyness.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_lbmethod_bybusyness - Win32 Release"
    # Name "mod_lbmethod_bybusyness - 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_lbmethod_bybusyness.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bytraffic.c���������������������������������������0000664�0001751�0001751�00000010511�14643766631�024255� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "scoreboard.h"
    #include "ap_mpm.h"
    #include "apr_version.h"
    #include "ap_hooks.h"
    
    module AP_MODULE_DECLARE_DATA lbmethod_bytraffic_module;
    
    static APR_OPTIONAL_FN_TYPE(proxy_balancer_get_best_worker)
                                *ap_proxy_balancer_get_best_worker_fn = NULL;
    
    static int is_best_bytraffic(proxy_worker *current, proxy_worker *prev_best, void *baton)
    {
        apr_off_t *min_traffic = (apr_off_t *)baton;
        apr_off_t traffic = (current->s->transferred / current->s->lbfactor)
                            + (current->s->read / current->s->lbfactor);
    
        if (!prev_best || (traffic < *min_traffic)) {
            *min_traffic = traffic;
    
            return TRUE;
        }
    
        return FALSE;
    }
    
    /*
     * 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)
    {
        apr_off_t min_traffic = 0;
    
        return ap_proxy_balancer_get_best_worker_fn(balancer, r, is_best_bytraffic,
                                                 &min_traffic);
    }
    
    /* assumed to be mutex protected by caller */
    static apr_status_t reset(proxy_balancer *balancer, server_rec *s)
    {
        int i;
        proxy_worker **worker;
        worker = (proxy_worker **)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
            (*worker)->s->transferred = 0;
            (*worker)->s->read = 0;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t age(proxy_balancer *balancer, server_rec *s)
    {
        return APR_SUCCESS;
    }
    
    static const proxy_balancer_method bytraffic =
    {
        "bytraffic",
        &find_best_bytraffic,
        NULL,
        &reset,
        &age,
        NULL
    };
    
    /* post_config hook: */
    static int lbmethod_bytraffic_post_config(apr_pool_t *pconf, apr_pool_t *plog,
            apr_pool_t *ptemp, server_rec *s)
    {
    
        /* lbmethod_bytraffic_post_config() will be called twice during startup.  So, don't
         * set up the static data the 1st time through. */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
    
        ap_proxy_balancer_get_best_worker_fn =
                     APR_RETRIEVE_OPTIONAL_FN(proxy_balancer_get_best_worker);
        if (!ap_proxy_balancer_get_best_worker_fn) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10150)
                         "mod_proxy must be loaded for mod_lbmethod_bytraffic");
            return !OK;
        }
    
        return OK;
    }
    
    static void register_hook(apr_pool_t *p)
    {
        ap_register_provider(p, PROXY_LBMETHOD, "bytraffic", "0", &bytraffic);
        ap_hook_post_config(lbmethod_bytraffic_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(lbmethod_bytraffic) = {
        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_hook /* register hooks */
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/config2.m4�����������������������������������������������������0000664�0001751�0001751�00000001067�12735002637�021207� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������APACHE_MODPATH_INIT(proxy/balancers)
    
    APACHE_MODULE(lbmethod_byrequests, Apache proxy Load balancing by request counting, , , $enable_proxy_balancer, , proxy_balancer)
    APACHE_MODULE(lbmethod_bytraffic, Apache proxy Load balancing by traffic counting, , , $enable_proxy_balancer, , proxy_balancer)
    APACHE_MODULE(lbmethod_bybusyness, Apache proxy Load balancing by busyness, , , $enable_proxy_balancer, , proxy_balancer)
    APACHE_MODULE(lbmethod_heartbeat, Apache proxy Load balancing from Heartbeats, , , $enable_proxy_balancer, , proxy_balancer)
    
    APACHE_MODPATH_FINISH
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_heartbeat.mak�������������������������������������0000664�0001751�0001751�00000031725�12701473373�024572� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_lbmethod_heartbeat.dsp
    !IF "$(CFG)" == ""
    CFG=mod_lbmethod_heartbeat - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_lbmethod_heartbeat - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_lbmethod_heartbeat - Win32 Release" && "$(CFG)" != "mod_lbmethod_heartbeat - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_lbmethod_heartbeat.mak" CFG="mod_lbmethod_heartbeat - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_heartbeat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_heartbeat - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Release" "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_lbmethod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" "mod_proxy_balancer - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat.res"
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_heartbeat_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_heartbeat.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_heartbeat.so" /d LONG_NAME="lbmethod_heartbeat_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_heartbeat.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_heartbeat.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_heartbeat.so" /implib:"$(OUTDIR)\mod_lbmethod_heartbeat.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_heartbeat.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_heartbeat.obj" \
    	"$(INTDIR)\mod_lbmethod_heartbeat.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib" \
    	"..\Release\mod_proxy.lib" \
    	"..\Release\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_heartbeat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_lbmethod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_heartbeat.so"
       if exist .\Release\mod_lbmethod_heartbeat.so.manifest mt.exe -manifest .\Release\mod_lbmethod_heartbeat.so.manifest -outputresource:.\Release\mod_lbmethod_heartbeat.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Debug" "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_lbmethod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" "mod_proxy_balancer - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat.res"
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_heartbeat_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_heartbeat.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_heartbeat_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_heartbeat.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_heartbeat.so" /d LONG_NAME="lbmethod_heartbeat_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_heartbeat.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_heartbeat.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_heartbeat.so" /implib:"$(OUTDIR)\mod_lbmethod_heartbeat.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_heartbeat.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_heartbeat.obj" \
    	"$(INTDIR)\mod_lbmethod_heartbeat.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib" \
    	"..\Debug\mod_proxy.lib" \
    	"..\Debug\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_heartbeat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_lbmethod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_heartbeat.so"
       if exist .\Debug\mod_lbmethod_heartbeat.so.manifest mt.exe -manifest .\Debug\mod_lbmethod_heartbeat.so.manifest -outputresource:.\Debug\mod_lbmethod_heartbeat.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_lbmethod_heartbeat.dep")
    !INCLUDE "mod_lbmethod_heartbeat.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_lbmethod_heartbeat.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release" || "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    SOURCE=.\mod_lbmethod_heartbeat.c
    
    "$(INTDIR)\mod_lbmethod_heartbeat.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release"
    
    "mod_proxy_balancer - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    
    "mod_proxy_balancer - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Release"
    
    
    "$(INTDIR)\mod_lbmethod_heartbeat.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_heartbeat.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_heartbeat.so" /d LONG_NAME="lbmethod_heartbeat_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - Win32 Debug"
    
    
    "$(INTDIR)\mod_lbmethod_heartbeat.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_heartbeat.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_heartbeat.so" /d LONG_NAME="lbmethod_heartbeat_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_heartbeat.dep�������������������������������������0000664�0001751�0001751�00000005724�12674411515�024571� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_lbmethod_heartbeat.mak
    
    .\mod_lbmethod_heartbeat.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_expr.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_mpm.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\ap_slotmem.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\heartbeat.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\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\scoreboard.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_charset.h"\
    	"..\..\..\include\util_ebcdic.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_mutex.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_version.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	"..\mod_proxy.h"\
    	
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    ��������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bytraffic.dsp�������������������������������������0000664�0001751�0001751�00000012137�11177743604�024621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_lbmethod_bytraffic" - 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_lbmethod_bytraffic - 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_lbmethod_bytraffic.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_lbmethod_bytraffic.mak" CFG="mod_lbmethod_bytraffic - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_bytraffic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_bytraffic - 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_lbmethod_bytraffic - 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 ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_lbmethod_bytraffic_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 0x409 /fo"Release/mod_lbmethod_bytraffic.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_bytraffic.so" /d LONG_NAME="lbmethod_bytraffic_module for Apache"
    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 /out:".\Release\mod_lbmethod_bytraffic.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bytraffic.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_lbmethod_bytraffic.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bytraffic.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_lbmethod_bytraffic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_lbmethod_bytraffic_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 0x409 /fo"Debug/mod_lbmethod_bytraffic.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_bytraffic.so" /d LONG_NAME="lbmethod_bytraffic_module for Apache"
    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 /out:".\Debug\mod_lbmethod_bytraffic.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bytraffic.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lbmethod_bytraffic.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bytraffic.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_lbmethod_bytraffic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_lbmethod_bytraffic - Win32 Release"
    # Name "mod_lbmethod_bytraffic - 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_lbmethod_bytraffic.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_byrequests.c��������������������������������������0000664�0001751�0001751�00000012130�13345726637�024511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "scoreboard.h"
    #include "ap_mpm.h"
    #include "apr_version.h"
    #include "ap_hooks.h"
    
    module AP_MODULE_DECLARE_DATA lbmethod_byrequests_module;
    
    static APR_OPTIONAL_FN_TYPE(proxy_balancer_get_best_worker)
                                *ap_proxy_balancer_get_best_worker_fn = NULL;
    
    static int is_best_byrequests(proxy_worker *current, proxy_worker *prev_best, void *baton)
    {
        int *total_factor = (int *)baton;
    
        current->s->lbstatus += current->s->lbfactor;
        *total_factor += current->s->lbfactor;
    
        return (!prev_best || (current->s->lbstatus > prev_best->s->lbstatus));
    }
    
    /*
     * 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 total_factor = 0;
        proxy_worker *worker = ap_proxy_balancer_get_best_worker_fn(balancer, r, is_best_byrequests, &total_factor);
    
        if (worker) {
            worker->s->lbstatus -= total_factor;
        }
    
        return worker;
    }
    
    /* assumed to be mutex protected by caller */
    static apr_status_t reset(proxy_balancer *balancer, server_rec *s)
    {
        int i;
        proxy_worker **worker;
        worker = (proxy_worker **)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
            (*worker)->s->lbstatus = 0;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t age(proxy_balancer *balancer, server_rec *s)
    {
        return APR_SUCCESS;
    }
    
    /*
     * How to add additional lbmethods:
     *   1. Create func which determines "best" candidate worker
     *      (eg: find_best_bytraffic, above)
     *   2. Register it as a provider.
     */
    static const proxy_balancer_method byrequests =
    {
        "byrequests",
        &find_best_byrequests,
        NULL,
        &reset,
        &age,
        NULL
    };
    
    /* post_config hook: */
    static int lbmethod_byrequests_post_config(apr_pool_t *pconf, apr_pool_t *plog,
            apr_pool_t *ptemp, server_rec *s)
    {
    
        /* lbmethod_byrequests_post_config() will be called twice during startup.  So, don't
         * set up the static data the 1st time through. */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
    
        ap_proxy_balancer_get_best_worker_fn =
                     APR_RETRIEVE_OPTIONAL_FN(proxy_balancer_get_best_worker);
        if (!ap_proxy_balancer_get_best_worker_fn) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10152)
                         "mod_proxy must be loaded for mod_lbmethod_byrequests");
            return !OK;
        }
    
        return OK;
    }
    
    static void register_hook(apr_pool_t *p)
    {
        ap_register_provider(p, PROXY_LBMETHOD, "byrequests", "0", &byrequests);
        ap_hook_post_config(lbmethod_byrequests_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(lbmethod_byrequests) = {
        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_hook /* register hooks */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bytraffic.mak�������������������������������������0000664�0001751�0001751�00000031725�12701473373�024604� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_lbmethod_bytraffic.dsp
    !IF "$(CFG)" == ""
    CFG=mod_lbmethod_bytraffic - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_lbmethod_bytraffic - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_lbmethod_bytraffic - Win32 Release" && "$(CFG)" != "mod_lbmethod_bytraffic - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_lbmethod_bytraffic.mak" CFG="mod_lbmethod_bytraffic - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_bytraffic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_bytraffic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_bytraffic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Release" "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_lbmethod_bytraffic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" "mod_proxy_balancer - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic.res"
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_bytraffic_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_bytraffic.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_bytraffic.so" /d LONG_NAME="lbmethod_bytraffic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_bytraffic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_bytraffic.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_bytraffic.so" /implib:"$(OUTDIR)\mod_lbmethod_bytraffic.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bytraffic.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_bytraffic.obj" \
    	"$(INTDIR)\mod_lbmethod_bytraffic.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib" \
    	"..\Release\mod_proxy.lib" \
    	"..\Release\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_bytraffic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_lbmethod_bytraffic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_bytraffic.so"
       if exist .\Release\mod_lbmethod_bytraffic.so.manifest mt.exe -manifest .\Release\mod_lbmethod_bytraffic.so.manifest -outputresource:.\Release\mod_lbmethod_bytraffic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_bytraffic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Debug" "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_lbmethod_bytraffic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" "mod_proxy_balancer - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic.res"
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_bytraffic_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bytraffic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_bytraffic_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_bytraffic.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_bytraffic.so" /d LONG_NAME="lbmethod_bytraffic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_bytraffic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_bytraffic.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_bytraffic.so" /implib:"$(OUTDIR)\mod_lbmethod_bytraffic.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bytraffic.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_bytraffic.obj" \
    	"$(INTDIR)\mod_lbmethod_bytraffic.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib" \
    	"..\Debug\mod_proxy.lib" \
    	"..\Debug\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_bytraffic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_lbmethod_bytraffic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_bytraffic.so"
       if exist .\Debug\mod_lbmethod_bytraffic.so.manifest mt.exe -manifest .\Debug\mod_lbmethod_bytraffic.so.manifest -outputresource:.\Debug\mod_lbmethod_bytraffic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_lbmethod_bytraffic.dep")
    !INCLUDE "mod_lbmethod_bytraffic.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_lbmethod_bytraffic.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release" || "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    SOURCE=.\mod_lbmethod_bytraffic.c
    
    "$(INTDIR)\mod_lbmethod_bytraffic.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release"
    
    "mod_proxy_balancer - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    
    "mod_proxy_balancer - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Release"
    
    
    "$(INTDIR)\mod_lbmethod_bytraffic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_bytraffic.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_bytraffic.so" /d LONG_NAME="lbmethod_bytraffic_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bytraffic - Win32 Debug"
    
    
    "$(INTDIR)\mod_lbmethod_bytraffic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_bytraffic.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_bytraffic.so" /d LONG_NAME="lbmethod_bytraffic_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bytraffic.dep�������������������������������������0000664�0001751�0001751�00000005663�12674411515�024605� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_lbmethod_bytraffic.mak
    
    .\mod_lbmethod_bytraffic.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_expr.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_mpm.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\ap_slotmem.h"\
    	"..\..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\scoreboard.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_charset.h"\
    	"..\..\..\include\util_ebcdic.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_mutex.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_version.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	"..\mod_proxy.h"\
    	
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    �����������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_byrequests.dsp������������������������������������0000664�0001751�0001751�00000012175�11177743604�025060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_lbmethod_byrequests" - 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_lbmethod_byrequests - 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_lbmethod_byrequests.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_lbmethod_byrequests.mak" CFG="mod_lbmethod_byrequests - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_byrequests - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_byrequests - 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_lbmethod_byrequests - 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 ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_lbmethod_byrequests_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 0x409 /fo"Release/mod_lbmethod_byrequests.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_byrequests.so" /d LONG_NAME="lbmethod_byrequests_module for Apache"
    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 /out:".\Release\mod_lbmethod_byrequests.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_byrequests.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_lbmethod_byrequests.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_byrequests.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_lbmethod_byrequests.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_byrequests - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_lbmethod_byrequests_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 0x409 /fo"Debug/mod_lbmethod_byrequests.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_byrequests.so" /d LONG_NAME="lbmethod_byrequests_module for Apache"
    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 /out:".\Debug\mod_lbmethod_byrequests.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_byrequests.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lbmethod_byrequests.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_byrequests.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_lbmethod_byrequests.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_lbmethod_byrequests - Win32 Release"
    # Name "mod_lbmethod_byrequests - 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_lbmethod_byrequests.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_heartbeat.c���������������������������������������0000664�0001751�0001751�00000032207�14557153357�024250� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "scoreboard.h"
    #include "ap_mpm.h"
    #include "apr_version.h"
    #include "ap_hooks.h"
    #include "ap_slotmem.h"
    #include "heartbeat.h"
    
    #ifndef LBM_HEARTBEAT_MAX_LASTSEEN
    /* If we haven't seen a heartbeat in the last N seconds, don't count this IP
     * as allive.
     */
    #define LBM_HEARTBEAT_MAX_LASTSEEN (10)
    #endif
    
    module AP_MODULE_DECLARE_DATA lbmethod_heartbeat_module;
    
    static int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
            proxy_worker *worker, server_rec *s) = NULL;
    
    static const ap_slotmem_provider_t *storage = NULL;
    static ap_slotmem_instance_t *hm_serversmem = NULL;
    
    /*
     * configuration structure
     * path: path of the file where the heartbeat information is stored.
     */
    typedef struct lb_hb_ctx_t
    {
        const char *path;
    } lb_hb_ctx_t;
    
    typedef struct hb_server_t {
        const char *ip;
        int busy;
        int ready;
        int port;
        int id;
        apr_time_t seen;
        proxy_worker *worker;
    } hb_server_t;
    
    typedef struct ctx_servers {
        apr_time_t now;
        apr_hash_t *servers;
    } ctx_servers_t;
    
    static void
    argstr_to_table(apr_pool_t *p, char *str, apr_table_t *parms)
    {
        char *key;
        char *value;
        char *strtok_state;
    
        key = apr_strtok(str, "&", &strtok_state);
        while (key) {
            value = strchr(key, '=');
            if (value) {
                *value = '\0';      /* Split the string in two */
                value++;            /* Skip passed the = */
            }
            else {
                value = "1";
            }
            ap_unescape_url(key);
            ap_unescape_url(value);
            apr_table_set(parms, key, value);
            /*
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03230)
             "Found query arg: %s = %s", key, value);
             */
            key = apr_strtok(NULL, "&", &strtok_state);
        }
    }
    
    static apr_status_t readfile_heartbeats(const char *path, apr_hash_t *servers,
                                        apr_pool_t *pool)
    {
        apr_finfo_t fi;
        apr_status_t rv;
        apr_file_t *fp;
    
        if (!path) {
            return APR_SUCCESS;
        }
    
        rv = apr_file_open(&fp, path, APR_READ|APR_BINARY|APR_BUFFERED,
                           APR_OS_DEFAULT, pool);
    
        if (rv) {
            return rv;
        }
    
        rv = apr_file_info_get(&fi, APR_FINFO_SIZE, fp);
    
        if (rv) {
            return rv;
        }
    
        {
            char *t;
            apr_bucket_alloc_t *ba = apr_bucket_alloc_create(pool);
            apr_bucket_brigade *bb = apr_brigade_create(pool, ba);
            apr_bucket_brigade *tmpbb = apr_brigade_create(pool, ba);
            apr_table_t *hbt = apr_table_make(pool, 10);
    
            apr_brigade_insert_file(bb, fp, 0, fi.size, pool);
    
            do {
                hb_server_t *server;
                char buf[4096];
                apr_size_t bsize = sizeof(buf);
                const char *ip, *val;
    
                apr_brigade_cleanup(tmpbb);
    
                if (APR_BRIGADE_EMPTY(bb)) {
                    break;
                }
    
                rv = apr_brigade_split_line(tmpbb, bb,
                                            APR_BLOCK_READ, sizeof(buf));
    
                if (rv) {
                    return rv;
                }
    
                apr_brigade_flatten(tmpbb, buf, &bsize);
    
                if (bsize == 0) {
                    break;
                }
    
                buf[bsize - 1] = 0;
    
                /* comment */
                if (buf[0] == '#') {
                    continue;
                }
    
                /* line format: <IP> <query_string>\n */
                t = strchr(buf, ' ');
                if (!t) {
                    continue;
                }
    
                ip = apr_pstrmemdup(pool, buf, t - buf);
                t++;
    
                server = apr_hash_get(servers, ip, APR_HASH_KEY_STRING);
    
                if (server == NULL) {
                    server = apr_pcalloc(pool, sizeof(hb_server_t));
                    server->ip = ip;
                    server->port = 80;
                    server->seen = -1;
    
                    apr_hash_set(servers, server->ip, APR_HASH_KEY_STRING, server);
                }
    
                apr_table_clear(hbt);
    
                argstr_to_table(pool, apr_pstrdup(pool, t), hbt);
    
                if ((val = apr_table_get(hbt, "busy"))) {
                    server->busy = atoi(val);
                }
    
                if ((val = apr_table_get(hbt, "ready"))) {
                    server->ready = atoi(val);
                }
    
                if ((val = apr_table_get(hbt, "lastseen"))) {
                    server->seen = atoi(val);
                }
    
                if ((val = apr_table_get(hbt, "port"))) {
                    server->port = atoi(val);
                }
    
                if (server->busy == 0 && server->ready != 0) {
                    /* Server has zero threads active, but lots of them ready,
                     * it likely just started up, so lets /4 the number ready,
                     * to prevent us from completely flooding it with all new
                     * requests.
                     */
                    server->ready = server->ready / 4;
                }
    
            } while (1);
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t hm_read(void* mem, void *data, apr_pool_t *pool)
    {
        hm_slot_server_t *slotserver = (hm_slot_server_t *) mem;
        ctx_servers_t *ctx = (ctx_servers_t *) data;
        apr_hash_t *servers = (apr_hash_t *) ctx->servers;
        hb_server_t *server = apr_hash_get(servers, slotserver->ip, APR_HASH_KEY_STRING);
        if (server == NULL) {
            server = apr_pcalloc(pool, sizeof(hb_server_t));
            server->ip = apr_pstrdup(pool, slotserver->ip);
            server->seen = -1;
    
            apr_hash_set(servers, server->ip, APR_HASH_KEY_STRING, server);
    
        }
        server->busy = slotserver->busy;
        server->ready = slotserver->ready;
        server->seen = apr_time_sec(ctx->now - slotserver->seen);
        server->id = slotserver->id;
        if (server->busy == 0 && server->ready != 0) {
            server->ready = server->ready / 4;
        }
        return APR_SUCCESS;
    }
    static apr_status_t readslot_heartbeats(ctx_servers_t *ctx,
                                        apr_pool_t *pool)
    {
        storage->doall(hm_serversmem, hm_read, ctx, pool);
        return APR_SUCCESS;
    }
    
    
    static apr_status_t read_heartbeats(const char *path, apr_hash_t *servers,
                                            apr_pool_t *pool)
    {
        apr_status_t rv;
        if (hm_serversmem) {
            ctx_servers_t ctx;
            ctx.now = apr_time_now();
            ctx.servers = servers;
            rv = readslot_heartbeats(&ctx, pool);
        } else
            rv = readfile_heartbeats(path, servers, pool);
        return rv;
    }
    
    static proxy_worker *find_best_hb(proxy_balancer *balancer,
                                      request_rec *r)
    {
        apr_status_t rv;
        int i;
        apr_uint32_t openslots = 0;
        proxy_worker **worker;
        hb_server_t *server;
        apr_array_header_t *up_servers;
        proxy_worker *mycandidate = NULL;
        apr_pool_t *tpool;
        apr_hash_t *servers;
    
        lb_hb_ctx_t *ctx =
            ap_get_module_config(r->server->module_config,
                                 &lbmethod_heartbeat_module);
    
        ap_proxy_retry_worker_fn =
                APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker);
        if (!ap_proxy_retry_worker_fn) {
            /* can only happen if mod_proxy isn't loaded */
            return NULL;
        }
    
        apr_pool_create(&tpool, r->pool);
        apr_pool_tag(tpool, "lb_heartbeat_tpool");
    
        servers = apr_hash_make(tpool);
    
        rv = read_heartbeats(ctx->path, servers, tpool);
    
        if (rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01213)
                          "lb_heartbeat: Unable to read heartbeats at '%s'",
                          ctx->path);
            apr_pool_destroy(tpool);
            return NULL;
        }
    
        up_servers = apr_array_make(tpool, apr_hash_count(servers), sizeof(hb_server_t *));
    
        for (i = 0; i < balancer->workers->nelts; i++) {
            worker = &APR_ARRAY_IDX(balancer->workers, i, proxy_worker *);
            server = apr_hash_get(servers, (*worker)->s->hostname_ex, APR_HASH_KEY_STRING);
    
            if (!server) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(01214)
                          "lb_heartbeat: No server for worker %s", (*worker)->s->name_ex);
                continue;
            }
    
            if (!PROXY_WORKER_IS_USABLE(*worker)) {
                ap_proxy_retry_worker_fn("BALANCER", *worker, r->server);
            }
    
            if (PROXY_WORKER_IS_USABLE(*worker)) {
                server->worker = *worker;
                if (server->seen < LBM_HEARTBEAT_MAX_LASTSEEN) {
                    openslots += server->ready;
                    APR_ARRAY_PUSH(up_servers, hb_server_t *) = server;
                }
            }
        }
    
        if (openslots > 0) {
            apr_uint32_t c = 0;
            apr_uint32_t pick = 0;
    
            pick = ap_random_pick(0, openslots);
    
            for (i = 0; i < up_servers->nelts; i++) {
                server = APR_ARRAY_IDX(up_servers, i, hb_server_t *);
                if (pick >= c && pick <= c + server->ready) {
                    mycandidate = server->worker;
                }
    
                c += server->ready;
            }
        }
    
        apr_pool_destroy(tpool);
    
        return mycandidate;
    }
    
    static apr_status_t reset(proxy_balancer *balancer, server_rec *s)
    {
        return APR_SUCCESS;
    }
    
    static apr_status_t age(proxy_balancer *balancer, server_rec *s)
    {
        return APR_SUCCESS;
    }
    
    static const proxy_balancer_method heartbeat =
    {
        "heartbeat",
        &find_best_hb,
        NULL,
        &reset,
        &age,
        NULL
    };
    
    static int lb_hb_init(apr_pool_t *p, apr_pool_t *plog,
                          apr_pool_t *ptemp, server_rec *s)
    {
        apr_size_t size;
        unsigned int num;
        lb_hb_ctx_t *ctx = ap_get_module_config(s->module_config,
                                                &lbmethod_heartbeat_module);
    
        /* do nothing on first call */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
            return OK;
    
        storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shm",
                                     AP_SLOTMEM_PROVIDER_VERSION);
        if (!storage) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(02281)
                         "Failed to lookup provider 'shm' for '%s'. Maybe you "
                         "need to load mod_slotmem_shm?",
                         AP_SLOTMEM_PROVIDER_GROUP);
            return OK;
        }
    
        /* Try to use a slotmem created by mod_heartmonitor */
        storage->attach(&hm_serversmem, "mod_heartmonitor", &size, &num, p);
        if (!hm_serversmem)
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(02282)
                         "No slotmem from mod_heartmonitor");
        else
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(02283)
                         "Using slotmem from mod_heartmonitor");
    
        if (hm_serversmem)
            ctx->path = "(slotmem)";
    
        return OK;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        static const char * const aszPred[]={ "mod_heartmonitor.c", NULL };
        ap_register_provider(p, PROXY_LBMETHOD, "heartbeat", "0", &heartbeat);
        ap_hook_post_config(lb_hb_init, aszPred, NULL, APR_HOOK_MIDDLE);
    }
    
    static void *lb_hb_create_config(apr_pool_t *p, server_rec *s)
    {
        lb_hb_ctx_t *ctx = (lb_hb_ctx_t *) apr_palloc(p, sizeof(lb_hb_ctx_t));
    
        ctx->path = ap_runtime_dir_relative(p, DEFAULT_HEARTBEAT_STORAGE);
    
        return ctx;
    }
    
    static void *lb_hb_merge_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        lb_hb_ctx_t *ps = apr_pcalloc(p, sizeof(lb_hb_ctx_t));
        lb_hb_ctx_t *base = (lb_hb_ctx_t *) basev;
        lb_hb_ctx_t *overrides = (lb_hb_ctx_t *) overridesv;
    
        if (overrides->path) {
            ps->path = apr_pstrdup(p, overrides->path);
        }
        else {
            ps->path = apr_pstrdup(p, base->path);
        }
    
        return ps;
    }
    
    static const char *cmd_lb_hb_storage(cmd_parms *cmd,
                                      void *dconf, const char *path)
    {
        apr_pool_t *p = cmd->pool;
        lb_hb_ctx_t *ctx =
        (lb_hb_ctx_t *) ap_get_module_config(cmd->server->module_config,
                                             &lbmethod_heartbeat_module);
    
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        ctx->path = ap_runtime_dir_relative(p, path);
    
        return NULL;
    }
    
    static const command_rec cmds[] = {
        AP_INIT_TAKE1("HeartbeatStorage", cmd_lb_hb_storage, NULL, RSRC_CONF,
                      "Path to read heartbeat data."),
        {NULL}
    };
    
    AP_DECLARE_MODULE(lbmethod_heartbeat) = {
        STANDARD20_MODULE_STUFF,
        NULL,                       /* create per-directory config structure */
        NULL,                       /* merge per-directory config structures */
        lb_hb_create_config,        /* create per-server config structure */
        lb_hb_merge_config,         /* merge per-server config structures */
        cmds,                       /* command apr_table_t */
        register_hooks              /* register hooks */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bybusyness.mak������������������������������������0000664�0001751�0001751�00000032061�12701473373�025033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_lbmethod_bybusyness.dsp
    !IF "$(CFG)" == ""
    CFG=mod_lbmethod_bybusyness - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_lbmethod_bybusyness - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_lbmethod_bybusyness - Win32 Release" && "$(CFG)" != "mod_lbmethod_bybusyness - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_lbmethod_bybusyness.mak" CFG="mod_lbmethod_bybusyness - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_bybusyness - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_bybusyness - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_bybusyness.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Release" "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_lbmethod_bybusyness.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" "mod_proxy_balancer - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness.res"
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_bybusyness_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_bybusyness.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_bybusyness.so" /d LONG_NAME="lbmethod_bybusyness_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_bybusyness.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_bybusyness.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_bybusyness.so" /implib:"$(OUTDIR)\mod_lbmethod_bybusyness.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bybusyness.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_bybusyness.obj" \
    	"$(INTDIR)\mod_lbmethod_bybusyness.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib" \
    	"..\Release\mod_proxy.lib" \
    	"..\Release\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_bybusyness.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_lbmethod_bybusyness.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_bybusyness.so"
       if exist .\Release\mod_lbmethod_bybusyness.so.manifest mt.exe -manifest .\Release\mod_lbmethod_bybusyness.so.manifest -outputresource:.\Release\mod_lbmethod_bybusyness.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lbmethod_bybusyness.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy_balancer - Win32 Debug" "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_lbmethod_bybusyness.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" "mod_proxy_balancer - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness.obj"
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness.res"
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness_src.idb"
    	-@erase "$(INTDIR)\mod_lbmethod_bybusyness_src.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.exp"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.lib"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.pdb"
    	-@erase "$(OUTDIR)\mod_lbmethod_bybusyness.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lbmethod_bybusyness_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lbmethod_bybusyness.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_bybusyness.so" /d LONG_NAME="lbmethod_bybusyness_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lbmethod_bybusyness.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lbmethod_bybusyness.pdb" /debug /out:"$(OUTDIR)\mod_lbmethod_bybusyness.so" /implib:"$(OUTDIR)\mod_lbmethod_bybusyness.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_bybusyness.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_lbmethod_bybusyness.obj" \
    	"$(INTDIR)\mod_lbmethod_bybusyness.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib" \
    	"..\Debug\mod_proxy.lib" \
    	"..\Debug\mod_proxy_balancer.lib"
    
    "$(OUTDIR)\mod_lbmethod_bybusyness.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_lbmethod_bybusyness.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lbmethod_bybusyness.so"
       if exist .\Debug\mod_lbmethod_bybusyness.so.manifest mt.exe -manifest .\Debug\mod_lbmethod_bybusyness.so.manifest -outputresource:.\Debug\mod_lbmethod_bybusyness.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_lbmethod_bybusyness.dep")
    !INCLUDE "mod_lbmethod_bybusyness.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_lbmethod_bybusyness.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release" || "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    SOURCE=.\mod_lbmethod_bybusyness.c
    
    "$(INTDIR)\mod_lbmethod_bybusyness.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy\balancers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy\balancers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release"
    
    "mod_proxy_balancer - Win32 Release" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 ReleaseCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    
    "mod_proxy_balancer - Win32 Debug" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" 
       cd ".\balancers"
    
    "mod_proxy_balancer - Win32 DebugCLEAN" : 
       cd ".\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\balancers"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Release"
    
    
    "$(INTDIR)\mod_lbmethod_bybusyness.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_bybusyness.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_bybusyness.so" /d LONG_NAME="lbmethod_bybusyness_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_bybusyness - Win32 Debug"
    
    
    "$(INTDIR)\mod_lbmethod_bybusyness.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lbmethod_bybusyness.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_bybusyness.so" /d LONG_NAME="lbmethod_bybusyness_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_bybusyness.dep������������������������������������0000664�0001751�0001751�00000005665�12674411515�025044� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_lbmethod_bybusyness.mak
    
    .\mod_lbmethod_bybusyness.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_expr.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_mpm.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\ap_slotmem.h"\
    	"..\..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\scoreboard.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_charset.h"\
    	"..\..\..\include\util_ebcdic.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_mutex.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_version.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	"..\mod_proxy.h"\
    	
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    ���������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/mod_lbmethod_heartbeat.dsp�������������������������������������0000664�0001751�0001751�00000012137�11177743604�024607� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_lbmethod_heartbeat" - 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_lbmethod_heartbeat - 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_lbmethod_heartbeat.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_lbmethod_heartbeat.mak" CFG="mod_lbmethod_heartbeat - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lbmethod_heartbeat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lbmethod_heartbeat - 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_lbmethod_heartbeat - 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 ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_lbmethod_heartbeat_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 0x409 /fo"Release/mod_lbmethod_heartbeat.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lbmethod_heartbeat.so" /d LONG_NAME="lbmethod_heartbeat_module for Apache"
    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 /out:".\Release\mod_lbmethod_heartbeat.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_heartbeat.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_lbmethod_heartbeat.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_heartbeat.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_lbmethod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_lbmethod_heartbeat - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I ".." /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_lbmethod_heartbeat_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 0x409 /fo"Debug/mod_lbmethod_heartbeat.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lbmethod_heartbeat.so" /d LONG_NAME="lbmethod_heartbeat_module for Apache"
    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 /out:".\Debug\mod_lbmethod_heartbeat.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_heartbeat.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lbmethod_heartbeat.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_lbmethod_heartbeat.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_lbmethod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_lbmethod_heartbeat - Win32 Release"
    # Name "mod_lbmethod_heartbeat - 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_lbmethod_heartbeat.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/balancers/Makefile.in����������������������������������������������������0000664�0001751�0001751�00000000267�11115517761�021464� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxyexpress��������������������������������������������������������0000664�0001751�0001751�00000010513�11611546631�021014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= proxyexpress
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy Express Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Prxy Xpress 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	=
    
    #
    # 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)/$(NLM_NAME).nlm
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib =
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/mod_proxy_express.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 = \
    	$(PRELUDE) \
    	$(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 \
    	aprlib \
    	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 = \
    	@libc.imp \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.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_express_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_connect.mak����������������������������������������������������0000664�0001751�0001751�00000026263�12701473373�021716� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_connect.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_connect - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_connect - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_connect - Win32 Release" && "$(CFG)" != "mod_proxy_connect - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_connect - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_connect.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_connect.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_connect.obj"
    	-@erase "$(INTDIR)\mod_proxy_connect.res"
    	-@erase "$(INTDIR)\mod_proxy_connect_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_connect_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_connect.exp"
    	-@erase "$(OUTDIR)\mod_proxy_connect.lib"
    	-@erase "$(OUTDIR)\mod_proxy_connect.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_connect.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_connect_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_connect.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_connect.so" /d LONG_NAME="proxy_connect_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_connect.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_connect.pdb" /debug /out:"$(OUTDIR)\mod_proxy_connect.so" /implib:"$(OUTDIR)\mod_proxy_connect.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_connect.obj" \
    	"$(INTDIR)\mod_proxy_connect.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_connect.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_connect.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_connect.so"
       if exist .\Release\mod_proxy_connect.so.manifest mt.exe -manifest .\Release\mod_proxy_connect.so.manifest -outputresource:.\Release\mod_proxy_connect.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_connect - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_connect.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_connect.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_connect.obj"
    	-@erase "$(INTDIR)\mod_proxy_connect.res"
    	-@erase "$(INTDIR)\mod_proxy_connect_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_connect_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_connect.exp"
    	-@erase "$(OUTDIR)\mod_proxy_connect.lib"
    	-@erase "$(OUTDIR)\mod_proxy_connect.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_connect.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_connect_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_connect.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_connect.so" /d LONG_NAME="proxy_connect_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_connect.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_connect.pdb" /debug /out:"$(OUTDIR)\mod_proxy_connect.so" /implib:"$(OUTDIR)\mod_proxy_connect.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_connect.obj" \
    	"$(INTDIR)\mod_proxy_connect.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_connect.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_connect.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_connect.so"
       if exist .\Debug\mod_proxy_connect.so.manifest mt.exe -manifest .\Debug\mod_proxy_connect.so.manifest -outputresource:.\Debug\mod_proxy_connect.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_connect.dep")
    !INCLUDE "mod_proxy_connect.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_connect.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_connect - Win32 Release" || "$(CFG)" == "mod_proxy_connect - Win32 Debug"
    SOURCE=.\mod_proxy_connect.c
    
    "$(INTDIR)\mod_proxy_connect.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_connect - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_connect - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_connect - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_connect - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_connect - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_connect - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_connect - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_connect - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_connect - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_connect.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_connect.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_connect.so" /d LONG_NAME="proxy_connect_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_connect - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_connect.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_connect.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_connect.so" /d LONG_NAME="proxy_connect_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_wstunnel.mak���������������������������������������������������0000664�0001751�0001751�00000026415�12701473373�022143� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_wstunnel.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_wstunnel - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_wstunnel - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_wstunnel - Win32 Release" && "$(CFG)" != "mod_proxy_wstunnel - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_wstunnel.mak" CFG="mod_proxy_wstunnel - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_wstunnel - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_wstunnel - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_wstunnel.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_wstunnel.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_wstunnel.obj"
    	-@erase "$(INTDIR)\mod_proxy_wstunnel.res"
    	-@erase "$(INTDIR)\mod_proxy_wstunnel_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_wstunnel_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.exp"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.lib"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_wstunnel_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_wstunnel.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_wstunnel.so" /d LONG_NAME="proxy_wstunnel_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_wstunnel.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_wstunnel.pdb" /debug /out:"$(OUTDIR)\mod_proxy_wstunnel.so" /implib:"$(OUTDIR)\mod_proxy_wstunnel.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_wstunnel.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_wstunnel.obj" \
    	"$(INTDIR)\mod_proxy_wstunnel.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_wstunnel.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_wstunnel.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_wstunnel.so"
       if exist .\Release\mod_proxy_wstunnel.so.manifest mt.exe -manifest .\Release\mod_proxy_wstunnel.so.manifest -outputresource:.\Release\mod_proxy_wstunnel.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_wstunnel.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_wstunnel.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_wstunnel.obj"
    	-@erase "$(INTDIR)\mod_proxy_wstunnel.res"
    	-@erase "$(INTDIR)\mod_proxy_wstunnel_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_wstunnel_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.exp"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.lib"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_wstunnel.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_wstunnel_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_wstunnel.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_wstunnel.so" /d LONG_NAME="proxy_wstunnel_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_wstunnel.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_wstunnel.pdb" /debug /out:"$(OUTDIR)\mod_proxy_wstunnel.so" /implib:"$(OUTDIR)\mod_proxy_wstunnel.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_wstunnel.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_wstunnel.obj" \
    	"$(INTDIR)\mod_proxy_wstunnel.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_wstunnel.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_wstunnel.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_wstunnel.so"
       if exist .\Debug\mod_proxy_wstunnel.so.manifest mt.exe -manifest .\Debug\mod_proxy_wstunnel.so.manifest -outputresource:.\Debug\mod_proxy_wstunnel.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_wstunnel.dep")
    !INCLUDE "mod_proxy_wstunnel.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_wstunnel.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_wstunnel - Win32 Release" || "$(CFG)" == "mod_proxy_wstunnel - Win32 Debug"
    SOURCE=.\mod_proxy_wstunnel.c
    
    "$(INTDIR)\mod_proxy_wstunnel.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_wstunnel.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_wstunnel.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_wstunnel.so" /d LONG_NAME="proxy_wstunnel_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_wstunnel - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_wstunnel.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_wstunnel.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_wstunnel.so" /d LONG_NAME="proxy_wstunnel_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ajp.dsp��������������������������������������������������������0000664�0001751�0001751�00000012244�10551346420�021040� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 0x409 /fo"Release/mod_proxy_ajp.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_ajp.so" /d LONG_NAME="proxy_ajp_module for Apache"
    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 /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 /out:".\Release\mod_proxy_ajp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_ajp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 0x409 /fo"Debug/mod_proxy_ajp.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_ajp.so" /d LONG_NAME="proxy_ajp_module for Apache"
    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 /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 /out:".\Debug\mod_proxy_ajp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_ajp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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
    # Begin Source File
    
    SOURCE=.\ajp_utils.c
    # End Source File
    # End Group
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ajp.c����������������������������������������������������������0000664�0001751�0001751�00000105046�15032730171�020476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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, sport[7];
        char *search = NULL;
        const char *err;
        apr_port_t port, def_port;
    
        /* ap_port_of_scheme() */
        if (ap_cstr_casecmpn(url, "ajp:", 4) == 0) {
            url += 4;
        }
        else {
            return DECLINED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "canonicalising URL %s", url);
    
        /*
         * do syntactic check.
         * We break the URL into host, port, path, search
         */
        port = def_port = ap_proxy_port_of_scheme("ajp");
    
        err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00867) "error parsing URL %s: %s",
                          url, err);
            return HTTP_BAD_REQUEST;
        }
    
        /*
         * now parse path/search args, according to rfc1738:
         * process the path. With proxy-nocanon set (by
         * mod_proxy) we use the raw, unparsed uri
         */
        if (apr_table_get(r->notes, "proxy-nocanon")) {
            path = url;   /* this is the raw path */
        }
        else if (apr_table_get(r->notes, "proxy-noencode")) {
            path = url;   /* this is the encoded path already */
            search = r->args;
        }
        else {
            core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
            int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
            path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
                                        r->proxyreq);
            if (!path) {
                return HTTP_BAD_REQUEST;
            }
            search = r->args;
        }
        /*
         * If we have a raw control character or a ' ' in nocanon path or
         * r->args, correct encoding was missed.
         */
        if (path == url && *ap_scan_vchar_obstext(path)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10418)
                          "To be forwarded path contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
        if (search && *ap_scan_vchar_obstext(search)) {
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10406)
                           "To be forwarded query string contains control "
                           "characters or spaces");
             return HTTP_FORBIDDEN;
        }
    
        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:ajp://", host, sport,
                                  "/", path, (search) ? "?" : "",
                                  (search) ? search : "", NULL);
        return OK;
    }
    
    #define METHOD_NON_IDEMPOTENT       0
    #define METHOD_IDEMPOTENT           1
    #define METHOD_IDEMPOTENT_WITH_ARGS 2
    
    static int is_idempotent(request_rec *r)
    {
        /*
         * RFC2616 (9.1.2): GET, HEAD, PUT, DELETE, OPTIONS, TRACE are considered
         * idempotent. Hint: HEAD requests use M_GET as method number as well.
         */
        switch (r->method_number) {
            case M_GET:
            case M_DELETE:
            case M_PUT:
            case M_OPTIONS:
            case M_TRACE:
                /*
                 * If the request has arguments it might have side-effects and thus
                 * it might be undesirable to resend it to a backend again
                 * automatically.
                 */
                if (r->args) {
                    return METHOD_IDEMPOTENT_WITH_ARGS;
                }
                return METHOD_IDEMPOTENT;
            /* Everything else is not considered idempotent. */
            default:
                return METHOD_NON_IDEMPOTENT;
        }
    }
    
    static apr_off_t get_content_length(request_rec * r)
    {
        apr_off_t len = 0;
    
        if (r->main == NULL) {
            const char *clp = apr_table_get(r->headers_in, "Content-Length");
    
            if (clp && !ap_parse_strict_length(&len, clp)) {
                len = -1; /* parse error */
            }
        }
    
        return len;
    }
    
    /*
     * XXX: AJP Auto Flushing
     *
     * When processing CMD_AJP13_SEND_BODY_CHUNK AJP messages we will do a poll
     * with FLUSH_WAIT milliseconds timeout to determine if more data is currently
     * available at the backend. If there is no more data available, we flush
     * the data to the client by adding a flush bucket to the brigade we pass
     * up the filter chain.
     * This is only a bandaid to fix the AJP/1.3 protocol shortcoming of not
     * sending (actually not having defined) a flush message, when the data
     * should be flushed to the client. As soon as this protocol shortcoming is
     * fixed this code should be removed.
     *
     * For further discussion see PR37100.
     * http://issues.apache.org/bugzilla/show_bug.cgi?id=37100
     */
    
    /*
     * process the request and write the response.
     */
    static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
                                    proxy_conn_rec *conn,
                                    conn_rec *origin,
                                    proxy_dir_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 = 0;
        char *buff;
        char *send_body_chunk_buff;
        apr_uint16_t size;
        apr_byte_t conn_reuse = 0;
        const char *tenc;
        int havebody = 1;
        int client_failed = 0;
        int backend_failed = 0;
        apr_off_t bb_len;
        int data_sent = 0;
        int request_ended = 0;
        int headers_sent = 0;
        int rv = OK;
        apr_int32_t conn_poll_fd;
        apr_pollfd_t *conn_poll;
        proxy_server_conf *psf =
        ap_get_module_config(r->server->module_config, &proxy_module);
        apr_size_t maxsize = AJP_MSG_BUFFER_SZ;
        int send_body = 0;
        apr_off_t content_length = 0;
        int original_status = r->status;
        const char *original_status_line = r->status_line;
        const char *secret = NULL;
    
        if (psf->io_buffer_size_set)
           maxsize = psf->io_buffer_size;
        /* Override with worker setting if present */
        if (conn->worker->s->io_buffer_size_set)
           maxsize = conn->worker->s->io_buffer_size;
        if (maxsize > AJP_MAX_BUFFER_SZ)
           maxsize = AJP_MAX_BUFFER_SZ;
        else if (maxsize < AJP_MSG_BUFFER_SZ)
           maxsize = AJP_MSG_BUFFER_SZ;
        maxsize = APR_ALIGN(maxsize, 1024);
    
        if (*conn->worker->s->secret)
            secret = conn->worker->s->secret;
    
        /*
         * Send the AJP request to the remote server
         */
    
        /* send request headers */
        status = ajp_send_header(conn->sock, r, maxsize, uri, secret);
        if (status != APR_SUCCESS) {
            conn->close = 1;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00868)
                          "request failed to %pI (%s:%hu)",
                          conn->addr, conn->hostname, conn->port);
            if (status == AJP_EOVERFLOW)
                return HTTP_BAD_REQUEST;
            else if  (status == AJP_EBAD_METHOD) {
                return HTTP_NOT_IMPLEMENTED;
            } else {
                /*
                 * This is only non fatal when the method is idempotent. In this
                 * case we can dare to retry it with a different worker if we are
                 * a balancer member.
                 */
                if (is_idempotent(r) == METHOD_IDEMPOTENT) {
                    return HTTP_SERVICE_UNAVAILABLE;
                }
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        /* allocate an AJP message to store the data of the buckets */
        bufsiz = maxsize;
        status = ajp_alloc_data_msg(r->pool, &buff, &bufsiz, &msg);
        if (status != APR_SUCCESS) {
            /* We had a failure: Close connection to backend */
            conn->close = 1;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00869)
                          "ajp_alloc_data_msg failed");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* read the first block of data */
        input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
        tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
        if (tenc) {
            if (ap_cstr_casecmp(tenc, "chunked") == 0) {
                /* The AJP protocol does not want body data yet */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870)
                              "request is chunked");
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396)
                              "%s Transfer-Encoding is not supported",
                              tenc);
                /* We had a failure: Close connection to backend */
                conn->close = 1;
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        } else {
            /* Get client provided Content-Length header */
            content_length = get_content_length(r);
            if (content_length < 0) {
                status = APR_EINVAL;
            }
            else {
                status = ap_get_brigade(r->input_filters, input_brigade,
                                        AP_MODE_READBYTES, APR_BLOCK_READ,
                                        maxsize - AJP_HEADER_SZ);
            }
            if (status != APR_SUCCESS) {
                /* We had a failure: Close connection to backend */
                conn->close = 1;
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00871)
                              "ap_get_brigade failed");
                apr_brigade_destroy(input_brigade);
                return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
            }
    
            /* have something */
            if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00872) "APR_BUCKET_IS_EOS");
            }
    
            /* Try to send something */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00873)
                          "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) {
                /* We had a failure: Close connection to backend */
                conn->close = 1;
                apr_brigade_destroy(input_brigade);
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00874)
                              "apr_brigade_flatten");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            apr_brigade_cleanup(input_brigade);
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00875)
                          "got %" APR_SIZE_T_FMT " bytes of data", bufsiz);
            if (bufsiz > 0) {
                status = ajp_send_data_msg(conn->sock, msg, bufsiz);
                ajp_msg_log(r, msg, "First ajp_send_data_msg: ajp_ilink_send packet dump");
                if (status != APR_SUCCESS) {
                    /* We had a failure: Close connection to backend */
                    conn->close = 1;
                    apr_brigade_destroy(input_brigade);
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00876)
                                  "send failed to %pI (%s:%hu)",
                                  conn->addr, conn->hostname, conn->port);
                    /*
                     * It is fatal when we failed to send a (part) of the request
                     * body.
                     */
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                conn->worker->s->transferred += bufsiz;
                send_body = 1;
            }
            else if (content_length > 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00877)
                              "read zero bytes, expecting"
                              " %" APR_OFF_T_FMT " bytes",
                              content_length);
                /*
                 * We can only get here if the client closed the connection
                 * to us without sending the body.
                 * Now the connection is in the wrong state on the backend.
                 * Sending an empty data msg doesn't help either as it does
                 * not move this connection to the correct state on the backend
                 * for later resusage by the next request again.
                 * Close it to clean things up.
                 */
                conn->close = 1;
                apr_brigade_destroy(input_brigade);
                return HTTP_BAD_REQUEST;
            }
        }
    
        /* read the response */
        conn->data = NULL;
        status = ajp_read_header(conn->sock, r, maxsize,
                                 (ajp_msg_t **)&(conn->data));
        if (status != APR_SUCCESS) {
            /* We had a failure: Close connection to backend */
            conn->close = 1;
            apr_brigade_destroy(input_brigade);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00878)
                          "read response failed from %pI (%s:%hu)",
                          conn->addr, conn->hostname, conn->port);
    
            /* If we had a successful cping/cpong and then a timeout
             * we assume it is a request that cause a back-end timeout,
             * but doesn't affect the whole worker.
             */
            if (APR_STATUS_IS_TIMEUP(status) &&
                    conn->worker->s->ping_timeout_set) {
                return HTTP_GATEWAY_TIME_OUT;
            }
    
            /*
             * This is only non fatal when we have not sent (parts) of a possible
             * request body so far (we do not store it and thus cannot send it
             * again) and the method is idempotent. In this case we can dare to
             * retry it with a different worker if we are a balancer member.
             */
            if (!send_body && (is_idempotent(r) == METHOD_IDEMPOTENT)) {
                return HTTP_SERVICE_UNAVAILABLE;
            }
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        /* parse the response */
        result = ajp_parse_type(r, conn->data);
        output_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
    
        /*
         * Prepare apr_pollfd_t struct for possible later check if there is currently
         * data available from the backend (do not flush response to client)
         * or not (flush response to client)
         */
        conn_poll = apr_pcalloc(p, sizeof(apr_pollfd_t));
        conn_poll->reqevents = APR_POLLIN;
        conn_poll->desc_type = APR_POLL_SOCKET;
        conn_poll->desc.s = conn->sock;
    
        bufsiz = maxsize;
        for (;;) {
            switch (result) {
                case CMD_AJP13_GET_BODY_CHUNK:
                    if (havebody) {
                        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
                            /* This is the end */
                            bufsiz = 0;
                            havebody = 0;
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00879)
                                          "APR_BUCKET_IS_EOS");
                        } else {
                            status = ap_get_brigade(r->input_filters, input_brigade,
                                                    AP_MODE_READBYTES,
                                                    APR_BLOCK_READ,
                                                    maxsize - AJP_HEADER_SZ);
                            if (status != APR_SUCCESS) {
                                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00880)
                                              "ap_get_brigade failed");
                                if (APR_STATUS_IS_TIMEUP(status)) {
                                    rv = HTTP_REQUEST_TIME_OUT;
                                }
                                else if (status == AP_FILTER_ERROR) {
                                    rv = AP_FILTER_ERROR;
                                }
                                client_failed = 1;
                                break;
                            }
                            bufsiz = maxsize;
                            status = apr_brigade_flatten(input_brigade, buff,
                                                         &bufsiz);
                            apr_brigade_cleanup(input_brigade);
                            if (status != APR_SUCCESS) {
                                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00881)
                                             "apr_brigade_flatten failed");
                                rv = HTTP_INTERNAL_SERVER_ERROR;
                                client_failed = 1;
                                break;
                            }
                        }
    
                        ajp_msg_reset(msg);
                        /* will go in ajp_send_data_msg */
                        status = ajp_send_data_msg(conn->sock, msg, bufsiz);
                        ajp_msg_log(r, msg, "ajp_send_data_msg after CMD_AJP13_GET_BODY_CHUNK: ajp_ilink_send packet dump");
                        if (status != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00882)
                                          "ajp_send_data_msg failed");
                            backend_failed = 1;
                            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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00883)
                                      "ap_proxy_ajp_request error read after end");
                        backend_failed = 1;
                    }
                    break;
                case CMD_AJP13_SEND_HEADERS:
                    if (headers_sent) {
                        /* Do not send anything to the client.
                         * Backend already send us the headers.
                         */
                        backend_failed = 1;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00884)
                                      "Backend sent headers twice.");
                        break;
                    }
                    /* AJP13_SEND_HEADERS: process them */
                    status = ajp_parse_header(r, conf, conn->data);
                    if (status != APR_SUCCESS) {
                        backend_failed = 1;
                    }
                    else if ((r->status == 401) && conf->error_override) {
                        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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00885)
                                          "ap_proxy_ajp_request: origin server "
                                          "sent 401 without WWW-Authenticate header");
                        }
                    }
                    headers_sent = 1;
                    break;
                case CMD_AJP13_SEND_BODY_CHUNK:
                    /* AJP13_SEND_BODY_CHUNK: piece of data */
                    status = ajp_parse_data(r, conn->data, &size, &send_body_chunk_buff);
                    if (status == APR_SUCCESS) {
                        /* If we are overriding the errors, we can't put the content
                         * of the page into the brigade.
                         */
                        if (!ap_proxy_should_override(conf, r->status)) {
                            /* AJP13_SEND_BODY_CHUNK with zero length
                             * is explicit flush message
                             */
                            if (size == 0) {
                                if (headers_sent) {
                                    e = apr_bucket_flush_create(r->connection->bucket_alloc);
                                    APR_BRIGADE_INSERT_TAIL(output_brigade, e);
                                }
                                else {
                                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00886)
                                                  "Ignoring flush message "
                                                  "received before headers");
                                }
                            }
                            else {
                                apr_status_t rv;
    
                                /* Handle the case where the error document is itself reverse
                                 * proxied and was successful. We must maintain any previous
                                 * error status so that an underlying error (eg HTTP_NOT_FOUND)
                                 * doesn't become an HTTP_OK.
                                 */
                                if (ap_proxy_should_override(conf, original_status)) {
                                    r->status = original_status;
                                    r->status_line = original_status_line;
                                }
    
                                e = apr_bucket_transient_create(send_body_chunk_buff, size,
                                                            r->connection->bucket_alloc);
                                APR_BRIGADE_INSERT_TAIL(output_brigade, e);
    
                                if ((conn->worker->s->flush_packets == flush_on) ||
                                    ((conn->worker->s->flush_packets == flush_auto) &&
                                    ((rv = apr_poll(conn_poll, 1, &conn_poll_fd,
                                                     conn->worker->s->flush_wait))
                                                     != APR_SUCCESS) &&
                                      APR_STATUS_IS_TIMEUP(rv))) {
                                    e = apr_bucket_flush_create(r->connection->bucket_alloc);
                                    APR_BRIGADE_INSERT_TAIL(output_brigade, e);
                                }
                                apr_brigade_length(output_brigade, 0, &bb_len);
                                if (bb_len != -1)
                                    conn->worker->s->read += bb_len;
                            }
                            if (headers_sent) {
                                if (ap_pass_brigade(r->output_filters,
                                                    output_brigade) != APR_SUCCESS) {
                                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00887)
                                                  "error processing body.%s",
                                                  r->connection->aborted ?
                                                  " Client aborted connection." : "");
                                    client_failed = 1;
                                }
                                data_sent = 1;
                                apr_brigade_cleanup(output_brigade);
                            }
                        }
                    }
                    else {
                        backend_failed = 1;
                    }
                    break;
                case CMD_AJP13_END_RESPONSE:
                    /* If we are overriding the errors, we must not send anything to
                     * the client, especially as the brigade already contains headers.
                     * So do nothing here, and it will be cleaned up below.
                     */
                    status = ajp_parse_reuse(r, conn->data, &conn_reuse);
                    if (status != APR_SUCCESS) {
                        backend_failed = 1;
                    }
                    if (!ap_proxy_should_override(conf, r->status)) {
                        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_DEBUG, 0, r, APLOGNO(00888)
                                          "error processing end");
                            client_failed = 1;
                        }
                        /* XXX: what about flush here? See mod_jk */
                        data_sent = 1;
                    }
                    request_ended = 1;
                    break;
                default:
                    backend_failed = 1;
                    break;
            }
    
            /*
             * If connection has been aborted by client: Stop working.
             * Pretend we are done (data_sent) to avoid further processing.
             */
            if (r->connection->aborted) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02821)
                              "client connection aborted");
                /* no response yet (or ever), set status for access log */
                if (!headers_sent) {
                    r->status = HTTP_BAD_REQUEST;
                }
                client_failed = 1;
                /* return DONE */
                data_sent = 1;
                break;
            }
    
            /*
             * We either have finished successfully or we failed.
             * So bail out
             */
            if ((result == CMD_AJP13_END_RESPONSE)
                    || backend_failed || client_failed)
                break;
    
            /* read the response */
            status = ajp_read_header(conn->sock, r, maxsize,
                                     (ajp_msg_t **)&(conn->data));
            if (status != APR_SUCCESS) {
                backend_failed = 1;
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00889)
                              "ajp_read_header failed");
                break;
            }
            result = ajp_parse_type(r, conn->data);
        }
        apr_brigade_destroy(input_brigade);
    
        /*
         * Clear output_brigade to remove possible buckets that remained there
         * after an error.
         */
        apr_brigade_cleanup(output_brigade);
    
        if (backend_failed || client_failed) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00890)
                          "Processing of request failed backend: %i, client: %i",
                          backend_failed, client_failed);
            /* We had a failure: Close connection to backend */
            conn->close = 1;
            if (data_sent) {
                /* Return DONE to avoid error messages being added to the stream */
                rv = DONE;
            }
        }
        else if (!request_ended) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00891)
                          "Processing of request didn't terminate cleanly");
            /* We had a failure: Close connection to backend */
            conn->close = 1;
            backend_failed = 1;
            if (data_sent) {
                /* Return DONE to avoid error messages being added to the stream */
                rv = DONE;
            }
        }
        else if (!conn_reuse) {
            /* Our backend signalled connection close */
            conn->close = 1;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00892)
                          "got response from %pI (%s:%hu)",
                          conn->addr, conn->hostname, conn->port);
    
            if (ap_proxy_should_override(conf, r->status)) {
                /* clear r->status for override error, otherwise ErrorDocument
                 * thinks that this is a recursive error, and doesn't find the
                 * custom error page
                 */
                rv = r->status;
                r->status = HTTP_OK;
                /*
                 * prevent proxy_handler() from treating this as an
                 * internal error.
                 */
                apr_table_setn(r->notes, "proxy-error-override", "1");
            }
            else {
                rv = OK;
            }
        }
    
        if (backend_failed) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00893)
                          "dialog to %pI (%s:%hu) failed",
                          conn->addr, conn->hostname, conn->port);
            /*
             * If we already send data, signal a broken backend connection
             * upwards in the chain.
             */
            if (data_sent) {
                ap_proxy_backend_broke(r, output_brigade);
            } else if (!send_body && (is_idempotent(r) == METHOD_IDEMPOTENT)) {
                /*
                 * This is only non fatal when we have not send (parts) of a possible
                 * request body so far (we do not store it and thus cannot send it
                 * again) and the method is idempotent. In this case we can dare to
                 * retry it with a different worker if we are a balancer member.
                 */
                rv = HTTP_SERVICE_UNAVAILABLE;
            } else {
                /* If we had a successful cping/cpong and then a timeout
                 * we assume it is a request that cause a back-end timeout,
                 * but doesn't affect the whole worker.
                 */
                if (APR_STATUS_IS_TIMEUP(status) &&
                        conn->worker->s->ping_timeout_set) {
                    apr_table_setn(r->notes, "proxy_timedout", "1");
                    rv = HTTP_GATEWAY_TIME_OUT;
                }
                else {
                    rv = HTTP_INTERNAL_SERVER_ERROR;
                }
            }
        }
        else if (client_failed) {
            int level = (r->connection->aborted) ? APLOG_DEBUG : APLOG_ERR;
            ap_log_rerror(APLOG_MARK, level, status, r, APLOGNO(02822)
                          "dialog with client %pI failed",
                          r->connection->client_addr);
            if (rv == OK) {
                rv = HTTP_BAD_REQUEST;
            }
        }
    
        /*
         * Ensure that we sent an EOS bucket thru the filter chain, if we already
         * have sent some data. Maybe ap_proxy_backend_broke was called and added
         * one to the brigade already (no longer making it empty). So we should
         * not do this in this case.
         */
        if (data_sent && !r->eos_sent && !r->connection->aborted
                && APR_BRIGADE_EMPTY(output_brigade)) {
            e = apr_bucket_eos_create(r->connection->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(output_brigade, e);
        }
    
        /* If we have added something to the brigade above, send it */
        if (!APR_BRIGADE_EMPTY(output_brigade)
            && ap_pass_brigade(r->output_filters, output_brigade) != APR_SUCCESS) {
            rv = AP_FILTER_ERROR;
        }
    
        apr_brigade_destroy(output_brigade);
    
        if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) {
            conn->close = 1;
        }
    
        return rv;
    }
    
    /*
     * This handles ajp:// URLs
     */
    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";
        int retry;
        proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                     &proxy_module);
        apr_pool_t *p = r->pool;
        apr_uri_t *uri;
    
        if (ap_cstr_casecmpn(url, "ajp:", 4) != 0) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00894) "declining URL %s", url);
            return DECLINED;
        }
    
        uri = apr_palloc(p, sizeof(*uri));
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00895) "serving URL %s", url);
    
        /* create space for state information */
        status = ap_proxy_acquire_connection(scheme, &backend, worker,
                                             r->server);
        if (status != OK) {
            if (backend) {
                backend->close = 1;
                ap_proxy_release_connection(scheme, backend, r->server);
            }
            return status;
        }
    
        backend->is_ssl = 0;
        backend->close = 0;
    
        retry = 0;
        while (retry < 2) {
            char *locurl = url;
            /* Step One: Determine Who To Connect To */
            status = ap_proxy_determine_connection(p, r, conf, worker, backend,
                                                   uri, &locurl, proxyname, proxyport,
                                                   server_portstr,
                                                   sizeof(server_portstr));
    
            if (status != OK)
                break;
    
            /* Step Two: Make the Connection */
            if (ap_proxy_check_connection(scheme, backend, r->server, 0,
                                          PROXY_CHECK_CONN_EMPTY)
                    && ap_proxy_connect_backend(scheme, backend, worker,
                                                r->server)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00896)
                              "failed to make connection to backend: %s",
                              backend->hostname);
                status = HTTP_SERVICE_UNAVAILABLE;
                break;
            }
    
            /* Handle CPING/CPONG */
            if (worker->s->ping_timeout_set) {
                status = ajp_handle_cping_cpong(backend->sock, r,
                                                worker->s->ping_timeout);
                /*
                 * In case the CPING / CPONG failed for the first time we might be
                 * just out of luck and got a faulty backend connection, but the
                 * backend might be healthy nevertheless. So ensure that the backend
                 * TCP connection gets closed and try it once again.
                 */
                if (status != APR_SUCCESS) {
                    backend->close = 1;
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00897)
                                  "cping/cpong failed to %pI (%s:%hu)",
                                  backend->addr, backend->hostname, backend->port);
                    status = HTTP_SERVICE_UNAVAILABLE;
                    retry++;
                    continue;
                }
            }
            /* Step Three: Process the Request */
            status = ap_proxy_ajp_request(p, r, backend, origin, dconf, uri, locurl,
                                          server_portstr);
            break;
        }
    
        /* 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);
        APR_REGISTER_OPTIONAL_FN(ajp_handle_cping_cpong);
    }
    
    AP_DECLARE_MODULE(proxy_ajp) = {
        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 */
    };
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_fcgi.c���������������������������������������������������������0000664�0001751�0001751�00000143276�14737241336�020656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "util_fcgi.h"
    #include "util_script.h"
    #include "ap_expr.h"
    
    module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
    
    typedef struct {
        ap_expr_info_t *cond;
        ap_expr_info_t *subst;
        const char *envname;
    } sei_entry;
    
    typedef struct {
        char *dirwalk_uri_path;
    } fcgi_req_config_t;
    
    /* We will assume FPM, but still differentiate */
    typedef enum {
        BACKEND_DEFAULT_UNKNOWN = 0,
        BACKEND_FPM,
        BACKEND_GENERIC,
    } fcgi_backend_t;
    
    
    #define FCGI_MAY_BE_FPM(dconf)                              \
            (dconf &&                                           \
            ((dconf->backend_type == BACKEND_DEFAULT_UNKNOWN) || \
            (dconf->backend_type == BACKEND_FPM)))
    
    typedef struct {
        fcgi_backend_t backend_type;
        apr_array_header_t *env_fixups;
    } fcgi_dirconf_t;
    
    /*
     * 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_fcgi_canon(request_rec *r, char *url)
    {
        char *host, sport[7];
        const char *err;
        char *path;
        apr_port_t port, def_port;
        fcgi_req_config_t *rconf = NULL;
        const char *pathinfo_type = NULL;
        fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config,
                                                     &proxy_fcgi_module);
    
        if (ap_cstr_casecmpn(url, "fcgi:", 5) == 0) {
            url += 5;
        }
        else {
            return DECLINED;
        }
    
        port = def_port = ap_proxy_port_of_scheme("fcgi");
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                     "canonicalising URL %s", url);
        err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01059)
                          "error parsing URL %s: %s", url, err);
            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);
        }
    
        if (apr_table_get(r->notes, "proxy-sethandler")
            || apr_table_get(r->notes, "proxy-nocanon")
            || apr_table_get(r->notes, "proxy-noencode")) {
            char *c = url;
    
            /* We do not call ap_proxy_canonenc_ex() on the path here, don't
             * let control characters pass still, and for php-fpm no '?' either.
             */
            if (FCGI_MAY_BE_FPM(dconf)) {
                while (!apr_iscntrl(*c) && *c != '?')
                    c++;
            }
            else {
                while (!apr_iscntrl(*c))
                    c++;
            }
            if (*c) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10414)
                              "To be forwarded path contains control characters%s (%s)",
                              FCGI_MAY_BE_FPM(dconf) ? " or '?'" : "", url);
                return HTTP_FORBIDDEN;
            }
    
            path = url;  /* this is the raw path */
        }
        else {
            core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
            int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
            path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
                                        r->proxyreq);
            if (!path) {
                return HTTP_BAD_REQUEST;
            }
        }
    
        r->filename = apr_pstrcat(r->pool, "proxy:fcgi://", host, sport, "/",
                                  path, NULL);
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01060)
                      "set r->filename to %s", r->filename);
    
        rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
        if (rconf == NULL) {
            rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
            ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
        }
        rconf->dirwalk_uri_path = NULL;
    
        pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo");
        if (pathinfo_type) {
            /* It has to be on disk for this to work */
            if (!strcasecmp(pathinfo_type, "full")) {
                rconf->dirwalk_uri_path = apr_pstrcat(r->pool, "/", url, NULL);
            }
            else if (!strcasecmp(pathinfo_type, "first-dot")) {
                char *split = ap_strchr(path, '.');
                if (split) {
                    char *slash = ap_strchr(split, '/');
                    if (slash) {
                        r->path_info = apr_pstrdup(r->pool, slash);
                        ap_unescape_url_keep2f(r->path_info, 0);
                        *slash = '\0'; /* truncate path */
                    }
                }
            }
            else if (!strcasecmp(pathinfo_type, "last-dot")) {
                char *split = ap_strrchr(path, '.');
                if (split) {
                    char *slash = ap_strchr(split, '/');
                    if (slash) {
                        r->path_info = apr_pstrdup(r->pool, slash);
                        ap_unescape_url_keep2f(r->path_info, 0);
                        *slash = '\0'; /* truncate path */
                    }
                }
            }
            else {
                /* before proxy-fcgi-pathinfo had multi-values. This requires the
                 * the FCGI server to fixup PATH_INFO because it's the entire path
                 */
                r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
                if (!strcasecmp(pathinfo_type, "unescape")) {
                    ap_unescape_url_keep2f(r->path_info, 0);
                }
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061)
                        "set r->path_info to %s", r->path_info);
            }
        }
    
        return OK;
    }
    
    
    /*
      ProxyFCGISetEnvIf "reqenv('PATH_INFO') =~ m#/foo(\d+)\.php$#" COVENV1 "$1"
      ProxyFCGISetEnvIf "reqenv('PATH_INFO') =~ m#/foo(\d+)\.php$#" PATH_INFO "/foo.php"
      ProxyFCGISetEnvIf "reqenv('PATH_TRANSLATED') =~ m#(/.*foo)(\d+)(.*)#" PATH_TRANSLATED "$1$3"
    */
    static apr_status_t fix_cgivars(request_rec *r, fcgi_dirconf_t *dconf)
    {
        sei_entry *entries;
        const char *err, *src;
        int i = 0, rc = 0;
        ap_regmatch_t regm[AP_MAX_REG_MATCH];
    
        entries = (sei_entry *) dconf->env_fixups->elts;
        for (i = 0; i < dconf->env_fixups->nelts; i++) {
            sei_entry *entry = &entries[i];
    
            rc = ap_expr_exec_re(r, entry->cond, AP_MAX_REG_MATCH, regm, &src, &err);
            if (rc < 0) { 
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10241) 
                              "fix_cgivars: Condition eval returned %d: %s", 
                              rc, err);
                return APR_EGENERAL;
            }
            else if (rc == 0) { 
                continue; /* evaluated false */
            }
    
            if (entry->envname[0] == '!') {
                apr_table_unset(r->subprocess_env, entry->envname+1);
            }
            else {
                const char *val = ap_expr_str_exec_re(r, entry->subst, AP_MAX_REG_MATCH, regm, &src, &err);
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03514)
                                  "Error evaluating expression for replacement of %s: '%s'",
                                   entry->envname, err);
                    continue;
                }
                if (APLOGrtrace4(r)) {
                    const char *oldval = apr_table_get(r->subprocess_env, entry->envname);
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                                  "fix_cgivars: override %s from '%s' to '%s'",
                                  entry->envname, oldval, val);
    
                }
                apr_table_setn(r->subprocess_env, entry->envname, val);
            }
        }
        return APR_SUCCESS;
    }
    
    /* Wrapper for apr_socket_sendv that handles updating the worker stats. */
    static apr_status_t send_data(proxy_conn_rec *conn,
                                  struct iovec *vec,
                                  int nvec,
                                  apr_size_t *len)
    {
        apr_status_t rv = APR_SUCCESS;
        apr_size_t written = 0, to_write = 0;
        int i, offset;
        apr_socket_t *s = conn->sock;
    
        for (i = 0; i < nvec; i++) {
            to_write += vec[i].iov_len;
        }
    
        offset = 0;
        while (to_write) {
            apr_size_t n = 0;
            rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
            if (rv != APR_SUCCESS) {
                break;
            }
            if (n > 0) {
                written += n;
                if (written >= to_write)
                    break;                 /* short circuit out */
                for (i = offset; i < nvec; ) {
                    if (n >= vec[i].iov_len) {
                        offset++;
                        n -= vec[i++].iov_len;
                    } else {
                        vec[i].iov_len -= n;
                        vec[i].iov_base = (char *) vec[i].iov_base + n;
                        break;
                    }
                }
            }
        }
    
        conn->worker->s->transferred += written;
        *len = written;
    
        return rv;
    }
    
    /* Wrapper for apr_socket_recv that handles updating the worker stats. */
    static apr_status_t get_data(proxy_conn_rec *conn,
                                 char *buffer,
                                 apr_size_t *buflen)
    {
        apr_status_t rv = apr_socket_recv(conn->sock, buffer, buflen);
    
        if (rv == APR_SUCCESS) {
            conn->worker->s->read += *buflen;
        }
    
        return rv;
    }
    
    static apr_status_t get_data_full(proxy_conn_rec *conn,
                                      char *buffer,
                                      apr_size_t buflen)
    {
        apr_size_t readlen;
        apr_size_t cumulative_len = 0;
        apr_status_t rv;
    
        do {
            readlen = buflen - cumulative_len;
            rv = get_data(conn, buffer + cumulative_len, &readlen);
            if (rv != APR_SUCCESS) {
                return rv;
            }
            cumulative_len += readlen;
        } while (cumulative_len < buflen);
    
        return APR_SUCCESS;
    }
    
    static apr_status_t send_begin_request(proxy_conn_rec *conn,
                                           apr_uint16_t request_id)
    {
        struct iovec vec[2];
        ap_fcgi_header header;
        unsigned char farray[AP_FCGI_HEADER_LEN];
        ap_fcgi_begin_request_body brb;
        unsigned char abrb[AP_FCGI_HEADER_LEN];
        apr_size_t len;
    
        ap_fcgi_fill_in_header(&header, AP_FCGI_BEGIN_REQUEST, request_id,
                               sizeof(abrb), 0);
    
        ap_fcgi_fill_in_request_body(&brb, AP_FCGI_RESPONDER,
                                     ap_proxy_connection_reusable(conn)
                                         ? AP_FCGI_KEEP_CONN : 0);
    
        ap_fcgi_header_to_array(&header, farray);
        ap_fcgi_begin_request_body_to_array(&brb, abrb);
    
        vec[0].iov_base = (void *)farray;
        vec[0].iov_len = sizeof(farray);
        vec[1].iov_base = (void *)abrb;
        vec[1].iov_len = sizeof(abrb);
    
        return send_data(conn, vec, 2, &len);
    }
    
    static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
                                         apr_pool_t *temp_pool,
                                         apr_uint16_t request_id)
    {
        const apr_array_header_t *envarr;
        const apr_table_entry_t *elts;
        struct iovec vec[2];
        ap_fcgi_header header;
        unsigned char farray[AP_FCGI_HEADER_LEN];
        char *body;
        apr_status_t rv;
        apr_size_t avail_len, len, required_len;
        int next_elem, starting_elem;
        fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
        fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config, &proxy_fcgi_module);
        char *proxy_filename = r->filename;
    
        /* Resolve SCRIPT_NAME/FILENAME from the filesystem? */
        if (rconf && rconf->dirwalk_uri_path) {
            char *saved_uri = r->uri;
            char *saved_path_info = r->path_info;
            char *saved_canonical_filename = r->canonical_filename;
            int saved_filetype = r->finfo.filetype;
            int i = 0;
    
            r->proxyreq = PROXYREQ_NONE;
            do {
                r->path_info = NULL;
                r->finfo.filetype = APR_NOFILE;
                r->uri = r->filename = r->canonical_filename = rconf->dirwalk_uri_path;
                /* Try without than with DocumentRoot prefix */
                if (i && ap_core_translate(r) != OK) {
                    continue;
                }
                ap_directory_walk(r);
            } while (r->finfo.filetype != APR_REG && ++i < 2);
            r->proxyreq = PROXYREQ_REVERSE;
    
            /* If no actual script was found, fall back to the "proxy:"
             * SCRIPT_FILENAME dealt with below or by FPM directly.
             */
            if (r->finfo.filetype != APR_REG) {
                r->filename = proxy_filename;
                r->canonical_filename = saved_canonical_filename;
                r->finfo.filetype = saved_filetype;
                r->path_info = saved_path_info;
            }
    
            /* Restore REQUEST_URI in any case */
            r->uri = saved_uri;
        }
    
        /* Strip "proxy:" prefixes? */
        if (r->filename == proxy_filename) {
            char *newfname = NULL;
    
            if (!strncmp(r->filename, "proxy:balancer://", 17)) {
                newfname = apr_pstrdup(r->pool, r->filename+17);
            }
    
            if (!FCGI_MAY_BE_FPM(dconf))  {
                if (!strncmp(r->filename, "proxy:fcgi://", 13)) {
                    /* If we strip this under FPM, and any internal redirect occurs
                     * on PATH_INFO, FPM may use PATH_TRANSLATED instead of
                     * SCRIPT_FILENAME (a la mod_fastcgi + Action).
                     */
                    newfname = apr_pstrdup(r->pool, r->filename+13);
                }
    
                /* Strip potential query string (nocanon) from SCRIPT_FILENAME
                 * if it's the same as QUERY_STRING.
                 */
                if (newfname && r->args && *r->args) {
                    char *qs = strchr(newfname, '?');
                    if (qs && !strcmp(qs+1, r->args)) {
                        *qs = '\0';
                    }
                }
            }
    
            if (newfname) {
                r->filename = ap_strchr(newfname, '/');
            }
        }
    
        ap_add_common_vars(r);
        ap_add_cgi_vars(r);
    
        /* SCRIPT_NAME/FILENAME set, restore original */
        r->filename = proxy_filename;
    
        /* XXX are there any FastCGI specific env vars we need to send? */
    
        /* Give admins final option to fine-tune env vars */
        if (APR_SUCCESS != (rv = fix_cgivars(r, dconf))) { 
            return rv;
        }
    
        /* XXX mod_cgi/mod_cgid use ap_create_environment here, which fills in
         *     the TZ value specially.  We could use that, but it would mean
         *     parsing the key/value pairs back OUT of the allocated env array,
         *     not to mention allocating a totally useless array in the first
         *     place, which would suck. */
    
        envarr = apr_table_elts(r->subprocess_env);
        elts = (const apr_table_entry_t *) envarr->elts;
    
        if (APLOGrtrace8(r)) {
            int i;
    
            for (i = 0; i < envarr->nelts; ++i) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, APLOGNO(01062)
                              "sending env var '%s' value '%s'",
                              elts[i].key, elts[i].val);
            }
        }
    
        /* Send envvars over in as many FastCGI records as it takes, */
        next_elem = 0; /* starting with the first one */
    
        avail_len = 16 * 1024; /* our limit per record, which could have been up
                                * to AP_FCGI_MAX_CONTENT_LEN
                                */
    
        while (next_elem < envarr->nelts) {
            starting_elem = next_elem;
            required_len = ap_fcgi_encoded_env_len(r->subprocess_env,
                                                   avail_len,
                                                   &next_elem);
    
            if (!required_len) {
                if (next_elem < envarr->nelts) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                                  APLOGNO(02536) "couldn't encode envvar '%s' in %"
                                  APR_SIZE_T_FMT " bytes",
                                  elts[next_elem].key, avail_len);
                    /* skip this envvar and continue */
                    ++next_elem;
                    continue;
                }
                /* only an unused element at the end of the array */
                break;
            }
    
            body = apr_palloc(temp_pool, required_len);
            rv = ap_fcgi_encode_env(r, r->subprocess_env, body, required_len,
                                    &starting_elem);
            /* we pre-compute, so we can't run out of space */
            ap_assert(rv == APR_SUCCESS);
            /* compute and encode must be in sync */
            ap_assert(starting_elem == next_elem);
    
            ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id,
                                   (apr_uint16_t)required_len, 0);
            ap_fcgi_header_to_array(&header, farray);
    
            vec[0].iov_base = (void *)farray;
            vec[0].iov_len = sizeof(farray);
            vec[1].iov_base = body;
            vec[1].iov_len = required_len;
    
            rv = send_data(conn, vec, 2, &len);
            apr_pool_clear(temp_pool);
    
            if (rv) {
                return rv;
            }
        }
    
        /* Envvars sent, so say we're done */
        ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id, 0, 0);
        ap_fcgi_header_to_array(&header, farray);
    
        vec[0].iov_base = (void *)farray;
        vec[0].iov_len = sizeof(farray);
    
        return send_data(conn, vec, 1, &len);
    }
    
    enum {
      HDR_STATE_READING_HEADERS,
      HDR_STATE_GOT_CR,
      HDR_STATE_GOT_CRLF,
      HDR_STATE_GOT_CRLFCR,
      HDR_STATE_GOT_LF,
      HDR_STATE_DONE_WITH_HEADERS
    };
    
    /* Try to find the end of the script headers in the response from the back
     * end fastcgi server. STATE holds the current header parsing state for this
     * request.
     *
     * Returns 0 if it can't find the end of the headers, and 1 if it found the
     * end of the headers. */
    static int handle_headers(request_rec *r, int *state,
                              const char *readbuf, apr_size_t readlen)
    {
        const char *itr = readbuf;
    
        while (readlen--) {
            if (*itr == '\r') {
                switch (*state) {
                    case HDR_STATE_GOT_CRLF:
                        *state = HDR_STATE_GOT_CRLFCR;
                        break;
    
                    default:
                        *state = HDR_STATE_GOT_CR;
                        break;
                }
            }
            else if (*itr == '\n') {
                switch (*state) {
                     case HDR_STATE_GOT_LF:
                         *state = HDR_STATE_DONE_WITH_HEADERS;
                         break;
    
                     case HDR_STATE_GOT_CR:
                         *state = HDR_STATE_GOT_CRLF;
                         break;
    
                     case HDR_STATE_GOT_CRLFCR:
                         *state = HDR_STATE_DONE_WITH_HEADERS;
                         break;
    
                     default:
                         *state = HDR_STATE_GOT_LF;
                         break;
                }
            }
            else {
                *state = HDR_STATE_READING_HEADERS;
            }
    
            if (*state == HDR_STATE_DONE_WITH_HEADERS)
                break;
    
            ++itr;
        }
    
        if (*state == HDR_STATE_DONE_WITH_HEADERS) {
            return 1;
        }
    
        return 0;
    }
    
    static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,
                                 request_rec *r, apr_pool_t *setaside_pool,
                                 apr_uint16_t request_id, const char **err,
                                 int *bad_request, int *has_responded,
                                 apr_bucket_brigade *input_brigade)
    {
        apr_bucket_brigade *ib, *ob;
        int seen_end_of_headers = 0, done = 0, ignore_body = 0;
        apr_status_t rv = APR_SUCCESS;
        int script_error_status = HTTP_OK;
        conn_rec *c = r->connection;
        struct iovec vec[2];
        ap_fcgi_header header;
        unsigned char farray[AP_FCGI_HEADER_LEN];
        apr_pollfd_t pfd;
        apr_pollfd_t *flushpoll = NULL;
        apr_int32_t flushpoll_fd;
        int header_state = HDR_STATE_READING_HEADERS;
        char stack_iobuf[AP_IOBUFSIZE];
        apr_size_t iobuf_size = AP_IOBUFSIZE;
        char *iobuf = stack_iobuf;
    
        *err = NULL;
        if (conn->worker->s->io_buffer_size_set) {
            iobuf_size = conn->worker->s->io_buffer_size;
            iobuf = apr_palloc(r->pool, iobuf_size);
        }
    
        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = conn->sock;
        pfd.p = r->pool;
        pfd.reqevents = APR_POLLIN | APR_POLLOUT;
    
        if (conn->worker->s->flush_packets == flush_auto) {
            flushpoll = apr_pcalloc(r->pool, sizeof(apr_pollfd_t));
            flushpoll->reqevents = APR_POLLIN;
            flushpoll->desc_type = APR_POLL_SOCKET;
            flushpoll->desc.s = conn->sock;
        }
    
        ib = apr_brigade_create(r->pool, c->bucket_alloc);
        ob = apr_brigade_create(r->pool, c->bucket_alloc);
    
        while (! done) {
            apr_interval_time_t timeout;
            apr_size_t len;
            int n;
    
            /* We need SOME kind of timeout here, or virtually anything will
             * cause timeout errors. */
            apr_socket_timeout_get(conn->sock, &timeout);
    
            rv = apr_poll(&pfd, 1, &n, timeout);
            if (rv != APR_SUCCESS) {
                if (APR_STATUS_IS_EINTR(rv)) {
                    continue;
                }
                *err = "polling";
                break;
            }
    
            if (pfd.rtnevents & APR_POLLOUT) {
                apr_size_t to_send, writebuflen;
                int last_stdin = 0;
                char *iobuf_cursor;
    
                if (APR_BRIGADE_EMPTY(input_brigade)) {
                    rv = ap_get_brigade(r->input_filters, ib,
                                        AP_MODE_READBYTES, APR_BLOCK_READ,
                                        iobuf_size);
                }
                else {
                    apr_bucket *e;
                    APR_BRIGADE_CONCAT(ib, input_brigade);
                    rv = apr_brigade_partition(ib, iobuf_size, &e);
                    if (rv == APR_SUCCESS) {
                        while (e != APR_BRIGADE_SENTINEL(ib)
                               && APR_BUCKET_IS_METADATA(e)) {
                            e = APR_BUCKET_NEXT(e);
                        }
                        apr_brigade_split_ex(ib, e, input_brigade);
                    }
                    else if (rv == APR_INCOMPLETE) {
                        rv = APR_SUCCESS;
                    }
                }
                if (rv != APR_SUCCESS) {
                    *err = "reading input brigade";
                    *bad_request = 1;
                    break;
                }
    
                if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(ib))) {
                    last_stdin = 1;
                }
    
                writebuflen = iobuf_size;
    
                rv = apr_brigade_flatten(ib, iobuf, &writebuflen);
    
                apr_brigade_cleanup(ib);
    
                if (rv != APR_SUCCESS) {
                    *err = "flattening brigade";
                    break;
                }
    
                to_send = writebuflen;
                iobuf_cursor = iobuf;
                while (to_send > 0) {
                    int nvec = 0;
                    apr_size_t write_this_time;
    
                    write_this_time =
                        to_send < AP_FCGI_MAX_CONTENT_LEN ? to_send : AP_FCGI_MAX_CONTENT_LEN;
    
                    ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id,
                                           (apr_uint16_t)write_this_time, 0);
                    ap_fcgi_header_to_array(&header, farray);
    
                    vec[nvec].iov_base = (void *)farray;
                    vec[nvec].iov_len = sizeof(farray);
                    ++nvec;
                    if (writebuflen) {
                        vec[nvec].iov_base = iobuf_cursor;
                        vec[nvec].iov_len = write_this_time;
                        ++nvec;
                    }
    
                    rv = send_data(conn, vec, nvec, &len);
                    if (rv != APR_SUCCESS) {
                        *err = "sending stdin";
                        break;
                    }
    
                    to_send -= write_this_time;
                    iobuf_cursor += write_this_time;
                }
                if (rv != APR_SUCCESS) {
                    break;
                }
    
                if (last_stdin) {
                    pfd.reqevents = APR_POLLIN; /* Done with input data */
    
                    /* signal EOF (empty FCGI_STDIN) */
                    ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id,
                                           0, 0);
                    ap_fcgi_header_to_array(&header, farray);
    
                    vec[0].iov_base = (void *)farray;
                    vec[0].iov_len = sizeof(farray);
    
                    rv = send_data(conn, vec, 1, &len);
                    if (rv != APR_SUCCESS) {
                        *err = "sending empty stdin";
                        break;
                    }
                }
            }
    
            if (pfd.rtnevents & APR_POLLIN) {
                apr_size_t readbuflen;
                apr_uint16_t clen, rid;
                apr_bucket *b;
                unsigned char plen;
                unsigned char type, version;
                int mayflush = 0;
    
                /* First, we grab the header... */
                rv = get_data_full(conn, (char *) farray, AP_FCGI_HEADER_LEN);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01067)
                                  "Failed to read FastCGI header");
                    break;
                }
    
                ap_log_rdata(APLOG_MARK, APLOG_TRACE8, r, "FastCGI header",
                             farray, AP_FCGI_HEADER_LEN, 0);
    
                ap_fcgi_header_fields_from_array(&version, &type, &rid,
                                                 &clen, &plen, farray);
    
                if (version != AP_FCGI_VERSION_1) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01068)
                                  "Got bogus version %d", (int)version);
                    rv = APR_EINVAL;
                    break;
                }
    
                if (rid != request_id) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01069)
                                  "Got bogus rid %d, expected %d",
                                  rid, request_id);
                    rv = APR_EINVAL;
                    break;
                }
    
    recv_again:
                if (clen > iobuf_size) {
                    readbuflen = iobuf_size;
                } else {
                    readbuflen = clen;
                }
    
                /* Now get the actual data.  Yes it sucks to do this in a second
                 * recv call, this will eventually change when we move to real
                 * nonblocking recv calls. */
                if (readbuflen != 0) {
                    rv = get_data(conn, iobuf, &readbuflen);
                    if (rv != APR_SUCCESS) {
                        *err = "reading response body";
                        break;
                    }
                }
    
                switch (type) {
                case AP_FCGI_STDOUT:
                    if (clen != 0) {
                        b = apr_bucket_transient_create(iobuf,
                                                        readbuflen,
                                                        c->bucket_alloc);
    
                        APR_BRIGADE_INSERT_TAIL(ob, b);
    
                        if (! seen_end_of_headers) {
                            int st = handle_headers(r, &header_state,
                                                    iobuf, readbuflen);
    
                            if (st == 1) {
                                int status;
                                seen_end_of_headers = 1;
    
                                status = ap_scan_script_header_err_brigade_ex(r, ob,
                                    NULL, APLOG_MODULE_INDEX);
    
                                /* FCGI has its own body framing mechanism which we don't
                                 * match against any provided Content-Length, so let the
                                 * core determine C-L vs T-E based on what's actually sent.
                                 */
                                if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
                                    apr_table_unset(r->headers_out, "Content-Length");
                                apr_table_unset(r->headers_out, "Transfer-Encoding");
    
                                /* suck in all the rest */
                                if (status != OK) {
                                    apr_bucket *tmp_b;
                                    apr_brigade_cleanup(ob);
                                    tmp_b = apr_bucket_eos_create(c->bucket_alloc);
                                    APR_BRIGADE_INSERT_TAIL(ob, tmp_b);
    
                                    *has_responded = 1;
                                    r->status = status;
                                    rv = ap_pass_brigade(r->output_filters, ob);
                                    if (rv != APR_SUCCESS) {
                                        *err = "passing headers brigade to output filters";
                                        break;
                                    }
                                    else if (status == HTTP_NOT_MODIFIED
                                             || status == HTTP_PRECONDITION_FAILED) {
                                        /* Special 'status' cases handled:
                                         * 1) HTTP 304 response MUST NOT contain
                                         *    a message-body, ignore it.
                                         * 2) HTTP 412 response.
                                         * The break is not added since there might
                                         * be more bytes to read from the FCGI
                                         * connection. Even if the message-body is
                                         * ignored (and the EOS bucket has already
                                         * been sent) we want to avoid subsequent
                                         * bogus reads. */
                                        ignore_body = 1;
                                    }
                                    else {
                                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070)
                                                        "Error parsing script headers");
                                        rv = APR_EINVAL;
                                        break;
                                    }
                                }
    
                                if (ap_proxy_should_override(conf, r->status) && ap_is_initial_req(r)) {
                                    /*
                                     * set script_error_status to discard
                                     * everything after the headers
                                     */
                                    script_error_status = r->status;
                                    /*
                                     * prevent ap_die() from treating this as a
                                     * recursive error, initially:
                                     */
                                    r->status = HTTP_OK;
                                }
    
                                if (script_error_status == HTTP_OK
                                    && !APR_BRIGADE_EMPTY(ob) && !ignore_body) {
                                    /* Send the part of the body that we read while
                                     * reading the headers.
                                     */
                                    *has_responded = 1;
                                    rv = ap_pass_brigade(r->output_filters, ob);
                                    if (rv != APR_SUCCESS) {
                                        *err = "passing brigade to output filters";
                                        break;
                                    }
                                    mayflush = 1;
                                }
                                apr_brigade_cleanup(ob);
    
                                apr_pool_clear(setaside_pool);
                            }
                            else {
                                /* We're still looking for the end of the
                                 * headers, so this part of the data will need
                                 * to persist. */
                                apr_bucket_setaside(b, setaside_pool);
                            }
                        } else {
                            /* we've already passed along the headers, so now pass
                             * through the content.  we could simply continue to
                             * setaside the content and not pass until we see the
                             * 0 content-length (below, where we append the EOS),
                             * but that could be a huge amount of data; so we pass
                             * along smaller chunks
                             */
                            if (script_error_status == HTTP_OK && !ignore_body) {
                                *has_responded = 1;
                                rv = ap_pass_brigade(r->output_filters, ob);
                                if (rv != APR_SUCCESS) {
                                    *err = "passing brigade to output filters";
                                    break;
                                }
                                mayflush = 1;
                            }
                            apr_brigade_cleanup(ob);
                        }
    
                        /* If we didn't read all the data, go back and get the
                         * rest of it. */
                        if (clen > readbuflen) {
                            clen -= readbuflen;
                            goto recv_again;
                        }
                    } else {
                        /* XXX what if we haven't seen end of the headers yet? */
    
                        if (script_error_status == HTTP_OK) {
                            b = apr_bucket_eos_create(c->bucket_alloc);
                            APR_BRIGADE_INSERT_TAIL(ob, b);
    
                            *has_responded = 1;
                            rv = ap_pass_brigade(r->output_filters, ob);
                            if (rv != APR_SUCCESS) {
                                *err = "passing brigade to output filters";
                                break;
                            }
                        }
    
                        /* XXX Why don't we cleanup here?  (logic from AJP) */
                    }
                    break;
    
                case AP_FCGI_STDERR:
                    /* TODO: Should probably clean up this logging a bit... */
                    if (clen) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01071)
                                      "Got error '%.*s'", (int)readbuflen, iobuf);
                    }
    
                    if (clen > readbuflen) {
                        clen -= readbuflen;
                        goto recv_again;
                    }
                    break;
    
                case AP_FCGI_END_REQUEST:
                    done = 1;
                    break;
    
                default:
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01072)
                                  "Got bogus record %d", type);
                    break;
                }
                /* Leave on above switch's inner error. */
                if (rv != APR_SUCCESS) {
                    break;
                }
    
                if (plen) {
                    rv = get_data_full(conn, iobuf, plen);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02537)
                                      "Error occurred reading padding");
                        break;
                    }
                }
    
                if (mayflush && ((conn->worker->s->flush_packets == flush_on) ||
                                 ((conn->worker->s->flush_packets == flush_auto) && 
                                  (apr_poll(flushpoll, 1, &flushpoll_fd,
                                   conn->worker->s->flush_wait) == APR_TIMEUP)))) {
                    apr_bucket* flush_b = apr_bucket_flush_create(r->connection->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(ob, flush_b);
                    rv = ap_pass_brigade(r->output_filters, ob);
                    if (rv != APR_SUCCESS) {
                        *err = "passing headers brigade to output filters";
                        break;
                    }
                    mayflush = 0;
                }
            }
        }
    
        apr_brigade_destroy(ib);
        apr_brigade_destroy(ob);
    
        if (script_error_status != HTTP_OK) {
            ap_die(script_error_status, r); /* send ErrorDocument */
            *has_responded = 1;
        }
    
        return rv;
    }
    
    /*
     * process the request and write the response.
     */
    static int fcgi_do_request(apr_pool_t *p, request_rec *r,
                               proxy_conn_rec *conn,
                               conn_rec *origin,
                               proxy_dir_conf *conf,
                               apr_uri_t *uri,
                               char *url, char *server_portstr,
                               apr_bucket_brigade *input_brigade)
    {
        /* Request IDs are arbitrary numbers that we assign to a
         * single request. This would allow multiplex/pipelining of
         * multiple requests to the same FastCGI connection, but
         * we don't support that, and always use a value of '1' to
         * keep things simple. */
        apr_uint16_t request_id = 1;
        apr_status_t rv;
        apr_pool_t *temp_pool;
        const char *err;
        int bad_request = 0,
            has_responded = 0;
    
        /* Step 1: Send AP_FCGI_BEGIN_REQUEST */
        rv = send_begin_request(conn, request_id);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01073)
                          "Failed Writing Request to %s:", server_portstr);
            conn->close = 1;
            return HTTP_SERVICE_UNAVAILABLE;
        }
    
        apr_pool_create(&temp_pool, r->pool);
        apr_pool_tag(temp_pool, "proxy_fcgi_do_request");
    
        /* Step 2: Send Environment via FCGI_PARAMS */
        rv = send_environment(conn, r, temp_pool, request_id);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01074)
                          "Failed writing Environment to %s:", server_portstr);
            conn->close = 1;
            return HTTP_SERVICE_UNAVAILABLE;
        }
    
        /* Step 3: Read records from the back end server and handle them. */
        rv = dispatch(conn, conf, r, temp_pool, request_id,
                      &err, &bad_request, &has_responded,
                      input_brigade);
        if (rv != APR_SUCCESS) {
            /* If the client aborted the connection during retrieval or (partially)
             * sending the response, don't return a HTTP_SERVICE_UNAVAILABLE, since
             * this is not a backend problem. */
            if (r->connection->aborted) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r,
                              "The client aborted the connection.");
                conn->close = 1;
                return OK;
            }
    
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01075)
                          "Error dispatching request to %s: %s%s%s",
                          server_portstr,
                          err ? "(" : "",
                          err ? err : "",
                          err ? ")" : "");
            conn->close = 1;
            if (has_responded) {
                return AP_FILTER_ERROR;
            }
            if (bad_request) {
                return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
            }
            if (APR_STATUS_IS_TIMEUP(rv)) {
                return HTTP_GATEWAY_TIME_OUT;
            }
            return HTTP_SERVICE_UNAVAILABLE;
        }
    
        return OK;
    }
    
    #define FCGI_SCHEME "FCGI"
    
    #define MAX_MEM_SPOOL 16384
    
    /*
     * This handles fcgi:(dest) URLs
     */
    static int proxy_fcgi_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;
        apr_bucket_brigade *input_brigade;
        apr_off_t input_bytes = 0;
        apr_uri_t *uri;
    
        proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                     &proxy_module);
    
        apr_pool_t *p = r->pool;
    
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01076)
                      "url: %s proxyname: %s proxyport: %d",
                      url, proxyname, proxyport);
    
        if (ap_cstr_casecmpn(url, "fcgi:", 5) != 0) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01077) "declining URL %s", url);
            return DECLINED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01078) "serving URL %s", url);
    
        /* Create space for state information */
        status = ap_proxy_acquire_connection(FCGI_SCHEME, &backend, worker,
                                             r->server);
        if (status != OK) {
            if (backend) {
                backend->close = 1;
                ap_proxy_release_connection(FCGI_SCHEME, backend, r->server);
            }
            return status;
        }
    
        backend->is_ssl = 0;
    
        /* Step One: Determine Who To Connect To */
        uri = apr_palloc(p, sizeof(*uri));
        status = ap_proxy_determine_connection(p, r, conf, worker, backend,
                                               uri, &url, proxyname, proxyport,
                                               server_portstr,
                                               sizeof(server_portstr));
        if (status != OK) {
            goto cleanup;
        }
    
        /* We possibly reuse input data prefetched in previous call(s), e.g. for a
         * balancer fallback scenario.
         */
        apr_pool_userdata_get((void **)&input_brigade, "proxy-fcgi-input", p);
        if (input_brigade == NULL) {
            const char *old_te = apr_table_get(r->headers_in, "Transfer-Encoding");
            const char *old_cl = NULL;
            if (old_te) {
                apr_table_unset(r->headers_in, "Content-Length");
            }
            else {
                old_cl = apr_table_get(r->headers_in, "Content-Length");
            }
    
            input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
            apr_pool_userdata_setn(input_brigade, "proxy-fcgi-input", NULL, p);
    
            /* Prefetch (nonlocking) the request body so to increase the chance
             * to get the whole (or enough) body and determine Content-Length vs
             * chunked or spooled. By doing this before connecting or reusing the
             * backend, we want to minimize the delay between this connection is
             * considered alive and the first bytes sent (should the client's link
             * be slow or some input filter retain the data). This is a best effort
             * to prevent the backend from closing (from under us) what it thinks is
             * an idle connection, hence to reduce to the minimum the unavoidable
             * local is_socket_connected() vs remote keepalive race condition.
             */
            status = ap_proxy_prefetch_input(r, backend, input_brigade,
                                             APR_NONBLOCK_READ, &input_bytes,
                                             MAX_MEM_SPOOL);
            if (status != OK) {
                goto cleanup;
            }
    
            /*
             * The request body is streamed by default, using either C-L or
             * chunked T-E, like this:
             *
             *   The whole body (including no body) was received on prefetch, i.e.
             *   the input brigade ends with EOS => C-L = input_bytes.
             *
             *   C-L is known and reliable, i.e. only protocol filters in the input
             *   chain thus none should change the body => use C-L from client.
             *
             *   The administrator has not "proxy-sendcl" which prevents T-E => use
             *   T-E and chunks.
             *
             *   Otherwise we need to determine and set a content-length, so spool
             *   the entire request body to memory/temporary file (MAX_MEM_SPOOL),
             *   such that we finally know its length => C-L = input_bytes.
             */
            if (!APR_BRIGADE_EMPTY(input_brigade)
                    && APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
                /* The whole thing fit, so our decision is trivial, use the input
                 * bytes for the Content-Length. If we expected no body, and read
                 * no body, do not set the Content-Length.
                 */
                if (old_cl || old_te || input_bytes) {
                    apr_table_setn(r->headers_in, "Content-Length",
                                   apr_off_t_toa(p, input_bytes));
                    if (old_te) {
                        apr_table_unset(r->headers_in, "Transfer-Encoding");
                    }
                }
            }
            else if (old_cl && r->input_filters == r->proto_input_filters) {
                /* Streaming is possible by preserving the existing C-L */
            }
            else if (!apr_table_get(r->subprocess_env, "proxy-sendcl")) {
                /* Streaming is possible using T-E: chunked */
            }
            else {
                /* No streaming, C-L is the only option so spool to memory/file */
                apr_bucket_brigade *tmp_bb;
                apr_off_t remaining_bytes = 0;
    
                AP_DEBUG_ASSERT(MAX_MEM_SPOOL >= input_bytes);
                tmp_bb = apr_brigade_create(p, r->connection->bucket_alloc);
                status = ap_proxy_spool_input(r, backend, tmp_bb, &remaining_bytes,
                                              MAX_MEM_SPOOL - input_bytes);
                if (status != OK) {
                    goto cleanup;
                }
    
                APR_BRIGADE_CONCAT(input_brigade, tmp_bb);
                input_bytes += remaining_bytes;
    
                apr_table_setn(r->headers_in, "Content-Length",
                               apr_off_t_toa(p, input_bytes));
                if (old_te) {
                    apr_table_unset(r->headers_in, "Transfer-Encoding");
                }
            }
        }
    
        /* This scheme handler does not reuse connections by default, to
         * avoid tying up a fastcgi that isn't expecting to work on
         * parallel requests.  But if the user went out of their way to
         * type the default value of disablereuse=off, we'll allow it.
         */
        backend->close = 1;
        if (worker->s->disablereuse_set && !worker->s->disablereuse) {
            backend->close = 0;
        }
    
        /* Step Two: Make the Connection */
        if (ap_proxy_check_connection(FCGI_SCHEME, backend, r->server, 0,
                                      PROXY_CHECK_CONN_EMPTY)
                && ap_proxy_connect_backend(FCGI_SCHEME, backend, worker,
                                            r->server)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01079)
                          "failed to make connection to backend: %s",
                          backend->hostname);
            status = HTTP_SERVICE_UNAVAILABLE;
            goto cleanup;
        }
    
        /* Step Three: Process the Request */
        status = fcgi_do_request(p, r, backend, origin, dconf, uri, url,
                                 server_portstr, input_brigade);
    
    cleanup:
        ap_proxy_release_connection(FCGI_SCHEME, backend, r->server);
        return status;
    }
    
    static void *fcgi_create_dconf(apr_pool_t *p, char *path)
    {
        fcgi_dirconf_t *a;
    
        a = (fcgi_dirconf_t *)apr_pcalloc(p, sizeof(fcgi_dirconf_t));
        a->backend_type = BACKEND_DEFAULT_UNKNOWN;
        a->env_fixups = apr_array_make(p, 20, sizeof(sei_entry));
    
        return a;
    }
    
    static void *fcgi_merge_dconf(apr_pool_t *p, void *basev, void *overridesv)
    {
        fcgi_dirconf_t *a, *base, *over;
    
        a     = (fcgi_dirconf_t *)apr_pcalloc(p, sizeof(fcgi_dirconf_t));
        base  = (fcgi_dirconf_t *)basev;
        over  = (fcgi_dirconf_t *)overridesv;
    
        a->backend_type = (over->backend_type != BACKEND_DEFAULT_UNKNOWN)
                          ? over->backend_type
                          : base->backend_type;
        a->env_fixups = apr_array_append(p, base->env_fixups, over->env_fixups);
        return a;
    }
    
    static const char *cmd_servertype(cmd_parms *cmd, void *in_dconf,
                                       const char *val)
    {
        fcgi_dirconf_t *dconf = in_dconf;
    
        if (!strcasecmp(val, "GENERIC")) {
           dconf->backend_type = BACKEND_GENERIC;
        }
        else if (!strcasecmp(val, "FPM")) {
           dconf->backend_type = BACKEND_FPM;
        }
        else {
            return "ProxyFCGIBackendType requires one of the following arguments: "
                   "'GENERIC', 'FPM'";
        }
    
        return NULL;
    }
    
    
    static const char *cmd_setenv(cmd_parms *cmd, void *in_dconf,
                                  const char *arg1, const char *arg2,
                                  const char *arg3)
    {
        fcgi_dirconf_t *dconf = in_dconf;
        const char *err;
        sei_entry *new;
        const char *envvar = arg2;
    
        new = apr_array_push(dconf->env_fixups);
        new->cond = ap_expr_parse_cmd(cmd, arg1, 0, &err, NULL);
        if (err) {
            return apr_psprintf(cmd->pool, "Could not parse expression \"%s\": %s",
                                arg1, err);
        }
    
        if (envvar[0] == '!') {
            /* Unset mode. */
            if (arg3) {
                return apr_psprintf(cmd->pool, "Third argument (\"%s\") is not "
                                    "allowed when using ProxyFCGISetEnvIf's unset "
                                    "mode (%s)", arg3, envvar);
            }
            else if (!envvar[1]) {
                /* i.e. someone tried to give us a name of just "!" */
                return "ProxyFCGISetEnvIf: \"!\" is not a valid variable name";
            }
    
            new->subst = NULL;
        }
        else {
            /* Set mode. */
            if (!arg3) {
                /* A missing expr-value should be treated as empty. */
                arg3 = "";
            }
    
            new->subst = ap_expr_parse_cmd(cmd, arg3, AP_EXPR_FLAG_STRING_RESULT, &err, NULL);
            if (err) {
                return apr_psprintf(cmd->pool, "Could not parse expression \"%s\": %s",
                                    arg3, err);
            }
        }
    
        new->envname = envvar;
    
        return NULL;
    }
    static void register_hooks(apr_pool_t *p)
    {
        proxy_hook_scheme_handler(proxy_fcgi_handler, NULL, NULL, APR_HOOK_FIRST);
        proxy_hook_canon_handler(proxy_fcgi_canon, NULL, NULL, APR_HOOK_FIRST);
    }
    
    static const command_rec command_table[] = {
        AP_INIT_TAKE1("ProxyFCGIBackendType", cmd_servertype, NULL, OR_FILEINFO,
                      "Specify the type of FastCGI server: 'Generic', 'FPM'"),
        AP_INIT_TAKE23("ProxyFCGISetEnvIf", cmd_setenv, NULL, OR_FILEINFO,
                      "expr-condition env-name expr-value"),
        { NULL }
    };
    
    AP_DECLARE_MODULE(proxy_fcgi) = {
        STANDARD20_MODULE_STUFF,
        fcgi_create_dconf,          /* create per-directory config structure */
        fcgi_merge_dconf,           /* merge per-directory config structures */
        NULL,                       /* create per-server config structure */
        NULL,                       /* merge per-server config structures */
        command_table,              /* command apr_table_t */
        register_hooks              /* register hooks */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_balancer.mak���������������������������������������������������0000664�0001751�0001751�00000026415�12701473373�022033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_balancer.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_balancer - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_balancer - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_balancer - Win32 Release" && "$(CFG)" != "mod_proxy_balancer - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_balancer.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_balancer.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_balancer.obj"
    	-@erase "$(INTDIR)\mod_proxy_balancer.res"
    	-@erase "$(INTDIR)\mod_proxy_balancer_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_balancer_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.exp"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.lib"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_balancer_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_balancer.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_balancer.so" /d LONG_NAME="proxy_balancer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_balancer.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_balancer.pdb" /debug /out:"$(OUTDIR)\mod_proxy_balancer.so" /implib:"$(OUTDIR)\mod_proxy_balancer.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_balancer.obj" \
    	"$(INTDIR)\mod_proxy_balancer.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_balancer.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_balancer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_balancer.so"
       if exist .\Release\mod_proxy_balancer.so.manifest mt.exe -manifest .\Release\mod_proxy_balancer.so.manifest -outputresource:.\Release\mod_proxy_balancer.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_balancer.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_balancer.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_balancer.obj"
    	-@erase "$(INTDIR)\mod_proxy_balancer.res"
    	-@erase "$(INTDIR)\mod_proxy_balancer_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_balancer_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.exp"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.lib"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_balancer.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_balancer_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_balancer.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_balancer.so" /d LONG_NAME="proxy_balancer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_balancer.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_balancer.pdb" /debug /out:"$(OUTDIR)\mod_proxy_balancer.so" /implib:"$(OUTDIR)\mod_proxy_balancer.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_balancer.obj" \
    	"$(INTDIR)\mod_proxy_balancer.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_balancer.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_balancer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_balancer.so"
       if exist .\Debug\mod_proxy_balancer.so.manifest mt.exe -manifest .\Debug\mod_proxy_balancer.so.manifest -outputresource:.\Debug\mod_proxy_balancer.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_balancer.dep")
    !INCLUDE "mod_proxy_balancer.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_balancer.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_balancer - Win32 Release" || "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
    SOURCE=.\mod_proxy_balancer.c
    
    "$(INTDIR)\mod_proxy_balancer.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_balancer.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_balancer.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_balancer.so" /d LONG_NAME="proxy_balancer_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_balancer.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_balancer.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_balancer.so" /d LONG_NAME="proxy_balancer_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_express.dep����������������������������������������������������0000664�0001751�0001751�00000005240�12674411515�021745� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_express.mak
    
    .\mod_proxy_express.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxyhtp������������������������������������������������������������0000664�0001751�0001751�00000010563�11546111464�020122� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.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_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_balancer.dsp���������������������������������������������������0000664�0001751�0001751�00000011651�10551346420�022036� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 0x409 /fo"Release/mod_proxy_balancer.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_balancer.so" /d LONG_NAME="proxy_balancer_module for Apache"
    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 /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 /out:".\Release\mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_balancer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 0x409 /fo"Debug/mod_proxy_balancer.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_balancer.so" /d LONG_NAME="proxy_balancer_module for Apache"
    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 /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 /out:".\Debug\mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_balancer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ajp.dep��������������������������������������������������������0000664�0001751�0001751�00000031324�12674411515�021030� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_ajp.mak
    
    .\mod_proxy_ajp.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ajp.h"\
    	".\mod_proxy.h"\
    	
    
    .\ajp_header.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ajp.h"\
    	".\ajp_header.h"\
    	".\mod_proxy.h"\
    	
    
    .\ajp_link.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ajp.h"\
    	".\mod_proxy.h"\
    	
    
    .\ajp_msg.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ajp.h"\
    	".\mod_proxy.h"\
    	
    
    .\ajp_utils.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ajp.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_connect.dep����������������������������������������������������0000664�0001751�0001751�00000005164�12674411515�021712� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_connect.mak
    
    .\mod_proxy_connect.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/.indent.pro��������������������������������������������������������������0000664�0001751�0001751�00000001401�10150161574�017530� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_balancer.c�����������������������������������������������������0000664�0001751�0001751�00000252234�15017773553�021513� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 */
    
    #include "mod_proxy.h"
    #include "proxy_util.h"
    #include "scoreboard.h"
    #include "ap_mpm.h"
    #include "apr_version.h"
    #include "ap_hooks.h"
    #include "apr_date.h"
    #include "util_md5.h"
    #include "mod_watchdog.h"
    
    static const char *balancer_mutex_type = "proxy-balancer-shm";
    ap_slotmem_provider_t *storage = NULL;
    
    module AP_MODULE_DECLARE_DATA proxy_balancer_module;
    
    static APR_OPTIONAL_FN_TYPE(set_worker_hc_param) *set_worker_hc_param_f = NULL;
    
    static int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
            proxy_worker *worker, server_rec *s) = NULL;
    
    static APR_OPTIONAL_FN_TYPE(hc_show_exprs) *hc_show_exprs_f = NULL;
    static APR_OPTIONAL_FN_TYPE(hc_select_exprs) *hc_select_exprs_f = NULL;
    static APR_OPTIONAL_FN_TYPE(hc_valid_expr) *hc_valid_expr_f = NULL;
    
    
    /*
     * Register our mutex type before the config is read so we
     * can adjust the mutex settings using the Mutex directive.
     */
    static int balancer_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                   apr_pool_t *ptemp)
    {
    
        apr_status_t rv;
    
        rv = ap_mutex_register(pconf, balancer_mutex_type, NULL,
                                   APR_LOCK_DEFAULT, 0);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        set_worker_hc_param_f = APR_RETRIEVE_OPTIONAL_FN(set_worker_hc_param);
        hc_show_exprs_f = APR_RETRIEVE_OPTIONAL_FN(hc_show_exprs);
        hc_select_exprs_f = APR_RETRIEVE_OPTIONAL_FN(hc_select_exprs);
        hc_valid_expr_f = APR_RETRIEVE_OPTIONAL_FN(hc_valid_expr);
        return OK;
    }
    
    #if 0
    extern void proxy_update_members(proxy_balancer **balancer, request_rec *r,
                                     proxy_server_conf *conf);
    #endif
    
    static int proxy_balancer_canon(request_rec *r, char *url)
    {
        char *host;
        apr_port_t port = 0;
        const char *err;
    
        /* TODO: offset of BALANCER_PREFIX ?? */
        if (ap_cstr_casecmpn(url, "balancer:", 9) == 0) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "canonicalising URL %s", url);
            url += 9;
        }
        else {
            return DECLINED;
        }
    
        /* do syntatic check.
         * We break the URL into host, port, path
         */
        err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01157)
                          "error parsing URL %s: %s",
                          url, err);
            return HTTP_BAD_REQUEST;
        }
    
        /* The canon_handler hooks are run per the BalancerMember in
         * balancer_fixup(), keep the original/raw path for now.
         */
        r->filename = apr_pstrcat(r->pool, "proxy:" BALANCER_PREFIX,
                                  host, "/", url, NULL);
    
        return OK;
    }
    
    static void init_balancer_members(apr_pool_t *p, 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++) {
            int worker_is_initialized;
            proxy_worker *worker = *workers;
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01158)
                         "Looking at %s -> %s initialized?", balancer->s->name,
                         ap_proxy_worker_name(p, worker));
            worker_is_initialized = PROXY_WORKER_IS_INITIALIZED(worker);
            if (!worker_is_initialized) {
                ap_proxy_initialize_worker(worker, s, p);
            }
            ++workers;
        }
    
        /* Set default number of attempts to the number of
         * workers.
         */
        if (!balancer->s->max_attempts_set && balancer->workers->nelts > 1) {
            balancer->s->max_attempts = balancer->workers->nelts - 1;
            balancer->s->max_attempts_set = 1;
        }
    }
    
    /* 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, int scolon_sep)
    {
        char *path = NULL;
        char *pathdelims = "?&";
    
        if (scolon_sep) {
            pathdelims = ";?&";
        }
        for (path = strstr(url, name); path; path = strstr(path + 1, name)) {
            path += strlen(name);
            if (*path == '=') {
                /*
                 * Session path was found, get its value
                 */
                ++path;
                if (*path) {
                    char *q;
                    path = apr_strtok(apr_pstrdup(pool, path), pathdelims, &q);
                    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) {
                        /*
                         * Session cookie was found, get its value
                         */
                        char *end_cookie, *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, request_rec *r,
                                           int recursion)
    {
        int i;
        int checking_standby;
        int checked_standby;
    
        proxy_worker **workers;
    
        checking_standby = checked_standby = 0;
        while (!checked_standby) {
            workers = (proxy_worker **)balancer->workers->elts;
            for (i = 0; i < balancer->workers->nelts; i++, workers++) {
                proxy_worker *worker = *workers;
                if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
                    continue;
                if (*(worker->s->route) && strcmp(worker->s->route, route) == 0) {
                    if (PROXY_WORKER_IS_USABLE(worker)) {
                        return worker;
                    } else {
                        /*
                         * 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.
                         */
                        ap_proxy_retry_worker_fn("BALANCER", worker, r->server);
                        if (PROXY_WORKER_IS_USABLE(worker)) {
                                return worker;
                        } else {
                            /*
                             * 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 some kind of
                             * session replication between those two remote.
                             * Also check that we haven't gone thru all the
                             * balancer members by means of redirects.
                             * This should avoid redirect cycles.
                             */
                            if ((*worker->s->redirect)
                                && (recursion < balancer->workers->nelts)) {
                                proxy_worker *rworker = NULL;
                                rworker = find_route_worker(balancer, worker->s->redirect,
                                                            r, recursion + 1);
                                /* Check if the redirect worker is usable */
                                if (rworker && !PROXY_WORKER_IS_USABLE(rworker)) {
                                    /*
                                     * 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.
                                     */
                                    ap_proxy_retry_worker_fn("BALANCER", rworker, r->server);
                                }
                                if (rworker && PROXY_WORKER_IS_USABLE(rworker))
                                    return rworker;
                            }
                        }
                    }
                }
            }
            checked_standby = checking_standby++;
        }
        return NULL;
    }
    
    static proxy_worker *find_session_route(proxy_balancer *balancer,
                                            request_rec *r,
                                            char **route,
                                            const char **sticky_used,
                                            char **url)
    {
        proxy_worker *worker = NULL;
        char *url_with_qs;
    
        if (!*balancer->s->sticky)
            return NULL;
        /*
         * The route might be contained in the query string and *url is not
         * supposed to contain the query string. Hence add it temporarily if
         * present.
         */
        if (r->args) {
            url_with_qs = apr_pstrcat(r->pool, *url, "?", r->args, NULL);
        }
        else {
            url_with_qs = *url;
        }
        /* Try to find the sticky route inside url */
        *route = get_path_param(r->pool, url_with_qs, balancer->s->sticky_path, balancer->s->scolonsep);
        if (*route) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01159)
                         "Found value %s for stickysession %s",
                         *route, balancer->s->sticky_path);
            *sticky_used =  balancer->s->sticky_path;
        }
        else {
            *route = get_cookie_param(r, balancer->s->sticky);
            if (*route) {
                *sticky_used =  balancer->s->sticky;
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01160)
                             "Found value %s for stickysession %s",
                             *route, balancer->s->sticky);
            }
        }
        /*
         * If we found a value for stickysession, find the first '.' (or whatever
         * sticky_separator is set to) within. Everything after '.' (if present)
         * is our route. 
         */
        if ((*route) && (balancer->s->sticky_separator != 0) && ((*route = strchr(*route, balancer->s->sticky_separator)) != NULL ))
            (*route)++;
        if ((*route) && (**route)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01161) "Found route %s", *route);
            /* We have a route in path or in cookie
             * Find the worker that has this route defined.
             */
            worker = find_route_worker(balancer, *route, r, 1);
            if (worker && strcmp(*route, worker->s->route)) {
                /*
                 * Notice that the route of the worker chosen is different from
                 * the route supplied by the client.
                 */
                apr_table_setn(r->subprocess_env, "BALANCER_ROUTE_CHANGED", "1");
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01162)
                              "Route changed from %s to %s",
                              *route, worker->s->route);
            }
            return worker;
        }
        else
            return NULL;
    }
    
    static proxy_worker *find_best_worker(proxy_balancer *balancer,
                                          request_rec *r)
    {
        proxy_worker *candidate = NULL;
        apr_status_t rv;
    
    #if APR_HAS_THREADS
        if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01163)
                          "%s: Lock failed for find_best_worker()",
                          balancer->s->name);
            return NULL;
        }
    #endif
    
        candidate = (*balancer->lbmethod->finder)(balancer, r);
    
        if (candidate)
            candidate->s->elected++;
    
    #if APR_HAS_THREADS
        if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01164)
                          "%s: Unlock failed for find_best_worker()",
                          balancer->s->name);
        }
    #endif
    
        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 (balancer->s->timeout) {
                /* XXX: This can perhaps be build using some
                 * smarter mechanism, like tread_cond.
                 * But since the statuses can came from
                 * different children, use the provided algo.
                 */
                apr_interval_time_t timeout = balancer->s->timeout;
                apr_interval_time_t step, tval = 0;
                /* Set the timeout to 0 so that we don't
                 * end in infinite loop
                 */
                balancer->s->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->s->timeout = timeout;
            }
        }
    
        return candidate;
    
    }
    
    static int balancer_fixup(request_rec *r, proxy_worker *worker, char **url)
    {
        const char *path;
        int rc;
    
        /* Build the proxy URL from the worker URL and the actual path */
        path = strstr(*url, "://");
        if (path) {
            path = ap_strchr_c(path + 3, '/');
        }
        r->filename = apr_pstrcat(r->pool, "proxy:", worker->s->name_ex, path, NULL);
    
        /* Canonicalize r->filename per the worker scheme's canon_handler hook */
        rc = ap_proxy_canon_url(r);
        if (rc == OK) {
            AP_DEBUG_ASSERT(strncmp(r->filename, "proxy:", 6) == 0);
            *url = apr_pstrdup(r->pool, r->filename + 6);
        }
        return rc;
    }
    
    static void force_recovery(proxy_balancer *balancer, server_rec *s)
    {
        int i;
        int ok = 0;
        proxy_worker **worker;
    
        worker = (proxy_worker **)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
            if (!((*worker)->s->status & PROXY_WORKER_IN_ERROR)) {
                ok = 1;
                break;
            }
            else {
                /* Try if we can recover */
                ap_proxy_retry_worker_fn("BALANCER", *worker, s);
                if (!((*worker)->s->status & PROXY_WORKER_IN_ERROR)) {
                    ok = 1;
                    break;
                }
            }
        }
        if (!ok && balancer->s->forcerecovery) {
            /* If all workers are in error state force the recovery.
             */
            worker = (proxy_worker **)balancer->workers->elts;
            for (i = 0; i < balancer->workers->nelts; i++, worker++) {
                ++(*worker)->s->retries;
                (*worker)->s->status &= ~PROXY_WORKER_IN_ERROR;
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01165)
                             "%s: Forcing recovery for worker (%s:%d)",
                             balancer->s->name, (*worker)->s->hostname_ex,
                             (int)(*worker)->s->port);
            }
        }
    }
    
    static apr_status_t decrement_busy_count(void *worker_)
    {
        proxy_worker *worker = worker_;
        
        if (worker->s->busy) {
            worker->s->busy--;
        }
    
        return APR_SUCCESS;
    }
    
    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 = NULL;
        const char *sticky = NULL;
        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 &&
            (ap_cstr_casecmpn(*url, BALANCER_PREFIX, sizeof(BALANCER_PREFIX) - 1)
             || !(*balancer = ap_proxy_get_balancer(r->pool, conf, *url, 1))))
            return DECLINED;
    
        /* Step 2: Lock the LoadBalancer
         * XXX: perhaps we need the process lock here
         */
    #if APR_HAS_THREADS
        if ((rv = PROXY_THREAD_LOCK(*balancer)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01166)
                          "%s: Lock failed for pre_request", (*balancer)->s->name);
            return DECLINED;
        }
    #endif
    
        /* Step 3: force recovery */
        force_recovery(*balancer, r->server);
    
        /* Step 3.5: Update member list for the balancer */
        /* TODO: Implement as provider! */
        ap_proxy_sync_balancer(*balancer, r->server, conf);
    
        /* Step 4: find the session route */
        runtime = find_session_route(*balancer, r, &route, &sticky, url);
        if (runtime) {
            if ((*balancer)->lbmethod && (*balancer)->lbmethod->updatelbstatus) {
                /* Call the LB implementation */
                (*balancer)->lbmethod->updatelbstatus(*balancer, runtime, r->server);
            }
            else { /* Use the default one */
                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)->s->sticky_force) {
            int i, member_of = 0;
            proxy_worker **workers;
            /*
             * We have a route provided that doesn't match the
             * balancer name. See if the provider route is the
             * member of the same balancer in which case return 503
             */
            workers = (proxy_worker **)(*balancer)->workers->elts;
            for (i = 0; i < (*balancer)->workers->nelts; i++) {
                if (*((*workers)->s->route) && strcmp((*workers)->s->route, route) == 0) {
                    member_of = 1;
                    break;
                }
                workers++;
            }
            if (member_of) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01167)
                              "%s: All workers are in error state for route (%s)",
                              (*balancer)->s->name, route);
    #if APR_HAS_THREADS
                if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01168)
                                  "%s: Unlock failed for pre_request",
                                  (*balancer)->s->name);
                }
    #endif
                return HTTP_SERVICE_UNAVAILABLE;
            }
        }
    
    #if APR_HAS_THREADS
        if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01169)
                          "%s: Unlock failed for pre_request",
                          (*balancer)->s->name);
        }
    #endif
        if (!*worker) {
            runtime = find_best_worker(*balancer, r);
            if (!runtime) {
                if ((*balancer)->workers->nelts) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01170)
                                  "%s: All workers are in error state",
                                  (*balancer)->s->name);
                } else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01171)
                                  "%s: No workers in balancer",
                                  (*balancer)->s->name);
                }
    
                return HTTP_SERVICE_UNAVAILABLE;
            }
            if (*(*balancer)->s->sticky && runtime) {
                /*
                 * This balancer has sticky sessions and the client either has not
                 * supplied any routing information or all workers for this route
                 * including possible redirect and hotstandby workers are in error
                 * state, but we have found another working worker for this
                 * balancer where we can send the request. Thus notice that we have
                 * changed the route to the backend.
                 */
                apr_table_setn(r->subprocess_env, "BALANCER_ROUTE_CHANGED", "1");
            }
            *worker = runtime;
        }
    
        (*worker)->s->busy++;
        apr_pool_cleanup_register(r->pool, *worker, decrement_busy_count,
                                  apr_pool_cleanup_null);
    
        /* Add balancer/worker info to env. */
        apr_table_setn(r->subprocess_env,
                       "BALANCER_NAME", (*balancer)->s->name);
        apr_table_setn(r->subprocess_env,
                       "BALANCER_WORKER_NAME", (*worker)->s->name_ex);
        apr_table_setn(r->subprocess_env,
                       "BALANCER_WORKER_ROUTE", (*worker)->s->route);
    
        /* 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 and canonicalizes according
         * to the worker scheme (calls canon_handler hooks).
         */
        access_status = balancer_fixup(r, *worker, url);
    
        /* Add the session route to request notes if present */
        if (route) {
            apr_table_setn(r->notes, "session-sticky", sticky);
            apr_table_setn(r->notes, "session-route", route);
    
            /* Add session info to env. */
            apr_table_setn(r->subprocess_env,
                           "BALANCER_SESSION_STICKY", sticky);
            apr_table_setn(r->subprocess_env,
                           "BALANCER_SESSION_ROUTE", route);
        }
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01172)
                      "%s: worker (%s) rewritten to %s",
                      (*balancer)->s->name, (*worker)->s->name_ex, *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 APR_HAS_THREADS
        if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01173)
                          "%s: Lock failed for post_request",
                          balancer->s->name);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    #endif
    
        if (!apr_is_empty_array(balancer->errstatuses)
            && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
            int i;
            for (i = 0; i < balancer->errstatuses->nelts; i++) {
                int val = ((int *)balancer->errstatuses->elts)[i];
                if (r->status == val) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01174)
                                  "%s: Forcing worker (%s) into error state "
                                  "due to status code %d matching 'failonstatus' "
                                  "balancer parameter",
                                  balancer->s->name, ap_proxy_worker_name(r->pool, worker),
                                  val);
                    worker->s->status |= PROXY_WORKER_IN_ERROR;
                    worker->s->error_time = apr_time_now();
                    break;
                }
            }
        }
    
        if (balancer->failontimeout
            && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)
            && (apr_table_get(r->notes, "proxy_timedout")) != NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02460)
                          "%s: Forcing worker (%s) into error state "
                          "due to timeout and 'failontimeout' parameter being set",
                           balancer->s->name, ap_proxy_worker_name(r->pool, worker));
            worker->s->status |= PROXY_WORKER_IN_ERROR;
            worker->s->error_time = apr_time_now();
    
        }
    #if APR_HAS_THREADS
        if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01175)
                          "%s: Unlock failed for post_request", balancer->s->name);
        }
    #endif
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01176)
                      "proxy_balancer_post_request for (%s)", balancer->s->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 its
         * load factor will always be 100
         */
        if (balancer->workers->nelts == 1) {
            (*workers)->s->lbstatus = (*workers)->s->lbfactor = 100;
            return;
        }
        for (i = 0; i < balancer->workers->nelts; i++) {
            /* Update the status entries */
            workers[i]->s->lbstatus = workers[i]->s->lbfactor;
        }
    }
    
    static apr_status_t lock_remove(void *data)
    {
        int i;
        proxy_balancer *balancer;
        server_rec *s = data;
        void *sconf = s->module_config;
        proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
    
        balancer = (proxy_balancer *)conf->balancers->elts;
        for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
            if (balancer->gmutex) {
                apr_global_mutex_destroy(balancer->gmutex);
                balancer->gmutex = NULL;
            }
        }
        return(0);
    }
    
    /*
     * Compute an ID for a vhost based on what makes it selected by requests.
     * The second and more Host(s)/IP(s):port(s), and the ServerAlias(es) are
     * optional (see make_servers_ids() below).
     */
     static const char *make_server_id(server_rec *s, apr_pool_t *p, int full)
    {
        apr_md5_ctx_t md5_ctx;
        unsigned char md5[APR_MD5_DIGESTSIZE];
        char id[2 * APR_MD5_DIGESTSIZE + 1];
        char host_ip[64]; /* for any IPv[46] string */
        server_addr_rec *sar;
        int i;
    
        apr_md5_init(&md5_ctx);
        for (sar = s->addrs; sar; sar = sar->next) {
            host_ip[0] = '\0';
            apr_sockaddr_ip_getbuf(host_ip, sizeof host_ip, sar->host_addr);
            apr_md5_update(&md5_ctx, (void *)sar->virthost, strlen(sar->virthost));
            apr_md5_update(&md5_ctx, (void *)host_ip, strlen(host_ip));
            apr_md5_update(&md5_ctx, (void *)&sar->host_port,
                           sizeof(sar->host_port));
            if (!full) {
                break;
            }
        }
        if (s->server_hostname) {
            apr_md5_update(&md5_ctx, (void *)s->server_hostname,
                           strlen(s->server_hostname));
        }
        if (full) {
            if (s->names) {
                for (i = 0; i < s->names->nelts; ++i) {
                    const char *name = APR_ARRAY_IDX(s->names, i, char *);
                    apr_md5_update(&md5_ctx, (void *)name, strlen(name));
                }
            }
            if (s->wild_names) {
                for (i = 0; i < s->wild_names->nelts; ++i) {
                    const char *name = APR_ARRAY_IDX(s->wild_names, i, char *);
                    apr_md5_update(&md5_ctx, (void *)name, strlen(name));
                }
            }
        }
        apr_md5_final(md5, &md5_ctx);
        ap_bin2hex(md5, APR_MD5_DIGESTSIZE, id);
    
        return apr_pstrmemdup(p, id, sizeof(id) - 1);
    }
    
    /*
     * First try to compute an unique ID for each vhost with minimal criteria,
     * that is the first Host/IP:port and ServerName. For most cases this should
     * be enough and avoids changing the ID unnecessarily across restart (or
     * stop/start w.r.t. persisted files) for things that this module does not
     * care about.
     *
     * But if it's not enough (collisions) do a second pass for the full monty,
     * that is additionally the other Host(s)/IP(s):port(s) and ServerAlias(es).
     *
     * Finally, for pathological configs where this is still not enough, let's
     * append a counter to duplicates, because we really want that ID to be unique
     * even if the vhost will never be selected to handle requests at run time, at
     * load time a duplicate may steal the original slotmems (depending on its
     * balancers' configurations), see how mod_slotmem_shm reuses slots/files based
     * solely on this ID and resets them if the sizes don't match.
     */
    static apr_array_header_t *make_servers_ids(server_rec *main_s, apr_pool_t *p)
    {
        server_rec *s = main_s;
        apr_array_header_t *ids = apr_array_make(p, 10, sizeof(const char *));
        apr_hash_t *dups = apr_hash_make(p);
        int idx, *dup, full_monty = 0;
        const char *id;
    
        for (idx = 0, s = main_s; s; s = s->next, ++idx) {
            id = make_server_id(s, p, 0);
            dup = apr_hash_get(dups, id, APR_HASH_KEY_STRING);
            apr_hash_set(dups, id, APR_HASH_KEY_STRING,
                         apr_pmemdup(p, &idx, sizeof(int)));
            if (dup) {
                full_monty = 1;
                APR_ARRAY_IDX(ids, *dup, const char *) = NULL;
                APR_ARRAY_PUSH(ids, const char *) = NULL;
            }
            else {
                APR_ARRAY_PUSH(ids, const char *) = id;
            }
        }
        if (full_monty) {
            apr_hash_clear(dups);
            for (idx = 0, s = main_s; s; s = s->next, ++idx) {
                id = APR_ARRAY_IDX(ids, idx, const char *);
                if (id) {
                    /* Preserve non-duplicates */
                    continue;
                }
                id = make_server_id(s, p, 1);
                if (apr_hash_get(dups, id, APR_HASH_KEY_STRING)) {
                    id = apr_psprintf(p, "%s_%x", id, idx);
                }
                else {
                    apr_hash_set(dups, id, APR_HASH_KEY_STRING, (void *)-1);
                }
                APR_ARRAY_IDX(ids, idx, const char *) = id;
            }
        }
    
        return ids;
    }
    
    /* post_config hook: */
    static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                             apr_pool_t *ptemp, server_rec *s)
    {
        apr_status_t rv;
        proxy_server_conf *conf;
        ap_slotmem_instance_t *new = NULL;
        apr_time_t tstamp;
        apr_array_header_t *ids;
        int idx;
    
        /* balancer_post_config() will be called twice during startup.  So, don't
         * set up the static data the 1st time through. */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
    
        ap_proxy_retry_worker_fn =
                APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker);
        if (!ap_proxy_retry_worker_fn) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02230)
                         "mod_proxy must be loaded for mod_proxy_balancer");
            return !OK;
        }
    
        /*
         * Get slotmem setups
         */
        storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shm",
                                     AP_SLOTMEM_PROVIDER_VERSION);
        if (!storage) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01177)
                         "Failed to lookup provider 'shm' for '%s': is "
                         "mod_slotmem_shm loaded??",
                         AP_SLOTMEM_PROVIDER_GROUP);
            return !OK;
        }
    
        ids = make_servers_ids(s, ptemp);
    
        tstamp = apr_time_now();
        /*
         * Go thru each Vhost and create the shared mem slotmem for
         * each balancer's workers
         */
        for (idx = 0; s; ++idx) {
            int i,j;
            const char *id;
            proxy_balancer *balancer;
            ap_slotmem_type_t type;
            void *sconf = s->module_config;
            conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
            /*
             * During create_proxy_config() we created a dummy id. Now that
             * we have identifying info, we can create the real id
             */
            id = APR_ARRAY_IDX(ids, idx, const char *);
            conf->id = apr_psprintf(pconf, "p%x",
                                    ap_proxy_hashfunc(id, PROXY_HASHFUNC_DEFAULT));
            if (conf->bslot) {
                /* Shared memory already created for this proxy_server_conf.
                 */
                s = s->next;
                continue;
            }
            if (conf->bal_persist) {
                type = AP_SLOTMEM_TYPE_PERSIST | AP_SLOTMEM_TYPE_CLEARINUSE;
            } else {
                type = 0;
            }
            if (conf->balancers->nelts) {
                conf->max_balancers = conf->balancers->nelts + conf->bgrowth;
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01178) "Doing balancers create: %d, %d (%d)",
                             (int)ALIGNED_PROXY_BALANCER_SHARED_SIZE,
                             (int)conf->balancers->nelts, conf->max_balancers);
    
                rv = storage->create(&new, conf->id,
                                     ALIGNED_PROXY_BALANCER_SHARED_SIZE,
                                     conf->max_balancers, type, pconf);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01179) "balancer slotmem_create failed");
                    return !OK;
                }
                conf->bslot = new;
            }
            conf->storage = storage;
    
            /* Initialize shared scoreboard data */
            balancer = (proxy_balancer *)conf->balancers->elts;
            for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
                proxy_worker **workers;
                proxy_worker *worker;
                proxy_balancer_shared *bshm;
                const char *sname;
                unsigned int index;
    
                /* now that we have the right id, we need to redo the sname field */
                ap_pstr2_alnum(pconf, balancer->s->name + sizeof(BALANCER_PREFIX) - 1,
                               &sname);
                sname = apr_pstrcat(pconf, conf->id, "_", sname, NULL);
                PROXY_STRNCPY(balancer->s->sname, sname); /* We know this will succeed */
    
                balancer->max_workers = balancer->workers->nelts + balancer->growth;
                /* Create global mutex */
                rv = ap_global_mutex_create(&(balancer->gmutex), NULL, balancer_mutex_type,
                                            balancer->s->sname, s, pconf, 0);
                if (rv != APR_SUCCESS || !balancer->gmutex) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01180)
                                 "mutex creation of %s : %s failed", balancer_mutex_type,
                                 balancer->s->sname);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                apr_pool_cleanup_register(pconf, (void *)s, lock_remove,
                                          apr_pool_cleanup_null);
    
                /* setup shm for balancers */
                bshm = ap_proxy_find_balancershm(storage, conf->bslot, balancer, &index);
                if (bshm) {
                    if ((rv = storage->fgrab(conf->bslot, index)) != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02408) "balancer slotmem_fgrab failed");
                        return !OK;
                    }
                }
                else {
                    if ((rv = storage->grab(conf->bslot, &index)) != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01181) "balancer slotmem_grab failed");
                        return !OK;
                    }
                    if ((rv = storage->dptr(conf->bslot, index, (void *)&bshm)) != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01182) "balancer slotmem_dptr failed");
                        return !OK;
                    }
                }
                if ((rv = ap_proxy_share_balancer(balancer, bshm, index)) != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01183) "Cannot share balancer");
                    return !OK;
                }
    
                /* create slotmem slots for workers */
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01184) "Doing workers create: %s (%s), %d, %d [%u]",
                             balancer->s->name, balancer->s->sname,
                             (int)ALIGNED_PROXY_WORKER_SHARED_SIZE,
                             (int)balancer->max_workers, i);
    
                rv = storage->create(&new, balancer->s->sname,
                                     ALIGNED_PROXY_WORKER_SHARED_SIZE,
                                     balancer->max_workers, type, pconf);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01185) "worker slotmem_create failed");
                    return !OK;
                }
                balancer->wslot = new;
                balancer->storage = storage;
    
                /* sync all timestamps */
                balancer->wupdated = balancer->s->wupdated = tstamp;
    
                /* now go thru each worker */
                workers = (proxy_worker **)balancer->workers->elts;
                for (j = 0; j < balancer->workers->nelts; j++, workers++) {
                    proxy_worker_shared *shm;
    
                    worker = *workers;
    
                    shm = ap_proxy_find_workershm(storage, balancer->wslot, worker, &index);
                    if (shm) {
                        if ((rv = storage->fgrab(balancer->wslot, index)) != APR_SUCCESS) {
                            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02409) "worker slotmem_fgrab failed");
                            return !OK;
                        }
                    }
                    else {
                        if ((rv = storage->grab(balancer->wslot, &index)) != APR_SUCCESS) {
                            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01186) "worker slotmem_grab failed");
                            return !OK;
    
                        }
                        if ((rv = storage->dptr(balancer->wslot, index, (void *)&shm)) != APR_SUCCESS) {
                            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01187) "worker slotmem_dptr failed");
                            return !OK;
                        }
                    }
                    if ((rv = ap_proxy_share_worker(worker, shm, index)) != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01188) "Cannot share worker");
                        return !OK;
                    }
                    worker->s->updated = tstamp;
                }
                if (conf->bal_persist) {
                    /* We could have just read-in a persisted config. Force a sync. */
                    balancer->wupdated--;
                    ap_proxy_sync_balancer(balancer, s, conf);
                }
            }
            s = s->next;
        }
    
        return OK;
    }
    
    static void create_radio(const char *name, unsigned int flag, request_rec *r)
    {
        ap_rvputs(r, "<td><label for='", name, "1'>On</label> <input name='", name, "' id='", name, "1' value='1' type=radio", NULL);
        if (flag)
            ap_rputs(" checked", r);
        ap_rvputs(r, "> <br/> <label for='", name, "0'>Off</label> <input name='", name, "' id='", name, "0' value='0' type=radio", NULL);
        if (!flag)
            ap_rputs(" checked", r);
        ap_rputs("></td>\n", r);
    }
    
    static void push2table(const char *input, apr_table_t *params,
                           const char *allowed[], apr_pool_t *p)
    {
        char *args;
        char *tok, *val;
        char *key;
    
        if (input == NULL) {
            return;
        }
        args = apr_pstrdup(p, input);
    
        key = apr_strtok(args, "&", &tok);
        while (key) {
            val = strchr(key, '=');
            if (val) {
                *val++ = '\0';
            }
            else {
                val = "";
            }
            ap_unescape_url(key);
            ap_unescape_url(val);
            /* hcuri, worker name, balancer name, at least  are escaped when building the form, so twice */
            ap_unescape_url(val);
            if (allowed == NULL) { /* allow all */
                apr_table_set(params, key, val);
            }
            else {
                const char **ok = allowed;
                while (*ok) {
                    if (strcmp(*ok, key) == 0) {
                        apr_table_set(params, key, val);
                        break;
                    }
                    ok++;
                }
            }
            key = apr_strtok(NULL, "&", &tok);
        }
    }
    
    /* Returns non-zero if the Referer: header value passed matches the
     * host of the request. */
    static int safe_referer(request_rec *r, const char *ref)
    {
        apr_uri_t uri;
    
        if (apr_uri_parse(r->pool, ref, &uri) || !uri.hostname)
            return 0;
    
        return strcasecmp(uri.hostname, ap_get_server_name(r)) == 0;
    }
    
    /*
     * Process the paramters and add or update the worker of the
     * balancer.  Must only be called if the nonce has been validated to
     * match, to avoid XSS attacks.
     */
    static int balancer_process_balancer_worker(request_rec *r, proxy_server_conf *conf,
                                                proxy_balancer *bsel,
                                                proxy_worker *wsel,
                                                apr_table_t *params)
    
    {
        apr_status_t rv;
        /* First set the params */
        if (wsel) {
            const char *val;
            int was_usable = PROXY_WORKER_IS_USABLE(wsel);
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01192) "settings worker params");
    
            if ((val = apr_table_get(params, "w_lf"))) {
                int ival;
                double fval = atof(val);
                ival = fval * 100.0;
                if (ival >= 100 && ival <= 10000) {
                    wsel->s->lbfactor = ival;
                    if (bsel)
                        recalc_factors(bsel);
                }
            }
            if ((val = apr_table_get(params, "w_wr"))) {
                if (strlen(val) && strlen(val) < sizeof(wsel->s->route))
                    strcpy(wsel->s->route, val);
                else
                    *wsel->s->route = '\0';
            }
            if ((val = apr_table_get(params, "w_rr"))) {
                if (strlen(val) && strlen(val) < sizeof(wsel->s->redirect))
                    strcpy(wsel->s->redirect, val);
                else
                    *wsel->s->redirect = '\0';
            }
            /*
             * TODO: Look for all 'w_status_#' keys and then loop thru
             * on that # character, since the character == the flag
             */
            if ((val = apr_table_get(params, "w_status_I"))) {
                ap_proxy_set_wstatus(PROXY_WORKER_IGNORE_ERRORS_FLAG, atoi(val), wsel);
            }
            if ((val = apr_table_get(params, "w_status_N"))) {
                ap_proxy_set_wstatus(PROXY_WORKER_DRAIN_FLAG, atoi(val), wsel);
            }
            if ((val = apr_table_get(params, "w_status_D"))) {
                ap_proxy_set_wstatus(PROXY_WORKER_DISABLED_FLAG, atoi(val), wsel);
            }
            if ((val = apr_table_get(params, "w_status_H"))) {
                ap_proxy_set_wstatus(PROXY_WORKER_HOT_STANDBY_FLAG, atoi(val), wsel);
            }
            if ((val = apr_table_get(params, "w_status_R"))) {
                ap_proxy_set_wstatus(PROXY_WORKER_HOT_SPARE_FLAG, atoi(val), wsel);
            }
            if ((val = apr_table_get(params, "w_status_S"))) {
                ap_proxy_set_wstatus(PROXY_WORKER_STOPPED_FLAG, atoi(val), wsel);
            }
            if ((val = apr_table_get(params, "w_status_C"))) {
                ap_proxy_set_wstatus(PROXY_WORKER_HC_FAIL_FLAG, atoi(val), wsel);
            }
            if ((val = apr_table_get(params, "w_ls"))) {
                int ival = atoi(val);
                if (ival >= 0 && ival <= 99) {
                    wsel->s->lbset = ival;
                 }
            }
            if ((val = apr_table_get(params, "w_hi"))) {
                apr_interval_time_t hci;
                if (ap_timeout_parameter_parse(val, &hci, "ms") == APR_SUCCESS) {
                    if (hci >= AP_WD_TM_SLICE) {
                        wsel->s->interval = hci;
                    }
                 }
            }
            if ((val = apr_table_get(params, "w_hp"))) {
                int ival = atoi(val);
                if (ival >= 1) {
                    wsel->s->passes = ival;
                 }
            }
            if ((val = apr_table_get(params, "w_hf"))) {
                int ival = atoi(val);
                if (ival >= 1) {
                    wsel->s->fails = ival;
                 }
            }
            if ((val = apr_table_get(params, "w_hm"))) {
                proxy_hcmethods_t *method = proxy_hcmethods;
                for (; method->name; method++) {
                    if (!ap_cstr_casecmp(method->name, val) && method->implemented)
                        wsel->s->method = method->method;
                }
            }
            if ((val = apr_table_get(params, "w_hu"))) {
                if (strlen(val) && strlen(val) < sizeof(wsel->s->hcuri))
                    strcpy(wsel->s->hcuri, val);
                else
                    *wsel->s->hcuri = '\0';
            }
            if (hc_valid_expr_f && (val = apr_table_get(params, "w_he"))) {
                if (strlen(val) && hc_valid_expr_f(r, val) && strlen(val) < sizeof(wsel->s->hcexpr))
                    strcpy(wsel->s->hcexpr, val);
                else
                    *wsel->s->hcexpr = '\0';
            }
            /* If the health check method doesn't support an expr, then null it */
            if (wsel->s->method == NONE || wsel->s->method == TCP || wsel->s->method == CPING) {
                *wsel->s->hcexpr = '\0';
            }
            /* if enabling, we need to reset all lb params */
            if (bsel && !was_usable && PROXY_WORKER_IS_USABLE(wsel)) {
                bsel->s->need_reset = 1;
            }
    
        }
    
        if (bsel) {
            const char *val;
            int ival;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01193)
                          "settings balancer params");
            if ((val = apr_table_get(params, "b_lbm"))) {
                if ((strlen(val) < (sizeof(bsel->s->lbpname)-1)) &&
                    strcmp(val, bsel->s->lbpname)) {
                    proxy_balancer_method *lbmethod;
                    lbmethod = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
                    if (lbmethod) {
                        PROXY_STRNCPY(bsel->s->lbpname, val);
                        bsel->lbmethod = lbmethod;
                        bsel->s->wupdated = apr_time_now();
                        bsel->s->need_reset = 1;
                    }
                }
            }
            if ((val = apr_table_get(params, "b_tmo"))) {
                ival = atoi(val);
                if (ival >= 0 && ival <= 7200) { /* 2 hrs enuff? */
                    bsel->s->timeout = apr_time_from_sec(ival);
                }
            }
            if ((val = apr_table_get(params, "b_max"))) {
                ival = atoi(val);
                if (ival >= 0 && ival <= 99) {
                    bsel->s->max_attempts = ival;
                }
            }
            if ((val = apr_table_get(params, "b_sforce"))) {
                ival = atoi(val);
                bsel->s->sticky_force = (ival != 0);
            }
            if ((val = apr_table_get(params, "b_ss")) && *val) {
                if (strlen(val) < (sizeof(bsel->s->sticky_path)-1)) {
                    if (*val == '-' && *(val+1) == '\0')
                        *bsel->s->sticky_path = *bsel->s->sticky = '\0';
                    else {
                        char *path;
                        PROXY_STRNCPY(bsel->s->sticky_path, val);
                        PROXY_STRNCPY(bsel->s->sticky, val);
    
                        if ((path = strchr((char *)bsel->s->sticky, '|'))) {
                            *path++ = '\0';
                            PROXY_STRNCPY(bsel->s->sticky_path, path);
                        }
                    }
                }
            }
            if ((val = apr_table_get(params, "b_wyes")) &&
                (*val == '1' && *(val+1) == '\0') &&
                (val = apr_table_get(params, "b_nwrkr"))) {
                char *ret;
                proxy_worker *nworker;
                nworker = ap_proxy_get_worker(r->pool, bsel, conf, val);
                if (!nworker && storage->num_free_slots(bsel->wslot)) {
    #if APR_HAS_THREADS
                    if ((rv = PROXY_GLOBAL_LOCK(bsel)) != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01194)
                                      "%s: Lock failed for adding worker",
                                      bsel->s->name);
                    }
    #endif
                    ret = ap_proxy_define_worker(conf->pool, &nworker, bsel, conf, val, 0);
                    if (!ret) {
                        unsigned int index;
                        proxy_worker_shared *shm;
                        PROXY_COPY_CONF_PARAMS(nworker, conf);
                        if ((rv = storage->grab(bsel->wslot, &index)) != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01195)
                                          "worker slotmem_grab failed");
    #if APR_HAS_THREADS
                            if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
                                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01196)
                                              "%s: Unlock failed for adding worker",
                                              bsel->s->name);
                            }
    #endif
                            return HTTP_BAD_REQUEST;
                        }
                        if ((rv = storage->dptr(bsel->wslot, index, (void *)&shm)) != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01197)
                                          "worker slotmem_dptr failed");
    #if APR_HAS_THREADS
                            if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
                                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01198)
                                              "%s: Unlock failed for adding worker",
                                              bsel->s->name);
                            }
    #endif
                            return HTTP_BAD_REQUEST;
                        }
                        if ((rv = ap_proxy_share_worker(nworker, shm, index)) != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01199)
                                          "Cannot share worker");
    #if APR_HAS_THREADS
                            if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
                                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01200)
                                              "%s: Unlock failed for adding worker",
                                              bsel->s->name);
                            }
    #endif
                            return HTTP_BAD_REQUEST;
                        }
                        if ((rv = ap_proxy_initialize_worker(nworker, r->server, conf->pool)) != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01201)
                                          "Cannot init worker");
    #if APR_HAS_THREADS
                            if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
                                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01202)
                                              "%s: Unlock failed for adding worker",
                                              bsel->s->name);
                            }
    #endif
                            return HTTP_BAD_REQUEST;
                        }
                        /* sync all timestamps */
                        bsel->wupdated = bsel->s->wupdated = nworker->s->updated = apr_time_now();
                        /* by default, all new workers are disabled */
                        ap_proxy_set_wstatus(PROXY_WORKER_DISABLED_FLAG, 1, nworker);
                    } else {
                                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10163)
                                      "%s: failed to add worker %s",
                                      bsel->s->name, val);
    #if APR_HAS_THREADS
                        PROXY_GLOBAL_UNLOCK(bsel);
    #endif
                        return HTTP_BAD_REQUEST;
                    }
    #if APR_HAS_THREADS
                    if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01203)
                                      "%s: Unlock failed for adding worker",
                                      bsel->s->name);
                    }
    #endif
                } else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10164)
                                      "%s: failed to add worker %s",
                                      bsel->s->name, val);
                    return HTTP_BAD_REQUEST;
                }
    
            }
    
        }
        return APR_SUCCESS;
    }
    
    /*
     * Process a request for balancer or worker management from another module
     */
    static apr_status_t balancer_manage(request_rec *r, apr_table_t *params)
    {
        void *sconf;
        proxy_server_conf *conf;
        proxy_balancer *bsel = NULL;
        proxy_worker *wsel = NULL;
        const char *name;
        sconf = r->server->module_config;
        conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
    
        /* Process the parameters */
        if ((name = apr_table_get(params, "b"))) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage "
                      "balancer: %s", name);
            bsel = ap_proxy_get_balancer(r->pool, conf,
                apr_pstrcat(r->pool, BALANCER_PREFIX, name, NULL), 0);
        }
    
        if ((name = apr_table_get(params, "w"))) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage "
                      "worker: %s", name);
            wsel = ap_proxy_get_worker(r->pool, bsel, conf, name);
        }
        if (bsel) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage "
                      "balancer: %s",  bsel->s->name);
            return(balancer_process_balancer_worker(r, conf, bsel, wsel, params));
        }
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage failed: "
                          "No balancer!");
        return HTTP_BAD_REQUEST;
    }
    
    /*
     * builds the page and links to configure via HTLM or XML.
     */
    static void balancer_display_page(request_rec *r, proxy_server_conf *conf,
                                      proxy_balancer *bsel,
                                      proxy_worker *wsel,
                                      int usexml)
    {
        const char *action;
        proxy_balancer *balancer;
        proxy_worker *worker;
        proxy_worker **workers;
        int i, n;
        action = ap_construct_url(r->pool, r->uri, r);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01204) "genning page");
    
        if (usexml) {
            char date[APR_RFC822_DATE_LEN];
            ap_set_content_type_ex(r, "text/xml", 1);
            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);
                /* Start proxy_balancer */
                ap_rvputs(r, "      <httpd:name>", balancer->s->name, "</httpd:name>\n", NULL);
                if (*balancer->s->sticky) {
                    ap_rvputs(r, "      <httpd:stickysession>", ap_escape_html(r->pool, balancer->s->sticky),
                              "</httpd:stickysession>\n", NULL);
                    ap_rprintf(r,
                               "      <httpd:nofailover>%s</httpd:nofailover>\n",
                               (balancer->s->sticky_force ? "On" : "Off"));
                }
                ap_rprintf(r,
                           "      <httpd:timeout>%" APR_TIME_T_FMT "</httpd:timeout>",
                           apr_time_sec(balancer->s->timeout));
                if (balancer->s->max_attempts_set) {
                    ap_rprintf(r,
                               "      <httpd:maxattempts>%d</httpd:maxattempts>\n",
                               balancer->s->max_attempts);
                }
                ap_rvputs(r, "      <httpd:lbmethod>", balancer->lbmethod->name,
                          "</httpd:lbmethod>\n", NULL);
                if (*balancer->s->sticky) {
                    ap_rprintf(r,
                               "      <httpd:scolonpathdelim>%s</httpd:scolonpathdelim>\n",
                               (balancer->s->scolonsep ? "On" : "Off"));
                }
                /* End proxy_balancer */
                ap_rputs("      <httpd:workers>\n", r);
                workers = (proxy_worker **)balancer->workers->elts;
                for (n = 0; n < balancer->workers->nelts; n++) {
                    worker = *workers;
                    /* Start proxy_worker */
                    ap_rputs("        <httpd:worker>\n", r);
                    ap_rvputs(r, "          <httpd:name>", ap_proxy_worker_name(r->pool, worker),
                              "</httpd:name>\n", NULL);
                    ap_rvputs(r, "          <httpd:scheme>", worker->s->scheme,
                              "</httpd:scheme>\n", NULL);
                    ap_rvputs(r, "          <httpd:hostname>", worker->s->hostname_ex,
                              "</httpd:hostname>\n", NULL);
                    ap_rprintf(r, "          <httpd:loadfactor>%.2f</httpd:loadfactor>\n",
                              (float)(worker->s->lbfactor)/100.0);
                    ap_rprintf(r,
                               "          <httpd:port>%d</httpd:port>\n",
                               worker->s->port);
                    ap_rprintf(r, "          <httpd:min>%d</httpd:min>\n",
                               worker->s->min);
                    ap_rprintf(r, "          <httpd:smax>%d</httpd:smax>\n",
                               worker->s->smax);
                    ap_rprintf(r, "          <httpd:max>%d</httpd:max>\n",
                               worker->s->hmax);
                    ap_rprintf(r,
                               "          <httpd:ttl>%" APR_TIME_T_FMT "</httpd:ttl>\n",
                               apr_time_sec(worker->s->ttl));
                    if (worker->s->timeout_set) {
                        ap_rprintf(r,
                                   "          <httpd:timeout>%" APR_TIME_T_FMT "</httpd:timeout>\n",
                                   apr_time_sec(worker->s->timeout));
                    }
                    if (worker->s->acquire_set) {
                        ap_rprintf(r,
                                   "          <httpd:acquire>%" APR_TIME_T_FMT "</httpd:acquire>\n",
                                   apr_time_msec(worker->s->acquire));
                    }
                    if (worker->s->recv_buffer_size_set) {
                        ap_rprintf(r,
                                   "          <httpd:recv_buffer_size>%" APR_SIZE_T_FMT "</httpd:recv_buffer_size>\n",
                                   worker->s->recv_buffer_size);
                    }
                    if (worker->s->io_buffer_size_set) {
                        ap_rprintf(r,
                                   "          <httpd:io_buffer_size>%" APR_SIZE_T_FMT "</httpd:io_buffer_size>\n",
                                   worker->s->io_buffer_size);
                    }
                    if (worker->s->keepalive_set) {
                        ap_rprintf(r,
                                   "          <httpd:keepalive>%s</httpd:keepalive>\n",
                                   (worker->s->keepalive ? "On" : "Off"));
                    }
                    /* Begin proxy_worker_stat */
                    ap_rputs("          <httpd:status>", r);
                    ap_rputs(ap_proxy_parse_wstatus(r->pool, worker), r);
                    ap_rputs("</httpd:status>\n", r);
                    if ((worker->s->error_time > 0) && apr_rfc822_date(date, worker->s->error_time) == APR_SUCCESS) {
                        ap_rvputs(r, "          <httpd:error_time>", date,
                                  "</httpd:error_time>\n", NULL);
                    }
                    ap_rprintf(r,
                               "          <httpd:retries>%d</httpd:retries>\n",
                               worker->s->retries);
                    ap_rprintf(r,
                               "          <httpd:lbstatus>%d</httpd:lbstatus>\n",
                               worker->s->lbstatus);
                    ap_rprintf(r,
                               "          <httpd:loadfactor>%.2f</httpd:loadfactor>\n",
                               (float)(worker->s->lbfactor)/100.0);
                    ap_rprintf(r,
                               "          <httpd:transferred>%" APR_OFF_T_FMT "</httpd:transferred>\n",
                               worker->s->transferred);
                    ap_rprintf(r,
                               "          <httpd:read>%" APR_OFF_T_FMT "</httpd:read>\n",
                               worker->s->read);
                    ap_rprintf(r,
                               "          <httpd:elected>%" APR_SIZE_T_FMT "</httpd:elected>\n",
                               worker->s->elected);
                    ap_rvputs(r, "          <httpd:route>",
                              ap_escape_html(r->pool, worker->s->route),
                              "</httpd:route>\n", NULL);
                    ap_rvputs(r, "          <httpd:redirect>",
                              ap_escape_html(r->pool, worker->s->redirect),
                              "</httpd:redirect>\n", NULL);
                    ap_rprintf(r,
                               "          <httpd:busy>%" APR_SIZE_T_FMT "</httpd:busy>\n",
                               worker->s->busy);
                    ap_rprintf(r, "          <httpd:lbset>%d</httpd:lbset>\n",
                               worker->s->lbset);
                    /* End proxy_worker_stat */
                    if (!ap_cstr_casecmp(worker->s->scheme, "ajp")) {
                        ap_rputs("          <httpd:flushpackets>", r);
                        switch (worker->s->flush_packets) {
                            case flush_off:
                                ap_rputs("Off", r);
                                break;
                            case flush_on:
                                ap_rputs("On", r);
                                break;
                            case flush_auto:
                                ap_rputs("Auto", r);
                                break;
                        }
                        ap_rputs("</httpd:flushpackets>\n", r);
                        if (worker->s->flush_packets == flush_auto) {
                            ap_rprintf(r,
                                       "          <httpd:flushwait>%d</httpd:flushwait>\n",
                                       worker->s->flush_wait);
                        }
                        if (worker->s->ping_timeout_set) {
                            ap_rprintf(r,
                                       "          <httpd:ping>%" APR_TIME_T_FMT "</httpd:ping>",
                                       apr_time_msec(worker->s->ping_timeout));
                        }
                    }
                    if (worker->s->disablereuse_set) {
                        ap_rprintf(r,
                                   "      <httpd:disablereuse>%s</httpd:disablereuse>\n",
                                   (worker->s->disablereuse ? "On" : "Off"));
                    }
                    if (worker->s->conn_timeout_set) {
                        ap_rprintf(r,
                                   "          <httpd:connectiontimeout>%" APR_TIME_T_FMT "</httpd:connectiontimeout>\n",
                                   apr_time_msec(worker->s->conn_timeout));
                    }
                    if (worker->s->retry_set) {
                        ap_rprintf(r,
                                   "          <httpd:retry>%" APR_TIME_T_FMT "</httpd:retry>\n",
                                   apr_time_sec(worker->s->retry));
                    }
                    ap_rputs("        </httpd:worker>\n", r);
                    ++workers;
                }
                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; charset=ISO-8859-1");
            ap_rputs(DOCTYPE_HTML_3_2
                     "<html><head><title>Balancer Manager</title>\n", r);
            ap_rputs("<style type='text/css'>\n"
                     "table {\n"
                     " border-width: 1px;\n"
                     " border-spacing: 3px;\n"
                     " border-style: solid;\n"
                     " border-color: gray;\n"
                     " border-collapse: collapse;\n"
                     " background-color: white;\n"
                     " text-align: center;\n"
                     "}\n"
                     "th {\n"
                     " border-width: 1px;\n"
                     " padding: 2px;\n"
                     " border-style: dotted;\n"
                     " border-color: gray;\n"
                     " background-color: lightgray;\n"
                     " text-align: center;\n"
                     "}\n"
                     "td {\n"
                     " border-width: 1px;\n"
                     " padding: 2px;\n"
                     " border-style: dotted;\n"
                     " border-color: gray;\n"
                     " background-color: white;\n"
                     " text-align: center;\n"
                     "}\n"
                     "</style>\n</head>\n", r);
            ap_rputs("<body><h1>Load Balancer Manager for ", r);
            ap_rvputs(r, ap_escape_html(r->pool, ap_get_server_name(r)),
                      "</h1>\n\n", NULL);
            ap_rvputs(r, "<dl><dt>Server Version: ",
                      ap_get_server_description(), "</dt>\n", NULL);
            ap_rvputs(r, "<dt>Server Built: ",
                      ap_get_server_built(), "</dt>\n", NULL);
            ap_rvputs(r, "<dt>Balancer changes will ", conf->bal_persist ? "" : "NOT ",
                      "be persisted on restart.</dt>", NULL);
            ap_rvputs(r, "<dt>Balancers are ", conf->inherit ? "" : "NOT ",
                      "inherited from main server.</dt>", NULL);
            ap_rvputs(r, "<dt>ProxyPass settings are ", conf->ppinherit ? "" : "NOT ",
                      "inherited from main server.</dt>", NULL);
            ap_rputs("</dl>\n", r);
            balancer = (proxy_balancer *)conf->balancers->elts;
            for (i = 0; i < conf->balancers->nelts; i++) {
    
                ap_rputs("<hr />\n<h3>LoadBalancer Status for ", r);
                ap_rvputs(r, "<a href=\"", ap_escape_uri(r->pool, r->uri), "?b=",
                          balancer->s->name + sizeof(BALANCER_PREFIX) - 1,
                          "&amp;nonce=", balancer->s->nonce,
                          "\">", NULL);
                ap_rvputs(r, balancer->s->name, "</a> [",balancer->s->sname, "]</h3>\n", NULL);
                ap_rputs("\n\n<table><tr>"
                    "<th>MaxMembers</th><th>StickySession</th><th>DisableFailover</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>"
                    "<th>Path</th><th>Active</th></tr>\n<tr>", r);
                /* the below is a safe cast, since the number of slots total will
                 * never be more than max_workers, which is restricted to int */
                ap_rprintf(r, "<td>%d [%d Used]</td>\n", balancer->max_workers,
                           balancer->max_workers - (int)storage->num_free_slots(balancer->wslot));
                if (*balancer->s->sticky) {
                    if (strcmp(balancer->s->sticky, balancer->s->sticky_path)) {
                        ap_rvputs(r, "<td>", ap_escape_html(r->pool, balancer->s->sticky), "|",
                                  ap_escape_html(r->pool, balancer->s->sticky_path), NULL);
                    }
                    else {
                        ap_rvputs(r, "<td>", ap_escape_html(r->pool, balancer->s->sticky), NULL);
                    }
                }
                else {
                    ap_rputs("<td> (None) ", r);
                }
                ap_rprintf(r, "</td><td>%s</td>\n",
                           balancer->s->sticky_force ? "On" : "Off");
                ap_rprintf(r, "<td>%" APR_TIME_T_FMT "</td>",
                    apr_time_sec(balancer->s->timeout));
                ap_rprintf(r, "<td>%d</td>\n", balancer->s->max_attempts);
                ap_rprintf(r, "<td>%s</td>\n",
                           balancer->s->lbpname);
                ap_rputs("<td>", r);
                if (*balancer->s->vhost) {
                    ap_rvputs(r, balancer->s->vhost, " -> ", NULL);
                }
                ap_rvputs(r, balancer->s->vpath, "</td>\n", NULL);
                ap_rprintf(r, "<td>%s</td>\n",
                           !balancer->s->inactive ? "Yes" : "No");
                ap_rputs("</tr>\n</table>\n<br />", r);
                ap_rputs("\n\n<table><tr>"
                    "<th>Worker URL</th>"
                    "<th>Route</th><th>RouteRedir</th>"
                    "<th>Factor</th><th>Set</th><th>Status</th>"
                    "<th>Elected</th><th>Busy</th><th>Load</th><th>To</th><th>From</th>", r);
                if (set_worker_hc_param_f) {
                    ap_rputs("<th>HC Method</th><th>HC Interval</th><th>Passes</th><th>Fails</th><th>HC uri</th><th>HC Expr</th>", r);
                }
                ap_rputs("</tr>\n", r);
    
                workers = (proxy_worker **)balancer->workers->elts;
                for (n = 0; n < balancer->workers->nelts; n++) {
                    char fbuf[50];
                    worker = *workers;
                    ap_rvputs(r, "<tr>\n<td><a href=\"",
                              ap_escape_uri(r->pool, r->uri), "?b=",
                              balancer->s->name + sizeof(BALANCER_PREFIX) - 1, "&amp;w=",
                              ap_escape_uri(r->pool, worker->s->name_ex),
                              "&amp;nonce=", balancer->s->nonce,
                              "\">", NULL);
                    ap_rvputs(r, (*worker->s->uds_path ? "<i>" : ""), ap_proxy_worker_name(r->pool, worker),
                              (*worker->s->uds_path ? "</i>" : ""), "</a></td>", NULL);
                    ap_rvputs(r, "<td>", ap_escape_html(r->pool, worker->s->route),
                              NULL);
                    ap_rvputs(r, "</td><td>",
                              ap_escape_html(r->pool, worker->s->redirect), NULL);
                    ap_rprintf(r, "</td><td>%.2f</td>", (float)(worker->s->lbfactor)/100.0);
                    ap_rprintf(r, "<td>%d</td><td>", worker->s->lbset);
                    ap_rvputs(r, ap_proxy_parse_wstatus(r->pool, worker), NULL);
                    ap_rputs("</td>", r);
                    ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td>", worker->s->elected);
                    ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td>", worker->s->busy);
                    ap_rprintf(r, "<td>%d</td><td>", worker->s->lbstatus);
                    ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
                    ap_rputs("</td><td>", r);
                    ap_rputs(apr_strfsize(worker->s->read, fbuf), r);
                    if (set_worker_hc_param_f) {
                        ap_rprintf(r, "</td><td>%s</td>", ap_proxy_show_hcmethod(worker->s->method));
                        ap_rprintf(r, "<td>%" APR_TIME_T_FMT "ms</td>", apr_time_as_msec(worker->s->interval));
                        ap_rprintf(r, "<td>%d (%d)</td>", worker->s->passes,worker->s->pcount);
                        ap_rprintf(r, "<td>%d (%d)</td>", worker->s->fails, worker->s->fcount);
                        ap_rprintf(r, "<td>%s</td>", ap_escape_html(r->pool, worker->s->hcuri));
                        ap_rprintf(r, "<td>%s", worker->s->hcexpr);
                    }
                    ap_rputs("</td></tr>\n", r);
    
                    ++workers;
                }
                ap_rputs("</table>\n", r);
                ++balancer;
            }
            ap_rputs("<hr />\n", r);
            if (hc_show_exprs_f) {
                hc_show_exprs_f(r);
            }
            if (wsel && bsel) {
                ap_rputs("<h3>Edit worker settings for ", r);
                ap_rvputs(r, (*wsel->s->uds_path?"<i>":""), ap_proxy_worker_name(r->pool, wsel), (*wsel->s->uds_path?"</i>":""), "</h3>\n", NULL);
                ap_rputs("<form method='POST' enctype='application/x-www-form-urlencoded' action=\"", r);
                ap_rvputs(r, ap_escape_uri(r->pool, action), "\">\n", NULL);
                ap_rputs("<table><tr><td>Load factor:</td><td><input name='w_lf' id='w_lf' type=text ", r);
                ap_rprintf(r, "value='%.2f'></td></tr>\n", (float)(wsel->s->lbfactor)/100.0);
                ap_rputs("<tr><td>LB Set:</td><td><input name='w_ls' id='w_ls' type=text ", r);
                ap_rprintf(r, "value='%d'></td></tr>\n", wsel->s->lbset);
                ap_rputs("<tr><td>Route:</td><td><input name='w_wr' id='w_wr' type=text ", r);
                ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->route),
                          NULL);
                ap_rputs("\"></td></tr>\n", r);
                ap_rputs("<tr><td>Route Redirect:</td><td><input name='w_rr' id='w_rr' type=text ", r);
                ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->redirect),
                          NULL);
                ap_rputs("\"></td></tr>\n", r);
                ap_rputs("<tr><td>Status:</td>", r);
                ap_rputs("<td><table><tr>"
                         "<th>Ignore Errors</th>"
                         "<th>Draining Mode</th>"
                         "<th>Disabled</th>"
                         "<th>Hot Standby</th>"
                         "<th>Hot Spare</th>", r);
                if (hc_show_exprs_f) {
                    ap_rputs("<th>HC Fail</th>", r);
                }
                ap_rputs("<th>Stopped</th></tr>\n<tr>", r);
                create_radio("w_status_I", (PROXY_WORKER_IS(wsel, PROXY_WORKER_IGNORE_ERRORS)), r);
                create_radio("w_status_N", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DRAIN)), r);
                create_radio("w_status_D", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DISABLED)), r);
                create_radio("w_status_H", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HOT_STANDBY)), r);
                create_radio("w_status_R", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HOT_SPARE)), r);
                if (hc_show_exprs_f) {
                    create_radio("w_status_C", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HC_FAIL)), r);
                }
                create_radio("w_status_S", (PROXY_WORKER_IS(wsel, PROXY_WORKER_STOPPED)), r);
                ap_rputs("</tr></table></td></tr>\n", r);
                if (hc_select_exprs_f) {
                    proxy_hcmethods_t *method = proxy_hcmethods;
                    ap_rputs("<tr><td colspan='2'>\n<table align='center'><tr><th>Health Check param</th><th>Value</th></tr>\n", r);
                    ap_rputs("<tr><td>Method</td><td><select name='w_hm'>\n", r);
                    for (; method->name; method++) {
                        if (method->implemented) {
                            ap_rprintf(r, "<option value='%s' %s >%s</option>\n",
                                    method->name,
                                    (wsel->s->method == method->method) ? "selected" : "",
                                    method->name);
                        }
                    }
                    ap_rputs("</select>\n</td></tr>\n", r);
                    ap_rputs("<tr><td>Expr</td><td><select name='w_he'>\n", r);
                    hc_select_exprs_f(r, wsel->s->hcexpr);
                    ap_rputs("</select>\n</td></tr>\n", r);
                    ap_rprintf(r, "<tr><td>Interval (ms)</td><td><input name='w_hi' id='w_hi' type='text' "
                               "value='%" APR_TIME_T_FMT "'></td></tr>\n", apr_time_as_msec(wsel->s->interval));
                    ap_rprintf(r, "<tr><td>Passes trigger</td><td><input name='w_hp' id='w_hp' type='text' "
                               "value='%d'></td></tr>\n", wsel->s->passes);
                    ap_rprintf(r, "<tr><td>Fails trigger)</td><td><input name='w_hf' id='w_hf' type='text' "
                               "value='%d'></td></tr>\n", wsel->s->fails);
                    ap_rprintf(r, "<tr><td>HC uri</td><td><input name='w_hu' id='w_hu' type='text' "
                               "value=\"%s\"></td></tr>\n", ap_escape_html(r->pool, wsel->s->hcuri));
                    ap_rputs("</table>\n</td></tr>\n", r);
                }
                ap_rputs("<tr><td colspan='2'><input type=submit value='Submit'></td></tr>\n", r);
                ap_rvputs(r, "</table>\n<input type=hidden name='w' id='w' ",  NULL);
                ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->s->name_ex), "\">\n", NULL);
                ap_rvputs(r, "<input type=hidden name='b' id='b' ", NULL);
                ap_rvputs(r, "value=\"", ap_escape_html(r->pool, bsel->s->name + sizeof(BALANCER_PREFIX) - 1),
                          "\">\n", NULL);
                ap_rvputs(r, "<input type=hidden name='nonce' id='nonce' value='",
                          bsel->s->nonce, "'>\n", NULL);
                ap_rputs("</form>\n", r);
                ap_rputs("<hr />\n", r);
            } else if (bsel) {
                const apr_array_header_t *provs;
                const ap_list_provider_names_t *pname;
                int i;
                ap_rputs("<h3>Edit balancer settings for ", r);
                ap_rvputs(r, ap_escape_html(r->pool, bsel->s->name), "</h3>\n", NULL);
                ap_rputs("<form method='POST' enctype='application/x-www-form-urlencoded' action=\"", r);
                ap_rvputs(r, ap_escape_uri(r->pool, action), "\">\n", NULL);
                ap_rputs("<table>\n", r);
                provs = ap_list_provider_names(r->pool, PROXY_LBMETHOD, "0");
                if (provs) {
                    ap_rputs("<tr><td>LBmethod:</td>", r);
                    ap_rputs("<td>\n<select name='b_lbm' id='b_lbm'>", r);
                    pname = (ap_list_provider_names_t *)provs->elts;
                    for (i = 0; i < provs->nelts; i++, pname++) {
                        ap_rvputs(r,"<option value='", pname->provider_name, "'", NULL);
                        if (strcmp(pname->provider_name, bsel->s->lbpname) == 0)
                            ap_rputs(" selected ", r);
                        ap_rvputs(r, ">", pname->provider_name, "\n", NULL);
                    }
                    ap_rputs("</select>\n</td></tr>\n", r);
                }
                ap_rputs("<tr><td>Timeout:</td><td><input name='b_tmo' id='b_tmo' type=text ", r);
                ap_rprintf(r, "value='%" APR_TIME_T_FMT "'></td></tr>\n", apr_time_sec(bsel->s->timeout));
                ap_rputs("<tr><td>Failover Attempts:</td><td><input name='b_max' id='b_max' type=text ", r);
                ap_rprintf(r, "value='%d'></td></tr>\n", bsel->s->max_attempts);
                ap_rputs("<tr><td>Disable Failover:</td>", r);
                create_radio("b_sforce", bsel->s->sticky_force, r);
                ap_rputs("</tr>\n", r);
                ap_rputs("<tr><td>Sticky Session:</td><td><input name='b_ss' id='b_ss' size=64 type=text ", r);
                if (strcmp(bsel->s->sticky, bsel->s->sticky_path)) {
                    ap_rvputs(r, "value =\"", ap_escape_html(r->pool, bsel->s->sticky), "|",
                              ap_escape_html(r->pool, bsel->s->sticky_path), NULL);
                }
                else {
                    ap_rvputs(r, "value =\"", ap_escape_html(r->pool, bsel->s->sticky), NULL);
                }
                ap_rputs("\">&nbsp;&nbsp;&nbsp;&nbsp;(Use '-' to delete)</td></tr>\n", r);
                if (storage->num_free_slots(bsel->wslot) != 0) {
                    ap_rputs("<tr><td>Add New Worker:</td><td><input name='b_nwrkr' id='b_nwrkr' size=32 type=text>"
                             "&nbsp;&nbsp;&nbsp;&nbsp;Are you sure? <input name='b_wyes' id='b_wyes' type=checkbox value='1'>"
                             "</td></tr>", r);
                }
                ap_rputs("<tr><td colspan=2><input type=submit value='Submit'></td></tr>\n", r);
                ap_rvputs(r, "</table>\n<input type=hidden name='b' id='b' ", NULL);
                ap_rvputs(r, "value=\"", ap_escape_html(r->pool, bsel->s->name + sizeof(BALANCER_PREFIX) - 1),
                          "\">\n", NULL);
                ap_rvputs(r, "<input type=hidden name='nonce' id='nonce' value='",
                          bsel->s->nonce, "'>\n", NULL);
                ap_rputs("</form>\n", r);
                ap_rputs("<hr />\n", r);
            }
            ap_rputs(ap_psignature("",r), r);
            ap_rputs("</body></html>\n", r);
            ap_rflush(r);
        }
    }
    
    /* Manages the loadfactors and member status
     *   The balancer, worker and nonce are obtained from
     *   the request args (?b=...&w=...&nonce=....).
     *   All other params are pulled from any POST
     *   data that exists.
     * TODO:
     *   /.../<whatever>/balancer/worker/nonce
     */
    static int balancer_handler(request_rec *r)
    {
        void *sconf;
        proxy_server_conf *conf;
        proxy_balancer *balancer, *bsel = NULL;
        proxy_worker *wsel = NULL;
        apr_table_t *params;
        int i;
        const char *name, *ref;
        apr_status_t rv;
    
        /* is this for us? */
        if (strcmp(r->handler, "balancer-manager")) {
            return DECLINED;
        }
    
        r->allowed = 0
        | (AP_METHOD_BIT << M_GET)
        | (AP_METHOD_BIT << M_POST);
        if ((r->method_number != M_GET) && (r->method_number != M_POST)) {
            return DECLINED;
        }
    
        sconf = r->server->module_config;
        conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
        params = apr_table_make(r->pool, 10);
    
        balancer = (proxy_balancer *)conf->balancers->elts;
        for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
    #if APR_HAS_THREADS
            if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01189)
                              "%s: Lock failed for balancer_handler",
                              balancer->s->name);
            }
    #endif
            ap_proxy_sync_balancer(balancer, r->server, conf);
    #if APR_HAS_THREADS
            if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01190)
                              "%s: Unlock failed for balancer_handler",
                              balancer->s->name);
            }
    #endif
        }
    
        if (r->args && (r->method_number == M_GET)) {
            const char *allowed[] = { "w", "b", "nonce", "xml", NULL };
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01191) "parsing r->args");
    
            push2table(r->args, params, allowed, r->pool);
        }
        if (r->method_number == M_POST) {
            apr_bucket_brigade *ib;
            apr_size_t len = 1024;
            char *buf = apr_pcalloc(r->pool, len+1);
    
            ib = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
            rv = ap_get_brigade(r->input_filters, ib, AP_MODE_READBYTES,
                                    APR_BLOCK_READ, len);
            if (rv != APR_SUCCESS) {
                return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
            }
            apr_brigade_flatten(ib, buf, &len);
            buf[len] = '\0';
            push2table(buf, params, NULL, r->pool);
        }
    
        /* Ignore parameters if this looks like XSRF */
        ref = apr_table_get(r->headers_in, "Referer");
        if (apr_table_elts(params)
            && (!ref || !safe_referer(r, ref))) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10187)
                          "ignoring params in balancer-manager cross-site access %s: %s", ref, ap_get_server_name(r));
            apr_table_clear(params);
        }
    
        /* Process the parameters */
        if ((name = apr_table_get(params, "b")))
            bsel = ap_proxy_get_balancer(r->pool, conf,
                apr_pstrcat(r->pool, BALANCER_PREFIX, name, NULL), 0);
    
        if ((name = apr_table_get(params, "w"))) {
            wsel = ap_proxy_get_worker(r->pool, bsel, conf, name);
        }
    
    
        /* Check that the supplied nonce matches this server's nonce;
         * otherwise ignore all parameters, to prevent a CSRF
         * attack. */
        if (bsel
            && (*bsel->s->nonce
                && ((name = apr_table_get(params, "nonce")) != NULL
                    && strcmp(bsel->s->nonce, name) == 0))) {
            /* Process the parameters and add the worker to the balancer */
            rv = balancer_process_balancer_worker(r, conf, bsel, wsel, params);
            if (rv != APR_SUCCESS) {
                return HTTP_BAD_REQUEST;
            }
        }
    
        /* display the HTML or XML page */
        if (apr_table_get(params, "xml")) {
            balancer_display_page(r, conf, bsel, wsel, 1);
        } else {
            balancer_display_page(r, conf, bsel, wsel, 0);
        }
        return DONE;
    }
    
    static void balancer_child_init(apr_pool_t *p, server_rec *s)
    {
        while (s) {
            proxy_balancer *balancer;
            int i;
            void *sconf = s->module_config;
            proxy_server_conf *conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
            apr_status_t rv;
    
            if (conf->balancers->nelts) {
                apr_size_t size;
                unsigned int num;
                storage->attach(&(conf->bslot), conf->id, &size, &num, p);
                if (!conf->bslot) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01205) "slotmem_attach failed");
                    exit(1); /* Ugly, but what else? */
                }
            }
    
            balancer = (proxy_balancer *)conf->balancers->elts;
            for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
                rv = ap_proxy_initialize_balancer(balancer, s, p);
    
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(01206)
                                 "Failed to init balancer %s in child",
                                 balancer->s->name);
                    exit(1); /* Ugly, but what else? */
                }
                init_balancer_members(p, s, 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
         */
        static const char *const aszPred[] = { "mpm_winnt.c", "mod_slotmem_shm.c", NULL};
        static const char *const aszPred2[] = { "mod_proxy.c", NULL};
         /* manager handler */
        APR_REGISTER_OPTIONAL_FN(balancer_manage);
        ap_hook_post_config(balancer_post_config, aszPred2, NULL, APR_HOOK_MIDDLE);
        ap_hook_pre_config(balancer_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(balancer_handler, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_child_init(balancer_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);
    }
    
    AP_DECLARE_MODULE(proxy_balancer) = {
        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 */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy.c��������������������������������������������������������������0000664�0001751�0001751�00000375156�14721076174�017671� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "mod_core.h"
    #include "apr_optional.h"
    #include "apr_strings.h"
    #include "scoreboard.h"
    #include "mod_status.h"
    #include "proxy_util.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_engine_set, (conn_rec *,
                                                  ap_conf_vector_t *,
                                                  int proxy, int enable));
    #endif
    
    #ifndef MAX
    #define MAX(x,y) ((x) >= (y) ? (x) : (y))
    #endif
    
    /*
     * We do health-checks only if that (sub)module is loaded in. This
     * allows for us to continue as is w/o requiring mod_watchdog for
     * those implementations which aren't using health checks
     */
    static APR_OPTIONAL_FN_TYPE(set_worker_hc_param) *set_worker_hc_param_f = NULL;
    
    /* Externals */
    proxy_hcmethods_t PROXY_DECLARE_DATA proxy_hcmethods[] = {
        {NONE, "NONE", 1},
        {TCP, "TCP", 1},
        {OPTIONS, "OPTIONS", 1},
        {HEAD, "HEAD", 1},
        {GET, "GET", 1},
        {CPING, "CPING", 0},
        {PROVIDER, "PROVIDER", 0},
        {OPTIONS11, "OPTIONS11", 1},
        {HEAD11, "HEAD11", 1},
        {GET11, "GET11", 1},
        {EOT, NULL, 1}
    };
    
    proxy_wstat_t PROXY_DECLARE_DATA proxy_wstat_tbl[] = {
        {PROXY_WORKER_INITIALIZED,   PROXY_WORKER_INITIALIZED_FLAG,   "Init "},
        {PROXY_WORKER_IGNORE_ERRORS, PROXY_WORKER_IGNORE_ERRORS_FLAG, "Ign "},
        {PROXY_WORKER_DRAIN,         PROXY_WORKER_DRAIN_FLAG,         "Drn "},
        {PROXY_WORKER_GENERIC,       PROXY_WORKER_GENERIC_FLAG,       "Gen "},
        {PROXY_WORKER_IN_SHUTDOWN,   PROXY_WORKER_IN_SHUTDOWN_FLAG,   "Shut "},
        {PROXY_WORKER_DISABLED,      PROXY_WORKER_DISABLED_FLAG,      "Dis "},
        {PROXY_WORKER_STOPPED,       PROXY_WORKER_STOPPED_FLAG,       "Stop "},
        {PROXY_WORKER_IN_ERROR,      PROXY_WORKER_IN_ERROR_FLAG,      "Err "},
        {PROXY_WORKER_HOT_STANDBY,   PROXY_WORKER_HOT_STANDBY_FLAG,   "Stby "},
        {PROXY_WORKER_HOT_SPARE,     PROXY_WORKER_HOT_SPARE_FLAG,     "Spar "},
        {PROXY_WORKER_FREE,          PROXY_WORKER_FREE_FLAG,          "Free "},
        {PROXY_WORKER_HC_FAIL,       PROXY_WORKER_HC_FAIL_FLAG,       "HcFl "},
        {0x0, '\0', NULL}
    };
    
    static const char * const proxy_id = "proxy";
    apr_global_mutex_t *proxy_mutex = NULL;
    
    /*
     * 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.
     *  fix_ups:        convert the URL stored in the filename to the
     *                  canonical form.
     *  handler:        handle proxy requests
     */
    
    /* -------------------------------------------------------------- */
    /* Translate the URL into a 'filename' */
    
    static const char *set_worker_param(apr_pool_t *p,
                                        server_rec *s,
                                        proxy_worker *worker,
                                        const char *key,
                                        const char *val)
    {
    
        int ival;
        apr_interval_time_t timeout;
    
        if (!strcasecmp(key, "loadfactor")) {
            /* Normalized load factor. Used with BalancerMember,
             * it is a number between 1 and 100.
             */
            double fval = atof(val);
            ival = fval * 100.0;
            if (ival < 100 || ival > 10000)
                return "LoadFactor must be a number between 1..100";
            worker->s->lbfactor = ival;
        }
        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 < 0)
                return "Retry must be a positive value";
            worker->s->retry = apr_time_from_sec(ival);
            worker->s->retry_set = 1;
        }
        else if (!strcasecmp(key, "ttl")) {
            /* Time in seconds that will destroy all the connections
             * that exceed the smax
             */
            ival = atoi(val);
            if (ival < 1)
                return "TTL must be at least one second";
            worker->s->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->s->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->s->hmax = ival;
        }
        /* XXX: More intelligent 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->s->smax = ival;
        }
        else if (!strcasecmp(key, "acquire")) {
            /* Acquire timeout in given unit (default is milliseconds).
             * If set this will be the maximum time to
             * wait for a free connection.
             */
            if (ap_timeout_parameter_parse(val, &timeout, "ms") != APR_SUCCESS)
                return "Acquire timeout has wrong format";
            if (timeout < 1000)
                return "Acquire must be at least one millisecond";
            worker->s->acquire = timeout;
            worker->s->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->s->timeout = apr_time_from_sec(ival);
            worker->s->timeout_set = 1;
        }
        else if (!strcasecmp(key, "iobuffersize")) {
            long s = atol(val);
            if (s < 512 && s) {
                return "IOBufferSize must be >= 512 bytes, or 0 for system default.";
            }
            worker->s->io_buffer_size = (s ? s : AP_IOBUFSIZE);
            worker->s->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->s->recv_buffer_size = ival;
            worker->s->recv_buffer_size_set = 1;
        }
        else if (!strcasecmp(key, "keepalive")) {
            if (!strcasecmp(val, "on"))
                worker->s->keepalive = 1;
            else if (!strcasecmp(val, "off"))
                worker->s->keepalive = 0;
            else
                return "KeepAlive must be On|Off";
            worker->s->keepalive_set = 1;
        }
        else if (!strcasecmp(key, "disablereuse")) {
            if (!strcasecmp(val, "on"))
                worker->s->disablereuse = 1;
            else if (!strcasecmp(val, "off"))
                worker->s->disablereuse = 0;
            else
                return "DisableReuse must be On|Off";
            worker->s->disablereuse_set = 1;
        }
        else if (!strcasecmp(key, "enablereuse")) {
            if (!strcasecmp(val, "on"))
                worker->s->disablereuse = 0;
            else if (!strcasecmp(val, "off"))
                worker->s->disablereuse = 1;
            else
                return "EnableReuse must be On|Off";
            worker->s->disablereuse_set = 1;
        }
        else if (!strcasecmp(key, "addressttl")) {
            /* Address TTL in seconds
             */
            apr_interval_time_t ttl;
            if (strcmp(val, "-1") == 0) {
                worker->s->address_ttl = -1;
            }
            else if (ap_timeout_parameter_parse(val, &ttl, "s") == APR_SUCCESS
                     && (ttl <= apr_time_from_sec(APR_INT32_MAX))
                     && (ttl % apr_time_from_sec(1)) == 0) {
                worker->s->address_ttl = apr_time_sec(ttl);
            }
            else {
                return "AddressTTL must be -1 or a number of seconds not "
                       "exceeding " APR_STRINGIFY(APR_INT32_MAX);
            }
            worker->s->address_ttl_set = 1;
        }
        else if (!strcasecmp(key, "route")) {
            /* Worker route.
             */
            if (strlen(val) >= sizeof(worker->s->route))
                return apr_psprintf(p, "Route length must be < %d characters",
                        (int)sizeof(worker->s->route));
            PROXY_STRNCPY(worker->s->route, val);
        }
        else if (!strcasecmp(key, "redirect")) {
            /* Worker redirection route.
             */
            if (strlen(val) >= sizeof(worker->s->redirect))
                return apr_psprintf(p, "Redirect length must be < %d characters",
                        (int)sizeof(worker->s->redirect));
            PROXY_STRNCPY(worker->s->redirect, val);
        }
        else if (!strcasecmp(key, "status")) {
            const char *v;
            int mode = 1;
            apr_status_t rv;
            /* Worker status.
             */
            for (v = val; *v; v++) {
                if (*v == '+') {
                    mode = 1;
                    v++;
                }
                else if (*v == '-') {
                    mode = 0;
                    v++;
                }
                rv = ap_proxy_set_wstatus(*v, mode, worker);
                if (rv != APR_SUCCESS)
                    return "Unknown status parameter option";
            }
        }
        else if (!strcasecmp(key, "flushpackets")) {
            if (!strcasecmp(val, "on"))
                worker->s->flush_packets = flush_on;
            else if (!strcasecmp(val, "off"))
                worker->s->flush_packets = flush_off;
            else if (!strcasecmp(val, "auto"))
                worker->s->flush_packets = flush_auto;
            else
                return "flushpackets must be on|off|auto";
        }
        else if (!strcasecmp(key, "flushwait")) {
            ival = atoi(val);
            if (ival > 1000 || ival < 0) {
                return "flushwait must be <= 1000, or 0 for system default of 10 millseconds.";
            }
            if (ival == 0)
                worker->s->flush_wait = PROXY_FLUSH_WAIT;
            else
                worker->s->flush_wait = ival * 1000;    /* change to microseconds */
        }
        else if (!strcasecmp(key, "ping")) {
            /* Ping/Pong timeout in given unit (default is second).
             */
            if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)
                return "Ping/Pong timeout has wrong format";
            if (timeout < 1000)
                return "Ping/Pong timeout must be at least one millisecond";
            worker->s->ping_timeout = timeout;
            worker->s->ping_timeout_set = 1;
        }
        else if (!strcasecmp(key, "lbset")) {
            ival = atoi(val);
            if (ival < 0 || ival > 99)
                return "lbset must be between 0 and 99";
            worker->s->lbset = ival;
        }
        else if (!strcasecmp(key, "connectiontimeout")) {
            /* Request timeout in given unit (default is second).
             * Defaults to connection timeout
             */
            if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)
                return "Connectiontimeout has wrong format";
            if (timeout < 1000)
                return "Connectiontimeout must be at least one millisecond.";
            worker->s->conn_timeout = timeout;
            worker->s->conn_timeout_set = 1;
        }
        else if (!strcasecmp(key, "flusher")) {
            if (PROXY_STRNCPY(worker->s->flusher, val) != APR_SUCCESS) {
                return apr_psprintf(p, "flusher name length must be < %d characters",
                                    (int)sizeof(worker->s->flusher));
            }
        }
        else if (!strcasecmp(key, "upgrade")) {
            if (PROXY_STRNCPY(worker->s->upgrade,
                              strcasecmp(val, "ANY") ? val : "*") != APR_SUCCESS) {
                return apr_psprintf(p, "upgrade protocol length must be < %d characters",
                                    (int)sizeof(worker->s->upgrade));
            }
        }
        else if (!strcasecmp(key, "responsefieldsize")) {
            long s = atol(val);
            if (s < 0) {
                return "ResponseFieldSize must be greater than 0 bytes, or 0 for system default.";
            }
            worker->s->response_field_size = (s ? s : HUGE_STRING_LEN);
            worker->s->response_field_size_set = 1;
        }
        else if (!strcasecmp(key, "secret")) {
            if (PROXY_STRNCPY(worker->s->secret, val) != APR_SUCCESS) {
                return apr_psprintf(p, "Secret length must be < %d characters",
                                    (int)sizeof(worker->s->secret));
            }
        }
        else {
            if (set_worker_hc_param_f) {
                return set_worker_hc_param_f(p, s, worker, key, val, NULL);
            } else {
                return "unknown Worker parameter";
            }
        }
        return NULL;
    }
    
    static const char *set_balancer_param(proxy_server_conf *conf,
                                          apr_pool_t *p,
                                          proxy_balancer *balancer,
                                          const char *key,
                                          const char *val)
    {
    
        int ival;
        if (!strcasecmp(key, "stickysession")) {
            char *path;
            /* Balancer sticky session name.
             * Set to something like JSESSIONID or
             * PHPSESSIONID, etc..,
             */
            if (strlen(val) >= sizeof(balancer->s->sticky_path))
                apr_psprintf(p, "stickysession length must be < %d characters",
                        (int)sizeof(balancer->s->sticky_path));
            PROXY_STRNCPY(balancer->s->sticky_path, val);
            PROXY_STRNCPY(balancer->s->sticky, val);
    
            if ((path = strchr((char *)balancer->s->sticky, '|'))) {
                *path++ = '\0';
                PROXY_STRNCPY(balancer->s->sticky_path, path);
            }
        }
        else if (!strcasecmp(key, "stickysessionsep")) {
            /* separator/delimiter for sessionid and route,
             * normally '.'
             */
            if (strlen(val) != 1) {
                if (!strcasecmp(val, "off"))
                    balancer->s->sticky_separator = 0;
                else      
                    return "stickysessionsep must be a single character or Off";
            }
            else
                balancer->s->sticky_separator = *val;
            balancer->s->sticky_separator_set = 1;
        }
        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->s->sticky_force = 1;
            else if (!strcasecmp(val, "off"))
                balancer->s->sticky_force = 0;
            else
                return "failover must be On|Off";
            balancer->s->sticky_force_set = 1;
        }
        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->s->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->s->max_attempts = ival;
            balancer->s->max_attempts_set = 1;
        }
        else if (!strcasecmp(key, "lbmethod")) {
            proxy_balancer_method *provider;
            if (strlen(val) > (sizeof(balancer->s->lbpname)-1))
                return "unknown lbmethod";
            provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
            if (provider) {
                balancer->lbmethod = provider;
                if (PROXY_STRNCPY(balancer->s->lbpname, val) == APR_SUCCESS) {
                    balancer->lbmethod_set = 1;
                    return NULL;
                }
                else {
                    return "lbmethod name too large";
                }
            }
            return "unknown lbmethod";
        }
        else if (!strcasecmp(key, "scolonpathdelim")) {
            /* If set to 'on' then ';' will also be
             * used as a session path separator/delim (ala
             * mod_jk)
             */
            if (!strcasecmp(val, "on"))
                balancer->s->scolonsep = 1;
            else if (!strcasecmp(val, "off"))
                balancer->s->scolonsep = 0;
            else
                return "scolonpathdelim must be On|Off";
            balancer->s->scolonsep_set = 1;
        }
        else if (!strcasecmp(key, "failonstatus")) {
            char *val_split;
            char *status;
            char *tok_state;
    
            val_split = apr_pstrdup(p, val);
    
            balancer->errstatuses = apr_array_make(p, 1, sizeof(int));
    
            status = apr_strtok(val_split, ", ", &tok_state);
            while (status != NULL) {
                ival = atoi(status);
                if (ap_is_HTTP_VALID_RESPONSE(ival)) {
                    *(int *)apr_array_push(balancer->errstatuses) = ival;
                }
                else {
                    return "failonstatus must be one or more HTTP response codes";
                }
                status = apr_strtok(NULL, ", ", &tok_state);
            }
    
        }
        else if (!strcasecmp(key, "failontimeout")) {
            if (!strcasecmp(val, "on"))
                balancer->failontimeout = 1;
            else if (!strcasecmp(val, "off"))
                balancer->failontimeout = 0;
            else
                return "failontimeout must be On|Off";
            balancer->failontimeout_set = 1;
        }
        else if (!strcasecmp(key, "nonce")) {
            if (!strcasecmp(val, "None")) {
                *balancer->s->nonce = '\0';
            }
            else {
                if (PROXY_STRNCPY(balancer->s->nonce, val) != APR_SUCCESS) {
                    return "Provided nonce is too large";
                }
            }
            balancer->s->nonce_set = 1;
        }
        else if (!strcasecmp(key, "growth")) {
            ival = atoi(val);
            if (ival < 1 || ival > 100)   /* arbitrary limit here */
                return "growth must be between 1 and 100";
            balancer->growth = ival;
            balancer->growth_set = 1;
        }
        else if (!strcasecmp(key, "forcerecovery")) {
            if (!strcasecmp(val, "on"))
                balancer->s->forcerecovery = 1;
            else if (!strcasecmp(val, "off"))
                balancer->s->forcerecovery = 0;
            else
                return "forcerecovery must be On|Off";
            balancer->s->forcerecovery_set = 1;
        }
        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;
    }
    
    /*
     * Inspired by mod_jk's jk_servlet_normalize().
     */
    static int alias_match_servlet(apr_pool_t *p,
                                   const char **urip,
                                   const char *alias)
    {
        char *map;
        const char *uri = *urip;
        apr_array_header_t *stack;
        int map_pos, uri_pos, alias_pos, first_pos;
        int alias_depth = 0, depth;
    
        /* Both uri and alias should start with '/' */
        if (uri[0] != '/' || alias[0] != '/') {
            return 0;
        }
    
        stack = apr_array_make(p, 5, sizeof(int));
        map = apr_palloc(p, strlen(uri) + 1);
        map[0] = '/';
        map[1] = '\0';
    
        map_pos = uri_pos = alias_pos = first_pos = 1;
        while (uri[uri_pos] != '\0') {
            /* Remove path parameters ;foo=bar/ from any path segment */
            if (uri[uri_pos] == ';') {
                do {
                    uri_pos++;
                } while (uri[uri_pos] != '/' && uri[uri_pos] != '\0');
                continue;
            }
    
            if (map[map_pos - 1] == '/') {
                /* Collapse ///// sequences to / */
                if (uri[uri_pos] == '/') {
                    do {
                        uri_pos++;
                    } while (uri[uri_pos] == '/');
                    continue;
                }
    
                if (uri[uri_pos] == '.') {
                    /* Remove /./ segments */
                    if (uri[uri_pos + 1] == '/'
                            || uri[uri_pos + 1] == ';'
                            || uri[uri_pos + 1] == '\0') {
                        uri_pos++;
                        if (uri[uri_pos] == '/') {
                            uri_pos++;
                        }
                        continue;
                    }
    
                    /* Remove /xx/../ segments */
                    if (uri[uri_pos + 1] == '.'
                        && (uri[uri_pos + 2] == '/'
                            || uri[uri_pos + 2] == ';'
                            || uri[uri_pos + 2] == '\0')) {
                        /* Wind map segment back the previous one */
                        if (map_pos == 1) {
                            /* Above root */
                            return 0;
                        }
                        do {
                            map_pos--;
                        } while (map[map_pos - 1] != '/');
                        map[map_pos] = '\0';
    
                        /* Wind alias segment back, unless in deeper segment */
                        if (alias_depth == stack->nelts) {
                            if (alias[alias_pos] == '\0') {
                                alias_pos--;
                            }
                            while (alias_pos > 0 && alias[alias_pos] == '/') {
                                alias_pos--;
                            }
                            while (alias_pos > 0 && alias[alias_pos - 1] != '/') {
                                alias_pos--;
                            }
                            AP_DEBUG_ASSERT(alias_pos > 0);
                            alias_depth--;
                        }
                        apr_array_pop(stack);
    
                        /* Move uri forward to the next segment */
                        uri_pos += 2;
                        if (uri[uri_pos] == '/') {
                            uri_pos++;
                        }
                        first_pos = 0;
                        continue;
                    }
                }
                if (first_pos) {
                    while (uri[first_pos] == '/') {
                        first_pos++;
                    }
                }
    
                /* New segment */
                APR_ARRAY_PUSH(stack, int) = first_pos ? first_pos : uri_pos;
                if (alias[alias_pos] != '\0') {
                    if (alias[alias_pos - 1] != '/') {
                        /* Remain in pair with uri segments */
                        do {
                            alias_pos++;
                        } while (alias[alias_pos - 1] != '/' && alias[alias_pos]);
                    }
                    while (alias[alias_pos] == '/') {
                        alias_pos++;
                    }
                    if (alias[alias_pos] != '\0') {
                        alias_depth++;
                    }
                }
            }
    
            if (alias[alias_pos] != '\0') {
                int *match = &APR_ARRAY_IDX(stack, alias_depth - 1, int);
                if (*match) {
                    if (alias[alias_pos] != uri[uri_pos]) {
                        /* Current segment does not match */
                        *match = 0;
                    }
                    else if (alias[alias_pos + 1] == '\0'
                             && alias[alias_pos] != '/') {
                        if (uri[uri_pos + 1] == ';') {
                            /* We'll preserve the parameters of the last
                             * segment if it does not end with '/', so mark
                             * the match as negative for below handling.
                             */
                            *match = -(uri_pos + 1);
                        }
                        else if (uri[uri_pos + 1] != '/'
                                 && uri[uri_pos + 1] != '\0') {
                            /* Last segment does not match all the way */
                            *match = 0;
                        }
                    }
                }
                /* Don't go past the segment if the uri isn't there yet */
                if (alias[alias_pos] != '/' || uri[uri_pos] == '/') {
                    alias_pos++;
                }
            }
    
            if (uri[uri_pos] == '/') {
                first_pos = uri_pos + 1;
            }
            map[map_pos++] = uri[uri_pos++];
            map[map_pos] = '\0';
        }
    
        /* Can't reach the end of uri before the end of the alias,
         * for example if uri is "/" and alias is "/examples"
         */
        if (alias[alias_pos] != '\0') {
            return 0;
        }
    
        /* Check whether each alias segment matched */
        for (depth = 0; depth < alias_depth; ++depth) {
            if (!APR_ARRAY_IDX(stack, depth, int)) {
                return 0;
            }
        }
    
        /* If alias_depth == stack->nelts we have a full match, i.e.
         * uri == alias so we can return uri_pos as is (the end of uri)
         */
        if (alias_depth < stack->nelts) {
            /* Return the segment following the alias */
            uri_pos = APR_ARRAY_IDX(stack, alias_depth, int);
            if (alias_depth) {
                /* But if the last segment of the alias does not end with '/'
                 * and the corresponding segment of the uri has parameters,
                 * we want to forward those parameters (see above for the
                 * negative pos trick/mark).
                 */
                int pos = APR_ARRAY_IDX(stack, alias_depth - 1, int);
                if (pos < 0) {
                    uri_pos = -pos;
                }
            }
        }
        /* If the alias lacks a trailing slash, take it from the uri (if any) */
        if (alias[alias_pos - 1] != '/' && uri[uri_pos - 1] == '/') {
            uri_pos--;
        }
    
        *urip = map;
        return uri_pos;
    }
    
    /* 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
                || ap_cstr_casecmp(r->parsed_uri.scheme, ap_http_scheme(r)) != 0
                || !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;
    }
    
    PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
                                            proxy_dir_conf *dconf)
    {
        int len;
        const char *fake;
        const char *real;
        ap_regmatch_t regm[AP_MAX_REG_MATCH];
        ap_regmatch_t reg1[AP_MAX_REG_MATCH];
        char *found = NULL;
        int mismatch = 0;
        unsigned int nocanon = ent->flags & PROXYPASS_NOCANON;
        const char *use_uri = nocanon ? r->unparsed_uri : r->uri;
        const char *servlet_uri = NULL;
    
        if (dconf && (dconf->interpolate_env == 1) && (ent->flags & PROXYPASS_INTERPOLATE)) {
            fake = ap_proxy_interpolate(r, ent->fake);
            real = ap_proxy_interpolate(r, ent->real);
        }
        else {
            fake = ent->fake;
            real = ent->real;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, APLOGNO(03461)
                      "attempting to match URI path '%s' against %s '%s' for "
                      "proxying", r->uri, (ent->regex ? "pattern" : "prefix"),
                      fake);
    
        if (ent->regex) {
            if (!ap_regexec(ent->regex, r->uri, AP_MAX_REG_MATCH, regm, 0)) {
                if ((real[0] == '!') && (real[1] == '\0')) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03462)
                                  "proxying is explicitly disabled for URI path "
                                  "'%s'; declining", r->uri);
                    return DECLINED;
                }
                /* test that we haven't reduced the URI */
                if (nocanon && ap_regexec(ent->regex, r->unparsed_uri,
                        AP_MAX_REG_MATCH, reg1, 0)) {
                    mismatch = 1;
                    use_uri = r->uri;
                }
                found = ap_pregsub(r->pool, real, use_uri, AP_MAX_REG_MATCH,
                        (use_uri == r->uri) ? regm : reg1);
                if (!found) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01135)
                                  "Substitution in regular expression failed. "
                                  "Replacement too long?");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
                /* Note: The strcmp() below catches cases where there
                 * was no regex substitution. This is so cases like:
                 *
                 *    ProxyPassMatch \.gif balancer://foo
                 *
                 * will work "as expected". The upshot is that the 2
                 * directives below act the exact same way (ie: $1 is implied):
                 *
                 *    ProxyPassMatch ^(/.*\.gif)$ balancer://foo
                 *    ProxyPassMatch ^(/.*\.gif)$ balancer://foo$1
                 *
                 * which may be confusing.
                 */
                if (strcmp(found, real) != 0) {
                    found = apr_pstrcat(r->pool, "proxy:", found, NULL);
                }
                else {
                    found = apr_pstrcat(r->pool, "proxy:", real, use_uri, NULL);
                }
            }
        }
        else {
            if ((ent->flags & PROXYPASS_MAP_SERVLET) == PROXYPASS_MAP_SERVLET) {
                servlet_uri = r->uri;
                len = alias_match_servlet(r->pool, &servlet_uri, fake);
                nocanon = 0; /* ignored since servlet's normalization applies */
            }
            else {
                len = alias_match(r->uri, fake);
            }
    
            if (len != 0) {
                if ((real[0] == '!') && (real[1] == '\0')) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03463)
                                  "proxying is explicitly disabled for URI path "
                                  "'%s'; declining", r->uri);
                    return DECLINED;
                }
                if (nocanon && len != alias_match(r->unparsed_uri, fake)) {
                    mismatch = 1;
                    use_uri = r->uri;
                }
                found = apr_pstrcat(r->pool, "proxy:", real, use_uri + len, NULL);
            }
        }
        if (mismatch) {
            /* We made a reducing transformation, so we can't safely use
             * unparsed_uri.  Safe fallback is to ignore nocanon.
             */
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01136)
                    "Unescaped URL path matched ProxyPass; ignoring unsafe nocanon");
        }
    
        if (found) {
            unsigned int encoded = ent->flags & PROXYPASS_MAP_ENCODED;
    
            /* A proxy module is assigned this URL, check whether it's interested
             * in the request itself (e.g. proxy_wstunnel cares about Upgrade
             * requests only, and could hand over to proxy_http otherwise).
             */
            int rc = proxy_run_check_trans(r, found + 6);
            if (rc != OK && rc != DECLINED) {
                return HTTP_CONTINUE;
            }
    
            r->filename = found;
            r->handler = "proxy-server";
            r->proxyreq = PROXYREQ_REVERSE;
            if (nocanon && !mismatch) {
                /* mod_proxy_http needs to be told.  Different module. */
                apr_table_setn(r->notes, "proxy-nocanon", "1");
            }
            if (ent->flags & PROXYPASS_NOQUERY) {
                apr_table_setn(r->notes, "proxy-noquery", "1");
            }
            if (encoded) {
                apr_table_setn(r->notes, "proxy-noencode", "1");
            }
    
            if (servlet_uri) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10248)
                              "Servlet path '%s' (%s) matches proxy handler '%s'",
                              r->uri, servlet_uri, found);
                /* Apply servlet normalization to r->uri so that <Location> or any
                 * directory context match does not have to handle path parameters.
                 * We change r->uri in-place so that r->parsed_uri.path is updated
                 * too. Since normalized servlet_uri is necessarily shorter than
                 * the original r->uri, strcpy() is fine.
                 */
                AP_DEBUG_ASSERT(strlen(r->uri) >= strlen(servlet_uri));
                strcpy(r->uri, servlet_uri);
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464)
                              "URI path '%s' matches proxy handler '%s'", r->uri,
                              found);
            }
            return (encoded) ? DONE : OK;
        }
    
        return HTTP_CONTINUE;
    }
    
    static int proxy_trans(request_rec *r, int pre_trans)
    {
        int i, enc;
        struct proxy_alias *ent;
        proxy_dir_conf *dconf;
        proxy_server_conf *conf;
    
        if (r->proxyreq) {
            /* someone has already set up the proxy, it was possibly ourselves
             * in proxy_detect (DONE will prevent further decoding of r->uri,
             * only if proxyreq is set before pre_trans already).
             */
            return pre_trans ? DONE : OK;
        }
    
        /* In early pre_trans hook, r->uri was not manipulated yet so we are
         * compliant with RFC1945 at this point. Otherwise, it probably isn't
         * an issue because this is a hybrid proxy/origin server.
         */
    
        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
        conf = (proxy_server_conf *) ap_get_module_config(r->server->module_config,
                                                          &proxy_module);
    
        /* Always and only do PROXY_MAP_ENCODED mapping in pre_trans, when
         * r->uri is still encoded, or we might consider for instance that
         * a decoded sub-delim is now a delimiter (e.g. "%3B" => ';' for
         * path parameters), which it's not.
         */
        if ((pre_trans && !conf->map_encoded_one)
                || (!pre_trans && conf->map_encoded_all)) {
            /* Fast path, nothing at this stage */
            return DECLINED;
        }
    
        if ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0')
            || !r->uri || r->uri[0] != '/') {
            return DECLINED;
        }
       
        if (apr_table_get(r->subprocess_env, "no-proxy")) { 
            return DECLINED;
        }
    
        /* short way - this location is reverse proxied? */
        if (dconf->alias) {
            enc = (dconf->alias->flags & PROXYPASS_MAP_ENCODED) != 0;
            if (!(pre_trans ^ enc)) {
                int rv = ap_proxy_trans_match(r, dconf->alias, dconf);
                if (rv != HTTP_CONTINUE) {
                    return rv;
                }
            }
        }
    
        /* long way - walk the list of aliases, find a match */
        for (i = 0; i < conf->aliases->nelts; i++) {
            ent = &((struct proxy_alias *)conf->aliases->elts)[i];
            enc = (ent->flags & PROXYPASS_MAP_ENCODED) != 0;
            if (!(pre_trans ^ enc)) {
                int rv = ap_proxy_trans_match(r, ent, dconf);
                if (rv != HTTP_CONTINUE) {
                    return rv;
                }
            }
        }
    
        return DECLINED;
    }
    
    static int proxy_pre_translate_name(request_rec *r)
    {
        return proxy_trans(r, 1);
    }
    
    static int proxy_translate_name(request_rec *r)
    {
        return proxy_trans(r, 0);
    }
    
    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->per_dir_config;
        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;
        apr_pool_t *rxpool = NULL;
    
        for (j = 0; j < num_sec; ++j)
        {
            int nmatch = 0;
            int i;
            ap_regmatch_t *pmatch = NULL;
    
            entry_config = sec_proxy[j];
            entry_proxy = ap_get_module_config(entry_config, &proxy_module);
    
            if (entry_proxy->r) {
    
                if (entry_proxy->refs && entry_proxy->refs->nelts) {
                    if (!rxpool) {
                        apr_pool_create(&rxpool, r->pool);
                        apr_pool_tag(rxpool, "proxy_rxpool");
                    }
                    nmatch = entry_proxy->refs->nelts;
                    pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
                }
    
                if (ap_regexec(entry_proxy->r, proxyname, nmatch, pmatch, 0)) {
                    continue;
                }
    
                for (i = 0; i < nmatch; i++) {
                    if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 &&
                            ((const char **)entry_proxy->refs->elts)[i]) {
                        apr_table_setn(r->subprocess_env,
                                ((const char **)entry_proxy->refs->elts)[i],
                                apr_pstrndup(r->pool,
                                        proxyname + pmatch[i].rm_so,
                                        pmatch[i].rm_eo - pmatch[i].rm_so));
                    }
                }
            }
    
            else if (
                /* XXX: What about case insensitive matching ???
                 * Compare regex, fnmatch or string as appropriate
                 * If the entry doesn't relate, then continue
                 */
                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;
    
        if (rxpool) {
            apr_pool_destroy(rxpool);
        }
    
        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)
    {
        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? */
    
        return ap_proxy_canon_url(r);
    }
    
    /* 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 /* has domain, or IPv4 literal */
         || strchr(r->parsed_uri.hostname, ':') != NULL /* IPv6 literal */
         || ap_cstr_casecmp(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_setn(r->headers_out, "Location", nuri);
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01138)
                      "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 rc = DECLINED, access_status, i;
        int direct_connect = 0;
        const char *str;
        apr_int64_t 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;
        int saved_status;
    
        /* is this for us? */
        if (!r->filename) {
            return DECLINED;
        }
    
        /* We may have forced the proxy handler via config or .htaccess */
        if (!r->proxyreq && r->handler && strncmp(r->handler, "proxy:", 6) == 0) {
            char *old_filename = r->filename;
    
            r->proxyreq = PROXYREQ_REVERSE;
            r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
            apr_table_setn(r->notes, "proxy-sethandler", "1");
    
            /* Still need to canonicalize r->filename */
            rc = ap_proxy_canon_url(r);
            if (rc != OK) {
                r->filename = old_filename;
                r->proxyreq = 0;
            }
        }
        else if (r->proxyreq && strncmp(r->filename, "proxy:", 6) == 0) {
            apr_table_unset(r->notes, "proxy-sethandler");
            rc = OK;
        }
        if (rc != OK) {
            return rc;
        }
    
        uri = r->filename + 6;
        p = strchr(uri, ':');
        if (p == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01141)
                          "proxy_handler no URL in %s", r->filename);
            return HTTP_BAD_REQUEST;
        }
        scheme = apr_pstrmemdup(r->pool, uri, p - uri);
    
        /* handle max-forwards / OPTIONS / TRACE */
        if ((str = apr_table_get(r->headers_in, "Max-Forwards"))) {
            char *end;
            maxfwd = apr_strtoi64(str, &end, 10);
            if (maxfwd < 0 || maxfwd == APR_INT64_MAX || *end) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10188) 
                              "Max-Forwards value '%s' could not be parsed", str);
                return ap_proxyerror(r, HTTP_BAD_REQUEST, 
                              "Max-Forwards request header could not be parsed");
            }
            else if (maxfwd == 0) {
                switch (r->method_number) {
                case M_TRACE: {
                    int access_status;
                    r->proxyreq = PROXYREQ_NONE;
                    access_status = ap_send_http_trace(r);
                    ap_die(access_status, r);
                    return OK;
                }
                case M_OPTIONS: {
                    int access_status;
                    r->proxyreq = PROXYREQ_NONE;
                    access_status = ap_send_http_options(r);
                    ap_die(access_status, r);
                    return OK;
                }
                default: {
                    return ap_proxyerror(r, HTTP_BAD_REQUEST,
                                         "Max-Forwards has reached zero - proxy loop?");
                }
                }
            }
            maxfwd = (maxfwd > 0) ? maxfwd - 1 : 0;
        }
        else {
            /* set configured max-forwards */
            maxfwd = conf->maxfwd;
        }
        if (maxfwd >= 0) {
            apr_table_setn(r->headers_in, "Max-Forwards",
                           apr_psprintf(r->pool, "%" APR_INT64_T_FMT, maxfwd));
        }
    
        if (r->method_number == M_TRACE) {
            core_server_config *coreconf = (core_server_config *)
                                           ap_get_core_module_config(sconf);
    
            if (coreconf->trace_enable == AP_TRACE_DISABLE)
            {
                /* Allow "error-notes" string to be printed by ap_send_error_response()
                 * Note; this goes nowhere, canned error response need an overhaul.
                 */
                apr_table_setn(r->notes, "error-notes",
                               "TRACE forbidden by server configuration");
                apr_table_setn(r->notes, "verbose-error-to", "*");
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01139)
                              "TRACE forbidden by server configuration");
                return HTTP_METHOD_NOT_ALLOWED;
            }
    
            /* Can't test ap_should_client_block, we aren't ready to send
             * the client a 100 Continue response till the connection has
             * been established
             */
            if (coreconf->trace_enable != AP_TRACE_EXTENDED
                && (r->read_length || r->read_chunked || r->remaining))
            {
                /* Allow "error-notes" string to be printed by ap_send_error_response()
                 * Note; this goes nowhere, canned error response need an overhaul.
                 */
                apr_table_setn(r->notes, "error-notes",
                               "TRACE with request body is not allowed");
                apr_table_setn(r->notes, "verbose-error-to", "*");
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01140)
                              "TRACE with request body is not allowed");
                return HTTP_REQUEST_ENTITY_TOO_LARGE;
            }
        }
    
        /* 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;
        }
    
        /* 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) ? APLOGNO(03231) "NoProxy for %s" : APLOGNO(03232) "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) {
                /*
                 * Only return if access_status is not HTTP_SERVICE_UNAVAILABLE
                 * This gives other modules the chance to hook into the
                 * request_status hook and decide what to do in this situation.
                 */
                if (access_status != HTTP_SERVICE_UNAVAILABLE)
                    return access_status;
                /*
                 * Ensure that balancer is NULL if worker is NULL to prevent
                 * potential problems in the post_request hook.
                 */
                if (!worker)
                    balancer = NULL;
                goto cleanup;
            }
    
            /* Initialise worker if needed, note the shared area must be initialized by the balancer logic */
            if (balancer) {
                ap_proxy_initialize_worker(worker, r->server, conf->pool);
            }
    
            if (balancer && balancer->s->max_attempts_set && !max_attempts)
                max_attempts = balancer->s->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 && ap_cstr_casecmp(scheme, ents[i].scheme) == 0) ||
                        (p2 != NULL &&
                        ap_cstr_casecmpn(url, ents[i].scheme,
                                    strlen(ents[i].scheme)) == 0)) {
    
                        /* handle the scheme */
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01142)
                                      "Trying to run scheme_handler against proxy");
    
                        if (ents[i].creds) {
                            apr_table_set(r->notes, "proxy-basic-creds", ents[i].creds);
                            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                          "Using proxy auth creds %s", ents[i].creds);
                        }
    
                        access_status = proxy_run_scheme_handler(r, worker,
                                                                 conf, url,
                                                                 ents[i].hostname,
                                                                 ents[i].port);
    
                        if (ents[i].creds) apr_table_unset(r->notes, "proxy-basic-creds");
    
                        /* Did the scheme handler process the request? */
                        if (access_status != DECLINED) {
                            const char *cl_a;
                            apr_off_t cl;
    
                            /*
                             * An fatal error or success, so no point in
                             * retrying with a direct connection.
                             */
                            if (access_status != HTTP_BAD_GATEWAY) {
                                goto cleanup;
                            }
    
                            cl_a = apr_table_get(r->headers_in, "Content-Length");
                            if (cl_a && (!ap_parse_strict_length(&cl, cl_a)
                                         || cl > 0)) {
                                /*
                                 * The request body is of length > 0. We cannot
                                 * retry with a direct connection since we already
                                 * sent (parts of) the request body to the proxy
                                 * and do not have any longer.
                                 */
                                goto cleanup;
                            }
                            /*
                             * Transfer-Encoding was set as input header, so we had
                             * a request body. We cannot retry with a direct
                             * connection for the same reason as above.
                             */
                            if (apr_table_get(r->headers_in, "Transfer-Encoding")) {
                                goto cleanup;
                            }
                        }
                    }
                }
            }
    
            /* 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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01143)
                          "Running scheme %s handler (attempt %d)",
                          scheme, attempts);
            AP_PROXY_RUN(r, worker, conf, url, attempts);
            access_status = proxy_run_scheme_handler(r, worker, conf,
                                                     url, NULL, 0);
            if (access_status == OK
                    || apr_table_get(r->notes, "proxy-error-override"))
                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_IGNORE_ERRORS)) {
                    worker->s->status |= PROXY_WORKER_IN_ERROR;
                    worker->s->error_time = apr_time_now();
                }
                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_IGNORE_ERRORS)) {
                    worker->s->status |= PROXY_WORKER_IN_ERROR;
                    worker->s->error_time = apr_time_now();
                }
            }
            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_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01144)
                          "No protocol handler was valid for the URL %s " 
                          "(scheme '%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, scheme);
            access_status = HTTP_INTERNAL_SERVER_ERROR;
            goto cleanup;
        }
    cleanup:
        /*
         * Save current r->status and set it to the value of access_status which
         * might be different (e.g. r->status could be HTTP_OK if e.g. we override
         * the error page on the proxy or if the error was not generated by the
         * backend itself but by the proxy e.g. a bad gateway) in order to give
         * ap_proxy_post_request a chance to act correctly on the status code.
         * But only do the above if access_status is not OK and not DONE, because
         * in this case r->status might contain the true status and overwriting
         * it with OK or DONE would be wrong.
         */
        if ((access_status != OK) && (access_status != DONE)) {
            saved_status = r->status;
            r->status = access_status;
            ap_proxy_post_request(worker, balancer, r, conf);
            /*
             * Only restore r->status if it has not been changed by
             * ap_proxy_post_request as we assume that this change was intentional.
             */
            if (r->status == access_status) {
                r->status = saved_status;
            }
        }
        else {
            ap_proxy_post_request(worker, balancer, r, conf);
        }
    
        proxy_run_request_status(&access_status, r);
        AP_PROXY_RUN_FINISHED(r, attempts, access_status);
    
        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->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry));
        ps->dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry));
        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->map_encoded_one = 0;
        ps->map_encoded_all = 1;
        ps->id = apr_psprintf(p, "p%x", 1); /* simply for storage size */
        ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */
        ps->viaopt_set = 0; /* 0 means default */
        ps->req = 0;
        ps->max_balancers = 0;
        ps->bal_persist = 0;
        ps->inherit = 1;
        ps->inherit_set = 0;
        ps->ppinherit = 1;
        ps->ppinherit_set = 0;
        ps->bgrowth = 5;
        ps->bgrowth_set = 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->timeout = 0;
        ps->timeout_set = 0;
        ps->badopt = bad_error;
        ps->badopt_set = 0;
        ps->source_address = NULL;
        ps->source_address_set = 0;
        apr_pool_create_ex(&ps->pool, p, NULL, NULL);
        apr_pool_tag(ps->pool, "proxy_server_conf");
    
        return ps;
    }
    
    static apr_array_header_t *merge_balancers(apr_pool_t *p,
                                               apr_array_header_t *base,
                                               apr_array_header_t *overrides)
    {
        proxy_balancer *b1;
        proxy_balancer *b2;
        proxy_balancer tmp;
        int x, y, found;
        apr_array_header_t *tocopy = apr_array_make(p, 1, sizeof(proxy_balancer));
    
        /* Check if the balancer is defined in both override and base configs:
         * a) If it is, Create copy of base balancer and change the configuration
         *    which can be changed by ProxyPass.
         * b) Otherwise, copy the balancer to tocopy array and merge it later.
         */
        b1 = (proxy_balancer *) base->elts;
        for (y = 0; y < base->nelts; y++) {
            b2 = (proxy_balancer *) overrides->elts;
            for (x = 0, found = 0; x < overrides->nelts; x++) {
                if (b1->hash.def == b2->hash.def && b1->hash.fnv == b2->hash.fnv) {
                    tmp = *b2;
                    *b2 = *b1;
                    b2->s = tmp.s;
    
                    /* For shared memory entries, b2->s belongs to override
                     * balancer, so if some entry is not set there, we have to
                     * update it according to the base balancer. */
                    if (*b2->s->sticky == 0 && *b1->s->sticky) {
                        PROXY_STRNCPY(b2->s->sticky_path, b1->s->sticky_path);
                        PROXY_STRNCPY(b2->s->sticky, b1->s->sticky);
                    }
                    if (!b2->s->sticky_separator_set
                        && b1->s->sticky_separator_set) {
                        b2->s->sticky_separator_set = b1->s->sticky_separator_set;
                        b2->s->sticky_separator = b1->s->sticky_separator;
                    }
                    if (!b2->s->timeout && b1->s->timeout) {
                        b2->s->timeout = b1->s->timeout;
                    }
                    if (!b2->s->max_attempts_set && b1->s->max_attempts_set) {
                        b2->s->max_attempts_set = b1->s->max_attempts_set;
                        b2->s->max_attempts = b1->s->max_attempts;
                    }
                    if (!b2->s->nonce_set && b1->s->nonce_set) {
                        b2->s->nonce_set = b1->s->nonce_set;
                        PROXY_STRNCPY(b2->s->nonce, b1->s->nonce);
                    }
                    if (!b2->s->sticky_force_set && b1->s->sticky_force_set) {
                        b2->s->sticky_force_set = b1->s->sticky_force_set;
                        b2->s->sticky_force = b1->s->sticky_force;
                    }
                    if (!b2->s->scolonsep_set && b1->s->scolonsep_set) {
                        b2->s->scolonsep_set = b1->s->scolonsep_set;
                        b2->s->scolonsep = b1->s->scolonsep;
                    }
                    if (!b2->s->forcerecovery_set && b1->s->forcerecovery_set) {
                        b2->s->forcerecovery_set = b1->s->forcerecovery_set;
                        b2->s->forcerecovery = b1->s->forcerecovery;
                    }
    
                    /* For non-shared memory entries, b2 is copy of b1, so we have
                     * to use tmp copy of b1 to detect changes done in override. */
                    if (tmp.lbmethod_set) {
                        b2->lbmethod_set = tmp.lbmethod_set;
                        b2->lbmethod = tmp.lbmethod;
                    }
                    if (tmp.growth_set) {
                        b2->growth_set = tmp.growth_set;
                        b2->growth = tmp.growth;
                    }
                    if (tmp.failontimeout_set) {
                        b2->failontimeout_set = tmp.failontimeout_set;
                        b2->failontimeout = tmp.failontimeout;
                    }
                    if (!apr_is_empty_array(tmp.errstatuses)) {
                        apr_array_cat(tmp.errstatuses, b2->errstatuses);
                        b2->errstatuses = tmp.errstatuses;
                    }
    
                    found = 1;
                    break;
                }
                b2++;
            }
            if (!found) {
                *(proxy_balancer *)apr_array_push(tocopy) = *b1;
            }
            b1++;
        }
    
        return apr_array_append(p, tocopy, overrides);
    }
    
    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->inherit = (overrides->inherit_set == 0) ? base->inherit : overrides->inherit;
        ps->inherit_set = overrides->inherit_set || base->inherit_set;
    
        ps->ppinherit = (overrides->ppinherit_set == 0) ? base->ppinherit : overrides->ppinherit;
        ps->ppinherit_set = overrides->ppinherit_set || base->ppinherit_set;
    
        if (ps->ppinherit) {
            ps->proxies = apr_array_append(p, base->proxies, overrides->proxies);
        }
        else {
            ps->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->noproxies = apr_array_append(p, base->noproxies, overrides->noproxies);
        ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn);
        if (ps->inherit || ps->ppinherit) {
            ps->workers = apr_array_append(p, base->workers, overrides->workers);
            ps->balancers = merge_balancers(p, base->balancers, overrides->balancers);
        }
        else {
            ps->workers = overrides->workers;
            ps->balancers = overrides->balancers;
        }
        ps->forward = overrides->forward ? overrides->forward : base->forward;
        ps->reverse = overrides->reverse ? overrides->reverse : base->reverse;
    
        ps->map_encoded_one = overrides->map_encoded_one || base->map_encoded_one;
        ps->map_encoded_all = overrides->map_encoded_all && base->map_encoded_all;
    
        ps->domain = (overrides->domain == NULL) ? base->domain : overrides->domain;
        ps->id = (overrides->id == NULL) ? base->id : overrides->id;
        ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt;
        ps->viaopt_set = overrides->viaopt_set || base->viaopt_set;
        ps->req = (overrides->req_set == 0) ? base->req : overrides->req;
        ps->req_set = overrides->req_set || base->req_set;
        ps->bgrowth = (overrides->bgrowth_set == 0) ? base->bgrowth : overrides->bgrowth;
        ps->bgrowth_set = overrides->bgrowth_set || base->bgrowth_set;
        ps->max_balancers = overrides->max_balancers || base->max_balancers;
        ps->bal_persist = overrides->bal_persist;
        ps->recv_buffer_size = (overrides->recv_buffer_size_set == 0) ? base->recv_buffer_size : overrides->recv_buffer_size;
        ps->recv_buffer_size_set = overrides->recv_buffer_size_set || base->recv_buffer_size_set;
        ps->io_buffer_size = (overrides->io_buffer_size_set == 0) ? base->io_buffer_size : overrides->io_buffer_size;
        ps->io_buffer_size_set = overrides->io_buffer_size_set || base->io_buffer_size_set;
        ps->maxfwd = (overrides->maxfwd_set == 0) ? base->maxfwd : overrides->maxfwd;
        ps->maxfwd_set = overrides->maxfwd_set || base->maxfwd_set;
        ps->timeout = (overrides->timeout_set == 0) ? base->timeout : overrides->timeout;
        ps->timeout_set = overrides->timeout_set || base->timeout_set;
        ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt;
        ps->badopt_set = overrides->badopt_set || base->badopt_set;
        ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status;
        ps->proxy_status_set = overrides->proxy_status_set || base->proxy_status_set;
        ps->source_address = (overrides->source_address_set == 0) ? base->source_address : overrides->source_address;
        ps->source_address_set = overrides->source_address_set || base->source_address_set;
        ps->pool = base->pool;
        return ps;
    }
    static const char *set_source_address(cmd_parms *parms, void *dummy,
                                          const char *arg)
    {
        proxy_server_conf *psf =
            ap_get_module_config(parms->server->module_config, &proxy_module);
        struct apr_sockaddr_t *addr;
    
        if (APR_SUCCESS == apr_sockaddr_info_get(&addr, arg, APR_UNSPEC, 0, 0,
                                                 psf->pool)) {
            psf->source_address = addr;
            psf->source_address_set = 1;
        }
        else {
            return "ProxySourceAddress invalid value";
        }
    
        return NULL;
    }
    
    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 */
    
        /* Put these in the dir config so they work inside <Location> */
        new->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
        new->cookie_paths = apr_array_make(p, 10, sizeof(struct proxy_alias));
        new->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias));
        new->error_override_codes = apr_array_make(p, 10, sizeof(int));
        new->preserve_host_set = 0;
        new->preserve_host = 0;
        new->interpolate_env = -1; /* unset */
        new->error_override = 0;
        new->error_override_set = 0;
        new->add_forwarded_headers = 1;
        new->add_forwarded_headers_set = 0;
        new->forward_100_continue = 1;
        new->forward_100_continue_set = 0;
    
        return (void *) new;
    }
    
    static int int_order(const void *i1, const void *i2)
    {
        return *(const int *)i1 - *(const int *)i2;
    }
    
    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;
        proxy_dir_conf *base = (proxy_dir_conf *) basev;
    
        new->p = add->p;
        new->p_is_fnmatch = add->p_is_fnmatch;
        new->r = add->r;
        new->refs = add->refs;
    
        /* Put these in the dir config so they work inside <Location> */
        new->raliases = apr_array_append(p, base->raliases, add->raliases);
        new->cookie_paths
            = apr_array_append(p, base->cookie_paths, add->cookie_paths);
        new->cookie_domains
            = apr_array_append(p, base->cookie_domains, add->cookie_domains);
        new->error_override_codes
            = apr_array_append(p, base->error_override_codes, add->error_override_codes);
        /* Keep the array sorted for binary search (since "base" and "add" are
         * already sorted, it's only needed only if both are merged).
         */
        if (base->error_override_codes->nelts
                && add->error_override_codes->nelts) {
            qsort(new->error_override_codes->elts,
                  new->error_override_codes->nelts,
                  sizeof(int), int_order);
        }
        new->interpolate_env = (add->interpolate_env == -1) ? base->interpolate_env
                                                            : add->interpolate_env;
        new->preserve_host = (add->preserve_host_set == 0) ? base->preserve_host
                                                            : add->preserve_host;
        new->preserve_host_set = add->preserve_host_set || base->preserve_host_set;
        new->error_override = (add->error_override_set == 0) ? base->error_override
                                                            : add->error_override;
        new->error_override_set = add->error_override_set || base->error_override_set;
        new->alias = (add->alias_set == 0) ? base->alias : add->alias;
        new->alias_set = add->alias_set || base->alias_set;
        new->add_forwarded_headers =
            (add->add_forwarded_headers_set == 0) ? base->add_forwarded_headers
            : add->add_forwarded_headers;
        new->add_forwarded_headers_set = add->add_forwarded_headers_set
            || base->add_forwarded_headers_set;
        new->forward_100_continue =
            (add->forward_100_continue_set == 0) ? base->forward_100_continue
                                                 : add->forward_100_continue;
        new->forward_100_continue_set = add->forward_100_continue_set
                                        || base->forward_100_continue_set;
    
        return new;
    }
    
    static const char *add_proxy(cmd_parms *cmd, void *dummy, const char *f1,
                                 const char *r1, const char *creds, 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;
        if (creds) {
            new->creds = apr_pstrcat(cmd->pool, "Basic ",
                                     ap_pbase64encode(cmd->pool, (char *)creds),
                                     NULL);
        }
        return NULL;
    }
    
    static const char *add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1,
                                         const char *r1, const char *creds)
    {
        return add_proxy(cmd, dummy, f1, r1, creds, 0);
    }
    
    static const char *add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1,
                                       const char *r1, const char *creds)
    {
        return add_proxy(cmd, dummy, f1, r1, creds, 1);
    }
    
    PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
    {
        const char *ptr;
        /*
         * We could be passed a URL during the config stage that contains
         * the UDS path... ignore it
         */
        if (!ap_cstr_casecmpn(url, "unix:", 5) &&
            ((ptr = ap_strchr_c(url + 5, '|')) != NULL)) {
            /* move past the 'unix:...|' UDS path info */
            const char *ret, *c;
    
            ret = ptr + 1;
            /* special cases: "unix:...|scheme:" ind "unix:...|scheme://" are OK,
             * expand to "unix:....|scheme://localhost"
             */
            c = ap_strchr_c(ret, ':');
            if (c == NULL) {
                return NULL;
            }
            if (c[1] == '\0') {
                return apr_pstrcat(p, ret, "//localhost", NULL);
            }
            else if (c[1] == '/' && c[2] == '/' && !c[3]) {
                return apr_pstrcat(p, ret, "localhost", NULL);
            }
            else {
                return ret;
            }
        }
        return url;
    }
    
    static const char *
        add_pass(cmd_parms *cmd, void *dummy, const char *arg, int is_regex)
    {
        proxy_dir_conf *dconf = (proxy_dir_conf *)dummy;
        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;
        const char *real;
        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;
        unsigned int worker_type = (is_regex) ? AP_PROXY_WORKER_IS_MATCH
                                              : AP_PROXY_WORKER_IS_PREFIX;
        unsigned int flags = 0;
        const char *err;
    
        err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES);
        if (err) {
            return err;
        }
    
        while (*arg) {
            word = ap_getword_conf(cmd->pool, &arg);
            if (!f) {
                if (!strcmp(word, "~")) {
                    if (is_regex) {
                        return "ProxyPassMatch invalid syntax ('~' usage).";
                    }
                    worker_type = AP_PROXY_WORKER_IS_MATCH;
                    continue;
                }
                f = word;
            }
            else if (!r) {
                r = word;
            }
            else if (!strcasecmp(word,"nocanon")) {
                flags |= PROXYPASS_NOCANON;
            }
            else if (!strcasecmp(word,"interpolate")) {
                flags |= PROXYPASS_INTERPOLATE;
            }
            else if (!strcasecmp(word,"noquery")) {
                flags |= PROXYPASS_NOQUERY;
            }
            else {
                char *val = strchr(word, '=');
                if (!val) {
                    if (cmd->path) {
                        if (*r == '/') {
                            return "ProxyPass|ProxyPassMatch can not have a path when defined in "
                                   "a location.";
                        }
                        else {
                            return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must "
                                   "be in the form 'key=value'.";
                        }
                    }
                    else {
                        return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be "
                               "in the form 'key=value'.";
                    }
                }
                else {
                    *val++ = '\0';
                }
                if (!strcasecmp(word, "mapping")) {
                    if (!strcasecmp(val, "encoded")) {
                        flags |= PROXYPASS_MAP_ENCODED;
                    }
                    else if (!strcasecmp(val, "servlet")) {
                        flags |= PROXYPASS_MAP_SERVLET;
                    }
                    else {
                        return "unknown mapping";
                    }
                }
                else {
                    apr_table_setn(params, word, val);
                }
            }
        }
        if (flags & PROXYPASS_MAP_ENCODED) {
            conf->map_encoded_one = 1;
        }
        else {
            conf->map_encoded_all = 0;
        }
    
        if (r == NULL) {
            return "ProxyPass|ProxyPassMatch needs a path when not defined in a location";
        }
        if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, r))) {
            return "ProxyPass|ProxyPassMatch uses an invalid \"unix:\" URL";
        }
    
    
        /* if per directory, save away the single alias */
        if (cmd->path) {
            dconf->alias = apr_pcalloc(cmd->pool, sizeof(struct proxy_alias));
            dconf->alias_set = 1;
            new = dconf->alias;
            if (apr_fnmatch_test(f)) {
                worker_type = AP_PROXY_WORKER_IS_MATCH;
            }
        }
        /* if per server, add to the alias array */
        else {
            new = apr_array_push(conf->aliases);
        }
    
        new->fake = apr_pstrdup(cmd->pool, f);
        new->real = apr_pstrdup(cmd->pool, real);
        new->flags = flags;
        if (worker_type & AP_PROXY_WORKER_IS_MATCH) {
            new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED);
            if (new->regex == NULL)
                return "Regular expression could not be compiled.";
        }
        else {
            new->regex = NULL;
        }
    
        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 worker */
        if (ap_proxy_valid_balancer_name(r, 9)) {
            proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r, 0);
            char *fake_copy;
    
            /*
             * In the regex case supplying a fake URL doesn't make sense as it
             * cannot be parsed anyway with apr_uri_parse later on in
             * ap_proxy_define_balancer / ap_proxy_update_balancer
             */
            if (worker_type & AP_PROXY_WORKER_IS_MATCH) {
                fake_copy = NULL;
            }
            else {
                fake_copy = f;
            }
            if (!balancer) {
                const char *err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, r, fake_copy, 0);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
            }
            else {
                ap_proxy_update_balancer(cmd->pool, balancer, fake_copy);
            }
            for (i = 0; i < arr->nelts; i++) {
                const char *err = set_balancer_param(conf, cmd->pool, balancer, elts[i].key,
                                                     elts[i].val);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
            }
            new->balancer = balancer;
        }
        else {
            int reuse = 0;
            proxy_worker *worker = ap_proxy_get_worker_ex(cmd->temp_pool, NULL,
                                                          conf, new->real,
                                                          worker_type);
            if (!worker) {
                const char *err;
                err = ap_proxy_define_worker_ex(cmd->pool, &worker, NULL,
                                                conf, r, worker_type);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
    
                PROXY_COPY_CONF_PARAMS(worker, conf);
            }
            else {
                reuse = 1;
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01145)
                             "Sharing worker '%s' instead of creating new worker '%s'",
                             ap_proxy_worker_name(cmd->pool, worker), new->real);
            }
    
            for (i = 0; i < arr->nelts; i++) {
                if (reuse) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01146)
                                 "Ignoring parameter '%s=%s' for worker '%s' because of worker sharing",
                                 elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool, worker));
                } else {
                    const char *err = set_worker_param(cmd->pool, s, 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_noregex(cmd_parms *cmd, void *dummy, const char *arg)
    {
        return add_pass(cmd, dummy, arg, 0);
    }
    
    static const char *
        add_pass_regex(cmd_parms *cmd, void *dummy, const char *arg)
    {
        return add_pass(cmd, dummy, arg, 1);
    }
    
    
    static const char * add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f,
                                         const char *r, const char *i)
    {
        proxy_dir_conf *conf = dconf;
        struct proxy_alias *new;
        const char *fake;
        const char *real;
        const char *interp;
        const char *err;
    
        err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES);
        if (err) {
            return err;
        }
    
        if (cmd->path == NULL) {
            if (r == NULL || !strcasecmp(r, "interpolate")) {
                return "ProxyPassReverse needs a path when not defined in a location";
            }
            fake = f;
            real = r;
            interp = i;
        }
        else {
            if (r && strcasecmp(r, "interpolate")) {
                return "ProxyPassReverse can not have a path when defined in a location";
            }
            fake = cmd->path;
            real = f;
            interp = r;
        }
    
        new = apr_array_push(conf->raliases);
        new->fake = fake;
        new->real = real;
        new->flags = interp ? PROXYPASS_INTERPOLATE : 0;
    
        return NULL;
    }
    static const char* cookie_path(cmd_parms *cmd, void *dconf, const char *f,
                                   const char *r, const char *interp)
    {
        proxy_dir_conf *conf = dconf;
        struct proxy_alias *new;
    
        new = apr_array_push(conf->cookie_paths);
        new->fake = f;
        new->real = r;
        new->flags = interp ? PROXYPASS_INTERPOLATE : 0;
    
        return NULL;
    }
    static const char* cookie_domain(cmd_parms *cmd, void *dconf, const char *f,
                                     const char *r, const char *interp)
    {
        proxy_dir_conf *conf = dconf;
        struct proxy_alias *new;
    
        new = apr_array_push(conf->cookie_domains);
        new->fake = f;
        new->real = r;
        new->flags = interp ? PROXYPASS_INTERPOLATE : 0;
        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 (strcasecmp(arg, list[i].name) == 0) { /* ignore case for host names */
                found = 1;
                break;
            }
        }
    
        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;
    }
    
    
    /* 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;
                break;
            }
        }
    
        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, APLOGNO(03018)
                             "Parsed addr %s", inet_ntoa(New->addr));
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(03019)
                             "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, APLOGNO(03020)
                             "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, APLOGNO(03021)
                             "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;
        return NULL;
    }
    
    static const char *
        set_proxy_error_override(cmd_parms *parms, void *dconf, const char *arg)
    {
        proxy_dir_conf *conf = dconf;
    
        if (strcasecmp(arg, "Off") == 0) {
            conf->error_override = 0;
            conf->error_override_set = 1;
        }
        else if (strcasecmp(arg, "On") == 0) {
            conf->error_override = 1;
            conf->error_override_set = 1;
        }
        else if (conf->error_override_set == 1) {
            int *newcode;
            int argcode, i;
            if (!apr_isdigit(arg[0]))
                return "ProxyErrorOverride: status codes to intercept must be numeric";
            if (!conf->error_override) 
                return "ProxyErrorOverride: status codes must follow a value of 'on'";
    
            argcode = strtol(arg, NULL, 10);
            if (!ap_is_HTTP_ERROR(argcode))
                return "ProxyErrorOverride: status codes to intercept must be valid HTTP Status Codes >=400 && <600";
    
            newcode = apr_array_push(conf->error_override_codes);
            *newcode = argcode;
    
            /* Keep the array sorted for binary search. */
            for (i = conf->error_override_codes->nelts - 1; i > 0; --i) {
                int *oldcode = &((int *)conf->error_override_codes->elts)[i - 1];
                if (*oldcode <= argcode) {
                    break;
                }
                *newcode = *oldcode;
                *oldcode = argcode;
                newcode = oldcode;
            }
        }
        else
            return "ProxyErrorOverride first parameter must be one of: off | on";
    
        return NULL;
    }
    
    static const char *
       add_proxy_http_headers(cmd_parms *parms, void *dconf, int flag)
    {
       proxy_dir_conf *conf = dconf;
       conf->add_forwarded_headers = flag;
       conf->add_forwarded_headers_set = 1;
       return NULL;
    }
    static const char *
        set_preserve_host(cmd_parms *parms, void *dconf, int flag)
    {
        proxy_dir_conf *conf = dconf;
    
        conf->preserve_host = flag;
        conf->preserve_host_set = 1;
        return NULL;
    }
    static const char *
       forward_100_continue(cmd_parms *parms, void *dconf, int flag)
    {
       proxy_dir_conf *conf = dconf;
       conf->forward_100_continue = flag;
       conf->forward_100_continue_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);
        if (s < 512 && s) {
            return "ProxyIOBufferSize must be >= 512 bytes, or 0 for system default.";
        }
        psf->io_buffer_size = (s ? 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);
    
        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 | full";
        }
    
        psf->proxy_status_set = 1;
        return NULL;
    }
    
    static const char *set_bgrowth(cmd_parms *parms, void *dummy, const char *arg)
    {
        proxy_server_conf *psf =
        ap_get_module_config(parms->server->module_config, &proxy_module);
    
        int growth = atoi(arg);
        if (growth < 0 || growth > 1000) {
            return "BalancerGrowth must be between 0 and 1000";
        }
        psf->bgrowth = growth;
        psf->bgrowth_set = 1;
    
        return NULL;
    }
    
    static const char *set_persist(cmd_parms *parms, void *dummy, int flag)
    {
        proxy_server_conf *psf =
        ap_get_module_config(parms->server->module_config, &proxy_module);
    
        psf->bal_persist = flag;
        return NULL;
    }
    
    static const char *set_inherit(cmd_parms *parms, void *dummy, int flag)
    {
        proxy_server_conf *psf =
        ap_get_module_config(parms->server->module_config, &proxy_module);
    
        psf->inherit = flag;
        psf->inherit_set = 1;
        return NULL;
    }
    
    static const char *set_ppinherit(cmd_parms *parms, void *dummy, int flag)
    {
        proxy_server_conf *psf =
        ap_get_module_config(parms->server->module_config, &proxy_module);
    
        psf->ppinherit = flag;
        psf->ppinherit_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;
        const char *real;
        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 reuse = 0;
        int i;
        /* XXX: Should this be NOT_IN_DIRECTORY|NOT_IN_FILES? */
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return err;
    
        if (cmd->path)
            path = apr_pstrdup(cmd->pool, cmd->path);
    
        while (*arg) {
            char *val;
            word = ap_getword_conf(cmd->pool, &arg);
            val = strchr(word, '=');
    
            if (!val) {
                if (!path)
                    path = word;
                else if (!name)
                    name = word;
                else {
                    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";
        if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, name))) {
            return "BalancerMember uses an invalid \"unix:\" URL";
        }
    
        ap_str_tolower(path);   /* lowercase scheme://hostname */
    
        /* Try to find the balancer */
        balancer = ap_proxy_get_balancer(cmd->temp_pool, conf, path, 0);
        if (!balancer) {
            err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, path, "/", 0);
            if (err)
                return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
        }
    
        /* Try to find existing worker */
        worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, real);
        if (!worker) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147)
                         "Defining worker '%s' for balancer '%s'",
                         name, balancer->s->name);
            if ((err = ap_proxy_define_worker(cmd->pool, &worker, balancer, conf, name, 0)) != NULL)
                return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01148)
                         "Defined worker '%s' for balancer '%s'",
                         ap_proxy_worker_name(cmd->pool, worker), balancer->s->name);
            PROXY_COPY_CONF_PARAMS(worker, conf);
        } else {
            reuse = 1;
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01149)
                         "Sharing worker '%s' instead of creating new worker '%s'",
                         ap_proxy_worker_name(cmd->pool, worker), name);
        }
        if (!worker->section_config) {
            worker->section_config = balancer->section_config;
        }
    
        arr = apr_table_elts(params);
        elts = (const apr_table_entry_t *)arr->elts;
        for (i = 0; i < arr->nelts; i++) {
            if (reuse) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01150)
                             "Ignoring parameter '%s=%s' for worker '%s' because of worker sharing",
                             elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool, worker));
            } else {
                err = set_worker_param(cmd->pool, cmd->server, worker, elts[i].key,
                                       elts[i].val);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
            }
        }
    
        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;
        unsigned int worker_type = 0;
        int in_proxy_section = 0;
        /* XXX: Should this be NOT_IN_DIRECTORY|NOT_IN_FILES? */
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return 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';
            if (strncasecmp(cmd->directive->parent->directive + 6,
                            "Match", 5) == 0) {
                worker_type = AP_PROXY_WORKER_IS_MATCH;
            }
            else {
                worker_type = AP_PROXY_WORKER_IS_PREFIX;
            }
            in_proxy_section = 1;
        }
        else {
            /* Standard set directive with worker/balancer
             * name as first param.
             */
            name = ap_getword_conf(cmd->temp_pool, &arg);
        }
    
        if (ap_proxy_valid_balancer_name(name, 9)) {
            balancer = ap_proxy_get_balancer(cmd->pool, conf, name, 0);
            if (!balancer) {
                if (in_proxy_section) {
                    err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, name, "/", 0);
                    if (err)
                        return apr_pstrcat(cmd->temp_pool, "ProxySet ",
                                           err, NULL);
                }
                else
                    return apr_pstrcat(cmd->temp_pool, "ProxySet can not find '",
                                       name, "' Balancer.", NULL);
            }
        }
        else {
            const char *real;
    
            if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, name))) {
                return "ProxySet uses an invalid \"unix:\" URL";
            }
    
            worker = ap_proxy_get_worker_ex(cmd->temp_pool, NULL, conf,
                                            real, worker_type);
            if (!worker) {
                if (in_proxy_section) {
                    err = ap_proxy_define_worker_ex(cmd->pool, &worker, NULL,
                                                    conf, name, worker_type);
                    if (err)
                        return apr_pstrcat(cmd->temp_pool, "ProxySet ",
                                           err, NULL);
                }
                else
                    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, cmd->server, worker, word, val);
            else
                err = set_balancer_param(conf, cmd->pool, balancer, word, val);
    
            if (err)
                return apr_pstrcat(cmd->temp_pool, "ProxySet: ", err, " ", word, "=", val, "; ", 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;
        char *word, *val;
        proxy_balancer *balancer = NULL;
        proxy_worker *worker = NULL;
        unsigned int worker_type = AP_PROXY_WORKER_IS_PREFIX;
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        proxy_server_conf *sconf =
        (proxy_server_conf *) ap_get_module_config(cmd->server->module_config, &proxy_module);
    
        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|PROXY_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";
            }
            worker_type = AP_PROXY_WORKER_IS_MATCH;
        }
    
        /* 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);
    
        if (r) {
            conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
            ap_regname(r, conf->refs, AP_REG_MATCH, 1);
        }
    
        ap_add_per_proxy_conf(cmd->server, new_dir_conf);
    
        if (*arg != '\0') {
            if (thiscmd->cmd_data)
                return "Multiple <ProxyMatch> arguments not (yet) supported.";
            if (conf->p_is_fnmatch)
                return apr_pstrcat(cmd->pool, thiscmd->name,
                                   "> arguments are not supported for wildchar url.",
                                   NULL);
            if (!ap_strchr_c(conf->p, ':'))
                return apr_pstrcat(cmd->pool, thiscmd->name,
                                   "> arguments are not supported for non url.",
                                   NULL);
            if (ap_proxy_valid_balancer_name((char *)conf->p, 9)) {
                balancer = ap_proxy_get_balancer(cmd->pool, sconf, conf->p, 0);
                if (!balancer) {
                    err = ap_proxy_define_balancer(cmd->pool, &balancer,
                                                   sconf, conf->p, "/", 0);
                    if (err)
                        return apr_pstrcat(cmd->temp_pool, thiscmd->name,
                                           " ", err, NULL);
                }
                if (!balancer->section_config) {
                    balancer->section_config = new_dir_conf;
                }
            }
            else {
                const char *real;
    
                if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, conf->p))) {
                    return "<Proxy/ProxyMatch > uses an invalid \"unix:\" URL";
                }
    
                worker = ap_proxy_get_worker_ex(cmd->temp_pool, NULL, sconf,
                                                real, worker_type);
                if (!worker) {
                    err = ap_proxy_define_worker_ex(cmd->pool, &worker, NULL, sconf,
                                                    conf->p, worker_type);
                    if (err)
                        return apr_pstrcat(cmd->temp_pool, thiscmd->name,
                                           " ", err, NULL);
                }
                if (!worker->section_config) {
                    worker->section_config = new_dir_conf;
                }
            }
            if (worker == NULL && balancer == NULL) {
                return apr_pstrcat(cmd->pool, thiscmd->name,
                                   "> arguments are supported only for workers.",
                                   NULL);
            }
            while (*arg) {
                word = ap_getword_conf(cmd->pool, &arg);
                val = strchr(word, '=');
                if (!val) {
                    return "Invalid Proxy parameter. Parameter must be "
                           "in the form 'key=value'";
                }
                else
                    *val++ = '\0';
                if (worker)
                    err = set_worker_param(cmd->pool, cmd->server, worker, word, val);
                else
                    err = set_balancer_param(sconf, cmd->pool, balancer,
                                             word, val);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, thiscmd->name, " ", err, " ",
                                       word, "=", val, "; ", conf->p, 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_TAKE23("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
         "a scheme, partial URL or '*' and a proxy server"),
        AP_INIT_TAKE23("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
         "a regex pattern and a proxy server"),
        AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot_char,
            (void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
            RSRC_CONF|ACCESS_CONF, "Interpolate Env Vars in reverse Proxy") ,
        AP_INIT_RAW_ARGS("ProxyPass", add_pass_noregex, NULL, RSRC_CONF|ACCESS_CONF,
         "a virtual path and a URL"),
        AP_INIT_RAW_ARGS("ProxyPassMatch", add_pass_regex, NULL, RSRC_CONF|ACCESS_CONF,
         "a virtual path and a URL"),
        AP_INIT_TAKE123("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF,
         "a virtual path and a URL for reverse proxy behaviour"),
        AP_INIT_TAKE23("ProxyPassReverseCookiePath", cookie_path, NULL,
           RSRC_CONF|ACCESS_CONF, "Path rewrite rule for proxying cookies"),
        AP_INIT_TAKE23("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_TAKE1("ProxyVia", set_via_opt, NULL, RSRC_CONF,
         "Configure Via: proxy header header to one of: on | off | block | full"),
        AP_INIT_ITERATE("ProxyErrorOverride", set_proxy_error_override, NULL, RSRC_CONF|ACCESS_CONF,
         "use our error handling pages instead of the servers' we are proxying"),
        AP_INIT_FLAG("ProxyPreserveHost", set_preserve_host, NULL, RSRC_CONF|ACCESS_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("BalancerGrowth", set_bgrowth, NULL, RSRC_CONF,
         "Number of additional Balancers that can be added post-config"),
        AP_INIT_FLAG("BalancerPersist", set_persist, NULL, RSRC_CONF,
         "on if the balancer should persist changes on reboot/restart made via the Balancer Manager"),
        AP_INIT_FLAG("BalancerInherit", set_inherit, NULL, RSRC_CONF,
         "on if this server should inherit Balancers and Workers defined in the main server "
         "(Setting to off recommended if using the Balancer Manager)"),
        AP_INIT_FLAG("ProxyPassInherit", set_ppinherit, NULL, RSRC_CONF,
         "on if this server should inherit all ProxyPass directives defined in the main server "
         "(Setting to off recommended if using the Balancer Manager)"),
        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"),
        AP_INIT_TAKE1("ProxySourceAddress", set_source_address, NULL, RSRC_CONF,
         "Configure local source IP used for request forward"),
        AP_INIT_FLAG("ProxyAddHeaders", add_proxy_http_headers, NULL, RSRC_CONF|ACCESS_CONF,
         "on if X-Forwarded-* headers should be added or completed"),
        AP_INIT_FLAG("Proxy100Continue", forward_100_continue, NULL, RSRC_CONF|ACCESS_CONF,
         "on if 100-Continue should be forwarded to the origin server, off if the "
         "proxy should handle it by itself"),
        {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_engine_set) *proxy_ssl_engine = 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 (c == NULL) {
            return ap_ssl_has_outgoing_handlers();
        }
        return ap_ssl_bind_outgoing(c, NULL, 1) == OK;
    }
    
    PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c)
    {
        return ap_ssl_bind_outgoing(c, NULL, 0) == OK;
    }
    
    PROXY_DECLARE(int) ap_proxy_ssl_engine(conn_rec *c,
                                           ap_conf_vector_t *per_dir_config,
                                           int enable)
    {
        /*
         * if c == NULL just check if the optional function was imported
         * else run the optional function so ssl filters are inserted
         */
        if (c == NULL) {
            return ap_ssl_has_outgoing_handlers();
        }
        return ap_ssl_bind_outgoing(c, per_dir_config, enable) == OK;
    }
    
    PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c)
    {
        return ap_ssl_conn_is_ssl(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)
    {
        return ap_ssl_var_lookup(p, s, c, r, var);
    }
    
    static int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                 apr_pool_t *ptemp, server_rec *main_s)
    {
        server_rec *s = main_s;
        apr_status_t rv = ap_global_mutex_create(&proxy_mutex, NULL,
                                                 proxy_id, NULL, s, pconf, 0);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02478)
            "failed to create %s mutex", proxy_id);
            return rv;
        }
    
        proxy_ssl_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable);
        proxy_ssl_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
        proxy_ssl_engine = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_set);
        ap_proxy_strmatch_path = apr_strmatch_precompile(pconf, "path=", 0);
        ap_proxy_strmatch_domain = apr_strmatch_precompile(pconf, "domain=", 0);
    
        for (; s; s = s->next) {
            int rc, i;
            proxy_server_conf *sconf =
                ap_get_module_config(s->module_config, &proxy_module);
            ap_conf_vector_t **sections =
                (ap_conf_vector_t **)sconf->sec_proxy->elts;
    
            for (i = 0; i < sconf->sec_proxy->nelts; ++i) {
                rc = proxy_run_section_post_config(pconf, ptemp, plog,
                                                   s, sections[i]);
                if (rc != OK && rc != DECLINED) {
                    return rc;
                }
            }
        }
    
        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 (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++) {
            if (!(flags & AP_STATUS_SHORT)) {
                ap_rputs("<hr />\n<h1>Proxy LoadBalancer Status for ", r);
                ap_rvputs(r, balancer->s->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);
                if (*balancer->s->sticky) {
                    if (strcmp(balancer->s->sticky, balancer->s->sticky_path)) {
                        ap_rvputs(r, "<td>", balancer->s->sticky, " | ",
                                  balancer->s->sticky_path, NULL);
                    }
                    else {
                        ap_rvputs(r, "<td>", balancer->s->sticky, NULL);
                    }
                }
                else {
                    ap_rputs("<td> - ", r);
                }
                ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
                           apr_time_sec(balancer->s->timeout));
                ap_rprintf(r, "<td>%s</td>\n",
                           balancer->lbmethod->name);
                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>Set</th><th>Acc</th><th>Busy</th><th>Wr</th><th>Rd</th>"
                         "</tr>\n", r);
            }
            else {
                ap_rprintf(r, "ProxyBalancer[%d]Name: %s\n", i, balancer->s->name);
            }
    
            worker = (proxy_worker **)balancer->workers->elts;
            for (n = 0; n < balancer->workers->nelts; n++) {
                char fbuf[50];
                if (!(flags & AP_STATUS_SHORT)) {
                    ap_rvputs(r, "<tr>\n<td>", (*worker)->s->scheme, "</td>", NULL);
                    ap_rvputs(r, "<td>", (*worker)->s->hostname_ex, "</td><td>", NULL);
                    ap_rvputs(r, ap_proxy_parse_wstatus(r->pool, *worker), NULL);
                    ap_rvputs(r, "</td><td>", (*worker)->s->route, NULL);
                    ap_rvputs(r, "</td><td>", (*worker)->s->redirect, NULL);
                    ap_rprintf(r, "</td><td>%.2f</td>", (float)((*worker)->s->lbfactor)/100.0);
                    ap_rprintf(r, "<td>%d</td>", (*worker)->s->lbset);
                    ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td>",
                               (*worker)->s->elected);
                    ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>",
                               (*worker)->s->busy);
                    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);
                }
                else {
                    ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Name: %s\n",
                               i, n, (*worker)->s->name_ex);
                    ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Status: %s\n",
                               i, n, ap_proxy_parse_wstatus(r->pool, *worker));
                    ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Elected: %"
                                  APR_SIZE_T_FMT "\n",
                               i, n, (*worker)->s->elected);
                    ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Busy: %"
                                  APR_SIZE_T_FMT "\n",
                               i, n, (*worker)->s->busy);
                    ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Sent: %"
                                  APR_OFF_T_FMT "K\n",
                               i, n, (*worker)->s->transferred >> 10);
                    ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Rcvd: %"
                                  APR_OFF_T_FMT "K\n",
                               i, n, (*worker)->s->read >> 10);
    
                    /* TODO: Add the rest of dynamic worker data */
                }
    
                ++worker;
            }
            if (!(flags & AP_STATUS_SHORT)) {
                ap_rputs("</table>\n", r);
            }
            ++balancer;
        }
        if (!(flags & AP_STATUS_SHORT)) {
            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</td></tr>\n"
                     "<tr><th>Acc</th><td>Number of uses</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;
    
        apr_status_t rv = apr_global_mutex_child_init(&proxy_mutex,
                                          apr_global_mutex_lockfile(proxy_mutex),
                                          p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(02479)
                         "could not init proxy_mutex in child");
            exit(1); /* Ugly, but what else? */
        }
    
        /* TODO */
        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);
            /*
             * NOTE: non-balancer members don't use shm at all...
             *       after all, why should they?
             */
            worker = (proxy_worker *)conf->workers->elts;
            for (i = 0; i < conf->workers->nelts; i++, worker++) {
                ap_proxy_initialize_worker(worker, s, p);
            }
            /* Create and initialize forward worker if defined */
            if (conf->req_set && conf->req) {
                proxy_worker *forward;
                ap_proxy_define_worker(conf->pool, &forward, NULL, NULL,
                                       "http://www.apache.org", 0);
                conf->forward = forward;
                PROXY_STRNCPY(conf->forward->s->name,     "proxy:forward");
                PROXY_STRNCPY(conf->forward->s->name_ex,  "proxy:forward");
                PROXY_STRNCPY(conf->forward->s->hostname, "*"); /* for compatibility */
                PROXY_STRNCPY(conf->forward->s->hostname_ex, "*");
                PROXY_STRNCPY(conf->forward->s->scheme,   "*");
                conf->forward->hash.def = conf->forward->s->hash.def =
                    ap_proxy_hashfunc(conf->forward->s->name_ex, PROXY_HASHFUNC_DEFAULT);
                 conf->forward->hash.fnv = conf->forward->s->hash.fnv =
                    ap_proxy_hashfunc(conf->forward->s->name_ex, PROXY_HASHFUNC_FNV);
                /* Do not disable worker in case of errors */
                conf->forward->s->status |= PROXY_WORKER_IGNORE_ERRORS;
                /* Mark as the "generic" worker */
                conf->forward->s->status |= PROXY_WORKER_GENERIC;
                ap_proxy_initialize_worker(conf->forward, s, p);
                /* Disable address cache for generic forward worker */
                conf->forward->s->is_address_reusable = 0;
            }
            if (!reverse) {
                ap_proxy_define_worker(conf->pool, &reverse, NULL, NULL,
                                       "http://www.apache.org", 0);
                PROXY_STRNCPY(reverse->s->name,     "proxy:reverse");
                PROXY_STRNCPY(reverse->s->name_ex,  "proxy:reverse");
                PROXY_STRNCPY(reverse->s->hostname, "*"); /* for compatibility */
                PROXY_STRNCPY(reverse->s->hostname_ex, "*");
                PROXY_STRNCPY(reverse->s->scheme,   "*");
                reverse->hash.def = reverse->s->hash.def =
                    ap_proxy_hashfunc(reverse->s->name_ex, PROXY_HASHFUNC_DEFAULT);
                reverse->hash.fnv = reverse->s->hash.fnv =
                    ap_proxy_hashfunc(reverse->s->name_ex, PROXY_HASHFUNC_FNV);
                /* Do not disable worker in case of errors */
                reverse->s->status |= PROXY_WORKER_IGNORE_ERRORS;
                /* Mark as the "generic" worker */
                reverse->s->status |= PROXY_WORKER_GENERIC;
                conf->reverse = reverse;
                ap_proxy_initialize_worker(conf->reverse, s, p);
                /* Disable address cache for generic reverse worker */
                reverse->s->is_address_reusable = 0;
            }
            conf->reverse = reverse;
            s = s->next;
        }
    }
    
    /*
     * This routine is called before the server processes the configuration
     * files.
     */
    static int proxy_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                apr_pool_t *ptemp)
    {
        apr_status_t rv = ap_mutex_register(pconf, proxy_id, NULL,
                APR_LOCK_DEFAULT, 0);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02480)
                    "failed to register %s mutex", proxy_id);
            return 500; /* An HTTP status would be a misnomer! */
        }
    
        APR_OPTIONAL_HOOK(ap, status_hook, proxy_status_hook, NULL, NULL,
                          APR_HOOK_MIDDLE);
        /* Reset workers count on graceful restart */
        proxy_lb_workers = 0;
        set_worker_hc_param_f = APR_RETRIEVE_OPTIONAL_FN(set_worker_hc_param);
        return OK;
    }
    static void register_hooks(apr_pool_t *p)
    {
        /* 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", "mod_proxy_balancer.c",
                                               "mod_proxy_hcheck.c", NULL};
        static const char * const aszModRewrite[] = { "mod_rewrite.c", NULL };
    
        /* handler */
        ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST);
        /* filename-to-URI translation */
        ap_hook_pre_translate_name(proxy_pre_translate_name, NULL, NULL,
                                   APR_HOOK_MIDDLE);
        /* mod_rewrite has a say on the uri before proxy translation */
        ap_hook_translate_name(proxy_translate_name, aszModRewrite, 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);
        /* fixup after mod_rewrite so that a [P] URL from there gets fixed up */
        ap_hook_fixups(proxy_fixup, aszModRewrite, NULL, 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);
    
        /* register optional functions within proxy_util.c */
        proxy_util_register_hooks(p);
    }
    
    AP_DECLARE_MODULE(proxy) =
    {
        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_HOOK_LINK(request_status)
        APR_HOOK_LINK(check_trans)
    )
    
    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, check_trans,
                                          (request_rec *r, const char *url),
                                          (r, url), 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, section_post_config,
                                        (apr_pool_t *p, apr_pool_t *plog,
                                         apr_pool_t *ptemp, server_rec *s,
                                         ap_conf_vector_t *section_config),
                                        (p, ptemp, plog, s, section_config),
                                        OK, DECLINED)
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups,
                                        (request_rec *r), (r),
                                        OK, DECLINED)
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, request_status,
                                        (int *status, request_rec *r),
                                        (status, r),
                                        OK, DECLINED)
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_connect.dsp����������������������������������������������������0000664�0001751�0001751�00000011613�10551346420�021716� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 0x409 /fo"Release/mod_proxy_connect.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_connect.so" /d LONG_NAME="proxy_connect_module for Apache"
    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 /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 /out:".\Release\mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_connect.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 0x409 /fo"Debug/mod_proxy_connect.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_connect.so" /d LONG_NAME="proxy_connect_module for Apache"
    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 /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 /out:".\Debug\mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_connect.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_fcgi.mak�������������������������������������������������������0000664�0001751�0001751�00000025645�12701473373�021200� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_fcgi.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_fcgi - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_fcgi - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_fcgi - Win32 Release" && "$(CFG)" != "mod_proxy_fcgi - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_fcgi.mak" CFG="mod_proxy_fcgi - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_fcgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_fcgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_fcgi - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_fcgi.obj"
    	-@erase "$(INTDIR)\mod_proxy_fcgi.res"
    	-@erase "$(INTDIR)\mod_proxy_fcgi_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_fcgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.exp"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.lib"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_fcgi_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_fcgi.so" /d LONG_NAME="proxy_fcgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_fcgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_fcgi.pdb" /debug /out:"$(OUTDIR)\mod_proxy_fcgi.so" /implib:"$(OUTDIR)\mod_proxy_fcgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_fcgi.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_fcgi.obj" \
    	"$(INTDIR)\mod_proxy_fcgi.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_fcgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_fcgi.so"
       if exist .\Release\mod_proxy_fcgi.so.manifest mt.exe -manifest .\Release\mod_proxy_fcgi.so.manifest -outputresource:.\Release\mod_proxy_fcgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_fcgi - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_fcgi.obj"
    	-@erase "$(INTDIR)\mod_proxy_fcgi.res"
    	-@erase "$(INTDIR)\mod_proxy_fcgi_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_fcgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.exp"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.lib"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_fcgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_fcgi_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_fcgi.so" /d LONG_NAME="proxy_fcgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_fcgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_fcgi.pdb" /debug /out:"$(OUTDIR)\mod_proxy_fcgi.so" /implib:"$(OUTDIR)\mod_proxy_fcgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_fcgi.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_fcgi.obj" \
    	"$(INTDIR)\mod_proxy_fcgi.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_fcgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_fcgi.so"
       if exist .\Debug\mod_proxy_fcgi.so.manifest mt.exe -manifest .\Debug\mod_proxy_fcgi.so.manifest -outputresource:.\Debug\mod_proxy_fcgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_fcgi.dep")
    !INCLUDE "mod_proxy_fcgi.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_fcgi.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_fcgi - Win32 Release" || "$(CFG)" == "mod_proxy_fcgi - Win32 Debug"
    SOURCE=.\mod_proxy_fcgi.c
    
    "$(INTDIR)\mod_proxy_fcgi.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_fcgi - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_fcgi - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_fcgi - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_fcgi - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_fcgi - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_fcgi - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_fcgi - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_fcgi - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_fcgi - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_fcgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_fcgi.so" /d LONG_NAME="proxy_fcgi_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_fcgi - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_fcgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_fcgi.so" /d LONG_NAME="proxy_fcgi_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/libproxy.exp�������������������������������������������������������������0000664�0001751�0001751�00000000015�10150161574�020035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������proxy_module
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/proxy_util.h�������������������������������������������������������������0000664�0001751�0001751�00000004213�14643762364�020061� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 PROXY_UTIL_H_
    #define PROXY_UTIL_H_
    
    /**
     * @file  proxy_util.h
     * @brief Internal interfaces private to mod_proxy.
     *
     * @defgroup MOD_PROXY_PRIVATE Private
     * @ingroup MOD_PROXY
     * @{
     */
    
    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);
    
    extern PROXY_DECLARE_DATA int proxy_lb_workers;
    extern PROXY_DECLARE_DATA const apr_strmatch_pattern *ap_proxy_strmatch_path;
    extern PROXY_DECLARE_DATA const apr_strmatch_pattern *ap_proxy_strmatch_domain;
    
    /**
     * Register optional functions declared within proxy_util.c.
     */
    void proxy_util_register_hooks(apr_pool_t *p);
    
    /*
     * interpolate an env str in a configuration string
     *
     * @param r    current request
     * @param str  the string to interpolcate
     * @return     the interpolated string
     */
    PROXY_DECLARE(const char *) ap_proxy_interpolate(request_rec *r,
                                                     const char *str);
    
    /*
     * Canonicalize the URL in r->filename
     * @param r           current request
     * @return            OK or an HTTP_XXX error
     */
    PROXY_DECLARE(int) ap_proxy_canon_url(request_rec *r);
    
    /** @} */
    
    #endif /* PROXY_UTIL_H_ */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy.h��������������������������������������������������������������0000664�0001751�0001751�00000203457�14737241277�017675� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
    
    /**
     * @file  mod_proxy.h
     * @brief Proxy Extension Module for Apache
     *
     * @defgroup MOD_PROXY mod_proxy
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #include "apr_hooks.h"
    #include "apr_optional.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 "apr_uuid.h"
    #include "util_mutex.h"
    #include "apr_global_mutex.h"
    #include "apr_thread_mutex.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 "http_ssl.h"
    #include "util_filter.h"
    #include "util_ebcdic.h"
    #include "ap_provider.h"
    #include "ap_slotmem.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
    };
    
    /* Flags for ap_proxy_canonenc_ex */
    #define PROXY_CANONENC_FORCEDEC 0x01
    #define PROXY_CANONENC_NOENCODEDSLASHENCODING 0x02
    
    typedef enum {
        NONE, TCP, OPTIONS, HEAD, GET, CPING, PROVIDER, OPTIONS11, HEAD11, GET11, EOT
    } hcmethod_t;
    
    typedef struct {
        hcmethod_t method;
        char *name;
        int implemented;
    } proxy_hcmethods_t;
    
    typedef struct {
        unsigned int bit;
        char flag;
        const char *name;
    } proxy_wstat_t;
    
    #define BALANCER_PREFIX "balancer://"
    
    #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 */
    /* Set this to -1, which complies with RFC2616 by not setting
     * max-forwards if the client didn't send it to us.
     */
    #define DEFAULT_MAX_FORWARDS    -1
    
    typedef struct proxy_balancer  proxy_balancer;
    typedef struct proxy_worker    proxy_worker;
    typedef struct proxy_conn_pool proxy_conn_pool;
    typedef struct proxy_balancer_method proxy_balancer_method;
    
    /* 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 */
        ap_regex_t *regexp;     /* compiled regex (if any) for the remote */
        const char *creds;      /* auth credentials (if any) for the proxy */
        int use_regex;          /* simple boolean. True if we have a regex pattern */
        apr_port_t  port;       /* the port for this proxy */
    };
    
    #define PROXYPASS_NOCANON 0x01
    #define PROXYPASS_INTERPOLATE 0x02
    #define PROXYPASS_NOQUERY 0x04
    #define PROXYPASS_MAP_ENCODED 0x08
    #define PROXYPASS_MAP_SERVLET 0x18 /* + MAP_ENCODED */
    struct proxy_alias {
        const char  *real;
        const char  *fake;
        ap_regex_t  *regex;
        unsigned int flags;
        proxy_balancer *balancer; /* only valid for reverse-proxys */
    };
    
    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 {
        apr_array_header_t *proxies;
        apr_array_header_t *sec_proxy;
        apr_array_header_t *aliases;
        apr_array_header_t *noproxies;
        apr_array_header_t *dirconn;
        apr_array_header_t *workers;    /* non-balancer workers, eg ProxyPass http://example.com */
        apr_array_header_t *balancers;  /* list of balancers @ config time */
        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 */
        const char *id;
        apr_pool_t *pool;       /* Pool used for allocating this struct's elements */
        int req;                /* true if proxy requests are enabled */
        int max_balancers;      /* maximum number of allowed balancers */
        int bgrowth;            /* number of post-config balancers can added */
        enum {
          via_off,
          via_on,
          via_block,
          via_full
        } viaopt;                   /* how to deal with proxy Via: headers */
        apr_size_t recv_buffer_size;
        apr_size_t io_buffer_size;
        long maxfwd;
        apr_interval_time_t timeout;
        enum {
          bad_error,
          bad_ignore,
          bad_body
        } badopt;                   /* how to deal with bad headers */
        enum {
            status_off,
            status_on,
            status_full
        } proxy_status;             /* Status display options */
        apr_sockaddr_t *source_address;
        apr_global_mutex_t  *mutex; /* global lock, for pool, etc */
        ap_slotmem_instance_t *bslot;  /* balancers shm data - runtime */
        ap_slotmem_provider_t *storage;
    
        unsigned int req_set:1;
        unsigned int viaopt_set:1;
        unsigned int recv_buffer_size_set:1;
        unsigned int io_buffer_size_set:1;
        unsigned int maxfwd_set:1;
        unsigned int timeout_set:1;
        unsigned int badopt_set:1;
        unsigned int proxy_status_set:1;
        unsigned int source_address_set:1;
        unsigned int bgrowth_set:1;
        unsigned int bal_persist:1;
        unsigned int inherit:1;
        unsigned int inherit_set:1;
        unsigned int ppinherit:1;
        unsigned int ppinherit_set:1;
        unsigned int map_encoded_one:1;
        unsigned int map_encoded_all:1;
    } proxy_server_conf;
    
    typedef struct {
        const char *p;            /* The path */
        ap_regex_t  *r;            /* Is this a regex? */
    
    /* FIXME
     * ProxyPassReverse and friends are documented as working inside
     * <Location>.  But in fact they never have done in the case of
     * more than one <Location>, because the server_conf can't see it.
     * We need to move them to the per-dir config.
     * Discussed in February 2005:
     * http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=110726027118798&w=2
     */
        apr_array_header_t *raliases;
        apr_array_header_t* cookie_paths;
        apr_array_header_t* cookie_domains;
        signed char p_is_fnmatch; /* Is the path an fnmatch candidate? */
        signed char interpolate_env;
        struct proxy_alias *alias;
    
        /**
         * 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
         */
        unsigned int error_override:1;
        unsigned int preserve_host:1;
        unsigned int preserve_host_set:1;
        unsigned int error_override_set:1;
        unsigned int alias_set:1;
        unsigned int add_forwarded_headers:1;
        unsigned int add_forwarded_headers_set:1;
    
        /** Named back references */
        apr_array_header_t *refs;
    
        unsigned int forward_100_continue:1;
        unsigned int forward_100_continue_set:1;
    
        apr_array_header_t *error_override_codes;
    } proxy_dir_conf;
    
    /* if we interpolate env vars per-request, we'll need a per-request
     * copy of the reverse proxy config
     */
    typedef struct {
        apr_array_header_t *raliases;
        apr_array_header_t* cookie_paths;
        apr_array_header_t* cookie_domains;
    } proxy_req_conf;
    
    struct proxy_address; /* opaque TTL'ed and refcount'ed address */
    
    typedef struct {
        conn_rec     *connection;
        request_rec  *r;           /* Request record of the backend request
                                    * that is used over the backend connection. */
        proxy_worker *worker;      /* Connection pool this connection belongs to */
        apr_pool_t   *pool;        /* Subpool for hostname and addr data */
        const char   *hostname;
        apr_sockaddr_t *addr;      /* Preparsed remote address info */
        apr_pool_t   *scpool;      /* Subpool used for socket and connection data */
        apr_socket_t *sock;        /* Connection socket */
        void         *data;        /* per scheme connection data */
        void         *forward;     /* opaque forward proxy data */
        apr_uint32_t flags;        /* Connection flags */
        apr_port_t   port;
        unsigned int is_ssl:1;
        unsigned int close:1;      /* Close 'this' connection */
        unsigned int need_flush:1; /* Flag to decide whether we need to flush the
                                    * filter chain or not */
        unsigned int inreslist:1;  /* connection in apr_reslist? */
        const char   *uds_path;    /* Unix domain socket path */
        const char   *ssl_hostname;/* Hostname (SNI) in use by SSL connection */
        apr_bucket_brigade *tmp_bb;/* Temporary brigade created with the connection
                                    * and its scpool/bucket_alloc (NULL before),
                                    * must be left cleaned when used (locally).
                                    */
        apr_pool_t   *uds_pool;     /* Subpool for reusing UDS paths */
        apr_pool_t   *fwd_pool;     /* Subpool for reusing ProxyRemote infos */
        struct proxy_address *address; /* Current remote address */
    } 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 */
        apr_reslist_t  *res;      /* Connection resource list */
        proxy_conn_rec *conn;     /* Single connection for prefork mpm */
        apr_pool_t     *dns_pool; /* The pool used for worker scoped DNS resolutions */
    };
    
    #define AP_VOLATILIZE_T(T, x) (*(T volatile *)&(x))
    
    /* worker status bits */
    /*
     * NOTE: Keep up-to-date w/ proxy_wstat_tbl[]
     * in mod_proxy.c !
     */
    #define PROXY_WORKER_INITIALIZED    0x0001
    #define PROXY_WORKER_IGNORE_ERRORS  0x0002
    #define PROXY_WORKER_DRAIN          0x0004
    #define PROXY_WORKER_GENERIC        0x0008
    #define PROXY_WORKER_IN_SHUTDOWN    0x0010
    #define PROXY_WORKER_DISABLED       0x0020
    #define PROXY_WORKER_STOPPED        0x0040
    #define PROXY_WORKER_IN_ERROR       0x0080
    #define PROXY_WORKER_HOT_STANDBY    0x0100
    #define PROXY_WORKER_FREE           0x0200
    #define PROXY_WORKER_HC_FAIL        0x0400
    #define PROXY_WORKER_HOT_SPARE      0x0800
    
    /* worker status flags */
    #define PROXY_WORKER_INITIALIZED_FLAG    'O'
    #define PROXY_WORKER_IGNORE_ERRORS_FLAG  'I'
    #define PROXY_WORKER_DRAIN_FLAG          'N'
    #define PROXY_WORKER_GENERIC_FLAG        'G'
    #define PROXY_WORKER_IN_SHUTDOWN_FLAG    'U'
    #define PROXY_WORKER_DISABLED_FLAG       'D'
    #define PROXY_WORKER_STOPPED_FLAG        'S'
    #define PROXY_WORKER_IN_ERROR_FLAG       'E'
    #define PROXY_WORKER_HOT_STANDBY_FLAG    'H'
    #define PROXY_WORKER_FREE_FLAG           'F'
    #define PROXY_WORKER_HC_FAIL_FLAG        'C'
    #define PROXY_WORKER_HOT_SPARE_FLAG      'R'
    
    #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
    PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR | \
    PROXY_WORKER_HC_FAIL )
    
    /* NOTE: these check the shared status */
    #define PROXY_WORKER_IS_INITIALIZED(f)  ( (f)->s->status &  PROXY_WORKER_INITIALIZED )
    
    #define PROXY_WORKER_IS_STANDBY(f)   ( (f)->s->status &  PROXY_WORKER_HOT_STANDBY )
    
    #define PROXY_WORKER_IS_SPARE(f)   ( (f)->s->status &  PROXY_WORKER_HOT_SPARE )
    
    #define PROXY_WORKER_IS_USABLE(f)   ( ( !( (f)->s->status & PROXY_WORKER_NOT_USABLE_BITMAP) ) && \
      PROXY_WORKER_IS_INITIALIZED(f) )
    
    #define PROXY_WORKER_IS_DRAINING(f)   ( (f)->s->status &  PROXY_WORKER_DRAIN )
    
    #define PROXY_WORKER_IS_GENERIC(f)   ( (f)->s->status &  PROXY_WORKER_GENERIC )
    
    #define PROXY_WORKER_IS_HCFAILED(f)   ( (f)->s->status &  PROXY_WORKER_HC_FAIL )
    
    #define PROXY_WORKER_IS_ERROR(f)   ( (f)->s->status &  PROXY_WORKER_IN_ERROR )
    
    #define PROXY_WORKER_IS(f, b)   ( (f)->s->status & (b) )
    
    /* default worker retry timeout in seconds */
    #define PROXY_WORKER_DEFAULT_RETRY    60
    
    /* Some max char string sizes, for shm fields */
    #define PROXY_WORKER_MAX_SCHEME_SIZE    16
    #define PROXY_WORKER_MAX_ROUTE_SIZE     64
    #define PROXY_BALANCER_MAX_ROUTE_SIZE PROXY_WORKER_MAX_ROUTE_SIZE
    #define PROXY_WORKER_MAX_NAME_SIZE      96
    #define PROXY_BALANCER_MAX_NAME_SIZE PROXY_WORKER_MAX_NAME_SIZE
    #define PROXY_WORKER_MAX_HOSTNAME_SIZE  64
    #define PROXY_BALANCER_MAX_HOSTNAME_SIZE PROXY_WORKER_MAX_HOSTNAME_SIZE
    #define PROXY_BALANCER_MAX_STICKY_SIZE  64
    #define PROXY_WORKER_MAX_SECRET_SIZE     64
    
    #define PROXY_RFC1035_HOSTNAME_SIZE	256
    #define PROXY_WORKER_EXT_NAME_SIZE      384
    
    /* RFC-1035 mentions limits of 255 for host-names and 253 for domain-names,
     * dotted together(?) this would fit the below size (+ trailing NUL).
     */
    #define PROXY_WORKER_RFC1035_NAME_SIZE  512
    
    #define PROXY_MAX_PROVIDER_NAME_SIZE    16
    
    #define PROXY_STRNCPY(dst, src) ap_proxy_strncpy((dst), (src), (sizeof(dst)))
    
    #define PROXY_COPY_CONF_PARAMS(w, c) \
    do {                             \
    (w)->s->timeout              = (c)->timeout;               \
    (w)->s->timeout_set          = (c)->timeout_set;           \
    (w)->s->recv_buffer_size     = (c)->recv_buffer_size;      \
    (w)->s->recv_buffer_size_set = (c)->recv_buffer_size_set;  \
    (w)->s->io_buffer_size       = (c)->io_buffer_size;        \
    (w)->s->io_buffer_size_set   = (c)->io_buffer_size_set;    \
    } while (0)
    
    #define PROXY_SHOULD_PING_100_CONTINUE(w, r) \
        ((w)->s->ping_timeout_set \
         && (PROXYREQ_REVERSE == (r)->proxyreq) \
         && ap_request_has_body((r)))
    
    #define PROXY_DO_100_CONTINUE(w, r) \
        (PROXY_SHOULD_PING_100_CONTINUE(w, r) \
         && !apr_table_get((r)->subprocess_env, "force-proxy-request-1.0"))
    
    /* use 2 hashes */
    typedef struct {
        unsigned int def;
        unsigned int fnv;
    } proxy_hashes ;
    
    /* Runtime worker status information. Shared in scoreboard */
    /* The addition of member uds_path in 2.4.7 was an incompatible API change. */
    typedef struct {
        char      name[PROXY_WORKER_MAX_NAME_SIZE];
        char      scheme[PROXY_WORKER_MAX_SCHEME_SIZE];   /* scheme to use ajp|http|https */
        char      hostname[PROXY_WORKER_MAX_HOSTNAME_SIZE];  /* remote backend address (deprecated, use hostname_ex below) */
        char      route[PROXY_WORKER_MAX_ROUTE_SIZE];     /* balancing route */
        char      redirect[PROXY_WORKER_MAX_ROUTE_SIZE];  /* temporary balancing redirection route */
        char      flusher[PROXY_WORKER_MAX_SCHEME_SIZE];  /* flush provider used by mod_proxy_fdpass */
        char      uds_path[PROXY_WORKER_MAX_NAME_SIZE];   /* path to worker's unix domain socket if applicable */
        int             lbset;      /* load balancer cluster set */
        int             retries;    /* number of retries on this worker */
        int             lbstatus;   /* Current lbstatus */
        int             lbfactor;   /* dynamic lbfactor */
        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 */
        int             flush_wait; /* poll wait time in microseconds if flush_auto */
        int             index;      /* shm array index */
        proxy_hashes    hash;       /* hash of worker name */
        unsigned int    status;     /* worker status bitfield */
        enum {
            flush_off,
            flush_on,
            flush_auto
        } flush_packets;           /* control AJP flushing */
        apr_time_t      updated;    /* timestamp of last update for dynamic workers, or queue-time of HC workers */
        apr_time_t      error_time; /* time of the last error */
        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 retry;   /* retry interval */
        apr_interval_time_t timeout; /* connection timeout */
        apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
        apr_interval_time_t ping_timeout;
        apr_interval_time_t conn_timeout;
        apr_size_t      recv_buffer_size;
        apr_size_t      io_buffer_size;
        apr_size_t      elected;    /* Number of times the worker was elected */
        apr_size_t      busy;       /* busyness factor */
        apr_port_t      port;
        apr_off_t       transferred;/* Number of bytes transferred to remote */
        apr_off_t       read;       /* Number of bytes read from remote */
        void            *context;   /* general purpose storage */
        unsigned int     keepalive:1;
        unsigned int     disablereuse:1;
        unsigned int     is_address_reusable:1;
        unsigned int     retry_set:1;
        unsigned int     timeout_set:1;
        unsigned int     acquire_set:1;
        unsigned int     ping_timeout_set:1;
        unsigned int     conn_timeout_set:1;
        unsigned int     recv_buffer_size_set:1;
        unsigned int     io_buffer_size_set:1;
        unsigned int     keepalive_set:1;
        unsigned int     disablereuse_set:1;
        unsigned int     was_malloced:1;
        unsigned int     is_name_matchable:1;
        char      hcuri[PROXY_WORKER_MAX_ROUTE_SIZE];     /* health check uri */
        char      hcexpr[PROXY_WORKER_MAX_SCHEME_SIZE];   /* name of condition expr for health check */
        int             passes;     /* number of successes for check to pass */
        int             pcount;     /* current count of passes */
        int             fails;      /* number of failures for check to fail */
        int             fcount;     /* current count of failures */
        hcmethod_t      method;     /* method to use for health check */
        apr_interval_time_t interval;
        char      upgrade[PROXY_WORKER_MAX_SCHEME_SIZE];/* upgrade protocol used by mod_proxy_wstunnel */
        char      hostname_ex[PROXY_RFC1035_HOSTNAME_SIZE];  /* RFC1035 compliant version of the remote backend address */
        apr_size_t   response_field_size; /* Size of proxy response buffer in bytes. */
        unsigned int response_field_size_set:1;
        char      secret[PROXY_WORKER_MAX_SECRET_SIZE]; /* authentication secret (e.g. AJP13) */
        char      name_ex[PROXY_WORKER_EXT_NAME_SIZE]; /* Extended name (>96 chars for 2.4.x) */
        unsigned int     address_ttl_set:1;
        apr_int32_t      address_ttl;    /* backend address' TTL (seconds) */
        apr_uint32_t     address_expiry; /* backend address' next expiry time */
        unsigned int     is_host_matchable:1;
    } proxy_worker_shared;
    
    #define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))
    
    /* Worker configuration */
    struct proxy_worker {
        proxy_hashes    hash;       /* hash of worker name */
        unsigned int local_status;  /* status of per-process worker */
        proxy_conn_pool     *cp;    /* Connection pool to use */
        proxy_worker_shared   *s;   /* Shared data */
        proxy_balancer  *balancer;  /* which balancer am I in? */
    #if APR_HAS_THREADS
        apr_thread_mutex_t  *tmutex; /* Thread lock for updating address cache */
    #endif
        void            *context;   /* general purpose storage */
        ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */
        struct proxy_address *volatile address; /* current worker address (if reusable) */
    };
    
    /* default to health check every 30 seconds */
    #define HCHECK_WATHCHDOG_DEFAULT_INTERVAL (30)
    /* The watchdog runs every 2 seconds, which is also the minimal check */
    #define HCHECK_WATHCHDOG_INTERVAL (2)
    
    /*
     * Time to wait (in microseconds) to find out if more data is currently
     * available at the backend.
     */
    #define PROXY_FLUSH_WAIT 10000
    
    typedef struct {
        char      sticky_path[PROXY_BALANCER_MAX_STICKY_SIZE];     /* URL sticky session identifier */
        char      sticky[PROXY_BALANCER_MAX_STICKY_SIZE];          /* sticky session identifier */
        char      lbpname[PROXY_MAX_PROVIDER_NAME_SIZE];  /* lbmethod provider name */
        char      nonce[APR_UUID_FORMATTED_LENGTH + 1];
        char      name[PROXY_BALANCER_MAX_NAME_SIZE];
        char      sname[PROXY_BALANCER_MAX_NAME_SIZE];
        char      vpath[PROXY_BALANCER_MAX_ROUTE_SIZE];
        char      vhost[PROXY_BALANCER_MAX_HOSTNAME_SIZE];
        apr_interval_time_t timeout;  /* Timeout for waiting on free connection */
        apr_time_t      wupdated;     /* timestamp of last change to workers list */
        int             max_attempts;     /* Number of attempts before failing */
        int             index;      /* shm array index */
        proxy_hashes hash;
        unsigned int    sticky_force:1;   /* Disable failover for sticky sessions */
        unsigned int    scolonsep:1;      /* true if ';' seps sticky session paths */
        unsigned int    max_attempts_set:1;
        unsigned int    was_malloced:1;
        unsigned int    need_reset:1;
        unsigned int    vhosted:1;
        unsigned int    inactive:1;
        unsigned int    forcerecovery:1;
        char      sticky_separator;                                /* separator for sessionid/route */
        unsigned int    forcerecovery_set:1;
        unsigned int    scolonsep_set:1;
        unsigned int    sticky_force_set:1; 
        unsigned int    nonce_set:1;
        unsigned int    sticky_separator_set:1;
    } proxy_balancer_shared;
    
    #define ALIGNED_PROXY_BALANCER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_balancer_shared)))
    
    struct proxy_balancer {
        apr_array_header_t *workers;  /* initially configured workers */
        apr_array_header_t *errstatuses;  /* statuses to force members into error */
        ap_slotmem_instance_t *wslot;  /* worker shm data - runtime */
        ap_slotmem_provider_t *storage;
        int growth;                   /* number of post-config workers can added */
        int max_workers;              /* maximum number of allowed workers */
        proxy_hashes hash;
        apr_time_t      wupdated;    /* timestamp of last change to workers list */
        proxy_balancer_method *lbmethod;
        apr_global_mutex_t  *gmutex; /* global lock for updating list of workers */
    #if APR_HAS_THREADS
        apr_thread_mutex_t  *tmutex; /* Thread lock for updating shm */
    #endif
        proxy_server_conf *sconf;
        void            *context;    /* general purpose storage */
        proxy_balancer_shared *s;    /* Shared data */
        int failontimeout;           /* Whether to mark a member in Err if IO timeout occurs */
        unsigned int failontimeout_set:1;
        unsigned int growth_set:1;
        unsigned int lbmethod_set:1;
        ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */
    };
    
    struct proxy_balancer_method {
        const char *name;            /* name of the load balancer method*/
        proxy_worker *(*finder)(proxy_balancer *balancer,
                                request_rec *r);
        void            *context;   /* general purpose storage */
        apr_status_t (*reset)(proxy_balancer *balancer, server_rec *s);
        apr_status_t (*age)(proxy_balancer *balancer, server_rec *s);
        apr_status_t (*updatelbstatus)(proxy_balancer *balancer, proxy_worker *elected, server_rec *s);
    };
    
    #define PROXY_THREAD_LOCK(x)      ( (x) && (x)->tmutex ? apr_thread_mutex_lock((x)->tmutex) : APR_SUCCESS)
    #define PROXY_THREAD_UNLOCK(x)    ( (x) && (x)->tmutex ? apr_thread_mutex_unlock((x)->tmutex) : APR_SUCCESS)
    
    #define PROXY_GLOBAL_LOCK(x)      ( (x) && (x)->gmutex ? apr_global_mutex_lock((x)->gmutex) : APR_SUCCESS)
    #define PROXY_GLOBAL_UNLOCK(x)    ( (x) && (x)->gmutex ? apr_global_mutex_unlock((x)->gmutex) : APR_SUCCESS)
    
    /* 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
    
    /* Using PROXY_DECLARE_OPTIONAL_HOOK instead of
     * APR_DECLARE_EXTERNAL_HOOK allows build/make_nw_export.awk
     * to distinguish between hooks that implement
     * proxy_hook_xx and proxy_hook_get_xx in mod_proxy.c and
     * those which don't.
     */
    #define PROXY_DECLARE_OPTIONAL_HOOK APR_DECLARE_EXTERNAL_HOOK
    
    /* These 2 are in mod_proxy.c */
    extern PROXY_DECLARE_DATA proxy_hcmethods_t proxy_hcmethods[];
    extern PROXY_DECLARE_DATA proxy_wstat_t proxy_wstat_tbl[];
    
    /* Following 4 from health check */
    APR_DECLARE_OPTIONAL_FN(void, hc_show_exprs, (request_rec *));
    APR_DECLARE_OPTIONAL_FN(void, hc_select_exprs, (request_rec *, const char *));
    APR_DECLARE_OPTIONAL_FN(int, hc_valid_expr, (request_rec *, const char *));
    APR_DECLARE_OPTIONAL_FN(const char *, set_worker_hc_param,
                            (apr_pool_t *, server_rec *, proxy_worker *,
                             const char *, const char *, void *));
    
    APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, section_post_config,
                              (apr_pool_t *p, apr_pool_t *plog,
                               apr_pool_t *ptemp, server_rec *s,
                               ap_conf_vector_t *section_config))
    
    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, check_trans,
                              (request_rec *r, const char *url))
    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 corresponding 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))
    
    /**
     * request status hook
     * It is called after all proxy processing has been done.  This gives other
     * modules a chance to create default content on failure, for example
     */
    APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, request_status,
                              (int *status, request_rec *r))
    
    /* proxy_util.c */
    
    PROXY_DECLARE(apr_status_t) ap_proxy_strncpy(char *dst, const char *src,
                                                 apr_size_t dlen);
    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_ex(apr_pool_t *p, const char *x, int len, enum enctype t,
                                              int flags, int proxyreq);
    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(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
    PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
    
    /** Test whether the hostname/address of the request are blocked by the ProxyBlock
     * configuration.
     * @param r         request
     * @param conf      server configuration
     * @param hostname  hostname from request URI
     * @param addr      resolved address of hostname, or NULL if not known
     * @return OK on success, or else an error
     */
    PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf, 
                                                 const char *hostname, apr_sockaddr_t *addr);
    
    PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
    /* 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 *, request_rec *);
    /* DEPRECATED (will be replaced with ap_proxy_check_connection */
    PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn,
                                                                request_rec *r);
    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_ssl_engine(conn_rec *c,
                                           ap_conf_vector_t *per_dir_config,
                                           int enable);
    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_dir_conf *conf, const char *url);
    PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str);
    
    #if !defined(WIN32)
    typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *,
                           proxy_dir_conf *, const char *);
    #elif defined(PROXY_DECLARE_STATIC)
    typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
                                     proxy_dir_conf *, const char *);
    #elif defined(PROXY_DECLARE_EXPORT)
    typedef __declspec(dllexport) const char *
      (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
                   proxy_dir_conf *, const char *);
    #else
    typedef __declspec(dllimport) const char *
      (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
                   proxy_dir_conf *, const char *);
    #endif
    
    
    /* Connection pool API */
    /**
     * Return the user-land, UDS aware worker name
     * @param p        memory pool used for displaying worker name
     * @param worker   the worker
     * @return         name
     */
    
    PROXY_DECLARE(char *) ap_proxy_worker_name(apr_pool_t *p,
                                               proxy_worker *worker);
    
    /**
     * Return whether a worker upgrade configuration matches Upgrade header
     * @param p       memory pool used for displaying worker name
     * @param worker  the worker
     * @param upgrade the Upgrade header to match
     * @param dflt    default protocol (NULL for none)
     * @return        1 (true) or 0 (false)
     */
    PROXY_DECLARE(int) ap_proxy_worker_can_upgrade(apr_pool_t *p,
                                                   const proxy_worker *worker,
                                                   const char *upgrade,
                                                   const char *dflt);
    
    /* Bitmask for ap_proxy_{define,get}_worker_ex(). */
    #define AP_PROXY_WORKER_IS_PREFIX   (1u << 0)
    #define AP_PROXY_WORKER_IS_MATCH    (1u << 1)
    #define AP_PROXY_WORKER_IS_MALLOCED (1u << 2)
    #define AP_PROXY_WORKER_NO_UDS      (1u << 3)
    
    /**
     * Get the worker from proxy configuration, looking for either PREFIXED or
     * MATCHED or both types of workers according to given mask
     * @param p        memory pool used for finding worker
     * @param balancer the balancer that the worker belongs to
     * @param conf     current proxy server configuration
     * @param url      url to find the worker from
     * @param mask     bitmask of AP_PROXY_WORKER_IS_*
     * @return         proxy_worker or NULL if not found
     */
    PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p,
                                                         proxy_balancer *balancer,
                                                         proxy_server_conf *conf,
                                                         const char *url,
                                                         unsigned int mask);
    
    /**
     * Get the worker from proxy configuration, both types
     * @param p        memory pool used for finding worker
     * @param balancer the balancer that the worker belongs to
     * @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_balancer *balancer,
                                                      proxy_server_conf *conf,
                                                      const char *url);
    
    /**
     * Define and Allocate space for the worker to proxy configuration, of either
     * PREFIXED or MATCHED type according to given mask
     * @param p         memory pool to allocate worker from
     * @param worker    the new worker
     * @param balancer  the balancer that the worker belongs to
     * @param conf      current proxy server configuration
     * @param url       url containing worker name
     * @param mask      bitmask of AP_PROXY_WORKER_IS_*
     * @return          error message or NULL if successful (*worker is new worker)
     */
    PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p,
                                                 proxy_worker **worker,
                                                 proxy_balancer *balancer,
                                                 proxy_server_conf *conf,
                                                 const char *url,
                                                 unsigned int mask);
    
     /**
     * Define and Allocate space for the worker to proxy configuration
     * @param p         memory pool to allocate worker from
     * @param worker    the new worker
     * @param balancer  the balancer that the worker belongs to
     * @param conf      current proxy server configuration
     * @param url       url containing worker name
     * @param do_malloc true if shared struct should be malloced
     * @return          error message or NULL if successful (*worker is new worker)
     */
    PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
                                                 proxy_worker **worker,
                                                 proxy_balancer *balancer,
                                                 proxy_server_conf *conf,
                                                 const char *url,
                                                 int do_malloc);
    
    /**
     * Define and Allocate space for the ap_strcmp_match()able worker to proxy
     * configuration.
     * @param p         memory pool to allocate worker from
     * @param worker    the new worker
     * @param balancer  the balancer that the worker belongs to
     * @param conf      current proxy server configuration
     * @param url       url containing worker name (produces match pattern)
     * @param do_malloc true if shared struct should be malloced
     * @return          error message or NULL if successful (*worker is new worker)
     * @deprecated Replaced by ap_proxy_define_worker_ex()
     */
    PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
                                                 proxy_worker **worker,
                                                 proxy_balancer *balancer,
                                                 proxy_server_conf *conf,
                                                 const char *url,
                                                 int do_malloc);
    
    /**
     * Share a defined proxy worker via shm
     * @param worker  worker to be shared
     * @param shm     location of shared info
     * @param i       index into shm
     * @return        APR_SUCCESS or error code
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_share_worker(proxy_worker *worker,
                                                      proxy_worker_shared *shm,
                                                      int i);
    
    /**
     * Initialize the worker by setting up worker connection pool and mutex
     * @param worker worker to initialize
     * @param s      current server record
     * @param p      memory pool used for mutex and connection pool
     * @return       APR_SUCCESS or error code
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker,
                                                           server_rec *s,
                                                           apr_pool_t *p);
    
    /**
     * Verifies valid balancer name (eg: balancer://foo)
     * @param name  name to test
     * @param i     number of chars to test; 0 for all.
     * @return      true/false
     */
    PROXY_DECLARE(int) ap_proxy_valid_balancer_name(char *name, int i);
    
    
    /**
     * Get the balancer from proxy configuration
     * @param p     memory pool used for temporary storage while finding balancer
     * @param conf  current proxy server configuration
     * @param url   url to find the worker from; must have balancer:// prefix
     * @param careactive true if we care if the balancer is active or not
     * @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,
                                                          int careactive);
    
    /**
     * Update the balancer's vhost related fields
     * @param p     memory pool used for temporary storage while finding balancer
     * @param balancer  balancer to be updated
     * @param url   url to find vhost info
     * @return      error string or NULL if OK
     */
    PROXY_DECLARE(char *) ap_proxy_update_balancer(apr_pool_t *p,
                                                   proxy_balancer *balancer,
                                                   const char *url);
    
    /**
     * Define and Allocate space for the balancer to proxy configuration
     * @param p      memory pool to allocate balancer from
     * @param balancer the new balancer
     * @param conf   current proxy server configuration
     * @param url    url containing balancer name
     * @param alias  alias/fake-path to this balancer
     * @param do_malloc true if shared struct should be malloced
     * @return       error message or NULL if successful
     */
    PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
                                                   proxy_balancer **balancer,
                                                   proxy_server_conf *conf,
                                                   const char *url,
                                                   const char *alias,
                                                   int do_malloc);
    
    /**
     * Share a defined proxy balancer via shm
     * @param balancer  balancer to be shared
     * @param shm       location of shared info
     * @param i         index into shm
     * @return          APR_SUCCESS or error code
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
                                                        proxy_balancer_shared *shm,
                                                        int i);
    
    /**
     * Initialize the balancer as needed
     * @param balancer balancer to initialize
     * @param s        current server record
     * @param p        memory pool used for mutex and connection pool
     * @return         APR_SUCCESS or error code
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer,
                                                             server_rec *s,
                                                             apr_pool_t *p);
    
    typedef int (proxy_is_best_callback_fn_t)(proxy_worker *current, proxy_worker *prev_best, void *baton);
    
    /**
     * Retrieve the best worker in a balancer for the current request
     * @param balancer balancer for which to find the best worker
     * @param r        current request record
     * @param is_best  a callback function provide by the lbmethod
     *                 that determines if the current worker is best
     * @param baton    an lbmethod-specific context pointer (baton)
     *                 passed to the is_best callback
     * @return         the best worker to be used for the request
     */
    PROXY_DECLARE(proxy_worker *) ap_proxy_balancer_get_best_worker(proxy_balancer *balancer,
                                                                    request_rec *r,
                                                                    proxy_is_best_callback_fn_t *is_best,
                                                                    void *baton);
    /*
     * Needed by the lb modules.
     */
    APR_DECLARE_OPTIONAL_FN(proxy_worker *, proxy_balancer_get_best_worker,
                                            (proxy_balancer *balancer,
                                             request_rec *r,
                                             proxy_is_best_callback_fn_t *is_best,
                                             void *baton));
    
    /**
     * Find the shm of the worker as needed
     * @param storage slotmem provider
     * @param slot    slotmem instance
     * @param worker  worker to find
     * @param index   pointer to index within slotmem of worker
     * @return        pointer to shm of worker, or NULL
     */
    PROXY_DECLARE(proxy_worker_shared *) ap_proxy_find_workershm(ap_slotmem_provider_t *storage,
                                                                 ap_slotmem_instance_t *slot,
                                                                 proxy_worker *worker,
                                                                 unsigned int *index);
    
    /**
     * Find the shm of the balancer as needed
     * @param storage  slotmem provider
     * @param slot     slotmem instance
     * @param balancer balancer of shm to find
     * @param index    pointer to index within slotmem of balancer
     * @return         pointer to shm of balancer, or NULL
     */
    PROXY_DECLARE(proxy_balancer_shared *) ap_proxy_find_balancershm(ap_slotmem_provider_t *storage,
                                                                     ap_slotmem_instance_t *slot,
                                                                     proxy_balancer *balancer,
                                                                     unsigned int *index);
    
    /*
     * Strip the UDS part of r->filename if any, and put the UDS path in
     * r->notes ("uds_path")
     * @param r        current request
     * @return         OK if fixed up, DECLINED if not UDS, or an HTTP_XXX error
     * @remark Deprecated (for internal use only)
     */
    PROXY_DECLARE(int) ap_proxy_fixup_uds_filename(request_rec *r);
    
    /**
     * 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 Whenever 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);
    
    /* Bitmask for ap_proxy_determine_address() */
    #define PROXY_DETERMINE_ADDRESS_CHECK   (1u << 0)
    /**
     * Resolve an address, reusing the one of the worker if any.
     * @param proxy_function calling proxy scheme (http, ajp, ...)
     * @param conn     proxy connection the address is used for
     * @param hostname host to resolve (should be the worker's if reusable)
     * @param hostport port to resolve (should be the worker's if reusable)
     * @param flags    bitmask of PROXY_DETERMINE_ADDRESS_*
     * @param r        current request (if any)
     * @param s        current server (or NULL if r != NULL and ap_proxyerror()
     *                                 should be called on error)
     * @return         APR_SUCCESS or an error, APR_EEXIST if the address is still
     *                 the same and PROXY_DETERMINE_ADDRESS_CHECK is asked
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_determine_address(const char *proxy_function,
                                                           proxy_conn_rec *conn,
                                                           const char *hostname,
                                                           apr_port_t hostport,
                                                           unsigned int flags,
                                                           request_rec *r,
                                                           server_rec *s);
    
    /**
     * Determine 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 a proxy
     * @param proxyport proxy host port
     * @param server_portstr Via headers server port, must be non-NULL
     * @param server_portstr_size size of the server_portstr buffer; must
     * be at least one, even if the protocol doesn't use this
     * @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 worker  worker used for retrying
     * @param s       current server record
     * @return        OK if marked for retry, DECLINED otherwise
     * @note The error status of the worker will cleared if the retry interval has
     * elapsed since the last error.
     */
    APR_DECLARE_OPTIONAL_FN(int, ap_proxy_retry_worker,
            (const char *proxy_function, proxy_worker *worker, server_rec *s));
    
    /**
     * Acquire a connection from worker 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 connection limit has been reached, the function will
     * block until a connection becomes available or the timeout has
     * elapsed.
     */
    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);
    
    #define PROXY_CHECK_CONN_EMPTY (1 << 0)
    /**
     * Check a connection to the backend
     * @param scheme calling proxy scheme (http, ajp, ...)
     * @param conn   acquired connection
     * @param server current server record
     * @param max_blank_lines how many blank lines to consume,
     *                        or zero for none (considered data)
     * @param flags  PROXY_CHECK_* bitmask
     * @return APR_SUCCESS: connection established,
     *         APR_ENOTEMPTY: connection established with data,
     *         APR_ENOSOCKET: not connected,
     *         APR_EINVAL: worker in error state (unusable),
     *         other: connection closed/aborted (remotely)
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_check_connection(const char *scheme,
                                                          proxy_conn_rec *conn,
                                                          server_rec *server,
                                                          unsigned max_blank_lines,
                                                          int flags);
    
    /**
     * 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 to a Unix Domain Socket (UDS) path
     * @param sock     UDS to connect
     * @param uds_path UDS path to connect to
     * @param p        pool to make the sock addr
     * @return         APR_SUCCESS or error status
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock,
                                                     const char *uds_path,
                                                     apr_pool_t *p);
    /**
     * Make a connection record for backend connection
     * @param proxy_function calling proxy scheme (http, ajp, ...)
     * @param conn    acquired connection
     * @param c       client connection record (unused, deprecated)
     * @param s       current server record
     * @return        OK or HTTP_XXX error
     * @note The function will return immediately if conn->connection
     * is already set,
     */
    PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
                                                  proxy_conn_rec *conn,
                                                  conn_rec *c, server_rec *s);
    
    /**
     * Make a connection record for backend connection, using request dir config
     * @param proxy_function calling proxy scheme (http, ajp, ...)
     * @param conn    acquired connection
     * @param r       current request record
     * @return        OK or HTTP_XXX error
     * @note The function will return immediately if conn->connection
     * is already set,
     */
    PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function,
                                                     proxy_conn_rec *conn,
                                                     request_rec *r);
    /**
     * Determine if proxy connection can potentially be reused at the
     * end of this request.
     * @param conn proxy connection
     * @return non-zero if reusable, 0 otherwise
     * @note Even if this function returns non-zero, the connection may
     * be subsequently marked for closure.
     */
    PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn);
    
    /**
     * Signal the upstream chain that the connection to the backend broke in the
     * middle of the response. This is done by sending an error bucket with
     * status HTTP_BAD_GATEWAY and an EOS bucket up the filter chain.
     * @param r       current request record of client request
     * @param brigade The brigade that is sent through the output filter chain
     */
    PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
                                               apr_bucket_brigade *brigade);
    
    /**
     * Return a hash based on the passed string
     * @param str     string to produce hash from
     * @param method  hashing method to use
     * @return        hash as unsigned int
     */
    
    typedef enum { PROXY_HASHFUNC_DEFAULT, PROXY_HASHFUNC_APR,  PROXY_HASHFUNC_FNV } proxy_hash_t;
    
    PROXY_DECLARE(unsigned int) ap_proxy_hashfunc(const char *str, proxy_hash_t method);
    
    
    /**
     * Set/unset the worker status bitfield depending on flag
     * @param c    flag
     * @param set  set or unset bit
     * @param w    worker to use
     * @return     APR_SUCCESS if valid flag
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_set_wstatus(char c, int set, proxy_worker *w);
    
    
    /**
     * Create readable representation of worker status bitfield
     * @param p  pool
     * @param w  worker to use
     * @return   string representation of status
     */
    PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w);
    
    
    /**
     * Sync balancer and workers based on any updates w/i shm
     * @param b  balancer to check/update member list of
     * @param s  server rec
     * @param conf config
     * @return   APR_SUCCESS if all goes well
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b,
                                                       server_rec *s,
                                                       proxy_server_conf *conf);
    
    /**
     * Configure and create workers (and balancer) in mod_balancer.
     * @param r request
     * @param params table with the parameters like b=mycluster etc.
     * @return 404 when the worker/balancer doesn't exist,
     *         400 if something is invalid
     *         200 for success.
     */ 
    APR_DECLARE_OPTIONAL_FN(apr_status_t, balancer_manage,
            (request_rec *, apr_table_t *params));
    
    /**
     * Find the matched alias for this request and setup for proxy handler
     * @param r     request
     * @param ent   proxy_alias record
     * @param dconf per-dir config or NULL
     * @return      OK if the alias matched,
     *              DONE if the alias matched and r->uri was normalized so
     *                   no further transformation should happen on it,
     *              DECLINED if proxying is disabled for this alias,
     *              HTTP_CONTINUE if the alias did not match
     */
    PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r,
                                            struct proxy_alias *ent,
                                            proxy_dir_conf *dconf);
    
    /**
     * Create a HTTP request header brigade,  old_cl_val and old_te_val as required.
     * @param p               pool
     * @param header_brigade  header brigade to use/fill
     * @param r               request
     * @param p_conn          proxy connection rec
     * @param worker          selected worker
     * @param conf            per-server proxy config
     * @param uri             uri
     * @param url             url
     * @param server_portstr  port as string
     * @param old_cl_val      stored old content-len val
     * @param old_te_val      stored old TE val
     * @return                OK or HTTP_EXPECTATION_FAILED
     */
    PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
                                               apr_bucket_brigade *header_brigade,
                                               request_rec *r,
                                               proxy_conn_rec *p_conn,
                                               proxy_worker *worker,
                                               proxy_server_conf *conf,
                                               apr_uri_t *uri,
                                               char *url, char *server_portstr,
                                               char **old_cl_val,
                                               char **old_te_val);
    
    /**
     * Prefetch the client request body (in memory), up to a limit.
     * Read what's in the client pipe. If nonblocking is set and read is EAGAIN,
     * pass a FLUSH bucket to the backend and read again in blocking mode.
     * @param r             client request
     * @param backend       backend connection
     * @param input_brigade input brigade to use/fill
     * @param block         blocking or non-blocking mode
     * @param bytes_read    number of bytes read
     * @param max_read      maximum number of bytes to read
     * @return              OK or HTTP_* error code
     * @note max_read is rounded up to APR_BUCKET_BUFF_SIZE
     */
    PROXY_DECLARE(int) ap_proxy_prefetch_input(request_rec *r,
                                               proxy_conn_rec *backend,
                                               apr_bucket_brigade *input_brigade,
                                               apr_read_type_e block,
                                               apr_off_t *bytes_read,
                                               apr_off_t max_read);
    
    /**
     * Spool the client request body to memory, or disk above given limit.
     * @param r             client request
     * @param backend       backend connection
     * @param input_brigade input brigade to use/fill
     * @param bytes_spooled number of bytes spooled
     * @param max_mem_spool maximum number of in-memory bytes
     * @return              OK or HTTP_* error code
     */
    PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r,
                                            proxy_conn_rec *backend,
                                            apr_bucket_brigade *input_brigade,
                                            apr_off_t *bytes_spooled,
                                            apr_off_t max_mem_spool);
    
    /**
     * Read what's in the client pipe. If the read would block (EAGAIN),
     * pass a FLUSH bucket to the backend and read again in blocking mode.
     * @param r             client request
     * @param backend       backend connection
     * @param input_brigade brigade to use/fill
     * @param max_read      maximum number of bytes to read
     * @return              OK or HTTP_* error code
     */
    PROXY_DECLARE(int) ap_proxy_read_input(request_rec *r,
                                           proxy_conn_rec *backend,
                                           apr_bucket_brigade *input_brigade,
                                           apr_off_t max_read);
    
    /**
     * @param bucket_alloc  bucket allocator
     * @param r             request
     * @param p_conn        proxy connection
     * @param origin        connection rec of origin
     * @param  bb           brigade to send to origin
     * @param  flush        flush
     * @return              status (OK)
     */
    PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucket_alloc_t *bucket_alloc,
                                             request_rec *r, proxy_conn_rec *p_conn,
                                             conn_rec *origin, apr_bucket_brigade *bb,
                                             int flush);
    
    struct proxy_tunnel_conn; /* opaque */
    typedef struct {
        request_rec *r;
        const char *scheme;
        apr_pollset_t *pollset;
        apr_array_header_t *pfds;
        apr_interval_time_t timeout;
        struct proxy_tunnel_conn *client,
                                 *origin;
        apr_size_t read_buf_size;
        int replied; /* TODO 2.5+: one bit to merge in below bitmask */
        unsigned int nohalfclose :1;
    } proxy_tunnel_rec;
    
    /**
     * Create a tunnel, to be activated by ap_proxy_tunnel_run().
     * @param tunnel   tunnel created
     * @param r        client request
     * @param c_o      connection to origin
     * @param scheme   caller proxy scheme (connect, ws(s), http(s), ...)
     * @return         APR_SUCCESS or error status
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_tunnel_create(proxy_tunnel_rec **tunnel,
                                                       request_rec *r, conn_rec *c_o,
                                                       const char *scheme);
    
    /**
     * Forward anything from either side of the tunnel to the other,
     * until one end aborts or a polling timeout/error occurs.
     * @param tunnel  tunnel to run
     * @return        OK if completion is full, HTTP_GATEWAY_TIME_OUT on timeout
     *                or another HTTP_ error otherwise.
     */
    PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel);
    
    /**
     * Clear the headers referenced by the Connection header from the given
     * table, and remove the Connection header.
     * @param r request
     * @param headers table of headers to clear
     * @return 1 if "close" was present, 0 otherwise.
     */
    APR_DECLARE_OPTIONAL_FN(int, ap_proxy_clear_connection,
            (request_rec *r, apr_table_t *headers));
    
    /**
     * Do a AJP CPING and wait for CPONG on the socket
     *
     */
    APR_DECLARE_OPTIONAL_FN(apr_status_t, ajp_handle_cping_cpong,
            (apr_socket_t *sock, request_rec *r,
             apr_interval_time_t timeout));
    
    
    /**
     * @param socket        socket to test
     * @return              TRUE if socket is connected/active
     */
    PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket);
    
    #define PROXY_LBMETHOD "proxylbmethod"
    
    /* 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 maximum number of workers in scoreboard.
     * @return  number of workers to allocate in the scoreboard
     */
    int ap_proxy_lb_workers(void);
    
    /**
     * Returns 1 if a response with the given status should be overridden.
     *
     * @param conf   proxy directory configuration
     * @param code   http status code
     * @return       1 if code is considered an error-code, 0 otherwise
     */
    PROXY_DECLARE(int) ap_proxy_should_override(proxy_dir_conf *conf, int code);
    
    /**
     * Return the port number of a known scheme (eg: http -> 80).
     * @param scheme        scheme to test
     * @return              port number or 0 if unknown
     */
    PROXY_DECLARE(apr_port_t) ap_proxy_port_of_scheme(const char *scheme);
    
    /**
     * Return the name of the health check method (eg: "OPTIONS").
     * @param method        method enum
     * @return              name of method
     */
    PROXY_DECLARE (const char *) ap_proxy_show_hcmethod(hcmethod_t method);
    
    /**
     * Strip a unix domain socket (UDS) prefix from the input URL
     * @param p             pool to allocate result from
     * @param url           a URL potentially prefixed with a UDS path
     * @return              URL with the UDS prefix removed
     */
    PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url);
    
    /*
     * Transform buckets from one bucket allocator to another one by creating a
     * transient bucket for each data bucket and let it use the data read from
     * the old bucket. Metabuckets are transformed by just recreating them.
     * Attention: Currently only the following bucket types are handled:
     *
     * All data buckets
     * FLUSH
     * EOS
     *
     * If an other bucket type is found its type is logged as a debug message
     * and APR_EGENERAL is returned.
     *
     * @param r     request_rec of the actual request. Used for logging purposes
     * @param from  the bucket brigade to take the buckets from
     * @param to    the bucket brigade to store the transformed buckets
     * @return      apr_status_t of the operation. Either APR_SUCCESS or
     *              APR_EGENERAL
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifetime_transform(request_rec *r,
                                                          apr_bucket_brigade *from,
                                                          apr_bucket_brigade *to);
    
    /* 
     * The flags for ap_proxy_transfer_between_connections(), where for legacy and
     * compatibility reasons FLUSH_EACH and FLUSH_AFTER are boolean values.
     */
    #define AP_PROXY_TRANSFER_FLUSH_EACH        (0x00)
    #define AP_PROXY_TRANSFER_FLUSH_AFTER       (0x01)
    #define AP_PROXY_TRANSFER_YIELD_PENDING     (0x02)
    #define AP_PROXY_TRANSFER_YIELD_MAX_READS   (0x04)
    
    /*
     * Sends all data that can be read non blocking from the input filter chain of
     * c_i and send it down the output filter chain of c_o. For reading it uses
     * the bucket brigade bb_i which should be created from the bucket allocator
     * associated with c_i. For sending through the output filter chain it uses
     * the bucket brigade bb_o which should be created from the bucket allocator
     * associated with c_o. In order to get the buckets from bb_i to bb_o
     * ap_proxy_buckets_lifetime_transform is used.
     *
     * @param r     request_rec of the actual request. Used for logging purposes
     * @param c_i   inbound connection conn_rec
     * @param c_o   outbound connection conn_rec
     * @param bb_i  bucket brigade for pulling data from the inbound connection
     * @param bb_o  bucket brigade for sending data through the outbound connection
     * @param name  string for logging from where data was pulled
     * @param sent  if not NULL will be set to 1 if data was sent through c_o
     * @param bsize maximum amount of data pulled in one iteration from c_i
     * @param flags AP_PROXY_TRANSFER_* bitmask
     * @return      apr_status_t of the operation. Could be any error returned from
     *              either the input filter chain of c_i or the output filter chain
     *              of c_o, APR_EPIPE if the outgoing connection was aborted, or
     *              APR_INCOMPLETE if AP_PROXY_TRANSFER_YIELD_PENDING was set and
     *              the output stack gets full before the input stack is exhausted.
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_transfer_between_connections(
                                                           request_rec *r,
                                                           conn_rec *c_i,
                                                           conn_rec *c_o,
                                                           apr_bucket_brigade *bb_i,
                                                           apr_bucket_brigade *bb_o,
                                                           const char *name,
                                                           int *sent,
                                                           apr_off_t bsize,
                                                           int flags);
    
    extern module PROXY_DECLARE_DATA proxy_module;
    
    #endif /*MOD_PROXY_H*/
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ftp.c����������������������������������������������������������0000664�0001751�0001751�00000237046�14675527312�020540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 */
    
    #define APR_WANT_BYTEFUNC
    #include "mod_proxy.h"
    #if APR_HAVE_TIME_H
    #include <time.h>
    #endif
    #include "apr_version.h"
    
    #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;
    
    typedef struct {
        int ftp_list_on_wildcard;
        int ftp_list_on_wildcard_set;
        int ftp_escape_wildcards;
        int ftp_escape_wildcards_set;
        const char *ftp_directory_charset;
    } proxy_ftp_dir_conf;
    
    static void *create_proxy_ftp_dir_config(apr_pool_t *p, char *dummy)
    {
        proxy_ftp_dir_conf *new =
            (proxy_ftp_dir_conf *) apr_pcalloc(p, sizeof(proxy_ftp_dir_conf));
    
        /* Put these in the dir config so they work inside <Location> */
        new->ftp_list_on_wildcard = 1;
        new->ftp_escape_wildcards = 1;
    
        return (void *) new;
    }
    
    static void *merge_proxy_ftp_dir_config(apr_pool_t *p, void *basev, void *addv)
    {
        proxy_ftp_dir_conf *new = (proxy_ftp_dir_conf *) apr_pcalloc(p, sizeof(proxy_ftp_dir_conf));
        proxy_ftp_dir_conf *add = (proxy_ftp_dir_conf *) addv;
        proxy_ftp_dir_conf *base = (proxy_ftp_dir_conf *) basev;
    
        /* Put these in the dir config so they work inside <Location> */
        new->ftp_list_on_wildcard = add->ftp_list_on_wildcard_set ?
                                    add->ftp_list_on_wildcard :
                                    base->ftp_list_on_wildcard;
        new->ftp_list_on_wildcard_set = add->ftp_list_on_wildcard_set ?
                                    1 :
                                    base->ftp_list_on_wildcard_set;
        new->ftp_escape_wildcards = add->ftp_escape_wildcards_set ?
                                    add->ftp_escape_wildcards :
                                    base->ftp_escape_wildcards;
        new->ftp_escape_wildcards_set = add->ftp_escape_wildcards_set ?
                                    1 :
                                    base->ftp_escape_wildcards_set;
        new->ftp_directory_charset = add->ftp_directory_charset ?
                                     add->ftp_directory_charset :
                                     base->ftp_directory_charset;
        return new;
    }
    
    static const char *set_ftp_list_on_wildcard(cmd_parms *cmd, void *dconf,
                                                int flag)
    {
        proxy_ftp_dir_conf *conf = dconf;
    
        conf->ftp_list_on_wildcard = flag;
        conf->ftp_list_on_wildcard_set = 1;
        return NULL;
    }
    
    static const char *set_ftp_escape_wildcards(cmd_parms *cmd, void *dconf,
                                                int flag)
    {
        proxy_ftp_dir_conf *conf = dconf;
    
        conf->ftp_escape_wildcards = flag;
        conf->ftp_escape_wildcards_set = 1;
        return NULL;
    }
    
    static const char *set_ftp_directory_charset(cmd_parms *cmd, void *dconf,
                                                 const char *arg)
    {
        proxy_ftp_dir_conf *conf = dconf;
    
        conf->ftp_directory_charset = arg;
        return NULL;
    }
    
    /*
     * 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.
     * Just returns the original string if ProxyFtpEscapeWildcards has been
     * configured "off".
     * Returns: escaped string
     */
    #define FTP_GLOBBING_CHARS "*?[{~"
    static const char *ftp_escape_globbingchars(apr_pool_t *p, const char *path, proxy_ftp_dir_conf *dconf)
    {
        char *ret;
        char *d;
    
        if (!dconf->ftp_escape_wildcards) {
            return path;
        }
    
        ret = apr_palloc(p, 2*strlen(path)+sizeof(""));
        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;
    }
    
    /*
     * 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 ftp_string_read() will not work properly on non ASCII
     * (EBCDIC) machines either.
     */
    static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb,
            char *buff, apr_size_t bufflen, int *eos, apr_size_t *outlen)
    {
        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;
        *outlen = 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 != (rv = 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) {
                        memcpy(pos, response, len);
                        pos += len;
                        *outlen += len;
                    }
                }
                apr_bucket_delete(e);
            }
            *pos = '\0';
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * 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;
        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
        /* */
        if (ap_cstr_casecmpn(url, "ftp:", 4) == 0) {
            url += 4;
        }
        else {
            return DECLINED;
        }
        def_port = apr_uri_port_of_scheme("ftp");
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "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_ex(p, url, strlen(url), enc_path, flags,
                                    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;
        apr_size_t nread;
        
        int eos;
    
        if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) {
            return -1;
        }
    /*
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(03233)
                     "<%s", response);
    */
        if (nread < 4) { 
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(10229) "Malformed FTP response '%s'", response);
            *mb = '\0';
            return -1;
        }
    
        if (!apr_isdigit(response[0]) || !apr_isdigit(response[1]) ||
            !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-'))
            status = 0;
        else
            status = 100 * response[0] + 10 * response[1] + response[2] - 111 * '0';
    
        mb = apr_cpystrn(mb, response + 4, me - mb);
    
        if (response[3] == '-') { /* multi-line reply "123-foo\nbar\n123 baz" */
            memcpy(buff, response, 3);
            buff[3] = ' ';
            do {
                if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) {
                    return -1;
                }
                mb = apr_cpystrn(mb, response + (' ' == response[0] ? 1 : 4), me - mb);
            } while (memcmp(response, buff, 4) != 0);
        }
    
        return status;
    }
    
    /* this is a filter that turns a raw ASCII directory listing into pretty HTML */
    
    /* ideally, mod_proxy should simply send the raw directory list up the filter
     * stack to mod_autoindex, which in theory should turn the raw ascii into
     * pretty html along with all the bells and whistles it provides...
     *
     * all in good time...! :)
     */
    
    typedef struct {
        apr_bucket_brigade *in;
        char buffer[MAX_STRING_LEN];
        enum {
            HEADER, BODY, FOOTER
        }    state;
    }      proxy_dir_ctx_t;
    
    /* fallback regex for ls -s1;  ($0..$2) == 3 */
    #define LS_REG_PATTERN "^ *([0-9]+) +([^ ]+)$"
    #define LS_REG_MATCH   3
    static ap_regex_t *ls_regex;
    
    static apr_status_t proxy_send_dir_filter(ap_filter_t *f,
                                              apr_bucket_brigade *in)
    {
        request_rec *r = f->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;
    
        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;
            const char *escpath;
    
            /*
             * In the reverse proxy case we need to construct our site string
             * via ap_construct_url. For non anonymous sites apr_uri_unparse would
             * only supply us with 'username@' which leads to the construction of
             * an invalid base href later on. Losing the username part of the URL
             * is no problem in the reverse proxy case as the browser sents the
             * credentials anyway once entered.
             */
            if (r->proxyreq == PROXYREQ_REVERSE) {
                site = ap_construct_url(p, "", r);
            }
            else {
                /* 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 (ap_cstr_casecmpn(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') ? "<a href=\"/%2f/\">%2f</a>/" : "";
    
            /* print "ftp://host/" */
            escpath = ap_escape_html(p, path);
            str = apr_psprintf(p, DOCTYPE_HTML_3_2
                    "<html>\n <head>\n  <title>%s%s%s</title>\n"
                    "<base href=\"%s%s%s\">\n"
                    " </head>\n"
                    " <body>\n  <h2>Directory of "
                    "<a href=\"/\">%s</a>/%s",
                    ap_escape_html(p, site), basedir, escpath,
                    ap_escape_uri(p, site), basedir, escpath,
                    ap_escape_uri(p, 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, "<a href=\"%s%s/\">%s</a>/", 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) {
                wildcard = ap_escape_html(p, wildcard);
                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, "</h2>\n\n  <hr />\n\n<pre>");
            }
            else {
                str = apr_psprintf(p, "</h2>\n\n(%s)\n\n  <hr />\n\n<pre>",
                                   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</pre>\n\n<hr />\n\n<pre>\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_regmatch_t re_result[LS_REG_MATCH];
    
            /* 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_delete(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 <a href=\"%s\">%s %s</a>\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, ' ');
                if (filename == NULL) {
                    /* Line is broken.  Ignore it. */
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01034)
                                  "proxy_ftp: could not parse line %s",
                                  ctx->buffer);
                    /* erase buffer for next time around */
                    ctx->buffer[0] = 0;
                    continue;  /* while state is BODY */
                }
                *(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 <a href=\"%s/\">%s</a>\n",
                                       ap_escape_html(p, ctx->buffer),
                                       ap_escape_uri(p, filename),
                                       ap_escape_html(p, filename));
                }
                else {
                    str = apr_psprintf(p, "%s <a href=\"%s\">%s</a>\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(ls_regex, ctx->buffer, LS_REG_MATCH, re_result, 0)) {
                /*
                 * We don't need to check for rm_eo == rm_so == -1 here since ls_regex
                 * is such that $2 cannot be unset if we have a match.
                 */
                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)),
                                  "<a href=\"", ap_escape_uri(p, filename), "\">",
                                  ap_escape_html(p, filename), "</a>\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, "</pre>\n\n  <hr />\n\n  %s\n\n </body>\n</html>\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;
    }
    
    /* Parse EPSV reply and return port, or zero on error. */
    static apr_port_t parse_epsv_reply(const char *reply)
    {
        const char *p;
        char *ep;
        long port;
    
        /* Reply syntax per RFC 2428: "229 blah blah (|||port|)" where '|'
         * can be any character in ASCII from 33-126, obscurely.  Verify
         * the syntax. */
        p = ap_strchr_c(reply, '(');
        if (p == NULL || !p[1] || p[1] != p[2] || p[1] != p[3]
            || p[4] == p[1]) {
            return 0;
        }
    
        errno = 0;
        port = strtol(p + 4, &ep, 10);
        if (errno || port < 1 || port > 65535 || ep[0] != p[1] || ep[1] != ')') {
            return 0;
        }
    
        return (apr_port_t)port;
    }
    
    /*
     * 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);
    
            if (APLOGrtrace2(r)) {
                /* 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_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, ">%s", message);
            }
        }
    
        rc = ftp_getrc_msg(ftp_ctrl, bb, message, sizeof(message));
        if (rc == -1 || rc == 421)
            strcpy(message,"<unable to read result>");
        if ((crlf = strchr(message, '\r')) != NULL ||
            (crlf = strchr(message, '\n')) != NULL)
            *crlf = '\0';
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "<%3.3u %s", rc, message);
    
        if (pmessage != NULL)
            *pmessage = apr_pstrdup(r->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 "<directory-name>" <commentary> */
        /* 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 request (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, APLOGNO(01035)
                          "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 = 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 <spiffnet@zoom.com>
     * PASV added by Chuck
     * Filters by [Graham Leggett <minfrin@sharp.fm>]
     */
    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;
        conn_rec *origin, *data = NULL;
        apr_status_t err = APR_SUCCESS;
        apr_bucket_brigade *bb;
        char *buf, *connectname;
        apr_port_t connectport;
        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
        proxy_ftp_dir_conf *fdconf = ap_get_module_config(r->per_dir_config,
                                                          &proxy_ftp_module);
    
        /* stuff for PASV mode */
        int connect = 0, use_port = 0;
        char dates[APR_RFC822_DATE_LEN];
        apr_status_t rv;
        int status;
    
        /* is this for us? */
        if (proxyhost) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "declining URL %s - proxyhost %s specified:", url,
                          proxyhost);
            return DECLINED;        /* proxy connections are via HTTP */
        }
        if (ap_cstr_casecmpn(url, "ftp:", 4)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "declining URL %s - not ftp:", url);
            return DECLINED;        /* only interested in FTP */
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "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)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10189) 
                              "URI cannot be parsed: %s", url);
                return ap_proxyerror(r, HTTP_BAD_REQUEST, "URI cannot be parsed");
            }
            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
            && ap_cstr_casecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0
            && (password = ap_pbase64decode(r->pool, password))[0] != ':') {
            /* Check the decoded string for special characters. */
            if (!ftp_check_string(password)) {
                return ap_proxyerror(r, HTTP_BAD_REQUEST,
                                     "user credentials contained invalid character");
            }
            /*
             * 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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01036)
                      "connecting %s to %s:%d", url, connectname, connectport);
    
        /* create space for state information */
        backend = 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 = 1;
                    ap_proxy_release_connection("FTP", backend, r->server);
                }
                return status;
            }
            ap_set_module_config(c->conn_config, &proxy_ftp_module, backend);
        }
    
        /*
         * get all the possible IP addresses for the destname and loop through
         * them until we get a successful connection
         */
        err = ap_proxy_determine_address("FTP", backend, connectname, connectport,
                                         0, r, r->server);
        if (APR_SUCCESS != err) {
            return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
                                  "Error resolving backend address");
        }
    
        /* check if ProxyBlock directive on this host */
        if (OK != ap_proxy_checkproxyblock2(r, conf, connectname, backend->addr)) {
            return ftp_proxyerror(r, backend, HTTP_FORBIDDEN,
                                  "Connect to remote machine blocked");
        }
    
    
        /*
         * 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)) {
            proxy_ftp_cleanup(r, backend);
            return HTTP_SERVICE_UNAVAILABLE;
        }
    
        status = ap_proxy_connection_create_ex("FTP", backend, r);
        if (status != OK) {
            proxy_ftp_cleanup(r, backend);
            return status;
        }
    
        /* Use old naming */
        origin = backend->connection;
        sock = backend->sock;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "control connection complete");
    
    
        /*
         * III: Send Control Request -------------------------
         *
         * Log into the ftp server, send the username & password, change to the
         * correct directory...
         */
    
        bb = apr_brigade_create(p, c->bucket_alloc);
    
        /* 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_addn(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 (ap_cstr_casecmpn(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';
    
            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, fdconf), 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_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) {
                /* Parse the port out of the EPSV reply. */
                data_port = parse_epsv_reply(ftpmessage);
    
                if (data_port) {
                    apr_sockaddr_t *remote_addr, epsv_addr;
    
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                  "EPSV contacting remote host on port %d", data_port);
    
                    /* Retrieve the client's address. */
                    rv = apr_socket_addr_get(&remote_addr, APR_REMOTE, sock);
                    if (rv == APR_SUCCESS) {
                        /* Take a shallow copy of the server address to
                         * modify; the _addr_get function gives back a
                         * pointer to the socket's internal structure.
                         * This is awkward given current APR network
                         * interfaces. */
                        epsv_addr = *remote_addr;
                        epsv_addr.port = data_port;
    #if APR_HAVE_IPV6
                        if (epsv_addr.family == APR_INET6) {
                            epsv_addr.sa.sin6.sin6_port = htons(data_port);
                        }
                        else
    #endif
                        {
                            epsv_addr.sa.sin.sin_port = htons(data_port);
                        }
                        rv = apr_socket_create(&data_sock, epsv_addr.family, SOCK_STREAM, 0, r->pool);
                    }
    
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01040) 
                                      "could not establish socket for client data connection");
                        proxy_ftp_cleanup(r, backend);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
    
                    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, APLOGNO(01041)
                                      "apr_socket_opt_set(SO_RCVBUF): Failed to "
                                      "set ProxyReceiveBufferSize, using default");
                    }
    
                    rv = apr_socket_opt_set(data_sock, APR_TCP_NODELAY, 1);
                    if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01042)
                                      "apr_socket_opt_set(APR_TCP_NODELAY): "
                                      "Failed to set");
                    }
    
                    rv = apr_socket_connect(data_sock, &epsv_addr);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01043)
                                      "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 {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                      "connected data socket to %pI", &epsv_addr);
                        connect = 1;
                    }
                }
            }
        }
    
        /* 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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01044)
                                  "PASV contacting host %d.%d.%d.%d:%d",
                                  h3, h2, h1, h0, pasvport);
    
                    if ((rv = apr_socket_create(&data_sock, backend->addr->family,
                                                SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01045)
                                      "error creating PASV socket");
                        proxy_ftp_cleanup(r, backend);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
    
                    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, APLOGNO(01046)
                                      "apr_socket_opt_set(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
                    }
    
                    rv = apr_socket_opt_set(data_sock, APR_TCP_NODELAY, 1);
                    if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01047)
                                      "apr_socket_opt_set(APR_TCP_NODELAY): "
                                      "Failed to set");
                    }
    
                    /* make the connection */
                    err = apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d",
                                                                         h3, h2, h1, h0),
                                                backend->addr->family, pasvport, 0, p);
                    if (APR_SUCCESS != err) {
                        return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
                                              apr_pstrcat(p, "DNS lookup failure for: ",
                                                          connectname, NULL));
                    }
                    rv = apr_socket_connect(data_sock, pasv_addr);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01048)
                                      "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;
                    }
                }
            }
        }
    /*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, backend->addr->family,
                                        SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01049)
                              "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, APLOGNO(01050)
                              "error setting reuseaddr option");
                proxy_ftp_cleanup(r, backend);
                return HTTP_INTERNAL_SERVER_ERROR;
    #endif                          /* _OSD_POSIX */
            }
    
            err = apr_sockaddr_info_get(&local_addr, local_ip, APR_UNSPEC, local_port, 0, r->pool);
            if (APR_SUCCESS != err) {
                return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
                                      apr_pstrcat(p, "DNS lookup failure for: ",
                                                  connectname, NULL));
            }
    
            if ((rv = apr_socket_bind(local_sock, local_addr)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01051)
                              "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, APLOGNO(01052)
                              "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, ftpmessage);
                }
    
                /* 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,
         * unless ProxyFtpListOnWildcard is off.
         */
        if (len == 0 || (ftp_check_globbingchars(path) && fdconf->ftp_list_on_wildcard)) {
            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, fdconf), 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_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                              "SIZE shows this is a directory");
                dirlisting = 1;
                rc = proxy_ftp_command(apr_pstrcat(p, "CWD ",
                               ftp_escape_globbingchars(p, path, fdconf), 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 = "LIST -lag" CRLF;
            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, fdconf), 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, fdconf), 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_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                          "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, fdconf), 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_description());
    
        /* set content-type */
        if (dirlisting) {
            ap_set_content_type_ex(r, apr_pstrcat(p, "text/html;charset=",
                                               fdconf->ftp_directory_charset ?
                                               fdconf->ftp_directory_charset :
                                               "ISO-8859-1",  NULL), 1);
        }
        else {
            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_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                              "Content-Length set to %s", size);
            }
        }
        if (r->content_type) {
            apr_table_setn(r->headers_out, "Content-Type", r->content_type);
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "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_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "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_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "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 (APR_STATUS_IS_EINTR(rv)) {
                    continue;
                }
                else if (rv == APR_SUCCESS) {
                    break;
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01053)
                                  "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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01054)
                          "an error occurred creating the transfer connection");
            proxy_ftp_cleanup(r, backend);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /*
         * We do not do SSL over the data connection, even if the virtual host we
         * are in might have SSL enabled
         */
        ap_proxy_ssl_engine(data, r->per_dir_config, 0);
        /* set up the connection filters */
        rc = ap_run_pre_connection(data, data_sock);
        if (rc != OK && rc != DONE) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01055)
                          "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_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "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, APLOGNO(01056)
                                 "proxy: readbytes: %#x", readbytes);
                }
    #endif
                /* sanity check */
                if (APR_BRIGADE_EMPTY(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);
                    if (data_sock) {
                        apr_socket_close(data_sock);
                    }
                    data_sock = NULL;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01057)
                                  "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_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "end body send");
    
        }
        if (data_sock) {
            ap_flush_conn(data);
            apr_socket_close(data_sock);
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01058) "data connection closed");
        }
    
        /* Retrieve the final response for the RETR or LIST commands */
        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 */
        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);
        /* Compile the output format of "ls -s1" as a fallback for non-unix ftp listings */
        ls_regex = ap_pregcomp(p, LS_REG_PATTERN, AP_REG_EXTENDED);
        ap_assert(ls_regex != NULL);
    }
    
    static const command_rec proxy_ftp_cmds[] =
    {
        AP_INIT_FLAG("ProxyFtpListOnWildcard", set_ftp_list_on_wildcard, NULL,
         RSRC_CONF|ACCESS_CONF, "Whether wildcard characters in a path cause mod_proxy_ftp to list the files instead of trying to get them. Defaults to on."),
        AP_INIT_FLAG("ProxyFtpEscapeWildcards", set_ftp_escape_wildcards, NULL,
         RSRC_CONF|ACCESS_CONF, "Whether the proxy should escape wildcards in paths before sending them to the FTP server.  Defaults to on, but most FTP servers will need it turned off if you need to manage paths that contain wildcard characters."),
        AP_INIT_TAKE1("ProxyFtpDirCharset", set_ftp_directory_charset, NULL,
         RSRC_CONF|ACCESS_CONF, "Define the character set for proxied FTP listings"),
        {NULL}
    };
    
    
    AP_DECLARE_MODULE(proxy_ftp) = {
        STANDARD20_MODULE_STUFF,
        create_proxy_ftp_dir_config,/* create per-directory config structure */
        merge_proxy_ftp_dir_config, /* merge per-directory config structures */
        NULL,                       /* create per-server config structure */
        NULL,                       /* merge per-server config structures */
        proxy_ftp_cmds,             /* command apr_table_t */
        ap_proxy_ftp_register_hook  /* register hooks */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_scgi.c���������������������������������������������������������0000664�0001751�0001751�00000052053�14603243511�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_proxy_scgi.c
     * Proxy backend module for the SCGI protocol
     * (http://python.ca/scgi/protocol.txt)
     *
     * Andr� Malo (nd/perlig.de), August 2007
     */
    
    #define APR_WANT_MEMFUNC
    #define APR_WANT_STRFUNC
    #include "apr_strings.h"
    #include "ap_hooks.h"
    #include "apr_optional_hooks.h"
    #include "apr_buckets.h"
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "util_script.h"
    
    #include "mod_proxy.h"
    #include "scgi.h"
    
    
    #define SCHEME "scgi"
    #define PROXY_FUNCTION "SCGI"
    #define SCGI_MAGIC "SCGI"
    #define SCGI_PROTOCOL_VERSION "1"
    
    /* just protect from typos */
    #define CONTENT_LENGTH "CONTENT_LENGTH"
    #define GATEWAY_INTERFACE "GATEWAY_INTERFACE"
    
    module AP_MODULE_DECLARE_DATA proxy_scgi_module;
    
    
    typedef enum {
        scgi_internal_redirect,
        scgi_sendfile
    } scgi_request_type;
    
    typedef struct {
        const char *location;    /* target URL */
        scgi_request_type type;  /* type of request */
    } scgi_request_config;
    
    const char *scgi_sendfile_off = "off";
    const char *scgi_sendfile_on = "X-Sendfile";
    const char *scgi_internal_redirect_off = "off";
    const char *scgi_internal_redirect_on = "Location";
    
    typedef struct {
        const char *sendfile;
        const char *internal_redirect;
    } scgi_config;
    
    
    /*
     * We create our own bucket type, which is actually derived (c&p) from the
     * socket bucket.
     * Maybe some time this should be made more abstract (like passing an
     * interception function to read or something) and go into the ap_ or
     * even apr_ namespace.
     */
    
    typedef struct {
        apr_socket_t *sock;
        apr_off_t *counter;
    } socket_ex_data;
    
    static apr_bucket *bucket_socket_ex_create(socket_ex_data *data,
                                               apr_bucket_alloc_t *list);
    
    
    static apr_status_t bucket_socket_ex_read(apr_bucket *a, const char **str,
                                              apr_size_t *len,
                                              apr_read_type_e block)
    {
        socket_ex_data *data = a->data;
        apr_socket_t *p = data->sock;
        char *buf;
        apr_status_t rv;
        apr_interval_time_t timeout;
    
        if (block == APR_NONBLOCK_READ) {
            apr_socket_timeout_get(p, &timeout);
            apr_socket_timeout_set(p, 0);
        }
    
        *str = NULL;
        *len = APR_BUCKET_BUFF_SIZE;
        buf = apr_bucket_alloc(*len, a->list);
    
        rv = apr_socket_recv(p, buf, len);
    
        if (block == APR_NONBLOCK_READ) {
            apr_socket_timeout_set(p, timeout);
        }
    
        if (rv != APR_SUCCESS && rv != APR_EOF) {
            apr_bucket_free(buf);
            return rv;
        }
    
        if (*len > 0) {
            apr_bucket_heap *h;
    
            /* count for stats */
            *data->counter += *len;
    
            /* 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, bucket_socket_ex_create(data, a->list));
        }
        else {
            apr_bucket_free(buf);
            a = apr_bucket_immortal_make(a, "", 0);
            *str = a->data;
        }
        return APR_SUCCESS;
    }
    
    static const apr_bucket_type_t bucket_type_socket_ex = {
        "SOCKET_EX", 5, APR_BUCKET_DATA,
        apr_bucket_destroy_noop,
        bucket_socket_ex_read,
        apr_bucket_setaside_notimpl,
        apr_bucket_split_notimpl,
        apr_bucket_copy_notimpl
    };
    
    static apr_bucket *bucket_socket_ex_make(apr_bucket *b, socket_ex_data *data)
    {
        b->type        = &bucket_type_socket_ex;
        b->length      = (apr_size_t)(-1);
        b->start       = -1;
        b->data        = data;
        return b;
    }
    
    static apr_bucket *bucket_socket_ex_create(socket_ex_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;
        return bucket_socket_ex_make(b, data);
    }
    
    
    /*
     * Canonicalize scgi-like URLs.
     */
    static int scgi_canon(request_rec *r, char *url)
    {
        char *host, sport[sizeof(":65535")];
        const char *err, *path;
        apr_port_t port, def_port;
        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
        if (ap_cstr_casecmpn(url, SCHEME "://", sizeof(SCHEME) + 2)) {
            return DECLINED;
        }
        url += sizeof(SCHEME); /* Keep slashes */
    
        port = def_port = SCGI_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, APLOGNO(00857)
                          "error parsing URL %s: %s", url, err);
            return HTTP_BAD_REQUEST;
        }
    
        if (port != def_port) {
            apr_snprintf(sport, sizeof(sport), ":%u", port);
        }
        else {
            sport[0] = '\0';
        }
    
        if (ap_strchr(host, ':')) { /* if literal IPv6 address */
            host = apr_pstrcat(r->pool, "[", host, "]", NULL);
        }
    
        path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
                                    r->proxyreq);
        if (!path) {
            return HTTP_BAD_REQUEST;
        }
    
        r->filename = apr_pstrcat(r->pool, "proxy:" SCHEME "://", host, sport, "/",
                                  path, NULL);
    
        if (apr_table_get(r->subprocess_env, "proxy-scgi-pathinfo")) {
            r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
        }
    
        return OK;
    }
    
    
    /*
     * Send a block of data, ensure, everything is sent
     */
    static int sendall(proxy_conn_rec *conn, const char *buf, apr_size_t length,
                       request_rec *r)
    {
        apr_status_t rv;
        apr_size_t written;
    
        while (length > 0) {
            written = length;
            if ((rv = apr_socket_send(conn->sock, buf, &written)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00858)
                              "sending data to %s:%u failed",
                              conn->hostname, conn->port);
                return HTTP_SERVICE_UNAVAILABLE;
            }
    
            /* count for stats */
            conn->worker->s->transferred += written;
            buf += written;
            length -= written;
        }
    
        return OK;
    }
    
    
    /*
     * Send SCGI header block
     */
    static int send_headers(request_rec *r, proxy_conn_rec *conn)
    {
        char *buf, *cp, *bodylen;
        const char *ns_len;
        const apr_array_header_t *env_table;
        const apr_table_entry_t *env;
        int j;
        apr_size_t len, bodylen_size;
        apr_size_t headerlen =   sizeof(CONTENT_LENGTH)
                               + sizeof(SCGI_MAGIC)
                               + sizeof(SCGI_PROTOCOL_VERSION);
    
        ap_add_common_vars(r);
        ap_add_cgi_vars(r);
    
        /*
         * The header blob basically takes the environment and concatenates
         * keys and values using 0 bytes. There are special treatments here:
         *   - GATEWAY_INTERFACE and SCGI_MAGIC are dropped
         *   - CONTENT_LENGTH is always set and must be sent as the very first
         *     variable
         *
         * Additionally it's wrapped into a so-called netstring (see SCGI spec)
         */
        env_table = apr_table_elts(r->subprocess_env);
        env = (apr_table_entry_t *)env_table->elts;
        for (j = 0; j < env_table->nelts; ++j) {
            if (   (!strcmp(env[j].key, GATEWAY_INTERFACE))
                || (!strcmp(env[j].key, CONTENT_LENGTH))
                || (!strcmp(env[j].key, SCGI_MAGIC))) {
                continue;
            }
            headerlen += strlen(env[j].key) + strlen(env[j].val) + 2;
        }
        bodylen = apr_psprintf(r->pool, "%" APR_OFF_T_FMT, r->remaining);
        bodylen_size = strlen(bodylen) + 1;
        headerlen += bodylen_size;
    
        ns_len = apr_psprintf(r->pool, "%" APR_SIZE_T_FMT ":", headerlen);
        len = strlen(ns_len);
        headerlen += len + 1; /* 1 == , */
        cp = buf = apr_palloc(r->pool, headerlen);
        memcpy(cp, ns_len, len);
        cp += len;
    
        memcpy(cp, CONTENT_LENGTH, sizeof(CONTENT_LENGTH));
        cp += sizeof(CONTENT_LENGTH);
        memcpy(cp, bodylen, bodylen_size);
        cp += bodylen_size;
        memcpy(cp, SCGI_MAGIC, sizeof(SCGI_MAGIC));
        cp += sizeof(SCGI_MAGIC);
        memcpy(cp, SCGI_PROTOCOL_VERSION, sizeof(SCGI_PROTOCOL_VERSION));
        cp += sizeof(SCGI_PROTOCOL_VERSION);
    
        for (j = 0; j < env_table->nelts; ++j) {
            if (   (!strcmp(env[j].key, GATEWAY_INTERFACE))
                || (!strcmp(env[j].key, CONTENT_LENGTH))
                || (!strcmp(env[j].key, SCGI_MAGIC))) {
                continue;
            }
            len = strlen(env[j].key) + 1;
            memcpy(cp, env[j].key, len);
            cp += len;
            len = strlen(env[j].val) + 1;
            memcpy(cp, env[j].val, len);
            cp += len;
        }
        *cp++ = ',';
    
        return sendall(conn, buf, headerlen, r);
    }
    
    
    /*
     * Send request body (if any)
     */
    static int send_request_body(request_rec *r, proxy_conn_rec *conn)
    {
        if (ap_should_client_block(r)) {
            char *buf = apr_palloc(r->pool, AP_IOBUFSIZE);
            int status;
            long readlen;
    
            readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
            while (readlen > 0) {
                status = sendall(conn, buf, (apr_size_t)readlen, r);
                if (status != OK) {
                    return HTTP_SERVICE_UNAVAILABLE;
                }
                readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
            }
            if (readlen == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00859)
                              "receiving request body failed");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        return OK;
    }
    
    
    /*
     * Fetch response from backend and pass back to the front
     */
    static int pass_response(request_rec *r, proxy_conn_rec *conn)
    {
        apr_bucket_brigade *bb;
        apr_bucket *b;
        const char *location;
        scgi_config *conf;
        socket_ex_data *sock_data;
        int status;
    
        sock_data = apr_palloc(r->pool, sizeof(*sock_data));
        sock_data->sock = conn->sock;
        sock_data->counter = &conn->worker->s->read;
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        b = bucket_socket_ex_create(sock_data, r->connection->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        b = apr_bucket_eos_create(r->connection->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
    
        status = ap_scan_script_header_err_brigade_ex(r, bb, NULL,
                                                      APLOG_MODULE_INDEX);
        if (status != OK) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00860)
                          "error reading response headers from %s:%u",
                          conn->hostname, conn->port);
            r->status_line = NULL;
            apr_brigade_destroy(bb);
            return status;
        }
    
        /* SCGI has its own body framing mechanism which we don't
         * match against any provided Content-Length, so let the
         * core determine C-L vs T-E based on what's actually sent.
         */
        if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
            apr_table_unset(r->headers_out, "Content-Length");
        apr_table_unset(r->headers_out, "Transfer-Encoding");
    
        conf = ap_get_module_config(r->per_dir_config, &proxy_scgi_module);
        if (conf->sendfile && conf->sendfile != scgi_sendfile_off) {
            short err = 1;
    
            location = apr_table_get(r->err_headers_out, conf->sendfile);
            if (!location) {
                err = 0;
                location = apr_table_get(r->headers_out, conf->sendfile);
            }
            if (location) {
                scgi_request_config *req_conf = apr_palloc(r->pool,
                                                           sizeof(*req_conf));
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00861)
                              "Found %s: %s - preparing subrequest.",
                              conf->sendfile, location);
    
                if (err) {
                    apr_table_unset(r->err_headers_out, conf->sendfile);
                }
                else {
                    apr_table_unset(r->headers_out, conf->sendfile);
                }
                req_conf->location = location;
                req_conf->type = scgi_sendfile;
                ap_set_module_config(r->request_config, &proxy_scgi_module,
                                     req_conf);
                apr_brigade_destroy(bb);
                return OK;
            }
        }
    
        if (r->status == HTTP_OK 
            && (!conf->internal_redirect /* default === On */
                || conf->internal_redirect != scgi_internal_redirect_off)) {
            short err = 1;
            const char *location_header = conf->internal_redirect ? 
                conf->internal_redirect : scgi_internal_redirect_on;
    
            location = apr_table_get(r->err_headers_out, location_header);
            if (!location) {
                err = 0;
                location = apr_table_get(r->headers_out, location_header);
            }
            if (location && *location == '/') {
                scgi_request_config *req_conf = apr_palloc(r->pool,
                                                           sizeof(*req_conf));
                if (ap_cstr_casecmp(location_header, "Location")) {
                    if (err) {
                        apr_table_unset(r->err_headers_out, location_header);
                    }
                    else {
                        apr_table_unset(r->headers_out, location_header);
                    }
                }
                req_conf->location = location;
                req_conf->type = scgi_internal_redirect;
                ap_set_module_config(r->request_config, &proxy_scgi_module,
                                     req_conf);
                apr_brigade_destroy(bb);
                return OK;
            }
        }
    
        if (ap_pass_brigade(r->output_filters, bb)) {
            return AP_FILTER_ERROR;
        }
    
        return OK;
    }
    
    /*
     * Internal redirect / subrequest handler, working on request_status hook
     */
    static int scgi_request_status(int *status, request_rec *r)
    {
        scgi_request_config *req_conf;
    
        if (   (*status == OK)
            && (req_conf = ap_get_module_config(r->request_config,
                                                &proxy_scgi_module))) {
            switch (req_conf->type) {
            case scgi_internal_redirect:
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00862)
                              "Internal redirect to %s", req_conf->location);
    
                r->status_line = NULL;
                if (r->method_number != M_GET) {
                    /* keep HEAD, which is passed around as M_GET, too */
                    r->method = "GET";
                    r->method_number = M_GET;
                }
                apr_table_unset(r->headers_in, "Content-Length");
                ap_internal_redirect_handler(req_conf->location, r);
                return OK;
                /* break; */
    
            case scgi_sendfile:
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00863)
                              "File subrequest to %s", req_conf->location);
                do {
                    request_rec *rr;
    
                    rr = ap_sub_req_lookup_file(req_conf->location, r,
                                                r->output_filters);
                    if (rr->status == HTTP_OK && rr->finfo.filetype != APR_NOFILE) {
                        /*
                         * We don't touch Content-Length here. It might be
                         * borked (there's plenty of room for a race condition).
                         * Either the backend sets it or it's gonna be chunked.
                         */
                        ap_run_sub_req(rr);
                    }
                    else {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00864)
                                      "Subrequest to file '%s' not possible. "
                                      "(rr->status=%d, rr->finfo.filetype=%d)",
                                      req_conf->location, rr->status,
                                      rr->finfo.filetype);
                        *status = HTTP_INTERNAL_SERVER_ERROR;
                        return *status;
                    }
                } while (0);
    
                return OK;
                /* break; */
            }
        }
    
        return DECLINED;
    }
    
    
    /*
     * This handles scgi:(dest) URLs
     */
    static int scgi_handler(request_rec *r, proxy_worker *worker,
                            proxy_server_conf *conf, char *url,
                            const char *proxyname, apr_port_t proxyport)
    {
        int status;
        proxy_conn_rec *backend = NULL;
        apr_pool_t *p = r->pool;
        apr_uri_t *uri;
        char dummy;
    
        if (ap_cstr_casecmpn(url, SCHEME "://", sizeof(SCHEME) + 2)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00865)
                          "declining URL %s", url);
            return DECLINED;
        }
    
        /* Create space for state information */
        status = ap_proxy_acquire_connection(PROXY_FUNCTION, &backend, worker,
                                             r->server);
        if (status != OK) {
            goto cleanup;
        }
        backend->is_ssl = 0;
    
        /* Step One: Determine Who To Connect To */
        uri = apr_palloc(p, sizeof(*uri));
        status = ap_proxy_determine_connection(p, r, conf, worker, backend,
                                               uri, &url, proxyname, proxyport,
                                               &dummy, 1);
        if (status != OK) {
            goto cleanup;
        }
    
        /* Step Two: Make the Connection */
        if (ap_proxy_connect_backend(PROXY_FUNCTION, backend, worker, r->server)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00866)
                          "failed to make connection to backend: %s:%u",
                          backend->hostname, backend->port);
            status = HTTP_SERVICE_UNAVAILABLE;
            goto cleanup;
        }
    
        /* Step Three: Process the Request */
        if (   ((status = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
            || ((status = send_headers(r, backend)) != OK)
            || ((status = send_request_body(r, backend)) != OK)
            || ((status = pass_response(r, backend)) != OK)) {
            goto cleanup;
        }
    
    cleanup:
        if (backend) {
            backend->close = 1; /* always close the socket */
            ap_proxy_release_connection(PROXY_FUNCTION, backend, r->server);
        }
        return status;
    }
    
    
    static void *create_scgi_config(apr_pool_t *p, char *dummy)
    {
        scgi_config *conf=apr_palloc(p, sizeof(*conf));
    
        conf->sendfile = NULL; /* === default (off) */
        conf->internal_redirect = NULL; /* === default (on) */
    
        return conf;
    }
    
    
    static void *merge_scgi_config(apr_pool_t *p, void *base_, void *add_)
    {
        scgi_config *base=base_, *add=add_, *conf=apr_palloc(p, sizeof(*conf));
    
        conf->sendfile = add->sendfile ? add->sendfile: base->sendfile;
        conf->internal_redirect = add->internal_redirect
                                  ? add->internal_redirect
                                  : base->internal_redirect;
        return conf;
    }
    
    
    static const char *scgi_set_send_file(cmd_parms *cmd, void *mconfig,
                                          const char *arg)
    {
        scgi_config *conf=mconfig;
    
        if (!strcasecmp(arg, "Off")) {
            conf->sendfile = scgi_sendfile_off;
        }
        else if (!strcasecmp(arg, "On")) {
            conf->sendfile = scgi_sendfile_on;
        }
        else {
            conf->sendfile = arg;
        }
        return NULL;
    }
    
    
    static const char *scgi_set_internal_redirect(cmd_parms *cmd, void *mconfig,
                                                  const char *arg)
    {
        scgi_config *conf = mconfig;
    
        if (!strcasecmp(arg, "Off")) {
            conf->internal_redirect = scgi_internal_redirect_off;
        }
        else if (!strcasecmp(arg, "On")) {
            conf->internal_redirect = scgi_internal_redirect_on;
        }
        else {
            conf->internal_redirect = arg;
        }
        return NULL;
    }
    
    
    static const command_rec scgi_cmds[] =
    {
        AP_INIT_TAKE1("ProxySCGISendfile", scgi_set_send_file, NULL,
                      RSRC_CONF|ACCESS_CONF,
                      "The name of the X-Sendfile pseudo response header or "
                      "On or Off"),
        AP_INIT_TAKE1("ProxySCGIInternalRedirect", scgi_set_internal_redirect, NULL,
                      RSRC_CONF|ACCESS_CONF,
                      "The name of the pseudo response header or On or Off"),
        {NULL}
    };
    
    
    static void register_hooks(apr_pool_t *p)
    {
        proxy_hook_scheme_handler(scgi_handler, NULL, NULL, APR_HOOK_FIRST);
        proxy_hook_canon_handler(scgi_canon, NULL, NULL, APR_HOOK_FIRST);
        APR_OPTIONAL_HOOK(proxy, request_status, scgi_request_status, NULL, NULL,
                          APR_HOOK_MIDDLE);
    }
    
    
    AP_DECLARE_MODULE(proxy_scgi) = {
        STANDARD20_MODULE_STUFF,
        create_scgi_config,  /* create per-directory config structure */
        merge_scgi_config,   /* merge per-directory config structures */
        NULL,                /* create per-server config structure */
        NULL,                /* merge per-server config structures */
        scgi_cmds,           /* command table */
        register_hooks       /* register hooks */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_scgi.mak�������������������������������������������������������0000664�0001751�0001751�00000025645�12701473373�021215� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_scgi.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_scgi - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_scgi - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_scgi - Win32 Release" && "$(CFG)" != "mod_proxy_scgi - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_scgi.mak" CFG="mod_proxy_scgi - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_scgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_scgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_scgi - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_scgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_scgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_scgi.obj"
    	-@erase "$(INTDIR)\mod_proxy_scgi.res"
    	-@erase "$(INTDIR)\mod_proxy_scgi_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_scgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.exp"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.lib"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_scgi_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_scgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_scgi.pdb" /debug /out:"$(OUTDIR)\mod_proxy_scgi.so" /implib:"$(OUTDIR)\mod_proxy_scgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_scgi.obj" \
    	"$(INTDIR)\mod_proxy_scgi.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_scgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_scgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_scgi.so"
       if exist .\Release\mod_proxy_scgi.so.manifest mt.exe -manifest .\Release\mod_proxy_scgi.so.manifest -outputresource:.\Release\mod_proxy_scgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_scgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_scgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_scgi.obj"
    	-@erase "$(INTDIR)\mod_proxy_scgi.res"
    	-@erase "$(INTDIR)\mod_proxy_scgi_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_scgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.exp"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.lib"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_scgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_scgi_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_scgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_scgi.pdb" /debug /out:"$(OUTDIR)\mod_proxy_scgi.so" /implib:"$(OUTDIR)\mod_proxy_scgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_scgi.obj" \
    	"$(INTDIR)\mod_proxy_scgi.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_scgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_scgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_scgi.so"
       if exist .\Debug\mod_proxy_scgi.so.manifest mt.exe -manifest .\Debug\mod_proxy_scgi.so.manifest -outputresource:.\Debug\mod_proxy_scgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_scgi.dep")
    !INCLUDE "mod_proxy_scgi.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_scgi.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_scgi - Win32 Release" || "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
    SOURCE=.\mod_proxy_scgi.c
    
    "$(INTDIR)\mod_proxy_scgi.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_scgi - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_scgi - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_scgi - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_scgi - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_scgi - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_scgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_scgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_balancer.dep���������������������������������������������������0000664�0001751�0001751�00000005333�12674411515�022026� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_balancer.mak
    
    .\mod_proxy_balancer.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ftp.dep��������������������������������������������������������0000664�0001751�0001751�00000005227�12674411515�021052� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_ftp.mak
    
    .\mod_proxy_ftp.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_http.dsp�������������������������������������������������������0000664�0001751�0001751�00000011461�10551346420�021245� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 0x409 /fo"Release/mod_proxy_http.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_http.so" /d LONG_NAME="proxy_http_module for Apache"
    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 /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 /out:".\Release\mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_http.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 0x409 /fo"Debug/mod_proxy_http.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_http.so" /d LONG_NAME="proxy_http_module for Apache"
    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 /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 /out:".\Debug\mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_http.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxyscgi�����������������������������������������������������������0000664�0001751�0001751�00000010603�11546111464�020247� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= proxyscgi
    
    #
    # This is used by the link '-desc ' directive. 
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy SCGI Sub-Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Proxy SCGI 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	=
    
    #
    # 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)/proxyscgi.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_scgi.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.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_scgi_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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ftp.dsp��������������������������������������������������������0000664�0001751�0001751�00000011423�10551346420�021055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 0x409 /fo"Release/mod_proxy_ftp.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_ftp.so" /d LONG_NAME="proxy_ftp_module for Apache"
    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 /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 /out:".\Release\mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_ftp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 0x409 /fo"Debug/mod_proxy_ftp.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_ftp.so" /d LONG_NAME="proxy_ftp_module for Apache"
    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 /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 /out:".\Debug\mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_ftp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_http.c���������������������������������������������������������0000664�0001751�0001751�00000244500�14526115472�020712� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "ap_regex.h"
    
    module AP_MODULE_DECLARE_DATA proxy_http_module;
    
    static int (*ap_proxy_clear_connection_fn)(request_rec *r, apr_table_t *headers) =
            NULL;
    
    static apr_status_t ap_proxy_http_cleanup(const char *scheme,
                                              request_rec *r,
                                              proxy_conn_rec *backend);
    
    static apr_status_t ap_proxygetline(apr_bucket_brigade *bb, char *s, int n,
                                        request_rec *r, int flags, int *read);
    
    static const char *get_url_scheme(const char **url, int *is_ssl)
    {
        const char *u = *url;
    
        switch (u[0]) {
        case 'h':
        case 'H':
            if (strncasecmp(u + 1, "ttp", 3) == 0) {
                if (u[4] == ':') {
                    *is_ssl = 0;
                    *url = u + 5;
                    return "http";
                }
                if (apr_tolower(u[4]) == 's' && u[5] == ':') {
                    *is_ssl = 1;
                    *url = u + 6;
                    return "https";
                }
            }
            break;
    
        case 'w':
        case 'W':
            if (apr_tolower(u[1]) == 's') {
                if (u[2] == ':') {
                    *is_ssl = 0;
                    *url = u + 3;
                    return "ws";
                }
                if (apr_tolower(u[2]) == 's' && u[3] == ':') {
                    *is_ssl = 1;
                    *url = u + 4;
                    return "wss";
                }
            }
            break;
        }
    
        *is_ssl = 0;
        return NULL;
    }
    
    /*
     * Canonicalise http-like URLs.
     *  scheme is the scheme for the URL
     *  url    is the URL starting with the first '/'
     */
    static int proxy_http_canon(request_rec *r, char *url)
    {
        const char *base_url = url;
        char *host, *path, sport[7];
        char *search = NULL;
        const char *err;
        const char *scheme;
        apr_port_t port, def_port;
        int is_ssl = 0;
    
        scheme = get_url_scheme((const char **)&url, &is_ssl);
        if (!scheme) {
            return DECLINED;
        }
        port = def_port = (is_ssl) ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "HTTP: canonicalising URL %s", base_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, APLOGNO(01083)
                          "error parsing URL %s: %s", base_url, err);
            return HTTP_BAD_REQUEST;
        }
    
        /*
         * now parse path/search args, according to rfc1738:
         * process the path.
         *
         * In a reverse proxy, our URL has been processed, so canonicalise
         * unless proxy-nocanon is set to say it's raw
         * In a forward proxy, we have and MUST NOT MANGLE the original.
         */
        switch (r->proxyreq) {
        default: /* wtf are we doing here? */
        case PROXYREQ_REVERSE:
            if (apr_table_get(r->notes, "proxy-nocanon")) {
                path = url;   /* this is the raw path */
            }
            else if (apr_table_get(r->notes, "proxy-noencode")) {
                path = url;   /* this is the encoded path already */
                search = r->args;
            }
            else {
                core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
                int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
                path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path,
                                            flags, r->proxyreq);
                if (!path) {
                    return HTTP_BAD_REQUEST;
                }
                search = r->args;
            }
            break;
        case PROXYREQ_PROXY:
            path = url;
            break;
        }
        /*
         * If we have a raw control character or a ' ' in nocanon path or
         * r->args, correct encoding was missed.
         */
        if (path == url && *ap_scan_vchar_obstext(path)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10415)
                          "To be forwarded path contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
        if (search && *ap_scan_vchar_obstext(search)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10408)
                          "To be forwarded query string contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
    
        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, NULL);
        return OK;
    }
    
    /* Clear all connection-based headers from the incoming headers table */
    typedef struct header_dptr {
        apr_pool_t *pool;
        apr_table_t *table;
        apr_time_t time;
    } header_dptr;
    static ap_regex_t *warn_rx;
    static int clean_warning_headers(void *data, const char *key, const char *val)
    {
        apr_table_t *headers = ((header_dptr*)data)->table;
        apr_pool_t *pool = ((header_dptr*)data)->pool;
        char *warning;
        char *date;
        apr_time_t warn_time;
        const int nmatch = 3;
        ap_regmatch_t pmatch[3];
    
        if (headers == NULL) {
            ((header_dptr*)data)->table = headers = apr_table_make(pool, 2);
        }
    /*
     * Parse this, suckers!
     *
     *    Warning    = "Warning" ":" 1#warning-value
     *
     *    warning-value = warn-code SP warn-agent SP warn-text
     *                                             [SP warn-date]
     *
     *    warn-code  = 3DIGIT
     *    warn-agent = ( host [ ":" port ] ) | pseudonym
     *                    ; the name or pseudonym of the server adding
     *                    ; the Warning header, for use in debugging
     *    warn-text  = quoted-string
     *    warn-date  = <"> HTTP-date <">
     *
     * Buggrit, use a bloomin' regexp!
     * (\d{3}\s+\S+\s+\".*?\"(\s+\"(.*?)\")?)  --> whole in $1, date in $3
     */
        while (!ap_regexec(warn_rx, val, nmatch, pmatch, 0)) {
            warning = apr_pstrndup(pool, val+pmatch[0].rm_so,
                                   pmatch[0].rm_eo - pmatch[0].rm_so);
            warn_time = 0;
            if (pmatch[2].rm_eo > pmatch[2].rm_so) {
                /* OK, we have a date here */
                date = apr_pstrndup(pool, val+pmatch[2].rm_so,
                                    pmatch[2].rm_eo - pmatch[2].rm_so);
                warn_time = apr_date_parse_http(date);
            }
            if (!warn_time || (warn_time == ((header_dptr*)data)->time)) {
                apr_table_addn(headers, key, warning);
            }
            val += pmatch[0].rm_eo;
        }
        return 1;
    }
    static apr_table_t *ap_proxy_clean_warnings(apr_pool_t *p, apr_table_t *headers)
    {
       header_dptr x;
       x.pool = p;
       x.table = NULL;
       x.time = apr_date_parse_http(apr_table_get(headers, "Date"));
       apr_table_do(clean_warning_headers, &x, headers, "Warning", NULL);
       if (x.table != NULL) {
           apr_table_unset(headers, "Warning");
           return apr_table_overlay(p, headers, x.table);
       }
       else {
            return headers;
       }
    }
    
    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);
    }
    
    #ifndef CRLF_ASCII
    #define CRLF_ASCII  "\015\012"
    #endif
    #ifndef ZERO_ASCII
    #define ZERO_ASCII  "\060"
    #endif
    
    #define MAX_MEM_SPOOL 16384
    
    typedef enum {
        RB_INIT = 0,
        RB_STREAM_CL,
        RB_STREAM_CHUNKED,
        RB_SPOOL_CL
    } rb_methods;
    
    typedef struct {
        apr_pool_t *p;
        request_rec *r;
        const char *proto;
        proxy_worker *worker;
        proxy_server_conf *sconf;
    
        char server_portstr[32];
        proxy_conn_rec *backend;
        conn_rec *origin;
    
        apr_bucket_alloc_t *bucket_alloc;
        apr_bucket_brigade *header_brigade;
        apr_bucket_brigade *input_brigade;
        char *old_cl_val, *old_te_val;
        apr_off_t cl_val;
    
        rb_methods rb_method;
    
        const char *upgrade;
    
        unsigned int do_100_continue        :1,
                     prefetch_nonblocking   :1,
                     force10                :1;
    } proxy_http_req_t;
    
    static int stream_reqbody(proxy_http_req_t *req)
    {
        request_rec *r = req->r;
        int seen_eos = 0, rv = OK;
        apr_size_t hdr_len;
        char chunk_hdr[20];  /* must be here due to transient bucket. */
        conn_rec *origin = req->origin;
        proxy_conn_rec *p_conn = req->backend;
        apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
        apr_bucket_brigade *header_brigade = req->header_brigade;
        apr_bucket_brigade *input_brigade = req->input_brigade;
        rb_methods rb_method = req->rb_method;
        apr_off_t bytes, bytes_streamed = 0;
        apr_bucket *e;
    
        do {
            if (APR_BRIGADE_EMPTY(input_brigade)
                    && APR_BRIGADE_EMPTY(header_brigade)) {
                rv = ap_proxy_read_input(r, p_conn, input_brigade,
                                         HUGE_STRING_LEN);
                if (rv != OK) {
                    return rv;
                }
            }
    
            if (!APR_BRIGADE_EMPTY(input_brigade)) {
                /* If this brigade contains EOS, remove it and be done. */
                if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
                    seen_eos = 1;
    
                    /* 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);
                bytes_streamed += bytes;
    
                if (rb_method == RB_STREAM_CHUNKED) {
                    if (bytes) {
                        /*
                         * Prepend the size of 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,
                                                        bucket_alloc);
                        APR_BRIGADE_INSERT_HEAD(input_brigade, e);
    
                        /*
                         * Append the end-of-chunk CRLF
                         */
                        e = apr_bucket_immortal_create(CRLF_ASCII, 2, bucket_alloc);
                        APR_BRIGADE_INSERT_TAIL(input_brigade, e);
                    }
                    if (seen_eos) {
                        /*
                         * Append the tailing 0-size chunk
                         */
                        e = apr_bucket_immortal_create(ZERO_ASCII CRLF_ASCII
                                                       /* <trailers> */
                                                       CRLF_ASCII,
                                                       5, bucket_alloc);
                        APR_BRIGADE_INSERT_TAIL(input_brigade, e);
                    }
                }
                else if (rb_method == RB_STREAM_CL
                         && (bytes_streamed > req->cl_val
                             || (seen_eos && bytes_streamed < req->cl_val))) {
                    /* C-L != bytes streamed?!?
                     *
                     * Prevent HTTP Request/Response Splitting.
                     *
                     * We can't stream more (or less) bytes at the back end since
                     * they could be interpreted in separate requests (more bytes
                     * now would start a new request, less bytes would make the
                     * first bytes of the next request be part of the current one).
                     *
                     * It can't happen from the client connection here thanks to
                     * ap_http_filter(), but some module's filter may be playing
                     * bad games, hence the HTTP_INTERNAL_SERVER_ERROR.
                     */
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01086)
                                  "read %s bytes of request body than expected "
                                  "(got %" APR_OFF_T_FMT ", expected "
                                  "%" APR_OFF_T_FMT ")",
                                  bytes_streamed > req->cl_val ? "more" : "less",
                                  bytes_streamed, req->cl_val);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
                if (seen_eos && apr_table_get(r->subprocess_env,
                                              "proxy-sendextracrlf")) {
                    e = apr_bucket_immortal_create(CRLF_ASCII, 2, bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(input_brigade, e);
                }
            }
    
            /* If we never sent the header brigade, go ahead and take care of
             * that now by prepending it (once only since header_brigade will be
             * empty afterward).
             */
            APR_BRIGADE_PREPEND(input_brigade, header_brigade);
    
            /* Flush here on EOS because we won't ap_proxy_read_input() again. */
            rv = ap_proxy_pass_brigade(bucket_alloc, r, p_conn, origin,
                                       input_brigade, seen_eos);
            if (rv != OK) {
                return rv;
            }
        } while (!seen_eos);
    
        return OK;
    }
    
    static void terminate_headers(proxy_http_req_t *req)
    {
        apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
        apr_bucket *e;
        char *buf;
    
        /*
         * Handle Connection: header if we do HTTP/1.1 request:
         * If we plan to close the backend connection sent Connection: close
         * otherwise sent Connection: Keep-Alive.
         */
        if (!req->force10) {
            if (req->upgrade) {
                buf = apr_pstrdup(req->p, "Connection: Upgrade" CRLF);
                ap_xlate_proto_to_ascii(buf, strlen(buf));
                e = apr_bucket_pool_create(buf, strlen(buf), req->p, bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(req->header_brigade, e);
    
                /* Tell the backend that it can upgrade the connection. */
                buf = apr_pstrcat(req->p, "Upgrade: ", req->upgrade, CRLF, NULL);
            }
            else if (ap_proxy_connection_reusable(req->backend)) {
                buf = apr_pstrdup(req->p, "Connection: Keep-Alive" CRLF);
            }
            else {
                buf = apr_pstrdup(req->p, "Connection: close" CRLF);
            }
            ap_xlate_proto_to_ascii(buf, strlen(buf));
            e = apr_bucket_pool_create(buf, strlen(buf), req->p, bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(req->header_brigade, e);
        }
    
        /* add empty line at the end of the headers */
        e = apr_bucket_immortal_create(CRLF_ASCII, 2, bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(req->header_brigade, e);
    }
    
    static int ap_proxy_http_prefetch(proxy_http_req_t *req,
                                      apr_uri_t *uri, char *url)
    {
        apr_pool_t *p = req->p;
        request_rec *r = req->r;
        conn_rec *c = r->connection;
        proxy_conn_rec *p_conn = req->backend;
        apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
        apr_bucket_brigade *header_brigade = req->header_brigade;
        apr_bucket_brigade *input_brigade = req->input_brigade;
        apr_bucket *e;
        apr_off_t bytes_read = 0;
        apr_off_t bytes;
        int rv;
    
        rv = ap_proxy_create_hdrbrgd(p, header_brigade, r, p_conn,
                                     req->worker, req->sconf,
                                     uri, url, req->server_portstr,
                                     &req->old_cl_val, &req->old_te_val);
        if (rv != OK) {
            return rv;
        }
    
        /* sub-requests never use keepalives, and mustn't pass request bodies.
         * Because the new logic looks at input_brigade, we will self-terminate
         * input_brigade and jump past all of the request body logic...
         * Reading anything with ap_get_brigade is likely to consume the
         * main request's body or read beyond EOS - which would be unpleasant.
         *
         * An exception: when a kept_body is present, then subrequest CAN use
         * pass request bodies, and we DONT skip the body.
         */
        if (!r->kept_body && r->main) {
            /* XXX: Why DON'T sub-requests use keepalives? */
            p_conn->close = 1;
            req->old_te_val = NULL;
            req->old_cl_val = NULL;
            req->rb_method = RB_STREAM_CL;
            e = apr_bucket_eos_create(input_brigade->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(input_brigade, e);
            goto skip_body;
        }
    
        /* WE only understand chunked.  Other modules might inject
         * (and therefore, decode) other flavors but we don't know
         * that the can and have done so unless they remove
         * their decoding from the headers_in T-E list.
         * XXX: Make this extensible, but in doing so, presume the
         * encoding has been done by the extensions' handler, and
         * do not modify add_te_chunked's logic
         */
        if (req->old_te_val && ap_cstr_casecmp(req->old_te_val, "chunked") != 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01093)
                          "%s Transfer-Encoding is not supported",
                          req->old_te_val);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        if (req->old_cl_val && req->old_te_val) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01094)
                          "client %s (%s) requested Transfer-Encoding "
                          "chunked body with Content-Length (C-L ignored)",
                          c->client_ip, c->remote_host ? c->remote_host: "");
            req->old_cl_val = NULL;
            p_conn->close = 1;
        }
    
        rv = ap_proxy_prefetch_input(r, req->backend, input_brigade,
                                     req->prefetch_nonblocking ? APR_NONBLOCK_READ
                                                               : APR_BLOCK_READ,
                                     &bytes_read, MAX_MEM_SPOOL);
        if (rv != OK) {
            return rv;
        }
    
        /* Use chunked request body encoding or send a content-length body?
         *
         * Prefer C-L when:
         *
         *   We have no request body (handled by RB_STREAM_CL)
         *
         *   We have a request body length <= MAX_MEM_SPOOL
         *
         *   The administrator has setenv force-proxy-request-1.0
         *
         *   The client sent a C-L body, and the administrator has
         *   not setenv proxy-sendchunked or has set setenv proxy-sendcl
         *
         *   The client sent a T-E body, and the administrator has
         *   setenv proxy-sendcl, and not setenv proxy-sendchunked
         *
         * If both proxy-sendcl and proxy-sendchunked are set, the
         * behavior is the same as if neither were set, large bodies
         * that can't be read will be forwarded in their original
         * form of C-L, or T-E.
         *
         * To ensure maximum compatibility, setenv proxy-sendcl
         * To reduce server resource use,   setenv proxy-sendchunked
         *
         * Then address specific servers with conditional setenv
         * options to restore the default behavior where desirable.
         *
         * 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.  Chunked is always preferable.
         *
         * We can only trust the client-provided C-L if the T-E header
         * is absent, and the filters are unchanged (the body won't
         * be resized by another content filter).
         */
        if (!APR_BRIGADE_EMPTY(input_brigade)
            && APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
            /* The whole thing fit, so our decision is trivial, use
             * the filtered bytes read from the client for the request
             * body Content-Length.
             *
             * If we expected no body, and read no body, do not set
             * the Content-Length.
             */
            if (req->old_cl_val || req->old_te_val || bytes_read) {
                req->old_cl_val = apr_off_t_toa(r->pool, bytes_read);
                req->cl_val = bytes_read;
            }
            req->rb_method = RB_STREAM_CL;
        }
        else if (req->old_te_val) {
            if (req->force10
                 || (apr_table_get(r->subprocess_env, "proxy-sendcl")
                      && !apr_table_get(r->subprocess_env, "proxy-sendchunks")
                      && !apr_table_get(r->subprocess_env, "proxy-sendchunked"))) {
                req->rb_method = RB_SPOOL_CL;
            }
            else {
                req->rb_method = RB_STREAM_CHUNKED;
            }
        }
        else if (req->old_cl_val) {
            if (r->input_filters == r->proto_input_filters) {
                if (!ap_parse_strict_length(&req->cl_val, req->old_cl_val)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01085)
                                  "could not parse request Content-Length (%s)",
                                  req->old_cl_val);
                    return HTTP_BAD_REQUEST;
                }
                req->rb_method = RB_STREAM_CL;
            }
            else if (!req->force10
                      && (apr_table_get(r->subprocess_env, "proxy-sendchunks")
                          || apr_table_get(r->subprocess_env, "proxy-sendchunked"))
                      && !apr_table_get(r->subprocess_env, "proxy-sendcl")) {
                req->rb_method = RB_STREAM_CHUNKED;
            }
            else {
                req->rb_method = RB_SPOOL_CL;
            }
        }
        else {
            /* This is an appropriate default; very efficient for no-body
             * requests, and has the behavior that it will not add any C-L
             * when the old_cl_val is NULL.
             */
            req->rb_method = RB_SPOOL_CL;
        }
    
        switch (req->rb_method) {
        case RB_STREAM_CHUNKED:
            add_te_chunked(req->p, bucket_alloc, header_brigade);
            break;
    
        case RB_STREAM_CL:
            if (req->old_cl_val) {
                add_cl(req->p, bucket_alloc, header_brigade, req->old_cl_val);
            }
            break;
    
        default: /* => RB_SPOOL_CL */
            /* If we have to spool the body, do it now, before connecting or
             * reusing the backend connection.
             */
            rv = ap_proxy_spool_input(r, p_conn, input_brigade,
                                      &bytes, MAX_MEM_SPOOL);
            if (rv != OK) {
                return rv;
            }
            if (bytes || req->old_te_val || req->old_cl_val) {
                add_cl(p, bucket_alloc, header_brigade, apr_off_t_toa(p, bytes));
            }
        }
    
    /* Yes I hate gotos.  This is the subrequest shortcut */
    skip_body:
        terminate_headers(req);
    
        return OK;
    }
    
    static int ap_proxy_http_request(proxy_http_req_t *req)
    {
        int rv;
        request_rec *r = req->r;
    
        /* send the request header/body, if any. */
        switch (req->rb_method) {
        case RB_SPOOL_CL:
        case RB_STREAM_CL:
        case RB_STREAM_CHUNKED:
            if (req->do_100_continue) {
                rv = ap_proxy_pass_brigade(req->bucket_alloc, r, req->backend,
                                           req->origin, req->header_brigade, 1);
            }
            else {
                rv = stream_reqbody(req);
            }
            break;
    
        default:
            /* shouldn't be possible */
            rv = HTTP_INTERNAL_SERVER_ERROR;
            break;
        }
    
        if (rv != OK) {
            conn_rec *c = r->connection;
            /* apr_status_t value has been logged in lower level method */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01097)
                          "pass request body failed to %pI (%s) from %s (%s)",
                          req->backend->addr,
                          req->backend->hostname ? req->backend->hostname: "",
                          c->client_ip, c->remote_host ? c->remote_host: "");
            return rv;
        }
    
        return OK;
    }
    
    /*
     * If the date is a valid RFC 850 date or asctime() date, then it
     * is converted to the RFC 1123 format.
     */
    static const char *date_canon(apr_pool_t *p, const char *date)
    {
        apr_status_t rv;
        char* ndate;
    
        apr_time_t time = apr_date_parse_http(date);
        if (!time) {
            return date;
        }
    
        ndate = apr_palloc(p, APR_RFC822_DATE_LEN);
        rv = apr_rfc822_date(ndate, time);
        if (rv != APR_SUCCESS) {
            return date;
        }
    
        return ndate;
    }
    
    static request_rec *make_fake_req(conn_rec *c, request_rec *r)
    {
        apr_pool_t *pool;
        request_rec *rp;
    
        apr_pool_create(&pool, c->pool);
        apr_pool_tag(pool, "proxy_http_rp");
    
        rp = apr_pcalloc(pool, sizeof(*r));
    
        rp->pool            = pool;
        rp->status          = HTTP_OK;
    
        rp->headers_in      = apr_table_make(pool, 50);
        rp->trailers_in     = apr_table_make(pool, 5);
    
        rp->subprocess_env  = apr_table_make(pool, 50);
        rp->headers_out     = apr_table_make(pool, 12);
        rp->trailers_out    = apr_table_make(pool, 5);
        rp->err_headers_out = apr_table_make(pool, 5);
        rp->notes           = apr_table_make(pool, 5);
    
        rp->server = r->server;
        rp->log = r->log;
        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->useragent_ip = c->client_ip;
        rp->useragent_addr = c->client_addr;
    
        rp->request_config  = ap_create_request_config(pool);
        proxy_run_create_req(r, rp);
    
        return rp;
    }
    
    static void process_proxy_header(request_rec *r, proxy_dir_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 (!ap_cstr_casecmp(date_hdrs[i], key)) {
                apr_table_add(r->headers_out, key,
                              date_canon(r->pool, value));
                return;
            }
        }
        for (i = 0; transform_hdrs[i].name; ++i) {
            if (!ap_cstr_casecmp(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);
    }
    
    /*
     * 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 apr_status_t 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;
        int saw_headers = 0;
        void *sconf = r->server->module_config;
        proxy_server_conf *psc;
        proxy_dir_conf *dconf;
        apr_status_t rc;
        apr_bucket_brigade *tmp_bb;
    
        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
        psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
    
        r->headers_out = apr_table_make(r->pool, 20);
        r->trailers_out = apr_table_make(r->pool, 5);
        *pread_len = 0;
    
        /*
         * Read header lines until we get the empty separator line, a read error,
         * the connection closes (EOF), or we timeout.
         */
        ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                      "Headers received from backend:");
    
        tmp_bb = apr_brigade_create(r->pool, c->bucket_alloc);
        while (1) {
            rc = ap_proxygetline(tmp_bb, buffer, size, rr,
                                 AP_GETLINE_FOLD | AP_GETLINE_NOSPC_EOL, &len);
    
    
            if (rc != APR_SUCCESS) {
                if (APR_STATUS_IS_ENOSPC(rc)) {
                    int trunc = (len > 128 ? 128 : len) / 2;
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124)
                            "header size is over the limit allowed by "
                            "ResponseFieldSize (%d bytes). "
                            "Bad response header: '%.*s[...]%s'",
                            size, trunc, buffer, buffer + len - trunc);
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10404) 
                                  "Error reading headers from backend");
                }
                r->headers_out = NULL;
                return rc;
            }
    
            if (len <= 0) {
                break;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "%s", buffer);
            }
    
            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 APR_EINVAL;
                    }
                    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_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01098)
                                          "Starting body due to bogus non-header "
                                          "in headers returned by %s (%s)",
                                          r->uri, r->method);
                            *pread_len = len;
                            return APR_SUCCESS;
                        }
                        else {
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01099)
                                          "No HTTP headers returned by %s (%s)",
                                          r->uri, r->method);
                            return APR_SUCCESS;
                        }
                    }
                }
                /* this is the psc->badopt == bad_ignore case */
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01100)
                              "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, dconf, buffer, value);
            saw_headers = 1;
        }
        return APR_SUCCESS;
    }
    
    
    
    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_proxygetline(apr_bucket_brigade *bb, char *s, int n,
                                        request_rec *r, int flags, int *read)
    {
        apr_status_t rv;
        apr_size_t len;
    
        rv = ap_rgetline(&s, n, &len, r, flags, bb);
        apr_brigade_cleanup(bb);
    
        if (rv == APR_SUCCESS || APR_STATUS_IS_ENOSPC(rv)) {
            *read = (int)len;
        } else {
            *read = -1;
        }
    
        return rv;
    }
    
    /*
     * Limit the number of interim responses we sent back to the client. Otherwise
     * we suffer from a memory build up. Besides there is NO sense in sending back
     * an unlimited number of interim responses to the client. Thus if we cross
     * this limit send back a 502 (Bad Gateway).
     */
    #ifndef AP_MAX_INTERIM_RESPONSES
    #define AP_MAX_INTERIM_RESPONSES 10
    #endif
    
    static int add_trailers(void *data, const char *key, const char *val)
    {
        if (val) {
            apr_table_add((apr_table_t*)data, key, val);
        }
        return 1;
    }
    
    static int send_continue_body(proxy_http_req_t *req)
    {
        int status;
    
        /* Send the request body (fully). */
        switch(req->rb_method) {
        case RB_SPOOL_CL:
        case RB_STREAM_CL:
        case RB_STREAM_CHUNKED:
            status = stream_reqbody(req);
            break;
        default:
            /* Shouldn't happen */
            status = HTTP_INTERNAL_SERVER_ERROR;
            break;
        }
        if (status != OK) {
            conn_rec *c = req->r->connection;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req->r,
                    APLOGNO(10154) "pass request body failed "
                    "to %pI (%s) from %s (%s) with status %i",
                    req->backend->addr,
                    req->backend->hostname ? req->backend->hostname : "",
                    c->client_ip, c->remote_host ? c->remote_host : "",
                    status);
            req->backend->close = 1;
        }
        return status;
    }
    
    static
    int ap_proxy_http_process_response(proxy_http_req_t *req)
    {
        apr_pool_t *p = req->p;
        request_rec *r = req->r;
        conn_rec *c = r->connection;
        proxy_worker *worker = req->worker;
        proxy_conn_rec *backend = req->backend;
        conn_rec *origin = req->origin;
        int do_100_continue = req->do_100_continue;
        int status;
    
        char *buffer;
        char fixed_buffer[HUGE_STRING_LEN];
        const char *buf;
        char keepchar;
        apr_bucket *e;
        apr_bucket_brigade *bb;
        apr_bucket_brigade *pass_bb;
        int len, backasswards;
        int interim_response = 0; /* non-zero whilst interim 1xx responses
                                   * are being read. */
        apr_size_t response_field_size = 0;
        int pread_len = 0;
        apr_table_t *save_table;
        int backend_broke = 0;
        static const char *hop_by_hop_hdrs[] =
            {"Keep-Alive", "Proxy-Authenticate", "TE", "Trailer", "Upgrade", NULL};
        int i;
        const char *te = NULL;
        int original_status = r->status;
        int proxy_status = OK;
        const char *original_status_line = r->status_line;
        const char *proxy_status_line = NULL;
        apr_interval_time_t old_timeout = 0;
        proxy_dir_conf *dconf;
    
        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
    
        bb = apr_brigade_create(p, c->bucket_alloc);
        pass_bb = apr_brigade_create(p, c->bucket_alloc);
    
        /* Only use dynamically sized buffer if user specifies ResponseFieldSize */
        if(backend->worker->s->response_field_size_set) {
            response_field_size = backend->worker->s->response_field_size;
    
            if (response_field_size != HUGE_STRING_LEN)
                buffer = apr_pcalloc(p, response_field_size);
            else
                buffer = fixed_buffer;
        }
        else {
            response_field_size = HUGE_STRING_LEN;
            buffer = fixed_buffer;
        }
    
        /* Setup for 100-Continue timeout if appropriate */
        if (do_100_continue && worker->s->ping_timeout_set) {
            apr_socket_timeout_get(backend->sock, &old_timeout);
            if (worker->s->ping_timeout != old_timeout) {
                apr_status_t rc;
                rc = apr_socket_timeout_set(backend->sock, worker->s->ping_timeout);
                if (rc != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(01101)
                                  "could not set 100-Continue timeout");
                }
            }
        }
    
        /* Get response from the remote server, and pass it up the
         * filter chain
         */
    
        backend->r = make_fake_req(origin, r);
        /* In case anyone needs to know, this is a fake request that is really a
         * response.
         */
        backend->r->proxyreq = PROXYREQ_RESPONSE;
        apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
                       origin->local_addr->port));
        do {
            apr_status_t rc;
            const char *upgrade = NULL;
            int major = 0, minor = 0;
            int toclose = 0;
    
            apr_brigade_cleanup(bb);
    
            rc = ap_proxygetline(backend->tmp_bb, buffer, response_field_size,
                                 backend->r, 0, &len);
            if (len == 0) {
                /* handle one potential stray CRLF */
                rc = ap_proxygetline(backend->tmp_bb, buffer, response_field_size,
                                     backend->r, 0, &len);
            }
            if (len <= 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(01102)
                              "error reading status line from remote "
                              "server %s:%d", backend->hostname, backend->port);
                if (APR_STATUS_IS_TIMEUP(rc)) {
                    apr_table_setn(r->notes, "proxy_timedout", "1");
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01103) "read timeout");
                    if (do_100_continue) {
                        return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE,
                                             "Timeout on 100-Continue");
                    }
                }
                /*
                 * If we are a reverse proxy request shutdown the connection
                 * WITHOUT ANY response to trigger a retry by the client
                 * if allowed (as for idempotent requests).
                 * BUT currently we should not do this if the request is the
                 * first request on a keepalive connection as browsers like
                 * seamonkey only display an empty page in this case and do
                 * not do a retry. We should also not do this on a
                 * connection which times out; instead handle as
                 * we normally would handle timeouts
                 */
                if (r->proxyreq == PROXYREQ_REVERSE && c->keepalives &&
                    !APR_STATUS_IS_TIMEUP(rc)) {
                    apr_bucket *eos;
    
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01104)
                                  "Closing connection to client because"
                                  " reading from backend server %s:%d failed."
                                  " Number of keepalives %i", backend->hostname,
                                  backend->port, c->keepalives);
                    ap_proxy_backend_broke(r, bb);
                    /*
                     * Add an EOC bucket to signal the ap_http_header_filter
                     * that it should get out of our way, BUT ensure that the
                     * EOC bucket is inserted BEFORE an EOS bucket in bb as
                     * some resource filters like mod_deflate pass everything
                     * up to the EOS down the chain immediately and sent the
                     * remainder of the brigade later (or even never). But in
                     * this case the ap_http_header_filter does not get out of
                     * our way soon enough.
                     */
                    e = ap_bucket_eoc_create(c->bucket_alloc);
                    eos = APR_BRIGADE_LAST(bb);
                    while ((APR_BRIGADE_SENTINEL(bb) != eos)
                           && !APR_BUCKET_IS_EOS(eos)) {
                        eos = APR_BUCKET_PREV(eos);
                    }
                    if (eos == APR_BRIGADE_SENTINEL(bb)) {
                        APR_BRIGADE_INSERT_TAIL(bb, e);
                    }
                    else {
                        APR_BUCKET_INSERT_BEFORE(eos, e);
                    }
                    ap_pass_brigade(r->output_filters, bb);
                    /* Mark the backend connection for closing */
                    backend->close = 1;
                    if (origin->keepalives) {
                        /* We already had a request on this backend connection and
                         * might just have run into a keepalive race. Hence we
                         * think positive and assume that the backend is fine and
                         * we do not need to signal an error on backend side.
                         */
                        return OK;
                    }
                    /*
                     * This happened on our first request on this connection to the
                     * backend. This indicates something fishy with the backend.
                     * Return HTTP_INTERNAL_SERVER_ERROR to signal an unrecoverable
                     * server error. We do not worry about r->status code and a
                     * possible error response here as the ap_http_outerror_filter
                     * will fix all of this for us.
                     */
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                if (!c->keepalives) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01105)
                                  "NOT Closing connection to client"
                                  " although reading from backend server %s:%d"
                                  " failed.",
                                  backend->hostname, backend->port);
                }
                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/#.# ###*")) {
                major = buffer[5] - '0';
                minor = buffer[7] - '0';
    
                /* If not an HTTP/1 message or
                 * if the status line was > 8192 bytes
                 */
                if ((major != 1) || (len >= response_field_size - 1)) {
                    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';
                proxy_status = atoi(&buffer[9]);
                apr_table_setn(r->notes, "proxy-status",
                               apr_pstrdup(r->pool, &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';
                }
                proxy_status_line = apr_pstrdup(p, &buffer[9]);
    
                /* The status out of the front is the same as the status coming in
                 * from the back, until further notice.
                 */
                r->status = proxy_status;
                r->status_line = proxy_status_line;
    
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                              "Status from backend: %d", proxy_status);
    
                /* read the headers. */
                /* N.B. for HTTP/1.0 clients, we have to fold line-wrapped headers*/
                /* Also, take care with headers with multiple occurrences. */
    
                /* 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 */
                rc = ap_proxy_read_headers(r, backend->r, buffer, response_field_size,
                                           origin, &pread_len);
    
                if (rc != APR_SUCCESS || r->headers_out == NULL) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01106)
                                  "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;
                }
    
                /* 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);
                }
    
                /*
                 * Save a possible Transfer-Encoding header as we need it later for
                 * ap_http_filter to know where to end.
                 */
                te = apr_table_get(r->headers_out, "Transfer-Encoding");
    
                /* can't have both Content-Length and Transfer-Encoding */
                if (te && apr_table_get(r->headers_out, "Content-Length")) {
                    /*
                     * 2616 section 4.4, point 3: "if both Transfer-Encoding
                     * and Content-Length are received, the latter MUST be
                     * ignored";
                     *
                     * To help mitigate HTTP Splitting, unset Content-Length
                     * and shut down the backend server connection
                     * XXX: We aught to treat such a response as uncachable
                     */
                    apr_table_unset(r->headers_out, "Content-Length");
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01107)
                                  "server %s:%d returned Transfer-Encoding"
                                  " and Content-Length",
                                  backend->hostname, backend->port);
                    backend->close = 1;
                }
    
                upgrade = apr_table_get(r->headers_out, "Upgrade");
                if (proxy_status == HTTP_SWITCHING_PROTOCOLS) {
                    if (!upgrade || !req->upgrade || (strcasecmp(req->upgrade,
                                                                 upgrade) != 0)) {
                        return ap_proxyerror(r, HTTP_BAD_GATEWAY,
                                             apr_pstrcat(p, "Unexpected Upgrade: ",
                                                         upgrade ? upgrade : "n/a",
                                                         " (expecting ",
                                                         req->upgrade ? req->upgrade
                                                                      : "n/a", ")",
                                                         NULL));
                    }
                    backend->close = 1;
                }
    
                /* strip connection listed hop-by-hop headers from response */
                toclose = ap_proxy_clear_connection_fn(r, r->headers_out);
                if (toclose) {
                    backend->close = 1;
                    if (toclose < 0) {
                        return ap_proxyerror(r, HTTP_BAD_GATEWAY,
                                             "Malformed connection header");
                    }
                }
    
                if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
                    ap_set_content_type(r, apr_pstrdup(p, buf));
                }
                if (!ap_is_HTTP_INFO(proxy_status)) {
                    ap_proxy_pre_http_request(origin, backend->r);
                }
    
                /* Clear hop-by-hop headers */
                for (i=0; hop_by_hop_hdrs[i]; ++i) {
                    apr_table_unset(r->headers_out, hop_by_hop_hdrs[i]);
                }
    
                /* Delete warnings with wrong date */
                r->headers_out = ap_proxy_clean_warnings(p, r->headers_out);
    
                /* handle Via header in response */
                if (req->sconf->viaopt != via_off
                        && req->sconf->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_addn(r->headers_out, "Via",
                                   (req->sconf->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,
                                               req->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,
                                               req->server_portstr)
                    );
                }
    
                /* cancel keepalive if HTTP/1.0 or less */
                if ((major < 1) || (minor < 1)) {
                    backend->close = 1;
                    origin->keepalive = AP_CONN_CLOSE;
                }
                else {
                    /*
                     * Keep track of the number of keepalives we processed on this
                     * connection.
                     */
                    origin->keepalives++;
                }
    
            } else {
                /* an http/0.9 response */
                backasswards = 1;
                r->status = proxy_status = 200;
                r->status_line = "200 OK";
                backend->close = 1;
            }
    
            if (ap_is_HTTP_INFO(proxy_status)) {
                const char *policy = NULL;
    
                /* RFC2616 tells us to forward this.
                 *
                 * OTOH, an interim response here may mean the backend
                 * is playing sillybuggers.  The Client didn't ask for
                 * it within the defined HTTP/1.1 mechanisms, and if
                 * it's an extension, it may also be unsupported by us.
                 *
                 * There's also the possibility that changing existing
                 * behaviour here might break something.
                 *
                 * So let's make it configurable.
                 *
                 * We need to force "r->expecting_100 = 1" for RFC behaviour
                 * otherwise ap_send_interim_response() does nothing when
                 * the client did not ask for 100-continue.
                 *
                 * 101 Switching Protocol has its own configuration which
                 * shouldn't be interfered by "proxy-interim-response".
                 */
                if (proxy_status != HTTP_SWITCHING_PROTOCOLS) {
                    policy = apr_table_get(r->subprocess_env,
                                           "proxy-interim-response");
                }
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "HTTP: received interim %d response (policy: %s)",
                              r->status, policy ? policy : "n/a");
                if (!policy
                        || (!strcasecmp(policy, "RFC")
                            && (proxy_status != HTTP_CONTINUE
                                || (r->expecting_100 = 1)))) {
                    switch (proxy_status) {
                    case HTTP_SWITCHING_PROTOCOLS:
                        AP_DEBUG_ASSERT(upgrade != NULL);
                        apr_table_setn(r->headers_out, "Connection", "Upgrade");
                        apr_table_setn(r->headers_out, "Upgrade",
                                       apr_pstrdup(p, upgrade));
                        break;
                    }
                    ap_send_interim_response(r, 1);
                }
                /* FIXME: refine this to be able to specify per-response-status
                 * policies and maybe also add option to bail out with 502
                 */
                else if (strcasecmp(policy, "Suppress")) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01108)
                                  "undefined proxy interim response policy");
                }
                interim_response++;
            }
            else {
                interim_response = 0;
            }
    
            /* If we still do 100-continue (end-to-end or ping), either the
             * current response is the expected "100 Continue" and we are done
             * with this mode, or this is another interim response and we'll wait
             * for the next one, or this is a final response and hence the backend
             * did not honor our expectation.
             */
            if (do_100_continue && (!interim_response
                                    || proxy_status == HTTP_CONTINUE)) {
                /* RFC 7231 - Section 5.1.1 - Expect - Requirement for servers
                 *   A server that responds with a final status code before
                 *   reading the entire message body SHOULD indicate in that
                 *   response whether it intends to close the connection or
                 *   continue reading and discarding the request message.
                 *
                 * So, if this response is not an interim 100 Continue, we can
                 * avoid sending the request body if the backend responded with
                 * "Connection: close" or HTTP < 1.1, and either let the core
                 * discard it or the caller try another balancer member with the
                 * same body (given status 503, though not implemented yet).
                 */
                int do_send_body = (proxy_status == HTTP_CONTINUE
                                    || (!toclose && major > 0 && minor > 0));
    
                /* Reset to old timeout iff we've adjusted it. */
                if (worker->s->ping_timeout_set) {
                    apr_socket_timeout_set(backend->sock, old_timeout);
                }
    
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10153)
                              "HTTP: %s100 continue sent by %pI (%s): "
                              "%ssending body (response: HTTP/%i.%i %s)",
                              proxy_status != HTTP_CONTINUE ? "no " : "",
                              backend->addr,
                              backend->hostname ? backend->hostname : "",
                              do_send_body ? "" : "not ",
                              major, minor, proxy_status_line);
    
                if (do_send_body) {
                    status = send_continue_body(req);
                    if (status != OK) {
                        return status;
                    }
                }
                else {
                    /* If we don't read the client connection any further, since
                     * there are pending data it should be "Connection: close"d to
                     * prevent reuse. We don't exactly c->keepalive = AP_CONN_CLOSE
                     * here though, because error_override or a potential retry on
                     * another backend could finally read that data and finalize
                     * the request processing, making keep-alive possible. So what
                     * we do is leaving r->expecting_100 alone, ap_set_keepalive()
                     * will do the right thing according to the final response and
                     * any later update of r->expecting_100.
                     */
                }
    
                /* Once only! */
                do_100_continue = 0;
            }
    
            if (proxy_status == HTTP_SWITCHING_PROTOCOLS) {
                apr_status_t rv;
                proxy_tunnel_rec *tunnel;
                apr_interval_time_t client_timeout = -1,
                                    backend_timeout = -1;
    
                /* If we didn't send the full body yet, do it now */
                if (do_100_continue) {
                    r->expecting_100 = 0;
                    status = send_continue_body(req);
                    if (status != OK) {
                        return status;
                    }
                }
    
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10239)
                              "HTTP: tunneling protocol %s", upgrade);
    
                rv = ap_proxy_tunnel_create(&tunnel, r, origin, upgrade);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10240)
                                  "can't create tunnel for %s", upgrade);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
                /* Set timeout to the highest configured for client or backend */
                apr_socket_timeout_get(backend->sock, &backend_timeout);
                apr_socket_timeout_get(ap_get_conn_socket(c), &client_timeout);
                if (backend_timeout >= 0 && backend_timeout > client_timeout) {
                    tunnel->timeout = backend_timeout;
                }
                else {
                    tunnel->timeout = client_timeout;
                }
    
                /* Let proxy tunnel forward everything */
                status = ap_proxy_tunnel_run(tunnel);
    
                /* We are done with both connections */
                return DONE;
            }
    
            if (interim_response) {
                /* Already forwarded above, read next response */
                continue;
            }
    
            /* Moved the fixups of Date headers and those affected by
             * ProxyPassReverse/etc from here to ap_proxy_read_headers
             */
    
            /* PR 41646: get HEAD right with ProxyErrorOverride */
            if (ap_proxy_should_override(dconf, proxy_status)) {
                if (proxy_status == HTTP_UNAUTHORIZED) {
                    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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01109)
                                      "origin server sent 401 without "
                                      "WWW-Authenticate header");
                    }
                }
    
                /* clear r->status for override error, otherwise ErrorDocument
                 * thinks that this is a recursive error, and doesn't find the
                 * custom error page
                 */
                r->status = HTTP_OK;
                /* Discard body, if one is expected */
                if (!r->header_only && !AP_STATUS_IS_HEADER_ONLY(proxy_status)) {
                    const char *tmp;
                    /* Add minimal headers needed to allow http_in filter
                     * detecting end of body without waiting for a timeout. */
                    if ((tmp = apr_table_get(r->headers_out, "Transfer-Encoding"))) {
                        apr_table_set(backend->r->headers_in, "Transfer-Encoding", tmp);
                    }
                    else if ((tmp = apr_table_get(r->headers_out, "Content-Length"))) {
                        apr_table_set(backend->r->headers_in, "Content-Length", tmp);
                    }
                    else if (te) {
                        apr_table_set(backend->r->headers_in, "Transfer-Encoding", te);
                    }
                    ap_discard_request_body(backend->r);
                }
                /*
                 * prevent proxy_handler() from treating this as an
                 * internal error.
                 */
                apr_table_setn(r->notes, "proxy-error-override", "1");
                return proxy_status;
            }
    
            /* Forward back Upgrade header if it matches the configured one(s), it
             * may be an HTTP_UPGRADE_REQUIRED response or some other status where
             * Upgrade makes sense to negotiate the protocol by other means.
             */
            if (upgrade && ap_proxy_worker_can_upgrade(p, worker, upgrade,
                                                       (*req->proto == 'w')
                                                       ? "WebSocket" : NULL)) {
                apr_table_setn(r->headers_out, "Connection", "Upgrade");
                apr_table_setn(r->headers_out, "Upgrade", apr_pstrdup(p, upgrade));
            }
    
            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 */
                (proxy_status != HTTP_NO_CONTENT) &&      /* not 204 */
                (proxy_status != HTTP_NOT_MODIFIED)) {    /* not 304 */
                apr_read_type_e mode;
                int finish;
    
                /* 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.
                 */
                backend->r->headers_in = apr_table_clone(backend->r->pool, r->headers_out);
                /*
                 * Restore Transfer-Encoding header from response if we saved
                 * one before and there is none left. We need it for the
                 * ap_http_filter. See above.
                 */
                if (te && !apr_table_get(backend->r->headers_in, "Transfer-Encoding")) {
                    apr_table_add(backend->r->headers_in, "Transfer-Encoding", te);
                }
    
                apr_table_unset(r->headers_out,"Transfer-Encoding");
    
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "start body send");
    
                /* read the body, pass it to the output filters */
    
                /* Handle the case where the error document is itself reverse
                 * proxied and was successful. We must maintain any previous
                 * error status so that an underlying error (eg HTTP_NOT_FOUND)
                 * doesn't become an HTTP_OK.
                 */
                if (ap_proxy_should_override(dconf, original_status)) {
                    r->status = original_status;
                    r->status_line = original_status_line;
                }
    
                mode = APR_NONBLOCK_READ;
                finish = FALSE;
                do {
                    apr_off_t readbytes;
                    apr_status_t rv;
    
                    rv = ap_get_brigade(backend->r->input_filters, bb,
                                        AP_MODE_READBYTES, mode,
                                        req->sconf->io_buffer_size);
    
                    /* ap_get_brigade will return success with an empty brigade
                     * for a non-blocking read which would block: */
                    if (mode == APR_NONBLOCK_READ
                        && (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) {
                        backend->close = 1;
                        break;
                    }
                    else if (rv != APR_SUCCESS) {
                        /* In this case, we are in real trouble because
                         * our backend bailed on us. Pass along a 502 error
                         * error bucket
                         */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01110)
                                      "error reading response");
                        apr_brigade_cleanup(bb);
                        ap_proxy_backend_broke(r, bb);
                        ap_pass_brigade(r->output_filters, bb);
                        backend_broke = 1;
                        backend->close = 1;
                        break;
                    }
                    /* next time try a non-blocking read */
                    mode = APR_NONBLOCK_READ;
    
                    if (!apr_is_empty_table(backend->r->trailers_in)) {
                        apr_table_do(add_trailers, r->trailers_out,
                                backend->r->trailers_in, NULL);
                        apr_table_clear(backend->r->trailers_in);
                    }
    
                    apr_brigade_length(bb, 0, &readbytes);
                    backend->worker->s->read += readbytes;
    #if DEBUGGING
                    {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01111)
                                  "readbytes: %#x", readbytes);
                    }
    #endif
                    /* sanity check */
                    if (APR_BRIGADE_EMPTY(bb)) {
                        break;
                    }
    
                    /* Switch the allocator lifetime of the buckets */
                    ap_proxy_buckets_lifetime_transform(r, bb, pass_bb);
    
                    /* found the last brigade? */
                    if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(pass_bb))) {
    
                        /* signal that we must leave */
                        finish = TRUE;
    
                        /* the brigade may contain transient buckets that contain
                         * data that lives only as long as the backend connection.
                         * Force a setaside so these transient buckets become heap
                         * buckets that live as long as the request.
                         */
                        for (e = APR_BRIGADE_FIRST(pass_bb); e
                                != APR_BRIGADE_SENTINEL(pass_bb); e
                                = APR_BUCKET_NEXT(e)) {
                            apr_bucket_setaside(e, r->pool);
                        }
    
                        /* finally it is safe to clean up the brigade from the
                         * connection pool, as we have forced a setaside on all
                         * buckets.
                         */
                        apr_brigade_cleanup(bb);
    
                        /* make sure we release the backend connection as soon
                         * as we know we are done, so that the backend isn't
                         * left waiting for a slow client to eventually
                         * acknowledge the data.
                         */
                        ap_proxy_release_connection(backend->worker->s->scheme,
                                backend, r->server);
                        /* Ensure that the backend is not reused */
                        req->backend = NULL;
    
                    }
    
                    /* try send what we read */
                    if (ap_pass_brigade(r->output_filters, pass_bb) != APR_SUCCESS
                        || c->aborted) {
                        /* Ack! Phbtt! Die! User aborted! */
                        /* Only close backend if we haven't got all from the
                         * backend. Furthermore if req->backend is NULL it is no
                         * longer safe to fiddle around with backend as it might
                         * be already in use by another thread.
                         */
                        if (req->backend) {
                            /* this causes socket close below */
                            req->backend->close = 1;
                        }
                        finish = TRUE;
                    }
    
                    /* make sure we always clean up after ourselves */
                    apr_brigade_cleanup(pass_bb);
                    apr_brigade_cleanup(bb);
    
                } while (!finish);
    
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "end body send");
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "header only");
    
                /* make sure we release the backend connection as soon
                 * as we know we are done, so that the backend isn't
                 * left waiting for a slow client to eventually
                 * acknowledge the data.
                 */
                ap_proxy_release_connection(backend->worker->s->scheme,
                        backend, r->server);
                /* Ensure that the backend is not reused */
                req->backend = NULL;
    
                /* Pass EOS bucket down the filter chain. */
                e = apr_bucket_eos_create(c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, e);
                ap_pass_brigade(r->output_filters, bb);
    
                apr_brigade_cleanup(bb);
            }
        } while (interim_response && (interim_response < AP_MAX_INTERIM_RESPONSES));
    
        /* We have to cleanup bb brigade, because buckets inserted to it could be
         * created from scpool and this pool can be freed before this brigade. */
        apr_brigade_cleanup(bb);
    
        /* See define of AP_MAX_INTERIM_RESPONSES for why */
        if (interim_response >= AP_MAX_INTERIM_RESPONSES) {
            return ap_proxyerror(r, HTTP_BAD_GATEWAY,
                                 apr_psprintf(p,
                                 "Too many (%d) interim responses from origin server",
                                 interim_response));
        }
    
        /* If our connection with the client is to be aborted, return DONE. */
        if (c->aborted || backend_broke) {
            return DONE;
        }
    
        return OK;
    }
    
    static
    apr_status_t ap_proxy_http_cleanup(const char *scheme, request_rec *r,
                                       proxy_conn_rec *backend)
    {
        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;
        const char *scheme;
        const char *u = url;
        proxy_http_req_t *req = NULL;
        proxy_conn_rec *backend = NULL;
        apr_bucket_brigade *input_brigade = NULL;
        int is_ssl = 0;
        conn_rec *c = r->connection;
        proxy_dir_conf *dconf;
        int retry = 0;
        char *locurl = url;
        int toclose = 0;
        /*
         * Use a shorter-lived pool to reduce memory usage
         * and avoid a memory leak
         */
        apr_pool_t *p = r->pool;
        apr_uri_t *uri;
    
        scheme = get_url_scheme(&u, &is_ssl);
        if (!scheme && proxyname && strncasecmp(url, "ftp:", 4) == 0) {
            u = url + 4;
            scheme = "ftp";
            is_ssl = 0;
        }
        if (!scheme || u[0] != '/' || u[1] != '/' || u[2] == '\0') {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01113)
                          "HTTP: declining URL %s", url);
            return DECLINED; /* only interested in HTTP, WS or FTP via proxy */
        }
        if (is_ssl && !ap_ssl_has_outgoing_handlers()) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01112)
                          "HTTP: declining URL %s (mod_ssl not configured?)", url);
            return DECLINED;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "HTTP: serving URL %s", url);
    
        /* create space for state information */
        if ((status = ap_proxy_acquire_connection(scheme, &backend,
                                                  worker, r->server)) != OK) {
            return status;
        }
    
        backend->is_ssl = is_ssl;
    
        req = apr_pcalloc(p, sizeof(*req));
        req->p = p;
        req->r = r;
        req->sconf = conf;
        req->worker = worker;
        req->backend = backend;
        req->proto = scheme;
        req->bucket_alloc = c->bucket_alloc;
        req->rb_method = RB_INIT;
    
        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
    
        if (apr_table_get(r->subprocess_env, "force-proxy-request-1.0")) {
            req->force10 = 1;
        }
        else if (*worker->s->upgrade || *req->proto == 'w') {
            /* Forward Upgrade header if it matches the configured one(s),
             * the default being "WebSocket" for ws[s] schemes.
             */
            const char *upgrade = apr_table_get(r->headers_in, "Upgrade");
            if (upgrade && ap_proxy_worker_can_upgrade(p, worker, upgrade,
                                                       (*req->proto == 'w')
                                                       ? "WebSocket" : NULL)) {
                req->upgrade = upgrade;
            }
        }
    
        /* We possibly reuse input data prefetched in previous call(s), e.g. for a
         * balancer fallback scenario, and in this case the 100 continue settings
         * should be consistent between balancer members. If not, we need to ignore
         * Proxy100Continue on=>off once we tried to prefetch already, otherwise
         * the HTTP_IN filter won't send 100 Continue for us anymore, and we might
         * deadlock with the client waiting for each other. Note that off=>on is
         * not an issue because in this case r->expecting_100 is false (the 100
         * Continue is out already), but we make sure that prefetch will be
         * nonblocking to avoid passing more time there. 
         */
        apr_pool_userdata_get((void **)&input_brigade, "proxy-req-input", p);
    
        /* Should we handle end-to-end or ping 100-continue? */
        if (!req->force10
            && ((r->expecting_100 && (dconf->forward_100_continue || input_brigade))
                || PROXY_SHOULD_PING_100_CONTINUE(worker, r))) {
            /* Tell ap_proxy_create_hdrbrgd() to preserve/add the Expect header */
            apr_table_setn(r->notes, "proxy-100-continue", "1");
            req->do_100_continue = 1;
        }
    
        /* Should we block while prefetching the body or try nonblocking and flush
         * data to the backend ASAP?
         */
        if (input_brigade
                || req->do_100_continue
                || apr_table_get(r->subprocess_env,
                                 "proxy-prefetch-nonblocking")) {
            req->prefetch_nonblocking = 1;
        }
    
        /*
         * In the case that we are handling a reverse proxy connection and this
         * is not a request that is coming over an already kept alive connection
         * with the client, do NOT reuse the connection to the backend, because
         * we cannot forward a failure to the client in this case as the client
         * does NOT expect this in this situation.
         * Yes, this creates a performance penalty.
         */
        if ((r->proxyreq == PROXYREQ_REVERSE) && (!c->keepalives)
            && (apr_table_get(r->subprocess_env, "proxy-initial-not-pooled"))) {
            backend->close = 1;
        }
    
        /* Step One: Determine Who To Connect To */
        uri = apr_palloc(p, sizeof(*uri));
        if ((status = ap_proxy_determine_connection(p, r, conf, worker, backend,
                                                uri, &locurl, proxyname,
                                                proxyport, req->server_portstr,
                                                sizeof(req->server_portstr))))
            goto cleanup;
    
        /* The header is always (re-)built since it depends on worker settings,
         * but the body can be fetched only once (even partially), so it's saved
         * in between proxy_http_handler() calls should we come back here.
         */
        req->header_brigade = apr_brigade_create(p, req->bucket_alloc);
        if (input_brigade == NULL) {
            input_brigade = apr_brigade_create(p, req->bucket_alloc);
            apr_pool_userdata_setn(input_brigade, "proxy-req-input", NULL, p);
        }
        req->input_brigade = input_brigade;
    
        /* Prefetch (nonlocking) the request body so to increase the chance to get
         * the whole (or enough) body and determine Content-Length vs chunked or
         * spooled. By doing this before connecting or reusing the backend, we want
         * to minimize the delay between this connection is considered alive and
         * the first bytes sent (should the client's link be slow or some input
         * filter retain the data). This is a best effort to prevent the backend
         * from closing (from under us) what it thinks is an idle connection, hence
         * to reduce to the minimum the unavoidable local is_socket_connected() vs
         * remote keepalive race condition.
         */
        if ((status = ap_proxy_http_prefetch(req, uri, locurl)) != OK)
            goto cleanup;
    
        /* We need to reset backend->close now, since ap_proxy_http_prefetch() set
         * it to disable the reuse of the connection *after* this request (no keep-
         * alive), not to close any reusable connection before this request. However
         * assure what is expected later by using a local flag and do the right thing
         * when ap_proxy_connect_backend() below provides the connection to close.
         */
        toclose = backend->close;
        backend->close = 0;
    
        while (retry < 2) {
            if (retry) {
                char *newurl = url;
    
                /* Step One (again): (Re)Determine Who To Connect To */
                if ((status = ap_proxy_determine_connection(p, r, conf, worker,
                                backend, uri, &newurl, proxyname, proxyport,
                                req->server_portstr, sizeof(req->server_portstr))))
                    break;
    
                /* The code assumes locurl is not changed during the loop, or
                 * ap_proxy_http_prefetch() would have to be called every time,
                 * and header_brigade be changed accordingly...
                 */
                AP_DEBUG_ASSERT(strcmp(newurl, locurl) == 0);
            }
    
            /* Step Two: Make the Connection */
            if (ap_proxy_check_connection(scheme, backend, r->server, 1,
                                          PROXY_CHECK_CONN_EMPTY)
                    && ap_proxy_connect_backend(scheme, backend, worker,
                                                r->server)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01114)
                              "HTTP: failed to make connection to backend: %s",
                              backend->hostname);
                status = HTTP_SERVICE_UNAVAILABLE;
                break;
            }
    
            /* Step Three: Create conn_rec */
            if ((status = ap_proxy_connection_create_ex(scheme, backend, r)) != OK)
                break;
            req->origin = backend->connection;
    
            /* Don't recycle the connection if prefetch (above) told not to do so */
            if (toclose) {
                backend->close = 1;
                req->origin->keepalive = AP_CONN_CLOSE;
            }
    
            /* Step Four: Send the Request
             * On the off-chance that we forced a 100-Continue as a
             * kinda HTTP ping test, allow for retries
             */
            status = ap_proxy_http_request(req);
            if (status != OK) {
                if (req->do_100_continue && status == HTTP_SERVICE_UNAVAILABLE) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO(01115)
                                  "HTTP: 100-Continue failed to %pI (%s:%d)",
                                  backend->addr, backend->hostname, backend->port);
                    backend->close = 1;
                    retry++;
                    continue;
                }
                break;
            }
    
            /* Step Five: Receive the Response... Fall thru to cleanup */
            status = ap_proxy_http_process_response(req);
    
            break;
        }
    
        /* Step Six: Clean Up */
    cleanup:
        if (req->backend) {
            if (status != OK)
                req->backend->close = 1;
            ap_proxy_http_cleanup(scheme, r, req->backend);
        }
        return status;
    }
    
    /* post_config hook: */
    static int proxy_http_post_config(apr_pool_t *pconf, apr_pool_t *plog,
            apr_pool_t *ptemp, server_rec *s)
    {
    
        /* proxy_http_post_config() will be called twice during startup.  So, don't
         * set up the static data the 1st time through. */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
    
        ap_proxy_clear_connection_fn =
                APR_RETRIEVE_OPTIONAL_FN(ap_proxy_clear_connection);
        if (!ap_proxy_clear_connection_fn) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02477)
                         "mod_proxy must be loaded for mod_proxy_http");
            return !OK;
        }
    
        return OK;
    }
    
    static void ap_proxy_http_register_hook(apr_pool_t *p)
    {
        ap_hook_post_config(proxy_http_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        proxy_hook_scheme_handler(proxy_http_handler, NULL, NULL, APR_HOOK_FIRST);
        proxy_hook_canon_handler(proxy_http_canon, NULL, NULL, APR_HOOK_FIRST);
        warn_rx = ap_pregcomp(p, "[0-9]{3}[ \t]+[^ \t]+[ \t]+\"[^\"]*\"([ \t]+\"([^\"]+)\")?", 0);
    }
    
    AP_DECLARE_MODULE(proxy_http) = {
        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 */
    };
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/proxy_util.c�������������������������������������������������������������0000664�0001751�0001751�00000645667�15022006156�020062� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_strings.h"
    #include "apr_hash.h"
    #include "apr_atomic.h"
    #include "http_core.h"
    #include "proxy_util.h"
    #include "ajp.h"
    #include "scgi.h"
    
    #include "mpm_common.h" /* for ap_max_mem_free */
    
    #include "mod_http2.h" /* for http2_get_num_workers() */
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>         /* for getpid() */
    #endif
    
    #if APR_HAVE_SYS_UN_H
    #include <sys/un.h>
    #endif
    #if (APR_MAJOR_VERSION < 2)
    #include "apr_support.h"        /* for apr_wait_for_io_or_timeout() */
    #endif
    
    APLOG_USE_MODULE(proxy);
    
    /*
     * Opaque structure containing infos for CONNECT-ing an origin server through a
     * remote (forward) proxy. Saved in the (opaque) proxy_conn_rec::forward pointer
     * field for backend connections kept alive, allowing for reuse when subsequent
     * requests should be routed through the same remote proxy.
     */
    typedef struct {
        const char   *proxy_auth;      /* Proxy authorization */
        const char   *target_host;     /* Target/origin hostname */
        apr_port_t   target_port;      /* Target/origin port */
    } remote_connect_info;
    
    /*
     * Opaque structure containing a refcounted and TTL'ed address.
     */
    typedef struct proxy_address {
        apr_sockaddr_t *addr;       /* Remote address info */
        const char *hostname;       /* Remote host name */
        apr_port_t hostport;        /* Remote host port */
        apr_uint32_t refcount;      /* Number of conns and/or worker using it */
        apr_uint32_t expiry;        /* Expiry timestamp (seconds to proxy_start_time) */
    } proxy_address;
    
    /* Global balancer counter */
    int PROXY_DECLARE_DATA proxy_lb_workers = 0;
    static int lb_workers_limit = 0;
    const apr_strmatch_pattern PROXY_DECLARE_DATA *ap_proxy_strmatch_path;
    const apr_strmatch_pattern PROXY_DECLARE_DATA *ap_proxy_strmatch_domain;
    
    extern apr_global_mutex_t *proxy_mutex;
    
    static const apr_time_t *proxy_start_time; /* epoch for expiring addresses */
    
    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);
    static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worker, server_rec *s);
    static proxy_worker *proxy_balancer_get_best_worker(proxy_balancer *balancer,
                                                        request_rec *r,
                                                        proxy_is_best_callback_fn_t *is_best,
                                                        void *baton);
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, create_req,
                                       (request_rec *r, request_rec *pr), (r, pr),
                                       OK, DECLINED)
    
    PROXY_DECLARE(apr_status_t) ap_proxy_strncpy(char *dst, const char *src,
                                                 apr_size_t dlen)
    {
        char *thenil;
        apr_size_t thelen;
    
        /* special case handling */
        if (!dlen) {
            /* XXX: APR_ENOSPACE would be better */
            return APR_EGENERAL;
        }
        if (!src) {
            *dst = '\0';
            return APR_SUCCESS;
        }
        thenil = apr_cpystrn(dst, src, dlen);
        thelen = thenil - dst;
        if (src[thelen] == '\0') {
            return APR_SUCCESS;
        }
        return APR_EGENERAL;
    }
    
    /* already called in the knowledge that the characters are hex digits */
    PROXY_DECLARE(int) ap_proxy_hex2c(const char *x)
    {
        int i;
    
    #if !APR_CHARSET_EBCDIC
        int 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_ex(apr_pool_t *p, const char *x, int len,
                                              enum enctype t, int flags,
                                              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 */
        int forcedec = flags & PROXY_CANONENC_FORCEDEC;
        int noencslashesenc = flags & PROXY_CANONENC_NOENCODEDSLASHENCODING;
    
    /*
     * 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 || noencslashesenc
                || (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]);
                if (ch != 0 && strchr(reserved, ch)) {  /* keep it encoded */
                    y[j++] = x[i++];
                    y[j++] = x[i++];
                    y[j] = x[i];
                    continue;
                }
                if (noencslashesenc && !forcedec && (proxyreq == PROXYREQ_REVERSE)) {
                    /*
                     * In the reverse proxy case when we only want to keep encoded
                     * slashes untouched revert back to '%' which will cause
                     * '%' to be encoded in the following.
                     */
                    ch = '%';
                }
                else {
                    i += 2;
                }
            }
    /* 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;
    }
    
    /*
     * 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 flags;
    
        flags = forcedec ? PROXY_CANONENC_FORCEDEC : 0;
        return ap_proxy_canonenc_ex(p, x, len, t, flags, proxyreq);
    }
    
    /*
     * 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 separating '/' */
        }
    
        /* 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 int proxyerror_core(request_rec *r, int statuscode, const char *message,
                               apr_status_t rv)
    {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00898)
                      "%s returned by %s", message, r->uri);
    
        apr_table_setn(r->notes, "error-notes",
            apr_pstrcat(r->pool,
                "The proxy server could not handle the request<p>"
                "Reason: <strong>", ap_escape_html(r->pool, message),
                "</strong></p>",
                NULL));
    
        /* Allow "error-notes" string to be printed by ap_send_error_response() */
        apr_table_setn(r->notes, "verbose-error-to", "*");
    
        r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode);
        return statuscode;
    }
    
    PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message)
    {
        return proxyerror_core(r, statuscode, message, 0);
    }
    
    static const char *
         proxy_get_host_of_request(request_rec *r)
    {
        char *url, *user = NULL, *password = NULL, *err, *host = NULL;
        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, APLOGNO(00899) "%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, APLOGNO(00900)
                             "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, APLOGNO(00901)
                         "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, APLOGNO(00902)
                         "         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) {
                /* ap_proxy_is_ipaddr() already confirmed that we have
                 * a valid octet in ip_addr[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, APLOGNO(00903)
                             "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr));
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00904)
                             "%s/", inet_ntoa(This->addr));
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00905)
                             "%s", inet_ntoa(This->mask));
    #endif
                return 1;
            }
    #if DEBUGGING
            else {
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00906)
                             "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr));
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00907)
                             "%s/", inet_ntoa(This->addr));
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00908)
                             "%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, APLOGNO(00909)
                 "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, APLOGNO(00910)
                                 "3)IP-Match: %s[%s] <-> ", host, inet_ntoa(*ip));
                    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00911)
                                 "%s/", inet_ntoa(This->addr));
                    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00912)
                                 "%s", inet_ntoa(This->mask));
    #endif
                    return 1;
                }
    #if DEBUGGING
                else {
                    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00913)
                                 "3)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(*ip));
                    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00914)
                                 "%s/", inet_ntoa(This->addr));
                    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00915)
                                 "%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, APLOGNO(03234)
                         "@@@@ 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;
    }
    
    /* Backwards-compatible interface. */
    PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf,
                                 apr_sockaddr_t *uri_addr)
    {
        return ap_proxy_checkproxyblock2(r, conf, uri_addr->hostname, uri_addr);
    }
    
    #define MAX_IP_STR_LEN (46)
    
    PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf,
                                                 const char *hostname, apr_sockaddr_t *addr)
    {
        int j;
    
        /* 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;
    
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                          "checking remote machine [%s] against [%s]",
                          hostname, npent[j].name);
            if (ap_strstr_c(hostname, npent[j].name) || npent[j].name[0] == '*') {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00916)
                              "connect to remote machine %s blocked: name %s "
                              "matched", hostname, npent[j].name);
                return HTTP_FORBIDDEN;
            }
    
            /* No IP address checks if no IP address was passed in,
             * i.e. the forward address proxy case, where this server does
             * not resolve the hostname.  */
            if (!addr)
                continue;
    
            for (conf_addr = npent[j].addr; conf_addr; conf_addr = conf_addr->next) {
                char caddr[MAX_IP_STR_LEN], uaddr[MAX_IP_STR_LEN];
                apr_sockaddr_t *uri_addr;
    
                if (apr_sockaddr_ip_getbuf(caddr, sizeof caddr, conf_addr))
                    continue;
    
                for (uri_addr = addr; uri_addr; uri_addr = uri_addr->next) {
                    if (apr_sockaddr_ip_getbuf(uaddr, sizeof uaddr, uri_addr))
                        continue;
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                                  "ProxyBlock comparing %s and %s", caddr, uaddr);
                    if (!strcmp(caddr, uaddr)) {
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00917)
                                      "connect to remote machine %s blocked: "
                                      "IP %s matched", hostname, caddr);
                        return HTTP_FORBIDDEN;
                    }
                }
            }
        }
    
        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;
    }
    
    PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
                                  proxy_dir_conf *conf, const char *url)
    {
        proxy_req_conf *rconf;
        struct proxy_alias *ent;
        int i, l1, l1_orig, l2;
        char *u;
    
        /*
         * XXX FIXME: Make sure this handled the ambiguous case of the :<PORT>
         * after the hostname
         * XXX FIXME: Ensure the /uri component is a case sensitive match
         */
        if (r->proxyreq != PROXYREQ_REVERSE) {
            return url;
        }
    
        l1_orig = strlen(url);
        if (conf->interpolate_env == 1) {
            rconf = ap_get_module_config(r->request_config, &proxy_module);
            ent = (struct proxy_alias *)rconf->raliases->elts;
        }
        else {
            ent = (struct proxy_alias *)conf->raliases->elts;
        }
        for (i = 0; i < conf->raliases->nelts; i++) {
            proxy_server_conf *sconf = (proxy_server_conf *)
                ap_get_module_config(r->server->module_config, &proxy_module);
            proxy_balancer *balancer;
            const char *real = ent[i].real;
    
            /* Restore the url length, if it had been changed by the code below */
            l1 = l1_orig;
    
            /*
             * First check if mapping against a balancer and see
             * if we have such a entity. If so, then we need to
             * find the particulars of the actual worker which may
             * or may not be the right one... basically, we need
             * to find which member actually handled this request.
             */
            if (ap_proxy_valid_balancer_name((char *)real, 0) &&
                (balancer = ap_proxy_get_balancer(r->pool, sconf, real, 1))) {
                int n, l3 = 0;
                proxy_worker **worker = (proxy_worker **)balancer->workers->elts;
                const char *urlpart = ap_strchr_c(real + sizeof(BALANCER_PREFIX) - 1, '/');
                if (urlpart) {
                    if (!urlpart[1])
                        urlpart = NULL;
                    else
                        l3 = strlen(urlpart);
                }
                /* The balancer comparison is a bit trickier.  Given the context
                 *   BalancerMember balancer://alias http://example.com/foo
                 *   ProxyPassReverse /bash balancer://alias/bar
                 * translate url http://example.com/foo/bar/that to /bash/that
                 */
                for (n = 0; n < balancer->workers->nelts; n++) {
                    l2 = strlen((*worker)->s->name_ex);
                    if (urlpart) {
                        /* urlpart (l3) assuredly starts with its own '/' */
                        if ((*worker)->s->name_ex[l2 - 1] == '/')
                            --l2;
                        if (l1 >= l2 + l3
                                && strncasecmp((*worker)->s->name_ex, url, l2) == 0
                                && strncmp(urlpart, url + l2, l3) == 0) {
                            u = apr_pstrcat(r->pool, ent[i].fake, &url[l2 + l3],
                                            NULL);
                            return ap_is_url(u) ? u : ap_construct_url(r->pool, u, r);
                        }
                    }
                    else if (l1 >= l2 && strncasecmp((*worker)->s->name_ex, url, l2) == 0) {
                        /* edge case where fake is just "/"... avoid double slash */
                        if ((ent[i].fake[0] == '/') && (ent[i].fake[1] == 0) && (url[l2] == '/')) {
                            u = apr_pstrdup(r->pool, &url[l2]);
                        } else {
                            u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
                        }
                        return ap_is_url(u) ? u : ap_construct_url(r->pool, u, r);
                    }
                    worker++;
                }
            }
            else {
                const char *part = url;
                l2 = strlen(real);
                if (real[0] == '/') {
                    part = ap_strstr_c(url, "://");
                    if (part) {
                        part = ap_strchr_c(part+3, '/');
                        if (part) {
                            l1 = strlen(part);
                        }
                        else {
                            part = url;
                        }
                    }
                    else {
                        part = url;
                    }
                }
                if (l2 > 0 && l1 >= l2 && strncasecmp(real, part, l2) == 0) {
                    u = apr_pstrcat(r->pool, ent[i].fake, &part[l2], NULL);
                    return ap_is_url(u) ? u : 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_dir_conf *conf, const char *str)
    {
        proxy_req_conf *rconf = ap_get_module_config(r->request_config,
                                                     &proxy_module);
        struct proxy_alias *ent;
        apr_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;
        apr_size_t l1, l2, poffs = 0, doffs = 0;
        int i;
        int ddiff = 0;
        int pdiff = 0;
        char *tmpstr, *tmpstr_orig, *token, *last, *ret;
    
        if (r->proxyreq != PROXYREQ_REVERSE) {
            return str;
        }
    
       /*
        * Find the match and replacement, but save replacing until we've done
        * both path and domain so we know the new strlen
        */
        tmpstr_orig = tmpstr = apr_pstrdup(r->pool, str);
        while ((token = apr_strtok(tmpstr, ";", &last))) {
            /* skip leading spaces */
            while (apr_isspace(*token)) {
                ++token;
            }
    
            if (ap_cstr_casecmpn("path=", token, 5) == 0) {
                pathp = token + 5;
                poffs = pathp - tmpstr_orig;
                l1 = strlen(pathp);
                pathe = str + poffs + l1;
                if (conf->interpolate_env == 1) {
                    ent = (struct proxy_alias *)rconf->cookie_paths->elts;
                }
                else {
                    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;
                    }
                }
            }
            else if (ap_cstr_casecmpn("domain=", token, 7) == 0) {
                domainp = token + 7;
                doffs = domainp - tmpstr_orig;
                l1 = strlen(domainp);
                domaine = str + doffs + l1;
                if (conf->interpolate_env == 1) {
                    ent = (struct proxy_alias *)rconf->cookie_domains->elts;
                }
                else {
                    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;
                    }
                }
            }
    
            /* Iterate the remaining tokens using apr_strtok(NULL, ...) */
            tmpstr = NULL;
        }
    
        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, str + doffs - 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, str + poffs - 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 + 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;
    }
    
    /*
     * BALANCER related...
     */
    
    /*
     * verifies that the balancer name conforms to standards.
     */
    PROXY_DECLARE(int) ap_proxy_valid_balancer_name(char *name, int i)
    {
        if (!i)
            i = sizeof(BALANCER_PREFIX)-1;
        return (!ap_cstr_casecmpn(name, BALANCER_PREFIX, i));
    }
    
    
    PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
                                                          proxy_server_conf *conf,
                                                          const char *url,
                                                          int care)
    {
        proxy_balancer *balancer;
        char *c, *uri = apr_pstrdup(p, url);
        int i;
        proxy_hashes hash;
    
        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';
        }
        ap_str_tolower(uri);
        hash.def = ap_proxy_hashfunc(uri, PROXY_HASHFUNC_DEFAULT);
        hash.fnv = ap_proxy_hashfunc(uri, PROXY_HASHFUNC_FNV);
        balancer = (proxy_balancer *)conf->balancers->elts;
        for (i = 0; i < conf->balancers->nelts; i++) {
            if (balancer->hash.def == hash.def && balancer->hash.fnv == hash.fnv) {
                if (!care || !balancer->s->inactive) {
                    return balancer;
                }
            }
            balancer++;
        }
        return NULL;
    }
    
    
    PROXY_DECLARE(char *) ap_proxy_update_balancer(apr_pool_t *p,
                                                    proxy_balancer *balancer,
                                                    const char *url)
    {
        apr_uri_t puri;
        if (!url) {
            return NULL;
        }
        if (apr_uri_parse(p, url, &puri) != APR_SUCCESS) {
            return apr_psprintf(p, "unable to parse: %s", url);
        }
        if (puri.path && PROXY_STRNCPY(balancer->s->vpath, puri.path) != APR_SUCCESS) {
            return apr_psprintf(p, "balancer %s front-end virtual-path (%s) too long",
                                balancer->s->name, puri.path);
        }
        if (puri.hostname && PROXY_STRNCPY(balancer->s->vhost, puri.hostname) != APR_SUCCESS) {
            return apr_psprintf(p, "balancer %s front-end vhost name (%s) too long",
                                balancer->s->name, puri.hostname);
        }
        return NULL;
    }
    
    #define PROXY_UNSET_NONCE '\n'
    
    PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
                                                   proxy_balancer **balancer,
                                                   proxy_server_conf *conf,
                                                   const char *url,
                                                   const char *alias,
                                                   int do_malloc)
    {
        proxy_balancer_method *lbmethod;
        proxy_balancer_shared *bshared;
        char *c, *q, *uri = apr_pstrdup(p, url);
        const char *sname;
    
        /* We should never get here without a valid BALANCER_PREFIX... */
    
        c = strchr(uri, ':');
        if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0')
            return apr_psprintf(p, "Bad syntax for a balancer name (%s)", uri);
        /* 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));
    
        /*
         * NOTE: The default method is byrequests - if it doesn't
         * exist, that's OK at this time. We check when we share and sync
         */
        lbmethod = ap_lookup_provider(PROXY_LBMETHOD, "byrequests", "0");
        (*balancer)->lbmethod = lbmethod;
        
        (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker *));
    #if APR_HAS_THREADS
        (*balancer)->gmutex = NULL;
        (*balancer)->tmutex = NULL;
    #endif
    
        if (do_malloc)
            bshared = ap_malloc(sizeof(proxy_balancer_shared));
        else
            bshared = apr_palloc(p, sizeof(proxy_balancer_shared));
    
        memset(bshared, 0, sizeof(proxy_balancer_shared));
    
        bshared->was_malloced = (do_malloc != 0);
        PROXY_STRNCPY(bshared->lbpname, "byrequests");
        if (PROXY_STRNCPY(bshared->name, uri) != APR_SUCCESS) {
            if (do_malloc) free(bshared);
            return apr_psprintf(p, "balancer name (%s) too long", uri);
        }
        (*balancer)->lbmethod_set = 1;
    
        /*
         * We do the below for verification. The real sname will be
         * done post_config
         */
        ap_pstr2_alnum(p, bshared->name + sizeof(BALANCER_PREFIX) - 1,
                       &sname);
        sname = apr_pstrcat(p, conf->id, "_", sname, NULL);
        if (PROXY_STRNCPY(bshared->sname, sname) != APR_SUCCESS) {
            if (do_malloc) free(bshared);
            return apr_psprintf(p, "balancer safe-name (%s) too long", sname);
        }
        bshared->hash.def = ap_proxy_hashfunc(bshared->name, PROXY_HASHFUNC_DEFAULT);
        bshared->hash.fnv = ap_proxy_hashfunc(bshared->name, PROXY_HASHFUNC_FNV);
        (*balancer)->hash = bshared->hash;
    
        bshared->forcerecovery = 1;
        bshared->sticky_separator = '.';
        *bshared->nonce = PROXY_UNSET_NONCE;  /* impossible valid input */
    
        (*balancer)->s = bshared;
        (*balancer)->sconf = conf;
    
        return ap_proxy_update_balancer(p, *balancer, alias);
    }
    
    /*
     * Create an already defined balancer and free up memory.
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
                                                        proxy_balancer_shared *shm,
                                                        int i)
    {
        apr_status_t rv = APR_SUCCESS;
        proxy_balancer_method *lbmethod;
        char *action = "copying";
        if (!shm || !balancer->s)
            return APR_EINVAL;
    
        if ((balancer->s->hash.def != shm->hash.def) ||
            (balancer->s->hash.fnv != shm->hash.fnv)) {
            memcpy(shm, balancer->s, sizeof(proxy_balancer_shared));
            if (balancer->s->was_malloced)
                free(balancer->s);
        } else {
            action = "re-using";
        }
        balancer->s = shm;
        balancer->s->index = i;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02337)
                     "%s shm[%d] (0x%pp) for %s", action, i, (void *)shm,
                     balancer->s->name);
        /* the below should always succeed */
        lbmethod = ap_lookup_provider(PROXY_LBMETHOD, balancer->s->lbpname, "0");
        if (lbmethod) {
            balancer->lbmethod = lbmethod;
            balancer->lbmethod_set = 1;
        } else {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(02432)
                         "Cannot find LB Method: %s", balancer->s->lbpname);
            return APR_EINVAL;
        }
        if (*balancer->s->nonce == PROXY_UNSET_NONCE) {
            char nonce[APR_UUID_FORMATTED_LENGTH + 1];
            apr_uuid_t uuid;
    
            /* Generate a pseudo-UUID from the PRNG to use as a nonce for
             * the lifetime of the process. uuid.data is a char array so
             * this is an adequate substitute for apr_uuid_get(). */
            ap_random_insecure_bytes(uuid.data, sizeof uuid.data);
            apr_uuid_format(nonce, &uuid);
            rv = PROXY_STRNCPY(balancer->s->nonce, nonce);
        }
        return rv;
    }
    
    PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer, server_rec *s, apr_pool_t *p)
    {
    #if APR_HAS_THREADS
        apr_status_t rv = APR_SUCCESS;
    #endif
        ap_slotmem_provider_t *storage = balancer->storage;
        apr_size_t size;
        unsigned int num;
    
        if (!storage) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(00918)
                         "no provider for %s", balancer->s->name);
            return APR_EGENERAL;
        }
        /*
         * for each balancer we need to init the global
         * mutex and then attach to the shared worker shm
         */
        if (!balancer->gmutex) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(00919)
                         "no mutex %s", balancer->s->name);
            return APR_EGENERAL;
        }
    
        /* Re-open the mutex for the child. */
        rv = apr_global_mutex_child_init(&(balancer->gmutex),
                                         apr_global_mutex_lockfile(balancer->gmutex),
                                         p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00920)
                         "Failed to reopen mutex %s in child",
                         balancer->s->name);
            return rv;
        }
    
        /* now attach */
        storage->attach(&(balancer->wslot), balancer->s->sname, &size, &num, p);
        if (!balancer->wslot) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(00921) "slotmem_attach failed");
            return APR_EGENERAL;
        }
    
    #if APR_HAS_THREADS
        if (balancer->tmutex == NULL) {
            rv = apr_thread_mutex_create(&(balancer->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(00922)
                             "can not create balancer thread mutex");
                return rv;
            }
        }
    #endif
        return APR_SUCCESS;
    }
    
    static proxy_worker *proxy_balancer_get_best_worker(proxy_balancer *balancer,
                                                        request_rec *r,
                                                        proxy_is_best_callback_fn_t *is_best,
                                                        void *baton)
    {
        int i = 0;
        int cur_lbset = 0;
        int max_lbset = 0;
        int unusable_workers = 0;
        apr_pool_t *tpool = NULL;
        apr_array_header_t *spares = NULL;
        apr_array_header_t *standbys = NULL;
        proxy_worker *worker = NULL;
        proxy_worker *best_worker = NULL;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(10122)
                     "proxy: Entering %s for BALANCER (%s)",
                     balancer->lbmethod->name, balancer->s->name);
    
        apr_pool_create(&tpool, r->pool);
        apr_pool_tag(tpool, "proxy_lb_best");
    
        spares = apr_array_make(tpool, 1, sizeof(proxy_worker*));
        standbys = apr_array_make(tpool, 1, sizeof(proxy_worker*));
    
        /* Process lbsets in order, only replacing unusable workers in a given lbset
         * with available spares from the same lbset. Hot standbys will be used as a
         * last resort when all other workers and spares are unavailable.
         */
        for (cur_lbset = 0; !best_worker && (cur_lbset <= max_lbset); cur_lbset++) {
            unusable_workers = 0;
            apr_array_clear(spares);
            apr_array_clear(standbys);
    
            for (i = 0; i < balancer->workers->nelts; i++) {
                worker = APR_ARRAY_IDX(balancer->workers, i, proxy_worker *);
    
                if (worker->s->lbset > max_lbset) {
                    max_lbset = worker->s->lbset;
                }
    
                if (worker->s->lbset != cur_lbset) {
                    continue;
                }
    
                /* A draining worker that is neither a spare nor a standby should be
                 * considered unusable to be replaced by spares.
                 */
                if (PROXY_WORKER_IS_DRAINING(worker)) {
                    if (!PROXY_WORKER_IS_SPARE(worker) && !PROXY_WORKER_IS_STANDBY(worker)) {
                        unusable_workers++;
                    }
    
                    continue;
                }
    
                /* 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);
                }
    
                if (PROXY_WORKER_IS_SPARE(worker)) {
                    if (PROXY_WORKER_IS_USABLE(worker)) {
                        APR_ARRAY_PUSH(spares, proxy_worker *) = worker;
                    }
                }
                else if (PROXY_WORKER_IS_STANDBY(worker)) {
                    if (PROXY_WORKER_IS_USABLE(worker)) {
                        APR_ARRAY_PUSH(standbys, proxy_worker *) = worker;
                    }
                }
                else if (PROXY_WORKER_IS_USABLE(worker)) {
                  if (is_best(worker, best_worker, baton)) {
                    best_worker = worker;
                  }
                }
                else {
                    unusable_workers++;
                }
            }
    
            /* Check if any spares are best. */
            for (i = 0; (i < spares->nelts) && (i < unusable_workers); i++) {
              worker = APR_ARRAY_IDX(spares, i, proxy_worker *);
    
              if (is_best(worker, best_worker, baton)) {
                best_worker = worker;
              }
            }
    
            /* If no workers are available, use the standbys. */
            if (!best_worker) {
                for (i = 0; i < standbys->nelts; i++) {
                  worker = APR_ARRAY_IDX(standbys, i, proxy_worker *);
    
                  if (is_best(worker, best_worker, baton)) {
                    best_worker = worker;
                  }
                }
            }
        }
    
        apr_pool_destroy(tpool);
    
        if (best_worker) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(10123)
                         "proxy: %s selected worker \"%s\" : busy %" APR_SIZE_T_FMT " : lbstatus %d",
                         balancer->lbmethod->name, best_worker->s->name_ex,
                         best_worker->s->busy, best_worker->s->lbstatus);
        }
    
        return best_worker;
    }
    
    PROXY_DECLARE(proxy_worker *) ap_proxy_balancer_get_best_worker(proxy_balancer *balancer,
                                                                    request_rec *r,
                                                                    proxy_is_best_callback_fn_t *is_best,
                                                                    void *baton)
    {
        return proxy_balancer_get_best_worker(balancer, r, is_best, baton);
    }
    
    /*
     * CONNECTION related...
     */
    
    static void socket_cleanup(proxy_conn_rec *conn)
    {
        conn->sock = NULL;
        conn->tmp_bb = NULL;
        conn->connection = NULL;
        conn->ssl_hostname = NULL;
        apr_pool_clear(conn->scpool);
        conn->close = 0;
    }
    
    static void conn_cleanup(proxy_conn_rec *conn)
    {
        socket_cleanup(conn);
        conn->address = NULL;
        conn->addr = NULL;
        conn->hostname = NULL;
        conn->port = 0;
        conn->uds_path = NULL;
        if (conn->uds_pool) {
            apr_pool_clear(conn->uds_pool);
        }
    }
    
    static apr_status_t conn_pool_cleanup(void *theworker)
    {
        /* Signal that the child is exiting */
        ((proxy_worker *)theworker)->cp = NULL;
        return APR_SUCCESS;
    }
    
    static apr_pool_t *make_conn_subpool(apr_pool_t *p, const char *tag,
                                         server_rec *s)
    {
        apr_pool_t *sp = NULL;
        apr_allocator_t *alloc;
        apr_thread_mutex_t *mutex;
        apr_status_t rv;
    
        rv = apr_allocator_create(&alloc);
        if (rv == APR_SUCCESS) {
            rv = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, p);
            if (rv == APR_SUCCESS) {
                apr_allocator_mutex_set(alloc, mutex);
                apr_allocator_max_free_set(alloc, ap_max_mem_free);
                rv = apr_pool_create_ex(&sp, p, NULL, alloc);
            }
            else {
                apr_allocator_destroy(alloc);
            }
        }
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(10474)
                         "failed to create %s pool", tag);
            ap_abort_on_oom();
            return NULL; /* not reached */
        }
        apr_allocator_owner_set(alloc, sp);
        apr_pool_tag(sp, tag);
    
        return sp;
    }
    
    static void init_conn_pool(apr_pool_t *p, proxy_worker *worker, server_rec *s)
    {
        proxy_conn_pool *cp;
    
        /*
         * 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));
        worker->cp = cp;
    
        /*
         * We need a first pool (cp->pool) to maintain the connections attached to
         * the worker and a second one (cp->dns_pool) to maintain the DNS addresses
         * in use (TTL'ed, refcounted). New connections are created as/on a subpool
         * of cp->pool and new addresses as/on a subpool of cp->dns_pool, such that
         * both leaks (the subpools can be destroyed when the connections and/or
         * addresses are over) and race conditions (the creation/destruction of
         * subpools is protected by the parent pool's mutex) can be avoided.
         *
         * cp->dns_pool is created before cp->pool because when a connection on the
         * latter is destroyed it might destroy an address on the former, so when
         * the base pools are destroyed (e.g. child exit) we thusly make sure that
         * cp->dns_pool and its subpools are still alive when cp->pool gets killed.
         *
         * Both cp->dns_pool and cp->pool have their own allocator/mutex too since
         * acquiring connections and addresses don't need to contend.
         */
        cp->dns_pool = make_conn_subpool(p, "proxy_worker_dns", s);
        cp->pool = make_conn_subpool(p, "proxy_worker_cp", s);
    
        /* When p is cleaning up the child is exiting, signal that to e.g. avoid
         * destroying the subpools explicitely in connection_destructor() when
         * they have been destroyed already by the reslist cleanup.
         */
        apr_pool_pre_cleanup_register(p, worker, conn_pool_cleanup);
    }
    
    PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn)
    {
        proxy_worker *worker = conn->worker;
    
        return !(conn->close || worker->s->disablereuse);
    }
    
    static proxy_conn_rec *connection_make(apr_pool_t *p, proxy_worker *worker)
    {
        proxy_conn_rec *conn;
    
        conn = apr_pcalloc(p, sizeof(proxy_conn_rec));
        conn->pool = p;
        conn->worker = worker;
    
        /*
         * Create another subpool that manages the data for the
         * socket and the connection member of the proxy_conn_rec struct as we
         * destroy this data more frequently than other data in the proxy_conn_rec
         * struct like hostname and addr (at least in the case where we have
         * keepalive connections that timed out).
         *
         * XXX: this is really needed only when worker->s->is_address_reusable,
         *      otherwise conn->scpool = conn->pool would be fine. For now we
         *      can't change it since it's (kind of) part of the API.
         */
        apr_pool_create(&conn->scpool, p);
        apr_pool_tag(conn->scpool, "proxy_conn_scpool");
    
        return conn;
    }
    
    static void connection_cleanup(void *theconn)
    {
        proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
        proxy_worker *worker = conn->worker;
    
        /* Sanity check: Did we already return the pooled connection? */
        if (conn->inreslist) {
            ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool, APLOGNO(00923)
                          "Pooled connection 0x%pp for worker %s has been"
                          " already returned to the connection pool.", conn,
                          ap_proxy_worker_name(conn->pool, worker));
            return;
        }
    
        if (conn->r) {
            apr_pool_destroy(conn->r->pool);
            conn->r = NULL;
        }
    
        /* determine if the connection should be cleared, closed or reused */
        if (!worker->s->is_address_reusable) {
            apr_pool_t *p = conn->pool;
            apr_pool_clear(p);
            conn = connection_make(p, worker);
        }
        else if (!conn->sock
                 || (conn->connection
                     && conn->connection->keepalive == AP_CONN_CLOSE)
                 || !ap_proxy_connection_reusable(conn)) {
            socket_cleanup(conn);
        }
        else if (conn->is_ssl) {
            /* The current ssl section/dir config of the conn is not necessarily
             * the one it will be reused for, so while the conn is in the reslist
             * reset its ssl config to the worker's, until a new user sets its own
             * ssl config eventually in proxy_connection_create() and so on.
             */
            ap_proxy_ssl_engine(conn->connection, worker->section_config, 1);
        }
    
        if (worker->s->hmax && worker->cp->res) {
            conn->inreslist = 1;
            apr_reslist_release(worker->cp->res, (void *)conn);
        }
        else {
            worker->cp->conn = conn;
        }
    }
    
    /* DEPRECATED */
    PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn,
                                                                request_rec *r)
    {
        apr_status_t rv;
    
        /*
         * If we have an existing SSL connection it might be possible that the
         * server sent some SSL message we have not read so far (e.g. an SSL
         * shutdown message if the server closed the keepalive connection while
         * the connection was held unused in our pool).
         * So ensure that if present (=> APR_NONBLOCK_READ) it is read and
         * processed. We don't expect any data to be in the returned brigade.
         */
        if (conn->sock && conn->connection) {
            rv = ap_get_brigade(conn->connection->input_filters, conn->tmp_bb,
                                AP_MODE_READBYTES, APR_NONBLOCK_READ,
                                HUGE_STRING_LEN);
            if (!APR_BRIGADE_EMPTY(conn->tmp_bb)) {
                apr_off_t len;
    
                rv = apr_brigade_length(conn->tmp_bb, 0, &len);
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, rv, r,
                              "SSL cleanup brigade contained %"
                              APR_OFF_T_FMT " bytes of data.", len);
                apr_brigade_cleanup(conn->tmp_bb);
            }
            if ((rv != APR_SUCCESS) && !APR_STATUS_IS_EAGAIN(rv)) {
                socket_cleanup(conn);
            }
        }
        return APR_SUCCESS;
    }
    
    /* reslist constructor */
    static apr_status_t connection_constructor(void **resource, void *params,
                                               apr_pool_t *pool)
    {
        apr_pool_t *p;
        proxy_conn_rec *conn;
        proxy_worker *worker = (proxy_worker *)params;
    
        /*
         * Create a subpool for each connection
         * This keeps the memory consumption constant
         * when it's recycled or destroyed.
         */
        apr_pool_create(&p, pool);
        apr_pool_tag(p, "proxy_conn_pool");
        conn = connection_make(p, worker);
        conn->inreslist = 1;
    
        *resource = conn;
        return APR_SUCCESS;
    }
    
    /* reslist destructor */
    static apr_status_t connection_destructor(void *resource, void *params,
                                              apr_pool_t *pool)
    {
        proxy_worker *worker = params;
    
        /* Destroy the pool only if not called from reslist_destroy */
        if (worker->cp) {
            proxy_conn_rec *conn = resource;
            apr_pool_destroy(conn->pool);
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * WORKER related...
     */
    
    PROXY_DECLARE(char *) ap_proxy_worker_name(apr_pool_t *p,
                                               proxy_worker *worker)
    {
        if (!(*worker->s->uds_path) || !p) {
            /* just in case */
            return worker->s->name_ex;
        }
        return apr_pstrcat(p, "unix:", worker->s->uds_path, "|", worker->s->name_ex, NULL);
    }
    
    PROXY_DECLARE(int) ap_proxy_worker_can_upgrade(apr_pool_t *p,
                                                   const proxy_worker *worker,
                                                   const char *upgrade,
                                                   const char *dflt)
    {
        /* Find in worker->s->upgrade list (if any) */
        const char *worker_upgrade = worker->s->upgrade;
        if (*worker_upgrade) {
            return (strcmp(worker_upgrade, "*") == 0
                    || ap_cstr_casecmp(worker_upgrade, upgrade) == 0
                    || ap_find_token(p, worker_upgrade, upgrade));
        }
    
        /* Compare to the provided default (if any) */
        return (dflt && ap_cstr_casecmp(dflt, upgrade) == 0);
    }
    
    /*
     * Taken from ap_strcmp_match() :
     * Match = 0, NoMatch = 1, Abort = -1, Inval = -2
     * Based loosely on sections of wildmat.c by Rich Salz
     * Hmmm... shouldn't this really go component by component?
     *
     * Adds handling of the "\<any>" => "<any>" unescaping.
     */
    static int ap_proxy_strcmp_ematch(const char *str, const char *expected)
    {
        apr_size_t x, y;
    
        for (x = 0, y = 0; expected[y]; ++y, ++x) {
            if (expected[y] == '$' && apr_isdigit(expected[y + 1])) {
                do {
                    y += 2;
                } while (expected[y] == '$' && apr_isdigit(expected[y + 1]));
                if (!expected[y])
                    return 0;
                while (str[x]) {
                    int ret;
                    if ((ret = ap_proxy_strcmp_ematch(&str[x++], &expected[y])) != 1)
                        return ret;
                }
                return -1;
            }
            else if (!str[x]) {
                return -1;
            }
            else if (expected[y] == '\\' && !expected[++y]) {
                /* NUL is an invalid char! */
                return -2;
            }
            if (str[x] != expected[y])
                return 1;
        }
        /* We got all the way through the worker path without a difference */
        return 0;
    }
    
    static int worker_matches(proxy_worker *worker,
                              const char *url, apr_size_t url_len,
                              apr_size_t min_match, apr_size_t *max_match,
                              unsigned int mask)
    {
        apr_size_t name_len = strlen(worker->s->name_ex);
        if (name_len <= url_len
            && name_len > *max_match
            /* min_match is the length of the scheme://host part only of url,
             * so it's used as a fast path to avoid the match when url is too
             * small, but it's irrelevant when the worker host contains globs
             * (i.e. ->is_host_matchable).
             */
            && (worker->s->is_name_matchable
                ? ((mask & AP_PROXY_WORKER_IS_MATCH)
                   && (worker->s->is_host_matchable || name_len >= min_match)
                   && !ap_proxy_strcmp_ematch(url, worker->s->name_ex))
                : ((mask & AP_PROXY_WORKER_IS_PREFIX)
                   && (name_len >= min_match)
                   && !strncmp(url, worker->s->name_ex, name_len)))) {
            *max_match = name_len;
            return 1;
        }
        return 0;
    }
    
    PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p,
                                                         proxy_balancer *balancer,
                                                         proxy_server_conf *conf,
                                                         const char *url,
                                                         unsigned int mask)
    {
        proxy_worker *max_worker = NULL;
        apr_size_t min_match, max_match = 0;
        apr_size_t url_len;
        const char *c;
        char *url_copy;
        int i;
    
        if (!url) {
            return NULL;
        }
    
        if (!(mask & AP_PROXY_WORKER_NO_UDS)) {
            url = ap_proxy_de_socketfy(p, url);
            if (!url) {
                return NULL;
            }
        }
    
        c = ap_strchr_c(url, ':');
        if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') {
            return NULL;
        }
    
        url_len = strlen(url);
        url_copy = apr_pstrmemdup(p, url, url_len);
    
        /* Default to lookup for both _PREFIX and _MATCH workers */
        if (!(mask & (AP_PROXY_WORKER_IS_PREFIX | AP_PROXY_WORKER_IS_MATCH))) {
            mask |= AP_PROXY_WORKER_IS_PREFIX | AP_PROXY_WORKER_IS_MATCH;
        }
    
        /*
         * We need to find the start of the path and
         * therefore we know the length of the scheme://hostname/
         * part to we can force-lowercase everything up to
         * the start of the path.
         */
        c = ap_strchr_c(c+3, '/');
        if (c) {
            char *pathstart;
            pathstart = url_copy + (c - url);
            *pathstart = '\0';
            ap_str_tolower(url_copy);
            min_match = strlen(url_copy);
            *pathstart = '/';
        }
        else {
            ap_str_tolower(url_copy);
            min_match = strlen(url_copy);
        }
    
        /*
         * Do a "longest match" on the worker name to find the worker that
         * fits best to the URL, but keep in mind that we must have at least
         * a minimum matching of length min_match such that
         * scheme://hostname[:port] matches between worker and url.
         */
        if (balancer) {
            proxy_worker **worker = (proxy_worker **)balancer->workers->elts;
            for (i = 0; i < balancer->workers->nelts; i++, worker++) {
                if (worker_matches(*worker, url_copy, url_len,
                                   min_match, &max_match, mask)) {
                    max_worker = *worker;
                }
            }
        }
        else {
            proxy_worker *worker = (proxy_worker *)conf->workers->elts;
            for (i = 0; i < conf->workers->nelts; i++, worker++) {
                if (worker_matches(worker, url_copy, url_len,
                                   min_match, &max_match, mask)) {
                    max_worker = worker;
                }
            }
        }
    
        return max_worker;
    }
    
    PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
                                                      proxy_balancer *balancer,
                                                      proxy_server_conf *conf,
                                                      const char *url)
    {
        return ap_proxy_get_worker_ex(p, balancer, conf, url, 0);
    }
    
    /*
     * To create a worker from scratch first we define the
     * specifics of the worker; this is all local data.
     * We then allocate space for it if data needs to be
     * shared. This allows for dynamic addition during
     * config and runtime.
     */
    PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p,
                                                 proxy_worker **worker,
                                                 proxy_balancer *balancer,
                                                 proxy_server_conf *conf,
                                                 const char *url,
                                                 unsigned int mask)
    {
        apr_status_t rv;
        proxy_worker_shared *wshared;
        const char *ptr = NULL, *sockpath = NULL, *pdollars = NULL;
        apr_port_t port_of_scheme;
        int address_not_reusable = 0;
        apr_uri_t uri;
    
        /*
         * Look to see if we are using UDS:
         * require format: unix:/path/foo/bar.sock|http://ignored/path2/
         * This results in talking http to the socket at /path/foo/bar.sock
         */
        if (!ap_cstr_casecmpn(url, "unix:", 5)
                && (ptr = ap_strchr_c(url + 5, '|'))) {
            rv = apr_uri_parse(p, apr_pstrmemdup(p, url, ptr - url), &uri);
            if (rv == APR_SUCCESS) {
                sockpath = ap_runtime_dir_relative(p, uri.path);
                ptr++;    /* so we get the scheme for the uds */
            }
            else {
                ptr = url;
            }
        }
        else {
            ptr = url;
        }
    
        if (mask & AP_PROXY_WORKER_IS_MATCH) {
            /* apr_uri_parse() will accept the '$' sign anywhere in the URL but
             * in the :port part, and we don't want scheme://host:port$1$2/path
             * to fail (e.g. "ProxyPassMatch ^/(a|b)(/.*)? http://host:port$2").
             * So we trim all the $n from the :port and prepend them in uri.path
             * afterward for apr_uri_unparse() to restore the original URL below.
             * If a dollar substitution is found in the hostname[:port] part of
             * the URL, reusing address and connections in the same worker is not
             * possible (the current implementation of active connections cache
             * handles/assumes a single origin server:port per worker only), so
             * we set address_not_reusable here during parsing to take that into
             * account in the worker settings below.
             */
    #define IS_REF(x) (x[0] == '$' && apr_isdigit(x[1]))
            const char *pos = ap_strstr_c(ptr, "://");
            if (pos) {
                pos += 3;
                while (*pos && *pos != ':' && *pos != '/') {
                    if (*pos == '$') {
                        address_not_reusable = 1;
                    }
                    pos++;
                }
                if (*pos == ':') {
                    pos++;
                    while (*pos && !IS_REF(pos) && *pos != '/') {
                        pos++;
                    }
                    if (IS_REF(pos)) {
                        struct iovec vec[2];
                        const char *path = pos + 2;
                        while (*path && *path != '/') {
                            path++;
                        }
                        pdollars = apr_pstrmemdup(p, pos, path - pos);
                        vec[0].iov_base = (void *)ptr;
                        vec[0].iov_len = pos - ptr;
                        vec[1].iov_base = (void *)path;
                        vec[1].iov_len = strlen(path);
                        ptr = apr_pstrcatv(p, vec, 2, NULL);
                        address_not_reusable = 1;
                    }
                }
            }
    #undef IS_REF
        }
    
        /* Normalize the url (worker name) */
        rv = apr_uri_parse(p, ptr, &uri);
        if (rv != APR_SUCCESS) {
            return apr_pstrcat(p, "Unable to parse URL: ", url, NULL);
        }
        if (!uri.scheme) {
            return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
        }
        if (!uri.hostname || !*uri.hostname) {
            if (sockpath) {
                /* allow for unix:/path|http: */
                uri.hostname = "localhost";
            }
            else {
                return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
            }
        }
        else {
            ap_str_tolower(uri.hostname);
        }
        ap_str_tolower(uri.scheme);
        port_of_scheme = ap_proxy_port_of_scheme(uri.scheme);
        if (uri.port && uri.port == port_of_scheme) {
            uri.port = 0;
        }
        if (pdollars) {
            /* Restore/prepend pdollars into the path. */
            uri.path = apr_pstrcat(p, pdollars, uri.path, NULL);
        }
        ptr = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD);
    
        /*
         * Workers can be associated w/ balancers or on their
         * own; ie: the generic reverse-proxy or a worker
         * in a simple ProxyPass statement. eg:
         *
         *      ProxyPass / http://www.example.com
         *
         * in which case the worker goes in the conf slot.
         */
        if (balancer) {
            proxy_worker **runtime;
            /* recall that we get a ptr to the ptr here */
            runtime = apr_array_push(balancer->workers);
            *worker = *runtime = apr_palloc(p, sizeof(proxy_worker));   /* right to left baby */
            /* we've updated the list of workers associated with
             * this balancer *locally* */
            balancer->wupdated = apr_time_now();
        } else if (conf) {
            *worker = apr_array_push(conf->workers);
        } else {
            /* we need to allocate space here */
            *worker = apr_palloc(p, sizeof(proxy_worker));
        }
        memset(*worker, 0, sizeof(proxy_worker));
        
        /* right here we just want to tuck away the worker info.
         * if called during config, we don't have shm setup yet,
         * so just note the info for later. */
        if (mask & AP_PROXY_WORKER_IS_MALLOCED)
            wshared = ap_malloc(sizeof(proxy_worker_shared));  /* will be freed ap_proxy_share_worker */
        else
            wshared = apr_palloc(p, sizeof(proxy_worker_shared));
        memset(wshared, 0, sizeof(proxy_worker_shared));
    
        if (PROXY_STRNCPY(wshared->name_ex, ptr) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(10366)
            "Alert! worker name (%s) too long; truncated to: %s", ptr, wshared->name_ex);
        }
        if (PROXY_STRNCPY(wshared->name, ptr) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(010118)
            "worker name (%s) too long; truncated for legacy modules that do not use "
            "proxy_worker_shared->name_ex: %s", ptr, wshared->name);
        }
        if (PROXY_STRNCPY(wshared->scheme, uri.scheme) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(010117)
            "Alert! worker scheme (%s) too long; truncated to: %s", uri.scheme, wshared->scheme);
        }
        if (PROXY_STRNCPY(wshared->hostname_ex, uri.hostname) != APR_SUCCESS) {
            return apr_psprintf(p, "worker hostname (%s) too long", uri.hostname);
        }
        if (PROXY_STRNCPY(wshared->hostname, uri.hostname) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(010118)
            "worker hostname (%s) too long; truncated for legacy modules that do not use "
            "proxy_worker_shared->hostname_ex: %s", uri.hostname, wshared->hostname);
        }
        wshared->port = (uri.port) ? uri.port : port_of_scheme;
        wshared->flush_packets = flush_off;
        wshared->flush_wait = PROXY_FLUSH_WAIT;
        wshared->address_ttl = (address_not_reusable) ? 0 : -1;
        wshared->is_address_reusable = (address_not_reusable == 0);
        wshared->disablereuse = (address_not_reusable != 0);
        wshared->lbfactor = 100;
        wshared->passes = 1;
        wshared->fails = 1;
        wshared->interval = apr_time_from_sec(HCHECK_WATHCHDOG_DEFAULT_INTERVAL);
        wshared->smax = -1;
        wshared->hash.def = ap_proxy_hashfunc(wshared->name_ex, PROXY_HASHFUNC_DEFAULT);
        wshared->hash.fnv = ap_proxy_hashfunc(wshared->name_ex, PROXY_HASHFUNC_FNV);
        wshared->was_malloced = (mask & AP_PROXY_WORKER_IS_MALLOCED) != 0;
        if (mask & AP_PROXY_WORKER_IS_MATCH) {
            wshared->is_name_matchable = 1;
            wshared->is_host_matchable = (address_not_reusable != 0);
    
            /* Before AP_PROXY_WORKER_IS_MATCH (< 2.4.47), a regex worker with
             * dollar substitution was never matched against any actual URL, thus
             * the requests fell through the generic worker. Now if a ProyPassMatch
             * matches, a worker (and its parameters) is always used to determine
             * the properties of the connection with the origin server. So for
             * instance the same "timeout=" will be enforced for all the requests
             * matched by the same ProyPassMatch worker, which is an improvement
             * compared to the global/vhost [Proxy]Timeout applied by the generic
             * worker. Likewise, address and connection reuse is the default for
             * a ProyPassMatch worker with no dollar substitution, just like a
             * "normal" worker. However to avoid DNS and connection reuse compat
             * issues, connection reuse is disabled by default if there is any
             * substitution in the uri-path (an explicit enablereuse=on can still
             * opt-in), and reuse is even disabled definitively for substitutions
             * happening in the hostname[:port] (is_address_reusable was unset
             * above so it will prevent enablereuse=on to apply anyway).
             */
            if (ap_strchr_c(wshared->name, '$')) {
                wshared->disablereuse = 1;
            }
        }
        if (sockpath) {
            if (PROXY_STRNCPY(wshared->uds_path, sockpath) != APR_SUCCESS) {
                return apr_psprintf(p, "worker uds path (%s) too long", sockpath);
            }
    
        }
        else {
            *wshared->uds_path = '\0';
        }
        if (!balancer) {
            wshared->status |= PROXY_WORKER_IGNORE_ERRORS;
        }
    
        (*worker)->hash = wshared->hash;
        (*worker)->context = NULL;
        (*worker)->cp = NULL;
        (*worker)->balancer = balancer;
        (*worker)->s = wshared;
    
        return NULL;
    }
    
    PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
                                                 proxy_worker **worker,
                                                 proxy_balancer *balancer,
                                                 proxy_server_conf *conf,
                                                 const char *url,
                                                 int do_malloc)
    {
        return ap_proxy_define_worker_ex(p, worker, balancer, conf, url,
                                         AP_PROXY_WORKER_IS_PREFIX |
                                         (do_malloc ? AP_PROXY_WORKER_IS_MALLOCED
                                                    : 0));
    }
    
    /* DEPRECATED */
    PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
                                                 proxy_worker **worker,
                                                 proxy_balancer *balancer,
                                                 proxy_server_conf *conf,
                                                 const char *url,
                                                 int do_malloc)
    {
        return ap_proxy_define_worker_ex(p, worker, balancer, conf, url,
                                         AP_PROXY_WORKER_IS_MATCH |
                                         (do_malloc ? AP_PROXY_WORKER_IS_MALLOCED
                                                    : 0));
    }
    
    /*
     * Create an already defined worker and free up memory
     */
    PROXY_DECLARE(apr_status_t) ap_proxy_share_worker(proxy_worker *worker, proxy_worker_shared *shm,
                                                      int i)
    {
        char *action = "copying";
        if (!shm || !worker->s)
            return APR_EINVAL;
    
        if ((worker->s->hash.def != shm->hash.def) ||
            (worker->s->hash.fnv != shm->hash.fnv)) {
            memcpy(shm, worker->s, sizeof(proxy_worker_shared));
            if (worker->s->was_malloced)
                free(worker->s); /* was malloced in ap_proxy_define_worker */
        } else {
            action = "re-using";
        }
        worker->s = shm;
        worker->s->index = i;
    
        if (APLOGdebug(ap_server_conf)) {
            apr_pool_t *pool;
            apr_pool_create(&pool, ap_server_conf->process->pool);
            apr_pool_tag(pool, "proxy_worker_name");
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02338)
                         "%s shm[%d] (0x%pp) for worker: %s", action, i, (void *)shm,
                         ap_proxy_worker_name(pool, worker));
            if (pool) {
                apr_pool_destroy(pool);
            }
        }
        return APR_SUCCESS;
    }
    
    PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, server_rec *s, apr_pool_t *p)
    {
        APR_OPTIONAL_FN_TYPE(http2_get_num_workers) *get_h2_num_workers;
        apr_status_t rv = APR_SUCCESS;
        int max_threads, minw, maxw;
    
        if (worker->s->status & PROXY_WORKER_INITIALIZED) {
            /* The worker is already initialized */
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00924)
                         "worker %s shared already initialized",
                         ap_proxy_worker_name(p, worker));
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00925)
                         "initializing worker %s shared",
                         ap_proxy_worker_name(p, worker));
            /* Set default parameters */
            if (!worker->s->retry_set) {
                worker->s->retry = apr_time_from_sec(PROXY_WORKER_DEFAULT_RETRY);
            }
            /* Consistently set address and connection reusabilty: when reuse
             * is disabled by configuration, or when the address is known already
             * to not be reusable for this worker (in any case, thus ignore/force
             * DisableReuse).
             */
            if (!worker->s->address_ttl || (!worker->s->address_ttl_set
                                            && worker->s->disablereuse)) {
                worker->s->is_address_reusable = 0;
            }
            if (!worker->s->is_address_reusable && !worker->s->disablereuse) {
                /* Explicit enablereuse=on can't work in this case, warn user. */
                if (worker->s->disablereuse_set) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10400)
                                 "enablereuse/disablereuse ignored for worker %s",
                                 ap_proxy_worker_name(p, worker));
                }
                worker->s->disablereuse = 1;
            }
    
            /*
             * When mod_http2 is loaded we might have more threads since it has
             * its own pool of processing threads.
             */
            ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads);
            get_h2_num_workers = APR_RETRIEVE_OPTIONAL_FN(http2_get_num_workers);
            if (get_h2_num_workers) {
                get_h2_num_workers(s, &minw, &maxw);
                /* So now the max is:
                 *   max_threads-1 threads for HTTP/1 each requiring one connection
                 *   + one thread for HTTP/2 requiring maxw connections
                 */
                max_threads = max_threads - 1 + maxw;
            }
            if (max_threads > 1) {
                /* Default hmax is max_threads to scale with the load and never
                 * wait for an idle connection to proceed.
                 */
                if (worker->s->hmax == 0) {
                    worker->s->hmax = max_threads;
                }
                if (worker->s->smax == -1 || worker->s->smax > worker->s->hmax) {
                    worker->s->smax = worker->s->hmax;
                }
                /* Set min to be lower than smax */
                if (worker->s->min > worker->s->smax) {
                    worker->s->min = worker->s->smax;
                }
            }
            else {
                /* This will suppress the apr_reslist creation */
                worker->s->min = worker->s->smax = worker->s->hmax = 0;
            }
        }
    
        /* What if local is init'ed and shm isn't?? Even possible? */
        if (worker->local_status & PROXY_WORKER_INITIALIZED) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00926)
                         "worker %s local already initialized",
                         ap_proxy_worker_name(p, worker));
        }
        else {
            apr_global_mutex_lock(proxy_mutex);
            /* Check again after we got the lock if we are still uninitialized */
            if (!(AP_VOLATILIZE_T(unsigned int, worker->local_status) & PROXY_WORKER_INITIALIZED)) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
                             "initializing worker %s local",
                             ap_proxy_worker_name(p, worker));
                /* Now init local worker data */
    #if APR_HAS_THREADS
                if (worker->tmutex == NULL) {
                    rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
                    if (rv != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00928)
                                     "can not create worker thread mutex");
                        apr_global_mutex_unlock(proxy_mutex);
                        return rv;
                    }
                }
    #endif
                if (worker->cp == NULL)
                    init_conn_pool(p, worker, s);
                if (worker->cp == NULL) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929)
                                 "can not create connection pool");
                    apr_global_mutex_unlock(proxy_mutex);
                    return APR_EGENERAL;
                }
    
                if (worker->s->hmax) {
                    rv = apr_reslist_create(&(worker->cp->res),
                                            worker->s->min, worker->s->smax,
                                            worker->s->hmax, worker->s->ttl,
                                            connection_constructor, connection_destructor,
                                            worker, worker->cp->pool);
    
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
                        "initialized pool in child %" APR_PID_T_FMT " for (%s:%d) min=%d max=%d smax=%d",
                         getpid(), worker->s->hostname_ex, (int)worker->s->port,
                         worker->s->min, worker->s->hmax, worker->s->smax);
    
                    /* Set the acquire timeout */
                    if (rv == APR_SUCCESS && worker->s->acquire_set) {
                        apr_reslist_timeout_set(worker->cp->res, worker->s->acquire);
                    }
    
                }
                else {
                    void *conn;
    
                    rv = connection_constructor(&conn, worker, worker->cp->pool);
                    worker->cp->conn = conn;
    
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00931)
                         "initialized single connection worker in child %" APR_PID_T_FMT " for (%s:%d)",
                         getpid(), worker->s->hostname_ex,
                         (int)worker->s->port);
                }
                if (rv == APR_SUCCESS) {
                    worker->local_status |= (PROXY_WORKER_INITIALIZED);
                }
            }
            apr_global_mutex_unlock(proxy_mutex);
    
        }
        if (rv == APR_SUCCESS) {
            worker->s->status |= (PROXY_WORKER_INITIALIZED);
        }
        return rv;
    }
    
    static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worker,
            server_rec *s)
    {
        if (worker->s->status & PROXY_WORKER_IN_ERROR) {
            if (PROXY_WORKER_IS(worker, PROXY_WORKER_STOPPED)) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(3305)
                             "%s: Won't retry worker (%s:%d): stopped",
                             proxy_function, worker->s->hostname_ex,
                             (int)worker->s->port);
                return DECLINED;
            }
            if ((worker->s->status & PROXY_WORKER_IGNORE_ERRORS)
                || apr_time_now() > worker->s->error_time + worker->s->retry) {
                ++worker->s->retries;
                worker->s->status &= ~PROXY_WORKER_IN_ERROR;
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00932)
                             "%s: worker for (%s:%d) has been marked for retry",
                             proxy_function, worker->s->hostname_ex,
                             (int)worker->s->port);
                return OK;
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00933)
                             "%s: too soon to retry worker for (%s:%d)",
                             proxy_function, worker->s->hostname_ex,
                             (int)worker->s->port);
                return DECLINED;
            }
        }
        else {
            return OK;
        }
    }
    
    /*
     * In the case of the reverse proxy, we need to see if we
     * were passed a UDS url (eg: from mod_proxy) and adjust uds_path
     * as required.  
     */
    static int fixup_uds_filename(request_rec *r) 
    {
        char *uds_url = r->filename + 6, *origin_url;
    
        if (!strncmp(r->filename, "proxy:", 6) &&
                !ap_cstr_casecmpn(uds_url, "unix:", 5) &&
                (origin_url = ap_strchr(uds_url + 5, '|'))) {
            char *uds_path = NULL, *col;
            apr_uri_t urisock;
            apr_status_t rv;
    
            *origin_url = '\0';
            rv = apr_uri_parse(r->pool, uds_url, &urisock);
            *origin_url++ = '|';
    
            if (rv == APR_SUCCESS && urisock.path && (!urisock.hostname
                                                      || !urisock.hostname[0])) {
                uds_path = ap_runtime_dir_relative(r->pool, urisock.path);
            }
            if (!uds_path || !(col = ap_strchr(origin_url, ':'))) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10292)
                        "Invalid proxy UDS filename (%s)", r->filename);
                apr_table_unset(r->notes, "uds_path");
                return HTTP_BAD_REQUEST;
            }
            apr_table_setn(r->notes, "uds_path", uds_path);
    
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                    "*: fixup UDS from %s: %s (%s)",
                    r->filename, origin_url, uds_path);
    
            /* The hostname part of the URL is not mandated for UDS though
             * the canon_handler hooks will require it. ProxyPass URLs are
             * fixed at load time by adding "localhost" automatically in the
             * worker URL, but SetHandler "proxy:unix:/udspath|scheme:[//]"
             * URLs are not so we have to fix it here the same way.
             */
            if (!col[1]) {
                /* origin_url is "scheme:" */
                r->filename = apr_pstrcat(r->pool, "proxy:",
                                          origin_url, "//localhost",
                                          NULL);
            }
            /* For a SetHandler "proxy:..." in a <Location "/path">, the "/path"
             * is appended to r->filename, hence the below origin_url cases too:
             */
            else if (col[1] == '/' && (col[2] != '/'    /* "scheme:/path" */
                                       || col[3] == '/' /* "scheme:///path" */
                                       || !col[3])) {   /* "scheme://" */
                char *scheme = origin_url;
                *col = '\0'; /* nul terminate scheme */
                if (col[2] != '/') {
                    origin_url = col + 1;
                }
                else {
                    origin_url = col + 3;
                }
                r->filename = apr_pstrcat(r->pool, "proxy:",
                                          scheme, "://localhost",
                                          origin_url, NULL);
            }
            else {
                /* origin_url is normal "scheme://host/path", can overwrite
                 * the UDS part of r->filename in place.
                 */
                memmove(uds_url, origin_url, strlen(origin_url) + 1);
            }
            return OK;
        }
    
        apr_table_unset(r->notes, "uds_path");
        return DECLINED;
    }
    
    /* Deprecated (unused upstream) */
    PROXY_DECLARE(int) ap_proxy_fixup_uds_filename(request_rec *r)
    {
        return fixup_uds_filename(r);
    }
    
    PROXY_DECLARE(const char *) ap_proxy_interpolate(request_rec *r,
                                                     const char *str)
    {
        /* Interpolate an env str in a configuration string
         * Syntax ${var} --> value_of(var)
         * Method: replace one var, and recurse on remainder of string
         * Nothing clever here, and crap like nested vars may do silly things
         * but we'll at least avoid sending the unwary into a loop
         */
        const char *start;
        const char *end;
        const char *var;
        const char *val;
        const char *firstpart;
    
        start = ap_strstr_c(str, "${");
        if (start == NULL) {
            return str;
        }
        end = ap_strchr_c(start+2, '}');
        if (end == NULL) {
            return str;
        }
        /* OK, this is syntax we want to interpolate.  Is there such a var ? */
        var = apr_pstrmemdup(r->pool, start+2, end-(start+2));
        val = apr_table_get(r->subprocess_env, var);
        firstpart = apr_pstrmemdup(r->pool, str, (start-str));
    
        if (val == NULL) {
            return apr_pstrcat(r->pool, firstpart,
                               ap_proxy_interpolate(r, end+1), NULL);
        }
        else {
            return apr_pstrcat(r->pool, firstpart, val,
                               ap_proxy_interpolate(r, end+1), NULL);
        }
    }
    
    static apr_array_header_t *proxy_vars(request_rec *r, apr_array_header_t *hdr)
    {
        int i;
        apr_array_header_t *ret = apr_array_make(r->pool, hdr->nelts,
                                                 sizeof (struct proxy_alias));
        struct proxy_alias *old = (struct proxy_alias *) hdr->elts;
    
        for (i = 0; i < hdr->nelts; ++i) {
            struct proxy_alias *newcopy = apr_array_push(ret);
            newcopy->fake = (old[i].flags & PROXYPASS_INTERPOLATE)
                            ? ap_proxy_interpolate(r, old[i].fake) : old[i].fake;
            newcopy->real = (old[i].flags & PROXYPASS_INTERPOLATE)
                            ? ap_proxy_interpolate(r, old[i].real) : old[i].real;
        }
        return ret;
    }
    
    PROXY_DECLARE(int) ap_proxy_canon_url(request_rec *r)
    {
        char *url, *p;
        int access_status;
        proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                     &proxy_module);
    
        if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
            return DECLINED;
    
        /* Put the UDS path appart if any (and not already stripped) */
        if (r->proxyreq == PROXYREQ_REVERSE) {
            access_status = fixup_uds_filename(r);
            if (ap_is_HTTP_ERROR(access_status)) {
                return access_status;
            }
        }
    
        /* Keep this after fixup_uds_filename() */
        url = apr_pstrdup(r->pool, r->filename + 6);
    
        if ((dconf->interpolate_env == 1) && (r->proxyreq == PROXYREQ_REVERSE)) {
            /* create per-request copy of reverse proxy conf,
             * and interpolate vars in it
             */
            proxy_req_conf *rconf = apr_palloc(r->pool, sizeof(proxy_req_conf));
            ap_set_module_config(r->request_config, &proxy_module, rconf);
            rconf->raliases = proxy_vars(r, dconf->raliases);
            rconf->cookie_paths = proxy_vars(r, dconf->cookie_paths);
            rconf->cookie_domains = proxy_vars(r, dconf->cookie_domains);
        }
    
        /* 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 */
    }
    
    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) {
            /* UDS path stripped from *url by proxy_fixup() already */
            *worker = ap_proxy_get_worker_ex(r->pool, NULL, conf, *url,
                                             AP_PROXY_WORKER_NO_UDS);
            if (*worker) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "%s: found worker %s for %s",
                              (*worker)->s->scheme, (*worker)->s->name_ex, *url);
                access_status = OK;
            }
            else if (r->proxyreq == PROXYREQ_PROXY) {
                if (conf->forward) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                                  "*: found forward proxy worker for %s", *url);
                    *worker = conf->forward;
                    access_status = OK;
                    /*
                     * The forward worker does not keep connections alive, so
                     * ensure that mod_proxy_http does the correct thing
                     * regarding the Connection header in the request.
                     */
                    apr_table_setn(r->subprocess_env, "proxy-nokeepalive", "1");
                }
            }
            else if (r->proxyreq == PROXYREQ_REVERSE) {
                if (conf->reverse) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                                  "*: using default reverse proxy worker for %s "
                                  "(no keepalive)", *url);
                    *worker = conf->reverse;
                    access_status = OK;
                    /*
                     * The reverse worker does not keep connections alive, so
                     * ensure that mod_proxy_http does the correct thing
                     * regarding the Connection header in the request.
                     */
                    apr_table_setn(r->subprocess_env, "proxy-nokeepalive", "1");
                }
            }
        }
        else if (access_status == DECLINED && *balancer != NULL) {
            /* All the workers are busy */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00934)
                          "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 = OK;
        if (balancer) {
            access_status = proxy_run_post_request(worker, balancer, r, conf);
            if (access_status == DECLINED) {
                access_status = OK; /* no post_request handler available */
                /* TODO: recycle direct worker */
            }
        }
    
        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,
                                                   request_rec *r)
    {
        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, r->pool)) != APR_SUCCESS) {
                loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
                ap_log_rerror(APLOG_MARK, loglevel, rv, r, APLOGNO(00935)
                              "%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 (conf->recv_buffer_size > 0 &&
                (rv = apr_socket_opt_set(*newsock, APR_SO_RCVBUF,
                                         conf->recv_buffer_size))) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00936)
                              "apr_socket_opt_set(SO_RCVBUF): Failed to set "
                              "ProxyReceiveBufferSize, using default");
            }
    
            rv = apr_socket_opt_set(*newsock, APR_TCP_NODELAY, 1);
            if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00937)
                              "apr_socket_opt_set(APR_TCP_NODELAY): "
                              "Failed to set");
            }
    
            /* Set a timeout on the socket */
            if (conf->timeout_set) {
                apr_socket_timeout_set(*newsock, conf->timeout);
            }
            else {
                apr_socket_timeout_set(*newsock, r->server->timeout);
            }
    
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                          "%s: fam %d socket created to connect to %s",
                          proxy_function, backend_addr->family, backend_name);
    
            if (conf->source_address) {
                apr_sockaddr_t *local_addr;
                /* Make a copy since apr_socket_bind() could change
                 * conf->source_address, which we don't want.
                 */
                local_addr = apr_pmemdup(r->pool, conf->source_address,
                                         sizeof(apr_sockaddr_t));
                local_addr->pool = r->pool;
                rv = apr_socket_bind(*newsock, local_addr);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00938)
                                  "%s: failed to bind socket to local address",
                                  proxy_function);
                }
            }
    
            /* 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_rerror(APLOG_MARK, loglevel, rv, r, APLOGNO(00939)
                              "%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;
    }
    
    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, APLOGNO(00940)
                             "%s: disabled connection for (%s:%d)",
                             proxy_function, worker->s->hostname_ex,
                             (int)worker->s->port);
                return HTTP_SERVICE_UNAVAILABLE;
            }
        }
    
        if (worker->s->hmax && worker->cp->res) {
            rv = apr_reslist_acquire(worker->cp->res, (void **)conn);
        }
        else {
            /* create the new connection if the previous was destroyed */
            if (!worker->cp->conn) {
                rv = 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, APLOGNO(00941)
                         "%s: failed to acquire connection for (%s:%d)",
                         proxy_function, worker->s->hostname_ex,
                         (int)worker->s->port);
            return HTTP_SERVICE_UNAVAILABLE;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00942)
                     "%s: has acquired connection for (%s:%d)",
                     proxy_function, worker->s->hostname_ex,
                     (int)worker->s->port);
    
        (*conn)->worker = worker;
        (*conn)->inreslist = 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, APLOGNO(00943)
                    "%s: has released connection for (%s:%d)",
                    proxy_function, conn->worker->s->hostname_ex,
                    (int)conn->worker->s->port);
        connection_cleanup(conn);
    
        return OK;
    }
    
    static APR_INLINE void proxy_address_inc(proxy_address *address)
    {
        apr_uint32_t old = apr_atomic_inc32(&address->refcount);
        ap_assert(old > 0 && old < APR_UINT32_MAX);
    }
    
    static APR_INLINE void proxy_address_dec(proxy_address *address)
    {
        /* Use _add32(, -1) since _dec32()'s returned value does not help */
        apr_uint32_t old = apr_atomic_add32(&address->refcount, -1);
        ap_assert(old > 0);
        if (old == 1) {
            apr_pool_destroy(address->addr->pool);
        }
    }
    
    static apr_status_t proxy_address_cleanup(void *address)
    {
        proxy_address_dec(address);
        return APR_SUCCESS;
    }
    
    static APR_INLINE proxy_address *worker_address_get(proxy_worker *worker)
    {
        /* No _readptr() so let's _casptr(, NULL, NULL) instead */
        return apr_atomic_casptr((void *)&worker->address, NULL, NULL);
    }
    
    /* XXX: Call when PROXY_THREAD_LOCK()ed only! */
    static APR_INLINE void worker_address_set(proxy_worker *worker,
                                              proxy_address *to)
    {
        proxy_address *old = apr_atomic_xchgptr((void *)&worker->address, to);
        if (old && old != to) {
            proxy_address_dec(old);
        }
    }
    
    static apr_status_t worker_address_resolve(proxy_worker *worker,
                                               apr_sockaddr_t **paddr,
                                               const char *hostname,
                                               apr_port_t hostport,
                                               const char *proxy_function,
                                               request_rec *r, server_rec *s)
    {
        apr_status_t rv;
        apr_pool_t *pool = NULL;
    
        apr_pool_create(&pool, worker->cp->dns_pool);
        rv = apr_sockaddr_info_get(paddr, hostname, APR_UNSPEC,
                                   hostport, 0, pool);
        if (rv != APR_SUCCESS) {
            if (r && !s) {
                proxyerror_core(r, HTTP_INTERNAL_SERVER_ERROR,
                                apr_pstrcat(pool,
                                            "DNS lookup failure for: ",
                                            hostname, NULL),
                                rv);
            }
            else if (r) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(10477)
                              "%s: resolving worker %s address",
                              proxy_function, hostname);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(10478)
                             "%s: resolving worker %s address",
                             proxy_function, hostname);
            }
            apr_pool_destroy(pool);
            return rv;
        }
    
        if (r ? APLOGrdebug(r) : APLOGdebug(s)) {
            char *addrs = NULL;
            apr_sockaddr_t *addr = *paddr;
            for (; addr; addr = addr->next) {
                addrs = apr_psprintf(pool, "%s%s%pI",
                                     addrs ? addrs : "",
                                     addrs ? ", " : "",
                                     addr);
            }
            if (r) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10479)
                              "%s: %s resolved to %s",
                              proxy_function, hostname, addrs);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10480)
                             "%s: %s resolved to %s",
                             proxy_function, hostname, addrs);
            }
        }
    
        return APR_SUCCESS;
    }
    
    static int proxy_addrs_equal(const apr_sockaddr_t *addr1,
                                 const apr_sockaddr_t *addr2)
    {
        const apr_sockaddr_t *base2 = addr2, *pos2;
        while (addr1 && addr2) {
            for (pos2 = base2; pos2; pos2 = pos2->next) {
                if (apr_sockaddr_equal(pos2, addr1)) {
                    break;
                }
            }
            if (!pos2) {
                return 0;
            }
            addr1 = addr1->next;
            addr2 = addr2->next;
        }
        if (addr1 || addr2) {
            return 0;
        }
        return 1;
    }
    
    PROXY_DECLARE(apr_status_t) ap_proxy_determine_address(const char *proxy_function,
                                                           proxy_conn_rec *conn,
                                                           const char *hostname,
                                                           apr_port_t hostport,
                                                           unsigned int flags,
                                                           request_rec *r,
                                                           server_rec *s)
    {
        proxy_worker *worker = conn->worker;
        apr_status_t rv;
    
        /*
         * 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.
         * The worker's addressTTL parameter may also be configured
         * to perform the DNS lookups only when the TTL expires,
         * or each time if that TTL is zero.
         */
        if (!worker->s->is_address_reusable) {
            conn->hostname = apr_pstrdup(conn->pool, hostname);
            conn->port = hostport;
    
            rv = apr_sockaddr_info_get(&conn->addr, hostname, APR_UNSPEC,
                                       hostport, 0, conn->pool);
            if (rv != APR_SUCCESS) {
                if (r && !s) {
                    proxyerror_core(r, HTTP_INTERNAL_SERVER_ERROR,
                                    apr_pstrcat(r->pool, "DNS lookup failure for: ",
                                                hostname, NULL), rv);
                }
                else if (r) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(10475)
                                  "%s: resolving backend %s address",
                                  proxy_function, hostname);
                }
                else {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(10476)
                                  "%s: resolving backend %s address",
                                  proxy_function, hostname);
                }
                return rv;
            }
        }
        else {
            apr_sockaddr_t *addr = NULL;
            proxy_address *address = NULL;
            apr_int32_t ttl = worker->s->address_ttl;
            apr_uint32_t now = 0;
    
            if (flags & PROXY_DETERMINE_ADDRESS_CHECK) {
                /* The caller wants to check if the address changed, return
                 * APR_EEXIST if not, otherwise fall through to update the
                 * worker's for everyone to switch.
                 */
                if (!conn->addr) {
                    /* Need something to compare with */
                    return APR_EINVAL;
                }
                rv = worker_address_resolve(worker, &addr,
                                            hostname, hostport,
                                            proxy_function, r, s);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
                if (proxy_addrs_equal(conn->addr, addr)) {
                    apr_pool_destroy(addr->pool);
                    return APR_EEXIST;
                }
            }
    
            AP_DEBUG_ASSERT(ttl != 0);
            if (ttl > 0) {
                /* TODO: use a monotonic clock here */
                now = apr_time_sec(apr_time_now() - *proxy_start_time);
            }
    
            /* Addresses are refcounted, destroyed when their refcount reaches 0.
             *
             * One ref is taken by worker->address as the worker's current/latest
             * address, it's dropped when that address expires/changes (see below).
             * The other refs are taken by the connections when using/switching to
             * the current worker address (also below), they are dropped when the
             * conns are destroyed (by the reslist though it should never happen
             * if hmax is greater than the number of threads) OR for an expired
             * conn->address when it's replaced by the new worker->address below.
             *
             * Dereferencing worker->address requires holding the worker mutex or
             * some concurrent connection processing might change/destroy it at any
             * time. So only conn->address is safe to dereference anywhere (unless
             * NULL..) since it has at least the lifetime of the connection.
             */
            if (!addr) {
                address = worker_address_get(worker);
            }
            if (!address
                || conn->address != address
                || apr_atomic_read32(&address->expiry) <= now) {
                PROXY_THREAD_LOCK(worker);
    
                /* Re-check while locked, might be a new address already */
                if (!addr) {
                    address = worker_address_get(worker);
                }
                if (!address || apr_atomic_read32(&address->expiry) <= now) {
                    if (!addr) {
                        rv = worker_address_resolve(worker, &addr,
                                                    hostname, hostport,
                                                    proxy_function, r, s);
                        if (rv != APR_SUCCESS) {
                            PROXY_THREAD_UNLOCK(worker);
                            return rv;
                        }
    
                        /* Recompute "now" should the DNS be slow
                         * TODO: use a monotonic clock here
                         */
                        now = apr_time_sec(apr_time_now() - *proxy_start_time);
                    }
    
                    address = apr_pcalloc(addr->pool, sizeof(*address));
                    address->hostname = apr_pstrdup(addr->pool, hostname);
                    address->hostport = hostport;
                    address->addr = addr;
    
                    if (ttl > 0) {
                        /* We keep each worker's expiry date shared accross all the
                         * children so that they update their address at the same
                         * time, regardless of whether a specific child forced an
                         * address to expire at some point (for connect() issues).
                         */
                        address->expiry = apr_atomic_read32(&worker->s->address_expiry);
                        if (address->expiry <= now) {
                            apr_uint32_t prev, next = (now + ttl) - (now % ttl);
                            do {
                                prev = apr_atomic_cas32(&worker->s->address_expiry,
                                                        next, address->expiry);
                                if (prev == address->expiry) {
                                    address->expiry = next;
                                    break;
                                }
                                address->expiry = prev;
                            } while (prev <= now);
                        }
                    }
                    else {
                        /* Never expires */
                        address->expiry = APR_UINT32_MAX;
                    }
    
                    /* One ref is for worker->address in any case */
                    if (worker->address || worker->cp->addr) {
                        apr_atomic_set32(&address->refcount, 1);
                    }
                    else {
                        /* Set worker->cp->addr once for compat with third-party
                         * modules. This addr never changed before and can't change
                         * underneath users now because of some TTL configuration.
                         * So we take one more ref for worker->cp->addr to remain
                         * allocated forever (though it might not be up to date..).
                         * Modules should use conn->addr instead of worker->cp-addr
                         * to get the actual address used by each conn, determined
                         * at connect() time.
                         */
                        apr_atomic_set32(&address->refcount, 2);
                        worker->cp->addr = address->addr;
                    }
    
                    /* Publish the changes. The old worker address (if any) is no
                     * longer used by this worker, it will be destroyed now if the
                     * worker is the last user (refcount == 1) or by the last conn
                     * using it (refcount > 1).
                     */
                    worker_address_set(worker, address);
                }
    
                /* Take the ref for conn->address (before dropping the mutex so to
                 * let no chance for this address be killed before it's used!)
                 */
                proxy_address_inc(address);
    
                PROXY_THREAD_UNLOCK(worker);
    
                /* Release the old conn address */
                if (conn->address) {
                    /* On Windows and OS/2, apr_socket_connect() called from
                     * ap_proxy_connect_backend() does a simple pointer copy of
                     * its given conn->addr[->next] into conn->sock->remote_addr.
                     * Thus conn->addr cannot be freed if the conn->sock should be
                     * kept alive (same new and old addresses) and the old address
                     * is still in conn->sock->remote_addr. In this case we rather
                     * delay the release of the old address by moving the cleanup
                     * to conn->scpool such that it runs when the socket is closed.
                     * In any other case, including other platforms, just release
                     * the old address now since conn->sock->remote_addr is either
                     * obsolete (socket forcibly closed) or a copy on conn->scpool
                     * already (not a dangling pointer).
                     */
                    int keep_addr_alive = 0,
                        keep_conn_alive = (conn->sock && conn->addr &&
                                           proxy_addrs_equal(conn->addr,
                                                             address->addr));
                    if (keep_conn_alive) {
    #if defined(WIN32) || defined(OS2)
                        apr_sockaddr_t *remote_addr = NULL;
                        apr_socket_addr_get(&remote_addr, APR_REMOTE, conn->sock);
                        for (addr = conn->addr; addr; addr = addr->next) {
                            if (addr == remote_addr) {
                                keep_addr_alive = 1;
                                break;
                            }
                        }
    #else
                        /* Nothing to do, keep_addr_alive = 0 */
    #endif
                    }
                    else if (conn->sock && (r ? APLOGrdebug(r) : APLOGdebug(s))) {
                        apr_sockaddr_t *local_addr = NULL;
                        apr_sockaddr_t *remote_addr = NULL;
                        apr_socket_addr_get(&local_addr, APR_LOCAL, conn->sock);
                        apr_socket_addr_get(&remote_addr, APR_REMOTE, conn->sock);
                        if (r) {
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10481)
                                          "%s: closing connection to %s (%pI<>%pI) on "
                                          "address change", proxy_function, hostname,
                                          local_addr, remote_addr);
                        }
                        else {
                            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10482)
                                         "%s: closing connection to %s (%pI<>%pI) on "
                                         "address change", proxy_function, hostname,
                                         local_addr, remote_addr);
                        }
                    }
                    if (keep_addr_alive) {
                        apr_pool_cleanup_kill(conn->pool, conn->address,
                                              proxy_address_cleanup);
                        apr_pool_cleanup_register(conn->scpool, conn->address,
                                                  proxy_address_cleanup,
                                                  apr_pool_cleanup_null);
                    }
                    else {
                        apr_pool_cleanup_run(conn->pool, conn->address,
                                             proxy_address_cleanup);
                        if (!keep_conn_alive) {
                            conn_cleanup(conn);
                        }
                    }
                }
    
                /* Use the new address */
                apr_pool_cleanup_register(conn->pool, address,
                                          proxy_address_cleanup,
                                          apr_pool_cleanup_null);
                conn->address = address;
                conn->hostname = address->hostname;
                conn->port = address->hostport;
                conn->addr = address->addr;
            }
        }
    
        return APR_SUCCESS;
    }
    
    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;
        const char *uds_path;
    
        /*
         * 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->hostname) {
            return ap_proxyerror(r, HTTP_BAD_REQUEST,
                                 apr_pstrcat(p,"URI has no hostname: ", *url,
                                             NULL));
        }
    
        if (!uri->port) {
            uri->port = ap_proxy_port_of_scheme(uri->scheme);
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00944)
                     "connecting %s to %s:%d", *url, uri->hostname, uri->port);
    
        /* Close a possible existing socket if we are told to do so */
        if (conn->close) {
            socket_cleanup(conn);
        }
    
        /*
         * allocate these out of the specified connection pool
         * The scheme handler decides if this is permanent or
         * short living pool.
         */
        /* Unless we are connecting the backend via a (forward Proxy)Remote, we
         * have to use the original form of the URI (non absolute), but this is
         * also the case via a remote proxy using the CONNECT method since the
         * original request (and URI) is to be embedded in the body.
         */
        if (!proxyname || conn->is_ssl) {
            *url = apr_pstrcat(p, uri->path, uri->query ? "?" : "",
                               uri->query ? uri->query : "",
                               uri->fragment ? "#" : "",
                               uri->fragment ? uri->fragment : "", NULL);
        }
        /*
         * Figure out if our passed in proxy_conn_rec has a usable
         * address cached.
         *
         * TODO: Handle this much better... 
         *
         * XXX: If generic workers are ever address-reusable, we need 
         *      to check host and port on the conn and be careful about
         *      spilling the cached addr from the worker.
         */
        uds_path = (*worker->s->uds_path
                    ? worker->s->uds_path
                    : apr_table_get(r->notes, "uds_path"));
        if (uds_path) {
            if (!conn->uds_path || strcmp(conn->uds_path, uds_path) != 0) {
                apr_pool_t *pool = conn->pool;
                if (conn->uds_path) {
                    conn_cleanup(conn);
                    if (!conn->uds_pool) {
                        apr_pool_create(&conn->uds_pool, worker->cp->dns_pool);
                    }
                    pool = conn->uds_pool;
                }
                /*
                 * In UDS cases, some structs are NULL. Protect from de-refs
                 * and provide info for logging at the same time.
                 */
    #if APR_HAVE_SOCKADDR_UN
                apr_sockaddr_info_get(&conn->addr, uds_path, APR_UNIX, 0, 0, pool);
                if (conn->addr && conn->addr->hostname) {
                    conn->uds_path = conn->addr->hostname;
                }
                else {
                    conn->uds_path = apr_pstrdup(pool, uds_path);
                }
    #else
                apr_sockaddr_info_get(&conn->addr, NULL, APR_UNSPEC, 0, 0, pool);
                conn->uds_path = apr_pstrdup(pool, uds_path);
    #endif
                conn->hostname = apr_pstrdup(pool, uri->hostname);
                conn->port = uri->port;
            }
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02545)
                         "%s: has determined UDS as %s (for %s:%hu)",
                         uri->scheme, conn->uds_path, conn->hostname, conn->port);
        }
        else {
            remote_connect_info *connect_info = NULL;
            const char *hostname = uri->hostname;
            apr_port_t hostport = uri->port;
    
            if (proxyname) {
                hostname = proxyname;
                hostport = proxyport;
    
                /*
                 * If we have a remote proxy and the protocol is HTTPS,
                 * then we need to prepend a HTTP CONNECT request before
                 * sending our actual HTTPS requests.
                 */
                if (conn->is_ssl) {
                    const char *proxy_auth;
    
                    /* Do we want to pass Proxy-Authorization along?
                     * If we haven't used it, then YES
                     * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
                     * So let's make it configurable by env.
                     * The logic here is the same used in mod_proxy_http.
                     */
                    proxy_auth = apr_table_get(r->notes, "proxy-basic-creds");
                    if (proxy_auth == NULL
                        && (r->user == NULL /* we haven't yet authenticated */
                            || apr_table_get(r->subprocess_env, "Proxy-Chain-Auth"))) {
                        proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
                    }
                    if (proxy_auth != NULL && proxy_auth[0] == '\0') {
                        proxy_auth = NULL;
                    }
    
                    /* Save our real backend data for using it later during HTTP CONNECT */
                    connect_info = conn->forward;
                    if (!connect_info
                        /* reset connect info if they changed */
                        || connect_info->target_port != uri->port
                        || ap_cstr_casecmp(connect_info->target_host, uri->hostname) != 0
                        || (connect_info->proxy_auth != NULL) != (proxy_auth != NULL)
                        || (connect_info->proxy_auth != NULL && proxy_auth != NULL &&
                            strcmp(connect_info->proxy_auth, proxy_auth) != 0)) {
                        apr_pool_t *fwd_pool = conn->pool;
                        if (worker->s->is_address_reusable) {
                            if (conn->fwd_pool) {
                                apr_pool_clear(conn->fwd_pool);
                            }
                            else {
                                apr_pool_create(&conn->fwd_pool, conn->pool);
                            }
                            fwd_pool = conn->fwd_pool;
                        }
                        connect_info = apr_pcalloc(fwd_pool, sizeof(*connect_info));
                        connect_info->target_host = apr_pstrdup(fwd_pool, uri->hostname);
                        connect_info->target_port = uri->port;
                        if (proxy_auth) {
                            connect_info->proxy_auth = apr_pstrdup(fwd_pool, proxy_auth);
                        }
                        conn->forward = NULL;
                    }
                }
            }
    
            /* Close the connection if the remote proxy or origin server don't match */
            if (conn->forward != connect_info
                || (conn->hostname 
                    && (conn->port != hostport
                        || ap_cstr_casecmp(conn->hostname, hostname) != 0))) {
                conn_cleanup(conn);
                conn->forward = connect_info;
            }
    
            /* Resolve the connection address with the determined hostname/port */
            if (ap_proxy_determine_address(uri->scheme, conn, hostname, hostport,
                                           0, r, NULL)) {
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        /* Get the server port for the Via headers */
        server_port = ap_get_server_port(r);
        AP_DEBUG_ASSERT(server_portstr_size > 0);
        if (ap_is_default_port(server_port, r)) {
            server_portstr[0] = '\0';
        }
        else {
            apr_snprintf(server_portstr, server_portstr_size, ":%d",
                         server_port);
        }
    
        /* check if ProxyBlock directive on this host */
        if (OK != ap_proxy_checkproxyblock2(r, conf, uri->hostname, 
                                           proxyname ? NULL : conn->addr)) {
            return ap_proxyerror(r, HTTP_FORBIDDEN,
                                 "Connect to remote machine blocked");
        }
        /*
         * When SSL is configured, determine the hostname (SNI) for the request
         * and save it in conn->ssl_hostname. Close any reused connection whose
         * SNI differs.
         */
        if (conn->is_ssl) {
            proxy_dir_conf *dconf;
            const char *ssl_hostname;
            /*
             * In the case of ProxyPreserveHost on use the hostname of
             * the request if present otherwise use the one from the
             * backend request URI.
             */
            dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
            if (dconf->preserve_host) {
                ssl_hostname = r->hostname;
            }
            else if (conn->forward) {
                ssl_hostname = ((remote_connect_info *)conn->forward)->target_host;
            }
            else {
                ssl_hostname = conn->hostname;
            }
            /*
             * Close if a SNI is in use but this request requires no or
             * a different one, or no SNI is in use but one is required.
             */
            if ((conn->ssl_hostname && (!ssl_hostname ||
                                        strcasecmp(conn->ssl_hostname,
                                                   ssl_hostname) != 0)) ||
                    (!conn->ssl_hostname && ssl_hostname && conn->sock)) {
                socket_cleanup(conn);
            }
            if (conn->ssl_hostname == NULL) {
                conn->ssl_hostname = apr_pstrdup(conn->scpool, ssl_hostname);
            }
        }
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00947)
                     "connecting %s to %pI (%s:%hu)", *url,
                     conn->addr, conn->hostname, conn->port);
        return OK;
    }
    
    #define USE_ALTERNATE_IS_CONNECTED 1
    
    #if !defined(APR_MSG_PEEK) && defined(MSG_PEEK)
    #define APR_MSG_PEEK MSG_PEEK
    #endif
    
    #if USE_ALTERNATE_IS_CONNECTED && defined(APR_MSG_PEEK)
    PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket)
    {
        apr_pollfd_t pfds[1];
        apr_status_t status;
        apr_int32_t  nfds;
    
        pfds[0].reqevents = APR_POLLIN;
        pfds[0].desc_type = APR_POLL_SOCKET;
        pfds[0].desc.s = socket;
    
        do {
            status = apr_poll(&pfds[0], 1, &nfds, 0);
        } while (APR_STATUS_IS_EINTR(status));
    
        if (status == APR_SUCCESS && nfds == 1 &&
            pfds[0].rtnevents == APR_POLLIN) {
            apr_sockaddr_t unused;
            apr_size_t len = 1;
            char buf[1];
            /* The socket might be closed in which case
             * the poll will return POLLIN.
             * If there is no data available the socket
             * is closed.
             */
            status = apr_socket_recvfrom(&unused, socket, APR_MSG_PEEK,
                                         &buf[0], &len);
            if (status == APR_SUCCESS && len)
                return 1;
            else
                return 0;
        }
        else if (APR_STATUS_IS_EAGAIN(status) || APR_STATUS_IS_TIMEUP(status)) {
            return 1;
        }
        return 0;
    
    }
    #else
    PROXY_DECLARE(int) ap_proxy_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, &current_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)
            || APR_STATUS_IS_ECONNRESET(socket_status)) {
            return 0;
        }
        else {
            return 1;
        }
    }
    #endif /* USE_ALTERNATE_IS_CONNECTED */
    
    
    /*
     * Send a HTTP CONNECT request to a remote proxy.
     * The proxy is given by "backend", the target server
     * is contained in the "forward" member of "backend".
     */
    static apr_status_t send_http_connect(proxy_conn_rec *backend,
                                          server_rec *s)
    {
        int status;
        apr_size_t nbytes;
        apr_size_t left;
        int complete = 0;
        char buffer[HUGE_STRING_LEN];
        char drain_buffer[HUGE_STRING_LEN];
        remote_connect_info *connect_info = backend->forward;
        int len = 0;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00948)
                     "CONNECT: sending the CONNECT request for %s:%d "
                     "to the remote proxy %pI (%s)",
                     connect_info->target_host, connect_info->target_port,
                     backend->addr, backend->hostname);
        /* Create the CONNECT request */
        nbytes = apr_snprintf(buffer, sizeof(buffer),
                              "CONNECT %s:%d HTTP/1.0" CRLF,
                              connect_info->target_host, connect_info->target_port);
        /* Add proxy authorization from the configuration, or initial
         * request if necessary */
        if (connect_info->proxy_auth != NULL) {
            nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
                                   "Proxy-Authorization: %s" CRLF,
                                   connect_info->proxy_auth);
        }
        /* Set a reasonable agent and send everything */
        nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
                               "Proxy-agent: %s" CRLF CRLF,
                               ap_get_server_banner());
        ap_xlate_proto_to_ascii(buffer, nbytes);
        apr_socket_send(backend->sock, buffer, &nbytes);
    
        /* Receive the whole CONNECT response */
        left = sizeof(buffer) - 1;
        /* Read until we find the end of the headers or run out of buffer */
        do {
            nbytes = left;
            status = apr_socket_recv(backend->sock, buffer + len, &nbytes);
            len += nbytes;
            left -= nbytes;
            buffer[len] = '\0';
            if (strstr(buffer + len - nbytes, CRLF_ASCII CRLF_ASCII) != NULL) {
                ap_xlate_proto_from_ascii(buffer, len);
                complete = 1;
                break;
            }
        } while (status == APR_SUCCESS && left > 0);
        /* Drain what's left */
        if (!complete) {
            nbytes = sizeof(drain_buffer) - 1;
            while (status == APR_SUCCESS && nbytes) {
                status = apr_socket_recv(backend->sock, drain_buffer, &nbytes);
                drain_buffer[nbytes] = '\0';
                nbytes = sizeof(drain_buffer) - 1;
                if (strstr(drain_buffer, CRLF_ASCII CRLF_ASCII) != NULL) {
                    break;
                }
            }
        }
    
        /* Check for HTTP_OK response status */
        if (status == APR_SUCCESS) {
            unsigned int major, minor;
            /* Only scan for three character status code */
            char code_str[4];
    
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00949)
                         "send_http_connect: response from the remote proxy: %s",
                         buffer);
    
            /* Extract the returned code */
            if (sscanf(buffer, "HTTP/%u.%u %3s", &major, &minor, code_str) == 3) {
                status = atoi(code_str);
                if (status == HTTP_OK) {
                    status = APR_SUCCESS;
                }
                else {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00950)
                                 "send_http_connect: the remote proxy returned code is '%s'",
                                 code_str);
                    status = APR_INCOMPLETE;
                }
            }
        }
    
        return(status);
    }
    
    
    /* TODO: In APR 2.x: Extend apr_sockaddr_t to possibly be a path !!! */
    PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock,
                                                     const char *uds_path,
                                                     apr_pool_t *p)
    {
    #if APR_HAVE_SYS_UN_H
        apr_status_t rv;
        apr_os_sock_t rawsock;
        apr_interval_time_t t;
        struct sockaddr_un *sa;
        apr_socklen_t addrlen, pathlen;
    
        rv = apr_os_sock_get(&rawsock, sock);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_socket_timeout_get(sock, &t);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        pathlen = strlen(uds_path);
        /* copy the UDS path (including NUL) to the sockaddr_un */
        addrlen = APR_OFFSETOF(struct sockaddr_un, sun_path) + pathlen;
        sa = (struct sockaddr_un *)apr_palloc(p, addrlen + 1);
        memcpy(sa->sun_path, uds_path, pathlen + 1);
        sa->sun_family = AF_UNIX;
    
        do {
            rv = connect(rawsock, (struct sockaddr*)sa, addrlen);
        } while (rv == -1 && (rv = errno) == EINTR);
    
        if (rv && rv != EISCONN) {
            if ((rv == EINPROGRESS || rv == EALREADY) && (t > 0))  {
    #if APR_MAJOR_VERSION < 2
                rv = apr_wait_for_io_or_timeout(NULL, sock, 0);
    #else
                rv = apr_socket_wait(sock, APR_WAIT_WRITE);
    #endif
            }
            if (rv != APR_SUCCESS) {
                return rv;
            }
        }
    
        return APR_SUCCESS;
    #else
        return APR_ENOTIMPL;
    #endif
    }
    
    PROXY_DECLARE(apr_status_t) ap_proxy_check_connection(const char *scheme,
                                                          proxy_conn_rec *conn,
                                                          server_rec *server,
                                                          unsigned max_blank_lines,
                                                          int flags)
    {
        apr_status_t rv = APR_SUCCESS;
        proxy_worker *worker = conn->worker;
    
        if (!PROXY_WORKER_IS_USABLE(worker)) {
            /*
             * The worker is in error likely done by a different thread / process
             * e.g. for a timeout or bad status. We should respect this and should
             * not continue with a connection via this worker even if we got one.
             */
            rv = APR_EINVAL;
        }
        else if (conn->connection) {
            /* We have a conn_rec, check the full filter stack for things like
             * SSL alert/shutdown, filters aside data...
             */
            rv = ap_check_pipeline(conn->connection, conn->tmp_bb,
                                   max_blank_lines);
            apr_brigade_cleanup(conn->tmp_bb);
            if (rv == APR_SUCCESS) {
                /* Some data available, the caller might not want them. */
                if (flags & PROXY_CHECK_CONN_EMPTY) {
                    rv = APR_ENOTEMPTY;
                }
            }
            else if (APR_STATUS_IS_EAGAIN(rv)) {
                /* Filter chain is OK and empty, yet we can't determine from
                 * ap_check_pipeline (actually ap_core_input_filter) whether
                 * an empty non-blocking read is EAGAIN or EOF on the socket
                 * side (it's always SUCCESS), so check it explicitly here.
                 */
                if (ap_proxy_is_socket_connected(conn->sock)) {
                    rv = APR_SUCCESS;
                }
                else {
                    rv = APR_EPIPE;
                }
            }
        }
        else if (conn->sock) {
            /* For modules working with sockets directly, check it. */
            if (!ap_proxy_is_socket_connected(conn->sock)) {
                rv = APR_EPIPE;
            }
        }
        else {
            rv = APR_ENOSOCKET;
        }
    
        if (rv == APR_SUCCESS) {
            if (APLOGtrace2(server)) {
                apr_sockaddr_t *local_addr = NULL;
                apr_socket_addr_get(&local_addr, APR_LOCAL, conn->sock);
                ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, server,
                             "%s: reusing backend connection %pI<>%pI",
                             scheme, local_addr, conn->addr);
            }
        }
        else if (conn->sock) {
            /* This clears conn->scpool (and associated data), so backup and
             * restore any ssl_hostname for this connection set earlier by
             * ap_proxy_determine_connection().
             */
            char ssl_hostname[PROXY_WORKER_RFC1035_NAME_SIZE];
            if (rv == APR_EINVAL
                    || !conn->ssl_hostname
                    || PROXY_STRNCPY(ssl_hostname, conn->ssl_hostname)) {
                ssl_hostname[0] = '\0';
            }
    
            socket_cleanup(conn);
            if (rv != APR_ENOTEMPTY) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, APLOGNO(00951)
                             "%s: backend socket is disconnected.", scheme);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, server, APLOGNO(03408)
                             "%s: reusable backend connection is not empty: "
                             "forcibly closed", scheme);
            }
    
            if (ssl_hostname[0]) {
                conn->ssl_hostname = apr_pstrdup(conn->scpool, ssl_hostname);
            }
        }
    
        return rv;
    }
    
    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 loglevel;
        remote_connect_info *connect_info = conn->forward;
        apr_sockaddr_t *backend_addr;
        /* the local address to use for the outgoing connection */
        apr_sockaddr_t *local_addr;
        apr_socket_t *newsock;
        void *sconf = s->module_config;
        int address_reusable = worker->s->is_address_reusable;
        int did_dns_lookup = 0;
        proxy_server_conf *conf =
            (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
    
        rv = ap_proxy_check_connection(proxy_function, conn, s, 0, 0);
        if (rv == APR_EINVAL) {
            return DECLINED;
        }
    
        /* We'll set conn->addr to the address actually connect()ed, so if the
         * network connection is not reused (per ap_proxy_check_connection()
         * above) we need to reset conn->addr to the first resolved address
         * and try to connect it first.
         */
        if (conn->address && rv != APR_SUCCESS) {
            conn->addr = conn->address->addr;
        }
        backend_addr = conn->addr;
    
        while (rv != APR_SUCCESS && (backend_addr || conn->uds_path)) {
    #if APR_HAVE_SYS_UN_H
            if (conn->uds_path)
            {
                rv = apr_socket_create(&newsock, AF_UNIX, SOCK_STREAM, 0,
                                       conn->scpool);
                if (rv != APR_SUCCESS) {
                    loglevel = APLOG_ERR;
                    ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(02453)
                                 "%s: error creating Unix domain socket "
                                 "%s (%s:%hu)",
                                 proxy_function,
                                 conn->uds_path,
                                 conn->hostname, conn->port);
                    break;
                }
                conn->connection = NULL;
    
                rv = ap_proxy_connect_uds(newsock, conn->uds_path, conn->scpool);
                if (rv != APR_SUCCESS) {
                    apr_socket_close(newsock);
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02454)
                                 "%s: attempt to connect to Unix domain socket "
                                 "%s (%s:%hu) failed",
                                 proxy_function, conn->uds_path,
                                 conn->hostname, conn->port);
                    break;
                }
    
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02823)
                             "%s: connection established with Unix domain socket "
                             "%s (%s:%hu)",
                             proxy_function,
                             conn->uds_path,
                             conn->hostname, conn->port);
            }
            else
    #endif
            {
                if ((rv = apr_socket_create(&newsock, backend_addr->family,
                                            SOCK_STREAM, APR_PROTO_TCP,
                                            conn->scpool)) != APR_SUCCESS) {
                    loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
                    ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00952)
                                 "%s: error creating fam %d socket to %pI for "
                                 "(%s:%hu)",
                                 proxy_function,
                                 backend_addr->family, backend_addr,
                                 conn->hostname, conn->port);
                    /*
                     * 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;
                }
                conn->connection = NULL;
    
                if (worker->s->recv_buffer_size > 0 &&
                    (rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF,
                                             worker->s->recv_buffer_size))) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00953)
                                 "apr_socket_opt_set(SO_RCVBUF): Failed to set "
                                 "ProxyReceiveBufferSize, using default");
                }
    
                rv = apr_socket_opt_set(newsock, APR_TCP_NODELAY, 1);
                if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00954)
                                 "apr_socket_opt_set(APR_TCP_NODELAY): "
                                 "Failed to set");
                }
    
                /* Set a timeout for connecting to the backend on the socket */
                if (worker->s->conn_timeout_set) {
                    apr_socket_timeout_set(newsock, worker->s->conn_timeout);
                }
                else if (worker->s->timeout_set) {
                    apr_socket_timeout_set(newsock, worker->s->timeout);
                }
                else if (conf->timeout_set) {
                    apr_socket_timeout_set(newsock, conf->timeout);
                }
                else {
                    apr_socket_timeout_set(newsock, s->timeout);
                }
                /* Set a keepalive option */
                if (worker->s->keepalive) {
                    if ((rv = apr_socket_opt_set(newsock,
                                                 APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00955)
                                     "apr_socket_opt_set(SO_KEEPALIVE): Failed to set"
                                     " Keepalive");
                    }
                }
                ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
                             "%s: fam %d socket created for %pI (%s:%hu)",
                             proxy_function, backend_addr->family, backend_addr,
                             conn->hostname, conn->port);
    
                if (conf->source_address_set) {
                    local_addr = apr_pmemdup(conn->scpool, conf->source_address,
                                             sizeof(apr_sockaddr_t));
                    local_addr->pool = conn->scpool;
                    rv = apr_socket_bind(newsock, local_addr);
                    if (rv != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00956)
                                     "%s: failed to bind socket to local address",
                                     proxy_function);
                    }
                }
    
                /* 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, APLOGNO(00957)
                                 "%s: attempt to connect to %pI (%s:%hu) failed",
                                 proxy_function, backend_addr,
                                 conn->hostname, conn->port);
                    backend_addr = backend_addr->next;
                    /*
                     * If we run out of resolved IP's when connecting and if
                     * we cache the resolution in the worker the resolution
                     * might have changed. Hence try a DNS lookup to see if this
                     * helps.
                     */
                    if (!backend_addr && address_reusable && !did_dns_lookup) {
                        /* Issue a new DNS lookup to check if the address changed,
                         * in which case (SUCCESS) restart the loop with the new
                         * one(s), otherwise leave (nothing we can do about it).
                         */
                        if (ap_proxy_determine_address(proxy_function, conn,
                                                       conn->hostname, conn->port,
                                                       PROXY_DETERMINE_ADDRESS_CHECK,
                                                       NULL, s) == APR_SUCCESS) {
                            backend_addr = conn->addr;
                        }
    
                        /*
                         * In case of an error backend_addr will be NULL which
                         * is enough to leave the loop. If successful we'll retry
                         * the new addresses only once.
                         */
                        did_dns_lookup = 1;
                    }
                    continue;
                }
    
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02824)
                             "%s: connection established with %pI (%s:%hu)",
                             proxy_function, backend_addr,
                             conn->hostname, conn->port);
    
                /* Set the actual sockaddr we are connected to */
                conn->addr = backend_addr;
            }
    
            /* Set a timeout on the socket */
            if (worker->s->timeout_set) {
                apr_socket_timeout_set(newsock, worker->s->timeout);
            }
            else if (conf->timeout_set) {
                apr_socket_timeout_set(newsock, conf->timeout);
            }
            else {
                 apr_socket_timeout_set(newsock, s->timeout);
            }
    
            conn->sock = newsock;
    
            /*
             * For HTTP CONNECT we need to prepend CONNECT request before
             * sending our actual HTTPS requests.
             */
            if (connect_info) {
                rv = send_http_connect(conn, s);
                /* If an error occurred, loop round and try again */
                if (rv != APR_SUCCESS) {
                    conn->sock = NULL;
                    apr_socket_close(newsock);
                    loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
                    ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00958)
                                 "%s: attempt to connect to %s:%hu "
                                 "via http CONNECT through %pI (%s:%hu) failed",
                                 proxy_function,
                                 connect_info->target_host, connect_info->target_port,
                                 backend_addr, conn->hostname, conn->port);
                    backend_addr = backend_addr->next;
                    continue;
                }
            }
        }
    
        if (PROXY_WORKER_IS_USABLE(worker)) {
            /*
             * Put the entire worker to error state if
             * the PROXY_WORKER_IGNORE_ERRORS flag is not set.
             * Although some connections may be alive
             * no further connections to the worker could be made
             */
            if (rv != APR_SUCCESS) {
                if (!(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
                    worker->s->error_time = apr_time_now();
                    worker->s->status |= PROXY_WORKER_IN_ERROR;
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00959)
                        "ap_proxy_connect_backend disabling worker for (%s:%d) "
                        "for %" APR_TIME_T_FMT "s",
                        worker->s->hostname_ex, (int)worker->s->port,
                        apr_time_sec(worker->s->retry));
                }
            }
            else {
                if (worker->s->retries) {
                    /*
                     * A worker came back. So here is where we need to
                     * either reset all params to initial conditions or
                     * apply some sort of aging
                     */
                }
                worker->s->error_time = 0;
                worker->s->retries = 0;
            }
        }
        else {
            /*
             * The worker is in error likely done by a different thread / process
             * e.g. for a timeout or bad status. We should respect this and should
             * not continue with a connection via this worker even if we got one.
             */
            rv = APR_EINVAL;
        }
        if (rv != APR_SUCCESS) {
            socket_cleanup(conn);
            return DECLINED;
        }
        return OK;
    }
    
    static apr_status_t connection_shutdown(void *theconn)
    {
        proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
        conn_rec *c = conn->connection;
        if (c) {
            if (!c->aborted) {
                apr_interval_time_t saved_timeout = 0;
                apr_socket_timeout_get(conn->sock, &saved_timeout);
                if (saved_timeout) {
                    apr_socket_timeout_set(conn->sock, 0);
                }
    
                (void)ap_shutdown_conn(c, 0);
                c->aborted = 1;
    
                if (saved_timeout) {
                    apr_socket_timeout_set(conn->sock, saved_timeout);
                }
            }
    
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02642)
                          "proxy: connection shutdown");
        }
        return APR_SUCCESS;
    }
    
    
    static int proxy_connection_create(const char *proxy_function,
                                       proxy_conn_rec *conn,
                                       request_rec *r, server_rec *s)
    {
        ap_conf_vector_t *per_dir_config = (r) ? r->per_dir_config
                                               : conn->worker->section_config;
        apr_sockaddr_t *backend_addr = conn->addr;
        apr_interval_time_t current_timeout;
        apr_bucket_alloc_t *bucket_alloc;
        int rc = OK;
    
        if (conn->connection) {
            if (conn->is_ssl) {
                /* on reuse, reinit the SSL connection dir config with the current
                 * r->per_dir_config, the previous one was reset on release.
                 */
                ap_proxy_ssl_engine(conn->connection, per_dir_config, 1);
            }
            return OK;
        }
    
        if (conn->sock) {
            bucket_alloc = apr_bucket_alloc_create(conn->scpool);
            conn->tmp_bb = apr_brigade_create(conn->scpool, bucket_alloc);
            /*
             * The socket is now open, create a new backend server connection
             */
            conn->connection = ap_run_create_connection(conn->scpool, s, conn->sock,
                                                        0, NULL, bucket_alloc);
        }
        if (!conn->connection) {
            /*
             * the peer reset the connection already; ap_run_create_connection()
             * closed the socket
             */
            ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                         s, APLOGNO(00960) "%s: an error occurred creating a "
                         "new connection to %pI (%s)%s",
                         proxy_function, backend_addr, conn->hostname,
                         conn->sock ? "" : " (not connected)");
            rc = HTTP_INTERNAL_SERVER_ERROR;
            goto cleanup;
        }
    
        /* For ssl connection to backend */
        if (conn->is_ssl) {
            if (!ap_proxy_ssl_engine(conn->connection, per_dir_config, 1)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                             s, APLOGNO(00961) "%s: failed to enable ssl support "
                             "for %pI (%s)", proxy_function,
                             backend_addr, conn->hostname);
                rc = HTTP_INTERNAL_SERVER_ERROR;
                goto cleanup;
            }
            if (conn->ssl_hostname) {
                /* Set a note on the connection about what CN is requested,
                 * such that mod_ssl can check if it is requested to do so.
                 */
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, conn->connection, 
                              "%s: set SNI to %s for (%s)", proxy_function,
                              conn->ssl_hostname, conn->hostname);
                apr_table_setn(conn->connection->notes, "proxy-request-hostname",
                               conn->ssl_hostname);
            }
        }
        else {
            /* TODO: See if this will break FTP */
            ap_proxy_ssl_engine(conn->connection, per_dir_config, 0);
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00962)
                     "%s: connection complete to %pI (%s)",
                     proxy_function, backend_addr, conn->hostname);
    
        /*
         * save the timeout of the socket because core_pre_connection
         * will set it to base_server->timeout
         * (core TimeOut directive).
         */
        apr_socket_timeout_get(conn->sock, &current_timeout);
        /* 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, APLOGNO(00963)
                         "%s: pre_connection setup failed (%d)",
                         proxy_function, rc);
            goto cleanup;
        }
        apr_socket_timeout_set(conn->sock, current_timeout);
    
        /* Shutdown the connection before closing it (eg. SSL connections
         * need to be close-notify-ed).
         */
        apr_pool_pre_cleanup_register(conn->scpool, conn, connection_shutdown);
    
        return OK;
    
    cleanup:
        socket_cleanup(conn);
        return rc;
    }
    
    PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function,
                                                     proxy_conn_rec *conn,
                                                     request_rec *r)
    {
        return proxy_connection_create(proxy_function, conn, r, r->server);
    }
    
    PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
                                                  proxy_conn_rec *conn,
                                                  conn_rec *c, server_rec *s)
    {
        (void) c; /* unused */
        return proxy_connection_create(proxy_function, conn, NULL, s);
    }
    
    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;
    }
    
    static APR_INLINE int error_code_overridden(const int *elts, int nelts,
                                                int code)
    {
        int min = 0;
        int max = nelts - 1;
        AP_DEBUG_ASSERT(max >= 0);
    
        while (min < max) {
            int mid = (min + max) / 2;
            int val = elts[mid];
    
            if (val < code) {
                min = mid + 1;
            }
            else if (val > code) {
                max = mid - 1;
            }
            else {
                return 1;
            }
        }
    
        return elts[min] == code;
    }
    
    PROXY_DECLARE(int) ap_proxy_should_override(proxy_dir_conf *conf, int code)
    {
        if (!conf->error_override) 
            return 0;
    
        if (apr_is_empty_array(conf->error_override_codes))
            return ap_is_HTTP_ERROR(code);
    
        /* Since error_override_codes is sorted, apply binary search. */
        return error_code_overridden((int *)conf->error_override_codes->elts,
                                     conf->error_override_codes->nelts,
                                     code);
    }
    
    PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
                                               apr_bucket_brigade *brigade)
    {
        apr_bucket *e;
        conn_rec *c = r->connection;
    
        r->no_cache = 1;
        /*
         * If this is a subrequest, then prevent also caching of the main
         * request.
         */
        if (r->main)
            r->main->no_cache = 1;
        e = ap_bucket_error_create(HTTP_BAD_GATEWAY, NULL, c->pool,
                                   c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(brigade, e);
        e = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(brigade, e);
    }
    
    /*
     * Provide a string hashing function for the proxy.
     * We offer 2 methods: one is the APR model but we
     * also provide our own, based on either FNV or SDBM.
     * The reason is in case we want to use both to ensure no
     * collisions.
     */
    PROXY_DECLARE(unsigned int)
    ap_proxy_hashfunc(const char *str, proxy_hash_t method)
    {
        if (method == PROXY_HASHFUNC_APR) {
            apr_ssize_t slen = strlen(str);
            return apr_hashfunc_default(str, &slen);
        }
        else if (method == PROXY_HASHFUNC_FNV) {
            /* FNV model */
            unsigned int hash;
            const unsigned int fnv_prime = 0x811C9DC5;
            for (hash = 0; *str; str++) {
                hash *= fnv_prime;
                hash ^= (*str);
            }
            return hash;
        }
        else { /* method == PROXY_HASHFUNC_DEFAULT */
            /* SDBM model */
            unsigned int hash;
            for (hash = 0; *str; str++) {
                hash = (*str) + (hash << 6) + (hash << 16) - hash;
            }
            return hash;
        }
    }
    
    PROXY_DECLARE(apr_status_t) ap_proxy_set_wstatus(char c, int set, proxy_worker *w)
    {
        unsigned int *status = &w->s->status;
        char flag = toupper(c);
        proxy_wstat_t *pwt = proxy_wstat_tbl;
        while (pwt->bit) {
            if (flag == pwt->flag) {
                if (set)
                    *status |= pwt->bit;
                else
                    *status &= ~(pwt->bit);
                return APR_SUCCESS;
            }
            pwt++;
        }
        return APR_EINVAL;
    }
    
    PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w)
    {
        char *ret = "";
        unsigned int status = w->s->status;
        proxy_wstat_t *pwt = proxy_wstat_tbl;
        while (pwt->bit) {
            if (status & pwt->bit)
                ret = apr_pstrcat(p, ret, pwt->name, NULL);
            pwt++;
        }
        if (!*ret) {
            ret = "??? ";
        }
        if (PROXY_WORKER_IS_USABLE(w))
            ret = apr_pstrcat(p, ret, "Ok ", NULL);
        return ret;
    }
    
    PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec *s,
                                                        proxy_server_conf *conf)
    {
        proxy_worker **workers;
        int i;
        int index;
        proxy_worker_shared *shm;
        proxy_balancer_method *lbmethod;
        ap_slotmem_provider_t *storage = b->storage;
    
        if (b->s->wupdated <= b->wupdated)
            return APR_SUCCESS;
        /* balancer sync */
        lbmethod = ap_lookup_provider(PROXY_LBMETHOD, b->s->lbpname, "0");
        if (lbmethod) {
            b->lbmethod = lbmethod;
        } else {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(02433)
                         "Cannot find LB Method: %s", b->s->lbpname);
            return APR_EINVAL;
        }
    
        /* worker sync */
    
        /*
         * Look thru the list of workers in shm
         * and see which one(s) we are lacking...
         * again, the cast to unsigned int is safe
         * since our upper limit is always max_workers
         * which is int.
         */
        for (index = 0; index < b->max_workers; index++) {
            int found;
            apr_status_t rv;
            if ((rv = storage->dptr(b->wslot, (unsigned int)index, (void *)&shm)) != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(00965) "worker slotmem_dptr failed");
                return APR_EGENERAL;
            }
            /* account for possible "holes" in the slotmem
             * (eg: slots 0-2 are used, but 3 isn't, but 4-5 is)
             */
            if (!shm->hash.def || !shm->hash.fnv)
                continue;
            found = 0;
            workers = (proxy_worker **)b->workers->elts;
            for (i = 0; i < b->workers->nelts; i++, workers++) {
                proxy_worker *worker = *workers;
                if (worker->hash.def == shm->hash.def && worker->hash.fnv == shm->hash.fnv) {
                    found = 1;
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02402)
                                 "re-grabbing shm[%d] (0x%pp) for worker: %s", i, (void *)shm,
                                 ap_proxy_worker_name(conf->pool, worker));
                    break;
                }
            }
            if (!found) {
                proxy_worker **runtime;
                /* XXX: a thread mutex is maybe enough here */
                apr_global_mutex_lock(proxy_mutex);
                runtime = apr_array_push(b->workers);
                *runtime = apr_pcalloc(conf->pool, sizeof(proxy_worker));
                apr_global_mutex_unlock(proxy_mutex);
                (*runtime)->hash = shm->hash;
                (*runtime)->balancer = b;
                (*runtime)->s = shm;
    
                rv = ap_proxy_initialize_worker(*runtime, s, conf->pool);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(00966) "Cannot init worker");
                    return rv;
                }
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02403)
                             "grabbing shm[%d] (0x%pp) for worker: %s", i, (void *)shm,
                             (*runtime)->s->name_ex);
            }
        }
        if (b->s->need_reset) {
            if (b->lbmethod && b->lbmethod->reset)
                b->lbmethod->reset(b, s);
            b->s->need_reset = 0;
        }
        b->wupdated = b->s->wupdated;
        return APR_SUCCESS;
    }
    
    PROXY_DECLARE(proxy_worker_shared *) ap_proxy_find_workershm(ap_slotmem_provider_t *storage,
                                                                   ap_slotmem_instance_t *slot,
                                                                   proxy_worker *worker,
                                                                   unsigned int *index)
    {
        proxy_worker_shared *shm;
        unsigned int i, limit;
        limit = storage->num_slots(slot);
        for (i = 0; i < limit; i++) {
            if (storage->dptr(slot, i, (void *)&shm) != APR_SUCCESS) {
                return NULL;
            }
            if ((worker->s->hash.def == shm->hash.def) &&
                (worker->s->hash.fnv == shm->hash.fnv)) {
                *index = i;
                return shm;
            }
        }
        return NULL;
    }
    
    PROXY_DECLARE(proxy_balancer_shared *) ap_proxy_find_balancershm(ap_slotmem_provider_t *storage,
                                                                     ap_slotmem_instance_t *slot,
                                                                     proxy_balancer *balancer,
                                                                     unsigned int *index)
    {
        proxy_balancer_shared *shm;
        unsigned int i, limit;
        limit = storage->num_slots(slot);
        for (i = 0; i < limit; i++) {
            if (storage->dptr(slot, i, (void *)&shm) != APR_SUCCESS) {
                return NULL;
            }
            if ((balancer->s->hash.def == shm->hash.def) &&
                (balancer->s->hash.fnv == shm->hash.fnv)) {
                *index = i;
                return shm;
            }
        }
        return NULL;
    }
    
    typedef struct header_connection {
        apr_pool_t *pool;
        apr_array_header_t *array;
        const char *first;
        unsigned int closed:1;
    } header_connection;
    
    static int find_conn_headers(void *data, const char *key, const char *val)
    {
        header_connection *x = data;
        const char *name;
    
        do {
            while (*val == ',' || *val == ';') {
                val++;
            }
            name = ap_get_token(x->pool, &val, 0);
            if (!strcasecmp(name, "close")) {
                x->closed = 1;
            }
            if (!x->first) {
                x->first = name;
            }
            else {
                const char **elt;
                if (!x->array) {
                    x->array = apr_array_make(x->pool, 4, sizeof(char *));
                }
                elt = apr_array_push(x->array);
                *elt = name;
            }
        } while (*val);
    
        return 1;
    }
    
    /**
     * Remove all headers referred to by the Connection header.
     */
    static int ap_proxy_clear_connection(request_rec *r, apr_table_t *headers)
    {
        const char **name;
        header_connection x;
    
        x.pool = r->pool;
        x.array = NULL;
        x.first = NULL;
        x.closed = 0;
    
        apr_table_unset(headers, "Proxy-Connection");
    
        apr_table_do(find_conn_headers, &x, headers, "Connection", NULL);
        if (x.first) {
            /* fast path - no memory allocated for one header */
            apr_table_unset(headers, "Connection");
            apr_table_unset(headers, x.first);
        }
        if (x.array) {
            /* two or more headers */
            while ((name = apr_array_pop(x.array))) {
                apr_table_unset(headers, *name);
            }
        }
    
        return x.closed;
    }
    
    PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
                                                apr_bucket_brigade *header_brigade,
                                                request_rec *r,
                                                proxy_conn_rec *p_conn,
                                                proxy_worker *worker,
                                                proxy_server_conf *conf,
                                                apr_uri_t *uri,
                                                char *url, char *server_portstr,
                                                char **old_cl_val,
                                                char **old_te_val)
    {
        int rc = OK;
        conn_rec *c = r->connection;
        int counter;
        char *buf;
        apr_table_t *saved_headers_in = r->headers_in;
        const char *saved_host = apr_table_get(saved_headers_in, "Host");
        const apr_array_header_t *headers_in_array;
        const apr_table_entry_t *headers_in;
        apr_bucket *e;
        int force10 = 0, do_100_continue = 0;
        conn_rec *origin = p_conn->connection;
        const char *host, *creds, *val;
        proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
    
        /*
         * HTTP "Ping" test? Easiest is 100-Continue. However:
         * To be compliant, we only use 100-Continue for requests with bodies.
         * We also make sure we won't be talking HTTP/1.0 as well.
         */
        if (apr_table_get(r->subprocess_env, "force-proxy-request-1.0")) {
            force10 = 1;
        }
        else if (apr_table_get(r->notes, "proxy-100-continue")
                 || PROXY_SHOULD_PING_100_CONTINUE(worker, r)) {
            do_100_continue = 1;
        }
        if (force10 || apr_table_get(r->subprocess_env, "proxy-nokeepalive")) {
            if (origin) {
                origin->keepalive = AP_CONN_CLOSE;
            }
            p_conn->close = 1;
        }
    
        if (force10) {
            buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.0" CRLF, NULL);
        }
        else {
            buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.1" 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);
    
        /*
         * Make a copy on r->headers_in for the request we make to the backend,
         * modify the copy in place according to our configuration and connection
         * handling, use it to fill in the forwarded headers' brigade, and finally
         * restore the saved/original ones in r->headers_in.
         *
         * Note: We need to take r->pool for apr_table_copy as the key / value
         * pairs in r->headers_in have been created out of r->pool and
         * p might be (and actually is) a longer living pool.
         * This would trigger the bad pool ancestry abort in apr_table_copy if
         * apr is compiled with APR_POOL_DEBUG.
         *
         * icing: if p indeed lives longer than r->pool, we should allocate
         * all new header values from r->pool as well and avoid leakage.
         */
        r->headers_in = apr_table_copy(r->pool, saved_headers_in);
    
        /* Return the original Transfer-Encoding and/or Content-Length values
         * then drop the headers, they must be set by the proxy handler based
         * on the actual body being forwarded.
         */
        if ((*old_te_val = (char *)apr_table_get(r->headers_in,
                                                 "Transfer-Encoding"))) {
            apr_table_unset(r->headers_in, "Transfer-Encoding");
        }
        if ((*old_cl_val = (char *)apr_table_get(r->headers_in,
                                                 "Content-Length"))) {
            apr_table_unset(r->headers_in, "Content-Length");
        }
    
        /* Clear out hop-by-hop request headers not to forward */
        if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
            rc = HTTP_BAD_REQUEST;
            goto cleanup;
        }
    
        /* RFC2616 13.5.1 says we should strip these */
        apr_table_unset(r->headers_in, "Keep-Alive");
        apr_table_unset(r->headers_in, "Upgrade");
        apr_table_unset(r->headers_in, "Trailer");
        apr_table_unset(r->headers_in, "TE");
    
        /* Compute Host header */
        if (dconf->preserve_host == 0) {
            if (!uri->hostname) {
                rc = HTTP_BAD_REQUEST;
                goto cleanup;
            }
            if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */
                if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
                    host = apr_pstrcat(r->pool, "[", uri->hostname, "]:",
                                       uri->port_str, NULL);
                } else {
                    host = apr_pstrcat(r->pool, "[", uri->hostname, "]", NULL);
                }
            } else {
                if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
                    host = apr_pstrcat(r->pool, uri->hostname, ":",
                                       uri->port_str, NULL);
                } else {
                    host = uri->hostname;
                }
            }
            apr_table_setn(r->headers_in, "Host", host);
        }
        else {
            /* don't want to use r->hostname as the incoming header might have a
             * port attached, let's use the original header.
             */
            host = saved_host;
            if (!host) {
                host =  r->server->server_hostname;
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01092)
                              "no HTTP 0.9 request (with no host line) "
                              "on incoming request and preserve host set "
                              "forcing hostname to be %s for uri %s",
                              host, r->uri);
                apr_table_setn(r->headers_in, "Host", host);
            }
        }
    
        /* 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)
                             );
        }
    
        /* Use HTTP/1.1 100-Continue as quick "HTTP ping" test
         * to backend
         */
        if (do_100_continue) {
            /* Add the Expect header if not already there. */
            if (!(val = apr_table_get(r->headers_in, "Expect"))
                || (ap_cstr_casecmp(val, "100-Continue") != 0 /* fast path */
                    && !ap_find_token(r->pool, val, "100-Continue"))) {
                apr_table_mergen(r->headers_in, "Expect", "100-Continue");
            }
        }
        else {
            /* XXX: we should strip the 100-continue token only from the
             * Expect header, but are there others actually used anywhere?
             */
            apr_table_unset(r->headers_in, "Expect");
        }
    
        /* 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 configuration instead of X-Forwarded-*. See the
         * ProxyVia option for details.
         */
        if (dconf->add_forwarded_headers) {
            if (PROXYREQ_REVERSE == r->proxyreq) {
                /* 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->useragent_ip);
    
                /* Add X-Forwarded-Host: so that upstream knows what the
                 * original request hostname was.
                 */
                if (saved_host) {
                    apr_table_mergen(r->headers_in, "X-Forwarded-Host",
                                     saved_host);
                }
    
                /* 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);
            }
        }
    
        /* Do we want to strip Proxy-Authorization ?
         * If we haven't used it, then NO
         * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
         * So let's make it configurable by env.
         */
        if (r->user != NULL /* we've authenticated */
            && !apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
            apr_table_unset(r->headers_in, "Proxy-Authorization");
        }
    
        /* for sub-requests, ignore freshness/expiry headers */
        if (r->main) {
            apr_table_unset(r->headers_in, "If-Match");
            apr_table_unset(r->headers_in, "If-Modified-Since");
            apr_table_unset(r->headers_in, "If-Range");
            apr_table_unset(r->headers_in, "If-Unmodified-Since");
            apr_table_unset(r->headers_in, "If-None-Match");
        }
    
        creds = apr_table_get(r->notes, "proxy-basic-creds");
        if (creds) {
            apr_table_mergen(r->headers_in, "Proxy-Authorization", creds);
        }
    
        /* run hook to fixup the request we are about to send */
        proxy_run_fixups(r);
    
        /* We used to send `Host: ` always first, so let's keep it that
         * way. No telling which legacy backend is relying on this.
         * If proxy_run_fixups() changed the value, use it (though removal
         * is ignored).
         */
        val = apr_table_get(r->headers_in, "Host");
        if (val) {
            apr_table_unset(r->headers_in, "Host");
            host = val;
        }
        buf = apr_pstrcat(p, "Host: ", host, 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);
    
        /* Append the (remaining) headers to the brigade */
        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) {
                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);
        }
    
    cleanup:
        r->headers_in = saved_headers_in;
        return rc;
    }
    
    PROXY_DECLARE(int) ap_proxy_prefetch_input(request_rec *r,
                                               proxy_conn_rec *backend,
                                               apr_bucket_brigade *input_brigade,
                                               apr_read_type_e block,
                                               apr_off_t *bytes_read,
                                               apr_off_t max_read)
    {
        apr_pool_t *p = r->pool;
        conn_rec *c = r->connection;
        apr_bucket_brigade *temp_brigade;
        apr_status_t status;
        apr_off_t bytes;
    
        *bytes_read = 0;
        if (max_read < APR_BUCKET_BUFF_SIZE) {
            max_read = APR_BUCKET_BUFF_SIZE;
        }
    
        /* Prefetch max_read bytes
         *
         * This helps us avoid any election of C-L v.s. T-E
         * request bodies, since we are willing to keep in
         * memory this much data, in any case.  This gives
         * us an instant C-L election if the body is of some
         * reasonable size.
         */
        temp_brigade = apr_brigade_create(p, input_brigade->bucket_alloc);
    
        /* Account for saved input, if any. */
        apr_brigade_length(input_brigade, 0, bytes_read);
    
        /* Ensure we don't hit a wall where we have a buffer too small for
         * ap_get_brigade's filters to fetch us another bucket, surrender
         * once we hit 80 bytes (an arbitrary value) less than max_read.
         */
        while (*bytes_read < max_read - 80
               && (APR_BRIGADE_EMPTY(input_brigade)
                   || !APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade)))) {
            status = ap_get_brigade(r->input_filters, temp_brigade,
                                    AP_MODE_READBYTES, block,
                                    max_read - *bytes_read);
            /* ap_get_brigade may return success with an empty brigade
             * for a non-blocking read which would block
             */
            if (block == APR_NONBLOCK_READ
                    && ((status == APR_SUCCESS && APR_BRIGADE_EMPTY(temp_brigade))
                        || APR_STATUS_IS_EAGAIN(status))) {
                break;
            }
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01095)
                              "prefetch request body failed to %pI (%s)"
                              " from %s (%s)", backend->addr,
                              backend->hostname ? backend->hostname : "",
                              c->client_ip, c->remote_host ? c->remote_host : "");
                return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
            }
    
            apr_brigade_length(temp_brigade, 1, &bytes);
            *bytes_read += bytes;
    
            /*
             * Save temp_brigade in input_brigade. (At least) in the SSL case
             * temp_brigade contains transient buckets whose data would get
             * overwritten during the next call of ap_get_brigade in the loop.
             * ap_save_brigade ensures these buckets to be set aside.
             * Calling ap_save_brigade with NULL as filter is OK, because
             * input_brigade already has been created and does not need to get
             * created by ap_save_brigade.
             */
            status = ap_save_brigade(NULL, &input_brigade, &temp_brigade, p);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01096)
                              "processing prefetched request body failed"
                              " to %pI (%s) from %s (%s)", backend->addr,
                              backend->hostname ? backend->hostname : "",
                              c->client_ip, c->remote_host ? c->remote_host : "");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        return OK;
    }
    
    PROXY_DECLARE(int) ap_proxy_read_input(request_rec *r,
                                           proxy_conn_rec *backend,
                                           apr_bucket_brigade *bb,
                                           apr_off_t max_read)
    {
        apr_bucket_alloc_t *bucket_alloc = bb->bucket_alloc;
        apr_read_type_e block = (backend->connection) ? APR_NONBLOCK_READ
                                                      : APR_BLOCK_READ;
        apr_status_t status;
        int rv;
    
        for (;;) {
            apr_brigade_cleanup(bb);
            status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
                                    block, max_read);
            if (block == APR_BLOCK_READ
                    || (!(status == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))
                        && !APR_STATUS_IS_EAGAIN(status))) {
                break;
            }
    
            /* Flush and retry (blocking) */
            apr_brigade_cleanup(bb);
            rv = ap_proxy_pass_brigade(bucket_alloc, r, backend,
                                       backend->connection, bb, 1);
            if (rv != OK) {
                return rv;
            }
            block = APR_BLOCK_READ;
        }
    
        if (status != APR_SUCCESS) {
            conn_rec *c = r->connection;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02608)
                          "read request body failed to %pI (%s)"
                          " from %s (%s)", backend->addr,
                          backend->hostname ? backend->hostname : "",
                          c->client_ip, c->remote_host ? c->remote_host : "");
            return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
        }
    
        return OK;
    }
    
    PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r,
                                            proxy_conn_rec *backend,
                                            apr_bucket_brigade *input_brigade,
                                            apr_off_t *bytes_spooled,
                                            apr_off_t max_mem_spool)
    {
        apr_pool_t *p = r->pool;
        int seen_eos = 0, rv = OK;
        apr_status_t status = APR_SUCCESS;
        apr_bucket_alloc_t *bucket_alloc = input_brigade->bucket_alloc;
        apr_bucket_brigade *body_brigade;
        apr_bucket *e;
        apr_off_t bytes, fsize = 0;
        apr_file_t *tmpfile = NULL;
    
        *bytes_spooled = 0;
        body_brigade = apr_brigade_create(p, bucket_alloc);
    
        do {
            if (APR_BRIGADE_EMPTY(input_brigade)) {
                rv = ap_proxy_read_input(r, backend, input_brigade,
                                         HUGE_STRING_LEN);
                if (rv != OK) {
                    return rv;
                }
            }
    
            /* If this brigade contains EOS, either stop or remove it. */
            if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
                seen_eos = 1;
            }
    
            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 */
                if (tmpfile == NULL) {
                    const char *temp_dir;
                    char *template;
    
                    status = apr_temp_dir_get(&temp_dir, p);
                    if (status != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01089)
                                      "search for temporary directory failed");
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                    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_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01090)
                                      "creation of temporary file in directory "
                                      "%s failed", temp_dir);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                }
                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_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01091)
                                      "write to temporary file %s failed",
                                      tmpfile_name);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                    AP_DEBUG_ASSERT(bytes_read == bytes_written);
                    fsize += bytes_written;
                }
                apr_brigade_cleanup(input_brigade);
            }
            else {
    
                /*
                 * Save input_brigade in body_brigade. (At least) in the SSL case
                 * input_brigade contains transient buckets whose data would get
                 * overwritten during the next call of ap_get_brigade in the loop.
                 * ap_save_brigade ensures these buckets to be set aside.
                 * Calling ap_save_brigade with NULL as filter is OK, because
                 * body_brigade already has been created and does not need to get
                 * created by ap_save_brigade.
                 */
                status = ap_save_brigade(NULL, &body_brigade, &input_brigade, p);
                if (status != APR_SUCCESS) {
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
            }
    
            *bytes_spooled += bytes;
        } while (!seen_eos);
    
        APR_BRIGADE_CONCAT(input_brigade, body_brigade);
        if (tmpfile) {
            apr_brigade_insert_file(input_brigade, tmpfile, 0, fsize, p);
        }
        if (apr_table_get(r->subprocess_env, "proxy-sendextracrlf")) {
            e = apr_bucket_immortal_create(CRLF_ASCII, 2, bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(input_brigade, e);
        }
        if (tmpfile) {
            /* We dropped metadata buckets when spooling to tmpfile,
             * terminate with EOS to allow for flushing in a one go.
             */
            e = apr_bucket_eos_create(bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(input_brigade, e);
        }
        return OK;
    }
    
    PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucket_alloc_t *bucket_alloc,
                                             request_rec *r, proxy_conn_rec *p_conn,
                                             conn_rec *origin, apr_bucket_brigade *bb,
                                             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(bb, e);
        }
        apr_brigade_length(bb, 0, &transferred);
        if (transferred != -1)
            p_conn->worker->s->transferred += transferred;
        status = ap_pass_brigade(origin->output_filters, bb);
        /* Cleanup the brigade now to avoid buckets lifetime
         * issues in case of error returned below. */
        apr_brigade_cleanup(bb);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01084)
                          "pass request body failed to %pI (%s)",
                          p_conn->addr, p_conn->hostname);
            if (origin->aborted) {
                const char *ssl_note;
    
                if (((ssl_note = apr_table_get(origin->notes, "SSL_connect_rv"))
                     != NULL) && (strcmp(ssl_note, "err") == 0)) {
                    return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
                                         "Error during SSL Handshake with"
                                         " remote server");
                }
                return APR_STATUS_IS_TIMEUP(status) ? HTTP_GATEWAY_TIME_OUT : HTTP_BAD_GATEWAY;
            }
            else {
                return HTTP_BAD_REQUEST;
            }
        }
        return OK;
    }
    
    /* Fill in unknown schemes from apr_uri_port_of_scheme() */
    
    typedef struct proxy_schemes_t {
        const char *name;
        apr_port_t default_port;
    } proxy_schemes_t ;
    
    static proxy_schemes_t pschemes[] =
    {
        {"fcgi",     8000},
        {"ajp",      AJP13_DEF_PORT},
        {"scgi",     SCGI_DEF_PORT},
        {"h2c",      DEFAULT_HTTP_PORT},
        {"h2",       DEFAULT_HTTPS_PORT},
        {"ws",       DEFAULT_HTTP_PORT},
        {"wss",      DEFAULT_HTTPS_PORT},
        { NULL, 0xFFFF }     /* unknown port */
    };
    
    PROXY_DECLARE(apr_port_t) ap_proxy_port_of_scheme(const char *scheme)
    {
        if (scheme) {
            apr_port_t port;
            if ((port = apr_uri_port_of_scheme(scheme)) != 0) {
                return port;
            } else {
                proxy_schemes_t *pscheme;
                for (pscheme = pschemes; pscheme->name != NULL; ++pscheme) {
                    if (ap_cstr_casecmp(scheme, pscheme->name) == 0) {
                        return pscheme->default_port;
                    }
                }
            }
        }
        return 0;
    }
    
    static APR_INLINE int ap_filter_should_yield(ap_filter_t *f)
    {
        return f->c->data_in_output_filters;
    }
    
    static APR_INLINE int ap_filter_output_pending(conn_rec *c)
    {
        ap_filter_t *f = c->output_filters;
        while (f->next) {
            f = f->next;
        }
        if (f->frec->filter_func.out_func(f, NULL)) {
            return AP_FILTER_ERROR;
        }
        return c->data_in_output_filters ? OK : DECLINED;
    }
    
    PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifetime_transform(request_rec *r,
                                                          apr_bucket_brigade *from,
                                                          apr_bucket_brigade *to)
    {
        apr_bucket *e;
        apr_bucket *new;
        const char *data;
        apr_size_t bytes;
        apr_status_t rv = APR_SUCCESS;
        apr_bucket_alloc_t *bucket_alloc = to->bucket_alloc;
    
        apr_brigade_cleanup(to);
        for (e = APR_BRIGADE_FIRST(from);
             e != APR_BRIGADE_SENTINEL(from);
             e = APR_BUCKET_NEXT(e)) {
            if (!APR_BUCKET_IS_METADATA(e)) {
                apr_bucket_read(e, &data, &bytes, APR_BLOCK_READ);
                new = apr_bucket_transient_create(data, bytes, bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(to, new);
            }
            else if (APR_BUCKET_IS_FLUSH(e)) {
                new = apr_bucket_flush_create(bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(to, new);
            }
            else if (APR_BUCKET_IS_EOS(e)) {
                new = apr_bucket_eos_create(bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(to, new);
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03304)
                              "Unhandled bucket type of type %s in"
                              " ap_proxy_buckets_lifetime_transform", e->type->name);
                rv = APR_EGENERAL;
            }
        }
        return rv;
    }
    
    /* An arbitrary large value to address pathological case where we keep
     * reading from one side only, without scheduling the other direction for
     * too long. This can happen with large MTU and small read buffers, like
     * micro-benchmarking huge files bidirectional transfer with client, proxy
     * and backend on localhost for instance. Though we could just ignore the
     * case and let the sender stop by itself at some point when/if it needs to
     * receive data, or the receiver stop when/if it needs to send...
     */
    #define PROXY_TRANSFER_MAX_READS 10000
    
    PROXY_DECLARE(apr_status_t) ap_proxy_transfer_between_connections(
                                                           request_rec *r,
                                                           conn_rec *c_i,
                                                           conn_rec *c_o,
                                                           apr_bucket_brigade *bb_i,
                                                           apr_bucket_brigade *bb_o,
                                                           const char *name,
                                                           int *sent,
                                                           apr_off_t bsize,
                                                           int flags)
    {
        apr_status_t rv;
        int flush_each = 0;
        unsigned int num_reads = 0;
    #ifdef DEBUGGING
        apr_off_t len;
    #endif
    
        /*
         * Compat: since FLUSH_EACH is default (and zero) for legacy reasons, we
         * pretend it's no FLUSH_AFTER nor YIELD_PENDING flags, the latter because
         * flushing would defeat the purpose of checking for pending data (hence
         * determine whether or not the output chain/stack is full for stopping).
         */
        if (!(flags & (AP_PROXY_TRANSFER_FLUSH_AFTER |
                       AP_PROXY_TRANSFER_YIELD_PENDING))) {
            flush_each = 1;
        }
    
        for (;;) {
            apr_brigade_cleanup(bb_i);
            rv = ap_get_brigade(c_i->input_filters, bb_i, AP_MODE_READBYTES,
                                APR_NONBLOCK_READ, bsize);
            if (rv != APR_SUCCESS) {
                if (!APR_STATUS_IS_EAGAIN(rv) && !APR_STATUS_IS_EOF(rv)) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(03308)
                                  "ap_proxy_transfer_between_connections: "
                                  "error on %s - ap_get_brigade",
                                  name);
                    if (rv == APR_INCOMPLETE) {
                        /* Don't return APR_INCOMPLETE, it'd mean "should yield"
                         * for the caller, while it means "incomplete body" here
                         * from ap_http_filter(), which is an error.
                         */
                        rv = APR_EGENERAL;
                    }
                }
                break;
            }
    
            if (c_o->aborted) {
                apr_brigade_cleanup(bb_i);
                flags &= ~AP_PROXY_TRANSFER_FLUSH_AFTER;
                rv = APR_EPIPE;
                break;
            }
            if (APR_BRIGADE_EMPTY(bb_i)) {
                break;
            }
    #ifdef DEBUGGING
            len = -1;
            apr_brigade_length(bb_i, 0, &len);
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03306)
                          "ap_proxy_transfer_between_connections: "
                          "read %" APR_OFF_T_FMT
                          " bytes from %s", len, name);
    #endif
            if (sent) {
                *sent = 1;
            }
            ap_proxy_buckets_lifetime_transform(r, bb_i, bb_o);
            if (flush_each) {
                apr_bucket *b;
                /*
                 * Do not use ap_fflush here since this would cause the flush
                 * bucket to be sent in a separate brigade afterwards which
                 * causes some filters to set aside the buckets from the first
                 * brigade and process them when FLUSH arrives in the second
                 * brigade. As set asides of our transformed buckets involve
                 * memory copying we try to avoid this. If we have the flush
                 * bucket in the first brigade they directly process the
                 * buckets without setting them aside.
                 */
                b = apr_bucket_flush_create(bb_o->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb_o, b);
            }
            rv = ap_pass_brigade(c_o->output_filters, bb_o);
            apr_brigade_cleanup(bb_o);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(03307)
                              "ap_proxy_transfer_between_connections: "
                              "error on %s - ap_pass_brigade",
                              name);
                flags &= ~AP_PROXY_TRANSFER_FLUSH_AFTER;
                break;
            }
    
            /* Yield if the output filters stack is full? This is to avoid
             * blocking and give the caller a chance to POLLOUT async.
             */
            if ((flags & AP_PROXY_TRANSFER_YIELD_PENDING)
                    && ap_filter_should_yield(c_o->output_filters)) {
                int rc = ap_filter_output_pending(c_o);
                if (rc == OK) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                                  "ap_proxy_transfer_between_connections: "
                                  "yield (output pending)");
                    rv = APR_INCOMPLETE;
                    break;
                }
                if (rc != DECLINED) {
                    rv = AP_FILTER_ERROR;
                    break;
                }
            }
    
            /* Yield if we keep hold of the thread for too long? This gives
             * the caller a chance to schedule the other direction too.
             */
            if ((flags & AP_PROXY_TRANSFER_YIELD_MAX_READS)
                    && ++num_reads > PROXY_TRANSFER_MAX_READS) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "ap_proxy_transfer_between_connections: "
                              "yield (max reads)");
                rv = APR_SUCCESS;
                break;
            }
        }
    
        if (flags & AP_PROXY_TRANSFER_FLUSH_AFTER) {
            ap_fflush(c_o->output_filters, bb_o);
            apr_brigade_cleanup(bb_o);
        }
        apr_brigade_cleanup(bb_i);
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, rv, r,
                      "ap_proxy_transfer_between_connections complete (%s %pI)",
                      (c_i == r->connection) ? "to" : "from",
                      (c_i == r->connection) ? c_o->client_addr
                                             : c_i->client_addr);
    
        if (APR_STATUS_IS_EAGAIN(rv)) {
            rv = APR_SUCCESS;
        }
        return rv;
    }
    
    struct proxy_tunnel_conn {
        /* the other side of the tunnel */
        struct proxy_tunnel_conn *other;
    
        conn_rec *c;
        const char *name;
    
        apr_pollfd_t *pfd;
        apr_bucket_brigade *bb;
    
        unsigned int down_in:1,
                     down_out:1;
    };
    
    PROXY_DECLARE(apr_status_t) ap_proxy_tunnel_create(proxy_tunnel_rec **ptunnel,
                                                       request_rec *r, conn_rec *c_o,
                                                       const char *scheme)
    {
        apr_status_t rv;
        conn_rec *c_i = r->connection;
        apr_interval_time_t client_timeout = -1, origin_timeout = -1;
        proxy_tunnel_rec *tunnel;
    
        *ptunnel = NULL;
    
        tunnel = apr_pcalloc(r->pool, sizeof(*tunnel));
    
        rv = apr_pollset_create(&tunnel->pollset, 2, r->pool, APR_POLLSET_NOCOPY);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        tunnel->r = r;
        tunnel->scheme = apr_pstrdup(r->pool, scheme);
        tunnel->client = apr_pcalloc(r->pool, sizeof(struct proxy_tunnel_conn));
        tunnel->origin = apr_pcalloc(r->pool, sizeof(struct proxy_tunnel_conn));
        tunnel->pfds = apr_array_make(r->pool, 2, sizeof(apr_pollfd_t));
        tunnel->read_buf_size = ap_get_read_buf_size(r);
        tunnel->client->other = tunnel->origin;
        tunnel->origin->other = tunnel->client;
        tunnel->timeout = -1;
    
        tunnel->client->c = c_i;
        tunnel->client->name = "client";
        tunnel->client->bb = apr_brigade_create(c_i->pool, c_i->bucket_alloc);
        tunnel->client->pfd = &APR_ARRAY_PUSH(tunnel->pfds, apr_pollfd_t);
        tunnel->client->pfd->p = r->pool;
        tunnel->client->pfd->desc_type = APR_NO_DESC;
        rv = ap_get_pollfd_from_conn(tunnel->client->c,
                                     tunnel->client->pfd, &client_timeout);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        tunnel->client->pfd->client_data = tunnel->client;
        if (tunnel->client->pfd->desc_type == APR_POLL_SOCKET) {
            apr_socket_opt_set(tunnel->client->pfd->desc.s, APR_SO_NONBLOCK, 1);
        }
    
        tunnel->origin->c = c_o;
        tunnel->origin->name = "origin";
        tunnel->origin->bb = apr_brigade_create(c_o->pool, c_o->bucket_alloc);
        tunnel->origin->pfd = &APR_ARRAY_PUSH(tunnel->pfds, apr_pollfd_t);
        tunnel->origin->pfd->p = r->pool;
        tunnel->origin->pfd->desc_type = APR_POLL_SOCKET;
        tunnel->origin->pfd->desc.s = ap_get_conn_socket(c_o);
        tunnel->origin->pfd->client_data = tunnel->origin;
        apr_socket_timeout_get(tunnel->origin->pfd->desc.s, &origin_timeout);
        apr_socket_opt_set(tunnel->origin->pfd->desc.s, APR_SO_NONBLOCK, 1);
    
        /* Defaults to the largest timeout of both connections */
        tunnel->timeout = (client_timeout >= 0 && client_timeout > origin_timeout ?
                           client_timeout : origin_timeout);
    
        /* No coalescing filters */
        ap_remove_output_filter_byhandle(c_i->output_filters,
                                         "SSL/TLS Coalescing Filter");
        ap_remove_output_filter_byhandle(c_o->output_filters,
                                         "SSL/TLS Coalescing Filter");
    
        /* Bidirectional non-HTTP stream will confuse mod_reqtimeoout */
        ap_remove_input_filter_byhandle(c_i->input_filters, "reqtimeout");
    
        /* The input/output filter stacks should contain connection filters only */
        r->input_filters = r->proto_input_filters = c_i->input_filters;
        r->output_filters = r->proto_output_filters = c_i->output_filters;
    
        /* Won't be reused after tunneling */
        c_i->keepalive = AP_CONN_CLOSE;
        c_o->keepalive = AP_CONN_CLOSE;
    
        /* Disable half-close forwarding for this request? */
        if (apr_table_get(r->subprocess_env, "proxy-nohalfclose")) {
            tunnel->nohalfclose = 1;
        }
    
        if (tunnel->client->pfd->desc_type == APR_POLL_SOCKET) {
            /* Both ends are sockets, the poll strategy is:
             * - poll both sides POLLOUT
             * - when one side is writable, remove the POLLOUT
             *   and add POLLIN to the other side.
             * - tunnel arriving data, remove POLLIN from the source
             *   again and add POLLOUT to the receiving side
             * - on EOF on read, remove the POLLIN from that side
             * Repeat until both sides are down */
            tunnel->client->pfd->reqevents = APR_POLLOUT | APR_POLLERR;
            tunnel->origin->pfd->reqevents = APR_POLLOUT | APR_POLLERR;
            if ((rv = apr_pollset_add(tunnel->pollset, tunnel->origin->pfd)) ||
                (rv = apr_pollset_add(tunnel->pollset, tunnel->client->pfd))) {
                return rv;
            }
        }
        else if (tunnel->client->pfd->desc_type == APR_POLL_FILE) {
            /* Input is a PIPE fd, the poll strategy is:
             * - always POLLIN on origin
             * - use socket strategy described above for client only
             * otherwise the same
             */
            tunnel->client->pfd->reqevents = 0;
            tunnel->origin->pfd->reqevents = APR_POLLIN | APR_POLLHUP |
                                             APR_POLLOUT | APR_POLLERR;
            if ((rv = apr_pollset_add(tunnel->pollset, tunnel->origin->pfd))) {
                return rv;
            }
        }
        else {
            /* input is already closed, unsual, but we know nothing about
             * the tunneled protocol. */
            tunnel->client->down_in = 1;
            tunnel->origin->pfd->reqevents = APR_POLLIN | APR_POLLHUP;
            if ((rv = apr_pollset_add(tunnel->pollset, tunnel->origin->pfd))) {
                return rv;
            }
        }
    
        *ptunnel = tunnel;
        return APR_SUCCESS;
    }
    
    static void add_pollset(apr_pollset_t *pollset, apr_pollfd_t *pfd,
                            apr_int16_t events)
    {
        apr_status_t rv;
    
        AP_DEBUG_ASSERT((pfd->reqevents & events) == 0);
    
        if (pfd->reqevents) {
            rv = apr_pollset_remove(pollset, pfd);
            if (rv != APR_SUCCESS) {
                AP_DEBUG_ASSERT(1);
            }
        }
    
        if (events & APR_POLLIN) {
            events |= APR_POLLHUP;
        }
        pfd->reqevents |= events | APR_POLLERR;
        rv = apr_pollset_add(pollset, pfd);
        if (rv != APR_SUCCESS) {
            AP_DEBUG_ASSERT(1);
        }
    }
    
    static void del_pollset(apr_pollset_t *pollset, apr_pollfd_t *pfd,
                            apr_int16_t events)
    {
        apr_status_t rv;
    
        AP_DEBUG_ASSERT((pfd->reqevents & events) != 0);
    
        rv = apr_pollset_remove(pollset, pfd);
        if (rv != APR_SUCCESS) {
            AP_DEBUG_ASSERT(0);
            return;
        }
    
        if (events & APR_POLLIN) {
            events |= APR_POLLHUP;
        }
        if (pfd->reqevents & ~(events | APR_POLLERR)) {
            pfd->reqevents &= ~events;
            rv = apr_pollset_add(pollset, pfd);
            if (rv != APR_SUCCESS) {
                AP_DEBUG_ASSERT(0);
                return;
            }
        }
        else {
            pfd->reqevents = 0;
        }
    }
    
    static int proxy_tunnel_forward(proxy_tunnel_rec *tunnel,
                                     struct proxy_tunnel_conn *in)
    {
        struct proxy_tunnel_conn *out = in->other;
        apr_status_t rv;
        int sent = 0;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, tunnel->r,
                      "proxy: %s: %s input ready",
                      tunnel->scheme, in->name);
    
        rv = ap_proxy_transfer_between_connections(tunnel->r,
                                                   in->c, out->c,
                                                   in->bb, out->bb,
                                                   in->name, &sent,
                                                   tunnel->read_buf_size,
                                               AP_PROXY_TRANSFER_YIELD_PENDING |
                                               AP_PROXY_TRANSFER_YIELD_MAX_READS);
        if (sent && out == tunnel->client) {
            tunnel->replied = 1;
        }
        if (rv != APR_SUCCESS) {
            if (APR_STATUS_IS_INCOMPLETE(rv)) {
                /* Pause POLLIN while waiting for POLLOUT on the other
                 * side, hence avoid filling the output filters even
                 * more to avoid blocking there.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, tunnel->r,
                              "proxy: %s: %s wait writable",
                              tunnel->scheme, out->name);
            }
            else if (APR_STATUS_IS_EOF(rv)) {
                /* Stop POLLIN and wait for POLLOUT (flush) on the
                 * other side to shut it down.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, tunnel->r,
                              "proxy: %s: %s read shutdown",
                              tunnel->scheme, in->name);
                if (tunnel->nohalfclose) {
                    /* No half-close forwarding, we are done both ways as
                     * soon as one side shuts down.
                     */
                    return DONE;
                }
                in->down_in = 1;
            }
            else {
                /* Real failure, bail out */
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            del_pollset(tunnel->pollset, in->pfd, APR_POLLIN);
            if (out->pfd->desc_type == APR_POLL_SOCKET) {
                /* if the output is a SOCKET, we can stop polling the input
                 * until the output signals POLLOUT again. */
                add_pollset(tunnel->pollset, out->pfd, APR_POLLOUT);
            }
            else {
                /* We can't use POLLOUT in this direction for the only
                 * APR_POLL_FILE case we have so far (mod_h2's "signal" pipe),
                 * we assume that the client's ouput filters chain will block/flush
                 * if necessary (i.e. no pending data), hence that the origin
                 * is EOF when reaching here. This direction is over. */
                ap_assert(in->down_in && APR_STATUS_IS_EOF(rv));
                ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, tunnel->r,
                              "proxy: %s: %s write shutdown",
                              tunnel->scheme, out->name);
                out->down_out = 1;
            }
        }
    
        return OK;
    }
    
    PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel)
    {
        int status = OK, rc;
        request_rec *r = tunnel->r;
        apr_pollset_t *pollset = tunnel->pollset;
        struct proxy_tunnel_conn *client = tunnel->client,
                                 *origin = tunnel->origin;
        apr_interval_time_t timeout = tunnel->timeout >= 0 ? tunnel->timeout : -1;
        const char *scheme = tunnel->scheme;
        apr_status_t rv;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10212)
                      "proxy: %s: tunnel running (timeout %lf)",
                      scheme, timeout >= 0 ? (double)timeout / APR_USEC_PER_SEC
                                           : (double)-1.0);
    
        /* Loop until both directions of the connection are closed,
         * or a failure occurs.
         */
        do {
            const apr_pollfd_t *results;
            apr_int32_t nresults, i;
    
            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
                          "proxy: %s: polling (client=%hx, origin=%hx)",
                          scheme, client->pfd->reqevents, origin->pfd->reqevents);
            do {
                rv = apr_pollset_poll(pollset, timeout, &nresults, &results);
            } while (APR_STATUS_IS_EINTR(rv));
    
            if (rv != APR_SUCCESS) {
                if (APR_STATUS_IS_TIMEUP(rv)) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, APLOGNO(10213)
                                  "proxy: %s: polling timed out "
                                  "(client=%hx, origin=%hx)",
                                  scheme, client->pfd->reqevents,
                                  origin->pfd->reqevents);
                    status = HTTP_GATEWAY_TIME_OUT;
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10214)
                                  "proxy: %s: polling failed", scheme);
                    status = HTTP_INTERNAL_SERVER_ERROR;
                }
                goto done;
            }
    
            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, APLOGNO(10215)
                          "proxy: %s: woken up, %i result(s)", scheme, nresults);
    
            for (i = 0; i < nresults; i++) {
                const apr_pollfd_t *pfd = &results[i];
                struct proxy_tunnel_conn *tc = pfd->client_data;
    
                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
                              "proxy: %s: #%i: %s: %hx/%hx", scheme, i,
                              tc->name, pfd->rtnevents, tc->pfd->reqevents);
    
                /* sanity check */
                if (pfd->desc.s != client->pfd->desc.s
                        && pfd->desc.s != origin->pfd->desc.s) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10222)
                                  "proxy: %s: unknown socket in pollset", scheme);
                    status = HTTP_INTERNAL_SERVER_ERROR;
                    goto done;
                }
    
                if (!(pfd->rtnevents & (APR_POLLIN  | APR_POLLOUT |
                                        APR_POLLHUP | APR_POLLERR))) {
                    /* this catches POLLNVAL etc.. */
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10220)
                                  "proxy: %s: polling events error (%x)",
                                  scheme, pfd->rtnevents);
                    status = HTTP_INTERNAL_SERVER_ERROR;
                    goto done;
                }
    
                /* We want to write if we asked for POLLOUT and got:
                 * - POLLOUT: the socket is ready for write;
                 * - !POLLIN: the socket is in error state (POLLERR) so we let
                 *   the user know by failing the write and log, OR the socket
                 *   is shutdown for read already (POLLHUP) so we have to
                 *   shutdown for write.
                 */
                if ((tc->pfd->reqevents & APR_POLLOUT)
                        && ((pfd->rtnevents & APR_POLLOUT)
                            || !(tc->pfd->reqevents & APR_POLLIN)
                            || !(pfd->rtnevents & (APR_POLLIN | APR_POLLHUP)))) {
                    struct proxy_tunnel_conn *out = tc, *in = tc->other;
    
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
                                  "proxy: %s: %s output ready",
                                  scheme, out->name);
    
                    rc = ap_filter_output_pending(out->c);
                    if (rc == OK) {
                        /* Keep polling out (only) */
                        continue;
                    }
                    if (rc != DECLINED) {
                        /* Real failure, bail out */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10221)
                                      "proxy: %s: %s flushing failed (%i)",
                                      scheme, out->name, rc);
                        status = rc;
                        goto done;
                    }
    
                    /* No more pending data. If the other side is not readable
                     * anymore it's time to shutdown for write (this direction
                     * is over). Otherwise back to normal business.
                     */
                    del_pollset(pollset, out->pfd, APR_POLLOUT);
                    if (in->down_in) {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                                      "proxy: %s: %s write shutdown",
                                      scheme, out->name);
                        apr_socket_shutdown(out->pfd->desc.s, 1);
                        out->down_out = 1;
                    }
                    else {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r,
                                      "proxy: %s: %s resume writable",
                                      scheme, out->name);
                        add_pollset(pollset, in->pfd, APR_POLLIN);
    
                        /* Flush any pending input data now, we don't know when
                         * the next POLLIN will trigger and retaining data might
                         * deadlock the underlying protocol. We don't check for
                         * pending data first with ap_filter_input_pending() since
                         * the read from proxy_tunnel_forward() is nonblocking
                         * anyway and returning OK if there's no data.
                         */
                        rc = proxy_tunnel_forward(tunnel, in);
                        if (rc != OK) {
                            status = rc;
                            goto done;
                        }
                    }
                }
    
                /* We want to read if we asked for POLLIN|HUP and got:
                 * - POLLIN|HUP: the socket is ready for read or EOF (POLLHUP);
                 * - !POLLOUT: the socket is in error state (POLLERR) so we let
                 *   the user know by failing the read and log.
                 */
                if ((tc->pfd->reqevents & APR_POLLIN)
                        && ((pfd->rtnevents & (APR_POLLIN | APR_POLLHUP))
                            || !(pfd->rtnevents & APR_POLLOUT))) {
                    rc = proxy_tunnel_forward(tunnel, tc);
                    if (rc != OK) {
                        status = rc;
                        goto done;
                    }
                }
            }
        } while (!client->down_out || !origin->down_out);
    
    done:
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10223)
                      "proxy: %s: tunneling returns (%i)", scheme, status);
        if (status == DONE) {
            status = OK;
        }
        return status;
    }
    
    PROXY_DECLARE (const char *) ap_proxy_show_hcmethod(hcmethod_t method)
    {
        proxy_hcmethods_t *m = proxy_hcmethods;
        for (; m->name; m++) {
            if (m->method == method) {
                return m->name;
            }
        }
        return "???";
    }
    
    void proxy_util_register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);
        APR_REGISTER_OPTIONAL_FN(ap_proxy_clear_connection);
        APR_REGISTER_OPTIONAL_FN(proxy_balancer_get_best_worker);
    
        {
            apr_time_t *start_time = ap_retained_data_get("proxy_start_time");
            if (start_time == NULL) {
                start_time = ap_retained_data_create("proxy_start_time",
                                                     sizeof(*start_time));
                *start_time = apr_time_now();
            }
            proxy_start_time = start_time;
        }
    }
    �������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_uwsgi.c��������������������������������������������������������0000664�0001751�0001751�00000044126�14603243511�021063� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_proxy_uwsgi ***
    
    Copyright 2009-2017 Unbit S.a.s. <info@unbit.it>
         
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT 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_MEMFUNC
    #define APR_WANT_STRFUNC
    #include "apr_strings.h"
    #include "apr_hooks.h"
    #include "apr_optional_hooks.h"
    #include "apr_buckets.h"
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "util_script.h"
    
    #include "mod_proxy.h"
    
    
    #define UWSGI_SCHEME "uwsgi"
    #define UWSGI_DEFAULT_PORT 3031
    
    module AP_MODULE_DECLARE_DATA proxy_uwsgi_module;
    
    
    static int uwsgi_canon(request_rec *r, char *url)
    {
        char *host, sport[sizeof(":65535")];
        const char *err, *path;
        apr_port_t port = UWSGI_DEFAULT_PORT;
    
        if (ap_cstr_casecmpn(url, UWSGI_SCHEME "://", sizeof(UWSGI_SCHEME) + 2)) {
            return DECLINED;
        }
        url += sizeof(UWSGI_SCHEME);        /* Keep slashes */
    
        err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10097)
                          "error parsing URL %s: %s", url, err);
            return HTTP_BAD_REQUEST;
        }
    
        if (port != UWSGI_DEFAULT_PORT)
            apr_snprintf(sport, sizeof(sport), ":%u", port);
        else
            sport[0] = '\0';
    
        if (ap_strchr(host, ':')) { /* if literal IPv6 address */
            host = apr_pstrcat(r->pool, "[", host, "]", NULL);
        }
    
        if (apr_table_get(r->notes, "proxy-nocanon")
            || apr_table_get(r->notes, "proxy-noencode")) {
            path = url;   /* this is the raw/encoded path */
        }
        else {
            core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
            int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
            path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
                                        r->proxyreq);
            if (!path) {
                return HTTP_BAD_REQUEST;
            }
        }
        /*
         * If we have a raw control character or a ' ' in nocanon path,
         * correct encoding was missed.
         */
        if (path == url && *ap_scan_vchar_obstext(path)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10417)
                          "To be forwarded path contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
    
        r->filename =
            apr_pstrcat(r->pool, "proxy:" UWSGI_SCHEME "://", host, sport, "/",
                        path, NULL);
    
        return OK;
    }
    
    
    static int uwsgi_send(proxy_conn_rec * conn, const char *buf,
                          apr_size_t length, request_rec *r)
    {
        apr_status_t rv;
        apr_size_t written;
    
        while (length > 0) {
            written = length;
            if ((rv = apr_socket_send(conn->sock, buf, &written)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10098)
                              "sending data to %s:%u failed",
                              conn->hostname, conn->port);
                return HTTP_SERVICE_UNAVAILABLE;
            }
    
            /* count for stats */
            conn->worker->s->transferred += written;
            buf += written;
            length -= written;
        }
    
        return OK;
    }
    
    
    /*
     * Send uwsgi header block
     */
    static int uwsgi_send_headers(request_rec *r, proxy_conn_rec * conn)
    {
        char *buf, *ptr;
    
        const apr_array_header_t *env_table;
        const apr_table_entry_t *env;
    
        int j;
    
        apr_size_t headerlen = 4;
        apr_size_t pktsize, keylen, vallen;
        const char *script_name;
        const char *path_info;
        const char *auth;
    
        ap_add_common_vars(r);
        ap_add_cgi_vars(r);
    
        /*
           this is not a security problem (in Linux) as uWSGI destroy the env memory area readable in /proc
           and generally if you host untrusted apps in your server and allows them to read others uid /proc/<pid>
           files you have higher problems...
         */
        auth = apr_table_get(r->headers_in, "Authorization");
        if (auth) {
            apr_table_setn(r->subprocess_env, "HTTP_AUTHORIZATION", auth);
        }
    
        script_name = apr_table_get(r->subprocess_env, "SCRIPT_NAME");
        path_info = apr_table_get(r->subprocess_env, "PATH_INFO");
    
        if (script_name && path_info) {
            if (strcmp(path_info, "/")) {
                apr_table_set(r->subprocess_env, "SCRIPT_NAME",
                              apr_pstrndup(r->pool, script_name,
                                           strlen(script_name) -
                                           strlen(path_info)));
            }
            else {
                if (!strcmp(script_name, "/")) {
                    apr_table_setn(r->subprocess_env, "SCRIPT_NAME", "");
                }
            }
        }
    
        env_table = apr_table_elts(r->subprocess_env);
        env = (apr_table_entry_t *) env_table->elts;
    
        for (j = 0; j < env_table->nelts; ++j) {
            headerlen += 2 + strlen(env[j].key) + 2 + (env[j].val ? strlen(env[j].val) : 0);
        }
    
        pktsize = headerlen - 4;
        if (pktsize > APR_UINT16_MAX) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10259)
                          "can't send headers to %s:%u: packet size too "
                          "large (%" APR_SIZE_T_FMT ")",
                          conn->hostname, conn->port, pktsize);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        ptr = buf = apr_palloc(r->pool, headerlen);
    
        ptr += 4;
    
        for (j = 0; j < env_table->nelts; ++j) {
            keylen = strlen(env[j].key);
            *ptr++ = (apr_byte_t) (keylen & 0xff);
            *ptr++ = (apr_byte_t) ((keylen >> 8) & 0xff);
            memcpy(ptr, env[j].key, keylen);
            ptr += keylen;
    
            vallen = env[j].val ? strlen(env[j].val) : 0;
            *ptr++ = (apr_byte_t) (vallen & 0xff);
            *ptr++ = (apr_byte_t) ((vallen >> 8) & 0xff);
            if (env[j].val) {
                memcpy(ptr, env[j].val, vallen);
            }
            ptr += vallen;
        }
    
        buf[0] = 0;
        buf[1] = (apr_byte_t) (pktsize & 0xff);
        buf[2] = (apr_byte_t) ((pktsize >> 8) & 0xff);
        buf[3] = 0;
    
        return uwsgi_send(conn, buf, headerlen, r);
    }
    
    
    static int uwsgi_send_body(request_rec *r, proxy_conn_rec * conn)
    {
        if (ap_should_client_block(r)) {
            char *buf = apr_palloc(r->pool, AP_IOBUFSIZE);
            int status;
            long readlen;
    
            readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
            while (readlen > 0) {
                status = uwsgi_send(conn, buf, (apr_size_t)readlen, r);
                if (status != OK) {
                    return HTTP_SERVICE_UNAVAILABLE;
                }
                readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
            }
            if (readlen == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10099)
                              "receiving request body failed");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        return OK;
    }
    
    static request_rec *make_fake_req(conn_rec *c, request_rec *r)
    {
        apr_pool_t *pool;
        request_rec *rp;
    
        apr_pool_create(&pool, c->pool);
        apr_pool_tag(pool, "proxy_uwsgi_rp");
    
        rp = apr_pcalloc(pool, sizeof(*r));
    
        rp->pool = pool;
        rp->status = HTTP_OK;
    
        rp->headers_in = apr_table_make(pool, 50);
        rp->subprocess_env = apr_table_make(pool, 50);
        rp->headers_out = apr_table_make(pool, 12);
        rp->err_headers_out = apr_table_make(pool, 5);
        rp->notes = apr_table_make(pool, 5);
    
        rp->server = r->server;
        rp->log = r->log;
        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->useragent_ip = c->client_ip;
        rp->useragent_addr = c->client_addr;
    
        rp->request_config = ap_create_request_config(pool);
        proxy_run_create_req(r, rp);
    
        return rp;
    }
    
    static int uwsgi_response(request_rec *r, proxy_conn_rec * backend,
                              proxy_server_conf * conf)
    {
    
        char buffer[HUGE_STRING_LEN];
        const char *buf;
        char *value, *end;
        char keepchar;
        int len;
        int backend_broke = 0;
        int status_start;
        int status_end;
        int finish = 0;
        conn_rec *c = r->connection;
        apr_off_t readbytes;
        apr_status_t rv;
        apr_bucket *e;
        apr_read_type_e mode = APR_NONBLOCK_READ;
        apr_bucket_brigade *pass_bb;
        apr_bucket_brigade *bb;
        proxy_dir_conf *dconf;
    
        request_rec *rp = make_fake_req(backend->connection, r);
        rp->proxyreq = PROXYREQ_RESPONSE;
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
        pass_bb = apr_brigade_create(r->pool, c->bucket_alloc);
    
        len = ap_getline(buffer, sizeof(buffer), rp, 1);
        if (len <= 0) {
            /* invalid or empty */
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        backend->worker->s->read += len;
        if ((apr_size_t)len >= sizeof(buffer)) {
            /* too long */
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* Position of http status code */
        if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) {
            status_start = 9;
        }
        else if (apr_date_checkmask(buffer, "HTTP/# ###*")) {
            status_start = 7;
        }
        else {
            /* not HTTP */
            return HTTP_BAD_GATEWAY;
        }
        status_end = status_start + 3;
    
        keepchar = buffer[status_end];
        buffer[status_end] = '\0';
        r->status = atoi(&buffer[status_start]);
    
        if (keepchar != '\0') {
            buffer[status_end] = 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[status_end] = ' ';
            buffer[status_end + 1] = '\0';
        }
        r->status_line = apr_pstrdup(r->pool, &buffer[status_start]);
    
        /* parse headers */
        while ((len = ap_getline(buffer, sizeof(buffer), rp, 1)) > 0) {
            if ((apr_size_t)len >= sizeof(buffer)) {
                /* too long */
                len = -1;
                break;
            }
            value = strchr(buffer, ':');
            if (!value) {
                /* invalid header */
                len = -1;
                break;
            }
            *value++ = '\0';
            if (*ap_scan_http_token(buffer)) {
                /* invalid name */
                len = -1;
                break;
            }
            while (apr_isspace(*value))
                ++value;
            for (end = &value[strlen(value) - 1];
                 end > value && apr_isspace(*end); --end)
                *end = '\0';
            if (*ap_scan_http_field_content(value)) {
                /* invalid value */
                len = -1;
                break;
            }
            apr_table_add(r->headers_out, buffer, value);
        }
        if (len < 0) {
            /* Reset headers, but not to NULL because things below the chain expect
             * this to be non NULL e.g. the ap_content_length_filter.
             */
            r->headers_out = apr_table_make(r->pool, 1);
            return HTTP_BAD_GATEWAY;
        }
    
        /* T-E wins over C-L */
        if (apr_table_get(r->headers_out, "Transfer-Encoding")) {
            apr_table_unset(r->headers_out, "Content-Length");
            backend->close = 1;
        }
    
        if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
            ap_set_content_type(r, apr_pstrdup(r->pool, buf));
        }
    
        /* honor ProxyErrorOverride and ErrorDocument */
    #if AP_MODULE_MAGIC_AT_LEAST(20101106,0)
        dconf =
            ap_get_module_config(r->per_dir_config, &proxy_module);
        if (ap_proxy_should_override(dconf, r->status)) {
    #else
        if (ap_proxy_should_override(conf, r->status)) {
    #endif
            int status = r->status;
            r->status = HTTP_OK;
            r->status_line = NULL;
    
            apr_brigade_cleanup(bb);
            apr_brigade_cleanup(pass_bb);
    
            return status;
        }
    
        while (!finish) {
            rv = ap_get_brigade(rp->input_filters, bb,
                                AP_MODE_READBYTES, mode, conf->io_buffer_size);
            if (APR_STATUS_IS_EAGAIN(rv)
                || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) {
                e = apr_bucket_flush_create(c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, e);
                if (ap_pass_brigade(r->output_filters, bb) || c->aborted) {
                    break;
                }
                apr_brigade_cleanup(bb);
                mode = APR_BLOCK_READ;
                continue;
            }
            else if (rv == APR_EOF) {
                break;
            }
            else if (rv != APR_SUCCESS) {
                ap_proxy_backend_broke(r, bb);
                ap_pass_brigade(r->output_filters, bb);
                backend_broke = 1;
                break;
            }
    
            mode = APR_NONBLOCK_READ;
            apr_brigade_length(bb, 0, &readbytes);
            backend->worker->s->read += readbytes;
    
            if (APR_BRIGADE_EMPTY(bb)) {
                apr_brigade_cleanup(bb);
                break;
            }
    
            ap_proxy_buckets_lifetime_transform(r, bb, pass_bb);
    
            /* found the last brigade? */
            if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb)))
                finish = 1;
    
            /* do not pass chunk if it is zero_sized */
            apr_brigade_length(pass_bb, 0, &readbytes);
    
            if ((readbytes > 0
                 && ap_pass_brigade(r->output_filters, pass_bb) != APR_SUCCESS)
                || c->aborted) {
                finish = 1;
            }
    
            apr_brigade_cleanup(bb);
            apr_brigade_cleanup(pass_bb);
        }
    
        e = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, e);
        ap_pass_brigade(r->output_filters, bb);
    
        apr_brigade_cleanup(bb);
    
        if (c->aborted || backend_broke) {
            return DONE;
        }
    
        return OK;
    }
    
    static int uwsgi_handler(request_rec *r, proxy_worker * worker,
                             proxy_server_conf * conf, char *url,
                             const char *proxyname, apr_port_t proxyport)
    {
        int status;
        proxy_conn_rec *backend = NULL;
        apr_pool_t *p = r->pool;
        char server_portstr[32];
        char *u_path_info;
        apr_uri_t *uri;
    
        if (ap_cstr_casecmpn(url, UWSGI_SCHEME "://", sizeof(UWSGI_SCHEME) + 2)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "declining URL %s", url);
            return DECLINED;
        }
    
        uri = apr_palloc(r->pool, sizeof(*uri));
    
        /* ADD PATH_INFO (unescaped) */
        u_path_info = ap_strchr(url + sizeof(UWSGI_SCHEME) + 2, '/');
        if (!u_path_info) {
            u_path_info = apr_pstrdup(r->pool, "/");
        }
        else if (ap_unescape_url(u_path_info) != OK) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10100)
                          "unable to decode uwsgi uri: %s", url);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        else {
            /* Remove duplicate slashes at the beginning of PATH_INFO */
            while (u_path_info[1] == '/') {
                u_path_info++;
            }
        }
        apr_table_add(r->subprocess_env, "PATH_INFO", u_path_info);
    
        /* Create space for state information */
        status = ap_proxy_acquire_connection(UWSGI_SCHEME, &backend, worker,
                                             r->server);
        if (status != OK) {
            goto cleanup;
        }
        backend->is_ssl = 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(UWSGI_SCHEME, backend, worker, r->server)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10101)
                          "failed to make connection to backend: %s:%u",
                          backend->hostname, backend->port);
            status = HTTP_SERVICE_UNAVAILABLE;
            goto cleanup;
        }
    
        /* Step Three: Create conn_rec */
        if ((status = ap_proxy_connection_create(UWSGI_SCHEME, backend,
                                                 r->connection,
                                                 r->server)) != OK)
            goto cleanup;
    
        /* Step Four: Process the Request */
        if (((status = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
            || ((status = uwsgi_send_headers(r, backend)) != OK)
            || ((status = uwsgi_send_body(r, backend)) != OK)
            || ((status = uwsgi_response(r, backend, conf)) != OK)) {
            goto cleanup;
        }
    
      cleanup:
        if (backend) {
            backend->close = 1;     /* always close the socket */
            ap_proxy_release_connection(UWSGI_SCHEME, backend, r->server);
        }
        return status;
    }
    
    
    static void register_hooks(apr_pool_t * p)
    {
        proxy_hook_scheme_handler(uwsgi_handler, NULL, NULL, APR_HOOK_FIRST);
        proxy_hook_canon_handler(uwsgi_canon, NULL, NULL, APR_HOOK_FIRST);
    }
    
    
    module AP_MODULE_DECLARE_DATA proxy_uwsgi_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 table */
        register_hooks              /* register hooks */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_connect.c������������������������������������������������������0000664�0001751�0001751�00000031727�14243413744�021370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 */
    
    #include "mod_proxy.h"
    #include "apr_poll.h"
    
    #define CONN_BLKSZ AP_IOBUFSIZE
    
    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 initially 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.
     */
    
    typedef struct {
        apr_array_header_t *allowed_connect_ports;
    } connect_conf;
    
    typedef struct {
        int first;
        int last;
    } port_range;
    
    static void *create_config(apr_pool_t *p, server_rec *s)
    {
        connect_conf *c = apr_pcalloc(p, sizeof(connect_conf));
        c->allowed_connect_ports = apr_array_make(p, 10, sizeof(port_range));
        return c;
    }
    
    static void *merge_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        connect_conf *c = apr_pcalloc(p, sizeof(connect_conf));
        connect_conf *base = (connect_conf *) basev;
        connect_conf *overrides = (connect_conf *) overridesv;
    
        c->allowed_connect_ports = apr_array_append(p,
                                                    base->allowed_connect_ports,
                                                    overrides->allowed_connect_ports);
    
        return c;
    }
    
    
    /*
     * 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;
        int first, last;
        connect_conf *conf =
            ap_get_module_config(s->module_config, &proxy_connect_module);
        port_range *New;
        char *endptr;
        const char *p = arg;
    
        if (!apr_isdigit(arg[0]))
            return "AllowCONNECT: port numbers must be numeric";
    
        first = strtol(p, &endptr, 10);
        if (*endptr == '-') {
            p = endptr + 1;
            last = strtol(p, &endptr, 10);
        }
        else {
            last = first;
        }
    
        if (endptr == p || *endptr != '\0')  {
            return apr_psprintf(parms->temp_pool,
                                "Cannot parse '%s' as port number", p);
        }
    
        New = apr_array_push(conf->allowed_connect_ports);
        New->first = first;
        New->last  = last;
        return NULL;
    }
    
    
    static int allowed_port(connect_conf *conf, int port)
    {
        int i;
        port_range *list = (port_range *) conf->allowed_connect_ports->elts;
    
        if (apr_is_empty_array(conf->allowed_connect_ports)) {
            return port == APR_URI_HTTPS_DEFAULT_PORT
                   || port == APR_URI_SNEWS_DEFAULT_PORT;
        }
    
        for (i = 0; i < conf->allowed_connect_ports->nelts; i++) {
            if (port >= list[i].first && port <= list[i].last)
                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_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "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)
    {
        connect_conf *c_conf =
            ap_get_module_config(r->server->module_config, &proxy_connect_module);
    
        apr_pool_t *p = r->pool;
        apr_socket_t *sock;
        conn_rec *c = r->connection;
        conn_rec *backconn;
    
        apr_status_t rv;
        apr_size_t nbytes;
        char buffer[HUGE_STRING_LEN];
    
        apr_bucket_brigade *bb;
        proxy_tunnel_rec *tunnel;
        int failed, rc;
    
        apr_uri_t uri;
        const char *connectname;
        apr_port_t connectport = 0;
        apr_sockaddr_t *nexthop;
    
        apr_interval_time_t current_timeout;
    
        /* is this for us? */
        if (r->method_number != M_CONNECT) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "declining URL %s", url);
            return DECLINED;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01019)
                      "connecting %s to %s:%d", url, uri.hostname, uri.port);
    
        /* Determine host/port of next hop; from request URI or of a proxy. */
        connectname = proxyname ? proxyname : uri.hostname;
        connectport = proxyname ? proxyport : uri.port;
    
        /* Do a DNS lookup for the next hop */
        rv = apr_sockaddr_info_get(&nexthop, connectname, APR_UNSPEC, 
                                   connectport, 0, p);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02327)
                          "failed to resolve hostname '%s'", connectname);
            return ap_proxyerror(r, HTTP_BAD_GATEWAY,
                                 apr_pstrcat(p, "DNS lookup failure for: ",
                                             connectname, NULL));
        }
    
        /* Check ProxyBlock directive on the hostname/address.  */
        if (ap_proxy_checkproxyblock2(r, conf, uri.hostname, 
                                     proxyname ? NULL : nexthop) != OK) {
            return ap_proxyerror(r, HTTP_FORBIDDEN,
                                 "Connect to remote machine blocked");
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "connecting to remote proxy %s on port %d",
                      connectname, connectport);
    
        /* Check if it is an allowed port */
        if (!allowed_port(c_conf, uri.port)) {
            return ap_proxyerror(r, HTTP_FORBIDDEN,
                                 "Connect to remote machine blocked");
        }
    
        /*
         * Step Two: Make the Connection
         *
         * We have determined who to connect to. Now make the connection.
         */
    
        /*
         * 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", nexthop,
                                             connectname, conf, r);
    
        /* handle a permanent error from the above loop */
        if (failed) {
            if (proxyname) {
                return DECLINED;
            }
            else {
                return HTTP_SERVICE_UNAVAILABLE;
            }
        }
    
        /*
         * Step Three: Send the Request
         *
         * Send the HTTP/1.1 CONNECT request to the remote server
         */
    
        backconn = ap_run_create_connection(c->pool, r->server, sock,
                                            c->id, c->sbh, c->bucket_alloc);
        if (!backconn) {
            /* peer reset */
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01021)
                          "an error occurred creating a new connection "
                          "to %pI (%s)", nexthop, connectname);
            apr_socket_close(sock);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        ap_proxy_ssl_engine(backconn, r->per_dir_config, 0);
    
        /*
         * save the timeout of the socket because core_pre_connection
         * will set it to base_server->timeout
         * (core TimeOut directive).
         */
        apr_socket_timeout_get(sock, &current_timeout);
        rc = ap_run_pre_connection(backconn, sock);
        if (rc != OK && rc != DONE) {
            backconn->aborted = 1;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01022)
                          "pre_connection setup failed (%d)", rc);
            apr_socket_close(sock);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        apr_socket_timeout_set(sock, current_timeout);
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                      "connection complete to %pI (%s)",
                      nexthop, connectname);
        apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
                       backconn->local_addr->port));
    
        bb = apr_brigade_create(p, c->bucket_alloc);
    
        /* 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_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                          "sending the CONNECT request to the remote proxy");
            ap_fprintf(backconn->output_filters, bb,
                       "CONNECT %s HTTP/1.0" CRLF, r->uri);
            ap_fprintf(backconn->output_filters, bb,
                       "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner());
            ap_fflush(backconn->output_filters, bb);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Returning 200 OK");
            nbytes = apr_snprintf(buffer, sizeof(buffer),
                                  "HTTP/1.0 200 Connection Established" CRLF);
            ap_xlate_proto_to_ascii(buffer, nbytes);
            ap_fwrite(c->output_filters, bb, buffer, nbytes);
            nbytes = apr_snprintf(buffer, sizeof(buffer),
                                  "Proxy-agent: %s" CRLF CRLF,
                                  ap_get_server_banner());
            ap_xlate_proto_to_ascii(buffer, nbytes);
            ap_fwrite(c->output_filters, bb, buffer, nbytes);
            ap_fflush(c->output_filters, bb);
    #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_banner());
            ap_rflush(r);
    #endif
        }
        apr_brigade_cleanup(bb);
    
        /*
         * Step Four: Handle Data Transfer
         *
         * Handle two way transfer of data over the socket (this is a tunnel).
         */
    
        /* r->sent_bodyct = 1; */
    
        rv = ap_proxy_tunnel_create(&tunnel, r, backconn, "CONNECT");
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10208)
                          "can't create tunnel for %pI (%s)",
                          nexthop, connectname);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        rc = ap_proxy_tunnel_run(tunnel);
        if (ap_is_HTTP_ERROR(rc)) {
            if (rc == HTTP_GATEWAY_TIME_OUT) {
                /* ap_proxy_tunnel_run() didn't log this */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10224)
                              "tunnel timed out");
            }
            /* Don't send an error page if we sent data already */
            if (proxyport && !tunnel->replied) {
                return rc;
            }
        }
    
        /*
         * Step Five: Clean Up
         *
         * Close the socket and clean up
         */
    
        if (backconn->aborted)
            apr_socket_close(sock);
        else
            ap_lingering_close(backconn);
    
        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);
    }
    
    static const command_rec cmds[] =
    {
        AP_INIT_ITERATE("AllowCONNECT", set_allowed_ports, NULL, RSRC_CONF,
         "A list of ports or port ranges which CONNECT may connect to"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(proxy_connect) = {
        STANDARD20_MODULE_STUFF,
        NULL,       /* create per-directory config structure */
        NULL,       /* merge per-directory config structures */
        create_config,       /* create per-server config structure */
        merge_config,       /* merge per-server config structures */
        cmds,       /* command apr_table_t */
        ap_proxy_connect_register_hook  /* register hooks */
    };
    �����������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_wstunnel.c�����������������������������������������������������0000664�0001751�0001751�00000045313�14411570023�021601� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "http_config.h"
    
    module AP_MODULE_DECLARE_DATA proxy_wstunnel_module;
    
    typedef struct {
        unsigned int fallback_to_proxy_http     :1,
                     fallback_to_proxy_http_set :1;
    } proxyws_dir_conf;
    
    static int can_fallback_to_proxy_http;
    
    static int proxy_wstunnel_check_trans(request_rec *r, const char *url)
    {
        proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                       &proxy_wstunnel_module);
    
        if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "check_trans fallback");
            return DECLINED;
        }
    
        if (ap_cstr_casecmpn(url, "ws:", 3) != 0
                && ap_cstr_casecmpn(url, "wss:", 4) != 0) {
            return DECLINED;
        }
    
        if (!apr_table_get(r->headers_in, "Upgrade")) {
            /* No Upgrade, let mod_proxy_http handle it (for instance).
             * Note: anything but OK/DECLINED will do (i.e. bypass wstunnel w/o
             * aborting the request), HTTP_UPGRADE_REQUIRED is documentary...
             */
            return HTTP_UPGRADE_REQUIRED;
        }
    
        return OK;
    }
    
    /*
     * 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_wstunnel_canon(request_rec *r, char *url)
    {
        proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                       &proxy_wstunnel_module);
        char *host, *path, sport[7];
        char *search = NULL;
        const char *err;
        char *scheme;
        apr_port_t port, def_port;
    
        if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "canon fallback");
            return DECLINED;
        }
    
        /* ap_port_of_scheme() */
        if (ap_cstr_casecmpn(url, "ws:", 3) == 0) {
            url += 3;
            scheme = "ws:";
            def_port = apr_uri_port_of_scheme("http");
        }
        else if (ap_cstr_casecmpn(url, "wss:", 4) == 0) {
            url += 4;
            scheme = "wss:";
            def_port = apr_uri_port_of_scheme("https");
        }
        else {
            return DECLINED;
        }
    
        port = def_port;
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "canonicalising URL %s", url);
    
        /*
         * do syntactic 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, APLOGNO(02439) "error parsing URL %s: %s",
                          url, err);
            return HTTP_BAD_REQUEST;
        }
    
        /*
         * now parse path/search args, according to rfc1738:
         * process the path. With proxy-nocanon set (by
         * mod_proxy) we use the raw, unparsed uri
         */
        if (apr_table_get(r->notes, "proxy-nocanon")) {
            path = url;   /* this is the raw path */
        }
        else if (apr_table_get(r->notes, "proxy-noencode")) {
            path = url;   /* this is the encoded path already */
            search = r->args;
        }
        else {
            core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
            int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
    
            path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
                                        r->proxyreq);
            if (!path) {
                return HTTP_BAD_REQUEST;
            }
            search = r->args;
        }
        /*
         * If we have a raw control character or a ' ' in nocanon path or
         * r->args, correct encoding was missed.
         */
        if (path == url && *ap_scan_vchar_obstext(path)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10419)
                          "To be forwarded path contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
        if (search && *ap_scan_vchar_obstext(search)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10409)
                          "To be forwarded query string contains control "
                          "characters or spaces");
            return HTTP_FORBIDDEN;
        }
    
        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;
    }
    
    /*
     * process the request and write the response.
     */
    static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
                                    proxy_conn_rec *conn,
                                    proxy_worker *worker,
                                    proxy_server_conf *conf,
                                    apr_uri_t *uri,
                                    char *url, char *server_portstr)
    {
        apr_status_t rv;
        apr_pollset_t *pollset;
        apr_pollfd_t pollfd;
        const apr_pollfd_t *signalled;
        apr_int32_t pollcnt, pi;
        apr_int16_t pollevent;
        conn_rec *c = r->connection;
        apr_socket_t *sock = conn->sock;
        conn_rec *backconn = conn->connection;
        char *buf;
        apr_bucket_brigade *header_brigade;
        apr_bucket *e;
        char *old_cl_val = NULL;
        char *old_te_val = NULL;
        apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
        apr_socket_t *client_socket = ap_get_conn_socket(c);
        int done = 0, replied = 0;
        const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
    
        header_brigade = apr_brigade_create(p, backconn->bucket_alloc);
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "sending request");
    
        rv = ap_proxy_create_hdrbrgd(p, header_brigade, r, conn,
                                     worker, conf, uri, url, server_portstr,
                                     &old_cl_val, &old_te_val);
        if (rv != OK) {
            return rv;
        }
    
        if (ap_cstr_casecmp(upgrade_method, "NONE") == 0) {
            buf = apr_pstrdup(p, "Upgrade: WebSocket" CRLF "Connection: Upgrade" CRLF CRLF);
        } else if (ap_cstr_casecmp(upgrade_method, "ANY") == 0) {
            const char *upgrade;
            upgrade = apr_table_get(r->headers_in, "Upgrade");
            buf = apr_pstrcat(p, "Upgrade: ", upgrade, CRLF "Connection: Upgrade" CRLF CRLF, NULL);
        } else {
            buf = apr_pstrcat(p, "Upgrade: ", upgrade_method, CRLF "Connection: Upgrade" CRLF 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);
    
        if ((rv = ap_proxy_pass_brigade(backconn->bucket_alloc, r, conn, backconn,
                                        header_brigade, 1)) != OK)
            return rv;
    
        apr_brigade_cleanup(header_brigade);
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "setting up poll()");
    
        if ((rv = apr_pollset_create(&pollset, 2, p, 0)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02443)
                          "error apr_pollset_create()");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
    #if 0
        apr_socket_opt_set(sock, APR_SO_NONBLOCK, 1);
        apr_socket_opt_set(sock, APR_SO_KEEPALIVE, 1);
        apr_socket_opt_set(client_socket, APR_SO_NONBLOCK, 1);
        apr_socket_opt_set(client_socket, APR_SO_KEEPALIVE, 1);
    #endif
    
        pollfd.p = p;
        pollfd.desc_type = APR_POLL_SOCKET;
        pollfd.reqevents = APR_POLLIN | APR_POLLHUP;
        pollfd.desc.s = sock;
        pollfd.client_data = NULL;
        apr_pollset_add(pollset, &pollfd);
    
        pollfd.desc.s = client_socket;
        apr_pollset_add(pollset, &pollfd);
    
        ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout");
    
        r->output_filters = c->output_filters;
        r->proto_output_filters = c->output_filters;
        r->input_filters = c->input_filters;
        r->proto_input_filters = c->input_filters;
    
        /* This handler should take care of the entire connection; make it so that
         * nothing else is attempted on the connection after returning. */
        c->keepalive = AP_CONN_CLOSE;
    
        do { /* Loop until done (one side closes the connection, or an error) */
            rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled);
            if (rv != APR_SUCCESS) {
                if (APR_STATUS_IS_EINTR(rv)) {
                    continue;
                }
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02444) "error apr_poll()");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02445)
                          "woke from poll(), i=%d", pollcnt);
    
            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 | APR_POLLHUP)) {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02446)
                                      "sock was readable");
                        done |= ap_proxy_transfer_between_connections(r, backconn,
                                                                      c,
                                                                      header_brigade,
                                                                      bb, "sock",
                                                                      &replied,
                                                                      AP_IOBUFSIZE,
                                                                      0)
                                                                     != APR_SUCCESS;
                    }
                    else if (pollevent & APR_POLLERR) {
                        ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447)
                                "error on backconn");
                        backconn->aborted = 1;
                        done = 1;
                    }
                    else { 
                        ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02605)
                                "unknown event on backconn %d", pollevent);
                        done = 1;
                    }
                }
                else if (cur->desc.s == client_socket) {
                    pollevent = cur->rtnevents;
                    if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02448)
                                      "client was readable");
                        done |= ap_proxy_transfer_between_connections(r, c,
                                                                      backconn, bb,
                                                                      header_brigade,
                                                                      "client",
                                                                      NULL,
                                                                      AP_IOBUFSIZE,
                                                                      0)
                                                                     != APR_SUCCESS;
                    }
                    else if (pollevent & APR_POLLERR) {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02607)
                                "error on client conn");
                        c->aborted = 1;
                        done = 1;
                    }
                    else { 
                        ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02606)
                                "unknown event on client conn %d", pollevent);
                        done = 1;
                    }
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02449)
                                  "unknown socket in pollset");
                    done = 1;
                }
    
            }
        } while (!done);
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                      "finished with poll() - cleaning up");
    
        if (!replied) {
            return HTTP_BAD_GATEWAY;
        }
        else {
            return OK;
        }
    
        return OK;
    }
    
    /*
     */
    static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
                                 proxy_server_conf *conf,
                                 char *url, const char *proxyname,
                                 apr_port_t proxyport)
    {
        proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                       &proxy_wstunnel_module);
        int status;
        char server_portstr[32];
        proxy_conn_rec *backend = NULL;
        const char *upgrade;
        char *scheme;
        apr_pool_t *p = r->pool;
        char *locurl = url;
        apr_uri_t *uri;
        int is_ssl = 0;
    
        if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "handler fallback");
            return DECLINED;
        }
    
        if (ap_cstr_casecmpn(url, "wss:", 4) == 0) {
            scheme = "WSS";
            is_ssl = 1;
        }
        else if (ap_cstr_casecmpn(url, "ws:", 3) == 0) {
            scheme = "WS";
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02450)
                          "declining URL %s", url);
            return DECLINED;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "serving URL %s", url);
    
        upgrade = apr_table_get(r->headers_in, "Upgrade");
        if (!upgrade || !ap_proxy_worker_can_upgrade(p, worker, upgrade,
                                                     "WebSocket")) {
            const char *worker_upgrade = *worker->s->upgrade ? worker->s->upgrade
                                                             : "WebSocket";
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02900)
                          "require upgrade for URL %s "
                          "(Upgrade header is %s, expecting %s)", 
                          url, upgrade ? upgrade : "missing", worker_upgrade);
            apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
            apr_table_setn(r->err_headers_out, "Upgrade", worker_upgrade);
            return HTTP_UPGRADE_REQUIRED;
        }
    
        uri = apr_palloc(p, sizeof(*uri));
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02451) "serving URL %s", url);
    
        /* create space for state information */
        status = ap_proxy_acquire_connection(scheme, &backend, worker, r->server);
        if (status != OK) {
            goto cleanup;
        }
    
        backend->is_ssl = is_ssl;
        backend->close = 0;
    
        /* Step One: Determine Who To Connect To */
        status = ap_proxy_determine_connection(p, r, conf, worker, backend,
                                               uri, &locurl, 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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02452)
                          "failed to make connection to backend: %s",
                          backend->hostname);
            status = HTTP_SERVICE_UNAVAILABLE;
            goto cleanup;
        }
    
        /* Step Three: Create conn_rec */
        status = ap_proxy_connection_create_ex(scheme, backend, r);
        if (status != OK) {
            goto cleanup;
        }
    
        /* Step Four: Process the Request */
        status = proxy_wstunnel_request(p, r, backend, worker, conf, uri, locurl,
                                      server_portstr);
    
    cleanup:
        /* Do not close the socket */
        if (backend) { 
            backend->close = 1;
            ap_proxy_release_connection(scheme, backend, r->server);
        }
        return status;
    }
    
    static void *create_proxyws_dir_config(apr_pool_t *p, char *dummy)
    {
        proxyws_dir_conf *new =
            (proxyws_dir_conf *) apr_pcalloc(p, sizeof(proxyws_dir_conf));
    
        new->fallback_to_proxy_http = 1;
    
        return (void *) new;
    }
    
    static void *merge_proxyws_dir_config(apr_pool_t *p, void *vbase, void *vadd)
    {
        proxyws_dir_conf *new = apr_pcalloc(p, sizeof(proxyws_dir_conf)),
                         *add = vadd, *base = vbase;
    
        new->fallback_to_proxy_http = (add->fallback_to_proxy_http_set)
                                      ? add->fallback_to_proxy_http
                                      : base->fallback_to_proxy_http;
        new->fallback_to_proxy_http_set = (add->fallback_to_proxy_http_set
                                           || base->fallback_to_proxy_http_set);
    
        return new;
    }
    
    static const char * proxyws_fallback_to_proxy_http(cmd_parms *cmd, void *conf, int arg)
    {
        proxyws_dir_conf *dconf = conf;
        dconf->fallback_to_proxy_http = !!arg;
        dconf->fallback_to_proxy_http_set = 1;
        return NULL;
    }
    
    static int proxy_wstunnel_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                          apr_pool_t *ptemp, server_rec *s)
    {
        can_fallback_to_proxy_http =
            (ap_find_linked_module("mod_proxy_http.c") != NULL);
    
        return OK;
    }
    
    static const command_rec ws_proxy_cmds[] =
    {
        AP_INIT_FLAG("ProxyWebsocketFallbackToProxyHttp",
                     proxyws_fallback_to_proxy_http, NULL, RSRC_CONF|ACCESS_CONF,
                     "whether to let mod_proxy_http handle the upgrade and tunneling, "
                     "On by default"),
    
        {NULL}
    };
    
    static void ws_proxy_hooks(apr_pool_t *p)
    {
        static const char * const aszSucc[] = { "mod_proxy_http.c", NULL};
        ap_hook_post_config(proxy_wstunnel_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        proxy_hook_scheme_handler(proxy_wstunnel_handler, NULL, aszSucc, APR_HOOK_FIRST);
        proxy_hook_check_trans(proxy_wstunnel_check_trans, NULL, aszSucc, APR_HOOK_MIDDLE);
        proxy_hook_canon_handler(proxy_wstunnel_canon, NULL, aszSucc, APR_HOOK_FIRST);
    }
    
    AP_DECLARE_MODULE(proxy_wstunnel) = {
        STANDARD20_MODULE_STUFF,
        create_proxyws_dir_config,  /* create per-directory config structure */
        merge_proxyws_dir_config,   /* merge per-directory config structures */
        NULL,                       /* create per-server config structure */
        NULL,                       /* merge per-server config structures */
        ws_proxy_cmds,              /* command apr_table_t */
        ws_proxy_hooks              /* register hooks */
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/ajp.h��������������������������������������������������������������������0000664�0001751�0001751�00000037151�13624764511�016416� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ajp.h
     * @brief Apache Jserv Protocol
     *
     * @defgroup AJP_defines mod_proxy AJP definitions
     * @ingroup  APACHE_INTERNAL
     * @{
     */
    
    #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_poll.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_PROTOCOL_INDICATOR    "SSL_PROTOCOL"
    #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"
    
    #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"
    #include "util_ebcdic.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;
        /** The size of the buffer */
        apr_size_t max_size;
    };
    
    /**
     * 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_HEADER_SZ               6
    #define AJP_MSG_BUFFER_SZ           8192
    #define AJP_MAX_BUFFER_SZ           65536
    #define AJP13_MAX_SEND_BODY_SZ      (AJP_MAX_BUFFER_SZ - AJP_HEADER_SZ)
    #define AJP_PING_PONG_SZ            128
    
    /** 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
     * @ingroup  MOD_PROXY
     * @{
     */
    /**
     * 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);
    
    /**
     * Reuse an AJP Message
     *
     * @param msg       AJP Message to reuse
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_reuse(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 rvalue_len 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 size      size of the buffer to create
     * @param rmsg      Pointer to newly created AJP message
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, 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 msg       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 msg      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
     * @param count     the number of bytes to dump
     * @param buf       buffer pointer for dump message
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err,
                              apr_size_t count, char **buf);
    
    /**
     * Log an AJP message
     *
     * @param r         The current request
     * @param msg       AJP Message to dump
     * @param err       error string to display
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_log(request_rec *r, ajp_msg_t *msg, char *err);
    
    /**
     * Send an AJP message to backend
     *
     * @param sock      backend socket
     * @param msg       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 msg       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
     * @param buffsize  max size of the AJP packet.
     * @param uri       requested uri
     * @param secret    authentication secret
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r,
                                 apr_size_t buffsize,
                                 apr_uri_t *uri,
                                 const char *secret);
    
    /**
     * Read the ajp message and return the type of the message.
     * @param sock      backend socket
     * @param r         current request
     * @param buffsize  size of the buffer.
     * @param msg       returned AJP message
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_read_header(apr_socket_t *sock,
                                 request_rec  *r,
                                 apr_size_t buffsize,
                                 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 conf      proxy config
     * @param msg       AJP message
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_parse_header(request_rec *r, proxy_dir_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);
    
    
    /**
     * Check the reuse flag in CMD_AJP13_END_RESPONSE
     * @param r         current request
     * @param msg       AJP message
     * @param reuse     returned reuse flag
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg,
                                 apr_byte_t *reuse);
    
    
    /**
     * Handle the CPING/CPONG messages
     * @param sock      backend socket
     * @param r         current request
     * @param timeout   time window for receiving cpong reply
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock,
                                        request_rec *r,
                                        apr_interval_time_t timeout);
    
    
    /**
     * Convert numeric message type into string
     * @param type      AJP message type
     * @return          AJP message type as a string
     */
    const char *ajp_type_str(int type);
    
    /** @} */
    
    #endif /* AJP_H */
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_uwsgi.dep������������������������������������������������������0000664�0001751�0001751�00000005234�13242652000�021401� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_scgi.mak
    
    .\mod_proxy_uwsgi.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	".\scgi.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_hcheck.dep�����������������������������������������������������0000664�0001751�0001751�00000000232�13017652517�021476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_hcheck.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxylbm_traf�������������������������������������������������������0000664�0001751�0001751�00000010365�12010715741�021110� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/proxy \
    			$(AP_WORK)/modules/http \
    			$(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	= proxylbm_traf
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy LoadBalance by Traffic Sub-Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= LBM Traf 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	=
    
    #
    # 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)/$(NLM_NAME).nlm
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib =
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/mod_lbmethod_bytraffic.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 = \
    	$(PRELUDE) \
    	$(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 \
    	aprlib \
    	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 = \
    	@libc.imp \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	lbmethod_bytraffic_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 balancers
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_fcgi.dsp�������������������������������������������������������0000664�0001751�0001751�00000011461�12243521372�021177� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_fcgi" - 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_fcgi - 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_fcgi.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_fcgi.mak" CFG="mod_proxy_fcgi - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_fcgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_fcgi - 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_fcgi - 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_fcgi_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 0x409 /fo"Release/mod_proxy_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_fcgi.so" /d LONG_NAME="proxy_fcgi_module for Apache"
    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 /out:".\Release\mod_proxy_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_fcgi.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_proxy_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_fcgi.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_fcgi - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_fcgi_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 0x409 /fo"Debug/mod_proxy_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_fcgi.so" /d LONG_NAME="proxy_fcgi_module for Apache"
    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 /out:".\Debug\mod_proxy_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_fcgi.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_fcgi.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_fcgi - Win32 Release"
    # Name "mod_proxy_fcgi - 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_fcgi.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxylbm_hb���������������������������������������������������������0000664�0001751�0001751�00000010366�12010715741�020546� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/proxy \
    			$(AP_WORK)/modules/http \
    			$(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	= proxylbm_hb
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy LoadBalance by Heartbeat Sub-Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= LBM Heart 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	=
    
    #
    # 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)/$(NLM_NAME).nlm
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib =
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/mod_lbmethod_heartbeat.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 = \
    	$(PRELUDE) \
    	$(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 \
    	aprlib \
    	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 = \
    	@libc.imp \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	lbmethod_heartbeat_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 balancers
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_scgi.dsp�������������������������������������������������������0000664�0001751�0001751�00000011461�11305077137�021217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_scgi" - 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_scgi - 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_scgi.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_scgi.mak" CFG="mod_proxy_scgi - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_scgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_scgi - 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_scgi - 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_scgi_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 0x409 /fo"Release/mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache"
    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 /out:".\Release\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_scgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_scgi - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_scgi_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 0x409 /fo"Debug/mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache"
    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 /out:".\Debug\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_scgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_scgi - Win32 Release"
    # Name "mod_proxy_scgi - 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_scgi.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/ajp_msg.c����������������������������������������������������������������0000664�0001751�0001751�00000042154�12661357032�017252� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    APLOG_USE_MODULE(proxy_ajp);
    
    #define AJP_MSG_DUMP_BYTES_PER_LINE 16
    /* 2 hex digits plus space plus one char per dumped byte */
    /* plus prefix plus separator plus '\0' */
    #define AJP_MSG_DUMP_PREFIX_LENGTH  strlen("XXXX    ")
    #define AJP_MSG_DUMP_LINE_LENGTH    ((AJP_MSG_DUMP_BYTES_PER_LINE * \
                                        strlen("XX .")) + \
                                        AJP_MSG_DUMP_PREFIX_LENGTH + \
                                        strlen(" - ") + 1)
    
    static char *hex_table = "0123456789ABCDEF";
    
    /**
     * Dump the given number of bytes on an AJP Message
     *
     * @param pool      pool to allocate from
     * @param msg       AJP Message to dump
     * @param err       error string to display
     * @param count     the number of bytes to dump
     * @param buf       buffer pointer for dump message
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err,
                              apr_size_t count, char **buf)
    {
        apr_size_t  i, j;
        char        *current;
        apr_size_t  bl, rl;
        apr_byte_t  x;
        apr_size_t  len = msg->len;
        apr_size_t  line_len;
    
        /* Display only first "count" bytes */
        if (len > count)
            len = count;
             /* First the space needed for the first line */
        bl = strlen(err) + 3 * (strlen(" XXX=") + 20) + 1 +
             /* Now for the data lines */
             (len + 15) / 16 * AJP_MSG_DUMP_LINE_LENGTH;
        *buf = apr_palloc(pool, bl);
        if (!*buf)
            return APR_ENOMEM;
        apr_snprintf(*buf, bl,
                     "%s pos=%" APR_SIZE_T_FMT
                     " len=%" APR_SIZE_T_FMT " max=%" APR_SIZE_T_FMT "\n",
                     err, msg->pos, msg->len, msg->max_size);
        current = *buf + strlen(*buf);
        for (i = 0; i < len; i += AJP_MSG_DUMP_BYTES_PER_LINE) {
            /* Safety check: do we have enough buffer for another line? */
            rl = bl - (current - *buf);
            if (AJP_MSG_DUMP_LINE_LENGTH > rl) {
                *(current - 1) = '\0';
                return APR_ENOMEM;
            }
            apr_snprintf(current, rl, "%.4lx    ", (unsigned long)i);
            current += AJP_MSG_DUMP_PREFIX_LENGTH;
            line_len = len - i;
            if (line_len > AJP_MSG_DUMP_BYTES_PER_LINE) {
                line_len = AJP_MSG_DUMP_BYTES_PER_LINE;
            }
            for (j = 0; j < line_len; j++) {
                x = msg->buf[i + j];
    
                *current++ = hex_table[x >> 4];
                *current++ = hex_table[x & 0x0f];
                *current++ = ' ';
            }
            *current++ = ' ';
            *current++ = '-';
            *current++ = ' ';
            for (j = 0; j < line_len; j++) {
                x = msg->buf[i + j];
    
                if (x > 0x20 && x < 0x7F) {
                    *current++ = x;
                }
                else {
                    *current++ = '.';
                }
            }
            *current++ = '\n';
        }
        *(current - 1) = '\0';
    
        return APR_SUCCESS;
    }
    
    /**
     * Log an AJP message
     *
     * @param request   The current request
     * @param msg       AJP Message to dump
     * @param err       error string to display
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_log(request_rec *r, ajp_msg_t *msg, char *err)
    {
        int level;
        apr_size_t count;
        char *buf, *next;
        apr_status_t rc = APR_SUCCESS;
    
        if (APLOGrtrace7(r)) {
            level = APLOG_TRACE7;
            count = 1024;
            if (APLOGrtrace8(r)) {
                level = APLOG_TRACE8;
                count = AJP_MAX_BUFFER_SZ;
            }
            rc = ajp_msg_dump(r->pool, msg, err, count, &buf);
            if (rc == APR_SUCCESS) {
                while ((next = ap_strchr(buf, '\n'))) {
                    *next = '\0';
                    /* Intentional no APLOGNO */
                    ap_log_rerror(APLOG_MARK, level, 0, r, "%s", buf);
                    buf = next + 1;
                }
                /* Intentional no APLOGNO */
                ap_log_rerror(APLOG_MARK, level, 0, r, "%s", buf);
            }
        }
        return rc;
    }
    
    /**
     * 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, APLOGNO(01080)
                          "ajp_msg_check_header() got bad signature %02x%02x",
                          head[0], head[1]);
    
            return AJP_EBAD_SIGNATURE;
        }
    
        msglen  = ((head[2] & 0xff) << 8);
        msglen += (head[3] & 0xFF);
    
        if (msglen > msg->max_size) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(01081)
                         "ajp_msg_check_header() incoming message is "
                         "too big %" APR_SIZE_T_FMT ", max is %" APR_SIZE_T_FMT,
                         msglen, msg->max_size);
            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;
    }
    
    /**
     * Reuse an AJP Message
     *
     * @param msg       AJP Message to reuse
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_reuse(ajp_msg_t *msg)
    {
        apr_byte_t *buf;
        apr_size_t max_size;
    
        buf = msg->buf;
        max_size = msg->max_size;
        memset(msg, 0, sizeof(ajp_msg_t));
        msg->buf = buf;
        msg->max_size = max_size;
        msg->header_len = AJP_HEADER_LEN;
        ajp_msg_reset(msg);
        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, APLOGNO(03229)
                     "%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) > msg->max_size) {
            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) > msg->max_size) {
            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) > msg->max_size) {
            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)
    {
        apr_size_t len;
    
        if (value == NULL) {
            return(ajp_msg_append_uint16(msg, 0xFFFF));
        }
    
        len = strlen(value);
        if ((msg->len + len + 3) > msg->max_size) {
            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 */
            ap_xlate_proto_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) > msg->max_size) {
            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 > msg->max_size)) {
            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 > msg->max_size)) {
            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 size      size of the buffer to create
     * @param rmsg      Pointer to newly created AJP message
     * @return          APR_SUCCESS or error
     */
    apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, ajp_msg_t **rmsg)
    {
        ajp_msg_t *msg = (ajp_msg_t *)apr_pcalloc(pool, sizeof(ajp_msg_t));
    
        msg->server_side = 0;
    
        msg->buf = (apr_byte_t *)apr_palloc(pool, size);
        msg->len = 0;
        msg->header_len = AJP_HEADER_LEN;
        msg->max_size = size;
        *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 (smsg->len > smsg->max_size) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(01082)
                         "ajp_msg_copy(): destination buffer too "
                         "small %" APR_SIZE_T_FMT ", max size is %" APR_SIZE_T_FMT,
                         smsg->len, smsg->max_size);
            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;
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/Makefile.in��������������������������������������������������������������0000664�0001751�0001751�00000000314�11120510723�017506� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# a modules Makefile has no explicit targets -- they will be defined by
    # whatever modules are enabled. just grab special.mk to deal with this.
    #SUBDIRS = balancers
    include $(top_srcdir)/build/special.mk
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_fdpass.c�������������������������������������������������������0000664�0001751�0001751�00000015260�14001631447�021203� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    
    #ifndef CMSG_DATA
    #error This module only works on unix platforms with the correct OS support
    #endif
    
    #include "mod_proxy_fdpass.h"
    
    module AP_MODULE_DECLARE_DATA proxy_fdpass_module;
    
    static int proxy_fdpass_canon(request_rec *r, char *url)
    {
        const char *path;
    
        if (ap_cstr_casecmpn(url, "fd://", 5) == 0) {
            url += 5;
        }
        else {
            return DECLINED;
        }
    
        path = ap_server_root_relative(r->pool, url);
    
        r->filename = apr_pstrcat(r->pool, "proxy:fd://", path, NULL);
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01151)
                      "set r->filename to %s", r->filename);
        return OK;
    }
    
    static apr_status_t get_socket_from_path(apr_pool_t *p,
                                             const char* path,
                                             apr_socket_t **out_sock)
    {
        apr_socket_t *s;
        apr_status_t rv;
        *out_sock = NULL;
    
        rv = apr_socket_create(&s, AF_UNIX, SOCK_STREAM, 0, p);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = ap_proxy_connect_uds(s, path, p);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        *out_sock = s;
    
        return APR_SUCCESS;
    }
    
    static apr_status_t send_socket(apr_pool_t *p,
                                    apr_socket_t *s,
                                    apr_socket_t *outbound)
    {
        apr_status_t rv;
        apr_os_sock_t rawsock;
        apr_os_sock_t srawsock;
        struct msghdr msg;
        struct cmsghdr *cmsg;
        struct iovec iov;
        char b = '\0';
    
        rv = apr_os_sock_get(&rawsock, outbound);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        rv = apr_os_sock_get(&srawsock, s);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        memset(&msg, 0, sizeof(msg));
    
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
    
        iov.iov_base = &b;
        iov.iov_len = 1;
    
        cmsg = apr_palloc(p, sizeof(*cmsg) + sizeof(rawsock));
        cmsg->cmsg_len = sizeof(*cmsg) + sizeof(rawsock);
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
    
        memcpy(CMSG_DATA(cmsg), &rawsock, sizeof(rawsock));
    
        msg.msg_control = cmsg;
        msg.msg_controllen = cmsg->cmsg_len;
    
        rv = sendmsg(srawsock, &msg, 0);
    
        if (rv == -1) {
            return errno;
        }
    
        return APR_SUCCESS;
    }
    
    static int proxy_fdpass_handler(request_rec *r, proxy_worker *worker,
                                  proxy_server_conf *conf,
                                  char *url, const char *proxyname,
                                  apr_port_t proxyport)
    {
        apr_status_t rv;
        apr_socket_t *sock;
        apr_socket_t *clientsock;
    
        if (ap_cstr_casecmpn(url, "fd://", 5) == 0) {
            url += 5;
        }
        else {
            return DECLINED;
        }
    
        rv = get_socket_from_path(r->pool, url, &sock);
    
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01152)
                          "Failed to connect to '%s'", url);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        {
            int status;
            const char *flush_method = *worker->s->flusher ? worker->s->flusher : "flush";
    
            proxy_fdpass_flush *flush = ap_lookup_provider(PROXY_FDPASS_FLUSHER,
                                                           flush_method, "0");
    
            if (!flush) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01153)
                              "Unable to find configured flush provider '%s'",
                              flush_method);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            status = flush->flusher(r);
            if (status) {
                return status;
            }
        }
    
        clientsock = ap_get_conn_socket(r->connection);
    
        rv = send_socket(r->pool, sock, clientsock);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01154) "send_socket failed:");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        {
            apr_socket_t *dummy;
            /* Create a dummy unconnected socket, and set it as the one we were
             * connected to, so that when the core closes it, it doesn't close
             * the tcp connection to the client.
             */
            rv = apr_socket_create(&dummy, APR_INET, SOCK_STREAM, APR_PROTO_TCP,
                                   r->connection->pool);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01155)
                              "failed to create dummy socket");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            ap_set_core_module_config(r->connection->conn_config, dummy);
        }
    
        return OK;
    }
    
    static int standard_flush(request_rec *r)
    {
        int status;
        apr_bucket_brigade *bb;
        apr_bucket *e;
    
        r->connection->keepalive = AP_CONN_CLOSE;
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        e = apr_bucket_flush_create(r->connection->bucket_alloc);
    
        APR_BRIGADE_INSERT_TAIL(bb, e);
    
        status = ap_pass_brigade(r->output_filters, bb);
    
        if (status != OK) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01156)
                          "ap_pass_brigade failed:");
            return status;
        }
    
        return OK;
    }
    
    
    static const proxy_fdpass_flush builtin_flush =
    {
        "flush",
        &standard_flush,
        NULL
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_provider(p, PROXY_FDPASS_FLUSHER, "flush", "0", &builtin_flush);
        proxy_hook_scheme_handler(proxy_fdpass_handler, NULL, NULL, APR_HOOK_FIRST);
        proxy_hook_canon_handler(proxy_fdpass_canon, NULL, NULL, APR_HOOK_FIRST);
    }
    
    AP_DECLARE_MODULE(proxy_fdpass) = {
        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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy.dsp������������������������������������������������������������0000664�0001751�0001751�00000011552�13303340351�020202� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 "../http2" /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 0x409 /fo"Release/mod_proxy.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy.so" /d LONG_NAME="proxy_module for Apache"
    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 /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 /out:".\Release\mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../ssl" /I "../http2" /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 0x409 /fo"Debug/mod_proxy.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy.so" /d LONG_NAME="proxy_module for Apache"
    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 /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 /out:".\Debug\mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxyhcheck���������������������������������������������������������0000664�0001751�0001751�00000010465�13163000600�020537� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(SRC)/include \
    			$(STDMOD)/core \
    			$(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	= proxyhcheck
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy Health Check Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Proxy Health 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	=
    
    #
    # 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)/$(NLM_NAME).nlm
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib =
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/mod_proxy_hcheck.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 = \
    	$(PRELUDE) \
    	$(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 \
    	aprlib \
    	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 = \
    	@libc.imp \
    	@aprlib.imp \
    	@httpd.imp \
    	@mod_proxy.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_hcheck_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 $(APBUILD)/NWGNUtail.inc
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxy���������������������������������������������������������������0000664�0001751�0001751�00000017572�13004502175�017407� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(AP_WORK)/modules/generators \
    			$(AP_WORK)/modules/ssl \
    			$(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	= 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	=
    
    #
    # 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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 = \
    	@$(OBJDIR)/mod_proxy.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 $(OBJDIR)/mod_proxy.imp $(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
    
    $(OBJDIR)/mod_proxy.imp: NWGNUproxy
    	@echo $(DL)GEN  $@$(DL)
    	@echo $(DL)# Exports of mod_proxy$(DL)> $@
    	@echo $(DL) (AP$(VERSION_MAJMIN))$(DL)>> $@
    	@echo $(DL) proxy_module,$(DL)>> $@
    	@echo $(DL) proxy_hcmethods,$(DL)>> $@
    	@echo $(DL) proxy_hook_canon_handler,$(DL)>> $@
    	@echo $(DL) proxy_hook_get_canon_handler,$(DL)>> $@
    	@echo $(DL) proxy_hook_get_post_request,$(DL)>> $@
    	@echo $(DL) proxy_hook_get_pre_request,$(DL)>> $@
    	@echo $(DL) proxy_hook_get_scheme_handler,$(DL)>> $@
    	@echo $(DL) proxy_hook_post_request,$(DL)>> $@
    	@echo $(DL) proxy_hook_pre_request,$(DL)>> $@
    	@echo $(DL) proxy_hook_scheme_handler,$(DL)>> $@
    	@echo $(DL) proxy_run_canon_handler,$(DL)>> $@
    	@echo $(DL) proxy_run_create_req,$(DL)>> $@
    	@echo $(DL) proxy_run_fixups,$(DL)>> $@
    	@echo $(DL) proxy_run_post_request,$(DL)>> $@
    	@echo $(DL) proxy_run_pre_request,$(DL)>> $@
    	@echo $(DL) proxy_run_request_status,$(DL)>> $@
    	@echo $(DL) proxy_run_scheme_handler,$(DL)>> $@
    	@echo $(DL) ap_proxy_acquire_connection,$(DL)>> $@
    	@echo $(DL) ap_proxy_backend_broke,$(DL)>> $@
    	@echo $(DL) ap_proxy_buckets_lifetime_transform,$(DL)>> $@
    	@echo $(DL) ap_proxy_c2hex,$(DL)>> $@
    	@echo $(DL) ap_proxy_canon_netloc,$(DL)>> $@
    	@echo $(DL) ap_proxy_canonenc,$(DL)>> $@
    	@echo $(DL) ap_proxy_check_connection,$(DL)>> $@
    	@echo $(DL) ap_proxy_checkproxyblock,$(DL)>> $@
    	@echo $(DL) ap_proxy_checkproxyblock2,$(DL)>> $@
    	@echo $(DL) ap_proxy_conn_is_https,$(DL)>> $@
    	@echo $(DL) ap_proxy_connect_backend,$(DL)>> $@
    	@echo $(DL) ap_proxy_connect_to_backend,$(DL)>> $@
    	@echo $(DL) ap_proxy_connection_create,$(DL)>> $@
    	@echo $(DL) ap_proxy_connection_reusable,$(DL)>> $@
    	@echo $(DL) ap_proxy_cookie_reverse_map,$(DL)>> $@
    	@echo $(DL) ap_proxy_create_hdrbrgd,$(DL)>> $@
    	@echo $(DL) ap_proxy_define_balancer,$(DL)>> $@
    	@echo $(DL) ap_proxy_define_worker,$(DL)>> $@
    	@echo $(DL) ap_proxy_determine_connection,$(DL)>> $@
    	@echo $(DL) ap_proxy_find_balancershm,$(DL)>> $@
    	@echo $(DL) ap_proxy_find_workershm,$(DL)>> $@
    	@echo $(DL) ap_proxy_get_balancer,$(DL)>> $@
    	@echo $(DL) ap_proxy_get_worker,$(DL)>> $@
    	@echo $(DL) ap_proxy_hashfunc,$(DL)>> $@
    	@echo $(DL) ap_proxy_hex2c,$(DL)>> $@
    	@echo $(DL) ap_proxy_initialize_balancer,$(DL)>> $@
    	@echo $(DL) ap_proxy_initialize_worker,$(DL)>> $@
    	@echo $(DL) ap_proxy_is_domainname,$(DL)>> $@
    	@echo $(DL) ap_proxy_is_hostname,$(DL)>> $@
    	@echo $(DL) ap_proxy_is_ipaddr,$(DL)>> $@
    	@echo $(DL) ap_proxy_is_word,$(DL)>> $@
    	@echo $(DL) ap_proxy_location_reverse_map,$(DL)>> $@
    	@echo $(DL) ap_proxy_parse_wstatus,$(DL)>> $@
    	@echo $(DL) ap_proxy_pass_brigade,$(DL)>> $@
    	@echo $(DL) ap_proxy_port_of_scheme,$(DL)>> $@
    	@echo $(DL) ap_proxy_post_request,$(DL)>> $@
    	@echo $(DL) ap_proxy_pre_http_request,$(DL)>> $@
    	@echo $(DL) ap_proxy_pre_request,$(DL)>> $@
    	@echo $(DL) ap_proxy_release_connection,$(DL)>> $@
    	@echo $(DL) ap_proxy_set_wstatus,$(DL)>> $@
    	@echo $(DL) ap_proxy_share_balancer,$(DL)>> $@
    	@echo $(DL) ap_proxy_share_worker,$(DL)>> $@
    	@echo $(DL) ap_proxy_show_hcmethod,$(DL)>> $@
    	@echo $(DL) ap_proxy_ssl_connection_cleanup,$(DL)>> $@
    	@echo $(DL) ap_proxy_ssl_disable,$(DL)>> $@
    	@echo $(DL) ap_proxy_ssl_enable,$(DL)>> $@
    	@echo $(DL) ap_proxy_ssl_val,$(DL)>> $@
    	@echo $(DL) ap_proxy_strncpy,$(DL)>> $@
    	@echo $(DL) ap_proxy_sync_balancer,$(DL)>> $@
    	@echo $(DL) ap_proxy_trans_match,$(DL)>> $@
    	@echo $(DL) ap_proxy_transfer_between_connections,$(DL)>> $@
    	@echo $(DL) ap_proxy_valid_balancer_name,$(DL)>> $@
    	@echo $(DL) ap_proxy_worker_name,$(DL)>> $@
    	@echo $(DL) ap_proxyerror$(DL)>> $@
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy.mak������������������������������������������������������������0000664�0001751�0001751�00000023774�13304313421�020174� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy - Win32 Release" && "$(CFG)" != "mod_proxy - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy.obj"
    	-@erase "$(INTDIR)\mod_proxy.res"
    	-@erase "$(INTDIR)\mod_proxy_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_src.pdb"
    	-@erase "$(INTDIR)\proxy_util.obj"
    	-@erase "$(OUTDIR)\mod_proxy.exp"
    	-@erase "$(OUTDIR)\mod_proxy.lib"
    	-@erase "$(OUTDIR)\mod_proxy.pdb"
    	-@erase "$(OUTDIR)\mod_proxy.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /I "../http2" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy.so" /d LONG_NAME="proxy_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy.pdb" /debug /out:"$(OUTDIR)\mod_proxy.so" /implib:"$(OUTDIR)\mod_proxy.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy.obj" \
    	"$(INTDIR)\proxy_util.obj" \
    	"$(INTDIR)\mod_proxy.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_proxy.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy.so"
       if exist .\Release\mod_proxy.so.manifest mt.exe -manifest .\Release\mod_proxy.so.manifest -outputresource:.\Release\mod_proxy.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy.obj"
    	-@erase "$(INTDIR)\mod_proxy.res"
    	-@erase "$(INTDIR)\mod_proxy_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_src.pdb"
    	-@erase "$(INTDIR)\proxy_util.obj"
    	-@erase "$(OUTDIR)\mod_proxy.exp"
    	-@erase "$(OUTDIR)\mod_proxy.lib"
    	-@erase "$(OUTDIR)\mod_proxy.pdb"
    	-@erase "$(OUTDIR)\mod_proxy.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /I "../http2" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy.so" /d LONG_NAME="proxy_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy.pdb" /debug /out:"$(OUTDIR)\mod_proxy.so" /implib:"$(OUTDIR)\mod_proxy.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy.obj" \
    	"$(INTDIR)\proxy_util.obj" \
    	"$(INTDIR)\mod_proxy.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_proxy.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy.so"
       if exist .\Debug\mod_proxy.so.manifest mt.exe -manifest .\Debug\mod_proxy.so.manifest -outputresource:.\Debug\mod_proxy.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy.dep")
    !INCLUDE "mod_proxy.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy - Win32 Release" || "$(CFG)" == "mod_proxy - Win32 Debug"
    SOURCE=.\mod_proxy.c
    
    "$(INTDIR)\mod_proxy.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\proxy_util.c
    
    "$(INTDIR)\proxy_util.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy.so" /d LONG_NAME="proxy_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy.so" /d LONG_NAME="proxy_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ����httpd-2.4.64/modules/proxy/mod_proxy_uwsgi.mak������������������������������������������������������0000664�0001751�0001751�00000025777�13242652000�021417� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_uwsgi.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_uwsgi - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_uwsgi - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_uwsgi - Win32 Release" && "$(CFG)" != "mod_proxy_uwsgi - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_uwsgi.mak" CFG="mod_proxy_uwsgi - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_uwsgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_uwsgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_uwsgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_uwsgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_uwsgi.obj"
    	-@erase "$(INTDIR)\mod_proxy_uwsgi.res"
    	-@erase "$(INTDIR)\mod_proxy_uwsgi_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_uwsgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.exp"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.lib"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_uwsgi_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_uwsgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_uwsgi.so" /d LONG_NAME="proxy_uwsgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_uwsgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_uwsgi.pdb" /debug /out:"$(OUTDIR)\mod_proxy_uwsgi.so" /implib:"$(OUTDIR)\mod_proxy_uwsgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_uwsgi.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_uwsgi.obj" \
    	"$(INTDIR)\mod_proxy_uwsgi.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_uwsgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_uwsgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_uwsgi.so"
       if exist .\Release\mod_proxy_uwsgi.so.manifest mt.exe -manifest .\Release\mod_proxy_uwsgi.so.manifest -outputresource:.\Release\mod_proxy_uwsgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_uwsgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_uwsgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_uwsgi.obj"
    	-@erase "$(INTDIR)\mod_proxy_uwsgi.res"
    	-@erase "$(INTDIR)\mod_proxy_uwsgi_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_uwsgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.exp"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.lib"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_uwsgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_uwsgi_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_uwsgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_uwsgi.so" /d LONG_NAME="proxy_uwsgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_uwsgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_uwsgi.pdb" /debug /out:"$(OUTDIR)\mod_proxy_uwsgi.so" /implib:"$(OUTDIR)\mod_proxy_uwsgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_uwsgi.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_uwsgi.obj" \
    	"$(INTDIR)\mod_proxy_uwsgi.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_uwsgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_uwsgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_uwsgi.so"
       if exist .\Debug\mod_proxy_uwsgi.so.manifest mt.exe -manifest .\Debug\mod_proxy_uwsgi.so.manifest -outputresource:.\Debug\mod_proxy_uwsgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_uwsgi.dep")
    !INCLUDE "mod_proxy_uwsgi.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_uwsgi.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_uwsgi - Win32 Release" || "$(CFG)" == "mod_proxy_uwsgi - Win32 Debug"
    SOURCE=.\mod_proxy_uwsgi.c
    
    "$(INTDIR)\mod_proxy_uwsgi.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_uwsgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_uwsgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_uwsgi.so" /d LONG_NAME="proxy_uwsgi_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_uwsgi - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_uwsgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_uwsgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_uwsgi.so" /d LONG_NAME="proxy_uwsgi_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �httpd-2.4.64/modules/proxy/mod_proxy_hcheck.dsp�����������������������������������������������������0000664�0001751�0001751�00000011607�13017652517�021524� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_hcheck" - 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_hcheck - 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_hcheck.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_hcheck.mak" CFG="mod_proxy_hcheck - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_hcheck - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_hcheck - 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_hcheck - 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 "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_hcheck_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 0x409 /fo"Release/mod_proxy_hcheck.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_hcheck.so" /d LONG_NAME="proxy_hcheck_module for Apache"
    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 /out:".\Release\mod_proxy_hcheck.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_hcheck.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_proxy_hcheck.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_hcheck.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_hcheck.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_hcheck - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_hcheck_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 0x409 /fo"Debug/mod_proxy_hcheck.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_hcheck.so" /d LONG_NAME="proxy_hcheck_module for Apache"
    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 /out:".\Debug\mod_proxy_hcheck.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_hcheck.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_hcheck.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_hcheck.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_hcheck.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_hcheck - Win32 Release"
    # Name "mod_proxy_hcheck - 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_hcheck.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ajp.mak��������������������������������������������������������0000664�0001751�0001751�00000027147�12701473373�021041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_ajp.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_ajp - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_ajp - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_ajp - Win32 Release" && "$(CFG)" != "mod_proxy_ajp - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ajp - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_ajp.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_ajp.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ajp_header.obj"
    	-@erase "$(INTDIR)\ajp_link.obj"
    	-@erase "$(INTDIR)\ajp_msg.obj"
    	-@erase "$(INTDIR)\ajp_utils.obj"
    	-@erase "$(INTDIR)\mod_proxy_ajp.obj"
    	-@erase "$(INTDIR)\mod_proxy_ajp.res"
    	-@erase "$(INTDIR)\mod_proxy_ajp_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_ajp_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.exp"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.lib"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_ajp_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_ajp.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_ajp.so" /d LONG_NAME="proxy_ajp_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_ajp.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_ajp.pdb" /debug /out:"$(OUTDIR)\mod_proxy_ajp.so" /implib:"$(OUTDIR)\mod_proxy_ajp.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_ajp.obj" \
    	"$(INTDIR)\ajp_header.obj" \
    	"$(INTDIR)\ajp_link.obj" \
    	"$(INTDIR)\ajp_msg.obj" \
    	"$(INTDIR)\ajp_utils.obj" \
    	"$(INTDIR)\mod_proxy_ajp.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_ajp.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_ajp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_ajp.so"
       if exist .\Release\mod_proxy_ajp.so.manifest mt.exe -manifest .\Release\mod_proxy_ajp.so.manifest -outputresource:.\Release\mod_proxy_ajp.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ajp - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_ajp.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_ajp.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ajp_header.obj"
    	-@erase "$(INTDIR)\ajp_link.obj"
    	-@erase "$(INTDIR)\ajp_msg.obj"
    	-@erase "$(INTDIR)\ajp_utils.obj"
    	-@erase "$(INTDIR)\mod_proxy_ajp.obj"
    	-@erase "$(INTDIR)\mod_proxy_ajp.res"
    	-@erase "$(INTDIR)\mod_proxy_ajp_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_ajp_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.exp"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.lib"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ajp.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_ajp_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_ajp.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_ajp.so" /d LONG_NAME="proxy_ajp_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_ajp.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_ajp.pdb" /debug /out:"$(OUTDIR)\mod_proxy_ajp.so" /implib:"$(OUTDIR)\mod_proxy_ajp.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_ajp.obj" \
    	"$(INTDIR)\ajp_header.obj" \
    	"$(INTDIR)\ajp_link.obj" \
    	"$(INTDIR)\ajp_msg.obj" \
    	"$(INTDIR)\ajp_utils.obj" \
    	"$(INTDIR)\mod_proxy_ajp.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_ajp.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_ajp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_ajp.so"
       if exist .\Debug\mod_proxy_ajp.so.manifest mt.exe -manifest .\Debug\mod_proxy_ajp.so.manifest -outputresource:.\Debug\mod_proxy_ajp.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_ajp.dep")
    !INCLUDE "mod_proxy_ajp.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_ajp.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_ajp - Win32 Release" || "$(CFG)" == "mod_proxy_ajp - Win32 Debug"
    SOURCE=.\mod_proxy_ajp.c
    
    "$(INTDIR)\mod_proxy_ajp.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ajp_header.c
    
    "$(INTDIR)\ajp_header.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ajp_link.c
    
    "$(INTDIR)\ajp_link.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ajp_msg.c
    
    "$(INTDIR)\ajp_msg.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ajp_utils.c
    
    "$(INTDIR)\ajp_utils.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_ajp - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ajp - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ajp - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ajp - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ajp - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ajp - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ajp - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ajp - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_ajp - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_ajp.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_ajp.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_ajp.so" /d LONG_NAME="proxy_ajp_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ajp - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_ajp.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_ajp.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_ajp.so" /d LONG_NAME="proxy_ajp_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/ajp_link.c���������������������������������������������������������������0000664�0001751�0001751�00000006601�11667005541�017416� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    APLOG_USE_MODULE(proxy_ajp);
    
    apr_status_t ajp_ilink_send(apr_socket_t *sock, ajp_msg_t *msg)
    {
        char         *buf;
        apr_status_t status;
        apr_size_t   length;
    
        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, APLOGNO(01029)
                              "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, apr_byte_t *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, (char *)(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;
    
        hlen = msg->header_len;
    
        status = ilink_read(sock, msg->buf, hlen);
    
        if (status != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL, APLOGNO(01030)
                         "ajp_ilink_receive() can't receive header");
            return (APR_STATUS_IS_TIMEUP(status) ? APR_TIMEUP : AJP_ENO_HEADER);
        }
    
        status = ajp_msg_check_header(msg, &blen);
    
        if (status != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(01031)
                         "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, APLOGNO(01032)
                         "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, APLOGNO(01033)
                     "ajp_ilink_receive() received packet len=%" APR_SIZE_T_FMT
                     "type=%d",
                      blen, (int)msg->buf[hlen]);
    
        return APR_SUCCESS;
    }
    
    �������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_express.dsp����������������������������������������������������0000664�0001751�0001751�00000011615�11611132050�021746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_express" - 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_express - 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_express.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_express.mak" CFG="mod_proxy_express - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_express - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_express - 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_express - 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_express_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 0x409 /fo"Release/mod_proxy_express.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_express.so" /d LONG_NAME="proxy_balancer_module for Apache"
    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 /out:".\Release\mod_proxy_express.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_express.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_proxy_express.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_express.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_express.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_express - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_express_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 0x409 /fo"Debug/mod_proxy_express.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_express.so" /d LONG_NAME="proxy_balancer_module for Apache"
    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 /out:".\Debug\mod_proxy_express.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_express.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_express.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_express.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_express.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_express - Win32 Release"
    # Name "mod_proxy_express - 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_express.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxyajp������������������������������������������������������������0000664�0001751�0001751�00000010746�11546111464�020104� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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)/ajp_header.o \
    	$(OBJDIR)/ajp_msg.o \
    	$(OBJDIR)/ajp_link.o \
    	$(OBJDIR)/ajp_utils.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.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_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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������httpd-2.4.64/modules/proxy/NWGNUmakefile������������������������������������������������������������0000664�0001751�0001751�00000010534�12720075454�020003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    	$(OBJDIR)/proxyfcgi.nlm \
    	$(OBJDIR)/proxyscgi.nlm \
    	$(OBJDIR)/proxyexpress.nlm \
    	$(OBJDIR)/proxyhcheck.nlm \
    	$(OBJDIR)/proxylbm_busy.nlm \
    	$(OBJDIR)/proxylbm_hb.nlm \
    	$(OBJDIR)/proxylbm_req.nlm \
    	$(OBJDIR)/proxylbm_traf.nlm \
    	$(OBJDIR)/proxywstunnel.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/ajp_header.c�������������������������������������������������������������0000664�0001751�0001751�00000074645�14737240630�017727� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "util_script.h"
    
    APLOG_USE_MODULE(proxy_ajp);
    
    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 header
         * that is of interest.
         */
        if (len < 4 || len > 15)
            return UNKNOWN_METHOD;
    
        memset(header, 0, sizeof header);
        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 (strcmp(p, "CHARSET") == 0)
                            return SC_ACCEPT_CHARSET;
                        else if (strcmp(p,  "ENCODING") == 0)
                            return SC_ACCEPT_ENCODING;
                        else if (strcmp(p, "LANGUAGE") == 0)
                            return SC_ACCEPT_LANGUAGE;
                        else
                            return UNKNOWN_METHOD;
                    }
                    else
                        return UNKNOWN_METHOD;
                }
                else if (strcmp(p, "UTHORIZATION") == 0)
                    return SC_AUTHORIZATION;
                else
                    return UNKNOWN_METHOD;
            break;
            case 'C':
                if (strcmp(p, "OOKIE2") == 0)
                    return SC_COOKIE2;
                else if (strcmp(p, "OOKIE") == 0)
                    return SC_COOKIE;
                else if (strcmp(p, "ONNECTION") == 0)
                    return SC_CONNECTION;
                else if (strcmp(p, "ONTENT-TYPE") == 0)
                    return SC_CONTENT_TYPE;
                else if (strcmp(p, "ONTENT-LENGTH") == 0)
                    return SC_CONTENT_LENGTH;
                else
                    return UNKNOWN_METHOD;
            break;
            case 'H':
                if (strcmp(p, "OST") == 0)
                    return SC_HOST;
                else
                    return UNKNOWN_METHOD;
            break;
            case 'P':
                if (strcmp(p, "RAGMA") == 0)
                    return SC_PRAGMA;
                else
                    return UNKNOWN_METHOD;
            break;
            case 'R':
                if (strcmp(p, "EFERER") == 0)
                    return SC_REFERER;
                else
                    return UNKNOWN_METHOD;
            break;
            case 'U':
                if (strcmp(p, "SER-AGENT") == 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_CONNECT */
        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(request_rec *r)
    {
        int method_id = r->method_number;
        if (method_id < 0 || method_id > M_INVALID) {
            return UNKNOWN_METHOD;
        }
        else if (r->header_only) {
            return SC_M_HEAD;
        }
        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,
                                              const char *secret)
    {
        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_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, "Into ajp_marshal_into_msgb");
    
        if ((method = sc_for_req_method_by_id(r)) == UNKNOWN_METHOD) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
                   "ajp_marshal_into_msgb - Sending unknown method %s as request attribute",
                   r->method);
            method = SC_M_JK_STORED;
        }
    
        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_useragent_host(r, REMOTE_HOST, NULL);
    
        ajp_msg_reset(msg);
    
        if (ajp_msg_append_uint8(msg, CMD_AJP13_FORWARD_REQUEST)     ||
            ajp_msg_append_uint8(msg, (apr_byte_t) method)           ||
            ajp_msg_append_string(msg, r->protocol)                  ||
            ajp_msg_append_string(msg, uri->path)                    ||
            ajp_msg_append_string(msg, r->useragent_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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00968)
                   "ajp_marshal_into_msgb: "
                   "Error appending the message beginning");
            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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00969)
                           "ajp_marshal_into_msgb: "
                           "Error appending the header name");
                    return AJP_EOVERFLOW;
                }
            }
            else {
                if (ajp_msg_append_string(msg, elts[i].key)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00970)
                           "ajp_marshal_into_msgb: "
                           "Error appending the header name");
                    return AJP_EOVERFLOW;
                }
            }
    
            if (ajp_msg_append_string(msg, elts[i].val)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00971)
                       "ajp_marshal_into_msgb: "
                       "Error appending the header value");
                return AJP_EOVERFLOW;
            }
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r,
                       "ajp_marshal_into_msgb: Header[%d] [%s] = [%s]",
                       i, elts[i].key, elts[i].val);
        }
    
        if (secret) {
            if (ajp_msg_append_uint8(msg, SC_A_SECRET) ||
                ajp_msg_append_string(msg, secret)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03228)
                       "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00972)
                       "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00973)
                       "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00974)
                       "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00975)
                       "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>
     */
        /*
         * Only lookup SSL variables if we are currently running HTTPS.
         * Furthermore ensure that only variables get set in the AJP message
         * that are not NULL and not empty.
         */
        if (is_ssl) {
            if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r,
                                           AJP13_SSL_CLIENT_CERT_INDICATOR))
                && envvar[0]) {
                if (ajp_msg_append_uint8(msg, SC_A_SSL_CERT)
                    || ajp_msg_append_string(msg, envvar)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00976)
                                  "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))
                && envvar[0]) {
                if (ajp_msg_append_uint8(msg, SC_A_SSL_CIPHER)
                    || ajp_msg_append_string(msg, envvar)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00977)
                                  "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))
                && envvar[0]) {
                if (ajp_msg_append_uint8(msg, SC_A_SSL_SESSION)
                    || ajp_msg_append_string(msg, envvar)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00978)
                                  "ajp_marshal_into_msgb: "
                                  "Error appending the SSL session");
                    return AJP_EOVERFLOW;
                }
            }
    
            /* ssl_key_size is required by Servlet 2.3 API */
            if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r,
                                           AJP13_SSL_KEY_SIZE_INDICATOR))
                && envvar[0]) {
    
                if (ajp_msg_append_uint8(msg, SC_A_SSL_KEY_SIZE)
                    || ajp_msg_append_uint16(msg, (unsigned short) atoi(envvar))) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00979)
                                  "ajp_marshal_into_msgb: "
                                  "Error appending the SSL key size");
                    return APR_EGENERAL;
                }
            }
        }
        /* If the method was unrecognized, encode it as an attribute */
        if (method == SC_M_JK_STORED) {
            if (ajp_msg_append_uint8(msg, SC_A_STORED_METHOD)
                || ajp_msg_append_string(msg, r->method)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02438)
                              "ajp_marshal_into_msgb: "
                              "Error appending the method '%s' as request attribute",
                              r->method);
                return AJP_EOVERFLOW;
            }
        }
        /* Forward the SSL protocol name.
         * Modern Tomcat versions know how to retrieve
         * the protocol name from this attribute.
         */
        if (is_ssl) {
            if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r,
                                           AJP13_SSL_PROTOCOL_INDICATOR))
                && envvar[0]) {
                const char *key = SC_A_SSL_PROTOCOL;
                if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
                    ajp_msg_append_string(msg, key)   ||
                    ajp_msg_append_string(msg, envvar)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02830)
                            "ajp_marshal_into_msgb: "
                            "Error appending attribute %s=%s",
                            key, envvar);
                    return AJP_EOVERFLOW;
                }
            }
        }
        /* Forward the remote port information, which was forgotten
         * from the builtin data of the AJP 13 protocol.
         * Since the servlet spec allows to retrieve it via getRemotePort(),
         * we provide the port to the Tomcat connector as a request
         * attribute. Modern Tomcat versions know how to retrieve
         * the remote port from this attribute.
         */
        {
            const char *key = SC_A_REQ_REMOTE_PORT;
            char *val = apr_itoa(r->pool, r->useragent_addr->port);
            if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
                ajp_msg_append_string(msg, key)   ||
                ajp_msg_append_string(msg, val)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00980)
                        "ajp_marshal_into_msgb: "
                        "Error appending attribute %s=%s",
                        key, val);
                return AJP_EOVERFLOW;
            }
        }
        /* Forward the local ip address information, which was forgotten
         * from the builtin data of the AJP 13 protocol.
         * Since the servlet spec allows to retrieve it via getLocalAddr(),
         * we provide the address to the Tomcat connector as a request
         * attribute. Modern Tomcat versions know how to retrieve
         * the local address from this attribute.
         */
        {
            const char *key = SC_A_REQ_LOCAL_ADDR;
            char *val = r->connection->local_ip;
            if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
                ajp_msg_append_string(msg, key)   ||
                ajp_msg_append_string(msg, val)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02646)
                        "ajp_marshal_into_msgb: "
                        "Error appending attribute %s=%s",
                        key, val);
                return AJP_EOVERFLOW;
            }
        }
        /* 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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00981)
                            "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00982)
                   "ajp_marshal_into_msgb: "
                   "Error appending the message end");
            return AJP_EOVERFLOW;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
                "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 int addit_dammit(void *v, const char *key, const char *val)
    {
        apr_table_addn(v, key, val);
        return 1;
    }
    
    static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg,
                                               request_rec *r,
                                               proxy_dir_conf *dconf)
    {
        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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00983)
                    "ajp_unmarshal_response: Null status");
            return rc;
        }
        r->status = status;
    
        rc = ajp_msg_get_string(msg, &ptr);
        if (rc == APR_SUCCESS) {
    #if APR_CHARSET_EBCDIC /* copy only if we have to */
            ptr = apr_pstrdup(r->pool, ptr);
            ap_xlate_proto_from_ascii(ptr, strlen(ptr));
    #endif
            r->status_line =  apr_psprintf(r->pool, "%d %s", status, ptr);
        }
        else {
            r->status_line = NULL;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
               "ajp_unmarshal_response: status = %d", status);
    
        rc = ajp_msg_get_uint16(msg, &num_headers);
        if (rc == APR_SUCCESS) {
            apr_table_t *save_table;
    
            /* First, tuck away all already existing cookies */
            /*
             * Could optimize here, but just in case we want to
             * also save other headers, keep this logic.
             */
            save_table = apr_table_make(r->pool, num_headers + 2);
            apr_table_do(addit_dammit, save_table, r->headers_out,
                         "Set-Cookie", NULL);
            r->headers_out = save_table;
        }
        else {
            /*
             * Reset headers, but not to NULL because things below the chain expect
             * this to be non NULL e.g. the ap_content_length_filter.
             */
            r->headers_out = apr_table_make(r->pool, 1);
            num_headers = 0;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10405)
                    "ajp_unmarshal_response: Bad number of headers");
            return rc;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
               "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_get_uint16(msg, &name);
                stringname = long_res_header_for_sc(name);
                if (stringname == NULL) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00984)
                           "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00985)
                           "ajp_unmarshal_response: "
                           "Null header name");
                    return rc;
                }
                ap_xlate_proto_from_ascii(stringname, strlen(stringname));
            }
    
            rc = ajp_msg_get_string(msg, &value);
            if (rc != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00986)
                       "ajp_unmarshal_response: "
                       "Null header value");
                return rc;
            }
    
            /* Set-Cookie need additional processing */
            if (!ap_cstr_casecmp(stringname, "Set-Cookie")) {
                value = ap_proxy_cookie_reverse_map(r, dconf, value);
            }
            /* Location, Content-Location, URI and Destination need additional
             * processing */
            else if (!ap_cstr_casecmp(stringname, "Location")
                     || !ap_cstr_casecmp(stringname, "Content-Location")
                     || !ap_cstr_casecmp(stringname, "URI")
                     || !ap_cstr_casecmp(stringname, "Destination"))
            {
              value = ap_proxy_location_reverse_map(r, dconf, value);
            }
    
            ap_xlate_proto_from_ascii(value, strlen(value));
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r,
                   "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 (ap_cstr_casecmp(stringname, "Content-Type") == 0) {
                 /* add corresponding filter */
                ap_set_content_type(r, apr_pstrdup(r->pool, value));
                ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r,
                   "ajp_unmarshal_response: ap_set_content_type to '%s'", value);
            }
        }
    
        /* AJP has its own body framing mechanism which we don't
         * match against any provided Content-Length, so let the
         * core determine C-L vs T-E based on what's actually sent.
         */
        if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
            apr_table_unset(r->headers_out, "Content-Length");
        apr_table_unset(r->headers_out, "Transfer-Encoding");
    
        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_size_t buffsize,
                                 apr_uri_t *uri,
                                 const char *secret)
    {
        ajp_msg_t *msg;
        apr_status_t rc;
    
        rc = ajp_msg_create(r->pool, buffsize, &msg);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00987)
                   "ajp_send_header: ajp_msg_create failed");
            return rc;
        }
    
        rc = ajp_marshal_into_msgb(msg, r, uri, secret);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00988)
                   "ajp_send_header: ajp_marshal_into_msgb failed");
            return rc;
        }
    
        rc = ajp_ilink_send(sock, msg);
        ajp_msg_log(r, msg, "ajp_send_header: ajp_ilink_send packet dump");
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00989)
                   "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,
                                 apr_size_t buffsize,
                                 ajp_msg_t **msg)
    {
        apr_byte_t result;
        apr_status_t rc;
    
        if (*msg) {
            rc = ajp_msg_reuse(*msg);
            if (rc != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00990)
                       "ajp_read_header: ajp_msg_reuse failed");
                return rc;
            }
        }
        else {
            rc = ajp_msg_create(r->pool, buffsize, msg);
            if (rc != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00991)
                       "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00992)
                   "ajp_read_header: ajp_ilink_receive failed");
            return rc;
        }
        ajp_msg_log(r, *msg, "ajp_read_header: ajp_ilink_receive packet dump");
        rc = ajp_msg_peek_uint8(*msg, &result);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00993)
                          "ajp_read_header: ajp_msg_peek_uint8 failed");
            return rc;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                   "ajp_read_header: ajp_ilink_received %s (0x%02x)",
                   ajp_type_str(result), 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_rerror(APLOG_MARK, APLOG_TRACE6, 0, r,
                   "ajp_parse_type: got %s (0x%02x)",
                   ajp_type_str(result), result);
        return (int) result;
    }
    
    /* parse the header */
    apr_status_t ajp_parse_header(request_rec  *r, proxy_dir_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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00994)
                   "ajp_parse_headers: ajp_msg_get_byte failed");
            return rc;
        }
        if (result != CMD_AJP13_SEND_HEADERS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00995)
                   "ajp_parse_headers: wrong type %s (0x%02x) expecting %s (0x%02x)",
                   ajp_type_str(result), result,
                   ajp_type_str(CMD_AJP13_SEND_HEADERS), CMD_AJP13_SEND_HEADERS);
            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;
        apr_uint16_t expected_len;
    
        rc = ajp_msg_get_uint8(msg, &result);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00996)
                   "ajp_parse_data: ajp_msg_get_byte failed");
            return rc;
        }
        if (result != CMD_AJP13_SEND_BODY_CHUNK) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00997)
                   "ajp_parse_data: wrong type %s (0x%02x) expecting %s (0x%02x)",
                   ajp_type_str(result), result,
                   ajp_type_str(CMD_AJP13_SEND_BODY_CHUNK), CMD_AJP13_SEND_BODY_CHUNK);
            return AJP_EBAD_HEADER;
        }
        rc = ajp_msg_get_uint16(msg, len);
        if (rc != APR_SUCCESS) {
            return rc;
        }
        /*
         * msg->len contains the complete length of the message including all
         * headers. So the expected length for a CMD_AJP13_SEND_BODY_CHUNK is
         * msg->len minus the sum of
         * AJP_HEADER_LEN    : The length of the header to every AJP message.
         * AJP_HEADER_SZ_LEN : The header giving the size of the chunk.
         * 1                 : The CMD_AJP13_SEND_BODY_CHUNK indicator byte (0x03).
         * 1                 : The last byte of this message always seems to be
         *                     0x00 and is not part of the chunk.
         */
        expected_len = msg->len - (AJP_HEADER_LEN + AJP_HEADER_SZ_LEN + 1 + 1);
        if (*len != expected_len) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00998)
                   "ajp_parse_data: Wrong chunk length. Length of chunk is %i,"
                   " expected length is %i.", *len, expected_len);
            return AJP_EBAD_HEADER;
        }
        *ptr = (char *)&(msg->buf[msg->pos]);
        return APR_SUCCESS;
    }
    
    /* Check the reuse flag in CMD_AJP13_END_RESPONSE */
    apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg,
                                 apr_byte_t *reuse)
    {
        apr_byte_t result;
        apr_status_t rc;
    
        rc = ajp_msg_get_uint8(msg, &result);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00999)
                   "ajp_parse_reuse: ajp_msg_get_byte failed");
            return rc;
        }
        if (result != CMD_AJP13_END_RESPONSE) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01000)
                   "ajp_parse_reuse: wrong type %s (0x%02x) expecting %s (0x%02x)",
                   ajp_type_str(result), result,
                   ajp_type_str(CMD_AJP13_END_RESPONSE), CMD_AJP13_END_RESPONSE);
            return AJP_EBAD_HEADER;
        }
        return ajp_msg_get_uint8(msg, reuse);
    }
    
    /*
     * 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, *len, msg)) != APR_SUCCESS)
            return rc;
        ajp_msg_reset(*msg);
        *ptr = (char *)&((*msg)->buf[6]);
        *len =  *len - 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);
    
    }
    �������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_hcheck.c�������������������������������������������������������0000664�0001751�0001751�00000136330�14526115472�021161� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "mod_watchdog.h"
    #include "ap_slotmem.h"
    #include "ap_expr.h"
    #if APR_HAS_THREADS
    #include "apr_thread_pool.h"
    #endif
    #include "http_ssl.h"
    
    module AP_MODULE_DECLARE_DATA proxy_hcheck_module;
    
    #define HCHECK_WATHCHDOG_NAME ("_proxy_hcheck_")
    #define HC_THREADPOOL_SIZE (16)
    
    /* Why? So we can easily set/clear HC_USE_THREADS during dev testing */
    #if APR_HAS_THREADS
    #ifndef HC_USE_THREADS
    #define HC_USE_THREADS 1
    #endif
    #else
    #define HC_USE_THREADS 0
    #endif
    
    typedef struct {
        char *name;
        hcmethod_t method;
        int passes;
        int fails;
        apr_interval_time_t interval;
        char *hurl;
        char *hcexpr;
    } hc_template_t;
    
    typedef struct {
        char *expr;
        ap_expr_info_t *pexpr;       /* parsed expression */
    } hc_condition_t;
    
    typedef struct {
        apr_pool_t *p;
        apr_array_header_t *templates;
        apr_table_t *conditions;
        apr_hash_t *hcworkers;
        server_rec *s;
    } sctx_t;
    
    /* Used in the HC worker via the context field */
    typedef struct {
        const char *path;   /* The path of the original worker URL */
        const char *method; /* Method string for the HTTP/AJP request */
        const char *req;    /* pre-formatted HTTP/AJP request */
        proxy_worker *w;    /* Pointer to the actual worker */
        const char *protocol; /* HTTP 1.0 or 1.1? */
    } wctx_t;
    
    typedef struct {
        apr_pool_t *ptemp;
        sctx_t *ctx;
        proxy_balancer *balancer;
        proxy_worker *worker;
        proxy_worker *hc;
        apr_time_t *now;
    } baton_t;
    
    static APR_OPTIONAL_FN_TYPE(ajp_handle_cping_cpong) *ajp_handle_cping_cpong = NULL;
    
    static void *hc_create_config(apr_pool_t *p, server_rec *s)
    {
        sctx_t *ctx = apr_pcalloc(p, sizeof(sctx_t));
        ctx->s = s;
        apr_pool_create(&ctx->p, p);
        apr_pool_tag(ctx->p, "proxy_hcheck");
        ctx->templates = apr_array_make(p, 10, sizeof(hc_template_t));
        ctx->conditions = apr_table_make(p, 10);
        ctx->hcworkers = apr_hash_make(p);
        return ctx;
    }
    
    static ap_watchdog_t *watchdog;
    #if HC_USE_THREADS
    static apr_thread_pool_t *hctp;
    static int tpsize;
    #endif
    
    /*
     * This serves double duty by not only validating (and creating)
     * the health-check template, but also ties into set_worker_param()
     * which does the actual setting of worker params in shm.
     */
    static const char *set_worker_hc_param(apr_pool_t *p,
                                        server_rec *s,
                                        proxy_worker *worker,
                                        const char *key,
                                        const char *val,
                                        void *v)
    {
        int ival;
        hc_template_t *temp;
        sctx_t *ctx = (sctx_t *) ap_get_module_config(s->module_config,
                                                      &proxy_hcheck_module);
        if (!worker && !v) {
            return "Bad call to set_worker_hc_param()";
        }
        if (!ctx) {
            ctx = hc_create_config(p, s);
            ap_set_module_config(s->module_config, &proxy_hcheck_module, ctx);
        }
        temp = (hc_template_t *)v;
        if (!strcasecmp(key, "hctemplate")) {
            hc_template_t *template;
            template = (hc_template_t *)ctx->templates->elts;
            for (ival = 0; ival < ctx->templates->nelts; ival++, template++) {
                if (!ap_cstr_casecmp(template->name, val)) {
                    if (worker) {
                        worker->s->method = template->method;
                        worker->s->interval = template->interval;
                        worker->s->passes = template->passes;
                        worker->s->fails = template->fails;
                        PROXY_STRNCPY(worker->s->hcuri, template->hurl);
                        PROXY_STRNCPY(worker->s->hcexpr, template->hcexpr);
                    } else {
                        temp->method = template->method;
                        temp->interval = template->interval;
                        temp->passes = template->passes;
                        temp->fails = template->fails;
                        temp->hurl = apr_pstrdup(p, template->hurl);
                        temp->hcexpr = apr_pstrdup(p, template->hcexpr);
                    }
                    return NULL;
                }
            }
            return apr_psprintf(p, "Unknown ProxyHCTemplate name: %s", val);
        }
        else if (!strcasecmp(key, "hcmethod")) {
            proxy_hcmethods_t *method = proxy_hcmethods;
            for (; method->name; method++) {
                if (!ap_cstr_casecmp(val, method->name)) {
                    if (!method->implemented) {
                        return apr_psprintf(p, "Health check method %s not (yet) implemented",
                                            val);
                    }
                    if (worker) {
                        worker->s->method = method->method;
                    } else {
                        temp->method = method->method;
                    }
                    return NULL;
                }
            }
            return "Unknown method";
        }
        else if (!strcasecmp(key, "hcinterval")) {
            apr_interval_time_t hci;
            apr_status_t rv;
            rv = ap_timeout_parameter_parse(val, &hci, "s");
            if (rv != APR_SUCCESS)
                return "Unparse-able hcinterval setting";
            if (hci < AP_WD_TM_SLICE)
                return apr_psprintf(p, "Interval must be a positive value greater than %"
                                    APR_TIME_T_FMT "ms", apr_time_as_msec(AP_WD_TM_SLICE));
            if (worker) {
                worker->s->interval = hci;
            } else {
                temp->interval = hci;
            }
        }
        else if (!strcasecmp(key, "hcpasses")) {
            ival = atoi(val);
            if (ival < 0)
                return "Passes must be a positive value";
            if (worker) {
                worker->s->passes = ival;
            } else {
                temp->passes = ival;
            }
        }
        else if (!strcasecmp(key, "hcfails")) {
            ival = atoi(val);
            if (ival < 0)
                return "Fails must be a positive value";
            if (worker) {
                worker->s->fails = ival;
            } else {
                temp->fails = ival;
            }
        }
        else if (!strcasecmp(key, "hcuri")) {
            if (strlen(val) >= sizeof(worker->s->hcuri))
                return apr_psprintf(p, "Health check uri length must be < %d characters",
                        (int)sizeof(worker->s->hcuri));
            if (worker) {
                PROXY_STRNCPY(worker->s->hcuri, val);
            } else {
                temp->hurl = apr_pstrdup(p, val);
            }
        }
        else if (!strcasecmp(key, "hcexpr")) {
            hc_condition_t *cond;
            cond = (hc_condition_t *)apr_table_get(ctx->conditions, val);
            if (!cond) {
                return apr_psprintf(p, "Unknown health check condition expr: %s", val);
            }
            /* This check is wonky... a known expr can't be this big. Check anyway */
            if (strlen(val) >= sizeof(worker->s->hcexpr))
                return apr_psprintf(p, "Health check uri length must be < %d characters",
                        (int)sizeof(worker->s->hcexpr));
            if (worker) {
                PROXY_STRNCPY(worker->s->hcexpr, val);
            } else {
                temp->hcexpr = apr_pstrdup(p, val);
            }
        }
      else {
            return "unknown Worker hcheck parameter";
        }
        return NULL;
    }
    
    static const char *set_hc_condition(cmd_parms *cmd, void *dummy, const char *arg)
    {
        char *name = NULL;
        char *expr;
        sctx_t *ctx;
        hc_condition_t *cond;
    
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return err;
        ctx = (sctx_t *) ap_get_module_config(cmd->server->module_config,
                                              &proxy_hcheck_module);
    
        name = ap_getword_conf(cmd->pool, &arg);
        if (!*name) {
            return apr_pstrcat(cmd->temp_pool, "Missing expression name for ",
                               cmd->cmd->name, NULL);
        }
        if (strlen(name) > (PROXY_WORKER_MAX_SCHEME_SIZE - 1)) {
            return apr_psprintf(cmd->temp_pool, "Expression name limited to %d characters",
                               (PROXY_WORKER_MAX_SCHEME_SIZE - 1));
        }
        /* get expr. Allow fancy new {...} quoting style */
        expr = ap_getword_conf2(cmd->temp_pool, &arg);
        if (!*expr) {
            return apr_pstrcat(cmd->temp_pool, "Missing expression for ",
                               cmd->cmd->name, NULL);
        }
        cond = apr_palloc(cmd->pool, sizeof(hc_condition_t));
        cond->pexpr = ap_expr_parse_cmd(cmd, expr, 0, &err, NULL);
        if (err) {
            return apr_psprintf(cmd->temp_pool, "Could not parse expression \"%s\": %s",
                                expr, err);
        }
        cond->expr = apr_pstrdup(cmd->pool, expr);
        apr_table_setn(ctx->conditions, name, (void *)cond);
        expr = ap_getword_conf(cmd->temp_pool, &arg);
        if (*expr) {
            return "error: extra parameter(s)";
        }
        return NULL;
    }
    
    static const char *set_hc_template(cmd_parms *cmd, void *dummy, const char *arg)
    {
        char *name = NULL;
        char *word, *val;
        hc_template_t *template;
        sctx_t *ctx;
    
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return err;
        ctx = (sctx_t *) ap_get_module_config(cmd->server->module_config,
                                              &proxy_hcheck_module);
    
        name = ap_getword_conf(cmd->temp_pool, &arg);
        if (!*name) {
            return apr_pstrcat(cmd->temp_pool, "Missing template name for ",
                               cmd->cmd->name, NULL);
        }
    
        template = (hc_template_t *)apr_array_push(ctx->templates);
    
        template->name = apr_pstrdup(cmd->pool, name);
        template->method = template->passes = template->fails = 1;
        template->interval = apr_time_from_sec(HCHECK_WATHCHDOG_DEFAULT_INTERVAL);
        template->hurl = NULL;
        template->hcexpr = NULL;
        while (*arg) {
            word = ap_getword_conf(cmd->pool, &arg);
            val = strchr(word, '=');
            if (!val) {
                return "Invalid ProxyHCTemplate parameter. Parameter must be "
                       "in the form 'key=value'";
            }
            else
                *val++ = '\0';
            err = set_worker_hc_param(cmd->pool, ctx->s, NULL, word, val, template);
    
            if (err) {
                /* get rid of recently pushed (bad) template */
                apr_array_pop(ctx->templates);
                return apr_pstrcat(cmd->temp_pool, "ProxyHCTemplate: ", err, " ", word, "=", val, "; ", name, NULL);
            }
            /* No error means we have a valid template */
        }
        return NULL;
    }
    
    #if HC_USE_THREADS
    static const char *set_hc_tpsize (cmd_parms *cmd, void *dummy, const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err)
            return err;
    
        tpsize = atoi(arg);
        if (tpsize < 0)
            return "Invalid ProxyHCTPsize parameter. Parameter must be "
                   ">= 0";
        return NULL;
    }
    #endif
    
    /*
     * Create a dummy request rec, simply so we can use ap_expr.
     * Use our short-lived pool for bucket_alloc so that we can simply move
     * buckets and use them after the backend connection is released.
     */
    static request_rec *create_request_rec(apr_pool_t *p, server_rec *s,
                                           proxy_balancer *balancer,
                                           const char *method,
                                           const char *protocol)
    {
        request_rec *r;
    
        r = apr_pcalloc(p, sizeof(request_rec));
        r->pool            = p;
        r->server          = s;
    
        r->per_dir_config = r->server->lookup_defaults;
        if (balancer->section_config) {
            r->per_dir_config = ap_merge_per_dir_configs(r->pool,
                                                         r->per_dir_config,
                                                         balancer->section_config);
        }
    
        r->proxyreq        = PROXYREQ_RESPONSE;
    
        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, 1);
        r->trailers_in     = apr_table_make(r->pool, 1);
        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->trailers_out    = apr_table_make(r->pool, 1);
        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->sent_bodyct     = 0;                      /* bytect isn't for body */
    
        r->read_length     = 0;
        r->read_body       = REQUEST_NO_BODY;
    
        r->status          = HTTP_OK;  /* Until further notice */
        r->the_request     = NULL;
    
        /* 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;
    
    
        /* Time to populate r with the data we have. */
        r->method = method;
        /* 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_OPTIONS
                || (r->method_number == M_GET && r->method[0] == 'H')) {
            r->header_only = 1;
        }
        else {
            r->header_only = 0;
        }
        r->protocol = "HTTP/1.0";
        r->proto_num = HTTP_VERSION(1, 0);
        if ( protocol && (protocol[7] == '1') ) {
            r->protocol = "HTTP/1.1";
            r->proto_num = HTTP_VERSION(1, 1);
        }
        r->hostname = NULL;
    
        return r;
    }
    
    static void set_request_connection(request_rec *r, conn_rec *conn)
    {
        conn->bucket_alloc = apr_bucket_alloc_create(r->pool);
        r->connection = conn;
    
        r->kept_body = apr_brigade_create(r->pool, conn->bucket_alloc);
        r->output_filters = r->proto_output_filters = conn->output_filters;
        r->input_filters = r->proto_input_filters = conn->input_filters;
    
        r->useragent_addr = conn->client_addr;
        r->useragent_ip = conn->client_ip;
    }
    
    static void create_hcheck_req(wctx_t *wctx, proxy_worker *hc,
                                  apr_pool_t *p)
    {
        char *req = NULL;
        const char *method = NULL;
        const char *protocol = NULL;
    
        /* TODO: Fold into switch/case below? This seems more obvious */
        if ( (hc->s->method == OPTIONS11) || (hc->s->method == HEAD11) || (hc->s->method == GET11) ) {
            protocol = "HTTP/1.1";
        } else {
            protocol = "HTTP/1.0";
        }
        switch (hc->s->method) {
            case OPTIONS:
            case OPTIONS11:
                method = "OPTIONS";
                req = apr_psprintf(p,
                                   "OPTIONS * %s\r\n"
                                   "Host: %s:%d\r\n"
                                   "\r\n", protocol,
                                   hc->s->hostname_ex, (int)hc->s->port);
                break;
    
            case HEAD:
            case HEAD11:
                method = "HEAD";
                /* fallthru */
            case GET:
            case GET11:
                if (!method) { /* did we fall thru? If not, we are GET */
                    method = "GET";
                }
                req = apr_psprintf(p,
                                   "%s %s%s%s %s\r\n"
                                   "Host: %s:%d\r\n"
                                   "\r\n",
                                   method,
                                   (wctx->path ? wctx->path : ""),
                                   (wctx->path && *hc->s->hcuri ? "/" : "" ),
                                   (*hc->s->hcuri ? hc->s->hcuri : ""),
                                   protocol,
                                   hc->s->hostname_ex, (int)hc->s->port);
                break;
    
            default:
                break;
        }
        wctx->req = req;
        wctx->method = method;
        wctx->protocol = protocol;
    }
    
    static proxy_worker *hc_get_hcworker(sctx_t *ctx, proxy_worker *worker,
                                         apr_pool_t *p)
    {
        proxy_worker *hc = NULL;
        apr_port_t port;
    
        hc = (proxy_worker *)apr_hash_get(ctx->hcworkers, &worker, sizeof worker);
        if (!hc) {
            apr_uri_t uri;
            apr_status_t rv;
            const char *url = worker->s->name_ex;
            wctx_t *wctx = apr_pcalloc(ctx->p, sizeof(wctx_t));
    
            port = (worker->s->port ? worker->s->port
                                    : ap_proxy_port_of_scheme(worker->s->scheme));
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(03248)
                         "Creating hc worker %pp for %s://%s:%d",
                         worker, worker->s->scheme, worker->s->hostname_ex,
                         (int)port);
    
            ap_proxy_define_worker(ctx->p, &hc, NULL, NULL, worker->s->name_ex, 0);
            apr_snprintf(hc->s->name, sizeof hc->s->name, "%pp", worker);
            apr_snprintf(hc->s->name_ex, sizeof hc->s->name_ex, "%pp", worker);
            PROXY_STRNCPY(hc->s->hostname, worker->s->hostname); /* for compatibility */
            PROXY_STRNCPY(hc->s->hostname_ex, worker->s->hostname_ex);
            PROXY_STRNCPY(hc->s->scheme,   worker->s->scheme);
            PROXY_STRNCPY(hc->s->hcuri,    worker->s->hcuri);
            PROXY_STRNCPY(hc->s->hcexpr,   worker->s->hcexpr);
            hc->hash.def = hc->s->hash.def = ap_proxy_hashfunc(hc->s->name_ex,
                                                               PROXY_HASHFUNC_DEFAULT);
            hc->hash.fnv = hc->s->hash.fnv = ap_proxy_hashfunc(hc->s->name_ex,
                                                               PROXY_HASHFUNC_FNV);
            hc->s->port = port;
            hc->s->conn_timeout_set = worker->s->conn_timeout_set;
            hc->s->conn_timeout = worker->s->conn_timeout;
            hc->s->ping_timeout_set = worker->s->ping_timeout_set;
            hc->s->ping_timeout = worker->s->ping_timeout;
            hc->s->timeout_set = worker->s->timeout_set;
            hc->s->timeout = worker->s->timeout;
            /* Do not disable worker in case of errors */
            hc->s->status |= PROXY_WORKER_IGNORE_ERRORS;
            /* Mark as the "generic" worker */
            hc->s->status |= PROXY_WORKER_GENERIC;
            ap_proxy_initialize_worker(hc, ctx->s, ctx->p);
            hc->s->is_address_reusable = worker->s->is_address_reusable;
            hc->s->disablereuse = worker->s->disablereuse;
            hc->s->method = worker->s->method;
            rv = apr_uri_parse(p, url, &uri);
            if (rv == APR_SUCCESS) {
                wctx->path = apr_pstrdup(ctx->p, uri.path);
            }
            wctx->w = worker;
            create_hcheck_req(wctx, hc, ctx->p);
            hc->context = wctx;
            apr_hash_set(ctx->hcworkers, &worker, sizeof worker, hc);
        }
        /* This *could* have changed via the Balancer Manager */
        /* TODO */
        if (hc->s->method != worker->s->method) {
            wctx_t *wctx = hc->context;
            port = (worker->s->port ? worker->s->port
                                    : ap_proxy_port_of_scheme(worker->s->scheme));
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(03311)
                         "Updating hc worker %pp for %s://%s:%d",
                         worker, worker->s->scheme, worker->s->hostname_ex,
                         (int)port);
            hc->s->method = worker->s->method;
            create_hcheck_req(wctx, hc, ctx->p);
        }
        return hc;
    }
    
    static int hc_determine_connection(const char *proxy_function,
                                       proxy_conn_rec *backend,
                                       server_rec *s)
    {
        proxy_worker *worker = backend->worker;
        apr_status_t rv;
    
        /*
         * normally, this is done in ap_proxy_determine_connection().
         * TODO: Look at using ap_proxy_determine_connection() with a
         * fake request_rec
         */
        rv = ap_proxy_determine_address(proxy_function, backend,
                                        worker->s->hostname_ex, worker->s->port,
                                        0, NULL, s);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03249)
                         "DNS lookup failure for: %s:%hu",
                         worker->s->hostname_ex, worker->s->port);
            return !OK;
        }
    
        return OK;
    }
    
    static apr_status_t backend_cleanup(const char *proxy_function, proxy_conn_rec *backend,
                                        server_rec *s, int status)
    {
        if (backend) {
            backend->close = 1;
            ap_proxy_release_connection(proxy_function, backend, s);
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03251)
                             "Health check %s Status (%d) for %s.",
                             ap_proxy_show_hcmethod(backend->worker->s->method),
                             status,
                             backend->worker->s->name_ex);
        }
        if (status != OK) {
            return APR_EGENERAL;
        }
        return APR_SUCCESS;
    }
    
    static int hc_get_backend(const char *proxy_function, proxy_conn_rec **backend,
                              proxy_worker *hc, sctx_t *ctx)
    {
        int status;
    
        status = ap_proxy_acquire_connection(proxy_function, backend, hc, ctx->s);
        if (status != OK) {
            return status;
        }
    
        if (strcmp(hc->s->scheme, "https") == 0 || strcmp(hc->s->scheme, "wss") == 0 ) {
            if (!ap_ssl_has_outgoing_handlers()) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ctx->s, APLOGNO(03252)
                              "mod_ssl not configured?");
                return !OK;
            }
            (*backend)->is_ssl = 1;
        }
    
        return hc_determine_connection(proxy_function, *backend, ctx->s);
    }
    
    static apr_status_t hc_init_baton(baton_t *baton)
    {
        sctx_t *ctx = baton->ctx;
        proxy_worker *worker = baton->worker, *hc;
        apr_status_t rv = APR_SUCCESS;
        int once = 0;
    
        /*
         * Since this is the watchdog, workers never actually handle a
         * request here, and so the local data isn't initialized (of
         * course, the shared memory is). So we need to bootstrap
         * worker->cp. Note, we only need do this once.
         */
        if (!worker->cp) {
            rv = ap_proxy_initialize_worker(worker, ctx->s, ctx->p);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ctx->s, APLOGNO(03250) "Cannot init worker");
                return rv;
            }
            once = 1;
        }
    
        baton->hc = hc = hc_get_hcworker(ctx, worker, baton->ptemp);
    
        /* Try to resolve the worker address once if it's reusable */
        if (once && worker->s->is_address_reusable) {
            proxy_conn_rec *backend = NULL;
            if (hc_get_backend("HCHECK", &backend, hc, ctx)) {
                rv = APR_EGENERAL;
            }
            if (backend) {
                backend->close = 1;
                ap_proxy_release_connection("HCHECK", backend, ctx->s);
            }
        }
    
        return rv;
    }
    
    static apr_status_t hc_check_cping(baton_t *baton, apr_thread_t *thread)
    {
        int status;
        sctx_t *ctx = baton->ctx;
        proxy_worker *hc = baton->hc;
        proxy_conn_rec *backend = NULL;
        apr_pool_t *ptemp = baton->ptemp;
        request_rec *r;
        apr_interval_time_t timeout;
    
        if (!ajp_handle_cping_cpong) {
            return APR_ENOTIMPL;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, baton->ctx->s, "HCCPING starting");
        if ((status = hc_get_backend("HCCPING", &backend, hc, ctx)) != OK) {
            return backend_cleanup("HCCPING", backend, ctx->s, status);
        }
        if ((status = ap_proxy_connect_backend("HCCPING", backend, hc, ctx->s)) != OK) {
            return backend_cleanup("HCCPING", backend, ctx->s, status);
        }
        r = create_request_rec(ptemp, ctx->s, baton->balancer, "CPING", NULL);
        if ((status = ap_proxy_connection_create_ex("HCCPING", backend, r)) != OK) {
            return backend_cleanup("HCCPING", backend, ctx->s, status);
        }
        set_request_connection(r, backend->connection);
        backend->connection->current_thread = thread;
    
        if (hc->s->ping_timeout_set) {
            timeout = hc->s->ping_timeout;
        } else if ( hc->s->conn_timeout_set) {
            timeout = hc->s->conn_timeout;
        } else if ( hc->s->timeout_set) {
            timeout = hc->s->timeout;
        } else {
            /* default to socket timeout */
            apr_socket_timeout_get(backend->sock, &timeout); 
        }
        status = ajp_handle_cping_cpong(backend->sock, r, timeout);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, baton->ctx->s, "HCCPING done %d", status);
        return backend_cleanup("HCCPING", backend, ctx->s, status);
    }
    
    static apr_status_t hc_check_tcp(baton_t *baton)
    {
        int status;
        sctx_t *ctx = baton->ctx;
        proxy_worker *hc = baton->hc;
        proxy_conn_rec *backend = NULL;
    
        status = hc_get_backend("HCTCP", &backend, hc, ctx);
        if (status == OK) {
            status = ap_proxy_connect_backend("HCTCP", backend, hc, ctx->s);
            /* does an unconditional ap_proxy_is_socket_connected() */
        }
        return backend_cleanup("HCTCP", backend, ctx->s, status);
    }
    
    static int hc_send(request_rec *r, const char *out, apr_bucket_brigade *bb)
    {
        apr_status_t rv;
        conn_rec *c = r->connection;
        apr_bucket_alloc_t *ba = c->bucket_alloc;
        ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, r->server, "%s", out);
        APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(out, strlen(out),
                                                           r->pool, ba));
        APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(ba));
        rv = ap_pass_brigade(c->output_filters, bb);
        apr_brigade_cleanup(bb);
        return (rv) ? !OK : OK;
    }
    
    static int hc_read_headers(request_rec *r)
    {
        char buffer[HUGE_STRING_LEN];
        int len;
        const char *ct;
    
        len = ap_getline(buffer, sizeof(buffer), r, 1);
        if (len <= 0) {
            return !OK;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(03254)
                     "%.*s", len, buffer);
        /* for the below, see ap_proxy_http_process_response() */
        if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) {
            int major;
            char keepchar;
            int proxy_status = OK;
            const char *proxy_status_line = NULL;
    
            major = buffer[5] - '0';
            if ((major != 1) || (len >= sizeof(buffer)-1)) {
                return !OK;
            }
    
            keepchar = buffer[12];
            buffer[12] = '\0';
            proxy_status = atoi(&buffer[9]);
            if (keepchar != '\0') {
                buffer[12] = keepchar;
            } else {
                buffer[12] = ' ';
                buffer[13] = '\0';
            }
            proxy_status_line = apr_pstrdup(r->pool, &buffer[9]);
            r->status = proxy_status;
            r->status_line = proxy_status_line;
        } else {
            return !OK;
        }
    
        /* OK, 1st line is OK... scarf in the headers */
        while ((len = ap_getline(buffer, sizeof(buffer), r, 1)) > 0) {
            char *value, *end;
            ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, r->server, "%.*s",
                         len, buffer);
            if (!(value = strchr(buffer, ':'))) {
                return !OK;
            }
            *value = '\0';
            ++value;
            while (apr_isspace(*value))
                ++value;            /* Skip to start of value   */
            for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
                *end = '\0';
            apr_table_add(r->headers_out, buffer, value);
        }
    
        /* Set the Content-Type for the request if set */
        if ((ct = apr_table_get(r->headers_out, "Content-Type")) != NULL)
            ap_set_content_type(r, ct);
    
        return OK;
    }
    
    static int hc_read_body(request_rec *r, apr_bucket_brigade *bb)
    {
        apr_status_t rv = APR_SUCCESS;
        int seen_eos = 0;
    
        do {
            apr_size_t len = HUGE_STRING_LEN;
    
            apr_brigade_cleanup(bb);
            rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_READBYTES,
                                APR_BLOCK_READ, len);
    
            if (rv != APR_SUCCESS) {
                if (APR_STATUS_IS_EOF(rv)) {
                    rv = APR_SUCCESS;
                    break;
                }
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server, APLOGNO(03300)
                              "Error reading response body");
                break;
            }
    
            while (!APR_BRIGADE_EMPTY(bb)) {
                apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
                if (APR_BUCKET_IS_EOS(bucket)) {
                    seen_eos = 1;
                    break;
                }
                if (APR_BUCKET_IS_FLUSH(bucket)) {
                    apr_bucket_delete(bucket);
                    continue;
                }
                APR_BUCKET_REMOVE(bucket);
                APR_BRIGADE_INSERT_TAIL(r->kept_body, bucket);
            }
        }
        while (!seen_eos);
        apr_brigade_cleanup(bb);
        return (rv == APR_SUCCESS ? OK : !OK);
    }
    
    /*
     * Send the HTTP OPTIONS, HEAD or GET request to the backend
     * server associated w/ worker. If we have Conditions,
     * then apply those to the resulting response, otherwise
     * any status code 2xx or 3xx is considered "passing"
     */
    static apr_status_t hc_check_http(baton_t *baton, apr_thread_t *thread)
    {
        int status;
        proxy_conn_rec *backend = NULL;
        sctx_t *ctx = baton->ctx;
        proxy_worker *hc = baton->hc;
        proxy_worker *worker = baton->worker;
        apr_pool_t *ptemp = baton->ptemp;
        request_rec *r;
        wctx_t *wctx;
        hc_condition_t *cond;
        apr_bucket_brigade *bb;
    
        wctx = (wctx_t *)hc->context;
        if (!wctx->req || !wctx->method) {
            return APR_ENOTIMPL;
        }
    
        if ((status = hc_get_backend("HCOH", &backend, hc, ctx)) != OK) {
            return backend_cleanup("HCOH", backend, ctx->s, status);
        }
        if ((status = ap_proxy_connect_backend("HCOH", backend, hc, ctx->s)) != OK) {
            return backend_cleanup("HCOH", backend, ctx->s, status);
        }
    
        r = create_request_rec(ptemp, ctx->s, baton->balancer, wctx->method, wctx->protocol);
        if ((status = ap_proxy_connection_create_ex("HCOH", backend, r)) != OK) {
            return backend_cleanup("HCOH", backend, ctx->s, status);
        }
        set_request_connection(r, backend->connection);
        backend->connection->current_thread = thread;
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        if ((status = hc_send(r, wctx->req, bb)) != OK) {
            return backend_cleanup("HCOH", backend, ctx->s, status);
        }
        if ((status = hc_read_headers(r)) != OK) {
            return backend_cleanup("HCOH", backend, ctx->s, status);
        }
        if (!r->header_only) {
            apr_table_t *saved_headers_in = r->headers_in;
            r->headers_in = apr_table_copy(r->pool, r->headers_out);
            ap_proxy_pre_http_request(backend->connection, r);
            status = hc_read_body(r, bb);
            r->headers_in = saved_headers_in;
            if (status != OK) {
                return backend_cleanup("HCOH", backend, ctx->s, status);
            }
            r->trailers_out = apr_table_copy(r->pool, r->trailers_in);
        }
    
        if (*worker->s->hcexpr &&
                (cond = (hc_condition_t *)apr_table_get(ctx->conditions, worker->s->hcexpr)) != NULL) {
            const char *err;
            int ok = ap_expr_exec(r, cond->pexpr, &err);
            if (ok > 0) {
                ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, ctx->s,
                             "Condition %s for %s (%s): passed", worker->s->hcexpr,
                             hc->s->name_ex, worker->s->name_ex);
            } else if (ok < 0 || err) {
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ctx->s, APLOGNO(03301)
                             "Error on checking condition %s for %s (%s): %s", worker->s->hcexpr,
                             hc->s->name_ex, worker->s->name_ex, err);
                status = !OK;
            } else {
                ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, ctx->s,
                             "Condition %s for %s (%s) : failed", worker->s->hcexpr,
                             hc->s->name_ex, worker->s->name_ex);
                status = !OK;
            }
        } else if (r->status < 200 || r->status > 399) {
            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, ctx->s,
                         "Response status %i for %s (%s): failed", r->status,
                         hc->s->name_ex, worker->s->name_ex);
            status = !OK;
        }
        return backend_cleanup("HCOH", backend, ctx->s, status);
    }
    
    static void * APR_THREAD_FUNC hc_check(apr_thread_t *thread, void *b)
    {
        baton_t *baton = (baton_t *)b;
        server_rec *s = baton->ctx->s;
        proxy_worker *worker = baton->worker;
        proxy_worker *hc = baton->hc;
        apr_time_t now;
        apr_status_t rv;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03256)
                     "%sHealth checking %s", (thread ? "Threaded " : ""),
                     worker->s->name_ex);
    
        if (hc->s->method == TCP) {
            rv = hc_check_tcp(baton);
        }
        else if (hc->s->method == CPING) {
            rv = hc_check_cping(baton, thread);
        }
        else {
            rv = hc_check_http(baton, thread);
        }
    
        now = apr_time_now();
        if (rv == APR_ENOTIMPL) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(03257)
                             "Somehow tried to use unimplemented hcheck method: %d",
                             (int)hc->s->method);
        }
        /* what state are we in ? */
        else if (PROXY_WORKER_IS_HCFAILED(worker) || PROXY_WORKER_IS_ERROR(worker)) {
            if (rv == APR_SUCCESS) {
                worker->s->pcount += 1;
                if (worker->s->pcount >= worker->s->passes) {
                    ap_proxy_set_wstatus(PROXY_WORKER_HC_FAIL_FLAG, 0, worker);
                    ap_proxy_set_wstatus(PROXY_WORKER_IN_ERROR_FLAG, 0, worker);
                    worker->s->pcount = 0;
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(03302)
                                 "%sHealth check ENABLING %s", (thread ? "Threaded " : ""),
                                 worker->s->name_ex);
    
                }
            }
        }
        else {
            if (rv != APR_SUCCESS) {
                worker->s->error_time = now;
                worker->s->fcount += 1;
                if (worker->s->fcount >= worker->s->fails) {
                    ap_proxy_set_wstatus(PROXY_WORKER_HC_FAIL_FLAG, 1, worker);
                    worker->s->fcount = 0;
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(03303)
                                 "%sHealth check DISABLING %s", (thread ? "Threaded " : ""),
                                 worker->s->name_ex);
                }
            }
        }
        if (baton->now) {
            *baton->now = now;
        }
        apr_pool_destroy(baton->ptemp);
        worker->s->updated = now;
    
        return NULL;
    }
    
    static apr_status_t hc_watchdog_callback(int state, void *data,
                                             apr_pool_t *pool)
    {
        apr_status_t rv = APR_SUCCESS;
        proxy_balancer *balancer;
        sctx_t *ctx = (sctx_t *)data;
        server_rec *s = ctx->s;
        proxy_server_conf *conf;
    
        switch (state) {
            case AP_WATCHDOG_STATE_STARTING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03258)
                             "%s watchdog started.",
                             HCHECK_WATHCHDOG_NAME);
    #if HC_USE_THREADS
                if (tpsize && hctp == NULL) {
                    rv =  apr_thread_pool_create(&hctp, tpsize,
                                                 tpsize, ctx->p);
                    if (rv != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03312)
                                     "apr_thread_pool_create() with %d threads failed",
                                     tpsize);
                        /* we can continue on without the threadpools */
                        hctp = NULL;
                    } else {
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03313)
                                     "apr_thread_pool_create() with %d threads succeeded",
                                     tpsize);
                    }
                } else {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03314)
                                 "Skipping apr_thread_pool_create()");
                    hctp = NULL;
                }
    #endif
                break;
    
            case AP_WATCHDOG_STATE_RUNNING:
                /* loop thru all workers */
                if (s) {
                    int i;
                    conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
                    balancer = (proxy_balancer *)conf->balancers->elts;
                    ctx->s = s;
                    for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
                        int n;
                        apr_time_t now;
                        proxy_worker **workers;
                        proxy_worker *worker;
                        /* Have any new balancers or workers been added dynamically? */
                        ap_proxy_sync_balancer(balancer, s, conf);
                        workers = (proxy_worker **)balancer->workers->elts;
                        now = apr_time_now();
                        for (n = 0; n < balancer->workers->nelts; n++) {
                            worker = *workers;
                            if (!PROXY_WORKER_IS(worker, PROXY_WORKER_STOPPED) &&
                                (worker->s->method != NONE) &&
                                (worker->s->updated != 0) &&
                                (now > worker->s->updated + worker->s->interval)) {
                                baton_t *baton;
                                apr_pool_t *ptemp;
    
                                ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
                                             "Checking %s worker: %s  [%d] (%pp)", balancer->s->name,
                                             worker->s->name_ex, worker->s->method, worker);
    
                                /* This pool has the lifetime of the check */
                                apr_pool_create(&ptemp, ctx->p);
                                apr_pool_tag(ptemp, "hc_request");
                                baton = apr_pcalloc(ptemp, sizeof(baton_t));
                                baton->ctx = ctx;
                                baton->balancer = balancer;
                                baton->worker = worker;
                                baton->ptemp = ptemp;
                                if ((rv = hc_init_baton(baton))) {
                                    worker->s->updated = now;
                                    apr_pool_destroy(ptemp);
                                    return rv;
                                }
                                worker->s->updated = 0;
    #if HC_USE_THREADS
                                if (hctp) {
                                    apr_thread_pool_push(hctp, hc_check, (void *)baton,
                                                         APR_THREAD_TASK_PRIORITY_NORMAL,
                                                         NULL);
                                }
                                else
    #endif
                                {
                                    baton->now = &now;
                                    hc_check(NULL, baton);
                                }
                            }
                            workers++;
                        }
                    }
                }
                break;
    
            case AP_WATCHDOG_STATE_STOPPING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03261)
                             "stopping %s watchdog.",
                             HCHECK_WATHCHDOG_NAME);
    #if HC_USE_THREADS
                if (hctp) {
                    rv =  apr_thread_pool_destroy(hctp);
                    if (rv != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03315)
                                     "apr_thread_pool_destroy() failed");
                    }
                    hctp = NULL;
                }
    #endif
                break;
        }
        return rv;
    }
    static int hc_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                             apr_pool_t *ptemp)
    {
    #if HC_USE_THREADS
        hctp = NULL;
        tpsize = HC_THREADPOOL_SIZE;
    #endif
    
        ajp_handle_cping_cpong = APR_RETRIEVE_OPTIONAL_FN(ajp_handle_cping_cpong);
        if (ajp_handle_cping_cpong) {
           proxy_hcmethods_t *method = proxy_hcmethods;
           for (; method->name; method++) {
               if (method->method == CPING) {
                   method->implemented = 1;
                   break;
               }
           }
        }
    
        return OK;
    }
    static int hc_post_config(apr_pool_t *p, apr_pool_t *plog,
                           apr_pool_t *ptemp, server_rec *main_s)
    {
        apr_status_t rv;
        server_rec *s = main_s;
    
        APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *hc_watchdog_get_instance;
        APR_OPTIONAL_FN_TYPE(ap_watchdog_register_callback) *hc_watchdog_register_callback;
    
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
        hc_watchdog_get_instance = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_get_instance);
        hc_watchdog_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback);
        if (!hc_watchdog_get_instance || !hc_watchdog_register_callback) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(03262)
                         "mod_watchdog is required");
            return !OK;
        }
        rv = hc_watchdog_get_instance(&watchdog,
                                      HCHECK_WATHCHDOG_NAME,
                                      0, 1, p);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03263)
                         "Failed to create watchdog instance (%s)",
                         HCHECK_WATHCHDOG_NAME);
            return !OK;
        }
        while (s) {
            sctx_t *ctx = ap_get_module_config(s->module_config,
                                               &proxy_hcheck_module);
    
            if (s != ctx->s) {
                ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, s, APLOGNO(10019)
                             "Missing unique per-server context: %s (%pp:%pp) (no hchecks)",
                             s->server_hostname, s, ctx->s);
                s = s->next;
                continue;
            }
            rv = hc_watchdog_register_callback(watchdog,
                    AP_WD_TM_SLICE,
                    ctx,
                    hc_watchdog_callback);
            if (rv) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03264)
                             "Failed to register watchdog callback (%s)",
                             HCHECK_WATHCHDOG_NAME);
                return !OK;
            }
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03265)
                         "watchdog callback registered (%s for %s)", HCHECK_WATHCHDOG_NAME, s->server_hostname);
            s = s->next;
        }
    
        return OK;
    }
    
    static void hc_show_exprs(request_rec *r)
    {
        const apr_table_entry_t *elts;
        const apr_array_header_t *hdr;
        int i;
        sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
                                                      &proxy_hcheck_module);
        if (!ctx)
            return;
        if (apr_is_empty_table(ctx->conditions))
            return;
    
        ap_rputs("\n\n<table>"
                 "<tr><th colspan='2'>Health check cond. expressions:</th></tr>\n"
                 "<tr><th>Expr name</th><th>Expression</th></tr>\n", r);
    
        hdr = apr_table_elts(ctx->conditions);
        elts = (const apr_table_entry_t *) hdr->elts;
        for (i = 0; i < hdr->nelts; ++i) {
            hc_condition_t *cond;
            if (!elts[i].key) {
                continue;
            }
            cond = (hc_condition_t *)elts[i].val;
            ap_rprintf(r, "<tr><td>%s</td><td>%s</td></tr>\n",
                       ap_escape_html(r->pool, elts[i].key),
                       ap_escape_html(r->pool, cond->expr));
        }
        ap_rputs("</table><hr/>\n", r);
    }
    
    static void hc_select_exprs(request_rec *r, const char *expr)
    {
        const apr_table_entry_t *elts;
        const apr_array_header_t *hdr;
        int i;
        sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
                                                      &proxy_hcheck_module);
        if (!ctx)
            return;
        if (apr_is_empty_table(ctx->conditions))
            return;
    
        hdr = apr_table_elts(ctx->conditions);
        elts = (const apr_table_entry_t *) hdr->elts;
        for (i = 0; i < hdr->nelts; ++i) {
            if (!elts[i].key) {
                continue;
            }
            ap_rprintf(r, "<option value='%s' %s >%s</option>\n",
                       ap_escape_html(r->pool, elts[i].key),
                       (!strcmp(elts[i].key, expr)) ? "selected" : "",
                               ap_escape_html(r->pool, elts[i].key));
        }
    }
    
    static int hc_valid_expr(request_rec *r, const char *expr)
    {
        const apr_table_entry_t *elts;
        const apr_array_header_t *hdr;
        int i;
        sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
                                                      &proxy_hcheck_module);
        if (!ctx)
            return 0;
        if (apr_is_empty_table(ctx->conditions))
            return 0;
    
        hdr = apr_table_elts(ctx->conditions);
        elts = (const apr_table_entry_t *) hdr->elts;
        for (i = 0; i < hdr->nelts; ++i) {
            if (!elts[i].key) {
                continue;
            }
            if (!strcmp(elts[i].key, expr))
                return 1;
        }
        return 0;
    }
    
    static const char *hc_get_body(request_rec *r)
    {
        apr_off_t length;
        apr_size_t len;
        apr_status_t rv;
        char *buf;
    
        if (!r || !r->kept_body)
            return "";
    
        rv = apr_brigade_length(r->kept_body, 1, &length);
        len = (apr_size_t)length;
        if (rv != APR_SUCCESS || len == 0)
            return "";
    
        buf = apr_palloc(r->pool, len + 1);
        rv = apr_brigade_flatten(r->kept_body, buf, &len);
        if (rv != APR_SUCCESS)
            return "";
        buf[len] = '\0'; /* ensure */
        return (const char*)buf;
    }
    
    static const char *hc_expr_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
    {
        char *var = (char *)data;
    
        if (var && *var && ctx->r && ap_cstr_casecmp(var, "BODY") == 0) {
            return hc_get_body(ctx->r);
        }
        return NULL;
    }
    
    static const char *hc_expr_func_fn(ap_expr_eval_ctx_t *ctx, const void *data,
                                    const char *arg)
    {
        char *var = (char *)arg;
    
        if (var && *var && ctx->r && ap_cstr_casecmp(var, "BODY") == 0) {
            return hc_get_body(ctx->r);
        }
        return NULL;
    }
    
    static int hc_expr_lookup(ap_expr_lookup_parms *parms)
    {
        switch (parms->type) {
        case AP_EXPR_FUNC_VAR:
            /* for now, we just handle everything that starts with HC_.
             */
            if (strncasecmp(parms->name, "HC_", 3) == 0) {
                *parms->func = hc_expr_var_fn;
                *parms->data = parms->name + 3;
                return OK;
            }
            break;
        case AP_EXPR_FUNC_STRING:
            /* Function HC() is implemented by us.
             */
            if (strcasecmp(parms->name, "HC") == 0) {
                *parms->func = hc_expr_func_fn;
                *parms->data = parms->arg;
                return OK;
            }
            break;
        }
        return DECLINED;
    }
    
    static const command_rec command_table[] = {
        AP_INIT_RAW_ARGS("ProxyHCTemplate", set_hc_template, NULL, OR_FILEINFO,
                         "Health check template"),
        AP_INIT_RAW_ARGS("ProxyHCExpr", set_hc_condition, NULL, OR_FILEINFO,
                         "Define a health check condition ruleset expression"),
    #if HC_USE_THREADS
        AP_INIT_TAKE1("ProxyHCTPsize", set_hc_tpsize, NULL, RSRC_CONF,
                         "Set size of health check thread pool"),
    #endif
        { NULL }
    };
    
    static void hc_register_hooks(apr_pool_t *p)
    {
        static const char *const aszPre[] = { "mod_proxy_balancer.c", "mod_proxy.c", NULL};
        static const char *const aszSucc[] = { "mod_watchdog.c", NULL};
        APR_REGISTER_OPTIONAL_FN(set_worker_hc_param);
        APR_REGISTER_OPTIONAL_FN(hc_show_exprs);
        APR_REGISTER_OPTIONAL_FN(hc_select_exprs);
        APR_REGISTER_OPTIONAL_FN(hc_valid_expr);
        ap_hook_pre_config(hc_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_config(hc_post_config, aszPre, aszSucc, APR_HOOK_LAST);
        ap_hook_expr_lookup(hc_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    /* the main config structure */
    
    AP_DECLARE_MODULE(proxy_hcheck) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,              /* create per-dir config structures */
        NULL,              /* merge  per-dir config structures */
        hc_create_config,  /* create per-server config structures */
        NULL,              /* merge  per-server config structures */
        command_table,     /* table of config file commands */
        hc_register_hooks  /* register hooks */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_express.c������������������������������������������������������0000664�0001751�0001751�00000020074�14210356064�021414� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_proxy.h"
    #include "apr_dbm.h"
    
    module AP_MODULE_DECLARE_DATA proxy_express_module;
    
    #include "apr_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    static int proxy_available = 0;
    
    typedef struct {
        const char *dbmfile;
        const char *dbmtype;
        int enabled;
    } express_server_conf;
    
    static const char *set_dbmfile(cmd_parms *cmd,
                                   void *dconf,
                                   const char *arg)
    {
        express_server_conf *sconf;
        sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
    
        if ((sconf->dbmfile = ap_server_root_relative(cmd->pool, arg)) == NULL) {
            return apr_pstrcat(cmd->pool, "ProxyExpressDBMFile: bad path to file: ",
                               arg, NULL);
        }
        return NULL;
    }
    
    static const char *set_dbmtype(cmd_parms *cmd,
                                   void *dconf,
                                   const char *arg)
    {
        express_server_conf *sconf;
        sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
    
        sconf->dbmtype = arg;
    
        return NULL;
    }
    
    static const char *set_enabled(cmd_parms *cmd,
                                   void *dconf,
                                   int flag)
    {
        express_server_conf *sconf;
        sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
    
        sconf->enabled = flag;
    
        return NULL;
    }
    
    static void *server_create(apr_pool_t *p, server_rec *s)
    {
        express_server_conf *a;
    
        a = (express_server_conf *)apr_pcalloc(p, sizeof(express_server_conf));
    
        a->dbmfile = NULL;
        a->dbmtype = "default";
        a->enabled = 0;
    
        return (void *)a;
    }
    
    static void *server_merge(apr_pool_t *p, void *basev, void *overridesv)
    {
        express_server_conf *a, *base, *overrides;
    
        a         = (express_server_conf *)apr_pcalloc(p,
                                                       sizeof(express_server_conf));
        base      = (express_server_conf *)basev;
        overrides = (express_server_conf *)overridesv;
    
        a->dbmfile = (overrides->dbmfile) ? overrides->dbmfile : base->dbmfile;
        a->dbmtype = (overrides->dbmtype) ? overrides->dbmtype : base->dbmtype;
        a->enabled = (overrides->enabled) ? overrides->enabled : base->enabled;
    
        return (void *)a;
    }
    
    static int post_config(apr_pool_t *p,
                           apr_pool_t *plog,
                           apr_pool_t *ptemp,
                           server_rec *s)
    {
        proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);
        return OK;
    }
    
    
    static int xlate_name(request_rec *r)
    {
        int i;
        const char *name;
        char *backend = NULL;
        apr_dbm_t *db;
        apr_status_t rv;
        apr_datum_t key, val;
        struct proxy_alias *ralias;
        proxy_dir_conf *dconf;
        express_server_conf *sconf;
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
    
        sconf = ap_get_module_config(r->server->module_config, &proxy_express_module);
        dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
    
        if (!sconf->enabled) {
            return DECLINED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01001) "proxy_express: Enabled");
        if (!sconf->dbmfile || (r->filename && strncmp(r->filename, "proxy:", 6) == 0)) {
            /* it should be go on as an internal proxy request */
            return DECLINED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01002)
                      "proxy_express: Opening DBM file: %s (%s)",
                      sconf->dbmfile, sconf->dbmtype);
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        rv = apr_dbm_get_driver(&driver, sconf->dbmtype, &err, r->pool);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                         APLOGNO(10275) "The dbm library '%s' could not be loaded: %s (%s: %d)",
                         sconf->dbmtype, err->msg, err->reason, err->rc);
            return DECLINED;
        }
    
        rv = apr_dbm_open2(&db, driver, sconf->dbmfile, APR_DBM_READONLY,
                             APR_OS_DEFAULT, r->pool);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                         APLOGNO(10276) "The '%s' file '%s' could not be loaded",
                         sconf->dbmtype, sconf->dbmfile);
            return DECLINED;
        }
    #else
        rv = apr_dbm_open_ex(&db, sconf->dbmtype, sconf->dbmfile, APR_DBM_READONLY,
                             APR_OS_DEFAULT, r->pool);
        if (rv != APR_SUCCESS) {
            return DECLINED;
        }
    #endif
    
        name = ap_get_server_name(r);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01003)
                      "proxy_express: looking for %s", name);
        key.dptr = (char *)name;
        key.dsize = strlen(key.dptr);
    
        rv = apr_dbm_fetch(db, key, &val);
        if (rv == APR_SUCCESS) {
            backend = apr_pstrmemdup(r->pool, val.dptr, val.dsize);
        }
        apr_dbm_close(db);
        if (rv != APR_SUCCESS || !backend) {
            return DECLINED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01004)
                      "proxy_express: found %s -> %s", name, backend);
        r->filename = apr_pstrcat(r->pool, "proxy:", backend, r->uri, NULL);
        r->handler = "proxy-server";
        r->proxyreq = PROXYREQ_REVERSE;
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01005)
                      "proxy_express: rewritten as: %s", r->filename);
    
        ralias = (struct proxy_alias *)dconf->raliases->elts;
        /*
         * See if we have already added a ProxyPassReverse entry
         * for this host... If so, don't do it again.
         */
        /*
         * NOTE: dconf is process specific so this will only
         *       work as long as we maintain that this process
         *       or thread is handling the backend
         */
        for (i = 0; i < dconf->raliases->nelts; i++, ralias++) {
            if (strcasecmp(backend, ralias->real) == 0) {
                ralias = NULL;
                break;
            }
        }
    
        /* Didn't find one... add it */
        if (!ralias) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01006)
                          "proxy_express: adding PPR entry");
            ralias = apr_array_push(dconf->raliases);
            ralias->fake = "/";
            ralias->real = apr_pstrdup(dconf->raliases->pool, backend);
            ralias->flags = 0;
        }
        return OK;
    }
    
    static const command_rec command_table[] = {
        AP_INIT_FLAG("ProxyExpressEnable", set_enabled, NULL, OR_FILEINFO,
                     "Enable the ProxyExpress functionality"),
        AP_INIT_TAKE1("ProxyExpressDBMFile", set_dbmfile, NULL, OR_FILEINFO,
                      "Location of ProxyExpressDBMFile file"),
        AP_INIT_TAKE1("ProxyExpressDBMType", set_dbmtype, NULL, OR_FILEINFO,
                      "Type of ProxyExpressDBMFile file"),
        { NULL }
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_LAST);
        ap_hook_translate_name(xlate_name, NULL, NULL, APR_HOOK_FIRST);
    }
    
    /* the main config structure */
    
    AP_DECLARE_MODULE(proxy_express) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,           /* create per-dir config structures */
        NULL,           /* merge  per-dir config structures */
        server_create,  /* create per-server config structures */
        server_merge,   /* merge  per-server config structures */
        command_table,  /* table of config file commands */
        register_hooks  /* register hooks */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/config.m4����������������������������������������������������������������0000664�0001751�0001751�00000007341�13303340351�017162� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl modules enabled in this directory by default
    
    APACHE_MODPATH_INIT(proxy)
    
    proxy_objs="mod_proxy.lo proxy_util.lo"
    APACHE_MODULE(proxy, Apache proxy module, $proxy_objs, , most)
    
    dnl set aside module selections and default, and set the module default to the
    dnl same scope (shared|static) as selected for mod proxy, along with setting
    dnl the default selection to "most" for remaining proxy modules, mirroring the
    dnl behavior of 2.4.1 and later, but failing ./configure only if an explicitly
    dnl enabled module is missing its prereqs
    save_module_selection=$module_selection
    save_module_default=$module_default
    if test "$enable_proxy" != "no"; then
        module_selection=most
        if test "$enable_proxy" = "shared" -o "$enable_proxy" = "static"; then
            module_default=$enable_proxy
        fi
    fi
    
    proxy_connect_objs="mod_proxy_connect.lo"
    proxy_ftp_objs="mod_proxy_ftp.lo"
    proxy_http_objs="mod_proxy_http.lo"
    proxy_fcgi_objs="mod_proxy_fcgi.lo"
    proxy_scgi_objs="mod_proxy_scgi.lo"
    proxy_uwsgi_objs="mod_proxy_uwsgi.lo"
    proxy_fdpass_objs="mod_proxy_fdpass.lo"
    proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo ajp_utils.lo"
    proxy_wstunnel_objs="mod_proxy_wstunnel.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_fcgi_objs="$proxy_fcgi_objs mod_proxy.la"
        proxy_scgi_objs="$proxy_scgi_objs mod_proxy.la"
        proxy_uwsgi_objs="$proxy_uwsgi_objs mod_proxy.la"
        proxy_fdpass_objs="$proxy_fdpass_objs mod_proxy.la"
        proxy_ajp_objs="$proxy_ajp_objs mod_proxy.la"
        proxy_wstunnel_objs="$proxy_wstunnel_objs mod_proxy.la"
        proxy_balancer_objs="$proxy_balancer_objs mod_proxy.la"
        ;;
    esac
    
    APACHE_MODULE(proxy_connect, Apache proxy CONNECT module.  Requires --enable-proxy., $proxy_connect_objs, , most, , proxy)
    APACHE_MODULE(proxy_ftp, Apache proxy FTP module.  Requires --enable-proxy., $proxy_ftp_objs, , most, , proxy)
    APACHE_MODULE(proxy_http, Apache proxy HTTP module.  Requires --enable-proxy., $proxy_http_objs, , most, , proxy)
    APACHE_MODULE(proxy_fcgi, Apache proxy FastCGI module.  Requires --enable-proxy., $proxy_fcgi_objs, , most, , proxy)
    APACHE_MODULE(proxy_scgi, Apache proxy SCGI module.  Requires --enable-proxy., $proxy_scgi_objs, , most, , proxy)
    APACHE_MODULE(proxy_uwsgi, Apache proxy UWSGI module.  Requires --enable-proxy., $proxy_uwsgi_objs, , most, , proxy)
    APACHE_MODULE(proxy_fdpass, Apache proxy to Unix Daemon Socket module.  Requires --enable-proxy., $proxy_fdpass_objs, , most, [
      AC_CHECK_DECL(CMSG_DATA,,, [
        #include <sys/types.h>
        #include <sys/socket.h>
      ])
      if test $ac_cv_have_decl_CMSG_DATA = "no"; then
        AC_MSG_WARN([Your system does not support CMSG_DATA.])
        enable_proxy_fdpass=no
      fi
    ],proxy)
    APACHE_MODULE(proxy_wstunnel, Apache proxy Websocket Tunnel module.  Requires --enable-proxy., $proxy_wstunnel_objs, , most, , proxy)
    APACHE_MODULE(proxy_ajp, Apache proxy AJP module.  Requires --enable-proxy., $proxy_ajp_objs, , most, , proxy)
    APACHE_MODULE(proxy_balancer, Apache proxy BALANCER module.  Requires --enable-proxy., $proxy_balancer_objs, , most, , proxy)
    
    APACHE_MODULE(proxy_express, mass reverse-proxy module. Requires --enable-proxy., , , most, , proxy)
    APACHE_MODULE(proxy_hcheck, [reverse-proxy health-check module. Requires --enable-proxy and --enable-watchdog.], , , most, , [proxy,watchdog])
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current -I\$(top_srcdir)/modules/http2])
    
    module_selection=$save_module_selection
    module_default=$save_module_default
    
    APACHE_MODPATH_FINISH
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_uwsgi.dsp������������������������������������������������������0000664�0001751�0001751�00000011517�13240664370�021433� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_uwsgi" - 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_uwsgi - 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_uwsgi.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_uwsgi.mak" CFG="mod_proxy_uwsgi - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_uwsgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_uwsgi - 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_uwsgi - 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_uwsgi_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 0x409 /fo"Release/mod_proxy_uwsgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_uwsgi.so" /d LONG_NAME="proxy_uwsgi_module for Apache"
    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 /out:".\Release\mod_proxy_uwsgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_uwsgi.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_proxy_uwsgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_uwsgi.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_uwsgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_uwsgi - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_uwsgi_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 0x409 /fo"Debug/mod_proxy_uwsgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_uwsgi.so" /d LONG_NAME="proxy_uwsgi_module for Apache"
    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 /out:".\Debug\mod_proxy_uwsgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_uwsgi.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_uwsgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_uwsgi.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_uwsgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_uwsgi - Win32 Release"
    # Name "mod_proxy_uwsgi - 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_uwsgi.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_hcheck.mak�����������������������������������������������������0000664�0001751�0001751�00000026155�13017652517�021512� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_hcheck.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_hcheck - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_hcheck - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_hcheck - Win32 Release" && "$(CFG)" != "mod_proxy_hcheck - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_hcheck.mak" CFG="mod_proxy_hcheck - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_hcheck - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_hcheck - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_hcheck - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_hcheck.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_hcheck.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_hcheck.obj"
    	-@erase "$(INTDIR)\mod_proxy_hcheck.res"
    	-@erase "$(INTDIR)\mod_proxy_hcheck_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_hcheck_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.exp"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.lib"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_hcheck_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_hcheck.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_hcheck.so" /d LONG_NAME="proxy_hcheck_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_hcheck.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_hcheck.pdb" /debug /out:"$(OUTDIR)\mod_proxy_hcheck.so" /implib:"$(OUTDIR)\mod_proxy_hcheck.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_hcheck.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_hcheck.obj" \
    	"$(INTDIR)\mod_proxy_hcheck.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_hcheck.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_hcheck.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_hcheck.so"
       if exist .\Release\mod_proxy_hcheck.so.manifest mt.exe -manifest .\Release\mod_proxy_hcheck.so.manifest -outputresource:.\Release\mod_proxy_hcheck.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_hcheck - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_hcheck.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_hcheck.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_hcheck.obj"
    	-@erase "$(INTDIR)\mod_proxy_hcheck.res"
    	-@erase "$(INTDIR)\mod_proxy_hcheck_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_hcheck_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.exp"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.lib"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_hcheck.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_hcheck_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_hcheck.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_hcheck.so" /d LONG_NAME="proxy_hcheck_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_hcheck.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_hcheck.pdb" /debug /out:"$(OUTDIR)\mod_proxy_hcheck.so" /implib:"$(OUTDIR)\mod_proxy_hcheck.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_hcheck.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_hcheck.obj" \
    	"$(INTDIR)\mod_proxy_hcheck.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_hcheck.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_hcheck.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_hcheck.so"
       if exist .\Debug\mod_proxy_hcheck.so.manifest mt.exe -manifest .\Debug\mod_proxy_hcheck.so.manifest -outputresource:.\Debug\mod_proxy_hcheck.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_hcheck.dep")
    !INCLUDE "mod_proxy_hcheck.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_hcheck.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_hcheck - Win32 Release" || "$(CFG)" == "mod_proxy_hcheck - Win32 Debug"
    SOURCE=.\mod_proxy_hcheck.c
    
    "$(INTDIR)\mod_proxy_hcheck.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_hcheck - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F .\libapr.mak CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F .\libapr.mak CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_hcheck - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F .\libapr.mak CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F .\libapr.mak CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_hcheck - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_hcheck - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_hcheck - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F .\libhttpd.mak CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F .\libhttpd.mak CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_hcheck - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F .\libhttpd.mak CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F .\libhttpd.mak CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_hcheck - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F .\mod_proxy.mak CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F .\mod_proxy.mak CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_hcheck - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F .\mod_proxy.mak CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F .\mod_proxy.mak CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_hcheck - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_hcheck.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_hcheck.res" /i "../../include" /i "../../srclib/apr/include" /i "\build6\hcheck\build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_hcheck.so" /d LONG_NAME="proxy_hcheck_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_hcheck - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_hcheck.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_hcheck.res" /i "../../include" /i "../../srclib/apr/include" /i "\build6\hcheck\build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_hcheck.so" /d LONG_NAME="proxy_hcheck_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_ftp.mak��������������������������������������������������������0000664�0001751�0001751�00000025513�12701473373�021053� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_ftp.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_ftp - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_ftp - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_ftp - Win32 Release" && "$(CFG)" != "mod_proxy_ftp - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ftp - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_ftp.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_ftp.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_ftp.obj"
    	-@erase "$(INTDIR)\mod_proxy_ftp.res"
    	-@erase "$(INTDIR)\mod_proxy_ftp_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_ftp_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.exp"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.lib"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_ftp_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_ftp.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_ftp.so" /d LONG_NAME="proxy_ftp_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_ftp.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_ftp.pdb" /debug /out:"$(OUTDIR)\mod_proxy_ftp.so" /implib:"$(OUTDIR)\mod_proxy_ftp.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_ftp.obj" \
    	"$(INTDIR)\mod_proxy_ftp.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_ftp.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_ftp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_ftp.so"
       if exist .\Release\mod_proxy_ftp.so.manifest mt.exe -manifest .\Release\mod_proxy_ftp.so.manifest -outputresource:.\Release\mod_proxy_ftp.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ftp - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_ftp.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_ftp.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_ftp.obj"
    	-@erase "$(INTDIR)\mod_proxy_ftp.res"
    	-@erase "$(INTDIR)\mod_proxy_ftp_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_ftp_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.exp"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.lib"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_ftp.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_ftp_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_ftp.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_ftp.so" /d LONG_NAME="proxy_ftp_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_ftp.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_ftp.pdb" /debug /out:"$(OUTDIR)\mod_proxy_ftp.so" /implib:"$(OUTDIR)\mod_proxy_ftp.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_ftp.obj" \
    	"$(INTDIR)\mod_proxy_ftp.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_ftp.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_ftp.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_ftp.so"
       if exist .\Debug\mod_proxy_ftp.so.manifest mt.exe -manifest .\Debug\mod_proxy_ftp.so.manifest -outputresource:.\Debug\mod_proxy_ftp.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_ftp.dep")
    !INCLUDE "mod_proxy_ftp.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_ftp.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_ftp - Win32 Release" || "$(CFG)" == "mod_proxy_ftp - Win32 Debug"
    SOURCE=.\mod_proxy_ftp.c
    
    "$(INTDIR)\mod_proxy_ftp.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_ftp - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ftp - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ftp - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ftp - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ftp - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ftp - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_ftp - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ftp - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_ftp - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_ftp.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_ftp.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_ftp.so" /d LONG_NAME="proxy_ftp_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_ftp - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_ftp.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_ftp.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_ftp.so" /d LONG_NAME="proxy_ftp_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy.dep������������������������������������������������������������0000664�0001751�0001751�00000012565�12674411515�020204� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy.mak
    
    .\mod_proxy.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\generators\mod_status.h"\
    	"..\ssl\mod_ssl.h"\
    	".\mod_proxy.h"\
    	".\proxy_util.h"\
    	
    
    .\proxy_util.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_support.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\ajp.h"\
    	".\mod_proxy.h"\
    	".\proxy_util.h"\
    	".\scgi.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxybalancer�������������������������������������������������������0000664�0001751�0001751�00000010611�11546111464�021070� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.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_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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_express.mak����������������������������������������������������0000664�0001751�0001751�00000026267�12701473373�021762� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_express.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_express - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_express - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_express - Win32 Release" && "$(CFG)" != "mod_proxy_express - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_express.mak" CFG="mod_proxy_express - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_express - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_express - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_express - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_express.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_express.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_proxy - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_express.obj"
    	-@erase "$(INTDIR)\mod_proxy_express.res"
    	-@erase "$(INTDIR)\mod_proxy_express_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_express_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_express.exp"
    	-@erase "$(OUTDIR)\mod_proxy_express.lib"
    	-@erase "$(OUTDIR)\mod_proxy_express.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_express.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_express_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_express.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_express.so" /d LONG_NAME="proxy_balancer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_express.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_express.pdb" /debug /out:"$(OUTDIR)\mod_proxy_express.so" /implib:"$(OUTDIR)\mod_proxy_express.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_express.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_express.obj" \
    	"$(INTDIR)\mod_proxy_express.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_express.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_express.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_express.so"
       if exist .\Release\mod_proxy_express.so.manifest mt.exe -manifest .\Release\mod_proxy_express.so.manifest -outputresource:.\Release\mod_proxy_express.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_express - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_express.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_proxy - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_express.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_proxy - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_proxy_express.obj"
    	-@erase "$(INTDIR)\mod_proxy_express.res"
    	-@erase "$(INTDIR)\mod_proxy_express_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_express_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_express.exp"
    	-@erase "$(OUTDIR)\mod_proxy_express.lib"
    	-@erase "$(OUTDIR)\mod_proxy_express.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_express.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_express_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_proxy_express.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_express.so" /d LONG_NAME="proxy_balancer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_express.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_express.pdb" /debug /out:"$(OUTDIR)\mod_proxy_express.so" /implib:"$(OUTDIR)\mod_proxy_express.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_express.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_express.obj" \
    	"$(INTDIR)\mod_proxy_express.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_proxy.lib"
    
    "$(OUTDIR)\mod_proxy_express.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_express.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_express.so"
       if exist .\Debug\mod_proxy_express.so.manifest mt.exe -manifest .\Debug\mod_proxy_express.so.manifest -outputresource:.\Debug\mod_proxy_express.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_express.dep")
    !INCLUDE "mod_proxy_express.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_express.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_express - Win32 Release" || "$(CFG)" == "mod_proxy_express - Win32 Debug"
    SOURCE=.\mod_proxy_express.c
    
    "$(INTDIR)\mod_proxy_express.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_express - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_express - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_express - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_express - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\proxy"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_express - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_express - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\proxy"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\proxy"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_express - Win32 Release"
    
    "mod_proxy - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" 
       cd "."
    
    "mod_proxy - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_proxy_express - Win32 Debug"
    
    "mod_proxy - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" 
       cd "."
    
    "mod_proxy - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_proxy.mak" CFG="mod_proxy - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_express - Win32 Release"
    
    
    "$(INTDIR)\mod_proxy_express.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_express.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_express.so" /d LONG_NAME="proxy_balancer_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_express - Win32 Debug"
    
    
    "$(INTDIR)\mod_proxy_express.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_proxy_express.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_express.so" /d LONG_NAME="proxy_balancer_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_fcgi.dep�������������������������������������������������������0000664�0001751�0001751�00000005254�12674411515�021171� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_fcgi.mak
    
    .\mod_proxy_fcgi.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_fcgi.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_wstunnel.dep���������������������������������������������������0000664�0001751�0001751�00000005166�12674411515�022142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_wstunnel.mak
    
    .\mod_proxy_wstunnel.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/scgi.h�������������������������������������������������������������������0000664�0001751�0001751�00000002205�12343342550�016551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file scgi.h
     * @brief Shared SCGI-related definitions
     *
     * @ingroup APACHE_INTERNAL
     * @{
     */
    
    #ifndef SCGI_H
    #define SCGI_H
    
    /* This is not defined by the protocol.  It is a convention
     * of mod_proxy_scgi, and mod_proxy utility routines must
     * use the same value as mod_proxy_scgi.
     */
    #define SCGI_DEF_PORT 4000
    
    /** @} */
    
    #endif /* SCGI_H */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxylbm_req��������������������������������������������������������0000664�0001751�0001751�00000010373�12010715741�020742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/proxy \
    			$(AP_WORK)/modules/http \
    			$(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	= proxylbm_req
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy LoadBalance by Requests Sub-Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= LBM Requests 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	=
    
    #
    # 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)/$(NLM_NAME).nlm
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib =
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/mod_lbmethod_byrequests.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 = \
    	$(PRELUDE) \
    	$(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 \
    	aprlib \
    	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 = \
    	@libc.imp \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	lbmethod_byrequests_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 balancers
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_fdpass.h�������������������������������������������������������0000664�0001751�0001751�00000002326�11737125415�021215� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_proxy_fdpass.h
     * @brief FD Passing interfaces
     *
     * @ingroup APACHE_INTERNAL
     * @{
     */
    
    #include "mod_proxy.h"
    
    #ifndef _PROXY_FDPASS_H_
    #define _PROXY_FDPASS_H_
    
    #define PROXY_FDPASS_FLUSHER "proxy_fdpass_flusher"
    
    typedef struct proxy_fdpass_flush proxy_fdpass_flush;
    struct proxy_fdpass_flush {
        const char *name;
        int (*flusher)(request_rec *r);
        void *context;
    };
    
    #endif /* _PROXY_FDPASS_H_ */
    /** @} */
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_scgi.dep�������������������������������������������������������0000664�0001751�0001751�00000005233�12674411515�021203� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_scgi.mak
    
    .\mod_proxy_scgi.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	".\scgi.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/ajp_header.h�������������������������������������������������������������0000664�0001751�0001751�00000015362�12473142031�017712� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file ajp_header.h
     * @brief AJP defines
     *
     * @addtogroup AJP_defines
     * @{
     */
    
    #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_STORED_METHOD      (unsigned char)13
    #define SC_A_ARE_DONE           (unsigned char)0xFF
    
    /*
     * AJP private request attributes
     *
     * The following request attribute is recognized by Tomcat
     * to contain the SSL protocol name
     */
    #define SC_A_SSL_PROTOCOL        ("AJP_SSL_PROTOCOL")
    /*
     * The following request attribute is recognized by Tomcat
     * to contain the forwarded remote port.
     */
    #define SC_A_REQ_REMOTE_PORT    ("AJP_REMOTE_PORT")
    /*
     * The following request attribute is recognized by Tomcat
     * to contain the forwarded local ip address.
     */
    #define SC_A_REQ_LOCAL_ADDR     ("AJP_LOCAL_ADDR")
    
    /*
     * 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
    #define SC_M_JK_STORED          (unsigned char)0xFF
    
    
    /*
     * 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 */
    /** @} */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxywstunnel�������������������������������������������������������0000664�0001751�0001751�00000010320�12161135207�021170� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(SRC)/include \
    			$(STDMOD)/http \
    			$(STDMOD)/proxy \
    			$(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	= proxywstunnel
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy Web Socket Tunnel Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Prxy WbSkt 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	=
    
    #
    # 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)/$(NLM_NAME).nlm
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib = 
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/mod_proxy_wstunnel.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 = \
    	$(PRELUDE) \
    	$(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 \
    	aprlib \
    	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 = \
    	@libc.imp \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	proxy_wstunnel_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 balancers
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxylbm_busy�������������������������������������������������������0000664�0001751�0001751�00000010370�12010715741�021132� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/proxy \
    			$(AP_WORK)/modules/http \
    			$(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	= proxylbm_busy
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy LoadBalance by Busyness Sub-Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= LBM Busy 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	=
    
    #
    # 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)/$(NLM_NAME).nlm
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib = 
    
    #
    # These are the OBJ files needed to create the NLM target above.
    # Paths must all use the '/' character
    #
    FILES_nlm_objs = \
    	$(OBJDIR)/mod_lbmethod_bybusyness.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 = \
    	$(PRELUDE) \
    	$(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 \
    	aprlib \
    	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 = \
    	@libc.imp \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	lbmethod_bybusyness_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 balancers
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_http.dep�������������������������������������������������������0000664�0001751�0001751�00000005156�12674411515�021241� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_http.mak
    
    .\mod_proxy_http.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_proxy.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/mod_proxy_wstunnel.dsp���������������������������������������������������0000664�0001751�0001751�00000011651�12505340507�022147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_wstunnel" - 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_wstunnel - 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_wstunnel.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_wstunnel.mak" CFG="mod_proxy_wstunnel - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_wstunnel - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_wstunnel - 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_wstunnel - 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_wstunnel_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 0x409 /fo"Release/mod_proxy_wstunnel.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_wstunnel.so" /d LONG_NAME="proxy_wstunnel_module for Apache"
    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 /out:".\Release\mod_proxy_wstunnel.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_wstunnel.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_proxy_wstunnel.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_wstunnel.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_wstunnel.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_wstunnel - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_wstunnel_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 0x409 /fo"Debug/mod_proxy_wstunnel.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_wstunnel.so" /d LONG_NAME="proxy_wstunnel_module for Apache"
    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 /out:".\Debug\mod_proxy_wstunnel.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_wstunnel.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_wstunnel.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_wstunnel.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_wstunnel.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_wstunnel - Win32 Release"
    # Name "mod_proxy_wstunnel - 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_wstunnel.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/ajp_utils.c��������������������������������������������������������������0000664�0001751�0001751�00000010626�12167341565�017630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    APLOG_USE_MODULE(proxy_ajp);
    
    /*
     * Handle the CPING/CPONG
     */
    apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock,
                                        request_rec *r,
                                        apr_interval_time_t timeout)
    {
        ajp_msg_t *msg;
        apr_status_t rc, rv;
        apr_interval_time_t org;
        apr_byte_t result;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
                             "Into ajp_handle_cping_cpong");
    
        rc = ajp_msg_create(r->pool, AJP_PING_PONG_SZ, &msg);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01007)
                   "ajp_handle_cping_cpong: ajp_msg_create failed");
            return rc;
        }
    
        rc = ajp_msg_serialize_cping(msg);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01008)
                   "ajp_handle_cping_cpong: ajp_marshal_into_msgb failed");
            return rc;
        }
    
        rc = ajp_ilink_send(sock, msg);
        ajp_msg_log(r, msg, "ajp_handle_cping_cpong: ajp_ilink_send packet dump");
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01009)
                   "ajp_handle_cping_cpong: ajp_ilink_send failed");
            return rc;
        }
    
        rc = apr_socket_timeout_get(sock, &org);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01010)
                   "ajp_handle_cping_cpong: apr_socket_timeout_get failed");
            return rc;
        }
    
        /* Set CPING/CPONG response timeout */
        rc = apr_socket_timeout_set(sock, timeout);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01011)
                   "ajp_handle_cping_cpong: apr_socket_timeout_set failed");
            return rc;
        }
        ajp_msg_reuse(msg);
    
        /* Read CPONG reply */
        rv = ajp_ilink_receive(sock, msg);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01012)
                   "ajp_handle_cping_cpong: ajp_ilink_receive failed");
            goto cleanup;
        }
    
        ajp_msg_log(r, msg, "ajp_handle_cping_cpong: ajp_ilink_receive packet dump");
        rv = ajp_msg_get_uint8(msg, &result);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01013)
                   "ajp_handle_cping_cpong: invalid CPONG message");
            goto cleanup;
        }
        if (result != CMD_AJP13_CPONG) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01014)
                   "ajp_handle_cping_cpong: awaited CPONG, received %d ",
                   result);
            rv = APR_EGENERAL;
            goto cleanup;
        }
    
    cleanup:
        /* Restore original socket timeout */
        rc = apr_socket_timeout_set(sock, org);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01015)
                   "ajp_handle_cping_cpong: apr_socket_timeout_set failed");
            return rc;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
                             "ajp_handle_cping_cpong: Done");
        return rv;
    }
    
    
    #define case_to_str(x)    case CMD_AJP13_##x:\
                                  return #x;\
                                  break;
    
    /**
     * Convert numeric message type into string
     * @param type      AJP message type
     * @return          AJP message type as a string
     */
    const char *ajp_type_str(int type)
    {
        switch (type) {
            case_to_str(FORWARD_REQUEST)
            case_to_str(SEND_BODY_CHUNK)
            case_to_str(SEND_HEADERS)
            case_to_str(END_RESPONSE)
            case_to_str(GET_BODY_CHUNK)
            case_to_str(SHUTDOWN)
            case_to_str(PING)
            case_to_str(CPONG)
            case_to_str(CPING)
            default:
                return "CMD_AJP13_UNKNOWN";
        }
    
    }
    ����������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/NWGNUproxyfcgi�����������������������������������������������������������0000664�0001751�0001751�00000010616�11546111464�020236� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(NWOS) \
    			$(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	= proxyfcgi
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy Fast CGI Sub-Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Proxy FCGI 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	=
    
    #
    # 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)/proxyfcgi.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_fcgi.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@$(OBJDIR)/mod_proxy.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_fcgi_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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/proxy/CHANGES������������������������������������������������������������������0000664�0001751�0001751�00000017670�10562624646�016474� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������******************************************
    * PLEASE NOTE: Now that development for  *
    * mod_proxy has been folded back into    *
    * the httpd-2.1 tree, this file has      *
    * been deprecated. Proxy changes should *
    * be noted in httpd-2.x'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>]
    
    ������������������������������������������������������������������������httpd-2.4.64/modules/generators/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016455� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/Makefile.in���������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�020504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgi.exp���������������������������������������������������������0000664�0001751�0001751�00000000013�10150161574�020554� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cgi_module
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgi.c�����������������������������������������������������������0000664�0001751�0001751�00000063260�14640775605�020235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
     *
     * This modules uses a httpd core function (ap_add_common_vars) to add some new env vars, 
     * like REDIRECT_URL and REDIRECT_QUERY_STRING for custom error responses and DOCUMENT_ROOT.
     * 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"
    
    #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 "ap_mpm.h"
    #include "mod_core.h"
    #include "mod_cgi.h"
    
    #if APR_HAVE_STRUCT_RLIMIT
    #if defined (RLIMIT_CPU) || defined (RLIMIT_NPROC) || defined (RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
    #define AP_CGI_USE_RLIMIT
    #endif
    #endif
    
    module AP_MODULE_DECLARE_DATA cgi_module;
    
    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;
    
    typedef struct {
        apr_interval_time_t timeout;
    } cgi_dirconf;
    
    #if APR_FILES_AS_SOCKETS
    #define WANT_CGI_BUCKET
    #endif
    #include "cgi_common.h"
    
    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 void *create_cgi_dirconf(apr_pool_t *p, char *dummy)
    {
        cgi_dirconf *c = (cgi_dirconf *) apr_pcalloc(p, sizeof(cgi_dirconf));
        return c;
    }
    
    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 char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg)
    {
        cgi_dirconf *dc = dummy;
    
        if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) {
            return "CGIScriptTimeout has wrong format";
        }
    
        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"),
    AP_INIT_TAKE1("CGIScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF,
         "The amount of time to wait between successful reads from "
         "the CGI script, in seconds."),
        {NULL}
    };
    
    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;
    
        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)%pm: %s\n",
                        err,
                        &err,
    #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;
    
    #ifdef AP_CGI_USE_RLIMIT
        core_dir_config *conf = ap_get_core_module_config(r->per_dir_config);
    #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]);
        fclose(dbg);
    #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) ||
    #if defined(RLIMIT_CPU) && defined(AP_CGI_USE_RLIMIT)
            ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_CPU,
                                          conf->limit_cpu)) != APR_SUCCESS) ||
    #endif
    #if defined(AP_CGI_USE_RLIMIT) && (defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS))
            ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_MEM,
                                          conf->limit_mem)) != APR_SUCCESS) ||
    #endif
    #if defined(RLIMIT_NPROC) && defined(AP_CGI_USE_RLIMIT)
            ((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, APLOGNO(01216)
                          "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. */
                /* Intentional no APLOGNO */
                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 {
                cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module);
                apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout;
    
                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, 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, timeout);
    
                    *script_err = procnew->err;
                    if (!*script_err)
                        return APR_EBADF;
                    apr_file_pipe_timeout_set(*script_err, timeout);
                }
            }
        }
        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 int cgi_handler(request_rec *r)
    {
        int nph;
        apr_size_t dbufsize;
        const char *argv0;
        const char *command;
        const char **argv;
        char *dbuf = NULL;
        apr_file_t *script_out = NULL, *script_in = NULL, *script_err = NULL;
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);
        apr_bucket *b;
        int is_included;
        apr_pool_t *p;
        cgi_server_conf *conf;
        apr_status_t rv;
        cgi_exec_info_t e_info;
        cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module);
        apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout;
    
        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;
    
        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, APLOGNO(02809),
                                   "Options ExecCGI is off in this directory");
        if (nph && is_included)
            return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(02810),
                                   "attempt to include NPH CGI script");
    
        if (r->finfo.filetype == APR_NOFILE)
            return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(02811),
                                   "script not found or unable to stat");
        if (r->finfo.filetype == APR_DIR)
            return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(02812),
                                   "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, APLOGNO(02813),
                                   "AcceptPathInfo off disallows user's path");
        }
    /*
        if (!ap_suexec_enabled) {
            if (!ap_can_exec(&r->finfo))
                return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(03194)
                                       "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, APLOGNO(01222)
                          "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, APLOGNO(01223)
                          "couldn't spawn child process: %s", r->filename);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* Buffer for logging script stdout. */
        if (conf->logname) {
            dbufsize = conf->bufbytes;
            dbuf = apr_palloc(r->pool, dbufsize + 1);
        }
        else {
            dbufsize = 0;
            dbuf = NULL;
        }
    
        /* Read the request body. */
        rv = cgi_handle_request(r, script_out, bb, dbuf, dbufsize);
        if (rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01225)
                          "Error reading request entity data");
            return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
        }
    
        /* Is this flush really needed? */
        apr_file_flush(script_out);
        apr_file_close(script_out);
    
        AP_DEBUG_ASSERT(script_in != NULL);
    
    #if APR_FILES_AS_SOCKETS
        b = cgi_bucket_create(r, dc->timeout, script_in, script_err, c->bucket_alloc);
        if (b == NULL)
            return HTTP_INTERNAL_SERVER_ERROR;
    #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);
    
        return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err);
    }
    
    /*============================================================================
     *============================================================================
     * 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_ex(rr, CGI_MAGIC_TYPE, 1);
    
        /* 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, APLOGNO(01226)
                          "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, APLOGNO(01227)
                          "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 int cgi_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)
         */
        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);
        ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(cgi) =
    {
        STANDARD20_MODULE_STUFF,
        create_cgi_dirconf,          /* 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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_asis.c����������������������������������������������������������0000664�0001751�0001751�00000010071�15022010441�020371� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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)
    {
        apr_file_t *f;
        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 == APR_NOFILE) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01233)
                        "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, APLOGNO(01234)
                        "file permissions deny server access: %s", r->filename);
            return HTTP_FORBIDDEN;
        }
    
        ap_scan_script_header_err_ex(r, f, NULL, APLOG_MODULE_INDEX);
        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 = "GET";
            r->method_number = M_GET;
    
            ap_internal_redirect_handler(location, r);
            return OK;
        }
    
        if (!r->header_only) {
            conn_rec *c = r->connection;
            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, APLOGNO(01235)
                              "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);
            apr_brigade_insert_file(bb, f, pos, r->finfo.size - pos, r->pool);
    
            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_DEBUG, rv, r, APLOGNO(01236)
                              "mod_asis: ap_pass_brigade failed for file %s", r->filename);
                return AP_FILTER_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);
    }
    
    AP_DECLARE_MODULE(asis) =
    {
        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 */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_status.c��������������������������������������������������������0000664�0001751�0001751�00000116730�14651200711�020776� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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:
     *
     * <Location /server-status>
     * SetHandler server-status
     * </Location>
     *
     * 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.]
     */
    
    #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 <time.h>
    #include "scoreboard.h"
    #include "http_log.h"
    #include "mod_status.h"
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    #include "apr_strings.h"
    
    #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, threads_per_child, max_servers,
               is_async;
    
    /* 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
    
    /* 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_uint32_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}
    };
    
    /* add another state for slots above the MaxRequestWorkers setting */
    #define SERVER_DISABLED SERVER_NUM_STATUS
    #define MOD_STATUS_NUM_STATUS (SERVER_NUM_STATUS+1)
    
    static char status_flags[MOD_STATUS_NUM_STATUS];
    
    static int status_handler(request_rec *r)
    {
        const char *loc;
        apr_time_t nowtime;
        apr_uint32_t up_time;
        ap_loadavg_t t;
        int j, i, res, written;
        int idle;
        int graceful;
        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;
        apr_time_t duration_global;
        apr_time_t duration_slot;
        int short_report;
        int no_table_report;
        global_score *global_record;
        worker_score *ws_record;
        process_score *ps_record;
        char *stat_buffer;
        pid_t *pid_buffer, worker_pid;
        int *thread_idle_buffer = NULL;
        int *thread_graceful_buffer = NULL;
        int *thread_busy_buffer = NULL;
        clock_t tu, ts, tcu, tcs;
        clock_t gu, gs, gcu, gcs;
        ap_generation_t mpm_generation, worker_generation;
    #ifdef HAVE_TIMES
        float tick;
        int times_per_thread;
    #endif
    
        if (strcmp(r->handler, STATUS_MAGIC_TYPE) && strcmp(r->handler,
                "server-status")) {
            return DECLINED;
        }
    
    #ifdef HAVE_TIMES
        times_per_thread = getpid() != child_pid;
    #endif
    
        ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
    
    #ifdef HAVE_TIMES
    #ifdef _SC_CLK_TCK
        tick = sysconf(_SC_CLK_TCK);
    #else
        tick = HZ;
    #endif
    #endif
    
        idle = 0;
        graceful = 0;
        busy = 0;
        count = 0;
        bcount = 0;
        kbcount = 0;
        duration_global = 0;
        short_report = 0;
        no_table_report = 0;
    
        if (!ap_exists_scoreboard_image()) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01237)
                          "Server status unavailable in inetd mode");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t));
        stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char));
        if (is_async) {
            thread_idle_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
            thread_graceful_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
            thread_busy_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
        }
    
        nowtime = apr_time_now();
    #ifdef HAVE_TIMES
        global_record = ap_get_scoreboard_global();
        gu = global_record->times.tms_utime;
        gs = global_record->times.tms_stime;
        gcu = global_record->times.tms_cutime;
        gcs = global_record->times.tms_cstime;
    #else
        gu = gs = gcu = gcs = 0;
    #endif
        tu = ts = tcu = tcs = 0;
    
        r->allowed = (AP_METHOD_BIT << M_GET);
        if (r->method_number != M_GET)
            return DECLINED;
    
        ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
    
        /*
         * 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: {
                        apr_size_t len = strlen(status_options[i].form_data_str);
                        long t = 0;
    
                        if (*(loc + len ) == '=') {
                            t = atol(loc + len + 1);
                        }
                        apr_table_setn(r->headers_out,
                                       status_options[i].hdr_out_str,
                                       apr_ltoa(r->pool, t < 1 ? 10 : t));
                        break;
                    }
                    case STAT_OPT_NOTABLE:
                        no_table_report = 1;
                        break;
                    case STAT_OPT_AUTO:
                        ap_set_content_type_ex(r, "text/plain; charset=ISO-8859-1", 1);
                        short_report = 1;
                        break;
                    }
                }
    
                i++;
            }
        }
    
        ws_record = apr_palloc(r->pool, sizeof *ws_record);
    
        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);
            if (is_async) {
                thread_idle_buffer[i] = 0;
                thread_graceful_buffer[i] = 0;
                thread_busy_buffer[i] = 0;
            }
            for (j = 0; j < thread_limit; ++j) {
                int indx = (i * thread_limit) + j;
    
                ap_copy_scoreboard_worker(ws_record, i, j);
                res = ws_record->status;
    
                if ((i >= max_servers || j >= threads_per_child)
                    && (res == SERVER_DEAD))
                    stat_buffer[indx] = status_flags[SERVER_DISABLED];
                else
                    stat_buffer[indx] = status_flags[res];
    
                if (!ps_record->quiescing
                    && ps_record->pid) {
                    if (res == SERVER_READY) {
                        if (ps_record->generation == mpm_generation)
                            idle++;
                        if (is_async)
                            thread_idle_buffer[i]++;
                    }
                    else if (res != SERVER_DEAD &&
                             res != SERVER_STARTING &&
                             res != SERVER_IDLE_KILL) {
                        if (res == SERVER_GRACEFUL) {
                            graceful++;
                            if (is_async)
                                thread_graceful_buffer[i]++;
                        } else {
                            busy++;
                            if (is_async)
                                thread_busy_buffer[i]++;
                        }
                    }
                }
    
                /* 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 += tmp_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 = tmp_tcs;
                            }
                        }
    #endif /* HAVE_TIMES */
    
                        count += lres;
                        bcount += bytes;
                        duration_global += ws_record->duration;
    
                        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);
        ap_get_loadavg(&t);
    
        if (!short_report) {
            ap_rputs(DOCTYPE_HTML_3_2
                     "<html><head>\n"
                     "<title>Apache Status</title>\n"
                     "</head><body>\n"
                     "<h1>Apache Server Status for ", r);
            ap_rvputs(r, ap_escape_html(r->pool, ap_get_server_name(r)),
                      " (via ", r->connection->local_ip,
                      ")</h1>\n\n", NULL);
            ap_rvputs(r, "<dl><dt>Server Version: ",
                      ap_get_server_description(), "</dt>\n", NULL);
            ap_rvputs(r, "<dt>Server MPM: ",
                      ap_show_mpm(), "</dt>\n", NULL);
            ap_rvputs(r, "<dt>Server Built: ",
                      ap_get_server_built(), "\n</dt></dl><hr /><dl>\n", NULL);
            ap_rvputs(r, "<dt>Current Time: ",
                      ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0),
                                 "</dt>\n", NULL);
            ap_rvputs(r, "<dt>Restart Time: ",
                      ap_ht_time(r->pool,
                                 ap_scoreboard_image->global->restart_time,
                                 DEFAULT_TIME_FORMAT, 0),
                      "</dt>\n", NULL);
            ap_rprintf(r, "<dt>Parent Server Config. Generation: %d</dt>\n",
                       ap_state_query(AP_SQ_CONFIG_GEN));
            ap_rprintf(r, "<dt>Parent Server MPM Generation: %d</dt>\n",
                       (int)mpm_generation);
            ap_rputs("<dt>Server uptime: ", r);
            show_time(r, up_time);
            ap_rputs("</dt>\n", r);
            ap_rprintf(r, "<dt>Server load: %.2f %.2f %.2f</dt>\n",
                       t.loadavg, t.loadavg5, t.loadavg15);
        }
        else {
            ap_rvputs(r, ap_get_server_name(r), "\n", NULL);
            ap_rvputs(r, "ServerVersion: ",
                      ap_get_server_description(), "\n", NULL);
            ap_rvputs(r, "ServerMPM: ",
                      ap_show_mpm(), "\n", NULL);
            ap_rvputs(r, "Server Built: ",
                      ap_get_server_built(), "\n", NULL);
            ap_rvputs(r, "CurrentTime: ",
                      ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0),
                                 "\n", NULL);
            ap_rvputs(r, "RestartTime: ",
                      ap_ht_time(r->pool,
                                 ap_scoreboard_image->global->restart_time,
                                 DEFAULT_TIME_FORMAT, 0),
                      "\n", NULL);
            ap_rprintf(r, "ParentServerConfigGeneration: %d\n",
                       ap_state_query(AP_SQ_CONFIG_GEN));
            ap_rprintf(r, "ParentServerMPMGeneration: %d\n",
                       (int)mpm_generation);
            ap_rprintf(r, "ServerUptimeSeconds: %u\n",
                       up_time);
            ap_rputs("ServerUptime:", r);
            show_time(r, up_time);
            ap_rputs("\n", r);
            ap_rprintf(r, "Load1: %.2f\nLoad5: %.2f\nLoad15: %.2f\n",
                       t.loadavg, t.loadavg5, t.loadavg15);
        }
    
        if (ap_extended_status) {
            clock_t cpu = gu + gs + gcu + gcs + tu + ts + tcu + tcs;
            if (short_report) {
                ap_rprintf(r, "Total Accesses: %lu\nTotal kBytes: %"
                           APR_OFF_T_FMT "\nTotal Duration: %"
                           APR_TIME_T_FMT "\n",
                           count, kbcount, apr_time_as_msec(duration_global));
    
    #ifdef HAVE_TIMES
                /* Allow for OS/2 not having CPU stats */
                ap_rprintf(r, "CPUUser: %g\nCPUSystem: %g\nCPUChildrenUser: %g\nCPUChildrenSystem: %g\n",
                           (gu + tu) / tick, (gs + ts) / tick, (gcu + tcu) / tick, (gcs + tcs) / tick);
    
                if (cpu)
                    ap_rprintf(r, "CPULoad: %g\n",
                               cpu / 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);
    
                    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);
                    ap_rprintf(r, "DurationPerReq: %g\n",
                               (float) apr_time_as_msec(duration_global) / (float) count);
                }
            }
            else { /* !short_report */
                ap_rprintf(r, "<dt>Total accesses: %lu - Total Traffic: ", count);
                format_kbyte_out(r, kbcount);
                ap_rprintf(r, " - Total Duration: %" APR_TIME_T_FMT "</dt>\n",
                           apr_time_as_msec(duration_global));
    
    #ifdef HAVE_TIMES
                /* Allow for OS/2 not having CPU stats */
                ap_rprintf(r, "<dt>CPU Usage: u%g s%g cu%g cs%g",
                           (gu + tu) / tick, (gs + ts) / tick, (gcu + tcu) / tick, (gcs + tcs) / tick);
    
                if (cpu)
                    ap_rprintf(r, " - %.3g%% CPU load</dt>\n",
                               cpu / tick / up_time * 100.);
                else
                    ap_rputs("</dt>\n", r);
    #endif
    
                ap_rputs("<dt>", r);
                if (up_time > 0) {
                    ap_rprintf(r, "%.3g requests/sec - ",
                               (float) count / (float) up_time);
    
                    format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount
                                                       / (float) up_time));
                    ap_rputs("/second", r);
                }
    
                if (count > 0) {
                    if (up_time > 0)
                        ap_rputs(" - ", r);
                    format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount
                                                       / (float) count));
                    ap_rprintf(r, "/request - %g ms/request",
                    (float) apr_time_as_msec(duration_global) / (float) count);
                }
    
                ap_rputs("</dt>\n", r);
            } /* short_report */
        } /* ap_extended_status */
    
        if (!short_report)
            ap_rprintf(r, "<dt>%d requests currently being processed, %d workers gracefully restarting, "
                          "%d idle workers</dt>\n", busy, graceful, idle);
        else
            ap_rprintf(r, "BusyWorkers: %d\nGracefulWorkers: %d\nIdleWorkers: %d\n", busy, graceful, idle);
    
        if (!short_report)
            ap_rputs("</dl>", r);
    
        if (is_async) {
            int wait_io = 0, write_completion = 0, lingering_close = 0, keep_alive = 0,
                connections = 0, stopping = 0, procs = 0;
            if (!short_report)
                ap_rputs("\n\n<table rules=\"all\" cellpadding=\"1%\">\n"
                         "<tr><th rowspan=\"2\">Slot</th>"
                             "<th rowspan=\"2\">PID</th>"
                             "<th rowspan=\"2\">Stopping</th>"
                             "<th colspan=\"2\">Connections</th>\n"
                             "<th colspan=\"3\">Threads</th>"
                             "<th colspan=\"4\">Async connections</th></tr>\n"
                         "<tr><th>total</th><th>accepting</th>"
                             "<th>busy</th><th>graceful</th><th>idle</th>"
                             "<th>wait-io</th><th>writing</th><th>keep-alive</th>"
                             "<th>closing</th></tr>\n", r);
            for (i = 0; i < server_limit; ++i) {
                ps_record = ap_get_scoreboard_process(i);
                if (ps_record->pid) {
                    connections      += ps_record->connections;
                    wait_io          += ps_record->wait_io;
                    write_completion += ps_record->write_completion;
                    keep_alive       += ps_record->keep_alive;
                    lingering_close  += ps_record->lingering_close;
                    procs++;
                    if (ps_record->quiescing) {
                        stopping++;
                    }
                    if (!short_report) {
                        const char *dying = "no";
                        const char *old = "";
                        if (ps_record->quiescing) {
                            dying = "yes";
                        }
                        if (ps_record->generation != mpm_generation)
                            old = " (old gen)";
                        ap_rprintf(r, "<tr><td>%u</td><td>%" APR_PID_T_FMT "</td>"
                                          "<td>%s%s</td>"
                                          "<td>%u</td><td>%s</td>"
                                          "<td>%u</td><td>%u</td><td>%u</td>"
                                          "<td>%u</td><td>%u</td><td>%u</td><td>%u</td>"
                                          "</tr>\n",
                                   i, ps_record->pid,
                                   dying, old,
                                   ps_record->connections,
                                   ps_record->not_accepting ? "no" : "yes",
                                   thread_busy_buffer[i],
                                   thread_graceful_buffer[i],
                                   thread_idle_buffer[i],
                                   ps_record->wait_io,
                                   ps_record->write_completion,
                                   ps_record->keep_alive,
                                   ps_record->lingering_close);
                    }
                }
            }
            if (!short_report) {
                ap_rprintf(r, "<tr><td>Sum</td>"
                              "<td>%d</td><td>%d</td>"
                              "<td>%d</td><td>&nbsp;</td>"
                              "<td>%d</td><td>%d</td><td>%d</td>"
                              "<td>%d</td><td>%d</td><td>%d</td><td>%d</td>"
                              "</tr>\n</table>\n",
                              procs, stopping,
                              connections,
                              busy, graceful, idle,
                              wait_io, write_completion, keep_alive,
                              lingering_close);
            }
            else {
                ap_rprintf(r, "Processes: %d\n"
                              "Stopping: %d\n"
                              "ConnsTotal: %d\n"
                              "ConnsAsyncWaitIO: %d\n"
                              "ConnsAsyncWriting: %d\n"
                              "ConnsAsyncKeepAlive: %d\n"
                              "ConnsAsyncClosing: %d\n",
                              procs, stopping,
                              connections,
                              wait_io, write_completion, keep_alive,
                              lingering_close);
            }
        }
    
        /* send the scoreboard 'table' out */
        if (!short_report)
            ap_rputs("<pre>", r);
        else
            ap_rputs("Scoreboard: ", r);
    
        written = 0;
        for (i = 0; i < server_limit; ++i) {
            for (j = 0; j < thread_limit; ++j) {
                int indx = (i * thread_limit) + j;
                if (stat_buffer[indx] != status_flags[SERVER_DISABLED]) {
                    ap_rputc(stat_buffer[indx], r);
                    if ((written % STATUS_MAXLINE == (STATUS_MAXLINE - 1))
                        && !short_report)
                        ap_rputs("\n", r);
                    written++;
                }
            }
        }
    
    
        if (short_report)
            ap_rputs("\n", r);
        else {
            ap_rputs("</pre>\n"
                     "<p>Scoreboard Key:<br />\n"
                     "\"<b><code>_</code></b>\" Waiting for Connection, \n"
                     "\"<b><code>S</code></b>\" Starting up, \n"
                     "\"<b><code>R</code></b>\" Reading Request,<br />\n"
                     "\"<b><code>W</code></b>\" Sending Reply, \n"
                     "\"<b><code>K</code></b>\" Keepalive (read), \n"
                     "\"<b><code>D</code></b>\" DNS Lookup,<br />\n"
                     "\"<b><code>C</code></b>\" Closing connection, \n"
                     "\"<b><code>L</code></b>\" Logging, \n"
                     "\"<b><code>G</code></b>\" Gracefully finishing,<br /> \n"
                     "\"<b><code>I</code></b>\" Idle cleanup of worker, \n"
                     "\"<b><code>.</code></b>\" Open slot with no current process<br />\n"
                     "</p>\n", r);
            if (!ap_extended_status) {
                int j;
                int k = 0;
                ap_rputs("PID Key: <br />\n"
                         "<pre>\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"
                         "</pre>\n", r);
            }
        }
    
        if (ap_extended_status && !short_report) {
            if (no_table_report)
                ap_rputs("<hr /><h2>Server Details</h2>\n\n", r);
            else
                ap_rputs("\n\n<table border=\"0\"><tr>"
                         "<th>Srv</th><th>PID</th><th>Acc</th>"
                         "<th>M</th>"
    #ifdef HAVE_TIMES
                         "<th>CPU\n</th>"
    #endif
                         "<th>SS</th><th>Req</th><th>Dur</th>"
                         "<th>Conn</th><th>Child</th><th>Slot</th>"
                         "<th>Client</th><th>Protocol</th><th>VHost</th>"
                         "<th>Request</th></tr>\n\n", r);
    
            for (i = 0; i < server_limit; ++i) {
                for (j = 0; j < thread_limit; ++j) {
                    ap_copy_scoreboard_worker(ws_record, 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)
                            apr_time_as_msec(ws_record->stop_time -
                              ws_record->start_time);
                    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;
                    duration_slot = ws_record->duration;
                    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,
                                       "<b>Server %d-%d</b> (-): %d|%lu|%lu [",
                                       i, (int)worker_generation,
                                       (int)conn_lres, my_lres, lres);
                        else
                            ap_rprintf(r,
                                       "<b>Server %d-%d</b> (%"
                                       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("<b>Read</b>", r);
                            break;
                        case SERVER_BUSY_WRITE:
                            ap_rputs("<b>Write</b>", r);
                            break;
                        case SERVER_BUSY_KEEPALIVE:
                            ap_rputs("<b>Keepalive</b>", r);
                            break;
                        case SERVER_BUSY_LOG:
                            ap_rputs("<b>Logging</b>", r);
                            break;
                        case SERVER_BUSY_DNS:
                            ap_rputs("<b>DNS lookup</b>", r);
                            break;
                        case SERVER_CLOSING:
                            ap_rputs("<b>Closing</b>", 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 %" APR_TIME_T_FMT "(",
    #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, apr_time_as_msec(duration_slot));
    
                        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,
                                   " <i>%s {%s}</i> <i>(%s)</i> <b>[%s]</b><br />\n\n",
                                   ap_escape_html(r->pool,
                                                  ws_record->client64),
                                   ap_escape_html(r->pool,
                                                  ap_escape_logitem(r->pool,
                                                                    ws_record->request)),
                                   ap_escape_html(r->pool,
                                                  ws_record->protocol),
                                   ap_escape_html(r->pool,
                                                  ws_record->vhost));
                    }
                    else { /* !no_table_report */
                        if (ws_record->status == SERVER_DEAD)
                            ap_rprintf(r,
                                       "<tr><td><b>%d-%d</b></td><td>-</td><td>%d/%lu/%lu",
                                       i, (int)worker_generation,
                                       (int)conn_lres, my_lres, lres);
                        else
                            ap_rprintf(r,
                                       "<tr><td><b>%d-%d</b></td><td>%"
                                       APR_PID_T_FMT
                                       "</td><td>%d/%lu/%lu",
                                       i, (int)worker_generation,
                                       worker_pid,
                                       (int)conn_lres,
                                       my_lres, lres);
    
                        switch (ws_record->status) {
                        case SERVER_READY:
                            ap_rputs("</td><td>_", r);
                            break;
                        case SERVER_STARTING:
                            ap_rputs("</td><td><b>S</b>", r);
                            break;
                        case SERVER_BUSY_READ:
                            ap_rputs("</td><td><b>R</b>", r);
                            break;
                        case SERVER_BUSY_WRITE:
                            ap_rputs("</td><td><b>W</b>", r);
                            break;
                        case SERVER_BUSY_KEEPALIVE:
                            ap_rputs("</td><td><b>K</b>", r);
                            break;
                        case SERVER_BUSY_LOG:
                            ap_rputs("</td><td><b>L</b>", r);
                            break;
                        case SERVER_BUSY_DNS:
                            ap_rputs("</td><td><b>D</b>", r);
                            break;
                        case SERVER_CLOSING:
                            ap_rputs("</td><td><b>C</b>", r);
                            break;
                        case SERVER_DEAD:
                            ap_rputs("</td><td>.", r);
                            break;
                        case SERVER_GRACEFUL:
                            ap_rputs("</td><td>G", r);
                            break;
                        case SERVER_IDLE_KILL:
                            ap_rputs("</td><td>I", r);
                            break;
                        default:
                            ap_rputs("</td><td>?", r);
                            break;
                        }
    
                        ap_rprintf(r,
                                   "\n</td>"
    #ifdef HAVE_TIMES
                                   "<td>%.2f</td>"
    #endif
                                   "<td>%ld</td><td>%ld</td><td>%" APR_TIME_T_FMT,
    #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, apr_time_as_msec(duration_slot));
    
                        ap_rprintf(r, "</td><td>%-1.1f</td><td>%-2.2f</td><td>%-2.2f\n",
                                   (float)conn_bytes / KBYTE, (float) my_bytes / MBYTE,
                                   (float)bytes / MBYTE);
    
                        ap_rprintf(r, "</td><td>%s</td><td>%s</td><td nowrap>%s</td>"
                                      "<td nowrap>%s</td></tr>\n\n",
                                   ap_escape_html(r->pool,
                                                  ws_record->client64),
                                   ap_escape_html(r->pool,
                                                  ws_record->protocol),
                                   ap_escape_html(r->pool,
                                                  ws_record->vhost),
                                   ap_escape_html(r->pool,
                                                  ap_escape_logitem(r->pool,
                                                          ws_record->request)));
                    } /* no_table_report */
                } /* for (j...) */
            } /* for (i...) */
    
            if (!no_table_report) {
                ap_rputs("</table>\n \
    <hr /> \
    <table>\n \
    <tr><th>Srv</th><td>Child Server number - generation</td></tr>\n \
    <tr><th>PID</th><td>OS process ID</td></tr>\n \
    <tr><th>Acc</th><td>Number of accesses this connection / this child / this slot</td></tr>\n \
    <tr><th>M</th><td>Mode of operation</td></tr>\n"
    
    #ifdef HAVE_TIMES
    "<tr><th>CPU</th><td>CPU usage, number of seconds</td></tr>\n"
    #endif
    
    "<tr><th>SS</th><td>Seconds since beginning of most recent request</td></tr>\n \
    <tr><th>Req</th><td>Milliseconds required to process most recent request</td></tr>\n \
    <tr><th>Dur</th><td>Sum of milliseconds required to process all requests</td></tr>\n \
    <tr><th>Conn</th><td>Kilobytes transferred this connection</td></tr>\n \
    <tr><th>Child</th><td>Megabytes transferred this child</td></tr>\n \
    <tr><th>Slot</th><td>Total megabytes transferred this slot</td></tr>\n \
    </table>\n", r);
            }
        } /* if (ap_extended_status && !short_report) */
        else {
    
            if (!short_report) {
                ap_rputs("<hr />To obtain a full report with current status "
                         "information you need to use the "
                         "<code>ExtendedStatus On</code> 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("<hr />\n",r), r);
            ap_rputs("</body></html>\n", r);
        }
    
        return 0;
    }
    
    static int status_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
    {
        /* When mod_status is loaded, default our ExtendedStatus to 'on'
         * other modules which prefer verbose scoreboards may play a similar game.
         * If left to their own requirements, mpm modules can make do with simple
         * scoreboard entries.
         */
        ap_extended_status = 1;
        return OK;
    }
    
    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';
        status_flags[SERVER_DISABLED] = ' ';
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
        ap_mpm_query(AP_MPMQ_MAX_THREADS, &threads_per_child);
        /* work around buggy MPMs */
        if (threads_per_child == 0)
            threads_per_child = 1;
        ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_servers);
        ap_mpm_query(AP_MPMQ_IS_ASYNC, &is_async);
        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_pre_config(status_pre_config, NULL, NULL, APR_HOOK_LAST);
        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
    }
    
    AP_DECLARE_MODULE(status) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,                       /* dir config creater */
        NULL,                       /* dir merger --- default is to override */
        NULL,                       /* server config */
        NULL,                       /* merge server config */
        NULL,                       /* command table */
        register_hooks              /* register_hooks */
    };
    ����������������������������������������httpd-2.4.64/modules/generators/config5.m4����������������������������������������������������������0000664�0001751�0001751�00000006301�14633767636�020264� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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, , , )
    APACHE_MODULE(info, server information, , , most)
    APACHE_MODULE(suexec, set uid and gid for spawned processes, , , no, [
                  other_targets=suexec ] )
    
    # Is mod_cgid needed?
    case $host in
        *mingw*)
            dnl No fork+thread+fd issues, and cgid doesn't work anyway.
            cgid_needed="no"
            ;;
        *)
            if ap_mpm_is_threaded; then
                dnl if we are using a threaded MPM on Unix, we can get better
                dnl performance with mod_cgid, and also avoid potential issues
                dnl with forking from a threaded process.
                cgid_needed="yes"
            else
                dnl if we are using a non-threaded MPM, it makes little sense to
                dnl use mod_cgid, and it just opens up holes we don't need.
                cgid_needed="no"
            fi
            ;;
    esac
    
    if test $cgid_needed = "yes"; then
        APACHE_MODULE(cgid, CGI scripts.  Enabled by default with threaded MPMs, , , most, [
        case $host in
          *-solaris2*)
            case `uname -r` in
              5.10)
              dnl Does the system have the appropriate patches?
              case `uname -p` in
                i386)
                  patch_id="120665"
                  ;;
                sparc)
                  patch_id="120664"
                  ;;
                *)
                  AC_MSG_WARN([Unknown platform])
                  patch_id="120664"
                  ;;
              esac
              AC_MSG_CHECKING([for Solaris patch $patch_id])
              showrev -p | grep "$patch_id" >/dev/null 2>&1
              if test $? -eq 1; then
              dnl Solaris 11 (next release) as of snv_19 doesn't have this problem.
              dnl It may be possible to use /kernel/drv/tl from later releases.
              AC_MSG_ERROR([Please apply either patch # 120664 (Sparc) or # 120665 (x86).
    Without these patches, mod_cgid is non-functional on Solaris 10 due to an OS
    bug with AF_UNIX sockets.
    If you can not apply these patches, you can do one of the following:
     - run configure with --disable-cgid
     - switch to the prefork MPM
    For more info: <http://issues.apache.org/bugzilla/show_bug.cgi?id=34264>])
              else
                AC_MSG_RESULT(yes)
              fi
              ;;
            esac
            ;;
        esac
      ])
        APACHE_MODULE(cgi, CGI scripts.  Enabled by default with non-threaded MPMs, , , no)
    else
        APACHE_MODULE(cgi, CGI scripts.  Enabled by default with non-threaded MPMs, , , most)
        APACHE_MODULE(cgid, CGI scripts.  Enabled by default with threaded MPMs, , , no)
    fi
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    AC_ARG_ENABLE(cgid-fdpassing,
      [APACHE_HELP_STRING(--enable-cgid-fdpassing,Enable experimental mod_cgid support for fd passing)],
      [if test "$enableval" = "yes"; then
         AC_CHECK_DECL(CMSG_DATA,
           [AC_DEFINE([HAVE_CGID_FDPASSING], 1, [Enable FD passing support in mod_cgid])],
           [AC_MSG_ERROR([cannot support mod_cgid fd-passing on this system])], [
    #include <sys/types.h>
    #include <sys/socket.h>])
      fi
    ])
    
    APACHE_MODPATH_FINISH
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/cgi_common.h��������������������������������������������������������0000664�0001751�0001751�00000052532�14633767636�020762� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_buckets.h"
    #include "apr_lib.h"
    #include "apr_poll.h"
    
    #define APR_WANT_STRFUNC
    #define APR_WANT_MEMFUNC
    #include "apr_want.h"
    
    #include "httpd.h"
    #include "util_filter.h"
    #include "util_script.h"
    
    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;
    
    /* These functions provided by mod_cgi.c/mod_cgid.c still. */
    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);
    static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f,
                                    apr_bucket_brigade *bb, char *s);
    static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f,
                                    apr_bucket_brigade *bb, const char *command);
    
    /* Read and discard all output from the brigade.  Note that with the
     * CGI bucket, the brigade will become empty once the script's stdout
     * is closed (or on error/timeout), but the stderr output may not have
     * been entirely captured at this point. */
    static void discard_script_output(apr_bucket_brigade *bb)
    {
        apr_bucket *e;
        const char *buf;
        apr_size_t len;
    
        for (e = APR_BRIGADE_FIRST(bb);
             e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e);
             e = APR_BRIGADE_FIRST(bb))
        {
            if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) {
                break;
            }
            apr_bucket_delete(e);
        }
    }
    
    static int log_scripterror(request_rec *r, cgi_server_conf *conf, int ret,
                               apr_status_t rv, const char *logno,
                               const char *error)
    {
        apr_file_t *f = NULL;
        apr_finfo_t finfo;
        char time_str[APR_CTIME_LEN];
    
        /* Intentional no APLOGNO */
        /* Callee provides APLOGNO in error text */
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                      "%sstderr from %s: %s", logno ? logno : "", r->filename, error);
    
        /* 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;
        cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module);
    
        while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN,
                                   script_err)) == APR_SUCCESS) {
    
            newline = strchr(argsbuffer, '\n');
            if (newline) {
                char *prev = newline - 1;
                if (prev >= argsbuffer && *prev == '\r') {
                    newline = prev;
                }
    
                *newline = '\0';
            }
            log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer);
        }
    
        return rv;
    }
    
    static apr_status_t cgi_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, APLOGNO(03195)
                          "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, APLOGNO(01228) "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, APLOGNO(01229) "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, APLOGNO(01230) "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, APLOGNO(01231) "unknown parameter "
                              "\"%s\" to tag exec in %s", tag, file);
                SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                break;
            }
        }
    
        return APR_SUCCESS;
    }
    
    /* Hook to register exec= handling with mod_include. */
    static void cgi_optfns_retrieve(void)
    {
        APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi;
    
        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", cgi_handle_exec);
        }
    }
    
    #ifdef WANT_CGI_BUCKET
    /* 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;
        apr_interval_time_t timeout;
    };
    
    /* 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_interval_time_t timeout,
                                         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);
    
        /* Disable APR timeout handling since we'll use poll() entirely. */
        apr_file_pipe_timeout_set(out, 0);
        apr_file_pipe_timeout_set(err, 0);
        
        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);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217)
                         "apr_pollset_create(); check system or user limits");
            return NULL;
        }
    
        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);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218)
                         "apr_pollset_add(); check system or user limits");
            return NULL;
        }
    
        fd.desc.f = err; /* script's stderr */
        fd.client_data = (void *)2;
        rv = apr_pollset_add(data->pollset, &fd);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219)
                         "apr_pollset_add(); check system or user limits");
            return NULL;
        }
    
        data->r = r;
        data->timeout = timeout;
        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 = 0;
        apr_status_t rv;
        int gotdata = 0;
    
        if (block != APR_NONBLOCK_READ) {
            timeout = data->timeout > 0 ? data->timeout : 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)) {
                if (timeout) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220)
                                  "Timeout waiting for output from CGI script %s",
                                  data->r->filename);
                    return rv;
                }
                else {
                    return APR_EAGAIN;
                }
            }
            else if (APR_STATUS_IS_EINTR(rv)) {
                continue;
            }
            else if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221)
                              "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 /* WANT_CGI_BUCKET */
    
    /* Handle the CGI response output, having set up the brigade with the
     * CGI or PIPE bucket as appropriate. */
    static int cgi_handle_response(request_rec *r, int nph, apr_bucket_brigade *bb,
                                   apr_interval_time_t timeout, cgi_server_conf *conf,
                                   char *logdata, apr_file_t *script_err)
    {
        apr_status_t rv;
        
        /* Handle script return... */
        if (!nph) {
            const char *location;
            char sbuf[MAX_STRING_LEN];
            int ret;
    
            ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
                                                       APLOG_MODULE_INDEX);
    
            /* xCGI has its own body framing mechanism which we don't
             * match against any provided Content-Length, so let the
             * core determine C-L vs T-E based on what's actually sent.
             */
            if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
                apr_table_unset(r->headers_out, "Content-Length");
            apr_table_unset(r->headers_out, "Transfer-Encoding");
    
            if (ret != OK) {
                /* In the case of a timeout reading script output, clear
                 * the brigade to avoid a second attempt to read the
                 * output. */
                if (ret == HTTP_GATEWAY_TIME_OUT) {
                    apr_brigade_cleanup(bb);
                }
    
                ret = log_script(r, conf, ret, logdata, sbuf, bb, script_err);
    
                /*
                 * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
                 * does not set an explicit status and ap_meets_conditions, which
                 * is called by ap_scan_script_header_err_brigade, detects that
                 * the conditions of the requests are met and the response is
                 * not modified.
                 * In this case set r->status and return OK in order to prevent
                 * running through the error processing stack as this would
                 * break with mod_cache, if the conditions had been set by
                 * mod_cache itself to validate a stale entity.
                 * BTW: We circumvent the error processing stack anyway if the
                 * CGI script set an explicit status code (whatever it is) and
                 * the only possible values for ret here are:
                 *
                 * HTTP_NOT_MODIFIED          (set by ap_meets_conditions)
                 * HTTP_PRECONDITION_FAILED   (set by ap_meets_conditions)
                 * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
                 * processing of the response of the CGI script, e.g broken headers
                 * or a crashed CGI process).
                 */
                if (ret == HTTP_NOT_MODIFIED) {
                    r->status = ret;
                    return OK;
                }
    
                return ret;
            }
    
            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);
    
                if (script_err) {
                    apr_file_pipe_timeout_set(script_err, 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 = "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) {
                /* XXX: 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;
            }
    
            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 (script_err && rv == APR_SUCCESS && !r->connection->aborted) {
            apr_file_pipe_timeout_set(script_err, timeout);
            log_script_err(r, script_err);
        }
    
        if (script_err) apr_file_close(script_err);
    
        return OK;                      /* NOT r->status, even if it has changed. */
    }
    
    /* Read the request body and write it to fd 'script_out', using 'bb'
     * as temporary bucket brigade.  If 'logbuf' is non-NULL, the first
     * logbufbytes of stdout are stored in logbuf. */
    static apr_status_t cgi_handle_request(request_rec *r, apr_file_t *script_out,
                                           apr_bucket_brigade *bb,
                                           char *logbuf, apr_size_t logbufbytes)
    {
        int seen_eos = 0;
        int child_stopped_reading = 0;
        apr_status_t rv;
        int 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 */
                rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
                if (rv) {
                    return rv;
                }
    
                if (logbufbytes && dbpos < logbufbytes) {
                    int cursize;
    
                    if ((dbpos + len) > logbufbytes) {
                        cursize = logbufbytes - dbpos;
                    }
                    else {
                        cursize = len;
                    }
                    memcpy(logbuf + 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;
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02651)
                                  "Error writing request body to script %s", 
                                  r->filename);
                }
            }
            apr_brigade_cleanup(bb);
        }
        while (!seen_eos);
    
        if (logbuf) {
            logbuf[dbpos] = '\0';
        }
    
        return APR_SUCCESS;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgi.mak���������������������������������������������������������0000664�0001751�0001751�00000022775�12701473373�020562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_cgi.dsp
    !IF "$(CFG)" == ""
    CFG=mod_cgi - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_cgi - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_cgi - Win32 Release" && "$(CFG)" != "mod_cgi - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cgi - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_cgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cgi.obj"
    	-@erase "$(INTDIR)\mod_cgi.res"
    	-@erase "$(INTDIR)\mod_cgi_src.idb"
    	-@erase "$(INTDIR)\mod_cgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_cgi.exp"
    	-@erase "$(OUTDIR)\mod_cgi.lib"
    	-@erase "$(OUTDIR)\mod_cgi.pdb"
    	-@erase "$(OUTDIR)\mod_cgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cgi_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cgi.so" /d LONG_NAME="cgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cgi.pdb" /debug /out:"$(OUTDIR)\mod_cgi.so" /implib:"$(OUTDIR)\mod_cgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cgi.obj" \
    	"$(INTDIR)\mod_cgi.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_cgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_cgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cgi.so"
       if exist .\Release\mod_cgi.so.manifest mt.exe -manifest .\Release\mod_cgi.so.manifest -outputresource:.\Release\mod_cgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_cgi - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_cgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cgi.obj"
    	-@erase "$(INTDIR)\mod_cgi.res"
    	-@erase "$(INTDIR)\mod_cgi_src.idb"
    	-@erase "$(INTDIR)\mod_cgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_cgi.exp"
    	-@erase "$(OUTDIR)\mod_cgi.lib"
    	-@erase "$(OUTDIR)\mod_cgi.pdb"
    	-@erase "$(OUTDIR)\mod_cgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cgi_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cgi.so" /d LONG_NAME="cgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cgi.pdb" /debug /out:"$(OUTDIR)\mod_cgi.so" /implib:"$(OUTDIR)\mod_cgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cgi.obj" \
    	"$(INTDIR)\mod_cgi.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_cgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_cgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cgi.so"
       if exist .\Debug\mod_cgi.so.manifest mt.exe -manifest .\Debug\mod_cgi.so.manifest -outputresource:.\Debug\mod_cgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_cgi.dep")
    !INCLUDE "mod_cgi.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_cgi.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_cgi - Win32 Release" || "$(CFG)" == "mod_cgi - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_cgi - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_cgi - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cgi - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_cgi - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cgi - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_cgi - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_cgi - Win32 Release"
    
    
    "$(INTDIR)\mod_cgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_cgi.so" /d LONG_NAME="cgi_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_cgi - Win32 Debug"
    
    
    "$(INTDIR)\mod_cgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_cgi.so" /d LONG_NAME="cgi_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_cgi.c
    
    "$(INTDIR)\mod_cgi.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���httpd-2.4.64/modules/generators/mod_autoindex.dep���������������������������������������������������0000664�0001751�0001751�00000004240�12674411515�022002� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_autoindex.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_autoindex.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_fnmatch.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_suexec.h��������������������������������������������������������0000664�0001751�0001751�00000002040�11637105701�020744� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_suexec.h
     * @brief SuExec Extension Module for Apache
     *
     * @defgroup MOD_SUEXEC mod_suexec
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #include "unixd.h"
    
    typedef struct {
        ap_unix_identity_t ugid;
        int active;
    } suexec_config_t;
    
    /** @}*/
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_autoindex.mak���������������������������������������������������0000664�0001751�0001751�00000024015�12701473373�022005� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_autoindex.dsp
    !IF "$(CFG)" == ""
    CFG=mod_autoindex - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_autoindex - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_autoindex - Win32 Release" && "$(CFG)" != "mod_autoindex - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_autoindex - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_autoindex.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_autoindex.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_autoindex.obj"
    	-@erase "$(INTDIR)\mod_autoindex.res"
    	-@erase "$(INTDIR)\mod_autoindex_src.idb"
    	-@erase "$(INTDIR)\mod_autoindex_src.pdb"
    	-@erase "$(OUTDIR)\mod_autoindex.exp"
    	-@erase "$(OUTDIR)\mod_autoindex.lib"
    	-@erase "$(OUTDIR)\mod_autoindex.pdb"
    	-@erase "$(OUTDIR)\mod_autoindex.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_autoindex_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_autoindex.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_autoindex.so" /d LONG_NAME="autoindex_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_autoindex.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_autoindex.pdb" /debug /out:"$(OUTDIR)\mod_autoindex.so" /implib:"$(OUTDIR)\mod_autoindex.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_autoindex.obj" \
    	"$(INTDIR)\mod_autoindex.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_autoindex.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_autoindex.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_autoindex.so"
       if exist .\Release\mod_autoindex.so.manifest mt.exe -manifest .\Release\mod_autoindex.so.manifest -outputresource:.\Release\mod_autoindex.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_autoindex - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_autoindex.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_autoindex.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_autoindex.obj"
    	-@erase "$(INTDIR)\mod_autoindex.res"
    	-@erase "$(INTDIR)\mod_autoindex_src.idb"
    	-@erase "$(INTDIR)\mod_autoindex_src.pdb"
    	-@erase "$(OUTDIR)\mod_autoindex.exp"
    	-@erase "$(OUTDIR)\mod_autoindex.lib"
    	-@erase "$(OUTDIR)\mod_autoindex.pdb"
    	-@erase "$(OUTDIR)\mod_autoindex.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_autoindex_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_autoindex.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_autoindex.so" /d LONG_NAME="autoindex_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_autoindex.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_autoindex.pdb" /debug /out:"$(OUTDIR)\mod_autoindex.so" /implib:"$(OUTDIR)\mod_autoindex.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_autoindex.obj" \
    	"$(INTDIR)\mod_autoindex.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_autoindex.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_autoindex.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_autoindex.so"
       if exist .\Debug\mod_autoindex.so.manifest mt.exe -manifest .\Debug\mod_autoindex.so.manifest -outputresource:.\Debug\mod_autoindex.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_autoindex.dep")
    !INCLUDE "mod_autoindex.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_autoindex.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_autoindex - Win32 Release" || "$(CFG)" == "mod_autoindex - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_autoindex - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_autoindex - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_autoindex - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_autoindex - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_autoindex - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_autoindex - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_autoindex - Win32 Release"
    
    
    "$(INTDIR)\mod_autoindex.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_autoindex.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_autoindex.so" /d LONG_NAME="autoindex_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_autoindex - Win32 Debug"
    
    
    "$(INTDIR)\mod_autoindex.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_autoindex.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_autoindex.so" /d LONG_NAME="autoindex_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_autoindex.c
    
    "$(INTDIR)\mod_autoindex.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_asis.dep��������������������������������������������������������0000664�0001751�0001751�00000003742�12674411515�020747� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_asis.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_asis.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_main.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������httpd-2.4.64/modules/generators/mod_status.dep������������������������������������������������������0000664�0001751�0001751�00000004127�12674411515�021331� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_status.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_status.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_main.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_status.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/NWGNUautoindex������������������������������������������������������0000664�0001751�0001751�00000010214�11540546347�021214� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/NWGNUmod_asis�������������������������������������������������������0000664�0001751�0001751�00000010172�11540546347�021015� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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_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	=
    
    #
    # 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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/NWGNUmod_cgi��������������������������������������������������������0000664�0001751�0001751�00000010231�11540546347�020614� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(AP_WORK)/modules/filters \
    			$(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_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	=
    
    #
    # 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_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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_info.dsp��������������������������������������������������������0000664�0001751�0001751�00000010467�10551346420�020755� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_info.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_info.so" /d LONG_NAME="info_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_info.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_info.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_info.so" /d LONG_NAME="info_module for Apache"
    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 /out:".\Debug\mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_info.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_autoindex.c�����������������������������������������������������0000664�0001751�0001751�00000233543�14675527312�021474� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <mbp@humbug.org.au>.
     */
    
    #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 ADDALTCLASS         (1 << 19)
    #define OPTION_UNSET        (1 << 20)
    
    #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;
        char *head_insert;
        char *header;
        char *readme;
        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;
        int ign_noinherit;
    
        char *ctype;
        char *charset;
        char *datetime_format;
    } 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
    
    static APR_INLINE int response_is_html(request_rec *r)
    {
        char *ctype = ap_field_noparam(r->pool, r->content_type);
    
        return !ap_cstr_casecmp(ctype, "text/html")
            || !ap_cstr_casecmp(ctype, "application/xhtml+xml");
    }
    
    /*
     * 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);
    
        if (xhtml) {
            ap_rvputs(r, DOCTYPE_XHTML_1_0T,
                      "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
                      " <head>\n  <title>Index of ", title,
                      "</title>\n", NULL);
        } else {
            ap_rvputs(r, DOCTYPE_HTML_3_2,
                      "<html>\n <head>\n"
                      "  <title>Index of ", title,
                      "</title>\n", NULL);
        }
    
        if (d->style_sheet != NULL) {
            ap_rvputs(r, "  <link rel=\"stylesheet\" href=\"", d->style_sheet,
                    "\" type=\"text/css\"", xhtml ? " />\n" : ">\n", NULL);
        }
        if (d->head_insert != NULL) {
            ap_rputs(d->head_insert, r);
        }
        ap_rputs(" </head>\n <body>\n", r);
    }
    
    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 = apr_pstrdup(arr->pool, data);
        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 {
            p->apply_to = apr_pstrdup(arr->pool, to);
        }
    }
    
    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->temp_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->temp_pool, icon);
    
        if (icon[0] == '(') {
            char *alt;
            char *cl = strchr(iconbak, ')');
    
            if (cl == NULL) {
                return "missing closing paren";
            }
            alt = ap_getword_nc(cmd->temp_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->temp_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_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, "AddAltClass")) {
                option = ADDALTCLASS;
            }
            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 if (!strncasecmp(w, "Type=", 5)) {
                d_cfg->ctype = apr_pstrdup(cmd->pool, &w[5]);
            }
            else if (!strncasecmp(w, "Charset=", 8)) {
                d_cfg->charset = apr_pstrdup(cmd->pool, &w[8]);
            }
            else if (!strcasecmp(w, "UseOldDateFormat")) {
                d_cfg->datetime_format = "%d-%b-%Y %H:%M";
            }
            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_FLAG("IndexIgnoreReset", ap_set_flag_slot,
                     (void *)APR_OFFSETOF(autoindex_config_rec, ign_noinherit),
                     DIR_CMD_PERMS,
                     "Reset the inherited list of IndexIgnore filenames"),
        AP_INIT_ITERATE2("AddDescription", add_desc, BY_PATH, DIR_CMD_PERMS,
                         "Descriptive text followed by one or more filenames"),
        AP_INIT_TAKE1("HeaderName", ap_set_string_slot,
                      (void *)APR_OFFSETOF(autoindex_config_rec, header),
                      DIR_CMD_PERMS, "a filename"),
        AP_INIT_TAKE1("ReadmeName", ap_set_string_slot,
                      (void *)APR_OFFSETOF(autoindex_config_rec, readme),
                      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"),
        AP_INIT_TAKE1("IndexHeadInsert", ap_set_string_slot,
                      (void *)APR_OFFSETOF(autoindex_config_rec, head_insert),
                      DIR_CMD_PERMS, "String to insert in HTML HEAD section"),
        {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->opts = OPTION_UNSET;
        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->head_insert = add->head_insert ? add->head_insert
                                              : base->head_insert;
        new->header = add->header ? add->header
                                    : base->header;
        new->readme = add->readme ? add->readme
                                    : base->readme;
        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->ctype = add->ctype ? add->ctype : base->ctype;
        new->charset = add->charset ? add->charset : base->charset;
        new->datetime_format = add->datetime_format ? add->datetime_format : base->datetime_format;
    
        new->alt_list = apr_array_append(p, add->alt_list, base->alt_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->ign_list = add->ign_noinherit ? add->ign_list : apr_array_append(p, add->ign_list, base->ign_list);
        if (add->opts == NO_OPTIONS) {
            /*
             * If the current directory explicitly 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 == OPTION_UNSET) {
                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(const char *content_type, const char *content_encoding,
                           char *path, apr_array_header_t *list, int path_only)
    {
        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;
    }
    
    static char *find_item_by_request(request_rec *r, apr_array_header_t *list, int path_only)
    {
        return find_item(ap_field_noparam(r->pool, r->content_type),
                         r->content_encoding, r->filename, list, path_only);
    }
    
    #define find_icon(d,p,t) find_item_by_request(p,d->icon_list,t)
    #define find_alt(d,p,t) find_item_by_request(p,d->alt_list,t)
    #define find_default_icon(d,n) find_item(NULL, NULL, n, d->icon_list, 1)
    #define find_default_alt(d,n) find_item(NULL, NULL, n, d->alt_list, 1)
    
    /*
     * 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("<pre>\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("&lt;", r);
                }
                else if (ch == '>') {
                    ap_rputs("&gt;", r);
                }
                else if (ch == '&') {
                    ap_rputs("&amp;", r);
                }
                c = i + 1;
            }
        }
        ap_rputs("</pre>\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)
    {
        autoindex_config_rec *d;
        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 (response_is_html(rr)) {
                    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 (!ap_cstr_casecmpn("text/", rr->content_type, 5)) {
                    /*
                     * If we can open the file, prefix it with the preamble
                     * regardless; since we'll be sending a <pre> 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);
        }
    
        d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config, &autoindex_module);
    
        if (emit_H1) {
            if (d->style_sheet != NULL) {
                /* Insert style id if stylesheet used */
                ap_rvputs(r, "  <h1 id=\"indextitle\">Index of ", title, "</h1>\n", NULL);
            } else {
                ap_rvputs(r, "<h1>Index of ", title, "</h1>\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 (response_is_html(rr)) {
                    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 (!ap_cstr_casecmpn("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("</body></html>\n", r);
        }
        if (rr != NULL) {
            ap_destroy_sub_req(rr);
        }
    }
    
    
    static char *find_title(request_rec *r)
    {
        char titlebuf[MAX_STRING_LEN], *find = "<title>";
        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)
            && (response_is_html(r)
                || !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);
        }
        if (!ap_normalize_path(p->name, AP_NORMALIZE_ALLOW_RELATIVE |
                                        AP_NORMALIZE_NOT_ABOVE_ROOT)
                || p->name[0] == '\0') {
            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^^"))) {
                    /* Special alt text for parent dir to distinguish it from other directories
                       this is essential when trying to style this dir entry via AddAltClass */
                    p->alt = "PARENTDIR";
                }
            }
            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;
        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 &auml; 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 *tp;
        int static_columns = !!(autoindex_opts & SUPPRESS_COLSORT);
        apr_pool_t *scratch;
        int name_width;
        int desc_width;
        char *datetime_format;
        char *name_scratch;
        char *pad_scratch;
        char *breakrow = "";
    
        apr_pool_create(&scratch, r->pool);
        apr_pool_tag(scratch, "autoindex_scratch");
    
        name_width = d->name_width;
        desc_width = d->desc_width;
        datetime_format = d->datetime_format ? d->datetime_format : "%Y-%m-%d %H:%M";
    
        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;
            if (d->style_sheet != NULL) {
                /* Emit table with style id */
                ap_rputs("  <table id=\"indexlist\">\n   <tr class=\"indexhead\">", r);
            } else {
                ap_rputs("  <table>\n   <tr>", r);
            }
            if (!(autoindex_opts & SUPPRESS_ICON)) {
                ap_rvputs(r, "<th", (d->style_sheet != NULL) ? " class=\"indexcolicon\">" : " valign=\"top\">", NULL);
                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("&nbsp;</th>", r);
                }
    
                ++cols;
            }
            ap_rvputs(r, "<th", (d->style_sheet != NULL) ? " class=\"indexcolname\">" : ">", NULL);
            emit_link(r, "Name", K_NAME, keyid, direction,
                      colargs, static_columns);
            if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
                ap_rvputs(r, "</th><th", (d->style_sheet != NULL) ? " class=\"indexcollastmod\">" : ">", NULL);
                emit_link(r, "Last modified", K_LAST_MOD, keyid, direction,
                          colargs, static_columns);
                ++cols;
            }
            if (!(autoindex_opts & SUPPRESS_SIZE)) {
                ap_rvputs(r, "</th><th", (d->style_sheet != NULL) ? " class=\"indexcolsize\">" : ">", NULL);
                emit_link(r, "Size", K_SIZE, keyid, direction,
                          colargs, static_columns);
                ++cols;
            }
            if (!(autoindex_opts & SUPPRESS_DESC)) {
                ap_rvputs(r, "</th><th", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">", NULL);
                emit_link(r, "Description", K_DESC, keyid, direction,
                          colargs, static_columns);
                ++cols;
            }
            if (!(autoindex_opts & SUPPRESS_RULES)) {
                breakrow = apr_psprintf(r->pool,
                                        "   <tr%s><th colspan=\"%d\">"
                                        "<hr%s></th></tr>\n",
                                        (d->style_sheet != NULL) ? " class=\"indexbreakrow\"" : "",
                                        cols,
                                        (autoindex_opts & EMIT_XHTML) ? " /" : "");
            }
            ap_rvputs(r, "</th></tr>\n", 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) {
                /* Even/Odd rows for IndexStyleSheet */
                if (d->style_sheet != NULL) {
                    if (ar[x]->alt && (autoindex_opts & ADDALTCLASS)) {
                        /* Include alt text in class name, distinguish between odd and even rows */
                        char *altclass = apr_pstrdup(scratch, ar[x]->alt);
                        ap_str_tolower(altclass);
                        ap_rvputs(r, "   <tr class=\"", ( x & 0x1) ? "odd-" : "even-", altclass, "\">", NULL);
                    } else {
                        /* Distinguish between odd and even rows */
                        ap_rvputs(r, "   <tr class=\"", ( x & 0x1) ? "odd" : "even", "\">", NULL);
                    }
                } else {
                    ap_rputs("<tr>", r);
                }
    
                if (!(autoindex_opts & SUPPRESS_ICON)) {
                    ap_rvputs(r, "<td", (d->style_sheet != NULL) ? " class=\"indexcolicon\">" : " valign=\"top\">", NULL);
                    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("&nbsp;", 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", (d->style_sheet != NULL) ? " class=\"indexcolname\">" : ">", "<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", (d->style_sheet != NULL) ? " class=\"indexcolname\">" : ">", "<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[32];
                        apr_time_exp_t ts;
                        apr_time_exp_lt(&ts, ar[x]->lm);
                        apr_strftime(time_str, &rv, sizeof(time_str),
                                     datetime_format,
                                     &ts);
                        ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcollastmod\">" : " align=\"right\">", time_str, "  ", NULL);
                    }
                    else {
                        ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcollastmod\">&nbsp;" : ">&nbsp;", NULL);
                    }
                }
                if (!(autoindex_opts & SUPPRESS_SIZE)) {
                    char buf[5];
                    ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcolsize\">" : " 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", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">", ar[x]->desc, NULL);
                        }
                        else {
                            ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">",
                                      terminate_description(d, ar[x]->desc,
                                                            autoindex_opts,
                                                            desc_width), NULL);
                        }
                    }
                    else {
                        ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">", "&nbsp;", NULL);
                    }
                }
                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[32];
                        apr_time_exp_t ts;
                        apr_time_exp_lt(&ts, ar[x]->lm);
                        apr_strftime(time_str, &rv, sizeof(time_str),
                                    datetime_format,
                                    &ts);
                        ap_rvputs(r, time_str, "  ", NULL);
                    }
                    else {
                       /* Length="1975-04-07 01:23  "  (default in 2.4 and later) or
                        * Length="07-Apr-1975 01:24  ". (2.2 and UseOldDateFormat) 
                        * See 'datetime_format' 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, "\"> ",
                          ap_escape_html(scratch, 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 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;
        char *ctype = "text/html";
        char *charset;
    
        if ((status = apr_dir_open(&thedir, name, r->pool)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01275)
                          "Can't open directory for index: %s", r->filename);
            return HTTP_FORBIDDEN;
        }
    
        if (autoindex_conf->ctype) {
            ctype = autoindex_conf->ctype;
        }
        if (autoindex_conf->charset) {
            charset = autoindex_conf->charset;
        }
        else {
    #if APR_HAS_UNICODE_FS
            charset = "UTF-8";
    #else
            charset = "ISO-8859-1";
    #endif
        }
        if (*charset) {
            ap_set_content_type_ex(r, apr_pstrcat(r->pool, ctype, ";charset=",
                                charset, NULL), 1);
        }
        else {
            ap_set_content_type_ex(r, ctype, 1);
        }
    
        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, autoindex_conf->header,
                  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, autoindex_conf->readme,
                  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) && !AP_IS_DEFAULT_HANDLER_NAME(r->handler)) {
            return DECLINED;
        }
        if (r->finfo.filetype != APR_DIR) {
            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 {
            const char *index_names = apr_table_get(r->notes, "dir-index-names");
    
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01276)
                          "Cannot serve directory %s: No matching DirectoryIndex (%s) found, and "
                          "server-generated directory index forbidden by "
                          "Options directive",
                           r->filename,
                           index_names ? index_names : "none");
            return HTTP_FORBIDDEN;
        }
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_handler(handle_autoindex,NULL,NULL,APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(autoindex) =
    {
        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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_info.c����������������������������������������������������������0000664�0001751�0001751�00000100252�14640775605�020417� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_version.h"
    #if APR_MAJOR_VERSION < 2
    #include "apu_version.h"
    #endif
    #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_connection.h"
    #include "http_request.h"
    #include "util_script.h"
    #include "ap_mpm.h"
    #include "mpm_common.h"
    #include "ap_provider.h"
    #include <stdio.h>
    #include <stdlib.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;
    
    /* current file name when doing -DDUMP_CONFIG */
    static const char *dump_config_fn_info;
    /* file handle when doing -DDUMP_CONFIG */
    static apr_file_t *out = NULL;
    
    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) {
            if (r)
                ap_rputc('0' + i % 10, r);
            else
                apr_file_putc((char)('0' + i % 10), out);
        }
        else {
            if (r)
                ap_rputs("&nbsp;", r);
            else
                apr_file_printf(out, " ");
        }
    }
    
    static void set_fn_info(request_rec *r, const char *name)
    {
        if (r)
            ap_set_module_config(r->request_config, &info_module, (void *)name);
        else
            dump_config_fn_info = name;
    }
    
    static const char *get_fn_info(request_rec *r)
    {
        if (r)
            return ap_get_module_config(r->request_config, &info_module);
        else
            return dump_config_fn_info;
    }
    
    
    static void mod_info_indent(request_rec * r, int nest,
                                const char *thisfn, int linenum)
    {
        int i;
        const char *prevfn = get_fn_info(r);
        if (thisfn == NULL)
            thisfn = "*UNKNOWN*";
        if (prevfn == NULL || 0 != strcmp(prevfn, thisfn)) {
            if (r) {
                thisfn = ap_escape_html(r->pool, thisfn);
                ap_rprintf(r, "<dd><tt><strong>In file: %s</strong></tt></dd>\n",
                       thisfn);
            }
            else {
                apr_file_printf(out, "# In file: %s\n", thisfn);
            }
            set_fn_info(r, thisfn);
        }
    
        if (r) {
            ap_rputs("<dd><tt>", r);
            put_int_flush_right(r, linenum > 0 ? linenum : 0, 4);
            ap_rputs(":&nbsp;", r);
        }
        else if (linenum > 0) {
            for (i = 1; i <= nest; ++i)
                apr_file_printf(out, "  ");
            apr_file_putc('#', out);
            put_int_flush_right(r, linenum, 4);
            apr_file_printf(out, ":\n");
        }
    
        for (i = 1; i <= nest; ++i) {
            if (r)
                ap_rputs("&nbsp;&nbsp;", r);
            else
                apr_file_printf(out, "  ");
        }
    }
    
    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);
        if (r)
            ap_rprintf(r, "%s <i>%s</i></tt></dd>\n",
                       ap_escape_html(r->pool, dir->directive),
                       ap_escape_html(r->pool, dir->args));
        else
            apr_file_printf(out, "%s %s\n", dir->directive, 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);
        if (r)
            ap_rprintf(r, "%s %s</tt></dd>\n",
                       ap_escape_html(r->pool, dir->directive),
                       ap_escape_html(r->pool, dir->args));
        else
            apr_file_printf(out, "%s %s\n", dir->directive, 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 == '<') {
            if (r)
                ap_rprintf(r, "&lt;/%s&gt;</tt></dd>",
                           ap_escape_html(r->pool, dirname + 1));
            else
                apr_file_printf(out, "</%s>\n", dirname + 1);
        }
        else {
            if (r)
                ap_rprintf(r, "/%s</tt></dd>", ap_escape_html(r->pool, dirname));
            else
                apr_file_printf(out, "/%s\n", 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 (ap_cstr_casecmp(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)
            set_fn_info(r, 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 const hook_lookup_t startup_hooks[] = {
        {"Pre-Config", ap_hook_get_pre_config},
        {"Check Configuration", ap_hook_get_check_config},
        {"Test Configuration", ap_hook_get_test_config},
        {"Post Configuration", ap_hook_get_post_config},
        {"Open Logs", ap_hook_get_open_logs},
        {"Pre-MPM", ap_hook_get_pre_mpm},
        {"MPM", ap_hook_get_mpm},
        {"Drop Privileges", ap_hook_get_drop_privileges},
        {"Retrieve Optional Functions", ap_hook_get_optional_fn_retrieve},
        {"Child Init", ap_hook_get_child_init},
        {NULL},
    };
    
    static const 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},
        {"Pre-Read Request", ap_hook_get_pre_read_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},
        {"Pre-Translate Name", ap_hook_get_pre_translate_name},
        {"Translate Name", ap_hook_get_translate_name},
        {"Map to Storage", ap_hook_get_map_to_storage},
        {"Check Access", ap_hook_get_access_checker_ex},
        {"Check Access (legacy)", ap_hook_get_access_checker},
        {"Verify User ID", ap_hook_get_check_user_id},
        {"Note Authentication Failure", ap_hook_get_note_auth_failure},
        {"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},
        {"Transaction Logging", ap_hook_get_log_transaction},
        {"Insert Errors", ap_hook_get_insert_error_filter},
        {"Generate Log ID", ap_hook_get_generate_log_id},
        {NULL},
    };
    
    static const hook_lookup_t other_hooks[] = {
        {"Monitor", ap_hook_get_monitor},
        {"Child Status", ap_hook_get_child_status},
        {"End Generation", ap_hook_get_end_generation},
        {"Error Logging", ap_hook_get_error_log},
        {"Query MPM Attributes", ap_hook_get_mpm_query},
        {"Query MPM Name", ap_hook_get_mpm_get_name},
        {"Register Timed Callback", ap_hook_get_mpm_register_timed_callback},
        {"Extend Expression Parser", ap_hook_get_expr_lookup},
        {"Set Management Items", ap_hook_get_get_mgmt_items},
    #if AP_ENABLE_EXCEPTION_HOOK
        {"Handle Fatal Exceptions", ap_hook_get_fatal_exception},
    #endif
        {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,
                                   const 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_description());
        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>Server loaded APR Version:</strong> "
                   "<tt>%s</tt></dt>\n", apr_version_string());
        ap_rprintf(r,
                   "<dt><strong>Compiled with APR Version:</strong> "
                   "<tt>%s</tt></dt>\n", APR_VERSION_STRING);
    #if APR_MAJOR_VERSION < 2
        ap_rprintf(r,
                   "<dt><strong>Server loaded APU Version:</strong> "
                   "<tt>%s</tt></dt>\n", apu_version_string());
        ap_rprintf(r,
                   "<dt><strong>Compiled with APU Version:</strong> "
                   "<tt>%s</tt></dt>\n", APU_VERSION_STRING);
    #endif
        ap_rprintf(r,
                   "<dt><strong>Server loaded PCRE Version:</strong> "
                   "<tt>%s</tt></dt>\n", ap_pcre_version_string(AP_REG_PCRE_LOADED));
        ap_rprintf(r,
                   "<dt><strong>Compiled with PCRE Version:</strong> "
                   "<tt>%s</tt></dt>\n", ap_pcre_version_string(AP_REG_PCRE_COMPILED));
        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_escape_html(r->pool, ap_get_server_name(r)),
                   ap_get_server_port(r));
        ap_rprintf(r,
                   "<dt><strong>Timeouts:</strong> "
                   "<tt>connection: %d &nbsp;&nbsp; "
                   "keep-alive: %d</tt></dt>",
                   (int) (apr_time_sec(serv->timeout)),
                   (int) (apr_time_sec(serv->keep_alive_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 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_rprintf(r, " -D PIPE_BUF=%ld\n", (long) PIPE_BUF);
    #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
    
    /* 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
    
    #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_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,
                       "&nbsp;&nbsp; %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<h2><a name=\"other_hooks\">Other Hooks</a></h2>\n<dl>",
             r);
    
        for (i = 0; other_hooks[i].name; i++) {
            ap_rprintf(r, "<dt><strong>%s:</strong>\n <br /><tt>\n",
                       other_hooks[i].name);
            dump_a_hook(r, other_hooks[i].get);
            ap_rputs("\n  </tt>\n</dt>\n", r);
        }
    
        ap_rputs("</dl>\n<hr />\n", r);
    
        return 0;
    }
    
    static int cmp_provider_groups(const void *a_, const void *b_)
    {
        const ap_list_provider_groups_t *a = a_, *b = b_;
        int ret = strcmp(a->provider_group, b->provider_group);
        if (!ret)
            ret = strcmp(a->provider_version, b->provider_version);
        return ret;
    }
    
    static int cmp_provider_names(const void *a_, const void *b_)
    {
        const ap_list_provider_names_t *a = a_, *b = b_;
        return strcmp(a->provider_name, b->provider_name);
    }
    
    static void show_providers(request_rec *r)
    {
        apr_array_header_t *groups = ap_list_provider_groups(r->pool);
        ap_list_provider_groups_t *group;
        apr_array_header_t *names;
        ap_list_provider_names_t *name;
        int i,j;
        const char *cur_group = NULL;
    
        qsort(groups->elts, groups->nelts, sizeof(ap_list_provider_groups_t),
              cmp_provider_groups);
        ap_rputs("<h2><a name=\"providers\">Providers</a></h2>\n<dl>", r);
    
        for (i = 0; i < groups->nelts; i++) {
            group = &APR_ARRAY_IDX(groups, i, ap_list_provider_groups_t);
            if (!cur_group || strcmp(cur_group, group->provider_group) != 0) {
                if (cur_group)
                    ap_rputs("\n</dt>\n", r);
                cur_group = group->provider_group;
                ap_rprintf(r, "<dt><strong>%s</strong> (version <tt>%s</tt>):"
                              "\n <br />\n", cur_group, group->provider_version);
            }
            names = ap_list_provider_names(r->pool, group->provider_group,
                                           group->provider_version);
            qsort(names->elts, names->nelts, sizeof(ap_list_provider_names_t),
                  cmp_provider_names);
            for (j = 0; j < names->nelts; j++) {
                name = &APR_ARRAY_IDX(names, j, ap_list_provider_names_t);
                ap_rprintf(r, "<tt>&nbsp;&nbsp;%s</tt><br/>", name->provider_name);
            }
        }
        if (cur_group)
            ap_rputs("\n</dt>\n", r);
        ap_rputs("</dl>\n<hr />\n", r);
    }
    
    static int cmp_module_name(const void *a_, const void *b_)
    {
        const module * const *a = a_;
        const module * const *b = b_;
        return strcmp((*a)->name, (*b)->name);
    }
    
    static apr_array_header_t *get_sorted_modules(apr_pool_t *p)
    {
        apr_array_header_t *arr = apr_array_make(p, 64, sizeof(module *));
        module *modp, **entry;
        for (modp = ap_top_module; modp; modp = modp->next) {
            entry = &APR_ARRAY_PUSH(arr, module *);
            *entry = modp;
        }
        qsort(arr->elts, arr->nelts, sizeof(module *), cmp_module_name);
        return arr;
    }
    
    static int display_info(request_rec * r)
    {
        module *modp = NULL;
        const char *more_info;
        const command_rec *cmd;
        apr_array_header_t *modules = NULL;
        int i;
    
        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_ex(r, "text/html; charset=ISO-8859-1", 1);
    
        ap_rputs(DOCTYPE_XHTML_1_0T
                 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
                 "<head>\n"
                 "  <title>Server Information</title>\n" "</head>\n", r);
        ap_rputs("<body><h1 style=\"text-align: center\">"
                 "Apache Server Information</h1>\n", r);
        if (!r->args || ap_cstr_casecmp(r->args, "list")) {
            if (!r->args) {
                ap_rputs("<dl><dt><tt>Subpages:<br />", r);
                ap_rputs("<a href=\"?config\">Configuration Files</a>, "
                         "<a href=\"?server\">Server Settings</a>, "
                         "<a href=\"?list\">Module List</a>, "
                         "<a href=\"?hooks\">Active Hooks</a>, "
                         "<a href=\"?providers\">Available Providers</a>", r);
                ap_rputs("</tt></dt></dl><hr />", r);
    
                ap_rputs("<dl><dt><tt>Sections:<br />", r);
                ap_rputs("<a href=\"#modules\">Loaded Modules</a>, "
                         "<a href=\"#server\">Server Settings</a>, "
                         "<a href=\"#startup_hooks\">Startup Hooks</a>, "
                         "<a href=\"#request_hooks\">Request Hooks</a>, "
                         "<a href=\"#other_hooks\">Other Hooks</a>, "
                         "<a href=\"#providers\">Providers</a>", r);
                ap_rputs("</tt></dt></dl><hr />", r);
    
                ap_rputs("<h2><a name=\"modules\">Loaded Modules</a></h2>"
                        "<dl><dt><tt>", r);
    
                modules = get_sorted_modules(r->pool);
                for (i = 0; i < modules->nelts; i++) {
                    modp = APR_ARRAY_IDX(modules, i, module *);
                    ap_rprintf(r, "<a href=\"#%s\">%s</a>", modp->name,
                               modp->name);
                    if (i < modules->nelts) {
                        ap_rputs(", ", r);
                    }
                }
                ap_rputs("</tt></dt></dl><hr />", r);
            }
    
            if (!r->args || !ap_cstr_casecmp(r->args, "server")) {
                show_server_settings(r);
            }
    
            if (!r->args || !ap_cstr_casecmp(r->args, "hooks")) {
                show_active_hooks(r);
            }
    
            if (!r->args || !ap_cstr_casecmp(r->args, "providers")) {
                show_providers(r);
            }
    
            if (r->args && 0 == ap_cstr_casecmp(r->args, "config")) {
                ap_rputs("<dl><dt><strong>Configuration:</strong>\n", r);
                mod_info_module_cmds(r, NULL, ap_conftree, 0, 0);
                ap_rputs("</dl><hr />", r);
            }
            else {
                int comma = 0;
                if (!modules)
                     modules = get_sorted_modules(r->pool);
                for (i = 0; i < modules->nelts; i++) {
                    modp = APR_ARRAY_IDX(modules, i, module *);
                    if (!r->args || !ap_cstr_casecmp(modp->name, r->args)) {
                        ap_rprintf(r,
                                   "<dl><dt><a name=\"%s\"><strong>Module Name:</strong></a> "
                                   "<font size=\"+1\"><tt><a href=\"?%s\">%s</a></tt></font></dt>\n",
                                   modp->name, modp->name, modp->name);
                        ap_rputs("<dt><strong>Content handlers:</strong> ", r);
    
                        if (module_find_hook(modp, ap_hook_get_handler)) {
                            ap_rputs("<tt> <em>yes</em></tt>", r);
                        }
                        else {
                            ap_rputs("<tt> <em>none</em></tt>", r);
                        }
    
                        ap_rputs("</dt>", r);
                        ap_rputs
                            ("<dt><strong>Configuration Phase Participation:</strong>\n",
                             r);
                        if (modp->create_dir_config) {
                            if (comma) {
                                ap_rputs(", ", r);
                            }
                            ap_rputs("<tt>Create Directory Config</tt>", r);
                            comma = 1;
                        }
                        if (modp->merge_dir_config) {
                            if (comma) {
                                ap_rputs(", ", r);
                            }
                            ap_rputs("<tt>Merge Directory Configs</tt>", r);
                            comma = 1;
                        }
                        if (modp->create_server_config) {
                            if (comma) {
                                ap_rputs(", ", r);
                            }
                            ap_rputs("<tt>Create Server Config</tt>", r);
                            comma = 1;
                        }
                        if (modp->merge_server_config) {
                            if (comma) {
                                ap_rputs(", ", r);
                            }
                            ap_rputs("<tt>Merge Server Configs</tt>", r);
                            comma = 1;
                        }
                        if (!comma)
                            ap_rputs("<tt> <em>none</em></tt>", r);
                        comma = 0;
                        ap_rputs("</dt>", r);
    
                        module_request_hook_participate(r, modp);
    
                        cmd = modp->cmds;
                        if (cmd) {
                            ap_rputs
                                ("<dt><strong>Module Directives:</strong></dt>",
                                 r);
                            while (cmd) {
                                if (cmd->name) {
                                    ap_rprintf(r, "<dd><tt>%s%s - <i>",
                                               ap_escape_html(r->pool, cmd->name),
                                               cmd->name[0] == '<' ? "&gt;" : "");
                                    if (cmd->errmsg) {
                                        ap_rputs(ap_escape_html(r->pool, cmd->errmsg), r);
                                    }
                                    ap_rputs("</i></tt></dd>\n", r);
                                }
                                else {
                                    break;
                                }
                                cmd++;
                            }
                            ap_rputs
                                ("<dt><strong>Current Configuration:</strong></dt>\n",
                                 r);
                            mod_info_module_cmds(r, modp->cmds, ap_conftree, 0,
                                                 0);
                        }
                        else {
                            ap_rputs
                                ("<dt><strong>Module Directives:</strong> <tt>none</tt></dt>",
                                 r);
                        }
                        more_info = find_more_info(r->server, modp->name);
                        if (more_info) {
                            ap_rputs
                                ("<dt><strong>Additional Information:</strong>\n</dt><dd>",
                                 r);
                            ap_rputs(more_info, r);
                            ap_rputs("</dd>", r);
                        }
                        ap_rputs("</dl><hr />\n", r);
                        if (r->args) {
                            break;
                        }
                    }
                }
                if (!modp && r->args && ap_cstr_casecmp(r->args, "server")) {
                    ap_rputs("<p><b>No such module</b></p>\n", r);
                }
            }
        }
        else {
            ap_rputs("<dl><dt>Server Module List</dt>", r);
            modules = get_sorted_modules(r->pool);
            for (i = 0; i < modules->nelts; i++) {
                modp = APR_ARRAY_IDX(modules, i, module *);
                ap_rputs("<dd>", r);
                ap_rputs(modp->name, r);
                ap_rputs("</dd>", r);
            }
            ap_rputs("</dl><hr />", r);
        }
        ap_rputs(ap_psignature("", r), r);
        ap_rputs("</body></html>\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 int check_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp,
                            server_rec *s)
    {
        if (ap_exists_config_define("DUMP_CONFIG")) {
            apr_file_open_stdout(&out, ptemp);
            mod_info_module_cmds(NULL, NULL, ap_conftree, 0, 0);
        }
    
        return DECLINED;
    }
    
    
    static void register_hooks(apr_pool_t * p)
    {
        ap_hook_handler(display_info, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_config(check_config, NULL, NULL, APR_HOOK_FIRST);
    }
    
    AP_DECLARE_MODULE(info) = {
        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
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_asis.mak��������������������������������������������������������0000664�0001751�0001751�00000023125�12701473373�020745� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_asis.dsp
    !IF "$(CFG)" == ""
    CFG=mod_asis - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_asis - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_asis - Win32 Release" && "$(CFG)" != "mod_asis - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_asis - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_asis.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_asis.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_asis.obj"
    	-@erase "$(INTDIR)\mod_asis.res"
    	-@erase "$(INTDIR)\mod_asis_src.idb"
    	-@erase "$(INTDIR)\mod_asis_src.pdb"
    	-@erase "$(OUTDIR)\mod_asis.exp"
    	-@erase "$(OUTDIR)\mod_asis.lib"
    	-@erase "$(OUTDIR)\mod_asis.pdb"
    	-@erase "$(OUTDIR)\mod_asis.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_asis_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_asis.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_asis.so" /d LONG_NAME="asis_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_asis.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_asis.pdb" /debug /out:"$(OUTDIR)\mod_asis.so" /implib:"$(OUTDIR)\mod_asis.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_asis.obj" \
    	"$(INTDIR)\mod_asis.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_asis.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_asis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_asis.so"
       if exist .\Release\mod_asis.so.manifest mt.exe -manifest .\Release\mod_asis.so.manifest -outputresource:.\Release\mod_asis.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_asis - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_asis.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_asis.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_asis.obj"
    	-@erase "$(INTDIR)\mod_asis.res"
    	-@erase "$(INTDIR)\mod_asis_src.idb"
    	-@erase "$(INTDIR)\mod_asis_src.pdb"
    	-@erase "$(OUTDIR)\mod_asis.exp"
    	-@erase "$(OUTDIR)\mod_asis.lib"
    	-@erase "$(OUTDIR)\mod_asis.pdb"
    	-@erase "$(OUTDIR)\mod_asis.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_asis_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_asis.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_asis.so" /d LONG_NAME="asis_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_asis.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_asis.pdb" /debug /out:"$(OUTDIR)\mod_asis.so" /implib:"$(OUTDIR)\mod_asis.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_asis.obj" \
    	"$(INTDIR)\mod_asis.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_asis.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_asis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_asis.so"
       if exist .\Debug\mod_asis.so.manifest mt.exe -manifest .\Debug\mod_asis.so.manifest -outputresource:.\Debug\mod_asis.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_asis.dep")
    !INCLUDE "mod_asis.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_asis.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_asis - Win32 Release" || "$(CFG)" == "mod_asis - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_asis - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_asis - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_asis - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_asis - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_asis - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_asis - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_asis - Win32 Release"
    
    
    "$(INTDIR)\mod_asis.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_asis.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_asis.so" /d LONG_NAME="asis_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_asis - Win32 Debug"
    
    
    "$(INTDIR)\mod_asis.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_asis.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_asis.so" /d LONG_NAME="asis_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_asis.c
    
    "$(INTDIR)\mod_asis.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_status.mak������������������������������������������������������0000664�0001751�0001751�00000023473�12701473373�021337� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_status.dsp
    !IF "$(CFG)" == ""
    CFG=mod_status - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_status - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_status - Win32 Release" && "$(CFG)" != "mod_status - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_status - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_status.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_status.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_status.obj"
    	-@erase "$(INTDIR)\mod_status.res"
    	-@erase "$(INTDIR)\mod_status_src.idb"
    	-@erase "$(INTDIR)\mod_status_src.pdb"
    	-@erase "$(OUTDIR)\mod_status.exp"
    	-@erase "$(OUTDIR)\mod_status.lib"
    	-@erase "$(OUTDIR)\mod_status.pdb"
    	-@erase "$(OUTDIR)\mod_status.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STATUS_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_status_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_status.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_status.so" /d LONG_NAME="status_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_status.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_status.pdb" /debug /out:"$(OUTDIR)\mod_status.so" /implib:"$(OUTDIR)\mod_status.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_status.obj" \
    	"$(INTDIR)\mod_status.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_status.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_status.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_status.so"
       if exist .\Release\mod_status.so.manifest mt.exe -manifest .\Release\mod_status.so.manifest -outputresource:.\Release\mod_status.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_status - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_status.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_status.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_status.obj"
    	-@erase "$(INTDIR)\mod_status.res"
    	-@erase "$(INTDIR)\mod_status_src.idb"
    	-@erase "$(INTDIR)\mod_status_src.pdb"
    	-@erase "$(OUTDIR)\mod_status.exp"
    	-@erase "$(OUTDIR)\mod_status.lib"
    	-@erase "$(OUTDIR)\mod_status.pdb"
    	-@erase "$(OUTDIR)\mod_status.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STATUS_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_status_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_status.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_status.so" /d LONG_NAME="status_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_status.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_status.pdb" /debug /out:"$(OUTDIR)\mod_status.so" /implib:"$(OUTDIR)\mod_status.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_status.obj" \
    	"$(INTDIR)\mod_status.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_status.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_status.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_status.so"
       if exist .\Debug\mod_status.so.manifest mt.exe -manifest .\Debug\mod_status.so.manifest -outputresource:.\Debug\mod_status.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_status.dep")
    !INCLUDE "mod_status.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_status.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_status - Win32 Release" || "$(CFG)" == "mod_status - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_status - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_status - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_status - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_status - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_status - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_status - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_status - Win32 Release"
    
    
    "$(INTDIR)\mod_status.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_status.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_status.so" /d LONG_NAME="status_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_status - Win32 Debug"
    
    
    "$(INTDIR)\mod_status.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_status.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_status.so" /d LONG_NAME="status_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_status.c
    
    "$(INTDIR)\mod_status.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_info.dep��������������������������������������������������������0000664�0001751�0001751�00000004506�12674411515�020742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_info.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_info.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mpm_common.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr-util\include\apu_version.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/NWGNUmakefile�������������������������������������������������������0000664�0001751�0001751�00000010061�11540562746�020772� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgid.c����������������������������������������������������������0000664�0001751�0001751�00000165275�14640775605�020412� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
     *
     * This modules uses a httpd core function (ap_add_common_vars) to add some new env vars, 
     * like REDIRECT_URL and REDIRECT_QUERY_STRING for custom error responses and DOCUMENT_ROOT.
     * 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
    
    #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 "ap_mpm.h"
    #include "mpm_common.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 */
    
    #if APR_HAVE_STRUCT_RLIMIT
    #if defined (RLIMIT_CPU) || defined (RLIMIT_NPROC) || defined (RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
    #define AP_CGID_USE_RLIMIT
    #endif
    #endif
    
    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 apr_pool_t *pcgi = NULL;
    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 struct sockaddr_un *server_addr;
    static apr_socklen_t server_addr_len;
    static pid_t parent_pid;
    static ap_unix_identity_t empty_ugid = { (uid_t)-1, (gid_t)-1, -1 };
    
    typedef struct { 
        apr_interval_time_t timeout;
    } cgid_dirconf;
    
    /* The APR other-child API doesn't tell us how the daemon exited
     * (SIGSEGV vs. exit(1)).  The other-child maintenance function
     * needs to decide whether to restart the daemon after a failure
     * based on whether or not it exited due to a fatal startup error
     * or something that happened at steady-state.  This exit status
     * is unlikely to collide with exit signals.
     */
    #define DAEMON_STARTUP_ERROR 254
    
    /* Read and discard the data in the brigade produced by a CGI script */
    static void discard_script_output(apr_bucket_brigade *bb);
    
    /* This doer will only ever be called when we are sure that we have
     * a valid ugid.
     */
    static ap_unix_identity_t *cgid_suexec_id_doer(const request_rec *r)
    {
        return (ap_unix_identity_t *)
                            ap_get_module_config(r->request_config, &cgid_module);
    }
    
    /* 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 "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
    
    #ifndef DEFAULT_CONNECT_STARTUP_DELAY
    #define DEFAULT_CONNECT_STARTUP_DELAY 60
    #endif
    
    typedef struct {
        const char *logname;
        long logbytes;
        int bufbytes;
    } cgid_server_conf;
    
    #ifdef AP_CGID_USE_RLIMIT
    typedef struct {
    #ifdef RLIMIT_CPU
        int    limit_cpu_set;
        struct rlimit limit_cpu;
    #endif
    #if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
        int    limit_mem_set;
        struct rlimit limit_mem;
    #endif
    #ifdef RLIMIT_NPROC
        int    limit_nproc_set;
        struct rlimit limit_nproc;
    #endif
    
    } cgid_rlimit_t;
    #endif
    
    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 env_count;
        ap_unix_identity_t ugid;
        apr_size_t filename_len;
        apr_size_t argv0_len;
        apr_size_t uri_len;
        apr_size_t args_len;
        int loglevel; /* to stuff in server_rec */
    
    #ifdef AP_CGID_USE_RLIMIT
        cgid_rlimit_t limits;
    #endif
    } cgid_req_t;
    
    #define cgi_server_conf cgid_server_conf
    #define cgi_module cgid_module
    
    #ifdef HAVE_CGID_FDPASSING
    /* Pull in CGI bucket implementation. */
    #define WANT_CGI_BUCKET
    #endif
    #include "cgi_common.h"
    
    /* 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 (!(*args) || 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, '+');
            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) {
                    if (status == DAEMON_STARTUP_ERROR) {
                        ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(01238)
                                     "cgid daemon failed to initialize");
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(01239)
                                     "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 */
    
                /* Remove the cgi socket, we must do it here in order to try and
                 * guarantee the same permissions as when the socket was created.
                 */
                if (unlink(sockname) < 0 && errno != ENOENT) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf, APLOGNO(01240)
                                 "Couldn't unlink unix domain socket %s",
                                 sockname);
                }
                break;
        }
    }
    #endif
    
    static apr_status_t close_unix_socket(void *thefd)
    {
        int fd = (int)((long)thefd);
    
        return close(fd);
    }
    
    /* Read from the socket dealing with incomplete messages and signals.
     * Returns 0 on success or errno on failure.  Stderr fd passed as
     * auxiliary data from other end is written to *errfd, or else stderr
     * fileno if not present. */
    static apr_status_t sock_readhdr(int fd, int *errfd, void *vbuf, size_t buf_size)
    {
        int rc;
    #ifndef HAVE_CGID_FDPASSING
        char *buf = vbuf;
        size_t bytes_read = 0;
    
        if (errfd) *errfd = 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);
    
       
    #else /* with FD passing */
        struct msghdr msg = {0};
        struct iovec vec = {vbuf, buf_size};
        struct cmsghdr *cmsg;
        union {  /* union to ensure alignment */
            struct cmsghdr cm;
            char buf[CMSG_SPACE(sizeof(int))];
        } u;
        
        msg.msg_iov = &vec;
        msg.msg_iovlen = 1;
    
        if (errfd) {
            msg.msg_control = u.buf;
            msg.msg_controllen = sizeof(u.buf);
            *errfd = 0;
        }
        
        /* use MSG_WAITALL to skip loop on truncated reads */
        do {
            rc = recvmsg(fd, &msg, MSG_WAITALL);
        } while (rc < 0 && errno == EINTR);
    
        if (rc == 0) {
            return ECONNRESET;
        }
        else if (rc < 0) {
            return errno;
        }
        else if (rc != buf_size) {
            /* MSG_WAITALL should ensure the recvmsg blocks until the
             * entire length is read, but let's be paranoid. */
            return APR_INCOMPLETE;
        }
    
        if (errfd
            && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL
            && cmsg->cmsg_len == CMSG_LEN(sizeof(*errfd))
            && cmsg->cmsg_level == SOL_SOCKET
            && cmsg->cmsg_type == SCM_RIGHTS) {
            *errfd = *((int *) CMSG_DATA(cmsg));
        }
    #endif
        
        return APR_SUCCESS;
    }
    
    /* As sock_readhdr but without auxiliary fd passing. */
    static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size)
    {
        return sock_readhdr(fd, NULL, vbuf, buf_size);
    }
    
    /* 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 sock_writev(int fd, int auxfd, request_rec *r, int count, ...)
    {
        va_list ap;
        int rc;
        struct iovec *vec;
        int i;
    
        vec = (struct iovec *)apr_palloc(r->pool, count * sizeof(struct iovec));
        va_start(ap, count);
        for (i = 0; i < count; i++) {
            vec[i].iov_base = va_arg(ap, caddr_t);
            vec[i].iov_len  = va_arg(ap, apr_size_t);
        }
        va_end(ap);
    
    #ifndef HAVE_CGID_FDPASSING
        do {
            rc = writev(fd, vec, count);
        } while (rc < 0 && errno == EINTR);
    #else
        {
            struct msghdr msg = { 0 };
            struct cmsghdr *cmsg;
            union { /* union for alignment */
                char buf[CMSG_SPACE(sizeof(int))];
                struct cmsghdr align;
            } u;
    
            msg.msg_iov = vec;
            msg.msg_iovlen = count;
    
            if (auxfd) {
                msg.msg_control = u.buf;
                msg.msg_controllen = sizeof(u.buf);
    
                cmsg = CMSG_FIRSTHDR(&msg);
                cmsg->cmsg_level = SOL_SOCKET;
                cmsg->cmsg_type = SCM_RIGHTS;
                cmsg->cmsg_len = CMSG_LEN(sizeof(int));
                *((int *) CMSG_DATA(cmsg)) = auxfd;
            }
    
            do {
                rc = sendmsg(fd, &msg, 0);
            } while (rc < 0 && errno == EINTR);
        }
    #endif
        
        if (rc < 0) {
            return errno;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env,
                                int *errfd, cgid_req_t *req)
    {
        int i;
        char **environ;
        core_request_config *temp_core;
        void **rconf;
        apr_status_t stat;
    
        r->server = apr_pcalloc(r->pool, sizeof(server_rec));
    
        /* read the request header */
        stat = sock_readhdr(fd, errfd, req, sizeof(*req));
        if (stat != APR_SUCCESS) {
            return stat;
        }
        r->server->log.level = req->loglevel;
        if (req->req_type == GETPID_REQ) {
            /* no more data sent for this request */
            return APR_SUCCESS;
        }
    
        /* Sanity check the structure received. */
        if (req->env_count < 0 || req->uri_len == 0
            || req->filename_len > APR_PATH_MAX || req->filename_len == 0
            || req->argv0_len > APR_PATH_MAX || req->argv0_len == 0
            || req->loglevel > APLOG_TRACE8) {
            return APR_EINVAL;
        }
        
        /* handle module indexes and such */
        rconf = (void **)ap_create_request_config(r->pool);
    
        temp_core = (core_request_config *)apr_palloc(r->pool, sizeof(core_module));
        rconf[AP_CORE_MODULE_INDEX] = (void *)temp_core;
        r->request_config = (ap_conf_vector_t *)rconf;
        ap_set_module_config(r->request_config, &cgid_module, (void *)&req->ugid);
    
        /* 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;
    
    #ifdef AP_CGID_USE_RLIMIT
        if ((stat = sock_read(fd, &(req->limits), sizeof(cgid_rlimit_t))) != APR_SUCCESS)
             return stat;
    #endif
    
        return APR_SUCCESS;
    }
    
    static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r,
                                 const char *argv0, char **env, int req_type)
    {
        int i;
        cgid_req_t req = {0};
        apr_status_t stat;
        ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r);
        core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config);
        int errfd;
    
    
        if (ugid == NULL) {
            req.ugid = empty_ugid;
        } else {
            memcpy(&req.ugid, ugid, sizeof(ap_unix_identity_t));
        }
    
        req.req_type = req_type;
        req.ppid = parent_pid;
        req.conn_id = r->connection->id;
        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;
        req.loglevel = r->server->log.level;
    
        if (errpipe)
            apr_os_file_get(&errfd, errpipe);
        else
            errfd = 0;
        
        /* Write the request header */
        if (req.args_len) {
            stat = sock_writev(fd, errfd, r, 5,
                               &req, sizeof(req),
                               r->filename, req.filename_len,
                               argv0, req.argv0_len,
                               r->uri, req.uri_len,
                               r->args, req.args_len);
        } else {
            stat = sock_writev(fd, errfd, r, 4,
                               &req, sizeof(req),
                               r->filename, req.filename_len,
                               argv0, req.argv0_len,
                               r->uri, req.uri_len);
        }
    
        if (stat != 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_writev(fd, 0, r, 2, &curlen, sizeof(curlen),
                                    env[i], curlen)) != APR_SUCCESS) {
                return stat;
            }
        }
    #if defined(RLIMIT_CPU) && defined(AP_CGID_USE_RLIMIT)
        if (core_conf->limit_cpu) {
            req.limits.limit_cpu = *(core_conf->limit_cpu);
            req.limits.limit_cpu_set = 1;
        }
        else {
            req.limits.limit_cpu_set = 0;
        }
    #endif
    
    #if defined(AP_CGID_USE_RLIMIT) && (defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS))
        if (core_conf->limit_mem) {
            req.limits.limit_mem = *(core_conf->limit_mem);
            req.limits.limit_mem_set = 1;
        }
        else {
            req.limits.limit_mem_set = 0;
        }
    
    #endif
    
    #if defined(RLIMIT_NPROC) && defined(AP_CGID_USE_RLIMIT)
        if (core_conf->limit_nproc) {
            req.limits.limit_nproc = *(core_conf->limit_nproc);
            req.limits.limit_nproc_set = 1;
        }
        else {
            req.limits.limit_nproc_set = 0;
        }
    #endif
    
    #ifdef AP_CGID_USE_RLIMIT
        if ( (stat = sock_write(fd, &(req.limits), sizeof(cgid_rlimit_t))) != APR_SUCCESS)
            return stat;
    #endif
    
        return APR_SUCCESS;
    }
    
    static void daemon_signal_handler(int sig)
    {
        if (sig == SIGHUP) {
            ++daemon_should_exit;
        }
    }
    
    /* Callback executed in the forked child process if exec of the CGI
     * script fails.  For the fd-passing case, output to stderr goes to
     * the client (request handling thread) and is logged via
     * ap_log_rerror there.  For the non-fd-passing case, the "fake"
     * request_rec passed via userdata is used to log. */
    static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err,
                                 const char *description)
    {
        void *vr;
    
        apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool);
        if (vr) {
            request_rec *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, APLOGNO(01241) "%s", description);
        }
        else {
            const char *logstr;
            
            logstr = apr_psprintf(pool, APLOGNO(01241) "error spawning CGI child: %s (%pm)\n",
                                  description, &err);
            fputs(logstr, stderr);
            fflush(stderr);
        }
    }
    
    static int cgid_server(void *data)
    {
        int sd, sd2, rc;
        mode_t omask;
        apr_pool_t *ptrans;
        server_rec *main_server = data;
        apr_hash_t *script_hash = apr_hash_make(pcgi);
        apr_status_t rv;
    
        apr_pool_create(&ptrans, pcgi);
        apr_pool_tag(ptrans, "cgid_ptrans");
    
        apr_signal(SIGCHLD, SIG_IGN);
        apr_signal(SIGHUP, daemon_signal_handler);
    
        /* Close our copy of the listening sockets */
        ap_close_listeners();
    
        /* cgid should use its own suexec doer */
        ap_hook_get_suexec_identity(cgid_suexec_id_doer, NULL, NULL,
                                    APR_HOOK_REALLY_FIRST);
        apr_hook_sort_all();
    
        if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, APLOGNO(01242)
                         "Couldn't create unix domain socket");
            return errno;
        }
    
        apr_pool_cleanup_register(pcgi, (void *)((long)sd),
                                  close_unix_socket, close_unix_socket);
    
        omask = umask(0077); /* so that only Apache can use socket */
        rc = bind(sd, (struct sockaddr *)server_addr, server_addr_len);
        umask(omask); /* can't fail, so can't clobber errno */
        if (rc < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, APLOGNO(01243)
                         "Couldn't bind unix domain socket %s",
                         sockname);
            return errno;
        }
    
        /* Not all flavors of unix use the current umask for AF_UNIX perms */
        rv = apr_file_perms_set(sockname, APR_FPROT_UREAD|APR_FPROT_UWRITE|APR_FPROT_UEXECUTE);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, main_server, APLOGNO(01244)
                         "Couldn't set permissions on unix domain socket %s",
                         sockname);
            return rv;
        }
    
        if (listen(sd, DEFAULT_CGID_LISTENBACKLOG) < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, APLOGNO(01245)
                         "Couldn't listen on unix domain socket");
            return errno;
        }
    
        if (!geteuid()) {
            if (chown(sockname, ap_unixd_config.user_id, -1) < 0) {
                ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, APLOGNO(01246)
                             "Couldn't change owner of unix domain socket %s",
                             sockname);
                return errno;
            }
        }
    
        /* if running as root, switch to configured user/group */
        if ((rc = ap_run_drop_privileges(pcgi, ap_server_conf)) != 0) {
            return rc;
        }
    
        while (!daemon_should_exit) {
            int errfileno;
            char *argv0 = NULL;
            char **env = NULL;
            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;
            void *key;
            apr_socklen_t len;
            struct sockaddr_un unix_addr;
    
            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, APLOGNO(01247)
                                 "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, &errfileno, &cgid_req);
            if (stat != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, stat,
                             main_server, APLOGNO(01248)
                             "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, APLOGNO(01249)
                             "CGI request received from wrong server instance; "
                             "see ScriptSock directive");
                close(sd2);
                continue;
            }
    
            if (cgid_req.req_type == GETPID_REQ) {
                pid_t pid;
                apr_status_t rv;
    
                pid = (pid_t)((long)apr_hash_get(script_hash, &cgid_req.conn_id, sizeof(cgid_req.conn_id)));
                rv = sock_write(sd2, &pid, sizeof(pid));
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv,
                                 main_server, APLOGNO(01250)
                                 "Error writing pid %" APR_PID_T_FMT " to handler", pid);
                }
                close(sd2);
                continue;
            }
    
            if (errfileno == 0) {
                errfileno = STDERR_FILENO;
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server,
                              "using passed fd %d as stderr", errfileno);
                /* Limit the received fd lifetime to pool lifetime */
                apr_pool_cleanup_register(ptrans, (void *)((long)errfileno),
                                          close_unix_socket, close_unix_socket);
            }
            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) ||
    #ifdef AP_CGID_USE_RLIMIT
    #ifdef RLIMIT_CPU
            (  (cgid_req.limits.limit_cpu_set) && ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_CPU,
                                          &cgid_req.limits.limit_cpu)) != APR_SUCCESS)) ||
    #endif
    #if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
            ( (cgid_req.limits.limit_mem_set) && ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_MEM,
                                          &cgid_req.limits.limit_mem)) != APR_SUCCESS)) ||
    #endif
    #ifdef RLIMIT_NPROC
            ( (cgid_req.limits.limit_nproc_set) && ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC,
                                          &cgid_req.limits.limit_nproc)) != APR_SUCCESS)) ||
    #endif
    #endif
    
                ((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, APLOGNO(01251)
                             "couldn't set child process attributes: %s", r->filename);
    
                procnew->pid = 0; /* no process to clean up */
                close(sd2);
            }
            else {
                if (errfileno == STDERR_FILENO) {
                    /* Used by cgid_child_errfn without fd-passing. */
                    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);
    
                if (memcmp(&empty_ugid, &cgid_req.ugid, sizeof(empty_ugid))) {
                    /* We have a valid identity, and can be sure that
                     * cgid_suexec_id_doer will return a valid ugid
                     */
                    rc = ap_os_create_privileged_process(r, procnew, argv0, argv,
                                                         (const char * const *)env,
                                                         procattr, ptrans);
                } else {
                    rc = apr_proc_create(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, APLOGNO(01252)
                                 "couldn't create child process: %d: %s", rc,
                                 apr_filepath_name_get(r->filename));
    
                    procnew->pid = 0; /* no process to clean up */
                }
            }
    
            /* If the script process was created, remember the pid for
             * later cleanup.  If the script process wasn't created, clear
             * out any prior pid with the same key.
             *
             * 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.
             */
    
            if (apr_hash_get(script_hash, &cgid_req.conn_id, sizeof(cgid_req.conn_id))) {
                key = &cgid_req.conn_id;
            }
            else {
                key = apr_pmemdup(pcgi, &cgid_req.conn_id, sizeof(cgid_req.conn_id));
            }
            apr_hash_set(script_hash, key, sizeof(cgid_req.conn_id),
                         (void *)((long)procnew->pid));
        }
        return -1; /* should be <= 0 to distinguish from startup errors */
    }
    
    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, APLOGNO(01253)
                         "mod_cgid: Couldn't spawn cgid daemon process");
            return DECLINED;
        }
        else if (daemon_pid == 0) {
            if (pcgi == NULL) {
                apr_pool_create(&pcgi, p);
                apr_pool_tag(pcgi, "cgid_pcgi");
            }
            exit(cgid_server(main_server) > 0 ? DAEMON_STARTUP_ERROR : -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 = ap_append_pid(pconf, 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;
        const char *userdata_key = "cgid_init";
        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) {
            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);
            return ret;
        }
        else {
            procnew = data;
        }
    
        if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG) {
            char *tmp_sockname;
    
            parent_pid = getpid();
            tmp_sockname = ap_runtime_dir_relative(p, sockname);
            if (strlen(tmp_sockname) > sizeof(server_addr->sun_path) - 1) {
                tmp_sockname[sizeof(server_addr->sun_path)] = '\0';
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, APLOGNO(01254)
                            "The length of the ScriptSock path exceeds maximum, "
                            "truncating to %s", tmp_sockname);
            }
            sockname = tmp_sockname;
    
            server_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) + strlen(sockname);
            server_addr = (struct sockaddr_un *)apr_palloc(p, server_addr_len + 1);
            server_addr->sun_family = AF_UNIX;
            strcpy(server_addr->sun_path, sockname);
    
            ret = cgid_start(p, main_server, procnew);
            if (ret != OK ) {
                return ret;
            }
        }
        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 void *create_cgid_dirconf(apr_pool_t *p, char *dummy)
    {
        cgid_dirconf *c = (cgid_dirconf *) apr_pcalloc(p, sizeof(cgid_dirconf));
        return c;
    }
    
    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;
        }
    
        /* Make sure the pid is appended to the sockname */
        sockname = ap_append_pid(cmd->pool, arg, ".");
        sockname = ap_runtime_dir_relative(cmd->pool, sockname);
    
        if (!sockname) {
            return apr_pstrcat(cmd->pool, "Invalid ScriptSock path",
                               arg, NULL);
        }
    
        return NULL;
    }
    static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg)
    {
        cgid_dirconf *dc = dummy;
    
        if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { 
            return "CGIDScriptTimeout has wrong format";
        }
     
        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."),
        AP_INIT_TAKE1("CGIDScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF,
                      "The amount of time to wait between successful reads from "
                      "the CGI script, in seconds."),
                      
        {NULL}
    };
    
    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_full(f, buf, len, NULL);
            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 int connect_to_daemon(int *sdptr, request_rec *r,
                                 cgid_server_conf *conf)
    {
        int sd;
        int connect_tries;
        int connect_errno;
        apr_interval_time_t sliding_timer;
    
        connect_tries = 0;
        sliding_timer = 100000; /* 100 milliseconds */
        while (1) {
            connect_errno = 0;
            ++connect_tries;
            if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
                return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno,
                                       APLOGNO(01255), "unable to create socket to cgi daemon");
            }
            if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) {
                /* Save errno for later */
                connect_errno = errno;
                /* ECONNREFUSED means the listen queue is full; ENOENT means that
                 * the cgid server either hasn't started up yet, or we're pointing
                 * at the wrong socket file */
                if ((errno == ECONNREFUSED || errno == ENOENT) && 
                     connect_tries < DEFAULT_CONNECT_ATTEMPTS) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, errno, r, APLOGNO(01256)
                                  "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, APLOGNO(01257),
                                           "unable to connect to cgi daemon after multiple tries");
                }
            }
            else {
                apr_pool_cleanup_register(r->pool, (void *)((long)sd),
                                          close_unix_socket, apr_pool_cleanup_null);
                break; /* we got connected! */
            }
    
            /* If we didn't find the socket but the server was not recently restarted,
             * chances are there's something wrong with the cgid daemon
             */
            if (connect_errno == ENOENT &&
                apr_time_sec(apr_time_now() - ap_scoreboard_image->global->restart_time) > 
                    DEFAULT_CONNECT_STARTUP_DELAY) {
                return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno,
                                       APLOGNO(02833),
                                       apr_pstrcat(r->pool,
                                                   "ScriptSock ", sockname, " does not exist", NULL));
            }
    
            /* gotta try again, but make sure the cgid daemon is still around */
            if (connect_errno != ENOENT && kill(daemon_pid, 0) != 0) {
                return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258),
                                       "cgid daemon is gone; is Apache terminating?");
            }
        }
        *sdptr = sd;
        return OK;
    }
    
    /****************************************************************
     *
     * Actual cgid handling...
     */
    
    struct cleanup_script_info {
        request_rec *r;
        cgid_server_conf *conf;
        pid_t pid;
    };
    
    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, APLOGNO(01259)
                      "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, APLOGNO(01260)
                      "CGI process %" APR_PID_T_FMT " didn't exit, sending SIGKILL again",
                      pid);
        kill(pid, SIGKILL);
    
        return APR_EGENERAL;
    }
    
    static apr_status_t get_cgi_pid(request_rec *r,  cgid_server_conf *conf, pid_t *pid) { 
        cgid_req_t req = {0};
        apr_status_t stat;
        int rc, sd;
    
        rc = connect_to_daemon(&sd, r, conf);
        if (rc != OK) {
            return APR_EGENERAL;
        }
    
        req.req_type = GETPID_REQ;
        req.ppid = parent_pid;
        req.conn_id = 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;
        }
    
        /* Don't accept zero as a pid here, calling kill(0, SIGTERM) etc
         * later is unpleasant. */
        if (*pid == 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01261)
                          "daemon couldn't find CGI process for connection %lu",
                          r->connection->id);
            return APR_EGENERAL;
        }
    
        return APR_SUCCESS;
    }
    
    
    static apr_status_t cleanup_script(void *vptr)
    {
        struct cleanup_script_info *info = vptr;
        return cleanup_nonchild_process(info->r, info->pid);
    }
    
    static int cgid_handler(request_rec *r)
    {
        conn_rec *c = r->connection;
        int retval, nph;
        char *argv0, *dbuf;
        apr_size_t dbufsize;
        apr_bucket_brigade *bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        apr_bucket *b;
        cgid_server_conf *conf;
        int is_included;
        int sd;
        char **env;
        apr_file_t *tempsock, *script_err, *errpipe_out;
        struct cleanup_script_info *info;
        apr_status_t rv;
        cgid_dirconf *dc;
        apr_interval_time_t timeout;
    
        if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) {
            return DECLINED;
        }
    
        conf = ap_get_module_config(r->server->module_config, &cgid_module);
        dc = ap_get_module_config(r->per_dir_config, &cgid_module);
    
        timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout;
        is_included = !strcmp(r->protocol, "INCLUDED");
    
        if ((argv0 = strrchr(r->filename, '/')) != NULL) {
            argv0++;
        }
        else {
            argv0 = r->filename;
        }
    
        nph = !(strncmp(argv0, "nph-", 4));
    
        argv0 = r->filename;
    
        if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r)) {
            return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01262),
                    "Options ExecCGI is off in this directory");
        }
    
        if (nph && is_included) {
            return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01263),
                    "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 == APR_NOFILE) {
            return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01264),
                    "script not found or unable to stat");
        }
    #endif
        if (r->finfo.filetype == APR_DIR) {
            return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01265),
                    "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, APLOGNO(01266),
                                   "AcceptPathInfo off disallows user's path");
        }
        /*
        if (!ap_suexec_enabled) {
            if (!ap_can_exec(&r->finfo))
                return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01267)
                                       "file permissions deny server execution");
        }
        */
    
    #ifdef HAVE_CGID_FDPASSING
        rv = apr_file_pipe_create(&script_err, &errpipe_out, r->pool);
        if (rv) {
            return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10176),
                                   "could not create pipe for stderr");
        }
    #else
        script_err = NULL;
        errpipe_out = NULL;
    #endif
        
        /*
         * httpd core function used to add common environment variables like
         * DOCUMENT_ROOT. 
         */
        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, errpipe_out, r, argv0, env, CGI_REQ);
        if (rv != APR_SUCCESS) {
            return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10245),
                                   "could not send request to cgi daemon");
        }
    
        /* The write-end of the pipe is only used by the server, so close
         * it here. */
        if (errpipe_out) apr_file_close(errpipe_out);
        
        info = apr_palloc(r->pool, sizeof(struct cleanup_script_info));
        info->conf = conf;
        info->r = r;
        rv = get_cgi_pid(r, conf, &(info->pid));
    
        if (rv == APR_SUCCESS) {
            apr_pool_cleanup_register(r->pool, info,
                                      cleanup_script, apr_pool_cleanup_null);
        }
        else { 
            return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10246),
                                   "failed reading PID from cgi daemon");
        }
    
        /* 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_file_pipe_timeout_set(tempsock, timeout);
        apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket);
    
        /* Buffer for logging script stdout. */
        if (conf->logname) {
            dbufsize = conf->bufbytes;
            dbuf = apr_palloc(r->pool, dbufsize + 1);
        }
        else {
            dbuf = NULL;
            dbufsize = 0;
        }
    
        /* Read the request body. */
        rv = cgi_handle_request(r, tempsock, bb, dbuf, dbufsize);
        if (rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01270)
                          "Error reading request entity data");
            return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
        }
    
        /* 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);
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
    #ifdef HAVE_CGID_FDPASSING
        b = cgi_bucket_create(r, dc->timeout, tempsock, script_err, c->bucket_alloc);
        if (b == NULL)
            return HTTP_INTERNAL_SERVER_ERROR; /* should call log_scripterror() w/ _UNAVAILABLE? */
    #else
        b = apr_bucket_pipe_create(tempsock, c->bucket_alloc);
    #endif
        APR_BRIGADE_INSERT_TAIL(bb, b);
        b = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
    
        return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err);
    }
    
    /* Handling include= for mod_include. */
    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_ex(rr, CGI_MAGIC_TYPE, 1);
    
        /* 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, const 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);
        cgid_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgid_module);
    
        struct cleanup_script_info *info;
        apr_status_t rv;
    
        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, NULL, r, command, env, SSI_REQ);
    
        info = apr_palloc(r->pool, sizeof(struct cleanup_script_info));
        info->conf = conf;
        info->r = r;
        rv = get_cgi_pid(r, conf, &(info->pid));
        if (APR_SUCCESS == rv) {             
            /* 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);
        }
        else { 
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "error determining cgi PID (for SSI)");
        }
    
        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);
        if (dc->timeout > 0) {
            apr_file_pipe_timeout_set(tempsock, dc->timeout);
        }
        else {
            apr_file_pipe_timeout_set(tempsock, r->server->timeout);
        }
    
        apr_pool_cleanup_kill(r->pool, (void *)((long)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 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);
        ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(cgid) = {
        STANDARD20_MODULE_STUFF,
        create_cgid_dirconf, /* 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 */
    };
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_suexec.c��������������������������������������������������������0000664�0001751�0001751�00000010472�13240674050�020747� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_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_CONTEXT);
    
        if (err != NULL) {
            return err;
        }
    
        if (!ap_unixd_config.suexec_enabled) {
            return apr_pstrcat(cmd->pool, "SuexecUserGroup configured, but "
                               "suEXEC is disabled: ",
                               ap_unixd_config.suexec_disabled_reason, NULL);
        }
    
        cfg->ugid.uid = ap_uname2id(uid);
        cfg->ugid.gid = ap_gname2id(gid);
        cfg->ugid.userdir = 0;
        cfg->active = 1;
    
        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) && ap_unixd_config.suexec_enabled) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01232)
                         "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);
    }
    
    AP_DECLARE_MODULE(suexec) =
    {
        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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_info.mak��������������������������������������������������������0000664�0001751�0001751�00000023125�12701473373�020741� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_info.dsp
    !IF "$(CFG)" == ""
    CFG=mod_info - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_info - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_info - Win32 Release" && "$(CFG)" != "mod_info - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_info - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_info.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_info.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_info.obj"
    	-@erase "$(INTDIR)\mod_info.res"
    	-@erase "$(INTDIR)\mod_info_src.idb"
    	-@erase "$(INTDIR)\mod_info_src.pdb"
    	-@erase "$(OUTDIR)\mod_info.exp"
    	-@erase "$(OUTDIR)\mod_info.lib"
    	-@erase "$(OUTDIR)\mod_info.pdb"
    	-@erase "$(OUTDIR)\mod_info.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_info_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_info.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_info.so" /d LONG_NAME="info_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_info.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_info.pdb" /debug /out:"$(OUTDIR)\mod_info.so" /implib:"$(OUTDIR)\mod_info.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_info.obj" \
    	"$(INTDIR)\mod_info.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_info.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_info.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_info.so"
       if exist .\Release\mod_info.so.manifest mt.exe -manifest .\Release\mod_info.so.manifest -outputresource:.\Release\mod_info.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_info - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_info.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_info.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_info.obj"
    	-@erase "$(INTDIR)\mod_info.res"
    	-@erase "$(INTDIR)\mod_info_src.idb"
    	-@erase "$(INTDIR)\mod_info_src.pdb"
    	-@erase "$(OUTDIR)\mod_info.exp"
    	-@erase "$(OUTDIR)\mod_info.lib"
    	-@erase "$(OUTDIR)\mod_info.pdb"
    	-@erase "$(OUTDIR)\mod_info.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_info_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_info.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_info.so" /d LONG_NAME="info_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_info.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_info.pdb" /debug /out:"$(OUTDIR)\mod_info.so" /implib:"$(OUTDIR)\mod_info.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_info.obj" \
    	"$(INTDIR)\mod_info.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_info.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_info.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_info.so"
       if exist .\Debug\mod_info.so.manifest mt.exe -manifest .\Debug\mod_info.so.manifest -outputresource:.\Debug\mod_info.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_info.dep")
    !INCLUDE "mod_info.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_info.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_info - Win32 Release" || "$(CFG)" == "mod_info - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_info - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_info - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_info - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_info - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\generators"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\generators"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_info - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ELSEIF  "$(CFG)" == "mod_info - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\generators"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\generators"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_info - Win32 Release"
    
    
    "$(INTDIR)\mod_info.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_info.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_info.so" /d LONG_NAME="info_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_info - Win32 Debug"
    
    
    "$(INTDIR)\mod_info.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_info.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_info.so" /d LONG_NAME="info_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_info.c
    
    "$(INTDIR)\mod_info.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgi.dep���������������������������������������������������������0000664�0001751�0001751�00000004323�12674411515�020546� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_cgi.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_cgi.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\mod_include.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_cgi.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgi.h�����������������������������������������������������������0000664�0001751�0001751�00000004700�11637105701�020217� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mod_cgi.h
     * @brief CGI Script Execution Extension Module for Apache
     *
     * @defgroup MOD_CGI mod_cgi
     * @ingroup APACHE_MODS
     * @{
     */
    
    #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 e_info pass e_info.cmd_type (Set to APR_SHELLCMD or APR_PROGRAM on entry)
                          and e_info.detached (Should the child start in detached state?)
     * @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 */
    /** @} */
    
    ����������������������������������������������������������������httpd-2.4.64/modules/generators/NWGNUstatus���������������������������������������������������������0000664�0001751�0001751�00000010135�11540546347�020541� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_asis.dsp��������������������������������������������������������0000664�0001751�0001751�00000010467�10551346420�020761� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_asis.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_asis.so" /d LONG_NAME="asis_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_asis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_asis.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_asis.so" /d LONG_NAME="asis_module for Apache"
    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 /out:".\Debug\mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_asis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_status.h��������������������������������������������������������0000664�0001751�0001751�00000004611�10455005461�021000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mod_status.h
     * @brief Status Report Extension Module to Apache
     *
     * @defgroup MOD_STATUS mod_status
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #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
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_autoindex.exp���������������������������������������������������0000664�0001751�0001751�00000000021�10150161574�022011� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������autoindex_module
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_status.exp������������������������������������������������������0000664�0001751�0001751�00000000016�10150161574�021340� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������status_module
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_status.dsp������������������������������������������������������0000664�0001751�0001751�00000010737�10551346420�021345� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_status.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_status.so" /d LONG_NAME="status_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_status.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATUS_DECLARE_EXPORT" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_status.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_status.so" /d LONG_NAME="status_module for Apache"
    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 /out:".\Debug\mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_status.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������httpd-2.4.64/modules/generators/mod_asis.exp��������������������������������������������������������0000664�0001751�0001751�00000000014�10150161574�020752� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������asis_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgid.exp��������������������������������������������������������0000664�0001751�0001751�00000000014�10150161574�020721� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cgid_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_cgi.dsp���������������������������������������������������������0000664�0001751�0001751�00000010523�10551346420�020555� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_cgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cgi.so" /d LONG_NAME="cgi_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_cgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_cgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cgi.so" /d LONG_NAME="cgi_module for Apache"
    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 /out:".\Debug\mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_cgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_info.exp��������������������������������������������������������0000664�0001751�0001751�00000000014�10150161574�020746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������info_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/.indent.pro���������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�020531� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/NWGNUinfo�����������������������������������������������������������0000664�0001751�0001751�00000010121�11540546347�020144� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/generators/mod_autoindex.dsp���������������������������������������������������0000664�0001751�0001751�00000010715�10551346420�022016� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_autoindex.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_autoindex.so" /d LONG_NAME="autoindex_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_autoindex.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_autoindex.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_autoindex.so" /d LONG_NAME="autoindex_module for Apache"
    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 /out:".\Debug\mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_autoindex.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������httpd-2.4.64/modules/session/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015767� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session.h����������������������������������������������������������0000664�0001751�0001751�00000015160�13523247020�020451� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_SESSION_H
    #define MOD_SESSION_H
    
    /* Create a set of SESSION_DECLARE(type), SESSION_DECLARE_NONSTD(type) and
     * SESSION_DECLARE_DATA with appropriate export and import tags for the platform
     */
    #if !defined(WIN32)
    #define SESSION_DECLARE(type)        type
    #define SESSION_DECLARE_NONSTD(type) type
    #define SESSION_DECLARE_DATA
    #elif defined(SESSION_DECLARE_STATIC)
    #define SESSION_DECLARE(type)        type __stdcall
    #define SESSION_DECLARE_NONSTD(type) type
    #define SESSION_DECLARE_DATA
    #elif defined(SESSION_DECLARE_EXPORT)
    #define SESSION_DECLARE(type)        __declspec(dllexport) type __stdcall
    #define SESSION_DECLARE_NONSTD(type) __declspec(dllexport) type
    #define SESSION_DECLARE_DATA         __declspec(dllexport)
    #else
    #define SESSION_DECLARE(type)        __declspec(dllimport) type __stdcall
    #define SESSION_DECLARE_NONSTD(type) __declspec(dllimport) type
    #define SESSION_DECLARE_DATA         __declspec(dllimport)
    #endif
    
    /**
     * @file  mod_session.h
     * @brief Session Module for Apache
     *
     * @defgroup MOD_SESSION mod_session
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #include "apr_hooks.h"
    #include "apr_optional.h"
    #include "apr_tables.h"
    #include "apr_uuid.h"
    #include "apr_pools.h"
    #include "apr_time.h"
    
    #include "httpd.h"
    #include "http_config.h"
    #include "ap_config.h"
    
    #define MOD_SESSION_NOTES_KEY "mod_session_key"
    
    /**
     * Define the name of a username stored in the session, so that modules interested
     * in the username can find it in a standard place.
     */
    #define MOD_SESSION_USER "user"
    
    /**
     * Define the name of a password stored in the session, so that modules interested
     * in the password can find it in a standard place.
     */
    #define MOD_SESSION_PW "pw"
    
    /**
     * A session structure.
     *
     * At the core of the session is a set of name value pairs making up the
     * session.
     *
     * The session might be uniquely identified by an anonymous uuid, or
     * a remote_user value, or both.
     */
    typedef struct {
        apr_pool_t *pool;             /* pool to be used for this session */
        apr_uuid_t *uuid;             /* anonymous uuid of this particular session */
        const char *remote_user;      /* user who owns this particular session */
        apr_table_t *entries;         /* key value pairs */
        const char *encoded;          /* the encoded version of the key value pairs */
        apr_time_t expiry;            /* if > 0, the time of expiry of this session */
        long maxage;                  /* if > 0, the maxage of the session, from
                                       * which expiry is calculated */
        int dirty;                    /* dirty flag */
        int cached;                   /* true if this session was loaded from a
                                       * cache of some kind */
        int written;                  /* true if this session has already been
                                       * written */
    } session_rec;
    
    /**
     * Structure to carry the per-dir session config.
     */
    typedef struct {
        int enabled;                  /* whether the session has been enabled for
                                       * this directory */
        int enabled_set;
        long maxage;                  /* seconds until session expiry */
        int maxage_set;
        const char *header;           /* header to inject session */
        int header_set;
        int env;                      /* whether the session has been enabled for
                                       * this directory */
        int env_set;
        apr_array_header_t *includes; /* URL prefixes to be included. All
                                       * URLs included if empty */
        apr_array_header_t *excludes; /* URL prefixes to be excluded. No
                                       * URLs excluded if empty */
        apr_time_t expiry_update_time; /* seconds the session expiry may change and
                                        * not have to be rewritten */
        int expiry_update_set;
    } session_dir_conf;
    
    /**
     * Hook to load the session.
     *
     * If the session doesn't exist, a blank one will be created.
     *
     * @param r The request
     * @param z A pointer to where the session will be written.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_load,
            (request_rec * r, session_rec ** z))
    
    /**
     * Hook to save the session.
     *
     * In most implementations the session is only saved if the dirty flag is
     * true. This prevents the session being saved unnecessarily.
     *
     * @param r The request
     * @param z A pointer to where the session will be written.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_save,
            (request_rec * r, session_rec * z))
    
    /**
     * Hook to encode the session.
     *
     * In the default implementation, the key value pairs are encoded using
     * key value pairs separated by equals, in turn separated by ampersand,
     * like a web form.
     *
     * @param r The request
     * @param z A pointer to where the session will be written.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_encode,
            (request_rec * r, session_rec * z))
    
    /**
     * Hook to decode the session.
     *
     * In the default implementation, the key value pairs are encoded using
     * key value pairs separated by equals, in turn separated by ampersand,
     * like a web form.
     *
     * @param r The request
     * @param z A pointer to where the session will be written.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, SESSION, apr_status_t, session_decode,
            (request_rec * r, session_rec * z))
    
    APR_DECLARE_OPTIONAL_FN(
            apr_status_t,
            ap_session_get,
            (request_rec * r, session_rec * z, const char *key, const char **value));
    APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_session_set,
            (request_rec * r, session_rec * z, const char *key, const char *value));
    APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_session_load,
            (request_rec *, session_rec **));
    APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_session_save,
            (request_rec *, session_rec *));
    
    /**
     * The name of the module.
     */
    extern module AP_MODULE_DECLARE_DATA session_module;
    
    #endif /* MOD_SESSION_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_crypto.c���������������������������������������������������0000664�0001751�0001751�00000064106�14021717461�022055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_session.h"
    #include "apu_version.h"
    #include "apr_base64.h"                /* for apr_base64_decode et al */
    #include "apr_lib.h"
    #include "apr_md5.h"
    #include "apr_strings.h"
    #include "http_log.h"
    #include "http_core.h"
    
    #if APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION < 4
    
    #error session_crypto_module requires APU v1.4.0 or later
    
    #elif APU_HAVE_CRYPTO == 0
    
    #error Crypto support must be enabled in APR
    
    #else
    
    #include "apr_crypto.h"                /* for apr_*_crypt et al */
    
    #define CRYPTO_KEY "session_crypto_context"
    
    module AP_MODULE_DECLARE_DATA session_crypto_module;
    
    /**
     * Structure to carry the per-dir session config.
     */
    typedef struct {
        apr_array_header_t *passphrases;
        int passphrases_set;
        const char *cipher;
        int cipher_set;
    } session_crypto_dir_conf;
    
    /**
     * Structure to carry the server wide session config.
     */
    typedef struct {
        const char *library;
        const char *params;
        int library_set;
    } session_crypto_conf;
    
    /* Wrappers around apr_siphash24() and apr_crypto_equals(),
     * available in APU-1.6/APR-2.0 only.
     */
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6)
    
    #include "apr_siphash.h"
    
    #define AP_SIPHASH_DSIZE    APR_SIPHASH_DSIZE
    #define AP_SIPHASH_KSIZE    APR_SIPHASH_KSIZE
    #define ap_siphash24_auth   apr_siphash24_auth
    
    #define ap_crypto_equals    apr_crypto_equals
    
    #else
    
    #define AP_SIPHASH_DSIZE    8
    #define AP_SIPHASH_KSIZE    16
    
    #define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
    
    #define U8TO64_LE(p) \
        (((apr_uint64_t)((p)[0])      ) | \
         ((apr_uint64_t)((p)[1]) <<  8) | \
         ((apr_uint64_t)((p)[2]) << 16) | \
         ((apr_uint64_t)((p)[3]) << 24) | \
         ((apr_uint64_t)((p)[4]) << 32) | \
         ((apr_uint64_t)((p)[5]) << 40) | \
         ((apr_uint64_t)((p)[6]) << 48) | \
         ((apr_uint64_t)((p)[7]) << 56))
    
    #define U64TO8_LE(p, v) \
    do { \
        (p)[0] = (unsigned char)((v)      ); \
        (p)[1] = (unsigned char)((v) >>  8); \
        (p)[2] = (unsigned char)((v) >> 16); \
        (p)[3] = (unsigned char)((v) >> 24); \
        (p)[4] = (unsigned char)((v) >> 32); \
        (p)[5] = (unsigned char)((v) >> 40); \
        (p)[6] = (unsigned char)((v) >> 48); \
        (p)[7] = (unsigned char)((v) >> 56); \
    } while (0)
    
    #define SIPROUND() \
    do { \
        v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
        v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
        v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
        v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
    } while(0)
    
    static apr_uint64_t ap_siphash24(const void *src, apr_size_t len,
                                     const unsigned char key[AP_SIPHASH_KSIZE])
    {
        const unsigned char *ptr, *end;
        apr_uint64_t v0, v1, v2, v3, m;
        apr_uint64_t k0, k1;
        unsigned int rem;
    
        k0 = U8TO64_LE(key + 0);
        k1 = U8TO64_LE(key + 8);
        v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL;
        v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL;
        v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL;
        v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL;
    
        rem = (unsigned int)(len & 0x7);
        for (ptr = src, end = ptr + len - rem; ptr < end; ptr += 8) {
            m = U8TO64_LE(ptr);
            v3 ^= m;
            SIPROUND();
            SIPROUND();
            v0 ^= m;
        }
        m = (apr_uint64_t)(len & 0xff) << 56;
        switch (rem) {
            case 7: m |= (apr_uint64_t)ptr[6] << 48;
            case 6: m |= (apr_uint64_t)ptr[5] << 40;
            case 5: m |= (apr_uint64_t)ptr[4] << 32;
            case 4: m |= (apr_uint64_t)ptr[3] << 24;
            case 3: m |= (apr_uint64_t)ptr[2] << 16;
            case 2: m |= (apr_uint64_t)ptr[1] << 8;
            case 1: m |= (apr_uint64_t)ptr[0];
            case 0: break;
        }
        v3 ^= m;
        SIPROUND();
        SIPROUND();
        v0 ^= m;
    
        v2 ^= 0xff;
        SIPROUND();
        SIPROUND();
        SIPROUND();
        SIPROUND();
    
        return v0 ^ v1 ^ v2 ^ v3;
    }
    
    static void ap_siphash24_auth(unsigned char out[AP_SIPHASH_DSIZE],
                                  const void *src, apr_size_t len,
                                  const unsigned char key[AP_SIPHASH_KSIZE])
    {
        apr_uint64_t h;
        h = ap_siphash24(src, len, key);
        U64TO8_LE(out, h);
    }
    
    static int ap_crypto_equals(const void *buf1, const void *buf2,
                                apr_size_t size)
    {
        const unsigned char *p1 = buf1;
        const unsigned char *p2 = buf2;
        unsigned char diff = 0;
        apr_size_t i;
    
        for (i = 0; i < size; ++i) {
            diff |= p1[i] ^ p2[i];
        }
    
        return 1 & ((diff - 1) >> 8);
    }
    
    #endif
    
    static void compute_auth(const void *src, apr_size_t len,
                             const char *passphrase, apr_size_t passlen,
                             unsigned char auth[AP_SIPHASH_DSIZE])
    {
        unsigned char key[APR_MD5_DIGESTSIZE];
    
        /* XXX: if we had a way to get the raw bytes from an apr_crypto_key_t
         *      we could use them directly (not available in APR-1.5.x).
         * MD5 is 128bit too, so use it to get a suitable siphash key
         * from the passphrase.
         */
        apr_md5(key, passphrase, passlen);
    
        ap_siphash24_auth(auth, src, len, key);
    }
    
    /**
     * Initialise the encryption as per the current config.
     *
     * Returns APR_SUCCESS if successful.
     */
    static apr_status_t crypt_init(request_rec *r,
            const apr_crypto_t *f, apr_crypto_block_key_type_e **cipher,
            session_crypto_dir_conf * dconf)
    {
        apr_status_t res;
        apr_hash_t *ciphers;
    
        res = apr_crypto_get_block_key_types(&ciphers, f);
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01823)
                    "no ciphers returned by APR. "
                    "session encryption not possible");
            return res;
        }
    
        *cipher = apr_hash_get(ciphers, dconf->cipher, APR_HASH_KEY_STRING);
        if (!(*cipher)) {
            apr_hash_index_t *hi;
            const void *key;
            apr_ssize_t klen;
            int sum = 0;
            int offset = 0;
            char *options = NULL;
    
            for (hi = apr_hash_first(r->pool, ciphers); hi; hi = apr_hash_next(hi)) {
                apr_hash_this(hi, NULL, &klen, NULL);
                sum += klen + 2;
            }
            for (hi = apr_hash_first(r->pool, ciphers); hi; hi = apr_hash_next(hi)) {
                apr_hash_this(hi, &key, &klen, NULL);
                if (!options) {
                    options = apr_palloc(r->pool, sum + 1);
                }
                else {
                    options[offset++] = ',';
                    options[offset++] = ' ';
                }
                strncpy(options + offset, key, klen);
                offset += klen;
            }
            options[offset] = 0;
    
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01824)
                    "cipher '%s' not recognised by crypto driver. "
                    "session encryption not possible, options: %s", dconf->cipher, options);
    
            return APR_EGENERAL;
        }
    
        return APR_SUCCESS;
    }
    
    /**
     * Encrypt the string given as per the current config.
     *
     * Returns APR_SUCCESS if successful.
     */
    static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f,
            session_crypto_dir_conf *dconf, const char *in, char **out)
    {
        apr_status_t res;
        apr_crypto_key_t *key = NULL;
        apr_size_t ivSize = 0;
        apr_crypto_block_t *block = NULL;
        unsigned char *encrypt = NULL;
        unsigned char *combined = NULL;
        apr_size_t encryptlen, tlen, combinedlen;
        char *base64;
        apr_size_t blockSize = 0;
        const unsigned char *iv = NULL;
        apr_uuid_t salt;
        apr_crypto_block_key_type_e *cipher;
        const char *passphrase;
        apr_size_t passlen;
    
        /* use a uuid as a salt value, and prepend it to our result */
        apr_uuid_get(&salt);
        res = crypt_init(r, f, &cipher, dconf);
        if (res != APR_SUCCESS) {
            return res;
        }
    
        /* encrypt using the first passphrase in the list */
        passphrase = APR_ARRAY_IDX(dconf->passphrases, 0, const char *);
        passlen = strlen(passphrase);
        res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen,
                (unsigned char *) (&salt), sizeof(apr_uuid_t),
                *cipher, APR_MODE_CBC, 1, 4096, f, r->pool);
        if (APR_STATUS_IS_ENOKEY(res)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01825)
                    "failure generating key from passphrase");
        }
        if (APR_STATUS_IS_EPADDING(res)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01826)
                    "padding is not supported for cipher");
        }
        if (APR_STATUS_IS_EKEYTYPE(res)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01827)
                    "the key type is not known");
        }
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01828)
                    "encryption could not be configured.");
            return res;
        }
    
        res = apr_crypto_block_encrypt_init(&block, &iv, key, &blockSize, r->pool);
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01829)
                    "apr_crypto_block_encrypt_init failed");
            return res;
        }
    
        /* encrypt the given string */
        res = apr_crypto_block_encrypt(&encrypt, &encryptlen,
                                       (const unsigned char *)in, strlen(in),
                                       block);
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01830)
                    "apr_crypto_block_encrypt failed");
            return res;
        }
        res = apr_crypto_block_encrypt_finish(encrypt + encryptlen, &tlen, block);
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01831)
                    "apr_crypto_block_encrypt_finish failed");
            return res;
        }
        encryptlen += tlen;
    
        /* prepend the salt and the iv to the result (keep room for the MAC) */
        combinedlen = AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize + encryptlen;
        combined = apr_palloc(r->pool, combinedlen);
        memcpy(combined + AP_SIPHASH_DSIZE, &salt, sizeof(apr_uuid_t));
        memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t), iv, ivSize);
        memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize,
               encrypt, encryptlen);
        /* authenticate the whole salt+IV+ciphertext with a leading MAC */
        compute_auth(combined + AP_SIPHASH_DSIZE, combinedlen - AP_SIPHASH_DSIZE,
                     passphrase, passlen, combined);
    
        /* base64 encode the result (APR handles the trailing '\0') */
        base64 = apr_palloc(r->pool, apr_base64_encode_len(combinedlen));
        apr_base64_encode(base64, (const char *) combined, combinedlen);
        *out = base64;
    
        return res;
    
    }
    
    /**
     * Decrypt the string given as per the current config.
     *
     * Returns APR_SUCCESS if successful.
     */
    static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f,
            session_crypto_dir_conf *dconf, const char *in, char **out)
    {
        apr_status_t res;
        apr_crypto_key_t *key = NULL;
        apr_size_t ivSize = 0;
        apr_crypto_block_t *block = NULL;
        unsigned char *decrypted = NULL;
        apr_size_t decryptedlen, tlen;
        apr_size_t decodedlen;
        char *decoded;
        apr_size_t blockSize = 0;
        apr_crypto_block_key_type_e *cipher;
        unsigned char auth[AP_SIPHASH_DSIZE];
        int i = 0;
    
        /* strip base64 from the string */
        decoded = apr_palloc(r->pool, apr_base64_decode_len(in));
        decodedlen = apr_base64_decode(decoded, in);
        decoded[decodedlen] = '\0';
    
        /* sanity check - decoded too short? */
        if (decodedlen < (AP_SIPHASH_DSIZE + sizeof(apr_uuid_t))) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(10005)
                    "too short to decrypt, aborting");
            return APR_ECRYPT;
        }
    
        res = crypt_init(r, f, &cipher, dconf);
        if (res != APR_SUCCESS) {
            return res;
        }
    
        res = APR_ECRYPT; /* in case we exhaust all passphrases */
    
        /* try each passphrase in turn */
        for (; i < dconf->passphrases->nelts; i++) {
            const char *passphrase = APR_ARRAY_IDX(dconf->passphrases, i, char *);
            apr_size_t passlen = strlen(passphrase);
            apr_size_t len = decodedlen - AP_SIPHASH_DSIZE;
            unsigned char *slider = (unsigned char *)decoded + AP_SIPHASH_DSIZE;
    
            /* Verify authentication of the whole salt+IV+ciphertext by computing
             * the MAC and comparing it (timing safe) with the one in the payload.
             */
            compute_auth(slider, len, passphrase, passlen, auth);
            if (!ap_crypto_equals(auth, decoded, AP_SIPHASH_DSIZE)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(10006)
                        "auth does not match, skipping");
                continue;
            }
    
            /* encrypt using the first passphrase in the list */
            res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen,
                                        slider, sizeof(apr_uuid_t),
                                        *cipher, APR_MODE_CBC, 1, 4096,
                                        f, r->pool);
            if (APR_STATUS_IS_ENOKEY(res)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01832)
                        "failure generating key from passphrase");
                continue;
            }
            else if (APR_STATUS_IS_EPADDING(res)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01833)
                        "padding is not supported for cipher");
                continue;
            }
            else if (APR_STATUS_IS_EKEYTYPE(res)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01834)
                        "the key type is not known");
                continue;
            }
            else if (APR_SUCCESS != res) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01835)
                        "encryption could not be configured.");
                continue;
            }
    
            /* sanity check - decoded too short? */
            if (len < (sizeof(apr_uuid_t) + ivSize)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01836)
                        "too short to decrypt, skipping");
                res = APR_ECRYPT;
                continue;
            }
    
            /* bypass the salt at the start of the decoded block */
            slider += sizeof(apr_uuid_t);
            len -= sizeof(apr_uuid_t);
    
            res = apr_crypto_block_decrypt_init(&block, &blockSize, slider, key,
                                                r->pool);
            if (APR_SUCCESS != res) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01837)
                        "apr_crypto_block_decrypt_init failed");
                continue;
            }
    
            /* bypass the iv at the start of the decoded block */
            slider += ivSize;
            len -= ivSize;
    
            /* decrypt the given string */
            res = apr_crypto_block_decrypt(&decrypted, &decryptedlen,
                                           slider, len, block);
            if (res) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01838)
                        "apr_crypto_block_decrypt failed");
                continue;
            }
            *out = (char *) decrypted;
    
            res = apr_crypto_block_decrypt_finish(decrypted + decryptedlen, &tlen, block);
            if (APR_SUCCESS != res) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01839)
                        "apr_crypto_block_decrypt_finish failed");
                continue;
            }
            decryptedlen += tlen;
            decrypted[decryptedlen] = 0;
    
            break;
        }
    
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, res, r, APLOGNO(01840)
                    "decryption failed");
        }
    
        return res;
    
    }
    
    /**
     * Crypto encoding for the session.
     *
     * @param r The request pointer.
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t session_crypto_encode(request_rec * r, session_rec * z)
    {
    
        char *encoded = NULL;
        apr_status_t res;
        const apr_crypto_t *f = NULL;
        session_crypto_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                &session_crypto_module);
    
        if (dconf->passphrases_set && z->encoded && *z->encoded) {
            apr_pool_userdata_get((void **)&f, CRYPTO_KEY, r->server->process->pconf);
            res = encrypt_string(r, f, dconf, z->encoded, &encoded);
            if (res != OK) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01841)
                        "encrypt session failed");
                return res;
            }
            z->encoded = encoded;
        }
    
        return OK;
    
    }
    
    /**
     * Crypto decoding for the session.
     *
     * @param r The request pointer.
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t session_crypto_decode(request_rec * r,
            session_rec * z)
    {
    
        char *encoded = NULL;
        apr_status_t res;
        const apr_crypto_t *f = NULL;
        session_crypto_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                &session_crypto_module);
    
        if ((dconf->passphrases_set) && z->encoded && *z->encoded) {
            apr_pool_userdata_get((void **)&f, CRYPTO_KEY,
                    r->server->process->pconf);
            res = decrypt_string(r, f, dconf, z->encoded, &encoded);
            if (res != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01842)
                        "decrypt session failed, wrong passphrase?");
                return res;
            }
            z->encoded = encoded;
        }
    
        return OK;
    
    }
    
    /**
     * Initialise the SSL in the post_config hook.
     */
    static int session_crypto_init(apr_pool_t *p, apr_pool_t *plog,
            apr_pool_t *ptemp, server_rec *s)
    {
        const apr_crypto_driver_t *driver = NULL;
        apr_crypto_t *f = NULL;
    
        session_crypto_conf *conf = ap_get_module_config(s->module_config,
                &session_crypto_module);
    
        /* session_crypto_init() will be called twice. Don't bother
         * going through all of the initialization on the first call
         * because it will just be thrown away.*/
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
    
        if (conf->library) {
    
            const apu_err_t *err = NULL;
            apr_status_t rv;
    
            rv = apr_crypto_init(p);
            if (APR_SUCCESS != rv) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01843)
                        "APR crypto could not be initialised");
                return rv;
            }
    
            rv = apr_crypto_get_driver(&driver, conf->library, conf->params, &err, p);
            if (APR_EREINIT == rv) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01844)
                        "warning: crypto for '%s' was already initialised, "
                        "using existing configuration", conf->library);
                rv = APR_SUCCESS;
            }
            if (APR_SUCCESS != rv && err) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01845)
                        "The crypto library '%s' could not be loaded: %s (%s: %d)", conf->library, err->msg, err->reason, err->rc);
                return rv;
            }
            if (APR_ENOTIMPL == rv) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01846)
                        "The crypto library '%s' could not be found",
                        conf->library);
                return rv;
            }
            if (APR_SUCCESS != rv || !driver) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01847)
                        "The crypto library '%s' could not be loaded",
                        conf->library);
                return rv;
            }
    
            rv = apr_crypto_make(&f, driver, conf->params, p);
            if (APR_SUCCESS != rv) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01848)
                        "The crypto library '%s' could not be initialised",
                        conf->library);
                return rv;
            }
    
            ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(01849)
                    "The crypto library '%s' was loaded successfully",
                    conf->library);
    
            apr_pool_userdata_set((const void *)f, CRYPTO_KEY,
                    apr_pool_cleanup_null, s->process->pconf);
    
        }
    
        return OK;
    }
    
    static void *create_session_crypto_config(apr_pool_t * p, server_rec *s)
    {
        session_crypto_conf *new =
        (session_crypto_conf *) apr_pcalloc(p, sizeof(session_crypto_conf));
    
        /* if no library has been configured, set the recommended library
         * as a sensible default.
         */
    #ifdef APU_CRYPTO_RECOMMENDED_DRIVER
        new->library = APU_CRYPTO_RECOMMENDED_DRIVER;
    #endif
    
        return (void *) new;
    }
    
    static void *create_session_crypto_dir_config(apr_pool_t * p, char *dummy)
    {
        session_crypto_dir_conf *new =
        (session_crypto_dir_conf *) apr_pcalloc(p, sizeof(session_crypto_dir_conf));
    
        new->passphrases = apr_array_make(p, 10, sizeof(char *));
    
        /* default cipher AES256-SHA */
        new->cipher = "aes256";
    
        return (void *) new;
    }
    
    static void *merge_session_crypto_dir_config(apr_pool_t * p, void *basev, void *addv)
    {
        session_crypto_dir_conf *new = (session_crypto_dir_conf *) apr_pcalloc(p, sizeof(session_crypto_dir_conf));
        session_crypto_dir_conf *add = (session_crypto_dir_conf *) addv;
        session_crypto_dir_conf *base = (session_crypto_dir_conf *) basev;
    
        new->passphrases = (add->passphrases_set == 0) ? base->passphrases : add->passphrases;
        new->passphrases_set = add->passphrases_set || base->passphrases_set;
        new->cipher = (add->cipher_set == 0) ? base->cipher : add->cipher;
        new->cipher_set = add->cipher_set || base->cipher_set;
    
        return new;
    }
    
    static const char *set_crypto_driver(cmd_parms * cmd, void *config, const char *arg)
    {
        session_crypto_conf *conf =
        (session_crypto_conf *)ap_get_module_config(cmd->server->module_config,
                &session_crypto_module);
    
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        conf->library = ap_getword_conf(cmd->pool, &arg);
        conf->params = arg;
        conf->library_set = 1;
    
        return NULL;
    }
    
    static const char *set_crypto_passphrase(cmd_parms * cmd, void *config, const char *arg)
    {
        int arglen = strlen(arg);
        char **argv;
        char *result;
        const char **passphrase;
        session_crypto_dir_conf *dconf = (session_crypto_dir_conf *) config;
    
        passphrase = apr_array_push(dconf->passphrases);
    
        if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) {
            if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) {
                return apr_pstrcat(cmd->pool,
                                   "Unable to parse exec arguments from ",
                                   arg+5, NULL);
            }
            argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);
    
            if (!argv[0]) {
                return apr_pstrcat(cmd->pool,
                                   "Invalid SessionCryptoPassphrase exec location:",
                                   arg+5, NULL);
            }
            result = ap_get_exec_line(cmd->pool,
                                      (const char*)argv[0], (const char * const *)argv);
    
            if(!result) {
                return apr_pstrcat(cmd->pool,
                                   "Unable to get bind password from exec of ",
                                   arg+5, NULL);
            }
            *passphrase = result;
        }
        else {
            *passphrase = arg;
        }
    
        dconf->passphrases_set = 1;
    
        return NULL;
    }
    
    static const char *set_crypto_passphrase_file(cmd_parms *cmd, void *config,
                                      const char *filename)
    {
        char buffer[MAX_STRING_LEN];
        char *arg;
        const char *args;
        ap_configfile_t *file;
        apr_status_t rv;
    
        filename = ap_server_root_relative(cmd->temp_pool, filename);
        rv = ap_pcfg_openfile(&file, cmd->temp_pool, filename);
        if (rv != APR_SUCCESS) {
            return apr_psprintf(cmd->pool, "%s: Could not open file %s: %pm",
                                cmd->cmd->name, filename, &rv);
        }
    
        while (!(ap_cfg_getline(buffer, sizeof(buffer), file))) {
            args = buffer;
            while (*(arg = ap_getword_conf(cmd->pool, &args)) != '\0') {
                if (*arg == '#') {
                    break;
                }
                set_crypto_passphrase(cmd, config, arg);
            }
        }
    
        ap_cfg_closefile(file);
    
        return NULL;
    }
    
    static const char *set_crypto_cipher(cmd_parms * cmd, void *config, const char *cipher)
    {
        session_crypto_dir_conf *dconf = (session_crypto_dir_conf *) config;
    
        dconf->cipher = cipher;
        dconf->cipher_set = 1;
    
        return NULL;
    }
    
    static const command_rec session_crypto_cmds[] =
    {
        AP_INIT_ITERATE("SessionCryptoPassphrase", set_crypto_passphrase, NULL, RSRC_CONF|OR_AUTHCFG,
                "The passphrase(s) used to encrypt the session. First will be used for encryption, all phrases will be accepted for decryption"),
        AP_INIT_TAKE1("SessionCryptoPassphraseFile", set_crypto_passphrase_file, NULL, RSRC_CONF|ACCESS_CONF,
                "File containing passphrase(s) used to encrypt the session, one per line. First will be used for encryption, all phrases will be accepted for decryption"),
        AP_INIT_TAKE1("SessionCryptoCipher", set_crypto_cipher, NULL, RSRC_CONF|OR_AUTHCFG,
                "The underlying crypto cipher to use"),
        AP_INIT_RAW_ARGS("SessionCryptoDriver", set_crypto_driver, NULL, RSRC_CONF,
                "The underlying crypto library driver to use"),
        { NULL }
    };
    
    static void register_hooks(apr_pool_t * p)
    {
        ap_hook_session_encode(session_crypto_encode, NULL, NULL, APR_HOOK_LAST);
        ap_hook_session_decode(session_crypto_decode, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_post_config(session_crypto_init, NULL, NULL, APR_HOOK_LAST);
    }
    
    AP_DECLARE_MODULE(session_crypto) =
    {
        STANDARD20_MODULE_STUFF,
        create_session_crypto_dir_config, /* dir config creater */
        merge_session_crypto_dir_config, /* dir merger --- default is to override */
        create_session_crypto_config, /* server config */
        NULL, /* merge server config */
        session_crypto_cmds, /* command apr_table_t */
        register_hooks /* register hooks */
    };
    
    #endif
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_cookie.mak�������������������������������������������������0000664�0001751�0001751�00000026434�12701473373�022342� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_session_cookie.dsp
    !IF "$(CFG)" == ""
    CFG=mod_session_cookie - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_session_cookie - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_session_cookie - Win32 Release" && "$(CFG)" != "mod_session_cookie - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_session_cookie.mak" CFG="mod_session_cookie - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session_cookie - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session_cookie - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_cookie - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_session - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_session - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session_cookie.obj"
    	-@erase "$(INTDIR)\mod_session_cookie.res"
    	-@erase "$(INTDIR)\mod_session_cookie_src.idb"
    	-@erase "$(INTDIR)\mod_session_cookie_src.pdb"
    	-@erase "$(OUTDIR)\mod_session_cookie.exp"
    	-@erase "$(OUTDIR)\mod_session_cookie.lib"
    	-@erase "$(OUTDIR)\mod_session_cookie.pdb"
    	-@erase "$(OUTDIR)\mod_session_cookie.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_cookie_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_cookie.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_cookie.pdb" /debug /out:"$(OUTDIR)\mod_session_cookie.so" /implib:"$(OUTDIR)\mod_session_cookie.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session_cookie.obj" \
    	"$(INTDIR)\mod_session_cookie.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_session.lib"
    
    "$(OUTDIR)\mod_session_cookie.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_session_cookie.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_cookie.so"
       if exist .\Release\mod_session_cookie.so.manifest mt.exe -manifest .\Release\mod_session_cookie.so.manifest -outputresource:.\Release\mod_session_cookie.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_session_cookie - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_session - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session_cookie.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_session - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session_cookie.obj"
    	-@erase "$(INTDIR)\mod_session_cookie.res"
    	-@erase "$(INTDIR)\mod_session_cookie_src.idb"
    	-@erase "$(INTDIR)\mod_session_cookie_src.pdb"
    	-@erase "$(OUTDIR)\mod_session_cookie.exp"
    	-@erase "$(OUTDIR)\mod_session_cookie.lib"
    	-@erase "$(OUTDIR)\mod_session_cookie.pdb"
    	-@erase "$(OUTDIR)\mod_session_cookie.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_cookie_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_cookie.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_cookie.pdb" /debug /out:"$(OUTDIR)\mod_session_cookie.so" /implib:"$(OUTDIR)\mod_session_cookie.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session_cookie.obj" \
    	"$(INTDIR)\mod_session_cookie.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_session.lib"
    
    "$(OUTDIR)\mod_session_cookie.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_session_cookie.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_cookie.so"
       if exist .\Debug\mod_session_cookie.so.manifest mt.exe -manifest .\Debug\mod_session_cookie.so.manifest -outputresource:.\Debug\mod_session_cookie.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_session_cookie.dep")
    !INCLUDE "mod_session_cookie.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_session_cookie.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_session_cookie - Win32 Release" || "$(CFG)" == "mod_session_cookie - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_session_cookie - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\session"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_cookie - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_cookie - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_cookie - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_cookie - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\session"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_cookie - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\session"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_cookie - Win32 Release"
    
    "mod_session - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" 
       cd "."
    
    "mod_session - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_session_cookie - Win32 Debug"
    
    "mod_session - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" 
       cd "."
    
    "mod_session - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_session_cookie - Win32 Release"
    
    
    "$(INTDIR)\mod_session_cookie.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_session_cookie - Win32 Debug"
    
    
    "$(INTDIR)\mod_session_cookie.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_session_cookie.c
    
    "$(INTDIR)\mod_session_cookie.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_cookie.dep�������������������������������������������������0000664�0001751�0001751�00000003351�12674411515�022332� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_session_cookie.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_session_cookie.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_cookies.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_session.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session.c����������������������������������������������������������0000664�0001751�0001751�00000054670�14240763005�020460� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_session.h"
    #include "apr_lib.h"
    #include "apr_strings.h"
    #include "util_filter.h"
    #include "http_log.h"
    #include "http_request.h"
    #include "http_protocol.h"
    
    #define SESSION_EXPIRY "expiry"
    #define HTTP_SESSION "HTTP_SESSION"
    
    APR_HOOK_STRUCT(
                    APR_HOOK_LINK(session_load)
                    APR_HOOK_LINK(session_save)
                    APR_HOOK_LINK(session_encode)
                    APR_HOOK_LINK(session_decode)
    )
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_load,
                          (request_rec * r, session_rec ** z), (r, z), DECLINED)
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_save,
                           (request_rec * r, session_rec * z), (r, z), DECLINED)
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_encode,
                       (request_rec * r, session_rec * z), (r, z), OK, DECLINED)
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_decode,
                       (request_rec * r, session_rec * z), (r, z), OK, DECLINED)
    
    static int session_identity_encode(request_rec * r, session_rec * z);
    static int session_identity_decode(request_rec * r, session_rec * z);
    static int session_fixups(request_rec * r);
    
    /**
     * Should the session be included within this URL.
     *
     * This function tests whether a session is valid for this URL. It uses the
     * include and exclude arrays to determine whether they should be included.
     */
    static int session_included(request_rec * r, session_dir_conf * conf)
    {
    
        const char **includes = (const char **) conf->includes->elts;
        const char **excludes = (const char **) conf->excludes->elts;
        int included = 1;                /* defaults to included */
        int i;
    
        if (conf->includes->nelts) {
            included = 0;
            for (i = 0; !included && i < conf->includes->nelts; i++) {
                const char *include = includes[i];
                if (strncmp(r->uri, include, strlen(include)) == 0) {
                    included = 1;
                }
            }
        }
    
        if (conf->excludes->nelts) {
            for (i = 0; included && i < conf->excludes->nelts; i++) {
                const char *exclude = excludes[i];
                if (strncmp(r->uri, exclude, strlen(exclude)) == 0) {
                    included = 0;
                }
            }
        }
    
        return included;
    }
    
    /**
     * Load the session.
     *
     * If the session doesn't exist, a blank one will be created.
     *
     * @param r The request
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t ap_session_load(request_rec * r, session_rec ** z)
    {
    
        session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                       &session_module);
        apr_time_t now;
        session_rec *zz = NULL;
        int rv = 0;
    
        /* is the session enabled? */
        if (!dconf || !dconf->enabled) {
            return APR_SUCCESS;
        }
    
        /* should the session be loaded at all? */
        if (!session_included(r, dconf)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01814)
                          "excluded by configuration for: %s", r->uri);
            return APR_SUCCESS;
        }
    
        /* load the session from the session hook */
        rv = ap_run_session_load(r, &zz);
        if (DECLINED == rv) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01815)
                          "session is enabled but no session modules have been configured, "
                          "session not loaded: %s", r->uri);
            return APR_EGENERAL;
        }
        else if (OK != rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01816)
                          "error while loading the session, "
                          "session not loaded: %s", r->uri);
            return rv;
        }
    
        /* found a session that hasn't expired? */
        now = apr_time_now();
    
        if (zz) {
            /* load the session attributes */
            rv = ap_run_session_decode(r, zz);
     
            /* having a session we cannot decode is just as good as having
               none at all */
           if (OK != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
                        "error while decoding the session, "
                        "session not loaded: %s", r->uri);
                zz = NULL;
            }
    
           /* invalidate session if session is expired */
            if (zz && zz->expiry && zz->expiry < now) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "session is expired");
                zz = NULL;
            }
        }
    
        /* no luck, create a blank session */
        if (!zz) {
            zz = (session_rec *) apr_pcalloc(r->pool, sizeof(session_rec));
            zz->pool = r->pool;
            zz->entries = apr_table_make(zz->pool, 10);
        }
    
        /* make sure the expiry and maxage are set, if present */
        if (dconf->maxage) {
            if (!zz->expiry) {
                zz->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
            }
            zz->maxage = dconf->maxage;
        }
    
        *z = zz;
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Save the session.
     *
     * In most implementations the session is only saved if the dirty flag is
     * true. This prevents the session being saved unnecessarily.
     *
     * @param r The request
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t ap_session_save(request_rec * r, session_rec * z)
    {
        if (z) {
            apr_time_t now = apr_time_now();
            apr_time_t initialExpiry = z->expiry;
            int rv = 0;
    
            session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                           &session_module);
    
            /* sanity checks, should we try save at all? */
            if (z->written) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01818)
                              "attempt made to save the session twice, "
                              "session not saved: %s", r->uri);
                return APR_EGENERAL;
            }
            if (z->expiry && z->expiry < now) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01819)
                              "attempt made to save a session when the session had already expired, "
                              "session not saved: %s", r->uri);
                return APR_EGENERAL;
            }
    
            /* reset the expiry back to maxage, if the expiry is present */
            if (dconf->maxage) {
                z->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
                z->maxage = dconf->maxage;
            }
    
            /* reset the expiry before saving if present */
            if (z->dirty && z->maxage) {
                z->expiry = now + z->maxage * APR_USEC_PER_SEC;
            } 
    
            /* don't save if the only change is the expiry by a small amount */
            if (!z->dirty && dconf->expiry_update_time
                    && (z->expiry - initialExpiry < dconf->expiry_update_time)) {
                return APR_SUCCESS;
            }
    
            /* also don't save sessions that didn't change at all */
            if (!z->dirty && !z->maxage) {
                return APR_SUCCESS;
            }
    
            /* encode the session */
            rv = ap_run_session_encode(r, z);
            if (OK != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01820)
                              "error while encoding the session, "
                              "session not saved: %s", r->uri);
                return rv;
            }
    
            /* try the save */
            rv = ap_run_session_save(r, z);
            if (DECLINED == rv) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01821)
                              "session is enabled but no session modules have been configured, "
                              "session not saved: %s", r->uri);
                return APR_EGENERAL;
            }
            else if (OK != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01822)
                              "error while saving the session, "
                              "session not saved: %s", r->uri);
                return rv;
            }
            else {
                z->written = 1;
            }
        }
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Get a particular value from the session.
     * @param r The current request.
     * @param z The current session. If this value is NULL, the session will be
     * looked up in the request, created if necessary, and saved to the request
     * notes.
     * @param key The key to get.
     * @param value The buffer to write the value to.
     */
    static apr_status_t ap_session_get(request_rec * r, session_rec * z,
            const char *key, const char **value)
    {
        if (!z) {
            apr_status_t rv;
            rv = ap_session_load(r, &z);
            if (APR_SUCCESS != rv) {
                return rv;
            }
        }
        if (z && z->entries) {
            *value = apr_table_get(z->entries, key);
        }
    
        return OK;
    }
    
    /**
     * Set a particular value to the session.
     *
     * Using this method ensures that the dirty flag is set correctly, so that
     * the session can be saved efficiently.
     * @param r The current request.
     * @param z The current session. If this value is NULL, the session will be
     * looked up in the request, created if necessary, and saved to the request
     * notes.
     * @param key The key to set. The existing key value will be replaced.
     * @param value The value to set.
     */
    static apr_status_t ap_session_set(request_rec * r, session_rec * z,
            const char *key, const char *value)
    {
        if (!z) {
            apr_status_t rv;
            rv = ap_session_load(r, &z);
            if (APR_SUCCESS != rv) {
                return rv;
            }
        }
        if (z) {
            if (value) {
                apr_table_set(z->entries, key, value);
            }
            else {
                apr_table_unset(z->entries, key);
            }
            z->dirty = 1;
        }
        return APR_SUCCESS;
    }
    
    static int identity_count(void *v, const char *key, const char *val)
    {
        apr_size_t *count = v;
    
        *count += strlen(key) * 3 + strlen(val) * 3 + 2;
        return 1;
    }
    
    static int identity_concat(void *v, const char *key, const char *val)
    {
        char *slider = v;
        apr_size_t length = strlen(slider);
    
        slider += length;
        if (length) {
            *slider = '&';
            slider++;
        }
        ap_escape_urlencoded_buffer(slider, key);
        slider += strlen(slider);
        *slider = '=';
        slider++;
        ap_escape_urlencoded_buffer(slider, val);
        return 1;
    }
    
    /**
     * Default identity encoding for the session.
     *
     * By default, the name value pairs in the session are URLEncoded, separated
     * by equals, and then in turn separated by ampersand, in the format of an
     * html form.
     *
     * This was chosen to make it easy for external code to unpack a session,
     * should there be a need to do so.
     *
     * @param r The request pointer.
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t session_identity_encode(request_rec * r, session_rec * z)
    {
        char *buffer = NULL;
        apr_size_t length = 0;
    
        if (z->expiry) {
            char *expiry = apr_psprintf(z->pool, "%" APR_INT64_T_FMT, z->expiry);
            apr_table_setn(z->entries, SESSION_EXPIRY, expiry);
        }
        apr_table_do(identity_count, &length, z->entries, NULL);
        buffer = apr_pcalloc(r->pool, length + 1);
        apr_table_do(identity_concat, buffer, z->entries, NULL);
        z->encoded = buffer;
        return OK;
    
    }
    
    /**
     * Default identity decoding for the session.
     *
     * By default, the name value pairs in the session are URLEncoded, separated
     * by equals, and then in turn separated by ampersand, in the format of an
     * html form.
     *
     * This was chosen to make it easy for external code to unpack a session,
     * should there be a need to do so.
     *
     * This function reverses that process, and populates the session table.
     *
     * Name / value pairs that are not encoded properly are ignored.
     *
     * @param r The request pointer.
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t session_identity_decode(request_rec * r, session_rec * z)
    {
    
        char *last = NULL;
        char *encoded, *pair;
        const char *sep = "&";
    
        /* sanity check - anything to decode? */
        if (!z->encoded) {
            return OK;
        }
    
        /* decode what we have */
        encoded = apr_pstrdup(r->pool, z->encoded);
        pair = apr_strtok(encoded, sep, &last);
        while (pair && pair[0]) {
            char *plast = NULL;
            const char *psep = "=";
            char *key = apr_strtok(pair, psep, &plast);
            if (key && *key) {
                char *val = apr_strtok(NULL, sep, &plast);
                if (!val || !*val) {
                    apr_table_unset(z->entries, key);
                }
                else if (!ap_unescape_urlencoded(key) && !ap_unescape_urlencoded(val)) {
                    if (!strcmp(SESSION_EXPIRY, key)) {
                        z->expiry = (apr_time_t) apr_atoi64(val);
                    }
                    else {
                        apr_table_set(z->entries, key, val);
                    }
                }
            }
            pair = apr_strtok(NULL, sep, &last);
        }
        z->encoded = NULL;
        return OK;
    
    }
    
    /**
     * Ensure any changes to the session are committed.
     *
     * This is done in an output filter so that our options for where to
     * store the session can include storing the session within a cookie:
     * As an HTTP header, the cookie must be set before the output is
     * written, but after the handler is run.
     *
     * NOTE: It is possible for internal redirects to cause more than one
     * request to be present, and each request might have a session
     * defined. We need to go through each session in turn, and save each
     * one.
     *
     * The same session might appear in more than one request. The first
     * attempt to save the session will be called
     */
    static apr_status_t session_output_filter(ap_filter_t * f,
            apr_bucket_brigade * in)
    {
    
        /* save all the sessions in all the requests */
        request_rec *r = f->r->main;
        if (!r) {
            r = f->r;
        }
        while (r) {
            session_rec *z = NULL;
            session_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                          &session_module);
    
            /* load the session, or create one if necessary */
            /* when unset or on error, z will be NULL */
            ap_session_load(r, &z);
            if (!z || z->written) {
                r = r->next;
                continue;
            }
    
            /* if a header was specified, insert the new values from the header */
            if (conf->header_set) {
                const char *override = apr_table_get(r->err_headers_out, conf->header);
                if (!override) {
                    override = apr_table_get(r->headers_out, conf->header);
                }
                if (override) {
                    apr_table_unset(r->err_headers_out, conf->header);
                    apr_table_unset(r->headers_out, conf->header);
                    z->encoded = override;
                    z->dirty = 1;
                    session_identity_decode(r, z);
                }
            }
    
            /* save away the session, and we're done */
            /* when unset or on error, we've complained to the log */
            ap_session_save(r, z);
    
            r = r->next;
        }
    
        /* remove ourselves from the filter chain */
        ap_remove_output_filter(f);
    
        /* send the data up the stack */
        return ap_pass_brigade(f->next, in);
    
    }
    
    /**
     * Insert the output filter.
     */
    static void session_insert_output_filter(request_rec * r)
    {
        ap_add_output_filter("MOD_SESSION_OUT", NULL, r, r->connection);
    }
    
    /**
     * Fixups hook.
     *
     * Load the session within a fixup - this ensures that the session is
     * properly loaded prior to the handler being called.
     *
     * The fixup is also responsible for injecting the session into the CGI
     * environment, should the admin have configured it so.
     *
     * @param r The request
     */
    static int session_fixups(request_rec * r)
    {
        session_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_module);
    
        session_rec *z = NULL;
    
        /* if an error occurs or no session has been configured, we ignore
         * the broken session and allow it to be recreated from scratch on save
         * if necessary.
         */
        ap_session_load(r, &z);
    
        if (conf->env) {
            if (z) {
                session_identity_encode(r, z);
                if (z->encoded) {
                    apr_table_set(r->subprocess_env, HTTP_SESSION, z->encoded);
                    z->encoded = NULL;
                }
            }
            apr_table_unset(r->headers_in, "Session");
        }
    
        return OK;
    
    }
    
    
    static void *create_session_dir_config(apr_pool_t * p, char *dummy)
    {
        session_dir_conf *new =
        (session_dir_conf *) apr_pcalloc(p, sizeof(session_dir_conf));
    
        new->includes = apr_array_make(p, 10, sizeof(const char **));
        new->excludes = apr_array_make(p, 10, sizeof(const char **));
    
        return (void *) new;
    }
    
    static void *merge_session_dir_config(apr_pool_t * p, void *basev, void *addv)
    {
        session_dir_conf *new = (session_dir_conf *) apr_pcalloc(p, sizeof(session_dir_conf));
        session_dir_conf *add = (session_dir_conf *) addv;
        session_dir_conf *base = (session_dir_conf *) basev;
    
        new->enabled = (add->enabled_set == 0) ? base->enabled : add->enabled;
        new->enabled_set = add->enabled_set || base->enabled_set;
        new->maxage = (add->maxage_set == 0) ? base->maxage : add->maxage;
        new->maxage_set = add->maxage_set || base->maxage_set;
        new->header = (add->header_set == 0) ? base->header : add->header;
        new->header_set = add->header_set || base->header_set;
        new->env = (add->env_set == 0) ? base->env : add->env;
        new->env_set = add->env_set || base->env_set;
        new->includes = apr_array_append(p, base->includes, add->includes);
        new->excludes = apr_array_append(p, base->excludes, add->excludes);
        new->expiry_update_time = (add->expiry_update_set == 0)
                                    ? base->expiry_update_time
                                    : add->expiry_update_time;
        new->expiry_update_set = add->expiry_update_set || base->expiry_update_set;
    
        return new;
    }
    
    
    static const char *
         set_session_enable(cmd_parms * parms, void *dconf, int flag)
    {
        session_dir_conf *conf = dconf;
    
        conf->enabled = flag;
        conf->enabled_set = 1;
    
        return NULL;
    }
    
    static const char *
         set_session_maxage(cmd_parms * parms, void *dconf, const char *arg)
    {
        session_dir_conf *conf = dconf;
    
        conf->maxage = atol(arg);
        conf->maxage_set = 1;
    
        return NULL;
    }
    
    static const char *
         set_session_header(cmd_parms * parms, void *dconf, const char *arg)
    {
        session_dir_conf *conf = dconf;
    
        conf->header = arg;
        conf->header_set = 1;
    
        return NULL;
    }
    
    static const char *
         set_session_env(cmd_parms * parms, void *dconf, int flag)
    {
        session_dir_conf *conf = dconf;
    
        conf->env = flag;
        conf->env_set = 1;
    
        return NULL;
    }
    
    static const char *add_session_include(cmd_parms * cmd, void *dconf, const char *f)
    {
        session_dir_conf *conf = dconf;
    
        const char **new = apr_array_push(conf->includes);
        *new = f;
    
        return NULL;
    }
    
    static const char *add_session_exclude(cmd_parms * cmd, void *dconf, const char *f)
    {
        session_dir_conf *conf = dconf;
    
        const char **new = apr_array_push(conf->excludes);
        *new = f;
    
        return NULL;
    }
    
    static const char *
         set_session_expiry_update(cmd_parms * parms, void *dconf, const char *arg)
    {
        session_dir_conf *conf = dconf;
    
        conf->expiry_update_time = atoi(arg);
        if (conf->expiry_update_time < 0) {
            return "SessionExpiryUpdateInterval must be zero (disable) or a positive value";
        }
        conf->expiry_update_time = apr_time_from_sec(conf->expiry_update_time);
        conf->expiry_update_set = 1;
    
        return NULL;
    }
    
    
    static const command_rec session_cmds[] =
    {
        AP_INIT_FLAG("Session", set_session_enable, NULL, RSRC_CONF|OR_AUTHCFG,
                     "on if a session should be maintained for these URLs"),
        AP_INIT_TAKE1("SessionMaxAge", set_session_maxage, NULL, RSRC_CONF|OR_AUTHCFG,
                      "length of time for which a session should be valid. Zero to disable"),
        AP_INIT_TAKE1("SessionHeader", set_session_header, NULL, RSRC_CONF|OR_AUTHCFG,
                      "output header, if present, whose contents will be injected into the session."),
        AP_INIT_FLAG("SessionEnv", set_session_env, NULL, RSRC_CONF|OR_AUTHCFG,
                     "on if a session should be written to the CGI environment. Defaults to off"),
        AP_INIT_TAKE1("SessionInclude", add_session_include, NULL, RSRC_CONF|OR_AUTHCFG,
                      "URL prefixes to include in the session. Defaults to all URLs"),
        AP_INIT_TAKE1("SessionExclude", add_session_exclude, NULL, RSRC_CONF|OR_AUTHCFG,
                      "URL prefixes to exclude from the session. Defaults to no URLs"),
        AP_INIT_TAKE1("SessionExpiryUpdateInterval", set_session_expiry_update, NULL, RSRC_CONF|OR_AUTHCFG,
                      "time interval for which a session's expiry time may change "
                      "without having to be rewritten. Zero to disable"),
        {NULL}
    };
    
    static void register_hooks(apr_pool_t * p)
    {
        ap_register_output_filter("MOD_SESSION_OUT", session_output_filter,
                                  NULL, AP_FTYPE_CONTENT_SET);
        ap_hook_insert_filter(session_insert_output_filter, NULL, NULL,
                              APR_HOOK_MIDDLE);
        ap_hook_insert_error_filter(session_insert_output_filter,
                                    NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_fixups(session_fixups, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_session_encode(session_identity_encode, NULL, NULL,
                               APR_HOOK_REALLY_FIRST);
        ap_hook_session_decode(session_identity_decode, NULL, NULL,
                               APR_HOOK_REALLY_LAST);
        APR_REGISTER_OPTIONAL_FN(ap_session_get);
        APR_REGISTER_OPTIONAL_FN(ap_session_set);
        APR_REGISTER_OPTIONAL_FN(ap_session_load);
        APR_REGISTER_OPTIONAL_FN(ap_session_save);
    }
    
    AP_DECLARE_MODULE(session) =
    {
        STANDARD20_MODULE_STUFF,
        create_session_dir_config,   /* dir config creater */
        merge_session_dir_config,    /* dir merger --- default is to override */
        NULL,                        /* server config */
        NULL,                        /* merge server config */
        session_cmds,                /* command apr_table_t */
        register_hooks               /* register hooks */
    };
    ������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session.mak��������������������������������������������������������0000664�0001751�0001751�00000023561�12701473373�021007� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_session.dsp
    !IF "$(CFG)" == ""
    CFG=mod_session - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_session - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_session - Win32 Release" && "$(CFG)" != "mod_session - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_session.mak" CFG="mod_session - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session.obj"
    	-@erase "$(INTDIR)\mod_session.res"
    	-@erase "$(INTDIR)\mod_session_src.idb"
    	-@erase "$(INTDIR)\mod_session_src.pdb"
    	-@erase "$(OUTDIR)\mod_session.exp"
    	-@erase "$(OUTDIR)\mod_session.lib"
    	-@erase "$(OUTDIR)\mod_session.pdb"
    	-@erase "$(OUTDIR)\mod_session.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SESSION_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session.pdb" /debug /out:"$(OUTDIR)\mod_session.so" /implib:"$(OUTDIR)\mod_session.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session.obj" \
    	"$(INTDIR)\mod_session.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_session.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_session.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session.so"
       if exist .\Release\mod_session.so.manifest mt.exe -manifest .\Release\mod_session.so.manifest -outputresource:.\Release\mod_session.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_session - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session.obj"
    	-@erase "$(INTDIR)\mod_session.res"
    	-@erase "$(INTDIR)\mod_session_src.idb"
    	-@erase "$(INTDIR)\mod_session_src.pdb"
    	-@erase "$(OUTDIR)\mod_session.exp"
    	-@erase "$(OUTDIR)\mod_session.lib"
    	-@erase "$(OUTDIR)\mod_session.pdb"
    	-@erase "$(OUTDIR)\mod_session.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SESSION_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session.pdb" /debug /out:"$(OUTDIR)\mod_session.so" /implib:"$(OUTDIR)\mod_session.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session.obj" \
    	"$(INTDIR)\mod_session.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_session.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_session.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session.so"
       if exist .\Debug\mod_session.so.manifest mt.exe -manifest .\Debug\mod_session.so.manifest -outputresource:.\Debug\mod_session.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_session.dep")
    !INCLUDE "mod_session.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_session.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_session - Win32 Release" || "$(CFG)" == "mod_session - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_session - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\session"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\session"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\session"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_session - Win32 Release"
    
    
    "$(INTDIR)\mod_session.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_session - Win32 Debug"
    
    
    "$(INTDIR)\mod_session.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_session.c
    
    "$(INTDIR)\mod_session.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session.dep��������������������������������������������������������0000664�0001751�0001751�00000003765�12674411515�021012� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_session.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_session.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_session.h"\
    	
    �����������httpd-2.4.64/modules/session/NWGNUmakefile����������������������������������������������������������0000664�0001751�0001751�00000010562�12143211133�020267� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    #
    ifneq "$(MAKECMDGOALS)" "clean"
    ifneq "$(findstring clobber_,$(MAKECMDGOALS))" "clobber_"
    APU_HAVE_CRYPTO = $(shell $(AWK) '/^\#define APU_HAVE_CRYPTO/{print $$3}' $(APRUTIL)/include/apu.h)
    endif
    endif
    
    #
    # 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)/session.nlm \
    	$(OBJDIR)/session_cookie.nlm \
    	$(OBJDIR)/session_dbd.nlm \
    	$(EOLIST)
    
    # If the APU library has cryptp API then build the mod_session_crypto module
    ifeq "$(APU_HAVE_CRYPTO)" "1"
    TARGET_nlm += $(OBJDIR)/session_crypto.nlm
    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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/config.m4��������������������������������������������������������������0000664�0001751�0001751�00000004330�12006475430�017465� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl modules enabled in this directory by default
    
    if test -z "$enable_session" ; then
      session_mods_enable=most
    else
      session_mods_enable=$enable_session
    fi
    
    dnl Session
    
    dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
    
    APACHE_MODPATH_INIT(session)
    
    dnl Session modules; modules that are capable of storing key value pairs in
    dnl various places, such as databases, LDAP, or cookies.
    dnl
    session_cookie_objects='mod_session_cookie.lo'
    session_crypto_objects='mod_session_crypto.lo'
    session_dbd_objects='mod_session_dbd.lo'
    
    case "$host" in
      *os2*)
        # OS/2 DLLs must resolve all symbols at build time
        # and we need some from main session module
        session_cookie_objects="$session_cookie_objects mod_session.la"
        session_crypto_objects="$session_crypto_objects mod_session.la"
        session_dbd_objects="$session_dbd_objects mod_session.la"
        ;;
    esac
    
    APACHE_MODULE(session, session module, , , most)
    APACHE_MODULE(session_cookie, session cookie module, $session_cookie_objects, , $session_mods_enable,,session)
    
    if test "$enable_session_crypto" != ""; then
      session_mods_enable_crypto=$enable_session_crypto
    else
      session_mods_enable_crypto=$session_mods_enable
    fi
    if test "$session_mods_enable_crypto" != "no"; then
      saved_CPPFLAGS="$CPPFLAGS"
      CPPFLAGS="$CPPFLAGS $APR_INCLUDES $APU_INCLUDES"
      AC_TRY_COMPILE([#include <apr_crypto.h>],[
    #if APU_HAVE_CRYPTO == 0
    #error no crypto support
    #endif
      ], [ap_HAVE_APR_CRYPTO="yes"], [ap_HAVE_APR_CRYPTO="no"])
      CPPFLAGS="$saved_CPPFLAGS"
      if test $ap_HAVE_APR_CRYPTO = "no"; then
        AC_MSG_WARN([Your APR does not include SSL/EVP support. To enable it: configure --with-crypto])
        if test "$enable_session_crypto" != "" -a "$enable_session_crypto" != "no"; then
            AC_MSG_ERROR([mod_session_crypto cannot be enabled])
        fi
        session_mods_enable_crypto="no"
      fi
    fi
    APACHE_MODULE(session_crypto, session crypto module, $session_crypto_objects, , $session_mods_enable_crypto, [
    if test "$session_mods_enable_crypto" = "no" ; then
      enable_session_crypto=no
    fi
    ],session)
    
    APACHE_MODULE(session_dbd, session dbd module, $session_dbd_objects, , $session_mods_enable,,session)
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_dbd.c������������������������������������������������������0000664�0001751�0001751�00000051375�15022010125�021253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_session.h"
    #include "apr_lib.h"
    #include "apr_strings.h"
    #include "http_log.h"
    #include "util_cookies.h"
    #include "apr_dbd.h"
    #include "mod_dbd.h"
    #include "mpm_common.h"
    
    #define MOD_SESSION_DBD "mod_session_dbd"
    
    module AP_MODULE_DECLARE_DATA session_dbd_module;
    
    /**
     * Structure to carry the per-dir session config.
     */
    typedef struct {
        const char *name;
        int name_set;
        const char *name_attrs;
        const char *name2;
        int name2_set;
        const char *name2_attrs;
        int peruser;
        int peruser_set;
        int remove;
        int remove_set;
        const char *selectlabel;
        const char *insertlabel;
        const char *updatelabel;
        const char *deletelabel;
    } session_dbd_dir_conf;
    
    /* optional function - look it up once in post_config */
    static ap_dbd_t *(*session_dbd_acquire_fn) (request_rec *) = NULL;
    static void (*session_dbd_prepare_fn) (server_rec *, const char *, const char *) = NULL;
    
    /**
     * Initialise the database.
     *
     * If the mod_dbd module is missing, this method will return APR_EGENERAL.
     */
    static apr_status_t dbd_init(request_rec *r, const char *query, ap_dbd_t **dbdp,
                                 apr_dbd_prepared_t **statementp)
    {
        ap_dbd_t *dbd;
        apr_dbd_prepared_t *statement;
    
        if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
            session_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
            session_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
            if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01850)
                              "You must load mod_dbd to enable AuthDBD functions");
                return APR_EGENERAL;
            }
        }
    
        dbd = session_dbd_acquire_fn(r);
        if (!dbd) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01851)
                          "failed to acquire database connection");
            return APR_EGENERAL;
        }
    
        statement = apr_hash_get(dbd->prepared, query, APR_HASH_KEY_STRING);
        if (!statement) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01852)
                          "failed to find the prepared statement called '%s'", query);
            return APR_EGENERAL;
        }
    
        *dbdp = dbd;
        *statementp = statement;
    
        return APR_SUCCESS;
    }
    
    /**
     * Load the session by the key specified.
     *
     * The session value is allocated using the passed apr_pool_t.
     */
    static apr_status_t dbd_load(apr_pool_t *p, request_rec * r,
                                 const char *key, const char **val)
    {
    
        apr_status_t rv;
        ap_dbd_t *dbd = NULL;
        apr_dbd_prepared_t *statement = NULL;
        apr_dbd_results_t *res = NULL;
        apr_dbd_row_t *row = NULL;
        apr_int64_t expiry = (apr_int64_t) apr_time_now();
    
        session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                          &session_dbd_module);
    
        if (conf->selectlabel == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01853)
                          "no SessionDBDselectlabel has been specified");
            return APR_EGENERAL;
        }
    
        rv = dbd_init(r, conf->selectlabel, &dbd, &statement);
        if (rv) {
            return rv;
        }
        rv = apr_dbd_pvbselect(dbd->driver, r->pool, dbd->handle, &res, statement,
                              0, key, &expiry, NULL);
        if (rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01854)
                          "query execution error saving session '%s' "
                          "in database using query '%s': %s", key, conf->selectlabel,
                          apr_dbd_error(dbd->driver, dbd->handle, rv));
            return APR_EGENERAL;
        }
        for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
             rv != -1;
             rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
            if (rv != 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01855)
                              "error retrieving results while saving '%s' "
                              "in database using query '%s': %s", key, conf->selectlabel,
                               apr_dbd_error(dbd->driver, dbd->handle, rv));
                return APR_EGENERAL;
            }
            if (*val == NULL) {
                *val = apr_pstrdup(p, apr_dbd_get_entry(dbd->driver, row, 0));
            }
            /* we can't break out here or row won't get cleaned up */
        }
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Load the session by firing off a dbd query.
     *
     * If the session is anonymous, the session key will be extracted from
     * the cookie specified. Failing that, the session key will be extracted
     * from the GET parameters.
     *
     * If the session is keyed by the username, the session will be extracted
     * by that.
     *
     * If no session is found, an empty session will be created.
     *
     * On success, this returns OK.
     */
    static apr_status_t session_dbd_load(request_rec * r, session_rec ** z)
    {
    
        session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                          &session_dbd_module);
    
        apr_status_t ret = APR_SUCCESS;
        session_rec *zz = NULL;
        const char *name = NULL;
        const char *note = NULL;
        const char *val = NULL;
        const char *key = NULL;
        request_rec *m = r->main ? r->main : r;
    
        /* is our session in a cookie? */
        if (conf->name2_set) {
            name = conf->name2;
        }
        else if (conf->name_set) {
            name = conf->name;
        }
        else if (conf->peruser_set && r->user) {
            name = r->user;
        }
        else {
            return DECLINED;
        }
    
        /* first look in the notes */
        note = apr_pstrcat(m->pool, MOD_SESSION_DBD, name, NULL);
        zz = (session_rec *)apr_table_get(m->notes, note);
        if (zz) {
            *z = zz;
            return OK;
        }
    
        /* load anonymous sessions */
        if (conf->name_set || conf->name2_set) {
    
            /* load an RFC2109 or RFC2965 compliant cookie */
            ap_cookie_read(r, name, &key, conf->remove);
            if (key) {
                ret = dbd_load(m->pool, r, key, &val);
                if (ret != APR_SUCCESS) {
                    return ret;
                }
            }
    
        }
    
        /* load named session */
        else if (conf->peruser) {
            if (r->user) {
                ret = dbd_load(m->pool, r, r->user, &val);
                if (ret != APR_SUCCESS) {
                    return ret;
                }
            }
        }
    
        /* otherwise not for us */
        else {
            return DECLINED;
        }
    
        /* create a new session and return it */
        zz = (session_rec *) apr_pcalloc(m->pool, sizeof(session_rec));
        zz->pool = m->pool;
        zz->entries = apr_table_make(zz->pool, 10);
        if (key && val) {
            apr_uuid_t *uuid = apr_pcalloc(zz->pool, sizeof(apr_uuid_t));
            if (APR_SUCCESS == apr_uuid_parse(uuid, key)) {
                zz->uuid = uuid;
            }
        }
        zz->encoded = val;
        *z = zz;
    
        /* put the session in the notes so we don't have to parse it again */
        apr_table_setn(m->notes, note, (char *)zz);
    
        /* don't cache pages with a session */
        apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
    
        return OK;
    
    }
    
    /**
     * Save the session by the key specified.
     */
    static apr_status_t dbd_save(request_rec * r, const char *oldkey,
            const char *newkey, const char *val, apr_int64_t expiry)
    {
    
        apr_status_t rv;
        ap_dbd_t *dbd = NULL;
        apr_dbd_prepared_t *statement;
        int rows = 0;
    
        session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                          &session_dbd_module);
    
        if (conf->updatelabel == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01856)
                          "no SessionDBDupdatelabel has been specified");
            return APR_EGENERAL;
        }
    
        rv = dbd_init(r, conf->updatelabel, &dbd, &statement);
        if (rv) {
            return rv;
        }
    
        if (oldkey) {
            rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows,
                    statement, val, &expiry, newkey, oldkey, NULL);
            if (rv) {
                ap_log_rerror(
                        APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01857) "query execution error updating session '%s' "
                        "using database query '%s': %s/%s", oldkey, newkey, conf->updatelabel, apr_dbd_error(dbd->driver, dbd->handle, rv));
                return APR_EGENERAL;
            }
    
            /*
             * if some rows were updated it means a session existed and was updated,
             * so we are done.
             */
            if (rows != 0) {
                return APR_SUCCESS;
            }
        }
    
        if (conf->insertlabel == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01858)
                          "no SessionDBDinsertlabel has been specified");
            return APR_EGENERAL;
        }
    
        rv = dbd_init(r, conf->insertlabel, &dbd, &statement);
        if (rv) {
            return rv;
        }
        rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
                              val, &expiry, newkey, NULL);
        if (rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01859)
                          "query execution error inserting session '%s' "
                          "in database with '%s': %s", newkey, conf->insertlabel,
                          apr_dbd_error(dbd->driver, dbd->handle, rv));
            return APR_EGENERAL;
        }
    
        /*
         * if some rows were inserted it means a session was inserted, so we are
         * done.
         */
        if (rows != 0) {
            return APR_SUCCESS;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01860)
                      "the session insert query did not cause any rows to be added "
                      "to the database for session '%s', session not inserted", newkey);
    
        return APR_EGENERAL;
    
    }
    
    /**
     * Remove the session by the key specified.
     */
    static apr_status_t dbd_remove(request_rec * r, const char *key)
    {
    
        apr_status_t rv;
        ap_dbd_t *dbd;
        apr_dbd_prepared_t *statement;
        int rows = 0;
    
        session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                          &session_dbd_module);
    
        if (conf->deletelabel == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01862)
                          "no SessionDBDdeletelabel has been specified");
            return APR_EGENERAL;
        }
    
        rv = dbd_init(r, conf->deletelabel, &dbd, &statement);
        if (rv != APR_SUCCESS) {
            /* No need to do additional error logging here, it has already
               been done in dbd_init if needed */
            return rv;
        }
    
        rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
                              key, NULL);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01864)
                          "query execution error removing session '%s' "
                          "from database", key);
            return rv;
        }
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Clean out expired sessions.
     *
     * TODO: We need to figure out a way to clean out expired sessions from the database.
     * The monitor hook doesn't help us that much, as we have no handle into the
     * server, and so we need to come up with a way to do this safely.
     */
    static apr_status_t dbd_clean(apr_pool_t *p, server_rec *s)
    {
    
        return APR_ENOTIMPL;
    
    }
    
    /**
     * Save the session by firing off a dbd query.
     *
     * If the session is anonymous, save the session and write a cookie
     * containing the uuid.
     *
     * If the session is keyed to the username, save the session using
     * the username as a key.
     *
     * On success, this method will return APR_SUCCESS.
     *
     * @param r The request pointer.
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t session_dbd_save(request_rec * r, session_rec * z)
    {
    
        apr_status_t ret = APR_SUCCESS;
        session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                          &session_dbd_module);
    
        /* support anonymous sessions */
        if (conf->name_set || conf->name2_set) {
            char *oldkey = NULL, *newkey = NULL;
    
            /* if the session is new or changed, make a new session ID */
            if (z->uuid) {
                oldkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
                apr_uuid_format(oldkey, z->uuid);
            }
            if (z->dirty || !oldkey) {
                z->uuid = apr_pcalloc(z->pool, sizeof(apr_uuid_t));
                apr_uuid_get(z->uuid);
                newkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
                apr_uuid_format(newkey, z->uuid);
            }
            else {
                newkey = oldkey;
            }
    
            /* save the session with the uuid as key */
            if (z->encoded && z->encoded[0]) {
                ret = dbd_save(r, oldkey, newkey, z->encoded, z->expiry);
            }
            else {
                ret = dbd_remove(r, oldkey);
            }
            if (ret != APR_SUCCESS) {
                return ret;
            }
    
            /* create RFC2109 compliant cookie */
            if (conf->name_set) {
                ap_cookie_write(r, conf->name, newkey, conf->name_attrs, z->maxage,
                                r->headers_out, r->err_headers_out, NULL);
            }
    
            /* create RFC2965 compliant cookie */
            if (conf->name2_set) {
                ap_cookie_write2(r, conf->name2, newkey, conf->name2_attrs, z->maxage,
                                 r->headers_out, r->err_headers_out, NULL);
            }
    
            return OK;
    
        }
    
        /* save named session */
        else if (conf->peruser) {
    
            /* don't cache pages with a session */
            apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
    
            if (r->user) {
                ret = dbd_save(r, r->user, r->user, z->encoded, z->expiry);
                if (ret != APR_SUCCESS) {
                    return ret;
                }
                return OK;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01865)
                   "peruser sessions can only be saved if a user is logged in, "
                              "session not saved: %s", r->uri);
            }
        }
    
        return DECLINED;
    
    }
    
    /**
     * This function performs housekeeping on the database, deleting expired
     * sessions.
     */
    static int session_dbd_monitor(apr_pool_t *p, server_rec *s)
    {
        /* TODO handle housekeeping */
        dbd_clean(p, s);
        return OK;
    }
    
    
    static void *create_session_dbd_dir_config(apr_pool_t * p, char *dummy)
    {
        session_dbd_dir_conf *new =
        (session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));
    
        new->remove = 1;
    
        new->selectlabel = "selectsession";
        new->insertlabel = "insertsession";
        new->updatelabel = "updatesession";
        new->deletelabel = "deletesession";
    
        return (void *) new;
    }
    
    static void *merge_session_dbd_dir_config(apr_pool_t * p, void *basev, void *addv)
    {
        session_dbd_dir_conf *new = (session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));
        session_dbd_dir_conf *add = (session_dbd_dir_conf *) addv;
        session_dbd_dir_conf *base = (session_dbd_dir_conf *) basev;
    
        new->name = (add->name_set == 0) ? base->name : add->name;
        new->name_attrs = (add->name_set == 0) ? base->name_attrs : add->name_attrs;
        new->name_set = add->name_set || base->name_set;
        new->name2 = (add->name2_set == 0) ? base->name2 : add->name2;
        new->name2_attrs = (add->name2_set == 0) ? base->name2_attrs : add->name2_attrs;
        new->name2_set = add->name2_set || base->name2_set;
        new->peruser = (add->peruser_set == 0) ? base->peruser : add->peruser;
        new->peruser_set = add->peruser_set || base->peruser_set;
        new->remove = (add->remove_set == 0) ? base->remove : add->remove;
        new->remove_set = add->remove_set || base->remove_set;
        new->selectlabel = (!add->selectlabel) ? base->selectlabel : add->selectlabel;
        new->updatelabel = (!add->updatelabel) ? base->updatelabel : add->updatelabel;
        new->insertlabel = (!add->insertlabel) ? base->insertlabel : add->insertlabel;
        new->deletelabel = (!add->deletelabel) ? base->deletelabel : add->deletelabel;
    
        return new;
    }
    
    /**
     * Sanity check a given string that it exists, is not empty,
     * and does not contain special characters.
     */
    static const char *check_string(cmd_parms * cmd, const char *string)
    {
        if (APR_SUCCESS != ap_cookie_check_string(string)) {
            return apr_pstrcat(cmd->pool, cmd->directive->directive,
                               " cannot contain '=', ';' or '&'.",
                               NULL);
        }
        return NULL;
    }
    
    static const char *
         set_dbd_peruser(cmd_parms * parms, void *dconf, int flag)
    {
        session_dbd_dir_conf *conf = dconf;
    
        conf->peruser = flag;
        conf->peruser_set = 1;
    
        return NULL;
    }
    
    static const char *
         set_dbd_cookie_remove(cmd_parms * parms, void *dconf, int flag)
    {
        session_dbd_dir_conf *conf = dconf;
    
        conf->remove = flag;
        conf->remove_set = 1;
    
        return NULL;
    }
    
    static const char *set_cookie_name(cmd_parms * cmd, void *config, const char *args)
    {
        char *last;
        char *line = apr_pstrdup(cmd->pool, args);
        session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
        char *cookie = apr_strtok(line, " \t", &last);
        if (!cookie) {
            return apr_pstrcat(cmd->pool, cmd->directive->directive,
                               " requires at least one argument!",
                               NULL);
        }
        conf->name = cookie;
        conf->name_set = 1;
        while (apr_isspace(*last)) {
            last++;
        }
        conf->name_attrs = last;
        return check_string(cmd, cookie);
    }
    
    static const char *set_cookie_name2(cmd_parms * cmd, void *config, const char *args)
    {
        char *last;
        char *line = apr_pstrdup(cmd->pool, args);
        session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
        char *cookie = apr_strtok(line, " \t", &last);
        if (!cookie) {
            return apr_pstrcat(cmd->pool, cmd->directive->directive,
                               " requires at least one argument!",
                               NULL);
        }
        conf->name2 = cookie;
        conf->name2_set = 1;
        while (apr_isspace(*last)) {
            last++;
        }
        conf->name2_attrs = last;
        return check_string(cmd, cookie);
    }
    
    static const command_rec session_dbd_cmds[] =
    {
        AP_INIT_TAKE1("SessionDBDSelectLabel", ap_set_string_slot,
          (void *) APR_OFFSETOF(session_dbd_dir_conf, selectlabel), RSRC_CONF|OR_AUTHCFG,
                      "Query label used to select a new session"),
        AP_INIT_TAKE1("SessionDBDInsertLabel", ap_set_string_slot,
          (void *) APR_OFFSETOF(session_dbd_dir_conf, insertlabel), RSRC_CONF|OR_AUTHCFG,
                      "Query label used to insert a new session"),
        AP_INIT_TAKE1("SessionDBDUpdateLabel", ap_set_string_slot,
          (void *) APR_OFFSETOF(session_dbd_dir_conf, updatelabel), RSRC_CONF|OR_AUTHCFG,
                      "Query label used to update an existing session"),
        AP_INIT_TAKE1("SessionDBDDeleteLabel", ap_set_string_slot,
          (void *) APR_OFFSETOF(session_dbd_dir_conf, deletelabel), RSRC_CONF|OR_AUTHCFG,
                      "Query label used to delete an existing session"),
        AP_INIT_FLAG("SessionDBDPerUser", set_dbd_peruser, NULL, RSRC_CONF|OR_AUTHCFG,
                     "Save the session per user"),
        AP_INIT_FLAG("SessionDBDCookieRemove", set_dbd_cookie_remove, NULL, RSRC_CONF|OR_AUTHCFG,
                     "Remove the session cookie after session load. On by default."),
        AP_INIT_RAW_ARGS("SessionDBDCookieName", set_cookie_name, NULL, RSRC_CONF|OR_AUTHCFG,
                     "The name of the RFC2109 cookie carrying the session key"),
        AP_INIT_RAW_ARGS("SessionDBDCookieName2", set_cookie_name2, NULL, RSRC_CONF|OR_AUTHCFG,
                     "The name of the RFC2965 cookie carrying the session key"),
        {NULL}
    };
    
    static void register_hooks(apr_pool_t * p)
    {
        ap_hook_session_load(session_dbd_load, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_session_save(session_dbd_save, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_monitor(session_dbd_monitor, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(session_dbd) =
    {
        STANDARD20_MODULE_STUFF,
        create_session_dbd_dir_config, /* dir config creater */
        merge_session_dbd_dir_config,  /* dir merger --- default is to
                                        * override */
        NULL,                          /* server config */
        NULL,                          /* merge server config */
        session_dbd_cmds,              /* command apr_table_t */
        register_hooks                 /* register hooks */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_cookie.c���������������������������������������������������0000664�0001751�0001751�00000022027�13523247020�021775� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_session.h"
    #include "apr_lib.h"
    #include "apr_strings.h"
    #include "http_log.h"
    #include "util_cookies.h"
    
    #define MOD_SESSION_COOKIE "mod_session_cookie"
    
    module AP_MODULE_DECLARE_DATA session_cookie_module;
    
    /**
     * Structure to carry the per-dir session config.
     */
    typedef struct {
        const char *name;
        int name_set;
        const char *name_attrs;
        const char *name2;
        int name2_set;
        const char *name2_attrs;
        int remove;
        int remove_set;
    } session_cookie_dir_conf;
    
    /**
     * Set the cookie and embed the session within it.
     *
     * This function adds an RFC2109 compliant Set-Cookie header for
     * the cookie specified in SessionCookieName, and an RFC2965 compliant
     * Set-Cookie2 header for the cookie specified in SessionCookieName2.
     *
     * If specified, the optional cookie attributes will be added to
     * each cookie. If defaults are not specified, DEFAULT_ATTRS
     * will be used.
     *
     * On success, this method will return APR_SUCCESS.
     *
     * @param r The request pointer.
     * @param z A pointer to where the session will be written.
     */
    static apr_status_t session_cookie_save(request_rec * r, session_rec * z)
    {
    
        session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                        &session_cookie_module);
    
        /* create RFC2109 compliant cookie */
        if (conf->name_set) {
            if (z->encoded && z->encoded[0]) {
                ap_cookie_write(r, conf->name, z->encoded, conf->name_attrs,
                                z->maxage, r->err_headers_out,
                                NULL);
            }
            else {
                ap_cookie_remove(r, conf->name, conf->name_attrs, r->headers_out,
                                 r->err_headers_out, NULL);
            }
        }
    
        /* create RFC2965 compliant cookie */
        if (conf->name2_set) {
            if (z->encoded && z->encoded[0]) {
                ap_cookie_write2(r, conf->name2, z->encoded, conf->name2_attrs,
                                 z->maxage, r->err_headers_out,
                                 NULL);
            }
            else {
                ap_cookie_remove2(r, conf->name2, conf->name2_attrs,
                                  r->headers_out, r->err_headers_out, NULL);
            }
        }
    
        if (conf->name_set || conf->name2_set) {
            return OK;
        }
        return DECLINED;
    
    }
    
    /**
     * Isolate the cookie with the name "name", and if present, extract
     * the payload from the cookie.
     *
     * If the cookie is found, the cookie and any other cookies with the
     * same name are removed from the cookies passed in the request, so
     * that credentials are not leaked to a backend server or process.
     *
     * A missing or malformed cookie will cause this function to return
     * APR_EGENERAL.
     *
     * On success, this returns APR_SUCCESS.
     */
    static apr_status_t session_cookie_load(request_rec * r, session_rec ** z)
    {
    
        session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                        &session_cookie_module);
    
        session_rec *zz = NULL;
        const char *val = NULL;
        const char *note = NULL;
        const char *name = NULL;
        request_rec *m = r;
    
        /* find the first redirect */
        while (m->prev) {
            m = m->prev;
        }
        /* find the main request */
        while (m->main) {
            m = m->main;
        }
    
        /* is our session in a cookie? */
        if (conf->name2_set) {
            name = conf->name2;
        }
        else if (conf->name_set) {
            name = conf->name;
        }
        else {
            return DECLINED;
        }
    
        /* first look in the notes */
        note = apr_pstrcat(m->pool, MOD_SESSION_COOKIE, name, NULL);
        zz = (session_rec *)apr_table_get(m->notes, note);
        if (zz) {
            *z = zz;
            return OK;
        }
    
        /* otherwise, try parse the cookie */
        ap_cookie_read(r, name, &val, conf->remove);
    
        /* create a new session and return it */
        zz = (session_rec *) apr_pcalloc(m->pool, sizeof(session_rec));
        zz->pool = m->pool;
        zz->entries = apr_table_make(m->pool, 10);
        zz->encoded = val;
        *z = zz;
    
        /* put the session in the notes so we don't have to parse it again */
        apr_table_setn(m->notes, note, (char *)zz);
    
        /* don't cache auth protected pages */
        apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
    
        return OK;
    
    }
    
    
    
    static void *create_session_cookie_dir_config(apr_pool_t * p, char *dummy)
    {
        session_cookie_dir_conf *new =
        (session_cookie_dir_conf *) apr_pcalloc(p, sizeof(session_cookie_dir_conf));
    
        return (void *) new;
    }
    
    static void *merge_session_cookie_dir_config(apr_pool_t * p, void *basev,
                                                 void *addv)
    {
        session_cookie_dir_conf *new = (session_cookie_dir_conf *)
                                    apr_pcalloc(p, sizeof(session_cookie_dir_conf));
        session_cookie_dir_conf *add = (session_cookie_dir_conf *) addv;
        session_cookie_dir_conf *base = (session_cookie_dir_conf *) basev;
    
        new->name = (add->name_set == 0) ? base->name : add->name;
        new->name_attrs = (add->name_set == 0) ? base->name_attrs : add->name_attrs;
        new->name_set = add->name_set || base->name_set;
        new->name2 = (add->name2_set == 0) ? base->name2 : add->name2;
        new->name2_attrs = (add->name2_set == 0) ? base->name2_attrs : add->name2_attrs;
        new->name2_set = add->name2_set || base->name2_set;
        new->remove = (add->remove_set == 0) ? base->remove : add->remove;
        new->remove_set = add->remove_set || base->remove_set;
    
        return new;
    }
    
    /**
     * Sanity check a given string that it exists, is not empty,
     * and does not contain special characters.
     */
    static const char *check_string(cmd_parms * cmd, const char *string)
    {
        if (!string || !*string || ap_strchr_c(string, '=') || ap_strchr_c(string, '&')) {
            return apr_pstrcat(cmd->pool, cmd->directive->directive,
                               " cannot be empty, or contain '=' or '&'.",
                               NULL);
        }
        return NULL;
    }
    
    static const char *set_cookie_name(cmd_parms * cmd, void *config,
                                       const char *args)
    {
        char *last;
        char *line = apr_pstrdup(cmd->pool, args);
        session_cookie_dir_conf *conf = (session_cookie_dir_conf *) config;
        char *cookie = apr_strtok(line, " \t", &last);
        conf->name = cookie;
        conf->name_set = 1;
        while (apr_isspace(*last)) {
            last++;
        }
        conf->name_attrs = last;
        return check_string(cmd, cookie);
    }
    
    static const char *set_cookie_name2(cmd_parms * cmd, void *config,
                                        const char *args)
    {
        char *last;
        char *line = apr_pstrdup(cmd->pool, args);
        session_cookie_dir_conf *conf = (session_cookie_dir_conf *) config;
        char *cookie = apr_strtok(line, " \t", &last);
        conf->name2 = cookie;
        conf->name2_set = 1;
        while (apr_isspace(*last)) {
            last++;
        }
        conf->name2_attrs = last;
        return check_string(cmd, cookie);
    }
    
    static const char *
         set_remove(cmd_parms * parms, void *dconf, int flag)
    {
        session_cookie_dir_conf *conf = dconf;
    
        conf->remove = flag;
        conf->remove_set = 1;
    
        return NULL;
    }
    
    static const command_rec session_cookie_cmds[] =
    {
        AP_INIT_RAW_ARGS("SessionCookieName", set_cookie_name, NULL, RSRC_CONF|OR_AUTHCFG,
                         "The name of the RFC2109 cookie carrying the session"),
        AP_INIT_RAW_ARGS("SessionCookieName2", set_cookie_name2, NULL, RSRC_CONF|OR_AUTHCFG,
                         "The name of the RFC2965 cookie carrying the session"),
        AP_INIT_FLAG("SessionCookieRemove", set_remove, NULL, RSRC_CONF|OR_AUTHCFG,
                     "Set to 'On' to remove the session cookie from the headers "
                     "and hide the cookie from a backend server or process"),
        {NULL}
    };
    
    static void register_hooks(apr_pool_t * p)
    {
        ap_hook_session_load(session_cookie_load, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_session_save(session_cookie_save, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(session_cookie) =
    {
        STANDARD20_MODULE_STUFF,
        create_session_cookie_dir_config, /* dir config creater */
        merge_session_cookie_dir_config,  /* dir merger --- default is to
                                           * override */
        NULL,                             /* server config */
        NULL,                             /* merge server config */
        session_cookie_cmds,              /* command apr_table_t */
        register_hooks                    /* register hooks */
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_dbd.mak����������������������������������������������������0000664�0001751�0001751�00000027703�12701473373�021622� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_session_dbd.dsp
    !IF "$(CFG)" == ""
    CFG=mod_session_dbd - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_session_dbd - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_session_dbd - Win32 Release" && "$(CFG)" != "mod_session_dbd - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_session_dbd.mak" CFG="mod_session_dbd - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_dbd - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_session - Win32 Release" "mod_dbd - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_dbd - Win32 ReleaseCLEAN" "mod_session - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session_dbd.obj"
    	-@erase "$(INTDIR)\mod_session_dbd.res"
    	-@erase "$(INTDIR)\mod_session_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_session_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_session_dbd.exp"
    	-@erase "$(OUTDIR)\mod_session_dbd.lib"
    	-@erase "$(OUTDIR)\mod_session_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_session_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_dbd_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_dbd.pdb" /debug /out:"$(OUTDIR)\mod_session_dbd.so" /implib:"$(OUTDIR)\mod_session_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session_dbd.obj" \
    	"$(INTDIR)\mod_session_dbd.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"..\database\Release\mod_dbd.lib" \
    	"$(OUTDIR)\mod_session.lib"
    
    "$(OUTDIR)\mod_session_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_session_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_dbd.so"
       if exist .\Release\mod_session_dbd.so.manifest mt.exe -manifest .\Release\mod_session_dbd.so.manifest -outputresource:.\Release\mod_session_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_session - Win32 Debug" "mod_dbd - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_dbd - Win32 DebugCLEAN" "mod_session - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session_dbd.obj"
    	-@erase "$(INTDIR)\mod_session_dbd.res"
    	-@erase "$(INTDIR)\mod_session_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_session_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_session_dbd.exp"
    	-@erase "$(OUTDIR)\mod_session_dbd.lib"
    	-@erase "$(OUTDIR)\mod_session_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_session_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_dbd_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_dbd.pdb" /debug /out:"$(OUTDIR)\mod_session_dbd.so" /implib:"$(OUTDIR)\mod_session_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session_dbd.obj" \
    	"$(INTDIR)\mod_session_dbd.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"..\database\Debug\mod_dbd.lib" \
    	"$(OUTDIR)\mod_session.lib"
    
    "$(OUTDIR)\mod_session_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_session_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_dbd.so"
       if exist .\Debug\mod_session_dbd.so.manifest mt.exe -manifest .\Debug\mod_session_dbd.so.manifest -outputresource:.\Debug\mod_session_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_session_dbd.dep")
    !INCLUDE "mod_session_dbd.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_session_dbd.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_session_dbd - Win32 Release" || "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_session_dbd - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\session"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_dbd - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_dbd - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\session"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\session"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_dbd - Win32 Release"
    
    "mod_dbd - Win32 Release" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" 
       cd "..\session"
    
    "mod_dbd - Win32 ReleaseCLEAN" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" RECURSE=1 CLEAN 
       cd "..\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    "mod_dbd - Win32 Debug" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" 
       cd "..\session"
    
    "mod_dbd - Win32 DebugCLEAN" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_dbd - Win32 Release"
    
    "mod_session - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" 
       cd "."
    
    "mod_session - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    "mod_session - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" 
       cd "."
    
    "mod_session - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_session_dbd - Win32 Release"
    
    
    "$(INTDIR)\mod_session_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - Win32 Debug"
    
    
    "$(INTDIR)\mod_session_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_session_dbd.c
    
    "$(INTDIR)\mod_session_dbd.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_dbd.dep����������������������������������������������������0000664�0001751�0001751�00000004202�12674411515�021606� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_session_dbd.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_session_dbd.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mpm_common.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_cookies.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbd.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\database\mod_dbd.h"\
    	".\mod_session.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/NWGNUsession�����������������������������������������������������������0000664�0001751�0001751�00000010342�11653006502�020200� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(SRC)/include \
    			$(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	= session
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Session Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Session 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	=
    
    #
    # 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)/$(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_session.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	session_module \
    	ap_hook_session_decode \
    	ap_hook_session_encode \
    	ap_hook_session_load \
    	ap_hook_session_save \
    	$(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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_crypto.mak�������������������������������������������������0000664�0001751�0001751�00000026434�12701473373�022411� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_session_crypto.dsp
    !IF "$(CFG)" == ""
    CFG=mod_session_crypto - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_session_crypto - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_session_crypto - Win32 Release" && "$(CFG)" != "mod_session_crypto - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_session_crypto.mak" CFG="mod_session_crypto - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session_crypto - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session_crypto - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_crypto - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_session - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_session - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session_crypto.obj"
    	-@erase "$(INTDIR)\mod_session_crypto.res"
    	-@erase "$(INTDIR)\mod_session_crypto_src.idb"
    	-@erase "$(INTDIR)\mod_session_crypto_src.pdb"
    	-@erase "$(OUTDIR)\mod_session_crypto.exp"
    	-@erase "$(OUTDIR)\mod_session_crypto.lib"
    	-@erase "$(OUTDIR)\mod_session_crypto.pdb"
    	-@erase "$(OUTDIR)\mod_session_crypto.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_crypto_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_crypto.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_crypto.pdb" /debug /out:"$(OUTDIR)\mod_session_crypto.so" /implib:"$(OUTDIR)\mod_session_crypto.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session_crypto.obj" \
    	"$(INTDIR)\mod_session_crypto.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_session.lib"
    
    "$(OUTDIR)\mod_session_crypto.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_session_crypto.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_crypto.so"
       if exist .\Release\mod_session_crypto.so.manifest mt.exe -manifest .\Release\mod_session_crypto.so.manifest -outputresource:.\Release\mod_session_crypto.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_session_crypto - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_session - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_session_crypto.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_session - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_session_crypto.obj"
    	-@erase "$(INTDIR)\mod_session_crypto.res"
    	-@erase "$(INTDIR)\mod_session_crypto_src.idb"
    	-@erase "$(INTDIR)\mod_session_crypto_src.pdb"
    	-@erase "$(OUTDIR)\mod_session_crypto.exp"
    	-@erase "$(OUTDIR)\mod_session_crypto.lib"
    	-@erase "$(OUTDIR)\mod_session_crypto.pdb"
    	-@erase "$(OUTDIR)\mod_session_crypto.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_session_crypto_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_session_crypto.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_session_crypto.pdb" /debug /out:"$(OUTDIR)\mod_session_crypto.so" /implib:"$(OUTDIR)\mod_session_crypto.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_session_crypto.obj" \
    	"$(INTDIR)\mod_session_crypto.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_session.lib"
    
    "$(OUTDIR)\mod_session_crypto.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_session_crypto.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_session_crypto.so"
       if exist .\Debug\mod_session_crypto.so.manifest mt.exe -manifest .\Debug\mod_session_crypto.so.manifest -outputresource:.\Debug\mod_session_crypto.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_session_crypto.dep")
    !INCLUDE "mod_session_crypto.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_session_crypto.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_session_crypto - Win32 Release" || "$(CFG)" == "mod_session_crypto - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_session_crypto - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\session"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_crypto - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_crypto - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_crypto - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\session"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_crypto - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\session"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ELSEIF  "$(CFG)" == "mod_session_crypto - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\session"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\session"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_session_crypto - Win32 Release"
    
    "mod_session - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" 
       cd "."
    
    "mod_session - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_session_crypto - Win32 Debug"
    
    "mod_session - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" 
       cd "."
    
    "mod_session - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_session.mak" CFG="mod_session - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_session_crypto - Win32 Release"
    
    
    "$(INTDIR)\mod_session_crypto.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_session_crypto - Win32 Debug"
    
    
    "$(INTDIR)\mod_session_crypto.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_session_crypto.c
    
    "$(INTDIR)\mod_session_crypto.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_crypto.dep�������������������������������������������������0000664�0001751�0001751�00000004061�12674411515�022400� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_session_crypto.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_session_crypto.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_crypto.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr-util\include\apu_errno.h"\
    	"..\..\srclib\apr-util\include\apu_version.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_session.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/NWGNUsession_cookie����������������������������������������������������0000664�0001751�0001751�00000010333�11653006502�021531� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(SRC)/include \
    			$(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	= session_cookie
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Session Cookie Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= SessionCookie 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	=
    
    #
    # 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)/$(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_session_cookie.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 = \
    	$(PRELUDE) \
    	$(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 \
    	session \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	ap_hook_session_load \
    	ap_hook_session_save \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	session_cookie_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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/NWGNUsession_dbd�������������������������������������������������������0000664�0001751�0001751�00000010332�11653006502�021010� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(SRC)/include \
    			$(STDMOD)/database \
    			$(NWOS) \
    
    #
    # 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	= session_dbd
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Session Cookie Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= SessionDbd 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	=
    
    #
    # 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)/$(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_session_dbd.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 = \
    	$(PRELUDE) \
    	$(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 \
    	session \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	ap_hook_session_load \
    	ap_hook_session_save \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	session_dbd_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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_crypto.dsp�������������������������������������������������0000664�0001751�0001751�00000011143�11022367030�022401� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_session_crypto" - 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_session_crypto - 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_session_crypto.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_session_crypto.mak" CFG="mod_session_crypto - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session_crypto - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session_crypto - 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_session_crypto - 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_session_crypto_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 /fo"Release/mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_session_crypto.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_session_crypto - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_session_crypto_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 /fo"Debug/mod_session_crypto.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_crypto.so" /d LONG_NAME="session_crypto_module for Apache"
    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 /out:".\Debug\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_crypto.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_crypto.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_session_crypto.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_session_crypto - Win32 Release"
    # Name "mod_session_crypto - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_session_crypto.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_dbd.dsp����������������������������������������������������0000664�0001751�0001751�00000011053�11022367030�021612� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_session_dbd" - 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_session_dbd - 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_session_dbd.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_session_dbd.mak" CFG="mod_session_dbd - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session_dbd - 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_session_dbd - 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 "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_session_dbd_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 /fo"Release/mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_session_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_session_dbd - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../database" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_session_dbd_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 /fo"Debug/mod_session_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_dbd.so" /d LONG_NAME="session_dbd_module for Apache"
    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 /out:".\Debug\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_dbd.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_session_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_session_dbd - Win32 Release"
    # Name "mod_session_dbd - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_session_dbd.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/Makefile.in������������������������������������������������������������0000664�0001751�0001751�00000000270�10776673775�020052� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/NWGNUsession_crypto����������������������������������������������������0000664�0001751�0001751�00000010417�11653006502�021603� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(SRC)/include \
    			$(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	= session_crypto
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Session Crypto Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= SessionCrypto 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	=
    
    #
    # 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)/$(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_session_crypto.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 = \
    	$(PRELUDE) \
    	$(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 \
    	session \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	ap_hook_session_decode \
    	ap_hook_session_encode \
    	ap_hook_session_load \
    	ap_hook_session_save \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	session_crypto_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session.dsp��������������������������������������������������������0000664�0001751�0001751�00000011007�11022367030�021000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_session" - 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_session - 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_session.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_session.mak" CFG="mod_session - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session - 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_session - 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 "SESSION_DECLARE_EXPORT" /Fd"Release\mod_session_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 /fo"Release/mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_session.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_session - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SESSION_DECLARE_EXPORT" /Fd"Debug\mod_session_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 /fo"Debug/mod_session.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session.so" /d LONG_NAME="session_module for Apache"
    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 /out:".\Debug\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_session.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_session - Win32 Release"
    # Name "mod_session - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_session.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_session.h
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/session/mod_session_cookie.dsp�������������������������������������������������0000664�0001751�0001751�00000011143�11022367030�022332� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_session_cookie" - 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_session_cookie - 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_session_cookie.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_session_cookie.mak" CFG="mod_session_cookie - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_session_cookie - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_session_cookie - 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_session_cookie - 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_session_cookie_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 /fo"Release/mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_session_cookie.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_session_cookie - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_session_cookie_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 /fo"Debug/mod_session_cookie.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_session_cookie.so" /d LONG_NAME="session_cookie_module for Apache"
    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 /out:".\Debug\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_session_cookie.so" /base:@..\..\os\win32\BaseAddr.ref,mod_session_cookie.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_session_cookie.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_session_cookie - Win32 Release"
    # Name "mod_session_cookie - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_session_cookie.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015221� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/unix/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016204� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/unix/mod_unixd.c����������������������������������������������������������0000664�0001751�0001751�00000032047�13303573314�020334� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "http_config.h"
    #include "http_main.h"
    #include "http_log.h"
    #include "http_core.h"
    #include "mpm_common.h"
    #include "os.h"
    #include "ap_mpm.h"
    #include "mod_unixd.h"
    #include "apr_thread_proc.h"
    #include "apr_strings.h"
    #include "apr_portable.h"
    #ifdef HAVE_PWD_H
    #include <pwd.h>
    #endif
    #ifdef HAVE_SYS_RESOURCE_H
    #include <sys/resource.h>
    #endif
    /* XXX */
    #include <sys/stat.h>
    #ifdef HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #ifdef HAVE_GRP_H
    #include <grp.h>
    #endif
    #ifdef HAVE_STRINGS_H
    #include <strings.h>
    #endif
    #ifdef HAVE_SYS_SEM_H
    #include <sys/sem.h>
    #endif
    #ifdef HAVE_SYS_PRCTL_H
    #include <sys/prctl.h>
    #endif
    
    #ifndef DEFAULT_USER
    #define DEFAULT_USER "#-1"
    #endif
    #ifndef DEFAULT_GROUP
    #define DEFAULT_GROUP "#-1"
    #endif
    
    #if 0
    typedef struct {
      const char *user_name;
      uid_t user_id;
      gid_t group_id;
      const char *chroot_dir;
    } unixd_config_t;
    #else
    /*
     * TODO: clean up the separation between this code
     *       and its data structures and unixd.c, as shown
     *       by the fact that we include unixd.h. Create
     *       mod_unixd.h which does what we need and
     *       clean up unixd.h for what it no longer needs
     */
    #include "unixd.h"
    #endif
    
    
    /* 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 (ap_unixd_config.user_name[0] == '#') {
                struct passwd *ent;
                uid_t uid = atol(&ap_unixd_config.user_name[1]);
    
                if ((ent = getpwuid(uid)) == NULL) {
                    ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02155)
                             "getpwuid: couldn't determine user name from uid %ld, "
                             "you probably need to modify the User directive",
                             (long)uid);
                    return -1;
                }
    
                name = ent->pw_name;
            }
            else
                name = ap_unixd_config.user_name;
    
    #if !defined(OS2)
            /* OS/2 doesn't support groups. */
            /*
             * Set the GID before initgroups(), since on some platforms
             * setgid() is known to zap the group list.
             */
            if (setgid(ap_unixd_config.group_id) == -1) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02156)
                            "setgid: unable to set group id to Group %ld",
                            (long)ap_unixd_config.group_id);
                return -1;
            }
    
            /* Reset `groups' attributes. */
    
            if (initgroups(name, ap_unixd_config.group_id) == -1) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02157)
                            "initgroups: unable to set groups for User %s "
                            "and Group %ld", name, (long)ap_unixd_config.group_id);
                return -1;
            }
    #endif /* !defined(OS2) */
        }
        return 0;
    }
    
    
    static int
    unixd_drop_privileges(apr_pool_t *pool, server_rec *s)
    {
        int rv = set_group_privs();
    
        if (rv) {
            return rv;
        }
    
        if (NULL != ap_unixd_config.chroot_dir) {
            if (geteuid()) {
                rv = errno;
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02158)
                             "Cannot chroot when not started as root");
                return rv;
            }
    
            if (chdir(ap_unixd_config.chroot_dir) != 0) {
                rv = errno;
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02159)
                             "Can't chdir to %s", ap_unixd_config.chroot_dir);
                return rv;
            }
    
            if (chroot(ap_unixd_config.chroot_dir) != 0) {
                rv = errno;
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02160)
                             "Can't chroot to %s", ap_unixd_config.chroot_dir);
                return rv;
            }
    
            if (chdir("/") != 0) {
                rv = errno;
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02161)
                             "Can't chdir to new root");
                return rv;
            }
        }
    
        /* Only try to switch if we're running as root */
        if (!geteuid() && (
    #ifdef _OSD_POSIX
            os_init_job_environment(NULL, ap_unixd_config.user_name, ap_exists_config_define("DEBUG")) != 0 ||
    #endif
            setuid(ap_unixd_config.user_id) == -1)) {
            rv = errno;
            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02162)
                        "setuid: unable to change to uid: %ld",
                        (long) ap_unixd_config.user_id);
            return rv;
        }
    #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
        /* this applies to Linux 2.4+ */
        if (ap_coredumpdir_configured) {
            if (prctl(PR_SET_DUMPABLE, 1)) {
                rv = errno;
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02163)
                             "set dumpable failed - this child will not coredump"
                             " after software errors");
                return rv;
            }
        }
    #endif
    
        return OK;
    }
    
    
    static 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;
        }
    
        ap_unixd_config.user_name = arg;
        ap_unixd_config.user_id = ap_uname2id(arg);
    #if !defined (BIG_SECURITY_HOLE) && !defined (OS2)
        if (ap_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;
    }
    
    static 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;
        }
    
        ap_unixd_config.group_name = arg;
        ap_unixd_config.group_id = ap_gname2id(arg);
    
        return NULL;
    }
    
    static const char*
    unixd_set_chroot_dir(cmd_parms *cmd, void *dummy,
                        const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
        if (!ap_is_directory(cmd->pool, arg)) {
            return "ChrootDir must be a valid directory";
        }
    
        ap_unixd_config.chroot_dir = arg;
        return NULL;
    }
    
    static const char *
    unixd_set_suexec(cmd_parms *cmd, void *dummy, int arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        if (!ap_unixd_config.suexec_enabled && arg) {
            return apr_pstrcat(cmd->pool, "suEXEC isn't supported: ",
                               ap_unixd_config.suexec_disabled_reason, NULL);
        }
    
        if (!arg) {
            ap_unixd_config.suexec_disabled_reason = "Suexec directive is Off";
        }
    
        ap_unixd_config.suexec_enabled = arg;
        return NULL;
    }
    
    #ifdef AP_SUEXEC_CAPABILITIES
    /* If suexec is using capabilities, don't test for the setuid bit. */
    #define SETUID_TEST(finfo) (1)
    #else
    #define SETUID_TEST(finfo) (finfo.protection & APR_USETID)
    #endif
    
    static int
    unixd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                     apr_pool_t *ptemp)
    {
        apr_finfo_t wrapper;
        ap_unixd_config.user_name = DEFAULT_USER;
        ap_unixd_config.user_id = ap_uname2id(DEFAULT_USER);
        ap_unixd_config.group_name = DEFAULT_GROUP;
        ap_unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
    
        ap_unixd_config.chroot_dir = NULL; /* none */
    
        /* Check for suexec */
        ap_unixd_config.suexec_enabled = 0;
        if ((apr_stat(&wrapper, SUEXEC_BIN, APR_FINFO_NORM, ptemp))
             == APR_SUCCESS) {
            if (SETUID_TEST(wrapper) && wrapper.user == 0
                && (access(SUEXEC_BIN, R_OK|X_OK) == 0)) {
                ap_unixd_config.suexec_enabled = 1;
                ap_unixd_config.suexec_disabled_reason = "";
            }
            else {
                ap_unixd_config.suexec_disabled_reason =
                    "Invalid owner or file mode for " SUEXEC_BIN;
            }
        }
        else {
            ap_unixd_config.suexec_disabled_reason =
                "Missing suexec binary " SUEXEC_BIN;
        }
    
        ap_sys_privileges_handlers(1);
        return OK;
    }
    
    AP_DECLARE(int) ap_unixd_setup_child(void)
    {
        if (set_group_privs()) {
            return -1;
        }
    
        if (NULL != ap_unixd_config.chroot_dir) {
            if (geteuid()) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02164)
                             "Cannot chroot when not started as root");
                return -1;
            }
            if (chdir(ap_unixd_config.chroot_dir) != 0) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02165)
                             "Can't chdir to %s", ap_unixd_config.chroot_dir);
                return -1;
            }
            if (chroot(ap_unixd_config.chroot_dir) != 0) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02166)
                             "Can't chroot to %s", ap_unixd_config.chroot_dir);
                return -1;
            }
            if (chdir("/") != 0) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02167)
                             "Can't chdir to new root");
                return -1;
            }
        }
    
        /* Only try to switch if we're running as root */
        if (!geteuid() && (
    #ifdef _OSD_POSIX
            os_init_job_environment(NULL, ap_unixd_config.user_name, ap_exists_config_define("DEBUG")) != 0 ||
    #endif
            setuid(ap_unixd_config.user_id) == -1)) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02168)
                        "setuid: unable to change to uid: %ld",
                        (long) ap_unixd_config.user_id);
            return -1;
        }
    #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
        /* this applies to Linux 2.4+ */
        if (ap_coredumpdir_configured) {
            if (prctl(PR_SET_DUMPABLE, 1)) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02169)
                             "set dumpable failed - this child will not coredump"
                             " after software errors");
            }
        }
    #endif
        return 0;
    }
    
    static void unixd_dump_config(apr_pool_t *p, server_rec *s)
    {
        apr_file_t *out = NULL;
        apr_uid_t uid = ap_unixd_config.user_id;
        apr_gid_t gid = ap_unixd_config.group_id;
        char *no_root = "";
        if (!ap_exists_config_define("DUMP_RUN_CFG"))
            return;
        if (geteuid() != 0)
            no_root = " not_used";
        apr_file_open_stdout(&out, p);
        apr_file_printf(out, "User: name=\"%s\" id=%lu%s\n",
                        ap_unixd_config.user_name, (unsigned long)uid, no_root);
        apr_file_printf(out, "Group: name=\"%s\" id=%lu%s\n",
                        ap_unixd_config.group_name, (unsigned long)gid, no_root);
        if (ap_unixd_config.chroot_dir)
            apr_file_printf(out, "ChrootDir: \"%s\"%s\n",
                            ap_unixd_config.chroot_dir, no_root);
    }
    
    static void unixd_hooks(apr_pool_t *pool)
    {
        ap_hook_pre_config(unixd_pre_config,
                           NULL, NULL, APR_HOOK_FIRST);
        ap_hook_test_config(unixd_dump_config,
                            NULL, NULL, APR_HOOK_FIRST);
        ap_hook_drop_privileges(unixd_drop_privileges,
                                NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    static const command_rec unixd_cmds[] = {
        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"),
        AP_INIT_TAKE1("ChrootDir", unixd_set_chroot_dir, NULL, RSRC_CONF,
                      "The directory to chroot(2) into"),
        AP_INIT_FLAG("Suexec", unixd_set_suexec, NULL, RSRC_CONF,
                     "Enable or disable suEXEC support"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(unixd) = {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        unixd_cmds,
        unixd_hooks
    };
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/unix/mod_systemd.c��������������������������������������������������������0000664�0001751�0001751�00000012602�15020012305�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdint.h>
    #include <ap_config.h>
    #include "ap_mpm.h"
    #include "ap_listen.h"
    #include <http_core.h>
    #include <httpd.h>
    #include <http_log.h>
    #include <apr_version.h>
    #include <apr_pools.h>
    #include <apr_strings.h>
    #include "unixd.h"
    #include "scoreboard.h"
    #include "mpm_common.h"
    
    #ifdef HAVE_SELINUX
    #include <selinux/selinux.h>
    #endif
    
    #include "systemd/sd-daemon.h"
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                  apr_pool_t *ptemp)
    {
        sd_notify(0,
                  "RELOADING=1\n"
                  "STATUS=Reading configuration...\n");
        ap_extended_status = 1;
        return OK;
    }
    
    #ifdef HAVE_SELINUX
    static void log_selinux_context(void)
    {
        char *con;
    
        if (is_selinux_enabled() && getcon(&con) == 0) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
                         APLOGNO(10497) "SELinux is enabled; "
                         "httpd running as context %s", con);
            freecon(con);
        }
    }
    #endif
    
    /* Report the service is ready in post_config, which could be during
     * startup or after a reload.  The server could still hit a fatal
     * startup error after this point during ap_run_mpm(), so this is
     * perhaps too early, but by post_config listen() has been called on
     * the TCP ports so new connections will not be rejected.  There will
     * always be a possible async failure event simultaneous to the
     * service reporting "ready", so this should be good enough. */
    static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                   apr_pool_t *ptemp, server_rec *main_server)
    {
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
            return OK;
    
    #ifdef HAVE_SELINUX
        log_selinux_context();
    #endif
    
        sd_notify(0, "READY=1\n"
                  "STATUS=Configuration loaded.\n");
        return OK;
    }
    
    static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type)
    {
        sd_notifyf(0, "READY=1\n"
                   "STATUS=Processing requests...\n"
                   "MAINPID=%" APR_PID_T_FMT, getpid());
    
        return OK;
    }
    
    static int systemd_monitor(apr_pool_t *p, server_rec *s)
    {
        ap_sload_t sload;
        apr_interval_time_t up_time;
        char bps[5];
    
        if (!ap_extended_status) {
            /* Nothing useful to report with ExtendedStatus disabled. */
            return DECLINED;
        }
        
        ap_get_sload(&sload);
        /* up_time in seconds */
        up_time = (apr_uint32_t) apr_time_sec(apr_time_now() -
                                   ap_scoreboard_image->global->restart_time);
    
        apr_strfsize((unsigned long)((float) (sload.bytes_served)
                                     / (float) up_time), bps);
    
        sd_notifyf(0, "READY=1\n"
                   "STATUS=Total requests: %lu; Idle/Busy workers %d/%d;"
                   "Requests/sec: %.3g; Bytes served/sec: %sB/sec\n",
                   sload.access_count, sload.idle, sload.busy,
                   ((float) sload.access_count) / (float) up_time, bps);
    
        return DECLINED;
    }
    
    static int ap_find_systemd_socket(process_rec * process, apr_port_t port) {
        int fdcount, fd;
        int sdc = sd_listen_fds(0);
    
        if (sdc < 0) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
                          "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
                          sdc);
            return -1;
        }
    
        if (sdc == 0) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
                          "find_systemd_socket: At least one socket must be set.");
            return -1;
        }
    
        fdcount = atoi(getenv("LISTEN_FDS"));
        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
            if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
                return fd;
            }
        }
    
        return -1;
    }
    
    static int ap_systemd_listen_fds(int unset_environment){
        return sd_listen_fds(unset_environment);
    }
    
    static void systemd_register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds);
        APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket);
    
        /* Enable ap_extended_status. */
        ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST);
        /* Signal service is ready. */
        ap_hook_post_config(systemd_post_config, NULL, NULL, APR_HOOK_REALLY_LAST);
        /* We know the PID in this hook ... */
        ap_hook_pre_mpm(systemd_pre_mpm, NULL, NULL, APR_HOOK_LAST);
        /* Used to update httpd's status line using sd_notifyf */
        ap_hook_monitor(systemd_monitor, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(systemd) = {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        systemd_register_hooks,
    };
    ������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/unix/mod_unixd.h����������������������������������������������������������0000664�0001751�0001751�00000002132�11637105701�020330� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mod_unixd.h
     * @brief common stuff that unix MPMs will want
     *
     * @addtogroup APACHE_OS_UNIX
     * @{
     */
    
    #ifndef MOD_UNIXD_H
    #define MOD_UNIXD_H
    
    #include "ap_config.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    AP_DECLARE(int) ap_unixd_setup_child(void);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/unix/config5.m4�����������������������������������������������������������0000664�0001751�0001751�00000002134�15020012305�017752� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    APACHE_MODPATH_INIT(arch/unix)
    
    if ap_mpm_is_enabled "worker" \
       || ap_mpm_is_enabled "event" \
       || ap_mpm_is_enabled "prefork"; then
        unixd_mods_enable=yes
    else
        unixd_mods_enable=no
    fi
    
    APACHE_MODULE(unixd, unix specific support, , , $unixd_mods_enable)
    APACHE_MODULE(privileges, Per-virtualhost Unix UserIDs and enhanced security for Solaris, , , no, [
      AC_CHECK_HEADERS(priv.h, [ap_HAVE_PRIV_H="yes"], [ap_HAVE_PRIV_H="no"])
      if test $ap_HAVE_PRIV_H = "no"; then
        AC_MSG_WARN([Your system does not support privileges.])
        enable_privileges="no"
      fi
    ])
    
    APACHE_MODULE(systemd, Systemd support, , , no, [
      if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
        AC_MSG_WARN([Your system does not support systemd.])
        enable_systemd="no"
      else
        AC_CHECK_LIB(selinux, is_selinux_enabled, [
          AC_DEFINE(HAVE_SELINUX, 1, [Defined if SELinux is supported])
          APR_ADDTO(MOD_SYSTEMD_LDADD, [-lselinux])
        ])
    
        APR_ADDTO(MOD_SYSTEMD_LDADD, [$SYSTEMD_LIBS])
      fi
    ])
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/unix/Makefile.in����������������������������������������������������������0000664�0001751�0001751�00000000051�11737125415�020241� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/unix/mod_privileges.c�����������������������������������������������������0000664�0001751�0001751�00000052621�12661357032�021361� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <priv.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_protocol.h"
    #include "http_log.h"
    #include "mpm_common.h"
    #include "ap_mpm.h"
    #include "apr_strings.h"
    
    /* TODO - get rid of unixd dependency */
    #include "unixd.h"
    
    #define CFG_CHECK(x) if ((x) == -1) { \
        char msgbuf[128]; \
        apr_strerror(errno, msgbuf, sizeof(msgbuf)); \
        return apr_pstrdup(cmd->pool, msgbuf); \
    }
    #define CR_CHECK(x, y) if (x == -1) \
        ap_log_error(APLOG_MARK, APLOG_CRIT, errno, 0, y \
                     "Failed to initialise privileges")
    
    module AP_MODULE_DECLARE_DATA privileges_module;
    
    /* #define BIG_SECURITY_HOLE 1 */
    
    typedef enum { PRIV_UNSET, PRIV_FAST, PRIV_SECURE, PRIV_SELECTIVE } priv_mode;
    
    typedef struct {
        priv_set_t *priv;
        priv_set_t *child_priv;
        uid_t uid;
        gid_t gid;
        priv_mode mode;
    } priv_cfg;
    
    typedef struct {
        priv_mode mode;
    } priv_dir_cfg;
    
    static priv_set_t *priv_setid;
    static priv_set_t *priv_default = NULL;
    static int dtrace_enabled = 0;
    
    static apr_status_t priv_cfg_cleanup(void *CFG)
    {
        priv_cfg *cfg = CFG;
        priv_freeset(cfg->priv);
        priv_freeset(cfg->child_priv);
        return APR_SUCCESS;
    }
    static void *privileges_merge_cfg(apr_pool_t *pool, void *BASE, void *ADD)
    {
        /* inherit the mode if it's not set; the rest won't be inherited */
        priv_cfg *base = BASE;
        priv_cfg *add = ADD;
        priv_cfg *ret = apr_pmemdup(pool, add, sizeof(priv_cfg));
        ret->mode = (add->mode == PRIV_UNSET) ? base->mode : add->mode;
        return ret;
    }
    static void *privileges_create_cfg(apr_pool_t *pool, server_rec *s)
    {
        priv_cfg *cfg = apr_palloc(pool, sizeof(priv_cfg));
    
        /* Start at basic privileges all round. */
        cfg->priv = priv_str_to_set("basic", ",", NULL);
        cfg->child_priv = priv_str_to_set("basic", ",", NULL);
    
        /* By default, run in secure vhost mode.
         * That means dropping basic privileges we don't usually need.
         */
        CR_CHECK(priv_delset(cfg->priv, PRIV_FILE_LINK_ANY), APLOGNO(03160));
        CR_CHECK(priv_delset(cfg->priv, PRIV_PROC_INFO), APLOGNO(03161));
        CR_CHECK(priv_delset(cfg->priv, PRIV_PROC_SESSION), APLOGNO(03162));
    
    /* Hmmm, should CGI default to secure too ? */
    /*
        CR_CHECK(priv_delset(cfg->child_priv, PRIV_FILE_LINK_ANY), APLOGNO(03163));
        CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_INFO), APLOGNO(03164));
        CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_SESSION), APLOGNO(03165));
        CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_FORK), APLOGNO(03166));
        CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_EXEC), APLOGNO(03167));
    */
    
        /* we´ll use 0 for unset */
        cfg->uid = 0;
        cfg->gid = 0;
        cfg->mode = PRIV_UNSET;
        apr_pool_cleanup_register(pool, cfg, priv_cfg_cleanup,
                                  apr_pool_cleanup_null);
    
        /* top-level default_priv wants the top-level cfg */
        if (priv_default == NULL) {
            priv_default = cfg->priv;
        }
        return cfg;
    }
    static void *privileges_create_dir_cfg(apr_pool_t *pool, char *dummy)
    {
        priv_dir_cfg *cfg = apr_palloc(pool, sizeof(priv_dir_cfg));
        cfg->mode = PRIV_UNSET;
        return cfg;
    }
    static void *privileges_merge_dir_cfg(apr_pool_t *pool, void *BASE, void *ADD)
    {
        priv_dir_cfg *base = BASE;
        priv_dir_cfg *add = ADD;
        priv_dir_cfg *ret = apr_palloc(pool, sizeof(priv_dir_cfg));
        ret->mode = (add->mode == PRIV_UNSET) ? base->mode : add->mode;
        return ret;
    }
    
    static apr_status_t privileges_end_req(void *data)
    {
        request_rec *r = data;
        priv_cfg *cfg = ap_get_module_config(r->server->module_config,
                                             &privileges_module);
        priv_dir_cfg *dcfg = ap_get_module_config(r->per_dir_config,
                                                  &privileges_module);
    
        /* ugly hack: grab default uid and gid from unixd */
        extern unixd_config_rec ap_unixd_config;
    
        /* If we forked a child, we dropped privilege to revert, so
         * all we can do now is exit
         */
        if ((cfg->mode == PRIV_SECURE) ||
            ((cfg->mode == PRIV_SELECTIVE) && (dcfg->mode == PRIV_SECURE))) {
            exit(0);
        }
    
        /* if either user or group are not the default, restore them */
        if (cfg->uid || cfg->gid) {
            if (setppriv(PRIV_ON, PRIV_EFFECTIVE, priv_setid) == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02136)
                              "PRIV_ON failed restoring default user/group");
            }
            if (cfg->uid && (setuid(ap_unixd_config.user_id) == -1)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02137)
                              "Error restoring default userid");
            }
            if (cfg->gid && (setgid(ap_unixd_config.group_id) == -1)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02138)
                              "Error restoring default group");
            }
        }
    
        /* restore default privileges */
        if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_default) == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, APLOGNO(02139)
                          "Error restoring default privileges");
        }
        return APR_SUCCESS;
    }
    static int privileges_req(request_rec *r)
    {
        /* secure mode: fork a process to handle the request */
        apr_proc_t proc;
        apr_status_t rv;
        int exitcode;
        apr_exit_why_e exitwhy;
        int fork_req;
        priv_cfg *cfg = ap_get_module_config(r->server->module_config,
                                             &privileges_module);
    
        void *breadcrumb = ap_get_module_config(r->request_config,
                                                &privileges_module);
    
        if (!breadcrumb) {
            /* first call: this is the vhost */
            fork_req = (cfg->mode == PRIV_SECURE);
    
            /* set breadcrumb */
            ap_set_module_config(r->request_config, &privileges_module, &cfg->mode);
    
            /* If we have per-dir config, defer doing anything */
            if ((cfg->mode == PRIV_SELECTIVE)) {
                /* Defer dropping privileges 'til we have a directory
                 * context that'll tell us whether to fork.
                 */
                return DECLINED;
            }
        }
        else {
            /* second call is for per-directory. */
            priv_dir_cfg *dcfg;
            if ((cfg->mode != PRIV_SELECTIVE)) {
                /* Our fate was already determined for the vhost -
                 * nothing to do per-directory
                 */
                return DECLINED;
            }
            dcfg = ap_get_module_config(r->per_dir_config, &privileges_module);
            fork_req = (dcfg->mode == PRIV_SECURE);
        }
    
        if (fork_req) {
           rv = apr_proc_fork(&proc, r->pool);
            switch (rv) {
            case APR_INPARENT:
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02140)
                              "parent waiting for child");
                /* FIXME - does the child need to run synchronously?
                 * esp. if we enable mod_privileges with threaded MPMs?
                 * We do need at least to ensure r outlives the child.
                 */
                rv = apr_proc_wait(&proc, &exitcode, &exitwhy, APR_WAIT);
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02141) "parent: child %s",
                              (rv == APR_CHILD_DONE) ? "done" : "notdone");
    
                /* The child has taken responsibility for reading all input
                 * and sending all output.  So we need to bow right out,
                 * and even abandon "normal" housekeeping.
                 */
                r->eos_sent = 1;
                apr_table_unset(r->headers_in, "Content-Type");
                apr_table_unset(r->headers_in, "Content-Length");
                /* Testing with ab and 100k requests reveals no nasties
                 * so I infer we're not leaking anything like memory
                 * or file descriptors.  That's nice!
                 */
                return DONE;
            case APR_INCHILD:
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02142) "In child!");
                break;  /* now we'll drop privileges in the child */
            default:
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02143)
                              "Failed to fork secure child process!");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        /* OK, now drop privileges. */
    
        /* cleanup should happen even if something fails part-way through here */
        apr_pool_cleanup_register(r->pool, r, privileges_end_req,
                                  apr_pool_cleanup_null);
        /* set user and group if configured */
        if (cfg->uid || cfg->gid) {
            if (setppriv(PRIV_ON, PRIV_EFFECTIVE, priv_setid) == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02144)
                              "No privilege to set user/group");
            }
            /* if we should be able to set these but can't, it could be
             * a serious security issue.  Bail out rather than risk it!
             */
            if (cfg->uid && (setuid(cfg->uid) == -1)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02145)
                              "Error setting userid");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            if (cfg->gid && (setgid(cfg->gid) == -1)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02146)
                              "Error setting group");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
        /* set vhost's privileges */
        if (setppriv(PRIV_SET, PRIV_EFFECTIVE, cfg->priv) == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, APLOGNO(02147)
                          "Error setting effective privileges");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* ... including those of any subprocesses */
        if (setppriv(PRIV_SET, PRIV_INHERITABLE, cfg->child_priv) == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, APLOGNO(02148)
                          "Error setting inheritable privileges");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        if (setppriv(PRIV_SET, PRIV_LIMIT, cfg->child_priv) == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, APLOGNO(02149)
                          "Error setting limit privileges");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* If we're in a child process, drop down PPERM too */
        if (fork_req) {
            if (setppriv(PRIV_SET, PRIV_PERMITTED, cfg->priv) == -1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, APLOGNO(02150)
                              "Error setting permitted privileges");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        return OK;
    }
    #define PDROP_CHECK(x) if (x == -1) { \
            ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s, APLOGNO(02151) \
                         "Error dropping privileges"); \
            return !OK; \
        }
    
    static int privileges_drop_first(apr_pool_t *pool, server_rec *s)
    {
        /* We need to set privileges before mod_unixd,
         * 'cos otherwise setuid will wipe our privilege to do so
         */
        priv_cfg *spcfg;
        server_rec *sp;
        priv_set_t *ppriv = priv_allocset();
    
        /* compute ppriv from the union of all the vhosts plus setid */
        priv_copyset(priv_setid, ppriv);
        for (sp = s; sp != NULL; sp=sp->next) {
            spcfg = ap_get_module_config(sp->module_config, &privileges_module);
            priv_union(spcfg->priv, ppriv);
        }
        PDROP_CHECK(setppriv(PRIV_SET, PRIV_PERMITTED, ppriv))
        PDROP_CHECK(setppriv(PRIV_SET, PRIV_EFFECTIVE, ppriv))
        priv_freeset(ppriv);
    
        return OK;
    }
    static int privileges_drop_last(apr_pool_t *pool, server_rec *s)
    {
        /* Our config stuff has set the privileges we need, so now
         * we just set them to those of the parent server_rec
         *
         * This has to happen after mod_unixd, 'cos mod_unixd needs
         * privileges we drop here.
         */
        priv_cfg *cfg = ap_get_module_config(s->module_config, &privileges_module);
    
        /* defaults - the default vhost */
        PDROP_CHECK(setppriv(PRIV_SET, PRIV_LIMIT, cfg->child_priv))
        PDROP_CHECK(setppriv(PRIV_SET, PRIV_INHERITABLE, cfg->child_priv))
        PDROP_CHECK(setppriv(PRIV_SET, PRIV_EFFECTIVE, cfg->priv))
    
        return OK;
    }
    static apr_status_t privileges_term(void *rec)
    {
        priv_freeset(priv_setid);
        return APR_SUCCESS;
    }
    static int privileges_postconf(apr_pool_t *pconf, apr_pool_t *plog,
                                   apr_pool_t *ptemp, server_rec *s)
    {
        priv_cfg *cfg;
        server_rec *sp;
    
        /* if we have dtrace enabled, merge it into everything */
        if (dtrace_enabled) {
            for (sp = s; sp != NULL; sp = sp->next) {
                cfg = ap_get_module_config(sp->module_config, &privileges_module);
                CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_KERNEL), APLOGNO(03168));
                CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_PROC), APLOGNO(03169));
                CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_USER), APLOGNO(03170));
                CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_KERNEL), APLOGNO(03171));
                CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_PROC), APLOGNO(03172));
                CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_USER), APLOGNO(03173));
            }
            CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_KERNEL), APLOGNO(03174));
            CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_PROC), APLOGNO(03175));
            CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_USER), APLOGNO(03176));
        }
    
        /* set up priv_setid for per-request use */
        priv_setid = priv_allocset();
        apr_pool_cleanup_register(pconf, NULL, privileges_term,
                                  apr_pool_cleanup_null);
        priv_emptyset(priv_setid);
        if (priv_addset(priv_setid, PRIV_PROC_SETID) == -1) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, errno, ptemp, APLOGNO(02152)
                          "priv_addset");
            return !OK;
        }
        return OK;
    }
    static int privileges_init(apr_pool_t *pconf, apr_pool_t *plog,
                               apr_pool_t *ptemp)
    {
        /* refuse to work if the MPM is threaded */
        int threaded;
        int rv = ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_NOTICE, rv, ptemp, APLOGNO(02153)
                          "mod_privileges: unable to determine MPM characteristics."
                          "  Please ensure you are using a non-threaded MPM "
                          "with this module.");
        }
        if (threaded) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, ptemp, APLOGNO(02154)
                          "mod_privileges is not compatible with a threaded MPM.");
            return !OK;
        }
        return OK;
    }
    static void privileges_hooks(apr_pool_t *pool)
    {
        ap_hook_post_read_request(privileges_req, NULL, NULL,
                                  APR_HOOK_REALLY_FIRST);
        ap_hook_header_parser(privileges_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
        ap_hook_drop_privileges(privileges_drop_first, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_drop_privileges(privileges_drop_last, NULL, NULL, APR_HOOK_LAST);
        ap_hook_post_config(privileges_postconf, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_pre_config(privileges_init, NULL, NULL, APR_HOOK_FIRST);
    }
    
    static const char *vhost_user(cmd_parms *cmd, void *dir, const char *arg)
    {
        priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                             &privileges_module);
        cfg->uid = ap_uname2id(arg);
        if (cfg->uid == 0) {
            return apr_pstrcat(cmd->pool, "Invalid userid for VHostUser: ",
                               arg, NULL);
        }
        return NULL;
    }
    static const char *vhost_group(cmd_parms *cmd, void *dir, const char *arg)
    {
        priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                             &privileges_module);
        cfg->gid = ap_gname2id(arg);
        if (cfg->uid == 0) {
            return apr_pstrcat(cmd->pool, "Invalid groupid for VHostGroup: ",
                               arg, NULL);
        }
        return NULL;
    }
    static const char *vhost_secure(cmd_parms *cmd, void *dir, int arg)
    {
        priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                             &privileges_module);
        if (!arg) {
            /* add basic privileges, excluding those covered by cgimode */
            CFG_CHECK(priv_addset(cfg->priv, PRIV_FILE_LINK_ANY));
            CFG_CHECK(priv_addset(cfg->priv, PRIV_PROC_INFO));
            CFG_CHECK(priv_addset(cfg->priv, PRIV_PROC_SESSION));
        }
        return NULL;
    }
    static const char *vhost_cgimode(cmd_parms *cmd, void *dir, const char *arg)
    {
        priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                             &privileges_module);
        if (!strcasecmp(arg, "on")) {
            /* default - nothing to do */
        }
        else if (!strcasecmp(arg, "off")) {
            /* drop fork+exec privs */
            CFG_CHECK(priv_delset(cfg->priv, PRIV_PROC_FORK));
            CFG_CHECK(priv_delset(cfg->priv, PRIV_PROC_EXEC));
        }
        else if (!strcasecmp(arg, "secure")) {
            /* deny privileges to CGI procs */
            CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_FORK));
            CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_EXEC));
            CFG_CHECK(priv_delset(cfg->child_priv, PRIV_FILE_LINK_ANY));
            CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_INFO));
            CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_SESSION));
        }
        else {
            return "VHostCGIMode must be On, Off or Secure";
        }
    
        return NULL;
    }
    static const char *dtraceenable(cmd_parms *cmd, void *dir, int arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
        dtrace_enabled = arg;
        return NULL;
    }
    
    static const char *privs_mode(cmd_parms *cmd, void *dir, const char *arg)
    {
        priv_mode mode = PRIV_UNSET;
        if (!strcasecmp(arg, "FAST")) {
            mode = PRIV_FAST;
        }
        else if (!strcasecmp(arg, "SECURE")) {
            mode = PRIV_SECURE;
        }
        else if (!strcasecmp(arg, "SELECTIVE")) {
            mode = PRIV_SELECTIVE;
        }
    
        if (cmd->path) {
            /* In a directory context, set the per_dir_config */
            priv_dir_cfg *cfg = dir;
            cfg->mode = mode;
            if ((mode == PRIV_UNSET) || (mode == PRIV_SELECTIVE)) {
                return "PrivilegesMode in a Directory context must be FAST or SECURE";
            }
        }
        else {
            /* In a global or vhost context, set the server config */
            priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                                 &privileges_module);
            cfg->mode = mode;
            if (mode == PRIV_UNSET) {
                return "PrivilegesMode must be FAST, SECURE or SELECTIVE";
            }
        }
        return NULL;
    }
    
    #ifdef BIG_SECURITY_HOLE
    static const char *vhost_privs(cmd_parms *cmd, void *dir, const char *arg)
    {
        priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                             &privileges_module);
        const char *priv = arg;
    
        if (*priv == '-') {
            CFG_CHECK(priv_delset(cfg->priv, priv+1));
        }
        else if (*priv == '+') {
            CFG_CHECK(priv_addset(cfg->priv, priv+1));
        }
        else {
            priv_emptyset(cfg->priv);
            CFG_CHECK(priv_addset(cfg->priv, priv));
        }
        return NULL;
    }
    static const char *vhost_cgiprivs(cmd_parms *cmd, void *dir, const char *arg)
    {
        priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                             &privileges_module);
        const char *priv = arg;
        if (*priv == '-') {
            CFG_CHECK(priv_delset(cfg->child_priv, priv+1));
        }
        else if (*priv == '+') {
            CFG_CHECK(priv_addset(cfg->child_priv, priv+1));
        }
        else {
            priv_emptyset(cfg->child_priv);
            CFG_CHECK(priv_addset(cfg->child_priv, priv));
        }
        return NULL;
    }
    #endif
    static const command_rec privileges_cmds[] = {
        AP_INIT_TAKE1("VHostUser", vhost_user, NULL, RSRC_CONF,
                      "Userid under which the virtualhost will run"),
        AP_INIT_TAKE1("VHostGroup", vhost_group, NULL, RSRC_CONF,
                      "Group under which the virtualhost will run"),
        AP_INIT_FLAG("VHostSecure", vhost_secure, NULL, RSRC_CONF,
                     "Run in enhanced security mode (default ON)"),
        AP_INIT_TAKE1("VHostCGIMode", vhost_cgimode, NULL, RSRC_CONF,
                      "Enable fork+exec for this virtualhost (Off|Secure|On)"),
        AP_INIT_FLAG("DTracePrivileges", dtraceenable, NULL, RSRC_CONF,
                     "Enable DTrace"),
        AP_INIT_TAKE1("PrivilegesMode", privs_mode, NULL, RSRC_CONF|ACCESS_CONF,
                      "tradeoff performance vs security (fast or secure)"),
    #ifdef BIG_SECURITY_HOLE
        AP_INIT_ITERATE("VHostPrivs", vhost_privs, NULL, RSRC_CONF,
                        "Privileges available in the (virtual) server"),
        AP_INIT_ITERATE("VHostCGIPrivs", vhost_cgiprivs, NULL, RSRC_CONF,
                        "Privileges available to external programs"),
    #endif
        {NULL}
    };
    AP_DECLARE_MODULE(privileges) = {
        STANDARD20_MODULE_STUFF,
        privileges_create_dir_cfg,
        privileges_merge_dir_cfg,
        privileges_create_cfg,
        privileges_merge_cfg,
        privileges_cmds,
        privileges_hooks
    };
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016163� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/mod_isapi.dep�������������������������������������������������������0000664�0001751�0001751�00000004464�12674411515�020625� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_isapi.mak
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    
    .\mod_isapi.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_expr.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_core.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\http_protocol.h"\
    	"..\..\..\include\http_request.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\mod_core.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_script.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_isapi.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/mod_isapi.h���������������������������������������������������������0000664�0001751�0001751�00000025660�13623622544�020306� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_isapi.h
     * @brief ISAPI module extension to Apache
     *
     * @defgroup MOD_ISAPI mod_isapi
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #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
     * necessary 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 overridden
     * 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 Extended 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 optionally 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, its return value is ignored.
     */
    #define HSE_TERM_MUST_UNLOAD      1
    #define HSE_TERM_ADVISORY_UNLOAD  2
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif  /* !MOD_ISAPI_H */
    /** @} */
    
    ��������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/mod_isapi.c���������������������������������������������������������0000664�0001751�0001751�00000176624�14245656653�020321� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <akosut@apache.org>, significant overhauls and
     * redesign by William Rowe <wrowe@covalent.net>, 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 extensions" 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
         * <Directory "c:/webapps/isapi">
         *     ISAPICacheFile myapp.dll anotherapp.dll thirdapp.dll
         * </Directory>
         * 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, APLOGNO(02103)
                         "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, APLOGNO(02104)
                         "unable to stat, skipping %s", fspec);
            return NULL;
        }
        if (tmp.filetype != APR_REG) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(02105)
                         "not a regular file, skipping %s", fspec);
            return NULL;
        }
    
        /* Load the extension 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, APLOGNO(02106)
                         "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 concatenated 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 overridable, 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 = 0x500; /* 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, APLOGNO(02107)
                         "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, APLOGNO(02108)
                         "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, APLOGNO(02109)
                         "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");
        apr_set_os_error(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, APLOGNO(02110)
                         "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;
    };
    
    static int APR_THREAD_FUNC regfnGetServerVariable(isapi_cid    *cid,
                                                      char         *variable_name,
                                                      void         *buf_ptr,
                                                      apr_uint32_t *buf_size)
    {
        request_rec *r = cid->r;
        const char *result;
        char *buf_data = (char*)buf_ptr;
        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;
                apr_set_os_error(APR_FROM_OS_ERROR(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);
                    buf_data += strlen(elts[i].key);
                    *(buf_data++) = ':';
                    strcpy(buf_data, elts[i].val);
                    buf_data += strlen(elts[i].val);
                    *(buf_data++) = '\r';
                    *(buf_data++) = '\n';
                }
            }
    
            *(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;
                apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER));
                return 0;
            }
    
            for (i = 0; i < arr->nelts; i++) {
                strcpy(buf_data, elts[i].key);
                buf_data += strlen(elts[i].key);
                *(buf_data++) = ':';
                *(buf_data++) = ' ';
                strcpy(buf_data, elts[i].val);
                buf_data += strlen(elts[i].val);
                *(buf_data++) = '\r';
                *(buf_data++) = '\n';
            }
            *(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;
                apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER));
                return 0;
            }
            strcpy(buf_data, result);
            *buf_size = len + 1;
            return 1;
        }
    
        /* Not Found */
        apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_INDEX));
        return 0;
    }
    
    static int APR_THREAD_FUNC regfnReadClient(isapi_cid    *cid,
                                               void         *buf_data,
                                               apr_uint32_t *buf_size)
    {
        request_rec *r = cid->r;
        apr_uint32_t read = 0;
        int res = 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;
        }
    
        *buf_size = read;
        if (res < 0) {
            apr_set_os_error(APR_FROM_OS_ERROR(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;
        int res;
        int old_status;
        const 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
         */
        old_status = cid->r->status;
    
        if (stat) {
            res = ap_scan_script_header_err_strs_ex(cid->r, NULL,
                    APLOG_MODULE_INDEX, &termch, &termarg, stat, head, NULL);
        }
        else {
            res = ap_scan_script_header_err_strs_ex(cid->r, NULL,
                    APLOG_MODULE_INDEX, &termch, &termarg, head, NULL);
        }
    
        /* Set our status. */
        if (res) {
            /* This is an immediate error result from the parser
             */
            cid->r->status = res;
            cid->r->status_line = ap_get_status_line(cid->r->status);
            cid->ecb->dwHttpStatusCode = cid->r->status;
        }
        else if (cid->r->status) {
            /* We have a status in r->status, so let's just use it.
             * This is likely to be the Status: parsed above, and
             * may also be a delayed error result from the parser.
             * If it was filled in, status_line should also have
             * been filled in.
             */
            cid->ecb->dwHttpStatusCode = cid->r->status;
        }
        else if (cid->ecb->dwHttpStatusCode
                  && cid->ecb->dwHttpStatusCode != HTTP_OK) {
            /* 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 if (old_status) {
            /* Well... either there is no dwHttpStatusCode or it's HTTP_OK.
             * In any case, we don't have a good status to return yet...
             * Perhaps the one we came in with will be better. Let's use it,
             * if we were given one (note this is a pedantic case, it would
             * normally be covered above unless the scan script code unset
             * the r->status). Should there be a check here as to whether
             * we are setting a valid response code?
             */
            cid->r->status = old_status;
            cid->r->status_line = ap_get_status_line(cid->r->status);
            cid->ecb->dwHttpStatusCode = cid->r->status;
        }
        else {
            /* None of dwHttpStatusCode, the parser's r->status nor the
             * old value of r->status were helpful, and nothing was decoded
             * from Status: string passed to us.  Let's just say HTTP_OK
             * and get the data out, this was the isapi dev's oversight.
             */
            cid->r->status = HTTP_OK;
            cid->r->status_line = ap_get_status_line(cid->r->status);
            cid->ecb->dwHttpStatusCode = cid->r->status;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, cid->r, APLOGNO(02111)
                    "Could not determine HTTP response code; using %d",
                    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;
    }
    
    static int APR_THREAD_FUNC regfnWriteClient(isapi_cid    *cid,
                                                void         *buf_ptr,
                                                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;
        char *buf_data = (char*)buf_ptr;
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv = APR_SUCCESS;
    
        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, buf_data, 0, buf_size);
            if (ate < 0) {
                apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
                return 0;
            }
    
            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 (rv != APR_SUCCESS)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02984)
                              "WriteClient ap_pass_brigade failed: %s",
                              r->filename);
        }
    
        if ((flags & HSE_IO_ASYNC) && cid->completion) {
            if (rv == APR_SUCCESS) {
                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 == APR_SUCCESS);
    }
    
    static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid    *cid,
                                                          apr_uint32_t  HSE_code,
                                                          void         *buf_ptr,
                                                          apr_uint32_t *buf_size,
                                                          apr_uint32_t *data_type)
    {
        request_rec *r = cid->r;
        conn_rec *c = r->connection;
        char *buf_data = (char*)buf_ptr;
        request_rec *subreq;
        apr_status_t rv;
    
        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 equivalent per the Jan 2000 SDK.
             *          They most definitely 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 = "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! */
            buf_data = apr_pstrdup(r->pool, (char*)buf_data);
            ap_internal_redirect(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) {
                apr_set_os_error(APR_FROM_OS_ERROR(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);
                rv = ap_pass_brigade(cid->r->output_filters, bb);
                cid->response_sent = 1;
                if (rv != APR_SUCCESS)
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(03177)
                                  "ServerSupportFunction "
                                  "HSE_REQ_SEND_RESPONSE_HEADER "
                                  "ap_pass_brigade failed: %s", r->filename);
                return (rv == APR_SUCCESS);
            }
            /* Deliberately hold off sending 'just the headers' to begin to
             * accumulate the body and speed up the overall response, or at
             * least wait for the end the session.
             */
            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, APLOGNO(02671)
                              "ServerSupportFunction "
                              "HSE_REQ_DONE_WITH_SESSION is not supported: %s",
                              r->filename);
            }
            apr_set_os_error(APR_FROM_OS_ERROR(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(cid->r->pool, file, *buf_size), r, NULL);
    
            if (!subreq->filename) {
                ap_destroy_sub_req(subreq);
                return 0;
            }
    
            len = (apr_uint32_t)strlen(subreq->filename);
    
            if ((subreq->finfo.filetype == APR_DIR)
                  && (!subreq->path_info)
                  && (subreq->filename[len - 1] != '/'))
                file = apr_pstrcat(cid->r->pool, subreq->filename, "/", NULL);
            else
                file = apr_pstrcat(cid->r->pool, subreq->filename,
                                                  subreq->path_info, NULL);
    
            ap_destroy_sub_req(subreq);
    
    #ifdef WIN32
            /* We need to make this a real Windows path name */
            apr_filepath_merge(&file, "", file, APR_FILEPATH_NATIVE, r->pool);
    #endif
    
            *buf_size = apr_cpystrn(buf_data, file, *buf_size) - buf_data;
    
            return 1;
        }
    
        case HSE_REQ_GET_SSPI_INFO:
            if (cid->dconf.log_unsupported)
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02672)
                               "ServerSupportFunction HSE_REQ_GET_SSPI_INFO "
                               "is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(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, APLOGNO(02985)
                              "%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, APLOGNO(02673)
                          "ServerSupportFunction HSE_REQ_IO_COMPLETION "
                          "is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(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_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, APLOGNO(02674)
                             "ServerSupportFunction HSE_REQ_TRANSMIT_FILE "
                             "as HSE_IO_ASYNC is not supported: %s", r->filename);
                apr_set_os_error(APR_FROM_OS_ERROR(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) {
                    apr_set_os_error(APR_FROM_OS_ERROR(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);
                    apr_set_os_error(APR_FROM_OS_ERROR(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;
            apr_brigade_insert_file(bb, fd, tf->Offset, fsize, r->pool);
    
            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);
            rv = ap_pass_brigade(r->output_filters, bb);
            cid->response_sent = 1;
            if (rv != APR_SUCCESS)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(03178)
                              "ServerSupportFunction "
                              "HSE_REQ_TRANSMIT_FILE "
                              "ap_pass_brigade failed: %s", r->filename);
    
            /* 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 == APR_SUCCESS) {
                        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 == APR_SUCCESS) {
                        cid->completion(cid->ecb, cid->completion_arg,
                                        sent, ERROR_SUCCESS);
                    }
                    else {
                        cid->completion(cid->ecb, cid->completion_arg,
                                        sent, ERROR_WRITE_FAULT);
                    }
                }
            }
            return (rv == APR_SUCCESS);
        }
    
        case HSE_REQ_REFRESH_ISAPI_ACL:
            if (cid->dconf.log_unsupported)
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02675)
                              "ServerSupportFunction "
                              "HSE_REQ_REFRESH_ISAPI_ACL "
                              "is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(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 = 0;
            if (!cid->dconf.fake_async) {
                if (cid->dconf.log_unsupported)
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02986)
                                  "asynchronous I/O not supported: %s",
                                  r->filename);
                apr_set_os_error(APR_FROM_OS_ERROR(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) {
                /* XXX: Many authors issue their next HSE_REQ_ASYNC_READ_CLIENT
                 * within the completion logic.  An example is MS's own PSDK
                 * sample web/iis/extensions/io/ASyncRead.  This potentially
                 * leads to stack exhaustion.  To refactor, the notification
                 * logic needs to move to isapi_handler() - differentiating
                 * the cid->completed event with a new flag to indicate
                 * an async-notice versus the async request completed.
                 */
                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, APLOGNO(02676)
                              "ServerSupportFunction "
                              "HSE_REQ_GET_IMPERSONATION_TOKEN "
                              "is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(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, APLOGNO(02677)
                              "ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE"
                              " is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(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, APLOGNO(02678)
                              "ServerSupportFunction "
                              "HSE_REQ_GET_CERT_INFO_EX "
                              "is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(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) {
                apr_set_os_error(APR_FROM_OS_ERROR(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);
                rv = ap_pass_brigade(cid->r->output_filters, bb);
                cid->response_sent = 1;
                if (rv != APR_SUCCESS)
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(03179)
                                  "ServerSupportFunction "
                                  "HSE_REQ_SEND_RESPONSE_HEADER_EX "
                                  "ap_pass_brigade failed: %s", r->filename);
                return (rv == APR_SUCCESS);
            }
            /* Deliberately hold off sending 'just the headers' to begin to
             * accumulate the body and speed up the overall response, or at
             * least wait for the end the session.
             */
            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, APLOGNO(02679)
                              "ServerSupportFunction "
                              "HSE_REQ_CLOSE_CONNECTION "
                              "is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(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, APLOGNO(02680)
                              "ServerSupportFunction "
                              "HSE_REQ_EXTENSION_TRIGGER "
                              "is not supported: %s", r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
            return 0;
    
        default:
            if (cid->dconf.log_unsupported)
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02681)
                              "ServerSupportFunction (%d) not supported: "
                              "%s", HSE_code, r->filename);
            apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
            return 0;
        }
    }
    
    /**********************************************************
     *
     *  ISAPI Module request invocation section
     *
     **********************************************************/
    
    static 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") == 0))
            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 = regfnGetServerVariable;
        cid->ecb->WriteClient = regfnWriteClient;
        cid->ecb->ReadClient = regfnReadClient;
        cid->ecb->ServerSupportFunction = regfnServerSupportFunction;
    
        /* Set up client input */
        res = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR);
        if (res) {
            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, (char*)cid->ecb->lpbData + read,
                                            cid->ecb->cbAvailable - read)) > 0)) {
                read += res;
            }
    
            if (res < 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, APLOGNO(02112)
                              "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) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02113)
                          "%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, APLOGNO(02114)
                                   "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.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), r, APLOGNO(02115)
                              "HSE_STATUS_ERROR result from "
                              "HttpExtensionProc(): %s", r->filename);
                r->status = HTTP_INTERNAL_SERVER_ERROR;
                break;
    
            default:
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), r, APLOGNO(02116)
                              "unrecognized result code %d "
                              "from HttpExtensionProc(): %s ",
                              rv, r->filename);
                r->status = HTTP_INTERNAL_SERVER_ERROR;
                break;
        }
    
        /* Flush the response now, including headers-only responses */
        if (cid->headers_set || cid->response_sent) {
            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);
            rv = ap_pass_brigade(r->output_filters, bb);
            cid->response_sent = 1;
    
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02117)
                              "ap_pass_brigade failed to "
                              "complete the response: %s ", r->filename);
            }
    
            return OK; /* NOT 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 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, APLOGNO(02118)
                         "could not create the isapi cache pool");
            return APR_EGENERAL;
        }
        apr_pool_tag(loaded.pool, "mod_isapi_load");
    
        loaded.hash = apr_hash_make(loaded.pool);
        if (!loaded.hash) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(02119)
                         "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, APLOG_ERR, rv, NULL, APLOGNO(02682)
                         "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);
    }
    
    AP_DECLARE_MODULE(isapi) = {
       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 */
    };
    ������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/mod_win32.c���������������������������������������������������������0000664�0001751�0001751�00000046443�12661357032�020136� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    /*
     * 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);
                    prep_string((const char**)&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);
                prep_string((const char**)&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 ? APLOGNO(03180) "No ExecCGI verb found for files of type '%s'."
                            : APLOGNO(03181) "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, APLOGNO(02100)
                              "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, APLOGNO(02101)
                              "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...
             * we check here also for '! so that .vbs scripts can work as CGI.
             */
            if ((bytes >= 2) && ((buffer[0] == '#') || (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, APLOGNO(02102)
                          "%s is not executable; ensure interpreted scripts have "
                          "\"#!\" or \"'!\" 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 (elts[i].key && *elts[i].key && *elts[i].val
                    && !(strncmp(elts[i].key, "REMOTE_", 7) == 0
                    || strcmp(elts[i].key, "GATEWAY_INTERFACE") == 0
                    || strcmp(elts[i].key, "REQUEST_METHOD") == 0
                    || strcmp(elts[i].key, "SERVER_ADDR") == 0
                    || strcmp(elts[i].key, "SERVER_PORT") == 0
                    || strcmp(elts[i].key, "SERVER_PROTOCOL") == 0)) {
                prep_string((const char**) &elts[i].val, r->pool);
            }
        }
        return APR_SUCCESS;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command);
    }
    
    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 }
    };
    
    AP_DECLARE_MODULE(win32) = {
       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 */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/config.m4�����������������������������������������������������������0000664�0001751�0001751�00000000361�10150161574�017660� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/mod_isapi.mak�������������������������������������������������������0000664�0001751�0001751�00000023512�12701473373�020621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_isapi.dsp
    !IF "$(CFG)" == ""
    CFG=mod_isapi - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_isapi - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_isapi - Win32 Release" && "$(CFG)" != "mod_isapi - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_isapi - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_isapi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_isapi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_isapi.obj"
    	-@erase "$(INTDIR)\mod_isapi.res"
    	-@erase "$(INTDIR)\mod_isapi_src.idb"
    	-@erase "$(INTDIR)\mod_isapi_src.pdb"
    	-@erase "$(OUTDIR)\mod_isapi.exp"
    	-@erase "$(OUTDIR)\mod_isapi.lib"
    	-@erase "$(OUTDIR)\mod_isapi.pdb"
    	-@erase "$(OUTDIR)\mod_isapi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_isapi_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_isapi.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_isapi.so" /d LONG_NAME="isapi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_isapi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_isapi.pdb" /debug /out:"$(OUTDIR)\mod_isapi.so" /implib:"$(OUTDIR)\mod_isapi.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_isapi.obj" \
    	"$(INTDIR)\mod_isapi.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_isapi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_isapi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_isapi.so"
       if exist .\Release\mod_isapi.so.manifest mt.exe -manifest .\Release\mod_isapi.so.manifest -outputresource:.\Release\mod_isapi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_isapi - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_isapi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_isapi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_isapi.obj"
    	-@erase "$(INTDIR)\mod_isapi.res"
    	-@erase "$(INTDIR)\mod_isapi_src.idb"
    	-@erase "$(INTDIR)\mod_isapi_src.pdb"
    	-@erase "$(OUTDIR)\mod_isapi.exp"
    	-@erase "$(OUTDIR)\mod_isapi.lib"
    	-@erase "$(OUTDIR)\mod_isapi.pdb"
    	-@erase "$(OUTDIR)\mod_isapi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_isapi_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_isapi.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_isapi.so" /d LONG_NAME="isapi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_isapi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_isapi.pdb" /debug /out:"$(OUTDIR)\mod_isapi.so" /implib:"$(OUTDIR)\mod_isapi.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_isapi.obj" \
    	"$(INTDIR)\mod_isapi.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_isapi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_isapi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_isapi.so"
       if exist .\Debug\mod_isapi.so.manifest mt.exe -manifest .\Debug\mod_isapi.so.manifest -outputresource:.\Debug\mod_isapi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_isapi.dep")
    !INCLUDE "mod_isapi.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_isapi.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_isapi - Win32 Release" || "$(CFG)" == "mod_isapi - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_isapi - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\arch\win32"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\arch\win32"
    
    !ELSEIF  "$(CFG)" == "mod_isapi - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\arch\win32"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\arch\win32"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_isapi - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\arch\win32"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\arch\win32"
    
    !ELSEIF  "$(CFG)" == "mod_isapi - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\arch\win32"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\arch\win32"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_isapi - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\arch\win32"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\arch\win32"
    
    !ELSEIF  "$(CFG)" == "mod_isapi - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\arch\win32"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\arch\win32"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_isapi - Win32 Release"
    
    
    "$(INTDIR)\mod_isapi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_isapi.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_isapi.so" /d LONG_NAME="isapi_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_isapi - Win32 Debug"
    
    
    "$(INTDIR)\mod_isapi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_isapi.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_isapi.so" /d LONG_NAME="isapi_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_isapi.c
    
    "$(INTDIR)\mod_isapi.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/Makefile.in���������������������������������������������������������0000664�0001751�0001751�00000000267�10150161574�020223� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/win32/mod_isapi.dsp�������������������������������������������������������0000664�0001751�0001751�00000011032�10551346420�020622� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_isapi.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_isapi.so" /d LONG_NAME="isapi_module for Apache"
    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 /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 /out:".\Release\mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_isapi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_isapi.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_isapi.so" /d LONG_NAME="isapi_module for Apache"
    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 /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 /out:".\Debug\mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_isapi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/netware/������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016666� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/netware/mod_nw_ssl.c������������������������������������������������������0000664�0001751�0001751�00000120605�12757564422�021206� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 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
     *
     * The module also supports RFC 2817 / TLS Upgrade for HTTP 1.1.
     * For this add a "NWSSLUpgradeable" 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:
     *
     *          NWSSLUpgradeable 8080 "SSL CertificateIP"
     *          NWSSLUpgradeable 123.45.67.89:8080 mycert
     *  
     */
    
    #define WS_SSL
    
    #define  MAX_ADDRESS  512
    #define  MAX_KEY       80
    
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_connection.h"
    #include "http_core.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "ap_listen.h"
    #include "apr_strings.h"
    #include "apr_portable.h"
    #include "apr_optional.h"
    
    #include <unilib.h>
    
    #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 <address>[: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;
        char addr[MAX_ADDRESS];
        struct sslserveropts opts;
        unsigned int optParam;
        WSAPROTOCOL_INFO SecureProtoInfo;
    
        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,
                         APLOGNO(02120)
                         "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,
                             APLOGNO(02121)
                             "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,
                         APLOGNO(02122)
                         "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,
                             APLOGNO(02123)
                             "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;
    }
    
    static 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, APLOGNO(02124)
                         "Error: %d with WSAIoctl(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 successful */
        if (SOCKET_ERROR == rcode ) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, APLOGNO(02125)
                     "Error: %d with WSAIoctl(SO_TLS_SET_CLIENT)",
                     WSAGetLastError());
        }
        return rcode;
    }
    
    static 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, APLOGNO(02126)
                         "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, APLOGNO(02127)
                         "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, APLOGNO(02128)
                         "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 :<port-number>";
    
            *(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;
        }
    
        apr_table_add(sc->sltable, ports, addr);
    
        /* 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;
        }
    
        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);
        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 :<port-number>";
    
            *(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 = 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;
        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;
    
        /* 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 need 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, APLOGNO(02129)
                                     "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, APLOGNO(02130)
                             "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)
    {
        if (!isSecure(r) && !isSecureUpgraded(r))
            return DECLINED;
    
        apr_table_setn(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_setn(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_ADDR"))
                    result = r->useragent_ip;
                else if (strcEQ(var, "REMOTE_HOST"))
                    result = ap_get_useragent_host(r, 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_for_url(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;
        }
    
        /*
         * 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_banner();
            else if (strcEQ(var, "API_VERSION")) {
                result = apr_itoa(p, MODULE_MAGIC_NUMBER_MAJOR);
                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);
    
        if (!r) {
            /*
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(02131)
                         "Unable to get upgradeable socket handle");
            */
            return ap_pass_brigade(f->next, bb);
        }
    
        /* 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");
    
        csd_data = (secsocket_data*)ap_get_module_config(r->connection->conn_config, &nwssl_module);
        csd = csd_data->csd;
    
        /* Send the interim 101 response. */
        upgradebb = apr_brigade_create(r->pool, f->c->bucket_alloc);
    
        ap_fputs(f->next, upgradebb, SWITCH_STATUS_LINE CRLF
                 UPGRADE_HEADER CRLF CONNECTION_HEADER CRLF CRLF);
    
        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, APLOGNO(02132)
                          "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, APLOGNO(02133)
                         "Upgradeable socket handle not found");
            return AP_FILTER_ERROR;
        }
    
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, APLOGNO(02134)
                     "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);
    }
    
    AP_DECLARE_MODULE(nwssl) =
    {
        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
    };
    
    ���������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/netware/libprews.c��������������������������������������������������������0000664�0001751�0001751�00000004542�11546464734�020672� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <netware.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;
    #endif
    }
    
    int  _NonAppCheckUnload( void )
    {
        return 0;
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/arch/netware/mod_netware.c�����������������������������������������������������0000664�0001751�0001751�00000015363�12604740124�021334� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "mpm_common.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_setn(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; i<len; i++) {
                if (CGIhdlr[i] == '\\') {
                    CGIhdlr[i] = '/';
                }
            }
        }
    
        apr_table_set(m->file_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;
        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 match 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, APLOGNO(02135)
                      "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 int
    netware_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                     apr_pool_t *ptemp)
    {
        ap_sys_privileges_handlers(1);
        return OK;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command);
        ap_hook_pre_config(netware_pre_config,
                           NULL, NULL, APR_HOOK_FIRST);
    }
    
    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 }
    };
    
    AP_DECLARE_MODULE(netware) = {
       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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/���������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015056� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016002� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/props.c���������������������������������������������������������������0000664�0001751�0001751�00000117546�14357025053�017321� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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<index>", 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:
    **
    **     <prop>
    **       <propname1>value</propname1>
    **       <propname2>value</propname1>
    **     </prop>
    **
    **   This implementation (mod_dav) DOES NOT save any attributes that are
    **   associated with the <propname1> 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 <propname1> element. Whether the xml:lang attribute is on
    **   <propname1> 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 */
    
    #define DAV_PROP_ELEMENT "mod_dav-element"
    
    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 */
    
        int flags;                    /* ro, disable lock discovery */
    
        /* 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)
    {
        /* need to escape the uri that's in the resource struct because during
         * the property walker it's not encoded. */
        const char *e_uri = ap_escape_uri(propdb->p,
                                          propdb->resource->uri);
    
        /* 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(e_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->flags & DAV_PROPDB_DISABLE_LOCKDISCOVERY) {
                value = "";
                break;
            }
    
            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_pstrcat(propdb->p,
                                "<D:supported-live-property D:name=\"",
                                name, "\"/>" DEBUG_CR, NULL);
            }
            else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') {
                /* use D: prefix to refer to the DAV: namespace URI */
                s = apr_pstrcat(propdb->p, "<D:", name, ">", value, "</D:", name,
                                ">" DEBUG_CR, NULL);
            }
            else {
                /* use D: prefix to refer to the DAV: namespace URI */
                s = apr_pstrcat(propdb->p, "<D:", name, "/>" DEBUG_CR, NULL);
            }
            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_pstrcat(pool, "<", name->name, "/>" DEBUG_CR, NULL);
        else {
            const char *prefix = dav_xmlns_add_uri(xi, name->ns);
    
            s = apr_pstrcat(pool, "<", prefix, ":", name->name, "/>" DEBUG_CR, NULL);
        }
    
        apr_text_append(pool, phdr, s);
    }
    
    static void dav_insert_xmlns(apr_pool_t *p, const char *pre_prefix, long ns,
                                 const char *ns_uri, apr_text_header *phdr)
    {
        const char *s;
    
        s = apr_psprintf(p, " xmlns:%s%ld=\"%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 flags,
                                            apr_array_header_t * ns_xlate,
                                            dav_propdb **p_propdb)
    {
        return dav_popen_propdb(r->pool, r, lockdb, resource,
                                flags, ns_xlate, p_propdb);
    }
    
    DAV_DECLARE(dav_error *)dav_popen_propdb(apr_pool_t *p,
                                             request_rec *r, dav_lockdb *lockdb,
                                             const dav_resource *resource,
                                             int flags,
                                             apr_array_header_t * ns_xlate,
                                             dav_propdb **p_propdb)
    {
        dav_propdb *propdb = NULL;
    
        propdb = apr_pcalloc(p, sizeof(*propdb));
        propdb->p = p;
    
        *p_propdb = NULL;
    
    #if DAV_DEBUG
        if (resource->uri == NULL) {
            return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
                                 "INTERNAL DESIGN ERROR: resource must define "
                                 "its URI.");
        }
    #endif
    
        propdb->r = r;
        propdb->resource = resource;
        propdb->ns_xlate = ns_xlate;
    
        propdb->db_hooks = DAV_GET_HOOKS_PROPDB(r);
    
        propdb->lockdb = lockdb;
    
        propdb->flags = flags;
    
        /* 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);
        }
    
        if (propdb->subreq) {
            ap_destroy_sub_req(propdb->subreq);
            propdb->subreq = NULL;
        }
    }
    
    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,
                            "<D:propstat>" DEBUG_CR
                            "<D:prop>" 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;
                dav_error *err;
    
                /* 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 */
                err = (*db_hooks->first_name)(propdb->db, &name);
                while (!err && name.ns) {
    
                    /*
                    ** We also look for <DAV:getcontenttype> and
                    ** <DAV:getcontentlanguage>. 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) {
                        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:
                    err = (*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,
                            "</D:prop>" DEBUG_CR
                            "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                            "</D:propstat>" 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 };
        dav_liveprop_elem *element;
        char *marks_liveprop;
        dav_xmlns_info *xi;
        int xi_filled = 0;
    
        /* we lose both the document and the element when calling (insert_prop),
         * make these available in the pool.
         */
        element = dav_get_liveprop_element(propdb->resource);
        if (!element) {
            element = apr_pcalloc(propdb->resource->pool, sizeof(dav_liveprop_elem));
            apr_pool_userdata_setn(element, DAV_PROP_ELEMENT, NULL, propdb->resource->pool);
        }
        else {
            memset(element, 0, sizeof(dav_liveprop_elem));
        }
        element->doc = doc;
    
        /* ### 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,
                       "<D:propstat>" DEBUG_CR
                       "<D:prop>" 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;
    
            element->elem = elem;
    
            /*
            ** 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 outlives propdb->p. Hence use the request pool */
                elem->priv = apr_pcalloc(propdb->r->pool, 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) {
                            long 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,
                                         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,
                                "<D:propstat>" DEBUG_CR
                                "<D:prop>" 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,
                        "</D:prop>" DEBUG_CR
                        "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                        "</D:propstat>" 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,
                            "</D:prop>" DEBUG_CR
                            "<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR
                            "</D:propstat>" 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(dav_liveprop_elem *) dav_get_liveprop_element(const dav_resource *resource)
    {
        dav_liveprop_elem *element;
    
        apr_pool_userdata_get((void **)&element, DAV_PROP_ELEMENT, resource->pool);
    
        return element;
    }
    
    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, 0,
                                     "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, 0,
                                     "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.
                **
                ** http://tools.ietf.org/html/rfc4918#section-14.23 says
                ** "Specifying the removal of a property that does not exist is
                ** not an error"
                */
                /* ### 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;
            }
        }
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/util_lock.c�����������������������������������������������������������0000664�0001751�0001751�00000067161�12506513633�020140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "mod_dav.h"
    #include "http_log.h"
    #include "http_config.h"
    #include "http_protocol.h"
    #include "http_core.h"
    
    APLOG_USE_MODULE(dav);
    
    /* ---------------------------------------------------------------
    **
    ** Property-related lock functions
    **
    */
    
    /*
    ** dav_lock_get_activelock:  Returns a <lockdiscovery> 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)*,
            ** <D: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, "<D:activelock>" DEBUG_CR "<D:locktype>");
            switch (lock->type) {
            case DAV_LOCKTYPE_WRITE:
                dav_buffer_append(p, pbuf, "<D:write/>");
                break;
            default:
                /* ### internal error. log something? */
                break;
            }
            dav_buffer_append(p, pbuf, "</D:locktype>" DEBUG_CR "<D:lockscope>");
            switch (lock->scope) {
            case DAV_LOCKSCOPE_EXCLUSIVE:
                dav_buffer_append(p, pbuf, "<D:exclusive/>");
                break;
            case DAV_LOCKSCOPE_SHARED:
                dav_buffer_append(p, pbuf, "<D:shared/>");
                break;
            default:
                /* ### internal error. log something? */
                break;
            }
            dav_buffer_append(p, pbuf, "</D:lockscope>" DEBUG_CR);
            apr_snprintf(tmp, sizeof(tmp), "<D:depth>%s</D:depth>" DEBUG_CR,
                         lock->depth == DAV_INFINITY ? "infinity" : "0");
            dav_buffer_append(p, pbuf, tmp);
    
            if (lock->owner) {
                /*
                ** This contains a complete, self-contained <DAV:owner> element,
                ** with namespace declarations and xml:lang handling. Just drop
                ** it in.
                */
                dav_buffer_append(p, pbuf, lock->owner);
            }
    
            dav_buffer_append(p, pbuf, "<D:timeout>");
            if (lock->timeout == DAV_TIMEOUT_INFINITE) {
                dav_buffer_append(p, pbuf, "Infinite");
            }
            else {
                time_t now = time(NULL);
                
                /*
                ** Check if the timeout is not, for any reason, already elapsed.
                ** (e.g., because of a large collection, or disk under heavy load...)
                 */
                if (now >= lock->timeout) {
                    dav_buffer_append(p, pbuf, "Second-0");
                }
                else {
                    apr_snprintf(tmp, sizeof(tmp), "Second-%lu", (long unsigned int)(lock->timeout - now));
                    dav_buffer_append(p, pbuf, tmp);
                }
            }
    
            dav_buffer_append(p, pbuf,
                              "</D:timeout>" DEBUG_CR
                              "<D:locktoken>" DEBUG_CR
                              "<D:href>");
            dav_buffer_append(p, pbuf,
                              (*hooks->format_locktoken)(p, lock->locktoken));
            dav_buffer_append(p, pbuf,
                              "</D:href>" DEBUG_CR
                              "</D:locktoken>" DEBUG_CR
                              "</D:activelock>" 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, 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, 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 <DAV:owner> element */
                apr_xml_quote_elem(p, child);
    
                /*
                ** Store a full <DAV:owner> 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, 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, 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 <locktoken> on <resource>. 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, 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, 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, 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;
            }
        }
    
        /* <locks> 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 <resource> 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, APLOGNO(00623)
                              "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;
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/mod_dav.dsp�����������������������������������������������������������0000664�0001751�0001751�00000012057�10551346420�020116� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_dav.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dav.so" /d LONG_NAME="dav_module for Apache"
    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 /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 /out:".\Release\mod_dav.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_dav.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_dav.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dav.so" /d LONG_NAME="dav_module for Apache"
    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 /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 /out:".\Debug\mod_dav.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_dav.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/mod_dav.h�������������������������������������������������������������0000664�0001751�0001751�00000303552�15017335303�017562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mod_dav.h
     * @brief DAV extension module for Apache 2.0.*
     *
     * @defgroup MOD_DAV mod_dav
     * @ingroup APACHE_MODS
     * @{
     */
    
    #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 <limits.h>     /* for INT_MAX */
    #include <time.h>       /* for time_t */
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    
    #define DAV_VERSION             AP_SERVER_BASEREVISION
    
    #define DAV_XML_HEADER          "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    #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	"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n<head>\n<title>"
    #define DAV_RESPONSE_BODY_2     "</title>\n</head><body>\n<h1>"
    #define DAV_RESPONSE_BODY_3     "</h1>\n<p>"
    #define DAV_RESPONSE_BODY_4     "</p>\n"
    #define DAV_RESPONSE_BODY_5     "</body></html>\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 */
    
        apr_status_t aprerr;        /* APR error if any, or 0/APR_SUCCESS */
    
        const char *namespace;      /* [optional] namespace of error */
        const char *tagname;        /* name of error-tag */
    
        struct dav_error *prev;     /* previous error (in stack) */
    
        const char *childtags;      /* error-tag may have children */
    
    } 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, apr_status_t aprerr,
                                          const char *desc);
    
    
    /*
    ** Create a new error structure with tagname and (optional) namespace;
    ** namespace may be NULL, which means "DAV:".
    */
    DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status,
                                              int error_id, apr_status_t aprerr,
                                              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.
    **
    ** <status> 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.
    **
    ** <error_id> 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);
    
    
    /*
    ** Join two errors together.
    **
    ** This function is used to add a new error stack onto an existing error so
    ** that subsequent errors can be reported after the first error.  It returns
    ** the correct error stack to use so that the caller can blindly call it
    ** without checking that both dest and src are not NULL.
    ** 
    ** <dest> is the error stack that the error will be added to.
    **
    ** <src> is the error stack that will be appended.
    */
    DAV_DECLARE(dav_error*) dav_join_error(dav_error* dest, dav_error* src);
    
    typedef struct dav_response dav_response;
    
    /*
    ** dav_handle_err()
    **
    ** Handle the standard error processing. <err> must be non-NULL.
    **
    ** <response> 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
    */
    DAV_DECLARE(int) dav_handle_err(request_rec *r, dav_error *err,
                                    dav_response *response);
    
    /* 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 <response> 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;
                             * currently has an ABI flaw where sometimes it is
                             * assumed to be encoded and sometimes not */
    
        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;
    
    DAV_DECLARE(dav_error *) dav_get_resource(request_rec *r, int label_allowed,
                                              int use_checked_in, dav_resource **res_p);
    
    /*
    ** If DavBasePath is configured for the request location, return the
    ** configured path, otherwise NULL.
    */
    DAV_DECLARE(const char *) dav_get_base_path(request_rec *r);
    
    /* --------------------------------------------------------------------
    **
    ** 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 accommodate 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 accommodate <extra_needed> 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;       /* <propstat> element text */
        apr_text * xmlns;           /* namespace decls for <response> elem */
    } dav_get_props_result;
    
    /* holds the contents of a <response> element */
    struct dav_response
    {
        const char *href;           /* always */
        const char *desc;           /* optional description at <response> level */
    
        /* use status if propresult.propstats is NULL. */
        dav_get_props_result propresult;
    
        int status;
    
        struct dav_response *next;
    };
    
    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
                                       <DAV:supported-live-property> 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
    
    /* Write a complete RESPONSE object out as a <DAV:response> xml
     * element.  Data is sent into brigade BB, which is auto-flushed into
     * the output filter stack for request R.  Use POOL for any temporary
     * allocations.
     *
     * [Presumably the <multistatus> tag has already been written;  this
     * routine is shared by dav_send_multistatus and dav_stream_response.]
     */
    DAV_DECLARE(void) dav_send_one_response(dav_response *response,
                                            apr_bucket_brigade *bb,
                                            request_rec *r,
                                            apr_pool_t *pool);
    
    /* Factorized helper function: prep request_rec R for a multistatus
     * response and write <multistatus> tag into BB, destined for
     * R->output_filters.  Use xml NAMESPACES in initial tag, if
     * non-NULL.
     */
    DAV_DECLARE(void) dav_begin_multistatus(apr_bucket_brigade *bb,
                                            request_rec *r, int status,
                                            apr_array_header_t *namespaces);
    
    /* Finish a multistatus response started by dav_begin_multistatus: */
    DAV_DECLARE(apr_status_t) dav_finish_multistatus(request_rec *r,
                                                     apr_bucket_brigade *bb);
    
    /* Send a multistatus response */
    DAV_DECLARE(void) dav_send_multistatus(request_rec *r, int status,
                                           dav_response *first,
                                           apr_array_header_t *namespaces);
    
    DAV_DECLARE(apr_text *) dav_failed_proppatch(apr_pool_t *p,
                                                 apr_array_header_t *prop_ctx);
    DAV_DECLARE(apr_text *) dav_success_proppatch(apr_pool_t *p,
                                                  apr_array_header_t *prop_ctx);
    
    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(int) dav_validate_root_ns(const apr_xml_doc *doc,
                                          int ns, const char *tagname);
    DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem,
                                               const char *tagname);
    DAV_DECLARE(apr_xml_elem *) dav_find_child_ns(const apr_xml_elem *elem,
                                                  int ns, const char *tagname);
    DAV_DECLARE(apr_xml_elem *) dav_find_next_ns(const apr_xml_elem *elem,
                                                 int ns, const char *tagname);
    
    /* find and return the attribute with a name in the given namespace */
    DAV_DECLARE(apr_xml_attr *) dav_find_attr_ns(const apr_xml_elem *elem,
                                                 int ns, const char *attrname);
    
    /* find and return the attribute with a given DAV: tagname */
    DAV_DECLARE(apr_xml_attr *) dav_find_attr(const apr_xml_elem *elem,
                                              const char *attrname);
    
    /* 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 <repos> and <propdb>. 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 <repos>) and the other functionality.
    **
    ** Live properties and report extensions are not part of the dav_provider
    ** structure because they are handled through the APR_HOOK interface (to
    ** allow for multiple 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))
    
    /*
    ** deliver_report: given a parsed report request, process the request
    **                 an deliver the resulting report.
    **
    ** The hook implementer should decide whether it should handle the given
    ** report, and if so, write the response to the output filter. If the
    ** report is not relevant, return DECLINED.
    */
    APR_DECLARE_EXTERNAL_HOOK(dav, DAV, int, deliver_report,
                             (request_rec *r,
                              const dav_resource *resource,
                              const apr_xml_doc *doc,
                              ap_filter_t *output, dav_error **err))
    
    /*
    ** gather_reports: get all reports.
    **
    ** The hook implementor should push one or more dav_report_elem structures
    ** containing report names into the specified array. These names are returned
    ** in the DAV:supported-reports-set property to let clients know
    ** what reports are supported by the installation.
    **
    */
    APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_reports,
                              (request_rec *r, const dav_resource *resource,
                               apr_array_header_t *reports, dav_error **err))
    
    /*
     ** method_precondition: check method preconditions.
     **
     ** If a WebDAV extension needs to set any preconditions on a method, this
     ** hook is where to do it. If the precondition fails, return an error
     ** response with the tagname set to the value of the failed precondition.
     **
     ** If the method requires an XML body, this will be read and provided as
     ** the doc value. If not, doc is NULL. An extension that needs to verify
     ** the non-XML body of a request should register an input filter to do so
     ** within this hook.
     **
     ** Methods like PUT will supply a single src resource, and the dst will
     ** be NULL.
     **
     ** Methods like COPY or MOVE will trigger this hook twice. The first
     ** invocation will supply just the source resource. The second invocation
     ** will supply a source and destination. This allows preconditions on the
     ** source resource to be verified before making an attempt to get the
     ** destination resource.
     **
     ** Methods like PROPFIND and LABEL will trigger this hook initially for
     ** the src resource, and then subsequently for each resource that has
     ** been walked during processing, with the walked resource passed in dst,
     ** and NULL passed in src.
     **
     ** As a rule, the src resource originates from a request that has passed
     ** through httpd's authn/authz hooks, while the dst resource has not.
     */
    APR_DECLARE_EXTERNAL_HOOK(dav, DAV, int, method_precondition,
                              (request_rec *r,
                               dav_resource *src, const dav_resource *dst,
                               const apr_xml_doc *doc, dav_error **err))
    
    
    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);
    DAV_DECLARE(const char *) dav_get_provider_name(request_rec *r);
    DAV_DECLARE(const dav_provider *) dav_get_provider(request_rec *r);
    
    
    /* ### 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_unknown /* the "unknown" state type; always matches false. */
    } 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.
        **
        ** Some DAV extensions, like CalDAV, specify both document elements
        ** and property elements that need to be taken into account when
        ** generating a property. The document element and property element
        ** are made available in the dav_liveprop_elem structure under the
        ** resource, accessible as follows:
        **
        ** dav_get_liveprop_element(resource);
        **
        ** 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 <value> 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:
        **     <lp1:executable>T</lp1:executable>
        **
        ** 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 conjunction 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(long) 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(long) dav_get_liveprop_ns_index(const char *uri);
    
    /* ### docco */
    DAV_DECLARE(long) dav_get_liveprop_ns_count(void);
    
    /* ### docco */
    DAV_DECLARE(void) dav_add_all_liveprop_xmlns(apr_pool_t *p,
                                                 apr_text_header *phdr);
    
    typedef struct {
        const apr_xml_doc *doc;
        const apr_xml_elem *elem;
    } dav_liveprop_elem;
    
    /*
     ** When calling insert_prop(), the associated request element and
     ** document is accessible using the following call.
     */
    DAV_DECLARE(dav_liveprop_elem *) dav_get_liveprop_element(const dav_resource
                                                              *resource);
    
    /*
    ** 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 <rectype> and <locktoken> fields must be filled
    ** in. All other (user) fields should be zeroed. The lock provider will
    ** usually fill in the <info> field, and the <next> 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 <is_locknull> 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_open_lockdb(request_rec *r,
                                             int ro,
                                             dav_lockdb **lockdb);
    DAV_DECLARE(void) dav_close_lockdb(dav_lockdb *lockdb);
    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);
    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 <dav_lock_scope> 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 */
    #define DAV_VALIDATE_NO_MODIFY  0x0200  /* resource is not being modified
                                               so allow even if lock token
                                               is not provided */
    
    /* 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 <locks> 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 <start_resource> and the lock
        ** specified by <locktoken>.
        **
        ** 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;
    
    #define DAV_PROPDB_NONE                  0 
    #define DAV_PROPDB_RO                    1
    #define DAV_PROPDB_DISABLE_LOCKDISCOVERY 2 
    
    DAV_DECLARE(dav_error *) dav_open_propdb(
        request_rec *r,
        dav_lockdb *lockdb,
        const dav_resource *resource,
        int flags,
        apr_array_header_t *ns_xlate,
        dav_propdb **propdb);
    
    DAV_DECLARE(dav_error *) dav_popen_propdb(
        apr_pool_t *p,
        request_rec *r,
        dav_lockdb *lockdb,
        const dav_resource *resource,
        int flags,
        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;
    
        apr_xml_elem *prop;             /* property to affect */
    
        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? */
    
        /* private items to the propdb */
        int is_liveprop;
        void *liveprop_ctx;
        struct dav_rollback_item *rollback;  /* optional rollback info */
    
        dav_error *err;                 /* error (if any) */
    
        /* 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 */
    #define DAV_WALKTYPE_TOLERANT   0x0008  /* tolerate non-fatal errors */
    
        /* 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;
    
        /* Get the request rec for a resource */
        request_rec * (*get_request_rec)(const dav_resource *resource);
    
        /* Get the pathname for a resource */
        const char * (*get_pathname)(const dav_resource *resource);
    };
    
    
    /* --------------------------------------------------------------------
    **
    ** 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 <DAV:mkworkspace> element is passed to the provider
        ** in the "doc" structure; it may be empty.
        **
        ** If workspace creation is successful, 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 successful, 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: <DAV:basicsearch>
         * DASL: <http://foo.bar.com/syntax1>
         * DASL: <http://akuma.com/syntax2>
         */
        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
    */
    
    typedef struct {
        int propid;                          /* live property ID */
        const dav_hooks_liveprop *provider;  /* the provider defining this prop */
    } dav_elem_private;
    
    /* --------------------------------------------------------------------
    **
    ** DAV OPTIONS
    */
    #define DAV_OPTIONS_EXTENSION_GROUP "dav_options"
    
    typedef struct dav_options_provider
    {
        dav_error* (*dav_header)(request_rec *r,
                                 const dav_resource *resource,
                                 apr_text_header *phdr);
    
        dav_error* (*dav_method)(request_rec *r,
                                 const dav_resource *resource,
                                 apr_text_header *phdr);
    
        void *ctx;
    } dav_options_provider;
    
    extern DAV_DECLARE(const dav_options_provider *) dav_get_options_providers(const char *name);
    
    extern DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p,
                                   const char *name,
                                   const dav_options_provider *provider);
    
    /* --------------------------------------------------------------------
    **
    ** DAV RESOURCE TYPE HOOKS
    */
    
    typedef struct dav_resource_type_provider
    {
        int (*get_resource_type)(const dav_resource *resource,
                      const char **name,
                      const char **uri);
    } dav_resource_type_provider;
    
    #define DAV_RESOURCE_TYPE_GROUP "dav_resource_type"
    
    DAV_DECLARE(void) dav_resource_type_provider_register(apr_pool_t *p,
                                            const char *name,
                                        const dav_resource_type_provider *provider);
    
    DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers(const char *name);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* _MOD_DAV_H_ */
    /** @} */
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/mod_dav.mak�����������������������������������������������������������0000664�0001751�0001751�00000025503�12701473373�020107� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_dav.dsp
    !IF "$(CFG)" == ""
    CFG=mod_dav - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_dav - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_dav - Win32 Release" && "$(CFG)" != "mod_dav - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dav.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_dav.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\liveprop.obj"
    	-@erase "$(INTDIR)\mod_dav.obj"
    	-@erase "$(INTDIR)\mod_dav.res"
    	-@erase "$(INTDIR)\mod_dav_src.idb"
    	-@erase "$(INTDIR)\mod_dav_src.pdb"
    	-@erase "$(INTDIR)\props.obj"
    	-@erase "$(INTDIR)\providers.obj"
    	-@erase "$(INTDIR)\std_liveprop.obj"
    	-@erase "$(INTDIR)\util.obj"
    	-@erase "$(INTDIR)\util_lock.obj"
    	-@erase "$(OUTDIR)\mod_dav.exp"
    	-@erase "$(OUTDIR)\mod_dav.lib"
    	-@erase "$(OUTDIR)\mod_dav.pdb"
    	-@erase "$(OUTDIR)\mod_dav.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DAV_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dav_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dav.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dav.so" /d LONG_NAME="dav_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dav.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dav.pdb" /debug /out:"$(OUTDIR)\mod_dav.so" /implib:"$(OUTDIR)\mod_dav.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\liveprop.obj" \
    	"$(INTDIR)\mod_dav.obj" \
    	"$(INTDIR)\props.obj" \
    	"$(INTDIR)\providers.obj" \
    	"$(INTDIR)\std_liveprop.obj" \
    	"$(INTDIR)\util.obj" \
    	"$(INTDIR)\util_lock.obj" \
    	"$(INTDIR)\mod_dav.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_dav.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_dav.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dav.so"
       if exist .\Release\mod_dav.so.manifest mt.exe -manifest .\Release\mod_dav.so.manifest -outputresource:.\Release\mod_dav.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_dav - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dav.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_dav.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\liveprop.obj"
    	-@erase "$(INTDIR)\mod_dav.obj"
    	-@erase "$(INTDIR)\mod_dav.res"
    	-@erase "$(INTDIR)\mod_dav_src.idb"
    	-@erase "$(INTDIR)\mod_dav_src.pdb"
    	-@erase "$(INTDIR)\props.obj"
    	-@erase "$(INTDIR)\providers.obj"
    	-@erase "$(INTDIR)\std_liveprop.obj"
    	-@erase "$(INTDIR)\util.obj"
    	-@erase "$(INTDIR)\util_lock.obj"
    	-@erase "$(OUTDIR)\mod_dav.exp"
    	-@erase "$(OUTDIR)\mod_dav.lib"
    	-@erase "$(OUTDIR)\mod_dav.pdb"
    	-@erase "$(OUTDIR)\mod_dav.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DAV_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dav_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dav.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dav.so" /d LONG_NAME="dav_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dav.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dav.pdb" /debug /out:"$(OUTDIR)\mod_dav.so" /implib:"$(OUTDIR)\mod_dav.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so 
    LINK32_OBJS= \
    	"$(INTDIR)\liveprop.obj" \
    	"$(INTDIR)\mod_dav.obj" \
    	"$(INTDIR)\props.obj" \
    	"$(INTDIR)\providers.obj" \
    	"$(INTDIR)\std_liveprop.obj" \
    	"$(INTDIR)\util.obj" \
    	"$(INTDIR)\util_lock.obj" \
    	"$(INTDIR)\mod_dav.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_dav.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_dav.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dav.so"
       if exist .\Debug\mod_dav.so.manifest mt.exe -manifest .\Debug\mod_dav.so.manifest -outputresource:.\Debug\mod_dav.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_dav.dep")
    !INCLUDE "mod_dav.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_dav.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_dav - Win32 Release" || "$(CFG)" == "mod_dav - Win32 Debug"
    SOURCE=.\liveprop.c
    
    "$(INTDIR)\liveprop.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\mod_dav.c
    
    "$(INTDIR)\mod_dav.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\props.c
    
    "$(INTDIR)\props.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\providers.c
    
    "$(INTDIR)\providers.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\std_liveprop.c
    
    "$(INTDIR)\std_liveprop.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\util.c
    
    "$(INTDIR)\util.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\util_lock.c
    
    "$(INTDIR)\util_lock.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_dav - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\dav\main"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\main"
    
    !ELSEIF  "$(CFG)" == "mod_dav - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\dav\main"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\main"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\dav\main"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\main"
    
    !ELSEIF  "$(CFG)" == "mod_dav - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\dav\main"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\main"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\dav\main"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\dav\main"
    
    !ELSEIF  "$(CFG)" == "mod_dav - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\dav\main"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\dav\main"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_dav - Win32 Release"
    
    
    "$(INTDIR)\mod_dav.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dav.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_dav.so" /d LONG_NAME="dav_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_dav - Win32 Debug"
    
    
    "$(INTDIR)\mod_dav.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dav.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_dav.so" /d LONG_NAME="dav_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/util.c����������������������������������������������������������������0000664�0001751�0001751�00000236677�14737240630�017144� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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,
                                          apr_status_t aprerr, const char *desc)
    {
        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->aprerr = aprerr;
    
        return err;
    }
    
    DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status,
                                              int error_id, apr_status_t aprerr,
                                              const char *desc,
                                              const char *namespace,
                                              const char *tagname)
    {
        dav_error *err = dav_new_error(p, status, error_id, aprerr, 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(dav_error*) dav_join_error(dav_error *dest, dav_error *src)
    {
        dav_error *curr = dest;
    
        /* src error doesn't exist so nothing to join just return dest */
        if (src == NULL) {
            return dest;
        }
    
        /* dest error doesn't exist so nothing to join just return src */
        if (curr == NULL) {
            return src;
        }
    
        /* find last error in dest stack */
        while (curr->prev != NULL) {
            curr = curr->prev;
        }
    
        /* add the src error onto end of dest stack and return it */
        curr->prev = src;
        return dest;
    }
    
    /* ### Unclear if this was designed to be used with an uninitialized
     * dav_buffer struct, but is used on by dav_lock_get_activelock().
     * Hence check for pbuf->buf. */
    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);
            if (pbuf->buf)
                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 (ap_cstr_casecmp(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
        ** ### <ServerAlias> 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_ns(const apr_xml_doc *doc,
                                          int ns, const char *tagname)
    {
        return doc->root &&
            doc->root->ns == ns &&
            strcmp(doc->root->name, tagname) == 0;
    }
    
    /* 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 dav_validate_root_ns(doc, APR_XML_NS_DAV_ID, tagname);
    }
    
    /* find and return the next child with a tagname in the given namespace */
    DAV_DECLARE(apr_xml_elem *) dav_find_next_ns(const apr_xml_elem *elem,
                                                 int ns, const char *tagname)
    {
        apr_xml_elem *child = elem->next;
    
        for (; child; child = child->next)
            if (child->ns == ns && !strcmp(child->name, tagname))
                return child;
        return NULL;
    }
    
    /* find and return the (unique) child with a tagname in the given namespace */
    DAV_DECLARE(apr_xml_elem *) dav_find_child_ns(const apr_xml_elem *elem,
                                                  int ns, const char *tagname)
    {
        apr_xml_elem *child = elem->first_child;
    
        for (; child; child = child->next)
            if (child->ns == ns && !strcmp(child->name, tagname))
                return child;
        return NULL;
    }
    
    /* 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)
    {
    	return dav_find_child_ns(elem, APR_XML_NS_DAV_ID, tagname);
    }
    
    /* find and return the attribute with a name in the given namespace */
    DAV_DECLARE(apr_xml_attr *) dav_find_attr_ns(const apr_xml_elem *elem,
                                                 int ns, const char *attrname)
    {
        apr_xml_attr *attr = elem->attr;
    
        for (; attr; attr = attr->next)
            if (attr->ns == ns && !strcmp(attr->name, attrname))
                return attr;
        return NULL;
    }
    
    /* find and return the attribute with a given DAV: tagname */
    DAV_DECLARE(apr_xml_attr *) dav_find_attr(const apr_xml_elem *elem,
                                              const char *attrname)
    {
    	return dav_find_attr_ns(elem, APR_XML_NS_DAV_ID, attrname);
    }
    
    /* 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;
                --len;
            }
    
            /* 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 usable 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_pstrcat(xi->pool, " xmlns:", (const char *)prefix, "=\"",
                            (const char *)uri, "\"", NULL);
            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) {
                /* If the state token cannot be parsed, treat it as an
                 * unknown state; this will evaluate to "false" later
                 * during If header validation. */
                if (err->error_id == DAV_ERR_LOCK_UNK_STATE_TOKEN) {
                    new_sl->type = dav_if_unknown;
                }
                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 occurrence 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;
        apr_status_t rv;
        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, 0,
                                         "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 ((rv = apr_uri_parse(r->pool, uri, &parsed_uri)) != APR_SUCCESS
                    || !parsed_uri.path) {
                    return dav_new_error(r->pool, HTTP_BAD_REQUEST,
                                         DAV_ERR_IF_TAGGED, rv,
                                         "Invalid URI in tagged If-header.");
                }
                /* note that parsed_uri.path is allocated; we can trash it */
    
                /* clean up the URI a bit */
                if (!ap_normalize_path(parsed_uri.path,
                                       AP_NORMALIZE_NOT_ABOVE_ROOT |
                                       AP_NORMALIZE_DECODE_UNRESERVED)) {
                    return dav_new_error(r->pool, HTTP_BAD_REQUEST,
                                         DAV_ERR_IF_TAGGED, rv,
                                         "Invalid URI path tagged If-header.");
                }
    
                /* the resources we will compare to have unencoded paths */
                if (ap_unescape_url(parsed_uri.path) != OK) {
                    return dav_new_error(r->pool, HTTP_BAD_REQUEST,
                                         DAV_ERR_IF_TAGGED, rv,
                                         "Invalid percent encoded URI in "
                                         "tagged If-header.");
                }
    
                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, 0,
                                         "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, 0,
                                         "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, 0, 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, 0, 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, 0,
                                                     "Invalid \"If:\" header: "
                                                     "Multiple \"not\" entries "
                                                     "for the same state.");
                            }
                            condition = DAV_IF_COND_NOT;
                            list += 2;
                        }
                        else {
                            return dav_new_error(r->pool, HTTP_BAD_REQUEST,
                                                 DAV_ERR_IF_UNK_CHAR, 0,
                                                 "Invalid \"If:\" header: "
                                                 "Unexpected character in List");
                        }
                        break;
    
                    case ' ':
                    case '\t':
                        break;
    
                    default:
                        return dav_new_error(r->pool, HTTP_BAD_REQUEST,
                                             DAV_ERR_IF_UNK_CHAR, 0,
                                             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, 0,
                                     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 <seen_locktoken> variable determines whether we have seen one
        ** of this resource's locktokens in the If: header.
        */
    
        /*
        ** If this is a new lock request, <flags> 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, 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, 0,
                                         "The requested resource is already "
                                         "locked exclusively.");
                }
            }
    
            /*
            ** The locks on the resource (if any) are all shared. Set the
            ** <seen_locktoken> 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 or if the resource is not being modified
            ** (per RFC 4918 the lock token is not required on resources
            ** we are not changing), then <seen_locktoken> 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
                              || flags & DAV_VALIDATE_NO_MODIFY);
        }
    
        /*
        ** 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, 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, 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 ? r->user : "[none]",
                                                "\" submitted a locktoken created "
                                                "by user \"",
                                                lock->auth_user, "\".", NULL);
                            return dav_new_error(p, HTTP_FORBIDDEN, 0, 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;
    
                case dav_if_unknown:
                    /* Request is predicated on some unknown state token,
                     * which must be presumed to *not* match, so fail
                     * unless this is a Not condition. */
    
                    if (state_list->condition == DAV_IF_COND_NORMAL) {
                        reason =
                            "an unknown state token was supplied";
                        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 */, 0,
                                     "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, 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, 0,
                                     "The preconditions specified by the \"If:\" "
                                     "header did not match this resource.");
            }
    
            return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0, 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, 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 */, 0,
                             "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;
    }
    
    /* If-* header checking */
    static int dav_meets_conditions(request_rec *r, int resource_state)
    {
        const char *if_match, *if_none_match;
        int retVal;
    
        /* If-Match '*' fix. Resource existence not checked by ap_meets_conditions.
         * If-Match '*' request should succeed only if the resource exists. */
        if ((if_match = apr_table_get(r->headers_in, "If-Match")) != NULL) {
            if (if_match[0] == '*' && resource_state != DAV_RESOURCE_EXISTS)
                return HTTP_PRECONDITION_FAILED;
        }
    
        retVal = ap_meets_conditions(r);
    
        /* If-None-Match '*' fix. If-None-Match '*' request should succeed
         * if the resource does not exist. */
        if (retVal == HTTP_PRECONDITION_FAILED) {
            /* Note. If if_none_match != NULL, if_none_match is the culprit.
             * Since, in presence of If-None-Match,
             * other If-* headers are undefined. */
            if ((if_none_match =
                apr_table_get(r->headers_in, "If-None-Match")) != NULL) {
                if (if_none_match[0] == '*'
                    && resource_state != DAV_RESOURCE_EXISTS) {
                    return OK;
                }
            }
        }
    
        return retVal;
    }
    
    /*
    ** 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;
        int resource_state;
        const char *etag;
        int set_etag = 0;
    
    #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, 0,
                                 "DESIGN ERROR: dav_validate_request called "
                                 "with depth>0, but no response ptr.");
        }
    #endif
    
        if (response != NULL)
            *response = NULL;
    
        /* Set the ETag header required by dav_meets_conditions() */
        etag = apr_table_get(r->headers_out, "ETag");
        if (!etag) {
            etag = (*resource->hooks->getetag)(resource);
            if (etag && *etag) {
                apr_table_set(r->headers_out, "ETag", etag);
                set_etag = 1;
            }
        }
        /* Do the standard checks for conditional requests using
         * If-..-Since, If-Match etc */
        resource_state = dav_get_resource_state(r, resource);
        result = dav_meets_conditions(r, resource_state);
        if (set_etag) {
            /*
             * If we have set an ETag to headers out above for
             * dav_meets_conditions() revert this here as we do not want to set
             * the ETag in responses to requests with methods where this might not
             * be desired.
             */
            apr_table_unset(r->headers_out, "ETag");
        }
        if (result != OK) {
            return dav_new_error(r->pool, result, 0, 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.
         * Avoid the walk there is no if_header and we aren't planning
         * to modify this resource. */
        if (resource->exists && depth > 0 && !(!if_header && flags & DAV_VALIDATE_NO_MODIFY)) {
            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, 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, 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 =
                    "<D:propstat>" DEBUG_CR
                    "<D:prop><D:lockdiscovery/></D:prop>" DEBUG_CR
                    "<D:status>HTTP/1.1 424 Failed Dependency</D:status>" DEBUG_CR
                    "</D:propstat>" 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, 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;        /* Beginning 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, 0,
                                 "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);
    
            /* If Target-Selector specified, add it to the Vary header */
            if (target != NULL) {
                const char *vary = apr_table_get(out_req->headers_out, "Vary");
    
                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, 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, 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, 0,
                                        "<DAV:cannot-modify-checked-in-parent>");
                    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, 0,
                                    "<DAV:cannot-modify-version-controlled-content>");
                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;
    }
    �����������������������������������������������������������������httpd-2.4.64/modules/dav/main/mod_dav.dep�����������������������������������������������������������0000664�0001751�0001751�00000033103�12674411515�020101� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_dav.mak
    
    .\liveprop.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dav.h"\
    	
    
    .\mod_dav.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_expr.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_script.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dav.h"\
    	
    
    .\props.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\http_request.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dav.h"\
    	
    
    .\providers.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dav.h"\
    	
    
    .\std_liveprop.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dav.h"\
    	
    
    .\util.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\http_protocol.h"\
    	"..\..\..\include\http_request.h"\
    	"..\..\..\include\http_vhost.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dav.h"\
    	
    
    .\util_lock.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_expr.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_core.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\http_protocol.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dav.h"\
    	
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/providers.c�����������������������������������������������������������0000664�0001751�0001751�00000004121�11255137170�020151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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");
    }
    
    DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p,
                            const char *name,
                            const dav_options_provider *provider)
    {
        ap_register_provider(p, DAV_OPTIONS_EXTENSION_GROUP, name, "0", provider);
    }
    
    DAV_DECLARE(const dav_options_provider *) dav_get_options_providers(const char *name)
    {
        return ap_lookup_provider(DAV_OPTIONS_EXTENSION_GROUP, name, "0");
    }
    
    
    DAV_DECLARE(void) dav_resource_type_provider_register(apr_pool_t *p,
                              const char *name,
                              const dav_resource_type_provider *provider)
    {
        ap_register_provider(p, DAV_RESOURCE_TYPE_GROUP, name, "0", provider);
    }
    
    DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers(const char *name)
    {
        return ap_lookup_provider(DAV_RESOURCE_TYPE_GROUP, name, "0");
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/config5.m4������������������������������������������������������������0000664�0001751�0001751�00000001034�11463663047�017574� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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.  --enable-dav also enables mod_dav_fs, $dav_objects, , $dav_enable)
    
    if test "$dav_enable" != "no" -o "$enable_dav" != "no"; then
      apache_need_expat=yes
    fi
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/Makefile.in�����������������������������������������������������������0000664�0001751�0001751�00000000267�10150161574�020042� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/mod_dav.c�������������������������������������������������������������0000664�0001751�0001751�00000554527�15017335303�017567� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "ap_provider.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"
    
    APLOG_USE_MODULE(dav);
    
    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;
        const char *base;
        int locktimeout;
        int allow_depthinfinity;
        int allow_lockdiscovery;
    
    } 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");
    
        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;
    
            l = strlen(dir);
            d = apr_pstrmemdup(p, dir, l);
            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, APLOGNO(00578)
                             "\"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, APLOGNO(00579)
                             "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->base = DAV_INHERIT_VALUE(parent, child, base);
        newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child,
                                                         allow_depthinfinity);
        newconf->allow_lockdiscovery = DAV_INHERIT_VALUE(parent, child,
                                                         allow_lockdiscovery);
    
        return newconf;
    }
    
    DAV_DECLARE(const char *) dav_get_provider_name(request_rec *r)
    {
        dav_dir_conf *conf = ap_get_module_config(r->per_dir_config, &dav_module);
        return conf ? conf->provider_name : NULL;
    }
    
    DAV_DECLARE(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;
    }
    
    DAV_DECLARE(const char *) dav_get_base_path(request_rec *r)
    {
        dav_dir_conf *conf = ap_get_module_config(r->per_dir_config, &dav_module);
    
        return conf && conf->base ? conf->base : NULL;
    }
    
    /*
     * 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 = 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 DAVBasePath directive, which is TAKE1
     */
    static const char *dav_cmd_davbasepath(cmd_parms *cmd, void *config, const char *arg1)
    {
        dav_dir_conf *conf = config;
    
        conf->base = arg1;
    
        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 the DAVLockDiscovery directive, which is FLAG.
     */
    static const char *dav_cmd_davlockdiscovery(cmd_parms *cmd, void *config,
                                                int arg)
    {
        dav_dir_conf *conf = (dav_dir_conf *)config;
    
        if (arg)
            conf->allow_lockdiscovery = DAV_ENABLED_ON;
        else
            conf->allow_lockdiscovery = 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;
        r->status_line = ap_get_status_line(status);
    
        ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
    
        /* 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("<hr />\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;
    
        ap_set_content_type_ex(r, DAV_XML_CONTENT_TYPE, 1);
    
        ap_rputs(DAV_XML_HEADER DEBUG_CR
                 "<D:error xmlns:D=\"DAV:\"", r);
    
        if (err->desc != NULL) {
            /* ### should move this namespace somewhere (with the others!) */
            ap_rputs(" xmlns:m=\"http://apache.org/dav/xmlns\"", r);
        }
    
        if (err->childtags) {
            if (err->namespace != NULL) {
                ap_rprintf(r,
                        " xmlns:C=\"%s\">" DEBUG_CR
                        "<C:%s>%s</C:%s>" DEBUG_CR,
                        err->namespace,
                        err->tagname, err->childtags, err->tagname);
            }
            else {
                ap_rprintf(r,
                        ">" DEBUG_CR
                        "<D:%s>%s</D:%s>" DEBUG_CR,
                        err->tagname, err->childtags, err->tagname);
            }
        }
        else {
            if (err->namespace != NULL) {
                ap_rprintf(r,
                        " xmlns:C=\"%s\">" DEBUG_CR
                        "<C:%s/>" DEBUG_CR,
                        err->namespace, err->tagname);
            }
            else {
                ap_rprintf(r,
                        ">" DEBUG_CR
                        "<D:%s/>" DEBUG_CR, err->tagname);
            }
        }
    
        /* here's our mod_dav specific tag: */
        if (err->desc != NULL) {
            ap_rprintf(r,
                       "<m:human-readable errcode=\"%d\">" DEBUG_CR
                       "%s" DEBUG_CR
                       "</m:human-readable>" DEBUG_CR,
                       err->error_id,
                       apr_xml_quote_string(r->pool, err->desc, 0));
        }
    
        ap_rputs("</D:error>" 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 <DAV:response> xml
       element.  Data is sent into brigade BB, which is auto-flushed into
       the output filter stack for request R.  Use POOL for any temporary
       allocations.
    
       [Presumably the <multistatus> tag has already been written;  this
       routine is shared by dav_send_multistatus and dav_stream_response.]
    */
    DAV_DECLARE(void) dav_send_one_response(dav_response *response,
                                            apr_bucket_brigade *bb,
                                            request_rec *r,
                                            apr_pool_t *pool)
    {
        apr_text *t = NULL;
    
        if (response->propresult.xmlns == NULL) {
          ap_fputs(r->output_filters, bb, "<D:response>");
        }
        else {
          ap_fputs(r->output_filters, bb, "<D:response");
          for (t = response->propresult.xmlns; t; t = t->next) {
            ap_fputs(r->output_filters, bb, t->text);
          }
          ap_fputc(r->output_filters, bb, '>');
        }
    
        ap_fputstrs(r->output_filters, bb,
                    DEBUG_CR "<D:href>",
                    dav_xml_escape_uri(pool, response->href),
                    "</D: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(r->output_filters, bb,
                      "<D:status>HTTP/1.1 ",
                      ap_get_status_line(response->status),
                      "</D:status>" DEBUG_CR,
                      NULL);
        }
        else {
          /* assume this includes <propstat> and is quoted properly */
          for (t = response->propresult.propstats; t; t = t->next) {
            ap_fputs(r->output_filters, 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(r->output_filters, bb,
                      "<D:responsedescription>",
                      response->desc,
                      "</D:responsedescription>" DEBUG_CR,
                      NULL);
        }
    
        ap_fputs(r->output_filters, bb, "</D:response>" DEBUG_CR);
    }
    
    
    /* Factorized helper function: prep request_rec R for a multistatus
       response and write <multistatus> tag into BB, destined for
       R->output_filters.  Use xml NAMESPACES in initial tag, if
       non-NULL. */
    DAV_DECLARE(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_ex(r, DAV_XML_CONTENT_TYPE, 1);
    
        /* Send the headers and actual multistatus response now... */
        ap_fputs(r->output_filters, bb, DAV_XML_HEADER DEBUG_CR
                 "<D:multistatus xmlns:D=\"DAV:\"");
    
        if (namespaces != NULL) {
           int i;
    
           for (i = namespaces->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: */
    DAV_DECLARE(apr_status_t) dav_finish_multistatus(request_rec *r,
                                                     apr_bucket_brigade *bb)
    {
        apr_bucket *b;
    
        ap_fputs(r->output_filters, bb, "</D:multistatus>" 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);
    }
    
    DAV_DECLARE(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);
        apr_pool_tag(subpool, "mod_dav-multistatus");
    
        for (; first != NULL; first = first->next) {
          apr_pool_clear(subpool);
          dav_send_one_response(first, bb, r, 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;
    
            /* Intentional no APLOGNO */
            ap_log_rerror(APLOG_MARK, level, errscan->aprerr, r, "%s  [%d, #%d]",
                          errscan->desc, errscan->status, errscan->error_id);
        }
    }
    
    /*
     * dav_handle_err()
     *
     * Handle the standard error processing. <err> must be non-NULL.
     *
     * <response> 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
     */
    DAV_DECLARE(int) dav_handle_err(request_rec *r, dav_error *err,
                                    dav_response *response)
    {
        /* log the errors */
        dav_log_err(r, err, APLOG_ERR);
    
        if (!ap_is_HTTP_VALID_RESPONSE(err->status)) {
            /* we have responded already */
            return AP_FILTER_ERROR;
        }
    
        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 <D:error> 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.
     * locn if provided is assumed to be escaped. */
    static int dav_created(request_rec *r, const char *locn, const char *what,
                           int replaced)
    {
        const char *body;
    
        if (locn == NULL) {
            locn = ap_escape_uri(r->pool, 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_pstrcat(r->pool, what, " ", ap_escape_html(r->pool, locn),
                           " has been created.", NULL);
        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 (ap_cstr_casecmp(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, APLOGNO(00580)
                      "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, APLOGNO(00581)
                      "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.
     */
    DAV_DECLARE(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, *base;
        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 */
        if (conf->provider == NULL) {
            return dav_new_error(r->pool, HTTP_METHOD_NOT_ALLOWED, 0, 0,
                                 apr_psprintf(r->pool,
                                 "DAV not enabled for %s",
                                 ap_escape_html(r->pool, r->uri)));
        }
    
        /* Take the repos root from DAVBasePath if configured, else the
         * path of the enclosing section. */
        base = conf->base ? conf->base : conf->dir;
    
        /* resolve the resource */
        err = (*conf->provider->repos->get_resource)(r, base,
                                                     label, use_checked_in,
                                                     res_p);
        if (err != NULL) {
            /* In the error path, give a hint that DavBasePath needs to be
             * used if the location was configured via a regex match. */
            if (!conf->base) {
                core_dir_config *cdc = ap_get_core_module_config(r->per_dir_config);
    
                if (cdc->r) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(10484)
                                 "failed to find repository for location configured "
                                 "via regex match - missing DAVBasePath?");
                }
            }
    
            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, 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;
    }
    
    DAV_DECLARE(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);
    }
    
    DAV_DECLARE(void) dav_close_lockdb(dav_lockdb *lockdb)
    {
        (lockdb->hooks->close_lockdb)(lockdb);
    }
    
    /**
     * @return  1 if valid content-range,
     *          0 if no content-range,
     *         -1 if malformed content-range
     */
    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;
    
        range_c = apr_table_get(r->headers_in, "content-range");
        if (range_c == NULL)
            return 0;
    
        range = apr_pstrdup(r->pool, range_c);
        if (ap_cstr_casecmpn(range, "bytes ", 6) != 0
            || (dash = ap_strchr(range + 6, '-')) == NULL
            || (slash = ap_strchr(range + 6, '/')) == NULL) {
            /* malformed header */
            return -1;
        }
    
        *dash++ = *slash++ = '\0';
    
        /* detect invalid ranges */
        if (!ap_parse_strict_length(range_start, range + 6)) {
            return -1;
        }
        if (!ap_parse_strict_length(range_end, dash)
                || *range_end < *range_start) {
            return -1;
        }
    
        if (*slash != '*') {
            apr_off_t dummy;
    
            if (!ap_parse_strict_length(&dummy, slash)
                    || dummy <= *range_end) {
                return -1;
            }
        }
    
        /* 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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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);
        }
    
        has_range = dav_parse_range(r, &range_start, &range_end);
        if (has_range < 0) {
            /* RFC 2616 14.16: If we receive an invalid Content-Range we must
             * not use the content.
             */
            body = apr_psprintf(r->pool,
                                "Malformed Content-Range header for PUT %s.",
                                ap_escape_html(r->pool, r->uri));
            return dav_error_response(r, HTTP_BAD_REQUEST, body);
        } else if (has_range) {
            mode = DAV_MODE_WRITE_SEEKABLE;
        }
        else {
            mode = DAV_MODE_WRITE_TRUNC;
        }
    
        /* 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);
        }
    
        /* Create the new file in the repository */
        if ((err = (*resource->hooks->open_stream)(resource, mode,
                                                   &stream)) != NULL) {
            int status = err->status ? err->status : HTTP_FORBIDDEN;
            if (status > 299) {
                err = dav_push_error(r->pool, status, 0,
                                     apr_psprintf(r->pool,
                                                  "Unable to PUT new contents for %s.",
                                                  ap_escape_html(r->pool, r->uri)),
                                     err);
            }
            else {
                err = NULL;
            }
        }
    
        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) {
                    int http_err;
                    char *msg = ap_escape_html(r->pool, r->uri);
                    http_err = ap_map_http_request_error(rc, HTTP_BAD_REQUEST);
                    msg = apr_psprintf(r->pool, "An error occurred while reading "
                                                "the request body (URI: %s)",
                                                msg);
                    err = dav_new_error(r->pool, http_err, 0, rc, msg);
                    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;
                    }
    
                    if (err == NULL) {
                        /* write whatever we read, until we see an error */
                        rc = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
                        if (rc != APR_SUCCESS) {
                           err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, rc,
                                               apr_psprintf(r->pool,
                                                            "An error occurred while"
                                                            " reading the request body"
                                                            " from the bucket (URI: %s)",
                                                            ap_escape_html(r->pool, r->uri)));
                            break;
                        }
    
                        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 */);
            err = dav_join_error(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) {
            err = dav_join_error(err, err2); /* don't forget err2 */
            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, 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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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, APLOGNO(00582)
                          "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, APLOGNO(00583)
                          "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, "<D:supported-method-set>" 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_pstrcat(r->pool,
                                "<D:supported-method D:name=\"",
                                elts[i].key,
                                "\"/>" DEBUG_CR, NULL);
                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, 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_pstrcat(r->pool,
                                        "<D:supported-method D:name=\"",
                                        name, "\"/>" DEBUG_CR, NULL);
                        apr_text_append(r->pool, body, s);
                    }
                }
            }
        }
    
        apr_text_append(r->pool, body, "</D:supported-method-set>" 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 */
        if ((err = dav_open_lockdb(r, 1, &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, DAV_PROPDB_RO, 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, "<D:supported-live-property-set>" 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, 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, "</D:supported-live-property-set>" 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,
                                                apr_text_header *body)
    {
        apr_xml_elem *child;
        apr_xml_attr *attr;
        dav_error *err = NULL;
        char *s;
        apr_array_header_t *reports;
        const dav_report_elem *rp;
    
        apr_text_append(r->pool, body, "<D:supported-report-set>" DEBUG_CR);
    
        reports = apr_array_make(r->pool, 5, sizeof(const char *));
        dav_run_gather_reports(r, resource, reports, &err);
        if (err != 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 (elem->first_child == NULL) {
            int i;
    
            /* show all supported reports */
            rp = (const dav_report_elem *)reports->elts;
            for (i = 0; i < reports->nelts; i++, rp++) {
                /* Note: we presume reports->namespace is
                 * properly XML/URL quoted */
                s = apr_pstrcat(r->pool,
                        "<D:supported-report D:name=\"",
                        rp->name,
                        "\" D:namespace=\"",
                        rp->nmspace,
                        "\"/>" DEBUG_CR, NULL);
                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;
                    int i;
    
                    /* 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, 0,
                                "A DAV:supported-report element "
                                "does not have a \"name\" attribute");
                    }
    
                    /* default namespace to DAV: */
                    if (nmspace == NULL) {
                        nmspace = "DAV:";
                    }
    
                    rp = (const dav_report_elem *)reports->elts;
                    for (i = 0; i < reports->nelts; i++, rp++) {
                        if (strcmp(name, rp->name) == 0
                                && strcmp(nmspace, rp->nmspace) == 0) {
                            /* Note: we presume reports->nmspace is
                             * properly XML/URL quoted
                             */
                            s = apr_pstrcat(r->pool,
                                    "<D:supported-report "
                                    "D:name=\"",
                                    rp->name,
                                    "\" D:namespace=\"",
                                    rp->nmspace,
                                    "\"/>" DEBUG_CR, NULL);
                            apr_text_append(r->pool, body, s);
                            break;
                        }
                    }
                }
            }
        }
    
        apr_text_append(r->pool, body, "</D:supported-report-set>" 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;
    
        apr_array_header_t *extensions;
        ap_list_provider_names_t *entry;
    
        /* 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 */
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            return dav_handle_err(r, err, NULL);
        }
    
        if (doc && !dav_validate_root(doc, "options")) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00584)
                          "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);
    
        /* DAV header additions registered by external modules */
        extensions = ap_list_provider_names(r->pool, DAV_OPTIONS_EXTENSION_GROUP, "0");
        entry = (ap_list_provider_names_t *)extensions->elts;
    
        for (i = 0; i < extensions->nelts; i++, entry++) {
            const dav_options_provider *options =
                dav_get_options_providers(entry->provider_name);
    
            if (options && options->dav_header) {
                apr_text_header hoptions = { 0 };
    
                options->dav_header(r, resource, &hoptions);
                for (t = hoptions.first; t && t->text; t = t->next)
                    dav_level = apr_pstrcat(r->pool, dav_level, ",", t->text, 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", "");
        }
    
        /* additional methods registered by external modules */
        extensions = ap_list_provider_names(r->pool, DAV_OPTIONS_EXTENSION_GROUP, "0");
        entry = (ap_list_provider_names_t *)extensions->elts;
    
        for (i = 0; i < extensions->nelts; i++, entry++) {
            const dav_options_provider *options =
                dav_get_options_providers(entry->provider_name);
    
            if (options && options->dav_method) {
                apr_text_header hoptions = { 0 };
    
                options->dav_method(r, resource, &hoptions);
                for (t = hoptions.first; t && t->text; t = t->next)
                    apr_table_addn(methods, t->text, "");
            }
        }
    
        /* 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: <DAV:basicsearch>
         * DASL: <http://foo.bar.com/syntax1>
         * DASL: <http://akuma.com/syntax2>
         */
        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, &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_ex(r, DAV_XML_CONTENT_TYPE, 1);
    
        /* send the headers and response body */
        ap_rputs(DAV_XML_HEADER DEBUG_CR
                 "<D:options-response xmlns:D=\"DAV:\">" DEBUG_CR, r);
    
        for (t = body.first; t != NULL; t = t->next)
            ap_rputs(t->text, r);
    
        ap_rputs("</D:options-response>" 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,
                        "<D:propstat>" DEBUG_CR
                        "<D:prop>" 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,
                        "</D:prop>" DEBUG_CR
                        "<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR
                        "</D:propstat>" 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_dir_conf *conf;
        int flags = DAV_PROPDB_RO;
        dav_error *err;
        dav_propdb *propdb;
        dav_get_props_result propstats = { 0 };
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(ctx->r, NULL, wres->resource, ctx->doc, &err) != DECLINED
                && err) {
            apr_pool_clear(ctx->scratchpool);
            return NULL;
        }
    
        conf = ap_get_module_config(ctx->r->per_dir_config, &dav_module);
        if (conf && conf->allow_lockdiscovery == DAV_ENABLED_OFF)
            flags |= DAV_PROPDB_DISABLE_LOCKDISCOVERY;
    
        /*
        ** 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_popen_propdb(ctx->scratchpool,
                               ctx->r, ctx->w.lockdb, wres->resource, flags,
                               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_stream_response(wres, 0, &propstats, ctx->scratchpool);
    
        dav_close_propdb(propdb);
    
        /* 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;
        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 ((result = ap_xml_parse_input(r, &doc)) != OK) {
            return result;
        }
        /* note: doc == NULL if no request body */
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            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 (doc && !dav_validate_root(doc, "propfind")) {
            /* This supplies additional information for the default message. */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00585)
                          "The \"propfind\" element was not found.");
            return HTTP_BAD_REQUEST;
        }
    
        /* ### validate that only one of these three elements is present */
    
        if (doc == NULL || dav_find_child(doc->root, "allprop") != NULL) {
            /* note: no request body implies allprop */
            ctx.propfind_type = DAV_PROPFIND_IS_ALLPROP;
        }
        else if (dav_find_child(doc->root, "propname") != NULL) {
            ctx.propfind_type = DAV_PROPFIND_IS_PROPNAME;
        }
        else if (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, APLOGNO(00586)
                          "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 | DAV_WALKTYPE_TOLERANT;
        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);
        apr_pool_tag(ctx.scratchpool, "mod_dav-scratch");
    
        if ((err = dav_open_lockdb(r, 1, &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 <multistatus> tag, with all doc->namespaces attached.  */
    
        /* NOTE: we *cannot* leave out the doc's namespaces from the
           initial <multistatus> 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 <response> elements will override these ns0,
           ns1, etc, but NOT within the <response> 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;
    }
    
    DAV_DECLARE(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,
                            "<D:propstat>" DEBUG_CR
                            "<D:prop>");
            apr_text_append(p, &hdr, apr_xml_empty_elem(p, ctx->prop));
            apr_text_append(p, &hdr, "</D:prop>" 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, 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, 0,
                                                      "Attempted DAV:remove "
                                                      "operation could not be "
                                                      "completed due to other "
                                                      "errors.");
                    ctx->err = err424_delete;
                }
            }
    
            s = apr_psprintf(p,
                             "<D:status>"
                             "HTTP/1.1 %d (status)"
                             "</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, "<D:responsedescription>" DEBUG_CR);
                apr_text_append(p, &hdr, ctx->err->desc);
                apr_text_append(p, &hdr, "</D:responsedescription>" DEBUG_CR);
            }
    
            apr_text_append(p, &hdr, "</D:propstat>" DEBUG_CR);
        }
    
        return hdr.first;
    }
    
    DAV_DECLARE(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,
                        "<D:propstat>" DEBUG_CR
                        "<D:prop>" DEBUG_CR);
    
        for ( ; i-- > 0; ++ctx ) {
            apr_text_append(p, &hdr, apr_xml_empty_elem(p, ctx->prop));
        }
    
        apr_text_append(p, &hdr,
                       "</D:prop>" DEBUG_CR
                       "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                       "</D:propstat>" 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 <func> 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 <reverse> 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 ((result = ap_xml_parse_input(r, &doc)) != OK) {
            return result;
        }
        /* note: doc == NULL if no request body */
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            return dav_handle_err(r, err, NULL);
        }
    
        if (!resource->exists) {
            /* Apache will supply a default error for this. */
            return HTTP_NOT_FOUND;
        }
    
        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, APLOGNO(00587)
                          "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,
                                   DAV_PROPDB_NONE, 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, APLOGNO(00588)
                              "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 (ap_cstr_casecmp(tenc, "chunked")) {
                /* Use this instead of Apache's default error string */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00589)
                              "Unknown Transfer-Encoding %s", tenc);
                return HTTP_NOT_IMPLEMENTED;
            }
    
            r->read_chunked = 1;
        }
        else if (lenp) {
            if (!ap_parse_strict_length(&r->remaining, lenp)) {
                r->remaining = 0;
                /* This supplies additional information for the default message. */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00590)
                              "Invalid Content-Length %s", lenp);
                return HTTP_BAD_REQUEST;
            }
        }
    
        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_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;
        }
    
        /* 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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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, err2->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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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_pstrcat(r->pool, "http://", nscp_host, nscp_path, NULL);
        }
        if (dest == NULL) {
            /* This supplies additional information for the default message. */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00591)
                          "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, APLOGNO(00592)
                              "%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_setn(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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, resnew, NULL, &err) != DECLINED
                && err) {
            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, APLOGNO(00593)
                          "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, APLOGNO(00594)
                          "Depth must be \"infinity\" when moving a collection.");
            return HTTP_BAD_REQUEST;
        }
    
        /*
         * Check If-Headers and existing locks for each resource in the source.
         * 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, if 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 ((err = dav_validate_request(r, resource, depth, NULL,
                                        &multi_response,
                                        (is_move ? DAV_VALIDATE_PARENT
                                                 : DAV_VALIDATE_RESOURCE
                                                   | DAV_VALIDATE_NO_MODIFY)
                                        | DAV_VALIDATE_USE_424,
                                        NULL)) != NULL) {
            err = dav_push_error(r->pool, err->status, 0,
                                 apr_psprintf(r->pool,
                                              "Could not %s %s due to a failed "
                                              "precondition on the source "
                                              "(e.g. locks).",
                                              is_move ? "MOVE" : "COPY",
                                              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->unparsed_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;
        dav_resource *parent;
        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, APLOGNO(00595)
                          "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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            return dav_handle_err(r, err, NULL);
        }
    
        /* Check if parent collection exists */
        if ((err = resource->hooks->get_parent_resource(resource, &parent)) != NULL) {
            /* ### add a higher-level description? */
            return dav_handle_err(r, err, NULL);
        }
        if (parent && (!parent->exists || parent->collection != 1)) {
            err = dav_new_error(r->pool, HTTP_CONFLICT, 0, 0,
                               apr_psprintf(r->pool,
                                            "The parent resource of %s does not "
                                            "exist or is not a collection.",
                                            ap_escape_html(r->pool, r->uri)));
            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, &ltl)) != 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_setn(r->headers_out, "Lock-Token", locktoken_txt);
        }
    
        (*locks_hooks->close_lockdb)(lockdb);
    
        r->status = HTTP_OK;
        ap_set_content_type_ex(r, DAV_XML_CONTENT_TYPE, 1);
    
        ap_rputs(DAV_XML_HEADER DEBUG_CR "<D:prop xmlns:D=\"DAV:\">" DEBUG_CR, r);
        if (lock == NULL)
            ap_rputs("<D:lockdiscovery/>" DEBUG_CR, r);
        else {
            ap_rprintf(r,
                       "<D:lockdiscovery>" DEBUG_CR
                       "%s" DEBUG_CR
                       "</D:lockdiscovery>" DEBUG_CR,
                       dav_lock_get_activelock(r, lock, NULL));
        }
        ap_rputs("</D:prop>", 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, APLOGNO(00596)
                          "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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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 infinite lock.  Thus, an UNLOCK
         *     on any part of an infinite 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);
    
        /* 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 */
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            return dav_handle_err(r, err, NULL);
        }
    
        /* remember the pre-creation resource state */
        resource_state = dav_get_resource_state(r, resource);
    
        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, APLOGNO(00597)
                              "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, APLOGNO(00598)
                              "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, APLOGNO(00599)
                              "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, APLOGNO(00600)
                              "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, 0,
                                "<DAV:initial-version-required/>");
            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, 0,
                                    "<DAV:cannot-add-to-existing-history/>");
                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, 0,
                                    "<DAV:must-be-versionable/>");
                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, APLOGNO(00601)
                              "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:
                           <!ELEMENT activity-set (href+ | new)>
                        */
    
                        /* This supplies additional info for the default msg. */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00602)
                                      "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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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, APLOGNO(00603)
                              "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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            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, APLOGNO(00604)
                          "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, APLOGNO(00605)
                              "The version element does not contain "
                              "an \"href\" element.");
                return HTTP_BAD_REQUEST;
            }
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00606)
                          "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, APLOGNO(00607)
                          "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, APLOGNO(00608)
                          "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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            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,
                                      "<DAV:must-be-checked-in-version-controlled-resource>");
        }
    
        /* 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, APLOGNO(00609)
                                  "%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;
    
        /* original request */
        request_rec *r;
    
        /* 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 for any method preconditions */
        if (dav_run_method_precondition(ctx->r, NULL, wres->resource, NULL, &err) != DECLINED
                && err) {
        	/* precondition failed, dropping through */
        }
    
        /* 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)
         */
        else 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, 0,
                                "<DAV:must-be-version-or-version-selector/>");
        }
        else if (wres->resource->working) {
            err = dav_new_error(ctx->w.pool, HTTP_CONFLICT, 0, 0,
                                "<DAV:must-not-be-checked-out/>");
        }
        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;
    
        /* parse the request body */
        if ((result = ap_xml_parse_input(r, &doc)) != OK) {
            return result;
        }
    
        /* 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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            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;
        }
    
        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, APLOGNO(00610)
                          "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, APLOGNO(00611)
                          "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, APLOGNO(00612)
                          "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, APLOGNO(00613)
                          "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.r = r;
        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, 0,
                                    multi_status->desc);
                multi_status = NULL;
            }
            else {
                err = dav_new_error(r->pool, HTTP_MULTI_STATUS, 0, 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_core_deliver_report(request_rec *r,
                              const dav_resource *resource,
                              const apr_xml_doc *doc,
                              ap_filter_t *output, dav_error **err)
    {
        const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r);
    
        if (vsn_hooks) {
            *err = (*vsn_hooks->deliver_report)(r, resource, doc,
                                                r->output_filters);
            return OK;
        }
    
        return DECLINED;
    }
    
    static void dav_core_gather_reports(
        request_rec *r,
        const dav_resource *resource,
        apr_array_header_t *reports,
        dav_error **err)
    {
        const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r);
    
        if (vsn_hooks) {
            const dav_report_elem *rp;
    
            (*err) = (*vsn_hooks->avail_reports)(resource, &rp);
            while (rp && rp->name) {
    
                dav_report_elem *report = apr_array_push(reports);
    
                report->nmspace = rp->nmspace;
                report->name = rp->name;
    
                rp++;
            }
        }
    
    }
    
    static int dav_method_report(request_rec *r)
    {
        dav_resource *resource;
        const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r);
        apr_xml_doc *doc;
        dav_error *err = NULL;
    
        int result;
        int label_allowed;
    
        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, APLOGNO(00614)
                          "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 ? (*vsn_hooks->report_label_header_allowed)(doc) : 0;
        err = dav_get_resource(r, label_allowed, 0 /* use_checked_in */,
                               &resource);
        if (err != NULL) {
            return dav_handle_err(r, err, NULL);
        }
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            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);
        err = NULL;
    
        /* run report hook */
        result = dav_run_deliver_report(r, resource, doc,
                r->output_filters, &err);
        if (err != 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;
        }
        switch (result) {
        case OK:
            return DONE;
        case DECLINED:
            /* No one handled the report */
            return HTTP_NOT_IMPLEMENTED;
        default:
            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;
        }
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, doc, &err) != DECLINED
                && err) {
            return dav_handle_err(r, err, NULL);
        }
    
        if (doc == NULL
            || !dav_validate_root(doc, "mkworkspace")) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00615)
                          "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, 0,
                                "<DAV:resource-must-be-null/>");
            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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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, 0,
                                "<DAV:resource-must-be-null/>");
            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, 0,
                              "<DAV:activity-location-ok/>");
          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, APLOGNO(00616)
                          "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, APLOGNO(00617)
                          "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, APLOGNO(00618)
                          "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, APLOGNO(00619)
                              "%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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, source_resource, NULL, doc, &err) != DECLINED
                && err) {
            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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, source_resource, resource, doc, &err) != DECLINED
                && err) {
            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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, NULL, NULL, &err) != DECLINED
                && err) {
            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, APLOGNO(00620)
                          "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, APLOGNO(00621)
                              "%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);
    
        /* check for any method preconditions */
        if (dav_run_method_precondition(r, resource, binding, NULL, &err) != DECLINED
                && err) {
            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->unparsed_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, APLOGNO(00622)
                         "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_hook_deliver_report(dav_core_deliver_report,
                                NULL, NULL, APR_HOOK_LAST);
        dav_hook_gather_reports(dav_core_gather_reports,
                                NULL, NULL, APR_HOOK_LAST);
    
        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 */
        AP_INIT_TAKE1("DAVBasePath", dav_cmd_davbasepath, NULL, ACCESS_CONF,
                      "specify the DAV repository base URL"),
    
        /* 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"),
    
        /* per directory/location, or per server */
        AP_INIT_FLAG("DAVLockDiscovery", dav_cmd_davlockdiscovery, NULL,
                     ACCESS_CONF|RSRC_CONF,
                     "allow lock discovery by 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_HOOK_LINK(deliver_report)
        APR_HOOK_LINK(gather_reports)
        APR_HOOK_LINK(method_precondition)
        )
    
    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))
    
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(dav, DAV, int, deliver_report,
                                          (request_rec *r,
                                           const dav_resource *resource,
                                           const apr_xml_doc *doc,
                                           ap_filter_t *output, dav_error **err),
                                          (r, resource, doc, output, err), DECLINED)
    
    APR_IMPLEMENT_EXTERNAL_HOOK_VOID(dav, DAV, gather_reports,
                                       (request_rec *r, const dav_resource *resource,
                                        apr_array_header_t *reports, dav_error **err),
                                       (r, resource, reports, err))
    
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(dav, DAV, int, method_precondition,
                                          (request_rec *r,
                                           dav_resource *src, const dav_resource *dest,
                                           const apr_xml_doc *doc,
                                           dav_error **err),
                                           (r, src, dest, doc, err), DECLINED)
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/std_liveprop.c��������������������������������������������������������0000664�0001751�0001751�00000017060�13700346712�020655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "ap_provider.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 = NULL;
        const char *s;
        apr_pool_t *p = resource->pool;
        const dav_liveprop_spec *info;
        long global_ns;
    
        switch (propid)
        {
        case DAV_PROPID_resourcetype:
            { /* additional type info provided by external modules ? */
                int i;
    
                apr_array_header_t *extensions =
                    ap_list_provider_names(p, DAV_RESOURCE_TYPE_GROUP, "0");
                ap_list_provider_names_t *entry =
                    (ap_list_provider_names_t *)extensions->elts;
    
                for (i = 0; i < extensions->nelts; i++, entry++) {
                    const dav_resource_type_provider *res_hooks =
                        dav_get_resource_type_providers(entry->provider_name);
                    const char *name = NULL, *uri = NULL;
    
                    if (!res_hooks || !res_hooks->get_resource_type)
                        continue;
    
                    if (!res_hooks->get_resource_type(resource, &name, &uri) &&
                        name) {
    
                        if (!uri || !strcasecmp(uri, "DAV:"))
                            value = apr_pstrcat(p, value ? value : "",
                                                "<D:", name, "/>", NULL);
                        else
                            value = apr_pstrcat(p, value ? value : "",
                                                "<x:", name,
                                                " xmlns:x=\"", uri,
                                                "\"/>", NULL);
                    }
                }
            }
            switch (resource->type) {
            case DAV_RESOURCE_TYPE_VERSION:
                if (resource->baselined) {
                    value = apr_pstrcat(p, value ? value : "", "<D:baseline/>", NULL);
                    break;
                }
                /* fall through */
            case DAV_RESOURCE_TYPE_REGULAR:
            case DAV_RESOURCE_TYPE_WORKING:
                if (resource->collection) {
                    value = apr_pstrcat(p, value ? value : "", "<D:collection/>", NULL);
                }
                else {
                    /* ### should we denote lock-null resources? */
                    if (value == NULL) {
                        value = "";        /* becomes: <D:resourcetype/> */
                    }
                }
                break;
            case DAV_RESOURCE_TYPE_HISTORY:
                value = apr_pstrcat(p, value ? value : "", "<D:version-history/>", NULL);
                break;
            case DAV_RESOURCE_TYPE_WORKSPACE:
                value = apr_pstrcat(p, value ? value : "", "<D:collection/>", NULL);
                break;
            case DAV_RESOURCE_TYPE_ACTIVITY:
                value = apr_pstrcat(p, value ? value : "", "<D:activity/>", NULL);
                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_pstrcat(p,
                             "<D:supported-live-property D:name=\"", info->name,
                             "\" D:namespace=\"", dav_core_namespace_uris[info->ns],
                             "\"/>" DEBUG_CR, NULL);
        }
        else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') {
            s = apr_psprintf(p, "<lp%ld:%s>%s</lp%ld:%s>" DEBUG_CR,
                             global_ns, info->name, value, global_ns, info->name);
        }
        else {
            s = apr_psprintf(p, "<lp%ld:%s/>" 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);
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/main/NWGNUmakefile���������������������������������������������������������0000664�0001751�0001751�00000010717�11541421667�020324� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/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	= 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	= $(NLM_NAME) 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	=
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_dav.o \
    	$(OBJDIR)/liveprop.o \
    	$(OBJDIR)/props.o \
    	$(OBJDIR)/providers.o \
    	$(OBJDIR)/std_liveprop.o \
    	$(OBJDIR)/util.o \
    	$(OBJDIR)/util_lock.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 = \
    	$(PRELUDE) \
    	$(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 \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������httpd-2.4.64/modules/dav/main/liveprop.c������������������������������������������������������������0000664�0001751�0001751�00000010435�10455005461�017777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 long 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)
    {
        long 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 = (long)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(long) dav_get_liveprop_ns_index(const char *uri)
    {
        return (long)apr_hash_get(dav_liveprop_uris, uri, APR_HASH_KEY_STRING);
    }
    
    DAV_DECLARE(long) 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%ld=\"%s\"", (long)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(long) 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);
        }
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015466� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/mod_dav_fs.mak����������������������������������������������������������0000664�0001751�0001751�00000026322�12701473373�020263� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_dav_fs.dsp
    !IF "$(CFG)" == ""
    CFG=mod_dav_fs - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_dav_fs - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_dav_fs - Win32 Release" && "$(CFG)" != "mod_dav_fs - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_fs - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dav_fs.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dav - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_dav_fs.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_dav - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\dbm.obj"
    	-@erase "$(INTDIR)\lock.obj"
    	-@erase "$(INTDIR)\mod_dav_fs.obj"
    	-@erase "$(INTDIR)\mod_dav_fs.res"
    	-@erase "$(INTDIR)\mod_dav_fs_src.idb"
    	-@erase "$(INTDIR)\mod_dav_fs_src.pdb"
    	-@erase "$(INTDIR)\repos.obj"
    	-@erase "$(OUTDIR)\mod_dav_fs.exp"
    	-@erase "$(OUTDIR)\mod_dav_fs.lib"
    	-@erase "$(OUTDIR)\mod_dav_fs.pdb"
    	-@erase "$(OUTDIR)\mod_dav_fs.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dav_fs_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dav_fs.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dav_fs.so" /d LONG_NAME="dav_fs_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dav_fs.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dav_fs.pdb" /debug /out:"$(OUTDIR)\mod_dav_fs.so" /implib:"$(OUTDIR)\mod_dav_fs.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\dbm.obj" \
    	"$(INTDIR)\lock.obj" \
    	"$(INTDIR)\mod_dav_fs.obj" \
    	"$(INTDIR)\repos.obj" \
    	"$(INTDIR)\mod_dav_fs.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib" \
    	"..\main\Release\mod_dav.lib"
    
    "$(OUTDIR)\mod_dav_fs.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_dav_fs.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dav_fs.so"
       if exist .\Release\mod_dav_fs.so.manifest mt.exe -manifest .\Release\mod_dav_fs.so.manifest -outputresource:.\Release\mod_dav_fs.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_dav_fs - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dav_fs.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dav - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_dav_fs.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_dav - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\dbm.obj"
    	-@erase "$(INTDIR)\lock.obj"
    	-@erase "$(INTDIR)\mod_dav_fs.obj"
    	-@erase "$(INTDIR)\mod_dav_fs.res"
    	-@erase "$(INTDIR)\mod_dav_fs_src.idb"
    	-@erase "$(INTDIR)\mod_dav_fs_src.pdb"
    	-@erase "$(INTDIR)\repos.obj"
    	-@erase "$(OUTDIR)\mod_dav_fs.exp"
    	-@erase "$(OUTDIR)\mod_dav_fs.lib"
    	-@erase "$(OUTDIR)\mod_dav_fs.pdb"
    	-@erase "$(OUTDIR)\mod_dav_fs.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dav_fs_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dav_fs.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dav_fs.so" /d LONG_NAME="dav_fs_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dav_fs.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dav_fs.pdb" /debug /out:"$(OUTDIR)\mod_dav_fs.so" /implib:"$(OUTDIR)\mod_dav_fs.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so 
    LINK32_OBJS= \
    	"$(INTDIR)\dbm.obj" \
    	"$(INTDIR)\lock.obj" \
    	"$(INTDIR)\mod_dav_fs.obj" \
    	"$(INTDIR)\repos.obj" \
    	"$(INTDIR)\mod_dav_fs.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib" \
    	"..\main\Debug\mod_dav.lib"
    
    "$(OUTDIR)\mod_dav_fs.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_dav_fs.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dav_fs.so"
       if exist .\Debug\mod_dav_fs.so.manifest mt.exe -manifest .\Debug\mod_dav_fs.so.manifest -outputresource:.\Debug\mod_dav_fs.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_dav_fs.dep")
    !INCLUDE "mod_dav_fs.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_dav_fs.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_dav_fs - Win32 Release" || "$(CFG)" == "mod_dav_fs - Win32 Debug"
    SOURCE=.\dbm.c
    
    "$(INTDIR)\dbm.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\lock.c
    
    "$(INTDIR)\lock.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\mod_dav_fs.c
    
    "$(INTDIR)\mod_dav_fs.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\repos.c
    
    "$(INTDIR)\repos.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_dav_fs - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\dav\fs"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\fs"
    
    !ELSEIF  "$(CFG)" == "mod_dav_fs - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\dav\fs"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\fs"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_fs - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\dav\fs"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\fs"
    
    !ELSEIF  "$(CFG)" == "mod_dav_fs - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\dav\fs"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\fs"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_fs - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\dav\fs"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\dav\fs"
    
    !ELSEIF  "$(CFG)" == "mod_dav_fs - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\dav\fs"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\dav\fs"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_fs - Win32 Release"
    
    "mod_dav - Win32 Release" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Release" 
       cd "..\fs"
    
    "mod_dav - Win32 ReleaseCLEAN" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Release" RECURSE=1 CLEAN 
       cd "..\fs"
    
    !ELSEIF  "$(CFG)" == "mod_dav_fs - Win32 Debug"
    
    "mod_dav - Win32 Debug" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Debug" 
       cd "..\fs"
    
    "mod_dav - Win32 DebugCLEAN" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\fs"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_dav_fs - Win32 Release"
    
    
    "$(INTDIR)\mod_dav_fs.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dav_fs.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_dav_fs.so" /d LONG_NAME="dav_fs_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_dav_fs - Win32 Debug"
    
    
    "$(INTDIR)\mod_dav_fs.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dav_fs.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_dav_fs.so" /d LONG_NAME="dav_fs_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/mod_dav_fs.c������������������������������������������������������������0000664�0001751�0001751�00000006460�11402752006�017724� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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);
    }
    
    AP_DECLARE_MODULE(dav_fs) =
    {
        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 */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/repos.c�����������������������������������������������������������������0000664�0001751�0001751�00000230002�14526656032�016756� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_UNISTD_H
    #include <unistd.h>             /* for getpid() */
    #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"
    
    APLOG_USE_MODULE(dav_fs);
    
    /* 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 */
        request_rec *r;
    };
    
    /* 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
    **
    ** DAV_FINFO_MASK gives the appropriate mask to use for the stat call
    ** used to get file attributes.
    */
    #ifndef WIN32
    #define DAV_FS_HAS_EXECUTABLE
    #define DAV_FINFO_MASK (APR_FINFO_LINK | APR_FINFO_TYPE | APR_FINFO_INODE | \
                            APR_FINFO_SIZE | APR_FINFO_CTIME | APR_FINFO_MTIME | \
                            APR_FINFO_PROT)
    #else
    /* as above, but without APR_FINFO_PROT */
    #define DAV_FINFO_MASK (APR_FINFO_LINK | APR_FINFO_TYPE | APR_FINFO_INODE | \
                            APR_FINFO_SIZE | APR_FINFO_CTIME | APR_FINFO_MTIME)
    #endif
    
    /*
    ** The single property that we define (in the DAV_FS_URI_MYPROPS namespace)
    */
    #define DAV_PROPID_FS_executable        1
    
    /*
     * prefix for temporary files
     */
    #define DAV_FS_TMP_PREFIX ".davfs.tmp"
    
    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 */
        char *temppath;
        int unlink_on_error;
    };
    
    /* 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 : \
                            APR_STATUS_IS_ENOENT(e) ? HTTP_CONFLICT : \
                            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
    */
    static request_rec *dav_fs_get_request_rec(const dav_resource *resource)
    {
        return resource->info->r;
    }
    
    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, rv,
                                     "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_size_t buflen)
    {
        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 */
            apr_snprintf(buf, buflen, "%.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 */
        apr_snprintf(buf, buflen, "%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 ((status = apr_file_perms_set(dst, perms)) != APR_SUCCESS) {
                    return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, status,
                                         "Could not set permissions on destination");
                }
            }
        }
        else {
            perms = APR_OS_DEFAULT;
        }
    
        dav_set_bufsize(p, pbuf, DAV_FS_COPY_BLOCKSIZE);
    
        if ((status = 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, status,
                                 "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, status,
                                 "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_status_t lcl_status;
    
                apr_file_close(inf);
                apr_file_close(outf);
    
                if ((lcl_status = apr_file_remove(dst, p)) != APR_SUCCESS) {
                    /* ### ACK! Inconsistent state... */
    
                    /* ### use something besides 500? */
                    return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
                                         lcl_status,
                                         "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, status,
                                     "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_status_t lcl_status;
    
                apr_file_close(inf);
                apr_file_close(outf);
    
                if ((lcl_status = apr_file_remove(dst, p)) != APR_SUCCESS) {
                    /* ### ACK! Inconsistent state... */
    
                    /* ### use something besides 500? */
                    return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
                                         lcl_status,
                                         "Could not delete output after write "
                                         "failure. Server is now in an "
                                         "inconsistent state.");
                }
    
                return dav_new_error(p, MAP_IO2HTTP(status), 0, status,
                                     "Could not write output file");
            }
        }
    
        apr_file_close(inf);
        apr_file_close(outf);
    
        if (is_move && (status = apr_file_remove(src, p)) != APR_SUCCESS) {
            dav_error *err;
            apr_status_t lcl_status;
    
            if (APR_STATUS_IS_ENOENT(status)) {
                /*
                 * Something is wrong here but the result is what we wanted.
                 * We definitely should not remove the destination file.
                 */
                err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, status,
                                     apr_psprintf(p, "Could not remove source "
                                                  "file %s after move to %s. The "
                                                  "server may be in an "
                                                  "inconsistent state.", src, dst));
                return err;
            }
            else if ((lcl_status = apr_file_remove(dst, p)) != APR_SUCCESS) {
                /* ### ACK. this creates an inconsistency. do more!? */
    
                /* ### use something besides 500? */
                return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, lcl_status,
                                     "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, status,
                                "Could not remove source file after move. "
                                "Destination was removed to ensure consistency.");
            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, rv,
                                     "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, rv,
                                 "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, 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) {
            /* try simple rename first */
            rv = apr_file_rename(src, dst, p);
            if (APR_STATUS_IS_EXDEV(rv)) {
                return dav_fs_copymove_file(is_move, p, src, dst, NULL, NULL, pbuf);
            }
            if (rv != APR_SUCCESS) {
                /* ### use something besides 500? */
                return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                                     "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, 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, status,
                                 "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, status,
                                     "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;
        ctx->r = r;
    
        /* ### 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_pstrmemdup(r->pool, r->uri, len-1);
            resource->uri = s;
        }
        else {
            resource->uri = r->uri;
        }
    
        if (r->finfo.filetype != APR_NOFILE) {
            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, 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 = APR_NOFILE;
                }
            }
        }
    
        *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 != APR_NOFILE) && (ctx2->finfo.filetype != APR_NOFILE)
            && (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 apr_status_t tmpfile_cleanup(void *data)
    {
        dav_stream *ds = data;
        if (ds->temppath) {
            apr_file_remove(ds->temppath, ds->p);
        }
        return APR_SUCCESS;
    }
    
    /* custom mktemp that creates the file with APR_OS_DEFAULT permissions */
    static apr_status_t dav_fs_mktemp(apr_file_t **fp, char *templ, apr_pool_t *p)
    {
        apr_status_t rv;
        int num = ((getpid() << 7) + (apr_uintptr_t)templ % (1 << 16) ) %
                   ( 1 << 23 ) ;
        char *numstr = templ + strlen(templ) - 6;
    
        ap_assert(numstr >= templ);
    
        do {
            num = (num + 1) % ( 1 << 23 );
            apr_snprintf(numstr, 7, "%06x", num);
            rv = apr_file_open(fp, templ,
                               APR_WRITE | APR_CREATE | APR_BINARY | APR_EXCL,
                               APR_OS_DEFAULT, p);
        } while (APR_STATUS_IS_EEXIST(rv));
    
        return rv;
    }
    
    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;
        ds->temppath = NULL;
        ds->unlink_on_error = 0;
    
        if (mode == DAV_MODE_WRITE_TRUNC) {
            ds->temppath = apr_pstrcat(p, ap_make_dirstr_parent(p, ds->pathname),
                                       DAV_FS_TMP_PREFIX "XXXXXX", NULL);
            rv = dav_fs_mktemp(&ds->f, ds->temppath, ds->p);
            apr_pool_cleanup_register(p, ds, tmpfile_cleanup,
                                      apr_pool_cleanup_null);
        }
        else if (mode == DAV_MODE_WRITE_SEEKABLE) {
            rv = apr_file_open(&ds->f, ds->pathname, flags | APR_FOPEN_EXCL,
                               APR_OS_DEFAULT, ds->p);
            if (rv == APR_SUCCESS) {
                /* we have created a new file */
                ds->unlink_on_error = 1;
            }
            else if (APR_STATUS_IS_EEXIST(rv)) {
                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, rv,
                                        apr_psprintf(p, "Could not open an existing "
                                                     "resource for writing: %s.",
                                                     ds->pathname));
                }
            }
        }
        else {
            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, rv,
                                     apr_psprintf(p, "Could not open an existing "
                                                  "resource for reading: %s.",
                                                  ds->pathname));
            }
        }
    
        if (rv != APR_SUCCESS) {
            return dav_new_error(p, MAP_IO2HTTP(rv), 0, rv,
                                 apr_psprintf(p, "An error occurred while opening "
                                              "a resource for writing: %s.",
                                              ds->pathname));
        }
    
        /* (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_status_t rv;
    
        apr_file_close(stream->f);
    
        if (!commit) {
            if (stream->temppath) {
                apr_pool_cleanup_run(stream->p, stream, tmpfile_cleanup);
            }
            else if (stream->unlink_on_error) {
                if ((rv = apr_file_remove(stream->pathname, stream->p))
                    != APR_SUCCESS) {
                    /* ### use a better description? */
                    return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
                                         rv,
                                         "There was a problem removing (rolling "
                                         "back) the resource "
                                         "when it was being closed.");
                }
            }
        }
        else if (stream->temppath) {
            rv = apr_file_rename(stream->temppath, stream->pathname, stream->p);
            if (rv) {
                return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                                     "There was a problem writing the file "
                                     "atomically after writes.");
            }
            apr_pool_cleanup_kill(stream->p, stream, tmpfile_cleanup);
        }
    
        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, status,
                                 "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, status,
                                 "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)
    {
        apr_status_t status;
    
        if ((status = 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, status,
                                 "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 <resource> */
        ap_set_last_modified(r);
        ap_set_etag(r);
    
        /* we accept byte-ranges */
        ap_set_accept_ranges(r);
    
        /* 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, 0,
                                 "Cannot GET this type of resource.");
        }
        if (resource->collection) {
            return dav_new_error(pool, HTTP_CONFLICT, 0, 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, status,
                                 "File permissions deny server access.");
        }
    
        bb = apr_brigade_create(pool, output->c->bucket_alloc);
    
        apr_brigade_insert_file(bb, fd, 0, resource->info->finfo.size, pool);
    
        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, AP_FILTER_ERROR, 0, status,
                                 "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, status,
                                 "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, status,
                                 "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, status,
                                 "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)
    {
        apr_status_t status;
        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 ((status = 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, status, 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(&params, 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, 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, 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;
        apr_status_t rv;
    
    #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, 0,
                                 "DESIGN ERROR: a mix of repositories "
                                 "was passed to move_resource.");
        }
    #endif
    
    
        /* try rename first */
        rv = apr_file_rename(srcinfo->pathname, dstinfo->pathname, srcinfo->pool);
    
        /* if we can't simply rename, then do it the hard way... */
        if (APR_STATUS_IS_EXDEV(rv)) {
            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;
        }
    
        /* no multistatus response */
        *response = NULL;
    
        if (rv != APR_SUCCESS) {
            /* ### should have a better error than this. */
            return dav_new_error(srcinfo->pool, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                                 "Could not rename resource.");
        }
    
        /* Rename did work. Update resource states and move properties as well */
        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)
    {
        apr_status_t status;
        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(&params, 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, 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 ((status = apr_file_remove(info->pathname, info->pool)) != APR_SUCCESS) {
            /* ### put a description in here */
            return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, status, 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;
        apr_status_t status;
        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 ((status = apr_dir_open(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {
            /* ### need a better error */
            return dav_new_error(pool, HTTP_NOT_FOUND, 0, status, NULL);
        }
        while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {
            apr_size_t len;
    
            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 and temp files are never authorized! */
                if (!strcmp(dirent.name, DAV_FS_STATE_DIR) ||
                    !strncmp(dirent.name, DAV_FS_TMP_PREFIX,
                             strlen(DAV_FS_TMP_PREFIX))) {
                    continue;
                }
            }
            /* skip the state dir and temp files unless a HIDDEN is performed */
            if (!(params->walk_type & DAV_WALKTYPE_HIDDEN)
                && (!strcmp(dirent.name, DAV_FS_STATE_DIR) ||
                    !strncmp(dirent.name, DAV_FS_TMP_PREFIX,
                             strlen(DAV_FS_TMP_PREFIX)))) {
                continue;
            }
    
            /* append this file onto the path buffer (copy null term) */
            dav_buffer_place_mem(pool, &fsctx->path1, dirent.name, len + 1, 0);
    
            status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf,
                              DAV_FINFO_MASK, pool);
            if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
                dav_resource_private *ctx = params->root->info;
    
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, ctx->r,
                              APLOGNO(10472) "could not access file (%s) during directory walk",
                              fsctx->path1.buf);
    
                /* If being tolerant, ignore failure due to losing a race
                 * with some other process deleting files out from under
                 * the directory walk. */
                if ((params->walk_type & DAV_WALKTYPE_TOLERANT)
                    && APR_STATUS_IS_ENOENT(status)) {
                    continue;
                }
                /* woah! where'd it go? */
                /* ### should have a better error here */
                err = dav_new_error(pool, HTTP_NOT_FOUND, 0, status, 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-existent (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, 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: Creates an etag for the file path.
     */
    static const char *dav_fs_getetag(const dav_resource *resource)
    {
        etag_rec er;
    
        dav_resource_private *ctx = resource->info;
    
        if (!resource->exists || !ctx->r) {
            return "";
        }
    
        er.vlist_validator = NULL;
        er.request_time = ctx->r->request_time;
        er.finfo = &ctx->finfo;
        er.pathname = ctx->pathname;
        er.fd = NULL;
        er.force_weak = 0;
    
        return ap_make_etag_ex(ctx->r, &er);
    }
    
    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,
        NULL,
        dav_fs_get_request_rec,
        dav_fs_pathname
    };
    
    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;
        long 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, sizeof(buf));
            value = buf;
            break;
    
        case DAV_PROPID_getcontentlength:
            /* our property, but not defined on collection resources */
            if (resource->collection)
                return DAV_PROP_INSERT_NOTDEF;
    
            apr_snprintf(buf, sizeof(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, sizeof(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, "<lp%ld:%s>%s</lp%ld:%s>" DEBUG_CR,
                             global_ns, info->name, value, global_ns, info->name);
        }
        else if (what == DAV_PROP_INSERT_NAME) {
            s = apr_psprintf(p, "<lp%ld:%s/>" DEBUG_CR, global_ns, info->name);
        }
        else {
            /* assert: what == DAV_PROP_INSERT_SUPPORTED */
            s = apr_pstrcat(p,
                            "<D:supported-live-property D:name=\"",
                            info->name,
                            "\" D:namespace=\"",
                            dav_fs_namespace_uris[info->ns],
                            "\"/>" DEBUG_CR, NULL);
        }
        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, 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, 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, 0,
                                 "The 'executable' property expects a single "
                                 "character, valued 'T' or 'F'. The value "
                                 "submitted is invalid.");
        }
    
        *context = (void *)((long)(value == 'T'));
    
        return NULL;
    
      too_long:
        return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, 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)
    {
        long value = context != NULL;
        apr_fileperms_t perms = resource->info->finfo.protection;
        apr_status_t status;
        long 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 ((status = apr_file_perms_set(resource->info->pathname, perms))
            != APR_SUCCESS) {
            return dav_new_error(resource->info->pool,
                                 HTTP_INTERNAL_SERVER_ERROR, 0, status,
                                 "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;
        apr_status_t status;
        int value = rollback_ctx != NULL;
    
        /* assert: prop == executable. operation == SET. */
    
        /* restore the executable bit */
        if (value)
            perms |= APR_UEXECUTE;
    
        if ((status = apr_file_perms_set(resource->info->pathname, perms))
            != APR_SUCCESS) {
            return dav_new_error(resource->info->pool,
                                 HTTP_INTERNAL_SERVER_ERROR, 0, status,
                                 "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) =
            "<http://apache.org/dav/propset/fs/1>";
    #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);
    }
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/config6.m4��������������������������������������������������������������0000664�0001751�0001751�00000001113�11707053320�017243� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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.  --enable-dav also enables mod_dav_fs., $dav_fs_objects, , $dav_fs_enable,,dav)
    
    APACHE_MODPATH_FINISH
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/repos.h�����������������������������������������������������������������0000664�0001751�0001751�00000006474�10455005461�016770� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  repos.h
     * @brief Declarations for the filesystem repository implementation
     *
     * @addtogroup MOD_DAV
     * @{
     */
    
    #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_ */
    /** @} */
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/dbm.c�������������������������������������������������������������������0000664�0001751�0001751�00000056722�14741720500�016376� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "apr_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    #include "mod_dav.h"
    #include "repos.h"
    #include "http_log.h"
    #include "http_main.h"      /* for ap_server_conf */
    
    APLOG_USE_MODULE(dav_fs);
    
    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 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 <db> if we had problems creating it. */
        if (db == NULL) {
            errcode = 1;
            errstr = "Could not open database.";
            if (APR_STATUS_IS_EDSOOPEN(status))
                ap_log_error(APLOG_MARK, APLOG_CRIT, status, ap_server_conf, APLOGNO(00576)
                "The DBM driver could not be loaded");
        }
        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, status, errstr);
        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)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *file = NULL;
        apr_status_t status;
    
        *pdb = NULL;
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((status = apr_dbm_get_driver(&driver, NULL, &err, p)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, APLOGNO(10289)
                         "mod_dav_fs: The DBM library '%s' could not be loaded: %s",
                                 err->reason, err->msg);
            return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 1, status,
                    "Could not load library for database.");
        }
        if ((status = apr_dbm_open2(&file, driver, pathname,
                                   ro ? APR_DBM_READONLY : APR_DBM_RWCREATE,
                                   APR_OS_DEFAULT, p))
                                   != APR_SUCCESS && !ro) {
            return dav_fs_dbm_error(NULL, p, status);
        }
    #else
        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);
        }
    #endif
    
        /* 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;
    
        if (!key.dptr) {
            /* no key could be created (namespace not known) => no value */
            memset(pvalue, 0, sizeof(*pvalue));
            status = APR_SUCCESS;
        } else {
            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 {
            long ns_id = (long)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 = apr_snprintf(nsbuf, sizeof(nsbuf), "%ld", 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_pstrcat(pool, "<", name+1, "/>" DEBUG_CR, NULL);
            }
            else {
                s = apr_pstrcat(pool, "<ns", name, "/>" DEBUG_CR, NULL);
            }
        }
        else if (*lang != '\0') {
            if (*name == ':') {
                /* "no namespace" case */
                s = apr_pstrcat(pool, "<", name+1, " xml:lang=\"",
                                lang, "\">", value, "</", name+1, ">" DEBUG_CR,
                                NULL);
            }
            else {
                s = apr_pstrcat(pool, "<ns", name, " xml:lang=\"",
                                lang, "\">", value, "</ns", name, ">" DEBUG_CR,
                                NULL);
            }
        }
        else if (*name == ':') {
            /* "no namespace" case */
            s = apr_pstrcat(pool, "<", name+1, ">", value, "</", name+1, ">"
                            DEBUG_CR, NULL);
        }
        else {
            s = apr_pstrcat(pool, "<ns", name, ">", value, "</ns", name, ">"
                            DEBUG_CR, NULL);
        }
    
        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, 0,
                                     "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;
            long 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, 0,
                                     "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);
            if (err != NULL)
                ap_log_error(APLOG_MARK, APLOG_WARNING, err->aprerr, ap_server_conf,
                             APLOGNO(00577) "Error writing propdb: %s", err->desc);
        }
    
        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);
            long ns_id = (long)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 *)((long)(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) {
            return NULL; /* no rollback, nothing to do */
        }
    
        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 */
    };
    ����������������������������������������������httpd-2.4.64/modules/dav/fs/mod_dav_fs.dep����������������������������������������������������������0000664�0001751�0001751�00000017325�12674411515�020265� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_dav_fs.mak
    
    .\dbm.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\http_main.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\mod_dav.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\repos.h"\
    	
    
    .\lock.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\mod_dav.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\repos.h"\
    	
    
    .\mod_dav_fs.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\mod_dav.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\repos.h"\
    	
    
    .\repos.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\http_protocol.h"\
    	"..\..\..\include\http_request.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\mod_dav.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\repos.h"\
    	
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/mod_dav_fs.dsp����������������������������������������������������������0000664�0001751�0001751�00000011633�10551346420�020271� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_dav_fs.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dav_fs.so" /d LONG_NAME="dav_fs_module for Apache"
    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 /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 /out:".\Release\mod_dav_fs.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_dav_fs.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_dav_fs.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dav_fs.so" /d LONG_NAME="dav_fs_module for Apache"
    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 /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 /out:".\Debug\mod_dav_fs.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_dav_fs.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/lock.c������������������������������������������������������������������0000664�0001751�0001751�00000131737�13623622544�016573� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_FNAME)
    ** followed by the full path. The key_type DAV_TYPE_INODE is not used anymore.
    **
    ** 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
    
    /*
     * not used anymore
     * #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 <db> field may be NULL, meaning one of two things:
    ** 1) That we have not actually opened the underlying database (yet). The
    **    <opened> field should be false.
    ** 2) We opened it readonly and it wasn't present.
    **
    ** The delayed opening (determined by <opened>) 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, 0,
                                 "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, 0,
                                 "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, 0,
                                 "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_key:  Given a resource, return a apr_datum_t key
    **    to look up lock information for this file.
    */
    static apr_datum_t dav_fs_build_key(apr_pool_t *p,
                                        const dav_resource *resource)
    {
        const char *pathname = dav_fs_pathname(resource);
        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_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, 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_pmemdup(p, 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_pmemdup(p, 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_pmemdup(p, 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, 0,
                                     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 <indirect>, 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, 0,
                             "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
            "<D:lockentry>" DEBUG_CR
            "<D:lockscope><D:exclusive/></D:lockscope>" DEBUG_CR
            "<D:locktype><D:write/></D:locktype>" DEBUG_CR
            "</D:lockentry>" DEBUG_CR
            "<D:lockentry>" DEBUG_CR
            "<D:lockscope><D:shared/></D:lockscope>" DEBUG_CR
            "<D:locktype><D:write/></D:locktype>" DEBUG_CR
            "</D:lockentry>" 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, rv,
                                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, 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 ((rv = apr_file_read(file, pbuf->buf, &amt)) != APR_SUCCESS
            || amt != finfo.size) {
            err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                                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;
        apr_status_t rv;
    
        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 ((rv = apr_file_remove(pathname, p)) != APR_SUCCESS) {
                return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                                     apr_psprintf(p,
                                                 "Error removing %s", pathname));
            }
            return NULL;
        }
    
        if ((rv = 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, rv,
                                 apr_psprintf(p,
                                             "Error opening %s for writing",
                                             pathname));
        }
    
        amt = pbuf->cur_len;
        if ((rv = apr_file_write_full(file, pbuf->buf, amt, &amt)) != APR_SUCCESS
            || amt != pbuf->cur_len) {
            err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                                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 existent state, i.e.
    **    remove it from the list in the appropriate .DAV/locknull file.
    */
    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;
        }
    
        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, 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 <lock> 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;
                break;
            }
        }
    
        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 */
    };
    ���������������������������������httpd-2.4.64/modules/dav/fs/NWGNUmakefile�����������������������������������������������������������0000664�0001751�0001751�00000010650�11541421667�020004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/netware \
    			$(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	= 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	= $(NLM_NAME) 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	=
    
    #
    # 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 this is specified it will be used by the link '-flags' directive
    #
    NLM_FLAGS	=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_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 = \
    	$(PRELUDE) \
    	$(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 \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/fs/Makefile.in�������������������������������������������������������������0000664�0001751�0001751�00000000267�10150161574�017526� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016006� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/mod_dav_lock.dep������������������������������������������������������0000664�0001751�0001751�00000007416�12674411515�021125� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_dav_lock.mak
    
    .\locks.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\http_log.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\mod_dav.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\locks.h"\
    	
    
    .\mod_dav_lock.c : \
    	"..\..\..\include\ap_config.h"\
    	"..\..\..\include\ap_config_layout.h"\
    	"..\..\..\include\ap_hooks.h"\
    	"..\..\..\include\ap_mmn.h"\
    	"..\..\..\include\ap_provider.h"\
    	"..\..\..\include\ap_regex.h"\
    	"..\..\..\include\ap_release.h"\
    	"..\..\..\include\apache_noprobes.h"\
    	"..\..\..\include\http_config.h"\
    	"..\..\..\include\httpd.h"\
    	"..\..\..\include\mod_dav.h"\
    	"..\..\..\include\os.h"\
    	"..\..\..\include\util_cfgtree.h"\
    	"..\..\..\include\util_filter.h"\
    	"..\..\..\include\util_xml.h"\
    	"..\..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\..\srclib\apr-util\include\apr_xml.h"\
    	"..\..\..\srclib\apr-util\include\apu.h"\
    	"..\..\..\srclib\apr\include\apr.h"\
    	"..\..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\..\srclib\apr\include\apr_general.h"\
    	"..\..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\..\srclib\apr\include\apr_time.h"\
    	"..\..\..\srclib\apr\include\apr_user.h"\
    	"..\..\..\srclib\apr\include\apr_want.h"\
    	".\locks.h"\
    	
    
    ..\..\..\build\win32\httpd.rc : \
    	"..\..\..\include\ap_release.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/mod_dav_lock.dsp������������������������������������������������������0000664�0001751�0001751�00000011552�10663444730�021140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_dav_lock" - 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_lock - 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_lock.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_lock.mak" CFG="mod_dav_lock - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_dav_lock - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_dav_lock - 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_lock - 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_lock_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 /fo"Release/mod_dav_lock.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dav_lock.so" /d LONG_NAME="dav_lock_module for Apache"
    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 /out:".\Release\mod_dav_lock.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_lock.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_dav_lock.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_lock.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_dav_lock.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_dav_lock - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_dav_lock_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 /fo"Debug/mod_dav_lock.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dav_lock.so" /d LONG_NAME="dav_lock_module for Apache"
    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 /out:".\Debug\mod_dav_lock.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_lock.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_dav_lock.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_lock.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_dav_lock.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_dav_lock - Win32 Release"
    # Name "mod_dav_lock - Win32 Debug"
    # Begin Group "Source Files"
    
    # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
    # Begin Source File
    
    SOURCE=.\locks.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_dav_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=.\locks.h
    # End Source File
    # End Group
    # Begin Source File
    
    SOURCE=..\..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/locks.c���������������������������������������������������������������0000664�0001751�0001751�00000115071�14210356064�017261� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "apr_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    #include "httpd.h"
    #include "http_log.h"
    #include "http_main.h"      /* for ap_server_conf */
    
    #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 <db> field may be NULL, meaning one of two things:
     * 1) That we have not actually opened the underlying database (yet). The
     *    <opened> field should be false.
     * 2) We opened it readonly and it wasn't present.
     *
     * The delayed opening (determined by <opened>) 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 errcode;
        const char *errstr;
        dav_error *err;
        char errbuf[200];
    
        if (status == APR_SUCCESS) {
            return NULL;
        }
    
        /* There might not be a <db> 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, status, errstr);
        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, 0,
                                 "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, 0,
                                 "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)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *er;
    #endif
        dav_error *err;
        apr_status_t status = APR_SUCCESS;
    
        if (lockdb->info->opened) {
            return NULL;
        }
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        status = apr_dbm_get_driver(&driver, NULL, &er, lockdb->info->pool);
    
        if (status) {
            ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, APLOGNO(10288)
                         "mod_dav_lock: The DBM library '%s' could not be loaded: %s",
                                 er->reason, er->msg);
            return dav_new_error(lockdb->info->pool, HTTP_INTERNAL_SERVER_ERROR, 1,
                    status, "Could not load library for property database.");
        }
    
        status = apr_dbm_open2(&lockdb->info->db, driver, lockdb->info->lockdb_path,
                              lockdb->ro ? APR_DBM_READONLY : APR_DBM_RWCREATE,
                              APR_OS_DEFAULT, lockdb->info->pool);
    #else
        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);
    #endif
    
        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, 0,
                                 "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, 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_pmemdup(p, 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_pmemdup(p, 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_pmemdup(p, 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, 0,
                                     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 <indirect>, 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, 0,
                             "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
            "<D:lockentry>" DEBUG_CR
            "<D:lockscope><D:exclusive/></D:lockscope>" DEBUG_CR
            "<D:locktype><D:write/></D:locktype>" DEBUG_CR
            "</D:lockentry>" DEBUG_CR
            "<D:lockentry>" DEBUG_CR
            "<D:lockscope><D:shared/></D:lockscope>" DEBUG_CR
            "<D:locktype><D:write/></D:locktype>" DEBUG_CR
            "</D:lockentry>" 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, 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 <lock> 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;
                break;
            }
        }
    
        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 */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/NWGNUmakefile���������������������������������������������������������0000664�0001751�0001751�00000010313�11541421667�020320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/netware \
    			$(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	= $(NLM_NAME) 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	=
    
    #
    # 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 this is specified it will be used by the link '-flags' directive
    #
    NLM_FLAGS	=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_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 = \
    	$(PRELUDE) \
    	$(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 \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/Makefile.in�����������������������������������������������������������0000664�0001751�0001751�00000000267�10150161574�020046� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/mod_dav_lock.mak������������������������������������������������������0000664�0001751�0001751�00000026124�12701473373�021123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_dav_lock.dsp
    !IF "$(CFG)" == ""
    CFG=mod_dav_lock - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_dav_lock - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_dav_lock - Win32 Release" && "$(CFG)" != "mod_dav_lock - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_lock.mak" CFG="mod_dav_lock - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_dav_lock - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_dav_lock - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_lock - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dav_lock.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dav - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_dav_lock.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_dav - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\locks.obj"
    	-@erase "$(INTDIR)\mod_dav_lock.obj"
    	-@erase "$(INTDIR)\mod_dav_lock.res"
    	-@erase "$(INTDIR)\mod_dav_lock_src.idb"
    	-@erase "$(INTDIR)\mod_dav_lock_src.pdb"
    	-@erase "$(OUTDIR)\mod_dav_lock.exp"
    	-@erase "$(OUTDIR)\mod_dav_lock.lib"
    	-@erase "$(OUTDIR)\mod_dav_lock.pdb"
    	-@erase "$(OUTDIR)\mod_dav_lock.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dav_lock_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dav_lock.res" /i "../../../include" /i "../../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dav_lock.so" /d LONG_NAME="dav_lock_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dav_lock.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dav_lock.pdb" /debug /out:"$(OUTDIR)\mod_dav_lock.so" /implib:"$(OUTDIR)\mod_dav_lock.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_lock.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\locks.obj" \
    	"$(INTDIR)\mod_dav_lock.obj" \
    	"$(INTDIR)\mod_dav_lock.res" \
    	"..\..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\..\Release\libhttpd.lib" \
    	"..\main\Release\mod_dav.lib"
    
    "$(OUTDIR)\mod_dav_lock.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_dav_lock.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dav_lock.so"
       if exist .\Release\mod_dav_lock.so.manifest mt.exe -manifest .\Release\mod_dav_lock.so.manifest -outputresource:.\Release\mod_dav_lock.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_dav_lock - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dav_lock.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dav - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_dav_lock.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_dav - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\locks.obj"
    	-@erase "$(INTDIR)\mod_dav_lock.obj"
    	-@erase "$(INTDIR)\mod_dav_lock.res"
    	-@erase "$(INTDIR)\mod_dav_lock_src.idb"
    	-@erase "$(INTDIR)\mod_dav_lock_src.pdb"
    	-@erase "$(OUTDIR)\mod_dav_lock.exp"
    	-@erase "$(OUTDIR)\mod_dav_lock.lib"
    	-@erase "$(OUTDIR)\mod_dav_lock.pdb"
    	-@erase "$(OUTDIR)\mod_dav_lock.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dav_lock_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dav_lock.res" /i "../../../include" /i "../../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dav_lock.so" /d LONG_NAME="dav_lock_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dav_lock.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dav_lock.pdb" /debug /out:"$(OUTDIR)\mod_dav_lock.so" /implib:"$(OUTDIR)\mod_dav_lock.lib" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_lock.so 
    LINK32_OBJS= \
    	"$(INTDIR)\locks.obj" \
    	"$(INTDIR)\mod_dav_lock.obj" \
    	"$(INTDIR)\mod_dav_lock.res" \
    	"..\..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\..\Debug\libhttpd.lib" \
    	"..\main\Debug\mod_dav.lib"
    
    "$(OUTDIR)\mod_dav_lock.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_dav_lock.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dav_lock.so"
       if exist .\Debug\mod_dav_lock.so.manifest mt.exe -manifest .\Debug\mod_dav_lock.so.manifest -outputresource:.\Debug\mod_dav_lock.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_dav_lock.dep")
    !INCLUDE "mod_dav_lock.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_dav_lock.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_dav_lock - Win32 Release" || "$(CFG)" == "mod_dav_lock - Win32 Debug"
    SOURCE=.\locks.c
    
    "$(INTDIR)\locks.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\mod_dav_lock.c
    
    "$(INTDIR)\mod_dav_lock.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_dav_lock - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\dav\lock"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\lock"
    
    !ELSEIF  "$(CFG)" == "mod_dav_lock - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\dav\lock"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\lock"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_lock - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\dav\lock"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\lock"
    
    !ELSEIF  "$(CFG)" == "mod_dav_lock - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\dav\lock"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\dav\lock"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_lock - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\dav\lock"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\dav\lock"
    
    !ELSEIF  "$(CFG)" == "mod_dav_lock - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\dav\lock"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\dav\lock"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dav_lock - Win32 Release"
    
    "mod_dav - Win32 Release" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Release" 
       cd "..\lock"
    
    "mod_dav - Win32 ReleaseCLEAN" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Release" RECURSE=1 CLEAN 
       cd "..\lock"
    
    !ELSEIF  "$(CFG)" == "mod_dav_lock - Win32 Debug"
    
    "mod_dav - Win32 Debug" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Debug" 
       cd "..\lock"
    
    "mod_dav - Win32 DebugCLEAN" : 
       cd ".\..\main"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dav.mak" CFG="mod_dav - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\lock"
    
    !ENDIF 
    
    SOURCE=..\..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_dav_lock - Win32 Release"
    
    
    "$(INTDIR)\mod_dav_lock.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dav_lock.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_dav_lock.so" /d LONG_NAME="dav_lock_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_dav_lock - Win32 Debug"
    
    
    "$(INTDIR)\mod_dav_lock.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dav_lock.res" /i "../../../include" /i "../../../srclib/apr/include" /i "../../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_dav_lock.so" /d LONG_NAME="dav_lock_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/mod_dav_lock.c��������������������������������������������������������0000664�0001751�0001751�00000006126�11402752006�020563� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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);
    }
    
    AP_DECLARE_MODULE(dav_lock) =
    {
        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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/config6.m4������������������������������������������������������������0000664�0001751�0001751�00000000657�11707053320�017577� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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, ,,,dav)
    
    APACHE_MODPATH_FINISH
    ���������������������������������������������������������������������������������httpd-2.4.64/modules/dav/lock/locks.h���������������������������������������������������������������0000664�0001751�0001751�00000002142�10455005461�017257� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  locks.h
     * @brief Declarations for the generic lock implementation
     *
     * @addtogroup MOD_DAV
     * @{
     */
    
    #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_ */
    /** @} */
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/���������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015065� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016044� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/���������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017330� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/test.lua�������������������������������������������������������0000664�0001751�0001751�00000005656�11737125415�021022� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-- Licensed to the Apache Software Foundation (ASF) under one or more
    -- contributor license agreements.  See the NOTICE file distributed with
    -- this work for additional information regarding copyright ownership.
    -- The ASF licenses this file to You under the Apache License, Version 2.0
    -- (the "License"); you may not use this file except in compliance with
    -- the License.  You may obtain a copy of the License at
    --
    -- http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT 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 'string'
    
    function print_args(r, simple, complex)
      local s = "    %s: %s\n"
      r:puts("  simple:\n")
      for k, v in pairs(simple) do
        r:puts(s:format(k, v))
      end
    
      s = "    %s: "
      r:puts("  complex:\n")
      for k, ary in pairs(complex) do
        r:puts(s:format(k))
        for i=1, #ary do
          r:puts(ary[i])
          if i < #ary then r:puts(", ") end
        end
        r:puts("\n")
      end
    end
    
    function debug_stuff(r)
      r:debug("This is a debug log message")
      -- r:info("This is an info log message")
      -- r:notice("This is an notice log message")
      -- r:warn("This is an warn log message")
      -- r:err("This is an err log message")
      -- r:alert("This is an alert log message")
      -- r:crit("This is an crit log message")
      -- r:emerg("This is an emerg log message")
    end
    
    function handle(r)
      r:puts("hello Lua world\n")
      r:puts("Query args:\n")
      
      print_args(r, r:parseargs());
      
      debug_stuff(r)
        
      r:puts("HTTP Method:\n  " .. r.method .. "\n")
    
      if r.method == 'POST' then
        print_args(r, r:parsebody())
      end
    
      require("other")
      r:puts("loaded relative to script:\n  ")
      other.doit(r)
      
      r:puts("loaded from LuaPackagePath:\n")
      require("kangaroo");
      kangaroo.hop(r);
    end
    
    function handle_foo(r)
      r:puts("Handler FOO!\n")
      r.status = 201
      r:debug("set status to 201")
    end
    
    
    function handle_attributes(r)
      local function pf(name)
        r:puts(("%s: %s\n"):format(name, tostring(r[name])))
      end
    
      pf("status")
      r.status = 201
      pf("status")
      r:puts("\n")
        
      pf("content_type")
      r.content_type = "text/plain?charset=ascii"
      pf("content_type")
      r:puts("\n")
      
      pf("method")
      pf("protocol")
      pf("assbackwards")
      pf("the_request")
      pf("range")
      pf("content_encoding")
      pf("user")
      pf("unparsed_uri")
      pf("ap_auth_type")
      pf("uri")
      pf("filename")
      pf("canonical_filename")
      pf("path_info")
      pf("args")
      
      r:puts("\n")
    end
    
    function test_headers(r)
      r:puts("test getting and setting headers here\n")
    end
    
    function handle_quietly(r)
      r:puts("hello!")
    end
    
    function handle_regex(r)
      r:puts("matched in handle_regex")
    end
    
    function handle_serverversion(r)
      r:puts(apache2.version)
    end
    
    function handle_fixupstest(r)
      r:puts("status is " .. r.status)
    end����������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/hooks.lua������������������������������������������������������0000664�0001751�0001751�00000001102�11123517417�021140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������require 'string'
    require 'apache2'
    
    function translate_name(r)
        if r.uri == "/translate-name" then
            r.uri = "/find_me.txt"
            return apache2.DECLINED
        end
        return apache2.DECLINED
    end
    
    function translate_name2(r)
        if r.uri == "/translate-name2" then
            r.uri = "/find_me.txt"
            return apache2.DECLINED
        end
        return apache2.DECLINED
    end
    
    function fixups_test(r)
      -- r:err("KABAZ")
      if r.uri == "/test_fixupstest" then
        -- r:err("KABIZ")
        r.status = 201
        return apache2.OK
      end
      -- r:err("ZIBAK")
      return apache2.DECLINED
    end��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/simple.lua�����������������������������������������������������0000664�0001751�0001751�00000000117�11152362007�021306� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������function handle(r)
       r.content_type = "text/plain"
       r:puts("Hi there!")
    end
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/filters.lua����������������������������������������������������0000664�0001751�0001751�00000000174�11123517417�021475� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    local s = require 'string'
    
    function handle_simple(r)
      -- r:addoutputfilter("wombathood")
      r:puts("added wombathood")
    end����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/headers.lua����������������������������������������������������0000664�0001751�0001751�00000000200�11173775143�021435� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������function handle(r)
       local host = r.headers_in['host']
       r:debug(host)
       r:puts(host)
       r.headers_out['wombat'] = 'lua'
    end
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/config_tests.lua�����������������������������������������������0000664�0001751�0001751�00000002264�11123517417�022516� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-- Licensed to the Apache Software Foundation (ASF) under one or more
    -- contributor license agreements.  See the NOTICE file distributed with
    -- this work for additional information regarding copyright ownership.
    -- The ASF licenses this file to You under the Apache License, Version 2.0
    -- (the "License"); you may not use this file except in compliance with
    -- the License.  You may obtain a copy of the License at
    --
    -- http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT 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 'string'
    
    local count = 0
    
    function handle(r)
        r:puts("success in handle " .. count)
    end
    
    function handle_server_vm(r)
        r:puts("hello from server scope " .. count)
        count = count + 1
    end
    
    function handle_request_vm(r)
        r:puts("hello from request scope " .. count)
        count = count + 1
    end
    
    function handle_conn_vm(r)
        r:puts("hello from request scope " .. count)
        count = count + 1
    end��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/find_me.txt����������������������������������������������������0000664�0001751�0001751�00000000016�11737125415�021463� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������please find me������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/htdocs/other.lua������������������������������������������������������0000664�0001751�0001751�00000001554�11123517417�021151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-- Licensed to the Apache Software Foundation (ASF) under one or more
    -- contributor license agreements.  See the NOTICE file distributed with
    -- this work for additional information regarding copyright ownership.
    -- The ASF licenses this file to You under the Apache License, Version 2.0
    -- (the "License"); you may not use this file except in compliance with
    -- the License.  You may obtain a copy of the License at
    --
    -- http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    
    module("other")
    
    function doit(r)
      r:debug("doing it...")
      r:puts("Do It!\n")
    end
    ����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/lib/������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016612� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/lib/kangaroo.lua������������������������������������������������������0000664�0001751�0001751�00000001530�11123517417�021105� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-- Licensed to the Apache Software Foundation (ASF) under one or more
    -- contributor license agreements.  See the NOTICE file distributed with
    -- this work for additional information regarding copyright ownership.
    -- The ASF licenses this file to You under the Apache License, Version 2.0
    -- (the "License"); you may not use this file except in compliance with
    -- the License.  You may obtain a copy of the License at
    --
    -- http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    module("kangaroo")
    
    function hop(r)
      r:puts("  hop hop!\n")
    end
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/helpers.lua�����������������������������������������������������������0000664�0001751�0001751�00000001262�11123517417�020202� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������module("helpers", package.seeall)
    
    local io = require("io")
    local http = require("socket.http")
    local string = require("string")
    
    base_url = "http://localhost"
    
    function get(uri)
      return http.request(base_url .. uri)  
    end
    
    function post(uri, body)
      local function do_it(body)
        local flat
        if (type(body) == "table") then
          i = 1
          for k, v in pairs(body) do
            if i == 1 then 
              flat = k .. "=" ..v 
            else
              flat = flat .. "&" .. k .. "=" .. v
            end
            i = i + 1
          end
        else
          flat = body;
        end
        return http.request(base_url .. uri, flat) 
      end
      if body then
        return do_it(body)
      else
        return do_it
      end
    end����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/test.lua��������������������������������������������������������������0000775�0001751�0001751�00000011047�11657256456�017543� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env lua
    
    -- Licensed to the Apache Software Foundation (ASF) under one or more
    -- contributor license agreements.  See the NOTICE file distributed with
    -- this work for additional information regarding copyright ownership.
    -- The ASF licenses this file to You under the Apache License, Version 2.0
    -- (the "License"); you may not use this file except in compliance with
    -- the License.  You may obtain a copy of the License at
    --
    -- http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    
    local mu = require "moonunit" 
    local http = require "helpers"
    
    http.base_url = "http://localhost:8008"
    
    local test = mu.TestCase:new{}
    
    function test:document_root()
      local b, c = http.get "/document_root.lua"
      assert(200 == c, "expected status code 200, got " .. c)
      assert(b:find("test"), "test not found in document root")
    end
    
    function test:basic_get()
      local b, c = http.get "/basic"
      assert(200 == c, "expected status code 200, got " .. c)
      assert(b:find("hello Lua world"), "'hello Lua world' not found in response")
    end
    
    function test:quietly()
      local b, c = http.get "/test_quietly"
      assert(200 == c, "unexpected response code " .. c)
      assert(b == 'hello!', "unexpected response body [" .. b .. "]")
    end
    
    function test.basic_post()
      local b, c = http.post "/basic" "hello=7&hello=1"
      assert(200 == c, "expected status code 200, got " .. c)
      assert(b:find("complex:%s+hello: 7, 1\n"), "didn't find complex post parsing")
      assert(b:find("simple:%s+hello: 7\n"), "didn't find simple post parsing")
    end
    
    function test.basic_post_alt()
      local b, c = http.post("/test_foo", "hello=7&hello=1")
      assert(201 == c, "expected status code 200, got " .. c)
      assert(b:find("Handler FOO!"), "unexpected output!")
    end
    
    function test.post_with_table()
      local b, c = http.post "/basic" { hello = "7" }
      assert(200 == c, "expected status code 200, got " .. c)
      assert(b:find("hello: 7"), "didn't get expected post data [" .. b .."]")
      
      b, c = http.post "/basic" { hello = "7", goodbye = "8" }
      
      assert(200 == c, "expected status code 200, got " .. c)
      assert(b:find("hello: 7"), "didn't get expected post data [" .. b .."]")
      assert(b:find("goodbye: 8"), "didn't get expected post data [" .. b .."]")
    end
    
    function test:simple_filter()
      local b, c = http.get "/filter/simple"
      assert(200 == c, "expected status code 200, got " .. c)
    end
    
    function test:request_attributes()
      local r, c = http.get "/test_attributes?yes=no"
      assert(201 == c, "expected status code 201, got " .. c)
      
      assert(r:find("status: 200\nstatus: 201"), "changing status code failed")
      assert(r:find("method: GET"), "method wasn't reported correctly")
      assert(r:find("protocol: HTTP/1.1"), "protocol reported incorrectly")
      assert(r:find("assbackwards: false"), "assbackwards reported incorrectly")
      assert(r:find("args: yes=no"), "args not reported correctly")
    end
    
    function test:map_regex()
      local r, c = http.get "/test_regex"
      assert(200 == c, "expected status code 200, got " .. c)
      assert(r:find("matched in handle_regex"), "didn't find 'matched in handle_regex'")  
    end
    
    function test:map_regex2()
      local r, c = http.get "/test_regex?a=8"
      assert(200 == c, "expected status code 200, got " .. c)
      assert(r:find("matched in handle_regex"), "didn't find 'matched in handle_regex'")  
    end
    
    function test:translate_name_hook()
      local r, c = http.get "/translate-name"
      assert(200 == c, "expected 200 got " .. c)
      assert(r:find("please find me"), "didn't get expected static file :-(, instead got " .. r)
    end
    
    function test:translate_name_hook2()
      local r, c = http.get "/translate-name2"
      assert(200 == c, "expected 200 got " .. c)
      assert(r:find("please find me"), "didn't get expected static file :-(, instead got " .. r)
    end
    
    function test:server_version()
      local r, c = http.get "/test_serverversion"
      assert(200 == c)
      assert(r:find("Apache/2"), "version isn't Apache/2, but is " .. r)
    end
    
    function test:fixups_hook()
      local r, c = http.get "/test_fixupstest"
      assert(201 == c, "incorrect status code returned, expected 201 got " .. c)
      assert(r:find("status is 201"), "handler sees incorrect status")
    end
    
    function test:simple()
        local r, c = http.get "/simple.lua"
        assert(200 == c, "incorrect status code returned, expected 200 got " .. c)
        assert(r:find("Hi"), "Didn't find 'Hi'")
    end
    
    test:run()
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/test_httpd.conf�������������������������������������������������������0000664�0001751�0001751�00000001603�11737125415�021071� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Customize these two values for your Apache2 install
    ServerRoot "/Users/brianm/.opt/httpd-2.2.3-worker-for-lua"
    DocumentRoot "/Users/brianm/src/wombat/test/htdocs"
    
    # Customize this value to point to the top of mod_wombat's test dir
    LuaRoot /Users/brianm/src/wombat/test
    
    Listen 8000
    
    LoadModule lua_module modules/mod_lua.so
    
    AddHandler lua-script .lua
    
    #LuaConfig httpd_config.lua configure
    
    LuaMapHandler /basic /Users/brianm/src/wombat/test/htdocs/test.lua
    LuaMapHandler /filter/simple /Users/brianm/src/wombat/test/htdocs/filters.lua handle_simple
    LuaMapHandler ^/(\w+)_(\w+)$ /Users/brianm/src/wombat/test/htdocs/$1.lua handle_$2
    
    LuaHookTranslateName htdocs/hooks.lua translate_name
    LuaHookTranslateName htdocs/hooks.lua translate_name2
    
    LuaHookFixups htdocs/hooks.lua fixups_test
    
    LuaPackagePath lib/?.lua
    
    # stat | forever | never
    LuaCodeCache stat
    
    ErrorLog logs/error_log
    LogLevel debug
    �����������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/test/moonunit.lua����������������������������������������������������������0000664�0001751�0001751�00000003131�11123517417�020405� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-- Licensed to the Apache Software Foundation (ASF) under one or more
    -- contributor license agreements.  See the NOTICE file distributed with
    -- this work for additional information regarding copyright ownership.
    -- The ASF licenses this file to You under the Apache License, Version 2.0
    -- (the "License"); you may not use this file except in compliance with
    -- the License.  You may obtain a copy of the License at
    --
    -- http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    
    module("moonunit", package.seeall)
    
    TestCase = {}
    
    function TestCase:new(it)
      it = it or {}
      setmetatable(it, self)
      self.__index = self
      return it
    end
    
    function TestCase:run(args)
      args = args or arg
      local function run_test(t, name)
        local status, err = pcall(t, self)
        if status then
          print(("%-39s \27[32mpass\27[39m"):format("[" .. name .. "]"))
        else
          print(("%-39s \27[31mFAIL\27[39m %s"):format("[" .. name .. "]", err))
        end
      end
      
      if (args and #args > 0) then
        for _, v in ipairs(args) do
          if type(self[v]) == "function" then
            run_test(self[v], v)
          else
            print(("%-39s FAIL %s"):format("[" .. v .. "]", 
              "'" .. v .. "' doesn't appear to be a test function"))
          end
        end
      else
        for k, v in pairs(self) do
          run_test(v, k)
        end
      end
    end
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/config.m4������������������������������������������������������������������0000664�0001751�0001751�00000007445�14037100633�016571� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    APACHE_MODPATH_INIT(lua)
    
    dnl CHECK_LUA_PATH(PREFIX, INCLUDE-PATH, LIB-PATH, LIB-NAME)
    dnl
    dnl Checks for a specific version of the Lua libraries. Use CHECK_LUA instead,
    dnl which will call this macro.
    dnl
    dnl Sets LUA_CFLAGS and LUA_LIBS, and breaks from its containing loop, if the
    dnl check succeeds.
    AC_DEFUN([CHECK_LUA_PATH], [dnl
        AC_MSG_CHECKING([for lua.h in $1/$2])
        if test -f $1/$2/lua.h; then
            AC_MSG_RESULT([yes])
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L$1/$3 $LDFLAGS $lib_m"
            AC_CHECK_LIB($4, luaL_newstate, [
                LUA_LIBS="-L$1/$3 -l$4 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
                   APR_ADDTO(LUA_LIBS, [$ap_platform_runtime_link_flag$1/$3])
                fi
                LUA_CFLAGS="-I$1/$2"
            ])
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            AC_MSG_RESULT([no])
        fi
    ])
    
    dnl Check for Lua Libraries
    dnl CHECK_LUA(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
    dnl Sets:
    dnl  LUA_CFLAGS
    dnl  LUA_LIBS
    AC_DEFUN([CHECK_LUA],
    [dnl
    
    AC_ARG_WITH(
        lua,
        [AC_HELP_STRING([--with-lua=PATH],[Path to the Lua installation prefix])],
        lua_path="$withval",
        :)
    
    dnl # Determine lua lib directory
    if test -z "$lua_path"; then
        test_paths=". /usr/local /usr"
    else
        test_paths="${lua_path}"
    fi
    
    for pklua in lua lua5.4 lua5.3 lua5.2 lua5.1; do
      if test -n "$PKGCONFIG" -a -z "$lua_path" \
         && $PKGCONFIG --atleast-version=5.1 $pklua; then
        LUA_LIBS="`$PKGCONFIG --libs $pklua`"
        LUA_CFLAGS="`$PKGCONFIG --cflags $pklua`"
        LUA_VERSION="`$PKGCONFIG --modversion $pklua`"
        AC_MSG_NOTICE([using Lua $LUA_VERSION configuration from pkg-config])
        break
      fi
    done
    
    if test -z "$LUA_VERSION"; then
      AC_CHECK_LIB(m, pow, lib_m="-lm")
      AC_CHECK_LIB(m, sqrt, lib_m="-lm")
      for x in $test_paths ; do
        CHECK_LUA_PATH([${x}], [include/lua-5.4], [lib/lua-5.4], [lua-5.4])
        CHECK_LUA_PATH([${x}], [include/lua5.4], [lib], [lua5.4])
        CHECK_LUA_PATH([${x}], [include/lua54], [lib/lua54], [lua])
    
        CHECK_LUA_PATH([${x}], [include/lua-5.3], [lib/lua-5.3], [lua-5.3])
        CHECK_LUA_PATH([${x}], [include/lua5.3], [lib], [lua5.3])
        CHECK_LUA_PATH([${x}], [include/lua53], [lib/lua53], [lua])
    
        CHECK_LUA_PATH([${x}], [include], [lib], [lua])
    
        CHECK_LUA_PATH([${x}], [include/lua-5.2], [lib/lua-5.2], [lua-5.2])
        CHECK_LUA_PATH([${x}], [include/lua5.2], [lib], [lua5.2])
        CHECK_LUA_PATH([${x}], [include/lua52], [lib/lua52], [lua])
    
        CHECK_LUA_PATH([${x}], [include/lua-5.1], [lib/lua-5.1], [lua-5.1])
        CHECK_LUA_PATH([${x}], [include/lua5.1], [lib], [lua5.1])
        CHECK_LUA_PATH([${x}], [include/lua51], [lib/lua51], [lua])
      done
    fi
    
    AC_SUBST(LUA_LIBS)
    AC_SUBST(LUA_CFLAGS)
    
    if test -z "${LUA_LIBS}"; then
      AC_MSG_WARN([*** Lua 5.4 5.3 5.2 or 5.1 library not found.])
      ifelse([$2], ,
        enable_lua="no"
        if test -z "${lua_path}"; then
            AC_MSG_WARN([Lua 5.4 5.3 5.2 or 5.1 library is required])
        else
            AC_MSG_ERROR([Lua 5.4 5.3 5.2 or 5.1 library is required])
        fi,
        $2)
    else
      AC_MSG_NOTICE([using '${LUA_LIBS}' for Lua Library])
      AC_ARG_ENABLE(luajit,APACHE_HELP_STRING(--enable-luajit,Enable LuaJit Support),
      [
        if test "$enableval" = "yes"; then
          APR_ADDTO(MOD_CPPFLAGS, ["-DAP_ENABLE_LUAJIT"])
        fi
      ])
      ifelse([$1], , , $1) 
    fi 
    ])
    
    lua_objects="lua_apr.lo lua_config.lo mod_lua.lo lua_request.lo lua_vmprep.lo lua_dbd.lo lua_passwd.lo"
    
    APACHE_MODULE(lua, Apache Lua Framework, $lua_objects, , , [
      CHECK_LUA()
      if test "x$enable_lua" != "xno" ; then
        APR_ADDTO(MOD_INCLUDES, [$LUA_CFLAGS])
        APR_ADDTO(MOD_LUA_LDADD, [$LUA_LIBS $CRYPT_LIBS])
      fi
    ])
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_config.c���������������������������������������������������������������0000664�0001751�0001751�00000016617�13127013226�017335� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "lua_config.h"
    #include "lua_vmprep.h"
    
    APLOG_USE_MODULE(lua);
    
    static ap_lua_dir_cfg *check_dir_config(lua_State *L, int index)
    {
        ap_lua_dir_cfg *cfg;
        luaL_checkudata(L, index, "Apache2.DirConfig");
        cfg = (ap_lua_dir_cfg *) lua_unboxpointer(L, index);
        return cfg;
    }
    
    static cmd_parms *check_cmd_parms(lua_State *L, int index)
    {
        cmd_parms *cmd;
        luaL_checkudata(L, index, "Apache2.CommandParameters");
        cmd = (cmd_parms *) lua_unboxpointer(L, index);
        return cmd;
    }
    
    static int apl_toscope(const char *name)
    {
        if (0 == strcmp("once", name))
            return AP_LUA_SCOPE_ONCE;
        if (0 == strcmp("request", name))
            return AP_LUA_SCOPE_REQUEST;
        if (0 == strcmp("connection", name))
            return AP_LUA_SCOPE_CONN;
        if (0 == strcmp("conn", name))
            return AP_LUA_SCOPE_CONN;
        if (0 == strcmp("thread", name))
            return AP_LUA_SCOPE_THREAD;
        return AP_LUA_SCOPE_ONCE;
    }
    
    apr_status_t ap_lua_map_handler(ap_lua_dir_cfg *cfg,
                                                     const char *file,
                                                     const char *function,
                                                     const char *pattern,
                                                     const char *scope)
    {
        ap_regex_t *uri_pattern;
        apr_status_t rv;
        ap_lua_mapped_handler_spec *handler =
            apr_pcalloc(cfg->pool, sizeof(ap_lua_mapped_handler_spec));
        handler->uri_pattern = NULL;
        handler->function_name = NULL;
    
        uri_pattern = apr_palloc(cfg->pool, sizeof(ap_regex_t));
        if ((rv = ap_regcomp(uri_pattern, pattern, 0)) != APR_SUCCESS) {
            return rv;
        }
        handler->file_name = apr_pstrdup(cfg->pool, file);
        handler->uri_pattern = uri_pattern;
        handler->scope = apl_toscope(scope);
    
        handler->function_name = apr_pstrdup(cfg->pool, function);
        *(const ap_lua_mapped_handler_spec **) apr_array_push(cfg->mapped_handlers) =
            handler;
        return APR_SUCCESS;
    }
    
    /* Change to use ap_lua_map_handler */
    static int cfg_lua_map_handler(lua_State *L)
    {
        ap_lua_dir_cfg *cfg = check_dir_config(L, 1);
        ap_lua_mapped_handler_spec *handler =
            apr_pcalloc(cfg->pool, sizeof(ap_lua_mapped_handler_spec));
        handler->uri_pattern = NULL;
        handler->function_name = NULL;
    
        luaL_checktype(L, 2, LUA_TTABLE);
        lua_getfield(L, 2, "file");
        if (lua_isstring(L, -1)) {
            const char *file = lua_tostring(L, -1);
            handler->file_name = apr_pstrdup(cfg->pool, file);
        }
        lua_pop(L, 1);
    
        lua_getfield(L, 2, "pattern");
        if (lua_isstring(L, -1)) {
            const char *pattern = lua_tostring(L, -1);
    
            ap_regex_t *uri_pattern = apr_palloc(cfg->pool, sizeof(ap_regex_t));
            if (ap_regcomp(uri_pattern, pattern, 0) != OK) {
                return luaL_error(L, "Unable to compile regular expression, '%s'",
                                  pattern);
            }
            handler->uri_pattern = uri_pattern;
        }
        lua_pop(L, 1);
    
        lua_getfield(L, 2, "scope");
        if (lua_isstring(L, -1)) {
            const char *scope = lua_tostring(L, -1);
            handler->scope = apl_toscope(scope);
        }
        else {
            handler->scope = AP_LUA_SCOPE_ONCE;
        }
        lua_pop(L, 1);
    
        lua_getfield(L, 2, "func");
        if (lua_isstring(L, -1)) {
            const char *value = lua_tostring(L, -1);
            handler->function_name = apr_pstrdup(cfg->pool, value);
        }
        else {
            handler->function_name = "handle";
        }
        lua_pop(L, 1);
    
    
        *(const ap_lua_mapped_handler_spec **) apr_array_push(cfg->mapped_handlers) =
            handler;
        return 0;
    }
    
    static int cfg_directory(lua_State *L)
    {
        ap_lua_dir_cfg *cfg = check_dir_config(L, 1);
        lua_pushstring(L, cfg->dir);
        return 1;
    }
    
    /*static int cfg_root(lua_State *L)
    {
        ap_lua_dir_cfg *cfg = check_dir_config(L, 1);
        lua_pushstring(L, cfg->root_path);
        return 1;
    }*/
    
    static const struct luaL_Reg cfg_methods[] = {
        {"match_handler", cfg_lua_map_handler},
        {"directory", cfg_directory},
        /* {"root", cfg_root}, */
        {NULL, NULL}
    };
    
    /* helper function for the logging functions below */
    static int cmd_log_at(lua_State *L, int level)
    {
        const char *msg;
        cmd_parms *cmd = check_cmd_parms(L, 1);
        lua_Debug dbg;
    
        lua_getstack(L, 1, &dbg);
        lua_getinfo(L, "Sl", &dbg);
    
        msg = luaL_checkstring(L, 2);
        /* Intentional no APLOGNO */
        ap_log_error(dbg.source, dbg.currentline, APLOG_MODULE_INDEX, level, 0,
                     cmd->server, "%s", msg);
        return 0;
    }
    
    /* r:debug(String) and friends which use apache logging */
    static int cmd_emerg(lua_State *L)
    {
        return cmd_log_at(L, APLOG_EMERG);
    }
    static int cmd_alert(lua_State *L)
    {
        return cmd_log_at(L, APLOG_ALERT);
    }
    static int cmd_crit(lua_State *L)
    {
        return cmd_log_at(L, APLOG_CRIT);
    }
    static int cmd_err(lua_State *L)
    {
        return cmd_log_at(L, APLOG_ERR);
    }
    static int cmd_warn(lua_State *L)
    {
        return cmd_log_at(L, APLOG_WARNING);
    }
    static int cmd_notice(lua_State *L)
    {
        return cmd_log_at(L, APLOG_NOTICE);
    }
    static int cmd_info(lua_State *L)
    {
        return cmd_log_at(L, APLOG_INFO);
    }
    static int cmd_debug(lua_State *L)
    {
        return cmd_log_at(L, APLOG_DEBUG);
    }
    static int cmd_trace1(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE1);
    }
    static int cmd_trace2(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE2);
    }
    static int cmd_trace3(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE3);
    }
    static int cmd_trace4(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE4);
    }
    static int cmd_trace5(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE5);
    }
    static int cmd_trace6(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE6);
    }
    static int cmd_trace7(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE7);
    }
    static int cmd_trace8(lua_State *L)
    {
        return cmd_log_at(L, APLOG_TRACE8);
    }
    
    static const struct luaL_Reg cmd_methods[] = {
        {"trace8", cmd_trace8},
        {"trace7", cmd_trace7},
        {"trace6", cmd_trace6},
        {"trace5", cmd_trace5},
        {"trace4", cmd_trace4},
        {"trace3", cmd_trace3},
        {"trace2", cmd_trace2},
        {"trace1", cmd_trace1},
        {"debug", cmd_debug},
        {"info", cmd_info},
        {"notice", cmd_notice},
        {"warn", cmd_warn},
        {"err", cmd_err},
        {"crit", cmd_crit},
        {"alert", cmd_alert},
        {"emerg", cmd_emerg},
    
        {NULL, NULL}
    };
    
    void ap_lua_load_config_lmodule(lua_State *L)
    {
        luaL_newmetatable(L, "Apache2.DirConfig");  /* [metatable] */
        lua_pushvalue(L, -1);
    
        lua_setfield(L, -2, "__index");
        luaL_setfuncs_compat(L, cfg_methods);       /* [metatable] */
    
    
        luaL_newmetatable(L, "Apache2.CommandParameters");
        lua_pushvalue(L, -1);
    
        lua_setfield(L, -2, "__index");
        luaL_setfuncs_compat(L, cmd_methods);       /* [metatable] */
    
    }
    �����������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/mod_lua.c������������������������������������������������������������������0000664�0001751�0001751�00000236025�15017334725�016656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_lua.h"
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <apr_thread_mutex.h>
    #include <apr_pools.h>
    #include "lua_apr.h"
    #include "lua_config.h"
    #include "apr_optional.h"
    #include "mod_auth.h"
    #include "util_mutex.h"
    
    
    #ifdef APR_HAS_THREADS
    #include "apr_thread_proc.h"
    #endif
    
    /* getpid for *NIX */
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* getpid for Windows */
    #if APR_HAVE_PROCESS_H
    #include <process.h>
    #endif
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_open,
                                        (lua_State *L, apr_pool_t *p),
                                        (L, p), OK, DECLINED)
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_request,
                                        (lua_State *L, request_rec *r),
                                        (L, r), OK, DECLINED)
    
    module AP_MODULE_DECLARE_DATA lua_module;
    
    #define AP_LUA_HOOK_FIRST (APR_HOOK_FIRST - 1)
    #define AP_LUA_HOOK_LAST  (APR_HOOK_LAST  + 1)
    
    typedef struct {
        const char *name;
        const char *file_name;
        const char *function_name;
        ap_lua_vm_spec *spec;
    } lua_authz_provider_spec;
    
    typedef struct {
        lua_authz_provider_spec *spec;
        apr_array_header_t *args;
    } lua_authz_provider_func;
    
    apr_hash_t *lua_authz_providers;
    
    typedef struct
    {
        apr_bucket_brigade *tmpBucket;
        lua_State *L;
        ap_lua_vm_spec *spec;
        int broken;
    } lua_filter_ctx;
    
    #define DEFAULT_LUA_SHMFILE "lua_ivm_shm"
    
    apr_global_mutex_t *lua_ivm_mutex;
    apr_shm_t *lua_ivm_shm;
    char *lua_ivm_shmfile;
    
    static apr_status_t shm_cleanup_wrapper(void *unused)
    {
        if (lua_ivm_shm) {
            return apr_shm_destroy(lua_ivm_shm);
        }
        return OK;
    }
    
    /**
     * error reporting if lua has an error.
     * Extracts the error from lua stack and prints
     */
    static void report_lua_error(lua_State *L, request_rec *r)
    {
        const char *lua_response;
        r->status = HTTP_INTERNAL_SERVER_ERROR;
        r->content_type = "text/html";
        ap_rputs("<h3>Error!</h3>\n", r);
        ap_rputs("<pre>", r);
        lua_response = lua_tostring(L, -1);
        ap_rputs(ap_escape_html(r->pool, lua_response), r);
        ap_rputs("</pre>\n", r);
    
        ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, r->pool, APLOGNO(01471) "Lua error: %s",
                      lua_response);
    }
    
    static void lua_open_callback(lua_State *L, apr_pool_t *p, void *ctx)
    {
        ap_lua_init(L, p);
        ap_lua_load_apache2_lmodule(L);
        ap_lua_load_request_lmodule(L, p);
        ap_lua_load_config_lmodule(L);
    }
    
    static int lua_open_hook(lua_State *L, apr_pool_t *p)
    {
        lua_open_callback(L, p, NULL);
        return OK;
    }
    
    static const char *scope_to_string(unsigned int scope)
    {
        switch (scope) {
        case AP_LUA_SCOPE_ONCE:
        case AP_LUA_SCOPE_UNSET:
            return "once";
        case AP_LUA_SCOPE_REQUEST:
            return "request";
        case AP_LUA_SCOPE_CONN:
            return "conn";
    #if APR_HAS_THREADS
        case AP_LUA_SCOPE_THREAD:
            return "thread";
        case AP_LUA_SCOPE_SERVER:
            return "server";
    #endif
        default:
            ap_assert(0);
            return 0;
        }
    }
    
    static void ap_lua_release_state(lua_State* L, ap_lua_vm_spec* spec, request_rec* r)
    {
        char *hash;
        apr_reslist_t* reslist = NULL;
    
        if (spec->scope == AP_LUA_SCOPE_SERVER) {
            ap_lua_server_spec* sspec = NULL;
            lua_settop(L, 0);
            lua_getfield(L, LUA_REGISTRYINDEX, "Apache2.Lua.server_spec");
            sspec = (ap_lua_server_spec*) lua_touserdata(L, 1);
            hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
            if (apr_pool_userdata_get((void **)&reslist, hash,
                                    r->server->process->pool) == APR_SUCCESS) {
                AP_DEBUG_ASSERT(sspec != NULL);
                if (reslist != NULL) {
                    apr_reslist_release(reslist, sspec);
                }
            }
        }
    }
    
    static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
                                          request_rec *r,
                                          const ap_lua_dir_cfg *cfg,
                                          const ap_lua_server_cfg *server_cfg,
                                          const char *filename,
                                          const char *bytecode,
                                          apr_size_t bytecode_len,
                                          const char *function,
                                          const char *what)
    {
        apr_pool_t *pool;
        ap_lua_vm_spec *spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
    
        spec->scope = cfg->vm_scope;
        spec->pool = r->pool;
        spec->package_paths = cfg->package_paths;
        spec->package_cpaths = cfg->package_cpaths;
        spec->cb = &lua_open_callback;
        spec->cb_arg = NULL;
        spec->bytecode = bytecode;
        spec->bytecode_len = bytecode_len;
        spec->codecache = (cfg->codecache == AP_LUA_CACHE_UNSET) ? AP_LUA_CACHE_STAT : cfg->codecache;
        spec->vm_min = cfg->vm_min ? cfg->vm_min : 1;
        spec->vm_max = cfg->vm_max ? cfg->vm_max : 1;
        
        if (filename) {
            char *file;
            apr_filepath_merge(&file, server_cfg->root_path,
                               filename, APR_FILEPATH_NOTRELATIVE, r->pool);
            spec->file = file;
        }
        else {
            spec->file = r->filename;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                      "%s details: scope: %s, file: %s, func: %s",
                      what, scope_to_string(spec->scope), spec->file,
                      function ? function : "-");
    
        switch (spec->scope) {
        case AP_LUA_SCOPE_ONCE:
        case AP_LUA_SCOPE_UNSET:
            apr_pool_create(&pool, r->pool);
            apr_pool_tag(pool, "mod_lua-vm");
            break;
        case AP_LUA_SCOPE_REQUEST:
            pool = r->pool;
            break;
        case AP_LUA_SCOPE_CONN:
            pool = r->connection->pool;
            break;
    #if APR_HAS_THREADS
        case AP_LUA_SCOPE_THREAD:
            pool = apr_thread_pool_get(r->connection->current_thread);
            break;
        case AP_LUA_SCOPE_SERVER:
            pool = r->server->process->pool;
            break;
    #endif
        default:
            ap_assert(0);
        }
    
        *lifecycle_pool = pool;
        return spec;
    }
    
    static const char* ap_lua_interpolate_string(apr_pool_t* pool, const char* string, const char** values)
    {
        char *stringBetween;
        const char* ret;
        int srclen,x,y;
        srclen = strlen(string);
        ret = "";
        y = 0;
        for (x=0; x < srclen; x++) {
            if (string[x] == '$' && x != srclen-1 && string[x+1] >= '0' && string[x+1] <= '9') {
                int v = *(string+x+1) - '0';
                if (x-y > 0) {
                    stringBetween = apr_pstrndup(pool, string+y, x-y);
                }
                else {
                    stringBetween = "";
                }
                ret = apr_pstrcat(pool, ret, stringBetween, values[v], NULL);
                y = ++x+1;
            }
        }
        
        if (x-y > 0 && y > 0) {
            stringBetween = apr_pstrndup(pool, string+y, x-y);
            ret = apr_pstrcat(pool, ret, stringBetween, NULL);
        }
        /* If no replacement was made, just return the original string */
        else if (y == 0) {
            return string;
        }
        return ret;
    }
    
    
    
    /**
     * "main"
     */
    static int lua_handler(request_rec *r)
    {
        int rc = OK;
        if (strcmp(r->handler, "lua-script")) {
            return DECLINED;
        }
        /* Decline the request if the script does not exist (or is a directory),
         * rather than just returning internal server error */
        if (
                (r->finfo.filetype == APR_NOFILE)
                || (r->finfo.filetype & APR_DIR)
            ) {
            return DECLINED;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "handling [%s] in mod_lua", r->filename);
    
        /* XXX: This seems wrong because it may generate wrong headers for HEAD requests */
        if (!r->header_only) {
            lua_State *L;
            apr_pool_t *pool;
            const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                             &lua_module);
            ap_lua_vm_spec *spec = create_vm_spec(&pool, r, cfg, NULL, NULL, NULL,
                                                  0, "handle", "request handler");
    
            L = ap_lua_get_lua_state(pool, spec, r);
            if (!L) {
                /* TODO annotate spec with failure reason */
                r->status = HTTP_INTERNAL_SERVER_ERROR;
                ap_rputs("Unable to compile VM, see logs", r);
                ap_lua_release_state(L, spec, r);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "got a vm!");
            lua_getglobal(L, "handle");
            if (!lua_isfunction(L, -1)) {
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01475)
                              "lua: Unable to find entry function '%s' in %s (not a valid function)",
                              "handle",
                              spec->file);
                ap_lua_release_state(L, spec, r);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            ap_lua_run_lua_request(L, r);
            if (lua_pcall(L, 1, 1, 0)) {
                report_lua_error(L, r);
            }
            if (lua_isnumber(L, -1)) {
                rc = lua_tointeger(L, -1);
            }
            ap_lua_release_state(L, spec, r);
        }
        return rc;
    }
    
    
    /* ------------------- Input/output content filters ------------------- */
    
    
    static apr_status_t lua_setup_filter_ctx(ap_filter_t* f, request_rec* r, lua_filter_ctx** c)
    {
        apr_pool_t *pool;
        ap_lua_vm_spec *spec;
        int n, rc, nres;
        lua_State *L;
        lua_filter_ctx *ctx;    
        ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
                                                            &lua_module);
        const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                        &lua_module);
        
        ctx = apr_pcalloc(r->pool, sizeof(lua_filter_ctx));
        ctx->broken = 0;
        *c = ctx;
        /* Find the filter that was called.
         * XXX: If we were wired with mod_filter, the filter (mod_filters name)
         *      and the provider (our underlying filters name) need to have matched.
         */
        for (n = 0; n < cfg->mapped_filters->nelts; n++) {
            ap_lua_filter_handler_spec *hook_spec =
                ((ap_lua_filter_handler_spec **) cfg->mapped_filters->elts)[n];
    
            if (hook_spec == NULL) {
                continue;
            }
            if (!strcasecmp(hook_spec->filter_name, f->frec->name)) {
                spec = create_vm_spec(&pool, r, cfg, server_cfg,
                                        hook_spec->file_name,
                                        NULL,
                                        0,
                                        hook_spec->function_name,
                                        "filter");
                L = ap_lua_get_lua_state(pool, spec, r);
                if (L) {
                    L = lua_newthread(L);
                }
    
                if (!L) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02328)
                                    "lua: Failed to obtain lua interpreter for %s %s",
                                    hook_spec->function_name, hook_spec->file_name);
                    ap_lua_release_state(L, spec, r);
                    return APR_EGENERAL;
                }
                if (hook_spec->function_name != NULL) {
                    lua_getglobal(L, hook_spec->function_name);
                    if (!lua_isfunction(L, -1)) {
                        ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02329)
                                    "lua: Unable to find entry function '%s' in %s (not a valid function)",
                                        hook_spec->function_name,
                                        hook_spec->file_name);
                        ap_lua_release_state(L, spec, r);
                        return APR_EGENERAL;
                    }
    
                    ap_lua_run_lua_request(L, r);
                }
                else {
                    int t;
                    ap_lua_run_lua_request(L, r);
    
                    t = lua_gettop(L);
                    lua_setglobal(L, "r");
                    lua_settop(L, t);
                }
                ctx->L = L;
                ctx->spec = spec;
                
                /* If a Lua filter is interested in filtering a request, it must first do a yield, 
                 * otherwise we'll assume that it's not interested and pretend we didn't find it.
                 */
                rc = lua_resume(L, 1, &nres);
                if (rc == LUA_YIELD) {
                    if (f->frec->providers == NULL) { 
                        /* Not wired by mod_filter */
                        apr_table_unset(r->headers_out, "Content-Length");
                        apr_table_unset(r->headers_out, "Content-MD5");
                        apr_table_unset(r->headers_out, "ETAG");
                    }
                    return OK;
                }
                else {
                    ap_lua_release_state(L, spec, r);
                    return APR_ENOENT;
                }
            }
        }
        return APR_ENOENT;
    }
    
    static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade *pbbIn)
    {
        request_rec *r = f->r;
        int rc, nres;
        lua_State *L;
        lua_filter_ctx* ctx;
        conn_rec *c = r->connection;
        apr_bucket *pbktIn;
        apr_status_t rv;
        
        /* Set up the initial filter context and acquire the function.
         * The corresponding Lua function should yield here.
         */
        if (!f->ctx) {
            rc = lua_setup_filter_ctx(f,r,&ctx);
            if (rc == APR_EGENERAL) {
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            if (rc == APR_ENOENT) {
                /* No filter entry found (or the script declined to filter), just pass on the buckets */
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next,pbbIn);
            }
            else { 
                /* We've got a willing lua filter, setup and check for a prefix */
                size_t olen;
                apr_bucket *pbktOut;
                const char* output = lua_tolstring(ctx->L, 1, &olen);
    
                f->ctx = ctx;
                ctx->tmpBucket = apr_brigade_create(r->pool, c->bucket_alloc);
    
                if (olen > 0) { 
                    pbktOut = apr_bucket_heap_create(output, olen, NULL, c->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
                    rv = ap_pass_brigade(f->next, ctx->tmpBucket);
                    apr_brigade_cleanup(ctx->tmpBucket);
                    if (rv != APR_SUCCESS) {
                        return rv;
                    }
                }
            }
        }
        ctx = (lua_filter_ctx*) f->ctx;
        L = ctx->L;
        /* While the Lua function is still yielding, pass in buckets to the coroutine */
        if (!ctx->broken) {
            while (!APR_BRIGADE_EMPTY(pbbIn)) {
                const char *data;
                apr_size_t len;
                apr_bucket *pbktOut;
    
                pbktIn = APR_BRIGADE_FIRST(pbbIn);
                if (APR_BUCKET_IS_EOS(pbktIn)) {
                    break;
                }
    
                /* read the bucket */
                apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ);
    
                /* Push the bucket onto the Lua stack as a global var */
                lua_pushlstring(L, data, len);
                lua_setglobal(L, "bucket");
                
                /* If Lua yielded, it means we have something to pass on */
                if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
                    size_t olen;
                    const char* output = lua_tolstring(L, 1, &olen);
                    if (olen > 0) { 
                        pbktOut = apr_bucket_heap_create(output, olen, NULL,
                                                c->bucket_alloc);
                        APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
                        rv = ap_pass_brigade(f->next, ctx->tmpBucket);
                        apr_brigade_cleanup(ctx->tmpBucket);
                        if (rv != APR_SUCCESS) {
                            return rv;
                        }
                    }
                }
                else {
                    ctx->broken = 1;
                    ap_lua_release_state(L, ctx->spec, r);
                    ap_remove_output_filter(f);
                    apr_brigade_cleanup(pbbIn);
                    apr_brigade_cleanup(ctx->tmpBucket);
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02663)
                                  "lua: Error while executing filter: %s",
                                  lua_tostring(L, -1));
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                apr_bucket_delete(pbktIn);
            }
            /* If we've safely reached the end, do a final call to Lua to allow for any 
            finishing moves by the script, such as appending a tail. */
            if (!APR_BRIGADE_EMPTY(pbbIn) && APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(pbbIn))) {
                apr_bucket *pbktEOS;
                lua_pushnil(L);
                lua_setglobal(L, "bucket");
                if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
                    apr_bucket *pbktOut;
                    size_t olen;
                    const char* output = lua_tolstring(L, 1, &olen);
                    if (olen > 0) { 
                        pbktOut = apr_bucket_heap_create(output, olen, NULL,
                                c->bucket_alloc);
                        APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
                    }
                }
                pbktEOS = apr_bucket_eos_create(c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktEOS);
                ap_lua_release_state(L, ctx->spec, r);
                rv = ap_pass_brigade(f->next, ctx->tmpBucket);
                apr_brigade_cleanup(ctx->tmpBucket);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
            }
        }
        /* Clean up */
        apr_brigade_cleanup(pbbIn);
        return APR_SUCCESS;    
    }
    
    
    
    static apr_status_t lua_input_filter_handle(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;
        int rc, lastCall = 0, nres;
        lua_State *L;
        lua_filter_ctx* ctx;
        conn_rec *c = r->connection;
        apr_status_t ret;
        
        /* Set up the initial filter context and acquire the function.
         * The corresponding Lua function should yield here.
         */
        if (!f->ctx) {
            rc = lua_setup_filter_ctx(f,r,&ctx);
            f->ctx = ctx;
            if (rc == APR_EGENERAL) {
                ctx->broken = 1;
                ap_remove_input_filter(f); 
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            if (rc == APR_ENOENT ) {
                ap_remove_input_filter(f);
                ctx->broken = 1;
            }
            if (rc == APR_SUCCESS) {
                ctx->tmpBucket = apr_brigade_create(r->pool, c->bucket_alloc);
            }
        }
        ctx = (lua_filter_ctx*) f->ctx;
        L = ctx->L;
        /* If the Lua script broke or denied serving the request, just pass the buckets through */
        if (ctx->broken) {
            return ap_get_brigade(f->next, pbbOut, eMode, eBlock, nBytes);
        }
        
        if (APR_BRIGADE_EMPTY(ctx->tmpBucket)) {
            ret = ap_get_brigade(f->next, ctx->tmpBucket, eMode, eBlock, nBytes);
            if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS)
                return ret;
        }
        
        /* While the Lua function is still yielding, pass buckets to the coroutine */
        if (!ctx->broken) {
            lastCall = 0;
            while (!APR_BRIGADE_EMPTY(ctx->tmpBucket)) {
                apr_bucket *pbktIn = APR_BRIGADE_FIRST(ctx->tmpBucket);
                apr_bucket *pbktOut;
                const char *data;
                apr_size_t len;
                
                if (APR_BUCKET_IS_EOS(pbktIn)) {
                    APR_BUCKET_REMOVE(pbktIn);
                    break;
                }
    
                /* read the bucket */
                ret = apr_bucket_read(pbktIn, &data, &len, eBlock);
                if (ret != APR_SUCCESS)
                    return ret;
    
                /* Push the bucket onto the Lua stack as a global var */
                lastCall++;
                lua_pushlstring(L, data, len);
                lua_setglobal(L, "bucket");
                
                /* If Lua yielded, it means we have something to pass on */
                if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
                    size_t olen;
                    const char* output = lua_tolstring(L, 1, &olen);
                    pbktOut = apr_bucket_heap_create(output, olen, 0, c->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut);
                    apr_bucket_delete(pbktIn);
                    return APR_SUCCESS;
                }
                else {
                    ctx->broken = 1;
                    ap_lua_release_state(L, ctx->spec, r);
                    ap_remove_input_filter(f); 
                    apr_bucket_delete(pbktIn);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
            /* If we've safely reached the end, do a final call to Lua to allow for any 
            finishing moves by the script, such as appending a tail. */
            if (lastCall == 0) {
                apr_bucket *pbktEOS = apr_bucket_eos_create(c->bucket_alloc);
                lua_pushnil(L);
                lua_setglobal(L, "bucket");
                if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
                    apr_bucket *pbktOut;
                    size_t olen;
                    const char* output = lua_tolstring(L, 1, &olen);
                    pbktOut = apr_bucket_heap_create(output, olen, 0, c->bucket_alloc);
                    APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut);
                }
                APR_BRIGADE_INSERT_TAIL(pbbOut,pbktEOS);
                ap_lua_release_state(L, ctx->spec, r);
            }
        }
        return APR_SUCCESS;
    }
    
    
    /* ---------------- Configury stuff --------------- */
    
    /** harnesses for magic hooks **/
    
    static int lua_request_rec_hook_harness(request_rec *r, const char *name, int apr_hook_when)
    {
        int rc;
        apr_pool_t *pool;
        lua_State *L;
        ap_lua_vm_spec *spec;
        ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
                                                             &lua_module);
        const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                         &lua_module);
        const char *key = apr_psprintf(r->pool, "%s_%d", name, apr_hook_when);
        apr_array_header_t *hook_specs = apr_hash_get(cfg->hooks, key,
                                                      APR_HASH_KEY_STRING);
        if (hook_specs) {
            int i;
            for (i = 0; i < hook_specs->nelts; i++) {
                ap_lua_mapped_handler_spec *hook_spec =
                    ((ap_lua_mapped_handler_spec **) hook_specs->elts)[i];
    
                if (hook_spec == NULL) {
                    continue;
                }
                spec = create_vm_spec(&pool, r, cfg, server_cfg,
                                      hook_spec->file_name,
                                      hook_spec->bytecode,
                                      hook_spec->bytecode_len,
                                      hook_spec->function_name,
                                      "request hook");
    
                L = ap_lua_get_lua_state(pool, spec, r);
    
                if (!L) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01477)
                        "lua: Failed to obtain lua interpreter for entry function '%s' in %s",
                                  hook_spec->function_name, hook_spec->file_name);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
                if (hook_spec->function_name != NULL) {
                    lua_getglobal(L, hook_spec->function_name);
                    if (!lua_isfunction(L, -1)) {
                        ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01478)
                                   "lua: Unable to find entry function '%s' in %s (not a valid function)",
                                      hook_spec->function_name,
                                      hook_spec->file_name);
                        ap_lua_release_state(L, spec, r);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
    
                    ap_lua_run_lua_request(L, r);
                }
                else {
                    int t;
                    ap_lua_run_lua_request(L, r);
    
                    t = lua_gettop(L);
                    lua_setglobal(L, "r");
                    lua_settop(L, t);
                }
    
                if (lua_pcall(L, 1, 1, 0)) {
                    report_lua_error(L, r);
                    ap_lua_release_state(L, spec, r);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                rc = DECLINED;
                if (lua_isnumber(L, -1)) {
                    rc = lua_tointeger(L, -1);
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "Lua hook %s:%s for phase %s returned %d", 
                                  hook_spec->file_name, hook_spec->function_name, name, rc);
                }
                else { 
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(03017)
                                  "Lua hook %s:%s for phase %s did not return a numeric value",
                                  hook_spec->file_name, hook_spec->function_name, name);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                if (rc != DECLINED) {
                    ap_lua_release_state(L, spec, r);
                    return rc;
                }
                ap_lua_release_state(L, spec, r);
            }
        }
        return DECLINED;
    }
    
    
    /* Fix for making sure that LuaMapHandler works when FallbackResource is set */
    static int lua_map_handler_fixups(request_rec *r)
    {
        /* If there is no handler set yet, this might be a LuaMapHandler request */
        if (r->handler == NULL) {
            int n = 0;
            ap_regmatch_t match[10];
            const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                         &lua_module);
            for (n = 0; n < cfg->mapped_handlers->nelts; n++) {
                ap_lua_mapped_handler_spec *hook_spec =
                ((ap_lua_mapped_handler_spec **) cfg->mapped_handlers->elts)[n];
    
                if (hook_spec == NULL) {
                    continue;
                }
                if (!ap_regexec(hook_spec->uri_pattern, r->uri, 10, match, 0)) {
                    r->handler = apr_pstrdup(r->pool, "lua-map-handler");
                    return OK;
                }
            }
        }
        return DECLINED;
    }
    
    
    static int lua_map_handler(request_rec *r)
    {
        int rc, n = 0;
        apr_pool_t *pool;
        lua_State *L;
        const char *filename, *function_name;
        const char *values[10];
        ap_lua_vm_spec *spec;
        ap_regmatch_t match[10];
        ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
                                                             &lua_module);
        const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                         &lua_module);
        for (n = 0; n < cfg->mapped_handlers->nelts; n++) {
            ap_lua_mapped_handler_spec *hook_spec =
                ((ap_lua_mapped_handler_spec **) cfg->mapped_handlers->elts)[n];
    
            if (hook_spec == NULL) {
                continue;
            }
            if (!ap_regexec(hook_spec->uri_pattern, r->uri, 10, match, 0)) {
                int i;
                for (i=0 ; i < 10; i++) {
                    if (match[i].rm_eo >= 0) {
                        values[i] = apr_pstrndup(r->pool, r->uri+match[i].rm_so, match[i].rm_eo - match[i].rm_so);
                    }
                    else values[i] = "";
                }
                filename = ap_lua_interpolate_string(r->pool, hook_spec->file_name, values);
                function_name = ap_lua_interpolate_string(r->pool, hook_spec->function_name, values);
                spec = create_vm_spec(&pool, r, cfg, server_cfg,
                                        filename,
                                        hook_spec->bytecode,
                                        hook_spec->bytecode_len,
                                        function_name,
                                        "mapped handler");
                L = ap_lua_get_lua_state(pool, spec, r);
    
                if (!L) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02330)
                                    "lua: Failed to obtain Lua interpreter for entry function '%s' in %s",
                                    function_name, filename);
                    ap_lua_release_state(L, spec, r);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
                if (function_name != NULL) {
                    lua_getglobal(L, function_name);
                    if (!lua_isfunction(L, -1)) {
                        ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02331)
                                        "lua: Unable to find entry function '%s' in %s (not a valid function)",
                                        function_name,
                                        filename);
                        ap_lua_release_state(L, spec, r);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
    
                    ap_lua_run_lua_request(L, r);
                }
                else {
                    int t;
                    ap_lua_run_lua_request(L, r);
    
                    t = lua_gettop(L);
                    lua_setglobal(L, "r");
                    lua_settop(L, t);
                }
    
                if (lua_pcall(L, 1, 1, 0)) {
                    report_lua_error(L, r);
                    ap_lua_release_state(L, spec, r);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                rc = DECLINED;
                if (lua_isnumber(L, -1)) {
                    rc = lua_tointeger(L, -1);
                }
                else { 
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02483)
                                  "lua: Lua handler %s in %s did not return a value, assuming apache2.OK",
                                  function_name,
                                  filename);
                    rc = OK;
                }
                ap_lua_release_state(L, spec, r);
                if (rc != DECLINED) {
                    return rc;
                }
            }
        }
        return DECLINED;
    }
    
    
    static apr_size_t config_getstr(ap_configfile_t *cfg, char *buf,
                                    size_t bufsiz)
    {
        apr_size_t i = 0;
    
        if (cfg->getstr) {
            apr_status_t rc = (cfg->getstr) (buf, bufsiz, cfg->param);
            if (rc == APR_SUCCESS) {
                i = strlen(buf);
                if (i && buf[i - 1] == '\n')
                    ++cfg->line_number;
            }
            else {
                buf[0] = '\0';
                i = 0;
            }
        }
        else {
            while (i < bufsiz) {
                char ch;
                apr_status_t rc = (cfg->getch) (&ch, cfg->param);
                if (rc != APR_SUCCESS)
                    break;
                buf[i++] = ch;
                if (ch == '\n') {
                    ++cfg->line_number;
                    break;
                }
            }
        }
        return i;
    }
    
    typedef struct cr_ctx
    {
        cmd_parms *cmd;
        ap_configfile_t *cfp;
        size_t startline;
        const char *endstr;
        char buf[HUGE_STRING_LEN];
    } cr_ctx;
    
    
    /* Okay, this deserves a little explanation -- in order for the errors that lua
     * generates to be 'accuarate', including line numbers, we basically inject
     * N line number new lines into the 'top' of the chunk reader.....
     *
     * be happy. this is cool.
     *
     */
    static const char *lf =
        "\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\n\n\n\n\n\n\n";
    #define N_LF 32
    
    static const char *direct_chunkreader(lua_State *lvm, void *udata,
                                          size_t *plen)
    {
        const char *p;
        struct cr_ctx *ctx = udata;
    
        if (ctx->startline) {
            *plen = ctx->startline > N_LF ? N_LF : ctx->startline;
            ctx->startline -= *plen;
            return lf;
        }
        *plen = config_getstr(ctx->cfp, ctx->buf, HUGE_STRING_LEN);
    
        for (p = ctx->buf; isspace(*p); ++p);
        if (p[0] == '<' && p[1] == '/') {
            apr_size_t i = 0;
            while (i < strlen(ctx->endstr)) {
                if (tolower(p[i + 2]) != ctx->endstr[i])
                    return ctx->buf;
                ++i;
            }
            *plen = 0;
            return NULL;
        }
        /*fprintf(stderr, "buf read: %s\n", ctx->buf); */
        return ctx->buf;
    }
    
    static int ldump_writer(lua_State *L, const void *b, size_t size, void *B)
    {
        (void) L;
        luaL_addlstring((luaL_Buffer *) B, (const char *) b, size);
        return 0;
    }
    
    typedef struct hack_section_baton
    {
        const char *name;
        ap_lua_mapped_handler_spec *spec;
        int apr_hook_when;
    } hack_section_baton;
    
    /* You can be unhappy now.
     *
     * This is uncool.
     *
     * When you create a <Section handler in httpd, the only 'easy' way to create
     * a directory context is to parse the section, and convert it into a 'normal'
     * Configureation option, and then collapse the entire section, in memory,
     * back into the parent section -- from which you can then get the new directive
     * invoked.... anyways. evil. Rici taught me how to do this hack :-)
     */
    static const char *hack_section_handler(cmd_parms *cmd, void *_cfg,
                                            const char *arg)
    {
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
        ap_directive_t *directive = cmd->directive;
        hack_section_baton *baton = directive->data;
        const char *key = apr_psprintf(cmd->pool, "%s_%d", baton->name, baton->apr_hook_when);
    
        apr_array_header_t *hook_specs = apr_hash_get(cfg->hooks, key,
                                                      APR_HASH_KEY_STRING);
        if (!hook_specs) {
            hook_specs = apr_array_make(cmd->pool, 2,
                                        sizeof(ap_lua_mapped_handler_spec *));
            apr_hash_set(cfg->hooks, key,
                         APR_HASH_KEY_STRING, hook_specs);
        }
    
        baton->spec->scope = cfg->vm_scope;
    
        *(ap_lua_mapped_handler_spec **) apr_array_push(hook_specs) = baton->spec;
    
        return NULL;
    }
    
    static const char *register_named_block_function_hook(const char *name,
                                                          cmd_parms *cmd,
                                                          void *mconfig,
                                                          const char *line)
    {
        const char *function = NULL;
        ap_lua_mapped_handler_spec *spec;
        int when = APR_HOOK_MIDDLE;
        const char *endp = ap_strrchr_c(line, '>');
    
        if (endp == NULL) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               "> directive missing closing '>'", NULL);
        }
    
        line = apr_pstrndup(cmd->temp_pool, line, endp - line);
    
        if (line[0]) { 
            const char *word;
            word = ap_getword_conf(cmd->temp_pool, &line);
            if (*word) {
                function = apr_pstrdup(cmd->pool, word);
            }
            word = ap_getword_conf(cmd->temp_pool, &line);
            if (*word) {
                if (!strcasecmp("early", word)) { 
                    when = AP_LUA_HOOK_FIRST;
                }
                else if (!strcasecmp("late", word)) {
                    when = AP_LUA_HOOK_LAST;
                }
                else { 
                    return apr_pstrcat(cmd->pool, cmd->cmd->name,
                                       "> 2nd argument must be 'early' or 'late'", NULL);
                }
            }
        }
    
        spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_mapped_handler_spec));
    
        {
            cr_ctx ctx;
            lua_State *lvm;
            char *tmp;
            int rv;
            ap_directive_t **current;
            hack_section_baton *baton;
    
            spec->file_name = apr_psprintf(cmd->pool, "%s:%u",
                                           cmd->config_file->name,
                                           cmd->config_file->line_number);
            if (function) {
                spec->function_name = (char *) function;
            }
            else {
                function = NULL;
            }
    
            ctx.cmd = cmd;
            tmp = apr_pstrdup(cmd->pool, cmd->err_directive->directive + 1);
            ap_str_tolower(tmp);
            ctx.endstr = tmp;
            ctx.cfp = cmd->config_file;
            ctx.startline = cmd->config_file->line_number;
    
            /* This lua State is used only to compile the input strings -> bytecode, so we don't need anything extra. */
            lvm = luaL_newstate();
    
            lua_settop(lvm, 0);
    
            rv = lua_load(lvm, direct_chunkreader, &ctx, spec->file_name);
    
            if (rv != 0) {
                const char *errstr = apr_pstrcat(cmd->pool, "Lua Error:",
                                                 lua_tostring(lvm, -1), NULL);
                lua_close(lvm);
                return errstr;
            }
            else {
                luaL_Buffer b;
                luaL_buffinit(lvm, &b);
                lua_dump(lvm, ldump_writer, &b);
                luaL_pushresult(&b);
                spec->bytecode_len = lua_rawlen(lvm, -1);
                spec->bytecode = apr_pstrmemdup(cmd->pool, lua_tostring(lvm, -1),
                                                spec->bytecode_len);
                lua_close(lvm);
            }
    
            current = mconfig;
    
            /* Here, we have to replace our current config node for the next pass */
            if (!*current) {
                *current = apr_pcalloc(cmd->pool, sizeof(**current));
            }
    
            baton = apr_pcalloc(cmd->pool, sizeof(hack_section_baton));
            baton->name = name;
            baton->spec = spec;
            baton->apr_hook_when = when;
    
            (*current)->filename = cmd->config_file->name;
            (*current)->line_num = cmd->config_file->line_number;
            (*current)->directive = apr_pstrdup(cmd->pool, "Lua_____ByteCodeHack");
            (*current)->args = NULL;
            (*current)->data = baton;
        }
    
        return NULL;
    }
    
    static const char *register_named_file_function_hook(const char *name,
                                                         cmd_parms *cmd,
                                                         void *_cfg,
                                                         const char *file,
                                                         const char *function,
                                                         int apr_hook_when)
    {
        ap_lua_mapped_handler_spec *spec;
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
        const char *key = apr_psprintf(cmd->pool, "%s_%d", name, apr_hook_when);
        apr_array_header_t *hook_specs = apr_hash_get(cfg->hooks, key,
                                                      APR_HASH_KEY_STRING);
    
        if (!hook_specs) {
            hook_specs = apr_array_make(cmd->pool, 2,
                                        sizeof(ap_lua_mapped_handler_spec *));
            apr_hash_set(cfg->hooks, key, APR_HASH_KEY_STRING, hook_specs);
        }
    
        spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_mapped_handler_spec));
        spec->file_name = apr_pstrdup(cmd->pool, file);
        spec->function_name = apr_pstrdup(cmd->pool, function);
        spec->scope = cfg->vm_scope;
    
        *(ap_lua_mapped_handler_spec **) apr_array_push(hook_specs) = spec;
        return NULL;
    }
    static const char *register_mapped_file_function_hook(const char *pattern,
                                                         cmd_parms *cmd,
                                                         void *_cfg,
                                                         const char *file,
                                                         const char *function)
    {
        ap_lua_mapped_handler_spec *spec;
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
        ap_regex_t *regex = apr_pcalloc(cmd->pool, sizeof(ap_regex_t));
        if (ap_regcomp(regex, pattern,0)) {
            return "Invalid regex pattern!";
        }
    
        spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_mapped_handler_spec));
        spec->file_name = apr_pstrdup(cmd->pool, file);
        spec->function_name = apr_pstrdup(cmd->pool, function);
        spec->scope = cfg->vm_scope;
        spec->uri_pattern = regex;
    
        *(ap_lua_mapped_handler_spec **) apr_array_push(cfg->mapped_handlers) = spec;
        return NULL;
    }
    static const char *register_filter_function_hook(const char *filter,
                                                         cmd_parms *cmd,
                                                         void *_cfg,
                                                         const char *file,
                                                         const char *function,
                                                         int direction)
    {
        ap_lua_filter_handler_spec *spec;
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
       
        spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_filter_handler_spec));
        spec->file_name = apr_pstrdup(cmd->pool, file);
        spec->function_name = apr_pstrdup(cmd->pool, function);
        spec->filter_name = filter;
    
        *(ap_lua_filter_handler_spec **) apr_array_push(cfg->mapped_filters) = spec;
        /* TODO: Make it work on other types than just AP_FTYPE_RESOURCE? */
        if (direction == AP_LUA_FILTER_OUTPUT) {
            spec->direction = AP_LUA_FILTER_OUTPUT;
            ap_register_output_filter_protocol(filter, lua_output_filter_handle, NULL, AP_FTYPE_RESOURCE,
                                                AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH);
        }
        else {
            spec->direction = AP_LUA_FILTER_INPUT;
            ap_register_input_filter(filter, lua_input_filter_handle, NULL, AP_FTYPE_RESOURCE);
        }
        return NULL;
    }
    /* disabled (see reference below)
    static int lua_check_user_id_harness_first(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "check_user_id", AP_LUA_HOOK_FIRST);
    }
    */
    static int lua_check_user_id_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "check_user_id", APR_HOOK_MIDDLE);
    }
    /* disabled (see reference below)
    static int lua_check_user_id_harness_last(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "check_user_id", AP_LUA_HOOK_LAST);
    }
    */
    
    static int lua_pre_trans_name_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "pre_translate_name", APR_HOOK_MIDDLE);
    }
    
    static int lua_translate_name_harness_first(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "translate_name", AP_LUA_HOOK_FIRST);
    }
    static int lua_translate_name_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "translate_name", APR_HOOK_MIDDLE);
    }
    static int lua_translate_name_harness_last(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "translate_name", AP_LUA_HOOK_LAST);
    }
    
    static int lua_fixup_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "fixups", APR_HOOK_MIDDLE);
    }
    
    static int lua_map_to_storage_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "map_to_storage", APR_HOOK_MIDDLE);
    }
    
    static int lua_type_checker_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "type_checker", APR_HOOK_MIDDLE);
    }
    
    static int lua_access_checker_harness_first(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "access_checker", AP_LUA_HOOK_FIRST);
    }
    static int lua_access_checker_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "access_checker", APR_HOOK_MIDDLE);
    }
    static int lua_access_checker_harness_last(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "access_checker", AP_LUA_HOOK_LAST);
    }
    
    static int lua_auth_checker_harness_first(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "auth_checker", AP_LUA_HOOK_FIRST);
    }
    static int lua_auth_checker_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "auth_checker", APR_HOOK_MIDDLE);
    }
    static int lua_auth_checker_harness_last(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "auth_checker", AP_LUA_HOOK_LAST);
    }
    static void lua_insert_filter_harness(request_rec *r)
    {
        /* ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03223)
         *               "LuaHookInsertFilter not yet implemented"); */
    }
    
    static int lua_log_transaction_harness(request_rec *r)
    {
        return lua_request_rec_hook_harness(r, "log_transaction", APR_HOOK_FIRST);
    }
    
    static int lua_quick_harness(request_rec *r, int lookup)
    {
        if (lookup) {
            return DECLINED;
        }
        return lua_request_rec_hook_harness(r, "quick", APR_HOOK_MIDDLE);
    }
    
    static const char *register_pre_trans_name_hook(cmd_parms *cmd, void *_cfg,
                                                    const char *file,
                                                    const char *function)
    {
        return register_named_file_function_hook("pre_translate_name", cmd, _cfg, file,
                                                 function, APR_HOOK_MIDDLE);
    }
    
    static const char *register_pre_trans_name_block(cmd_parms *cmd, void *_cfg,
                                                     const char *line)
    {
        return register_named_block_function_hook("pre_translate_name", cmd, _cfg,
                                                  line);
    }
    
    static const char *register_translate_name_hook(cmd_parms *cmd, void *_cfg,
                                                    const char *file,
                                                    const char *function,
                                                    const char *when)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                               NOT_IN_HTACCESS);
        int apr_hook_when = APR_HOOK_MIDDLE;
        if (err) {
            return err;
        }
        
        if (when) { 
            if (!strcasecmp(when, "early")) { 
                apr_hook_when = AP_LUA_HOOK_FIRST;
            } 
            else if (!strcasecmp(when, "late")) { 
                apr_hook_when = AP_LUA_HOOK_LAST;
            } 
            else { 
                return "Third argument must be 'early' or 'late'";
            }
        }
    
        return register_named_file_function_hook("translate_name", cmd, _cfg,
                                                 file, function, apr_hook_when);
    }
    
    static const char *register_translate_name_block(cmd_parms *cmd, void *_cfg,
                                                     const char *line)
    {
        return register_named_block_function_hook("translate_name", cmd, _cfg,
                                                  line);
    }
    
    
    static const char *register_fixups_hook(cmd_parms *cmd, void *_cfg,
                                            const char *file,
                                            const char *function)
    {
        return register_named_file_function_hook("fixups", cmd, _cfg, file,
                                                 function, APR_HOOK_MIDDLE);
    }
    static const char *register_fixups_block(cmd_parms *cmd, void *_cfg,
                                             const char *line)
    {
        return register_named_block_function_hook("fixups", cmd, _cfg, line);
    }
    
    static const char *register_map_to_storage_hook(cmd_parms *cmd, void *_cfg,
                                                    const char *file,
                                                    const char *function)
    {
        return register_named_file_function_hook("map_to_storage", cmd, _cfg,
                                                 file, function, APR_HOOK_MIDDLE);
    }
    
    static const char *register_log_transaction_hook(cmd_parms *cmd, void *_cfg,
                                                    const char *file,
                                                    const char *function)
    {
        return register_named_file_function_hook("log_transaction", cmd, _cfg,
                                                 file, function, APR_HOOK_FIRST);
    }
    
    static const char *register_map_to_storage_block(cmd_parms *cmd, void *_cfg,
                                                     const char *line)
    {
        return register_named_block_function_hook("map_to_storage", cmd, _cfg,
                                                  line);
    }
    
    
    static const char *register_check_user_id_hook(cmd_parms *cmd, void *_cfg,
                                                   const char *file,
                                                   const char *function,
                                                   const char *when)
    {
        int apr_hook_when = APR_HOOK_MIDDLE;
    /* XXX: This does not currently work!!
        if (when) {
            if (!strcasecmp(when, "early")) {
                apr_hook_when = AP_LUA_HOOK_FIRST;
            }
            else if (!strcasecmp(when, "late")) {
                apr_hook_when = AP_LUA_HOOK_LAST;
            }
            else {
                return "Third argument must be 'early' or 'late'";
            }
        }
    */
        return register_named_file_function_hook("check_user_id", cmd, _cfg, file,
                                                 function, apr_hook_when);
    }
    static const char *register_check_user_id_block(cmd_parms *cmd, void *_cfg,
                                                    const char *line)
    {
        return register_named_block_function_hook("check_user_id", cmd, _cfg,
                                                  line);
    }
    
    static const char *register_type_checker_hook(cmd_parms *cmd, void *_cfg,
                                                  const char *file,
                                                  const char *function)
    {
        return register_named_file_function_hook("type_checker", cmd, _cfg, file,
                                                 function, APR_HOOK_MIDDLE);
    }
    static const char *register_type_checker_block(cmd_parms *cmd, void *_cfg,
                                                   const char *line)
    {
        return register_named_block_function_hook("type_checker", cmd, _cfg,
                                                  line);
    }
    
    static const char *register_access_checker_hook(cmd_parms *cmd, void *_cfg,
                                                    const char *file,
                                                    const char *function,
                                                    const char *when)
    {
        int apr_hook_when = APR_HOOK_MIDDLE;
    
        if (when) {
            if (!strcasecmp(when, "early")) {
                apr_hook_when = AP_LUA_HOOK_FIRST;
            }
            else if (!strcasecmp(when, "late")) {
                apr_hook_when = AP_LUA_HOOK_LAST;
            }
            else {
                return "Third argument must be 'early' or 'late'";
            }
        }
    
        return register_named_file_function_hook("access_checker", cmd, _cfg,
                                                 file, function, apr_hook_when);
    }
    static const char *register_access_checker_block(cmd_parms *cmd, void *_cfg,
                                                     const char *line)
    {
    
        return register_named_block_function_hook("access_checker", cmd, _cfg,
                                                  line);
    }
    
    static const char *register_auth_checker_hook(cmd_parms *cmd, void *_cfg,
                                                  const char *file,
                                                  const char *function,
                                                  const char *when)
    {
        int apr_hook_when = APR_HOOK_MIDDLE;
    
        if (when) {
            if (!strcasecmp(when, "early")) {
                apr_hook_when = AP_LUA_HOOK_FIRST;
            }
            else if (!strcasecmp(when, "late")) {
                apr_hook_when = AP_LUA_HOOK_LAST;
            }
            else {
                return "Third argument must be 'early' or 'late'";
            }
        }
    
        return register_named_file_function_hook("auth_checker", cmd, _cfg, file,
                                                 function, apr_hook_when);
    }
    static const char *register_auth_checker_block(cmd_parms *cmd, void *_cfg,
                                                   const char *line)
    {
        return register_named_block_function_hook("auth_checker", cmd, _cfg,
                                                  line);
    }
    
    static const char *register_insert_filter_hook(cmd_parms *cmd, void *_cfg,
                                                   const char *file,
                                                   const char *function)
    {
        return "LuaHookInsertFilter not yet implemented";
    }
    
    static const char *register_quick_hook(cmd_parms *cmd, void *_cfg,
                                           const char *file, const char *function)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                    NOT_IN_HTACCESS);
        if (err) {
            return err;
        }
        return register_named_file_function_hook("quick", cmd, _cfg, file,
                                                 function, APR_HOOK_MIDDLE);
    }
    static const char *register_map_handler(cmd_parms *cmd, void *_cfg,
                                           const char* match, const char *file, const char *function)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                    NOT_IN_HTACCESS);
        if (err) {
            return err;
        }
        if (!function) function = "handle";
        return register_mapped_file_function_hook(match, cmd, _cfg, file,
                                                 function);
    }
    static const char *register_output_filter(cmd_parms *cmd, void *_cfg,
                                           const char* filter, const char *file, const char *function)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                    NOT_IN_HTACCESS);
        if (err) {
            return err;
        }
        if (!function) function = "handle";
        return register_filter_function_hook(filter, cmd, _cfg, file,
                                                 function, AP_LUA_FILTER_OUTPUT);
    }
    static const char *register_input_filter(cmd_parms *cmd, void *_cfg,
                                           const char* filter, const char *file, const char *function)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                    NOT_IN_HTACCESS);
        if (err) {
            return err;
        }
        if (!function) function = "handle";
        return register_filter_function_hook(filter, cmd, _cfg, file,
                                                 function, AP_LUA_FILTER_INPUT);
    }
    static const char *register_quick_block(cmd_parms *cmd, void *_cfg,
                                            const char *line)
    {
        return register_named_block_function_hook("quick", cmd, _cfg,
                                                  line);
    }
    
    
    
    static const char *register_package_helper(cmd_parms *cmd, 
                                               const char *arg,
                                               apr_array_header_t *dir_array)
    {
        apr_status_t rv;
    
        ap_lua_server_cfg *server_cfg =
            ap_get_module_config(cmd->server->module_config, &lua_module);
    
        char *fixed_filename;
        rv = apr_filepath_merge(&fixed_filename, 
                                server_cfg->root_path, 
                                arg,
                                APR_FILEPATH_NOTRELATIVE, 
                                cmd->pool);
    
        if (rv != APR_SUCCESS) {
            return apr_psprintf(cmd->pool,
                                "Unable to build full path to file, %s", arg);
        }
    
        *(const char **) apr_array_push(dir_array) = fixed_filename;
        return NULL;
    }
    
    
    /**
     * Called for config directive which looks like
     * LuaPackagePath /lua/package/path/mapped/thing/like/this/?.lua
     */
    static const char *register_package_dir(cmd_parms *cmd, void *_cfg,
                                            const char *arg)
    {
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    
        return register_package_helper(cmd, arg, cfg->package_paths);
    }
    
    /**
     * Called for config directive which looks like
     * LuaPackageCPath /lua/package/path/mapped/thing/like/this/?.so
     */
    static const char *register_package_cdir(cmd_parms *cmd, 
                                             void *_cfg,
                                             const char *arg)
    {
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    
        return register_package_helper(cmd, arg, cfg->package_cpaths);
    }
    
    static const char *register_lua_inherit(cmd_parms *cmd, 
                                          void *_cfg,
                                          const char *arg)
    {
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
        
        if (strcasecmp("none", arg) == 0) {
            cfg->inherit = AP_LUA_INHERIT_NONE;
        }
        else if (strcasecmp("parent-first", arg) == 0) {
            cfg->inherit = AP_LUA_INHERIT_PARENT_FIRST;
        }
        else if (strcasecmp("parent-last", arg) == 0) {
            cfg->inherit = AP_LUA_INHERIT_PARENT_LAST;
        }
        else { 
            return apr_psprintf(cmd->pool,
                                "LuaInherit type of '%s' not recognized, valid "
                                "options are 'none', 'parent-first', and 'parent-last'", 
                                arg);
        }
        return NULL;
    }
    static const char *register_lua_codecache(cmd_parms *cmd, 
                                          void *_cfg,
                                          const char *arg)
    {
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
        
        if (strcasecmp("never", arg) == 0) {
            cfg->codecache = AP_LUA_CACHE_NEVER;
        }
        else if (strcasecmp("stat", arg) == 0) {
            cfg->codecache = AP_LUA_CACHE_STAT;
        }
        else if (strcasecmp("forever", arg) == 0) {
            cfg->codecache = AP_LUA_CACHE_FOREVER;
        }
        else { 
            return apr_psprintf(cmd->pool,
                                "LuaCodeCache type of '%s' not recognized, valid "
                                "options are 'never', 'stat', and 'forever'", 
                                arg);
        }
        return NULL;
    }
    static const char *register_lua_scope(cmd_parms *cmd, 
                                          void *_cfg,
                                          const char *scope, 
                                          const char *min,
                                          const char *max)
    {
        ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
        if (strcmp("once", scope) == 0) {
            cfg->vm_scope = AP_LUA_SCOPE_ONCE;
        }
        else if (strcmp("request", scope) == 0) {
            cfg->vm_scope = AP_LUA_SCOPE_REQUEST;
        }
        else if (strcmp("conn", scope) == 0) {
            cfg->vm_scope = AP_LUA_SCOPE_CONN;
        }
        else if (strcmp("thread", scope) == 0) {
    #if !APR_HAS_THREADS
            return apr_psprintf(cmd->pool,
                                "Scope type of '%s' cannot be used because this "
                                "server does not have threading support "
                                "(APR_HAS_THREADS)",
                                scope);
    #endif
            cfg->vm_scope = AP_LUA_SCOPE_THREAD;
        }
        else if (strcmp("server", scope) == 0) {
            unsigned int vmin, vmax;
    #if !APR_HAS_THREADS
            return apr_psprintf(cmd->pool,
                                "Scope type of '%s' cannot be used because this "
                                "server does not have threading support "
                                "(APR_HAS_THREADS)",
                                scope);
    #endif
            cfg->vm_scope = AP_LUA_SCOPE_SERVER;
            vmin = min ? atoi(min) : 1;
            vmax = max ? atoi(max) : 1;
            if (vmin == 0) {
                vmin = 1;
            }
            if (vmax < vmin) {
                vmax = vmin;
            }
            cfg->vm_min = vmin;
            cfg->vm_max = vmax;
        }
        else {
            return apr_psprintf(cmd->pool,
                                "Invalid value for LuaScope, '%s', acceptable "
                                "values are: 'once', 'request', 'conn'"
    #if APR_HAS_THREADS
                                ", 'thread', 'server'"
    #endif
                                ,scope);
        }
    
        return NULL;
    }
    
    
    
    static const char *register_lua_root(cmd_parms *cmd, void *_cfg,
                                         const char *root)
    {
        /* ap_lua_dir_cfg* cfg = (ap_lua_dir_cfg*)_cfg; */
        ap_lua_server_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                                      &lua_module);
    
        cfg->root_path = root;
        return NULL;
    }
    
    const char *ap_lua_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c,
                               request_rec *r, const char *var)
    {
        return ap_ssl_var_lookup(p, s, c, r, var);
    }
    
    int ap_lua_ssl_is_https(conn_rec *c)
    {
        return ap_ssl_conn_is_ssl(c);
    }
    
    /*******************************/
    
    static const char *lua_authz_parse(cmd_parms *cmd, const char *require_line,
                                       const void **parsed_require_line)
    {
        const char *provider_name;
        lua_authz_provider_spec *spec;
        lua_authz_provider_func *func = apr_pcalloc(cmd->pool, sizeof(lua_authz_provider_func));
    
        apr_pool_userdata_get((void**)&provider_name, AUTHZ_PROVIDER_NAME_NOTE,
                              cmd->temp_pool);
        ap_assert(provider_name != NULL);
    
        spec = apr_hash_get(lua_authz_providers, provider_name, APR_HASH_KEY_STRING);
        ap_assert(spec != NULL);
        func->spec = spec;
    
        if (require_line && *require_line) {
            const char *arg;
            func->args = apr_array_make(cmd->pool, 2, sizeof(const char *));
            while ((arg = ap_getword_conf(cmd->pool, &require_line)) && *arg) {
                APR_ARRAY_PUSH(func->args, const char *) = arg;
            }
        }
    
        *parsed_require_line = func;
        return NULL;
    }
    
    static authz_status lua_authz_check(request_rec *r, const char *require_line,
                                        const void *parsed_require_line)
    {
        apr_pool_t *pool;
        ap_lua_vm_spec *spec;
        lua_State *L;
        ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
                                                             &lua_module);
        const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                         &lua_module);
        const lua_authz_provider_func *prov_func = parsed_require_line;
        const lua_authz_provider_spec *prov_spec = prov_func->spec;
        int result;
        int nargs = 0;
    
        spec = create_vm_spec(&pool, r, cfg, server_cfg, prov_spec->file_name,
                              NULL, 0, prov_spec->function_name, "authz provider");
    
        L = ap_lua_get_lua_state(pool, spec, r);
        if (L == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02314)
                          "Unable to compile VM for authz provider %s", prov_spec->name);
            return AUTHZ_GENERAL_ERROR;
        }
        lua_getglobal(L, prov_spec->function_name);
        if (!lua_isfunction(L, -1)) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02319)
                          "Unable to find entry function '%s' in %s (not a valid function)",
                          prov_spec->function_name, prov_spec->file_name);
            ap_lua_release_state(L, spec, r);
            return AUTHZ_GENERAL_ERROR;
        }
        ap_lua_run_lua_request(L, r);
        if (prov_func->args) {
            int i;
            if (!lua_checkstack(L, prov_func->args->nelts)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02315)
                              "Error: authz provider %s: too many arguments", prov_spec->name);
                ap_lua_release_state(L, spec, r);
                return AUTHZ_GENERAL_ERROR;
            }
            for (i = 0; i < prov_func->args->nelts; i++) {
                const char *arg = APR_ARRAY_IDX(prov_func->args, i, const char *);
                lua_pushstring(L, arg);
            }
            nargs = prov_func->args->nelts;
        }
        if (lua_pcall(L, 1 + nargs, 1, 0)) {
            const char *err = lua_tostring(L, -1);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02316)
                          "Error executing authz provider %s: %s", prov_spec->name, err);
            ap_lua_release_state(L, spec, r);
            return AUTHZ_GENERAL_ERROR;
        }
        if (!lua_isnumber(L, -1)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02317)
                          "Error: authz provider %s did not return integer", prov_spec->name);
            ap_lua_release_state(L, spec, r);
            return AUTHZ_GENERAL_ERROR;
        }
        result = lua_tointeger(L, -1);
        ap_lua_release_state(L, spec, r);
        switch (result) {
            case AUTHZ_DENIED:
            case AUTHZ_GRANTED:
            case AUTHZ_NEUTRAL:
            case AUTHZ_GENERAL_ERROR:
            case AUTHZ_DENIED_NO_USER:
                return result;
            default:
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02318)
                              "Error: authz provider %s: invalid return value %d",
                              prov_spec->name, result);
        }
        return AUTHZ_GENERAL_ERROR;
    }
    
    static const authz_provider lua_authz_provider =
    {
        &lua_authz_check,
        &lua_authz_parse,
    };
    
    static const char *register_authz_provider(cmd_parms *cmd, void *_cfg,
                                               const char *name, const char *file,
                                               const char *function)
    {
        lua_authz_provider_spec *spec;
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err)
            return err;
    
        spec = apr_pcalloc(cmd->pool, sizeof(*spec));
        spec->name = name;
        spec->file_name = file;
        spec->function_name = function;
    
        apr_hash_set(lua_authz_providers, name, APR_HASH_KEY_STRING, spec);
        ap_register_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP, name,
                                  AUTHZ_PROVIDER_VERSION,
                                  &lua_authz_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        return NULL;
    }
    
    
    static const command_rec lua_commands[] = {
    
        AP_INIT_TAKE1("LuaRoot", register_lua_root, NULL, OR_ALL,
                      "Specify the base path for resolving relative paths for mod_lua directives"),
    
        AP_INIT_TAKE1("LuaPackagePath", register_package_dir, NULL, OR_ALL,
                      "Add a directory to lua's package.path"),
    
        AP_INIT_TAKE1("LuaPackageCPath", register_package_cdir, NULL, OR_ALL,
                      "Add a directory to lua's package.cpath"),
    
        AP_INIT_TAKE3("LuaAuthzProvider", register_authz_provider, NULL, RSRC_CONF|EXEC_ON_READ,
                      "Provide an authorization provider"),
    
        AP_INIT_TAKE2("LuaHookPreTranslateName", register_pre_trans_name_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the pre_translate name phase of request processing"),
    
        AP_INIT_RAW_ARGS("<LuaHookPreTranslateName", register_pre_trans_name_block, NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the pre_translate name phase of request processing"),
    
        AP_INIT_TAKE23("LuaHookTranslateName", register_translate_name_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the translate name phase of request processing"),
    
        AP_INIT_RAW_ARGS("<LuaHookTranslateName", register_translate_name_block,
                         NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the translate name phase of request processing"),
    
        AP_INIT_TAKE2("LuaHookFixups", register_fixups_hook, NULL, OR_ALL,
                      "Provide a hook for the fixups phase of request processing"),
        AP_INIT_RAW_ARGS("<LuaHookFixups", register_fixups_block, NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a inline hook for the fixups phase of request processing"),
    
        /* todo: test */
        AP_INIT_TAKE2("LuaHookMapToStorage", register_map_to_storage_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the map_to_storage phase of request processing"),
        AP_INIT_RAW_ARGS("<LuaHookMapToStorage", register_map_to_storage_block,
                         NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the map_to_storage phase of request processing"),
    
        /* todo: test */
        AP_INIT_TAKE23("LuaHookCheckUserID", register_check_user_id_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the check_user_id phase of request processing"),
        AP_INIT_RAW_ARGS("<LuaHookCheckUserID", register_check_user_id_block,
                         NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the check_user_id phase of request processing"),
    
        /* todo: test */
        AP_INIT_TAKE2("LuaHookTypeChecker", register_type_checker_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the type_checker phase of request processing"),
        AP_INIT_RAW_ARGS("<LuaHookTypeChecker", register_type_checker_block, NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the type_checker phase of request processing"),
    
        /* todo: test */
        AP_INIT_TAKE23("LuaHookAccessChecker", register_access_checker_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the access_checker phase of request processing"),
        AP_INIT_RAW_ARGS("<LuaHookAccessChecker", register_access_checker_block,
                         NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the access_checker phase of request processing"),
    
        /* todo: test */
        AP_INIT_TAKE23("LuaHookAuthChecker", register_auth_checker_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the auth_checker phase of request processing"),
        AP_INIT_RAW_ARGS("<LuaHookAuthChecker", register_auth_checker_block, NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the auth_checker phase of request processing"),
    
        /* todo: test */
        AP_INIT_TAKE2("LuaHookInsertFilter", register_insert_filter_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the insert_filter phase of request processing"),
        
        AP_INIT_TAKE2("LuaHookLog", register_log_transaction_hook, NULL,
                      OR_ALL,
                      "Provide a hook for the logging phase of request processing"),
    
        AP_INIT_TAKE123("LuaScope", register_lua_scope, NULL, OR_ALL,
                        "One of once, request, conn, server -- default is once"),
    
        AP_INIT_TAKE1("LuaInherit", register_lua_inherit, NULL, OR_ALL,
         "Controls how Lua scripts in parent contexts are merged with the current " 
         " context: none|parent-last|parent-first (default: parent-first) "),
        
        AP_INIT_TAKE1("LuaCodeCache", register_lua_codecache, NULL, OR_ALL,
         "Controls the behavior of the in-memory code cache " 
         " context: stat|forever|never (default: stat) "),
    
        AP_INIT_TAKE2("LuaQuickHandler", register_quick_hook, NULL, OR_ALL,
                      "Provide a hook for the quick handler of request processing"),
        AP_INIT_RAW_ARGS("<LuaQuickHandler", register_quick_block, NULL,
                         EXEC_ON_READ | OR_ALL,
                         "Provide a hook for the quick handler of request processing"),
        AP_INIT_RAW_ARGS("Lua_____ByteCodeHack", hack_section_handler, NULL,
                         OR_ALL,
                         "(internal) Byte code handler"),
        AP_INIT_TAKE23("LuaMapHandler", register_map_handler, NULL, OR_ALL,
                      "Maps a path to a lua handler"),
        AP_INIT_TAKE3("LuaOutputFilter", register_output_filter, NULL, OR_ALL,
                      "Registers a Lua function as an output filter"),
        AP_INIT_TAKE3("LuaInputFilter", register_input_filter, NULL, OR_ALL,
                      "Registers a Lua function as an input filter"),
        {NULL}
    };
    
    
    static void *create_dir_config(apr_pool_t *p, char *dir)
    {
        ap_lua_dir_cfg *cfg = apr_pcalloc(p, sizeof(ap_lua_dir_cfg));
        cfg->package_paths = apr_array_make(p, 2, sizeof(char *));
        cfg->package_cpaths = apr_array_make(p, 2, sizeof(char *));
        cfg->mapped_handlers =
            apr_array_make(p, 1, sizeof(ap_lua_mapped_handler_spec *));
        cfg->mapped_filters =
            apr_array_make(p, 1, sizeof(ap_lua_filter_handler_spec *));
        cfg->pool = p;
        cfg->hooks = apr_hash_make(p);
        cfg->dir = apr_pstrdup(p, dir);
        cfg->vm_scope = AP_LUA_SCOPE_UNSET;
        cfg->codecache = AP_LUA_CACHE_UNSET;
        cfg->vm_min = 0;
        cfg->vm_max = 0;
        cfg->inherit = AP_LUA_INHERIT_UNSET;
    
        return cfg;
    }
    
    static int create_request_config(request_rec *r)
    {
        ap_lua_request_cfg *cfg = apr_palloc(r->pool, sizeof(ap_lua_request_cfg));
        cfg->mapped_request_details = NULL;
        cfg->request_scoped_vms = apr_hash_make(r->pool);
        ap_set_module_config(r->request_config, &lua_module, cfg);
        return OK;
    }
    
    static void *create_server_config(apr_pool_t *p, server_rec *s)
    {
    
        ap_lua_server_cfg *cfg = apr_pcalloc(p, sizeof(ap_lua_server_cfg));
        cfg->root_path = NULL;
    
        return cfg;
    }
    
    static int lua_request_hook(lua_State *L, request_rec *r)
    {
        ap_lua_push_request(L, r);
        return OK;
    }
    
    static int lua_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                apr_pool_t *ptemp)
    {
        ap_mutex_register(pconf, "lua-ivm-shm", NULL, APR_LOCK_DEFAULT, 0);
        return OK;
    }
    
    static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                 apr_pool_t *ptemp, server_rec *s)
    {
        apr_pool_t **pool;
        apr_status_t rs;
    
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
            return OK;
    
        /* Create ivm mutex */
        rs = ap_global_mutex_create(&lua_ivm_mutex, NULL, "lua-ivm-shm", NULL,
                                s, pconf, 0);
        if (APR_SUCCESS != rs) {
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* Create shared memory space, anonymous first if possible. */
        rs = apr_shm_create(&lua_ivm_shm, sizeof pool, NULL, pconf);
        if (APR_STATUS_IS_ENOTIMPL(rs)) {
            /* Fall back to filename-based; nuke any left-over first. */
            lua_ivm_shmfile = ap_runtime_dir_relative(pconf, DEFAULT_LUA_SHMFILE);
    
            apr_shm_remove(lua_ivm_shmfile, pconf);
            
            rs = apr_shm_create(&lua_ivm_shm, sizeof pool, lua_ivm_shmfile, pconf);
        }
        if (rs != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02665)
                "mod_lua: Failed to create shared memory segment on file %s",
                         lua_ivm_shmfile ? lua_ivm_shmfile : "(anonymous)");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        pool = (apr_pool_t **)apr_shm_baseaddr_get(lua_ivm_shm);
        apr_pool_create(pool, pconf);
        apr_pool_tag(*pool, "mod_lua-shared");
        apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper,
                              apr_pool_cleanup_null);
        return OK;
    }
    static void *overlay_hook_specs(apr_pool_t *p,
                                            const void *key,
                                            apr_ssize_t klen,
                                            const void *overlay_val,
                                            const void *base_val,
                                            const void *data)
    {
        const apr_array_header_t *overlay_info = (const apr_array_header_t*)overlay_val;
        const apr_array_header_t *base_info = (const apr_array_header_t*)base_val;
        return apr_array_append(p, base_info, overlay_info);
    }
    
    static void *merge_dir_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        ap_lua_dir_cfg *a, *base, *overrides;
    
        a         = (ap_lua_dir_cfg *)apr_pcalloc(p, sizeof(ap_lua_dir_cfg));
        base      = (ap_lua_dir_cfg*)basev;
        overrides = (ap_lua_dir_cfg*)overridesv;
    
        a->pool = overrides->pool;
        a->dir = apr_pstrdup(p, overrides->dir);
    
        a->vm_scope = (overrides->vm_scope == AP_LUA_SCOPE_UNSET) ? base->vm_scope: overrides->vm_scope;
        a->inherit = (overrides->inherit == AP_LUA_INHERIT_UNSET) ? base->inherit : overrides->inherit;
        a->codecache = (overrides->codecache == AP_LUA_CACHE_UNSET) ? base->codecache : overrides->codecache;
        
        a->vm_min = (overrides->vm_min == 0) ? base->vm_min : overrides->vm_min;
        a->vm_max = (overrides->vm_max == 0) ? base->vm_max : overrides->vm_max;
    
        if (a->inherit == AP_LUA_INHERIT_UNSET || a->inherit == AP_LUA_INHERIT_PARENT_FIRST) { 
            a->package_paths = apr_array_append(p, base->package_paths, overrides->package_paths);
            a->package_cpaths = apr_array_append(p, base->package_cpaths, overrides->package_cpaths);
            a->mapped_handlers = apr_array_append(p, base->mapped_handlers, overrides->mapped_handlers);
            a->mapped_filters = apr_array_append(p, base->mapped_filters, overrides->mapped_filters);
            a->hooks = apr_hash_merge(p, overrides->hooks, base->hooks, overlay_hook_specs, NULL);
        }
        else if (a->inherit == AP_LUA_INHERIT_PARENT_LAST) { 
            a->package_paths = apr_array_append(p, overrides->package_paths, base->package_paths);
            a->package_cpaths = apr_array_append(p, overrides->package_cpaths, base->package_cpaths);
            a->mapped_handlers = apr_array_append(p, overrides->mapped_handlers, base->mapped_handlers);
            a->mapped_filters = apr_array_append(p, overrides->mapped_filters, base->mapped_filters);
            a->hooks = apr_hash_merge(p, base->hooks, overrides->hooks, overlay_hook_specs, NULL);
        }
        else { 
            a->package_paths = overrides->package_paths;
            a->package_cpaths = overrides->package_cpaths;
            a->mapped_handlers= overrides->mapped_handlers;
            a->mapped_filters= overrides->mapped_filters;
            a->hooks= overrides->hooks;
        }
    
        return a;
    }
    
    static void lua_register_hooks(apr_pool_t *p)
    {
        /* ap_register_output_filter("luahood", luahood, NULL, AP_FTYPE_RESOURCE); */
        ap_hook_handler(lua_handler, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_create_request(create_request_config, NULL, NULL,
                               APR_HOOK_MIDDLE);
    
        /* http_request.h hooks */
        ap_hook_pre_translate_name(lua_pre_trans_name_harness, NULL, NULL,
                                   APR_HOOK_MIDDLE);
    
        ap_hook_translate_name(lua_translate_name_harness_first, NULL, NULL,
                               AP_LUA_HOOK_FIRST);
        ap_hook_translate_name(lua_translate_name_harness, NULL, NULL,
                               APR_HOOK_MIDDLE);
        ap_hook_translate_name(lua_translate_name_harness_last, NULL, NULL,
                               AP_LUA_HOOK_LAST);
    
        ap_hook_fixups(lua_fixup_harness, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_map_to_storage(lua_map_to_storage_harness, NULL, NULL,
                               APR_HOOK_MIDDLE);
    
    /*  XXX: Does not work :(  
     *  ap_hook_check_user_id(lua_check_user_id_harness_first, NULL, NULL,
                              AP_LUA_HOOK_FIRST);
     */
        ap_hook_check_user_id(lua_check_user_id_harness, NULL, NULL,
                               APR_HOOK_MIDDLE);
    /*  XXX: Does not work :(
     * ap_hook_check_user_id(lua_check_user_id_harness_last, NULL, NULL,
                              AP_LUA_HOOK_LAST);
    */
        ap_hook_type_checker(lua_type_checker_harness, NULL, NULL,
                             APR_HOOK_MIDDLE);
    
        ap_hook_access_checker(lua_access_checker_harness_first, NULL, NULL,
                               AP_LUA_HOOK_FIRST);
        ap_hook_access_checker(lua_access_checker_harness, NULL, NULL,
                               APR_HOOK_MIDDLE);
        ap_hook_access_checker(lua_access_checker_harness_last, NULL, NULL,
                               AP_LUA_HOOK_LAST);
        ap_hook_auth_checker(lua_auth_checker_harness_first, NULL, NULL,
                             AP_LUA_HOOK_FIRST);
        ap_hook_auth_checker(lua_auth_checker_harness, NULL, NULL,
                             APR_HOOK_MIDDLE);
        ap_hook_auth_checker(lua_auth_checker_harness_last, NULL, NULL,
                             AP_LUA_HOOK_LAST);
    
        ap_hook_insert_filter(lua_insert_filter_harness, NULL, NULL,
                              APR_HOOK_MIDDLE);
        ap_hook_quick_handler(lua_quick_harness, NULL, NULL, APR_HOOK_FIRST);
    
        ap_hook_post_config(lua_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_pre_config(lua_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    
        APR_OPTIONAL_HOOK(ap_lua, lua_open, lua_open_hook, NULL, NULL,
                          APR_HOOK_REALLY_FIRST);
    
        APR_OPTIONAL_HOOK(ap_lua, lua_request, lua_request_hook, NULL, NULL,
                          APR_HOOK_REALLY_FIRST);
        ap_hook_handler(lua_map_handler, NULL, NULL, AP_LUA_HOOK_FIRST);
        
        /* Hook this right before FallbackResource kicks in */
        ap_hook_fixups(lua_map_handler_fixups, NULL, NULL, AP_LUA_HOOK_LAST-2);
        ap_hook_child_init(ap_lua_init_mutex, NULL, NULL, APR_HOOK_MIDDLE);
    
        /* providers */
        lua_authz_providers = apr_hash_make(p);
        
        /* Logging catcher */
        ap_hook_log_transaction(lua_log_transaction_harness,NULL,NULL,
                                APR_HOOK_FIRST);
    }
    
    AP_DECLARE_MODULE(lua) = {
        STANDARD20_MODULE_STUFF,
        create_dir_config,          /* create per-dir    config structures */
        merge_dir_config,           /* merge  per-dir    config structures */
        create_server_config,       /* create per-server config structures */
        NULL,                       /* merge  per-server config structures */
        lua_commands,               /* table of config file commands       */
        lua_register_hooks          /* register hooks                      */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_apr.c������������������������������������������������������������������0000664�0001751�0001751�00000006122�13614571031�016644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_lua.h"
    #include "lua_apr.h"
    APLOG_USE_MODULE(lua);
    
    req_table_t *ap_lua_check_apr_table(lua_State *L, int index)
    {
        req_table_t* t;
        luaL_checkudata(L, index, "Apr.Table");
        t = lua_unboxpointer(L, index);
        return t;
    }
    
    
    void ap_lua_push_apr_table(lua_State *L, req_table_t *t)
    {
        lua_boxpointer(L, t);
        luaL_getmetatable(L, "Apr.Table");
        lua_setmetatable(L, -2);
    }
    
    static int lua_table_set(lua_State *L)
    {
        req_table_t    *t = ap_lua_check_apr_table(L, 1);
        const char     *key = luaL_checkstring(L, 2);
        const char     *val = luaL_optlstring(L, 3, NULL, NULL);
    
        if (!val) { 
            apr_table_unset(t->t, key);
            return 0;
        }
    
        /* Unless it's the 'notes' table, check for newline chars */
        /* t->r will be NULL in case of the connection notes, but since 
           we aren't going to check anything called 'notes', we can safely 
           disregard checking whether t->r is defined.
        */
        if (strcmp(t->n, "notes") && ap_strchr_c(val, '\n')) {
            char *badchar;
            char *replacement = apr_pstrdup(t->r->pool, val);
            badchar = replacement;
            while ( (badchar = ap_strchr(badchar, '\n')) ) {
                *badchar = ' ';
            }
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, t->r, APLOGNO(02614)
                          "mod_lua: Value for '%s' in table '%s' contains newline!",
                      key, t->n);
            apr_table_set(t->t, key, replacement);
        }
        else {
            apr_table_set(t->t, key, val);
        }
        return 0;
    }
    
    static int lua_table_get(lua_State *L)
    {
        req_table_t    *t = ap_lua_check_apr_table(L, 1);
        const char     *key = luaL_checkstring(L, 2);
        const char     *val = apr_table_get(t->t, key);
        lua_pushstring(L, val);
        return 1;
    }
    
    static const luaL_Reg lua_table_methods[] = {
        {"set", lua_table_set},
        {"get", lua_table_get},
        {0, 0}
    };
    
    
    int ap_lua_init(lua_State *L, apr_pool_t *p)
    {
        luaL_newmetatable(L, "Apr.Table");
    #if LUA_VERSION_NUM < 502
        luaL_register(L, "apr_table", lua_table_methods);
    #else
        luaL_newlib(L, lua_table_methods);
    #endif
        lua_pushstring(L, "__index");
        lua_pushstring(L, "get");
        lua_gettable(L, 2);
        lua_settable(L, 1);
    
        lua_pushstring(L, "__newindex");
        lua_pushstring(L, "set");
        lua_gettable(L, 2);
        lua_settable(L, 1);
    
        return 0;
    }
    
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/NWGNUmakefile��������������������������������������������������������������0000664�0001751�0001751�00000011735�13055576313�017411� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(SRC)/include \
    			$(STDMOD)/database \
    			$(STDMOD)/http \
    			$(STDMOD)/ssl \
    			$(NWOS) \
    			$(LUASRC)/src \
    			$(EOLIST)
    
    #
    # These flags will come after CFLAGS
    #
    XCFLAGS		+= \
    			-opt nointrinsics \
    			$(EOLIST)
    
    #
    # These defines will come after DEFINES
    #
    XDEFINES	+= \
    			-DLUA_COMPAT_ALL \
    			-DLUA_COMPAT_5_2 \
    			-DLUA_COMPAT_5_1 \
    			-DLUA_COMPAT_MODULE \
    			$(EOLIST)
    
    #
    # These flags will be added to the link.opt file
    #
    XLFLAGS		+= \
    			-L$(OBJDIR) \
    			$(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_lua
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) LUA Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= LUA 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	= 131072
    
    
    #
    # 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)/$(NLM_NAME).nlm \
    	$(EOLIST)
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib = \
    	$(OBJDIR)/lua.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_lua.o \
    	$(OBJDIR)/lua_apr.o \
    	$(OBJDIR)/lua_config.o \
    	$(OBJDIR)/lua_passwd.o \
    	$(OBJDIR)/lua_request.o \
    	$(OBJDIR)/lua_vmprep.o \
    	$(OBJDIR)/lua_dbd.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 = \
    	$(PRELUDE) \
    	$(OBJDIR)/lua.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 = \
    	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 = \
    	@aprlib.imp \
    	@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 = \
    	lua_module \
    	$(EOLIST)
    
    #
    # These are the OBJ files needed to create the LIB target above.
    # Paths must all use the '/' character
    #
    UNWANTED = $(LUASRC)/src/lua.c $(LUASRC)/src/luac.c $(LUASRC)/src/print.c
    
    FILES_lib_objs = \
    	$(patsubst $(LUASRC)/src/%.c,$(OBJDIR)/%.o, $(filter-out $(UNWANTED), $(wildcard $(LUASRC)/src/*.c))) \
    	$(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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    vpath %.c $(LUASRC)/src ../arch/netware
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������httpd-2.4.64/modules/lua/docs/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016015� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/docs/writing-handlers.txt��������������������������������������������������0000664�0001751�0001751�00000003411�11366570643�022037� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mod_lua always looks to invoke a function for the handler, rather than
    just evaluating a script body CGI style. A handler function looks
    something like this:
    
        -- example.lua --
        require "string"
    
        function handle_something(r)
            r.content_type = "text/plain"
            r:puts("Hello Lua World!\n")
        
            if r.method == 'GET' then
                for k, v in pairs( r:parseargs() ) do
                    r:puts( string.format("%s: %s", k, v) )
                end
            elseif r.method == 'POST' then
                for k, v in pairs( r:parsebody() ) do
                    r:puts( string.format("%s: %s", k, v) )
                end
            else
                r:puts("unknown HTTP method " .. r.method)
            end 
        end
    
    This handler function just prints out the uri or form encoded
    arguments to a plaintext page.
    
    This means (and in fact encourages) that you can have multiple
    handlers (or hooks, or filters) in the same script.
    
    Data Structures:
        request_rec:
            the request_rec is mapped in as a userdata. It has a metatable
            which lets you do useful things with it. For the most part it
            has the same fields as the request_rec struct (see httpd.h 
            until we get better docs here) many of which are writeable as
            well as readable, and has (at least) the following methods:
            
            r:puts("hello", " world", "!") -- print to response body
            
            -- logging functions
            r:debug("This is a debug log message")
            r:info("This is an info log message")
            r:notice("This is an notice log message")
            r:warn("This is an warn log message")
            r:err("This is an err log message")
            r:alert("This is an alert log message")
            r:crit("This is an crit log message")
            r:emerg("This is an emerg log message")
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/docs/basic-configuration.txt�����������������������������������������������0000664�0001751�0001751�00000013023�11376506251�022477� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������See sample_httpd.conf for examples
    
    The basic module loading directive is
        LoadModule lua_module modules/mod_lua.so
    
    The handler name is "lua-script" so you can use the normal
    AddHandler directive, such as "AddHandler lua-script .lua" to
    set anything ending in .lua to use mod_lua to evaluate
    
    mod_lua exports several additional directives:
    
        LuaRoot /path/to/a/directory
            Specify the base path which will be used to evaluate all
            relative paths within mod_lua. If not specified they
            will be resolved relative to the current working directory,
            which may not always work well for a server.
    
        LuaScope once|request|conn|server [max|min max]
            Specify the lifecycle scope of the Lua interpreter which will
            be used by handlers in this "Directory." The default is "once"
            
            once: use the interpreter once and throw it away.
            
            request: use the interpreter to handle anything based on 
                     the same file within this request, which is also 
                     request scoped.
                     
            conn: Same as request but attached to the connection_rec
            
            server: This one is different than others because the
                    server scope is quite long lived, and multiple threads
                    will have the same server_rec. To accommodate this
                    server scoped interpreter are stored in an apr
                    resource list. The min and max arguments are intended
                    to specify the pool size, but are unused at this time.
    
        LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]
            This directive matches a uri pattern to invoke a specific
            handler function in a specific file. It uses PCRE regular
            expressions to match the uri, and supports interpolating
            match groups into both the file path and the function name
            be careful writing your regular expressions to avoid security
            issues.
            
            Examples:
                LuaMapHandler /(\w+)/(/w+) /scripts/$1.lua handle_$2
                    This would match uri's such as /photos/show?id=9
                    to the file /scripts/photos.lua and invoke the
                    handler function handle_show on the lua vm after
                    loading that file.
                    
                LuaMapHandler /bingo /scripts/wombat.lua
                    This would invoke the "handle" function, which
                    is the default if no specific function name is
                    provided.
        
        LuaPackagePath /path/to/include/?.lua
            Add a path to lua's module search path. Follows the same
            conventions as lua. This just munges the package.path in the 
            lua vms.
            
            Examples:
                LuaPackagePath /scripts/lib/?.lua
                LuaPackagePath /scripts/lib/?/init.lua
    
        LuaPackageCPath /path/to/include/?.soa
            Add a path to lua's shared library search path. Follows the same
            conventions as lua. This just munges the package.cpath in the 
            lua vms.
            
            Examples:
                LuaPackagePath /scripts/lib/?.so
    
        LuaCodeCache stat|forever|never
            Specify the behavior of the in-memory code cache. The default
            is stat, which stats the top level script (not any included
            ones) each time that file is needed, and reloads it if the
            modified time indicates it is newer than the one it has
            already loaded. The other values cause it to keep the file
            cached forever (don't stat and replace) or to never cache the 
            file.
            
            In general stat or forever is good production and stat or never
            for development.
            
            Examples:
                LuaCodeCache stat
                LuaCodeCache forever
                LuaCodeCache never
        
        LuaHookTranslateName  /path/to/lua/script.lua  hook_function_name
            Add a hook (at APR_HOOK_MIDDLE) to the translate name phase of
            request processing. The hook function receives a single
            argument, the request_rec, and should return a status code, 
            which is either an HTTP error code, or the constants defined
            in the apache2 module: apache2.OK, apache2.DECLINED, or
            apache2.DONE. 
    
            For those new to hooks, basically each hook will be invoked
            until one of them returns apache2.OK. If your hook doesn't
            want to do the translation it should just return
            apache2.DECLINED. If the request should stop processing, then
            return apache2.DONE.
    
            Example:
                LuaHookTranslateName /scripts/conf/hooks.lua silly_mapper
    
                -- /scripts/conf/hooks.lua --
                function silly_mapper(r)
                    if r.uri == "/" then
                        r.file = "/var/www/home.lua"
                        return apache2.OK
                    else
                        return apache2.DECLINED
                    end
                end
    
        LuaHookFixups  /path/to/lua/script.lua  hook_function_name
            Just like LuaHookTranslateName, but executed at the fixups phase
    
        LuaHookMapToStorage  /path/to/lua/script.lua  hook_function_name
            ...
    
        LuaHookCheckUserID  /path/to/lua/script.lua  hook_function_name
            ...
    
        LuaHookTypeChecker  /path/to/lua/script.lua  hook_function_name
            ...
    
        LuaHookAuthChecker  /path/to/lua/script.lua  hook_function_name
            ...
    
        LuaHookAccessChecker  /path/to/lua/script.lua  hook_function_name
            ...
    
        LuaHookAuthChecker  /path/to/lua/script.lua  hook_function_name
            ...
    
        LuaHookInsertFilter  /path/to/lua/script.lua  hook_function_name
            Not Yet Implemented
     
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/docs/README����������������������������������������������������������������0000664�0001751�0001751�00000000541�11123517417�016665� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Index of documents:
        building-from-subversion.txt
            Basic build instructions
            
        basic-configuration.txt
            Getting mod_wombat up and running
            
        running-developer-tests.txt
            How to set up and run the developer and regression tests
            
        writing-handlers.txt
            basics on writing handlers in mod_wombat���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/docs/building-from-subversion.txt������������������������������������������0000664�0001751�0001751�00000005312�11123517417�023502� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Install Lua 5.1
        http://www.lua.org/download.html
        
        Lua does not use autoconf for compiling. This means that you do not use
        ./configure. It has good build instructions, though, so hopefully things
        will go smoothly.
        
        I like to change the directory Lua installs to. In order to do this you
        need to set LUA_TOP in the configuration makefile for Lua. For these 
        instructions I have set LUA_TOP to /Users/brianm/.opt/lua-5.1.2 -- you
        will see this directory referred to later.
        
        
    Install Apache HTTPD 2.2
        http://httpd.apache.org/download.cgi
        
        You can build apache pretty much any way you like, as long as you enable
        dynamic module loading (--enable-so) so that mod_wombat can be loaded.
        
        You may user (and I encourage you to!) the threaded MPMs -- mod_wombat
        plays nicely with them.
    
        I build it with these flags:
            
        ./configure --prefix=/Users/brianm/.opt/httpd-2.2.4-worker-wombat \
                    --with-mpm=worker  \
                    --enable-so
        
        
    Install libapreq2
        http://httpd.apache.org/apreq/download.cgi
            The download link is in the page body, NOT under the "Download!" link
            in the left hand column.
        
        Right now, mod_wombat requires libapreq2 for parsing entity bodies. This
        dependency will probably be made optional in the near future, but for now
        you need it.
        
        I build it with these flags:
        
        ./configure --prefix=/Users/brianm/.opt/libapreq2-2.0.8 \
          --with-apache2-apxs=/Users/brianm/.opt/httpd-2.2.4-worker-wombat/bin/apxs
        
        
    Install mod_wombat from subversion
        http://svn.apache.org/repos/asf/httpd/mod_wombat/trunk
        
        The first step, when building from subversion, is to bootstrap autoconf. 
        To do this run the bootstrap script:
        
        ./bootstrap
        
        The bootstrap script may report an error that it cannot find
        libtoolize or glibtoolize. That is fine as long as it 
        doesn't report that it cannot find both of them. The script
        just sets up the autoconf magic. 
        
        After that, it is a normal configure and build:
        
        ./configure  --with-lua=/Users/brianm/.opt/lua-5.1.2/ \
          --with-apxs=/Users/brianm/.opt/httpd-2.2.4-worker-wombat/bin/apxs \
          --with-apreq2=/Users/brianm/.opt/libapreq2-2.0.8/
          
        If compiling (make) reports an error that it cannot find the
        libapreq2 header file, please tell me ( brianm@apache.org )
        as this occurs under some configurations but we haven't 
        hammered down the weird things libapreq2 does with its
        install. If you build libapreq2 with a --prefix configuration
        option, it always seems to work.
      
          
    That is it. To configure mod_wombat, look at the basic-configuration.txt document.����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/docs/running-developer-tests.txt�������������������������������������������0000664�0001751�0001751�00000001011�11366570643�023353� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-*- mode:org -*-
    * Building mod_lua
      The first step is to build mod_lua per the instructions in
      building-from-subversion.txt.
    
    * Build and install LuaSocket
        http://www.cs.princeton.edu/~diego/professional/luasocket/
        FreeBSD: /usr/ports/net/luasocket
    
    * Running Tests
      1. Replace apache's httpd.conf with test/test_httpd.conf
      2. Customize the new httpd.conf to match your directories
      3. Finally, to run the tests, start apache and run:
         $ cd test
         $ lua ./test.lua
         FreeBSD: lua-5.1 ./test.lua
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/mod_lua.mak����������������������������������������������������������������0000664�0001751�0001751�00000025571�12701473373�017206� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_lua.dsp
    !IF "$(CFG)" == ""
    CFG=mod_lua - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_lua - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_lua - Win32 Release" && "$(CFG)" != "mod_lua - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_lua.mak" CFG="mod_lua - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lua - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lua - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lua - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lua.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_lua.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\lua_apr.obj"
    	-@erase "$(INTDIR)\lua_config.obj"
    	-@erase "$(INTDIR)\lua_dbd.obj"
    	-@erase "$(INTDIR)\lua_passwd.obj"
    	-@erase "$(INTDIR)\lua_request.obj"
    	-@erase "$(INTDIR)\lua_vmprep.obj"
    	-@erase "$(INTDIR)\mod_lua.obj"
    	-@erase "$(INTDIR)\mod_lua.res"
    	-@erase "$(INTDIR)\mod_lua_src.idb"
    	-@erase "$(INTDIR)\mod_lua_src.pdb"
    	-@erase "$(OUTDIR)\mod_lua.exp"
    	-@erase "$(OUTDIR)\mod_lua.lib"
    	-@erase "$(OUTDIR)\mod_lua.pdb"
    	-@erase "$(OUTDIR)\mod_lua.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/lua/src" /I "../ssl" /I "../database" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_LUA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lua_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lua.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lua.so" /d LONG_NAME="lua_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lua.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lua.pdb" /debug /out:"$(OUTDIR)\mod_lua.so" /implib:"$(OUTDIR)\mod_lua.lib" /libpath:"../../srclib/lua/src" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\lua_apr.obj" \
    	"$(INTDIR)\lua_config.obj" \
    	"$(INTDIR)\lua_passwd.obj" \
    	"$(INTDIR)\lua_request.obj" \
    	"$(INTDIR)\lua_vmprep.obj" \
    	"$(INTDIR)\mod_lua.obj" \
    	"$(INTDIR)\lua_dbd.obj" \
    	"$(INTDIR)\mod_lua.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_lua.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_lua.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lua.so"
       if exist .\Release\mod_lua.so.manifest mt.exe -manifest .\Release\mod_lua.so.manifest -outputresource:.\Release\mod_lua.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_lua - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_lua.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_lua.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\lua_apr.obj"
    	-@erase "$(INTDIR)\lua_config.obj"
    	-@erase "$(INTDIR)\lua_dbd.obj"
    	-@erase "$(INTDIR)\lua_passwd.obj"
    	-@erase "$(INTDIR)\lua_request.obj"
    	-@erase "$(INTDIR)\lua_vmprep.obj"
    	-@erase "$(INTDIR)\mod_lua.obj"
    	-@erase "$(INTDIR)\mod_lua.res"
    	-@erase "$(INTDIR)\mod_lua_src.idb"
    	-@erase "$(INTDIR)\mod_lua_src.pdb"
    	-@erase "$(OUTDIR)\mod_lua.exp"
    	-@erase "$(OUTDIR)\mod_lua.lib"
    	-@erase "$(OUTDIR)\mod_lua.pdb"
    	-@erase "$(OUTDIR)\mod_lua.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/lua/src" /I "../ssl" /I "../database" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_LUA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_lua_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_lua.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lua.so" /d LONG_NAME="lua_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_lua.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_lua.pdb" /debug /out:"$(OUTDIR)\mod_lua.so" /implib:"$(OUTDIR)\mod_lua.lib" /libpath:"../../srclib/lua/src" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so 
    LINK32_OBJS= \
    	"$(INTDIR)\lua_apr.obj" \
    	"$(INTDIR)\lua_config.obj" \
    	"$(INTDIR)\lua_passwd.obj" \
    	"$(INTDIR)\lua_request.obj" \
    	"$(INTDIR)\lua_vmprep.obj" \
    	"$(INTDIR)\mod_lua.obj" \
    	"$(INTDIR)\lua_dbd.obj" \
    	"$(INTDIR)\mod_lua.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_lua.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_lua.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_lua.so"
       if exist .\Debug\mod_lua.so.manifest mt.exe -manifest .\Debug\mod_lua.so.manifest -outputresource:.\Debug\mod_lua.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_lua.dep")
    !INCLUDE "mod_lua.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_lua.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_lua - Win32 Release" || "$(CFG)" == "mod_lua - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_lua - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\lua"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\lua"
    
    !ELSEIF  "$(CFG)" == "mod_lua - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\lua"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\lua"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lua - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\lua"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\lua"
    
    !ELSEIF  "$(CFG)" == "mod_lua - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\lua"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\lua"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_lua - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\lua"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\lua"
    
    !ELSEIF  "$(CFG)" == "mod_lua - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\lua"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\lua"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_lua - Win32 Release"
    
    
    "$(INTDIR)\mod_lua.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lua.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_lua.so" /d LONG_NAME="lua_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_lua - Win32 Debug"
    
    
    "$(INTDIR)\mod_lua.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_lua.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_lua.so" /d LONG_NAME="lua_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\lua_apr.c
    
    "$(INTDIR)\lua_apr.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\lua_config.c
    
    "$(INTDIR)\lua_config.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\lua_dbd.c
    
    "$(INTDIR)\lua_dbd.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\lua_passwd.c
    
    "$(INTDIR)\lua_passwd.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\lua_request.c
    
    "$(INTDIR)\lua_request.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\lua_vmprep.c
    
    "$(INTDIR)\lua_vmprep.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\mod_lua.c
    
    "$(INTDIR)\mod_lua.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_passwd.h���������������������������������������������������������������0000664�0001751�0001751�00000004440�12210657505�017373� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _LUA_PASSWD_H
    #define _LUA_PASSWD_H
    
    #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_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    #define MAX_PASSWD_LEN 256
    
    #define ALG_APMD5  0
    #define ALG_APSHA  1
    #define ALG_BCRYPT 2
    #define ALG_CRYPT  3
    
    #define BCRYPT_DEFAULT_COST 5
    
    #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 ERR_RANDOM 8
    #define ERR_GENERAL 9
    #define ERR_ALG_NOT_SUPP 10
    
    #if defined(WIN32) || defined(NETWARE)
    #define CRYPT_ALGO_SUPPORTED 0
    #define PLAIN_ALGO_SUPPORTED 1
    #else
    #define CRYPT_ALGO_SUPPORTED 1
    #define PLAIN_ALGO_SUPPORTED 0
    #endif
    
    #if APR_VERSION_AT_LEAST(2,0,0) || \
        (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 5)
    #define BCRYPT_ALGO_SUPPORTED 1
    #else
    #define BCRYPT_ALGO_SUPPORTED 0
    #endif
    
    typedef struct passwd_ctx passwd_ctx;
    
    struct passwd_ctx {
        apr_pool_t      *pool;
        const char      *errstr;
        char            *out;
        apr_size_t      out_len;
        char            *passwd;
        int             alg;
        int             cost;
    };
    
    
    /*
     * The following functions return zero on success; otherwise, one of
     * the ERR_* codes is returned and an error message is stored in ctx->errstr.
     */
    
    /*
     * Make a password record from the given information.
     */
    int mk_password_hash(passwd_ctx *ctx);
    
    #endif /* _LUA_PASSWD_H */
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/mod_lua.h������������������������������������������������������������������0000664�0001751�0001751�00000012331�14046725222�016650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_LUA_H_
    #define _MOD_LUA_H_
    
    #include <stdio.h>
    
    #include "httpd.h"
    #include "http_core.h"
    #include "http_config.h"
    #include "http_request.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_ssl.h"
    #include "ap_regex.h"
    
    #include "ap_config.h"
    #include "util_filter.h"
    
    #include "apr_thread_rwlock.h"
    #include "apr_strings.h"
    #include "apr_tables.h"
    #include "apr_hash.h"
    #include "apr_buckets.h"
    #include "apr_file_info.h"
    #include "apr_time.h"
    #include "apr_hooks.h"
    #include "apr_reslist.h"
    
    #include "lua.h"
    #include "lauxlib.h"
    #include "lualib.h"
    
    #if LUA_VERSION_NUM > 501
    /* Load mode for lua_load() */
    #define lua_load(a,b,c,d)  lua_load(a,b,c,d,NULL)
    
    #if LUA_VERSION_NUM > 503
    #define lua_resume(a,b,c)    lua_resume(a, NULL, b, c)
    #else
    /* ### For version < 5.4, assume that exactly one stack item is on the
     * stack, which is what the code did before but seems dubious. */
    #define lua_resume(a,b,c)    (*(c) = 1, lua_resume(a, NULL, b))
    #endif
    
    #define luaL_setfuncs_compat(a,b) luaL_setfuncs(a,b,0)
    #else
    #define lua_rawlen(L,i)    lua_objlen(L, (i))
    #define luaL_setfuncs_compat(a,b) luaL_register(a,NULL,b)
    #define lua_resume(a,b,c)    (*(c) = 1, lua_resume(a, b))
    #endif
    #if LUA_VERSION_NUM > 502
    #define lua_dump(a,b,c) lua_dump(a,b,c,0)
    #endif
    
    /* Create a set of AP_LUA_DECLARE(type), AP_LUA_DECLARE_NONSTD(type) and
     * AP_LUA_DECLARE_DATA with appropriate export and import tags for the platform
     */
    #if !defined(WIN32)
    #define AP_LUA_DECLARE(type)            type
    #define AP_LUA_DECLARE_NONSTD(type)     type
    #define AP_LUA_DECLARE_DATA
    #elif defined(AP_LUA_DECLARE_STATIC)
    #define AP_LUA_DECLARE(type)            type __stdcall
    #define AP_LUA_DECLARE_NONSTD(type)     type
    #define AP_LUA_DECLARE_DATA
    #elif defined(AP_LUA_DECLARE_EXPORT)
    #define AP_LUA_DECLARE(type)            __declspec(dllexport) type __stdcall
    #define AP_LUA_DECLARE_NONSTD(type)     __declspec(dllexport) type
    #define AP_LUA_DECLARE_DATA             __declspec(dllexport)
    #else
    #define AP_LUA_DECLARE(type)            __declspec(dllimport) type __stdcall
    #define AP_LUA_DECLARE_NONSTD(type)     __declspec(dllimport) type
    #define AP_LUA_DECLARE_DATA             __declspec(dllimport)
    #endif
    
    
    #include "lua_request.h"
    #include "lua_vmprep.h"
    
    typedef enum {
        AP_LUA_INHERIT_UNSET        = -1,
        AP_LUA_INHERIT_NONE         =  0,
        AP_LUA_INHERIT_PARENT_FIRST =  1,
        AP_LUA_INHERIT_PARENT_LAST  =  2
    } ap_lua_inherit_t;
    
    /**
     * make a userdata out of a C pointer, and vice versa
     * instead of using lightuserdata
     */
    #ifndef lua_boxpointer
    #define lua_boxpointer(L,u) (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
    #define lua_unboxpointer(L,i)   (*(void **)(lua_touserdata(L, i)))
    #endif
    
    void ap_lua_rstack_dump(lua_State *L, request_rec *r, const char *msg);
    
    typedef struct
    {
        apr_array_header_t *package_paths;
        apr_array_header_t *package_cpaths;
    
        /**
         * mapped handlers/filters
         */
        apr_array_header_t *mapped_handlers;
        apr_array_header_t *mapped_filters;
    
        apr_pool_t *pool;
    
        /**
         * AP_LUA_SCOPE_ONCE | AP_LUA_SCOPE_REQUEST | AP_LUA_SCOPE_CONN | AP_LUA_SCOPE_SERVER
         */
        unsigned int vm_scope;
        unsigned int vm_min;
        unsigned int vm_max;
    
        /* info for the hook harnesses */
        apr_hash_t *hooks;          /* <wombat_hook_info> */
    
        /* the actual directory being configured */
        const char *dir;
      
        /* Whether Lua scripts in a sub-dir are run before parents */
        ap_lua_inherit_t inherit;
        
        /**
         * AP_LUA_CACHE_NEVER | AP_LUA_CACHE_STAT | AP_LUA_CACHE_FOREVER
         */
        unsigned int codecache;
    
    } ap_lua_dir_cfg;
    
    typedef struct
    {
        /* value of the LuaRoot directive */
        const char *root_path;
    } ap_lua_server_cfg;
    
    typedef struct
    {
        const char *function_name;
        ap_lua_vm_spec *spec;
    } mapped_request_details;
    
    typedef struct
    {
        mapped_request_details *mapped_request_details;
        apr_hash_t *request_scoped_vms;
    } ap_lua_request_cfg;
    
    typedef struct
    {
        lua_State *L;
        const char *function;
    } ap_lua_filter_ctx;
    
    extern module AP_MODULE_DECLARE_DATA lua_module;
    
    APR_DECLARE_EXTERNAL_HOOK(ap_lua, AP_LUA, int, lua_open,
                              (lua_State *L, apr_pool_t *p))
    
    APR_DECLARE_EXTERNAL_HOOK(ap_lua, AP_LUA, int, lua_request,
                              (lua_State *L, request_rec *r))
    
    const char *ap_lua_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c,
                               request_rec *r, const char *var);
    
    int ap_lua_ssl_is_https(conn_rec *c);
    
    #endif /* !_MOD_LUA_H_ */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/README���������������������������������������������������������������������0000664�0001751�0001751�00000003323�13127013226�015731� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-*- mode:org -*-
    * Requirements:
    ** lua 5.1, 5.2, 5.3 ( http://www.lua.org/ ) or LuaJIT 2.x ( http://www.luajit.org/ )
    ** Apache HTTPD 2.4 ( http://httpd.apache.org/ ) or higher
    
    * Documentation
      See docs/README
    
    * Building
      For now, see docs/building-from-subversion.txt
    
    
    * Task List
    ** TODO Use r->file to determine file, doing rewriting in translate_name   
    ** TODO Provide means to get useful output from lua errors in response body
       Probably have to put it on the vm spec for pre-handler errors, as
       it is pre-handler, will prolly be on the request_config somewhere,
       but sometimes cannot put there, so... fun
    ** TODO Mapping in the server_rec
    ** TODO Figure out how reentrancy works regarding filter chain stuff. 
       Do we need new "threads"?
    ** TODO: Flatten LuaHook* to LuaHook phase file fn ?
    ** TODO: document or remove block sections
    ** TODO: test per-dir behavior of block sections
    ** TODO: Suppress internal details (fs path to scripts, etc) in error responses
    ** TODO: Check whether we can tighten the mode flag in lua_load(),
             luaL_loadfile() an dluaL_loadbuffer() from NULL (="bt")
             to e.g. "t".
        
    * License
      Apache License, Version 2.0,
      
      http://www.apache.org/licenses/LICENSE-2.0 
    
      See NOTICE file for more information
            
    * Problems and Patches:
      Please use dev@httpd.apache.org for discussing mod_lua development
      To subscribe send email to dev-subscribe@httpd.apache.org  
      Note that this is for development discussion, not user support :-)
       
    * Contributors Include
    ** Brian McCallister
    ** Paul Querna
    ** Garrett Rooney
    ** Martin Traverso
    ** Brian Akins
    ** Justin Erenkrantz
    ** Philip M. Gollucci
    ** Stefan Fritsch
    ** Eric Covener
    ** Daniel Gruno
    ** Günter Knauf
    ** Jim Jagielski
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_request.h��������������������������������������������������������������0000664�0001751�0001751�00000003332�13055576313�017566� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _LUA_REQUEST_H_
    #define _LUA_REQUEST_H_
    
    #include "mod_lua.h"
    #include "util_varbuf.h"
    
    void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p);
    void ap_lua_push_connection(lua_State *L, conn_rec *r);
    void ap_lua_push_server(lua_State *L, server_rec *r);
    void ap_lua_push_request(lua_State *L, request_rec *r);
    
    #define APL_REQ_FUNTYPE_STRING      1
    #define APL_REQ_FUNTYPE_INT         2
    #define APL_REQ_FUNTYPE_TABLE       3
    #define APL_REQ_FUNTYPE_LUACFUN     4
    #define APL_REQ_FUNTYPE_BOOLEAN     5
    
    typedef struct
    {
        const void *fun;
        int type;
    } req_fun_t;
    
    
    /* Struct to use as userdata for request_rec tables */
    typedef struct
    {
        request_rec *r; /* Request_rec */
        apr_table_t *t; /* apr_table_t* */
        const char  *n; /* name of table */
    } req_table_t;
    
    typedef struct {
        int type;
        size_t size;
        size_t vb_size;
        lua_Number number;
        struct ap_varbuf vb;
    } lua_ivm_object;
    
    #endif /* !_LUA_REQUEST_H_ */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/mod_lua.dsp����������������������������������������������������������������0000664�0001751�0001751�00000012511�12223620035�017176� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_lua" - 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_lua - 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_lua.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_lua.mak" CFG="mod_lua - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_lua - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_lua - 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_lua - 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 "../../srclib/lua/src" /I "../ssl" /I "../database" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_LUA_DECLARE_EXPORT" /Fd"Release\mod_lua_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 /fo"Release/mod_lua.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_lua.so" /d LONG_NAME="lua_module for Apache"
    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 /out:".\Release\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so
    # ADD LINK32 kernel32.lib ws2_32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so /opt:ref /libpath:"../../srclib/lua/src"
    # Begin Special Build Tool
    TargetPath=.\Release\mod_lua.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_lua - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/lua/src" /I "../ssl" /I "../database" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_LUA_DECLARE_EXPORT" /Fd"Debug\mod_lua_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 /fo"Debug/mod_lua.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_lua.so" /d LONG_NAME="lua_module for Apache"
    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 /out:".\Debug\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so
    # ADD LINK32 kernel32.lib ws2_32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so /libpath:"../../srclib/lua/src"
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_lua.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_lua - Win32 Release"
    # Name "mod_lua - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\lua_apr.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_apr.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_config.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_config.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_passwd.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_passwd.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_request.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_request.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_vmprep.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_vmprep.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_lua.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_lua.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_dbd.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\lua_dbd.h
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_config.h���������������������������������������������������������������0000664�0001751�0001751�00000002371�12155362210�017332� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_lua.h"
    
    #ifndef _APL_CONFIG_H_
    #define _APL_CONFIG_H_
    
    void ap_lua_load_config_lmodule(lua_State *L);
    
    apr_status_t ap_lua_map_handler(ap_lua_dir_cfg *cfg,
                                                    const char *file,
                                                    const char *function,
                                                    const char *pattern,
                                                    const char *scope);
    
    #endif /* !_APL_CONFIG_H_ */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_request.c��������������������������������������������������������������0000664�0001751�0001751�00000277545�14737241513�017603� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_lua.h"
    #include "lua_apr.h"
    #include "lua_dbd.h"
    #include "lua_passwd.h"
    #include "scoreboard.h"
    #include "util_md5.h"
    #include "util_script.h"
    #include "util_varbuf.h"
    #include "apr_date.h"
    #include "apr_pools.h"
    #include "apr_thread_mutex.h"
    #include "apr_tables.h"
    #include "util_cookies.h"
    
    #define APR_WANT_BYTEFUNC
    #include "apr_want.h"
    
    extern apr_global_mutex_t* lua_ivm_mutex;
    extern apr_shm_t *lua_ivm_shm;
    
    APLOG_USE_MODULE(lua);
    #define POST_MAX_VARS 500
    
    #ifndef MODLUA_MAX_REG_MATCH
    #define MODLUA_MAX_REG_MATCH 25
    #endif
    
    typedef char *(*req_field_string_f) (request_rec * r);
    typedef int (*req_field_int_f) (request_rec * r);
    typedef req_table_t *(*req_field_apr_table_f) (request_rec * r);
    
    
    void ap_lua_rstack_dump(lua_State *L, request_rec *r, const char *msg)
    {
        int i;
        int top = lua_gettop(L);
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01484) "Lua Stack Dump: [%s]", msg);
        for (i = 1; i <= top; i++) {
            int t = lua_type(L, i);
            switch (t) {
            case LUA_TSTRING:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03001)
                                  "%d:  '%s'", i, lua_tostring(L, i));
                    break;
                }
            case LUA_TUSERDATA:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03002)
                                  "%d:  userdata", i);
                    break;
                }
            case LUA_TLIGHTUSERDATA:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03003)
                                  "%d:  lightuserdata", i);
                    break;
                }
            case LUA_TNIL:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03004)
                                  "%d:  NIL", i);
                    break;
                }
            case LUA_TNONE:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03005)
                                  "%d:  None", i);
                    break;
                }
            case LUA_TBOOLEAN:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03006)
                                  "%d:  %s", i,
                                  lua_toboolean(L, i) ? "true" : "false");
                    break;
                }
            case LUA_TNUMBER:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03007)
                                  "%d:  %g", i, lua_tonumber(L, i));
                    break;
                }
            case LUA_TTABLE:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03008)
                                  "%d:  <table>", i);
                    break;
                }
            case LUA_TFUNCTION:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03009)
                                  "%d:  <function>", i);
                    break;
                }
            default:{
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03010)
                                  "%d:  unknown: -[%s]-", i, lua_typename(L, i));
                    break;
                }
            }
        }
    }
    
    /**
     * Verify that the thing at index is a request_rec wrapping
     * userdata thingamajig and return it if it is. if it is not
     * lua will enter its error handling routine.
     */
    static request_rec *ap_lua_check_request_rec(lua_State *L, int index)
    {
        request_rec *r;
        luaL_checkudata(L, index, "Apache2.Request");
        r = (request_rec *) lua_unboxpointer(L, index);
        return r;
    }
    
    /* ------------------ request methods -------------------- */
    /* helper callback for req_parseargs */
    static int req_aprtable2luatable_cb(void *l, const char *key,
                                        const char *value)
    {
        int t;
        lua_State *L = (lua_State *) l;     /* [table<s,t>, table<s,s>] */
        /* rstack_dump(L, RRR, "start of cb"); */
        /* L is [table<s,t>, table<s,s>] */
        /* build complex */
    
        lua_getfield(L, -1, key);   /* [VALUE, table<s,t>, table<s,s>] */
        /* rstack_dump(L, RRR, "after getfield"); */
        t = lua_type(L, -1);
        switch (t) {
        case LUA_TNIL:
        case LUA_TNONE:{
                lua_pop(L, 1);      /* [table<s,t>, table<s,s>] */
                lua_newtable(L);    /* [array, table<s,t>, table<s,s>] */
                lua_pushnumber(L, 1);       /* [1, array, table<s,t>, table<s,s>] */
                lua_pushstring(L, value);   /* [string, 1, array, table<s,t>, table<s,s>] */
                lua_settable(L, -3);        /* [array, table<s,t>, table<s,s>]  */
                lua_setfield(L, -2, key);   /* [table<s,t>, table<s,s>] */
                break;
            }
        case LUA_TTABLE:{
                /* [array, table<s,t>, table<s,s>] */
                int size = lua_rawlen(L, -1);
                lua_pushnumber(L, size + 1);        /* [#, array, table<s,t>, table<s,s>] */
                lua_pushstring(L, value);   /* [string, #, array, table<s,t>, table<s,s>] */
                lua_settable(L, -3);        /* [array, table<s,t>, table<s,s>] */
                lua_setfield(L, -2, key);   /* [table<s,t>, table<s,s>] */
                break;
            }
        }
    
        /* L is [table<s,t>, table<s,s>] */
        /* build simple */
        lua_getfield(L, -2, key);   /* [VALUE, table<s,s>, table<s,t>] */
        if (lua_isnoneornil(L, -1)) {       /* only set if not already set */
            lua_pop(L, 1);          /* [table<s,s>, table<s,t>]] */
            lua_pushstring(L, value);       /* [string, table<s,s>, table<s,t>] */
            lua_setfield(L, -3, key);       /* [table<s,s>, table<s,t>]  */
        }
        else {
            lua_pop(L, 1);
        }
        return 1;
    }
    
    /* helper callback for req_parseargs */
    static int req_aprtable2luatable_cb_len(void *l, const char *key,
                                        const char *value, size_t len)
    {
        int t;
        lua_State *L = (lua_State *) l;     /* [table<s,t>, table<s,s>] */
        /* rstack_dump(L, RRR, "start of cb"); */
        /* L is [table<s,t>, table<s,s>] */
        /* build complex */
    
        lua_getfield(L, -1, key);   /* [VALUE, table<s,t>, table<s,s>] */
        /* rstack_dump(L, RRR, "after getfield"); */
        t = lua_type(L, -1);
        switch (t) {
        case LUA_TNIL:
        case LUA_TNONE:{
                lua_pop(L, 1);      /* [table<s,t>, table<s,s>] */
                lua_newtable(L);    /* [array, table<s,t>, table<s,s>] */
                lua_pushnumber(L, 1);       /* [1, array, table<s,t>, table<s,s>] */
                lua_pushlstring(L, value, len);   /* [string, 1, array, table<s,t>, table<s,s>] */
                lua_settable(L, -3);        /* [array, table<s,t>, table<s,s>]  */
                lua_setfield(L, -2, key);   /* [table<s,t>, table<s,s>] */
                break;
            }
        
        case LUA_TTABLE:{
                /* [array, table<s,t>, table<s,s>] */
                int size = lua_rawlen(L, -1);
                lua_pushnumber(L, size + 1);        /* [#, array, table<s,t>, table<s,s>] */
                lua_pushlstring(L, value, len);   /* [string, #, array, table<s,t>, table<s,s>] */
                lua_settable(L, -3);        /* [array, table<s,t>, table<s,s>] */
                lua_setfield(L, -2, key);   /* [table<s,t>, table<s,s>] */
                break;
            }
        }
    
        /* L is [table<s,t>, table<s,s>] */
        /* build simple */
        lua_getfield(L, -2, key);   /* [VALUE, table<s,s>, table<s,t>] */
        if (lua_isnoneornil(L, -1)) {       /* only set if not already set */
            lua_pop(L, 1);          /* [table<s,s>, table<s,t>]] */
            lua_pushlstring(L, value, len);       /* [string, table<s,s>, table<s,t>] */
            lua_setfield(L, -3, key);       /* [table<s,s>, table<s,t>]  */
        }
        else {
            lua_pop(L, 1);
        }
        return 1;
    }
    
    
    /*
     =======================================================================================================================
        lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size): Reads any additional form data sent in POST/PUT
        requests. Used for multipart POST data.
     =======================================================================================================================
     */
    static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size,
            apr_off_t maxsize)
    {
        int rc = OK;
    
        *rbuf = NULL;
        *size = 0;
    
        if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
            return (rc);
        }
        if (ap_should_client_block(r)) {
    
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            apr_off_t    len_read = -1;
            apr_off_t    rpos = 0;
            apr_off_t length = r->remaining;
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
            if (maxsize != 0 && length > maxsize) {
                return APR_EINCOMPLETE; /* Only room for incomplete data chunk :( */
            }
            *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length) + 1);
            while ((rpos < length)
                   && (len_read = ap_get_client_block(r, (char *) *rbuf + rpos,
                                                   length - rpos)) > 0) {
                rpos += len_read;
            }
            if (len_read < 0) {
                return APR_EINCOMPLETE;
            }
            *size = rpos;
        }
        else {
            rc = DONE;
        }
    
        return (rc);
    }
    
    
    /*
     * =======================================================================================================================
     * lua_write_body: Reads any additional form data sent in POST/PUT requests
     * and writes to a file.
     * =======================================================================================================================
     */
    static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t *size)
    {
        apr_status_t rc = OK;
    
        *size = 0;
    
        if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))
            return rc;
        if (ap_should_client_block(r)) {
            char argsbuffer[HUGE_STRING_LEN];
            apr_off_t rsize,
                      len_read,
                      rpos = 0;
            apr_off_t length = r->remaining;
    
            *size = length;
            while ((len_read =
                        ap_get_client_block(r, argsbuffer,
                                            sizeof(argsbuffer))) > 0) {
                if ((rpos + len_read) > length)
                    rsize = (apr_size_t) length - rpos;
                else
                    rsize = len_read;
    
                rc = apr_file_write_full(file, argsbuffer, (apr_size_t) rsize,
                                         NULL);
                if (rc != APR_SUCCESS)
                    return rc;
                rpos += rsize;
            }
        }
        else {
            rc = DONE;
        }
    
        return rc;
    }
    
    /* expose apr_table as (r/o) lua table */
    static int req_aprtable2luatable(lua_State *L, apr_table_t *t)
    {
        lua_newtable(L);
        lua_newtable(L);            /* [table, table] */
        apr_table_do(req_aprtable2luatable_cb, L, t, NULL);
        return 2;                   /* [table<string, string>, table<string, array<string>>] */
    }
    
    static int req_headers_in_table(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        return req_aprtable2luatable(L, r->headers_in);
    }
    static int req_headers_out_table(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        return req_aprtable2luatable(L, r->headers_out);
    }
    static int req_err_headers_out_table(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        return req_aprtable2luatable(L, r->err_headers_out);
    }
    static int req_notes_table(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        return req_aprtable2luatable(L, r->notes);
    }
    static int req_subprocess_env_table(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        return req_aprtable2luatable(L, r->subprocess_env);
    }
    /* r:parseargs() returning a lua table */
    static int req_parseargs(lua_State *L)
    {
        apr_table_t *form_table;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        lua_newtable(L);
        lua_newtable(L);            /* [table, table] */
        ap_args_to_table(r, &form_table);
        apr_table_do(req_aprtable2luatable_cb, L, form_table, NULL);
        return 2;                   /* [table<string, string>, table<string, array<string>>] */
    }
    
    /* ap_lua_binstrstr: Binary strstr function for uploaded data with NULL bytes */
    static char* ap_lua_binstrstr (const char * haystack, size_t hsize, const char* needle, size_t nsize)
    {
        size_t p;
        if (haystack == NULL) return NULL;
        if (needle == NULL) return NULL;
        if (hsize < nsize) return NULL;
        for (p = 0; p <= (hsize - nsize); ++p) {
            if (memcmp(haystack + p, needle, nsize) == 0) {
                return (char*) (haystack + p);
            }
        }
        return NULL;
    } 
    
    /* r:parsebody(): Parses regular (url-enocded) or multipart POST data and returns two tables*/
    static int req_parsebody(lua_State *L)
    {
        apr_array_header_t          *pairs;
        apr_off_t len;
        int res;
        apr_size_t size;
        apr_size_t max_post_size;
        char *multipart;
        const char *contentType;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        max_post_size = (apr_size_t) luaL_optinteger(L, 2, MAX_STRING_LEN);
        multipart = apr_pcalloc(r->pool, 256);
        contentType = apr_table_get(r->headers_in, "Content-Type");
        lua_newtable(L);
        lua_newtable(L);            /* [table, table] */    
        if (contentType != NULL && (sscanf(contentType, "multipart/form-data; boundary=%250c", multipart) == 1)) {
            char        *buffer, *key, *filename;
            char        *start = 0, *end = 0, *crlf = 0;
            const char  *data;
            int         i;
            size_t      vlen = 0;
            size_t      len = 0;
            if (lua_read_body(r, &data, (apr_off_t*) &size, max_post_size) != OK) {
                return 2;
            }
            len = strlen(multipart);
            i = 0;
            for
            (
                start = strstr((char *) data, multipart);
                start != NULL;
                start = end
            ) {
                i++;
                if (i == POST_MAX_VARS) break;
                crlf = strstr((char *) start, "\r\n\r\n");
                if (!crlf) break;
                end = ap_lua_binstrstr(crlf, (size - (crlf - data)), multipart, len);
                if (end == NULL) break;
                key = (char *) apr_pcalloc(r->pool, 256);
                filename = (char *) apr_pcalloc(r->pool, 256);
                if (end - crlf <= 8) break;
                vlen = end - crlf - 8;
                buffer = (char *) apr_pcalloc(r->pool, vlen+1);
                memcpy(buffer, crlf + 4, vlen);
                sscanf(start + len + 2,
                    "Content-Disposition: form-data; name=\"%255[^\"]\"; filename=\"%255[^\"]\"",
                    key, filename);
                if (*key) {
                    req_aprtable2luatable_cb_len(L, key, buffer, vlen);
                }
            }
        }
        else {
            char *buffer;
            res = ap_parse_form_data(r, NULL, &pairs, -1, max_post_size);
            if (res == OK) {
                while(pairs && !apr_is_empty_array(pairs)) {
                    ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
                    apr_brigade_length(pair->value, 1, &len);
                    size = (apr_size_t) len;
                    buffer = apr_palloc(r->pool, size + 1);
                    apr_brigade_flatten(pair->value, buffer, &size);
                    buffer[len] = 0;
                    req_aprtable2luatable_cb(L, pair->name, buffer);
                }
            }
        }
        return 2;                   /* [table<string, string>, table<string, array<string>>] */
    }
    
    
    /*
     * lua_ap_requestbody; r:requestbody([filename]) - Reads or stores the request
     * body
     */
    static int lua_ap_requestbody(lua_State *L)
    {
        const char     *filename;
        request_rec    *r;
        apr_off_t      maxSize;
        
        r = ap_lua_check_request_rec(L, 1);
        filename = luaL_optstring(L, 2, 0);
        maxSize = (apr_off_t)luaL_optinteger(L, 3, 0);
    
        if (r) {
            apr_off_t size;
            if (maxSize > 0 && r->remaining > maxSize) {
                lua_pushnil(L);
                lua_pushliteral(L, "Request body was larger than the permitted size.");
                return 2;
            }
            if (r->method_number != M_POST && r->method_number != M_PUT)
                return (0);
            if (!filename) {
                const char     *data;
    
                if (lua_read_body(r, &data, &size, maxSize) != OK)
                    return (0);
    
                lua_pushlstring(L, data, (size_t) size);
                lua_pushinteger(L, (lua_Integer) size);
                return (2);
            } else {
                apr_status_t rc;
                apr_file_t     *file;
    
                rc = apr_file_open(&file, filename, APR_CREATE | APR_FOPEN_WRITE,
                                   APR_FPROT_OS_DEFAULT, r->pool);
                lua_settop(L, 0);
                if (rc == APR_SUCCESS) {
                    rc = lua_write_body(r, file, &size);
                    apr_file_close(file);
                    if (rc != OK) {
                        lua_pushboolean(L, 0);
                        return 1;
                    }
                    lua_pushinteger(L, (lua_Integer) size);
                    return (1);
                } else
                    lua_pushboolean(L, 0);
                return (1);
            }
        }
    
        return (0);
    }
    
    /* wrap ap_rputs as r:puts(String) */
    static int req_puts(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
    
        int argc = lua_gettop(L);
        int i;
    
        for (i = 2; i <= argc; i++) {
            ap_rputs(luaL_checkstring(L, i), r);
        }
        return 0;
    }
    
    /* wrap ap_rwrite as r:write(String) */
    static int req_write(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        size_t n;
        int rv;
        const char *buf = luaL_checklstring(L, 2, &n);
    
        rv = ap_rwrite((void *) buf, n, r);
        lua_pushinteger(L, rv);
        return 1;
    }
    
    /* r:add_output_filter(name) */
    static int req_add_output_filter(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        const char *name = luaL_checkstring(L, 2);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01485) "adding output filter %s",
                      name);
        ap_add_output_filter(name, L, r, r->connection);
        return 0;
    }
    
    /* wrap ap_construct_url as r:construct_url(String) */
    static int req_construct_url(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        const char *name = luaL_checkstring(L, 2);
        lua_pushstring(L, ap_construct_url(r->pool, name, r));
        return 1;
    }
    
    /* wrap ap_escape_html r:escape_html(String) */
    static int req_escape_html(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        const char *s = luaL_checkstring(L, 2);
        lua_pushstring(L, ap_escape_html(r->pool, s));
        return 1;
    }
    
    /* wrap optional ssl_var_lookup as  r:ssl_var_lookup(String) */
    static int req_ssl_var_lookup(lua_State *L)
    {
        request_rec *r = ap_lua_check_request_rec(L, 1);
        const char *s = luaL_checkstring(L, 2);
        const char *res = ap_lua_ssl_val(r->pool, r->server, r->connection, r, 
                                         (char *)s);
        lua_pushstring(L, res);
        return 1;
    }
    
    /* BEGIN dispatch mathods for request_rec fields */
    
    /* not really a field, but we treat it like one */
    static const char *req_document_root(request_rec *r)
    {
        return ap_document_root(r);
    }
    
    static const char *req_context_prefix(request_rec *r)
    {
        return ap_context_prefix(r);
    }
    
    static const char *req_context_document_root(request_rec *r)
    {
        return ap_context_document_root(r);
    }
    
    static char *req_uri_field(request_rec *r)
    {
        return r->uri;
    }
    
    static const char *req_method_field(request_rec *r)
    {
        return r->method;
    }
    static const char *req_handler_field(request_rec *r)
    {
        return r->handler;
    }
    static const char *req_proxyreq_field(request_rec *r)
    {
        switch (r->proxyreq) {
            case PROXYREQ_NONE:     return "PROXYREQ_NONE";
            case PROXYREQ_PROXY:    return "PROXYREQ_PROXY";
            case PROXYREQ_REVERSE:  return "PROXYREQ_REVERSE";
            case PROXYREQ_RESPONSE: return "PROXYREQ_RESPONSE";
            default: return NULL;
        }
    }
    static const char *req_hostname_field(request_rec *r)
    {
        return r->hostname;
    }
    
    static const char *req_args_field(request_rec *r)
    {
        return r->args;
    }
    
    static const char *req_path_info_field(request_rec *r)
    {
        return r->path_info;
    }
    
    static const char *req_canonical_filename_field(request_rec *r)
    {
        return r->canonical_filename;
    }
    
    static const char *req_filename_field(request_rec *r)
    {
        return r->filename;
    }
    
    static const char *req_user_field(request_rec *r)
    {
        return r->user;
    }
    
    static const char *req_unparsed_uri_field(request_rec *r)
    {
        return r->unparsed_uri;
    }
    
    static const char *req_ap_auth_type_field(request_rec *r)
    {
        return r->ap_auth_type;
    }
    
    static const char *req_content_encoding_field(request_rec *r)
    {
        return r->content_encoding;
    }
    
    static const char *req_content_type_field(request_rec *r)
    {
        return r->content_type;
    }
    
    static const char *req_range_field(request_rec *r)
    {
        return r->range;
    }
    
    static const char *req_protocol_field(request_rec *r)
    {
        return r->protocol;
    }
    
    static const char *req_the_request_field(request_rec *r)
    {
        return r->the_request;
    }
    
    static const char *req_log_id_field(request_rec *r)
    {
        return r->log_id;
    }
    
    static const char *req_useragent_ip_field(request_rec *r)
    {
        return r->useragent_ip;
    }
    
    static int req_remaining_field(request_rec *r)
    {
        return r->remaining;
    }
    
    static int req_status_field(request_rec *r)
    {
        return r->status;
    }
    
    static int req_assbackwards_field(request_rec *r)
    {
        return r->assbackwards;
    }
    
    static req_table_t* req_headers_in(request_rec *r)
    {
      req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t));
      t->r = r;
      t->t = r->headers_in;
      t->n = "headers_in";
      return t;
    }
    
    static req_table_t* req_headers_out(request_rec *r)
    {
      req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t));
      t->r = r;
      t->t = r->headers_out;
      t->n = "headers_out";
      return t;
    }
    
    static req_table_t* req_err_headers_out(request_rec *r)
    {
      req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t));
      t->r = r;
      t->t = r->err_headers_out;
      t->n = "err_headers_out";
      return t;
    }
    
    static req_table_t* req_subprocess_env(request_rec *r)
    {
      req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t));
      t->r = r;
      t->t = r->subprocess_env;
      t->n = "subprocess_env";
      return t;
    }
    
    static req_table_t* req_notes(request_rec *r)
    {
      req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t));
      t->r = r;
      t->t = r->notes;
      t->n = "notes";
      return t;
    }
    
    static int req_ssl_is_https_field(request_rec *r)
    {
        return ap_lua_ssl_is_https(r->connection);
    }
    
    static int req_ap_get_server_port(request_rec *r)
    {
        return (int) ap_get_server_port(r);
    }
    
    static int lua_ap_rflush (lua_State *L) {
    
        int returnValue;
        request_rec *r;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        returnValue = ap_rflush(r);
        lua_pushboolean(L, (returnValue == 0));
        return 1;
    }
    
    
    static const char* lua_ap_options(request_rec* r) 
    {
        int opts;
        opts = ap_allow_options(r);
        return apr_psprintf(r->pool, "%s %s %s %s %s %s", (opts&OPT_INDEXES) ? "Indexes" : "", (opts&OPT_INCLUDES) ? "Includes" : "", (opts&OPT_SYM_LINKS) ? "FollowSymLinks" : "", (opts&OPT_EXECCGI) ? "ExecCGI" : "", (opts&OPT_MULTI) ? "MultiViews" : "", (opts&OPT_ALL) == OPT_ALL ? "All" : "" );
    }
    
    static const char* lua_ap_allowoverrides(request_rec* r) 
    {
        int opts;
        opts = ap_allow_overrides(r);
        if ( (opts & OR_ALL) == OR_ALL) {
            return "All";
        }
        else if (opts == OR_NONE) {
            return "None";
        }
        return apr_psprintf(r->pool, "%s %s %s %s %s", (opts & OR_LIMIT) ? "Limit" : "", (opts & OR_OPTIONS) ? "Options" : "", (opts & OR_FILEINFO) ? "FileInfo" : "", (opts & OR_AUTHCFG) ? "AuthCfg" : "", (opts & OR_INDEXES) ? "Indexes" : "" );
        
    }
    
    static int lua_ap_started(request_rec* r) 
    {
        return (int)(ap_scoreboard_image->global->restart_time / 1000000);
    }
    
    static const char* lua_ap_basic_auth_pw(request_rec* r) 
    {
        const char* pw = NULL;
        ap_get_basic_auth_pw(r, &pw);
        return pw ? pw : "";
    }
    
    static int lua_ap_limit_req_body(request_rec* r) 
    {
        return (int) ap_get_limit_req_body(r);
    }
    
    static int lua_ap_is_initial_req(request_rec *r)
    {
        return ap_is_initial_req(r);
    }
    
    static int lua_ap_some_auth_required(request_rec *r)
    {
        return ap_some_auth_required(r);
    }
    
    static int lua_ap_sendfile(lua_State *L)
    {
    
        apr_finfo_t file_info;
        const char  *filename;
        request_rec *r;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TSTRING);
        r = ap_lua_check_request_rec(L, 1);
        filename = lua_tostring(L, 2);
        apr_stat(&file_info, filename, APR_FINFO_MIN, r->pool);
        if (file_info.filetype == APR_NOFILE || file_info.filetype == APR_DIR) {
            lua_pushboolean(L, 0);
        }
        else {
            apr_size_t      sent;
            apr_status_t    rc;
            apr_file_t      *file;
    
            rc = apr_file_open(&file, filename, APR_READ, APR_OS_DEFAULT,
                                r->pool);
            if (rc == APR_SUCCESS) {
                ap_send_fd(file, r, 0, (apr_size_t)file_info.size, &sent);
                apr_file_close(file);
                lua_pushinteger(L, sent);
            }
            else {
                lua_pushboolean(L, 0);
            }
        }
    
        return (1);
    }
    
    
    /*
     * lua_apr_b64encode; r:encode_base64(string) - encodes a string to Base64
     * format
     */
    static int lua_apr_b64encode(lua_State *L)
    {
        const char     *plain;
        char           *encoded;
        size_t          plain_len, encoded_len;
        request_rec    *r;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        plain = lua_tolstring(L, 2, &plain_len);
        encoded_len = apr_base64_encode_len(plain_len);
        if (encoded_len) {
            encoded = apr_palloc(r->pool, encoded_len);
            encoded_len = apr_base64_encode(encoded, plain, plain_len);
            if (encoded_len > 0 && encoded[encoded_len - 1] == '\0')
                encoded_len--; 
            lua_pushlstring(L, encoded, encoded_len);
            return 1;
        }
        return 0;
    }
    
    /*
     * lua_apr_b64decode; r:decode_base64(string) - decodes a Base64 string
     */
    static int lua_apr_b64decode(lua_State *L)
    {
        const char     *encoded;
        char           *plain;
        size_t          encoded_len, decoded_len;
        request_rec    *r;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        encoded = lua_tolstring(L, 2, &encoded_len);
        decoded_len = apr_base64_decode_len(encoded);
        if (decoded_len) {
            plain = apr_palloc(r->pool, decoded_len);
            decoded_len = apr_base64_decode(plain, encoded);
            if (decoded_len > 0 && plain[decoded_len - 1] == '\0')
                decoded_len--; 
            lua_pushlstring(L, plain, decoded_len);
            return 1;
        }
        return 0;
    }
    
    /*
     * lua_ap_unescape; r:unescape(string) - Unescapes an URL-encoded string
     */
    static int lua_ap_unescape(lua_State *L)
    {
        const char     *escaped;
        char           *plain;
        size_t x,
               y;
        request_rec    *r;
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        escaped = lua_tolstring(L, 2, &x);
        plain = apr_pstrdup(r->pool, escaped);
        y = ap_unescape_urlencoded(plain);
        if (!y) {
            lua_pushstring(L, plain);
            return 1;
        }
        return 0;
    }
    
    /*
     * lua_ap_escape; r:escape(string) - URL-escapes a string
     */
    static int lua_ap_escape(lua_State *L)
    {
        const char     *plain;
        char           *escaped;
        size_t x;
        request_rec    *r;
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        plain = lua_tolstring(L, 2, &x);
        escaped = ap_escape_urlencoded(r->pool, plain);
        lua_pushstring(L, escaped);
        return 1;
    }
    
    /*
     * lua_apr_md5; r:md5(string) - Calculates an MD5 digest of a string
     */
    static int lua_apr_md5(lua_State *L)
    {
        const char     *buffer;
        char           *result;
        size_t len;
        request_rec    *r;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        buffer = lua_tolstring(L, 2, &len);
        result = ap_md5_binary(r->pool, (const unsigned char *)buffer, len);
        lua_pushstring(L, result);
        return 1;
    }
    
    /*
     * lua_apr_sha1; r:sha1(string) - Calculates the SHA1 digest of a string
     */
    static int lua_apr_sha1(lua_State *L)
    {
        unsigned char digest[APR_SHA1_DIGESTSIZE];
        apr_sha1_ctx_t sha1;
        const char     *buffer;
        char           *result;
        size_t len;
        request_rec    *r;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        result = apr_pcalloc(r->pool, sizeof(digest) * 2 + 1);
        buffer = lua_tolstring(L, 2, &len);
        apr_sha1_init(&sha1);
        apr_sha1_update(&sha1, buffer, len);
        apr_sha1_final(digest, &sha1);
        
        ap_bin2hex(digest, sizeof(digest), result);
        lua_pushstring(L, result);
        return 1;
    }
    
    /*
     * lua_apr_htpassword; r:htpassword(string [, algorithm [, cost]]) - Creates
     * a htpassword hash from a string
     */
    static int lua_apr_htpassword(lua_State *L)
    {
        passwd_ctx     ctx = { 0 };
        request_rec    *r;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        ctx.passwd = apr_pstrdup(r->pool, lua_tostring(L, 2));
        ctx.alg = luaL_optinteger(L, 3, ALG_APMD5);
        ctx.cost = luaL_optinteger(L, 4, 0);
        ctx.pool = r->pool;
        ctx.out = apr_pcalloc(r->pool, MAX_PASSWD_LEN);
        ctx.out_len = MAX_PASSWD_LEN;
        if (mk_password_hash(&ctx)) {
            lua_pushboolean(L, 0);
            lua_pushstring(L, ctx.errstr);
            return 2;
        } else {
            lua_pushstring(L, ctx.out);
        }
        return 1;
    }
    
    /*
     * lua_apr_touch; r:touch(string [, time]) - Sets mtime of a file
     */
    static int lua_apr_touch(lua_State *L)
    {
        request_rec     *r;
        const char      *path;
        apr_status_t    status;
        apr_time_t      mtime;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        path = lua_tostring(L, 2);
        mtime = (apr_time_t)luaL_optnumber(L, 3, (lua_Number)apr_time_now());
        status = apr_file_mtime_set(path, mtime, r->pool);
        lua_pushboolean(L, (status == 0));
        return 1;
    }
    
    /*
     * lua_apr_mkdir; r:mkdir(string [, permissions]) - Creates a directory
     */
    static int lua_apr_mkdir(lua_State *L)
    {
        request_rec     *r;
        const char      *path;
        apr_status_t    status;
        apr_fileperms_t perms;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        path = lua_tostring(L, 2);
        perms = luaL_optinteger(L, 3, APR_OS_DEFAULT);
        status = apr_dir_make(path, perms, r->pool);
        lua_pushboolean(L, (status == 0));
        return 1;
    }
    
    /*
     * lua_apr_mkrdir; r:mkrdir(string [, permissions]) - Creates directories
     * recursive
     */
    static int lua_apr_mkrdir(lua_State *L)
    {
        request_rec     *r;
        const char      *path;
        apr_status_t    status;
        apr_fileperms_t perms;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        path = lua_tostring(L, 2);
        perms = luaL_optinteger(L, 3, APR_OS_DEFAULT);
        status = apr_dir_make_recursive(path, perms, r->pool);
        lua_pushboolean(L, (status == 0));
        return 1;
    }
    
    /*
     * lua_apr_rmdir; r:rmdir(string) - Removes a directory
     */
    static int lua_apr_rmdir(lua_State *L)
    {
        request_rec     *r;
        const char      *path;
        apr_status_t    status;
    
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        path = lua_tostring(L, 2);
        status = apr_dir_remove(path, r->pool);
        lua_pushboolean(L, (status == 0));
        return 1;
    }
    
    /*
     * lua_apr_date_parse_rfc; r.date_parse_rfc(string) - Parses a DateTime string
     */
    static int lua_apr_date_parse_rfc(lua_State *L)
    {
        const char *input;
        apr_time_t result;
    
        luaL_checktype(L, 1, LUA_TSTRING);
        input = lua_tostring(L, 1);
        result = apr_date_parse_rfc(input);
        if (result == 0)
            return 0;
        lua_pushnumber(L, (lua_Number)(result / APR_USEC_PER_SEC));
        return 1;
    }
    
    /*
     * lua_ap_mpm_query; r:mpm_query(info) - Queries for MPM info
     */
    static int lua_ap_mpm_query(lua_State *L)
    {
        int x,
            y;
    
        x = lua_tointeger(L, 1);
        ap_mpm_query(x, &y);
        lua_pushinteger(L, y);
        return 1;
    }
    
    /*
     * lua_ap_expr; r:expr(string) - Evaluates an expr statement.
     */
    static int lua_ap_expr(lua_State *L)
    {
        request_rec    *r;
        int x = 0;
        const char     *expr,
        *err;
        ap_expr_info_t res;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TSTRING);
        r = ap_lua_check_request_rec(L, 1);
        expr = lua_tostring(L, 2);
    
    
        res.filename = NULL;
        res.flags = 0;
        res.line_number = 0;
        res.module_index = APLOG_MODULE_INDEX;
    
        err = ap_expr_parse(r->pool, r->pool, &res, expr, NULL);
        if (!err) {
            x = ap_expr_exec(r, &res, &err);
            lua_pushboolean(L, x);
            if (x < 0) {
                lua_pushstring(L, err);
                return 2;
            }
            return 1;
        } else {
            lua_pushboolean(L, 0);
            lua_pushstring(L, err);
            return 2;
        }
        lua_pushboolean(L, 0);
        return 1;
    }
    
    
    /*
     * lua_ap_regex; r:regex(string, pattern [, flags])
     * - Evaluates a regex and returns captures if matched
     */
    static int lua_ap_regex(lua_State *L)
    {
        request_rec    *r;
        int i,
            rv,
            flags;
        const char     *pattern,
        *source;
        char           *err;
        ap_regex_t regex;
        ap_regmatch_t matches[MODLUA_MAX_REG_MATCH+1];
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TSTRING);
        luaL_checktype(L, 3, LUA_TSTRING);
        r = ap_lua_check_request_rec(L, 1);
        source = lua_tostring(L, 2);
        pattern = lua_tostring(L, 3);
        flags = luaL_optinteger(L, 4, 0);
    
        rv = ap_regcomp(&regex, pattern, flags);
        if (rv) {
            lua_pushboolean(L, 0);
            err = apr_palloc(r->pool, 256);
            ap_regerror(rv, &regex, err, 256);
            lua_pushstring(L, err);
            return 2;
        }
    
        if (regex.re_nsub > MODLUA_MAX_REG_MATCH) {
            lua_pushboolean(L, 0);
            err = apr_palloc(r->pool, 64);
            apr_snprintf(err, 64,
                         "regcomp found %d matches; only %d allowed.",
                         regex.re_nsub, MODLUA_MAX_REG_MATCH);
            lua_pushstring(L, err);
            return 2;
        }
    
        rv = ap_regexec(&regex, source, MODLUA_MAX_REG_MATCH, matches, 0);
        if (rv == AP_REG_NOMATCH) {
            lua_pushboolean(L, 0);
            return 1;
        }
        
        lua_newtable(L);
        for (i = 0; i <= regex.re_nsub; i++) {
            lua_pushinteger(L, i);
            if (matches[i].rm_so >= 0 && matches[i].rm_eo >= 0)
                lua_pushstring(L,
                               apr_pstrndup(r->pool, source + matches[i].rm_so,
                                            matches[i].rm_eo - matches[i].rm_so));
            else
                lua_pushnil(L);
            lua_settable(L, -3);
    
        }
        return 1;
    }
    
    
    
    
    /*
     * lua_ap_scoreboard_process; r:scoreboard_process(a) - returns scoreboard info
     */
    static int lua_ap_scoreboard_process(lua_State *L)
    {
        int i;
        process_score  *ps_record;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TNUMBER);
        i = lua_tointeger(L, 2);
        ps_record = ap_get_scoreboard_process(i);
        if (ps_record) {
            lua_newtable(L);
    
            lua_pushstring(L, "connections");
            lua_pushnumber(L, ps_record->connections);
            lua_settable(L, -3);
    
            lua_pushstring(L, "keepalive");
            lua_pushnumber(L, ps_record->keep_alive);
            lua_settable(L, -3);
    
            lua_pushstring(L, "lingering_close");
            lua_pushnumber(L, ps_record->lingering_close);
            lua_settable(L, -3);
    
            lua_pushstring(L, "pid");
            lua_pushnumber(L, ps_record->pid);
            lua_settable(L, -3);
    
            lua_pushstring(L, "suspended");
            lua_pushnumber(L, ps_record->suspended);
            lua_settable(L, -3);
    
            lua_pushstring(L, "wait_io");
            lua_pushnumber(L, ps_record->wait_io);
            lua_settable(L, -3);
    
            lua_pushstring(L, "write_completion");
            lua_pushnumber(L, ps_record->write_completion);
            lua_settable(L, -3);
    
            lua_pushstring(L, "not_accepting");
            lua_pushnumber(L, ps_record->not_accepting);
            lua_settable(L, -3);
    
            lua_pushstring(L, "quiescing");
            lua_pushnumber(L, ps_record->quiescing);
            lua_settable(L, -3);
    
            return 1;
        }
        return 0;
    }
    
    /*
     * lua_ap_scoreboard_worker; r:scoreboard_worker(proc, thread) - Returns thread
     * info
     */
    static int lua_ap_scoreboard_worker(lua_State *L)
    {
        int i, j;
        worker_score *ws_record = NULL;
        request_rec *r = NULL;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TNUMBER);
        luaL_checktype(L, 3, LUA_TNUMBER);
    
        r = ap_lua_check_request_rec(L, 1);
        if (!r) return 0;
    
        i = lua_tointeger(L, 2);
        j = lua_tointeger(L, 3);
        ws_record = apr_palloc(r->pool, sizeof *ws_record);
    
        ap_copy_scoreboard_worker(ws_record, i, j);
        if (ws_record) {
            lua_newtable(L);
    
            lua_pushstring(L, "access_count");
            lua_pushnumber(L, ws_record->access_count);
            lua_settable(L, -3);
    
            lua_pushstring(L, "bytes_served");
            lua_pushnumber(L, (lua_Number) ws_record->bytes_served);
            lua_settable(L, -3);
    
            lua_pushstring(L, "client");
            lua_pushstring(L, ws_record->client);
            lua_settable(L, -3);
    
            lua_pushstring(L, "client64");
            lua_pushstring(L, ws_record->client64);
            lua_settable(L, -3);
    
            lua_pushstring(L, "conn_bytes");
            lua_pushnumber(L, (lua_Number) ws_record->conn_bytes);
            lua_settable(L, -3);
    
            lua_pushstring(L, "conn_count");
            lua_pushnumber(L, ws_record->conn_count);
            lua_settable(L, -3);
    
            lua_pushstring(L, "generation");
            lua_pushnumber(L, ws_record->generation);
            lua_settable(L, -3);
    
            lua_pushstring(L, "last_used");
            lua_pushnumber(L, (lua_Number) ws_record->last_used);
            lua_settable(L, -3);
    
            lua_pushstring(L, "pid");
            lua_pushnumber(L, ws_record->pid);
            lua_settable(L, -3);
    
            lua_pushstring(L, "request");
            lua_pushstring(L, ws_record->request);
            lua_settable(L, -3);
    
            lua_pushstring(L, "start_time");
            lua_pushnumber(L, (lua_Number) ws_record->start_time);
            lua_settable(L, -3);
    
            lua_pushstring(L, "status");
            lua_pushnumber(L, ws_record->status);
            lua_settable(L, -3);
    
            lua_pushstring(L, "stop_time");
            lua_pushnumber(L, (lua_Number) ws_record->stop_time);
            lua_settable(L, -3);
    
            lua_pushstring(L, "tid");
    
            lua_pushinteger(L, (lua_Integer) ws_record->tid);
            lua_settable(L, -3);
    
            lua_pushstring(L, "vhost");
            lua_pushstring(L, ws_record->vhost);
            lua_settable(L, -3);
    #ifdef HAVE_TIMES
            lua_pushstring(L, "stimes");
            lua_pushnumber(L, ws_record->times.tms_stime);
            lua_settable(L, -3);
    
            lua_pushstring(L, "utimes");
            lua_pushnumber(L, ws_record->times.tms_utime);
            lua_settable(L, -3);
    #endif
            return 1;
        }
        return 0;
    }
    
    /*
     * lua_ap_clock; r:clock() - Returns timestamp with microsecond precision
     */
    static int lua_ap_clock(lua_State *L)
    {
        apr_time_t now;
        now = apr_time_now();
        lua_pushnumber(L, (lua_Number) now);
        return 1;
    }
    
    /*
     * lua_ap_add_input_filter; r:add_input_filter(name) - Adds an input filter to
     * the chain
     */
    static int lua_ap_add_input_filter(lua_State *L)
    {
        request_rec    *r;
        const char     *filterName;
        ap_filter_rec_t *filter;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TSTRING);
        r = ap_lua_check_request_rec(L, 1);
        filterName = lua_tostring(L, 2);
        filter = ap_get_input_filter_handle(filterName);
        if (filter) {
            ap_add_input_filter_handle(filter, NULL, r, r->connection);
            lua_pushboolean(L, 1);
        } else
            lua_pushboolean(L, 0);
        return 1;
    }
    
    
    /*
     * lua_ap_module_info; r:module_info(mod_name) - Returns information about a
     * loaded module
     */
    static int lua_ap_module_info(lua_State *L)
    {
        const char     *moduleName;
        module         *mod;
    
        luaL_checktype(L, 1, LUA_TSTRING);
        moduleName = lua_tostring(L, 1);
        mod = ap_find_linked_module(moduleName);
        if (mod && mod->cmds) {
            const command_rec *cmd;
            lua_newtable(L);
            lua_pushstring(L, "commands");
            lua_newtable(L);
            for (cmd = mod->cmds; cmd->name; ++cmd) {
                lua_pushstring(L, cmd->name);
                lua_pushstring(L, cmd->errmsg);
                lua_settable(L, -3);
            }
            lua_settable(L, -3);
            return 1;
        }
        return 0;
    }
    
    /*
     * lua_ap_runtime_dir_relative: r:runtime_dir_relative(file): Returns the
     * filename as relative to the runtime dir
     */
    static int lua_ap_runtime_dir_relative(lua_State *L)
    {
        request_rec    *r;
        const char     *file;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        file = luaL_optstring(L, 2, ".");
        lua_pushstring(L, ap_runtime_dir_relative(r->pool, file));
        return 1;
    }
    
    /*
     * lua_ap_set_document_root; r:set_document_root(path) - sets the current doc
     * root for the request
     */
    static int lua_ap_set_document_root(lua_State *L)
    {
        request_rec    *r;
        const char     *root;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TSTRING);
        r = ap_lua_check_request_rec(L, 1);
        root = lua_tostring(L, 2);
        ap_set_document_root(r, root);
        return 0;
    }
    
    /*
     * lua_ap_getdir; r:get_direntries(directory) - Gets all entries of a
     * directory and returns the directory info as a table
     */
    static int lua_ap_getdir(lua_State *L)
    {
        request_rec    *r;
        apr_dir_t      *thedir;
        apr_finfo_t    file_info;
        apr_status_t   status;
        const char     *directory;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TSTRING);
        r = ap_lua_check_request_rec(L, 1);
        directory = lua_tostring(L, 2);
        if (apr_dir_open(&thedir, directory, r->pool) == APR_SUCCESS) {
            int i = 0;
            lua_newtable(L);
            do {
                status = apr_dir_read(&file_info, APR_FINFO_NAME, thedir);
                if (APR_STATUS_IS_INCOMPLETE(status)) {
                    continue; /* ignore un-stat()able files */
                }
                else if (status != APR_SUCCESS) {
                    break;
                }
                lua_pushinteger(L, ++i);
                lua_pushstring(L, file_info.name);
                lua_settable(L, -3);
    
            } while (1);
            apr_dir_close(thedir);
            return 1;
        }
        else {
            return 0;
        }
    }
    
    /*
     * lua_ap_stat; r:stat(filename [, wanted]) - Runs stat on a file and
     * returns the file info as a table
     */
    static int lua_ap_stat(lua_State *L)
    {
        request_rec    *r;
        const char     *filename;
        apr_finfo_t file_info;
        apr_int32_t wanted;
    
        luaL_checktype(L, 1, LUA_TUSERDATA);
        luaL_checktype(L, 2, LUA_TSTRING);
        r = ap_lua_check_request_rec(L, 1);
        filename = lua_tostring(L, 2);
        wanted = luaL_optinteger(L, 3, APR_FINFO_MIN);
        if (apr_stat(&file_info, filename, wanted, r->pool) == OK) {
            lua_newtable(L);
            if (wanted & APR_FINFO_MTIME) {
                lua_pushstring(L, "mtime");
                lua_pushnumber(L, (lua_Number) file_info.mtime);
                lua_settable(L, -3);
            }
            if (wanted & APR_FINFO_ATIME) {
                lua_pushstring(L, "atime");
                lua_pushnumber(L, (lua_Number) file_info.atime);
                lua_settable(L, -3);
            }
            if (wanted & APR_FINFO_CTIME) {
                lua_pushstring(L, "ctime");
                lua_pushnumber(L, (lua_Number) file_info.ctime);
                lua_settable(L, -3);
            }
            if (wanted & APR_FINFO_SIZE) {
                lua_pushstring(L, "size");
                lua_pushnumber(L, (lua_Number) file_info.size);
                lua_settable(L, -3);
            }
            if (wanted & APR_FINFO_TYPE) {
                lua_pushstring(L, "filetype");
                lua_pushinteger(L, file_info.filetype);
                lua_settable(L, -3);
            }
            if (wanted & APR_FINFO_PROT) {
                lua_pushstring(L, "protection");
                lua_pushinteger(L, file_info.protection);
                lua_settable(L, -3);
            }
            return 1;
        }
        else {
            return 0;
        }
    }
    
    /*
     * lua_ap_loaded_modules; r:loaded_modules() - Returns a list of loaded modules
     */
    static int lua_ap_loaded_modules(lua_State *L)
    {
        int i;
        lua_newtable(L);
        for (i = 0; ap_loaded_modules[i] && ap_loaded_modules[i]->name; i++) {
            lua_pushinteger(L, i + 1);
            lua_pushstring(L, ap_loaded_modules[i]->name);
            lua_settable(L, -3);
        }
        return 1;
    }
    
    /*
     * lua_ap_server_info; r:server_info() - Returns server info, such as the
     * executable filename, server root, mpm etc
     */
    static int lua_ap_server_info(lua_State *L)
    {
        lua_newtable(L);
    
        lua_pushstring(L, "server_executable");
        lua_pushstring(L, ap_server_argv0);
        lua_settable(L, -3);
    
        lua_pushstring(L, "server_root");
        lua_pushstring(L, ap_server_root);
        lua_settable(L, -3);
    
        lua_pushstring(L, "scoreboard_fname");
        lua_pushstring(L, ap_scoreboard_fname);
        lua_settable(L, -3);
    
        lua_pushstring(L, "server_mpm");
        lua_pushstring(L, ap_show_mpm());
        lua_settable(L, -3);
    
        return 1;
    }
    
    
    /*
     * === Auto-scraped functions ===
     */
    
    
    /**
     * ap_set_context_info: Set context_prefix and context_document_root.
     * @param r The request
     * @param prefix the URI prefix, without trailing slash
     * @param document_root the corresponding directory on disk, without trailing
     * slash
     * @note If one of prefix of document_root is NULL, the corrsponding
     * property will not be changed.
     */
    static int lua_ap_set_context_info(lua_State *L)
    {
        request_rec    *r;
        const char     *prefix;
        const char     *document_root;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        prefix = lua_tostring(L, 2);
        luaL_checktype(L, 3, LUA_TSTRING);
        document_root = lua_tostring(L, 3);
        ap_set_context_info(r, prefix, document_root);
        return 0;
    }
    
    
    /**
     * ap_os_escape_path (apr_pool_t *p, const char *path, int partial)
     * 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
     */
    static int lua_ap_os_escape_path(lua_State *L)
    {
        char           *returnValue;
        request_rec    *r;
        const char     *path;
        int partial = 0;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        path = lua_tostring(L, 2);
        if (lua_isboolean(L, 3))
            partial = lua_toboolean(L, 3);
        returnValue = ap_os_escape_path(r->pool, path, partial);
        lua_pushstring(L, returnValue);
        return 1;
    }
    
    
    /**
     * ap_escape_logitem (apr_pool_t *p, const char *str)
     * Escape a string for logging
     * @param p The pool to allocate from
     * @param str The string to escape
     * @return The escaped string
     */
    static int lua_ap_escape_logitem(lua_State *L)
    {
        char           *returnValue;
        request_rec    *r;
        const char     *str;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        str = lua_tostring(L, 2);
        returnValue = ap_escape_logitem(r->pool, str);
        lua_pushstring(L, returnValue);
        return 1;
    }
    
    /**
     * ap_strcmp_match (const char *str, const char *expected)
     * Determine if a string matches a pattern containing the wildcards '?' or '*'
     * @param str The string to check
     * @param expected The pattern to match against
     * @param ignoreCase Whether to ignore case when matching
     * @return 1 if the two strings match, 0 otherwise
     */
    static int lua_ap_strcmp_match(lua_State *L)
    {
        int returnValue;
        const char     *str;
        const char     *expected;
        int ignoreCase = 0;
        luaL_checktype(L, 1, LUA_TSTRING);
        str = lua_tostring(L, 1);
        luaL_checktype(L, 2, LUA_TSTRING);
        expected = lua_tostring(L, 2);
        if (lua_isboolean(L, 3))
            ignoreCase = lua_toboolean(L, 3);
        if (!ignoreCase)
            returnValue = ap_strcmp_match(str, expected);
        else
            returnValue = ap_strcasecmp_match(str, expected);
        lua_pushboolean(L, (!returnValue));
        return 1;
    }
    
    
    /**
     * ap_set_keepalive (request_rec *r)
     * Set the keepalive status for this request
     * @param r The current request
     * @return 1 if keepalive can be set, 0 otherwise
     */
    static int lua_ap_set_keepalive(lua_State *L)
    {
        int returnValue;
        request_rec    *r;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        returnValue = ap_set_keepalive(r);
        lua_pushboolean(L, returnValue);
        return 1;
    }
    
    /**
     * ap_make_etag (request_rec *r, int force_weak)
     * 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
     */
    static int lua_ap_make_etag(lua_State *L)
    {
        char           *returnValue;
        request_rec    *r;
        int force_weak;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TBOOLEAN);
        force_weak = (int)luaL_optinteger(L, 2, 0);
        returnValue = ap_make_etag(r, force_weak);
        lua_pushstring(L, returnValue);
        return 1;
    }
    
    
    
    /**
     * ap_send_interim_response (request_rec *r, int send_headers)
     * Send an interim (HTTP 1xx) response immediately.
     * @param r The request
     * @param send_headers Whether to send&clear headers in r->headers_out
     */
    static int lua_ap_send_interim_response(lua_State *L)
    {
        request_rec    *r;
        int send_headers = 0;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        if (lua_isboolean(L, 2))
            send_headers = lua_toboolean(L, 2);
        ap_send_interim_response(r, send_headers);
        return 0;
    }
    
    
    /**
     * ap_custom_response (request_rec *r, int status, const char *string)
     * 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
     */
    static int lua_ap_custom_response(lua_State *L)
    {
        request_rec    *r;
        int status;
        const char     *string;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        luaL_checktype(L, 2, LUA_TNUMBER);
        status = lua_tointeger(L, 2);
        luaL_checktype(L, 3, LUA_TSTRING);
        string = lua_tostring(L, 3);
        ap_custom_response(r, status, string);
        return 0;
    }
    
    
    /**
     * ap_exists_config_define (const char *name)
     * Check for a definition from the server command line
     * @param name The define to check for
     * @return 1 if defined, 0 otherwise
     */
    static int lua_ap_exists_config_define(lua_State *L)
    {
        int returnValue;
        const char     *name;
        luaL_checktype(L, 1, LUA_TSTRING);
        name = lua_tostring(L, 1);
        returnValue = ap_exists_config_define(name);
        lua_pushboolean(L, returnValue);
        return 1;
    }
    
    static int lua_ap_get_server_name_for_url(lua_State *L)
    {
        const char     *servername;
        request_rec    *r;
        luaL_checktype(L, 1, LUA_TUSERDATA);
        r = ap_lua_check_request_rec(L, 1);
        servername = ap_get_server_name_for_url(r);
        lua_pushstring(L, servername);
        return 1;
    }
    
    /* ap_state_query (int query_code) item starts a new field  */
    static int lua_ap_state_query(lua_State *L)
    {
    
        int returnValue;
        int query_code;
        luaL_checktype(L, 1, LUA_TNUMBER);
        query_code = lua_tointeger(L, 1);
        returnValue = ap_state_query(query_code);
        lua_pushinteger(L, returnValue);
        return 1;
    }
    
    /*
     * lua_ap_usleep; r:usleep(microseconds)
     * - Sleep for the specified number of microseconds.
     */
    static int lua_ap_usleep(lua_State *L)
    {
        apr_interval_time_t msec;
        luaL_checktype(L, 1, LUA_TNUMBER);
        msec = (apr_interval_time_t)lua_tonumber(L, 1);
        apr_sleep(msec);
        return 0;
    }
    
    /* END dispatch methods for request_rec fields */
    
    static int req_dispatch(lua_State *L)
    {
        apr_hash_t *dispatch;
        req_fun_t *rft;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        const char *name = luaL_checkstring(L, 2);
        lua_pop(L, 2);
    
        lua_getfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch");
        dispatch = lua_touserdata(L, 1);
        lua_pop(L, 1);
    
        rft = apr_hash_get(dispatch, name, APR_HASH_KEY_STRING);
        if (rft) {
            switch (rft->type) {
            case APL_REQ_FUNTYPE_TABLE:{
                    req_table_t *rs;
                    req_field_apr_table_f func = (req_field_apr_table_f)rft->fun;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01486)
                                  "request_rec->dispatching %s -> apr table",
                                  name);
                    rs = (*func)(r);
                    ap_lua_push_apr_table(L, rs);
                    return 1;
                }
    
            case APL_REQ_FUNTYPE_LUACFUN:{
                    lua_CFunction func = (lua_CFunction)rft->fun;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01487)
                                  "request_rec->dispatching %s -> lua_CFunction",
                                  name);
                    lua_pushcfunction(L, func);
                    return 1;
                }
            case APL_REQ_FUNTYPE_STRING:{
                    req_field_string_f func = (req_field_string_f)rft->fun;
                    char *rs;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01488)
                                  "request_rec->dispatching %s -> string", name);
                    rs = (*func) (r);
                    lua_pushstring(L, rs);
                    return 1;
                }
            case APL_REQ_FUNTYPE_INT:{
                    req_field_int_f func = (req_field_int_f)rft->fun;
                    int rs;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01489)
                                  "request_rec->dispatching %s -> int", name);
                    rs = (*func) (r);
                    lua_pushinteger(L, rs);
                    return 1;
                }
            case APL_REQ_FUNTYPE_BOOLEAN:{
                    req_field_int_f func = (req_field_int_f)rft->fun;
                    int rs;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01490)
                                  "request_rec->dispatching %s -> boolean", name);
                    rs = (*func) (r);
                    lua_pushboolean(L, rs);
                    return 1;
                }
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01491) "nothing for %s", name);
        return 0;
    }
    
    /* helper function for the logging functions below */
    static int req_log_at(lua_State *L, int level)
    {
        const char *msg;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        lua_Debug dbg;
    
        lua_getstack(L, 1, &dbg);
        lua_getinfo(L, "Sl", &dbg);
    
        msg = luaL_checkstring(L, 2);
        /* Intentional no APLOGNO */
        ap_log_rerror(dbg.source, dbg.currentline, APLOG_MODULE_INDEX, level, 0,
                      r, "%s", msg);
        return 0;
    }
    
    /* r:debug(String) and friends which use apache logging */
    static int req_emerg(lua_State *L)
    {
        return req_log_at(L, APLOG_EMERG);
    }
    static int req_alert(lua_State *L)
    {
        return req_log_at(L, APLOG_ALERT);
    }
    static int req_crit(lua_State *L)
    {
        return req_log_at(L, APLOG_CRIT);
    }
    static int req_err(lua_State *L)
    {
        return req_log_at(L, APLOG_ERR);
    }
    static int req_warn(lua_State *L)
    {
        return req_log_at(L, APLOG_WARNING);
    }
    static int req_notice(lua_State *L)
    {
        return req_log_at(L, APLOG_NOTICE);
    }
    static int req_info(lua_State *L)
    {
        return req_log_at(L, APLOG_INFO);
    }
    static int req_debug(lua_State *L)
    {
        return req_log_at(L, APLOG_DEBUG);
    }
    
    static int lua_ivm_get(lua_State *L) 
    {
        const char *key, *raw_key;
        apr_pool_t *pool;
        lua_ivm_object *object = NULL;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        key = luaL_checkstring(L, 2);
        raw_key = apr_pstrcat(r->pool, "lua_ivm_", key, NULL);
        apr_global_mutex_lock(lua_ivm_mutex);
        pool = *((apr_pool_t**) apr_shm_baseaddr_get(lua_ivm_shm));
        apr_pool_userdata_get((void **)&object, raw_key, pool);
        if (object) {
            if (object->type == LUA_TBOOLEAN) lua_pushboolean(L, (int) object->number);
            else if (object->type == LUA_TNUMBER) lua_pushnumber(L, object->number);
            else if (object->type == LUA_TSTRING) lua_pushlstring(L, object->vb.buf, object->size);
            apr_global_mutex_unlock(lua_ivm_mutex);
            return 1;
        }
        else {
            apr_global_mutex_unlock(lua_ivm_mutex);
            return 0;
        }
    }
    
    
    static int lua_ivm_set(lua_State *L) 
    {
        const char *key, *raw_key;
        const char *value = NULL;
        apr_pool_t *pool;
        size_t str_len;
        lua_ivm_object *object = NULL;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        key = luaL_checkstring(L, 2);
        luaL_checkany(L, 3);
        raw_key = apr_pstrcat(r->pool, "lua_ivm_", key, NULL);
        
        apr_global_mutex_lock(lua_ivm_mutex);
        pool = *((apr_pool_t**) apr_shm_baseaddr_get(lua_ivm_shm));
        apr_pool_userdata_get((void **)&object, raw_key, pool);
        if (!object) {
            object = apr_pcalloc(pool, sizeof(lua_ivm_object));
            ap_varbuf_init(pool, &object->vb, 2);
            object->size = 1;
            object->vb_size = 1;
        }
        object->type = lua_type(L, 3);
        if (object->type == LUA_TNUMBER) object->number = lua_tonumber(L, 3);
        else if (object->type == LUA_TBOOLEAN) object->number = lua_tonumber(L, 3);
        else if (object->type == LUA_TSTRING) {
            value = lua_tolstring(L, 3, &str_len);
            str_len++; /* add trailing \0 */
            if ( str_len > object->vb_size) {
                ap_varbuf_grow(&object->vb, str_len);
                object->vb_size = str_len;
            }
            object->size = str_len-1;
            memset(object->vb.buf, 0, str_len);
            memcpy(object->vb.buf, value, str_len-1);
        }
        apr_pool_userdata_set(object, raw_key, NULL, pool);
        apr_global_mutex_unlock(lua_ivm_mutex);
        return 0;
    }
    
    static int lua_get_cookie(lua_State *L) 
    {
        const char *key, *cookie;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        key = luaL_checkstring(L, 2);
        cookie = NULL;
        ap_cookie_read(r, key, &cookie, 0);
        if (cookie != NULL) {
            lua_pushstring(L, cookie);
            return 1;
        }
        return 0;
    }
    
    static int lua_set_cookie(lua_State *L) 
    {
        const char *key, *value, *out, *path = "", *domain = "";
        const char *strexpires = "", *strdomain = "", *strpath = "";
        int secure = 0, expires = 0, httponly = 0;
        char cdate[APR_RFC822_DATE_LEN+1];
        apr_status_t rv;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        
        /* New >= 2.4.8 method: */
        if (lua_istable(L, 2)) {
             
            /* key */
            lua_pushstring(L, "key");
            lua_gettable(L, -2);
            key = luaL_checkstring(L, -1);
            lua_pop(L, 1);
            
            /* value */
            lua_pushstring(L, "value");
            lua_gettable(L, -2);
            value = luaL_checkstring(L, -1);
            lua_pop(L, 1);
            
            /* expiry */
            lua_pushstring(L, "expires");
            lua_gettable(L, -2);
            expires = (int)luaL_optinteger(L, -1, 0);
            lua_pop(L, 1);
            
            /* secure */
            lua_pushstring(L, "secure");
            lua_gettable(L, -2);
            if (lua_isboolean(L, -1)) {
                secure = lua_toboolean(L, -1);
            }
            lua_pop(L, 1);
            
            /* httponly */
            lua_pushstring(L, "httponly");
            lua_gettable(L, -2);
            if (lua_isboolean(L, -1)) {
                httponly = lua_toboolean(L, -1);
            }
            lua_pop(L, 1);
            
            /* path */
            lua_pushstring(L, "path");
            lua_gettable(L, -2);
            path = luaL_optstring(L, -1, "/");
            lua_pop(L, 1);
            
            /* domain */
            lua_pushstring(L, "domain");
            lua_gettable(L, -2);
            domain = luaL_optstring(L, -1, "");
            lua_pop(L, 1);        
        }
        /* Old <= 2.4.7 method: */
        else {
            key = luaL_checkstring(L, 2);
            value = luaL_checkstring(L, 3);
            secure = 0;
            if (lua_isboolean(L, 4)) {
                secure = lua_toboolean(L, 4);
            }
            expires = luaL_optinteger(L, 5, 0);
        }
        
        /* Calculate expiry if set */
        if (expires > 0) {
            rv = apr_rfc822_date(cdate, apr_time_from_sec(expires));
            if (rv == APR_SUCCESS) {
                strexpires = apr_psprintf(r->pool, "Expires=%s;", cdate);
            }
        }
        
        /* Create path segment */
        if (path != NULL && strlen(path) > 0) {
            strpath = apr_psprintf(r->pool, "Path=%s;", path);
        }
        
        /* Create domain segment */
        if (domain != NULL && strlen(domain) > 0) {
            /* Domain does NOT like quotes in most browsers, so let's avoid that */
            strdomain = apr_psprintf(r->pool, "Domain=%s;", domain);
        }
        
        /* URL-encode key/value */
        value = ap_escape_urlencoded(r->pool, value);
        key = ap_escape_urlencoded(r->pool, key);
        
        /* Create the header */
        out = apr_psprintf(r->pool, "%s=%s; %s %s %s %s %s", key, value, 
                secure ? "Secure;" : "", 
                expires ? strexpires : "", 
                httponly ? "HttpOnly;" : "", 
                *strdomain ? strdomain : "", 
                *strpath ? strpath : "");
        
        apr_table_add(r->err_headers_out, "Set-Cookie", out);
        return 0;
    }
    
    static apr_uint64_t ap_ntoh64(const apr_uint64_t *input)
    {
        apr_uint64_t rval;
        unsigned char *data = (unsigned char *)&rval;
        if (APR_IS_BIGENDIAN) {
            return *input;
        }
        
        data[0] = *input >> 56;
        data[1] = *input >> 48;
        data[2] = *input >> 40;
        data[3] = *input >> 32;
        data[4] = *input >> 24;
        data[5] = *input >> 16;
        data[6] = *input >> 8;
        data[7] = *input >> 0;
    
        return rval;
    }
    
    static int lua_websocket_greet(lua_State *L)
    {
        const char *key = NULL;
        unsigned char digest[APR_SHA1_DIGESTSIZE];
        apr_sha1_ctx_t sha1;
        char           *encoded;
        int encoded_len;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        key = apr_table_get(r->headers_in, "Sec-WebSocket-Key");
        if (key != NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03011) 
                          "Websocket: Got websocket key: %s", key);
            key = apr_pstrcat(r->pool, key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", 
                    NULL);
            apr_sha1_init(&sha1);
            apr_sha1_update(&sha1, key, strlen(key));
            apr_sha1_final(digest, &sha1);
            encoded_len = apr_base64_encode_len(APR_SHA1_DIGESTSIZE);
            if (encoded_len) {
                encoded = apr_palloc(r->pool, encoded_len);
                encoded_len = apr_base64_encode(encoded, (char*) digest, APR_SHA1_DIGESTSIZE);
                r->status = 101;
                apr_table_setn(r->headers_out, "Upgrade", "websocket");
                apr_table_setn(r->headers_out, "Connection", "Upgrade");
                apr_table_setn(r->headers_out, "Sec-WebSocket-Accept", encoded);
                
                /* Trick httpd into NOT using the chunked filter, IMPORTANT!!!111*/
                apr_table_setn(r->headers_out, "Transfer-Encoding", "chunked");
                
                r->clength = 0;
                r->bytes_sent = 0;
                r->read_chunked = 0;
                ap_rflush(r);
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03012) 
                              "Websocket: Upgraded from HTTP to Websocket");
                lua_pushboolean(L, 1);
                return 1;
            }
        }
        ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02666)
                      "Websocket: Upgrade from HTTP to Websocket failed");
        return 0;
    }
    
    static apr_status_t lua_websocket_readbytes(conn_rec* c,
                                                apr_bucket_brigade *brigade,
                                                char* buffer, apr_off_t len)
    {
        apr_size_t delivered;
        apr_status_t rv;
    
        rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES, 
                APR_BLOCK_READ, len);
        if (rv == APR_SUCCESS) {
            delivered = len;
            rv = apr_brigade_flatten(brigade, buffer, &delivered);
            if ((rv == APR_SUCCESS) && (delivered < len)) {
                rv = APR_INCOMPLETE;
            }
        }
        apr_brigade_cleanup(brigade);
        return rv;
    }
    
    static int lua_websocket_peek(lua_State *L) 
    {
        apr_status_t rv;
        apr_bucket_brigade *brigade;
        
        request_rec *r = ap_lua_check_request_rec(L, 1);
        
        brigade = apr_brigade_create(r->connection->pool, 
                r->connection->bucket_alloc);
        rv = ap_get_brigade(r->connection->input_filters, brigade, 
                AP_MODE_READBYTES, APR_NONBLOCK_READ, 1);
        if (rv == APR_SUCCESS) {
            lua_pushboolean(L, 1);
        }
        else {
            lua_pushboolean(L, 0);
        }
        apr_brigade_cleanup(brigade);
        return 1;
    }
    
    static int lua_websocket_read(lua_State *L) 
    {
        apr_status_t rv;
        int do_read = 1;
        int n = 0;
        apr_size_t plen = 0;
        unsigned short payload_short = 0;
        apr_uint64_t payload_long = 0;
        unsigned char *mask_bytes;
        char byte;
        apr_bucket_brigade *brigade;
        conn_rec* c;
    
        request_rec *r = ap_lua_check_request_rec(L, 1);
        c = r->connection;
    
        mask_bytes = apr_pcalloc(r->pool, 4);
    
        brigade = apr_brigade_create(r->pool, c->bucket_alloc);
    
        while (do_read) {
            do_read = 0;
            /* Get opcode and FIN bit */
            rv = lua_websocket_readbytes(c, brigade, &byte, 1);
            if (rv == APR_SUCCESS) {
                unsigned char ubyte, fin, opcode, mask, payload;
                ubyte = (unsigned char)byte;
                /* fin bit is the first bit */
                fin = ubyte >> (CHAR_BIT - 1);
                /* opcode is the last four bits (there's 3 reserved bits we don't care about) */
                opcode = ubyte & 0xf;
    
                /* Get the payload length and mask bit */
                rv = lua_websocket_readbytes(c, brigade, &byte, 1);
                if (rv == APR_SUCCESS) {
                    ubyte = (unsigned char)byte;
                    /* Mask is the first bit */
                    mask = ubyte >> (CHAR_BIT - 1);
                    /* Payload is the last 7 bits */
                    payload = ubyte & 0x7f;
                    plen = payload;
    
                    /* Extended payload? */
                    if (payload == 126) {
                        rv = lua_websocket_readbytes(c, brigade,
                                                     (char*) &payload_short, 2);
    
                        if (rv != APR_SUCCESS) {
                            return 0;
                        }
    
                        plen = ntohs(payload_short);
                    }
                    /* Super duper extended payload? */
                    if (payload == 127) {
                        rv = lua_websocket_readbytes(c, brigade,
                                                     (char*) &payload_long, 8);
    
                        if (rv != APR_SUCCESS) {
                            return 0;
                        }
    
                        plen = ap_ntoh64(&payload_long);
                    }
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210)
                                  "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s", 
                                  plen,
                                  (payload >= 126) ? "extra payload" : "no extra payload", 
                                  mask ? "on" : "off", 
                                  fin ? "This is a final frame" : "more to follow");
                    if (mask) {
                        rv = lua_websocket_readbytes(c, brigade,
                                                     (char*) mask_bytes, 4);
    
                        if (rv != APR_SUCCESS) {
                            return 0;
                        }
                    }
                    if (plen < (HUGE_STRING_LEN*1024) && plen > 0) {
                        apr_size_t remaining = plen;
                        char *buffer = apr_palloc(r->pool, plen+1);
                        buffer[plen] = 0;
    
                        rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
    
                        if (rv != APR_SUCCESS) {
                            return 0;
                        }
    
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                      "Websocket: Frame contained %" APR_SIZE_T_FMT \
                                      " bytes, pushed to Lua stack", remaining);
                        if (mask) {
                            for (n = 0; n < plen; n++) {
                                buffer[n] ^= mask_bytes[n%4];
                            }
                        }
    
                        lua_pushlstring(L, buffer, (size_t) plen); /* push to stack */
                        lua_pushboolean(L, fin); /* push FIN bit to stack as boolean */
                        return 2;
                    }
    
                    /* Decide if we need to react to the opcode or not */
                    if (opcode == 0x09) { /* ping */
                        char frame[2];
                        apr_bucket *b;
    
                        frame[0] = 0x8A;
                        frame[1] = 0;
    
                        /* Pong! */
                        b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
                        APR_BRIGADE_INSERT_TAIL(brigade, b);
    
                        rv = ap_pass_brigade(c->output_filters, brigade);
                        apr_brigade_cleanup(brigade);
    
                        if (rv != APR_SUCCESS) {
                            return 0;
                        }
    
                        do_read = 1;
                    }
                }
            }
        }
        return 0;
    }
    
    
    static int lua_websocket_write(lua_State *L) 
    {
        const char *string;
        apr_status_t rv;
        size_t len;
        int raw = 0;
        char prelude;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        
        if (lua_isboolean(L, 3)) {
            raw = lua_toboolean(L, 3);
        }
        string = lua_tolstring(L, 2, &len);
        
        if (raw != 1) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03013) 
                          "Websocket: Writing framed message to client");
            
            prelude = 0x81; /* text frame, FIN */
            ap_rputc(prelude, r);
            if (len < 126) {
                ap_rputc(len, r);
            } 
            else if (len < 65535) {
                apr_uint16_t slen = len;
                ap_rputc(126, r); 
                slen = htons(slen);
                ap_rwrite((char*) &slen, 2, r);
            }
            else {
                apr_uint64_t llen = len;
                ap_rputc(127, r);
                llen = ap_ntoh64(&llen); /* ntoh doubles as hton */
                ap_rwrite((char*) &llen, 8, r);
            }
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03014) 
                          "Websocket: Writing raw message to client");
        }
        ap_rwrite(string, len, r);
        rv = ap_rflush(r);
        if (rv == APR_SUCCESS) {
            lua_pushboolean(L, 1);
        }
        else {
            lua_pushboolean(L, 0);
        }
        return 1;
    }
    
    
    static int lua_websocket_close(lua_State *L) 
    {
        apr_socket_t *sock;
        char prelude[2];
        request_rec *r = ap_lua_check_request_rec(L, 1);
        
        sock = ap_get_conn_socket(r->connection);
        
        /* Send a header that says: socket is closing. */
        prelude[0] = 0x88; /* closing socket opcode */
        prelude[1] = 0; /* zero length frame */
        ap_rwrite(prelude, 2, r);
        
        /* Close up tell the MPM and filters to back off */
        apr_socket_close(sock);
        r->output_filters = NULL;
        r->connection->keepalive = AP_CONN_CLOSE;
        return 0;
    }
    
    static int lua_websocket_ping(lua_State *L) 
    {
        apr_socket_t *sock;
        apr_size_t plen;
        char prelude[2];
        apr_status_t rv;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        sock = ap_get_conn_socket(r->connection);
        
        /* Send a header that says: PING. */
        prelude[0] = 0x89; /* ping  opcode */
        prelude[1] = 0;
        plen = 2;
        apr_socket_send(sock, prelude, &plen);
        
        
        /* Get opcode and FIN bit from pong */
        plen = 2;
        rv = apr_socket_recv(sock, prelude, &plen);
        if (rv == APR_SUCCESS) {
            unsigned char opcode = prelude[0];
            unsigned char len = prelude[1];
            unsigned char mask = len >> 7;
            if (mask) len -= 128;
            plen = len;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03015) 
                          "Websocket: Got PONG opcode: %x", opcode);
            if (opcode == 0x8A) {
                lua_pushboolean(L, 1);
            }
            else {
                lua_pushboolean(L, 0);
            }
            if (plen > 0) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, 
                              "Websocket: Reading %" APR_SIZE_T_FMT " bytes of PONG", plen);
                return 1;
            }
            if (mask) {
                plen = 2;
                apr_socket_recv(sock, prelude, &plen);
                plen = 2;
                apr_socket_recv(sock, prelude, &plen);
            }
        }
        else {
            lua_pushboolean(L, 0);
        }
        return 1;
    }
    
    
    #define APLUA_REQ_TRACE(lev) static int req_trace##lev(lua_State *L)  \
    {                                                               \
        return req_log_at(L, APLOG_TRACE##lev);                     \
    }
    
    APLUA_REQ_TRACE(1)
    APLUA_REQ_TRACE(2)
    APLUA_REQ_TRACE(3)
    APLUA_REQ_TRACE(4)
    APLUA_REQ_TRACE(5)
    APLUA_REQ_TRACE(6)
    APLUA_REQ_TRACE(7)
    APLUA_REQ_TRACE(8)
    
    /* handle r.status = 201 */
    static int req_newindex(lua_State *L)
    {
        const char *key;
        /* request_rec* r = lua_touserdata(L, lua_upvalueindex(1)); */
        /* const char* key = luaL_checkstring(L, -2); */
        request_rec *r = ap_lua_check_request_rec(L, 1);
        key = luaL_checkstring(L, 2);
    
        if (0 == strcmp("ap_auth_type", key)) {
            const char *value = luaL_checkstring(L, 3);
            r->ap_auth_type = apr_pstrdup(r->pool, value);
            return 0;
        }
    
        if (0 == strcmp("args", key)) {
            const char *value = luaL_checkstring(L, 3);
            r->args = apr_pstrdup(r->pool, value);
            return 0;
        }
    
        if (0 == strcmp("content_type", key)) {
            const char *value = luaL_checkstring(L, 3);
            ap_set_content_type(r, apr_pstrdup(r->pool, value));
            return 0;
        }
    
        if (0 == strcmp("filename", key)) {
            const char *value = luaL_checkstring(L, 3);
            r->filename = apr_pstrdup(r->pool, value);
            return 0;
        }
    
        if (0 == strcmp("handler", key)) {
            const char *value = luaL_checkstring(L, 3);
            r->handler = apr_pstrdup(r->pool, value);
            return 0;
        }
    
        if (0 == strcmp("proxyreq", key)) {
            int value = luaL_checkinteger(L, 3);
            r->proxyreq = value;
            return 0;
        }
    
        if (0 == strcmp("status", key)) {
            int code = luaL_checkinteger(L, 3);
            r->status = code;
            return 0;
        }
    
        if (0 == strcmp("uri", key)) {
            const char *value = luaL_checkstring(L, 3);
            r->uri = apr_pstrdup(r->pool, value);
            return 0;
        }
    
        if (0 == strcmp("user", key)) {
            const char *value = luaL_checkstring(L, 3);
            r->user = apr_pstrdup(r->pool, value);
            return 0;
        }
    
        lua_pushstring(L,
                       apr_psprintf(r->pool,
                                    "Property [%s] may not be set on a request_rec",
                                    key));
        lua_error(L);
        return 0;
    }
    
    
    
    /* helper function for walking config trees */
    static void read_cfg_tree(lua_State *L, request_rec *r, ap_directive_t *rcfg) {
        int x = 0;
        const char* value;
        ap_directive_t *cfg;
        lua_newtable(L);
        
        for (cfg = rcfg; cfg; cfg = cfg->next) {
            x++;
            lua_pushnumber(L, x);
            lua_newtable(L);
            value = apr_psprintf(r->pool, "%s %s", cfg->directive, cfg->args);
            lua_pushstring(L, "directive");
            lua_pushstring(L, value);
            lua_settable(L, -3);
            lua_pushstring(L, "file");
            lua_pushstring(L, cfg->filename);
            lua_settable(L, -3);
            lua_pushstring(L, "line");
            lua_pushnumber(L, cfg->line_num);
            lua_settable(L, -3);
            if (cfg->first_child) {
                lua_pushstring(L, "children");
                read_cfg_tree(L, r, cfg->first_child);
                lua_settable(L, -3);
            }
            lua_settable(L, -3);
        }
    }
    
    static int lua_ap_get_config(lua_State *L) {
        request_rec *r = ap_lua_check_request_rec(L, 1);   
        read_cfg_tree(L, r, ap_conftree);
        
        return 1;
    }
    
    
    /* Hack, hack, hack...! TODO: Make this actually work properly */
    static int lua_ap_get_active_config(lua_State *L) {
        ap_directive_t *subdir;
        ap_directive_t *dir = ap_conftree;
        request_rec *r = ap_lua_check_request_rec(L, 1);
        
        for (dir = ap_conftree; dir; dir = dir->next) {
            if (ap_strcasestr(dir->directive, "<virtualhost") && dir->first_child) {
                for (subdir = dir->first_child; subdir; subdir = subdir->next) {
                    if (ap_strcasecmp_match(subdir->directive, "servername") &&
                            !ap_strcasecmp_match(r->hostname, subdir->args)) {
                        read_cfg_tree(L, r, dir->first_child);
                        return 1;
                    }
                    if (ap_strcasecmp_match(subdir->directive, "serveralias") &&
                            !ap_strcasecmp_match(r->hostname, subdir->args)) {
                        read_cfg_tree(L, r, dir->first_child);
                        return 1;
                    }
                }
            }
        }     
        return 0;
    }
    
    
    
    static const struct luaL_Reg request_methods[] = {
        {"__index", req_dispatch},
        {"__newindex", req_newindex},
        /*   {"__newindex", req_set_field}, */
        {NULL, NULL}
    };
    
    
    static const struct luaL_Reg connection_methods[] = {
        {NULL, NULL}
    };
    
    static const char* lua_ap_auth_name(request_rec* r)
    {
        const char *name;
        name = ap_auth_name(r);
        return name ? name : "";
    }
    
    static const char* lua_ap_get_server_name(request_rec* r)
    {
        const char *name;
        name = ap_get_server_name(r);
        return name ? name : "localhost";
    }
    
    
    
    
    static const struct luaL_Reg server_methods[] = {
        {NULL, NULL}
    };
    
    
    static req_fun_t *makefun(const void *fun, int type, apr_pool_t *pool)
    {
        req_fun_t *rft = apr_palloc(pool, sizeof(req_fun_t));
        rft->fun = fun;
        rft->type = type;
        return rft;
    }
    
    void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
    {
    
        apr_hash_t *dispatch = apr_hash_make(p);
    
        apr_hash_set(dispatch, "puts", APR_HASH_KEY_STRING,
                     makefun(&req_puts, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "write", APR_HASH_KEY_STRING,
                     makefun(&req_write, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "document_root", APR_HASH_KEY_STRING,
                     makefun(&req_document_root, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "context_prefix", APR_HASH_KEY_STRING,
                     makefun(&req_context_prefix, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "context_document_root", APR_HASH_KEY_STRING,
                     makefun(&req_context_document_root, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "parseargs", APR_HASH_KEY_STRING,
                     makefun(&req_parseargs, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "parsebody", APR_HASH_KEY_STRING,
                     makefun(&req_parsebody, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "debug", APR_HASH_KEY_STRING,
                     makefun(&req_debug, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "info", APR_HASH_KEY_STRING,
                     makefun(&req_info, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "notice", APR_HASH_KEY_STRING,
                     makefun(&req_notice, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "warn", APR_HASH_KEY_STRING,
                     makefun(&req_warn, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "err", APR_HASH_KEY_STRING,
                     makefun(&req_err, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "crit", APR_HASH_KEY_STRING,
                     makefun(&req_crit, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "alert", APR_HASH_KEY_STRING,
                     makefun(&req_alert, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "emerg", APR_HASH_KEY_STRING,
                     makefun(&req_emerg, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace1", APR_HASH_KEY_STRING,
                     makefun(&req_trace1, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace2", APR_HASH_KEY_STRING,
                     makefun(&req_trace2, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace3", APR_HASH_KEY_STRING,
                     makefun(&req_trace3, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace4", APR_HASH_KEY_STRING,
                     makefun(&req_trace4, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace5", APR_HASH_KEY_STRING,
                     makefun(&req_trace5, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace6", APR_HASH_KEY_STRING,
                     makefun(&req_trace6, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace7", APR_HASH_KEY_STRING,
                     makefun(&req_trace7, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "trace8", APR_HASH_KEY_STRING,
                     makefun(&req_trace8, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "add_output_filter", APR_HASH_KEY_STRING,
                     makefun(&req_add_output_filter, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "construct_url", APR_HASH_KEY_STRING,
                     makefun(&req_construct_url, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "escape_html", APR_HASH_KEY_STRING,
                     makefun(&req_escape_html, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "ssl_var_lookup", APR_HASH_KEY_STRING,
                     makefun(&req_ssl_var_lookup, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "is_https", APR_HASH_KEY_STRING,
                     makefun(&req_ssl_is_https_field, APL_REQ_FUNTYPE_BOOLEAN, p));
        apr_hash_set(dispatch, "assbackwards", APR_HASH_KEY_STRING,
                     makefun(&req_assbackwards_field, APL_REQ_FUNTYPE_BOOLEAN, p));
        apr_hash_set(dispatch, "status", APR_HASH_KEY_STRING,
                     makefun(&req_status_field, APL_REQ_FUNTYPE_INT, p));
        apr_hash_set(dispatch, "protocol", APR_HASH_KEY_STRING,
                     makefun(&req_protocol_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "range", APR_HASH_KEY_STRING,
                     makefun(&req_range_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "content_type", APR_HASH_KEY_STRING,
                     makefun(&req_content_type_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "content_encoding", APR_HASH_KEY_STRING,
                     makefun(&req_content_encoding_field, APL_REQ_FUNTYPE_STRING,
                             p));
        apr_hash_set(dispatch, "ap_auth_type", APR_HASH_KEY_STRING,
                     makefun(&req_ap_auth_type_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "unparsed_uri", APR_HASH_KEY_STRING,
                     makefun(&req_unparsed_uri_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "user", APR_HASH_KEY_STRING,
                     makefun(&req_user_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "filename", APR_HASH_KEY_STRING,
                     makefun(&req_filename_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "canonical_filename", APR_HASH_KEY_STRING,
                     makefun(&req_canonical_filename_field,
                             APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "path_info", APR_HASH_KEY_STRING,
                     makefun(&req_path_info_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "args", APR_HASH_KEY_STRING,
                     makefun(&req_args_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "handler", APR_HASH_KEY_STRING,
                     makefun(&req_handler_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "hostname", APR_HASH_KEY_STRING,
                     makefun(&req_hostname_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "uri", APR_HASH_KEY_STRING,
                     makefun(&req_uri_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "the_request", APR_HASH_KEY_STRING,
                     makefun(&req_the_request_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "log_id", APR_HASH_KEY_STRING,
                     makefun(&req_log_id_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "useragent_ip", APR_HASH_KEY_STRING,
                     makefun(&req_useragent_ip_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "method", APR_HASH_KEY_STRING,
                     makefun(&req_method_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "proxyreq", APR_HASH_KEY_STRING,
                     makefun(&req_proxyreq_field, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "headers_in", APR_HASH_KEY_STRING,
                     makefun(&req_headers_in, APL_REQ_FUNTYPE_TABLE, p));
        apr_hash_set(dispatch, "headers_in_table", APR_HASH_KEY_STRING,
                     makefun(&req_headers_in_table, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "headers_out", APR_HASH_KEY_STRING,
                     makefun(&req_headers_out, APL_REQ_FUNTYPE_TABLE, p));
        apr_hash_set(dispatch, "headers_out_table", APR_HASH_KEY_STRING,
                     makefun(&req_headers_out_table, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "err_headers_out", APR_HASH_KEY_STRING,
                     makefun(&req_err_headers_out, APL_REQ_FUNTYPE_TABLE, p));
        apr_hash_set(dispatch, "err_headers_out_table", APR_HASH_KEY_STRING,
                     makefun(&req_err_headers_out_table, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "notes", APR_HASH_KEY_STRING,
                     makefun(&req_notes, APL_REQ_FUNTYPE_TABLE, p));
        apr_hash_set(dispatch, "notes_table", APR_HASH_KEY_STRING,
                     makefun(&req_notes_table, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "subprocess_env", APR_HASH_KEY_STRING,
                     makefun(&req_subprocess_env, APL_REQ_FUNTYPE_TABLE, p));
        apr_hash_set(dispatch, "subprocess_env_table", APR_HASH_KEY_STRING,
                     makefun(&req_subprocess_env_table, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "flush", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_rflush, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "port", APR_HASH_KEY_STRING,
                     makefun(&req_ap_get_server_port, APL_REQ_FUNTYPE_INT, p));
        apr_hash_set(dispatch, "banner", APR_HASH_KEY_STRING,
                     makefun(&ap_get_server_banner, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "options", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_options, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "allowoverrides", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_allowoverrides, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "started", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_started, APL_REQ_FUNTYPE_INT, p));
        apr_hash_set(dispatch, "basic_auth_pw", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_basic_auth_pw, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "limit_req_body", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_limit_req_body, APL_REQ_FUNTYPE_INT, p));
        apr_hash_set(dispatch, "server_built", APR_HASH_KEY_STRING,
                     makefun(&ap_get_server_built, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "is_initial_req", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_is_initial_req, APL_REQ_FUNTYPE_BOOLEAN, p));
        apr_hash_set(dispatch, "remaining", APR_HASH_KEY_STRING,
                     makefun(&req_remaining_field, APL_REQ_FUNTYPE_INT, p));
        apr_hash_set(dispatch, "some_auth_required", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_some_auth_required, APL_REQ_FUNTYPE_BOOLEAN, p));
        apr_hash_set(dispatch, "server_name", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_get_server_name, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "auth_name", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_auth_name, APL_REQ_FUNTYPE_STRING, p));
        apr_hash_set(dispatch, "sendfile", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_sendfile, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "dbacquire", APR_HASH_KEY_STRING,
                     makefun(&lua_db_acquire, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "stat", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_stat, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "get_direntries", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_getdir, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "regex", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_regex, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "usleep", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_usleep, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "base64_encode", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_b64encode, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "base64_decode", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_b64decode, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "md5", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_md5, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "sha1", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_sha1, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "htpassword", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_htpassword, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "touch", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_touch, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "mkdir", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_mkdir, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "mkrdir", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_mkrdir, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "rmdir", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_rmdir, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "date_parse_rfc", APR_HASH_KEY_STRING,
                     makefun(&lua_apr_date_parse_rfc, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "escape", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_escape, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "unescape", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_unescape, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "mpm_query", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_mpm_query, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "expr", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_expr, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "scoreboard_process", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_scoreboard_process, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "scoreboard_worker", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_scoreboard_worker, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "clock", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_clock, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "requestbody", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_requestbody, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "add_input_filter", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_add_input_filter, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "module_info", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_module_info, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "loaded_modules", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_loaded_modules, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "runtime_dir_relative", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_runtime_dir_relative, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "server_info", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_server_info, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "set_document_root", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_set_document_root, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "set_context_info", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_set_context_info, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "os_escape_path", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_os_escape_path, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "escape_logitem", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_escape_logitem, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "strcmp_match", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_strcmp_match, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "set_keepalive", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_set_keepalive, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "make_etag", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_make_etag, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "send_interim_response", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_send_interim_response, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "custom_response", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_custom_response, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "exists_config_define", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_exists_config_define, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "state_query", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_state_query, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "get_server_name_for_url", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_get_server_name_for_url, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "ivm_get", APR_HASH_KEY_STRING,
                     makefun(&lua_ivm_get, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "ivm_set", APR_HASH_KEY_STRING,
                     makefun(&lua_ivm_set, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "getcookie", APR_HASH_KEY_STRING,
                     makefun(&lua_get_cookie, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "setcookie", APR_HASH_KEY_STRING,
                     makefun(&lua_set_cookie, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "wsupgrade", APR_HASH_KEY_STRING,
                     makefun(&lua_websocket_greet, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "wsread", APR_HASH_KEY_STRING,
                     makefun(&lua_websocket_read, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "wspeek", APR_HASH_KEY_STRING,
                     makefun(&lua_websocket_peek, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "wswrite", APR_HASH_KEY_STRING,
                     makefun(&lua_websocket_write, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "wsclose", APR_HASH_KEY_STRING,
                     makefun(&lua_websocket_close, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "wsping", APR_HASH_KEY_STRING,
                     makefun(&lua_websocket_ping, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "config", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_get_config, APL_REQ_FUNTYPE_LUACFUN, p));
        apr_hash_set(dispatch, "activeconfig", APR_HASH_KEY_STRING,
                     makefun(&lua_ap_get_active_config, APL_REQ_FUNTYPE_LUACFUN, p));
        lua_pushlightuserdata(L, dispatch);
        lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch");
    
        luaL_newmetatable(L, "Apache2.Request");     /* [metatable] */
        lua_pushvalue(L, -1);
    
        lua_setfield(L, -2, "__index");
        luaL_setfuncs_compat(L, request_methods);    /* [metatable] */
    
        lua_pop(L, 2);
    
        luaL_newmetatable(L, "Apache2.Connection");  /* [metatable] */
        lua_pushvalue(L, -1);
    
        lua_setfield(L, -2, "__index");
        luaL_setfuncs_compat(L, connection_methods); /* [metatable] */
    
        lua_pop(L, 2);
    
        luaL_newmetatable(L, "Apache2.Server");      /* [metatable] */
        lua_pushvalue(L, -1);
    
        lua_setfield(L, -2, "__index");
        luaL_setfuncs_compat(L, server_methods);     /* [metatable] */
    
        lua_pop(L, 2);
    
    }
    
    void ap_lua_push_connection(lua_State *L, conn_rec *c)
    {
        req_table_t* t;
        lua_boxpointer(L, c);
        luaL_getmetatable(L, "Apache2.Connection");
        lua_setmetatable(L, -2);
        luaL_getmetatable(L, "Apache2.Connection");
    
        t = apr_pcalloc(c->pool, sizeof(req_table_t));
        t->t = c->notes;
        t->r = NULL;
        t->n = "notes";
        ap_lua_push_apr_table(L, t);
        lua_setfield(L, -2, "notes");
    
        lua_pushstring(L, c->client_ip);
        lua_setfield(L, -2, "client_ip");
    
        lua_pop(L, 1);
    }
    
    
    void ap_lua_push_server(lua_State *L, server_rec *s)
    {
        lua_boxpointer(L, s);
        luaL_getmetatable(L, "Apache2.Server");
        lua_setmetatable(L, -2);
        luaL_getmetatable(L, "Apache2.Server");
    
        lua_pushstring(L, s->server_hostname);
        lua_setfield(L, -2, "server_hostname");
    
        lua_pop(L, 1);
    }
    
    void ap_lua_push_request(lua_State *L, request_rec *r)
    {
        lua_boxpointer(L, r);
        luaL_getmetatable(L, "Apache2.Request");
        lua_setmetatable(L, -2);
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_vmprep.c���������������������������������������������������������������0000664�0001751�0001751�00000045256�13350443433�017407� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_lua.h"
    #include "http_log.h"
    #include "apr_uuid.h"
    #include "lua_config.h"
    #include "apr_file_info.h"
    #include "mod_auth.h"
    
    APLOG_USE_MODULE(lua);
    
    #ifndef AP_LUA_MODULE_EXT
    #if defined(NETWARE) 
    #define AP_LUA_MODULE_EXT ".nlm"
    #elif defined(WIN32)
    #define AP_LUA_MODULE_EXT ".dll"
    #elif (defined(__hpux__) || defined(__hpux)) && !defined(__ia64)
    #define AP_LUA_MODULE_EXT ".sl"
    #else
    #define AP_LUA_MODULE_EXT ".so"
    #endif
    #endif
    
    #if APR_HAS_THREADS
        apr_thread_mutex_t *ap_lua_mutex;
    #endif
    extern apr_global_mutex_t *lua_ivm_mutex;
        
    void ap_lua_init_mutex(apr_pool_t *pool, server_rec *s) 
    {
        apr_status_t rv;
        
        /* global IVM mutex */
        rv = apr_global_mutex_child_init(&lua_ivm_mutex,
                                         apr_global_mutex_lockfile(lua_ivm_mutex),
                                         pool);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03016)
                         "mod_lua: Failed to reopen mutex lua-ivm-shm in child");
            exit(1); /* bah :( */
        }
        
        /* Server pool mutex */
    #if APR_HAS_THREADS
        apr_thread_mutex_create(&ap_lua_mutex, APR_THREAD_MUTEX_DEFAULT, pool);
    #endif
    }
    
    /* forward dec'l from this file */
    
    #if 0
    static void pstack_dump(lua_State *L, apr_pool_t *r, int level,
                            const char *msg)
    {
        int i;
        int top = lua_gettop(L);
    
        ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03211)
                      "Lua Stack Dump: [%s]", msg);
    
        for (i = 1; i <= top; i++) {
            int t = lua_type(L, i);
            switch (t) {
            case LUA_TSTRING:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03212)
                                  "%d:  '%s'", i, lua_tostring(L, i));
                    break;
                }
            case LUA_TUSERDATA:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03213)
                                  "%d:  userdata", i);
                    break;
                }
            case LUA_TLIGHTUSERDATA:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03214)
                                  "%d:  lightuserdata", i);
                    break;
                }
            case LUA_TNIL:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03215)
                                  "%d:  NIL", i);
                    break;
                }
            case LUA_TNONE:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03216)
                                  "%d:  None", i);
                    break;
                }
            case LUA_TBOOLEAN:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03217)
                                  "%d:  %s",
                                  i, lua_toboolean(L, i) ? "true" : "false");
                    break;
                }
            case LUA_TNUMBER:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03218)
                                  "%d:  %g", i, lua_tonumber(L, i));
                    break;
                }
            case LUA_TTABLE:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03219)
                                  "%d:  <table>", i);
                    break;
                }
            case LUA_TTHREAD:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03220)
                                  "%d:  <thread>", i);
                    break;
                }
            case LUA_TFUNCTION:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03221)
                                  "%d:  <function>", i);
                    break;
                }
            default:{
                    ap_log_perror(APLOG_MARK, level, 0, r, APLOGNO(03222)
                                  "%d:  unknown: [%s]", i, lua_typename(L, i));
                    break;
                }
            }
        }
    }
    #endif
    
    /* BEGIN modules*/
    
    /* BEGIN apache lmodule  */
    
    #define makeintegerfield(L, n) lua_pushinteger(L, n); lua_setfield(L, -2, #n)
    
    void ap_lua_load_apache2_lmodule(lua_State *L)
    {
        lua_getglobal(L, "package");
        lua_getfield(L, -1, "loaded");
        lua_newtable(L);
        lua_setfield(L, -2, "apache2");
        lua_setglobal(L, "apache2");
        lua_pop(L, 1);              /* empty stack */
    
        lua_getglobal(L, "apache2");
    
        lua_pushstring(L, ap_get_server_banner());
        lua_setfield(L, -2, "version");
    
        makeintegerfield(L, OK);
        makeintegerfield(L, DECLINED);
        makeintegerfield(L, DONE);
        makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
        makeintegerfield(L, PROXYREQ_NONE);
        makeintegerfield(L, PROXYREQ_PROXY);
        makeintegerfield(L, PROXYREQ_REVERSE);
        makeintegerfield(L, PROXYREQ_RESPONSE);
        makeintegerfield(L, PROXYREQ_RESPONSE);
        makeintegerfield(L, AUTHZ_DENIED);
        makeintegerfield(L, AUTHZ_GRANTED);
        makeintegerfield(L, AUTHZ_NEUTRAL);
        makeintegerfield(L, AUTHZ_GENERAL_ERROR);
        makeintegerfield(L, AUTHZ_DENIED_NO_USER);
        
        /*
           makeintegerfield(L, HTTP_CONTINUE);
           makeintegerfield(L, HTTP_SWITCHING_PROTOCOLS);
           makeintegerfield(L, HTTP_PROCESSING);
           makeintegerfield(L, HTTP_OK);
           makeintegerfield(L, HTTP_CREATED);
           makeintegerfield(L, HTTP_ACCEPTED);
           makeintegerfield(L, HTTP_NON_AUTHORITATIVE);
           makeintegerfield(L, HTTP_NO_CONTENT);
           makeintegerfield(L, HTTP_RESET_CONTENT);
           makeintegerfield(L, HTTP_PARTIAL_CONTENT);
           makeintegerfield(L, HTTP_MULTI_STATUS);
           makeintegerfield(L, HTTP_ALREADY_REPORTED);
           makeintegerfield(L, HTTP_IM_USED);
           makeintegerfield(L, HTTP_MULTIPLE_CHOICES);
           makeintegerfield(L, HTTP_MOVED_PERMANENTLY);
           makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
           makeintegerfield(L, HTTP_SEE_OTHER);
           makeintegerfield(L, HTTP_NOT_MODIFIED);
           makeintegerfield(L, HTTP_USE_PROXY);
           makeintegerfield(L, HTTP_TEMPORARY_REDIRECT);
           makeintegerfield(L, HTTP_PERMANENT_REDIRECT);
           makeintegerfield(L, HTTP_BAD_REQUEST);
           makeintegerfield(L, HTTP_UNAUTHORIZED);
           makeintegerfield(L, HTTP_PAYMENT_REQUIRED);
           makeintegerfield(L, HTTP_FORBIDDEN);
           makeintegerfield(L, HTTP_NOT_FOUND);
           makeintegerfield(L, HTTP_METHOD_NOT_ALLOWED);
           makeintegerfield(L, HTTP_NOT_ACCEPTABLE);
           makeintegerfield(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
           makeintegerfield(L, HTTP_REQUEST_TIME_OUT);
           makeintegerfield(L, HTTP_CONFLICT);
           makeintegerfield(L, HTTP_GONE);
           makeintegerfield(L, HTTP_LENGTH_REQUIRED);
           makeintegerfield(L, HTTP_PRECONDITION_FAILED);
           makeintegerfield(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
           makeintegerfield(L, HTTP_REQUEST_URI_TOO_LARGE);
           makeintegerfield(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
           makeintegerfield(L, HTTP_RANGE_NOT_SATISFIABLE);
           makeintegerfield(L, HTTP_EXPECTATION_FAILED);
           makeintegerfield(L, HTTP_UNPROCESSABLE_ENTITY);
           makeintegerfield(L, HTTP_LOCKED);
           makeintegerfield(L, HTTP_FAILED_DEPENDENCY);
           makeintegerfield(L, HTTP_UPGRADE_REQUIRED);
           makeintegerfield(L, HTTP_PRECONDITION_REQUIRED);
           makeintegerfield(L, HTTP_TOO_MANY_REQUESTS);
           makeintegerfield(L, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
           makeintegerfield(L, HTTP_INTERNAL_SERVER_ERROR);
           makeintegerfield(L, HTTP_NOT_IMPLEMENTED);
           makeintegerfield(L, HTTP_BAD_GATEWAY);
           makeintegerfield(L, HTTP_SERVICE_UNAVAILABLE);
           makeintegerfield(L, HTTP_GATEWAY_TIME_OUT);
           makeintegerfield(L, HTTP_VERSION_NOT_SUPPORTED);
           makeintegerfield(L, HTTP_VARIANT_ALSO_VARIES);
           makeintegerfield(L, HTTP_INSUFFICIENT_STORAGE);
           makeintegerfield(L, HTTP_LOOP_DETECTED);
           makeintegerfield(L, HTTP_NOT_EXTENDED);
           makeintegerfield(L, HTTP_NETWORK_AUTHENTICATION_REQUIRED);
         */
    }
    
    /* END apache2 lmodule */
    
    /*  END library functions */
    
    /* callback for cleaning up a lua vm when pool is closed */
    static apr_status_t cleanup_lua(void *l)
    {
        AP_DEBUG_ASSERT(l != NULL);
        lua_close((lua_State *) l);
        return APR_SUCCESS;
    }
    
    static apr_status_t server_cleanup_lua(void *resource, void *params, apr_pool_t *pool)
    {
        ap_lua_server_spec* spec = (ap_lua_server_spec*) resource;
        AP_DEBUG_ASSERT(spec != NULL);
        if (spec->L != NULL) {
            lua_close((lua_State *) spec->L);
        }
        return APR_SUCCESS;
    }
    
    /*
            munge_path(L, 
                       "path", 
                       "?.lua", 
                       "./?.lua", 
                       lifecycle_pool,
                       spec->package_paths, 
                       spec->file);
    */
    /**
     * field -> "path" or "cpath"
     * sub_pat -> "?.lua"
     * rep_pat -> "./?.lua"
     * pool -> lifecycle pool for allocations
     * paths -> things to add
     * file -> ???
     */
    static void munge_path(lua_State *L,
                           const char *field,
                           const char *sub_pat,
                           const char *rep_pat,
                           apr_pool_t *pool,
                           apr_array_header_t *paths,
                           const char *file)
    {
        const char *current;
        const char *parent_dir;
        const char *pattern;
        const char *modified;
        char *part;
    
        lua_getglobal(L, "package");
        lua_getfield(L, -1, field);
        
        current = lua_tostring(L, -1);
    
        parent_dir = ap_make_dirstr_parent(pool, file);
     
        pattern = apr_pstrcat(pool, parent_dir, sub_pat, NULL);
    
        luaL_gsub(L, current, rep_pat, pattern);
        lua_setfield(L, -3, field);
        lua_getfield(L, -2, field);
        modified = lua_tostring(L, -1);
    
    
        lua_pop(L, 2);
    
        part = apr_pstrcat(pool, modified, ";", apr_array_pstrcat(pool, paths, ';'),
                           NULL);
    
        lua_pushstring(L, part);
        lua_setfield(L, -2, field);
        lua_pop(L, 1);              /* pop "package" off the stack     */
    }
    
    #ifdef AP_ENABLE_LUAJIT
    static int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool)
    {
        lua_getglobal(L, "require");
        lua_pushliteral(L, "jit.");
        lua_pushvalue(L, -3);
        lua_concat(L, 2);
        if (lua_pcall(L, 1, 1, 0)) {
            const char *msg = lua_tostring(L, -1);
            ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01480)
                          "Failed to init LuaJIT: %s", msg);
            return 1;
        }
        lua_getfield(L, -1, "start");
        lua_remove(L, -2);  /* drop module table */
        return 0;
    }
    
    #endif
    
    static apr_status_t vm_construct(lua_State **vm, void *params, apr_pool_t *lifecycle_pool)
    {
        lua_State* L;
    
        ap_lua_vm_spec *spec = params;
    
        L = luaL_newstate();
    #ifdef AP_ENABLE_LUAJIT
        luaopen_jit(L);
    #endif
        luaL_openlibs(L);
        if (spec->package_paths) {
            munge_path(L, 
                       "path", "?.lua", "./?.lua", 
                       lifecycle_pool,
                       spec->package_paths, 
                       spec->file);
        }
        if (spec->package_cpaths) {
            munge_path(L,
                       "cpath", "?" AP_LUA_MODULE_EXT, "./?" AP_LUA_MODULE_EXT,
                       lifecycle_pool,
                       spec->package_cpaths,
                       spec->file);
        }
    
        if (spec->cb) {
            spec->cb(L, lifecycle_pool, spec->cb_arg);
        }
    
    
        if (spec->bytecode && spec->bytecode_len > 0) {
            luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
            lua_pcall(L, 0, LUA_MULTRET, 0);
        }
        else {
            int rc;
            ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01481)
                "loading lua file %s", spec->file);
            rc = luaL_loadfile(L, spec->file);
            if (rc != 0) {
                ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
                              "Error loading %s: %s", spec->file,
                              rc == LUA_ERRMEM ? "memory allocation error"
                                               : lua_tostring(L, 0));
                return APR_EBADF;
            }
            if ( lua_pcall(L, 0, LUA_MULTRET, 0) == LUA_ERRRUN ) {
                ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(02613)
                              "Error loading %s: %s", spec->file,
                                lua_tostring(L, -1));
                return APR_EBADF;
            }
        }
    
    #ifdef AP_ENABLE_LUAJIT
        loadjitmodule(L, lifecycle_pool);
    #endif
        lua_pushlightuserdata(L, lifecycle_pool);
        lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool");
        *vm = L;
    
        return APR_SUCCESS;
    }
    
    static ap_lua_vm_spec* copy_vm_spec(apr_pool_t* pool, ap_lua_vm_spec* spec) 
    {
        ap_lua_vm_spec* copied_spec = apr_pcalloc(pool, sizeof(ap_lua_vm_spec));
        copied_spec->bytecode_len = spec->bytecode_len;
        copied_spec->bytecode = apr_pstrdup(pool, spec->bytecode);
        copied_spec->cb = spec->cb;
        copied_spec->cb_arg = NULL;
        copied_spec->file = apr_pstrdup(pool, spec->file);
        copied_spec->package_cpaths = apr_array_copy(pool, spec->package_cpaths);
        copied_spec->package_paths = apr_array_copy(pool, spec->package_paths);
        copied_spec->pool = pool;
        copied_spec->scope = AP_LUA_SCOPE_SERVER;
        copied_spec->codecache = spec->codecache;
        return copied_spec;
    }
    
    static apr_status_t server_vm_construct(lua_State **resource, void *params, apr_pool_t *pool)
    {
        lua_State* L;
        ap_lua_server_spec* spec = apr_pcalloc(pool, sizeof(ap_lua_server_spec));
        *resource = NULL;
        if (vm_construct(&L, params, pool) == APR_SUCCESS) {
            spec->finfo = apr_pcalloc(pool, sizeof(ap_lua_finfo));
            if (L != NULL) {
                spec->L = L;
                *resource = (void*) spec;
                lua_pushlightuserdata(L, spec);
                lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Lua.server_spec");
                return APR_SUCCESS;
            }
        }
        return APR_EGENERAL;
    }
    
    /**
     * Function used to create a lua_State instance bound into the web
     * server in the appropriate scope.
     */
    lua_State *ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
                                                   ap_lua_vm_spec *spec, request_rec* r)
    {
        lua_State *L = NULL;
        ap_lua_finfo *cache_info = NULL;
        int tryCache = 0;
        
        if (spec->scope == AP_LUA_SCOPE_SERVER) {
            char *hash;
            apr_reslist_t* reslist = NULL;
            ap_lua_server_spec* sspec = NULL;
            hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
    #if APR_HAS_THREADS
            apr_thread_mutex_lock(ap_lua_mutex);
    #endif
            if (apr_pool_userdata_get((void **)&reslist, hash,
                                      r->server->process->pool) == APR_SUCCESS) {
                if (reslist != NULL) {
                    if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
                        L = sspec->L;
                        cache_info = sspec->finfo;
                    }
                }
            }
            if (L == NULL) {
                ap_lua_vm_spec* server_spec = copy_vm_spec(r->server->process->pool, spec);
                if (
                        apr_reslist_create(&reslist, spec->vm_min, spec->vm_max, spec->vm_max, 0, 
                                    (apr_reslist_constructor) server_vm_construct, 
                                    (apr_reslist_destructor) server_cleanup_lua, 
                                    server_spec, r->server->process->pool)
                        == APR_SUCCESS && reslist != NULL) {
                    apr_pool_userdata_set(reslist, hash, NULL,
                                                r->server->process->pool);
                    if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
                        L = sspec->L;
                        cache_info = sspec->finfo;
                    }
                    else {
    #if APR_HAS_THREADS
                        apr_thread_mutex_unlock(ap_lua_mutex);
    #endif
                        return NULL;
                    }
                }
            }
    #if APR_HAS_THREADS
            apr_thread_mutex_unlock(ap_lua_mutex);
    #endif
        }
        else {
            if (apr_pool_userdata_get((void **)&L, spec->file,
                                  lifecycle_pool) != APR_SUCCESS) {
                L = NULL;
            }
        }
        if (L == NULL) {
            ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483)
                            "creating lua_State with file %s", spec->file);
            /* not available, so create */
    
            if (!vm_construct(&L, spec, lifecycle_pool)) {
                AP_DEBUG_ASSERT(L != NULL);
                apr_pool_userdata_set(L, spec->file, cleanup_lua, lifecycle_pool);
            }
        }
    
        if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) {
            tryCache = 1;
        }
        else {
            char* mkey;
            if (spec->scope != AP_LUA_SCOPE_SERVER) {
                mkey = apr_psprintf(r->pool, "ap_lua_modified:%s", spec->file);
                apr_pool_userdata_get((void **)&cache_info, mkey, lifecycle_pool);
                if (cache_info == NULL) {
                    cache_info = apr_pcalloc(lifecycle_pool, sizeof(ap_lua_finfo));
                    apr_pool_userdata_set((void*) cache_info, mkey, NULL, lifecycle_pool);
                }
            }
            if (spec->codecache == AP_LUA_CACHE_STAT) {
                apr_finfo_t lua_finfo;
                apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME|APR_FINFO_SIZE, lifecycle_pool);
    
                /* On first visit, modified will be zero, but that's fine - The file is 
                loaded in the vm_construct function.
                */
                if ((cache_info->modified == lua_finfo.mtime && cache_info->size == lua_finfo.size)
                        || cache_info->modified == 0) {
                    tryCache = 1;
                }
                cache_info->modified = lua_finfo.mtime;
                cache_info->size = lua_finfo.size;
            }
            else if (spec->codecache == AP_LUA_CACHE_NEVER) {
                if (cache_info->runs == 0)
                    tryCache = 1;
            }
            cache_info->runs++;
        }
        if (tryCache == 0 && spec->scope != AP_LUA_SCOPE_ONCE) {
            int rc;
            ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(02332)
                "(re)loading lua file %s", spec->file);
            rc = luaL_loadfile(L, spec->file);
            if (rc != 0) {
                ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(02333)
                              "Error loading %s: %s", spec->file,
                              rc == LUA_ERRMEM ? "memory allocation error"
                                               : lua_tostring(L, 0));
                return 0;
            }
            lua_pcall(L, 0, LUA_MULTRET, 0);
        }
    
        return L;
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_dbd.c������������������������������������������������������������������0000664�0001751�0001751�00000064574�13055576313�016641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_lua.h"
    #include "lua_dbd.h"
    
    APLOG_USE_MODULE(lua);
    static APR_OPTIONAL_FN_TYPE(ap_dbd_close) *lua_ap_dbd_close = NULL;
    static APR_OPTIONAL_FN_TYPE(ap_dbd_open) *lua_ap_dbd_open = NULL;
    
    
    
    
    static request_rec *ap_lua_check_request_rec(lua_State *L, int index)
    {
        request_rec *r;
        luaL_checkudata(L, index, "Apache2.Request");
        r = lua_unboxpointer(L, index);
        return r;
    }
    
    static lua_db_handle *lua_get_db_handle(lua_State *L)
    {
        luaL_checktype(L, 1, LUA_TTABLE);
        lua_rawgeti(L, 1, 0);
        luaL_checktype(L, -1, LUA_TUSERDATA);
        return (lua_db_handle *) lua_topointer(L, -1);
    }
    
    static lua_db_result_set *lua_get_result_set(lua_State *L)
    {
        luaL_checktype(L, 1, LUA_TTABLE);
        lua_rawgeti(L, 1, 0);
        luaL_checktype(L, -1, LUA_TUSERDATA);
        return (lua_db_result_set *) lua_topointer(L, -1);
    }
    
    
    /*
       =============================================================================
        db:close(): Closes an open database connection.
       =============================================================================
     */
    int lua_db_close(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~*/
        lua_db_handle   *db;
        apr_status_t     rc = 0;
        /*~~~~~~~~~~~~~~~~~~~~*/
        
        db = lua_get_db_handle(L);
        if (db && db->alive) {
            if (db->type == LUA_DBTYPE_APR_DBD) {
                rc = apr_dbd_close(db->driver, db->handle);
                if (db->pool) apr_pool_destroy(db->pool);
            }
            else {
                lua_ap_dbd_close = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_close);
                if (lua_ap_dbd_close != NULL)
                    if (db->dbdhandle) lua_ap_dbd_close(db->server, db->dbdhandle);
            }
    
            db->driver = NULL;
            db->handle = NULL;
            db->alive = 0;
            db->pool = NULL;
        }
    
        lua_settop(L, 0);
        lua_pushnumber(L, rc);
        return 1;
    } 
    
    /*
       =============================================================================
         db:__gc(): Garbage collecting function.
       =============================================================================
     */
    int lua_db_gc(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~*/
        lua_db_handle    *db;
        /*~~~~~~~~~~~~~~~~~~~~*/
    
        db = lua_touserdata(L, 1);
        if (db && db->alive) {
            if (db->type == LUA_DBTYPE_APR_DBD) {
                apr_dbd_close(db->driver, db->handle);
                if (db->pool) apr_pool_destroy(db->pool);
            }
            else {
                lua_ap_dbd_close = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_close);
                if (lua_ap_dbd_close != NULL)
                    if (db->dbdhandle) lua_ap_dbd_close(db->server, db->dbdhandle);
            }
            db->driver = NULL;
            db->handle = NULL;
            db->alive = 0;
            db->pool = NULL;
        }
        lua_settop(L, 0);
        return 0;
    }
    
    /*
       =============================================================================
        db:active(): Returns true if the connection to the db is still active.
       =============================================================================
     */
    int lua_db_active(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~*/
        lua_db_handle   *db = 0;
        apr_status_t     rc = 0;
        /*~~~~~~~~~~~~~~~~~~~~*/
    
        db = lua_get_db_handle(L);
        if (db && db->alive) {
            rc = apr_dbd_check_conn(db->driver, db->pool, db->handle);
            if (rc == APR_SUCCESS) {
                lua_pushboolean(L, 1);
                return 1;
            }
        }
    
        lua_pushboolean(L, 0);
        return 1;
    }
    
    /*
       =============================================================================
        db:query(statement): Executes the given database query and returns the 
        number of rows affected. If an error is encountered, returns nil as the 
        first parameter and the error message as the second.
       =============================================================================
     */
    int lua_db_query(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~*/
        lua_db_handle   *db = 0;
        apr_status_t     rc = 0;
        int              x = 0;
        const char      *statement;
        /*~~~~~~~~~~~~~~~~~~~~~~~*/
        luaL_checktype(L, 3, LUA_TSTRING);
        statement = lua_tostring(L, 3);
        db = lua_get_db_handle(L);
        if (db && db->alive)
            rc = apr_dbd_query(db->driver, db->handle, &x, statement);
        else {
            rc = 0;
            x = -1;
        }
    
        if (rc == APR_SUCCESS)
            lua_pushnumber(L, x);
        else {
    
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            const char  *err = apr_dbd_error(db->driver, db->handle, rc);
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
            lua_pushnil(L);
            if (err) {
                lua_pushstring(L, err);
                return 2;
            }
        }
    
        return 1;
    }
    
    /*
       =============================================================================
        db:escape(string): Escapes a string for safe use in the given database type.
       =============================================================================
     */
    int lua_db_escape(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~~*/
        lua_db_handle    *db = 0;
        const char       *statement;
        const char       *escaped = 0;
        request_rec      *r;
        /*~~~~~~~~~~~~~~~~~~~~~*/
    
        r = ap_lua_check_request_rec(L, 2);
        if (r) {
            luaL_checktype(L, 3, LUA_TSTRING);
            statement = lua_tostring(L, 3);
            db = lua_get_db_handle(L);
            if (db && db->alive) {
                apr_dbd_init(r->pool);
                escaped = apr_dbd_escape(db->driver, r->pool, statement,
                                         db->handle);
                if (escaped) {
                    lua_pushstring(L, escaped);
                    return 1;
                }
            }
            else {
                lua_pushnil(L);
            }
            return (1);
        }
    
        return 0;
    }
    
    /*
       =============================================================================
         resultset(N): Fetches one or more rows from a result set.
       =============================================================================
     */
    int lua_db_get_row(lua_State *L) 
    {
        int row_no,x,alpha = 0;
        const char      *entry, *rowname;
        apr_dbd_row_t   *row = 0;
        lua_db_result_set *res = lua_get_result_set(L);
        
        row_no = luaL_optinteger(L, 2, 0);
        if (lua_isboolean(L, 3)) {
            alpha = lua_toboolean(L, 3);
        }
        lua_settop(L,0);
        
        /* Fetch all rows at once? */
        
        if (row_no == 0) {
            row_no = 1;
            lua_newtable(L);
            while (apr_dbd_get_row(res->driver, res->pool, res->results,
                                &row, -1) != -1)
             {
                lua_pushinteger(L, row_no);
                lua_newtable(L);
                for (x = 0; x < res->cols; x++) {
                    entry = apr_dbd_get_entry(res->driver, row, x);
                    if (entry) {
                        if (alpha == 1) {
                            rowname = apr_dbd_get_name(res->driver, 
                                    res->results, x);
                            lua_pushstring(L, rowname ? rowname : "(oob)");
                        }
                        else {
                            lua_pushinteger(L, x + 1);
                        }
                        lua_pushstring(L, entry);
                        lua_rawset(L, -3);
                    }
                }
                lua_rawset(L, -3);
                row_no++;
            }
            return 1;
        }
        
        /* Just fetch a single row */
        if (apr_dbd_get_row(res->driver, res->pool, res->results,
                                &row, row_no) != -1)
             {
            
            lua_newtable(L);
            for (x = 0; x < res->cols; x++) {
                entry = apr_dbd_get_entry(res->driver, row, x);
                if (entry) {
                    if (alpha == 1) {
                        rowname = apr_dbd_get_name(res->driver, 
                                res->results, x);
                        lua_pushstring(L, rowname ? rowname : "(oob)");
                    }
                    else {
                        lua_pushinteger(L, x + 1);
                    }
                    lua_pushstring(L, entry);
                    lua_rawset(L, -3);
                }
            }
            return 1;
        }
        return 0;
    }
    
    
    /*
       =============================================================================
        db:select(statement): Queries the database for the given statement and 
        returns the rows/columns found as a table. If an error is encountered, 
        returns nil as the first parameter and the error message as the second.
       =============================================================================
     */
    int lua_db_select(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~*/
        lua_db_handle   *db = 0;
        apr_status_t     rc = 0;
        const char      *statement;
        request_rec     *r;
        /*~~~~~~~~~~~~~~~~~~~~~~~*/
        r = ap_lua_check_request_rec(L, 2);
        if (r) {
            luaL_checktype(L, 3, LUA_TSTRING);
            statement = lua_tostring(L, 3);
            db = lua_get_db_handle(L);
            if (db && db->alive) {
    
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                int cols;
                apr_dbd_results_t   *results = 0;
                lua_db_result_set* resultset = NULL;
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
                rc = apr_dbd_select(db->driver, db->pool, db->handle,
                                    &results, statement, 0);
                if (rc == APR_SUCCESS) {
                    
                    cols = apr_dbd_num_cols(db->driver, results);
                    
                    if (cols > 0) {
                        lua_newtable(L);
                        resultset = lua_newuserdata(L, sizeof(lua_db_result_set));
                        resultset->cols = cols;
                        resultset->driver = db->driver;
                        resultset->pool = db->pool;
                        resultset->rows = apr_dbd_num_tuples(db->driver, results);
                        resultset->results = results;
                        luaL_newmetatable(L, "lua_apr.dbselect");
                        lua_pushliteral(L, "__call");
                        lua_pushcfunction(L, lua_db_get_row);
                        lua_rawset(L, -3);
                        lua_setmetatable(L, -3);
                        lua_rawseti(L, -2, 0);
                        return 1;
                    }
                    return 0;
                }
                else {
    
                    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                    const char  *err = apr_dbd_error(db->driver, db->handle, rc);
                    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
                    lua_pushnil(L);
                    if (err) {
                        lua_pushstring(L, err);
                        return 2;
                    }
                }
            }
    
            lua_pushboolean(L, 0);
            return 1;
        }
    
        return 0;
    }
    
    
    
    /*
       =============================================================================
        statement:select(var1, var2, var3...): Injects variables into a prepared 
        statement and returns the number of rows matching the query.
       =============================================================================
     */
    int lua_db_prepared_select(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        lua_db_prepared_statement  *st = 0;
        apr_status_t     rc = 0;
        const char       **vars;
        int              x, have;
        /*~~~~~~~~~~~~~~~~~~~~~~~*/
        
        /* Fetch the prepared statement and the vars passed */
        luaL_checktype(L, 1, LUA_TTABLE);
        lua_rawgeti(L, 1, 0);
        luaL_checktype(L, -1, LUA_TUSERDATA);
        st = (lua_db_prepared_statement*) lua_topointer(L, -1);
        
        /* Check if we got enough variables passed on to us.
         * This, of course, only works for prepared statements made through lua. */
        have = lua_gettop(L) - 2;
        if (st->variables != -1 && have < st->variables ) {
            lua_pushboolean(L, 0);
            lua_pushfstring(L, 
                    "Error in executing prepared statement: Expected %d arguments, got %d.", 
                    st->variables, have);
            return 2;
        }
        vars = apr_pcalloc(st->db->pool, have*sizeof(char *));
        for (x = 0; x < have; x++) {
            vars[x] = lua_tostring(L, x + 2);
        }
    
        /* Fire off the query */
        if (st->db && st->db->alive) {
    
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            int cols;
            apr_dbd_results_t   *results = 0;
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
            rc = apr_dbd_pselect(st->db->driver, st->db->pool, st->db->handle,
                                    &results, st->statement, 0, have, vars);
            if (rc == APR_SUCCESS) {
    
                /*~~~~~~~~~~~~~~~~~~~~~*/
                lua_db_result_set *resultset;
                /*~~~~~~~~~~~~~~~~~~~~~*/
    
                cols = apr_dbd_num_cols(st->db->driver, results);
                lua_newtable(L);
                resultset = lua_newuserdata(L, sizeof(lua_db_result_set));
                resultset->cols = cols;
                resultset->driver = st->db->driver;
                resultset->pool = st->db->pool;
                resultset->rows = apr_dbd_num_tuples(st->db->driver, results);
                resultset->results = results;
                luaL_newmetatable(L, "lua_apr.dbselect");
                lua_pushliteral(L, "__call");
                lua_pushcfunction(L, lua_db_get_row);
                lua_rawset(L, -3);
                lua_setmetatable(L, -3);
                lua_rawseti(L, -2, 0);
                return 1;
                
            }
            else {
    
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                const char  *err = apr_dbd_error(st->db->driver, st->db->handle, rc);
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
                lua_pushnil(L);
                if (err) {
                    lua_pushstring(L, err);
                    return 2;
                }
                return 1;
            }
        }
    
        lua_pushboolean(L, 0);
        lua_pushliteral(L, 
                "Database connection seems to be closed, please reacquire it.");
        return (2);
    }
    
    
    /*
       =============================================================================
        statement:query(var1, var2, var3...): Injects variables into a prepared 
        statement and returns the number of rows affected.
       =============================================================================
     */
    int lua_db_prepared_query(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        lua_db_prepared_statement  *st = 0;
        apr_status_t     rc = 0;
        const char       **vars;
        int              x, have;
        /*~~~~~~~~~~~~~~~~~~~~~~~*/
        
        /* Fetch the prepared statement and the vars passed */
        luaL_checktype(L, 1, LUA_TTABLE);
        lua_rawgeti(L, 1, 0);
        luaL_checktype(L, -1, LUA_TUSERDATA);
        st = (lua_db_prepared_statement*) lua_topointer(L, -1);
        
        /* Check if we got enough variables passed on to us.
         * This, of course, only works for prepared statements made through lua. */
        have = lua_gettop(L) - 2;
        if (st->variables != -1 && have < st->variables ) {
            lua_pushboolean(L, 0);
            lua_pushfstring(L, 
                    "Error in executing prepared statement: Expected %d arguments, got %d.", 
                    st->variables, have);
            return 2;
        }
        vars = apr_pcalloc(st->db->pool, have*sizeof(char *));
        for (x = 0; x < have; x++) {
            vars[x] = lua_tostring(L, x + 2);
        }
    
        /* Fire off the query */
        if (st->db && st->db->alive) {
    
            /*~~~~~~~~~~~~~~*/
            int affected = 0;
            /*~~~~~~~~~~~~~~*/
    
            rc = apr_dbd_pquery(st->db->driver, st->db->pool, st->db->handle,
                                    &affected, st->statement, have, vars);
            if (rc == APR_SUCCESS) {
                lua_pushinteger(L, affected);
                return 1;
            }
            else {
    
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                const char  *err = apr_dbd_error(st->db->driver, st->db->handle, rc);
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
                lua_pushnil(L);
                if (err) {
                    lua_pushstring(L, err);
                    return 2;
                }
                return 1;
            }
        }
    
        lua_pushboolean(L, 0);
        lua_pushliteral(L, 
                "Database connection seems to be closed, please reacquire it.");
        return (2);
    }
    
    /*
       =============================================================================
        db:prepare(statement): Prepares a statement for later query/select.
        Returns a table with a :query and :select function, same as the db funcs.
       =============================================================================
     */
    int lua_db_prepare(lua_State* L) 
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        lua_db_handle   *db = 0;
        apr_status_t     rc = 0;
        const char      *statement, *at;
        request_rec     *r;
        lua_db_prepared_statement* st;
        int need = 0;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        
        r = ap_lua_check_request_rec(L, 2);
        if (r) {
            apr_dbd_prepared_t *pstatement = NULL;
            luaL_checktype(L, 3, LUA_TSTRING);
            statement = lua_tostring(L, 3);
            
            /* Count number of variables in statement */
            at = ap_strchr_c(statement,'%');
            while (at != NULL) {
                if (at[1] == '%') {
                    at++;
                }
                else {
                    need++;
                }
                at = ap_strchr_c(at+1,'%');
            }
            
            
            db = lua_get_db_handle(L);
            rc = apr_dbd_prepare(db->driver, r->pool, db->handle, statement, 
                        NULL, &pstatement);
            if (rc != APR_SUCCESS) {
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                const char  *err = apr_dbd_error(db->driver, db->handle, rc);
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
                lua_pushnil(L);
                if (err) {
                    lua_pushstring(L, err);
                    return 2;
                }
                return 1;
            }
            
            /* Push the prepared statement table */
            lua_newtable(L);
            st = lua_newuserdata(L, sizeof(lua_db_prepared_statement));
            st->statement = pstatement;
            st->variables = need;
            st->db = db;
            
            lua_pushliteral(L, "select");
            lua_pushcfunction(L, lua_db_prepared_select);
            lua_rawset(L, -4);
            lua_pushliteral(L, "query");
            lua_pushcfunction(L, lua_db_prepared_query);
            lua_rawset(L, -4);
            lua_rawseti(L, -2, 0);
            return 1;
        }
        return 0;
    }
    
    
    
    /*
       =============================================================================
        db:prepared(statement): Fetches a prepared statement made through 
        DBDPrepareSQL.
       =============================================================================
     */
    int lua_db_prepared(lua_State* L) 
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        lua_db_handle   *db = 0;
        const char      *tag;
        request_rec     *r;
        lua_db_prepared_statement* st;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        
        r = ap_lua_check_request_rec(L, 2);
        if (r) {
            apr_dbd_prepared_t *pstatement = NULL;
            db = lua_get_db_handle(L);
            luaL_checktype(L, 3, LUA_TSTRING);
            tag = lua_tostring(L, 3);
            
            /* Look for the statement */
            pstatement = apr_hash_get(db->dbdhandle->prepared, tag, 
                    APR_HASH_KEY_STRING);
            
            if (pstatement == NULL) {
                lua_pushnil(L);
                lua_pushfstring(L, 
                        "Could not find any prepared statement called %s!", tag);
                return 2;
            }
            
            
            /* Push the prepared statement table */
            lua_newtable(L);
            st = lua_newuserdata(L, sizeof(lua_db_prepared_statement));
            st->statement = pstatement;
            st->variables = -1; /* we don't know :( */
            st->db = db;
            lua_pushliteral(L, "select");
            lua_pushcfunction(L, lua_db_prepared_select);
            lua_rawset(L, -4);
            lua_pushliteral(L, "query");
            lua_pushcfunction(L, lua_db_prepared_query);
            lua_rawset(L, -4);
            lua_rawseti(L, -2, 0);
            return 1;
        }
        return 0;
    }
    
    
    
    /* lua_push_db_handle: Creates a database table object with database functions 
       and a userdata at index 0, which will call lua_dbgc when garbage collected.
     */
    static lua_db_handle* lua_push_db_handle(lua_State *L, request_rec* r, int type,
            apr_pool_t* pool) 
    {
        lua_db_handle* db;
        lua_newtable(L);
        db = lua_newuserdata(L, sizeof(lua_db_handle));
        db->alive = 1;
        db->pool = pool;
        db->type = type;
        db->dbdhandle = 0;
        db->server = r->server;
        luaL_newmetatable(L, "lua_apr.dbacquire");
        lua_pushliteral(L, "__gc");
        lua_pushcfunction(L, lua_db_gc);
        lua_rawset(L, -3);
        lua_setmetatable(L, -2);
        lua_rawseti(L, -2, 0);
        
        lua_pushliteral(L, "escape");
        lua_pushcfunction(L, lua_db_escape);
        lua_rawset(L, -3);
        
        lua_pushliteral(L, "close");
        lua_pushcfunction(L, lua_db_close);
        lua_rawset(L, -3);
        
        lua_pushliteral(L, "select");
        lua_pushcfunction(L, lua_db_select);
        lua_rawset(L, -3);
        
        lua_pushliteral(L, "query");
        lua_pushcfunction(L, lua_db_query);
        lua_rawset(L, -3);
        
        lua_pushliteral(L, "active");
        lua_pushcfunction(L, lua_db_active);
        lua_rawset(L, -3);
        
        lua_pushliteral(L, "prepare");
        lua_pushcfunction(L, lua_db_prepare);
        lua_rawset(L, -3);
        
        lua_pushliteral(L, "prepared");
        lua_pushcfunction(L, lua_db_prepared);
        lua_rawset(L, -3);
        return db;
    }
    
    /*
       =============================================================================
        dbacquire(dbType, dbString): Opens a new connection to a database of type 
        _dbType_ and with the connection parameters _dbString_. If successful, 
        returns a table with functions for using the database handle. If an error 
        occurs, returns nil as the first parameter and the error message as the 
        second. See the APR_DBD for a list of database types and connection strings 
        supported.
       =============================================================================
     */
    int lua_db_acquire(lua_State *L)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        const char      *type;
        const char      *arguments;
        const char      *error = 0;
        request_rec     *r;
        lua_db_handle   *db = 0;
        apr_status_t     rc = 0;
        ap_dbd_t        *dbdhandle = NULL;
        apr_pool_t      *pool = NULL;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
        r = ap_lua_check_request_rec(L, 1);
        if (r) {
            type = luaL_optstring(L, 2, "mod_dbd"); /* Defaults to mod_dbd */
            
            if (!strcmp(type, "mod_dbd")) {
    
                lua_settop(L, 0);
                lua_ap_dbd_open = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_open);
                if (lua_ap_dbd_open)
                    dbdhandle = (ap_dbd_t *) lua_ap_dbd_open(
                            r->server->process->pool, r->server);
    
                if (dbdhandle) {
                    db = lua_push_db_handle(L, r, LUA_DBTYPE_MOD_DBD, dbdhandle->pool);
                    db->driver = dbdhandle->driver;
                    db->handle = dbdhandle->handle;
                    db->dbdhandle = dbdhandle;
                    return 1;
                }
                else {
                    lua_pushnil(L);
                    if ( lua_ap_dbd_open == NULL )
                        lua_pushliteral(L,
                                        "mod_dbd doesn't seem to have been loaded.");
                    else
                        lua_pushliteral(
                            L,
                            "Could not acquire connection from mod_dbd. If your database is running, this may indicate a permission problem.");
                    return 2;
                }
            }
            else {
                rc = apr_pool_create(&pool, NULL);
                if (rc != APR_SUCCESS) {
                    lua_pushnil(L);
                    lua_pushliteral(L, "Could not allocate memory for database!");
                    return 2;
                }
                apr_pool_tag(pool, "lua_dbd_pool");
                apr_dbd_init(pool);
                dbdhandle = apr_pcalloc(pool, sizeof(ap_dbd_t));
                rc = apr_dbd_get_driver(pool, type, &dbdhandle->driver);
                if (rc == APR_SUCCESS) {
                    luaL_checktype(L, 3, LUA_TSTRING);
                    arguments = lua_tostring(L, 3);
                    lua_settop(L, 0);
                    
                    if (*arguments) {
                        rc = apr_dbd_open_ex(dbdhandle->driver, pool, 
                                arguments, &dbdhandle->handle, &error);
                        if (rc == APR_SUCCESS) {
                            db = lua_push_db_handle(L, r, LUA_DBTYPE_APR_DBD, pool);
                            db->driver = dbdhandle->driver;
                            db->handle = dbdhandle->handle;
                            db->dbdhandle = dbdhandle;
                            return 1;
                        }
                        else {
                            lua_pushnil(L);
                            if (error) {
                                lua_pushstring(L, error);
                                return 2;
                            }
    
                            return 1;
                        }
                    }
    
                    lua_pushnil(L);
                    lua_pushliteral(L,
                                    "No database connection string was specified.");
                    apr_pool_destroy(pool);
                    return (2);
                }
                else {
                    lua_pushnil(L);
                    if (APR_STATUS_IS_ENOTIMPL(rc)) {
                        lua_pushfstring(L, 
                             "driver for %s not available", type);
                    }
                    else if (APR_STATUS_IS_EDSOOPEN(rc)) {
                        lua_pushfstring(L, 
                                    "can't find driver for %s", type);
                    }
                    else if (APR_STATUS_IS_ESYMNOTFOUND(rc)) {
                        lua_pushfstring(L, 
                                    "driver for %s is invalid or corrupted",
                                    type);
                    }
                    else {
                        lua_pushliteral(L, 
                                    "mod_lua not compatible with APR in get_driver");
                    }
                    lua_pushinteger(L, rc);
                    apr_pool_destroy(pool);
                    return 3;
                }
            }
    
            lua_pushnil(L);
            return 1;
        }
    
        return 0;
    }
    
    ������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_apr.h������������������������������������������������������������������0000664�0001751�0001751�00000002322�12315507465�016656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _LUA_APR_H_
    #define _LUA_APR_H_
    
    #include "scoreboard.h"
    #include "http_main.h"
    #include "ap_mpm.h"
    #include "apr_md5.h"
    #include "apr_sha1.h"
    #include "apr_poll.h"
    #include "apr.h"
    #include "apr_tables.h"
    #include "apr_base64.h"
    
    
    int ap_lua_init(lua_State *L, apr_pool_t * p);
    req_table_t *ap_lua_check_apr_table(lua_State *L, int index);
    void ap_lua_push_apr_table(lua_State *L, req_table_t *t);
    
    #endif /* !_LUA_APR_H_ */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_dbd.h������������������������������������������������������������������0000664�0001751�0001751�00000004044�12155362210�016615� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _LUA_DBD_H_
    #define _LUA_DBD_H_
    
    #include "mod_lua.h"
    #include "apr.h"
    #include "apr_dbd.h"
    #include "mod_dbd.h"
    
    #define LUA_DBTYPE_APR_DBD 0
    #define LUA_DBTYPE_MOD_DBD 1
    typedef struct
    {
        apr_dbd_t               *handle;
        const apr_dbd_driver_t  *driver;
        int                     alive;
        apr_pool_t              *pool;
        char                    type;
        ap_dbd_t *              dbdhandle;
        server_rec              *server;
    } lua_db_handle;
    
    typedef struct {
        const apr_dbd_driver_t  *driver;
        int                     rows;
        int                     cols;
        apr_dbd_results_t       *results;
        apr_pool_t              *pool;
    } lua_db_result_set;
    
    typedef struct {
        apr_dbd_prepared_t      *statement;
        int                     variables;
        lua_db_handle           *db;
    } lua_db_prepared_statement;
    
    int lua_db_acquire(lua_State* L);
    int lua_db_escape(lua_State* L);
    int lua_db_close(lua_State* L);
    int lua_db_prepare(lua_State* L);
    int lua_db_prepared(lua_State* L);
    int lua_db_select(lua_State* L);
    int lua_db_query(lua_State* L);
    int lua_db_prepared_select(lua_State* L);
    int lua_db_prepared_query(lua_State* L);
    int lua_db_get_row(lua_State* L);
    int lua_db_gc(lua_State* L);
    int lua_db_active(lua_State* L);
    
    #endif /* !_LUA_DBD_H_ */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/mod_lua.dep����������������������������������������������������������������0000664�0001751�0001751�00000035220�12674411515�017175� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_lua.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\lua_apr.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_sha1.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\lua_apr.h"\
    	".\lua_request.h"\
    	".\lua_vmprep.h"\
    	".\mod_lua.h"\
    	
    
    .\lua_config.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\lua_config.h"\
    	".\lua_request.h"\
    	".\lua_vmprep.h"\
    	".\mod_lua.h"\
    	
    
    .\lua_dbd.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbd.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\database\mod_dbd.h"\
    	".\lua_dbd.h"\
    	".\lua_request.h"\
    	".\lua_vmprep.h"\
    	".\mod_lua.h"\
    	
    
    .\lua_passwd.c : \
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_sha1.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr-util\include\apu_version.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\lua_passwd.h"\
    	
    
    .\lua_request.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_cookies.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_md5.h"\
    	"..\..\include\util_script.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_dbd.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_sha1.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr-util\include\apu_version.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\database\mod_dbd.h"\
    	".\lua_apr.h"\
    	".\lua_dbd.h"\
    	".\lua_passwd.h"\
    	".\lua_request.h"\
    	".\lua_vmprep.h"\
    	".\mod_lua.h"\
    	
    
    .\lua_vmprep.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\lua_config.h"\
    	".\lua_request.h"\
    	".\lua_vmprep.h"\
    	".\mod_lua.h"\
    	
    
    .\mod_lua.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_sha1.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\ssl\mod_ssl.h"\
    	".\lua_apr.h"\
    	".\lua_config.h"\
    	".\lua_request.h"\
    	".\lua_vmprep.h"\
    	".\mod_lua.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_passwd.c���������������������������������������������������������������0000664�0001751�0001751�00000012134�12155674011�017364� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "lua_passwd.h"
    #include "apr_strings.h"
    #include "apr_errno.h"
    
    #if APR_HAVE_STDIO_H
    #include <stdio.h>
    #endif
    
    #include "apr_md5.h"
    #include "apr_sha1.h"
    
    #if APR_HAVE_TIME_H
    #include <time.h>
    #endif
    #if APR_HAVE_CRYPT_H
    #include <crypt.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_STRING_H
    #include <string.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if APR_HAVE_IO_H
    #include <io.h>
    #endif
    
    static int generate_salt(char *s, size_t size, const char **errstr,
                             apr_pool_t *pool)
    {
        unsigned char rnd[32];
        static const char itoa64[] =
            "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        apr_size_t n;
        unsigned int val = 0, bits = 0;
        apr_status_t rv;
    
        n = (size * 6 + 7)/8;
        if (n > sizeof(rnd)) {
            *errstr = apr_psprintf(pool, "generate_salt(): BUG: Buffer too small");
            return ERR_RANDOM;
        }
        rv = apr_generate_random_bytes(rnd, n);
        if (rv) {
            *errstr = apr_psprintf(pool, "Unable to generate random bytes: %pm",
                                   &rv);
            return ERR_RANDOM;
        }
        n = 0;
        while (size > 0) {
            if (bits < 6) {
                val |= (rnd[n++] << bits);
                bits += 8;
            }
            *s++ = itoa64[val & 0x3f];
            size--;
            val >>= 6;
            bits -= 6;
       }
       *s = '\0';
       return 0;
    }
    
    /*
     * Make a password record from the given information.  A zero return
     * indicates success; on failure, ctx->errstr points to the error message.
     */
    int mk_password_hash(passwd_ctx *ctx)
    {
        char *pw;
        char salt[16];
        apr_status_t rv;
        int ret = 0;
    #if CRYPT_ALGO_SUPPORTED
        char *cbuf;
    #endif
    
        pw = ctx->passwd;
        switch (ctx->alg) {
        case ALG_APSHA:
            /* XXX out >= 28 + strlen(sha1) chars - fixed len SHA */
            apr_sha1_base64(pw, strlen(pw), ctx->out);
            break;
    
        case ALG_APMD5:
            ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
            if (ret != 0) {
                ret = ERR_GENERAL;
                break;
            }
            rv = apr_md5_encode(pw, salt, ctx->out, ctx->out_len);
            if (rv != APR_SUCCESS) {
                ctx->errstr = apr_psprintf(ctx->pool,
                                           "could not encode password: %pm", &rv);
                ret = ERR_GENERAL;
            }
            break;
    
    #if CRYPT_ALGO_SUPPORTED
        case ALG_CRYPT:
            ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
            if (ret != 0)
                break;
            cbuf = crypt(pw, salt);
            if (cbuf == NULL) {
                rv = APR_FROM_OS_ERROR(errno);
                ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
                ret = ERR_PWMISMATCH;
                break;
            }
    
            apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
            if (strlen(pw) > 8) {
                char *truncpw = apr_pstrdup(ctx->pool, pw);
                truncpw[8] = '\0';
                if (!strcmp(ctx->out, crypt(truncpw, salt))) {
                    ctx->errstr = apr_psprintf(ctx->pool,
                                               "Warning: Password truncated to 8 "
                                               "characters by CRYPT algorithm.");
                }
                memset(truncpw, '\0', strlen(pw));
            }
            break;
    #endif /* CRYPT_ALGO_SUPPORTED */
    
    #if BCRYPT_ALGO_SUPPORTED
        case ALG_BCRYPT:
            rv = apr_generate_random_bytes((unsigned char*)salt, 16);
            if (rv != APR_SUCCESS) {
                ctx->errstr = apr_psprintf(ctx->pool, "Unable to generate random "
                                           "bytes: %pm", &rv);
                ret = ERR_RANDOM;
                break;
            }
    
            if (ctx->cost == 0)
                ctx->cost = BCRYPT_DEFAULT_COST;
            rv = apr_bcrypt_encode(pw, ctx->cost, (unsigned char*)salt, 16,
                                   ctx->out, ctx->out_len);
            if (rv != APR_SUCCESS) {
                ctx->errstr = apr_psprintf(ctx->pool, "Unable to encode with "
                                           "bcrypt: %pm", &rv);
                ret = ERR_PWMISMATCH;
                break;
            }
            break;
    #endif /* BCRYPT_ALGO_SUPPORTED */
    
        default:
            ctx->errstr = apr_psprintf(ctx->pool,
                                      "mk_password_hash(): unsupported algorithm %d",
                                      ctx->alg);
            ret = ERR_GENERAL;
        }
        memset(pw, '\0', strlen(pw));
        return ret;
    }
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/lua_vmprep.h���������������������������������������������������������������0000664�0001751�0001751�00000010315�12155362210�017373� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "lua.h"
    #include "lauxlib.h"
    #include "lualib.h"
    
    #include "httpd.h"
    
    #include "apr_thread_rwlock.h"
    #include "apr_strings.h"
    #include "apr_tables.h"
    #include "apr_hash.h"
    #include "apr_buckets.h"
    #include "apr_file_info.h"
    #include "apr_time.h"
    #include "apr_pools.h"
    #include "apr_reslist.h"
    
    
    #ifndef VMPREP_H
    #define VMPREP_H
    
    #define AP_LUA_SCOPE_UNSET         0
    #define AP_LUA_SCOPE_ONCE          1
    #define AP_LUA_SCOPE_REQUEST       2
    #define AP_LUA_SCOPE_CONN          3
    #define AP_LUA_SCOPE_THREAD        4
    #define AP_LUA_SCOPE_SERVER        5
    
    #define AP_LUA_CACHE_UNSET         0
    #define AP_LUA_CACHE_NEVER         1
    #define AP_LUA_CACHE_STAT          2
    #define AP_LUA_CACHE_FOREVER       3
    
    #define AP_LUA_FILTER_INPUT        1
    #define AP_LUA_FILTER_OUTPUT       2
    
    typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p,
                                                 void *ctx);
    /**
     * Specification for a lua virtual machine
     */
    typedef struct
    {
        /* NEED TO ADD ADDITIONAL PACKAGE PATHS AS PART OF SPEC INSTEAD OF DIR CONFIG */
        apr_array_header_t *package_paths;
        apr_array_header_t *package_cpaths;
    
        /* name of base file to load in the vm */
        const char *file;
    
        /* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_THREAD | APL_SCOPE_SERVER */
        int scope;
        unsigned int vm_min;
        unsigned int vm_max;
    
        ap_lua_state_open_callback cb;
        void* cb_arg;
    
        /* pool to use for lifecycle if APL_SCOPE_ONCE is set, otherwise unused */
        apr_pool_t *pool;
    
        /* Pre-compiled Lua Byte code to load directly.  If bytecode_len is >0,
         * the file part of this structure is ignored for loading purposes, but
         * it is used for error messages.
         */
        const char *bytecode;
        apr_size_t bytecode_len;
        
        int codecache;
    } ap_lua_vm_spec;
    
    typedef struct
    {
        const char *function_name;
        const char *file_name;
        int scope;
        ap_regex_t *uri_pattern;
        const char *bytecode;
        apr_size_t bytecode_len;
        int codecache;
    } ap_lua_mapped_handler_spec;
    
    typedef struct
    {
        const char *function_name;
        const char *file_name;
        const char* filter_name;
        int         direction; /* AP_LUA_FILTER_INPUT | AP_LUA_FILTER_OUTPUT */
    } ap_lua_filter_handler_spec;
    
    typedef struct {
        apr_size_t runs;
        apr_time_t modified;
        apr_off_t  size;
    } ap_lua_finfo;
    
    typedef struct {
        lua_State* L;
        ap_lua_finfo* finfo;
    } ap_lua_server_spec;
    
    /**
     * Fake out addition of the "apache2" module
     */
    void ap_lua_load_apache2_lmodule(lua_State *L);
    
    /*
     * alternate means of getting lua_State (preferred eventually)
     * Obtain a lua_State which has loaded file and is associated with lifecycle_pool
     * If one exists, will return extant one, otherwise will create, attach, and return
     * This does no locking around the lua_State, so if the pool is shared between
     * threads, locking is up the client.
     *
     * @lifecycle_pool -> pool whose lifeycle controls the lua_State
     * @file file to be opened, also used as a key for uniquing lua_States
     * @cb callback for vm initialization called *before* the file is opened
     * @ctx a baton passed to cb
     */
    lua_State *ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
                                                    ap_lua_vm_spec *spec, request_rec* r);
    
    #if APR_HAS_THREADS || defined(DOXYGEN)
    /*
     * Initialize mod_lua mutex.
     * @pool pool for mutex
     * @s server_rec for logging
     */
    void ap_lua_init_mutex(apr_pool_t *pool, server_rec *s);
    #endif
    
    #endif
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/lua/Makefile.in����������������������������������������������������������������0000664�0001751�0001751�00000000267�11737125415�017133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/�������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015347� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/cache_storage.c����������������������������������������������������������0000664�0001751�0001751�00000070502�13514075260�020277� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_cache.h"
    
    #include "cache_storage.h"
    #include "cache_util.h"
    
    APLOG_USE_MODULE(cache);
    
    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(cache_request_rec *cache, request_rec *r)
    {
        cache_provider_list *list;
        cache_handle_t *h;
    
        list = cache->providers;
    
        /* Remove the stale cache entry if present. If not, we're
         * being called from outside of a request; remove the
         * non-stale handle.
         */
        h = cache->stale_handle ? cache->stale_handle : cache->handle;
        if (!h) {
           return OK;
        }
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00691)
                     "cache: Removing url %s from the cache", h->cache_obj->key);
    
        /* for each specified cache type, delete the URL */
        while (list) {
            list->provider->remove_url(h, r);
            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(cache_request_rec *cache, request_rec *r,
                            apr_off_t size, apr_bucket_brigade *in)
    {
        cache_provider_list *list;
        cache_handle_t *h = apr_pcalloc(r->pool, sizeof(cache_handle_t));
        apr_status_t rv;
    
        if (!cache) {
            /* This should never happen */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, APLOGNO(00692)
                    "cache: No cache request information available for key"
                    " generation");
            return APR_EGENERAL;
        }
    
        if (!cache->key) {
            rv = cache_generate_key(r, r->pool, &cache->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, cache->key, size, in)) {
            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 filter_header_do(void *v, const char *key, const char *val)
    {
        if ((*key == 'W' || *key == 'w') && !ap_cstr_casecmp(key, "Warning")
                && *val == '1') {
            /* any stored Warning headers with warn-code 1xx (see section
             * 14.46) MUST be deleted from the cache entry and the forwarded
             * response.
             */
        }
        else {
            apr_table_addn(v, key, val);
        }
        return 1;
    }
    static int remove_header_do(void *v, const char *key, const char *val)
    {
        if ((*key == 'W' || *key == 'w') && !ap_cstr_casecmp(key, "Warning")) {
            /* any stored Warning headers with warn-code 2xx MUST be retained
             * in the cache entry and the forwarded response.
             */
        }
        else {
            apr_table_unset(v, key);
        }
        return 1;
    }
    static int add_header_do(void *v, const char *key, const char *val)
    {
        apr_table_addn(v, key, val);
        return 1;
    }
    
    /**
     * Take two sets of headers, sandwich them together, and apply the result to
     * r->headers_out.
     *
     * To complicate this, a header may be duplicated in either table. Should a
     * header exist in the top table, all matching headers will be removed from
     * the bottom table before the headers are combined. The Warning headers are
     * handled specially. Warnings are added rather than being replaced, while
     * in the case of revalidation 1xx Warnings are stripped.
     *
     * The Content-Type and Last-Modified headers are then re-parsed and inserted
     * into the request.
     */
    void cache_accept_headers(cache_handle_t *h, request_rec *r, apr_table_t *top,
            apr_table_t *bottom, int revalidation)
    {
        const char *v;
    
        if (revalidation) {
            r->headers_out = apr_table_make(r->pool, 10);
            apr_table_do(filter_header_do, r->headers_out, bottom, NULL);
        }
        else if (r->headers_out != bottom) {
            r->headers_out = apr_table_copy(r->pool, bottom);
        }
        apr_table_do(remove_header_do, r->headers_out, top, NULL);
        apr_table_do(add_header_do, r->headers_out, top, NULL);
    
        v = apr_table_get(r->headers_out, "Content-Type");
        if (v) {
            ap_set_content_type(r, v);
            /*
             * Also unset possible Content-Type headers in r->headers_out and
             * r->err_headers_out as they may be different to what we have received
             * from the cache.
             * Actually they are not needed as r->content_type set by
             * ap_set_content_type above will be used in the store_headers functions
             * of the storage providers as a fallback and the HTTP_HEADER filter
             * does overwrite the Content-Type header with r->content_type anyway.
             */
            apr_table_unset(r->headers_out, "Content-Type");
            apr_table_unset(r->err_headers_out, "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(r->headers_out, "Last-Modified");
        if (v) {
            ap_update_mtime(r, apr_date_parse_http(v));
            ap_set_last_modified(r);
        }
    
    }
    
    /*
     * 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(cache_request_rec *cache, request_rec *r)
    {
        cache_provider_list *list;
        apr_status_t rv;
        cache_handle_t *h;
    
        if (!cache) {
            /* This should never happen */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, APLOGNO(00693)
                    "cache: No cache request information available for key"
                    " generation");
            return DECLINED;
        }
    
        /* if no-cache, we can't serve from the cache, but we may store to the
         * cache.
         */
        if (!ap_cache_check_no_cache(cache, r)) {
            return DECLINED;
        }
    
        if (!cache->key) {
            rv = cache_generate_key(r, r->pool, &cache->key);
            if (rv != APR_SUCCESS) {
                return DECLINED;
            }
        }
    
        /* 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, cache->key))) {
            case OK: {
                char *vary = NULL;
                int mismatch = 0;
                char *last = NULL;
    
                if (list->provider->recall_headers(h, r) != APR_SUCCESS) {
                    /* try again with next cache type */
                    list = list->next;
                    continue;
                }
    
                /*
                 * 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 = cache_strqtok(
                        apr_pstrdup(r->pool,
                                cache_table_getm(r->pool, h->resp_hdrs, "Vary")),
                        CACHE_SEPARATOR, &last);
                while (vary) {
                    const char *h1, *h2;
    
                    /*
                     * 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 = cache_table_getm(r->pool, r->headers_in, vary);
                    h2 = cache_table_getm(r->pool, h->req_hdrs, vary);
                    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_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                                r, APLOGNO(00694) "cache_select(): Vary header mismatch.");
                        mismatch = 1;
                        break;
                    }
                    vary = cache_strqtok(NULL, CACHE_SEPARATOR, &last);
                }
    
                /* no vary match, try next provider */
                if (mismatch) {
                    /* try again with next cache type */
                    list = list->next;
                    continue;
                }
    
                cache->provider = list->provider;
                cache->provider_name = list->provider_name;
    
                /*
                 * RFC2616 13.3.4 Rules for When to Use Entity Tags and Last-Modified
                 * Dates: An HTTP/1.1 caching proxy, upon receiving a conditional request
                 * that includes both a Last-Modified date and one or more entity tags as
                 * cache validators, MUST NOT return a locally cached response to the
                 * client unless that cached response is consistent with all of the
                 * conditional header fields in the request.
                 */
                if (ap_condition_if_match(r, h->resp_hdrs) == AP_CONDITION_NOMATCH
                        || ap_condition_if_unmodified_since(r, h->resp_hdrs)
                                == AP_CONDITION_NOMATCH
                        || ap_condition_if_none_match(r, h->resp_hdrs)
                                == AP_CONDITION_NOMATCH
                        || ap_condition_if_modified_since(r, h->resp_hdrs)
                                == AP_CONDITION_NOMATCH
                        || ap_condition_if_range(r, h->resp_hdrs) == AP_CONDITION_NOMATCH) {
                    mismatch = 1;
                }
    
                /* Is our cached response fresh enough? */
                if (mismatch || !cache_check_freshness(h, cache, r)) {
                    const char *etag, *lastmod;
    
                    /* Cache-Control: only-if-cached and revalidation required, try
                     * the next provider
                     */
                    if (cache->control_in.only_if_cached) {
                        /* try again with next cache type */
                        list = list->next;
                        continue;
                    }
    
                    /* set aside the stale entry for accessing later */
                    cache->stale_headers = apr_table_copy(r->pool,
                            r->headers_in);
                    cache->stale_handle = h;
    
                    /* if no existing conditionals, use conditionals of our own */
                    if (!mismatch) {
    
                        ap_log_rerror(
                                APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00695) "Cached response for %s isn't fresh. Adding "
                                "conditional request headers.", r->uri);
    
                        /* Remove existing conditionals that might conflict with ours */
                        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);
                            }
    
                            /*
                             * Do not do Range requests with our own conditionals: If
                             * we get 304 the Range does not matter and otherwise the
                             * entity changed and we want to have the complete entity
                             */
                            apr_table_unset(r->headers_in, "Range");
    
                        }
    
                    }
    
                    /* ready to revalidate, pretend we were never here */
                    return DECLINED;
                }
    
                /* Okay, this response looks okay.  Merge in our stuff and go. */
                cache_accept_headers(h, r, h->resp_hdrs, r->headers_out, 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;
            }
            }
        }
    
        /* if Cache-Control: only-if-cached, and not cached, return 504 */
        if (cache->control_in.only_if_cached) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00696)
                    "cache: 'only-if-cached' requested and no cached entity, "
                    "returning 504 Gateway Timeout for: %s", r->uri);
            return HTTP_GATEWAY_TIME_OUT;
        }
    
        return DECLINED;
    }
    
    static apr_status_t cache_canonicalise_key(request_rec *r, apr_pool_t* p,
                                               const char *path, const char *query,
                                               apr_uri_t *parsed_uri,
                                               const char **key)
    {
        cache_server_conf *conf;
        char *port_str, *hn, *lcs;
        const char *hostname, *scheme;
        int i;
        const char *kpath;
        const char *kquery;
    
        if (*key) {
            /*
             * We have been here before during the processing of this request.
             */
            return APR_SUCCESS;
        }
    
        /*
         * Get the module configuration. We need this for the CacheIgnoreQueryString
         * option below.
         */
        conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
                &cache_module);
    
        /*
         * Use the canonical name to improve cache hit rate, but only if this is
         * not a proxy request or if this is a reverse proxy request.
         * We need to handle both cases in the same manner as for the reverse proxy
         * case we have the following situation:
         *
         * If a cached entry is looked up by mod_cache's quick handler r->proxyreq
         * is still unset in the reverse proxy case as it only gets set in the
         * translate name hook (either by ProxyPass or mod_rewrite) which is run
         * after the quick handler hook. This is different to the forward proxy
         * case where it gets set before the quick handler is run (in the
         * post_read_request hook).
         * If a cache entry is created by the CACHE_SAVE filter we always have
         * r->proxyreq set correctly.
         * So we must ensure that in the reverse proxy case we use the same code
         * path and using the canonical name seems to be the right thing to do
         * in the reverse proxy case.
         */
        if (!r->proxyreq || (r->proxyreq == PROXYREQ_REVERSE)) {
            if (conf->base_uri && conf->base_uri->hostname) {
                hostname = conf->base_uri->hostname;
            }
            else {
                /* Use _default_ as the hostname if none present, as in mod_vhost */
                hostname = ap_get_server_name(r);
                if (!hostname) {
                    hostname = "_default_";
                }
            }
        }
        else if (parsed_uri->hostname) {
            /* Copy the parsed uri hostname */
            hn = apr_pstrdup(p, parsed_uri->hostname);
            ap_str_tolower(hn);
            /* const work-around */
            hostname = hn;
        }
        else {
            /* We are a proxied request, with no hostname. Unlikely
             * to get very far - but just in case */
            hostname = "_default_";
        }
    
        /*
         * Copy the scheme, ensuring that it is lower case. If the parsed uri
         * contains no string or if this is not a proxy request get the http
         * scheme for this request. As r->parsed_uri.scheme is not set if this
         * is a reverse proxy request, it is ensured that the cases
         * "no proxy request" and "reverse proxy request" are handled in the same
         * manner (see above why this is needed).
         */
        if (r->proxyreq && parsed_uri->scheme) {
            /* Copy the scheme and lower-case it */
            lcs = apr_pstrdup(p, parsed_uri->scheme);
            ap_str_tolower(lcs);
            /* const work-around */
            scheme = lcs;
        }
        else {
            if (conf->base_uri && conf->base_uri->scheme) {
                scheme = conf->base_uri->scheme;
            }
            else {
                scheme = ap_http_scheme(r);
            }
        }
    
        /*
         * If this is a proxy request, but not a reverse proxy request (see comment
         * above why these cases must be handled in the same manner), copy the
         * URI's port-string (which may be a service name). If the URI contains
         * no port-string, use apr-util's notion of the default port for that
         * scheme - if available. Otherwise use the port-number of the current
         * server.
         */
        if (r->proxyreq && (r->proxyreq != PROXYREQ_REVERSE)) {
            if (parsed_uri->port_str) {
                port_str = apr_pcalloc(p, strlen(parsed_uri->port_str) + 2);
                port_str[0] = ':';
                for (i = 0; parsed_uri->port_str[i]; i++) {
                    port_str[i + 1] = apr_tolower(parsed_uri->port_str[i]);
                }
            }
            else if (apr_uri_port_of_scheme(scheme)) {
                port_str = apr_psprintf(p, ":%u", apr_uri_port_of_scheme(scheme));
            }
            else {
                /* No port string given in the AbsoluteUri, and we have no
                 * idea what the default port for the scheme is. Leave it
                 * blank and live with the inefficiency of some extra cached
                 * entities.
                 */
                port_str = "";
            }
        }
        else {
            if (conf->base_uri && conf->base_uri->port_str) {
                port_str = apr_pstrcat(p, ":", conf->base_uri->port_str, NULL);
            }
            else if (conf->base_uri && conf->base_uri->hostname) {
                port_str = "";
            }
            else {
                /* Use the server port */
                port_str = apr_psprintf(p, ":%u", ap_get_server_port(r));
            }
        }
    
        /*
         * Check if we need to ignore session identifiers in the URL and do so
         * if needed.
         */
        kpath = path;
        kquery = conf->ignorequerystring ? NULL : query;
        if (conf->ignore_session_id->nelts) {
            int i;
            char **identifier;
    
            identifier = (char **) conf->ignore_session_id->elts;
            for (i = 0; i < conf->ignore_session_id->nelts; i++, identifier++) {
                int len;
                const char *param;
    
                len = strlen(*identifier);
                /*
                 * Check that we have a parameter separator in the last segment
                 * of the path and that the parameter matches our identifier
                 */
                if ((param = ap_strrchr_c(kpath, ';'))
                        && !strncmp(param + 1, *identifier, len)
                        && (*(param + len + 1) == '=')
                        && !ap_strchr_c(param + len + 2, '/')) {
                    kpath = apr_pstrmemdup(p, kpath, param - kpath);
                    continue;
                }
                /*
                 * Check if the identifier is in the query string and cut it out.
                 */
                if (kquery && *kquery) {
                    /*
                     * First check if the identifier is at the beginning of the
                     * query string and followed by a '='
                     */
                    if (!strncmp(kquery, *identifier, len) && kquery[len] == '=') {
                        param = kquery;
                    }
                    else {
                        char *complete;
    
                        /*
                         * In order to avoid subkey matching (PR 48401) prepend
                         * identifier with a '&' and append a '='
                         */
                        complete = apr_pstrcat(p, "&", *identifier, "=", NULL);
                        param = ap_strstr_c(kquery, complete);
                        /* If we found something we are sitting on the '&' */
                        if (param) {
                            param++;
                        }
                    }
                    if (param) {
                        const char *amp;
                        char *dup = NULL;
    
                        if (kquery != param) {
                            dup = apr_pstrmemdup(p, kquery, param - kquery);
                            kquery = dup;
                        }
                        else {
                            kquery = "";
                        }
    
                        if ((amp = ap_strchr_c(param + len + 1, '&'))) {
                            kquery = apr_pstrcat(p, kquery, amp + 1, NULL);
                        }
                        else {
                            /*
                             * If query string is not "", then we have the case
                             * that the identifier parameter we removed was the
                             * last one in the original query string. Hence we have
                             * a trailing '&' which needs to be removed.
                             */
                            if (dup) {
                                dup[strlen(dup) - 1] = '\0';
                            }
                        }
                    }
                }
            }
        }
    
        /* Key format is a URI, optionally without the query-string (NULL
         * per above if conf->ignorequerystring)
         */
        *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
                           kpath, "?", kquery, NULL);
    
        /*
         * Store the key in the request_config for the cache as r->parsed_uri
         * might have changed in the time from our first visit here triggered by the
         * quick handler and our possible second visit triggered by the CACHE_SAVE
         * filter (e.g. r->parsed_uri got unescaped). In this case we would save the
         * resource in the cache under a key where it is never found by the quick
         * handler during following requests.
         */
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00698)
                      "cache: Key for entity %s?%s is %s", path, query, *key);
    
        return APR_SUCCESS;
    }
    
    apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p,
                                            const char **key)
    {
        /* In early processing (quick-handler, forward proxy), we want the initial
         * query-string from r->parsed_uri, since any change before CACHE_SAVE
         * shouldn't modify the key. Otherwise we want the actual query-string.
         */
        const char *path = r->uri;
        const char *query = r->args;
        if (cache_use_early_url(r)) {
            path = r->parsed_uri.path;
            query = r->parsed_uri.query;
        }
        return cache_canonicalise_key(r, p, path, query, &r->parsed_uri, key);
    }
    
    /*
     * Invalidate a specific URL entity in all caches
     *
     * All cached entities for this URL are removed, usually in
     * response to a POST/PUT or DELETE.
     *
     * This function returns OK if at least one entity was found and
     * removed, and DECLINED if no cached entities were removed.
     */
    int cache_invalidate(cache_request_rec *cache, request_rec *r)
    {
        cache_provider_list *list;
        apr_status_t rv, status = DECLINED;
        cache_handle_t *h;
        apr_uri_t location_uri;
        apr_uri_t content_location_uri;
    
        const char *location, *location_key = NULL;
        const char *content_location, *content_location_key = NULL;
    
        if (!cache) {
            /* This should never happen */
            ap_log_rerror(
                    APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, APLOGNO(00697) "cache: No cache request information available for key"
                    " generation");
            return DECLINED;
        }
    
        if (!cache->key) {
            rv = cache_generate_key(r, r->pool, &cache->key);
            if (rv != APR_SUCCESS) {
                return DECLINED;
            }
        }
    
        location = apr_table_get(r->headers_out, "Location");
        if (location) {
            if (apr_uri_parse(r->pool, location, &location_uri)
                    || cache_canonicalise_key(r, r->pool,
                                              location_uri.path,
                                              location_uri.query,
                                              &location_uri, &location_key)
                    || !(r->parsed_uri.hostname
                         && location_uri.hostname
                         && !strcmp(r->parsed_uri.hostname,
                                    location_uri.hostname))) {
                location_key = NULL;
            }
        }
    
        content_location = apr_table_get(r->headers_out, "Content-Location");
        if (content_location) {
            if (apr_uri_parse(r->pool, content_location,
                              &content_location_uri)
                    || cache_canonicalise_key(r, r->pool,
                                              content_location_uri.path,
                                              content_location_uri.query,
                                              &content_location_uri,
                                              &content_location_key)
                    || !(r->parsed_uri.hostname
                         && content_location_uri.hostname
                         && !strcmp(r->parsed_uri.hostname,
                                    content_location_uri.hostname))) {
                content_location_key = NULL;
            }
        }
    
        /* go through the cache types */
        h = apr_palloc(r->pool, sizeof(cache_handle_t));
    
        list = cache->providers;
    
        while (list) {
    
            /* invalidate the request uri */
            rv = list->provider->open_entity(h, r, cache->key);
            if (OK == rv) {
                rv = list->provider->invalidate_entity(h, r);
                status = OK;
            }
            ap_log_rerror(
                    APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02468) "cache: Attempted to invalidate cached entity with key: %s", cache->key);
    
            /* invalidate the Location */
            if (location_key) {
                rv = list->provider->open_entity(h, r, location_key);
                if (OK == rv) {
                    rv = list->provider->invalidate_entity(h, r);
                    status = OK;
                }
                ap_log_rerror(
                        APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02469) "cache: Attempted to invalidate cached entity with key: %s", location_key);
            }
    
            /* invalidate the Content-Location */
            if (content_location_key) {
                rv = list->provider->open_entity(h, r, content_location_key);
                if (OK == rv) {
                    rv = list->provider->invalidate_entity(h, r);
                    status = OK;
                }
                ap_log_rerror(
                        APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02470) "cache: Attempted to invalidate cached entity with key: %s", content_location_key);
            }
    
            list = list->next;
        }
    
        return status;
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_redis.c������������������������������������������������������0000664�0001751�0001751�00000041567�13444157463�021163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
    * this work for additional information regarding copyright ownership.
    * The ASF licenses this file to You under the Apache License, Version 2.0
    * (the "License"); you may not use this file except in compliance with
    * the License.  You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT 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_protocol.h"
    
    #include "apr.h"
    #include "apu_version.h"
    
    #include "ap_socache.h"
    #include "ap_mpm.h"
    #include "http_log.h"
    #include "apr_strings.h"
    #include "mod_status.h"
    
    typedef struct {
        apr_uint32_t ttl;
        apr_uint32_t rwto;
    } socache_rd_svr_cfg;
    
    /* apr_redis support requires >= 1.6 */
    #if APU_MAJOR_VERSION > 1 || \
        (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION > 5)
    #define HAVE_APU_REDIS 1
    #endif
    
    /* The underlying apr_redis system is thread safe.. */
    #define RD_KEY_LEN 254
    
    #ifndef RD_DEFAULT_SERVER_PORT
    #define RD_DEFAULT_SERVER_PORT 6379
    #endif
    
    
    #ifndef RD_DEFAULT_SERVER_MIN
    #define RD_DEFAULT_SERVER_MIN 0
    #endif
    
    #ifndef RD_DEFAULT_SERVER_SMAX
    #define RD_DEFAULT_SERVER_SMAX 1
    #endif
    
    #ifndef RD_DEFAULT_SERVER_TTL
    #define RD_DEFAULT_SERVER_TTL    apr_time_from_sec(15)
    #endif
    
    #ifndef RD_DEFAULT_SERVER_RWTO
    #define RD_DEFAULT_SERVER_RWTO    apr_time_from_sec(5)
    #endif
    
    module AP_MODULE_DECLARE_DATA socache_redis_module;
    
    #ifdef HAVE_APU_REDIS
    #include "apr_redis.h"
    struct ap_socache_instance_t {
        const char *servers;
        apr_redis_t *rc;
        const char *tag;
        apr_size_t taglen; /* strlen(tag) + 1 */
    };
    
    static const char *socache_rd_create(ap_socache_instance_t **context,
                                         const char *arg,
                                         apr_pool_t *tmp, apr_pool_t *p)
    {
        ap_socache_instance_t *ctx;
    
        *context = ctx = apr_pcalloc(p, sizeof *ctx);
    
        if (!arg || !*arg) {
            return "List of server names required to create redis socache.";
        }
    
        ctx->servers = apr_pstrdup(p, arg);
    
        return NULL;
    }
    
    static apr_status_t socache_rd_init(ap_socache_instance_t *ctx,
                                        const char *namespace,
                                        const struct ap_socache_hints *hints,
                                        server_rec *s, apr_pool_t *p)
    {
        apr_status_t rv;
        int thread_limit = 0;
        apr_uint16_t nservers = 0;
        char *cache_config;
        char *split;
        char *tok;
    
        socache_rd_svr_cfg *sconf = ap_get_module_config(s->module_config,
                &socache_redis_module);
    
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
    
        /* Find all the servers in the first run to get a total count */
        cache_config = apr_pstrdup(p, ctx->servers);
        split = apr_strtok(cache_config, ",", &tok);
        while (split) {
            nservers++;
            split = apr_strtok(NULL,",", &tok);
        }
    
        rv = apr_redis_create(p, nservers, 0, &ctx->rc);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03473)
                         "Failed to create Redis Object of '%d' size.",
                         nservers);
            return rv;
        }
    
        /* Now add each server to the redis */
        cache_config = apr_pstrdup(p, ctx->servers);
        split = apr_strtok(cache_config, ",", &tok);
        while (split) {
            apr_redis_server_t *st;
            char *host_str;
            char *scope_id;
            apr_port_t port;
    
            rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03474)
                             "Failed to Parse redis Server: '%s'", split);
                return rv;
            }
    
            if (host_str == NULL) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03475)
                             "Failed to Parse Server, "
                             "no hostname specified: '%s'", split);
                return APR_EINVAL;
            }
    
            if (port == 0) {
                port = RD_DEFAULT_SERVER_PORT;
            }
    
            rv = apr_redis_server_create(p,
                                         host_str, port,
                                         RD_DEFAULT_SERVER_MIN,
                                         RD_DEFAULT_SERVER_SMAX,
                                         thread_limit,
                                         sconf->ttl,
                                         sconf->rwto,
                                         &st);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03476)
                             "Failed to Create redis Server: %s:%d",
                             host_str, port);
                return rv;
            }
    
            rv = apr_redis_add_server(ctx->rc, st);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03477)
                             "Failed to Add redis Server: %s:%d",
                             host_str, port);
                return rv;
            }
    
            split = apr_strtok(NULL,",", &tok);
        }
    
        ctx->tag = apr_pstrcat(p, namespace, ":", NULL);
        ctx->taglen = strlen(ctx->tag) + 1;
    
        /* socache API constraint: */
        AP_DEBUG_ASSERT(ctx->taglen <= 16);
    
        return APR_SUCCESS;
    }
    
    static void socache_rd_destroy(ap_socache_instance_t *context, server_rec *s)
    {
        /* noop. */
    }
    
    /* Converts (binary) id into a key prefixed by the predetermined
     * namespace tag; writes output to key buffer.  Returns non-zero if
     * the id won't fit in the key buffer. */
    static int socache_rd_id2key(ap_socache_instance_t *ctx,
                                 const unsigned char *id, unsigned int idlen,
                                 char *key, apr_size_t keylen)
    {
        char *cp;
    
        if (idlen * 2 + ctx->taglen >= keylen)
            return 1;
    
        cp = apr_cpystrn(key, ctx->tag, ctx->taglen);
        ap_bin2hex(id, idlen, cp);
    
        return 0;
    }
    
    static apr_status_t socache_rd_store(ap_socache_instance_t *ctx, server_rec *s,
                                         const unsigned char *id, unsigned int idlen,
                                         apr_time_t expiry,
                                         unsigned char *ucaData, unsigned int nData,
                                         apr_pool_t *p)
    {
        char buf[RD_KEY_LEN];
        apr_status_t rv;
        apr_uint32_t timeout;
    
        if (socache_rd_id2key(ctx, id, idlen, buf, sizeof(buf))) {
            return APR_EINVAL;
        }
        timeout = apr_time_sec(expiry - apr_time_now());
        if (timeout <= 0) {
            return APR_EINVAL;
        }
    
        rv = apr_redis_setex(ctx->rc, buf, (char*)ucaData, nData, timeout, 0);
    
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03478)
                         "scache_rd: error setting key '%s' "
                         "with %d bytes of data", buf, nData);
            return rv;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_rd_retrieve(ap_socache_instance_t *ctx, server_rec *s,
                                            const unsigned char *id, unsigned int idlen,
                                            unsigned char *dest, unsigned int *destlen,
                                            apr_pool_t *p)
    {
        apr_size_t data_len;
        char buf[RD_KEY_LEN], *data;
        apr_status_t rv;
    
        if (socache_rd_id2key(ctx, id, idlen, buf, sizeof buf)) {
            return APR_EINVAL;
        }
    
        /* ### this could do with a subpool, but _getp looks like it will
         * eat memory like it's going out of fashion anyway. */
    
        rv = apr_redis_getp(ctx->rc, p, buf, &data, &data_len, NULL);
        if (rv) {
            if (rv != APR_NOTFOUND) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(03479)
                             "scache_rd: 'retrieve' FAIL");
            }
            return rv;
        }
        else if (data_len > *destlen) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(03480)
                         "scache_rd: 'retrieve' OVERFLOW");
            return APR_ENOMEM;
        }
    
        memcpy(dest, data, data_len);
        *destlen = data_len;
    
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_rd_remove(ap_socache_instance_t *ctx, server_rec *s,
                                          const unsigned char *id,
                                          unsigned int idlen, apr_pool_t *p)
    {
        char buf[RD_KEY_LEN];
        apr_status_t rv;
    
        if (socache_rd_id2key(ctx, id, idlen, buf, sizeof buf)) {
            return APR_EINVAL;
        }
    
        rv = apr_redis_delete(ctx->rc, buf, 0);
    
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03481)
                         "scache_rd: error deleting key '%s' ",
                         buf);
        }
    
        return rv;
    }
    
    static void socache_rd_status(ap_socache_instance_t *ctx, request_rec *r, int flags)
    {
        apr_redis_t *rc = ctx->rc;
        int i;
    
        for (i = 0; i < rc->ntotal; i++) {
            apr_redis_server_t *rs;
            apr_redis_stats_t *stats;
            char *role;
            apr_status_t rv;
            char *br = (!(flags & AP_STATUS_SHORT) ? "<br />" : "");
    
            rs = rc->live_servers[i];
    
            ap_rprintf(r, "Redis server: %s:%d [%s]%s\n", rs->host, (int)rs->port,
                    (rs->status == APR_RC_SERVER_LIVE) ? "Up" : "Down",
                    br);
            rv = apr_redis_stats(rs, r->pool, &stats);
            if (rv != APR_SUCCESS)
                continue;
            if (!(flags & AP_STATUS_SHORT)) {
                ap_rprintf(r, "<b>General::</b> Version: <i>%u.%u.%u</i> [%u bits], PID: <i>%u</i>, Uptime: <i>%u hrs</i> <br />\n",
                         stats->major, stats->minor, stats->patch, stats->arch_bits,
                         stats->process_id, stats->uptime_in_seconds/3600);
                 ap_rprintf(r, "<b>Clients::</b> Connected: <i>%d</i>, Blocked: <i>%d</i> <br />\n",
                         stats->connected_clients, stats->blocked_clients);
                 ap_rprintf(r, "<b>Memory::</b> Total: <i>%" APR_UINT64_T_FMT "</i>, Max: <i>%" APR_UINT64_T_FMT "</i>, Used: <i>%" APR_UINT64_T_FMT "</i> <br />\n",
                         stats->total_system_memory, stats->maxmemory, stats->used_memory);
                 ap_rprintf(r, "<b>CPU::</b> System: <i>%u</i>, User: <i>%u</i><br />\n",
                         stats->used_cpu_sys, stats->used_cpu_user );
                 ap_rprintf(r, "<b>Connections::</b> Recd: <i>%" APR_UINT64_T_FMT "</i>, Processed: <i>%" APR_UINT64_T_FMT "</i>, Rejected: <i>%" APR_UINT64_T_FMT "</i> <br />\n",
                         stats->total_connections_received, stats->total_commands_processed,
                         stats->rejected_connections);
                 ap_rprintf(r, "<b>Cache::</b> Hits: <i>%" APR_UINT64_T_FMT "</i>, Misses: <i>%" APR_UINT64_T_FMT "</i> <br />\n",
                         stats->keyspace_hits, stats->keyspace_misses);
                 ap_rprintf(r, "<b>Net::</b> Input bytes: <i>%" APR_UINT64_T_FMT "</i>, Output bytes: <i>%" APR_UINT64_T_FMT "</i> <br />\n",
                         stats->total_net_input_bytes, stats->total_net_output_bytes);
                 if (stats->role == APR_RS_SERVER_MASTER)
                     role = "master";
                 else if (stats->role == APR_RS_SERVER_SLAVE)
                     role = "slave";
                 else
                     role = "unknown";
                 ap_rprintf(r, "<b>Misc::</b> Role: <i>%s</i>, Connected Slaves: <i>%u</i>, Is Cluster?: <i>%s</i> \n",
                         role, stats->connected_clients,
                         (stats->cluster_enabled ? "yes" : "no"));
                ap_rputs("<hr><br />\n", r);
            }
            else {
                ap_rprintf(r, "Version: %u.%u.%u [%u bits], PID: %u, Uptime: %u hrs %s\n",
                        stats->major, stats->minor, stats->patch, stats->arch_bits,
                        stats->process_id, stats->uptime_in_seconds/3600, br);
                ap_rprintf(r, "Clients:: Connected: %d, Blocked: %d %s\n",
                        stats->connected_clients, stats->blocked_clients, br);
                ap_rprintf(r, "Memory:: Total: %" APR_UINT64_T_FMT ", Max: %" APR_UINT64_T_FMT ", Used: %" APR_UINT64_T_FMT " %s\n",
                        stats->total_system_memory, stats->maxmemory, stats->used_memory,
                        br);
                ap_rprintf(r, "CPU:: System: %u, User: %u %s\n",
                        stats->used_cpu_sys, stats->used_cpu_user , br);
                ap_rprintf(r, "Connections:: Recd: %" APR_UINT64_T_FMT ", Processed: %" APR_UINT64_T_FMT ", Rejected: %" APR_UINT64_T_FMT " %s\n",
                        stats->total_connections_received, stats->total_commands_processed,
                        stats->rejected_connections, br);
                ap_rprintf(r, "Cache:: Hits: %" APR_UINT64_T_FMT ", Misses: %" APR_UINT64_T_FMT " %s\n",
                        stats->keyspace_hits, stats->keyspace_misses, br);
                ap_rprintf(r, "Net:: Input bytes: %" APR_UINT64_T_FMT ", Output bytes: %" APR_UINT64_T_FMT " %s\n",
                        stats->total_net_input_bytes, stats->total_net_output_bytes, br);
                if (stats->role == APR_RS_SERVER_MASTER)
                    role = "master";
                else if (stats->role == APR_RS_SERVER_SLAVE)
                    role = "slave";
                else
                    role = "unknown";
                ap_rprintf(r, "Misc:: Role: %s, Connected Slaves: %u, Is Cluster?: %s %s\n",
                        role, stats->connected_clients,
                        (stats->cluster_enabled ? "yes" : "no"), br);
            }
        }
    
    }
    
    static apr_status_t socache_rd_iterate(ap_socache_instance_t *instance,
                                           server_rec *s, void *userctx,
                                           ap_socache_iterator_t *iterator,
                                           apr_pool_t *pool)
    {
        return APR_ENOTIMPL;
    }
    
    static const ap_socache_provider_t socache_mc = {
        "redis",
        0,
        socache_rd_create,
        socache_rd_init,
        socache_rd_destroy,
        socache_rd_store,
        socache_rd_retrieve,
        socache_rd_remove,
        socache_rd_status,
        socache_rd_iterate,
    };
    
    #endif /* HAVE_APU_REDIS */
    
    static void* create_server_config(apr_pool_t* p, server_rec* s)
    {
        socache_rd_svr_cfg *sconf = apr_palloc(p, sizeof(socache_rd_svr_cfg));
    
        sconf->ttl = RD_DEFAULT_SERVER_TTL;
        sconf->rwto = RD_DEFAULT_SERVER_RWTO;
    
        return sconf;
    }
    
    static const char *socache_rd_set_ttl(cmd_parms *cmd, void *dummy,
                                          const char *arg)
    {
        apr_interval_time_t ttl;
        socache_rd_svr_cfg *sconf = ap_get_module_config(cmd->server->module_config,
                                                         &socache_redis_module);
    
        if (ap_timeout_parameter_parse(arg, &ttl, "s") != APR_SUCCESS) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               " has wrong format", NULL);
        }
    
        if ((ttl < apr_time_from_sec(0)) || (ttl > apr_time_from_sec(3600))) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               " can only be 0 or up to one hour.", NULL);
        }
    
        /* apr_redis_server_create needs a ttl in usec. */
        sconf->ttl = ttl;
    
        return NULL;
    }
    
    static const char *socache_rd_set_rwto(cmd_parms *cmd, void *dummy,
                                          const char *arg)
    {
        apr_interval_time_t rwto;
        socache_rd_svr_cfg *sconf = ap_get_module_config(cmd->server->module_config,
                                                         &socache_redis_module);
    
        if (ap_timeout_parameter_parse(arg, &rwto, "s") != APR_SUCCESS) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               " has wrong format", NULL);
        }
    
        if ((rwto < apr_time_from_sec(0)) || (rwto > apr_time_from_sec(3600))) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               " can only be 0 or up to one hour.", NULL);
        }
    
        /* apr_redis_server_create needs a ttl in usec. */
        sconf->rwto = rwto;
    
        return NULL;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
    #ifdef HAVE_APU_REDIS
    
        ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "redis",
                             AP_SOCACHE_PROVIDER_VERSION,
                             &socache_mc);
    #endif
    }
    
    static const command_rec socache_redis_cmds[] =
    {
        AP_INIT_TAKE1("RedisConnPoolTTL", socache_rd_set_ttl, NULL, RSRC_CONF,
                      "TTL used for the connection pool with the Redis server(s)"),
        AP_INIT_TAKE1("RedisTimeout", socache_rd_set_rwto, NULL, RSRC_CONF,
                      "R/W timeout used for the connection with the Redis server(s)"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(socache_redis) = {
        STANDARD20_MODULE_STUFF, 
        NULL,                        /* create per-dir    config structures */
        NULL,                        /* merge  per-dir    config structures */
        create_server_config,        /* create per-server config structures */
        NULL,                        /* merge  per-server config structures */
        socache_redis_cmds,          /* table of config file commands       */
        register_hooks               /* register hooks                      */
    };
    
    �����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_memcache.dsp�������������������������������������������������0000664�0001751�0001751�00000011117�13025030244�022125� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_socache_memcache" - 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_socache_memcache - 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_socache_memcache.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_socache_memcache.mak" CFG="mod_socache_memcache - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_memcache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_memcache - 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_socache_memcache - 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_socache_memcache_EXPORTS" /FD /c
    # ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_socache_memcache_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 /fo"Release/mod_socache_memcache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_memcache.so" /d LONG_NAME="socache_memcache_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_socache_memcache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_memcache.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_socache_memcache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_socache_memcache - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_socache_memcache_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 /fo"Debug/mod_socache_memcache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_memcache.so" /d LONG_NAME="socache_memcache_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_socache_memcache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_memcache.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_socache_memcache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_socache_memcache - Win32 Release"
    # Name "mod_socache_memcache - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_socache_memcache.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_socache.mak����������������������������������������������������0000664�0001751�0001751�00000026246�12701473373�021437� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_cache_socache.dsp
    !IF "$(CFG)" == ""
    CFG=mod_cache_socache - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_cache_socache - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_cache_socache - Win32 Release" && "$(CFG)" != "mod_cache_socache - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_socache.mak" CFG="mod_cache_socache - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_cache_socache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_cache_socache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_socache - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cache_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_cache - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_cache_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_cache - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cache_socache.obj"
    	-@erase "$(INTDIR)\mod_cache_socache.res"
    	-@erase "$(INTDIR)\mod_cache_socache_src.idb"
    	-@erase "$(INTDIR)\mod_cache_socache_src.pdb"
    	-@erase "$(OUTDIR)\mod_cache_socache.exp"
    	-@erase "$(OUTDIR)\mod_cache_socache.lib"
    	-@erase "$(OUTDIR)\mod_cache_socache.pdb"
    	-@erase "$(OUTDIR)\mod_cache_socache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cache_socache_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cache_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cache_socache.so" /d LONG_NAME="cache_socache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cache_socache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cache_socache.pdb" /debug /out:"$(OUTDIR)\mod_cache_socache.so" /implib:"$(OUTDIR)\mod_cache_socache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_socache.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cache_socache.obj" \
    	"$(INTDIR)\mod_cache_socache.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_cache.lib"
    
    "$(OUTDIR)\mod_cache_socache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_cache_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cache_socache.so"
       if exist .\Release\mod_cache_socache.so.manifest mt.exe -manifest .\Release\mod_cache_socache.so.manifest -outputresource:.\Release\mod_cache_socache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_cache_socache - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cache_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_cache - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_cache_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_cache - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cache_socache.obj"
    	-@erase "$(INTDIR)\mod_cache_socache.res"
    	-@erase "$(INTDIR)\mod_cache_socache_src.idb"
    	-@erase "$(INTDIR)\mod_cache_socache_src.pdb"
    	-@erase "$(OUTDIR)\mod_cache_socache.exp"
    	-@erase "$(OUTDIR)\mod_cache_socache.lib"
    	-@erase "$(OUTDIR)\mod_cache_socache.pdb"
    	-@erase "$(OUTDIR)\mod_cache_socache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cache_socache_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cache_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cache_socache.so" /d LONG_NAME="cache_socache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cache_socache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cache_socache.pdb" /debug /out:"$(OUTDIR)\mod_cache_socache.so" /implib:"$(OUTDIR)\mod_cache_socache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_socache.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cache_socache.obj" \
    	"$(INTDIR)\mod_cache_socache.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_cache.lib"
    
    "$(OUTDIR)\mod_cache_socache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_cache_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cache_socache.so"
       if exist .\Debug\mod_cache_socache.so.manifest mt.exe -manifest .\Debug\mod_cache_socache.so.manifest -outputresource:.\Debug\mod_cache_socache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_cache_socache.dep")
    !INCLUDE "mod_cache_socache.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_cache_socache.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_cache_socache - Win32 Release" || "$(CFG)" == "mod_cache_socache - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_cache_socache - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache_socache - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_socache - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache_socache - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_socache - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache_socache - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_socache - Win32 Release"
    
    "mod_cache - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Release" 
       cd "."
    
    "mod_cache - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_cache_socache - Win32 Debug"
    
    "mod_cache - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Debug" 
       cd "."
    
    "mod_cache - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_cache_socache - Win32 Release"
    
    
    "$(INTDIR)\mod_cache_socache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cache_socache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_cache_socache.so" /d LONG_NAME="cache_socache_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_cache_socache - Win32 Debug"
    
    
    "$(INTDIR)\mod_cache_socache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cache_socache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_cache_socache.so" /d LONG_NAME="cache_socache_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_cache_socache.c
    
    "$(INTDIR)\mod_cache_socache.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_shmcb.mak����������������������������������������������������0000664�0001751�0001751�00000024521�12701473373�021462� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_socache_shmcb.dsp
    !IF "$(CFG)" == ""
    CFG=mod_socache_shmcb - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_socache_shmcb - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_socache_shmcb - Win32 Release" && "$(CFG)" != "mod_socache_shmcb - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_socache_shmcb.mak" CFG="mod_socache_shmcb - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_shmcb - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_shmcb - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_shmcb - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_shmcb.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_socache_shmcb.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_shmcb.obj"
    	-@erase "$(INTDIR)\mod_socache_shmcb.res"
    	-@erase "$(INTDIR)\mod_socache_shmcb_src.idb"
    	-@erase "$(INTDIR)\mod_socache_shmcb_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.exp"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.lib"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.pdb"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_shmcb_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_shmcb.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_shmcb.so" /d LONG_NAME="socache_shmcb_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_shmcb.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_shmcb.pdb" /debug /out:"$(OUTDIR)\mod_socache_shmcb.so" /implib:"$(OUTDIR)\mod_socache_shmcb.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_shmcb.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_shmcb.obj" \
    	"$(INTDIR)\mod_socache_shmcb.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_shmcb.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_socache_shmcb.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_shmcb.so"
       if exist .\Release\mod_socache_shmcb.so.manifest mt.exe -manifest .\Release\mod_socache_shmcb.so.manifest -outputresource:.\Release\mod_socache_shmcb.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_socache_shmcb - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_shmcb.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_socache_shmcb.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_shmcb.obj"
    	-@erase "$(INTDIR)\mod_socache_shmcb.res"
    	-@erase "$(INTDIR)\mod_socache_shmcb_src.idb"
    	-@erase "$(INTDIR)\mod_socache_shmcb_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.exp"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.lib"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.pdb"
    	-@erase "$(OUTDIR)\mod_socache_shmcb.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_shmcb_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_shmcb.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_shmcb.so" /d LONG_NAME="socache_shmcb_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_shmcb.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_shmcb.pdb" /debug /out:"$(OUTDIR)\mod_socache_shmcb.so" /implib:"$(OUTDIR)\mod_socache_shmcb.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_shmcb.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_shmcb.obj" \
    	"$(INTDIR)\mod_socache_shmcb.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_shmcb.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_socache_shmcb.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_shmcb.so"
       if exist .\Debug\mod_socache_shmcb.so.manifest mt.exe -manifest .\Debug\mod_socache_shmcb.so.manifest -outputresource:.\Debug\mod_socache_shmcb.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_socache_shmcb.dep")
    !INCLUDE "mod_socache_shmcb.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_socache_shmcb.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_socache_shmcb - Win32 Release" || "$(CFG)" == "mod_socache_shmcb - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_socache_shmcb - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_shmcb - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_shmcb - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_shmcb - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_shmcb - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_shmcb - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_socache_shmcb - Win32 Release"
    
    
    "$(INTDIR)\mod_socache_shmcb.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_shmcb.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_socache_shmcb.so" /d LONG_NAME="socache_shmcb_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_socache_shmcb - Win32 Debug"
    
    
    "$(INTDIR)\mod_socache_shmcb.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_shmcb.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_socache_shmcb.so" /d LONG_NAME="socache_shmcb_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_socache_shmcb.c
    
    "$(INTDIR)\mod_socache_shmcb.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_file_cache.dep�������������������������������������������������������0000664�0001751�0001751�00000003765�12674411515�020751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_file_cache.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_file_cache.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������httpd-2.4.64/modules/cache/mod_socache_shmcb.dep����������������������������������������������������0000664�0001751�0001751�00000003767�12674411515�021472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_socache_shmcb.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_socache_shmcb.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\generators\mod_status.h"\
    	
    ���������httpd-2.4.64/modules/cache/mod_socache_dbm.dsp������������������������������������������������������0000664�0001751�0001751�00000010710�12520576322�021136� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_socache_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_socache_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_socache_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_socache_dbm.mak" CFG="mod_socache_dbm - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_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_socache_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" /D "_MBCS" /D "_USRDLL" /D "mod_socache_dbm_EXPORTS" /FD /c
    # ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_socache_dbm_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 /fo"Release/mod_socache_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_dbm.so" /d LONG_NAME="socache_dbm_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_socache_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dbm.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_socache_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_socache_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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_socache_dbm_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 /fo"Debug/mod_socache_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_dbm.so" /d LONG_NAME="socache_dbm_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_socache_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dbm.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_socache_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_socache_dbm - Win32 Release"
    # Name "mod_socache_dbm - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_socache_dbm.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ��������������������������������������������������������httpd-2.4.64/modules/cache/cache_common.h�����������������������������������������������������������0000664�0001751�0001751�00000003741�12151211714�020121� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file cache_common.h
     * @brief Common Cache structs
     *
     * @defgroup Cache_cache  Cache Functions
     * @ingroup  MOD_CACHE
     * @{
     */
    
    #ifndef CACHE_COMMON_H
    #define CACHE_COMMON_H
    
    /* a cache control header breakdown */
    typedef struct cache_control {
        unsigned int parsed:1;
        unsigned int cache_control:1;
        unsigned int pragma:1;
        unsigned int no_cache:1;
        unsigned int no_cache_header:1; /* no cache by header match */
        unsigned int no_store:1;
        unsigned int max_age:1;
        unsigned int max_stale:1;
        unsigned int min_fresh:1;
        unsigned int no_transform:1;
        unsigned int only_if_cached:1;
        unsigned int public:1;
        unsigned int private:1;
        unsigned int private_header:1; /* private by header match */
        unsigned int must_revalidate:1;
        unsigned int proxy_revalidate:1;
        unsigned int s_maxage:1;
        unsigned int invalidated:1; /* has this entity been invalidated? */
        apr_int64_t max_age_value; /* if positive, then set */
        apr_int64_t max_stale_value; /* if positive, then set */
        apr_int64_t min_fresh_value; /* if positive, then set */
        apr_int64_t s_maxage_value; /* if positive, then set */
    } cache_control_t;
    
    #endif /* CACHE_COMMON_H */
    /** @} */
    �������������������������������httpd-2.4.64/modules/cache/mod_cache.h��������������������������������������������������������������0000664�0001751�0001751�00000016130�11666462060�017420� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_cache.h
     * @brief Main include file for the Apache Transparent Cache
     *
     * @defgroup MOD_CACHE mod_cache
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #ifndef MOD_CACHE_H
    #define MOD_CACHE_H
    
    #include "httpd.h"
    #include "apr_date.h"
    #include "apr_optional.h"
    #include "apr_hooks.h"
    
    #include "cache_common.h"
    
    /* 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
    
    /* cache info information */
    typedef struct cache_info cache_info;
    struct cache_info {
        /**
         * the original time corresponding to the 'Date:' header of the request
         * served
         */
        apr_time_t date;
        /** a time when the cached entity is due to expire */
        apr_time_t expire;
        /** r->request_time from the same request */
        apr_time_t request_time;
        /** apr_time_now() at the time the entity was actually cached */
        apr_time_t response_time;
        /**
         * HTTP status code of the cached entity. Though not necessarily the
         * status code finally issued to the request.
         */
        int status;
        /* cached cache-control */
        cache_control_t control;
    };
    
    /* cache handle information */
    typedef struct cache_object cache_object_t;
    struct cache_object {
        const char *key;
        cache_object_t *next;
        cache_info info;
        /* Opaque portion (specific to the implementation) of the cache object */
        void *vobj;
    };
    
    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 *in,
                               apr_bucket_brigade *out);
        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, apr_bucket_brigade *bb);
        int (*open_entity) (cache_handle_t *h, request_rec *r,
                               const char *urlkey);
        int (*remove_url) (cache_handle_t *h, request_rec *r);
        apr_status_t (*commit_entity)(cache_handle_t *h, request_rec *r);
        apr_status_t (*invalidate_entity)(cache_handle_t *h, request_rec *r);
    } cache_provider;
    
    typedef enum {
        AP_CACHE_HIT,
        AP_CACHE_REVALIDATE,
        AP_CACHE_MISS,
        AP_CACHE_INVALIDATE
    } ap_cache_status_e;
    
    #define AP_CACHE_HIT_ENV "cache-hit"
    #define AP_CACHE_REVALIDATE_ENV "cache-revalidate"
    #define AP_CACHE_MISS_ENV "cache-miss"
    #define AP_CACHE_INVALIDATE_ENV "cache-invalidate"
    #define AP_CACHE_STATUS_ENV "cache-status"
    
    
    /* 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);
    
    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(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list, const char **str);
    
    /* Create a new table consisting of those elements from an
     * headers table that are allowed to be stored in a cache.
     */
    CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers(apr_pool_t *pool,
                                                            apr_table_t *t,
                                                            server_rec *s);
    
    /* 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_headers_in(request_rec *r);
    
    /* Create a new table consisting of those elements from an output
     * headers table that are allowed to be stored in a cache;
     * ensure there is a content type and capture any errors.
     */
    CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers_out(request_rec *r);
    
    /**
     * Parse the Cache-Control and Pragma headers in one go, marking
     * which tokens appear within the header. Populate the structure
     * passed in.
     */
    int ap_cache_control(request_rec *r, cache_control_t *cc, const char *cc_header,
            const char *pragma_header, apr_table_t *headers);
    
    
    /* hooks */
    
    /**
     * Cache status hook.
     * This hook is called as soon as the cache has made a decision as to whether
     * an entity should be served from cache (hit), should be served from cache
     * after a successful validation (revalidate), or served from the backend
     * and potentially cached (miss).
     *
     * A basic implementation of this hook exists in mod_cache which writes this
     * information to the subprocess environment, and optionally to request
     * headers. Further implementations may add hooks as appropriate to perform
     * more advanced processing, or to store statistics about the cache behaviour.
     */
    APR_DECLARE_EXTERNAL_HOOK(cache, CACHE, int, cache_status, (cache_handle_t *h,
                    request_rec *r, apr_table_t *headers, ap_cache_status_e status,
                    const char *reason))
    
    APR_DECLARE_OPTIONAL_FN(apr_status_t,
                            ap_cache_generate_key,
                            (request_rec *r, apr_pool_t*p, const char **key));
    
    
    #endif /*MOD_CACHE_H*/
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_file_cache.dsp�������������������������������������������������������0000664�0001751�0001751�00000010761�10551346420�020753� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_file_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_file_cache.so" /d LONG_NAME="file_cache_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 /nologo /subsystem:windows /dll /out:".\Release\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
    # ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_file_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_file_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_file_cache.so" /d LONG_NAME="file_cache_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
    # ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_file_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������httpd-2.4.64/modules/cache/cache_disk_common.h������������������������������������������������������0000664�0001751�0001751�00000004455�11544421404�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file cache_disk_common.h
     * @brief Common Disk Cache vars/structs
     *
     * @defgroup Cache_cache  Cache Functions
     * @ingroup  MOD_DISK_CACHE
     * @{
     */
    
    #ifndef CACHE_DIST_COMMON_H
    #define CACHE_DIST_COMMON_H
    
    #define VARY_FORMAT_VERSION 5
    #define DISK_FORMAT_VERSION 6
    
    #define CACHE_HEADER_SUFFIX ".header"
    #define CACHE_DATA_SUFFIX   ".data"
    #define CACHE_VDIR_SUFFIX   ".vary"
    
    #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
    
    typedef struct {
        /* Indicates the format of the header struct stored on-disk. */
        apr_uint32_t 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;
        /* The ident of the body file, so we can test the body matches the header */
        apr_ino_t inode;
        apr_dev_t device;
        /* Does this cached request have a body? */
        unsigned int has_body:1;
        unsigned int header_only:1;
        /* The parsed cache control header */
        cache_control_t control;
    } disk_cache_info_t;
    
    #endif /* CACHE_DIST_COMMON_H */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_dc.dsp�������������������������������������������������������0000664�0001751�0001751�00000010607�11022367030�020755� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_socache_dc" - 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_socache_dc - 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_socache_dc.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_socache_dc.mak" CFG="mod_socache_dc - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_dc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_dc - 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_socache_dc - 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_socache_dc_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_socache_dc_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 /fo"Release/mod_socache_dc.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_dc.so" /d LONG_NAME="socache_dc_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_socache_dc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dc.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_socache_dc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_socache_dc - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_socache_dc_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 /fo"Debug/mod_socache_dc.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_dc.so" /d LONG_NAME="socache_dc_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_socache_dc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dc.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_socache_dc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_socache_dc - Win32 Release"
    # Name "mod_socache_dc - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_socache_dc.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_socache.c������������������������������������������������������0000664�0001751�0001751�00000152731�14743422115�021104� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_lib.h"
    #include "apr_file_io.h"
    #include "apr_strings.h"
    #include "apr_buckets.h"
    
    #include "apr_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_core.h"
    #include "http_protocol.h"
    #include "ap_provider.h"
    #include "ap_socache.h"
    #include "util_filter.h"
    #include "util_script.h"
    #include "util_charset.h"
    #include "util_mutex.h"
    
    #include "mod_cache.h"
    #include "mod_status.h"
    
    #include "cache_socache_common.h"
    
    /*
     * mod_cache_socache: Shared Object Cache Based HTTP 1.1 Cache.
     *
     * Flow to Find the entry:
     *   Incoming client requests URI /foo/bar/baz
     *   Fetch URI key (may contain Format #1 or Format #2)
     *   If format #1 (Contains a list of Vary Headers):
     *      Use each header name (from .header) with our request values (headers_in) to
     *      regenerate key using HeaderName+HeaderValue+.../foo/bar/baz
     *      re-read in key (must be format #2)
     *
     * Format #1:
     *   apr_uint32_t format;
     *   apr_time_t expire;
     *   apr_array_t vary_headers (delimited by CRLF)
     *
     * Format #2:
     *   cache_socache_info_t (first sizeof(apr_uint32_t) bytes is the format)
     *   entity name (sobj->name) [length is in cache_socache_info_t->name_len]
     *   r->headers_out (delimited by CRLF)
     *   CRLF
     *   r->headers_in (delimited by CRLF)
     *   CRLF
     */
    
    module AP_MODULE_DECLARE_DATA cache_socache_module;
    
    /*
     * cache_socache_object_t
     * Pointed to by cache_object_t::vobj
     */
    typedef struct cache_socache_object_t
    {
        apr_pool_t *pool; /* pool */
        unsigned char *buffer; /* the cache buffer */
        apr_size_t buffer_len; /* size of the buffer */
        apr_bucket_brigade *body; /* brigade containing the body, if any */
        apr_table_t *headers_in; /* Input headers to save */
        apr_table_t *headers_out; /* Output headers to save */
        cache_socache_info_t socache_info; /* Header information. */
        apr_size_t body_offset; /* offset to the start of the body */
        apr_off_t body_length; /* length of the cached entity body */
        apr_time_t expire; /* when to expire the entry */
    
        const char *name; /* Requested URI without vary bits - suitable for mortals. */
        const char *key; /* On-disk prefix; URI with Vary bits (if present) */
        apr_off_t offset; /* Max size to set aside */
        apr_time_t timeout; /* Max time to set aside */
        unsigned int newbody :1; /* whether a new body is present */
        unsigned int done :1; /* Is the attempt to cache complete? */
    } cache_socache_object_t;
    
    /*
     * mod_cache_socache configuration
     */
    #define DEFAULT_MAX_FILE_SIZE 100*1024
    #define DEFAULT_MAXTIME 86400
    #define DEFAULT_MINTIME 600
    #define DEFAULT_READSIZE 0
    #define DEFAULT_READTIME 0
    
    typedef struct cache_socache_provider_conf
    {
        const char *args;
        ap_socache_provider_t *socache_provider;
        ap_socache_instance_t *socache_instance;
    } cache_socache_provider_conf;
    
    typedef struct cache_socache_conf
    {
        cache_socache_provider_conf *provider;
    } cache_socache_conf;
    
    typedef struct cache_socache_dir_conf
    {
        apr_off_t max; /* maximum file size for cached files */
        apr_time_t maxtime; /* maximum expiry time */
        apr_time_t mintime; /* minimum expiry time */
        apr_off_t readsize; /* maximum data to attempt to cache in one go */
        apr_time_t readtime; /* maximum time taken to cache in one go */
        unsigned int max_set :1;
        unsigned int maxtime_set :1;
        unsigned int mintime_set :1;
        unsigned int readsize_set :1;
        unsigned int readtime_set :1;
    } cache_socache_dir_conf;
    
    /* Shared object cache and mutex */
    static const char * const cache_socache_id = "cache-socache";
    static apr_global_mutex_t *socache_mutex = NULL;
    
    /*
     * Local static functions
     */
    
    static apr_status_t read_array(request_rec *r, apr_array_header_t *arr,
            unsigned char *buffer, apr_size_t buffer_len, apr_size_t *slider)
    {
        apr_size_t val = *slider;
    
        while (*slider < buffer_len) {
            if (buffer[*slider] == '\r') {
                if (val == *slider) {
                    (*slider)++;
                    return APR_SUCCESS;
                }
                *((const char **) apr_array_push(arr)) = apr_pstrndup(r->pool,
                        (const char *) buffer + val, *slider - val);
                (*slider)++;
                if (buffer[*slider] == '\n') {
                    (*slider)++;
                }
                val = *slider;
            }
            else if (buffer[*slider] == '\0') {
                (*slider)++;
                return APR_SUCCESS;
            }
            else {
                (*slider)++;
            }
        }
    
        return APR_EOF;
    }
    
    static apr_status_t store_array(apr_array_header_t *arr, unsigned char *buffer,
            apr_size_t buffer_len, apr_size_t *slider)
    {
        int i, len;
        const char **elts;
    
        elts = (const char **) arr->elts;
    
        for (i = 0; i < arr->nelts; i++) {
            apr_size_t e_len = strlen(elts[i]);
            if (e_len + 3 >= buffer_len - *slider) {
                return APR_EOF;
            }
            len = apr_snprintf(buffer ? (char *) buffer + *slider : NULL,
                    buffer ? buffer_len - *slider : 0, "%s" CRLF, elts[i]);
            *slider += len;
        }
        if (buffer) {
            memcpy(buffer + *slider, CRLF, sizeof(CRLF) - 1);
        }
        *slider += sizeof(CRLF) - 1;
    
        return APR_SUCCESS;
    }
    
    static apr_status_t read_table(cache_handle_t *handle, request_rec *r,
            apr_table_t *table, unsigned char *buffer, apr_size_t buffer_len,
            apr_size_t *slider)
    {
        apr_size_t key = *slider, colon = 0, len = 0;
    
        while (*slider < buffer_len) {
            if (buffer[*slider] == ':') {
                if (!colon) {
                    colon = *slider;
                }
                (*slider)++;
            }
            else if (buffer[*slider] == '\r') {
                len = colon;
                if (key == *slider) {
                    (*slider)++;
                    if (buffer[*slider] == '\n') {
                        (*slider)++;
                    }
                    return APR_SUCCESS;
                }
                if (!colon || buffer[colon++] != ':') {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02344)
                            "Premature end of cache headers.");
                    return APR_EGENERAL;
                }
                /* Do not go past the \r from above as apr_isspace('\r') is true */
                while (apr_isspace(buffer[colon]) && (colon < *slider)) {
                    colon++;
                }
                apr_table_addn(table, apr_pstrmemdup(r->pool, (const char *) buffer
                        + key, len - key), apr_pstrmemdup(r->pool,
                        (const char *) buffer + colon, *slider - colon));
                (*slider)++;
                if (buffer[*slider] == '\n') {
                    (*slider)++;
                }
                key = *slider;
                colon = 0;
            }
            else if (buffer[*slider] == '\0') {
                (*slider)++;
                return APR_SUCCESS;
            }
            else {
                (*slider)++;
            }
        }
    
        return APR_EOF;
    }
    
    static apr_status_t store_table(apr_table_t *table, unsigned char *buffer,
            apr_size_t buffer_len, apr_size_t *slider)
    {
        int i, len;
        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) {
                apr_size_t key_len = strlen(elts[i].key);
                apr_size_t val_len = strlen(elts[i].val);
                if (key_len + val_len + 5 >= buffer_len - *slider) {
                    return APR_EOF;
                }
                len = apr_snprintf(buffer ? (char *) buffer + *slider : NULL,
                        buffer ? buffer_len - *slider : 0, "%s: %s" CRLF,
                        elts[i].key, elts[i].val);
                *slider += len;
            }
        }
        if (3 >= buffer_len - *slider) {
            return APR_EOF;
        }
        if (buffer) {
            memcpy(buffer + *slider, CRLF, sizeof(CRLF) - 1);
        }
        *slider += sizeof(CRLF) - 1;
    
        return APR_SUCCESS;
    }
    
    static const char* regen_key(apr_pool_t *p, apr_table_t *headers,
                                 apr_array_header_t *varray, const char *oldkey,
                                 apr_size_t *newkeylen)
    {
        struct iovec *iov;
        int i, k;
        int nvec;
        const char *header;
        const char **elts;
    
        nvec = (varray->nelts * 2) + 1;
        iov = apr_palloc(p, sizeof(struct iovec) * nvec);
        elts = (const char **) varray->elts;
    
        /* TODO:
         *    - Handle multiple-value headers better. (sort them?)
         *    - Handle Case in-sensitive Values better.
         *        This isn't the end of the world, since it just lowers the cache
         *        hit rate, but it would be nice to fix.
         *
         * The majority are case insenstive if they are values (encoding etc).
         * Most of rfc2616 is case insensitive on header contents.
         *
         * So the better solution may be to identify headers which should be
         * treated case-sensitive?
         *  HTTP URI's (3.2.3) [host and scheme are insensitive]
         *  HTTP method (5.1.1)
         *  HTTP-date values (3.3.1)
         *  3.7 Media Types [excerpt]
         *     The type, subtype, and parameter attribute names are case-
         *     insensitive. Parameter values might or might not be case-sensitive,
         *     depending on the semantics of the parameter name.
         *  4.20 Except [excerpt]
         *     Comparison of expectation values is case-insensitive for unquoted
         *     tokens (including the 100-continue token), and is case-sensitive for
         *     quoted-string expectation-extensions.
         */
    
        for (i = 0, k = 0; i < varray->nelts; i++) {
            header = apr_table_get(headers, elts[i]);
            if (!header) {
                header = "";
            }
            iov[k].iov_base = (char*) elts[i];
            iov[k].iov_len = strlen(elts[i]);
            k++;
            iov[k].iov_base = (char*) header;
            iov[k].iov_len = strlen(header);
            k++;
        }
        iov[k].iov_base = (char*) oldkey;
        iov[k].iov_len = strlen(oldkey);
        k++;
    
        return apr_pstrcatv(p, iov, k, newkeylen);
    }
    
    static int array_alphasort(const void *fn1, const void *fn2)
    {
        return strcmp(*(char**) fn1, *(char**) fn2);
    }
    
    static void tokens_to_array(apr_pool_t *p, const char *data,
            apr_array_header_t *arr)
    {
        char *token;
    
        while ((token = ap_get_list_item(p, &data)) != NULL) {
            *((const char **) apr_array_push(arr)) = token;
        }
    
        /* Sort it so that "Vary: A, B" and "Vary: B, A" are stored the same. */
        qsort((void *) arr->elts, arr->nelts, sizeof(char *), array_alphasort);
    }
    
    /*
     * Hook and mod_cache callback functions
     */
    static int create_entity(cache_handle_t *h, request_rec *r, const char *key,
            apr_off_t len, apr_bucket_brigade *bb)
    {
        cache_socache_dir_conf *dconf =
                ap_get_module_config(r->per_dir_config, &cache_socache_module);
        cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
                &cache_socache_module);
        cache_object_t *obj;
        cache_socache_object_t *sobj;
        apr_size_t total;
    
        if (conf->provider == NULL) {
            return DECLINED;
        }
    
        /* we don't support caching of range requests (yet) */
        /* TODO: but we could */
        if (r->status == HTTP_PARTIAL_CONTENT) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02345)
                    "URL %s partial content response not cached",
                    key);
            return DECLINED;
        }
    
        /*
         * We have a chicken and egg problem. We don't know until we
         * attempt to store_headers just how big the response will be
         * and whether it will fit in the cache limits set. But we
         * need to make a decision now as to whether we plan to try.
         * If we make the wrong decision, we could prevent another
         * cache implementation, such as cache_disk, from getting the
         * opportunity to cache, and that would be unfortunate.
         *
         * In a series of tests, from cheapest to most expensive,
         * decide whether or not to ignore this attempt to cache,
         * with a small margin just to be sure.
         */
        if (len < 0) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02346)
                    "URL '%s' had no explicit size, ignoring", key);
            return DECLINED;
        }
        if (len > dconf->max) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02347)
                    "URL '%s' body larger than limit, ignoring "
                    "(%" APR_OFF_T_FMT " > %" APR_OFF_T_FMT ")",
                    key, len, dconf->max);
            return DECLINED;
        }
    
        /* estimate the total cached size, given current headers */
        total = len + sizeof(cache_socache_info_t) + strlen(key);
        if (APR_SUCCESS != store_table(r->headers_out, NULL, dconf->max, &total)
                || APR_SUCCESS != store_table(r->headers_in, NULL, dconf->max,
                        &total)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02348)
                    "URL '%s' estimated headers size larger than limit, ignoring "
                    "(%" APR_SIZE_T_FMT " > %" APR_OFF_T_FMT ")",
                    key, total, dconf->max);
            return DECLINED;
        }
    
        if (total >= dconf->max) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02349)
                    "URL '%s' body and headers larger than limit, ignoring "
                    "(%" APR_OFF_T_FMT " > %" APR_OFF_T_FMT ")",
                    key, len, dconf->max);
            return DECLINED;
        }
    
        /* Allocate and initialize cache_object_t and cache_socache_object_t */
        h->cache_obj = obj = apr_pcalloc(r->pool, sizeof(*obj));
        obj->vobj = sobj = apr_pcalloc(r->pool, sizeof(*sobj));
    
        obj->key = apr_pstrdup(r->pool, key);
        sobj->key = obj->key;
        sobj->name = obj->key;
    
        return OK;
    }
    
    static apr_status_t sobj_body_pre_cleanup(void *baton)
    {
        cache_socache_object_t *sobj = baton;
        apr_brigade_cleanup(sobj->body);
        sobj->body = NULL;
        return APR_SUCCESS;
    }
    
    static int open_entity(cache_handle_t *h, request_rec *r, const char *key)
    {
        cache_socache_dir_conf *dconf =
                ap_get_module_config(r->per_dir_config, &cache_socache_module);
        cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
                &cache_socache_module);
        apr_uint32_t format;
        apr_size_t slider;
        unsigned int buffer_len;
        const char *nkey;
        apr_status_t rc;
        cache_object_t *obj;
        cache_info *info;
        cache_socache_object_t *sobj;
        apr_size_t len;
    
        nkey = NULL;
        h->cache_obj = NULL;
    
        if (!conf->provider || !conf->provider->socache_instance) {
            return DECLINED;
        }
    
        /* Create and init the cache object */
        obj = apr_pcalloc(r->pool, sizeof(cache_object_t));
        sobj = apr_pcalloc(r->pool, sizeof(cache_socache_object_t));
    
        info = &(obj->info);
    
        /* Create a temporary pool for the buffer, and destroy it if something
         * goes wrong so we don't have large buffers of unused memory hanging
         * about for the lifetime of the response.
         */
        apr_pool_create(&sobj->pool, r->pool);
        apr_pool_tag(sobj->pool, "mod_cache_socache (open_entity)");
    
        sobj->buffer = apr_palloc(sobj->pool, dconf->max);
        sobj->buffer_len = dconf->max;
    
        /* attempt to retrieve the cached entry */
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_lock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02350)
                        "could not acquire lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
        }
        buffer_len = sobj->buffer_len;
        rc = conf->provider->socache_provider->retrieve(
                conf->provider->socache_instance, r->server, (unsigned char *) key,
                strlen(key), sobj->buffer, &buffer_len, r->pool);
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_unlock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02351)
                        "could not release lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
        }
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02352)
                    "Key not found in cache: %s", key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
        if (buffer_len >= sobj->buffer_len) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02353)
                    "Key found in cache but too big, ignoring: %s", key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
    
        /* read the format from the cache file */
        memcpy(&format, sobj->buffer, sizeof(format));
        slider = sizeof(format);
    
        if (format == CACHE_SOCACHE_VARY_FORMAT_VERSION) {
            apr_array_header_t* varray;
            apr_time_t expire;
    
            memcpy(&expire, sobj->buffer + slider, sizeof(expire));
            slider += sizeof(expire);
    
            varray = apr_array_make(r->pool, 5, sizeof(char*));
            rc = read_array(r, varray, sobj->buffer, buffer_len, &slider);
            if (rc != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02354)
                        "Cannot parse vary entry for key: %s", key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
    
            nkey = regen_key(r->pool, r->headers_in, varray, key, &len);
    
            /* attempt to retrieve the cached entry */
            if (socache_mutex) {
                apr_status_t status = apr_global_mutex_lock(socache_mutex);
                if (status != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02355)
                            "could not acquire lock, ignoring: %s", obj->key);
                    apr_pool_destroy(sobj->pool);
                    sobj->pool = NULL;
                    return DECLINED;
                }
            }
            buffer_len = sobj->buffer_len;
            rc = conf->provider->socache_provider->retrieve(
                    conf->provider->socache_instance, r->server,
                    (unsigned char *) nkey, len, sobj->buffer,
                    &buffer_len, r->pool);
            if (socache_mutex) {
                apr_status_t status = apr_global_mutex_unlock(socache_mutex);
                if (status != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02356)
                            "could not release lock, ignoring: %s", obj->key);
                    apr_pool_destroy(sobj->pool);
                    sobj->pool = NULL;
                    return DECLINED;
                }
            }
            if (rc != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02357)
                        "Key not found in cache: %s", key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
            if (buffer_len >= sobj->buffer_len) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(02358)
                        "Key found in cache but too big, ignoring: %s", key);
                goto fail;
            }
    
        }
        else if (format != CACHE_SOCACHE_DISK_FORMAT_VERSION) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02359)
                    "Key '%s' found in cache has version %d, expected %d, ignoring",
                    key, format, CACHE_SOCACHE_DISK_FORMAT_VERSION);
            goto fail;
        }
        else {
            nkey = key;
        }
    
        obj->key = nkey;
        sobj->key = nkey;
        sobj->name = key;
    
        if (buffer_len >= sizeof(cache_socache_info_t)) {
            memcpy(&sobj->socache_info, sobj->buffer, sizeof(cache_socache_info_t));
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02360)
                    "Cache entry for key '%s' too short, removing", nkey);
            goto fail;
        }
        slider = sizeof(cache_socache_info_t);
    
        /* Store it away so we can get it later. */
        info->status = sobj->socache_info.status;
        info->date = sobj->socache_info.date;
        info->expire = sobj->socache_info.expire;
        info->request_time = sobj->socache_info.request_time;
        info->response_time = sobj->socache_info.response_time;
    
        memcpy(&info->control, &sobj->socache_info.control, sizeof(cache_control_t));
    
        if (sobj->socache_info.name_len <= buffer_len - slider) {
            if (strncmp((const char *) sobj->buffer + slider, sobj->name,
                    sobj->socache_info.name_len)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02361)
                        "Cache entry for key '%s' URL mismatch, ignoring", nkey);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
            slider += sobj->socache_info.name_len;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02362)
                    "Cache entry for key '%s' too short, removing", nkey);
            goto fail;
        }
    
        /* Is this a cached HEAD request? */
        if (sobj->socache_info.header_only && !r->header_only) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02363)
                    "HEAD request cached, non-HEAD requested, ignoring: %s",
                    sobj->key);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return DECLINED;
        }
    
        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 */
        if (APR_SUCCESS != read_table(h, r, h->resp_hdrs, sobj->buffer, buffer_len,
                &slider)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02364)
                    "Cache entry for key '%s' response headers unreadable, removing", nkey);
            goto fail;
        }
        if (APR_SUCCESS != read_table(h, r, h->req_hdrs, sobj->buffer, buffer_len,
                &slider)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(02365)
                    "Cache entry for key '%s' request headers unreadable, removing", nkey);
            goto fail;
        }
    
        /* Retrieve the body if we have one */
        len = buffer_len - slider;
        if (len > 0) {
            apr_bucket *e;
            /* Create the body brigade later concatenated to the output filters'
             * brigade by recall_body(). Since sobj->buffer (the data) point to
             * sobj->pool (a subpool of r->pool), be safe by using a pool bucket
             * which can morph to heap if sobj->pool is destroyed while the bucket
             * is still alive. But if sobj->pool gets destroyed while the bucket is
             * still in sobj->body (i.e. recall_body() was never called), we don't
             * need to morph to something just about to be freed, so a pre_cleanup
             * will take care of cleaning up sobj->body before this happens (and is
             * a noop otherwise).
             */
            sobj->body = apr_brigade_create(sobj->pool, r->connection->bucket_alloc);
            apr_pool_pre_cleanup_register(sobj->pool, sobj, sobj_body_pre_cleanup);
            e = apr_bucket_pool_create((const char *) sobj->buffer + slider, len,
                                       sobj->pool, r->connection->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(sobj->body, e);
        }
    
        /* make the configuration stick */
        h->cache_obj = obj;
        obj->vobj = sobj;
    
        return OK;
    
    fail:
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_lock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02366)
                        "could not acquire lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
        }
        if (nkey) {
            conf->provider->socache_provider->remove(
                    conf->provider->socache_instance, r->server,
                    (unsigned char *) nkey, strlen(nkey), r->pool);
        }
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_unlock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02367)
                        "could not release lock, ignoring: %s", obj->key);
            }
        }
        apr_pool_destroy(sobj->pool);
        sobj->pool = NULL;
        return DECLINED;
    }
    
    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(cache_handle_t *h, request_rec *r)
    {
        cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
                &cache_socache_module);
        cache_socache_object_t *sobj;
    
        sobj = (cache_socache_object_t *) h->cache_obj->vobj;
        if (!sobj) {
            return DECLINED;
        }
    
        /* Remove the key from the cache */
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_lock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02368)
                        "could not acquire lock, ignoring: %s", sobj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
        }
        conf->provider->socache_provider->remove(conf->provider->socache_instance,
                r->server, (unsigned char *) sobj->key, strlen(sobj->key), r->pool);
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_unlock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02369)
                        "could not release lock, ignoring: %s", sobj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return DECLINED;
            }
        }
    
        return OK;
    }
    
    static apr_status_t recall_headers(cache_handle_t *h, request_rec *r)
    {
        /* we recalled the headers during open_entity, so do nothing */
        return APR_SUCCESS;
    }
    
    static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p,
            apr_bucket_brigade *bb)
    {
        cache_socache_object_t *sobj = (cache_socache_object_t*) h->cache_obj->vobj;
    
        if (sobj->body) {
            APR_BRIGADE_CONCAT(bb, sobj->body);
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t store_headers(cache_handle_t *h, request_rec *r,
            cache_info *info)
    {
        cache_socache_dir_conf *dconf =
                ap_get_module_config(r->per_dir_config, &cache_socache_module);
        cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
                &cache_socache_module);
        apr_size_t slider;
        apr_status_t rv;
        cache_object_t *obj = h->cache_obj;
        cache_socache_object_t *sobj = (cache_socache_object_t*) obj->vobj;
        cache_socache_info_t *socache_info;
    
        memcpy(&h->cache_obj->info, info, sizeof(cache_info));
    
        if (r->headers_out) {
            sobj->headers_out = ap_cache_cacheable_headers_out(r);
        }
    
        if (r->headers_in) {
            sobj->headers_in = ap_cache_cacheable_headers_in(r);
        }
    
        sobj->expire
                = obj->info.expire > r->request_time + dconf->maxtime ? r->request_time
                        + dconf->maxtime
                        : obj->info.expire + dconf->mintime;
    
        apr_pool_create(&sobj->pool, r->pool);
        apr_pool_tag(sobj->pool, "mod_cache_socache (store_headers)");
    
        sobj->buffer = apr_palloc(sobj->pool, dconf->max);
        sobj->buffer_len = dconf->max;
        socache_info = (cache_socache_info_t *) sobj->buffer;
    
        if (sobj->headers_out) {
            const char *vary;
    
            vary = apr_table_get(sobj->headers_out, "Vary");
    
            if (vary) {
                apr_array_header_t* varray;
                apr_uint32_t format = CACHE_SOCACHE_VARY_FORMAT_VERSION;
    
                memcpy(sobj->buffer, &format, sizeof(format));
                slider = sizeof(format);
    
                memcpy(sobj->buffer + slider, &obj->info.expire,
                        sizeof(obj->info.expire));
                slider += sizeof(obj->info.expire);
    
                varray = apr_array_make(r->pool, 6, sizeof(char*));
                tokens_to_array(r->pool, vary, varray);
    
                if (APR_SUCCESS != (rv = store_array(varray, sobj->buffer,
                        sobj->buffer_len, &slider))) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02370)
                            "buffer too small for Vary array, caching aborted: %s",
                            obj->key);
                    apr_pool_destroy(sobj->pool);
                    sobj->pool = NULL;
                    return rv;
                }
                if (socache_mutex) {
                    apr_status_t status = apr_global_mutex_lock(socache_mutex);
                    if (status != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02371)
                                "could not acquire lock, ignoring: %s", obj->key);
                        apr_pool_destroy(sobj->pool);
                        sobj->pool = NULL;
                        return status;
                    }
                }
                rv = conf->provider->socache_provider->store(
                        conf->provider->socache_instance, r->server,
                        (unsigned char *) obj->key, strlen(obj->key), sobj->expire,
                        (unsigned char *) sobj->buffer, (unsigned int) slider,
                        sobj->pool);
                if (socache_mutex) {
                    apr_status_t status = apr_global_mutex_unlock(socache_mutex);
                    if (status != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02372)
                                "could not release lock, ignoring: %s", obj->key);
                    }
                }
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02373)
                            "Vary not written to cache, ignoring: %s", obj->key);
                    apr_pool_destroy(sobj->pool);
                    sobj->pool = NULL;
                    return rv;
                }
    
                obj->key = sobj->key = regen_key(r->pool, sobj->headers_in, varray,
                                                 sobj->name, NULL);
            }
        }
    
        socache_info->format = CACHE_SOCACHE_DISK_FORMAT_VERSION;
        socache_info->date = obj->info.date;
        socache_info->expire = obj->info.expire;
        socache_info->entity_version = sobj->socache_info.entity_version++;
        socache_info->request_time = obj->info.request_time;
        socache_info->response_time = obj->info.response_time;
        socache_info->status = obj->info.status;
    
        if (r->header_only && r->status != HTTP_NOT_MODIFIED) {
            socache_info->header_only = 1;
        }
        else {
            socache_info->header_only = sobj->socache_info.header_only;
        }
    
        socache_info->name_len = strlen(sobj->name);
    
        memcpy(&socache_info->control, &obj->info.control, sizeof(cache_control_t));
        slider = sizeof(cache_socache_info_t);
    
        if (slider + socache_info->name_len >= sobj->buffer_len) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02374)
                    "cache buffer too small for name: %s",
                    sobj->name);
            apr_pool_destroy(sobj->pool);
            sobj->pool = NULL;
            return APR_EGENERAL;
        }
        memcpy(sobj->buffer + slider, sobj->name, socache_info->name_len);
        slider += socache_info->name_len;
    
        if (sobj->headers_out) {
            if (APR_SUCCESS != store_table(sobj->headers_out, sobj->buffer,
                    sobj->buffer_len, &slider)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02375)
                        "out-headers didn't fit in buffer: %s", sobj->name);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return APR_EGENERAL;
            }
        }
    
        /* Parse the vary header and dump those fields from the headers_in. */
        /* TODO: Make call to the same thing cache_select calls to crack Vary. */
        if (sobj->headers_in) {
            if (APR_SUCCESS != store_table(sobj->headers_in, sobj->buffer,
                    sobj->buffer_len, &slider)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02376)
                        "in-headers didn't fit in buffer %s",
                        sobj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return APR_EGENERAL;
            }
        }
    
        sobj->body_offset = slider;
    
        return APR_SUCCESS;
    }
    
    static apr_status_t store_body(cache_handle_t *h, request_rec *r,
            apr_bucket_brigade *in, apr_bucket_brigade *out)
    {
        apr_bucket *e;
        apr_status_t rv = APR_SUCCESS;
        cache_socache_object_t *sobj =
                (cache_socache_object_t *) h->cache_obj->vobj;
        cache_socache_dir_conf *dconf =
                ap_get_module_config(r->per_dir_config, &cache_socache_module);
        int seen_eos = 0;
    
        if (!sobj->offset) {
            sobj->offset = dconf->readsize;
        }
        if (!sobj->timeout && dconf->readtime) {
            sobj->timeout = apr_time_now() + dconf->readtime;
        }
    
        if (!sobj->newbody) {
            sobj->body_length = 0;
            sobj->newbody = 1;
        }
        if (sobj->offset) {
            apr_brigade_partition(in, sobj->offset, &e);
        }
    
        while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(in)) {
            const char *str;
            apr_size_t length;
    
            e = APR_BRIGADE_FIRST(in);
    
            /* are we done completely? if so, pass any trailing buckets right through */
            if (sobj->done || !sobj->pool) {
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                continue;
            }
    
            /* have we seen eos yet? */
            if (APR_BUCKET_IS_EOS(e)) {
                seen_eos = 1;
                sobj->done = 1;
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                break;
            }
    
            /* honour flush buckets, we'll get called again */
            if (APR_BUCKET_IS_FLUSH(e)) {
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                break;
            }
    
            /* metadata buckets are preserved as is */
            if (APR_BUCKET_IS_METADATA(e)) {
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                continue;
            }
    
            /* read the bucket, write to the cache */
            rv = apr_bucket_read(e, &str, &length, APR_BLOCK_READ);
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(out, e);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02377)
                        "Error when reading bucket for URL %s",
                        h->cache_obj->key);
                /* Remove the intermediate cache file and return non-APR_SUCCESS */
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return rv;
            }
    
            /* don't write empty buckets to the cache */
            if (!length) {
                continue;
            }
    
            sobj->body_length += length;
            if (sobj->body_length >= sobj->buffer_len - sobj->body_offset) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02378)
                        "URL %s failed the buffer size check "
                        "(%" APR_OFF_T_FMT ">=%" APR_SIZE_T_FMT ")",
                        h->cache_obj->key, sobj->body_length,
                        sobj->buffer_len - sobj->body_offset);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return APR_EGENERAL;
            }
            memcpy(sobj->buffer + sobj->body_offset + sobj->body_length - length,
                   str, length);
    
            /* have we reached the limit of how much we're prepared to write in one
             * go? If so, leave, we'll get called again. This prevents us from trying
             * to swallow too much data at once, or taking so long to write the data
             * the client times out.
             */
            sobj->offset -= length;
            if (sobj->offset <= 0) {
                sobj->offset = 0;
                break;
            }
            if ((dconf->readtime && apr_time_now() > sobj->timeout)) {
                sobj->timeout = 0;
                break;
            }
    
        }
    
        /* Was this the final bucket? If yes, perform sanity checks.
         */
        if (seen_eos) {
            const char *cl_header;
            apr_off_t cl;
    
            if (r->connection->aborted || r->no_cache) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02380)
                        "Discarding body for URL %s "
                        "because connection has been aborted.",
                        h->cache_obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return APR_EGENERAL;
            }
    
            cl_header = apr_table_get(r->headers_out, "Content-Length");
            if (cl_header && (!ap_parse_strict_length(&cl, cl_header)
                              || cl != sobj->body_length)) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02381)
                        "URL %s didn't receive complete response, not caching",
                        h->cache_obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return APR_EGENERAL;
            }
    
            /* All checks were fine, we're good to go when the commit comes */
    
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t commit_entity(cache_handle_t *h, request_rec *r)
    {
        cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
                &cache_socache_module);
        cache_object_t *obj = h->cache_obj;
        cache_socache_object_t *sobj = (cache_socache_object_t *) obj->vobj;
        apr_status_t rv;
    
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_lock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02384)
                        "could not acquire lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return status;
            }
        }
        rv = conf->provider->socache_provider->store(
                conf->provider->socache_instance, r->server,
                (unsigned char *) sobj->key, strlen(sobj->key), sobj->expire,
                sobj->buffer, sobj->body_offset + sobj->body_length, sobj->pool);
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_unlock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02385)
                        "could not release lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return status;
            }
        }
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(02386)
                    "could not write to cache, ignoring: %s", sobj->key);
            goto fail;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02387)
                "commit_entity: Headers and body for URL %s cached for maximum of %d seconds.",
                sobj->name, (apr_uint32_t)apr_time_sec(sobj->expire - r->request_time));
    
        apr_pool_destroy(sobj->pool);
        sobj->pool = NULL;
    
        return APR_SUCCESS;
    
    fail:
        /* For safety, remove any existing entry on failure, just in case it could not
         * be revalidated successfully.
         */
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_lock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02388)
                        "could not acquire lock, ignoring: %s", obj->key);
                apr_pool_destroy(sobj->pool);
                sobj->pool = NULL;
                return rv;
            }
        }
        conf->provider->socache_provider->remove(conf->provider->socache_instance,
                r->server, (unsigned char *) sobj->key, strlen(sobj->key), r->pool);
        if (socache_mutex) {
            apr_status_t status = apr_global_mutex_unlock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02389)
                        "could not release lock, ignoring: %s", obj->key);
            }
        }
    
        apr_pool_destroy(sobj->pool);
        sobj->pool = NULL;
        return rv;
    }
    
    static apr_status_t invalidate_entity(cache_handle_t *h, request_rec *r)
    {
        /* mark the entity as invalidated */
        h->cache_obj->info.control.invalidated = 1;
    
        return commit_entity(h, r);
    }
    
    static void *create_dir_config(apr_pool_t *p, char *dummy)
    {
        cache_socache_dir_conf *dconf =
                apr_pcalloc(p, sizeof(cache_socache_dir_conf));
    
        dconf->max = DEFAULT_MAX_FILE_SIZE;
        dconf->maxtime = apr_time_from_sec(DEFAULT_MAXTIME);
        dconf->mintime = apr_time_from_sec(DEFAULT_MINTIME);
        dconf->readsize = DEFAULT_READSIZE;
        dconf->readtime = DEFAULT_READTIME;
    
        return dconf;
    }
    
    static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv)
    {
        cache_socache_dir_conf
                *new =
                        (cache_socache_dir_conf *) apr_pcalloc(p, sizeof(cache_socache_dir_conf));
        cache_socache_dir_conf *add = (cache_socache_dir_conf *) addv;
        cache_socache_dir_conf *base = (cache_socache_dir_conf *) basev;
    
        new->max = (add->max_set == 0) ? base->max : add->max;
        new->max_set = add->max_set || base->max_set;
        new->maxtime = (add->maxtime_set == 0) ? base->maxtime : add->maxtime;
        new->maxtime_set = add->maxtime_set || base->maxtime_set;
        new->mintime = (add->mintime_set == 0) ? base->mintime : add->mintime;
        new->mintime_set = add->mintime_set || base->mintime_set;
        new->readsize = (add->readsize_set == 0) ? base->readsize : add->readsize;
        new->readsize_set = add->readsize_set || base->readsize_set;
        new->readtime = (add->readtime_set == 0) ? base->readtime : add->readtime;
        new->readtime_set = add->readtime_set || base->readtime_set;
    
        return new;
    }
    
    static void *create_config(apr_pool_t *p, server_rec *s)
    {
        cache_socache_conf *conf = apr_pcalloc(p, sizeof(cache_socache_conf));
    
        return conf;
    }
    
    static void *merge_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        cache_socache_conf *ps;
        cache_socache_conf *base = (cache_socache_conf *) basev;
        cache_socache_conf *overrides = (cache_socache_conf *) overridesv;
    
        /* socache server config only has one field */
        ps = overrides ? overrides : base;
    
        return ps;
    }
    
    /*
     * mod_cache_socache configuration directives handlers.
     */
    static const char *set_cache_socache(cmd_parms *cmd, void *in_struct_ptr,
            const char *arg)
    {
        cache_socache_conf *conf = ap_get_module_config(cmd->server->module_config,
                &cache_socache_module);
        cache_socache_provider_conf *provider = conf->provider
                = apr_pcalloc(cmd->pool, sizeof(cache_socache_provider_conf));
    
        const char *err = NULL, *sep, *name;
    
        /* Argument is of form 'name:args' or just 'name'. */
        sep = ap_strchr_c(arg, ':');
        if (sep) {
            name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
            sep++;
            provider->args = sep;
        }
        else {
            name = arg;
        }
    
        provider->socache_provider = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
                name, AP_SOCACHE_PROVIDER_VERSION);
        if (provider->socache_provider == NULL) {
            err = apr_psprintf(cmd->pool,
                        "Unknown socache provider '%s'. Maybe you need "
                        "to load the appropriate socache module "
                        "(mod_socache_%s?)", name, name);
        }
        return err;
    }
    
    static const char *set_cache_max(cmd_parms *parms, void *in_struct_ptr,
            const char *arg)
    {
        cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
    
        if (apr_strtoff(&dconf->max, arg, NULL, 10) != APR_SUCCESS
                || dconf->max < 1024 || dconf->max > APR_UINT32_MAX) {
            return "CacheSocacheMaxSize argument must be a integer representing "
                   "the max size of a cached entry (headers and body), at least 1024 "
                   "and at most " APR_STRINGIFY(APR_UINT32_MAX);
        }
        dconf->max_set = 1;
        return NULL;
    }
    
    static const char *set_cache_maxtime(cmd_parms *parms, void *in_struct_ptr,
            const char *arg)
    {
        cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
        apr_off_t seconds;
    
        if (apr_strtoff(&seconds, arg, NULL, 10) != APR_SUCCESS || seconds < 0) {
            return "CacheSocacheMaxTime argument must be the maximum amount of time in seconds to cache an entry.";
        }
        dconf->maxtime = apr_time_from_sec(seconds);
        dconf->maxtime_set = 1;
        return NULL;
    }
    
    static const char *set_cache_mintime(cmd_parms *parms, void *in_struct_ptr,
            const char *arg)
    {
        cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
        apr_off_t seconds;
    
        if (apr_strtoff(&seconds, arg, NULL, 10) != APR_SUCCESS || seconds < 0) {
            return "CacheSocacheMinTime argument must be the minimum amount of time in seconds to cache an entry.";
        }
        dconf->mintime = apr_time_from_sec(seconds);
        dconf->mintime_set = 1;
        return NULL;
    }
    
    static const char *set_cache_readsize(cmd_parms *parms, void *in_struct_ptr,
            const char *arg)
    {
        cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
    
        if (apr_strtoff(&dconf->readsize, arg, NULL, 10) != APR_SUCCESS
                || dconf->readsize < 0) {
            return "CacheSocacheReadSize argument must be a non-negative integer representing the max amount of data to cache in go.";
        }
        dconf->readsize_set = 1;
        return NULL;
    }
    
    static const char *set_cache_readtime(cmd_parms *parms, void *in_struct_ptr,
            const char *arg)
    {
        cache_socache_dir_conf *dconf = (cache_socache_dir_conf *) in_struct_ptr;
        apr_off_t milliseconds;
    
        if (apr_strtoff(&milliseconds, arg, NULL, 10) != APR_SUCCESS
                || milliseconds < 0) {
            return "CacheSocacheReadTime argument must be a non-negative integer representing the max amount of time taken to cache in go.";
        }
        dconf->readtime = apr_time_from_msec(milliseconds);
        dconf->readtime_set = 1;
        return NULL;
    }
    
    static apr_status_t remove_lock(void *data)
    {
        if (socache_mutex) {
            apr_global_mutex_destroy(socache_mutex);
            socache_mutex = NULL;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t destroy_cache(void *data)
    {
        server_rec *s = data;
        cache_socache_conf *conf =
                ap_get_module_config(s->module_config, &cache_socache_module);
        if (conf->provider && conf->provider->socache_instance) {
            conf->provider->socache_provider->destroy(
                    conf->provider->socache_instance, s);
            conf->provider->socache_instance = NULL;
        }
        return APR_SUCCESS;
    }
    
    static int socache_status_hook(request_rec *r, int flags)
    {
        apr_status_t status = APR_SUCCESS;
        cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
                                                        &cache_socache_module);
        if (!conf->provider || !conf->provider->socache_provider ||
            !conf->provider->socache_instance) {
            return DECLINED;
        }
    
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rputs("<hr>\n"
                     "<table cellspacing=0 cellpadding=0>\n"
                     "<tr><td bgcolor=\"#000000\">\n"
                     "<b><font color=\"#ffffff\" face=\"Arial,Helvetica\">"
                     "mod_cache_socache Status:</font></b>\n"
                     "</td></tr>\n"
                     "<tr><td bgcolor=\"#ffffff\">\n", r);
        }
        else {
            ap_rputs("ModCacheSocacheStatus\n", r);
        }
    
        if (socache_mutex) {
            status = apr_global_mutex_lock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02816)
                        "could not acquire lock for cache status");
            }
        }
    
        if (status != APR_SUCCESS) {
            if (!(flags & AP_STATUS_SHORT)) {
                ap_rputs("No cache status data available\n", r);
            }
            else {
                ap_rputs("NotAvailable\n", r);
            }
        } else {
            conf->provider->socache_provider->status(conf->provider->socache_instance,
                                                     r, flags);
        }
    
        if (socache_mutex && status == APR_SUCCESS) {
            status = apr_global_mutex_unlock(socache_mutex);
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02817)
                        "could not release lock for cache status");
            }
        }
    
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rputs("</td></tr>\n</table>\n", r);
        }
        return OK;
    }
    
    static void socache_status_register(apr_pool_t *p)
    {
        APR_OPTIONAL_HOOK(ap, status_hook, socache_status_hook, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    static int socache_precfg(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptmp)
    {
        apr_status_t rv = ap_mutex_register(pconf, cache_socache_id, NULL,
                APR_LOCK_DEFAULT, 0);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02390)
                    "failed to register %s mutex", cache_socache_id);
            return 500; /* An HTTP status would be a misnomer! */
        }
    
        /* Register to handle mod_status status page generation */
        socache_status_register(pconf);
    
        return OK;
    }
    
    static int socache_post_config(apr_pool_t *pconf, apr_pool_t *plog,
            apr_pool_t *ptmp, server_rec *base_server)
    {
        server_rec *s;
        apr_status_t rv;
        const char *errmsg;
        static struct ap_socache_hints socache_hints =
        { 64, 2048, 60000000 };
    
        for (s = base_server; s; s = s->next) {
            cache_socache_conf *conf =
                    ap_get_module_config(s->module_config, &cache_socache_module);
    
            if (!conf->provider) {
                continue;
            }
    
            if (!socache_mutex && conf->provider->socache_provider->flags
                    & AP_SOCACHE_FLAG_NOTMPSAFE) {
    
                rv = ap_global_mutex_create(&socache_mutex, NULL, cache_socache_id,
                        NULL, s, pconf, 0);
                if (rv != APR_SUCCESS) {
                    ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02391)
                            "failed to create %s mutex", cache_socache_id);
                    return 500; /* An HTTP status would be a misnomer! */
                }
                apr_pool_cleanup_register(pconf, NULL, remove_lock,
                        apr_pool_cleanup_null);
            }
    
            errmsg = conf->provider->socache_provider->create(
                    &conf->provider->socache_instance, conf->provider->args, ptmp,
                    pconf);
            if (errmsg) {
                ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog,
                        APLOGNO(02392) "%s", errmsg);
                return 500; /* An HTTP status would be a misnomer! */
            }
    
            rv = conf->provider->socache_provider->init(
                    conf->provider->socache_instance, cache_socache_id,
                    &socache_hints, s, pconf);
            if (rv != APR_SUCCESS) {
                ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02393)
                        "failed to initialise %s cache", cache_socache_id);
                return 500; /* An HTTP status would be a misnomer! */
            }
            apr_pool_cleanup_register(pconf, (void *) s, destroy_cache,
                    apr_pool_cleanup_null);
    
        }
    
        return OK;
    }
    
    static void socache_child_init(apr_pool_t *p, server_rec *s)
    {
        const char *lock;
        apr_status_t rv;
        if (!socache_mutex) {
            return; /* don't waste the overhead of creating mutex & cache */
        }
        lock = apr_global_mutex_lockfile(socache_mutex);
        rv = apr_global_mutex_child_init(&socache_mutex, lock, p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(02394)
                    "failed to initialise mutex in child_init");
        }
    }
    
    static const command_rec cache_socache_cmds[] =
    {
        AP_INIT_TAKE1("CacheSocache", set_cache_socache, NULL, RSRC_CONF,
                "The shared object cache to store cache files"),
        AP_INIT_TAKE1("CacheSocacheMaxTime", set_cache_maxtime, NULL, RSRC_CONF | ACCESS_CONF,
                "The maximum cache expiry age to cache a document in seconds"),
        AP_INIT_TAKE1("CacheSocacheMinTime", set_cache_mintime, NULL, RSRC_CONF | ACCESS_CONF,
                "The minimum cache expiry age to cache a document in seconds"),
        AP_INIT_TAKE1("CacheSocacheMaxSize", set_cache_max, NULL, RSRC_CONF | ACCESS_CONF,
                "The maximum cache entry size (headers and body) to cache a document"),
        AP_INIT_TAKE1("CacheSocacheReadSize", set_cache_readsize, NULL, RSRC_CONF | ACCESS_CONF,
                "The maximum quantity of data to attempt to read and cache in one go"),
        AP_INIT_TAKE1("CacheSocacheReadTime", set_cache_readtime, NULL, RSRC_CONF | ACCESS_CONF,
                "The maximum time taken to attempt to read and cache in go"),
        { NULL }
    };
    
    static const cache_provider cache_socache_provider =
    {
        &remove_entity, &store_headers, &store_body, &recall_headers, &recall_body,
        &create_entity, &open_entity, &remove_url, &commit_entity,
        &invalidate_entity
    };
    
    static void cache_socache_register_hook(apr_pool_t *p)
    {
        /* cache initializer */
        ap_register_provider(p, CACHE_PROVIDER_GROUP, "socache", "0",
                &cache_socache_provider);
        ap_hook_pre_config(socache_precfg, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_config(socache_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_child_init(socache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(cache_socache) = { STANDARD20_MODULE_STUFF,
        create_dir_config,  /* create per-directory config structure */
        merge_dir_config, /* merge per-directory config structures */
        create_config, /* create per-server config structure */
        merge_config, /* merge per-server config structures */
        cache_socache_cmds, /* command apr_table_t */
        cache_socache_register_hook /* register hooks */
    };
    ���������������������������������������httpd-2.4.64/modules/cache/mod_socache_memcache.c���������������������������������������������������0000664�0001751�0001751�00000034776�14205766751�021625� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
    * this work for additional information regarding copyright ownership.
    * The ASF licenses this file to You under the Apache License, Version 2.0
    * (the "License"); you may not use this file except in compliance with
    * the License.  You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT 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_protocol.h"
    
    #include "apr.h"
    
    #include "ap_socache.h"
    #include "ap_mpm.h"
    #include "http_log.h"
    #include "apr_memcache.h"
    #include "apr_strings.h"
    #include "mod_status.h"
    
    /* The underlying apr_memcache system is thread safe.. */
    #define MC_KEY_LEN 254
    
    #ifndef MC_DEFAULT_SERVER_PORT
    #define MC_DEFAULT_SERVER_PORT 11211
    #endif
    
    
    #ifndef MC_DEFAULT_SERVER_MIN
    #define MC_DEFAULT_SERVER_MIN 0
    #endif
    
    #ifndef MC_DEFAULT_SERVER_SMAX
    #define MC_DEFAULT_SERVER_SMAX 1
    #endif
    
    #ifndef MC_DEFAULT_SERVER_TTL
    #define MC_DEFAULT_SERVER_TTL    apr_time_from_sec(15)
    #endif
    
    module AP_MODULE_DECLARE_DATA socache_memcache_module;
    
    typedef struct {
        apr_uint32_t ttl;
    } socache_mc_svr_cfg;
    
    struct ap_socache_instance_t {
        const char *servers;
        apr_memcache_t *mc;
        const char *tag;
        apr_size_t taglen; /* strlen(tag) + 1 */
    };
    
    static const char *socache_mc_create(ap_socache_instance_t **context,
                                         const char *arg,
                                         apr_pool_t *tmp, apr_pool_t *p)
    {
        ap_socache_instance_t *ctx;
    
        *context = ctx = apr_palloc(p, sizeof *ctx);
    
        if (!arg || !*arg) {
            return "List of server names required to create memcache socache.";
        }
    
        ctx->servers = apr_pstrdup(p, arg);
    
        return NULL;
    }
    
    static apr_status_t socache_mc_init(ap_socache_instance_t *ctx,
                                        const char *namespace,
                                        const struct ap_socache_hints *hints,
                                        server_rec *s, apr_pool_t *p)
    {
        apr_status_t rv;
        int thread_limit = 0;
        apr_uint16_t nservers = 0;
        char *cache_config;
        char *split;
        char *tok;
    
        socache_mc_svr_cfg *sconf = ap_get_module_config(s->module_config,
                                                         &socache_memcache_module);
    
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
    
        /* Find all the servers in the first run to get a total count */
        cache_config = apr_pstrdup(p, ctx->servers);
        split = apr_strtok(cache_config, ",", &tok);
        while (split) {
            nservers++;
            split = apr_strtok(NULL,",", &tok);
        }
    
        rv = apr_memcache_create(p, nservers, 0, &ctx->mc);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00785)
                         "Failed to create Memcache Object of '%d' size.",
                         nservers);
            return rv;
        }
    
        /* Now add each server to the memcache */
        cache_config = apr_pstrdup(p, ctx->servers);
        split = apr_strtok(cache_config, ",", &tok);
        while (split) {
            apr_memcache_server_t *st;
            char *host_str;
            char *scope_id;
            apr_port_t port;
    
            rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00786)
                             "Failed to Parse memcache Server: '%s'", split);
                return rv;
            }
    
            if (host_str == NULL) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00787)
                             "Failed to Parse Server, "
                             "no hostname specified: '%s'", split);
                return APR_EINVAL;
            }
    
            if (port == 0) {
                port = MC_DEFAULT_SERVER_PORT;
            }
    
            rv = apr_memcache_server_create(p,
                                            host_str, port,
                                            MC_DEFAULT_SERVER_MIN,
                                            MC_DEFAULT_SERVER_SMAX,
                                            thread_limit,
                                            sconf->ttl,
                                            &st);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00788)
                             "Failed to Create memcache Server: %s:%d",
                             host_str, port);
                return rv;
            }
    
            rv = apr_memcache_add_server(ctx->mc, st);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00789)
                             "Failed to Add memcache Server: %s:%d",
                             host_str, port);
                return rv;
            }
    
            split = apr_strtok(NULL,",", &tok);
        }
    
        ctx->tag = apr_pstrcat(p, namespace, ":", NULL);
        ctx->taglen = strlen(ctx->tag) + 1;
    
        /* socache API constraint: */
        AP_DEBUG_ASSERT(ctx->taglen <= 16);
    
        return APR_SUCCESS;
    }
    
    static void socache_mc_destroy(ap_socache_instance_t *context, server_rec *s)
    {
        /* noop. */
    }
    
    /* Converts (binary) id into a key prefixed by the predetermined
     * namespace tag; writes output to key buffer.  Returns non-zero if
     * the id won't fit in the key buffer. */
    static int socache_mc_id2key(ap_socache_instance_t *ctx,
                                 const unsigned char *id, unsigned int idlen,
                                 char *key, apr_size_t keylen)
    {
        char *cp;
    
        if (idlen * 2 + ctx->taglen >= keylen)
            return 1;
    
        cp = apr_cpystrn(key, ctx->tag, ctx->taglen);
        ap_bin2hex(id, idlen, cp);
    
        return 0;
    }
    
    static apr_status_t socache_mc_store(ap_socache_instance_t *ctx, server_rec *s,
                                         const unsigned char *id, unsigned int idlen,
                                         apr_time_t expiry,
                                         unsigned char *ucaData, unsigned int nData,
                                         apr_pool_t *p)
    {
        char buf[MC_KEY_LEN];
        apr_status_t rv;
    
        if (socache_mc_id2key(ctx, id, idlen, buf, sizeof buf)) {
            return APR_EINVAL;
        }
    
        /* memcache needs time in seconds till expiry; fail if this is not
         * positive *before* casting to unsigned (apr_uint32_t). */
        expiry -= apr_time_now();
        if (apr_time_sec(expiry) <= 0) {
            return APR_EINVAL;
        }
        rv = apr_memcache_set(ctx->mc, buf, (char*)ucaData, nData,
                              apr_time_sec(expiry), 0);
    
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00790)
                         "scache_mc: error setting key '%s' "
                         "with %d bytes of data", buf, nData);
            return rv;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_mc_retrieve(ap_socache_instance_t *ctx, server_rec *s,
                                            const unsigned char *id, unsigned int idlen,
                                            unsigned char *dest, unsigned int *destlen,
                                            apr_pool_t *p)
    {
        apr_size_t data_len;
        char buf[MC_KEY_LEN], *data;
        apr_status_t rv;
    
        if (socache_mc_id2key(ctx, id, idlen, buf, sizeof buf)) {
            return APR_EINVAL;
        }
    
        /* ### this could do with a subpool, but _getp looks like it will
         * eat memory like it's going out of fashion anyway. */
    
        rv = apr_memcache_getp(ctx->mc, p, buf, &data, &data_len, NULL);
        if (rv) {
            if (rv != APR_NOTFOUND) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00791)
                             "scache_mc: 'retrieve' FAIL");
            }
            return rv;
        }
        else if (data_len > *destlen) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00792)
                         "scache_mc: 'retrieve' OVERFLOW");
            return APR_ENOMEM;
        }
    
        memcpy(dest, data, data_len);
        *destlen = data_len;
    
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_mc_remove(ap_socache_instance_t *ctx, server_rec *s,
                                          const unsigned char *id,
                                          unsigned int idlen, apr_pool_t *p)
    {
        char buf[MC_KEY_LEN];
        apr_status_t rv;
    
        if (socache_mc_id2key(ctx, id, idlen, buf, sizeof buf)) {
            return APR_EINVAL;
        }
    
        rv = apr_memcache_delete(ctx->mc, buf, 0);
    
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00793)
                         "scache_mc: error deleting key '%s' ",
                         buf);
        }
    
        return rv;
    }
    
    static void socache_mc_status(ap_socache_instance_t *ctx, request_rec *r, int flags)
    {
        apr_memcache_t *rc = ctx->mc;
        int i;
    
        for (i = 0; i < rc->ntotal; i++) {
            apr_memcache_server_t *ms;
            apr_memcache_stats_t *stats;
            apr_status_t rv;
            char *br = (!(flags & AP_STATUS_SHORT) ? "<br />" : "");
    
            ms = rc->live_servers[i];
    
            ap_rprintf(r, "Memcached server: %s:%d [%s]%s\n", ms->host, (int)ms->port,
                    (ms->status == APR_MC_SERVER_LIVE) ? "Up" : "Down",
                    br);
            rv = apr_memcache_stats(ms, r->pool, &stats);
            if (rv != APR_SUCCESS)
                continue;
            if (!(flags & AP_STATUS_SHORT)) {
                ap_rprintf(r, "<b>Version:</b> <i>%s</i> [%u bits], PID: <i>%u</i>, Uptime: <i>%u hrs</i> <br />\n",
                        stats->version , stats->pointer_size, stats->pid, stats->uptime/3600);
                ap_rprintf(r, "<b>Clients::</b> Structures: <i>%u</i>, Total: <i>%u</i>, Current: <i>%u</i> <br />\n",
                        stats->connection_structures, stats->total_connections, stats->curr_connections);
                ap_rprintf(r, "<b>Storage::</b> Total Items: <i>%u</i>, Current Items: <i>%u</i>, Bytes: <i>%" APR_UINT64_T_FMT "</i> <br />\n",
                        stats->total_items, stats->curr_items, stats->bytes);
                ap_rprintf(r, "<b>CPU::</b> System: <i>%u</i>, User: <i>%u</i> <br />\n",
                        (unsigned)stats->rusage_system, (unsigned)stats->rusage_user );
                ap_rprintf(r, "<b>Cache::</b> Gets: <i>%u</i>, Sets: <i>%u</i>, Hits: <i>%u</i>, Misses: <i>%u</i> <br />\n",
                        stats->cmd_get, stats->cmd_set, stats->get_hits, stats->get_misses);
                ap_rprintf(r, "<b>Net::</b> Input bytes: <i>%" APR_UINT64_T_FMT "</i>, Output bytes: <i>%" APR_UINT64_T_FMT "</i> <br />\n",
                        stats->bytes_read, stats->bytes_written);
                ap_rprintf(r, "<b>Misc::</b> Evictions: <i>%" APR_UINT64_T_FMT "</i>, MaxMem: <i>%u</i>, Threads: <i>%u</i> <br />\n",
                        stats->evictions, stats->limit_maxbytes, stats->threads);
                ap_rputs("<hr><br />\n", r);
            }
            else {
                ap_rprintf(r, "Version: %s [%u bits], PID: %u, Uptime: %u hrs %s\n",
                        stats->version , stats->pointer_size, stats->pid, stats->uptime/3600, br);
                ap_rprintf(r, "Clients:: Structures: %d, Total: %d, Current: %u %s\n",
                        stats->connection_structures, stats->total_connections, stats->curr_connections, br);
                ap_rprintf(r, "Storage:: Total Items: %u, Current Items: %u, Bytes: %" APR_UINT64_T_FMT " %s\n",
                        stats->total_items, stats->curr_items, stats->bytes, br);
                ap_rprintf(r, "CPU:: System: %u, User: %u %s\n",
                        (unsigned)stats->rusage_system, (unsigned)stats->rusage_user , br);
                ap_rprintf(r, "Cache:: Gets: %u, Sets: %u, Hits: %u, Misses: %u %s\n",
                        stats->cmd_get, stats->cmd_set, stats->get_hits, stats->get_misses, br);
                ap_rprintf(r, "Net:: Input bytes: %" APR_UINT64_T_FMT ", Output bytes: %" APR_UINT64_T_FMT " %s\n",
                        stats->bytes_read, stats->bytes_written, br);
                ap_rprintf(r, "Misc:: Evictions: %" APR_UINT64_T_FMT ", MaxMem: %u, Threads: %u %s\n",
                        stats->evictions, stats->limit_maxbytes, stats->threads, br);
            }
        }
    
    }
    
    static apr_status_t socache_mc_iterate(ap_socache_instance_t *instance,
                                           server_rec *s, void *userctx,
                                           ap_socache_iterator_t *iterator,
                                           apr_pool_t *pool)
    {
        return APR_ENOTIMPL;
    }
    
    static const ap_socache_provider_t socache_mc = {
        "memcache",
        0,
        socache_mc_create,
        socache_mc_init,
        socache_mc_destroy,
        socache_mc_store,
        socache_mc_retrieve,
        socache_mc_remove,
        socache_mc_status,
        socache_mc_iterate
    };
    
    static void *create_server_config(apr_pool_t *p, server_rec *s)
    {
        socache_mc_svr_cfg *sconf = apr_pcalloc(p, sizeof(socache_mc_svr_cfg));
        
        sconf->ttl = MC_DEFAULT_SERVER_TTL;
    
        return sconf;
    }
    
    static const char *socache_mc_set_ttl(cmd_parms *cmd, void *dummy,
                                          const char *arg)
    {
        apr_interval_time_t ttl;
        socache_mc_svr_cfg *sconf = ap_get_module_config(cmd->server->module_config,
                                                         &socache_memcache_module);
    
        if (ap_timeout_parameter_parse(arg, &ttl, "s") != APR_SUCCESS) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               " has wrong format", NULL);
        }
    
        if ((ttl < apr_time_from_sec(0)) || (ttl > apr_time_from_sec(3600))) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               " can only be 0 or up to one hour.", NULL);
        }
    
        /* apr_memcache_server_create needs a ttl in usec. */
        sconf->ttl = ttl;
    
        return NULL;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "memcache",
                             AP_SOCACHE_PROVIDER_VERSION,
                             &socache_mc);
    }
    
    static const command_rec socache_memcache_cmds[] = {
        AP_INIT_TAKE1("MemcacheConnTTL", socache_mc_set_ttl, NULL, RSRC_CONF,
                      "TTL used for the connection with the memcache server(s)"),
        { NULL }
    };
    
    AP_DECLARE_MODULE(socache_memcache) = {
        STANDARD20_MODULE_STUFF,
        NULL,                     /* create per-dir    config structures */
        NULL,                     /* merge  per-dir    config structures */
        create_server_config,     /* create per-server config structures */
        NULL,                     /* merge  per-server config structures */
        socache_memcache_cmds,    /* table of config file commands       */
        register_hooks            /* register hooks                      */
    };
    ��httpd-2.4.64/modules/cache/mod_cache_disk.dsp�������������������������������������������������������0000664�0001751�0001751�00000010617�11471761032�020770� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_cache_disk" - 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_disk - 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_disk.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_disk.mak" CFG="mod_cache_disk - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_cache_disk - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_cache_disk - 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_disk - 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_cache_disk_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 /fo"Release/mod_cache_disk.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cache_disk.so" /d LONG_NAME="cache_disk_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_cache_disk.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_disk.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_cache_disk.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_cache_disk - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fd"Debug\mod_cache_disk_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 /fo"Debug/mod_cache_disk.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cache_disk.so" /d LONG_NAME="cache_disk_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_cache_disk.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_disk.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_cache_disk.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_cache_disk - Win32 Release"
    # Name "mod_cache_disk - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_cache.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_cache_disk.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/NWGNUmod_cach������������������������������������������������������������0000664�0001751�0001751�00000010535�11540546347�017651� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/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	+= \
    			-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	=
    
    #
    # 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 this is 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		=
    
    #
    # 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)
    
    #
    # 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 = \
    	$(PRELUDE) \
    	$(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 \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache.dsp������������������������������������������������������������0000664�0001751�0001751�00000011250�11022330134�017733� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cache.so" /d LONG_NAME="cache_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cache.so" /d LONG_NAME="cache_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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_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=.\mod_cache.h
    # End Source File
    # End Group
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_disk.h���������������������������������������������������������0000664�0001751�0001751�00000006374�11662033112�020427� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_DISK_H
    #define MOD_CACHE_DISK_H
    
    #include "apr_file_io.h"
    
    #include "cache_disk_common.h"
    
    /*
     * include for mod_cache_disk: Disk Based HTTP 1.1 Cache.
     */
    
    typedef struct {
        apr_pool_t *pool;
        const char *file;
        apr_file_t *fd;
        char *tempfile;
        apr_file_t *tempfd;
    } disk_cache_file_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 */
        apr_size_t root_len;
        const char *prefix;
        disk_cache_file_t data;      /* data file structure */
        disk_cache_file_t hdrs;      /* headers file structure */
        disk_cache_file_t vary;      /* vary file structure */
        const char *hashfile;        /* Computed hash key for this URI */
        const char *name;            /* Requested URI without vary bits - suitable for mortals. */
        const char *key;             /* On-disk prefix; URI with Vary bits (if present) */
        apr_off_t file_size;         /*  File size of the cached data file  */
        disk_cache_info_t disk_info; /* Header information. */
        apr_table_t *headers_in;     /* Input headers to save */
        apr_table_t *headers_out;    /* Output headers to save */
        apr_off_t offset;            /* Max size to set aside */
        apr_time_t timeout;          /* Max time to set aside */
        unsigned int done:1;         /* Is the attempt to cache complete? */
    } disk_cache_object_t;
    
    
    /*
     * mod_cache_disk configuration
     */
    /* TODO: Make defaults OS specific */
    #define CACHEFILE_LEN 20        /* must be less than HASH_LEN/2 */
    #define DEFAULT_DIRLEVELS 2
    #define DEFAULT_DIRLENGTH 2
    #define DEFAULT_MIN_FILE_SIZE 1
    #define DEFAULT_MAX_FILE_SIZE 1000000
    #define DEFAULT_READSIZE 0
    #define DEFAULT_READTIME 0
    
    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 */
    } disk_cache_conf;
    
    typedef struct {
        apr_off_t minfs;             /* minimum file size for cached files */
        apr_off_t maxfs;             /* maximum file size for cached files */
        apr_off_t readsize;          /* maximum data to attempt to cache in one go */
        apr_time_t readtime;         /* maximum time taken to cache in one go */
        unsigned int minfs_set:1;
        unsigned int maxfs_set:1;
        unsigned int readsize_set:1;
        unsigned int readtime_set:1;
    } disk_cache_dir_conf;
    
    #endif /*MOD_CACHE_DISK_H*/
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_file_cache.exp�������������������������������������������������������0000664�0001751�0001751�00000000022�10150161574�020746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������file_cache_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_dbm.c��������������������������������������������������������0000664�0001751�0001751�00000064002�14210356064�020572� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "http_request.h"
    #include "http_protocol.h"
    #include "http_config.h"
    #include "mpm_common.h"
    #include "mod_status.h"
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_time.h"
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    #include "apr_dbm.h"
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    #include "ap_socache.h"
    
    #if AP_NEED_SET_MUTEX_PERMS
    #include "unixd.h"
    #endif
    
    /* Use of the context structure must be thread-safe after the initial
     * create/init; callers must hold the mutex. */
    struct ap_socache_instance_t {
        const char *data_file;
        /* Pool must only be used with the mutex held. */
        apr_pool_t *pool;
        apr_time_t last_expiry;
        apr_interval_time_t expiry_interval;
    };
    
    /**
     * Support for DBM library
     */
    #define DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
    
    #define DEFAULT_DBM_PREFIX "socache-dbm-"
    
    /* ### this should use apr_dbm_usednames. */
    #if !defined(DBM_FILE_SUFFIX_DIR) && !defined(DBM_FILE_SUFFIX_PAG)
    #if defined(DBM_SUFFIX)
    #define DBM_FILE_SUFFIX_DIR DBM_SUFFIX
    #define DBM_FILE_SUFFIX_PAG DBM_SUFFIX
    #elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM))
    #define DBM_FILE_SUFFIX_DIR ".db"
    #define DBM_FILE_SUFFIX_PAG ".db"
    #else
    #define DBM_FILE_SUFFIX_DIR ".dir"
    #define DBM_FILE_SUFFIX_PAG ".pag"
    #endif
    #endif
    
    static void socache_dbm_expire(ap_socache_instance_t *ctx, server_rec *s);
    
    static apr_status_t socache_dbm_remove(ap_socache_instance_t *ctx,
                                           server_rec *s, const unsigned char *id,
                                           unsigned int idlen, apr_pool_t *p);
    
    static const char *socache_dbm_create(ap_socache_instance_t **context,
                                          const char *arg,
                                          apr_pool_t *tmp, apr_pool_t *p)
    {
        ap_socache_instance_t *ctx;
    
        *context = ctx = apr_pcalloc(p, sizeof *ctx);
    
        if (arg && *arg) {
            ctx->data_file = ap_server_root_relative(p, arg);
            if (!ctx->data_file) {
                return apr_psprintf(tmp, "Invalid cache file path %s", arg);
            }
        }
    
        apr_pool_create(&ctx->pool, p);
        apr_pool_tag(ctx->pool, "socache_dbm_instance");
    
        return NULL;
    }
    
    #if AP_NEED_SET_MUTEX_PERMS
    static int try_chown(apr_pool_t *p, server_rec *s,
                         const char *name, const char *suffix)
    {
        if (suffix)
            name = apr_pstrcat(p, name, suffix, NULL);
        if (-1 == chown(name, ap_unixd_config.user_id,
                        (gid_t)-1 /* no gid change */ ))
        {
            if (errno != ENOENT)
                ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(errno), s, APLOGNO(00802)
                             "Can't change owner of %s", name);
            return -1;
        }
        return 0;
    }
    #endif
    
    
    static apr_status_t socache_dbm_init(ap_socache_instance_t *ctx,
                                         const char *namespace,
                                         const struct ap_socache_hints *hints,
                                         server_rec *s, apr_pool_t *p)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *dbm;
        apr_status_t rv;
    
        /* for the DBM we need the data file */
        if (ctx->data_file == NULL) {
            const char *path = apr_pstrcat(p, DEFAULT_DBM_PREFIX, namespace,
                                           NULL);
    
            ctx->data_file = ap_runtime_dir_relative(p, path);
    
            if (ctx->data_file == NULL) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00803)
                             "could not use default path '%s' for DBM socache",
                             path);
                return APR_EINVAL;
            }
        }
    
        /* open it once to create it and to make sure it _can_ be created */
        apr_pool_clear(ctx->pool);
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
                ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10277)
                    "Cannot load socache DBM library '%s': %s",
                         err->reason, err->msg);
            return rv;
        }
        if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
                APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00804)
                         "Cannot create socache DBM file `%s'",
                         ctx->data_file);
            return DECLINED;
        }
    #else
        if ((rv = apr_dbm_open(&dbm, ctx->data_file,
                APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00804)
                         "Cannot create socache DBM file `%s'",
                         ctx->data_file);
            return rv;
        }
    #endif
        apr_dbm_close(dbm);
    
        ctx->expiry_interval = (hints && hints->expiry_interval
                                ? hints->expiry_interval : apr_time_from_sec(30));
    
    #if AP_NEED_SET_MUTEX_PERMS
        /*
         * 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 */) {
            try_chown(p, s, ctx->data_file, NULL);
            if (try_chown(p, s, ctx->data_file, DBM_FILE_SUFFIX_DIR))
                if (try_chown(p, s, ctx->data_file, ".db"))
                    try_chown(p, s, ctx->data_file, ".dir");
            if (try_chown(p, s, ctx->data_file, DBM_FILE_SUFFIX_PAG))
                if (try_chown(p, s, ctx->data_file, ".db"))
                    try_chown(p, s, ctx->data_file, ".pag");
        }
    #endif
        socache_dbm_expire(ctx, s);
    
        return APR_SUCCESS;
    }
    
    static void socache_dbm_destroy(ap_socache_instance_t *ctx, server_rec *s)
    {
        /* the correct way */
        unlink(apr_pstrcat(ctx->pool, ctx->data_file, DBM_FILE_SUFFIX_DIR, NULL));
        unlink(apr_pstrcat(ctx->pool, ctx->data_file, DBM_FILE_SUFFIX_PAG, NULL));
        /* the additional ways to be sure */
        unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".dir", NULL));
        unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".pag", NULL));
        unlink(apr_pstrcat(ctx->pool, ctx->data_file, ".db", NULL));
        unlink(ctx->data_file);
    }
    
    static apr_status_t socache_dbm_store(ap_socache_instance_t *ctx,
                                          server_rec *s, const unsigned char *id,
                                          unsigned int idlen, apr_time_t expiry,
                                          unsigned char *ucaData,
                                          unsigned int nData, apr_pool_t *pool)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *dbm;
        apr_datum_t dbmkey;
        apr_datum_t dbmval;
        apr_status_t rv;
    
        /* 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, APLOGNO(00805)
                     "data size too large for DBM socache: %d >= %d",
                     (idlen + nData), PAIRMAX);
            return APR_ENOSPC;
        }
    #else
        if ((idlen + nData) >= 950 /* at least less than approx. 1KB */) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00806)
                     "data size too large for DBM socache: %d >= %d",
                     (idlen + nData), 950);
            return APR_ENOSPC;
        }
    #endif
    
        /* create DBM key */
        dbmkey.dptr  = (char *)id;
        dbmkey.dsize = idlen;
    
        /* create DBM value */
        dbmval.dsize = sizeof(apr_time_t) + nData;
        dbmval.dptr  = (char *)ap_malloc(dbmval.dsize);
        memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t));
        memcpy((char *)dbmval.dptr+sizeof(apr_time_t), ucaData, nData);
    
        /* and store it to the DBM file */
        apr_pool_clear(ctx->pool);
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
                ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10278)
                    "Cannot load socache DBM library '%s' (store): %s",
                         err->reason, err->msg);
            free(dbmval.dptr);
            return rv;
        }
        if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
                APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00807)
                         "Cannot open socache DBM file `%s' for writing "
                         "(store)",
                         ctx->data_file);
            free(dbmval.dptr);
            return rv;
        }
    #else
        if ((rv = apr_dbm_open(&dbm, ctx->data_file,
                               APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00807)
                         "Cannot open socache DBM file `%s' for writing "
                         "(store)",
                         ctx->data_file);
            free(dbmval.dptr);
            return rv;
        }
    #endif
        if ((rv = apr_dbm_store(dbm, dbmkey, dbmval)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00808)
                         "Cannot store socache object to DBM file `%s'",
                         ctx->data_file);
            apr_dbm_close(dbm);
            free(dbmval.dptr);
            return rv;
        }
        apr_dbm_close(dbm);
    
        /* free temporary buffers */
        free(dbmval.dptr);
    
        /* allow the regular expiring to occur */
        socache_dbm_expire(ctx, s);
    
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_dbm_retrieve(ap_socache_instance_t *ctx, server_rec *s,
                                             const unsigned char *id, unsigned int idlen,
                                             unsigned char *dest, unsigned int *destlen,
                                             apr_pool_t *p)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *dbm;
        apr_datum_t dbmkey;
        apr_datum_t dbmval;
        unsigned int nData;
        apr_time_t expiry;
        apr_time_t now;
        apr_status_t rc;
    
        /* allow the regular expiring to occur */
        socache_dbm_expire(ctx, 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.
         */
        apr_pool_clear(ctx->pool);
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
                ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10279)
                    "Cannot load socache DBM library '%s' (fetch): %s",
                         err->reason, err->msg);
            return rc;
        }
        if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
                APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, APLOGNO(00809)
                         "Cannot open socache DBM file `%s' for reading "
                         "(fetch)",
                         ctx->data_file);
            return rc;
        }
    #else
        if ((rc = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, APLOGNO(00809)
                         "Cannot open socache DBM file `%s' for reading "
                         "(fetch)",
                         ctx->data_file);
            return rc;
        }
    #endif
        rc = apr_dbm_fetch(dbm, dbmkey, &dbmval);
        if (rc != APR_SUCCESS) {
            apr_dbm_close(dbm);
            return APR_NOTFOUND;
        }
        if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) {
            apr_dbm_close(dbm);
            return APR_EGENERAL;
        }
    
        /* parse resulting data */
        nData = dbmval.dsize-sizeof(apr_time_t);
        if (nData > *destlen) {
            apr_dbm_close(dbm);
            return APR_ENOSPC;
        }
    
        *destlen = nData;
        memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
        memcpy(dest, (char *)dbmval.dptr + sizeof(apr_time_t), nData);
    
        apr_dbm_close(dbm);
    
        /* make sure the stuff is still not expired */
        now = apr_time_now();
        if (expiry <= now) {
            socache_dbm_remove(ctx, s, id, idlen, p);
            return APR_NOTFOUND;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_dbm_remove(ap_socache_instance_t *ctx,
                                           server_rec *s, const unsigned char *id,
                                           unsigned int idlen, apr_pool_t *p)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        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 */
        apr_pool_clear(ctx->pool);
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
                ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10280)
                    "Cannot load socache DBM library '%s' (delete): %s",
                         err->reason, err->msg);
            return rv;
        }
        if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file,
                APR_DBM_RWCREATE, DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00810)
                         "Cannot open socache DBM file `%s' for writing "
                         "(delete)",
                         ctx->data_file);
            return rv;
        }
    #else
        if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00810)
                         "Cannot open socache DBM file `%s' for writing "
                         "(delete)",
                         ctx->data_file);
            return rv;
        }
    #endif
        apr_dbm_delete(dbm, dbmkey);
        apr_dbm_close(dbm);
    
        return APR_SUCCESS;
    }
    
    static void socache_dbm_expire(ap_socache_instance_t *ctx, server_rec *s)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *dbm;
        apr_datum_t dbmkey;
        apr_datum_t dbmval;
        apr_time_t expiry;
        int elts = 0;
        int deleted = 0;
        int expired;
        apr_datum_t *keylist;
        int keyidx;
        int i;
        apr_time_t now;
        apr_status_t rv;
    
        /*
         * make sure the expiration for still not-accessed
         * socache entries is done only from time to time
         */
        now = apr_time_now();
    
        if (now < ctx->last_expiry + ctx->expiry_interval) {
            return;
        }
    
        ctx->last_expiry = now;
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
                ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10281)
                    "Cannot load socache DBM library '%s' (expire): %s",
                         err->reason, err->msg);
            return rv;
        }
    #endif
    
        /*
         * 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
    
        for (;;) {
            /* allocate the key array in a memory sub pool */
            apr_pool_clear(ctx->pool);
    
            if ((keylist = apr_palloc(ctx->pool, sizeof(dbmkey)*KEYMAX)) == NULL) {
                break;
            }
    
            /* pass 1: scan DBM database */
            keyidx = 0;
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
            if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                                   DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00811)
                             "Cannot open socache DBM file `%s' for "
                             "scanning",
                             ctx->data_file);
                break;
            }
    #else
            if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                                   DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00811)
                             "Cannot open socache DBM file `%s' for "
                             "scanning",
                             ctx->data_file);
                break;
            }
    #endif
            apr_dbm_firstkey(dbm, &dbmkey);
            while (dbmkey.dptr != NULL) {
                elts++;
                expired = FALSE;
                apr_dbm_fetch(dbm, dbmkey, &dbmval);
                if (dbmval.dsize <= sizeof(apr_time_t) || dbmval.dptr == NULL)
                    expired = TRUE;
                else {
                    memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
                    if (expiry <= now)
                        expired = TRUE;
                }
                if (expired) {
                    if ((keylist[keyidx].dptr = apr_pmemdup(ctx->pool, dbmkey.dptr, dbmkey.dsize)) != NULL) {
                        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 APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
            if (apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                             DBM_FILE_MODE, ctx->pool) != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00812)
                             "Cannot re-open socache DBM file `%s' for "
                             "expiring",
                             ctx->data_file);
                break;
            }
    #else
            if (apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                             DBM_FILE_MODE, ctx->pool) != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00812)
                             "Cannot re-open socache DBM file `%s' for "
                             "expiring",
                             ctx->data_file);
                break;
            }
    #endif
            for (i = 0; i < keyidx; i++) {
                apr_dbm_delete(dbm, keylist[i]);
                deleted++;
            }
            apr_dbm_close(dbm);
    
            if (keyidx < KEYMAX)
                break;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00813)
                     "DBM socache expiry: "
                     "old: %d, new: %d, removed: %d",
                     elts, elts-deleted, deleted);
    }
    
    static void socache_dbm_status(ap_socache_instance_t *ctx, request_rec *r,
                                   int flags)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *dbm;
        apr_datum_t dbmkey;
        apr_datum_t dbmval;
        int elts;
        long size;
        int avg;
        apr_status_t rv;
    
        elts = 0;
        size = 0;
    
        apr_pool_clear(ctx->pool);
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
                ctx->pool) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10282)
                    "Cannot load socache DBM library '%s' (status retrieval): %s",
                         err->reason, err->msg);
            return;
        }
        if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00814)
                         "Cannot open socache DBM file `%s' for status "
                         "retrieval",
                         ctx->data_file);
            return;
        }
    #else
        if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00814)
                         "Cannot open socache DBM file `%s' for status "
                         "retrieval",
                         ctx->data_file);
            return;
        }
    #endif
        /*
         * 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;
            elts += 1;
            size += dbmval.dsize;
        }
        apr_dbm_close(dbm);
        if (size > 0 && elts > 0)
            avg = (int)(size / (long)elts);
        else
            avg = 0;
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rprintf(r, "cache type: <b>DBM</b>, maximum size: <b>unlimited</b><br>");
            ap_rprintf(r, "current entries: <b>%d</b>, current size: <b>%ld</b> bytes<br>", elts, size);
            ap_rprintf(r, "average entry size: <b>%d</b> bytes<br>", avg);
        }
        else {
            ap_rputs("CacheType: DBM\n", r);
            ap_rputs("CacheMaximumSize: unlimited\n", r);
            ap_rprintf(r, "CacheCurrentEntries: %d\n", elts);
            ap_rprintf(r, "CacheCurrentSize: %ld\n", size);
            ap_rprintf(r, "CacheAvgEntrySize: %d\n", avg);
        }
    }
    
    static apr_status_t socache_dbm_iterate(ap_socache_instance_t *ctx,
                                            server_rec *s, void *userctx,
                                            ap_socache_iterator_t *iterator,
                                            apr_pool_t *pool)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *dbm;
        apr_datum_t dbmkey;
        apr_datum_t dbmval;
        apr_time_t expiry;
        int expired;
        apr_time_t now;
        apr_status_t rv;
    
        /*
         * make sure the expired records are omitted
         */
        now = apr_time_now();
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        if ((rv = apr_dbm_get_driver(&driver, NULL, &err,
                ctx->pool) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10283)
                    "Cannot load socache DBM library '%s' (iterating): %s",
                         err->reason, err->msg);
            return rv;
        }
        if ((rv = apr_dbm_open2(&dbm, driver, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00815)
                         "Cannot open socache DBM file `%s' for "
                         "iterating", ctx->data_file);
            return rv;
        }
    #else
        if ((rv = apr_dbm_open(&dbm, ctx->data_file, APR_DBM_RWCREATE,
                               DBM_FILE_MODE, ctx->pool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00815)
                         "Cannot open socache DBM file `%s' for "
                         "iterating", ctx->data_file);
            return rv;
        }
    #endif
        rv = apr_dbm_firstkey(dbm, &dbmkey);
        while (rv == APR_SUCCESS && dbmkey.dptr != NULL) {
            expired = FALSE;
            apr_dbm_fetch(dbm, dbmkey, &dbmval);
            if (dbmval.dsize <= sizeof(apr_time_t) || dbmval.dptr == NULL)
                expired = TRUE;
            else {
                memcpy(&expiry, dbmval.dptr, sizeof(apr_time_t));
                if (expiry <= now)
                    expired = TRUE;
            }
            if (!expired) {
                rv = iterator(ctx, s, userctx,
                                 (unsigned char *)dbmkey.dptr, dbmkey.dsize,
                                 (unsigned char *)dbmval.dptr + sizeof(apr_time_t),
                                 dbmval.dsize - sizeof(apr_time_t), pool);
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00816)
                             "dbm `%s' entry iterated", ctx->data_file);
                if (rv != APR_SUCCESS)
                    return rv;
            }
            rv = apr_dbm_nextkey(dbm, &dbmkey);
        }
        apr_dbm_close(dbm);
    
        if (rv != APR_SUCCESS && rv != APR_EOF) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00817)
                         "Failure reading first/next socache DBM file `%s' record",
                         ctx->data_file);
            return rv;
        }
        return APR_SUCCESS;
    }
    
    static const ap_socache_provider_t socache_dbm = {
        "dbm",
        AP_SOCACHE_FLAG_NOTMPSAFE,
        socache_dbm_create,
        socache_dbm_init,
        socache_dbm_destroy,
        socache_dbm_store,
        socache_dbm_retrieve,
        socache_dbm_remove,
        socache_dbm_status,
        socache_dbm_iterate
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "dbm",
                             AP_SOCACHE_PROVIDER_VERSION,
                             &socache_dbm);
    }
    
    AP_DECLARE_MODULE(socache_dbm) = {
        STANDARD20_MODULE_STUFF,
        NULL, NULL, NULL, NULL, NULL,
        register_hooks
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_shmcb.c������������������������������������������������������0000664�0001751�0001751�00000126433�14557153357�021151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "http_request.h"
    #include "http_protocol.h"
    #include "http_config.h"
    #include "mod_status.h"
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_time.h"
    #include "apr_shm.h"
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    #include "apr_general.h"
    
    #if APR_HAVE_LIMITS_H
    #include <limits.h>
    #endif
    
    #include "ap_socache.h"
    
    /* XXX Unfortunately, there are still many unsigned ints in use here, so we
     * XXX cannot allow more than UINT_MAX. Since some of the ints are exposed in
     * XXX public interfaces, a simple search and replace is not enough.
     * XXX It should be possible to extend that so that the total cache size can
     * XXX be APR_SIZE_MAX and only the object size needs to be smaller than
     * XXX UINT_MAX.
     */
    #define SHMCB_MAX_SIZE (UINT_MAX<APR_SIZE_MAX ? UINT_MAX : APR_SIZE_MAX)
    
    #define DEFAULT_SHMCB_PREFIX "socache-shmcb-"
    
    #define DEFAULT_SHMCB_SUFFIX ".cache"
    
    #define ALIGNED_HEADER_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBHeader))
    #define ALIGNED_SUBCACHE_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBSubcache))
    #define ALIGNED_INDEX_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBIndex))
    
    /*
     * Header structure - the start of the shared-mem segment
     */
    typedef struct {
        /* Stats for cache operations */
        unsigned long stat_stores;
        unsigned long stat_replaced;
        unsigned long stat_expiries;
        unsigned long stat_scrolled;
        unsigned long stat_retrieves_hit;
        unsigned long stat_retrieves_miss;
        unsigned long stat_removes_hit;
        unsigned long stat_removes_miss;
        /* Number of subcaches */
        unsigned int subcache_num;
        /* How many indexes each subcache's queue has */
        unsigned int index_num;
        /* How large each subcache is, including the queue and data */
        unsigned int subcache_size;
        /* How far into each subcache the data area is (optimisation) */
        unsigned int subcache_data_offset;
        /* How large the data area in each subcache is (optimisation) */
        unsigned int subcache_data_size;
    } SHMCBHeader;
    
    /*
     * Subcache structure - the start of each subcache, followed by
     * indexes then data
     */
    typedef struct {
        /* The start position and length of the cyclic buffer of indexes */
        unsigned int idx_pos, idx_used;
        /* Same for the data area */
        unsigned int data_pos, data_used;
    } SHMCBSubcache;
    
    /*
     * Index structure - each subcache has an array of these
     */
    typedef struct {
        /* absolute time this entry expires */
        apr_time_t expires;
        /* location within the subcache's data area */
        unsigned int data_pos;
        /* size (most logic ignores this, we keep it only to minimise memcpy) */
        unsigned int data_used;
        /* length of the used data which contains the id */
        unsigned int id_len;
        /* Used to mark explicitly-removed socache entries */
        unsigned char removed;
    } SHMCBIndex;
    
    struct ap_socache_instance_t {
        apr_pool_t *pool;
        const char *data_file;
        apr_size_t shm_size;
        apr_shm_t *shm;
        SHMCBHeader *header;
    };
    
    /* The SHM data segment is of fixed size and stores data as follows.
     *
     *   [ SHMCBHeader | Subcaches ]
     *
     * The SHMCBHeader header structure stores metadata concerning the
     * cache and the contained subcaches.
     *
     * Subcaches is a hash table of header->subcache_num SHMCBSubcache
     * structures.  The hash table is indexed by SHMCB_MASK(id). Each
     * SHMCBSubcache structure has a fixed size (header->subcache_size),
     * which is determined at creation time, and looks like the following:
     *
     *   [ SHMCBSubcache | Indexes | Data ]
     *
     * Each subcache is prefixed by the SHMCBSubcache structure.
     *
     * The subcache's "Data" segment is a single cyclic data buffer, of
     * total size header->subcache_data_size; data inside is referenced
     * using byte offsets. The offset marking the beginning of the cyclic
     * buffer is subcache->data_pos; the buffer's length is
     * subcache->data_used.
     *
     * "Indexes" is an array of header->index_num SHMCBIndex structures,
     * which is used as a cyclic queue; subcache->idx_pos gives the array
     * index of the first in use, subcache->idx_used gives the number in
     * use.  Both ->idx_* values have a range of [0, header->index_num)
     *
     * Each in-use SHMCBIndex structure represents a single cached object.
     * The ID and data segment are stored consecutively in the subcache's
     * cyclic data buffer.  The "Data" segment can thus be seen to
     * look like this, for example
     *
     * offset:  [ 0     1     2     3     4     5     6    ...
     * contents:[ ID1   Data1       ID2   Data2       ID3  ...
     *
     * where the corresponding indices would look like:
     *
     * idx1 = { data_pos = 0, data_used = 3, id_len = 1, ...}
     * idx2 = { data_pos = 3, data_used = 3, id_len = 1, ...}
     * ...
     */
    
    /* This macro takes a pointer to the header and a zero-based index and returns
     * a pointer to the corresponding subcache. */
    #define SHMCB_SUBCACHE(pHeader, num) \
                    (SHMCBSubcache *)(((unsigned char *)(pHeader)) + \
                            ALIGNED_HEADER_SIZE + \
                            (num) * ((pHeader)->subcache_size))
    
    /* This macro takes a pointer to the header and an id and returns a
     * pointer to the corresponding subcache. */
    #define SHMCB_MASK(pHeader, id) \
                    SHMCB_SUBCACHE((pHeader), *(id) & ((pHeader)->subcache_num - 1))
    
    /* This macro takes the same params as the last, generating two outputs for use
     * in ap_log_error(...). */
    #define SHMCB_MASK_DBG(pHeader, id) \
                    *(id), (*(id) & ((pHeader)->subcache_num - 1))
    
    /* This macro takes a pointer to a subcache and a zero-based index and returns
     * a pointer to the corresponding SHMCBIndex. */
    #define SHMCB_INDEX(pSubcache, num) \
                    (SHMCBIndex *)(((unsigned char *)pSubcache) + \
                            ALIGNED_SUBCACHE_SIZE + \
                            (num) * ALIGNED_INDEX_SIZE)
    
    /* This macro takes a pointer to the header and a subcache and returns a
     * pointer to the corresponding data area. */
    #define SHMCB_DATA(pHeader, pSubcache) \
                    ((unsigned char *)(pSubcache) + (pHeader)->subcache_data_offset)
    
    /*
     * Cyclic functions - assists in "wrap-around"/modulo logic
     */
    
    /* Addition modulo 'mod' */
    #define SHMCB_CYCLIC_INCREMENT(val,inc,mod) \
                    (((val) + (inc)) % (mod))
    
    /* Subtraction (or "distance between") modulo 'mod' */
    #define SHMCB_CYCLIC_SPACE(val1,val2,mod) \
                    ((val2) >= (val1) ? ((val2) - (val1)) : \
                            ((val2) + (mod) - (val1)))
    
    /* A "normal-to-cyclic" memcpy. */
    static void shmcb_cyclic_ntoc_memcpy(unsigned int buf_size, unsigned char *data,
                                         unsigned int dest_offset, const unsigned char *src,
                                         unsigned int src_len)
    {
        if (dest_offset + src_len < buf_size)
            /* It be copied all in one go */
            memcpy(data + dest_offset, src, src_len);
        else {
            /* Copy the two splits */
            memcpy(data + dest_offset, src, buf_size - dest_offset);
            memcpy(data, src + buf_size - dest_offset,
                   src_len + dest_offset - buf_size);
        }
    }
    
    /* A "cyclic-to-normal" memcpy. */
    static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest,
                                         const unsigned char *data, unsigned int src_offset,
                                         unsigned int src_len)
    {
        if (src_offset + src_len < buf_size)
            /* It be copied all in one go */
            memcpy(dest, data + src_offset, src_len);
        else {
            /* Copy the two splits */
            memcpy(dest, data + src_offset, buf_size - src_offset);
            memcpy(dest + buf_size - src_offset, data,
                   src_len + src_offset - buf_size);
        }
    }
    
    /* A memcmp against a cyclic data buffer.  Compares SRC of length
     * SRC_LEN against the contents of cyclic buffer DATA (which is of
     * size BUF_SIZE), starting at offset DEST_OFFSET. Got that?  Good. */
    static int shmcb_cyclic_memcmp(unsigned int buf_size, unsigned char *data,
                                   unsigned int dest_offset,
                                   const unsigned char *src,
                                   unsigned int src_len)
    {
        if (dest_offset + src_len < buf_size)
            /* It be compared all in one go */
            return memcmp(data + dest_offset, src, src_len);
        else {
            /* Compare the two splits */
            int diff;
    
            diff = memcmp(data + dest_offset, src, buf_size - dest_offset);
            if (diff) {
                return diff;
            }
            return memcmp(data, src + buf_size - dest_offset,
                          src_len + dest_offset - buf_size);
        }
    }
    
    
    /* Prototypes for low-level subcache operations */
    static void shmcb_subcache_expire(server_rec *, SHMCBHeader *, SHMCBSubcache *,
                                      apr_time_t);
    /* Returns zero on success, non-zero on failure. */
    static int shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
                                    SHMCBSubcache *subcache,
                                    unsigned char *data, unsigned int data_len,
                                    const unsigned char *id, unsigned int id_len,
                                    apr_time_t expiry);
    /* Returns zero on success, non-zero on failure. */
    static int shmcb_subcache_retrieve(server_rec *, SHMCBHeader *, SHMCBSubcache *,
                                       const unsigned char *id, unsigned int idlen,
                                       unsigned char *data, unsigned int *datalen);
    /* Returns zero on success, non-zero on failure. */
    static int shmcb_subcache_remove(server_rec *, SHMCBHeader *, SHMCBSubcache *,
                                     const unsigned char *, unsigned int);
    
    /* Returns result of the (iterator)() call, zero is success (continue) */
    static apr_status_t shmcb_subcache_iterate(ap_socache_instance_t *instance,
                                               server_rec *s,
                                               void *userctx,
                                               SHMCBHeader *header,
                                               SHMCBSubcache *subcache,
                                               ap_socache_iterator_t *iterator,
                                               unsigned char **buf,
                                               apr_size_t *buf_len,
                                               apr_pool_t *pool,
                                               apr_time_t now);
    
    /*
     * High-Level "handlers" as per ssl_scache.c
     * subcache internals are deferred to shmcb_subcache_*** functions lower down
     */
    
    static const char *socache_shmcb_create(ap_socache_instance_t **context,
                                            const char *arg,
                                            apr_pool_t *tmp, apr_pool_t *p)
    {
        ap_socache_instance_t *ctx;
        char *path, *cp, *cp2;
    
        /* Allocate the context. */
        *context = ctx = apr_pcalloc(p, sizeof *ctx);
        ctx->pool = p;
    
        ctx->shm_size  = 1024*512; /* 512KB */
    
        if (!arg || *arg == '\0') {
            /* Use defaults. */
            return NULL;
        }
    
        ctx->data_file = path = ap_server_root_relative(p, arg);
    
        cp = strrchr(path, '(');
        cp2 = path + strlen(path) - 1;
        if (cp) {
            char *endptr;
            if (*cp2 != ')') {
                return "Invalid argument: no closing parenthesis or cache size "
                       "missing after pathname with parenthesis";
            }
            *cp++ = '\0';
            *cp2  = '\0';
    
    
            ctx->shm_size = strtol(cp, &endptr, 10);
            if (endptr != cp2) {
                return "Invalid argument: cache size not numerical";
            }
    
            if (ctx->shm_size < 8192) {
                return "Invalid argument: size has to be >= 8192 bytes";
    
            }
    
            if (ctx->shm_size >= SHMCB_MAX_SIZE) {
                return apr_psprintf(tmp, "Invalid argument: size has "
                        "to be < %" APR_SIZE_T_FMT " bytes on this platform",
                        SHMCB_MAX_SIZE);
            }
        }
        else if (cp2 >= path && *cp2 == ')') {
            return "Invalid argument: no opening parenthesis";
        }
    
        return NULL;
    }
    
    static apr_status_t socache_shmcb_cleanup(void *arg)
    {
        ap_socache_instance_t *ctx = arg;
        if (ctx->shm) {
            apr_shm_destroy(ctx->shm);
            ctx->shm = NULL;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
                                           const char *namespace,
                                           const struct ap_socache_hints *hints,
                                           server_rec *s, apr_pool_t *p)
    {
        void *shm_segment;
        apr_size_t shm_segsize;
        apr_status_t rv;
        SHMCBHeader *header;
        unsigned int num_subcache, num_idx, loop;
        apr_size_t avg_obj_size, avg_id_len;
    
        /* Create shared memory segment */
        if (ctx->data_file == NULL) {
            const char *path = apr_pstrcat(p, DEFAULT_SHMCB_PREFIX, namespace,
                                           DEFAULT_SHMCB_SUFFIX, NULL);
    
            ctx->data_file = ap_runtime_dir_relative(p, path);
        }
    
        /* Use anonymous shm by default, fall back on name-based. */
        rv = apr_shm_create(&ctx->shm, ctx->shm_size, NULL, p);
        if (APR_STATUS_IS_ENOTIMPL(rv)) {
            /* If anon shm isn't supported, fail if no named file was
             * configured successfully; the ap_server_root_relative call
             * above will return NULL for invalid paths. */
            if (ctx->data_file == NULL) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00818)
                             "Could not use anonymous shm for '%s' cache",
                             namespace);
                ctx->shm = NULL;
                return APR_EINVAL;
            }
    
            /* For a name-based segment, remove it first in case of a
             * previous unclean shutdown. */
            apr_shm_remove(ctx->data_file, p);
    
            rv = apr_shm_create(&ctx->shm, ctx->shm_size, ctx->data_file, p);
        }
    
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00819)
                         "Could not allocate shared memory segment for shmcb "
                         "socache");
            ctx->shm = NULL;
            return rv;
        }
        apr_pool_cleanup_register(ctx->pool, ctx, socache_shmcb_cleanup,
                                  apr_pool_cleanup_null); 
    
        shm_segment = apr_shm_baseaddr_get(ctx->shm);
        shm_segsize = apr_shm_size_get(ctx->shm);
        if (shm_segsize < (5 * ALIGNED_HEADER_SIZE)) {
            /* the segment is ridiculously small, bail out */
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00820)
                         "shared memory segment too small");
            return APR_ENOSPC;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00821)
                     "shmcb_init allocated %" APR_SIZE_T_FMT
                     " bytes of shared memory",
                     shm_segsize);
        /* Discount the header */
        shm_segsize -= ALIGNED_HEADER_SIZE;
        /* Select index size based on average object size hints, if given. */
        avg_obj_size = hints && hints->avg_obj_size ? hints->avg_obj_size : 150;
        avg_id_len = hints && hints->avg_id_len ? hints->avg_id_len : 30;
        num_idx = (shm_segsize) / (avg_obj_size + avg_id_len);
        num_subcache = 256;
        while ((num_idx / num_subcache) < (2 * num_subcache))
            num_subcache /= 2;
        num_idx /= num_subcache;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00822)
                     "for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT
                     " including header), recommending %u subcaches, "
                     "%u indexes each", shm_segsize,
                     shm_segsize + ALIGNED_HEADER_SIZE,
                     num_subcache, num_idx);
        if (num_idx < 5) {
            /* we're still too small, bail out */
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00823)
                         "shared memory segment too small");
            return APR_ENOSPC;
        }
        /* OK, we're sorted */
        ctx->header = header = shm_segment;
        header->stat_stores = 0;
        header->stat_replaced = 0;
        header->stat_expiries = 0;
        header->stat_scrolled = 0;
        header->stat_retrieves_hit = 0;
        header->stat_retrieves_miss = 0;
        header->stat_removes_hit = 0;
        header->stat_removes_miss = 0;
        header->subcache_num = num_subcache;
        /* Convert the subcache size (in bytes) to a value that is suitable for
         * structure alignment on the host platform, by rounding down if necessary. */
        header->subcache_size = (size_t)(shm_segsize / num_subcache);
        if (header->subcache_size != APR_ALIGN_DEFAULT(header->subcache_size)) {
            header->subcache_size = APR_ALIGN_DEFAULT(header->subcache_size) -
                                    APR_ALIGN_DEFAULT(1);
        }
        header->subcache_data_offset = ALIGNED_SUBCACHE_SIZE +
                                       num_idx * ALIGNED_INDEX_SIZE;
        header->subcache_data_size = header->subcache_size -
                                     header->subcache_data_offset;
        header->index_num = num_idx;
    
        /* Output trace info */
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00824)
                     "shmcb_init_memory choices follow");
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00825)
                     "subcache_num = %u", header->subcache_num);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00826)
                     "subcache_size = %u", header->subcache_size);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00827)
                     "subcache_data_offset = %u", header->subcache_data_offset);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00828)
                     "subcache_data_size = %u", header->subcache_data_size);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00829)
                     "index_num = %u", header->index_num);
        /* The header is done, make the caches empty */
        for (loop = 0; loop < header->subcache_num; loop++) {
            SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
            subcache->idx_pos = subcache->idx_used = 0;
            subcache->data_pos = subcache->data_used = 0;
        }
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(00830)
                     "Shared memory socache initialised");
        /* Success ... */
    
        return APR_SUCCESS;
    }
    
    static void socache_shmcb_destroy(ap_socache_instance_t *ctx, server_rec *s)
    {
        if (ctx) {
            apr_pool_cleanup_run(ctx->pool, ctx, socache_shmcb_cleanup); 
        }
    }
    
    static apr_status_t socache_shmcb_store(ap_socache_instance_t *ctx,
                                            server_rec *s, const unsigned char *id,
                                            unsigned int idlen, apr_time_t expiry,
                                            unsigned char *encoded,
                                            unsigned int len_encoded,
                                            apr_pool_t *p)
    {
        SHMCBHeader *header = ctx->header;
        SHMCBSubcache *subcache = SHMCB_MASK(header, id);
        int tryreplace;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00831)
                     "socache_shmcb_store (0x%02x -> subcache %d)",
                     SHMCB_MASK_DBG(header, id));
        /* XXX: Says who?  Why shouldn't this be acceptable, or padded if not? */
        if (idlen < 4) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00832) "unusably short id provided "
                    "(%u bytes)", idlen);
            return APR_EINVAL;
        }
        tryreplace = shmcb_subcache_remove(s, header, subcache, id, idlen);
        if (shmcb_subcache_store(s, header, subcache, encoded,
                                 len_encoded, id, idlen, expiry)) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00833)
                         "can't store an socache entry!");
            return APR_ENOSPC;
        }
        if (tryreplace == 0) {
            header->stat_replaced++;
        }
        else {
            header->stat_stores++;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00834)
                     "leaving socache_shmcb_store successfully");
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_shmcb_retrieve(ap_socache_instance_t *ctx,
                                               server_rec *s,
                                               const unsigned char *id, unsigned int idlen,
                                               unsigned char *dest, unsigned int *destlen,
                                               apr_pool_t *p)
    {
        SHMCBHeader *header = ctx->header;
        SHMCBSubcache *subcache = SHMCB_MASK(header, id);
        int rv;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00835)
                     "socache_shmcb_retrieve (0x%02x -> subcache %d)",
                     SHMCB_MASK_DBG(header, id));
    
        /* Get the entry corresponding to the id, if it exists. */
        rv = shmcb_subcache_retrieve(s, header, subcache, id, idlen,
                                     dest, destlen);
        if (rv == 0)
            header->stat_retrieves_hit++;
        else
            header->stat_retrieves_miss++;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00836)
                     "leaving socache_shmcb_retrieve successfully");
    
        return rv == 0 ? APR_SUCCESS : APR_NOTFOUND;
    }
    
    static apr_status_t socache_shmcb_remove(ap_socache_instance_t *ctx,
                                             server_rec *s, const unsigned char *id,
                                             unsigned int idlen, apr_pool_t *p)
    {
        SHMCBHeader *header = ctx->header;
        SHMCBSubcache *subcache = SHMCB_MASK(header, id);
        apr_status_t rv;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00837)
                     "socache_shmcb_remove (0x%02x -> subcache %d)",
                     SHMCB_MASK_DBG(header, id));
        if (idlen < 4) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00838) "unusably short id provided "
                    "(%u bytes)", idlen);
            return APR_EINVAL;
        }
        if (shmcb_subcache_remove(s, header, subcache, id, idlen) == 0) {
            header->stat_removes_hit++;
            rv = APR_SUCCESS;
        } else {
            header->stat_removes_miss++;
            rv = APR_NOTFOUND;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00839)
                     "leaving socache_shmcb_remove successfully");
    
        return rv;
    }
    
    static void socache_shmcb_status(ap_socache_instance_t *ctx,
                                     request_rec *r, int flags)
    {
        server_rec *s = r->server;
        SHMCBHeader *header = ctx->header;
        unsigned int loop, total = 0, cache_total = 0, non_empty_subcaches = 0;
        apr_time_t idx_expiry, min_expiry = 0, max_expiry = 0;
        apr_time_t now = apr_time_now();
        double expiry_total = 0;
        int index_pct, cache_pct;
    
        AP_DEBUG_ASSERT(header->subcache_num > 0);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00840) "inside shmcb_status");
        /* Perform the iteration inside the mutex to avoid corruption or invalid
         * pointer arithmetic. The rest of our logic uses read-only header data so
         * doesn't need the lock. */
        /* Iterate over the subcaches */
        for (loop = 0; loop < header->subcache_num; loop++) {
            SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
            shmcb_subcache_expire(s, header, subcache, now);
            total += subcache->idx_used;
            cache_total += subcache->data_used;
            if (subcache->idx_used) {
                SHMCBIndex *idx = SHMCB_INDEX(subcache, subcache->idx_pos);
                non_empty_subcaches++;
                idx_expiry = idx->expires;
                expiry_total += (double)idx_expiry;
                max_expiry = ((idx_expiry > max_expiry) ? idx_expiry : max_expiry);
                if (!min_expiry)
                    min_expiry = idx_expiry;
                else
                    min_expiry = ((idx_expiry < min_expiry) ? idx_expiry : min_expiry);
            }
        }
        index_pct = (100 * total) / (header->index_num *
                                     header->subcache_num);
        cache_pct = (100 * cache_total) / (header->subcache_data_size *
                                           header->subcache_num);
        /* Generate Output */
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rprintf(r, "cache type: <b>SHMCB</b>, shared memory: <b>%" APR_SIZE_T_FMT "</b> "
                       "bytes, current entries: <b>%d</b><br>",
                       ctx->shm_size, total);
            ap_rprintf(r, "subcaches: <b>%d</b>, indexes per subcache: <b>%d</b><br>",
                       header->subcache_num, header->index_num);
            if (non_empty_subcaches) {
                apr_time_t average_expiry = (apr_time_t)(expiry_total / (double)non_empty_subcaches);
                ap_rprintf(r, "time left on oldest entries' objects: ");
                if (now < average_expiry)
                    ap_rprintf(r, "avg: <b>%d</b> seconds, (range: %d...%d)<br>",
                               (int)apr_time_sec(average_expiry - now),
                               (int)apr_time_sec(min_expiry - now),
                               (int)apr_time_sec(max_expiry - now));
                else
                    ap_rprintf(r, "expiry_threshold: <b>Calculation error!</b><br>");
            }
    
            ap_rprintf(r, "index usage: <b>%d%%</b>, cache usage: <b>%d%%</b><br>",
                       index_pct, cache_pct);
            ap_rprintf(r, "total entries stored since starting: <b>%lu</b><br>",
                       header->stat_stores);
            ap_rprintf(r, "total entries replaced since starting: <b>%lu</b><br>",
                       header->stat_replaced);
            ap_rprintf(r, "total entries expired since starting: <b>%lu</b><br>",
                       header->stat_expiries);
            ap_rprintf(r, "total (pre-expiry) entries scrolled out of the cache: "
                       "<b>%lu</b><br>", header->stat_scrolled);
            ap_rprintf(r, "total retrieves since starting: <b>%lu</b> hit, "
                       "<b>%lu</b> miss<br>", header->stat_retrieves_hit,
                       header->stat_retrieves_miss);
            ap_rprintf(r, "total removes since starting: <b>%lu</b> hit, "
                       "<b>%lu</b> miss<br>", header->stat_removes_hit,
                       header->stat_removes_miss);
        }
        else {
            ap_rputs("CacheType: SHMCB\n", r);
            ap_rprintf(r, "CacheSharedMemory: %" APR_SIZE_T_FMT "\n",
                       ctx->shm_size);
            ap_rprintf(r, "CacheCurrentEntries: %d\n", total);
            ap_rprintf(r, "CacheSubcaches: %d\n", header->subcache_num);
            ap_rprintf(r, "CacheIndexesPerSubcaches: %d\n", header->index_num);
            if (non_empty_subcaches) {
                apr_time_t average_expiry = (apr_time_t)(expiry_total / (double)non_empty_subcaches);
                if (now < average_expiry) {
                    ap_rprintf(r, "CacheTimeLeftOldestAvg: %d\n", (int)apr_time_sec(average_expiry - now));
                    ap_rprintf(r, "CacheTimeLeftOldestMin: %d\n", (int)apr_time_sec(min_expiry - now));
                    ap_rprintf(r, "CacheTimeLeftOldestMax: %d\n", (int)apr_time_sec(max_expiry - now));
                }
            }
    
            ap_rprintf(r, "CacheIndexUsage: %d%%\n", index_pct);
            ap_rprintf(r, "CacheUsage: %d%%\n", cache_pct);
            ap_rprintf(r, "CacheStoreCount: %lu\n", header->stat_stores);
            ap_rprintf(r, "CacheReplaceCount: %lu\n", header->stat_replaced);
            ap_rprintf(r, "CacheExpireCount: %lu\n", header->stat_expiries);
            ap_rprintf(r, "CacheDiscardCount: %lu\n", header->stat_scrolled);
            ap_rprintf(r, "CacheRetrieveHitCount: %lu\n", header->stat_retrieves_hit);
            ap_rprintf(r, "CacheRetrieveMissCount: %lu\n", header->stat_retrieves_miss);
            ap_rprintf(r, "CacheRemoveHitCount: %lu\n", header->stat_removes_hit);
            ap_rprintf(r, "CacheRemoveMissCount: %lu\n", header->stat_removes_miss);
        }
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00841) "leaving shmcb_status");
    }
    
    static apr_status_t socache_shmcb_iterate(ap_socache_instance_t *instance,
                                              server_rec *s, void *userctx,
                                              ap_socache_iterator_t *iterator,
                                              apr_pool_t *pool)
    {
        SHMCBHeader *header = instance->header;
        unsigned int loop;
        apr_time_t now = apr_time_now();
        apr_status_t rv = APR_SUCCESS;
        apr_size_t buflen = 0;
        unsigned char *buf = NULL;
    
        /* Perform the iteration inside the mutex to avoid corruption or invalid
         * pointer arithmetic. The rest of our logic uses read-only header data so
         * doesn't need the lock. */
        /* Iterate over the subcaches */
        for (loop = 0; loop < header->subcache_num && rv == APR_SUCCESS; loop++) {
            SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
            rv = shmcb_subcache_iterate(instance, s, userctx, header, subcache,
                                        iterator, &buf, &buflen, pool, now);
        }
        return rv;
    }
    
    /*
     * Subcache-level cache operations
     */
    
    static void shmcb_subcache_expire(server_rec *s, SHMCBHeader *header,
                                      SHMCBSubcache *subcache, apr_time_t now)
    {
        unsigned int loop = 0, freed = 0, expired = 0;
        unsigned int new_idx_pos = subcache->idx_pos;
        SHMCBIndex *idx = NULL;
    
        while (loop < subcache->idx_used) {
            idx = SHMCB_INDEX(subcache, new_idx_pos);
            if (idx->removed)
                freed++;
            else if (idx->expires <= now)
                expired++;
            else
                /* not removed and not expired yet, we're done iterating */
                break;
            loop++;
            new_idx_pos = SHMCB_CYCLIC_INCREMENT(new_idx_pos, 1, header->index_num);
        }
        if (!loop)
            /* Nothing to do */
            return;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00842)
                     "expiring %u and reclaiming %u removed socache entries",
                     expired, freed);
        if (loop == subcache->idx_used) {
            /* We're expiring everything, piece of cake */
            subcache->idx_used = 0;
            subcache->data_used = 0;
        } else {
            /* There remain other indexes, so we can use idx to adjust 'data' */
            unsigned int diff = SHMCB_CYCLIC_SPACE(subcache->data_pos,
                                                   idx->data_pos,
                                                   header->subcache_data_size);
            /* Adjust the indexes */
            subcache->idx_used -= loop;
            subcache->idx_pos = new_idx_pos;
            /* Adjust the data area */
            subcache->data_used -= diff;
            subcache->data_pos = idx->data_pos;
        }
        header->stat_expiries += expired;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00843)
                     "we now have %u socache entries", subcache->idx_used);
    }
    
    static int shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
                                    SHMCBSubcache *subcache,
                                    unsigned char *data, unsigned int data_len,
                                    const unsigned char *id, unsigned int id_len,
                                    apr_time_t expiry)
    {
        unsigned int data_offset, new_idx, id_offset;
        SHMCBIndex *idx;
        unsigned int total_len = id_len + data_len;
    
        /* Sanity check the input */
        if (total_len > header->subcache_data_size) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00844)
                         "inserting socache entry larger (%d) than subcache data area (%d)",
                         total_len, header->subcache_data_size);
            return -1;
        }
    
        /* First reclaim space from removed and expired records. */
        shmcb_subcache_expire(s, header, subcache, apr_time_now());
    
        /* Loop until there is enough space to insert
         * XXX: This should first compress out-of-order expiries and
         * removed records, and then force-remove oldest-first
         */
        if (header->subcache_data_size - subcache->data_used < total_len
            || subcache->idx_used == header->index_num) {
    
            idx = SHMCB_INDEX(subcache, subcache->idx_pos);
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00845)
                         "about to force-expire, subcache: idx_used=%d, "
                         "data_used=%d", subcache->idx_used, subcache->data_used);
            do {
                SHMCBIndex *idx2;
    
                /* Adjust the indexes by one */
                subcache->idx_pos = SHMCB_CYCLIC_INCREMENT(subcache->idx_pos, 1,
                                                           header->index_num);
                subcache->idx_used--;
                if (!subcache->idx_used) {
                    /* There's nothing left */
                    subcache->data_used = 0;
                    break;
                }
                /* Adjust the data */
                idx2 = SHMCB_INDEX(subcache, subcache->idx_pos);
                subcache->data_used -= SHMCB_CYCLIC_SPACE(idx->data_pos, idx2->data_pos,
                                                          header->subcache_data_size);
                subcache->data_pos = idx2->data_pos;
                /* Stats */
                header->stat_scrolled++;
                /* Loop admin */
                idx = idx2;
            } while (header->subcache_data_size - subcache->data_used < total_len);
    
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00846)
                         "finished force-expire, subcache: idx_used=%d, "
                         "data_used=%d", subcache->idx_used, subcache->data_used);
        }
    
        /* HERE WE ASSUME THAT THE NEW ENTRY SHOULD GO ON THE END! I'M NOT
         * CHECKING WHETHER IT SHOULD BE GENUINELY "INSERTED" SOMEWHERE.
         *
         * We aught to fix that.  httpd (never mind third party modules)
         * does not promise to perform any processing in date order
         * (c.f. FAQ "My log entries are not in date order!")
         */
        /* Insert the id */
        id_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
                                           header->subcache_data_size);
        shmcb_cyclic_ntoc_memcpy(header->subcache_data_size,
                                 SHMCB_DATA(header, subcache), id_offset,
                                 id, id_len);
        subcache->data_used += id_len;
        /* Insert the data */
        data_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
                                             header->subcache_data_size);
        shmcb_cyclic_ntoc_memcpy(header->subcache_data_size,
                                 SHMCB_DATA(header, subcache), data_offset,
                                 data, data_len);
        subcache->data_used += data_len;
        /* Insert the index */
        new_idx = SHMCB_CYCLIC_INCREMENT(subcache->idx_pos, subcache->idx_used,
                                         header->index_num);
        idx = SHMCB_INDEX(subcache, new_idx);
        idx->expires = expiry;
        idx->data_pos = id_offset;
        idx->data_used = total_len;
        idx->id_len = id_len;
        idx->removed = 0;
        subcache->idx_used++;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00847)
                     "insert happened at idx=%d, data=(%u:%u)", new_idx,
                     id_offset, data_offset);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00848)
                     "finished insert, subcache: idx_pos/idx_used=%d/%d, "
                     "data_pos/data_used=%d/%d",
                     subcache->idx_pos, subcache->idx_used,
                     subcache->data_pos, subcache->data_used);
        return 0;
    }
    
    static int shmcb_subcache_retrieve(server_rec *s, SHMCBHeader *header,
                                       SHMCBSubcache *subcache,
                                       const unsigned char *id, unsigned int idlen,
                                       unsigned char *dest, unsigned int *destlen)
    {
        unsigned int pos;
        unsigned int loop = 0;
        apr_time_t now = apr_time_now();
    
        pos = subcache->idx_pos;
    
        while (loop < subcache->idx_used) {
            SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
    
            /* Only consider 'idx' if the id matches, and the "removed"
             * flag isn't set, and the record is not expired.
             * Check the data length too to avoid a buffer overflow
             * in case of corruption, which should be impossible,
             * but it's cheap to be safe. */
            if (!idx->removed
                && idx->id_len == idlen
                && (idx->data_used - idx->id_len) <= *destlen
                && shmcb_cyclic_memcmp(header->subcache_data_size,
                                       SHMCB_DATA(header, subcache),
                                       idx->data_pos, id, idx->id_len) == 0) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00849)
                             "match at idx=%d, data=%d", pos, idx->data_pos);
                if (idx->expires > now) {
                    unsigned int data_offset;
    
                    /* Find the offset of the data segment, after the id */
                    data_offset = SHMCB_CYCLIC_INCREMENT(idx->data_pos,
                                                         idx->id_len,
                                                         header->subcache_data_size);
    
                    *destlen = idx->data_used - idx->id_len;
    
                    /* Copy out the data */
                    shmcb_cyclic_cton_memcpy(header->subcache_data_size,
                                             dest, SHMCB_DATA(header, subcache),
                                             data_offset, *destlen);
    
                    return 0;
                }
                else {
                    /* Already stale, quietly remove and treat as not-found */
                    idx->removed = 1;
                    header->stat_expiries++;
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00850)
                                 "shmcb_subcache_retrieve discarding expired entry");
                    return -1;
                }
            }
            /* Increment */
            loop++;
            pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00851)
                     "shmcb_subcache_retrieve found no match");
        return -1;
    }
    
    static int shmcb_subcache_remove(server_rec *s, SHMCBHeader *header,
                                     SHMCBSubcache *subcache,
                                     const unsigned char *id,
                                     unsigned int idlen)
    {
        unsigned int pos;
        unsigned int loop = 0;
    
        pos = subcache->idx_pos;
        while (loop < subcache->idx_used) {
            SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
    
            /* Only consider 'idx' if the id matches, and the "removed"
             * flag isn't set. */
            if (!idx->removed && idx->id_len == idlen
                && shmcb_cyclic_memcmp(header->subcache_data_size,
                                       SHMCB_DATA(header, subcache),
                                       idx->data_pos, id, idx->id_len) == 0) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00852)
                             "possible match at idx=%d, data=%d", pos, idx->data_pos);
    
                /* Found the matching entry, remove it quietly. */
                idx->removed = 1;
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00853)
                             "shmcb_subcache_remove removing matching entry");
                return 0;
            }
            /* Increment */
            loop++;
            pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
        }
    
        return -1; /* failure */
    }
    
    
    static apr_status_t shmcb_subcache_iterate(ap_socache_instance_t *instance,
                                               server_rec *s,
                                               void *userctx,
                                               SHMCBHeader *header,
                                               SHMCBSubcache *subcache,
                                               ap_socache_iterator_t *iterator,
                                               unsigned char **buf,
                                               apr_size_t *buf_len,
                                               apr_pool_t *pool,
                                               apr_time_t now)
    {
        unsigned int pos;
        unsigned int loop = 0;
        apr_status_t rv;
    
        pos = subcache->idx_pos;
        while (loop < subcache->idx_used) {
            SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
    
            /* Only consider 'idx' if the "removed" flag isn't set. */
            if (!idx->removed) {
    
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00854)
                             "iterating idx=%d, data=%d", pos, idx->data_pos);
                if (idx->expires > now) {
                    unsigned char *id = *buf;
                    unsigned char *dest;
                    unsigned int data_offset, dest_len;
                    apr_size_t buf_req;
    
                    /* Find the offset of the data segment, after the id */
                    data_offset = SHMCB_CYCLIC_INCREMENT(idx->data_pos,
                                                         idx->id_len,
                                                         header->subcache_data_size);
    
                    dest_len = idx->data_used - idx->id_len;
    
                    buf_req = APR_ALIGN_DEFAULT(idx->id_len + 1)
                            + APR_ALIGN_DEFAULT(dest_len + 1);
    
                    if (buf_req > *buf_len) {
                         /* Grow to ~150% of this buffer requirement on resize
                          * always using APR_ALIGN_DEFAULT sized pages
                          */
                         *buf_len = buf_req + APR_ALIGN_DEFAULT(buf_req / 2);
                         *buf = apr_palloc(pool, *buf_len);
                         id = *buf;
                    }
    
                    dest = *buf + APR_ALIGN_DEFAULT(idx->id_len + 1);
    
                    /* Copy out the data, because it's potentially cyclic */
                    shmcb_cyclic_cton_memcpy(header->subcache_data_size, id,
                                             SHMCB_DATA(header, subcache),
                                             idx->data_pos, idx->id_len);
                    id[idx->id_len] = '\0';
    
                    shmcb_cyclic_cton_memcpy(header->subcache_data_size, dest,
                                             SHMCB_DATA(header, subcache),
                                             data_offset, dest_len);
                    dest[dest_len] = '\0';
    
                    rv = iterator(instance, s, userctx, id, idx->id_len,
                                  dest, dest_len, pool);
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00855)
                                 "shmcb entry iterated");
                    if (rv != APR_SUCCESS)
                        return rv;
                }
                else {
                    /* Already stale, quietly remove and treat as not-found */
                    idx->removed = 1;
                    header->stat_expiries++;
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00856)
                                 "shmcb_subcache_iterate discarding expired entry");
                }
            }
            /* Increment */
            loop++;
            pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
        }
    
        return APR_SUCCESS;
    }
    
    static const ap_socache_provider_t socache_shmcb = {
        "shmcb",
        AP_SOCACHE_FLAG_NOTMPSAFE,
        socache_shmcb_create,
        socache_shmcb_init,
        socache_shmcb_destroy,
        socache_shmcb_store,
        socache_shmcb_retrieve,
        socache_shmcb_remove,
        socache_shmcb_status,
        socache_shmcb_iterate
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "shmcb",
                             AP_SOCACHE_PROVIDER_VERSION,
                             &socache_shmcb);
    
        /* Also register shmcb under the default provider name. */
        ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP,
                             AP_SOCACHE_DEFAULT_PROVIDER,
                             AP_SOCACHE_PROVIDER_VERSION,
                             &socache_shmcb);
    }
    
    AP_DECLARE_MODULE(socache_shmcb) = {
        STANDARD20_MODULE_STUFF,
        NULL, NULL, NULL, NULL, NULL,
        register_hooks
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_file_cache.c���������������������������������������������������������0000664�0001751�0001751�00000032601�14001071231�020371� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stoddard apache.org>
     *         Based on mod_mmap_static by Dean Gaudet <dgaudet arctic.org>
     *
     * 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 <sys/types.h>
    #endif
    
    #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, APLOGNO(00794)
                         "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, APLOGNO(00795)
                         "unable to stat(%s), skipping", fspec);
            return;
        }
        if (tmp.finfo.filetype != APR_REG) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00796)
                         "%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, APLOGNO(00797)
                         "%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, APLOGNO(00798)
                         "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, APLOGNO(00799)
                             "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, APLOGNO(00800)
                     "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, APLOGNO(00801)
                     "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 AP_FILTER_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);
    
        apr_brigade_insert_file(bb, file->file, 0, file->finfo.size, r->pool);
    
        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 AP_FILTER_ERROR;
    #endif
        return OK;
    }
    
    static int file_cache_handler(request_rec *r)
    {
        a_file *match;
        int errstatus;
        int rc = OK;
    
        /* Bail out if r->handler isn't the default value, and doesn't look like a Content-Type
         * XXX: Even though we made the user explicitly list each path to cache?
         */
        if (ap_strcmp_match(r->handler, "*/*") && !AP_IS_DEFAULT_HANDLER_NAME(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_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);
    
        ap_set_etag(r);
        if ((errstatus = ap_meets_conditions(r)) != OK) {
           return errstatus;
        }
    
        /* 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 const 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);
        */
    
    }
    
    AP_DECLARE_MODULE(file_cache) =
    {
        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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_redis.dep����������������������������������������������������0000664�0001751�0001751�00000000233�13446306656�021474� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_socache_shmcb.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/cache_util.c�������������������������������������������������������������0000664�0001751�0001751�00000130012�14002600524�017567� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_cache.h"
    
    #include "cache_util.h"
    #include <ap_provider.h>
    
    APLOG_USE_MODULE(cache);
    
    /* -------------------------------------------------------------- */
    
    extern APR_OPTIONAL_FN_TYPE(ap_cache_generate_key) *cache_generate_key;
    
    extern module AP_MODULE_DECLARE_DATA cache_module;
    
    /* Determine if "url" matches the hostname, scheme and port and path
     * in "filter". All but the path comparisons are case-insensitive.
     */
    static int uri_meets_conditions(const apr_uri_t *filter, const apr_size_t pathlen,
                                    const apr_uri_t *url, const char *path)
    {
        /* Scheme, hostname port and local part. The filter URI and the
         * URI we test may have the following shapes:
         *   /<path>
         *   <scheme>[:://<hostname>[:<port>][/<path>]]
         * That is, if there is no scheme then there must be only the path,
         * and we check only the path; if there is a scheme, we check the
         * scheme for equality, and then if present we match the hostname,
         * and then if present match the port, and finally the path if any.
         *
         * Note that this means that "/<path>" only matches local paths,
         * and to match proxied paths one *must* specify the scheme.
         */
    
        /* Is the filter is just for a local path or a proxy URI? */
        if (!filter->scheme) {
            if (url->scheme || url->hostname) {
                return 0;
            }
        }
        else {
            /* The URI scheme must be present and identical except for case. */
            if (!url->scheme || ap_cstr_casecmp(filter->scheme, url->scheme)) {
                return 0;
            }
    
            /* If the filter hostname is null or empty it matches any hostname,
             * if it begins with a "*" it matches the _end_ of the URI hostname
             * excluding the "*", if it begins with a "." it matches the _end_
             * of the URI * hostname including the ".", otherwise it must match
             * the URI hostname exactly. */
    
            if (filter->hostname && filter->hostname[0]) {
                if (filter->hostname[0] == '.') {
                    const size_t fhostlen = strlen(filter->hostname);
                    const size_t uhostlen = url->hostname ? strlen(url->hostname) : 0;
    
                    if (fhostlen > uhostlen
                        || (url->hostname
                            && strcasecmp(filter->hostname,
                                          url->hostname + uhostlen - fhostlen))) {
                        return 0;
                    }
                }
                else if (filter->hostname[0] == '*') {
                    const size_t fhostlen = strlen(filter->hostname + 1);
                    const size_t uhostlen = url->hostname ? strlen(url->hostname) : 0;
    
                    if (fhostlen > uhostlen
                        || (url->hostname
                            && strcasecmp(filter->hostname + 1,
                                          url->hostname + uhostlen - fhostlen))) {
                        return 0;
                    }
                }
                else if (!url->hostname || strcasecmp(filter->hostname, url->hostname)) {
                    return 0;
                }
            }
    
            /* If the filter port is empty it matches any URL port.
             * If the filter or URL port are missing, or the URL port is
             * empty, they default to the port for their scheme. */
    
            if (!(filter->port_str && !filter->port_str[0])) {
                /* NOTE:  ap_port_of_scheme will return 0 if given NULL input */
                const unsigned fport = filter->port_str ? filter->port
                        : apr_uri_port_of_scheme(filter->scheme);
                const unsigned uport = (url->port_str && url->port_str[0])
                        ? url->port : apr_uri_port_of_scheme(url->scheme);
    
                if (fport != uport) {
                    return 0;
                }
            }
        }
    
        /* For HTTP caching purposes, an empty (NULL) path is equivalent to
         * a single "/" path. RFCs 3986/2396
         */
        if (!path) {
            if (*filter->path == '/' && pathlen == 1) {
                return 1;
            }
            else {
                return 0;
            }
        }
    
        /* Url has met all of the filter conditions so far, determine
         * if the paths match.
         */
        return !strncmp(filter->path, path, pathlen);
    }
    
    int cache_use_early_url(request_rec *r)
    {
        cache_server_conf *conf;
    
        if (r->proxyreq == PROXYREQ_PROXY) {
            return 1;
        }
    
        conf = ap_get_module_config(r->server->module_config, &cache_module);
        if (conf->quick) {
            return 1;
        }
    
        return 0;
    }
    
    static cache_provider_list *get_provider(request_rec *r, struct cache_enable *ent,
            cache_provider_list *providers)
    {
        /* Fetch from global config and add to the list. */
        cache_provider *provider;
        provider = ap_lookup_provider(CACHE_PROVIDER_GROUP, ent->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->type;
            newp->provider = provider;
    
            if (!providers) {
                providers = newp;
            }
            else {
                cache_provider_list *last = providers;
    
                while (last->next) {
                    if (last->provider == provider) {
                        return providers;
                    }
                    last = last->next;
                }
                if (last->provider == provider) {
                    return providers;
                }
                last->next = newp;
            }
        }
    
        return providers;
    }
    
    cache_provider_list *cache_get_providers(request_rec *r,
                                             cache_server_conf *conf)
    {
        cache_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &cache_module);
        cache_provider_list *providers = NULL;
        const char *path;
        int i;
    
        /* per directory cache disable */
        if (dconf->disable) {
            return NULL;
        }
    
        path = cache_use_early_url(r) ? r->parsed_uri.path : r->uri;
    
        /* global cache disable */
        for (i = 0; i < conf->cachedisable->nelts; i++) {
            struct cache_disable *ent =
                                   (struct cache_disable *)conf->cachedisable->elts;
            if (uri_meets_conditions(&ent[i].url, ent[i].pathlen,
                                     &r->parsed_uri, path)) {
                /* Stop searching now. */
                return NULL;
            }
        }
    
        /* loop through all the per directory cacheenable entries */
        for (i = 0; i < dconf->cacheenable->nelts; i++) {
            struct cache_enable *ent =
                                    (struct cache_enable *)dconf->cacheenable->elts;
            providers = get_provider(r, &ent[i], providers);
        }
    
        /* loop through all the global cacheenable entries */
        for (i = 0; i < conf->cacheenable->nelts; i++) {
            struct cache_enable *ent =
                                    (struct cache_enable *)conf->cacheenable->elts;
            if (uri_meets_conditions(&ent[i].url, ent[i].pathlen,
                                     &r->parsed_uri, path)) {
                providers = get_provider(r, &ent[i], providers);
            }
        }
    
        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;
    
        if (current_age < 0) {
            current_age = 0;
        }
    
        return apr_time_sec(current_age);
    }
    
    /**
     * Try obtain a cache wide lock on the given cache key.
     *
     * If we return APR_SUCCESS, we obtained the lock, and we are clear to
     * proceed to the backend. If we return APR_EEXIST, then the lock is
     * already locked, someone else has gone to refresh the backend data
     * already, so we must return stale data with a warning in the mean
     * time. If we return anything else, then something has gone pear
     * shaped, and we allow the request through to the backend regardless.
     *
     * This lock is created from the request pool, meaning that should
     * something go wrong and the lock isn't deleted on return of the
     * request headers from the backend for whatever reason, at worst the
     * lock will be cleaned up when the request dies or finishes.
     *
     * If something goes truly bananas and the lock isn't deleted when the
     * request dies, the lock will be trashed when its max-age is reached,
     * or when a request arrives containing a Cache-Control: no-cache. At
     * no point is it possible for this lock to permanently deny access to
     * the backend.
     */
    apr_status_t cache_try_lock(cache_server_conf *conf, cache_request_rec *cache,
            request_rec *r)
    {
        apr_status_t status;
        const char *lockname;
        const char *path;
        char dir[5];
        apr_time_t now = apr_time_now();
        apr_finfo_t finfo;
        apr_file_t *lockfile;
        void *dummy;
    
        finfo.mtime = 0;
    
        if (!conf || !conf->lock || !conf->lockpath) {
            /* no locks configured, leave */
            return APR_SUCCESS;
        }
    
        /* lock already obtained earlier? if so, success */
        apr_pool_userdata_get(&dummy, CACHE_LOCKFILE_KEY, r->pool);
        if (dummy) {
            return APR_SUCCESS;
        }
    
        /* create the key if it doesn't exist */
        if (!cache->key) {
            cache_handle_t *h;
            /*
             * Try to use the key of a possible open but stale cache
             * entry if we have one.
             */
            if (cache->handle != NULL) {
                h = cache->handle;
            }
            else {
                h = cache->stale_handle;
            }
            if ((h != NULL) &&
                (h->cache_obj != NULL) &&
                (h->cache_obj->key != NULL)) {
                cache->key = apr_pstrdup(r->pool, h->cache_obj->key);
            }
            else {
                cache_generate_key(r, r->pool, &cache->key);
            }
        }
    
        /* create a hashed filename from the key, and save it for later */
        lockname = ap_cache_generate_name(r->pool, 0, 0, cache->key);
    
        /* lock files represent discrete just-went-stale URLs "in flight", so
         * we support a simple two level directory structure, more is overkill.
         */
        dir[0] = '/';
        dir[1] = lockname[0];
        dir[2] = '/';
        dir[3] = lockname[1];
        dir[4] = 0;
    
        /* make the directories */
        path = apr_pstrcat(r->pool, conf->lockpath, dir, NULL);
        if (APR_SUCCESS != (status = apr_dir_make_recursive(path,
                APR_UREAD|APR_UWRITE|APR_UEXECUTE, r->pool))) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00778)
                    "Could not create a cache lock directory: %s",
                    path);
            return status;
        }
        lockname = apr_pstrcat(r->pool, path, "/", lockname, NULL);
        apr_pool_userdata_set(lockname, CACHE_LOCKNAME_KEY, NULL, r->pool);
    
        /* is an existing lock file too old? */
        status = apr_stat(&finfo, lockname,
                    APR_FINFO_MTIME | APR_FINFO_NLINK, r->pool);
        if (!(APR_STATUS_IS_ENOENT(status)) && APR_SUCCESS != status) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00779)
                    "Could not stat a cache lock file: %s",
                    lockname);
            return status;
        }
        if ((status == APR_SUCCESS) && (((now - finfo.mtime) > conf->lockmaxage)
                                      || (now < finfo.mtime))) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO(00780)
                    "Cache lock file for '%s' too old, removing: %s",
                    r->uri, lockname);
            apr_file_remove(lockname, r->pool);
        }
    
        /* try obtain a lock on the file */
        if (APR_SUCCESS == (status = apr_file_open(&lockfile, lockname,
                APR_WRITE | APR_CREATE | APR_EXCL | APR_DELONCLOSE,
                APR_UREAD | APR_UWRITE, r->pool))) {
            apr_pool_userdata_set(lockfile, CACHE_LOCKFILE_KEY, NULL, r->pool);
        }
        return status;
    
    }
    
    /**
     * Remove the cache lock, if present.
     *
     * First, try to close the file handle, whose delete-on-close should
     * kill the file. Otherwise, just delete the file by name.
     *
     * If no lock name has yet been calculated, do the calculation of the
     * lock name first before trying to delete the file.
     *
     * If an optional bucket brigade is passed, the lock will only be
     * removed if the bucket brigade contains an EOS bucket.
     */
    apr_status_t cache_remove_lock(cache_server_conf *conf,
            cache_request_rec *cache, request_rec *r, apr_bucket_brigade *bb)
    {
        void *dummy;
        const char *lockname;
    
        if (!conf || !conf->lock || !conf->lockpath) {
            /* no locks configured, leave */
            return APR_SUCCESS;
        }
        if (bb) {
            apr_bucket *e;
            int eos_found = 0;
            for (e = APR_BRIGADE_FIRST(bb);
                 e != APR_BRIGADE_SENTINEL(bb);
                 e = APR_BUCKET_NEXT(e))
            {
                if (APR_BUCKET_IS_EOS(e)) {
                    eos_found = 1;
                    break;
                }
            }
            if (!eos_found) {
                /* no eos found in brigade, don't delete anything just yet,
                 * we are not done.
                 */
                return APR_SUCCESS;
            }
        }
        apr_pool_userdata_get(&dummy, CACHE_LOCKFILE_KEY, r->pool);
        if (dummy) {
            return apr_file_close((apr_file_t *)dummy);
        }
        apr_pool_userdata_get(&dummy, CACHE_LOCKNAME_KEY, r->pool);
        lockname = (const char *)dummy;
        if (!lockname) {
            char dir[5];
    
            /* create the key if it doesn't exist */
            if (!cache->key) {
                cache_generate_key(r, r->pool, &cache->key);
            }
    
            /* create a hashed filename from the key, and save it for later */
            lockname = ap_cache_generate_name(r->pool, 0, 0, cache->key);
    
            /* lock files represent discrete just-went-stale URLs "in flight", so
             * we support a simple two level directory structure, more is overkill.
             */
            dir[0] = '/';
            dir[1] = lockname[0];
            dir[2] = '/';
            dir[3] = lockname[1];
            dir[4] = 0;
    
            lockname = apr_pstrcat(r->pool, conf->lockpath, dir, "/", lockname, NULL);
        }
        return apr_file_remove(lockname, r->pool);
    }
    
    int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r)
    {
    
        cache_server_conf *conf =
          (cache_server_conf *)ap_get_module_config(r->server->module_config,
                                                    &cache_module);
    
        /*
         * At this point, we may have data cached, but the request may have
         * specified that cached data may not be used in a response.
         *
         * This is covered under RFC2616 section 14.9.4 (Cache Revalidation and
         * Reload Controls).
         *
         * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache, or Pragma:
         * no-cache. The server MUST NOT use a cached copy when responding to such
         * a request.
         */
    
        /* This value comes from the client's initial request. */
        if (!cache->control_in.parsed) {
            const char *cc_req = cache_table_getm(r->pool, r->headers_in,
                    "Cache-Control");
            const char *pragma = cache_table_getm(r->pool, r->headers_in, "Pragma");
            ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
        }
    
        if (cache->control_in.no_cache) {
    
            if (!conf->ignorecachecontrol) {
                return 0;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02657)
                        "Incoming request is asking for an uncached version of "
                        "%s, but we have been configured to ignore it and serve "
                        "cached content anyway", r->unparsed_uri);
            }
        }
    
        return 1;
    }
    
    int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r)
    {
    
        cache_server_conf *conf =
          (cache_server_conf *)ap_get_module_config(r->server->module_config,
                                                    &cache_module);
    
        /*
         * At this point, we may have data cached, but the request may have
         * specified that cached data may not be used in a response.
         *
         * - RFC2616 14.9.2 What May be Stored by Caches. If Cache-Control:
         * no-store arrives, do not serve from or store to the cache.
         */
    
        /* This value comes from the client's initial request. */
        if (!cache->control_in.parsed) {
            const char *cc_req = cache_table_getm(r->pool, r->headers_in,
                    "Cache-Control");
            const char *pragma = cache_table_getm(r->pool, r->headers_in, "Pragma");
            ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
        }
    
        if (cache->control_in.no_store) {
    
            if (!conf->ignorecachecontrol) {
                /* We're not allowed to serve a cached copy */
                return 0;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02658)
                        "Incoming request is asking for a no-store version of "
                        "%s, but we have been configured to ignore it and serve "
                        "cached content anyway", r->unparsed_uri);
            }
        }
    
        return 1;
    }
    
    int cache_check_freshness(cache_handle_t *h, cache_request_rec *cache,
            request_rec *r)
    {
        apr_status_t status;
        apr_int64_t age, maxage_req, maxage_cresp, maxage, smaxage, maxstale;
        apr_int64_t minfresh;
        const char *cc_req;
        const char *pragma;
        const char *agestr = NULL;
        apr_time_t age_c = 0;
        cache_info *info = &(h->cache_obj->info);
        const char *warn_head;
        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
         * perform the request unconditionally, and ignore cached content. We
         * should never reach here, but if we do, mark the content as stale,
         * as this is the best we can do.
         *
         * - 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 <max-stale>
         * 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");
    
        ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
    
        if (cache->control_in.no_cache) {
    
            if (!conf->ignorecachecontrol) {
                /* Treat as stale, causing revalidation */
                return 0;
            }
    
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00781)
                    "Incoming request is asking for a uncached version of "
                    "%s, but we have been configured to ignore it and "
                    "serve a cached response anyway",
                    r->unparsed_uri);
        }
    
        /* These come from the cached entity. */
        if (h->cache_obj->info.control.no_cache
                || h->cache_obj->info.control.invalidated) {
            /*
             * The cached entity contained Cache-Control: no-cache, or a
             * no-cache with a header present, or a private with a header
             * present, or the cached entity has been invalidated in the
             * past, so treat as stale causing revalidation.
             */
            return 0;
        }
    
        if ((agestr = apr_table_get(h->resp_hdrs, "Age"))) {
            char *endp;
            apr_off_t offt;
            if (!apr_strtoff(&offt, agestr, &endp, 10)
                    && endp > agestr && !*endp) {
                age_c = offt;
            }
        }
    
        /* calculate age of object */
        age = ap_cache_current_age(info, age_c, r->request_time);
    
        /* extract s-maxage */
        smaxage = h->cache_obj->info.control.s_maxage_value;
    
        /* extract max-age from request */
        maxage_req = -1;
        if (!conf->ignorecachecontrol) {
            maxage_req = cache->control_in.max_age_value;
        }
    
        /*
         * extract max-age from response, if both s-maxage and max-age, s-maxage
         * takes priority
         */
        if (smaxage != -1) {
            maxage_cresp = smaxage;
        }
        else {
            maxage_cresp = h->cache_obj->info.control.max_age_value;
        }
    
        /*
         * 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 (cache->control_in.max_stale) {
            if (cache->control_in.max_stale_value != -1) {
                maxstale = cache->control_in.max_stale_value;
            }
            else {
                /*
                 * If no value is assigned to max-stale, then the client is willing
                 * to accept a stale response of any age (RFC2616 14.9.3). We will
                 * set it to one year in this case as this situation is somewhat
                 * similar to a "never expires" Expires header (RFC2616 14.21)
                 * which is set to a date one year from the time the response is
                 * sent in this case.
                 */
                maxstale = APR_INT64_C(86400*365);
            }
        }
        else {
            maxstale = 0;
        }
    
        /* extract min-fresh */
        if (!conf->ignorecachecontrol && cache->control_in.min_fresh) {
            minfresh = cache->control_in.min_fresh_value;
        }
        else {
            minfresh = 0;
        }
    
        /* override maxstale if must-revalidate, proxy-revalidate or s-maxage */
        if (maxstale && (h->cache_obj->info.control.must_revalidate
                || h->cache_obj->info.control.proxy_revalidate || smaxage != -1)) {
            maxstale = 0;
        }
    
        /* handle expiration */
        if (((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)))) {
    
            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 (!(((maxage != -1) && age < maxage) ||
                  (info->expire != APR_DATE_BAD &&
                   (apr_time_sec(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_mergen(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 response header age
             * calculated is more than 24 hours add the warning 113
             */
            if ((maxage_cresp == -1) && (smaxage == -1) && (apr_table_get(
                    h->resp_hdrs, "Expires") == 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_mergen(h->resp_hdrs, "Warning",
                                     "113 Heuristic expiration");
                }
            }
            return 1;    /* Cache object is fresh (enough) */
        }
    
        /*
         * At this point we are stale, but: if we are under load, we may let
         * a significant number of stale requests through before the first
         * stale request successfully revalidates itself, causing a sudden
         * unexpected thundering herd which in turn brings angst and drama.
         *
         * So.
         *
         * We want the first stale request to go through as normal. But the
         * second and subsequent request, we must pretend to be fresh until
         * the first request comes back with either new content or confirmation
         * that the stale content is still fresh.
         *
         * To achieve this, we create a very simple file based lock based on
         * the key of the cached object. We attempt to open the lock file with
         * exclusive write access. If we succeed, woohoo! we're first, and we
         * follow the stale path to the backend server. If we fail, oh well,
         * we follow the fresh path, and avoid being a thundering herd.
         *
         * The lock lives only as long as the stale request that went on ahead.
         * If the request succeeds, the lock is deleted. If the request fails,
         * the lock is deleted, and another request gets to make a new lock
         * and try again.
         *
         * At any time, a request marked "no-cache" will force a refresh,
         * ignoring the lock, ensuring an extended lockout is impossible.
         *
         * A lock that exceeds a maximum age will be deleted, and another
         * request gets to make a new lock and try again.
         */
        status = cache_try_lock(conf, cache, r);
        if (APR_SUCCESS == status) {
            /* we obtained a lock, follow the stale path */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00782)
                    "Cache lock obtained for stale cached URL, "
                    "revalidating entry: %s",
                    r->unparsed_uri);
            return 0;
        }
        else if (APR_STATUS_IS_EEXIST(status)) {
            /* lock already exists, return stale data anyway, with a warning */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00783)
                    "Cache already locked for stale cached URL, "
                    "pretend it is fresh: %s",
                    r->unparsed_uri);
    
            /* make sure we don't stomp on a previous warning */
            warn_head = apr_table_get(h->resp_hdrs, "Warning");
            if ((warn_head == NULL) ||
                ((warn_head != NULL) && (ap_strstr_c(warn_head, "110") == NULL))) {
                apr_table_mergen(h->resp_hdrs, "Warning",
                                 "110 Response is stale");
            }
    
            return 1;
        }
        else {
            /* some other error occurred, just treat the object as stale */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00784)
                    "Attempt to obtain a cache lock for stale "
                    "cached URL failed, revalidating entry anyway: %s",
                    r->unparsed_uri);
            return 0;
        }
    
    }
    
    /* 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_pstrmemdup(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);
    }
    
    /**
     * String tokenizer that ignores separator characters within quoted strings
     * and escaped characters, as per RFC2616 section 2.2.
     */
    char *cache_strqtok(char *str, const char *sep, char **last)
    {
        char *token;
        int quoted = 0;
    
        if (!str) {         /* subsequent call */
            str = *last;    /* start where we left off */
        }
    
        if (!str) {         /* no more tokens */
            return NULL;
        }
    
        /* skip characters in sep (will terminate at '\0') */
        while (*str && ap_strchr_c(sep, *str)) {
            ++str;
        }
    
        if (!*str) {        /* no more tokens */
            return NULL;
        }
    
        token = str;
    
        /* skip valid token characters to terminate token and
         * prepare for the next call (will terminate at '\0)
         * on the way, ignore all quoted strings, and within
         * quoted strings, escaped characters.
         */
        *last = token;
        while (**last) {
            if (!quoted) {
                if (**last == '\"' && !ap_strchr_c(sep, '\"')) {
                    quoted = 1;
                    ++*last;
                }
                else if (!ap_strchr_c(sep, **last)) {
                    ++*last;
                }
                else {
                    break;
                }
            }
            else {
                if (**last == '\"') {
                    quoted = 0;
                    ++*last;
                }
                else if (**last == '\\') {
                    ++*last;
                    if (**last) {
                        ++*last;
                    }
                }
                else {
                    ++*last;
                }
            }
        }
    
        if (**last) {
            **last = '\0';
            ++*last;
        }
    
        return token;
    }
    
    /**
     * Parse the Cache-Control and Pragma headers in one go, marking
     * which tokens appear within the header. Populate the structure
     * passed in.
     */
    int ap_cache_control(request_rec *r, cache_control_t *cc,
            const char *cc_header, const char *pragma_header, apr_table_t *headers)
    {
        char *last;
    
        if (cc->parsed) {
            return cc->cache_control || cc->pragma;
        }
    
        cc->parsed = 1;
        cc->max_age_value = -1;
        cc->max_stale_value = -1;
        cc->min_fresh_value = -1;
        cc->s_maxage_value = -1;
    
        if (pragma_header) {
            char *header = apr_pstrdup(r->pool, pragma_header);
            const char *token = cache_strqtok(header, CACHE_SEPARATOR, &last);
            while (token) {
                if (!ap_cstr_casecmp(token, "no-cache")) {
                    cc->no_cache = 1;
                }
                token = cache_strqtok(NULL, CACHE_SEPARATOR, &last);
            }
            cc->pragma = 1;
        }
    
        if (cc_header) {
            char *endp;
            apr_off_t offt;
            char *header = apr_pstrdup(r->pool, cc_header);
            const char *token = cache_strqtok(header, CACHE_SEPARATOR, &last);
            while (token) {
                switch (token[0]) {
                case 'n':
                case 'N': {
                    if (!ap_cstr_casecmpn(token, "no-cache", 8)) {
                        if (token[8] == '=') {
                            cc->no_cache_header = 1;
                        }
                        else if (!token[8]) {
                            cc->no_cache = 1;
                        }
                    }
                    else if (!ap_cstr_casecmp(token, "no-store")) {
                        cc->no_store = 1;
                    }
                    else if (!ap_cstr_casecmp(token, "no-transform")) {
                        cc->no_transform = 1;
                    }
                    break;
                }
                case 'm':
                case 'M': {
                    if (!ap_cstr_casecmpn(token, "max-age", 7)) {
                        if (token[7] == '='
                                && !apr_strtoff(&offt, token + 8, &endp, 10)
                                && endp > token + 8 && !*endp) {
                            cc->max_age = 1;
                            cc->max_age_value = offt;
                        }
                    }
                    else if (!ap_cstr_casecmp(token, "must-revalidate")) {
                        cc->must_revalidate = 1;
                    }
                    else if (!ap_cstr_casecmpn(token, "max-stale", 9)) {
                        if (token[9] == '='
                                && !apr_strtoff(&offt, token + 10, &endp, 10)
                                && endp > token + 10 && !*endp) {
                            cc->max_stale = 1;
                            cc->max_stale_value = offt;
                        }
                        else if (!token[9]) {
                            cc->max_stale = 1;
                            cc->max_stale_value = -1;
                        }
                    }
                    else if (!ap_cstr_casecmpn(token, "min-fresh", 9)) {
                        if (token[9] == '='
                                && !apr_strtoff(&offt, token + 10, &endp, 10)
                                && endp > token + 10 && !*endp) {
                            cc->min_fresh = 1;
                            cc->min_fresh_value = offt;
                        }
                    }
                    break;
                }
                case 'o':
                case 'O': {
                    if (!ap_cstr_casecmp(token, "only-if-cached")) {
                        cc->only_if_cached = 1;
                    }
                    break;
                }
                case 'p':
                case 'P': {
                    if (!ap_cstr_casecmp(token, "public")) {
                        cc->public = 1;
                    }
                    else if (!ap_cstr_casecmpn(token, "private", 7)) {
                        if (token[7] == '=') {
                            cc->private_header = 1;
                        }
                        else if (!token[7]) {
                            cc->private = 1;
                        }
                    }
                    else if (!ap_cstr_casecmp(token, "proxy-revalidate")) {
                        cc->proxy_revalidate = 1;
                    }
                    break;
                }
                case 's':
                case 'S': {
                    if (!ap_cstr_casecmpn(token, "s-maxage", 8)) {
                        if (token[8] == '='
                                && !apr_strtoff(&offt, token + 9, &endp, 10)
                                && endp > token + 9 && !*endp) {
                            cc->s_maxage = 1;
                            cc->s_maxage_value = offt;
                        }
                    }
                    break;
                }
                }
                token = cache_strqtok(NULL, CACHE_SEPARATOR, &last);
            }
            cc->cache_control = 1;
        }
    
        return (cc_header != NULL || pragma_header != NULL);
    }
    
    /**
     * Parse the Cache-Control, identifying and removing headers that
     * exist as tokens after the no-cache and private tokens.
     */
    static int cache_control_remove(request_rec *r, const char *cc_header,
            apr_table_t *headers)
    {
        char *last, *slast;
        int found = 0;
    
        if (cc_header) {
            char *header = apr_pstrdup(r->pool, cc_header);
            char *token = cache_strqtok(header, CACHE_SEPARATOR, &last);
            while (token) {
                switch (token[0]) {
                case 'n':
                case 'N': {
                    if (!ap_cstr_casecmpn(token, "no-cache", 8)) {
                        if (token[8] == '=') {
                            const char *header = cache_strqtok(token + 9,
                                    CACHE_SEPARATOR "\"", &slast);
                            while (header) {
                                apr_table_unset(headers, header);
                                header = cache_strqtok(NULL, CACHE_SEPARATOR "\"",
                                        &slast);
                            }
                            found = 1;
                        }
                    }
                    break;
                }
                case 'p':
                case 'P': {
                    if (!ap_cstr_casecmpn(token, "private", 7)) {
                        if (token[7] == '=') {
                            const char *header = cache_strqtok(token + 8,
                                    CACHE_SEPARATOR "\"", &slast);
                            while (header) {
                                apr_table_unset(headers, header);
                                header = cache_strqtok(NULL, CACHE_SEPARATOR "\"",
                                        &slast);
                            }
                            found = 1;
                        }
                    }
                    break;
                }
                }
                token = cache_strqtok(NULL, CACHE_SEPARATOR, &last);
            }
        }
    
        return found;
    }
    
    /*
     * Create a new table consisting of those elements from an
     * headers table that are allowed to be stored in a cache.
     */
    CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers(apr_pool_t *pool,
                                                            apr_table_t *t,
                                                            server_rec *s)
    {
        cache_server_conf *conf;
        char **header;
        int i;
        apr_table_t *headers_out;
    
        /* Short circuit the common case that there are not
         * (yet) any headers populated.
         */
        if (t == NULL) {
            return apr_table_make(pool, 10);
        };
    
        /* 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
         */
        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;
    }
    
    /*
     * 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_headers_in(request_rec *r)
    {
        return ap_cache_cacheable_headers(r->pool, r->headers_in, r->server);
    }
    
    /*
     * Create a new table consisting of those elements from an output
     * headers table that are allowed to be stored in a cache;
     * ensure there is a content type and capture any errors.
     */
    CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers_out(request_rec *r)
    {
        apr_table_t *headers_out;
    
        headers_out = ap_cache_cacheable_headers(r->pool,
                                                 cache_merge_headers_out(r),
                                                 r->server);
    
        cache_control_remove(r,
                cache_table_getm(r->pool, headers_out, "Cache-Control"),
                headers_out);
    
        return headers_out;
    }
    
    apr_table_t *cache_merge_headers_out(request_rec *r)
    {
        apr_table_t *headers_out;
    
        headers_out = apr_table_overlay(r->pool, r->headers_out,
                                        r->err_headers_out);
    
        if (r->content_type
                && !apr_table_get(headers_out, "Content-Type")) {
            const char *ctype = ap_make_content_type(r, r->content_type);
            if (ctype) {
                apr_table_setn(headers_out, "Content-Type", ctype);
            }
        }
    
        if (r->content_encoding
                && !apr_table_get(headers_out, "Content-Encoding")) {
            apr_table_setn(headers_out, "Content-Encoding",
                           r->content_encoding);
        }
    
        return headers_out;
    }
    
    typedef struct
    {
        apr_pool_t *p;
        const char *first;
        apr_array_header_t *merged;
    } cache_table_getm_t;
    
    static int cache_table_getm_do(void *v, const char *key, const char *val)
    {
        cache_table_getm_t *state = (cache_table_getm_t *) v;
    
        if (!state->first) {
            /**
             * The most common case is a single header, and this is covered by
             * a fast path that doesn't allocate any memory. On the second and
             * subsequent header, an array is created and the array concatenated
             * together to form the final value.
             */
            state->first = val;
        }
        else {
            const char **elt;
            if (!state->merged) {
                state->merged = apr_array_make(state->p, 10, sizeof(const char *));
                elt = apr_array_push(state->merged);
                *elt = state->first;
            }
            elt = apr_array_push(state->merged);
            *elt = val;
        }
        return 1;
    }
    
    const char *cache_table_getm(apr_pool_t *p, const apr_table_t *t,
            const char *key)
    {
        cache_table_getm_t state;
    
        state.p = p;
        state.first = NULL;
        state.merged = NULL;
    
        apr_table_do(cache_table_getm_do, &state, t, key, NULL);
    
        if (!state.first) {
            return NULL;
        }
        else if (!state.merged) {
            return state.first;
        }
        else {
            return apr_array_pstrcat(p, state.merged, ',');
        }
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/.indent.pro��������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�017423� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_dc.c���������������������������������������������������������0000664�0001751�0001751�00000016437�13623622544�020435� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "http_request.h"
    #include "http_config.h"
    #include "http_protocol.h"
    #include "mod_status.h"
    
    #include "apr_strings.h"
    #include "apr_time.h"
    
    #include "ap_socache.h"
    
    #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
    
    struct ap_socache_instance_t {
        /* Configured target server: */
        const char *target;
        /* distcache client context: */
        DC_CTX *dc;
    };
    
    static const char *socache_dc_create(ap_socache_instance_t **context,
                                         const char *arg,
                                         apr_pool_t *tmp, apr_pool_t *p)
    {
        struct ap_socache_instance_t *ctx;
    
        ctx = *context = apr_palloc(p, sizeof *ctx);
    
        ctx->target = apr_pstrdup(p, arg);
    
        return NULL;
    }
    
    static apr_status_t socache_dc_init(ap_socache_instance_t *ctx,
                                        const char *namespace,
                                        const struct ap_socache_hints *hints,
                                        server_rec *s, apr_pool_t *p)
    {
    #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 negligible and it reduces the
         * performance/stability danger of file-descriptor bloatage. */
    #define SESSION_CTX_FLAGS        0
    #endif
        ctx->dc = DC_CTX_new(ctx->target, SESSION_CTX_FLAGS);
        if (!ctx->dc) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00738) "distributed scache failed to obtain context");
            return APR_EGENERAL;
        }
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(00739) "distributed scache context initialised");
    
        return APR_SUCCESS;
    }
    
    static void socache_dc_destroy(ap_socache_instance_t *ctx, server_rec *s)
    {
        if (ctx && ctx->dc) {
            DC_CTX_free(ctx->dc);
            ctx->dc = NULL;
        }
    }
    
    static apr_status_t socache_dc_store(ap_socache_instance_t *ctx, server_rec *s,
                                         const unsigned char *id, unsigned int idlen,
                                         apr_time_t expiry,
                                         unsigned char *der, unsigned int der_len,
                                         apr_pool_t *p)
    {
        /* !@#$%^ - why do we deal with *absolute* time anyway???
         * Uhm - because most things expire things at a specific time?
         * Were the API were thought out expiry - r->request_time is a good approximation
         */
        expiry -= apr_time_now();
        /* Send the serialised session to the distributed cache context */
        if (!DC_CTX_add_session(ctx->dc, id, idlen, der, der_len,
                                apr_time_msec(expiry))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00740) "distributed scache 'store' failed");
            return APR_EGENERAL;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00741) "distributed scache 'store' successful");
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_dc_retrieve(ap_socache_instance_t *ctx, server_rec *s,
                                            const unsigned char *id, unsigned int idlen,
                                            unsigned char *dest, unsigned int *destlen,
                                            apr_pool_t *p)
    {
        unsigned int data_len;
    
        /* Retrieve any corresponding session from the distributed cache context */
        if (!DC_CTX_get_session(ctx->dc, id, idlen, dest, *destlen, &data_len)) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00742) "distributed scache 'retrieve' MISS");
            return APR_NOTFOUND;
        }
        if (data_len > *destlen) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00743) "distributed scache 'retrieve' OVERFLOW");
            return APR_ENOSPC;
        }
        *destlen = data_len;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00744) "distributed scache 'retrieve' HIT");
        return APR_SUCCESS;
    }
    
    static apr_status_t socache_dc_remove(ap_socache_instance_t *ctx,
                                          server_rec *s, const unsigned char *id,
                                          unsigned int idlen, apr_pool_t *p)
    {
        /* Remove any corresponding session from the distributed cache context */
        if (!DC_CTX_remove_session(ctx->dc, id, idlen)) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00745) "distributed scache 'remove' MISS");
            return APR_NOTFOUND;
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00746) "distributed scache 'remove' HIT");
            return APR_SUCCESS;
        }
    }
    
    static void socache_dc_status(ap_socache_instance_t *ctx, request_rec *r, int flags)
    {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00747)
                      "distributed scache 'socache_dc_status'");
        if (!(flags & AP_STATUS_SHORT)) {
            ap_rprintf(r, "cache type: <b>DC (Distributed Cache)</b>, "
                       " target: <b>%s</b><br>", ctx->target);
        }
        else {
            ap_rputs("CacheType: DC\n", r);
            ap_rvputs(r, "CacheTarget: ", ctx->target, "\n", NULL);
        }
    }
    
    static apr_status_t socache_dc_iterate(ap_socache_instance_t *instance,
                                           server_rec *s, void *userctx,
                                           ap_socache_iterator_t *iterator,
                                           apr_pool_t *pool)
    {
        return APR_ENOTIMPL;
    }
    
    static const ap_socache_provider_t socache_dc = {
        "distcache",
        0,
        socache_dc_create,
        socache_dc_init,
        socache_dc_destroy,
        socache_dc_store,
        socache_dc_retrieve,
        socache_dc_remove,
        socache_dc_status,
        socache_dc_iterate
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_provider(p, AP_SOCACHE_PROVIDER_GROUP, "dc",
                             AP_SOCACHE_PROVIDER_VERSION,
                             &socache_dc);
    }
    
    AP_DECLARE_MODULE(socache_dc) = {
        STANDARD20_MODULE_STUFF,
        NULL, NULL, NULL, NULL, NULL,
        register_hooks
    };
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/config.m4����������������������������������������������������������������0000664�0001751�0001751�00000011454�13444157463�017064� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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, , , most)
    
    dnl #  list of object files for mod_cache
    cache_objs="dnl
    mod_cache.lo dnl
    cache_storage.lo dnl
    cache_util.lo dnl
    "
    cache_disk_objs="mod_cache_disk.lo"
    cache_socache_objs="mod_cache_socache.lo"
    
    case "$host" in
      *os2*)
        # OS/2 DLLs must resolve all symbols at build time
        # and we need some from main cache module
        cache_disk_objs="$cache_disk_objs mod_cache.la"
        cache_socache_objs="$cache_socache_objs mod_cache.la"
        ;;
    esac
    
    APACHE_MODULE(cache, dynamic file caching.  At least one storage management module (e.g. mod_cache_disk) is also necessary., $cache_objs, , most)
    APACHE_MODULE(cache_disk, disk caching module, $cache_disk_objs, , most, , cache)
    APACHE_MODULE(cache_socache, shared object caching module, $cache_socache_objs, , most)
    
    dnl
    dnl APACHE_CHECK_DISTCACHE
    dnl
    dnl Configure for the detected distcache installation, giving
    dnl preference to "--with-distcache=<path>" if it was specified.
    dnl
    AC_DEFUN([APACHE_CHECK_DISTCACHE],[
    if test "x$ap_distcache_configured" = "x"; then
      dnl initialise the variables we use
      ap_distcache_found=""
      ap_distcache_base=""
      ap_distcache_libs=""
      ap_distcache_ldflags=""
      ap_distcache_with=""
    
      dnl Determine the distcache base directory, if any
      AC_MSG_CHECKING([for user-provided distcache base])
      AC_ARG_WITH(distcache, APACHE_HELP_STRING(--with-distcache=PATH, Distcache installation directory), [
        dnl If --with-distcache 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_distcache_with="yes"
          ap_distcache_base="`cd $withval ; pwd`"
        fi
      ])
      if test "x$ap_distcache_base" = "x"; then
        AC_MSG_RESULT(none)
      else
        AC_MSG_RESULT($ap_distcache_base)
      fi
    
      dnl Run header and version checks
      saved_CPPFLAGS="$CPPFLAGS"
      saved_LIBS="$LIBS"
      saved_LDFLAGS="$LDFLAGS"
    
      if test "x$ap_distcache_base" != "x"; then
        APR_ADDTO(CPPFLAGS, [-I$ap_distcache_base/include])
        APR_ADDTO(MOD_INCLUDES, [-I$ap_distcache_base/include])
        APR_ADDTO(LDFLAGS, [-L$ap_distcache_base/lib])
        APR_ADDTO(ap_distcache_ldflags, [-L$ap_distcache_base/lib])
        if test "x$ap_platform_runtime_link_flag" != "x"; then
          APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_distcache_base/lib])
          APR_ADDTO(ap_distcache_ldflags, [$ap_platform_runtime_link_flag$ap_distcache_base/lib])
        fi
      fi
      dnl First check for mandatory headers
      AC_CHECK_HEADERS([distcache/dc_client.h], [ap_distcache_found="yes"], [])
      if test "$ap_distcache_found" = "yes"; then
        dnl test for a good version
        AC_MSG_CHECKING(for distcache version)
        AC_TRY_COMPILE([#include <distcache/dc_client.h>],[
    #if DISTCACHE_CLIENT_API != 0x0001
    #error "distcache API version is unrecognised"
    #endif],
          [],
          [ap_distcache_found="no"])
        AC_MSG_RESULT($ap_distcache_found)
      fi
      if test "$ap_distcache_found" != "yes"; then
        if test "x$ap_distcache_with" = "x"; then
          AC_MSG_WARN([...No distcache detected])
        else
          AC_MSG_ERROR([...No distcache detected])
        fi
      else
        dnl Run library and function checks
        AC_MSG_CHECKING(for distcache libraries)
        ap_distcache_libs="-ldistcache -lnal"
        APR_ADDTO(LIBS, [$ap_distcache_libs])
    
        AC_TRY_LINK(
          [#include <distcache/dc_client.h>],
          [DC_CTX *foo = DC_CTX_new((const char *)0,0);],
          [],
          [ap_distcache_found="no"])
        AC_MSG_RESULT($ap_distcache_found)
        if test "$ap_distcache_found" != "yes"; then
          if test "x$ap_distcache_base" = "x"; then
            AC_MSG_WARN([... Error, distcache libraries were missing or unusable])
          else
            AC_MSG_ERROR([... Error, distcache libraries were missing or unusable])
          fi
        fi
      fi
    
      dnl restore
      CPPFLAGS="$saved_CPPFLAGS"
      LIBS="$saved_LIBS"
      LDFLAGS="$saved_LDFLAGS"
    
      dnl Adjust apache's configuration based on what we found above.
      if test "$ap_distcache_found" = "yes"; then
        APR_ADDTO(MOD_SOCACHE_DC_LDADD, [$ap_distcache_ldflags $ap_distcache_libs])
        AC_DEFINE(HAVE_DISTCACHE, 1, [Define if distcache support is enabled])
      else
        enable_socache_dc=no
      fi
      ap_distcache_configured="yes"
    fi
    ])
    
    APACHE_MODULE(socache_shmcb,  shmcb small object cache provider, , , most)
    APACHE_MODULE(socache_dbm, dbm small object cache provider, , , most)
    APACHE_MODULE(socache_memcache, memcache small object cache provider, , , most)
    APACHE_MODULE(socache_redis, redis small object cache provider, , , most)
    APACHE_MODULE(socache_dc, distcache small object cache provider, , , no, [
        APACHE_CHECK_DISTCACHE
    ])
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_memcache.mak�������������������������������������������������0000664�0001751�0001751�00000025131�13025033421�022110� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_socache_memcache.dsp
    !IF "$(CFG)" == ""
    CFG=mod_socache_memcache - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_socache_memcache - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_socache_memcache - Win32 Release" && "$(CFG)" != "mod_socache_memcache - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_socache_memcache.mak" CFG="mod_socache_memcache - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_memcache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_memcache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_memcache - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_memcache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_socache_memcache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_memcache.obj"
    	-@erase "$(INTDIR)\mod_socache_memcache.res"
    	-@erase "$(INTDIR)\mod_socache_memcache_src.idb"
    	-@erase "$(INTDIR)\mod_socache_memcache_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_memcache.exp"
    	-@erase "$(OUTDIR)\mod_socache_memcache.lib"
    	-@erase "$(OUTDIR)\mod_socache_memcache.pdb"
    	-@erase "$(OUTDIR)\mod_socache_memcache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_memcache_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_memcache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_memcache.so" /d LONG_NAME="socache_memcache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_memcache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_memcache.pdb" /debug /out:"$(OUTDIR)\mod_socache_memcache.so" /implib:"$(OUTDIR)\mod_socache_memcache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_memcache.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_memcache.obj" \
    	"$(INTDIR)\mod_socache_memcache.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_memcache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_socache_memcache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_memcache.so"
       if exist .\Release\mod_socache_memcache.so.manifest mt.exe -manifest .\Release\mod_socache_memcache.so.manifest -outputresource:.\Release\mod_socache_memcache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_socache_memcache - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_memcache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_socache_memcache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_memcache.obj"
    	-@erase "$(INTDIR)\mod_socache_memcache.res"
    	-@erase "$(INTDIR)\mod_socache_memcache_src.idb"
    	-@erase "$(INTDIR)\mod_socache_memcache_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_memcache.exp"
    	-@erase "$(OUTDIR)\mod_socache_memcache.lib"
    	-@erase "$(OUTDIR)\mod_socache_memcache.pdb"
    	-@erase "$(OUTDIR)\mod_socache_memcache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_memcache_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_memcache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_memcache.so" /d LONG_NAME="socache_memcache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_memcache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_memcache.pdb" /debug /out:"$(OUTDIR)\mod_socache_memcache.so" /implib:"$(OUTDIR)\mod_socache_memcache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_memcache.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_memcache.obj" \
    	"$(INTDIR)\mod_socache_memcache.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_memcache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_socache_memcache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_memcache.so"
       if exist .\Debug\mod_socache_memcache.so.manifest mt.exe -manifest .\Debug\mod_socache_memcache.so.manifest -outputresource:.\Debug\mod_socache_memcache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_socache_memcache.dep")
    !INCLUDE "mod_socache_memcache.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_socache_memcache.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_socache_memcache - Win32 Release" || "$(CFG)" == "mod_socache_memcache - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_socache_memcache - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_memcache - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_memcache - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_memcache - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_memcache - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_memcache - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_socache_memcache - Win32 Release"
    
    
    "$(INTDIR)\mod_socache_memcache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_memcache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_socache_memcache.so" /d LONG_NAME="socache_memcache_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_socache_memcache - Win32 Debug"
    
    
    "$(INTDIR)\mod_socache_memcache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_memcache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_socache_memcache.so" /d LONG_NAME="socache_memcache_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_socache_memcache.c
    
    "$(INTDIR)\mod_socache_memcache.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_disk.mak�������������������������������������������������������0000664�0001751�0001751�00000025562�12701473373�020764� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_cache_disk.dsp
    !IF "$(CFG)" == ""
    CFG=mod_cache_disk - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_cache_disk - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_cache_disk - Win32 Release" && "$(CFG)" != "mod_cache_disk - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_disk.mak" CFG="mod_cache_disk - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_cache_disk - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_cache_disk - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_disk - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cache_disk.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_cache - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_cache_disk.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_cache - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cache_disk.obj"
    	-@erase "$(INTDIR)\mod_cache_disk.res"
    	-@erase "$(INTDIR)\mod_cache_disk_src.idb"
    	-@erase "$(INTDIR)\mod_cache_disk_src.pdb"
    	-@erase "$(OUTDIR)\mod_cache_disk.exp"
    	-@erase "$(OUTDIR)\mod_cache_disk.lib"
    	-@erase "$(OUTDIR)\mod_cache_disk.pdb"
    	-@erase "$(OUTDIR)\mod_cache_disk.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cache_disk_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cache_disk.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cache_disk.so" /d LONG_NAME="cache_disk_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cache_disk.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cache_disk.pdb" /debug /out:"$(OUTDIR)\mod_cache_disk.so" /implib:"$(OUTDIR)\mod_cache_disk.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_disk.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cache_disk.obj" \
    	"$(INTDIR)\mod_cache_disk.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_cache.lib"
    
    "$(OUTDIR)\mod_cache_disk.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_cache_disk.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cache_disk.so"
       if exist .\Release\mod_cache_disk.so.manifest mt.exe -manifest .\Release\mod_cache_disk.so.manifest -outputresource:.\Release\mod_cache_disk.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_cache_disk - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cache_disk.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_cache - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_cache_disk.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_cache - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_cache_disk.obj"
    	-@erase "$(INTDIR)\mod_cache_disk.res"
    	-@erase "$(INTDIR)\mod_cache_disk_src.idb"
    	-@erase "$(INTDIR)\mod_cache_disk_src.pdb"
    	-@erase "$(OUTDIR)\mod_cache_disk.exp"
    	-@erase "$(OUTDIR)\mod_cache_disk.lib"
    	-@erase "$(OUTDIR)\mod_cache_disk.pdb"
    	-@erase "$(OUTDIR)\mod_cache_disk.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cache_disk_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cache_disk.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cache_disk.so" /d LONG_NAME="cache_disk_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cache_disk.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cache_disk.pdb" /debug /out:"$(OUTDIR)\mod_cache_disk.so" /implib:"$(OUTDIR)\mod_cache_disk.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_disk.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_cache_disk.obj" \
    	"$(INTDIR)\mod_cache_disk.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_cache.lib"
    
    "$(OUTDIR)\mod_cache_disk.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_cache_disk.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cache_disk.so"
       if exist .\Debug\mod_cache_disk.so.manifest mt.exe -manifest .\Debug\mod_cache_disk.so.manifest -outputresource:.\Debug\mod_cache_disk.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_cache_disk.dep")
    !INCLUDE "mod_cache_disk.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_cache_disk.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_cache_disk - Win32 Release" || "$(CFG)" == "mod_cache_disk - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_cache_disk - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache_disk - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_disk - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache_disk - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_disk - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache_disk - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache_disk - Win32 Release"
    
    "mod_cache - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Release" 
       cd "."
    
    "mod_cache - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_cache_disk - Win32 Debug"
    
    "mod_cache - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Debug" 
       cd "."
    
    "mod_cache - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_cache.mak" CFG="mod_cache - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_cache_disk - Win32 Release"
    
    
    "$(INTDIR)\mod_cache_disk.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cache_disk.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_cache_disk.so" /d LONG_NAME="cache_disk_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_cache_disk - Win32 Debug"
    
    
    "$(INTDIR)\mod_cache_disk.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cache_disk.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_cache_disk.so" /d LONG_NAME="cache_disk_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_cache_disk.c
    
    "$(INTDIR)\mod_cache_disk.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_dc.mak�������������������������������������������������������0000664�0001751�0001751�00000024043�12701473373�020753� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_socache_dc.dsp
    !IF "$(CFG)" == ""
    CFG=mod_socache_dc - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_socache_dc - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_socache_dc - Win32 Release" && "$(CFG)" != "mod_socache_dc - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_socache_dc.mak" CFG="mod_socache_dc - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_dc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_dc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_dc - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_dc.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_socache_dc.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_dc.obj"
    	-@erase "$(INTDIR)\mod_socache_dc.res"
    	-@erase "$(INTDIR)\mod_socache_dc_src.idb"
    	-@erase "$(INTDIR)\mod_socache_dc_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dc.exp"
    	-@erase "$(OUTDIR)\mod_socache_dc.lib"
    	-@erase "$(OUTDIR)\mod_socache_dc.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dc.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_dc_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_dc.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_dc.so" /d LONG_NAME="socache_dc_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_dc.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_dc.pdb" /debug /out:"$(OUTDIR)\mod_socache_dc.so" /implib:"$(OUTDIR)\mod_socache_dc.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dc.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_dc.obj" \
    	"$(INTDIR)\mod_socache_dc.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_dc.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_socache_dc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_dc.so"
       if exist .\Release\mod_socache_dc.so.manifest mt.exe -manifest .\Release\mod_socache_dc.so.manifest -outputresource:.\Release\mod_socache_dc.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dc - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_dc.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_socache_dc.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_dc.obj"
    	-@erase "$(INTDIR)\mod_socache_dc.res"
    	-@erase "$(INTDIR)\mod_socache_dc_src.idb"
    	-@erase "$(INTDIR)\mod_socache_dc_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dc.exp"
    	-@erase "$(OUTDIR)\mod_socache_dc.lib"
    	-@erase "$(OUTDIR)\mod_socache_dc.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dc.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_dc_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_dc.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_dc.so" /d LONG_NAME="socache_dc_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_dc.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_dc.pdb" /debug /out:"$(OUTDIR)\mod_socache_dc.so" /implib:"$(OUTDIR)\mod_socache_dc.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dc.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_dc.obj" \
    	"$(INTDIR)\mod_socache_dc.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_dc.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_socache_dc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_dc.so"
       if exist .\Debug\mod_socache_dc.so.manifest mt.exe -manifest .\Debug\mod_socache_dc.so.manifest -outputresource:.\Debug\mod_socache_dc.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_socache_dc.dep")
    !INCLUDE "mod_socache_dc.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_socache_dc.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_socache_dc - Win32 Release" || "$(CFG)" == "mod_socache_dc - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_socache_dc - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dc - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_dc - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dc - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_dc - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dc - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_socache_dc - Win32 Release"
    
    
    "$(INTDIR)\mod_socache_dc.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_dc.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_socache_dc.so" /d LONG_NAME="socache_dc_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_socache_dc - Win32 Debug"
    
    
    "$(INTDIR)\mod_socache_dc.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_dc.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_socache_dc.so" /d LONG_NAME="socache_dc_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_socache_dc.c
    
    "$(INTDIR)\mod_socache_dc.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_socache.dep����������������������������������������������������0000664�0001751�0001751�00000004536�12674411515�021434� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_cache_socache.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_cache_socache.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\generators\mod_status.h"\
    	".\cache_common.h"\
    	".\cache_socache_common.h"\
    	".\mod_cache.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_memcache.dep�������������������������������������������������0000664�0001751�0001751�00000004231�12674411515�022123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_socache_memcache.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_socache_memcache.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_memcache.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr-util\include\apu_version.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_redis.dsp����������������������������������������������������0000664�0001751�0001751�00000011504�13444157463�021513� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_socache_redis" - 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_socache_redis - 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_socache_redis.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_socache_redis.mak" CFG="mod_socache_redis - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_redis - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_redis - 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_socache_redis - 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 "../generators" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Release\mod_socache_redis_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 /fo"Release/mod_socache_redis.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_redis.so" /d LONG_NAME="socache_redis module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_socache_redis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_redis.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_socache_redis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_redis.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_socache_redis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_socache_redis - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../generators" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Debug\mod_socache_redis_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 /fo"Debug/mod_socache_redis.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_redis.so" /d LONG_NAME="socache_redis module for Apache"
    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 /out:".\Debug\mod_socache_redis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_redis.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_socache_redis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_redis.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_socache_redis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_socache_redis - Win32 Release"
    # Name "mod_socache_redis - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_socache_redis.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/NWGNUsocachmem�����������������������������������������������������������0000664�0001751�0001751�00000010467�13023777056�020060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(STDMOD)/generators \
    			$(AP_WORK)/server/mpm/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	= socachemem
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Socache Memory Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= socachemem
    
    #
    # 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	=
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_socache_memcache.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 = \
    	$(PRELUDE) \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	socache_memcache_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_file_cache.mak�������������������������������������������������������0000664�0001751�0001751�00000024033�12701473373�020741� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_file_cache.dsp
    !IF "$(CFG)" == ""
    CFG=mod_file_cache - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_file_cache - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_file_cache - Win32 Release" && "$(CFG)" != "mod_file_cache - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_file_cache - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_file_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_file_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_file_cache.obj"
    	-@erase "$(INTDIR)\mod_file_cache.res"
    	-@erase "$(INTDIR)\mod_file_cache_src.idb"
    	-@erase "$(INTDIR)\mod_file_cache_src.pdb"
    	-@erase "$(OUTDIR)\mod_file_cache.exp"
    	-@erase "$(OUTDIR)\mod_file_cache.lib"
    	-@erase "$(OUTDIR)\mod_file_cache.pdb"
    	-@erase "$(OUTDIR)\mod_file_cache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_file_cache_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_file_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_file_cache.so" /d LONG_NAME="file_cache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_file_cache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=/nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_file_cache.pdb" /debug /out:"$(OUTDIR)\mod_file_cache.so" /implib:"$(OUTDIR)\mod_file_cache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_file_cache.obj" \
    	"$(INTDIR)\mod_file_cache.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_file_cache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_file_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_file_cache.so"
       if exist .\Release\mod_file_cache.so.manifest mt.exe -manifest .\Release\mod_file_cache.so.manifest -outputresource:.\Release\mod_file_cache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_file_cache - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_file_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_file_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_file_cache.obj"
    	-@erase "$(INTDIR)\mod_file_cache.res"
    	-@erase "$(INTDIR)\mod_file_cache_src.idb"
    	-@erase "$(INTDIR)\mod_file_cache_src.pdb"
    	-@erase "$(OUTDIR)\mod_file_cache.exp"
    	-@erase "$(OUTDIR)\mod_file_cache.lib"
    	-@erase "$(OUTDIR)\mod_file_cache.pdb"
    	-@erase "$(OUTDIR)\mod_file_cache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_file_cache_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_file_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_file_cache.so" /d LONG_NAME="file_cache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_file_cache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=/nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_file_cache.pdb" /debug /out:"$(OUTDIR)\mod_file_cache.so" /implib:"$(OUTDIR)\mod_file_cache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_file_cache.obj" \
    	"$(INTDIR)\mod_file_cache.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_file_cache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_file_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_file_cache.so"
       if exist .\Debug\mod_file_cache.so.manifest mt.exe -manifest .\Debug\mod_file_cache.so.manifest -outputresource:.\Debug\mod_file_cache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_file_cache.dep")
    !INCLUDE "mod_file_cache.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_file_cache.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_file_cache - Win32 Release" || "$(CFG)" == "mod_file_cache - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_file_cache - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_file_cache - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_file_cache - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_file_cache - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_file_cache - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_file_cache - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_file_cache - Win32 Release"
    
    
    "$(INTDIR)\mod_file_cache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_file_cache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_file_cache.so" /d LONG_NAME="file_cache_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_file_cache - Win32 Debug"
    
    
    "$(INTDIR)\mod_file_cache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_file_cache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_file_cache.so" /d LONG_NAME="file_cache_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_file_cache.c
    
    "$(INTDIR)\mod_file_cache.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache.dep������������������������������������������������������������0000664�0001751�0001751�00000015505�12674411515�017745� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_cache.mak
    
    .\cache_storage.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_atomic.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\cache_common.h"\
    	".\cache_storage.h"\
    	".\cache_util.h"\
    	".\mod_cache.h"\
    	
    
    .\cache_util.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_atomic.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\cache_common.h"\
    	".\cache_util.h"\
    	".\mod_cache.h"\
    	
    
    .\mod_cache.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_atomic.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\cache_common.h"\
    	".\cache_storage.h"\
    	".\cache_util.h"\
    	".\mod_cache.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_dbm.dep������������������������������������������������������0000664�0001751�0001751�00000004170�12674411515�021125� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_socache_dbm.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_socache_dbm.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mpm_common.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\generators\mod_status.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/NWGNUsocachdbm�����������������������������������������������������������0000664�0001751�0001751�00000010452�12561766033�020035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/netware \
    			$(NWOS) \
    			$(STDMOD)/generators \
    			$(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	= socachedbm
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Socache DBM Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= socachedbm
    
    #
    # 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	=
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_socache_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 = \
    	$(PRELUDE) \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	socache_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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_shmcb.dsp����������������������������������������������������0000664�0001751�0001751�00000010776�12520576322�021504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_socache_shmcb" - 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_socache_shmcb - 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_socache_shmcb.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_socache_shmcb.mak" CFG="mod_socache_shmcb - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_shmcb - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_shmcb - 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_socache_shmcb - 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_socache_shmcb_EXPORTS" /FD /c
    # ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_socache_shmcb_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 /fo"Release/mod_socache_shmcb.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_shmcb.so" /d LONG_NAME="socache_shmcb_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_socache_shmcb.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_shmcb.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_socache_shmcb.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_socache_shmcb - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_socache_shmcb_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 /fo"Debug/mod_socache_shmcb.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_shmcb.so" /d LONG_NAME="socache_shmcb_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_socache_shmcb.so" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_shmcb.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_socache_shmcb.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_socache_shmcb - Win32 Release"
    # Name "mod_socache_shmcb - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_socache_shmcb.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ��httpd-2.4.64/modules/cache/NWGNUcach_socache��������������������������������������������������������0000664�0001751�0001751�00000010506�12561746315�020476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(SRC)/include \
    			$(STDMOD)/generators \
    			$(SERVER)/mpm/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	= cach_socache
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Cache Socache Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= cach_socache
    
    #
    # 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	=
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_cache_socache.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 = \
    	$(PRELUDE) \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	@mod_cache.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	cache_socache_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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/cache_storage.h����������������������������������������������������������0000664�0001751�0001751�00000004421�12154266057�020306� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file cache_storage.h
     * @brief Cache Storage Functions
     *
     * @defgroup Cache_storage  Cache Storage Functions
     * @ingroup  MOD_CACHE
     * @{
     */
    
    #ifndef CACHE_STORAGE_H
    #define CACHE_STORAGE_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include "mod_cache.h"
    #include "cache_util.h"
    
    /**
     * cache_storage.c
     */
    int cache_remove_url(cache_request_rec *cache, request_rec *r);
    int cache_create_entity(cache_request_rec *cache, request_rec *r,
                            apr_off_t size, apr_bucket_brigade *in);
    int cache_select(cache_request_rec *cache, request_rec *r);
    
    /**
     * invalidate a specific URL entity in all caches
     *
     * All cached entities for this URL are removed, usually in
     * response to a POST/PUT or DELETE.
     *
     * This function returns OK if at least one entity was found and
     * removed, and DECLINED if no cached entities were removed.
     * @param cache cache_request_rec
     * @param r request_rec
     */
    int cache_invalidate(cache_request_rec *cache, request_rec *r);
    
    apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p,
            const char **key);
    
    /**
     * Merge in cached headers into the response
     * @param h cache_handle_t
     * @param r request_rec
     * @param top headers to be applied
     * @param bottom headers to be overwritten
     * @param revalidation true if revalidation is taking place
     */
    void cache_accept_headers(cache_handle_t *h, request_rec *r, apr_table_t *top,
            apr_table_t *bottom, int revalidation);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* !CACHE_STORAGE_H */
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/NWGNUcach_dsk������������������������������������������������������������0000664�0001751�0001751�00000010460�11667422031�017641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/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	= cach_dsk
    
    #
    # 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	= $(NLM_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	= 65536
    
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_cache_disk.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 = \
    	$(PRELUDE) \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	@mod_cache.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	cache_disk_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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache.c��������������������������������������������������������������0000664�0001751�0001751�00000303441�13701324531�017407� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mod_cache.h"
    
    #include "cache_storage.h"
    #include "cache_util.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_filter_handle;
    static ap_filter_rec_t *cache_save_filter_handle;
    static ap_filter_rec_t *cache_save_subreq_filter_handle;
    static ap_filter_rec_t *cache_out_filter_handle;
    static ap_filter_rec_t *cache_out_subreq_filter_handle;
    static ap_filter_rec_t *cache_remove_url_filter_handle;
    static ap_filter_rec_t *cache_invalidate_filter_handle;
    
    /**
     * Entity headers' names
     */
    static const char *MOD_CACHE_ENTITY_HEADERS[] = {
        "Allow",
        "Content-Encoding",
        "Content-Language",
        "Content-Length",
        "Content-Location",
        "Content-MD5",
        "Content-Range",
        "Content-Type",
        "Last-Modified",
        NULL
    };
    
    /*
     * 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.
     *
     * By default, the cache handler runs in the quick handler, bypassing
     * virtually all server processing and offering the cache its optimal
     * performance. In this mode, the cache bolts onto the front of the
     * server, and behaves as a discrete RFC2616 caching proxy
     * implementation.
     *
     * Under certain circumstances, an admin might want to run the cache as
     * a normal handler instead of a quick handler, allowing the cache to
     * run after the authorisation hooks, or by allowing fine control over
     * the placement of the cache in the filter chain. This option comes at
     * a performance penalty, and should only be used to achieve specific
     * caching goals where the admin understands what they are doing.
     */
    
    static int cache_quick_handler(request_rec *r, int lookup)
    {
        apr_status_t rv;
        const char *auth;
        cache_provider_list *providers;
        cache_request_rec *cache;
        apr_bucket_brigade *out;
        apr_bucket *e;
        ap_filter_t *next;
        ap_filter_rec_t *cache_out_handle;
        cache_server_conf *conf;
    
        conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
                                                          &cache_module);
    
        /* only run if the quick handler is enabled */
        if (!conf->quick) {
            return DECLINED;
        }
    
        /*
         * Which cache module (if any) should handle this request?
         */
        if (!(providers = cache_get_providers(r, conf))) {
            return DECLINED;
        }
    
        /* make space for the per request config */
        cache = apr_pcalloc(r->pool, sizeof(cache_request_rec));
        cache->size = -1;
        cache->out = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        /* save away the possible providers */
        cache->providers = providers;
    
        /*
         * Are we allowed to serve cached info at all?
         */
        if (!ap_cache_check_no_store(cache, r)) {
            return DECLINED;
        }
    
        /* 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;
        }
    
        /* Are we PUT/POST/DELETE? If so, prepare to invalidate the cached entities.
         */
        switch (r->method_number) {
        case M_PUT:
        case M_POST:
        case M_DELETE:
        {
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02461)
                    "PUT/POST/DELETE: Adding CACHE_INVALIDATE filter for %s",
                    r->uri);
    
            /* Add cache_invalidate filter to this request to force a
             * cache entry to be invalidated if the response is
             * ultimately successful (2xx).
             */
            ap_add_output_filter_handle(
                    cache_invalidate_filter_handle, cache, r,
                    r->connection);
    
            return DECLINED;
        }
        case M_GET: {
            break;
        }
        default : {
    
            ap_log_rerror(
                    APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02462) "cache: Method '%s' not cacheable by mod_cache, ignoring: %s", r->method, r->uri);
    
            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(cache, r);
        if (rv != OK) {
            if (rv == DECLINED) {
                if (!lookup) {
    
                    /* try to obtain a cache lock at this point. if we succeed,
                     * we are the first to try and cache this url. if we fail,
                     * it means someone else is already trying to cache this
                     * url, and we should just let the request through to the
                     * backend without any attempt to cache. this stops
                     * duplicated simultaneous attempts to cache an entity.
                     */
                    rv = cache_try_lock(conf, cache, r);
                    if (APR_SUCCESS == rv) {
    
                        /*
                         * Add cache_save filter to cache this request. Choose
                         * the correct filter by checking if we are a subrequest
                         * or not.
                         */
                        if (r->main) {
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                                    r, APLOGNO(00749) "Adding CACHE_SAVE_SUBREQ filter for %s",
                                    r->uri);
                            cache->save_filter = ap_add_output_filter_handle(
                                    cache_save_subreq_filter_handle, cache, r,
                                    r->connection);
                        }
                        else {
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                                    r, APLOGNO(00750) "Adding CACHE_SAVE filter for %s",
                                    r->uri);
                            cache->save_filter = ap_add_output_filter_handle(
                                    cache_save_filter_handle, cache, r,
                                    r->connection);
                        }
    
                        apr_pool_userdata_setn(cache, CACHE_CTX_KEY, NULL, r->pool);
    
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00751)
                                "Adding CACHE_REMOVE_URL filter for %s",
                                r->uri);
    
                        /* Add cache_remove_url filter to this request to remove a
                         * stale cache entry if needed. Also put the current cache
                         * request rec in the filter context, as the request that
                         * is available later during running the filter may be
                         * different due to an internal redirect.
                         */
                        cache->remove_url_filter = ap_add_output_filter_handle(
                                cache_remove_url_filter_handle, cache, r,
                                r->connection);
    
                    }
                    else {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv,
                                r, APLOGNO(00752) "Cache locked for url, not caching "
                                "response: %s", r->uri);
                        /* cache_select() may have added conditional headers */
                        if (cache->stale_headers) {
                            r->headers_in = cache->stale_headers;
                        }
    
                    }
                }
                else {
                    if (cache->stale_headers) {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                                r, APLOGNO(00753) "Restoring request headers for %s",
                                r->uri);
    
                        r->headers_in = cache->stale_headers;
                    }
                }
            }
            else {
                /* error */
                return rv;
            }
            return DECLINED;
        }
    
        /* we've got a cache hit! tell everyone who cares */
        cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_HIT,
                "cache hit");
    
        /* if we are a lookup, we are exiting soon one way or another; Restore
         * the headers. */
        if (lookup) {
            if (cache->stale_headers) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00754)
                        "Restoring request headers.");
                r->headers_in = cache->stale_headers;
            }
        }
    
        rv = ap_meets_conditions(r);
        if (rv != OK) {
            /* If we are a lookup, we have to return DECLINED as we have no
             * way of knowing if we will be able to serve the content.
             */
            if (lookup) {
                return DECLINED;
            }
    
            /* 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);
    
        /*
         * Add cache_out filter to serve this request. Choose
         * the correct filter by checking if we are a subrequest
         * or not.
         */
        if (r->main) {
            cache_out_handle = cache_out_subreq_filter_handle;
        }
        else {
            cache_out_handle = cache_out_filter_handle;
        }
        ap_add_output_filter_handle(cache_out_handle, cache, r, r->connection);
    
        /*
         * Remove all filters that are before the cache_out filter. This ensures
         * that we kick off the filter stack with our cache_out filter being the
         * first in the chain. This make sense because we want to restore things
         * in the same manner as we saved them.
         * There may be filters before our cache_out filter, because
         *
         * 1. We call ap_set_content_type during cache_select. This causes
         *    Content-Type specific filters to be added.
         * 2. We call the insert_filter hook. This causes filters e.g. like
         *    the ones set with SetOutputFilter to be added.
         */
        next = r->output_filters;
        while (next && (next->frec != cache_out_handle)) {
            ap_remove_output_filter(next);
            next = next->next;
        }
    
        /* kick off the filter stack */
        out = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        e = apr_bucket_eos_create(out->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(out, e);
    
        return ap_pass_brigade_fchk(r, out,
                                    "cache_quick_handler(%s): ap_pass_brigade returned",
                                    cache->provider_name);
    }
    
    /**
     * If the two filter handles are present within the filter chain, replace
     * the last instance of the first filter with the last instance of the
     * second filter, and return true. If the second filter is not present at
     * all, the first filter is removed, and false is returned. If neither
     * filter is present, false is returned and this function does nothing.
     * If a stop filter is specified, processing will stop once this filter is
     * reached.
     */
    static int cache_replace_filter(ap_filter_t *next, ap_filter_rec_t *from,
            ap_filter_rec_t *to, ap_filter_rec_t *stop) {
        ap_filter_t *ffrom = NULL, *fto = NULL;
        while (next && next->frec != stop) {
            if (next->frec == from) {
                ffrom = next;
            }
            if (next->frec == to) {
                fto = next;
            }
            next = next->next;
        }
        if (ffrom && fto) {
            ffrom->frec = fto->frec;
            ffrom->ctx = fto->ctx;
            ap_remove_output_filter(fto);
            return 1;
        }
        if (ffrom) {
            ap_remove_output_filter(ffrom);
        }
        return 0;
    }
    
    /**
     * Find the given filter, and return it if found, or NULL otherwise.
     */
    static ap_filter_t *cache_get_filter(ap_filter_t *next, ap_filter_rec_t *rec) {
        while (next) {
            if (next->frec == rec && next->ctx) {
                break;
            }
            next = next->next;
        }
        return next;
    }
    
    /**
     * The cache handler is functionally similar to the cache_quick_hander,
     * however a number of steps that are required by the quick handler are
     * not required here, as the normal httpd processing has already handled
     * these steps.
     */
    static int cache_handler(request_rec *r)
    {
        apr_status_t rv;
        cache_provider_list *providers;
        cache_request_rec *cache;
        apr_bucket_brigade *out;
        apr_bucket *e;
        ap_filter_t *next;
        ap_filter_rec_t *cache_out_handle;
        ap_filter_rec_t *cache_save_handle;
        cache_server_conf *conf;
    
        conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
                                                          &cache_module);
    
        /* only run if the quick handler is disabled */
        if (conf->quick) {
            return DECLINED;
        }
    
        /*
         * Which cache module (if any) should handle this request?
         */
        if (!(providers = cache_get_providers(r, conf))) {
            return DECLINED;
        }
    
        /* make space for the per request config */
        cache = apr_pcalloc(r->pool, sizeof(cache_request_rec));
        cache->size = -1;
        cache->out = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        /* save away the possible providers */
        cache->providers = providers;
    
        /*
         * Are we allowed to serve cached info at all?
         */
        if (!ap_cache_check_no_store(cache, r)) {
            return DECLINED;
        }
    
        /* Are we PUT/POST/DELETE? If so, prepare to invalidate the cached entities.
         */
        switch (r->method_number) {
        case M_PUT:
        case M_POST:
        case M_DELETE:
        {
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02463)
                    "PUT/POST/DELETE: Adding CACHE_INVALIDATE filter for %s",
                    r->uri);
    
            /* Add cache_invalidate filter to this request to force a
             * cache entry to be invalidated if the response is
             * ultimately successful (2xx).
             */
            ap_add_output_filter_handle(
                    cache_invalidate_filter_handle, cache, r,
                    r->connection);
    
            return DECLINED;
        }
        case M_GET: {
            break;
        }
        default : {
    
            ap_log_rerror(
                    APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02464) "cache: Method '%s' not cacheable by mod_cache, ignoring: %s", r->method, r->uri);
    
            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(cache, r);
        if (rv != OK) {
            if (rv == DECLINED) {
    
                /* try to obtain a cache lock at this point. if we succeed,
                 * we are the first to try and cache this url. if we fail,
                 * it means someone else is already trying to cache this
                 * url, and we should just let the request through to the
                 * backend without any attempt to cache. this stops
                 * duplicated simultaneous attempts to cache an entity.
                 */
                rv = cache_try_lock(conf, cache, r);
                if (APR_SUCCESS == rv) {
    
                    /*
                     * Add cache_save filter to cache this request. Choose
                     * the correct filter by checking if we are a subrequest
                     * or not.
                     */
                    if (r->main) {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                                r, APLOGNO(00756) "Adding CACHE_SAVE_SUBREQ filter for %s",
                                r->uri);
                        cache_save_handle = cache_save_subreq_filter_handle;
                    }
                    else {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                                r, APLOGNO(00757) "Adding CACHE_SAVE filter for %s",
                                r->uri);
                        cache_save_handle = cache_save_filter_handle;
                    }
                    ap_add_output_filter_handle(cache_save_handle, cache, r,
                            r->connection);
    
                    /*
                     * Did the user indicate the precise location of the
                     * CACHE_SAVE filter by inserting the CACHE filter as a
                     * marker?
                     *
                     * If so, we get cunning and replace CACHE with the
                     * CACHE_SAVE filter. This has the effect of inserting
                     * the CACHE_SAVE filter at the precise location where
                     * the admin wants to cache the content. All filters that
                     * lie before and after the original location of the CACHE
                     * filter will remain in place.
                     */
                    if (cache_replace_filter(r->output_filters,
                            cache_filter_handle, cache_save_handle,
                            ap_get_input_filter_handle("SUBREQ_CORE"))) {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                                r, APLOGNO(00758) "Replacing CACHE with CACHE_SAVE "
                                "filter for %s", r->uri);
                    }
    
                    /* save away the save filter stack */
                    cache->save_filter = cache_get_filter(r->output_filters,
                            cache_save_filter_handle);
    
                    apr_pool_userdata_setn(cache, CACHE_CTX_KEY, NULL, r->pool);
    
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00759)
                            "Adding CACHE_REMOVE_URL filter for %s",
                            r->uri);
    
                    /* Add cache_remove_url filter to this request to remove a
                     * stale cache entry if needed. Also put the current cache
                     * request rec in the filter context, as the request that
                     * is available later during running the filter may be
                     * different due to an internal redirect.
                     */
                    cache->remove_url_filter
                            = ap_add_output_filter_handle(
                                    cache_remove_url_filter_handle, cache, r,
                                    r->connection);
    
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv,
                            r, APLOGNO(00760) "Cache locked for url, not caching "
                            "response: %s", r->uri);
                }
            }
            else {
                /* error */
                return rv;
            }
            return DECLINED;
        }
    
        /* we've got a cache hit! tell everyone who cares */
        cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_HIT,
                "cache hit");
    
        rv = ap_meets_conditions(r);
        if (rv != OK) {
            return rv;
        }
    
        /* Serve up the content */
    
        /*
         * Add cache_out filter to serve this request. Choose
         * the correct filter by checking if we are a subrequest
         * or not.
         */
        if (r->main) {
            cache_out_handle = cache_out_subreq_filter_handle;
        }
        else {
            cache_out_handle = cache_out_filter_handle;
        }
        ap_add_output_filter_handle(cache_out_handle, cache, r, r->connection);
    
        /*
         * Did the user indicate the precise location of the CACHE_OUT filter by
         * inserting the CACHE filter as a marker?
         *
         * If so, we get cunning and replace CACHE with the CACHE_OUT filters.
         * This has the effect of inserting the CACHE_OUT filter at the precise
         * location where the admin wants to cache the content. All filters that
         * lie *after* the original location of the CACHE filter will remain in
         * place.
         */
        if (cache_replace_filter(r->output_filters, cache_filter_handle,
                cache_out_handle, ap_get_input_filter_handle("SUBREQ_CORE"))) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
                    r, APLOGNO(00761) "Replacing CACHE with CACHE_OUT filter for %s",
                    r->uri);
        }
    
        /*
         * Remove all filters that are before the cache_out filter. This ensures
         * that we kick off the filter stack with our cache_out filter being the
         * first in the chain. This make sense because we want to restore things
         * in the same manner as we saved them.
         * There may be filters before our cache_out filter, because
         *
         * 1. We call ap_set_content_type during cache_select. This causes
         *    Content-Type specific filters to be added.
         * 2. We call the insert_filter hook. This causes filters e.g. like
         *    the ones set with SetOutputFilter to be added.
         */
        next = r->output_filters;
        while (next && (next->frec != cache_out_handle)) {
            ap_remove_output_filter(next);
            next = next->next;
        }
    
        /* kick off the filter stack */
        out = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        e = apr_bucket_eos_create(out->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(out, e);
        return ap_pass_brigade_fchk(r, out, "cache(%s): ap_pass_brigade returned",
                                    cache->provider_name);
    }
    
    /*
     * CACHE_OUT filter
     * ----------------
     *
     * Deliver cached content (headers and body) up the stack.
     */
    static apr_status_t cache_out_filter(ap_filter_t *f, apr_bucket_brigade *in)
    {
        request_rec *r = f->r;
        cache_request_rec *cache = (cache_request_rec *)f->ctx;
    
        if (!cache) {
            /* user likely configured CACHE_OUT manually; they should use mod_cache
             * configuration to do that */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00762)
                    "CACHE/CACHE_OUT filter enabled while caching is disabled, ignoring");
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, in);
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00763)
                "cache: running CACHE_OUT filter");
    
        /* clean out any previous response up to EOS, if any */
        while (!APR_BRIGADE_EMPTY(in)) {
            apr_bucket *e = APR_BRIGADE_FIRST(in);
            if (APR_BUCKET_IS_EOS(e)) {
                apr_bucket_brigade *bb = apr_brigade_create(r->pool,
                        r->connection->bucket_alloc);
    
                /* restore content type of cached response if available */
                /* Needed especially when stale content gets served. */
                const char *ct = apr_table_get(cache->handle->resp_hdrs, "Content-Type");
                if (ct) {
                    ap_set_content_type(r, ct);
                }
    
                /* restore status of cached response */
                r->status = cache->handle->cache_obj->info.status;
    
                /* recall_headers() was called in cache_select() */
                cache->provider->recall_body(cache->handle, r->pool, bb);
                APR_BRIGADE_PREPEND(in, bb);
    
                /* This filter is done once it has served up its content */
                ap_remove_output_filter(f);
    
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00764)
                        "cache: serving %s", r->uri);
                return ap_pass_brigade(f->next, in);
    
            }
            apr_bucket_delete(e);
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * Having jumped through all the hoops and decided to cache the
     * response, call store_body() for each brigade, handling the
     * case where the provider can't swallow the full brigade. In this
     * case, we write the brigade we were passed out downstream, and
     * loop around to try and cache some more until the in brigade is
     * completely empty. As soon as the out brigade contains eos, call
     * commit_entity() to finalise the cached element.
     */
    static int cache_save_store(ap_filter_t *f, apr_bucket_brigade *in,
            cache_server_conf *conf, cache_request_rec *cache)
    {
        int rv = APR_SUCCESS;
        apr_bucket *e;
    
        /* pass the brigade in into the cache provider, which is then
         * expected to move cached buckets to the out brigade, for us
         * to pass up the filter stack. repeat until in is empty, or
         * we fail.
         */
        while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(in)) {
    
            rv = cache->provider->store_body(cache->handle, f->r, in, cache->out);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, f->r, APLOGNO(00765)
                        "cache: Cache provider's store_body failed for URI %s", f->r->uri);
                ap_remove_output_filter(f);
    
                /* give someone else the chance to cache the file */
                cache_remove_lock(conf, cache, f->r, NULL);
    
                /* give up trying to cache, just step out the way */
                APR_BRIGADE_PREPEND(in, cache->out);
                return ap_pass_brigade(f->next, in);
    
            }
    
            /* does the out brigade contain eos? if so, we're done, commit! */
            for (e = APR_BRIGADE_FIRST(cache->out);
                 e != APR_BRIGADE_SENTINEL(cache->out);
                 e = APR_BUCKET_NEXT(e))
            {
                if (APR_BUCKET_IS_EOS(e)) {
                    rv = cache->provider->commit_entity(cache->handle, f->r);
                    break;
                }
            }
    
            /* conditionally remove the lock as soon as we see the eos bucket */
            cache_remove_lock(conf, cache, f->r, cache->out);
    
            if (APR_BRIGADE_EMPTY(cache->out)) {
                if (APR_BRIGADE_EMPTY(in)) {
                    /* cache provider wants more data before passing the brigade
                     * upstream, oblige the provider by leaving to fetch more.
                     */
                    break;
                }
                else {
                    /* oops, no data out, but not all data read in either, be
                     * safe and stand down to prevent a spin.
                     */
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, f->r, APLOGNO(00766)
                            "cache: Cache provider's store_body returned an "
                            "empty brigade, but didn't consume all of the "
                            "input brigade, standing down to prevent a spin");
                    ap_remove_output_filter(f);
    
                    /* give someone else the chance to cache the file */
                    cache_remove_lock(conf, cache, f->r, NULL);
    
                    return ap_pass_brigade(f->next, in);
                }
            }
    
            rv = ap_pass_brigade(f->next, cache->out);
        }
    
        return rv;
    }
    
    /**
     * Sanity check for 304 Not Modified responses, as per RFC2616 Section 10.3.5.
     */
    static int cache_header_cmp(apr_pool_t *pool, apr_table_t *left,
            apr_table_t *right, const char *key)
    {
        const char *h1, *h2;
    
        if ((h1 = cache_table_getm(pool, left, key))
                && (h2 = cache_table_getm(pool, right, key)) && (strcmp(h1, h2))) {
            return 1;
        }
        return 0;
    }
    
    /*
     * 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)
     *
     * After the various failure cases, the cache lock is proactively removed, so
     * that another request is given the opportunity to attempt to cache without
     * waiting for a potentially slow client to acknowledge the failure.
     */
    
    static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
    {
        int rv = !OK;
        request_rec *r = f->r;
        cache_request_rec *cache = (cache_request_rec *)f->ctx;
        cache_server_conf *conf;
        cache_dir_conf *dconf;
        cache_control_t control;
        const char *cc_out, *cl, *pragma;
        const char *exps, *lastmods, *dates, *etag;
        apr_time_t exp, date, lastmod, now;
        apr_off_t size = -1;
        cache_info *info = NULL;
        const char *reason, **eh;
        apr_pool_t *p;
        apr_bucket *e;
        apr_table_t *headers;
        const char *query;
    
        conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
                                                          &cache_module);
    
        /* Setup cache_request_rec */
        if (!cache) {
            /* user likely configured CACHE_SAVE manually; they should really use
             * mod_cache configuration to do that
             */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00767)
                    "CACHE/CACHE_SAVE filter enabled while caching is disabled, ignoring");
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, in);
        }
    
        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 cacheability check and set up the
         * cached file handle?
         */
        if (cache->in_checked) {
            return cache_save_store(f, in, conf, cache);
        }
    
        /*
         * 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.
         */
    
        dconf = ap_get_module_config(r->per_dir_config, &cache_module);
    
        /* RFC2616 13.8 Errors or Incomplete Response Cache Behavior:
         * If a cache receives a 5xx response while attempting to revalidate an
         * entry, it MAY either forward this response to the requesting client,
         * or act as if the server failed to respond. In the latter case, it MAY
         * return a previously received response unless the cached entry
         * includes the "must-revalidate" cache-control directive (see section
         * 14.9).
         *
         * This covers the case where an error was generated behind us, for example
         * by a backend server via mod_proxy.
         */
        if (dconf->stale_on_error && r->status >= HTTP_INTERNAL_SERVER_ERROR) {
    
            ap_remove_output_filter(cache->remove_url_filter);
    
            if (cache->stale_handle
                    && !cache->stale_handle->cache_obj->info.control.must_revalidate
                    && !cache->stale_handle->cache_obj->info.control.proxy_revalidate) {
                const char *warn_head;
    
                /* morph the current save filter into the out filter, and serve from
                 * cache.
                 */
                cache->handle = cache->stale_handle;
                if (r->main) {
                    f->frec = cache_out_subreq_filter_handle;
                }
                else {
                    f->frec = cache_out_filter_handle;
                }
    
                r->headers_out = cache->stale_handle->resp_hdrs;
    
                ap_set_content_type(r, apr_table_get(
                        cache->stale_handle->resp_hdrs, "Content-Type"));
    
                /* add a revalidation warning */
                warn_head = apr_table_get(r->err_headers_out, "Warning");
                if ((warn_head == NULL) || ((warn_head != NULL)
                        && (ap_strstr_c(warn_head, "111") == NULL))) {
                    apr_table_mergen(r->err_headers_out, "Warning",
                            "111 Revalidation failed");
                }
    
                cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_HIT,
                        apr_psprintf(r->pool,
                                "cache hit: %d status; stale content returned",
                                r->status));
    
                /* give someone else the chance to cache the file */
                cache_remove_lock(conf, cache, f->r, NULL);
    
                /* pass brigade to our morphed out filter */
                return ap_pass_brigade(f, in);
            }
        }
    
        query = cache_use_early_url(r) ? r->parsed_uri.query : r->args;
    
        /* 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) {
            exp = apr_date_parse_http(exps);
        }
        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 = cache_table_getm(r->pool, r->err_headers_out, "Cache-Control");
        pragma = cache_table_getm(r->pool, r->err_headers_out, "Pragma");
        headers = r->err_headers_out;
        if (!cc_out && !pragma) {
            cc_out = cache_table_getm(r->pool, r->headers_out, "Cache-Control");
            pragma = cache_table_getm(r->pool, r->headers_out, "Pragma");
            headers = r->headers_out;
        }
    
        /* Have we received a 304 response without any headers at all? Fall back to
         * the original headers in the original cached request.
         */
        if (r->status == HTTP_NOT_MODIFIED && cache->stale_handle) {
            if (!cc_out && !pragma) {
                cc_out = cache_table_getm(r->pool, cache->stale_handle->resp_hdrs,
                        "Cache-Control");
                pragma = cache_table_getm(r->pool, cache->stale_handle->resp_hdrs,
                        "Pragma");
            }
    
            /* 304 does not contain Content-Type and mod_mime regenerates the
             * Content-Type based on the r->filename. This would lead to original
             * Content-Type to be lost (overwritten by whatever mod_mime generates).
             * We preserves the original Content-Type here. */
            ap_set_content_type(r, apr_table_get(
                    cache->stale_handle->resp_hdrs, "Content-Type"));
        }
    
        /* Parse the cache control header */
        memset(&control, 0, sizeof(cache_control_t));
        ap_cache_control(r, &control, cc_out, pragma, headers);
    
        /*
         * 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_PARTIAL_CONTENT
            && 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 allow the caching of 206, but a cache implementation might choose
             * to decline to cache a 206 if it doesn't know how to.
             * We include 304 Not Modified here too as this is the origin server
             * telling us to serve the cached copy.
             */
            if (exps != NULL || cc_out != NULL) {
                /* We are also allowed to cache any response given that it has a
                 * valid Expires or Cache Control header. If we find a either of
                 * those here,  we pass request through the rest of the tests. From
                 * the RFC:
                 *
                 * A response received with any other status code (e.g. status
                 * codes 302 and 307) MUST NOT be returned in a reply to a
                 * subsequent request unless there are cache-control directives or
                 * another header(s) that explicitly allow it. For example, these
                 * include the following: an Expires header (section 14.21); a
                 * "max-age", "s-maxage",  "must-revalidate", "proxy-revalidate",
                 * "public" or "private" cache-control directive (section 14.9).
                 *
                 * FIXME: Wrong if cc_out has just an extension we don't know about 
                 */
            }
            else {
                reason = apr_psprintf(p, "Response status %d", r->status);
            }
        }
    
        if (reason) {
            /* noop */
        }
        else if (!control.s_maxage && !control.max_age && !dconf->store_expired
                 && exps != NULL && exp == APR_DATE_BAD) {
            /* if a broken Expires header is present, don't cache it
             * Unless CC: s-maxage or max-age is present
             */
            reason = apr_pstrcat(p, "Broken expires header: ", exps, NULL);
        }
        else if (!control.s_maxage && !control.max_age
                && !dconf->store_expired && exp != APR_DATE_BAD
                && exp < r->request_time) {
            /* if a Expires header is in the past, don't cache it 
             * Unless CC: s-maxage or max-age is present
             */
            reason = "Expires header already expired; not cacheable";
        }
        else if (!dconf->store_expired && (control.must_revalidate
                || control.proxy_revalidate) && (!control.s_maxage_value
                || (!control.s_maxage && !control.max_age_value)) && lastmods
                == NULL && etag == NULL) {
            /* if we're already stale, but can never revalidate, don't cache it */
            reason
                    = "s-maxage or max-age zero and no Last-Modified or Etag; not cacheable";
        }
        else if (!conf->ignorequerystring && query && exps == NULL
                && !control.max_age && !control.s_maxage) {
            /* if a query string is present but no explicit expiration time,
             * don't cache it (RFC 2616/13.9 & 13.2.1)
             */
            reason = "Query string present but no explicit expiration time";
        }
        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) && (dconf->no_last_mod_ignore == 0) && !control.max_age
                && !control.s_maxage) {
            /* 200 OK response from HTTP/1.0 and up without Last-Modified,
             * Etag, Expires, Cache-Control:max-age, or Cache-Control:s-maxage
             * 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; Expires; Cache-Control:max-age or Cache-Control:s-maxage headers";
        }
        else if (!dconf->store_nostore && control.no_store) {
            /* RFC2616 14.9.2 Cache-Control: no-store response
             * indicating do not cache, or stop now if you are
             * trying to cache it.
             */
            reason = "Cache-Control: no-store present";
        }
        else if (!dconf->store_private && control.private) {
            /* RFC2616 14.9.1 Cache-Control: private response
             * this object is marked for this user's eyes only. Behave
             * as a tunnel.
             */
            reason = "Cache-Control: private present";
        }
        else if (apr_table_get(r->headers_in, "Authorization")
                && !(control.s_maxage || control.must_revalidate
                        || control.proxy_revalidate || control.public)) {
            /* 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 (ap_find_token(NULL, apr_table_get(r->headers_out, "Vary"), "*")) {
            reason = "Vary header contains '*'";
        }
        else if (apr_table_get(r->subprocess_env, "no-cache") != NULL) {
            reason = "environment variable 'no-cache' is set";
        }
        else if (r->no_cache) {
            /* or we've been asked not to cache it above */
            reason = "r->no_cache present";
        }
        else if (cache->stale_handle
                && APR_DATE_BAD
                        != (date = apr_date_parse_http(
                                apr_table_get(r->headers_out, "Date")))
                && date < cache->stale_handle->cache_obj->info.date) {
    
            /**
             * 13.12 Cache Replacement:
             *
             * Note: a new response that has an older Date header value than
             * existing cached responses is not cacheable.
             */
            reason = "updated entity is older than cached entity";
    
            /* while this response is not cacheable, the previous response still is */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02474)
                    "cache: Removing CACHE_REMOVE_URL filter.");
            ap_remove_output_filter(cache->remove_url_filter);
        }
        else if (r->status == HTTP_NOT_MODIFIED && cache->stale_handle) {
            apr_table_t *left = cache->stale_handle->resp_hdrs;
            apr_table_t *right = r->headers_out;
            const char *ehs = NULL;
    
            /* and lastly, contradiction checks for revalidated responses
             * as per RFC2616 Section 10.3.5
             */
            if (cache_header_cmp(r->pool, left, right, "ETag")) {
                ehs = "ETag";
            }
            for (eh = MOD_CACHE_ENTITY_HEADERS; *eh; ++eh) {
                if (cache_header_cmp(r->pool, left, right, *eh)) {
                    ehs = (ehs) ? apr_pstrcat(r->pool, ehs, ", ", *eh, NULL) : *eh;
                }
            }
            if (ehs) {
                reason = apr_pstrcat(r->pool, "contradiction: 304 Not Modified; "
                                     "but ", ehs, " modified", NULL);
            }
        }
    
        /**
         * Enforce RFC2616 Section 10.3.5, just in case. We caught any
         * inconsistencies above.
         *
         * If the conditional GET used a strong cache validator (see section
         * 13.3.3), the response SHOULD NOT include other entity-headers.
         * Otherwise (i.e., the conditional GET used a weak validator), the
         * response MUST NOT include other entity-headers; this prevents
         * inconsistencies between cached entity-bodies and updated headers.
         */
        if (r->status == HTTP_NOT_MODIFIED) {
            for (eh = MOD_CACHE_ENTITY_HEADERS; *eh; ++eh) {
                apr_table_unset(r->headers_out, *eh);
            }
        }
    
        /* Hold the phone. Some servers might allow us to cache a 2xx, but
         * then make their 304 responses non cacheable. RFC2616 says this:
         *
         * If a 304 response indicates an entity not currently cached, then
         * the cache MUST disregard the response and repeat the request
         * without the conditional.
         *
         * A 304 response with contradictory headers is technically a
         * different entity, to be safe, we remove the entity from the cache.
         */
        if (reason && r->status == HTTP_NOT_MODIFIED && cache->stale_handle) {
    
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02473) 
                    "cache: %s responded with an uncacheable 304, " 
                    "retrying the request %s. Reason: %s", 
                    cache->key, r->unparsed_uri, reason);
    
            /* we've got a cache conditional miss! tell anyone who cares */
            cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_MISS,
                    apr_psprintf(r->pool,
                            "conditional cache miss: 304 was uncacheable, entity removed: %s",
                            reason));
    
            /* remove the cached entity immediately, we might cache it again */
            ap_remove_output_filter(cache->remove_url_filter);
            cache_remove_url(cache, r);
    
            /* let someone else attempt to cache */
            cache_remove_lock(conf, cache, r, NULL);
    
            /* remove this filter from the chain */
            ap_remove_output_filter(f);
    
            /* retry without the conditionals */
            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");
    
            /* Currently HTTP_NOT_MODIFIED, and after the redirect, handlers won't think to set status to HTTP_OK */
            r->status = HTTP_OK; 
            ap_internal_redirect(r->unparsed_uri, r);
    
            return APR_SUCCESS;
        }
    
        /* 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 && !ap_parse_strict_length(&size, cl)) {
            reason = "invalid content length";
        }
    
        if (reason) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00768)
                    "cache: %s not cached for request %s. Reason: %s",
                    cache->key, r->unparsed_uri, reason);
    
            /* we've got a cache miss! tell anyone who cares */
            cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_MISS,
                    reason);
    
            /* remove this filter from the chain */
            ap_remove_output_filter(f);
    
            /* remove the lock file unconditionally */
            cache_remove_lock(conf, cache, r, NULL);
    
            /* 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;
    
        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
             */
            int all_buckets_here=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)) {
                    continue;
                }
                if (e->length == (apr_size_t)-1) {
                    break;
                }
                size += e->length;
            }
            if (!all_buckets_here) {
                size = -1;
            }
        }
    
        /* remember content length to check response size against later */
        cache->size = size;
    
        /* It's safe to cache the response.
         *
         * There are two possibilities 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;
                /*
                 * Restore the original request headers as they may be needed
                 * by further output filters like the byterange filter to make
                 * the correct decisions.
                 */
                r->headers_in = cache->stale_headers;
            }
        }
    
        /* no cache handle, create a new entity */
        if (!cache->handle) {
            rv = cache_create_entity(cache, r, size, in);
            info = apr_pcalloc(r->pool, sizeof(cache_info));
            /* We only set info->status upon the initial creation. */
            info->status = r->status;
        }
    
        if (rv != OK) {
            /* we've got a cache miss! tell anyone who cares */
            cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_MISS,
                    "cache miss: cache unwilling to store response");
    
            /* Caching layer declined the opportunity to cache the response */
            ap_remove_output_filter(f);
            cache_remove_lock(conf, cache, r, NULL);
            return ap_pass_brigade(f->next, in);
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00769)
                "cache: Caching url %s for request %s",
                cache->key, r->unparsed_uri);
    
        /* We are actually caching this response. So it does not
         * make sense to remove this entity any more.
         */
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00770)
                "cache: Removing CACHE_REMOVE_URL filter.");
        ap_remove_output_filter(cache->remove_url_filter);
    
        /*
         * 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.
         */
    
        /* store away the previously parsed cache control headers */
        memcpy(&info->control, &control, sizeof(cache_control_t));
    
        /* Read the date. Generate one if one is not supplied */
        dates = apr_table_get(r->err_headers_out, "Date");
        if (dates == NULL) {
            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 */
            /* no date header (or bad header)! */
            info->date = now;
        }
        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;
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0,
                    r, APLOGNO(00771) "cache: Last modified is in the future, "
                    "replacing with now");
        }
    
    
        /* CC has priority over Expires.  */
        if (control.s_maxage || control.max_age) {
            apr_int64_t x;
    
            x = control.s_maxage ? control.s_maxage_value : control.max_age_value;
            x = x * MSEC_ONE_SEC;
    
            if (x < dconf->minex) {
                x = dconf->minex;
            }
            if (x > dconf->maxex) {
                x = dconf->maxex;
            }
            exp = date + x;
        }
    
        /* if no expiry date then
         *   if Cache-Control: s-maxage
         *      expiry date = date + smaxage
         *   if Cache-Control: max-age
         *      expiry date = date + max-age
         *   else if lastmod
         *      expiry date = date + min((date - lastmod) * factor, maxexpire)
         *   else
         *      expire date = date + defaultexpire
         */
    
        if (exp == APR_DATE_BAD) {
            if ((lastmod != APR_DATE_BAD) && (lastmod < date)) {
                /* 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...
                 */
                apr_time_t x = (apr_time_t) ((date - lastmod) * dconf->factor);
    
                if (x < dconf->minex) {
                    x = dconf->minex;
                }
                if (x > dconf->maxex) {
                    x = dconf->maxex;
                }
                exp = date + x;
            }
            else {
                exp = date + dconf->defex;
            }
        }
        info->expire = exp;
    
        /* We found a stale entry which wasn't really stale. */
        if (cache->stale_handle) {
    
            /* 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 (note that store_headers() below already selects
             * the cacheable only headers using ap_cache_cacheable_headers_out(),
             * here we want to keep the original headers in r->headers_out and
             * forward all of them to the client, including non-cacheable ones).
             */
            r->headers_out = cache_merge_headers_out(r);
            apr_table_clear(r->err_headers_out);
    
            /* Merge in our cached headers.  However, keep any updated values. */
            /* take output, overlay on top of cached */
            cache_accept_headers(cache->handle, r, r->headers_out,
                    cache->handle->resp_hdrs, 1);
        }
    
        /* Write away header information to cache. It is possible that we are
         * trying to update headers for an entity which has already been cached.
         *
         * This may fail, due to an unwritable cache area. E.g. filesystem full,
         * permissions problems or a read-only (re)mount. This must be handled
         * later.
         */
        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 (cache->stale_handle) {
            apr_bucket_brigade *bb;
            apr_bucket *bkt;
            int status;
    
            /* Load in the saved status and clear the status line. */
            r->status = info->status;
            r->status_line = NULL;
    
            /* We're just saving response headers, so we are done. Commit
             * the response at this point, unless there was a previous error.
             */
            if (rv == APR_SUCCESS) {
                rv = cache->provider->commit_entity(cache->handle, r);
            }
    
            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;
    
                /* Strip the entity headers merged from the cached headers before
                 * updating the entry (see cache_accept_headers() above).
                 */
                for (eh = MOD_CACHE_ENTITY_HEADERS; *eh; ++eh) {
                    apr_table_unset(r->headers_out, *eh);
                }
    
                bkt = apr_bucket_flush_create(bb->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, bkt);
            }
            else {
                cache->provider->recall_body(cache->handle, r->pool, bb);
    
                bkt = apr_bucket_eos_create(bb->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, bkt);
            }
    
            cache->block_response = 1;
    
            /* Before returning we need to handle the possible case of an
             * unwritable cache. Rather than leaving the entity in the cache
             * and having it constantly re-validated, now that we have recalled
             * the body it is safe to try and remove the url from the cache.
             */
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(00772)
                        "cache: updating headers with store_headers failed. "
                        "Removing cached url.");
    
                rv = cache->provider->remove_url(cache->stale_handle, r);
                if (rv != OK) {
                    /* Probably a mod_cache_disk cache area has been (re)mounted
                     * read-only, or that there is a permissions problem.
                     */
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(00773)
                            "cache: attempt to remove url from cache unsuccessful.");
                }
    
                /* we've got a cache conditional hit! tell anyone who cares */
                cache_run_cache_status(cache->handle, r, r->headers_out,
                        AP_CACHE_REVALIDATE,
                        "conditional cache hit: entity refresh failed");
    
            }
            else {
    
                /* we've got a cache conditional hit! tell anyone who cares */
                cache_run_cache_status(cache->handle, r, r->headers_out,
                        AP_CACHE_REVALIDATE,
                        "conditional cache hit: entity refreshed");
    
            }
    
            /* let someone else attempt to cache */
            cache_remove_lock(conf, cache, r, NULL);
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02971)
                        "cache: serving %s (revalidated)", r->uri);
    
            return ap_pass_brigade(f->next, bb);
        }
    
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(00774)
                    "cache: store_headers failed");
    
            /* we've got a cache miss! tell anyone who cares */
            cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_MISS,
                    "cache miss: store_headers failed");
    
            ap_remove_output_filter(f);
            cache_remove_lock(conf, cache, r, NULL);
            return ap_pass_brigade(f->next, in);
        }
    
        /* we've got a cache miss! tell anyone who cares */
        cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_MISS,
                "cache miss: attempting entity save");
    
        return cache_save_store(f, in, conf, cache);
    }
    
    /*
     * CACHE_REMOVE_URL filter
     * -----------------------
     *
     * This filter gets added in the quick handler every time the CACHE_SAVE filter
     * gets inserted. Its purpose is to remove a confirmed stale cache entry from
     * the cache.
     *
     * CACHE_REMOVE_URL has to be a protocol filter to ensure that is run even if
     * the response is a canned error message, which removes the content filters
     * and thus the CACHE_SAVE filter from the chain.
     *
     * CACHE_REMOVE_URL expects cache request rec within its context because the
     * request this filter runs on can be different from the one whose cache entry
     * should be removed, due to internal redirects.
     *
     * Note that CACHE_SAVE_URL (as a content-set filter, hence run before the
     * protocol filters) will remove this filter if it decides to cache the file.
     * Therefore, if this filter is left in, it must mean we need to toss any
     * existing files.
     */
    static apr_status_t cache_remove_url_filter(ap_filter_t *f,
                                                apr_bucket_brigade *in)
    {
        request_rec *r = f->r;
        cache_request_rec *cache;
    
        /* Setup cache_request_rec */
        cache = (cache_request_rec *) f->ctx;
    
        if (!cache) {
            /* user likely configured CACHE_REMOVE_URL manually; they should really
             * use mod_cache configuration to do that. So:
             * 1. Remove ourselves
             * 2. Do nothing and bail out
             */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00775)
                    "cache: CACHE_REMOVE_URL enabled unexpectedly");
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, in);
        }
    
        /* Now remove this cache entry from the cache */
        cache_remove_url(cache, r);
    
        /* remove ourselves */
        ap_remove_output_filter(f);
        return ap_pass_brigade(f->next, in);
    }
    
    /*
     * CACHE_INVALIDATE filter
     * -----------------------
     *
     * This filter gets added in the quick handler should a PUT, POST or DELETE
     * method be detected. If the response is successful, we must invalidate any
     * cached entity as per RFC2616 section 13.10.
     *
     * CACHE_INVALIDATE has to be a protocol filter to ensure that is run even if
     * the response is a canned error message, which removes the content filters
     * from the chain.
     *
     * CACHE_INVALIDATE expects cache request rec within its context because the
     * request this filter runs on can be different from the one whose cache entry
     * should be removed, due to internal redirects.
     */
    static apr_status_t cache_invalidate_filter(ap_filter_t *f,
                                                apr_bucket_brigade *in)
    {
        request_rec *r = f->r;
        cache_request_rec *cache;
    
        /* Setup cache_request_rec */
        cache = (cache_request_rec *) f->ctx;
    
        if (!cache) {
            /* user likely configured CACHE_INVALIDATE manually; they should really
             * use mod_cache configuration to do that. So:
             * 1. Remove ourselves
             * 2. Do nothing and bail out
             */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02465)
                    "cache: CACHE_INVALIDATE enabled unexpectedly: %s", r->uri);
        }
        else {
    
            if (r->status > 299) {
    
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02466)
                        "cache: response status to '%s' method is %d (>299), not invalidating cached entity: %s", r->method, r->status, r->uri);
    
            }
            else {
    
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(02467)
                        "cache: Invalidating all cached entities in response to '%s' request for %s",
                        r->method, r->uri);
    
                cache_invalidate(cache, r);
    
                /* we've got a cache invalidate! tell everyone who cares */
                cache_run_cache_status(cache->handle, r, r->headers_out,
                        AP_CACHE_INVALIDATE, apr_psprintf(r->pool,
                                "cache invalidated by %s", r->method));
    
            }
    
        }
    
        /* remove ourselves */
        ap_remove_output_filter(f);
        return ap_pass_brigade(f->next, in);
    }
    
    /*
     * CACHE filter
     * ------------
     *
     * This filter can be optionally inserted into the filter chain by the admin as
     * a marker representing the precise location within the filter chain where
     * caching is to be performed.
     *
     * When the filter chain is set up in the non-quick version of the URL handler,
     * the CACHE filter is replaced by the CACHE_OUT or CACHE_SAVE filter,
     * effectively inserting the caching filters at the point indicated by the
     * admin. The CACHE filter is then removed.
     *
     * This allows caching to be performed before the content is passed to the
     * INCLUDES filter, or to a filter that might perform transformations unique
     * to the specific request and that would otherwise be non-cacheable.
     */
    static apr_status_t cache_filter(ap_filter_t *f, apr_bucket_brigade *in)
    {
    
        cache_server_conf
                *conf =
                        (cache_server_conf *) ap_get_module_config(f->r->server->module_config,
                                &cache_module);
    
        /* was the quick handler enabled */
        if (conf->quick) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r, APLOGNO(00776)
                    "cache: CACHE filter was added in quick handler mode and "
                    "will be ignored: %s", f->r->unparsed_uri);
        }
        /* otherwise we may have been bypassed, nothing to see here */
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, APLOGNO(00777)
                    "cache: CACHE filter was added twice, or was added where "
                    "the cache has been bypassed and will be ignored: %s",
                    f->r->unparsed_uri);
        }
    
        /* we are just a marker, so let's just remove ourselves */
        ap_remove_output_filter(f);
        return ap_pass_brigade(f->next, in);
    }
    
    /**
     * If configured, add the status of the caching attempt to the subprocess
     * environment, and if configured, to headers in the response.
     *
     * The status is saved below the broad category of the status (hit, miss,
     * revalidate), as well as a single cache-status key. This can be used for
     * conditional logging.
     *
     * The status is optionally saved to an X-Cache header, and the detail of
     * why a particular cache entry was cached (or not cached) is optionally
     * saved to an X-Cache-Detail header. This extra detail is useful for
     * service developers who may need to know whether their Cache-Control headers
     * are working correctly.
     */
    static int cache_status(cache_handle_t *h, request_rec *r,
            apr_table_t *headers, ap_cache_status_e status, const char *reason)
    {
        cache_server_conf
                *conf =
                        (cache_server_conf *) ap_get_module_config(r->server->module_config,
                                &cache_module);
    
        cache_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &cache_module);
        int x_cache = 0, x_cache_detail = 0;
    
        switch (status) {
        case AP_CACHE_HIT: {
            apr_table_setn(r->subprocess_env, AP_CACHE_HIT_ENV, reason);
            break;
        }
        case AP_CACHE_REVALIDATE: {
            apr_table_setn(r->subprocess_env, AP_CACHE_REVALIDATE_ENV, reason);
            break;
        }
        case AP_CACHE_MISS: {
            apr_table_setn(r->subprocess_env, AP_CACHE_MISS_ENV, reason);
            break;
        }
        case AP_CACHE_INVALIDATE: {
            apr_table_setn(r->subprocess_env, AP_CACHE_INVALIDATE_ENV, reason);
            break;
        }
        }
    
        apr_table_setn(r->subprocess_env, AP_CACHE_STATUS_ENV, reason);
    
        if (dconf && dconf->x_cache_set) {
            x_cache = dconf->x_cache;
        }
        else {
            x_cache = conf->x_cache;
        }
        if (x_cache) {
            apr_table_setn(headers, "X-Cache", apr_psprintf(r->pool, "%s from %s",
                    status == AP_CACHE_HIT ? "HIT"
                            : status == AP_CACHE_REVALIDATE ? "REVALIDATE" : status
                                    == AP_CACHE_INVALIDATE ? "INVALIDATE" : "MISS",
                    r->server->server_hostname));
        }
    
        if (dconf && dconf->x_cache_detail_set) {
            x_cache_detail = dconf->x_cache_detail;
        }
        else {
            x_cache_detail = conf->x_cache_detail;
        }
        if (x_cache_detail) {
            apr_table_setn(headers, "X-Cache-Detail", apr_psprintf(r->pool,
                    "\"%s\" from %s", reason, r->server->server_hostname));
        }
    
        return OK;
    }
    
    /**
     * If an error has occurred, but we have a stale cached entry, restore the
     * filter stack from the save filter onwards. The canned error message will
     * be discarded in the process, and replaced with the cached response.
     */
    static void cache_insert_error_filter(request_rec *r)
    {
        void *dummy;
        cache_dir_conf *dconf;
    
        /* ignore everything except for 5xx errors */
        if (r->status < HTTP_INTERNAL_SERVER_ERROR) {
            return;
        }
    
        dconf = ap_get_module_config(r->per_dir_config, &cache_module);
    
        if (!dconf->stale_on_error) {
            return;
        }
    
        /* RFC2616 13.8 Errors or Incomplete Response Cache Behavior:
         * If a cache receives a 5xx response while attempting to revalidate an
         * entry, it MAY either forward this response to the requesting client,
         * or act as if the server failed to respond. In the latter case, it MAY
         * return a previously received response unless the cached entry
         * includes the "must-revalidate" cache-control directive (see section
         * 14.9).
         *
         * This covers the case where the error was generated by our server via
         * ap_die().
         */
        apr_pool_userdata_get(&dummy, CACHE_CTX_KEY, r->pool);
        if (dummy) {
            cache_request_rec *cache = (cache_request_rec *) dummy;
    
            ap_remove_output_filter(cache->remove_url_filter);
    
            if (cache->stale_handle && cache->save_filter
                    && !cache->stale_handle->cache_obj->info.control.must_revalidate
                    && !cache->stale_handle->cache_obj->info.control.proxy_revalidate
                    && !cache->stale_handle->cache_obj->info.control.s_maxage) {
                const char *warn_head;
                cache_server_conf
                        *conf =
                                (cache_server_conf *) ap_get_module_config(r->server->module_config,
                                        &cache_module);
    
                /* morph the current save filter into the out filter, and serve from
                 * cache.
                 */
                cache->handle = cache->stale_handle;
                if (r->main) {
                    cache->save_filter->frec = cache_out_subreq_filter_handle;
                }
                else {
                    cache->save_filter->frec = cache_out_filter_handle;
                }
    
                r->output_filters = cache->save_filter;
    
                r->err_headers_out = cache->stale_handle->resp_hdrs;
    
                /* add a revalidation warning */
                warn_head = apr_table_get(r->err_headers_out, "Warning");
                if ((warn_head == NULL) || ((warn_head != NULL)
                        && (ap_strstr_c(warn_head, "111") == NULL))) {
                    apr_table_mergen(r->err_headers_out, "Warning",
                            "111 Revalidation failed");
                }
    
                cache_run_cache_status(
                        cache->handle,
                        r,
                        r->err_headers_out,
                        AP_CACHE_HIT,
                        apr_psprintf(
                                r->pool,
                                "cache hit: %d status; stale content returned",
                                r->status));
    
                /* give someone else the chance to cache the file */
                cache_remove_lock(conf, cache, r, NULL);
    
            }
        }
    
        return;
    }
    
    /* -------------------------------------------------------------- */
    /* Setup configurable data */
    
    static void *create_dir_config(apr_pool_t *p, char *dummy)
    {
        cache_dir_conf *dconf = apr_pcalloc(p, sizeof(cache_dir_conf));
    
        dconf->no_last_mod_ignore = 0;
        dconf->store_expired = 0;
        dconf->store_private = 0;
        dconf->store_nostore = 0;
    
        /* maximum time to cache a document */
        dconf->maxex = DEFAULT_CACHE_MAXEXPIRE;
        dconf->minex = DEFAULT_CACHE_MINEXPIRE;
        /* default time to cache a document */
        dconf->defex = DEFAULT_CACHE_EXPIRE;
    
        /* factor used to estimate Expires date from LastModified date */
        dconf->factor = DEFAULT_CACHE_LMFACTOR;
    
        dconf->x_cache = DEFAULT_X_CACHE;
        dconf->x_cache_detail = DEFAULT_X_CACHE_DETAIL;
    
        dconf->stale_on_error = DEFAULT_CACHE_STALE_ON_ERROR;
    
        /* array of providers for this URL space */
        dconf->cacheenable = apr_array_make(p, 10, sizeof(struct cache_enable));
    
        return dconf;
    }
    
    static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv) {
        cache_dir_conf *new = (cache_dir_conf *) apr_pcalloc(p, sizeof(cache_dir_conf));
        cache_dir_conf *add = (cache_dir_conf *) addv;
        cache_dir_conf *base = (cache_dir_conf *) basev;
    
        new->no_last_mod_ignore = (add->no_last_mod_ignore_set == 0) ? base->no_last_mod_ignore : add->no_last_mod_ignore;
        new->no_last_mod_ignore_set = add->no_last_mod_ignore_set || base->no_last_mod_ignore_set;
    
        new->store_expired = (add->store_expired_set == 0) ? base->store_expired : add->store_expired;
        new->store_expired_set = add->store_expired_set || base->store_expired_set;
        new->store_private = (add->store_private_set == 0) ? base->store_private : add->store_private;
        new->store_private_set = add->store_private_set || base->store_private_set;
        new->store_nostore = (add->store_nostore_set == 0) ? base->store_nostore : add->store_nostore;
        new->store_nostore_set = add->store_nostore_set || base->store_nostore_set;
    
        /* maximum time to cache a document */
        new->maxex = (add->maxex_set == 0) ? base->maxex : add->maxex;
        new->maxex_set = add->maxex_set || base->maxex_set;
        new->minex = (add->minex_set == 0) ? base->minex : add->minex;
        new->minex_set = add->minex_set || base->minex_set;
    
        /* default time to cache a document */
        new->defex = (add->defex_set == 0) ? base->defex : add->defex;
        new->defex_set = add->defex_set || base->defex_set;
    
        /* factor used to estimate Expires date from LastModified date */
        new->factor = (add->factor_set == 0) ? base->factor : add->factor;
        new->factor_set = add->factor_set || base->factor_set;
    
        new->x_cache = (add->x_cache_set == 0) ? base->x_cache : add->x_cache;
        new->x_cache_set = add->x_cache_set || base->x_cache_set;
        new->x_cache_detail = (add->x_cache_detail_set == 0) ? base->x_cache_detail
                : add->x_cache_detail;
        new->x_cache_detail_set = add->x_cache_detail_set
                || base->x_cache_detail_set;
    
        new->stale_on_error = (add->stale_on_error_set == 0) ? base->stale_on_error
                : add->stale_on_error;
        new->stale_on_error_set = add->stale_on_error_set
                || base->stale_on_error_set;
    
        new->cacheenable = add->enable_set ? apr_array_append(p, base->cacheenable,
                add->cacheenable) : base->cacheenable;
        new->enable_set = add->enable_set || base->enable_set;
        new->disable = (add->disable_set == 0) ? base->disable : add->disable;
        new->disable_set = add->disable_set || base->disable_set;
    
        return new;
    }
    
    static void * create_cache_config(apr_pool_t *p, server_rec *s)
    {
        const char *tmppath = NULL;
        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));
        ps->ignorecachecontrol = 0;
        ps->ignorecachecontrol_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;
        /* flag indicating that query-string should be ignored when caching */
        ps->ignorequerystring = 0;
        ps->ignorequerystring_set = 0;
        /* by default, run in the quick handler */
        ps->quick = 1;
        ps->quick_set = 0;
        /* array of identifiers that should not be used for key calculation */
        ps->ignore_session_id = apr_array_make(p, 10, sizeof(char *));
        ps->ignore_session_id_set = CACHE_IGNORE_SESSION_ID_UNSET;
        ps->lock = 0; /* thundering herd lock defaults to off */
        ps->lock_set = 0;
        apr_temp_dir_get(&tmppath, p);
        if (tmppath) {
            ps->lockpath = apr_pstrcat(p, tmppath, DEFAULT_CACHE_LOCKPATH, NULL);
        }
        ps->lockmaxage = apr_time_from_sec(DEFAULT_CACHE_MAXAGE);
        ps->x_cache = DEFAULT_X_CACHE;
        ps->x_cache_detail = DEFAULT_X_CACHE_DETAIL;
        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);
    
        ps->ignorecachecontrol  =
            (overrides->ignorecachecontrol_set == 0)
            ? base->ignorecachecontrol
            : overrides->ignorecachecontrol;
        ps->ignore_headers =
            (overrides->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET)
            ? base->ignore_headers
            : overrides->ignore_headers;
        ps->ignorequerystring =
            (overrides->ignorequerystring_set == 0)
            ? base->ignorequerystring
            : overrides->ignorequerystring;
        ps->ignore_session_id =
            (overrides->ignore_session_id_set == CACHE_IGNORE_SESSION_ID_UNSET)
            ? base->ignore_session_id
            : overrides->ignore_session_id;
        ps->lock =
            (overrides->lock_set == 0)
            ? base->lock
            : overrides->lock;
        ps->lockpath =
            (overrides->lockpath_set == 0)
            ? base->lockpath
            : overrides->lockpath;
        ps->lockmaxage =
            (overrides->lockmaxage_set == 0)
            ? base->lockmaxage
            : overrides->lockmaxage;
        ps->quick =
            (overrides->quick_set == 0)
            ? base->quick
            : overrides->quick;
        ps->x_cache =
            (overrides->x_cache_set == 0)
            ? base->x_cache
            : overrides->x_cache;
        ps->x_cache_detail =
            (overrides->x_cache_detail_set == 0)
            ? base->x_cache_detail
            : overrides->x_cache_detail;
        ps->base_uri =
            (overrides->base_uri_set == 0)
            ? base->base_uri
            : overrides->base_uri;
        return ps;
    }
    
    static const char *set_cache_quick_handler(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->quick = flag;
        conf->quick_set = 1;
        return NULL;
    
    }
    
    static const char *set_cache_ignore_no_last_mod(cmd_parms *parms, void *dummy,
                                                    int flag)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->no_last_mod_ignore = flag;
        dconf->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_expired(cmd_parms *parms, void *dummy,
                                               int flag)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->store_expired = flag;
        dconf->store_expired_set = 1;
        return NULL;
    }
    
    static const char *set_cache_store_private(cmd_parms *parms, void *dummy,
                                               int flag)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->store_private = flag;
        dconf->store_private_set = 1;
        return NULL;
    }
    
    static const char *set_cache_store_nostore(cmd_parms *parms, void *dummy,
                                               int flag)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->store_nostore = flag;
        dconf->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 (!strcasecmp(header, "None")) {
            /* 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_ignore_session_id(cmd_parms *parms, void *dummy,
                                             const char *identifier)
    {
        cache_server_conf *conf;
        char **new;
    
        conf =
            (cache_server_conf *)ap_get_module_config(parms->server->module_config,
                                                      &cache_module);
        if (!strcasecmp(identifier, "None")) {
            /* if identifier None is listed clear array */
            conf->ignore_session_id->nelts = 0;
        }
        else {
            if ((conf->ignore_session_id_set == CACHE_IGNORE_SESSION_ID_UNSET) ||
                (conf->ignore_session_id->nelts)) {
                /*
                 * Only add identifier if no "None" has been found in identifier
                 * list so far.
                 */
                new = (char **)apr_array_push(conf->ignore_session_id);
                (*new) = (char *)identifier;
            }
        }
        conf->ignore_session_id_set = CACHE_IGNORE_SESSION_ID_SET;
        return NULL;
    }
    
    static const char *add_cache_enable(cmd_parms *parms, void *dummy,
                                        const char *type,
                                        const char *url)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
        cache_server_conf *conf;
        struct cache_enable *new;
    
        const char *err = ap_check_cmd_context(parms,
                                               NOT_IN_DIRECTORY|NOT_IN_LIMIT|NOT_IN_FILES);
        if (err != NULL) {
            return err;
        }
    
        if (*type == '/') {
            return apr_psprintf(parms->pool,
              "provider (%s) starts with a '/'.  Are url and provider switched?",
              type);
        }
    
        if (!url) {
            url = parms->path;
        }
        if (!url) {
            return apr_psprintf(parms->pool,
              "CacheEnable provider (%s) is missing an URL.", type);
        }
        if (parms->path && strncmp(parms->path, url, strlen(parms->path))) {
            return "When in a Location, CacheEnable must specify a path or an URL below "
            "that location.";
        }
    
        conf =
            (cache_server_conf *)ap_get_module_config(parms->server->module_config,
                                                      &cache_module);
    
        if (parms->path) {
            new = apr_array_push(dconf->cacheenable);
            dconf->enable_set = 1;
        }
        else {
            new = apr_array_push(conf->cacheenable);
        }
    
        new->type = type;
        if (apr_uri_parse(parms->pool, url, &(new->url))) {
            return NULL;
        }
        if (new->url.path) {
            new->pathlen = strlen(new->url.path);
        } else {
            new->pathlen = 1;
            new->url.path = "/";
        }
        return NULL;
    }
    
    static const char *add_cache_disable(cmd_parms *parms, void *dummy,
                                         const char *url)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
        cache_server_conf *conf;
        struct cache_disable *new;
    
        const char *err = ap_check_cmd_context(parms,
                                               NOT_IN_DIRECTORY|NOT_IN_LIMIT|NOT_IN_FILES);
        if (err != NULL) {
            return err;
        }
    
        conf =
            (cache_server_conf *)ap_get_module_config(parms->server->module_config,
                                                      &cache_module);
    
        if (parms->path) {
            if (!strcasecmp(url, "on")) {
                dconf->disable = 1;
                dconf->disable_set = 1;
                return NULL;
            }
            else {
                return "CacheDisable must be followed by the word 'on' when in a Location.";
            }
        }
    
        if (!url || (url[0] != '/' && !ap_strchr_c(url, ':'))) {
            return "CacheDisable must specify a path or an URL.";
        }
    
        new = apr_array_push(conf->cachedisable);
        if (apr_uri_parse(parms->pool, url, &(new->url))) {
            return NULL;
        }
        if (new->url.path) {
            new->pathlen = strlen(new->url.path);
        } else {
            new->pathlen = 1;
            new->url.path = "/";
        }
        return NULL;
    }
    
    static const char *set_cache_maxex(cmd_parms *parms, void *dummy,
                                       const char *arg)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->maxex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC);
        dconf->maxex_set = 1;
        return NULL;
    }
    
    static const char *set_cache_minex(cmd_parms *parms, void *dummy,
                                       const char *arg)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->minex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC);
        dconf->minex_set = 1;
        return NULL;
    }
    
    static const char *set_cache_defex(cmd_parms *parms, void *dummy,
                                       const char *arg)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->defex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC);
        dconf->defex_set = 1;
        return NULL;
    }
    
    static const char *set_cache_factor(cmd_parms *parms, void *dummy,
                                        const char *arg)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
        double val;
    
        if (sscanf(arg, "%lg", &val) != 1) {
            return "CacheLastModifiedFactor value must be a float";
        }
        dconf->factor = val;
        dconf->factor_set = 1;
        return NULL;
    }
    
    static const char *set_cache_ignore_querystring(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->ignorequerystring = flag;
        conf->ignorequerystring_set = 1;
        return NULL;
    }
    
    static const char *set_cache_lock(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->lock = flag;
        conf->lock_set = 1;
        return NULL;
    }
    
    static const char *set_cache_lock_path(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->lockpath = ap_server_root_relative(parms->pool, arg);
        if (!conf->lockpath) {
            return apr_pstrcat(parms->pool, "Invalid CacheLockPath path ",
                               arg, NULL);
        }
        conf->lockpath_set = 1;
        return NULL;
    }
    
    static const char *set_cache_lock_maxage(cmd_parms *parms, void *dummy,
                                        const char *arg)
    {
        cache_server_conf *conf;
        apr_int64_t seconds;
    
        conf =
            (cache_server_conf *)ap_get_module_config(parms->server->module_config,
                                                      &cache_module);
        seconds = apr_atoi64(arg);
        if (seconds <= 0) {
            return "CacheLockMaxAge value must be a non-zero positive integer";
        }
        conf->lockmaxage = apr_time_from_sec(seconds);
        conf->lockmaxage_set = 1;
        return NULL;
    }
    
    static const char *set_cache_x_cache(cmd_parms *parms, void *dummy, int flag)
    {
    
        if (parms->path) {
            cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
            dconf->x_cache = flag;
            dconf->x_cache_set = 1;
    
        }
        else {
            cache_server_conf *conf =
                (cache_server_conf *)ap_get_module_config(parms->server->module_config,
                                                          &cache_module);
    
            conf->x_cache = flag;
            conf->x_cache_set = 1;
    
        }
    
        return NULL;
    }
    
    static const char *set_cache_x_cache_detail(cmd_parms *parms, void *dummy, int flag)
    {
    
        if (parms->path) {
            cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
            dconf->x_cache_detail = flag;
            dconf->x_cache_detail_set = 1;
    
        }
        else {
            cache_server_conf *conf =
                (cache_server_conf *)ap_get_module_config(parms->server->module_config,
                                                          &cache_module);
    
            conf->x_cache_detail = flag;
            conf->x_cache_detail_set = 1;
    
        }
    
        return NULL;
    }
    
    static const char *set_cache_key_base_url(cmd_parms *parms, void *dummy,
            const char *arg)
    {
        cache_server_conf *conf;
        apr_status_t rv;
    
        conf =
            (cache_server_conf *)ap_get_module_config(parms->server->module_config,
                                                      &cache_module);
        conf->base_uri = apr_pcalloc(parms->pool, sizeof(apr_uri_t));
        rv = apr_uri_parse(parms->pool, arg, conf->base_uri);
        if (rv != APR_SUCCESS) {
            return apr_psprintf(parms->pool, "Could not parse '%s' as an URL.", arg);
        }
        else if (!conf->base_uri->scheme && !conf->base_uri->hostname &&
                !conf->base_uri->port_str) {
            return apr_psprintf(parms->pool, "URL '%s' must contain at least one of a scheme, a hostname or a port.", arg);
        }
        conf->base_uri_set = 1;
        return NULL;
    }
    
    static const char *set_cache_stale_on_error(cmd_parms *parms, void *dummy,
            int flag)
    {
        cache_dir_conf *dconf = (cache_dir_conf *)dummy;
    
        dconf->stale_on_error = flag;
        dconf->stale_on_error_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
         * implementations (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_TAKE12("CacheEnable", add_cache_enable, NULL, RSRC_CONF|ACCESS_CONF,
                       "A cache type and partial URL prefix below which "
                       "caching is enabled"),
        AP_INIT_TAKE1("CacheDisable", add_cache_disable, NULL, RSRC_CONF|ACCESS_CONF,
                      "A partial URL prefix below which caching is disabled"),
        AP_INIT_TAKE1("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF|ACCESS_CONF,
                      "The maximum time in seconds to cache a document"),
        AP_INIT_TAKE1("CacheMinExpire", set_cache_minex, NULL, RSRC_CONF|ACCESS_CONF,
                      "The minimum time in seconds to cache a document"),
        AP_INIT_TAKE1("CacheDefaultExpire", set_cache_defex, NULL, RSRC_CONF|ACCESS_CONF,
                      "The default time in seconds to cache a document"),
        AP_INIT_FLAG("CacheQuickHandler", set_cache_quick_handler, NULL,
                     RSRC_CONF,
                     "Run the cache in the quick handler, default on"),
        AP_INIT_FLAG("CacheIgnoreNoLastMod", set_cache_ignore_no_last_mod, NULL,
                     RSRC_CONF|ACCESS_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("CacheStoreExpired", set_cache_store_expired,
                     NULL, RSRC_CONF|ACCESS_CONF,
                     "Ignore expiration dates when populating cache, resulting in "
                     "an If-Modified-Since request to the backend on retrieval"),
        AP_INIT_FLAG("CacheStorePrivate", set_cache_store_private,
                     NULL, RSRC_CONF|ACCESS_CONF,
                     "Ignore 'Cache-Control: private' and store private content"),
        AP_INIT_FLAG("CacheStoreNoStore", set_cache_store_nostore,
                     NULL, RSRC_CONF|ACCESS_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_FLAG("CacheIgnoreQueryString", set_cache_ignore_querystring,
                     NULL, RSRC_CONF,
                     "Ignore query-string when caching"),
        AP_INIT_ITERATE("CacheIgnoreURLSessionIdentifiers", add_ignore_session_id,
                        NULL, RSRC_CONF, "A space separated list of session "
                        "identifiers that should be ignored for creating the key "
                        "of the cached entity."),
        AP_INIT_TAKE1("CacheLastModifiedFactor", set_cache_factor, NULL, RSRC_CONF|ACCESS_CONF,
                      "The factor used to estimate Expires date from "
                      "LastModified date"),
        AP_INIT_FLAG("CacheLock", set_cache_lock,
                     NULL, RSRC_CONF,
                     "Enable or disable the thundering herd lock."),
        AP_INIT_TAKE1("CacheLockPath", set_cache_lock_path, NULL, RSRC_CONF,
                      "The thundering herd lock path. Defaults to the '"
                      DEFAULT_CACHE_LOCKPATH "' directory in the system "
                      "temp directory."),
        AP_INIT_TAKE1("CacheLockMaxAge", set_cache_lock_maxage, NULL, RSRC_CONF,
                      "Maximum age of any thundering herd lock."),
        AP_INIT_FLAG("CacheHeader", set_cache_x_cache, NULL, RSRC_CONF | ACCESS_CONF,
                     "Add a X-Cache header to responses. Default is off."),
        AP_INIT_FLAG("CacheDetailHeader", set_cache_x_cache_detail, NULL,
                     RSRC_CONF | ACCESS_CONF,
                     "Add a X-Cache-Detail header to responses. Default is off."),
        AP_INIT_TAKE1("CacheKeyBaseURL", set_cache_key_base_url, NULL, RSRC_CONF,
                      "Override the base URL of reverse proxied cache keys."),
        AP_INIT_FLAG("CacheStaleOnError", set_cache_stale_on_error,
                     NULL, RSRC_CONF|ACCESS_CONF,
                     "Serve stale content on 5xx errors if present. Defaults to on."),
        {NULL}
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        /* cache initializer */
        /* cache quick handler */
        ap_hook_quick_handler(cache_quick_handler, NULL, NULL, APR_HOOK_FIRST);
        /* cache handler */
        ap_hook_handler(cache_handler, NULL, NULL, APR_HOOK_REALLY_FIRST);
        /* cache status */
        cache_hook_cache_status(cache_status, NULL, NULL, APR_HOOK_MIDDLE);
        /* cache error handler */
        ap_hook_insert_error_filter(cache_insert_error_filter, NULL, NULL, APR_HOOK_MIDDLE);
        /* 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.
         *
         * Depending on the type of request (subrequest / main request) they
         * need to be run before AP_FTYPE_CONTENT_SET / after AP_FTYPE_CONTENT_SET
         * filters. Thus create two filter handles for each type:
         * cache_save_filter_handle / cache_out_filter_handle to be used by
         * main requests and
         * cache_save_subreq_filter_handle / cache_out_subreq_filter_handle
         * to be run by subrequest
         */
        /*
         * CACHE is placed into the filter chain at an admin specified location,
         * and when the cache_handler is run, the CACHE filter is swapped with
         * the CACHE_OUT filter, or CACHE_SAVE filter as appropriate. This has
         * the effect of offering optional fine control of where the cache is
         * inserted into the filter chain.
         */
        cache_filter_handle =
            ap_register_output_filter("CACHE",
                                      cache_filter,
                                      NULL,
                                      AP_FTYPE_RESOURCE);
        /*
         * CACHE_SAVE must go into the filter chain after a possible DEFLATE
         * filter to ensure that the compressed content is stored.
         * Incrementing filter type by 1 ensures this happens.
         */
        cache_save_filter_handle =
            ap_register_output_filter("CACHE_SAVE",
                                      cache_save_filter,
                                      NULL,
                                      AP_FTYPE_CONTENT_SET+1);
        /*
         * CACHE_SAVE_SUBREQ must go into the filter chain before SUBREQ_CORE to
         * handle subrequsts. Decrementing filter type by 1 ensures this
         * happens.
         */
        cache_save_subreq_filter_handle =
            ap_register_output_filter("CACHE_SAVE_SUBREQ",
                                      cache_save_filter,
                                      NULL,
                                      AP_FTYPE_CONTENT_SET-1);
        /*
         * CACHE_OUT must go into the filter chain after a possible DEFLATE
         * filter to ensure that already compressed cache objects do not
         * get compressed again. Incrementing 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);
        /*
         * CACHE_OUT_SUBREQ must go into the filter chain before SUBREQ_CORE to
         * handle subrequsts. Decrementing filter type by 1 ensures this
         * happens.
         */
        cache_out_subreq_filter_handle =
            ap_register_output_filter("CACHE_OUT_SUBREQ",
                                      cache_out_filter,
                                      NULL,
                                      AP_FTYPE_CONTENT_SET-1);
        /* CACHE_REMOVE_URL has to be a protocol filter to ensure that is
         * run even if the response is a canned error message, which
         * removes the content filters.
         */
        cache_remove_url_filter_handle =
            ap_register_output_filter("CACHE_REMOVE_URL",
                                      cache_remove_url_filter,
                                      NULL,
                                      AP_FTYPE_PROTOCOL);
        cache_invalidate_filter_handle =
            ap_register_output_filter("CACHE_INVALIDATE",
                                      cache_invalidate_filter,
                                      NULL,
                                      AP_FTYPE_PROTOCOL);
        ap_hook_post_config(cache_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
    }
    
    AP_DECLARE_MODULE(cache) =
    {
        STANDARD20_MODULE_STUFF,
        create_dir_config,      /* create per-directory config structure */
        merge_dir_config,       /* 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
    };
    
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(cache_status)
    )
    
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(cache, CACHE, int, cache_status,
            (cache_handle_t *h, request_rec *r,
                    apr_table_t *headers, ap_cache_status_e status,
                    const char *reason), (h, r, headers, status, reason),
            OK, DECLINED)
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_redis.mak����������������������������������������������������0000664�0001751�0001751�00000024521�13446306656�021502� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_socache_redis.dsp
    !IF "$(CFG)" == ""
    CFG=mod_socache_redis - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_socache_redis - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_socache_redis - Win32 Release" && "$(CFG)" != "mod_socache_redis - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_socache_redis.mak" CFG="mod_socache_redis - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_redis - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_redis - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_redis - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_redis.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_socache_redis.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_redis.obj"
    	-@erase "$(INTDIR)\mod_socache_redis.res"
    	-@erase "$(INTDIR)\mod_socache_redis_src.idb"
    	-@erase "$(INTDIR)\mod_socache_redis_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_redis.exp"
    	-@erase "$(OUTDIR)\mod_socache_redis.lib"
    	-@erase "$(OUTDIR)\mod_socache_redis.pdb"
    	-@erase "$(OUTDIR)\mod_socache_redis.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_redis_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_redis.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_redis.so" /d LONG_NAME="socache_redis_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_redis.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_redis.pdb" /debug /out:"$(OUTDIR)\mod_socache_redis.so" /implib:"$(OUTDIR)\mod_socache_redis.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_redis.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_redis.obj" \
    	"$(INTDIR)\mod_socache_redis.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_redis.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_socache_redis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_redis.so"
       if exist .\Release\mod_socache_redis.so.manifest mt.exe -manifest .\Release\mod_socache_redis.so.manifest -outputresource:.\Release\mod_socache_redis.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_socache_redis - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_redis.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_socache_redis.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_redis.obj"
    	-@erase "$(INTDIR)\mod_socache_redis.res"
    	-@erase "$(INTDIR)\mod_socache_redis_src.idb"
    	-@erase "$(INTDIR)\mod_socache_redis_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_redis.exp"
    	-@erase "$(OUTDIR)\mod_socache_redis.lib"
    	-@erase "$(OUTDIR)\mod_socache_redis.pdb"
    	-@erase "$(OUTDIR)\mod_socache_redis.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_redis_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_redis.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_redis.so" /d LONG_NAME="socache_redis_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_redis.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_redis.pdb" /debug /out:"$(OUTDIR)\mod_socache_redis.so" /implib:"$(OUTDIR)\mod_socache_redis.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_redis.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_redis.obj" \
    	"$(INTDIR)\mod_socache_redis.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_redis.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_socache_redis.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_redis.so"
       if exist .\Debug\mod_socache_redis.so.manifest mt.exe -manifest .\Debug\mod_socache_redis.so.manifest -outputresource:.\Debug\mod_socache_redis.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_socache_redis.dep")
    !INCLUDE "mod_socache_redis.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_socache_redis.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_socache_redis - Win32 Release" || "$(CFG)" == "mod_socache_redis - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_socache_redis - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_redis - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_redis - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_redis - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_redis - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_redis - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_socache_redis - Win32 Release"
    
    
    "$(INTDIR)\mod_socache_redis.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_redis.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_socache_redis.so" /d LONG_NAME="socache_redis_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_socache_redis - Win32 Debug"
    
    
    "$(INTDIR)\mod_socache_redis.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_redis.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_socache_redis.so" /d LONG_NAME="socache_redis_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_socache_redis.c
    
    "$(INTDIR)\mod_socache_redis.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/cache_util.h�������������������������������������������������������������0000664�0001751�0001751�00000027166�13065257310�017624� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file cache_util.h
     * @brief Cache Storage Functions
     *
     * @defgroup Cache_util  Cache Utility Functions
     * @ingroup  MOD_CACHE
     * @{
     */
    
    #ifndef CACHE_UTIL_H
    #define CACHE_UTIL_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include "mod_cache.h"
    
    #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_uri.h"
    
    #ifdef HAVE_NETDB_H
    #include <netdb.h>
    #endif
    
    #ifdef HAVE_SYS_SOCKET_H
    #include <sys/socket.h>
    #endif
    
    #ifdef HAVE_NETINET_IN_H
    #include <netinet/in.h>
    #endif
    
    #ifdef HAVE_ARPA_INET_H
    #include <arpa/inet.h>
    #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_MINEXPIRE 0
    #define DEFAULT_CACHE_EXPIRE    MSEC_ONE_HR
    #define DEFAULT_CACHE_LMFACTOR  (0.1)
    #define DEFAULT_CACHE_MAXAGE    5
    #define DEFAULT_X_CACHE         0
    #define DEFAULT_X_CACHE_DETAIL  0
    #define DEFAULT_CACHE_STALE_ON_ERROR 1
    #define DEFAULT_CACHE_LOCKPATH "/mod_cache-lock"
    #define CACHE_LOCKNAME_KEY "mod_cache-lockname"
    #define CACHE_LOCKFILE_KEY "mod_cache-lockfile"
    #define CACHE_CTX_KEY "mod_cache-ctx"
    #define CACHE_SEPARATOR ", \t"
    
    /**
     * cache_util.c
     */
    
    struct cache_enable {
        apr_uri_t url;
        const char *type;
        apr_size_t pathlen;
    };
    
    struct cache_disable {
        apr_uri_t url;
        apr_size_t pathlen;
    };
    
    /* 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 */
        /** store the headers that should not be stored in the cache */
        apr_array_header_t *ignore_headers;
        /** store the identifiers that should not be used for key calculation */
        apr_array_header_t *ignore_session_id;
        const char *lockpath;
        apr_time_t lockmaxage;
        apr_uri_t *base_uri;
        /** ignore client's requests for uncached responses */
        unsigned int ignorecachecontrol:1;
        /** ignore query-string when caching */
        unsigned int ignorequerystring:1;
        /** run within the quick handler */
        unsigned int quick:1;
        /* thundering herd lock */
        unsigned int lock:1;
        unsigned int x_cache:1;
        unsigned int x_cache_detail:1;
        /* flag if CacheIgnoreHeader has been set */
        #define CACHE_IGNORE_HEADERS_SET   1
        #define CACHE_IGNORE_HEADERS_UNSET 0
        unsigned int ignore_headers_set:1;
        /* flag if CacheIgnoreURLSessionIdentifiers has been set */
        #define CACHE_IGNORE_SESSION_ID_SET   1
        #define CACHE_IGNORE_SESSION_ID_UNSET 0
        unsigned int ignore_session_id_set:1;
        unsigned int base_uri_set:1;
        unsigned int ignorecachecontrol_set:1;
        unsigned int ignorequerystring_set:1;
        unsigned int quick_set:1;
        unsigned int lock_set:1;
        unsigned int lockpath_set:1;
        unsigned int lockmaxage_set:1;
        unsigned int x_cache_set:1;
        unsigned int x_cache_detail_set:1;
    } cache_server_conf;
    
    typedef struct {
        /* Minimum time to keep cached files in msecs */
        apr_time_t minex;
        /* Maximum time to keep cached files in msecs */
        apr_time_t maxex;
        /* default time to keep cached file in msecs */
        apr_time_t defex;
        /* factor for estimating expires date */
        double factor;
        /* cache enabled for this location */
        apr_array_header_t *cacheenable;
        /* cache disabled for this location */
        unsigned int disable:1;
        /* set X-Cache headers */
        unsigned int x_cache:1;
        unsigned int x_cache_detail:1;
        /* serve stale on error */
        unsigned int stale_on_error:1;
        /** ignore the last-modified header when deciding to cache this request */
        unsigned int no_last_mod_ignore:1;
        /** ignore expiration date from server */
        unsigned int store_expired:1;
        /** ignore Cache-Control: private header from server */
        unsigned int store_private:1;
        /** ignore Cache-Control: no-store header from client or server */
        unsigned int store_nostore:1;
        unsigned int minex_set:1;
        unsigned int maxex_set:1;
        unsigned int defex_set:1;
        unsigned int factor_set:1;
        unsigned int x_cache_set:1;
        unsigned int x_cache_detail_set:1;
        unsigned int stale_on_error_set:1;
        unsigned int no_last_mod_ignore_set:1;
        unsigned int store_expired_set:1;
        unsigned int store_private_set:1;
        unsigned int store_nostore_set:1;
        unsigned int enable_set:1;
        unsigned int disable_set:1;
    } cache_dir_conf;
    
    /* 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 entity 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 */
        ap_filter_t *save_filter;           /* Enable us to restore the filter on error */
        ap_filter_t *remove_url_filter;     /* Enable us to remove the filter */
        const char *key;                    /* The cache key created for this
                                             * request
                                             */
        apr_off_t size;                     /* the content length from the headers, or -1 */
        apr_bucket_brigade *out;            /* brigade to reuse for upstream responses */
        cache_control_t control_in;         /* cache control incoming */
    } cache_request_rec;
    
    /**
     * Check the whether the request allows a cached object to be served as per RFC2616
     * section 14.9.4 (Cache Revalidation and Reload Controls)
     * @param cache cache_request_rec
     * @param r request_rec
     * @return 0 ==> cache object may not be served, 1 ==> cache object may be served
     */
    int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r);
    
    /**
     * Check the whether the request allows a cached object to be stored as per RFC2616
     * section 14.9.2 (What May be Stored by Caches)
     * @param cache cache_request_rec
     * @param r request_rec
     * @return 0 ==> cache object may not be served, 1 ==> cache object may be served
     */
    int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r);
    
    /**
     * Check the freshness of the cache object per RFC2616 section 13.2 (Expiration Model)
     * @param h cache_handle_t
     * @param cache cache_request_rec
     * @param r request_rec
     * @return 0 ==> cache object is stale, 1 ==> cache object is fresh
     */
    int cache_check_freshness(cache_handle_t *h, cache_request_rec *cache,
            request_rec *r);
    
    /**
     * Try obtain a cache wide lock on the given cache key.
     *
     * If we return APR_SUCCESS, we obtained the lock, and we are clear to
     * proceed to the backend. If we return APR_EEXISTS, then the lock is
     * already locked, someone else has gone to refresh the backend data
     * already, so we must return stale data with a warning in the mean
     * time. If we return anything else, then something has gone pear
     * shaped, and we allow the request through to the backend regardless.
     *
     * This lock is created from the request pool, meaning that should
     * something go wrong and the lock isn't deleted on return of the
     * request headers from the backend for whatever reason, at worst the
     * lock will be cleaned up when the request is dies or finishes.
     *
     * If something goes truly bananas and the lock isn't deleted when the
     * request dies, the lock will be trashed when its max-age is reached,
     * or when a request arrives containing a Cache-Control: no-cache. At
     * no point is it possible for this lock to permanently deny access to
     * the backend.
     */
    apr_status_t cache_try_lock(cache_server_conf *conf, cache_request_rec *cache,
            request_rec *r);
    
    /**
     * Remove the cache lock, if present.
     *
     * First, try to close the file handle, whose delete-on-close should
     * kill the file. Otherwise, just delete the file by name.
     *
     * If no lock name has yet been calculated, do the calculation of the
     * lock name first before trying to delete the file.
     *
     * If an optional bucket brigade is passed, the lock will only be
     * removed if the bucket brigade contains an EOS bucket.
     */
    apr_status_t cache_remove_lock(cache_server_conf *conf,
            cache_request_rec *cache, request_rec *r, apr_bucket_brigade *bb);
    
    cache_provider_list *cache_get_providers(request_rec *r,
                                             cache_server_conf *conf);
    
    /**
     * Get a value from a table, where the table may contain multiple
     * values for a given key.
     *
     * When the table contains a single value, that value is returned
     * unchanged.
     *
     * When the table contains two or more values for a key, all values
     * for the key are returned, separated by commas.
     */
    const char *cache_table_getm(apr_pool_t *p, const apr_table_t *t,
            const char *key);
    
    /**
     * String tokenizer that ignores separator characters within quoted strings
     * and escaped characters, as per RFC2616 section 2.2.
     */
    char *cache_strqtok(char *str, const char *sep, char **last);
    
    /**
     * Merge err_headers_out into headers_out and add request's Content-Type and
     * Content-Encoding if available.
     */
    apr_table_t *cache_merge_headers_out(request_rec *r);
    
    /**
     * Return whether to use request's path/query from early stage (r->parsed_uri)
     * or the current/rewritable ones (r->uri/r->args).
     */
    int cache_use_early_url(request_rec *r);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* !CACHE_UTIL_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache.mak������������������������������������������������������������0000664�0001751�0001751�00000024147�12701473373�017750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_cache.dsp
    !IF "$(CFG)" == ""
    CFG=mod_cache - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_cache - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_cache - Win32 Release" && "$(CFG)" != "mod_cache - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\cache_storage.obj"
    	-@erase "$(INTDIR)\cache_util.obj"
    	-@erase "$(INTDIR)\mod_cache.obj"
    	-@erase "$(INTDIR)\mod_cache.res"
    	-@erase "$(INTDIR)\mod_cache_src.idb"
    	-@erase "$(INTDIR)\mod_cache_src.pdb"
    	-@erase "$(OUTDIR)\mod_cache.exp"
    	-@erase "$(OUTDIR)\mod_cache.lib"
    	-@erase "$(OUTDIR)\mod_cache.pdb"
    	-@erase "$(OUTDIR)\mod_cache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cache_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cache.so" /d LONG_NAME="cache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cache.pdb" /debug /out:"$(OUTDIR)\mod_cache.so" /implib:"$(OUTDIR)\mod_cache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\cache_storage.obj" \
    	"$(INTDIR)\cache_util.obj" \
    	"$(INTDIR)\mod_cache.obj" \
    	"$(INTDIR)\mod_cache.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_cache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cache.so"
       if exist .\Release\mod_cache.so.manifest mt.exe -manifest .\Release\mod_cache.so.manifest -outputresource:.\Release\mod_cache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_cache - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_cache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\cache_storage.obj"
    	-@erase "$(INTDIR)\cache_util.obj"
    	-@erase "$(INTDIR)\mod_cache.obj"
    	-@erase "$(INTDIR)\mod_cache.res"
    	-@erase "$(INTDIR)\mod_cache_src.idb"
    	-@erase "$(INTDIR)\mod_cache_src.pdb"
    	-@erase "$(OUTDIR)\mod_cache.exp"
    	-@erase "$(OUTDIR)\mod_cache.lib"
    	-@erase "$(OUTDIR)\mod_cache.pdb"
    	-@erase "$(OUTDIR)\mod_cache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "CACHE_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_cache_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_cache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cache.so" /d LONG_NAME="cache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_cache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_cache.pdb" /debug /out:"$(OUTDIR)\mod_cache.so" /implib:"$(OUTDIR)\mod_cache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so 
    LINK32_OBJS= \
    	"$(INTDIR)\cache_storage.obj" \
    	"$(INTDIR)\cache_util.obj" \
    	"$(INTDIR)\mod_cache.obj" \
    	"$(INTDIR)\mod_cache.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_cache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_cache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_cache.so"
       if exist .\Debug\mod_cache.so.manifest mt.exe -manifest .\Debug\mod_cache.so.manifest -outputresource:.\Debug\mod_cache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_cache.dep")
    !INCLUDE "mod_cache.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_cache.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_cache - Win32 Release" || "$(CFG)" == "mod_cache - Win32 Debug"
    SOURCE=.\cache_storage.c
    
    "$(INTDIR)\cache_storage.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\cache_util.c
    
    "$(INTDIR)\cache_util.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\mod_cache.c
    
    "$(INTDIR)\mod_cache.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_cache - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_cache - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_cache - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_cache - Win32 Release"
    
    
    "$(INTDIR)\mod_cache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_cache.so" /d LONG_NAME="cache_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_cache - Win32 Debug"
    
    
    "$(INTDIR)\mod_cache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_cache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_cache.so" /d LONG_NAME="cache_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_dbm.mak������������������������������������������������������0000664�0001751�0001751�00000024241�12701473373�021127� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_socache_dbm.dsp
    !IF "$(CFG)" == ""
    CFG=mod_socache_dbm - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_socache_dbm - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_socache_dbm - Win32 Release" && "$(CFG)" != "mod_socache_dbm - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_socache_dbm.mak" CFG="mod_socache_dbm - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_socache_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_socache_dbm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_dbm - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_socache_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_dbm.obj"
    	-@erase "$(INTDIR)\mod_socache_dbm.res"
    	-@erase "$(INTDIR)\mod_socache_dbm_src.idb"
    	-@erase "$(INTDIR)\mod_socache_dbm_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dbm.exp"
    	-@erase "$(OUTDIR)\mod_socache_dbm.lib"
    	-@erase "$(OUTDIR)\mod_socache_dbm.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dbm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_dbm_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_socache_dbm.so" /d LONG_NAME="socache_dbm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_dbm.pdb" /debug /out:"$(OUTDIR)\mod_socache_dbm.so" /implib:"$(OUTDIR)\mod_socache_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dbm.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_dbm.obj" \
    	"$(INTDIR)\mod_socache_dbm.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_socache_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_dbm.so"
       if exist .\Release\mod_socache_dbm.so.manifest mt.exe -manifest .\Release\mod_socache_dbm.so.manifest -outputresource:.\Release\mod_socache_dbm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dbm - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_socache_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_socache_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_socache_dbm.obj"
    	-@erase "$(INTDIR)\mod_socache_dbm.res"
    	-@erase "$(INTDIR)\mod_socache_dbm_src.idb"
    	-@erase "$(INTDIR)\mod_socache_dbm_src.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dbm.exp"
    	-@erase "$(OUTDIR)\mod_socache_dbm.lib"
    	-@erase "$(OUTDIR)\mod_socache_dbm.pdb"
    	-@erase "$(OUTDIR)\mod_socache_dbm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_socache_dbm_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_socache_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_socache_dbm.so" /d LONG_NAME="socache_dbm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_socache_dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_socache_dbm.pdb" /debug /out:"$(OUTDIR)\mod_socache_dbm.so" /implib:"$(OUTDIR)\mod_socache_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_socache_dbm.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_socache_dbm.obj" \
    	"$(INTDIR)\mod_socache_dbm.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_socache_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_socache_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_socache_dbm.so"
       if exist .\Debug\mod_socache_dbm.so.manifest mt.exe -manifest .\Debug\mod_socache_dbm.so.manifest -outputresource:.\Debug\mod_socache_dbm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_socache_dbm.dep")
    !INCLUDE "mod_socache_dbm.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_socache_dbm.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_socache_dbm - Win32 Release" || "$(CFG)" == "mod_socache_dbm - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_socache_dbm - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dbm - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_dbm - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dbm - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cache"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cache"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_socache_dbm - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ELSEIF  "$(CFG)" == "mod_socache_dbm - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cache"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cache"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_socache_dbm - Win32 Release"
    
    
    "$(INTDIR)\mod_socache_dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_socache_dbm.so" /d LONG_NAME="socache_dbm_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_socache_dbm - Win32 Debug"
    
    
    "$(INTDIR)\mod_socache_dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_socache_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_socache_dbm.so" /d LONG_NAME="socache_dbm_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_socache_dbm.c
    
    "$(INTDIR)\mod_socache_dbm.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_disk.dep�������������������������������������������������������0000664�0001751�0001751�00000004025�12674411515�020752� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_cache_disk.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_cache_disk.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_date.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\cache_common.h"\
    	".\cache_disk_common.h"\
    	".\mod_cache.h"\
    	".\mod_cache_disk.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_socache_dc.dep�������������������������������������������������������0000664�0001751�0001751�00000003722�12674411515�020753� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_socache_dc.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_socache_dc.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������httpd-2.4.64/modules/cache/NWGNUsocachshmcb���������������������������������������������������������0000664�0001751�0001751�00000010461�12561766033�020367� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/netware \
    			$(NWOS) \
    			$(STDMOD)/generators \
    			$(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	= socacheshmcb
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Socache DC Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= socacheshmcb
    
    #
    # 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	=
    
    #
    # 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 this is 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		=
    
    #
    # Declare all target files (you must add your files here)
    #
    
    #
    # 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_socache_shmcb.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 = \
    	$(PRELUDE) \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	socache_shmcb_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_socache.dsp����������������������������������������������������0000664�0001751�0001751�00000011003�12441706176�021437� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_cache_socache" - 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_socache - 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_socache.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_socache.mak" CFG="mod_cache_socache - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_cache_socache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_cache_socache - 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_socache - 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" /I "../generators" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fd"Release\mod_cache_socache_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 /fo"Release/mod_cache_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_cache_socache.so" /d LONG_NAME="cache_socache_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_cache_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_socache.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_cache_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_cache_socache - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fd"Debug\mod_cache_socache_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 /fo"Debug/mod_cache_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_cache_socache.so" /d LONG_NAME="cache_socache_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_cache_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache_socache.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_cache_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_cache_socache - Win32 Release"
    # Name "mod_cache_socache - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_cache.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_cache_socache.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/NWGNUmakefile������������������������������������������������������������0000664�0001751�0001751�00000010132�12137751745�017665� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/cach_dsk.nlm \
    	$(OBJDIR)/cach_socache.nlm \
    	$(OBJDIR)/socachdbm.nlm \
    	$(OBJDIR)/socachmem.nlm \
    	$(OBJDIR)/socachshmcb.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/cache_socache_common.h���������������������������������������������������0000664�0001751�0001751�00000003537�12146465263�021627� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file cache_socache_common.h
     * @brief Common Shared Object Cache vars/structs
     *
     * @defgroup Cache_cache  Cache Functions
     * @ingroup  MOD_SOCACHE_CACHE
     * @{
     */
    
    #ifndef CACHE_SOCACHE_COMMON_H
    #define CACHE_SOCACHE_COMMON_H
    
    #include "apr_time.h"
    
    #include "cache_common.h"
    
    #define CACHE_SOCACHE_VARY_FORMAT_VERSION 1
    #define CACHE_SOCACHE_DISK_FORMAT_VERSION 2
    
    typedef struct {
        /* Indicates the format of the header struct stored on-disk. */
        apr_uint32_t 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;
        /* Does this cached request have a body? */
        unsigned int header_only:1;
        /* The parsed cache control header */
        cache_control_t control;
    } cache_socache_info_t;
    
    #endif /* CACHE_SOCACHE_COMMON_H */
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/mod_cache_disk.c���������������������������������������������������������0000664�0001751�0001751�00000151235�14002600524�020415� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_lib.h"
    #include "apr_file_io.h"
    #include "apr_strings.h"
    #include "mod_cache.h"
    #include "mod_cache_disk.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_core.h"
    #include "ap_provider.h"
    #include "util_filter.h"
    #include "util_script.h"
    #include "util_charset.h"
    
    /*
     * mod_cache_disk: Disk Based HTTP 1.1 Cache.
     *
     * Flow to Find the .data file:
     *   Incoming client requests URI /foo/bar/baz
     *   Generate <hash> off of /foo/bar/baz
     *   Open <hash>.header
     *   Read in <hash>.header file (may contain Format #1 or Format #2)
     *   If format #1 (Contains a list of Vary Headers):
     *      Use each header name (from .header) with our request values (headers_in) to
     *      regenerate <hash> using HeaderName+HeaderValue+.../foo/bar/baz
     *      re-read in <hash>.header (must be format #2)
     *   read in <hash>.data
     *
     * Format #1:
     *   apr_uint32_t format;
     *   apr_time_t expire;
     *   apr_array_t vary_headers (delimited by CRLF)
     *
     * Format #2:
     *   disk_cache_info_t (first sizeof(apr_uint32_t) bytes is the format)
     *   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
     */
    
    module AP_MODULE_DECLARE_DATA cache_disk_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 *in,
                                   apr_bucket_brigade *out);
    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 apr_status_t read_array(request_rec *r, apr_array_header_t* arr,
                                   apr_file_t *file);
    
    /*
     * Local static functions
     */
    
    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);
        }
    
        if (dobj->prefix) {
            return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX "/",
                               dobj->hashfile, CACHE_HEADER_SUFFIX, NULL);
         }
         else {
            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);
        }
    
        if (dobj->prefix) {
            return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX "/",
                               dobj->hashfile, CACHE_DATA_SUFFIX, NULL);
         }
         else {
            return apr_pstrcat(p, conf->cache_root, "/", dobj->hashfile,
                               CACHE_DATA_SUFFIX, NULL);
         }
    }
    
    static apr_status_t mkdir_structure(disk_cache_conf *conf, const char *file, apr_pool_t *pool)
    {
        apr_status_t rv;
        char *p;
    
        for (p = (char*)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)) {
                return rv;
            }
            *p = '/';
            ++p;
        }
        return APR_SUCCESS;
    }
    
    /* htcacheclean may remove directories underneath us.
     * So, we'll try renaming three times at a cost of 0.002 seconds.
     */
    static apr_status_t safe_file_rename(disk_cache_conf *conf,
                                         const char *src, const char *dest,
                                         apr_pool_t *pool)
    {
        apr_status_t rv;
    
        rv = apr_file_rename(src, dest, pool);
    
        if (rv != APR_SUCCESS) {
            int i;
    
            for (i = 0; i < 2 && rv != APR_SUCCESS; i++) {
                /* 1000 micro-seconds aka 0.001 seconds. */
                apr_sleep(1000);
    
                rv = mkdir_structure(conf, dest, pool);
                if (rv != APR_SUCCESS)
                    continue;
    
                rv = apr_file_rename(src, dest, pool);
            }
        }
    
        return rv;
    }
    
    static apr_status_t file_cache_el_final(disk_cache_conf *conf, disk_cache_file_t *file,
                                            request_rec *r)
    {
        apr_status_t rv = APR_SUCCESS;
    
        /* This assumes that the tempfiles are on the same file system
         * as the cache_root. If not, then we need a file copy/move
         * rather than a rename.
         */
    
        /* move the file over */
        if (file->tempfd) {
    
            rv = safe_file_rename(conf, file->tempfile, file->file, file->pool);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00699)
                        "rename tempfile to file failed:"
                        " %s -> %s", file->tempfile, file->file);
                apr_file_remove(file->tempfile, file->pool);
            }
    
            file->tempfd = NULL;
        }
    
        return rv;
    }
    
    static apr_status_t file_cache_temp_cleanup(void *dummy)
    {
        disk_cache_file_t *file = (disk_cache_file_t *)dummy;
    
        /* clean up the temporary file */
        if (file->tempfd) {
            apr_file_remove(file->tempfile, file->pool);
            file->tempfd = NULL;
        }
        file->tempfile = NULL;
        file->pool = NULL;
    
        return APR_SUCCESS;
    }
    
    static apr_status_t file_cache_create(disk_cache_conf *conf, disk_cache_file_t *file,
                                          apr_pool_t *pool)
    {
        file->pool = pool;
        file->tempfile = apr_pstrcat(pool, conf->cache_root, AP_TEMPFILE, NULL);
    
        apr_pool_cleanup_register(pool, file, file_cache_temp_cleanup, apr_pool_cleanup_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;
        apr_size_t len;
    
        /* read the data from the cache file */
        len = sizeof(disk_cache_info_t);
        rv = apr_file_read_full(fd, &dobj->disk_info, len, &len);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        /* Store it away so we can get it later. */
        info->status = dobj->disk_info.status;
        info->date = dobj->disk_info.date;
        info->expire = dobj->disk_info.expire;
        info->request_time = dobj->disk_info.request_time;
        info->response_time = dobj->disk_info.response_time;
    
        memcpy(&info->control, &dobj->disk_info.control, sizeof(cache_control_t));
    
        /* Note that we could optimize this by conditionally doing the palloc
         * depending upon the size. */
        urlbuff = apr_palloc(r->pool, dobj->disk_info.name_len + 1);
        len = dobj->disk_info.name_len;
        rv = apr_file_read_full(fd, urlbuff, len, &len);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        urlbuff[dobj->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;
    }
    
    static const char* regen_key(apr_pool_t *p, apr_table_t *headers,
                                 apr_array_header_t *varray, const char *oldkey)
    {
        struct iovec *iov;
        int i, k;
        int nvec;
        const char *header;
        const char **elts;
    
        nvec = (varray->nelts * 2) + 1;
        iov = apr_palloc(p, sizeof(struct iovec) * nvec);
        elts = (const char **) varray->elts;
    
        /* TODO:
         *    - Handle multiple-value headers better. (sort them?)
         *    - Handle Case in-sensitive Values better.
         *        This isn't the end of the world, since it just lowers the cache
         *        hit rate, but it would be nice to fix.
         *
         * The majority are case insenstive if they are values (encoding etc).
         * Most of rfc2616 is case insensitive on header contents.
         *
         * So the better solution may be to identify headers which should be
         * treated case-sensitive?
         *  HTTP URI's (3.2.3) [host and scheme are insensitive]
         *  HTTP method (5.1.1)
         *  HTTP-date values (3.3.1)
         *  3.7 Media Types [excerpt]
         *     The type, subtype, and parameter attribute names are case-
         *     insensitive. Parameter values might or might not be case-sensitive,
         *     depending on the semantics of the parameter name.
         *  4.20 Except [excerpt]
         *     Comparison of expectation values is case-insensitive for unquoted
         *     tokens (including the 100-continue token), and is case-sensitive for
         *     quoted-string expectation-extensions.
         */
    
        for (i=0, k=0; i < varray->nelts; i++) {
            header = apr_table_get(headers, elts[i]);
            if (!header) {
                header = "";
            }
            iov[k].iov_base = (char*) elts[i];
            iov[k].iov_len = strlen(elts[i]);
            k++;
            iov[k].iov_base = (char*) header;
            iov[k].iov_len = strlen(header);
            k++;
        }
        iov[k].iov_base = (char*) oldkey;
        iov[k].iov_len = strlen(oldkey);
        k++;
    
        return apr_pstrcatv(p, iov, k, NULL);
    }
    
    static int array_alphasort(const void *fn1, const void *fn2)
    {
        return strcmp(*(char**)fn1, *(char**)fn2);
    }
    
    static void tokens_to_array(apr_pool_t *p, const char *data,
                                apr_array_header_t *arr)
    {
        char *token;
    
        while ((token = ap_get_list_item(p, &data)) != NULL) {
            *((const char **) apr_array_push(arr)) = token;
        }
    
        /* Sort it so that "Vary: A, B" and "Vary: B, A" are stored the same. */
        qsort((void *) arr->elts, arr->nelts,
             sizeof(char *), array_alphasort);
    }
    
    /*
     * Hook and mod_cache callback functions
     */
    static int create_entity(cache_handle_t *h, request_rec *r, const char *key, apr_off_t len,
                             apr_bucket_brigade *bb)
    {
        disk_cache_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &cache_disk_module);
        disk_cache_conf *conf = ap_get_module_config(r->server->module_config,
                                                     &cache_disk_module);
        cache_object_t *obj;
        disk_cache_object_t *dobj;
        apr_pool_t *pool;
    
        if (conf->cache_root == NULL) {
            return DECLINED;
        }
    
        /* we don't support caching of range requests (yet) */
        if (r->status == HTTP_PARTIAL_CONTENT) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00700)
                    "URL %s partial content response not cached",
                    key);
            return DECLINED;
        }
    
        /* Note, len is -1 if unknown so don't trust it too hard */
        if (len > dconf->maxfs) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00701)
                    "URL %s failed the size check "
                    "(%" APR_OFF_T_FMT " > %" APR_OFF_T_FMT ")",
                    key, len, dconf->maxfs);
            return DECLINED;
        }
        if (len >= 0 && len < dconf->minfs) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00702)
                    "URL %s failed the size check "
                    "(%" APR_OFF_T_FMT " < %" APR_OFF_T_FMT ")",
                    key, len, dconf->minfs);
            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->prefix = NULL;
        /* Save the cache root */
        dobj->root = apr_pstrmemdup(r->pool, conf->cache_root, conf->cache_root_len);
        dobj->root_len = conf->cache_root_len;
    
        apr_pool_create(&pool, r->pool);
        apr_pool_tag(pool, "mod_cache (create_entity)");
    
        file_cache_create(conf, &dobj->hdrs, pool);
        file_cache_create(conf, &dobj->vary, pool);
        file_cache_create(conf, &dobj->data, pool);
    
        dobj->data.file = data_file(r->pool, conf, dobj, key);
        dobj->hdrs.file = header_file(r->pool, conf, dobj, key);
        dobj->vary.file = header_file(r->pool, conf, dobj, key);
    
        dobj->disk_info.header_only = r->header_only;
    
        return OK;
    }
    
    static int open_entity(cache_handle_t *h, request_rec *r, const char *key)
    {
        apr_uint32_t format;
        apr_size_t len;
        const char *nkey;
        apr_status_t rc;
        static int error_logged = 0;
        disk_cache_conf *conf = ap_get_module_config(r->server->module_config,
                                                     &cache_disk_module);
    #ifdef APR_SENDFILE_ENABLED
        core_dir_config *coreconf = ap_get_core_module_config(r->per_dir_config);
    #endif
        apr_finfo_t finfo;
        cache_object_t *obj;
        cache_info *info;
        disk_cache_object_t *dobj;
        int flags;
        apr_pool_t *pool;
    
        h->cache_obj = NULL;
    
        /* Look up entity keyed to 'url' */
        if (conf->cache_root == NULL) {
            if (!error_logged) {
                error_logged = 1;
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00703)
                        "Cannot cache files to disk without a CacheRoot specified.");
            }
            return DECLINED;
        }
    
        /* Create and init the cache object */
        obj = apr_pcalloc(r->pool, sizeof(cache_object_t));
        dobj = apr_pcalloc(r->pool, sizeof(disk_cache_object_t));
    
        info = &(obj->info);
    
        /* Open the headers file */
        dobj->prefix = NULL;
    
        /* Save the cache root */
        dobj->root = apr_pstrmemdup(r->pool, conf->cache_root, conf->cache_root_len);
        dobj->root_len = conf->cache_root_len;
    
        dobj->vary.file = header_file(r->pool, conf, dobj, key);
        flags = APR_READ|APR_BINARY|APR_BUFFERED;
        rc = apr_file_open(&dobj->vary.fd, dobj->vary.file, flags, 0, r->pool);
        if (rc != APR_SUCCESS) {
            return DECLINED;
        }
    
        /* read the format from the cache file */
        len = sizeof(format);
        apr_file_read_full(dobj->vary.fd, &format, len, &len);
    
        if (format == VARY_FORMAT_VERSION) {
            apr_array_header_t* varray;
            apr_time_t expire;
    
            len = sizeof(expire);
            apr_file_read_full(dobj->vary.fd, &expire, len, &len);
    
            varray = apr_array_make(r->pool, 5, sizeof(char*));
            rc = read_array(r, varray, dobj->vary.fd);
            if (rc != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(00704)
                        "Cannot parse vary header file: %s",
                        dobj->vary.file);
                apr_file_close(dobj->vary.fd);
                return DECLINED;
            }
            apr_file_close(dobj->vary.fd);
    
            nkey = regen_key(r->pool, r->headers_in, varray, key);
    
            dobj->hashfile = NULL;
            dobj->prefix = dobj->vary.file;
            dobj->hdrs.file = header_file(r->pool, conf, dobj, nkey);
    
            flags = APR_READ|APR_BINARY|APR_BUFFERED;
            rc = apr_file_open(&dobj->hdrs.fd, dobj->hdrs.file, flags, 0, r->pool);
            if (rc != APR_SUCCESS) {
                return DECLINED;
            }
        }
        else if (format != DISK_FORMAT_VERSION) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00705)
                    "File '%s' has a version mismatch. File had version: %d.",
                    dobj->vary.file, format);
            apr_file_close(dobj->vary.fd);
            return DECLINED;
        }
        else {
            apr_off_t offset = 0;
    
            /* oops, not vary as it turns out */
            dobj->hdrs.fd = dobj->vary.fd;
            dobj->vary.fd = NULL;
            dobj->hdrs.file = dobj->vary.file;
    
            /* This wasn't a Vary Format file, so we must seek to the
             * start of the file again, so that later reads work.
             */
            apr_file_seek(dobj->hdrs.fd, APR_SET, &offset);
            nkey = key;
        }
    
        obj->key = nkey;
        dobj->key = nkey;
        dobj->name = key;
    
        apr_pool_create(&pool, r->pool);
        apr_pool_tag(pool, "mod_cache (open_entity)");
    
        file_cache_create(conf, &dobj->hdrs, pool);
        file_cache_create(conf, &dobj->vary, pool);
        file_cache_create(conf, &dobj->data, pool);
    
        dobj->data.file = data_file(r->pool, conf, dobj, nkey);
    
        /* Read the bytes to setup the cache_info fields */
        rc = file_cache_recall_mydata(dobj->hdrs.fd, info, dobj, r);
        if (rc != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(00706)
                    "Cannot read header file %s", dobj->hdrs.file);
            apr_file_close(dobj->hdrs.fd);
            return DECLINED;
        }
    
    
        /* Is this a cached HEAD request? */
        if (dobj->disk_info.header_only && !r->header_only) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00707)
                    "HEAD request cached, non-HEAD requested, ignoring: %s",
                    dobj->hdrs.file);
            apr_file_close(dobj->hdrs.fd);
            return DECLINED;
        }
    
        /* Open the data file */
        if (dobj->disk_info.has_body) {
            flags = APR_READ | APR_BINARY;
    #ifdef APR_SENDFILE_ENABLED
            /* When we are in the quick handler we don't have the per-directory
             * configuration, so this check only takes the global setting of
             * the EnableSendFile directive into account.
             */
            flags |= AP_SENDFILE_ENABLED(coreconf->enable_sendfile);
    #endif
            rc = apr_file_open(&dobj->data.fd, dobj->data.file, flags, 0, r->pool);
            if (rc != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, APLOGNO(00708)
                        "Cannot open data file %s", dobj->data.file);
                apr_file_close(dobj->hdrs.fd);
                return DECLINED;
            }
    
            rc = apr_file_info_get(&finfo, APR_FINFO_SIZE | APR_FINFO_IDENT,
                    dobj->data.fd);
            if (rc == APR_SUCCESS) {
                dobj->file_size = finfo.size;
            }
    
            /* Atomic check - does the body file belong to the header file? */
            if (dobj->disk_info.inode == finfo.inode &&
                    dobj->disk_info.device == finfo.device) {
    
                /* Initialize the cache_handle callback functions */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00709)
                        "Recalled cached URL info header %s", dobj->name);
    
                /* make the configuration stick */
                h->cache_obj = obj;
                obj->vobj = dobj;
    
                return OK;
            }
    
        }
        else {
    
            /* make the configuration stick */
            h->cache_obj = obj;
            obj->vobj = dobj;
    
            return OK;
        }
    
        /* Oh dear, no luck matching header to the body */
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00710)
                "Cached URL info header '%s' didn't match body, ignoring this entry",
                dobj->name);
    
        apr_file_close(dobj->hdrs.fd);
        return DECLINED;
    }
    
    static void close_disk_cache_fd(disk_cache_file_t *file)
    {
       if (file->fd != NULL) {
           apr_file_close(file->fd);
           file->fd = NULL;
       }
       if (file->tempfd != NULL) {
           apr_file_close(file->tempfd);
           file->tempfd = NULL;
       }
    }
    
    static int remove_entity(cache_handle_t *h)
    {
        disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj;
    
        close_disk_cache_fd(&(dobj->hdrs));
        close_disk_cache_fd(&(dobj->vary));
        close_disk_cache_fd(&(dobj->data));
    
        /* Null out the cache object pointer so next time we start from scratch  */
        h->cache_obj = NULL;
        return OK;
    }
    
    static int remove_url(cache_handle_t *h, request_rec *r)
    {
        apr_status_t rc;
        disk_cache_object_t *dobj;
    
        /* Get disk cache object from cache handle */
        dobj = (disk_cache_object_t *) h->cache_obj->vobj;
        if (!dobj) {
            return DECLINED;
        }
    
        /* Delete headers file */
        if (dobj->hdrs.file) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00711)
                    "Deleting %s from cache.", dobj->hdrs.file);
    
            rc = apr_file_remove(dobj->hdrs.file, r->pool);
            if ((rc != APR_SUCCESS) && !APR_STATUS_IS_ENOENT(rc)) {
                /* Will only result in an output if httpd is started with -e debug.
                 * For reason see log_error_core for the case s == NULL.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(00712)
                        "Failed to delete headers file %s from cache.",
                        dobj->hdrs.file);
                return DECLINED;
            }
        }
    
        /* Delete data file */
        if (dobj->data.file) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00713)
                    "Deleting %s from cache.", dobj->data.file);
    
            rc = apr_file_remove(dobj->data.file, r->pool);
            if ((rc != APR_SUCCESS) && !APR_STATUS_IS_ENOENT(rc)) {
                /* Will only result in an output if httpd is started with -e debug.
                 * For reason see log_error_core for the case s == NULL.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rc, r, APLOGNO(00714)
                        "Failed to delete data file %s from cache.",
                        dobj->data.file);
                return DECLINED;
            }
        }
    
        /* now delete directories as far as possible up to our cache root */
        if (dobj->root) {
            const char *str_to_copy;
    
            str_to_copy = dobj->hdrs.file ? dobj->hdrs.file : dobj->data.file;
            if (str_to_copy) {
                char *dir, *slash, *q;
    
                dir = apr_pstrdup(r->pool, str_to_copy);
    
                /* remove filename */
                slash = strrchr(dir, '/');
                *slash = '\0';
    
                /*
                 * now walk our way back to the cache root, delete everything
                 * in the way as far as possible
                 *
                 * Note: due to the way we constructed the file names in
                 * header_file and data_file, we are guaranteed that the
                 * cache_root is suffixed by at least one '/' which will be
                 * turned into a terminating null by this loop.  Therefore,
                 * we won't either delete or go above our cache root.
                 */
                for (q = dir + dobj->root_len; *q ; ) {
                     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00715)
                            "Deleting directory %s from cache", dir);
    
                     rc = apr_dir_remove(dir, r->pool);
                     if (rc != APR_SUCCESS && !APR_STATUS_IS_ENOENT(rc)) {
                        break;
                     }
                     slash = strrchr(q, '/');
                     *slash = '\0';
                }
            }
        }
    
        return OK;
    }
    
    static apr_status_t read_array(request_rec *r, apr_array_header_t* arr,
                                   apr_file_t *file)
    {
        char w[MAX_STRING_LEN];
        apr_size_t p;
        apr_status_t rv;
    
        while (1) {
            rv = apr_file_gets(w, MAX_STRING_LEN - 1, file);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00716)
                              "Premature end of vary array.");
                return rv;
            }
    
            p = strlen(w);
            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 array, break out of the loop. */
            if (w[0] == '\0') {
                break;
            }
    
            *((const char **) apr_array_push(arr)) = apr_pstrdup(r->pool, w);
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t store_array(apr_file_t *fd, apr_array_header_t* arr)
    {
        int i;
        apr_status_t rv;
        struct iovec iov[2];
        apr_size_t amt;
        const char **elts;
    
        elts = (const char **) arr->elts;
    
        for (i = 0; i < arr->nelts; i++) {
            iov[0].iov_base = (char*) elts[i];
            iov[0].iov_len = strlen(elts[i]);
            iov[1].iov_base = CRLF;
            iov[1].iov_len = sizeof(CRLF) - 1;
    
            rv = apr_file_writev_full(fd, (const struct iovec *) &iov, 2, &amt);
            if (rv != APR_SUCCESS) {
                return rv;
            }
        }
    
        iov[0].iov_base = CRLF;
        iov[0].iov_len = sizeof(CRLF) - 1;
    
        return apr_file_writev_full(fd, (const struct iovec *) &iov, 1, &amt);
    }
    
    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;
        apr_size_t 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, rv, r, APLOGNO(00717)
                              "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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00718)
                            "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 (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;
        apr_status_t rv;
    
        /* This case should not happen... */
        if (!dobj->hdrs.fd) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00719)
                    "recalling headers; but no header fd for %s", dobj->name);
            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 */
        rv = read_table(h, r, h->resp_hdrs, dobj->hdrs.fd);
        if (rv != APR_SUCCESS) { 
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02987) 
                          "Error reading response headers from %s for %s",
                          dobj->hdrs.file, dobj->name);
        }
        rv = read_table(h, r, h->req_hdrs, dobj->hdrs.fd);
        if (rv != APR_SUCCESS) { 
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02988) 
                          "Error reading request headers from %s for %s",
                          dobj->hdrs.file, dobj->name);
        }
    
        apr_file_close(dobj->hdrs.fd);
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00720)
                "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)
    {
        disk_cache_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj;
    
        if (dobj->data.fd) {
            apr_brigade_insert_file(bb, dobj->data.fd, 0, dobj->file_size, p);
        }
    
        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_full(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_full(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_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj;
    
        memcpy(&h->cache_obj->info, info, sizeof(cache_info));
    
        if (r->headers_out) {
            dobj->headers_out = ap_cache_cacheable_headers_out(r);
        }
    
        if (r->headers_in) {
            dobj->headers_in = ap_cache_cacheable_headers_in(r);
        }
    
        if (r->header_only && r->status != HTTP_NOT_MODIFIED) {
            dobj->disk_info.header_only = 1;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t write_headers(cache_handle_t *h, request_rec *r)
    {
        disk_cache_conf *conf = ap_get_module_config(r->server->module_config,
                                                     &cache_disk_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];
    
        memset(&disk_info, 0, sizeof(disk_cache_info_t));
    
        if (dobj->headers_out) {
            const char *tmp;
    
            tmp = apr_table_get(dobj->headers_out, "Vary");
    
            if (tmp) {
                apr_array_header_t* varray;
                apr_uint32_t format = VARY_FORMAT_VERSION;
    
                /* If we were initially opened as a vary format, rollback
                 * that internal state for the moment so we can recreate the
                 * vary format hints in the appropriate directory.
                 */
                if (dobj->prefix) {
                    dobj->hdrs.file = dobj->prefix;
                    dobj->prefix = NULL;
                }
    
                rv = mkdir_structure(conf, dobj->hdrs.file, r->pool);
                if (rv == APR_SUCCESS) {
                    rv = apr_file_mktemp(&dobj->vary.tempfd, dobj->vary.tempfile,
                                         APR_CREATE | APR_WRITE | APR_BINARY | APR_EXCL,
                                         dobj->vary.pool);
                }
    
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00721)
                            "could not create vary file %s",
                            dobj->vary.tempfile);
                    return rv;
                }
    
                amt = sizeof(format);
                rv = apr_file_write_full(dobj->vary.tempfd, &format, amt, NULL);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00722)
                            "could not write to vary file %s",
                            dobj->vary.tempfile);
                    apr_file_close(dobj->vary.tempfd);
                    apr_pool_destroy(dobj->vary.pool);
                    return rv;
                }
    
                amt = sizeof(h->cache_obj->info.expire);
                rv = apr_file_write_full(dobj->vary.tempfd,
                                         &h->cache_obj->info.expire, amt, NULL);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00723)
                            "could not write to vary file %s",
                            dobj->vary.tempfile);
                    apr_file_close(dobj->vary.tempfd);
                    apr_pool_destroy(dobj->vary.pool);
                    return rv;
                }
    
                varray = apr_array_make(r->pool, 6, sizeof(char*));
                tokens_to_array(r->pool, tmp, varray);
    
                store_array(dobj->vary.tempfd, varray);
    
                rv = apr_file_close(dobj->vary.tempfd);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00724)
                            "could not close vary file %s",
                            dobj->vary.tempfile);
                    apr_pool_destroy(dobj->vary.pool);
                    return rv;
                }
    
                tmp = regen_key(r->pool, dobj->headers_in, varray, dobj->name);
                dobj->prefix = dobj->hdrs.file;
                dobj->hashfile = NULL;
                dobj->data.file = data_file(r->pool, conf, dobj, tmp);
                dobj->hdrs.file = header_file(r->pool, conf, dobj, tmp);
            }
        }
    
    
        rv = apr_file_mktemp(&dobj->hdrs.tempfd, dobj->hdrs.tempfile,
                             APR_CREATE | APR_WRITE | APR_BINARY |
                             APR_BUFFERED | APR_EXCL, dobj->hdrs.pool);
    
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00725)
                    "could not create header file %s",
                    dobj->hdrs.tempfile);
            return rv;
        }
    
        disk_info.format = DISK_FORMAT_VERSION;
        disk_info.date = h->cache_obj->info.date;
        disk_info.expire = h->cache_obj->info.expire;
        disk_info.entity_version = dobj->disk_info.entity_version++;
        disk_info.request_time = h->cache_obj->info.request_time;
        disk_info.response_time = h->cache_obj->info.response_time;
        disk_info.status = h->cache_obj->info.status;
        disk_info.inode = dobj->disk_info.inode;
        disk_info.device = dobj->disk_info.device;
        disk_info.has_body = dobj->disk_info.has_body;
        disk_info.header_only = dobj->disk_info.header_only;
    
        disk_info.name_len = strlen(dobj->name);
    
        memcpy(&disk_info.control, &h->cache_obj->info.control, sizeof(cache_control_t));
    
        iov[0].iov_base = (void*)&disk_info;
        iov[0].iov_len = sizeof(disk_cache_info_t);
        iov[1].iov_base = (void*)dobj->name;
        iov[1].iov_len = disk_info.name_len;
    
        rv = apr_file_writev_full(dobj->hdrs.tempfd, (const struct iovec *) &iov,
                                  2, &amt);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00726)
                    "could not write info to header file %s",
                    dobj->hdrs.tempfile);
            apr_file_close(dobj->hdrs.tempfd);
            apr_pool_destroy(dobj->hdrs.pool);
            return rv;
        }
    
        if (dobj->headers_out) {
            rv = store_table(dobj->hdrs.tempfd, dobj->headers_out);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00727)
                        "could not write out-headers to header file %s",
                        dobj->hdrs.tempfile);
                apr_file_close(dobj->hdrs.tempfd);
                apr_pool_destroy(dobj->hdrs.pool);
                return rv;
            }
        }
    
        /* Parse the vary header and dump those fields from the headers_in. */
        /* FIXME: Make call to the same thing cache_select calls to crack Vary. */
        if (dobj->headers_in) {
            rv = store_table(dobj->hdrs.tempfd, dobj->headers_in);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00728)
                        "could not write in-headers to header file %s",
                        dobj->hdrs.tempfile);
                apr_file_close(dobj->hdrs.tempfd);
                apr_pool_destroy(dobj->hdrs.pool);
                return rv;
            }
        }
    
        rv = apr_file_close(dobj->hdrs.tempfd); /* flush and close */
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00729)
                    "could not close header file %s",
                    dobj->hdrs.tempfile);
            apr_pool_destroy(dobj->hdrs.pool);
            return rv;
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t store_body(cache_handle_t *h, request_rec *r,
                                   apr_bucket_brigade *in, apr_bucket_brigade *out)
    {
        apr_bucket *e;
        apr_status_t rv = APR_SUCCESS;
        disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj;
        disk_cache_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &cache_disk_module);
        int seen_eos = 0;
    
        if (!dobj->offset) {
            dobj->offset = dconf->readsize;
        }
        if (!dobj->timeout && dconf->readtime) {
            dobj->timeout = apr_time_now() + dconf->readtime;
        }
    
        if (dobj->offset) {
            apr_brigade_partition(in, dobj->offset, &e);
        }
    
        while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(in)) {
            const char *str;
            apr_size_t length, written;
    
            e = APR_BRIGADE_FIRST(in);
    
            /* are we done completely? if so, pass any trailing buckets right through */
            if (dobj->done || !dobj->data.pool) {
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                continue;
            }
    
            /* have we seen eos yet? */
            if (APR_BUCKET_IS_EOS(e)) {
                seen_eos = 1;
                dobj->done = 1;
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                break;
            }
    
            /* honour flush buckets, we'll get called again */
            if (APR_BUCKET_IS_FLUSH(e)) {
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                break;
            }
    
            /* metadata buckets are preserved as is */
            if (APR_BUCKET_IS_METADATA(e)) {
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(out, e);
                continue;
            }
    
            /* read the bucket, write to the cache */
            rv = apr_bucket_read(e, &str, &length, APR_BLOCK_READ);
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(out, e);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00730)
                        "Error when reading bucket for URL %s",
                        h->cache_obj->key);
                /* Remove the intermediate cache file and return non-APR_SUCCESS */
                apr_pool_destroy(dobj->data.pool);
                return rv;
            }
    
            /* don't write empty buckets to the cache */
            if (!length) {
                continue;
            }
    
            if (!dobj->disk_info.header_only) {
    
                /* Attempt to create the data file at the last possible moment, if
                 * the body is empty, we don't write a file at all, and save an inode.
                 */
                if (!dobj->data.tempfd) {
                    apr_finfo_t finfo;
                    rv = apr_file_mktemp(&dobj->data.tempfd, dobj->data.tempfile,
                            APR_CREATE | APR_WRITE | APR_BINARY | APR_BUFFERED
                                    | APR_EXCL, dobj->data.pool);
                    if (rv != APR_SUCCESS) {
                        apr_pool_destroy(dobj->data.pool);
                        return rv;
                    }
                    dobj->file_size = 0;
                    rv = apr_file_info_get(&finfo, APR_FINFO_IDENT,
                            dobj->data.tempfd);
                    if (rv != APR_SUCCESS) {
                        apr_pool_destroy(dobj->data.pool);
                        return rv;
                    }
                    dobj->disk_info.device = finfo.device;
                    dobj->disk_info.inode = finfo.inode;
                    dobj->disk_info.has_body = 1;
                }
    
                /* write to the cache, leave if we fail */
                rv = apr_file_write_full(dobj->data.tempfd, str, length, &written);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(
                            APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00731) "Error when writing cache file for URL %s", h->cache_obj->key);
                    /* Remove the intermediate cache file and return non-APR_SUCCESS */
                    apr_pool_destroy(dobj->data.pool);
                    return rv;
                }
                dobj->file_size += written;
                if (dobj->file_size > dconf->maxfs) {
                    ap_log_rerror(
                            APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00732) "URL %s failed the size check "
                            "(%" APR_OFF_T_FMT ">%" APR_OFF_T_FMT ")", h->cache_obj->key, dobj->file_size, dconf->maxfs);
                    /* Remove the intermediate cache file and return non-APR_SUCCESS */
                    apr_pool_destroy(dobj->data.pool);
                    return APR_EGENERAL;
                }
    
            }
    
            /* have we reached the limit of how much we're prepared to write in one
             * go? If so, leave, we'll get called again. This prevents us from trying
             * to swallow too much data at once, or taking so long to write the data
             * the client times out.
             */
            dobj->offset -= length;
            if (dobj->offset <= 0) {
                dobj->offset = 0;
                break;
            }
            if ((dconf->readtime && apr_time_now() > dobj->timeout)) {
                dobj->timeout = 0;
                break;
            }
    
        }
    
        /* Was this the final bucket? If yes, close the temp file and perform
         * sanity checks.
         */
        if (seen_eos) {
            if (!dobj->disk_info.header_only) {
                const char *cl_header;
                apr_off_t cl;
    
                if (dobj->data.tempfd) {
                    rv = apr_file_close(dobj->data.tempfd);
                    if (rv != APR_SUCCESS) {
                        /* Buffered write failed, abandon attempt to write */
                        apr_pool_destroy(dobj->data.pool);
                        return rv;
                    }
                }
    
                if (r->connection->aborted || r->no_cache) {
                    ap_log_rerror(
                            APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00733) "Discarding body for URL %s "
                            "because connection has been aborted.", h->cache_obj->key);
                    /* Remove the intermediate cache file and return non-APR_SUCCESS */
                    apr_pool_destroy(dobj->data.pool);
                    return APR_EGENERAL;
                }
    
                if (dobj->file_size < dconf->minfs) {
                    ap_log_rerror(
                            APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00734) "URL %s failed the size check "
                            "(%" APR_OFF_T_FMT "<%" APR_OFF_T_FMT ")", h->cache_obj->key, dobj->file_size, dconf->minfs);
                    /* Remove the intermediate cache file and return non-APR_SUCCESS */
                    apr_pool_destroy(dobj->data.pool);
                    return APR_EGENERAL;
                }
    
                cl_header = apr_table_get(r->headers_out, "Content-Length");
                if (cl_header && (!ap_parse_strict_length(&cl, cl_header)
                                  || cl != dobj->file_size)) {
                    ap_log_rerror(
                            APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00735) "URL %s didn't receive complete response, not caching", h->cache_obj->key);
                    /* Remove the intermediate cache file and return non-APR_SUCCESS */
                    apr_pool_destroy(dobj->data.pool);
                    return APR_EGENERAL;
                }
            }
    
            /* All checks were fine, we're good to go when the commit comes */
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t commit_entity(cache_handle_t *h, request_rec *r)
    {
        disk_cache_conf *conf = ap_get_module_config(r->server->module_config,
                                                     &cache_disk_module);
        disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj;
        apr_status_t rv;
    
        /* write the headers to disk at the last possible moment */
        rv = write_headers(h, r);
    
        /* move header and data tempfiles to the final destination */
        if (APR_SUCCESS == rv) {
            rv = file_cache_el_final(conf, &dobj->hdrs, r);
        }
        if (APR_SUCCESS == rv) {
            rv = file_cache_el_final(conf, &dobj->vary, r);
        }
        if (APR_SUCCESS == rv) {
            if (!dobj->disk_info.header_only) {
                rv = file_cache_el_final(conf, &dobj->data, r);
            }
            else if (dobj->data.file) {
                rv = apr_file_remove(dobj->data.file, dobj->data.pool);
            }
        }
    
        /* remove the cached items completely on any failure */
        if (APR_SUCCESS != rv) {
            remove_url(h, r);
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00736)
                    "commit_entity: URL '%s' not cached due to earlier disk error.",
                    dobj->name);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00737)
                    "commit_entity: Headers and body for URL %s cached.",
                    dobj->name);
        }
    
        apr_pool_destroy(dobj->data.pool);
    
        return APR_SUCCESS;
    }
    
    static apr_status_t invalidate_entity(cache_handle_t *h, request_rec *r)
    {
        apr_status_t rv;
    
        rv = recall_headers(h, r);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        /* mark the entity as invalidated */
        h->cache_obj->info.control.invalidated = 1;
    
        return commit_entity(h, r);
    }
    
    static void *create_dir_config(apr_pool_t *p, char *dummy)
    {
        disk_cache_dir_conf *dconf = apr_pcalloc(p, sizeof(disk_cache_dir_conf));
    
        dconf->maxfs = DEFAULT_MAX_FILE_SIZE;
        dconf->minfs = DEFAULT_MIN_FILE_SIZE;
        dconf->readsize = DEFAULT_READSIZE;
        dconf->readtime = DEFAULT_READTIME;
    
        return dconf;
    }
    
    static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv)
    {
        disk_cache_dir_conf *new = (disk_cache_dir_conf *) apr_pcalloc(p, sizeof(disk_cache_dir_conf));
        disk_cache_dir_conf *add = (disk_cache_dir_conf *) addv;
        disk_cache_dir_conf *base = (disk_cache_dir_conf *) basev;
    
        new->maxfs = (add->maxfs_set == 0) ? base->maxfs : add->maxfs;
        new->maxfs_set = add->maxfs_set || base->maxfs_set;
        new->minfs = (add->minfs_set == 0) ? base->minfs : add->minfs;
        new->minfs_set = add->minfs_set || base->minfs_set;
        new->readsize = (add->readsize_set == 0) ? base->readsize : add->readsize;
        new->readsize_set = add->readsize_set || base->readsize_set;
        new->readtime = (add->readtime_set == 0) ? base->readtime : add->readtime;
        new->readtime_set = add->readtime_set || base->readtime_set;
    
        return new;
    }
    
    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->cache_root = NULL;
        conf->cache_root_len = 0;
    
        return conf;
    }
    
    /*
     * mod_cache_disk 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,
                                                     &cache_disk_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,
                                                     &cache_disk_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,
                                                     &cache_disk_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_dir_conf *dconf = (disk_cache_dir_conf *)in_struct_ptr;
    
        if (apr_strtoff(&dconf->minfs, arg, NULL, 10) != APR_SUCCESS ||
                dconf->minfs < 0)
        {
            return "CacheMinFileSize argument must be a non-negative integer representing the min size of a file to cache in bytes.";
        }
        dconf->minfs_set = 1;
        return NULL;
    }
    
    static const char
    *set_cache_maxfs(cmd_parms *parms, void *in_struct_ptr, const char *arg)
    {
        disk_cache_dir_conf *dconf = (disk_cache_dir_conf *)in_struct_ptr;
    
        if (apr_strtoff(&dconf->maxfs, arg, NULL, 10) != APR_SUCCESS ||
                dconf->maxfs < 0)
        {
            return "CacheMaxFileSize argument must be a non-negative integer representing the max size of a file to cache in bytes.";
        }
        dconf->maxfs_set = 1;
        return NULL;
    }
    
    static const char
    *set_cache_readsize(cmd_parms *parms, void *in_struct_ptr, const char *arg)
    {
        disk_cache_dir_conf *dconf = (disk_cache_dir_conf *)in_struct_ptr;
    
        if (apr_strtoff(&dconf->readsize, arg, NULL, 10) != APR_SUCCESS ||
                dconf->readsize < 0)
        {
            return "CacheReadSize argument must be a non-negative integer representing the max amount of data to cache in go.";
        }
        dconf->readsize_set = 1;
        return NULL;
    }
    
    static const char
    *set_cache_readtime(cmd_parms *parms, void *in_struct_ptr, const char *arg)
    {
        disk_cache_dir_conf *dconf = (disk_cache_dir_conf *)in_struct_ptr;
        apr_off_t milliseconds;
    
        if (apr_strtoff(&milliseconds, arg, NULL, 10) != APR_SUCCESS ||
                milliseconds < 0)
        {
            return "CacheReadTime argument must be a non-negative integer representing the max amount of time taken to cache in go.";
        }
        dconf->readtime = apr_time_from_msec(milliseconds);
        dconf->readtime_set = 1;
        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 | ACCESS_CONF,
                      "The minimum file size to cache a document"),
        AP_INIT_TAKE1("CacheMaxFileSize", set_cache_maxfs, NULL, RSRC_CONF | ACCESS_CONF,
                      "The maximum file size to cache a document"),
        AP_INIT_TAKE1("CacheReadSize", set_cache_readsize, NULL, RSRC_CONF | ACCESS_CONF,
                      "The maximum quantity of data to attempt to read and cache in one go"),
        AP_INIT_TAKE1("CacheReadTime", set_cache_readtime, NULL, RSRC_CONF | ACCESS_CONF,
                      "The maximum time taken to attempt to read and cache in go"),
        {NULL}
    };
    
    static const cache_provider cache_disk_provider =
    {
        &remove_entity,
        &store_headers,
        &store_body,
        &recall_headers,
        &recall_body,
        &create_entity,
        &open_entity,
        &remove_url,
        &commit_entity,
        &invalidate_entity
    };
    
    static void disk_cache_register_hook(apr_pool_t *p)
    {
        /* cache initializer */
        ap_register_provider(p, CACHE_PROVIDER_GROUP, "disk", "0",
                             &cache_disk_provider);
    }
    
    AP_DECLARE_MODULE(cache_disk) = {
        STANDARD20_MODULE_STUFF,
        create_dir_config,          /* create per-directory config structure */
        merge_dir_config,           /* 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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cache/Makefile.in��������������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�017376� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015746� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_config.c�������������������������������������������������������0000664�0001751�0001751�00000163275�14737241445�021076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
     *
     * 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 compatible
     * 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
     *    <VirtualHost>
     *    LogFormat      "... custom format ..."
     *    TransferLog    log/virtual_only
     *    CustomLog      log/virtual_useragents "%t %{user-agent}i"
     *    </VirtualHost>
     *
     * 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.
     * %...k:  number of keepalive requests served over this connection
     * %...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 canonical port for the server
     * %...{format}p: the canonical port for the server, or the actual local
     *                or remote port
     * %...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.
     * %...{s}T:  the time taken to serve the request, in seconds, same as %T.
     * %...{us}T:  the time taken to serve the request, in micro seconds, same as %D.
     * %...{ms}T:  the time taken to serve the request, in milliseconds.
     * %...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.)
     * %...L:  Log-Id of the Request (or '-' if none)
     * %...{c}L:  Log-Id of the Connection (or '-' if none)
     *
     * 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 <unistd.h>
    #endif
    #ifdef HAVE_LIMITS_H
    #include <limits.h>
    #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;
        int inherit;
        ap_expr_info_t *condition_expr;
        /** place of definition or NULL if already checked */
        const ap_directive_t *directive;
    } config_log_state;
    
    /*
     * log_request_state holds request specific log data that is not
     * part of the request_rec.
     */
    typedef struct {
        apr_time_t request_end_time;
    } log_request_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 *pfmt(apr_pool_t *p, int i)
    {
        if (i <= 0) {
            return "-";
        }
        else {
            return apr_itoa(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)
    {
        const char *remote_host;
        if (a && !strcmp(a, "c")) {
            remote_host = ap_get_remote_host(r->connection, r->per_dir_config,
                                             REMOTE_NAME, NULL);
        }
        else {
            remote_host = ap_get_useragent_host(r, REMOTE_NAME, NULL);
        }
        return ap_escape_logitem(r->pool, remote_host);
    }
    
    static const char *log_remote_address(request_rec *r, char *a)
    {
        if (a && !strcmp(a, "c")) {
            return r->connection->client_ip;
        }
        else {
            return r->useragent_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_log_id(request_rec *r, char *a)
    {
        if (a && !strcmp(a, "c")) {
            return r->connection->log_id ? r->connection->log_id : "-";
        }
        else {
            return r->log_id ? r->log_id : "-";
        }
    }
    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 *log_handler(request_rec *r, char *a)
    {
        return ap_escape_logitem(r->pool, r->handler);
    }
    
    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 const char *log_trailer_in(request_rec *r, char *a)
    {
        return ap_escape_logitem(r->pool, apr_table_get(r->trailers_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 (!ap_cstr_casecmp(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 (!ap_cstr_casecmp(a, "Content-type") && r->content_type) {
            cp = ap_field_noparam(r->pool, r->content_type);
        }
        else if (!ap_cstr_casecmp(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_trailer_out(request_rec *r, char *a)
    {
        return ap_escape_logitem(r->pool, apr_table_get(r->trailers_out, a));
    }
    
    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_entry;
    
        /*
         * This supports Netscape version 0 cookies while being tolerant to
         * some properties of RFC2109/2965 version 1 cookies:
         * - case-insensitive match of cookie names
         * - white space between the tokens
         * It does not support the following version 1 features:
         * - quoted strings as cookie values
         * - commas to separate cookies
         */
    
        if ((cookies_entry = apr_table_get(r->headers_in, "Cookie"))) {
            char *cookie, *last1, *last2;
            char *cookies = apr_pstrdup(r->pool, cookies_entry);
    
            while ((cookie = apr_strtok(cookies, ";", &last1))) {
                char *name = apr_strtok(cookie, "=", &last2);
                /* last2 points to the next char following an '=' delim,
                   or the trailing NUL char of the string */
                char *value = last2;
                if (name && *name &&  value && *value) {
                    char *last = value - 2;
                    /* Move past leading WS */
                    name += strspn(name, " \t");
                    while (last >= name && apr_isspace(*last)) {
                        *last = '\0';
                        --last;
                    }
    
                    if (!ap_cstr_casecmp(name, a)) {
                        /* last1 points to the next char following the ';' delim,
                           or the trailing NUL char of the string */
                        last = last1 - (*last1 ? 2 : 1);
                        /* Move past leading WS */
                        value += strspn(value, " \t");
                        while (last >= value && apr_isspace(*last)) {
                           *last = '\0';
                           --last;
                        }
    
                        return ap_escape_logitem(r->pool, value);
                    }
                }
                /* Iterate the remaining tokens using apr_strtok(NULL, ...) */
                cookies = NULL;
            }
        }
        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_FMT_CUSTOM          0
    #define TIME_FMT_CLF             1
    #define TIME_FMT_ABS_SEC         2
    #define TIME_FMT_ABS_MSEC        3
    #define TIME_FMT_ABS_USEC        4
    #define TIME_FMT_ABS_MSEC_FRAC   5
    #define TIME_FMT_ABS_USEC_FRAC   6
    
    #define TIME_CACHE_SIZE 4
    #define TIME_CACHE_MASK 3
    static cached_request_time request_time_cache[TIME_CACHE_SIZE];
    
    static apr_time_t get_request_end_time(request_rec *r)
    {
        log_request_state *state = (log_request_state *)ap_get_module_config(r->request_config,
                                                                             &log_config_module);
        if (!state) {
            state = apr_pcalloc(r->pool, sizeof(log_request_state));
            ap_set_module_config(r->request_config, &log_config_module, state);
        }
        if (state->request_end_time == 0) {
            state->request_end_time = apr_time_now();
        }
        return state->request_end_time;
    }
    
    
    static const char *log_request_time(request_rec *r, char *a)
    {
        apr_time_exp_t xt;
        apr_time_t request_time = r->request_time;
        int fmt_type = TIME_FMT_CUSTOM;
        char *fmt = a;
    
        if (fmt && *fmt) {
            if (!strncmp(fmt, "begin", 5)) {
                fmt += 5;
                if (!*fmt) {
                    fmt_type = TIME_FMT_CLF;
                }
                else if (*fmt == ':') {
                    fmt++;
                    a = fmt;
                }
            }
            else if (!strncmp(fmt, "end", 3)) {
                fmt += 3;
                if (!*fmt) {
                    request_time = get_request_end_time(r);
                    fmt_type = TIME_FMT_CLF;
                }
                else if (*fmt == ':') {
                    fmt++;
                    a = fmt;
                    request_time = get_request_end_time(r);
                }
            }
            if (!strncmp(fmt, "msec", 4)) {
                fmt += 4;
                if (!*fmt) {
                    fmt_type = TIME_FMT_ABS_MSEC;
                }
                else if (!strcmp(fmt, "_frac")) {
                    fmt_type = TIME_FMT_ABS_MSEC_FRAC;
                }
            }
            else if (!strncmp(fmt, "usec", 4)) {
                fmt += 4;
                if (!*fmt) {
                    fmt_type = TIME_FMT_ABS_USEC;
                }
                else if (!strcmp(fmt, "_frac")) {
                    fmt_type = TIME_FMT_ABS_USEC_FRAC;
                }
            }
            else if (!strcmp(fmt, "sec")) {
                fmt_type = TIME_FMT_ABS_SEC;
            }
            else if (!*fmt) {
                fmt_type = TIME_FMT_CLF;
            }
        }
        else {
            fmt_type = TIME_FMT_CLF;
        }
    
        if (fmt_type >= TIME_FMT_ABS_SEC) {      /* Absolute (micro-/milli-)second time
                                                  * or msec/usec fraction
                                                  */
            char* buf = apr_palloc(r->pool, 20);
            switch (fmt_type) {
            case TIME_FMT_ABS_SEC:
                apr_snprintf(buf, 20, "%" APR_TIME_T_FMT, apr_time_sec(request_time));
                break;
            case TIME_FMT_ABS_MSEC:
                apr_snprintf(buf, 20, "%" APR_TIME_T_FMT, apr_time_as_msec(request_time));
                break;
            case TIME_FMT_ABS_USEC:
                apr_snprintf(buf, 20, "%" APR_TIME_T_FMT, request_time);
                break;
            case TIME_FMT_ABS_MSEC_FRAC:
                apr_snprintf(buf, 20, "%03" APR_TIME_T_FMT, apr_time_msec(request_time));
                break;
            case TIME_FMT_ABS_USEC_FRAC:
                apr_snprintf(buf, 20, "%06" APR_TIME_T_FMT, apr_time_usec(request_time));
                break;
            default:
                return "-";
            }
            return buf;
        }
        else if (fmt_type == TIME_FMT_CUSTOM) {  /* 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.)
             */
            ap_explode_recent_localtime(&xt, request_time);
            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));
            unsigned t_seconds = (unsigned)apr_time_sec(request_time);
            unsigned i = t_seconds & TIME_CACHE_MASK;
            *cached_time = request_time_cache[i];
            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;
                request_time_cache[i] = *cached_time;
            }
            return cached_time->timestr;
        }
    }
    
    static const char *log_request_duration_microseconds(request_rec *r, char *a)
    {    
        return apr_psprintf(r->pool, "%" APR_TIME_T_FMT,
                            (get_request_end_time(r) - r->request_time));
    }
    
    static const char *log_request_duration_scaled(request_rec *r, char *a)
    {
        apr_time_t duration = get_request_end_time(r) - r->request_time;
        if (*a == '\0' || !strcasecmp(a, "s")) {
            duration = apr_time_sec(duration);
        }
        else if (!strcasecmp(a, "ms")) {
            duration = apr_time_as_msec(duration);
        }
        else if (!strcasecmp(a, "us")) {
        }
        else {
            /* bogus format */
            return a;
        }
        return apr_psprintf(r->pool, "%" APR_TIME_T_FMT, duration);
    }
    
    /* 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)
    {
        apr_port_t port;
    
        if (*a == '\0' || !strcasecmp(a, "canonical")) {
            port = r->server->port ? r->server->port : ap_default_port(r);
        }
        else if (!strcasecmp(a, "remote")) {
            port = r->useragent_addr->port;
        }
        else if (!strcasecmp(a, "local")) {
            port = r->connection->local_addr->port;
        }
        else {
            /* bogus format */
            return a;
        }
        return apr_itoa(r->pool, (int)port);
    }
    
    /* 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' || !strcasecmp(a, "pid")) {
            return ap_append_pid(r->pool, "", "");
        }
        else if (!strcasecmp(a, "tid") || !strcasecmp(a, "hextid")) {
    #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,
                                /* APR can format a thread id in hex */
                                *a == 'h' ? "%pt" : "%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 "-";
    }
    
    static const char *log_requests_on_connection(request_rec *r, char *a)
    {
        int num = r->connection->keepalives ? r->connection->keepalives - 1 : 0;
        return apr_itoa(r->pool, num);
    }
    
    /*****************************************************************
     *
     * 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 = NULL;
    
        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:
                /* check for '^' + two character format first */
                if (*s == '^' && *(s+1) && *(s+2)) { 
                    handler = (ap_log_handler *)apr_hash_get(log_hash, s, 3); 
                    if (handler) { 
                       s += 3;
                    }
                }
                if (!handler) {  
                    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) {
            /* XXX: error handling */
            apr_file_write_full(buf->handle, buf->outbuf, buf->outcnt, NULL);
            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;
                }
            }
        }
        else if (cls->condition_expr != NULL) {
            const char *err;
            int rc = ap_expr_exec(r, cls->condition_expr, &err);
            if (rc < 0)
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00644)
                               "Error evaluating log condition: %s", err);
            if (rc <= 0)
                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]);
            len += strl[i] = strlen(strs[i]);
        }
    
        if (!log_writer) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00645)
                    "log writer isn't correctly setup");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        rv = log_writer(r, cls->log_writer, strs, strl, format->nelts, len);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, APLOGNO(00646)
                          "Error writing to %s", cls->fname);
        }
        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;
    
        /*
         * Initialize per request state
         */
        log_request_state *state = apr_pcalloc(r->pool, sizeof(log_request_state));
        ap_set_module_config(r->request_config, &log_config_module, state);
    
        /*
         * 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);
            }
        }
    
        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->inherit || !mls->config_logs->nelts) {
                    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, add->formats, base->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;
        cls->condition_expr = NULL;
        if (envclause != NULL) {
            if (strncasecmp(envclause, "env=", 4) == 0) {
                if ((envclause[4] == '\0')
                    || ((envclause[4] == '!') && (envclause[5] == '\0'))) {
                    return "missing environment variable name";
                }
                cls->condition_var = apr_pstrdup(cmd->pool, &envclause[4]);
            }
            else if (strncasecmp(envclause, "expr=", 5) == 0) {
                const char *err;
                if ((envclause[5] == '\0'))
                    return "missing condition";
                cls->condition_expr = ap_expr_parse_cmd(cmd, &envclause[5],
                                                        AP_EXPR_FLAG_DONT_VARY,
                                                        &err, NULL);
                if (err)
                    return err;
            }
            else {
                return "error in condition clause";
            }
        }
    
        cls->fname = fn;
        cls->format_string = fmt;
        cls->directive = cmd->directive;
        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 *add_global_log(cmd_parms *cmd, void *dummy, const char *fn,
                                      const char *fmt, const char *envclause) {
        multi_log_state *mls = ap_get_module_config(cmd->server->module_config,
                                                    &log_config_module);
        config_log_state *clsarray;
        config_log_state *cls;
        const char *ret;
    
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err) {
            return err;
        }
    
        /* Add a custom log through the normal channel */
        ret = add_custom_log(cmd, dummy, fn, fmt, envclause);
    
        /* Set the inherit flag unless there was some error */
        if (ret == NULL) {
            clsarray = (config_log_state*)mls->config_logs->elts;
            cls = &clsarray[mls->config_logs->nelts-1];
            cls->inherit = 1;
        }
    
        return ret;
    }
    
    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_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);
        }
        else {
            ap_log_set_writer_init(ap_default_log_writer_init);
            ap_log_set_writer(ap_default_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=\" or \"expr=\" clause (see docs)"),
    AP_INIT_TAKE23("GlobalLog", add_global_log, NULL, RSRC_CONF,
         "Same as CustomLog, but forces virtualhosts to inherit the log"),
    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_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, APLOGNO(00647)
                                     "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, strlen(tag), (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;
    
        /*
         * We do this memcpy dance because write() is atomic for len < PIPE_BUF,
         * while writev() need not be.
         */
        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, APLOGNO(00648)
                                "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, APLOGNO(00649)
                                "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;
    
            /*
             * We do this memcpy dance because write() is atomic for
             * len < PIPE_BUF, while writev() need not be.
             */
            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_full(buf->handle, str, w, NULL);
    
        }
        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, "L", log_log_id, 1);
            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, "k", log_requests_on_connection, 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_scaled, 1);
            log_pfn_register(p, "U", log_request_uri, 1);
            log_pfn_register(p, "s", log_status, 1);
            log_pfn_register(p, "R", log_handler, 1);
    
            log_pfn_register(p, "^ti", log_trailer_in, 0);
            log_pfn_register(p, "^to", log_trailer_out, 0);
        }
    
        /* reset to default conditions */
        ap_log_set_writer_init(ap_default_log_writer_init);
        ap_log_set_writer(ap_default_log_writer);
        buffered_logs = 0;
    
        return OK;
    }
    
    static int check_log_dir(apr_pool_t *p, server_rec *s, config_log_state *cls)
    {
        if (!cls->fname || cls->fname[0] == '|' || !cls->directive) {
            return OK;
        }
        else {
            char *abs = ap_server_root_relative(p, cls->fname);
            char *dir = ap_make_dirstr_parent(p, abs);
            apr_finfo_t finfo;
            const ap_directive_t *directive = cls->directive;
            apr_status_t rv = apr_stat(&finfo, dir, APR_FINFO_TYPE, p);
            cls->directive = NULL; /* Don't check this config_log_state again */
            if (rv == APR_SUCCESS && finfo.filetype != APR_DIR)
                rv = APR_ENOTDIR;
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, rv, s,
                             APLOGNO(02297)
                             "Cannot access directory '%s' for log file '%s' "
                             "defined at %s:%d", dir, cls->fname,
                             directive->filename, directive->line_num);
                return !OK;
            }
        }
        return OK;
    }
    
    static int log_check_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
    {
        int rv = OK;
        while (s) {
            multi_log_state *mls = ap_get_module_config(s->module_config,
                                                        &log_config_module);
            /*
             * We don't need to check mls->server_config_logs because it just
             * points to the parent server's mls->config_logs.
             */
            apr_array_header_t *log_list = mls->config_logs;
            config_log_state *clsarray = (config_log_state *) log_list->elts;
            int i;
            for (i = 0; i < log_list->nelts; ++i) {
                if (check_log_dir(ptemp, s, &clsarray[i]) != OK)
                    rv = !OK;
            }
    
            s = s->next;
        }
        return rv;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_pre_config(log_pre_config,NULL,NULL,APR_HOOK_REALLY_FIRST);
        ap_hook_check_config(log_check_config,NULL,NULL,APR_HOOK_MIDDLE);
        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);
    }
    
    AP_DECLARE_MODULE(log_config) =
    {
        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 */
    };
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_config.mak�����������������������������������������������������0000664�0001751�0001751�00000024101�12701473373�021400� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_log_config.dsp
    !IF "$(CFG)" == ""
    CFG=mod_log_config - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_log_config - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_log_config - Win32 Release" && "$(CFG)" != "mod_log_config - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_config - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_log_config.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_log_config.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_log_config.obj"
    	-@erase "$(INTDIR)\mod_log_config.res"
    	-@erase "$(INTDIR)\mod_log_config_src.idb"
    	-@erase "$(INTDIR)\mod_log_config_src.pdb"
    	-@erase "$(OUTDIR)\mod_log_config.exp"
    	-@erase "$(OUTDIR)\mod_log_config.lib"
    	-@erase "$(OUTDIR)\mod_log_config.pdb"
    	-@erase "$(OUTDIR)\mod_log_config.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_log_config_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_log_config.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_log_config.so" /d LONG_NAME="log_config_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_log_config.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_log_config.pdb" /debug /out:"$(OUTDIR)\mod_log_config.so" /implib:"$(OUTDIR)\mod_log_config.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_log_config.obj" \
    	"$(INTDIR)\mod_log_config.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_log_config.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_log_config.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_log_config.so"
       if exist .\Release\mod_log_config.so.manifest mt.exe -manifest .\Release\mod_log_config.so.manifest -outputresource:.\Release\mod_log_config.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_log_config - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_log_config.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_log_config.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_log_config.obj"
    	-@erase "$(INTDIR)\mod_log_config.res"
    	-@erase "$(INTDIR)\mod_log_config_src.idb"
    	-@erase "$(INTDIR)\mod_log_config_src.pdb"
    	-@erase "$(OUTDIR)\mod_log_config.exp"
    	-@erase "$(OUTDIR)\mod_log_config.lib"
    	-@erase "$(OUTDIR)\mod_log_config.pdb"
    	-@erase "$(OUTDIR)\mod_log_config.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_log_config_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_log_config.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_log_config.so" /d LONG_NAME="log_config_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_log_config.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_log_config.pdb" /debug /out:"$(OUTDIR)\mod_log_config.so" /implib:"$(OUTDIR)\mod_log_config.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_log_config.obj" \
    	"$(INTDIR)\mod_log_config.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_log_config.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_log_config.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_log_config.so"
       if exist .\Debug\mod_log_config.so.manifest mt.exe -manifest .\Debug\mod_log_config.so.manifest -outputresource:.\Debug\mod_log_config.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_log_config.dep")
    !INCLUDE "mod_log_config.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_log_config.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_log_config - Win32 Release" || "$(CFG)" == "mod_log_config - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_log_config - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_config - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_config - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\loggers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_config - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\loggers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_config - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_config - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_log_config - Win32 Release"
    
    
    "$(INTDIR)\mod_log_config.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_log_config.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_log_config.so" /d LONG_NAME="log_config_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_log_config - Win32 Debug"
    
    
    "$(INTDIR)\mod_log_config.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_log_config.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_log_config.so" /d LONG_NAME="log_config_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_log_config.c
    
    "$(INTDIR)\mod_log_config.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_logio.c������������������������������������������������������������0000664�0001751�0001751�00000020025�13262704500�020046� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <bojan rexursive.com>.
     */
    
    #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"
    #include "http_request.h"
    
    module AP_MODULE_DECLARE_DATA logio_module;
    
    static const char logio_filter_name[] = "LOG_INPUT_OUTPUT";
    static const char logio_ttfb_filter_name[] = "LOGIO_TTFB_OUT";
    
    /*
     * Logging of input and output config...
     */
    
    typedef struct logio_config_t {
        apr_off_t bytes_in;
        apr_off_t bytes_out;
        apr_off_t bytes_last_request;
    } logio_config_t;
    
    typedef struct logio_dirconf_t {
        unsigned int track_ttfb:1;
    } logio_dirconf_t;
    
    typedef struct logio_req_t {
        apr_time_t ttfb;
    } logio_req_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;
    }
    
    /*
     * Optional function for modules to adjust bytes_in
     */
    
    static void ap_logio_add_bytes_in(conn_rec *c, apr_off_t bytes)
    {
        logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module);
    
        cf->bytes_in += bytes;
    }
    
    /*
     * Optional function to get total byte count of last request for
     * ap_increment_counts.
     */
    
    static apr_off_t ap_logio_get_last_bytes(conn_rec *c)
    {
        logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module);
    
        return cf->bytes_last_request;
    }
    
    /*
     * 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);
    }
    
    static const char *log_bytes_combined(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 + cf->bytes_in);
    }
    
    static const char *log_ttfb(request_rec *r, char *a)
    {
        logio_req_t *rconf = ap_get_module_config(r->request_config,
                                               &logio_module);
    
        if (!rconf || !rconf->ttfb) { 
            return "-";
        }
    
        return apr_psprintf(r->pool, "%" APR_TIME_T_FMT, rconf->ttfb);
    }
    /*
     * 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);
    
        /* need to save byte count of last request for ap_increment_counts */
        cf->bytes_last_request = cf->bytes_in + cf->bytes_out;
        cf->bytes_in = cf->bytes_out = 0;
    
        return OK;
    }
    
    /*
     * Logging of input filter...
     */
    
    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;
    }
    
    /*
     * 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);
    
        return OK;
    }
    
    static int logio_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
    {
        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);
            log_pfn_register(p, "S", log_bytes_combined, 0);
            log_pfn_register(p, "^FB", log_ttfb, 0);
        }
    
        return OK;
    }
    
    static apr_status_t logio_ttfb_filter(ap_filter_t *f, apr_bucket_brigade *b)
    {
        request_rec *r = f->r;
        logio_dirconf_t *conf = ap_get_module_config(r->per_dir_config,
                                                     &logio_module);
        if (conf && conf->track_ttfb) { 
            logio_req_t *rconf = ap_get_module_config(r->request_config, 
                                                      &logio_module);
            if (rconf == NULL) { 
                rconf = apr_pcalloc(r->pool, sizeof(logio_req_t));
                rconf->ttfb = apr_time_now() - r->request_time;
                ap_set_module_config(r->request_config, &logio_module, rconf);
            }
        }
        ap_remove_output_filter(f);
        return ap_pass_brigade(f->next, b);
    }
    
    static void logio_insert_filter(request_rec * r)
    {
        logio_dirconf_t *conf = ap_get_module_config(r->per_dir_config,
                                                     &logio_module);
        if (conf->track_ttfb) { 
            ap_add_output_filter(logio_ttfb_filter_name, NULL, r, r->connection);
        }
    }
    
    static const char *logio_track_ttfb(cmd_parms *cmd, void *in_dir_config, int arg)
    {
        logio_dirconf_t *dir_config = in_dir_config;
        dir_config->track_ttfb = arg;
        return NULL;
    }
    
    static void *create_logio_dirconf (apr_pool_t *p, char *dummy)
    {
        logio_dirconf_t *new =
            (logio_dirconf_t *) apr_pcalloc(p, sizeof(logio_dirconf_t));
        return (void *) new;
    }
    
    
    static const command_rec logio_cmds[] = {
        AP_INIT_FLAG ("LogIOTrackTTFB", logio_track_ttfb, NULL, OR_ALL,
                      "Set to 'ON' to enable tracking time to first byte"),
        {NULL}
    };
    
    
    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_hook_insert_filter(logio_insert_filter, NULL, NULL, APR_HOOK_LAST);
        ap_register_output_filter(logio_ttfb_filter_name, logio_ttfb_filter, NULL,
                                  AP_FTYPE_RESOURCE);
    
        APR_REGISTER_OPTIONAL_FN(ap_logio_add_bytes_out);
        APR_REGISTER_OPTIONAL_FN(ap_logio_add_bytes_in);
        APR_REGISTER_OPTIONAL_FN(ap_logio_get_last_bytes);
    }
    
    AP_DECLARE_MODULE(logio) =
    {
        STANDARD20_MODULE_STUFF,
        create_logio_dirconf,       /* create per-dir config */ 
        NULL,                       /* merge per-dir config */
        NULL,                       /* server config */
        NULL,                       /* merge server config */
        logio_cmds,                 /* command apr_table_t */
        register_hooks              /* register hooks */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_debug.c��������������������������������������������������������0000664�0001751�0001751�00000022451�14104434146�020673� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "ap_expr.h"
    
    extern module AP_MODULE_DECLARE_DATA log_debug_module;
    
    typedef struct {
        ap_expr_info_t *msg_expr;
        ap_expr_info_t *condition;
        const char *hook;
    } msg_entry;
    
    typedef struct {
        apr_array_header_t *entries;
    } log_debug_dirconf;
    
    static const char *allhooks = "all";
    static const char * const hooks[] = {
        "log_transaction",      /*  0 */
        "quick_handler",        /*  1 */
        "handler",              /*  2 */
        "translate_name",       /*  3 */
        "map_to_storage",       /*  4 */
        "fixups",               /*  5 */
        "type_checker",         /*  6 */
        "check_access",         /*  7 */
        "check_access_ex",      /*  8 */
        "check_authn",          /*  9 */
        "check_authz",          /* 10 */
        "insert_filter",        /* 11 */
        "pre_translate_name",   /* 12 */
        NULL
    };
    
    static void do_debug_log(request_rec *r, const char *hookname)
    {
        log_debug_dirconf *dconf = ap_get_module_config(r->per_dir_config, &log_debug_module);
        int i;
        if (dconf->entries == NULL)
            return;
    
        for (i = 0; i < dconf->entries->nelts; i++) {
            const char *msg, *err;
            msg_entry *entry = APR_ARRAY_IDX(dconf->entries, i, msg_entry *);
            if (entry->hook != allhooks && entry->hook != hookname)
                continue;
            if (entry->condition) {
                int ret = ap_expr_exec(r, entry->condition, &err);
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00640)
                                  "Can't evaluate condition: %s", err);
                    continue;
                }
                if (!ret)
                    continue;
            }
            msg = ap_expr_str_exec(r, entry->msg_expr, &err);
            if (err)
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00641)
                              "Can't evaluate message expression: %s", err);
            if (APLOGrdebug(r))
                /* Intentional no APLOGNO */
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                               "%s (%s hook, %s:%d)",
                               msg, hookname, entry->msg_expr->filename,
                               entry->msg_expr->line_number);
            else
                /* Intentional no APLOGNO */
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                              "%s", msg);
        }
    }
    
    static int log_debug_log_transaction(request_rec *r)
    {
        do_debug_log(r, hooks[0]);
        return DECLINED;
    }
    
    static int log_debug_quick_handler(request_rec *r, int lookup_uri)
    {
        do_debug_log(r, hooks[1]);
        return DECLINED;
    }
    
    static int log_debug_handler(request_rec *r)
    {
        do_debug_log(r, hooks[2]);
        return DECLINED;
    }
    
    static int log_debug_pre_translate_name(request_rec *r)
    {
        do_debug_log(r, hooks[12]);
        return DECLINED;
    }
    
    static int log_debug_translate_name(request_rec *r)
    {
        do_debug_log(r, hooks[3]);
        return DECLINED;
    }
    
    static int log_debug_map_to_storage(request_rec *r)
    {
        do_debug_log(r, hooks[4]);
        return DECLINED;
    }
    
    static int log_debug_fixups(request_rec *r)
    {
        do_debug_log(r, hooks[5]);
        return DECLINED;
    }
    
    static int log_debug_type_checker(request_rec *r)
    {
        do_debug_log(r, hooks[6]);
        return DECLINED;
    }
    
    static int log_debug_check_access(request_rec *r)
    {
        do_debug_log(r, hooks[7]);
        return DECLINED;
    }
    
    static int log_debug_check_access_ex(request_rec *r)
    {
        do_debug_log(r, hooks[8]);
        return DECLINED;
    }
    
    static int log_debug_check_authn(request_rec *r)
    {
        do_debug_log(r, hooks[9]);
        return DECLINED;
    }
    
    static int log_debug_check_authz(request_rec *r)
    {
        do_debug_log(r, hooks[10]);
        return DECLINED;
    }
    
    static void log_debug_insert_filter(request_rec *r)
    {
        do_debug_log(r, hooks[11]);
    }
    
    static void *log_debug_create_dconf(apr_pool_t *p, char *dirspec)
    {
        log_debug_dirconf *dconf = apr_pcalloc(p, sizeof(log_debug_dirconf));
        return dconf;
    }
    
    static void *log_debug_merge_dconf(apr_pool_t *p, void *parent_conf, void *new_conf)
    {
        log_debug_dirconf *merged = apr_pcalloc(p, sizeof(log_debug_dirconf));
        const log_debug_dirconf *parent = parent_conf;
        const log_debug_dirconf *new = new_conf;
    
        if (parent->entries == NULL)
            merged->entries = new->entries;
        else if (new->entries == NULL)
            merged->entries = parent->entries;
        else
            /* apr_array_append actually creates a new array */
            merged->entries = apr_array_append(p, parent->entries, new->entries);
    
        return merged;
    }
    
    static const char *cmd_log_message(cmd_parms *cmd, void *dconf_, const char *arg1,
                                       const char *arg2, const char *arg3)
    {
        msg_entry *entry = apr_pcalloc(cmd->pool, sizeof(msg_entry));
        log_debug_dirconf *dconf = dconf_;
        int i, j;
        const char *err;
        const char *args[2];
        args[0] = arg2;
        args[1] = arg3;
    
        entry->msg_expr = ap_expr_parse_cmd(cmd, arg1, AP_EXPR_FLAG_STRING_RESULT|
                                                       AP_EXPR_FLAG_DONT_VARY,
                                            &err, NULL);
        if (err)
            return apr_psprintf(cmd->pool,
                                "Could not parse message expression '%s': %s",
                                arg1, err);
    
        for (i = 0; i < 2; i++) {
            if (args[i] == NULL)
                break;
    
            if (strncasecmp(args[i], "hook=", 5) == 0) {
                const char *name = args[i] + 5;
                j = 0;
                while (hooks[j]) {
                    if (strcasecmp(hooks[j], name) == 0) {
                        entry->hook = hooks[j];
                        break;
                    }
                    j++;
                }
                if (entry->hook == NULL) {
                    if (strcmp(name, "*") == 0 || strcasecmp(name, allhooks) == 0)
                        entry->hook = allhooks;
                    else
                        return apr_psprintf(cmd->pool, "Invalid hook name: %s", name);
                }
            }
            else if (strncasecmp(args[i], "expr=", 5) == 0) {
                const char *expr = args[i] + 5;
                entry->condition = ap_expr_parse_cmd(cmd, expr,
                                                     AP_EXPR_FLAG_DONT_VARY,
                                                     &err, NULL);
                if (err)
                    return apr_psprintf(cmd->pool,
                                        "Could not parse expression '%s': %s",
                                        expr, err);
            }
            else {
                return apr_psprintf(cmd->pool, "Invalid argument %s", args[i]);
            }
        }
        if (entry->hook == NULL)
            entry->hook = hooks[0];
    
        if (!dconf->entries)
            dconf->entries = apr_array_make(cmd->pool, 4, sizeof(msg_entry *));
    
        APR_ARRAY_PUSH(dconf->entries, msg_entry *) = entry;
    
        return NULL;
    }
    
    static const command_rec log_debug_cmds[] =
    {
        AP_INIT_TAKE123("LogMessage", cmd_log_message, NULL, RSRC_CONF|ACCESS_CONF,
            "Log a debug message to the error log if this config block is used for "
            " a request"),
        {NULL}
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_log_transaction(log_debug_log_transaction, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_quick_handler(log_debug_quick_handler, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_handler(log_debug_handler, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_pre_translate_name(log_debug_pre_translate_name, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_translate_name(log_debug_translate_name, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_map_to_storage(log_debug_map_to_storage, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_fixups(log_debug_fixups, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_type_checker(log_debug_type_checker, NULL, NULL, APR_HOOK_FIRST);
        ap_hook_check_access(log_debug_check_access, NULL, NULL, APR_HOOK_FIRST, AP_AUTH_INTERNAL_PER_URI);
        ap_hook_check_access_ex(log_debug_check_access_ex, NULL, NULL, APR_HOOK_FIRST, AP_AUTH_INTERNAL_PER_URI);
        ap_hook_check_authn(log_debug_check_authn, NULL, NULL, APR_HOOK_FIRST, AP_AUTH_INTERNAL_PER_URI);
        ap_hook_check_authz(log_debug_check_authz, NULL, NULL, APR_HOOK_FIRST, AP_AUTH_INTERNAL_PER_URI);
        ap_hook_insert_filter(log_debug_insert_filter, NULL, NULL, APR_HOOK_FIRST);
    }
    
    AP_DECLARE_MODULE(log_debug) =
    {
        STANDARD20_MODULE_STUFF,
        log_debug_create_dconf,     /* create per-dir config */
        log_debug_merge_dconf,      /* merge per-dir config */
        NULL,                       /* server config */
        NULL,                       /* merge server config */
        log_debug_cmds,             /* command apr_table_t */
        register_hooks              /* register hooks */
    };
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_forensic.mak���������������������������������������������������0000664�0001751�0001751�00000024425�12701473373�021754� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_log_forensic.dsp
    !IF "$(CFG)" == ""
    CFG=mod_log_forensic - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_log_forensic - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_log_forensic - Win32 Release" && "$(CFG)" != "mod_log_forensic - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_forensic - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_log_forensic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_log_forensic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_log_forensic.obj"
    	-@erase "$(INTDIR)\mod_log_forensic.res"
    	-@erase "$(INTDIR)\mod_log_forensic_src.idb"
    	-@erase "$(INTDIR)\mod_log_forensic_src.pdb"
    	-@erase "$(OUTDIR)\mod_log_forensic.exp"
    	-@erase "$(OUTDIR)\mod_log_forensic.lib"
    	-@erase "$(OUTDIR)\mod_log_forensic.pdb"
    	-@erase "$(OUTDIR)\mod_log_forensic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_log_forensic_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_log_forensic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_log_forensic.so" /d LONG_NAME="log_forensic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_log_forensic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_log_forensic.pdb" /debug /out:"$(OUTDIR)\mod_log_forensic.so" /implib:"$(OUTDIR)\mod_log_forensic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_log_forensic.obj" \
    	"$(INTDIR)\mod_log_forensic.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_log_forensic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_log_forensic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_log_forensic.so"
       if exist .\Release\mod_log_forensic.so.manifest mt.exe -manifest .\Release\mod_log_forensic.so.manifest -outputresource:.\Release\mod_log_forensic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_log_forensic - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_log_forensic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_log_forensic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_log_forensic.obj"
    	-@erase "$(INTDIR)\mod_log_forensic.res"
    	-@erase "$(INTDIR)\mod_log_forensic_src.idb"
    	-@erase "$(INTDIR)\mod_log_forensic_src.pdb"
    	-@erase "$(OUTDIR)\mod_log_forensic.exp"
    	-@erase "$(OUTDIR)\mod_log_forensic.lib"
    	-@erase "$(OUTDIR)\mod_log_forensic.pdb"
    	-@erase "$(OUTDIR)\mod_log_forensic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_log_forensic_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_log_forensic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_log_forensic.so" /d LONG_NAME="log_forensic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_log_forensic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_log_forensic.pdb" /debug /out:"$(OUTDIR)\mod_log_forensic.so" /implib:"$(OUTDIR)\mod_log_forensic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_log_forensic.obj" \
    	"$(INTDIR)\mod_log_forensic.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_log_forensic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_log_forensic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_log_forensic.so"
       if exist .\Debug\mod_log_forensic.so.manifest mt.exe -manifest .\Debug\mod_log_forensic.so.manifest -outputresource:.\Debug\mod_log_forensic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_log_forensic.dep")
    !INCLUDE "mod_log_forensic.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_log_forensic.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_log_forensic - Win32 Release" || "$(CFG)" == "mod_log_forensic - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_log_forensic - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_forensic - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_forensic - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\loggers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_forensic - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\loggers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_forensic - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_forensic - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_log_forensic - Win32 Release"
    
    
    "$(INTDIR)\mod_log_forensic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_log_forensic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_log_forensic.so" /d LONG_NAME="log_forensic_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_log_forensic - Win32 Debug"
    
    
    "$(INTDIR)\mod_log_forensic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_log_forensic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_log_forensic.so" /d LONG_NAME="log_forensic_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_log_forensic.c
    
    "$(INTDIR)\mod_log_forensic.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_forensic.c�����������������������������������������������������0000664�0001751�0001751�00000017127�14300512413�021411� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <tbird precision-guesswork.com>, 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 <unistd.h>
    #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, APLOGNO(00650)
                             "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, APLOGNO(00651)
                             "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(*p, T_ESCAPE_FORENSIC)) {
                ap_assert(q+2 < e);
                *q++ = '%';
                ap_bin2hex(p, 1, q);
                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 apr_size_t count_string(const char *p)
    {
        apr_size_t n;
    
        for (n = 0 ; *p ; ++p, ++n)
            if (TEST_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, "%" APR_PID_T_FMT ":%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 || id == NULL) {
            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);
    }
    
    AP_DECLARE_MODULE(log_forensic) =
    {
        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 */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_debug.mak������������������������������������������������������0000664�0001751�0001751�00000021670�12701473373�021231� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_log_debug.dsp
    !IF "$(CFG)" == ""
    CFG=mod_log_debug - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_log_debug - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_log_debug - Win32 Release" && "$(CFG)" != "mod_log_debug - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_debug.mak" CFG="mod_log_debug - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_log_debug - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_log_debug - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_debug - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_log_debug.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_log_debug.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_log_debug.obj"
    	-@erase "$(INTDIR)\mod_log_debug.res"
    	-@erase "$(INTDIR)\mod_log_debug_src.idb"
    	-@erase "$(INTDIR)\mod_log_debug_src.pdb"
    	-@erase "$(OUTDIR)\mod_log_debug.exp"
    	-@erase "$(OUTDIR)\mod_log_debug.lib"
    	-@erase "$(OUTDIR)\mod_log_debug.pdb"
    	-@erase "$(OUTDIR)\mod_log_debug.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_log_debug_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_log_debug.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_log_debug.so" /d LONG_NAME="log_debug_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_log_debug.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_log_debug.pdb" /debug /out:"$(OUTDIR)\mod_log_debug.so" /implib:"$(OUTDIR)\mod_log_debug.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_log_debug.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_log_debug.obj" \
    	"$(INTDIR)\mod_log_debug.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_log_debug.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_log_debug.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_log_debug.so"
       if exist .\Release\mod_log_debug.so.manifest mt.exe -manifest .\Release\mod_log_debug.so.manifest -outputresource:.\Release\mod_log_debug.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_log_debug - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_log_debug.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_log_debug.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_log_debug.obj"
    	-@erase "$(INTDIR)\mod_log_debug.res"
    	-@erase "$(INTDIR)\mod_log_debug_src.idb"
    	-@erase "$(INTDIR)\mod_log_debug_src.pdb"
    	-@erase "$(OUTDIR)\mod_log_debug.exp"
    	-@erase "$(OUTDIR)\mod_log_debug.lib"
    	-@erase "$(OUTDIR)\mod_log_debug.pdb"
    	-@erase "$(OUTDIR)\mod_log_debug.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_log_debug_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_log_debug.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_log_debug.so" /d LONG_NAME="log_debug_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_log_debug.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_log_debug.pdb" /debug /out:"$(OUTDIR)\mod_log_debug.so" /implib:"$(OUTDIR)\mod_log_debug.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_log_debug.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_log_debug.obj" \
    	"$(INTDIR)\mod_log_debug.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_log_debug.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_log_debug.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_log_debug.so"
       if exist .\Debug\mod_log_debug.so.manifest mt.exe -manifest .\Debug\mod_log_debug.so.manifest -outputresource:.\Debug\mod_log_debug.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_log_debug.dep")
    !INCLUDE "mod_log_debug.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_log_debug.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_log_debug - Win32 Release" || "$(CFG)" == "mod_log_debug - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_log_debug - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_debug - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_log_debug - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_log_debug - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_log_debug - Win32 Release"
    
    
    "$(INTDIR)\mod_log_debug.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_log_debug.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_log_debug.so" /d LONG_NAME="log_debug_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_log_debug - Win32 Debug"
    
    
    "$(INTDIR)\mod_log_debug.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_log_debug.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_log_debug.so" /d LONG_NAME="log_debug_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_log_debug.c
    
    "$(INTDIR)\mod_log_debug.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_config.dep�����������������������������������������������������0000664�0001751�0001751�00000004313�12674411515�021402� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_log_config.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_log_config.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_time.h"\
    	"..\..\srclib\apr-util\include\apr_anylock.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_log_config.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_debug.dsp������������������������������������������������������0000664�0001751�0001751�00000010715�12062614564�021244� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_log_debug" - 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_debug - 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_debug.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_debug.mak" CFG="mod_log_debug - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_log_debug - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_log_debug - 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_debug - 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_debug_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 /fo"Release/mod_log_debug.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_log_debug.so" /d LONG_NAME="log_debug_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_log_debug.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_debug.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_log_debug.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_debug.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_log_debug.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_log_debug - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_log_debug_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 /fo"Debug/mod_log_debug.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_log_debug.so" /d LONG_NAME="log_debug_module for Apache"
    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 /out:".\Debug\mod_log_debug.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_debug.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_log_debug.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_debug.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_log_debug.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_log_debug - Win32 Release"
    # Name "mod_log_debug - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_log_debug.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������httpd-2.4.64/modules/loggers/mod_logio.mak����������������������������������������������������������0000664�0001751�0001751�00000023211�12701473373�020404� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_logio.dsp
    !IF "$(CFG)" == ""
    CFG=mod_logio - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_logio - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_logio - Win32 Release" && "$(CFG)" != "mod_logio - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_logio - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_logio.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_logio.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_logio.obj"
    	-@erase "$(INTDIR)\mod_logio.res"
    	-@erase "$(INTDIR)\mod_logio_src.idb"
    	-@erase "$(INTDIR)\mod_logio_src.pdb"
    	-@erase "$(OUTDIR)\mod_logio.exp"
    	-@erase "$(OUTDIR)\mod_logio.lib"
    	-@erase "$(OUTDIR)\mod_logio.pdb"
    	-@erase "$(OUTDIR)\mod_logio.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_logio_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_logio.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_logio.so" /d LONG_NAME="logio_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_logio.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_logio.pdb" /debug /out:"$(OUTDIR)\mod_logio.so" /implib:"$(OUTDIR)\mod_logio.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_logio.obj" \
    	"$(INTDIR)\mod_logio.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_logio.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_logio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_logio.so"
       if exist .\Release\mod_logio.so.manifest mt.exe -manifest .\Release\mod_logio.so.manifest -outputresource:.\Release\mod_logio.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_logio - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_logio.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_logio.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_logio.obj"
    	-@erase "$(INTDIR)\mod_logio.res"
    	-@erase "$(INTDIR)\mod_logio_src.idb"
    	-@erase "$(INTDIR)\mod_logio_src.pdb"
    	-@erase "$(OUTDIR)\mod_logio.exp"
    	-@erase "$(OUTDIR)\mod_logio.lib"
    	-@erase "$(OUTDIR)\mod_logio.pdb"
    	-@erase "$(OUTDIR)\mod_logio.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_logio_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_logio.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_logio.so" /d LONG_NAME="logio_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_logio.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_logio.pdb" /debug /out:"$(OUTDIR)\mod_logio.so" /implib:"$(OUTDIR)\mod_logio.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_logio.obj" \
    	"$(INTDIR)\mod_logio.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_logio.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_logio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_logio.so"
       if exist .\Debug\mod_logio.so.manifest mt.exe -manifest .\Debug\mod_logio.so.manifest -outputresource:.\Debug\mod_logio.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_logio.dep")
    !INCLUDE "mod_logio.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_logio.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_logio - Win32 Release" || "$(CFG)" == "mod_logio - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_logio - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_logio - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\loggers"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_logio - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\loggers"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_logio - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\loggers"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\loggers"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_logio - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ELSEIF  "$(CFG)" == "mod_logio - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\loggers"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\loggers"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_logio - Win32 Release"
    
    
    "$(INTDIR)\mod_logio.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_logio.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_logio.so" /d LONG_NAME="logio_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_logio - Win32 Debug"
    
    
    "$(INTDIR)\mod_logio.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_logio.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_logio.so" /d LONG_NAME="logio_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_logio.c
    
    "$(INTDIR)\mod_logio.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_logio.dep����������������������������������������������������������0000664�0001751�0001751�00000004117�12674411515�020407� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_logio.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_logio.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_log_config.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/NWGNUlogdebug����������������������������������������������������������0000664�0001751�0001751�00000010402�11605024175�020264� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/modules/http \
    			$(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	= logdebug
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Debug Logging Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Logdbg 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	=
    
    #
    # 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)/$(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_log_debug.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	log_debug_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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_forensic.dsp���������������������������������������������������0000664�0001751�0001751�00000011113�10551346420�021751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_log_forensic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_log_forensic.so" /d LONG_NAME="log_forensic_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_log_forensic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_log_forensic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_log_forensic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_log_forensic.so" /d LONG_NAME="log_forensic_module for Apache"
    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 /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 /out:".\Debug\mod_log_forensic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_log_forensic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_forensic.exp���������������������������������������������������0000664�0001751�0001751�00000000024�10150161574�021756� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������log_forensic_module
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/NWGNUmakefile����������������������������������������������������������0000664�0001751�0001751�00000010003�11605024175�020246� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    	$(OBJDIR)/logdebug.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_config.dsp�����������������������������������������������������0000664�0001751�0001751�00000010753�10551346420�021417� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_log_config.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_log_config.so" /d LONG_NAME="log_config_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_log_config.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_log_config.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_log_config.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_log_config.so" /d LONG_NAME="log_config_module for Apache"
    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 /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 /out:".\Debug\mod_log_config.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_log_config.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������httpd-2.4.64/modules/loggers/mod_log_forensic.dep���������������������������������������������������0000664�0001751�0001751�00000003614�12674411515�021750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_log_forensic.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_log_forensic.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\server\test_char.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_atomic.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/config.m4��������������������������������������������������������������0000664�0001751�0001751�00000001257�11607365420�017454� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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.  You won't be able to log requests to the server without this module., , , yes)
    APACHE_MODULE(log_debug, configurable debug logging, , , most)
    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)
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/NWGNUmodlogio����������������������������������������������������������0000664�0001751�0001751�00000010360�11540562746�020321� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/modules/http \
    			$(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	= 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	=
    
    #
    # 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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_config.exp�����������������������������������������������������0000664�0001751�0001751�00000000022�10150161574�021411� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������log_config_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_debug.dep������������������������������������������������������0000664�0001751�0001751�00000003655�12674411515�021233� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_log_debug.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_log_debug.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_log_config.h�������������������������������������������������������0000664�0001751�0001751�00000004665�11637105701�021066� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_log_config.h
     * @brief Logging Configuration Extension Module for Apache
     *
     * @defgroup MOD_LOG_CONFIG mod_log_config
     * @ingroup APACHE_MODS
     * @{
     */
    
    #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 */
    /** @} */
    
    ���������������������������������������������������������������������������httpd-2.4.64/modules/loggers/NWGNUforensic����������������������������������������������������������0000664�0001751�0001751�00000010412�11540562746�020316� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/modules/http \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/mod_logio.dsp����������������������������������������������������������0000664�0001751�0001751�00000010525�10551346420�020417� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_logio.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_logio.so" /d LONG_NAME="logio_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_logio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_logio.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_logio.so" /d LONG_NAME="logio_module for Apache"
    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 /out:".\Debug\mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_logio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/.indent.pro������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�020022� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/loggers/Makefile.in������������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�017775� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/���������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015026� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_file.dsp���������������������������������������������������������0000664�0001751�0001751�00000011045�10551346420�020502� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authn_file.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache"
    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 /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 /out:".\Debug\mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authn_file.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthndbd��������������������������������������������������������������0000664�0001751�0001751�00000010237�11540546347�017363� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(NWOS) \
    			$(AP_WORK)/modules/database \
    			$(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	= authndbd
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) SQL Database Authentication Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= AuthnDBD 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	=
    
    #
    # 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)/authndbd.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_dbd.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	authn_dbd_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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_host.mak���������������������������������������������������������0000664�0001751�0001751�00000025706�12701473373�020556� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_host.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authz_host - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authz_host - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authz_host - Win32 Release" && "$(CFG)" != "mod_authz_host - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_host - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_host.obj"
    	-@erase "$(INTDIR)\mod_authz_host.res"
    	-@erase "$(INTDIR)\mod_authz_host_src.idb"
    	-@erase "$(INTDIR)\mod_authz_host_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_host.exp"
    	-@erase "$(OUTDIR)\mod_authz_host.lib"
    	-@erase "$(OUTDIR)\mod_authz_host.pdb"
    	-@erase "$(OUTDIR)\mod_authz_host.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_host_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_host.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_host.pdb" /debug /out:"$(OUTDIR)\mod_authz_host.so" /implib:"$(OUTDIR)\mod_authz_host.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_host.obj" \
    	"$(INTDIR)\mod_authz_host.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_host.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authz_host.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_host.so"
       if exist .\Release\mod_authz_host.so.manifest mt.exe -manifest .\Release\mod_authz_host.so.manifest -outputresource:.\Release\mod_authz_host.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authz_host - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_host.obj"
    	-@erase "$(INTDIR)\mod_authz_host.res"
    	-@erase "$(INTDIR)\mod_authz_host_src.idb"
    	-@erase "$(INTDIR)\mod_authz_host_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_host.exp"
    	-@erase "$(OUTDIR)\mod_authz_host.lib"
    	-@erase "$(OUTDIR)\mod_authz_host.pdb"
    	-@erase "$(OUTDIR)\mod_authz_host.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_host_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_host.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_host.pdb" /debug /out:"$(OUTDIR)\mod_authz_host.so" /implib:"$(OUTDIR)\mod_authz_host.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_host.obj" \
    	"$(INTDIR)\mod_authz_host.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_host.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authz_host.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_host.so"
       if exist .\Debug\mod_authz_host.so.manifest mt.exe -manifest .\Debug\mod_authz_host.so.manifest -outputresource:.\Debug\mod_authz_host.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authz_host.dep")
    !INCLUDE "mod_authz_host.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authz_host.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authz_host - Win32 Release" || "$(CFG)" == "mod_authz_host - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authz_host - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_host - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_host - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_host - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_host - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_host - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_host - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authz_host - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authz_host - Win32 Release"
    
    
    "$(INTDIR)\mod_authz_host.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authz_host - Win32 Debug"
    
    
    "$(INTDIR)\mod_authz_host.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authz_host.c
    
    "$(INTDIR)\mod_authz_host.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUallowmethods����������������������������������������������������������0000664�0001751�0001751�00000010207�11540546347�020271� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= allowmethods
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Method Restriction Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Allowmethods 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	=
    
    #
    # 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)/allowmethods.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_allowmethods.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	allowmethods_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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/Makefile.in����������������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�017055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_basic.dsp���������������������������������������������������������0000664�0001751�0001751�00000011125�10551346420�020465� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_auth_basic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache"
    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 /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 /out:".\Debug\mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_auth_basic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbm.mak����������������������������������������������������������0000664�0001751�0001751�00000025554�12701473373�020344� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_dbm.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authz_dbm - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authz_dbm - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authz_dbm - Win32 Release" && "$(CFG)" != "mod_authz_dbm - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbm - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_dbm.obj"
    	-@erase "$(INTDIR)\mod_authz_dbm.res"
    	-@erase "$(INTDIR)\mod_authz_dbm_src.idb"
    	-@erase "$(INTDIR)\mod_authz_dbm_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbm.exp"
    	-@erase "$(OUTDIR)\mod_authz_dbm.lib"
    	-@erase "$(OUTDIR)\mod_authz_dbm.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbm_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbm.so" /implib:"$(OUTDIR)\mod_authz_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_dbm.obj" \
    	"$(INTDIR)\mod_authz_dbm.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authz_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbm.so"
       if exist .\Release\mod_authz_dbm.so.manifest mt.exe -manifest .\Release\mod_authz_dbm.so.manifest -outputresource:.\Release\mod_authz_dbm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbm - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_dbm.obj"
    	-@erase "$(INTDIR)\mod_authz_dbm.res"
    	-@erase "$(INTDIR)\mod_authz_dbm_src.idb"
    	-@erase "$(INTDIR)\mod_authz_dbm_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbm.exp"
    	-@erase "$(OUTDIR)\mod_authz_dbm.lib"
    	-@erase "$(OUTDIR)\mod_authz_dbm.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbm_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbm.so" /implib:"$(OUTDIR)\mod_authz_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_dbm.obj" \
    	"$(INTDIR)\mod_authz_dbm.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authz_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbm.so"
       if exist .\Debug\mod_authz_dbm.so.manifest mt.exe -manifest .\Debug\mod_authz_dbm.so.manifest -outputresource:.\Debug\mod_authz_dbm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authz_dbm.dep")
    !INCLUDE "mod_authz_dbm.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authz_dbm.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authz_dbm - Win32 Release" || "$(CFG)" == "mod_authz_dbm - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authz_dbm - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbm - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbm - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbm - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbm - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbm - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbm - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbm - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authz_dbm - Win32 Release"
    
    
    "$(INTDIR)\mod_authz_dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbm - Win32 Debug"
    
    
    "$(INTDIR)\mod_authz_dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authz_dbm.c
    
    "$(INTDIR)\mod_authz_dbm.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_digest.dep��������������������������������������������������������0000664�0001751�0001751�00000004732�12674411515�020661� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_auth_digest.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_auth_digest.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_md5.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_anylock.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_rmm.h"\
    	"..\..\srclib\apr-util\include\apr_sha1.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbm.dep����������������������������������������������������������0000664�0001751�0001751�00000004266�12674411515�020324� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authn_dbm.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authn_dbm.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_anon.dep���������������������������������������������������������0000664�0001751�0001751�00000004062�12674411515�020507� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authn_anon.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authn_anon.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_file.dep���������������������������������������������������������0000664�0001751�0001751�00000004214�12674411515�020472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authn_file.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authn_file.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_user.dsp���������������������������������������������������������0000664�0001751�0001751�00000011045�10551346420�020555� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authz_user.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache"
    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 /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 /out:".\Debug\mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authz_user.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_socache.dep������������������������������������������������������0000664�0001751�0001751�00000004320�12674411515�021156� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authn_socache.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authn_socache.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_socache.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_groupfile.dep����������������������������������������������������0000664�0001751�0001751�00000004233�12674411515�021564� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authz_groupfile.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authz_groupfile.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_authz_owner.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthzdbm��������������������������������������������������������������0000664�0001751�0001751�00000010172�11540546347�017406� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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		= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbm.dsp����������������������������������������������������������0000664�0001751�0001751�00000011007�10551346420�020323� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authn_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache"
    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 /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 /out:".\Debug\mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authn_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_core.c�����������������������������������������������������������0000664�0001751�0001751�00000034366�14357011702�020162� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #define APR_WANT_STRFUNC
    #define APR_WANT_BYTEFUNC
    #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_request.h"
    #include "http_protocol.h"
    #include "ap_expr.h"
    #include "ap_provider.h"
    
    #include "mod_auth.h"
    
    #if APR_HAVE_NETINET_IN_H
    #include <netinet/in.h>
    #endif
    
    /* TODO List
    
    - Track down all of the references to r->ap_auth_type
       and change them to ap_auth_type()
    - Remove ap_auth_type and ap_auth_name from the
       request_rec
    
    */
    
    typedef struct {
        ap_expr_info_t *ap_auth_type;
        int auth_type_set;
        ap_expr_info_t *ap_auth_name;
    } authn_core_dir_conf;
    
    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_core_module;
    
    static void *create_authn_core_dir_config(apr_pool_t *p, char *dummy)
    {
        authn_core_dir_conf *conf =
                (authn_core_dir_conf *)apr_pcalloc(p, sizeof(authn_core_dir_conf));
    
        return (void *)conf;
    }
    
    static void *merge_authn_core_dir_config(apr_pool_t *a, void *basev, void *newv)
    {
        authn_core_dir_conf *base = (authn_core_dir_conf *)basev;
        authn_core_dir_conf *new = (authn_core_dir_conf *)newv;
        authn_core_dir_conf *conf =
            (authn_core_dir_conf *)apr_pcalloc(a, sizeof(authn_core_dir_conf));
    
        if (new->auth_type_set) {
            conf->ap_auth_type = new->ap_auth_type;
            conf->auth_type_set = 1;
        }
        else {
            conf->ap_auth_type = base->ap_auth_type;
            conf->auth_type_set = base->auth_type_set;
        }
    
        if (new->ap_auth_name) {
            conf->ap_auth_name = new->ap_auth_name;
        } else {
            conf->ap_auth_name = base->ap_auth_name;
        }
    
        return (void*)conf;
    }
    
    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 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_core_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 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_core_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;
    }
    
    /* Only per-server directive we have is GLOBAL_ONLY */
    static void *merge_authn_alias_svr_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        return basev;
    }
    
    static const authn_provider authn_alias_provider =
    {
        &authn_alias_check_password,
        &authn_alias_get_realm_hash,
    };
    
    static const authn_provider authn_alias_provider_nodigest =
    {
        &authn_alias_check_password,
        NULL,
    };
    
    static const char *authaliassection(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        const char *endp = ap_strrchr_c(arg, '>');
        const char *args;
        char *provider_alias;
        char *provider_name;
        int old_overrides = cmd->override;
        const char *errmsg;
        const authn_provider *provider = NULL;
        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_core_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->temp_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);
        }
    
        if (strcasecmp(provider_name, provider_alias) == 0) {
            return apr_pstrcat(cmd->pool,
                               "The alias provider name must be different from the base provider name.", NULL);
        }
    
        /* Look up the alias provider to make sure that it hasn't already been registered. */
        provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, provider_alias,
                                      AUTHN_PROVIDER_VERSION);
        if (provider) {
            return apr_pstrcat(cmd->pool, "The alias provider ", provider_alias,
                               " has already be registered previously as either a base provider or an alias provider.",
                               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_AUTHCFG | ACCESS_CONF;
        errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_auth_config);
        cmd->override = old_overrides;
    
        if (!errmsg) {
            provider_alias_rec *prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(provider_alias_rec));
            provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, provider_name,
                                          AUTHN_PROVIDER_VERSION);
    
            if (!provider) {
                /* by the time they use it, the provider should be loaded and
                   registered with us. */
                return apr_psprintf(cmd->pool,
                                    "Unknown Authn provider: %s",
                                    provider_name);
            }
    
            /* 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_auth_provider(cmd->pool, AUTHN_PROVIDER_GROUP,
                                      provider_alias, AUTHN_PROVIDER_VERSION,
                                      provider->get_realm_hash ?
                                          &authn_alias_provider :
                                          &authn_alias_provider_nodigest,
                                      AP_AUTH_INTERNAL_PER_CONF);
        }
    
        return errmsg;
    }
    
    /*
     * 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)
    {
        authn_core_dir_conf *aconfig = (authn_core_dir_conf *)mconfig;
        const char *expr_err = NULL;
    
        aconfig->ap_auth_name = ap_expr_parse_cmd(cmd, word1, AP_EXPR_FLAG_STRING_RESULT,
                &expr_err, NULL);
        if (expr_err) {
            return apr_pstrcat(cmd->temp_pool,
                    "Cannot parse expression '", word1, "' in AuthName: ",
                          expr_err, NULL);
        }
    
        return NULL;
    }
    
    static const char *set_authtype(cmd_parms *cmd, void *mconfig,
                                    const char *word1)
    {
        authn_core_dir_conf *aconfig = (authn_core_dir_conf *)mconfig;
        const char *expr_err = NULL;
    
        aconfig->ap_auth_type = ap_expr_parse_cmd(cmd, word1, AP_EXPR_FLAG_STRING_RESULT,
                &expr_err, NULL);
        if (expr_err) {
            return apr_pstrcat(cmd->temp_pool,
                    "Cannot parse expression '", word1, "' in AuthType: ",
                          expr_err, NULL);
        }
    
        aconfig->auth_type_set = 1;
    
        return NULL;
    }
    
    static const char *authn_ap_auth_type(request_rec *r)
    {
        authn_core_dir_conf *conf;
    
        conf = (authn_core_dir_conf *) ap_get_module_config(r->per_dir_config,
                &authn_core_module);
    
        if (conf->ap_auth_type) {
            const char *err = NULL, *type;
            type = ap_expr_str_exec(r, conf->ap_auth_type, &err);
            if (err) {
                ap_log_rerror(
                        APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(02834) "AuthType expression could not be evaluated: %s", err);
                return NULL;
            }
    
            return strcasecmp(type, "None") ? type : NULL;
        }
    
        return NULL;
    }
    
    static const char *authn_ap_auth_name(request_rec *r)
    {
        authn_core_dir_conf *conf;
        const char *err = NULL, *name;
    
        conf = (authn_core_dir_conf *) ap_get_module_config(r->per_dir_config,
                &authn_core_module);
    
        if (conf->ap_auth_name) {
            name = ap_expr_str_exec(r, conf->ap_auth_name, &err);
            if (err) {
                ap_log_rerror(
                        APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(02835) "AuthName expression could not be evaluated: %s", err);
                return NULL;
            }
    
            return ap_escape_quotes(r->pool, name);
        }
    
        return NULL;
    }
    
    static const command_rec authn_cmds[] =
    {
        AP_INIT_TAKE1("AuthType", set_authtype, NULL, OR_AUTHCFG,
                      "an HTTP authorization type (e.g., \"Basic\")"),
        AP_INIT_TAKE1("AuthName", set_authname, NULL, OR_AUTHCFG,
                      "the authentication realm (e.g. \"Members Only\")"),
        AP_INIT_RAW_ARGS("<AuthnProviderAlias", authaliassection, NULL, RSRC_CONF,
                         "container for grouping an authentication provider's "
                         "directives under a provider alias"),
        {NULL}
    };
    
    static int authenticate_no_user(request_rec *r)
    {
        /* if there isn't an AuthType, then assume that no authentication
            is required so return OK */
        if (!ap_auth_type(r)) {
            return OK;
        }
    
        /* there's an AuthType configured, but no authentication module
         * loaded to support it
         */
        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01796)
                      "AuthType %s configured without corresponding module",
                      ap_auth_type(r));
    
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(authn_ap_auth_type);
        APR_REGISTER_OPTIONAL_FN(authn_ap_auth_name);
    
        ap_hook_check_authn(authenticate_no_user, NULL, NULL, APR_HOOK_LAST,
                            AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(authn_core) =
    {
        STANDARD20_MODULE_STUFF,
        create_authn_core_dir_config,   /* dir config creater */
        merge_authn_core_dir_config,    /* dir merger --- default is to override */
        create_authn_alias_svr_config,  /* server config */
        merge_authn_alias_svr_config,   /* merge server config */
        authn_cmds,
        register_hooks                  /* register hooks */
    };
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthzusr��������������������������������������������������������������0000664�0001751�0001751�00000010167�11540546347�017461� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_ldap.dep��������������������������������������������������������0000664�0001751�0001751�00000005127�12674411515�020671� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authnz_ldap.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authnz_ldap.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_ldap.h"\
    	"..\..\srclib\apr-util\include\apr_anylock.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_ldap.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_init.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_option.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_rebind.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_url.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_rmm.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthbasc��������������������������������������������������������������0000664�0001751�0001751�00000010172�11540546347�017362� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbd.dep����������������������������������������������������������0000664�0001751�0001751�00000004214�12674411515�020320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authz_dbd.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authz_dbd.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbd.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\database\mod_dbd.h"\
    	".\mod_authz_dbd.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_user.c�����������������������������������������������������������0000664�0001751�0001751�00000010710�12267522020�020205� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "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 {
            int dummy;  /* just here to stop compiler warnings for now. */
    } 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));
    
        return conf;
    }
    
    static const command_rec authz_user_cmds[] =
    {
        {NULL}
    };
    
    module AP_MODULE_DECLARE_DATA authz_user_module;
    
    static authz_status user_check_authorization(request_rec *r,
                                                 const char *require_args,
                                                 const void *parsed_require_args)
    {
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t, *w;
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02594)
                          "authz_user authorize: require user: Can't "
                          "evaluate require expression: %s", err);
            return AUTHZ_DENIED;
        }
    
        t = require;
        while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
            if (!strcmp(r->user, w)) {
                return AUTHZ_GRANTED;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01663)
                      "access to %s failed, reason: user '%s' does not meet "
                      "'require'ments for user to be allowed access",
                      r->uri, r->user);
    
        return AUTHZ_DENIED;
    }
    
    static authz_status validuser_check_authorization(request_rec *r,
                                                      const char *require_line,
                                                      const void *parsed_require_line)
    {
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        return AUTHZ_GRANTED;
    }
    
    static const char *user_parse_config(cmd_parms *cmd, const char *require_line,
                                         const void **parsed_require_line)
    {
        const char *expr_err = NULL;
        ap_expr_info_t *expr;
    
        expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
                &expr_err, NULL);
    
        if (expr_err)
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression in require line: ",
                               expr_err, NULL);
    
        *parsed_require_line = expr;
    
        return NULL;
    }
    
    static const authz_provider authz_user_provider =
    {
        &user_check_authorization,
        &user_parse_config,
    };
    static const authz_provider authz_validuser_provider =
    {
        &validuser_check_authorization,
        NULL,
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "user",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_user_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "valid-user",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_validuser_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(authz_user) =
    {
        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 */
    };
    ��������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_core.dep���������������������������������������������������������0000664�0001751�0001751�00000004062�12674411515�020504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authn_core.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authn_core.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_ldap.dsp��������������������������������������������������������0000664�0001751�0001751�00000011155�10551346420�020677� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authnz_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache"
    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 /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 /out:".\Debug\mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authnz_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_basic.c�����������������������������������������������������������0000664�0001751�0001751�00000042564�14601027034�020131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_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 "util_md5.h"
    #include "ap_provider.h"
    #include "ap_expr.h"
    
    #include "mod_auth.h"
    
    typedef struct {
        authn_provider_list *providers;
        char *dir; /* unused variable */
        int authoritative;
        ap_expr_info_t *fakeuser;
        ap_expr_info_t *fakepass;
        const char *use_digest_algorithm;
        unsigned int fake_set:1,
                     use_digest_algorithm_set:1,
                     authoritative_set:1;
    } 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));
    
        /* Any failures are fatal. */
        conf->authoritative = 1;
    
        return conf;
    }
    
    static void *merge_auth_basic_dir_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        auth_basic_config_rec *newconf = apr_pcalloc(p, sizeof(*newconf));
        auth_basic_config_rec *base = basev;
        auth_basic_config_rec *overrides = overridesv;
    
        newconf->authoritative =
                overrides->authoritative_set ? overrides->authoritative :
                        base->authoritative;
        newconf->authoritative_set = overrides->authoritative_set
                || base->authoritative_set;
    
        newconf->fakeuser =
                overrides->fake_set ? overrides->fakeuser : base->fakeuser;
        newconf->fakepass =
                overrides->fake_set ? overrides->fakepass : base->fakepass;
        newconf->fake_set = overrides->fake_set || base->fake_set;
    
        newconf->use_digest_algorithm =
            overrides->use_digest_algorithm_set ? overrides->use_digest_algorithm
                                                : base->use_digest_algorithm;
        newconf->use_digest_algorithm_set =
            overrides->use_digest_algorithm_set || base->use_digest_algorithm_set;
    
        newconf->providers = overrides->providers ? overrides->providers : base->providers;
    
        return newconf;
    }
    
    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;
    
        newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
        newp->provider_name = arg;
    
        /* lookup and cache the actual provider now */
        newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
                                            newp->provider_name,
                                            AUTHN_PROVIDER_VERSION);
    
        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", newp->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_authoritative(cmd_parms * cmd, void *config, int flag)
    {
        auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
    
        conf->authoritative = flag;
        conf->authoritative_set = 1;
    
        return NULL;
    }
    
    static const char *add_basic_fake(cmd_parms * cmd, void *config,
            const char *user, const char *pass)
    {
        auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
        const char *err;
    
        if (!strcasecmp(user, "off")) {
            conf->fakeuser = NULL;
            conf->fakepass = NULL;
            conf->fake_set = 1;
        }
        else {
            /* if password is unspecified, set it to the fixed string "password" to
             * be compatible with the behaviour of mod_ssl.
             */
            if (!pass) {
                pass = "password";
            }
    
            conf->fakeuser =
                    ap_expr_parse_cmd(cmd, user, AP_EXPR_FLAG_STRING_RESULT,
                            &err, NULL);
            if (err) {
                return apr_psprintf(cmd->pool,
                        "Could not parse fake username expression '%s': %s", user,
                        err);
            }
            conf->fakepass =
                    ap_expr_parse_cmd(cmd, pass, AP_EXPR_FLAG_STRING_RESULT,
                            &err, NULL);
            if (err) {
                return apr_psprintf(cmd->pool,
                        "Could not parse fake password expression associated to user '%s': %s",
                        user, err);
            }
            conf->fake_set = 1;
        }
    
        return NULL;
    }
    
    static const char *set_use_digest_algorithm(cmd_parms *cmd, void *config,
                                                const char *alg)
    {
        auth_basic_config_rec *conf = (auth_basic_config_rec *)config;
    
        if (strcasecmp(alg, "Off") && strcasecmp(alg, "MD5")) {
            return apr_pstrcat(cmd->pool,
                               "Invalid algorithm in "
                               "AuthBasicUseDigestAlgorithm: ", alg, NULL);
        }
    
        conf->use_digest_algorithm = alg;
        conf->use_digest_algorithm_set = 1;
    
        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", set_authoritative, NULL, 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"),
        AP_INIT_TAKE12("AuthBasicFake", add_basic_fake, NULL, OR_AUTHCFG,
                      "Fake basic authentication using the given expressions for "
                      "username and password, 'off' to disable. Password defaults "
                      "to 'password' if missing."),
        AP_INIT_TAKE1("AuthBasicUseDigestAlgorithm", set_use_digest_algorithm,
                      NULL, OR_AUTHCFG,
                      "Set to 'MD5' to use the auth provider's authentication "
                      "check for digest auth, using a hash of 'user:realm:pass'"),
        {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 hook_note_basic_auth_failure(request_rec *r, const char *auth_type)
    {
        if (ap_cstr_casecmp(auth_type, "Basic"))
            return DECLINED;
    
        note_basic_auth_failure(r);
        return OK;
    }
    
    static int get_basic_auth(request_rec *r, const char **user,
                              const char **pw)
    {
        const char *auth_line;
        char *decoded_line;
    
        /* 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 (ap_cstr_casecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
            /* Client tried to authenticate using wrong auth scheme */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01614)
                          "client used wrong authentication scheme: %s", r->uri);
            note_basic_auth_failure(r);
            return HTTP_UNAUTHORIZED;
        }
    
        /* Skip leading spaces. */
        while (*auth_line == ' ' || *auth_line == '\t') {
            auth_line++;
        }
    
        decoded_line = ap_pbase64decode(r->pool, auth_line);
    
        *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;
        const char *realm = NULL;
        const char *digest = NULL;
        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 || ap_cstr_casecmp(current_auth, "Basic")) {
            return DECLINED;
        }
    
        /* We need an authentication realm. */
        if (!ap_auth_name(r)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01615)
                          "need AuthName: %s", r->uri);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        r->ap_auth_type = (char*)current_auth;
    
        res = get_basic_auth(r, &sent_user, &sent_pw);
        if (res) {
            return res;
        }
    
        if (conf->use_digest_algorithm
            && !ap_cstr_casecmp(conf->use_digest_algorithm, "MD5")) {
            realm = ap_auth_name(r);
            digest = ap_md5(r->pool,
                            (unsigned char *)apr_pstrcat(r->pool, sent_user, ":",
                                                         realm, ":",
                                                         sent_pw, NULL));
        }
    
        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,
                                              AUTHN_PROVIDER_VERSION);
    
                if (!provider || !provider->check_password) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01616)
                                  "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);
            }
    
            if (digest) {
                char *password;
    
                if (!provider->get_realm_hash) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02493)
                                  "Authn provider does not support "
                                  "AuthBasicUseDigestAlgorithm");
                    auth_result = AUTH_GENERAL_ERROR;
                    break;
                }
                /* We expect the password to be hash of user:realm:password */
                auth_result = provider->get_realm_hash(r, sent_user, realm,
                                                       &password);
                if (auth_result == AUTH_USER_FOUND) {
                    auth_result = strcmp(digest, password) ? AUTH_DENIED
                                                           : AUTH_GRANTED;
                }
            }
            else {
                auth_result = provider->check_password(r, sent_user, sent_pw);
            }
    
            apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
    
            /* Something occurred. 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, APLOGNO(01617)
                          "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, APLOGNO(01618)
                          "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 401, tell them to try again. */
            if (return_code == HTTP_UNAUTHORIZED) {
                note_basic_auth_failure(r);
            }
            return return_code;
        }
    
        return OK;
    }
    
    /* If requested, create a fake basic authentication header for the benefit
     * of a proxy or application running behind this server.
     */
    static int authenticate_basic_fake(request_rec *r)
    {
        const char *auth_line, *user, *pass, *err;
        auth_basic_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                           &auth_basic_module);
    
        if (!conf->fakeuser) {
            return DECLINED;
        }
    
        user = ap_expr_str_exec(r, conf->fakeuser, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02455)
                          "AuthBasicFake: could not evaluate user expression for URI '%s': %s", r->uri, err);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        if (!user || !*user) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02458)
                          "AuthBasicFake: empty username expression for URI '%s', ignoring", r->uri);
    
            apr_table_unset(r->headers_in, "Authorization");
    
            return DECLINED;
        }
    
        pass = ap_expr_str_exec(r, conf->fakepass, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02456)
                          "AuthBasicFake: could not evaluate password expression for URI '%s': %s", r->uri, err);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        if (!pass || !*pass) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02459)
                          "AuthBasicFake: empty password expression for URI '%s', ignoring", r->uri);
    
            apr_table_unset(r->headers_in, "Authorization");
    
            return DECLINED;
        }
    
        auth_line = apr_pstrcat(r->pool, "Basic ",
                                ap_pbase64encode(r->pool,
                                                 apr_pstrcat(r->pool, user,
                                                             ":", pass, NULL)),
                                NULL);
        apr_table_setn(r->headers_in, "Authorization", auth_line);
    
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02457)
                      "AuthBasicFake: \"Authorization: %s\"",
                      auth_line);
    
        return OK;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_check_authn(authenticate_basic_user, NULL, NULL, APR_HOOK_MIDDLE,
                            AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_fixups(authenticate_basic_fake, NULL, NULL, APR_HOOK_LAST);
        ap_hook_note_auth_failure(hook_note_basic_auth_failure, NULL, NULL,
                                  APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(auth_basic) =
    {
        STANDARD20_MODULE_STUFF,
        create_auth_basic_dir_config,  /* dir config creater */
        merge_auth_basic_dir_config,   /* dir merger --- default is to override */
        NULL,                          /* server config */
        NULL,                          /* merge server config */
        auth_basic_cmds,               /* command apr_table_t */
        register_hooks                 /* register hooks */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbm.c������������������������������������������������������������0000664�0001751�0001751�00000015330�14210356064�017763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "apr_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
    #define AUTHN_CACHE_STORE(r,user,realm,data) \
        if (authn_cache_store != NULL) \
            authn_cache_store((r), "dbm", (user), (realm), (data))
    
    typedef struct {
        const char *pwfile;
        const 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 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", ap_set_string_slot,
         (void *)APR_OFFSETOF(authn_dbm_config_rec, dbmtype),
         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(request_rec *r, const char *dbmtype,
                                        const char *dbmfile,
                                        const char *user, char **value)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        apr_dbm_t *f;
        apr_datum_t key, val;
        apr_status_t rv;
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        rv = apr_dbm_get_driver(&driver, dbmtype, &err, r->pool);
    
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10284)
                    "could not load '%s' dbm library: %s",
                         err->reason, err->msg);
            return rv;
        }
    
        rv = apr_dbm_open2(&f, driver, dbmfile, APR_DBM_READONLY,
                             APR_OS_DEFAULT, r->pool);
    #else
        rv = apr_dbm_open_ex(&f, dbmtype, dbmfile, APR_DBM_READONLY,
                             APR_OS_DEFAULT, r->pool);
    #endif
    
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10285)
                          "could not open dbm (type %s) file: %s",
                          dbmtype, dbmfile);
            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(r->pool, val.dptr, val.dsize);
        }
    
        apr_dbm_close(f);
    
        /* NOT FOUND is not an error case; this is indicated by a NULL result.
         * Treat all NULL lookup/error results as success for the simple case 
         * of auth credential lookup, these are DECLINED in both cases.
         */
        return APR_SUCCESS;
    }
    
    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(r, conf->dbmtype, conf->pwfile, user, &dbm_password);
    
        if (rv != APR_SUCCESS) {
            return AUTH_GENERAL_ERROR;
        }
    
        if (!dbm_password) {
            return AUTH_USER_NOT_FOUND;
        }
    
        colon_pw = ap_strchr(dbm_password, ':');
        if (colon_pw) {
            *colon_pw = '\0';
        }
        AUTHN_CACHE_STORE(r, user, NULL, dbm_password);
    
        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(r, conf->dbmtype, conf->pwfile,
                             apr_pstrcat(r->pool, user, ":", realm, NULL),
                             &dbm_hash);
    
        if (rv != APR_SUCCESS) {
            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;
        AUTHN_CACHE_STORE(r, user, realm, dbm_hash);
    
        return AUTH_USER_FOUND;
    }
    
    static const authn_provider authn_dbm_provider =
    {
        &check_dbm_pw,
        &get_dbm_realm_hash,
    };
    
    static void opt_retr(void)
    {
        authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
    }
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "dbm",
                                  AUTHN_PROVIDER_VERSION,
                                  &authn_dbm_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(authn_dbm) =
    {
        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 */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_form.c������������������������������������������������������������0000664�0001751�0001751�00000137412�14001631447�020013� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_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 "util_md5.h"
    #include "ap_expr.h"
    
    #include "mod_auth.h"
    #include "mod_session.h"
    #include "mod_request.h"
    
    #define FORM_LOGIN_HANDLER "form-login-handler"
    #define FORM_LOGOUT_HANDLER "form-logout-handler"
    #define FORM_REDIRECT_HANDLER "form-redirect-handler"
    #define MOD_AUTH_FORM_HASH "site"
    
    static APR_OPTIONAL_FN_TYPE(ap_session_load) *ap_session_load_fn = NULL;
    static APR_OPTIONAL_FN_TYPE(ap_session_get)  *ap_session_get_fn = NULL;
    static APR_OPTIONAL_FN_TYPE(ap_session_set)  *ap_session_set_fn = NULL;
    
    static void (*ap_request_insert_filter_fn) (request_rec * r) = NULL;
    static void (*ap_request_remove_filter_fn) (request_rec * r) = NULL;
    
    typedef struct {
        authn_provider_list *providers;
        char *dir;
        int authoritative;
        int authoritative_set;
        const char *site;
        int site_set;
        const char *username;
        int username_set;
        const char *password;
        int password_set;
        apr_size_t form_size;
        int form_size_set;
        int fakebasicauth;
        int fakebasicauth_set;
        const char *location;
        int location_set;
        const char *method;
        int method_set;
        const char *mimetype;
        int mimetype_set;
        const char *body;
        int body_set;
        int disable_no_store;
        int disable_no_store_set;
        ap_expr_info_t *loginsuccess;
        int loginsuccess_set;
        ap_expr_info_t *loginrequired;
        int loginrequired_set;
        ap_expr_info_t *logout;
        int logout_set;
    } auth_form_config_rec;
    
    static void *create_auth_form_dir_config(apr_pool_t * p, char *d)
    {
        auth_form_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
    
        conf->dir = d;
        /* Any failures are fatal. */
        conf->authoritative = 1;
    
        /* form size defaults to 8k */
        conf->form_size = HUGE_STRING_LEN;
    
        /* default form field names */
        conf->username = "httpd_username";
        conf->password = "httpd_password";
        conf->location = "httpd_location";
        conf->method = "httpd_method";
        conf->mimetype = "httpd_mimetype";
        conf->body = "httpd_body";
    
        return conf;
    }
    
    static void *merge_auth_form_dir_config(apr_pool_t * p, void *basev, void *addv)
    {
        auth_form_config_rec *new = (auth_form_config_rec *) apr_pcalloc(p, sizeof(auth_form_config_rec));
        auth_form_config_rec *add = (auth_form_config_rec *) addv;
        auth_form_config_rec *base = (auth_form_config_rec *) basev;
    
        new->providers = !add->providers ? base->providers : add->providers;
        new->authoritative = (add->authoritative_set == 0) ? base->authoritative : add->authoritative;
        new->authoritative_set = add->authoritative_set || base->authoritative_set;
        new->site = (add->site_set == 0) ? base->site : add->site;
        new->site_set = add->site_set || base->site_set;
        new->username = (add->username_set == 0) ? base->username : add->username;
        new->username_set = add->username_set || base->username_set;
        new->password = (add->password_set == 0) ? base->password : add->password;
        new->password_set = add->password_set || base->password_set;
        new->location = (add->location_set == 0) ? base->location : add->location;
        new->location_set = add->location_set || base->location_set;
        new->form_size = (add->form_size_set == 0) ? base->form_size : add->form_size;
        new->form_size_set = add->form_size_set || base->form_size_set;
        new->fakebasicauth = (add->fakebasicauth_set == 0) ? base->fakebasicauth : add->fakebasicauth;
        new->fakebasicauth_set = add->fakebasicauth_set || base->fakebasicauth_set;
        new->method = (add->method_set == 0) ? base->method : add->method;
        new->method_set = add->method_set || base->method_set;
        new->mimetype = (add->mimetype_set == 0) ? base->mimetype : add->mimetype;
        new->mimetype_set = add->mimetype_set || base->mimetype_set;
        new->body = (add->body_set == 0) ? base->body : add->body;
        new->body_set = add->body_set || base->body_set;
        new->disable_no_store = (add->disable_no_store_set == 0) ? base->disable_no_store : add->disable_no_store;
        new->disable_no_store_set = add->disable_no_store_set || base->disable_no_store_set;
        new->loginsuccess = (add->loginsuccess_set == 0) ? base->loginsuccess : add->loginsuccess;
        new->loginsuccess_set = add->loginsuccess_set || base->loginsuccess_set;
        new->loginrequired = (add->loginrequired_set == 0) ? base->loginrequired : add->loginrequired;
        new->loginrequired_set = add->loginrequired_set || base->loginrequired_set;
        new->logout = (add->logout_set == 0) ? base->logout : add->logout;
        new->logout_set = add->logout_set || base->logout_set;
    
        return new;
    }
    
    static const char *add_authn_provider(cmd_parms * cmd, void *config,
                                               const char *arg)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        authn_provider_list *newp;
    
        newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
        newp->provider_name = arg;
    
        /* lookup and cache the actual provider now */
        newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
                                            newp->provider_name,
                                            AUTHN_PROVIDER_VERSION);
    
        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 "
                                "Form Authentication", newp->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;
    }
    
    /**
     * Sanity check a given string that it exists, is not empty,
     * and does not contain special characters.
     */
    static const char *check_string(cmd_parms * cmd, const char *string)
    {
        if (!string || !*string || ap_strchr_c(string, '=') || ap_strchr_c(string, '&')) {
            return apr_pstrcat(cmd->pool, cmd->directive->directive,
                               " cannot be empty, or contain '=' or '&'.",
                               NULL);
        }
        return NULL;
    }
    
    static const char *set_cookie_form_location(cmd_parms * cmd, void *config, const char *location)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->location = location;
        conf->location_set = 1;
        return check_string(cmd, location);
    }
    
    static const char *set_cookie_form_username(cmd_parms * cmd, void *config, const char *username)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->username = username;
        conf->username_set = 1;
        return check_string(cmd, username);
    }
    
    static const char *set_cookie_form_password(cmd_parms * cmd, void *config, const char *password)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->password = password;
        conf->password_set = 1;
        return check_string(cmd, password);
    }
    
    static const char *set_cookie_form_method(cmd_parms * cmd, void *config, const char *method)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->method = method;
        conf->method_set = 1;
        return check_string(cmd, method);
    }
    
    static const char *set_cookie_form_mimetype(cmd_parms * cmd, void *config, const char *mimetype)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->mimetype = mimetype;
        conf->mimetype_set = 1;
        return check_string(cmd, mimetype);
    }
    
    static const char *set_cookie_form_body(cmd_parms * cmd, void *config, const char *body)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->body = body;
        conf->body_set = 1;
        return check_string(cmd, body);
    }
    
    static const char *set_cookie_form_size(cmd_parms * cmd, void *config,
                                                 const char *arg)
    {
        auth_form_config_rec *conf = config;
        apr_off_t size;
    
        if (APR_SUCCESS != apr_strtoff(&size, arg, NULL, 10)
            || size < 0 || size > APR_SIZE_MAX) {
            return "AuthCookieFormSize must be a size in bytes, or zero.";
        }
        conf->form_size = (apr_size_t)size;
        conf->form_size_set = 1;
    
        return NULL;
    }
    
    static const char *set_login_required_location(cmd_parms * cmd, void *config, const char *loginrequired)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        const char *err;
    
        conf->loginrequired = ap_expr_parse_cmd(cmd, loginrequired, AP_EXPR_FLAG_STRING_RESULT,
                                            &err, NULL);
        if (err) {
            return apr_psprintf(cmd->pool,
                                "Could not parse login required expression '%s': %s",
                                loginrequired, err);
        }
        conf->loginrequired_set = 1;
    
        return NULL;
    }
    
    static const char *set_login_success_location(cmd_parms * cmd, void *config, const char *loginsuccess)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        const char *err;
    
        conf->loginsuccess = ap_expr_parse_cmd(cmd, loginsuccess, AP_EXPR_FLAG_STRING_RESULT,
                                            &err, NULL);
        if (err) {
            return apr_psprintf(cmd->pool,
                                "Could not parse login success expression '%s': %s",
                                loginsuccess, err);
        }
        conf->loginsuccess_set = 1;
    
        return NULL;
    }
    
    static const char *set_logout_location(cmd_parms * cmd, void *config, const char *logout)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        const char *err;
    
        conf->logout = ap_expr_parse_cmd(cmd, logout, AP_EXPR_FLAG_STRING_RESULT,
                                            &err, NULL);
        if (err) {
            return apr_psprintf(cmd->pool,
                                "Could not parse logout required expression '%s': %s",
                                logout, err);
        }
        conf->logout_set = 1;
    
        return NULL;
    }
    
    static const char *set_site_passphrase(cmd_parms * cmd, void *config, const char *site)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->site = site;
        conf->site_set = 1;
        return NULL;
    }
    
    static const char *set_authoritative(cmd_parms * cmd, void *config, int flag)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->authoritative = flag;
        conf->authoritative_set = 1;
        return NULL;
    }
    
    static const char *set_fake_basic_auth(cmd_parms * cmd, void *config, int flag)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->fakebasicauth = flag;
        conf->fakebasicauth_set = 1;
        return NULL;
    }
    
    static const char *set_disable_no_store(cmd_parms * cmd, void *config, int flag)
    {
        auth_form_config_rec *conf = (auth_form_config_rec *) config;
        conf->disable_no_store = flag;
        conf->disable_no_store_set = 1;
        return NULL;
    }
    
    static const command_rec auth_form_cmds[] =
    {
        AP_INIT_ITERATE("AuthFormProvider", add_authn_provider, NULL, OR_AUTHCFG,
                        "specify the auth providers for a directory or location"),
        AP_INIT_TAKE1("AuthFormUsername", set_cookie_form_username, NULL, OR_AUTHCFG,
                      "The field of the login form carrying the username"),
        AP_INIT_TAKE1("AuthFormPassword", set_cookie_form_password, NULL, OR_AUTHCFG,
                      "The field of the login form carrying the password"),
        AP_INIT_TAKE1("AuthFormLocation", set_cookie_form_location, NULL, OR_AUTHCFG,
                      "The field of the login form carrying the URL to redirect on "
                      "successful login."),
        AP_INIT_TAKE1("AuthFormMethod", set_cookie_form_method, NULL, OR_AUTHCFG,
                      "The field of the login form carrying the original request method."),
        AP_INIT_TAKE1("AuthFormMimetype", set_cookie_form_mimetype, NULL, OR_AUTHCFG,
                      "The field of the login form carrying the original request mimetype."),
        AP_INIT_TAKE1("AuthFormBody", set_cookie_form_body, NULL, OR_AUTHCFG,
                      "The field of the login form carrying the urlencoded original request "
                      "body."),
        AP_INIT_TAKE1("AuthFormSize", set_cookie_form_size, NULL, ACCESS_CONF,
                      "Maximum size of body parsed by the form parser"),
        AP_INIT_TAKE1("AuthFormLoginRequiredLocation", set_login_required_location,
                      NULL, OR_AUTHCFG,
                      "If set, redirect the browser to this URL rather than "
                      "return 401 Not Authorized."),
        AP_INIT_TAKE1("AuthFormLoginSuccessLocation", set_login_success_location,
                      NULL, OR_AUTHCFG,
                      "If set, redirect the browser to this URL when a login "
                      "processed by the login handler is successful."),
        AP_INIT_TAKE1("AuthFormLogoutLocation", set_logout_location,
                      NULL, OR_AUTHCFG,
                      "The URL of the logout successful page. An attempt to access an "
                      "URL handled by the handler " FORM_LOGOUT_HANDLER " will result "
                      "in an redirect to this page after logout."),
        AP_INIT_TAKE1("AuthFormSitePassphrase", set_site_passphrase,
                      NULL, OR_AUTHCFG,
                      "If set, use this passphrase to determine whether the user should "
                      "be authenticated. Bypasses the user authentication check on "
                      "every website hit, and is useful for high traffic sites."),
        AP_INIT_FLAG("AuthFormAuthoritative", set_authoritative,
                     NULL, 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"),
        AP_INIT_FLAG("AuthFormFakeBasicAuth", set_fake_basic_auth,
                     NULL, OR_AUTHCFG,
                     "Set to 'On' to pass through authentication to the rest of the "
                     "server as a basic authentication header."),
        AP_INIT_FLAG("AuthFormDisableNoStore", set_disable_no_store,
                     NULL, OR_AUTHCFG,
                     "Set to 'on' to stop the sending of a Cache-Control no-store header with "
                     "the login screen. This allows the browser to cache the credentials, but "
                     "at the risk of it being possible for the login form to be resubmitted "
                     "and revealed to the backend server through XSS. Use at own risk."),
        {NULL}
    };
    
    module AP_MODULE_DECLARE_DATA auth_form_module;
    
    static void note_cookie_auth_failure(request_rec * r)
    {
        auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                          &auth_form_module);
    
        if (conf->location && ap_strchr_c(conf->location, ':')) {
            apr_table_setn(r->err_headers_out, "Location", conf->location);
        }
    }
    
    static int hook_note_cookie_auth_failure(request_rec * r,
                                             const char *auth_type)
    {
        if (ap_cstr_casecmp(auth_type, "form"))
            return DECLINED;
    
        note_cookie_auth_failure(r);
        return OK;
    }
    
    /**
     * Set the auth username and password into the main request
     * notes table.
     */
    static void set_notes_auth(request_rec * r,
                                    const char *user, const char *pw,
                                    const char *method, const char *mimetype)
    {
        apr_table_t *notes = NULL;
        const char *authname;
    
        /* find the main request */
        while (r->main) {
            r = r->main;
        }
        /* find the first redirect */
        while (r->prev) {
            r = r->prev;
        }
        notes = r->notes;
    
        /* have we isolated the user and pw before? */
        authname = ap_auth_name(r);
        if (user) {
            apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-user", NULL), user);
        }
        if (pw) {
            apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-pw", NULL), pw);
        }
        if (method) {
            apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-method", NULL), method);
        }
        if (mimetype) {
            apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-mimetype", NULL), mimetype);
        }
    
    }
    
    /**
     * Get the auth username and password from the main request
     * notes table, if present.
     */
    static void get_notes_auth(request_rec *r,
                               const char **user, const char **pw,
                               const char **method, const char **mimetype)
    {
        const char *authname;
        request_rec *m = r;
    
        /* find the main request */
        while (m->main) {
            m = m->main;
        }
        /* find the first redirect */
        while (m->prev) {
            m = m->prev;
        }
    
        /* have we isolated the user and pw before? */
        authname = ap_auth_name(m);
        if (user) {
            *user = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-user", NULL));
        }
        if (pw) {
            *pw = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-pw", NULL));
        }
        if (method) {
            *method = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-method", NULL));
        }
        if (mimetype) {
            *mimetype = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-mimetype", NULL));
        }
    
        /* set the user, even though the user is unauthenticated at this point */
        if (user && *user) {
            r->user = (char *) *user;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "from notes: user: %s, pw: %s, method: %s, mimetype: %s",
                      user ? *user : "<null>", pw ? *pw : "<null>",
                      method ? *method : "<null>", mimetype ? *mimetype : "<null>");
    
    }
    
    /**
     * Set the auth username and password into the session.
     *
     * If either the username, or the password are NULL, the username
     * and/or password will be removed from the session.
     */
    static apr_status_t set_session_auth(request_rec * r,
                                         const char *user, const char *pw, const char *site)
    {
        const char *hash = NULL;
        const char *authname = ap_auth_name(r);
        session_rec *z = NULL;
    
        if (site) {
            hash = ap_md5(r->pool,
                          (unsigned char *) apr_pstrcat(r->pool, user, ":", site, NULL));
        }
    
        ap_session_load_fn(r, &z);
        ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_USER, NULL), user);
        ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_PW, NULL), pw);
        ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_AUTH_FORM_HASH, NULL), hash);
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Get the auth username and password from the main request
     * notes table, if present.
     */
    static apr_status_t get_session_auth(request_rec * r,
                                         const char **user, const char **pw, const char **hash)
    {
        const char *authname = ap_auth_name(r);
        session_rec *z = NULL;
    
        ap_session_load_fn(r, &z);
    
        if (user) {
            ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_USER, NULL), user);
        }
        if (pw) {
            ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_PW, NULL), pw);
        }
        if (hash) {
            ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_AUTH_FORM_HASH, NULL), hash);
        }
    
        /* set the user, even though the user is unauthenticated at this point */
        if (user && *user) {
            r->user = (char *) *user;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "from session: " MOD_SESSION_USER ": %s, " MOD_SESSION_PW
                      ": %s, " MOD_AUTH_FORM_HASH ": %s",
                      user ? *user : "<null>", pw ? *pw : "<null>",
                      hash ? *hash : "<null>");
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Isolate the username and password in a POSTed form with the
     * username in the "username" field, and the password in the
     * "password" field.
     *
     * If either the username or the password is missing, this
     * function will return HTTP_UNAUTHORIZED.
     *
     * The location field is considered optional, and will be returned
     * if present.
     */
    static int get_form_auth(request_rec * r,
                                 const char *username,
                                 const char *password,
                                 const char *location,
                                 const char *method,
                                 const char *mimetype,
                                 const char *body,
                                 const char **sent_user,
                                 const char **sent_pw,
                                 const char **sent_loc,
                                 const char **sent_method,
                                 const char **sent_mimetype,
                                 apr_bucket_brigade **sent_body,
                                 auth_form_config_rec * conf)
    {
        /* sanity check - are we a POST request? */
    
        /* find the username and password in the form */
        apr_array_header_t *pairs = NULL;
        apr_off_t len;
        apr_size_t size;
        int res;
        char *buffer;
    
        /* have we isolated the user and pw before? */
        get_notes_auth(r, sent_user, sent_pw, sent_method, sent_mimetype);
        if (sent_user && *sent_user && sent_pw && *sent_pw) {
            return OK;
        }
    
        res = ap_parse_form_data(r, NULL, &pairs, -1, conf->form_size);
        if (res != OK) {
            return res;
        }
        while (pairs && !apr_is_empty_array(pairs)) {
            ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
            if (username && !strcmp(pair->name, username) && sent_user) {
                apr_brigade_length(pair->value, 1, &len);
                size = (apr_size_t) len;
                buffer = apr_palloc(r->pool, size + 1);
                apr_brigade_flatten(pair->value, buffer, &size);
                buffer[len] = 0;
                *sent_user = buffer;
            }
            else if (password && !strcmp(pair->name, password) && sent_pw) {
                apr_brigade_length(pair->value, 1, &len);
                size = (apr_size_t) len;
                buffer = apr_palloc(r->pool, size + 1);
                apr_brigade_flatten(pair->value, buffer, &size);
                buffer[len] = 0;
                *sent_pw = buffer;
            }
            else if (location && !strcmp(pair->name, location) && sent_loc) {
                apr_brigade_length(pair->value, 1, &len);
                size = (apr_size_t) len;
                buffer = apr_palloc(r->pool, size + 1);
                apr_brigade_flatten(pair->value, buffer, &size);
                buffer[len] = 0;
                *sent_loc = buffer;
            }
            else if (method && !strcmp(pair->name, method) && sent_method) {
                apr_brigade_length(pair->value, 1, &len);
                size = (apr_size_t) len;
                buffer = apr_palloc(r->pool, size + 1);
                apr_brigade_flatten(pair->value, buffer, &size);
                buffer[len] = 0;
                *sent_method = buffer;
            }
            else if (mimetype && !strcmp(pair->name, mimetype) && sent_mimetype) {
                apr_brigade_length(pair->value, 1, &len);
                size = (apr_size_t) len;
                buffer = apr_palloc(r->pool, size + 1);
                apr_brigade_flatten(pair->value, buffer, &size);
                buffer[len] = 0;
                *sent_mimetype = buffer;
            }
            else if (body && !strcmp(pair->name, body) && sent_body) {
                *sent_body = pair->value;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                      "from form: user: %s, pw: %s, method: %s, mimetype: %s, location: %s",
                      sent_user ? *sent_user : "<null>", sent_pw ? *sent_pw : "<null>",
                      sent_method ? *sent_method : "<null>",
                      sent_mimetype ? *sent_mimetype : "<null>",
                      sent_loc ? *sent_loc : "<null>");
    
        /* set the user, even though the user is unauthenticated at this point */
        if (sent_user && *sent_user) {
            r->user = (char *) *sent_user;
        }
    
        /* a missing username or missing password means auth denied */
        if (!sent_user || !*sent_user) {
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02982)
                          "form parsed, but username field '%s' was missing or empty, unauthorized",
                          username);
    
            return HTTP_UNAUTHORIZED;
        }
        if (!sent_pw || !*sent_pw) {
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02983)
                          "form parsed, but password field '%s' was missing or empty, unauthorized",
                          password);
    
            return HTTP_UNAUTHORIZED;
        }
    
        /*
         * save away the username, password, mimetype and method, so that they
         * are available should the auth need to be run again.
         */
        set_notes_auth(r, *sent_user, *sent_pw, sent_method ? *sent_method : NULL,
                       sent_mimetype ? *sent_mimetype : NULL);
    
        return OK;
    }
    
    /* 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.
     */
    
    
    /**
     * Given a username and site passphrase hash from the session, determine
     * whether the site passphrase is valid for this session.
     *
     * If the site passphrase is NULL, or if the sent_hash is NULL, this
     * function returns DECLINED.
     *
     * If the site passphrase hash does not match the sent hash, this function
     * returns AUTH_USER_NOT_FOUND.
     *
     * On success, returns OK.
     */
    static int check_site(request_rec * r, const char *site, const char *sent_user, const char *sent_hash)
    {
    
        if (site && sent_user && sent_hash) {
            const char *hash = ap_md5(r->pool,
                          (unsigned char *) apr_pstrcat(r->pool, sent_user, ":", site, NULL));
    
            if (!strcmp(sent_hash, hash)) {
                return OK;
            }
            else {
                return AUTH_USER_NOT_FOUND;
            }
        }
    
        return DECLINED;
    
    }
    
    /**
     * Given a username and password (extracted externally from a cookie), run
     * the authnz hooks to determine whether this request is authorized.
     *
     * Return an HTTP code.
     */
    static int check_authn(request_rec * r, const char *sent_user, const char *sent_pw)
    {
        authn_status auth_result;
        authn_provider_list *current_provider;
        auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                          &auth_form_module);
    
        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,
                                              AUTHN_PROVIDER_VERSION);
    
                if (!provider || !provider->check_password) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01806)
                                  "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);
            }
    
            if (!sent_user || !sent_pw) {
                auth_result = AUTH_USER_NOT_FOUND;
                break;
            }
    
            auth_result = provider->check_password(r, sent_user, sent_pw);
    
            apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
    
            /* Something occurred. 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, APLOGNO(01807)
                              "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, APLOGNO(01808)
                              "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 401, tell them to try again. */
            if (return_code == HTTP_UNAUTHORIZED) {
                note_cookie_auth_failure(r);
            }
    
    /* TODO: Flag the user somehow as to the reason for the failure */
    
            return return_code;
        }
    
        return OK;
    
    }
    
    /* fake the basic authentication header if configured to do so */
    static void fake_basic_authentication(request_rec *r, auth_form_config_rec *conf,
                                          const char *user, const char *pw)
    {
        if (conf->fakebasicauth) {
            char *basic = apr_pstrcat(r->pool, user, ":", pw, NULL);
            apr_size_t size = (apr_size_t) strlen(basic);
            char *base64 = apr_palloc(r->pool,
                                      apr_base64_encode_len(size + 1) * sizeof(char));
            apr_base64_encode(base64, basic, size);
            apr_table_setn(r->headers_in, "Authorization",
                           apr_pstrcat(r->pool, "Basic ", base64, NULL));
        }
    }
    
    /**
     * Must we use form authentication? If so, extract the cookie and run
     * the authnz hooks to determine if the login is valid.
     *
     * If the login is not valid, a 401 Not Authorized will be returned. It
     * is up to the webmaster to ensure this screen displays a suitable login
     * form to give the user the opportunity to log in.
     */
    static int authenticate_form_authn(request_rec * r)
    {
        auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                          &auth_form_module);
        const char *sent_user = NULL, *sent_pw = NULL, *sent_hash = NULL;
        const char *sent_loc = NULL, *sent_method = "GET", *sent_mimetype = NULL;
        const char *current_auth = NULL;
        const char *err;
        apr_status_t res;
        int rv = HTTP_UNAUTHORIZED;
    
        /* Are we configured to be Form auth? */
        current_auth = ap_auth_type(r);
        if (!current_auth || ap_cstr_casecmp(current_auth, "form")) {
            return DECLINED;
        }
    
        /*
         * XSS security warning: using cookies to store private data only works
         * when the administrator has full control over the source website. When
         * in forward-proxy mode, websites are public by definition, and so can
         * never be secure. Abort the auth attempt in this case.
         */
        if (PROXYREQ_PROXY == r->proxyreq) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01809)
                          "form auth cannot be used for proxy "
                          "requests due to XSS risk, access denied: %s", r->uri);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* We need an authentication realm. */
        if (!ap_auth_name(r)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01810)
                          "need AuthName: %s", r->uri);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        r->ap_auth_type = (char *) current_auth;
    
        /* try get the username and password from the notes, if present */
        get_notes_auth(r, &sent_user, &sent_pw, &sent_method, &sent_mimetype);
        if (!sent_user || !sent_pw || !*sent_user || !*sent_pw) {
    
            /* otherwise try get the username and password from a session, if present */
            res = get_session_auth(r, &sent_user, &sent_pw, &sent_hash);
    
        }
        else {
            res = APR_SUCCESS;
        }
    
        /* first test whether the site passphrase matches */
        if (APR_SUCCESS == res && sent_user && sent_hash && sent_pw) {
            rv = check_site(r, conf->site, sent_user, sent_hash);
            if (OK == rv) {
                fake_basic_authentication(r, conf, sent_user, sent_pw);
                return OK;
            }
        }
    
        /* otherwise test for a normal password match */
        if (APR_SUCCESS == res && sent_user && sent_pw) {
            rv = check_authn(r, sent_user, sent_pw);
            if (OK == rv) {
                fake_basic_authentication(r, conf, sent_user, sent_pw);
                return OK;
            }
        }
    
        /*
         * If we reach this point, the request should fail with access denied,
         * except for one potential scenario:
         *
         * If the request is a POST, and the posted form contains user defined fields
         * for a username and a password, and the username and password are correct,
         * then return the response obtained by a GET to this URL.
         *
         * If an additional user defined location field is present in the form,
         * instead of a GET of the current URL, redirect the browser to the new
         * location.
         *
         * As a further option, if the user defined fields for the type of request,
         * the mime type of the body of the request, and the body of the request
         * itself are present, replace this request with a new request of the given
         * type and with the given body.
         *
         * Otherwise access is denied.
         *
         * Reading the body requires some song and dance, because the input filters
         * are not yet configured. To work around this problem, we create a
         * subrequest and use that to create a sane filter stack we can read the
         * form from.
         *
         * The main request is then capped with a kept_body input filter, which has
         * the effect of guaranteeing the input stack can be safely read a second time.
         *
         */
        if (HTTP_UNAUTHORIZED == rv && r->method_number == M_POST && ap_is_initial_req(r)) {
            request_rec *rr;
            apr_bucket_brigade *sent_body = NULL;
    
            /* create a subrequest of our current uri */
            rr = ap_sub_req_lookup_uri(r->uri, r, r->input_filters);
            rr->headers_in = r->headers_in;
    
            /* run the insert_filters hook on the subrequest to ensure a body read can
             * be done properly.
             */
            ap_run_insert_filter(rr);
    
            /* parse the form by reading the subrequest */
            rv = get_form_auth(rr, conf->username, conf->password, conf->location,
                               conf->method, conf->mimetype, conf->body,
                               &sent_user, &sent_pw, &sent_loc, &sent_method,
                               &sent_mimetype, &sent_body, conf);
    
            /* make sure any user detected within the subrequest is saved back to
             * the main request.
             */
            r->user = apr_pstrdup(r->pool, rr->user);
    
            /* we cannot clean up rr at this point, as memory allocated to rr is
             * referenced from the main request. It will be cleaned up when the
             * main request is cleaned up.
             */
    
            /* insert the kept_body filter on the main request to guarantee the
             * input filter stack cannot be read a second time, optionally inject
             * a saved body if one was specified in the login form.
             */
            if (sent_body && sent_mimetype) {
                apr_table_set(r->headers_in, "Content-Type", sent_mimetype);
                r->kept_body = sent_body;
            }
            else {
                r->kept_body = apr_brigade_create(r->pool, r->connection->bucket_alloc);
            }
            ap_request_insert_filter_fn(r);
    
            /* did the form ask to change the method? if so, switch in the redirect handler
             * to relaunch this request as the subrequest with the new method. If the
             * form didn't specify a method, the default value GET will force a redirect.
             */
            if (sent_method && strcmp(r->method, sent_method)) {
                r->handler = FORM_REDIRECT_HANDLER;
            }
    
            /* check the authn in the main request, based on the username found */
            if (OK == rv) {
                rv = check_authn(r, sent_user, sent_pw);
                if (OK == rv) {
                    fake_basic_authentication(r, conf, sent_user, sent_pw);
                    set_session_auth(r, sent_user, sent_pw, conf->site);
                    if (sent_loc) {
                        apr_table_set(r->headers_out, "Location", sent_loc);
                        return HTTP_MOVED_TEMPORARILY;
                    }
                    if (conf->loginsuccess) {
                        const char *loginsuccess = ap_expr_str_exec(r,
                                conf->loginsuccess, &err);
                        if (!err) {
                            apr_table_set(r->headers_out, "Location", loginsuccess);
                            return HTTP_MOVED_TEMPORARILY;
                        }
                        else {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02339)
                                          "Can't evaluate login success expression: %s", err);
                            return HTTP_INTERNAL_SERVER_ERROR;
                        }
                    }
                }
            }
    
        }
    
        /*
         * did the admin prefer to be redirected to the login page on failure
         * instead?
         */
        if (HTTP_UNAUTHORIZED == rv && conf->loginrequired) {
            const char *loginrequired = ap_expr_str_exec(r,
                    conf->loginrequired, &err);
            if (!err) {
                apr_table_set(r->headers_out, "Location", loginrequired);
                return HTTP_MOVED_TEMPORARILY;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02340)
                              "Can't evaluate login required expression: %s", err);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        /* did the user ask to be redirected on login success? */
        if (sent_loc) {
            apr_table_set(r->headers_out, "Location", sent_loc);
            rv = HTTP_MOVED_TEMPORARILY;
        }
    
    
        /*
         * potential security issue: if we return a login to the browser, we must
         * send a no-store to make sure a well behaved browser will not try and
         * send the login details a second time if the back button is pressed.
         *
         * if the user has full control over the backend, the
         * AuthCookieDisableNoStore can be used to turn this off.
         */
        if (HTTP_UNAUTHORIZED == rv && !conf->disable_no_store) {
            apr_table_addn(r->headers_out, "Cache-Control", "no-store");
            apr_table_addn(r->err_headers_out, "Cache-Control", "no-store");
        }
    
        return rv;
    
    }
    
    /**
     * Handle a login attempt.
     *
     * If the login session is either missing or form authnz is unsuccessful, a
     * 401 Not Authorized will be returned to the browser. The webmaster
     * is expected to insert a login form into the 401 Not Authorized
     * error screen.
     *
     * If the webmaster wishes, they can point the form submission at this
     * handler, which will redirect the user to the correct page on success.
     * On failure, the 401 Not Authorized error screen will be redisplayed,
     * where the login attempt can be repeated.
     *
     */
    static int authenticate_form_login_handler(request_rec * r)
    {
        auth_form_config_rec *conf;
        const char *err;
    
        const char *sent_user = NULL, *sent_pw = NULL, *sent_loc = NULL;
        int rv;
    
        if (strcmp(r->handler, FORM_LOGIN_HANDLER)) {
            return DECLINED;
        }
    
        if (r->method_number != M_POST) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01811)
              "the " FORM_LOGIN_HANDLER " only supports the POST method for %s",
                          r->uri);
            return HTTP_METHOD_NOT_ALLOWED;
        }
    
        conf = ap_get_module_config(r->per_dir_config, &auth_form_module);
    
        rv = get_form_auth(r, conf->username, conf->password, conf->location,
                           NULL, NULL, NULL,
                           &sent_user, &sent_pw, &sent_loc,
                           NULL, NULL, NULL, conf);
        if (OK == rv) {
            rv = check_authn(r, sent_user, sent_pw);
            if (OK == rv) {
                set_session_auth(r, sent_user, sent_pw, conf->site);
                if (sent_loc) {
                    apr_table_set(r->headers_out, "Location", sent_loc);
                    return HTTP_MOVED_TEMPORARILY;
                }
                if (conf->loginsuccess) {
                    const char *loginsuccess = ap_expr_str_exec(r,
                            conf->loginsuccess, &err);
                    if (!err) {
                        apr_table_set(r->headers_out, "Location", loginsuccess);
                        return HTTP_MOVED_TEMPORARILY;
                    }
                    else {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02341)
                                      "Can't evaluate login success expression: %s", err);
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                }
                return HTTP_OK;
            }
        }
    
        /* did we prefer to be redirected to the login page on failure instead? */
        if (HTTP_UNAUTHORIZED == rv && conf->loginrequired) {
            const char *loginrequired = ap_expr_str_exec(r,
                    conf->loginrequired, &err);
            if (!err) {
                apr_table_set(r->headers_out, "Location", loginrequired);
                return HTTP_MOVED_TEMPORARILY;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02342)
                              "Can't evaluate login required expression: %s", err);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        return rv;
    
    }
    
    /**
     * Handle a logout attempt.
     *
     * If an attempt is made to access this URL, any username and password
     * embedded in the session is deleted.
     *
     * This has the effect of logging the person out.
     *
     * If a logout URI has been specified, this function will create an
     * internal redirect to this page.
     */
    static int authenticate_form_logout_handler(request_rec * r)
    {
        auth_form_config_rec *conf;
        const char *err;
    
        if (strcmp(r->handler, FORM_LOGOUT_HANDLER)) {
            return DECLINED;
        }
    
        conf = ap_get_module_config(r->per_dir_config, &auth_form_module);
    
        /* remove the username and password, effectively logging the user out */
        set_session_auth(r, NULL, NULL, NULL);
    
        /*
         * make sure the logout page is never cached - otherwise the logout won't
         * work!
         */
        apr_table_addn(r->headers_out, "Cache-Control", "no-store");
        apr_table_addn(r->err_headers_out, "Cache-Control", "no-store");
    
        /* if set, internal redirect to the logout page */
        if (conf->logout) {
            const char *logout = ap_expr_str_exec(r,
                    conf->logout, &err);
            if (!err) {
                apr_table_addn(r->headers_out, "Location", logout);
                return HTTP_TEMPORARY_REDIRECT;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02343)
                              "Can't evaluate logout expression: %s", err);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        return HTTP_OK;
    
    }
    
    /**
     * Handle a redirect attempt.
     *
     * If during a form login, the method, mimetype and request body are
     * specified, this handler will ensure that this request is included
     * as an internal redirect.
     *
     */
    static int authenticate_form_redirect_handler(request_rec * r)
    {
    
        request_rec *rr = NULL;
        const char *sent_method = NULL, *sent_mimetype = NULL;
    
        if (strcmp(r->handler, FORM_REDIRECT_HANDLER)) {
            return DECLINED;
        }
    
        /* get the method and mimetype from the notes */
        get_notes_auth(r, NULL, NULL, &sent_method, &sent_mimetype);
    
        if (r->kept_body && sent_method && sent_mimetype) {
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01812)
              "internal redirect to method '%s' and body mimetype '%s' for the "
                          "uri: %s", sent_method, sent_mimetype, r->uri);
    
            rr = ap_sub_req_method_uri(sent_method, r->uri, r, r->output_filters);
            r->status = ap_run_sub_req(rr);
    
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01813)
            "internal redirect requested but one or all of method, mimetype or "
                          "body are NULL: %s", r->uri);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* return the underlying error, or OK on success */
        return r->status == HTTP_OK || r->status == OK ? OK : r->status;
    
    }
    
    static int authenticate_form_post_config(apr_pool_t *pconf, apr_pool_t *plog,
            apr_pool_t *ptemp, server_rec *s)
    {
    
        if (!ap_session_load_fn || !ap_session_get_fn || !ap_session_set_fn) {
            ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load);
            ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get);
            ap_session_set_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_set);
            if (!ap_session_load_fn || !ap_session_get_fn || !ap_session_set_fn) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(02617)
                        "You must load mod_session to enable the mod_auth_form "
                                           "functions");
                return !OK;
            }
        }
    
        if (!ap_request_insert_filter_fn || !ap_request_remove_filter_fn) {
            ap_request_insert_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_insert_filter);
            ap_request_remove_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_remove_filter);
            if (!ap_request_insert_filter_fn || !ap_request_remove_filter_fn) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(02618)
                        "You must load mod_request to enable the mod_auth_form "
                                           "functions");
                return !OK;
            }
        }
    
        return OK;
    }
    
    static void register_hooks(apr_pool_t * p)
    {
        ap_hook_post_config(authenticate_form_post_config,NULL,NULL,APR_HOOK_MIDDLE);
    
    #if AP_MODULE_MAGIC_AT_LEAST(20080403,1)
        ap_hook_check_authn(authenticate_form_authn, NULL, NULL, APR_HOOK_MIDDLE,
                            AP_AUTH_INTERNAL_PER_CONF);
    #else
        ap_hook_check_user_id(authenticate_form_authn, NULL, NULL, APR_HOOK_MIDDLE);
    #endif
        ap_hook_handler(authenticate_form_login_handler, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(authenticate_form_logout_handler, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(authenticate_form_redirect_handler, NULL, NULL, APR_HOOK_MIDDLE);
    
        ap_hook_note_auth_failure(hook_note_cookie_auth_failure, NULL, NULL,
                                  APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(auth_form) =
    {
        STANDARD20_MODULE_STUFF,
        create_auth_form_dir_config, /* dir config creater */
        merge_auth_form_dir_config,  /* dir merger --- default is to override */
        NULL,                        /* server config */
        NULL,                        /* merge server config */
        auth_form_cmds,              /* command apr_table_t */
        register_hooks               /* register hooks */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_host.c�����������������������������������������������������������0000664�0001751�0001751�00000031162�13250450660�020213� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_hash.h"
    
    #define APR_WANT_STRFUNC
    #define APR_WANT_BYTEFUNC
    #include "apr_want.h"
    
    #include "ap_config.h"
    #include "ap_provider.h"
    #include "httpd.h"
    #include "http_core.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_request.h"
    
    #include "mod_auth.h"
    
    #if APR_HAVE_NETINET_IN_H
    #include <netinet/in.h>
    #endif
    
    /*
     * To save memory if the same subnets are used in hundres of vhosts, we store
     * each subnet only once and use this temporary hash to find it again.
     */
    static apr_hash_t *parsed_subnets;
    
    static apr_ipsubnet_t *localhost_v4;
    #if APR_HAVE_IPV6
    static apr_ipsubnet_t *localhost_v6;
    #endif
    
    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 const char *ip_parse_config(cmd_parms *cmd,
                                       const char *require_line,
                                       const void **parsed_require_line)
    {
        const char *t, *w;
        int count = 0;
        apr_ipsubnet_t **ip;
        apr_pool_t *ptemp = cmd->temp_pool;
        apr_pool_t *p = cmd->pool;
    
        /* The 'ip' provider will allow the configuration to specify a list of
            ip addresses to check rather than a single address.  This is different
            from the previous host based syntax. */
    
        t = require_line;
        while ((w = ap_getword_conf(ptemp, &t)) && w[0])
            count++;
    
        if (count == 0)
            return "'require ip' requires an argument";
    
        ip = apr_pcalloc(p, sizeof(apr_ipsubnet_t *) * (count + 1));
        *parsed_require_line = ip;
    
        t = require_line;
        while ((w = ap_getword_conf(ptemp, &t)) && w[0]) {
            char *addr = apr_pstrdup(ptemp, w);
            char *mask;
            apr_status_t rv;
    
            if (parsed_subnets &&
                (*ip = apr_hash_get(parsed_subnets, w, APR_HASH_KEY_STRING)) != NULL)
            {
                /* we already have parsed this subnet */
                ip++;
                continue;
            }
    
            if ((mask = ap_strchr(addr, '/')))
                *mask++ = '\0';
    
            rv = apr_ipsubnet_create(ip, addr, mask, p);
    
            if(APR_STATUS_IS_EINVAL(rv)) {
                /* looked nothing like an IP address */
                return apr_psprintf(p, "ip address '%s' appears to be invalid", w);
            }
            else if (rv != APR_SUCCESS) {
                return apr_psprintf(p, "ip address '%s' appears to be invalid: %pm",
                                    w, &rv);
            }
    
            if (parsed_subnets)
                apr_hash_set(parsed_subnets, w, APR_HASH_KEY_STRING, *ip);
            ip++;
        }
    
        return NULL;
    }
    
    static authz_status ip_check_authorization(request_rec *r,
                                               const char *require_line,
                                               const void *parsed_require_line)
    {
        /* apr_ipsubnet_test should accept const but doesn't */
        apr_ipsubnet_t **ip = (apr_ipsubnet_t **)parsed_require_line;
    
        while (*ip) {
            if (apr_ipsubnet_test(*ip, r->useragent_addr))
                return AUTHZ_GRANTED;
            ip++;
        }
    
        /* authz_core will log the require line and the result at DEBUG */
        return AUTHZ_DENIED;
    }
    
    static authz_status host_check_authorization(request_rec *r,
                                                 const char *require_line,
                                                 const void *parsed_require_line)
    {
        const char *t, *w;
        const char *remotehost = NULL;
        int remotehost_is_ip;
    
        remotehost = ap_get_useragent_host(r, REMOTE_DOUBLE_REV, &remotehost_is_ip);
    
        if ((remotehost == NULL) || remotehost_is_ip) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01753)
                          "access check of '%s' to %s failed, reason: unable to get the "
                          "remote host name", require_line, r->uri);
        }
        else {
            const char *err = NULL;
            const ap_expr_info_t *expr = parsed_require_line;
            const char *require;
    
            require = ap_expr_str_exec(r, expr, &err);
            if (err) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02593)
                              "authz_host authorize: require host: Can't "
                              "evaluate require expression: %s", err);
                return AUTHZ_DENIED;
            }
    
            /* The 'host' provider will allow the configuration to specify a list of
                host names to check rather than a single name.  This is different
                from the previous host based syntax. */
            t = require;
    
            /* '#' is not a valid hostname character and admin could
             * specify 'Require host localhost# Add example.com later'. We
             * should not grant access to 'example.com' in that case. */
            w = ap_strchr_c(t, '#');
            if (w) {
                if (w == t) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10120)
                                  "authz_host authorize: dubious empty "
                                  "'Require host %s' with only comment", t);
                    return AUTHZ_DENIED;
                }
    
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10121)
                              "authz_host authorize: ignoring comment in "
                              "'Require host %s'", t);
    
                /* Truncate the string at the #. */
                t = apr_pstrmemdup(r->pool, t, w - t);
            }
            
            while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
                if (in_domain(w, remotehost)) {
                    return AUTHZ_GRANTED;
                }
            }
        }
    
        /* authz_core will log the require line and the result at DEBUG */
        return AUTHZ_DENIED;
    }
    
    static authz_status
    forward_dns_check_authorization(request_rec *r,
                                    const char *require_line,
                                    const void *parsed_require_line)
    {
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_line;
        const char *require, *t;
        char *w;
    
        /* the require line is an expression, which is evaluated now. */
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03354)
                        "authz_host authorize: require forward-dns: "
                        "Can't evaluate require expression: %s", err);
          return AUTHZ_DENIED;
        }
    
        /* tokenize expected list of names */
        t = require;
        while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
    
            apr_sockaddr_t *sa;
            apr_status_t rv;
            char *hash_ptr;
    
            /* stop on apache configuration file comments */
            if ((hash_ptr = ap_strchr(w, '#'))) {
                if (hash_ptr == w) {
                    break;
                }
                *hash_ptr = '\0';
            }
    
            /* does the client ip match one of the names? */
            rv = apr_sockaddr_info_get(&sa, w, APR_UNSPEC, 0, 0, r->pool);
            if (rv == APR_SUCCESS) {
    
                while (sa) {
                    int match = apr_sockaddr_equal(sa, r->useragent_addr);
    
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03355)
                                  "access check for %s as '%s': %s",
                                  r->useragent_ip, w, match? "yes": "no");
                    if (match) {
                        return AUTHZ_GRANTED;
                    }
    
                    sa = sa->next;
                }
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03356)
                              "No sockaddr info for \"%s\"", w);
            }
    
            /* stop processing, we are in a comment */
            if (hash_ptr) {
                break;
            }
        }
    
        return AUTHZ_DENIED;
    }
    
    static authz_status local_check_authorization(request_rec *r,
                                                  const char *require_line,
                                                  const void *parsed_require_line)
    {
         if (   apr_sockaddr_equal(r->connection->local_addr,
                                   r->useragent_addr)
             || apr_ipsubnet_test(localhost_v4, r->useragent_addr)
    #if APR_HAVE_IPV6
             || apr_ipsubnet_test(localhost_v6, r->useragent_addr)
    #endif
            )
         {
            return AUTHZ_GRANTED;
         }
    
         return AUTHZ_DENIED;
    }
    
    static const char *host_parse_config(cmd_parms *cmd, const char *require_line,
                                         const void **parsed_require_line)
    {
        const char *expr_err = NULL;
        ap_expr_info_t *expr;
    
        expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
                &expr_err, NULL);
    
        if (expr_err)
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression in require line: ",
                               expr_err, NULL);
    
        *parsed_require_line = expr;
    
        return NULL;
    }
    
    static const authz_provider authz_ip_provider =
    {
        &ip_check_authorization,
        &ip_parse_config,
    };
    
    static const authz_provider authz_host_provider =
    {
        &host_check_authorization,
        &host_parse_config,
    };
    
    static const authz_provider authz_forward_dns_provider =
    {
        &forward_dns_check_authorization,
        &host_parse_config,
    };
    
    static const authz_provider authz_local_provider =
    {
        &local_check_authorization,
        NULL,
    };
    
    
    static int authz_host_pre_config(apr_pool_t *p, apr_pool_t *plog,
                                     apr_pool_t *ptemp)
    {
        /* we only use this hash in the parse config phase, ptemp is enough */
        parsed_subnets = apr_hash_make(ptemp);
    
        apr_ipsubnet_create(&localhost_v4, "127.0.0.0", "8", p);
        apr_hash_set(parsed_subnets, "127.0.0.0/8", APR_HASH_KEY_STRING, localhost_v4);
    
    #if APR_HAVE_IPV6
        apr_ipsubnet_create(&localhost_v6, "::1", NULL, p);
        apr_hash_set(parsed_subnets, "::1", APR_HASH_KEY_STRING, localhost_v6);
    #endif
    
        return OK;
    }
    
    static int authz_host_post_config(apr_pool_t *p, apr_pool_t *plog,
                                      apr_pool_t *ptemp, server_rec *s)
    {
        /* make sure we don't use this during .htaccess parsing */
        parsed_subnets = NULL;
    
        return OK;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_pre_config(authz_host_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_config(authz_host_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ip",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_ip_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "host",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_host_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "forward-dns",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_forward_dns_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "local",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_local_provider, AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(authz_host) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,                           /* dir config creater */
        NULL,                           /* dir merger --- default is to override */
        NULL,                           /* server config */
        NULL,                           /* merge server config */
        NULL,
        register_hooks                  /* register hooks */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_basic.mak���������������������������������������������������������0000664�0001751�0001751�00000024115�12701473373�020461� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_auth_basic.dsp
    !IF "$(CFG)" == ""
    CFG=mod_auth_basic - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_auth_basic - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_auth_basic - Win32 Release" && "$(CFG)" != "mod_auth_basic - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_basic - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_auth_basic.obj"
    	-@erase "$(INTDIR)\mod_auth_basic.res"
    	-@erase "$(INTDIR)\mod_auth_basic_src.idb"
    	-@erase "$(INTDIR)\mod_auth_basic_src.pdb"
    	-@erase "$(OUTDIR)\mod_auth_basic.exp"
    	-@erase "$(OUTDIR)\mod_auth_basic.lib"
    	-@erase "$(OUTDIR)\mod_auth_basic.pdb"
    	-@erase "$(OUTDIR)\mod_auth_basic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_basic_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_basic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_basic.pdb" /debug /out:"$(OUTDIR)\mod_auth_basic.so" /implib:"$(OUTDIR)\mod_auth_basic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_auth_basic.obj" \
    	"$(INTDIR)\mod_auth_basic.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_auth_basic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_auth_basic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_basic.so"
       if exist .\Release\mod_auth_basic.so.manifest mt.exe -manifest .\Release\mod_auth_basic.so.manifest -outputresource:.\Release\mod_auth_basic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_auth_basic - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_auth_basic.obj"
    	-@erase "$(INTDIR)\mod_auth_basic.res"
    	-@erase "$(INTDIR)\mod_auth_basic_src.idb"
    	-@erase "$(INTDIR)\mod_auth_basic_src.pdb"
    	-@erase "$(OUTDIR)\mod_auth_basic.exp"
    	-@erase "$(OUTDIR)\mod_auth_basic.lib"
    	-@erase "$(OUTDIR)\mod_auth_basic.pdb"
    	-@erase "$(OUTDIR)\mod_auth_basic.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_basic_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_basic.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_basic.pdb" /debug /out:"$(OUTDIR)\mod_auth_basic.so" /implib:"$(OUTDIR)\mod_auth_basic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_auth_basic.obj" \
    	"$(INTDIR)\mod_auth_basic.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_auth_basic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_auth_basic.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_basic.so"
       if exist .\Debug\mod_auth_basic.so.manifest mt.exe -manifest .\Debug\mod_auth_basic.so.manifest -outputresource:.\Debug\mod_auth_basic.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_auth_basic.dep")
    !INCLUDE "mod_auth_basic.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_auth_basic.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_auth_basic - Win32 Release" || "$(CFG)" == "mod_auth_basic - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_auth_basic - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_basic - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_basic - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_basic - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_basic - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_basic - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_auth_basic - Win32 Release"
    
    
    "$(INTDIR)\mod_auth_basic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_auth_basic - Win32 Debug"
    
    
    "$(INTDIR)\mod_auth_basic.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_auth_basic.c
    
    "$(INTDIR)\mod_auth_basic.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_fcgi.c����������������������������������������������������������0000664�0001751�0001751�00000134423�14603243511�020326� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_lib.h"
    #include "apr_strings.h"
    
    #include "ap_provider.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 "ap_provider.h"
    #include "mod_auth.h"
    #include "util_fcgi.h"
    #include "ap_mmn.h"
    
    module AP_MODULE_DECLARE_DATA authnz_fcgi_module;
    
    typedef struct {
        const char *name; /* provider name */
        const char *backend; /* backend address, as configured */
        const char *host;
        apr_port_t port;
        apr_sockaddr_t *backend_addrs;
        int is_authn;
        int is_authz;
    } fcgi_provider_conf;
    
    typedef struct {
        const char *name; /* provider name */
        const char *default_user; /* this is user if authorizer returns
                                   * success and a user expression yields
                                   * empty string
                                   */
        ap_expr_info_t *user_expr; /* expr to evaluate to set r->user */
        char authoritative; /* fail request if user is rejected? */
        char require_basic_auth; /* fail if client didn't send credentials? */
    } fcgi_dir_conf;
    
    typedef struct {
        /* If an "authnz" provider successfully authenticates, record
         * the provider name here for checking during authz.
         */
        const char *successful_authnz_provider;
    } fcgi_request_notes;
    
    static apr_hash_t *fcgi_authn_providers, *fcgi_authz_providers;
    
    #define FCGI_IO_TIMEOUT apr_time_from_sec(30)
    
    #ifndef NON200_RESPONSE_BUF_LEN
    #define NON200_RESPONSE_BUF_LEN 8192
    #endif
    
    /* fcgi://{hostname|IPv4|IPv6}:port[/] */
    #define FCGI_BACKEND_REGEX_STR "m%^fcgi://(.*):(\\d{1,5})/?$%"
    
    /*
     * utility function to connect to a peer; generally useful, but 
     * wait for AF_UNIX support in this mod before thinking about how
     * to make it available to other modules
     */
    static apr_status_t connect_to_peer(apr_socket_t **newsock,
                                        request_rec *r,
                                        apr_sockaddr_t *backend_addrs,
                                        const char *backend_name,
                                        apr_interval_time_t timeout)
    {
        apr_status_t rv = APR_EINVAL; /* returned if no backend addr was provided
                                       */
        int connected = 0;
        apr_sockaddr_t *addr = backend_addrs;
    
        while (addr && !connected) {
            int loglevel = addr->next ? APLOG_DEBUG : APLOG_ERR;
            rv = apr_socket_create(newsock, addr->family,
                                   SOCK_STREAM, 0, r->pool);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, loglevel, rv, r,
                              APLOGNO(02494) "error creating family %d socket "
                              "for target %s",
                              addr->family, backend_name);
                addr = addr->next;
                continue;
            }
    
            apr_socket_opt_set(*newsock, APR_TCP_NODELAY, 1);
            apr_socket_timeout_set(*newsock,
                                   timeout ? timeout : r->server->timeout);
    
            rv = apr_socket_connect(*newsock, addr);
            if (rv != APR_SUCCESS) {
                apr_socket_close(*newsock);
                ap_log_rerror(APLOG_MARK, loglevel, rv, r,
                              APLOGNO(02495) "attempt to connect to %pI (%s) "
                              "failed", addr, backend_name);
                addr = addr->next;
                continue;
            }
    
            connected = 1;
        }
    
        return rv;
    #undef FN_LOG_MARK
    }
    
    static void log_provider_info(const fcgi_provider_conf *conf, request_rec *r)
    {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      APLOGNO(02496) "name %s, backend %s, host %s, port %d, "
                      "first address %pI, %c%c",
                      conf->name,
                      conf->backend,
                      conf->host,
                      (int)conf->port,
                      conf->backend_addrs,
                      conf->is_authn ? 'N' : '_',
                      conf->is_authz ? 'Z' : '_');
    }
    
    static void setupenv(request_rec *r, const char *password, const char *apache_role)
    {
        ap_add_common_vars(r);
        ap_add_cgi_vars(r);
        apr_table_setn(r->subprocess_env, "FCGI_ROLE", AP_FCGI_AUTHORIZER_STR);
        if (apache_role) {
            apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", apache_role);
        }
        if (password) {
            apr_table_setn(r->subprocess_env, "REMOTE_PASSWD", password);
        }
        /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED,
         * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass
         * PROXY_AUTH to allow CGI to perform proxy auth for httpd
         */
        apr_table_unset(r->subprocess_env, "CONTENT_LENGTH");
        apr_table_unset(r->subprocess_env, "PATH_INFO");
        apr_table_unset(r->subprocess_env, "PATH_TRANSLATED");
        apr_table_unset(r->subprocess_env, "SCRIPT_NAME");
        apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE");
        apr_table_unset(r->subprocess_env, "HTTP_TE");
        apr_table_unset(r->subprocess_env, "HTTP_TRAILER");
        apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING");
        apr_table_unset(r->subprocess_env, "HTTP_UPGRADE");
    
        /* Connection hop-by-hop header to prevent the CGI from hanging */
        apr_table_setn(r->subprocess_env, "HTTP_CONNECTION", "close");
    }
    
    static apr_status_t recv_data(const fcgi_provider_conf *conf,
                                  request_rec *r,
                                  apr_socket_t *s,
                                  char *buf,
                                  apr_size_t *buflen)
    {
        apr_status_t rv;
    
        rv = apr_socket_recv(s, buf, buflen);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          APLOGNO(02497) "Couldn't read from backend %s",
                          conf->backend);
            return rv;
        }
    
    #if AP_MODULE_MAGIC_AT_LEAST(20130702,2) 
        ap_log_rdata(APLOG_MARK, APLOG_TRACE5, r, "FastCGI data received",
                     buf, *buflen, AP_LOG_DATA_SHOW_OFFSET);
    #endif
        return APR_SUCCESS;
    }
    
    static apr_status_t recv_data_full(const fcgi_provider_conf *conf,
                                       request_rec *r,
                                       apr_socket_t *s,
                                       char *buf,
                                       apr_size_t buflen)
    {
        apr_size_t readlen;
        apr_size_t cumulative_len = 0;
        apr_status_t rv;
    
        do {
            readlen = buflen - cumulative_len;
            rv = recv_data(conf, r, s, buf + cumulative_len, &readlen);
            if (rv != APR_SUCCESS) {
                return rv;
            }
            cumulative_len += readlen;
        } while (cumulative_len < buflen);
    
        return APR_SUCCESS;
    }
    
    static apr_status_t sendv_data(const fcgi_provider_conf *conf,
                                   request_rec *r,
                                   apr_socket_t *s,
                                   struct iovec *vec,
                                   int nvec,
                                   apr_size_t *len)
    {
        apr_size_t to_write = 0, written = 0;
        apr_status_t rv = APR_SUCCESS;
        int i, offset;
    
        for (i = 0; i < nvec; i++) {
            to_write += vec[i].iov_len;
    #if AP_MODULE_MAGIC_AT_LEAST(20130702,2) 
            ap_log_rdata(APLOG_MARK, APLOG_TRACE5, r, "FastCGI data sent",
                         vec[i].iov_base, vec[i].iov_len, AP_LOG_DATA_SHOW_OFFSET);
    #endif
        }
    
        offset = 0;
        while (to_write) {
            apr_size_t n = 0;
            rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                              APLOGNO(02498) "Sending data to %s failed",
                              conf->backend);
                break;
            }
            if (n > 0) {
                written += n;
                if (written >= to_write)
                    break;                 /* short circuit out */
                for (i = offset; i < nvec; ) {
                    if (n >= vec[i].iov_len) {
                        offset++;
                        n -= vec[i++].iov_len;
                    } else {
                        vec[i].iov_len -= n;
                        vec[i].iov_base = (char *) vec[i].iov_base + n;
                        break;
                    }
                }
            }
        }
    
        *len = written;
    
        return rv;
    }
    
    static apr_status_t send_begin_request(request_rec *r,
                                           const fcgi_provider_conf *conf,
                                           apr_socket_t *s, int role,
                                           apr_uint16_t request_id)
    {
        struct iovec vec[2];
        ap_fcgi_header header;
        unsigned char farray[AP_FCGI_HEADER_LEN];
        ap_fcgi_begin_request_body brb;
        unsigned char abrb[AP_FCGI_HEADER_LEN];
        apr_size_t len;
    
        ap_fcgi_fill_in_header(&header, AP_FCGI_BEGIN_REQUEST, request_id,
                               sizeof(abrb), 0);
        ap_fcgi_fill_in_request_body(&brb, role, 0 /* *NOT* AP_FCGI_KEEP_CONN */);
    
        ap_fcgi_header_to_array(&header, farray);
        ap_fcgi_begin_request_body_to_array(&brb, abrb);
    
        vec[0].iov_base = (void *)farray;
        vec[0].iov_len = sizeof(farray);
        vec[1].iov_base = (void *)abrb;
        vec[1].iov_len = sizeof(abrb);
    
        return sendv_data(conf, r, s, vec, 2, &len);
    }
    
    static apr_status_t send_environment(apr_socket_t *s,
                                         const fcgi_provider_conf *conf,
                                         request_rec *r, apr_uint16_t request_id,
                                         apr_pool_t *temp_pool)
    {
        const char *fn = "send_environment";
        const apr_array_header_t *envarr;
        const apr_table_entry_t *elts;
        struct iovec vec[2];
        ap_fcgi_header header;
        unsigned char farray[AP_FCGI_HEADER_LEN];
        char *body;
        apr_status_t rv;
        apr_size_t avail_len, len, required_len;
        int i, next_elem, starting_elem;
    
        envarr = apr_table_elts(r->subprocess_env);
        elts = (const apr_table_entry_t *) envarr->elts;
    
        if (APLOG_R_IS_LEVEL(r, APLOG_TRACE2)) {
    
            for (i = 0; i < envarr->nelts; ++i) {
                if (!elts[i].key) {
                    continue;
                }
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "%s: '%s': '%s'",
                              fn, elts[i].key, 
                              !strcmp(elts[i].key, "REMOTE_PASSWD") ?
                                  "XXXXXXXX" : elts[i].val);
            }
        }
    
        /* Send envvars over in as many FastCGI records as it takes, */
        next_elem = 0; /* starting with the first one */
    
        avail_len = 16 * 1024; /* our limit per record, which could have been up
                                * to AP_FCGI_MAX_CONTENT_LEN
                                */
    
        while (next_elem < envarr->nelts) {
            starting_elem = next_elem;
            required_len = ap_fcgi_encoded_env_len(r->subprocess_env,
                                                   avail_len,
                                                   &next_elem);
    
            if (!required_len) {
                if (next_elem < envarr->nelts) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                                  APLOGNO(02499) "couldn't encode envvar '%s' in %"
                                  APR_SIZE_T_FMT " bytes",
                                  elts[next_elem].key, avail_len);
                    /* skip this envvar and continue */
                    ++next_elem;
                    continue;
                }
                /* only an unused element at the end of the array */
                break;
            }
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                          APLOGNO(02500) "required len for encoding envvars: %"
                          APR_SIZE_T_FMT ", %d/%d elems processed so far",
                          required_len, next_elem, envarr->nelts);
    
            body = apr_palloc(temp_pool, required_len);
            rv = ap_fcgi_encode_env(r, r->subprocess_env, body, required_len,
                                    &starting_elem);
            /* we pre-compute, so we can't run out of space */
            ap_assert(rv == APR_SUCCESS);
            /* compute and encode must be in sync */
            ap_assert(starting_elem == next_elem);
    
            ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id,
                                   (apr_uint16_t)required_len, 0);
            ap_fcgi_header_to_array(&header, farray);
    
            vec[0].iov_base = (void *)farray;
            vec[0].iov_len = sizeof(farray);
            vec[1].iov_base = body;
            vec[1].iov_len = required_len;
    
            rv = sendv_data(conf, r, s, vec, 2, &len);
            apr_pool_clear(temp_pool);
    
            if (rv) {
                return rv;
            }
        }
    
        /* Envvars sent, so say we're done */
        ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id, 0, 0);
        ap_fcgi_header_to_array(&header, farray);
    
        vec[0].iov_base = (void *)farray;
        vec[0].iov_len = sizeof(farray);
    
        return sendv_data(conf, r, s, vec, 1, &len);
    }
    
    /*
     * This header-state logic is from mod_proxy_fcgi.
     */
    enum {
      HDR_STATE_READING_HEADERS,
      HDR_STATE_GOT_CR,
      HDR_STATE_GOT_CRLF,
      HDR_STATE_GOT_CRLFCR,
      HDR_STATE_GOT_LF,
      HDR_STATE_DONE_WITH_HEADERS
    };
    
    /* Try to find the end of the script headers in the response from the back
     * end fastcgi server. STATE holds the current header parsing state for this
     * request.
     *
     * Returns 0 if it can't find the end of the headers, and 1 if it found the
     * end of the headers. */
    static int handle_headers(request_rec *r, int *state,
                              const char *readbuf, apr_size_t readlen)
    {
        const char *itr = readbuf;
    
        while (readlen--) {
            if (*itr == '\r') {
                switch (*state) {
                    case HDR_STATE_GOT_CRLF:
                        *state = HDR_STATE_GOT_CRLFCR;
                        break;
    
                    default:
                        *state = HDR_STATE_GOT_CR;
                        break;
                }
            }
            else if (*itr == '\n') {
                switch (*state) {
                     case HDR_STATE_GOT_LF:
                         *state = HDR_STATE_DONE_WITH_HEADERS;
                         break;
    
                     case HDR_STATE_GOT_CR:
                         *state = HDR_STATE_GOT_CRLF;
                         break;
    
                     case HDR_STATE_GOT_CRLFCR:
                         *state = HDR_STATE_DONE_WITH_HEADERS;
                         break;
    
                     default:
                         *state = HDR_STATE_GOT_LF;
                         break;
                }
            }
            else {
                *state = HDR_STATE_READING_HEADERS;
            }
    
            if (*state == HDR_STATE_DONE_WITH_HEADERS)
                break;
    
            ++itr;
        }
    
        if (*state == HDR_STATE_DONE_WITH_HEADERS) {
            return 1;
        }
    
        return 0;
    }
    
    /*
     * handle_response() is based on mod_proxy_fcgi's dispatch()
     */
    static apr_status_t handle_response(const fcgi_provider_conf *conf,
                                        request_rec *r, apr_socket_t *s,
                                        apr_pool_t *temp_pool,
                                        apr_uint16_t request_id,
                                        char *rspbuf,
                                        apr_size_t *rspbuflen)
    {
        apr_bucket *b;
        apr_bucket_brigade *ob;
        apr_size_t orspbuflen = 0;
        apr_status_t rv = APR_SUCCESS;
        const char *fn = "handle_response";
        int header_state = HDR_STATE_READING_HEADERS;
        int seen_end_of_headers = 0, done = 0;
    
        if (rspbuflen) {
            orspbuflen = *rspbuflen;
            *rspbuflen = 0; /* unless we actually read something */
        }
    
        ob = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        while (!done && rv == APR_SUCCESS) { /* Keep reading FastCGI records until
                                              * we get AP_FCGI_END_REQUEST (done)
                                              * or an error occurs.
                                              */
            apr_size_t readbuflen;
            apr_uint16_t clen;
            apr_uint16_t rid;
            char readbuf[AP_IOBUFSIZE + 1];
            unsigned char farray[AP_FCGI_HEADER_LEN];
            unsigned char plen;
            unsigned char type;
            unsigned char version;
    
            rv = recv_data_full(conf, r, s, (char *)farray, AP_FCGI_HEADER_LEN);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                              APLOGNO(02501) "%s: Error occurred before reading "
                              "entire header", fn);
                break;
            }
    
            ap_fcgi_header_fields_from_array(&version, &type, &rid, &clen, &plen,
                                             farray);
    
            if (version != AP_FCGI_VERSION_1) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              APLOGNO(02502) "%s: Got bogus FastCGI header "
                              "version %d", fn, (int)version);
                rv = APR_EINVAL;
                break;
            }
    
            if (rid != request_id) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              APLOGNO(02503) "%s: Got bogus FastCGI header "
                              "request id %d, expected %d",
                              fn, rid, request_id);
                rv = APR_EINVAL;
                break;
            }
    
        recv_again: /* if we need to keep reading more of a record's content */
    
            if (clen > sizeof(readbuf) - 1) {
                readbuflen = sizeof(readbuf) - 1;
            } else {
                readbuflen = clen;
            }
    
            /*
             * Now get the actual content of the record.
             */
            if (readbuflen != 0) {
                rv = recv_data(conf, r, s, readbuf, &readbuflen);
                if (rv != APR_SUCCESS) {
                    break;
                }
                readbuf[readbuflen] = '\0';
            }
    
            switch (type) {
            case AP_FCGI_STDOUT: /* Response headers and optional body */
                if (clen != 0) {
                    b = apr_bucket_transient_create(readbuf,
                                                    readbuflen,
                                                    r->connection->bucket_alloc);
    
                    APR_BRIGADE_INSERT_TAIL(ob, b);
    
                    if (!seen_end_of_headers) {
                        int st = handle_headers(r, &header_state,
                                                readbuf, readbuflen);
    
                        if (st == 1) {
                            int status;
    
                            seen_end_of_headers = 1;
    
                            status =
                                ap_scan_script_header_err_brigade_ex(r, ob,
                                                                     NULL, 
                                                                     APLOG_MODULE_INDEX);
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                                          APLOGNO(02504) "%s: script header "
                                          "parsing -> %d/%d",
                                          fn, status, r->status);
    
                            /* FCGI has its own body framing mechanism which we don't
                             * match against any provided Content-Length, so let the
                             * core determine C-L vs T-E based on what's actually sent.
                             */
                            if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
                                apr_table_unset(r->headers_out, "Content-Length");
                            apr_table_unset(r->headers_out, "Transfer-Encoding");
    
                            if (rspbuf) { /* caller wants to see response body,
                                           * if any
                                           */
                                apr_status_t tmprv;
    
                                if (rspbuflen) {
                                    *rspbuflen = orspbuflen;
                                }
                                tmprv = apr_brigade_flatten(ob, rspbuf, rspbuflen);
                                if (tmprv != APR_SUCCESS) {
                                    /* should not occur for these bucket types;
                                     * does not indicate overflow
                                     */
                                    ap_log_rerror(APLOG_MARK, APLOG_ERR, tmprv, r,
                                                  APLOGNO(02505) "%s: error "
                                                  "flattening response body",
                                                  fn);
                                }
                            }
    
                            if (status != OK) {
                                r->status = status;
                                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                              APLOGNO(02506) "%s: Error parsing "
                                              "script headers from %s",
                                              fn, conf->backend);
                                rv = APR_EINVAL;
                                break;
                            }
                            apr_pool_clear(temp_pool);
                        }
                        else {
                            /* We're still looking for the end of the
                             * headers, so this part of the data will need
                             * to persist. */
                            apr_bucket_setaside(b, temp_pool);
                        }
                    }
    
                    /* If we didn't read all the data go back and get the
                     * rest of it. */
                    if (clen > readbuflen) {
                        clen -= readbuflen;
                        goto recv_again;
                    }
                }
                break;
    
            case AP_FCGI_STDERR: /* Text to log */
                if (clen) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                                  APLOGNO(02507) "%s: Logged from %s: '%s'",
                                  fn, conf->backend, readbuf);
                }
    
                if (clen > readbuflen) {
                    clen -= readbuflen;
                    goto recv_again; /* continue reading this record */
                }
                break;
    
            case AP_FCGI_END_REQUEST:
                done = 1;
                break;
    
            default:
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              APLOGNO(02508) "%s: Got bogus FastCGI record type "
                              "%d", fn, type);
                break;
            }
            /* Leave on above switch's inner error. */
            if (rv != APR_SUCCESS) {
                break;
            }
    
            /*
             * Read/discard any trailing padding.
             */
            if (plen) {
                rv = recv_data_full(conf, r, s, readbuf, plen);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                                  APLOGNO(02509) "%s: Error occurred reading "
                                  "padding",
                                  fn);
                    break;
                }
            }
        }
    
        apr_brigade_cleanup(ob);
    
        if (rv == APR_SUCCESS && !seen_end_of_headers) {
            rv = APR_EINVAL;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          APLOGNO(02510) "%s: Never reached end of script headers",
                          fn);
        }
    
        return rv;
    }
    
    /* almost from mod_fcgid */
    static int mod_fcgid_modify_auth_header(void *vars,
                                            const char *key, const char *val)
    {
        /* When the application gives a 200 response, the server ignores response
           headers whose names aren't prefixed with Variable- prefix, and ignores
           any response content */
        if (ap_cstr_casecmpn(key, "Variable-", 9) == 0)
            apr_table_setn(vars, key, val);
        return 1;
    }
    
    static int fix_auth_header(void *vr, const char *key, const char *val)
    {
        request_rec *r = vr;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "moving %s->%s", key, val);
        apr_table_unset(r->err_headers_out, key);
        apr_table_setn(r->subprocess_env, key + 9, val);
        return 1;
    }
    
    static void req_rsp(request_rec *r, const fcgi_provider_conf *conf,
                        const char *password, const char *apache_role,
                        char *rspbuf, apr_size_t *rspbuflen)
    {
        const char *fn = "req_rsp";
        apr_pool_t *temp_pool;
        apr_size_t orspbuflen = 0;
        apr_socket_t *s;
        apr_status_t rv;
        apr_table_t *saved_subprocess_env = 
          apr_table_copy(r->pool, r->subprocess_env);
    
        if (rspbuflen) {
            orspbuflen = *rspbuflen;
            *rspbuflen = 0; /* unless we actually read something */
        }
    
        apr_pool_create(&temp_pool, r->pool);
        apr_pool_tag(temp_pool, "mod_authnz_fcgi (req_rsp)");
    
        setupenv(r, password, apache_role);
    
        rv = connect_to_peer(&s, r, conf->backend_addrs,
                             conf->backend, FCGI_IO_TIMEOUT);
        if (rv == APR_SUCCESS) {
            apr_uint16_t request_id = 1;
    
            rv = send_begin_request(r, conf, s, AP_FCGI_AUTHORIZER, request_id);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                              APLOGNO(02511) "%s: Failed writing request to %s",
                              fn, conf->backend);
            }
    
            if (rv == APR_SUCCESS) {
                rv = send_environment(s, conf, r, request_id, temp_pool);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                                  APLOGNO(02512) "%s: Failed writing environment "
                                  "to %s", fn, conf->backend);
                }
            }
    
            /* The responder owns the request body, not the authorizer.
             * Don't even send an empty AP_FCGI_STDIN block.  libfcgi doesn't care,
             * but it wasn't sent to authorizers by mod_fastcgi or mod_fcgi and
             * may be unhandled by the app.  Additionally, the FastCGI spec does
             * not mention FCGI_STDIN in the Authorizer description, though it
             * does describe FCGI_STDIN elsewhere in more general terms than
             * simply a wrapper for the client's request body.
             */
    
            if (rv == APR_SUCCESS) {
                if (rspbuflen) {
                    *rspbuflen = orspbuflen;
                }
                rv = handle_response(conf, r, s, temp_pool, request_id, rspbuf,
                                     rspbuflen);
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                                  APLOGNO(02514) "%s: Failed handling response "
                                  "from %s", fn, conf->backend);
                }
            }
    
            apr_socket_close(s);
        }
    
        if (rv != APR_SUCCESS) {
            /* some sort of mechanical problem */
            r->status = HTTP_INTERNAL_SERVER_ERROR;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                          APLOGNO(02515) "%s: Received HTTP status %d",
                          fn, r->status);
        }
    
        r->subprocess_env = saved_subprocess_env;
    
        if (r->status == HTTP_OK) {
            /* An Authorizer application's 200 response may include headers
             * whose names are prefixed with Variable-, and they should be
             * available to subsequent phases via subprocess_env (and yanked
             * from the client response).
             */
            apr_table_t *vars = apr_table_make(temp_pool, /* not used to allocate
                                                           * any values that end up
                                                           * in r->(anything)
                                                           */
                                               10);
            apr_table_do(mod_fcgid_modify_auth_header, vars,
                         r->err_headers_out, NULL);
            apr_table_do(fix_auth_header, r, vars, NULL);
        }
    
        apr_pool_destroy(temp_pool);
    }
    
    static int fcgi_check_authn(request_rec *r)
    {
        const char *fn = "fcgi_check_authn";
        fcgi_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                    &authnz_fcgi_module);
        const char *password = NULL;
        const fcgi_provider_conf *conf;
        const char *prov;
        const char *auth_type;
        char rspbuf[NON200_RESPONSE_BUF_LEN + 1]; /* extra byte for '\0' */
        apr_size_t rspbuflen = sizeof rspbuf - 1;
        int res;
    
        prov = dconf && dconf->name ? dconf->name : NULL;
    
        if (!prov || !ap_cstr_casecmp(prov, "None")) {
            return DECLINED;
        }
    
        auth_type = ap_auth_type(r);
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      APLOGNO(02516) "%s, prov %s, authoritative %s, "
                      "require-basic %s, user expr? %s type %s",
                      fn, prov,
                      dconf->authoritative ? "yes" : "no",
                      dconf->require_basic_auth ? "yes" : "no",
                      dconf->user_expr ? "yes" : "no",
                      auth_type);
    
        if (auth_type && !ap_cstr_casecmp(auth_type, "Basic")) {
            if ((res = ap_get_basic_auth_pw(r, &password))) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                              APLOGNO(02517) "%s: couldn't retrieve basic auth "
                              "password", fn);
                if (dconf->require_basic_auth) {
                    return res;
                }
                password = NULL;
            }
        }
    
        conf = apr_hash_get(fcgi_authn_providers, prov, APR_HASH_KEY_STRING);
        if (!conf) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
                          APLOGNO(02518) "%s: can't find config for provider %s",
                          fn, prov);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        if (APLOGrdebug(r)) {
            log_provider_info(conf, r);
        }
    
        req_rsp(r, conf, password, AP_FCGI_APACHE_ROLE_AUTHENTICATOR_STR,
                rspbuf, &rspbuflen);
    
        if (r->status == HTTP_OK) {
            if (dconf->user_expr) {
                const char *err;
                const char *user = ap_expr_str_exec(r, dconf->user_expr,
                                                    &err);
                if (user && strlen(user)) {
                    r->user = apr_pstrdup(r->pool, user);
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                                  APLOGNO(02519) "%s: Setting user to '%s'",
                                  fn, r->user);
                }
                else if (user && dconf->default_user) {
                    r->user = apr_pstrdup(r->pool, dconf->default_user);
                }
                else if (user) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                  APLOGNO(02520) "%s: Failure extracting user "
                                  "after calling authorizer: user expression "
                                  "yielded empty string (variable not set?)",
                                  fn);
                    r->status = HTTP_INTERNAL_SERVER_ERROR;
                }
                else {
                    /* unexpected error, not even an empty string was returned */
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                  APLOGNO(02521) "%s: Failure extracting user "
                                  "after calling authorizer: %s",
                                  fn, err);
                    r->status = HTTP_INTERNAL_SERVER_ERROR;
                }
            }
            if (conf->is_authz) {
                /* combined authn/authz phase, so app won't be invoked for authz
                 *
                 * Remember that the request was successfully authorized by this
                 * provider.
                 */
                fcgi_request_notes *rnotes = apr_palloc(r->pool, sizeof(*rnotes));
                rnotes->successful_authnz_provider = conf->name;
                ap_set_module_config(r->request_config, &authnz_fcgi_module,
                                     rnotes);
            }
        }
        else {
            /* From the spec:
             *   For Authorizer response status values other than "200" (OK), the 
             *   Web server denies access and sends the response status, headers,
             *   and content back to the HTTP client.
             * But:
             *   This only makes sense if this authorizer is authoritative.
             */
            if (rspbuflen > 0 && !dconf->authoritative) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                              APLOGNO(02522) "%s: Ignoring response body from non-"
                              "authoritative authorizer", fn);
            }
            else if (rspbuflen > 0) {
                if (rspbuflen == sizeof rspbuf - 1) {
                    /* apr_brigade_flatten() interface :( */
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                                  APLOGNO(02523) "%s: possible overflow handling "
                                  "response body", fn);
                }
                rspbuf[rspbuflen] = '\0'; /* we reserved an extra byte for '\0' */
                ap_custom_response(r, r->status, rspbuf); /* API makes a copy */
            }
        }
    
        return r->status == HTTP_OK ? 
            OK : dconf->authoritative ? r->status : DECLINED;
    }
    
    static authn_status fcgi_check_password(request_rec *r, const char *user,
                                            const char *password)
    {
        const char *fn = "fcgi_check_password";
        const char *prov = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
        const fcgi_provider_conf *conf;
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      APLOGNO(02524) "%s(%s, XXX): provider %s",
                      fn, user, prov);
    
        if (!prov) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
                          APLOGNO(02525) "%s: provider note isn't set", fn);
            return AUTH_GENERAL_ERROR;
        }
    
        conf = apr_hash_get(fcgi_authn_providers, prov, APR_HASH_KEY_STRING);
        if (!conf) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
                          APLOGNO(02526) "%s: can't find config for provider %s",
                          fn, prov);
            return AUTH_GENERAL_ERROR;
        }
    
        if (APLOGrdebug(r)) {
            log_provider_info(conf, r);
        }
    
        req_rsp(r, conf, password, 
                /* combined authn and authz: FCGI_APACHE_ROLE not set */
                conf->is_authz ? NULL : AP_FCGI_APACHE_ROLE_AUTHENTICATOR_STR,
                NULL, NULL);
    
        if (r->status == HTTP_OK) {
            if (conf->is_authz) {
                /* combined authn/authz phase, so app won't be invoked for authz
                 *
                 * Remember that the request was successfully authorized by this
                 * provider.
                 */
                fcgi_request_notes *rnotes = apr_palloc(r->pool, sizeof(*rnotes));
                rnotes->successful_authnz_provider = conf->name;
                ap_set_module_config(r->request_config, &authnz_fcgi_module,
                                     rnotes);
            }
            return AUTH_GRANTED;
        }
        else if (r->status == HTTP_INTERNAL_SERVER_ERROR) {
            return AUTH_GENERAL_ERROR;
        }
        else {
            return AUTH_DENIED;
        }
    }
    
    static const authn_provider fcgi_authn_provider = {
        &fcgi_check_password,
        NULL /* get-realm-hash not supported */
    };
    
    static authz_status fcgi_authz_check(request_rec *r,
                                         const char *require_line,
                                         const void *parsed_require_line)
    {
        const char *fn = "fcgi_authz_check";
        const char *prov = apr_table_get(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
        const fcgi_provider_conf *conf;
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      APLOGNO(02527) "%s(%s)", fn, require_line);
    
        if (!prov) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
                          APLOGNO(02528) "%s: provider note isn't set", fn);
            return AUTHZ_GENERAL_ERROR;
        }
    
        conf = apr_hash_get(fcgi_authz_providers, prov, APR_HASH_KEY_STRING);
        if (!conf) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
                          APLOGNO(02529) "%s: can't find config for provider %s",
                          fn, prov);
            return AUTHZ_GENERAL_ERROR;
        }
    
        if (APLOGrdebug(r)) {
            log_provider_info(conf, r);
        }
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (conf->is_authn) {
            /* combined authn/authz phase, so app won't be invoked for authz
             *
             * If the provider already successfully authorized this request, 
             * success.
             */
            fcgi_request_notes *rnotes = ap_get_module_config(r->request_config,
                                                            &authnz_fcgi_module);
            if (rnotes
                && rnotes->successful_authnz_provider
                && !strcmp(rnotes->successful_authnz_provider, conf->name)) {
                return AUTHZ_GRANTED;
            }
            else {
                return AUTHZ_DENIED;
            }
        }
        else {
            req_rsp(r, conf, NULL, AP_FCGI_APACHE_ROLE_AUTHORIZER_STR, NULL, NULL);
    
            if (r->status == HTTP_OK) {
                return AUTHZ_GRANTED;
            }
            else if (r->status == HTTP_INTERNAL_SERVER_ERROR) {
                return AUTHZ_GENERAL_ERROR;
            }
            else {
                return AUTHZ_DENIED;
            }
        }
    }
    
    static const char *fcgi_authz_parse(cmd_parms *cmd, const char *require_line,
                                        const void **parsed_require_line)
    {
        /* Allowed form: Require [not] registered-provider-name<EOS>
         */
        if (strcmp(require_line, "")) {
            return "mod_authnz_fcgi doesn't support restrictions on providers "
                   "(i.e., multiple require args)";
        }
    
        return NULL;
    }
    
    static const authz_provider fcgi_authz_provider = {
        &fcgi_authz_check,
        &fcgi_authz_parse,
    };
    
    static const char *fcgi_check_authn_provider(cmd_parms *cmd,
                                            void *d,
                                            int argc,
                                            char *const argv[])
    {
        const char *dname = "AuthnzFcgiCheckAuthnProvider";
        fcgi_dir_conf *dc = d;
        int ca = 0;
    
        if (ca >= argc) {
            return apr_pstrcat(cmd->pool, dname, ": No provider given", NULL);
        }
    
        dc->name = argv[ca];
        ca++;
    
        if (!strcasecmp(dc->name, "None")) {
            if (ca < argc) {
                return "Options aren't supported with \"None\"";
            }
        }
    
        while (ca < argc) {
            const char *var = argv[ca], *val;
            int badarg = 0;
    
            ca++;
    
            /* at present, everything needs an argument */
            if (ca >= argc) {
                return apr_pstrcat(cmd->pool, dname, ": ", var,
                                   "needs an argument", NULL);
            }
    
            val = argv[ca];
            ca++;
    
            if (!strcasecmp(var, "Authoritative")) {
                if (!strcasecmp(val, "On")) {
                    dc->authoritative = 1;
                }
                else if (!strcasecmp(val, "Off")) {
                    dc->authoritative = 0;
                }
                else {
                    badarg = 1;
                }
            }
            else if (!strcasecmp(var, "DefaultUser")) {
                dc->default_user = val;
            }
            else if (!strcasecmp(var, "RequireBasicAuth")) {
                if (!strcasecmp(val, "On")) {
                    dc->require_basic_auth = 1;
                }
                else if (!strcasecmp(val, "Off")) {
                    dc->require_basic_auth = 0;
                }
                else {
                    badarg = 1;
                }
            }
            else if (!strcasecmp(var, "UserExpr")) {
                const char *err;
                int flags = AP_EXPR_FLAG_DONT_VARY | AP_EXPR_FLAG_RESTRICTED
                    | AP_EXPR_FLAG_STRING_RESULT;
    
                dc->user_expr = ap_expr_parse_cmd(cmd, val,
                                                  flags, &err, NULL);
                if (err) {
                    return apr_psprintf(cmd->pool, "%s: Error parsing '%s': '%s'",
                                        dname, val, err);
                }
            }
            else {
                return apr_pstrcat(cmd->pool, dname, ": Unexpected option '",
                                   var, "'", NULL);
            }
            if (badarg) {
                return apr_pstrcat(cmd->pool, dname, ": Bad argument '",
                                   val, "' to option '", var, "'", NULL);
            }
        }
    
        return NULL;
    }
    
    /* AuthnzFcgiAuthDefineProvider {authn|authz|authnz} provider-name \
     *   fcgi://backendhost:backendport/
     */
    static const char *fcgi_define_provider(cmd_parms *cmd,
                                            void *d,
                                            int argc,
                                            char *const argv[])
    {
        const char *dname = "AuthnzFcgiDefineProvider";
        ap_rxplus_t *fcgi_backend_regex;
        apr_status_t rv;
        char *host;
        const char *err, *stype;
        fcgi_provider_conf *conf = apr_pcalloc(cmd->pool, sizeof(*conf));
        int ca = 0, rc, port;
    
        fcgi_backend_regex = ap_rxplus_compile(cmd->pool, FCGI_BACKEND_REGEX_STR);
        if (!fcgi_backend_regex) {
            return apr_psprintf(cmd->pool,
                                "%s: failed to compile regexec '%s'",
                                dname, FCGI_BACKEND_REGEX_STR);
        }
    
        err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err)
            return err;
    
        if (ca >= argc) {
            return apr_pstrcat(cmd->pool, dname, ": No type given", NULL);
        }
    
        stype = argv[ca];
        ca++;
    
        if (!strcasecmp(stype, "authn")) {
            conf->is_authn = 1;
        }
        else if (!strcasecmp(stype, "authz")) {
            conf->is_authz = 1;
        }
        else if (!strcasecmp(stype, "authnz")) {
            conf->is_authn = conf->is_authz = 1;
        }
        else {
            return apr_pstrcat(cmd->pool,
                               dname,
                               ": Invalid provider type ",
                               stype,
                               NULL);
        }
    
        if (ca >= argc) {
            return apr_pstrcat(cmd->pool, dname, ": No provider name given", NULL);
        }
        conf->name = argv[ca];
        ca++;
    
        if (ca >= argc) {
            return apr_pstrcat(cmd->pool, dname, ": No backend-address given",
                               NULL);
        }
    
        rc = ap_rxplus_exec(cmd->pool, fcgi_backend_regex, argv[ca], NULL);
        if (!rc || ap_rxplus_nmatch(fcgi_backend_regex) != 3) {
            return apr_pstrcat(cmd->pool,
                               dname, ": backend-address '",
                               argv[ca],
                               "' has invalid form",
                               NULL);
        }
    
        host = ap_rxplus_pmatch(cmd->pool, fcgi_backend_regex, 1);
        if (host[0] == '[' && host[strlen(host) - 1] == ']') {
            host += 1;
            host[strlen(host) - 1] = '\0';
        }
    
        port = atoi(ap_rxplus_pmatch(cmd->pool, fcgi_backend_regex, 2));
        if (port > 65535) {
            return apr_pstrcat(cmd->pool,
                               dname, ": backend-address '",
                               argv[ca],
                               "' has invalid port",
                               NULL);
        }
    
        conf->backend = argv[ca];
        conf->host = host;
        conf->port = port;
        ca++;
    
        rv = apr_sockaddr_info_get(&conf->backend_addrs, conf->host,
                                   APR_UNSPEC, conf->port, 0, cmd->pool);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, rv, NULL,
                         APLOGNO(02530) "Address %s could not be resolved",
                         conf->backend);
            return apr_pstrcat(cmd->pool,
                               dname,
                               ": Error resolving backend address",
                               NULL);
        }
    
        if (ca != argc) {
            return apr_pstrcat(cmd->pool,
                               dname,
                               ": Unexpected parameter ",
                               argv[ca],
                               NULL);
        }
    
        if (conf->is_authn) {
            apr_hash_set(fcgi_authn_providers, conf->name, APR_HASH_KEY_STRING,
                         conf);
            ap_register_auth_provider(cmd->pool, AUTHN_PROVIDER_GROUP,
                                      conf->name,
                                      AUTHN_PROVIDER_VERSION,
                                      &fcgi_authn_provider,
                                      AP_AUTH_INTERNAL_PER_CONF);
        }
    
        if (conf->is_authz) {
            apr_hash_set(fcgi_authz_providers, conf->name, APR_HASH_KEY_STRING,
                         conf);
            ap_register_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP,
                                      conf->name,
                                      AUTHZ_PROVIDER_VERSION,
                                      &fcgi_authz_provider,
                                      AP_AUTH_INTERNAL_PER_CONF);
        }
    
        return NULL;
    }
    
    static const command_rec fcgi_cmds[] = {
        AP_INIT_TAKE_ARGV("AuthnzFcgiDefineProvider", 
                          fcgi_define_provider,
                          NULL,
                          RSRC_CONF,
                          "Define a FastCGI authn and/or authz provider"),
    
        AP_INIT_TAKE_ARGV("AuthnzFcgiCheckAuthnProvider",
                          fcgi_check_authn_provider,
                          NULL,
                          OR_FILEINFO,
                          "Enable/disable a FastCGI authorizer to handle "
                          "check_authn phase"),
    
        {NULL}
    };
    
    static int fcgi_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                               apr_pool_t *ptemp)
    {
        fcgi_authn_providers = apr_hash_make(pconf);
        fcgi_authz_providers = apr_hash_make(pconf);
    
        return OK;
    }
    
    static void fcgi_register_hooks(apr_pool_t *p)
    {
        static const char * const auth_basic_runs_after_me[] = 
            {"mod_auth_basic.c", NULL}; /* to allow for custom response */
    
        ap_hook_pre_config(fcgi_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_authn(fcgi_check_authn, NULL, auth_basic_runs_after_me,
                            APR_HOOK_MIDDLE, AP_AUTH_INTERNAL_PER_CONF);
    }
    
    static void *create_dir_conf(apr_pool_t *p, char *dummy)
    {
        fcgi_dir_conf *dconf = apr_pcalloc(p, sizeof(fcgi_dir_conf));
    
        dconf->authoritative = 1;
        return dconf;
    }
    
    static void *merge_dir_conf(apr_pool_t *p, void *basev, void *overridesv)
    {
        fcgi_dir_conf *a = (fcgi_dir_conf *)apr_pcalloc(p, sizeof(*a));
        fcgi_dir_conf *base = (fcgi_dir_conf *)basev, 
            *over = (fcgi_dir_conf *)overridesv;
    
        /* currently we just have a single directive applicable to a 
         * directory, so if it is set then grab all fields from fcgi_dir_conf
         */
        if (over->name) {
            memcpy(a, over, sizeof(*a));
        }
        else {
            memcpy(a, base, sizeof(*a));
        }
        
        return a;
    }
    
    AP_DECLARE_MODULE(authnz_fcgi) =
    {
        STANDARD20_MODULE_STUFF,
        create_dir_conf,                 /* dir config creater */
        merge_dir_conf,                  /* dir merger */
        NULL,                            /* server config */
        NULL,                            /* merge server config */
        fcgi_cmds,                       /* command apr_table_t */
        fcgi_register_hooks              /* register hooks */
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbd.c������������������������������������������������������������0000664�0001751�0001751�00000033763�14246213552�020003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "http_config.h"
    #include "ap_provider.h"
    #include "http_request.h"
    #include "http_protocol.h"
    #include "http_core.h"
    #include "apr_dbd.h"
    #include "mod_dbd.h"
    #include "apr_strings.h"
    #include "mod_authz_dbd.h"
    
    #include "mod_auth.h"
    
    
    module AP_MODULE_DECLARE_DATA authz_dbd_module;
    
    /* Export a hook for modules that manage clientside sessions
     * (e.g. mod_auth_cookie)
     * to deal with those when we successfully login/logout at the server
     *
     * XXX: WHY would this be specific to dbd_authz?  Why wouldn't we track
     * this across all authz user providers in a lower level mod, such as
     * mod_auth_basic/digest?
     */
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(authz_dbd, AUTHZ_DBD, int, client_login,
                                (request_rec *r, int code, const char *action),
                                (r, code, action), OK, DECLINED)
    
    
    typedef struct {
        const char *query;
        const char *redir_query;
        int redirect;
    } authz_dbd_cfg ;
    
    static ap_dbd_t *(*dbd_handle)(request_rec*) = NULL;
    static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
    
    static const char *const noerror = "???";
    
    static void *authz_dbd_cr_cfg(apr_pool_t *pool, char *dummy)
    {
        authz_dbd_cfg *ret = apr_pcalloc(pool, sizeof(authz_dbd_cfg));
        ret->redirect = -1;
        return ret;
    }
    
    static void *authz_dbd_merge_cfg(apr_pool_t *pool, void *BASE, void *ADD)
    {
        authz_dbd_cfg *base = BASE;
        authz_dbd_cfg *add = ADD;
        authz_dbd_cfg *ret = apr_palloc(pool, sizeof(authz_dbd_cfg));
    
        ret->query = (add->query == NULL) ? base->query : add->query;
        ret->redir_query = (add->redir_query == NULL)
                                ? base->redir_query : add->redir_query;
        ret->redirect = (add->redirect == -1) ? base->redirect : add->redirect;
        return ret;
    }
    
    static const char *authz_dbd_prepare(cmd_parms *cmd, void *cfg,
                                         const char *query)
    {
        static unsigned int label_num = 0;
        char *label;
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return err;
    
        if (dbd_prepare == NULL) {
            dbd_prepare = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
            if (dbd_prepare == NULL) {
                return "You must load mod_dbd to enable AuthzDBD functions";
            }
            dbd_handle = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
        }
        label = apr_psprintf(cmd->pool, "authz_dbd_%d", ++label_num);
    
        dbd_prepare(cmd->server, query, label);
    
        /* save the label here for our own use */
        return ap_set_string_slot(cmd, cfg, label);
    }
    
    static const command_rec authz_dbd_cmds[] = {
        AP_INIT_FLAG("AuthzDBDLoginToReferer", ap_set_flag_slot,
                     (void*)APR_OFFSETOF(authz_dbd_cfg, redirect), ACCESS_CONF,
                     "Whether to redirect to referer on successful login"),
        AP_INIT_TAKE1("AuthzDBDQuery", authz_dbd_prepare,
                      (void*)APR_OFFSETOF(authz_dbd_cfg, query), ACCESS_CONF,
                      "SQL query for DBD Authz or login"),
        AP_INIT_TAKE1("AuthzDBDRedirectQuery", authz_dbd_prepare,
                      (void*)APR_OFFSETOF(authz_dbd_cfg, redir_query), ACCESS_CONF,
                      "SQL query to get per-user redirect URL after login"),
        {NULL}
    };
    
    static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg,
                               const char *action)
    {
        int rv;
        const char *newuri = NULL;
        int nrows;
        const char *message;
        ap_dbd_t *dbd;
        apr_dbd_prepared_t *query;
        apr_dbd_results_t *res = NULL;
        apr_dbd_row_t *row = NULL;
    
        if (cfg->query == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01642)
                          "No query configured for %s!", action);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        
        dbd = dbd_handle(r);
        if (dbd == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02902)
                          "No db handle available for %s! "
                          "Check your database access",
                          action);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING);
        if (query == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643)
                          "Error retrieving Query for %s!", action);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        rv = apr_dbd_pvquery(dbd->driver, r->pool, dbd->handle, &nrows,
                             query, r->user, NULL);
        if (rv == 0) {
            if (nrows != 1) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01644)
                              "authz_dbd: %s of user %s updated %d rows",
                              action, r->user, nrows);
            }
        }
        else {
            message = apr_dbd_error(dbd->driver, dbd->handle, rv);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01645)
                          "authz_dbd: query for %s failed; user %s [%s]",
                          action, r->user, message?message:noerror);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        if (cfg->redirect == 1) {
            newuri = apr_table_get(r->headers_in, "Referer");
        }
    
        if (!newuri && cfg->redir_query) {
            query = apr_hash_get(dbd->prepared, cfg->redir_query,
                                 APR_HASH_KEY_STRING);
            if (query == NULL) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01646)
                              "authz_dbd: no redirect query!");
                /* OK, this is non-critical; we can just not-redirect */
            }
            else if ((rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle,
                                            &res, query, 0, r->user, NULL)) == 0) {
                for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
                     rv != -1;
                     rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
                    if (rv != 0) {
                        message = apr_dbd_error(dbd->driver, dbd->handle, rv);
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01647)
                              "authz_dbd in get_row; action=%s user=%s [%s]",
                              action, r->user, message?message:noerror);
                    }
                    else if (newuri == NULL) {
                        newuri =
                            apr_pstrdup(r->pool,
                                        apr_dbd_get_entry(dbd->driver, row, 0));
                    }
                    /* we can't break out here or row won't get cleaned up */
                }
            }
            else {
                message = apr_dbd_error(dbd->driver, dbd->handle, rv);
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01648)
                              "authz_dbd/redirect for %s of %s [%s]",
                              action, r->user, message?message:noerror);
            }
        }
        if (newuri != NULL) {
            r->status = HTTP_MOVED_TEMPORARILY;
            apr_table_set(r->err_headers_out, "Location", newuri);
        }
        authz_dbd_run_client_login(r, OK, action);
        return OK;
    }
    
    static int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg,
                                     apr_array_header_t *groups)
    {
        /* SELECT user_group FROM authz WHERE user = %s */
        int rv;
        const char *message;
        ap_dbd_t *dbd;
        apr_dbd_prepared_t *query;
        apr_dbd_results_t *res = NULL;
        apr_dbd_row_t *row = NULL;
    
        if (cfg->query == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01649)
                          "No query configured for dbd-group!");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        
        dbd = dbd_handle(r);
        if (dbd == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02903)
                          "No db handle available for dbd-query! "
                          "Check your database access");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING);
        if (query == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01650)
                          "Error retrieving query for dbd-group!");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
                              query, 0, r->user, NULL);
        if (rv == 0) {
            for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
                 rv != -1;
                 rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
                if (rv == 0) {
                    APR_ARRAY_PUSH(groups, const char *) =
                        apr_pstrdup(r->pool,
                                    apr_dbd_get_entry(dbd->driver, row, 0));
                }
                else {
                    message = apr_dbd_error(dbd->driver, dbd->handle, rv);
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01651)
                            "authz_dbd in get_row; user_group query for user=%s [%s]",
                            r->user, message?message:noerror);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
        }
        else {
            message = apr_dbd_error(dbd->driver, dbd->handle, rv);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01652)
                          "authz_dbd, in groups query for %s [%s]",
                          r->user, message?message:noerror);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        return OK;
    }
    
    static authz_status dbdgroup_check_authorization(request_rec *r,
                                                     const char *require_args,
                                                     const void *parsed_require_args)
    {
        int rv;
        const char *w;
        apr_array_header_t *groups;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t;
        authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                  &authz_dbd_module);
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        groups = apr_array_make(r->pool, 4, sizeof(const char*));
        rv = authz_dbd_group_query(r, cfg, groups);
        if (rv != OK) {
            return AUTHZ_GENERAL_ERROR;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02590)
                          "authz_dbd authorize: require dbd-group: Can't "
                          "evaluate require expression: %s", err);
            return AUTHZ_DENIED;
        }
    
        t = require;
        while (t[0]) {
            w = ap_getword_white(r->pool, &t);
            if (ap_array_str_contains(groups, w)) {
                return AUTHZ_GRANTED;
            }
        }
    
        return AUTHZ_DENIED;
    }
    
    static authz_status dbdlogin_check_authorization(request_rec *r,
                                                     const char *require_args,
                                                     const void *parsed_require_args)
    {
        authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                  &authz_dbd_module);
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        return (authz_dbd_login(r, cfg, "login") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED);
    }
    
    static authz_status dbdlogout_check_authorization(request_rec *r,
                                                      const char *require_args,
                                                      const void *parsed_require_args)
    {
        authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                  &authz_dbd_module);
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        return (authz_dbd_login(r, cfg, "logout") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED);
    }
    
    static const char *dbd_parse_config(cmd_parms *cmd, const char *require_line,
                                        const void **parsed_require_line)
    {
        const char *expr_err = NULL;
        ap_expr_info_t *expr;
    
        expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
                                 &expr_err, NULL);
    
        if (expr_err) {
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression in require line: ",
                               expr_err, NULL);
        }
    
        *parsed_require_line = expr;
    
        return NULL;
    }
    
    static const authz_provider authz_dbdgroup_provider =
    {
        &dbdgroup_check_authorization,
        &dbd_parse_config,
    };
    
    static const authz_provider authz_dbdlogin_provider =
    {
        &dbdlogin_check_authorization,
        NULL,
    };
    
    static const authz_provider authz_dbdlogout_provider =
    {
        &dbdlogout_check_authorization,
        NULL,
    };
    
    static void authz_dbd_hooks(apr_pool_t *p)
    {
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-group",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_dbdgroup_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-login",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_dbdlogin_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-logout",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_dbdlogout_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(authz_dbd) =
    {
        STANDARD20_MODULE_STUFF,
        authz_dbd_cr_cfg,
        authz_dbd_merge_cfg,
        NULL,
        NULL,
        authz_dbd_cmds,
        authz_dbd_hooks
    };
    �������������httpd-2.4.64/modules/aaa/mod_authz_groupfile.c������������������������������������������������������0000664�0001751�0001751�00000024512�14037102164�021230� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 presence of a
     *
     *         require group <list-of-groups>
     *
     * 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
     *
     */
    
    #include "apr_strings.h"
    #include "apr_lib.h" /* apr_isspace */
    
    #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 "util_varbuf.h"
    
    #include "mod_auth.h"
    #include "mod_authz_owner.h"
    
    typedef struct {
        char *groupfile;
    } 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;
        return conf;
    }
    
    static const command_rec authz_groupfile_cmds[] =
    {
        AP_INIT_TAKE1("AuthGroupFile", ap_set_file_slot,
                      (void *)APR_OFFSETOF(authz_groupfile_config_rec, groupfile),
                      OR_AUTHCFG,
                      "text file containing group names and member user IDs"),
        {NULL}
    };
    
    module AP_MODULE_DECLARE_DATA authz_groupfile_module;
    
    #define VARBUF_INIT_LEN 512
    #define VARBUF_MAX_LEN  (16*1024*1024)
    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;
        struct ap_varbuf vb;
        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);
        apr_pool_tag(sp, "authz_groupfile (groups_for_user)");
    
        ap_varbuf_init(p, &vb, VARBUF_INIT_LEN);
    
        while (!(ap_varbuf_cfg_getline(&vb, f, VARBUF_MAX_LEN))) {
            if ((vb.buf[0] == '#') || (!vb.buf[0])) {
                continue;
            }
            ll = vb.buf;
            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);
        ap_varbuf_free(&vb);
    
        *out = grps;
        return APR_SUCCESS;
    }
    
    static authz_status group_check_authorization(request_rec *r,
                                                  const char *require_args,
                                                  const void *parsed_require_args)
    {
        authz_groupfile_config_rec *conf = ap_get_module_config(r->per_dir_config,
                &authz_groupfile_module);
        char *user = r->user;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t, *w;
        apr_table_t *grpstatus = NULL;
        apr_status_t status;
    
        if (!user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        /* If there is no group file - then we are not
         * configured. So decline.
         */
        if (!(conf->groupfile)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01664)
                            "No group file was specified in the configuration");
            return AUTHZ_DENIED;
        }
    
        status = groups_for_user(r->pool, user, conf->groupfile,
                                    &grpstatus);
    
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01665)
                            "Could not open group file: %s",
                            conf->groupfile);
            return AUTHZ_DENIED;
        }
    
        if (apr_is_empty_table(grpstatus)) {
            /* no groups available, so exit immediately */
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01666)
                          "Authorization of user %s to access %s failed, reason: "
                          "user doesn't appear in group file (%s).",
                          r->user, r->uri, conf->groupfile);
            return AUTHZ_DENIED;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02592)
                          "authz_groupfile authorize: require group: Can't "
                          "evaluate require expression: %s", err);
            return AUTHZ_DENIED;
        }
    
        t = require;
        while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
            if (apr_table_get(grpstatus, w)) {
                return AUTHZ_GRANTED;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01667)
                        "Authorization of user %s to access %s failed, reason: "
                        "user is not part of the 'require'ed group(s).",
                        r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group;
    
    static authz_status filegroup_check_authorization(request_rec *r,
                                                      const char *require_args,
                                                      const void *parsed_require_args)
    {
        authz_groupfile_config_rec *conf = ap_get_module_config(r->per_dir_config,
                &authz_groupfile_module);
        char *user = r->user;
        apr_table_t *grpstatus = NULL;
        apr_status_t status;
        const char *filegroup = NULL;
    
        if (!user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        /* If there is no group file - then we are not
         * configured. So decline.
         */
        if (!(conf->groupfile)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01668)
                            "No group file was specified in the configuration");
            return AUTHZ_DENIED;
        }
    
        status = groups_for_user(r->pool, user, conf->groupfile,
                                 &grpstatus);
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01669)
                          "Could not open group file: %s",
                          conf->groupfile);
            return AUTHZ_DENIED;
        }
    
        if (apr_is_empty_table(grpstatus)) {
            /* no groups available, so exit immediately */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01670)
                            "Authorization of user %s to access %s failed, reason: "
                            "user doesn't appear in group file (%s).",
                            r->user, r->uri, conf->groupfile);
            return AUTHZ_DENIED;
        }
    
        filegroup = authz_owner_get_file_group(r);
    
        if (filegroup) {
            if (apr_table_get(grpstatus, filegroup)) {
                return AUTHZ_GRANTED;
            }
        }
        else {
            /* No need to emit a error log entry because the call
            to authz_owner_get_file_group already did it
            for us.
            */
            return AUTHZ_DENIED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01671)
                      "Authorization of user %s to access %s failed, reason: "
                      "user is not part of the 'require'ed file group.",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static const char *groupfile_parse_config(cmd_parms *cmd, const char *require_line,
                                              const void **parsed_require_line)
    {
        const char *expr_err = NULL;
        ap_expr_info_t *expr;
    
        expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
                &expr_err, NULL);
    
        if (expr_err)
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression in require line: ",
                               expr_err, NULL);
    
        *parsed_require_line = expr;
    
        return NULL;
    }
    
    static const authz_provider authz_group_provider =
    {
        &group_check_authorization,
        &groupfile_parse_config,
    };
    
    static const authz_provider authz_filegroup_provider =
    {
        &filegroup_check_authorization,
        NULL,
    };
    
    
    static void authz_groupfile_getfns(void)
    {
        authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group);
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "group",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_group_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "file-group",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_filegroup_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_optional_fn_retrieve(authz_groupfile_getfns, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(authz_groupfile) =
    {
        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 */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_access_compat.c��������������������������������������������������������0000664�0001751�0001751�00000024103�13250450660�020624� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_protocol.h"
    #include "http_request.h"
    
    #include "mod_auth.h"
    
    #if APR_HAVE_NETINET_IN_H
    #include <netinet/in.h>
    #endif
    
    enum allowdeny_type {
        T_ENV,
        T_NENV,
        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;
        int *satisfy; /* for every method one */
    } access_compat_dir_conf;
    
    module AP_MODULE_DECLARE_DATA access_compat_module;
    
    static void *create_access_compat_dir_config(apr_pool_t *p, char *dummy)
    {
        int i;
        access_compat_dir_conf *conf =
            (access_compat_dir_conf *)apr_pcalloc(p, sizeof(access_compat_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));
        conf->satisfy = apr_palloc(p, sizeof(*conf->satisfy) * METHODS);
        for (i = 0; i < METHODS; ++i) {
            conf->satisfy[i] = SATISFY_NOSPEC;
        }
    
        return (void *)conf;
    }
    
    static const char *order(cmd_parms *cmd, void *dv, const char *arg)
    {
        access_compat_dir_conf *d = (access_compat_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 *satisfy(cmd_parms *cmd, void *dv, const char *arg)
    {
        access_compat_dir_conf *d = (access_compat_dir_conf *) dv;
        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)) {
                d->satisfy[i] = satisfy;
            }
        }
    
        return NULL;
    }
    
    static const char *allow_cmd(cmd_parms *cmd, void *dv, const char *from,
                                 const char *where_c)
    {
        access_compat_dir_conf *d = (access_compat_dir_conf *) dv;
        allowdeny *a;
        char *where = apr_pstrdup(cmd->pool, where_c);
        char *s;
        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=!", 5)) {
            a->type = T_NENV;
            a->x.from += 5;
    
        }
        else 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) {
                return apr_psprintf(cmd->pool, "%pm", &rv);
            }
            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)
                return apr_psprintf(cmd->pool, "%pm", &rv);
            a->type = T_IP;
        }
        else if (ap_strchr(where, '#')) {
            return "No comments are allowed here";
        }
        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 access_compat_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"),
        AP_INIT_TAKE1("Satisfy", satisfy, NULL, OR_AUTHCFG,
                      "access policy if both allow and require used ('all' or 'any')"),
        {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_NENV:
                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->useragent_addr)) {
                    return 1;
                }
                break;
    
            case T_HOST:
                if (!gothost) {
                    int remotehost_is_ip;
    
                    remotehost = ap_get_useragent_host(r, 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 access_compat_ap_satisfies(request_rec *r)
    {
        access_compat_dir_conf *conf = (access_compat_dir_conf *)
            ap_get_module_config(r->per_dir_config, &access_compat_module);
    
        return conf->satisfy[r->method_number];
    }
    
    static int check_dir_access(request_rec *r)
    {
        int method = r->method_number;
        int ret = OK;
        access_compat_dir_conf *a = (access_compat_dir_conf *)
            ap_get_module_config(r->per_dir_config, &access_compat_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_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01797)
                          "client denied by server configuration: %s%s",
                          r->filename ? "" : "uri ",
                          r->filename ? r->filename : r->uri);
        }
    
        return ret;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(access_compat_ap_satisfies);
    
        /* This can be access checker since we don't require r->user to be set. */
        ap_hook_check_access(check_dir_access, NULL, NULL, APR_HOOK_MIDDLE,
                             AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(access_compat) =
    {
        STANDARD20_MODULE_STUFF,
        create_access_compat_dir_config,   /* dir config creater */
        NULL,                           /* dir merger --- default is to override */
        NULL,                           /* server config */
        NULL,                           /* merge server config */
        access_compat_cmds,
        register_hooks                  /* register hooks */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_allowmethods.mak�������������������������������������������������������0000664�0001751�0001751�00000024315�12701473373�021063� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_allowmethods.dsp
    !IF "$(CFG)" == ""
    CFG=mod_allowmethods - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_allowmethods - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_allowmethods - Win32 Release" && "$(CFG)" != "mod_allowmethods - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_allowmethods.mak" CFG="mod_allowmethods - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_allowmethods - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_allowmethods - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_allowmethods - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_allowmethods.obj"
    	-@erase "$(INTDIR)\mod_allowmethods.res"
    	-@erase "$(INTDIR)\mod_allowmethods_src.idb"
    	-@erase "$(INTDIR)\mod_allowmethods_src.pdb"
    	-@erase "$(OUTDIR)\mod_allowmethods.exp"
    	-@erase "$(OUTDIR)\mod_allowmethods.lib"
    	-@erase "$(OUTDIR)\mod_allowmethods.pdb"
    	-@erase "$(OUTDIR)\mod_allowmethods.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_allowmethods_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_allowmethods.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_allowmethods.pdb" /debug /out:"$(OUTDIR)\mod_allowmethods.so" /implib:"$(OUTDIR)\mod_allowmethods.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_allowmethods.obj" \
    	"$(INTDIR)\mod_allowmethods.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_allowmethods.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_allowmethods.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_allowmethods.so"
       if exist .\Release\mod_allowmethods.so.manifest mt.exe -manifest .\Release\mod_allowmethods.so.manifest -outputresource:.\Release\mod_allowmethods.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_allowmethods - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_allowmethods.obj"
    	-@erase "$(INTDIR)\mod_allowmethods.res"
    	-@erase "$(INTDIR)\mod_allowmethods_src.idb"
    	-@erase "$(INTDIR)\mod_allowmethods_src.pdb"
    	-@erase "$(OUTDIR)\mod_allowmethods.exp"
    	-@erase "$(OUTDIR)\mod_allowmethods.lib"
    	-@erase "$(OUTDIR)\mod_allowmethods.pdb"
    	-@erase "$(OUTDIR)\mod_allowmethods.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_allowmethods_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_allowmethods.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_allowmethods.pdb" /debug /out:"$(OUTDIR)\mod_allowmethods.so" /implib:"$(OUTDIR)\mod_allowmethods.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_allowmethods.obj" \
    	"$(INTDIR)\mod_allowmethods.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_allowmethods.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_allowmethods.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_allowmethods.so"
       if exist .\Debug\mod_allowmethods.so.manifest mt.exe -manifest .\Debug\mod_allowmethods.so.manifest -outputresource:.\Debug\mod_allowmethods.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_allowmethods.dep")
    !INCLUDE "mod_allowmethods.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_allowmethods.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_allowmethods - Win32 Release" || "$(CFG)" == "mod_allowmethods - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_allowmethods - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_allowmethods - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_allowmethods - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_allowmethods - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_allowmethods - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_allowmethods - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_allowmethods - Win32 Release"
    
    
    "$(INTDIR)\mod_allowmethods.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_allowmethods - Win32 Debug"
    
    
    "$(INTDIR)\mod_allowmethods.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_allowmethods.c
    
    "$(INTDIR)\mod_allowmethods.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_anon.mak���������������������������������������������������������0000664�0001751�0001751�00000025706�12701473373�020520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_anon.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authn_anon - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authn_anon - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authn_anon - Win32 Release" && "$(CFG)" != "mod_authn_anon - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_anon - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_anon.obj"
    	-@erase "$(INTDIR)\mod_authn_anon.res"
    	-@erase "$(INTDIR)\mod_authn_anon_src.idb"
    	-@erase "$(INTDIR)\mod_authn_anon_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_anon.exp"
    	-@erase "$(OUTDIR)\mod_authn_anon.lib"
    	-@erase "$(OUTDIR)\mod_authn_anon.pdb"
    	-@erase "$(OUTDIR)\mod_authn_anon.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_anon_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_anon.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_anon.pdb" /debug /out:"$(OUTDIR)\mod_authn_anon.so" /implib:"$(OUTDIR)\mod_authn_anon.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_anon.obj" \
    	"$(INTDIR)\mod_authn_anon.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_anon.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authn_anon.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_anon.so"
       if exist .\Release\mod_authn_anon.so.manifest mt.exe -manifest .\Release\mod_authn_anon.so.manifest -outputresource:.\Release\mod_authn_anon.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authn_anon - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_anon.obj"
    	-@erase "$(INTDIR)\mod_authn_anon.res"
    	-@erase "$(INTDIR)\mod_authn_anon_src.idb"
    	-@erase "$(INTDIR)\mod_authn_anon_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_anon.exp"
    	-@erase "$(OUTDIR)\mod_authn_anon.lib"
    	-@erase "$(OUTDIR)\mod_authn_anon.pdb"
    	-@erase "$(OUTDIR)\mod_authn_anon.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_anon_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_anon.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_anon.pdb" /debug /out:"$(OUTDIR)\mod_authn_anon.so" /implib:"$(OUTDIR)\mod_authn_anon.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_anon.obj" \
    	"$(INTDIR)\mod_authn_anon.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_anon.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authn_anon.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_anon.so"
       if exist .\Debug\mod_authn_anon.so.manifest mt.exe -manifest .\Debug\mod_authn_anon.so.manifest -outputresource:.\Debug\mod_authn_anon.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authn_anon.dep")
    !INCLUDE "mod_authn_anon.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authn_anon.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authn_anon - Win32 Release" || "$(CFG)" == "mod_authn_anon - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authn_anon - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_anon - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_anon - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_anon - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_anon - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_anon - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_anon - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authn_anon - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authn_anon - Win32 Release"
    
    
    "$(INTDIR)\mod_authn_anon.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authn_anon - Win32 Debug"
    
    
    "$(INTDIR)\mod_authn_anon.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authn_anon.c
    
    "$(INTDIR)\mod_authn_anon.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbm.c������������������������������������������������������������0000664�0001751�0001751�00000026117�14210356064�020004� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "apr_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    #include "httpd.h"
    #include "http_config.h"
    #include "ap_provider.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"
    #include "mod_authz_owner.h"
    
    typedef struct {
        const char *grpfile;
        const char *dbmtype;
    } 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";
    
        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"),
        {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,
                                    const char *dbmgrpfile, const char *dbtype,
                                    const char ** out)
    {
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        const apr_dbm_driver_t *driver;
        const apu_err_t *err;
    #endif
        char *grp_colon, *val;
        apr_status_t retval;
        apr_dbm_t *f;
    
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
        retval = apr_dbm_get_driver(&driver, dbtype, &err, r->pool);
    
        if (retval != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, retval, r, APLOGNO(10286)
                    "could not load '%s' dbm library: %s",
                         err->reason, err->msg);
            return retval;
        }
    
        retval = apr_dbm_open2(&f, driver, dbmgrpfile, APR_DBM_READONLY,
                                 APR_OS_DEFAULT, r->pool);
    #else
        retval = apr_dbm_open_ex(&f, dbtype, dbmgrpfile, APR_DBM_READONLY,
                                 APR_OS_DEFAULT, r->pool);
    #endif
    
        if (retval != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, retval, r, APLOGNO(01799)
                          "could not open dbm (type %s) group access "
                          "file: %s", dbtype, dbmgrpfile);
            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;
    }
    
    static authz_status dbmgroup_check_authorization(request_rec *r,
                                                     const char *require_args,
                                                     const void *parsed_require_args)
    {
        authz_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                          &authz_dbm_module);
        char *user = r->user;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t;
        char *w;
        const char *orig_groups = NULL;
        const char *realm = ap_auth_name(r);
        const char *groups;
        char *v;
    
        if (!user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!conf->grpfile) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01798)
                            "No group file was specified in the configuration");
            return AUTHZ_DENIED;
        }
    
        /* 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) {
                return AUTHZ_GENERAL_ERROR;
            }
    
            if (groups == NULL) {
                /* no groups available, so exit immediately */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01800)
                              "Authorization of user %s to access %s failed, reason: "
                              "user doesn't appear in DBM group file (%s).",
                              r->user, r->uri, conf->grpfile);
                return AUTHZ_DENIED;
            }
    
            orig_groups = groups;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02591)
                          "authz_dbm authorize: require dbm-group: Can't "
                          "evaluate require expression: %s", err);
            return AUTHZ_DENIED;
        }
    
        t = require;
        while ((w = ap_getword_white(r->pool, &t)) && w[0]) {
            groups = orig_groups;
            while (groups[0]) {
                v = ap_getword(r->pool, &groups, ',');
                if (!strcmp(v, w)) {
                    return AUTHZ_GRANTED;
                }
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01801)
                      "Authorization of user %s to access %s failed, reason: "
                      "user is not part of the 'require'ed group(s).",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group;
    
    static authz_status dbmfilegroup_check_authorization(request_rec *r,
                                                         const char *require_args,
                                                         const void *parsed_require_args)
    {
        authz_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                          &authz_dbm_module);
        char *user = r->user;
        const char *realm = ap_auth_name(r);
        const char *filegroup = NULL;
        apr_status_t status;
        const char *groups;
        char *v;
    
        if (!user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!conf->grpfile) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01802)
                            "No group file was specified in the configuration");
            return AUTHZ_DENIED;
        }
    
        /* fetch group data from dbm file. */
        status = get_dbm_grp(r, apr_pstrcat(r->pool, user, ":", realm, NULL),
                             user, conf->grpfile, conf->dbmtype, &groups);
    
        if (status != APR_SUCCESS) {
            return AUTHZ_DENIED;
        }
    
        if (groups == NULL) {
            /* no groups available, so exit immediately */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01804)
                          "Authorization of user %s to access %s failed, reason: "
                          "user doesn't appear in DBM group file (%s).",
                          r->user, r->uri, conf->grpfile);
            return AUTHZ_DENIED;
        }
    
        filegroup = authz_owner_get_file_group(r);
    
        if (filegroup) {
            while (groups[0]) {
                v = ap_getword(r->pool, &groups, ',');
                if (!strcmp(v, filegroup)) {
                    return AUTHZ_GRANTED;
                }
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01805)
                      "Authorization of user %s to access %s failed, reason: "
                      "user is not part of the 'require'ed group(s).",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static const char *dbm_parse_config(cmd_parms *cmd, const char *require_line,
                                         const void **parsed_require_line)
    {
        const char *expr_err = NULL;
        ap_expr_info_t *expr;
    
        expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
                &expr_err, NULL);
    
        if (expr_err)
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression in require line: ",
                               expr_err, NULL);
    
        *parsed_require_line = expr;
    
        return NULL;
    }
    
    static const authz_provider authz_dbmgroup_provider =
    {
        &dbmgroup_check_authorization,
        &dbm_parse_config,
    };
    
    static const authz_provider authz_dbmfilegroup_provider =
    {
        &dbmfilegroup_check_authorization,
        NULL,
    };
    
    static void authz_dbm_getfns(void)
    {
        authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group);
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbm-group",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_dbmgroup_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbm-file-group",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_dbmfilegroup_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_optional_fn_retrieve(authz_dbm_getfns, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(authz_dbm) =
    {
        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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_socache.c��������������������������������������������������������0000664�0001751�0001751�00000041570�13623622544�020641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include "ap_socache.h"
    #include "util_mutex.h"
    #include "apr_optional.h"
    
    module AP_MODULE_DECLARE_DATA authn_socache_module;
    
    typedef struct authn_cache_dircfg {
        apr_interval_time_t timeout;
        apr_array_header_t *providers;
        const char *context;
    } authn_cache_dircfg;
    
    /* FIXME:
     * I think the cache and mutex should be global
     */
    static apr_global_mutex_t *authn_cache_mutex = NULL;
    static ap_socache_provider_t *socache_provider = NULL;
    static ap_socache_instance_t *socache_instance = NULL;
    static const char *const authn_cache_id = "authn-socache";
    static int configured;
    
    static apr_status_t remove_lock(void *data)
    {
        if (authn_cache_mutex) {
            apr_global_mutex_destroy(authn_cache_mutex);
            authn_cache_mutex = NULL;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t destroy_cache(void *data)
    {
        if (socache_instance) {
            socache_provider->destroy(socache_instance, (server_rec*)data);
            socache_instance = NULL;
        }
        return APR_SUCCESS;
    }
    
    static int authn_cache_precfg(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptmp)
    {
        apr_status_t rv = ap_mutex_register(pconf, authn_cache_id,
                                            NULL, APR_LOCK_DEFAULT, 0);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01673)
                          "failed to register %s mutex", authn_cache_id);
            return 500; /* An HTTP status would be a misnomer! */
        }
        socache_provider = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
                                              AP_SOCACHE_DEFAULT_PROVIDER,
                                              AP_SOCACHE_PROVIDER_VERSION);
        configured = 0;
        return OK;
    }
    
    static int authn_cache_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                       apr_pool_t *ptmp, server_rec *s)
    {
        apr_status_t rv;
        static struct ap_socache_hints authn_cache_hints = {64, 32, 60000000};
        const char *errmsg;
    
        if (!configured) {
            return OK;    /* don't waste the overhead of creating mutex & cache */
        }
        if (socache_provider == NULL) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog, APLOGNO(01674)
                          "Please select a socache provider with AuthnCacheSOCache "
                          "(no default found on this platform). Maybe you need to "
                          "load mod_socache_shmcb or another socache module first");
            return 500; /* An HTTP status would be a misnomer! */
        }
    
        /* We have socache_provider, but do not have socache_instance. This should
         * happen only when using "default" socache_provider, so create default
         * socache_instance in this case. */
        if (socache_instance == NULL) {
            errmsg = socache_provider->create(&socache_instance, NULL,
                                              ptmp, pconf);
            if (errmsg) {
                ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog, APLOGNO(02612)
                            "failed to create mod_socache_shmcb socache "
                            "instance: %s", errmsg);
                return 500;
            }
        }
    
        rv = ap_global_mutex_create(&authn_cache_mutex, NULL,
                                    authn_cache_id, NULL, s, pconf, 0);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01675)
                          "failed to create %s mutex", authn_cache_id);
            return 500; /* An HTTP status would be a misnomer! */
        }
        apr_pool_cleanup_register(pconf, NULL, remove_lock, apr_pool_cleanup_null);
    
        rv = socache_provider->init(socache_instance, authn_cache_id,
                                    &authn_cache_hints, s, pconf);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01677)
                          "failed to initialise %s cache", authn_cache_id);
            return 500; /* An HTTP status would be a misnomer! */
        }
        apr_pool_cleanup_register(pconf, (void*)s, destroy_cache, apr_pool_cleanup_null);
        return OK;
    }
    
    static void authn_cache_child_init(apr_pool_t *p, server_rec *s)
    {
        const char *lock;
        apr_status_t rv;
        if (!configured) {
            return;       /* don't waste the overhead of creating mutex & cache */
        }
        lock = apr_global_mutex_lockfile(authn_cache_mutex);
        rv = apr_global_mutex_child_init(&authn_cache_mutex, lock, p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(01678)
                         "failed to initialise mutex in child_init");
        }
    }
    
    static const char *authn_cache_socache(cmd_parms *cmd, void *CFG,
                                           const char *arg)
    {
        const char *errmsg = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        const char *sep, *name;
    
        if (errmsg)
            return errmsg;
    
        /* Argument is of form 'name:args' or just 'name'. */
        sep = ap_strchr_c(arg, ':');
        if (sep) {
            name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
            sep++;
        }
        else {
            name = arg;
        }
    
        socache_provider = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP, name,
                                              AP_SOCACHE_PROVIDER_VERSION);
        if (socache_provider == NULL) {
            errmsg = apr_psprintf(cmd->pool,
                                  "Unknown socache provider '%s'. Maybe you need "
                                  "to load the appropriate socache module "
                                  "(mod_socache_%s?)", arg, arg);
        }
        else {
            errmsg = socache_provider->create(&socache_instance, sep,
                                              cmd->temp_pool, cmd->pool);
        }
    
        if (errmsg) {
            errmsg = apr_psprintf(cmd->pool, "AuthnCacheSOCache: %s", errmsg);
        }
        return errmsg;
    }
    
    static const char *authn_cache_enable(cmd_parms *cmd, void *CFG)
    {
        const char *errmsg = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        configured = 1;
        return errmsg;
    }
    
    static const char *const directory = "directory";
    static void* authn_cache_dircfg_create(apr_pool_t *pool, char *s)
    {
        authn_cache_dircfg *ret = apr_palloc(pool, sizeof(authn_cache_dircfg));
        ret->timeout = apr_time_from_sec(300);
        ret->providers = NULL;
        ret->context = directory;
        return ret;
    }
    
    /* not sure we want this.  Might be safer to document use-all-or-none */
    static void* authn_cache_dircfg_merge(apr_pool_t *pool, void *BASE, void *ADD)
    {
        authn_cache_dircfg *base = BASE;
        authn_cache_dircfg *add = ADD;
        authn_cache_dircfg *ret = apr_pmemdup(pool, add, sizeof(authn_cache_dircfg));
        /* preserve context and timeout if not defaults */
        if (add->context == directory) {
            ret->context = base->context;
        }
        if (add->timeout == apr_time_from_sec(300)) {
            ret->timeout = base->timeout;
        }
        if (add->providers == NULL) {
            ret->providers = base->providers;
        }
        return ret;
    }
    
    static const char *authn_cache_setprovider(cmd_parms *cmd, void *CFG,
                                               const char *arg)
    {
        authn_cache_dircfg *cfg = CFG;
        if (cfg->providers == NULL) {
            cfg->providers = apr_array_make(cmd->pool, 4, sizeof(const char*));
        }
        APR_ARRAY_PUSH(cfg->providers, const char*) = arg;
        configured = 1;
        return NULL;
    }
    
    static const char *authn_cache_timeout(cmd_parms *cmd, void *CFG,
                                           const char *arg)
    {
        authn_cache_dircfg *cfg = CFG;
        int secs = atoi(arg);
        cfg->timeout = apr_time_from_sec(secs);
        return NULL;
    }
    
    static const command_rec authn_cache_cmds[] =
    {
        /* global stuff: cache and mutex */
        AP_INIT_TAKE1("AuthnCacheSOCache", authn_cache_socache, NULL, RSRC_CONF,
                      "socache provider for authn cache"),
        AP_INIT_NO_ARGS("AuthnCacheEnable", authn_cache_enable, NULL, RSRC_CONF,
                        "enable socache configuration in htaccess even if not enabled anywhere else"),
        /* per-dir stuff */
        AP_INIT_ITERATE("AuthnCacheProvideFor", authn_cache_setprovider, NULL,
                        OR_AUTHCFG, "Determine what authn providers to cache for"),
        AP_INIT_TAKE1("AuthnCacheTimeout", authn_cache_timeout, NULL,
                      OR_AUTHCFG, "Timeout (secs) for cached credentials"),
        AP_INIT_TAKE1("AuthnCacheContext", ap_set_string_slot,
                      (void*)APR_OFFSETOF(authn_cache_dircfg, context),
                      ACCESS_CONF, "Context for authn cache"),
        {NULL}
    };
    
    static const char *construct_key(request_rec *r, const char *context,
                                     const char *user, const char *realm)
    {
        /* handle "special" context values */
        if (!strcmp(context, directory)) {
            /* FIXME: are we at risk of this blowing up? */
            char *new_context;
            char *slash = strrchr(r->uri, '/');
            new_context = apr_palloc(r->pool, slash - r->uri +
                                     strlen(r->server->server_hostname) + 1);
            strcpy(new_context, r->server->server_hostname);
            strncat(new_context, r->uri, slash - r->uri);
            context = new_context;
        }
        else if (!strcmp(context, "server")) {
            context = r->server->server_hostname;
        }
        /* any other context value is literal */
    
        if (realm == NULL) {                              /* basic auth */
            return apr_pstrcat(r->pool, context, ":", user, NULL);
        }
        else {                                            /* digest auth */
            return apr_pstrcat(r->pool, context, ":", user, ":", realm, NULL);
        }
    }
    
    static void ap_authn_cache_store(request_rec *r, const char *module,
                                     const char *user, const char *realm,
                                     const char* data)
    {
        apr_status_t rv;
        authn_cache_dircfg *dcfg;
        const char *key;
        apr_time_t expiry;
    
        /* first check whether we're caching for this module */
        dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module);
        if (!configured || !dcfg->providers) {
            return;
        }
        if (!ap_array_str_contains(dcfg->providers, module)) {
            return;
        }
    
        /* OK, we're on.  Grab mutex to do our business */
        rv = apr_global_mutex_trylock(authn_cache_mutex);
        if (APR_STATUS_IS_EBUSY(rv)) {
            /* don't wait around; just abandon it */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(01679)
                          "authn credentials for %s not cached (mutex busy)", user);
            return;
        }
        else if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01680)
                          "Failed to cache authn credentials for %s in %s",
                          module, dcfg->context);
            return;
        }
    
        /* We have the mutex, so go ahead */
        /* first build our key and determine expiry time */
        key = construct_key(r, dcfg->context, user, realm);
        expiry = apr_time_now() + dcfg->timeout;
    
        /* store it */
        rv = socache_provider->store(socache_instance, r->server,
                                     (unsigned char*)key, strlen(key), expiry,
                                     (unsigned char*)data, strlen(data), r->pool);
        if (rv == APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01681)
                          "Cached authn credentials for %s in %s",
                          user, dcfg->context);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01682)
                          "Failed to cache authn credentials for %s in %s",
                          module, dcfg->context);
        }
    
        /* We're done with the mutex */
        rv = apr_global_mutex_unlock(authn_cache_mutex);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01683) "Failed to release mutex!");
        }
    }
    
    #define MAX_VAL_LEN 256
    static authn_status check_password(request_rec *r, const char *user,
                                       const char *password)
    {
        /* construct key
         * look it up
         * if found, test password
         *
         * mutexing here would be a big performance drag.
         * It's definitely unnecessary with some backends (like ndbm or gdbm)
         * Is there a risk in the general case?  I guess the only risk we
         * care about is a race condition that gets us a dangling pointer
         * to no-longer-defined memory.  Hmmm ...
         */
        apr_status_t rv;
        const char *key;
        authn_cache_dircfg *dcfg;
        unsigned char val[MAX_VAL_LEN];
        unsigned int vallen = MAX_VAL_LEN - 1;
        dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module);
        if (!configured || !dcfg->providers) {
            return AUTH_USER_NOT_FOUND;
        }
        key = construct_key(r, dcfg->context, user, NULL);
        rv = socache_provider->retrieve(socache_instance, r->server,
                                        (unsigned char*)key, strlen(key),
                                        val, &vallen, r->pool);
    
        if (APR_STATUS_IS_NOTFOUND(rv)) {
            /* not found - just return */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01684)
                          "Authn cache: no credentials found for %s", user);
            return AUTH_USER_NOT_FOUND;
        }
        else if (rv == APR_SUCCESS) {
            /* OK, we got a value */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01685)
                          "Authn cache: found credentials for %s", user);
            val[vallen] = 0;
        }
        else {
            /* error: give up and pass the buck */
            /* FIXME: getting this for NOTFOUND - prolly a bug in mod_socache */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01686)
                          "Error accessing authentication cache");
            return AUTH_USER_NOT_FOUND;
        }
    
        rv = apr_password_validate(password, (char*) val);
        if (rv != 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)
    {
        apr_status_t rv;
        const char *key;
        authn_cache_dircfg *dcfg;
        unsigned char val[MAX_VAL_LEN];
        unsigned int vallen = MAX_VAL_LEN - 1;
        dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module);
        if (!configured || !dcfg->providers) {
            return AUTH_USER_NOT_FOUND;
        }
        key = construct_key(r, dcfg->context, user, realm);
        rv = socache_provider->retrieve(socache_instance, r->server,
                                        (unsigned char*)key, strlen(key),
                                        val, &vallen, r->pool);
    
        if (APR_STATUS_IS_NOTFOUND(rv)) {
            /* not found - just return */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01687)
                          "Authn cache: no credentials found for %s", user);
            return AUTH_USER_NOT_FOUND;
        }
        else if (rv == APR_SUCCESS) {
            /* OK, we got a value */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01688)
                          "Authn cache: found credentials for %s", user);
        }
        else {
            /* error: give up and pass the buck */
            /* FIXME: getting this for NOTFOUND - prolly a bug in mod_socache */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01689)
                          "Error accessing authentication cache");
            return AUTH_USER_NOT_FOUND;
        }
        *rethash = apr_pstrmemdup(r->pool, (char *)val, vallen);
    
        return AUTH_USER_FOUND;
    }
    
    static const authn_provider authn_cache_provider =
    {
        &check_password,
        &get_realm_hash,
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "socache",
                                  AUTHN_PROVIDER_VERSION,
                                  &authn_cache_provider, AP_AUTH_INTERNAL_PER_CONF);
        APR_REGISTER_OPTIONAL_FN(ap_authn_cache_store);
        ap_hook_pre_config(authn_cache_precfg, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_config(authn_cache_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_child_init(authn_cache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(authn_socache) =
    {
        STANDARD20_MODULE_STUFF,
        authn_cache_dircfg_create,
        authn_cache_dircfg_merge,
        NULL,
        NULL,
        authn_cache_cmds,
        register_hooks
    };
    ����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_allowmethods.c���������������������������������������������������������0000664�0001751�0001751�00000010443�12757564422�020541� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_core.h"
    #include "http_config.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "http_log.h"
    #include "apr_strings.h"
    
    /**
     * This module makes it easy to restrict what HTTP methods can be ran against
     * a server.
     *
     * It provides one command:
     *    AllowMethods
     * This command takes a list of HTTP methods to allow.
     *
     *  The most common configuration should be like this:
     *   <Directory />
     *    AllowMethods GET HEAD OPTIONS
     *   </Directory>
     *   <Directory /special/cgi-bin>
     *      AllowMethods GET HEAD OPTIONS POST
     *   </Directory>
     *  Non-matching methods will be returned a status 405 (method not allowed)
     *
     *  To allow all methods, and effectively turn off mod_allowmethods, use:
     *    AllowMethods reset
     */
    
    typedef struct am_conf_t {
        int allowed_set;
        apr_int64_t allowed;
    } am_conf_t;
    
    module AP_MODULE_DECLARE_DATA allowmethods_module;
    
    static int am_check_access(request_rec *r)
    {
        int method = r->method_number;
        am_conf_t *conf;
    
        conf = (am_conf_t *) ap_get_module_config(r->per_dir_config,
                                                  &allowmethods_module);
        if (!conf || conf->allowed == 0) {
            return DECLINED;
        }
    
        r->allowed = conf->allowed;
    
        if (conf->allowed & (AP_METHOD_BIT << method)) {
            return DECLINED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01623)
                      "client method denied by server configuration: '%s' to %s%s",
                      r->method,
                      r->filename ? "" : "uri ",
                      r->filename ? r->filename : r->uri);
    
        return HTTP_METHOD_NOT_ALLOWED;
    }
    
    static void *am_create_conf(apr_pool_t *p, char *dummy)
    {
        am_conf_t *conf = apr_pcalloc(p, sizeof(am_conf_t));
    
        conf->allowed = 0;
        conf->allowed_set = 0;
        return conf;
    }
    
    static void *am_merge_conf(apr_pool_t *pool, void *a, void *b)
    {
        am_conf_t *base = (am_conf_t *)a;
        am_conf_t *add = (am_conf_t *)b;
        am_conf_t *conf = apr_palloc(pool, sizeof(am_conf_t));
    
        if (add->allowed_set) {
            conf->allowed = add->allowed;
            conf->allowed_set = add->allowed_set;
        }
        else {
            conf->allowed = base->allowed;
            conf->allowed_set = base->allowed_set;
        }
    
        return conf;
    }
    
    static const char *am_allowmethods(cmd_parms *cmd, void *d, int argc,
                                       char *const argv[])
    {
        int i;
        am_conf_t *conf = (am_conf_t *)d;
    
        if (argc == 0) {
            return "AllowMethods: No method or 'reset' keyword given";
        }
        if (argc == 1) {
            if (strcasecmp("reset", argv[0]) == 0) {
                conf->allowed = 0;
                conf->allowed_set = 1;
                return NULL;
            }
        }
    
        for (i = 0; i < argc; i++) {
            int m;
    
            m = ap_method_number_of(argv[i]);
            if (m == M_INVALID) {
                return apr_pstrcat(cmd->pool, "AllowMethods: Invalid Method '",
                                   argv[i], "'", NULL);
            }
    
            conf->allowed |= (AP_METHOD_BIT << m);
        }
        conf->allowed_set = 1;
        return NULL;
    }
    
    static void am_register_hooks(apr_pool_t * p)
    {
        ap_hook_access_checker(am_check_access, NULL, NULL, APR_HOOK_REALLY_FIRST);
    }
    
    static const command_rec am_cmds[] = {
        AP_INIT_TAKE_ARGV("AllowMethods", am_allowmethods, NULL,
                          ACCESS_CONF,
                          "only allow specific methods"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(allowmethods) = {
        STANDARD20_MODULE_STUFF,
        am_create_conf,
        am_merge_conf,
        NULL,
        NULL,
        am_cmds,
        am_register_hooks,
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_digest.mak��������������������������������������������������������0000664�0001751�0001751�00000024165�12701473373�020664� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_auth_digest.dsp
    !IF "$(CFG)" == ""
    CFG=mod_auth_digest - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_auth_digest - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_auth_digest - Win32 Release" && "$(CFG)" != "mod_auth_digest - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_digest - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_auth_digest.obj"
    	-@erase "$(INTDIR)\mod_auth_digest.res"
    	-@erase "$(INTDIR)\mod_auth_digest_src.idb"
    	-@erase "$(INTDIR)\mod_auth_digest_src.pdb"
    	-@erase "$(OUTDIR)\mod_auth_digest.exp"
    	-@erase "$(OUTDIR)\mod_auth_digest.lib"
    	-@erase "$(OUTDIR)\mod_auth_digest.pdb"
    	-@erase "$(OUTDIR)\mod_auth_digest.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_digest_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_digest.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_digest.pdb" /debug /out:"$(OUTDIR)\mod_auth_digest.so" /implib:"$(OUTDIR)\mod_auth_digest.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_auth_digest.obj" \
    	"$(INTDIR)\mod_auth_digest.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_auth_digest.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_auth_digest.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_digest.so"
       if exist .\Release\mod_auth_digest.so.manifest mt.exe -manifest .\Release\mod_auth_digest.so.manifest -outputresource:.\Release\mod_auth_digest.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_auth_digest - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_auth_digest.obj"
    	-@erase "$(INTDIR)\mod_auth_digest.res"
    	-@erase "$(INTDIR)\mod_auth_digest_src.idb"
    	-@erase "$(INTDIR)\mod_auth_digest_src.pdb"
    	-@erase "$(OUTDIR)\mod_auth_digest.exp"
    	-@erase "$(OUTDIR)\mod_auth_digest.lib"
    	-@erase "$(OUTDIR)\mod_auth_digest.pdb"
    	-@erase "$(OUTDIR)\mod_auth_digest.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_digest_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_digest.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_digest.pdb" /debug /out:"$(OUTDIR)\mod_auth_digest.so" /implib:"$(OUTDIR)\mod_auth_digest.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_auth_digest.obj" \
    	"$(INTDIR)\mod_auth_digest.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_auth_digest.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_auth_digest.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_digest.so"
       if exist .\Debug\mod_auth_digest.so.manifest mt.exe -manifest .\Debug\mod_auth_digest.so.manifest -outputresource:.\Debug\mod_auth_digest.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_auth_digest.dep")
    !INCLUDE "mod_auth_digest.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_auth_digest.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_auth_digest - Win32 Release" || "$(CFG)" == "mod_auth_digest - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_auth_digest - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_digest - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_digest - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_digest - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_digest - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_digest - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_auth_digest - Win32 Release"
    
    
    "$(INTDIR)\mod_auth_digest.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_auth_digest - Win32 Debug"
    
    
    "$(INTDIR)\mod_auth_digest.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_auth_digest.c
    
    "$(INTDIR)\mod_auth_digest.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_owner.dep��������������������������������������������������������0000664�0001751�0001751�00000004114�12674411515�020720� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authz_owner.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authz_owner.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_authz_owner.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthzgrp��������������������������������������������������������������0000664�0001751�0001751�00000010206�11540546347�017432� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_core.dep���������������������������������������������������������0000664�0001751�0001751�00000004214�12674411515�020517� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authz_core.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authz_core.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_host.dep���������������������������������������������������������0000664�0001751�0001751�00000004214�12674411515�020544� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authz_host.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authz_host.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_anon.c�����������������������������������������������������������0000664�0001751�0001751�00000015337�12623122041�020153� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Adapted to allow anonymous logins, just like with Anon-FTP, when
     * one gives the magic user name 'anonymous' and ones email address
     * as the password.
     *
     * Just add the following tokes to your <directory> 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 {
        const 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 = 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, APLOGNO(01672)
                              "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_auth_provider(p, AUTHN_PROVIDER_GROUP, "anon",
                                  AUTHN_PROVIDER_VERSION,
                                  &authn_anon_provider, AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(authn_anon) =
    {
        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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbm.dsp����������������������������������������������������������0000664�0001751�0001751�00000011007�10551346420�020337� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authz_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache"
    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 /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 /out:".\Debug\mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authz_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_fcgi.dsp��������������������������������������������������������0000664�0001751�0001751�00000011464�12553146475�020706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_authnz_fcgi" - 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_fcgi - 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_authnz_fcgi.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_fcgi.mak" CFG="mod_authnz_fcgi - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authnz_fcgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authnz_fcgi - 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_fcgi - 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 "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authnz_fcgi_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 /fo"Release/mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authnz_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_authnz_fcgi - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authnz_fcgi_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 /fo"Debug/mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache"
    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 /out:".\Debug\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authnz_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_authnz_fcgi - Win32 Release"
    # Name "mod_authnz_fcgi - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_authnz_fcgi.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\include\mod_auth.h
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\include\util_fcgi.h
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/config.m4������������������������������������������������������������������0000664�0001751�0001751�00000006573�12323565636�016551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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)
    APACHE_MODULE(authn_dbd, SQL-based authentication control, , , most)
    APACHE_MODULE(authn_socache, Cached authentication control, , , most)
    
    dnl General Authentication modules; module which implements the 
    dnl non-authn module specific directives.
    dnl
    APACHE_MODULE(authn_core, core authentication module, , , yes)
    
    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)
    APACHE_MODULE(authz_dbd, SQL based authorization and Login/Session support, , , most)
    
    dnl General Authorization modules; provider module which implements the 
    dnl non-authz module specific directives.
    dnl
    APACHE_MODULE(authz_core, core authorization provider vector module, , , yes)
    
    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, , , most, [
      APACHE_CHECK_APR_HAS_LDAP
      if test "$ac_cv_APR_HAS_LDAP" = "yes" ; then
        if test -z "$apu_config" ; then
          LDAP_LIBS="`$apr_config --ldap-libs`"
        else
          LDAP_LIBS="`$apu_config --ldap-libs`"
        fi
        APR_ADDTO(MOD_AUTHNZ_LDAP_LDADD, [$LDAP_LIBS])
        AC_SUBST(MOD_AUTHNZ_LDAP_LDADD)
      else
        AC_MSG_WARN([apr/apr-util is compiled without ldap support])
        enable_authnz_ldap=no
      fi
    ])
    
    dnl FastCGI authorizer interface, supporting authn and authz.
    APACHE_MODULE(authnz_fcgi,
                  FastCGI authorizer-based authentication and authorization, , , no)
    
    dnl - host access control compatibility modules. Implements Order, Allow,
    dnl Deny, Satisfy for backward compatibility.  These directives have been
    dnl deprecated in 2.4.
    APACHE_MODULE(access_compat, mod_access compatibility, , , yes)
    
    dnl these are the front-end authentication modules
    
    APACHE_MODULE(auth_basic, basic authentication, , , yes)
    APACHE_MODULE(auth_form, form authentication, , , most)
    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_MODULE(allowmethods, restrict allowed HTTP methods, , , most)
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    �������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/.indent.pro����������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�017102� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbd.dep����������������������������������������������������������0000664�0001751�0001751�00000004004�12674411515�020301� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authn_dbd.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authn_dbd.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbd.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr-util\include\apu_version.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_core.mak���������������������������������������������������������0000664�0001751�0001751�00000025706�12701473373�020515� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_core.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authn_core - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authn_core - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authn_core - Win32 Release" && "$(CFG)" != "mod_authn_core - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_core.mak" CFG="mod_authn_core - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authn_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authn_core - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_core - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_core.obj"
    	-@erase "$(INTDIR)\mod_authn_core.res"
    	-@erase "$(INTDIR)\mod_authn_core_src.idb"
    	-@erase "$(INTDIR)\mod_authn_core_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_core.exp"
    	-@erase "$(OUTDIR)\mod_authn_core.lib"
    	-@erase "$(OUTDIR)\mod_authn_core.pdb"
    	-@erase "$(OUTDIR)\mod_authn_core.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_core_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_core.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_core.pdb" /debug /out:"$(OUTDIR)\mod_authn_core.so" /implib:"$(OUTDIR)\mod_authn_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_core.obj" \
    	"$(INTDIR)\mod_authn_core.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authn_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_core.so"
       if exist .\Release\mod_authn_core.so.manifest mt.exe -manifest .\Release\mod_authn_core.so.manifest -outputresource:.\Release\mod_authn_core.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authn_core - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_core.obj"
    	-@erase "$(INTDIR)\mod_authn_core.res"
    	-@erase "$(INTDIR)\mod_authn_core_src.idb"
    	-@erase "$(INTDIR)\mod_authn_core_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_core.exp"
    	-@erase "$(OUTDIR)\mod_authn_core.lib"
    	-@erase "$(OUTDIR)\mod_authn_core.pdb"
    	-@erase "$(OUTDIR)\mod_authn_core.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_core_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_core.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_core.pdb" /debug /out:"$(OUTDIR)\mod_authn_core.so" /implib:"$(OUTDIR)\mod_authn_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_core.obj" \
    	"$(INTDIR)\mod_authn_core.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authn_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_core.so"
       if exist .\Debug\mod_authn_core.so.manifest mt.exe -manifest .\Debug\mod_authn_core.so.manifest -outputresource:.\Debug\mod_authn_core.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authn_core.dep")
    !INCLUDE "mod_authn_core.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authn_core.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authn_core - Win32 Release" || "$(CFG)" == "mod_authn_core - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authn_core - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_core - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_core - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_core - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_core - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_core - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_core - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authn_core - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authn_core - Win32 Release"
    
    
    "$(INTDIR)\mod_authn_core.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authn_core - Win32 Debug"
    
    
    "$(INTDIR)\mod_authn_core.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authn_core.c
    
    "$(INTDIR)\mod_authn_core.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_socache.mak������������������������������������������������������0000664�0001751�0001751�00000024445�12701473373�021171� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_socache.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authn_socache - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authn_socache - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authn_socache - Win32 Release" && "$(CFG)" != "mod_authn_socache - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_socache.mak" CFG="mod_authn_socache - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authn_socache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authn_socache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_socache - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_socache.obj"
    	-@erase "$(INTDIR)\mod_authn_socache.res"
    	-@erase "$(INTDIR)\mod_authn_socache_src.idb"
    	-@erase "$(INTDIR)\mod_authn_socache_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_socache.exp"
    	-@erase "$(OUTDIR)\mod_authn_socache.lib"
    	-@erase "$(OUTDIR)\mod_authn_socache.pdb"
    	-@erase "$(OUTDIR)\mod_authn_socache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_socache_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_socache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_socache.pdb" /debug /out:"$(OUTDIR)\mod_authn_socache.so" /implib:"$(OUTDIR)\mod_authn_socache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_socache.obj" \
    	"$(INTDIR)\mod_authn_socache.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_authn_socache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authn_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_socache.so"
       if exist .\Release\mod_authn_socache.so.manifest mt.exe -manifest .\Release\mod_authn_socache.so.manifest -outputresource:.\Release\mod_authn_socache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authn_socache - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_socache.obj"
    	-@erase "$(INTDIR)\mod_authn_socache.res"
    	-@erase "$(INTDIR)\mod_authn_socache_src.idb"
    	-@erase "$(INTDIR)\mod_authn_socache_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_socache.exp"
    	-@erase "$(OUTDIR)\mod_authn_socache.lib"
    	-@erase "$(OUTDIR)\mod_authn_socache.pdb"
    	-@erase "$(OUTDIR)\mod_authn_socache.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_socache_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_socache.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_socache.pdb" /debug /out:"$(OUTDIR)\mod_authn_socache.so" /implib:"$(OUTDIR)\mod_authn_socache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_socache.obj" \
    	"$(INTDIR)\mod_authn_socache.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_authn_socache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authn_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_socache.so"
       if exist .\Debug\mod_authn_socache.so.manifest mt.exe -manifest .\Debug\mod_authn_socache.so.manifest -outputresource:.\Debug\mod_authn_socache.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authn_socache.dep")
    !INCLUDE "mod_authn_socache.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authn_socache.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authn_socache - Win32 Release" || "$(CFG)" == "mod_authn_socache - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authn_socache - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_socache - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_socache - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_socache - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_socache - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_socache - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authn_socache - Win32 Release"
    
    
    "$(INTDIR)\mod_authn_socache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authn_socache - Win32 Debug"
    
    
    "$(INTDIR)\mod_authn_socache.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authn_socache.c
    
    "$(INTDIR)\mod_authn_socache.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_file.mak���������������������������������������������������������0000664�0001751�0001751�00000025706�12701473373�020504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_file.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authn_file - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authn_file - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authn_file - Win32 Release" && "$(CFG)" != "mod_authn_file - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_file - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_file.obj"
    	-@erase "$(INTDIR)\mod_authn_file.res"
    	-@erase "$(INTDIR)\mod_authn_file_src.idb"
    	-@erase "$(INTDIR)\mod_authn_file_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_file.exp"
    	-@erase "$(OUTDIR)\mod_authn_file.lib"
    	-@erase "$(OUTDIR)\mod_authn_file.pdb"
    	-@erase "$(OUTDIR)\mod_authn_file.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_file_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_file.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_file.pdb" /debug /out:"$(OUTDIR)\mod_authn_file.so" /implib:"$(OUTDIR)\mod_authn_file.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_file.obj" \
    	"$(INTDIR)\mod_authn_file.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_file.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authn_file.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_file.so"
       if exist .\Release\mod_authn_file.so.manifest mt.exe -manifest .\Release\mod_authn_file.so.manifest -outputresource:.\Release\mod_authn_file.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authn_file - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_file.obj"
    	-@erase "$(INTDIR)\mod_authn_file.res"
    	-@erase "$(INTDIR)\mod_authn_file_src.idb"
    	-@erase "$(INTDIR)\mod_authn_file_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_file.exp"
    	-@erase "$(OUTDIR)\mod_authn_file.lib"
    	-@erase "$(OUTDIR)\mod_authn_file.pdb"
    	-@erase "$(OUTDIR)\mod_authn_file.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_file_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_file.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_file.pdb" /debug /out:"$(OUTDIR)\mod_authn_file.so" /implib:"$(OUTDIR)\mod_authn_file.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_file.obj" \
    	"$(INTDIR)\mod_authn_file.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_file.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authn_file.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_file.so"
       if exist .\Debug\mod_authn_file.so.manifest mt.exe -manifest .\Debug\mod_authn_file.so.manifest -outputresource:.\Debug\mod_authn_file.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authn_file.dep")
    !INCLUDE "mod_authn_file.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authn_file.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authn_file - Win32 Release" || "$(CFG)" == "mod_authn_file - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authn_file - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_file - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_file - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_file - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_file - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_file - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_file - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authn_file - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authn_file - Win32 Release"
    
    
    "$(INTDIR)\mod_authn_file.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authn_file - Win32 Debug"
    
    
    "$(INTDIR)\mod_authn_file.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authn_file.c
    
    "$(INTDIR)\mod_authn_file.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_ldap.c����������������������������������������������������������0000664�0001751�0001751�00000232221�14737241167�020346� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "ap_provider.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"
    #include "apr_lib.h"
    
    #include <ctype.h>
    
    #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
    
    static char *default_attributes[3] = { "member", "uniqueMember", NULL };
    
    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
    
        /* 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 bind_authoritative;         /* If true, will return errors when bind fails */
    
        int user_is_dn;                 /* If true, r->user is replaced by DN during authn */
        char *remote_user_attribute;    /* If set, r->user is replaced by this attribute during authn */
        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 identifying user members. Default:"member uniqueMember" */
        int group_attrib_is_dn;         /* If true, the group attribute is the DN, otherwise,
                                            it's the exact string passed by the HTTP client */
        char **sgAttributes;            /* Array of strings constructed (post-config) from subgroupattrs. Last entry is NULL. */
        apr_array_header_t *subgroupclasses; /* List of object classes of sub-groups. Default:"groupOfNames groupOfUniqueNames" */
        int maxNestingDepth;            /* Maximum recursive nesting depth permitted during subgroup processing. Default: 10 */
    
        int secure;                     /* True if SSL connections are requested */
        char *authz_prefix;             /* Prefix for environment variables added during authz */
        int initial_bind_as_user;               /* true if we should try to bind (to lookup DN) directly with the basic auth username */
        ap_regex_t *bind_regex;         /* basic auth -> bind'able username regex */
        const char *bind_subst;         /* basic auth -> bind'able username substitution */
        int search_as_user;             /* true if authz searches should be done with the users credentials (when we did authn) */
        int compare_as_user;            /* true if authz compares should be done with the users credentials (when we did authn) */
    } authn_ldap_config_t;
    
    typedef struct {
        const char *dn;                 /* The saved dn from a successful search */
        const char *user;               /* The username provided by the client */
        const char **vals;              /* The additional values pulled during the DN search*/
        const char *password;           /* if this module successfully authenticates, the basic auth password, else null */
    } authn_ldap_request_t;
    
    enum auth_ldap_phase {
        LDAP_AUTHN, LDAP_AUTHZ
    };
    
    enum auth_ldap_optype {
        LDAP_SEARCH, LDAP_COMPARE, LDAP_COMPARE_AND_SEARCH /* nested groups */
    };
    
    /* maximum group elements supported */
    #define GROUPATTR_MAX_ELTS 10
    
    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_check_subgroups) *util_ldap_cache_check_subgroups;
    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)
    {
        char *charset;
    
        if (!language)          /* our default codepage */
            return apr_pstrdup(p, "ISO-8859-1");
    
        charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING);
    
        /*
         * Test if language values like 'en-US' return a match from the charset
         * conversion map when shortened to 'en'.
         */
        if (!charset && strlen(language) > 3 && language[2] == '-') {
            char *language_short = apr_pstrndup(p, language, 2);
            charset = (char*) apr_hash_get(charset_conversions, language_short, 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;
    }
    
    
    static const char* authn_ldap_xlate_password(request_rec *r,
                                                 const char* sent_password)
    {
        apr_xlate_t *convset = NULL;
        apr_size_t inbytes;
        apr_size_t outbytes;
        char *outbuf;
    
        if (charset_conversions && (convset = get_conv_set(r)) ) {
            inbytes = strlen(sent_password);
            outbytes = (inbytes+1)*3;
            outbuf = apr_pcalloc(r->pool, outbytes);
    
            /* Convert the password to UTF-8. */
            if (apr_xlate_conv_buffer(convset, sent_password, &inbytes, outbuf,
                                      &outbytes) == APR_SUCCESS)
                return outbuf;
        }
    
        return sent_password;
    }
    
    
    /*
     * Build the search filter, or at least as much of the search filter that
     * will fit in the buffer, and return APR_EGENERAL if it won't fit, otherwise
     * APR_SUCCESS.
     *
     * 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 apr_status_t authn_ldap_build_filter(char filtbuf[FILTER_LENGTH],
                                 request_rec *r,
                                 const char *user,
                                 const char *filter,
                                 authn_ldap_config_t *sec)
    {
        char *q;
        const char *p, *filtbuf_end;
        apr_xlate_t *convset = NULL;
        apr_size_t inbytes;
        apr_size_t outbytes;
        char *outbuf;
        int nofilter = 0, len;
        apr_status_t rv = APR_SUCCESS;
    
        if (!filter) {
            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 = outbuf;
            }
        }
    
        /*
         * Create the first part of the filter, which consists of the
         * config-supplied portions.
         */
    
        if ((nofilter = (!filter || !*filter || !strcasecmp(filter, "none")))) { 
            len = apr_snprintf(filtbuf, FILTER_LENGTH, "(%s=", sec->attribute);
        }
        else { 
            len = 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;
        for (p = user, q = filtbuf + len; *p; ) {
            if (strchr("*()\\", *p) != NULL) {
    #if APR_HAS_MICROSOFT_LDAPSDK
                if (q + 3 >= filtbuf_end) { /* accounts for final \0 */
                    rv = APR_EGENERAL;
                    goto out;
                }
                *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
                if (q + 2 >= filtbuf_end) { /* accounts for final \0 */
                    rv = APR_EGENERAL;
                    goto out;
                }
                *q++ = '\\';
                *q++ = *p++;
    #endif
            }
            else {
                if (q + 1 >= filtbuf_end) { /* accounts for final \0 */
                    rv = APR_EGENERAL;
                    goto out;
                }
                *q++ = *p++;
            }
        }
    
        /*
         * Append the closing parens of the filter, unless doing so would
         * overrun the buffer.
         */
    
        if (nofilter) { 
            if (q + 1 >= filtbuf_end) { /* accounts for final \0 */
                rv = APR_EGENERAL;
                goto out;
            }
            *q++ = ')';
        } 
        else { 
            if (q + 2 >= filtbuf_end) { /* accounts for final \0 */
                rv = APR_EGENERAL;
                goto out;
            }
            *q++ = ')';
            *q++ = ')';
        }
    
    out:
        *q = '\0';
        return rv;
    }
    
    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->subgroupclasses = 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->bind_authoritative = 1;
        sec->deref = always;
        sec->group_attrib_is_dn = 1;
        sec->secure = -1;   /*Initialize to unset*/
        sec->maxNestingDepth = 10;
        sec->sgAttributes = apr_pcalloc(p, sizeof (char *) * (GROUPATTR_MAX_ELTS + 1));
    
        sec->user_is_dn = 0;
        sec->remote_user_attribute = NULL;
        sec->compare_dn_on_server = 0;
    
        sec->authz_prefix = AUTHZ_PREFIX;
    
        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;
    }
    
    static int set_request_vars(request_rec *r, enum auth_ldap_phase phase, const char **vals) {
        char *prefix = NULL;
        int prefix_len;
        int remote_user_attribute_set = 0;
        authn_ldap_config_t *sec =
            (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
    
        prefix = (phase == LDAP_AUTHN) ? AUTHN_PREFIX : sec->authz_prefix;
        prefix_len = strlen(prefix);
    
        if (sec->attributes && vals) {
            apr_table_t *e = r->subprocess_env;
            int i = 0;
            while (sec->attributes[i]) {
                char *str = apr_pstrcat(r->pool, prefix, sec->attributes[i], NULL);
                int j = prefix_len;
                while (str[j]) {
                    str[j] = apr_toupper(str[j]);
                    j++;
                }
                apr_table_setn(e, str, vals[i] ? vals[i] : "");
    
                /* handle remote_user_attribute, if set */
                if ((phase == LDAP_AUTHN) &&
                    sec->remote_user_attribute &&
                    !strcmp(sec->remote_user_attribute, sec->attributes[i])) {
                    r->user = (char *)apr_pstrdup(r->pool, vals[i]);
                    remote_user_attribute_set = 1;
                }
                i++;
            }
        }
        return remote_user_attribute_set;
    }
    
    static const char *ldap_determine_binddn(request_rec *r, const char *user) {
        authn_ldap_config_t *sec =
            (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
        const char *result = user;
        ap_regmatch_t regm[AP_MAX_REG_MATCH];
    
        if (NULL == user || NULL == sec || !sec->bind_regex || !sec->bind_subst) {
            return result;
        }
    
        if (!ap_regexec(sec->bind_regex, user, AP_MAX_REG_MATCH, regm, 0)) {
            char *substituted = ap_pregsub(r->pool, sec->bind_subst, user, AP_MAX_REG_MATCH, regm);
            if (NULL != substituted) {
                result = substituted;
            }
        }
    
        apr_table_set(r->subprocess_env, "LDAP_BINDASUSER", result);
    
        return result;
    }
    
    
    /* Some LDAP servers restrict who can search or compare, and the hard-coded ID
     * might be good for the DN lookup but not for later operations.
     */
    static util_ldap_connection_t *get_connection_for_authz(request_rec *r, enum auth_ldap_optype type) {
        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);
    
        const char *binddn = sec->binddn;
        const char *bindpw = sec->bindpw;
    
        /* If the per-request config isn't set, we didn't authenticate this user, and leave the default credentials */
        if (req && req->password &&
             ((type == LDAP_SEARCH && sec->search_as_user)    ||
              (type == LDAP_COMPARE && sec->compare_as_user)  ||
              (type == LDAP_COMPARE_AND_SEARCH && sec->compare_as_user && sec->search_as_user))){
                binddn = req->dn;
                bindpw = req->password;
        }
    
        return util_ldap_connection_find(r, sec->host, sec->port,
                                         binddn, bindpw,
                                         sec->deref, sec->secure);
    }
    /*
     * 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)
    {
        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;
        int remote_user_attribute_set = 0;
        const char *dn = NULL;
        const char *utfpassword;
    
        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) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02558) 
                          "no AuthLDAPURL");
    
            return AUTH_GENERAL_ERROR;
        }
    
        /* Get the password that the client sent */
        if (password == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01692)
                          "auth_ldap authenticate: no password specified");
            return AUTH_GENERAL_ERROR;
        }
    
        if (user == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01693)
                          "auth_ldap authenticate: no user specified");
            return AUTH_GENERAL_ERROR;
        }
    
        /*
         * 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 (!(*password)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10263)
                          "auth_ldap authenticate: empty password specified");
            return AUTH_DENIED;
        }
    
        /* There is a good AuthLDAPURL, right? */
        if (sec->host) {
            const char *binddn = sec->binddn;
            const char *bindpw = sec->bindpw;
            if (sec->initial_bind_as_user) {
                bindpw = password;
                binddn = ldap_determine_binddn(r, user);
            }
    
            ldc = util_ldap_connection_find(r, sec->host, sec->port,
                                           binddn, bindpw,
                                           sec->deref, sec->secure);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01690)
                          "auth_ldap authenticate: no sec->host - weird...?");
            return AUTH_GENERAL_ERROR;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01691)
                      "auth_ldap authenticate: using URL %s", sec->url);
    
        /* build the username filter */
        if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, user, NULL, sec)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02622)
                          "auth_ldap authenticate: ldap filter too long (>%d): %s",
                          FILTER_LENGTH, filtbuf);
            util_ldap_connection_close(ldc);
            return AUTH_GENERAL_ERROR;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "auth_ldap authenticate: final authn filter is %s", filtbuf);
    
        /* convert password to utf-8 */
        utfpassword = authn_ldap_xlate_password(r, password);
    
        /* do the user search */
        result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope,
                                             sec->attributes, filtbuf, utfpassword,
                                             &dn, &(req->vals));
        util_ldap_connection_close(ldc);
    
        /* handle bind failure */
        if (result != LDAP_SUCCESS) {
            if (!sec->bind_authoritative) {
               ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01694)
                          "auth_ldap authenticate: user %s authentication failed; "
                          "URI %s [%s][%s] (not authoritative)",
                          user, r->uri, ldc->reason, ldap_err2string(result));
               return AUTH_USER_NOT_FOUND;
            }
    
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01695)
                          "auth_ldap authenticate: "
                          "user %s authentication failed; URI %s [%s][%s]",
                          user, r->uri, ldc->reason, ldap_err2string(result));
    
            /* talking to a primitive LDAP server (like RACF-over-LDAP) that doesn't return specific errors */
            if (!strcasecmp(sec->filter, "none") && LDAP_OTHER == result) { 
                return AUTH_USER_NOT_FOUND;
            }
    
            return (LDAP_NO_SUCH_OBJECT == result) ? AUTH_USER_NOT_FOUND
    #ifdef LDAP_SECURITY_ERROR
                     : (LDAP_SECURITY_ERROR(result)) ? AUTH_DENIED
    #else
                     : (LDAP_INAPPROPRIATE_AUTH == result) ? AUTH_DENIED
                     : (LDAP_INVALID_CREDENTIALS == result) ? AUTH_DENIED
    #ifdef LDAP_INSUFFICIENT_ACCESS
                     : (LDAP_INSUFFICIENT_ACCESS == result) ? AUTH_DENIED
    #endif
    #ifdef LDAP_INSUFFICIENT_RIGHTS
                     : (LDAP_INSUFFICIENT_RIGHTS == result) ? AUTH_DENIED
    #endif
    #endif
    #ifdef LDAP_CONSTRAINT_VIOLATION
        /* At least Sun Directory Server sends this if a user is
         * locked. This is not covered by LDAP_SECURITY_ERROR.
         */
                     : (LDAP_CONSTRAINT_VIOLATION == result) ? AUTH_DENIED
    #endif
                     : AUTH_GENERAL_ERROR;
        }
    
        /* mark the user and DN */
        req->dn = dn;
        req->user = user;
        req->password = password;
        if (sec->user_is_dn) {
            r->user = (char *)req->dn;
        }
    
        /* add environment variables */
        remote_user_attribute_set = set_request_vars(r, LDAP_AUTHN, req->vals);
    
        /* sanity check */
        if (sec->remote_user_attribute && !remote_user_attribute_set) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01696)
                      "auth_ldap authenticate: "
                      "REMOTE_USER was to be set with attribute '%s', "
                      "but this attribute was not requested for in the "
                      "LDAP query for the user. REMOTE_USER will fall "
                      "back to username or DN as appropriate.",
                      sec->remote_user_attribute);
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01697)
                      "auth_ldap authenticate: accepting %s", user);
    
        return AUTH_GRANTED;
    }
    
    static authz_status ldapuser_check_authorization(request_rec *r,
                                                     const char *require_args,
                                                     const void *parsed_require_args)
    {
        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;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t;
        char *w;
    
        char filtbuf[FILTER_LENGTH];
        const char *dn = NULL;
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!sec->have_ldap_url) {
            return AUTHZ_DENIED;
        }
    
        if (sec->host) {
            ldc = get_connection_for_authz(r, LDAP_COMPARE);
            apr_pool_cleanup_register(r->pool, ldc,
                                      authnz_ldap_cleanup_connection_close,
                                      apr_pool_cleanup_null);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01698)
                          "auth_ldap authorize: no sec->host - weird...?");
            return AUTHZ_DENIED;
        }
    
        /*
         * If we have been authenticated by some other module than mod_authnz_ldap,
         * the req structure needed for authorization needs to be created
         * and populated with the userid and DN of the account in LDAP
         */
    
    
        if (!strlen(r->user)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01699)
                "ldap authorize: Userid is blank, AuthType=%s",
                r->ap_auth_type);
        }
    
        if(!req) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01700)
                "ldap authorize: Creating LDAP req structure");
    
            req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
                sizeof(authn_ldap_request_t));
    
            /* Build the username filter */
            if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02623)
                              "auth_ldap authorize: ldap filter too long (>%d): %s",
                              FILTER_LENGTH, filtbuf);
                return AUTHZ_DENIED;
            }
    
            /* Search for the user DN */
            result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
                 sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
    
            /* Search failed, log error and return failure */
            if(result != LDAP_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01701)
                    "auth_ldap authorise: User DN not found, %s", ldc->reason);
                return AUTHZ_DENIED;
            }
    
            ap_set_module_config(r->request_config, &authnz_ldap_module, req);
            req->dn = dn;
            req->user = r->user;
    
        }
    
        if (req->dn == NULL || strlen(req->dn) == 0) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01702)
                          "auth_ldap authorize: require user: user's DN has not "
                          "been defined; failing authorization");
            return AUTHZ_DENIED;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02585)
                          "auth_ldap authorize: require user: Can't evaluate expression: %s",
                          err);
            return AUTHZ_DENIED;
        }
    
        /*
         * 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, require);
        switch(result) {
            case LDAP_COMPARE_TRUE: {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01703)
                              "auth_ldap authorize: require user: authorization "
                              "successful");
                set_request_vars(r, LDAP_AUTHZ, req->vals);
                return AUTHZ_GRANTED;
            }
            default: {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01704)
                              "auth_ldap authorize: require user: "
                              "authorization failed [%s][%s]",
                              ldc->reason, ldap_err2string(result));
            }
        }
    
        /*
         * Now break apart the line and compare each word on it
         */
        t = require;
        while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
            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, 0, r, APLOGNO(01705)
                                  "auth_ldap authorize: "
                                  "require user: authorization successful");
                    set_request_vars(r, LDAP_AUTHZ, req->vals);
                    return AUTHZ_GRANTED;
                }
                default: {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01706)
                                  "auth_ldap authorize: "
                                  "require user: authorization failed [%s][%s]",
                                  ldc->reason, ldap_err2string(result));
                }
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01707)
                      "auth_ldap authorize user: authorization denied for "
                      "user %s to %s",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static authz_status ldapgroup_check_authorization(request_rec *r,
                                                      const char *require_args,
                                                      const void *parsed_require_args)
    {
        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;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t;
    
        char filtbuf[FILTER_LENGTH];
        const char *dn = NULL;
        struct mod_auth_ldap_groupattr_entry_t *ent;
        int i;
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!sec->have_ldap_url) {
            return AUTHZ_DENIED;
        }
    
        if (sec->host) {
            ldc = get_connection_for_authz(r, LDAP_COMPARE); /* for the top-level group only */
            apr_pool_cleanup_register(r->pool, ldc,
                                      authnz_ldap_cleanup_connection_close,
                                      apr_pool_cleanup_null);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01708)
                          "auth_ldap authorize: no sec->host - weird...?");
            return AUTHZ_DENIED;
        }
    
        /*
         * 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 there are no elements in the sub group classes array, the default
         * should be groupOfNames and groupOfUniqueNames; populate the array now.
         */
        if (sec->subgroupclasses->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->subgroupclasses);
            grp->name = "groupOfNames";
            grp = apr_array_push(sec->subgroupclasses);
            grp->name = "groupOfUniqueNames";
    #if APR_HAS_THREADS
            apr_thread_mutex_unlock(sec->lock);
    #endif
        }
    
        /*
         * 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
         */
    
        if (!strlen(r->user)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01709)
                "ldap authorize: Userid is blank, AuthType=%s",
                r->ap_auth_type);
        }
    
        if(!req) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01710)
                "ldap authorize: Creating LDAP req structure");
    
            req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
                sizeof(authn_ldap_request_t));
            /* Build the username filter */
            if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02624)
                              "auth_ldap authorize: ldap filter too long (>%d): %s",
                              FILTER_LENGTH, filtbuf);
                return AUTHZ_DENIED;
            }
    
            /* Search for the user DN */
            result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
                 sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
    
            /* Search failed, log error and return failure */
            if(result != LDAP_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01711)
                    "auth_ldap authorise: User DN not found, %s", ldc->reason);
                return AUTHZ_DENIED;
            }
    
            ap_set_module_config(r->request_config, &authnz_ldap_module, req);
            req->dn = dn;
            req->user = r->user;
        }
    
        ent = (struct mod_auth_ldap_groupattr_entry_t *) sec->groupattr->elts;
    
        if (sec->group_attrib_is_dn) {
            if (req->dn == NULL || strlen(req->dn) == 0) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01712)
                              "auth_ldap authorize: require group: user's DN has "
                              "not been defined; failing authorization for user %s",
                              r->user);
                return AUTHZ_DENIED;
            }
        }
        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;
            }
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02586)
                          "auth_ldap authorize: require group: Can't evaluate expression: %s",
                          err);
            return AUTHZ_DENIED;
        }
    
        t = require;
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01713)
                      "auth_ldap authorize: require group: testing for group "
                      "membership in \"%s\"",
                      t);
    
        /* PR52464 exhaust attrs in base group before checking subgroups */
        for (i = 0; i < sec->groupattr->nelts; i++) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01714)
                          "auth_ldap authorize: require group: testing for %s: "
                          "%s (%s)",
                          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);
            if (result == LDAP_COMPARE_TRUE) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01715)
                              "auth_ldap authorize: require group: "
                              "authorization successful (attribute %s) "
                              "[%s][%d - %s]",
                              ent[i].name, ldc->reason, result,
                              ldap_err2string(result));
                set_request_vars(r, LDAP_AUTHZ, req->vals);
                return AUTHZ_GRANTED;
            }
            else { 
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01719)
                                  "auth_ldap authorize: require group \"%s\": "
                                  "didn't match with attr %s [%s][%d - %s]",
                                  t, ent[i].name, ldc->reason, result, 
                                  ldap_err2string(result));
            }
        }
        
        for (i = 0; i < sec->groupattr->nelts; i++) {
            /* nested groups need searches and compares, so grab a new handle */
            authnz_ldap_cleanup_connection_close(ldc);
            apr_pool_cleanup_kill(r->pool, ldc,authnz_ldap_cleanup_connection_close);
    
            ldc = get_connection_for_authz(r, LDAP_COMPARE_AND_SEARCH);
            apr_pool_cleanup_register(r->pool, ldc,
                                      authnz_ldap_cleanup_connection_close,
                                      apr_pool_cleanup_null);
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01716)
                           "auth_ldap authorise: require group \"%s\": "
                           "failed [%s][%d - %s], checking sub-groups",
                           t, ldc->reason, result, ldap_err2string(result));
    
            result = util_ldap_cache_check_subgroups(r, ldc, sec->url, t, ent[i].name,
                                                     sec->group_attrib_is_dn ? req->dn : req->user,
                                                     sec->sgAttributes[0] ? sec->sgAttributes : default_attributes,
                                                     sec->subgroupclasses,
                                                     0, sec->maxNestingDepth);
            if (result == LDAP_COMPARE_TRUE) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01717)
                              "auth_ldap authorise: require group "
                              "(sub-group): authorisation successful "
                              "(attribute %s) [%s][%d - %s]",
                              ent[i].name, ldc->reason, result,
                              ldap_err2string(result));
                set_request_vars(r, LDAP_AUTHZ, req->vals);
                return AUTHZ_GRANTED;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01718)
                              "auth_ldap authorise: require group "
                              "(sub-group) \"%s\": didn't match with attr %s "
                              "[%s][%d - %s]",
                              t, ldc->reason, ent[i].name, result, 
                              ldap_err2string(result));
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01720)
                      "auth_ldap authorize group: authorization denied for "
                      "user %s to %s",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static authz_status ldapdn_check_authorization(request_rec *r,
                                                   const char *require_args,
                                                   const void *parsed_require_args)
    {
        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;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t;
    
        char filtbuf[FILTER_LENGTH];
        const char *dn = NULL;
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!sec->have_ldap_url) {
            return AUTHZ_DENIED;
        }
    
        if (sec->host) {
            ldc = get_connection_for_authz(r, LDAP_SEARCH); /* _comparedn is a searche */
            apr_pool_cleanup_register(r->pool, ldc,
                                      authnz_ldap_cleanup_connection_close,
                                      apr_pool_cleanup_null);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01721)
                          "auth_ldap authorize: no sec->host - weird...?");
            return AUTHZ_DENIED;
        }
    
        /*
         * 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
         */
    
        if (!strlen(r->user)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01722)
                "ldap authorize: Userid is blank, AuthType=%s",
                r->ap_auth_type);
        }
    
        if(!req) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01723)
                "ldap authorize: Creating LDAP req structure");
    
            req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
                sizeof(authn_ldap_request_t));
            /* Build the username filter */
            if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02625)
                              "auth_ldap authorize: ldap filter too long (>%d): %s",
                              FILTER_LENGTH, filtbuf);
                return AUTHZ_DENIED;
            }
    
            /* Search for the user DN */
            result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
                 sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
    
            /* Search failed, log error and return failure */
            if(result != LDAP_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01724)
                    "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason);
                return AUTHZ_DENIED;
            }
    
            ap_set_module_config(r->request_config, &authnz_ldap_module, req);
            req->dn = dn;
            req->user = r->user;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02587)
                          "auth_ldap authorize: require dn: Can't evaluate expression: %s",
                          err);
            return AUTHZ_DENIED;
        }
    
        t = require;
    
        if (req->dn == NULL || strlen(req->dn) == 0) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01725)
                          "auth_ldap authorize: require dn: user's DN has not "
                          "been defined; failing authorization");
            return AUTHZ_DENIED;
        }
    
        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, 0, r, APLOGNO(01726)
                              "auth_ldap authorize: "
                              "require dn: authorization successful");
                set_request_vars(r, LDAP_AUTHZ, req->vals);
                return AUTHZ_GRANTED;
            }
            default: {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01727)
                              "auth_ldap authorize: "
                              "require dn \"%s\": LDAP error [%s][%s]",
                              t, ldc->reason, ldap_err2string(result));
            }
        }
    
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01728)
                      "auth_ldap authorize dn: authorization denied for "
                      "user %s to %s",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static authz_status ldapattribute_check_authorization(request_rec *r,
                                                          const char *require_args,
                                                          const void *parsed_require_args)
    {
        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;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t;
        char *w, *value;
    
        char filtbuf[FILTER_LENGTH];
        const char *dn = NULL;
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!sec->have_ldap_url) {
            return AUTHZ_DENIED;
        }
    
        if (sec->host) {
            ldc = get_connection_for_authz(r, LDAP_COMPARE);
            apr_pool_cleanup_register(r->pool, ldc,
                                      authnz_ldap_cleanup_connection_close,
                                      apr_pool_cleanup_null);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01729)
                          "auth_ldap authorize: no sec->host - weird...?");
            return AUTHZ_DENIED;
        }
    
        /*
         * 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
         */
    
        if (!strlen(r->user)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01730)
                "ldap authorize: Userid is blank, AuthType=%s",
                r->ap_auth_type);
        }
    
        if(!req) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01731)
                "ldap authorize: Creating LDAP req structure");
    
            req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
                sizeof(authn_ldap_request_t));
            /* Build the username filter */
            if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02626)
                              "auth_ldap authorize: ldap filter too long (>%d): %s",
                              FILTER_LENGTH, filtbuf);
                return AUTHZ_DENIED;
            }
    
            /* Search for the user DN */
            result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
                 sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
    
            /* Search failed, log error and return failure */
            if(result != LDAP_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01732)
                    "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason);
                return AUTHZ_DENIED;
            }
    
            ap_set_module_config(r->request_config, &authnz_ldap_module, req);
            req->dn = dn;
            req->user = r->user;
        }
    
        if (req->dn == NULL || strlen(req->dn) == 0) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01733)
                          "auth_ldap authorize: require ldap-attribute: user's DN "
                          "has not been defined; failing authorization");
            return AUTHZ_DENIED;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02588)
                          "auth_ldap authorize: require ldap-attribute: Can't "
                          "evaluate expression: %s", err);
            return AUTHZ_DENIED;
        }
    
        t = require;
    
        while (t[0]) {
            w = ap_getword(r->pool, &t, '=');
            value = ap_getword_conf(r->pool, &t);
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01734)
                          "auth_ldap authorize: checking attribute %s has value %s",
                          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, 0, r, APLOGNO(01735)
                                  "auth_ldap authorize: "
                                  "require attribute: authorization successful");
                    set_request_vars(r, LDAP_AUTHZ, req->vals);
                    return AUTHZ_GRANTED;
                }
                default: {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01736)
                                  "auth_ldap authorize: require attribute: "
                                  "authorization failed [%s][%s]",
                                  ldc->reason, ldap_err2string(result));
                }
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01737)
                      "auth_ldap authorize attribute: authorization denied for "
                      "user %s to %s",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static authz_status ldapfilter_check_authorization(request_rec *r,
                                                       const char *require_args,
                                                       const void *parsed_require_args)
    {
        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;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
    
        const char *t;
    
        char filtbuf[FILTER_LENGTH];
        const char *dn = NULL;
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!sec->have_ldap_url) {
            return AUTHZ_DENIED;
        }
    
        if (sec->host) {
            ldc = get_connection_for_authz(r, LDAP_SEARCH);
            apr_pool_cleanup_register(r->pool, ldc,
                                      authnz_ldap_cleanup_connection_close,
                                      apr_pool_cleanup_null);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01738)
                          "auth_ldap authorize: no sec->host - weird...?");
            return AUTHZ_DENIED;
        }
    
        /*
         * 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
         */
    
        if (!strlen(r->user)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01739)
                "ldap authorize: Userid is blank, AuthType=%s",
                r->ap_auth_type);
        }
    
        if(!req) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01740)
                "ldap authorize: Creating LDAP req structure");
    
            req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
                sizeof(authn_ldap_request_t));
            /* Build the username filter */
            if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02627)
                              "auth_ldap authorize: ldap filter too long (>%d): %s",
                              FILTER_LENGTH, filtbuf);
                return AUTHZ_DENIED;
            }
    
            /* Search for the user DN */
            result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
                 sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
    
            /* Search failed, log error and return failure */
            if(result != LDAP_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01741)
                    "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason);
                return AUTHZ_DENIED;
            }
    
            ap_set_module_config(r->request_config, &authnz_ldap_module, req);
            req->dn = dn;
            req->user = r->user;
        }
    
        if (req->dn == NULL || strlen(req->dn) == 0) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01742)
                          "auth_ldap authorize: require ldap-filter: user's DN "
                          "has not been defined; failing authorization");
            return AUTHZ_DENIED;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02589)
                          "auth_ldap authorize: require ldap-filter: Can't "
                          "evaluate require expression: %s", err);
            return AUTHZ_DENIED;
        }
    
        t = require;
    
        if (t[0]) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01743)
                          "auth_ldap authorize: checking filter %s", t);
    
            /* Build the username filter */
            if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, req->user, t, sec)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02628)
                              "auth_ldap authorize: ldap filter too long (>%d): %s",
                              FILTER_LENGTH, filtbuf);
                return AUTHZ_DENIED;
            }
    
            /* Search for the user DN */
            result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
                 sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
    
            /* Make sure that the filtered search returned the correct user dn */
            if (result == LDAP_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01744)
                              "auth_ldap authorize: checking dn match %s", dn);
                if (sec->compare_as_user) {
                    /* ldap-filter is the only authz that requires a search and a compare */
                    apr_pool_cleanup_kill(r->pool, ldc, authnz_ldap_cleanup_connection_close);
                    authnz_ldap_cleanup_connection_close(ldc);
                    ldc = get_connection_for_authz(r, LDAP_COMPARE);
                }
                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, 0, r, APLOGNO(01745)
                                  "auth_ldap authorize: require ldap-filter: "
                                  "authorization successful");
                    set_request_vars(r, LDAP_AUTHZ, req->vals);
                    return AUTHZ_GRANTED;
                }
                case LDAP_FILTER_ERROR: {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01746)
                                  "auth_ldap authorize: require ldap-filter: "
                                  "%s authorization failed [%s][%s]",
                                  filtbuf, ldc->reason, ldap_err2string(result));
                    break;
                }
                default: {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01747)
                                  "auth_ldap authorize: require ldap-filter: "
                                  "authorization failed [%s][%s]",
                                  ldc->reason, ldap_err2string(result));
                }
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01748)
                      "auth_ldap authorize filter: authorization denied for "
                      "user %s to %s",
                      r->user, r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static authz_status ldapsearch_check_authorization(request_rec *r,
                                                       const char *require_args,
                                                       const void *parsed_require_args)
    {
        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;
    
        const char *err = NULL;
        const ap_expr_info_t *expr = parsed_require_args;
        const char *require;
        const char *t;
        const char *dn = NULL;
    
        if (!sec->have_ldap_url) {
            return AUTHZ_DENIED;
        }
    
        if (sec->host) {
            ldc = get_connection_for_authz(r, LDAP_SEARCH);
            apr_pool_cleanup_register(r->pool, ldc,
                                      authnz_ldap_cleanup_connection_close,
                                      apr_pool_cleanup_null);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02636)
                          "auth_ldap authorize: no sec->host - weird...?");
            return AUTHZ_DENIED;
        }
    
        require = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02629)
                          "auth_ldap authorize: require ldap-search: Can't "
                          "evaluate require expression: %s", err);
            return AUTHZ_DENIED;
        }
    
        t = require;
    
        if (t[0]) {
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02630)
                          "auth_ldap authorize: checking filter %s", t);
    
            /* Search for the user DN */
            result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
                 sec->scope, sec->attributes, t, &dn, &(req->vals));
    
            /* Make sure that the filtered search returned a single dn */
            if (result == LDAP_SUCCESS && dn) {
                req->dn = dn;
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02631)
                              "auth_ldap authorize: require ldap-search: "
                              "authorization successful");
                set_request_vars(r, LDAP_AUTHZ, req->vals);
                return AUTHZ_GRANTED;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02632)
                              "auth_ldap authorize: require ldap-search: "
                              "%s authorization failed [%s][%s]",
                              t, ldc->reason, ldap_err2string(result));
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02633)
                      "auth_ldap authorize search: authorization denied for "
                      "to %s", r->uri);
    
        return AUTHZ_DENIED;
    }
    
    static const char *ldap_parse_config(cmd_parms *cmd, const char *require_line,
                                         const void **parsed_require_line)
    {
        const char *expr_err = NULL;
        ap_expr_info_t *expr;
    
        expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
                &expr_err, NULL);
    
        if (expr_err)
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression in require line: ",
                               expr_err, NULL);
    
        *parsed_require_line = expr;
    
        return NULL;
    }
    
    
    /*
     * 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;
    
        rc = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result));
        if (rc != APR_SUCCESS) {
            return result->reason;
        }
        sec->url = apr_pstrdup(cmd->pool, url);
    
        /* Set all the values, or at least some sane defaults */
        if (sec->host) {
            sec->host = apr_pstrcat(cmd->pool, urld->lud_host, " ", sec->host, NULL);
        }
        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_pstrmemdup(cmd->pool, urld->lud_filter+1,
                                                        strlen(urld->lud_filter)-2);
            }
            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;
        }
        else
        {
            sec->port = urld->lud_port? urld->lud_port : LDAP_PORT;
        }
    
        sec->have_ldap_url = 1;
    
        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, cmd->server,
                     "auth_ldap url parse: `%s', Host: %s, Port: %d, DN: %s, "
                     "attrib: %s, scope: %s, filter: %s, connection mode: %s",
                     url,
                     urld->lud_host,
                     urld->lud_port,
                     urld->lud_dn,
                     urld->lud_attrs? urld->lud_attrs[0] : "(null)",
                     (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" :
                      urld->lud_scope == LDAP_SCOPE_BASE? "base" :
                      urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown"),
                     urld->lud_filter,
                     sec->secure == APR_LDAP_SSL  ? "using SSL": "not using SSL"
                     );
    
        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 AuthLDAPDereferenceAliases directive";
        }
        return NULL;
    }
    
    static const char *mod_auth_ldap_add_subgroup_attribute(cmd_parms *cmd, void *config, const char *arg)
    {
        int i = 0;
    
        authn_ldap_config_t *sec = config;
    
        for (i = 0; sec->sgAttributes[i]; i++) {
            ;
        }
        if (i == GROUPATTR_MAX_ELTS)
            return "Too many AuthLDAPSubGroupAttribute values";
    
        sec->sgAttributes[i] = apr_pstrdup(cmd->pool, arg);
    
        return NULL;
    }
    
    static const char *mod_auth_ldap_add_subgroup_class(cmd_parms *cmd, void *config, const char *arg)
    {
        struct mod_auth_ldap_groupattr_entry_t *new;
    
        authn_ldap_config_t *sec = config;
    
        if (sec->subgroupclasses->nelts > GROUPATTR_MAX_ELTS)
            return "Too many AuthLDAPSubGroupClass values";
    
        new = apr_array_push(sec->subgroupclasses);
        new->name = apr_pstrdup(cmd->pool, arg);
    
        return NULL;
    }
    
    static const char *mod_auth_ldap_set_subgroup_maxdepth(cmd_parms *cmd,
                                                           void *config,
                                                           const char *max_depth)
    {
        authn_ldap_config_t *sec = config;
    
        sec->maxNestingDepth = atol(max_depth);
    
        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 char *set_bind_pattern(cmd_parms *cmd, void *_cfg, const char *exp, const char *subst)
    {
        authn_ldap_config_t *sec = _cfg;
        ap_regex_t *regexp;
    
        regexp = ap_pregcomp(cmd->pool, exp, AP_REG_EXTENDED);
    
        if (!regexp) {
            return apr_pstrcat(cmd->pool, "AuthLDAPInitialBindPattern: cannot compile regular "
                                          "expression '", exp, "'", NULL);
        }
    
        sec->bind_regex = regexp;
        sec->bind_subst = subst;
    
        return NULL;
    }
    
    static const char *set_bind_password(cmd_parms *cmd, void *_cfg, const char *arg)
    {
        authn_ldap_config_t *sec = _cfg;
        int arglen = strlen(arg);
        char **argv;
        char *result;
    
        if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) {
            if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) {
                return apr_pstrcat(cmd->pool,
                                   "Unable to parse exec arguments from ",
                                   arg+5, NULL);
            }
            argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);
    
            if (!argv[0]) {
                return apr_pstrcat(cmd->pool,
                                   "Invalid AuthLDAPBindPassword exec location:",
                                   arg+5, NULL);
            }
            result = ap_get_exec_line(cmd->pool,
                                      (const char*)argv[0], (const char * const *)argv);
    
            if (!result) {
                return apr_pstrcat(cmd->pool,
                                   "Unable to get bind password from exec of ",
                                   arg+5, NULL);
            }
            sec->bindpw = result;
        }
        else {
            sec->bindpw = (char *)arg;
        }
    
        if (!(*sec->bindpw)) {
            return "Empty passwords are invalid for AuthLDAPBindPassword";
        }
    
        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 compliant\n"
                      "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n"
                      "<ul>\n"
                      "<li>Host is the name of the LDAP server. Use a space separated list of hosts \n"
                      "to specify redundant servers.\n"
                      "<li>Port is optional, and specifies the port to connect to.\n"
                      "<li>basedn specifies the base DN to start searches from\n"
                      "<li>Attrib specifies what attribute to search for in the directory. If not "
                      "provided, it defaults to <b>uid</b>.\n"
                      "<li>Scope is the scope of the search, and can be either <b>sub</b> or "
                      "<b>one</b>. If not provided, the default is <b>sub</b>.\n"
                      "<li>Filter is a filter to use in the search. If not provided, "
                      "defaults to <b>(objectClass=*)</b>.\n"
                      "</ul>\n"
                      "Searches are performed using the attribute and the filter combined. "
                      "For example, assume that the\n"
                      "LDAP URL is <b>ldap://ldap.airius.com/ou=People, o=Airius?uid?sub?(posixid=*)</b>. "
                      "Searches will\n"
                      "be done using the filter <b>(&((posixid=*))(uid=<i>username</i>))</b>, "
                      "where <i>username</i>\n"
                      "is the user name passed by the HTTP client. The search will be a subtree "
                      "search on the branch <b>ou=People, o=Airius</b>."),
    
        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", set_bind_password, NULL, OR_AUTHCFG,
                      "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."),
    
        AP_INIT_FLAG("AuthLDAPBindAuthoritative", ap_set_flag_slot,
                      (void *)APR_OFFSETOF(authn_ldap_config_t, bind_authoritative), OR_AUTHCFG,
                      "Set to 'on' to return failures when user-specific bind fails - defaults to on."),
    
        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_TAKE1("AuthLDAPRemoteUserAttribute", ap_set_string_slot,
                     (void *)APR_OFFSETOF(authn_ldap_config_t, remote_user_attribute), OR_AUTHCFG,
                     "Override the user supplied username and place the "
                     "contents of this attribute in the REMOTE_USER "
                     "environment variable."),
    
        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("AuthLDAPSubGroupAttribute", mod_auth_ldap_add_subgroup_attribute, NULL, OR_AUTHCFG,
                        "Attribute labels used to define sub-group (or nested group) membership in groups - "
                        "defaults to member and uniqueMember"),
    
        AP_INIT_ITERATE("AuthLDAPSubGroupClass", mod_auth_ldap_add_subgroup_class, NULL, OR_AUTHCFG,
                         "LDAP objectClass values used to identify sub-group instances - "
                         "defaults to groupOfNames and groupOfUniqueNames"),
    
        AP_INIT_TAKE1("AuthLDAPMaxSubGroupDepth", mod_auth_ldap_set_subgroup_maxdepth, NULL, OR_AUTHCFG,
                          "Maximum subgroup nesting depth to be evaluated - defaults to 10 (top-level group = 0)"),
    
        AP_INIT_ITERATE("AuthLDAPGroupAttribute", mod_auth_ldap_add_group_attribute, NULL, OR_AUTHCFG,
                        "A list of attribute labels used to identify the user members of groups - 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 be one of the "
                      "values \"never\", \"searching\", \"finding\", or \"always\". "
                      "Defaults to always."),
    
        AP_INIT_TAKE1("AuthLDAPCharsetConfig", set_charset_config, NULL, RSRC_CONF,
                      "Character set conversion configuration file. If omitted, character set "
                      "conversion is disabled."),
    
        AP_INIT_TAKE1("AuthLDAPAuthorizePrefix", ap_set_string_slot,
                      (void *)APR_OFFSETOF(authn_ldap_config_t, authz_prefix), OR_AUTHCFG,
                      "The prefix to add to environment variables set during "
                      "successful authorization, default '" AUTHZ_PREFIX "'"),
    
        AP_INIT_FLAG("AuthLDAPInitialBindAsUser", ap_set_flag_slot,
                     (void *)APR_OFFSETOF(authn_ldap_config_t, initial_bind_as_user), OR_AUTHCFG,
                     "Set to 'on' to perform the initial DN lookup with the basic auth credentials "
                     "instead of anonymous or hard-coded credentials"),
    
         AP_INIT_TAKE2("AuthLDAPInitialBindPattern", set_bind_pattern, NULL, OR_AUTHCFG,
                       "The regex and substitution to determine a username that can bind based on an HTTP basic auth username"),
    
         AP_INIT_FLAG("AuthLDAPSearchAsUser", ap_set_flag_slot,
                      (void *)APR_OFFSETOF(authn_ldap_config_t, search_as_user), OR_AUTHCFG,
                      "Set to 'on' to perform authorization-based searches with the users credentials, when this module "
                      "has also performed authentication.  Does not affect nested groups lookup."),
         AP_INIT_FLAG("AuthLDAPCompareAsUser", ap_set_flag_slot,
                      (void *)APR_OFFSETOF(authn_ldap_config_t, compare_as_user), OR_AUTHCFG,
                      "Set to 'on' to perform authorization-based compares with the users credentials, when this module "
                      "has also performed authentication.  Does not affect nested groups lookups."),
        {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, APLOGNO(03159)
                             "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, 0, s, APLOGNO(01749)
                         "Module mod_ldap missing. Mod_ldap (aka. util_ldap) "
                         "must be loaded in order for mod_authnz_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, APLOGNO(01750)
                         "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, APLOGNO(01751)
                         "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, APLOGNO(01752)
                         "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,
        NULL,
    };
    
    static const authz_provider authz_ldapuser_provider =
    {
        &ldapuser_check_authorization,
        &ldap_parse_config,
    };
    static const authz_provider authz_ldapgroup_provider =
    {
        &ldapgroup_check_authorization,
        &ldap_parse_config,
    };
    
    static const authz_provider authz_ldapdn_provider =
    {
        &ldapdn_check_authorization,
        &ldap_parse_config,
    };
    
    static const authz_provider authz_ldapattribute_provider =
    {
        &ldapattribute_check_authorization,
        &ldap_parse_config,
    };
    
    static const authz_provider authz_ldapfilter_provider =
    {
        &ldapfilter_check_authorization,
        &ldap_parse_config,
    };
    
    static const authz_provider authz_ldapsearch_provider =
    {
        &ldapsearch_check_authorization,
        &ldap_parse_config,
    };
    
    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);
        util_ldap_cache_check_subgroups = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_check_subgroups);
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        /* Register authn provider */
        ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "ldap",
                                  AUTHN_PROVIDER_VERSION,
                                  &authn_ldap_provider, AP_AUTH_INTERNAL_PER_CONF);
    
        /* Register authz providers */
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-user",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_ldapuser_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-group",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_ldapgroup_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-dn",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_ldapdn_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-attribute",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_ldapattribute_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-filter",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_ldapfilter_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-search",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_ldapsearch_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
    
        ap_hook_post_config(authnz_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE);
    
        ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(authnz_ldap) =
    {
        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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_digest.c����������������������������������������������������������0000664�0001751�0001751�00000201347�14246213552�020332� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <akosut@nueva.pvt.k12.ca.us>
     * Updated to RFC-2617 by Ronald Tschal�r <ronald@innovation.ch>
     * 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.
     *
     * 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)
     *   - The source of the secret should be run-time directive (with server
     *     scope: RSRC_CONF)
     *   - 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.
     *   - MD5-sess and auth-int are not yet implemented. An incomplete
     *     implementation has been removed and can be retrieved from svn history.
     */
    
    #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 "util_mutex.h"
    #include "apr_shm.h"
    #include "apr_rmm.h"
    #include "ap_provider.h"
    
    #include "mod_auth.h"
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* struct to hold the configuration info */
    
    typedef struct digest_config_struct {
        const char  *dir_name;
        authn_provider_list *providers;
        const char  *realm;
        apr_array_header_t *qop_list;
        apr_sha1_ctx_t  nonce_ctx;
        apr_time_t    nonce_lifetime;
        int          check_nc;
        const char  *algorithm;
        char        *uri_list;
    } 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
    #define RETAINED_DATA_ID    "mod_auth_digest"
    
    
    /* 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               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 */
        const char           *raw_request_uri;
        apr_uri_t            *psd_request_uri;
        apr_time_t            nonce_time;
        enum hdr_sts          auth_hdr_sts;
        int                   needed_auth;
        const char           *ha1;
        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;
    
    /* 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 const char     *client_mutex_type = "authdigest-client";
    static const char     *opaque_mutex_type = "authdigest-opaque";
    static const char     *client_shm_filename;
    
    #define DEF_SHMEM_SIZE  1000L           /* ~ 12 entries */
    #define DEF_NUM_BUCKETS 15L
    #define HASH_DEPTH      5
    
    static apr_size_t shmem_size  = DEF_SHMEM_SIZE;
    static unsigned 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_INFO, 0, NULL, APLOGNO(01756)
                      "cleaning up shared memory");
    
        if (client_rmm) {
            apr_rmm_destroy(client_rmm);
            client_rmm = NULL;
        }
    
        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;
        }
    
        client_list = NULL;
    
        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, APLOGNO(01760)
                     "%s - all nonce-count checking and one-time nonces "
                     "disabled", msg);
    
        cleanup_tables(NULL);
    }
    
    /* RMM helper functions that behave like single-step malloc/free. */
    
    static void *rmm_malloc(apr_rmm_t *rmm, apr_size_t size)
    {
        apr_rmm_off_t offset = apr_rmm_malloc(rmm, size);
    
        if (!offset) {
            return NULL;
        }
    
        return apr_rmm_addr_get(rmm, offset);
    }
    
    static apr_status_t rmm_free(apr_rmm_t *rmm, void *alloc)
    {
        apr_rmm_off_t offset = apr_rmm_offset_get(rmm, alloc);
    
        return apr_rmm_free(rmm, offset);
    }
    
    #if APR_HAS_SHARED_MEMORY
    
    static int initialize_tables(server_rec *s, apr_pool_t *ctx)
    {
        unsigned long idx;
        apr_status_t   sts;
    
        /* set up client list */
    
        /* Create the shared memory segment */
    
        client_shm = NULL;
        client_rmm = NULL;
        client_lock = NULL;
        opaque_lock = NULL;
        client_list = NULL;
    
        /*
         * Create a unique filename using our pid. This information is
         * stashed in the global variable so the children inherit it.
         */
        client_shm_filename = ap_runtime_dir_relative(ctx, "authdigest_shm");
        client_shm_filename = ap_append_pid(ctx, client_shm_filename, ".");
    
        /* Use anonymous shm by default, fall back on name-based. */
        sts = apr_shm_create(&client_shm, shmem_size, NULL, ctx);
        if (APR_STATUS_IS_ENOTIMPL(sts)) {
            /* For a name-based segment, remove it first in case of a
             * previous unclean shutdown. */
            apr_shm_remove(client_shm_filename, ctx);
    
            /* Now create that segment */
            sts = apr_shm_create(&client_shm, shmem_size,
                                client_shm_filename, ctx);
        }
    
        if (APR_SUCCESS != sts) {
            ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, APLOGNO(01762)
                         "Failed to create shared memory segment on file %s",
                         client_shm_filename);
            log_error_and_cleanup("failed to initialize shm", sts, s);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        sts = apr_rmm_init(&client_rmm,
                           NULL, /* no lock, we'll do the locking ourselves */
                           apr_shm_baseaddr_get(client_shm),
                           shmem_size, ctx);
        if (sts != APR_SUCCESS) {
            log_error_and_cleanup("failed to initialize rmm", sts, s);
            return !OK;
        }
    
        client_list = 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 !OK;
        }
        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;
    
        sts = ap_global_mutex_create(&client_lock, NULL, client_mutex_type, NULL,
                                     s, ctx, 0);
        if (sts != APR_SUCCESS) {
            log_error_and_cleanup("failed to create lock (client_lock)", sts, s);
            return !OK;
        }
    
    
        /* setup opaque */
    
        opaque_cntr = rmm_malloc(client_rmm, sizeof(*opaque_cntr));
        if (opaque_cntr == NULL) {
            log_error_and_cleanup("failed to allocate shared memory", -1, s);
            return !OK;
        }
        *opaque_cntr = 1UL;
    
        sts = ap_global_mutex_create(&opaque_lock, NULL, opaque_mutex_type, NULL,
                                     s, ctx, 0);
        if (sts != APR_SUCCESS) {
            log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s);
            return !OK;
        }
    
    
        /* setup one-time-nonce counter */
    
        otn_counter = rmm_malloc(client_rmm, sizeof(*otn_counter));
        if (otn_counter == NULL) {
            log_error_and_cleanup("failed to allocate shared memory", -1, s);
            return !OK;
        }
        *otn_counter = 0;
        /* no lock here */
    
    
        /* success */
        return OK;
    }
    
    #endif /* APR_HAS_SHARED_MEMORY */
    
    static int pre_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
    {
        apr_status_t rv;
        void *retained;
    
        rv = ap_mutex_register(pconf, client_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
        if (rv != APR_SUCCESS)
            return !OK;
        rv = ap_mutex_register(pconf, opaque_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
        if (rv != APR_SUCCESS)
            return !OK;
    
        retained = ap_retained_data_get(RETAINED_DATA_ID);
        if (retained == NULL) {
            retained = ap_retained_data_create(RETAINED_DATA_ID, SECRET_LEN);
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(01757)
                         "generating secret for digest authentication");
    #if APR_HAS_RANDOM
            rv = apr_generate_random_bytes(retained, SECRET_LEN);
    #else
    #error APR random number support is missing
    #endif
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(01758)
                             "error generating secret");
                return !OK;
            }
        }
        secret = retained;
        return OK;
    }
    
    static int initialize_module(apr_pool_t *p, apr_pool_t *plog,
                                 apr_pool_t *ptemp, server_rec *s)
    {
        /* 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. */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
            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.
         */
        if (initialize_tables(s, p) != OK) {
            return !OK;
        }
    #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;
        }
    
        /* Get access to rmm in child */
        sts = apr_rmm_attach(&client_rmm,
                             NULL,
                             apr_shm_baseaddr_get(client_shm),
                             p);
        if (sts != APR_SUCCESS) {
            log_error_and_cleanup("failed to attach to rmm", sts, s);
            return;
        }
    
        sts = apr_global_mutex_child_init(&client_lock,
                                          apr_global_mutex_lockfile(client_lock),
                                          p);
        if (sts != APR_SUCCESS) {
            log_error_and_cleanup("failed to create lock (client_lock)", sts, s);
            return;
        }
        sts = apr_global_mutex_child_init(&opaque_lock,
                                          apr_global_mutex_lockfile(opaque_lock),
                                          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_array_make(p, 2, sizeof(char *));
            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;
    #ifdef AP_DEBUG
        int i;
    
        /* check that we got random numbers */
        for (i = 0; i < SECRET_LEN; i++) {
            if (secret[i] != 0)
                break;
        }
        ap_assert(i < SECRET_LEN);
    #endif
    
        /* 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, SECRET_LEN);
        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;
    
        newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
        newp->provider_name = arg;
    
        /* lookup and cache the actual provider now */
        newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
                                            newp->provider_name,
                                            AUTHN_PROVIDER_VERSION);
    
        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", newp->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;
    
        if (!ap_cstr_casecmp(op, "none")) {
            apr_array_clear(conf->qop_list);
            *(const char **)apr_array_push(conf->qop_list) = "none";
            return NULL;
        }
    
        if (!ap_cstr_casecmp(op, "auth-int")) {
            return "AuthDigestQop auth-int is not implemented";
        }
        else if (ap_cstr_casecmp(op, "auth")) {
            return apr_pstrcat(cmd->pool, "Unrecognized qop: ", op, NULL);
        }
    
        *(const char **)apr_array_push(conf->qop_list) = op;
    
        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)
    {
        return "AuthDigestNonceFormat is not implemented";
    }
    
    static const char *set_nc_check(cmd_parms *cmd, void *config, int flag)
    {
    #if !APR_HAS_SHARED_MEMORY
        if (flag) {
            return "AuthDigestNcCheck: ERROR: nonce-count checking "
                         "is not supported on platforms without shared-memory "
                         "support";
        }
    #endif
    
        ((digest_config_rec *) config)->check_nc = flag;
        return NULL;
    }
    
    static const char *set_algorithm(cmd_parms *cmd, void *config, const char *alg)
    {
        if (!ap_cstr_casecmp(alg, "MD5-sess")) {
            return "AuthDigestAlgorithm: ERROR: algorithm `MD5-sess' "
                    "is not implemented";
        }
        else if (ap_cstr_casecmp(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, APLOGNO(01763)
                     "Set shmem-size: %" APR_SIZE_T_FMT ", 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, APLOGNO(01764)
                          "get_client(): client %lu found", key);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01765)
                          "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(server_rec *s)
    {
        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;
    
            if (!entry) {
                /* This bucket is empty. */
                continue;
            }
    
            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_status_t err;
    
                err = rmm_free(client_rmm, entry);
                num_removed++;
    
                if (err) {
                    /* Nothing we can really do but log... */
                    ap_log_error(APLOG_MARK, APLOG_ERR, err, s, APLOGNO(10007)
                                 "Failed to free auth_digest client allocation");
                }
            }
        }
    
        /* 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;
    
        apr_global_mutex_lock(client_lock);
    
        /* try to allocate a new entry */
    
        entry = rmm_malloc(client_rmm, sizeof(client_entry));
        if (!entry) {
            long num_removed = gc(s);
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01766)
                         "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 = rmm_malloc(client_rmm, sizeof(client_entry));
            if (!entry) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01767)
                             "unable to allocate new auth_digest client");
                apr_global_mutex_unlock(client_lock);
                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, APLOGNO(01768)
                     "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 (ap_cstr_casecmp(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 */
    
            vv = 0;
            if (auth_line[0] == '=') {
                auth_line++;
                while (apr_isspace(auth_line[0])) {
                    auth_line++;
                }
    
                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 (!ap_cstr_casecmp(key, "username"))
                resp->username = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "realm"))
                resp->realm = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "nonce"))
                resp->nonce = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "uri"))
                resp->uri = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "response"))
                resp->digest = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "algorithm"))
                resp->algorithm = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "cnonce"))
                resp->cnonce = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "opaque"))
                resp->opaque = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(key, "qop"))
                resp->message_qop = apr_pstrdup(r->pool, value);
            else if (!ap_cstr_casecmp(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)
    {
        unsigned char sha1[APR_SHA1_DIGESTSIZE];
        apr_sha1_ctx_t ctx;
    
        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);
    
        ap_bin2hex(sha1, APR_SHA1_DIGESTSIZE, hash);
    }
    
    
    /* 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);
        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;
        }
        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_unlock(opaque_lock);
    
        if (!(entry = add_client(op, &new_entry, r->server))) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01769)
                          "failed to allocate client entry - ignoring client");
            return NULL;
        }
    
        return entry;
    }
    
    
    /*
     * 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;
    
        /* Setup qop */
        if (apr_is_empty_array(conf->qop_list)) {
            qop = ", qop=\"auth\"";
        }
        else if (!ap_cstr_casecmp(*(const char **)(conf->qop_list->elts), "none")) {
            qop = "";
        }
        else {
            qop = apr_pstrcat(r->pool, ", qop=\"",
                                       apr_array_pstrcat(r->pool, conf->qop_list, ','),
                                       "\"",
                                       NULL);
        }
    
        /* Setup opaque */
    
        if (resp->opaque == NULL) {
            /* new client */
            if ((conf->check_nc || conf->nonce_lifetime == 0)
                && (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 domain attribute. We want to send this attribute wherever
         * possible so that the client won't send the Authorization header
         * unnecessarily (it's usually > 200 bytes!).
         */
    
    
        /* don't send domain
         * - for proxy requests
         * - if it's not 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));
    
    }
    
    static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type)
    {
        request_rec *mainreq;
        digest_header_rec *resp;
        digest_config_rec *conf;
    
        if (ap_cstr_casecmp(auth_type, "Digest"))
            return DECLINED;
    
        /* 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);
    
        note_digest_auth_failure(r, conf, resp, 0);
    
        return OK;
    }
    
    
    /*
     * Authorization header verification code
     */
    
    static authn_status get_hash(request_rec *r, const char *user,
                                 digest_config_rec *conf, const char **rethash)
    {
        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,
                                              AUTHN_PROVIDER_VERSION);
    
                if (!provider || !provider->get_realm_hash) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01770)
                                  "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 occurred.  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) {
            *rethash = 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) {
            /* Shouldn't happen, but just in case... */
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01771)
                          "cannot check nonce count without shared memory");
            return OK;
        }
    
        if (!conf->check_nc || !client_shm) {
            return OK;
        }
    
        if (!apr_is_empty_array(conf->qop_list) &&
            !ap_cstr_casecmp(*(const char **)(conf->qop_list->elts), "none")) {
            /* qop is none, client must not send a nonce count */
            if (snc != NULL) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01772)
                              "invalid nc %s received - no nonce count allowed when qop=none",
                              snc);
                return !OK;
            }
            /* qop is none, cannot check nonce count */
            return OK;
        }
    
        nc = strtol(snc, &endptr, 16);
        if (endptr < (snc+strlen(snc)) && !apr_isspace(*endptr)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01773)
                          "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, APLOGNO(01774)
                          "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;
        time_rec nonce_time;
        char tmp, hash[NONCE_HASH_LEN+1];
    
        /* Since the time part of the nonce is a base64 encoding of an
         * apr_time_t (8 bytes), it should end with a '=', fail early otherwise.
         */
        if (strlen(resp->nonce) != NONCE_LEN
                || resp->nonce[NONCE_TIME_LEN - 1] != '=') {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01775)
                          "invalid nonce '%s' received - length is not %d "
                          "or time encoding is incorrect",
                          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';
        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, APLOGNO(01776)
                          "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, APLOGNO(01777)
                          "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, APLOGNO(01778)
                              "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, APLOGNO(01779)
                              "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 *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, resp->ha1, ":",
                                                   resp->nonce, ":", ha2, NULL));
    }
    
    /* RFC-2617 */
    static const char *new_digest(const request_rec *r,
                                  digest_header_rec *resp)
    {
        const char *ha1, *ha2, *a2;
    
        ha1 = resp->ha1;
    
        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;
        }
    
        dst->hostinfo = src->hostinfo;
    }
    
    /* 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)) || ap_cstr_casecmp(t, "Digest")) {
            return DECLINED;
        }
    
        if (!ap_auth_name(r)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01780)
                          "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, APLOGNO(01781)
                              "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, APLOGNO(01782)
                              "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, APLOGNO(01783)
                              "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 incompatible 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, APLOGNO(01784)
                                  "applying AuthDigestEnableQueryStringHack "
                                  "to uri <%s>", resp->raw_request_uri);
    
                   d_uri.query = r_uri.query;
                }
            }
    
            if (r->method_number == M_CONNECT) {
                if (!r_uri.hostinfo || strcmp(resp->uri, r_uri.hostinfo)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01785)
                                  "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, APLOGNO(01786)
                              "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, APLOGNO(01787)
                          "received invalid opaque - got `%s'",
                          resp->opaque);
            note_digest_auth_failure(r, conf, resp, 0);
            return HTTP_UNAUTHORIZED;
        }
    
        if (!conf->realm) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02533)
                          "realm mismatch - got `%s' but no realm specified",
                          resp->realm);
            note_digest_auth_failure(r, conf, resp, 0);
            return HTTP_UNAUTHORIZED;
        }
    
        if (!resp->realm || strcmp(resp->realm, conf->realm)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01788)
                          "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
            && ap_cstr_casecmp(resp->algorithm, "MD5")) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01789)
                          "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, &resp->ha1);
    
        if (return_code == AUTH_USER_NOT_FOUND) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790)
                          "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, APLOGNO(01791)
                          "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))) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792)
                              "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;
            const char **tmp = (const char **)(conf->qop_list->elts);
            for (idx = 0; idx < conf->qop_list->nelts; idx++) {
                if (!ap_cstr_casecmp(*tmp, resp->message_qop)) {
                    match = 1;
                    break;
                }
                ++tmp;
            }
    
            if (!match
                && !(apr_is_empty_array(conf->qop_list)
                     && !ap_cstr_casecmp(resp->message_qop, "auth"))) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01793)
                              "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);
            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, APLOGNO(01794)
                              "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
     */
    
    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, *nextnonce = "";
    
        if (resp == NULL || !resp->needed_auth || conf == NULL) {
            return OK;
        }
    
        /* 2069-style entity-digest is not supported (it's too hard, and
         * there are no clients which support 2069 but not 2617). */
    
        /* 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 (!apr_is_empty_array(conf->qop_list) &&
            !ap_cstr_casecmp(*(const char **)(conf->qop_list->elts), "none")
            && resp->message_qop == NULL) {
            /* use only RFC-2069 format */
            ai = nextnonce;
        }
        else {
            const char *resp_dig, *ha1, *a2, *ha2;
    
            /* calculate rspauth attribute
             */
            ha1 = resp->ha1;
    
            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 : "",
                             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_pre_config(pre_init, NULL, NULL, APR_HOOK_MIDDLE);
        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_authn(authenticate_digest_user, NULL, NULL, APR_HOOK_MIDDLE,
                            AP_AUTH_INTERNAL_PER_CONF);
    
        ap_hook_fixups(add_auth_info, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_note_auth_failure(hook_note_digest_auth_failure, NULL, NULL,
                                  APR_HOOK_MIDDLE);
    
    }
    
    AP_DECLARE_MODULE(auth_digest) =
    {
        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 */
    };
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbd.c������������������������������������������������������������0000664�0001751�0001751�00000026177�14205766751�020001� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_log.h"
    #include "http_request.h"
    #include "apr_lib.h"
    #include "apr_dbd.h"
    #include "mod_dbd.h"
    #include "apr_strings.h"
    #include "mod_auth.h"
    #include "apr_md5.h"
    #include "apu_version.h"
    
    module AP_MODULE_DECLARE_DATA authn_dbd_module;
    
    typedef struct {
        const char *user;
        const char *realm;
    } authn_dbd_conf;
    
    /* optional function - look it up once in post_config */
    static ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL;
    static void (*authn_dbd_prepare_fn)(server_rec*, const char*, const char*) = NULL;
    static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
    #define AUTHN_CACHE_STORE(r,user,realm,data) \
        if (authn_cache_store != NULL) \
            authn_cache_store((r), "dbd", (user), (realm), (data))
    
    static void *authn_dbd_cr_conf(apr_pool_t *pool, char *dummy)
    {
        authn_dbd_conf *ret = apr_pcalloc(pool, sizeof(authn_dbd_conf));
        return ret;
    }
    
    static void *authn_dbd_merge_conf(apr_pool_t *pool, void *BASE, void *ADD)
    {
        authn_dbd_conf *add = ADD;
        authn_dbd_conf *base = BASE;
        authn_dbd_conf *ret = apr_palloc(pool, sizeof(authn_dbd_conf));
        ret->user = (add->user == NULL) ? base->user : add->user;
        ret->realm = (add->realm == NULL) ? base->realm : add->realm;
        return ret;
    }
    
    static const char *authn_dbd_prepare(cmd_parms *cmd, void *cfg, const char *query)
    {
        static unsigned int label_num = 0;
        char *label;
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return err;
    
        if (authn_dbd_prepare_fn == NULL) {
            authn_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
            if (authn_dbd_prepare_fn == NULL) {
                return "You must load mod_dbd to enable AuthDBD functions";
            }
            authn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
        }
        label = apr_psprintf(cmd->pool, "authn_dbd_%d", ++label_num);
    
        authn_dbd_prepare_fn(cmd->server, query, label);
    
        /* save the label here for our own use */
        return ap_set_string_slot(cmd, cfg, label);
    }
    
    static const command_rec authn_dbd_cmds[] =
    {
        AP_INIT_TAKE1("AuthDBDUserPWQuery", authn_dbd_prepare,
                      (void *)APR_OFFSETOF(authn_dbd_conf, user), ACCESS_CONF,
                      "Query used to fetch password for user"),
        AP_INIT_TAKE1("AuthDBDUserRealmQuery", authn_dbd_prepare,
                      (void *)APR_OFFSETOF(authn_dbd_conf, realm), ACCESS_CONF,
                      "Query used to fetch password for user+realm"),
        {NULL}
    };
    
    static authn_status authn_dbd_password(request_rec *r, const char *user,
                                           const char *password)
    {
        apr_status_t rv;
        const char *dbd_password = NULL;
        apr_dbd_prepared_t *statement;
        apr_dbd_results_t *res = NULL;
        apr_dbd_row_t *row = NULL;
        int ret;
    
        authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
                                                    &authn_dbd_module);
        ap_dbd_t *dbd = authn_dbd_acquire_fn(r);
        if (dbd == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01653)
                          "Failed to acquire database connection to look up "
                          "user '%s'", user);
            return AUTH_GENERAL_ERROR;
        }
    
        if (conf->user == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01654)
                          "No AuthDBDUserPWQuery has been specified");
            return AUTH_GENERAL_ERROR;
        }
    
        statement = apr_hash_get(dbd->prepared, conf->user, APR_HASH_KEY_STRING);
        if (statement == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01655)
                          "A prepared statement could not be found for "
                          "AuthDBDUserPWQuery with the key '%s'", conf->user);
            return AUTH_GENERAL_ERROR;
        }
        if ((ret = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
                                    statement, 0, user, NULL)) != 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01656)
                          "Query execution error looking up '%s' "
                          "in database [%s]",
                          user, apr_dbd_error(dbd->driver, dbd->handle, ret));
            return AUTH_GENERAL_ERROR;
        }
        for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
             rv != -1;
             rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
            if (rv != 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01657)
                              "Error retrieving results while looking up '%s' "
                              "in database", user);
                return AUTH_GENERAL_ERROR;
            }
            if (dbd_password == NULL) {
                /* add the rest of the columns to the environment */
                int i = 1;
                const char *name;
                for (name = apr_dbd_get_name(dbd->driver, res, i);
                     name != NULL;
                     name = apr_dbd_get_name(dbd->driver, res, i)) {
    
                    char *str = apr_pstrcat(r->pool, AUTHN_PREFIX,
                                            name,
                                            NULL);
                    int j = sizeof(AUTHN_PREFIX)-1; /* string length of "AUTHENTICATE_", excluding the trailing NIL */
                    while (str[j]) {
                        if (!apr_isalnum(str[j])) {
                            str[j] = '_';
                        }
                        else {
                            str[j] = apr_toupper(str[j]);
                        }
                        j++;
                    }
                    apr_table_set(r->subprocess_env, str,
                                  apr_dbd_get_entry(dbd->driver, row, i));
                    i++;
                }
    
                dbd_password = apr_pstrdup(r->pool,
                                           apr_dbd_get_entry(dbd->driver, row, 0));
            }
            /* we can't break out here or row won't get cleaned up */
        }
    
        if (!dbd_password) {
            return AUTH_USER_NOT_FOUND;
        }
        AUTHN_CACHE_STORE(r, user, NULL, dbd_password);
    
        rv = apr_password_validate(password, dbd_password);
    
        if (rv != APR_SUCCESS) {
            return AUTH_DENIED;
        }
    
        return AUTH_GRANTED;
    }
    
    static authn_status authn_dbd_realm(request_rec *r, const char *user,
                                        const char *realm, char **rethash)
    {
        apr_status_t rv;
        const char *dbd_hash = NULL;
        apr_dbd_prepared_t *statement;
        apr_dbd_results_t *res = NULL;
        apr_dbd_row_t *row = NULL;
        int ret;
    
        authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
                                                    &authn_dbd_module);
        ap_dbd_t *dbd = authn_dbd_acquire_fn(r);
        if (dbd == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01658)
                          "Failed to acquire database connection to look up "
                          "user '%s:%s'", user, realm);
            return AUTH_GENERAL_ERROR;
        }
        if (conf->realm == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01659)
                          "No AuthDBDUserRealmQuery has been specified");
            return AUTH_GENERAL_ERROR;
        }
        statement = apr_hash_get(dbd->prepared, conf->realm, APR_HASH_KEY_STRING);
        if (statement == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01660)
                          "A prepared statement could not be found for "
                          "AuthDBDUserRealmQuery with the key '%s'", conf->realm);
            return AUTH_GENERAL_ERROR;
        }
        if ((ret = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
                                    statement, 0, user, realm, NULL)) != 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01661)
                          "Query execution error looking up '%s:%s' "
                          "in database [%s]",
                          user, realm,
                          apr_dbd_error(dbd->driver, dbd->handle, ret));
            return AUTH_GENERAL_ERROR;
        }
        for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
             rv != -1;
             rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
            if (rv != 0) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01662)
                              "Error retrieving results while looking up '%s:%s' "
                              "in database", user, realm);
                return AUTH_GENERAL_ERROR;
            }
            if (dbd_hash == NULL) {
                /* add the rest of the columns to the environment */
                int i = 1;
                const char *name;
                for (name = apr_dbd_get_name(dbd->driver, res, i);
                     name != NULL;
                     name = apr_dbd_get_name(dbd->driver, res, i)) {
    
                    char *str = apr_pstrcat(r->pool, AUTHN_PREFIX,
                                            name,
                                            NULL);
                    int j = sizeof(AUTHN_PREFIX)-1; /* string length of "AUTHENTICATE_", excluding the trailing NIL */
                    while (str[j]) {
                        if (!apr_isalnum(str[j])) {
                            str[j] = '_';
                        }
                        else {
                            str[j] = apr_toupper(str[j]);
                        }
                        j++;
                    }
                    apr_table_set(r->subprocess_env, str,
                                  apr_dbd_get_entry(dbd->driver, row, i));
                    i++;
                }
    
                dbd_hash = apr_pstrdup(r->pool,
                                       apr_dbd_get_entry(dbd->driver, row, 0));
            }
            /* we can't break out here or row won't get cleaned up */
        }
    
        if (!dbd_hash) {
            return AUTH_USER_NOT_FOUND;
        }
        AUTHN_CACHE_STORE(r, user, realm, dbd_hash);
        *rethash = apr_pstrdup(r->pool, dbd_hash);
        return AUTH_USER_FOUND;
    }
    
    static void opt_retr(void)
    {
        authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
    }
    
    static void authn_dbd_hooks(apr_pool_t *p)
    {
        static const authn_provider authn_dbd_provider = {
            &authn_dbd_password,
            &authn_dbd_realm
        };
    
        ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "dbd",
                                  AUTHN_PROVIDER_VERSION,
                                  &authn_dbd_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(authn_dbd) =
    {
        STANDARD20_MODULE_STUFF,
        authn_dbd_cr_conf,
        authn_dbd_merge_conf,
        NULL,
        NULL,
        authn_dbd_cmds,
        authn_dbd_hooks
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_core.c�����������������������������������������������������������0000664�0001751�0001751�00000112631�13607376315�020201� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_config.h"
    #include "http_core.h"
    #include "http_log.h"
    #include "http_request.h"
    #include "http_protocol.h"
    #include "ap_provider.h"
    #include "ap_expr.h"
    
    #include "mod_auth.h"
    
    #if APR_HAVE_NETINET_IN_H
    #include <netinet/in.h>
    #endif
    
    #undef AUTHZ_EXTRA_CONFIGS
    
    typedef struct provider_alias_rec {
        char *provider_name;
        char *provider_alias;
        char *provider_args;
        const void *provider_parsed_args;
        ap_conf_vector_t *sec_auth;
        const authz_provider *provider;
    } provider_alias_rec;
    
    typedef enum {
        AUTHZ_LOGIC_AND,
        AUTHZ_LOGIC_OR,
        AUTHZ_LOGIC_OFF,
        AUTHZ_LOGIC_UNSET
    } authz_logic_op;
    
    typedef struct authz_section_conf authz_section_conf;
    
    struct authz_section_conf {
        const char *provider_name;
        const char *provider_args;
        const void *provider_parsed_args;
        const authz_provider *provider;
        apr_int64_t limited;
        authz_logic_op op;
        int negate;
        /** true if this is not a real container but produced by AuthMerging;
         *  only used for logging */
        int is_merged;
        authz_section_conf *first;
        authz_section_conf *next;
    };
    
    typedef struct authz_core_dir_conf authz_core_dir_conf;
    
    struct authz_core_dir_conf {
        authz_section_conf *section;
        authz_core_dir_conf *next;
        authz_logic_op op;
        signed char authz_forbidden_on_fail;
    };
    
    #define UNSET -1
    
    typedef struct authz_core_srv_conf {
        apr_hash_t *alias_rec;
    } authz_core_srv_conf;
    
    module AP_MODULE_DECLARE_DATA authz_core_module;
    
    static authz_core_dir_conf *authz_core_first_dir_conf;
    
    static void *create_authz_core_dir_config(apr_pool_t *p, char *dummy)
    {
        authz_core_dir_conf *conf = apr_pcalloc(p, sizeof(*conf));
    
        conf->op = AUTHZ_LOGIC_UNSET;
        conf->authz_forbidden_on_fail = UNSET;
    
        conf->next = authz_core_first_dir_conf;
        authz_core_first_dir_conf = conf;
    
        return (void *)conf;
    }
    
    static void *merge_authz_core_dir_config(apr_pool_t *p,
                                             void *basev, void *newv)
    {
        authz_core_dir_conf *base = (authz_core_dir_conf *)basev;
        authz_core_dir_conf *new = (authz_core_dir_conf *)newv;
        authz_core_dir_conf *conf;
    
        if (new->op == AUTHZ_LOGIC_UNSET && !new->section && base->section ) {
            /* Only authz_forbidden_on_fail has been set in new. Don't treat
             * it as a new auth config w.r.t. AuthMerging */
            conf = apr_pmemdup(p, base, sizeof(*base));
        }
        else if (new->op == AUTHZ_LOGIC_OFF || new->op == AUTHZ_LOGIC_UNSET ||
                 !(base->section || new->section)) {
            conf = apr_pmemdup(p, new, sizeof(*new));
        }
        else {
            authz_section_conf *section;
    
            if (base->section) {
                if (new->section) {
                    section = apr_pcalloc(p, sizeof(*section));
    
                    section->limited =
                        base->section->limited | new->section->limited;
    
                    section->op = new->op;
                    section->is_merged = 1;
    
                    section->first = apr_pmemdup(p, base->section,
                                                 sizeof(*base->section));
                    section->first->next = apr_pmemdup(p, new->section,
                                                       sizeof(*new->section));
                } else {
                    section = apr_pmemdup(p, base->section,
                                          sizeof(*base->section));
                }
            }
            else {
                section = apr_pmemdup(p, new->section, sizeof(*new->section));
            }
    
            conf = apr_pcalloc(p, sizeof(*conf));
    
            conf->section = section;
            conf->op = new->op;
        }
    
        if (new->authz_forbidden_on_fail == UNSET)
            conf->authz_forbidden_on_fail = base->authz_forbidden_on_fail;
        else
            conf->authz_forbidden_on_fail = new->authz_forbidden_on_fail;
    
        return (void*)conf;
    }
    
    /* Only per-server directive we have is GLOBAL_ONLY */
    static void *merge_authz_core_svr_config(apr_pool_t *p,
                                             void *basev, void *newv)
    {
        return basev;
    }
    
    static void *create_authz_core_svr_config(apr_pool_t *p, server_rec *s)
    {
        authz_core_srv_conf *authcfg;
    
        authcfg = apr_pcalloc(p, sizeof(*authcfg));
        authcfg->alias_rec = apr_hash_make(p);
    
        return (void *)authcfg;
    }
    
    /* This is a fake authz provider that really merges various authz alias
     * configurations and then invokes them.
     */
    static authz_status authz_alias_check_authorization(request_rec *r,
                                                        const char *require_args,
                                                        const void *parsed_require_args)
    {
        const char *provider_name;
    
        /* Look up the provider alias in the alias list.
         * Get the dir_config and call ap_merge_per_dir_configs()
         * Call the real provider->check_authorization() function
         * Return the result of the above function call
         */
    
        provider_name = apr_table_get(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
    
        if (provider_name) {
            authz_core_srv_conf *authcfg;
            provider_alias_rec *prvdraliasrec;
    
            authcfg = ap_get_module_config(r->server->module_config,
                                           &authz_core_module);
    
            prvdraliasrec = apr_hash_get(authcfg->alias_rec, provider_name,
                                         APR_HASH_KEY_STRING);
    
            /* If we found the alias provider in the list, then merge the directory
               configurations and call the real provider */
            if (prvdraliasrec) {
                ap_conf_vector_t *orig_dir_config = r->per_dir_config;
                authz_status ret;
    
                r->per_dir_config =
                    ap_merge_per_dir_configs(r->pool, orig_dir_config,
                                             prvdraliasrec->sec_auth);
    
                ret = prvdraliasrec->provider->
                    check_authorization(r, prvdraliasrec->provider_args,
                                        prvdraliasrec->provider_parsed_args);
    
                r->per_dir_config = orig_dir_config;
    
                return ret;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02305)
                      "no alias provider found for '%s' (BUG?)",
                      provider_name ? provider_name : "n/a");
    
        return AUTHZ_DENIED;
    }
    
    static const authz_provider authz_alias_provider =
    {
        &authz_alias_check_authorization,
        NULL,
    };
    
    static const char *authz_require_alias_section(cmd_parms *cmd, void *mconfig,
                                                   const char *args)
    {
        const char *endp = ap_strrchr_c(args, '>');
        char *provider_name;
        char *provider_alias;
        char *provider_args, *extra_args;
        ap_conf_vector_t *new_authz_config;
        int old_overrides = cmd->override;
        const char *errmsg;
    
        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->temp_pool, args, endp - args);
    
        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);
        provider_args = ap_getword_conf(cmd->pool, &args);
        extra_args = 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);
        }
        
        /* We only handle one "Require-Parameters" parameter.  If several parameters
           are needed, they must be enclosed between quotes */
        if (extra_args && *extra_args) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(10142)
                         "When several arguments (%s %s...) are passed to a %s directive, "
                         "they must be enclosed in quotation marks.  Otherwise, only the "
                         "first one is taken into account",
                         provider_args, extra_args, cmd->cmd->name);
        }
    
        new_authz_config = ap_create_per_dir_config(cmd->pool);
    
        /* Walk the subsection configuration to get the per_dir config that we will
         * merge just before the real provider is called.
         */
        cmd->override = OR_AUTHCFG | ACCESS_CONF;
        errmsg = ap_walk_config(cmd->directive->first_child, cmd,
                                new_authz_config);
        cmd->override = old_overrides;
    
        if (!errmsg) {
            provider_alias_rec *prvdraliasrec;
            authz_core_srv_conf *authcfg;
    
            prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(*prvdraliasrec));
    
            /* Save off the new directory config along with the original
             * provider name and function pointer data
             */
            prvdraliasrec->provider_name = provider_name;
            prvdraliasrec->provider_alias = provider_alias;
            prvdraliasrec->provider_args = provider_args;
            prvdraliasrec->sec_auth = new_authz_config;
            prvdraliasrec->provider =
                ap_lookup_provider(AUTHZ_PROVIDER_GROUP, provider_name,
                                   AUTHZ_PROVIDER_VERSION);
    
            /* by the time the config file is used, the provider should be loaded
             * and registered with us.
             */
            if (!prvdraliasrec->provider) {
                return apr_psprintf(cmd->pool,
                                    "Unknown Authz provider: %s",
                                    provider_name);
            }
            if (prvdraliasrec->provider->parse_require_line) {
                err = prvdraliasrec->provider->parse_require_line(cmd,
                             provider_args, &prvdraliasrec->provider_parsed_args);
                if (err)
                    return apr_psprintf(cmd->pool,
                                        "Can't parse 'Require %s %s': %s",
                                        provider_name, provider_args, err);
            }
    
            authcfg = ap_get_module_config(cmd->server->module_config,
                                           &authz_core_module);
    
            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_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP,
                                      provider_alias, AUTHZ_PROVIDER_VERSION,
                                      &authz_alias_provider,
                                      AP_AUTH_INTERNAL_PER_CONF);
        }
    
        return errmsg;
    }
    
    static const char* format_authz_result(authz_status result)
    {
        return ((result == AUTHZ_DENIED)
                ? "denied"
                : ((result == AUTHZ_GRANTED)
                   ? "granted"
                   : ((result == AUTHZ_DENIED_NO_USER)
                      ? "denied (no authenticated user yet)"
                      : "neutral")));
    }
    
    static const char* format_authz_command(apr_pool_t *p,
                                            authz_section_conf *section)
    {
        return (section->provider
                ? apr_pstrcat(p, "Require ", (section->negate ? "not " : ""),
                              section->provider_name, " ",
                              section->provider_args, NULL)
                : apr_pstrcat(p, section->is_merged ? "AuthMerging " : "<Require",
                              ((section->op == AUTHZ_LOGIC_AND)
                               ? (section->negate ? "NotAll" : "All")
                               : (section->negate ? "None" : "Any")),
                              section->is_merged ? "" : ">", NULL));
    }
    
    static authz_section_conf* create_default_section(apr_pool_t *p)
    {
        authz_section_conf *section = apr_pcalloc(p, sizeof(*section));
    
        section->op = AUTHZ_LOGIC_OR;
    
        return section;
    }
    
    static const char *add_authz_provider(cmd_parms *cmd, void *config,
                                          const char *args)
    {
        authz_core_dir_conf *conf = (authz_core_dir_conf*)config;
        authz_section_conf *section = apr_pcalloc(cmd->pool, sizeof(*section));
        authz_section_conf *child;
    
        section->provider_name = ap_getword_conf(cmd->pool, &args);
    
        if (!strcasecmp(section->provider_name, "not")) {
            section->provider_name = ap_getword_conf(cmd->pool, &args);
            section->negate = 1;
        }
    
        section->provider_args = args;
    
        /* lookup and cache the actual provider now */
        section->provider = ap_lookup_provider(AUTHZ_PROVIDER_GROUP,
                                               section->provider_name,
                                               AUTHZ_PROVIDER_VERSION);
    
        /* by the time the config file is used, the provider should be loaded
         * and registered with us.
         */
        if (!section->provider) {
            return apr_psprintf(cmd->pool,
                                "Unknown Authz provider: %s",
                                section->provider_name);
        }
    
        /* if the provider doesn't provide the appropriate function, reject it */
        if (!section->provider->check_authorization) {
            return apr_psprintf(cmd->pool,
                                "The '%s' Authz provider is not supported by any "
                                "of the loaded authorization modules",
                                section->provider_name);
        }
    
        section->limited = cmd->limited;
    
        if (section->provider->parse_require_line) {
            const char *err;
            apr_pool_userdata_setn(section->provider_name,
                                   AUTHZ_PROVIDER_NAME_NOTE,
                                   apr_pool_cleanup_null,
                                   cmd->temp_pool);
            err = section->provider->parse_require_line(cmd, args,
                                                  &section->provider_parsed_args);
    
            if (err)
                return err;
        }
    
        if (!conf->section) {
            conf->section = create_default_section(cmd->pool);
        }
    
        if (section->negate && conf->section->op == AUTHZ_LOGIC_OR) {
            return apr_psprintf(cmd->pool, "negative %s directive has no effect "
                                "in %s directive",
                                cmd->cmd->name,
                                format_authz_command(cmd->pool, conf->section));
        }
    
        conf->section->limited |= section->limited;
    
        child = conf->section->first;
    
        if (child) {
            while (child->next) {
                child = child->next;
            }
    
            child->next = section;
        }
        else {
            conf->section->first = section;
        }
    
        return NULL;
    }
    
    static const char *add_authz_section(cmd_parms *cmd, void *mconfig,
                                         const char *args)
    {
        authz_core_dir_conf *conf = mconfig;
        const char *endp = ap_strrchr_c(args, '>');
        authz_section_conf *old_section = conf->section;
        authz_section_conf *section;
        int old_overrides = cmd->override;
        apr_int64_t old_limited = cmd->limited;
        const char *errmsg;
    
        if (endp == NULL) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               "> directive missing closing '>'", NULL);
        }
    
        args = apr_pstrndup(cmd->temp_pool, args, endp - args);
    
        if (args[0]) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               "> directive doesn't take additional arguments",
                               NULL);
        }
    
        section = apr_pcalloc(cmd->pool, sizeof(*section));
    
        if (!strcasecmp(cmd->cmd->name, "<RequireAll")) {
            section->op = AUTHZ_LOGIC_AND;
        }
        else if (!strcasecmp(cmd->cmd->name, "<RequireAny")) {
            section->op = AUTHZ_LOGIC_OR;
        }
        else if (!strcasecmp(cmd->cmd->name, "<RequireNotAll")) {
            section->op = AUTHZ_LOGIC_AND;
            section->negate = 1;
        }
        else {
            section->op = AUTHZ_LOGIC_OR;
            section->negate = 1;
        }
    
        conf->section = section;
    
        /* trigger NOT_IN_LIMIT errors as if this were a <Limit> directive */
        cmd->limited &= ~(AP_METHOD_BIT << (METHODS - 1));
    
        cmd->override = OR_AUTHCFG;
        errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context);
        cmd->override = old_overrides;
    
        cmd->limited = old_limited;
    
        conf->section = old_section;
    
        if (errmsg) {
            return errmsg;
        }
    
        if (section->first) {
            authz_section_conf *child;
    
            if (!old_section) {
                old_section = conf->section = create_default_section(cmd->pool);
            }
    
            if (section->negate && old_section->op == AUTHZ_LOGIC_OR) {
                return apr_psprintf(cmd->pool, "%s directive has "
                                    "no effect in %s directive",
                                    format_authz_command(cmd->pool, section),
                                    format_authz_command(cmd->pool, old_section));
            }
    
            old_section->limited |= section->limited;
    
            if (!section->negate && section->op == old_section->op) {
                /* be associative */
                section = section->first;
            }
    
            child = old_section->first;
    
            if (child) {
                while (child->next) {
                    child = child->next;
                }
    
                child->next = section;
            }
            else {
                old_section->first = section;
            }
        }
        else {
            return apr_pstrcat(cmd->pool,
                               format_authz_command(cmd->pool, section),
                               " directive contains no authorization directives",
                               NULL);
        }
    
        return NULL;
    }
    
    static const char *authz_merge_sections(cmd_parms *cmd, void *mconfig,
                                            const char *arg)
    {
        authz_core_dir_conf *conf = mconfig;
    
        if (!strcasecmp(arg, "Off")) {
            conf->op = AUTHZ_LOGIC_OFF;
        }
        else if (!strcasecmp(arg, "And")) {
            conf->op = AUTHZ_LOGIC_AND;
        }
        else if (!strcasecmp(arg, "Or")) {
            conf->op = AUTHZ_LOGIC_OR;
        }
        else {
            return apr_pstrcat(cmd->pool, cmd->cmd->name, " must be one of: "
                               "Off | And | Or", NULL);
        }
    
        return NULL;
    }
    
    static int authz_core_check_section(apr_pool_t *p, server_rec *s,
                                        authz_section_conf *section, int is_conf)
    {
        authz_section_conf *prev = NULL;
        authz_section_conf *child = section->first;
        int ret = !OK;
    
        while (child) {
            if (child->first) {
                if (authz_core_check_section(p, s, child, 0) != OK) {
                    return !OK;
                }
    
                if (child->negate && child->op != section->op) {
                    authz_section_conf *next = child->next;
    
                    /* avoid one level of recursion when De Morgan permits */
                    child = child->first;
    
                    if (prev) {
                        prev->next = child;
                    }
                    else {
                        section->first = child;
                    }
    
                    do {
                        child->negate = !child->negate;
                    } while (child->next && (child = child->next));
    
                    child->next = next;
                }
            }
    
            prev = child;
            child = child->next;
        }
    
        child = section->first;
    
        while (child) {
            if (!child->negate) {
                ret = OK;
                break;
            }
    
            child = child->next;
        }
    
        if (ret != OK) {
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, APR_SUCCESS, s, APLOGNO(01624)
                         "%s directive contains only negative authorization directives",
                         is_conf ? "<Directory>, <Location>, or similar"
                                 : format_authz_command(p, section));
        }
    
        return ret;
    }
    
    static int authz_core_pre_config(apr_pool_t *p, apr_pool_t *plog,
                                     apr_pool_t *ptemp)
    {
        authz_core_first_dir_conf = NULL;
    
        return OK;
    }
    
    static int authz_core_check_config(apr_pool_t *p, apr_pool_t *plog,
                                       apr_pool_t *ptemp, server_rec *s)
    {
        authz_core_dir_conf *conf = authz_core_first_dir_conf;
    
        while (conf) {
            if (conf->section) {
                if (authz_core_check_section(p, s, conf->section, 1) != OK) {
                    return !OK;
                }
            }
    
            conf = conf->next;
        }
    
        return OK;
    }
    
    static const command_rec authz_cmds[] =
    {
        AP_INIT_RAW_ARGS("<AuthzProviderAlias", authz_require_alias_section,
                         NULL, RSRC_CONF,
                         "container for grouping an authorization provider's "
                         "directives under a provider alias"),
        AP_INIT_RAW_ARGS("Require", add_authz_provider, NULL, OR_AUTHCFG,
                         "specifies authorization directives "
                         "which one must pass (or not) for a request to suceeed"),
        AP_INIT_RAW_ARGS("<RequireAll", add_authz_section, NULL, OR_AUTHCFG,
                         "container for grouping authorization directives "
                         "of which none must fail and at least one must pass "
                         "for a request to succeed"),
        AP_INIT_RAW_ARGS("<RequireAny", add_authz_section, NULL, OR_AUTHCFG,
                         "container for grouping authorization directives "
                         "of which one must pass "
                         "for a request to succeed"),
    #ifdef AUTHZ_EXTRA_CONFIGS
        AP_INIT_RAW_ARGS("<RequireNotAll", add_authz_section, NULL, OR_AUTHCFG,
                         "container for grouping authorization directives "
                         "of which some must fail or none must pass "
                         "for a request to succeed"),
    #endif
        AP_INIT_RAW_ARGS("<RequireNone", add_authz_section, NULL, OR_AUTHCFG,
                         "container for grouping authorization directives "
                         "of which none must pass "
                         "for a request to succeed"),
        AP_INIT_TAKE1("AuthMerging", authz_merge_sections, NULL, OR_AUTHCFG,
                      "controls how a <Directory>, <Location>, or similar "
                      "directive's authorization directives are combined with "
                      "those of its predecessor"),
        AP_INIT_FLAG("AuthzSendForbiddenOnFailure", ap_set_flag_slot_char,
                     (void *)APR_OFFSETOF(authz_core_dir_conf, authz_forbidden_on_fail),
                     OR_AUTHCFG,
                     "Controls if an authorization failure should result in a "
                     "'403 FORBIDDEN' response instead of the HTTP-conforming "
                     "'401 UNAUTHORIZED'"),
        {NULL}
    };
    
    static authz_status apply_authz_sections(request_rec *r,
                                             authz_section_conf *section,
                                             authz_logic_op parent_op)
    {
        authz_status auth_result;
    
        /* check to make sure that the request method requires authorization */
        if (!(section->limited & (AP_METHOD_BIT << r->method_number))) {
            auth_result =
                (parent_op == AUTHZ_LOGIC_AND) ? AUTHZ_GRANTED : AUTHZ_NEUTRAL;
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01625)
                          "authorization result of %s: %s "
                          "(directive limited to other methods)",
                          format_authz_command(r->pool, section),
                          format_authz_result(auth_result));
    
            return auth_result;
        }
    
        if (section->provider) {
            apr_table_setn(r->notes, AUTHZ_PROVIDER_NAME_NOTE,
                           section->provider_name);
    
            auth_result =
                section->provider->check_authorization(r, section->provider_args,
                                                       section->provider_parsed_args);
    
            apr_table_unset(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
        }
        else {
            authz_section_conf *child = section->first;
    
            auth_result = AUTHZ_NEUTRAL;
    
            while (child) {
                authz_status child_result;
    
                child_result = apply_authz_sections(r, child, section->op);
    
                if (child_result == AUTHZ_GENERAL_ERROR) {
                    return AUTHZ_GENERAL_ERROR;
                }
    
                if (child_result != AUTHZ_NEUTRAL) {
                    /*
                     * Handling of AUTHZ_DENIED/AUTHZ_DENIED_NO_USER: Return
                     * AUTHZ_DENIED_NO_USER if providing a user may change the
                     * result, AUTHZ_DENIED otherwise.
                     */
                    if (section->op == AUTHZ_LOGIC_AND) {
                        if (child_result == AUTHZ_DENIED) {
                            auth_result = child_result;
                            break;
                        }
                        if ((child_result == AUTHZ_DENIED_NO_USER
                             && auth_result != AUTHZ_DENIED)
                            || (auth_result == AUTHZ_NEUTRAL)) {
                            auth_result = child_result;
                        }
                    }
                    else {
                        /* AUTHZ_LOGIC_OR */
                        if (child_result == AUTHZ_GRANTED) {
                            auth_result = child_result;
                            break;
                        }
                        if ((child_result == AUTHZ_DENIED_NO_USER
                             && auth_result == AUTHZ_DENIED)
                            || (auth_result == AUTHZ_NEUTRAL)) {
                            auth_result = child_result;
                        }
                    }
                }
    
                child = child->next;
            }
        }
    
        if (section->negate) {
            if (auth_result == AUTHZ_GRANTED) {
                auth_result = AUTHZ_DENIED;
            }
            else if (auth_result == AUTHZ_DENIED ||
                     auth_result == AUTHZ_DENIED_NO_USER) {
                /* For negated directives, if the original result was denied
                 * then the new result is neutral since we can not grant
                 * access simply because authorization was not rejected.
                 */
                auth_result = AUTHZ_NEUTRAL;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01626)
                      "authorization result of %s: %s",
                      format_authz_command(r->pool, section),
                      format_authz_result(auth_result));
    
        return auth_result;
    }
    
    static int authorize_user_core(request_rec *r, int after_authn)
    {
        authz_core_dir_conf *conf;
        authz_status auth_result;
    
        conf = ap_get_module_config(r->per_dir_config, &authz_core_module);
    
        if (!conf->section) {
            if (ap_auth_type(r)) {
                /* there's an AuthType configured, but no authorization
                 * directives applied to support it
                 */
    
                ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01627)
                              "AuthType configured with no corresponding "
                              "authorization directives");
    
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01628)
                          "authorization result: granted (no directives)");
    
            return OK;
        }
    
        auth_result = apply_authz_sections(r, conf->section, AUTHZ_LOGIC_AND);
    
        if (auth_result == AUTHZ_GRANTED) {
            return OK;
        }
        else if (auth_result == AUTHZ_DENIED_NO_USER) {
            if (after_authn) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01629)
                              "authorization failure (no authenticated user): %s",
                              r->uri);
                /*
                 * If we're returning 401 to an authenticated user, tell them to
                 * try again. If unauthenticated, note_auth_failure has already
                 * been called during auth.
                 */
                if (r->user)
                    ap_note_auth_failure(r);
    
                return HTTP_UNAUTHORIZED;
            }
            else {
                /*
                 * We need a user before we can decide what to do.
                 * Get out of the way and proceed with authentication.
                 */
                return DECLINED;
            }
        }
        else if (auth_result == AUTHZ_DENIED || auth_result == AUTHZ_NEUTRAL) {
            if (!after_authn || ap_auth_type(r) == NULL) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01630)
                              "client denied by server configuration: %s%s",
                              r->filename ? "" : "uri ",
                              r->filename ? r->filename : r->uri);
    
                return HTTP_FORBIDDEN;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01631)
                              "user %s: authorization failure for \"%s\": ",
                              r->user, r->uri);
    
                if (conf->authz_forbidden_on_fail > 0) {
                    return HTTP_FORBIDDEN;
                }
                else {
                    /*
                     * If we're returning 401 to an authenticated user, tell them to
                     * try again. If unauthenticated, note_auth_failure has already
                     * been called during auth.
                     */
                    if (r->user)
                        ap_note_auth_failure(r);
                    return HTTP_UNAUTHORIZED;
                }
            }
        }
        else {
            /* We'll assume that the module has already said what its
             * error was in the logs.
             */
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }
    
    static int authorize_userless(request_rec *r)
    {
        return authorize_user_core(r, 0);
    }
    
    static int authorize_user(request_rec *r)
    {
        return authorize_user_core(r, 1);
    }
    
    static int authz_some_auth_required(request_rec *r)
    {
        authz_core_dir_conf *conf;
    
        conf = ap_get_module_config(r->per_dir_config, &authz_core_module);
    
        if (conf->section
            && (conf->section->limited & (AP_METHOD_BIT << r->method_number))) {
            return 1;
        }
    
        return 0;
    }
    
    /*
     * env authz provider
     */
    
    static authz_status env_check_authorization(request_rec *r,
                                                const char *require_line,
                                                const void *parsed_require_line)
    {
        const char *t, *w;
    
        /* The 'env' provider will allow the configuration to specify a list of
            env variables to check rather than a single variable.  This is different
            from the previous host based syntax. */
        t = require_line;
        while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
            if (apr_table_get(r->subprocess_env, w)) {
                return AUTHZ_GRANTED;
            }
        }
    
        return AUTHZ_DENIED;
    }
    
    static const authz_provider authz_env_provider =
    {
        &env_check_authorization,
        NULL,
    };
    
    
    /*
     * all authz provider
     */
    
    static authz_status all_check_authorization(request_rec *r,
                                                const char *require_line,
                                                const void *parsed_require_line)
    {
        if (parsed_require_line) {
            return AUTHZ_GRANTED;
        }
        return AUTHZ_DENIED;
    }
    
    static const char *all_parse_config(cmd_parms *cmd, const char *require_line,
                                        const void **parsed_require_line)
    {
        /*
         * If the argument to the 'all' provider is 'granted' then just let
         * everybody in. This would be equivalent to the previous syntax of
         * 'allow from all'. If the argument is 'denied' we reject everybody,
         * which is equivalent to 'deny from all'.
         */
        if (strcasecmp(require_line, "granted") == 0) {
            *parsed_require_line = (void *)1;
            return NULL;
        }
        else if (strcasecmp(require_line, "denied") == 0) {
            /* *parsed_require_line is already NULL */
            return NULL;
        }
        else {
            return "Argument for 'Require all' must be 'granted' or 'denied'";
        }
    }
    
    static const authz_provider authz_all_provider =
    {
        &all_check_authorization,
        &all_parse_config,
    };
    
    
    /*
     * method authz provider
     */
    
    static authz_status method_check_authorization(request_rec *r,
                                                   const char *require_line,
                                                   const void *parsed_require_line)
    {
        const apr_int64_t *allowed = parsed_require_line;
        if (*allowed & (AP_METHOD_BIT << r->method_number))
            return AUTHZ_GRANTED;
        else
            return AUTHZ_DENIED;
    }
    
    static const char *method_parse_config(cmd_parms *cmd, const char *require_line,
                                           const void **parsed_require_line)
    {
        const char *w, *t;
        apr_int64_t *allowed = apr_pcalloc(cmd->pool, sizeof(apr_int64_t));
    
        t = require_line;
    
        while ((w = ap_getword_conf(cmd->temp_pool, &t)) && w[0]) {
            int m = ap_method_number_of(w);
            if (m == M_INVALID) {
                return apr_pstrcat(cmd->pool, "Invalid Method '", w, "'", NULL);
            }
    
            *allowed |= (AP_METHOD_BIT << m);
        }
    
        *parsed_require_line = allowed;
        return NULL;
    }
    
    static const authz_provider authz_method_provider =
    {
        &method_check_authorization,
        &method_parse_config,
    };
    
    /*
     * expr authz provider
     */
    
    #define REQUIRE_EXPR_NOTE "Require_expr_info"
    struct require_expr_info {
        ap_expr_info_t *expr;
        int want_user;
    };
    
    static int expr_lookup_fn(ap_expr_lookup_parms *parms)
    {
        if (parms->type == AP_EXPR_FUNC_VAR
            && strcasecmp(parms->name, "REMOTE_USER") == 0) {
            struct require_expr_info *info;
            apr_pool_userdata_get((void**)&info, REQUIRE_EXPR_NOTE, parms->ptemp);
            AP_DEBUG_ASSERT(info != NULL);
            info->want_user = 1;
        }
        return ap_expr_lookup_default(parms);
    }
    
    static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
                                         const void **parsed_require_line)
    {
        const char *expr_err = NULL;
        struct require_expr_info *info = apr_pcalloc(cmd->pool, sizeof(*info));
    
        /* if the expression happens to be surrounded by quotes, skip them */
        if (require_line[0] == '"') {
            apr_size_t len = strlen(require_line);
    
            if (require_line[len-1] == '"')
                require_line = apr_pstrndup(cmd->temp_pool,
                                            require_line + 1,
                                            len - 2);
        }
    
        apr_pool_userdata_setn(info, REQUIRE_EXPR_NOTE, apr_pool_cleanup_null,
                              cmd->temp_pool);
        info->expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
                                       expr_lookup_fn);
    
        if (expr_err)
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression in require line: ",
                               expr_err, NULL);
    
        *parsed_require_line = info;
    
        return NULL;
    }
    
    static authz_status expr_check_authorization(request_rec *r,
                                                 const char *require_line,
                                                 const void *parsed_require_line)
    {
        const char *err = NULL;
        const struct require_expr_info *info = parsed_require_line;
        int rc = ap_expr_exec(r, info->expr, &err);
    
        if (rc < 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02320)
                          "Error evaluating expression in 'Require expr': %s",
                          err);
            return AUTHZ_GENERAL_ERROR;
        }
        else if (rc == 0) {
            if (info->want_user)
                return AUTHZ_DENIED_NO_USER;
            else
                return AUTHZ_DENIED;
        }
        else {
            return AUTHZ_GRANTED;
        }
    }
    
    static const authz_provider authz_expr_provider =
    {
        &expr_check_authorization,
        &expr_parse_config,
    };
    
    
    static void register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(authz_some_auth_required);
    
        ap_hook_pre_config(authz_core_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_config(authz_core_check_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_authz(authorize_user, NULL, NULL, APR_HOOK_LAST,
                            AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_check_access_ex(authorize_userless, NULL, NULL, APR_HOOK_LAST,
                                AP_AUTH_INTERNAL_PER_CONF);
    
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "env",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_env_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "all",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_all_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "method",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_method_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "expr",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_expr_provider, AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(authz_core) =
    {
        STANDARD20_MODULE_STUFF,
        create_authz_core_dir_config,   /* dir config creater */
        merge_authz_core_dir_config,    /* dir merger */
        create_authz_core_svr_config,   /* server config */
        merge_authz_core_svr_config ,   /* merge server config */
        authz_cmds,
        register_hooks                  /* register hooks */
    };
    
    �������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_owner.dsp��������������������������������������������������������0000664�0001751�0001751�00000011103�10663420702�020724� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_authz_owner" - 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_owner - 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_owner.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_owner.mak" CFG="mod_authz_owner - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authz_owner - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authz_owner - 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_owner - 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_owner_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 /fo"Release/mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authz_owner.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_authz_owner - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_owner_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 /fo"Debug/mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache"
    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 /out:".\Debug\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authz_owner.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_authz_owner - Win32 Release"
    # Name "mod_authz_owner - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_authz_owner.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_socache.dsp������������������������������������������������������0000664�0001751�0001751�00000011177�12062614564�021204� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_authn_socache" - 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_socache - 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_socache.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_socache.mak" CFG="mod_authn_socache - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authn_socache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authn_socache - 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_socache - 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_socache_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 /fo"Release/mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authn_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_authn_socache - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_socache_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 /fo"Debug/mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache"
    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 /out:".\Debug\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authn_socache.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_authn_socache - Win32 Release"
    # Name "mod_authn_socache - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_authn_socache.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_core.dsp���������������������������������������������������������0000664�0001751�0001751�00000011045�12062614564�020535� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_authz_core" - 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_core - 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_core.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_core.mak" CFG="mod_authz_core - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authz_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authz_core - 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_core - 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_core_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 /fo"Release/mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authz_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_authz_core - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_core_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 /fo"Debug/mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache"
    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 /out:".\Debug\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authz_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_authz_core - Win32 Release"
    # Name "mod_authz_core - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_authz_core.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUmakefile��������������������������������������������������������������0000664�0001751�0001751�00000011251�11653043670�017340� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    #
    ifeq "$(wildcard $(APRUTIL)/include/apr_ldap.h)" "$(APRUTIL)/include/apr_ldap.h"
    WITH_LDAP = $(shell $(AWK) '/^\#define APR_HAS_LDAP /{print $$3}' $(APRUTIL)/include/apr_ldap.h)
    else
    WITH_LDAP = 0
    endif
    
    #
    # 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)/authform.nlm \
    	$(OBJDIR)/authnano.nlm \
    	$(OBJDIR)/authndbd.nlm \
    	$(OBJDIR)/authndbm.nlm \
    	$(OBJDIR)/authnfil.nlm \
    	$(OBJDIR)/authnsocache.nlm \
    	$(OBJDIR)/authzdbd.nlm \
    	$(OBJDIR)/authzdbm.nlm \
    	$(OBJDIR)/authzgrp.nlm \
    	$(OBJDIR)/authzusr.nlm \
    	$(OBJDIR)/allowmethods.nlm \
    	$(OBJDIR)/accesscompat.nlm \
    	$(EOLIST)
    
    # If WITH_LDAP and LDAPSDK have been defined then build the authnz_ldap module
    ifeq "$(WITH_LDAP)" "1"
    ifneq "$(LDAPSDK)" ""
    TARGET_nlm += $(OBJDIR)/authnzldap.nlm
    endif
    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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbd.mak����������������������������������������������������������0000664�0001751�0001751�00000027511�12701473373�020326� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_dbd.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authz_dbd - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authz_dbd - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authz_dbd - Win32 Release" && "$(CFG)" != "mod_authz_dbd - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_dbd.mak" CFG="mod_authz_dbd - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authz_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authz_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbd - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dbd - Win32 Release" "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" "mod_dbd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_dbd.obj"
    	-@erase "$(INTDIR)\mod_authz_dbd.res"
    	-@erase "$(INTDIR)\mod_authz_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_authz_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbd.exp"
    	-@erase "$(OUTDIR)\mod_authz_dbd.lib"
    	-@erase "$(OUTDIR)\mod_authz_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbd_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbd.so" /implib:"$(OUTDIR)\mod_authz_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_dbd.obj" \
    	"$(INTDIR)\mod_authz_dbd.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib" \
    	"..\database\Release\mod_dbd.lib"
    
    "$(OUTDIR)\mod_authz_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authz_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbd.so"
       if exist .\Release\mod_authz_dbd.so.manifest mt.exe -manifest .\Release\mod_authz_dbd.so.manifest -outputresource:.\Release\mod_authz_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dbd - Win32 Debug" "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" "mod_dbd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_dbd.obj"
    	-@erase "$(INTDIR)\mod_authz_dbd.res"
    	-@erase "$(INTDIR)\mod_authz_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_authz_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbd.exp"
    	-@erase "$(OUTDIR)\mod_authz_dbd.lib"
    	-@erase "$(OUTDIR)\mod_authz_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_authz_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbd_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbd.so" /implib:"$(OUTDIR)\mod_authz_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_dbd.obj" \
    	"$(INTDIR)\mod_authz_dbd.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib" \
    	"..\database\Debug\mod_dbd.lib"
    
    "$(OUTDIR)\mod_authz_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authz_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbd.so"
       if exist .\Debug\mod_authz_dbd.so.manifest mt.exe -manifest .\Debug\mod_authz_dbd.so.manifest -outputresource:.\Debug\mod_authz_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authz_dbd.dep")
    !INCLUDE "mod_authz_dbd.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authz_dbd.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authz_dbd - Win32 Release" || "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authz_dbd - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbd - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbd - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbd - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_dbd - Win32 Release"
    
    "mod_dbd - Win32 Release" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" 
       cd "..\aaa"
    
    "mod_dbd - Win32 ReleaseCLEAN" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" RECURSE=1 CLEAN 
       cd "..\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    "mod_dbd - Win32 Debug" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" 
       cd "..\aaa"
    
    "mod_dbd - Win32 DebugCLEAN" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authz_dbd - Win32 Release"
    
    
    "$(INTDIR)\mod_authz_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - Win32 Debug"
    
    
    "$(INTDIR)\mod_authz_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authz_dbd.c
    
    "$(INTDIR)\mod_authz_dbd.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_owner.mak��������������������������������������������������������0000664�0001751�0001751�00000026040�12701473373�020723� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_owner.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authz_owner - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authz_owner - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authz_owner - Win32 Release" && "$(CFG)" != "mod_authz_owner - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_owner.mak" CFG="mod_authz_owner - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authz_owner - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authz_owner - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_owner - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_owner.obj"
    	-@erase "$(INTDIR)\mod_authz_owner.res"
    	-@erase "$(INTDIR)\mod_authz_owner_src.idb"
    	-@erase "$(INTDIR)\mod_authz_owner_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_owner.exp"
    	-@erase "$(OUTDIR)\mod_authz_owner.lib"
    	-@erase "$(OUTDIR)\mod_authz_owner.pdb"
    	-@erase "$(OUTDIR)\mod_authz_owner.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_owner_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_owner.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_owner.pdb" /debug /out:"$(OUTDIR)\mod_authz_owner.so" /implib:"$(OUTDIR)\mod_authz_owner.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_owner.obj" \
    	"$(INTDIR)\mod_authz_owner.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_owner.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authz_owner.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_owner.so"
       if exist .\Release\mod_authz_owner.so.manifest mt.exe -manifest .\Release\mod_authz_owner.so.manifest -outputresource:.\Release\mod_authz_owner.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authz_owner - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_owner.obj"
    	-@erase "$(INTDIR)\mod_authz_owner.res"
    	-@erase "$(INTDIR)\mod_authz_owner_src.idb"
    	-@erase "$(INTDIR)\mod_authz_owner_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_owner.exp"
    	-@erase "$(OUTDIR)\mod_authz_owner.lib"
    	-@erase "$(OUTDIR)\mod_authz_owner.pdb"
    	-@erase "$(OUTDIR)\mod_authz_owner.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_owner_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_owner.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_owner.pdb" /debug /out:"$(OUTDIR)\mod_authz_owner.so" /implib:"$(OUTDIR)\mod_authz_owner.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_owner.obj" \
    	"$(INTDIR)\mod_authz_owner.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_owner.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authz_owner.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_owner.so"
       if exist .\Debug\mod_authz_owner.so.manifest mt.exe -manifest .\Debug\mod_authz_owner.so.manifest -outputresource:.\Debug\mod_authz_owner.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authz_owner.dep")
    !INCLUDE "mod_authz_owner.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authz_owner.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authz_owner - Win32 Release" || "$(CFG)" == "mod_authz_owner - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authz_owner - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_owner - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_owner - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_owner - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_owner - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_owner - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_owner - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authz_owner - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authz_owner - Win32 Release"
    
    
    "$(INTDIR)\mod_authz_owner.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authz_owner - Win32 Debug"
    
    
    "$(INTDIR)\mod_authz_owner.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authz_owner.c
    
    "$(INTDIR)\mod_authz_owner.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_basic.dep���������������������������������������������������������0000664�0001751�0001751�00000004377�12674411515�020470� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_auth_basic.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_auth_basic.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_md5.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbd.mak����������������������������������������������������������0000664�0001751�0001751�00000027471�12701473373�020317� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_dbd.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authn_dbd - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authn_dbd - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authn_dbd - Win32 Release" && "$(CFG)" != "mod_authn_dbd - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_dbd.mak" CFG="mod_authn_dbd - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authn_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authn_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbd - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dbd - Win32 Release" "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" "mod_dbd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_dbd.obj"
    	-@erase "$(INTDIR)\mod_authn_dbd.res"
    	-@erase "$(INTDIR)\mod_authn_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_authn_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbd.exp"
    	-@erase "$(OUTDIR)\mod_authn_dbd.lib"
    	-@erase "$(OUTDIR)\mod_authn_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "DBD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbd_src" /FD /I ../database /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbd.so" /implib:"$(OUTDIR)\mod_authn_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_dbd.obj" \
    	"$(INTDIR)\mod_authn_dbd.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib" \
    	"..\database\Release\mod_dbd.lib"
    
    "$(OUTDIR)\mod_authn_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authn_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbd.so"
       if exist .\Release\mod_authn_dbd.so.manifest mt.exe -manifest .\Release\mod_authn_dbd.so.manifest -outputresource:.\Release\mod_authn_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_dbd - Win32 Debug" "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" "mod_dbd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_dbd.obj"
    	-@erase "$(INTDIR)\mod_authn_dbd.res"
    	-@erase "$(INTDIR)\mod_authn_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_authn_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbd.exp"
    	-@erase "$(OUTDIR)\mod_authn_dbd.lib"
    	-@erase "$(OUTDIR)\mod_authn_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "DBD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbd_src" /FD /EHsc /I ../database /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbd.so" /implib:"$(OUTDIR)\mod_authn_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_dbd.obj" \
    	"$(INTDIR)\mod_authn_dbd.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib" \
    	"..\database\Debug\mod_dbd.lib"
    
    "$(OUTDIR)\mod_authn_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authn_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbd.so"
       if exist .\Debug\mod_authn_dbd.so.manifest mt.exe -manifest .\Debug\mod_authn_dbd.so.manifest -outputresource:.\Debug\mod_authn_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authn_dbd.dep")
    !INCLUDE "mod_authn_dbd.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authn_dbd.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authn_dbd - Win32 Release" || "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authn_dbd - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbd - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbd - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbd - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbd - Win32 Release"
    
    "mod_dbd - Win32 Release" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" 
       cd "..\aaa"
    
    "mod_dbd - Win32 ReleaseCLEAN" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" RECURSE=1 CLEAN 
       cd "..\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    "mod_dbd - Win32 Debug" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" 
       cd "..\aaa"
    
    "mod_dbd - Win32 DebugCLEAN" : 
       cd ".\..\database"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authn_dbd - Win32 Release"
    
    
    "$(INTDIR)\mod_authn_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - Win32 Debug"
    
    
    "$(INTDIR)\mod_authn_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authn_dbd.c
    
    "$(INTDIR)\mod_authn_dbd.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_fcgi.mak��������������������������������������������������������0000664�0001751�0001751�00000024327�12701473373�020665� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authnz_fcgi.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authnz_fcgi - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authnz_fcgi - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authnz_fcgi - Win32 Release" && "$(CFG)" != "mod_authnz_fcgi - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_fcgi.mak" CFG="mod_authnz_fcgi - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authnz_fcgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authnz_fcgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authnz_fcgi.obj"
    	-@erase "$(INTDIR)\mod_authnz_fcgi.res"
    	-@erase "$(INTDIR)\mod_authnz_fcgi_src.idb"
    	-@erase "$(INTDIR)\mod_authnz_fcgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.exp"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.lib"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_fcgi_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_fcgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_fcgi.pdb" /debug /out:"$(OUTDIR)\mod_authnz_fcgi.so" /implib:"$(OUTDIR)\mod_authnz_fcgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authnz_fcgi.obj" \
    	"$(INTDIR)\mod_authnz_fcgi.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_authnz_fcgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authnz_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_fcgi.so"
       if exist .\Release\mod_authnz_fcgi.so.manifest mt.exe -manifest .\Release\mod_authnz_fcgi.so.manifest -outputresource:.\Release\mod_authnz_fcgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authnz_fcgi.obj"
    	-@erase "$(INTDIR)\mod_authnz_fcgi.res"
    	-@erase "$(INTDIR)\mod_authnz_fcgi_src.idb"
    	-@erase "$(INTDIR)\mod_authnz_fcgi_src.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.exp"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.lib"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_fcgi.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_fcgi_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_fcgi.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_fcgi.pdb" /debug /out:"$(OUTDIR)\mod_authnz_fcgi.so" /implib:"$(OUTDIR)\mod_authnz_fcgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authnz_fcgi.obj" \
    	"$(INTDIR)\mod_authnz_fcgi.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_authnz_fcgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authnz_fcgi.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_fcgi.so"
       if exist .\Debug\mod_authnz_fcgi.so.manifest mt.exe -manifest .\Debug\mod_authnz_fcgi.so.manifest -outputresource:.\Debug\mod_authnz_fcgi.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authnz_fcgi.dep")
    !INCLUDE "mod_authnz_fcgi.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authnz_fcgi.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release" || "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
    
    
    "$(INTDIR)\mod_authnz_fcgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
    
    
    "$(INTDIR)\mod_authnz_fcgi.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authnz_fcgi.c
    
    "$(INTDIR)\mod_authnz_fcgi.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthnfil��������������������������������������������������������������0000664�0001751�0001751�00000010171�11540546347�017401� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_core.mak���������������������������������������������������������0000664�0001751�0001751�00000025706�12701473373�020531� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_core.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authz_core - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authz_core - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authz_core - Win32 Release" && "$(CFG)" != "mod_authz_core - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_core.mak" CFG="mod_authz_core - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authz_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authz_core - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_core - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_core.obj"
    	-@erase "$(INTDIR)\mod_authz_core.res"
    	-@erase "$(INTDIR)\mod_authz_core_src.idb"
    	-@erase "$(INTDIR)\mod_authz_core_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_core.exp"
    	-@erase "$(OUTDIR)\mod_authz_core.lib"
    	-@erase "$(OUTDIR)\mod_authz_core.pdb"
    	-@erase "$(OUTDIR)\mod_authz_core.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_core_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_core.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_core.pdb" /debug /out:"$(OUTDIR)\mod_authz_core.so" /implib:"$(OUTDIR)\mod_authz_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_core.obj" \
    	"$(INTDIR)\mod_authz_core.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authz_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_core.so"
       if exist .\Release\mod_authz_core.so.manifest mt.exe -manifest .\Release\mod_authz_core.so.manifest -outputresource:.\Release\mod_authz_core.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authz_core - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_core.obj"
    	-@erase "$(INTDIR)\mod_authz_core.res"
    	-@erase "$(INTDIR)\mod_authz_core_src.idb"
    	-@erase "$(INTDIR)\mod_authz_core_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_core.exp"
    	-@erase "$(OUTDIR)\mod_authz_core.lib"
    	-@erase "$(OUTDIR)\mod_authz_core.pdb"
    	-@erase "$(OUTDIR)\mod_authz_core.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_core_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_core.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_core.pdb" /debug /out:"$(OUTDIR)\mod_authz_core.so" /implib:"$(OUTDIR)\mod_authz_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_core.obj" \
    	"$(INTDIR)\mod_authz_core.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authz_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_core.so"
       if exist .\Debug\mod_authz_core.so.manifest mt.exe -manifest .\Debug\mod_authz_core.so.manifest -outputresource:.\Debug\mod_authz_core.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authz_core.dep")
    !INCLUDE "mod_authz_core.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authz_core.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authz_core - Win32 Release" || "$(CFG)" == "mod_authz_core - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authz_core - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_core - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_core - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_core - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_core - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_core - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_core - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authz_core - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authz_core - Win32 Release"
    
    
    "$(INTDIR)\mod_authz_core.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authz_core - Win32 Debug"
    
    
    "$(INTDIR)\mod_authz_core.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authz_core.c
    
    "$(INTDIR)\mod_authz_core.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������httpd-2.4.64/modules/aaa/mod_allowmethods.dep�������������������������������������������������������0000664�0001751�0001751�00000003771�12674411515�021065� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_allowmethods.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_allowmethods.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �������httpd-2.4.64/modules/aaa/NWGNUaccesscompat����������������������������������������������������������0000664�0001751�0001751�00000010225�11540546347�020234� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= accesscompat
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) host access control compatibility Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= AccessCompModule
    
    #
    # 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	=
    
    #
    # 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)/accesscompat.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_access_compat.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	access_compat_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_user.mak���������������������������������������������������������0000664�0001751�0001751�00000025706�12701473373�020557� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_user.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authz_user - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authz_user - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authz_user - Win32 Release" && "$(CFG)" != "mod_authz_user - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_user - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_user.obj"
    	-@erase "$(INTDIR)\mod_authz_user.res"
    	-@erase "$(INTDIR)\mod_authz_user_src.idb"
    	-@erase "$(INTDIR)\mod_authz_user_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_user.exp"
    	-@erase "$(OUTDIR)\mod_authz_user.lib"
    	-@erase "$(OUTDIR)\mod_authz_user.pdb"
    	-@erase "$(OUTDIR)\mod_authz_user.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_user_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_user.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_user.pdb" /debug /out:"$(OUTDIR)\mod_authz_user.so" /implib:"$(OUTDIR)\mod_authz_user.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_user.obj" \
    	"$(INTDIR)\mod_authz_user.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_user.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authz_user.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_user.so"
       if exist .\Release\mod_authz_user.so.manifest mt.exe -manifest .\Release\mod_authz_user.so.manifest -outputresource:.\Release\mod_authz_user.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authz_user - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_user.obj"
    	-@erase "$(INTDIR)\mod_authz_user.res"
    	-@erase "$(INTDIR)\mod_authz_user_src.idb"
    	-@erase "$(INTDIR)\mod_authz_user_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_user.exp"
    	-@erase "$(OUTDIR)\mod_authz_user.lib"
    	-@erase "$(OUTDIR)\mod_authz_user.pdb"
    	-@erase "$(OUTDIR)\mod_authz_user.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_user_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_user.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_user.pdb" /debug /out:"$(OUTDIR)\mod_authz_user.so" /implib:"$(OUTDIR)\mod_authz_user.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_user.obj" \
    	"$(INTDIR)\mod_authz_user.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_user.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authz_user.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_user.so"
       if exist .\Debug\mod_authz_user.so.manifest mt.exe -manifest .\Debug\mod_authz_user.so.manifest -outputresource:.\Debug\mod_authz_user.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authz_user.dep")
    !INCLUDE "mod_authz_user.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authz_user.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authz_user - Win32 Release" || "$(CFG)" == "mod_authz_user - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authz_user - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_user - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_user - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_user - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_user - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_user - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_user - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authz_user - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authz_user - Win32 Release"
    
    
    "$(INTDIR)\mod_authz_user.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authz_user - Win32 Debug"
    
    
    "$(INTDIR)\mod_authz_user.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authz_user.c
    
    "$(INTDIR)\mod_authz_user.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthzdbd��������������������������������������������������������������0000664�0001751�0001751�00000010225�11540546347�017374� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(NWOS) \
    			$(STDMOD)/database \
    			$(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	= authzdbd
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) DBD Database Authorization Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= AuthzDBD 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	=
    
    #
    # 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)/authzdbd.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_dbd.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	authz_dbd_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_host.dsp���������������������������������������������������������0000664�0001751�0001751�00000011045�10551346420�020554� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authz_host.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache"
    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 /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 /out:".\Debug\mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authz_host.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_fcgi.dep��������������������������������������������������������0000664�0001751�0001751�00000004231�12674411515�020654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authnz_fcgi.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authnz_fcgi.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_fcgi.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbm.dep����������������������������������������������������������0000664�0001751�0001751�00000004316�12674411515�020334� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authz_dbm.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authz_dbm.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbm.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_authz_owner.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_user.dep���������������������������������������������������������0000664�0001751�0001751�00000004062�12674411515�020546� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_authz_user.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_authz_user.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_owner.h����������������������������������������������������������0000664�0001751�0001751�00000002201�12553146475�020400� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_AUTHZ_OWNER_H
    #define MOD_AUTHZ_OWNER_H
    
    #include "http_request.h"
    
    /* mod_authz_owner exports an optional function which retrieves the
     * group name of the file identified by r->filename, if available, or
     * else returns NULL. */
    APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r));
    
    #endif /* MOD_AUTHZ_OWNER_H */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_access_compat.mak������������������������������������������������������0000664�0001751�0001751�00000024525�12701473373�021170� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_access_compat.dsp
    !IF "$(CFG)" == ""
    CFG=mod_access_compat - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_access_compat - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_access_compat - Win32 Release" && "$(CFG)" != "mod_access_compat - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_access_compat.mak" CFG="mod_access_compat - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_access_compat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_access_compat - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_access_compat - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_access_compat.obj"
    	-@erase "$(INTDIR)\mod_access_compat.res"
    	-@erase "$(INTDIR)\mod_access_compat_src.idb"
    	-@erase "$(INTDIR)\mod_access_compat_src.pdb"
    	-@erase "$(OUTDIR)\mod_access_compat.exp"
    	-@erase "$(OUTDIR)\mod_access_compat.lib"
    	-@erase "$(OUTDIR)\mod_access_compat.pdb"
    	-@erase "$(OUTDIR)\mod_access_compat.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_access_compat_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_access_compat.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_access_compat.pdb" /debug /out:"$(OUTDIR)\mod_access_compat.so" /implib:"$(OUTDIR)\mod_access_compat.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_access_compat.obj" \
    	"$(INTDIR)\mod_access_compat.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_access_compat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_access_compat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_access_compat.so"
       if exist .\Release\mod_access_compat.so.manifest mt.exe -manifest .\Release\mod_access_compat.so.manifest -outputresource:.\Release\mod_access_compat.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_access_compat - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_access_compat.obj"
    	-@erase "$(INTDIR)\mod_access_compat.res"
    	-@erase "$(INTDIR)\mod_access_compat_src.idb"
    	-@erase "$(INTDIR)\mod_access_compat_src.pdb"
    	-@erase "$(OUTDIR)\mod_access_compat.exp"
    	-@erase "$(OUTDIR)\mod_access_compat.lib"
    	-@erase "$(OUTDIR)\mod_access_compat.pdb"
    	-@erase "$(OUTDIR)\mod_access_compat.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_access_compat_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_access_compat.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_access_compat.pdb" /debug /out:"$(OUTDIR)\mod_access_compat.so" /implib:"$(OUTDIR)\mod_access_compat.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_access_compat.obj" \
    	"$(INTDIR)\mod_access_compat.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_access_compat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_access_compat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_access_compat.so"
       if exist .\Debug\mod_access_compat.so.manifest mt.exe -manifest .\Debug\mod_access_compat.so.manifest -outputresource:.\Debug\mod_access_compat.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_access_compat.dep")
    !INCLUDE "mod_access_compat.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_access_compat.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_access_compat - Win32 Release" || "$(CFG)" == "mod_access_compat - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_access_compat - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_access_compat - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_access_compat - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_access_compat - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_access_compat - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_access_compat - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_access_compat - Win32 Release"
    
    
    "$(INTDIR)\mod_access_compat.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_access_compat - Win32 Debug"
    
    
    "$(INTDIR)\mod_access_compat.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_access_compat.c
    
    "$(INTDIR)\mod_access_compat.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_form.mak����������������������������������������������������������0000664�0001751�0001751�00000024025�12701473373�020343� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_auth_form.dsp
    !IF "$(CFG)" == ""
    CFG=mod_auth_form - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_auth_form - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_auth_form - Win32 Release" && "$(CFG)" != "mod_auth_form - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_form.mak" CFG="mod_auth_form - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_auth_form - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_auth_form - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_form - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_auth_form.obj"
    	-@erase "$(INTDIR)\mod_auth_form.res"
    	-@erase "$(INTDIR)\mod_auth_form_src.idb"
    	-@erase "$(INTDIR)\mod_auth_form_src.pdb"
    	-@erase "$(OUTDIR)\mod_auth_form.exp"
    	-@erase "$(OUTDIR)\mod_auth_form.lib"
    	-@erase "$(OUTDIR)\mod_auth_form.pdb"
    	-@erase "$(OUTDIR)\mod_auth_form.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../session" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_form_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_form.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_form.pdb" /debug /out:"$(OUTDIR)\mod_auth_form.so" /implib:"$(OUTDIR)\mod_auth_form.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_auth_form.obj" \
    	"$(INTDIR)\mod_auth_form.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_auth_form.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_auth_form.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_form.so"
       if exist .\Release\mod_auth_form.so.manifest mt.exe -manifest .\Release\mod_auth_form.so.manifest -outputresource:.\Release\mod_auth_form.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_auth_form - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_auth_form.obj"
    	-@erase "$(INTDIR)\mod_auth_form.res"
    	-@erase "$(INTDIR)\mod_auth_form_src.idb"
    	-@erase "$(INTDIR)\mod_auth_form_src.pdb"
    	-@erase "$(OUTDIR)\mod_auth_form.exp"
    	-@erase "$(OUTDIR)\mod_auth_form.lib"
    	-@erase "$(OUTDIR)\mod_auth_form.pdb"
    	-@erase "$(OUTDIR)\mod_auth_form.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../session" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_form_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_form.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_form.pdb" /debug /out:"$(OUTDIR)\mod_auth_form.so" /implib:"$(OUTDIR)\mod_auth_form.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_auth_form.obj" \
    	"$(INTDIR)\mod_auth_form.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_auth_form.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_auth_form.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_form.so"
       if exist .\Debug\mod_auth_form.so.manifest mt.exe -manifest .\Debug\mod_auth_form.so.manifest -outputresource:.\Debug\mod_auth_form.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_auth_form.dep")
    !INCLUDE "mod_auth_form.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_auth_form.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_auth_form - Win32 Release" || "$(CFG)" == "mod_auth_form - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_auth_form - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_form - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_form - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_form - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_auth_form - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_auth_form - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_auth_form - Win32 Release"
    
    
    "$(INTDIR)\mod_auth_form.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_auth_form - Win32 Debug"
    
    
    "$(INTDIR)\mod_auth_form.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_auth_form.c
    
    "$(INTDIR)\mod_auth_form.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbm.mak����������������������������������������������������������0000664�0001751�0001751�00000025554�12701473373�020330� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_dbm.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authn_dbm - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authn_dbm - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authn_dbm - Win32 Release" && "$(CFG)" != "mod_authn_dbm - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbm - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_dbm.obj"
    	-@erase "$(INTDIR)\mod_authn_dbm.res"
    	-@erase "$(INTDIR)\mod_authn_dbm_src.idb"
    	-@erase "$(INTDIR)\mod_authn_dbm_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbm.exp"
    	-@erase "$(OUTDIR)\mod_authn_dbm.lib"
    	-@erase "$(OUTDIR)\mod_authn_dbm.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbm_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbm.so" /implib:"$(OUTDIR)\mod_authn_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_dbm.obj" \
    	"$(INTDIR)\mod_authn_dbm.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authn_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbm.so"
       if exist .\Release\mod_authn_dbm.so.manifest mt.exe -manifest .\Release\mod_authn_dbm.so.manifest -outputresource:.\Release\mod_authn_dbm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbm - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authn_dbm.obj"
    	-@erase "$(INTDIR)\mod_authn_dbm.res"
    	-@erase "$(INTDIR)\mod_authn_dbm_src.idb"
    	-@erase "$(INTDIR)\mod_authn_dbm_src.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbm.exp"
    	-@erase "$(OUTDIR)\mod_authn_dbm.lib"
    	-@erase "$(OUTDIR)\mod_authn_dbm.pdb"
    	-@erase "$(OUTDIR)\mod_authn_dbm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbm_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbm.so" /implib:"$(OUTDIR)\mod_authn_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authn_dbm.obj" \
    	"$(INTDIR)\mod_authn_dbm.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authn_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authn_dbm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbm.so"
       if exist .\Debug\mod_authn_dbm.so.manifest mt.exe -manifest .\Debug\mod_authn_dbm.so.manifest -outputresource:.\Debug\mod_authn_dbm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authn_dbm.dep")
    !INCLUDE "mod_authn_dbm.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authn_dbm.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authn_dbm - Win32 Release" || "$(CFG)" == "mod_authn_dbm - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authn_dbm - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbm - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbm - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbm - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbm - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbm - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authn_dbm - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbm - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authn_dbm - Win32 Release"
    
    
    "$(INTDIR)\mod_authn_dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbm - Win32 Debug"
    
    
    "$(INTDIR)\mod_authn_dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authn_dbm.c
    
    "$(INTDIR)\mod_authn_dbm.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authnz_ldap.mak��������������������������������������������������������0000664�0001751�0001751�00000026112�12701473373�020667� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authnz_ldap.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authnz_ldap - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_authnz_ldap - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authnz_ldap - Win32 Release" && "$(CFG)" != "mod_authnz_ldap - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authnz_ldap - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_ldap - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_ldap - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authnz_ldap.obj"
    	-@erase "$(INTDIR)\mod_authnz_ldap.res"
    	-@erase "$(INTDIR)\mod_authnz_ldap_src.idb"
    	-@erase "$(INTDIR)\mod_authnz_ldap_src.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.exp"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.lib"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../ldap" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_ldap_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_ldap.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_ldap.pdb" /debug /out:"$(OUTDIR)\mod_authnz_ldap.so" /implib:"$(OUTDIR)\mod_authnz_ldap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authnz_ldap.obj" \
    	"$(INTDIR)\mod_authnz_ldap.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"..\ldap\Release\mod_ldap.lib"
    
    "$(OUTDIR)\mod_authnz_ldap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authnz_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_ldap.so"
       if exist .\Release\mod_authnz_ldap.so.manifest mt.exe -manifest .\Release\mod_authnz_ldap.so.manifest -outputresource:.\Release\mod_authnz_ldap.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_ldap - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_ldap - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authnz_ldap.obj"
    	-@erase "$(INTDIR)\mod_authnz_ldap.res"
    	-@erase "$(INTDIR)\mod_authnz_ldap_src.idb"
    	-@erase "$(INTDIR)\mod_authnz_ldap_src.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.exp"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.lib"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.pdb"
    	-@erase "$(OUTDIR)\mod_authnz_ldap.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_ldap_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_ldap.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_ldap.pdb" /debug /out:"$(OUTDIR)\mod_authnz_ldap.so" /implib:"$(OUTDIR)\mod_authnz_ldap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authnz_ldap.obj" \
    	"$(INTDIR)\mod_authnz_ldap.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"..\ldap\Debug\mod_ldap.lib"
    
    "$(OUTDIR)\mod_authnz_ldap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authnz_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_ldap.so"
       if exist .\Debug\mod_authnz_ldap.so.manifest mt.exe -manifest .\Debug\mod_authnz_ldap.so.manifest -outputresource:.\Debug\mod_authnz_ldap.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authnz_ldap.dep")
    !INCLUDE "mod_authnz_ldap.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authnz_ldap.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authnz_ldap - Win32 Release" || "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authnz_ldap - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authnz_ldap - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authnz_ldap - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authnz_ldap - Win32 Release"
    
    "mod_ldap - Win32 Release" : 
       cd ".\..\ldap"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Release" 
       cd "..\aaa"
    
    "mod_ldap - Win32 ReleaseCLEAN" : 
       cd ".\..\ldap"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Release" RECURSE=1 CLEAN 
       cd "..\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
    
    "mod_ldap - Win32 Debug" : 
       cd ".\..\ldap"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Debug" 
       cd "..\aaa"
    
    "mod_ldap - Win32 DebugCLEAN" : 
       cd ".\..\ldap"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\aaa"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authnz_ldap - Win32 Release"
    
    
    "$(INTDIR)\mod_authnz_ldap.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
    
    
    "$(INTDIR)\mod_authnz_ldap.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authnz_ldap.c
    
    "$(INTDIR)\mod_authnz_ldap.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_groupfile.mak����������������������������������������������������0000664�0001751�0001751�00000026610�12701473373�021570� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_groupfile.dsp
    !IF "$(CFG)" == ""
    CFG=mod_authz_groupfile - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_authz_groupfile - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_authz_groupfile - Win32 Release" && "$(CFG)" != "mod_authz_groupfile - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_groupfile - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_groupfile.obj"
    	-@erase "$(INTDIR)\mod_authz_groupfile.res"
    	-@erase "$(INTDIR)\mod_authz_groupfile_src.idb"
    	-@erase "$(INTDIR)\mod_authz_groupfile_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.exp"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.lib"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.pdb"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_groupfile_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_groupfile.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_groupfile.pdb" /debug /out:"$(OUTDIR)\mod_authz_groupfile.so" /implib:"$(OUTDIR)\mod_authz_groupfile.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_groupfile.obj" \
    	"$(INTDIR)\mod_authz_groupfile.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_groupfile.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_authz_groupfile.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_groupfile.so"
       if exist .\Release\mod_authz_groupfile.so.manifest mt.exe -manifest .\Release\mod_authz_groupfile.so.manifest -outputresource:.\Release\mod_authz_groupfile.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_authz_groupfile.obj"
    	-@erase "$(INTDIR)\mod_authz_groupfile.res"
    	-@erase "$(INTDIR)\mod_authz_groupfile_src.idb"
    	-@erase "$(INTDIR)\mod_authz_groupfile_src.pdb"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.exp"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.lib"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.pdb"
    	-@erase "$(OUTDIR)\mod_authz_groupfile.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_groupfile_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_groupfile.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_groupfile.pdb" /debug /out:"$(OUTDIR)\mod_authz_groupfile.so" /implib:"$(OUTDIR)\mod_authz_groupfile.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_authz_groupfile.obj" \
    	"$(INTDIR)\mod_authz_groupfile.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"$(OUTDIR)\mod_auth_basic.lib"
    
    "$(OUTDIR)\mod_authz_groupfile.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_authz_groupfile.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_groupfile.so"
       if exist .\Debug\mod_authz_groupfile.so.manifest mt.exe -manifest .\Debug\mod_authz_groupfile.so.manifest -outputresource:.\Debug\mod_authz_groupfile.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_authz_groupfile.dep")
    !INCLUDE "mod_authz_groupfile.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_authz_groupfile.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_authz_groupfile - Win32 Release" || "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_authz_groupfile - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_groupfile - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\aaa"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_groupfile - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ELSEIF  "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\aaa"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\aaa"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_authz_groupfile - Win32 Release"
    
    "mod_auth_basic - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" 
       cd "."
    
    "mod_auth_basic - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
    
    "mod_auth_basic - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" 
       cd "."
    
    "mod_auth_basic - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_authz_groupfile - Win32 Release"
    
    
    "$(INTDIR)\mod_authz_groupfile.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
    
    
    "$(INTDIR)\mod_authz_groupfile.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_authz_groupfile.c
    
    "$(INTDIR)\mod_authz_groupfile.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_access_compat.dep������������������������������������������������������0000664�0001751�0001751�00000004162�12674411515�021162� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_access_compat.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_access_compat.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_form.dep����������������������������������������������������������0000664�0001751�0001751�00000004547�12674411515�020351� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_auth_form.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_auth_form.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_auth.h"\
    	"..\..\include\mod_request.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_md5.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_uuid.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\session\mod_session.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_file.c�����������������������������������������������������������0000664�0001751�0001751�00000013672�12147424465�020157� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
    #define AUTHN_CACHE_STORE(r,user,realm,data) \
        if (authn_cache_store != NULL) \
            authn_cache_store((r), "file", (user), (realm), (data))
    
    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 command_rec authn_file_cmds[] =
    {
        AP_INIT_TAKE1("AuthUserFile", ap_set_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;
    
        if (!conf->pwfile) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01619)
                          "AuthUserFile not specified in the configuration");
            return AUTH_GENERAL_ERROR;
        }
    
        status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);
    
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01620)
                          "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;
        }
        AUTHN_CACHE_STORE(r, user, NULL, file_password);
    
        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;
    
        if (!conf->pwfile) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01621)
                          "AuthUserFile not specified in the configuration");
            return AUTH_GENERAL_ERROR;
        }
    
        status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);
    
        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01622)
                          "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;
        AUTHN_CACHE_STORE(r, user, realm, file_hash);
    
        return AUTH_USER_FOUND;
    }
    
    static const authn_provider authn_file_provider =
    {
        &check_password,
        &get_realm_hash,
    };
    
    static void opt_retr(void)
    {
        authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
    }
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "file",
                                  AUTHN_PROVIDER_VERSION,
                                  &authn_file_provider, AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(authn_file) =
    {
        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 */
    };
    ����������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_core.dsp���������������������������������������������������������0000664�0001751�0001751�00000011045�12062614564�020521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_authn_core" - 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_core - 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_core.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_core.mak" CFG="mod_authn_core - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authn_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authn_core - 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_core - 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_core_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 /fo"Release/mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authn_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_authn_core - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_core_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 /fo"Debug/mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache"
    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 /out:".\Debug\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authn_core.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_authn_core - Win32 Release"
    # Name "mod_authn_core - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_authn_core.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthnsocache����������������������������������������������������������0000664�0001751�0001751�00000010213�11540546347�020231� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= authnsocache
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Authentication Cache Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= AuthnSOCache 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	=
    
    #
    # 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)/authnsocache.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_socache.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	authn_socache_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthndbm��������������������������������������������������������������0000664�0001751�0001751�00000010172�11540546347�017372� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthnzldap������������������������������������������������������������0000664�0001751�0001751�00000010676�11540546347�017753� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(NWOS) \
    			$(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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthform��������������������������������������������������������������0000664�0001751�0001751�00000010251�11540546347�017413� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(NWOS) \
    			$(STDMOD)/session \
    			$(STDMOD)/filters \
    			$(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	= authform
    
    #
    # 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	=
    
    #
    # 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)/$(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_auth_form.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	auth_form_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_owner.c����������������������������������������������������������0000664�0001751�0001751�00000015531�12530051571�020370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "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"
    #include "mod_authz_owner.h"
    
    static const command_rec authz_owner_cmds[] =
    {
        {NULL}
    };
    
    module AP_MODULE_DECLARE_DATA authz_owner_module;
    
    static authz_status fileowner_check_authorization(request_rec *r,
                                                      const char *require_args,
                                                      const void *parsed_require_args)
    {
        char *reason = NULL;
        apr_status_t status = 0;
    
    #if !APR_HAS_USER
        reason = "'Require file-owner' is not supported on this platform.";
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01632)
                      "Authorization of user %s to access %s failed, reason: %s",
                      r->user, r->uri, reason ? reason : "unknown");
        return AUTHZ_DENIED;
    #else  /* APR_HAS_USER */
        char *owner = NULL;
        apr_finfo_t finfo;
    
        if (!r->user) {
            return AUTHZ_DENIED_NO_USER;
        }
    
        if (!r->filename) {
            reason = "no filename available";
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01633)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return AUTHZ_DENIED;
        }
    
        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);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01634)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return AUTHZ_DENIED;
        }
    
        if (!(finfo.valid & APR_FINFO_USER)) {
            reason = "no file owner information available";
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01635)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return AUTHZ_DENIED;
        }
    
        status = apr_uid_name_get(&owner, finfo.user, r->pool);
        if (status != APR_SUCCESS || !owner) {
            reason = "could not get name of file owner";
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01636)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return AUTHZ_DENIED;
        }
    
        if (strcmp(owner, r->user)) {
            reason = apr_psprintf(r->pool, "file owner %s does not match.",
                                    owner);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01637)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return AUTHZ_DENIED;
        }
    
        /* this user is authorized */
        return AUTHZ_GRANTED;
    #endif /* APR_HAS_USER */
    }
    
    static char *authz_owner_get_file_group(request_rec *r)
    {
        /* 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 !APR_HAS_USER
        return NULL;
    #else  /* APR_HAS_USER */
        char *reason = NULL;
        char *group = NULL;
        apr_finfo_t finfo;
        apr_status_t status = 0;
    
        if (!r->filename) {
            reason = "no filename available";
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01638)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return NULL;
        }
    
        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);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01639)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return NULL;
        }
    
        if (!(finfo.valid & APR_FINFO_GROUP)) {
            reason = "no file group information available";
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01640)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return NULL;
        }
    
        status = apr_gid_name_get(&group, finfo.group, r->pool);
        if (status != APR_SUCCESS || !group) {
            reason = "could not get name of file group";
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01641)
                          "Authorization of user %s to access %s failed, reason: %s",
                          r->user, r->uri, reason ? reason : "unknown");
            return NULL;
        }
    
        return group;
    #endif /* APR_HAS_USER */
    }
    
    static const authz_provider authz_fileowner_provider =
    {
        &fileowner_check_authorization,
        NULL,
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(authz_owner_get_file_group);
    
        ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "file-owner",
                                  AUTHZ_PROVIDER_VERSION,
                                  &authz_fileowner_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
    }
    
    AP_DECLARE_MODULE(authz_owner) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,                          /* 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 */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthdigt��������������������������������������������������������������0000664�0001751�0001751�00000010172�11540546347�017401� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/NWGNUauthnano��������������������������������������������������������������0000664�0001751�0001751�00000010175�11540546347�017410� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbd.dsp����������������������������������������������������������0000664�0001751�0001751�00000011351�10663420702�020330� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_authz_dbd" - 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_dbd - 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_dbd.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_dbd.mak" CFG="mod_authz_dbd - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authz_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authz_dbd - 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_dbd - 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 "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_dbd_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 /fo"Release/mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authz_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_authz_dbd - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_dbd_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 /fo"Debug/mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache"
    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 /out:".\Debug\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authz_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_authz_dbd - Win32 Release"
    # Name "mod_authz_dbd - Win32 Debug"
    # Begin Source File
    
    SOURCE=..\database\mod_dbd.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_authz_dbd.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_authz_dbd.h
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_form.dsp����������������������������������������������������������0000664�0001751�0001751�00000011127�11022367030�020343� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_auth_form" - 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_form - 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_form.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_form.mak" CFG="mod_auth_form - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_auth_form - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_auth_form - 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_form - 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 "../session" /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_form_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 /fo"Release/mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_auth_form.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_auth_form - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../session" /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_form_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 /fo"Debug/mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache"
    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 /out:".\Debug\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_auth_form.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_auth_form - Win32 Release"
    # Name "mod_auth_form - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_auth_form.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_access_compat.dsp������������������������������������������������������0000664�0001751�0001751�00000011257�12062614564�021203� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_access_compat" - 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_access_compat - 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_access_compat.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_access_compat.mak" CFG="mod_access_compat - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_access_compat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_access_compat - 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_access_compat - 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_access_compat_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 /fo"Release/mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_access_compat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_access_compat - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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_access_compat_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 /fo"Debug/mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache"
    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 /out:".\Debug\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_access_compat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_access_compat - Win32 Release"
    # Name "mod_access_compat - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_access_compat.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_dbd.h������������������������������������������������������������0000664�0001751�0001751�00000003665�11637105701�020003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_AUTHZ_DBD_H
    #define MOD_AUTHZ_DBD_H
    #include "httpd.h"
    
    /* Create a set of AUTHZ_DBD_DECLARE(type), AUTHZ_DBD_DECLARE_NONSTD(type) and
     * AUTHZ_DBD_DECLARE_DATA with appropriate export and import tags
     */
    #if !defined(WIN32)
    #define AUTHZ_DBD_DECLARE(type)            type
    #define AUTHZ_DBD_DECLARE_NONSTD(type)     type
    #define AUTHZ_DBD_DECLARE_DATA
    #elif defined(AUTHZ_DBD_DECLARE_STATIC)
    #define AUTHZ_DBD_DECLARE(type)            type __stdcall
    #define AUTHZ_DBD_DECLARE_NONSTD(type)     type
    #define AUTHZ_DBD_DECLARE_DATA
    #elif defined(AUTHZ_DBD_DECLARE_EXPORT)
    #define AUTHZ_DBD_DECLARE(type)            __declspec(dllexport) type __stdcall
    #define AUTHZ_DBD_DECLARE_NONSTD(type)     __declspec(dllexport) type
    #define AUTHZ_DBD_DECLARE_DATA             __declspec(dllexport)
    #else
    #define AUTHZ_DBD_DECLARE(type)            __declspec(dllimport) type __stdcall
    #define AUTHZ_DBD_DECLARE_NONSTD(type)     __declspec(dllimport) type
    #define AUTHZ_DBD_DECLARE_DATA             __declspec(dllimport)
    #endif
    
    APR_DECLARE_EXTERNAL_HOOK(authz_dbd, AUTHZ_DBD, int, client_login,
                              (request_rec *r, int code, const char *action))
    #endif
    ���������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_allowmethods.dsp�������������������������������������������������������0000664�0001751�0001751�00000011141�11456275562�021100� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_allowmethods" - 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_allowmethods - 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_allowmethods.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_allowmethods.mak" CFG="mod_allowmethods - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_allowmethods - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_allowmethods - 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_allowmethods - 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_allowmethods_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 /fo"Release/mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_allowmethods.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_allowmethods - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_allowmethods_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 /fo"Debug/mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache"
    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 /out:".\Debug\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_allowmethods.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_allowmethods - Win32 Release"
    # Name "mod_allowmethods - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_allowmethods.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_auth_digest.dsp��������������������������������������������������������0000664�0001751�0001751�00000011103�10551346420�020657� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_auth_digest.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache"
    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 /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 /out:".\Debug\mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_auth_digest.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_anon.dsp���������������������������������������������������������0000664�0001751�0001751�00000011045�10551346420�020516� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authn_anon.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache"
    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 /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 /out:".\Debug\mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authn_anon.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authz_groupfile.dsp����������������������������������������������������0000664�0001751�0001751�00000011273�10551346420�021576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authz_groupfile.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache"
    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 /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 /out:".\Debug\mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authz_groupfile.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/aaa/mod_authn_dbd.dsp����������������������������������������������������������0000664�0001751�0001751�00000011225�10551346420�020314� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_authn_dbd" - 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_dbd - 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_dbd.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_dbd.mak" CFG="mod_authn_dbd - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_authn_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_authn_dbd - 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_dbd - 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 ../database /D DBD_DECLARE_EXPORT /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_dbd_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 /fo"Release/mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_authn_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_authn_dbd - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I ../database /D DBD_DECLARE_EXPORT /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_dbd_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 /fo"Debug/mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache"
    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 /out:".\Debug\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_authn_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_authn_dbd - Win32 Release"
    # Name "mod_authn_dbd - Win32 Debug"
    # Begin Source File
    
    SOURCE=..\database\mod_dbd.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_authn_dbd.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015224� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/util_ldap_cache.h���������������������������������������������������������0000664�0001751�0001751�00000020544�13225507043�020471� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
    
    /**
     * @file  util_ldap_cache.h
     * @brief 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 ttl;                  /* Time to live for items in cache */
        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;
    
    /*
     * When a group is found, subgroups are stored in the group's cache entry.
     */
    typedef struct util_compare_subgroup_t {
        const char **subgroupDNs;
        int len;
    } util_compare_subgroup_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;
        int sgl_processed;      /* 0 if no sgl processing yet. 1 if sgl has been processed (even if SGL is NULL). Saves repeat work on leaves. */
        struct util_compare_subgroup_t *subgroupList;
    } 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);
    util_compare_subgroup_t *util_ald_sgl_dup(util_ald_cache_t *cache, util_compare_subgroup_t *sgl);
    void util_ald_sgl_free(util_ald_cache_t *cache, util_compare_subgroup_t **sgl);
    
    /* 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,
                                    long cache_ttl,
                                    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 */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/util_ldap_cache.c���������������������������������������������������������0000664�0001751�0001751�00000032341�14526151712�020465� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <apr_strings.h>
    
    #if APR_HAS_LDAP
    
    /* ------------------------------------------------------------------ */
    
    unsigned long util_ldap_url_node_hash(void *n)
    {
        util_url_node_t *node = n;
        return util_ald_hash_string(1, node->url);
    }
    
    int util_ldap_url_node_compare(void *a, void *b)
    {
        util_url_node_t *na = a;
        util_url_node_t *nb = 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 = c;
        util_url_node_t *node = util_ald_alloc(cache, sizeof *node);
    
        if (node) {
            if (!(node->url = util_ald_strdup(cache, n->url))) {
                util_ald_free(cache, node);
                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 = 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 = n;
        char date_str[APR_CTIME_LEN];
        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;
    
            ap_rprintf(r,
                       "<tr valign='top'>"
                       "<td nowrap>%s (%s)</td>"
                       "<td nowrap>%ld</td>"
                       "<td nowrap>%ld</td>"
                       "<td nowrap>%ld</td>"
                       "<td nowrap>%" APR_TIME_T_FMT "</td>"
                       "<td nowrap>%ld</td>"
                       "<td nowrap>%s</td>"
                       "</tr>",
                       node->url,
                       type_str,
                       cache_node->size,
                       cache_node->maxentries,
                       cache_node->numentries,
                       apr_time_sec(cache_node->ttl),
                       cache_node->fullmark,
                       date_str);
        }
    
    }
    
    /* ------------------------------------------------------------------ */
    
    /* Cache functions for search nodes */
    unsigned long util_ldap_search_node_hash(void *n)
    {
        util_search_node_t *node = n;
        return util_ald_hash_string(1, node->username);
    }
    
    int util_ldap_search_node_compare(void *a, void *b)
    {
        util_search_node_t *na = a;
        util_search_node_t *nb = b;
    
        return (strcmp(na->username, nb->username) == 0);
    }
    
    void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c)
    {
        util_search_node_t *node = c;
        util_search_node_t *newnode = util_ald_alloc(cache, sizeof *newnode);
    
        /* 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 = 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 = n;
        char date_str[APR_CTIME_LEN];
    
        apr_ctime(date_str, node->lastbind);
    
        ap_rprintf(r,
                   "<tr valign='top'>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "</tr>",
                   ap_escape_html(r->pool, node->username),
                   ap_escape_html(r->pool, node->dn),
                   date_str);
    }
    
    /* ------------------------------------------------------------------ */
    
    unsigned long util_ldap_compare_node_hash(void *n)
    {
        util_compare_node_t *node = 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 = a;
        util_compare_node_t *nb = 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 = c;
        util_compare_node_t *node = util_ald_alloc(cache, sizeof *node);
    
        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)) ||
                ((n->subgroupList) && !(node->subgroupList = util_ald_sgl_dup(cache, n->subgroupList)))) {
                util_ldap_compare_node_free(cache, node);
                return NULL;
            }
            node->lastcompare = n->lastcompare;
            node->result = n->result;
            node->sgl_processed = n->sgl_processed;
            return node;
        }
        else {
            return NULL;
        }
    }
    
    void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n)
    {
        util_compare_node_t *node = n;
    
        util_ald_sgl_free(cache, &(node->subgroupList));
        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 = n;
        char date_str[APR_CTIME_LEN];
        char *cmp_result;
        char *sub_groups_val;
        char *sub_groups_checked;
    
        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);
        }
    
        if (node->subgroupList) {
            sub_groups_val = "Yes";
        }
        else {
            sub_groups_val = "No";
        }
    
        if (node->sgl_processed) {
            sub_groups_checked = "Yes";
        }
        else {
            sub_groups_checked = "No";
        }
    
        ap_rprintf(r,
                   "<tr valign='top'>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "</tr>",
                   ap_escape_html(r->pool, node->dn),
                   ap_escape_html(r->pool, node->attrib),
                   ap_escape_html(r->pool, node->value),
                   date_str,
                   cmp_result,
                   sub_groups_val,
                   sub_groups_checked);
    }
    
    /* ------------------------------------------------------------------ */
    
    unsigned long util_ldap_dn_compare_node_hash(void *n)
    {
        util_dn_compare_node_t *node = n;
        return util_ald_hash_string(1, node->reqdn);
    }
    
    int util_ldap_dn_compare_node_compare(void *a, void *b)
    {
        util_dn_compare_node_t *na = a;
        util_dn_compare_node_t *nb = b;
    
        return (strcmp(na->reqdn, nb->reqdn) == 0);
    }
    
    void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c)
    {
        util_dn_compare_node_t *n = c;
        util_dn_compare_node_t *node = util_ald_alloc(cache, sizeof *node);
    
        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 = 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 = n;
    
        ap_rprintf(r,
                   "<tr valign='top'>"
                   "<td nowrap>%s</td>"
                   "<td nowrap>%s</td>"
                   "</tr>",
                   ap_escape_html(r->pool, node->reqdn),
                   ap_escape_html(r->pool, node->dn));
    }
    
    
    /* ------------------------------------------------------------------ */
    static apr_status_t util_ldap_cache_module_kill(void *data)
    {
        util_ldap_state_t *st = 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;
            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;
        apr_size_t size;
    
        if (st->cache_bytes > 0) {
            if (st->cache_file) {
                /* Remove any existing shm segment with this name. */
                apr_shm_remove(st->cache_file, st->pool);
            }
    
            size = APR_ALIGN_DEFAULT(st->cache_bytes);
    
            result = apr_shm_create(&st->cache_shm, size, st->cache_file, st->pool);
            if (result != APR_SUCCESS) {
                return result;
            }
    
            /* Determine the usable size of the shm segment. */
            size = apr_shm_size_get(st->cache_shm);
    
            /* This will create a rmm "handler" to get into the shared memory area */
            result = apr_rmm_init(&st->cache_rmm, NULL,
                                  apr_shm_baseaddr_get(st->cache_shm), size,
                                  st->pool);
            if (result != APR_SUCCESS) {
                return result;
            }
        }
    
    #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,
                                  st->search_cache_ttl,
                                  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 */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/mod_ldap.dep��������������������������������������������������������������0000664�0001751�0001751�00000016173�12674411515�017501� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_ldap.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\util_ldap.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_ldap.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_anylock.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_ldap.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_init.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_option.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_rebind.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_url.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_rmm.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\util_ldap_cache.h"\
    	
    
    .\util_ldap_cache.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_ldap.h"\
    	"..\..\srclib\apr-util\include\apr_anylock.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_ldap.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_init.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_option.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_rebind.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_url.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_rmm.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\util_ldap_cache.h"\
    	
    
    .\util_ldap_cache_mgr.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_ldap.h"\
    	"..\..\srclib\apr-util\include\apr_anylock.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_ldap.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_init.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_option.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_rebind.h"\
    	"..\..\srclib\apr-util\include\apr_ldap_url.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_rmm.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_thread_rwlock.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\util_ldap_cache.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/README.ldap���������������������������������������������������������������0000664�0001751�0001751�00000003446�10752740261�017024� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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 httpd.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.
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/util_ldap_cache_mgr.c�����������������������������������������������������0000664�0001751�0001751�00000075364�13677706301�021354� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <apr_strings.h>
    
    APLOG_USE_MODULE(ldap);
    
    #if APR_HAS_LDAP
    
    /* only here until strdup is gone */
    #include <string.h>
    
    /* here till malloc is gone */
    #include <stdlib.h>
    
    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
    }
    
    /*
     * Duplicate a subgroupList from one compare entry to another.
     * Returns: ptr to a new copy of the subgroupList or NULL if allocation failed.
     */
    util_compare_subgroup_t *util_ald_sgl_dup(util_ald_cache_t *cache, util_compare_subgroup_t *sgl_in)
    {
        int i = 0;
        util_compare_subgroup_t *sgl_out = NULL;
    
        if (!sgl_in) {
            return NULL;
        }
    
        sgl_out = (util_compare_subgroup_t *) util_ald_alloc(cache, sizeof(util_compare_subgroup_t));
        if (sgl_out) {
            sgl_out->subgroupDNs = util_ald_alloc(cache, sizeof(char *) * sgl_in->len);
            if (sgl_out->subgroupDNs) {
                for (i = 0; i < sgl_in->len; i++) {
                    sgl_out->subgroupDNs[i] = util_ald_strdup(cache, sgl_in->subgroupDNs[i]);
                    if (!sgl_out->subgroupDNs[i]) {
                        /* We ran out of SHM, delete the strings we allocated for the SGL */
                        for (i = (i - 1); i >= 0; i--) {
                                util_ald_free(cache, sgl_out->subgroupDNs[i]);
                        }
                        util_ald_free(cache, sgl_out->subgroupDNs);
                        util_ald_free(cache, sgl_out);
                        sgl_out =  NULL;
                        break;
                    }
                }
                /* We were able to allocate new strings for all the subgroups */
                if (sgl_out != NULL) {
                    sgl_out->len = sgl_in->len;
                }
            }
        }
    
        return sgl_out;
    }
    
    /*
     * Delete an entire subgroupList.
     */
    void util_ald_sgl_free(util_ald_cache_t *cache, util_compare_subgroup_t **sgl)
    {
        int i = 0;
        if (sgl == NULL || *sgl == NULL) {
            return;
        }
    
        for (i = 0; i < (*sgl)->len; i++) {
            util_ald_free(cache, (*sgl)->subgroupDNs[i]);
        }
        util_ald_free(cache, *sgl);
    }
    
    /*
     * 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 now;
    
        if (!cache)
            return;
    
        now = cache->last_purge = apr_time_now();
        cache->npurged = 0;
        cache->numpurges++;
    
        /* If the marktime is farther back than TTL from now, 
           move the marktime forward to include additional expired entries.
        */
        if (now - cache->ttl > cache->marktime) {
            cache->marktime = now - cache->ttl;
        }
    
        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;
                }
            }
        }
    
        now = apr_time_now();
        cache->avg_purgetime =
             ((now - 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;
        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,
                          st->search_cache_ttl,
                          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,
                          st->compare_cache_ttl,
                          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,
                          st->compare_cache_ttl,
                          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;
    
            return util_ald_cache_insert(st->util_ldap_cache, &curl);
        }
        else {
            /* util_ald_destroy_cache is a noop for a NULL argument. */
            util_ald_destroy_cache(search_cache);
            util_ald_destroy_cache(compare_cache);
            util_ald_destroy_cache(dn_compare_cache);
    
            return NULL;
        }
    }
    
    
    util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st,
                                    long cache_size,
                                    long cache_ttl,
                                    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 APR_HAS_SHARED_MEMORY
        apr_rmm_off_t block;
    #endif
    
        if (cache_size <= 0)
            return NULL;
    
    #if APR_HAS_SHARED_MEMORY
        if (!st->cache_rmm) {
            cache = (util_ald_cache_t *)calloc(sizeof(util_ald_cache_t), 1);
        }
        else {
            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) {
            /* This frees cache in the right way even if !APR_HAS_SHARED_MEMORY or !st->cache_rmm */
            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->ttl = cache_ttl;
        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)
    {
        unsigned long 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)
    {
        unsigned long hashval;
        void *tmp_payload;
        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 */
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(01323)
                             "Purge of LDAP cache failed");
                return NULL;
            }
        }
    
        node = (util_cache_node_t *)util_ald_alloc(cache,
                                                   sizeof(util_cache_node_t));
        if (node == NULL) {
            /*
             * XXX: The cache management should be rewritten to work
             * properly when LDAPSharedCacheSize is too small.
             */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(01324)
                         "LDAPSharedCacheSize is too small. Increase it or "
                         "reduce LDAPCacheEntries/LDAPOpCacheEntries!");
            if (cache->numentries < cache->fullmark) {
                /*
                 * We have not even reached fullmark, trigger a complete purge.
                 * This is still better than not being able to add new entries
                 * at all.
                 */
                cache->marktime = apr_time_now();
            }
            util_ald_cache_purge(cache);
            node = (util_cache_node_t *)util_ald_alloc(cache,
                                                       sizeof(util_cache_node_t));
            if (node == NULL) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(01325)
                             "Could not allocate memory for LDAP cache entry");
                return NULL;
            }
        }
    
        /* Take a copy of the payload before proceeding. */
        tmp_payload = (*cache->copy)(cache, payload);
        if (tmp_payload == NULL) {
            /*
             * XXX: The cache management should be rewritten to work
             * properly when LDAPSharedCacheSize is too small.
             */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(01326)
                         "LDAPSharedCacheSize is too small. Increase it or "
                         "reduce LDAPCacheEntries/LDAPOpCacheEntries!");
            if (cache->numentries < cache->fullmark) {
                /*
                 * We have not even reached fullmark, trigger a complete purge.
                 * This is still better than not being able to add new entries
                 * at all.
                 */
                cache->marktime = apr_time_now();
            }
            util_ald_cache_purge(cache);
            tmp_payload = (*cache->copy)(cache, payload);
            if (tmp_payload == NULL) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(01327)
                             "Could not allocate memory for LDAP cache value");
                util_ald_free(cache, node);
                return NULL;
            }
        }
        payload = tmp_payload;
    
        /* populate the entry */
        cache->inserts++;
        hashval = (*cache->hash)(payload) % cache->size;
        node->add_time = apr_time_now();
        node->payload = 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)
    {
        unsigned long 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,
                     "<a href=\"%s?%s\">%s</a>",
                 ap_escape_html(r->pool, ap_escape_uri(r->pool, r->uri)),
                 id,
                 name);
        }
        else {
            buf2 = name;
        }
    
        buf = apr_psprintf(p,
                 "<tr valign='top'>"
                 "<td nowrap>%s</td>"
                 "<td align='right' nowrap>%lu (%.0f%% full)</td>"
                 "<td align='right'>%.1f</td>"
                 "<td align='right'>%lu/%lu</td>"
                 "<td align='right'>%.0f%%</td>"
                 "<td align='right'>%lu/%lu</td>",
             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"
                     "<td align='right'>%lu</td>\n"
                     "<td align='right' nowrap>%s</td>\n",
                 buf,
                 cache->numpurges,
                 str_ctime);
        }
        else {
            buf = apr_psprintf(p,
                     "%s<td colspan='2' align='center'>(none)</td>\n",
                 buf);
        }
    
        buf = apr_psprintf(p, "%s<td align='right'>%.2gms</td>\n</tr>", 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) {
            ap_rputs("<tr valign='top'><td nowrap colspan=7>Cache has not been enabled/initialised.</td></tr>", r);
            return NULL;
        }
    
        if (r->args && strlen(r->args)) {
            char cachetype[5], lint[2];
            unsigned int id, off;
            char date_str[APR_CTIME_LEN];
    
            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_rprintf(r,
                           "<p>\n"
                           "<table border='0'>\n"
                           "<tr>\n"
                           "<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Cache Name:</b></font></td>"
                           "<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%s (%s)</b></font></td>"
                           "</tr>\n"
                           "</table>\n</p>\n",
                           buf,
                           cachetype[0] == 'm'? "Main" :
                           (cachetype[0] == 's' ? "Search" :
                            (cachetype[0] == 'c' ? "Compares" : "DNCompares")));
    
                switch (cachetype[0]) {
                    case 'm':
                        if (util_ldap_cache->marktime) {
                            apr_ctime(date_str, util_ldap_cache->marktime);
                        }
                        else
                            date_str[0] = 0;
    
                        ap_rprintf(r,
                                   "<p>\n"
                                   "<table border='0'>\n"
                                   "<tr>\n"
                                   "<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Size:</b></font></td>"
                                   "<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
                                   "</tr>\n"
                                   "<tr>\n"
                                   "<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Max Entries:</b></font></td>"
                                   "<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
                                   "</tr>\n"
                                   "<tr>\n"
                                   "<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b># Entries:</b></font></td>"
                                   "<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
                                   "</tr>\n"
                                   "<tr>\n"
                                   "<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>TTL (sec):</b></font></td>"
                                   "<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%" APR_TIME_T_FMT "</b></font></td>"
                                   "</tr>\n"
                                   "<tr>\n"
                                   "<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark:</b></font></td>"
                                   "<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%ld</b></font></td>"
                                   "</tr>\n"
                                   "<tr>\n"
                                   "<td bgcolor='#000000'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark Time:</b></font></td>"
                                   "<td bgcolor='#ffffff'><font size='-1' face='Arial,Helvetica' color='#000000'><b>%s</b></font></td>"
                                   "</tr>\n"
                                   "</table>\n</p>\n",
                                   util_ldap_cache->size,
                                   util_ldap_cache->maxentries,
                                   util_ldap_cache->numentries,
                                   apr_time_sec(util_ldap_cache->ttl),
                                   util_ldap_cache->fullmark,
                                   date_str);
    
                        ap_rputs("<p>\n"
                                 "<table border='0'>\n"
                                 "<tr bgcolor='#000000'>\n"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>LDAP URL</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Size</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Max Entries</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b># Entries</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>TTL (sec)</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Full Mark Time</b></font></td>"
                                 "</tr>\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("</table>\n</p>\n", r);
    
    
                        break;
                    case 's':
                        ap_rputs("<p>\n"
                                 "<table border='0'>\n"
                                 "<tr bgcolor='#000000'>\n"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>LDAP Filter</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>User Name</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Last Bind</b></font></td>"
                                 "</tr>\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("</table>\n</p>\n", r);
                        break;
                    case 'c':
                        ap_rputs("<p>\n"
                                 "<table border='0'>\n"
                                 "<tr bgcolor='#000000'>\n"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>DN</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Attribute</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Value</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Last Compare</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Result</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Sub-groups?</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>S-G Checked?</b></font></td>"
                                 "</tr>\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("</table>\n</p>\n", r);
                        break;
                    case 'd':
                        ap_rputs("<p>\n"
                                 "<table border='0'>\n"
                                 "<tr bgcolor='#000000'>\n"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Require DN</b></font></td>"
                                 "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Actual DN</b></font></td>"
                                 "</tr>\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("</table>\n</p>\n", r);
                        break;
                    default:
                        break;
                }
    
            }
            else {
                buf = "";
            }
        }
        else {
            ap_rputs("<p>\n"
                     "<table border='0'>\n"
                     "<tr bgcolor='#000000'>\n"
                     "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Cache Name</b></font></td>"
                     "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Entries</b></font></td>"
                     "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Avg. Chain Len.</b></font></td>"
                     "<td colspan='2'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Hits</b></font></td>"
                     "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Ins/Rem</b></font></td>"
                     "<td colspan='2'><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Purges</b></font></td>"
                     "<td><font size='-1' face='Arial,Helvetica' color='#ffffff'><b>Avg Purge Time</b></font></td>"
                     "</tr>\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("</table>\n</p>\n", r);
        }
    
        return buf;
    }
    
    #endif /* APR_HAS_LDAP */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/config.m4�����������������������������������������������������������������0000664�0001751�0001751�00000001343�11616721533�016727� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    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, , most , [
      APACHE_CHECK_APR_HAS_LDAP
      if test "$ac_cv_APR_HAS_LDAP" = "yes" ; then
        if test -z "$apu_config" ; then
          LDAP_LIBS="`$apr_config --ldap-libs`"
        else
          LDAP_LIBS="`$apu_config --ldap-libs`"
        fi
        APR_ADDTO(MOD_LDAP_LDADD, [$LDAP_LIBS])
        AC_SUBST(MOD_LDAP_LDADD)
      else
        AC_MSG_WARN([apr/apr-util is compiled without ldap support])
        enable_ldap=no
      fi
    ])
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/util_ldap.c���������������������������������������������������������������0000664�0001751�0001751�00000342307�14737240630�017352� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_mutex.h"
    #include "util_ldap.h"
    #include "util_ldap_cache.h"
    
    #include <apr_strings.h>
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    #if !APR_HAS_LDAP
    #error mod_ldap requires APR-util to have LDAP support built in
    #endif
    
    /* Default define for ldap functions that need a SIZELIMIT but
     * do not have the define
     * XXX This should be removed once a supporting #define is
     *  released through APR-Util.
     */
    #ifndef APR_LDAP_SIZELIMIT
    #define APR_LDAP_SIZELIMIT -1
    #endif
    
    #ifdef LDAP_OPT_DEBUG_LEVEL
    #define AP_LDAP_OPT_DEBUG LDAP_OPT_DEBUG_LEVEL
    #else
    #ifdef LDAP_OPT_DEBUG
    #define AP_LDAP_OPT_DEBUG LDAP_OPT_DEBUG
    #endif
    #endif
    
    #define AP_LDAP_HOPLIMIT_UNSET -1
    #define AP_LDAP_CHASEREFERRALS_SDKDEFAULT -1
    #define AP_LDAP_CHASEREFERRALS_OFF 0
    #define AP_LDAP_CHASEREFERRALS_ON 1
    
    #define AP_LDAP_CONNPOOL_DEFAULT -1
    #define AP_LDAP_CONNPOOL_INFINITE -2
    
    #if !defined(LDAP_OPT_NETWORK_TIMEOUT) && defined(LDAP_OPT_CONNECT_TIMEOUT)
    #define LDAP_OPT_NETWORK_TIMEOUT LDAP_OPT_CONNECT_TIMEOUT
    #endif
    
    module AP_MODULE_DECLARE_DATA ldap_module;
    static const char *ldap_cache_mutex_type = "ldap-cache";
    static apr_status_t uldap_connection_unbind(void *param);
    
    /* For OpenLDAP with the 3-arg version of ldap_set_rebind_proc(), use
     * a simpler rebind callback than the implementation in APR-util.
     * Testing for API version >= 3001 appears safe although OpenLDAP
     * 2.1.x (API version = 2004) also has the 3-arg API. */
    #if APR_HAS_OPENLDAP_LDAPSDK && defined(LDAP_API_VERSION) && LDAP_API_VERSION >= 3001
    
    #define uldap_rebind_init(p) APR_SUCCESS /* noop */
    
    static int uldap_rebind_proc(LDAP *ld, const char *url, ber_tag_t request,
                                 ber_int_t msgid, void *params)
    {
        util_ldap_connection_t *ldc = params;
    
        return ldap_bind_s(ld, ldc->binddn, ldc->bindpw, LDAP_AUTH_SIMPLE);
    }
    
    static apr_status_t uldap_rebind_add(util_ldap_connection_t *ldc)
    {
        ldap_set_rebind_proc(ldc->ldap, uldap_rebind_proc, ldc);
        return APR_SUCCESS;
    }
    
    #else /* !APR_HAS_OPENLDAP_LDAPSDK */
    
    #define USE_APR_LDAP_REBIND
    #include <apr_ldap_rebind.h>
    
    #define uldap_rebind_init(p) apr_ldap_rebind_init(p)
    #define uldap_rebind_add(ldc) apr_ldap_rebind_add((ldc)->rebind_pool, \
                                                      (ldc)->ldap, (ldc)->binddn, \
                                                      (ldc)->bindpw)
    #endif
    
    static APR_INLINE apr_status_t ldap_cache_lock(util_ldap_state_t *st, request_rec *r) { 
        apr_status_t rv = APR_SUCCESS;
        if (st->util_ldap_cache_lock) { 
            apr_status_t rv = apr_global_mutex_lock(st->util_ldap_cache_lock);
            if (rv != APR_SUCCESS) { 
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, APLOGNO(10134) "LDAP cache lock failed");
                ap_assert(0);
            }
        }
        return rv; 
    }
    static APR_INLINE apr_status_t ldap_cache_unlock(util_ldap_state_t *st, request_rec *r) { 
        apr_status_t rv = APR_SUCCESS;
        if (st->util_ldap_cache_lock) { 
            apr_status_t rv = apr_global_mutex_unlock(st->util_ldap_cache_lock);
            if (rv != APR_SUCCESS) { 
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, APLOGNO(10135) "LDAP cache lock failed");
                ap_assert(0);
            }
        }
        return rv; 
    }
    
    static void util_ldap_strdup (char **str, const char *newstr)
    {
        if (*str) {
            free(*str);
            *str = NULL;
        }
    
        if (newstr) {
            *str = strdup(newstr);
        }
    }
    
    /*
     * Status Handler
     * --------------
     *
     * This handler generates a status page about the current performance of
     * the LDAP cache. It is enabled as follows:
     *
     * <Location /ldap-status>
     *   SetHandler ldap-status
     * </Location>
     *
     */
    static int util_ldap_handler(request_rec *r)
    {
        util_ldap_state_t *st;
    
        r->allowed |= (1 << M_GET);
        if (r->method_number != M_GET) {
            return DECLINED;
        }
    
        if (strcmp(r->handler, "ldap-status")) {
            return DECLINED;
        }
    
        st = (util_ldap_state_t *) ap_get_module_config(r->server->module_config,
                &ldap_module);
    
        ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
    
        if (r->header_only)
            return OK;
    
        ap_rputs(DOCTYPE_HTML_3_2
                 "<html><head><title>LDAP Cache Information</title></head>\n", r);
        ap_rputs("<body bgcolor='#ffffff'><h1 align=center>LDAP Cache Information"
                 "</h1>\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)
    {
    
         /* We leave bound LDAP connections floating around in our pool,
          * but always check/fix the binddn/bindpw when we take them out
          * of the pool
          */
         if (!ldc->keep) {
             uldap_connection_unbind(ldc);
             ldc->r = NULL;
         }
         else {
             /* mark our connection as available for reuse */
             ldc->freed = apr_time_now();
             ldc->r = NULL;
         }
    
    #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.
     */
    static apr_status_t uldap_connection_unbind(void *param)
    {
        util_ldap_connection_t *ldc = param;
    
        if (ldc) {
    #ifdef USE_APR_LDAP_REBIND
            /* forget the rebind info for this conn */
            if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
                apr_pool_clear(ldc->rebind_pool);
            }
    #endif
    
            if (ldc->ldap) {
                if (ldc->r) { 
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc); 
                }
                ldap_unbind_s(ldc->ldap);
                ldc->ldap = NULL;
            }
            ldc->bound = 0;
        }
    
        return APR_SUCCESS;
    }
    
    /* not presently used, not part of the API */
    #if 0
    /*
     * util_ldap_connection_remove frees all storage associated with the LDAP
     * connection and removes it completely from the per-virtualhost list of
     * connections
     *
     * The caller should hold the lock for this connection
     */
    static apr_status_t util_ldap_connection_remove (void *param)
    {
        util_ldap_connection_t *ldc = param, *l = NULL, *prev = NULL;
        util_ldap_state_t *st;
    
        if (!ldc) return APR_SUCCESS;
    
        st = ldc->st;
    
        uldap_connection_unbind(ldc);
    
    #if APR_HAS_THREADS
        apr_thread_mutex_lock(st->mutex);
    #endif
    
        /* Remove ldc from the list */
        for (l=st->connections; l; l=l->next) {
            if (l == ldc) {
                if (prev) {
                    prev->next = l->next;
                }
                else {
                    st->connections = l->next;
                }
                break;
            }
            prev = l;
        }
    
        if (ldc->bindpw) {
            free((void*)ldc->bindpw);
        }
        if (ldc->binddn) {
            free((void*)ldc->binddn);
        }
    
    #if APR_HAS_THREADS
        apr_thread_mutex_unlock(ldc->lock);
        apr_thread_mutex_unlock(st->mutex);
    #endif
    
        /* Destroy the pool associated with this connection */
    
        apr_pool_destroy(ldc->pool);
    
        return APR_SUCCESS;
    }
    #endif
    
    static int uldap_connection_init(request_rec *r,
                                     util_ldap_connection_t *ldc)
    {
        int rc = 0, ldap_option = 0;
        int version  = LDAP_VERSION3;
        apr_ldap_err_t *result = NULL;
    #ifdef LDAP_OPT_NETWORK_TIMEOUT
        struct timeval connectionTimeout = {0};
    #endif
        util_ldap_state_t *st =
            (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
            &ldap_module);
        int have_client_certs = !apr_is_empty_array(ldc->client_certs);
    #if !APR_HAS_SOLARIS_LDAPSDK
        /*
         * Normally we enable SSL/TLS with apr_ldap_set_option(), except
         * with Solaris LDAP, where this is broken.
         */
        int secure = APR_LDAP_NONE;
    #else
        /*
         * With Solaris LDAP, we enable TSL via the secure argument
         * to apr_ldap_init(). This requires a fix from apr-util >= 1.4.0.
         *
         * Just in case client certificates ever get supported, we
         * handle those as with the other LDAP SDKs.
         */
        int secure = have_client_certs ? APR_LDAP_NONE : ldc->secure;
    #endif
    
        /* 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(r->pool, &(ldc->ldap),
                      ldc->host,
                      APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
                      secure, &(result));
    
        if (NULL == result) {
            /* something really bad happened */
            ldc->bound = 0;
            if (NULL == ldc->reason) {
                ldc->reason = "LDAP: ldap initialization failed. Make sure the apr_ldap module is installed.";
            }
            return(APR_EGENERAL);
        }
    
        if (result->rc) {
            ldc->reason = result->reason;
            ldc->bound = 0;
            return result->rc;
        }
    
        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);
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp init", ldc);
    
        if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
            /* Now that we have an ldap struct, add it to the referral list for rebinds. */
            rc = uldap_rebind_add(ldc);
            if (rc != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, APLOGNO(01277)
                        "LDAP: Unable to add rebind cross reference entry. Out of memory?");
                uldap_connection_unbind(ldc);
                ldc->reason = "LDAP: Unable to add rebind cross reference entry.";
                return(rc);
            }
        }
    
        /* always default to LDAP V3 */
        ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
    
        /* set client certificates */
        if (have_client_certs) {
            apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
                                ldc->client_certs, &(result));
            if (LDAP_SUCCESS != result->rc) {
                uldap_connection_unbind( ldc );
                ldc->reason = result->reason;
                return(result->rc);
            }
        }
    
        /* switch on SSL/TLS */
        if (APR_LDAP_NONE != ldc->secure
    #if APR_HAS_SOLARIS_LDAPSDK
            /* See comments near apr_ldap_init() above */
            && have_client_certs
    #endif
           ) {
            apr_ldap_set_option(r->pool, ldc->ldap,
                                APR_LDAP_OPT_TLS, &ldc->secure, &(result));
            if (LDAP_SUCCESS != result->rc) {
                uldap_connection_unbind( ldc );
                ldc->reason = result->reason;
                return(result->rc);
            }
        }
    
        /* Set the alias dereferencing option */
        ldap_option = ldc->deref;
        ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &ldap_option);
    
        if (ldc->ChaseReferrals != AP_LDAP_CHASEREFERRALS_SDKDEFAULT) {
            /* Set options for rebind and referrals. */
            ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, r->server,
                    "LDAP: Setting referrals to %s.",
                    ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"));
            apr_ldap_set_option(r->pool, ldc->ldap,
                    APR_LDAP_OPT_REFERRALS,
                    (void *)((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ?
                        LDAP_OPT_ON : LDAP_OPT_OFF),
                    &(result));
            if (result->rc != LDAP_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01279)
                        "Unable to set LDAP_OPT_REFERRALS option to %s: %d.",
                        ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"),
                        result->rc);
                result->reason = "Unable to set LDAP_OPT_REFERRALS.";
                ldc->reason = result->reason;
                uldap_connection_unbind(ldc);
                return(result->rc);
            }
        }
    
        if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
            if ((ldc->ReferralHopLimit != AP_LDAP_HOPLIMIT_UNSET) && ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
                /* Referral hop limit - only if referrals are enabled and a hop limit is explicitly requested */
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01280)
                        "Setting referral hop limit to %d.",
                        ldc->ReferralHopLimit);
                apr_ldap_set_option(r->pool, ldc->ldap,
                        APR_LDAP_OPT_REFHOPLIMIT,
                        (void *)&ldc->ReferralHopLimit,
                        &(result));
                if (result->rc != LDAP_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01281)
                            "Unable to set LDAP_OPT_REFHOPLIMIT option to %d: %d.",
                            ldc->ReferralHopLimit,
                            result->rc);
                    result->reason = "Unable to set LDAP_OPT_REFHOPLIMIT.";
                    ldc->reason = result->reason;
                    uldap_connection_unbind(ldc);
                    return(result->rc);
                }
            }
        }
    
    /*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(r->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) {
            connectionTimeout.tv_sec = st->connectionTimeout;
        }
    
        if (connectionTimeout.tv_sec > 0) {
            rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
                                     (void *)&connectionTimeout, &(result));
            if (APR_SUCCESS != rc) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01282)
                                 "LDAP: Could not set the connection timeout");
            }
        }
    #endif
    
    #ifdef LDAP_OPT_TIMEOUT
        /*
         * LDAP_OPT_TIMEOUT is not portable, but it influences all synchronous ldap
         * function calls and not just ldap_search_ext_s(), which accepts a timeout
         * parameter.
         * XXX: It would be possible to simulate LDAP_OPT_TIMEOUT by replacing all
         * XXX: synchronous ldap function calls with asynchronous calls and using
         * XXX: ldap_result() with a timeout.
         */
        if (st->opTimeout) {
            rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
                                     st->opTimeout, &(result));
            if (APR_SUCCESS != rc) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01283)
                                 "LDAP: Could not set LDAP_OPT_TIMEOUT");
            }
        }
    #endif
    
        return(rc);
    }
    
    static int uldap_ld_errno(util_ldap_connection_t *ldc)
    {
        int ldaprc;
    #ifdef LDAP_OPT_ERROR_NUMBER
        if (LDAP_SUCCESS == ldap_get_option(ldc->ldap, LDAP_OPT_ERROR_NUMBER, &ldaprc)) return ldaprc;
    #endif
    #ifdef LDAP_OPT_RESULT_CODE
        if (LDAP_SUCCESS == ldap_get_option(ldc->ldap, LDAP_OPT_RESULT_CODE, &ldaprc)) return ldaprc;
    #endif
        return LDAP_OTHER;
    }
    
    /*
     * Replacement function for ldap_simple_bind_s() with a timeout.
     * To do this in a portable way, we have to use ldap_simple_bind() and
     * ldap_result().
     *
     * Returns LDAP_SUCCESS on success; and an error code on failure
     */
    static int uldap_simple_bind(util_ldap_connection_t *ldc, char *binddn,
                                 char* bindpw, struct timeval *timeout)
    {
        LDAPMessage *result;
        int rc;
        int msgid = ldap_simple_bind(ldc->ldap, binddn, bindpw);
        if (msgid == -1) {
            ldc->reason = "LDAP: ldap_simple_bind() failed";
            return uldap_ld_errno(ldc);
        }
        rc = ldap_result(ldc->ldap, msgid, 0, timeout, &result);
        if (rc == -1) {
            ldc->reason = "LDAP: ldap_simple_bind() result retrieval failed";
            /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
            return uldap_ld_errno(ldc);
        }
        else if (rc == 0) {
            ldc->reason = "LDAP: ldap_simple_bind() timed out";
            rc = LDAP_TIMEOUT;
        } else if (ldap_parse_result(ldc->ldap, result, &rc, NULL, NULL, NULL,
                                     NULL, 1) == -1) {
            ldc->reason = "LDAP: ldap_simple_bind() parse result failed";
            return uldap_ld_errno(ldc);
        }
        else { 
            ldc->last_backend_conn = ldc->r->request_time;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp bind", ldc);
        }
        return rc;
    }
    
    /*
     * 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 new_connection = 0;
        util_ldap_state_t *st;
    
        /* sanity check for NULL */
        if (!ldc) {
            return -1;
        }
    
        /* If the connection is already bound, return
        */
        if (ldc->bound && !ldc->must_rebind)
        {
            ldc->reason = "LDAP: connection open successful (already bound)";
            return LDAP_SUCCESS;
        }
    
        /* create the ldap session handle
        */
        if (NULL == ldc->ldap)
        {
           new_connection = 1;
           rc = uldap_connection_init( r, ldc );
           if (LDAP_SUCCESS != rc)
           {
               return rc;
           }
        }
    
    
        st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
                                                       &ldap_module);
    
        /* loop trying to bind up to st->retries times if LDAP_SERVER_DOWN or LDAP_TIMEOUT
         * are returned.  Close the connection before the first retry, and then on every
         * other retry.
         *
         * On Success or any other error, break out of the loop.
         *
         * 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.
         */
    
        while (failures <= st->retries) {
            if (failures > 0 && st->retry_delay > 0) {
                apr_sleep(st->retry_delay);
            }
            rc = uldap_simple_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
                                   st->opTimeout);
    
            if (rc == LDAP_SUCCESS) break;
    
            failures++;
    
            if (AP_LDAP_IS_SERVER_DOWN(rc)) {
                 ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "ldap_simple_bind() failed with server down "
                              "(try %d)", failures);
            }
            else if (rc == LDAP_TIMEOUT) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01284)
                              "ldap_simple_bind() timed out on %s "
                              "connection, dropped by firewall?",
                              new_connection ? "new" : "reused");
            }
            else {
                /* Other errors not retryable */
                break;
            }
    
            if (!(failures % 2)) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "attempt to re-init the connection");
                uldap_connection_unbind(ldc);
                if (LDAP_SUCCESS != uldap_connection_init(r, ldc)) {
                    /* leave rc as the initial bind return code */
                    break;
                }
            }
        }
    
        /* free the handle if there was an error
        */
        if (LDAP_SUCCESS != rc)
        {
            uldap_connection_unbind(ldc);
            ldc->reason = "LDAP: ldap_simple_bind() failed";
        }
        else {
            ldc->bound = 1;
            ldc->must_rebind = 0;
            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 ((strcmp(src[i].path, dest[i].path)) ||
                (src[i].type != dest[i].type) ||
                /* One is passwordless? If so, then not equal */
                ((src[i].password == NULL) ^ (dest[i].password == NULL)) ||
                (src[i].password != NULL && dest[i].password != NULL &&
                 strcmp(src[i].password, dest[i].password))) {
                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;
        apr_time_t now = apr_time_now();
    
        util_ldap_state_t *st =
            (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
            &ldap_module);
        util_ldap_config_t *dc =
            (util_ldap_config_t *) ap_get_module_config(r->per_dir_config, &ldap_module);
    
    #if APR_HAS_THREADS
        /* mutex lock this function */
        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(dc->client_certs, l->client_certs))
            {
                if (st->connection_pool_ttl > 0) {
                    if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                      "Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago",
                                      (now - l->last_backend_conn) / APR_USEC_PER_SEC);
                        l->r = r;
                        uldap_connection_unbind(l);
                        /* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */
                    }
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, 
                                  "Reuse %s LDC %pp", 
                                  l->bound ? "bound" : "unbound", l);
                }
                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(dc->client_certs, l->client_certs))
                {
                    if (st->connection_pool_ttl > 0) {
                        if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
                            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                    "Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago",
                                    (now - l->last_backend_conn) / APR_USEC_PER_SEC);
                            l->r = r;
                            uldap_connection_unbind(l);
                            /* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */
                        }
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, 
                                      "Reuse %s LDC %pp (will rebind)", 
                                       l->bound ? "bound" : "unbound", l);
                    }
    
                    /* the bind credentials have changed */
                    l->must_rebind = 1;
                    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 was found after the second search, we
         * must create one.
         */
        if (!l) {
            apr_pool_t *newpool;
            if (apr_pool_create(&newpool, NULL) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01285)
                              "util_ldap: Failed to create memory pool");
    #if APR_HAS_THREADS
                apr_thread_mutex_unlock(st->mutex);
    #endif
                return NULL;
            }
            apr_pool_tag(newpool, "util_ldap_connection");
    
            /*
             * 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 of this connection in the new pool */
            l = apr_pcalloc(newpool, sizeof(util_ldap_connection_t));
            l->pool = newpool;
            l->st = st;
    
    #if APR_HAS_THREADS
            apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, l->pool);
            apr_thread_mutex_lock(l->lock);
    #endif
            l->bound = 0;
            l->host = apr_pstrdup(l->pool, host);
            l->port = port;
            l->deref = deref;
            util_ldap_strdup((char**)&(l->binddn), binddn);
            util_ldap_strdup((char**)&(l->bindpw), bindpw);
            l->ChaseReferrals = dc->ChaseReferrals;
            l->ReferralHopLimit = dc->ReferralHopLimit;
    
            /* 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, dc->client_certs);
    
            /* whether or not to keep this connection in the pool when it's returned */
            l->keep = (st->connection_pool_ttl == 0) ? 0 : 1;
    
    #ifdef USE_APR_LDAP_REBIND
            if (l->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
                if (apr_pool_create(&(l->rebind_pool), l->pool) != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01286)
                                  "util_ldap: Failed to create memory pool");
    #if APR_HAS_THREADS
                    apr_thread_mutex_unlock(st->mutex);
    #endif
                    return NULL;
                }
                apr_pool_tag(l->rebind_pool, "util_ldap_rebind");
            }
    #endif
    
            if (p) {
                p->next = l;
            }
            else {
                st->connections = l;
            }
        }
    
    #if APR_HAS_THREADS
        apr_thread_mutex_unlock(st->mutex);
    #endif
        l->r = r;
        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(st, r);
    
        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(st, r);
    
        /* 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(st, r);
    
            /* 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(st, r);
                ldc->reason = "DN Comparison TRUE (cached)";
                return LDAP_COMPARE_TRUE;
            }
    
            /* unlock this read lock */
            ldap_cache_unlock(st, r);
        }
    
    start_over:
        if (failures > st->retries) {
            return result;
        }
    
        if (failures > 0 && st->retry_delay > 0) {
            apr_sleep(st->retry_delay);
        }
    
        /* make a server connection */
        if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
            /* connect to server failed */
            return result;
        }
    
        /* search for reqdn */
        result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE,
                                   "(objectclass=*)", NULL, 1,
                                   NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
        if (AP_LDAP_IS_SERVER_DOWN(result))
        {
            ldc->reason = "DN Comparison ldap_search_ext_s() "
                          "failed with server down";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            goto start_over;
        }
        if (result == LDAP_TIMEOUT && failures == 0) {
            /*
             * we are reusing a connection that doesn't seem to be active anymore
             * (firewall state drop?), let's try a new connection.
             */
            ldc->reason = "DN Comparison ldap_search_ext_s() "
                          "failed with timeout";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            goto start_over;
        }
        if (result != LDAP_SUCCESS) {
            /* search for reqdn failed - no match */
            ldc->reason = "DN Comparison ldap_search_ext_s() failed";
            return result;
        }
    
        ldc->last_backend_conn = r->request_time;
        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(st, r);
                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(st, r);
            }
            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(st, r);
        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(st, r);
    
        if (curl) {
            /* make a comparison to the cache */
            ldap_cache_lock(st, r);
            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;
            the_compare_node.sgl_processed = 0;
            the_compare_node.subgroupList = NULL;
    
            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 */
                    if (LDAP_COMPARE_TRUE == compare_nodep->result) {
                        ldc->reason = "Comparison true (cached)";
                    }
                    else if (LDAP_COMPARE_FALSE == compare_nodep->result) {
                        ldc->reason = "Comparison false (cached)";
                    }
                    else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) {
                        ldc->reason = "Comparison no such attribute (cached)";
                    }
                    else {
                        ldc->reason = apr_psprintf(r->pool, 
                                                  "Comparison undefined: (%d): %s (adding to cache)", 
                                                  result, ldap_err2string(result));
                    }
    
                    /* record the result code to return with the reason... */
                    result = compare_nodep->result;
                    /* and unlock this read lock */
                    ldap_cache_unlock(st, r);
    
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, 
                                  "ldap_compare_s(%pp, %s, %s, %s) = %s (cached)", 
                                  ldc->ldap, dn, attrib, value, ldap_err2string(result));
                    return result;
                }
            }
            /* unlock this read lock */
            ldap_cache_unlock(st, r);
        }
    
    start_over:
        if (failures > st->retries) {
            return result;
        }
    
        if (failures > 0 && st->retry_delay > 0) {
            apr_sleep(st->retry_delay);
        }
    
        if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
            /* connect failed */
            return result;
        }
    
        result = ldap_compare_s(ldc->ldap,
                                (char *)dn,
                                (char *)attrib,
                                (char *)value);
        if (AP_LDAP_IS_SERVER_DOWN(result)) {
            /* connection failed - try again */
            ldc->reason = "ldap_compare_s() failed with server down";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            goto start_over;
        }
        if (result == LDAP_TIMEOUT && failures == 0) {
            /*
             * we are reusing a connection that doesn't seem to be active anymore
             * (firewall state drop?), let's try a new connection.
             */
            ldc->reason = "ldap_compare_s() failed with timeout";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            goto start_over;
        }
    
        ldc->last_backend_conn = r->request_time;
        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(st, r);
                the_compare_node.lastcompare = curtime;
                the_compare_node.result = result;
                the_compare_node.sgl_processed = 0;
                the_compare_node.subgroupList = NULL;
    
                /* 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))
                {
                    void *junk;
    
                    junk = util_ald_cache_insert(curl->compare_cache,
                                                 &the_compare_node);
                    if (junk == NULL) {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01287)
                                      "cache_compare: Cache insertion failure.");
                    }
                }
                else {
                    compare_nodep->lastcompare = curtime;
                    compare_nodep->result = result;
                }
                ldap_cache_unlock(st, r);
            }
    
            if (LDAP_COMPARE_TRUE == result) {
                ldc->reason = "Comparison true (adding to cache)";
            }
            else if (LDAP_COMPARE_FALSE == result) {
                ldc->reason = "Comparison false (adding to cache)";
            }
            else if (LDAP_NO_SUCH_ATTRIBUTE == result) {
                ldc->reason = "Comparison no such attribute (adding to cache)";
            }
            else {
                ldc->reason = apr_psprintf(r->pool, 
                                           "Comparison undefined: (%d): %s (adding to cache)", 
                                            result, ldap_err2string(result));
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, 
                      "ldap_compare_s(%pp, %s, %s, %s) = %s", 
                      ldc->ldap, dn, attrib, value, ldap_err2string(result));
        return result;
    }
    
    
    static util_compare_subgroup_t* uldap_get_subgroups(request_rec *r,
                                                        util_ldap_connection_t *ldc,
                                                        const char *url,
                                                        const char *dn,
                                                        char **subgroupAttrs,
                                                        apr_array_header_t *subgroupclasses)
    {
        int failures = 0;
        int result = LDAP_COMPARE_FALSE;
        util_compare_subgroup_t *res = NULL;
        LDAPMessage *sga_res, *entry;
        struct mod_auth_ldap_groupattr_entry_t *sgc_ents;
        apr_array_header_t *subgroups = apr_array_make(r->pool, 20, sizeof(char *));
        util_ldap_state_t *st = (util_ldap_state_t *)
                                ap_get_module_config(r->server->module_config,
                                                     &ldap_module);
    
        sgc_ents = (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
    
        if (!subgroupAttrs) {
            return res;
        }
    
    start_over:
        /*
         * 3.B. The cache didn't have any subgrouplist yet. Go check for subgroups.
         */
        if (failures > st->retries) {
            return res;
        }
    
        if (failures > 0 && st->retry_delay > 0) {
            apr_sleep(st->retry_delay);
        }
    
    
        if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
            /* connect failed */
            return res;
        }
    
        /* try to do the search */
        result = ldap_search_ext_s(ldc->ldap, (char *)dn, LDAP_SCOPE_BASE,
                                   NULL, subgroupAttrs, 0,
                                   NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &sga_res);
        if (AP_LDAP_IS_SERVER_DOWN(result)) {
            ldc->reason = "ldap_search_ext_s() for subgroups failed with server"
                          " down";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            goto start_over;
        }
        if (result == LDAP_TIMEOUT && failures == 0) {
            /*
             * we are reusing a connection that doesn't seem to be active anymore
             * (firewall state drop?), let's try a new connection.
             */
            ldc->reason = "ldap_search_ext_s() for subgroups failed with timeout";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            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 subgroups failed";
            return res;
        }
    
        ldc->last_backend_conn = r->request_time;
        entry = ldap_first_entry(ldc->ldap, sga_res);
    
        /*
         * Get values for the provided sub-group attributes.
         */
        if (subgroupAttrs) {
            int indx = 0, tmp_sgcIndex;
    
            while (subgroupAttrs[indx]) {
                char **values;
                int val_index = 0;
    
                /* Get *all* matching "member" values from this group. */
                values = ldap_get_values(ldc->ldap, entry, subgroupAttrs[indx]);
    
                if (values) {
                    val_index = 0;
                    /*
                     * Now we are going to pare the subgroup members of this group
                     * to *just* the subgroups, add them to the compare_nodep, and
                     * then proceed to check the new level of subgroups.
                     */
                    while (values[val_index]) {
                        /* Check if this entry really is a group. */
                        tmp_sgcIndex = 0;
                        result = LDAP_COMPARE_FALSE;
                        while ((tmp_sgcIndex < subgroupclasses->nelts)
                               && (result != LDAP_COMPARE_TRUE)) {
                            result = uldap_cache_compare(r, ldc, url,
                                                         values[val_index],
                                                         "objectClass",
                                                         sgc_ents[tmp_sgcIndex].name
                                                         );
    
                            if (result != LDAP_COMPARE_TRUE) {
                                tmp_sgcIndex++;
                            }
                        }
                        /* It's a group, so add it to the array.  */
                        if (result == LDAP_COMPARE_TRUE) {
                            char **newgrp = (char **) apr_array_push(subgroups);
                            *newgrp = apr_pstrdup(r->pool, values[val_index]);
                        }
                        val_index++;
                    }
                    ldap_value_free(values);
                }
                indx++;
            }
        }
    
        ldap_msgfree(sga_res);
    
        if (subgroups->nelts > 0) {
            /* We need to fill in tmp_local_subgroups using the data from LDAP */
            int sgindex;
            char **group;
            res = apr_pcalloc(r->pool, sizeof(util_compare_subgroup_t));
            res->subgroupDNs  = apr_palloc(r->pool,
                                           sizeof(char *) * (subgroups->nelts));
            for (sgindex = 0; (group = apr_array_pop(subgroups)); sgindex++) {
                res->subgroupDNs[sgindex] = apr_pstrdup(r->pool, *group);
            }
            res->len = sgindex;
        }
    
        return res;
    }
    
    
    /*
     * Does a recursive lookup operation to try to find a user within (cached)
     * nested groups. It accepts a cache that it will use to lookup previous
     * compare attempts. 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
     *
     * DON'T CALL THIS UNLESS YOU CALLED uldap_cache_compare FIRST!!!!!
     *
     *
     * 1. Call uldap_cache_compare for each subgroupclass value to check the
     *    generic, user-agnostic, cached group entry. This will create a new generic
     *    cache entry if there
     *    wasn't one. If nothing returns LDAP_COMPARE_TRUE skip to step 5 since we
     *    have no groups.
     * 2. Lock The cache and get the generic cache entry.
     * 3. Check if there is already a subgrouplist in this generic group's cache
     *    entry.
     *    A. If there is, go to step 4.
     *    B. If there isn't:
     *       i)   Use ldap_search to get the full list
     *            of subgroup "members" (which may include non-group "members").
     *       ii)  Use uldap_cache_compare to strip the list down to just groups.
     *       iii) Lock and add this stripped down list to the cache of the generic
     *            group.
     * 4. Loop through the sgl and call uldap_cache_compare (using the user info)
     *    for each
     *    subgroup to see if the subgroup contains the user and to get the subgroups
     *    added to the
     *    cache (with user-afinity, if they aren't already there).
     *    A. If the user is in the subgroup, then we'll be returning
     *       LDAP_COMPARE_TRUE.
     *    B. if the user isn't in the subgroup (LDAP_COMPARE_FALSE via
     *       uldap_cache_compare) then recursively call this function to get the
     *       sub-subgroups added...
     * 5. Cleanup local allocations.
     * 6. Return the final result.
     */
    
    static int uldap_cache_check_subgroups(request_rec *r,
                                           util_ldap_connection_t *ldc,
                                           const char *url, const char *dn,
                                           const char *attrib, const char *value,
                                           char **subgroupAttrs,
                                           apr_array_header_t *subgroupclasses,
                                           int cur_subgroup_depth,
                                           int max_subgroup_depth)
    {
        int result = LDAP_COMPARE_FALSE;
        util_url_node_t *curl;
        util_url_node_t curnode;
        util_compare_node_t *compare_nodep;
        util_compare_node_t the_compare_node;
        util_compare_subgroup_t *tmp_local_sgl = NULL;
        int sgl_cached_empty = 0, sgindex = 0, base_sgcIndex = 0;
        struct mod_auth_ldap_groupattr_entry_t *sgc_ents =
                (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
        util_ldap_state_t *st = (util_ldap_state_t *)
                                ap_get_module_config(r->server->module_config,
                                                     &ldap_module);
    
        /*
         * Stop looking at deeper levels of nested groups if we have reached the
         * max. Since we already checked the top-level group in uldap_cache_compare,
         * we don't need to check it again here - so if max_subgroup_depth is set
         * to 0, we won't check it (i.e. that is why we check < rather than <=).
         * We'll be calling uldap_cache_compare from here to check if the user is
         * in the next level before we recurse into that next level looking for
         * more subgroups.
         */
        if (cur_subgroup_depth >= max_subgroup_depth) {
            return LDAP_COMPARE_FALSE;
        }
    
        /*
         * 1. Check the "groupiness" of the specified basedn. Stopping at the first
         *    TRUE return.
         */
        while ((base_sgcIndex < subgroupclasses->nelts)
               && (result != LDAP_COMPARE_TRUE)) {
            result = uldap_cache_compare(r, ldc, url, dn, "objectClass",
                                         sgc_ents[base_sgcIndex].name);
            if (result != LDAP_COMPARE_TRUE) {
                base_sgcIndex++;
            }
        }
    
        if (result != LDAP_COMPARE_TRUE) {
            ldc->reason = "DN failed group verification.";
            return result;
        }
    
        /*
         * 2. Find previously created cache entry and check if there is already a
         *    subgrouplist.
         */
        ldap_cache_lock(st, r);
        curnode.url = url;
        curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
        ldap_cache_unlock(st, r);
    
        if (curl && curl->compare_cache) {
            /* make a comparison to the cache */
            ldap_cache_lock(st, r);
    
            the_compare_node.dn = (char *)dn;
            the_compare_node.attrib = (char *)"objectClass";
            the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
            the_compare_node.result = 0;
            the_compare_node.sgl_processed = 0;
            the_compare_node.subgroupList = NULL;
    
            compare_nodep = util_ald_cache_fetch(curl->compare_cache,
                                                 &the_compare_node);
    
            if (compare_nodep != NULL) {
                /*
                 * Found the generic group entry... but the user isn't in this
                 * group or we wouldn't be here.
                 */
                if (compare_nodep->sgl_processed) {
                    if (compare_nodep->subgroupList) {
                        /* Make a local copy of the subgroup list */
                        int i;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01288)
                                      "Making local copy of SGL for "
                                      "group (%s)(objectClass=%s) ",
                                      dn, (char *)sgc_ents[base_sgcIndex].name);
                        tmp_local_sgl = apr_pcalloc(r->pool,
                                                    sizeof(util_compare_subgroup_t));
                        tmp_local_sgl->len = compare_nodep->subgroupList->len;
                        tmp_local_sgl->subgroupDNs =
                            apr_palloc(r->pool,
                                       sizeof(char *) * compare_nodep->subgroupList->len);
                        for (i = 0; i < compare_nodep->subgroupList->len; i++) {
                            tmp_local_sgl->subgroupDNs[i] =
                                apr_pstrdup(r->pool,
                                            compare_nodep->subgroupList->subgroupDNs[i]);
                        }
                    }
                    else {
                        sgl_cached_empty = 1;
                    }
                }
            }
            ldap_cache_unlock(st, r);
        }
    
        if (!tmp_local_sgl && !sgl_cached_empty) {
            /* No Cached SGL, retrieve from LDAP */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01289)
                          "no cached SGL for %s, retrieving from LDAP", dn);
            tmp_local_sgl = uldap_get_subgroups(r, ldc, url, dn, subgroupAttrs,
                                                subgroupclasses);
            if (!tmp_local_sgl) {
                /* No SGL aailable via LDAP either */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01290) "no subgroups for %s",
                              dn);
            }
    
          if (curl && curl->compare_cache) {
            /*
             * Find the generic group cache entry and add the sgl we just retrieved.
             */
            ldap_cache_lock(st, r);
    
            the_compare_node.dn = (char *)dn;
            the_compare_node.attrib = (char *)"objectClass";
            the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
            the_compare_node.result = 0;
            the_compare_node.sgl_processed = 0;
            the_compare_node.subgroupList = NULL;
    
            compare_nodep = util_ald_cache_fetch(curl->compare_cache,
                                                 &the_compare_node);
    
            if (compare_nodep == NULL) {
                /*
                 * The group entry we want to attach our SGL to doesn't exist.
                 * We only got here if we verified this DN was actually a group
                 * based on the objectClass, but we can't call the compare function
                 * while we already hold the cache lock -- only the insert.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01291)
                              "Cache entry for %s doesn't exist", dn);
                the_compare_node.result = LDAP_COMPARE_TRUE;
                util_ald_cache_insert(curl->compare_cache, &the_compare_node);
                compare_nodep = util_ald_cache_fetch(curl->compare_cache,
                                                     &the_compare_node);
                if (compare_nodep == NULL) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01292)
                                  "util_ldap: Couldn't retrieve group entry "
                                  "for %s from cache",
                                  dn);
                }
            }
    
            /*
             * We have a valid cache entry and a locally generated SGL.
             * Attach the SGL to the cache entry
             */
            if (compare_nodep && !compare_nodep->sgl_processed) {
                if (!tmp_local_sgl) {
                    /* We looked up an SGL for a group and found it to be empty */
                    if (compare_nodep->subgroupList == NULL) {
                        compare_nodep->sgl_processed = 1;
                    }
                }
                else {
                    util_compare_subgroup_t *sgl_copy =
                        util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl);
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01293)
                                 "Copying local SGL of len %d for group %s into cache",
                                 tmp_local_sgl->len, dn);
                    if (sgl_copy) {
                        if (compare_nodep->subgroupList) {
                            util_ald_sgl_free(curl->compare_cache,
                                              &(compare_nodep->subgroupList));
                        }
                        compare_nodep->subgroupList = sgl_copy;
                        compare_nodep->sgl_processed = 1;
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01294)
                                     "Copy of SGL failed to obtain shared memory, "
                                     "couldn't update cache");
                    }
                }
            }
            ldap_cache_unlock(st, r);
          }
        }
    
        /*
         * tmp_local_sgl has either been created, or copied out of the cache
         * If tmp_local_sgl is NULL, there are no subgroups to process and we'll
         * return false
         */
        result = LDAP_COMPARE_FALSE;
        if (!tmp_local_sgl) {
            return result;
        }
    
        while ((result != LDAP_COMPARE_TRUE) && (sgindex < tmp_local_sgl->len)) {
            const char *group = NULL;
            group = tmp_local_sgl->subgroupDNs[sgindex];
            /*
             * 4. Now loop through the subgroupList and call uldap_cache_compare
             * to check for the user.
             */
            result = uldap_cache_compare(r, ldc, url, group, attrib, value);
            if (result == LDAP_COMPARE_TRUE) {
                /*
                 * 4.A. We found the user in the subgroup. Return
                 * LDAP_COMPARE_TRUE.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01295)
                              "Found user %s in a subgroup (%s) at level %d of %d.",
                              r->user, group, cur_subgroup_depth+1,
                              max_subgroup_depth);
            }
            else {
                /*
                 * 4.B. We didn't find the user in this subgroup, so recurse into
                 * it and keep looking.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01296)
                              "User %s not found in subgroup (%s) at level %d of "
                              "%d.", r->user, group, cur_subgroup_depth+1,
                              max_subgroup_depth);
                result = uldap_cache_check_subgroups(r, ldc, url, group, attrib,
                                                     value, subgroupAttrs,
                                                     subgroupclasses,
                                                     cur_subgroup_depth+1,
                                                     max_subgroup_depth);
            }
            sgindex++;
        }
    
        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(st, r);
        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(st, r);
    
        if (curl) {
            ldap_cache_lock(st, r);
            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 = apr_pstrdup(r->pool, search_nodep->dn);
                    if (attrs) {
                        int i;
                        *retvals = apr_palloc(r->pool, sizeof(char *) * search_nodep->numvals);
                        for (i = 0; i < search_nodep->numvals; i++) {
                            (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
                        }
                    }
                    ldap_cache_unlock(st, r);
                    ldc->reason = "Authentication successful (cached)";
                    return LDAP_SUCCESS;
                }
            }
            /* unlock this read lock */
            ldap_cache_unlock(st, r);
        }
    
        /*
         * 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 > st->retries) {
            return result;
        }
    
        if (failures > 0 && st->retry_delay > 0) {
            apr_sleep(st->retry_delay);
        }
    
        if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
            return result;
        }
    
        /* try do the search */
        result = ldap_search_ext_s(ldc->ldap,
                                   (char *)basedn, scope,
                                   (char *)filter, attrs, 0,
                                   NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
        if (AP_LDAP_IS_SERVER_DOWN(result))
        {
            ldc->reason = "ldap_search_ext_s() for user failed with server down";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            goto start_over;
        }
    
        if (result == LDAP_TIMEOUT) {
            ldc->reason = "ldap_search_ext_s() for user failed with timeout";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            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.
         */
        ldc->last_backend_conn = r->request_time;
        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)
         */
        result = uldap_simple_bind(ldc, (char *)*binddn, (char *)bindpw,
                                   st->opTimeout);
        if (AP_LDAP_IS_SERVER_DOWN(result) ||
            (result == LDAP_TIMEOUT && failures == 0)) {
            if (AP_LDAP_IS_SERVER_DOWN(result))
                ldc->reason = "ldap_simple_bind() to check user credentials "
                              "failed with server down";
            else
                ldc->reason = "ldap_simple_bind() to check user credentials "
                              "timed out";
            ldap_msgfree(res);
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            goto start_over;
        }
    
        /* failure? if so - return */
        if (result != LDAP_SUCCESS) {
            ldc->reason = "ldap_simple_bind() 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.
             */
            ldc->must_rebind = 1;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp used for authn, must be rebound", ldc);
        }
    
        /*
         * 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(st, r);
            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(st, r);
        }
        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(st, r);
        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(st, r);
    
        if (curl) {
            ldap_cache_lock(st, r);
            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 = apr_pstrdup(r->pool, search_nodep->dn);
                    if (attrs) {
                        int i;
                        *retvals = apr_palloc(r->pool, sizeof(char *) * search_nodep->numvals);
                        for (i = 0; i < search_nodep->numvals; i++) {
                            (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
                        }
                    }
                    ldap_cache_unlock(st, r);
                    ldc->reason = "Search successful (cached)";
                    return LDAP_SUCCESS;
                }
            }
            /* unlock this read lock */
            ldap_cache_unlock(st, r);
        }
    
        /*
         * 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 > st->retries) {
            return result;
        }
    
        if (failures > 0 && st->retry_delay > 0) {
            apr_sleep(st->retry_delay);
        }
    
        if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
            return result;
        }
    
        /* try do the search */
        result = ldap_search_ext_s(ldc->ldap,
                                   (char *)basedn, scope,
                                   (char *)filter, attrs, 0,
                                   NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
        if (AP_LDAP_IS_SERVER_DOWN(result))
        {
            ldc->reason = "ldap_search_ext_s() for user failed with server down";
            uldap_connection_unbind(ldc);
            failures++;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
            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.
         */
        ldc->last_backend_conn = r->request_time;
        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);
    
        /*
         * 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(st, r);
            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(st, r);
        }
    
        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);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        st->cache_bytes = atol(bytes);
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01297)
                     "ldap cache: Setting shared memory cache size to "
                     "%" APR_SIZE_T_FMT " bytes.",
                     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);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        if (file) {
            st->cache_file = ap_server_root_relative(st->pool, file);
        }
        else {
            st->cache_file = NULL;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01298)
                     "LDAP cache: Setting shared memory cache file to %s.",
                     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);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        st->search_cache_ttl = atol(ttl) * 1000000;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01299)
                     "ldap cache: Setting cache TTL to %ld microseconds.",
                     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);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        st->search_cache_size = atol(size);
        if (st->search_cache_size < 0) {
            st->search_cache_size = 0;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01300)
                     "ldap cache: Setting search cache size to %ld entries.",
                     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);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        st->compare_cache_ttl = atol(ttl) * APR_USEC_PER_SEC;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01301)
                     "ldap cache: Setting operation cache TTL to %ld microseconds.",
                     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);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        st->compare_cache_size = atol(size);
        if (st->compare_cache_size < 0) {
            st->compare_cache_size = 0;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01302)
                     "ldap cache: Setting operation cache size to %ld entries.",
                     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 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, 0, cmd->server, APLOGNO(01303)
                          "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, APLOGNO(01304)
                             "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_config_t *dc =  config;
        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 CA_DER, CA_BASE64, "
                                               "CERT_DER, CERT_BASE64, "
                                               "CERT_NICKNAME, CERT_PFX, "
                                               "KEY_DER, KEY_BASE64, KEY_PFX",
                                               type);
            }
            else if ( 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 CA_DER, CA_BASE64, "
                                               "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, 0, cmd->server, APLOGNO(01305)
                          "LDAP: SSL trusted client cert - %s (type %s)",
                           file, type);
    
        /* add the certificate to the client array */
        cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(dc->client_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, APLOGNO(01306)
                             "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, 0, cmd->server, APLOGNO(01307)
                          "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);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01308)
                          "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)
    {
    #ifdef LDAP_OPT_NETWORK_TIMEOUT
        util_ldap_state_t *st =
            (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
                                                      &ldap_module);
    #endif
        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, 0, cmd->server, APLOGNO(01309)
                     "ldap connection: Setting connection timeout to %ld seconds.",
                     st->connectionTimeout);
    #else
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, APLOGNO(01310)
                     "LDAP: Connection timeout option not supported by the "
                     "LDAP SDK in use." );
    #endif
    
        return NULL;
    }
    
    
    static const char *util_ldap_set_chase_referrals(cmd_parms *cmd,
                                                     void *config,
                                                     const char *arg)
    {
        util_ldap_config_t *dc =  config;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01311)
                          "LDAP: Setting referral chasing %s", arg);
    
        if (0 == strcasecmp(arg, "on")) {
            dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_ON;
        }
        else if (0 == strcasecmp(arg, "off")) {
            dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_OFF;
        }
        else if (0 == strcasecmp(arg, "default")) {
            dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_SDKDEFAULT;
        }
        else {
            return "LDAPReferrals must be 'on', 'off', or 'default'";
        }
    
        return(NULL);
    }
    
    static const char *util_ldap_set_debug_level(cmd_parms *cmd,
                                                 void *config,
                                                 const char *arg) {
    #ifdef AP_LDAP_OPT_DEBUG
        util_ldap_state_t *st =
            (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
                                                      &ldap_module);
    #endif
    
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
    
    #ifndef AP_LDAP_OPT_DEBUG
        return "This directive is not supported with the currently linked LDAP library";
    #else
        st->debug_level = atoi(arg);
        return NULL;
    #endif
    }
    
    static const char *util_ldap_set_referral_hop_limit(cmd_parms *cmd,
                                                        void *config,
                                                        const char *hop_limit)
    {
        util_ldap_config_t *dc =  config;
    
        dc->ReferralHopLimit = atol(hop_limit);
    
        if (dc->ReferralHopLimit <= 0) {
            return "LDAPReferralHopLimit must be greater than zero (Use 'LDAPReferrals Off' to disable referral chasing)";
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01312)
                     "LDAP: Limit chased referrals to maximum of %d hops.",
                     dc->ReferralHopLimit);
    
        return NULL;
    }
    
    static void *util_ldap_create_dir_config(apr_pool_t *p, char *d)
    {
        util_ldap_config_t *dc =
            (util_ldap_config_t *) apr_pcalloc(p,sizeof(util_ldap_config_t));
    
        /* defaults are AP_LDAP_CHASEREFERRALS_ON and AP_LDAP_DEFAULT_HOPLIMIT */
        dc->client_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
        dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_ON;
        dc->ReferralHopLimit = AP_LDAP_HOPLIMIT_UNSET;
    
        return dc;
    }
    
    static const char *util_ldap_set_op_timeout(cmd_parms *cmd,
                                                void *dummy,
                                                const char *val)
    {
        long timeout;
        char *endptr;
        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;
        }
    
        timeout = strtol(val, &endptr, 10);
        if ((val == endptr) || (*endptr != '\0')) {
            return "Timeout not numerical";
        }
        if (timeout < 0) {
            return "Timeout must be non-negative";
        }
    
        if (timeout) {
            if (!st->opTimeout) {
                st->opTimeout = apr_pcalloc(cmd->pool, sizeof(struct timeval));
            }
            st->opTimeout->tv_sec = timeout;
        }
        else {
            st->opTimeout = NULL;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01313)
                     "ldap connection: Setting op timeout to %ld seconds.",
                     timeout);
    
    #ifndef LDAP_OPT_TIMEOUT
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01314)
                     "LDAP: LDAP_OPT_TIMEOUT option not supported by the "
                     "LDAP library in use. Using LDAPTimeout value as search "
                     "timeout only." );
    #endif
    
        return NULL;
    }
    
    static const char *util_ldap_set_conn_ttl(cmd_parms *cmd,
                                              void *dummy,
                                              const char *val)
    {
        apr_interval_time_t timeout = -1;
        util_ldap_state_t *st =
            (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
                                                      &ldap_module);
    
        /* Negative values mean AP_LDAP_CONNPOOL_INFINITE */
        if (val[0] != '-' &&
            ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS) {
            return "LDAPConnectionPoolTTL has wrong format";
        }
    
        if (timeout < 0) {
            /* reserve -1 for default value */
            timeout = AP_LDAP_CONNPOOL_INFINITE;
        }
        st->connection_pool_ttl = timeout;
        return NULL;
    }
    
    static const char *util_ldap_set_retry_delay(cmd_parms *cmd,
                                                 void *dummy,
                                                 const char *val)
    {
        apr_interval_time_t timeout;
        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;
        }
    
        if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS) {
            return "LDAPRetryDelay has wrong format";
        }
    
        if (timeout < 0) {
            return "LDAPRetryDelay must be >= 0";
        }
    
        st->retry_delay = timeout;
        return NULL;
    }
    
    static const char *util_ldap_set_retries(cmd_parms *cmd,
                                             void *dummy,
                                             const char *val)
    {
        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;
        }
    
        st->retries = atoi(val);
        if (st->retries < 0) {
            return  "LDAPRetries must be >= 0";
        }
    
        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));
    
        /* Create a per vhost pool for mod_ldap to use, serialized with
         * st->mutex (also one per vhost).  both are replicated by fork(),
         * no shared memory managed by either.
         */
        apr_pool_create(&st->pool, p);
        apr_pool_tag(st->pool, "util_ldap_state");
    #if APR_HAS_THREADS
        apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool);
    #endif
    
        st->cache_bytes = 500000;
        st->search_cache_ttl = 600 * APR_USEC_PER_SEC; /* 10 minutes */
        st->search_cache_size = 1024;
        st->compare_cache_ttl = 600 * APR_USEC_PER_SEC; /* 10 minutes */
        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->secure = APR_LDAP_NONE;
        st->secure_set = 0;
        st->connectionTimeout = 10;
        st->opTimeout = apr_pcalloc(p, sizeof(struct timeval));
        st->opTimeout->tv_sec = 60;
        st->verify_svr_cert = 1;
        st->connection_pool_ttl = AP_LDAP_CONNPOOL_DEFAULT; /* no limit */
        st->retries = 3;
        st->retry_delay = 0; /* no delay */
    
        return st;
    }
    
    /* cache-related settings are not merged here, but in the post_config hook,
     * since the cache has not yet sprung to life
     */
    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 = overrides->pool;
    #if APR_HAS_THREADS
        st->mutex = overrides->mutex;
    #endif
    
        /* The cache settings can not be modified in a
            virtual host since all server use the same
            shared memory cache. */
        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 = NULL;
        st->ssl_supported = 0; /* not known until post-config and re-merged */
        st->global_certs = apr_array_append(p, base->global_certs,
                                               overrides->global_certs);
        st->secure = (overrides->secure_set == 0) ? base->secure
                                                  : overrides->secure;
    
        /* These LDAP connection settings can not be overwritten in
            a virtual host. Once set in the base server, they must
            remain the same. None of the LDAP SDKs seem to be able
            to handle setting the verify_svr_cert flag on a
            per-connection basis.  The OpenLDAP client appears to be
            able to handle the connection timeout per-connection
            but the Novell SDK cannot.  Allowing the timeout to
            be set by each vhost is of little value so rather than
            trying to make special exceptions for one LDAP SDK, GLOBAL_ONLY
            is being enforced on this setting as well. */
        st->connectionTimeout = base->connectionTimeout;
        st->opTimeout = base->opTimeout;
        st->verify_svr_cert = base->verify_svr_cert;
        st->debug_level = base->debug_level;
    
        st->connection_pool_ttl = (overrides->connection_pool_ttl == AP_LDAP_CONNPOOL_DEFAULT) ?
                                    base->connection_pool_ttl : overrides->connection_pool_ttl;
    
        st->retries = base->retries;
        st->retry_delay = base->retry_delay;
    
        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_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                    apr_pool_t *ptemp)
    {
        apr_status_t result;
    
        result = ap_mutex_register(pconf, ldap_cache_mutex_type, NULL,
                                   APR_LOCK_DEFAULT, 0);
        if (result != APR_SUCCESS) {
            return result;
        }
    
        return OK;
    }
    
    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;
        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);
    
        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.*/
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
    
    #if APR_HAS_SHARED_MEMORY
            /*
             * If we are using shared memory caching and the cache file already
             * exists then delete it.  Otherwise we are going to run into problems
             * creating the shared memory.
             */
            if (st->cache_file && st->cache_bytes > 0) {
                char *lck_file = apr_pstrcat(ptemp, st->cache_file, ".lck",
                                             NULL);
                apr_file_remove(lck_file, ptemp);
            }
    #endif
            return OK;
        }
    
    #if APR_HAS_SHARED_MEMORY
        /*
         * initializing cache if we don't already have a shm address
         */
        if (!st->cache_shm) {
    #endif
            result = util_ldap_cache_init(p, st);
            if (result != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, result, s, APLOGNO(01315)
                             "LDAP cache: could not create shared memory segment");
                return DONE;
            }
    
            result = ap_global_mutex_create(&st->util_ldap_cache_lock, NULL,
                                            ldap_cache_mutex_type, NULL, s, p, 0);
            if (result != APR_SUCCESS) {
                return result;
            }
    
            /* 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);
                st_vhost->util_ldap_cache = st->util_ldap_cache;
                st_vhost->util_ldap_cache_lock = st->util_ldap_cache_lock;
    #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, result, s, APLOGNO(01316)
                             "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
                s_vhost = s_vhost->next;
            }
    #if APR_HAS_SHARED_MEMORY
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01317)
                         "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_INFO, 0, s, APLOGNO(01318) "%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(ptemp, 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_INFO, 0, s, APLOGNO(01319)
                         "LDAP: SSL support available" );
        }
        else {
            st->ssl_supported = 0;
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01320)
                         "LDAP: SSL support unavailable%s%s",
                         result_err ? ": " : "",
                         result_err ? result_err->reason : "");
        }
    
        /* ssl_supported is really a global setting */
        s_vhost = s->next;
        while (s_vhost) {
            st_vhost = (util_ldap_state_t *)
                       ap_get_module_config(s_vhost->module_config,
                                            &ldap_module);
    
            st_vhost->ssl_supported = st->ssl_supported;
            s_vhost = s_vhost->next;
        }
    
        /* Initialize the rebind callback's cross reference list. */
        (void) uldap_rebind_init(p);
    
    #ifdef AP_LDAP_OPT_DEBUG
        if (st->debug_level > 0) {
            result = ldap_set_option(NULL, AP_LDAP_OPT_DEBUG, &st->debug_level);
            if (result != LDAP_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01321)
                        "LDAP: Could not set the LDAP library debug level to %d:(%d) %s",
                        st->debug_level, result, ldap_err2string(result));
            }
        }
    #endif
    
        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,
                  apr_global_mutex_lockfile(st->util_ldap_cache_lock), p);
        if (sts != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, sts, s, APLOGNO(01322)
                         "Failed to initialise global mutex %s in child process",
                         ldap_cache_mutex_type);
        }
    }
    
    static const 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: 500000)"),
    
        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 or -1 to disable the search 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 or -1 to disable the compare 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 arguments; the first argument is the cert "
                       "type of the second argument, 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. The second argument "
                       "specifes the file and/or directory containing the trusted CA "
                       "certificates (and global client certs for Netware) used to "
                       "validate the LDAP server. The third argument is an optional "
                       "passphrase if applicable."),
    
        AP_INIT_TAKE23("LDAPTrustedClientCert", util_ldap_set_trusted_client_cert,
                       NULL, OR_AUTHCFG,
                       "Takes three arguments: the first argument is the certificate "
                       "type of the second argument, 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. The second argument "
                       "specifies the file and/or directory containing the client "
                       "certificate, or certificate ID used to validate this LDAP "
                       "client.  The third argument 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)"),
    
        AP_INIT_TAKE1("LDAPReferrals", util_ldap_set_chase_referrals,
                      NULL, OR_AUTHCFG,
                      "Choose whether referrals are chased ['ON'|'OFF'|'DEFAULT'].  Default 'ON'"),
    
        AP_INIT_TAKE1("LDAPReferralHopLimit", util_ldap_set_referral_hop_limit,
                      NULL, OR_AUTHCFG,
                      "Limit the number of referral hops that LDAP can follow. "
                      "(Integer value, Consult LDAP SDK documentation for applicability and defaults"),
    
        AP_INIT_TAKE1("LDAPLibraryDebug", util_ldap_set_debug_level,
                      NULL, RSRC_CONF,
                      "Enable debugging in LDAP SDK (Default: off, values: SDK specific"),
    
        AP_INIT_TAKE1("LDAPTimeout", util_ldap_set_op_timeout,
                      NULL, RSRC_CONF,
                      "Specify the LDAP bind/search timeout in seconds "
                      "(0 = no limit). Default: 60"),
        AP_INIT_TAKE1("LDAPConnectionPoolTTL", util_ldap_set_conn_ttl,
                      NULL, RSRC_CONF,
                      "Specify the maximum amount of time a bound connection can sit "
                      "idle and still be considered valid for reuse"
                      "(0 = no pool, -1 = no limit, n = time in seconds). Default: -1"),
        AP_INIT_TAKE1("LDAPRetries", util_ldap_set_retries,
                      NULL, RSRC_CONF,
                      "Specify the number of times a failed LDAP operation should be retried "
                      "(0 = no retries). Default: 3"),
        AP_INIT_TAKE1("LDAPRetryDelay", util_ldap_set_retry_delay,
                      NULL, RSRC_CONF,
                      "Specify the delay between retries of a failed LDAP operation "
                      "(0 = no delay). Default: 0"),
    
    
        {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_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);
        APR_REGISTER_OPTIONAL_FN(uldap_cache_check_subgroups);
    
        ap_hook_pre_config(util_ldap_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        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);
    }
    
    AP_DECLARE_MODULE(ldap) = {
       STANDARD20_MODULE_STUFF,
       util_ldap_create_dir_config, /* 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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/mod_ldap.mak��������������������������������������������������������������0000664�0001751�0001751�00000024121�12701473373�017472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_ldap.dsp
    !IF "$(CFG)" == ""
    CFG=mod_ldap - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_ldap - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_ldap - Win32 Release" && "$(CFG)" != "mod_ldap - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ldap - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ldap.res"
    	-@erase "$(INTDIR)\mod_ldap_src.idb"
    	-@erase "$(INTDIR)\mod_ldap_src.pdb"
    	-@erase "$(INTDIR)\util_ldap.obj"
    	-@erase "$(INTDIR)\util_ldap_cache.obj"
    	-@erase "$(INTDIR)\util_ldap_cache_mgr.obj"
    	-@erase "$(OUTDIR)\mod_ldap.exp"
    	-@erase "$(OUTDIR)\mod_ldap.lib"
    	-@erase "$(OUTDIR)\mod_ldap.pdb"
    	-@erase "$(OUTDIR)\mod_ldap.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ldap_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ldap.so" /d LONG_NAME="ldap_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ldap.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ldap.pdb" /debug /out:"$(OUTDIR)\mod_ldap.so" /implib:"$(OUTDIR)\mod_ldap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\util_ldap.obj" \
    	"$(INTDIR)\util_ldap_cache.obj" \
    	"$(INTDIR)\util_ldap_cache_mgr.obj" \
    	"$(INTDIR)\mod_ldap.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_ldap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ldap.so"
       if exist .\Release\mod_ldap.so.manifest mt.exe -manifest .\Release\mod_ldap.so.manifest -outputresource:.\Release\mod_ldap.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_ldap - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_ldap.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ldap.res"
    	-@erase "$(INTDIR)\mod_ldap_src.idb"
    	-@erase "$(INTDIR)\mod_ldap_src.pdb"
    	-@erase "$(INTDIR)\util_ldap.obj"
    	-@erase "$(INTDIR)\util_ldap_cache.obj"
    	-@erase "$(INTDIR)\util_ldap_cache_mgr.obj"
    	-@erase "$(OUTDIR)\mod_ldap.exp"
    	-@erase "$(OUTDIR)\mod_ldap.lib"
    	-@erase "$(OUTDIR)\mod_ldap.pdb"
    	-@erase "$(OUTDIR)\mod_ldap.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ldap_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ldap.so" /d LONG_NAME="ldap_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ldap.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ldap.pdb" /debug /out:"$(OUTDIR)\mod_ldap.so" /implib:"$(OUTDIR)\mod_ldap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so 
    LINK32_OBJS= \
    	"$(INTDIR)\util_ldap.obj" \
    	"$(INTDIR)\util_ldap_cache.obj" \
    	"$(INTDIR)\util_ldap_cache_mgr.obj" \
    	"$(INTDIR)\mod_ldap.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_ldap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ldap.so"
       if exist .\Debug\mod_ldap.so.manifest mt.exe -manifest .\Debug\mod_ldap.so.manifest -outputresource:.\Debug\mod_ldap.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_ldap.dep")
    !INCLUDE "mod_ldap.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_ldap.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_ldap - Win32 Release" || "$(CFG)" == "mod_ldap - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_ldap - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\ldap"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\ldap"
    
    !ELSEIF  "$(CFG)" == "mod_ldap - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\ldap"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\ldap"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ldap - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\ldap"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\ldap"
    
    !ELSEIF  "$(CFG)" == "mod_ldap - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\ldap"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\ldap"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ldap - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\ldap"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\ldap"
    
    !ELSEIF  "$(CFG)" == "mod_ldap - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\ldap"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\ldap"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_ldap - Win32 Release"
    
    
    "$(INTDIR)\mod_ldap.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ldap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_ldap.so" /d LONG_NAME="ldap_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_ldap - Win32 Debug"
    
    
    "$(INTDIR)\mod_ldap.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ldap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_ldap.so" /d LONG_NAME="ldap_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\util_ldap.c
    
    "$(INTDIR)\util_ldap.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\util_ldap_cache.c
    
    "$(INTDIR)\util_ldap_cache.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\util_ldap_cache_mgr.c
    
    "$(INTDIR)\util_ldap_cache_mgr.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/NWGNUmakefile�������������������������������������������������������������0000664�0001751�0001751�00000010646�11540562746�017552� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(NWOS) \
    			$(LDAPSDK)/inc \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	@lldapsdk.imp \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/mod_ldap.dsp��������������������������������������������������������������0000664�0001751�0001751�00000011210�11612604620�017472� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ldap.so" /d LONG_NAME="ldap_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ldap.so" /d LONG_NAME="ldap_module for Apache"
    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 /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 /out:".\Debug\mod_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_ldap.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_ldap - Win32 Release"
    # Name "mod_ldap - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\util_ldap.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\util_ldap.h
    # 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\httpd.rc
    # End Source File
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/ldap/Makefile.in���������������������������������������������������������������0000664�0001751�0001751�00000000267�10150161574�017264� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015754� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ratelimit.h��������������������������������������������������������0000664�0001751�0001751�00000004374�11737125415�020762� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_RATELIMIT_H_
    #define _MOD_RATELIMIT_H_
    
    /* Create a set of AP_RL_DECLARE(type), AP_RL_DECLARE_NONSTD(type) and
     * AP_RL_DECLARE_DATA with appropriate export and import tags for the platform
     */
    #if !defined(WIN32)
    #define AP_RL_DECLARE(type)            type
    #define AP_RL_DECLARE_NONSTD(type)     type
    #define AP_RL_DECLARE_DATA
    #elif defined(AP_RL_DECLARE_STATIC)
    #define AP_RL_DECLARE(type)            type __stdcall
    #define AP_RL_DECLARE_NONSTD(type)     type
    #define AP_RL_DECLARE_DATA
    #elif defined(AP_RL_DECLARE_EXPORT)
    #define AP_RL_DECLARE(type)            __declspec(dllexport) type __stdcall
    #define AP_RL_DECLARE_NONSTD(type)     __declspec(dllexport) type
    #define AP_RL_DECLARE_DATA             __declspec(dllexport)
    #else
    #define AP_RL_DECLARE(type)            __declspec(dllimport) type __stdcall
    #define AP_RL_DECLARE_NONSTD(type)     __declspec(dllimport) type
    #define AP_RL_DECLARE_DATA             __declspec(dllimport)
    #endif
    
    AP_RL_DECLARE_DATA extern const apr_bucket_type_t ap_rl_bucket_type_end;
    AP_RL_DECLARE_DATA extern const apr_bucket_type_t ap_rl_bucket_type_start;
    
    #define AP_RL_BUCKET_IS_END(e)         (e->type == &ap_rl_bucket_type_end)
    #define AP_RL_BUCKET_IS_START(e)         (e->type == &ap_rl_bucket_type_start)
    
    /* TODO: Make these Optional Functions, so that module load order doesn't matter. */
    AP_RL_DECLARE(apr_bucket*) ap_rl_end_create(apr_bucket_alloc_t *list);
    AP_RL_DECLARE(apr_bucket*) ap_rl_start_create(apr_bucket_alloc_t *list);
    
    #endif
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUmod_data����������������������������������������������������������0000664�0001751�0001751�00000010141�11660333246�020255� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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_data
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Data 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	=
    
    #
    # 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)/$(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)/$(NLM_NAME).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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	data_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUproxyhtml���������������������������������������������������������0000664�0001751�0001751�00000010631�11652776275�020575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(LIBXML2SDK)/include \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(AP_WORK)/modules/http \
    			$(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		+= \
    			-L$(LIBXML2SDK)/lib -llibxml2.lib \
    			$(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	= proxyhtml
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Proxy HTML 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	=
    
    #
    # 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)/$(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_proxy_html.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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_html_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_include.h����������������������������������������������������������0000664�0001751�0001751�00000007620�11637105701�020403� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_include.h
     * @brief Server Side Include Filter Extension Module for Apache
     *
     * @defgroup MOD_INCLUDE mod_include
     * @ingroup APACHE_MODS
     * @{
     */
    
    #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;
    
        /* the current request */
        request_rec  *r;
    
        /* 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 */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/Makefile.in������������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�020003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUcharsetl����������������������������������������������������������0000664�0001751�0001751�00000010312�11540546347�020317� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(NWOS) \
    			$(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	=
    
    #
    # 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 \
    	$(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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_deflate.mak��������������������������������������������������������0000664�0001751�0001751�00000024013�12701473373�020706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_deflate.dsp
    !IF "$(CFG)" == ""
    CFG=mod_deflate - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_deflate - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_deflate - Win32 Release" && "$(CFG)" != "mod_deflate - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_deflate - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_deflate.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_deflate.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_deflate.obj"
    	-@erase "$(INTDIR)\mod_deflate.res"
    	-@erase "$(INTDIR)\mod_deflate_src.idb"
    	-@erase "$(INTDIR)\mod_deflate_src.pdb"
    	-@erase "$(OUTDIR)\mod_deflate.exp"
    	-@erase "$(OUTDIR)\mod_deflate.lib"
    	-@erase "$(OUTDIR)\mod_deflate.pdb"
    	-@erase "$(OUTDIR)\mod_deflate.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "NDEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_deflate_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_deflate.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_deflate.so" /d LONG_NAME="deflate_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_deflate.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib zdll.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_deflate.pdb" /debug /out:"$(OUTDIR)\mod_deflate.so" /implib:"$(OUTDIR)\mod_deflate.lib" /libpath:"../../srclib/zlib" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_deflate.obj" \
    	"$(INTDIR)\mod_deflate.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_deflate.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_deflate.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_deflate.so"
       if exist .\Release\mod_deflate.so.manifest mt.exe -manifest .\Release\mod_deflate.so.manifest -outputresource:.\Release\mod_deflate.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_deflate - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_deflate.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_deflate.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_deflate.obj"
    	-@erase "$(INTDIR)\mod_deflate.res"
    	-@erase "$(INTDIR)\mod_deflate_src.idb"
    	-@erase "$(INTDIR)\mod_deflate_src.pdb"
    	-@erase "$(OUTDIR)\mod_deflate.exp"
    	-@erase "$(OUTDIR)\mod_deflate.lib"
    	-@erase "$(OUTDIR)\mod_deflate.pdb"
    	-@erase "$(OUTDIR)\mod_deflate.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "_DEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_deflate_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_deflate.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_deflate.so" /d LONG_NAME="deflate_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_deflate.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib zdll.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_deflate.pdb" /debug /out:"$(OUTDIR)\mod_deflate.so" /implib:"$(OUTDIR)\mod_deflate.lib" /libpath:"../../srclib/zlib" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_deflate.obj" \
    	"$(INTDIR)\mod_deflate.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_deflate.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_deflate.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_deflate.so"
       if exist .\Debug\mod_deflate.so.manifest mt.exe -manifest .\Debug\mod_deflate.so.manifest -outputresource:.\Debug\mod_deflate.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_deflate.dep")
    !INCLUDE "mod_deflate.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_deflate.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_deflate - Win32 Release" || "$(CFG)" == "mod_deflate - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_deflate - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_deflate - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_deflate - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_deflate - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_deflate - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_deflate - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_deflate - Win32 Release"
    
    
    "$(INTDIR)\mod_deflate.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_deflate.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_deflate.so" /d LONG_NAME="deflate_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_deflate - Win32 Debug"
    
    
    "$(INTDIR)\mod_deflate.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_deflate.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_deflate.so" /d LONG_NAME="deflate_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_deflate.c
    
    "$(INTDIR)\mod_deflate.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUmod_request�������������������������������������������������������0000664�0001751�0001751�00000010153�11540546347�021044� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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_request
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Request Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Request 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	=
    
    #
    # 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_request.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_request.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	request_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUmodsed������������������������������������������������������������0000664�0001751�0001751�00000010317�11540546347�017772� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= modsed
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) SED Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= modsed 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	=
    
    #
    # 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)/modsed.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_sed.o \
    	$(OBJDIR)/regexp.o \
    	$(OBJDIR)/sed0.o \
    	$(OBJDIR)/sed1.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	sed_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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUdeflate�����������������������������������������������������������0000664�0001751�0001751�00000011316�12002760021�020100� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(STDMOD)/ssl \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    vpath %.c $(ZLIBSDK)
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_xml2enc.mak��������������������������������������������������������0000664�0001751�0001751�00000024312�12701473373�020654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_xml2enc.dsp
    !IF "$(CFG)" == ""
    CFG=mod_xml2enc - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_xml2enc - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_xml2enc - Win32 Release" && "$(CFG)" != "mod_xml2enc - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_xml2enc.mak" CFG="mod_xml2enc - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_xml2enc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_xml2enc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_xml2enc - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_xml2enc.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_xml2enc.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\mod_xml2enc.obj"
    	-@erase "$(INTDIR)\mod_xml2enc_src.idb"
    	-@erase "$(INTDIR)\mod_xml2enc_src.pdb"
    	-@erase "$(OUTDIR)\mod_xml2enc.exp"
    	-@erase "$(OUTDIR)\mod_xml2enc.lib"
    	-@erase "$(OUTDIR)\mod_xml2enc.pdb"
    	-@erase "$(OUTDIR)\mod_xml2enc.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/libxml2/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_xml2enc_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d "NDEBUG" /d BIN_NAME="mod_xml2enc.so" /d LONG_NAME="xml2enc_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_xml2enc.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_xml2enc.pdb" /debug /out:"$(OUTDIR)\mod_xml2enc.so" /implib:"$(OUTDIR)\mod_xml2enc.lib" /libpath:"../../srclib/libxml2/win32/bin.msvc" /base:@..\..\os\win32\BaseAddr.ref,mod_xml2enc.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_xml2enc.obj" \
    	"$(INTDIR)\httpd.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_xml2enc.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_xml2enc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_xml2enc.so"
       if exist .\Release\mod_xml2enc.so.manifest mt.exe -manifest .\Release\mod_xml2enc.so.manifest -outputresource:.\Release\mod_xml2enc.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_xml2enc - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_xml2enc.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_xml2enc.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\mod_xml2enc.obj"
    	-@erase "$(INTDIR)\mod_xml2enc_src.idb"
    	-@erase "$(INTDIR)\mod_xml2enc_src.pdb"
    	-@erase "$(OUTDIR)\mod_xml2enc.exp"
    	-@erase "$(OUTDIR)\mod_xml2enc.lib"
    	-@erase "$(OUTDIR)\mod_xml2enc.pdb"
    	-@erase "$(OUTDIR)\mod_xml2enc.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/libxml2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_xml2enc_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d "_DEBUG" /d BIN_NAME="mod_xml2enc.so" /d LONG_NAME="xml2enc_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_xml2enc.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_xml2enc.pdb" /debug /out:"$(OUTDIR)\mod_xml2enc.so" /implib:"$(OUTDIR)\mod_xml2enc.lib" /libpath:"../../srclib/libxml2/win32/bin.msvc" /base:@..\..\os\win32\BaseAddr.ref,mod_xml2enc.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_xml2enc.obj" \
    	"$(INTDIR)\httpd.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_xml2enc.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_xml2enc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_xml2enc.so"
       if exist .\Debug\mod_xml2enc.so.manifest mt.exe -manifest .\Debug\mod_xml2enc.so.manifest -outputresource:.\Debug\mod_xml2enc.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_xml2enc.dep")
    !INCLUDE "mod_xml2enc.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_xml2enc.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_xml2enc - Win32 Release" || "$(CFG)" == "mod_xml2enc - Win32 Debug"
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_xml2enc - Win32 Release"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_xml2enc.so" /d LONG_NAME="xml2enc_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_xml2enc - Win32 Debug"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_xml2enc.so" /d LONG_NAME="xml2enc_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_xml2enc.c
    
    "$(INTDIR)\mod_xml2enc.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_xml2enc - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_xml2enc - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_xml2enc - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_xml2enc - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_xml2enc - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_xml2enc - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_deflate.dep��������������������������������������������������������0000664�0001751�0001751�00000003461�12674411515�020711� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_deflate.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_deflate.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\ssl\mod_ssl.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_buffer.mak���������������������������������������������������������0000664�0001751�0001751�00000023363�12701473373�020562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_buffer.dsp
    !IF "$(CFG)" == ""
    CFG=mod_buffer - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_buffer - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_buffer - Win32 Release" && "$(CFG)" != "mod_buffer - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_buffer.mak" CFG="mod_buffer - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_buffer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_buffer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_buffer - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_buffer.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_buffer.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_buffer.obj"
    	-@erase "$(INTDIR)\mod_buffer.res"
    	-@erase "$(INTDIR)\mod_buffer_src.idb"
    	-@erase "$(INTDIR)\mod_buffer_src.pdb"
    	-@erase "$(OUTDIR)\mod_buffer.exp"
    	-@erase "$(OUTDIR)\mod_buffer.lib"
    	-@erase "$(OUTDIR)\mod_buffer.pdb"
    	-@erase "$(OUTDIR)\mod_buffer.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_buffer_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_buffer.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_buffer.so" /d LONG_NAME="buffer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_buffer.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_buffer.pdb" /debug /out:"$(OUTDIR)\mod_buffer.so" /implib:"$(OUTDIR)\mod_buffer.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_buffer.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_buffer.obj" \
    	"$(INTDIR)\mod_buffer.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_buffer.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_buffer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_buffer.so"
       if exist .\Release\mod_buffer.so.manifest mt.exe -manifest .\Release\mod_buffer.so.manifest -outputresource:.\Release\mod_buffer.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_buffer - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_buffer.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_buffer.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_buffer.obj"
    	-@erase "$(INTDIR)\mod_buffer.res"
    	-@erase "$(INTDIR)\mod_buffer_src.idb"
    	-@erase "$(INTDIR)\mod_buffer_src.pdb"
    	-@erase "$(OUTDIR)\mod_buffer.exp"
    	-@erase "$(OUTDIR)\mod_buffer.lib"
    	-@erase "$(OUTDIR)\mod_buffer.pdb"
    	-@erase "$(OUTDIR)\mod_buffer.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_buffer_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_buffer.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_buffer.so" /d LONG_NAME="buffer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_buffer.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_buffer.pdb" /debug /out:"$(OUTDIR)\mod_buffer.so" /implib:"$(OUTDIR)\mod_buffer.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_buffer.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_buffer.obj" \
    	"$(INTDIR)\mod_buffer.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_buffer.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_buffer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_buffer.so"
       if exist .\Debug\mod_buffer.so.manifest mt.exe -manifest .\Debug\mod_buffer.so.manifest -outputresource:.\Debug\mod_buffer.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_buffer.dep")
    !INCLUDE "mod_buffer.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_buffer.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_buffer - Win32 Release" || "$(CFG)" == "mod_buffer - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_buffer - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_buffer - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_buffer - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_buffer - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_buffer - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_buffer - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_buffer - Win32 Release"
    
    
    "$(INTDIR)\mod_buffer.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_buffer.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_buffer.so" /d LONG_NAME="buffer_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_buffer - Win32 Debug"
    
    
    "$(INTDIR)\mod_buffer.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_buffer.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_buffer.so" /d LONG_NAME="buffer_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_buffer.c
    
    "$(INTDIR)\mod_buffer.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ext_filter.mak�����������������������������������������������������0000664�0001751�0001751�00000024101�12701473373�021445� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_ext_filter.dsp
    !IF "$(CFG)" == ""
    CFG=mod_ext_filter - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_ext_filter - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_ext_filter - Win32 Release" && "$(CFG)" != "mod_ext_filter - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ext_filter - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ext_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_ext_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ext_filter.obj"
    	-@erase "$(INTDIR)\mod_ext_filter.res"
    	-@erase "$(INTDIR)\mod_ext_filter_src.idb"
    	-@erase "$(INTDIR)\mod_ext_filter_src.pdb"
    	-@erase "$(OUTDIR)\mod_ext_filter.exp"
    	-@erase "$(OUTDIR)\mod_ext_filter.lib"
    	-@erase "$(OUTDIR)\mod_ext_filter.pdb"
    	-@erase "$(OUTDIR)\mod_ext_filter.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ext_filter_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ext_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ext_filter.so" /d LONG_NAME="ext_filter_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ext_filter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ext_filter.pdb" /debug /out:"$(OUTDIR)\mod_ext_filter.so" /implib:"$(OUTDIR)\mod_ext_filter.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ext_filter.obj" \
    	"$(INTDIR)\mod_ext_filter.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_ext_filter.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_ext_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ext_filter.so"
       if exist .\Release\mod_ext_filter.so.manifest mt.exe -manifest .\Release\mod_ext_filter.so.manifest -outputresource:.\Release\mod_ext_filter.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_ext_filter - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ext_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_ext_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ext_filter.obj"
    	-@erase "$(INTDIR)\mod_ext_filter.res"
    	-@erase "$(INTDIR)\mod_ext_filter_src.idb"
    	-@erase "$(INTDIR)\mod_ext_filter_src.pdb"
    	-@erase "$(OUTDIR)\mod_ext_filter.exp"
    	-@erase "$(OUTDIR)\mod_ext_filter.lib"
    	-@erase "$(OUTDIR)\mod_ext_filter.pdb"
    	-@erase "$(OUTDIR)\mod_ext_filter.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ext_filter_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ext_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ext_filter.so" /d LONG_NAME="ext_filter_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ext_filter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ext_filter.pdb" /debug /out:"$(OUTDIR)\mod_ext_filter.so" /implib:"$(OUTDIR)\mod_ext_filter.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ext_filter.obj" \
    	"$(INTDIR)\mod_ext_filter.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_ext_filter.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_ext_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ext_filter.so"
       if exist .\Debug\mod_ext_filter.so.manifest mt.exe -manifest .\Debug\mod_ext_filter.so.manifest -outputresource:.\Debug\mod_ext_filter.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_ext_filter.dep")
    !INCLUDE "mod_ext_filter.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_ext_filter.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_ext_filter - Win32 Release" || "$(CFG)" == "mod_ext_filter - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_ext_filter - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_ext_filter - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ext_filter - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_ext_filter - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ext_filter - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_ext_filter - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_ext_filter - Win32 Release"
    
    
    "$(INTDIR)\mod_ext_filter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ext_filter.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_ext_filter.so" /d LONG_NAME="ext_filter_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_ext_filter - Win32 Debug"
    
    
    "$(INTDIR)\mod_ext_filter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ext_filter.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_ext_filter.so" /d LONG_NAME="ext_filter_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_ext_filter.c
    
    "$(INTDIR)\mod_ext_filter.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ratelimit.mak������������������������������������������������������0000664�0001751�0001751�00000024035�12701473373�021300� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_ratelimit.dsp
    !IF "$(CFG)" == ""
    CFG=mod_ratelimit - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_ratelimit - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_ratelimit - Win32 Release" && "$(CFG)" != "mod_ratelimit - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_ratelimit.mak" CFG="mod_ratelimit - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_ratelimit - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_ratelimit - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ratelimit - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ratelimit.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_ratelimit.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ratelimit.obj"
    	-@erase "$(INTDIR)\mod_ratelimit.res"
    	-@erase "$(INTDIR)\mod_ratelimit_src.idb"
    	-@erase "$(INTDIR)\mod_ratelimit_src.pdb"
    	-@erase "$(OUTDIR)\mod_ratelimit.exp"
    	-@erase "$(OUTDIR)\mod_ratelimit.lib"
    	-@erase "$(OUTDIR)\mod_ratelimit.pdb"
    	-@erase "$(OUTDIR)\mod_ratelimit.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ratelimit_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ratelimit.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ratelimit.so" /d LONG_NAME="ratelimit_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ratelimit.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ratelimit.pdb" /debug /out:"$(OUTDIR)\mod_ratelimit.so" /implib:"$(OUTDIR)\mod_ratelimit.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ratelimit.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ratelimit.obj" \
    	"$(INTDIR)\mod_ratelimit.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_ratelimit.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_ratelimit.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ratelimit.so"
       if exist .\Release\mod_ratelimit.so.manifest mt.exe -manifest .\Release\mod_ratelimit.so.manifest -outputresource:.\Release\mod_ratelimit.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_ratelimit - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_ratelimit.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_ratelimit.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_ratelimit.obj"
    	-@erase "$(INTDIR)\mod_ratelimit.res"
    	-@erase "$(INTDIR)\mod_ratelimit_src.idb"
    	-@erase "$(INTDIR)\mod_ratelimit_src.pdb"
    	-@erase "$(OUTDIR)\mod_ratelimit.exp"
    	-@erase "$(OUTDIR)\mod_ratelimit.lib"
    	-@erase "$(OUTDIR)\mod_ratelimit.pdb"
    	-@erase "$(OUTDIR)\mod_ratelimit.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ratelimit_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ratelimit.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ratelimit.so" /d LONG_NAME="ratelimit_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ratelimit.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ratelimit.pdb" /debug /out:"$(OUTDIR)\mod_ratelimit.so" /implib:"$(OUTDIR)\mod_ratelimit.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_ratelimit.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_ratelimit.obj" \
    	"$(INTDIR)\mod_ratelimit.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_ratelimit.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_ratelimit.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ratelimit.so"
       if exist .\Debug\mod_ratelimit.so.manifest mt.exe -manifest .\Debug\mod_ratelimit.so.manifest -outputresource:.\Debug\mod_ratelimit.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_ratelimit.dep")
    !INCLUDE "mod_ratelimit.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_ratelimit.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_ratelimit - Win32 Release" || "$(CFG)" == "mod_ratelimit - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_ratelimit - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_ratelimit - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ratelimit - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_ratelimit - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_ratelimit - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_ratelimit - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_ratelimit - Win32 Release"
    
    
    "$(INTDIR)\mod_ratelimit.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ratelimit.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_ratelimit.so" /d LONG_NAME="ratelimit_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_ratelimit - Win32 Debug"
    
    
    "$(INTDIR)\mod_ratelimit.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_ratelimit.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_ratelimit.so" /d LONG_NAME="ratelimit_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_ratelimit.c
    
    "$(INTDIR)\mod_ratelimit.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_filter.dsp���������������������������������������������������������0000664�0001751�0001751�00000010563�10674443511�020610� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_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_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_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_filter.mak" CFG="mod_filter - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_filter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_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_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_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 /fo"Release/mod_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_filter.so" /d LONG_NAME="filter_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_filter.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_filter.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_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 /fo"Debug/mod_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_filter.so" /d LONG_NAME="filter_module for Apache"
    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 /out:".\Debug\mod_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_filter.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_filter.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_filter - Win32 Release"
    # Name "mod_filter - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_filter.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUsubstitute��������������������������������������������������������0000664�0001751�0001751�00000010262�11540546347�020731� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= substitute
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Substitute Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Substitute 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	=
    
    #
    # 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)/substitute.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_substitute.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	substitute_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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUmod_filter��������������������������������������������������������0000664�0001751�0001751�00000010145�11540546347�020642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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_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	=
    
    #
    # 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_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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_substitute.mak�����������������������������������������������������0000664�0001751�0001751�00000024115�12701473373�021520� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_substitute.dsp
    !IF "$(CFG)" == ""
    CFG=mod_substitute - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_substitute - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_substitute - Win32 Release" && "$(CFG)" != "mod_substitute - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_substitute.mak" CFG="mod_substitute - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_substitute - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_substitute - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_substitute - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_substitute.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_substitute.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_substitute.obj"
    	-@erase "$(INTDIR)\mod_substitute.res"
    	-@erase "$(INTDIR)\mod_substitute_src.idb"
    	-@erase "$(INTDIR)\mod_substitute_src.pdb"
    	-@erase "$(OUTDIR)\mod_substitute.exp"
    	-@erase "$(OUTDIR)\mod_substitute.lib"
    	-@erase "$(OUTDIR)\mod_substitute.pdb"
    	-@erase "$(OUTDIR)\mod_substitute.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_substitute_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_substitute.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_substitute.so" /d LONG_NAME="substitute_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_substitute.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_substitute.pdb" /debug /out:"$(OUTDIR)\mod_substitute.so" /implib:"$(OUTDIR)\mod_substitute.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_substitute.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_substitute.obj" \
    	"$(INTDIR)\mod_substitute.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_substitute.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_substitute.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_substitute.so"
       if exist .\Release\mod_substitute.so.manifest mt.exe -manifest .\Release\mod_substitute.so.manifest -outputresource:.\Release\mod_substitute.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_substitute - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_substitute.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_substitute.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_substitute.obj"
    	-@erase "$(INTDIR)\mod_substitute.res"
    	-@erase "$(INTDIR)\mod_substitute_src.idb"
    	-@erase "$(INTDIR)\mod_substitute_src.pdb"
    	-@erase "$(OUTDIR)\mod_substitute.exp"
    	-@erase "$(OUTDIR)\mod_substitute.lib"
    	-@erase "$(OUTDIR)\mod_substitute.pdb"
    	-@erase "$(OUTDIR)\mod_substitute.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_substitute_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_substitute.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_substitute.so" /d LONG_NAME="substitute_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_substitute.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_substitute.pdb" /debug /out:"$(OUTDIR)\mod_substitute.so" /implib:"$(OUTDIR)\mod_substitute.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_substitute.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_substitute.obj" \
    	"$(INTDIR)\mod_substitute.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_substitute.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_substitute.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_substitute.so"
       if exist .\Debug\mod_substitute.so.manifest mt.exe -manifest .\Debug\mod_substitute.so.manifest -outputresource:.\Debug\mod_substitute.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_substitute.dep")
    !INCLUDE "mod_substitute.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_substitute.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_substitute - Win32 Release" || "$(CFG)" == "mod_substitute - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_substitute - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_substitute - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_substitute - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_substitute - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_substitute - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_substitute - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_substitute - Win32 Release"
    
    
    "$(INTDIR)\mod_substitute.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_substitute.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_substitute.so" /d LONG_NAME="substitute_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_substitute - Win32 Debug"
    
    
    "$(INTDIR)\mod_substitute.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_substitute.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_substitute.so" /d LONG_NAME="substitute_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_substitute.c
    
    "$(INTDIR)\mod_substitute.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_request.mak��������������������������������������������������������0000664�0001751�0001751�00000023471�12701473373�021001� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_request.dsp
    !IF "$(CFG)" == ""
    CFG=mod_request - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_request - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_request - Win32 Release" && "$(CFG)" != "mod_request - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_request.mak" CFG="mod_request - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_request - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_request - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_request - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_request.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_request.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_request.obj"
    	-@erase "$(INTDIR)\mod_request.res"
    	-@erase "$(INTDIR)\mod_request_src.idb"
    	-@erase "$(INTDIR)\mod_request_src.pdb"
    	-@erase "$(OUTDIR)\mod_request.exp"
    	-@erase "$(OUTDIR)\mod_request.lib"
    	-@erase "$(OUTDIR)\mod_request.pdb"
    	-@erase "$(OUTDIR)\mod_request.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_request_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_request.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_request.so" /d LONG_NAME="request_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_request.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_request.pdb" /debug /out:"$(OUTDIR)\mod_request.so" /implib:"$(OUTDIR)\mod_request.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_request.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_request.obj" \
    	"$(INTDIR)\mod_request.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_request.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_request.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_request.so"
       if exist .\Release\mod_request.so.manifest mt.exe -manifest .\Release\mod_request.so.manifest -outputresource:.\Release\mod_request.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_request - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_request.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_request.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_request.obj"
    	-@erase "$(INTDIR)\mod_request.res"
    	-@erase "$(INTDIR)\mod_request_src.idb"
    	-@erase "$(INTDIR)\mod_request_src.pdb"
    	-@erase "$(OUTDIR)\mod_request.exp"
    	-@erase "$(OUTDIR)\mod_request.lib"
    	-@erase "$(OUTDIR)\mod_request.pdb"
    	-@erase "$(OUTDIR)\mod_request.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_request_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_request.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_request.so" /d LONG_NAME="request_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_request.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_request.pdb" /debug /out:"$(OUTDIR)\mod_request.so" /implib:"$(OUTDIR)\mod_request.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_request.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_request.obj" \
    	"$(INTDIR)\mod_request.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_request.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_request.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_request.so"
       if exist .\Debug\mod_request.so.manifest mt.exe -manifest .\Debug\mod_request.so.manifest -outputresource:.\Debug\mod_request.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_request.dep")
    !INCLUDE "mod_request.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_request.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_request - Win32 Release" || "$(CFG)" == "mod_request - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_request - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_request - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_request - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_request - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_request - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_request - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_request - Win32 Release"
    
    
    "$(INTDIR)\mod_request.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_request.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_request.so" /d LONG_NAME="request_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_request - Win32 Debug"
    
    
    "$(INTDIR)\mod_request.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_request.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_request.so" /d LONG_NAME="request_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_request.c
    
    "$(INTDIR)\mod_request.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_data.c�������������������������������������������������������������0000664�0001751�0001751�00000020176�14640775605�017702� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_data.c --- Turn the response into an rfc2397 data URL, suitable for
     *                displaying as inline content on a page.
     */
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_buckets.h"
    #include "apr_base64.h"
    #include "apr_lib.h"
    
    #include "ap_config.h"
    #include "util_filter.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_request.h"
    #include "http_protocol.h"
    
    #define DATA_FILTER "DATA"
    
    module AP_MODULE_DECLARE_DATA data_module;
    
    typedef struct data_ctx
    {
        unsigned char overflow[3];
        int count;
        apr_bucket_brigade *bb;
    } data_ctx;
    
    /**
     * Create a data URL as follows:
     *
     * data:[<mime-type>;][charset=<charset>;]base64,<payload>
     *
     * Where:
     *
     * mime-type: The mime type of the original response.
     * charset: The optional character set corresponding to the mime type.
     * payload: A base64 version of the response body.
     *
     * The content type of the response is set to text/plain.
     *
     * The Content-Length header, if present, is updated with the new content
     * length based on the increase in size expected from the base64 conversion.
     * If the Content-Length header is too large to fit into an int, we remove
     * the Content-Length header instead.
     */
    static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        apr_bucket *e, *ee;
        request_rec *r = f->r;
        data_ctx *ctx = f->ctx;
        apr_status_t rv = APR_SUCCESS;
    
        /* first time in? create a context */
        if (!ctx) {
            char *type;
            char *charset = NULL;
            char *end;
            const char *content_length;
    
            /* base64-ing won't work on subrequests, it would be nice if
             * it did. Within subrequests, we have no EOS to check for,
             * so we don't know when to flush the tail to the network.
             */
            if (!ap_is_initial_req(f->r)) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
            ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
    
            type = apr_pstrdup(r->pool, r->content_type);
            if (type) {
                charset = strchr(type, ' ');
                if (charset) {
                    *charset++ = 0;
                    end = strchr(charset, ' ');
                    if (end) {
                        *end++ = 0;
                    }
                }
            }
    
            apr_brigade_printf(ctx->bb, NULL, NULL, "data:%s%s;base64,",
                    type ? type : "", charset ? charset : "");
    
            content_length = apr_table_get(r->headers_out, "Content-Length");
            if (content_length) {
                apr_off_t len, clen;
                apr_brigade_length(ctx->bb, 1, &len);
                if (ap_parse_strict_length(&clen, content_length)
                        && clen < APR_INT32_MAX) {
                    ap_set_content_length(r, len +
                                          apr_base64_encode_len((int)clen) - 1);
                }
                else {
                    apr_table_unset(r->headers_out, "Content-Length");
                }
            }
    
            ap_set_content_type_ex(r, "text/plain", 1);
    
        }
    
        /* Do nothing if asked to filter nothing. */
        if (APR_BRIGADE_EMPTY(bb)) {
            return ap_pass_brigade(f->next, bb);
        }
    
        while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(bb)) {
            const char *data;
            apr_size_t size;
            apr_size_t tail;
            apr_size_t len;
            /* buffer big enough for 8000 encoded bytes (6000 raw bytes) and terminator */
            char buffer[APR_BUCKET_BUFF_SIZE + 1];
            char encoded[((sizeof(ctx->overflow)) / 3) * 4 + 1];
    
            e = APR_BRIGADE_FIRST(bb);
    
            /* EOS means we are done. */
            if (APR_BUCKET_IS_EOS(e)) {
    
                /* write away the tail */
                if (ctx->count) {
                    len = apr_base64_encode_binary(encoded, ctx->overflow,
                            ctx->count);
                    apr_brigade_write(ctx->bb, NULL, NULL, encoded, len - 1);
                    ctx->count = 0;
                }
    
                /* pass the EOS across */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
    
                /* pass what we have down the chain */
                ap_remove_output_filter(f);
                rv = ap_pass_brigade(f->next, ctx->bb);
    
                /* pass any stray buckets after the EOS down the stack */
                if ((APR_SUCCESS == rv) && (!APR_BRIGADE_EMPTY(bb))) {
                   rv = ap_pass_brigade(f->next, bb);
                }
                continue;
            }
    
            /* flush what we can, we can't flush the tail until EOS */
            if (APR_BUCKET_IS_FLUSH(e)) {
    
                /* pass the flush bucket across */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
    
                /* pass what we have down the chain */
                rv = ap_pass_brigade(f->next, ctx->bb);
                continue;
            }
    
            /* metadata buckets are preserved as is */
            if (APR_BUCKET_IS_METADATA(e)) {
                /*
                 * Remove meta data bucket from old brigade and insert into the
                 * new.
                 */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                continue;
            }
    
            /* make sure we don't read more than 6000 bytes at a time */
            apr_brigade_partition(bb, (APR_BUCKET_BUFF_SIZE / 4 * 3), &ee);
    
            /* size will never be more than 6000 bytes */
            if (APR_SUCCESS == (rv = apr_bucket_read(e, &data, &size,
                    APR_BLOCK_READ))) {
    
                /* fill up and write out our overflow buffer if partially used */
                while (size && ctx->count && ctx->count < sizeof(ctx->overflow)) {
                    ctx->overflow[ctx->count++] = *data++;
                    size--;
                }
                if (ctx->count == sizeof(ctx->overflow)) {
                    len = apr_base64_encode_binary(encoded, ctx->overflow,
                            sizeof(ctx->overflow));
                    apr_brigade_write(ctx->bb, NULL, NULL, encoded, len - 1);
                    ctx->count = 0;
                }
    
                /* write the main base64 chunk */
                tail = size % sizeof(ctx->overflow);
                size -= tail;
                if (size) {
                    len = apr_base64_encode_binary(buffer,
                            (const unsigned char *) data, size);
                    apr_brigade_write(ctx->bb, NULL, NULL, buffer, len - 1);
                }
    
                /* save away any tail in the overflow buffer */
                if (tail) {
                    memcpy(ctx->overflow, data + size, tail);
                    ctx->count += tail;
                }
    
                apr_bucket_delete(e);
    
                /* pass what we have down the chain */
                rv = ap_pass_brigade(f->next, ctx->bb);
                if (rv) {
                    /* should break out of the loop, since our write to the client
                     * failed in some way. */
                    continue;
                }
    
            }
    
        }
    
        return rv;
    
    }
    
    static const command_rec data_cmds[] = { { NULL } };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_output_filter(DATA_FILTER, data_out_filter, NULL,
                AP_FTYPE_RESOURCE);
    }
    AP_DECLARE_MODULE(data) = { 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 */
        data_cmds, /* command apr_table_t */
        register_hooks /* register hooks */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_xml2enc.c����������������������������������������������������������0000664�0001751�0001751�00000063703�14576247100�020334� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*      Copyright (c) 2007-11, WebThing Ltd
     *      Copyright (c) 2011-, The Apache Software Foundation
     *
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    #if defined(WIN32)
    #define XML2ENC_DECLARE_EXPORT
    #endif
    
    #include <ctype.h>
    
    /* libxml2 includes unicode/[...].h files which uses C++ comments */
    #if defined(__clang__)
    #pragma clang diagnostic push
    #pragma clang diagnostic warning "-Wcomment"
    #elif defined(__GNUC__)
    #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic warning "-Wcomment"
    #endif
    #endif
    
    /* libxml2 */
    #include <libxml/encoding.h>
    
    #if defined(__clang__)
    #pragma clang diagnostic pop
    #elif defined(__GNUC__)
    #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
    #pragma GCC diagnostic pop
    #endif
    #endif
    
    #include "http_protocol.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "apr_strings.h"
    #include "apr_xlate.h"
    
    #include "apr_optional.h"
    #include "mod_xml2enc.h"
    
    module AP_MODULE_DECLARE_DATA xml2enc_module;
    
    #define BUFLEN 8192
    #define BUF_MIN 4096
    #define APR_BRIGADE_DO(b,bb) for (b = APR_BRIGADE_FIRST(bb); \
                                      b != APR_BRIGADE_SENTINEL(bb); \
                                      b = APR_BUCKET_NEXT(b))
    
    #define ENC_INITIALISED 0x100
    #define ENC_SEEN_EOS 0x200
    #define ENC_SKIPTO ENCIO_SKIPTO
    
    #define HAVE_ENCODING(enc) \
            (((enc)!=XML_CHAR_ENCODING_NONE)&&((enc)!=XML_CHAR_ENCODING_ERROR))
    
    /*
     * XXX: Check all those ap_assert()s and replace those that should not happen
     * XXX: with AP_DEBUG_ASSERT and those that may happen with proper error
     * XXX: handling.
     */
    typedef struct {
        xmlCharEncoding xml2enc;
        char* buf;
        apr_size_t bytes;
        apr_xlate_t* convset;
        unsigned int flags;
        apr_off_t bblen;
        apr_bucket_brigade* bbnext;
        apr_bucket_brigade* bbsave;
        const char* encoding;
    } xml2ctx;
    
    typedef struct {
        const char* default_charset;
        xmlCharEncoding default_encoding;
        apr_array_header_t* skipto;
    } xml2cfg;
    
    typedef struct {
        const char* val;
    } tattr;
    
    static ap_regex_t* seek_meta_ctype;
    static ap_regex_t* seek_charset;
    
    static apr_status_t xml2enc_filter(request_rec* r, const char* enc,
                                       unsigned int mode)
    {
        /* set up a ready-initialised ctx to convert to enc, and insert filter */
        apr_xlate_t* convset; 
        apr_status_t rv;
        unsigned int flags = (mode ^ ENCIO);
        if ((mode & ENCIO) == ENCIO_OUTPUT) {
            rv = apr_xlate_open(&convset, enc, "UTF-8", r->pool);
            flags |= ENC_INITIALISED;
        }
        else if ((mode & ENCIO) == ENCIO_INPUT) {
            rv = apr_xlate_open(&convset, "UTF-8", enc, r->pool);
            flags |= ENC_INITIALISED;
        }
        else if ((mode & ENCIO) == ENCIO_INPUT_CHECKS) {
            convset = NULL;
            rv = APR_SUCCESS; /* we'll initialise later by sniffing */
        }
        else {
            rv = APR_EGENERAL;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01426)
                          "xml2enc: bad mode %x", mode);
        }
        if (rv == APR_SUCCESS) {
            xml2ctx* ctx = apr_pcalloc(r->pool, sizeof(xml2ctx));
            ctx->flags = flags;
            if (flags & ENC_INITIALISED) {
                ctx->convset = convset;
                ctx->bblen = BUFLEN;
                ctx->buf = apr_palloc(r->pool, (apr_size_t)ctx->bblen);
            }
            ap_add_output_filter("xml2enc", ctx, r, r->connection);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01427)
                          "xml2enc: Charset %s not supported.", enc) ;
        }
        return rv;
    }
    
    /* This needs to operate only when we're using htmlParser */
    /* Different modules may apply different rules here.  Ho, hum.  */
    static void fix_skipto(request_rec* r, xml2ctx* ctx)
    {
        apr_status_t rv;
        xml2cfg* cfg = ap_get_module_config(r->per_dir_config, &xml2enc_module);
        if ((cfg->skipto != NULL) && (ctx->flags & ENC_SKIPTO)) {
            int found = 0;
            char* p = ap_strchr(ctx->buf, '<');
            tattr* starts = (tattr*) cfg->skipto->elts;
            while (!found && p && *p) {
                int i;
                for (i = 0; i < cfg->skipto->nelts; ++i) {
                    if (!strncasecmp(p+1, starts[i].val, strlen(starts[i].val))) {
                        /* found a starting element. Strip all that comes before. */
                        apr_bucket* b;
                        apr_bucket* bstart;
                        rv = apr_brigade_partition(ctx->bbsave, (p-ctx->buf),
                                                   &bstart);
                        ap_assert(rv == APR_SUCCESS);
                        while (b = APR_BRIGADE_FIRST(ctx->bbsave), b != bstart) {
                            apr_bucket_delete(b);
                        }
                        ctx->bytes -= (p-ctx->buf);
                        ctx->buf = p ;
                        found = 1;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01428)
                                      "Skipped to first <%s> element",
                                      starts[i].val) ;
                        break;
                    }
                }
                p = ap_strchr(p+1, '<');
            }
            if (p == NULL) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01429)
                              "Failed to find start of recognised HTML!");
            }
        }
    }
    static void sniff_encoding(request_rec* r, xml2ctx* ctx)
    {
        xml2cfg* cfg = NULL; /* initialise to shut compiler warnings up */
        char* p ;
        apr_bucket* cutb;
        apr_bucket* cute;
        apr_bucket* b;
        ap_regmatch_t match[2] ;
        apr_status_t rv;
        const char* ctype = r->content_type;
    
        if (ctype) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01430)
                          "Content-Type is %s", ctype) ;
    
            /* If we've got it in the HTTP headers, there's nothing to do */
            if (ctype && (p = ap_strcasestr(ctype, "charset=") , p != NULL)) {
                p += 8 ;
                if (ctx->encoding = apr_pstrndup(r->pool, p, strcspn(p, " ;") ),
                    ctx->encoding) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01431)
                                  "Got charset %s from HTTP headers", ctx->encoding) ;
                    ctx->xml2enc = xmlParseCharEncoding(ctx->encoding);
                }
            }
        }
    
        /* to sniff, first we look for BOM */
        if (ctx->xml2enc == XML_CHAR_ENCODING_NONE) {
            ctx->xml2enc = xmlDetectCharEncoding((const unsigned char*)ctx->buf,
                                                 ctx->bytes);
            if (HAVE_ENCODING(ctx->xml2enc)) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01432)
                              "Got charset from XML rules.") ;
                ctx->encoding = xmlGetCharEncodingName(ctx->xml2enc);
            }
        }
    
        /* If none of the above, look for a META-thingey */
        /* also we're probably about to invalidate it, so we remove it. */
        if (ap_regexec(seek_meta_ctype, ctx->buf, 1, match, 0) == 0 ) {
            /* get markers on the start and end of the match */
            rv = apr_brigade_partition(ctx->bbsave, match[0].rm_eo, &cute);
            ap_assert(rv == APR_SUCCESS);
            rv = apr_brigade_partition(ctx->bbsave, match[0].rm_so, &cutb);
            ap_assert(rv == APR_SUCCESS);
            /* now set length of useful buf for start-of-data hooks */
            ctx->bytes = match[0].rm_so;
            if (ctx->encoding == NULL) {
                p = apr_pstrndup(r->pool, ctx->buf + match[0].rm_so,
                                 match[0].rm_eo - match[0].rm_so) ;
                if (ap_regexec(seek_charset, p, 2, match, 0) == 0) {
                    if (ctx->encoding = apr_pstrndup(r->pool, p+match[1].rm_so,
                                                   match[1].rm_eo - match[1].rm_so),
                        ctx->encoding) {
                        ctx->xml2enc = xmlParseCharEncoding(ctx->encoding);
                        if (HAVE_ENCODING(ctx->xml2enc))
                            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01433)
                                          "Got charset %s from HTML META", ctx->encoding) ;
                    }
                }
            }
    
            /* cut out the <meta> we're invalidating */
            while (cutb != cute) {
                b = APR_BUCKET_NEXT(cutb);
                apr_bucket_delete(cutb);
                cutb = b;
            }
            /* and leave a string */
            ctx->buf[ctx->bytes] = 0;
        }
    
        /* either it's set to something we found or it's still the default */
        /* Aaargh!  libxml2 has undocumented <META-crap> support.  So this fails
         * if metafix is not active.  Have to make it conditional.
         *
         * No, that means no-metafix breaks things.  Deal immediately with
         * this particular instance of metafix.
         */
        if (!HAVE_ENCODING(ctx->xml2enc)) {
            cfg = ap_get_module_config(r->per_dir_config, &xml2enc_module);
            if (!ctx->encoding) {
                ctx->encoding = cfg->default_charset?cfg->default_charset:"ISO-8859-1";
            }
            /* Unsupported charset. Can we get (iconv) support through apr_xlate? */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01434)
                          "Charset %s not supported by libxml2; trying apr_xlate",
                          ctx->encoding);
            if (apr_xlate_open(&ctx->convset, "UTF-8", ctx->encoding, r->pool)
                == APR_SUCCESS) {
                ctx->xml2enc = XML_CHAR_ENCODING_UTF8 ;
            } else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01435)
                              "Charset %s not supported.  Consider aliasing it?",
                              ctx->encoding) ;
            }
        }
    
        if (!HAVE_ENCODING(ctx->xml2enc)) {
            /* Use configuration default as a last resort */
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01436)
                      "No usable charset information; using configuration default");
            ctx->xml2enc = (cfg->default_encoding == XML_CHAR_ENCODING_NONE)
                            ? XML_CHAR_ENCODING_8859_1 : cfg->default_encoding ;
        }
        if (ctype && ctx->encoding) {
            if (ap_regexec(seek_charset, ctype, 2, match, 0)) {
                r->content_type = apr_pstrcat(r->pool, ctype, ";charset=utf-8",
                                              NULL);
            } else {
                char* str = apr_palloc(r->pool, strlen(r->content_type) + 13
                                       - (match[0].rm_eo - match[0].rm_so) + 1);
                memcpy(str, r->content_type, match[1].rm_so);
                memcpy(str + match[1].rm_so, "utf-8", 5);
                strcpy(str + match[1].rm_so + 5, r->content_type+match[1].rm_eo);
                r->content_type = str;
            }
        }
    }
    
    static apr_status_t xml2enc_filter_init(ap_filter_t* f)
    {
        xml2ctx* ctx;
        if (!f->ctx) {
            xml2cfg* cfg = ap_get_module_config(f->r->per_dir_config,
                                                &xml2enc_module);
            f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(xml2ctx));
            ctx->xml2enc = XML_CHAR_ENCODING_NONE;
            if (cfg->skipto != NULL) {
                ctx->flags |= ENC_SKIPTO;
            }
        }
        return APR_SUCCESS;
    }
    static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
    {
        xml2ctx* ctx = f->ctx;
        apr_status_t rv;
        apr_bucket* b;
        apr_bucket* bstart;
        apr_size_t insz = 0;
        int pending_meta = 0;
        char *mtype;
        char *p;
    
        if (!ctx || !f->r->content_type) {
            /* log error about configuring this */
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, bb) ;
        }
    
        /* Extract the media type, ignoring parameters in content-type. */
        mtype = apr_pstrdup(f->r->pool, f->r->content_type);
        if ((p = ap_strchr(mtype, ';')) != NULL) *p = '\0';
        ap_str_tolower(mtype);
    
        /* Accept text/ types, plus any XML media type per RFC 7303. */
        if (!(strncmp(mtype, "text/", 5) == 0
              || strcmp(mtype, "application/xml") == 0
              || (strlen(mtype) > 7 /* minimum 'a/b+xml' length */
                  && (p = strstr(mtype, "+xml")) != NULL
                  && strlen(p) == 4 /* ensures +xml is a suffix */))) {
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, bb) ;
        }
    
        if (ctx->bbsave == NULL) {
            ctx->bbsave = apr_brigade_create(f->r->pool,
                                             f->r->connection->bucket_alloc);
        }
        /* append to any data left over from last time */
        APR_BRIGADE_CONCAT(ctx->bbsave, bb);
    
        if (!(ctx->flags & ENC_INITIALISED)) {
            /* some kind of initialisation required */
            /* Turn all this off when post-processing */
    
            /* if we don't have enough data to sniff but more's to come, wait */
            apr_brigade_length(ctx->bbsave, 0, &ctx->bblen);
            if ((ctx->bblen < BUF_MIN) && (ctx->bblen != -1)) {
                APR_BRIGADE_DO(b, ctx->bbsave) {
                    if (APR_BUCKET_IS_EOS(b)) {
                        ctx->flags |= ENC_SEEN_EOS;
                        break;
                    }
                }
                if (!(ctx->flags & ENC_SEEN_EOS)) {
                    /* not enough data to sniff.  Wait for more */
                    APR_BRIGADE_DO(b, ctx->bbsave) {
                        rv = apr_bucket_setaside(b, f->r->pool);
                        ap_assert(rv == APR_SUCCESS);
                    }
                    return APR_SUCCESS;
                }
            }
            if (ctx->bblen == -1) {
                ctx->bblen = BUFLEN-1;
            }
    
            /* flatten it into a NULL-terminated string */
            ctx->buf = apr_palloc(f->r->pool, (apr_size_t)(ctx->bblen+1));
            ctx->bytes = (apr_size_t)ctx->bblen;
            rv = apr_brigade_flatten(ctx->bbsave, ctx->buf, &ctx->bytes);
            ap_assert(rv == APR_SUCCESS);
            ctx->buf[ctx->bytes] = 0;
            sniff_encoding(f->r, ctx);
    
            /* FIXME: hook here for rewriting start-of-data? */
            /* nah, we only have one action here - call it inline */
            fix_skipto(f->r, ctx);
    
            /* we might change the Content-Length, so let's force its re-calculation */
            apr_table_unset(f->r->headers_out, "Content-Length");
    
            /* consume the data we just sniffed */
            /* we need to omit any <meta> we just invalidated */
            ctx->flags |= ENC_INITIALISED;
            ap_set_module_config(f->r->request_config, &xml2enc_module, ctx);
        }
        if (ctx->bbnext == NULL) {
            ctx->bbnext = apr_brigade_create(f->r->pool,
                                             f->r->connection->bucket_alloc);
        }
    
        if (!ctx->convset) {
            rv = ap_pass_brigade(f->next, ctx->bbsave);
            apr_brigade_cleanup(ctx->bbsave);
            ap_remove_output_filter(f);
            return rv;
        }
        /* move the data back to bb */
        APR_BRIGADE_CONCAT(bb, ctx->bbsave);
    
        while (!APR_BRIGADE_EMPTY(bb)) {
            b = APR_BRIGADE_FIRST(bb);
            ctx->bytes = 0;
            if (APR_BUCKET_IS_METADATA(b)) {
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(ctx->bbnext, b);
                /* Besides FLUSH, aggregate meta buckets to send them at
                 * once below. This resource filter is over on EOS.
                 */
                pending_meta = 1;
                if (APR_BUCKET_IS_EOS(b)) {
                    ap_remove_output_filter(f);
                    APR_BRIGADE_CONCAT(ctx->bbnext, bb);
                }
                else if (!APR_BUCKET_IS_FLUSH(b)) {
                    continue;
                }
            }
            if (pending_meta) {
                pending_meta = 0;
                /* passing meta bucket down the chain */
                rv = ap_pass_brigade(f->next, ctx->bbnext);
                apr_brigade_cleanup(ctx->bbnext);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
                continue;
            }
            /* data bucket */
            {
                char* buf;
                apr_size_t bytes = 0;
                char fixbuf[BUFLEN];
                apr_bucket* bdestroy = NULL;
                if (insz > 0) { /* we have dangling data.  Flatten it. */
                    buf = fixbuf;
                    bytes = BUFLEN;
                    rv = apr_brigade_flatten(bb, buf, &bytes);
                    ap_assert(rv == APR_SUCCESS);
                    if (bytes == insz) {
                        /* this is only what we've already tried to convert.
                         * The brigade is exhausted.
                         * Save remaining data for next time round
                         */
              
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, APLOGNO(01437)
                                      "xml2enc: Setting aside %" APR_SIZE_T_FMT
                                      " unconverted bytes", bytes);
                        rv = ap_fflush(f->next, ctx->bbnext);
                        APR_BRIGADE_CONCAT(ctx->bbsave, bb);
                        APR_BRIGADE_DO(b, ctx->bbsave) {
                            ap_assert(apr_bucket_setaside(b, f->r->pool)
                                      == APR_SUCCESS);
                        }
                        return rv;
                    }
                    /* remove the data we've just read */
                    rv = apr_brigade_partition(bb, bytes, &bstart);
                    while (b = APR_BRIGADE_FIRST(bb), b != bstart) {
                        apr_bucket_delete(b);
                    }
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, APLOGNO(01438)
                                  "xml2enc: consuming %" APR_SIZE_T_FMT
                                  " bytes flattened", bytes);
                }
                else {
                    rv = apr_bucket_read(b, (const char**)&buf, &bytes,
                                         APR_BLOCK_READ);
                    APR_BUCKET_REMOVE(b);
                    bdestroy = b;  /* can't destroy until finished with the data */
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, APLOGNO(01439)
                                  "xml2enc: consuming %" APR_SIZE_T_FMT
                                  " bytes from bucket", bytes);
                }
                /* OK, we've got some input we can use in [buf,bytes] */
                if (rv == APR_SUCCESS) {
                    apr_size_t consumed;
                    xml2enc_run_preprocess(f, &buf, &bytes);
                    consumed = insz = bytes;
                    while (insz > 0) {
                        apr_status_t rv2;
                        if (ctx->bytes == ctx->bblen) {
                            /* nothing was converted last time!
                             * break out of this loop! 
                             */
                            b = apr_bucket_transient_create(buf+(bytes - insz), insz,
                                                            bb->bucket_alloc);
                            APR_BRIGADE_INSERT_HEAD(bb, b);
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, APLOGNO(01440)
                                          "xml2enc: reinserting %" APR_SIZE_T_FMT
                                          " unconsumed bytes from bucket", insz);
                            break;
                        }
                        ctx->bytes = (apr_size_t)ctx->bblen;
                        rv = apr_xlate_conv_buffer(ctx->convset, buf+(bytes - insz),
                                                   &insz, ctx->buf, &ctx->bytes);
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, f->r, APLOGNO(01441)
                                      "xml2enc: converted %" APR_SIZE_T_FMT
                                      "/%" APR_OFF_T_FMT " bytes", consumed - insz,
                                      ctx->bblen - ctx->bytes);
                        consumed = insz;
                        rv2 = ap_fwrite(f->next, ctx->bbnext, ctx->buf,
                                        (apr_size_t)ctx->bblen - ctx->bytes);
                        if (rv2 != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv2, f->r, APLOGNO(01442)
                                          "ap_fwrite failed");
                            return rv2;
                        }
                        switch (rv) {
                        case APR_SUCCESS:
                            continue;
                        case APR_EINCOMPLETE:
                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, APLOGNO(01443)
                                          "INCOMPLETE");
                            continue;     /* If outbuf too small, go round again.
                                           * If it was inbuf, we'll break out when
                                           * we test ctx->bytes == ctx->bblen
                                           */
                        case APR_EINVAL: /* try skipping one bad byte */
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(01444)
                                       "Skipping invalid byte(s) in input stream!");
                            --insz;
                            continue;
                        default:
                            /* Erk!  What's this?
                             * Bail out, flush, and hope to eat the buf raw
                             */
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(01445)
                                          "Failed to convert input; trying it raw") ;
                            ctx->convset = NULL;
                            rv = ap_fflush(f->next, ctx->bbnext);
                            if (rv != APR_SUCCESS)
                                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, f->r, APLOGNO(01446)
                                              "ap_fflush failed");
                            apr_brigade_cleanup(ctx->bbnext);
                        }
                    }
                } else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(01447)
                                  "xml2enc: error reading data") ;
                }
                if (bdestroy)
                    apr_bucket_destroy(bdestroy);
                if (rv != APR_SUCCESS)
                    return rv;
            }
        }
        if (pending_meta) {
            /* passing pending meta bucket down the chain before leaving */
            rv = ap_pass_brigade(f->next, ctx->bbnext);
            apr_brigade_cleanup(ctx->bbnext);
            if (rv != APR_SUCCESS) {
                return rv;
            }
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t xml2enc_charset(request_rec* r, xmlCharEncoding* encp,
                                        const char** encoding)
    {
        xml2ctx* ctx = ap_get_module_config(r->request_config, &xml2enc_module);
        if (!ctx || !(ctx->flags & ENC_INITIALISED)) {
            return APR_EAGAIN;
        }
        *encp = ctx->xml2enc;
        *encoding = ctx->encoding;
        return HAVE_ENCODING(ctx->xml2enc) ? APR_SUCCESS : APR_EGENERAL;
    }
    
    #define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH
    static void xml2enc_hooks(apr_pool_t* pool)
    {
        ap_register_output_filter_protocol("xml2enc", xml2enc_ffunc,
                                           xml2enc_filter_init,
                                           AP_FTYPE_RESOURCE, PROTO_FLAGS);
        APR_REGISTER_OPTIONAL_FN(xml2enc_filter);
        APR_REGISTER_OPTIONAL_FN(xml2enc_charset);
        seek_meta_ctype = ap_pregcomp(pool,
                           "(<meta[^>]*http-equiv[ \t\r\n='\"]*content-type[^>]*>)",
                                      AP_REG_EXTENDED|AP_REG_ICASE) ;
        seek_charset = ap_pregcomp(pool, "charset=([A-Za-z0-9_-]+)",
                                   AP_REG_EXTENDED|AP_REG_ICASE) ;
    }
    static const char* set_alias(cmd_parms* cmd, void* CFG,
                                 const char* charset, const char* alias)
    {
        const char* errmsg = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (errmsg != NULL)
            return errmsg ;
        else if (xmlAddEncodingAlias(charset, alias) == 0)
            return NULL;
        else
            return "Error setting charset alias";
    }
    
    static const char* set_default(cmd_parms* cmd, void* CFG, const char* charset)
    {
        xml2cfg* cfg = CFG;
        cfg->default_charset = charset;
        cfg->default_encoding = xmlParseCharEncoding(charset);
        switch(cfg->default_encoding) {
        case XML_CHAR_ENCODING_NONE:
            return "Default charset not found";
        case XML_CHAR_ENCODING_ERROR:
            return "Invalid or unsupported default charset";
        default:
            return NULL;
        }
    }
    static const char* set_skipto(cmd_parms* cmd, void* CFG, const char* arg)
    {
        tattr* attr;
        xml2cfg* cfg = CFG;
        if (cfg->skipto == NULL)
            cfg->skipto = apr_array_make(cmd->pool, 4, sizeof(tattr));
        attr = apr_array_push(cfg->skipto) ;
        attr->val = arg;
        return NULL;
    }
    
    static const command_rec xml2enc_cmds[] = {
        AP_INIT_TAKE1("xml2EncDefault", set_default, NULL, OR_ALL,
                      "Usage: xml2EncDefault charset"),
        AP_INIT_ITERATE2("xml2EncAlias", set_alias, NULL, RSRC_CONF,
                         "EncodingAlias charset alias [more aliases]"),
        AP_INIT_ITERATE("xml2StartParse", set_skipto, NULL, OR_ALL,
                        "Ignore anything in front of the first of these elements"),
        { NULL }
    };
    static void* xml2enc_config(apr_pool_t* pool, char* x)
    {
        xml2cfg* ret = apr_pcalloc(pool, sizeof(xml2cfg));
        ret->default_encoding = XML_CHAR_ENCODING_NONE ;
        return ret;
    }
    
    static void* xml2enc_merge(apr_pool_t* pool, void* BASE, void* ADD)
    {
        xml2cfg* base = BASE;
        xml2cfg* add = ADD;
        xml2cfg* ret = apr_pcalloc(pool, sizeof(xml2cfg));
        ret->default_encoding = (add->default_encoding == XML_CHAR_ENCODING_NONE)
                              ? base->default_encoding : add->default_encoding ;
        ret->default_charset = add->default_charset
                             ? add->default_charset : base->default_charset;
        ret->skipto = add->skipto ? add->skipto : base->skipto;
        return ret;
    }
    
    AP_DECLARE_MODULE(xml2enc) = {
        STANDARD20_MODULE_STUFF,
        xml2enc_config,
        xml2enc_merge,
        NULL,
        NULL,
        xml2enc_cmds,
        xml2enc_hooks
    };
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(xml2enc, XML2ENC, int, preprocess,
                          (ap_filter_t *f, char** bufp, apr_size_t* bytesp),
                          (f, bufp, bytesp), OK, DECLINED)
    �������������������������������������������������������������httpd-2.4.64/modules/filters/regexp.h���������������������������������������������������������������0000664�0001751�0001751�00000007275�14205766164�017433� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
     * Use is subject to license terms.
     *
     *      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
     *        All Rights Reserved
     *
     * University Copyright- Copyright (c) 1982, 1986, 1988
     * The Regents of the University of California
     * All Rights Reserved
     *
     * University Acknowledgment- Portions of this document are derived from
     * software developed by the University of California, Berkeley, and its
     * contributors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  http://www.apache.org/licenses/LICENSE-2.0.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _REGEXP_H
    #define _REGEXP_H
    
    #include "libsed.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define    CBRA    2
    #define    CCHR    4
    #define    CDOT    8
    #define    CCL    12
    #define    CXCL    16
    #define    CDOL    20
    #define    CCEOF    22
    #define    CKET    24
    #define    CBACK    36
    #define    NCCL    40
    
    #define    STAR    01
    #define    RNGE    03
    
    #define    NBRA    9
    
    #define    PLACE(c)    ep[c >> 3] |= bittab[c & 07]
    #define    ISTHERE(c)    (ep[c >> 3] & bittab[c & 07])
    
    typedef struct _step_vars_storage {
        char    *loc1, *loc2, *locs;
        char    *braslist[NBRA];
        char    *braelist[NBRA];
        int    low;
        int    size;
    } step_vars_storage;
    
    typedef struct _sed_comp_args {
        int circf; /* Regular expression starts with ^ */
        int nbra; /* braces count */
    } sed_comp_args;
    
    extern char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
                             char *ep, char *endbuf, int seof);
    extern void command_errf(sed_commands_t *commands, const char *fmt, ...)
                             __attribute__((format(printf,2,3)));
    
    #define SEDERR_CGMES "command garbled: %s"
    #define SEDERR_SMMES "Space missing before filename: %s"
    #define SEDERR_TMMES "too much command text: %s"
    #define SEDERR_LTLMES "label too long: %s"
    #define SEDERR_ULMES "undefined label: %s"
    #define SEDERR_DLMES "duplicate labels: %s"
    #define SEDERR_TMLMES "too many labels: %s"
    #define SEDERR_AD0MES "no addresses allowed: %s"
    #define SEDERR_AD1MES "only one address allowed: %s"
    #define SEDERR_TOOBIG "suffix too large: %s"
    #define SEDERR_OOMMES "out of memory"
    #define SEDERR_COPFMES "cannot open pattern file: %s"
    #define SEDERR_COIFMES "cannot open input file: %s"
    #define SEDERR_TMOMES "too many {'s"
    #define SEDERR_TMCMES "too many }'s"
    #define SEDERR_NRMES "first RE may not be null"
    #define SEDERR_UCMES "unrecognized command: %s"
    #define SEDERR_TMWFMES "too many files in w commands"
    #define SEDERR_COMES "cannot open %s"
    #define SEDERR_CCMES "cannot create %s"
    #define SEDERR_TMLNMES "too many line numbers"
    #define SEDERR_TMAMES "too many appends after line %" APR_INT64_T_FMT
    #define SEDERR_TMRMES "too many reads after line %" APR_INT64_T_FMT
    #define SEDERR_DOORNG "``\\digit'' out of range: %s"
    #define SEDERR_EDMOSUB "ending delimiter missing on substitution: %s"
    #define SEDERR_EDMOSTR "ending delimiter missing on string: %s"
    #define SEDERR_FNTL "file name too long: %s"
    #define SEDERR_CLTL "command line too long"
    #define SEDERR_TSNTSS "transform strings not the same size: %s"
    #define SEDERR_OLTL "output line too long."
    #define SEDERR_HSOVERFLOW "hold space overflowed."
    #define SEDERR_INTERNAL "internal sed error"
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* _REGEXP_H */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reflector.c��������������������������������������������������������0000664�0001751�0001751�00000015672�13701324531�020744� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_tables.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_core.h"
    
    module AP_MODULE_DECLARE_DATA reflector_module;
    
    typedef struct {
        apr_table_t *headers;
    } reflector_cfg;
    
    static int header_do(void *dummy, const char *key, const char *value)
    {
        request_rec *r = (request_rec *) dummy;
        const char *payload;
    
        payload = apr_table_get(r->headers_in, key);
        if (payload) {
            apr_table_setn(r->headers_out, value, payload);
        }
    
        return 1;
    }
    
    static int reflector_handler(request_rec * r)
    {
        apr_bucket_brigade *bbin, *bbout;
        reflector_cfg *conf;
        apr_status_t status;
    
        if (strcmp(r->handler, "reflector")) {
            return DECLINED;
        }
    
        conf = (reflector_cfg *) ap_get_module_config(r->per_dir_config,
                                                      &reflector_module);
    
        ap_allow_methods(r, 1, "POST", "OPTIONS", NULL);
    
        if (r->method_number == M_OPTIONS) {
            return ap_send_http_options(r);
        }
    
        else if (r->method_number == M_POST) {
            const char *content_length, *content_type;
            int 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;
            }
    
            /* copy headers from in to out if configured */
            apr_table_do(header_do, r, conf->headers, NULL);
    
            /* last modified defaults to now, unless otherwise set on the way in */
            if (!apr_table_get(r->headers_out, "Last-Modified")) {
                ap_update_mtime(r, apr_time_now());
                ap_set_last_modified(r);
            }
            ap_set_accept_ranges(r);
    
            /* reflect the content length, if present */
            if ((content_length = apr_table_get(r->headers_in, "Content-Length"))) {
                apr_off_t clen;
    
                if (!ap_parse_strict_length(&clen, content_length)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10243)
                                  "reflector_handler: invalid content-length '%s'",
                                  content_length);
                    return HTTP_BAD_REQUEST;
                }
    
                ap_set_content_length(r, clen);
            }
    
            /* reflect the content type, if present */
            if ((content_type = apr_table_get(r->headers_in, "Content-Type"))) {
    
                ap_set_content_type(r, content_type);
    
            }
    
            bbin = apr_brigade_create(r->pool, r->connection->bucket_alloc);
            bbout = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
            seen_eos = 0;
            do {
                apr_bucket *bucket;
    
                status = ap_get_brigade(r->input_filters, bbin, AP_MODE_READBYTES,
                                        APR_BLOCK_READ, HUGE_STRING_LEN);
    
                if (status != APR_SUCCESS) {
                    apr_brigade_destroy(bbin);
                    return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
                }
    
                for (bucket = APR_BRIGADE_FIRST(bbin);
                     bucket != APR_BRIGADE_SENTINEL(bbin);
                     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.
                     */
                    status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
                    if (status != APR_SUCCESS) {
                        apr_brigade_destroy(bbin);
                        return HTTP_BAD_REQUEST;
                    }
    
                    apr_brigade_write(bbout, NULL, NULL, data, len);
    
                    status = ap_pass_brigade(r->output_filters, bbout);
                    if (status != APR_SUCCESS) {
                        /* no way to know what type of error occurred */
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(01410)
                                 "reflector_handler: ap_pass_brigade returned %i",
                                      status);
                        return AP_FILTER_ERROR;
                    }
    
                }
    
                apr_brigade_cleanup(bbin);
    
            } while (!seen_eos);
    
            return OK;
    
        }
    
        else {
            return HTTP_METHOD_NOT_ALLOWED;
        }
    
    }
    
    static void *create_reflector_dir_config(apr_pool_t * p, char *d)
    {
        reflector_cfg *conf = apr_pcalloc(p, sizeof(reflector_cfg));
    
        conf->headers = apr_table_make(p, 8);
    
        return conf;
    }
    
    static void *merge_reflector_dir_config(apr_pool_t * p, void *basev, void *addv)
    {
        reflector_cfg *new = (reflector_cfg *) apr_pcalloc(p,
                sizeof(reflector_cfg));
        reflector_cfg *add = (reflector_cfg *) addv;
        reflector_cfg *base = (reflector_cfg *) basev;
    
        new->headers = apr_table_overlay(p, add->headers, base->headers);
    
        return new;
    }
    
    static const char *reflector_header(cmd_parms * cmd, void *dummy, const char *in,
            const char *out)
    {
        reflector_cfg *cfg = (reflector_cfg *) dummy;
    
        apr_table_addn(cfg->headers, in, out ? out : in);
    
        return NULL;
    }
    
    static void reflector_hooks(apr_pool_t * p)
    {
        ap_hook_handler(reflector_handler, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    static const command_rec reflector_cmds[] = {
        AP_INIT_TAKE12("ReflectorHeader", reflector_header, NULL, OR_OPTIONS,
          "Header to reflect back in the response, with an optional new name."),
        {NULL}
    };
    
    AP_DECLARE_MODULE(reflector) = {
        STANDARD20_MODULE_STUFF,
        create_reflector_dir_config,
        merge_reflector_dir_config,
        NULL,
        NULL,
        reflector_cmds,
        reflector_hooks
    };
    ����������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ext_filter.c�������������������������������������������������������0000664�0001751�0001751�00000074031�14675527312�021133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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 log_stderr;
        int onfail;
    } 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, hit_eos;
    #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 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->log_stderr = -1;
        dc->onfail = -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->log_stderr != -1) {   /* if admin coded something... */
            a->log_stderr = over->log_stderr;
        }
        else {
            a->log_stderr = base->log_stderr;
        }
    
        if (over->onfail != -1) {   /* if admin coded something... */
            a->onfail = over->onfail;
        }
        else {
            a->onfail = base->onfail;
        }
    
        return a;
    }
    
    static const char *add_options(cmd_parms *cmd, void *in_dc,
                                   const char *arg)
    {
        ef_dir_t *dc = in_dc;
    
        if (!strcasecmp(arg, "LogStderr")) {
            dc->log_stderr = 1;
        }
        else if (!strcasecmp(arg, "NoLogStderr")) {
            dc->log_stderr = 0;
        }
        else if (!strcasecmp(arg, "Onfail=remove")) {
            dc->onfail = 1;
        }
        else if (!strcasecmp(arg, "Onfail=abort")) {
            dc->onfail = 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;
        char *normalized_name;
        ef_filter_t *filter;
    
        name = ap_getword_white(cmd->pool, &args);
        if (!name) {
            return "Filter name not found";
        }
    
        /* During request processing, we find information about the filter
         * by looking up the filter name provided by core server in our
         * hash table.  But the core server has normalized the filter
         * name by converting it to lower case.  Thus, when adding the
         * filter to our hash table we have to use lower case as well.
         */
        normalized_name = apr_pstrdup(cmd->pool, name);
        ap_str_tolower(normalized_name);
    
        if (apr_hash_get(conf->h, normalized_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, normalized_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: 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_core_module_config(r->per_dir_config);
        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 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)%pm: %s\n",
                        time_str,
                        r->useragent_ip,
                        err,
                        &err,
                        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);
    
        rc = apr_procattr_error_check_set(ctx->procattr, 1);
        if (rc != APR_SUCCESS) {
            return rc;
        }
    
        /* 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, APLOGNO(01458)
                          "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 *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 ExtFilterInType %s "
                            "ExtFilterOuttype %s",
                            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, APLOGNO(01459)
                          "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_ex(f->r, ctx->filter->outtype, 1);
            }
            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 (APLOGrtrace1(f->r)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 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 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;
        apr_size_t len;
        char buf[4096];
        apr_status_t rv;
        apr_bucket *b;
    
        while (1) {
            int lvl = APLOG_TRACE5;
            len = sizeof(buf);
            rv = apr_file_read(ctx->proc->out, buf, &len);
            if (rv && !APR_STATUS_IS_EAGAIN(rv))
               lvl = APLOG_DEBUG;
            ap_log_rerror(APLOG_MARK, lvl, rv, r, APLOGNO(01460)
                          "apr_file_read(child output), len %" APR_SIZE_T_FMT, len);
            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;
        apr_status_t rv;
        apr_size_t bytes_written = 0;
        apr_size_t tmplen;
    
        do {
            tmplen = len - bytes_written;
            rv = apr_file_write_full(ctx->proc->in,
                           (const char *)data + bytes_written,
                           tmplen, &tmplen);
            bytes_written += tmplen;
            if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(01461)
                              "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 != APR_SUCCESS && !APR_STATUS_IS_EINTR(rv)) {
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, f->r, APLOGNO(01462)
                                      "apr_pollset_poll()");
                        /* some error such as APR_TIMEUP */
                        return rv;
                    }
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE6, rv, f->r,
                                  "apr_pollset_poll()");
    #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(apr_time_from_msec(100));
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE6, 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;
        apr_size_t len;
        const char *data;
        apr_status_t rv;
        char buf[4096];
        apr_bucket *eos = NULL;
        apr_bucket_brigade *bb_tmp;
    
        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;
            }
    
            if (AP_BUCKET_IS_ERROR(b)) {
                apr_bucket *cpy;
                apr_bucket_copy(b, &cpy);
                APR_BRIGADE_INSERT_TAIL(bb_tmp, cpy);
                break;
            }
    
            rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01463) "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, APLOGNO(01464)
                              "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, APLOGNO(01465)
                              "apr_file_pipe_timeout_set(child output)");
                return rv;
            }
        }
    
        do {
            int lvl = APLOG_TRACE6;
            len = sizeof(buf);
            rv = apr_file_read(ctx->proc->out, buf, &len);
            if (rv && !APR_STATUS_IS_EOF(rv) && !APR_STATUS_IS_EAGAIN(rv))
                lvl = APLOG_ERR;
            ap_log_rerror(APLOG_MARK, lvl, rv, r, APLOGNO(01466)
                          "apr_file_read(child output), len %" APR_SIZE_T_FMT, len);
            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);
            ctx->hit_eos = 1;
        }
    
        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) {
                ctx = f->ctx;
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01467)
                              "can't initialise output filter %s: %s",
                              f->frec->name,
                              (ctx->dc->onfail == 1) ? "removing" : "aborting");
                ap_remove_output_filter(f);
                if (ctx->dc->onfail == 1) {
                    return ap_pass_brigade(f->next, bb);
                }
                else {
                    apr_bucket *e;
                    f->r->status_line = "500 Internal Server Error";
    
                    apr_brigade_cleanup(bb);
                    e = ap_bucket_error_create(HTTP_INTERNAL_SERVER_ERROR,
                                               NULL, 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);
                    ap_pass_brigade(f->next, bb);
                    return AP_FILTER_ERROR;
                }
            }
            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, APLOGNO(01468)
                          "ef_unified_filter() failed");
        }
    
        if ((rv = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(01469)
                          "ap_pass_brigade() failed");
        }
        return rv;
    }
    
    static apr_status_t 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;
    
        /* 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);
        }
    
        if (!ctx) {
            if ((rv = init_filter_instance(f)) != APR_SUCCESS) {
                ctx = f->ctx;
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(01470)
                              "can't initialise input filter %s: %s",
                              f->frec->name,
                              (ctx->dc->onfail == 1) ? "removing" : "aborting");
                ap_remove_input_filter(f);
                if (ctx->dc->onfail == 1) {
                    return ap_get_brigade(f->next, bb, mode, block, readbytes);
                }
                else {
                    f->r->status = HTTP_INTERNAL_SERVER_ERROR;
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
            ctx = f->ctx;
        }
    
        if (ctx->hit_eos) {
            /* Match behaviour of HTTP_IN if filter is re-invoked after
             * hitting EOS: give back another EOS. */
            apr_bucket *e = apr_bucket_eos_create(f->c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, e);
            return APR_SUCCESS;
        }
    
        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;
    }
    
    AP_DECLARE_MODULE(ext_filter) =
    {
        STANDARD20_MODULE_STUFF,
        create_ef_dir_conf,
        merge_ef_dir_conf,
        create_ef_server_conf,
        NULL,
        cmds,
        register_hooks
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_proxy_html.c�������������������������������������������������������0000664�0001751�0001751�00000143262�14640775605�021200� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*      Copyright (c) 2003-11, WebThing Ltd
     *      Copyright (c) 2011-, The Apache Software Foundation
     *
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*      GO_FASTER
            You can #define GO_FASTER to disable trace logging.
    */
    
    #ifdef GO_FASTER
    #define VERBOSE(x)
    #define VERBOSEB(x)
    #else
    #define VERBOSE(x) if (verbose) x
    #define VERBOSEB(x) if (verbose) {x}
    #endif
    
    /* libxml2 includes unicode/[...].h files which uses C++ comments */
    #if defined(__clang__)
    #pragma clang diagnostic push
    #pragma clang diagnostic warning "-Wcomment"
    #elif defined(__GNUC__)
    #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic warning "-Wcomment"
    #endif
    #endif
    
    /* libxml2 */
    #include <libxml/HTMLparser.h>
    
    #if defined(__clang__)
    #pragma clang diagnostic pop
    #elif defined(__GNUC__)
    #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
    #pragma GCC diagnostic pop
    #endif
    #endif
    
    #include "http_protocol.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "apr_strings.h"
    #include "apr_hash.h"
    #include "apr_strmatch.h"
    #include "apr_lib.h"
    
    #include "apr_optional.h"
    #include "mod_xml2enc.h"
    #include "http_request.h"
    #include "ap_expr.h"
    
    /* globals set once at startup */
    static ap_rxplus_t *old_expr;
    static ap_regex_t *seek_meta;
    static const apr_strmatch_pattern* seek_content;
    static apr_status_t (*xml2enc_charset)(request_rec*, xmlCharEncoding*, const char**) = NULL;
    static apr_status_t (*xml2enc_filter)(request_rec*, const char*, unsigned int) = NULL;
    
    module AP_MODULE_DECLARE_DATA proxy_html_module;
    
    #define M_HTML                  0x01
    #define M_EVENTS                0x02
    #define M_CDATA                 0x04
    #define M_REGEX                 0x08
    #define M_ATSTART               0x10
    #define M_ATEND                 0x20
    #define M_LAST                  0x40
    #define M_NOTLAST               0x80
    #define M_INTERPOLATE_TO        0x100
    #define M_INTERPOLATE_FROM      0x200
    
    typedef struct {
        const char *val;
    } tattr;
    typedef struct {
        unsigned int start;
        unsigned int end;
    } meta;
    typedef struct urlmap {
        struct urlmap *next;
        unsigned int flags;
        unsigned int regflags;
        union {
            const char *c;
            ap_regex_t *r;
        } from;
        const char *to;
        ap_expr_info_t *cond;
    } urlmap;
    typedef struct {
        urlmap *map;
        const char *doctype;
        const char *etag;
        unsigned int flags;
        int bufsz;
        apr_hash_t *links;
        apr_array_header_t *events;
        const char *charset_out;
        int extfix;
        int metafix;
        int strip_comments;
        int interp;
        int enabled;
    } proxy_html_conf;
    typedef struct {
        ap_filter_t *f;
        proxy_html_conf *cfg;
        htmlParserCtxtPtr parser;
        apr_bucket_brigade *bb;
        char *buf;
        size_t offset;
        size_t avail;
        const char *encoding;
        urlmap *map;
        char rbuf[4];
        apr_size_t rlen;
        apr_size_t rmin;
    } saxctxt;
    
    
    #define NORM_LC 0x1
    #define NORM_MSSLASH 0x2
    #define NORM_RESET 0x4
    static htmlSAXHandler sax;
    
    typedef enum { ATTR_IGNORE, ATTR_URI, ATTR_EVENT } rewrite_t;
    
    static const char *const fpi_html =
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n";
    static const char *const fpi_html_legacy =
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
    static const char *const fpi_xhtml =
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
    static const char *const fpi_xhtml_legacy =
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
    static const char *const fpi_html5 = "<!DOCTYPE html>\n";
    static const char *const html_etag = ">";
    static const char *const xhtml_etag = " />";
    /*#define DEFAULT_DOCTYPE fpi_html */
    static const char *const DEFAULT_DOCTYPE = "";
    #define DEFAULT_ETAG html_etag
    
    static void normalise(unsigned int flags, char *str)
    {
        char *p;
        if (flags & NORM_LC)
            for (p = str; *p; ++p)
                if (isupper(*p))
                    *p = tolower(*p);
    
        if (flags & NORM_MSSLASH)
            for (p = ap_strchr(str, '\\'); p; p = ap_strchr(p+1, '\\'))
                *p = '/';
    
    }
    #define consume_buffer(ctx,inbuf,bytes,flag) \
            htmlParseChunk(ctx->parser, inbuf, bytes, flag)
    
    #define AP_fwrite(ctx,inbuf,bytes,flush) \
            ap_fwrite(ctx->f->next, ctx->bb, inbuf, bytes);
    
    /* This is always utf-8 on entry.  We can convert charset within FLUSH */
    #define FLUSH AP_fwrite(ctx, (chars+begin), (i-begin), 0); begin = i+1
    static void pcharacters(void *ctxt, const xmlChar *uchars, int length)
    {
        const char *chars = (const char*) uchars;
        saxctxt *ctx = (saxctxt*) ctxt;
        int i;
        int begin;
        for (begin=i=0; i<length; i++) {
            switch (chars[i]) {
            case '&' : FLUSH; ap_fputs(ctx->f->next, ctx->bb, "&amp;"); break;
            case '<' : FLUSH; ap_fputs(ctx->f->next, ctx->bb, "&lt;"); break;
            case '>' : FLUSH; ap_fputs(ctx->f->next, ctx->bb, "&gt;"); break;
            case '"' : FLUSH; ap_fputs(ctx->f->next, ctx->bb, "&quot;"); break;
            default : break;
            }
        }
        FLUSH;
    }
    
    static void preserve(saxctxt *ctx, const size_t len)
    {
        char *newbuf;
        if (len <= (ctx->avail - ctx->offset))
            return;
        else while (len > (ctx->avail - ctx->offset))
            ctx->avail += ctx->cfg->bufsz;
    
        newbuf = realloc(ctx->buf, ctx->avail);
        if (newbuf != ctx->buf) {
            if (ctx->buf)
                apr_pool_cleanup_kill(ctx->f->r->pool, ctx->buf,
                                      (int(*)(void*))free);
            apr_pool_cleanup_register(ctx->f->r->pool, newbuf,
                                      (int(*)(void*))free, apr_pool_cleanup_null);
            ctx->buf = newbuf;
        }
    }
    
    static void pappend(saxctxt *ctx, const char *buf, const size_t len)
    {
        preserve(ctx, len);
        memcpy(ctx->buf+ctx->offset, buf, len);
        ctx->offset += len;
    }
    
    static void dump_content(saxctxt *ctx)
    {
        urlmap *m;
        char *found;
        size_t s_from, s_to;
        size_t match;
        char c = 0;
        int nmatch;
        ap_regmatch_t pmatch[10];
        char *subs;
        size_t len, offs;
        urlmap *themap = ctx->map;
    #ifndef GO_FASTER
        int verbose = APLOGrtrace1(ctx->f->r);
    #endif
    
        pappend(ctx, &c, 1);        /* append null byte */
            /* parse the text for URLs */
        for (m = themap; m; m = m->next) {
            if (!(m->flags & M_CDATA))
                continue;
            if (m->flags & M_REGEX) {
                nmatch = 10;
                offs = 0;
                while (!ap_regexec(m->from.r, ctx->buf+offs, nmatch, pmatch, 0)) {
                    match = pmatch[0].rm_so;
                    s_from = pmatch[0].rm_eo - match;
                    subs = ap_pregsub(ctx->f->r->pool, m->to, ctx->buf+offs,
                                      nmatch, pmatch);
                    s_to = strlen(subs);
                    len = strlen(ctx->buf);
                    offs += match;
                    VERBOSEB(
                        const char *f = apr_pstrndup(ctx->f->r->pool,
                        ctx->buf + offs, s_from);
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, ctx->f->r,
                                      "C/RX: match at %s, substituting %s", f, subs);
                    )
                    if (s_to > s_from) {
                        preserve(ctx, s_to - s_from);
                        memmove(ctx->buf+offs+s_to, ctx->buf+offs+s_from,
                                len + 1 - s_from - offs);
                        memcpy(ctx->buf+offs, subs, s_to);
                    }
                    else {
                        memcpy(ctx->buf + offs, subs, s_to);
                        memmove(ctx->buf+offs+s_to, ctx->buf+offs+s_from,
                                len + 1 - s_from - offs);
                    }
                    offs += s_to;
                }
            }
            else {
                s_from = strlen(m->from.c);
                s_to = strlen(m->to);
                for (found = strstr(ctx->buf, m->from.c); found;
                     found = strstr(ctx->buf+match+s_to, m->from.c)) {
                    match = found - ctx->buf;
                    if ((m->flags & M_ATSTART) && (match != 0))
                        break;
                    len = strlen(ctx->buf);
                    if ((m->flags & M_ATEND) && (match < (len - s_from)))
                        continue;
                    VERBOSE(ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, ctx->f->r,
                                          "C: matched %s, substituting %s",
                                          m->from.c, m->to));
                    if (s_to > s_from) {
                        preserve(ctx, s_to - s_from);
                        memmove(ctx->buf+match+s_to, ctx->buf+match+s_from,
                                len + 1 - s_from - match);
                        memcpy(ctx->buf+match, m->to, s_to);
                    }
                    else {
                        memcpy(ctx->buf+match, m->to, s_to);
                        memmove(ctx->buf+match+s_to, ctx->buf+match+s_from,
                                len + 1 - s_from - match);
                    }
                }
            }
        }
        AP_fwrite(ctx, ctx->buf, strlen(ctx->buf), 1);
    }
    static void pcdata(void *ctxt, const xmlChar *uchars, int length)
    {
        const char *chars = (const char*) uchars;
        saxctxt *ctx = (saxctxt*) ctxt;
        if (ctx->cfg->extfix) {
            pappend(ctx, chars, length);
        }
        else {
            /* not sure if this should force-flush
             * (i.e. can one cdata section come in multiple calls?)
             */
            AP_fwrite(ctx, chars, length, 0);
        }
    }
    static void pcomment(void *ctxt, const xmlChar *uchars)
    {
        const char *chars = (const char*) uchars;
        saxctxt *ctx = (saxctxt*) ctxt;
        if (ctx->cfg->strip_comments)
            return;
    
        if (ctx->cfg->extfix) {
            pappend(ctx, "<!--", 4);
            pappend(ctx, chars, strlen(chars));
            pappend(ctx, "-->", 3);
        }
        else {
            ap_fputs(ctx->f->next, ctx->bb, "<!--");
            AP_fwrite(ctx, chars, strlen(chars), 1);
            ap_fputs(ctx->f->next, ctx->bb, "-->");
            dump_content(ctx);
        }
    }
    static void pendElement(void *ctxt, const xmlChar *uname)
    {
        saxctxt *ctx = (saxctxt*) ctxt;
        const char *name = (const char*) uname;
        const htmlElemDesc* desc = htmlTagLookup(uname);
    
        if ((ctx->cfg->doctype == fpi_html) || (ctx->cfg->doctype == fpi_xhtml)) {
            /* enforce html */
            if (!desc || desc->depr)
                return;
        
        }
        else if ((ctx->cfg->doctype == fpi_html_legacy)
                 || (ctx->cfg->doctype == fpi_xhtml_legacy)) {
            /* enforce html legacy */
            if (!desc)
                return;
        }
        /* TODO - implement HTML "allowed here" using the stack */
        /* nah.  Keeping the stack is too much overhead */
    
        if (ctx->offset > 0) {
            dump_content(ctx);
            ctx->offset = 0;        /* having dumped it, we can re-use the memory */
        }
        if (!desc || !desc->empty) {
            ap_fprintf(ctx->f->next, ctx->bb, "</%s>", name);
        }
    }
    
    static void pstartElement(void *ctxt, const xmlChar *uname,
                              const xmlChar** uattrs)
    {
        int required_attrs;
        int num_match;
        size_t offs, len;
        char *subs;
        rewrite_t is_uri;
        const char** a;
        urlmap *m;
        size_t s_to, s_from, match;
        char *found;
        saxctxt *ctx = (saxctxt*) ctxt;
        size_t nmatch;
        ap_regmatch_t pmatch[10];
    #ifndef GO_FASTER
        int verbose = APLOGrtrace1(ctx->f->r);
    #endif
        apr_array_header_t *linkattrs;
        int i;
        const char *name = (const char*) uname;
        const char** attrs = (const char**) uattrs;
        const htmlElemDesc* desc = htmlTagLookup(uname);
        urlmap *themap = ctx->map;
    #ifdef HAVE_STACK
        const void** descp;
    #endif
        int enforce = 0;
        if ((ctx->cfg->doctype == fpi_html) || (ctx->cfg->doctype == fpi_xhtml)) {
            /* enforce html */
            if (!desc || desc->depr) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->f->r, APLOGNO(01416)
                              "Bogus HTML element %s dropped", name);
                return;
            }
            enforce = 2;
        }
        else if ((ctx->cfg->doctype == fpi_html_legacy)
                 || (ctx->cfg->doctype == fpi_xhtml_legacy)) {
            /* enforce html legacy */
            if (!desc) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->f->r, APLOGNO(01417)
                              "Deprecated HTML element %s dropped", name);
                return;
            }
            enforce = 1;
        }
    #ifdef HAVE_STACK
        descp = apr_array_push(ctx->stack);
        *descp = desc;
        /* TODO - implement HTML "allowed here" */
    #endif
    
        ap_fputc(ctx->f->next, ctx->bb, '<');
        ap_fputs(ctx->f->next, ctx->bb, name);
    
        required_attrs = 0;
        if ((enforce > 0) && (desc != NULL) && (desc->attrs_req != NULL))
            for (a = desc->attrs_req; *a; a++)
                ++required_attrs;
    
        if (attrs) {
            linkattrs = apr_hash_get(ctx->cfg->links, name, APR_HASH_KEY_STRING);
            for (a = attrs; *a; a += 2) {
                if (desc && enforce > 0) {
                    switch (htmlAttrAllowed(desc, (xmlChar*)*a, 2-enforce)) {
                    case HTML_INVALID:
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->f->r, APLOGNO(01418)
                                      "Bogus HTML attribute %s of %s dropped",
                                      *a, name);
                        continue;
                    case HTML_DEPRECATED:
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->f->r, APLOGNO(01419)
                                      "Deprecated HTML attribute %s of %s dropped",
                                      *a, name);
                        continue;
                    case HTML_REQUIRED:
                        required_attrs--;   /* cross off the number still needed */
                    /* fallthrough - required implies valid */
                    default:
                        break;
                    }
                }
                ctx->offset = 0;
                if (a[1]) {
                    pappend(ctx, a[1], strlen(a[1])+1);
                    is_uri = ATTR_IGNORE;
                    if (linkattrs) {
                        tattr *attrs = (tattr*) linkattrs->elts;
                        for (i=0; i < linkattrs->nelts; ++i) {
                            if (!strcmp(*a, attrs[i].val)) {
                                is_uri = ATTR_URI;
                                break;
                            }
                        }
                    }
                    if ((is_uri == ATTR_IGNORE) && ctx->cfg->extfix
                        && (ctx->cfg->events != NULL)) {
                        for (i=0; i < ctx->cfg->events->nelts; ++i) {
                            tattr *attrs = (tattr*) ctx->cfg->events->elts;
                            if (!strcmp(*a, attrs[i].val)) {
                                is_uri = ATTR_EVENT;
                                break;
                            }
                        }
                    }
                    switch (is_uri) {
                    case ATTR_URI:
                        num_match = 0;
                        for (m = themap; m; m = m->next) {
                            if (!(m->flags & M_HTML))
                                continue;
                            if (m->flags & M_REGEX) {
                                nmatch = 10;
                                if (!ap_regexec(m->from.r, ctx->buf, nmatch,
                                                pmatch, 0)) {
                                    ++num_match;
                                    offs = match = pmatch[0].rm_so;
                                    s_from = pmatch[0].rm_eo - match;
                                    subs = ap_pregsub(ctx->f->r->pool, m->to,
                                                      ctx->buf, nmatch, pmatch);
                                    VERBOSE({
                                        const char *f;
                                        f = apr_pstrndup(ctx->f->r->pool,
                                                         ctx->buf + offs, s_from);
                                        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0,
                                                      ctx->f->r,
                                             "H/RX: match at %s, substituting %s",
                                                      f, subs);
                                    })
                                    s_to = strlen(subs);
                                    len = strlen(ctx->buf);
                                    if (s_to > s_from) {
                                        preserve(ctx, s_to - s_from);
                                        memmove(ctx->buf+offs+s_to,
                                                ctx->buf+offs+s_from,
                                                len + 1 - s_from - offs);
                                        memcpy(ctx->buf+offs, subs, s_to);
                                    }
                                    else {
                                        memcpy(ctx->buf + offs, subs, s_to);
                                        memmove(ctx->buf+offs+s_to,
                                                ctx->buf+offs+s_from,
                                                len + 1 - s_from - offs);
                                    }
                                }
                            } else {
                                s_from = strlen(m->from.c);
                                if (!strncasecmp(ctx->buf, m->from.c, s_from)) {
                                    ++num_match;
                                    s_to = strlen(m->to);
                                    len = strlen(ctx->buf);
                                    VERBOSE(ap_log_rerror(APLOG_MARK, APLOG_TRACE3,
                                                          0, ctx->f->r,
                                                  "H: matched %s, substituting %s",
                                                          m->from.c, m->to));
                                    if (s_to > s_from) {
                                        preserve(ctx, s_to - s_from);
                                        memmove(ctx->buf+s_to, ctx->buf+s_from,
                                                len + 1 - s_from);
                                        memcpy(ctx->buf, m->to, s_to);
                                    }
                                    else {     /* it fits in the existing space */
                                        memcpy(ctx->buf, m->to, s_to);
                                        memmove(ctx->buf+s_to, ctx->buf+s_from,
                                                len + 1 - s_from);
                                    }
                                    break;
                                }
                            }
                            /* URIs only want one match unless overridden in the config */
                            if ((num_match > 0) && !(m->flags & M_NOTLAST))
                                break;
                        }
                        break;
                    case ATTR_EVENT:
                        for (m = themap; m; m = m->next) {
                            num_match = 0;        /* reset here since we're working per-rule */
                            if (!(m->flags & M_EVENTS))
                                continue;
                            if (m->flags & M_REGEX) {
                                nmatch = 10;
                                offs = 0;
                                while (!ap_regexec(m->from.r, ctx->buf+offs,
                                                   nmatch, pmatch, 0)) {
                                    match = pmatch[0].rm_so;
                                    s_from = pmatch[0].rm_eo - match;
                                    subs = ap_pregsub(ctx->f->r->pool, m->to, ctx->buf+offs,
                                                        nmatch, pmatch);
                                    VERBOSE({
                                        const char *f;
                                        f = apr_pstrndup(ctx->f->r->pool,
                                                         ctx->buf + offs, s_from);
                                        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0,
                                                      ctx->f->r,
                                               "E/RX: match at %s, substituting %s",
                                                      f, subs);
                                    })
                                    s_to = strlen(subs);
                                    offs += match;
                                    len = strlen(ctx->buf);
                                    if (s_to > s_from) {
                                        preserve(ctx, s_to - s_from);
                                        memmove(ctx->buf+offs+s_to,
                                                ctx->buf+offs+s_from,
                                                len + 1 - s_from - offs);
                                        memcpy(ctx->buf+offs, subs, s_to);
                                    }
                                    else {
                                        memcpy(ctx->buf + offs, subs, s_to);
                                        memmove(ctx->buf+offs+s_to,
                                                ctx->buf+offs+s_from,
                                                len + 1 - s_from - offs);
                                    }
                                    offs += s_to;
                                    ++num_match;
                                }
                            }
                            else {
                                found = strstr(ctx->buf, m->from.c);
                                if ((m->flags & M_ATSTART) && (found != ctx->buf))
                                    continue;
                                while (found) {
                                    s_from = strlen(m->from.c);
                                    s_to = strlen(m->to);
                                    match = found - ctx->buf;
                                    if ((s_from < strlen(found))
                                        && (m->flags & M_ATEND)) {
                                        found = strstr(ctx->buf+match+s_from,
                                                       m->from.c);
                                        continue;
                                    }
                                    else {
                                        found = strstr(ctx->buf+match+s_to,
                                                       m->from.c);
                                    }
                                    VERBOSE(ap_log_rerror(APLOG_MARK, APLOG_TRACE3,
                                                          0, ctx->f->r,
                                                  "E: matched %s, substituting %s",
                                                          m->from.c, m->to));
                                    len = strlen(ctx->buf);
                                    if (s_to > s_from) {
                                        preserve(ctx, s_to - s_from);
                                        memmove(ctx->buf+match+s_to,
                                                ctx->buf+match+s_from,
                                                len + 1 - s_from - match);
                                        memcpy(ctx->buf+match, m->to, s_to);
                                    }
                                    else {
                                        memcpy(ctx->buf+match, m->to, s_to);
                                        memmove(ctx->buf+match+s_to,
                                                ctx->buf+match+s_from,
                                                len + 1 - s_from - match);
                                    }
                                    ++num_match;
                                }
                            }
                            if (num_match && (m->flags & M_LAST))
                                break;
                        }
                        break;
                    case ATTR_IGNORE:
                        break;
                    }
                }
                if (!a[1])
                    ap_fputstrs(ctx->f->next, ctx->bb, " ", a[0], NULL);
                else {
    
                    if (ctx->cfg->flags != 0)
                        normalise(ctx->cfg->flags, ctx->buf);
    
                    /* write the attribute, using pcharacters to html-escape
                       anything that needs it in the value.
                    */
                    ap_fputstrs(ctx->f->next, ctx->bb, " ", a[0], "=\"", NULL);
                    pcharacters(ctx, (const xmlChar*)ctx->buf, strlen(ctx->buf));
                    ap_fputc(ctx->f->next, ctx->bb, '"');
                }
            }
        }
        ctx->offset = 0;
        if (desc && desc->empty)
            ap_fputs(ctx->f->next, ctx->bb, ctx->cfg->etag);
        else
            ap_fputc(ctx->f->next, ctx->bb, '>');
    
        if ((enforce > 0) && (required_attrs > 0)) {
            /* if there are more required attributes than we found then complain */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->f->r, APLOGNO(01420)
                          "HTML element %s is missing %d required attributes",
                          name, required_attrs);
        }
    }
    
    static meta *metafix(request_rec *r, const char *buf, apr_size_t len)
    {
        meta *ret = NULL;
        size_t offs = 0;
        const char *p;
        const char *q;
        char *header;
        char *content;
        ap_regmatch_t pmatch[2];
        char delim;
    
        while (offs < len &&
               !ap_regexec_len(seek_meta, buf + offs, len - offs, 2, pmatch, 0)) {
            header = NULL;
            content = NULL;
            p = buf+offs+pmatch[1].rm_eo;
            while (!apr_isalpha(*++p));
            for (q = p; apr_isalnum(*q) || (*q == '-'); ++q);
            header = apr_pstrmemdup(r->pool, p, q-p);
            if (ap_cstr_casecmpn(header, "Content-", 8)) {
                /* find content=... string */
                p = apr_strmatch(seek_content, buf+offs+pmatch[0].rm_so,
                                  pmatch[0].rm_eo - pmatch[0].rm_so);
                /* if it doesn't contain "content", ignore, don't crash! */
                if (p != NULL) {
                    while (*p) {
                        p += 7;
                        while (apr_isspace(*p))
                            ++p;
                        /* XXX Should we search for another content= pattern? */
                        if (*p != '=')
                            break;
                        while (*p && apr_isspace(*++p));
                        if ((*p == '\'') || (*p == '"')) {
                            delim = *p++;
                            for (q = p; *q && *q != delim; ++q);
                            /* No terminating delimiter found? Skip the bogus directive */
                            if (*q != delim)
                               break;
                        } else {
                            for (q = p; *q && !apr_isspace(*q) && (*q != '>'); ++q);
                        }
                        content = apr_pstrmemdup(r->pool, p, q-p);
                        break;
                    }
                }
            }
            else if (!ap_cstr_casecmpn(header, "Content-Type", 12)) {
                ret = apr_palloc(r->pool, sizeof(meta));
                ret->start = offs+pmatch[0].rm_so;
                ret->end = offs+pmatch[0].rm_eo;
            }
            if (header && content) {
    #ifndef GO_FASTER
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "Adding header [%s: %s] from HTML META",
                              header, content); 
    #endif
                apr_table_setn(r->headers_out, header, content);
            }
            offs += pmatch[0].rm_eo;
        }
        return ret;
    }
    
    static const char *interpolate_vars(request_rec *r, const char *str)
    {
        const char *start;
        const char *end;
        const char *delim;
        const char *before;
        const char *after;
        const char *replacement;
        const char *var;
        for (;;) {
            if ((start = ap_strstr_c(str, "${")) == NULL)
                break;
    
            if ((end = ap_strchr_c(start+2, '}')) == NULL)
                break;
    
            delim = ap_strchr_c(start+2, '|');
    
            /* Restrict delim to ${...} */
            if (delim && delim >= end) {
                delim = NULL;
            }
    
            before = apr_pstrmemdup(r->pool, str, start-str);
            after = end+1;
            if (delim) {
                var = apr_pstrmemdup(r->pool, start+2, delim-start-2);
            }
            else {
                var = apr_pstrmemdup(r->pool, start+2, end-start-2);
            }
            replacement = apr_table_get(r->subprocess_env, var);
            if (!replacement) {
                if (delim)
                    replacement = apr_pstrmemdup(r->pool, delim+1, end-delim-1);
                else
                    replacement = "";
            }
            str = apr_pstrcat(r->pool, before, replacement, after, NULL);
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "Interpolating %s  =>  %s", var, replacement);
        }
        return str;
    }
    static void fixup_rules(saxctxt *ctx)
    {
        urlmap *newp;
        urlmap *p;
        urlmap *prev = NULL;
        request_rec *r = ctx->f->r;
    
        for (p = ctx->cfg->map; p; p = p->next) {
            if (p->cond != NULL) {
                const char *err;
                int ok = ap_expr_exec(r, p->cond, &err);
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01421)
                                  "Error evaluating expr: %s", err);
                }
                if (ok == 0) {
                    continue;  /* condition is unsatisfied */
                }
            }
    
            newp = apr_pmemdup(r->pool, p, sizeof(urlmap));
    
            if (newp->flags & M_INTERPOLATE_FROM) {
                newp->from.c = interpolate_vars(r, newp->from.c);
                if (!newp->from.c || !*newp->from.c)
                    continue;        /* don't use empty from-pattern */
                if (newp->flags & M_REGEX) {
                    newp->from.r = ap_pregcomp(r->pool, newp->from.c,
                                               newp->regflags);
                }
            }
            if (newp->flags & M_INTERPOLATE_TO) {
                newp->to = interpolate_vars(r, newp->to);
            }
            /* evaluate p->cond; continue if unsatisfied */
            /* create new urlmap with memcpy and append to map */
            /* interpolate from if flagged to do so */
            /* interpolate to if flagged to do so */
    
            if (prev != NULL)
                prev->next = newp;
            else
                ctx->map = newp;
            prev = newp;
        }
    
        if (prev)
            prev->next = NULL;
    }
    
    static saxctxt *check_filter_init (ap_filter_t *f)
    {
        saxctxt *fctx;
        if (!f->ctx) {
            proxy_html_conf *cfg;
            const char *force;
            const char *errmsg = NULL;
            cfg = ap_get_module_config(f->r->per_dir_config, &proxy_html_module);
            force = apr_table_get(f->r->subprocess_env, "PROXY_HTML_FORCE");
    
            if (!force) {
                if (!f->r->proxyreq) {
                    errmsg = "Non-proxy request; not inserting proxy-html filter";
                }
                else if (!f->r->content_type) {
                    errmsg = "No content-type; bailing out of proxy-html filter";
                }
                else if (ap_cstr_casecmpn(f->r->content_type, "text/html", 9) &&
                         ap_cstr_casecmpn(f->r->content_type,
                                     "application/xhtml+xml", 21)) {
                    errmsg = "Non-HTML content; not inserting proxy-html filter";
                }
            }
            if (!cfg->links) {
                errmsg = "No links configured: nothing for proxy-html filter to do";
            }
    
            if (errmsg) {
    #ifndef GO_FASTER
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, f->r, "%s", errmsg);
    #endif
                ap_remove_output_filter(f);
                return NULL;
            }
    
            fctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(saxctxt));
            fctx->f = f;
            fctx->bb = apr_brigade_create(f->r->pool,
                                          f->r->connection->bucket_alloc);
            fctx->cfg = cfg;
            apr_table_unset(f->r->headers_out, "Content-Length");
    
            if (cfg->interp)
                fixup_rules(fctx);
            else
                fctx->map = cfg->map;
            /* defer dealing with charset_out until after sniffing charset_in
             * so we can support setting one to t'other.
             */
        }
        return f->ctx;
    }
    
    static void prepend_rbuf(saxctxt *ctxt, apr_bucket_brigade *bb)
    {
        if (ctxt->rlen) {
            apr_bucket *b = apr_bucket_transient_create(ctxt->rbuf,
                                                        ctxt->rlen,
                                                        bb->bucket_alloc);
            APR_BRIGADE_INSERT_HEAD(bb, b);
            ctxt->rlen = 0;
        }
    }
    
    static apr_status_t proxy_html_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        apr_bucket* b;
        meta *m = NULL;
        xmlCharEncoding enc;
        const char *buf = 0;
        apr_size_t bytes = 0;
    #ifndef USE_OLD_LIBXML2
        int xmlopts = XML_PARSE_RECOVER | XML_PARSE_NONET |
                      XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING;
    #endif
    
        saxctxt *ctxt = check_filter_init(f);
        if (!ctxt)
            return ap_pass_brigade(f->next, bb);
        for (b = APR_BRIGADE_FIRST(bb);
             b != APR_BRIGADE_SENTINEL(bb);
             b = APR_BUCKET_NEXT(b)) {
            if (APR_BUCKET_IS_METADATA(b)) {
                if (APR_BUCKET_IS_EOS(b)) {
                    if (ctxt->parser != NULL) {
                        consume_buffer(ctxt, "", 0, 1);
                    }
                    else {
                        prepend_rbuf(ctxt, ctxt->bb);
                    }
                    APR_BRIGADE_INSERT_TAIL(ctxt->bb,
                        apr_bucket_eos_create(ctxt->bb->bucket_alloc));
                    ap_pass_brigade(ctxt->f->next, ctxt->bb);
                    apr_brigade_cleanup(ctxt->bb);
                }
                else if (APR_BUCKET_IS_FLUSH(b)) {
                    /* pass on flush, except at start where it would cause
                     * headers to be sent before doc sniffing
                     */
                    if (ctxt->parser != NULL) {
                        ap_fflush(ctxt->f->next, ctxt->bb);
                    }
                }
            }
            else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
                     == APR_SUCCESS) {
                if (ctxt->parser == NULL) {
                    const char *cenc;
    
                    /* For documents smaller than four bytes, there is no reason to do
                     * HTML rewriting. The URL schema (i.e. 'http') needs four bytes alone.
                     * And the HTML parser needs at least four bytes to initialise correctly.
                     */
                    ctxt->rmin += bytes;
                    if (ctxt->rmin < sizeof(ctxt->rbuf)) {
                        memcpy(ctxt->rbuf + ctxt->rlen, buf, bytes);
                        ctxt->rlen += bytes;
                        continue;
                    }
                    if (ctxt->rlen && ctxt->rlen < sizeof(ctxt->rbuf)) {
                        apr_size_t rem = sizeof(ctxt->rbuf) - ctxt->rlen;
                        memcpy(ctxt->rbuf + ctxt->rlen, buf, rem);
                        ctxt->rlen += rem;
                        buf += rem;
                        bytes -= rem;
                    }
    
                    if (!xml2enc_charset ||
                        (xml2enc_charset(f->r, &enc, &cenc) != APR_SUCCESS)) {
                        if (!xml2enc_charset)
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r, APLOGNO(01422)
                                          "No i18n support found.  Install mod_xml2enc if required");
                        enc = XML_CHAR_ENCODING_NONE;
                        ap_set_content_type_ex(f->r, "text/html;charset=utf-8", 1);
                    }
                    else {
                        /* if we wanted a non-default charset_out, insert the
                         * xml2enc filter now that we've sniffed it
                         */
                        if (ctxt->cfg->charset_out && xml2enc_filter) {
                            if (*ctxt->cfg->charset_out != '*')
                                cenc = ctxt->cfg->charset_out;
                            xml2enc_filter(f->r, cenc, ENCIO_OUTPUT);
                            ap_set_content_type(f->r,
                                                apr_pstrcat(f->r->pool,
                                                            "text/html;charset=",
                                                            cenc, NULL));
                        }
                        else /* Normal case, everything worked, utf-8 output */
                            ap_set_content_type_ex(f->r, "text/html;charset=utf-8", 1);
                    }
    
                    ap_fputs(f->next, ctxt->bb, ctxt->cfg->doctype);
    
                    if (ctxt->rlen) {
                        ctxt->parser = htmlCreatePushParserCtxt(&sax, ctxt,
                                                                ctxt->rbuf,
                                                                ctxt->rlen,
                                                                NULL, enc);
                    }
                    else {
                        ctxt->parser = htmlCreatePushParserCtxt(&sax, ctxt, buf, 4,
                                                                NULL, enc);
                        buf += 4;
                        bytes -= 4;
                    }
                    if (ctxt->parser == NULL) {
                        prepend_rbuf(ctxt, bb);
                        ap_remove_output_filter(f);
                        return ap_pass_brigade(f->next, bb);
                    }
                    ctxt->rlen = 0;
                    apr_pool_cleanup_register(f->r->pool, ctxt->parser,
                                              (int(*)(void*))htmlFreeParserCtxt,
                                              apr_pool_cleanup_null);
    #ifndef USE_OLD_LIBXML2
                    if (xmlopts = xmlCtxtUseOptions(ctxt->parser, xmlopts), xmlopts)
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r, APLOGNO(01423)
                                      "Unsupported parser opts %x", xmlopts);
    #endif
                    if (ctxt->cfg->metafix)
                        m = metafix(f->r, buf, bytes);
                    if (m) {
                        consume_buffer(ctxt, buf, m->start, 0);
                        consume_buffer(ctxt, buf+m->end, bytes-m->end, 0);
                    }
                    else {
                        consume_buffer(ctxt, buf, bytes, 0);
                    }
                }
                else {
                    consume_buffer(ctxt, buf, bytes, 0);
                }
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(01424)
                              "Error in bucket read");
            }
        }
        /*ap_fflush(ctxt->f->next, ctxt->bb);        // uncomment for debug */
        apr_brigade_cleanup(bb);
        return APR_SUCCESS;
    }
    
    static void *proxy_html_config(apr_pool_t *pool, char *x)
    {
        proxy_html_conf *ret = apr_pcalloc(pool, sizeof(proxy_html_conf));
        ret->doctype = DEFAULT_DOCTYPE;
        ret->etag = DEFAULT_ETAG;
        ret->bufsz = 8192;
        /* ret->interp = 1; */
        /* don't initialise links and events until they get set/used */
        return ret;
    }
    
    static void *proxy_html_merge(apr_pool_t *pool, void *BASE, void *ADD)
    {
        proxy_html_conf *base = (proxy_html_conf *) BASE;
        proxy_html_conf *add = (proxy_html_conf *) ADD;
        proxy_html_conf *conf = apr_palloc(pool, sizeof(proxy_html_conf));
    
        /* don't merge declarations - just use the most specific */
        conf->links = (add->links == NULL) ? base->links : add->links;
        conf->events = (add->events == NULL) ? base->events : add->events;
    
        conf->charset_out = (add->charset_out == NULL)
                            ? base->charset_out : add->charset_out;
    
        if (add->map && base->map) {
            urlmap *a;
            conf->map = NULL;
            for (a = base->map; a; a = a->next) {
                urlmap *save = conf->map;
                conf->map = apr_pmemdup(pool, a, sizeof(urlmap));
                conf->map->next = save;
            }
            for (a = add->map; a; a = a->next) {
                urlmap *save = conf->map;
                conf->map = apr_pmemdup(pool, a, sizeof(urlmap));
                conf->map->next = save;
            }
        }
        else
            conf->map = add->map ? add->map : base->map;
    
        conf->doctype = (add->doctype == DEFAULT_DOCTYPE)
                        ? base->doctype : add->doctype;
        conf->etag = (add->etag == DEFAULT_ETAG) ? base->etag : add->etag;
        conf->bufsz = add->bufsz;
        if (add->flags & NORM_RESET) {
            conf->flags = add->flags ^ NORM_RESET;
            conf->metafix = add->metafix;
            conf->extfix = add->extfix;
            conf->interp = add->interp;
            conf->strip_comments = add->strip_comments;
            conf->enabled = add->enabled;
        }
        else {
            conf->flags = base->flags | add->flags;
            conf->metafix = base->metafix | add->metafix;
            conf->extfix = base->extfix | add->extfix;
            conf->interp = base->interp | add->interp;
            conf->strip_comments = base->strip_comments | add->strip_comments;
            conf->enabled = add->enabled | base->enabled;
        }
        return conf;
    }
    #define REGFLAG(n,s,c) ((s&&(ap_strchr_c((s),(c))!=NULL)) ? (n) : 0)
    #define XREGFLAG(n,s,c) ((!s||(ap_strchr_c((s),(c))==NULL)) ? (n) : 0)
    static const char *comp_urlmap(cmd_parms *cmd, urlmap *newmap,
                                   const char *from, const char *to,
                                   const char *flags, const char *cond)
    {
        const char *err = NULL;
        newmap->flags
            = XREGFLAG(M_HTML,flags,'h')
            | XREGFLAG(M_EVENTS,flags,'e')
            | XREGFLAG(M_CDATA,flags,'c')
            | REGFLAG(M_ATSTART,flags,'^')
            | REGFLAG(M_ATEND,flags,'$')
            | REGFLAG(M_REGEX,flags,'R')
            | REGFLAG(M_LAST,flags,'L')
            | REGFLAG(M_NOTLAST,flags,'l')
            | REGFLAG(M_INTERPOLATE_TO,flags,'V')
            | REGFLAG(M_INTERPOLATE_FROM,flags,'v');
    
        if ((newmap->flags & M_INTERPOLATE_FROM) || !(newmap->flags & M_REGEX)) {
            newmap->from.c = from;
            newmap->to = to;
        }
        else {
            newmap->regflags
                = REGFLAG(AP_REG_EXTENDED,flags,'x')
                | REGFLAG(AP_REG_ICASE,flags,'i')
                | REGFLAG(AP_REG_NOSUB,flags,'n')
                | REGFLAG(AP_REG_NEWLINE,flags,'s');
            newmap->from.r = ap_pregcomp(cmd->pool, from, newmap->regflags);
            newmap->to = to;
        }
        if (cond != NULL) {
            /* back-compatibility: support old-style ENV expressions
             * by converting to ap_expr syntax.
             *
             * 1. var --> env(var)
             * 2. var=val --> env(var)=val
             * 3. !var --> !env(var)
             * 4. !var=val --> env(var)!=val
             */
            char *newcond = NULL;
            if (ap_rxplus_exec(cmd->temp_pool, old_expr, cond, &newcond)) {
               /* we got a substitution.  Check for the case (3) above
                * that the regexp gets wrong: a negation without a comparison.
                */
                if ((cond[0] == '!') && !ap_strchr_c(cond, '=')) {
                    memmove(newcond+1, newcond, strlen(newcond)-1);
                    newcond[0] = '!';
                }
                cond = newcond;
            }
            newmap->cond = ap_expr_parse_cmd(cmd, cond, 0, &err, NULL);
        }
        else {
            newmap->cond = NULL;
        }
        return err;
    }
    
    static const char *set_urlmap(cmd_parms *cmd, void *CFG, const char *args)
    {
        proxy_html_conf *cfg = (proxy_html_conf *)CFG;
        urlmap *map;
        apr_pool_t *pool = cmd->pool;
        urlmap *newmap;
        const char *usage =
                  "Usage: ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]";
        const char *from;
        const char *to;
        const char *flags;
        const char *cond = NULL;
      
        if (from = ap_getword_conf(cmd->pool, &args), !from)
            return usage;
        if (to = ap_getword_conf(cmd->pool, &args), !to)
            return usage;
        flags = ap_getword_conf(cmd->pool, &args);
        if (flags && *flags)
            cond = ap_getword_conf(cmd->pool, &args);
        if (cond && !*cond)
            cond = NULL;
    
        /* the args look OK, so let's use them */
        newmap = apr_palloc(pool, sizeof(urlmap));
        newmap->next = NULL;
        if (cfg->map) {
            for (map = cfg->map; map->next; map = map->next);
            map->next = newmap;
        }
        else
            cfg->map = newmap;
    
        return comp_urlmap(cmd, newmap, from, to, flags, cond);
    }
    
    static const char *set_doctype(cmd_parms *cmd, void *CFG,
                                   const char *t, const char *l)
    {
        proxy_html_conf *cfg = (proxy_html_conf *)CFG;
        if (!strcasecmp(t, "xhtml")) {
            cfg->etag = xhtml_etag;
            if (l && !strcasecmp(l, "legacy"))
                cfg->doctype = fpi_xhtml_legacy;
            else
                cfg->doctype = fpi_xhtml;
        }
        else if (!strcasecmp(t, "html")) {
            cfg->etag = html_etag;
            if (l && !strcasecmp(l, "legacy"))
                cfg->doctype = fpi_html_legacy;
            else
                cfg->doctype = fpi_html;
        }
        else if (!strcasecmp(t, "html5")) {
            cfg->etag = html_etag;
            cfg->doctype = fpi_html5;
        }
        else {
            cfg->doctype = t;
            if (l && ((l[0] == 'x') || (l[0] == 'X')))
                cfg->etag = xhtml_etag;
            else
                cfg->etag = html_etag;
        }
        return NULL;
    }
    
    static const char *set_flags(cmd_parms *cmd, void *CFG, const char *arg)
    {
        proxy_html_conf *cfg = CFG;
        if (arg && *arg) {
            if (!strcasecmp(arg, "lowercase"))
                cfg->flags |= NORM_LC;
            else if (!strcasecmp(arg, "dospath"))
                cfg->flags |= NORM_MSSLASH;
            else if (!strcasecmp(arg, "reset"))
                cfg->flags |= NORM_RESET;
        }
        return NULL;
    }
    
    static const char *set_events(cmd_parms *cmd, void *CFG, const char *arg)
    {
        tattr *attr;
        proxy_html_conf *cfg = CFG;
        if (cfg->events == NULL)
            cfg->events = apr_array_make(cmd->pool, 20, sizeof(tattr));
        attr = apr_array_push(cfg->events);
        attr->val = arg;
        return NULL;
    }
    
    static const char *set_links(cmd_parms *cmd, void *CFG,
                                 const char *elt, const char *att)
    {
        apr_array_header_t *attrs;
        tattr *attr;
        proxy_html_conf *cfg = CFG;
    
        if (cfg->links == NULL)
            cfg->links = apr_hash_make(cmd->pool);
    
        attrs = apr_hash_get(cfg->links, elt, APR_HASH_KEY_STRING);
        if (!attrs) {
            attrs = apr_array_make(cmd->pool, 2, sizeof(tattr*));
            apr_hash_set(cfg->links, elt, APR_HASH_KEY_STRING, attrs);
        }
        attr = apr_array_push(attrs);
        attr->val = att;
        return NULL;
    }
    static const command_rec proxy_html_cmds[] = {
        AP_INIT_ITERATE("ProxyHTMLEvents", set_events, NULL,
                        RSRC_CONF|ACCESS_CONF,
                        "Strings to be treated as scripting events"),
        AP_INIT_ITERATE2("ProxyHTMLLinks", set_links, NULL,
                         RSRC_CONF|ACCESS_CONF, "Declare HTML Attributes"),
        AP_INIT_RAW_ARGS("ProxyHTMLURLMap", set_urlmap, NULL,
                         RSRC_CONF|ACCESS_CONF, "Map URL From To"),
        AP_INIT_TAKE12("ProxyHTMLDoctype", set_doctype, NULL,
                       RSRC_CONF|ACCESS_CONF, "(HTML|XHTML) [Legacy]"),
        AP_INIT_ITERATE("ProxyHTMLFixups", set_flags, NULL,
                        RSRC_CONF|ACCESS_CONF, "Options are lowercase, dospath"),
        AP_INIT_FLAG("ProxyHTMLMeta", ap_set_flag_slot,
                     (void*)APR_OFFSETOF(proxy_html_conf, metafix),
                     RSRC_CONF|ACCESS_CONF, "Fix META http-equiv elements"),
        AP_INIT_FLAG("ProxyHTMLInterp", ap_set_flag_slot,
                     (void*)APR_OFFSETOF(proxy_html_conf, interp),
                     RSRC_CONF|ACCESS_CONF,
                     "Support interpolation and conditions in URLMaps"),
        AP_INIT_FLAG("ProxyHTMLExtended", ap_set_flag_slot,
                     (void*)APR_OFFSETOF(proxy_html_conf, extfix),
                     RSRC_CONF|ACCESS_CONF, "Map URLs in Javascript and CSS"),
        AP_INIT_FLAG("ProxyHTMLStripComments", ap_set_flag_slot,
                     (void*)APR_OFFSETOF(proxy_html_conf, strip_comments),
                     RSRC_CONF|ACCESS_CONF, "Strip out comments"),
        AP_INIT_TAKE1("ProxyHTMLBufSize", ap_set_int_slot,
                      (void*)APR_OFFSETOF(proxy_html_conf, bufsz),
                      RSRC_CONF|ACCESS_CONF, "Buffer size"),
        AP_INIT_TAKE1("ProxyHTMLCharsetOut", ap_set_string_slot,
                      (void*)APR_OFFSETOF(proxy_html_conf, charset_out),
                      RSRC_CONF|ACCESS_CONF, "Usage: ProxyHTMLCharsetOut charset"),
        AP_INIT_FLAG("ProxyHTMLEnable", ap_set_flag_slot,
                     (void*)APR_OFFSETOF(proxy_html_conf, enabled),
                     RSRC_CONF|ACCESS_CONF,
                     "Enable proxy-html and xml2enc filters"),
        { NULL }
    };
    static int mod_proxy_html(apr_pool_t *p, apr_pool_t *p1, apr_pool_t *p2)
    {
        seek_meta = ap_pregcomp(p, "<meta[^>]*(http-equiv)[^>]*>",
                                AP_REG_EXTENDED|AP_REG_ICASE);
        seek_content = apr_strmatch_precompile(p, "content", 0);
        memset(&sax, 0, sizeof(htmlSAXHandler));
        sax.startElement = pstartElement;
        sax.endElement = pendElement;
        sax.characters = pcharacters;
        sax.comment = pcomment;
        sax.cdataBlock = pcdata;
        xml2enc_charset = APR_RETRIEVE_OPTIONAL_FN(xml2enc_charset);
        xml2enc_filter = APR_RETRIEVE_OPTIONAL_FN(xml2enc_filter);
        if (!xml2enc_charset) {
            ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p2, APLOGNO(01425)
                          "I18n support in mod_proxy_html requires mod_xml2enc. "
                          "Without it, non-ASCII characters in proxied pages are "
                          "likely to display incorrectly.");
        }
    
        /* old_expr only needs to last the life of the config phase */
        old_expr = ap_rxplus_compile(p1, "s/^(!)?(\\w+)((=)(.+))?$/reqenv('$2')$1$4'$5'/");
        return OK;
    }
    static void proxy_html_insert(request_rec *r)
    {
        proxy_html_conf *cfg;
        cfg = ap_get_module_config(r->per_dir_config, &proxy_html_module);
        if (cfg->enabled) {
            if (xml2enc_filter)
                xml2enc_filter(r, NULL, ENCIO_INPUT_CHECKS);
            ap_add_output_filter("proxy-html", NULL, r, r->connection);
        }
    }
    static void proxy_html_hooks(apr_pool_t *p)
    {
        static const char *aszSucc[] = { "mod_filter.c", NULL };
        ap_register_output_filter_protocol("proxy-html", proxy_html_filter,
                                           NULL, AP_FTYPE_RESOURCE,
                              AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH);
        /* move this to pre_config so old_expr is available to interpret
         * old-style conditions on URL maps.
         */
        ap_hook_pre_config(mod_proxy_html, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_insert_filter(proxy_html_insert, NULL, aszSucc, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(proxy_html) = {
        STANDARD20_MODULE_STUFF,
        proxy_html_config,
        proxy_html_merge,
        NULL,
        NULL,
        proxy_html_cmds,
        proxy_html_hooks
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/sed1.c�����������������������������������������������������������������0000664�0001751�0001751�00000074137�14245660240�016761� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
     * Use is subject to license terms.
     *
     *      Copyright (c) 1984 AT&T
     *        All Rights Reserved
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  http://www.apache.org/licenses/LICENSE-2.0.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "libsed.h"
    #include "sed.h"
    #include "apr_strings.h"
    #include "regexp.h"
    
    static const char *const trans[040]  = {
        "\\01",
        "\\02",
        "\\03",
        "\\04",
        "\\05",
        "\\06",
        "\\07",
        "\\10",
        "\\11",
        "\n",
        "\\13",
        "\\14",
        "\\15",
        "\\16",
        "\\17",
        "\\20",
        "\\21",
        "\\22",
        "\\23",
        "\\24",
        "\\25",
        "\\26",
        "\\27",
        "\\30",
        "\\31",
        "\\32",
        "\\33",
        "\\34",
        "\\35",
        "\\36",
        "\\37"
    };
    static const char rub[] = {"\\177"};
    
    extern int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars);
    static int substitute(sed_eval_t *eval, sed_reptr_t *ipc,
                          step_vars_storage *step_vars);
    static apr_status_t execute(sed_eval_t *eval);
    static int match(sed_eval_t *eval, char *expbuf, int gf,
                     step_vars_storage *step_vars);
    static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
                              step_vars_storage *step_vars);
    static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2);
    static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
                                step_vars_storage *step_vars);
    static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz);
    static apr_status_t arout(sed_eval_t *eval);
    
    static void eval_errf(sed_eval_t *eval, const char *fmt, ...)
    {
        if (eval->errfn && eval->pool) {
            va_list args;
            const char* error;
            va_start(args, fmt);
            error = apr_pvsprintf(eval->pool, fmt, args);
            eval->errfn(eval->data, error);
            va_end(args);
        }
    }
    
    #define INIT_BUF_SIZE 1024
    #define MAX_BUF_SIZE 1024*8192
    
    /*
     * grow_buffer
     */
    static apr_status_t grow_buffer(apr_pool_t *pool, char **buffer,
                            char **spend, apr_size_t *cursize,
                            apr_size_t newsize)
    {
        char* newbuffer = NULL;
        apr_size_t spendsize = 0;
        if (*cursize >= newsize) {
            return APR_SUCCESS;
        }
        /* Avoid number of times realloc is called. It could cause huge memory
         * requirement if line size is huge e.g 2 MB */
        if (newsize < *cursize * 2) {
            newsize = *cursize * 2;
        }
    
        /* Align it to 4 KB boundary */
        newsize = (newsize  + ((1 << 12) - 1)) & ~((1 << 12) - 1);
        if (newsize > MAX_BUF_SIZE) { 
            return APR_ENOMEM;
        }
        newbuffer = apr_pcalloc(pool, newsize);
        if (*spend && *buffer && (*cursize > 0)) {
            spendsize = *spend - *buffer;
        }
        if ((*cursize > 0) && *buffer) {
            memcpy(newbuffer, *buffer, *cursize);
        }
        *buffer = newbuffer;
        *cursize = newsize;
        if (spend != buffer) {
            *spend = *buffer + spendsize;
        }
        return APR_SUCCESS;
    }
    
    /*
     * grow_line_buffer
     */
    static apr_status_t grow_line_buffer(sed_eval_t *eval, apr_size_t newsize)
    {
        return grow_buffer(eval->pool, &eval->linebuf, &eval->lspend,
                    &eval->lsize, newsize);
    }
    
    /*
     * grow_hold_buffer
     */
    static apr_status_t grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize)
    {
        return grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend,
                    &eval->hsize, newsize);
    }
    
    /*
     * grow_gen_buffer
     */
    static apr_status_t grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize,
                                char **gspend)
    {
        apr_status_t rc = 0;
        if (gspend == NULL) {
            gspend = &eval->genbuf;
        }
        rc = grow_buffer(eval->pool, &eval->genbuf, gspend,
                         &eval->gsize, newsize);
        if (rc == APR_SUCCESS) { 
            eval->lcomend = &eval->genbuf[71];
        }
        return rc;
    }
    
    /*
     * appendmem_to_linebuf
     */
    static apr_status_t appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len)
    {
        apr_status_t rc = 0;
        apr_size_t reqsize = (eval->lspend - eval->linebuf) + len;
        if (eval->lsize < reqsize) {
            rc = grow_line_buffer(eval, reqsize);
            if (rc != APR_SUCCESS) { 
                return rc;
            }
        }
        memcpy(eval->lspend, sz, len);
        eval->lspend += len;
        return APR_SUCCESS;
    }
    
    /*
     * append_to_linebuf
     */
    static apr_status_t append_to_linebuf(sed_eval_t *eval, const char* sz,
                                  step_vars_storage *step_vars)
    {
        apr_size_t len = strlen(sz);
        char *old_linebuf = eval->linebuf;
        apr_status_t rc = 0;
        /* Copy string including null character */
        rc = appendmem_to_linebuf(eval, sz, len + 1);
        if (rc != APR_SUCCESS) { 
            return rc;
        }
        --eval->lspend; /* lspend will now point to NULL character */
        /* Sync step_vars after a possible linebuf expansion */
        if (step_vars && old_linebuf != eval->linebuf) {
            if (step_vars->loc1) {
                step_vars->loc1 = step_vars->loc1 - old_linebuf + eval->linebuf;
            }
            if (step_vars->loc2) {
                step_vars->loc2 = step_vars->loc2 - old_linebuf + eval->linebuf;
            }
            if (step_vars->locs) {
                step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf;
            }
        }
        return APR_SUCCESS;
    }
    
    /*
     * copy_to_linebuf
     */
    static apr_status_t copy_to_linebuf(sed_eval_t *eval, const char* sz,
                                step_vars_storage *step_vars)
    {
        eval->lspend = eval->linebuf;
        return append_to_linebuf(eval, sz, step_vars);
    }
    
    /*
     * append_to_holdbuf
     */
    static apr_status_t append_to_holdbuf(sed_eval_t *eval, const char* sz)
    {
        apr_size_t len = strlen(sz);
        apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1;
        apr_status_t rc = 0;
        if (eval->hsize <= reqsize) {
            rc = grow_hold_buffer(eval, reqsize);
            if (rc != APR_SUCCESS) { 
                return rc;
            }
        }
        memcpy(eval->hspend, sz, len + 1);
        /* hspend will now point to NULL character */
        eval->hspend += len;
        return APR_SUCCESS;
    }
    
    /*
     * copy_to_holdbuf
     */
    static apr_status_t copy_to_holdbuf(sed_eval_t *eval, const char* sz)
    {
        eval->hspend = eval->holdbuf;
        return append_to_holdbuf(eval, sz);
    }
    
    /*
     * append_to_genbuf
     */
    static apr_status_t append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
    {
        apr_size_t len = strlen(sz);
        apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1;
        apr_status_t rc = 0;
        if (eval->gsize < reqsize) {
            rc = grow_gen_buffer(eval, reqsize, gspend);
            if (rc != APR_SUCCESS) { 
                return rc;
            }
        }
        memcpy(*gspend, sz, len + 1);
        /* *gspend will now point to NULL character */
        *gspend += len;
        return APR_SUCCESS;
    }
    
    /*
     * copy_to_genbuf
     */
    static apr_status_t copy_to_genbuf(sed_eval_t *eval, const char* sz)
    {
        apr_size_t len = strlen(sz);
        apr_size_t reqsize = len + 1;
        apr_status_t rc = APR_SUCCESS;;
        if (eval->gsize < reqsize) {
            rc = grow_gen_buffer(eval, reqsize, NULL);
            if (rc != APR_SUCCESS) { 
                return rc;
            }
        }
        memcpy(eval->genbuf, sz, len + 1);
        return rc;
    }
    
    /*
     * sed_init_eval
     */
    apr_status_t sed_init_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data, sed_write_fn_t *writefn, apr_pool_t* p)
    {
        memset(eval, 0, sizeof(*eval));
        eval->pool = p;
        eval->writefn = writefn;
        return sed_reset_eval(eval, commands, errfn, data);
    }
    
    /*
     * sed_reset_eval
     */
    apr_status_t sed_reset_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data)
    {
        int i;
    
        eval->errfn = errfn;
        eval->data = data;
    
        eval->commands = commands;
    
        eval->lnum = 0;
        eval->fout = NULL;
    
        if (eval->linebuf == NULL) {
            eval->lsize = INIT_BUF_SIZE;
            eval->linebuf = apr_pcalloc(eval->pool, eval->lsize);
        }
        if (eval->holdbuf == NULL) {
            eval->hsize = INIT_BUF_SIZE;
            eval->holdbuf = apr_pcalloc(eval->pool, eval->hsize);
        }
        if (eval->genbuf == NULL) {
            eval->gsize = INIT_BUF_SIZE;
            eval->genbuf = apr_pcalloc(eval->pool, eval->gsize);
        }
        eval->lspend = eval->linebuf;
        eval->hspend = eval->holdbuf;
        eval->lcomend = &eval->genbuf[71];
    
        for (i = 0; i < sizeof(eval->abuf) / sizeof(eval->abuf[0]); i++)
            eval->abuf[i] = NULL;
        eval->aptr = eval->abuf;
        eval->pending = NULL;
        eval->inar = apr_pcalloc(eval->pool, commands->nrep * sizeof(unsigned char));
        eval->nrep = commands->nrep;
    
        eval->dolflag = 0;
        eval->sflag = 0;
        eval->jflag = 0;
        eval->delflag = 0;
        eval->lreadyflag = 0;
        eval->quitflag = 0;
        eval->finalflag = 1; /* assume we're evaluating only one file/stream */
        eval->numpass = 0;
        eval->nullmatch = 0;
        eval->col = 0;
    
        for (i = 0; i < commands->nfiles; i++) {
            const char* filename = commands->fname[i];
            if (apr_file_open(&eval->fcode[i], filename,
                              APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
                              eval->pool) != APR_SUCCESS) {
                eval_errf(eval, SEDERR_COMES, filename);
                return APR_EGENERAL;
            }
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * sed_destroy_eval
     */
    void sed_destroy_eval(sed_eval_t *eval)
    {
        int i;
        /* eval->linebuf, eval->holdbuf, eval->genbuf and eval->inar are allocated
         * on pool. It will be freed when pool will be freed */
        for (i = 0; i < eval->commands->nfiles; i++) {
            if (eval->fcode[i] != NULL) {
                apr_file_close(eval->fcode[i]);
                eval->fcode[i] = NULL;
            }
        }
    }
    
    /*
     * sed_eval_file
     */
    apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout)
    {
        for (;;) {
            char buf[1024];
            apr_size_t read_bytes = 0;
    
            read_bytes = sizeof(buf);
            if (apr_file_read(fin, buf, &read_bytes) != APR_SUCCESS)
                break;
    
            if (sed_eval_buffer(eval, buf, read_bytes, fout) != APR_SUCCESS)
                return APR_EGENERAL;
    
            if (eval->quitflag)
                return APR_SUCCESS;
        }
    
        return sed_finalize_eval(eval, fout);
    }
    
    /*
     * sed_eval_buffer
     */
    apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout)
    {
        apr_status_t rv;
    
        if (eval->quitflag)
            return APR_SUCCESS;
    
        if (!sed_canbe_finalized(eval->commands)) {
            /* Commands were not finalized properly. */
            const char* error = sed_get_finalize_error(eval->commands, eval->pool);
            if (error) {
                eval_errf(eval, error);
                return APR_EGENERAL;
            }
        }
    
        eval->fout = fout;
    
        /* Process leftovers */
        if (bufsz && eval->lreadyflag) {
            eval->lreadyflag = 0;
            eval->lspend--;
            *eval->lspend = '\0';
            rv = execute(eval);
            if (rv != APR_SUCCESS)
                return rv;
        }
    
        while (bufsz) {
            apr_status_t rc = 0;
            char *n;
            apr_size_t llen;
    
            n = memchr(buf, '\n', bufsz);
            if (n == NULL)
                break;
    
            llen = n - buf;
            if (llen == bufsz - 1) {
                /* This might be the last line; delay its processing */
                eval->lreadyflag = 1;
                break;
            }
    
            rc = appendmem_to_linebuf(eval, buf, llen + 1);
            if (rc != APR_SUCCESS) { 
                return rc;
            }
            --eval->lspend;
            /* replace new line character with NULL */
            *eval->lspend = '\0';
            buf += (llen + 1);
            bufsz -= (llen + 1);
            rv = execute(eval);
            if (rv != APR_SUCCESS)
                return rv;
            if (eval->quitflag)
                break;
        }
    
        /* Save the leftovers for later */
        if (bufsz) {
            apr_status_t rc = appendmem_to_linebuf(eval, buf, bufsz);
            if (rc != APR_SUCCESS) { 
                return rc;
            }
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * sed_finalize_eval
     */
    apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
    {
        if (eval->quitflag)
            return APR_SUCCESS;
    
        if (eval->finalflag)
            eval->dolflag = 1;
    
        eval->fout = fout;
    
        /* Process leftovers */
        if (eval->lspend > eval->linebuf) {
            apr_status_t rv;
            apr_status_t rc = 0;
    
            if (eval->lreadyflag) {
                eval->lreadyflag = 0;
                eval->lspend--;
            } else {
                /* Code can probably reach here when last character in output
                 * buffer is not a newline.
                 */
                /* Assure space for NULL */
                rc = append_to_linebuf(eval, "", NULL);
                if (rc != APR_SUCCESS) { 
                    return rc;
                }
            }
    
            *eval->lspend = '\0';
            rv = execute(eval);
            if (rv != APR_SUCCESS)
                return rv;
        }
    
        eval->quitflag = 1;
    
        return APR_SUCCESS;
    }
    
    /*
     * execute
     */
    static apr_status_t execute(sed_eval_t *eval)
    {
        sed_reptr_t *ipc = eval->commands->ptrspace;
        step_vars_storage step_vars;
        apr_status_t rv = APR_SUCCESS;
    
        eval->lnum++;
    
        eval->sflag = 0;
    
        if (eval->pending) {
            ipc = eval->pending;
            eval->pending = NULL;
        }
    
        memset(&step_vars, 0, sizeof(step_vars));
    
        while (ipc->command) {
            char *p1;
            char *p2;
            int c;
    
            p1 = ipc->ad1;
            p2 = ipc->ad2;
    
            if (p1) {
    
                if (eval->inar[ipc->nrep]) {
                    if (*p2 == CEND) {
                        p1 = 0;
                    } else if (*p2 == CLNUM) {
                        c = (unsigned char)p2[1];
                        if (eval->lnum > eval->commands->tlno[c]) {
                            eval->inar[ipc->nrep] = 0;
                            if (ipc->negfl)
                                goto yes;
                            ipc = ipc->next;
                            continue;
                        }
                        if (eval->lnum == eval->commands->tlno[c]) {
                            eval->inar[ipc->nrep] = 0;
                        }
                    } else if (match(eval, p2, 0, &step_vars)) {
                        eval->inar[ipc->nrep] = 0;
                    }
                } else if (*p1 == CEND) {
                    if (!eval->dolflag) {
                        if (ipc->negfl)
                            goto yes;
                        ipc = ipc->next;
                        continue;
                    }
                } else if (*p1 == CLNUM) {
                    c = (unsigned char)p1[1];
                    if (eval->lnum != eval->commands->tlno[c]) {
                        if (ipc->negfl)
                            goto yes;
                        ipc = ipc->next;
                        continue;
                    }
                    if (p2)
                        eval->inar[ipc->nrep] = 1;
                } else if (match(eval, p1, 0, &step_vars)) {
                    if (p2)
                        eval->inar[ipc->nrep] = 1;
                } else {
                    if (ipc->negfl)
                        goto yes;
                    ipc = ipc->next;
                    continue;
                }
            }
    
            if (ipc->negfl) {
                ipc = ipc->next;
                continue;
            }
    
    yes:
            rv = command(eval, ipc, &step_vars);
            if (rv != APR_SUCCESS)
                return rv;
    
            if (eval->quitflag)
                return APR_SUCCESS;
    
            if (eval->pending)
                return APR_SUCCESS;
    
            if (eval->delflag)
                break;
    
            if (eval->jflag) {
                eval->jflag = 0;
                if ((ipc = ipc->lb1) == 0) {
                    ipc = eval->commands->ptrspace;
                    break;
                }
            } else
                ipc = ipc->next;
        }
    
        if (!eval->commands->nflag && !eval->delflag) {
            rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
            if (rv != APR_SUCCESS)
                return rv;
        }
    
        if (eval->aptr > eval->abuf)
            rv = arout(eval);
    
        eval->delflag = 0;
    
        eval->lspend = eval->linebuf;
    
        return rv;
    }
    
    /*
     * match
     */
    static int match(sed_eval_t *eval, char *expbuf, int gf,
                     step_vars_storage *step_vars)
    {
        char   *p1;
        int circf;
    
        if (gf) {
            if (*expbuf)    return(0);
            step_vars->locs = p1 = step_vars->loc2;
        } else {
            p1 = eval->linebuf;
            step_vars->locs = 0;
        }
    
        circf = *expbuf++;
        return(sed_step(p1, expbuf, circf, step_vars));
    }
    
    /*
     * substitute
     */
    static int substitute(sed_eval_t *eval, sed_reptr_t *ipc,
                          step_vars_storage *step_vars)
    {
        if (match(eval, ipc->re1, 0, step_vars) == 0)    return(0);
    
        eval->numpass = 0;
        eval->sflag = 0;        /* Flags if any substitution was made */
        if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS)
            return -1;
    
        if (ipc->gfl) {
            while (*step_vars->loc2) {
                if (match(eval, ipc->re1, 1, step_vars) == 0) break;
                if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS)
                    return -1;
            }
        }
        return(eval->sflag);
    }
    
    /*
     * dosub
     */
    static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
                              step_vars_storage *step_vars)
    {
        char *lp, *sp, *rp;
        int c;
        apr_status_t rv = APR_SUCCESS;
    
        if (n > 0 && n < 999) {
            eval->numpass++;
            if (n != eval->numpass) return APR_SUCCESS;
        }
        eval->sflag = 1;
        lp = eval->linebuf;
        sp = eval->genbuf;
        rp = rhsbuf;
        sp = place(eval, sp, lp, step_vars->loc1);
        if (sp == NULL) { 
            return APR_EGENERAL;
        }
        while ((c = *rp++) != 0) {
            if (c == '&') {
                sp = place(eval, sp, step_vars->loc1, step_vars->loc2);
                if (sp == NULL) {
                    return APR_EGENERAL;
                }
            }
            else if (c == '\\') {
                c = *rp++;
                if (c >= '1' && c < NBRA+'1') {
                    sp = place(eval, sp, step_vars->braslist[c-'1'],
                               step_vars->braelist[c-'1']);
                    if (sp == NULL)
                        return APR_EGENERAL;
                }
                else
                    *sp++ = c;
              } else
                *sp++ = c;
            if (sp >= eval->genbuf + eval->gsize) {
                /* expand genbuf and set the sp appropriately */
                rv = grow_gen_buffer(eval, eval->gsize + 1024, &sp);
                if (rv != APR_SUCCESS) { 
                    return rv;
                }
            }
        }
        lp = step_vars->loc2;
        step_vars->loc2 = sp - eval->genbuf + eval->linebuf;
        rv = append_to_genbuf(eval, lp, &sp);
        if (rv != APR_SUCCESS) { 
            return rv;
        }
        rv = copy_to_linebuf(eval, eval->genbuf, step_vars);
        return rv;
    }
    
    /*
     * place
     */
    static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2)
    {
        char *sp = asp;
        apr_size_t n = al2 - al1;
        apr_size_t reqsize = (sp - eval->genbuf) + n + 1;
    
        if (eval->gsize < reqsize) {
            apr_status_t rc = grow_gen_buffer(eval, reqsize, &sp);
            if (rc != APR_SUCCESS) { 
                return NULL;
            }
        }
        memcpy(sp, al1, n);
        return sp + n;
    }
    
    /*
     * command
     */
    static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
                                step_vars_storage *step_vars)
    {
        int    i;
        char   *p1, *p2;
        const char *p3;
        int length;
        char sz[32]; /* 32 bytes enough to store 64 bit integer in decimal */
        apr_status_t rv = APR_SUCCESS;
    
    
        switch(ipc->command) {
    
            case ACOM:
                if (eval->aptr >= &eval->abuf[SED_ABUFSIZE]) {
                    eval_errf(eval, SEDERR_TMAMES, eval->lnum);
                } else {
                    *eval->aptr++ = ipc;
                    *eval->aptr = NULL;
                }
                break;
    
            case CCOM:
                eval->delflag = 1;
                if (!eval->inar[ipc->nrep] || eval->dolflag) {
                    for (p1 = ipc->re1; *p1; p1++)
                        ;
                    rv = wline(eval, ipc->re1, p1 - ipc->re1);
                }
                break;
    
            case DCOM:
                eval->delflag++;
                break;
    
            case CDCOM:
                p1 = eval->linebuf;
    
                while (*p1 != '\n') {
                    if (*p1++ == 0) {
                        eval->delflag++;
                        return APR_SUCCESS;
                    }
                }
    
                p1++;
                rv = copy_to_linebuf(eval, p1, step_vars);
                if (rv != APR_SUCCESS) return rv;
                eval->jflag++;
                break;
    
            case EQCOM:
                length = apr_snprintf(sz, sizeof(sz), "%d", (int) eval->lnum);
                rv = wline(eval, sz, length);
                break;
    
            case GCOM:
                rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
                if (rv != APR_SUCCESS) return rv;
                break;
    
            case CGCOM:
                rv = append_to_linebuf(eval, "\n", step_vars);
                if (rv != APR_SUCCESS) return rv;
                rv = append_to_linebuf(eval, eval->holdbuf, step_vars);
                if (rv != APR_SUCCESS) return rv;
                break;
    
            case HCOM:
                rv = copy_to_holdbuf(eval, eval->linebuf);
                if (rv != APR_SUCCESS) return rv;
                break;
    
            case CHCOM:
                rv = append_to_holdbuf(eval, "\n");
                if (rv != APR_SUCCESS) return rv;
                rv = append_to_holdbuf(eval, eval->linebuf);
                if (rv != APR_SUCCESS) return rv;
                break;
    
            case ICOM:
                for (p1 = ipc->re1; *p1; p1++);
                rv = wline(eval, ipc->re1, p1 - ipc->re1);
                break;
    
            case BCOM:
                eval->jflag = 1;
                break;
    
            case LCOM:
                p1 = eval->linebuf;
                p2 = eval->genbuf;
                eval->genbuf[72] = 0;
                while (*p1) {
                    if ((unsigned char)*p1 >= 040) {
                        if (*p1 == 0177) {
                            p3 = rub;
                            while ((*p2++ = *p3++) != 0)
                                if (p2 >= eval->lcomend) {
                                    *p2 = '\\';
                                    rv = wline(eval, eval->genbuf,
                                               strlen(eval->genbuf));
                                    if (rv != APR_SUCCESS)
                                        return rv;
                                    p2 = eval->genbuf;
                                }
                            p2--;
                            p1++;
                            continue;
                        }
                        if (!isprint(*p1 & 0377)) {
                            *p2++ = '\\';
                            if (p2 >= eval->lcomend) {
                                *p2 = '\\';
                                rv = wline(eval, eval->genbuf,
                                           strlen(eval->genbuf));
                                if (rv != APR_SUCCESS)
                                    return rv;
                                p2 = eval->genbuf;
                            }
                            *p2++ = (*p1 >> 6) + '0';
                            if (p2 >= eval->lcomend) {
                                *p2 = '\\';
                                rv = wline(eval, eval->genbuf,
                                           strlen(eval->genbuf));
                                if (rv != APR_SUCCESS)
                                    return rv;
                                p2 = eval->genbuf;
                            }
                            *p2++ = ((*p1 >> 3) & 07) + '0';
                            if (p2 >= eval->lcomend) {
                                *p2 = '\\';
                                rv = wline(eval, eval->genbuf,
                                           strlen(eval->genbuf));
                                if (rv != APR_SUCCESS)
                                    return rv;
                                p2 = eval->genbuf;
                            }
                            *p2++ = (*p1++ & 07) + '0';
                            if (p2 >= eval->lcomend) {
                                *p2 = '\\';
                                rv = wline(eval, eval->genbuf,
                                           strlen(eval->genbuf));
                                if (rv != APR_SUCCESS)
                                    return rv;
                                p2 = eval->genbuf;
                            }
                        } else {
                            *p2++ = *p1++;
                            if (p2 >= eval->lcomend) {
                                *p2 = '\\';
                                rv = wline(eval, eval->genbuf,
                                           strlen(eval->genbuf));
                                if (rv != APR_SUCCESS)
                                    return rv;
                                p2 = eval->genbuf;
                            }
                        }
                    } else {
                        p3 = trans[(unsigned char)*p1-1];
                        while ((*p2++ = *p3++) != 0)
                            if (p2 >= eval->lcomend) {
                                *p2 = '\\';
                                rv = wline(eval, eval->genbuf,
                                           strlen(eval->genbuf));
                                if (rv != APR_SUCCESS)
                                    return rv;
                                p2 = eval->genbuf;
                            }
                        p2--;
                        p1++;
                    }
                }
                *p2 = 0;
                rv = wline(eval, eval->genbuf, strlen(eval->genbuf));
                break;
    
            case NCOM:
                if (!eval->commands->nflag) {
                    rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
                    if (rv != APR_SUCCESS)
                        return rv;
                }
    
                if (eval->aptr > eval->abuf) {
                    rv = arout(eval);
                    if (rv != APR_SUCCESS)
                        return rv;
                }
                eval->lspend = eval->linebuf;
                eval->pending = ipc->next;
                break;
    
            case CNCOM:
                if (eval->aptr > eval->abuf) {
                    rv = arout(eval);
                    if (rv != APR_SUCCESS)
                        return rv;
                }
                rv = append_to_linebuf(eval, "\n", step_vars);
                if (rv != APR_SUCCESS) return rv;
                eval->pending = ipc->next;
                break;
    
            case PCOM:
                rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
                break;
    
            case CPCOM:
                for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++);
                rv = wline(eval, eval->linebuf, p1 - eval->linebuf);
                break;
    
            case QCOM:
                if (!eval->commands->nflag) {
                    rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
                    if (rv != APR_SUCCESS)
                        break;
                }
    
                if (eval->aptr > eval->abuf) {
                    rv = arout(eval);
                    if (rv != APR_SUCCESS)
                        return rv;
                }
    
                eval->quitflag = 1;
                break;
    
            case RCOM:
                if (eval->aptr >= &eval->abuf[SED_ABUFSIZE]) {
                    eval_errf(eval, SEDERR_TMRMES, eval->lnum);
                } else {
                    *eval->aptr++ = ipc;
                    *eval->aptr = NULL;
                }
                break;
    
            case SCOM:
                i = substitute(eval, ipc, step_vars);
                if (i == -1) {
                    return APR_EGENERAL;
                }
                if (ipc->pfl && eval->commands->nflag && i) {
                    if (ipc->pfl == 1) {
                        rv = wline(eval, eval->linebuf, eval->lspend -
                                   eval->linebuf);
                        if (rv != APR_SUCCESS)
                            return rv;
                    } else {
                        for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++);
                        rv = wline(eval, eval->linebuf, p1 - eval->linebuf);
                        if (rv != APR_SUCCESS)
                            return rv;
                    }
                }
                if (i && (ipc->findex >= 0) && eval->fcode[ipc->findex])
                    apr_file_printf(eval->fcode[ipc->findex], "%s\n",
                                    eval->linebuf);
                break;
    
            case TCOM:
                if (eval->sflag == 0)  break;
                eval->sflag = 0;
                eval->jflag = 1;
                break;
    
            case WCOM:
                if (ipc->findex >= 0)
                    apr_file_printf(eval->fcode[ipc->findex], "%s\n",
                                    eval->linebuf);
                break;
    
            case XCOM:
                rv = copy_to_genbuf(eval, eval->linebuf);
                if (rv != APR_SUCCESS) return rv;
                rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
                if (rv != APR_SUCCESS) return rv;
                rv = copy_to_holdbuf(eval, eval->genbuf);
                if (rv != APR_SUCCESS) return rv;
                break;
    
            case YCOM:
                p1 = eval->linebuf;
                p2 = ipc->re1;
                while ((*p1 = p2[(unsigned char)*p1]) != 0)    p1++;
                break;
        }
        return rv;
    }
    
    /*
     * arout
     */
    static apr_status_t arout(sed_eval_t *eval)
    {
        apr_status_t rv = APR_SUCCESS;
        eval->aptr = eval->abuf - 1;
        while (*++eval->aptr) {
            if ((*eval->aptr)->command == ACOM) {
                char *p1;
    
                for (p1 = (*eval->aptr)->re1; *p1; p1++);
                rv = wline(eval, (*eval->aptr)->re1, p1 - (*eval->aptr)->re1);
                if (rv != APR_SUCCESS)
                    return rv;
            } else {
                apr_file_t *fi = NULL;
                char buf[512];
                apr_size_t n = sizeof(buf);
    
                if (apr_file_open(&fi, (*eval->aptr)->re1, APR_READ, 0, eval->pool)
                                  != APR_SUCCESS)
                    continue;
                while ((apr_file_read(fi, buf, &n)) == APR_SUCCESS) {
                    if (n == 0)
                        break;
                    rv = eval->writefn(eval->fout, buf, n);
                    if (rv != APR_SUCCESS) {
                        apr_file_close(fi);
                        return rv;
                    }
                    n = sizeof(buf);
                }
                apr_file_close(fi);
            }
        }
        eval->aptr = eval->abuf;
        *eval->aptr = NULL;
        return rv;
    }
    
    /*
     * wline
     */
    static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz)
    {
        apr_status_t rv = APR_SUCCESS;
        rv = eval->writefn(eval->fout, buf, sz);
        if (rv != APR_SUCCESS)
            return rv;
        rv = eval->writefn(eval->fout, "\n", 1);
        return rv;
    }
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_substitute.c�������������������������������������������������������0000664�0001751�0001751�00000075605�14037102164�021173� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_substitute.c: Perform content rewriting on the fly
     */
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "http_log.h"
    #include "apr_general.h"
    #include "apr_strings.h"
    #include "apr_strmatch.h"
    #include "apr_lib.h"
    #include "util_filter.h"
    #include "util_varbuf.h"
    #include "apr_buckets.h"
    #include "http_request.h"
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    /*
     * We want to limit the memory usage in a way that is predictable.
     * Therefore we limit the resulting length of the line.
     * This is the default value.
     */
    #define AP_SUBST_MAX_LINE_LENGTH (1024*1024)
    
    static const char substitute_filter_name[] = "SUBSTITUTE";
    
    module AP_MODULE_DECLARE_DATA substitute_module;
    
    typedef struct subst_pattern_t {
        const apr_strmatch_pattern *pattern;
        const ap_regex_t *regexp;
        const char *replacement;
        apr_size_t replen;
        apr_size_t patlen;
        int flatten;
        const char *from;
    } subst_pattern_t;
    
    typedef struct {
        apr_array_header_t *patterns;
        apr_size_t max_line_length;
        int max_line_length_set;
        int inherit_before;
    } subst_dir_conf;
    
    typedef struct {
        apr_bucket_brigade *linebb;
        apr_bucket_brigade *linesbb;
        apr_bucket_brigade *passbb;
        apr_bucket_brigade *pattbb;
        apr_pool_t *tpool;
    } substitute_module_ctx;
    
    static void *create_substitute_dcfg(apr_pool_t *p, char *d)
    {
        subst_dir_conf *dcfg =
            (subst_dir_conf *) apr_palloc(p, sizeof(subst_dir_conf));
    
        dcfg->patterns = apr_array_make(p, 10, sizeof(subst_pattern_t));
        dcfg->max_line_length = AP_SUBST_MAX_LINE_LENGTH;
        dcfg->max_line_length_set = 0;
        dcfg->inherit_before = -1;
        return dcfg;
    }
    
    static void *merge_substitute_dcfg(apr_pool_t *p, void *basev, void *overv)
    {
        subst_dir_conf *a =
            (subst_dir_conf *) apr_palloc(p, sizeof(subst_dir_conf));
        subst_dir_conf *base = (subst_dir_conf *) basev;
        subst_dir_conf *over = (subst_dir_conf *) overv;
    
        a->inherit_before = (over->inherit_before != -1)
                                ? over->inherit_before
                                : base->inherit_before;
        /* SubstituteInheritBefore wasn't the default behavior until 2.5.x,
         * and may be re-disabled as desired; the original default behavior
         * was to apply inherited subst patterns after locally scoped patterns.
         * In later 2.2 and 2.4 versions, SubstituteInheritBefore may be toggled
         * 'on' to follow the corrected/expected behavior, without violating POLS.
         */
        if (a->inherit_before == 1) {
            a->patterns = apr_array_append(p, base->patterns,
                                              over->patterns);
        }
        else {
            a->patterns = apr_array_append(p, over->patterns,
                                              base->patterns);
        }
        a->max_line_length = over->max_line_length_set ?
                                 over->max_line_length : base->max_line_length;
        a->max_line_length_set = over->max_line_length_set
                               | base->max_line_length_set;
        return a;
    }
    
    #define AP_MAX_BUCKETS 1000
    
    #define SEDRMPATBCKT(b, offset, tmp_b, patlen) do {  \
        apr_bucket_split(b, offset);                     \
        tmp_b = APR_BUCKET_NEXT(b);                      \
        apr_bucket_split(tmp_b, patlen);                 \
        b = APR_BUCKET_NEXT(tmp_b);                      \
        apr_bucket_delete(tmp_b);                        \
    } while (0)
    
    #define CAP2LINEMAX(n) ((n) < (apr_size_t)200 ? (int)(n) : 200)
    
    static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
                                     apr_bucket_brigade *mybb,
                                     apr_pool_t *pool)
    {
        int i;
        int force_quick = 0;
        ap_regmatch_t regm[AP_MAX_REG_MATCH];
        apr_size_t bytes;
        apr_size_t len;
        const char *buff;
        struct ap_varbuf vb;
        apr_bucket *b;
        apr_bucket *tmp_b;
    
        subst_dir_conf *cfg =
        (subst_dir_conf *) ap_get_module_config(f->r->per_dir_config,
                                                 &substitute_module);
        subst_pattern_t *script;
    
        APR_BRIGADE_INSERT_TAIL(mybb, inb);
        ap_varbuf_init(pool, &vb, 0);
    
        script = (subst_pattern_t *) cfg->patterns->elts;
        /*
         * Simple optimization. If we only have one pattern, then
         * we can safely avoid the overhead of flattening
         */
        if (cfg->patterns->nelts == 1) {
           force_quick = 1;
        }
        for (i = 0; i < cfg->patterns->nelts; i++) {
            for (b = APR_BRIGADE_FIRST(mybb);
                 b != APR_BRIGADE_SENTINEL(mybb);
                 b = APR_BUCKET_NEXT(b)) {
                if (APR_BUCKET_IS_METADATA(b)) {
                    /*
                     * we should NEVER see this, because we should never
                     * be passed any, but "handle" it just in case.
                     */
                    continue;
                }
                if (apr_bucket_read(b, &buff, &bytes, APR_BLOCK_READ)
                        == APR_SUCCESS) {
                    int have_match = 0;
    
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                  "Line read (%" APR_SIZE_T_FMT " bytes): %.*s",
                                  bytes, CAP2LINEMAX(bytes), buff);
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                  "Replacing %s:'%s' by '%s'",
                                  script->pattern ? "string" :
                                  script->regexp  ? "regex"  :
                                                    "unknown",
                                  script->from, script->replacement);
    
                    vb.strlen = 0;
                    if (script->pattern) {
                        const char *repl;
                        /*
                         * space_left counts how many bytes we have left until the
                         * line length reaches max_line_length.
                         */
                        apr_size_t space_left = cfg->max_line_length;
                        apr_size_t repl_len = strlen(script->replacement);
                        while ((repl = apr_strmatch(script->pattern, buff, bytes)))
                        {
                            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                          "Matching found, result: '%s'",
                                          script->replacement);
                            have_match = 1;
                            /* get offset into buff for pattern */
                            len = (apr_size_t) (repl - buff);
                            if (script->flatten && !force_quick) {
                                /*
                                 * We are flattening the buckets here, meaning
                                 * that we don't do the fast bucket splits.
                                 * Instead we copy over what the buckets would
                                 * contain and use them. This is slow, since we
                                 * are constanting allocing space and copying
                                 * strings.
                                 */
                                if (vb.strlen + len + repl_len > cfg->max_line_length)
                                    return APR_ENOMEM;
                                ap_varbuf_strmemcat(&vb, buff, len);
                                ap_varbuf_strmemcat(&vb, script->replacement, repl_len);
                            }
                            else {
                                /*
                                 * The string before the match but after the
                                 * previous match (if any) has length 'len'.
                                 * Check if we still have space for this string and
                                 * the replacement string.
                                 */
                                if (space_left < len + repl_len)
                                    return APR_ENOMEM;
                                space_left -= len + repl_len;
                                /*
                                 * We now split off the string before the match
                                 * as its own bucket, then isolate the matched
                                 * string and delete it.
                                 */
                                SEDRMPATBCKT(b, len, tmp_b, script->patlen);
                                /*
                                 * Finally, we create a bucket that contains the
                                 * replacement...
                                 */
                                tmp_b = apr_bucket_transient_create(script->replacement,
                                          script->replen,
                                          f->r->connection->bucket_alloc);
                                /* ... and insert it */
                                APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                            }
                            /* now we need to adjust buff for all these changes */
                            len += script->patlen;
                            bytes -= len;
                            buff += len;
                        }
                        if (have_match) {
                            if (script->flatten && !force_quick) {
                                /* XXX: we should check for AP_MAX_BUCKETS here and
                                 * XXX: call ap_pass_brigade accordingly
                                 */
                                char *copy = ap_varbuf_pdup(pool, &vb, NULL, 0,
                                                            buff, bytes, &len);
                                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                              "New line (%" APR_SIZE_T_FMT " bytes): %.*s",
                                              len, CAP2LINEMAX(len), copy);
                                tmp_b = apr_bucket_pool_create(copy, len, pool,
                                                               f->r->connection->bucket_alloc);
                                APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                                apr_bucket_delete(b);
                                b = tmp_b;
                            }
                            else {
                                /*
                                 * We want the behaviour to be predictable.
                                 * Therefore we try to always error out if the
                                 * line length is larger than the limit,
                                 * regardless of the content of the line. So,
                                 * let's check if the remaining non-matching
                                 * string does not exceed the limit.
                                 */
                                if (space_left < b->length)
                                    return APR_ENOMEM;
                                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                              "New line (%" APR_SIZE_T_FMT " bytes): %.*s",
                                              bytes, CAP2LINEMAX(bytes), buff);
                            }
                        }
                    }
                    else if (script->regexp) {
                        int left = bytes;
                        const char *pos = buff;
                        char *repl;
                        apr_size_t space_left = cfg->max_line_length;
                        while (!ap_regexec_len(script->regexp, pos, left,
                                           AP_MAX_REG_MATCH, regm, 0)) {
                            apr_status_t rv;
                            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                          "Matching found");
                            have_match = 1;
                            if (script->flatten && !force_quick) {
                                /* check remaining buffer size */
                                /* Note that the last param in ap_varbuf_regsub below
                                 * must stay positive. If it gets 0, it would mean
                                 * unlimited space available. */
                                if (vb.strlen + regm[0].rm_so >= cfg->max_line_length)
                                    return APR_ENOMEM;
                                /* copy bytes before the match */
                                if (regm[0].rm_so > 0)
                                    ap_varbuf_strmemcat(&vb, pos, regm[0].rm_so);
                                /* add replacement string, last argument is unsigned! */
                                rv = ap_varbuf_regsub(&vb, script->replacement, pos,
                                                      AP_MAX_REG_MATCH, regm,
                                                      cfg->max_line_length - vb.strlen);
                                if (rv != APR_SUCCESS)
                                    return rv;
                                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                              "Result: '%s'", vb.buf);
                            }
                            else {
                                apr_size_t repl_len;
                                /* account for string before the match */
                                if (space_left <= regm[0].rm_so)
                                    return APR_ENOMEM;
                                space_left -= regm[0].rm_so;
                                rv = ap_pregsub_ex(pool, &repl,
                                                   script->replacement, pos,
                                                   AP_MAX_REG_MATCH, regm,
                                                   space_left);
                                if (rv != APR_SUCCESS)
                                    return rv;
                                repl_len = strlen(repl);
                                space_left -= repl_len;
                                len = (apr_size_t) (regm[0].rm_eo - regm[0].rm_so);
                                SEDRMPATBCKT(b, regm[0].rm_so, tmp_b, len);
                                tmp_b = apr_bucket_transient_create(repl, repl_len,
                                                    f->r->connection->bucket_alloc);
                                APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                              "Result: '%s'", repl);
                            }
                            /*
                             * reset to past what we just did. pos now maps to b
                             * again
                             */
                            pos += regm[0].rm_eo;
                            left -= regm[0].rm_eo;
                        }
                        if (have_match && script->flatten && !force_quick) {
                            char *copy;
                            /* Copy result plus the part after the last match into
                             * a bucket.
                             */
                            copy = ap_varbuf_pdup(pool, &vb, NULL, 0, pos, left,
                                                  &len);
                            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, f->r,
                                          "New line (%" APR_SIZE_T_FMT " bytes): %.*s",
                                          len, CAP2LINEMAX(len), copy);
                            tmp_b = apr_bucket_pool_create(copy, len, pool,
                                               f->r->connection->bucket_alloc);
                            APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                            apr_bucket_delete(b);
                            b = tmp_b;
                        }
                    }
                    else {
                        ap_assert(0);
                        continue;
                    }
                }
            }
            script++;
        }
        ap_varbuf_free(&vb);
        return APR_SUCCESS;
    }
    
    static apr_status_t substitute_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        apr_size_t bytes;
        apr_size_t len;
        apr_size_t fbytes;
        const char *buff;
        const char *nl = NULL;
        char *bflat;
        apr_bucket *b;
        apr_bucket *tmp_b;
        apr_bucket_brigade *tmp_bb = NULL;
        apr_status_t rv;
        subst_dir_conf *cfg =
        (subst_dir_conf *) ap_get_module_config(f->r->per_dir_config,
                                                 &substitute_module);
    
        substitute_module_ctx *ctx = f->ctx;
    
        /*
         * First time around? Create the saved bb that we used for each pass
         * through. Note that we can also get here when we explicitly clear ctx,
         * for error handling
         */
        if (!ctx) {
            f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
            /*
             * Create all the temporary brigades we need and reuse them to avoid
             * creating them over and over again from r->pool which would cost a
             * lot of memory in some cases.
             */
            ctx->linebb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
            ctx->linesbb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
            ctx->pattbb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
            /*
             * Everything to be passed to the next filter goes in
             * here, our pass brigade.
             */
            ctx->passbb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
            /* Create our temporary pool only once */
            apr_pool_create(&(ctx->tpool), f->r->pool);
            apr_pool_tag(ctx->tpool, "substitute_tpool");
            apr_table_unset(f->r->headers_out, "Content-Length");
        }
    
        /*
         * Shortcircuit processing
         */
        if (APR_BRIGADE_EMPTY(bb))
            return APR_SUCCESS;
    
        /*
         * Here's the concept:
         *  Read in the data and look for newlines. Once we
         *  find a full "line", add it to our working brigade.
         *  If we've finished reading the brigade and we have
         *  any left over data (not a "full" line), store that
         *  for the next pass.
         *
         * Note: anything stored in ctx->linebb for sure does not have
         * a newline char, so we don't concat that bb with the
         * new bb, since we would spending time searching for the newline
         * in data we know it doesn't exist. So instead, we simply scan
         * our current bb and, if we see a newline, prepend ctx->linebb
         * to the front of it. This makes the code much less straight-
         * forward (otherwise we could APR_BRIGADE_CONCAT(ctx->linebb, bb)
         * and just scan for newlines and not bother with needing to know
         * when ctx->linebb needs to be reset) but also faster. We'll take
         * the speed.
         *
         * Note: apr_brigade_split_line would be nice here, but we
         * really can't use it since we need more control and we want
         * to re-use already read bucket data.
         *
         * See mod_include if still confused :)
         */
    
        while ((b = APR_BRIGADE_FIRST(bb)) && (b != APR_BRIGADE_SENTINEL(bb))) {
            if (APR_BUCKET_IS_EOS(b)) {
                /*
                 * if we see the EOS, then we need to pass along everything we
                 * have. But if the ctx->linebb isn't empty, then we need to add
                 * that to the end of what we'll be passing.
                 */
                if (!APR_BRIGADE_EMPTY(ctx->linebb)) {
                    rv = apr_brigade_pflatten(ctx->linebb, &bflat,
                                              &fbytes, ctx->tpool);
                    if (rv != APR_SUCCESS)
                        goto err;
                    if (fbytes > cfg->max_line_length) {
                        rv = APR_ENOMEM;
                        goto err;
                    }
                    tmp_b = apr_bucket_transient_create(bflat, fbytes,
                                                    f->r->connection->bucket_alloc);
                    rv = do_pattmatch(f, tmp_b, ctx->pattbb, ctx->tpool);
                    if (rv != APR_SUCCESS)
                        goto err;
                    APR_BRIGADE_CONCAT(ctx->passbb, ctx->pattbb);
                    apr_brigade_cleanup(ctx->linebb);
                }
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(ctx->passbb, b);
            }
            /*
             * No need to handle FLUSH buckets separately as we call
             * ap_pass_brigade anyway at the end of the loop.
             */
            else if (APR_BUCKET_IS_METADATA(b)) {
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(ctx->passbb, b);
            }
            else {
                /*
                 * We have actual "data" so read in as much as we can and start
                 * scanning and splitting from our read buffer
                 */
                rv = apr_bucket_read(b, &buff, &bytes, APR_BLOCK_READ);
                if (rv != APR_SUCCESS || bytes == 0) {
                    apr_bucket_delete(b);
                }
                else {
                    int num = 0;
                    while (bytes > 0) {
                        nl = memchr(buff, '\n', bytes);
                        if (nl) {
                            len = (apr_size_t) (nl - buff) + 1;
                            /* split *after* the newline */
                            apr_bucket_split(b, len);
                            /*
                             * We've likely read more data, so bypass rereading
                             * bucket data and continue scanning through this
                             * buffer
                             */
                            bytes -= len;
                            buff += len;
                            /*
                             * we need b to be updated for future potential
                             * splitting
                             */
                            tmp_b = APR_BUCKET_NEXT(b);
                            APR_BUCKET_REMOVE(b);
                            /*
                             * Hey, we found a newline! Don't forget the old
                             * stuff that needs to be added to the front. So we
                             * add the split bucket to the end, flatten the whole
                             * bb, morph the whole shebang into a bucket which is
                             * then added to the tail of the newline bb.
                             */
                            if (!APR_BRIGADE_EMPTY(ctx->linebb)) {
                                APR_BRIGADE_INSERT_TAIL(ctx->linebb, b);
                                rv = apr_brigade_pflatten(ctx->linebb, &bflat,
                                                          &fbytes, ctx->tpool);
                                if (rv != APR_SUCCESS)
                                    goto err;
                                if (fbytes > cfg->max_line_length) {
                                    /* Avoid pflattening further lines, we will
                                     * abort later on anyway.
                                     */
                                    rv = APR_ENOMEM;
                                    goto err;
                                }
                                b = apr_bucket_transient_create(bflat, fbytes,
                                                f->r->connection->bucket_alloc);
                                apr_brigade_cleanup(ctx->linebb);
                            }
                            rv = do_pattmatch(f, b, ctx->pattbb, ctx->tpool);
                            if (rv != APR_SUCCESS)
                                goto err;
                            /*
                             * Count how many buckets we have in ctx->passbb
                             * so far. Yes, this is correct we count ctx->passbb
                             * and not ctx->pattbb as we do not reset num on every
                             * iteration.
                             */
                            for (b = APR_BRIGADE_FIRST(ctx->pattbb);
                                 b != APR_BRIGADE_SENTINEL(ctx->pattbb);
                                 b = APR_BUCKET_NEXT(b)) {
                                num++;
                            }
                            APR_BRIGADE_CONCAT(ctx->passbb, ctx->pattbb);
                            /*
                             * If the number of buckets in ctx->passbb reaches an
                             * "insane" level, we consume much memory for all the
                             * buckets as such. So lets flush them down the chain
                             * in this case and thus clear ctx->passbb. This frees
                             * the buckets memory for further processing.
                             * Usually this condition should not become true, but
                             * it is a safety measure for edge cases.
                             */
                            if (num > AP_MAX_BUCKETS) {
                                b = apr_bucket_flush_create(
                                                    f->r->connection->bucket_alloc);
                                APR_BRIGADE_INSERT_TAIL(ctx->passbb, b);
                                rv = ap_pass_brigade(f->next, ctx->passbb);
                                apr_brigade_cleanup(ctx->passbb);
                                num = 0;
                                apr_pool_clear(ctx->tpool);
                                if (rv != APR_SUCCESS)
                                    goto err;
                            }
                            b = tmp_b;
                        }
                        else {
                            /*
                             * no newline in whatever is left of this buffer so
                             * tuck data away and get next bucket
                             */
                            APR_BUCKET_REMOVE(b);
                            APR_BRIGADE_INSERT_TAIL(ctx->linebb, b);
                            bytes = 0;
                        }
                    }
                }
            }
            if (!APR_BRIGADE_EMPTY(ctx->passbb)) {
                rv = ap_pass_brigade(f->next, ctx->passbb);
                apr_brigade_cleanup(ctx->passbb);
                if (rv != APR_SUCCESS)
                    goto err;
            }
            apr_pool_clear(ctx->tpool);
        }
    
        /* Anything left we want to save/setaside for the next go-around */
        if (!APR_BRIGADE_EMPTY(ctx->linebb)) {
            /*
             * Provide ap_save_brigade with an existing empty brigade
             * (ctx->linesbb) to avoid creating a new one.
             */
            ap_save_brigade(f, &(ctx->linesbb), &(ctx->linebb), f->r->pool);
            tmp_bb = ctx->linebb;
            ctx->linebb = ctx->linesbb;
            ctx->linesbb = tmp_bb;
        }
    
        return APR_SUCCESS;
    err:
        if (rv == APR_ENOMEM)
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(01328) "Line too long, URI %s",
                          f->r->uri);
        apr_pool_clear(ctx->tpool);
        return rv;
    }
    
    static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line)
    {
        char *from = NULL;
        char *to = NULL;
        char *flags = NULL;
        char *ourline;
        char delim;
        subst_pattern_t *nscript;
        int is_pattern = 0;
        int ignore_case = 0;
        int flatten = 1;
        ap_regex_t *r = NULL;
    
        if (apr_tolower(*line) != 's') {
            return "Bad Substitute format, must be an s/// pattern";
        }
        ourline = apr_pstrdup(cmd->pool, line);
        delim = *++ourline;
        if (delim)
            from = ++ourline;
        if (from) {
            if (*ourline != delim) {
                while (*++ourline && *ourline != delim);
            }
            if (*ourline) {
                *ourline = '\0';
                to = ++ourline;
            }
        }
        if (to) {
            if (*ourline != delim) {
                while (*++ourline && *ourline != delim);
            }
            if (*ourline) {
                *ourline = '\0';
                flags = ++ourline;
            }
        }
    
        if (!delim || !from || !*from || !to) {
            return "Bad Substitute format, must be a complete s/// pattern";
        }
    
        if (flags) {
            while (*flags) {
                delim = apr_tolower(*flags);    /* re-use */
                if (delim == 'i')
                    ignore_case = 1;
                else if (delim == 'n')
                    is_pattern = 1;
                else if (delim == 'f')
                    flatten = 1;
                else if (delim == 'q')
                    flatten = 0;
                else
                    return "Bad Substitute flag, only s///[infq] are supported";
                flags++;
            }
        }
    
        /* first see if we can compile the regex */
        if (!is_pattern) {
            int flags = AP_REG_NO_DEFAULT
                        | (ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY)
                        | (ignore_case ? AP_REG_ICASE : 0);
            r = ap_pregcomp(cmd->pool, from, flags);
            if (!r)
                return "Substitute could not compile regex";
        }
        nscript = apr_array_push(((subst_dir_conf *) cfg)->patterns);
        /* init the new entries */
        nscript->pattern = NULL;
        nscript->regexp = NULL;
        nscript->replacement = NULL;
        nscript->patlen = 0;
        nscript->from = from;
    
        if (is_pattern) {
            nscript->patlen = strlen(from);
            nscript->pattern = apr_strmatch_precompile(cmd->pool, from,
                                                       !ignore_case);
        }
        else {
            nscript->regexp = r;
        }
    
        nscript->replacement = to;
        nscript->replen = strlen(to);
        nscript->flatten = flatten;
    
        return NULL;
    }
    
    #define KBYTE         1024
    #define MBYTE         1048576
    #define GBYTE         1073741824
    
    static const char *set_max_line_length(cmd_parms *cmd, void *cfg, const char *arg)
    {
        subst_dir_conf *dcfg = (subst_dir_conf *)cfg;
        apr_off_t max;
        char *end;
        apr_status_t rv;
    
        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 == 'G' || *end == 'g') && !end[1]) {
                max *= GBYTE;
            }
            else if (*end && /* neither empty nor [Bb] */
                     ((*end != 'B' && *end != 'b') || end[1])) {
                rv = APR_EGENERAL;
            }
        }
    
        if (rv != APR_SUCCESS || max < 0)
        {
            return "SubstituteMaxLineLength must be a non-negative integer optionally "
                   "suffixed with 'b', 'k', 'm' or 'g'.";
        }
        dcfg->max_line_length = (apr_size_t)max;
        dcfg->max_line_length_set = 1;
        return NULL;
    }
    
    #define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH
    static void register_hooks(apr_pool_t *pool)
    {
        ap_register_output_filter(substitute_filter_name, substitute_filter,
                                  NULL, AP_FTYPE_RESOURCE);
    }
    
    static const command_rec substitute_cmds[] = {
        AP_INIT_TAKE1("Substitute", set_pattern, NULL, OR_FILEINFO,
                      "Pattern to filter the response content (s/foo/bar/[inf])"),
        AP_INIT_TAKE1("SubstituteMaxLineLength", set_max_line_length, NULL, OR_FILEINFO,
                      "Maximum line length"),
        AP_INIT_FLAG("SubstituteInheritBefore", ap_set_flag_slot,
                     (void *)APR_OFFSETOF(subst_dir_conf, inherit_before), OR_FILEINFO,
                     "Apply inherited patterns before those of the current context"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(substitute) = {
        STANDARD20_MODULE_STUFF,
        create_substitute_dcfg,     /* dir config creater */
        merge_substitute_dcfg,      /* dir merger --- default is to override */
        NULL,                       /* server config */
        NULL,                       /* merge server config */
        substitute_cmds,            /* command table */
        register_hooks              /* register hooks */
    };
    ���������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_brotli.c�����������������������������������������������������������0000664�0001751�0001751�00000050534�13630321750�020247� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_core.h"
    #include "http_log.h"
    #include "apr_strings.h"
    
    #include <brotli/encode.h>
    
    module AP_MODULE_DECLARE_DATA brotli_module;
    
    typedef enum {
        ETAG_MODE_ADDSUFFIX = 0,
        ETAG_MODE_NOCHANGE = 1,
        ETAG_MODE_REMOVE = 2
    } etag_mode_e;
    
    typedef struct brotli_server_config_t {
        int quality;
        int lgwin;
        int lgblock;
        etag_mode_e etag_mode;
        const char *note_ratio_name;
        const char *note_input_name;
        const char *note_output_name;
    } brotli_server_config_t;
    
    static void *create_server_config(apr_pool_t *p, server_rec *s)
    {
        brotli_server_config_t *conf = apr_pcalloc(p, sizeof(*conf));
    
        /* These default values allow mod_brotli to behave similarly to
         * mod_deflate in terms of compression speed and memory usage.
         *
         * The idea is that since Brotli (generally) gives better compression
         * ratio than Deflate, simply enabling mod_brotli on the server
         * will reduce the amount of transferred data while keeping everything
         * else unchanged.  See https://quixdb.github.io/squash-benchmark/
         */
        conf->quality = 5;
        conf->lgwin = 18;
        /* Zero is a special value for BROTLI_PARAM_LGBLOCK that allows
         * Brotli to automatically select the optimal input block size based
         * on other encoder parameters.  See enc/quality.h: ComputeLgBlock().
         */
        conf->lgblock = 0;
        conf->etag_mode = ETAG_MODE_ADDSUFFIX;
    
        return conf;
    }
    
    static const char *set_filter_note(cmd_parms *cmd, void *dummy,
                                       const char *arg1, const char *arg2)
    {
        brotli_server_config_t *conf =
            ap_get_module_config(cmd->server->module_config, &brotli_module);
    
        if (!arg2) {
            conf->note_ratio_name = arg1;
            return NULL;
        }
    
        if (ap_cstr_casecmp(arg1, "Ratio") == 0) {
            conf->note_ratio_name = arg2;
        }
        else if (ap_cstr_casecmp(arg1, "Input") == 0) {
            conf->note_input_name = arg2;
        }
        else if (ap_cstr_casecmp(arg1, "Output") == 0) {
            conf->note_output_name = arg2;
        }
        else {
            return apr_psprintf(cmd->pool, "Unknown BrotliFilterNote type '%s'",
                                arg1);
        }
    
        return NULL;
    }
    
    static const char *set_compression_quality(cmd_parms *cmd, void *dummy,
                                               const char *arg)
    {
        brotli_server_config_t *conf =
            ap_get_module_config(cmd->server->module_config, &brotli_module);
        int val = atoi(arg);
    
        if (val < 0 || val > 11) {
            return "BrotliCompressionQuality must be between 0 and 11";
        }
    
        conf->quality = val;
        return NULL;
    }
    
    static const char *set_compression_lgwin(cmd_parms *cmd, void *dummy,
                                             const char *arg)
    {
        brotli_server_config_t *conf =
            ap_get_module_config(cmd->server->module_config, &brotli_module);
        int val = atoi(arg);
    
        if (val < 10 || val > 24) {
            return "BrotliCompressionWindow must be between 10 and 24";
        }
    
        conf->lgwin = val;
        return NULL;
    }
    
    static const char *set_compression_lgblock(cmd_parms *cmd, void *dummy,
                                               const char *arg)
    {
        brotli_server_config_t *conf =
            ap_get_module_config(cmd->server->module_config, &brotli_module);
        int val = atoi(arg);
    
        if (val < 16 || val > 24) {
            return "BrotliCompressionMaxInputBlock must be between 16 and 24";
        }
    
        conf->lgblock = val;
        return NULL;
    }
    
    static const char *set_etag_mode(cmd_parms *cmd, void *dummy,
                                     const char *arg)
    {
        brotli_server_config_t *conf =
            ap_get_module_config(cmd->server->module_config, &brotli_module);
    
        if (ap_cstr_casecmp(arg, "AddSuffix") == 0) {
            conf->etag_mode = ETAG_MODE_ADDSUFFIX;
        }
        else if (ap_cstr_casecmp(arg, "NoChange") == 0) {
            conf->etag_mode = ETAG_MODE_NOCHANGE;
        }
        else if (ap_cstr_casecmp(arg, "Remove") == 0) {
            conf->etag_mode = ETAG_MODE_REMOVE;
        }
        else {
            return "BrotliAlterETag accepts only 'AddSuffix', 'NoChange' and 'Remove'";
        }
    
        return NULL;
    }
    
    typedef struct brotli_ctx_t {
        BrotliEncoderState *state;
        apr_bucket_brigade *bb;
        apr_off_t total_in;
        apr_off_t total_out;
    } brotli_ctx_t;
    
    static void *alloc_func(void *opaque, size_t size)
    {
        return apr_bucket_alloc(size, opaque);
    }
    
    static void free_func(void *opaque, void *block)
    {
        if (block) {
            apr_bucket_free(block);
        }
    }
    
    static apr_status_t cleanup_ctx(void *data)
    {
        brotli_ctx_t *ctx = data;
    
        BrotliEncoderDestroyInstance(ctx->state);
        ctx->state = NULL;
        return APR_SUCCESS;
    }
    
    static brotli_ctx_t *create_ctx(int quality,
                                    int lgwin,
                                    int lgblock,
                                    apr_bucket_alloc_t *alloc,
                                    apr_pool_t *pool)
    {
        brotli_ctx_t *ctx = apr_pcalloc(pool, sizeof(*ctx));
    
        ctx->state = BrotliEncoderCreateInstance(alloc_func, free_func, alloc);
        BrotliEncoderSetParameter(ctx->state, BROTLI_PARAM_QUALITY, quality);
        BrotliEncoderSetParameter(ctx->state, BROTLI_PARAM_LGWIN, lgwin);
        BrotliEncoderSetParameter(ctx->state, BROTLI_PARAM_LGBLOCK, lgblock);
        apr_pool_cleanup_register(pool, ctx, cleanup_ctx, apr_pool_cleanup_null);
    
        ctx->bb = apr_brigade_create(pool, alloc);
        ctx->total_in = 0;
        ctx->total_out = 0;
    
        return ctx;
    }
    
    static apr_status_t process_chunk(brotli_ctx_t *ctx,
                                      const void *data,
                                      apr_size_t len,
                                      ap_filter_t *f)
    {
        const apr_byte_t *next_in = data;
        apr_size_t avail_in = len;
    
        while (avail_in > 0) {
            apr_byte_t *next_out = NULL;
            apr_size_t avail_out = 0;
    
            if (!BrotliEncoderCompressStream(ctx->state,
                                             BROTLI_OPERATION_PROCESS,
                                             &avail_in, &next_in,
                                             &avail_out, &next_out, NULL)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(03459)
                              "Error while compressing data");
                return APR_EGENERAL;
            }
    
            if (BrotliEncoderHasMoreOutput(ctx->state)) {
                apr_size_t output_len = 0;
                const apr_byte_t *output;
                apr_status_t rv;
                apr_bucket *b;
    
                /* Drain the accumulated output.  Avoid copying the data by
                 * wrapping a pointer to the internal output buffer and passing
                 * it down to the next filter.  The pointer is only valid until
                 * the next call to BrotliEncoderCompressStream(), but we're okay
                 * with that, since the brigade is cleaned up right after the
                 * ap_pass_brigade() call.
                 */
                output = BrotliEncoderTakeOutput(ctx->state, &output_len);
                ctx->total_out += output_len;
    
                b = apr_bucket_transient_create((const char *)output, output_len,
                                                ctx->bb->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
    
                rv = ap_pass_brigade(f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
            }
        }
    
        ctx->total_in += len;
        return APR_SUCCESS;
    }
    
    static apr_status_t flush(brotli_ctx_t *ctx,
                              BrotliEncoderOperation op,
                              ap_filter_t *f)
    {
        while (1) {
            const apr_byte_t *next_in = NULL;
            apr_size_t avail_in = 0;
            apr_byte_t *next_out = NULL;
            apr_size_t avail_out = 0;
            apr_size_t output_len;
            const apr_byte_t *output;
            apr_bucket *b;
    
            if (!BrotliEncoderCompressStream(ctx->state, op,
                                             &avail_in, &next_in,
                                             &avail_out, &next_out, NULL)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(03460)
                              "Error while compressing data");
                return APR_EGENERAL;
            }
    
            if (!BrotliEncoderHasMoreOutput(ctx->state)) {
                break;
            }
    
            /* A flush can require several calls to BrotliEncoderCompressStream(),
             * so place the data on the heap (otherwise, the pointer will become
             * invalid after the next call to BrotliEncoderCompressStream()).
             */
            output_len = 0;
            output = BrotliEncoderTakeOutput(ctx->state, &output_len);
            ctx->total_out += output_len;
    
            b = apr_bucket_heap_create((const char *)output, output_len, NULL,
                                       ctx->bb->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
        }
    
        return APR_SUCCESS;
    }
    
    static const char *get_content_encoding(request_rec *r)
    {
        const char *encoding;
    
        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;
        }
    
        return encoding;
    }
    
    static apr_status_t compress_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        request_rec *r = f->r;
        brotli_ctx_t *ctx = f->ctx;
        apr_status_t rv;
        brotli_server_config_t *conf;
    
        if (APR_BRIGADE_EMPTY(bb)) {
            return APR_SUCCESS;
        }
    
        conf = ap_get_module_config(r->server->module_config, &brotli_module);
    
        if (!ctx) {
            const char *encoding;
            const char *token;
            const char *accepts;
            const char *q = NULL;
    
            /* Only work on main request, not subrequests, that are not
             * a 204 response with no content, and are not tagged with the
             * no-brotli env variable, and are not a partial response to
             * a Range request.
             *
             * Note that responding to 304 is handled separately to set
             * the required headers (such as ETag) per RFC7232, 4.1.
             */
            if (r->main || r->status == HTTP_NO_CONTENT
                || apr_table_get(r->subprocess_env, "no-brotli")
                || apr_table_get(r->headers_out, "Content-Range")) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /* Let's see what our current Content-Encoding is. */
            encoding = get_content_encoding(r);
    
            if (encoding) {
                const char *tmp = encoding;
    
                token = ap_get_token(r->pool, &tmp, 0);
                while (token && *token) {
                    if (strcmp(token, "identity") != 0 &&
                        strcmp(token, "7bit") != 0 &&
                        strcmp(token, "8bit") != 0 &&
                        strcmp(token, "binary") != 0) {
                        /* The data is already encoded, do nothing. */
                        ap_remove_output_filter(f);
                        return ap_pass_brigade(f->next, bb);
                    }
    
                    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");
    
            accepts = apr_table_get(r->headers_in, "Accept-Encoding");
            if (!accepts) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /* Do we have Accept-Encoding: br? */
            token = ap_get_token(r->pool, &accepts, 0);
            while (token && token[0] && ap_cstr_casecmp(token, "br") != 0) {
                while (*accepts == ';') {
                    ++accepts;
                    ap_get_token(r->pool, &accepts, 1);
                }
    
                if (*accepts == ',') {
                    ++accepts;
                }
                token = (*accepts) ? ap_get_token(r->pool, &accepts, 0) : NULL;
            }
    
            /* Find the qvalue, if provided */
            if (*accepts) {
                while (*accepts == ';') {
                    ++accepts;
                }
                q = ap_get_token(r->pool, &accepts, 1);
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "token: '%s' - q: '%s'", token ? token : "NULL", q);
            }
    
            /* No acceptable token found or q=0 */
            if (!token || token[0] == '\0' ||
                (q && strlen(q) >= 3 && strncmp("q=0.000", q, strlen(q)) == 0)) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /* If the entire Content-Encoding is "identity", we can replace it. */
            if (!encoding || ap_cstr_casecmp(encoding, "identity") == 0) {
                apr_table_setn(r->headers_out, "Content-Encoding", "br");
            } else {
                apr_table_mergen(r->headers_out, "Content-Encoding", "br");
            }
    
            if (r->content_encoding) {
                r->content_encoding = apr_table_get(r->headers_out,
                                                    "Content-Encoding");
            }
    
            apr_table_unset(r->headers_out, "Content-Length");
            apr_table_unset(r->headers_out, "Content-MD5");
    
            /* https://bz.apache.org/bugzilla/show_bug.cgi?id=39727
             * https://bz.apache.org/bugzilla/show_bug.cgi?id=45023
             *
             * ETag must be unique among the possible representations, so a
             * change to content-encoding requires a corresponding change to the
             * ETag.  We make this behavior configurable, and mimic mod_deflate's
             * DeflateAlterETag with BrotliAlterETag to keep the transition from
             * mod_deflate seamless.
             */
            if (conf->etag_mode == ETAG_MODE_REMOVE) {
                apr_table_unset(r->headers_out, "ETag");
            }
            else if (conf->etag_mode == ETAG_MODE_ADDSUFFIX) {
                const char *etag = apr_table_get(r->headers_out, "ETag");
    
                if (etag) {
                    apr_size_t len = strlen(etag);
    
                    if (len > 2 && etag[len - 1] == '"') {
                        etag = apr_pstrmemdup(r->pool, etag, len - 1);
                        etag = apr_pstrcat(r->pool, etag, "-br\"", NULL);
                        apr_table_setn(r->headers_out, "ETag", etag);
                    }
                }
            }
    
            /* For 304 responses, we only need to send out the headers. */
            if (r->status == HTTP_NOT_MODIFIED) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            ctx = create_ctx(conf->quality, conf->lgwin, conf->lgblock,
                             f->c->bucket_alloc, r->pool);
            f->ctx = ctx;
        }
    
        while (!APR_BRIGADE_EMPTY(bb)) {
            apr_bucket *e = APR_BRIGADE_FIRST(bb);
    
            /* Optimization: If we are a HEAD request and bytes_sent is not zero
             * it means that we have passed the content-length filter once and
             * have more data to send.  This means that the content-length filter
             * could not determine our content-length for the response to the
             * HEAD request anyway (the associated GET request would deliver the
             * body in chunked encoding) and we can stop compressing.
             */
            if (r->header_only && r->bytes_sent) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            if (APR_BUCKET_IS_EOS(e)) {
                rv = flush(ctx, BROTLI_OPERATION_FINISH, f);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
    
                /* Leave notes for logging. */
                if (conf->note_input_name) {
                    apr_table_setn(r->notes, conf->note_input_name,
                                   apr_off_t_toa(r->pool, ctx->total_in));
                }
                if (conf->note_output_name) {
                    apr_table_setn(r->notes, conf->note_output_name,
                                   apr_off_t_toa(r->pool, ctx->total_out));
                }
                if (conf->note_ratio_name) {
                    if (ctx->total_in > 0) {
                        int ratio = (int) (ctx->total_out * 100 / ctx->total_in);
    
                        apr_table_setn(r->notes, conf->note_ratio_name,
                                       apr_itoa(r->pool, ratio));
                    }
                    else {
                        apr_table_setn(r->notes, conf->note_ratio_name, "-");
                    }
                }
    
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
    
                rv = ap_pass_brigade(f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                apr_pool_cleanup_run(r->pool, ctx, cleanup_ctx);
                return rv;
            }
            else if (APR_BUCKET_IS_FLUSH(e)) {
                rv = flush(ctx, BROTLI_OPERATION_FLUSH, f);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
    
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
    
                rv = ap_pass_brigade(f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
            }
            else if (APR_BUCKET_IS_METADATA(e)) {
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
            }
            else {
                const char *data;
                apr_size_t len;
    
                rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
                rv = process_chunk(ctx, data, len, f);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
                apr_bucket_delete(e);
            }
        }
        return APR_SUCCESS;
    }
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_output_filter("BROTLI_COMPRESS", compress_filter, NULL,
                                  AP_FTYPE_CONTENT_SET);
    }
    
    static const command_rec cmds[] = {
        AP_INIT_TAKE12("BrotliFilterNote", set_filter_note,
                       NULL, RSRC_CONF,
                       "Set a note to report on compression ratio"),
        AP_INIT_TAKE1("BrotliCompressionQuality", set_compression_quality,
                      NULL, RSRC_CONF,
                      "Compression quality between 0 and 11 (higher quality means "
                      "slower compression)"),
        AP_INIT_TAKE1("BrotliCompressionWindow", set_compression_lgwin,
                      NULL, RSRC_CONF,
                      "Sliding window size between 10 and 24 (larger windows can "
                      "improve compression, but require more memory)"),
        AP_INIT_TAKE1("BrotliCompressionMaxInputBlock", set_compression_lgblock,
                      NULL, RSRC_CONF,
                      "Maximum input block size between 16 and 24 (larger block "
                      "sizes require more memory)"),
        AP_INIT_TAKE1("BrotliAlterETag", set_etag_mode,
                      NULL, RSRC_CONF,
                      "Set how mod_brotli should modify ETag response headers: "
                      "'AddSuffix' (default), 'NoChange', 'Remove'"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(brotli) = {
        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 */
        cmds,                      /* command apr_table_t */
        register_hooks             /* register hooks */
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_brotli.mak���������������������������������������������������������0000664�0001751�0001751�00000024076�13100405645�020575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_brotli.dsp
    !IF "$(CFG)" == ""
    CFG=mod_brotli - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_brotli - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_brotli - Win32 Release" && "$(CFG)" != "mod_brotli - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_brotli.mak" CFG="mod_brotli - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_brotli - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_brotli - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_brotli - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_brotli.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_brotli.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_brotli.obj"
    	-@erase "$(INTDIR)\mod_brotli.res"
    	-@erase "$(INTDIR)\mod_brotli_src.idb"
    	-@erase "$(INTDIR)\mod_brotli_src.pdb"
    	-@erase "$(OUTDIR)\mod_brotli.exp"
    	-@erase "$(OUTDIR)\mod_brotli.lib"
    	-@erase "$(OUTDIR)\mod_brotli.pdb"
    	-@erase "$(OUTDIR)\mod_brotli.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/brotli/include" /I "../../srclib/brotli/c/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_brotli_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_brotli.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_brotli.so" /d LONG_NAME="brotli_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_brotli.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib brotlicommon.lib brotlienc.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_brotli.pdb" /libpath:"../../srclib/brotli" /debug /out:"$(OUTDIR)\mod_brotli.so" /implib:"$(OUTDIR)\mod_brotli.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_brotli.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_brotli.obj" \
    	"$(INTDIR)\mod_brotli.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_brotli.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_brotli.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_brotli.so"
       if exist .\Release\mod_brotli.so.manifest mt.exe -manifest .\Release\mod_brotli.so.manifest -outputresource:.\Release\mod_brotli.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_brotli - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_brotli.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_brotli.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_brotli.obj"
    	-@erase "$(INTDIR)\mod_brotli.res"
    	-@erase "$(INTDIR)\mod_brotli_src.idb"
    	-@erase "$(INTDIR)\mod_brotli_src.pdb"
    	-@erase "$(OUTDIR)\mod_brotli.exp"
    	-@erase "$(OUTDIR)\mod_brotli.lib"
    	-@erase "$(OUTDIR)\mod_brotli.pdb"
    	-@erase "$(OUTDIR)\mod_brotli.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/brotli/include" /I "../../srclib/brotli/c/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_brotli_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_brotli.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_brotli.so" /d LONG_NAME="brotli_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_brotli.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib brotlicommon.lib brotlienc.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_brotli.pdb" /debug /libpath:"../../srclib/brotli" /out:"$(OUTDIR)\mod_brotli.so" /implib:"$(OUTDIR)\mod_brotli.lib" /libpath:"..\..\srclib\brotli\Debug\bin" /base:@..\..\os\win32\BaseAddr.ref,mod_brotli.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_brotli.obj" \
    	"$(INTDIR)\mod_brotli.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_brotli.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_brotli.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_brotli.so"
       if exist .\Debug\mod_brotli.so.manifest mt.exe -manifest .\Debug\mod_brotli.so.manifest -outputresource:.\Debug\mod_brotli.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_brotli.dep")
    !INCLUDE "mod_brotli.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_brotli.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_brotli - Win32 Release" || "$(CFG)" == "mod_brotli - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_brotli - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_brotli - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_brotli - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_brotli - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_brotli - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_brotli - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_brotli - Win32 Release"
    
    
    "$(INTDIR)\mod_brotli.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_brotli.res" /i "../../include" /i "../../srclib/apr/include" /i "\build4\httpd-2.4.23\build\win32" /d "NDEBUG" /d BIN_NAME="mod_brotli.so" /d LONG_NAME="brotli_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_brotli - Win32 Debug"
    
    
    "$(INTDIR)\mod_brotli.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_brotli.res" /i "../../include" /i "../../srclib/apr/include" /i "\build4\httpd-2.4.23\build\win32" /d "_DEBUG" /d BIN_NAME="mod_brotli.so" /d LONG_NAME="brotli_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_brotli.c
    
    "$(INTDIR)\mod_brotli.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reflector.dep������������������������������������������������������0000664�0001751�0001751�00000004020�12674411515�021262� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_reflector.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_reflector.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_core.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_data.dep�����������������������������������������������������������0000664�0001751�0001751�00000003735�12674411515�020222� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_data.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_data.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_base64.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������httpd-2.4.64/modules/filters/mod_substitute.dsp�����������������������������������������������������0000664�0001751�0001751�00000011045�12062614564�021533� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_substitute" - 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_substitute - 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_substitute.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_substitute.mak" CFG="mod_substitute - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_substitute - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_substitute - 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_substitute - 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_substitute_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 /fo"Release/mod_substitute.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_substitute.so" /d LONG_NAME="substitute_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_substitute.so" /base:@..\..\os\win32\BaseAddr.ref,mod_substitute.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_substitute.so" /base:@..\..\os\win32\BaseAddr.ref,mod_substitute.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_substitute.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_substitute - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_substitute_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 /fo"Debug/mod_substitute.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_substitute.so" /d LONG_NAME="substitute_module for Apache"
    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 /out:".\Debug\mod_substitute.so" /base:@..\..\os\win32\BaseAddr.ref,mod_substitute.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_substitute.so" /base:@..\..\os\win32\BaseAddr.ref,mod_substitute.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_substitute.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_substitute - Win32 Release"
    # Name "mod_substitute - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_substitute.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_data.dsp�����������������������������������������������������������0000664�0001751�0001751�00000010533�12062614564�020232� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_data" - 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_data - 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_data.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_data.mak" CFG="mod_data - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_data - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_data - 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_data - 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" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_data_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 /fo"Release/mod_data.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_data.so" /d LONG_NAME="data_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_data.so" /base:@..\..\os\win32\BaseAddr.ref,mod_data.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_data.so" /base:@..\..\os\win32\BaseAddr.ref,mod_data.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_data.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_data - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fd"Debug\mod_data_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 /fo"Debug/mod_data.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_data.so" /d LONG_NAME="data_module for Apache"
    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 /out:".\Debug\mod_data.so" /base:@..\..\os\win32\BaseAddr.ref,mod_data.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_data.so" /base:@..\..\os\win32\BaseAddr.ref,mod_data.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_data.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_data - Win32 Release"
    # Name "mod_data - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_data.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_include.dep��������������������������������������������������������0000664�0001751�0001751�00000004327�12674411515�020732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_include.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_include.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_ebcdic.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_include.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUmodbuffer���������������������������������������������������������0000664�0001751�0001751�00000010234�11540546347�020466� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= modbuffer
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Buffer Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= modbuffer
    
    #
    # 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	=
    
    #
    # 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)/modbuffer.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_buffer.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	buffer_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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reqtimeout.dep�����������������������������������������������������0000664�0001751�0001751�00000004104�12674411515�021476� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_reqtimeout.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_reqtimeout.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_version.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_substitute.dep�����������������������������������������������������0000664�0001751�0001751�00000003563�12674411515�021523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_substitute.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_substitute.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_varbuf.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_proxy_html.dsp�����������������������������������������������������0000664�0001751�0001751�00000011735�12234633661�021533� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_proxy_html" - 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_html - 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_html.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_html.mak" CFG="mod_proxy_html - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_html - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_html - 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_html - 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 "../../srclib/libxml2/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_html_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" /i "../../include" /i "../../srclib/apr/include" /I "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d BIN_NAME="mod_proxy_html.so" /d LONG_NAME="proxy_html_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_proxy_html.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_html.so
    # ADD LINK32 kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /libpath:"../../srclib/libxml2/win32/bin.msvc" /debug /out:".\Release\mod_proxy_html.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_html.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_proxy_html.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_proxy_html - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/libxml2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_html_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" /i "../../include" /i "../../srclib/apr/include" /I "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d BIN_NAME="mod_proxy_html.so" /d LONG_NAME="proxy_html_module for Apache" 
    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 /out:".\Debug\mod_proxy_html.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_html.so
    # ADD LINK32 kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /libpath:"../../srclib/libxml2/win32/bin.msvc" /debug /out:".\Debug\mod_proxy_html.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_html.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_proxy_html.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_proxy_html - Win32 Release"
    # Name "mod_proxy_html - Win32 Debug"
    # Begin Group "Header Files"
    
    # PROP Default_Filter "h"
    # Begin Source File
    
    SOURCE=.\mod_xml2enc.h
    # End Source File
    # End Group
    # Begin Group "Source Files"
    
    # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
    # Begin Source File
    
    SOURCE=.\mod_proxy_html.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Group
    # End Target
    # End Project
    �����������������������������������httpd-2.4.64/modules/filters/mod_sed.mak������������������������������������������������������������0000664�0001751�0001751�00000023765�12701473373�020072� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_sed.dsp
    !IF "$(CFG)" == ""
    CFG=mod_sed - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_sed - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_sed - Win32 Release" && "$(CFG)" != "mod_sed - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_sed.mak" CFG="mod_sed - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_sed - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_sed - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_sed - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_sed.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_sed.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_sed.obj"
    	-@erase "$(INTDIR)\mod_sed.res"
    	-@erase "$(INTDIR)\mod_sed_src.idb"
    	-@erase "$(INTDIR)\mod_sed_src.pdb"
    	-@erase "$(INTDIR)\regexp.obj"
    	-@erase "$(INTDIR)\sed0.obj"
    	-@erase "$(INTDIR)\sed1.obj"
    	-@erase "$(OUTDIR)\mod_sed.exp"
    	-@erase "$(OUTDIR)\mod_sed.lib"
    	-@erase "$(OUTDIR)\mod_sed.pdb"
    	-@erase "$(OUTDIR)\mod_sed.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_sed_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_sed.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_sed.so" /d LONG_NAME="sed_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_sed.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_sed.pdb" /debug /out:"$(OUTDIR)\mod_sed.so" /implib:"$(OUTDIR)\mod_sed.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_sed.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_sed.obj" \
    	"$(INTDIR)\regexp.obj" \
    	"$(INTDIR)\sed0.obj" \
    	"$(INTDIR)\sed1.obj" \
    	"$(INTDIR)\mod_sed.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_sed.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_sed.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_sed.so"
       if exist .\Release\mod_sed.so.manifest mt.exe -manifest .\Release\mod_sed.so.manifest -outputresource:.\Release\mod_sed.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_sed - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_sed.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_sed.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_sed.obj"
    	-@erase "$(INTDIR)\mod_sed.res"
    	-@erase "$(INTDIR)\mod_sed_src.idb"
    	-@erase "$(INTDIR)\mod_sed_src.pdb"
    	-@erase "$(INTDIR)\regexp.obj"
    	-@erase "$(INTDIR)\sed0.obj"
    	-@erase "$(INTDIR)\sed1.obj"
    	-@erase "$(OUTDIR)\mod_sed.exp"
    	-@erase "$(OUTDIR)\mod_sed.lib"
    	-@erase "$(OUTDIR)\mod_sed.pdb"
    	-@erase "$(OUTDIR)\mod_sed.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_sed_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_sed.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_sed.so" /d LONG_NAME="sed_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_sed.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_sed.pdb" /debug /out:"$(OUTDIR)\mod_sed.so" /implib:"$(OUTDIR)\mod_sed.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_sed.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_sed.obj" \
    	"$(INTDIR)\regexp.obj" \
    	"$(INTDIR)\sed0.obj" \
    	"$(INTDIR)\sed1.obj" \
    	"$(INTDIR)\mod_sed.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_sed.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_sed.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_sed.so"
       if exist .\Debug\mod_sed.so.manifest mt.exe -manifest .\Debug\mod_sed.so.manifest -outputresource:.\Debug\mod_sed.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_sed.dep")
    !INCLUDE "mod_sed.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_sed.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_sed - Win32 Release" || "$(CFG)" == "mod_sed - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_sed - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_sed - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_sed - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_sed - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_sed - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_sed - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_sed - Win32 Release"
    
    
    "$(INTDIR)\mod_sed.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_sed.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_sed.so" /d LONG_NAME="sed_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_sed - Win32 Debug"
    
    
    "$(INTDIR)\mod_sed.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_sed.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_sed.so" /d LONG_NAME="sed_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_sed.c
    
    "$(INTDIR)\mod_sed.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\regexp.c
    
    "$(INTDIR)\regexp.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\sed0.c
    
    "$(INTDIR)\sed0.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\sed1.c
    
    "$(INTDIR)\sed1.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������httpd-2.4.64/modules/filters/NWGNUreflector���������������������������������������������������������0000664�0001751�0001751�00000010245�11737125415�020501� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= reflector
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Reflector Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= reflector
    
    #
    # 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	=
    
    #
    # 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)/reflector.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_reflector.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	reflector_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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_xml2enc.dsp��������������������������������������������������������0000664�0001751�0001751�00000011610�12234633661�020666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_xml2enc" - 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_xml2enc - 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_xml2enc.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_xml2enc.mak" CFG="mod_xml2enc - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_xml2enc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_xml2enc - 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_xml2enc - 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 "../../srclib/libxml2/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_xml2enc_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" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d BIN_NAME="mod_xml2enc.so" /d LONG_NAME="xml2enc_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_xml2enc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_xml2enc.so
    # ADD LINK32 kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /debug /libpath:"../../srclib/libxml2/win32/bin.msvc" /out:".\Release\mod_xml2enc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_xml2enc.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_xml2enc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_xml2enc - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/libxml2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_xml2enc_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" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d BIN_NAME="mod_xml2enc.so" /d LONG_NAME="xml2enc_module for Apache"
    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 /out:".\Debug\mod_xml2enc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_xml2enc.so
    # ADD LINK32 kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /debug /libpath:"../../srclib/libxml2/win32/bin.msvc" /out:".\Debug\mod_xml2enc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_xml2enc.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_xml2enc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_xml2enc - Win32 Release"
    # Name "mod_xml2enc - Win32 Debug"
    # Begin Group "Header Files"
    
    # PROP Default_Filter "h"
    # Begin Source File
    
    SOURCE=.\mod_xml2enc.h
    # End Source File
    # End Group
    # Begin Group "Source Files"
    
    # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
    # Begin Source File
    
    SOURCE=.\mod_xml2enc.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Group
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUextfiltr����������������������������������������������������������0000664�0001751�0001751�00000010165�11540546347�020361� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= 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	=
    
    #
    # 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 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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_include.c����������������������������������������������������������0000664�0001751�0001751�00000411257�14640775605�020420� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "ap_expr.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_ACCESS
    } 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_UNSET
    } xbithack_t;
    
    typedef struct {
        const char *default_error_msg;
        const char *default_time_fmt;
        const char *undefined_echo;
        xbithack_t  xbithack;
        signed char lastmodified;
        signed char etag;
        signed char legacy_expr;
    } 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];
        int have_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;
    
        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;
    
        char         legacy_expr;     /* use ap_expr or legacy mod_include
                                        expression parser? */
    
        ap_expr_eval_ctx_t *expr_eval_ctx;  /* NULL if there wasn't an ap_expr yet */
        const char         *expr_vary_this; /* for use by ap_expr_eval_ctx */
        const char         *expr_err;       /* for use by ap_expr_eval_ctx */
    #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");
    }
    
    #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 = '\0';
    #define LAZY_VALUE (&lazy_eval_sentinel)
    
    /* default values */
    #define DEFAULT_START_SEQUENCE "<!--#"
    #define DEFAULT_END_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)"
    
    #define UNSET -1
    
    #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, &#00; 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. */
    
    /* Note: this function is deprecated in favour of apr_unescape_entity() in APR */
    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)
    {
        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);
        apr_table_setn(e, "DOCUMENT_ARGS", r->args ? r->args : "");
        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, const char *timefmt)
    {
        char *val;
        if (!strcasecmp(var, "DATE_LOCAL")) {
            val = ap_ht_time(r->pool, r->request_time, timefmt, 0);
        }
        else if (!strcasecmp(var, "DATE_GMT")) {
            val = ap_ht_time(r->pool, r->request_time, timefmt, 1);
        }
        else if (!strcasecmp(var, "LAST_MODIFIED")) {
            val = ap_ht_time(r->pool, r->finfo.mtime, timefmt, 0);
        }
        else if (!strcasecmp(var, "USER_NAME")) {
            if (apr_uid_name_get(&val, r->finfo.user, r->pool) != APR_SUCCESS) {
                val = "<unknown>";
            }
        }
        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->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 || !re->have_match) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01329)
                    "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, APLOGNO(01330)
                              "regex capture $%" APR_SIZE_T_FMT
                              " is out of range (last regex was: '%s') in %s",
                              idx, re->rexp, r->filename);
                return NULL;
            }
            else if (re->match[idx].rm_so < 0 || re->match[idx].rm_eo < 0) {
                /* This particular subpattern was not used by the regex */
                return NULL;
            }
            else {
                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, ctx->time_str);
            }
        }
    
        return val;
    }
    
    static const char *include_expr_var_fn(ap_expr_eval_ctx_t *eval_ctx,
                                           const void *data,
                                           const char *arg)
    {
        const char *res, *name = data;
        include_ctx_t *ctx = eval_ctx->data;
        if ((name[0] == 'e') || (name[0] == 'E')) {
            /* keep legacy "env" semantics */
            if ((res = apr_table_get(ctx->r->notes, arg)) != NULL)
                return res;
            else if ((res = get_include_var(arg, ctx)) != NULL)
                return res;
            else
                return getenv(arg);
        }
        else {
            return get_include_var(arg, ctx);
        }
    }
    
    static int include_expr_lookup(ap_expr_lookup_parms *parms)
    {
        switch (parms->type) {
        case AP_EXPR_FUNC_STRING:
            if (strcasecmp(parms->name, "v") == 0 ||
                strcasecmp(parms->name, "reqenv") == 0 ||
                strcasecmp(parms->name, "env") == 0) {
                *parms->func = include_expr_var_fn;
                *parms->data = parms->name;
                return OK;
            }
            break;
        /*
         * We could also make the SSI vars available as %{...} style variables
         * (AP_EXPR_FUNC_VAR), but this would create problems if we ever want
         * to cache parsed expressions for performance reasons.
         */
        }
        return ap_run_expr_lookup(parms);
    }
    
    
    /*
     * 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->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, APLOGNO(01331) "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;
    
        compiled = ap_pregcomp(ctx->dpool, rexp, AP_REG_EXTENDED);
        if (!compiled) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02667)
                          "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;
        re->have_match = !ap_regexec(compiled, string, AP_MAX_REG_MATCH,
                                     re->match, 0);
    
        ap_pregfree(ctx->dpool, compiled);
        return re->have_match;
    }
    
    static int get_ptoken(include_ctx_t *ctx, const char **parse, token_t *token, token_t *previous)
    {
        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 '/':
            /* if last token was ACCESS, this token is STRING */
            if (previous != NULL && TOKEN_ACCESS == previous->type) {
                break;
            }
            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;
        case '-':
            if (**parse == 'A') {
                TYPE_TOKEN(token, TOKEN_ACCESS);
                ++*parse;
                return 0;
            }
            break;
        }
    
        /* 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(ctx->dpool, "");
        }
        else {
            apr_size_t len = p - token->value - shift;
            char *c = apr_palloc(ctx->dpool, 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->r;
        request_rec *rr = NULL;
        const char *error = APLOGNO(03188) "Invalid expression \"%s\" in file %s";
        const char *parse = expr;
        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);
    
            {
    #ifdef DEBUG_INCLUDE
                int was_unmatched =
    #endif
                get_ptoken(ctx, &parse, &new->token,
                           (current != NULL ? &current->token : NULL));
                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_ACCESS:
                case TOKEN_LBRACE:
                    root = current = new;
                    continue;
    
                default:
                    /* Intentional no APLOGNO */
                    /* error text provides APLOGNO */
                    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(&current->token, TOKEN_GROUP);
                    continue;
                }
    
                error = APLOGNO(03189) "Unmatched ')' in \"%s\" in file %s";
                break;
    
            case TOKEN_NOT:
            case TOKEN_ACCESS:
            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;
            }
    
            /* Intentional no APLOGNO */
            /* error text provides APLOGNO */
            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, APLOGNO(01332)
                                  "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, APLOGNO(01333)
                                "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, APLOGNO(01334)
                                  "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_ACCESS:
                if (current->left || !current->right ||
                    (current->right->token.type != TOKEN_STRING &&
                     current->right->token.type != TOKEN_RE)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01335)
                                "Invalid expression \"%s\" in file %s: Token '-A' must be followed by a URI string.",
                                expr, r->filename);
                    *was_error = 1;
                    return 0;
                }
                current->right->token.value =
                    ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0,
                                        SSI_EXPAND_DROP_NAME);
                rr = ap_sub_req_lookup_uri(current->right->token.value, r, NULL);
                /* 400 and higher are considered access denied */
                if (rr->status < HTTP_BAD_REQUEST) {
                    current->value = 1;
                }
                else {
                    current->value = 0;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rr->status, r, APLOGNO(01336)
                                  "mod_include: The tested "
                                  "subrequest -A \"%s\" returned an error code.",
                                  current->right->token.value);
                }
                ap_destroy_sub_req(rr);
                break;
    
            case TOKEN_RE:
                if (!error) {
                    error = APLOGNO(03190) "No operator before regex in expr \"%s\" in file %s";
                }
            case TOKEN_LBRACE:
                if (!error) {
                    error = APLOGNO(03191) "Unmatched '(' in \"%s\" in file %s";
                }
            default:
                if (!error) {
                    error = APLOGNO(03192) "internal parser error in \"%s\" in file %s";
                }
    
                /* Intentional no APLOGNO */
                /* error text provides APLOGNO */
                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);
    }
    
    /* same as above, but use common ap_expr syntax / API */
    static int parse_ap_expr(include_ctx_t *ctx, const char *expr, int *was_error)
    {
        ap_expr_info_t *expr_info = apr_pcalloc(ctx->pool, sizeof (*expr_info));
        const char *err;
        int ret;
        backref_t *re = ctx->intern->re;
        ap_expr_eval_ctx_t *eval_ctx = ctx->intern->expr_eval_ctx;
    
        expr_info->filename = ctx->r->filename;
        expr_info->line_number = 0;
        expr_info->module_index = APLOG_MODULE_INDEX;
        expr_info->flags = AP_EXPR_FLAG_RESTRICTED;
        err = ap_expr_parse(ctx->r->pool, ctx->r->pool, expr_info, expr,
                            include_expr_lookup);
        if (err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(01337)
                          "Could not parse expr \"%s\" in %s: %s", expr,
                          ctx->r->filename, err);
            *was_error = 1;
            return 0;
        }
    
        if (!re) {
            ctx->intern->re = re = apr_pcalloc(ctx->pool, sizeof(*re));
        }
        else {
            /* ap_expr_exec_ctx() does not care about re->have_match but only about
             * re->source
             */
            if (!re->have_match)
                re->source = NULL;
        }
    
        if (!eval_ctx) {
            eval_ctx = apr_pcalloc(ctx->pool, sizeof(*eval_ctx));
            ctx->intern->expr_eval_ctx = eval_ctx;
            eval_ctx->r         = ctx->r;
            eval_ctx->c         = ctx->r->connection;
            eval_ctx->s         = ctx->r->server;
            eval_ctx->p         = ctx->r->pool;
            eval_ctx->data      = ctx;
            eval_ctx->err       = &ctx->intern->expr_err;
            eval_ctx->vary_this = &ctx->intern->expr_vary_this;
            eval_ctx->re_nmatch = AP_MAX_REG_MATCH;
            eval_ctx->re_pmatch = re->match;
            eval_ctx->re_source = &re->source;
        }
    
        eval_ctx->info = expr_info;
        ret = ap_expr_exec_ctx(eval_ctx);
        if (ret < 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(01338)
                          "Could not evaluate expr \"%s\" in %s: %s", expr,
                          ctx->r->filename, ctx->intern->expr_err);
            *was_error = 1;
            return 0;
        }
        *was_error = 0;
        if (re->source)
            re->have_match = 1;
        return ret;
    }
    
    /*
     * +-------------------------------------------------------+
     * |                                                       |
     * |                    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);
        }
    }
    
    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_SECUREROOTTEST |
                                    APR_FILEPATH_NOTABSOLUTE, r->pool);
    
            if (rv != APR_SUCCESS) {
                error_fmt = APLOGNO(02668) "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 != APR_NOFILE) {
                    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 = APLOGNO(02669) "unable to get information "
                                    "about \"%s\" in parsed file %s";
                    }
                }
                else {
                    error_fmt = APLOGNO(02670) "unable to lookup information "
                                "about \"%s\" in parsed file %s";
                }
            }
    
            if (error_fmt) {
                ret = -1;
                /* Intentional no APLOGNO */
                /* error_fmt provides APLOGNO */
                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 != APR_NOFILE) {
                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, APLOGNO(01339) "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, APLOGNO(01340) "unknown parameter \"%s\" "
                          "to tag %s in %s", tag, directive, r->filename);
            return -1;
        }
    }
    
    /*
     * <!--#comment blah blah blah ... -->
     */
    static apr_status_t handle_comment(include_ctx_t *ctx, ap_filter_t *f,
                                       apr_bucket_brigade *bb)
    {
        return APR_SUCCESS;
    }
    
    /*
     * <!--#include virtual|file="..." [onerror|virtual|file="..."] ... -->
     *
     * Output each file/virtual in turn until one of them returns an error.
     * On error, ignore all further file/virtual attributes until we reach
     * an onerror attribute, where we make an attempt to serve the onerror
     * virtual url. If onerror fails, or no onerror is present, the default
     * error string is inserted into the stream.
     */
    static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f,
                                       apr_bucket_brigade *bb)
    {
        request_rec *r = f->r;
        char *last_error;
    
        if (!ctx->argc) {
            ap_log_rerror(APLOG_MARK,
                          (ctx->flags & SSI_FLAG_PRINTING)
                              ? APLOG_ERR : APLOG_WARNING,
                          0, r, APLOGNO(01341)
                          "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;
        }
    
        last_error = NULL;
        while (1) {
            char *tag     = NULL;
            char *tag_val = NULL;
            request_rec *rr = NULL;
            char *error_fmt = NULL;
            char *parsed_string;
            apr_status_t rv = APR_SUCCESS;
            int status = 0;
    
            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") && strcmp(tag,
                    "onerror")) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01342) "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;
    
                /* be safe; only files in this directory or below allowed */
                rv = apr_filepath_merge(&newpath, NULL, parsed_string,
                                        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 if ((tag[0] == 'v' && !last_error)
                    || (tag[0] == 'o' && last_error)) {
                if (r->kept_body) {
                    rr = ap_sub_req_method_uri(r->method, parsed_string, r, f->next);
                }
                else {
                    rr = ap_sub_req_lookup_uri(parsed_string, r, f->next);
                }
            }
            else {
                continue;
            }
    
            if (!error_fmt && rr->status != HTTP_OK) {
                error_fmt = "unable to include \"%s\" in parsed file %s, subrequest setup returned %d";
            }
    
            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, content type not text/*";
            }
    
            /* 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 && ((status = ap_run_sub_req(rr)))) {
                error_fmt = "unable to include \"%s\" in parsed file %s, subrequest returned %d";
            }
    
            if (error_fmt) {
                /* Intentional no APLOGNO */
                /* error text is also sent to client */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, error_fmt, tag_val,
                        r->filename, status ? status : rr ? rr->status : 0);
                if (last_error) {
                    /* onerror threw an error, give up completely */
                    break;
                }
                last_error = error_fmt;
            }
            else {
                last_error = NULL;
            }
    
            /* 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 (last_error) {
            SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * <!--#echo [decoding="..."] [encoding="..."] var="..." [decoding="..."]
     *  [encoding="..."] var="..." ... -->
     */
    static apr_status_t handle_echo(include_ctx_t *ctx, ap_filter_t *f,
                                    apr_bucket_brigade *bb)
    {
        const char *encoding = "entity", *decoding = "none";
        request_rec *r = f->r;
        int error = 0;
    
        if (!ctx->argc) {
            ap_log_rerror(APLOG_MARK,
                          (ctx->flags & SSI_FLAG_PRINTING)
                              ? APLOG_ERR : APLOG_WARNING,
                          0, r, APLOGNO(01343)
                          "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;
        }
    
        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) {
                    char *last = NULL;
                    char *e, *d, *token;
    
                    echo_text = val;
    
                    d = apr_pstrdup(ctx->pool, decoding);
                    token = apr_strtok(d, ", \t", &last);
    
                    while (token) {
                        if (!ap_cstr_casecmp(token, "none")) {
                            /* do nothing */
                        }
                        else if (!ap_cstr_casecmp(token, "url")) {
                            char *buf = apr_pstrdup(ctx->pool, echo_text);
                            ap_unescape_url(buf);
                            echo_text = buf;
                        }
                        else if (!ap_cstr_casecmp(token, "urlencoded")) {
                            char *buf = apr_pstrdup(ctx->pool, echo_text);
                            ap_unescape_urlencoded(buf);
                            echo_text = buf;
                        }
                        else if (!ap_cstr_casecmp(token, "entity")) {
                            char *buf = apr_pstrdup(ctx->pool, echo_text);
                            decodehtml(buf);
                            echo_text = buf;
                        }
                        else if (!ap_cstr_casecmp(token, "base64")) {
                            echo_text = ap_pbase64decode(ctx->dpool, echo_text);
                        }
                        else {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01344) "unknown value "
                                          "\"%s\" to parameter \"decoding\" of tag echo in "
                                          "%s", token, r->filename);
                            SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                            error = 1;
                            break;
                        }
                        token = apr_strtok(NULL, ", \t", &last);
                    }
    
                    e = apr_pstrdup(ctx->pool, encoding);
                    token = apr_strtok(e, ", \t", &last);
    
                    while (token) {
                        if (!ap_cstr_casecmp(token, "none")) {
                            /* do nothing */
                        }
                        else if (!ap_cstr_casecmp(token, "url")) {
                            echo_text = ap_escape_uri(ctx->dpool, echo_text);
                        }
                        else if (!ap_cstr_casecmp(token, "urlencoded")) {
                            echo_text = ap_escape_urlencoded(ctx->dpool, echo_text);
                        }
                        else if (!ap_cstr_casecmp(token, "entity")) {
                            echo_text = ap_escape_html2(ctx->dpool, echo_text, 0);
                        }
                        else if (!ap_cstr_casecmp(token, "base64")) {
                            char *buf;
                            buf = ap_pbase64encode(ctx->dpool, (char *)echo_text);
                            echo_text = buf;
                        }
                        else {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01345) "unknown value "
                                          "\"%s\" to parameter \"encoding\" of tag echo in "
                                          "%s", token, r->filename);
                            SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                            error = 1;
                            break;
                        }
                        token = apr_strtok(NULL, ", \t", &last);
                    }
    
                    e_len = strlen(echo_text);
                }
                else {
                    echo_text = ctx->intern->undefined_echo;
                    e_len = ctx->intern->undefined_echo_len;
                }
    
                if (error) {
                    break;
                }
    
                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, "decoding")) {
                decoding = tag_val;
            }
            else if (!strcmp(tag, "encoding")) {
                encoding = tag_val;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01346) "unknown parameter "
                              "\"%s\" in tag echo of %s", tag, r->filename);
                SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                break;
            }
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * <!--#config [timefmt="..."] [sizefmt="..."] [errmsg="..."]
     *             [echomsg="..."] -->
     */
    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, APLOGNO(01347)
                          "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, APLOGNO(01348) "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, APLOGNO(01349) "unknown parameter "
                              "\"%s\" to tag config in %s", tag, r->filename);
                SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                break;
            }
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * <!--#fsize virtual|file="..." [virtual|file="..."] ... -->
     */
    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, APLOGNO(01350)
                          "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;
    }
    
    /*
     * <!--#flastmod virtual|file="..." [virtual|file="..."] ... -->
     */
    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, APLOGNO(01351)
                          "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;
    }
    
    /*
     * <!--#if expr="..." -->
     */
    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)
                          ? APLOGNO(01352) "too many arguments for if element in %s"
                          : APLOGNO(01353) "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, APLOGNO(01354) "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, APLOGNO(01355) "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));
    
        if (ctx->intern->legacy_expr)
            expr_ret = parse_expr(ctx, expr, &was_error);
        else
            expr_ret = parse_ap_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;
    }
    
    /*
     * <!--#elif expr="..." -->
     */
    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)
                          ? APLOGNO(01356) "too many arguments for if element in %s"
                          : APLOGNO(01357) "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, APLOGNO(01358) "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, APLOGNO(01359) "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;
        }
    
        if (ctx->intern->legacy_expr)
            expr_ret = parse_expr(ctx, expr, &was_error);
        else
            expr_ret = parse_ap_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;
    }
    
    /*
     * <!--#else -->
     */
    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, APLOGNO(01360)
                          "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;
    }
    
    /*
     * <!--#endif -->
     */
    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, APLOGNO(01361)
                          "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;
    }
    
    /*
     * <!--#set var="..." value="..." ... -->
     */
    static apr_status_t handle_set(include_ctx_t *ctx, ap_filter_t *f,
                                   apr_bucket_brigade *bb)
    {
        const char *encoding = "none", *decoding = "none";
        char *var = NULL;
        request_rec *r = f->r;
        request_rec *sub = r->main;
        apr_pool_t *p = r->pool;
        int error = 0;
    
        if (ctx->argc < 2) {
            ap_log_rerror(APLOG_MARK,
                          (ctx->flags & SSI_FLAG_PRINTING)
                              ? APLOG_ERR : APLOG_WARNING,
                          0, r,
                          APLOGNO(01362) "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_RAW);
    
            if (!tag || !tag_val) {
                break;
            }
    
            if (!strcmp(tag, "var")) {
                decodehtml(tag_val);
                var = ap_ssi_parse_string(ctx, tag_val, NULL, 0,
                                          SSI_EXPAND_DROP_NAME);
            }
            else if (!strcmp(tag, "decoding")) {
                decoding = tag_val;
            }
            else if (!strcmp(tag, "encoding")) {
                encoding = tag_val;
            }
            else if (!strcmp(tag, "value")) {
                char *parsed_string;
    
                if (!var) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01363) "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);
    
                if (parsed_string) {
                    char *last = NULL;
                    char *e, *d, *token;
    
                    d = apr_pstrdup(ctx->pool, decoding);
                    token = apr_strtok(d, ", \t", &last);
    
                    while (token) {
                        if (!ap_cstr_casecmp(token, "none")) {
                            /* do nothing */
                        }
                        else if (!ap_cstr_casecmp(token, "url")) {
                            char *buf = apr_pstrdup(ctx->pool, parsed_string);
                            ap_unescape_url(buf);
                            parsed_string = buf;
                        }
                        else if (!ap_cstr_casecmp(token, "urlencoded")) {
                            char *buf = apr_pstrdup(ctx->pool, parsed_string);
                            ap_unescape_urlencoded(buf);
                            parsed_string = buf;
                        }
                        else if (!ap_cstr_casecmp(token, "entity")) {
                            char *buf = apr_pstrdup(ctx->pool, parsed_string);
                            decodehtml(buf);
                            parsed_string = buf;
                        }
                        else if (!ap_cstr_casecmp(token, "base64")) {
                            parsed_string = ap_pbase64decode(ctx->dpool, parsed_string);
                        }
                        else {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01364) "unknown value "
                                          "\"%s\" to parameter \"decoding\" of tag set in "
                                          "%s", token, r->filename);
                            SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                            error = 1;
                            break;
                        }
                        token = apr_strtok(NULL, ", \t", &last);
                    }
    
                    e = apr_pstrdup(ctx->pool, encoding);
                    token = apr_strtok(e, ", \t", &last);
    
                    while (token) {
                        if (!ap_cstr_casecmp(token, "none")) {
                            /* do nothing */
                        }
                        else if (!ap_cstr_casecmp(token, "url")) {
                            parsed_string = ap_escape_uri(ctx->dpool, parsed_string);
                        }
                        else if (!ap_cstr_casecmp(token, "urlencoded")) {
                            parsed_string = ap_escape_urlencoded(ctx->dpool, parsed_string);
                        }
                        else if (!ap_cstr_casecmp(token, "entity")) {
                            parsed_string = ap_escape_html2(ctx->dpool, parsed_string, 0);
                        }
                        else if (!ap_cstr_casecmp(token, "base64")) {
                            char *buf;
                            buf = ap_pbase64encode(ctx->dpool, (char *)parsed_string);
                            parsed_string = buf;
                        }
                        else {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01365) "unknown value "
                                          "\"%s\" to parameter \"encoding\" of tag set in "
                                          "%s", token, r->filename);
                            SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                            error = 1;
                            break;
                        }
                        token = apr_strtok(NULL, ", \t", &last);
                    }
    
                }
    
                if (error) {
                    break;
                }
    
                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, APLOGNO(01366) "Invalid tag for set "
                              "directive in %s", r->filename);
                SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
                break;
            }
        }
    
        return APR_SUCCESS;
    }
    
    /*
     * <!--#printenv -->
     */
    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,
                          APLOGNO(01367) "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;
    
            /* get key */
            key_text = ap_escape_html(ctx->dpool, elts[i].key);
    
            /* get value */
            val_text = elts[i].val;
            if (val_text == LAZY_VALUE)
                val_text = add_include_vars_lazy(r, elts[i].key, ctx->time_str);
            val_text = ap_escape_html(ctx->dpool, val_text);
    
            apr_brigade_putstrs(bb, NULL, NULL, key_text, "=", val_text, "\n",
                                NULL);
        }
    
        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. <!--#printenv-->
                 */
                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, ctx->r, APLOGNO(01368) "missing "
                              "directive name in parsed document %s",
                              ctx->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, ctx->r, APLOGNO(01369) "missing "
                              "argument name for value to tag %s in %s",
                              apr_pstrmemdup(ctx->r->pool, intern->directive,
                                             intern->directive_len),
                                             ctx->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, ctx->r, APLOGNO(01370) "missing "
                              "argument name for value to tag %s in %s",
                              apr_pstrmemdup(ctx->r->pool, intern->directive,
                                             intern->directive_len),
                                             ctx->r->filename);
            }
            else {
                ap_str_tolower(intern->current_arg->name);
            }
    
            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;
        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 = NULL;
    
            /* 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 <!--#printenv--> 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_pmemdup(ctx->pool, 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_bucket_setaside(b, r->pool);
                        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_bucket_setaside(b, r->pool);
                        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_bucket_setaside(b, r->pool);
                    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, APLOGNO(01371)
                                      "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_pmemdup(ctx->pool, 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, APLOGNO(01372)
                              "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, APLOGNO(01373)
                              "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.
         */
        if (conf->etag <= 0) {
            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;
        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, APLOGNO(01374)
                          "mod_include: Options +Includes (or IncludesNoExec) "
                          "wasn't set, INCLUDES filter removed: %s", r->uri);
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, b);
        }
    
        if (!f->ctx) {
            struct ssi_internal_ctx *intern;
            include_ctx_t *ctx;
    
            /* create context for this filter */
            f->ctx = ctx = apr_palloc(r->pool, sizeof(*ctx));
            ctx->r = r;
            ctx->intern = intern = apr_palloc(r->pool, sizeof(*ctx->intern));
            ctx->pool = r->pool;
            apr_pool_create(&ctx->dpool, ctx->pool);
            apr_pool_tag(ctx->dpool, "includes_dpool");
    
            /* 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_INC_WITH_EXEC) == 0) {
                ctx->flags |= SSI_FLAG_NO_EXEC;
            }
            intern->legacy_expr = (conf->legacy_expr > 0);
            intern->expr_eval_ctx = NULL;
            intern->expr_err = NULL;
            intern->expr_vary_this = NULL;
    
            ctx->if_nesting_level = 0;
            intern->re = NULL;
    
            ctx->error_str = conf->default_error_msg ? conf->default_error_msg :
                             DEFAULT_ERROR_MSG;
            ctx->time_str = conf->default_time_fmt ? conf->default_time_fmt :
                            DEFAULT_TIME_FORMAT;
            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 ? conf->undefined_echo :
                                     DEFAULT_UNDEFINED_ECHO;
            intern->undefined_echo_len = strlen(intern->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 <!--#config timefmt -->.
             */
            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);
        }
        /* 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.
         *
         * SSILastModified on means we *should* set the Last-Modified field
         * if not present, or respect an existing value if present.
         */
    
        /* Must we respect the last modified header? By default, no */
        if (conf->lastmodified > 0) {
    
            /* update the last modified if we have a valid time, and only if
             * we don't already have a valid last modified.
             */
            if (r->finfo.valid & APR_FINFO_MTIME
                    && !apr_table_get(f->r->headers_out, "Last-Modified")) {
                ap_update_mtime(r, r->finfo.mtime);
                ap_set_last_modified(r);
            }
    
        }
    
        /* Assure the platform supports Group protections */
        else if (((conf->xbithack == XBITHACK_FULL ||
                   (conf->xbithack == XBITHACK_UNSET &&
                    DEFAULT_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)
    {
        if (r->handler && (strcmp(r->handler, "server-parsed") == 0))
        {
            if (!r->content_type || !*r->content_type) {
                ap_set_content_type_ex(r, "text/html", 1);
            }
            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
        {
            include_dir_config *conf = ap_get_module_config(r->per_dir_config,
                                                            &include_module);
    
            if (conf->xbithack == XBITHACK_OFF ||
                (DEFAULT_XBITHACK == XBITHACK_OFF &&
                 conf->xbithack == XBITHACK_UNSET))
            {
                return DECLINED;
            }
    
            if (!(r->finfo.protection & APR_UEXECUTE)) {
                return DECLINED;
            }
    
            if (!r->content_type || strncmp(r->content_type, "text/html", 9)) {
                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_pcalloc(p, sizeof(include_dir_config));
    
        result->xbithack          = XBITHACK_UNSET;
        result->lastmodified      = UNSET;
        result->etag              = UNSET;
        result->legacy_expr       = UNSET;
    
        return result;
    }
    
    #define MERGE(b,o,n,val,unset) n->val = o->val != unset  ? o->val : b->val
    static void *merge_includes_dir_config(apr_pool_t *p, void *basev, void *overridesv)
    {
        include_dir_config *base = (include_dir_config *)basev,
                           *over = (include_dir_config *)overridesv,
                           *new  = apr_palloc(p, sizeof(include_dir_config));
        MERGE(base, over, new, default_error_msg, NULL);
        MERGE(base, over, new, default_time_fmt,  NULL);
        MERGE(base, over, new, undefined_echo,    NULL);
        MERGE(base, over, new, xbithack,          XBITHACK_UNSET);
        MERGE(base, over, new, lastmodified,      UNSET);
        MERGE(base, over, new, etag,              UNSET);
        MERGE(base, over, new, legacy_expr,       UNSET);
        return new;
    }
    
    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("comment", handle_comment);
            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"),
        AP_INIT_FLAG("SSILegacyExprParser", ap_set_flag_slot_char,
                      (void *)APR_OFFSETOF(include_dir_config, legacy_expr),
                      OR_LIMIT,
                      "Whether to use the legacy expression parser compatible "
                      "with <= 2.2.x. Limited to 'on' or 'off'"),
        AP_INIT_FLAG("SSILastModified", ap_set_flag_slot_char,
                      (void *)APR_OFFSETOF(include_dir_config, lastmodified),
                      OR_LIMIT, "Whether to set the last modified header or respect "
                      "an existing header. Limited to 'on' or 'off'"),
        AP_INIT_FLAG("SSIEtag", ap_set_flag_slot_char,
                      (void *)APR_OFFSETOF(include_dir_config, etag),
                      OR_LIMIT, "Whether to allow the generation of ETags within the server. "
                      "Existing ETags will be preserved. Limited to 'on' or 'off'"),
        {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);
    }
    
    AP_DECLARE_MODULE(include) =
    {
        STANDARD20_MODULE_STUFF,
        create_includes_dir_config,   /* dir config creater */
        merge_includes_dir_config,    /* dir config merger */
        create_includes_server_config,/* server config */
        NULL,                         /* merge server config */
        includes_cmds,                /* command apr_table_t */
        register_hooks                /* register hooks */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_sed.c��������������������������������������������������������������0000664�0001751�0001751�00000043570�14245660240�017534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
     * Use is subject to license terms.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  http://www.apache.org/licenses/LICENSE-2.0.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "apr_strings.h"
    #include "apr_general.h"
    #include "util_filter.h"
    #include "apr_buckets.h"
    #include "http_request.h"
    #include "libsed.h"
    
    static const char *sed_filter_name = "Sed";
    #define MODSED_OUTBUF_SIZE 8000
    #define MAX_TRANSIENT_BUCKETS 50
    
    typedef struct sed_expr_config
    {
        sed_commands_t *sed_cmds;
        const char *last_error;
    } sed_expr_config;
    
    typedef struct sed_config
    {
        sed_expr_config output;
        sed_expr_config input;
    } sed_config;
    
    /* Context for filter invocation for single HTTP request */
    typedef struct sed_filter_ctxt
    {
        sed_eval_t eval;
        ap_filter_t *f;
        request_rec *r;
        apr_bucket_brigade *bb;
        apr_bucket_brigade *bbinp;
        char *outbuf;
        char *curoutbuf;
        apr_size_t bufsize;
        apr_pool_t *tpool;
        int numbuckets;
    } sed_filter_ctxt;
    
    module AP_MODULE_DECLARE_DATA sed_module;
    
    /* This function will be call back from libsed functions if there is any error
     * happened during execution of sed scripts
     */
    static apr_status_t log_sed_errf(void *data, const char *error)
    {
        request_rec *r = (request_rec *) data;
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02998) "%s", error);
        return APR_SUCCESS;
    }
    
    /* This function will be call back from libsed functions if there is any
     * compilation error.
     */
    static apr_status_t sed_compile_errf(void *data, const char *error)
    {
        sed_expr_config *sed_cfg = (sed_expr_config *) data;
        sed_cfg->last_error = error;
        return APR_SUCCESS;
    }
    
    /* clear the temporary pool (used for transient buckets)
     */
    static void clear_ctxpool(sed_filter_ctxt* ctx)
    {
        apr_pool_clear(ctx->tpool);
        ctx->outbuf = NULL;
        ctx->curoutbuf = NULL;
        ctx->numbuckets = 0;
    }
    
    /* alloc_outbuf
     * allocate output buffer
     */
    static void alloc_outbuf(sed_filter_ctxt* ctx)
    {
        ctx->outbuf = apr_palloc(ctx->tpool, ctx->bufsize + 1);
        ctx->curoutbuf = ctx->outbuf;
    }
    
    /* append_bucket
     * Allocate a new bucket from buf and sz and append to ctx->bb
     */
    static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, apr_size_t sz)
    {
        apr_status_t status = APR_SUCCESS;
        apr_bucket *b;
        if (ctx->tpool == ctx->r->pool) {
            /* We are not using transient bucket */
            b = apr_bucket_pool_create(buf, sz, ctx->r->pool,
                                       ctx->r->connection->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
        }
        else {
            /* We are using transient bucket */
            b = apr_bucket_transient_create(buf, sz,
                                            ctx->r->connection->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
            ctx->numbuckets++;
            if (ctx->numbuckets >= MAX_TRANSIENT_BUCKETS) {
                b = apr_bucket_flush_create(ctx->r->connection->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
                status = ap_pass_brigade(ctx->f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                clear_ctxpool(ctx);
            }
        }
        return status;
    }
    
    /*
     * flush_output_buffer
     * Flush the  output data (stored in ctx->outbuf)
     */
    static apr_status_t flush_output_buffer(sed_filter_ctxt *ctx)
    {
        apr_size_t size = ctx->curoutbuf - ctx->outbuf;
        char *out;
        apr_status_t status = APR_SUCCESS;
        if ((ctx->outbuf == NULL) || (size <=0))
            return status;
        out = apr_pmemdup(ctx->tpool, ctx->outbuf, size);
        status = append_bucket(ctx, out, size);
        ctx->curoutbuf = ctx->outbuf;
        return status;
    }
    
    /* This is a call back function. When libsed wants to generate the output,
     * this function will be invoked.
     */
    static apr_status_t sed_write_output(void *dummy, char *buf, apr_size_t sz)
    {
        /* dummy is basically filter context. Context is passed during invocation
         * of sed_eval_buffer
         */
        apr_size_t remainbytes = 0;
        apr_status_t status = APR_SUCCESS;
        sed_filter_ctxt *ctx = (sed_filter_ctxt *) dummy;
        if (ctx->outbuf == NULL) {
            alloc_outbuf(ctx);
        }
        remainbytes = ctx->bufsize - (ctx->curoutbuf - ctx->outbuf);
        if (sz >= remainbytes) {
            if (remainbytes > 0) {
                memcpy(ctx->curoutbuf, buf, remainbytes);
                buf += remainbytes;
                sz -= remainbytes;
                ctx->curoutbuf += remainbytes;
            }
            /* buffer is now full */
            status = append_bucket(ctx, ctx->outbuf, ctx->bufsize);
            if (status == APR_SUCCESS) {
                /* if size is bigger than the allocated buffer directly add to output
                 * brigade */
                if (sz >= ctx->bufsize) {
                    char* newbuf = apr_pmemdup(ctx->tpool, buf, sz);
                    status = append_bucket(ctx, newbuf, sz);
                    if (status == APR_SUCCESS) {
                        /* old buffer is now used so allocate new buffer */
                        alloc_outbuf(ctx);
                    }
                    else {
                        clear_ctxpool(ctx);
                    }
                }
                else {
                    /* old buffer is now used so allocate new buffer */
                    alloc_outbuf(ctx);
                    memcpy(ctx->curoutbuf, buf, sz);
                    ctx->curoutbuf += sz;
                }
            }
            else {
                clear_ctxpool(ctx);
            }
        }
        else {
            memcpy(ctx->curoutbuf, buf, sz);
            ctx->curoutbuf += sz;
        }
        return status;
    }
    
    /* Compile a sed expression. Compiled context is saved in sed_cfg->sed_cmds.
     * Memory required for compilation context is allocated from cmd->pool.
     */
    static apr_status_t compile_sed_expr(sed_expr_config *sed_cfg,
                                         cmd_parms *cmd,
                                         const char *expr)
    {
        apr_status_t status = APR_SUCCESS;
    
        if (!sed_cfg->sed_cmds) {
            sed_commands_t *sed_cmds;
            sed_cmds = apr_pcalloc(cmd->pool, sizeof(sed_commands_t));
            status = sed_init_commands(sed_cmds, sed_compile_errf, sed_cfg,
                                       cmd->pool);
            if (status != APR_SUCCESS) {
                sed_destroy_commands(sed_cmds);
                return status;
            }
            sed_cfg->sed_cmds = sed_cmds;
        }
        status = sed_compile_string(sed_cfg->sed_cmds, expr);
        if (status != APR_SUCCESS) {
            sed_destroy_commands(sed_cfg->sed_cmds);
            sed_cfg->sed_cmds = NULL;
        }
        return status;
    }
    
    /* sed eval cleanup function */
    static apr_status_t sed_eval_cleanup(void *data)
    {
        sed_eval_t *eval = (sed_eval_t *) data;
        sed_destroy_eval(eval);
        return APR_SUCCESS;
    }
    
    /* Initialize sed filter context. If successful then context is set in f->ctx
     */
    static apr_status_t init_context(ap_filter_t *f, sed_expr_config *sed_cfg, int usetpool)
    {
        apr_status_t status;
        sed_filter_ctxt* ctx;
        request_rec *r = f->r;
        /* Create the context. Call sed_init_eval. libsed will generated
         * output by calling sed_write_output and generates any error by
         * invoking log_sed_errf.
         */
        ctx = apr_pcalloc(r->pool, sizeof(sed_filter_ctxt));
        ctx->r = r;
        ctx->bb = NULL;
        ctx->numbuckets = 0;
        ctx->f = f;
        status = sed_init_eval(&ctx->eval, sed_cfg->sed_cmds, log_sed_errf,
                               r, &sed_write_output, r->pool);
        if (status != APR_SUCCESS) {
            return status;
        }
        apr_pool_cleanup_register(r->pool, &ctx->eval, sed_eval_cleanup,
                                  apr_pool_cleanup_null);
        ctx->bufsize = MODSED_OUTBUF_SIZE;
        if (usetpool) {
            apr_pool_create(&(ctx->tpool), r->pool);
            apr_pool_tag(ctx->tpool, "sed_tpool");
        }
        else {
            ctx->tpool = r->pool;
        }
        alloc_outbuf(ctx);
        f->ctx = ctx;
        return APR_SUCCESS;
    }
    
    /* Entry function for Sed output filter */
    static apr_status_t sed_response_filter(ap_filter_t *f,
                                            apr_bucket_brigade *bb)
    {
        apr_bucket *b;
        apr_status_t status = APR_SUCCESS;
        sed_config *cfg = ap_get_module_config(f->r->per_dir_config,
                                               &sed_module);
        sed_filter_ctxt *ctx = f->ctx;
        sed_expr_config *sed_cfg = &cfg->output;
    
        if ((sed_cfg == NULL) || (sed_cfg->sed_cmds == NULL)) {
            /* No sed expressions */
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, bb);
        }
    
        if (ctx == NULL) {
    
            if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
                /* no need to run sed filter for Head requests */
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            status = init_context(f, sed_cfg, 1);
            if (status != APR_SUCCESS)
                 return status;
            ctx = f->ctx;
            apr_table_unset(f->r->headers_out, "Content-Length");
    
            ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
        }
    
        /* Here is the main logic. Iterate through all the buckets, read the
         * content of the bucket, call sed_eval_buffer on the data.
         * sed_eval_buffer will read the data line by line, run filters on each
         * line. sed_eval_buffer will generates the output by calling
         * sed_write_output which will add the output to ctx->bb. At the end of
         * the loop, ctx->bb is passed to the next filter in chain. At the end of
         * the data, if new line is not found then sed_eval_buffer will store the
         * data in its own buffer.
         *
         * Once eos bucket is found then sed_finalize_eval will flush the rest of
         * the data. If there is no new line in last line of data, new line is
         * appended (that is a solaris sed behavior). libsed's internal memory for
         * evaluation is allocated on request's pool so it will be cleared once
         * request is over.
         *
         * If flush bucket is found then append the flush bucket to ctx->bb
         * and pass it to next filter. There may be some data which will still be
         * in sed's internal buffer which can't be flushed until new line
         * character is arrived.
         */
        while (!APR_BRIGADE_EMPTY(bb)) {
            b = APR_BRIGADE_FIRST(bb);
            if (APR_BUCKET_IS_EOS(b)) {
                /* Now clean up the internal sed buffer */
                sed_finalize_eval(&ctx->eval, ctx);
                status = flush_output_buffer(ctx);
                if (status != APR_SUCCESS) {
                    break;
                }
                /* Move the eos bucket to ctx->bb brigade */
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
            }
            else if (APR_BUCKET_IS_FLUSH(b)) {
                status = flush_output_buffer(ctx);
                if (status != APR_SUCCESS) {
                    break;
                }
                /* Move the flush bucket to ctx->bb brigade */
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
            }
            else {
                if (!APR_BUCKET_IS_METADATA(b)) {
                    const char *buf = NULL;
                    apr_size_t bytes = 0;
    
                    status = apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ);
                    if (status == APR_SUCCESS) {
                        status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
                    }
                    if (status != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10394) "error evaluating sed on output");
                        break;
                    }
                }
                apr_bucket_delete(b);
            }
        }
        if (status == APR_SUCCESS) {
            status = flush_output_buffer(ctx);
        }
        if (!APR_BRIGADE_EMPTY(ctx->bb)) {
            if (status == APR_SUCCESS) {
                status = ap_pass_brigade(f->next, ctx->bb);
            }
            apr_brigade_cleanup(ctx->bb);
        }
        clear_ctxpool(ctx);
        return status;
    }
    
    /* Entry function for Sed input filter */
    static apr_status_t sed_request_filter(ap_filter_t *f,
                                           apr_bucket_brigade *bb,
                                           ap_input_mode_t mode,
                                           apr_read_type_e block,
                                           apr_off_t readbytes)
    {
        sed_config *cfg = ap_get_module_config(f->r->per_dir_config,
                                               &sed_module);
        sed_filter_ctxt *ctx = f->ctx;
        apr_status_t status;
        apr_bucket_brigade *bbinp;
        sed_expr_config *sed_cfg = &cfg->input;
    
        if (mode != AP_MODE_READBYTES) {
            return ap_get_brigade(f->next, bb, mode, block, readbytes);
        }
    
        if ((sed_cfg == NULL) || (sed_cfg->sed_cmds == NULL)) {
            /* No sed expression */
            return ap_get_brigade(f->next, bb, mode, block, readbytes);
        }
    
        if (!ctx) {
            if (!ap_is_initial_req(f->r)) {
                ap_remove_input_filter(f);
                /* XXX : Should we filter the sub requests too */
                return ap_get_brigade(f->next, bb, mode, block, readbytes);
            }
            status = init_context(f, sed_cfg, 0);
            if (status != APR_SUCCESS)
                 return status;
            ctx = f->ctx;
            ctx->bb    = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
            ctx->bbinp = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
        }
    
        bbinp = ctx->bbinp;
    
        /* Here is the logic :
         * Read the readbytes data from next level fiter into bbinp. Loop through
         * the buckets in bbinp and read the data from buckets and invoke
         * sed_eval_buffer on the data. libsed will generate its output using
         * sed_write_output which will add data in ctx->bb. Do it until it have
         * at least one bucket in ctx->bb. At the end of data eos bucket
         * should be there.
         *
         * Once eos bucket is seen, then invoke sed_finalize_eval to clear the
         * output. If the last byte of data is not a new line character then sed
         * will add a new line to the data that is default sed behaviour. Note
         * that using this filter with POST data, caller may not expect this
         * behaviour.
         *
         * If next level fiter generate the flush bucket, we can't do much about
         * it. If we want to return the flush bucket in brigade bb (to the caller)
         * the question is where to add it?
         */
        while (APR_BRIGADE_EMPTY(ctx->bb)) {
            apr_bucket *b;
    
            /* read the bytes from next level filter */
            apr_brigade_cleanup(bbinp);
            status = ap_get_brigade(f->next, bbinp, mode, block, readbytes);
            if (status != APR_SUCCESS) {
                return status;
            }
            for (b = APR_BRIGADE_FIRST(bbinp); b != APR_BRIGADE_SENTINEL(bbinp);
                 b = APR_BUCKET_NEXT(b)) {
                const char *buf = NULL;
                apr_size_t bytes;
    
                if (APR_BUCKET_IS_EOS(b)) {
                    /* eos bucket. Clear the internal sed buffers */
                    sed_finalize_eval(&ctx->eval, ctx);
                    flush_output_buffer(ctx);
                    APR_BUCKET_REMOVE(b);
                    APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
                    break;
                }
                else if (APR_BUCKET_IS_FLUSH(b)) {
                    /* What should we do with flush bucket */
                    continue;
                }
                if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
                         == APR_SUCCESS) {
                    status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
                    if (status != APR_SUCCESS) { 
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10395) "error evaluating sed on input");
                        return status;
                    }
                    flush_output_buffer(ctx);
                }
            }
        }
    
        if (!APR_BRIGADE_EMPTY(ctx->bb)) {
            apr_bucket *b = NULL;
    
            if (apr_brigade_partition(ctx->bb, readbytes, &b) == APR_INCOMPLETE) {
                APR_BRIGADE_CONCAT(bb, ctx->bb);
            }
            else {
                APR_BRIGADE_CONCAT(bb, ctx->bb);
                apr_brigade_split_ex(bb, b, ctx->bb);
            }
        }
        return APR_SUCCESS;
    }
    
    static const char *sed_add_expr(cmd_parms *cmd, void *cfg, const char *arg)
    {
        int offset = (int) (long) cmd->info;
        sed_expr_config *sed_cfg =
                    (sed_expr_config *) (((char *) cfg) + offset);
        if (compile_sed_expr(sed_cfg, cmd, arg) != APR_SUCCESS) {
            return apr_psprintf(cmd->temp_pool,
                                "Failed to compile sed expression. %s",
                                sed_cfg->last_error);
        }
        return NULL;
    }
    
    static void *create_sed_dir_config(apr_pool_t *p, char *s)
    {
        sed_config *cfg = apr_pcalloc(p, sizeof(sed_config));
        return cfg;
    }
    
    static const command_rec sed_filter_cmds[] = {
        AP_INIT_TAKE1("OutputSed", sed_add_expr,
                      (void *) APR_OFFSETOF(sed_config, output),
                      ACCESS_CONF,
                      "Sed regular expression for Response"),
        AP_INIT_TAKE1("InputSed", sed_add_expr,
                      (void *) APR_OFFSETOF(sed_config, input),
                      ACCESS_CONF,
                      "Sed regular expression for Request"),
        {NULL}
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_output_filter(sed_filter_name, sed_response_filter, NULL,
                                  AP_FTYPE_RESOURCE);
        ap_register_input_filter(sed_filter_name, sed_request_filter, NULL,
                                 AP_FTYPE_RESOURCE);
    }
    
    AP_DECLARE_MODULE(sed) = {
        STANDARD20_MODULE_STUFF,
        create_sed_dir_config,      /* dir config creater */
        NULL,                       /* dir merger --- default is to override */
        NULL,                       /* server config */
        NULL,                       /* merge server config */
        sed_filter_cmds,            /* command table */
        register_hooks              /* register hooks */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_request.c����������������������������������������������������������0000664�0001751�0001751�00000032267�14110270207�020441� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_request.c --- HTTP routines to set aside or process request bodies.
     */
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_buckets.h"
    #include "apr_lib.h"
    
    #include "ap_config.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "http_protocol.h"
    #include "http_log.h"           /* For errors detected in basic auth common
                                     * support code... */
    #include "http_request.h"
    
    #include "mod_request.h"
    
    /* Handles for core filters */
    static ap_filter_rec_t *keep_body_input_filter_handle;
    static ap_filter_rec_t *kept_body_input_filter_handle;
    
    static apr_status_t bail_out_on_error(apr_bucket_brigade *bb,
                                          ap_filter_t *f,
                                          int http_error)
    {
        apr_bucket *e;
    
        apr_brigade_cleanup(bb);
        e = ap_bucket_error_create(http_error,
                                   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);
        return ap_pass_brigade(f->r->output_filters, bb);
    }
    
    typedef struct keep_body_filter_ctx {
        apr_off_t remaining;
        apr_off_t keep_body;
    } keep_body_ctx_t;
    
    /**
     * This is the KEEP_BODY_INPUT filter for HTTP requests, for times when the
     * body should be set aside for future use by other modules.
     */
    static apr_status_t keep_body_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;
        keep_body_ctx_t *ctx = f->ctx;
        apr_status_t rv;
        apr_bucket *bucket;
        apr_off_t len = 0;
    
        if (!ctx) {
            const char *lenp;
            request_dir_conf *dconf = ap_get_module_config(f->r->per_dir_config,
                                                           &request_module);
    
            /* must we step out of the way? */
            if (!dconf->keep_body || f->r->kept_body) {
                ap_remove_input_filter(f);
                return ap_get_brigade(f->next, b, mode, block, readbytes);
            }
    
            f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
    
            /* fail fast if the content length exceeds keep body */
            lenp = apr_table_get(f->r->headers_in, "Content-Length");
            if (lenp) {
    
                /* Protects against over/underflow, non-digit chars in the
                 * string, leading plus/minus signs, trailing characters and
                 * a negative number.
                 */
                if (!ap_parse_strict_length(&ctx->remaining, lenp)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(01411)
                                  "Invalid Content-Length '%s'", lenp);
    
                    ap_remove_input_filter(f);
                    return bail_out_on_error(b, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
                }
    
                /* If we have a limit in effect and we know the C-L ahead of
                 * time, stop it here if it is invalid.
                 */
                if (dconf->keep_body < ctx->remaining) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(01412)
                              "Requested content-length of %" APR_OFF_T_FMT
                              " is larger than the configured limit"
                              " of %" APR_OFF_T_FMT, ctx->remaining, dconf->keep_body);
                    ap_remove_input_filter(f);
                    return bail_out_on_error(b, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
                }
    
            }
    
            f->r->kept_body = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc);
            ctx->remaining = dconf->keep_body;
        }
    
        /* get the brigade from upstream, and read it in to get its length */
        rv = ap_get_brigade(f->next, b, mode, block, readbytes);
        if (rv == APR_SUCCESS) {
            rv = apr_brigade_length(b, 1, &len);
        }
    
        /* does the length take us over the limit? */
        if (APR_SUCCESS == rv && len > ctx->remaining) {
            if (f->r->kept_body) {
                apr_brigade_cleanup(f->r->kept_body);
                f->r->kept_body = NULL;
            }
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(01413)
                          "Requested content-length of %" APR_OFF_T_FMT
                          " is larger than the configured limit"
                          " of %" APR_OFF_T_FMT, len, ctx->keep_body);
            return bail_out_on_error(b, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
        }
        ctx->remaining -= len;
    
        /* pass any errors downstream */
        if (rv != APR_SUCCESS) {
            if (f->r->kept_body) {
                apr_brigade_cleanup(f->r->kept_body);
                f->r->kept_body = NULL;
            }
            return rv;
        }
    
        /* all is well, set aside the buckets */
        for (bucket = APR_BRIGADE_FIRST(b);
             bucket != APR_BRIGADE_SENTINEL(b);
             bucket = APR_BUCKET_NEXT(bucket))
        {
            apr_bucket_copy(bucket, &e);
            APR_BRIGADE_INSERT_TAIL(f->r->kept_body, e);
        }
    
        return APR_SUCCESS;
    }
    
    
    typedef struct kept_body_filter_ctx {
        apr_off_t offset;
        apr_off_t remaining;
    } kept_body_ctx_t;
    
    /**
     * Initialisation of filter to handle a kept body on subrequests.
     *
     * If a body is to be reinserted into a subrequest, any chunking will have
     * been removed from the body during storage. We need to change the request
     * from Transfer-Encoding: chunked to an explicit Content-Length.
     */
    static int kept_body_filter_init(ap_filter_t *f)
    {
        apr_off_t length = 0;
        request_rec *r = f->r;
        apr_bucket_brigade *kept_body = r->kept_body;
    
        if (kept_body) {
            apr_table_unset(r->headers_in, "Transfer-Encoding");
            apr_brigade_length(kept_body, 1, &length);
            apr_table_setn(r->headers_in, "Content-Length", apr_off_t_toa(r->pool, length));
        }
    
        return OK;
    }
    
    /**
     * Filter to handle a kept body on subrequests.
     *
     * If a body has been previously kept by the request, and if a subrequest wants
     * to re-insert the body into the request, this input filter makes it happen.
     */
    static apr_status_t kept_body_filter(ap_filter_t *f, apr_bucket_brigade *b,
                                         ap_input_mode_t mode,
                                         apr_read_type_e block,
                                         apr_off_t readbytes)
    {
        request_rec *r = f->r;
        apr_bucket_brigade *kept_body = r->kept_body;
        kept_body_ctx_t *ctx = f->ctx;
        apr_bucket *ec, *e2;
        apr_status_t rv;
    
        /* just get out of the way of things we don't want. */
        if (!kept_body || (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE)) {
            return ap_get_brigade(f->next, b, mode, block, readbytes);
        }
    
        /* set up the context if it does not already exist */
        if (!ctx) {
            f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx));
            ctx->offset = 0;
            apr_brigade_length(kept_body, 1, &ctx->remaining);
        }
    
        /* kept_body is finished, send next filter */
        if (ctx->remaining <= 0) {
            return ap_get_brigade(f->next, b, mode, block, readbytes);
        }
    
        /* send all of the kept_body, but no more */
        if (readbytes > ctx->remaining) {
            readbytes = ctx->remaining;
        }
    
        /* send part of the kept_body */
        if ((rv = apr_brigade_partition(kept_body, ctx->offset, &ec)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01414)
                          "apr_brigade_partition() failed on kept_body at %" APR_OFF_T_FMT, ctx->offset);
            return rv;
        }
        if ((rv = apr_brigade_partition(kept_body, ctx->offset + readbytes, &e2)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01415)
                          "apr_brigade_partition() failed on kept_body at %" APR_OFF_T_FMT, ctx->offset + readbytes);
            return rv;
        }
    
        do {
            apr_bucket *foo;
            const char *str;
            apr_size_t len;
    
            if (apr_bucket_copy(ec, &foo) != APR_SUCCESS) {
                /* As above; this should not fail since the bucket has
                 * a known length, but just to be sure, 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(b, foo);
            ec = APR_BUCKET_NEXT(ec);
        } while (ec != e2);
    
        ctx->remaining -= readbytes;
        ctx->offset += readbytes;
    
        return APR_SUCCESS;
    }
    
    /**
     * Check whether this filter is not already present.
     */
    static int request_is_filter_present(request_rec * r, ap_filter_rec_t *fn)
    {
        ap_filter_t * f = r->input_filters;
        while (f) {
            if (f->frec == fn) {
                return 1;
            }
            f = f->next;
        }
        return 0;
    }
    
    /**
     * Insert filter hook.
     *
     * Add the KEEP_BODY filter to the request, if the admin wants to keep
     * the body using the KeptBodySize directive.
     *
     * As a precaution, any pre-existing instances of either the kept_body or
     * keep_body filters will be removed before the filter is added.
     *
     * @param r The request
     */
    static void ap_request_insert_filter(request_rec * r)
    {
        request_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &request_module);
    
        if (r->kept_body) {
            if (!request_is_filter_present(r, kept_body_input_filter_handle)) {
                ap_add_input_filter_handle(kept_body_input_filter_handle,
                                           NULL, r, r->connection);
            }
        }
        else if (conf->keep_body) {
            if (!request_is_filter_present(r, kept_body_input_filter_handle)) {
                ap_add_input_filter_handle(keep_body_input_filter_handle,
                                           NULL, r, r->connection);
            }
        }
    }
    
    /*
     * Remove the kept_body and keep_body filters from this specific request.
     */
    static void ap_request_remove_filter(request_rec *r)
    {
        ap_filter_t *f = r->input_filters;
    
        while (f) {
            if (f->frec->filter_func.in_func == kept_body_filter ||
                f->frec->filter_func.in_func == keep_body_filter) {
                ap_remove_input_filter(f);
            }
            f = f->next;
        }
    }
    
    static void *create_request_dir_config(apr_pool_t *p, char *dummy)
    {
        request_dir_conf *new =
            (request_dir_conf *) apr_pcalloc(p, sizeof(request_dir_conf));
    
        new->keep_body_set = 0; /* unset */
        new->keep_body = 0; /* don't by default */
    
        return (void *) new;
    }
    
    static void *merge_request_dir_config(apr_pool_t *p, void *basev, void *addv)
    {
        request_dir_conf *new = (request_dir_conf *) apr_pcalloc(p, sizeof(request_dir_conf));
        request_dir_conf *add = (request_dir_conf *) addv;
        request_dir_conf *base = (request_dir_conf *) basev;
    
        new->keep_body = (add->keep_body_set == 0) ? base->keep_body : add->keep_body;
        new->keep_body_set = add->keep_body_set || base->keep_body_set;
    
        return new;
    }
    
    static const char *set_kept_body_size(cmd_parms *cmd, void *dconf,
                                          const char *arg)
    {
        request_dir_conf *conf = dconf;
        char *end = NULL;
    
        if (APR_SUCCESS != apr_strtoff(&(conf->keep_body), arg, &end, 10)
                || conf->keep_body < 0 || *end) {
            return "KeptBodySize must be a valid size in bytes, or zero.";
        }
        conf->keep_body_set = 1;
    
        return NULL;
    }
    
    static const command_rec request_cmds[] = {
        AP_INIT_TAKE1("KeptBodySize", set_kept_body_size, NULL, ACCESS_CONF,
                      "Maximum size of request bodies kept aside for use by filters"),
        { NULL }
    };
    
    static void register_hooks(apr_pool_t *p)
    {
        keep_body_input_filter_handle =
            ap_register_input_filter(KEEP_BODY_FILTER, keep_body_filter,
                                     NULL, AP_FTYPE_RESOURCE);
        kept_body_input_filter_handle =
            ap_register_input_filter(KEPT_BODY_FILTER, kept_body_filter,
                                     kept_body_filter_init, AP_FTYPE_RESOURCE);
        ap_hook_insert_filter(ap_request_insert_filter, NULL, NULL, APR_HOOK_LAST);
        APR_REGISTER_OPTIONAL_FN(ap_request_insert_filter);
        APR_REGISTER_OPTIONAL_FN(ap_request_remove_filter);
    }
    
    AP_DECLARE_MODULE(request) = {
        STANDARD20_MODULE_STUFF,
        create_request_dir_config, /* create per-directory config structure */
        merge_request_dir_config,  /* merge per-directory config structures */
        NULL,                      /* create per-server config structure */
        NULL,                      /* merge per-server config structures */
        request_cmds,              /* command apr_table_t */
        register_hooks             /* register hooks */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reqtimeout.c�������������������������������������������������������0000664�0001751�0001751�00000052414�13650305431�021151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_request.h"
    #include "http_connection.h"
    #include "http_protocol.h"
    #include "http_log.h"
    #include "http_core.h"
    #include "util_filter.h"
    #define APR_WANT_STRFUNC
    #include "apr_strings.h"
    #include "apr_version.h"
    
    module AP_MODULE_DECLARE_DATA reqtimeout_module;
    
    #define UNSET                            -1
    #define MRT_DEFAULT_handshake_TIMEOUT     0 /* disabled */
    #define MRT_DEFAULT_handshake_MAX_TIMEOUT 0
    #define MRT_DEFAULT_handshake_MIN_RATE    0
    #define MRT_DEFAULT_header_TIMEOUT       20
    #define MRT_DEFAULT_header_MAX_TIMEOUT   40
    #define MRT_DEFAULT_header_MIN_RATE      500
    #define MRT_DEFAULT_body_TIMEOUT         20
    #define MRT_DEFAULT_body_MAX_TIMEOUT     0
    #define MRT_DEFAULT_body_MIN_RATE        500
    
    typedef struct
    {
        int timeout;            /* timeout in secs */
        int max_timeout;        /* max timeout in secs */
        int min_rate;           /* min rate in bytes/s */
        apr_time_t rate_factor; /* scale factor (#usecs per min_rate) */
    } reqtimeout_stage_t;
    
    typedef struct
    {
        reqtimeout_stage_t handshake;   /* Handshaking (TLS) */
        reqtimeout_stage_t header;      /* Reading the HTTP header */
        reqtimeout_stage_t body;        /* Reading the HTTP body */
    } reqtimeout_srv_cfg;
    
    /* this struct is used both as conn_config and as filter context */
    typedef struct
    {
        apr_time_t timeout_at;
        apr_time_t max_timeout_at;
        reqtimeout_stage_t cur_stage;
        int in_keep_alive;
        char *type;
        apr_socket_t *socket;
        apr_bucket_brigade *tmpbb;
    } reqtimeout_con_cfg;
    
    static const char *const reqtimeout_filter_name = "reqtimeout";
    static int default_handshake_rate_factor;
    static int default_header_rate_factor;
    static int default_body_rate_factor;
    
    static void extend_timeout(reqtimeout_con_cfg *ccfg, apr_bucket_brigade *bb)
    {
        apr_off_t len;
        apr_time_t new_timeout_at;
    
        if (apr_brigade_length(bb, 0, &len) != APR_SUCCESS || len <= 0)
            return;
    
        new_timeout_at = ccfg->timeout_at + len * ccfg->cur_stage.rate_factor;
        if (ccfg->max_timeout_at > 0 && new_timeout_at > ccfg->max_timeout_at) {
            ccfg->timeout_at = ccfg->max_timeout_at;
        }
        else {
            ccfg->timeout_at = new_timeout_at;
        }
    }
    
    static apr_status_t check_time_left(reqtimeout_con_cfg *ccfg,
                                        apr_time_t *time_left_p,
                                        apr_time_t now)
    {
        if (!now)
            now = apr_time_now();
        *time_left_p = ccfg->timeout_at - now;
        if (*time_left_p <= 0)
            return APR_TIMEUP;
    
        if (*time_left_p < apr_time_from_sec(1)) {
            *time_left_p = apr_time_from_sec(1);
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t have_lf_or_eos(apr_bucket_brigade *bb)
    {
        apr_bucket *b = APR_BRIGADE_LAST(bb);
    
        for ( ; b != APR_BRIGADE_SENTINEL(bb) ; b = APR_BUCKET_PREV(b) ) {
            const char *str;
            apr_size_t len;
            apr_status_t rv;
    
            if (APR_BUCKET_IS_EOS(b))
                return APR_SUCCESS;
    
            if (APR_BUCKET_IS_METADATA(b))
                continue;
    
            rv = apr_bucket_read(b, &str, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS)
                return rv;
    
            if (len == 0)
                continue;
    
            if (str[len-1] == APR_ASCII_LF)
                return APR_SUCCESS;
        }
        return APR_INCOMPLETE;
    }
    
    /*
     * Append bbIn to bbOut and merge small buckets, to avoid DoS by high memory
     * usage
     */
    static apr_status_t brigade_append(apr_bucket_brigade *bbOut, apr_bucket_brigade *bbIn)
    {
        while (!APR_BRIGADE_EMPTY(bbIn)) {
            apr_bucket *e = APR_BRIGADE_FIRST(bbIn);
            const char *str;
            apr_size_t len;
            apr_status_t rv;
    
            rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                return rv;
            }
    
            APR_BUCKET_REMOVE(e);
            if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) {
                APR_BRIGADE_INSERT_TAIL(bbOut, e);
            }
            else {
                if (len > 0) {
                    rv = apr_brigade_write(bbOut, NULL, NULL, str, len);
                    if (rv != APR_SUCCESS) {
                        apr_bucket_destroy(e);
                        return rv;
                    }
                }
                apr_bucket_destroy(e);
            }
        }
        return APR_SUCCESS;
    }
    
    
    #define MIN(x,y) ((x) < (y) ? (x) : (y))
    static apr_status_t reqtimeout_filter(ap_filter_t *f,
                                          apr_bucket_brigade *bb,
                                          ap_input_mode_t mode,
                                          apr_read_type_e block,
                                          apr_off_t readbytes)
    {
        apr_time_t time_left;
        apr_time_t now = 0;
        apr_status_t rv;
        apr_interval_time_t saved_sock_timeout = UNSET;
        reqtimeout_con_cfg *ccfg = f->ctx;
    
        if (ccfg->in_keep_alive) {
            /* For this read[_request line()], wait for the first byte using the
             * normal keep-alive timeout (hence don't take this expected idle time
             * into account to setup the connection expiry below).
             */
            ccfg->in_keep_alive = 0;
            rv = ap_get_brigade(f->next, bb, AP_MODE_SPECULATIVE, block, 1);
            if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
                return rv;
            }
            apr_brigade_cleanup(bb);
        }
    
        if (ccfg->cur_stage.timeout > 0) {
            /* set new timeout */
            now = apr_time_now();
            ccfg->timeout_at = now + apr_time_from_sec(ccfg->cur_stage.timeout);
            ccfg->cur_stage.timeout = 0;
            if (ccfg->cur_stage.max_timeout > 0) {
                ccfg->max_timeout_at = now + apr_time_from_sec(ccfg->cur_stage.max_timeout);
                ccfg->cur_stage.max_timeout = 0;
            }
        }
        else if (ccfg->timeout_at == 0) {
            /* no timeout set, or in between requests */
            return ap_get_brigade(f->next, bb, mode, block, readbytes);
        }
    
        if (!ccfg->socket) {
            ccfg->socket = ap_get_conn_socket(f->c);
        }
    
        rv = check_time_left(ccfg, &time_left, now);
        if (rv != APR_SUCCESS)
            goto out;
    
        if (block == APR_NONBLOCK_READ || mode == AP_MODE_INIT
            || mode == AP_MODE_EATCRLF) {
            rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
            if (ccfg->cur_stage.rate_factor && rv == APR_SUCCESS) {
                extend_timeout(ccfg, bb);
            }
            return rv;
        }
    
        rv = apr_socket_timeout_get(ccfg->socket, &saved_sock_timeout);
        AP_DEBUG_ASSERT(rv == APR_SUCCESS);
    
        rv = apr_socket_timeout_set(ccfg->socket, MIN(time_left, saved_sock_timeout));
        AP_DEBUG_ASSERT(rv == APR_SUCCESS);
    
        if (mode == AP_MODE_GETLINE) {
            /*
             * For a blocking AP_MODE_GETLINE read, apr_brigade_split_line()
             * would loop until a whole line has been read. As this would make it
             * impossible to enforce a total timeout, we only do non-blocking
             * reads.
             */
            apr_off_t remaining = HUGE_STRING_LEN;
            do {
                apr_off_t bblen;
    #if APR_MAJOR_VERSION < 2
                apr_int32_t nsds;
                apr_interval_time_t poll_timeout;
                apr_pollfd_t pollset;
    #endif
    
                rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, APR_NONBLOCK_READ, remaining);
                if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
                    break;
                }
    
                if (!APR_BRIGADE_EMPTY(bb)) {
                    if (ccfg->cur_stage.rate_factor) {
                        extend_timeout(ccfg, bb);
                    }
    
                    rv = have_lf_or_eos(bb);
                    if (rv != APR_INCOMPLETE) {
                        break;
                    }
    
                    rv = apr_brigade_length(bb, 1, &bblen);
                    if (rv != APR_SUCCESS) {
                        break;
                    }
                    remaining -= bblen;
                    if (remaining <= 0) {
                        break;
                    }
    
                    /* Haven't got a whole line yet, save what we have ... */
                    if (!ccfg->tmpbb) {
                        ccfg->tmpbb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
                    }
                    rv = brigade_append(ccfg->tmpbb, bb);
                    if (rv != APR_SUCCESS)
                        break;
                }
    
                /* ... and wait for more */
    #if APR_MAJOR_VERSION < 2
                pollset.p = f->c->pool;
                pollset.desc_type = APR_POLL_SOCKET;
                pollset.reqevents = APR_POLLIN|APR_POLLHUP;
                pollset.desc.s = ccfg->socket;
                apr_socket_timeout_get(ccfg->socket, &poll_timeout);
                rv = apr_poll(&pollset, 1, &nsds, poll_timeout);
    #else
                rv = apr_socket_wait(ccfg->socket, APR_WAIT_READ);
    #endif
                if (rv != APR_SUCCESS)
                    break;
    
                rv = check_time_left(ccfg, &time_left, 0);
                if (rv != APR_SUCCESS)
                    break;
    
                rv = apr_socket_timeout_set(ccfg->socket,
                                       MIN(time_left, saved_sock_timeout));
                AP_DEBUG_ASSERT(rv == APR_SUCCESS);
    
            } while (1);
    
            if (ccfg->tmpbb)
                APR_BRIGADE_PREPEND(bb, ccfg->tmpbb);
    
        }
        else { /* mode != AP_MODE_GETLINE */
            rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
            /* Don't extend the timeout in speculative mode, wait for
             * the real (relevant) bytes to be asked later, within the
             * currently allotted time.
             */
            if (ccfg->cur_stage.rate_factor && rv == APR_SUCCESS
                    && mode != AP_MODE_SPECULATIVE) {
                extend_timeout(ccfg, bb);
            }
        }
    
        apr_socket_timeout_set(ccfg->socket, saved_sock_timeout);
    
    out:
        if (APR_STATUS_IS_TIMEUP(rv)) {
            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, APLOGNO(01382)
                          "Request %s read timeout", ccfg->type);
            /*
             * If we allow a normal lingering close, the client may keep this
             * process/thread busy for another 30s (MAX_SECS_TO_LINGER).
             * Therefore we tell ap_lingering_close() to shorten this period to
             * 2s (SECONDS_TO_LINGER).
             */
            apr_table_setn(f->c->notes, "short-lingering-close", "1");
    
            /*
             * Also, we must not allow keep-alive requests, as
             * ap_finalize_protocol() may ignore our error status (if the timeout
             * happened on a request body that is discarded).
             */
            f->c->keepalive = AP_CONN_CLOSE;
        }
        return rv;
    }
    
    static apr_status_t reqtimeout_eor(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        if (!APR_BRIGADE_EMPTY(bb) && AP_BUCKET_IS_EOR(APR_BRIGADE_LAST(bb))) {
            reqtimeout_con_cfg *ccfg = f->ctx;
            ccfg->timeout_at = 0;
        }
        return ap_pass_brigade(f->next, bb);
    }
    
    #define INIT_STAGE(cfg, ccfg, stage) do { \
        if (cfg->stage.timeout != UNSET) { \
            ccfg->cur_stage.timeout     = cfg->stage.timeout; \
            ccfg->cur_stage.max_timeout = cfg->stage.max_timeout; \
            ccfg->cur_stage.rate_factor = cfg->stage.rate_factor; \
        } \
        else { \
            ccfg->cur_stage.timeout     = MRT_DEFAULT_##stage##_TIMEOUT; \
            ccfg->cur_stage.max_timeout = MRT_DEFAULT_##stage##_MAX_TIMEOUT; \
            ccfg->cur_stage.rate_factor = default_##stage##_rate_factor; \
        } \
    } while (0)
    
    static int reqtimeout_init(conn_rec *c)
    {
        reqtimeout_con_cfg *ccfg;
        reqtimeout_srv_cfg *cfg;
    
        cfg = ap_get_module_config(c->base_server->module_config,
                                   &reqtimeout_module);
        AP_DEBUG_ASSERT(cfg != NULL);
    
        /* For compatibility, handshake timeout is disabled when UNSET (< 0) */
        if (cfg->handshake.timeout <= 0
                && cfg->header.timeout == 0
                && cfg->body.timeout == 0) {
            /* disabled for this vhost */
            return DECLINED;
        }
    
        ccfg = ap_get_module_config(c->conn_config, &reqtimeout_module);
        if (ccfg == NULL) {
            ccfg = apr_pcalloc(c->pool, sizeof(reqtimeout_con_cfg));
            ap_set_module_config(c->conn_config, &reqtimeout_module, ccfg);
            ap_add_output_filter(reqtimeout_filter_name, ccfg, NULL, c);
            ap_add_input_filter(reqtimeout_filter_name, ccfg, NULL, c);
    
            ccfg->type = "handshake";
            if (cfg->handshake.timeout > 0) {
                INIT_STAGE(cfg, ccfg, handshake);
            }
        }
    
        /* we are not handling the connection, we just do initialization */
        return DECLINED;
    }
    
    static void reqtimeout_before_header(request_rec *r, conn_rec *c)
    {
        reqtimeout_srv_cfg *cfg;
        reqtimeout_con_cfg *ccfg =
            ap_get_module_config(c->conn_config, &reqtimeout_module);
    
        if (ccfg == NULL) {
            /* not configured for this connection */
            return;
        }
    
        cfg = ap_get_module_config(c->base_server->module_config,
                                   &reqtimeout_module);
        AP_DEBUG_ASSERT(cfg != NULL);
    
        /* (Re)set the state for this new request, but ccfg->socket and
         * ccfg->tmpbb which have the lifetime of the connection.
         */
        ccfg->type = "header";
        ccfg->timeout_at = 0;
        ccfg->max_timeout_at = 0;
        ccfg->in_keep_alive = (c->keepalives > 0);
        INIT_STAGE(cfg, ccfg, header);
    }
    
    static int reqtimeout_before_body(request_rec *r)
    {
        reqtimeout_srv_cfg *cfg;
        reqtimeout_con_cfg *ccfg =
            ap_get_module_config(r->connection->conn_config, &reqtimeout_module);
    
        if (ccfg == NULL) {
            /* not configured for this connection */
            return OK;
        }
        cfg = ap_get_module_config(r->server->module_config,
                                  &reqtimeout_module);
        AP_DEBUG_ASSERT(cfg != NULL);
    
        ccfg->type = "body";
        ccfg->timeout_at = 0;
        ccfg->max_timeout_at = 0;
        if (r->method_number == M_CONNECT) {
            /* disabled for a CONNECT request */
            ccfg->cur_stage.timeout = 0;
        }
        else {
            INIT_STAGE(cfg, ccfg, body);
        }
        return OK;
    }
    
    #define UNSET_STAGE(cfg, stage) do { \
        cfg->stage.timeout = UNSET; \
        cfg->stage.max_timeout = UNSET; \
        cfg->stage.min_rate = UNSET; \
    } while (0)
    
    static void *reqtimeout_create_srv_config(apr_pool_t *p, server_rec *s)
    {
        reqtimeout_srv_cfg *cfg = apr_pcalloc(p, sizeof(reqtimeout_srv_cfg));
    
        UNSET_STAGE(cfg, handshake);
        UNSET_STAGE(cfg, header);
        UNSET_STAGE(cfg, body);
    
        return cfg;
    }
    
    #define MERGE_INT(cfg, base, add, val) \
        cfg->val = (add->val == UNSET) ? base->val : add->val
    #define MERGE_STAGE(cfg, base, add, stage) do { \
        MERGE_INT(cfg, base, add, stage.timeout); \
        MERGE_INT(cfg, base, add, stage.max_timeout); \
        MERGE_INT(cfg, base, add, stage.min_rate); \
        cfg->stage.rate_factor = (cfg->stage.min_rate == UNSET) \
                                 ? base->stage.rate_factor \
                                 : add->stage.rate_factor; \
    } while (0)
    
    static void *reqtimeout_merge_srv_config(apr_pool_t *p, void *base_, void *add_)
    {
        reqtimeout_srv_cfg *base = base_;
        reqtimeout_srv_cfg *add  = add_;
        reqtimeout_srv_cfg *cfg  = apr_pcalloc(p, sizeof(reqtimeout_srv_cfg));
    
        MERGE_STAGE(cfg, base, add, handshake);
        MERGE_STAGE(cfg, base, add, header);
        MERGE_STAGE(cfg, base, add, body);
    
        return cfg;
    }
    
    static const char *parse_int(apr_pool_t *p, const char *arg, int *val)
    {
        char *endptr;
        *val = strtol(arg, &endptr, 10);
    
        if (arg == endptr) {
            return apr_psprintf(p, "Value '%s' not numerical", endptr);
        }
        if (*endptr != '\0') {
            return apr_psprintf(p, "Cannot parse '%s'", endptr);
        }
        if (*val < 0) {
            return "Value must be non-negative";
        }
        return NULL;
    }
    
    static const char *set_reqtimeout_param(reqtimeout_srv_cfg *conf,
                                          apr_pool_t *p,
                                          const char *key,
                                          const char *val)
    {
        const char *ret = NULL;
        char *rate_str = NULL, *initial_str, *max_str = NULL;
        reqtimeout_stage_t *stage;
    
        if (!strcasecmp(key, "handshake")) {
            stage = &conf->handshake;
        }
        else if (!strcasecmp(key, "header")) {
            stage = &conf->header;
        }
        else if (!strcasecmp(key, "body")) {
            stage = &conf->body;
        }
        else {
            return "Unknown RequestReadTimeout parameter";
        }
    
        memset(stage, 0, sizeof(*stage));
    
        if ((rate_str = ap_strcasestr(val, ",minrate="))) {
            initial_str = apr_pstrndup(p, val, rate_str - val);
            rate_str += strlen(",minrate=");
            ret = parse_int(p, rate_str, &stage->min_rate);
            if (ret)
                return ret;
    
            if (stage->min_rate == 0)
                return "Minimum data rate must be larger than 0";
    
            if ((max_str = strchr(initial_str, '-'))) {
                *max_str++ = '\0';
                ret = parse_int(p, max_str, &stage->max_timeout);
                if (ret)
                    return ret;
            }
    
            ret = parse_int(p, initial_str, &stage->timeout);
        }
        else {
            if (ap_strchr_c(val, '-'))
                return "Must set MinRate option if using timeout range";
            ret = parse_int(p, val, &stage->timeout);
        }
        if (ret)
            return ret;
    
        if (stage->max_timeout && stage->timeout >= stage->max_timeout) {
            return "Maximum timeout must be larger than initial timeout";
        }
    
        if (stage->min_rate) {
            stage->rate_factor = apr_time_from_sec(1) / stage->min_rate;
        }
    
        return NULL;
    }
    
    static const char *set_reqtimeouts(cmd_parms *cmd, void *mconfig,
                                       const char *arg)
    {
        reqtimeout_srv_cfg *conf =
        ap_get_module_config(cmd->server->module_config,
                             &reqtimeout_module);
    
        while (*arg) {
            char *word, *val;
            const char *err;
    
            word = ap_getword_conf(cmd->temp_pool, &arg);
            val = strchr(word, '=');
            if (!val) {
                return "Invalid RequestReadTimeout parameter. Parameter must be "
                "in the form 'key=value'";
            }
            else
                *val++ = '\0';
    
            err = set_reqtimeout_param(conf, cmd->pool, word, val);
    
            if (err)
                return apr_psprintf(cmd->temp_pool, "RequestReadTimeout: %s=%s: %s",
                                   word, val, err);
        }
    
        return NULL;
    
    }
    
    static void reqtimeout_hooks(apr_pool_t *pool)
    {
        /*
         * mod_ssl is AP_FTYPE_CONNECTION + 5 and mod_reqtimeout needs to
         * be called before mod_ssl for the handshake stage to catch SSL traffic.
         */
        ap_register_input_filter(reqtimeout_filter_name, reqtimeout_filter, NULL,
                                 AP_FTYPE_CONNECTION + 8);
    
        /*
         * We need to pause timeout detection in between requests, for
         * speculative and non-blocking reads, so between each outgoing EOR
         * and the next pre_read_request call.
         */
        ap_register_output_filter(reqtimeout_filter_name, reqtimeout_eor, NULL,
                                  AP_FTYPE_CONNECTION);
    
        /*
         * mod_reqtimeout needs to be called before ap_process_http_request (which
         * is run at APR_HOOK_REALLY_LAST) but after all other protocol modules.
         * This ensures that it only influences normal http connections and not
         * e.g. mod_ftp. We still process it first though, for the handshake stage
         * to work with/before mod_ssl, but since it's disabled by default it won't
         * influence non-HTTP modules unless configured explicitly. Also, if
         * mod_reqtimeout used the pre_connection hook, it would be inserted on
         * mod_proxy's backend connections, and we don't want this.
         */
        ap_hook_process_connection(reqtimeout_init, NULL, NULL, APR_HOOK_FIRST);
    
        ap_hook_pre_read_request(reqtimeout_before_header, NULL, NULL,
                                 APR_HOOK_MIDDLE);
        ap_hook_post_read_request(reqtimeout_before_body, NULL, NULL,
                                  APR_HOOK_MIDDLE);
    
    #if MRT_DEFAULT_handshake_MIN_RATE
        default_handshake_rate_factor = apr_time_from_sec(1) /
                                        MRT_DEFAULT_handshake_MIN_RATE;
    #endif
    #if MRT_DEFAULT_header_MIN_RATE
        default_header_rate_factor = apr_time_from_sec(1) /
                                     MRT_DEFAULT_header_MIN_RATE;
    #endif
    #if MRT_DEFAULT_body_MIN_RATE
        default_body_rate_factor = apr_time_from_sec(1) /
                                   MRT_DEFAULT_body_MIN_RATE;
    #endif
    }
    
    static const command_rec reqtimeout_cmds[] = {
        AP_INIT_RAW_ARGS("RequestReadTimeout", set_reqtimeouts, NULL, RSRC_CONF,
                         "Set various timeout parameters for TLS handshake and/or "
                         "reading request headers and body"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(reqtimeout) = {
        STANDARD20_MODULE_STUFF,
        NULL,                           /* create per-dir config structures */
        NULL,                           /* merge  per-dir config structures */
        reqtimeout_create_srv_config,   /* create per-server config structures */
        reqtimeout_merge_srv_config,    /* merge per-server config structures */
        reqtimeout_cmds,                /* table of config file commands */
        reqtimeout_hooks
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_brotli.dsp���������������������������������������������������������0000664�0001751�0001751�00000011331�13100405645�020601� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_brotli" - 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_brotli - 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_brotli.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_brotli.mak" CFG="mod_brotli - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_brotli - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_brotli - 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_brotli - 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/brotli/include" /I "../../srclib/brotli/c/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_brotli_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 /fo"Release/mod_brotli.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_brotli.so" /d LONG_NAME="brotli_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_brotli.so" /libpath:"../../srclib/brotli" /base:@..\..\os\win32\BaseAddr.ref,mod_brotli.so
    # ADD LINK32 kernel32.lib brotlicommon.lib brotlienc.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_brotli.so" /libpath:"../../srclib/brotli" /base:@..\..\os\win32\BaseAddr.ref,mod_brotli.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_brotli.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_brotli - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/brotli/include" /I "../../srclib/brotli/c/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fd"Debug\mod_brotli_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 /fo"Debug/mod_brotli.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_brotli.so" /d LONG_NAME="brotli_module for Apache"
    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 /out:".\Debug\mod_brotli.so" /libpath:"../../srclib/brotli" /base:@..\..\os\win32\BaseAddr.ref,mod_brotli.so
    # ADD LINK32 kernel32.lib brotlicommon.lib brotlienc.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_brotli.so" /libpath:"../../srclib/brotli" /base:@..\..\os\win32\BaseAddr.ref,mod_brotli.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_brotli.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_brotli - Win32 Release"
    # Name "mod_brotli - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_brotli.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/regexp.c���������������������������������������������������������������0000664�0001751�0001751�00000035515�13025005707�017410� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
     * Use is subject to license terms.
     *
     *      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
     *        All Rights Reserved
     *
     * University Copyright- Copyright (c) 1982, 1986, 1988
     * The Regents of the University of California
     * All Rights Reserved
     *
     * University Acknowledgment- Portions of this document are derived from
     * software developed by the University of California, Berkeley, and its
     * contributors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  http://www.apache.org/licenses/LICENSE-2.0.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     * or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /* Code moved from regexp.h */
    
    #include "apr.h"
    #include "apr_lib.h"
    #if APR_HAVE_LIMITS_H
    #include <limits.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #include "libsed.h"
    #include "regexp.h"
    #include "sed.h"
    
    #define GETC() ((unsigned char)*sp++)
    #define PEEKC() ((unsigned char)*sp)
    #define UNGETC(c) (--sp)
    #define SEDCOMPILE_ERROR(c) { \
                regerrno = c; \
                goto out; \
                }
    #define ecmp(s1, s2, n)    (strncmp(s1, s2, n) == 0)
    #define uletter(c) (isalpha(c) || c == '_')
    
    
    static unsigned char bittab[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
    
    static int regerr(sed_commands_t *commands, int err);
    static void comperr(sed_commands_t *commands, char *msg);
    static void getrnge(char *str, step_vars_storage *vars);
    static int _advance(char *, char *, step_vars_storage *);
    extern int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars);
    
    
    static void comperr(sed_commands_t *commands, char *msg)
    {
        command_errf(commands, msg, commands->linebuf);
    }
    
    /*
    */
    static int regerr(sed_commands_t *commands, int err)
    {
        switch(err) {
        case 0:
            /* No error */
            break;
        case 11:
            comperr(commands, "Range endpoint too large: %s");
            break;
    
        case 16:
            comperr(commands, "Bad number: %s");
            break;
    
        case 25:
            comperr(commands, "``\\digit'' out of range: %s");
            break;
    
        case 36:
            comperr(commands, "Illegal or missing delimiter: %s");
            break;
    
        case 41:
            comperr(commands, "No remembered search string: %s");
            break;
    
        case 42:
            comperr(commands, "\\( \\) imbalance: %s");
            break;
    
        case 43:
            comperr(commands, "Too many \\(: %s");
            break;
    
        case 44:
            comperr(commands, "More than 2 numbers given in \\{ \\}: %s");
            break;
    
        case 45:
            comperr(commands, "} expected after \\: %s");
            break;
    
        case 46:
            comperr(commands, "First number exceeds second in \\{ \\}: %s");
            break;
    
        case 49:
            comperr(commands, "[ ] imbalance: %s");
            break;
    
        case 50:
            comperr(commands, SEDERR_TMMES);
            break;
    
        default:
            comperr(commands, "Unknown regexp error code %s\n");
            break;
        }
        return (0);
    }
    
    
    char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
                      char *ep, char *endbuf, int seof)
    {
        int c;
        int eof = seof;
        char *lastep;
        int cclcnt;
        char bracket[NBRA], *bracketp;
        int closed;
        int neg;
        int lc;
        int i, cflg;
        int iflag; /* used for non-ascii characters in brackets */
        char *sp = commands->cp;
        int regerrno = 0;
    
        lastep = 0;
        if ((c = GETC()) == eof || c == '\n') {
            if (c == '\n') {
                UNGETC(c);
            }
            commands->cp = sp;
            goto out;
        }
        bracketp = bracket;
        compargs->circf = closed = compargs->nbra = 0;
        if (c == '^')
            compargs->circf++;
        else
            UNGETC(c);
        while (1) {
            if (ep >= endbuf)
                SEDCOMPILE_ERROR(50);
            c = GETC();
            if (c != '*' && ((c != '\\') || (PEEKC() != '{')))
                lastep = ep;
            if (c == eof) {
                *ep++ = CCEOF;
                if (bracketp != bracket)
                    SEDCOMPILE_ERROR(42);
                commands->cp = sp;
                goto out;
            }
            switch (c) {
    
            case '.':
                *ep++ = CDOT;
                continue;
    
            case '\n':
                SEDCOMPILE_ERROR(36);
                commands->cp = sp;
                goto out;
            case '*':
                if (lastep == 0 || *lastep == CBRA || *lastep == CKET)
                    goto defchar;
                *lastep |= STAR;
                continue;
    
            case '$':
                if (PEEKC() != eof && PEEKC() != '\n')
                    goto defchar;
                *ep++ = CDOL;
                continue;
    
            case '[':
                if (&ep[17] >= endbuf)
                    SEDCOMPILE_ERROR(50);
    
                *ep++ = CCL;
                lc = 0;
                for (i = 0; i < 16; i++)
                    ep[i] = 0;
    
                neg = 0;
                if ((c = GETC()) == '^') {
                    neg = 1;
                    c = GETC();
                }
                iflag = 1;
                do {
                    c &= 0377;
                    if (c == '\0' || c == '\n')
                        SEDCOMPILE_ERROR(49);
                    if ((c & 0200) && iflag) {
                        iflag = 0;
                        if (&ep[32] >= endbuf)
                            SEDCOMPILE_ERROR(50);
                        ep[-1] = CXCL;
                        for (i = 16; i < 32; i++)
                            ep[i] = 0;
                    }
                    if (c == '-' && lc != 0) {
                        if ((c = GETC()) == ']') {
                            PLACE('-');
                            break;
                        }
                        if ((c & 0200) && iflag) {
                            iflag = 0;
                            if (&ep[32] >= endbuf)
                                SEDCOMPILE_ERROR(50);
                            ep[-1] = CXCL;
                            for (i = 16; i < 32; i++)
                                ep[i] = 0;
                        }
                        while (lc < c) {
                            PLACE(lc);
                            lc++;
                        }
                    }
                    lc = c;
                    PLACE(c);
                } while ((c = GETC()) != ']');
    
                if (iflag)
                    iflag = 16;
                else
                    iflag = 32;
    
                if (neg) {
                    if (iflag == 32) {
                        for (cclcnt = 0; cclcnt < iflag;
                            cclcnt++)
                            ep[cclcnt] ^= 0377;
                        ep[0] &= 0376;
                    } else {
                        ep[-1] = NCCL;
                        /* make nulls match so test fails */
                        ep[0] |= 01;
                    }
                }
    
                ep += iflag;
    
                continue;
    
            case '\\':
                switch (c = GETC()) {
    
                case '(':
                    if (compargs->nbra >= NBRA)
                        SEDCOMPILE_ERROR(43);
                    *bracketp++ = compargs->nbra;
                    *ep++ = CBRA;
                    *ep++ = compargs->nbra++;
                    continue;
    
                case ')':
                    if (bracketp <= bracket)
                        SEDCOMPILE_ERROR(42);
                    *ep++ = CKET;
                    *ep++ = *--bracketp;
                    closed++;
                    continue;
    
                case '{':
                    if (lastep == (char *) 0)
                        goto defchar;
                    *lastep |= RNGE;
                    cflg = 0;
                nlim:
                    c = GETC();
                    i = 0;
                    do {
                        if ('0' <= c && c <= '9')
                            i = 10 * i + c - '0';
                        else
                            SEDCOMPILE_ERROR(16);
                    } while (((c = GETC()) != '\\') && (c != ','));
                    if (i >= 255)
                        SEDCOMPILE_ERROR(11);
                    *ep++ = i;
                    if (c == ',') {
                        if (cflg++)
                            SEDCOMPILE_ERROR(44);
                        if ((c = GETC()) == '\\')
                            *ep++ = (char) 255;
                        else {
                            UNGETC(c);
                            goto nlim;
                            /* get 2'nd number */
                        }
                    }
                    if (GETC() != '}')
                        SEDCOMPILE_ERROR(45);
                    if (!cflg)    /* one number */
                        *ep++ = i;
                    else if ((ep[-1] & 0377) < (ep[-2] & 0377))
                        SEDCOMPILE_ERROR(46);
                    continue;
    
                case '\n':
                    SEDCOMPILE_ERROR(36);
    
                case 'n':
                    c = '\n';
                    goto defchar;
    
                default:
                    if (c >= '1' && c <= '9') {
                        if ((c -= '1') >= closed)
                            SEDCOMPILE_ERROR(25);
                        *ep++ = CBACK;
                        *ep++ = c;
                        continue;
                    }
                }
        /* Drop through to default to use \ to turn off special chars */
    
            defchar:
            default:
                lastep = ep;
                *ep++ = CCHR;
                *ep++ = c;
            }
        }
    out:
        if (regerrno) {
            regerr(commands, regerrno);
            return (char*) NULL;
        }
        /* XXX : Basant : what extra */
        /* int reglength = (int)(ep - expbuf); */
        return ep;
    }
    
    int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars)
    {
        int c;
    
    
        if (circf) {
            vars->loc1 = p1;
            return (_advance(p1, p2, vars));
        }
        /* fast check for first character */
        if (*p2 == CCHR) {
            c = p2[1];
            do {
                if (*p1 != c)
                    continue;
                if (_advance(p1, p2, vars)) {
                    vars->loc1 = p1;
                    return (1);
                }
            } while (*p1++);
            return (0);
        }
            /* regular algorithm */
        do {
            if (_advance(p1, p2, vars)) {
                vars->loc1 = p1;
                return (1);
            }
        } while (*p1++);
        return (0);
    }
    
    static int _advance(char *lp, char *ep, step_vars_storage *vars)
    {
        char *curlp;
        int c;
        char *bbeg;
        char neg;
        int ct;
        int epint; /* int value of *ep */
    
        while (1) {
            neg = 0;
            switch (*ep++) {
    
            case CCHR:
                if (*ep++ == *lp++)
                    continue;
                return (0);
    
            case CDOT:
                if (*lp++)
                    continue;
                return (0);
    
            case CDOL:
                if (*lp == 0)
                    continue;
                return (0);
    
            case CCEOF:
                vars->loc2 = lp;
                return (1);
    
            case CXCL:
                c = (unsigned char)*lp++;
                if (ISTHERE(c)) {
                    ep += 32;
                    continue;
                }
                return (0);
    
            case NCCL:
                neg = 1;
    
            case CCL:
                c = *lp++;
                if (((c & 0200) == 0 && ISTHERE(c)) ^ neg) {
                    ep += 16;
                    continue;
                }
                return (0);
    
            case CBRA:
                epint = (int) *ep;
                vars->braslist[epint] = lp;
                ep++;
                continue;
    
            case CKET:
                epint = (int) *ep;
                vars->braelist[epint] = lp;
                ep++;
                continue;
    
            case CCHR | RNGE:
                c = *ep++;
                getrnge(ep, vars);
                while (vars->low--)
                    if (*lp++ != c)
                        return (0);
                curlp = lp;
                while (vars->size--)
                    if (*lp++ != c)
                        break;
                if (vars->size < 0)
                    lp++;
                ep += 2;
                goto star;
    
            case CDOT | RNGE:
                getrnge(ep, vars);
                while (vars->low--)
                    if (*lp++ == '\0')
                        return (0);
                curlp = lp;
                while (vars->size--)
                    if (*lp++ == '\0')
                        break;
                if (vars->size < 0)
                    lp++;
                ep += 2;
                goto star;
    
            case CXCL | RNGE:
                getrnge(ep + 32, vars);
                while (vars->low--) {
                    c = (unsigned char)*lp++;
                    if (!ISTHERE(c))
                        return (0);
                }
                curlp = lp;
                while (vars->size--) {
                    c = (unsigned char)*lp++;
                    if (!ISTHERE(c))
                        break;
                }
                if (vars->size < 0)
                    lp++;
                ep += 34;        /* 32 + 2 */
                goto star;
    
            case NCCL | RNGE:
                neg = 1;
    
            case CCL | RNGE:
                getrnge(ep + 16, vars);
                while (vars->low--) {
                    c = *lp++;
                    if (((c & 0200) || !ISTHERE(c)) ^ neg)
                        return (0);
                }
                curlp = lp;
                while (vars->size--) {
                    c = *lp++;
                    if (((c & 0200) || !ISTHERE(c)) ^ neg)
                        break;
                }
                if (vars->size < 0)
                    lp++;
                ep += 18;         /* 16 + 2 */
                goto star;
    
            case CBACK:
                epint = (int) *ep;
                bbeg = vars->braslist[epint];
                ct = vars->braelist[epint] - bbeg;
                ep++;
    
                if (ecmp(bbeg, lp, ct)) {
                    lp += ct;
                    continue;
                }
                return (0);
    
            case CBACK | STAR:
                epint = (int) *ep;
                bbeg = vars->braslist[epint];
                ct = vars->braelist[epint] - bbeg;
                ep++;
                curlp = lp;
                while (ecmp(bbeg, lp, ct))
                    lp += ct;
    
                while (lp >= curlp) {
                    if (_advance(lp, ep, vars))
                        return (1);
                    lp -= ct;
                }
                return (0);
    
    
            case CDOT | STAR:
                curlp = lp;
                while (*lp++);
                goto star;
    
            case CCHR | STAR:
                curlp = lp;
                while (*lp++ == *ep);
                ep++;
                goto star;
    
            case CXCL | STAR:
                curlp = lp;
                do {
                    c = (unsigned char)*lp++;
                } while (ISTHERE(c));
                ep += 32;
                goto star;
    
            case NCCL | STAR:
                neg = 1;
    
            case CCL | STAR:
                curlp = lp;
                do {
                    c = *lp++;
                } while (((c & 0200) == 0 && ISTHERE(c)) ^ neg);
                ep += 16;
                goto star;
    
            star:
                do {
                    if (--lp == vars->locs)
                        break;
                    if (_advance(lp, ep, vars))
                        return (1);
                } while (lp > curlp);
                return (0);
    
            }
        }
    }
    
    static void getrnge(char *str, step_vars_storage *vars)
    {
        vars->low = *str++ & 0377;
        vars->size = ((*str & 0377) == 255)? 20000: (*str &0377) - vars->low;
    }
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_data.mak�����������������������������������������������������������0000664�0001751�0001751�00000023103�12701473373�020212� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_data.dsp
    !IF "$(CFG)" == ""
    CFG=mod_data - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_data - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_data - Win32 Release" && "$(CFG)" != "mod_data - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_data.mak" CFG="mod_data - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_data - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_data - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_data - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_data.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_data.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_data.obj"
    	-@erase "$(INTDIR)\mod_data.res"
    	-@erase "$(INTDIR)\mod_data_src.idb"
    	-@erase "$(INTDIR)\mod_data_src.pdb"
    	-@erase "$(OUTDIR)\mod_data.exp"
    	-@erase "$(OUTDIR)\mod_data.lib"
    	-@erase "$(OUTDIR)\mod_data.pdb"
    	-@erase "$(OUTDIR)\mod_data.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_data_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_data.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_data.so" /d LONG_NAME="data_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_data.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_data.pdb" /debug /out:"$(OUTDIR)\mod_data.so" /implib:"$(OUTDIR)\mod_data.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_data.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_data.obj" \
    	"$(INTDIR)\mod_data.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_data.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_data.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_data.so"
       if exist .\Release\mod_data.so.manifest mt.exe -manifest .\Release\mod_data.so.manifest -outputresource:.\Release\mod_data.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_data - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_data.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_data.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_data.obj"
    	-@erase "$(INTDIR)\mod_data.res"
    	-@erase "$(INTDIR)\mod_data_src.idb"
    	-@erase "$(INTDIR)\mod_data_src.pdb"
    	-@erase "$(OUTDIR)\mod_data.exp"
    	-@erase "$(OUTDIR)\mod_data.lib"
    	-@erase "$(OUTDIR)\mod_data.pdb"
    	-@erase "$(OUTDIR)\mod_data.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_data_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_data.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_data.so" /d LONG_NAME="data_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_data.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_data.pdb" /debug /out:"$(OUTDIR)\mod_data.so" /implib:"$(OUTDIR)\mod_data.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_data.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_data.obj" \
    	"$(INTDIR)\mod_data.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_data.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_data.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_data.so"
       if exist .\Debug\mod_data.so.manifest mt.exe -manifest .\Debug\mod_data.so.manifest -outputresource:.\Debug\mod_data.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_data.dep")
    !INCLUDE "mod_data.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_data.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_data - Win32 Release" || "$(CFG)" == "mod_data - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_data - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_data - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_data - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_data - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_data - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_data - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_data - Win32 Release"
    
    
    "$(INTDIR)\mod_data.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_data.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_data.so" /d LONG_NAME="data_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_data - Win32 Debug"
    
    
    "$(INTDIR)\mod_data.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_data.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_data.so" /d LONG_NAME="data_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_data.c
    
    "$(INTDIR)\mod_data.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_include.mak��������������������������������������������������������0000664�0001751�0001751�00000023471�12701473373�020734� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_include.dsp
    !IF "$(CFG)" == ""
    CFG=mod_include - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_include - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_include - Win32 Release" && "$(CFG)" != "mod_include - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_include - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_include.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_include.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_include.obj"
    	-@erase "$(INTDIR)\mod_include.res"
    	-@erase "$(INTDIR)\mod_include_src.idb"
    	-@erase "$(INTDIR)\mod_include_src.pdb"
    	-@erase "$(OUTDIR)\mod_include.exp"
    	-@erase "$(OUTDIR)\mod_include.lib"
    	-@erase "$(OUTDIR)\mod_include.pdb"
    	-@erase "$(OUTDIR)\mod_include.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_include_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_include.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_include.so" /d LONG_NAME="include_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_include.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_include.pdb" /debug /out:"$(OUTDIR)\mod_include.so" /implib:"$(OUTDIR)\mod_include.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_include.obj" \
    	"$(INTDIR)\mod_include.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_include.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_include.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_include.so"
       if exist .\Release\mod_include.so.manifest mt.exe -manifest .\Release\mod_include.so.manifest -outputresource:.\Release\mod_include.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_include - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_include.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_include.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_include.obj"
    	-@erase "$(INTDIR)\mod_include.res"
    	-@erase "$(INTDIR)\mod_include_src.idb"
    	-@erase "$(INTDIR)\mod_include_src.pdb"
    	-@erase "$(OUTDIR)\mod_include.exp"
    	-@erase "$(OUTDIR)\mod_include.lib"
    	-@erase "$(OUTDIR)\mod_include.pdb"
    	-@erase "$(OUTDIR)\mod_include.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_include_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_include.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_include.so" /d LONG_NAME="include_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_include.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_include.pdb" /debug /out:"$(OUTDIR)\mod_include.so" /implib:"$(OUTDIR)\mod_include.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_include.obj" \
    	"$(INTDIR)\mod_include.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_include.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_include.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_include.so"
       if exist .\Debug\mod_include.so.manifest mt.exe -manifest .\Debug\mod_include.so.manifest -outputresource:.\Debug\mod_include.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_include.dep")
    !INCLUDE "mod_include.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_include.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_include - Win32 Release" || "$(CFG)" == "mod_include - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_include - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_include - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_include - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_include - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_include - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_include - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_include - Win32 Release"
    
    
    "$(INTDIR)\mod_include.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_include.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_include.so" /d LONG_NAME="include_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_include - Win32 Debug"
    
    
    "$(INTDIR)\mod_include.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_include.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_include.so" /d LONG_NAME="include_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_include.c
    
    "$(INTDIR)\mod_include.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reqtimeout.mak�����������������������������������������������������0000664�0001751�0001751�00000024165�12701473373�021510� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_reqtimeout.dsp
    !IF "$(CFG)" == ""
    CFG=mod_reqtimeout - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_reqtimeout - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_reqtimeout - Win32 Release" && "$(CFG)" != "mod_reqtimeout - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_reqtimeout.mak" CFG="mod_reqtimeout - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_reqtimeout - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_reqtimeout - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_reqtimeout - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_reqtimeout.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_reqtimeout.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_reqtimeout.obj"
    	-@erase "$(INTDIR)\mod_reqtimeout.res"
    	-@erase "$(INTDIR)\mod_reqtimeout_src.idb"
    	-@erase "$(INTDIR)\mod_reqtimeout_src.pdb"
    	-@erase "$(OUTDIR)\mod_reqtimeout.exp"
    	-@erase "$(OUTDIR)\mod_reqtimeout.lib"
    	-@erase "$(OUTDIR)\mod_reqtimeout.pdb"
    	-@erase "$(OUTDIR)\mod_reqtimeout.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_reqtimeout_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_reqtimeout.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_reqtimeout.pdb" /debug /out:"$(OUTDIR)\mod_reqtimeout.so" /implib:"$(OUTDIR)\mod_reqtimeout.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_reqtimeout.obj" \
    	"$(INTDIR)\mod_reqtimeout.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_reqtimeout.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_reqtimeout.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_reqtimeout.so"
       if exist .\Release\mod_reqtimeout.so.manifest mt.exe -manifest .\Release\mod_reqtimeout.so.manifest -outputresource:.\Release\mod_reqtimeout.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_reqtimeout - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_reqtimeout.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_reqtimeout.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_reqtimeout.obj"
    	-@erase "$(INTDIR)\mod_reqtimeout.res"
    	-@erase "$(INTDIR)\mod_reqtimeout_src.idb"
    	-@erase "$(INTDIR)\mod_reqtimeout_src.pdb"
    	-@erase "$(OUTDIR)\mod_reqtimeout.exp"
    	-@erase "$(OUTDIR)\mod_reqtimeout.lib"
    	-@erase "$(OUTDIR)\mod_reqtimeout.pdb"
    	-@erase "$(OUTDIR)\mod_reqtimeout.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_reqtimeout_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_reqtimeout.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_reqtimeout.pdb" /debug /out:"$(OUTDIR)\mod_reqtimeout.so" /implib:"$(OUTDIR)\mod_reqtimeout.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_reqtimeout.obj" \
    	"$(INTDIR)\mod_reqtimeout.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_reqtimeout.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_reqtimeout.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_reqtimeout.so"
       if exist .\Debug\mod_reqtimeout.so.manifest mt.exe -manifest .\Debug\mod_reqtimeout.so.manifest -outputresource:.\Debug\mod_reqtimeout.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_reqtimeout.dep")
    !INCLUDE "mod_reqtimeout.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_reqtimeout.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_reqtimeout - Win32 Release" || "$(CFG)" == "mod_reqtimeout - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_reqtimeout - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_reqtimeout - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_reqtimeout - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_reqtimeout - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_reqtimeout - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_reqtimeout - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_reqtimeout - Win32 Release"
    
    
    "$(INTDIR)\mod_reqtimeout.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_reqtimeout - Win32 Debug"
    
    
    "$(INTDIR)\mod_reqtimeout.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_reqtimeout.c
    
    "$(INTDIR)\mod_reqtimeout.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ratelimit.c��������������������������������������������������������0000664�0001751�0001751�00000025130�13341325553�020744� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "util_filter.h"
    
    #include "mod_ratelimit.h"
    
    #define RATE_LIMIT_FILTER_NAME "RATE_LIMIT"
    #define RATE_INTERVAL_MS (200)
    
    typedef enum rl_state_e
    {
        RATE_LIMIT,
        RATE_FULLSPEED
    } rl_state_e;
    
    typedef struct rl_ctx_t
    {
        int speed;
        int chunk_size;
        int burst;
        int do_sleep;
        rl_state_e state;
        apr_bucket_brigade *tmpbb;
        apr_bucket_brigade *holdingbb;
    } rl_ctx_t;
    
    #if defined(RLFDEBUG)
    static void brigade_dump(request_rec *r, apr_bucket_brigade *bb)
    {
        apr_bucket *e;
        int i = 0;
    
        for (e = APR_BRIGADE_FIRST(bb);
             e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e), i++) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03193)
                          "brigade: [%d] %s", i, e->type->name);
    
        }
    }
    #endif /* RLFDEBUG */
    
    static apr_status_t
    rate_limit_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        apr_status_t rv = APR_SUCCESS;
        rl_ctx_t *ctx = f->ctx;
        apr_bucket_alloc_t *ba = f->r->connection->bucket_alloc;
    
        /* Set up our rl_ctx_t on first use */
        if (ctx == NULL) {
            const char *rl = NULL;
            int ratelimit;
            int burst = 0;
    
            /* no subrequests. */
            if (f->r->main != NULL) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /* Configuration: rate limit */
            rl = apr_table_get(f->r->subprocess_env, "rate-limit");
    
            if (rl == NULL) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
            
            /* rl is in kilo bytes / second  */
            ratelimit = atoi(rl) * 1024;
            if (ratelimit <= 0) {
                /* remove ourselves */
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r,
                              APLOGNO(03488) "rl: disabling: rate-limit = %s (too high?)", rl);
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /* Configuration: optional initial burst */
            rl = apr_table_get(f->r->subprocess_env, "rate-initial-burst");
            if (rl != NULL) {
                burst = atoi(rl) * 1024;
                if (burst <= 0) {
                   ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r,
                                 APLOGNO(03489) "rl: disabling burst: rate-initial-burst = %s (too high?)", rl);
                   burst = 0;
                }
            }
    
            /* Set up our context */
            ctx = apr_palloc(f->r->pool, sizeof(rl_ctx_t));
            f->ctx = ctx;
            ctx->state = RATE_LIMIT;
            ctx->speed = ratelimit;
            ctx->burst = burst;
            ctx->do_sleep = 0;
    
            /* calculate how many bytes / interval we want to send */
            /* speed is bytes / second, so, how many  (speed / 1000 % interval) */
            ctx->chunk_size = (ctx->speed / (1000 / RATE_INTERVAL_MS));
            ctx->tmpbb = apr_brigade_create(f->r->pool, ba);
            ctx->holdingbb = apr_brigade_create(f->r->pool, ba);
        }
        else {
            APR_BRIGADE_PREPEND(bb, ctx->holdingbb);
        }
    
        while (!APR_BRIGADE_EMPTY(bb)) {
            apr_bucket *e;
    
            if (ctx->state == RATE_FULLSPEED) {
                /* Find where we 'stop' going full speed. */
                for (e = APR_BRIGADE_FIRST(bb);
                     e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e)) {
                    if (AP_RL_BUCKET_IS_END(e)) {
                        apr_brigade_split_ex(bb, e, ctx->holdingbb);
                        ctx->state = RATE_LIMIT;
                        break;
                    }
                }
    
                e = apr_bucket_flush_create(ba);
                APR_BRIGADE_INSERT_TAIL(bb, e);
                rv = ap_pass_brigade(f->next, bb);
                apr_brigade_cleanup(bb);
    
                if (rv != APR_SUCCESS) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, f->r, APLOGNO(01455)
                                  "rl: full speed brigade pass failed.");
                    return rv;
                }
            }
            else {
                for (e = APR_BRIGADE_FIRST(bb);
                     e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e)) {
                    if (AP_RL_BUCKET_IS_START(e)) {
                        apr_brigade_split_ex(bb, e, ctx->holdingbb);
                        ctx->state = RATE_FULLSPEED;
                        break;
                    }
                }
    
                while (!APR_BRIGADE_EMPTY(bb)) {
                    apr_off_t len = ctx->chunk_size + ctx->burst;
    
                    APR_BRIGADE_CONCAT(ctx->tmpbb, bb);
    
                    /*
                     * Pull next chunk of data; the initial amount is our
                     * burst allotment (if any) plus a chunk.  All subsequent
                     * iterations are just chunks with whatever remaining
                     * burst amounts we have left (in case not done in the
                     * first bucket).
                     */
                    rv = apr_brigade_partition(ctx->tmpbb, len, &e);
                    if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(01456)
                                      "rl: partition failed.");
                        return rv;
                    }
                    /* Send next metadata now if any */
                    while (e != APR_BRIGADE_SENTINEL(ctx->tmpbb)
                           && APR_BUCKET_IS_METADATA(e)) {
                        e = APR_BUCKET_NEXT(e);
                    }
                    if (e != APR_BRIGADE_SENTINEL(ctx->tmpbb)) {
                        apr_brigade_split_ex(ctx->tmpbb, e, bb);
                    }
                    else {
                        apr_brigade_length(ctx->tmpbb, 1, &len);
                    }
    
                    /*
                     * Adjust the burst amount depending on how much
                     * we've done up to now.
                     */
                    if (ctx->burst) {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
                            APLOGNO(03485) "rl: burst %d; len %"APR_OFF_T_FMT, ctx->burst, len);
                        if (len < ctx->burst) {
                            ctx->burst -= len;
                        }
                        else {
                            ctx->burst = 0;
                        }
                    }
    
                    e = APR_BRIGADE_LAST(ctx->tmpbb);
                    if (APR_BUCKET_IS_EOS(e)) {
                        ap_remove_output_filter(f);
                    }
                    else if (!APR_BUCKET_IS_FLUSH(e)) {
                        if (APR_BRIGADE_EMPTY(bb)) {
                            /* Wait for more (or next call) */
                            break;
                        }
                        e = apr_bucket_flush_create(ba);
                        APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, e);
                    }
    
    #if defined(RLFDEBUG)
                    brigade_dump(f->r, ctx->tmpbb);
                    brigade_dump(f->r, bb);
    #endif /* RLFDEBUG */
    
                    if (ctx->do_sleep) {
                        apr_sleep(RATE_INTERVAL_MS * 1000);
                    }
                    else {
                        ctx->do_sleep = 1;
                    }
    
                    rv = ap_pass_brigade(f->next, ctx->tmpbb);
                    apr_brigade_cleanup(ctx->tmpbb);
    
                    if (rv != APR_SUCCESS) {
                        /* Most often, user disconnects from stream */
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, f->r, APLOGNO(01457)
                                      "rl: brigade pass failed.");
                        return rv;
                    }
                }
            }
    
            if (!APR_BRIGADE_EMPTY(ctx->holdingbb)) {
                /* Any rate-limited data in tmpbb is sent unlimited along
                 * with the rest.
                 */
                APR_BRIGADE_CONCAT(bb, ctx->tmpbb);
                APR_BRIGADE_CONCAT(bb, ctx->holdingbb);
            }
        }
    
    #if defined(RLFDEBUG)
        brigade_dump(f->r, ctx->tmpbb);
    #endif /* RLFDEBUG */
    
        /* Save remaining tmpbb with the correct lifetime for the next call */
        return ap_save_brigade(f, &ctx->holdingbb, &ctx->tmpbb, f->r->pool);
    }
    
    
    static apr_status_t
    rl_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_RL_DECLARE(apr_bucket *)
        ap_rl_end_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;
        b->length = 0;
        b->start = 0;
        b->data = NULL;
        b->type = &ap_rl_bucket_type_end;
    
        return b;
    }
    
    AP_RL_DECLARE(apr_bucket *)
        ap_rl_start_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;
        b->length = 0;
        b->start = 0;
        b->data = NULL;
        b->type = &ap_rl_bucket_type_start;
    
        return b;
    }
    
    
    
    AP_RL_DECLARE_DATA const apr_bucket_type_t ap_rl_bucket_type_end = {
        "RL_END", 5, APR_BUCKET_METADATA,
        apr_bucket_destroy_noop,
        rl_bucket_read,
        apr_bucket_setaside_noop,
        apr_bucket_split_notimpl,
        apr_bucket_simple_copy
    };
    
    
    AP_RL_DECLARE_DATA const apr_bucket_type_t ap_rl_bucket_type_start = {
        "RL_START", 5, APR_BUCKET_METADATA,
        apr_bucket_destroy_noop,
        rl_bucket_read,
        apr_bucket_setaside_noop,
        apr_bucket_split_notimpl,
        apr_bucket_simple_copy
    };
    
    
    
    
    static void register_hooks(apr_pool_t *p)
    {
        /* run after mod_deflate etc etc, but not at connection level, ie, mod_ssl. */
        ap_register_output_filter(RATE_LIMIT_FILTER_NAME, rate_limit_filter,
                                  NULL, AP_FTYPE_CONNECTION - 1);
    }
    
    AP_DECLARE_MODULE(ratelimit) = {
        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
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_filter.c�����������������������������������������������������������0000664�0001751�0001751�00000061463�13044663503�020250� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_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"
    #include "ap_expr.h"
    
    module AP_MODULE_DECLARE_DATA filter_module;
    
    /**
     * @brief 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 {
        ap_expr_info_t *expr;
        const char **types;
    
        /** The filter that implements this provider */
        ap_filter_rec_t *frec;
    
        /** The next provider in the list */
        ap_filter_provider_t *next;
    };
    
    /** 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, APLOGNO(01375) "%s", 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, APLOGNO(01376)
                              "%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 == filter_init) {
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(01377)
                              "Chaining of FilterProviders not supported");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            else 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, APLOGNO(01378)
                                  "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;
        int match = 0;
        const char *err = NULL;
        request_rec *r = f->r;
        harness_ctx *ctx = f->ctx;
        provider_ctx *pctx;
    #ifndef NO_PROTOCOL
        unsigned int proto_flags;
        mod_filter_ctx *rctx = ap_get_module_config(r->request_config,
                                                    &filter_module);
    #endif
    
        /* Check registered providers in order */
        for (provider = filter->providers; provider; provider = provider->next) {
            if (provider->expr) {
                match = ap_expr_exec(r, provider->expr, &err);
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01379)
                                  "Error evaluating filter dispatch condition: %s",
                                  err);
                    match = 0;
                }
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "Expression condition for '%s' %s",
                              provider->frec->name,
                              match ? "matched" : "did not match");
            }
            else if (r->content_type) {
                const char **type = provider->types;
                size_t len = strcspn(r->content_type, "; \t");
                AP_DEBUG_ASSERT(type != NULL);
                ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                              "Content-Type '%s' ...", r->content_type);
                while (*type) {
                    /* Handle 'content-type;charset=...' correctly */
                    if (strncmp(*type, r->content_type, len) == 0
                        && (*type)[len] == '\0') {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                                      "... matched '%s'", *type);
                        match = 1;
                        break;
                    }
                    else {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                                      "... did not match '%s'", *type);
                    }
                    type++;
                }
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "Content-Type condition for '%s' %s",
                              provider->frec->name,
                              match ? "matched" : "did not match");
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                              "Content-Type condition for '%s' did not match: "
                              "no Content-Type", provider->frec->name);
            }
    
            if (match) {
                /* 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) {
                        const char *str = apr_table_get(r->headers_out,
                                                        "Cache-Control");
                        if (str) {
                            if (ap_strcasestr(str, "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_setn(r->headers_out, "Accept-Ranges", "none");
                }
                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;
    #ifndef NO_PROTOCOL
        const char *cachecontrol;
    #endif
        harness_ctx *ctx = f->ctx;
        ap_filter_rec_t *filter = f->frec;
    
        if (f->r->status != 200
            && !apr_table_get(f->r->subprocess_env, "filter-errordocs")) {
            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) {
                        if (ap_strcasestr(cachecontrol, "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);
            }
            AP_DEBUG_ASSERT(ctx->func != NULL);
        }
    
        /* 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->temp_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;
            }
            if (!strcasecmp(arg, "change=no")) {
                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 *add_filter(cmd_parms *cmd, void *CFG,
                                  const char *fname, const char *pname,
                                  const char *expr, const char **types)
    {
        mod_filter_cfg *cfg = CFG;
        ap_filter_provider_t *provider;
        const char *c;
        ap_filter_rec_t* frec;
        ap_filter_rec_t* provider_frec;
        ap_expr_info_t *node;
        const char *err = NULL;
    
        /* if provider has been registered, we can look it up */
        provider_frec = ap_get_output_filter_handle(pname);
        if (!provider_frec) {
            return apr_psprintf(cmd->pool, "Unknown filter provider %s", pname);
        }
    
        /* 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);
            frec->ftype = provider_frec->ftype;
        }
    
        if (!frec) {
            return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname);
        }
    
        provider = apr_palloc(cmd->pool, sizeof(ap_filter_provider_t));
        if (expr) {
            node = ap_expr_parse_cmd(cmd, expr, 0, &err, NULL);
            if (err) {
                return apr_pstrcat(cmd->pool,
                                   "Error parsing FilterProvider expression:", err,
                                   NULL);
            }
            provider->expr = node;
            provider->types = NULL;
        }
        else {
            provider->types = types;
            provider->expr = NULL;
        }
        provider->frec = provider_frec;
        provider->next = frec->providers;
        frec->providers = provider;
        return NULL;
    }
    
    static const char *filter_provider(cmd_parms *cmd, void *CFG,
                                       const char *fname, const char *pname,
                                       const char *expr)
    {
        return add_filter(cmd, CFG, fname, pname, expr, 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 */
                         /** IG: Add a NULL provider to the beginning so that
                          *  we can ensure that we'll empty everything before
                          *  this when doing config merges later */
            p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
            p->fname = NULL;
            cfg->chain = p;
            break;
    
        case '=':        /* initialise chain with this arg */
                         /** IG: Prepend a NULL provider to the beginning as above */
            p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
            p->fname = NULL;
            p->next = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
            p->next->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_bytype1(cmd_parms *cmd, void *CFG,
                                      const char *pname, const char **types)
    {
        const char *rv;
        const char *fname;
        int seen_name = 0;
        mod_filter_cfg *cfg = CFG;
    
        /* construct fname from name */
        fname = apr_pstrcat(cmd->pool, "BYTYPE:", pname, NULL);
    
        /* check whether this is already registered, in which case
         * it's already in the filter chain
         */
        if (apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING)) {
            seen_name = 1;
        }
    
        rv = add_filter(cmd, CFG, fname, pname, NULL, types);
    
        /* If it's the first time through, add to filterchain */
        if (rv == NULL && !seen_name) {
            rv = filter_chain(cmd, CFG, fname);
        }
        return rv;
    }
    
    static const char *filter_bytype(cmd_parms *cmd, void *CFG,
                                     int argc, char *const argv[])
    {
        /* back compatibility, need to parse multiple components in filter name */
        char *pname;
        char *strtok_state = NULL;
        char *name;
        const char **types;
        const char *rv = NULL;
        if (argc < 2)
            return "AddOutputFilterByType requires at least two arguments";
        name = apr_pstrdup(cmd->temp_pool, argv[0]);
        types = apr_palloc(cmd->pool, argc * sizeof(char *));
        memcpy(types, &argv[1], (argc - 1) * sizeof(char *));
        types[argc-1] = NULL;
        for (pname = apr_strtok(name, ";", &strtok_state);
             pname != NULL && rv == NULL;
             pname = apr_strtok(NULL, ";", &strtok_state)) {
            rv = filter_bytype1(cmd, CFG, pname, types);
        }
        return rv;
    }
    
    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
    
        /** IG: Now that we've merged to the final config, go one last time
         *  through the chain, and prune out the NULL filters */
    
        for (p = cfg->chain; p; p = p->next) {
            if (p->fname == NULL)
                cfg->chain = p->next;
        }
    
        for (p = cfg->chain; p; p = p->next) {
            filter = apr_hash_get(cfg->live_filters, p->fname, APR_HASH_KEY_STRING);
            if (filter == NULL) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01380)
                              "Unknown filter %s not added", p->fname);
                continue;
            }
            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
        }
    }
    
    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 (newlink->fname == NULL) {
                    conf->chain = savelink = newlink;
                }
                else 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));
                /** Filter out merged chain resets */
                if (newlink->fname == NULL) {
                    conf->chain = savelink = newlink;
                }
                else if (savelink) {
                    savelink->next = newlink;
                    savelink = newlink;
                }
                else {
                    conf->chain = 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]"),
        AP_INIT_TAKE3("FilterProvider", filter_provider, NULL, OR_OPTIONS,
            "filter-name provider-name match-expression"),
        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,
            "filter-name debug-level"),
        AP_INIT_TAKE_ARGV("AddOutputFilterByType", filter_bytype, NULL, OR_FILEINFO,
            "output filter name followed by one or more content-types"),
    #ifndef NO_PROTOCOL
        AP_INIT_TAKE23("FilterProtocol", filter_protocol, NULL, OR_OPTIONS,
            "filter-name [provider-name] protocol-args"),
    #endif
        { NULL }
    };
    
    AP_DECLARE_MODULE(filter) = {
        STANDARD20_MODULE_STUFF,
        filter_config,
        filter_merge,
        NULL,
        NULL,
        filter_cmds,
        filter_hooks
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_charset_lite.mak���������������������������������������������������0000664�0001751�0001751�00000024353�12701473373�021757� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_charset_lite.dsp
    !IF "$(CFG)" == ""
    CFG=mod_charset_lite - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_charset_lite - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_charset_lite - Win32 Release" && "$(CFG)" != "mod_charset_lite - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_charset_lite - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_charset_lite.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_charset_lite.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_charset_lite.obj"
    	-@erase "$(INTDIR)\mod_charset_lite.res"
    	-@erase "$(INTDIR)\mod_charset_lite_src.idb"
    	-@erase "$(INTDIR)\mod_charset_lite_src.pdb"
    	-@erase "$(OUTDIR)\mod_charset_lite.exp"
    	-@erase "$(OUTDIR)\mod_charset_lite.lib"
    	-@erase "$(OUTDIR)\mod_charset_lite.pdb"
    	-@erase "$(OUTDIR)\mod_charset_lite.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_charset_lite_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_charset_lite.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_charset_lite.so" /d LONG_NAME="charset_lite_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_charset_lite.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_charset_lite.pdb" /debug /out:"$(OUTDIR)\mod_charset_lite.so" /implib:"$(OUTDIR)\mod_charset_lite.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_charset_lite.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_charset_lite.obj" \
    	"$(INTDIR)\mod_charset_lite.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_charset_lite.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_charset_lite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_charset_lite.so"
       if exist .\Release\mod_charset_lite.so.manifest mt.exe -manifest .\Release\mod_charset_lite.so.manifest -outputresource:.\Release\mod_charset_lite.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_charset_lite - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_charset_lite.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_charset_lite.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_charset_lite.obj"
    	-@erase "$(INTDIR)\mod_charset_lite.res"
    	-@erase "$(INTDIR)\mod_charset_lite_src.idb"
    	-@erase "$(INTDIR)\mod_charset_lite_src.pdb"
    	-@erase "$(OUTDIR)\mod_charset_lite.exp"
    	-@erase "$(OUTDIR)\mod_charset_lite.lib"
    	-@erase "$(OUTDIR)\mod_charset_lite.pdb"
    	-@erase "$(OUTDIR)\mod_charset_lite.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_charset_lite_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_charset_lite.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_charset_lite.so" /d LONG_NAME="charset_lite_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_charset_lite.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_charset_lite.pdb" /debug /out:"$(OUTDIR)\mod_charset_lite.so" /implib:"$(OUTDIR)\mod_charset_lite.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_charset_lite.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_charset_lite.obj" \
    	"$(INTDIR)\mod_charset_lite.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_charset_lite.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_charset_lite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_charset_lite.so"
       if exist .\Debug\mod_charset_lite.so.manifest mt.exe -manifest .\Debug\mod_charset_lite.so.manifest -outputresource:.\Debug\mod_charset_lite.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_charset_lite.dep")
    !INCLUDE "mod_charset_lite.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_charset_lite.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_charset_lite - Win32 Release" || "$(CFG)" == "mod_charset_lite - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_charset_lite - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_charset_lite - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_charset_lite - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_charset_lite - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_charset_lite - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_charset_lite - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_charset_lite - Win32 Release"
    
    
    "$(INTDIR)\mod_charset_lite.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_charset_lite.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_charset_lite.so" /d LONG_NAME="charset_lite_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_charset_lite - Win32 Debug"
    
    
    "$(INTDIR)\mod_charset_lite.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_charset_lite.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_charset_lite.so" /d LONG_NAME="charset_lite_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_charset_lite.c
    
    "$(INTDIR)\mod_charset_lite.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_filter.mak���������������������������������������������������������0000664�0001751�0001751�00000023341�12701473373�020572� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_filter.dsp
    !IF "$(CFG)" == ""
    CFG=mod_filter - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_filter - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_filter - Win32 Release" && "$(CFG)" != "mod_filter - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_filter.mak" CFG="mod_filter - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_filter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_filter - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_filter - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_filter.obj"
    	-@erase "$(INTDIR)\mod_filter.res"
    	-@erase "$(INTDIR)\mod_filter_src.idb"
    	-@erase "$(INTDIR)\mod_filter_src.pdb"
    	-@erase "$(OUTDIR)\mod_filter.exp"
    	-@erase "$(OUTDIR)\mod_filter.lib"
    	-@erase "$(OUTDIR)\mod_filter.pdb"
    	-@erase "$(OUTDIR)\mod_filter.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_filter_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_filter.so" /d LONG_NAME="filter_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_filter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_filter.pdb" /debug /out:"$(OUTDIR)\mod_filter.so" /implib:"$(OUTDIR)\mod_filter.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_filter.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_filter.obj" \
    	"$(INTDIR)\mod_filter.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_filter.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_filter.so"
       if exist .\Release\mod_filter.so.manifest mt.exe -manifest .\Release\mod_filter.so.manifest -outputresource:.\Release\mod_filter.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_filter - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_filter.obj"
    	-@erase "$(INTDIR)\mod_filter.res"
    	-@erase "$(INTDIR)\mod_filter_src.idb"
    	-@erase "$(INTDIR)\mod_filter_src.pdb"
    	-@erase "$(OUTDIR)\mod_filter.exp"
    	-@erase "$(OUTDIR)\mod_filter.lib"
    	-@erase "$(OUTDIR)\mod_filter.pdb"
    	-@erase "$(OUTDIR)\mod_filter.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_filter_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_filter.so" /d LONG_NAME="filter_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_filter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_filter.pdb" /debug /out:"$(OUTDIR)\mod_filter.so" /implib:"$(OUTDIR)\mod_filter.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_filter.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_filter.obj" \
    	"$(INTDIR)\mod_filter.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_filter.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_filter.so"
       if exist .\Debug\mod_filter.so.manifest mt.exe -manifest .\Debug\mod_filter.so.manifest -outputresource:.\Debug\mod_filter.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_filter.dep")
    !INCLUDE "mod_filter.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_filter.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_filter - Win32 Release" || "$(CFG)" == "mod_filter - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_filter - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_filter - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_filter - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_filter - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_filter - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_filter - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_filter - Win32 Release"
    
    
    "$(INTDIR)\mod_filter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_filter.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_filter.so" /d LONG_NAME="filter_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_filter - Win32 Debug"
    
    
    "$(INTDIR)\mod_filter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_filter.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_filter.so" /d LONG_NAME="filter_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_filter.c
    
    "$(INTDIR)\mod_filter.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reflector.mak������������������������������������������������������0000664�0001751�0001751�00000024035�12701473373�021273� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_reflector.dsp
    !IF "$(CFG)" == ""
    CFG=mod_reflector - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_reflector - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_reflector - Win32 Release" && "$(CFG)" != "mod_reflector - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_reflector.mak" CFG="mod_reflector - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_reflector - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_reflector - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_reflector - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_reflector.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_reflector.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_reflector.obj"
    	-@erase "$(INTDIR)\mod_reflector.res"
    	-@erase "$(INTDIR)\mod_reflector_src.idb"
    	-@erase "$(INTDIR)\mod_reflector_src.pdb"
    	-@erase "$(OUTDIR)\mod_reflector.exp"
    	-@erase "$(OUTDIR)\mod_reflector.lib"
    	-@erase "$(OUTDIR)\mod_reflector.pdb"
    	-@erase "$(OUTDIR)\mod_reflector.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_reflector_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_reflector.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_reflector.so" /d LONG_NAME="reflector_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_reflector.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_reflector.pdb" /debug /out:"$(OUTDIR)\mod_reflector.so" /implib:"$(OUTDIR)\mod_reflector.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_reflector.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_reflector.obj" \
    	"$(INTDIR)\mod_reflector.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_reflector.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_reflector.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_reflector.so"
       if exist .\Release\mod_reflector.so.manifest mt.exe -manifest .\Release\mod_reflector.so.manifest -outputresource:.\Release\mod_reflector.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_reflector - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_reflector.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_reflector.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_reflector.obj"
    	-@erase "$(INTDIR)\mod_reflector.res"
    	-@erase "$(INTDIR)\mod_reflector_src.idb"
    	-@erase "$(INTDIR)\mod_reflector_src.pdb"
    	-@erase "$(OUTDIR)\mod_reflector.exp"
    	-@erase "$(OUTDIR)\mod_reflector.lib"
    	-@erase "$(OUTDIR)\mod_reflector.pdb"
    	-@erase "$(OUTDIR)\mod_reflector.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_reflector_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_reflector.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_reflector.so" /d LONG_NAME="reflector_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_reflector.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_reflector.pdb" /debug /out:"$(OUTDIR)\mod_reflector.so" /implib:"$(OUTDIR)\mod_reflector.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_reflector.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_reflector.obj" \
    	"$(INTDIR)\mod_reflector.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_reflector.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_reflector.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_reflector.so"
       if exist .\Debug\mod_reflector.so.manifest mt.exe -manifest .\Debug\mod_reflector.so.manifest -outputresource:.\Debug\mod_reflector.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_reflector.dep")
    !INCLUDE "mod_reflector.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_reflector.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_reflector - Win32 Release" || "$(CFG)" == "mod_reflector - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_reflector - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_reflector - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_reflector - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_reflector - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_reflector - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_reflector - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_reflector - Win32 Release"
    
    
    "$(INTDIR)\mod_reflector.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_reflector.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_reflector.so" /d LONG_NAME="reflector_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_reflector - Win32 Debug"
    
    
    "$(INTDIR)\mod_reflector.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_reflector.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_reflector.so" /d LONG_NAME="reflector_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_reflector.c
    
    "$(INTDIR)\mod_reflector.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_deflate.c����������������������������������������������������������0000664�0001751�0001751�00000215037�14600561366�020370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "http_core.h"
    #include "apr_lib.h"
    #include "apr_strings.h"
    #include "apr_general.h"
    #include "util_filter.h"
    #include "apr_buckets.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "http_ssl.h"
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    #include "zlib.h"
    
    static const char deflateFilterName[] = "DEFLATE";
    module AP_MODULE_DECLARE_DATA deflate_module;
    
    #define AP_INFLATE_RATIO_LIMIT 200
    #define AP_INFLATE_RATIO_BURST 3
    
    #define AP_DEFLATE_ETAG_ADDSUFFIX 0
    #define AP_DEFLATE_ETAG_NOCHANGE  1
    #define AP_DEFLATE_ETAG_REMOVE    2
    
    typedef struct deflate_filter_config_t
    {
        int windowSize;
        int memlevel;
        int compressionlevel;
        int bufferSize;
        const char *note_ratio_name;
        const char *note_input_name;
        const char *note_output_name;
        int etag_opt;
    } deflate_filter_config;
    
    typedef struct deflate_dirconf_t {
        apr_off_t inflate_limit;
        int ratio_limit,
            ratio_burst;
    } deflate_dirconf_t;
    
    /* 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
    
    /* Check whether a request is gzipped, so we can un-gzip it.
     * If a request has multiple encodings, we need the gzip
     * to be the outermost non-identity encoding.
     */
    static int check_gzip(request_rec *r, apr_table_t *hdrs1, apr_table_t *hdrs2)
    {
        int found = 0;
        apr_table_t *hdrs = hdrs1;
        const char *encoding = apr_table_get(hdrs, "Content-Encoding");
    
        if (!encoding && (hdrs2 != NULL)) {
            /* the output filter has two tables and a content_encoding to check */
            encoding = apr_table_get(hdrs2, "Content-Encoding");
            hdrs = hdrs2;
            if (!encoding) {
                encoding = r->content_encoding;
                hdrs = NULL;
            }
        }
        if (encoding && *encoding) {
    
            /* check the usual/simple case first */
            if (!ap_cstr_casecmp(encoding, "gzip")
                || !ap_cstr_casecmp(encoding, "x-gzip")) {
                found = 1;
                if (hdrs) {
                    apr_table_unset(hdrs, "Content-Encoding");
                }
                else {
                    r->content_encoding = NULL;
                }
            }
            else if (ap_strchr_c(encoding, ',') != NULL) {
                /* If the outermost encoding isn't gzip, there's nothing
                 * we can do.  So only check the last non-identity token
                 */
                char *new_encoding = apr_pstrdup(r->pool, encoding);
                char *ptr;
                for(;;) {
                    char *token = ap_strrchr(new_encoding, ',');
                    if (!token) {        /* gzip:identity or other:identity */
                        if (!ap_cstr_casecmp(new_encoding, "gzip")
                            || !ap_cstr_casecmp(new_encoding, "x-gzip")) {
                            found = 1;
                            if (hdrs) {
                                apr_table_unset(hdrs, "Content-Encoding");
                            }
                            else {
                                r->content_encoding = NULL;
                            }
                        }
                        break; /* seen all tokens */
                    }
                    for (ptr=token+1; apr_isspace(*ptr); ++ptr);
                    if (!ap_cstr_casecmp(ptr, "gzip")
                        || !ap_cstr_casecmp(ptr, "x-gzip")) {
                        *token = '\0';
                        if (hdrs) {
                            apr_table_setn(hdrs, "Content-Encoding", new_encoding);
                        }
                        else {
                            r->content_encoding = new_encoding;
                        }
                        found = 1;
                    }
                    else if (!ptr[0] || !ap_cstr_casecmp(ptr, "identity")) {
                        *token = '\0';
                        continue; /* strip the token and find the next one */
                    }
                    break; /* found a non-identity token */
                }
            }
        }
        /*
         * If we have dealt with the headers above but content_encoding was set
         * before sync it with the new value in the hdrs table as
         * r->content_encoding takes precedence later on in the http_header_filter
         * and hence would destroy what we have just set in the hdrs table.
         */
        if (hdrs && r->content_encoding) {
            r->content_encoding = apr_table_get(hdrs, "Content-Encoding");
        }
        return found;
    }
    
    /* 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 void *create_deflate_dirconf(apr_pool_t *p, char *dummy)
    {
        deflate_dirconf_t *dc = apr_pcalloc(p, sizeof(*dc));
        dc->ratio_limit = AP_INFLATE_RATIO_LIMIT;
        dc->ratio_burst = AP_INFLATE_RATIO_BURST;
        return dc;
    }
    
    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 = 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 = arg1;
        }
        else if (!strcasecmp(arg1, "ratio")) {
            c->note_ratio_name = arg2;
        }
        else if (!strcasecmp(arg1, "input")) {
            c->note_input_name = arg2;
        }
        else if (!strcasecmp(arg1, "output")) {
            c->note_output_name = 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_etag(cmd_parms *cmd, void *dummy,
                                            const char *arg)
    {
        deflate_filter_config *c = ap_get_module_config(cmd->server->module_config,
                                                        &deflate_module);
    
        if (!strcasecmp(arg, "NoChange")) { 
          c->etag_opt = AP_DEFLATE_ETAG_NOCHANGE;
        }
        else if (!strcasecmp(arg, "AddSuffix")) { 
          c->etag_opt = AP_DEFLATE_ETAG_ADDSUFFIX;
        }
        else if (!strcasecmp(arg, "Remove")) { 
          c->etag_opt = AP_DEFLATE_ETAG_REMOVE;
        }
        else { 
            return "DeflateAlterETAG accepts only 'NoChange', 'AddSuffix', and 'Remove'";
        }
    
        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;
    }
    
    
    static const char *deflate_set_inflate_limit(cmd_parms *cmd, void *dirconf,
                                          const char *arg)
    {
        deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf;
        char *errp;
    
        if (APR_SUCCESS != apr_strtoff(&dc->inflate_limit, arg, &errp, 10)) {
            return "DeflateInflateLimitRequestBody is not parsable.";
        }
        if (*errp || dc->inflate_limit < 0) {
            return "DeflateInflateLimitRequestBody requires a non-negative integer.";
        }
    
        return NULL;
    }
    
    static const char *deflate_set_inflate_ratio_limit(cmd_parms *cmd,
                                                       void *dirconf,
                                                       const char *arg)
    {
        deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf;
        int i;
    
        i = atoi(arg);
        if (i <= 0)
            return "DeflateInflateRatioLimit must be positive";
    
        dc->ratio_limit = i;
    
        return NULL;
    }
    
    static const char *deflate_set_inflate_ratio_burst(cmd_parms *cmd,
                                                       void *dirconf,
                                                       const char *arg)
    {
        deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf;
        int i;
    
        i = atoi(arg);
        if (i <= 0)
            return "DeflateInflateRatioBurst must be positive";
    
        dc->ratio_burst = i;
    
        return NULL;
    }
    
    typedef struct deflate_ctx_t
    {
        z_stream stream;
        unsigned char *buffer;
        unsigned long crc;
        apr_bucket_brigade *bb, *proc_bb;
        int (*libz_end_func)(z_streamp);
        unsigned char *validation_buffer;
        apr_size_t validation_buffer_length;
        char header[10]; /* sizeof(gzip_header) */
        apr_size_t header_len;
        int zlib_flags;
        int ratio_hits;
        apr_off_t inflate_total;
        unsigned int consume_pos,
                     consume_len;
        unsigned int filter_init:1;
        unsigned int done:1;
    } deflate_ctx;
    
    /* Number of validation bytes (CRC and length) after the compressed data */
    #define VALIDATION_SIZE 8
    /* Do not update ctx->crc, see comment in flush_libz_buffer */
    #define NO_UPDATE_CRC 0
    /* Do update ctx->crc, see comment in flush_libz_buffer */
    #define UPDATE_CRC 1
    
    static void consume_buffer(deflate_ctx *ctx, deflate_filter_config *c,
                               int len, int crc, apr_bucket_brigade *bb)
    {
        apr_bucket *b;
    
        /*
         * Do we need to update ctx->crc? Usually this is the case for
         * inflate action where we need to do a crc on the output, whereas
         * in the deflate case we need to do a crc on the input
         */
        if (crc) {
            ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
        }
    
        b = apr_bucket_heap_create((char *)ctx->buffer, len, NULL,
                                   bb->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
    
        ctx->stream.next_out = ctx->buffer;
        ctx->stream.avail_out = c->bufferSize;
    }
    
    static int flush_libz_buffer(deflate_ctx *ctx, deflate_filter_config *c,
                                 int (*libz_func)(z_streamp, int), int flush,
                                 int crc)
    {
        int zRC = Z_OK;
        int done = 0;
        int deflate_len;
    
        for (;;) {
             deflate_len = c->bufferSize - ctx->stream.avail_out;
             if (deflate_len > 0) {
                 consume_buffer(ctx, c, deflate_len, crc, ctx->bb);
             }
    
             if (done)
                 break;
    
             zRC = libz_func(&ctx->stream, flush);
    
             /*
              * We can ignore Z_BUF_ERROR because:
              * When we call libz_func we can assume that
              *
              * - avail_in is zero (due to the surrounding code that calls
              *   flush_libz_buffer)
              * - avail_out is non zero due to our actions some lines above
              *
              * So the only reason for Z_BUF_ERROR is that the internal libz
              * buffers are now empty and thus we called libz_func one time
              * too often. This does not hurt. It simply says that we are done.
              */
             if (zRC == Z_BUF_ERROR) {
                 zRC = Z_OK;
                 break;
             }
    
             done = (ctx->stream.avail_out != 0 || zRC == Z_STREAM_END);
    
             if (zRC != Z_OK && zRC != Z_STREAM_END)
                 break;
        }
        return zRC;
    }
    
    static apr_status_t deflate_ctx_cleanup(void *data)
    {
        deflate_ctx *ctx = (deflate_ctx *)data;
    
        if (ctx)
            ctx->libz_end_func(&ctx->stream);
        return APR_SUCCESS;
    }
    
    /* ETag must be unique among the possible representations, so a change
     * to content-encoding requires a corresponding change to the ETag.
     * This routine appends -transform (e.g., -gzip) to the entity-tag
     * value inside the double-quotes if an ETag has already been set
     * and its value already contains double-quotes. PR 39727
     */
    static void deflate_check_etag(request_rec *r, const char *transform, int etag_opt)
    {
        const char *etag = apr_table_get(r->headers_out, "ETag");
        apr_size_t etaglen;
    
        if (etag_opt == AP_DEFLATE_ETAG_REMOVE) { 
            apr_table_unset(r->headers_out, "ETag");
            return;
        }
    
        if ((etag && ((etaglen = strlen(etag)) > 2))) {
            if (etag[etaglen - 1] == '"') {
                apr_size_t transformlen = strlen(transform);
                char *newtag = apr_palloc(r->pool, etaglen + transformlen + 2);
                char *d = newtag;
                char *e = d + etaglen - 1;
                const char *s = etag;
    
                for (; d < e; ++d, ++s) {
                    *d = *s;          /* copy etag to newtag up to last quote */
                }
                *d++ = '-';           /* append dash to newtag */
                s = transform;
                e = d + transformlen;
                for (; d < e; ++d, ++s) {
                    *d = *s;          /* copy transform to newtag */
                }
                *d++ = '"';           /* append quote to newtag */
                *d   = '\0';          /* null terminate newtag */
    
                apr_table_setn(r->headers_out, "ETag", newtag);
            }
        }
    }
    
    /* Check whether the (inflate) ratio exceeds the configured limit/burst. */
    static int check_ratio(request_rec *r, deflate_ctx *ctx,
                           const deflate_dirconf_t *dc)
    {
        if (ctx->stream.total_in) {
            int ratio = ctx->stream.total_out / ctx->stream.total_in;
            if (ratio < dc->ratio_limit) {
                ctx->ratio_hits = 0;
            }
            else if (++ctx->ratio_hits > dc->ratio_burst) {
                return 0;
            }
        }
        return 1;
    }
    
    static int have_ssl_compression(request_rec *r)
    {
        const char *comp;
        comp = ap_ssl_var_lookup(r->pool, r->server, r->connection, r,
                                 "SSL_COMPRESS_METHOD");
        if (comp == NULL || *comp == '\0' || strcmp(comp, "NULL") == 0)
            return 0;
        return 1;
    }
    
    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;
        apr_status_t rv;
        apr_size_t len = 0, blen;
        const char *data;
        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 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;
    
            if (have_ssl_compression(r)) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "Compression enabled at SSL level; not compressing "
                              "at HTTP level.");
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /* We have checked above that bb is not empty */
            e = APR_BRIGADE_LAST(bb);
            if (APR_BUCKET_IS_EOS(e)) {
                /*
                 * If we already know the size of the response, we can skip
                 * compression on responses smaller than the compression overhead.
                 * However, if we compress, we must initialize deflate_out before
                 * calling ap_pass_brigade() for the first time.  Otherwise the
                 * headers will be sent to the client without
                 * "Content-Encoding: gzip".
                 */
                e = APR_BRIGADE_FIRST(bb);
                while (1) {
                    apr_status_t rc;
                    if (APR_BUCKET_IS_EOS(e)) {
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                      "Not compressing very small response of %"
                                      APR_SIZE_T_FMT " bytes", len);
                        ap_remove_output_filter(f);
                        return ap_pass_brigade(f->next, bb);
                    }
                    if (APR_BUCKET_IS_METADATA(e)) {
                        e = APR_BUCKET_NEXT(e);
                        continue;
                    }
    
                    if (e->length == (apr_size_t)-1) {
                        rc = apr_bucket_read(e, &data, &blen, APR_BLOCK_READ);
                        if (rc != APR_SUCCESS)
                            return rc;
                    }
                    else {
                        blen = e->length;
                    }
                    len += blen;
                    /* 50 is for Content-Encoding and Vary headers and ETag suffix */
                    if (len > sizeof(gzip_header) + VALIDATION_SIZE + 50)
                        break;
    
                    e = APR_BUCKET_NEXT(e);
                }
            }
    
            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
    
            /*
             * Only work on main request, not subrequests,
             * that are not a 204 response with no content
             * and are not tagged with the no-gzip env variable
             * and not a partial response to a Range request.
             *
             * Note that responding to 304 is handled separately to
             * set the required headers (such as ETag) per RFC7232, 4.1.
             */
            if ((r->main != NULL) || (r->status == HTTP_NO_CONTENT) ||
                apr_table_get(r->subprocess_env, "no-gzip") ||
                apr_table_get(r->headers_out, "Content-Range")
               ) {
                if (APLOG_R_IS_LEVEL(r, APLOG_TRACE1)) {
                    const char *reason =
                        (r->main != NULL)                           ? "subrequest" :
                        (r->status == HTTP_NO_CONTENT)              ? "no content" :
                        apr_table_get(r->subprocess_env, "no-gzip") ? "no-gzip" :
                        "content-range";
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                  "Not compressing (%s)", reason);
                }
                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_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                  "Not compressing, (gzip-only-text/html)");
                    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_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                      "Not compressing (content-encoding already "
                                      " set: %s)", token);
                        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;
                const char *q = NULL;
    
                /* 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] && ap_cstr_casecmp(token, "gzip")) {
                    /* skip parameters, XXX: ;q=foo evaluation? */
                    while (*accepts == ';') {
                        ++accepts;
                        ap_get_token(r->pool, &accepts, 1);
                    }
    
                    /* retrieve next token */
                    if (*accepts == ',') {
                        ++accepts;
                    }
                    token = (*accepts) ? ap_get_token(r->pool, &accepts, 0) : NULL;
                }
    
                /* Find the qvalue, if provided */
                if (*accepts) {
                    while (*accepts == ';') {
                        ++accepts;
                    }
                    q = ap_get_token(r->pool, &accepts, 1);
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                  "token: '%s' - q: '%s'", token ? token : "NULL", q);
                }
    
                /* No acceptable token found or q=0 */
                if (!token || token[0] == '\0' ||
                    (q && strlen(q) >= 3 && strncmp("q=0.000", q, strlen(q)) == 0)) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                  "Not compressing (no Accept-Encoding: gzip or q=0)");
                    ap_remove_output_filter(f);
                    return ap_pass_brigade(f->next, bb);
                }
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "Forcing compression (force-gzip set)");
            }
    
            /* At this point we have decided to filter the content. Let's try to
             * to initialize zlib (except for 304 responses, where we will only
             * send out the headers).
             */
    
            if (r->status != HTTP_NOT_MODIFIED) {
                ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
                ctx->buffer = apr_palloc(r->pool, c->bufferSize);
                ctx->libz_end_func = deflateEnd;
    
                zRC = deflateInit2(&ctx->stream, c->compressionlevel, Z_DEFLATED,
                                   c->windowSize, c->memlevel,
                                   Z_DEFAULT_STRATEGY);
    
                if (zRC != Z_OK) {
                    deflateEnd(&ctx->stream);
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01383)
                                  "unable to init Zlib: "
                                  "deflateInit2 returned %d: URL %s",
                                  zRC, r->uri);
                    /*
                     * Remove ourselves as it does not make sense to return:
                     * We are not able to init libz and pass data down the chain
                     * uncompressed.
                     */
                    ap_remove_output_filter(f);
                    return ap_pass_brigade(f->next, bb);
                }
                /*
                 * Register a cleanup function to ensure that we cleanup the internal
                 * libz resources.
                 */
                apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup,
                                          apr_pool_cleanup_null);
    
                /* Set the filter init flag so subsequent invocations know we are
                 * active.
                 */
                ctx->filter_init = 1;
            }
    
            /*
             * Zlib initialization worked, so we can now change the important
             * content metadata before sending the response out.
             */
    
            /* If the entire Content-Encoding is "identity", we can replace it. */
            if (!encoding || !ap_cstr_casecmp(encoding, "identity")) {
                apr_table_setn(r->headers_out, "Content-Encoding", "gzip");
            }
            else {
                apr_table_mergen(r->headers_out, "Content-Encoding", "gzip");
            }
            /* Fix r->content_encoding if it was set before */
            if (r->content_encoding) {
                r->content_encoding = apr_table_get(r->headers_out,
                                                    "Content-Encoding");
            }
            apr_table_unset(r->headers_out, "Content-Length");
            apr_table_unset(r->headers_out, "Content-MD5");
            if (c->etag_opt != AP_DEFLATE_ETAG_NOCHANGE) {  
                deflate_check_etag(r, "gzip", c->etag_opt);
            }
    
            /* For a 304 response, only change the headers */
            if (r->status == HTTP_NOT_MODIFIED) {
                ap_remove_output_filter(f);
                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);
    
            /* initialize deflate output buffer */
            ctx->stream.next_out = ctx->buffer;
            ctx->stream.avail_out = c->bufferSize;
        } else if (!ctx->filter_init) {
            /* Hmm.  We've run through the filter init before as we have a ctx,
             * but we never initialized.  We probably have a dangling ref.  Bail.
             */
            return ap_pass_brigade(f->next, bb);
        }
    
        while (!APR_BRIGADE_EMPTY(bb))
        {
            apr_bucket *b;
    
            /*
             * Optimization: If we are a HEAD request and bytes_sent is not zero
             * it means that we have passed the content-length filter once and
             * have more data to sent. This means that the content-length filter
             * could not determine our content-length for the response to the
             * HEAD request anyway (the associated GET request would deliver the
             * body in chunked encoding) and we can stop compressing.
             */
            if (r->header_only && r->bytes_sent) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            e = APR_BRIGADE_FIRST(bb);
    
            if (APR_BUCKET_IS_EOS(e)) {
                char *buf;
    
                ctx->stream.avail_in = 0; /* should be zero already anyway */
                /* flush the remaining data from the zlib buffers */
                flush_libz_buffer(ctx, c, deflate, Z_FINISH, NO_UPDATE_CRC);
    
                buf = apr_palloc(r->pool, VALIDATION_SIZE);
                putLong((unsigned char *)&buf[0], ctx->crc);
                putLong((unsigned char *)&buf[4], ctx->stream.total_in);
    
                b = apr_bucket_pool_create(buf, VALIDATION_SIZE, r->pool,
                                           f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01384)
                              "Zlib: Compressed %" APR_UINT64_T_FMT
                              " to %" APR_UINT64_T_FMT " : URL %s",
                              (apr_uint64_t)ctx->stream.total_in,
                              (apr_uint64_t)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_out > 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);
    
                /* We've ended the libz stream, so remove ourselves. */
                ap_remove_output_filter(f);
    
                /* No need for cleanup any longer */
                apr_pool_cleanup_kill(r->pool, ctx, deflate_ctx_cleanup);
    
                /* 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.
                 */
                rv = ap_pass_brigade(f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                return rv;
            }
    
            if (APR_BUCKET_IS_FLUSH(e)) {
                /* flush the remaining data from the zlib buffers */
                zRC = flush_libz_buffer(ctx, c, deflate, Z_SYNC_FLUSH,
                                        NO_UPDATE_CRC);
                if (zRC != Z_OK) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01385)
                                  "Zlib error %d flushing zlib output buffer (%s)",
                                  zRC, ctx->stream.msg);
                    return APR_EGENERAL;
                }
    
                /* Remove flush bucket from old brigade anf insert into the new. */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                rv = ap_pass_brigade(f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
                continue;
            }
    
            if (APR_BUCKET_IS_METADATA(e)) {
                /*
                 * Remove meta data bucket from old brigade and insert into the
                 * new.
                 */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                continue;
            }
    
            /* read */
            rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
            if (rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10298)
                              "failed reading from %s bucket", e->type->name);
                return rv;
            }
            if (!len) {
                apr_bucket_delete(e);
                continue;
            }
            if (len > APR_INT32_MAX) {
                apr_bucket_split(e, APR_INT32_MAX);
                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 = (int)len;
    
            while (ctx->stream.avail_in != 0) {
                if (ctx->stream.avail_out == 0) {
                    consume_buffer(ctx, c, c->bufferSize, NO_UPDATE_CRC, ctx->bb);
    
                    /* Send what we have right now to the next filter. */
                    rv = ap_pass_brigade(f->next, ctx->bb);
                    apr_brigade_cleanup(ctx->bb);
                    if (rv != APR_SUCCESS) {
                        return rv;
                    }
                }
    
                zRC = deflate(&(ctx->stream), Z_NO_FLUSH);
    
                if (zRC != Z_OK) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01386)
                                  "Zlib error %d deflating data (%s)", zRC,
                                  ctx->stream.msg);
                    return APR_EGENERAL;
                }
            }
    
            apr_bucket_delete(e);
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t consume_zlib_flags(deflate_ctx *ctx,
                                           const char **data, apr_size_t *len)
    {
        if ((ctx->zlib_flags & EXTRA_FIELD)) {
            /* Consume 2 bytes length prefixed data. */
            if (ctx->consume_pos == 0) {
                if (!*len) {
                    return APR_INCOMPLETE;
                }
                ctx->consume_len = (unsigned int)**data;
                ctx->consume_pos++;
                ++*data;
                --*len;
            }
            if (ctx->consume_pos == 1) {
                if (!*len) {
                    return APR_INCOMPLETE;
                }
                ctx->consume_len += ((unsigned int)**data) << 8;
                ctx->consume_pos++;
                ++*data;
                --*len;
            }
            if (*len < ctx->consume_len) {
                ctx->consume_len -= *len;
                *len = 0;
                return APR_INCOMPLETE;
            }
            *data += ctx->consume_len;
            *len -= ctx->consume_len;
    
            ctx->consume_len = ctx->consume_pos = 0;
            ctx->zlib_flags &= ~EXTRA_FIELD;
        }
    
        if ((ctx->zlib_flags & ORIG_NAME)) {
            /* Consume nul terminated string. */
            while (*len && **data) {
                ++*data;
                --*len;
            }
            if (!*len) {
                return APR_INCOMPLETE;
            }
            /* .. and nul. */
            ++*data;
            --*len;
    
            ctx->zlib_flags &= ~ORIG_NAME;
        }
    
        if ((ctx->zlib_flags & COMMENT)) {
            /* Consume nul terminated string. */
            while (*len && **data) {
                ++*data;
                --*len;
            }
            if (!*len) {
                return APR_INCOMPLETE;
            }
            /* .. and nul. */
            ++*data;
            --*len;
    
            ctx->zlib_flags &= ~COMMENT;
        }
    
        if ((ctx->zlib_flags & HEAD_CRC)) {
            /* Consume CRC16 (2 octets). */
            if (ctx->consume_pos == 0) {
                if (!*len) {
                    return APR_INCOMPLETE;
                }
                ctx->consume_pos++;
                ++*data;
                --*len;
            }
            if (!*len) {
                return APR_INCOMPLETE;
            }
            ++*data;
            --*len;
            
            ctx->consume_pos = 0;
            ctx->zlib_flags &= ~HEAD_CRC;
        }
    
        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;
        deflate_dirconf_t *dc;
        apr_off_t inflate_limit;
    
        /* 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);
        dc = ap_get_module_config(r->per_dir_config, &deflate_module);
    
        if (!ctx || ctx->header_len < sizeof(ctx->header)) {
            apr_size_t len;
    
            if (!ctx) {
                /* 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);
                }
    
                /* We can't operate on Content-Ranges */
                if (apr_table_get(r->headers_in, "Content-Range") != NULL) {
                    ap_remove_input_filter(f);
                    return ap_get_brigade(f->next, bb, mode, block, readbytes);
                }
    
                /* Check whether request body is gzipped.
                 *
                 * If it is, we're transforming the contents, invalidating
                 * some request headers including Content-Encoding.
                 *
                 * If not, we just remove ourself.
                 */
                if (check_gzip(r, r->headers_in, NULL) == 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);
            }
    
            do {
                apr_brigade_cleanup(ctx->bb);
    
                len = sizeof(ctx->header) - ctx->header_len;
                rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block,
                                    len);
    
                /* ap_get_brigade may return success with an empty brigade for
                 * a non-blocking read which would block (an empty brigade for
                 * a blocking read is an issue which is simply forwarded here).
                 */
                if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(ctx->bb)) {
                    return rv;
                }
    
                /* zero length body? step aside */
                bkt = APR_BRIGADE_FIRST(ctx->bb);
                if (APR_BUCKET_IS_EOS(bkt)) {
                    if (ctx->header_len) {
                        /* If the header was (partially) read it's an error, this
                         * is not a gzip Content-Encoding, as claimed.
                         */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02619)
                                      "Encountered premature end-of-stream while "
                                      "reading inflate header");
                        return APR_EGENERAL;
                    }
                    APR_BUCKET_REMOVE(bkt);
                    APR_BRIGADE_INSERT_TAIL(bb, bkt);
                    ap_remove_input_filter(f);
                    return APR_SUCCESS;
                }
    
                rv = apr_brigade_flatten(ctx->bb,
                                         ctx->header + ctx->header_len, &len);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
                if (len && !ctx->header_len) {
                    apr_table_unset(r->headers_in, "Content-Length");
                    apr_table_unset(r->headers_in, "Content-MD5");
                }
                ctx->header_len += len;
    
            } while (ctx->header_len < sizeof(ctx->header));
    
            /* We didn't get the magic bytes. */
            if (ctx->header[0] != deflate_magic[0] ||
                ctx->header[1] != deflate_magic[1]) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01387)
                              "Zlib: Invalid header");
                return APR_EGENERAL;
            }
    
            ctx->zlib_flags = ctx->header[3];
            if ((ctx->zlib_flags & RESERVED)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01388)
                              "Zlib: Invalid flags %02x", ctx->zlib_flags);
                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, APLOGNO(01389)
                              "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);
        }
    
        inflate_limit = dc->inflate_limit; 
        if (inflate_limit == 0) { 
            /* The core is checking the deflated body, we'll check the inflated */
            inflate_limit = ap_get_limit_req_body(f->r);
        }
    
        if (APR_BRIGADE_EMPTY(ctx->proc_bb)) {
            rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes);
    
            /* Don't terminate on EAGAIN (or success with an empty brigade in
             * non-blocking mode), just return focus.
             */
            if (block == APR_NONBLOCK_READ
                    && (APR_STATUS_IS_EAGAIN(rv)
                        || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(ctx->bb)))) {
                return rv;
            }
            if (rv != APR_SUCCESS) {
                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 (APR_BUCKET_IS_EOS(bkt)) {
                    if (!ctx->done) {
                        inflateEnd(&ctx->stream);
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02481)
                                      "Encountered premature end-of-stream while inflating");
                        return APR_EGENERAL;
                    }
    
                    /* Move everything to the returning brigade. */
                    APR_BUCKET_REMOVE(bkt);
                    APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, bkt);
                    break;
                }
    
                if (APR_BUCKET_IS_FLUSH(bkt)) {
                    apr_bucket *tmp_b;
    
                    if (!ctx->done) {
                        ctx->inflate_total += ctx->stream.avail_out;
                        zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
                        ctx->inflate_total -= ctx->stream.avail_out;
                        if (zRC != Z_OK) {
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391)
                                          "Zlib error %d inflating data (%s)", zRC,
                                          ctx->stream.msg);
                            return APR_EGENERAL;
                        }
     
                        if (inflate_limit && ctx->inflate_total > inflate_limit) { 
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647)
                                          "Inflated content length of %" APR_OFF_T_FMT
                                          " is larger than the configured limit"
                                          " of %" APR_OFF_T_FMT, 
                                          ctx->inflate_total, inflate_limit);
                            return APR_ENOSPC;
                        }
    
                        if (!check_ratio(r, ctx, dc)) {
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805)
                                          "Inflated content ratio is larger than the "
                                          "configured limit %i by %i time(s)",
                                          dc->ratio_limit, dc->ratio_burst);
                            return APR_EINVAL;
                        }
    
                        consume_buffer(ctx, c, c->bufferSize - ctx->stream.avail_out,
                                       UPDATE_CRC, ctx->proc_bb);
                    }
    
                    /* Flush everything so far in the returning brigade, but continue
                     * reading should EOS/more follow (don't lose them).
                     */
                    tmp_b = APR_BUCKET_PREV(bkt);
                    APR_BUCKET_REMOVE(bkt);
                    APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, bkt);
                    bkt = tmp_b;
                    continue;
                }
    
                /* sanity check - data after completed compressed body and before eos? */
                if (ctx->done) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02482)
                                  "Encountered extra data after compressed data");
                    return APR_EGENERAL;
                }
    
                /* read */
                apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ);
                if (!len) {
                    continue;
                }
                if (len > APR_INT32_MAX) {
                    apr_bucket_split(bkt, APR_INT32_MAX);
                    apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ);
                }
    
                if (ctx->zlib_flags) {
                    rv = consume_zlib_flags(ctx, &data, &len);
                    if (rv == APR_SUCCESS) {
                        ctx->zlib_flags = 0;
                    }
                    if (!len) {
                        continue;
                    }
                }
    
                /* pass through zlib inflate. */
                ctx->stream.next_in = (unsigned char *)data;
                ctx->stream.avail_in = (int)len;
    
                if (!ctx->validation_buffer) {
                    while (ctx->stream.avail_in != 0) {
                        if (ctx->stream.avail_out == 0) {
                            consume_buffer(ctx, c, c->bufferSize, UPDATE_CRC,
                                           ctx->proc_bb);
                        }
    
                        ctx->inflate_total += ctx->stream.avail_out;
                        zRC = inflate(&ctx->stream, Z_NO_FLUSH);
                        ctx->inflate_total -= ctx->stream.avail_out;
                        if (zRC != Z_OK && zRC != Z_STREAM_END) {
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01392)
                                          "Zlib error %d inflating data (%s)", zRC,
                                          ctx->stream.msg);
                            return APR_EGENERAL;
                        }
    
                        if (inflate_limit && ctx->inflate_total > inflate_limit) { 
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02648)
                                    "Inflated content length of %" APR_OFF_T_FMT
                                    " is larger than the configured limit"
                                    " of %" APR_OFF_T_FMT, 
                                    ctx->inflate_total, inflate_limit);
                            return APR_ENOSPC;
                        }
    
                        if (!check_ratio(r, ctx, dc)) {
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02649)
                                    "Inflated content ratio is larger than the "
                                    "configured limit %i by %i time(s)",
                                    dc->ratio_limit, dc->ratio_burst);
                            return APR_EINVAL;
                        }
    
                        if (zRC == Z_STREAM_END) {
                            ctx->validation_buffer = apr_pcalloc(r->pool,
                                                                 VALIDATION_SIZE);
                            ctx->validation_buffer_length = 0;
                            break;
                        }
                    }
                }
    
                if (ctx->validation_buffer) {
                    apr_size_t avail, valid;
                    unsigned char *buf = ctx->validation_buffer;
    
                    avail = ctx->stream.avail_in;
                    valid = (apr_size_t)VALIDATION_SIZE -
                             ctx->validation_buffer_length;
    
                    /*
                     * We have inflated all data. Now try to capture the
                     * validation bytes. We may not have them all available
                     * right now, but capture what is there.
                     */
                    if (avail < valid) {
                        memcpy(buf + ctx->validation_buffer_length,
                               ctx->stream.next_in, avail);
                        ctx->validation_buffer_length += avail;
                        continue;
                    }
                    memcpy(buf + ctx->validation_buffer_length,
                           ctx->stream.next_in, valid);
                    ctx->validation_buffer_length += valid;
    
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01393)
                                  "Zlib: Inflated %" APR_UINT64_T_FMT
                                  " to %" APR_UINT64_T_FMT " : URL %s",
                                  (apr_uint64_t)ctx->stream.total_in,
                                  (apr_uint64_t)ctx->stream.total_out, r->uri);
    
                    consume_buffer(ctx, c, c->bufferSize - ctx->stream.avail_out,
                                   UPDATE_CRC, ctx->proc_bb);
    
                    {
                        unsigned long compCRC, compLen;
                        compCRC = getLong(buf);
                        if (ctx->crc != compCRC) {
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01394)
                                          "Zlib: CRC error inflating data");
                            return APR_EGENERAL;
                        }
                        compLen = getLong(buf + VALIDATION_SIZE / 2);
                        /* gzip stores original size only as 4 byte value */
                        if ((ctx->stream.total_out & 0xFFFFFFFF) != compLen) {
                            inflateEnd(&ctx->stream);
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01395)
                                          "Zlib: Length %" APR_UINT64_T_FMT
                                          " of inflated data does not match"
                                          " expected value %ld",
                                          (apr_uint64_t)ctx->stream.total_out, compLen);
                            return APR_EGENERAL;
                        }
                    }
    
                    inflateEnd(&ctx->stream);
    
                    ctx->done = 1;
    
                    /* Did we have trailing data behind the closing 8 bytes? */
                    if (avail > valid) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02485)
                                      "Encountered extra data after compressed data");
                        return APR_EGENERAL;
                    }
                }
    
            }
            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) {
            consume_buffer(ctx, c, c->bufferSize - ctx->stream.avail_out,
                           UPDATE_CRC, ctx->proc_bb);
        }
    
        if (!APR_BRIGADE_EMPTY(ctx->proc_bb)) {
            if (apr_brigade_partition(ctx->proc_bb, readbytes, &bkt) == APR_INCOMPLETE) {
                APR_BRIGADE_CONCAT(bb, ctx->proc_bb);
            }
            else {
                APR_BRIGADE_CONCAT(bb, ctx->proc_bb);
                apr_brigade_split_ex(bb, bkt, ctx->proc_bb);
            }
            if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
                ap_remove_input_filter(f);
            }
        }
    
        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)
    {
        apr_bucket *e;
        request_rec *r = f->r;
        deflate_ctx *ctx = f->ctx;
        int zRC;
        apr_status_t rv;
        deflate_filter_config *c;
        deflate_dirconf_t *dc;
    
        /* 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);
        dc = ap_get_module_config(r->per_dir_config, &deflate_module);
    
        if (!ctx) {
    
            /*
             * Only work on main request, not subrequests,
             * that are not a 204 response with no content
             * and not a partial response to a Range request,
             * and only when Content-Encoding ends in gzip.
             *
             * Note that responding to 304 is handled separately to
             * set the required headers (such as ETag) per RFC7232, 4.1.
             */
            if (!ap_is_initial_req(r) || (r->status == HTTP_NO_CONTENT) ||
                (apr_table_get(r->headers_out, "Content-Range") != NULL) ||
                (check_gzip(r, r->headers_out, r->err_headers_out) == 0)
               ) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /*
             * At this point we have decided to filter the content, so change
             * important content metadata before sending any response out.
             * Content-Encoding was already reset by the check_gzip() call.
             */
            apr_table_unset(r->headers_out, "Content-Length");
            apr_table_unset(r->headers_out, "Content-MD5");
            if (c->etag_opt != AP_DEFLATE_ETAG_NOCHANGE) {
                deflate_check_etag(r, "gunzip", c->etag_opt);
            }
    
            /* For a 304 response, only change the headers */
            if (r->status == HTTP_NOT_MODIFIED) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
            ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
            ctx->buffer = apr_palloc(r->pool, c->bufferSize);
            ctx->libz_end_func = inflateEnd;
            ctx->validation_buffer = NULL;
            ctx->validation_buffer_length = 0;
    
            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, APLOGNO(01397)
                              "unable to init Zlib: "
                              "inflateInit2 returned %d: URL %s",
                              zRC, r->uri);
                /*
                 * Remove ourselves as it does not make sense to return:
                 * We are not able to init libz and pass data down the chain
                 * compressed.
                 */
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            /*
             * Register a cleanup function to ensure that we cleanup the internal
             * libz resources.
             */
            apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup,
                                      apr_pool_cleanup_null);
    
            /* initialize inflate output buffer */
            ctx->stream.next_out = ctx->buffer;
            ctx->stream.avail_out = c->bufferSize;
        }
    
        while (!APR_BRIGADE_EMPTY(bb))
        {
            const char *data;
            apr_size_t len;
    
            e = APR_BRIGADE_FIRST(bb);
    
            if (APR_BUCKET_IS_EOS(e)) {
                /*
                 * We are really done now. Ensure that we never return here, even
                 * if a second EOS bucket falls down the chain. Thus remove
                 * ourselves.
                 */
                ap_remove_output_filter(f);
                /* should be zero already anyway */
                ctx->stream.avail_in = 0;
                /*
                 * Flush the remaining data from the zlib buffers. It is correct
                 * to use Z_SYNC_FLUSH in this case and not Z_FINISH as in the
                 * deflate case. In the inflate case Z_FINISH requires to have a
                 * large enough output buffer to put ALL data in otherwise it
                 * fails, whereas in the deflate case you can empty a filled output
                 * buffer and call it again until no more output can be created.
                 */
                flush_libz_buffer(ctx, c, inflate, Z_SYNC_FLUSH, UPDATE_CRC);
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01398)
                              "Zlib: Inflated %" APR_UINT64_T_FMT 
                              " to %" APR_UINT64_T_FMT " : URL %s",
                              (apr_uint64_t)ctx->stream.total_in,
                              (apr_uint64_t)ctx->stream.total_out, r->uri);
    
                if (ctx->validation_buffer_length == VALIDATION_SIZE) {
                    unsigned long compCRC, compLen;
                    compCRC = getLong(ctx->validation_buffer);
                    if (ctx->crc != compCRC) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01399)
                                      "Zlib: Checksum of inflated stream invalid");
                        return APR_EGENERAL;
                    }
                    ctx->validation_buffer += VALIDATION_SIZE / 2;
                    compLen = getLong(ctx->validation_buffer);
                    /* gzip stores original size only as 4 byte value */
                    if ((ctx->stream.total_out & 0xFFFFFFFF) != compLen) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01400)
                                      "Zlib: Length of inflated stream invalid");
                        return APR_EGENERAL;
                    }
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01401)
                                  "Zlib: Validation bytes not present");
                    return APR_EGENERAL;
                }
    
                inflateEnd(&ctx->stream);
                /* No need for cleanup any longer */
                apr_pool_cleanup_kill(r->pool, ctx, deflate_ctx_cleanup);
    
                /* 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.
                 */
                rv = ap_pass_brigade(f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                return rv;
            }
    
            if (APR_BUCKET_IS_FLUSH(e)) {
                /* flush the remaining data from the zlib buffers */
                zRC = flush_libz_buffer(ctx, c, inflate, Z_SYNC_FLUSH, UPDATE_CRC);
                if (zRC == Z_STREAM_END) {
                    if (ctx->validation_buffer == NULL) {
                        ctx->validation_buffer = apr_pcalloc(f->r->pool,
                                                             VALIDATION_SIZE);
                    }
                }
                else if (zRC != Z_OK) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01402)
                                  "Zlib error %d flushing inflate buffer (%s)",
                                  zRC, ctx->stream.msg);
                    return APR_EGENERAL;
                }
    
                /* Remove flush bucket from old brigade anf insert into the new. */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                rv = ap_pass_brigade(f->next, ctx->bb);
                apr_brigade_cleanup(ctx->bb);
                if (rv != APR_SUCCESS) {
                    return rv;
                }
                continue;
            }
    
            if (APR_BUCKET_IS_METADATA(e)) {
                /*
                 * Remove meta data bucket from old brigade and insert into the
                 * new.
                 */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                continue;
            }
    
            /* read */
            apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
            if (!len) {
                apr_bucket_delete(e);
                continue;
            }
            if (len > APR_INT32_MAX) {
                apr_bucket_split(e, APR_INT32_MAX);
                apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
            }
    
            /* first bucket contains zlib header */
            if (ctx->header_len < sizeof(ctx->header)) {
                apr_size_t rem;
    
                rem = sizeof(ctx->header) - ctx->header_len;
                if (len < rem) {
                    memcpy(ctx->header + ctx->header_len, data, len);
                    ctx->header_len += len;
                    apr_bucket_delete(e);
                    continue;
                }
                memcpy(ctx->header + ctx->header_len, data, rem);
                ctx->header_len += rem;
                {
                    int zlib_method;
                    zlib_method = ctx->header[2];
                    if (zlib_method != Z_DEFLATED) {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01404)
                                      "inflate: data not deflated!");
                        ap_remove_output_filter(f);
                        return ap_pass_brigade(f->next, bb);
                    }
                    if (ctx->header[0] != deflate_magic[0] ||
                        ctx->header[1] != deflate_magic[1]) {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01405)
                                          "inflate: bad header");
                        return APR_EGENERAL ;
                    }
                    ctx->zlib_flags = ctx->header[3];
                    if ((ctx->zlib_flags & RESERVED)) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02620)
                                      "inflate: bad flags %02x",
                                      ctx->zlib_flags);
                        return APR_EGENERAL;
                    }
                }
                if (len == rem) {
                    apr_bucket_delete(e);
                    continue;
                }
                data += rem;
                len -= rem;
            }
    
            if (ctx->zlib_flags) {
                rv = consume_zlib_flags(ctx, &data, &len);
                if (rv == APR_SUCCESS) {
                    ctx->zlib_flags = 0;
                }
                if (!len) {
                    apr_bucket_delete(e);
                    continue;
                }
            }
    
            /* pass through zlib inflate. */
            ctx->stream.next_in = (unsigned char *)data;
            ctx->stream.avail_in = len;
    
            if (ctx->validation_buffer) {
                if (ctx->validation_buffer_length < VALIDATION_SIZE) {
                    apr_size_t copy_size;
    
                    copy_size = VALIDATION_SIZE - ctx->validation_buffer_length;
                    if (copy_size > ctx->stream.avail_in)
                        copy_size = ctx->stream.avail_in;
                    memcpy(ctx->validation_buffer + ctx->validation_buffer_length,
                           ctx->stream.next_in, copy_size);
                    /* Saved copy_size bytes */
                    ctx->stream.avail_in -= copy_size;
                    ctx->validation_buffer_length += copy_size;
                }
                if (ctx->stream.avail_in) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01407)
                                  "Zlib: %d bytes of garbage at the end of "
                                  "compressed stream.", ctx->stream.avail_in);
                    /*
                     * There is nothing worth consuming for zlib left, because it is
                     * either garbage data or the data has been copied to the
                     * validation buffer (processing validation data is no business
                     * for zlib). So set ctx->stream.avail_in to zero to indicate
                     * this to the following while loop.
                     */
                    ctx->stream.avail_in = 0;
                }
            }
    
            while (ctx->stream.avail_in != 0) {
                if (ctx->stream.avail_out == 0) {
                    consume_buffer(ctx, c, c->bufferSize, UPDATE_CRC, ctx->bb);
    
                    /* Send what we have right now to the next filter. */
                    rv = ap_pass_brigade(f->next, ctx->bb);
                    apr_brigade_cleanup(ctx->bb);
                    if (rv != APR_SUCCESS) {
                        return rv;
                    }
                }
    
                zRC = inflate(&ctx->stream, Z_NO_FLUSH);
    
                if (zRC != Z_OK && zRC != Z_STREAM_END) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01409)
                                  "Zlib error %d inflating data (%s)", zRC,
                                  ctx->stream.msg);
                    return APR_EGENERAL;
                }
    
                /* Don't check length limits on inflate_out */
                if (!check_ratio(r, ctx, dc)) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02650)
                                  "Inflated content ratio is larger than the "
                                  "configured limit %i by %i time(s)",
                                  dc->ratio_limit, dc->ratio_burst);
                    return APR_EINVAL;
                }
    
                if (zRC == Z_STREAM_END) {
                    /*
                     * We have inflated all data. Now try to capture the
                     * validation bytes. We may not have them all available
                     * right now, but capture what is there.
                     */
                    ctx->validation_buffer = apr_pcalloc(f->r->pool,
                                                         VALIDATION_SIZE);
                    if (ctx->stream.avail_in > VALIDATION_SIZE) {
                        ctx->validation_buffer_length = VALIDATION_SIZE;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01408)
                                      "Zlib: %d bytes of garbage at the end of "
                                      "compressed stream.",
                                      ctx->stream.avail_in - VALIDATION_SIZE);
                    }
                    else if (ctx->stream.avail_in > 0) {
                        ctx->validation_buffer_length = ctx->stream.avail_in;
                    }
                    if (ctx->validation_buffer_length)
                        memcpy(ctx->validation_buffer, ctx->stream.next_in,
                               ctx->validation_buffer_length);
                    break;
                }
            }
    
            apr_bucket_delete(e);
        }
    
        return APR_SUCCESS;
    }
    
    static int mod_deflate_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                       apr_pool_t *ptemp, server_rec *s)
    {
        return OK;
    }
    
    
    #define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH
    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);
        ap_hook_post_config(mod_deflate_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    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)"),
        AP_INIT_TAKE1("DeflateInflateLimitRequestBody", deflate_set_inflate_limit, NULL, OR_ALL,
                      "Set a limit on size of inflated input"),
        AP_INIT_TAKE1("DeflateInflateRatioLimit", deflate_set_inflate_ratio_limit, NULL, OR_ALL,
                      "Set the inflate ratio limit above which inflation is "
                      "aborted (default: " APR_STRINGIFY(AP_INFLATE_RATIO_LIMIT) ")"),
        AP_INIT_TAKE1("DeflateInflateRatioBurst", deflate_set_inflate_ratio_burst, NULL, OR_ALL,
                      "Set the maximum number of following inflate ratios above limit "
                      "(default: " APR_STRINGIFY(AP_INFLATE_RATIO_BURST) ")"),
       AP_INIT_TAKE1("DeflateAlterEtag", deflate_set_etag, NULL, RSRC_CONF,
                      "Set how mod_deflate should modify ETAG response headers: 'AddSuffix' (default), 'NoChange' (2.2.x behavior), 'Remove'"),
    
        {NULL}
    };
    
    AP_DECLARE_MODULE(deflate) = {
        STANDARD20_MODULE_STUFF,
        create_deflate_dirconf,       /* 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 */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/libsed.h���������������������������������������������������������������0000664�0001751�0001751�00000010762�14211416072�017361� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
     * Use is subject to license terms.
     *
     *      Copyright (c) 1984 AT&T
     *        All Rights Reserved
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  http://www.apache.org/licenses/LICENSE-2.0.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 LIBSED_H
    #define LIBSED_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include <limits.h>
    
    #include "apr_file_io.h"
    
    #define SED_NLINES 256
    #define SED_DEPTH 20
    #define SED_LABSIZE 50
    #define SED_ABUFSIZE 20
    
    typedef struct sed_reptr_s sed_reptr_t;
    
    struct sed_reptr_s {
        sed_reptr_t *next;
        char        *ad1;
        char        *ad2;
        char        *re1;
        sed_reptr_t *lb1;
        char        *rhs;
        int         findex;
        char        command;
        int         gfl;
        char        pfl;
        char        negfl;
        int         nrep;
    };
    
    typedef struct sed_label_s sed_label_t;
    
    struct sed_label_s {
        char        asc[9];
        sed_reptr_t *chain;
        sed_reptr_t *address;
    };
    
    typedef apr_status_t (sed_err_fn_t)(void *data, const char *error);
    typedef apr_status_t (sed_write_fn_t)(void *ctx, char *buf, apr_size_t sz);
    
    typedef struct sed_commands_s sed_commands_t;
    #define NWFILES 11 /* 10 plus one for standard output */
    
    struct sed_commands_s {
        sed_err_fn_t *errfn;
        void         *data;
    
        apr_size_t   lsize;
        char         *linebuf;
        char         *lbend;
        const char   *saveq;
    
        char         *cp;
        char         *lastre;
        char         *respace;
        char         sseof;
        char         *reend;
        const char   *earg;
        int          eflag;
        int          gflag;
        int          nflag;
        apr_int64_t  tlno[SED_NLINES];
        int          nlno;
        int          depth;
    
        char         *fname[NWFILES];
        int          nfiles;
    
        sed_label_t  ltab[SED_LABSIZE];
        sed_label_t  *labtab;
        sed_label_t  *lab;
        sed_label_t  *labend;
    
        sed_reptr_t  **cmpend[SED_DEPTH];
        sed_reptr_t  *ptrspace;
        sed_reptr_t  *ptrend;
        sed_reptr_t  *rep;
        int          nrep;
        apr_pool_t   *pool;
        int          canbefinal;
    };
    
    typedef struct sed_eval_s sed_eval_t;
    
    struct sed_eval_s {
        sed_err_fn_t   *errfn;
        sed_write_fn_t *writefn;
        void           *data;
    
        sed_commands_t *commands;
    
        apr_int64_t    lnum;
        void           *fout;
    
        apr_size_t     lsize;
        char           *linebuf;
        char           *lspend;
    
        apr_size_t     hsize;
        char           *holdbuf;
        char           *hspend;
    
        apr_size_t     gsize;
        char           *genbuf;
        char           *lcomend;
    
        apr_file_t    *fcode[NWFILES];
        sed_reptr_t    *abuf[SED_ABUFSIZE];
        sed_reptr_t    **aptr;
        sed_reptr_t    *pending;
        unsigned char  *inar;
        int            nrep;
    
        int            dolflag;
        int            sflag;
        int            jflag;
        int            delflag;
        int            lreadyflag;
        int            quitflag;
        int            finalflag;
        int            numpass;
        int            nullmatch;
        int            col;
        apr_pool_t     *pool;
    };
    
    apr_status_t sed_init_commands(sed_commands_t *commands, sed_err_fn_t *errfn, void *data,
                                   apr_pool_t *p);
    apr_status_t sed_compile_string(sed_commands_t *commands, const char *s);
    apr_status_t sed_compile_file(sed_commands_t *commands, apr_file_t *fin);
    char* sed_get_finalize_error(const sed_commands_t *commands, apr_pool_t* pool);
    int sed_canbe_finalized(const sed_commands_t *commands);
    void sed_destroy_commands(sed_commands_t *commands);
    
    apr_status_t sed_init_eval(sed_eval_t *eval, sed_commands_t *commands,
                               sed_err_fn_t *errfn, void *data,
                               sed_write_fn_t *writefn, apr_pool_t *p);
    apr_status_t sed_reset_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data);
    apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout);
    apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout);
    apr_status_t sed_finalize_eval(sed_eval_t *eval, void *f);
    void sed_destroy_eval(sed_eval_t *eval);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* LIBSED_H */
    ��������������httpd-2.4.64/modules/filters/mod_charset_lite.c�����������������������������������������������������0000664�0001751�0001751�00000123710�14001631447�021417� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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 {
        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;
        /** treat all mimetypes as text? */
        enum {FX_INIT, FX_FORCE, FX_NOFORCE} force_xlate;
    } 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;
        int is_sb;              /* single-byte translation? */
        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 */
        apr_bucket_brigade *tmpbb; /* used for passing downstream */
    } 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;
    
    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));
    
        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->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;
        a->force_xlate=
            over->force_xlate != FX_INIT ? over->force_xlate : base->force_xlate;
        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 (!strcasecmp(flag, "TranslateAllMimeTypes")) {
            dc->force_xlate = FX_FORCE;
        }
        else if (!strcasecmp(flag, "NoTranslateAllMimeTypes")) {
            dc->force_xlate = FX_NOFORCE;
        }
        else {
            return apr_pstrcat(cmd->temp_pool,
                               "Invalid CharsetOptions option: ",
                               flag,
                               NULL);
        }
    
        return NULL;
    }
    
    /* find_code_page() is a fixup hook that checks if the module is
     * configured and the input or output potentially need to be translated.
     * If so, context is initialized for the filters.
     */
    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;
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                      "uri: %s file: %s method: %d "
                      "imt: %s flags: %s%s%s %s->%s",
                      r->uri,
                      r->filename ? r->filename : "(none)",
                      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) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01448)
                          "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 (r->filename
            && (!strncmp(r->filename, "redirect:", 9)
                || !strncmp(r->filename, "gone:", 5)
                || !strncmp(r->filename, "passthrough:", 12)
                || !strncmp(r->filename, "forbidden:", 10))) {
            return DECLINED;
        }
    
        /* no translation when server and network charsets are set to the same value */
        if (!strcasecmp(dc->charset_source, dc->charset_default)) {
            return DECLINED;
        }
    
        /* 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;
        output_ctx->tmpbb = apr_brigade_create(r->pool,
                                               r->connection->bucket_alloc);
        ap_set_module_config(r->request_config, &charset_lite_module, reqinfo);
    
        reqinfo->output_ctx = output_ctx;
    
        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, APLOGNO(01449)
                              "can't open translation %s->%s",
                              dc->charset_default, dc->charset_source);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            if (apr_xlate_sb_get(input_ctx->xlate, &input_ctx->is_sb) != APR_SUCCESS) {
                input_ctx->is_sb = 0;
            }
        }
    
        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 (dc && (dc->implicit_add == IA_NOIMPADD)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE6, 0, r,
                          "xlate output filter not added implicitly because "
                          "CharsetOptions included 'NoImplicitAdd'");
            return;
        }
    
        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);
            }
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 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);
            }
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 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
     */
    
    static apr_status_t send_bucket_downstream(ap_filter_t *f, apr_bucket *b)
    {
        charset_filter_ctx_t *ctx = f->ctx;
        apr_status_t rv;
    
        APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, b);
        rv = ap_pass_brigade(f->next, ctx->tmpbb);
        if (rv != APR_SUCCESS) {
            ctx->ees = EES_DOWNSTREAM;
        }
        apr_brigade_cleanup(ctx->tmpbb);
        return rv;
    }
    
    /* 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 *b;
    
        b = apr_bucket_transient_create(tmp, len, c->bucket_alloc);
        return send_bucket_downstream(f, b);
    }
    
    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];
        apr_size_t len;
    
        switch(ctx->ees) {
        case EES_LIMIT:
            rv = 0;
            msg = APLOGNO(02193) "xlate filter - a built-in restriction was encountered";
            break;
        case EES_BAD_INPUT:
            rv = 0;
            msg = APLOGNO(02194) "xlate filter - an input character was invalid";
            break;
        case EES_BUCKET_READ:
            rv = 0;
            msg = APLOGNO(02195) "xlate filter - bucket read routine failed";
            break;
        case EES_INCOMPLETE_CHAR:
            rv = 0;
            strcpy(msgbuf, APLOGNO(02196) "xlate filter - incomplete char at end of input - ");
            len = ctx->saved;
    
            /* We must ensure not to process more than what would fit in the
             * remaining of the destination buffer, including terminating NULL */
            if (len > (sizeof(msgbuf) - strlen(msgbuf) - 1) / 2)
                len = (sizeof(msgbuf) - strlen(msgbuf) - 1) / 2;
    
            ap_bin2hex(ctx->buf, len, msgbuf + strlen(msgbuf));
            msg = msgbuf;
            break;
        case EES_DOWNSTREAM:
            msg = APLOGNO(02197) "xlate filter - an error occurred in a lower filter";
            break;
        default:
            msg = APLOGNO(02198) "xlate filter - returning error";
        }
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(02997) "%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 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 (APLOGrtrace1(f->r)) {
                                const char *symbol = output ? "->" : "<-";
    
                                ap_log_rerror(APLOG_MARK, APLOG_DEBUG,
                                              0, f->r, APLOGNO(01451)
                                              "%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, APLOGNO(01452)
                                          "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 or metadata
     *
     * inputs:
     *   bb:               brigade to process
     *   buffer:           storage to hold the translated characters
     *   buffer_avail:     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_avail:     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_METADATA(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;
            }
        }
    
        /* Check the mime type to see if translation should be performed.
         */
        if (!ctx->noop && ctx->xlate == NULL) {
            const char *mime_type = f->r->content_type;
    
            if (mime_type && (ap_cstr_casecmpn(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
                ap_cstr_casecmpn(mime_type, "message/", 8) == 0 ||
                dc->force_xlate == FX_FORCE)) {
    
                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, APLOGNO(01453)
                                  "can't open translation %s->%s",
                                  dc->charset_source, dc->charset_default);
                    ctx->noop = 1;
                }
                else {
                    if (apr_xlate_sb_get(ctx->xlate, &ctx->is_sb) != APR_SUCCESS) {
                        ctx->is_sb = 0;
                    }
                }
            }
            else {
                ctx->noop = 1;
                if (mime_type) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE6, 0, f->r,
                                  "mime type is %s; no translation selected",
                                  mime_type);
                }
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE6, 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 && !ctx->is_sb) {
                /* We're not converting between two single-byte charsets, so unset
                 * Content-Length since it is unlikely to remain the same.
                 */
                apr_table_unset(f->r->headers_out, "Content-Length");
            }
        }
    
        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)) {
                    break;
                }
                if (APR_BUCKET_IS_EOS(dptr)) {
                    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;
                }
                if (APR_BUCKET_IS_METADATA(dptr)) {
                    apr_bucket *metadata_bucket;
                    metadata_bucket = dptr;
                    dptr = APR_BUCKET_NEXT(dptr);
                    APR_BUCKET_REMOVE(metadata_bucket);
                    rv = send_bucket_downstream(f, metadata_bucket);
                    if (rv != APR_SUCCESS) {
                        done = 1;
                    }
                    continue;
                }
                rv = apr_bucket_read(dptr, &cur_str, &cur_len, APR_BLOCK_READ);
                if (rv != APR_SUCCESS) {
                    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 apr_status_t 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;
    
        /* 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);
        }
    
        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;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE6, 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 && !ctx->is_sb
                && apr_table_get(f->r->headers_in, "Content-Length")) {
                /* A Content-Length header is present, but it won't be valid after
                 * conversion because we're not converting between two single-byte
                 * charsets.  This will affect most CGI scripts and may affect
                 * some modules.
                 * Content-Length can't be unset here because that would break
                 * being able to read the request body.
                 * Processing of chunked request bodies is not impacted by this
                 * filter since the length was not declared anyway.
                 */
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, f->r,
                              "Request body length may change, resulting in "
                              "misprocessing by some modules or scripts");
            }
        }
    
        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
                 */
            }
            /* If we have any metadata at the head of ctx->bb, go ahead and move it
             * onto the end of bb to be returned to our caller.
             */
            if (!APR_BRIGADE_EMPTY(ctx->bb)) {
                apr_bucket *b = APR_BRIGADE_FIRST(ctx->bb);
                while (b != APR_BRIGADE_SENTINEL(ctx->bb)
                       && APR_BUCKET_IS_METADATA(b)) {
                    APR_BUCKET_REMOVE(b);
                    APR_BRIGADE_INSERT_TAIL(bb, b);
                    b = APR_BRIGADE_FIRST(ctx->bb);
                }
            }
        }
        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, TranslateAllMimeTypes, "
                        "NoTranslateAllMimeTypes"),
        {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);
    }
    
    AP_DECLARE_MODULE(charset_lite) =
    {
        STANDARD20_MODULE_STUFF,
        create_charset_dir_conf,
        merge_charset_dir_conf,
        NULL,
        NULL,
        cmds,
        charset_register_hooks
    };
    
    ��������������������������������������������������������httpd-2.4.64/modules/filters/config.m4��������������������������������������������������������������0000664�0001751�0001751�00000015223�13522234304�017452� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl modules enabled in this directory by default
    
    dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
    
    APACHE_MODPATH_INIT(filters)
    
    APACHE_MODULE(buffer, Filter Buffering, , , most)
    APACHE_MODULE(data, RFC2397 data encoder, , , )
    APACHE_MODULE(ratelimit, Output Bandwidth Limiting, , , most)
    APACHE_MODULE(reqtimeout, Limit time waiting for request from client, , , yes)
    APACHE_MODULE(ext_filter, external filter module, , , most)
    APACHE_MODULE(request, Request Body Filtering, , , most)
    APACHE_MODULE(include, Server Side Includes, , , most)
    APACHE_MODULE(filter, Smart Filtering, , , yes)
    APACHE_MODULE(reflector, Reflect request through the output filter stack, , , )
    APACHE_MODULE(substitute, response content rewrite-like filtering, , , most)
    
    sed_obj="mod_sed.lo sed0.lo sed1.lo regexp.lo"
    APACHE_MODULE(sed, filter request and/or response bodies through sed, $sed_obj, , most, [
        if test "x$enable_sed" = "xshared"; then
            # The only symbol which needs to be exported is the module
            # structure, so ask libtool to hide libsed internals:
            APR_ADDTO(MOD_SED_LDADD, [-export-symbols-regex sed_module])
        fi
    ])
    
    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.  Enabled by default only on EBCDIC systems., , , yes)
    else
        APACHE_MODULE(charset_lite, character set translation.  Enabled by default only on EBCDIC systems., , , )
    fi
    
    
    APACHE_MODULE(deflate, Deflate transfer encoding support, , , most, [
      AC_ARG_WITH(z, APACHE_HELP_STRING(--with-z=PATH,use a specific zlib library),
      [
        if test "x$withval" != "xyes" && test "x$withval" != "x"; then
          ap_zlib_base="$withval"
          ap_zlib_with="yes"
        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
        ap_zlib_ldflags=""
        if test "$ap_zlib_base" != "/usr"; then
          APR_ADDTO(INCLUDES, [-I${ap_zlib_base}/include])
          APR_ADDTO(MOD_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])
          APR_ADDTO(ap_zlib_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])
             APR_ADDTO(ap_zlib_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 <zlib.h>], [int i = Z_OK;], 
          [AC_MSG_RESULT(found) 
           APR_ADDTO(MOD_DEFLATE_LDADD, [$ap_zlib_ldflags -lz])],
          [AC_MSG_RESULT(not found)
           enable_deflate=no
           if test "x$ap_zlib_with" = "x"; then
             AC_MSG_WARN([... Error, zlib was missing or unusable])
           else
             AC_MSG_ERROR([... Error, zlib was missing or unusable])
           fi
          ])
        INCLUDES=$ap_save_includes
        LDFLAGS=$ap_save_ldflags
        CPPFLAGS=$ap_save_cppflags
        APR_REMOVEFROM(LIBS, [-lz])
      fi
    ])
    
    AC_DEFUN([FIND_LIBXML2], [
      AC_CACHE_CHECK([for libxml2], [ac_cv_libxml2], [
        AC_ARG_WITH(libxml2,
          [APACHE_HELP_STRING(--with-libxml2=PATH,location for libxml2)],
          [test_paths="${with_libxml2}/include/libxml2 ${with_libxml2}/include ${with_libxml2}"],
          [test_paths="/usr/include/libxml2 /usr/local/include/libxml2 /usr/include /usr/local/include"]
        )
        AC_MSG_CHECKING(for libxml2)
        xml2_path=""
        for x in ${test_paths}; do
            if test -f "${x}/libxml/parser.h"; then
              xml2_path="${x}"
              break
            fi
        done
        if test -n "${xml2_path}" ; then
          ac_cv_libxml2=yes
          XML2_INCLUDES="${xml2_path}"
        else
          ac_cv_libxml2=no
        fi
      ])
    ])
    
    APACHE_MODULE(xml2enc, i18n support for markup filters, , , , [
      FIND_LIBXML2
      if test "$ac_cv_libxml2" = "yes" ; then
        APR_ADDTO(MOD_CFLAGS, [-I${XML2_INCLUDES}])
        APR_ADDTO(MOD_XML2ENC_LDADD, [-lxml2])
      else
        enable_xml2enc=no
      fi
    ])
    APACHE_MODULE(proxy_html, Fix HTML Links in a Reverse Proxy, , , , [
      FIND_LIBXML2
      if test "$ac_cv_libxml2" = "yes" ; then
        APR_ADDTO(MOD_CFLAGS, [-I${XML2_INCLUDES}])
        APR_ADDTO(MOD_PROXY_HTML_LDADD, [-lxml2])
      else
        enable_proxy_html=no
      fi
    ]
    )
    
    APACHE_MODULE(brotli, Brotli compression support, , , most, [
      AC_ARG_WITH(brotli, APACHE_HELP_STRING(--with-brotli=PATH,Brotli installation directory),[
        if test "$withval" != "yes" -a "x$withval" != "x"; then
          ap_brotli_base="$withval"
          ap_brotli_with=yes
        fi
      ])
      ap_brotli_found=no
      if test -n "$ap_brotli_base"; then
        ap_save_cppflags=$CPPFLAGS
        APR_ADDTO(CPPFLAGS, [-I${ap_brotli_base}/include])
        AC_MSG_CHECKING([for Brotli library >= 0.6.0 via prefix])
        AC_TRY_COMPILE(
          [#include <brotli/encode.h>],[
    const uint8_t *o = BrotliEncoderTakeOutput((BrotliEncoderState*)0, (size_t*)0);
    if (o) return *o;],
          [AC_MSG_RESULT(yes)
           ap_brotli_found=yes
           ap_brotli_cflags="-I${ap_brotli_base}/include"
           ap_brotli_libs="-L${ap_brotli_base}/lib -lbrotlienc -lbrotlicommon"],
          [AC_MSG_RESULT(no)]
        )
        CPPFLAGS=$ap_save_cppflags
      else
        if test -n "$PKGCONFIG"; then
          AC_MSG_CHECKING([for Brotli library >= 0.6.0 via pkg-config])
          if $PKGCONFIG --exists "libbrotlienc >= 0.6.0"; then
            AC_MSG_RESULT(yes)
            ap_brotli_found=yes
            ap_brotli_cflags=`$PKGCONFIG libbrotlienc --cflags`
            ap_brotli_libs=`$PKGCONFIG libbrotlienc --libs`
          else
            AC_MSG_RESULT(no)
          fi
        fi
      fi
      if test "$ap_brotli_found" = "yes"; then
        APR_ADDTO(MOD_CFLAGS, [$ap_brotli_cflags])
        APR_ADDTO(MOD_BROTLI_LDADD, [$ap_brotli_libs])
        if test "$enable_brotli" = "shared"; then
          dnl The only symbol which needs to be exported is the module
          dnl structure, so ask libtool to hide everything else:
          APR_ADDTO(MOD_BROTLI_LDADD, [-export-symbols-regex brotli_module])
        fi
      else
        enable_brotli=no
        if test "$ap_brotli_with" = "yes"; then
          AC_MSG_ERROR([Brotli library was missing or unusable])
        fi
      fi
    ])
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_brotli.dep���������������������������������������������������������0000664�0001751�0001751�00000003113�13100131425�020552� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_brotli.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_brotli.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUxml2enc�����������������������������������������������������������0000664�0001751�0001751�00000010351�11652776275�020076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(LIBXML2SDK)/include \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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		+= \
    			-L$(LIBXML2SDK)/lib -llibxml2.lib \
    			$(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	= xml2enc
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) xml2enc Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Substitute 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	=
    
    #
    # 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)/$(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_xml2enc.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	xml2enc_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUmakefile����������������������������������������������������������0000664�0001751�0001751�00000011224�11660331006�020255� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    	$(OBJDIR)/charsetl.nlm \
    	$(OBJDIR)/mod_data.nlm \
    	$(OBJDIR)/mod_filter.nlm \
    	$(OBJDIR)/mod_request.nlm \
    	$(OBJDIR)/substitute.nlm \
    	$(OBJDIR)/modsed.nlm \
    	$(OBJDIR)/modbuffer.nlm \
    	$(OBJDIR)/ratelimit.nlm \
    	$(OBJDIR)/reqtimeout.nlm \
    	$(OBJDIR)/reflector.nlm \
    	$(EOLIST)
    
    # If the zlib library source exists then build the mod_deflate module
    ifneq "$(ZLIBSDK)" ""
    ifeq "$(wildcard $(ZLIBSDK))" "$(ZLIBSDK)"
    TARGET_nlm += $(OBJDIR)/deflate.nlm \
    	$(EOLIST)
    endif
    endif
    
    # If the libxml2 library source exists then build the mod_proxy_html module
    ifneq "$(LIBXML2SDK)" ""
    ifeq "$(wildcard $(LIBXML2SDK))" "$(LIBXML2SDK)"
    TARGET_nlm += \
    	$(OBJDIR)/proxyhtml.nlm \
    	$(OBJDIR)/xml2enc.nlm \
    	$(EOLIST)
    endif
    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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_filter.dep���������������������������������������������������������0000664�0001751�0001751�00000003374�12674411515�020575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_filter.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_filter.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_xml2enc.h����������������������������������������������������������0000664�0001751�0001751�00000004403�11737125415�020331� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_XML2ENC
    #define MOD_XML2ENC
    
    #define ENCIO_INPUT 0x01
    #define ENCIO_OUTPUT 0x02
    #define ENCIO_INPUT_CHECKS 0x04
    #define ENCIO (ENCIO_INPUT|ENCIO_OUTPUT|ENCIO_INPUT_CHECKS)
    #define ENCIO_SKIPTO 0x10
    
    /* declarations to deal with WIN32 compile-flag-in-source-code crap */
    #if !defined(WIN32)
    #define XML2ENC_DECLARE(type)            type
    #define XML2ENC_DECLARE_NONSTD(type)     type
    #define XML2ENC_DECLARE_DATA
    #elif defined(XML2ENC_DECLARE_STATIC)
    #define XML2ENC_DECLARE(type)            type __stdcall
    #define XML2ENC_DECLARE_NONSTD(type)     type
    #define XML2ENC_DECLARE_DATA
    #elif defined(XML2ENC_DECLARE_EXPORT)
    #define XML2ENC_DECLARE(type)            __declspec(dllexport) type __stdcall
    #define XML2ENC_DECLARE_NONSTD(type)     __declspec(dllexport) type
    #define XML2ENC_DECLARE_DATA             __declspec(dllexport)
    #else
    #define XML2ENC_DECLARE(type)            __declspec(dllimport) type __stdcall
    #define XML2ENC_DECLARE_NONSTD(type)     __declspec(dllimport) type
    #define XML2ENC_DECLARE_DATA             __declspec(dllimport)
    #endif
    
    APR_DECLARE_OPTIONAL_FN(apr_status_t, xml2enc_charset,
                            (request_rec* r, xmlCharEncoding* enc,
                             const char** cenc));
    
    APR_DECLARE_OPTIONAL_FN(apr_status_t, xml2enc_filter,
                            (request_rec* r, const char* enc, unsigned int mode));
    
    APR_DECLARE_EXTERNAL_HOOK(xml2enc, XML2ENC, int, preprocess,
                              (ap_filter_t *f, char** bufp, apr_size_t* bytesp))
    
    #endif
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUratelimit���������������������������������������������������������0000664�0001751�0001751�00000010246�11540546347�020512� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= ratelimit
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Rate Limit Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= ratelimit
    
    #
    # 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	=
    
    #
    # 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)/ratelimit.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_ratelimit.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	ratelimit_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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/sed.h������������������������������������������������������������������0000664�0001751�0001751�00000002646�11637145452�016706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
     * Use is subject to license terms.
     *
     *      Copyright (c) 1984 AT&T
     *        All Rights Reserved
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  http://www.apache.org/licenses/LICENSE-2.0.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _SED_H
    #define _SED_H
    
    #include <stdlib.h>
    #include <limits.h>
    
    #define CEND    16
    #define CLNUM   14
    
    #define RESIZE  10000
    #define LBSIZE  1000
    
    #define ACOM    01
    #define BCOM    020
    #define CCOM    02
    #define CDCOM   025
    #define CNCOM   022
    #define COCOM   017
    #define CPCOM   023
    #define DCOM    03
    #define ECOM    015
    #define EQCOM   013
    #define FCOM    016
    #define GCOM    027
    #define CGCOM   030
    #define HCOM    031
    #define CHCOM   032
    #define ICOM    04
    #define LCOM    05
    #define NCOM    012
    #define PCOM    010
    #define QCOM    011
    #define RCOM    06
    #define SCOM    07
    #define TCOM    021
    #define WCOM    014
    #define CWCOM   024
    #define YCOM    026
    #define XCOM    033
    
    #endif /* _SED_H */
    ������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/sed0.c�����������������������������������������������������������������0000664�0001751�0001751�00000067362�12730516456�016770� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
     * Use is subject to license terms.
     *
     *      Copyright (c) 1984 AT&T
     *        All Rights Reserved
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  http://www.apache.org/licenses/LICENSE-2.0.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "libsed.h"
    #include "sed.h"
    #include "regexp.h"
    
    #define CCEOF 22
    
    static int fcomp(sed_commands_t *commands, apr_file_t *fin);
    static char *compsub(sed_commands_t *commands,
                         sed_comp_args *compargs, char *rhsbuf);
    static int rline(sed_commands_t *commands, apr_file_t *fin,
                     char *lbuf, char *lbend);
    static char *address(sed_commands_t *commands, char *expbuf,
                         apr_status_t* status);
    static char *text(sed_commands_t *commands, char *textbuf, char *endbuf);
    static sed_label_t *search(sed_commands_t *commands);
    static char *ycomp(sed_commands_t *commands, char *expbuf);
    static char *comple(sed_commands_t *commands, sed_comp_args *compargs,
                        char *x1, char *ep, char *x3, char x4);
    static sed_reptr_t *alloc_reptr(sed_commands_t *commands);
    static int check_finalized(const sed_commands_t *commands);
    
    void command_errf(sed_commands_t *commands, const char *fmt, ...)
    {
        if (commands->errfn && commands->pool) {
            va_list args;
            const char* error;
            va_start(args, fmt);
            error = apr_pvsprintf(commands->pool, fmt, args);
            commands->errfn(commands->data, error);
            va_end(args);
        }
    }
    
    /*
     * sed_init_commands
     */
    apr_status_t sed_init_commands(sed_commands_t *commands, sed_err_fn_t *errfn, void *data,
                                   apr_pool_t *p)
    {
        memset(commands, 0, sizeof(*commands));
    
        commands->errfn = errfn;
        commands->data = data;
    
        commands->labtab = commands->ltab;
        commands->lab = commands->labtab + 1;
        commands->pool = p;
    
        commands->respace = apr_pcalloc(p, RESIZE);
        if (commands->respace == NULL) {
            command_errf(commands, SEDERR_OOMMES);
            return APR_EGENERAL;
        }
    
        commands->rep = alloc_reptr(commands);
        if (commands->rep == NULL)
            return APR_EGENERAL;
    
        commands->rep->ad1 = commands->respace;
        commands->reend = &commands->respace[RESIZE - 1];
        commands->labend = &commands->labtab[SED_LABSIZE];
        commands->canbefinal = 1;
    
        return APR_SUCCESS;
    }
    
    /*
     * sed_destroy_commands
     */
    void sed_destroy_commands(sed_commands_t *commands)
    {
    }
    
    /*
     * sed_compile_string
     */
    apr_status_t sed_compile_string(sed_commands_t *commands, const char *s)
    {
        apr_status_t rv;
    
        commands->earg = s;
        commands->eflag = 1;
    
        rv = fcomp(commands, NULL);
        if (rv == APR_SUCCESS)
            commands->canbefinal = check_finalized(commands);
    
        commands->eflag = 0;
    
        return (rv != 0 ? APR_EGENERAL : APR_SUCCESS);
    }
    
    /*
     * sed_compile_file
     */
    apr_status_t sed_compile_file(sed_commands_t *commands, apr_file_t *fin)
    {
        apr_status_t rv = fcomp(commands, fin);
        return (rv != 0 ? APR_EGENERAL : APR_SUCCESS);
    }
    
    /*
     * sed_get_finalize_error
     */
    char* sed_get_finalize_error(const sed_commands_t *commands, apr_pool_t* pool)
    {
        const sed_label_t *lab;
        if (commands->depth) {
            return SEDERR_TMOMES;
        }
    
        /* Empty branch chain is not a issue */
        for (lab = commands->labtab + 1; lab < commands->lab; lab++) {
            char *error;
            if (lab->address == 0) {
                error = apr_psprintf(pool, SEDERR_ULMES, lab->asc);
                return error;
            }
    
            if (lab->chain) {
                return SEDERR_INTERNAL;
            }
        }
        return NULL;
    }
    
    /*
     * sed_canbe_finalized
     */
    int sed_canbe_finalized(const sed_commands_t *commands)
    {
        return commands->canbefinal;
    }
    
    /*
     * check_finalized
     */
    static int check_finalized(const sed_commands_t *commands)
    {
        const sed_label_t *lab;
        if (commands->depth) {
            return 0;
        }
    
        /* Empty branch chain is not a issue */
        for (lab = commands->labtab + 1; lab < commands->lab; lab++) {
            if (lab->address == 0 || (lab->chain)) {
                return 0;
            }
        }
        return 1;
    }
    
    /*
     * dechain
     */
    static void dechain(sed_label_t *lpt, sed_reptr_t *address)
    {
        sed_reptr_t *rep;
        if ((lpt == NULL) || (lpt->chain == NULL) || (address == NULL))
            return;
        rep = lpt->chain;
        while (rep->lb1) {
            sed_reptr_t *next;
    
            next = rep->lb1;
            rep->lb1 = address;
            rep = next;
        }
        rep->lb1 = address;
        lpt->chain = NULL;
    }
    
    /*
     * fcomp
     */
    static int fcomp(sed_commands_t *commands, apr_file_t *fin)
    {
        char *p, *op, *tp;
        sed_reptr_t *pt, *pt1;
        int i, ii;
        sed_label_t *lpt;
        char fnamebuf[APR_PATH_MAX];
        apr_status_t status;
        sed_comp_args compargs;
    
        op = commands->lastre;
        if (!commands->linebuf) {
            commands->linebuf = apr_pcalloc(commands->pool, LBSIZE + 1);
        }
    
        if (rline(commands, fin, commands->linebuf,
                  (commands->linebuf + LBSIZE + 1)) < 0)
            return 0;
        if (*commands->linebuf == '#') {
            if (commands->linebuf[1] == 'n')
                commands->nflag = 1;
        }
        else {
            commands->cp = commands->linebuf;
            goto comploop;
        }
    
        for (;;) {
            if (rline(commands, fin, commands->linebuf,
                      (commands->linebuf + LBSIZE + 1)) < 0)
                break;
    
            commands->cp = commands->linebuf;
    
    comploop:
            while (*commands->cp == ' ' || *commands->cp == '\t')
                commands->cp++;
            if (*commands->cp == '\0' || *commands->cp == '#')
                continue;
            if (*commands->cp == ';') {
                commands->cp++;
                goto comploop;
            }
    
            p = address(commands, commands->rep->ad1, &status);
            if (status != APR_SUCCESS) {
                command_errf(commands, SEDERR_CGMES, commands->linebuf);
                return -1;
            }
    
            if (p == commands->rep->ad1) {
                if (op)
                    commands->rep->ad1 = op;
                else {
                    command_errf(commands, SEDERR_NRMES);
                    return -1;
                }
            } else if (p == 0) {
                p = commands->rep->ad1;
                commands->rep->ad1 = 0;
            } else {
                op = commands->rep->ad1;
                if (*commands->cp == ',' || *commands->cp == ';') {
                    commands->cp++;
                    commands->rep->ad2 = p;
                    p = address(commands, commands->rep->ad2, &status);
                    if ((status != APR_SUCCESS) || (p == 0)) {
                        command_errf(commands, SEDERR_CGMES, commands->linebuf);
                        return -1;
                    }
                    if (p == commands->rep->ad2)
                        commands->rep->ad2 = op;
                    else
                        op = commands->rep->ad2;
                } else
                    commands->rep->ad2 = 0;
            }
    
            if(p > &commands->respace[RESIZE-1]) {
                command_errf(commands, SEDERR_TMMES, commands->linebuf);
                return -1;
            }
    
            while (*commands->cp == ' ' || *commands->cp == '\t')
                commands->cp++;
    
    swit:
            switch(*commands->cp++) {
            default:
                command_errf(commands, SEDERR_UCMES, commands->linebuf);
                return -1;
    
            case '!':
                commands->rep->negfl = 1;
                goto swit;
    
            case '{':
                commands->rep->command = BCOM;
                commands->rep->negfl = !(commands->rep->negfl);
                commands->cmpend[commands->depth++] = &commands->rep->lb1;
                commands->rep = alloc_reptr(commands);
                commands->rep->ad1 = p;
                if (*commands->cp == '\0')
                    continue;
                goto comploop;
    
            case '}':
                if (commands->rep->ad1) {
                    command_errf(commands, SEDERR_AD0MES, commands->linebuf);
                    return -1;
                }
    
                if (--commands->depth < 0) {
                    command_errf(commands, SEDERR_TMCMES);
                    return -1;
                }
                *commands->cmpend[commands->depth] = commands->rep;
    
                commands->rep->ad1 = p;
                continue;
    
            case '=':
                commands->rep->command = EQCOM;
                if (commands->rep->ad2) {
                    command_errf(commands, SEDERR_AD1MES, commands->linebuf);
                    return -1;
                }
                break;
    
            case ':':
                if (commands->rep->ad1) {
                    command_errf(commands, SEDERR_AD0MES, commands->linebuf);
                    return -1;
                }
    
                while (*commands->cp++ == ' ');
                commands->cp--;
    
                tp = commands->lab->asc;
                while ((*tp++ = *commands->cp++)) {
                    if (tp >= &(commands->lab->asc[8])) {
                        command_errf(commands, SEDERR_LTLMES, commands->linebuf);
                        return -1;
                    }
                }
                *--tp = '\0';
    
                if ((lpt = search(commands)) != NULL) {
                    if (lpt->address) {
                        command_errf(commands, SEDERR_DLMES, commands->linebuf);
                        return -1;
                    }
                    dechain(lpt, commands->rep);
                } else {
                    commands->lab->chain = 0;
                    lpt = commands->lab;
                    if (++commands->lab >= commands->labend) {
                        command_errf(commands, SEDERR_TMLMES, commands->linebuf);
                        return -1;
                    }
                }
                lpt->address = commands->rep;
                commands->rep->ad1 = p;
    
                continue;
    
            case 'a':
                commands->rep->command = ACOM;
                if (commands->rep->ad2) {
                    command_errf(commands, SEDERR_AD1MES, commands->linebuf);
                    return -1;
                }
                if (*commands->cp == '\\')
                    commands->cp++;
                if (*commands->cp++ != '\n') {
                    command_errf(commands, SEDERR_CGMES, commands->linebuf);
                    return -1;
                }
                commands->rep->re1 = p;
                p = text(commands, commands->rep->re1, commands->reend);
                if (p == NULL)
                    return -1;
                break;
    
            case 'c':
                commands->rep->command = CCOM;
                if (*commands->cp == '\\') commands->cp++;
                if (*commands->cp++ != ('\n')) {
                    command_errf(commands, SEDERR_CGMES, commands->linebuf);
                    return -1;
                }
                commands->rep->re1 = p;
                p = text(commands, commands->rep->re1, commands->reend);
                if (p == NULL)
                    return -1;
                break;
    
            case 'i':
                commands->rep->command = ICOM;
                if (commands->rep->ad2) {
                    command_errf(commands, SEDERR_AD1MES, commands->linebuf);
                    return -1;
                }
                if (*commands->cp == '\\') commands->cp++;
                if (*commands->cp++ != ('\n')) {
                    command_errf(commands, SEDERR_CGMES, commands->linebuf);
                    return -1;
                }
                commands->rep->re1 = p;
                p = text(commands, commands->rep->re1, commands->reend);
                if (p == NULL)
                    return -1;
                break;
    
            case 'g':
                commands->rep->command = GCOM;
                break;
    
            case 'G':
                commands->rep->command = CGCOM;
                break;
    
            case 'h':
                commands->rep->command = HCOM;
                break;
    
            case 'H':
                commands->rep->command = CHCOM;
                break;
    
            case 't':
                commands->rep->command = TCOM;
                goto jtcommon;
    
            case 'b':
                commands->rep->command = BCOM;
    jtcommon:
                while (*commands->cp++ == ' ');
                commands->cp--;
    
                if (*commands->cp == '\0') {
                    if ((pt = commands->labtab->chain) != NULL) {
                        while ((pt1 = pt->lb1) != NULL)
                            pt = pt1;
                        pt->lb1 = commands->rep;
                    } else
                        commands->labtab->chain = commands->rep;
                    break;
                }
                tp = commands->lab->asc;
                while ((*tp++ = *commands->cp++))
                    if (tp >= &(commands->lab->asc[8])) {
                        command_errf(commands, SEDERR_LTLMES, commands->linebuf);
                        return -1;
                    }
                commands->cp--;
                *--tp = '\0';
    
                if ((lpt = search(commands)) != NULL) {
                    if (lpt->address) {
                        commands->rep->lb1 = lpt->address;
                    } else {
                        pt = lpt->chain;
                        while ((pt1 = pt->lb1) != NULL)
                            pt = pt1;
                        pt->lb1 = commands->rep;
                    }
                } else {
                    commands->lab->chain = commands->rep;
                    commands->lab->address = 0;
                    if (++commands->lab >= commands->labend) {
                        command_errf(commands, SEDERR_TMLMES, commands->linebuf);
                        return -1;
                    }
                }
                break;
    
            case 'n':
                commands->rep->command = NCOM;
                break;
    
            case 'N':
                commands->rep->command = CNCOM;
                break;
    
            case 'p':
                commands->rep->command = PCOM;
                break;
    
            case 'P':
                commands->rep->command = CPCOM;
                break;
    
            case 'r':
                commands->rep->command = RCOM;
                if (commands->rep->ad2) {
                    command_errf(commands, SEDERR_AD1MES, commands->linebuf);
                    return -1;
                }
                if (*commands->cp++ != ' ') {
                    command_errf(commands, SEDERR_CGMES, commands->linebuf);
                    return -1;
                }
                commands->rep->re1 = p;
                p = text(commands, commands->rep->re1, commands->reend);
                if (p == NULL)
                    return -1;
                break;
    
            case 'd':
                commands->rep->command = DCOM;
                break;
    
            case 'D':
                commands->rep->command = CDCOM;
                commands->rep->lb1 = commands->ptrspace;
                break;
    
            case 'q':
                commands->rep->command = QCOM;
                if (commands->rep->ad2) {
                    command_errf(commands, SEDERR_AD1MES, commands->linebuf);
                    return -1;
                }
                break;
    
            case 'l':
                commands->rep->command = LCOM;
                break;
    
            case 's':
                commands->rep->command = SCOM;
                commands->sseof = *commands->cp++;
                commands->rep->re1 = p;
                p = comple(commands, &compargs, (char *) 0, commands->rep->re1,
                           commands->reend, commands->sseof);
                if (p == NULL)
                    return -1;
                if (p == commands->rep->re1) {
                    if (op)
                        commands->rep->re1 = op;
                    else {
                        command_errf(commands, SEDERR_NRMES);
                        return -1;
                    }
                } else
                    op = commands->rep->re1;
                commands->rep->rhs = p;
    
                p = compsub(commands, &compargs, commands->rep->rhs);
                if ((p) == NULL)
                    return -1;
    
                if (*commands->cp == 'g') {
                    commands->cp++;
                    commands->rep->gfl = 999;
                } else if (commands->gflag)
                    commands->rep->gfl = 999;
    
                if (*commands->cp >= '1' && *commands->cp <= '9') {
                    i = *commands->cp - '0';
                    commands->cp++;
                    while (1) {
                        ii = *commands->cp;
                        if (ii < '0' || ii > '9')
                            break;
                        i = i*10 + ii - '0';
                        if (i > 512) {
                            command_errf(commands, SEDERR_TOOBIG, commands->linebuf);
                            return -1;
                        }
                        commands->cp++;
                    }
                    commands->rep->gfl = i;
                }
    
                if (*commands->cp == 'p') {
                    commands->cp++;
                    commands->rep->pfl = 1;
                }
    
                if (*commands->cp == 'P') {
                    commands->cp++;
                    commands->rep->pfl = 2;
                }
    
                if (*commands->cp == 'w') {
                    commands->cp++;
                    if (*commands->cp++ !=  ' ') {
                        command_errf(commands, SEDERR_SMMES, commands->linebuf);
                        return -1;
                    }
                    if (text(commands, fnamebuf, &fnamebuf[APR_PATH_MAX-1]) == NULL) {
                        command_errf(commands, SEDERR_FNTL, commands->linebuf);
                        return -1;
                    }
                    for (i = commands->nfiles - 1; i >= 0; i--)
                        if (strcmp(fnamebuf,commands->fname[i]) == 0) {
                            commands->rep->findex = i;
                            goto done;
                        }
                    if (commands->nfiles >= NWFILES) {
                        command_errf(commands, SEDERR_TMWFMES);
                        return -1;
                    }
                    commands->fname[commands->nfiles] =
                                apr_pstrdup(commands->pool, fnamebuf);
                    if (commands->fname[commands->nfiles] == NULL) {
                        command_errf(commands, SEDERR_OOMMES);
                        return -1;
                    }
                    commands->rep->findex = commands->nfiles++;
                }
                break;
    
            case 'w':
                commands->rep->command = WCOM;
                if (*commands->cp++ != ' ') {
                    command_errf(commands, SEDERR_SMMES, commands->linebuf);
                    return -1;
                }
                if (text(commands, fnamebuf, &fnamebuf[APR_PATH_MAX-1]) == NULL) {
                    command_errf(commands, SEDERR_FNTL, commands->linebuf);
                    return -1;
                }
                for (i = commands->nfiles - 1; i >= 0; i--)
                    if (strcmp(fnamebuf, commands->fname[i]) == 0) {
                        commands->rep->findex = i;
                        goto done;
                    }
                if (commands->nfiles >= NWFILES) {
                    command_errf(commands, SEDERR_TMWFMES);
                    return -1;
                }
                if ((commands->fname[commands->nfiles] =
                            apr_pstrdup(commands->pool, fnamebuf)) == NULL) {
                    command_errf(commands, SEDERR_OOMMES);
                    return -1;
                }
    
                commands->rep->findex = commands->nfiles++;
                break;
    
            case 'x':
                commands->rep->command = XCOM;
                break;
    
            case 'y':
                commands->rep->command = YCOM;
                commands->sseof = *commands->cp++;
                commands->rep->re1 = p;
                p = ycomp(commands, commands->rep->re1);
                if (p == NULL)
                    return -1;
                break;
            }
    done:
            commands->rep = alloc_reptr(commands);
    
            commands->rep->ad1 = p;
    
            if (*commands->cp++ != '\0') {
                if (commands->cp[-1] == ';')
                    goto comploop;
                command_errf(commands, SEDERR_CGMES, commands->linebuf);
                return -1;
            }
        }
        commands->rep->command = 0;
        commands->lastre = op;
    
        return 0;
    }
    
    static char *compsub(sed_commands_t *commands,
                         sed_comp_args *compargs, char *rhsbuf)
    {
        char   *p, *q;
    
        p = rhsbuf;
        q = commands->cp;
        for(;;) {
            if(p > &commands->respace[RESIZE-1]) {
                command_errf(commands, SEDERR_TMMES, commands->linebuf);
                return NULL;
            }
            if((*p = *q++) == '\\') {
                p++;
                if(p > &commands->respace[RESIZE-1]) {
                    command_errf(commands, SEDERR_TMMES, commands->linebuf);
                    return NULL;
                }
                *p = *q++;
                if(*p > compargs->nbra + '0' && *p <= '9') {
                    command_errf(commands, SEDERR_DOORNG, commands->linebuf);
                    return NULL;
                }
                p++;
                continue;
            }
            if(*p == commands->sseof) {
                *p++ = '\0';
                commands->cp = q;
                return(p);
            }
              if(*p++ == '\0') {
                command_errf(commands, SEDERR_EDMOSUB, commands->linebuf);
                return NULL;
            }
        }
    }
    
    /*
     * rline
     */
    static int rline(sed_commands_t *commands, apr_file_t *fin,
                     char *lbuf, char *lbend)
    {
        char   *p;
        const char *q;
        int    t;
        apr_size_t bytes_read;
    
        p = lbuf;
    
        if(commands->eflag) {
            if(commands->eflag > 0) {
                commands->eflag = -1;
                q = commands->earg;
                while((t = *q++) != '\0') {
                    if(t == '\n') {
                        commands->saveq = q;
                        goto out1;
                    }
                    if (p < lbend)
                        *p++ = t;
                    if(t == '\\') {
                        if((t = *q++) == '\0') {
                            commands->saveq = NULL;
                            return(-1);
                        }
                        if (p < lbend)
                            *p++ = t;
                    }
                }
                commands->saveq = NULL;
    
            out1:
                if (p == lbend) {
                    command_errf(commands, SEDERR_CLTL);
                    return -1;
                }
                *p = '\0';
                return(1);
            }
            if((q = commands->saveq) == 0)    return(-1);
    
            while((t = *q++) != '\0') {
                if(t == '\n') {
                    commands->saveq = q;
                    goto out2;
                }
                if(p < lbend)
                    *p++ = t;
                if(t == '\\') {
                    if((t = *q++) == '\0') {
                        commands->saveq = NULL;
                        return(-1);
                    }
                    if (p < lbend)
                        *p++ = t;
                }
            }
            commands->saveq = NULL;
    
        out2:
            if (p == lbend) {
                command_errf(commands, SEDERR_CLTL);
                return -1;
            }
            *p = '\0';
            return(1);
        }
    
        bytes_read = 1;
        /* XXX extremely inefficient 1 byte reads */
        while (apr_file_read(fin, &t, &bytes_read) != APR_SUCCESS) {
            if(t == '\n') {
                if (p == lbend) {
                    command_errf(commands, SEDERR_CLTL);
                    return -1;
                }
                *p = '\0';
                return(1);
            }
            if (p < lbend)
                *p++ = t;
            if(t == '\\') {
                bytes_read = 1;
                if (apr_file_read(fin, &t, &bytes_read) != APR_SUCCESS) {
                    return -1;
                }
                if(p < lbend)
                    *p++ = t;
            }
            bytes_read = 1;
        }
        return(-1);
    }
    
    /*
     * address
     */
    static char *address(sed_commands_t *commands, char *expbuf,
                         apr_status_t* status)
    {
        char   *rcp;
        apr_int64_t lno;
        sed_comp_args compargs;
    
        *status = APR_SUCCESS;
        if(*commands->cp == '$') {
            if (expbuf > &commands->respace[RESIZE-2]) {
                command_errf(commands, SEDERR_TMMES, commands->linebuf);
                *status = APR_EGENERAL;
                return NULL;
            }
            commands->cp++;
            *expbuf++ = CEND;
            *expbuf++ = CCEOF;
            return(expbuf);
        }
        if (*commands->cp == '/' || *commands->cp == '\\' ) {
            if ( *commands->cp == '\\' )
                commands->cp++;
            commands->sseof = *commands->cp++;
            return(comple(commands, &compargs, (char *) 0, expbuf, commands->reend,
                          commands->sseof));
        }
    
        rcp = commands->cp;
        lno = 0;
    
        while(*rcp >= '0' && *rcp <= '9')
            lno = lno*10 + *rcp++ - '0';
    
        if(rcp > commands->cp) {
            if (expbuf > &commands->respace[RESIZE-3]) {
                command_errf(commands, SEDERR_TMMES, commands->linebuf);
                *status = APR_EGENERAL;
                return NULL;
            }
            *expbuf++ = CLNUM;
            *expbuf++ = commands->nlno;
            commands->tlno[commands->nlno++] = lno;
            if(commands->nlno >= SED_NLINES) {
                command_errf(commands, SEDERR_TMLNMES);
                *status = APR_EGENERAL;
                return NULL;
            }
            *expbuf++ = CCEOF;
            commands->cp = rcp;
            return(expbuf);
        }
        return(NULL);
    }
    
    /*
     * text
     */
    static char *text(sed_commands_t *commands, char *textbuf, char *tbend)
    {
        char   *p, *q;
    
        p = textbuf;
        q = commands->cp;
    #ifndef S5EMUL
        /*
         * Strip off indentation from text to be inserted.
         */
        while(*q == '\t' || *q == ' ')    q++;
    #endif
        for(;;) {
    
            if(p > tbend)
                return(NULL);    /* overflowed the buffer */
            if((*p = *q++) == '\\')
                *p = *q++;
            if(*p == '\0') {
                commands->cp = --q;
                return(++p);
            }
    #ifndef S5EMUL
            /*
             * Strip off indentation from text to be inserted.
             */
            if(*p == '\n') {
                while(*q == '\t' || *q == ' ')    q++;
            }
    #endif
            p++;
        }
    }
    
    
    /*
     * search
     */
    static sed_label_t *search(sed_commands_t *commands)
    {
        sed_label_t *rp;
        sed_label_t *ptr;
    
        rp = commands->labtab;
        ptr = commands->lab;
        while (rp < ptr) {
            if (strcmp(rp->asc, ptr->asc) == 0)
                return rp;
            rp++;
        }
    
        return 0;
    }
    
    /*
     * ycomp
     */
    static char *ycomp(sed_commands_t *commands, char *expbuf)
    {
        char    c;
        int cint; /* integer value of char c */
        char *ep, *tsp;
        int i;
        char    *sp;
    
        ep = expbuf;
        if(ep + 0377 > &commands->respace[RESIZE-1]) {
            command_errf(commands, SEDERR_TMMES, commands->linebuf);
            return NULL;
        }
        sp = commands->cp;
        for(tsp = commands->cp; (c = *tsp) != commands->sseof; tsp++) {
            if(c == '\\')
                tsp++;
            if(c == '\0' || c == '\n') {
                command_errf(commands, SEDERR_EDMOSTR, commands->linebuf);
                return NULL;
            }
        }
        tsp++;
        memset(ep, 0, 0400);
    
        while((c = *sp++) != commands->sseof) {
            c &= 0377;
            if(c == '\\' && *sp == 'n') {
                sp++;
                c = '\n';
            }
            cint = (int) c;
            if((ep[cint] = *tsp++) == '\\' && *tsp == 'n') {
                ep[cint] = '\n';
                tsp++;
            }
            if(ep[cint] == commands->sseof || ep[cint] == '\0') {
                command_errf(commands, SEDERR_TSNTSS, commands->linebuf);
            }
        }
        if(*tsp != commands->sseof) {
            if(*tsp == '\0') {
                command_errf(commands, SEDERR_EDMOSTR, commands->linebuf);
            }
            else {
                command_errf(commands, SEDERR_TSNTSS, commands->linebuf);
            }
            return NULL;
        }
        commands->cp = ++tsp;
    
        for(i = 0; i < 0400; i++)
            if(ep[i] == 0)
                ep[i] = i;
    
        return(ep + 0400);
    }
    
    /*
     * comple
     */
    static char *comple(sed_commands_t *commands, sed_comp_args *compargs,
                        char *x1, char *ep, char *x3, char x4)
    {
        char *p;
    
        p = sed_compile(commands, compargs, ep + 1, x3, x4);
        if(p == ep + 1)
            return(ep);
        *ep = compargs->circf;
        return(p);
    }
    
    /*
     * alloc_reptr
     */
    static sed_reptr_t *alloc_reptr(sed_commands_t *commands)
    {
        sed_reptr_t *var;
    
        var = apr_pcalloc(commands->pool, sizeof(sed_reptr_t));
        if (var == NULL) {
            command_errf(commands, SEDERR_OOMMES);
            return 0;
        }
    
        var->nrep = commands->nrep;
        var->findex = -1;
        commands->nrep++;
    
        if (commands->ptrspace == NULL)
            commands->ptrspace = var;
        else
            commands->ptrend->next = var;
    
        commands->ptrend = var;
        commands->labtab->address = var;
        return var;
    }
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_proxy_html.mak�����������������������������������������������������0000664�0001751�0001751�00000024664�12701473373�021523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy_html.dsp
    !IF "$(CFG)" == ""
    CFG=mod_proxy_html - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_proxy_html - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_proxy_html - Win32 Release" && "$(CFG)" != "mod_proxy_html - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_html.mak" CFG="mod_proxy_html - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_proxy_html - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_proxy_html - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_html - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_html.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_proxy_html.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\mod_proxy_html.obj"
    	-@erase "$(INTDIR)\mod_proxy_html_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_html_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_html.exp"
    	-@erase "$(OUTDIR)\mod_proxy_html.lib"
    	-@erase "$(OUTDIR)\mod_proxy_html.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_html.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/libxml2/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_html_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_html.so" /d LONG_NAME="proxy_html_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_html.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_html.pdb" /debug /out:"$(OUTDIR)\mod_proxy_html.so" /implib:"$(OUTDIR)\mod_proxy_html.lib" /libpath:"../../srclib/libxml2/win32/bin.msvc" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_html.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_html.obj" \
    	"$(INTDIR)\httpd.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_proxy_html.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_proxy_html.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_html.so"
       if exist .\Release\mod_proxy_html.so.manifest mt.exe -manifest .\Release\mod_proxy_html.so.manifest -outputresource:.\Release\mod_proxy_html.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_html - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_proxy_html.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy_html.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\mod_proxy_html.obj"
    	-@erase "$(INTDIR)\mod_proxy_html_src.idb"
    	-@erase "$(INTDIR)\mod_proxy_html_src.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_html.exp"
    	-@erase "$(OUTDIR)\mod_proxy_html.lib"
    	-@erase "$(OUTDIR)\mod_proxy_html.pdb"
    	-@erase "$(OUTDIR)\mod_proxy_html.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/libxml2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy_html_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_html.so" /d LONG_NAME="proxy_html_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy_html.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib libxml2.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy_html.pdb" /debug /out:"$(OUTDIR)\mod_proxy_html.so" /implib:"$(OUTDIR)\mod_proxy_html.lib" /libpath:"../../srclib/libxml2/win32/bin.msvc" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_html.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_proxy_html.obj" \
    	"$(INTDIR)\httpd.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_proxy_html.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_proxy_html.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_proxy_html.so"
       if exist .\Debug\mod_proxy_html.so.manifest mt.exe -manifest .\Debug\mod_proxy_html.so.manifest -outputresource:.\Debug\mod_proxy_html.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_proxy_html.dep")
    !INCLUDE "mod_proxy_html.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_proxy_html.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_proxy_html - Win32 Release" || "$(CFG)" == "mod_proxy_html - Win32 Debug"
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_proxy_html - Win32 Release"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_proxy_html.so" /d LONG_NAME="proxy_html_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_proxy_html - Win32 Debug"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../srclib/apr-util/include" /i "../../srclib/libxml2/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_proxy_html.so" /d LONG_NAME="proxy_html_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_proxy_html.c
    
    "$(INTDIR)\mod_proxy_html.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_proxy_html - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_html - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_html - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_html - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\filters"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\filters"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_proxy_html - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ELSEIF  "$(CFG)" == "mod_proxy_html - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\filters"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\filters"
    
    !ENDIF 
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reflector.dsp������������������������������������������������������0000664�0001751�0001751�00000011001�12062614564�021275� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_reflector" - 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_reflector - 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_reflector.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_reflector.mak" CFG="mod_reflector - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_reflector - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_reflector - 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_reflector - 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 "AP_RL_DECLARE_EXPORT" /Fd"Release\mod_reflector_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 /fo"Release/mod_reflector.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_reflector.so" /d LONG_NAME="reflector_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_reflector.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reflector.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_reflector.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reflector.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_reflector.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_reflector - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fd"Debug\mod_reflector_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 /fo"Debug/mod_reflector.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_reflector.so" /d LONG_NAME="reflector_module for Apache"
    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 /out:".\Debug\mod_reflector.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reflector.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_reflector.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reflector.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_reflector.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_reflector - Win32 Release"
    # Name "mod_reflector - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_reflector.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_proxy_html.dep�����������������������������������������������������0000664�0001751�0001751�00000004103�12674411515�021504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_proxy_html.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_proxy_html.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_strmatch.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_xml2enc.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_request.dep��������������������������������������������������������0000664�0001751�0001751�00000003724�12674411515�020777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_request.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_request.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\mod_request.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������httpd-2.4.64/modules/filters/mod_charset_lite.dep���������������������������������������������������0000664�0001751�0001751�00000004215�12674411515�021751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_charset_lite.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_charset_lite.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_charset.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_buffer.dep���������������������������������������������������������0000664�0001751�0001751�00000003270�12674411515�020554� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_buffer.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_buffer.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ext_filter.dep�����������������������������������������������������0000664�0001751�0001751�00000004071�12674411515�021450� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_ext_filter.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_ext_filter.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\include\util_time.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ratelimit.dep������������������������������������������������������0000664�0001751�0001751�00000003060�12674411515�021272� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_ratelimit.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_ratelimit.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_ratelimit.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_sed.dep������������������������������������������������������������0000664�0001751�0001751�00000007124�12674411515�020060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_sed.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_sed.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\libsed.h"\
    	
    
    .\regexp.c : \
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\libsed.h"\
    	".\regexp.h"\
    	".\sed.h"\
    	
    
    .\sed0.c : \
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\libsed.h"\
    	".\regexp.h"\
    	".\sed.h"\
    	
    
    .\sed1.c : \
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\libsed.h"\
    	".\regexp.h"\
    	".\sed.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/.indent.pro������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�020030� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_include.dsp��������������������������������������������������������0000664�0001751�0001751�00000010717�10551346420�020742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_include.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_include.so" /d LONG_NAME="include_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_include.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_include.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_include.so" /d LONG_NAME="include_module for Apache"
    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 /out:".\Debug\mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_include.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������httpd-2.4.64/modules/filters/mod_ext_filter.exp�����������������������������������������������������0000664�0001751�0001751�00000000022�10150161574�021456� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ext_filter_module
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_charset_lite.dsp���������������������������������������������������0000664�0001751�0001751�00000010607�10551346420�021763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_charset_lite.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_charset_lite.so" /d LONG_NAME="charset_lite_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_charset_lite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_charset_lite.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_charset_lite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_charset_lite.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_charset_lite.so" /d LONG_NAME="charset_lite_module for Apache"
    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
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_charset_lite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_charset_lite.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_charset_lite.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_charset_lite.exp���������������������������������������������������0000664�0001751�0001751�00000000024�10314225744�021763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������charset_lite_module
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_buffer.c�����������������������������������������������������������0000664�0001751�0001751�00000026664�12604740124�020234� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_buffer.c --- Buffer the input and output filter stacks, collapse
     *                  many small buckets into fewer large buckets.
     */
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_buckets.h"
    #include "apr_lib.h"
    
    #include "ap_config.h"
    #include "util_filter.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_request.h"
    
    static const char bufferFilterName[] = "BUFFER";
    module AP_MODULE_DECLARE_DATA buffer_module;
    
    #define DEFAULT_BUFFER_SIZE 128*1024
    
    typedef struct buffer_conf {
        apr_off_t size; /* size of the buffer */
        int size_set; /* has the size been set */
    } buffer_conf;
    
    typedef struct buffer_ctx {
        apr_bucket_brigade *bb;
        apr_bucket_brigade *tmp;
        buffer_conf *conf;
        apr_off_t remaining;
        int seen_eos;
    } buffer_ctx;
    
    /**
     * Buffer buckets being written to the output filter stack.
     */
    static apr_status_t buffer_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
    {
        apr_bucket *e;
        request_rec *r = f->r;
        buffer_ctx *ctx = f->ctx;
        apr_status_t rv = APR_SUCCESS;
        int move = 0;
    
        /* first time in? create a context */
        if (!ctx) {
    
            /* buffering won't work on subrequests, it would be nice if
             * it did. Within subrequests, we have no EOS to check for,
             * so we don't know when to flush the buffer to the network
             */
            if (f->r->main) {
                ap_remove_output_filter(f);
                return ap_pass_brigade(f->next, bb);
            }
    
            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
            ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
            ctx->conf = ap_get_module_config(f->r->per_dir_config, &buffer_module);
        }
    
        /* Do nothing if asked to filter nothing. */
        if (APR_BRIGADE_EMPTY(bb)) {
            return ap_pass_brigade(f->next, bb);
        }
    
        /* Empty buffer means we can potentially optimise below */
        if (APR_BRIGADE_EMPTY(ctx->bb)) {
            move = 1;
        }
    
        while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(bb)) {
            const char *data;
            apr_off_t len;
            apr_size_t size;
    
            e = APR_BRIGADE_FIRST(bb);
    
            /* EOS means we are done. */
            if (APR_BUCKET_IS_EOS(e)) {
    
                /* should we add an etag? */
    
                /* pass the EOS across */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
    
                /* pass what we have down the chain */
                rv = ap_pass_brigade(f->next, ctx->bb);
                continue;
            }
    
            /* A flush takes precedence over buffering */
            if (APR_BUCKET_IS_FLUSH(e)) {
    
                /* pass the flush bucket across */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
    
                /* pass what we have down the chain */
                rv = ap_pass_brigade(f->next, ctx->bb);
                continue;
            }
    
            /* metadata buckets are preserved as is */
            if (APR_BUCKET_IS_METADATA(e)) {
                /*
                 * Remove meta data bucket from old brigade and insert into the
                 * new.
                 */
                APR_BUCKET_REMOVE(e);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                continue;
            }
    
            /* is our buffer full?
             * If so, send what we have down the filter chain. If the buffer
             * gets full, we can no longer compute a content length.
             */
            apr_brigade_length(ctx->bb, 1, &len);
            if (len > ctx->conf->size) {
    
                /* pass what we have down the chain */
                rv = ap_pass_brigade(f->next, ctx->bb);
                if (rv) {
                    /* should break out of the loop, since our write to the client
                     * failed in some way. */
                    continue;
                }
            }
    
            /* at this point we are ready to buffer.
             * Buffering takes advantage of an optimisation in the handling of
             * bucket brigades. Heap buckets are always created at a fixed
             * size, regardless of the size of the data placed into them.
             * The apr_brigade_write() call will first try and pack the data
             * into any free space in the most recent heap bucket, before
             * allocating a new bucket if necessary.
             */
            if (APR_SUCCESS == (rv = apr_bucket_read(e, &data, &size,
                    APR_BLOCK_READ))) {
    
                /* further optimisation: if the buckets are already heap
                 * buckets, and the buckets stay exactly APR_BUCKET_BUFF_SIZE
                 * long (as they would be if we were reading bits of a
                 * large bucket), then move the buckets instead of copying
                 * them.
                 */
                if (move && APR_BUCKET_IS_HEAP(e)) {
                    APR_BUCKET_REMOVE(e);
                    APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                    if (APR_BUCKET_BUFF_SIZE != size) {
                        move = 0;
                    }
                } else {
                    apr_brigade_write(ctx->bb, NULL, NULL, data, size);
                    apr_bucket_delete(e);
                }
    
            }
    
        }
    
        return rv;
    
    }
    
    /**
     * Buffer buckets being read from the input filter stack.
     */
    static apr_status_t buffer_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 *e, *after;
        apr_status_t rv;
        buffer_ctx *ctx = f->ctx;
    
        /* buffer on main requests only */
        if (!ap_is_initial_req(f->r)) {
            ap_remove_input_filter(f);
            return ap_get_brigade(f->next, bb, mode, block, readbytes);
        }
    
        /* first time in? create a context */
        if (!ctx) {
            ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
            ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
            ctx->tmp = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
            ctx->conf = ap_get_module_config(f->r->per_dir_config, &buffer_module);
        }
    
        /* 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);
        }
    
        /* if our buffer is empty, read off the network until the buffer is full */
        if (APR_BRIGADE_EMPTY(ctx->bb)) {
            int seen_flush = 0;
    
            ctx->remaining = ctx->conf->size;
    
            while (!ctx->seen_eos && !seen_flush && ctx->remaining > 0) {
                const char *data;
                apr_size_t size = 0;
    
                if (APR_BRIGADE_EMPTY(ctx->tmp)) {
                    rv = ap_get_brigade(f->next, ctx->tmp, mode, block,
                                        ctx->remaining);
    
                    /* if an error was received, bail out now. If the error is
                     * EAGAIN and we have not yet seen an EOS, we will definitely
                     * be called again, at which point we will send our buffered
                     * data. Instead of sending EAGAIN, some filters return an
                     * empty brigade instead when data is not yet available. In
                     * this case, pass through the APR_SUCCESS and emulate the
                     * underlying filter.
                     */
                    if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(ctx->tmp)) {
                        return rv;
                    }
                }
    
                do {
                    e = APR_BRIGADE_FIRST(ctx->tmp);
    
                    /* if we see an EOS, we are done */
                    if (APR_BUCKET_IS_EOS(e)) {
                        APR_BUCKET_REMOVE(e);
                        APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                        ctx->seen_eos = 1;
                        break;
                    }
    
                    /* flush buckets clear the buffer */
                    if (APR_BUCKET_IS_FLUSH(e)) {
                        APR_BUCKET_REMOVE(e);
                        APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                        seen_flush = 1;
                        break;
                    }
    
                    /* pass metadata buckets through */
                    if (APR_BUCKET_IS_METADATA(e)) {
                        APR_BUCKET_REMOVE(e);
                        APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                        continue;
                    }
    
                    /* read the bucket in, pack it into the buffer */
                    if (APR_SUCCESS == (rv = apr_bucket_read(e, &data, &size,
                                                             APR_BLOCK_READ))) {
                        apr_brigade_write(ctx->bb, NULL, NULL, data, size);
                        ctx->remaining -= size;
                        apr_bucket_delete(e);
                    } else {
                        return rv;
                    }
    
                } while (!APR_BRIGADE_EMPTY(ctx->tmp));
            }
        }
    
        /* give the caller the data they asked for from the buffer */
        apr_brigade_partition(ctx->bb, readbytes, &after);
        e = APR_BRIGADE_FIRST(ctx->bb);
        while (e != after) {
            if (APR_BUCKET_IS_EOS(e)) {
                /* last bucket read, step out of the way */
                ap_remove_input_filter(f);
            }
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(bb, e);
            e = APR_BRIGADE_FIRST(ctx->bb);
        }
    
        return APR_SUCCESS;
    }
    
    static void *create_buffer_config(apr_pool_t *p, char *dummy)
    {
        buffer_conf *new = (buffer_conf *) apr_pcalloc(p, sizeof(buffer_conf));
    
        new->size_set = 0; /* unset */
        new->size = DEFAULT_BUFFER_SIZE; /* default size */
    
        return (void *) new;
    }
    
    static void *merge_buffer_config(apr_pool_t *p, void *basev, void *addv)
    {
        buffer_conf *new = (buffer_conf *) apr_pcalloc(p, sizeof(buffer_conf));
        buffer_conf *add = (buffer_conf *) addv;
        buffer_conf *base = (buffer_conf *) basev;
    
        new->size = (add->size_set == 0) ? base->size : add->size;
        new->size_set = add->size_set || base->size_set;
    
        return new;
    }
    
    static const char *set_buffer_size(cmd_parms *cmd, void *dconf, const char *arg)
    {
        buffer_conf *conf = dconf;
    
        if (APR_SUCCESS != apr_strtoff(&(conf->size), arg, NULL, 10) || conf->size
                <= 0) {
            return "BufferSize must be a size in bytes, and greater than zero";
        }
        conf->size_set = 1;
    
        return NULL;
    }
    
    static const command_rec buffer_cmds[] = { AP_INIT_TAKE1("BufferSize",
            set_buffer_size, NULL, ACCESS_CONF,
            "Maximum size of the buffer used by the buffer filter"), { NULL } };
    
    static void register_hooks(apr_pool_t *p)
    {
        ap_register_output_filter(bufferFilterName, buffer_out_filter, NULL,
                AP_FTYPE_CONTENT_SET);
        ap_register_input_filter(bufferFilterName, buffer_in_filter, NULL,
                AP_FTYPE_CONTENT_SET);
    }
    
    AP_DECLARE_MODULE(buffer) = {
        STANDARD20_MODULE_STUFF,
        create_buffer_config, /* create per-directory config structure */
        merge_buffer_config, /* merge per-directory config structures */
        NULL, /* create per-server config structure */
        NULL, /* merge per-server config structures */
        buffer_cmds, /* command apr_table_t */
        register_hooks /* register hooks */
    };
    ����������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_sed.dsp������������������������������������������������������������0000664�0001751�0001751�00000011242�12062614564�020072� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_sed" - 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_sed - 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_sed.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_sed.mak" CFG="mod_sed - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_sed - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_sed - 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_sed - 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_sed_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 /fo"Release/mod_sed.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_sed.so" /d LONG_NAME="sed_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_sed.so" /base:@..\..\os\win32\BaseAddr.ref,mod_sed.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_sed.so" /base:@..\..\os\win32\BaseAddr.ref,mod_sed.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_sed.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_sed - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_sed_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 /fo"Debug/mod_sed.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_sed.so" /d LONG_NAME="sed_module for Apache"
    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 /out:".\Debug\mod_sed.so" /base:@..\..\os\win32\BaseAddr.ref,mod_sed.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_sed.so" /base:@..\..\os\win32\BaseAddr.ref,mod_sed.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_sed.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_sed - Win32 Release"
    # Name "mod_sed - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\libsed.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_sed.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\regexp.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\regexp.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\sed.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\sed0.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\sed1.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_xml2enc.dep��������������������������������������������������������0000664�0001751�0001751�00000003656�12674411515�020663� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_xml2enc.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_xml2enc.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_xml2enc.h"\
    	
    ����������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_deflate.dsp��������������������������������������������������������0000664�0001751�0001751�00000011143�12007303266�020714� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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" /FD /c
    # ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "NDEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /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 /fo"Release/mod_deflate.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_deflate.so" /d LONG_NAME="deflate_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_deflate.so" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so
    # ADD LINK32 kernel32.lib zdll.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_deflate.so" /libpath:"../../srclib/zlib" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_deflate.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "_DEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /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 /fo"Debug/mod_deflate.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_deflate.so" /d LONG_NAME="deflate_module for Apache"
    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 /out:".\Debug\mod_deflate.so" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so
    # ADD LINK32 kernel32.lib zdll.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_deflate.so" /libpath:"../../srclib/zlib" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_deflate.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ratelimit.dsp������������������������������������������������������0000664�0001751�0001751�00000011101�11162707322�021276� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_ratelimit" - 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_ratelimit - 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_ratelimit.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_ratelimit.mak" CFG="mod_ratelimit - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_ratelimit - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_ratelimit - 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_ratelimit - 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 "AP_RL_DECLARE_EXPORT" /Fd"Release\mod_ratelimit_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 /fo"Release/mod_ratelimit.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ratelimit.so" /d LONG_NAME="ratelimit_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_ratelimit.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ratelimit.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_ratelimit.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ratelimit.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_ratelimit.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_ratelimit - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fd"Debug\mod_ratelimit_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 /fo"Debug/mod_ratelimit.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ratelimit.so" /d LONG_NAME="ratelimit_module for Apache"
    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 /out:".\Debug\mod_ratelimit.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ratelimit.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_ratelimit.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ratelimit.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_ratelimit.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_ratelimit - Win32 Release"
    # Name "mod_ratelimit - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_ratelimit.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_ratelimit.h
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_reqtimeout.dsp�����������������������������������������������������0000664�0001751�0001751�00000011037�11342055347�021515� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_reqtimeout" - 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_reqtimeout - 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_reqtimeout.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_reqtimeout.mak" CFG="mod_reqtimeout - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_reqtimeout - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_reqtimeout - 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_reqtimeout - 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 "AP_RL_DECLARE_EXPORT" /Fd"Release\mod_reqtimeout_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 /fo"Release/mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_reqtimeout.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_reqtimeout - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fd"Debug\mod_reqtimeout_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 /fo"Debug/mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache"
    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 /out:".\Debug\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_reqtimeout.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_reqtimeout - Win32 Release"
    # Name "mod_reqtimeout - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_reqtimeout.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/NWGNUreqtimeout��������������������������������������������������������0000664�0001751�0001751�00000010262�11540546347�020714� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= reqtimeout
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Request Timeout Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_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	= 8192
    
    
    #
    # 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)/$(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_reqtimeout.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	reqtimeout_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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_include.exp��������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�020740� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_ext_filter.dsp�����������������������������������������������������0000664�0001751�0001751�00000010753�10674443511�021471� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_ext_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ext_filter.so" /d LONG_NAME="ext_filter_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /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 /out:".\Release\mod_ext_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_ext_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_ext_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ext_filter.so" /d LONG_NAME="ext_filter_module for Apache"
    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 /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 /out:".\Debug\mod_ext_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_ext_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������httpd-2.4.64/modules/filters/mod_request.dsp��������������������������������������������������������0000664�0001751�0001751�00000010733�11022367030�020777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_request" - 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_request - 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_request.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_request.mak" CFG="mod_request - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_request - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_request - 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_request - 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_request_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 /fo"Release/mod_request.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_request.so" /d LONG_NAME="request_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_request.so" /base:@..\..\os\win32\BaseAddr.ref,mod_request.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_request.so" /base:@..\..\os\win32\BaseAddr.ref,mod_request.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_request.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_request - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_request_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 /fo"Debug/mod_request.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_request.so" /d LONG_NAME="request_module for Apache"
    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 /out:".\Debug\mod_request.so" /base:@..\..\os\win32\BaseAddr.ref,mod_request.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_request.so" /base:@..\..\os\win32\BaseAddr.ref,mod_request.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_request.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_request - Win32 Release"
    # Name "mod_request - Win32 Debug"
    # Begin Source File
    
    SOURCE=..\..\include\mod_request.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_request.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������httpd-2.4.64/modules/filters/mod_deflate.exp��������������������������������������������������������0000664�0001751�0001751�00000000017�10150161574�020721� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������deflate_module
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/filters/mod_buffer.dsp���������������������������������������������������������0000664�0001751�0001751�00000010627�11141403164�020563� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_buffer" - 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_buffer - 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_buffer.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_buffer.mak" CFG="mod_buffer - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_buffer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_buffer - 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_buffer - 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" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_buffer_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 /fo"Release/mod_buffer.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_buffer.so" /d LONG_NAME="buffer_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_buffer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_buffer.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_buffer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_buffer.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_buffer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_buffer - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fd"Debug\mod_buffer_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 /fo"Debug/mod_buffer.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_buffer.so" /d LONG_NAME="buffer_module for Apache"
    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 /out:".\Debug\mod_buffer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_buffer.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_buffer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_buffer.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_buffer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_buffer - Win32 Release"
    # Name "mod_buffer - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_buffer.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015765� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/mod_heartmonitor.mak���������������������������������������������������0000664�0001751�0001751�00000026417�12701473373�022040� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_heartmonitor.dsp
    !IF "$(CFG)" == ""
    CFG=mod_heartmonitor - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_heartmonitor - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_heartmonitor - Win32 Release" && "$(CFG)" != "mod_heartmonitor - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_heartmonitor.mak" CFG="mod_heartmonitor - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_heartmonitor - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_heartmonitor - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartmonitor - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_heartmonitor.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_watchdog - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_heartmonitor.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_watchdog - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_heartmonitor.obj"
    	-@erase "$(INTDIR)\mod_heartmonitor.res"
    	-@erase "$(INTDIR)\mod_heartmonitor_src.idb"
    	-@erase "$(INTDIR)\mod_heartmonitor_src.pdb"
    	-@erase "$(OUTDIR)\mod_heartmonitor.exp"
    	-@erase "$(OUTDIR)\mod_heartmonitor.lib"
    	-@erase "$(OUTDIR)\mod_heartmonitor.pdb"
    	-@erase "$(OUTDIR)\mod_heartmonitor.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_heartmonitor_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_heartmonitor.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_heartmonitor.so" /d LONG_NAME="heartmonitor_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_heartmonitor.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_heartmonitor.pdb" /debug /out:"$(OUTDIR)\mod_heartmonitor.so" /implib:"$(OUTDIR)\mod_heartmonitor.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_heartmonitor.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_heartmonitor.obj" \
    	"$(INTDIR)\mod_heartmonitor.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"..\core\Release\mod_watchdog.lib"
    
    "$(OUTDIR)\mod_heartmonitor.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_heartmonitor.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_heartmonitor.so"
       if exist .\Release\mod_heartmonitor.so.manifest mt.exe -manifest .\Release\mod_heartmonitor.so.manifest -outputresource:.\Release\mod_heartmonitor.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_heartmonitor - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_heartmonitor.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_watchdog - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_heartmonitor.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_watchdog - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_heartmonitor.obj"
    	-@erase "$(INTDIR)\mod_heartmonitor.res"
    	-@erase "$(INTDIR)\mod_heartmonitor_src.idb"
    	-@erase "$(INTDIR)\mod_heartmonitor_src.pdb"
    	-@erase "$(OUTDIR)\mod_heartmonitor.exp"
    	-@erase "$(OUTDIR)\mod_heartmonitor.lib"
    	-@erase "$(OUTDIR)\mod_heartmonitor.pdb"
    	-@erase "$(OUTDIR)\mod_heartmonitor.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_heartmonitor_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_heartmonitor.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_heartmonitor.so" /d LONG_NAME="heartmonitor_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_heartmonitor.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_heartmonitor.pdb" /debug /out:"$(OUTDIR)\mod_heartmonitor.so" /implib:"$(OUTDIR)\mod_heartmonitor.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_heartmonitor.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_heartmonitor.obj" \
    	"$(INTDIR)\mod_heartmonitor.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"..\core\Debug\mod_watchdog.lib"
    
    "$(OUTDIR)\mod_heartmonitor.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_heartmonitor.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_heartmonitor.so"
       if exist .\Debug\mod_heartmonitor.so.manifest mt.exe -manifest .\Debug\mod_heartmonitor.so.manifest -outputresource:.\Debug\mod_heartmonitor.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_heartmonitor.dep")
    !INCLUDE "mod_heartmonitor.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_heartmonitor.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_heartmonitor - Win32 Release" || "$(CFG)" == "mod_heartmonitor - Win32 Debug"
    SOURCE=.\mod_heartmonitor.c
    
    "$(INTDIR)\mod_heartmonitor.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_heartmonitor - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cluster"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartmonitor - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cluster"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartmonitor - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cluster"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartmonitor - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cluster"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartmonitor - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cluster"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartmonitor - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cluster"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cluster"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartmonitor - Win32 Release"
    
    "mod_watchdog - Win32 Release" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Release" 
       cd "..\cluster"
    
    "mod_watchdog - Win32 ReleaseCLEAN" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Release" RECURSE=1 CLEAN 
       cd "..\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartmonitor - Win32 Debug"
    
    "mod_watchdog - Win32 Debug" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Debug" 
       cd "..\cluster"
    
    "mod_watchdog - Win32 DebugCLEAN" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\cluster"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_heartmonitor - Win32 Release"
    
    
    "$(INTDIR)\mod_heartmonitor.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_heartmonitor.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_heartmonitor.so" /d LONG_NAME="heartmonitor_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_heartmonitor - Win32 Debug"
    
    
    "$(INTDIR)\mod_heartmonitor.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_heartmonitor.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_heartmonitor.so" /d LONG_NAME="heartmonitor_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/Makefile.in������������������������������������������������������������0000664�0001751�0001751�00000000267�11737125415�020033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/NWGNUmodheartbeat������������������������������������������������������0000664�0001751�0001751�00000010314�11540546347�021164� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/modules/core \
    			$(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	= modheartbeat
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Heart Beat Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= modheartbeat
    
    #
    # 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	=
    
    #
    # 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)/modheartbeat.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_heartbeat.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	heartbeat_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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/mod_heartbeat.mak������������������������������������������������������0000664�0001751�0001751�00000026001�12701473373�021251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_heartbeat.dsp
    !IF "$(CFG)" == ""
    CFG=mod_heartbeat - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_heartbeat - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_heartbeat - Win32 Release" && "$(CFG)" != "mod_heartbeat - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_heartbeat.mak" CFG="mod_heartbeat - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_heartbeat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_heartbeat - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartbeat - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_watchdog - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_watchdog - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_heartbeat.obj"
    	-@erase "$(INTDIR)\mod_heartbeat.res"
    	-@erase "$(INTDIR)\mod_heartbeat_src.idb"
    	-@erase "$(INTDIR)\mod_heartbeat_src.pdb"
    	-@erase "$(OUTDIR)\mod_heartbeat.exp"
    	-@erase "$(OUTDIR)\mod_heartbeat.lib"
    	-@erase "$(OUTDIR)\mod_heartbeat.pdb"
    	-@erase "$(OUTDIR)\mod_heartbeat.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_heartbeat_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_heartbeat.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_heartbeat.so" /d LONG_NAME="heartbeat_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_heartbeat.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_heartbeat.pdb" /debug /out:"$(OUTDIR)\mod_heartbeat.so" /implib:"$(OUTDIR)\mod_heartbeat.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_heartbeat.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_heartbeat.obj" \
    	"$(INTDIR)\mod_heartbeat.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib" \
    	"..\core\Release\mod_watchdog.lib"
    
    "$(OUTDIR)\mod_heartbeat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_heartbeat.so"
       if exist .\Release\mod_heartbeat.so.manifest mt.exe -manifest .\Release\mod_heartbeat.so.manifest -outputresource:.\Release\mod_heartbeat.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_heartbeat - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "mod_watchdog - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_heartbeat.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_watchdog - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_heartbeat.obj"
    	-@erase "$(INTDIR)\mod_heartbeat.res"
    	-@erase "$(INTDIR)\mod_heartbeat_src.idb"
    	-@erase "$(INTDIR)\mod_heartbeat_src.pdb"
    	-@erase "$(OUTDIR)\mod_heartbeat.exp"
    	-@erase "$(OUTDIR)\mod_heartbeat.lib"
    	-@erase "$(OUTDIR)\mod_heartbeat.pdb"
    	-@erase "$(OUTDIR)\mod_heartbeat.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_heartbeat_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_heartbeat.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_heartbeat.so" /d LONG_NAME="heartbeat_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_heartbeat.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_heartbeat.pdb" /debug /out:"$(OUTDIR)\mod_heartbeat.so" /implib:"$(OUTDIR)\mod_heartbeat.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_heartbeat.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_heartbeat.obj" \
    	"$(INTDIR)\mod_heartbeat.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib" \
    	"..\core\Debug\mod_watchdog.lib"
    
    "$(OUTDIR)\mod_heartbeat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_heartbeat.so"
       if exist .\Debug\mod_heartbeat.so.manifest mt.exe -manifest .\Debug\mod_heartbeat.so.manifest -outputresource:.\Debug\mod_heartbeat.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_heartbeat.dep")
    !INCLUDE "mod_heartbeat.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_heartbeat.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_heartbeat - Win32 Release" || "$(CFG)" == "mod_heartbeat - Win32 Debug"
    SOURCE=.\mod_heartbeat.c
    
    "$(INTDIR)\mod_heartbeat.obj" : $(SOURCE) "$(INTDIR)"
    
    
    !IF  "$(CFG)" == "mod_heartbeat - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\cluster"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartbeat - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\cluster"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartbeat - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\cluster"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartbeat - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\cluster"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\cluster"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartbeat - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\cluster"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartbeat - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\cluster"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\cluster"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_heartbeat - Win32 Release"
    
    "mod_watchdog - Win32 Release" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Release" 
       cd "..\cluster"
    
    "mod_watchdog - Win32 ReleaseCLEAN" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Release" RECURSE=1 CLEAN 
       cd "..\cluster"
    
    !ELSEIF  "$(CFG)" == "mod_heartbeat - Win32 Debug"
    
    "mod_watchdog - Win32 Debug" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Debug" 
       cd "..\cluster"
    
    "mod_watchdog - Win32 DebugCLEAN" : 
       cd ".\..\core"
       $(MAKE) /$(MAKEFLAGS) /F ".\mod_watchdog.mak" CFG="mod_watchdog - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\cluster"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_heartbeat - Win32 Release"
    
    
    "$(INTDIR)\mod_heartbeat.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_heartbeat.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_heartbeat.so" /d LONG_NAME="heartbeat_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_heartbeat - Win32 Debug"
    
    
    "$(INTDIR)\mod_heartbeat.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_heartbeat.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_heartbeat.so" /d LONG_NAME="heartbeat_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/mod_heartbeat.c��������������������������������������������������������0000664�0001751�0001751�00000014742�11737125415�020733� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "apr_strings.h"
    
    #include "ap_mpm.h"
    #include "scoreboard.h"
    #include "mod_watchdog.h"
    
    #ifndef HEARTBEAT_INTERVAL
    #define HEARTBEAT_INTERVAL (1)
    #endif
    
    module AP_MODULE_DECLARE_DATA heartbeat_module;
    
    typedef struct hb_ctx_t
    {
        int active;
        apr_sockaddr_t *mcast_addr;
        int server_limit;
        int thread_limit;
        apr_status_t status;
    } hb_ctx_t;
    
    static const char *msg_format = "v=%u&ready=%u&busy=%u";
    
    #define MSG_VERSION (1)
    
    static int hb_monitor(hb_ctx_t *ctx, apr_pool_t *p)
    {
        apr_size_t len;
        apr_socket_t *sock = NULL;
        char buf[256];
        int i, j;
        apr_uint32_t ready = 0;
        apr_uint32_t busy = 0;
        ap_generation_t mpm_generation;
    
        ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
    
        for (i = 0; i < ctx->server_limit; i++) {
            process_score *ps;
            ps = ap_get_scoreboard_process(i);
    
            for (j = 0; j < ctx->thread_limit; j++) {
                int res;
    
                worker_score *ws = NULL;
    
                ws = &ap_scoreboard_image->servers[i][j];
    
                res = ws->status;
    
                if (res == SERVER_READY && ps->generation == mpm_generation) {
                    ready++;
                }
                else if (res != SERVER_DEAD &&
                         res != SERVER_STARTING && res != SERVER_IDLE_KILL &&
                         ps->generation == mpm_generation) {
                    busy++;
                }
            }
        }
    
        len = apr_snprintf(buf, sizeof(buf), msg_format, MSG_VERSION, ready, busy);
    
        do {
            apr_status_t rv;
            rv = apr_socket_create(&sock, ctx->mcast_addr->family,
                                   SOCK_DGRAM, APR_PROTO_UDP, p);
            if (rv) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv,
                             NULL, APLOGNO(02097) "Heartbeat: apr_socket_create failed");
                break;
            }
    
            rv = apr_mcast_loopback(sock, 1);
            if (rv) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv,
                             NULL, APLOGNO(02098) "Heartbeat: apr_mcast_loopback failed");
                break;
            }
    
            rv = apr_socket_sendto(sock, ctx->mcast_addr, 0, buf, &len);
            if (rv) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv,
                             NULL, APLOGNO(02099) "Heartbeat: apr_socket_sendto failed");
                break;
            }
        } while (0);
    
        if (sock) {
            apr_socket_close(sock);
        }
    
        return OK;
    }
    
    static int hb_watchdog_init(server_rec *s, const char *name, apr_pool_t *pool)
    {
        hb_ctx_t *ctx = ap_get_module_config(s->module_config, &heartbeat_module);
    
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &ctx->thread_limit);
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &ctx->server_limit);
    
        return OK;
    }
    
    static int hb_watchdog_exit(server_rec *s, const char *name, apr_pool_t *pool)
    {
        return OK;
    }
    
    static int hb_watchdog_step(server_rec *s, const char *name, apr_pool_t *pool)
    {
        hb_ctx_t *ctx = ap_get_module_config(s->module_config, &heartbeat_module);
    
        if (!ctx->active || strcmp(name, AP_WATCHDOG_SINGLETON)) {
            return OK;
        }
        return hb_monitor(ctx, pool);
    }
    
    static int hb_watchdog_need(server_rec *s, const char *name,
                              int parent, int singleton)
    {
        hb_ctx_t *ctx = ap_get_module_config(s->module_config, &heartbeat_module);
    
        if (ctx->active && singleton && !strcmp(name, AP_WATCHDOG_SINGLETON))
            return OK;
        else
            return DECLINED;
    }
    
    static void hb_register_hooks(apr_pool_t *p)
    {
        ap_hook_watchdog_need(hb_watchdog_need, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_watchdog_init(hb_watchdog_init, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_watchdog_step(hb_watchdog_step, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_watchdog_exit(hb_watchdog_exit, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    static void *hb_create_config(apr_pool_t *p, server_rec *s)
    {
        hb_ctx_t *cfg = (hb_ctx_t *) apr_pcalloc(p, sizeof(hb_ctx_t));
    
        return cfg;
    }
    
    static const char *cmd_hb_address(cmd_parms *cmd,
                                      void *dconf, const char *addr)
    {
        apr_status_t rv;
        char *host_str;
        char *scope_id;
        apr_port_t port = 0;
        apr_pool_t *p = cmd->pool;
        hb_ctx_t *ctx =
            (hb_ctx_t *) ap_get_module_config(cmd->server->module_config,
                                              &heartbeat_module);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        if (!ctx->active) {
            ctx->active = 1;
        }
        else {
            return "HeartbeatAddress: May only be specified once.";
        }
    
        rv = apr_parse_addr_port(&host_str, &scope_id, &port, addr, cmd->temp_pool);
    
        if (rv) {
            return "HeartbeatAddress: Unable to parse address.";
        }
    
        if (host_str == NULL) {
            return "HeartbeatAddress: No host provided in address";
        }
    
        if (port == 0) {
            return "HeartbeatAddress: No port provided in address";
        }
    
        rv = apr_sockaddr_info_get(&ctx->mcast_addr, host_str, APR_INET, port, 0,
                                   p);
    
        if (rv) {
            return "HeartbeatAddress: apr_sockaddr_info_get failed.";
        }
    
        return NULL;
    }
    
    static const command_rec hb_cmds[] = {
        AP_INIT_TAKE1("HeartbeatAddress", cmd_hb_address, NULL, RSRC_CONF,
                      "Address to send heartbeat requests"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(heartbeat) = {
        STANDARD20_MODULE_STUFF,
        NULL,                       /* create per-directory config structure */
        NULL,                       /* merge per-directory config structures */
        hb_create_config,           /* create per-server config structure */
        NULL,                       /* merge per-server config structures */
        hb_cmds,                    /* command apr_table_t */
        hb_register_hooks
    };
    ������������������������������httpd-2.4.64/modules/cluster/README.heartbeat�������������������������������������������������������0000664�0001751�0001751�00000001743�12757564422�020614� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mod_heartbeat
    
    Broadcasts the current Apache Connection status over multicast.
    
    Example Configuration:
      HeartbeatAddress 239.0.0.1:27999
    
    Dependencies:
      mod_status must be either a static module, or if a dynamic module, it must be 
      loaded before mod_heartbeat.
    
    
    Consuming:
      Every 1 second, this module generates a single multicast UDP packet,
      containing the number of busy and idle workers.
      
      The packet is a simple ASCII format, similar to GET query parameters in UDP.
      
      An Example packet:
        v=1&ready=75&busy=0
    
      Consumers should handle new variables besides busy and ready, separated by '&'
      being added in the future.
      
    Misc:
      The interval of 1 seconds is controlled by the HEARTBEAT_INTERVAL
      compile time define.  This is not currently tunable at run time. To make this
      module send the status packet more often, you must add to the CFLAGS used to
      compile the module to include:
        -DHEARTBEAT_INTERVAL=3
      Would cause the broadcasts to be sent every 3 seconds.
    
    
    �����������������������������httpd-2.4.64/modules/cluster/mod_heartmonitor.dep���������������������������������������������������0000664�0001751�0001751�00000004344�12674411515�022032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_heartmonitor.mak
    
    .\mod_heartmonitor.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\heartbeat.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\core\mod_watchdog.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/NWGNUmakefile����������������������������������������������������������0000664�0001751�0001751�00000007764�11540562746�020322� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/modheartbeat.nlm \
    	$(OBJDIR)/modheartmonitor.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ������������httpd-2.4.64/modules/cluster/mod_heartbeat.dsp������������������������������������������������������0000664�0001751�0001751�00000011455�11203324224�021260� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_heartbeat" - 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_heartbeat - 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_heartbeat.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_heartbeat.mak" CFG="mod_heartbeat - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_heartbeat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_heartbeat - 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_heartbeat - 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 "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_heartbeat_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 0x409 /fo"Release/mod_heartbeat.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_heartbeat.so" /d LONG_NAME="heartbeat_module for Apache"
    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 /out:".\Release\mod_heartbeat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartbeat.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_heartbeat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartbeat.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_heartbeat - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_heartbeat_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 0x409 /fo"Debug/mod_heartbeat.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_heartbeat.so" /d LONG_NAME="heartbeat_module for Apache"
    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 /out:".\Debug\mod_heartbeat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartbeat.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_heartbeat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartbeat.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_heartbeat.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_heartbeat - Win32 Release"
    # Name "mod_heartbeat - 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_heartbeat.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/NWGNUmodheartmonitor���������������������������������������������������0000664�0001751�0001751�00000010343�11540546347�021742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/modules/core \
    			$(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	= modheartmonitor
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Heart Beat Monitor Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= modheartmonitor
    
    #
    # 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	=
    
    #
    # 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)/modheartmonitor.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_heartmonitor.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	heartmonitor_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/README.heartmonitor����������������������������������������������������0000664�0001751�0001751�00000001353�11123517417�021351� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mod_heartmonitor
    
    Collects the Apache Connection status data over multicast.
    
    Example Configuration:
      # First parameter is the interface to listen on
      HeartbeatListen 239.0.0.1:27999
      # Absolute path, or relative path to ServerRoot
      HeartbeatStorage logs/hb.dat
    
    Dependencies:
      Due to a bug in APR's apr_socket_recvfrom, version 1.2.12 or newer must be
      used:
        <http://svn.apache.org/viewvc?view=rev&revision=467600>
    
    Consuming:
      This module atomically writes to the configured path, a list of servers, 
      along with metadata about them.
      
      Included data about each server:
        - IP Address
        - Busy Slots
        - Open Slots
        - Last Seen
    
      Every 5 seconds, this file will be updated with the current status of the 
      cluster.
    
      
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/mod_heartmonitor.c�����������������������������������������������������0000664�0001751�0001751�00000070230�14640775605�021511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "http_core.h"
    #include "http_protocol.h"
    #include "apr_strings.h"
    #include "apr_hash.h"
    #include "apr_time.h"
    #include "ap_mpm.h"
    #include "scoreboard.h"
    #include "mod_watchdog.h"
    #include "ap_slotmem.h"
    #include "heartbeat.h"
    
    
    #ifndef HM_UPDATE_SEC
    /* How often we update the stats file */
    /* TODO: Make a runtime config */
    #define HM_UPDATE_SEC (5)
    #endif
    
    #define HM_WATHCHDOG_NAME ("_heartmonitor_")
    
    static const ap_slotmem_provider_t *storage = NULL;
    static ap_slotmem_instance_t *slotmem = NULL;
    static int maxworkers = 10;
    
    module AP_MODULE_DECLARE_DATA heartmonitor_module;
    
    typedef struct hm_server_t
    {
        const char *ip;
        int busy;
        int ready;
        unsigned int port;
        apr_time_t seen;
    } hm_server_t;
    
    typedef struct hm_ctx_t
    {
        int active;
        const char *storage_path;
        ap_watchdog_t *watchdog;
        apr_interval_time_t interval;
        apr_sockaddr_t *mcast_addr;
        apr_status_t status;
        volatile int keep_running;
        apr_socket_t *sock;
        apr_pool_t *p;
        apr_hash_t *servers;
        server_rec *s;
    } hm_ctx_t;
    
    typedef struct hm_slot_server_ctx_t {
      hm_server_t *s;
      int found;
      unsigned int item_id;
    } hm_slot_server_ctx_t;
    
    static apr_status_t hm_listen(hm_ctx_t *ctx)
    {
        apr_status_t rv;
    
        rv = apr_socket_create(&ctx->sock, ctx->mcast_addr->family,
                               SOCK_DGRAM, APR_PROTO_UDP, ctx->p);
    
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02068)
                         "Failed to create listening socket.");
            return rv;
        }
    
        rv = apr_socket_opt_set(ctx->sock, APR_SO_REUSEADDR, 1);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02069)
                         "Failed to set APR_SO_REUSEADDR to 1 on socket.");
            return rv;
        }
    
    
        rv = apr_socket_opt_set(ctx->sock, APR_SO_NONBLOCK, 1);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02070)
                         "Failed to set APR_SO_NONBLOCK to 1 on socket.");
            return rv;
        }
    
        rv = apr_socket_bind(ctx->sock, ctx->mcast_addr);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02071)
                         "Failed to bind on socket.");
            return rv;
        }
    
        rv = apr_mcast_join(ctx->sock, ctx->mcast_addr, NULL, NULL);
    
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02072)
                         "Failed to join multicast group");
            return rv;
        }
    
        rv = apr_mcast_loopback(ctx->sock, 1);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02073)
                         "Failed to accept localhost mulitcast on socket.");
            return rv;
        }
    
        return APR_SUCCESS;
    }
    
    /* XXX: The same exists in mod_lbmethod_heartbeat.c where it is named argstr_to_table */
    static void qs_to_table(const char *input, apr_table_t *parms,
                            apr_pool_t *p)
    {
        char *key;
        char *value;
        char *query_string;
        char *strtok_state;
    
        if (input == NULL) {
            return;
        }
    
        query_string = apr_pstrdup(p, input);
    
        key = apr_strtok(query_string, "&", &strtok_state);
        while (key) {
            value = strchr(key, '=');
            if (value) {
                *value = '\0';      /* Split the string in two */
                value++;            /* Skip passed the = */
            }
            else {
                value = "1";
            }
            ap_unescape_url(key);
            ap_unescape_url(value);
            apr_table_set(parms, key, value);
            /*
               ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03182)
               "Found query arg: %s = %s", key, value);
             */
            key = apr_strtok(NULL, "&", &strtok_state);
        }
    }
    
    
    #define SEEN_TIMEOUT (30)
    
    /* Store in the slotmem */
    static apr_status_t hm_update(void* mem, void *data, apr_pool_t *p)
    {
        hm_slot_server_t *old = (hm_slot_server_t *) mem;
        hm_slot_server_ctx_t *s = (hm_slot_server_ctx_t *) data;
        hm_server_t *new = s->s;
        if (strcmp(old->ip, new->ip)==0) {
            s->found = 1;
            old->busy = new->busy;
            old->ready = new->ready;
            old->seen = new->seen;
        }
        return APR_SUCCESS;
    }
    /* Read the id corresponding to the entry in the slotmem */
    static apr_status_t hm_readid(void* mem, void *data, apr_pool_t *p)
    {
        hm_slot_server_t *old = (hm_slot_server_t *) mem;
        hm_slot_server_ctx_t *s = (hm_slot_server_ctx_t *) data;
        hm_server_t *new = s->s;
        if (strcmp(old->ip, new->ip)==0) {
            s->found = 1;
            s->item_id = old->id;
        }
        return APR_SUCCESS;
    }
    /* update the entry or create it if not existing */
    static  apr_status_t  hm_slotmem_update_stat(hm_server_t *s, apr_pool_t *pool)
    {
        /* We call do_all (to try to update) otherwise grab + put */
        hm_slot_server_ctx_t ctx;
        ctx.s = s;
        ctx.found = 0;
        storage->doall(slotmem, hm_update, &ctx, pool);
        if (!ctx.found) {
            unsigned int i;
            hm_slot_server_t hmserver;
            memset(&hmserver, 0, sizeof(hmserver));
            apr_cpystrn(hmserver.ip, s->ip, sizeof(hmserver.ip));
            hmserver.busy = s->busy;
            hmserver.ready = s->ready;
            hmserver.seen = s->seen;
            /* XXX locking for grab() / put() */
            storage->grab(slotmem, &i);
            hmserver.id = i;
            storage->put(slotmem, i, (unsigned char *)&hmserver, sizeof(hmserver));
        }
        return APR_SUCCESS;
    }
    static  apr_status_t  hm_slotmem_remove_stat(hm_server_t *s, apr_pool_t *pool)
    {
        hm_slot_server_ctx_t ctx;
        ctx.s = s;
        ctx.found = 0;
        storage->doall(slotmem, hm_readid, &ctx, pool);
        if (ctx.found) {
            storage->release(slotmem, ctx.item_id);
        }
        return APR_SUCCESS;
    }
    static apr_status_t hm_file_update_stat(hm_ctx_t *ctx, hm_server_t *s, apr_pool_t *pool)
    {
        apr_status_t rv;
        apr_file_t *fp;
        apr_file_t *fpin;
        apr_time_t now;
        apr_time_t fage;
        apr_finfo_t fi;
        int updated = 0;
        char *path = apr_pstrcat(pool, ctx->storage_path, ".tmp.XXXXXX", NULL);
    
    
        /* TODO: Update stats file (!) */
        rv = apr_file_mktemp(&fp, path, APR_CREATE | APR_WRITE, pool);
    
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02074)
                         "Unable to open tmp file: %s", path);
            return rv;
        }
        rv = apr_file_open(&fpin, ctx->storage_path, APR_READ|APR_BINARY|APR_BUFFERED,
                           APR_OS_DEFAULT, pool);
    
        now = apr_time_now();
        if (rv == APR_SUCCESS) {
            char *t;
            apr_table_t *hbt = apr_table_make(pool, 10);
            apr_bucket_alloc_t *ba;
            apr_bucket_brigade *bb;
            apr_bucket_brigade *tmpbb;
    
            rv = apr_file_info_get(&fi, APR_FINFO_SIZE | APR_FINFO_MTIME, fpin);
            if (rv) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02075)
                             "Unable to read file: %s", ctx->storage_path);
                return rv;
            }
    
            /* Read the file and update the line corresponding to the node */
            ba = apr_bucket_alloc_create(pool);
            bb = apr_brigade_create(pool, ba);
            apr_brigade_insert_file(bb, fpin, 0, fi.size, pool);
            tmpbb = apr_brigade_create(pool, ba);
            fage = apr_time_sec(now - fi.mtime);
            do {
                char buf[4096];
                const char *ip;
                apr_size_t bsize = sizeof(buf);
    
                apr_brigade_cleanup(tmpbb);
                if (APR_BRIGADE_EMPTY(bb)) {
                    break;
                }
                rv = apr_brigade_split_line(tmpbb, bb,
                                            APR_BLOCK_READ, sizeof(buf));
    
                if (rv) {
                    ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02076)
                                 "Unable to read from file: %s", ctx->storage_path);
                    return rv;
                }
    
                apr_brigade_flatten(tmpbb, buf, &bsize);
                if (bsize == 0) {
                    break;
                }
                buf[bsize - 1] = 0;
                t = strchr(buf, ' ');
                if (t) {
                    ip = apr_pstrmemdup(pool, buf, t - buf);
                }
                else {
                    ip = NULL;
                }
    
                if (!ip || buf[0] == '#') {
                    /* copy things we can't process */
                    apr_file_printf(fp, "%s\n", buf);
                }
                else if (strcmp(ip, s->ip) != 0 ) {
                    hm_server_t node;
                    apr_time_t seen;
                    const char *val;
    
                    /* Update seen time according to the last file modification */
                    apr_table_clear(hbt);
                    qs_to_table(apr_pstrdup(pool, t), hbt, pool);
                    if ((val = apr_table_get(hbt, "busy"))) {
                        node.busy = atoi(val);
                    }
                    else {
                        node.busy = 0;
                    }
    
                    if ((val = apr_table_get(hbt, "ready"))) {
                        node.ready = atoi(val);
                    }
                    else {
                        node.ready = 0;
                    }
    
                    if ((val = apr_table_get(hbt, "lastseen"))) {
                        node.seen = atoi(val);
                    }
                    else {
                        node.seen = SEEN_TIMEOUT;
                    }
                    seen = fage + node.seen;
    
                    if ((val = apr_table_get(hbt, "port"))) {
                        node.port = atoi(val);
                    }
                    else {
                        node.port = 80;
                    }
                    apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u&port=%u\n",
                                    ip, node.ready, node.busy, (unsigned int) seen, node.port);
                }
                else {
                    apr_time_t seen;
                    seen = apr_time_sec(now - s->seen);
                    apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u&port=%u\n",
                                    s->ip, s->ready, s->busy, (unsigned int) seen, s->port);
                    updated = 1;
                }
            } while (1);
        }
    
        if (!updated) {
            apr_time_t seen;
            seen = apr_time_sec(now - s->seen);
            apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u&port=%u\n",
                            s->ip, s->ready, s->busy, (unsigned int) seen, s->port);
        }
    
        rv = apr_file_flush(fp);
        if (rv) {
          ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02077)
                       "Unable to flush file: %s", path);
          return rv;
        }
    
        rv = apr_file_close(fp);
        if (rv) {
          ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02078)
                       "Unable to close file: %s", path);
          return rv;
        }
    
        rv = apr_file_perms_set(path,
                                APR_FPROT_UREAD | APR_FPROT_GREAD |
                                APR_FPROT_WREAD);
        if (rv && rv != APR_INCOMPLETE && rv != APR_ENOTIMPL) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02079)
                         "Unable to set file permissions on %s",
                         path);
            return rv;
        }
    
        rv = apr_file_rename(path, ctx->storage_path, pool);
    
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02080)
                         "Unable to move file: %s -> %s", path,
                         ctx->storage_path);
            return rv;
        }
    
        return APR_SUCCESS;
    }
    static  apr_status_t  hm_update_stat(hm_ctx_t *ctx, hm_server_t *s, apr_pool_t *pool)
    {
        if (slotmem)
            return hm_slotmem_update_stat(s, pool);
        else
            return hm_file_update_stat(ctx, s, pool);
    }
    
    /* Store in a file */
    static apr_status_t hm_file_update_stats(hm_ctx_t *ctx, apr_pool_t *p)
    {
        apr_status_t rv;
        apr_file_t *fp;
        apr_hash_index_t *hi;
        apr_time_t now;
        char *path = apr_pstrcat(p, ctx->storage_path, ".tmp.XXXXXX", NULL);
        /* TODO: Update stats file (!) */
        rv = apr_file_mktemp(&fp, path, APR_CREATE | APR_WRITE, p);
    
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02081)
                         "Unable to open tmp file: %s", path);
            return rv;
        }
    
        now = apr_time_now();
        for (hi = apr_hash_first(p, ctx->servers);
             hi != NULL; hi = apr_hash_next(hi)) {
            hm_server_t *s = NULL;
            apr_time_t seen;
            apr_hash_this(hi, NULL, NULL, (void **) &s);
            seen = apr_time_sec(now - s->seen);
            if (seen > SEEN_TIMEOUT) {
                /*
                 * Skip this entry from the heartbeat file -- when it comes back,
                 * we will reuse the memory...
                 */
            }
            else {
                apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u&port=%u\n",
                                s->ip, s->ready, s->busy, (unsigned int) seen, s->port);
            }
        }
    
        rv = apr_file_flush(fp);
        if (rv) {
          ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02082)
                       "Unable to flush file: %s", path);
          return rv;
        }
    
        rv = apr_file_close(fp);
        if (rv) {
          ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02083)
                       "Unable to close file: %s", path);
          return rv;
        }
    
        rv = apr_file_perms_set(path,
                                APR_FPROT_UREAD | APR_FPROT_GREAD |
                                APR_FPROT_WREAD);
        if (rv && rv != APR_INCOMPLETE && rv != APR_ENOTIMPL) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02084)
                         "Unable to set file permissions on %s",
                         path);
            return rv;
        }
    
        rv = apr_file_rename(path, ctx->storage_path, p);
    
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02085)
                         "Unable to move file: %s -> %s", path,
                         ctx->storage_path);
            return rv;
        }
    
        return APR_SUCCESS;
    }
    /* Store in a slotmem */
    static apr_status_t hm_slotmem_update_stats(hm_ctx_t *ctx, apr_pool_t *p)
    {
        apr_status_t rv;
        apr_time_t now;
        apr_hash_index_t *hi;
        now = apr_time_now();
        for (hi = apr_hash_first(p, ctx->servers);
             hi != NULL; hi = apr_hash_next(hi)) {
            hm_server_t *s = NULL;
            apr_time_t seen;
            apr_hash_this(hi, NULL, NULL, (void **) &s);
            seen = apr_time_sec(now - s->seen);
            if (seen > SEEN_TIMEOUT) {
                /* remove it */
                rv = hm_slotmem_remove_stat(s, p);
            } else {
                /* update it */
                rv = hm_slotmem_update_stat(s, p);
            }
            if (rv !=APR_SUCCESS)
                return rv;
        }
        return APR_SUCCESS;
    }
    /* Store/update the stats */
    static apr_status_t hm_update_stats(hm_ctx_t *ctx, apr_pool_t *p)
    {
        if (slotmem)
            return hm_slotmem_update_stats(ctx, p);
        else
            return hm_file_update_stats(ctx, p);
    }
    
    static hm_server_t *hm_get_server(hm_ctx_t *ctx, const char *ip, const int port)
    {
        hm_server_t *s;
    
        s = apr_hash_get(ctx->servers, ip, APR_HASH_KEY_STRING);
    
        if (s == NULL) {
            s = apr_palloc(ctx->p, sizeof(hm_server_t));
            s->ip = apr_pstrdup(ctx->p, ip);
            s->port = port;
            s->ready = 0;
            s->busy = 0;
            s->seen = 0;
            apr_hash_set(ctx->servers, s->ip, APR_HASH_KEY_STRING, s);
        }
    
        return s;
    }
    
    /* Process a message received from a backend node */
    static void hm_processmsg(hm_ctx_t *ctx, apr_pool_t *p,
                              apr_sockaddr_t *from, char *buf, apr_size_t len)
    {
        apr_table_t *tbl;
    
        buf[len] = '\0';
    
        tbl = apr_table_make(p, 10);
    
        qs_to_table(buf, tbl, p);
    
        if (apr_table_get(tbl, "v") != NULL &&
            apr_table_get(tbl, "busy") != NULL &&
            apr_table_get(tbl, "ready") != NULL) {
            char *ip;
            int port = 80;
            hm_server_t *s;
            /* TODO: REMOVE ME BEFORE PRODUCTION (????) */
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(02086)
                         "%pI busy=%s ready=%s", from,
                         apr_table_get(tbl, "busy"), apr_table_get(tbl, "ready"));
    
            apr_sockaddr_ip_get(&ip, from);
    
            if (apr_table_get(tbl, "port") != NULL)
                port = atoi(apr_table_get(tbl, "port"));
    
            s = hm_get_server(ctx, ip, port);
    
            s->busy = atoi(apr_table_get(tbl, "busy"));
            s->ready = atoi(apr_table_get(tbl, "ready"));
            s->seen = apr_time_now();
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ctx->s, APLOGNO(02087)
                         "malformed message from %pI",
                         from);
        }
    
    }
    /* Read message from multicast socket */
    #define MAX_MSG_LEN (1000)
    static apr_status_t hm_recv(hm_ctx_t *ctx, apr_pool_t *p)
    {
        char buf[MAX_MSG_LEN + 1];
        apr_sockaddr_t from;
        apr_size_t len = MAX_MSG_LEN;
        apr_status_t rv;
    
        from.pool = p;
    
        rv = apr_socket_recvfrom(&from, ctx->sock, 0, buf, &len);
    
        if (APR_STATUS_IS_EAGAIN(rv)) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02088) "would block");
            return APR_SUCCESS;
        }
        else if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02089) "recvfrom failed");
            return rv;
        }
    
        hm_processmsg(ctx, p, &from, buf, len);
    
        return rv;
    }
    
    static apr_status_t hm_watchdog_callback(int state, void *data,
                                             apr_pool_t *pool)
    {
        apr_status_t rv = APR_SUCCESS;
        apr_time_t cur, now;
        hm_ctx_t *ctx = (hm_ctx_t *)data;
    
        if (!ctx->active) {
            return rv;
        }
    
        switch (state) {
            case AP_WATCHDOG_STATE_STARTING:
                rv = hm_listen(ctx);
                if (rv) {
                    ctx->status = rv;
                    ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s, APLOGNO(02090)
                                 "Unable to listen for connections!");
                }
                else {
                    ctx->keep_running = 1;
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(02091)
                                 "%s listener started.",
                                 HM_WATHCHDOG_NAME);
                }
            break;
            case AP_WATCHDOG_STATE_RUNNING:
                /* store in the slotmem or in the file depending on configuration */
                hm_update_stats(ctx, pool);
                cur = now = apr_time_sec(apr_time_now());
    
                while ((now - cur) < apr_time_sec(ctx->interval)) {
                    int n;
                    apr_status_t rc;
                    apr_pool_t *p;
                    apr_pollfd_t pfd;
                    apr_interval_time_t timeout;
    
                    apr_pool_create(&p, pool);
                    apr_pool_tag(p, "hm_running");
    
                    pfd.desc_type = APR_POLL_SOCKET;
                    pfd.desc.s = ctx->sock;
                    pfd.p = p;
                    pfd.reqevents = APR_POLLIN;
    
                    timeout = apr_time_from_sec(1);
    
                    rc = apr_poll(&pfd, 1, &n, timeout);
    
                    if (!ctx->keep_running) {
                        apr_pool_destroy(p);
                        break;
                    }
                    if (rc == APR_SUCCESS && (pfd.rtnevents & APR_POLLIN)) {
                        hm_recv(ctx, p);
                    }
                    now = apr_time_sec(apr_time_now());
                    apr_pool_destroy(p);
                }
            break;
            case AP_WATCHDOG_STATE_STOPPING:
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ctx->s, APLOGNO(02092)
                             "stopping %s listener.",
                             HM_WATHCHDOG_NAME);
    
                ctx->keep_running = 0;
                if (ctx->sock) {
                    apr_socket_close(ctx->sock);
                    ctx->sock = NULL;
                }
            break;
        }
        return rv;
    }
    
    static int hm_post_config(apr_pool_t *p, apr_pool_t *plog,
                              apr_pool_t *ptemp, server_rec *s)
    {
        apr_status_t rv;
        hm_ctx_t *ctx = ap_get_module_config(s->module_config,
                                             &heartmonitor_module);
        APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *hm_watchdog_get_instance;
        APR_OPTIONAL_FN_TYPE(ap_watchdog_register_callback) *hm_watchdog_register_callback;
    
        hm_watchdog_get_instance = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_get_instance);
        hm_watchdog_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback);
        if (!hm_watchdog_get_instance || !hm_watchdog_register_callback) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(02093)
                         "mod_watchdog is required");
            return !OK;
        }
    
        /* Create the slotmem */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_CONFIG) {
            /* this is the real thing */
            if (maxworkers) {
                storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shm",
                                             AP_SLOTMEM_PROVIDER_VERSION);
                if (!storage) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02284)
                                 "failed to lookup provider 'shm' for '%s', "
                                 "maybe you need to load mod_slotmem_shm?",
                                 AP_SLOTMEM_PROVIDER_GROUP);
                    return !OK;
                }
                storage->create(&slotmem, "mod_heartmonitor", sizeof(hm_slot_server_t), maxworkers, AP_SLOTMEM_TYPE_PREGRAB, p);
                if (!slotmem) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02285)
                                 "slotmem_create for status failed");
                    return !OK;
                }
            }
        }
    
        if (!ctx->active) {
            return OK;
        }
        rv = hm_watchdog_get_instance(&ctx->watchdog,
                                      HM_WATHCHDOG_NAME,
                                      0, 1, p);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(02094)
                         "Failed to create watchdog instance (%s)",
                         HM_WATHCHDOG_NAME);
            return !OK;
        }
        /* Register a callback with zero interval. */
        rv = hm_watchdog_register_callback(ctx->watchdog,
                                           0,
                                           ctx,
                                           hm_watchdog_callback);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(02095)
                         "Failed to register watchdog callback (%s)",
                         HM_WATHCHDOG_NAME);
            return !OK;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02096)
                     "wd callback %s", HM_WATHCHDOG_NAME);
        return OK;
    }
    
    static int hm_handler(request_rec *r)
    {
        apr_bucket_brigade *input_brigade;
        apr_size_t len;
        char *buf;
        apr_status_t status;
        apr_table_t *tbl;
        hm_server_t hmserver;
        char *ip;
        hm_ctx_t *ctx;
    
        if (strcmp(r->handler, "heartbeat")) {
            return DECLINED;
        }
        if (r->method_number != M_POST) {
            return HTTP_METHOD_NOT_ALLOWED;
        }
    
        len = MAX_MSG_LEN;
        ctx = ap_get_module_config(r->server->module_config,
                &heartmonitor_module);
    
        buf = apr_pcalloc(r->pool, MAX_MSG_LEN);
        input_brigade = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
        status = ap_get_brigade(r->input_filters, input_brigade, AP_MODE_READBYTES, APR_BLOCK_READ, MAX_MSG_LEN);
        if (status != APR_SUCCESS) {
            return ap_map_http_request_error(status, HTTP_BAD_REQUEST);
        }
        apr_brigade_flatten(input_brigade, buf, &len);
    
        /* we can't use hm_processmsg because it uses hm_get_server() */
        buf[len] = '\0';
        tbl = apr_table_make(r->pool, 10);
        qs_to_table(buf, tbl, r->pool);
        apr_sockaddr_ip_get(&ip, r->connection->client_addr);
        hmserver.ip = ip;
        hmserver.port = 80;
        if (apr_table_get(tbl, "port") != NULL)
            hmserver.port = atoi(apr_table_get(tbl, "port"));
        hmserver.busy = atoi(apr_table_get(tbl, "busy"));
        hmserver.ready = atoi(apr_table_get(tbl, "ready"));
        hmserver.seen = apr_time_now();
        hm_update_stat(ctx, &hmserver, r->pool);
    
        ap_set_content_type_ex(r, "text/plain", 1);
        ap_set_content_length(r, 2);
        ap_rputs("OK", r);
        ap_rflush(r);
    
        return OK;
    }
    
    static void hm_register_hooks(apr_pool_t *p)
    {
        static const char * const aszSucc[]={ "mod_proxy.c", NULL };
        ap_hook_post_config(hm_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    
        ap_hook_handler(hm_handler, NULL, aszSucc, APR_HOOK_FIRST);
    }
    
    static void *hm_create_config(apr_pool_t *p, server_rec *s)
    {
        hm_ctx_t *ctx = (hm_ctx_t *) apr_palloc(p, sizeof(hm_ctx_t));
    
        ctx->active = 0;
        ctx->storage_path = ap_runtime_dir_relative(p, DEFAULT_HEARTBEAT_STORAGE);
        /* TODO: Add directive for tuning the update interval
         */
        ctx->interval = apr_time_from_sec(HM_UPDATE_SEC);
        ctx->s = s;
        apr_pool_create(&ctx->p, p);
        apr_pool_tag(ctx->p, "hm_ctx");
        ctx->servers = apr_hash_make(ctx->p);
    
        return ctx;
    }
    
    static const char *cmd_hm_storage(cmd_parms *cmd,
                                      void *dconf, const char *path)
    {
        apr_pool_t *p = cmd->pool;
        hm_ctx_t *ctx =
            (hm_ctx_t *) ap_get_module_config(cmd->server->module_config,
                                              &heartmonitor_module);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        ctx->storage_path = ap_runtime_dir_relative(p, path);
    
        return NULL;
    }
    
    static const char *cmd_hm_listen(cmd_parms *cmd,
                                     void *dconf, const char *mcast_addr)
    {
        apr_status_t rv;
        char *host_str;
        char *scope_id;
        apr_port_t port = 0;
        apr_pool_t *p = cmd->pool;
        hm_ctx_t *ctx =
            (hm_ctx_t *) ap_get_module_config(cmd->server->module_config,
                                              &heartmonitor_module);
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        if (!ctx->active) {
            ctx->active = 1;
        }
        else {
            return "HeartbeatListen: May only be specified once.";
        }
    
        rv = apr_parse_addr_port(&host_str, &scope_id, &port, mcast_addr, cmd->temp_pool);
    
        if (rv) {
            return "HeartbeatListen: Unable to parse multicast address.";
        }
    
        if (host_str == NULL) {
            return "HeartbeatListen: No host provided in multicast address";
        }
    
        if (port == 0) {
            return "HeartbeatListen: No port provided in multicast address";
        }
    
        rv = apr_sockaddr_info_get(&ctx->mcast_addr, host_str, APR_INET, port, 0,
                                   p);
    
        if (rv) {
            return
                "HeartbeatListen: apr_sockaddr_info_get failed on multicast address";
        }
    
        return NULL;
    }
    
    static const char *cmd_hm_maxworkers(cmd_parms *cmd,
                                      void *dconf, const char *data)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        maxworkers = atoi(data);
        if (maxworkers != 0 && maxworkers < 10)
            return "HeartbeatMaxServers: Should be 0 for file storage, "
                   "or greater or equal than 10 for slotmem";
    
        return NULL;
    }
    
    static const command_rec hm_cmds[] = {
        AP_INIT_TAKE1("HeartbeatListen", cmd_hm_listen, NULL, RSRC_CONF,
                      "Address to listen for heartbeat requests"),
        AP_INIT_TAKE1("HeartbeatStorage", cmd_hm_storage, NULL, RSRC_CONF,
                      "Path to store heartbeat data."),
        AP_INIT_TAKE1("HeartbeatMaxServers", cmd_hm_maxworkers, NULL, RSRC_CONF,
                      "Max number of servers when using slotmem (instead file) to store heartbeat data."),
        {NULL}
    };
    
    AP_DECLARE_MODULE(heartmonitor) = {
        STANDARD20_MODULE_STUFF,
        NULL,                       /* create per-directory config structure */
        NULL,                       /* merge per-directory config structures */
        hm_create_config,           /* create per-server config structure */
        NULL,                       /* merge per-server config structures */
        hm_cmds,                    /* command apr_table_t */
        hm_register_hooks
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/cluster/mod_heartbeat.dep������������������������������������������������������0000664�0001751�0001751�00000003713�12674411515�021255� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_heartbeat.mak
    
    .\mod_heartbeat.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	"..\core\mod_watchdog.h"\
    	
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    �����������������������������������������������������httpd-2.4.64/modules/cluster/config5.m4�������������������������������������������������������������0000664�0001751�0001751�00000000666�11707053320�017555� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    APACHE_MODPATH_INIT(cluster)
    
    heartbeat_objects='mod_heartbeat.lo'
    
    case "$host" in
      *os2*)
        # OS/2 DLLs must resolve all symbols at build time
        # and we need some from the watchdog module
        heartbeat_objects="$heartbeat_objects ../core/mod_watchdog.la"
        ;;
    esac
    
    APACHE_MODULE(heartbeat, Generates Heartbeats, $heartbeat_objects, , , , watchdog)
    APACHE_MODULE(heartmonitor, Collects Heartbeats, , , )
    
    APACHE_MODPATH_FINISH
    ��������������������������������������������������������������������������httpd-2.4.64/modules/cluster/mod_heartmonitor.dsp���������������������������������������������������0000664�0001751�0001751�00000011607�11203324224�022033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_heartmonitor" - 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_heartmonitor - 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_heartmonitor.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_heartmonitor.mak" CFG="mod_heartmonitor - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_heartmonitor - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_heartmonitor - 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_heartmonitor - 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 "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_heartmonitor_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 0x409 /fo"Release/mod_heartmonitor.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_heartmonitor.so" /d LONG_NAME="heartmonitor_module for Apache"
    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 /out:".\Release\mod_heartmonitor.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartmonitor.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_heartmonitor.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartmonitor.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_heartmonitor.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_heartmonitor - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../core" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_heartmonitor_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 0x409 /fo"Debug/mod_heartmonitor.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_heartmonitor.so" /d LONG_NAME="heartmonitor_module for Apache"
    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 /out:".\Debug\mod_heartmonitor.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartmonitor.so
    # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_heartmonitor.so" /base:@..\..\os\win32\BaseAddr.ref,mod_heartmonitor.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_heartmonitor.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_heartmonitor - Win32 Release"
    # Name "mod_heartmonitor - 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_heartmonitor.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\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016122� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter.mak���������������������������������������������������0000664�0001751�0001751�00000024261�12701473373�021735� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_case_filter.dsp
    !IF "$(CFG)" == ""
    CFG=mod_case_filter - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_case_filter - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_case_filter - Win32 Release" && "$(CFG)" != "mod_case_filter - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_case_filter.mak" CFG="mod_case_filter - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_case_filter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_case_filter - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_case_filter - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_case_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_case_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_case_filter.obj"
    	-@erase "$(INTDIR)\mod_case_filter.res"
    	-@erase "$(INTDIR)\mod_case_filter_src.idb"
    	-@erase "$(INTDIR)\mod_case_filter_src.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter.exp"
    	-@erase "$(OUTDIR)\mod_case_filter.lib"
    	-@erase "$(OUTDIR)\mod_case_filter.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_case_filter_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_case_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_case_filter.so" /d LONG_NAME="case_filter_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_case_filter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_case_filter.pdb" /debug /out:"$(OUTDIR)\mod_case_filter.so" /implib:"$(OUTDIR)\mod_case_filter.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_case_filter.obj" \
    	"$(INTDIR)\mod_case_filter.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_case_filter.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_case_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_case_filter.so"
       if exist .\Release\mod_case_filter.so.manifest mt.exe -manifest .\Release\mod_case_filter.so.manifest -outputresource:.\Release\mod_case_filter.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_case_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_case_filter.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_case_filter.obj"
    	-@erase "$(INTDIR)\mod_case_filter.res"
    	-@erase "$(INTDIR)\mod_case_filter_src.idb"
    	-@erase "$(INTDIR)\mod_case_filter_src.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter.exp"
    	-@erase "$(OUTDIR)\mod_case_filter.lib"
    	-@erase "$(OUTDIR)\mod_case_filter.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_case_filter_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_case_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_case_filter.so" /d LONG_NAME="case_filter_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_case_filter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_case_filter.pdb" /debug /out:"$(OUTDIR)\mod_case_filter.so" /implib:"$(OUTDIR)\mod_case_filter.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_case_filter.obj" \
    	"$(INTDIR)\mod_case_filter.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_case_filter.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_case_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_case_filter.so"
       if exist .\Debug\mod_case_filter.so.manifest mt.exe -manifest .\Debug\mod_case_filter.so.manifest -outputresource:.\Debug\mod_case_filter.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_case_filter.dep")
    !INCLUDE "mod_case_filter.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_case_filter.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_case_filter - Win32 Release" || "$(CFG)" == "mod_case_filter - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_case_filter - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_case_filter - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_case_filter - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_case_filter - Win32 Release"
    
    
    "$(INTDIR)\mod_case_filter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_case_filter.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_case_filter.so" /d LONG_NAME="case_filter_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_case_filter - Win32 Debug"
    
    
    "$(INTDIR)\mod_case_filter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_case_filter.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_case_filter.so" /d LONG_NAME="case_filter_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_case_filter.c
    
    "$(INTDIR)\mod_case_filter.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter.dep���������������������������������������������������0000664�0001751�0001751�00000003172�12674411515�021732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_case_filter.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_case_filter.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/README����������������������������������������������������������������0000664�0001751�0001751�00000004436�12757564422�017015� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������README for Apache 2.0 Example Module
    [April, 1997, updated May 2000]
    
    The files in the src/modules/examples 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_hooks.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-hooks-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-hooks
    to the other ./configure arguments executed from the httpd source tree.
    After that run 'make'.
    
    To add another module of your own:
    
        A. cp modules/examples/mod_example_hooks.c modules/examples/mod_myexample.c
        B. Modify the file
        C. Add an entry to modules/examples/config.m4, e.g.
             APACHE_MODULE(myexample, my new module, , , no)
           The last argument specifies if the module is built by-default
        D. Build the server with --enable-myexample
    
    For windows, the process is slightly different;
    
        A. copy modules\examples\mod_example_hooks.c modules\examples\mod_myexample.c
        B. copy modules\examples\mod_example_hooks.dsp modules\examples\mod_myexample.dsp
        C. replace the occurrences of 'example_hooks' with your module name.
        D. add the new .dsp to your Apache.dsw workspace, with dependencies
           on the libapr, libaprutil and libhttpd projects.  With the newer
           Developer Studio 2002 through 2005, when you add the new .dsp
           file it will be converted to a .vcproj file.
    
    To activate the example module, include a block similar to the
    following in your httpd.conf file:
    
        <Location /example-info>
    	SetHandler example-hooks-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-hooks-handler .example
    
    After reloading/restarting your server, you should be able to browse
    to this location and see the brief display mentioned earlier.
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_ipc.mak���������������������������������������������������0000664�0001751�0001751�00000024261�12701473373�021743� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_example_ipc.dsp
    !IF "$(CFG)" == ""
    CFG=mod_example_ipc - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_example_ipc - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_example_ipc - Win32 Release" && "$(CFG)" != "mod_example_ipc - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_example_ipc.mak" CFG="mod_example_ipc - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_example_ipc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_example_ipc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_example_ipc - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_example_ipc.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_example_ipc.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_example_ipc.obj"
    	-@erase "$(INTDIR)\mod_example_ipc.res"
    	-@erase "$(INTDIR)\mod_example_ipc_src.idb"
    	-@erase "$(INTDIR)\mod_example_ipc_src.pdb"
    	-@erase "$(OUTDIR)\mod_example_ipc.exp"
    	-@erase "$(OUTDIR)\mod_example_ipc.lib"
    	-@erase "$(OUTDIR)\mod_example_ipc.pdb"
    	-@erase "$(OUTDIR)\mod_example_ipc.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_example_ipc_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_example_ipc.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_example_ipc.so" /d LONG_NAME="example_ipc_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_example_ipc.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_example_ipc.pdb" /debug /out:"$(OUTDIR)\mod_example_ipc.so" /implib:"$(OUTDIR)\mod_example_ipc.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_example_ipc.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_example_ipc.obj" \
    	"$(INTDIR)\mod_example_ipc.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_example_ipc.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_example_ipc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_example_ipc.so"
       if exist .\Release\mod_example_ipc.so.manifest mt.exe -manifest .\Release\mod_example_ipc.so.manifest -outputresource:.\Release\mod_example_ipc.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_example_ipc - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_example_ipc.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_example_ipc.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_example_ipc.obj"
    	-@erase "$(INTDIR)\mod_example_ipc.res"
    	-@erase "$(INTDIR)\mod_example_ipc_src.idb"
    	-@erase "$(INTDIR)\mod_example_ipc_src.pdb"
    	-@erase "$(OUTDIR)\mod_example_ipc.exp"
    	-@erase "$(OUTDIR)\mod_example_ipc.lib"
    	-@erase "$(OUTDIR)\mod_example_ipc.pdb"
    	-@erase "$(OUTDIR)\mod_example_ipc.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_example_ipc_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_example_ipc.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_example_ipc.so" /d LONG_NAME="example_ipc_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_example_ipc.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_example_ipc.pdb" /debug /out:"$(OUTDIR)\mod_example_ipc.so" /implib:"$(OUTDIR)\mod_example_ipc.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_example_ipc.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_example_ipc.obj" \
    	"$(INTDIR)\mod_example_ipc.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_example_ipc.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_example_ipc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_example_ipc.so"
       if exist .\Debug\mod_example_ipc.so.manifest mt.exe -manifest .\Debug\mod_example_ipc.so.manifest -outputresource:.\Debug\mod_example_ipc.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_example_ipc.dep")
    !INCLUDE "mod_example_ipc.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_example_ipc.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_example_ipc - Win32 Release" || "$(CFG)" == "mod_example_ipc - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_example_ipc - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_example_ipc - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_example_ipc - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_example_ipc - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_example_ipc - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_example_ipc - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_example_ipc - Win32 Release"
    
    
    "$(INTDIR)\mod_example_ipc.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_example_ipc.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_example_ipc.so" /d LONG_NAME="example_ipc_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_example_ipc - Win32 Debug"
    
    
    "$(INTDIR)\mod_example_ipc.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_example_ipc.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_example_ipc.so" /d LONG_NAME="example_ipc_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_example_ipc.c
    
    "$(INTDIR)\mod_example_ipc.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_ipc.dep���������������������������������������������������0000664�0001751�0001751�00000003765�12674411515�021750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_example_ipc.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_example_ipc.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������httpd-2.4.64/modules/examples/NWGNUcase_flt���������������������������������������������������������0000664�0001751�0001751�00000010265�11540546347�020447� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= case_flt
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Case Filter Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_NAME) 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	=
    
    #
    # 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)/$(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_case_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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	case_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter_in.c��������������������������������������������������0000664�0001751�0001751�00000011204�13775037340�022070� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <ctype.h>
    
    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;
            apr_size_t 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 = ap_malloc(len);
            for (n=0 ; n < len ; ++n) {
                buf[n] = apr_toupper(data[n]);
            }
    
            pbktOut = apr_bucket_heap_create(buf, len, free, 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);
    }
    
    AP_DECLARE_MODULE(case_filter_in) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        CaseFilterInCreateServerConfig,
        NULL,
        CaseFilterInCmds,
        CaseFilterInRegisterHooks
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_hooks.mak�������������������������������������������������0000664�0001751�0001751�00000024541�12701473373�022314� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_example_hooks.dsp
    !IF "$(CFG)" == ""
    CFG=mod_example_hooks - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_example_hooks - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_example_hooks - Win32 Release" && "$(CFG)" != "mod_example_hooks - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_example_hooks.mak" CFG="mod_example_hooks - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_example_hooks - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_example_hooks - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_example_hooks - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_example_hooks.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_example_hooks.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_example_hooks.obj"
    	-@erase "$(INTDIR)\mod_example_hooks.res"
    	-@erase "$(INTDIR)\mod_example_hooks_src.idb"
    	-@erase "$(INTDIR)\mod_example_hooks_src.pdb"
    	-@erase "$(OUTDIR)\mod_example_hooks.exp"
    	-@erase "$(OUTDIR)\mod_example_hooks.lib"
    	-@erase "$(OUTDIR)\mod_example_hooks.pdb"
    	-@erase "$(OUTDIR)\mod_example_hooks.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_example_hooks_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_example_hooks.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_example_hooks.so" /d LONG_NAME="example_hooks_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_example_hooks.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_example_hooks.pdb" /debug /out:"$(OUTDIR)\mod_example_hooks.so" /implib:"$(OUTDIR)\mod_example_hooks.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_example_hooks.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_example_hooks.obj" \
    	"$(INTDIR)\mod_example_hooks.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_example_hooks.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_example_hooks.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_example_hooks.so"
       if exist .\Release\mod_example_hooks.so.manifest mt.exe -manifest .\Release\mod_example_hooks.so.manifest -outputresource:.\Release\mod_example_hooks.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_example_hooks - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_example_hooks.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_example_hooks.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_example_hooks.obj"
    	-@erase "$(INTDIR)\mod_example_hooks.res"
    	-@erase "$(INTDIR)\mod_example_hooks_src.idb"
    	-@erase "$(INTDIR)\mod_example_hooks_src.pdb"
    	-@erase "$(OUTDIR)\mod_example_hooks.exp"
    	-@erase "$(OUTDIR)\mod_example_hooks.lib"
    	-@erase "$(OUTDIR)\mod_example_hooks.pdb"
    	-@erase "$(OUTDIR)\mod_example_hooks.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_example_hooks_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_example_hooks.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_example_hooks.so" /d LONG_NAME="example_hooks_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_example_hooks.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_example_hooks.pdb" /debug /out:"$(OUTDIR)\mod_example_hooks.so" /implib:"$(OUTDIR)\mod_example_hooks.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_example_hooks.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_example_hooks.obj" \
    	"$(INTDIR)\mod_example_hooks.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_example_hooks.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_example_hooks.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_example_hooks.so"
       if exist .\Debug\mod_example_hooks.so.manifest mt.exe -manifest .\Debug\mod_example_hooks.so.manifest -outputresource:.\Debug\mod_example_hooks.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_example_hooks.dep")
    !INCLUDE "mod_example_hooks.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_example_hooks.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_example_hooks - Win32 Release" || "$(CFG)" == "mod_example_hooks - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_example_hooks - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_example_hooks - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_example_hooks - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_example_hooks - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_example_hooks - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_example_hooks - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_example_hooks - Win32 Release"
    
    
    "$(INTDIR)\mod_example_hooks.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_example_hooks.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_example_hooks.so" /d LONG_NAME="example_hooks_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_example_hooks - Win32 Debug"
    
    
    "$(INTDIR)\mod_example_hooks.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_example_hooks.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_example_hooks.so" /d LONG_NAME="example_hooks_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_example_hooks.c
    
    "$(INTDIR)\mod_example_hooks.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_hooks.dep�������������������������������������������������0000664�0001751�0001751�00000004266�12674411515�022315� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_example_hooks.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_example_hooks.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.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\httpd.h"\
    	"..\..\include\mpm_common.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_script.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/NWGNUmakefile���������������������������������������������������������0000664�0001751�0001751�00000011226�11657403725�020443� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    #
    # If there is only one element to build it needs to be included twice
    # in the below target list.
    # Normally if there is only one element to be built within a
    # directory, the makefile for the single element would be called NWGNUmakefile.
    # But if there are multiples, the parent NWGNUmakefile must reference more
    # than one submakefile. Because the experimental directory might vary in the
    # number of submakefiles, but for the moment only contains one, we reference
    # it twice to allow it parent NWGNUmakefile to work properly.  If another
    # submakefile is added, the extra reference to the first NLM should be removed.
    TARGET_nlm = \
    	$(OBJDIR)/example_hooks.nlm \
    	$(OBJDIR)/example_ipc.nlm \
    	$(OBJDIR)/case_flt.nlm \
    	$(OBJDIR)/case_flt_in.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/NWGNUexample_hooks����������������������������������������������������0000664�0001751�0001751�00000010407�11540546347�021523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/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	= example_hooks
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Example Hook Callback Handler Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Example Hook Callback Handler 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	=
    
    #
    # 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)/example_hooks.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_hooks.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	example_hooks_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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/config.m4�������������������������������������������������������������0000664�0001751�0001751�00000000550�10720056417�017621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    APACHE_MODPATH_INIT(examples)
    
    APACHE_MODULE(example_hooks, Example hook callback handler module, , , no)
    APACHE_MODULE(case_filter, Example uppercase conversion filter, , , no)
    APACHE_MODULE(case_filter_in, Example uppercase conversion input filter, , , no)
    APACHE_MODULE(example_ipc, Example of shared memory and mutex usage, , , no)
    
    APACHE_MODPATH_FINISH
    ��������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_hooks.c���������������������������������������������������0000664�0001751�0001751�00000161631�14640775605�021777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_hooks 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_'.
     *
     * To use mod_example_hooks, configure the Apache build with
     * --enable-example-hooks and compile.  Set up a <Location> block in your
     * configuration file like so:
     *
     * <Location /example>
     *    SetHandler example-hooks-handler
     * </Location>
     *
     * When you look at that location on your server, you will see a backtrace of
     * the callbacks that have been invoked up to that point.  See the ErrorLog for
     * more information on code paths that  touch mod_example_hooks.
     *
     * IMPORTANT NOTES
     * ===============
     *
     * Do NOT use this module on a production server. It attaches itself to every
     * phase of the server runtime operations including startup, shutdown and
     * request processing, and produces copious amounts of logging data.  This will
     * negatively affect server performance.
     *
     * Do NOT use mod_example_hooks as the basis for your own code.  This module
     * implements every callback hook offered by the Apache core, and your
     * module will almost certainly not have to implement this much.  If you
     * want a simple module skeleton to start development, use apxs -g.
     *
     * XXX TO DO XXX
     * =============
     *
     * * Enable HTML backtrace entries for more callbacks that are not directly
     *   associated with a request
     * * Make sure every callback that posts an HTML backtrace entry does so in the *   right category, so nothing gets overwritten
     * * Implement some logic to show what happens in the parent, and what in the
     *   child(ren)
     */
    
    #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"
    #ifdef HAVE_UNIX_SUEXEC
    #include "unixd.h"
    #endif
    #include "scoreboard.h"
    #include "mpm_common.h"
    
    #include "apr_strings.h"
    
    #include <stdio.h>
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* 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;
    
    /*
     * String pointer to hold the startup trace. No harm working with a global until
     * the server is (may be) multi-threaded.
     */
    static const char *trace = 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_hooks_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_hooks_module);
    }
    
    /*
     * The following utility routines are not used in the module. Don't
     * compile them so -Wall doesn't complain about functions that are
     * defined but not used.
     */
    #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_hooks_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_hooks_module);
    }
    #endif /* if 0 */
    
    /*
     * 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_hooks_module);
    }
    
    /*
     * 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.
     */
    #ifndef EXAMPLE_LOG_EACH
    #define EXAMPLE_LOG_EACH 0
    #endif
    
    #if EXAMPLE_LOG_EACH
    static void example_log_each(apr_pool_t *p, server_rec *s, const char *note)
    {
        if (s != NULL) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02991)
                         "mod_example_hooks: %s", note);
        }
        else {
            apr_file_t *out = NULL;
            apr_file_open_stderr(&out, p);
            apr_file_printf(out, "mod_example_hooks traced in non-loggable "
                            "context: %s\n", note);
        }
    }
    #endif
    
    /*
     * This utility routine traces the hooks called when the server starts up.
     * It leaves a trace in a global variable, so it should not be called from
     * a hook handler that runs in a multi-threaded situation.
     */
    
    static void trace_startup(apr_pool_t *p, server_rec *s, x_cfg *mconfig,
                              const char *note)
    {
        const char *sofar;
        char *where, *addon;
    
    #if EXAMPLE_LOG_EACH
        example_log_each(p, s, note);
    #endif
    
        /*
         * 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 : "";
    
        addon = apr_pstrcat(p,
                            "   <li>\n"
                            "    <dl>\n"
                            "     <dt><samp>", note, "</samp></dt>\n"
                            "     <dd><samp>[", where, "]</samp></dd>\n"
                            "    </dl>\n"
                            "   </li>\n",
                            NULL);
    
        /*
         * Make sure that we start with a valid string, even if we have never been
         * called.
         */
        sofar = (trace == NULL) ? "" : trace;
    
        trace = apr_pstrcat(p, sofar, addon, NULL);
    }
    
    
    /*
     * This utility route traces the hooks called as a request is handled.
     * It takes the current request as argument
     */
    #define TRACE_NOTE "example-hooks-trace"
    
    static void trace_request(const request_rec *r, const char *note)
    {
        const char *trace_copy, *sofar;
        char *addon, *where;
        x_cfg *cfg;
    
    #if EXAMPLE_LOG_EACH
        example_log_each(r->pool, r->server, note);
    #endif
    
        if ((sofar = apr_table_get(r->notes, TRACE_NOTE)) == NULL) {
            sofar = "";
        }
    
        cfg = our_dconfig(r);
    
        where = (cfg != NULL) ? cfg->loc : "nowhere";
        where = (where != NULL) ? where : "";
    
        addon = apr_pstrcat(r->pool,
                            "   <li>\n"
                            "    <dl>\n"
                            "     <dt><samp>", note, "</samp></dt>\n"
                            "     <dd><samp>[", where, "]</samp></dd>\n"
                            "    </dl>\n"
                            "   </li>\n",
                            NULL);
    
        trace_copy = apr_pstrcat(r->pool, sofar, addon, NULL);
        apr_table_set(r->notes, TRACE_NOTE, trace_copy);
    }
    
    /*
     * This utility routine traces the hooks called while processing a
     * Connection. Its trace is kept in the pool notes of the pool associated
     * with the Connection.
     */
    
    /*
     * Key to get and set the userdata.  We should be able to get away
     * with a constant key, since in prefork mode the process will have
     * the connection and its pool to itself entirely, and in
     * multi-threaded mode each connection will have its own pool.
     */
    #define CONN_NOTE "example-hooks-connection"
    
    static void trace_connection(conn_rec *c, const char *note)
    {
        const char *trace_copy, *sofar;
        char *addon, *where;
        void *data;
        x_cfg *cfg;
    
    #if EXAMPLE_LOG_EACH
        example_log_each(c->pool, c->base_server, note);
    #endif
    
        cfg = our_cconfig(c);
    
        where = (cfg != NULL) ? cfg->loc : "nowhere";
        where = (where != NULL) ? where : "";
    
        addon = apr_pstrcat(c->pool,
                            "   <li>\n"
                            "    <dl>\n"
                            "     <dt><samp>", note, "</samp></dt>\n"
                            "     <dd><samp>[", where, "]</samp></dd>\n"
                            "    </dl>\n"
                            "   </li>\n",
                            NULL);
    
        /* Find existing notes and copy */
        apr_pool_userdata_get(&data, CONN_NOTE, c->pool);
        sofar = (data == NULL) ? "" : (const char *) data;
    
        /* Tack addon onto copy */
        trace_copy = apr_pstrcat(c->pool, sofar, addon, NULL);
    
        /*
         * Stash copy back into pool notes.  This call has a cleanup
         * parameter, but we're not using it because the string has been
         * allocated from that same pool.  There is also an unused return
         * value: we have nowhere to communicate any error that might
         * occur, and will have to check for the existence of this data on
         * the other end.
         */
        apr_pool_userdata_set((const void *) trace_copy, CONN_NOTE,
                              NULL, c->pool);
    }
    
    static void trace_nocontext(apr_pool_t *p, const char *file, int line,
                                const char *note)
    {
        /*
         * Since we have no request or connection to trace, or any idea
         * from where this routine was called, there's really not much we
         * can do.  If we are not logging everything by way of the
         * EXAMPLE_LOG_EACH constant, do nothing in this routine.
         */
    
    #ifdef EXAMPLE_LOG_EACH
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_NOTICE, 0, p, "%s", note);
    #endif
    }
    
    
    /*--------------------------------------------------------------------------*/
    /* 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_startup(cmd->pool, cmd->server, cfg, "cmd_example()");
        return NULL;
    }
    
    /*
     * 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 <Location>, <Directory>, 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;
        char *note;
    
        /*
         * 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);
        note = apr_psprintf(p, "x_create_dir_config(p == %pp, dirspec == %s)",
                            (void*) p, dirspec);
        trace_startup(p, NULL, cfg, note);
        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 <Location> 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_psprintf(p, "x_merge_dir_config(p == %pp, parent_conf == "
                            "%pp, newloc_conf == %pp)", (void*) p,
                            (void*) parent_conf, (void*) newloc_conf);
        trace_startup(p, 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_startup(p, s, 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_startup(p, NULL, merged_config, note);
        return (void *) merged_config;
    }
    
    
    /*--------------------------------------------------------------------------*
     *                                                                          *
     * Now let's declare routines for each of the callback hooks 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_hooks" 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.                                                    *
     *                                                                          *
     * There are three types of hooks (see include/ap_config.h):                *
     *                                                                          *
     * VOID      : No return code, run all handlers declared by any module      *
     * RUN_FIRST : Run all handlers until one returns something other           *
     *             than DECLINED. Hook runner result is result of last callback *
     * RUN_ALL   : Run all handlers until one returns something other than OK   *
     *             or DECLINED. The hook runner returns that other value. If    *
     *             all hooks run, the hook runner returns OK.                   *
     *                                                                          *
     * 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.             *
     *                                                                          *
     * See include/httpd.h for a list of HTTP_mumble status codes.  Handlers    *
     * that are not declared as int return a valid pointer, or NULL if they     *
     * DECLINE to handle their phase for that specific request.  Exceptions, if *
     * any, are noted with each routine.                                        *
     *--------------------------------------------------------------------------*/
    
    /*
     * 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_startup(pconf, NULL, NULL, "x_pre_config()");
        return OK;
    }
    
    /*
     * This routine is called after the server processes the configuration
     * files.  At this point the module may review and adjust its configuration
     * settings in relation to one another and report any problems.  On restart,
     * this routine will be called twice, once in the startup process (which
     * exits shortly after this phase) and once in the running server process.
     *
     * 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_check_config(apr_pool_t *pconf, apr_pool_t *plog,
                              apr_pool_t *ptemp, server_rec *s)
    {
        /*
         * Log the call and exit.
         */
        trace_startup(pconf, s, NULL, "x_check_config()");
        return OK;
    }
    
    /*
     * This routine is called when the -t command-line option is supplied.
     * It executes only once, in the startup process, after the check_config
     * phase and just before the process exits.  At this point the module
     * may output any information useful in configuration testing.
     *
     * This is a VOID hook: all defined handlers get called.
     */
    static void x_test_config(apr_pool_t *pconf, server_rec *s)
    {
        apr_file_t *out = NULL;
    
        apr_file_open_stderr(&out, pconf);
    
        apr_file_printf(out, "Example module configuration test routine\n");
    
        trace_startup(pconf, s, NULL, "x_test_config()");
    }
    
    /*
     * 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_startup(pconf, s, NULL, "x_open_logs()");
        return OK;
    }
    
    /*
     * This routine is called after the server finishes the configuration
     * process.  At this point the module may review and adjust its configuration
     * settings in relation to one another and report any problems.  On restart,
     * this routine will be called only once, in the running server process.
     *
     * 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_startup(pconf, s, NULL, "x_post_config()");
        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_startup(s->process->pool, s, NULL, note);
        return APR_SUCCESS;
    }
    
    /*
     * All our process initialiser does is add its trace to the log.
     *
     * This is a VOID hook: all defined handlers get called.
     */
    static void x_child_init(apr_pool_t *p, server_rec *s)
    {
        char *note;
        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(p, "x_child_init(", sname, ")", NULL);
        trace_startup(p, s, NULL, note);
    
        apr_pool_cleanup_register(p, s, x_child_exit, x_child_exit);
    }
    
    /*
     * The hook runner for ap_hook_http_scheme is aliased to ap_http_scheme(),
     * a routine that the core and other modules call when they need to know
     * the URL scheme for the request.  For instance, mod_ssl returns "https"
     * if the server_rec associated with the request has SSL enabled.
     *
     * This hook was named 'ap_hook_http_method' in httpd 2.0.
     *
     * This is a RUN_FIRST hook: the first handler to return a non NULL
     * value aborts the handler chain.  The http_core module inserts a
     * fallback handler (with APR_HOOK_REALLY_LAST preference) that returns
     * "http".
     */
    static const char *x_http_scheme(const request_rec *r)
    {
        /*
         * Log the call and exit.
         */
        trace_request(r, "x_http_scheme()");
    
        /* We have no claims to make about the request scheme */
        return NULL;
    }
    
    /*
     * The runner for this hook is aliased to ap_default_port(), which the
     * core and other modules call when they need to know the default port
     * for a particular server.  This is used for instance to omit the
     * port number from a Redirect response Location header URL if the port
     * number is equal to the default port for the service (like 80 for http).
     *
     * This is a RUN_FIRST hook: the first handler to return a non-zero
     * value is the last one executed.  The http_core module inserts a
     * fallback handler (with APR_HOOK_REALLY_LAST order specifier) that
     * returns 80.
     */
    static apr_port_t x_default_port(const request_rec *r)
    {
        /*
         * Log the call and exit.
         */
        trace_request(r, "x_default_port()");
        return 0;
    }
    
    /*
     * This routine is called just before the handler gets invoked. It allows
     * a module to insert a previously defined filter into the filter chain.
     *
     * No filter has been defined by this module, so we just log the call
     * and exit.
     *
     * This is a VOID hook: all defined handlers get called.
     */
    static void x_insert_filter(request_rec *r)
    {
        /*
         * Log the call and exit.
         */
        trace_request(r, "x_insert_filter()");
    }
    
    /*
     * This routine is called to insert a previously defined error filter into
     * the filter chain as the request is being processed.
     *
     * For the purpose of this example, we don't have a filter to insert,
     * so just add to the trace and exit.
     *
     * This is a VOID hook: all defined handlers get called.
     */
    static void x_insert_error_filter(request_rec *r)
    {
        trace_request(r, "x_insert_error_filter()");
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* 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.
     *
     * This routine gets called for every request, unless another handler earlier
     * in the callback chain has already handled the request. It is up to us to
     * test the request_rec->handler field and see whether we are meant to handle
     * this request.
     *
     * The content handler gets to write directly to the client using calls like
     * ap_rputs() and ap_rprintf()
     *
     * This is a RUN_FIRST hook.
     */
    static int x_handler(request_rec *r)
    {
        x_cfg *dcfg;
        char *note;
        void *conn_data;
        apr_status_t status;
    
        dcfg = our_dconfig(r);
        /*
         * Add our trace to the log, and whether we get to write
         * content for this request.
         */
        note = apr_pstrcat(r->pool, "x_handler(), handler is \"",
                          r->handler, "\"", NULL);
        trace_request(r, note);
    
        /* If it's not for us, get out as soon as possible. */
        if (strcmp(r->handler, "example-hooks-handler")) {
            return DECLINED;
        }
    
        /*
         * Set the Content-type header. Note that we do not actually have to send
         * the headers: this is done by the http core.
         */
        ap_set_content_type_ex(r, "text/html", 1);
        /*
         * 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("<HTML>\n", r);
        ap_rputs(" <HEAD>\n", r);
        ap_rputs("  <TITLE>mod_example_hooks Module Content-Handler Output\n", r);
        ap_rputs("  </TITLE>\n", r);
        ap_rputs(" </HEAD>\n", r);
        ap_rputs(" <BODY>\n", r);
        ap_rputs("  <H1><SAMP>mod_example_hooks</SAMP> Module Content-Handler Output\n", r);
        ap_rputs("  </H1>\n", r);
        ap_rputs("  <P>\n", r);
        ap_rprintf(r, "  Apache HTTP Server version: \"%s\"\n",
                ap_get_server_banner());
        ap_rputs("  <BR>\n", r);
        ap_rprintf(r, "  Server built: \"%s\"\n", ap_get_server_built());
        ap_rputs("  </P>\n", r);
        ap_rputs("  <P>\n", r);
        ap_rputs("  The format for the callback trace is:\n", r);
        ap_rputs("  </P>\n", r);
        ap_rputs("  <DL>\n", r);
        ap_rputs("   <DT><EM>n</EM>.<SAMP>&lt;routine-name&gt;", r);
        ap_rputs("(&lt;routine-data&gt;)</SAMP>\n", r);
        ap_rputs("   </DT>\n", r);
        ap_rputs("   <DD><SAMP>[&lt;applies-to&gt;]</SAMP>\n", r);
        ap_rputs("   </DD>\n", r);
        ap_rputs("  </DL>\n", r);
        ap_rputs("  <P>\n", r);
        ap_rputs("  The <SAMP>&lt;routine-data&gt;</SAMP> is supplied by\n", r);
        ap_rputs("  the routine when it requests the trace,\n", r);
        ap_rputs("  and the <SAMP>&lt;applies-to&gt;</SAMP> is extracted\n", r);
        ap_rputs("  from the configuration record at the time of the trace.\n", r);
        ap_rputs("  <STRONG>SVR()</STRONG> 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); <STRONG>DIR()</STRONG>\n", r);
        ap_rputs("  indicates a location in the URL or filesystem\n", r);
        ap_rputs("  namespace.\n", r);
        ap_rputs("  </P>\n", r);
        ap_rprintf(r, "  <H2>Startup callbacks so far:</H2>\n  <OL>\n%s  </OL>\n",
                trace);
        ap_rputs("  <H2>Connection-specific callbacks so far:</H2>\n", r);
    
        status =  apr_pool_userdata_get(&conn_data, CONN_NOTE,
                                        r->connection->pool);
        if ((status == APR_SUCCESS) && conn_data) {
            ap_rprintf(r, "  <OL>\n%s  </OL>\n", (char *) conn_data);
        }
        else {
            ap_rputs("  <P>No connection-specific callback information was "
                     "retrieved.</P>\n", r);
        }
    
        ap_rputs("  <H2>Request-specific callbacks so far:</H2>\n", r);
        ap_rprintf(r, "  <OL>\n%s  </OL>\n", apr_table_get(r->notes, TRACE_NOTE));
        ap_rputs("  <H2>Environment for <EM>this</EM> call:</H2>\n", r);
        ap_rputs("  <UL>\n", r);
        ap_rprintf(r, "   <LI>Applies-to: <SAMP>%s</SAMP>\n   </LI>\n", dcfg->loc);
        ap_rprintf(r, "   <LI>\"Example\" directive declared here: %s\n   </LI>\n",
                (dcfg->local ? "YES" : "NO"));
        ap_rprintf(r, "   <LI>\"Example\" inherited: %s\n   </LI>\n",
                (dcfg->congenital ? "YES" : "NO"));
        ap_rputs("  </UL>\n", r);
        ap_rputs(" </BODY>\n", r);
        ap_rputs("</HTML>\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;
    }
    
    /*
     * The quick_handler hook presents modules with a very powerful opportunity to
     * serve their content in a very early request phase.  Note that this handler
     * can not serve any requests from the file system because hooks like
     * map_to_storage have not run.  The quick_handler hook also runs before any
     * authentication and access control.
     *
     * This hook is used by mod_cache to serve cached content.
     *
     * This is a RUN_FIRST hook. Return OK if you have served the request,
     * DECLINED if you want processing to continue, or a HTTP_* error code to stop
     * processing the request.
     */
    static int x_quick_handler(request_rec *r, int lookup_uri)
    {
        /*
         * Log the call and exit.
         */
        trace_request(r, "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.
     *
     * This is a RUN_ALL hook.
     */
    static int x_pre_connection(conn_rec *c, void *csd)
    {
        char *note;
    
        /*
         * Log the call and exit.
         */
        note = apr_psprintf(c->pool, "x_pre_connection(c = %pp, p = %pp)",
                            (void*) c, (void*) c->pool);
        trace_connection(c, note);
    
        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.
     *
     * This is a RUN_FIRST hook.
     */
    static int x_process_connection(conn_rec *c)
    {
        trace_connection(c, "x_process_connection()");
        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.
     *
     * This is a HOOK_VOID hook.
     */
    static void x_pre_read_request(request_rec *r, conn_rec *c)
    {
        /*
         * We don't actually *do* anything here, except note the fact that we were
         * called.
         */
        trace_request(r, "x_pre_read_request()");
    }
    
    /*
     * 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.
     *
     * This is a RUN_ALL hook.
     */
    static int x_post_read_request(request_rec *r)
    {
        /*
         * We don't actually *do* anything here, except note the fact that we were
         * called.
         */
        trace_request(r, "x_post_read_request()");
        return DECLINED;
    }
    
    /*
     * This routine gives our module an opportunity to translate the URI into an
     * actual filename, before URL decoding happens.
     *
     * This is a RUN_FIRST hook.
     */
    static int x_pre_translate_name(request_rec *r)
    {
        /*
         * We don't actually *do* anything here, except note the fact that we were
         * called.
         */
        trace_request(r, "x_pre_translate_name()");
        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.
     *
     * This is a RUN_FIRST hook.
     */
    static int x_translate_name(request_rec *r)
    {
        /*
         * We don't actually *do* anything here, except note the fact that we were
         * called.
         */
        trace_request(r, "x_translate_name()");
        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.
     *
     * This is a RUN_FIRST hook.
     */
    static int x_map_to_storage(request_rec *r)
    {
        /*
         * We don't actually *do* anything here, except note the fact that we were
         * called.
         */
        trace_request(r, "x_map_to_storage()");
        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 <Directory>
     * 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.
     *
     * This is a RUN_ALL hook.
     */
    static int x_header_parser(request_rec *r)
    {
        /*
         * We don't actually *do* anything here, except note the fact that we were
         * called.
         */
        trace_request(r, "x_header_parser()");
        return DECLINED;
    }
    
    
    /*
     * This routine is called to check for any module-specific restrictions placed
     * upon the requested resource.  (See the mod_access_compat module for an
     * example.)
     *
     * This is a RUN_ALL hook. The first handler to return a status other than OK
     * or DECLINED (for instance, HTTP_FORBIDDEN) aborts the callback chain.
     */
    static int x_check_access(request_rec *r)
    {
        trace_request(r, "x_check_access()");
        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).
     *
     * This is a RUN_FIRST hook. The return value is OK, DECLINED, or some
     * HTTP_mumble error (typically HTTP_UNAUTHORIZED).
     */
    static int x_check_authn(request_rec *r)
    {
        /*
         * Don't do anything except log the call.
         */
        trace_request(r, "x_check_authn()");
        return DECLINED;
    }
    
    /*
     * This routine is called to check to see if the resource being requested
     * requires authorisation.
     *
     * This is a RUN_FIRST hook. 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_check_authz(request_rec *r)
    {
        /*
         * Log the call and return OK, or access will be denied (even though we
         * didn't actually do anything).
         */
        trace_request(r, "x_check_authz()");
        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.
     *
     * This is a RUN_FIRST hook.
     */
    static int x_type_checker(request_rec *r)
    {
        /*
         * Log the call, but don't do anything else - and report truthfully that
         * we didn't do anything.
         */
        trace_request(r, "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.
     *
     * This is a RUN_ALL HOOK.
     */
    static int x_fixups(request_rec *r)
    {
        /*
         * Log the call and exit.
         */
        trace_request(r, "x_fixups()");
        return DECLINED;
    }
    
    /*
     * This routine is called to perform any module-specific logging activities
     * over and above the normal server things.
     *
     * This is a RUN_ALL hook.
     */
    static int x_log_transaction(request_rec *r)
    {
        trace_request(r, "x_log_transaction()");
        return DECLINED;
    }
    
    #ifdef HAVE_UNIX_SUEXEC
    
    /*
     * This routine is called to find out under which user id to run suexec
     * Unless our module runs CGI programs, there is no reason for us to
     * mess with this information.
     *
     * This is a RUN_FIRST hook. The return value is a pointer to an
     * ap_unix_identity_t or NULL.
     */
    static ap_unix_identity_t *x_get_suexec_identity(const request_rec *r)
    {
        trace_request(r, "x_get_suexec_identity()");
        return NULL;
    }
    #endif
    
    /*
     * This routine is called to create a connection. This hook is implemented
     * by the Apache core: there is no known reason a module should override
     * it.
     *
     * This is a RUN_FIRST hook.
     *
     * Return NULL to decline, a valid conn_rec pointer to accept.
     */
    static conn_rec *x_create_connection(apr_pool_t *p, server_rec *server,
                                         apr_socket_t *csd, long conn_id,
                                         void *sbh, apr_bucket_alloc_t *alloc)
    {
        trace_nocontext(p, __FILE__, __LINE__, "x_create_connection()");
        return NULL;
    }
    
    /*
     * This hook is defined in server/core.c, but it is not actually called
     * or documented.
     *
     * This is a RUN_ALL hook.
     */
    static int x_get_mgmt_items(apr_pool_t *p, const char *val, apr_hash_t *ht)
    {
        /* We have nothing to do here but trace the call, and no context
         * in which to trace it.
         */
        trace_nocontext(p, __FILE__, __LINE__, "x_check_config()");
        return DECLINED;
    }
    
    /*
     * This routine gets called shortly after the request_rec structure
     * is created. It provides the opportunity to manipulae the request
     * at a very early stage.
     *
     * This is a RUN_ALL hook.
     */
    static int x_create_request(request_rec *r)
    {
        /*
         * We have a request_rec, but it is not filled in enough to give
         * us a usable configuration. So, add a trace without context.
         */
        trace_nocontext( r->pool, __FILE__, __LINE__, "x_create_request()");
        return DECLINED;
    }
    
    /*
     * This routine gets called during the startup of the MPM.
     * No known existing module implements this hook.
     *
     * This is a RUN_ALL hook.
     */
    static int x_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type)
    {
        trace_nocontext(p, __FILE__, __LINE__, "x_pre_mpm()");
        return DECLINED;
    }
    
    /*
     * This hook gets run periodically by a maintenance function inside
     * the MPM. Its exact purpose is unknown and undocumented at this time.
     *
     * This is a RUN_ALL hook.
     */
    static int x_monitor(apr_pool_t *p, server_rec *s)
    {
        trace_nocontext(p, __FILE__, __LINE__, "x_monitor()");
        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)
    {
        trace = NULL;
        ap_hook_pre_config(x_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_config(x_check_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_test_config(x_test_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_open_logs(x_open_logs, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_config(x_post_config, 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);
        ap_hook_pre_read_request(x_pre_read_request, 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_log_transaction, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_http_scheme(x_http_scheme, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_default_port(x_default_port, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_pre_translate_name(x_pre_translate_name, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_translate_name(x_translate_name, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_map_to_storage(x_map_to_storage, NULL,NULL, APR_HOOK_MIDDLE);
        ap_hook_header_parser(x_header_parser, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_fixups(x_fixups, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_type_checker(x_type_checker, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_access(x_check_access, NULL, NULL, APR_HOOK_MIDDLE,
                             AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_check_authn(x_check_authn, NULL, NULL, APR_HOOK_MIDDLE,
                            AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_check_authz(x_check_authz, NULL, NULL, APR_HOOK_MIDDLE,
                            AP_AUTH_INTERNAL_PER_CONF);
        ap_hook_insert_filter(x_insert_filter, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_insert_error_filter(x_insert_error_filter, NULL, NULL, APR_HOOK_MIDDLE);
    #ifdef HAVE_UNIX_SUEXEC
        ap_hook_get_suexec_identity(x_get_suexec_identity, NULL, NULL, APR_HOOK_MIDDLE);
    #endif
        ap_hook_create_connection(x_create_connection, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_get_mgmt_items(x_get_mgmt_items, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_create_request(x_create_request, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_pre_mpm(x_pre_mpm, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_monitor(x_monitor, 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.
     */
    AP_DECLARE_MODULE(example_hooks) =
    {
        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 */
    };
    �������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter_in.mak������������������������������������������������0000664�0001751�0001751�00000024671�12701473373�022430� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_case_filter_in.dsp
    !IF "$(CFG)" == ""
    CFG=mod_case_filter_in - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_case_filter_in - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_case_filter_in - Win32 Release" && "$(CFG)" != "mod_case_filter_in - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_case_filter_in.mak" CFG="mod_case_filter_in - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_case_filter_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_case_filter_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_case_filter_in - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_case_filter_in.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_case_filter_in.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_case_filter_in.obj"
    	-@erase "$(INTDIR)\mod_case_filter_in.res"
    	-@erase "$(INTDIR)\mod_case_filter_in_src.idb"
    	-@erase "$(INTDIR)\mod_case_filter_in_src.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter_in.exp"
    	-@erase "$(OUTDIR)\mod_case_filter_in.lib"
    	-@erase "$(OUTDIR)\mod_case_filter_in.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter_in.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_case_filter_in_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_case_filter_in.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_case_filter_in.so" /d LONG_NAME="case_filter_in_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_case_filter_in.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_case_filter_in.pdb" /debug /out:"$(OUTDIR)\mod_case_filter_in.so" /implib:"$(OUTDIR)\mod_case_filter_in.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter_in.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_case_filter_in.obj" \
    	"$(INTDIR)\mod_case_filter_in.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_case_filter_in.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_case_filter_in.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_case_filter_in.so"
       if exist .\Release\mod_case_filter_in.so.manifest mt.exe -manifest .\Release\mod_case_filter_in.so.manifest -outputresource:.\Release\mod_case_filter_in.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter_in - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_case_filter_in.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_case_filter_in.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_case_filter_in.obj"
    	-@erase "$(INTDIR)\mod_case_filter_in.res"
    	-@erase "$(INTDIR)\mod_case_filter_in_src.idb"
    	-@erase "$(INTDIR)\mod_case_filter_in_src.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter_in.exp"
    	-@erase "$(OUTDIR)\mod_case_filter_in.lib"
    	-@erase "$(OUTDIR)\mod_case_filter_in.pdb"
    	-@erase "$(OUTDIR)\mod_case_filter_in.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_case_filter_in_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_case_filter_in.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_case_filter_in.so" /d LONG_NAME="case_filter_in_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_case_filter_in.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_case_filter_in.pdb" /debug /out:"$(OUTDIR)\mod_case_filter_in.so" /implib:"$(OUTDIR)\mod_case_filter_in.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter_in.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_case_filter_in.obj" \
    	"$(INTDIR)\mod_case_filter_in.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_case_filter_in.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_case_filter_in.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_case_filter_in.so"
       if exist .\Debug\mod_case_filter_in.so.manifest mt.exe -manifest .\Debug\mod_case_filter_in.so.manifest -outputresource:.\Debug\mod_case_filter_in.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_case_filter_in.dep")
    !INCLUDE "mod_case_filter_in.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_case_filter_in.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_case_filter_in - Win32 Release" || "$(CFG)" == "mod_case_filter_in - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_case_filter_in - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter_in - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_case_filter_in - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter_in - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\examples"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\examples"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_case_filter_in - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ELSEIF  "$(CFG)" == "mod_case_filter_in - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\examples"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\examples"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_case_filter_in - Win32 Release"
    
    
    "$(INTDIR)\mod_case_filter_in.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_case_filter_in.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_case_filter_in.so" /d LONG_NAME="case_filter_in_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_case_filter_in - Win32 Debug"
    
    
    "$(INTDIR)\mod_case_filter_in.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_case_filter_in.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_case_filter_in.so" /d LONG_NAME="case_filter_in_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_case_filter_in.c
    
    "$(INTDIR)\mod_case_filter_in.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter_in.dep������������������������������������������������0000664�0001751�0001751�00000003200�12674411515�022410� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_case_filter_in.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_case_filter_in.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter.c�����������������������������������������������������0000664�0001751�0001751�00000010372�12533331131�021371� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <ctype.h>
    
    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);
        }
    
        /* Q: is there any advantage to passing a brigade for each bucket?
         * A: obviously, it can cut down server resource consumption, if this
         * experimental module was fed a file of 4MB, it would be using 8MB for
         * the 'read' buckets and the 'write' buckets.
         *
         * Note it is more efficient to consume (destroy) each bucket as it's
         * processed above than to do a single cleanup down here.  In any case,
         * don't let our caller pass the same buckets to us, twice;
         */
        apr_brigade_cleanup(pbbIn);
        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);
    }
    
    AP_DECLARE_MODULE(case_filter) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        CaseFilterCreateServerConfig,
        NULL,
        CaseFilterCmds,
        CaseFilterRegisterHooks
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/NWGNUexample_ipc������������������������������������������������������0000664�0001751�0001751�00000010375�11540546347�021157� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/server/mpm/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	= example_ipc
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Example IPC Callback Handler Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Example IPC Callback Handler 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	=
    
    #
    # 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)/example_ipc.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_ipc.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	example_ipc_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/Makefile.in�����������������������������������������������������������0000664�0001751�0001751�00000000267�10720056417�020164� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_ipc.c�����������������������������������������������������0000664�0001751�0001751�00000030712�12661357032�021411� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_example_ipc -- Apache sample module
     *
     * This module illustrates the use in an Apache 2.x module of the Interprocess
     * Communications routines that come with APR. It is example code, and not meant
     * to be used in a production server.
     *
     * To play with this sample module first compile it into a DSO file and install
     * it into Apache's modules directory by running:
     *
     *    $ /path/to/apache2/bin/apxs -c -i mod_example_ipc.c
     *
     * Then activate it in Apache's httpd.conf file for instance for the URL
     * /example_ipc in as follows:
     *
     *    #   httpd.conf
     *    LoadModule example_ipc_module modules/mod_example_ipc.so
     *    <Location /example_ipc>
     *    SetHandler example_ipc
     *    </Location>
     *
     * Then restart Apache via
     *
     *    $ /path/to/apache2/bin/apachectl restart
     *
     * The module allocates a counter in shared memory, which is incremented by the
     * request handler under a mutex. After installation, activate the handler by
     * hitting the URL configured above with ab at various concurrency levels to see
     * how mutex contention affects server performance.
     */
    
    #include "apr.h"
    #include "apr_strings.h"
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "util_mutex.h"
    #include "ap_config.h"
    
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    #define HTML_HEADER "<html>\n<head>\n<title>Mod_example_IPC Status Page " \
                        "</title>\n</head>\n<body>\n<h1>Mod_example_IPC Status</h1>\n"
    #define HTML_FOOTER "</body>\n</html>\n"
    
    /* Number of microseconds to camp out on the mutex */
    #define CAMPOUT 10
    /* Maximum number of times we camp out before giving up */
    #define MAXCAMP 10
    /* Number of microseconds the handler sits on the lock once acquired. */
    #define SLEEPYTIME 1000
    
    apr_shm_t *exipc_shm; /* Pointer to shared memory block */
    char *shmfilename; /* Shared memory file name, used on some systems */
    apr_global_mutex_t *exipc_mutex; /* Lock around shared memory segment access */
    static const char *exipc_mutex_type = "example-ipc-shm";
    
    /* Data structure for shared memory block */
    typedef struct exipc_data {
        apr_uint64_t counter;
        /* More fields if necessary */
    } exipc_data;
    
    /*
     * Clean up the shared memory block. This function is registered as
     * cleanup function for the configuration pool, which gets called
     * on restarts. It assures that the new children will not talk to a stale
     * shared memory segment.
     */
    static apr_status_t shm_cleanup_wrapper(void *unused)
    {
        if (exipc_shm)
            return apr_shm_destroy(exipc_shm);
        return OK;
    }
    
    /*
     * This routine is called in the parent; we must register our
     * mutex type before the config is processed so that users can
     * adjust the mutex settings using the Mutex directive.
     */
    
    static int exipc_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                apr_pool_t *ptemp)
    {
        ap_mutex_register(pconf, exipc_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
        return OK;
    }
    
    /*
     * This routine is called in the parent, so we'll set up the shared
     * memory segment and mutex here.
     */
    
    static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                 apr_pool_t *ptemp, server_rec *s)
    {
        apr_status_t rs;
        exipc_data *base;
        const char *tempdir;
    
    
        /*
         * Do nothing if we are not creating the final configuration.
         * The parent process gets initialized a couple of times as the
         * server starts up, and we don't want to create any more mutexes
         * and shared memory segments than we're actually going to use.
         */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
            return OK;
    
        /*
         * The shared memory allocation routines take a file name.
         * Depending on system-specific implementation of these
         * routines, that file may or may not actually be created. We'd
         * like to store those files in the operating system's designated
         * temporary directory, which APR can point us to.
         */
        rs = apr_temp_dir_get(&tempdir, pconf);
        if (APR_SUCCESS != rs) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02992)
                         "Failed to find temporary directory");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* Create the shared memory segment */
    
        /*
         * Create a unique filename using our pid. This information is
         * stashed in the global variable so the children inherit it.
         */
        shmfilename = apr_psprintf(pconf, "%s/httpd_shm.%ld", tempdir,
                                   (long int)getpid());
    
        /* Now create that segment */
        rs = apr_shm_create(&exipc_shm, sizeof(exipc_data),
                            (const char *) shmfilename, pconf);
        if (APR_SUCCESS != rs) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02993)
                         "Failed to create shared memory segment on file %s",
                         shmfilename);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /* Created it, now let's zero it out */
        base = (exipc_data *)apr_shm_baseaddr_get(exipc_shm);
        base->counter = 0;
    
        /* Create global mutex */
    
        rs = ap_global_mutex_create(&exipc_mutex, NULL, exipc_mutex_type, NULL,
                                    s, pconf, 0);
        if (APR_SUCCESS != rs) {
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        /*
         * Destroy the shm segment when the configuration pool gets destroyed. This
         * happens on server restarts. The parent will then (above) allocate a new
         * shm segment that the new children will bind to.
         */
        apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper,
                                  apr_pool_cleanup_null);
        return OK;
    }
    
    /*
     * This routine gets called when a child inits. We use it to attach
     * to the shared memory segment, and reinitialize the mutex.
     */
    
    static void exipc_child_init(apr_pool_t *p, server_rec *s)
    {
        apr_status_t rs;
    
        /*
         * Re-open the mutex for the child. Note we're reusing
         * the mutex pointer global here.
         */
        rs = apr_global_mutex_child_init(&exipc_mutex,
                                         apr_global_mutex_lockfile(exipc_mutex),
                                         p);
        if (APR_SUCCESS != rs) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s, APLOGNO(02994)
                         "Failed to reopen mutex %s in child",
                         exipc_mutex_type);
            /* There's really nothing else we can do here, since This
             * routine doesn't return a status. If this ever goes wrong,
             * it will turn Apache into a fork bomb. Let's hope it never
             * will.
             */
            exit(1); /* Ugly, but what else? */
        }
    }
    
    /* The sample content handler */
    static int exipc_handler(request_rec *r)
    {
        int gotlock = 0;
        int camped;
        apr_time_t startcamp;
        apr_int64_t timecamped;
        apr_status_t rs;
        exipc_data *base;
    
        if (strcmp(r->handler, "example_ipc")) {
            return DECLINED;
        }
    
        /*
         * The main function of the handler, aside from sending the
         * status page to the client, is to increment the counter in
         * the shared memory segment. This action needs to be mutexed
         * out using the global mutex.
         */
    
        /*
         * First, acquire the lock. This code is a lot more involved than
         * it usually needs to be, because the process based trylock
         * routine is not implemented on unix platforms. I left it in to
         * show how it would work if trylock worked, and for situations
         * and platforms where trylock works.
         */
        for (camped = 0, timecamped = 0; camped < MAXCAMP; camped++) {
            rs = apr_global_mutex_trylock(exipc_mutex);
            if (APR_STATUS_IS_EBUSY(rs)) {
                apr_sleep(CAMPOUT);
            }
            else if (APR_SUCCESS == rs) {
                gotlock = 1;
                break; /* Get out of the loop */
            }
            else if (APR_STATUS_IS_ENOTIMPL(rs)) {
                /* If it's not implemented, just hang in the mutex. */
                startcamp = apr_time_now();
                rs = apr_global_mutex_lock(exipc_mutex);
                timecamped = (apr_int64_t) (apr_time_now() - startcamp);
                if (APR_SUCCESS == rs) {
                    gotlock = 1;
                    break; /* Out of the loop */
                }
                else {
                    /* Some error, log and bail */
                    ap_log_error(APLOG_MARK, APLOG_ERR, rs, r->server, APLOGNO(02995)
                                 "Child %ld failed to acquire lock",
                                 (long int)getpid());
                    break; /* Out of the loop without having the lock */
                }
            }
            else {
                /* Some other error, log and bail */
                ap_log_error(APLOG_MARK, APLOG_ERR, rs, r->server, APLOGNO(02996)
                             "Child %ld failed to try and acquire lock",
                             (long int)getpid());
                break; /* Out of the loop without having the lock */
            }
    
            /*
             * The only way to get to this point is if the trylock worked
             * and returned BUSY. So, bump the time and try again
             */
            timecamped += CAMPOUT;
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, r->server, APLOGNO(03187)
                         "Child %ld camping out on mutex for %" APR_INT64_T_FMT
                         " microseconds",
                         (long int) getpid(), timecamped);
        } /* Lock acquisition loop */
    
        /* Sleep for a millisecond to make it a little harder for
         * httpd children to acquire the lock.
         */
        apr_sleep(SLEEPYTIME);
    
        r->content_type = "text/html";
    
        if (!r->header_only) {
            ap_rputs(HTML_HEADER, r);
            if (gotlock) {
                /* Increment the counter */
                base = (exipc_data *)apr_shm_baseaddr_get(exipc_shm);
                base->counter++;
                /* Send a page with our pid and the new value of the counter. */
                ap_rprintf(r, "<p>Lock acquired after %ld microseoncds.</p>\n",
                           (long int) timecamped);
                ap_rputs("<table border=\"1\">\n", r);
                ap_rprintf(r, "<tr><td>Child pid:</td><td>%d</td></tr>\n",
                           (int) getpid());
                ap_rprintf(r, "<tr><td>Counter:</td><td>%u</td></tr>\n",
                           (unsigned int)base->counter);
                ap_rputs("</table>\n", r);
            }
            else {
                /*
                 * Send a page saying that we couldn't get the lock. Don't say
                 * what the counter is, because without the lock the value could
                 * race.
                 */
                ap_rprintf(r, "<p>Child %d failed to acquire lock "
                           "after camping out for %d microseconds.</p>\n",
                           (int) getpid(), (int) timecamped);
            }
            ap_rputs(HTML_FOOTER, r);
        } /* r->header_only */
    
        /* Release the lock */
        if (gotlock)
            rs = apr_global_mutex_unlock(exipc_mutex);
        /* Swallowing the result because what are we going to do with it at
         * this stage?
         */
    
        return OK;
    }
    
    static void exipc_register_hooks(apr_pool_t *p)
    {
        ap_hook_pre_config(exipc_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_config(exipc_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_child_init(exipc_child_init, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(exipc_handler, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    /* Dispatch list for API hooks */
    AP_DECLARE_MODULE(example_ipc) = {
        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       */
        exipc_register_hooks   /* register hooks                      */
    };
    ������������������������������������������������������httpd-2.4.64/modules/examples/NWGNUcase_flt_in������������������������������������������������������0000664�0001751�0001751�00000010301�11540546347�021124� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= case_flt_in
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Case Filter In Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_NAME) 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	=
    
    #
    # 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)/$(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_case_filter_in.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	case_filter_in_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 $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_hooks.dsp�������������������������������������������������0000664�0001751�0001751�00000011177�10720355073�022326� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_example_hooks" - 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_example_hooks - 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_example_hooks.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_example_hooks.mak" CFG="mod_example_hooks - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_example_hooks - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_example_hooks - 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_example_hooks - 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_example_hooks_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 /fo"Release/mod_example_hooks.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_example_hooks.so" /d LONG_NAME="example_hooks_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_example_hooks.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_hooks.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_example_hooks.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_hooks.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_example_hooks.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_example_hooks - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_example_hooks_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 /fo"Debug/mod_example_hooks.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_example_hooks.so" /d LONG_NAME="example_hooks_module for Apache"
    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 /out:".\Debug\mod_example_hooks.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_hooks.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_example_hooks.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_hooks.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_example_hooks.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_example_hooks - Win32 Release"
    # Name "mod_example_hooks - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_example_hooks.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter_in.dsp������������������������������������������������0000664�0001751�0001751�00000011244�10720056417�022431� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_case_filter_in" - 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_case_filter_in - 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_case_filter_in.mak".
    !MESSAGE 
    !MESSAGE You can specify a configuration when running NMAKE
    !MESSAGE by defining the macro CFG on the command line. For case_filter_in:
    !MESSAGE 
    !MESSAGE NMAKE /f "mod_case_filter_in.mak" CFG="mod_case_filter_in - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_case_filter_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_case_filter_in - 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_case_filter_in - 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_case_filter_in_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 /fo"Release/mod_case_filter_in.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_case_filter_in.so" /d LONG_NAME="case_filter_in_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_case_filter_in.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter_in.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_case_filter_in.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter_in.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_case_filter_in.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_case_filter_in - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_case_filter_in_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 /fo"Debug/mod_case_filter_in.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_case_filter_in.so" /d LONG_NAME="case_filter_in_module for Apache"
    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 /out:".\Debug\mod_case_filter_in.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter_in.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_case_filter_in.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter_in.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_case_filter_in.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_case_filter_in - Win32 Release"
    # Name "mod_case_filter_in - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_case_filter_in.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_example_ipc.dsp���������������������������������������������������0000664�0001751�0001751�00000011103�11022367030�021733� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_example_ipc" - 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_example_ipc - 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_example_ipc.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_example_ipc.mak" CFG="mod_example_ipc - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_example_ipc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_example_ipc - 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_example_ipc - 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_example_ipc_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 /fo"Release/mod_example_ipc.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_example_ipc.so" /d LONG_NAME="example_ipc_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_example_ipc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_ipc.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_example_ipc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_ipc.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_example_ipc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_example_ipc - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_example_ipc_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 /fo"Debug/mod_example_ipc.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_example_ipc.so" /d LONG_NAME="example_ipc_module for Apache"
    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 /out:".\Debug\mod_example_ipc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_ipc.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_example_ipc.so" /base:@..\..\os\win32\BaseAddr.ref,mod_example_ipc.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_example_ipc.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_example_ipc - Win32 Release"
    # Name "mod_example_ipc - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_example_ipc.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/examples/mod_case_filter.dsp���������������������������������������������������0000664�0001751�0001751�00000011107�10720056417�021741� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_case_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_case_filter - 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_case_filter.mak".
    !MESSAGE 
    !MESSAGE You can specify a configuration when running NMAKE
    !MESSAGE by defining the macro CFG on the command line. For case_filter:
    !MESSAGE 
    !MESSAGE NMAKE /f "mod_case_filter.mak" CFG="mod_case_filter - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_case_filter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_case_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_case_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_case_filter_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 /fo"Release/mod_case_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_case_filter.so" /d LONG_NAME="case_filter_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_case_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_case_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_case_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_case_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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_case_filter_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 /fo"Debug/mod_case_filter.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_case_filter.so" /d LONG_NAME="case_filter_module for Apache"
    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 /out:".\Debug\mod_case_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_case_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_case_filter.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_case_filter.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_case_filter - Win32 Release"
    # Name "mod_case_filter - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_case_filter.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015764� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_plain.mak��������������������������������������������������0000664�0001751�0001751�00000024511�12701473373�022160� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_slotmem_plain.dsp
    !IF "$(CFG)" == ""
    CFG=mod_slotmem_plain - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_slotmem_plain - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_slotmem_plain - Win32 Release" && "$(CFG)" != "mod_slotmem_plain - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_slotmem_plain.mak" CFG="mod_slotmem_plain - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_slotmem_plain - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_slotmem_plain - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_slotmem_plain - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_slotmem_plain.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_slotmem_plain.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_slotmem_plain.obj"
    	-@erase "$(INTDIR)\mod_slotmem_plain.res"
    	-@erase "$(INTDIR)\mod_slotmem_plain_src.idb"
    	-@erase "$(INTDIR)\mod_slotmem_plain_src.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.exp"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.lib"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_slotmem_plain_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_slotmem_plain.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_slotmem_plain.so" /d LONG_NAME="slotmem_plain_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_slotmem_plain.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_slotmem_plain.pdb" /debug /out:"$(OUTDIR)\mod_slotmem_plain.so" /implib:"$(OUTDIR)\mod_slotmem_plain.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_plain.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_slotmem_plain.obj" \
    	"$(INTDIR)\mod_slotmem_plain.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_slotmem_plain.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_slotmem_plain.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_slotmem_plain.so"
       if exist .\Release\mod_slotmem_plain.so.manifest mt.exe -manifest .\Release\mod_slotmem_plain.so.manifest -outputresource:.\Release\mod_slotmem_plain.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_plain - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_slotmem_plain.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_slotmem_plain.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_slotmem_plain.obj"
    	-@erase "$(INTDIR)\mod_slotmem_plain.res"
    	-@erase "$(INTDIR)\mod_slotmem_plain_src.idb"
    	-@erase "$(INTDIR)\mod_slotmem_plain_src.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.exp"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.lib"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_plain.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_slotmem_plain_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_slotmem_plain.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_slotmem_plain.so" /d LONG_NAME="slotmem_plain_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_slotmem_plain.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_slotmem_plain.pdb" /debug /out:"$(OUTDIR)\mod_slotmem_plain.so" /implib:"$(OUTDIR)\mod_slotmem_plain.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_plain.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_slotmem_plain.obj" \
    	"$(INTDIR)\mod_slotmem_plain.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_slotmem_plain.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_slotmem_plain.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_slotmem_plain.so"
       if exist .\Debug\mod_slotmem_plain.so.manifest mt.exe -manifest .\Debug\mod_slotmem_plain.so.manifest -outputresource:.\Debug\mod_slotmem_plain.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_slotmem_plain.dep")
    !INCLUDE "mod_slotmem_plain.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_slotmem_plain.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_slotmem_plain - Win32 Release" || "$(CFG)" == "mod_slotmem_plain - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_slotmem_plain - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\slotmem"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_plain - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\slotmem"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_slotmem_plain - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\slotmem"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_plain - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\slotmem"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_slotmem_plain - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\slotmem"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\slotmem"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_plain - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\slotmem"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\slotmem"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_slotmem_plain - Win32 Release"
    
    
    "$(INTDIR)\mod_slotmem_plain.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_slotmem_plain.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_slotmem_plain.so" /d LONG_NAME="slotmem_plain_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_plain - Win32 Debug"
    
    
    "$(INTDIR)\mod_slotmem_plain.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_slotmem_plain.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_slotmem_plain.so" /d LONG_NAME="slotmem_plain_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_slotmem_plain.c
    
    "$(INTDIR)\mod_slotmem_plain.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_plain.c����������������������������������������������������0000664�0001751�0001751�00000021614�12063353435�021630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /* Memory handler for a plain memory divided in slot.
     * This one uses plain memory.
     */
    
    #include  "ap_slotmem.h"
    
    #define AP_SLOTMEM_IS_PREGRAB(t) (t->type & AP_SLOTMEM_TYPE_PREGRAB)
    
    struct ap_slotmem_instance_t {
        char                 *name;       /* per segment name */
        void                 *base;       /* data set start */
        apr_size_t           size;        /* size of each memory slot */
        unsigned int         num;         /* number of mem slots */
        apr_pool_t           *gpool;      /* per segment global pool */
        char                 *inuse;      /* in-use flag table*/
        ap_slotmem_type_t    type;        /* type-specific flags */
        struct ap_slotmem_instance_t  *next;       /* location of next allocated segment */
    };
    
    
    /* global pool and list of slotmem we are handling */
    static struct ap_slotmem_instance_t *globallistmem = NULL;
    static apr_pool_t *gpool = NULL;
    
    static apr_status_t slotmem_do(ap_slotmem_instance_t *mem, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool)
    {
        unsigned int i;
        char *ptr;
        char *inuse;
        apr_status_t retval = APR_SUCCESS;
    
    
        if (!mem)
            return APR_ENOSHMAVAIL;
    
        ptr = (char *)mem->base;
        inuse = mem->inuse;
        for (i = 0; i < mem->num; i++, inuse++) {
            if (!AP_SLOTMEM_IS_PREGRAB(mem) ||
               (AP_SLOTMEM_IS_PREGRAB(mem) && *inuse)) {
                retval = func((void *) ptr, data, pool);
                if (retval != APR_SUCCESS)
                    break;
            }
            ptr += mem->size;
        }
        return retval;
    }
    
    static apr_status_t slotmem_create(ap_slotmem_instance_t **new, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool)
    {
        ap_slotmem_instance_t *res;
        ap_slotmem_instance_t *next = globallistmem;
        apr_size_t basesize = (item_size * item_num);
    
        const char *fname;
    
        if (name) {
            if (name[0] == ':')
                fname = name;
            else
                fname = ap_runtime_dir_relative(pool, name);
    
            /* first try to attach to existing slotmem */
            if (next) {
                for (;;) {
                    if (strcmp(next->name, fname) == 0) {
                        /* we already have it */
                        *new = next;
                        return APR_SUCCESS;
                    }
                    if (!next->next) {
                         break;
                    }
                    next = next->next;
                }
            }
        }
        else
            fname = "anonymous";
    
        /* create the memory using the gpool */
        res = (ap_slotmem_instance_t *) apr_pcalloc(gpool, sizeof(ap_slotmem_instance_t));
        res->base = apr_pcalloc(gpool, basesize + (item_num * sizeof(char)));
        if (!res->base)
            return APR_ENOSHMAVAIL;
    
        /* For the chained slotmem stuff */
        res->name = apr_pstrdup(gpool, fname);
        res->size = item_size;
        res->num = item_num;
        res->next = NULL;
        res->type = type;
        res->inuse = (char *)res->base + basesize;
        if (globallistmem == NULL)
            globallistmem = res;
        else
            next->next = res;
    
        *new = res;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_attach(ap_slotmem_instance_t **new, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool)
    {
        ap_slotmem_instance_t *next = globallistmem;
        const char *fname;
    
        if (name) {
            if (name[0] == ':')
                fname = name;
            else
                fname = ap_runtime_dir_relative(pool, name);
        }
        else
            return APR_ENOSHMAVAIL;
    
        /* first try to attach to existing slotmem */
        while (next) {
            if (strcmp(next->name, fname) == 0) {
                /* we already have it */
                *new = next;
                *item_size = next->size;
                *item_num = next->num;
                return APR_SUCCESS;
            }
            next = next->next;
        }
    
        return APR_ENOSHMAVAIL;
    }
    
    static apr_status_t slotmem_dptr(ap_slotmem_instance_t *score, unsigned int id, void **mem)
    {
    
        char *ptr;
    
        if (!score)
            return APR_ENOSHMAVAIL;
        if (id >= score->num)
            return APR_EINVAL;
    
        ptr = (char *)score->base + score->size * id;
        if (!ptr)
            return APR_ENOSHMAVAIL;
        *mem = ptr;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_get(ap_slotmem_instance_t *slot, unsigned int id, unsigned char *dest, apr_size_t dest_len)
    {
        void *ptr;
        char *inuse;
        apr_status_t ret;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse + id;
        if (id >= slot->num) {
            return APR_EINVAL;
        }
        if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) {
            return APR_NOTFOUND;
        }
        ret = slotmem_dptr(slot, id, &ptr);
        if (ret != APR_SUCCESS) {
            return ret;
        }
        *inuse=1;
        memcpy(dest, ptr, dest_len); /* bounds check? */
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_put(ap_slotmem_instance_t *slot, unsigned int id, unsigned char *src, apr_size_t src_len)
    {
        void *ptr;
        char *inuse;
        apr_status_t ret;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse + id;
        if (id >= slot->num) {
            return APR_EINVAL;
        }
        if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) {
            return APR_NOTFOUND;
        }
        ret = slotmem_dptr(slot, id, &ptr);
        if (ret != APR_SUCCESS) {
            return ret;
        }
        *inuse=1;
        memcpy(ptr, src, src_len); /* bounds check? */
        return APR_SUCCESS;
    }
    
    static unsigned int slotmem_num_slots(ap_slotmem_instance_t *slot)
    {
        return slot->num;
    }
    
    static unsigned int slotmem_num_free_slots(ap_slotmem_instance_t *slot)
    {
        unsigned int i, counter=0;
        char *inuse = slot->inuse;
        for (i = 0; i < slot->num; i++, inuse++) {
            if (!*inuse)
                counter++;
        }
        return counter;
    }
    
    static apr_size_t slotmem_slot_size(ap_slotmem_instance_t *slot)
    {
        return slot->size;
    }
    
    /*
     * XXXX: if !AP_SLOTMEM_IS_PREGRAB, then still worry about
     *       inuse for grab and return?
     */
    static apr_status_t slotmem_grab(ap_slotmem_instance_t *slot, unsigned int *id)
    {
        unsigned int i;
        char *inuse;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse;
    
        for (i = 0; i < slot->num; i++, inuse++) {
            if (!*inuse) {
                break;
            }
        }
        if (i >= slot->num) {
            return APR_EINVAL;
        }
        *inuse = 1;
        *id = i;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_fgrab(ap_slotmem_instance_t *slot, unsigned int id)
    {
        char *inuse;
        
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
        
        if (id >= slot->num) {
            return APR_EINVAL;
        }
        inuse = slot->inuse + id;
        *inuse = 1;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_release(ap_slotmem_instance_t *slot, unsigned int id)
    {
        char *inuse;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse;
    
        if (id >= slot->num) {
            return APR_EINVAL;
        }
        if (!inuse[id] ) {
            return APR_NOTFOUND;
        }
        inuse[id] = 0;
        return APR_SUCCESS;
    }
    
    static const ap_slotmem_provider_t storage = {
        "plainmem",
        &slotmem_do,
        &slotmem_create,
        &slotmem_attach,
        &slotmem_dptr,
        &slotmem_get,
        &slotmem_put,
        &slotmem_num_slots,
        &slotmem_num_free_slots,
        &slotmem_slot_size,
        &slotmem_grab,
        &slotmem_release,
        &slotmem_fgrab
    };
    
    static int pre_config(apr_pool_t *p, apr_pool_t *plog,
                          apr_pool_t *ptemp)
    {
        gpool = p;
        return OK;
    }
    
    static void ap_slotmem_plain_register_hook(apr_pool_t *p)
    {
        /* XXX: static const char * const prePos[] = { "mod_slotmem.c", NULL }; */
        ap_register_provider(p, AP_SLOTMEM_PROVIDER_GROUP, "plain",
                             AP_SLOTMEM_PROVIDER_VERSION, &storage);
        ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(slotmem_plain) = {
        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_slotmem_plain_register_hook    /* register hooks */
    };
    
    ��������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_shm.c������������������������������������������������������0000664�0001751�0001751�00000061333�14563146667�021334� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /* Memory handler for a shared memory divided in slot.
     * This one uses shared memory.
     *
     * Shared memory is cleaned-up for each restart, graceful or
     * otherwise.
     */
    
    #include  "ap_slotmem.h"
    
    #include "httpd.h"
    #include "http_main.h"
    #include "ap_mpm.h" /* for ap_mpm_query() */
    
    #define AP_SLOTMEM_IS_PREGRAB(t)    (t->desc->type & AP_SLOTMEM_TYPE_PREGRAB)
    #define AP_SLOTMEM_IS_PERSIST(t)    (t->desc->type & AP_SLOTMEM_TYPE_PERSIST)
    #define AP_SLOTMEM_IS_CLEARINUSE(t) (t->desc->type & AP_SLOTMEM_TYPE_CLEARINUSE)
    
    /* The description of the slots to reuse the slotmem */
    typedef struct {
        apr_size_t size;             /* size of each memory slot */
        unsigned int num;            /* number of mem slots */
        ap_slotmem_type_t type;      /* type-specific flags */
    } sharedslotdesc_t;
    
    #define AP_SLOTMEM_OFFSET (APR_ALIGN_DEFAULT(sizeof(sharedslotdesc_t)))
    #define AP_UNSIGNEDINT_OFFSET (APR_ALIGN_DEFAULT(sizeof(unsigned int)))
    
    struct ap_slotmem_instance_t {
        char                 *name;       /* file based SHM path/name */
        char                 *pname;      /* persisted file path/name */
        int                  fbased;      /* filebased? */
        void                 *shm;        /* ptr to memory segment (apr_shm_t *) */
        void                 *base;       /* data set start */
        apr_pool_t           *gpool;      /* per segment pool (generation cleared) */
        char                 *inuse;      /* in-use flag table*/
        unsigned int         *num_free;   /* slot free count for this instance */
        void                 *persist;    /* persist dataset start */
        const sharedslotdesc_t *desc;     /* per slot desc */
        struct ap_slotmem_instance_t  *next;       /* location of next allocated segment */
    };
    
    /*
     * Layout for SHM and persisted file :
     *
     *   +-------------------------------------------------------------+~>
     *   | desc | num_free | base (slots) | inuse (array) | md5 | desc | compat..
     *   +------+-----------------------------------------+------------+~>
     *   ^      ^                                         ^    \ /     ^   :
     *   |______|_____________ SHM (mem->@) ______________|     | _____|__/
     *          |                                               |/     |
     *          |                                         ^     v      |
     *          |_____________________ File (mem->persist +  [meta]) __|
     */
    
    /* global pool and list of slotmem we are handling */
    static struct ap_slotmem_instance_t *globallistmem = NULL;
    static apr_pool_t *gpool = NULL;
    
    #define DEFAULT_SLOTMEM_PREFIX "slotmem-shm-"
    #define DEFAULT_SLOTMEM_SUFFIX ".shm"
    #define DEFAULT_SLOTMEM_PERSIST_SUFFIX ".persist"
    
    /*
     * Persist the slotmem in a file
     * slotmem name and file name.
     * none      : no persistent data
     * rel_name  : $server_root/rel_name
     * /abs_name : $abs_name
     *
     */
    static int slotmem_filenames(apr_pool_t *pool,
                                 const char *slotname,
                                 const char **filename,
                                 const char **persistname)
    {
        const char *fname = NULL, *pname = NULL;
    
        if (slotname && *slotname && strcasecmp(slotname, "none") != 0) {
            if (!ap_os_is_path_absolute(pool, slotname)) {
                /* Each generation needs its own file name. */
                int generation = 0;
                ap_mpm_query(AP_MPMQ_GENERATION, &generation);
                fname = apr_psprintf(pool, "%s%s_%x%s", DEFAULT_SLOTMEM_PREFIX,
                                     slotname, generation, DEFAULT_SLOTMEM_SUFFIX);
                fname = ap_runtime_dir_relative(pool, fname);
            }
            else {
                /* Don't mangle the file name if given an absolute path, it's
                 * up to the caller to provide a unique name when necessary.
                 */
                fname = slotname;
            }
    
            if (persistname) {
                /* Persisted file names are immutable... */
                if (!ap_os_is_path_absolute(pool, slotname)) {
                    pname = apr_pstrcat(pool, DEFAULT_SLOTMEM_PREFIX,
                                        slotname, DEFAULT_SLOTMEM_SUFFIX,
                                        DEFAULT_SLOTMEM_PERSIST_SUFFIX,
                                        NULL);
                    pname = ap_runtime_dir_relative(pool, pname);
                }
                else {
                    pname = apr_pstrcat(pool, slotname,
                                        DEFAULT_SLOTMEM_PERSIST_SUFFIX,
                                        NULL);
                }
            }
        }
    
        *filename = fname;
        if (persistname) {
            *persistname = pname;
        }
        return (fname != NULL);
    }
    
    static void slotmem_clearinuse(ap_slotmem_instance_t *slot)
    {
        unsigned int i;
        char *inuse;
        
        if (!slot) {
            return;
        }
        
        inuse = slot->inuse;
        
        for (i = 0; i < slot->desc->num; i++, inuse++) {
            if (*inuse) {
                *inuse = 0;
                (*slot->num_free)++;
            }
        }
    }
    
    static void store_slotmem(ap_slotmem_instance_t *slotmem)
    {
        apr_file_t *fp;
        apr_status_t rv;
        apr_size_t nbytes;
        unsigned char digest[APR_MD5_DIGESTSIZE];
        const char *storename = slotmem->pname;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02334)
                     "storing %s", storename);
    
        if (storename) {
            rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE,
                               APR_OS_DEFAULT, slotmem->gpool);
            if (APR_STATUS_IS_EEXIST(rv)) {
                apr_file_remove(storename, slotmem->gpool);
                rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE,
                                   APR_OS_DEFAULT, slotmem->gpool);
            }
            if (rv != APR_SUCCESS) {
                return;
            }
            if (AP_SLOTMEM_IS_CLEARINUSE(slotmem)) {
                slotmem_clearinuse(slotmem);
            }
            nbytes = (slotmem->desc->size * slotmem->desc->num) +
                     (slotmem->desc->num * sizeof(char)) + AP_UNSIGNEDINT_OFFSET;
            apr_md5(digest, slotmem->persist, nbytes);
            rv = apr_file_write_full(fp, slotmem->persist, nbytes, NULL);
            if (rv == APR_SUCCESS) {
                rv = apr_file_write_full(fp, digest, APR_MD5_DIGESTSIZE, NULL);
            }
            if (rv == APR_SUCCESS) {
                rv = apr_file_write_full(fp, slotmem->desc, AP_SLOTMEM_OFFSET,
                                         NULL);
            }
            apr_file_close(fp);
            if (rv != APR_SUCCESS) {
                apr_file_remove(storename, slotmem->gpool);
            }
        }
    }
    
    static apr_status_t restore_slotmem(sharedslotdesc_t *desc,
                                        const char *storename, apr_size_t size,
                                        apr_pool_t *pool)
    {
        apr_file_t *fp;
        apr_status_t rv = APR_ENOTIMPL;
        void *ptr = (char *)desc + AP_SLOTMEM_OFFSET;
        apr_size_t nbytes = size - AP_SLOTMEM_OFFSET;
        unsigned char digest[APR_MD5_DIGESTSIZE];
        unsigned char digest2[APR_MD5_DIGESTSIZE];
        char desc_buf[AP_SLOTMEM_OFFSET];
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02335)
                     "restoring %s", storename);
    
        if (storename) {
            rv = apr_file_open(&fp, storename, APR_READ | APR_WRITE, APR_OS_DEFAULT,
                               pool);
            if (rv == APR_SUCCESS) {
                rv = apr_file_read_full(fp, ptr, nbytes, NULL);
                if (rv == APR_SUCCESS || rv == APR_EOF) {
                    /*
                     * if at EOF, don't bother checking md5
                     *  - backwards compatibility
                     *  */
                    if (apr_file_eof(fp) != APR_EOF) {
                        rv = apr_file_read_full(fp, digest, APR_MD5_DIGESTSIZE, NULL);
                        if (rv == APR_SUCCESS || rv == APR_EOF) {
                            apr_md5(digest2, ptr, nbytes);
                            if (memcmp(digest, digest2, APR_MD5_DIGESTSIZE)) {
                                rv = APR_EMISMATCH;
                            }
                            /*
                             * if at EOF, don't bother checking desc
                             *  - backwards compatibility
                             *  */
                            else if (apr_file_eof(fp) != APR_EOF) {
                                rv = apr_file_read_full(fp, desc_buf, sizeof(desc_buf), NULL);
                                if (rv == APR_SUCCESS || rv == APR_EOF) {
                                    if (memcmp(desc, desc_buf, sizeof(desc_buf))) {
                                        rv = APR_EMISMATCH;
                                    }
                                    else {
                                        rv = APR_SUCCESS;
                                    }
                                }
                                else {
                                    rv = APR_INCOMPLETE;
                                }
                            }
                            else {
                                rv = APR_EOF;
                            }
                        }
                        else {
                            rv = APR_INCOMPLETE;
                        }
                    }
                    else {
                        rv = APR_EOF;
                    }
                    if (rv == APR_EMISMATCH) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02551)
                                     "persisted slotmem md5/desc mismatch");
                    }
                    else if (rv == APR_EOF) {
                        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(02552)
                                     "persisted slotmem at EOF... bypassing md5/desc match check "
                                     "(old persist file?)");
                        rv = APR_SUCCESS;
                    }
                }
                else {
                    rv = APR_INCOMPLETE;
                }
                if (rv == APR_INCOMPLETE) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02553)
                                 "persisted slotmem read had unexpected size");
                }
                apr_file_close(fp);
            }
        }
        return rv;
    }
    
    /*
     * Whether the module is called from a MPM that re-enter main() and
     * pre/post_config phases.
     */
    static APR_INLINE int is_child_process(void)
    {
    #ifdef WIN32
        return getenv("AP_PARENT_PID") != NULL;
    #else
        return 0;
    #endif
    }
    
    static apr_status_t cleanup_slotmem(void *param)
    {
        int is_child = is_child_process();
        ap_slotmem_instance_t *next = globallistmem;
    
        while (next) {
            if (!is_child && AP_SLOTMEM_IS_PERSIST(next)) {
                store_slotmem(next);
            }
            apr_shm_destroy(next->shm);
            apr_shm_remove(next->name, next->gpool);
            next = next->next;
        }
    
        globallistmem = NULL;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_doall(ap_slotmem_instance_t *mem,
                                      ap_slotmem_callback_fn_t *func,
                                      void *data, apr_pool_t *pool)
    {
        unsigned int i;
        char *ptr;
        char *inuse;
        apr_status_t retval = APR_SUCCESS;
    
        if (!mem) {
            return APR_ENOSHMAVAIL;
        }
    
        ptr = (char *)mem->base;
        inuse = mem->inuse;
        for (i = 0; i < mem->desc->num; i++, inuse++) {
            if (!AP_SLOTMEM_IS_PREGRAB(mem) || *inuse) {
                retval = func((void *) ptr, data, pool);
                if (retval != APR_SUCCESS)
                    break;
            }
            ptr += mem->desc->size;
        }
        return retval;
    }
    
    static apr_status_t slotmem_create(ap_slotmem_instance_t **new,
                                       const char *name, apr_size_t item_size,
                                       unsigned int item_num,
                                       ap_slotmem_type_t type, apr_pool_t *pool)
    {
        int fbased = 1;
        int restored = 0;
        char *ptr;
        sharedslotdesc_t *desc;
        ap_slotmem_instance_t *res;
        ap_slotmem_instance_t *next = globallistmem;
        const char *fname, *pname = NULL;
        apr_shm_t *shm;
        apr_size_t basesize = (item_size * item_num);
        apr_size_t size = AP_SLOTMEM_OFFSET + AP_UNSIGNEDINT_OFFSET +
                          (item_num * sizeof(char)) + basesize;
        int persist = (type & AP_SLOTMEM_TYPE_PERSIST) != 0;
        apr_status_t rv;
    
        *new = NULL;
        if (gpool == NULL) {
            return APR_ENOSHMAVAIL;
        }
        if (slotmem_filenames(pool, name, &fname, persist ? &pname : NULL)) {
            /* first try to attach to existing slotmem */
            if (next) {
                for (;;) {
                    if (strcmp(next->name, fname) == 0) {
                        /* we already have it */
                        *new = next;
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02603)
                                     "create found %s in global list", fname);
                        return APR_SUCCESS;
                    }
                    if (!next->next) {
                         break;
                    }
                    next = next->next;
                }
            }
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02602)
                         "create didn't find %s in global list", fname);
        }
        else {
            fbased = 0;
            fname = "none";
        }
    
        /* first try to attach to existing shared memory */
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02300)
                     "create %s: %"APR_SIZE_T_FMT"/%u", fname, item_size,
                     item_num);
    
        {
            /* For MPMs that run pre/post_config() phases in both the parent
             * and children processes (e.g. winnt), SHMs created by the
             * parent exist in the children already; attach them.
             */
            if (fbased) {
                if (is_child_process()) {
                    rv = apr_shm_attach(&shm, fname, gpool);
                }
                else {
                    apr_shm_remove(fname, pool);
                    rv = apr_shm_create(&shm, size, fname, gpool);
                }
            }
            else {
                rv = apr_shm_create(&shm, size, NULL, gpool);
            }
            ap_log_error(APLOG_MARK, rv == APR_SUCCESS ? APLOG_DEBUG : APLOG_ERR,
                         rv, ap_server_conf, APLOGNO(02611)
                         "create: apr_shm_%s(%s) %s",
                         fbased && is_child_process() ? "attach" : "create",
                         fname, rv == APR_SUCCESS ? "succeeded" : "failed");
            if (rv != APR_SUCCESS) {
                return rv;
            }
    
            desc = (sharedslotdesc_t *)apr_shm_baseaddr_get(shm);
            memset(desc, 0, size);
            desc->size = item_size;
            desc->num = item_num;
            desc->type = type;
    
            /*
             * TODO: Error check the below... What error makes
             * sense if the restore fails? Any?
             * For now, we continue with a fresh new slotmem,
             * but NOTICE in the log.
             */
            if (persist) {
                rv = restore_slotmem(desc, pname, size, pool);
                if (rv == APR_SUCCESS) {
                    restored = 1;
                }
                else {
                    /* just in case, re-zero */
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                                 APLOGNO(02554) "could not restore %s", fname);
                    memset((char *)desc + AP_SLOTMEM_OFFSET, 0,
                           size - AP_SLOTMEM_OFFSET);
                }
            }
        }
    
        ptr = (char *)desc + AP_SLOTMEM_OFFSET;
    
        /* For the chained slotmem stuff */
        res = apr_pcalloc(gpool, sizeof(ap_slotmem_instance_t));
        res->name = apr_pstrdup(gpool, fname);
        res->pname = apr_pstrdup(gpool, pname);
        res->fbased = fbased;
        res->shm = shm;
        res->persist = (void *)ptr;
        res->num_free = (unsigned int *)ptr;
        ptr += AP_UNSIGNEDINT_OFFSET;
        if (!restored) {
            *res->num_free = item_num;
        }
        res->base = (void *)ptr;
        res->desc = desc;
        res->gpool = gpool;
        res->next = NULL;
        res->inuse = ptr + basesize;
        if (fbased) {
            if (globallistmem == NULL) {
                globallistmem = res;
            }
            else {
                next->next = res;
            }
        }
    
        *new = res;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_attach(ap_slotmem_instance_t **new,
                                       const char *name, apr_size_t *item_size,
                                       unsigned int *item_num, apr_pool_t *pool)
    {
        char *ptr;
        ap_slotmem_instance_t *res;
        ap_slotmem_instance_t *next = globallistmem;
        sharedslotdesc_t *desc;
        const char *fname;
        apr_shm_t *shm;
        apr_status_t rv;
    
        if (gpool == NULL) {
            return APR_ENOSHMAVAIL;
        }
        if (!slotmem_filenames(pool, name, &fname, NULL)) {
            return APR_ENOSHMAVAIL;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02301)
                     "attach looking for %s", fname);
    
        /* first try to attach to existing slotmem */
        if (next) {
            for (;;) {
                if (strcmp(next->name, fname) == 0) {
                    /* we already have it */
                    *new = next;
                    *item_size = next->desc->size;
                    *item_num = next->desc->num;
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                                 APLOGNO(02302)
                                 "attach found %s: %"APR_SIZE_T_FMT"/%u", fname,
                                 *item_size, *item_num);
                    return APR_SUCCESS;
                }
                if (!next->next) {
                     break;
                }
                next = next->next;
            }
        }
    
        /* next try to attach to existing shared memory */
        rv = apr_shm_attach(&shm, fname, gpool);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    
        /* Read the description of the slotmem */
        desc = (sharedslotdesc_t *)apr_shm_baseaddr_get(shm);
        ptr = (char *)desc + AP_SLOTMEM_OFFSET;
    
        /* For the chained slotmem stuff */
        res = apr_pcalloc(gpool, sizeof(ap_slotmem_instance_t));
        res->name = apr_pstrdup(gpool, fname);
        res->fbased = 1;
        res->shm = shm;
        res->persist = (void *)ptr;
        res->num_free = (unsigned int *)ptr;
        ptr += AP_UNSIGNEDINT_OFFSET;
        res->base = (void *)ptr;
        res->desc = desc;
        res->gpool = gpool;
        res->inuse = ptr + (desc->size * desc->num);
        res->next = NULL;
    
        *new = res;
        *item_size = desc->size;
        *item_num = desc->num;
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                     APLOGNO(02303)
                     "attach found %s: %"APR_SIZE_T_FMT"/%u", fname,
                     *item_size, *item_num);
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_dptr(ap_slotmem_instance_t *slot,
                                     unsigned int id, void **mem)
    {
        char *ptr;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
        if (id >= slot->desc->num) {
            return APR_EINVAL;
        }
    
        ptr = (char *)slot->base + slot->desc->size * id;
        if (!ptr) {
            return APR_ENOSHMAVAIL;
        }
        *mem = (void *)ptr;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_get(ap_slotmem_instance_t *slot, unsigned int id,
                                    unsigned char *dest, apr_size_t dest_len)
    {
        void *ptr;
        char *inuse;
        apr_status_t ret;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse + id;
        if (id >= slot->desc->num) {
            return APR_EINVAL;
        }
        if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) {
            return APR_NOTFOUND;
        }
        ret = slotmem_dptr(slot, id, &ptr);
        if (ret != APR_SUCCESS) {
            return ret;
        }
        *inuse = 1;
        memcpy(dest, ptr, dest_len); /* bounds check? */
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_put(ap_slotmem_instance_t *slot, unsigned int id,
                                    unsigned char *src, apr_size_t src_len)
    {
        void *ptr;
        char *inuse;
        apr_status_t ret;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse + id;
        if (id >= slot->desc->num) {
            return APR_EINVAL;
        }
        if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) {
            return APR_NOTFOUND;
        }
        ret = slotmem_dptr(slot, id, &ptr);
        if (ret != APR_SUCCESS) {
            return ret;
        }
        *inuse=1;
        memcpy(ptr, src, src_len); /* bounds check? */
        return APR_SUCCESS;
    }
    
    static unsigned int slotmem_num_slots(ap_slotmem_instance_t *slot)
    {
        return slot->desc->num;
    }
    
    static unsigned int slotmem_num_free_slots(ap_slotmem_instance_t *slot)
    {
        if (AP_SLOTMEM_IS_PREGRAB(slot))
            return *slot->num_free;
        else {
            unsigned int i, counter=0;
            char *inuse = slot->inuse;
            for (i=0; i<slot->desc->num; i++, inuse++) {
                if (!*inuse)
                    counter++;
            }
            return counter;
        }
    }
    
    static apr_size_t slotmem_slot_size(ap_slotmem_instance_t *slot)
    {
        return slot->desc->size;
    }
    
    static apr_status_t slotmem_grab(ap_slotmem_instance_t *slot, unsigned int *id)
    {
        unsigned int i;
        char *inuse;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse;
    
        for (i = 0; i < slot->desc->num; i++, inuse++) {
            if (!*inuse) {
                break;
            }
        }
        if (i >= slot->desc->num) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02293)
                         "slotmem(%s) grab failed. Num %u/num_free %u",
                         slot->name, slotmem_num_slots(slot),
                         slotmem_num_free_slots(slot));
            return APR_EINVAL;
        }
        *inuse = 1;
        *id = i;
        (*slot->num_free)--;
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_fgrab(ap_slotmem_instance_t *slot, unsigned int id)
    {
        char *inuse;
        
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        if (id >= slot->desc->num) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02397)
                         "slotmem(%s) fgrab failed. Num %u/num_free %u",
                         slot->name, slotmem_num_slots(slot),
                         slotmem_num_free_slots(slot));
            return APR_EINVAL;
        }
        inuse = slot->inuse + id;
    
        if (!*inuse) {
            *inuse = 1;
            (*slot->num_free)--;
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t slotmem_release(ap_slotmem_instance_t *slot,
                                        unsigned int id)
    {
        char *inuse;
    
        if (!slot) {
            return APR_ENOSHMAVAIL;
        }
    
        inuse = slot->inuse;
    
        if (id >= slot->desc->num || !inuse[id] ) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02294)
                         "slotmem(%s) release failed. Num %u/inuse[%u] %d",
                         slot->name, slotmem_num_slots(slot),
                         id, (int)inuse[id]);
            if (id >= slot->desc->num) {
                return APR_EINVAL;
            } else {
                return APR_NOTFOUND;
            }
        }
        inuse[id] = 0;
        (*slot->num_free)++;
        return APR_SUCCESS;
    }
    
    static const ap_slotmem_provider_t storage = {
        "sharedmem",
        &slotmem_doall,
        &slotmem_create,
        &slotmem_attach,
        &slotmem_dptr,
        &slotmem_get,
        &slotmem_put,
        &slotmem_num_slots,
        &slotmem_num_free_slots,
        &slotmem_slot_size,
        &slotmem_grab,
        &slotmem_release,
        &slotmem_fgrab
    };
    
    /* make the storage usable from outside */
    static const ap_slotmem_provider_t *slotmem_shm_getstorage(void)
    {
        return (&storage);
    }
    
    /*
     * Make sure the shared memory is cleaned
     */
    static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
                           server_rec *s)
    {
        apr_pool_cleanup_register(p, NULL, cleanup_slotmem, apr_pool_cleanup_null);
        return OK;
    }
    
    static int pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
    {
        gpool = p;
        globallistmem = NULL;
        return OK;
    }
    
    static void ap_slotmem_shm_register_hook(apr_pool_t *p)
    {
        const ap_slotmem_provider_t *storage = slotmem_shm_getstorage();
        ap_register_provider(p, AP_SLOTMEM_PROVIDER_GROUP, "shm",
                             AP_SLOTMEM_PROVIDER_VERSION, storage);
        ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_LAST);
        ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(slotmem_shm) = {
        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_slotmem_shm_register_hook  /* register hooks */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_shm.dep����������������������������������������������������0000664�0001751�0001751�00000004043�12674411515�021641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_slotmem_shm.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_slotmem_shm.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_main.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/config.m4��������������������������������������������������������������0000664�0001751�0001751�00000000523�11665401625�017467� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl modules enabled in this directory by default
    
    dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
    
    APACHE_MODPATH_INIT(slotmem)
    
    APACHE_MODULE(slotmem_shm, slotmem provider that uses shared memory, , , most)
    APACHE_MODULE(slotmem_plain, slotmem provider that uses plain memory, , , )
    
    APACHE_MODPATH_FINISH
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_plain.dep��������������������������������������������������0000664�0001751�0001751�00000003513�12674411515�022156� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_slotmem_plain.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_slotmem_plain.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\ap_slotmem.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_md5.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apr_xlate.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_shm.dsp����������������������������������������������������0000664�0001751�0001751�00000011011�12062614564�021650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_slotmem_shm" - 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_slotmem_shm - 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_slotmem_shm.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_slotmem_shm.mak" CFG="mod_slotmem_shm - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_slotmem_shm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_slotmem_shm - 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_slotmem_shm - 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_slotmem_shm_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 /fo"Release/mod_slotmem_shm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_slotmem_shm.so" /d LONG_NAME="slotmem_shm_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_slotmem_shm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_shm.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_slotmem_shm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_shm.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_slotmem_shm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_shm - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_slotmem_shm_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 /fo"Debug/mod_slotmem_shm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_slotmem_shm.so" /d LONG_NAME="slotmem_shm_module for Apache"
    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 /out:".\Debug\mod_slotmem_shm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_shm.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_slotmem_shm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_shm.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_slotmem_shm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_slotmem_shm - Win32 Release"
    # Name "mod_slotmem_shm - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_slotmem_shm.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/NWGNUslotmem_shm�������������������������������������������������������0000664�0001751�0001751�00000010226�11540546347�021055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= slotmem_shm
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Slotmem SHM Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Slotmem SHM 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	=
    
    #
    # 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)/$(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_slotmem_shm.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	slotmem_shm_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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_shm.mak����������������������������������������������������0000664�0001751�0001751�00000024231�12701473373�021643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_slotmem_shm.dsp
    !IF "$(CFG)" == ""
    CFG=mod_slotmem_shm - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_slotmem_shm - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_slotmem_shm - Win32 Release" && "$(CFG)" != "mod_slotmem_shm - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_slotmem_shm.mak" CFG="mod_slotmem_shm - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_slotmem_shm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_slotmem_shm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_slotmem_shm - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_slotmem_shm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_slotmem_shm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_slotmem_shm.obj"
    	-@erase "$(INTDIR)\mod_slotmem_shm.res"
    	-@erase "$(INTDIR)\mod_slotmem_shm_src.idb"
    	-@erase "$(INTDIR)\mod_slotmem_shm_src.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.exp"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.lib"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_slotmem_shm_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_slotmem_shm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_slotmem_shm.so" /d LONG_NAME="slotmem_shm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_slotmem_shm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_slotmem_shm.pdb" /debug /out:"$(OUTDIR)\mod_slotmem_shm.so" /implib:"$(OUTDIR)\mod_slotmem_shm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_shm.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_slotmem_shm.obj" \
    	"$(INTDIR)\mod_slotmem_shm.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_slotmem_shm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_slotmem_shm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_slotmem_shm.so"
       if exist .\Release\mod_slotmem_shm.so.manifest mt.exe -manifest .\Release\mod_slotmem_shm.so.manifest -outputresource:.\Release\mod_slotmem_shm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_shm - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_slotmem_shm.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_slotmem_shm.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_slotmem_shm.obj"
    	-@erase "$(INTDIR)\mod_slotmem_shm.res"
    	-@erase "$(INTDIR)\mod_slotmem_shm_src.idb"
    	-@erase "$(INTDIR)\mod_slotmem_shm_src.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.exp"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.lib"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.pdb"
    	-@erase "$(OUTDIR)\mod_slotmem_shm.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_slotmem_shm_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_slotmem_shm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_slotmem_shm.so" /d LONG_NAME="slotmem_shm_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_slotmem_shm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_slotmem_shm.pdb" /debug /out:"$(OUTDIR)\mod_slotmem_shm.so" /implib:"$(OUTDIR)\mod_slotmem_shm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_shm.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_slotmem_shm.obj" \
    	"$(INTDIR)\mod_slotmem_shm.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_slotmem_shm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_slotmem_shm.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_slotmem_shm.so"
       if exist .\Debug\mod_slotmem_shm.so.manifest mt.exe -manifest .\Debug\mod_slotmem_shm.so.manifest -outputresource:.\Debug\mod_slotmem_shm.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_slotmem_shm.dep")
    !INCLUDE "mod_slotmem_shm.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_slotmem_shm.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_slotmem_shm - Win32 Release" || "$(CFG)" == "mod_slotmem_shm - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_slotmem_shm - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\slotmem"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_shm - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\slotmem"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_slotmem_shm - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\slotmem"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_shm - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\slotmem"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\slotmem"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_slotmem_shm - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\slotmem"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\slotmem"
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_shm - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\slotmem"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\slotmem"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_slotmem_shm - Win32 Release"
    
    
    "$(INTDIR)\mod_slotmem_shm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_slotmem_shm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_slotmem_shm.so" /d LONG_NAME="slotmem_shm_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_shm - Win32 Debug"
    
    
    "$(INTDIR)\mod_slotmem_shm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_slotmem_shm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_slotmem_shm.so" /d LONG_NAME="slotmem_shm_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_slotmem_shm.c
    
    "$(INTDIR)\mod_slotmem_shm.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/mod_slotmem_plain.dsp��������������������������������������������������0000664�0001751�0001751�00000011105�12062614564�022170� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_slotmem_plain" - 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_slotmem_plain - 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_slotmem_plain.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_slotmem_plain.mak" CFG="mod_slotmem_plain - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_slotmem_plain - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_slotmem_plain - 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_slotmem_plain - 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_slotmem_plain_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 /fo"Release/mod_slotmem_plain.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_slotmem_plain.so" /d LONG_NAME="slotmem_plain_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_slotmem_plain.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_plain.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_slotmem_plain.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_plain.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_slotmem_plain.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_slotmem_plain - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_slotmem_plain_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 /fo"Debug/mod_slotmem_plain.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_slotmem_plain.so" /d LONG_NAME="slotmem_plain_module for Apache"
    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 /out:".\Debug\mod_slotmem_plain.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_plain.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_slotmem_plain.so" /base:@..\..\os\win32\BaseAddr.ref,mod_slotmem_plain.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_slotmem_plain.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_slotmem_plain - Win32 Release"
    # Name "mod_slotmem_plain - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_slotmem_plain.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/NWGNUslotmem_plain�����������������������������������������������������0000664�0001751�0001751�00000010240�11540546347�021365� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= slotmem_plain
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Slotmem Plain Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= Slotmem Plain 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	=
    
    #
    # 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)/$(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_slotmem_plain.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	slotmem_plain_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 $(APBUILD)/NWGNUtail.inc
    
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/slotmem/NWGNUmakefile����������������������������������������������������������0000664�0001751�0001751�00000007761�11540562746�020316� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/slotmem_plain.nlm \
    	$(OBJDIR)/slotmem_shm.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ���������������httpd-2.4.64/modules/slotmem/Makefile.in������������������������������������������������������������0000664�0001751�0001751�00000000267�11203275423�020023� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015234� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016213� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/����������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017140� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test20.conf�����������������������������������������������������0000664�0001751�0001751�00000000261�12553146475�021131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# directory in directory through a macro
    
    <Macro foo $dir>
      <Directory $dir>
        Warning "macro foo $dir"
      </Directory>
    </Macro>
    
    <Directory /tmp>
      Use foo /tmp
    </Directory>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test24.conf�����������������������������������������������������0000664�0001751�0001751�00000000536�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# nesting...
    
    <Macro bla>
      <Location /intra>
        Warning "macro bla intra"
      </Location>
      <Location /private>
        Warning "macro bla private"
      </Location>
    </Macro>
    
    # ok location in config
    Use bla
    
    # ok, location in VH
    <VirtualHost foo.com>
      Use bla
    </VirtualHost>
    
    <Directory /tmp>
      # fails: Location within an Directory
      Use bla
    </Directory>
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test28.conf�����������������������������������������������������0000664�0001751�0001751�00000000253�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# interaction with IfModule
    
    <IfModule mod_macro.c>
      <Macro foo>
        Warning "macro foo"
      </Macro>
    
      Use foo
    
      Error "done!"
    </IfModule>
    
    Error "should not get there"
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test32.conf�����������������������������������������������������0000664�0001751�0001751�00000000125�12553146475�021133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# error if same argument name.
    
    <Macro foo $arg1 $arg2 $arg3 $arg2>
    # bad
    </Macro>
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test36.conf�����������������������������������������������������0000664�0001751�0001751�00000000356�12553146475�021145� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<Macro warnings $u $n $u1 $n1 $u2 $n2>
      Warning "many warnings! $u $u1 $u2"
      # $n $n1 $n2
    </Macro>
    
    # warn about unused arguments
    Use warnings 1 2 3 4 5 6
    
    # may warn about empty arguments?
    Use warnings '' '' '' '' '' ''
    
    Error "done!"
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test31.conf�����������������������������������������������������0000664�0001751�0001751�00000000437�12553146475�021140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# parameter name conflicts
    
    <Macro bla $dir $di $dd $d>
      Warning "argument name conflicts"
      $d $di $dir $dd
    </Macro>
    
    Use bla '' '' 8080 Listen
    
    <Macro foo $d $di $dir $dd>
      Warning "conflicts, but arguments are not used"
    </Macro>
    
    Use foo '' '' 8080 Listen
    
    Error "done on line 16."
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test26.conf�����������������������������������������������������0000664�0001751�0001751�00000000542�12553146475�021141� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ok till stop.
    # test quotes...
    
    <Macro funny "first arg" 'second ... arg'>
      <Directory first arg>
        Warning "funny directory"
      </Directory>
      <Location second ... arg>
        Warning "funny location"
      </Location>
    </Macro>
    
    Use funny /unexpected/1 /intra
    
    <VirtualHost www.apache.org>
      Use funny /unexpected/2 /intranet
    </VirtualHost>
    
    Error "done!"
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test30.conf�����������������������������������������������������0000664�0001751�0001751�00000000350�12553146475�021131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# name conficts: the longest is chosen
    # also test a parametric section
    
    <Macro foo $dir $directive>
      <$directive $dir>
        Warning "section $directive $dir"
      </$directive>
    </Macro>
    
    Use foo /unexpected/1 Directory
    
    Error "done!"
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test35.conf�����������������������������������������������������0000664�0001751�0001751�00000000272�12553146475�021141� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# unused arguments
    
    <Macro warnings u1 u2 n1 n2 u3>
      Warning "macro cannot be used just within a comment u1 u2 u3"
      # n1 n2
    </Macro>
     
    Use warnings 1 2 3 4 5
    
    Error "done on line 10."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test39.conf�����������������������������������������������������0000664�0001751�0001751�00000000536�12553146475�021150� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# okay till stop.
    
    <IfModule mod_macro.c>
      <Macro ModMacro>
        Warning Thanks for using mod_macro!
      </Macro>
    </IfModule>
    
    <IfModule !mod_macro.c>
      <Macro ModMacro>
        Error Sorry, mod_macro must be installed to run this configuration file.
      </Macro>
    </IfModule>
    
    Use ModMacro
    
    <Macro foo>
      Warning "macro foo"
    </Macro>
    
    Use foo
    
    Error "done!"
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test34.conf�����������������������������������������������������0000664�0001751�0001751�00000000344�12553146475�021140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# macro parameter prefix conflicts in two orders
    
    <Macro foo $d $dd>
      Warning "macro foo conflict one"
    </Macro>
    
    <Macro bla $dd $d>
      Warning "macro bla conflict two"
    </Macro>
    
    Use foo 1 2
    Use bla 1 2
    
    Error "done on line 14."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test38.conf�����������������������������������������������������0000664�0001751�0001751�00000000307�12553146475�021143� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ifmodule
    
    <IfModule mod_macro.c>
    Warning it is really a good idea to have mod_macro.c installed.
    </IfModule>
    
    <IfModule !mod_perl.c>
    Error it seems you do not have mod perl installed.
    </IfModule>
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test44.conf�����������������������������������������������������0000664�0001751�0001751�00000000325�12553146475�021140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# working recursion...
    
    <Macro foo>
    use bla
    </Macro>
    
    <Macro bla>
    <IfDefine NoFoo>
    use foo
    </IfDefine>
    </Macro>
    
    
    <IfDefine !NoFoo>
    # foo gonna call bla, bla wont call foo back...
    use foo
    </IfDefine>
    
    Error okay.
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test48.conf�����������������������������������������������������0000664�0001751�0001751�00000000476�12553146475�021153� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test substitution...
    
    <Macro M %premier>
    Warning %premier
    </Macro>
    
    Use M 1
    Use M 12
    Use M 123
    Use M 1234
    Use M 12345
    Use M 123456
    Use M 1234567
    Use M 12345678
    Use M 123456789
    Use M 1234567890
    Use M 1234567890a
    Use M 1234567890ab
    Use M 1234567890abc
    Use M 1234567890abcd
    Use M 1234567890abcde
    
    Error "done line 23."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test41.conf�����������������������������������������������������0000664�0001751�0001751�00000000537�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# another configuration example without mod_macro
    
    <VirtualHost www.foo.com>
      DocumentRoot /foo/document/root/directory
    
      <Location /A>
        Warning "location /A"
      </Location>
    
      <Location /B>
        Warning "location /B"
      </Location>
    
      <Location /C>
        Warning "location /C"
      </Location>
    
    </VirtualHost>
    
    Error Stop configuration file processing.
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test45.conf�����������������������������������������������������0000664�0001751�0001751�00000000254�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# strange chars
    
    <Macro warnings $1 %2 &3 @4 #5 ~6 *7 .8 ,9 !a -b +c =d :e ;f ?g>
    # hello $1 %2 &3 @4 #5 ~6 *7 .8 ,9 !a -b +c =d :e ;f ?g
    </Macro>
    
    Error "done on line 7."
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test61.conf�����������������������������������������������������0000664�0001751�0001751�00000000420�12553146475�021133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# deep expansion
    <Macro F1 $x>
      Warning "F1:1 x=$x"
    </Macro>
    <Macro F2 $x>
      Warning "F2:1 x=$x"
      Use F1 $x
    </Macro>
    <Macro F3 $x>
      Warning "F3:1 x=$x"
      Use F2 $x
    </Macro>
    <Macro F4 $x>
      Warning "F4:1 x=$x"
      Use F3 $x
    </Macro>
    Use F4 "line=17"
    Error "done line 18."
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test65.conf�����������������������������������������������������0000664�0001751�0001751�00000000306�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# simple use continuation
    <Macro Line $line>
      # first macro line is a comment
      Warning "Line: $line"
    </Macro>
    Use Line \
      "on line 6-7"
    Use \
      Line \
        "on line 8-10"
    Error "done on line 11."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test47.conf�����������������������������������������������������0000664�0001751�0001751�00000000213�12553146475�021137� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty macro contents...
    
    <Macro foo>
    </Macro>
    
    Use foo
    
    <Macro bla $i>
    </Macro>
    
    <Macro bof $i>
    # some contents...
    </Macro>
    
    Error okay.
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test51.conf�����������������������������������������������������0000664�0001751�0001751�00000000324�12553146475�021135� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# undef existing macro, and try to use it
    <Macro foo>
      Warning "foo macro contents"
    </Macro>
    # expanded, but will not be processed because of error
    Use foo
    UndefMacro foo
    # error, does not exist anymore
    Use foo
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/inc63_2.conf����������������������������������������������������0000664�0001751�0001751�00000000120�12553146475�021145� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# use macro defined elsewhere
    Use Foo "inc63_2.conf:2"
    Use Bla "inc63_2.conf:3"
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test04.conf�����������������������������������������������������0000664�0001751�0001751�00000000106�12553146475�021131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# wrong args
    <Macro foo>
      Warning "macro foo"
    </Macro>
    Use foo hello
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test08.conf�����������������������������������������������������0000664�0001751�0001751�00000000060�12553146475�021134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# missing begin macro
    ServerName hello
    </Macro>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/inc63_1.conf����������������������������������������������������0000664�0001751�0001751�00000000150�12553146475�021147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# macro for include
    <Macro Foo $where>
      Warning "Foo macro at $where"
    </Macro>
    Use Foo "inc63_.conf:5"
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test03.conf�����������������������������������������������������0000664�0001751�0001751�00000000111�12553146475�021124� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# use undefined macro
    <Macro foo>
      Warning "macro foo"
    </Macro>
    Use bla
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test07.conf�����������������������������������������������������0000664�0001751�0001751�00000000057�12553146475�021141� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# missing end macro
    <Macro foo $premier>
    hello
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test57.conf�����������������������������������������������������0000664�0001751�0001751�00000000116�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty argument name
    <Macro foo $x ''>
      Warning "macro foo line 1"
    </Macro>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test69.conf�����������������������������������������������������0000664�0001751�0001751�00000000514�12553146475�021147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# warn if ignored non-blank stuff after closing '>'
    <Macro Foo> this stuff is ignored...
      Warning "Foo"
    </Macro> this stuff is ignored as well...
    Use Foo
    <Macro Bla>				
      Warning "Bla"
    </Macro>			
    Use Bla
    <Macro Comments> # comments are fine
      Warning "Comments"
    </Macro> # comments are fine
    Use Comments
    Error "done on line 14."
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test64.conf�����������������������������������������������������0000664�0001751�0001751�00000000145�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# just continuations
    Warning "on line 2"
    Warning \
      "from line 3 to line 4"
    Error "done on line 5."
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test43.conf�����������������������������������������������������0000664�0001751�0001751�00000000533�12553146475�021140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# non necessarily nested.
    
    <Macro begindir $dir>
    <Directory $dir>
    # hello
    </Macro>
    
    <Macro enddir>
    </Directory>
    </Macro>
    
    Use begindir /unexpected/1
    Use enddir
    
    
    Use begindir /unexpected/2
    Use enddir
    
    Use begindir /unexpected/3
    <Limit GET>
    </Limit>
    Use enddir
    
    <VirtualHost foo.com>
    Use begindir /unexpected/4
    Use enddir
    </VirtualHost>
    
    Error ok!
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test55.conf�����������������������������������������������������0000664�0001751�0001751�00000000370�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# line numbers...
    <Macro foo $where>
      Warning "macro foo(:2) line 1 ($where)"
    </Macro>
    <Macro bla $where>
      Warning "macro bla(:5) line 1 ($where)"
      Use foo "bla line 2"
    </Macro>
    Use foo "file line 9"
    Use bla "file line 10"
    Error "done line 11."
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test12.conf�����������������������������������������������������0000664�0001751�0001751�00000000262�12553146475�021133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# multiply defined generates a warning
    <Macro foo>
      Warning "macro foo 1, line 1"
    </Macro>
    
    <Macro foo>
      Warning "macro foo 2, line 1"
    </Macro>
    
    Use foo
    
    Error "done line 12."
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test11.conf�����������������������������������������������������0000664�0001751�0001751�00000000311�12553146475�021125� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# inner macros...
    <Macro foo $arg>
    <Macro $arg.in>
    Warning "macro $arg.in line 1"
    </Macro>
    </Macro>
    
    # generate a one.in macro
    Use foo one
    
    # use it!
    Use one.in
    
    # end processing
    Error "done line 15."
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test15.conf�����������������������������������������������������0000664�0001751�0001751�00000000162�12553146475�021135� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# non nested...
    <macro test>
    <directory /tmp>
    </macro>
    
    use test
    </directory>
    
    Error should not reach this point.
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test19.conf�����������������������������������������������������0000664�0001751�0001751�00000000625�12553146475�021145� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# okay till done
    
    <Macro foo $where>
      # something
      Warning "macro foo line 2 in $where"
    </Macro>
    
    <Directory /tmp>
      Use foo Directory
    </Directory>
    
    <Location /intra>
      Use foo Location
    </Location>
    
    <VirtualHost www.apache.org>
      Use foo VirtualHost
    </VirtualHost>
    
    <VirtualHost www.perl.com>
      <Directory /tmp>
        Use foo "VirtualHost & Directory"
      </Directory>
    </VirtualHost>
    
    Error "done line 26."
    �����������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test23.conf�����������������������������������������������������0000664�0001751�0001751�00000000270�12553146475�021134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# macro defined in a directory
    
    <Directory /tmp>
      <Macro foo>
        Warning "macro foo in /tmp"
      </Macro>
    </Directory>
    
    Use foo
    
    <Directory /tmp>
      Use foo
    </Directory>
    
    Error "done!"
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test27.conf�����������������������������������������������������0000664�0001751�0001751�00000000501�12553146475�021135� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# define a macro in a macro.
    
    <Macro foo $dir $name>
      <Macro foo.$name>
        <Directory $dir>
          Warning "foo.$name $dir"
        </Directory>
      </Macro>
    </Macro>
    
    Use foo /unexpected/1 one
    Use foo /unexpected/2 two
    
    Use foo.one
    Use foo.two
    Use foo.one
    
    UndefMacro foo.one
    UndefMacro foo.two
    UndefMacro foo
    
    Error "done!"
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test02.conf�����������������������������������������������������0000664�0001751�0001751�00000000063�12553146475�021131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# no macro name and spaces
    <Macro       >
    </Macro>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test06.conf�����������������������������������������������������0000664�0001751�0001751�00000000133�12553146475�021133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# wrong args
    <Macro foo $premier>
      Warning "macro foo $premier"
    </Macro>
    Use foo one two
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test10.conf�����������������������������������������������������0000664�0001751�0001751�00000000140�12553146475�021124� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# indirect recursion is bad
    <Macro foo>
    Use bla
    </Macro>
    
    <Macro bla>
    Use foo
    </Macro>
    
    Use foo
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test14.conf�����������������������������������������������������0000664�0001751�0001751�00000001036�12553146475�021135� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# VirtualHost example
    
    <Macro MyVirtualHost $host $port $dir>
      Listen $port
      <VirtualHost $host:$port>
        DocumentRoot $dir
        <Directory $dir>
          Warning "directory $dir"
        </Directory>
        # limit access to intranet subdir.
        <Directory $dir/intranet>
          Warning "directory $dir/intranet"
        </Directory>
      </VirtualHost>
    </Macro>
    
    Use MyVirtualHost www.apache.org 80 /projects/apache/web
    
    Use MyVirtualHost www.perl.com 8080 /projects/perl/web
    
    Use MyVirtualHost www.ensmp.fr 1234 /projects/mines/web
    
    Error "done line 23."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test18.conf�����������������������������������������������������0000664�0001751�0001751�00000000161�12553146475�021137� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# bad but good nesting
    
    <Macro foo>
    </Location>
    </Macro>
    
    <Location /intranet>
    Use foo
    
    Error "done on line 10."
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test22.conf�����������������������������������������������������0000664�0001751�0001751�00000000204�12553146475�021130� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# simple nesting
    
    <Macro foo>
      <Directory /tmp>
        Warning "macro foo"
      </Directory>
    </Macro>
    
    Use foo
    
    Error "done on line 11."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test01.conf�����������������������������������������������������0000664�0001751�0001751�00000000041�12553146475�021124� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# no macro name
    <Macro>
    </Macro>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test05.conf�����������������������������������������������������0000664�0001751�0001751�00000000122�12553146475�021130� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# wrong args
    <Macro foo $premier>
      Warning "macro foo $premier"
    </Macro>
    Use foo
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test09.conf�����������������������������������������������������0000664�0001751�0001751�00000000071�12553146475�021137� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# recursion is bad
    <Macro foo>
    Use foo
    </Macro>
    
    Use foo
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test13.conf�����������������������������������������������������0000664�0001751�0001751�00000000336�12553146475�021136� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# case insensitive
    <Macro FOO>
      Warning "macro FOO line 1"
    </MACRO>
    
    <MACRO bla>
      Warning "macro bla line 1"
    </macro>
    
    use foo
    
    <macro foo>
      Warning "redefined macro foo line 1"
    </macro>
    
    use FOO
    
    Error "done line 18."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test17.conf�����������������������������������������������������0000664�0001751�0001751�00000000156�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# bad but good nesting
    
    <Macro foo>
    </Directory>
    </Macro>
    
    <Directory /tmp>
    Use foo
    
    Error "done on line 10."
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test21.conf�����������������������������������������������������0000664�0001751�0001751�00000000222�12553146475�021127� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# raise an error
    
    <Macro foo>
      <Directory /tmp>
        Error "macro foo dir /tmp"
      </Directory>
    </Macro>
    
    <VirtualHost *>
      Use foo
    </VirtualHost>
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test25.conf�����������������������������������������������������0000664�0001751�0001751�00000000765�12553146475�021147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ok till stop.
    
    <Macro RestrictedAccessPolicy $ips>
      Warning "restricted access policy $ips"
    </Macro>
    
    <Directory /unexpected/1>
      Use RestrictedAccessPolicy 10.0.0.0/8
    </Directory>
    
    <Macro LocalAccessOnly>
      Use RestrictedAccessPolicy 10.0.0.0/8
    </Macro>
    
    <Directory /unexpected/2>
      Use RestrictedAccessPolicy "192.54.172.0/24 192.54.148.0/24 10.0.0.0/8"
    </Directory>
    
    <Location /intra>
      Use LocalAccessOnly
    </Location>
    
    <Location /admin>
      Use LocalAccessOnly
    </Location>
    
    Error "done line 27."
    �����������httpd-2.4.64/modules/core/test/conf/test29.conf�����������������������������������������������������0000664�0001751�0001751�00000000542�12553146475�021144� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# trigger line overflow during expansion
    
    <Macro toobigaline a>
      Warning aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
              aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    </Macro>
    
    Use toobigaline "cette ligne va etre vraiment trop longue ya pas de doute"
    
    Error "should not get there!"
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test33.conf�����������������������������������������������������0000664�0001751�0001751�00000000026�12553146475�021134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty name.
    
    Use ''
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test46.conf�����������������������������������������������������0000664�0001751�0001751�00000000202�12553146475�021134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# various working prefixes
    
    <Macro $i %j @k>
    # hello %j @k
    </Macro>
    
    <Macro warnings $i second>
    # not used.
    </Macro>
    
    Error okay.
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test59.conf�����������������������������������������������������0000664�0001751�0001751�00000000105�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty name
    <Macro ''>
      Warning "empty quoted name macro"
    </Macro>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test50.conf�����������������������������������������������������0000664�0001751�0001751�00000000125�12553146475�021133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# undef non existing macro
    <Macro foo>
      Warning "foo macro"
    </Macro>
    UndefMacro bla
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test63.conf�����������������������������������������������������0000664�0001751�0001751�00000000300�12553146475�021132� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# include
    include ${PWD}/inc63_1.conf
    Use Foo "test63.conf:3"
    <Macro Bla $where>
      Warning "Bla at $where"
    </Macro>
    include ${PWD}/inc63_2.conf
    Use Bla "test63.conf:8"
    Error "done at line 9."
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test54.conf�����������������������������������������������������0000664�0001751�0001751�00000000101�12553146475�021131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty macro
    <Macro foo>
    </Macro>
    Use foo
    
    Error "done line 6."
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test67.conf�����������������������������������������������������0000664�0001751�0001751�00000000042�12553146475�021141� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Error "done at line 1 without LF."����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test58.conf�����������������������������������������������������0000664�0001751�0001751�00000000111�12553146475�021136� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# bad directive closing
    <Macro foo
      Warning "macro foo line 1"
    </Macro>
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test42.conf�����������������������������������������������������0000664�0001751�0001751�00000000231�12553146475�021132� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# multiple macro uses
    
    <Macro foo $p>
     Warning "macro foo $p"
    </Macro>
    
    Use foo ''
    Use foo ''
    Use foo ''
    Use foo ''
    Use foo ''
    
    Error "done on line 13."
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test62.conf�����������������������������������������������������0000664�0001751�0001751�00000000427�12553146475�021143� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test continuations
    <Macro Line \
      $start \
      $stop>
      Warning \
        "Line:1-2 start at $start"
      Warning \
        "Line:3-4 stop at $stop"
    </Macro>
    
    Use Line 11 11
    Use Line \
      12 13
    Use Line \
      14 \
      16
    Use Line 17 \
      18
    Use Line \
      \
      19 \
      \
      23
    
    Error "done line 25."
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test66.conf�����������������������������������������������������0000664�0001751�0001751�00000000205�12553146475�021141� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# no double substitution
    <Macro Foo $x $y>
      Warning "Foo: x=$x y=$y"
    </Macro>
    Use Foo X Y
    Use Foo "$y" "$x"
    Error "done on line 7."
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test16.conf�����������������������������������������������������0000664�0001751�0001751�00000000121�12553146475�021131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# bad nesting
    
    <Macro foo>
    </Limit>
    </Macro>
    
    <Limit GET>
    Use foo
    </Limit>
    
    stop
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test37.conf�����������������������������������������������������0000664�0001751�0001751�00000000132�12553146475�021136� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty argument name
    
    <Macro stupid ''>
      Warn "macro stupid"
    </Macro>
    
    Use stupid hello
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test40.conf�����������������������������������������������������0000664�0001751�0001751�00000001331�12553146475�021132� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# configuration example with mod_macro
    #
    
    <VirtualHost www.foo.com>
      DocumentRoot /foo/document/root/directory
    
      <Macro SubDirAccessControl $subdir>
        # access control to subdirs...
        <Location /$subdir>
          Warning "location /$subdir"
        </Location>
      </Macro>
    
      # repeat uses
      Use SubDirAccessControl A
      Use SubDirAccessControl B
      Use SubDirAccessControl C
      Use SubDirAccessControl D
      Use SubDirAccessControl E
      Use SubDirAccessControl G
      Use SubDirAccessControl H
      Use SubDirAccessControl J
      Use SubDirAccessControl K
      Use SubDirAccessControl L
      Use SubDirAccessControl M
      Use SubDirAccessControl N
    
      # cleanup
      UndefMacro SubDirAccessControl
    
    </VirtualHost>
    
    Error Stop configuration file processing.
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test52.conf�����������������������������������������������������0000664�0001751�0001751�00000000222�12553146475�021133� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# undef existing macro, and try to use it
    <Macro foo>
      Warning "foo macro contents line 1"
    </Macro>
    Use foo
    UndefMacro foo
    
    Error "done line 8."
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test56.conf�����������������������������������������������������0000664�0001751�0001751�00000000354�12553146475�021145� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# nesting warnings
    <Macro Open $dir>
      <Directory $dir>
        Warning "Open:2 $dir"
    </Macro>
    <Macro Close>
        Warning "Close:1"
      </Directory>
    </Macro>
    
    # some uses
    Use Open /tmp
    Use Close
    
    Use Open /etc
    Use Close
    
    Error "done line 18."
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test49.conf�����������������������������������������������������0000664�0001751�0001751�00000000055�12553146475�021145� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# undef macro before anything
    UndefMacro foo
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test53.conf�����������������������������������������������������0000664�0001751�0001751�00000000067�12553146475�021143� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# use undefined macro without prior definition
    Use bla
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test60.conf�����������������������������������������������������0000664�0001751�0001751�00000000567�12553146475�021146� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# @ escaping
    <Macro Foo $one $two>
      Warning "macro Foo arg 1: $one"
      Warning "macro Foo arg 2: $two"
    </Macro>
    <Macro Bla @first @second>
      Warning Macro Bla arg 1: @first
      Warning Macro Bla arg 2: @second
      Use Foo @first 'second'
      Use Foo 'first' @second
      Use Foo @first @second
    </Macro>
    
    Use Foo hello world
    Use Bla "hello world" "thank you"
    
    Error "done on line 17."
    �����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/conf/test68.conf�����������������������������������������������������0000664�0001751�0001751�00000000150�12553146475�021142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# two directives with continuations & no eol at eof
    Warning \
      "line 2-3"
    Error \
      "done on line 4-5."������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/Makefile�������������������������������������������������������������0000664�0001751�0001751�00000002377�12553146475�017666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # mod_macro non regression tests
    
    # where is apache
    APA.dir	= /tmp/apache
    
    # apache executable with mod macro loaded
    HTTPD = \
    	$(APA.dir)/bin/httpd \
    	  -C 'LoadModule macro_module modules/mod_macro.so' \
    	  -C "Define PWD $$PWD/conf"
    
    # default target
    .PHONY: default
    default: clean
    
    # run all non regression tests
    .PHONY: check
    check: check-out
    
    # result directory
    OUT	= out
    out:
    	mkdir $@
    
    # test cases & results
    F.conf	= $(wildcard conf/test*.conf)
    F.out	= $(F.conf:conf/%.conf=$(OUT)/%.out)
    
    # run all tests
    .PHONY: run-test
    run-test: $(F.out)
    
    # generate & compare in a separate directory
    .PHONY: check-out
    check-out: out
    	$(RM) out/*.out
    	$(MAKE) OUT=out run-test
    	diff -r out/ ref/
    
    # generate & compare in the same directory
    .PHONY: check-ref
    check-ref:
    	$(RM) ref/*.out
    	$(MAKE) OUT=ref run-test
    	svn diff ref/
    
    # run one test case
    # filter output so that it is portable
    # use '|' sed separator because $PWD will contain plenty '/'
    $(OUT)/%.out: conf/%.conf
    	{ \
    	  echo "# testing with $<" ; \
    	  $(HTTPD) -f $$PWD/$< 2>&1 ; \
    	  echo "# exit: $$?" ; \
    	} > $@.tmp ; \
    	sed -e "s|$$PWD|.|g" \
    	    -e "s|^\[[\.a-zA-Z0-9 :]*\] ||" \
    	    -e "s|\[pid [0-9]*:tid [0-9]*] ||" \
    	    $@.tmp > $@ ; \
    	$(RM) $@.tmp
    
    # cleanup
    .PHONY: clean
    clean:
    	$(RM) *~
    	$(RM) -r out
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/�����������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016767� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test69.out�������������������������������������������������������0000664�0001751�0001751�00000001512�12076740760�020654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test69.conf
    [macro:warn] non blank chars found after <Macro closing '>' on line 2 of ./conf/test69.conf:  this stuff is ignored...
    [macro:warn] non blank chars found after directive closing on line 4 of ./conf/test69.conf:  this stuff is ignored as well...
    [core:warn] Foo on line 1 of macro 'foo' (defined on line 2 of "./conf/test69.conf") used on line 5 of "./conf/test69.conf"
    [core:warn] Bla on line 1 of macro 'bla' (defined on line 6 of "./conf/test69.conf") used on line 9 of "./conf/test69.conf"
    [core:warn] Comments on line 1 of macro 'comments' (defined on line 10 of "./conf/test69.conf") used on line 13 of "./conf/test69.conf"
    [core:error] done on line 14. on line 14 of ./conf/test69.conf
    AH00526: Syntax error on line 14 of ./conf/test69.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test25.out�������������������������������������������������������0000664�0001751�0001751�00000002143�12076740760�020645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test25.conf
    [core:warn] restricted access policy 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 8 of "./conf/test25.conf"
    [core:warn] restricted access policy 192.54.172.0/24 192.54.148.0/24 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 16 of "./conf/test25.conf"
    [core:warn] restricted access policy 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 1 of "macro 'localaccessonly' (defined on line 11 of "./conf/test25.conf") used on line 20 of "./conf/test25.conf""
    [core:warn] restricted access policy 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 1 of "macro 'localaccessonly' (defined on line 11 of "./conf/test25.conf") used on line 24 of "./conf/test25.conf""
    [core:error] done line 27. on line 27 of ./conf/test25.conf
    AH00526: Syntax error on line 27 of ./conf/test25.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test68.out�������������������������������������������������������0000664�0001751�0001751�00000000411�12076740760�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test68.conf
    [core:warn] line 2-3 on line 3 of ./conf/test68.conf
    [core:error] done on line 4-5. on line 5 of ./conf/test68.conf
    AH00526: Syntax error on line 5 of ./conf/test68.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test26.out�������������������������������������������������������0000664�0001751�0001751�00000002127�12076740760�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test26.conf
    [macro:warn] macro 'funny' (defined on line 4 of "./conf/test26.conf") argument name 'first arg' (#1) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'funny' (defined on line 4 of "./conf/test26.conf") argument name 'second ... arg' (#2) without expected prefix, better prefix argument names with one of '$%@'.
    [core:warn] funny directory on line 2 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 13 of "./conf/test26.conf"
    [core:warn] funny location on line 5 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 13 of "./conf/test26.conf"
    [core:warn] funny directory on line 2 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 16 of "./conf/test26.conf"
    [core:warn] funny location on line 5 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 16 of "./conf/test26.conf"
    [core:error] done! on line 19 of ./conf/test26.conf
    AH00526: Syntax error on line 19 of ./conf/test26.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test64.out�������������������������������������������������������0000664�0001751�0001751�00000000512�12076740760�020646� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test64.conf
    [core:warn] on line 2 on line 2 of ./conf/test64.conf
    [core:warn] from line 3 to line 4 on line 4 of ./conf/test64.conf
    [core:error] done on line 5. on line 5 of ./conf/test64.conf
    AH00526: Syntax error on line 5 of ./conf/test64.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test62.out�������������������������������������������������������0000664�0001751�0001751�00000003143�12076740760�020647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test62.conf
    [core:warn] Line:1-2 start at 11 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 11 of "./conf/test62.conf"
    [core:warn] Line:3-4 stop at 11 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 11 of "./conf/test62.conf"
    [core:warn] Line:1-2 start at 12 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 13 of "./conf/test62.conf"
    [core:warn] Line:3-4 stop at 13 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 13 of "./conf/test62.conf"
    [core:warn] Line:1-2 start at 14 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 16 of "./conf/test62.conf"
    [core:warn] Line:3-4 stop at 16 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 16 of "./conf/test62.conf"
    [core:warn] Line:1-2 start at 17 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 18 of "./conf/test62.conf"
    [core:warn] Line:3-4 stop at 18 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 18 of "./conf/test62.conf"
    [core:warn] Line:1-2 start at 19 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 23 of "./conf/test62.conf"
    [core:warn] Line:3-4 stop at 23 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 23 of "./conf/test62.conf"
    [core:error] done line 25. on line 25 of ./conf/test62.conf
    AH00526: Syntax error on line 25 of ./conf/test62.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test36.out�������������������������������������������������������0000664�0001751�0001751�00000004333�12076740760�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test36.conf
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($u #1 and $u1 #3), be careful about your macro definition!
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($u #1 and $u2 #5), be careful about your macro definition!
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($n #2 and $n1 #4), be careful about your macro definition!
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($n #2 and $n2 #6), be careful about your macro definition!
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument '$n' (#2) never used
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument '$n1' (#4) never used
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument '$n2' (#6) never used
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #1
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #2
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #3
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #4
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #5
    [macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #6
    [core:warn] many warnings! 1 3 5 on line 1 of macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 7 of "./conf/test36.conf"
    [core:warn] many warnings!    on line 1 of macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf"
    [core:error] done! on line 12 of ./conf/test36.conf
    AH00526: Syntax error on line 12 of ./conf/test36.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test04.out�������������������������������������������������������0000664�0001751�0001751�00000000272�12076740760�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test04.conf
    httpd: Syntax error on line 5 of ./conf/test04.conf: macro 'foo' (defined on line 2 of "./conf/test04.conf") used with 1 arguments instead of 0
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test42.out�������������������������������������������������������0000664�0001751�0001751�00000002743�12076740760�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test42.conf
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 7 of "./conf/test42.conf": empty argument #1
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 8 of "./conf/test42.conf": empty argument #1
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 9 of "./conf/test42.conf": empty argument #1
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 10 of "./conf/test42.conf": empty argument #1
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 11 of "./conf/test42.conf": empty argument #1
    [core:warn] macro foo  on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 7 of "./conf/test42.conf"
    [core:warn] macro foo  on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 8 of "./conf/test42.conf"
    [core:warn] macro foo  on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 9 of "./conf/test42.conf"
    [core:warn] macro foo  on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 10 of "./conf/test42.conf"
    [core:warn] macro foo  on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 11 of "./conf/test42.conf"
    [core:error] done on line 13. on line 13 of ./conf/test42.conf
    AH00526: Syntax error on line 13 of ./conf/test42.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������httpd-2.4.64/modules/core/test/ref/test39.out�������������������������������������������������������0000664�0001751�0001751�00000000750�12076740760�020654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test39.conf
    [core:warn] Thanks for using mod_macro! on line 1 of macro 'modmacro' (defined on line 4 of "./conf/test39.conf") used on line 15 of "./conf/test39.conf"
    [core:warn] macro foo on line 1 of macro 'foo' (defined on line 17 of "./conf/test39.conf") used on line 21 of "./conf/test39.conf"
    [core:error] done! on line 23 of ./conf/test39.conf
    AH00526: Syntax error on line 23 of ./conf/test39.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ������������������������httpd-2.4.64/modules/core/test/ref/test40.out�������������������������������������������������������0000664�0001751�0001751�00000004061�12076740760�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test40.conf
    AH00112: Warning: DocumentRoot [/foo/document/root/directory] does not exist
    [core:warn] location /A on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 15 of "./conf/test40.conf"
    [core:warn] location /B on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 16 of "./conf/test40.conf"
    [core:warn] location /C on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 17 of "./conf/test40.conf"
    [core:warn] location /D on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 18 of "./conf/test40.conf"
    [core:warn] location /E on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 19 of "./conf/test40.conf"
    [core:warn] location /G on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 20 of "./conf/test40.conf"
    [core:warn] location /H on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 21 of "./conf/test40.conf"
    [core:warn] location /J on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 22 of "./conf/test40.conf"
    [core:warn] location /K on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 23 of "./conf/test40.conf"
    [core:warn] location /L on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 24 of "./conf/test40.conf"
    [core:warn] location /M on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 25 of "./conf/test40.conf"
    [core:warn] location /N on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 26 of "./conf/test40.conf"
    [core:error] Stop configuration file processing. on line 33 of ./conf/test40.conf
    AH00526: Syntax error on line 33 of ./conf/test40.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test33.out�������������������������������������������������������0000664�0001751�0001751�00000000173�12076740760�020645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test33.conf
    httpd: Syntax error on line 3 of ./conf/test33.conf: no macro defined before Use
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test37.out�������������������������������������������������������0000664�0001751�0001751�00000000262�12076740760�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test37.conf
    httpd: Syntax error on line 3 of ./conf/test37.conf: macro 'stupid' (defined on line 3 of "./conf/test37.conf"): empty argument #1 name
    # exit: 1
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test48.out�������������������������������������������������������0000664�0001751�0001751�00000004117�12076740760�020655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test48.conf
    [core:warn] 1 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 7 of "./conf/test48.conf"
    [core:warn] 12 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 8 of "./conf/test48.conf"
    [core:warn] 123 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 9 of "./conf/test48.conf"
    [core:warn] 1234 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 10 of "./conf/test48.conf"
    [core:warn] 12345 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 11 of "./conf/test48.conf"
    [core:warn] 123456 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 12 of "./conf/test48.conf"
    [core:warn] 1234567 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 13 of "./conf/test48.conf"
    [core:warn] 12345678 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 14 of "./conf/test48.conf"
    [core:warn] 123456789 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 15 of "./conf/test48.conf"
    [core:warn] 1234567890 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 16 of "./conf/test48.conf"
    [core:warn] 1234567890a on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 17 of "./conf/test48.conf"
    [core:warn] 1234567890ab on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 18 of "./conf/test48.conf"
    [core:warn] 1234567890abc on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 19 of "./conf/test48.conf"
    [core:warn] 1234567890abcd on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 20 of "./conf/test48.conf"
    [core:warn] 1234567890abcde on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 21 of "./conf/test48.conf"
    [core:error] done line 23. on line 23 of ./conf/test48.conf
    AH00526: Syntax error on line 23 of ./conf/test48.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test12.out�������������������������������������������������������0000664�0001751�0001751�00000000741�12076740760�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test12.conf
    [macro:warn] macro 'foo' multiply defined: defined on line 2 of "./conf/test12.conf", redefined on line 6 of "./conf/test12.conf"
    [core:warn] macro foo 2, line 1 on line 1 of macro 'foo' (defined on line 6 of "./conf/test12.conf") used on line 10 of "./conf/test12.conf"
    [core:error] done line 12. on line 12 of ./conf/test12.conf
    AH00526: Syntax error on line 12 of ./conf/test12.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������httpd-2.4.64/modules/core/test/ref/test15.out�������������������������������������������������������0000664�0001751�0001751�00000000503�12076740760�020642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test15.conf
    [macro:warn] bad cumulated nesting (+1) in macro 'test' (defined on line 2 of "./conf/test15.conf")
    [core:error] should not reach this point. on line 9 of ./conf/test15.conf
    AH00526: Syntax error on line 9 of ./conf/test15.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test17.out�������������������������������������������������������0000664�0001751�0001751�00000000641�12076740760�020647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test17.conf
    [macro:warn] bad (negative) nesting on line 2 of macro 'foo' (defined on line 3 of "./conf/test17.conf")
    [macro:warn] bad cumulated nesting (-1) in macro 'foo' (defined on line 3 of "./conf/test17.conf")
    [core:error] done on line 10. on line 10 of ./conf/test17.conf
    AH00526: Syntax error on line 10 of ./conf/test17.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test11.out�������������������������������������������������������0000664�0001751�0001751�00000000656�12076740760�020647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test11.conf
    [core:warn] macro one.in line 1 on line 1 of macro 'one.in' (defined on line 1 of "macro 'foo' (defined on line 2 of "./conf/test11.conf") used on line 9 of "./conf/test11.conf"") used on line 12 of "./conf/test11.conf"
    [core:error] done line 15. on line 15 of ./conf/test11.conf
    AH00526: Syntax error on line 15 of ./conf/test11.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ����������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test14.out�������������������������������������������������������0000664�0001751�0001751�00000002577�12076740760�020656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test14.conf
    AH00112: Warning: DocumentRoot [/projects/apache/web] does not exist
    [core:warn] directory /projects/apache/web on line 5 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 17 of "./conf/test14.conf"
    [core:warn] directory /projects/apache/web/intranet on line 8 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 17 of "./conf/test14.conf"
    AH00112: Warning: DocumentRoot [/projects/perl/web] does not exist
    [core:warn] directory /projects/perl/web on line 5 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 19 of "./conf/test14.conf"
    [core:warn] directory /projects/perl/web/intranet on line 8 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 19 of "./conf/test14.conf"
    AH00112: Warning: DocumentRoot [/projects/mines/web] does not exist
    [core:warn] directory /projects/mines/web on line 5 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 21 of "./conf/test14.conf"
    [core:warn] directory /projects/mines/web/intranet on line 8 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 21 of "./conf/test14.conf"
    [core:error] done line 23. on line 23 of ./conf/test14.conf
    AH00526: Syntax error on line 23 of ./conf/test14.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test16.out�������������������������������������������������������0000664�0001751�0001751�00000000525�12076740760�020647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test16.conf
    [macro:warn] bad (negative) nesting on line 2 of macro 'foo' (defined on line 3 of "./conf/test16.conf")
    [macro:warn] bad cumulated nesting (-1) in macro 'foo' (defined on line 3 of "./conf/test16.conf")
    httpd: Syntax error on line 9 of ./conf/test16.conf: </Limit> without matching <Limit> section
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test13.out�������������������������������������������������������0000664�0001751�0001751�00000001164�12076740760�020644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test13.conf
    [macro:warn] macro 'foo' multiply defined: defined on line 2 of "./conf/test13.conf", redefined on line 12 of "./conf/test13.conf"
    [core:warn] macro FOO line 1 on line 1 of macro 'foo' (defined on line 2 of "./conf/test13.conf") used on line 10 of "./conf/test13.conf"
    [core:warn] redefined macro foo line 1 on line 1 of macro 'foo' (defined on line 12 of "./conf/test13.conf") used on line 16 of "./conf/test13.conf"
    [core:error] done line 18. on line 18 of ./conf/test13.conf
    AH00526: Syntax error on line 18 of ./conf/test13.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test51.out�������������������������������������������������������0000664�0001751�0001751�00000000165�12076740760�020646� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test51.conf
    httpd: Syntax error on line 9 of ./conf/test51.conf: macro 'foo' undefined
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test01.out�������������������������������������������������������0000664�0001751�0001751�00000000203�12076740760�020632� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test01.conf
    httpd: Syntax error on line 2 of ./conf/test01.conf: <Macro macro definition: empty name
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test44.out�������������������������������������������������������0000664�0001751�0001751�00000000312�12076740760�020642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test44.conf
    [core:error] okay. on line 19 of ./conf/test44.conf
    AH00526: Syntax error on line 19 of ./conf/test44.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test35.out�������������������������������������������������������0000664�0001751�0001751�00000002654�12076740760�020655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test35.conf
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'u1' (#1) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'u2' (#2) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'n1' (#3) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'n2' (#4) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'u3' (#5) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf"): argument 'n1' (#3) never used
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf"): argument 'n2' (#4) never used
    [core:warn] macro cannot be used just within a comment 1 2 5 on line 1 of macro 'warnings' (defined on line 3 of "./conf/test35.conf") used on line 8 of "./conf/test35.conf"
    [core:error] done on line 10. on line 10 of ./conf/test35.conf
    AH00526: Syntax error on line 10 of ./conf/test35.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test06.out�������������������������������������������������������0000664�0001751�0001751�00000000272�12076740760�020645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test06.conf
    httpd: Syntax error on line 5 of ./conf/test06.conf: macro 'foo' (defined on line 2 of "./conf/test06.conf") used with 2 arguments instead of 1
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test46.out�������������������������������������������������������0000664�0001751�0001751�00000001232�12076740760�020646� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test46.conf
    [macro:warn] macro '$i' (defined on line 3 of "./conf/test46.conf") better prefix a macro name with any of '$%@'
    [macro:warn] macro '$i' (defined on line 3 of "./conf/test46.conf"): empty contents!
    [macro:warn] macro 'warnings' (defined on line 7 of "./conf/test46.conf") argument name 'second' (#2) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 7 of "./conf/test46.conf"): empty contents!
    [core:error] okay. on line 11 of ./conf/test46.conf
    AH00526: Syntax error on line 11 of ./conf/test46.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test02.out�������������������������������������������������������0000664�0001751�0001751�00000000203�12076740760�020633� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test02.conf
    httpd: Syntax error on line 2 of ./conf/test02.conf: <Macro macro definition: empty name
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test43.out�������������������������������������������������������0000664�0001751�0001751�00000001002�12076740760�020636� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test43.conf
    [macro:warn] bad cumulated nesting (+1) in macro 'begindir' (defined on line 3 of "./conf/test43.conf")
    [macro:warn] bad (negative) nesting on line 2 of macro 'enddir' (defined on line 8 of "./conf/test43.conf")
    [macro:warn] bad cumulated nesting (-1) in macro 'enddir' (defined on line 8 of "./conf/test43.conf")
    [core:error] ok! on line 29 of ./conf/test43.conf
    AH00526: Syntax error on line 29 of ./conf/test43.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test30.out�������������������������������������������������������0000664�0001751�0001751�00000001014�12076740760�020635� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test30.conf
    [macro:warn] macro 'foo' (defined on line 4 of "./conf/test30.conf"): argument name prefix conflict ($dir #1 and $directive #2), be careful about your macro definition!
    [core:warn] section Directory /unexpected/1 on line 2 of macro 'foo' (defined on line 4 of "./conf/test30.conf") used on line 10 of "./conf/test30.conf"
    [core:error] done! on line 12 of ./conf/test30.conf
    AH00526: Syntax error on line 12 of ./conf/test30.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test34.out�������������������������������������������������������0000664�0001751�0001751�00000002307�12076740760�020647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test34.conf
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test34.conf"): argument name prefix conflict ($d #1 and $dd #2), be careful about your macro definition!
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test34.conf"): argument '$d' (#1) never used
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test34.conf"): argument '$dd' (#2) never used
    [macro:warn] macro 'bla' (defined on line 7 of "./conf/test34.conf"): argument name prefix conflict ($dd #1 and $d #2), be careful about your macro definition!
    [macro:warn] macro 'bla' (defined on line 7 of "./conf/test34.conf"): argument '$dd' (#1) never used
    [macro:warn] macro 'bla' (defined on line 7 of "./conf/test34.conf"): argument '$d' (#2) never used
    [core:warn] macro foo conflict one on line 1 of macro 'foo' (defined on line 3 of "./conf/test34.conf") used on line 11 of "./conf/test34.conf"
    [core:warn] macro bla conflict two on line 1 of macro 'bla' (defined on line 7 of "./conf/test34.conf") used on line 12 of "./conf/test34.conf"
    [core:error] done on line 14. on line 14 of ./conf/test34.conf
    AH00526: Syntax error on line 14 of ./conf/test34.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test38.out�������������������������������������������������������0000664�0001751�0001751�00000000523�12076740760�020651� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test38.conf
    [core:warn] it is really a good idea to have mod_macro.c installed. on line 4 of ./conf/test38.conf
    [core:error] it seems you do not have mod perl installed. on line 8 of ./conf/test38.conf
    AH00526: Syntax error on line 8 of ./conf/test38.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test10.out�������������������������������������������������������0000664�0001751�0001751�00000000440�12076740760�020635� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test10.conf
    httpd: Syntax error on line 1 of macro 'bla' (defined on line 6 of "./conf/test10.conf") used on line 1 of "macro 'foo' (defined on line 2 of "./conf/test10.conf") used on line 10 of "./conf/test10.conf"": recursive use of macro 'foo' is invalid
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test50.out�������������������������������������������������������0000664�0001751�0001751�00000000203�12076740760�020636� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test50.conf
    httpd: Syntax error on line 5 of ./conf/test50.conf: cannot remove undefined macro 'bla'
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test52.out�������������������������������������������������������0000664�0001751�0001751�00000000541�12076740760�020645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test52.conf
    [core:warn] foo macro contents line 1 on line 1 of macro 'foo' (defined on line 2 of "./conf/test52.conf") used on line 5 of "./conf/test52.conf"
    [core:error] done line 8. on line 8 of ./conf/test52.conf
    AH00526: Syntax error on line 8 of ./conf/test52.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test54.out�������������������������������������������������������0000664�0001751�0001751�00000000445�12076740760�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test54.conf
    [macro:warn] macro 'foo' (defined on line 2 of "./conf/test54.conf"): empty contents!
    [core:error] done line 6. on line 6 of ./conf/test54.conf
    AH00526: Syntax error on line 6 of ./conf/test54.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test56.out�������������������������������������������������������0000664�0001751�0001751�00000002030�12076740760�020644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test56.conf
    [macro:warn] bad cumulated nesting (+1) in macro 'open' (defined on line 2 of "./conf/test56.conf")
    [macro:warn] bad (negative) nesting on line 3 of macro 'close' (defined on line 6 of "./conf/test56.conf")
    [macro:warn] bad cumulated nesting (-1) in macro 'close' (defined on line 6 of "./conf/test56.conf")
    [core:warn] Open:2 /tmp on line 2 of macro 'open' (defined on line 2 of "./conf/test56.conf") used on line 12 of "./conf/test56.conf"
    [core:warn] Close:1 on line 1 of macro 'close' (defined on line 6 of "./conf/test56.conf") used on line 13 of "./conf/test56.conf"
    [core:warn] Open:2 /etc on line 2 of macro 'open' (defined on line 2 of "./conf/test56.conf") used on line 15 of "./conf/test56.conf"
    [core:warn] Close:1 on line 1 of macro 'close' (defined on line 6 of "./conf/test56.conf") used on line 16 of "./conf/test56.conf"
    [core:error] done line 18. on line 18 of ./conf/test56.conf
    AH00526: Syntax error on line 18 of ./conf/test56.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test03.out�������������������������������������������������������0000664�0001751�0001751�00000000165�12076740760�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test03.conf
    httpd: Syntax error on line 5 of ./conf/test03.conf: macro 'bla' undefined
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test05.out�������������������������������������������������������0000664�0001751�0001751�00000000272�12076740760�020644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test05.conf
    httpd: Syntax error on line 5 of ./conf/test05.conf: macro 'foo' (defined on line 2 of "./conf/test05.conf") used with 0 arguments instead of 1
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test07.out�������������������������������������������������������0000664�0001751�0001751�00000000315�12076740760�020644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test07.conf
    httpd: Syntax error on line 2 of ./conf/test07.conf: macro 'foo' (defined on line 2 of "./conf/test07.conf")\n\tcontents error: expected token not found: </Macro>
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test45.out�������������������������������������������������������0000664�0001751�0001751�00000004743�12076740760�020657� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test45.conf
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '&3' (#3) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '#5' (#5) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '~6' (#6) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '*7' (#7) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '.8' (#8) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name ',9' (#9) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '!a' (#10) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '-b' (#11) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '+c' (#12) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '=d' (#13) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name ':e' (#14) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name ';f' (#15) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '?g' (#16) without expected prefix, better prefix argument names with one of '$%@'.
    [macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf"): empty contents!
    [core:error] done on line 7. on line 7 of ./conf/test45.conf
    AH00526: Syntax error on line 7 of ./conf/test45.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������httpd-2.4.64/modules/core/test/ref/test19.out�������������������������������������������������������0000664�0001751�0001751�00000001474�12076740760�020656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test19.conf
    [core:warn] macro foo line 2 in Directory on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 9 of "./conf/test19.conf"
    [core:warn] macro foo line 2 in Location on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 13 of "./conf/test19.conf"
    [core:warn] macro foo line 2 in VirtualHost on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 17 of "./conf/test19.conf"
    [core:warn] macro foo line 2 in VirtualHost & Directory on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 22 of "./conf/test19.conf"
    [core:error] done line 26. on line 26 of ./conf/test19.conf
    AH00526: Syntax error on line 26 of ./conf/test19.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test18.out�������������������������������������������������������0000664�0001751�0001751�00000000641�12076740760�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test18.conf
    [macro:warn] bad (negative) nesting on line 2 of macro 'foo' (defined on line 3 of "./conf/test18.conf")
    [macro:warn] bad cumulated nesting (-1) in macro 'foo' (defined on line 3 of "./conf/test18.conf")
    [core:error] done on line 10. on line 10 of ./conf/test18.conf
    AH00526: Syntax error on line 10 of ./conf/test18.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test53.out�������������������������������������������������������0000664�0001751�0001751�00000000173�12076740760�020647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test53.conf
    httpd: Syntax error on line 2 of ./conf/test53.conf: no macro defined before Use
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test55.out�������������������������������������������������������0000664�0001751�0001751�00000001361�12076740760�020651� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test55.conf
    [core:warn] macro foo(:2) line 1 (file line 9) on line 1 of macro 'foo' (defined on line 2 of "./conf/test55.conf") used on line 9 of "./conf/test55.conf"
    [core:warn] macro bla(:5) line 1 (file line 10) on line 1 of macro 'bla' (defined on line 5 of "./conf/test55.conf") used on line 10 of "./conf/test55.conf"
    [core:warn] macro foo(:2) line 1 (bla line 2) on line 1 of macro 'foo' (defined on line 2 of "./conf/test55.conf") used on line 2 of "macro 'bla' (defined on line 5 of "./conf/test55.conf") used on line 10 of "./conf/test55.conf""
    [core:error] done line 11. on line 11 of ./conf/test55.conf
    AH00526: Syntax error on line 11 of ./conf/test55.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test58.out�������������������������������������������������������0000664�0001751�0001751�00000000205�12076740760�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test58.conf
    httpd: Syntax error on line 2 of ./conf/test58.conf: <Macro> directive missing closing '>'
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test22.out�������������������������������������������������������0000664�0001751�0001751�00000000527�12076740760�020646� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test22.conf
    [core:warn] macro foo on line 2 of macro 'foo' (defined on line 3 of "./conf/test22.conf") used on line 9 of "./conf/test22.conf"
    [core:error] done on line 11. on line 11 of ./conf/test22.conf
    AH00526: Syntax error on line 11 of ./conf/test22.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test57.out�������������������������������������������������������0000664�0001751�0001751�00000000257�12076740760�020656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test57.conf
    httpd: Syntax error on line 2 of ./conf/test57.conf: macro 'foo' (defined on line 2 of "./conf/test57.conf"): empty argument #2 name
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test20.out�������������������������������������������������������0000664�0001751�0001751�00000000312�12076740760�020634� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test20.conf
    AH00526: Syntax error on line 1 of macro 'foo' (defined on line 3 of "./conf/test20.conf") used on line 10 of "./conf/test20.conf":
    <Directory not allowed here
    # exit: 1
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test59.out�������������������������������������������������������0000664�0001751�0001751�00000000207�12076740760�020653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test59.conf
    httpd: Syntax error on line 2 of ./conf/test59.conf: <Macro macro definition: name not found
    # exit: 1
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test23.out�������������������������������������������������������0000664�0001751�0001751�00000000737�12076740760�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test23.conf
    [core:warn] macro foo in /tmp on line 1 of macro 'foo' (defined on line 4 of "./conf/test23.conf") used on line 9 of "./conf/test23.conf"
    [core:warn] macro foo in /tmp on line 1 of macro 'foo' (defined on line 4 of "./conf/test23.conf") used on line 12 of "./conf/test23.conf"
    [core:error] done! on line 15 of ./conf/test23.conf
    AH00526: Syntax error on line 15 of ./conf/test23.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������httpd-2.4.64/modules/core/test/ref/test49.out�������������������������������������������������������0000664�0001751�0001751�00000000202�12076740760�020645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test49.conf
    httpd: Syntax error on line 2 of ./conf/test49.conf: no macro defined before UndefMacro
    # exit: 1
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test21.out�������������������������������������������������������0000664�0001751�0001751�00000000557�12076740760�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test21.conf
    [core:error] macro foo dir /tmp on line 2 of macro 'foo' (defined on line 3 of "./conf/test21.conf") used on line 10 of "./conf/test21.conf"
    AH00526: Syntax error on line 2 of macro 'foo' (defined on line 3 of "./conf/test21.conf") used on line 10 of "./conf/test21.conf":
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test24.out�������������������������������������������������������0000664�0001751�0001751�00000001361�12076740760�020645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test24.conf
    [core:warn] macro bla intra on line 2 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 13 of "./conf/test24.conf"
    [core:warn] macro bla private on line 5 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 13 of "./conf/test24.conf"
    [core:warn] macro bla intra on line 2 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 17 of "./conf/test24.conf"
    [core:warn] macro bla private on line 5 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 17 of "./conf/test24.conf"
    AH00526: Syntax error on line 1 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 22 of "./conf/test24.conf":
    <Location not allowed here
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test61.out�������������������������������������������������������0000664�0001751�0001751�00000002264�12076740760�020651� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test61.conf
    [core:warn] F4:1 x=line=17 on line 1 of macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf"
    [core:warn] F3:1 x=line=17 on line 1 of macro 'f3' (defined on line 9 of "./conf/test61.conf") used on line 2 of "macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf""
    [core:warn] F2:1 x=line=17 on line 1 of macro 'f2' (defined on line 5 of "./conf/test61.conf") used on line 2 of "macro 'f3' (defined on line 9 of "./conf/test61.conf") used on line 2 of "macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf"""
    [core:warn] F1:1 x=line=17 on line 1 of macro 'f1' (defined on line 2 of "./conf/test61.conf") used on line 2 of "macro 'f2' (defined on line 5 of "./conf/test61.conf") used on line 2 of "macro 'f3' (defined on line 9 of "./conf/test61.conf") used on line 2 of "macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf""""
    [core:error] done line 18. on line 18 of ./conf/test61.conf
    AH00526: Syntax error on line 18 of ./conf/test61.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test63.out�������������������������������������������������������0000664�0001751�0001751�00000001655�12076740760�020656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test63.conf
    [core:warn] Foo macro at inc63_.conf:5 on line 1 of macro 'foo' (defined on line 2 of "./conf/inc63_1.conf") used on line 5 of "./conf/inc63_1.conf"
    [core:warn] Foo macro at test63.conf:3 on line 1 of macro 'foo' (defined on line 2 of "./conf/inc63_1.conf") used on line 3 of "./conf/test63.conf"
    [core:warn] Foo macro at inc63_2.conf:2 on line 1 of macro 'foo' (defined on line 2 of "./conf/inc63_1.conf") used on line 2 of "./conf/inc63_2.conf"
    [core:warn] Bla at inc63_2.conf:3 on line 1 of macro 'bla' (defined on line 4 of "./conf/test63.conf") used on line 3 of "./conf/inc63_2.conf"
    [core:warn] Bla at test63.conf:8 on line 1 of macro 'bla' (defined on line 4 of "./conf/test63.conf") used on line 8 of "./conf/test63.conf"
    [core:error] done at line 9. on line 9 of ./conf/test63.conf
    AH00526: Syntax error on line 9 of ./conf/test63.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �����������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test29.out�������������������������������������������������������0000664�0001751�0001751�00000001021�12076740760�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test29.conf
    [macro:warn] macro 'toobigaline' (defined on line 3 of "./conf/test29.conf") argument name 'a' (#1) without expected prefix, better prefix argument names with one of '$%@'.
    httpd: Syntax error on line 8 of ./conf/test29.conf: macro 'toobigaline' (defined on line 3 of "./conf/test29.conf") used on line 8 of "./conf/test29.conf" error while substituting: while processing line 1 of macro 'toobigaline' (defined on line 3 of "./conf/test29.conf") cannot substitute, buffer size too small
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test27.out�������������������������������������������������������0000664�0001751�0001751�00000001552�12076740760�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test27.conf
    [core:warn] foo.one /unexpected/1 on line 2 of macro 'foo.one' (defined on line 1 of "macro 'foo' (defined on line 3 of "./conf/test27.conf") used on line 11 of "./conf/test27.conf"") used on line 14 of "./conf/test27.conf"
    [core:warn] foo.two /unexpected/2 on line 2 of macro 'foo.two' (defined on line 1 of "macro 'foo' (defined on line 3 of "./conf/test27.conf") used on line 12 of "./conf/test27.conf"") used on line 15 of "./conf/test27.conf"
    [core:warn] foo.one /unexpected/1 on line 2 of macro 'foo.one' (defined on line 1 of "macro 'foo' (defined on line 3 of "./conf/test27.conf") used on line 11 of "./conf/test27.conf"") used on line 16 of "./conf/test27.conf"
    [core:error] done! on line 22 of ./conf/test27.conf
    AH00526: Syntax error on line 22 of ./conf/test27.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test65.out�������������������������������������������������������0000664�0001751�0001751�00000000755�12076740760�020660� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test65.conf
    [core:warn] Line: on line 6-7 on line 1 of macro 'line' (defined on line 2 of "./conf/test65.conf") used on line 7 of "./conf/test65.conf"
    [core:warn] Line: on line 8-10 on line 1 of macro 'line' (defined on line 2 of "./conf/test65.conf") used on line 10 of "./conf/test65.conf"
    [core:error] done on line 11. on line 11 of ./conf/test65.conf
    AH00526: Syntax error on line 11 of ./conf/test65.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    �������������������httpd-2.4.64/modules/core/test/ref/test67.out�������������������������������������������������������0000664�0001751�0001751�00000000335�12076740760�020654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test67.conf
    [core:error] done at line 1 without LF. on line 1 of ./conf/test67.conf
    AH00526: Syntax error on line 1 of ./conf/test67.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test31.out�������������������������������������������������������0000664�0001751�0001751�00000005247�12076740760�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test31.conf
    [macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($dir #1 and $di #2), be careful about your macro definition!
    [macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($dir #1 and $d #4), be careful about your macro definition!
    [macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($di #2 and $d #4), be careful about your macro definition!
    [macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($dd #3 and $d #4), be careful about your macro definition!
    [macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf") used on line 8 of "./conf/test31.conf": empty argument #1
    [macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf") used on line 8 of "./conf/test31.conf": empty argument #2
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($d #1 and $di #2), be careful about your macro definition!
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($d #1 and $dir #3), be careful about your macro definition!
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($d #1 and $dd #4), be careful about your macro definition!
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($di #2 and $dir #3), be careful about your macro definition!
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$d' (#1) never used
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$di' (#2) never used
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$dir' (#3) never used
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$dd' (#4) never used
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf") used on line 14 of "./conf/test31.conf": empty argument #1
    [macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf") used on line 14 of "./conf/test31.conf": empty argument #2
    [core:warn] argument name conflicts on line 1 of macro 'bla' (defined on line 3 of "./conf/test31.conf") used on line 8 of "./conf/test31.conf"
    [core:warn] conflicts, but arguments are not used on line 1 of macro 'foo' (defined on line 10 of "./conf/test31.conf") used on line 14 of "./conf/test31.conf"
    [core:error] done on line 16. on line 16 of ./conf/test31.conf
    AH00526: Syntax error on line 16 of ./conf/test31.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test60.out�������������������������������������������������������0000664�0001751�0001751�00000004140�12076740760�020643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test60.conf
    [core:warn] macro Foo arg 1: hello on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 14 of "./conf/test60.conf"
    [core:warn] macro Foo arg 2: world on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 14 of "./conf/test60.conf"
    [core:warn] Macro Bla arg 1: "hello world" on line 1 of macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf"
    [core:warn] Macro Bla arg 2: "thank you" on line 2 of macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf"
    [core:warn] macro Foo arg 1: hello world on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 3 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
    [core:warn] macro Foo arg 2: second on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 3 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
    [core:warn] macro Foo arg 1: first on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 4 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
    [core:warn] macro Foo arg 2: thank you on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 4 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
    [core:warn] macro Foo arg 1: hello world on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 5 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
    [core:warn] macro Foo arg 2: thank you on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 5 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
    [core:error] done on line 17. on line 17 of ./conf/test60.conf
    AH00526: Syntax error on line 17 of ./conf/test60.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test28.out�������������������������������������������������������0000664�0001751�0001751�00000000514�12076740760�020650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test28.conf
    [core:warn] macro foo on line 1 of macro 'foo' (defined on line 4 of "./conf/test28.conf") used on line 8 of "./conf/test28.conf"
    [core:error] done! on line 10 of ./conf/test28.conf
    AH00526: Syntax error on line 10 of ./conf/test28.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test32.out�������������������������������������������������������0000664�0001751�0001751�00000000346�12076740760�020646� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test32.conf
    httpd: Syntax error on line 3 of ./conf/test32.conf: argument name conflict in macro 'foo' (defined on line 3 of "./conf/test32.conf"): argument '$arg2': #2 and #4, change argument names!
    # exit: 1
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test47.out�������������������������������������������������������0000664�0001751�0001751�00000000715�12076740760�020654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test47.conf
    [macro:warn] macro 'foo' (defined on line 3 of "./conf/test47.conf"): empty contents!
    [macro:warn] macro 'bla' (defined on line 8 of "./conf/test47.conf"): empty contents!
    [macro:warn] macro 'bof' (defined on line 11 of "./conf/test47.conf"): empty contents!
    [core:error] okay. on line 15 of ./conf/test47.conf
    AH00526: Syntax error on line 15 of ./conf/test47.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������������������������httpd-2.4.64/modules/core/test/ref/test08.out�������������������������������������������������������0000664�0001751�0001751�00000000211�12076740760�020640� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test08.conf
    httpd: Syntax error on line 3 of ./conf/test08.conf: </Macro> without matching <Macro> section
    # exit: 1
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test41.out�������������������������������������������������������0000664�0001751�0001751�00000000737�12076740760�020652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test41.conf
    AH00112: Warning: DocumentRoot [/foo/document/root/directory] does not exist
    [core:warn] location /A on line 7 of ./conf/test41.conf
    [core:warn] location /B on line 11 of ./conf/test41.conf
    [core:warn] location /C on line 15 of ./conf/test41.conf
    [core:error] Stop configuration file processing. on line 20 of ./conf/test41.conf
    AH00526: Syntax error on line 20 of ./conf/test41.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ���������������������������������httpd-2.4.64/modules/core/test/ref/test09.out�������������������������������������������������������0000664�0001751�0001751�00000000323�12076740760�020645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test09.conf
    httpd: Syntax error on line 1 of macro 'foo' (defined on line 2 of "./conf/test09.conf") used on line 6 of "./conf/test09.conf": recursive use of macro 'foo' is invalid
    # exit: 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/test/ref/test66.out�������������������������������������������������������0000664�0001751�0001751�00000000736�12076740760�020660� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# testing with conf/test66.conf
    [core:warn] Foo: x=X y=Y on line 1 of macro 'foo' (defined on line 2 of "./conf/test66.conf") used on line 5 of "./conf/test66.conf"
    [core:warn] Foo: x=$y y=$x on line 1 of macro 'foo' (defined on line 2 of "./conf/test66.conf") used on line 6 of "./conf/test66.conf"
    [core:error] done on line 7. on line 7 of ./conf/test66.conf
    AH00526: Syntax error on line 7 of ./conf/test66.conf:
    Configuration processing stopped by Error directive
    # exit: 1
    ����������������������������������httpd-2.4.64/modules/core/config.m4�����������������������������������������������������������������0000664�0001751�0001751�00000003367�12733773575�016765� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl modules enabled in this directory by default
    
    dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
    
    APACHE_MODPATH_INIT(core)
    
    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. 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])
        INSTALL_DSO=yes
    else
        INSTALL_DSO=no
    fi
    APACHE_SUBST(INSTALL_DSO)
    
    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.  This module will be automatically enabled unless you build all modules statically., , , $enable_so)
    
    APACHE_MODULE(watchdog, Watchdog module, , , most, [
        APR_CHECK_APR_DEFINE(APR_HAS_THREADS)
        if test $ac_cv_define_APR_HAS_THREADS = "no"; then
            AC_MSG_WARN([mod_watchdog requires apr to be built with --enable-threads])
            enable_watchdog=no
        fi
    ])
    
    APACHE_MODULE(macro, Define and use macros in configuration files, , , most)
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_watchdog.dep����������������������������������������������������������0000664�0001751�0001751�00000004074�12674411515�020366� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_watchdog.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_watchdog.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_mpm.h"\
    	"..\..\include\ap_provider.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\include\util_mutex.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_watchdog.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_so.c������������������������������������������������������������������0000664�0001751�0001751�00000035404�14001071231�016641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #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;
    }
    
    static const char *dso_load(cmd_parms *cmd, apr_dso_handle_t **modhandlep,
                                const char *filename, const char **used_filename)
    {
        int retry = 0;
        const char *fullname = ap_server_root_relative(cmd->temp_pool, filename);
        char my_error[256];
        if (filename != NULL && ap_strchr_c(filename, '/') == NULL) {
            /* retry on error without path to use dlopen()'s search path */
            retry = 1;
        }
    
        if (fullname == NULL && !retry) {
            return apr_psprintf(cmd->temp_pool, "Invalid %s path %s",
                                cmd->cmd->name, filename);
        }
        *used_filename = fullname;
        if (fullname && apr_dso_load(modhandlep, fullname, cmd->pool) == APR_SUCCESS) {
            return NULL;
        }
        if (retry) {
            *used_filename = filename;
            if (apr_dso_load(modhandlep, filename, cmd->pool) == APR_SUCCESS)
                return NULL;
        }
    
        return apr_pstrcat(cmd->temp_pool, "Cannot load ", filename,
                            " into server: ",
                            apr_dso_error(*modhandlep, my_error, sizeof(my_error)),
                            NULL);
    }
    
    /*
     * 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 *module_file;
        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-existent tree into the build when we return to
         * execute_now.
         */
        *(ap_directive_t **)dummy = 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, APLOGNO(01574)
                              "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
         */
        error = dso_load(cmd, &modhandle, filename, &module_file);
        if (error)
            return error;
        ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, APLOGNO(01575)
                     "loaded module %s from %s", modname, module_file);
    
        /*
         * 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 ", module_file, ": ",
                              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_psprintf(cmd->pool, "API module structure '%s' in file %s "
                                "is garbled - expected signature %08lx but saw "
                                "%08lx - perhaps this is not an Apache module DSO, "
                                "or was compiled for a different Apache version?",
                                modname, module_file,
                                MODULE_MAGIC_COOKIE, modp->magic);
        }
    
        /*
         * Add this module to the Apache core structures
         */
        error = ap_add_loaded_module(modp, cmd->pool, modname);
        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 address 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 *used_file, *error;
    
        error = dso_load(cmd, &handle, filename, &used_file);
        if (error)
            return error;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(01576)
                     "loaded file %s", used_file);
    
        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_stdout(&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, APLOGNO(01577)
                     "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, APLOGNO(01578)
                     "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 }
    };
    
    AP_DECLARE_MODULE(so) = {
       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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_macro.dep�������������������������������������������������������������0000664�0001751�0001751�00000003105�12674411515�017661� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_macro.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_macro.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_watchdog.c������������������������������������������������������������0000664�0001751�0001751�00000066612�14207134173�020042� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /* Watchdog module.
     */
    
    #include "apr.h"
    #include "mod_watchdog.h"
    #include "ap_provider.h"
    #include "ap_mpm.h"
    #include "http_core.h"
    #include "util_mutex.h"
    
    #include "apr_atomic.h"
    
    #define AP_WATCHDOG_PGROUP    "watchdog"
    #define AP_WATCHDOG_PVERSION  "parent"
    #define AP_WATCHDOG_CVERSION  "child"
    
    typedef struct watchdog_list_t watchdog_list_t;
    
    struct watchdog_list_t
    {
        struct watchdog_list_t *next;
        ap_watchdog_t *wd;
        apr_status_t status;
        apr_interval_time_t interval;
        apr_interval_time_t step;
        const void *data;
        ap_watchdog_callback_fn_t *callback_fn;
    };
    
    struct ap_watchdog_t
    {
        apr_uint32_t          thread_started; /* set to 1 once thread running */
        apr_proc_mutex_t     *mutex;
        const char           *name;
        watchdog_list_t      *callbacks;
        int                   is_running;
        int                   singleton;
        int                   active;
        apr_interval_time_t   step;
        apr_thread_t         *thread;
        apr_pool_t           *pool;
    };
    
    typedef struct wd_server_conf_t wd_server_conf_t;
    struct wd_server_conf_t
    {
        int child_workers;
        int parent_workers;
        apr_pool_t *pool;
        server_rec *s;
    };
    
    static wd_server_conf_t *wd_server_conf = NULL;
    static apr_interval_time_t wd_interval = AP_WD_TM_INTERVAL;
    static int mpm_is_forked = AP_MPMQ_NOT_SUPPORTED;
    static const char *wd_proc_mutex_type = "watchdog-callback";
    
    static apr_status_t wd_worker_cleanup(void *data)
    {
        apr_status_t rv;
        ap_watchdog_t *w = (ap_watchdog_t *)data;
    
        /* Do nothing if the thread wasn't started. */
        if (apr_atomic_read32(&w->thread_started) != 1)
            return APR_SUCCESS;
    
        if (w->is_running) {
            watchdog_list_t *wl = w->callbacks;
            while (wl) {
                if (wl->status == APR_SUCCESS) {
                    /* Execute watchdog callback with STOPPING state */
                    (*wl->callback_fn)(AP_WATCHDOG_STATE_STOPPING,
                                        (void *)wl->data, w->pool);
                    wl->status = APR_EOF;
                }
                wl = wl->next;
            }
        }
        w->is_running = 0;
        apr_thread_join(&rv, w->thread);
        return rv;
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* Main watchdog worker thread.                                             */
    /* For singleton workers child thread that first obtains the process       */
    /* mutex is running. Threads in other child's are locked on mutex.          */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    static void* APR_THREAD_FUNC wd_worker(apr_thread_t *thread, void *data)
    {
        ap_watchdog_t *w = (ap_watchdog_t *)data;
        apr_status_t rv;
        int locked = 0;
        int probed = 0;
        int inited = 0;
        int mpmq_s = 0;
        apr_pool_t *temp_pool = NULL;
    
        w->pool = apr_thread_pool_get(thread);
        w->is_running = 1;
    
        apr_atomic_set32(&w->thread_started, 1); /* thread started */
    
        if (w->mutex) {
            while (w->is_running) {
                if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
                    w->is_running = 0;
                    break;
                }
                if (mpmq_s == AP_MPMQ_STOPPING) {
                    w->is_running = 0;
                    break;
                }
                rv = apr_proc_mutex_trylock(w->mutex);
                if (rv == APR_SUCCESS) {
                    if (probed) {
                        /* Sleep after we were locked
                         * up to 1 second. Httpd can be
                         * in the middle of shutdown, and
                         * our child didn't yet received
                         * the shutdown signal.
                         */
                        probed = 10;
                        while (w->is_running && probed > 0) {
                            apr_sleep(AP_WD_TM_INTERVAL);
                            probed--;
                            if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
                                w->is_running = 0;
                                break;
                            }
                            if (mpmq_s == AP_MPMQ_STOPPING) {
                                w->is_running = 0;
                                break;
                            }
                        }
                    }
                    locked = 1;
                    break;
                }
                probed = 1;
                apr_sleep(AP_WD_TM_SLICE);
            }
        }
    
        apr_pool_create(&temp_pool, w->pool);
        apr_pool_tag(temp_pool, "wd_running");
    
        if (w->is_running) {
            watchdog_list_t *wl = w->callbacks;
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wd_server_conf->s,
                         APLOGNO(02972) "%sWatchdog (%s) running",
                         w->singleton ? "Singleton " : "", w->name);
            apr_time_clock_hires(w->pool);
            if (wl) {
                while (wl && w->is_running) {
                    /* Execute watchdog callback */
                    wl->status = (*wl->callback_fn)(AP_WATCHDOG_STATE_STARTING,
                                                    (void *)wl->data, temp_pool);
                    wl = wl->next;
                }
                apr_pool_clear(temp_pool);
            }
            else {
                ap_run_watchdog_init(wd_server_conf->s, w->name, w->pool);
                inited = 1;
            }
        }
    
        /* Main execution loop */
        while (w->is_running) {
            apr_time_t curr;
            watchdog_list_t *wl = w->callbacks;
    
            apr_sleep(AP_WD_TM_SLICE);
            if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
                w->is_running = 0;
            }
            if (mpmq_s == AP_MPMQ_STOPPING) {
                w->is_running = 0;
            }
            if (!w->is_running) {
                break;
            }
            curr = apr_time_now() - AP_WD_TM_SLICE;
            while (wl && w->is_running) {
                if (wl->status == APR_SUCCESS) {
                    wl->step += (apr_time_now() - curr);
                    if (wl->step >= wl->interval) {
                        wl->step = 0;
                        /* Execute watchdog callback */
                        wl->status = (*wl->callback_fn)(AP_WATCHDOG_STATE_RUNNING,
                                                        (void *)wl->data, temp_pool);
                        if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpmq_s) != APR_SUCCESS) {
                            w->is_running = 0;
                        }
                        if (mpmq_s == AP_MPMQ_STOPPING) {
                            w->is_running = 0;
                        }
                    }
                }
                wl = wl->next;
            }
            if (w->is_running && w->callbacks == NULL) {
                /* This is hook mode watchdog
                 * running on WatchogInterval
                 */
                w->step += (apr_time_now() - curr);
                if (w->step >= wd_interval) {
                    w->step = 0;
                    /* Run watchdog step hook */
                    ap_run_watchdog_step(wd_server_conf->s, w->name, temp_pool);
                }
            }
    
            apr_pool_clear(temp_pool);
        }
    
        apr_pool_destroy(temp_pool);
    
        if (inited) {
            /* Run the watchdog exit hooks.
             * If this was singleton watchdog the init hook
             * might never been called, so skip the exit hook
             * in that case as well.
             */
            ap_run_watchdog_exit(wd_server_conf->s, w->name, w->pool);
        }
        else {
            watchdog_list_t *wl = w->callbacks;
            while (wl) {
                if (wl->status == APR_SUCCESS) {
                    /* Execute watchdog callback with STOPPING state */
                    (*wl->callback_fn)(AP_WATCHDOG_STATE_STOPPING,
                                       (void *)wl->data, w->pool);
                }
                wl = wl->next;
            }
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wd_server_conf->s,
                     APLOGNO(02973) "%sWatchdog (%s) stopping",
                     w->singleton ? "Singleton " : "", w->name);
    
        if (locked)
            apr_proc_mutex_unlock(w->mutex);
        apr_thread_exit(w->thread, APR_SUCCESS);
    
        return NULL;
    }
    
    static apr_status_t wd_startup(ap_watchdog_t *w, apr_pool_t *p)
    {
        apr_status_t rc;
    
        apr_atomic_set32(&w->thread_started, 0);
    
        if (w->singleton) {
            /* Initialize singleton mutex in child */
            rc = apr_proc_mutex_child_init(&w->mutex,
                                           apr_proc_mutex_lockfile(w->mutex), p);
            if (rc != APR_SUCCESS)
                return rc;
        }
    
        /* Start the newly created watchdog */
        rc = ap_thread_create(&w->thread, NULL, wd_worker, w, p);
        if (rc == APR_SUCCESS) {
            apr_pool_pre_cleanup_register(p, w, wd_worker_cleanup);
        }
    
        return rc;
    }
    
    static apr_status_t ap_watchdog_get_instance(ap_watchdog_t **watchdog,
                                                 const char *name,
                                                 int parent,
                                                 int singleton,
                                                 apr_pool_t *p)
    {
        ap_watchdog_t *w;
        const char *pver = parent ? AP_WATCHDOG_PVERSION : AP_WATCHDOG_CVERSION;
    
        if (parent && mpm_is_forked != AP_MPMQ_NOT_SUPPORTED) {
            /* Parent threads are not supported for
             * forked mpm's
             */
            *watchdog = NULL;
            return APR_ENOTIMPL;
        }
        w = ap_lookup_provider(AP_WATCHDOG_PGROUP, name, pver);
        if (w) {
            *watchdog = w;
            return APR_SUCCESS;
        }
        w = apr_pcalloc(p, sizeof(ap_watchdog_t));
        w->name      = name;
        w->pool      = p;
        w->singleton = parent ? 0 : singleton;
        *watchdog    = w;
        return ap_register_provider(p, AP_WATCHDOG_PGROUP, name,
                                    pver, *watchdog);
    }
    
    static apr_status_t ap_watchdog_set_callback_interval(ap_watchdog_t *w,
                                                          apr_interval_time_t interval,
                                                          const void *data,
                                                          ap_watchdog_callback_fn_t *callback)
    {
        watchdog_list_t *c = w->callbacks;
        apr_status_t rv = APR_EOF;
    
        while (c) {
            if (c->data == data && c->callback_fn == callback) {
                /* We have existing callback.
                 * Update the interval and reset status, so the
                 * callback and continue execution if stopped earlier.
                 */
                c->interval = interval;
                c->step     = 0;
                c->status   = APR_SUCCESS;
                rv          = APR_SUCCESS;
                break;
            }
            c = c->next;
        }
        return rv;
    }
    
    static apr_status_t ap_watchdog_register_callback(ap_watchdog_t *w,
                                                      apr_interval_time_t interval,
                                                      const void *data,
                                                      ap_watchdog_callback_fn_t *callback)
    {
        watchdog_list_t *c = w->callbacks;
    
        while (c) {
            if (c->data == data && c->callback_fn == callback) {
                /* We have already registered callback.
                 * Do not allow callbacks that have the same
                 * function and data pointers.
                 */
                return APR_EEXIST;
            }
            c = c->next;
        }
        c = apr_palloc(w->pool, sizeof(watchdog_list_t));
        c->data        = data;
        c->callback_fn = callback;
        c->interval    = interval;
        c->step        = 0;
        c->status      = APR_EINIT;
    
        c->wd          = w;
        c->next        = w->callbacks;
        w->callbacks   = c;
        w->active++;
    
        return APR_SUCCESS;
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* Pre config hook.                                                         */
    /* Create default watchdogs for parent and child                            */
    /* Parent watchdog executes inside parent process so it doesn't need the    */
    /* singleton mutex                                                          */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    static int wd_pre_config_hook(apr_pool_t *pconf, apr_pool_t *plog,
                                  apr_pool_t *ptemp)
    {
        apr_status_t rv;
        ap_watchdog_t *w;
    
        ap_mpm_query(AP_MPMQ_IS_FORKED, &mpm_is_forked);
        if ((rv = ap_watchdog_get_instance(&w,
                    AP_WATCHDOG_SINGLETON, 0, 1, pconf)) != APR_SUCCESS) {
            return rv;
        }
        if ((rv = ap_watchdog_get_instance(&w,
                    AP_WATCHDOG_DEFAULT, 0, 0, pconf)) != APR_SUCCESS) {
            return rv;
        }
        if (mpm_is_forked == AP_MPMQ_NOT_SUPPORTED) {
            /* Create parent process watchdog for
             * non forked mpm's only.
             */
            if ((rv = ap_watchdog_get_instance(&w,
                        AP_WATCHDOG_DEFAULT, 1, 0, pconf)) != APR_SUCCESS) {
                return rv;
            }
        }
    
        if ((rv = ap_mutex_register(pconf, wd_proc_mutex_type, NULL,
                                    APR_LOCK_DEFAULT, 0)) != APR_SUCCESS) {
            return rv;
        }
    
        return OK;
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* Post config hook.                                                        */
    /* Create watchdog thread in parent and initializes Watchdog module         */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    static int wd_post_config_hook(apr_pool_t *pconf, apr_pool_t *plog,
                                   apr_pool_t *ptemp, server_rec *s)
    {
        apr_status_t rv;
        const char *pk = "watchdog_init_module_tag";
        apr_pool_t *ppconf = pconf;
        const apr_array_header_t *wl;
    
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
            /* First time config phase -- skip. */
            return OK;
    
        apr_pool_userdata_get((void *)&wd_server_conf, pk, ppconf);
        if (!wd_server_conf) {
            if (!(wd_server_conf = apr_pcalloc(ppconf, sizeof(wd_server_conf_t))))
                return APR_ENOMEM;
            apr_pool_create(&wd_server_conf->pool, ppconf);
            apr_pool_tag(wd_server_conf->pool, "wd_server_conf");
            apr_pool_userdata_set(wd_server_conf, pk, apr_pool_cleanup_null, ppconf);
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(010033)
                     "Watchdog: Running with WatchdogInterval %"
                     APR_TIME_T_FMT "ms", apr_time_as_msec(wd_interval));
        wd_server_conf->s = s;
        if ((wl = ap_list_provider_names(pconf, AP_WATCHDOG_PGROUP,
                                                AP_WATCHDOG_PVERSION))) {
            const ap_list_provider_names_t *wn;
            int i;
    
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02974)
                    "Watchdog: found parent providers.");
    
            wn = (ap_list_provider_names_t *)wl->elts;
            for (i = 0; i < wl->nelts; i++) {
                ap_watchdog_t *w = ap_lookup_provider(AP_WATCHDOG_PGROUP,
                                                      wn[i].provider_name,
                                                      AP_WATCHDOG_PVERSION);
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02975)
                        "Watchdog: Looking for parent (%s).", wn[i].provider_name);
                if (w) {
                    if (!w->active) {
                        int status = ap_run_watchdog_need(s, w->name, 1,
                                                          w->singleton);
                        if (status == OK) {
                            /* One of the modules returned OK to this watchdog.
                             * Mark it as active
                             */
                            w->active = 1;
                        }
                    }
                    if (w->active) {
                        /* We have active watchdog.
                         * Create the watchdog thread
                         */
                        if ((rv = wd_startup(w, wd_server_conf->pool)) != APR_SUCCESS) {
                            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(01571)
                                    "Watchdog: Failed to create parent worker thread.");
                            return rv;
                        }
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(02976)
                                "Watchdog: Created parent worker thread (%s).", w->name);
                        wd_server_conf->parent_workers++;
                    }
                }
            }
        }
        if (wd_server_conf->parent_workers) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01572)
                         "Spawned %d parent worker threads.",
                         wd_server_conf->parent_workers);
        }
        if ((wl = ap_list_provider_names(pconf, AP_WATCHDOG_PGROUP,
                                                AP_WATCHDOG_CVERSION))) {
            const ap_list_provider_names_t *wn;
            int i;
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02977)
                    "Watchdog: found child providers.");
    
            wn = (ap_list_provider_names_t *)wl->elts;
            for (i = 0; i < wl->nelts; i++) {
                ap_watchdog_t *w = ap_lookup_provider(AP_WATCHDOG_PGROUP,
                                                      wn[i].provider_name,
                                                      AP_WATCHDOG_CVERSION);
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02978)
                        "Watchdog: Looking for child (%s).", wn[i].provider_name);
                if (w) {
                    if (!w->active) {
                        int status = ap_run_watchdog_need(s, w->name, 0,
                                                          w->singleton);
                        if (status == OK) {
                            /* One of the modules returned OK to this watchdog.
                             * Mark it as active
                             */
                            w->active = 1;
                        }
                    }
                    if (w->active) {
                        /* We have some callbacks registered.
                         * Create mutexes for singleton watchdogs
                         */
                        if (w->singleton) {
                            rv = ap_proc_mutex_create(&w->mutex, NULL, wd_proc_mutex_type,
                                                      w->name, s,
                                                      wd_server_conf->pool, 0);
                            if (rv != APR_SUCCESS) {
                                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(10095)
                                             "Watchdog: Failed to create singleton mutex.");
                                return rv;
                            }
                            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(02979)
                                    "Watchdog: Created singleton mutex (%s).", w->name);
                        }
                        wd_server_conf->child_workers++;
                    }
                }
            }
        }
        return OK;
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* Child init hook.                                                         */
    /* Create watchdog threads and initializes Mutexes in child                 */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    static void wd_child_init_hook(apr_pool_t *p, server_rec *s)
    {
        apr_status_t rv = OK;
        const apr_array_header_t *wl;
    
        if (!wd_server_conf->child_workers) {
            /* We don't have anything configured, bail out.
             */
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(02980)
                         "Watchdog: nothing configured?");
            return;
        }
        if ((wl = ap_list_provider_names(p, AP_WATCHDOG_PGROUP,
                                            AP_WATCHDOG_CVERSION))) {
            const ap_list_provider_names_t *wn;
            int i;
            wn = (ap_list_provider_names_t *)wl->elts;
            for (i = 0; i < wl->nelts; i++) {
                ap_watchdog_t *w = ap_lookup_provider(AP_WATCHDOG_PGROUP,
                                                      wn[i].provider_name,
                                                      AP_WATCHDOG_CVERSION);
                if (w && w->active) {
                    /* We have some callbacks registered.
                     * Kick of the watchdog
                     */
                    if ((rv = wd_startup(w, wd_server_conf->pool)) != APR_SUCCESS) {
                        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(01573)
                                     "Watchdog: Failed to create child worker thread.");
                        /* No point to continue */
                        return;
                    }
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(02981)
                                 "Watchdog: Created child worker thread (%s).", wn[i].provider_name);
                }
            }
        }
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* WatchdogInterval directive                                               */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    static const char *wd_cmd_watchdog_int(cmd_parms *cmd, void *dummy,
                                           const char *arg)
    {
        apr_status_t rv;
        const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (errs != NULL)
            return errs;
        rv = ap_timeout_parameter_parse(arg, &wd_interval, "s");
    
        if (rv != APR_SUCCESS)
            return "Unparse-able WatchdogInterval setting";
        if (wd_interval < AP_WD_TM_SLICE) {
            return apr_psprintf(cmd->pool, "Invalid WatchdogInterval: minimal value %"
                    APR_TIME_T_FMT "ms", apr_time_as_msec(AP_WD_TM_SLICE));
        }
    
        return NULL;
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* List of directives specific to our module.                               */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    static const command_rec wd_directives[] =
    {
        AP_INIT_TAKE1(
            "WatchdogInterval",                 /* directive name               */
            wd_cmd_watchdog_int,                /* config action routine        */
            NULL,                               /* argument to include in call  */
            RSRC_CONF,                          /* where available              */
            "Watchdog interval in seconds"
        ),
        {NULL}
    };
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* Which functions are responsible for which hooks in the server.           */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    static void wd_register_hooks(apr_pool_t *p)
    {
    
        /* Only the mpm_winnt has child init hook handler.
         * Make sure that we are called after the mpm child init handler
         * initializes.
         */
        static const char *const after_mpm[]      = { "mpm_winnt.c", NULL};
    
        /* Pre config handling
         */
        ap_hook_pre_config(wd_pre_config_hook,
                           NULL,
                           NULL,
                           APR_HOOK_FIRST);
    
        /* Post config handling
         */
        ap_hook_post_config(wd_post_config_hook,
                            NULL,
                            NULL,
                            APR_HOOK_LAST);
    
        /* Child init hook
         */
        ap_hook_child_init(wd_child_init_hook,
                           after_mpm,
                           NULL,
                           APR_HOOK_MIDDLE);
    
        APR_REGISTER_OPTIONAL_FN(ap_watchdog_get_instance);
        APR_REGISTER_OPTIONAL_FN(ap_watchdog_register_callback);
        APR_REGISTER_OPTIONAL_FN(ap_watchdog_set_callback_interval);
    }
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* The list of callback routines and data structures that provide           */
    /* the static hooks into our module from the other parts of the server.     */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    AP_DECLARE_MODULE(watchdog) = {
        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       */
        wd_directives,              /* command apr_table_t                      */
        wd_register_hooks           /* register hooks                           */
    };
    
    /*--------------------------------------------------------------------------*/
    /*                                                                          */
    /* The list of optional hooks that we provide                               */
    /*                                                                          */
    /*--------------------------------------------------------------------------*/
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(watchdog_need)
        APR_HOOK_LINK(watchdog_init)
        APR_HOOK_LINK(watchdog_exit)
        APR_HOOK_LINK(watchdog_step)
    )
    
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, AP_WD, int, watchdog_need,
                                          (server_rec *s, const char *name,
                                           int parent, int singleton),
                                          (s, name, parent, singleton),
                                          DECLINED)
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, AP_WD, int, watchdog_init,
                                        (server_rec *s, const char *name,
                                         apr_pool_t *pool),
                                        (s, name, pool),
                                        OK, DECLINED)
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, AP_WD, int, watchdog_exit,
                                        (server_rec *s, const char *name,
                                         apr_pool_t *pool),
                                        (s, name, pool),
                                        OK, DECLINED)
    APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, AP_WD, int, watchdog_step,
                                        (server_rec *s, const char *name,
                                         apr_pool_t *pool),
                                        (s, name, pool),
                                        OK, DECLINED)
    ����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_watchdog.mak����������������������������������������������������������0000664�0001751�0001751�00000023641�12701473373�020370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_watchdog.dsp
    !IF "$(CFG)" == ""
    CFG=mod_watchdog - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_watchdog - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_watchdog - Win32 Release" && "$(CFG)" != "mod_watchdog - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_watchdog.mak" CFG="mod_watchdog - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_watchdog - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_watchdog - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_watchdog - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_watchdog.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_watchdog.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_watchdog.obj"
    	-@erase "$(INTDIR)\mod_watchdog.res"
    	-@erase "$(INTDIR)\mod_watchdog_src.idb"
    	-@erase "$(INTDIR)\mod_watchdog_src.pdb"
    	-@erase "$(OUTDIR)\mod_watchdog.exp"
    	-@erase "$(OUTDIR)\mod_watchdog.lib"
    	-@erase "$(OUTDIR)\mod_watchdog.pdb"
    	-@erase "$(OUTDIR)\mod_watchdog.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "AP_WD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_watchdog_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_watchdog.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_watchdog.so" /d LONG_NAME="watchdog_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_watchdog.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_watchdog.pdb" /debug /out:"$(OUTDIR)\mod_watchdog.so" /implib:"$(OUTDIR)\mod_watchdog.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_watchdog.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_watchdog.obj" \
    	"$(INTDIR)\mod_watchdog.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_watchdog.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_watchdog.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_watchdog.so"
       if exist .\Release\mod_watchdog.so.manifest mt.exe -manifest .\Release\mod_watchdog.so.manifest -outputresource:.\Release\mod_watchdog.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_watchdog - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_watchdog.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_watchdog.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_watchdog.obj"
    	-@erase "$(INTDIR)\mod_watchdog.res"
    	-@erase "$(INTDIR)\mod_watchdog_src.idb"
    	-@erase "$(INTDIR)\mod_watchdog_src.pdb"
    	-@erase "$(OUTDIR)\mod_watchdog.exp"
    	-@erase "$(OUTDIR)\mod_watchdog.lib"
    	-@erase "$(OUTDIR)\mod_watchdog.pdb"
    	-@erase "$(OUTDIR)\mod_watchdog.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "AP_WD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_watchdog_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_watchdog.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_watchdog.so" /d LONG_NAME="watchdog_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_watchdog.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_watchdog.pdb" /debug /out:"$(OUTDIR)\mod_watchdog.so" /implib:"$(OUTDIR)\mod_watchdog.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_watchdog.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_watchdog.obj" \
    	"$(INTDIR)\mod_watchdog.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_watchdog.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_watchdog.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_watchdog.so"
       if exist .\Debug\mod_watchdog.so.manifest mt.exe -manifest .\Debug\mod_watchdog.so.manifest -outputresource:.\Debug\mod_watchdog.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_watchdog.dep")
    !INCLUDE "mod_watchdog.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_watchdog.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_watchdog - Win32 Release" || "$(CFG)" == "mod_watchdog - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_watchdog - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\core"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ELSEIF  "$(CFG)" == "mod_watchdog - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\core"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_watchdog - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\core"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ELSEIF  "$(CFG)" == "mod_watchdog - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\core"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_watchdog - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\core"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\core"
    
    !ELSEIF  "$(CFG)" == "mod_watchdog - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\core"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\core"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_watchdog - Win32 Release"
    
    
    "$(INTDIR)\mod_watchdog.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_watchdog.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_watchdog.so" /d LONG_NAME="watchdog_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_watchdog - Win32 Debug"
    
    
    "$(INTDIR)\mod_watchdog.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_watchdog.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_watchdog.so" /d LONG_NAME="watchdog_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_watchdog.c
    
    "$(INTDIR)\mod_watchdog.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_macro.c���������������������������������������������������������������0000664�0001751�0001751�00000074041�14513155260�017336� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "apr.h"
    #include "apr_strings.h"
    #include "apr_hash.h"
    
    /************************************************ COMPILE TIME DEBUG CONTROL */
    /*
       debug:
       #define MOD_MACRO_DEBUG 1
    
       gdb:
       run -f ./test/conf/test??.conf
    */
    /* #define MOD_MACRO_DEBUG 1 */
    #undef MOD_MACRO_DEBUG
    
    #if defined(debug)
    #undef debug
    #endif /* debug */
    
    #if defined(MOD_MACRO_DEBUG)
    #define debug(stmt) stmt
    #else
    #define debug(stmt)
    #endif /* MOD_MACRO_DEBUG */
    
    /******************************************************** MODULE DECLARATION */
    
    module AP_MODULE_DECLARE_DATA macro_module;
    
    /********************************************************** MACRO MANAGEMENT */
    
    /*
      this is a macro: name, arguments, contents, location.
    */
    typedef struct
    {
        char *name;                    /* lower case name of the macro */
        apr_array_header_t *arguments; /* of char*, macro parameter names */
        apr_array_header_t *contents;  /* of char*, macro body */
        char *location;                /* of macro definition, for error messages */
    } ap_macro_t;
    
    /* configuration tokens.
     */
    #define BEGIN_MACRO "<Macro"
    #define END_MACRO   "</Macro>"
    #define USE_MACRO   "Use"
    #define UNDEF_MACRO "UndefMacro"
    
    /*
      Macros are kept globally...
      They are not per-server or per-directory entities.
    
      note: they are in a temp_pool, and there is a lazy initialization.
            ap_macros is reset to NULL in pre_config hook to not depend
            on static vs dynamic configuration.
    
      hash type: (char *) name -> (ap_macro_t *) macro
    */
    static apr_hash_t *ap_macros = NULL;
    
    /*************************************************************** PARSE UTILS */
    
    #define empty_string_p(p) (!(p) || *(p) == '\0')
    #define trim(line) while (*(line) == ' ' || *(line) == '\t') (line)++
    
    /*
      return configuration-parsed arguments from line as an array.
      the line is expected not to contain any '\n'?
    */
    static apr_array_header_t *get_arguments(apr_pool_t * pool, const char *line)
    {
        apr_array_header_t *args = apr_array_make(pool, 1, sizeof(char *));
    
        trim(line);
        while (*line) {
            char *arg = ap_getword_conf(pool, &line);
            char **new = apr_array_push(args);
            *new = arg;
            trim(line);
        }
    
        return args;
    }
    
    /*
      warn if anything non blank appears, but ignore comments...
    */
    static void warn_if_non_blank(const char * what,
                                  char * ptr,
                                  ap_configfile_t * cfg)
    {
        char * p;
        for (p=ptr; *p; p++) {
            if (*p == '#')
                break;
            if (*p != ' ' && *p != '\t') {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02989)
                             "%s on line %d of %s: %s",
                             what, cfg->line_number, cfg->name, ptr);
                break;
            }
        }
    }
    
    /*
      get read lines as an array till end_token.
      counts nesting for begin_token/end_token.
      it assumes a line-per-line configuration (thru getline).
      this function could be exported.
      begin_token may be NULL.
    */
    static char *get_lines_till_end_token(apr_pool_t * pool,
                                          ap_configfile_t * config_file,
                                          const char *end_token,
                                          const char *begin_token,
                                          const char *where,
                                          apr_array_header_t ** plines)
    {
        apr_array_header_t *lines = apr_array_make(pool, 1, sizeof(char *));
        char line[MAX_STRING_LEN];  /* sorry, but this is expected by getline:-( */
        int macro_nesting = 1, any_nesting = 1;
        int line_number_start = config_file->line_number;
    
        while (!ap_cfg_getline(line, MAX_STRING_LEN, config_file)) {
            char *ptr = line;
            char *first, **new;
            /* skip comments */
            if (*line == '#')
                continue;
            first = ap_getword_conf_nc(pool, &ptr);
            if (first) {
                /* detect nesting... */
                if (!strncmp(first, "</", 2)) {
                    any_nesting--;
                    if (any_nesting < 0) {
                        ap_log_error(APLOG_MARK, APLOG_WARNING,
                                     0, NULL, APLOGNO(02793)
                                     "bad (negative) nesting on line %d of %s",
                                     config_file->line_number - line_number_start,
                                     where);
                    }
                }
                else if (!strncmp(first, "<", 1)) {
                    any_nesting++;
                }
    
                if (!strcasecmp(first, end_token)) {
                    /* check for proper closing */
                    char * endp = (char *) ap_strrchr_c(line, '>');
    
                    /* this cannot happen if end_token contains '>' */
                    if (endp == NULL) {
                      return "end directive missing closing '>'";
                    }
    
                    warn_if_non_blank(
                        APLOGNO(02794) "non blank chars found after directive closing",
                        endp+1, config_file);
    
                    macro_nesting--;
                    if (!macro_nesting) {
                        if (any_nesting) {
                            ap_log_error(APLOG_MARK,
                                         APLOG_WARNING, 0, NULL, APLOGNO(02795)
                                         "bad cumulated nesting (%+d) in %s",
                                         any_nesting, where);
                        }
                        *plines = lines;
                        return NULL;
                    }
                }
                else if (begin_token && !strcasecmp(first, begin_token)) {
                    macro_nesting++;
                }
            }
            new = apr_array_push(lines);
            *new = apr_psprintf(pool, "%s" APR_EOL_STR, line); /* put EOL back? */
        }
    
        return apr_psprintf(pool, "expected token not found: %s", end_token);
    }
    
    /* the @* arguments are double-quote escaped when substituted */
    #define ESCAPE_ARG '@'
    
    /* other $* and %* arguments are simply replaced without escaping */
    #define ARG_PREFIX "$%@"
    
    /*
      characters allowed in an argument?
      not used yet, because that would trigger some backward compatibility.
    */
    #define ARG_CONTENT              \
        "abcdefghijklmnopqrstuvwxyz"   \
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"   \
        "0123456789_" ARG_PREFIX
    
    /*
      returns whether it looks like an argument, i.e. prefixed by ARG_PREFIX.
    */
    static int looks_like_an_argument(const char *word)
    {
        return ap_strchr(ARG_PREFIX, *word) != 0;
    }
    
    /*
      generates an error on macro with two arguments of the same name.
      generates an error if a macro argument name is empty.
      generates a warning if arguments name prefixes conflict.
      generates a warning if the first char of an argument is not in ARG_PREFIX
    */
    static const char *check_macro_arguments(apr_pool_t * pool,
                                             const ap_macro_t * macro)
    {
        char **tab = (char **) macro->arguments->elts;
        int nelts = macro->arguments->nelts;
        int i;
    
        for (i = 0; i < nelts; i++) {
            size_t ltabi = strlen(tab[i]);
            int j;
    
            if (ltabi == 0) {
                return apr_psprintf(pool,
                                    "macro '%s' (%s): empty argument #%d name",
                                    macro->name, macro->location, i + 1);
            }
            else if (!looks_like_an_argument(tab[i])) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02796)
                             "macro '%s' (%s) "
                             "argument name '%s' (#%d) without expected prefix, "
                             "better prefix argument names with one of '%s'.",
                             macro->name, macro->location,
                             tab[i], i + 1, ARG_PREFIX);
            }
    
            for (j = i + 1; j < nelts; j++) {
                size_t ltabj = strlen(tab[j]);
    
                /* must not use the same argument name twice */
                if (!strcmp(tab[i], tab[j])) {
                    return apr_psprintf(pool,
                                        "argument name conflict in macro '%s' (%s): "
                                        "argument '%s': #%d and #%d, "
                                        "change argument names!",
                                        macro->name, macro->location,
                                        tab[i], i + 1, j + 1);
                }
    
                /* warn about common prefix, but only if non empty names */
                if (ltabi && ltabj &&
                    !strncmp(tab[i], tab[j], ltabi < ltabj ? ltabi : ltabj)) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING,
                                 0, NULL, APLOGNO(02797)
                                 "macro '%s' (%s): "
                                 "argument name prefix conflict (%s #%d and %s #%d), "
                                 "be careful about your macro definition!",
                                 macro->name, macro->location,
                                 tab[i], i + 1, tab[j], j + 1);
                }
            }
        }
    
        return NULL;
    }
    
    /*
      warn about empty strings in array. could be legitimate.
    */
    static void check_macro_use_arguments(const char *where,
                                          const apr_array_header_t * array)
    {
        char **tab = (char **) array->elts;
        int i;
        for (i = 0; i < array->nelts; i++) {
            if (empty_string_p(tab[i])) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02798)
                             "%s: empty argument #%d", where, i + 1);
            }
        }
    }
    
    /******************************************************** SUBSTITUTION UTILS */
    
    /* could be switched to '\'' */
    #define DELIM '"'
    #define ESCAPE '\\'
    
    /*
      returns the number of needed escapes for the string
    */
    static int number_of_escapes(const char delim, const char *str)
    {
        int nesc = 0;
        const char *s = str;
        while (*s) {
            if (*s == ESCAPE || *s == delim)
                nesc++;
            s++;
        }
        debug(fprintf(stderr, "escapes: %d ---%s---\n", nesc, str));
        return nesc;
    }
    
    /*
      replace name by replacement at the beginning of buf of bufsize.
      returns an error message or NULL.
      C is not really a nice language for processing strings.
    */
    static char *substitute(char *buf,
                            const int bufsize,
                            const char *name,
                            const char *replacement, const int do_esc)
    {
        int lbuf = strlen(buf),
            lname = strlen(name),
            lrepl = strlen(replacement),
            lsubs = lrepl +
            (do_esc ? (2 + number_of_escapes(DELIM, replacement)) : 0),
            shift = lsubs - lname, size = lbuf + shift, i, j;
    
        /* buf must starts with name */
        ap_assert(!strncmp(buf, name, lname));
    
        /* hmmm??? */
        if (!strcmp(name, replacement))
            return NULL;
    
        debug(fprintf(stderr,
                      "substitute(%s,%s,%s,%d,sh=%d,lbuf=%d,lrepl=%d,lsubs=%d)\n",
                      buf, name, replacement, do_esc, shift, lbuf, lrepl, lsubs));
    
        if (size >= bufsize) {
            /* could/should I reallocate? */
            return "cannot substitute, buffer size too small";
        }
    
        /* cannot use strcpy as strings may overlap */
        if (shift != 0) {
            memmove(buf + lname + shift, buf + lname, lbuf - lname + 1);
        }
    
        /* insert the replacement with escapes */
        j = 0;
        if (do_esc)
            buf[j++] = DELIM;
        for (i = 0; i < lrepl; i++, j++) {
            if (do_esc && (replacement[i] == DELIM || replacement[i] == ESCAPE))
                buf[j++] = ESCAPE;
            buf[j] = replacement[i];
        }
        if (do_esc)
            buf[j++] = DELIM;
    
        return NULL;
    }
    
    /*
      find first occurrence of args in buf.
      in case of conflict, the LONGEST argument is kept. (could be the FIRST?).
      returns the pointer and the whichone found, or NULL.
    */
    static char *next_substitution(const char *buf,
                                   const apr_array_header_t * args, int *whichone)
    {
        char *chosen = NULL, **tab = (char **) args->elts;
        size_t lchosen = 0;
        int i;
    
        for (i = 0; i < args->nelts; i++) {
            char *found = ap_strstr((char *) buf, tab[i]);
            size_t lfound = strlen(tab[i]);
            if (found && (!chosen || found < chosen ||
                          (found == chosen && lchosen < lfound))) {
                chosen = found;
                lchosen = lfound;
                *whichone = i;
            }
        }
    
        return chosen;
    }
    
    /*
      substitute macro arguments by replacements in buf of bufsize.
      returns an error message or NULL.
      if used is defined, returns the used macro arguments.
    */
    static const char *substitute_macro_args(
        char *buf,
        int bufsize,
        const ap_macro_t * macro,
        const apr_array_header_t * replacements,
        apr_array_header_t * used)
    {
        char *ptr = buf,
            **atab = (char **) macro->arguments->elts,
            **rtab = (char **) replacements->elts;
        int whichone = -1;
    
        if (used) {
            ap_assert(used->nalloc >= replacements->nelts);
        }
        debug(fprintf(stderr, "1# %s", buf));
    
        while ((ptr = next_substitution(ptr, macro->arguments, &whichone))) {
            const char *errmsg = substitute(ptr, buf - ptr + bufsize,
                                            atab[whichone], rtab[whichone],
                                            atab[whichone][0] == ESCAPE_ARG);
            if (errmsg) {
                return errmsg;
            }
            ptr += strlen(rtab[whichone]);
            if (used) {
                used->elts[whichone] = 1;
            }
        }
        debug(fprintf(stderr, "2# %s", buf));
    
        return NULL;
    }
    
    /*
      perform substitutions in a macro contents and
      return the result as a newly allocated array, if result is defined.
      may also return an error message.
      passes used down to substitute_macro_args.
    */
    static const char *process_content(apr_pool_t * pool,
                                       const ap_macro_t * macro,
                                       const apr_array_header_t * replacements,
                                       apr_array_header_t * used,
                                       apr_array_header_t ** result)
    {
        apr_array_header_t *contents = macro->contents;
        char line[MAX_STRING_LEN];
        int i;
    
        if (result) {
            *result = apr_array_make(pool, contents->nelts, sizeof(char *));
        }
    
        /* for each line of the macro body */
        for (i = 0; i < contents->nelts; i++) {
            const char *errmsg;
            /* copy the line and substitute macro parameters */
            apr_cpystrn(line, ((char **) contents->elts)[i], MAX_STRING_LEN);
            errmsg = substitute_macro_args(line, MAX_STRING_LEN,
                                           macro, replacements, used);
            if (errmsg) {
                return apr_psprintf(pool,
                                   "while processing line %d of macro '%s' (%s) %s",
                                    i + 1, macro->name, macro->location, errmsg);
            }
            /* append substituted line to result array */
            if (result) {
                char **new = apr_array_push(*result);
                *new = apr_pstrdup(pool, line);
            }
        }
    
        return NULL;
    }
    
    /*
      warn if some macro arguments are not used.
    */
    static const char *check_macro_contents(apr_pool_t * pool,
                                            const ap_macro_t * macro)
    {
        int nelts = macro->arguments->nelts;
        char **names = (char **) macro->arguments->elts;
        apr_array_header_t *used;
        int i;
        const char *errmsg;
    
        if (macro->contents->nelts == 0) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02799)
                         "macro '%s' (%s): empty contents!",
                         macro->name, macro->location);
            return NULL;            /* no need to further warnings... */
        }
    
        used = apr_array_make(pool, nelts, sizeof(char));
    
        for (i = 0; i < nelts; i++) {
            used->elts[i] = 0;
        }
    
        errmsg = process_content(pool, macro, macro->arguments, used, NULL);
    
        if (errmsg) {
            return errmsg;
        }
    
        for (i = 0; i < nelts; i++) {
            if (!used->elts[i]) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02800)
                             "macro '%s' (%s): argument '%s' (#%d) never used",
                             macro->name, macro->location, names[i], i + 1);
            }
        }
    
        return NULL;
    }
    
    
    /************************************************** MACRO PSEUDO CONFIG FILE */
    
    /*
      The expanded content of the macro is to be parsed as a ap_configfile_t.
      This is used to have some kind of old fashionned C object oriented inherited
      data structure for configs.
    
      The following struct stores the contents.
    
      This structure holds pointers (next, upper) to the current "file" which was
      being processed and is interrupted by the macro expansion. At the end
      of processing the macro, the initial data structure will be put back
      in place (see function next_one) and the reading will go on from there.
    
      If macros are used within macros, there may be a cascade of such temporary
      arrays used to insert the expanded macro contents before resuming the real
      file processing.
    
      There is some hopus-pocus to deal with line_number when transiting from
      one config to the other.
    */
    typedef struct
    {
        int index;                    /* current element */
        int char_index;               /* current char in element */
        int length;                   /* cached length of the current line */
        apr_array_header_t *contents; /* array of char * */
        ap_configfile_t *next;        /* next config once this one is processed */
        ap_configfile_t **upper;      /* hack: where to update it if needed */
    } array_contents_t;
    
    /*
      Get next config if any.
      this may be called several times if there are continuations.
    */
    static int next_one(array_contents_t * ml)
    {
        if (ml->next) {
            ap_assert(ml->upper);
            *(ml->upper) = ml->next;
            return 1;
        }
        return 0;
    }
    
    /*
      returns next char if possible
      this may involve switching to enclosing config.
    */
    static apr_status_t array_getch(char *ch, void *param)
    {
        array_contents_t *ml = (array_contents_t *) param;
        char **tab = (char **) ml->contents->elts;
    
        while (ml->char_index >= ml->length) {
            if (ml->index >= ml->contents->nelts) {
                /* maybe update */
                if (ml->next && ml->next->getch && next_one(ml)) {
                    apr_status_t rc = ml->next->getch(ch, ml->next->param);
                    if (*ch==LF)
                        ml->next->line_number++;
                    return rc;
                }
                return APR_EOF;
            }
            ml->index++;
            ml->char_index = 0;
            ml->length = ml->index >= ml->contents->nelts ?
                0 : strlen(tab[ml->index]);
        }
    
        *ch = tab[ml->index][ml->char_index++];
        return APR_SUCCESS;
    }
    
    /*
      returns a buf a la fgets.
      no more than a line at a time, otherwise the parsing is too much ahead...
      NULL at EOF.
    */
    static apr_status_t array_getstr(void *buf, size_t bufsize, void *param)
    {
        array_contents_t *ml = (array_contents_t *) param;
        char *buffer = (char *) buf;
        char next = '\0';
        size_t i = 0;
        apr_status_t rc = APR_SUCCESS;
    
        /* read chars from stream, stop on newline */
        while (i < bufsize - 1 && next != LF &&
               ((rc = array_getch(&next, param)) == APR_SUCCESS)) {
            buffer[i++] = next;
        }
    
        if (rc == APR_EOF) {
            /* maybe update to next, possibly a recursion */
            if (next_one(ml)) {
                ap_assert(ml->next->getstr);
                /* keep next line count in sync! the caller will update
                   the current line_number, we need to forward to the next */
                ml->next->line_number++;
                return ml->next->getstr(buf, bufsize, ml->next->param);
            }
            /* else that is really all we can do */
            return APR_EOF;
        }
    
        buffer[i] = '\0';
    
        return APR_SUCCESS;
    }
    
    /*
      close the array stream?
    */
    static apr_status_t array_close(void *param)
    {
        array_contents_t *ml = (array_contents_t *) param;
        /* move index at end of stream... */
        ml->index = ml->contents->nelts;
        ml->char_index = ml->length;
        return APR_SUCCESS;
    }
    
    /*
      create an array config stream insertion "object".
      could be exported.
    */
    static ap_configfile_t *make_array_config(apr_pool_t * pool,
                                              apr_array_header_t * contents,
                                              const char *where,
                                              ap_configfile_t * cfg,
                                              ap_configfile_t ** upper)
    {
        array_contents_t *ls =
            (array_contents_t *) apr_palloc(pool, sizeof(array_contents_t));
        ap_assert(ls!=NULL);
    
        ls->index = 0;
        ls->char_index = 0;
        ls->contents = contents;
        ls->length = ls->contents->nelts < 1 ?
            0 : strlen(((char **) ls->contents->elts)[0]);
        ls->next = cfg;
        ls->upper = upper;
    
        return ap_pcfg_open_custom(pool, where, (void *) ls,
                                   array_getch, array_getstr, array_close);
    }
    
    
    /********************************************************** KEYWORD HANDLING */
    
    /*
      handles: <Macro macroname arg1 arg2 ...> any trash there is ignored...
    */
    static const char *macro_section(cmd_parms * cmd,
                                     void *dummy, const char *arg)
    {
        apr_pool_t *pool;
        char *endp, *name, *where;
        const char *errmsg;
        ap_macro_t *macro;
    
        debug(fprintf(stderr, "macro_section: arg='%s'\n", arg));
    
        /* lazy initialization */
        if (ap_macros == NULL) {
            pool = cmd->pool;
            ap_macros = apr_hash_make(pool);
            ap_assert(ap_macros != NULL);
            apr_pool_cleanup_register(pool, &ap_macros,
                                      ap_pool_cleanup_set_null,
                                      apr_pool_cleanup_null);
        }
        else {
            pool = apr_hash_pool_get(ap_macros);
        }
    
        endp = (char *) ap_strrchr_c(arg, '>');
    
        if (endp == NULL) {
            return BEGIN_MACRO "> directive missing closing '>'";
        }
    
        if (endp == arg) {
            return BEGIN_MACRO " macro definition: empty name";
        }
    
        warn_if_non_blank(APLOGNO(02801) "non blank chars found after "
                          BEGIN_MACRO " closing '>'",
                          endp+1, cmd->config_file);
    
        /* coldly drop '>[^>]*$' out */
        *endp = '\0';
    
        /* get lowercase macro name */
        name = ap_getword_conf(pool, &arg);
        if (empty_string_p(name)) {
            return BEGIN_MACRO " macro definition: name not found";
        }
    
        ap_str_tolower(name);
        macro = apr_hash_get(ap_macros, name, APR_HASH_KEY_STRING);
    
        if (macro != NULL) {
            /* already defined: warn about the redefinition */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02802)
                         "macro '%s' multiply defined: "
                         "%s, redefined on line %d of \"%s\"",
                         macro->name, macro->location,
                         cmd->config_file->line_number, cmd->config_file->name);
        }
        else {
            /* allocate a new macro */
            macro = (ap_macro_t *) apr_palloc(pool, sizeof(ap_macro_t));
            macro->name = name;
        }
    
        debug(fprintf(stderr, "macro_section: name=%s\n", name));
    
        /* get macro arguments */
        macro->location = apr_psprintf(pool,
                                       "defined on line %d of \"%s\"",
                                       cmd->config_file->line_number,
                                       cmd->config_file->name);
        debug(fprintf(stderr, "macro_section: location=%s\n", macro->location));
    
        where =
            apr_psprintf(pool, "macro '%s' (%s)", macro->name, macro->location);
    
        if (looks_like_an_argument(name)) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02803)
                         "%s better prefix a macro name with any of '%s'",
                         where, ARG_PREFIX);
        }
    
        /* get macro parameters */
        macro->arguments = get_arguments(pool, arg);
    
        errmsg = check_macro_arguments(cmd->temp_pool, macro);
    
        if (errmsg) {
            return errmsg;
        }
    
        errmsg = get_lines_till_end_token(pool, cmd->config_file,
                                          END_MACRO, BEGIN_MACRO,
                                          where, &macro->contents);
    
        if (errmsg) {
            return apr_psprintf(cmd->temp_pool,
                                "%s" APR_EOL_STR "\tcontents error: %s",
                                where, errmsg);
        }
    
        errmsg = check_macro_contents(cmd->temp_pool, macro);
    
        if (errmsg) {
            return apr_psprintf(cmd->temp_pool,
                                "%s" APR_EOL_STR "\tcontents checking error: %s",
                                where, errmsg);
        }
    
        /* store the new macro */
        apr_hash_set(ap_macros, name, APR_HASH_KEY_STRING, macro);
    
        return NULL;
    }
    
    /*
      handles: Use name value1 value2 ...
    */
    static const char *use_macro(cmd_parms * cmd, void *dummy, const char *arg)
    {
        char *name, *recursion, *where;
        const char *errmsg;
        ap_macro_t *macro;
        apr_array_header_t *replacements;
        apr_array_header_t *contents;
    
        debug(fprintf(stderr, "use_macro -%s-\n", arg));
    
        /* must be initialized, or no macros has been defined */
        if (ap_macros == NULL) {
            return "no macro defined before " USE_MACRO;
        }
    
        /* get lowercase macro name */
        name = ap_getword_conf(cmd->temp_pool, &arg);
        ap_str_tolower(name);
    
        if (empty_string_p(name)) {
            return "no macro name specified with " USE_MACRO;
        }
    
        /* get macro definition */
        macro = apr_hash_get(ap_macros, name, APR_HASH_KEY_STRING);
    
        if (!macro) {
            return apr_psprintf(cmd->temp_pool, "macro '%s' undefined", name);
        }
    
        /* recursion is detected here by looking at the config file name,
         * which may already contains "macro 'foo'". Ok, it looks like a hack,
         * but otherwise it is uneasy to keep this data available somewhere...
         * the name has just the needed visibility and liveness.
         */
        recursion =
            apr_pstrcat(cmd->temp_pool, "macro '", macro->name, "'", NULL);
    
        if (ap_strstr((char *) cmd->config_file->name, recursion)) {
            return apr_psprintf(cmd->temp_pool,
                                "recursive use of macro '%s' is invalid",
                                macro->name);
        }
    
        /* get macro arguments */
        replacements = get_arguments(cmd->temp_pool, arg);
    
        if (macro->arguments->nelts != replacements->nelts) {
            return apr_psprintf(cmd->temp_pool,
                                "macro '%s' (%s) used "
                                "with %d arguments instead of %d",
                                macro->name, macro->location,
                                replacements->nelts, macro->arguments->nelts);
        }
    
        where = apr_psprintf(cmd->temp_pool,
                             "macro '%s' (%s) used on line %d of \"%s\"",
                             macro->name, macro->location,
                             cmd->config_file->line_number,
                             cmd->config_file->name);
    
        check_macro_use_arguments(where, replacements);
    
        errmsg = process_content(cmd->temp_pool, macro, replacements,
                                 NULL, &contents);
    
        if (errmsg) {
            return apr_psprintf(cmd->temp_pool,
                                "%s error while substituting: %s",
                                where, errmsg);
        }
    
        /* the current "config file" is replaced by a string array...
           at the end of processing the array, the initial config file
           will be returned there (see next_one) so as to go on. */
        cmd->config_file = make_array_config(cmd->temp_pool, contents, where,
                                             cmd->config_file, &cmd->config_file);
    
        return NULL;
    }
    
    static const char *undef_macro(cmd_parms * cmd, void *dummy, const char *arg)
    {
        char *name;
        ap_macro_t *macro;
    
        /* must be initialized, or no macros has been defined */
        if (ap_macros == NULL) {
            return "no macro defined before " UNDEF_MACRO;
        }
    
        if (empty_string_p(arg)) {
            return "no macro name specified with " UNDEF_MACRO;
        }
    
        /* check that the macro is defined */
        name = apr_pstrdup(cmd->temp_pool, arg);
        ap_str_tolower(name);
        macro = apr_hash_get(ap_macros, name, APR_HASH_KEY_STRING);
        if (macro == NULL) {
            /* could be a warning? */
            return apr_psprintf(cmd->temp_pool,
                                "cannot remove undefined macro '%s'", name);
        }
    
        /* free macro: cannot do that */
        /* remove macro from hash table */
        apr_hash_set(ap_macros, name, APR_HASH_KEY_STRING, NULL);
    
        return NULL;
    }
    
    /************************************************************* EXPORT MODULE */
    
    /*
      macro module commands.
      configuration file macro stuff
      they are processed immediately when found, hence the EXEC_ON_READ.
    */
    static const command_rec macro_cmds[] = {
        AP_INIT_RAW_ARGS(BEGIN_MACRO, macro_section, NULL, EXEC_ON_READ | OR_ALL,
                         "Beginning of a macro definition section."),
        AP_INIT_RAW_ARGS(USE_MACRO, use_macro, NULL, EXEC_ON_READ | OR_ALL,
                         "Use of a macro."),
        AP_INIT_TAKE1(UNDEF_MACRO, undef_macro, NULL, EXEC_ON_READ | OR_ALL,
                      "Remove a macro definition."),
    
        {NULL}
    };
    
    /*
      Module hooks are request-oriented thus it does not suit configuration
      file utils a lot. I haven't found any clean hook to apply something
      before then after configuration file processing. Also what about
      .htaccess files?
    
      Thus I think that server/util.c or server/config.c
      would be a better place for this stuff.
    */
    
    AP_DECLARE_MODULE(macro) = {
        STANDARD20_MODULE_STUFF,    /* common stuff */
            NULL,                   /* create per-directory config */
            NULL,                   /* merge per-directory config structures */
            NULL,                   /* create per-server config structure */
            NULL,                   /* merge per-server config structures */
            macro_cmds,             /* configuration commands */
            NULL                    /* register hooks */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_macro.mak�������������������������������������������������������������0000664�0001751�0001751�00000023075�12701473373�017672� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_macro.dsp
    !IF "$(CFG)" == ""
    CFG=mod_macro - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_macro - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_macro - Win32 Release" && "$(CFG)" != "mod_macro - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_macro.mak" CFG="mod_macro - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_macro - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_macro - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_macro - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_macro.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_macro.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\mod_macro.obj"
    	-@erase "$(INTDIR)\mod_macro_src.idb"
    	-@erase "$(INTDIR)\mod_macro_src.pdb"
    	-@erase "$(OUTDIR)\mod_macro.exp"
    	-@erase "$(OUTDIR)\mod_macro.lib"
    	-@erase "$(OUTDIR)\mod_macro.pdb"
    	-@erase "$(OUTDIR)\mod_macro.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_macro_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_macro.so" /d LONG_NAME="macro_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_macro.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_macro.pdb" /debug /out:"$(OUTDIR)\mod_macro.so" /implib:"$(OUTDIR)\mod_macro.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_macro.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_macro.obj" \
    	"$(INTDIR)\httpd.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_macro.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_macro.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_macro.so"
       if exist .\Release\mod_macro.so.manifest mt.exe -manifest .\Release\mod_macro.so.manifest -outputresource:.\Release\mod_macro.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_macro - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_macro.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_macro.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\mod_macro.obj"
    	-@erase "$(INTDIR)\mod_macro_src.idb"
    	-@erase "$(INTDIR)\mod_macro_src.pdb"
    	-@erase "$(OUTDIR)\mod_macro.exp"
    	-@erase "$(OUTDIR)\mod_macro.lib"
    	-@erase "$(OUTDIR)\mod_macro.pdb"
    	-@erase "$(OUTDIR)\mod_macro.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_macro_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_macro.so" /d LONG_NAME="macro_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_macro.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_macro.pdb" /debug /out:"$(OUTDIR)\mod_macro.so" /implib:"$(OUTDIR)\mod_macro.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_macro.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_macro.obj" \
    	"$(INTDIR)\httpd.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_macro.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_macro.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_macro.so"
       if exist .\Debug\mod_macro.so.manifest mt.exe -manifest .\Debug\mod_macro.so.manifest -outputresource:.\Debug\mod_macro.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_macro.dep")
    !INCLUDE "mod_macro.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_macro.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_macro - Win32 Release" || "$(CFG)" == "mod_macro - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_macro - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\core"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ELSEIF  "$(CFG)" == "mod_macro - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\core"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_macro - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\core"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ELSEIF  "$(CFG)" == "mod_macro - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\core"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\core"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_macro - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\core"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\core"
    
    !ELSEIF  "$(CFG)" == "mod_macro - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\core"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\core"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_macro - Win32 Release"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_macro.so" /d LONG_NAME="macro_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_macro - Win32 Debug"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_macro.so" /d LONG_NAME="macro_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_macro.c
    
    "$(INTDIR)\mod_macro.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_macro.dsp�������������������������������������������������������������0000664�0001751�0001751�00000010441�12553146475�017706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_macro" - 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_macro - 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_macro.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_macro.mak" CFG="mod_macro - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_macro - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_macro - 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_macro - 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_macro_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" /i "../../include" /i "../../srclib/apr/include" /d BIN_NAME="mod_macro.so" /d LONG_NAME="macro_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_macro.so" /base:@..\..\os\win32\BaseAddr.ref,mod_macro.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_macro.so" /base:@..\..\os\win32\BaseAddr.ref,mod_macro.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_macro.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_macro - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_macro_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" /i "../../include" /i "../../srclib/apr/include" /d BIN_NAME="mod_macro.so" /d LONG_NAME="macro_module for Apache"
    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 /out:".\Debug\mod_macro.so" /base:@..\..\os\win32\BaseAddr.ref,mod_macro.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_macro.so" /base:@..\..\os\win32\BaseAddr.ref,mod_macro.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_macro.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_macro - Win32 Release"
    # Name "mod_macro - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_macro.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/NWGNUmakefile�������������������������������������������������������������0000664�0001751�0001751�00000010306�12120077420�017534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(SRC)/include \
    			$(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	= macro
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Macro 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	=
    
    #
    # 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)/macro.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_macro.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	macro_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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_watchdog.h������������������������������������������������������������0000664�0001751�0001751�00000016536�12402343161�020041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_WATCHDOG_H
    #define MOD_WATCHDOG_H
    
    /**
     * @file  mod_watchdog.h
     * @brief Watchdog module for Apache
     *
     * @defgroup MOD_WATCHDOG mod_watchdog
     * @ingroup  APACHE_MODS
     * @{
     */
    
    #include "httpd.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "ap_provider.h"
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_pools.h"
    #include "apr_shm.h"
    #include "apr_hash.h"
    #include "apr_hooks.h"
    #include "apr_optional.h"
    #include "apr_file_io.h"
    #include "apr_time.h"
    #include "apr_thread_proc.h"
    #include "apr_global_mutex.h"
    #include "apr_thread_mutex.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /**
     * Default singleton watchdog instance name.
     * Singleton watchdog is protected by mutex and
     * guaranteed to be run inside a single child process
     * at any time.
     */
    #define AP_WATCHDOG_SINGLETON       "_singleton_"
    
    /**
     * Default watchdog instance name
     */
    #define AP_WATCHDOG_DEFAULT         "_default_"
    
    /**
     * Default Watchdog interval
     */
    #define AP_WD_TM_INTERVAL           APR_TIME_C(1000000)  /* 1 second     */
    
    /**
     * Watchdog thread timer resolution
     */
    #define AP_WD_TM_SLICE              APR_TIME_C(100000)   /* 100 ms       */
    
    /* State values for callback */
    #define AP_WATCHDOG_STATE_STARTING  1
    #define AP_WATCHDOG_STATE_RUNNING   2
    #define AP_WATCHDOG_STATE_STOPPING  3
    
    typedef struct ap_watchdog_t ap_watchdog_t;
    
    /* Create a set of AP_WD_DECLARE(type), AP_WD_DECLARE_NONSTD(type) and
     * AP_WD_DECLARE_DATA with appropriate export and import tags for the platform
     */
    #if !defined(AP_WD_DECLARE)
    #if !defined(WIN32)
    #define AP_WD_DECLARE(type)            type
    #define AP_WD_DECLARE_NONSTD(type)     type
    #define AP_WD_DECLARE_DATA
    #elif defined(AP_WD_DECLARE_STATIC)
    #define AP_WD_DECLARE(type)            type __stdcall
    #define AP_WD_DECLARE_NONSTD(type)     type
    #define AP_WD_DECLARE_DATA
    #elif defined(AP_WD_DECLARE_EXPORT)
    #define AP_WD_DECLARE(type)            __declspec(dllexport) type __stdcall
    #define AP_WD_DECLARE_NONSTD(type)     __declspec(dllexport) type
    #define AP_WD_DECLARE_DATA             __declspec(dllexport)
    #else
    #define AP_WD_DECLARE(type)            __declspec(dllimport) type __stdcall
    #define AP_WD_DECLARE_NONSTD(type)     __declspec(dllimport) type
    #define AP_WD_DECLARE_DATA             __declspec(dllimport)
    #endif
    #endif
    
    /**
     * Callback function used for watchdog.
     * @param state Watchdog state function. See @p AP_WATCHDOG_STATE_ .
     * @param data is what was passed to @p ap_watchdog_register_callback function.
     * @param pool Temporary callback pool destroyed after the call.
     * @return APR_SUCCESS to continue calling this callback.
     */
    typedef apr_status_t ap_watchdog_callback_fn_t(int state, void *data,
                                                   apr_pool_t *pool);
    
    /**
     * Get watchdog instance.
     * @param watchdog Storage for watchdog instance.
     * @param name Watchdog name.
     * @param parent Non-zero to get the parent process watchdog instance.
     * @param singleton Non-zero to get the singleton watchdog instance.
     * @param p The pool to use.
     * @return APR_SUCCESS if all went well
     * @remark Use @p AP_WATCHDOG_DEFAULT to get default watchdog instance.
     *         If separate watchdog thread is needed provide unique name
     *         and function will create a new watchdog instance.
     *         Note that default client process watchdog works in singleton mode.
     */
    APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_watchdog_get_instance,
                            (ap_watchdog_t **watchdog, const char *name, int parent,
                             int singleton, apr_pool_t *p));
    
    /**
     * Register watchdog callback.
     * @param watchdog Watchdog to use
     * @param interval Interval on which the callback function will execute.
     * @param callback  The function to call on watchdog event.
     * @param data The data to pass to the callback function.
     * @return APR_SUCCESS if all went well. APR_EEXIST if already registered.
     */
    APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_watchdog_register_callback,
                            (ap_watchdog_t *watchdog, apr_interval_time_t interval,
                             const void *data, ap_watchdog_callback_fn_t *callback));
    
    /**
     * Update registered watchdog callback interval.
     * @param w Watchdog to use
     * @param interval New interval on which the callback function will execute.
     * @param callback  The function to call on watchdog event.
     * @param data The data to pass to the callback function.
     * @return APR_SUCCESS if all went well. APR_EOF if callback was not found.
     */
    APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_watchdog_set_callback_interval,
                            (ap_watchdog_t *w, apr_interval_time_t interval,
                             const void *data, ap_watchdog_callback_fn_t *callback));
    
    /**
     * Watchdog require hook.
     * @param s The server record
     * @param name Watchdog name.
     * @param parent Non-zero to indicate the parent process watchdog mode.
     * @param singleton Non-zero to indicate the singleton watchdog mode.
     * @return OK to enable notifications from this watchdog, DECLINED otherwise.
     * @remark This is called in post config phase for all watchdog instances
     *         that have no callbacks registered. Modules using this hook
     *         should ensure that their post_config hook is called after watchdog
     *         post_config.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, AP_WD, int, watchdog_need, (server_rec *s,
                              const char *name,
                              int parent, int singleton))
    
    
    /**
     * Watchdog initialize hook.
     * It is called after the watchdog thread is initialized.
     * @param s The server record
     * @param name Watchdog name.
     * @param pool The pool used to create the watchdog.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, AP_WD, int, watchdog_init, (
                              server_rec *s,
                              const char *name,
                              apr_pool_t *pool))
    
    /**
     * Watchdog terminate hook.
     * It is called when the watchdog thread is terminated.
     * @param s The server record
     * @param name Watchdog name.
     * @param pool The pool used to create the watchdog.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, AP_WD, int, watchdog_exit, (
                              server_rec *s,
                              const char *name,
                              apr_pool_t *pool))
    
    /**
     * Fixed interval watchdog hook.
     * It is called regularly on @p AP_WD_TM_INTERVAL interval.
     * @param s The server record
     * @param name Watchdog name.
     * @param pool Temporary pool destroyed after the call.
     */
    APR_DECLARE_EXTERNAL_HOOK(ap, AP_WD, int, watchdog_step, (
                              server_rec *s,
                              const char *name,
                              apr_pool_t *pool))
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* MOD_WATCHDOG_H */
    /** @} */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/Makefile.in���������������������������������������������������������������0000664�0001751�0001751�00000000051�11665401625�017271� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_so.h������������������������������������������������������������������0000664�0001751�0001751�00000002312�11665401625�016657� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file mod_so.h
     * @brief Shared Object Loader Extension Module for Apache
     *
     * @defgroup MOD_SO mod_so
     * @ingroup APACHE_MODS
     * @{
     */
    
    #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 */
    /** @} */
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/core/mod_watchdog.dsp����������������������������������������������������������0000664�0001751�0001751�00000011042�11665401625�020375� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_watchdog" - 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_watchdog - 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_watchdog.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_watchdog.mak" CFG="mod_watchdog - Win32 Release"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_watchdog - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_watchdog - 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_watchdog - 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 "AP_WD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_watchdog_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 /fo"Release/mod_watchdog.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_watchdog.so" /d LONG_NAME="watchdog_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_watchdog.so" /base:@..\..\os\win32\BaseAddr.ref,mod_watchdog.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_watchdog.so" /base:@..\..\os\win32\BaseAddr.ref,mod_watchdog.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_watchdog.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_watchdog - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "AP_WD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_watchdog_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 /fo"Debug/mod_watchdog.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_watchdog.so" /d LONG_NAME="watchdog_module for Apache"
    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 /out:".\Debug\mod_watchdog.so" /base:@..\..\os\win32\BaseAddr.ref,mod_watchdog.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_watchdog.so" /base:@..\..\os\win32\BaseAddr.ref,mod_watchdog.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_watchdog.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_watchdog - Win32 Release"
    # Name "mod_watchdog - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_watchdog.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_watchdog.h
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015263� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/mod_optional_hook_import.c������������������������������������������������0000664�0001751�0001751�00000002616�14300512413�022511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_DEBUG,OK,NULL, APLOGNO(01866)
                     "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);
    }
    
    AP_DECLARE_MODULE(optional_hook_import) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        ImportRegisterHooks
    };
    ������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/mod_optional_fn_export.c��������������������������������������������������0000664�0001751�0001751�00000002711�11667005541�022173� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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, APLOGNO(01871)
                     "Optional function test said: %s",szStr);
    
        return OK;
    }
    
    static void ExportRegisterHooks(apr_pool_t *p)
    {
        APR_REGISTER_OPTIONAL_FN(TestOptionalFn);
    }
    
    AP_DECLARE_MODULE(optional_fn_export) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        ExportRegisterHooks
    };
    �������������������������������������������������������httpd-2.4.64/modules/test/NWGNUoptfnimport����������������������������������������������������������0000664�0001751�0001751�00000010322�11540546347�020403� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= optfnimport
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) OptionalFunction Import Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_NAME) 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	=
    
    #
    # 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)/$(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_optional_fn_import.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	optional_fn_import_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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/mod_optional_hook_export.h������������������������������������������������0000664�0001751�0001751�00000001743�12215067346�022542� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_OPTIONAL_HOOK_EXPORT_H
    
    #include "ap_config.h"
    
    AP_DECLARE_HOOK(int,optional_hook_test,(const char *))
    
    #endif /* def MOD_OPTIONAL_HOOK_EXPORT_H */
    �����������������������������httpd-2.4.64/modules/test/NWGNUopthookimport��������������������������������������������������������0000664�0001751�0001751�00000010324�11540546347�020742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= opthookimport
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) OptionalHook Import Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_NAME) 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	=
    
    #
    # 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)/$(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_optional_hook_import.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	optional_hook_import_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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/mod_dialup.c��������������������������������������������������������������0000664�0001751�0001751�00000017357�14021721047�017545� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_core.h"
    
    #include "util_filter.h"
    #include "http_log.h"
    #include "http_config.h"
    #include "http_request.h"
    #include "http_protocol.h"
    
    
    
    #include "ap_mpm.h"
    
    module AP_MODULE_DECLARE_DATA dialup_module;
    
    typedef struct dialup_dcfg_t {
        apr_size_t bytes_per_second;
    } dialup_dcfg_t;
    
    typedef struct dialup_baton_t {
        apr_size_t bytes_per_second;
        request_rec *r;
        apr_file_t *fd;
        apr_bucket_brigade *bb;
        apr_bucket_brigade *tmpbb;
    } dialup_baton_t;
    
    static int
    dialup_send_pulse(dialup_baton_t *db)
    {
        int status;
        apr_off_t len = 0;
        apr_size_t bytes_sent = 0;
    
        while (!APR_BRIGADE_EMPTY(db->bb) && bytes_sent < db->bytes_per_second) {
            apr_bucket *e;
    
            if (db->r->connection->aborted) {
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            status = apr_brigade_partition(db->bb, db->bytes_per_second, &e);
    
            if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
                /* XXXXXX: Log me. */
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            if (e != APR_BRIGADE_SENTINEL(db->bb)) {
                apr_bucket *f;
                apr_bucket *b = APR_BUCKET_PREV(e);
                f = APR_RING_FIRST(&db->bb->list);
                APR_RING_UNSPLICE(f, b, link);
                APR_RING_SPLICE_HEAD(&db->tmpbb->list, f, b, apr_bucket, link);
            }
            else {
                APR_BRIGADE_CONCAT(db->tmpbb, db->bb);
            }
    
            e = apr_bucket_flush_create(db->r->connection->bucket_alloc);
    
            APR_BRIGADE_INSERT_TAIL(db->tmpbb, e);
    
            apr_brigade_length(db->tmpbb, 1, &len);
            bytes_sent += len;
            status = ap_pass_brigade(db->r->output_filters, db->tmpbb);
    
            apr_brigade_cleanup(db->tmpbb);
    
            if (status != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, db->r, APLOGNO(01867)
                              "dialup: pulse: ap_pass_brigade failed:");
                return AP_FILTER_ERROR;
            }
        }
    
        if (APR_BRIGADE_EMPTY(db->bb)) {
            return DONE;
        }
        else {
            return SUSPENDED;
        }
    }
    
    static void
    dialup_callback(void *baton)
    {
        int status;
        dialup_baton_t *db = (dialup_baton_t *)baton;
    
        apr_thread_mutex_lock(db->r->invoke_mtx);
    
        status = dialup_send_pulse(db);
    
        if (status == SUSPENDED) {
            ap_mpm_register_timed_callback(apr_time_from_sec(1), dialup_callback, baton);
        }
        else if (status == DONE) {
            apr_thread_mutex_unlock(db->r->invoke_mtx);
            ap_finalize_request_protocol(db->r);
            ap_process_request_after_handler(db->r);
            return;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, db->r, APLOGNO(01868)
                          "dialup: pulse returned: %d", status);
            db->r->status = HTTP_OK;
            ap_die(status, db->r);
        }
    
        apr_thread_mutex_unlock(db->r->invoke_mtx);
    }
    
    static int
    dialup_handler(request_rec *r)
    {
        int status;
        apr_status_t rv;
        dialup_dcfg_t *dcfg;
        core_dir_config *ccfg;
        apr_file_t *fd;
        dialup_baton_t *db;
        apr_bucket *e;
    
    
        /* See core.c, default handler for all of the cases we just decline. */
        if (r->method_number != M_GET ||
            r->finfo.filetype == APR_NOFILE ||
            r->finfo.filetype == APR_DIR) {
            return DECLINED;
        }
    
        dcfg = ap_get_module_config(r->per_dir_config,
                                    &dialup_module);
    
        if (dcfg->bytes_per_second == 0) {
            return DECLINED;
        }
    
        ccfg = ap_get_core_module_config(r->per_dir_config);
    
    
        rv = apr_file_open(&fd, r->filename, APR_READ | APR_BINARY
    #if APR_HAS_SENDFILE
                               | AP_SENDFILE_ENABLED(ccfg->enable_sendfile)
    #endif
                           , 0, r->pool);
    
        if (rv) {
            return DECLINED;
        }
    
        /* copied from default handler: */
        ap_update_mtime(r, r->finfo.mtime);
        ap_set_last_modified(r);
        ap_set_etag_fd(r, fd);
        ap_set_accept_ranges(r);
        ap_set_content_length(r, r->finfo.size);
    
        status = ap_meets_conditions(r);
        if (status != OK) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01869)
                          "dialup: declined, meets conditions, good luck core handler");
            return DECLINED;
        }
    
        db = apr_palloc(r->pool, sizeof(dialup_baton_t));
    
        db->bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        db->tmpbb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        e = apr_brigade_insert_file(db->bb, fd, 0, r->finfo.size, r->pool);
    
    #if APR_HAS_MMAP
        if (ccfg->enable_mmap == ENABLE_MMAP_OFF) {
            apr_bucket_file_enable_mmap(e, 0);
        }
    #endif
    
    
        db->bytes_per_second = dcfg->bytes_per_second;
        db->r = r;
        db->fd = fd;
    
        e = apr_bucket_eos_create(r->connection->bucket_alloc);
    
        APR_BRIGADE_INSERT_TAIL(db->bb, e);
    
        status = dialup_send_pulse(db);
        if (status != SUSPENDED && status != DONE) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01870)
                          "dialup: failed, send pulse");
            return status;
        }
    
        ap_mpm_register_timed_callback(apr_time_from_sec(1), dialup_callback, db);
    
        return SUSPENDED;
    }
    
    
    
    #ifndef APR_HOOK_ALMOST_LAST
    #define APR_HOOK_ALMOST_LAST (APR_HOOK_REALLY_LAST - 1)
    #endif
    
    static void
    dialup_register_hooks(apr_pool_t *p)
    {
        ap_hook_handler(dialup_handler, NULL, NULL, APR_HOOK_ALMOST_LAST);
    }
    
    typedef struct modem_speed_t {
        const char *name;
        apr_size_t bytes_per_second;
    } modem_speed_t;
    
    #ifndef BITRATE_TO_BYTES
    #define BITRATE_TO_BYTES(x) ((1000 * x)/8)
    #endif
    
    static const modem_speed_t modem_bitrates[] =
    {
        {"V.21",    BITRATE_TO_BYTES(0.1)},
        {"V.26bis", BITRATE_TO_BYTES(2.4)},
        {"V.32",    BITRATE_TO_BYTES(9.6)},
        {"V.34",    BITRATE_TO_BYTES(28.8)},
        {"V.92",    BITRATE_TO_BYTES(56.0)},
        {"i-was-rich-and-got-a-leased-line", BITRATE_TO_BYTES(1500)},
        {NULL, 0}
    };
    
    static const char *
    cmd_modem_standard(cmd_parms *cmd,
                 void *dconf,
                 const char *input)
    {
        const modem_speed_t *standard;
        int i = 0;
        dialup_dcfg_t *dcfg = (dialup_dcfg_t*)dconf;
    
        dcfg->bytes_per_second = 0;
    
        while (modem_bitrates[i].name != NULL) {
            standard = &modem_bitrates[i];
            if (strcasecmp(standard->name, input) == 0) {
                dcfg->bytes_per_second = standard->bytes_per_second;
                break;
            }
            i++;
        }
    
        if (dcfg->bytes_per_second == 0) {
            return "mod_dialup: Unknown Modem Standard specified.";
        }
    
        return NULL;
    }
    
    static void *
    dialup_dcfg_create(apr_pool_t *p, char *dummy)
    {
        dialup_dcfg_t *cfg = apr_palloc(p, sizeof(dialup_dcfg_t));
    
        cfg->bytes_per_second = 0;
    
        return cfg;
    }
    
    
    static const command_rec dialup_cmds[] =
    {
        AP_INIT_TAKE1("ModemStandard", cmd_modem_standard, NULL, ACCESS_CONF,
                      "Modem Standard to.. simulate. "
                      "Must be one of: 'V.21', 'V.26bis', 'V.32', 'V.34', or 'V.92'"),
        {NULL}
    };
    
    AP_DECLARE_MODULE(dialup) =
    {
        STANDARD20_MODULE_STUFF,
        dialup_dcfg_create,
        NULL,
        NULL,
        NULL,
        dialup_cmds,
        dialup_register_hooks
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/mod_optional_hook_export.c������������������������������������������������0000664�0001751�0001751�00000002631�11402752006�022521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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);
    }
    
    AP_DECLARE_MODULE(optional_hook_export) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        ExportRegisterHooks
    };
    �������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/mod_optional_fn_export.h��������������������������������������������������0000664�0001751�0001751�00000001567�10455005461�022203� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 *));
    �����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/.indent.pro���������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�017337� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/NWGNUmakefile�������������������������������������������������������������0000664�0001751�0001751�00000011233�11660227471�017576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    #
    # If there is only one element to build it needs to be included twice
    # in the below target list.
    # Normally if there is only one element to be built within a
    # directory, the makefile for the single element would be called NWGNUmakefile.
    # But if there are multiples, the parent NWGNUmakefile must reference more
    # than one submakefile. Because the experimental directory might vary in the
    # number of submakefiles, but for the moment only contains one, we reference
    # it twice to allow it parent NWGNUmakefile to work properly.  If another
    # submakefile is added, the extra reference to the first NLM should be removed.
    TARGET_nlm = \
    	$(OBJDIR)/optfnexport.nlm \
    	$(OBJDIR)/optfnimport.nlm \
    	$(OBJDIR)/opthookexport.nlm \
    	$(OBJDIR)/opthookimport.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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/NWGNUopthookexport��������������������������������������������������������0000664�0001751�0001751�00000010324�11540546347�020751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= opthookexport
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) OptionalHook Export Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_NAME) 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	=
    
    #
    # 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)/$(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_optional_hook_export.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	optional_hook_export_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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/Makefile.in���������������������������������������������������������������0000664�0001751�0001751�00000000267�10150161574�017323� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/mod_optional_fn_import.c��������������������������������������������������0000664�0001751�0001751�00000003212�12604740124�022154� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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);
    }
    
    AP_DECLARE_MODULE(optional_fn_import) =
    {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        ImportRegisterHooks
    };
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/config.m4�����������������������������������������������������������������0000664�0001751�0001751�00000000757�11607365420�016775� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    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_MODULE(dialup, rate limits static files to dialup modem speeds, , , )
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    �����������������httpd-2.4.64/modules/test/NWGNUoptfnexport����������������������������������������������������������0000664�0001751�0001751�00000010322�11540546347�020412� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= optfnexport
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) OptionalFunction Export Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_NAME) 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	=
    
    #
    # 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)/$(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_optional_fn_export.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	optional_fn_export_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 $(APBUILD)/NWGNUtail.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/test/README��������������������������������������������������������������������0000664�0001751�0001751�00000000077�10150161574�016135� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������test modules have moved to httpd-test/perl-framework/c-modules
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016050� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/mod_dbd.h�������������������������������������������������������������0000664�0001751�0001751�00000010072�11637105701�017600� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mod_dbd.h
     * @brief Database Access Extension Module for Apache
     *
     * Overview of what this is and does:
     * http://www.apache.org/~niq/dbd.html
     * or
     * http://apache.webthing.com/database/
     *
     * @defgroup MOD_DBD mod_dbd
     * @ingroup APACHE_MODS
     * @{
     */
    
    #ifndef DBD_H
    #define DBD_H
    
    /* Create a set of DBD_DECLARE(type), DBD_DECLARE_NONSTD(type) and
     * DBD_DECLARE_DATA with appropriate export and import tags for the platform
     */
    #if !defined(WIN32)
    #define DBD_DECLARE(type)            type
    #define DBD_DECLARE_NONSTD(type)     type
    #define DBD_DECLARE_DATA
    #elif defined(DBD_DECLARE_STATIC)
    #define DBD_DECLARE(type)            type __stdcall
    #define DBD_DECLARE_NONSTD(type)     type
    #define DBD_DECLARE_DATA
    #elif defined(DBD_DECLARE_EXPORT)
    #define DBD_DECLARE(type)            __declspec(dllexport) type __stdcall
    #define DBD_DECLARE_NONSTD(type)     __declspec(dllexport) type
    #define DBD_DECLARE_DATA             __declspec(dllexport)
    #else
    #define DBD_DECLARE(type)            __declspec(dllimport) type __stdcall
    #define DBD_DECLARE_NONSTD(type)     __declspec(dllimport) type
    #define DBD_DECLARE_DATA             __declspec(dllimport)
    #endif
    
    #include <httpd.h>
    #include <apr_optional.h>
    #include <apr_hash.h>
    #include <apr_hooks.h>
    
    typedef struct {
        server_rec *server;
        const char *name;
        const char *params;
        int persist;
    #if APR_HAS_THREADS
        int nmin;
        int nkeep;
        int nmax;
        int exptime;
        int set;
    #endif
        apr_hash_t *queries;
        apr_array_header_t *init_queries;
    } dbd_cfg_t;
    
    typedef struct {
        apr_dbd_t *handle;
        const apr_dbd_driver_t *driver;
        apr_hash_t *prepared;
        apr_pool_t *pool;
    } ap_dbd_t;
    
    /* Export functions to access the database */
    
    /* acquire a connection that MUST be explicitly closed.
     * Returns NULL on error
     */
    DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t*, server_rec*);
    
    /* release a connection acquired with ap_dbd_open */
    DBD_DECLARE_NONSTD(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.
     */
    DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_acquire(request_rec*);
    
    /* acquire a connection that will have the lifetime of a connection
     * and MUST NOT be explicitly closed.  Return NULL on error.
     * This is the preferred function for most applications.
     */
    DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_cacquire(conn_rec*);
    
    /* Prepare a statement for use by a client module during
     * the server startup/configuration phase.  Can't be called
     * after the server has created its children (use apr_dbd_*).
     */
    DBD_DECLARE_NONSTD(void) ap_dbd_prepare(server_rec*, const char*, const char*);
    
    /* 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*));
    APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_cacquire, (conn_rec*));
    APR_DECLARE_OPTIONAL_FN(void, ap_dbd_prepare, (server_rec*, const char*, const char*));
    
    APR_DECLARE_EXTERNAL_HOOK(dbd, DBD, apr_status_t, post_connect,
                              (apr_pool_t *, dbd_cfg_t *, ap_dbd_t *))
    
    #endif
    /** @} */
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/Makefile.in�����������������������������������������������������������0000664�0001751�0001751�00000000267�10315220761�020105� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/mod_dbd.mak�����������������������������������������������������������0000664�0001751�0001751�00000023041�12701473373�020127� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_dbd.dsp
    !IF "$(CFG)" == ""
    CFG=mod_dbd - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to mod_dbd - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_dbd - Win32 Release" && "$(CFG)" != "mod_dbd - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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_dbd.mak" CFG="mod_dbd - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dbd - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_dbd.obj"
    	-@erase "$(INTDIR)\mod_dbd.res"
    	-@erase "$(INTDIR)\mod_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_dbd.exp"
    	-@erase "$(OUTDIR)\mod_dbd.lib"
    	-@erase "$(OUTDIR)\mod_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DBD_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dbd_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dbd.so" /d LONG_NAME="dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dbd.pdb" /debug /out:"$(OUTDIR)\mod_dbd.so" /implib:"$(OUTDIR)\mod_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_dbd.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_dbd.obj" \
    	"$(INTDIR)\mod_dbd.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dbd.so"
       if exist .\Release\mod_dbd.so.manifest mt.exe -manifest .\Release\mod_dbd.so.manifest -outputresource:.\Release\mod_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_dbd - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_dbd.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_dbd.obj"
    	-@erase "$(INTDIR)\mod_dbd.res"
    	-@erase "$(INTDIR)\mod_dbd_src.idb"
    	-@erase "$(INTDIR)\mod_dbd_src.pdb"
    	-@erase "$(OUTDIR)\mod_dbd.exp"
    	-@erase "$(OUTDIR)\mod_dbd.lib"
    	-@erase "$(OUTDIR)\mod_dbd.pdb"
    	-@erase "$(OUTDIR)\mod_dbd.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DBD_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dbd_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dbd.so" /d LONG_NAME="dbd_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dbd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dbd.pdb" /debug /out:"$(OUTDIR)\mod_dbd.so" /implib:"$(OUTDIR)\mod_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_dbd.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_dbd.obj" \
    	"$(INTDIR)\mod_dbd.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dbd.so"
       if exist .\Debug\mod_dbd.so.manifest mt.exe -manifest .\Debug\mod_dbd.so.manifest -outputresource:.\Debug\mod_dbd.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_dbd.dep")
    !INCLUDE "mod_dbd.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_dbd.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_dbd - Win32 Release" || "$(CFG)" == "mod_dbd - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_dbd - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\database"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\database"
    
    !ELSEIF  "$(CFG)" == "mod_dbd - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\database"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\database"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dbd - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\database"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\database"
    
    !ELSEIF  "$(CFG)" == "mod_dbd - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\database"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\database"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dbd - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\database"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\database"
    
    !ELSEIF  "$(CFG)" == "mod_dbd - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\database"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\database"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_dbd - Win32 Release"
    
    
    "$(INTDIR)\mod_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_dbd.so" /d LONG_NAME="dbd_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_dbd - Win32 Debug"
    
    
    "$(INTDIR)\mod_dbd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_dbd.so" /d LONG_NAME="dbd_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_dbd.c
    
    "$(INTDIR)\mod_dbd.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/config.m4�������������������������������������������������������������0000664�0001751�0001751�00000000244�11245631222�017543� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    APACHE_MODPATH_INIT(database)
    
    APACHE_MODULE(dbd, Apache DBD Framework, , , most)
    
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    APACHE_MODPATH_FINISH
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/mod_dbd.c�������������������������������������������������������������0000664�0001751�0001751�00000072763�14037102164�017607� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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/
     */
    
    #include "apr_reslist.h"
    #include "apr_strings.h"
    #include "apr_hash.h"
    #include "apr_tables.h"
    #include "apr_lib.h"
    #include "apr_dbd.h"
    
    #define APR_WANT_MEMFUNC
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    #include "http_protocol.h"
    #include "http_config.h"
    #include "http_log.h"
    #include "http_request.h"
    #include "mod_dbd.h"
    
    extern module AP_MODULE_DECLARE_DATA dbd_module;
    
    APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(dbd, DBD, apr_status_t, post_connect,
                                        (apr_pool_t *pool, dbd_cfg_t *cfg,
                                        ap_dbd_t *dbd),
                                        (pool, cfg, dbd), OK, DECLINED)
    
    /************ svr cfg: manage db connection pool ****************/
    
    #define NMIN_SET     0x1
    #define NKEEP_SET    0x2
    #define NMAX_SET     0x4
    #define EXPTIME_SET  0x8
    
    typedef struct dbd_group_t dbd_group_t;
    
    struct dbd_group_t {
        dbd_cfg_t *cfg;
        dbd_group_t *next;
        apr_pool_t *pool;
    #if APR_HAS_THREADS
        apr_thread_mutex_t *mutex;
        apr_reslist_t *reslist;
        int destroyed;
    #else
        ap_dbd_t *rec;
    #endif
    };
    
    typedef struct {
        dbd_cfg_t *cfg;
        dbd_group_t *group;
    } svr_cfg;
    
    typedef enum { cmd_name, cmd_params, cmd_persist,
                   cmd_min, cmd_keep, cmd_max, cmd_exp
    } cmd_parts;
    
    static apr_pool_t *config_pool;
    static dbd_group_t *group_list;
    
    /* a default DBDriver value that'll generate meaningful error messages */
    static const char *const no_dbdriver = "[DBDriver unset]";
    
    /* A default nmin of >0 will help with generating meaningful
     * startup error messages if the database is down.
     */
    #define DEFAULT_NMIN 1
    #define DEFAULT_NKEEP 2
    #define DEFAULT_NMAX 10
    #define DEFAULT_EXPTIME 300
    
    #define DEFAULT_SQL_INIT_ARRAY_SIZE 5
    
    static void *create_dbd_config(apr_pool_t *pool, server_rec *s)
    {
        svr_cfg *svr = apr_pcalloc(pool, sizeof(svr_cfg));
        dbd_cfg_t *cfg = svr->cfg = apr_pcalloc(pool, sizeof(dbd_cfg_t));
    
        cfg->server = s;
        cfg->name = no_dbdriver; /* to generate meaningful error messages */
        cfg->params = ""; /* don't risk segfault on misconfiguration */
        cfg->persist = -1;
    #if APR_HAS_THREADS
        cfg->nmin = DEFAULT_NMIN;
        cfg->nkeep = DEFAULT_NKEEP;
        cfg->nmax = DEFAULT_NMAX;
        cfg->exptime = DEFAULT_EXPTIME;
    #endif
        cfg->queries = apr_hash_make(pool);
        cfg->init_queries = apr_array_make(pool, DEFAULT_SQL_INIT_ARRAY_SIZE,
                                           sizeof(const char *));
    
        return svr;
    }
    
    static void *merge_dbd_config(apr_pool_t *pool, void *basev, void *addv)
    {
        dbd_cfg_t *base = ((svr_cfg*) basev)->cfg;
        dbd_cfg_t *add = ((svr_cfg*) addv)->cfg;
        svr_cfg *svr = apr_pcalloc(pool, sizeof(svr_cfg));
        dbd_cfg_t *new = svr->cfg = apr_pcalloc(pool, sizeof(dbd_cfg_t));
    
        new->server = add->server;
        new->name = (add->name != no_dbdriver) ? add->name : base->name;
        new->params = strcmp(add->params, "") ? add->params : base->params;
        new->persist = (add->persist != -1) ? add->persist : base->persist;
    #if APR_HAS_THREADS
        new->nmin = (add->set&NMIN_SET) ? add->nmin : base->nmin;
        new->nkeep = (add->set&NKEEP_SET) ? add->nkeep : base->nkeep;
        new->nmax = (add->set&NMAX_SET) ? add->nmax : base->nmax;
        new->exptime = (add->set&EXPTIME_SET) ? add->exptime : base->exptime;
    #endif
        new->queries = apr_hash_overlay(pool, add->queries, base->queries);
        new->init_queries = apr_array_append(pool, add->init_queries,
                                             base->init_queries);
    
        return svr;
    }
    
    static void ap_dbd_sql_init(server_rec *s, const char *query)
    {
        svr_cfg *svr;
        const char **arr_item;
    
        svr = ap_get_module_config(s->module_config, &dbd_module);
        if (!svr) {
             /* some modules may call from within config directive handlers, and
              * if these are called in a server context that contains no mod_dbd
              * config directives, then we have to create our own server config
              */
             svr = create_dbd_config(config_pool, s);
             ap_set_module_config(s->module_config, &dbd_module, svr);
        }
    
        if (query) {
            arr_item = apr_array_push(svr->cfg->init_queries);
            *arr_item = query;
        }
    }
    
    static const char *dbd_param(cmd_parms *cmd, void *dconf, const char *val)
    {
        apr_status_t rv;
        const apr_dbd_driver_t *driver = NULL;
        svr_cfg *svr = ap_get_module_config(cmd->server->module_config,
                                            &dbd_module);
        dbd_cfg_t *cfg = svr->cfg;
    
        switch ((long) cmd->info) {
        case cmd_name:
            cfg->name = val;
            /* loading the driver involves once-only dlloading that is
             * best done at server startup.  This also guarantees that
             * we won't return an error later.
             */
            rv = apr_dbd_get_driver(cmd->pool, cfg->name, &driver);
            if (APR_STATUS_IS_ENOTIMPL(rv)) {
                return apr_psprintf(cmd->pool, "No driver for %s", cfg->name);
            }
            else if (APR_STATUS_IS_EDSOOPEN(rv)) {
                return apr_psprintf(cmd->pool,
    #ifdef NETWARE
                                    "Can't load driver file dbd%s.nlm",
    #else
                                    "Can't load driver file apr_dbd_%s.so",
    #endif
                                    cfg->name);
            }
            else if (APR_STATUS_IS_ESYMNOTFOUND(rv)) {
                return apr_psprintf(cmd->pool,
                                    "Failed to load driver apr_dbd_%s_driver",
                                    cfg->name);
            }
            break;
        case cmd_params:
            cfg->params = val;
            break;
        }
    
        return NULL;
    }
    
    #if APR_HAS_THREADS
    static const char *dbd_param_int(cmd_parms *cmd, void *dconf, const char *val)
    {
        svr_cfg *svr = ap_get_module_config(cmd->server->module_config,
                                            &dbd_module);
        dbd_cfg_t *cfg = svr->cfg;
        const char *p;
    
        for (p = val; *p; ++p) {
            if (!apr_isdigit(*p)) {
                return "Argument must be numeric!";
            }
        }
    
        switch ((long) cmd->info) {
        case cmd_min:
            cfg->nmin = atoi(val);
            cfg->set |= NMIN_SET;
            break;
        case cmd_keep:
            cfg->nkeep = atoi(val);
            cfg->set |= NKEEP_SET;
            break;
        case cmd_max:
            cfg->nmax = atoi(val);
            cfg->set |= NMAX_SET;
            break;
        case cmd_exp:
            cfg->exptime = atoi(val);
            cfg->set |= EXPTIME_SET;
            break;
        }
    
        return NULL;
    }
    #endif
    
    static const char *dbd_param_flag(cmd_parms *cmd, void *dconf, int flag)
    {
        svr_cfg *svr = ap_get_module_config(cmd->server->module_config,
                                            &dbd_module);
    
        switch ((long) cmd->info) {
        case cmd_persist:
            svr->cfg->persist = flag;
            break;
        }
    
        return NULL;
    }
    
    static const char *dbd_prepare(cmd_parms *cmd, void *dconf, const char *query,
                                   const char *label)
    {
        if (!label) {
            label = query;
            query = "";
        }
    
        ap_dbd_prepare(cmd->server, query, label);
    
        return NULL;
    }
    
    static const char *dbd_init_sql(cmd_parms *cmd, void *dconf, const char *query)
    {
        if (!query || *query == '\n') {
            return "You should specify SQL statement";
        }
    
        ap_dbd_sql_init(cmd->server, query);
    
        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_FLAG("DBDPersist", dbd_param_flag, (void*)cmd_persist, RSRC_CONF,
                     "Use persistent connection/pool"),
        AP_INIT_TAKE12("DBDPrepareSQL", dbd_prepare, NULL, RSRC_CONF,
                       "SQL statement to prepare (or nothing, to override "
                       "statement inherited from main server) and label"),
        AP_INIT_TAKE1("DBDInitSQL", dbd_init_sql, NULL, RSRC_CONF,
                       "SQL statement to be executed after connection is created"),
    #if APR_HAS_THREADS
        AP_INIT_TAKE1("DBDMin", dbd_param_int, (void*)cmd_min, RSRC_CONF,
                      "Minimum number of connections"),
        /* XXX: note that mod_proxy calls this "smax" */
        AP_INIT_TAKE1("DBDKeep", dbd_param_int, (void*)cmd_keep, RSRC_CONF,
                      "Maximum number of sustained connections"),
        AP_INIT_TAKE1("DBDMax", dbd_param_int, (void*)cmd_max, RSRC_CONF,
                      "Maximum number of connections"),
        /* XXX: note that mod_proxy calls this "ttl" (time to live) */
        AP_INIT_TAKE1("DBDExptime", dbd_param_int, (void*)cmd_exp, RSRC_CONF,
                      "Keepalive time for idle connections"),
    #endif
        {NULL}
    };
    
    static int dbd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                              apr_pool_t *ptemp)
    {
       config_pool = pconf;
       group_list = NULL;
       return OK;
    }
    
    DBD_DECLARE_NONSTD(void) ap_dbd_prepare(server_rec *s, const char *query,
                                            const char *label)
    {
        svr_cfg *svr;
    
        svr = ap_get_module_config(s->module_config, &dbd_module);
        if (!svr) {
             /* some modules may call from within config directive handlers, and
              * if these are called in a server context that contains no mod_dbd
              * config directives, then we have to create our own server config
              */
             svr = create_dbd_config(config_pool, s);
             ap_set_module_config(s->module_config, &dbd_module, svr);
        }
    
        if (apr_hash_get(svr->cfg->queries, label, APR_HASH_KEY_STRING)
            && strcmp(query, "")) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02653)
                         "conflicting SQL statements with label %s", label);
        }
    
        apr_hash_set(svr->cfg->queries, label, APR_HASH_KEY_STRING, query);
    }
    
    typedef struct {
        const char *label, *query;
    } dbd_query_t;
    
    static int dbd_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                               apr_pool_t *ptemp, server_rec *s)
    {
        server_rec *sp;
        apr_array_header_t *add_queries = apr_array_make(ptemp, 10,
                                                         sizeof(dbd_query_t));
    
        for (sp = s; sp; sp = sp->next) {
            svr_cfg *svr = ap_get_module_config(sp->module_config, &dbd_module);
            dbd_cfg_t *cfg = svr->cfg;
            apr_hash_index_t *hi_first = apr_hash_first(ptemp, cfg->queries);
            dbd_group_t *group;
    
            /* dbd_setup in 2.2.3 and under was causing spurious error messages
             * when dbd isn't configured.  We can stop that with a quick check here
             * together with a similar check in ap_dbd_open (where being
             * unconfigured is a genuine error that must be reported).
             */
            if (cfg->name == no_dbdriver || !cfg->persist) {
                continue;
            }
    
            for (group = group_list; group; group = group->next) {
                dbd_cfg_t *group_cfg = group->cfg;
                apr_hash_index_t *hi;
                int group_ok = 1;
    
                if (strcmp(cfg->name, group_cfg->name)
                    || strcmp(cfg->params, group_cfg->params)) {
                    continue;
                }
    
    #if APR_HAS_THREADS
                if (cfg->nmin != group_cfg->nmin
                    || cfg->nkeep != group_cfg->nkeep
                    || cfg->nmax != group_cfg->nmax
                    || cfg->exptime != group_cfg->exptime) {
                    continue;
                }
    #endif
    
                add_queries->nelts = 0;
    
                for (hi = hi_first; hi; hi = apr_hash_next(hi)) {
                    const char *label, *query;
                    const char *group_query;
    
                    apr_hash_this(hi, (void*) &label, NULL, (void*) &query);
    
                    group_query = apr_hash_get(group_cfg->queries, label,
                                               APR_HASH_KEY_STRING);
    
                    if (!group_query) {
                        dbd_query_t *add_query = apr_array_push(add_queries);
    
                        add_query->label = label;
                        add_query->query = query;
                    }
                    else if (strcmp(query, group_query)) {
                        group_ok = 0;
                        break;
                    }
                }
    
                if (group_ok) {
                    int i;
    
                    for (i = 0; i < add_queries->nelts; ++i) {
                        dbd_query_t *add_query = ((dbd_query_t*) add_queries->elts)
                                                 + i;
    
                        apr_hash_set(group_cfg->queries, add_query->label,
                                     APR_HASH_KEY_STRING, add_query->query);
                    }
    
                    svr->group = group;
                    break;
                }
            }
    
            if (!svr->group) {
                svr->group = group = apr_pcalloc(pconf, sizeof(dbd_group_t));
    
                group->cfg = cfg;
    
                group->next = group_list;
                group_list = group;
            }
        }
    
        return OK;
    }
    
    static apr_status_t dbd_prepared_init(apr_pool_t *pool, dbd_cfg_t *cfg,
                                          ap_dbd_t *rec)
    {
        apr_hash_index_t *hi;
    
        rec->prepared = apr_hash_make(pool);
    
        for (hi = apr_hash_first(pool, cfg->queries); hi;
             hi = apr_hash_next(hi)) {
            const char *label, *query;
            apr_dbd_prepared_t *stmt;
    
            apr_hash_this(hi, (void*) &label, NULL, (void*) &query);
    
            if (!strcmp(query, "")) {
                continue;
            }
    
            stmt = NULL;
            if (apr_dbd_prepare(rec->driver, pool, rec->handle, query,
                                label, &stmt)) {
                return APR_EGENERAL;
            }
            else {
                apr_hash_set(rec->prepared, label, APR_HASH_KEY_STRING, stmt);
            }
        }
    
        return APR_SUCCESS;
    }
    
    static apr_status_t dbd_init_sql_init(apr_pool_t *pool, dbd_cfg_t *cfg,
                                          ap_dbd_t *rec)
    {
        int i;
        apr_status_t rv = APR_SUCCESS;
    
        for (i = 0; i < cfg->init_queries->nelts; i++) {
            int nrows;
            char **query_p;
    
            query_p = (char **)cfg->init_queries->elts + i;
    
            if (apr_dbd_query(rec->driver, rec->handle, &nrows, *query_p)) {
                rv = APR_EGENERAL;
                break;
            }
        }
    
        return rv;
    }
    
    static apr_status_t dbd_close(void *data)
    {
        ap_dbd_t *rec = data;
    
        return apr_dbd_close(rec->driver, rec->handle);
    }
    
    #if APR_HAS_THREADS
    static apr_status_t dbd_destruct(void *data, void *params, apr_pool_t *pool)
    {
        dbd_group_t *group = params;
    
        if (!group->destroyed) {
            ap_dbd_t *rec = data;
    
            apr_pool_destroy(rec->pool);
        }
    
        return APR_SUCCESS;
    }
    #endif
    
    /* an apr_reslist_constructor for SQL connections
     * Also use this for opening in non-reslist modes, since it gives
     * us all the error-handling in one place.
     */
    static apr_status_t dbd_construct(void **data_ptr,
                                      void *params, apr_pool_t *pool)
    {
        dbd_group_t *group = params;
        dbd_cfg_t *cfg = group->cfg;
        apr_pool_t *rec_pool, *prepared_pool;
        ap_dbd_t *rec;
        apr_status_t rv;
        const char *err = "";
    
        rv = apr_pool_create(&rec_pool, pool);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, cfg->server, APLOGNO(00624)
                         "Failed to create memory pool");
            return rv;
        }
        apr_pool_tag(rec_pool, "dbd_rec_pool");
    
        rec = apr_pcalloc(rec_pool, sizeof(ap_dbd_t));
    
        rec->pool = rec_pool;
    
        /* The driver is loaded at config time now, so this just checks a hash.
         * If that changes, the driver DSO could be registered to unload against
         * our pool, which is probably not what we want.  Error checking isn't
         * necessary now, but in case that changes in the future ...
         */
        rv = apr_dbd_get_driver(rec->pool, cfg->name, &rec->driver);
        if (rv != APR_SUCCESS) {
            if (APR_STATUS_IS_ENOTIMPL(rv)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->server, APLOGNO(00625)
                             "driver for %s not available", cfg->name);
            }
            else if (APR_STATUS_IS_EDSOOPEN(rv)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->server, APLOGNO(00626)
                             "can't find driver for %s", cfg->name);
            }
            else if (APR_STATUS_IS_ESYMNOTFOUND(rv)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->server, APLOGNO(00627)
                             "driver for %s is invalid or corrupted",
                             cfg->name);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->server, APLOGNO(00628)
                             "mod_dbd not compatible with APR in get_driver");
            }
            apr_pool_destroy(rec->pool);
            return rv;
        }
    
        rv = apr_dbd_open_ex(rec->driver, rec->pool, cfg->params, &rec->handle, &err);
        if (rv != APR_SUCCESS) {
            switch (rv) {
            case APR_EGENERAL:
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->server, APLOGNO(00629)
                             "Can't connect to %s: %s", cfg->name, err);
                break;
            default:
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->server, APLOGNO(00630)
                             "mod_dbd not compatible with APR in open");
                break;
            }
    
            apr_pool_destroy(rec->pool);
            return rv;
        }
    
        apr_pool_cleanup_register(rec->pool, rec, dbd_close,
                                  apr_pool_cleanup_null);
    
        /* we use a sub-pool for the prepared statements for each connection so
         * that they will be cleaned up first, before the connection is closed
         */
        rv = apr_pool_create(&prepared_pool, rec->pool);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, cfg->server, APLOGNO(00631)
                         "Failed to create memory pool");
    
            apr_pool_destroy(rec->pool);
            return rv;
        }
        apr_pool_tag(prepared_pool, "dbd_prepared_pool");
    
        rv = dbd_prepared_init(prepared_pool, cfg, rec);
        if (rv != APR_SUCCESS) {
            const char *errmsg = apr_dbd_error(rec->driver, rec->handle, rv);
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->server, APLOGNO(00632)
                         "failed to prepare SQL statements: %s",
                         (errmsg ? errmsg : "[???]"));
    
            apr_pool_destroy(rec->pool);
            return rv;
        }
    
        dbd_run_post_connect(prepared_pool, cfg, rec);
    
        *data_ptr = rec;
    
        return APR_SUCCESS;
    }
    
    #if APR_HAS_THREADS
    static apr_status_t dbd_destroy(void *data)
    {
        dbd_group_t *group = data;
    
        group->destroyed = 1;
    
        return APR_SUCCESS;
    }
    
    static apr_status_t dbd_setup(server_rec *s, dbd_group_t *group)
    {
        dbd_cfg_t *cfg = group->cfg;
        apr_status_t rv;
    
        /* We create the reslist using a sub-pool of the pool passed to our
         * child_init hook.  No other threads can be here because we're
         * either in the child_init phase or dbd_setup_lock() acquired our mutex.
         * No other threads will use this sub-pool after this, except via
         * reslist calls, which have an internal mutex.
         *
         * We need to short-circuit the cleanup registered internally by
         * apr_reslist_create().  We do this by registering dbd_destroy()
         * as a cleanup afterwards, so that it will run before the reslist's
         * internal cleanup.
         *
         * If we didn't do this, then we could free memory twice when the pool
         * was destroyed.  When apr_pool_destroy() runs, it first destroys all
         * all the per-connection sub-pools created in dbd_construct(), and
         * then it runs the reslist's cleanup.  The cleanup calls dbd_destruct()
         * on each resource, which would then attempt to destroy the sub-pools
         * a second time.
         */
        rv = apr_reslist_create(&group->reslist,
                                cfg->nmin, cfg->nkeep, cfg->nmax,
                                apr_time_from_sec(cfg->exptime),
                                dbd_construct, dbd_destruct, group,
                                group->pool);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00633)
                         "failed to initialise");
            return rv;
        }
    
        apr_pool_cleanup_register(group->pool, group, dbd_destroy,
                                  apr_pool_cleanup_null);
    
        return APR_SUCCESS;
    }
    #endif
    
    static apr_status_t dbd_setup_init(apr_pool_t *pool, server_rec *s)
    {
        dbd_group_t *group;
        apr_status_t rv = APR_SUCCESS;
    
        for (group = group_list; group; group = group->next) {
            apr_status_t rv2;
    
            rv2 = apr_pool_create(&group->pool, pool);
            if (rv2 != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv2, s, APLOGNO(00634)
                             "Failed to create reslist cleanup memory pool");
                return rv2;
            }
            apr_pool_tag(group->pool, "dbd_group");
    
    #if APR_HAS_THREADS
            rv2 = dbd_setup(s, group);
            if (rv2 == APR_SUCCESS) {
                continue;
            }
            else if (rv == APR_SUCCESS) {
                rv = rv2;
            }
    
            /* we failed, so create a mutex so that subsequent competing callers
             * to ap_dbd_open can serialize themselves while they retry
             */
            rv2 = apr_thread_mutex_create(&group->mutex,
                                          APR_THREAD_MUTEX_DEFAULT, pool);
            if (rv2 != APR_SUCCESS) {
                 ap_log_error(APLOG_MARK, APLOG_CRIT, rv2, s, APLOGNO(00635)
                              "Failed to create thread mutex");
                 return rv2;
            }
    #endif
        }
    
        return rv;
    }
    
    static void dbd_child_init(apr_pool_t *p, server_rec *s)
    {
      apr_status_t rv = dbd_setup_init(p, s);
      if (rv) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(00636)
                     "child init failed!");
      }
    }
    
    #if APR_HAS_THREADS
    static apr_status_t dbd_setup_lock(server_rec *s, dbd_group_t *group)
    {
        apr_status_t rv = APR_SUCCESS, rv2;
    
        /* several threads could be here at the same time, all trying to
         * initialize the reslist because dbd_setup_init failed to do so
         */
        if (!group->mutex) {
            /* we already logged an error when the mutex couldn't be created */
            return APR_EGENERAL;
        }
    
        rv2 = apr_thread_mutex_lock(group->mutex);
        if (rv2 != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv2, s, APLOGNO(00637)
                         "Failed to acquire thread mutex");
            return rv2;
        }
    
        if (!group->reslist) {
            rv = dbd_setup(s, group);
        }
    
        rv2 = apr_thread_mutex_unlock(group->mutex);
        if (rv2 != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv2, s, APLOGNO(00638)
                         "Failed to release thread mutex");
            if (rv == APR_SUCCESS) {
                rv = rv2;
            }
        }
    
        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
    */
    DBD_DECLARE_NONSTD(void) ap_dbd_close(server_rec *s, ap_dbd_t *rec)
    {
        svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
    
        if (!svr->cfg->persist) {
            apr_pool_destroy(rec->pool);
        }
    #if APR_HAS_THREADS
        else {
            apr_reslist_release(svr->group->reslist, rec);
        }
    #endif
    }
    
    static apr_status_t dbd_check(apr_pool_t *pool, server_rec *s, ap_dbd_t *rec)
    {
        svr_cfg *svr;
        apr_status_t rv = apr_dbd_check_conn(rec->driver, pool, rec->handle);
        const char *errmsg;
    
        if ((rv == APR_SUCCESS) || (rv == APR_ENOTIMPL)) {
            return APR_SUCCESS;
        }
    
        /* we don't have a driver-specific error code, so we'll just pass
         * a "success" value and rely on the driver to ignore it
         */
        errmsg = apr_dbd_error(rec->driver, rec->handle, 0);
        if (!errmsg) {
            errmsg = "(unknown)";
        }
    
        svr = ap_get_module_config(s->module_config, &dbd_module);
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00639)
                     "DBD [%s] Error: %s", svr->cfg->name, errmsg);
        return rv;
    }
    
    DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s)
    {
        svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
        dbd_group_t *group = svr->group;
        dbd_cfg_t *cfg = svr->cfg;
        ap_dbd_t *rec = NULL;
    #if APR_HAS_THREADS
        apr_status_t rv;
    #endif
    
        /* If nothing is configured, we shouldn't be here */
        if (cfg->name == no_dbdriver) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02654)
                         "not configured");
            return NULL;
        }
    
        if (!cfg->persist) {
            /* Return a once-only connection */
            group = apr_pcalloc(pool, sizeof(dbd_group_t));
    
            group->cfg = cfg;
    
            dbd_construct((void*) &rec, group, pool);
            return rec;
        }
    
    #if APR_HAS_THREADS
        if (!group->reslist) {
            if (dbd_setup_lock(s, group) != APR_SUCCESS) {
                return NULL;
            }
        }
    
        rv = apr_reslist_acquire(group->reslist, (void*) &rec);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02655)
                         "Failed to acquire DBD connection from pool!");
            return NULL;
        }
    
        if (dbd_check(pool, s, rec) != APR_SUCCESS) {
            apr_reslist_invalidate(group->reslist, rec);
            return NULL;
        }
    #else
        /* If we have a persistent connection and it's good, we'll use it;
         * since this is non-threaded, we can update without a mutex
         */
        rec = group->rec;
        if (rec) {
            if (dbd_check(pool, s, rec) != APR_SUCCESS) {
                apr_pool_destroy(rec->pool);
                rec = NULL;
            }
        }
    
        /* We don't have a connection right now, so we'll open one */
        if (!rec) {
            dbd_construct((void*) &rec, group, group->pool);
            group->rec = rec;
        }
    #endif
    
        return rec;
    }
    
    #if APR_HAS_THREADS
    typedef struct {
        ap_dbd_t *rec;
        apr_reslist_t *reslist;
    } dbd_acquire_t;
    
    static apr_status_t dbd_release(void *data)
    {
        dbd_acquire_t *acq = data;
        apr_reslist_release(acq->reslist, acq->rec);
        return APR_SUCCESS;
    }
    
    DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_acquire(request_rec *r)
    {
        dbd_acquire_t *acq;
    
        while (!ap_is_initial_req(r)) {
            if (r->prev) {
                r = r->prev;
            }
            else if (r->main) {
                r = r->main;
            }
        }
    
        acq = ap_get_module_config(r->request_config, &dbd_module);
        if (!acq) {
            acq = apr_palloc(r->pool, sizeof(dbd_acquire_t));
            acq->rec = ap_dbd_open(r->pool, r->server);
            if (acq->rec) {
                svr_cfg *svr = ap_get_module_config(r->server->module_config,
                                                    &dbd_module);
    
                ap_set_module_config(r->request_config, &dbd_module, acq);
                if (svr->cfg->persist) {
                    acq->reslist = svr->group->reslist;
                    apr_pool_cleanup_register(r->pool, acq, dbd_release,
                                              apr_pool_cleanup_null);
                }
            }
        }
    
        return acq->rec;
    }
    
    DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_cacquire(conn_rec *c)
    {
        dbd_acquire_t *acq = ap_get_module_config(c->conn_config, &dbd_module);
    
        if (!acq) {
            acq = apr_palloc(c->pool, sizeof(dbd_acquire_t));
            acq->rec = ap_dbd_open(c->pool, c->base_server);
            if (acq->rec) {
                svr_cfg *svr = ap_get_module_config(c->base_server->module_config,
                                                    &dbd_module);
    
                ap_set_module_config(c->conn_config, &dbd_module, acq);
                if (svr->cfg->persist) {
                    acq->reslist = svr->group->reslist;
                    apr_pool_cleanup_register(c->pool, acq, dbd_release,
                                              apr_pool_cleanup_null);
                }
            }
        }
    
        return acq->rec;
    }
    #else
    DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_acquire(request_rec *r)
    {
        ap_dbd_t *rec;
    
        while (!ap_is_initial_req(r)) {
            if (r->prev) {
                r = r->prev;
            }
            else if (r->main) {
                r = r->main;
            }
        }
    
        rec = ap_get_module_config(r->request_config, &dbd_module);
        if (!rec) {
            rec = ap_dbd_open(r->pool, r->server);
            if (rec) {
                ap_set_module_config(r->request_config, &dbd_module, rec);
            }
        }
    
        return rec;
    }
    
    DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_cacquire(conn_rec *c)
    {
        ap_dbd_t *rec = ap_get_module_config(c->conn_config, &dbd_module);
    
        if (!rec) {
            rec = ap_dbd_open(c->pool, c->base_server);
            if (rec) {
                ap_set_module_config(c->conn_config, &dbd_module, rec);
            }
        }
    
        return rec;
    }
    #endif
    
    static void dbd_hooks(apr_pool_t *pool)
    {
        ap_hook_pre_config(dbd_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_config(dbd_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_child_init(dbd_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    
        APR_REGISTER_OPTIONAL_FN(ap_dbd_prepare);
        APR_REGISTER_OPTIONAL_FN(ap_dbd_open);
        APR_REGISTER_OPTIONAL_FN(ap_dbd_close);
        APR_REGISTER_OPTIONAL_FN(ap_dbd_acquire);
        APR_REGISTER_OPTIONAL_FN(ap_dbd_cacquire);
    
        APR_OPTIONAL_HOOK(dbd, post_connect, dbd_init_sql_init,
                          NULL, NULL, APR_HOOK_MIDDLE);
    
        apr_dbd_init(pool);
    }
    
    AP_DECLARE_MODULE(dbd) = {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        create_dbd_config,
        merge_dbd_config,
        dbd_cmds,
        dbd_hooks
    };
    
    �������������httpd-2.4.64/modules/database/NWGNUmakefile���������������������������������������������������������0000664�0001751�0001751�00000010433�11540562746�020370� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= moddbd
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) DBD Module
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= DBD 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	=
    
    #
    # 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)/moddbd.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_dbd.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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@httpd.imp \
    	@libc.imp \
    	$(EOLIST)
    
    #
    # Any symbols exported to here
    #
    FILES_nlm_exports = \
    	dbd_module \
    	ap_dbd_open \
    	ap_dbd_close \
    	ap_dbd_acquire \
    	ap_dbd_cacquire \
    	ap_dbd_prepare \
    	$(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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/mod_dbd.dep�����������������������������������������������������������0000664�0001751�0001751�00000004100�12674411515�020121� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_dbd.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_dbd.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_dbd.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_reslist.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_lib.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	".\mod_dbd.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/database/mod_dbd.dsp�����������������������������������������������������������0000664�0001751�0001751�00000010675�10551346420�020147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="mod_dbd" - 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_dbd - 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_dbd.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_dbd.mak" CFG="mod_dbd - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "mod_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE "mod_dbd - 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_dbd - 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 "DBD_DECLARE_EXPORT" /Fd"Release\mod_dbd_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 /fo"Release/mod_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dbd.so" /d LONG_NAME="dbd_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dbd.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "mod_dbd - 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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DBD_DECLARE_EXPORT" /Fd"Debug\mod_dbd_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 /fo"Debug/mod_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dbd.so" /d LONG_NAME="dbd_module for Apache"
    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 /out:".\Debug\mod_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dbd.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dbd.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_dbd.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "mod_dbd - Win32 Release"
    # Name "mod_dbd - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\mod_dbd.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\mod_dbd.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������httpd-2.4.64/modules/echo/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015222� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/echo/mod_echo.mak��������������������������������������������������������������0000664�0001751�0001751�00000023015�12701473373�017467� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_echo.dsp
    !IF "$(CFG)" == ""
    CFG=mod_echo - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_echo - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_echo - Win32 Release" && "$(CFG)" != "mod_echo - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_echo - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_echo.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_echo.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_echo.obj"
    	-@erase "$(INTDIR)\mod_echo.res"
    	-@erase "$(INTDIR)\mod_echo_src.idb"
    	-@erase "$(INTDIR)\mod_echo_src.pdb"
    	-@erase "$(OUTDIR)\mod_echo.exp"
    	-@erase "$(OUTDIR)\mod_echo.lib"
    	-@erase "$(OUTDIR)\mod_echo.pdb"
    	-@erase "$(OUTDIR)\mod_echo.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_echo_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_echo.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_echo.so" /d LONG_NAME="echo_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_echo.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_echo.pdb" /debug /out:"$(OUTDIR)\mod_echo.so" /implib:"$(OUTDIR)\mod_echo.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_echo.obj" \
    	"$(INTDIR)\mod_echo.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_echo.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_echo.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_echo.so"
       if exist .\Release\mod_echo.so.manifest mt.exe -manifest .\Release\mod_echo.so.manifest -outputresource:.\Release\mod_echo.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_echo - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_echo.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_echo.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_echo.obj"
    	-@erase "$(INTDIR)\mod_echo.res"
    	-@erase "$(INTDIR)\mod_echo_src.idb"
    	-@erase "$(INTDIR)\mod_echo_src.pdb"
    	-@erase "$(OUTDIR)\mod_echo.exp"
    	-@erase "$(OUTDIR)\mod_echo.lib"
    	-@erase "$(OUTDIR)\mod_echo.pdb"
    	-@erase "$(OUTDIR)\mod_echo.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_echo_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_echo.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_echo.so" /d LONG_NAME="echo_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_echo.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_echo.pdb" /debug /out:"$(OUTDIR)\mod_echo.so" /implib:"$(OUTDIR)\mod_echo.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_echo.obj" \
    	"$(INTDIR)\mod_echo.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_echo.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_echo.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_echo.so"
       if exist .\Debug\mod_echo.so.manifest mt.exe -manifest .\Debug\mod_echo.so.manifest -outputresource:.\Debug\mod_echo.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_echo.dep")
    !INCLUDE "mod_echo.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_echo.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_echo - Win32 Release" || "$(CFG)" == "mod_echo - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_echo - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\echo"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\echo"
    
    !ELSEIF  "$(CFG)" == "mod_echo - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\echo"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\echo"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_echo - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\echo"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\echo"
    
    !ELSEIF  "$(CFG)" == "mod_echo - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\echo"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\echo"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_echo - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\echo"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\echo"
    
    !ELSEIF  "$(CFG)" == "mod_echo - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\echo"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\echo"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_echo - Win32 Release"
    
    
    "$(INTDIR)\mod_echo.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_echo.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_echo.so" /d LONG_NAME="echo_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_echo - Win32 Debug"
    
    
    "$(INTDIR)\mod_echo.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_echo.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_echo.so" /d LONG_NAME="echo_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_echo.c
    
    "$(INTDIR)\mod_echo.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/echo/mod_echo.dsp��������������������������������������������������������������0000664�0001751�0001751�00000010467�10551346420�017505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_echo.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_echo.so" /d LONG_NAME="echo_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_echo.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_echo.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_echo.so" /d LONG_NAME="echo_module for Apache"
    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 /out:".\Debug\mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_echo.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/echo/mod_echo.c����������������������������������������������������������������0000664�0001751�0001751�00000015602�13350264472�017143� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "http_core.h"
    #include "http_log.h"
    
    #include "apr_buckets.h"
    #include "apr_strings.h"
    #include "util_filter.h"
    #include "scoreboard.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 apr_status_t brigade_peek(apr_bucket_brigade *bbIn,
                                     char *buff, apr_size_t bufflen)
    {
        apr_bucket *b;
        apr_size_t readbytes = 0;
    
        if (bufflen--)
            /* compensate for NULL */
            *buff = '\0';
        else
            return APR_EGENERAL;
    
        if (APR_BRIGADE_EMPTY(bbIn))
            return APR_EGENERAL;
    
        b = APR_BRIGADE_FIRST(bbIn);
    
        while ((b != APR_BRIGADE_SENTINEL(bbIn)) && (readbytes < bufflen)) {
            const char *pos;
            const char *str;
            apr_size_t len;
            apr_status_t rv;
    
            if ((rv = apr_bucket_read(b, &str, &len, APR_NONBLOCK_READ))
                    != APR_SUCCESS)
                return rv;
    
            if ((pos = memchr(str, APR_ASCII_LF, len)) != NULL)
                len = pos - str;
            if (len > bufflen - readbytes)
                len = bufflen - readbytes;
            memcpy (buff + readbytes, str, len);
            readbytes += len;
            buff[readbytes] = '\0';
    
            b = APR_BUCKET_NEXT(b);
        }
        return APR_SUCCESS;
    }
    
    
    static int update_echo_child_status(ap_sb_handle_t *sbh,
                                        int status, conn_rec *c,
                                        apr_bucket_brigade *last_echoed)
    {
        worker_score *ws = ap_get_scoreboard_worker(sbh);
        int old_status = ws->status;
    
        ws->status = status;
    
        if (!ap_extended_status)
            return old_status;
    
        ws->last_used = apr_time_now();
    
        /* initial pass only, please - in the name of efficiency */
        if (c) {
            apr_cpystrn(ws->client64,
                        ap_get_remote_host(c, c->base_server->lookup_defaults,
                                           REMOTE_NOLOOKUP, NULL),
                        sizeof(ws->client64));
            apr_cpystrn(ws->vhost, c->base_server->server_hostname,
                        sizeof(ws->vhost));
            /* Deliberate trailing space - filling in string on WRITE passes */
            apr_cpystrn(ws->request, "ECHO ", sizeof(ws->request));
        }
    
        /* each subsequent WRITE pass, let's update what we echoed */
        if (last_echoed) {
            brigade_peek(last_echoed, ws->request + sizeof("ECHO ") - 1,
                         sizeof(ws->request) - sizeof("ECHO ") + 1);
        }
    
        return old_status;
    }
    
    static int process_echo_connection(conn_rec *c)
    {
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_socket_t *csd = NULL;
        EchoConfig *pConfig = ap_get_module_config(c->base_server->module_config,
                                                   &echo_module);
    
        if (!pConfig->bEnabled) {
            return DECLINED;
        }
    
        ap_time_process_request(c->sbh, START_PREQUEST);
        update_echo_child_status(c->sbh, SERVER_BUSY_READ, c, NULL);
    
        bb = apr_brigade_create(c->pool, c->bucket_alloc);
    
        for ( ; ; ) {
            apr_status_t rv;
    
            /* 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_cleanup(bb);
                if (!APR_STATUS_IS_EOF(rv) && ! APR_STATUS_IS_TIMEUP(rv))
                    ap_log_error(APLOG_MARK, APLOG_INFO, rv, c->base_server, APLOGNO(01611)
                                 "ProtocolEcho: Failure reading from %s",
                                 c->client_ip);
                break;
            }
    
            /* Something horribly wrong happened.  Someone didn't block! */
            if (APR_BRIGADE_EMPTY(bb)) {
                ap_log_error(APLOG_MARK, APLOG_INFO, rv, c->base_server, APLOGNO(01612)
                             "ProtocolEcho: Error - read empty brigade from %s!",
                             c->client_ip);
                break;
            }
    
            if (!csd) {
                csd = ap_get_conn_socket(c);
                apr_socket_timeout_set(csd, c->base_server->keep_alive_timeout);
            }
    
            update_echo_child_status(c->sbh, SERVER_BUSY_WRITE, NULL, bb);
    
            /* Make sure the data is flushed to the client */
            b = apr_bucket_flush_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, b);
            rv = ap_pass_brigade(c->output_filters, bb);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_INFO, rv, c->base_server, APLOGNO(01613)
                             "ProtocolEcho: Failure writing to %s",
                             c->client_ip);
                break;
            }
            apr_brigade_cleanup(bb);
    
            /* Announce our intent to loop */
            update_echo_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, NULL, NULL);
        }
        apr_brigade_destroy(bb);
        ap_time_process_request(c->sbh, STOP_PREQUEST);
        update_echo_child_status(c->sbh, SERVER_CLOSING, c, NULL);
        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);
    }
    
    AP_DECLARE_MODULE(echo) = {
        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 */
    };
    ������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/echo/NWGNUmakefile�������������������������������������������������������������0000664�0001751�0001751�00000010305�11540562746�017540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/echo/config.m4�����������������������������������������������������������������0000664�0001751�0001751�00000000334�11607365420�016723� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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, , , )
    
    APACHE_MODPATH_FINISH
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/echo/.indent.pro���������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�017276� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/echo/mod_echo.dep��������������������������������������������������������������0000664�0001751�0001751�00000003751�12674411515�017473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_echo.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_echo.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\scoreboard.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    �����������������������httpd-2.4.64/modules/echo/Makefile.in���������������������������������������������������������������0000664�0001751�0001751�00000000051�10150161574�017251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016237� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/mod_dumpio.c���������������������������������������������������������0000664�0001751�0001751�00000021067�13262704726�020544� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_strings.h"
    
    module AP_MODULE_DECLARE_DATA dumpio_module ;
    
    typedef struct dumpio_conf_t {
        int enable_input;
        int enable_output;
    } dumpio_conf_t;
    
    /* consider up to 80 additional characters, and factor the longest
     * line length of all \xNN sequences; log_error cannot record more
     * than MAX_STRING_LEN characters.
     */
    #define dumpio_MAX_STRING_LEN (MAX_STRING_LEN / 4 - 80)
    
    /*
     * 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, dumpio_conf_t *ptr)
    {
        conn_rec *c = f->c;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE7, 0, c,
                      "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)))
        {
    #if APR_CHARSET_EBCDIC
            char xlatebuf[dumpio_MAX_STRING_LEN + 1];
    #endif
            const char *buf;
            apr_size_t nbytes;
            apr_status_t rv = apr_bucket_read(b, &buf, &nbytes, APR_BLOCK_READ);
    
            if (rv == APR_SUCCESS)
            {
                while (nbytes)
                {
                    apr_size_t logbytes = nbytes;
                    if (logbytes > dumpio_MAX_STRING_LEN)
                        logbytes = dumpio_MAX_STRING_LEN;
                    nbytes -= logbytes;
    
    #if APR_CHARSET_EBCDIC
                    memcpy(xlatebuf, buf, logbytes);
                    ap_xlate_proto_from_ascii(xlatebuf, logbytes);
                    xlatebuf[logbytes] = '\0';
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE7, 0, c,
                                  "mod_dumpio:  %s (%s-%s): %s", f->frec->name,
                                  (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data",
                                  b->type->name, xlatebuf);
    #else
                    /* XXX: Seriously flawed; we do not pay attention to embedded
                     * \0's in the request body, these should be escaped; however,
                     * the logging function already performs a significant amount
                     * of escaping, and so any escaping would be double-escaped.
                     * The coding solution is to throw away the current logic
                     * within ap_log_error, and introduce new vformatter %-escapes
                     * for escaping text, and for binary text (fixed len strings).
                     */
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE7, 0, c,
                                  "mod_dumpio:  %s (%s-%s): %.*s", f->frec->name,
                                  (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data",
                                  b->type->name, (int)logbytes, buf);
    #endif
                    buf += logbytes;
                }
            }
            else {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE7, rv, c,
                              "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;
        dumpio_conf_t *ptr = f->ctx;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE7, 0, c,
                      "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, ptr);
            }
        }
        else {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE7, 0, c,
                          "mod_dumpio: %s - %d", f->frec->name, ret) ;
            return 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;
        dumpio_conf_t *ptr = f->ctx;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE7, 0, c, "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, ptr);
        }
    
        return ap_pass_brigade(f->next, bb) ;
    }
    
    static int dumpio_pre_conn(conn_rec *c, void *csd)
    {
        dumpio_conf_t *ptr;
    
        if (!APLOGctrace7(c)) {
            /* Nothing to do below TRACE7 */
            return DECLINED;
        }
    
        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", ptr, NULL, c);
        if (ptr->enable_output)
            ap_add_output_filter("DUMPIO_OUT", ptr, 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 = 0;
        ptr->enable_output = 0;
        return ptr;
    }
    
    static const char *dumpio_enable_input(cmd_parms *cmd, void *dummy, int arg)
    {
        dumpio_conf_t *ptr = 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 = 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 }
    };
    
    AP_DECLARE_MODULE(dumpio) = {
            STANDARD20_MODULE_STUFF,
            NULL,                   /* create per-dir    config structures */
            NULL,                   /* merge  per-dir    config structures */
            dumpio_create_sconfig,  /* create per-server config structures */
            NULL,                   /* merge  per-server config structures */
            dumpio_cmds,            /* table of config file commands       */
            dumpio_register_hooks   /* register hooks                      */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/mod_bucketeer.dep����������������������������������������������������0000664�0001751�0001751�00000003621�12674411515�021537� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_bucketeer.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_bucketeer.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\http_protocol.h"\
    	"..\..\include\http_request.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_dso.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_global_mutex.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_portable.h"\
    	"..\..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_shm.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/mod_bucketeer.mak����������������������������������������������������0000664�0001751�0001751�00000024001�12701473373�021533� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_bucketeer.dsp
    !IF "$(CFG)" == ""
    CFG=mod_bucketeer - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_bucketeer - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_bucketeer - Win32 Release" && "$(CFG)" != "mod_bucketeer - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_bucketeer - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_bucketeer.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_bucketeer.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_bucketeer.obj"
    	-@erase "$(INTDIR)\mod_bucketeer.res"
    	-@erase "$(INTDIR)\mod_bucketeer_src.idb"
    	-@erase "$(INTDIR)\mod_bucketeer_src.pdb"
    	-@erase "$(OUTDIR)\mod_bucketeer.exp"
    	-@erase "$(OUTDIR)\mod_bucketeer.lib"
    	-@erase "$(OUTDIR)\mod_bucketeer.pdb"
    	-@erase "$(OUTDIR)\mod_bucketeer.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_bucketeer_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_bucketeer.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_bucketeer.so" /d LONG_NAME="bucketeer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_bucketeer.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_bucketeer.pdb" /debug /out:"$(OUTDIR)\mod_bucketeer.so" /implib:"$(OUTDIR)\mod_bucketeer.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_bucketeer.obj" \
    	"$(INTDIR)\mod_bucketeer.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_bucketeer.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_bucketeer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_bucketeer.so"
       if exist .\Release\mod_bucketeer.so.manifest mt.exe -manifest .\Release\mod_bucketeer.so.manifest -outputresource:.\Release\mod_bucketeer.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_bucketeer - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_bucketeer.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_bucketeer.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_bucketeer.obj"
    	-@erase "$(INTDIR)\mod_bucketeer.res"
    	-@erase "$(INTDIR)\mod_bucketeer_src.idb"
    	-@erase "$(INTDIR)\mod_bucketeer_src.pdb"
    	-@erase "$(OUTDIR)\mod_bucketeer.exp"
    	-@erase "$(OUTDIR)\mod_bucketeer.lib"
    	-@erase "$(OUTDIR)\mod_bucketeer.pdb"
    	-@erase "$(OUTDIR)\mod_bucketeer.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_bucketeer_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_bucketeer.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_bucketeer.so" /d LONG_NAME="bucketeer_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_bucketeer.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_bucketeer.pdb" /debug /out:"$(OUTDIR)\mod_bucketeer.so" /implib:"$(OUTDIR)\mod_bucketeer.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_bucketeer.obj" \
    	"$(INTDIR)\mod_bucketeer.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_bucketeer.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_bucketeer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_bucketeer.so"
       if exist .\Debug\mod_bucketeer.so.manifest mt.exe -manifest .\Debug\mod_bucketeer.so.manifest -outputresource:.\Debug\mod_bucketeer.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_bucketeer.dep")
    !INCLUDE "mod_bucketeer.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_bucketeer.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_bucketeer - Win32 Release" || "$(CFG)" == "mod_bucketeer - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_bucketeer - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\debugging"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ELSEIF  "$(CFG)" == "mod_bucketeer - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\debugging"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_bucketeer - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\debugging"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ELSEIF  "$(CFG)" == "mod_bucketeer - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\debugging"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_bucketeer - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\debugging"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\debugging"
    
    !ELSEIF  "$(CFG)" == "mod_bucketeer - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\debugging"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\debugging"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_bucketeer - Win32 Release"
    
    
    "$(INTDIR)\mod_bucketeer.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_bucketeer.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_bucketeer.so" /d LONG_NAME="bucketeer_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_bucketeer - Win32 Debug"
    
    
    "$(INTDIR)\mod_bucketeer.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_bucketeer.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_bucketeer.so" /d LONG_NAME="bucketeer_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_bucketeer.c
    
    "$(INTDIR)\mod_bucketeer.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/mod_dumpio.dep�������������������������������������������������������0000664�0001751�0001751�00000003366�12674411515�021071� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by mod_dumpio.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    
    .\mod_dumpio.c : \
    	"..\..\include\ap_config.h"\
    	"..\..\include\ap_config_layout.h"\
    	"..\..\include\ap_expr.h"\
    	"..\..\include\ap_hooks.h"\
    	"..\..\include\ap_mmn.h"\
    	"..\..\include\ap_regex.h"\
    	"..\..\include\ap_release.h"\
    	"..\..\include\apache_noprobes.h"\
    	"..\..\include\http_config.h"\
    	"..\..\include\http_connection.h"\
    	"..\..\include\http_core.h"\
    	"..\..\include\http_log.h"\
    	"..\..\include\httpd.h"\
    	"..\..\include\os.h"\
    	"..\..\include\util_cfgtree.h"\
    	"..\..\include\util_filter.h"\
    	"..\..\srclib\apr-util\include\apr_buckets.h"\
    	"..\..\srclib\apr-util\include\apr_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_optional.h"\
    	"..\..\srclib\apr-util\include\apr_optional_hooks.h"\
    	"..\..\srclib\apr-util\include\apr_uri.h"\
    	"..\..\srclib\apr-util\include\apu.h"\
    	"..\..\srclib\apr\include\apr.h"\
    	"..\..\srclib\apr\include\apr_allocator.h"\
    	"..\..\srclib\apr\include\apr_errno.h"\
    	"..\..\srclib\apr\include\apr_file_info.h"\
    	"..\..\srclib\apr\include\apr_file_io.h"\
    	"..\..\srclib\apr\include\apr_general.h"\
    	"..\..\srclib\apr\include\apr_hash.h"\
    	"..\..\srclib\apr\include\apr_inherit.h"\
    	"..\..\srclib\apr\include\apr_mmap.h"\
    	"..\..\srclib\apr\include\apr_network_io.h"\
    	"..\..\srclib\apr\include\apr_poll.h"\
    	"..\..\srclib\apr\include\apr_pools.h"\
    	"..\..\srclib\apr\include\apr_ring.h"\
    	"..\..\srclib\apr\include\apr_strings.h"\
    	"..\..\srclib\apr\include\apr_tables.h"\
    	"..\..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\..\srclib\apr\include\apr_thread_proc.h"\
    	"..\..\srclib\apr\include\apr_time.h"\
    	"..\..\srclib\apr\include\apr_user.h"\
    	"..\..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/config.m4������������������������������������������������������������0000664�0001751�0001751�00000000332�11463657631�017746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    APACHE_MODPATH_INIT(debugging)
    
    APACHE_MODULE(bucketeer, buckets manipulation filter.  Useful only for developers and testing purposes., , , no)
    APACHE_MODULE(dumpio, I/O dump filter, , , most)
    
    APACHE_MODPATH_FINISH
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/NWGNUmoddumpio�������������������������������������������������������0000664�0001751�0001751�00000010145�11674073627�021002� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= moddumpio
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) DumpIO 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	=
    
    #
    # 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)/$(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_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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/NWGNUmakefile��������������������������������������������������������0000664�0001751�0001751�00000007756�11711770464�020573� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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)/modbucketeer.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 = \
    	$(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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ������������������httpd-2.4.64/modules/debugging/mod_bucketeer.c������������������������������������������������������0000664�0001751�0001751�00000013602�11402752006�021200� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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->passdelimiter) {
                            apr_status_t rv;
    
                            rv = ap_pass_brigade(f->next, ctx->bb);
                            if (rv) {
                                return rv;
                            }
                        }
                    }
                }
                /* 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}
    };
    
    AP_DECLARE_MODULE(bucketeer) = {
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        create_bucketeer_server_config,
        NULL,
        bucketeer_filter_cmds,
        register_hooks
    };
    ������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/Makefile.in����������������������������������������������������������0000664�0001751�0001751�00000000267�10453255255�020305� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/mod_bucketeer.dsp����������������������������������������������������0000664�0001751�0001751�00000010715�10551346420�021551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_bucketeer.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_bucketeer.so" /d LONG_NAME="bucketeer_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_bucketeer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_bucketeer.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_bucketeer.so" /d LONG_NAME="bucketeer_module for Apache"
    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 /out:".\Debug\mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_bucketeer.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������httpd-2.4.64/modules/debugging/README���������������������������������������������������������������0000664�0001751�0001751�00000000041�10453255255�017106� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������debugging modules for Apache 2.x
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/mod_dumpio.mak�������������������������������������������������������0000664�0001751�0001751�00000023371�12701473373�021070� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on mod_dumpio.dsp
    !IF "$(CFG)" == ""
    CFG=mod_dumpio - Win32 Release
    !MESSAGE No configuration specified. Defaulting to mod_dumpio - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "mod_dumpio - Win32 Release" && "$(CFG)" != "mod_dumpio - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dumpio - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dumpio.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_dumpio.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_dumpio.obj"
    	-@erase "$(INTDIR)\mod_dumpio.res"
    	-@erase "$(INTDIR)\mod_dumpio_src.idb"
    	-@erase "$(INTDIR)\mod_dumpio_src.pdb"
    	-@erase "$(OUTDIR)\mod_dumpio.exp"
    	-@erase "$(OUTDIR)\mod_dumpio.lib"
    	-@erase "$(OUTDIR)\mod_dumpio.pdb"
    	-@erase "$(OUTDIR)\mod_dumpio.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dumpio_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dumpio.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dumpio.so" /d LONG_NAME="dumpio_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dumpio.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dumpio.pdb" /debug /out:"$(OUTDIR)\mod_dumpio.so" /implib:"$(OUTDIR)\mod_dumpio.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_dumpio.obj" \
    	"$(INTDIR)\mod_dumpio.res" \
    	"..\..\srclib\apr\Release\libapr-1.lib" \
    	"..\..\srclib\apr-util\Release\libaprutil-1.lib" \
    	"..\..\Release\libhttpd.lib"
    
    "$(OUTDIR)\mod_dumpio.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\mod_dumpio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dumpio.so"
       if exist .\Release\mod_dumpio.so.manifest mt.exe -manifest .\Release\mod_dumpio.so.manifest -outputresource:.\Release\mod_dumpio.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "mod_dumpio - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\mod_dumpio.so" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_dumpio.so" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\mod_dumpio.obj"
    	-@erase "$(INTDIR)\mod_dumpio.res"
    	-@erase "$(INTDIR)\mod_dumpio_src.idb"
    	-@erase "$(INTDIR)\mod_dumpio_src.pdb"
    	-@erase "$(OUTDIR)\mod_dumpio.exp"
    	-@erase "$(OUTDIR)\mod_dumpio.lib"
    	-@erase "$(OUTDIR)\mod_dumpio.pdb"
    	-@erase "$(OUTDIR)\mod_dumpio.so"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_dumpio_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_dumpio.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dumpio.so" /d LONG_NAME="dumpio_module for Apache" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_dumpio.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_dumpio.pdb" /debug /out:"$(OUTDIR)\mod_dumpio.so" /implib:"$(OUTDIR)\mod_dumpio.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so 
    LINK32_OBJS= \
    	"$(INTDIR)\mod_dumpio.obj" \
    	"$(INTDIR)\mod_dumpio.res" \
    	"..\..\srclib\apr\Debug\libapr-1.lib" \
    	"..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"..\..\Debug\libhttpd.lib"
    
    "$(OUTDIR)\mod_dumpio.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\mod_dumpio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_dumpio.so"
       if exist .\Debug\mod_dumpio.so.manifest mt.exe -manifest .\Debug\mod_dumpio.so.manifest -outputresource:.\Debug\mod_dumpio.so;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("mod_dumpio.dep")
    !INCLUDE "mod_dumpio.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "mod_dumpio.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "mod_dumpio - Win32 Release" || "$(CFG)" == "mod_dumpio - Win32 Debug"
    
    !IF  "$(CFG)" == "mod_dumpio - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\modules\debugging"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ELSEIF  "$(CFG)" == "mod_dumpio - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\modules\debugging"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dumpio - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\..\modules\debugging"
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ELSEIF  "$(CFG)" == "mod_dumpio - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\..\modules\debugging"
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\modules\debugging"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "mod_dumpio - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd ".\modules\debugging"
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd ".\modules\debugging"
    
    !ELSEIF  "$(CFG)" == "mod_dumpio - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd ".\modules\debugging"
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd ".\..\.."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd ".\modules\debugging"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "mod_dumpio - Win32 Release"
    
    
    "$(INTDIR)\mod_dumpio.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dumpio.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_dumpio.so" /d LONG_NAME="dumpio_module for Apache" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "mod_dumpio - Win32 Debug"
    
    
    "$(INTDIR)\mod_dumpio.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\mod_dumpio.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_dumpio.so" /d LONG_NAME="dumpio_module for Apache" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\mod_dumpio.c
    
    "$(INTDIR)\mod_dumpio.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/NWGNUmodbucketeer����������������������������������������������������0000664�0001751�0001751�00000010164�11674073627�021457� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(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	= modbucketeer
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) Bucketeer 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	=
    
    #
    # 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)/$(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_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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/debugging/mod_dumpio.dsp�������������������������������������������������������0000664�0001751�0001751�00000010563�10551346420�021076� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/mod_dumpio.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_dumpio.so" /d LONG_NAME="dumpio_module for Apache"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\mod_dumpio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /fo"Debug/mod_dumpio.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_dumpio.so" /d LONG_NAME="dumpio_module for Apache"
    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 /out:".\Debug\mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so
    # ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so
    # Begin Special Build Tool
    TargetPath=.\Debug\mod_dumpio.so
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !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=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/experimental/������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017001� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/experimental/Makefile.in�������������������������������������������������������0000664�0001751�0001751�00000000267�10150161574�021041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/experimental/NWGNUmakefile�����������������������������������������������������0000664�0001751�0001751�00000011043�11657403725�021317� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    #
    # If there is only one element to build it needs to be included twice
    # in the below target list.
    # Normally if there is only one element to be built within a
    # directory, the makefile for the single element would be called NWGNUmakefile.
    # But if there are multiples, the parent NWGNUmakefile must reference more
    # than one submakefile. Because the experimental directory might vary in the
    # number of submakefiles, but for the moment only contains one, we reference
    # it twice to allow it parent NWGNUmakefile to work properly.  If another
    # submakefile is added, the extra reference to the first NLM should be removed.
    TARGET_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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/experimental/.indent.pro�������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�021055� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/experimental/config.m4���������������������������������������������������������0000664�0001751�0001751�00000000072�10723032512�020470� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    APACHE_MODPATH_INIT(experimental)
    
    APACHE_MODPATH_FINISH
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/README�������������������������������������������������������������������������0000664�0001751�0001751�00000003240�12602235527�015155� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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.
    
    database/
      The apache DBD framework manages connections to SQL backends efficiently.
    
    cluster/
      Modules for working with multiple servers.
    
    dav/
      This directory houses modules that implement WebDAV functionality.
    
    echo/
    
    examples/
      This directory contains some sample code that should help you on your
      way to develop your own Apache modules.  
    
    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.
    
    http2/
      This directory houses modules that provide HTTP/2 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.  
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/config7.m4���������������������������������������������������������������������0000664�0001751�0001751�00000004115�12077512322�016072� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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/<module-type> directory.),
      [
        withval=`echo $withval | sed -e 's/,/ /g'`
        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<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
          else
            cat >>$modpath_current/modules.mk.tmp<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    EOF
            cat $modpath_current/modules.mk >> $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
      ],
      [ AC_MSG_RESULT(none) 
      ])
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/Makefile.in��������������������������������������������������������������������0000664�0001751�0001751�00000000147�10150161574�016341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    SUBDIRS = $(MODULE_DIRS)
    CLEAN_SUBDIRS = $(MODULE_CLEANDIRS)
    
    include $(top_builddir)/build/rules.mk
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/modules/NWGNUmakefile������������������������������������������������������������������0000664�0001751�0001751�00000005040�12757564422�016626� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # To build with exerimental modules set the environment
    #  variable WITH_EXPERIMENTAL=1
    # To build with the mod_ssl module set the environment
    #  variable WITH_SSL=1
    # To build with the mod_lua module set the environment
    #  variable WITH_LUA=1
    # To build with the mod_http2 module set the environment
    #  variable WITH_HTTP2=1
    #
    # Check if LDAP is enabled in APR-UTIL
    #
    include $(AP_WORK)/build/NWGNUenvironment.inc
    ifeq "$(wildcard $(APRUTIL)/include/apr_ldap.h)" "$(APRUTIL)/include/apr_ldap.h"
    WITH_LDAP = $(shell $(AWK) '/^\#define APR_HAS_LDAP /{print $$3}' $(APRUTIL)/include/apr_ldap.h)
    else
    WITH_LDAP = 1
    ifneq "$(MAKECMDGOALS)" "clean"
    ifneq "$(findstring clobber_,$(MAKECMDGOALS))" "clobber_"
    WITH_LDAP = 0
    endif
    endif
    endif
    
    # If USE_STDSOCKETS is defined we always build mod_ssl
    ifdef USE_STDSOCKETS
    WITH_SSL = 1
    endif
    
    #
    # Declare the sub-directories to be built here
    #
    
    SUBDIRS = \
    	aaa \
    	cache \
    	cluster \
    	core \
    	dav/main \
    	dav/fs \
    	dav/lock \
    	echo \
    	examples \
    	generators \
    	loggers \
    	mappers \
    	metadata \
    	proxy \
    	filters \
    	database \
    	session \
    	slotmem \
    	$(EOLIST)
    
    # If WITH_LDAP and LDAPSDK have been defined then build the util_ldap module
    ifeq "$(WITH_LDAP)" "1"
    ifneq "$(LDAPSDK)" ""
    SUBDIRS += ldap
    endif
    endif
    
    # If WITH_SSL and OSSLSDK have been defined then build the mod_ssl module
    ifeq "$(WITH_SSL)" "1"
    ifneq "$(OSSLSDK)" ""
    SUBDIRS += ssl
    endif
    endif
    
    # If WITH_LUA and LUASRC have been defined then build the mod_lua module
    ifeq "$(WITH_LUA)" "1"
    ifneq "$(LUASRC)" ""
    SUBDIRS += lua
    endif
    endif
    
    # Allow the mod_http2 module to be built if WITH_HTTP2 is defined
    ifeq "$(WITH_HTTP2)" "1"
    ifneq "$(NGH2SRC)" ""
    SUBDIRS += http2
    endif
    endif
    
    # Allow the experimental modules to be built if WITH_EXPERIMENTAL is defined
    ifeq "$(WITH_EXPERIMENTAL)" "1"
    SUBDIRS += experimental
    endif
    
    # Allow the debugging modules to be built if WITH_DEBUGGING is defined
    ifeq "$(WITH_DEBUGGING)" "1"
    SUBDIRS += debugging
    endif
    
    # Allow the test modules to be built if WITH_TEST is defined
    ifeq "$(WITH_TEST)" "1"
    SUBDIRS += test
    endif
    
    #If the mod_edir directory exists then build the mod_edir module
    ifeq "$(wildcard $(STDMOD)/mod_edir)" "$(STDMOD)/mod_edir"
    SUBDIRS += mod_edir
    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
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/����������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�013613� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015263� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016324� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/�������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017610� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020352� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/hello.py�������������������������������������������������0000664�0001751�0001751�00000001525�14476620064�022031� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import os
    import json
    
    resp = {
        'https': os.getenv('HTTPS', ''),
        'host': os.getenv('X_HOST', '') if 'X_HOST' in os.environ else os.getenv('SERVER_NAME', ''),
        'server': os.getenv('SERVER_NAME', ''),
        'h2_original_host': os.getenv('H2_ORIGINAL_HOST', ''),
        'port': os.getenv('SERVER_PORT', ''),
        'protocol': os.getenv('SERVER_PROTOCOL', ''),
        'ssl_protocol': os.getenv('SSL_PROTOCOL', ''),
        'h2': os.getenv('HTTP2', ''),
        'h2push': os.getenv('H2PUSH', ''),
        'h2_stream_id': os.getenv('H2_STREAM_ID', ''),
        'x-forwarded-for': os.getenv('HTTP_X_FORWARDED_FOR', ''),
        'x-forwarded-host': os.getenv('HTTP_X_FORWARDED_HOST', ''),
        'x-forwarded-server': os.getenv('HTTP_X_FORWARDED_SERVER', ''),
    }
    
    print("Content-Type: application/json")
    print()
    print(json.JSONEncoder(indent=2).encode(resp))
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/xxx/�����������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�021201� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/xxx/test.json��������������������������������������������0000664�0001751�0001751�00000000025�14431664350�023044� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"name": "test.json"}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/ssi/�����������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�021150� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/ssi/include.inc������������������������������������������0000664�0001751�0001751�00000000022�14436122317�023251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Hello include<br>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/ssi/test.html��������������������������������������������0000664�0001751�0001751�00000000231�14436122317�023002� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html>
    <html>
    <head><meta charset="UTF-8"></head>
    <body>
        test<br>
        <!--#include virtual="./include.inc"-->
        hello<br>
    </body>
    </html>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/files/���������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�021454� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/files/empty.txt������������������������������������������0000664�0001751�0001751�00000000000�14107751520�023331� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/echohd.py������������������������������������������������0000664�0001751�0001751�00000000720�14424160200�022134� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os, sys
    from requestparser import get_request_params
    
    
    forms, files = get_request_params()
    name = forms['name'] if 'name' in forms else None
    
    if name:
        print("Status: 200")
        print("""\
    Content-Type: text/plain\n""")
        print("""%s: %s""" % (name, os.environ['HTTP_'+name]))
    else:
        print("Status: 400 Parameter Missing")
        print("""\
    Content-Type: text/html\n
    <html><body>
    <p>No name was specified</p>
    </body></html>""")
    
    
    ������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/necho.py�������������������������������������������������0000664�0001751�0001751�00000002572�14424160200�022005� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import time
    import os, sys
    from requestparser import get_request_params
    
    
    forms, files = get_request_params()
    status = '200 Ok'
    
    try:
        count = forms['count']
        text = forms['text']
        
        waitsec = float(forms['wait1']) if 'wait1' in forms else 0.0
        if waitsec > 0:
            time.sleep(waitsec)
        
        if int(count):
            print("Status: 200")
            print("""\
    Content-Type: text/plain\n""")
    
            waitsec = float(forms['wait2']) if 'wait2' in forms else 0.0
            if waitsec > 0:
                time.sleep(waitsec)
        
            i = 0;
            for i in range(0, int(count)):
                print("%s" % (text))
    
            waitsec = float(forms['wait3']) if 'wait3' in forms else 0.0
            if waitsec > 0:
                time.sleep(waitsec)
        
        else:
            print("Status: 400 Parameter Missing")
            print("""\
    Content-Type: text/html\n
        <html><body>
        <p>No count was specified: %s</p>
        </body></html>""" % (count))
    
    except KeyError as ex:
        print("Status: 200 Ok")
        print(f"""\
    Content-Type: text/html\n
        <html><body>uri: uri={os.environ['REQUEST_URI']} ct={os.environ['CONTENT_TYPE']} ex={ex}
        forms={forms}
        Echo <form method="POST" enctype="application/x-www-form-urlencoded">
        <input type="text" name="count">
        <input type="text" name="text">
        <button type="submit">Echo</button></form>
        </body></html>""")
        pass
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/alive.json�����������������������������������������������0000664�0001751�0001751�00000000053�14356741666�022353� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
        "host" : "cgi",
        "alive" : true
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/env.py���������������������������������������������������0000664�0001751�0001751�00000001571�14424160200�021477� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os, sys
    from requestparser import get_request_params
    
    
    forms, files = get_request_params()
    
    status = '200 Ok'
    
    try:
        ename = forms['name']
    
        # Test if the file was uploaded
        if ename is not None:
            val = os.environ[ename] if ename in os.environ else ""
            print("Status: 200")
            print("""\
    Content-Type: text/plain\n""")
            print(f"{ename}={val}")
    
        else:
            print("Status: 400 Parameter Missing")
            print("""\
    Content-Type: text/html\n
        <html><body>
        <p>No name was specified: name</p>
        </body></html>""")
    
    except KeyError:
        print("Status: 200 Ok")
        print("""\
    Content-Type: text/html\n
        <html><body>
        Echo <form method="POST" enctype="application/x-www-form-urlencoded">
        <input type="text" name="name">
        <button type="submit">submit</button></form>
        </body></html>""")
        pass
    
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/requestparser.py�����������������������������������������0000664�0001751�0001751�00000003361�14424160200�023613� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os
    import sys
    from urllib import parse
    import multipart # https://github.com/andrew-d/python-multipart (`apt install python3-multipart`)
    import shutil
    
    
    try:  # Windows needs stdio set for binary mode.
        import msvcrt
    
        msvcrt.setmode(0, os.O_BINARY)  # stdin  = 0
        msvcrt.setmode(1, os.O_BINARY)  # stdout = 1
    except ImportError:
        pass
    
    
    class FileItem:
    
        def __init__(self, mparse_item):
            self.item = mparse_item
    
        @property
        def file_name(self):
            return os.path.basename(self.item.file_name.decode())
    
        def save_to(self, destpath: str):
            fsrc = self.item.file_object
            fsrc.seek(0)
            with open(destpath, 'wb') as fd:
                shutil.copyfileobj(fsrc, fd)
    
    
    def get_request_params():
        oforms = {}
        ofiles = {}
        if "REQUEST_URI" in os.environ:
            qforms = parse.parse_qs(parse.urlsplit(os.environ["REQUEST_URI"]).query)
            for name, values in qforms.items():
                oforms[name] = values[0]
        if "CONTENT_TYPE" in os.environ:
            ctype = os.environ["CONTENT_TYPE"]
            if ctype == "application/x-www-form-urlencoded":
                s = sys.stdin.read()
                qforms = parse.parse_qs(s)
                for name, values in qforms.items():
                    oforms[name] = values[0]
            elif ctype.startswith("multipart/"):
                def on_field(field):
                    oforms[field.field_name.decode()] = field.value.decode()
                def on_file(file):
                    ofiles[file.field_name.decode()] = FileItem(file)
                multipart.parse_form(headers={"Content-Type": ctype},
                                     input_stream=sys.stdin.buffer,
                                     on_field=on_field, on_file=on_file)
        return oforms, ofiles
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/hecho.py�������������������������������������������������0000664�0001751�0001751�00000002057�14424160200�021775� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os, sys
    from requestparser import get_request_params
    
    
    forms, files = get_request_params()
    
    status = '200 Ok'
    
    try:
    
        # A nested FieldStorage instance holds the file
        name = forms['name']
        value = ''
        
        try:
            value = forms['value']
        except KeyError:
            value = os.environ.get("HTTP_"+name, "unset")
        
        # Test if a value was given
        if name:
            print("Status: 200")
            print("%s: %s" % (name, value,))
            print ("""\
    Content-Type: text/plain\n""")
    
        else:
            print("Status: 400 Parameter Missing")
            print("""\
    Content-Type: text/html\n
        <html><body>
        <p>No name and value was specified: %s %s</p>
        </body></html>""" % (name, value))
    
    except KeyError:
        print("Status: 200 Ok")
        print("""\
    Content-Type: text/html\n
        <html><body>
        Echo <form method="POST" enctype="application/x-www-form-urlencoded">
        <input type="text" name="name">
        <input type="text" name="value">
        <button type="submit">Echo</button></form>
        </body></html>""")
        pass
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/upload.py������������������������������������������������0000664�0001751�0001751�00000003010�14424160200�022161� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os
    import sys
    from requestparser import get_request_params
    
    
    forms, files = get_request_params()
    
    status = '200 Ok'
    
    # Test if the file was uploaded
    if 'file' in files:
        fitem = files['file']
        # strip leading path from file name to avoid directory traversal attacks
        fname = os.path.basename(fitem.file_name)
        fpath = f'{os.environ["DOCUMENT_ROOT"]}/files/{fname}'
        fitem.save_to(fpath)
        message = "The file %s was uploaded successfully" % (fname)
        print("Status: 201 Created")
        print("Content-Type: text/html")
        print("Location: %s://%s/files/%s" % (os.environ["REQUEST_SCHEME"], os.environ["HTTP_HOST"], fname))
        print("")
        print("<html><body><p>%s</p></body></html>" % (message))
    
    elif 'remove' in forms:
        remove = forms['remove']
        try:
            fname = os.path.basename(remove)
            os.remove('./files/' + fname)
            message = 'The file "' + fname + '" was removed successfully'
        except OSError as e:
            message = 'Error removing ' + fname + ': ' + e.strerror
            status = '404 File Not Found'
        print("Status: %s" % (status))
        print("""
    Content-Type: text/html
    
    <html><body>
    <p>%s</p>
    </body></html>""" % (message))
    
    else:
        message = '''\
            Upload File<form method="POST" enctype="multipart/form-data">
            <input type="file" name="file">
            <button type="submit">Upload</button></form>
            '''
        print("Status: %s" % (status))
        print("""\
    Content-Type: text/html
    
    <html><body>
    <p>%s</p>
    </body></html>""" % (message))
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/mnot164.py�����������������������������������������������0000664�0001751�0001751�00000000555�14424160200�022120� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os, sys
    from requestparser import get_request_params
    
    
    forms, files = get_request_params()
    text = forms['text'] if 'text' in forms else "a"
    count = int(forms['count']) if 'count' in forms else 77784
    
    print("Status: 200 OK")
    print("Content-Type: text/html")
    print()
    sys.stdout.flush()
    for _ in range(count):
        sys.stdout.write(text)
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/cgi/echo.py��������������������������������������������������0000664�0001751�0001751�00000000443�14401067034�021630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os, sys
    import multipart
    
    status = '200 Ok'
    
    content = ''
    for line in sys.stdin:
        content += line
        
    # Just echo what we get
    print("Status: 200")
    print(f"Request-Length: {len(content)}")
    print("Content-Type: application/data\n")
    sys.stdout.write(content)
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/noh2/��������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020456� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/noh2/alive.json����������������������������������������������0000664�0001751�0001751�00000000055�14107751520�022441� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
        "host" : "noh2",
        "alive" : true
    }
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/htdocs/noh2/index.html����������������������������������������������0000664�0001751�0001751�00000000222�14107751520�022437� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html>
        <head>
            <title>mod_h2 test site noh2</title>
        </head>
        <body>
            <h1>mod_h2 test site noh2</h1>
        </body>
    </html>
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_202_trailer.py�������������������������������������������������0000664�0001751�0001751�00000007524�14646040741�021766� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    def setup_data(env):
        s100 = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n"
        with open(os.path.join(env.gen_dir, "data-1k"), 'w') as f:
            for i in range(10):
                f.write(s100)
    
    
    # The trailer tests depend on "nghttp" as no other client seems to be able to send those
    # rare things.
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestTrailers:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            setup_data(env)
            conf = H2Conf(env, extras={
                f"cgi.{env.http_tld}": [
                    "<Location \"/h2test/trailer\">",
                    "  SetHandler h2test-trailer",
                    "</Location>"
                ],
            })
            conf.add_vhost_cgi(h2proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
    
        # check if the server survives a trailer or two
        def test_h2_202_01(self, env):
            url = env.mkurl("https", "cgi", "/echo.py")
            fpath = os.path.join(env.gen_dir, "data-1k")
            r = env.nghttp().upload(url, fpath, options=["--trailer", "test: 1"])
            assert r.response["status"] < 300
            assert len(r.response["body"]) == 1000
    
            r = env.nghttp().upload(url, fpath, options=["--trailer", "test: 1b", "--trailer", "XXX: test"])
            assert r.response["status"] < 300
            assert len(r.response["body"]) == 1000
    
        # check if the server survives a trailer without content-length
        def test_h2_202_02(self, env):
            url = env.mkurl("https", "cgi", "/echo.py")
            fpath = os.path.join(env.gen_dir, "data-1k")
            r = env.nghttp().upload(url, fpath, options=["--trailer", "test: 2", "--no-content-length"])
            assert r.response["status"] < 300
            assert len(r.response["body"]) == 1000
    
        # check if echoing request headers in response from GET works
        def test_h2_202_03(self, env):
            url = env.mkurl("https", "cgi", "/echohd.py?name=X")
            r = env.nghttp().get(url, options=["--header", "X: 3"])
            assert r.response["status"] < 300
            assert r.response["body"] == b"X: 3\n"
    
        # check if echoing request headers in response from POST works
        def test_h2_202_03b(self, env):
            url = env.mkurl("https", "cgi", "/echohd.py?name=X")
            r = env.nghttp().post_name(url, "Y", options=["--header", "X: 3b"])
            assert r.response["status"] < 300
            assert r.response["body"] == b"X: 3b\n"
    
        # check if echoing request headers in response from POST works, but trailers are not seen
        # This is the way CGI invocation works.
        def test_h2_202_04(self, env):
            url = env.mkurl("https", "cgi", "/echohd.py?name=X")
            r = env.nghttp().post_name(url, "Y", options=["--header", "X: 4a", "--trailer", "X: 4b"])
            assert r.response["status"] < 300
            assert r.response["body"] == b"X: 4a\n"
    
        # check that our h2test-trailer handler works
        def test_h2_202_10(self, env):
            url = env.mkurl("https", "cgi", "/h2test/trailer?1024")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            assert len(r.response["body"]) == 1024
            assert 'trailer' in r.response
            assert 'trailer-content-length' in r.response['trailer']
            assert r.response['trailer']['trailer-content-length'] == '1024'
    
        # check that trailers also for with empty bodies
        def test_h2_202_11(self, env):
            url = env.mkurl("https", "cgi", "/h2test/trailer?0")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            assert len(r.response["body"]) == 0, f'{r.response["body"]}'
            assert 'trailer' in r.response
            assert 'trailer-content-length' in r.response['trailer']
            assert r.response['trailer']['trailer-content-length'] == '0'
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/conftest.py���������������������������������������������������������0000664�0001751�0001751�00000002133�14643712504�020516� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import os
    
    import pytest
    import sys
    
    sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
    
    from .env import H2TestEnv
    
    
    def pytest_report_header(config, startdir):
        env = H2TestEnv()
        return f"mod_h2 [apache: {env.get_httpd_version()}, mpm: {env.mpm_module}, {env.prefix}]"
    
    
    @pytest.fixture(scope="package")
    def env(pytestconfig) -> H2TestEnv:
        level = logging.INFO
        console = logging.StreamHandler()
        console.setLevel(level)
        console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
        logging.getLogger('').addHandler(console)
        logging.getLogger('').setLevel(level=level)
        env = H2TestEnv(pytestconfig=pytestconfig)
        env.setup_httpd()
        env.apache_access_log_clear()
        env.httpd_error_log.clear_log()
        return env
    
    
    @pytest.fixture(autouse=True, scope="package")
    def _h2_package_scope(env):
        env.httpd_error_log.add_ignored_lognos([
            'AH10400',  # warning that 'enablereuse' has not effect in certain configs
            'AH00045',  # child did not exit in time, SIGTERM was sent
        ])
        yield
        assert env.apache_stop() == 0
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_100_conn_reuse.py����������������������������������������������0000664�0001751�0001751�00000005707�14643712504�022462� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestConnReuse:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_noh2().add_vhost_test1().add_vhost_cgi().install()
            assert env.apache_restart() == 0
    
        # make sure the protocol selection on the different hosts work as expected
        def test_h2_100_01(self, env):
            # this host defaults to h2, but we can request h1
            url = env.mkurl("https", "cgi", "/hello.py")
            assert "2" == env.curl_protocol_version( url )
            assert "1.1" == env.curl_protocol_version( url, options=[ "--http1.1" ] )
            
            # this host does not enable h2, it always falls back to h1
            url = env.mkurl("https", "noh2", "/hello.py")
            assert "1.1" == env.curl_protocol_version( url )
            assert "1.1" == env.curl_protocol_version( url, options=[ "--http2" ] )
    
        # access a ServerAlias, after using ServerName in SNI
        def test_h2_100_02(self, env):
            url = env.mkurl("https", "cgi", "/hello.py")
            hostname = ("cgi-alias.%s" % env.http_tld)
            r = env.curl_get(url, 5, options=["-H", f"Host: {hostname}"])
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            assert hostname == r.response["json"]["host"]
    
        # access another vhost, after using ServerName in SNI, that uses same SSL setup
        def test_h2_100_03(self, env):
            url = env.mkurl("https", "cgi", "/")
            hostname = ("test1.%s" % env.http_tld)
            r = env.curl_get(url, 5, options=[ "-H", "Host:%s" % hostname ])
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            assert "text/html" == r.response["header"]["content-type"]
    
        # access another vhost, after using ServerName in SNI, 
        # that has different SSL certificate. This triggers a 421 (misdirected request) response.
        def test_h2_100_04(self, env):
            url = env.mkurl("https", "cgi", "/hello.py")
            hostname = ("noh2.%s" % env.http_tld)
            r = env.curl_get(url, 5, options=[ "-H", "Host:%s" % hostname ])
            assert 421 == r.response["status"]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02032"   # Hostname provided via SNI and hostname provided via HTTP have no compatible SSL setup
                ]
            )
    
        # access an unknown vhost, after using ServerName in SNI
        def test_h2_100_05(self, env):
            url = env.mkurl("https", "cgi", "/hello.py")
            hostname = ("unknown.%s" % env.http_tld)
            r = env.curl_get(url, 5, options=[ "-H", "Host:%s" % hostname ])
            assert 421 == r.response["status"]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02032"   # Hostname provided via SNI and hostname provided via HTTP have no compatible SSL setup
                ]
            )
    ���������������������������������������������������������httpd-2.4.64/test/modules/http2/test_203_rfc9113.py�������������������������������������������������0000664�0001751�0001751�00000005124�14646040741�021407� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    from typing import List, Optional
    
    from pyhttpd.env import HttpdTestEnv
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestRfc9113:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_test1().install()
            assert env.apache_restart() == 0
    
        # by default, we accept leading/trailing ws in request fields
        def test_h2_203_01_ws_ignore(self, env):
            url = env.mkurl("https", "test1", "/")
            r = env.curl_get(url, options=['-H', 'trailing-space: must not  '])
            assert r.exit_code == 0, f'curl output: {r.stderr}'
            assert r.response["status"] == 200, f'curl output: {r.stdout}'
            r = env.curl_get(url, options=['-H', 'trailing-space: must not\t'])
            assert r.exit_code == 0, f'curl output: {r.stderr}'
            assert r.response["status"] == 200, f'curl output: {r.stdout}'
    
        # response header are also handled, but we strip ws before sending
        @pytest.mark.parametrize(["hvalue", "expvalue", "status", "lognos"], [
            ['"123"', '123', 200, None],
            ['"123 "', '123', 200, None],       # trailing space stripped
            ['"123\t"', '123', 200, None],     # trailing tab stripped
            ['" 123"', '123', 200, None],        # leading space is stripped
            ['"          123"', '123', 200, None],  # leading spaces are stripped
            ['"\t123"', '123', 200, None],       # leading tab is stripped
            ['"expr=%{unescape:123%0A 123}"', '', 500, ["AH02430"]],  # illegal char
            ['" \t "', '', 200, None],          # just ws
        ])
        def test_h2_203_02(self, env, hvalue, expvalue, status, lognos: Optional[List[str]]):
            hname = 'ap-test-007'
            conf = H2Conf(env, extras={
                f'test1.{env.http_tld}': [
                    '<Location /index.html>',
                    f'Header add {hname} {hvalue}',
                    '</Location>',
                ]
            })
            conf.add_vhost_test1(proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_get(url, options=['--http2'])
            if status == 500 and r.exit_code != 0:
                # in 2.4.x we fail late on control chars in a response
                # and RST_STREAM. That's also ok
                return
            assert r.response["status"] == status
            if int(status) < 400:
                assert r.response["header"][hname] == expvalue
            #
            if lognos is not None:
                env.httpd_error_log.ignore_recent(lognos = lognos)
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_008_ranges.py��������������������������������������������������0000664�0001751�0001751�00000020222�14643712504�021575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import json
    import logging
    import os
    import re
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    log = logging.getLogger(__name__)
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestRanges:
    
        LOGFILE = ""
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            TestRanges.LOGFILE = os.path.join(env.server_logs_dir, "test_008")
            TestRanges.SRCDIR = os.path.dirname(inspect.getfile(TestRanges))
            if os.path.isfile(TestRanges.LOGFILE):
                os.remove(TestRanges.LOGFILE)
            destdir = os.path.join(env.gen_dir, 'apache/htdocs/test1')
            env.make_data_file(indir=destdir, fname="data-100m", fsize=100*1024*1024)
            conf = H2Conf(env=env, extras={
                'base': [
                    'CustomLog logs/test_008 combined'
                ],
                f'test1.{env.http_tld}': [
                    '<Location /status>',
                    '  SetHandler server-status',
                    '</Location>',
                ]
            })
            conf.add_vhost_cgi()
            conf.add_vhost_test1()
            conf.install()
            assert env.apache_restart() == 0
    
        def test_h2_008_01(self, env):
            # issue: #203
            resource = "data-1k"
            full_length = 1000
            chunk = 200
            self.curl_upload_and_verify(env, resource, ["-v", "--http2"])
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", f"/files/{resource}?01full")
            r = env.curl_get(url, 5, options=["--http2"])
            assert r.response["status"] == 200
            url = env.mkurl("https", "cgi", f"/files/{resource}?01range")
            r = env.curl_get(url, 5, options=["--http1.1", "-H", "Range: bytes=0-{0}".format(chunk-1)])
            assert 206 == r.response["status"]
            assert chunk == len(r.response["body"].decode('utf-8'))
            r = env.curl_get(url, 5, options=["--http2", "-H", "Range: bytes=0-{0}".format(chunk-1)])
            assert 206 == r.response["status"]
            assert chunk == len(r.response["body"].decode('utf-8'))
            # Restart for logs to be flushed out
            assert env.apache_restart() == 0
            # now check what response lengths have actually been reported
            detected = {}
            for line in open(TestRanges.LOGFILE).readlines():
                e = json.loads(line)
                if e['request'] == f'GET /files/{resource}?01full HTTP/2.0':
                    assert e['bytes_rx_I'] > 0
                    assert e['bytes_resp_B'] == full_length
                    assert e['bytes_tx_O'] > full_length
                    detected['h2full'] = 1
                elif e['request'] == f'GET /files/{resource}?01range HTTP/2.0':
                    assert e['bytes_rx_I'] > 0
                    assert e['bytes_resp_B'] == chunk
                    assert e['bytes_tx_O'] > chunk
                    assert e['bytes_tx_O'] < chunk + 256 # response + frame stuff
                    detected['h2range'] = 1
                elif e['request'] == f'GET /files/{resource}?01range HTTP/1.1':
                    assert e['bytes_rx_I'] > 0         # input bytes received
                    assert e['bytes_resp_B'] == chunk  # response bytes sent (payload)
                    assert e['bytes_tx_O'] > chunk     # output bytes sent
                    detected['h1range'] = 1
            assert 'h1range' in detected, f'HTTP/1.1 range request not found in {TestRanges.LOGFILE}'
            assert 'h2range' in detected, f'HTTP/2 range request not found in {TestRanges.LOGFILE}'
            assert 'h2full' in detected, f'HTTP/2 full request not found in {TestRanges.LOGFILE}'
    
        def test_h2_008_02(self, env, repeat):
            path = '/002.jpg'
            res_len = 90364
            url = env.mkurl("https", "test1", f'{path}?02full')
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            h = r.response["header"]
            assert "accept-ranges" in h
            assert "bytes" == h["accept-ranges"]
            assert "content-length" in h
            clen = h["content-length"]
            assert int(clen) == res_len
            # get the first 1024 bytes of the resource, 206 status, but content-length as original
            url = env.mkurl("https", "test1", f'{path}?02range')
            r = env.curl_get(url, 5, options=["-H", "range: bytes=0-1023"])
            assert 206 == r.response["status"]
            assert "HTTP/2" == r.response["protocol"]
            assert 1024 == len(r.response["body"])
            assert "content-length" in h
            assert clen == h["content-length"]
            # Restart for logs to be flushed out
            assert env.apache_restart() == 0
            # now check what response lengths have actually been reported
            found = False
            for line in open(TestRanges.LOGFILE).readlines():
                e = json.loads(line)
                if e['request'] == f'GET {path}?02range HTTP/2.0':
                    assert e['bytes_rx_I'] > 0
                    assert e['bytes_resp_B'] == 1024
                    assert e['bytes_tx_O'] > 1024
                    assert e['bytes_tx_O'] < 1024 + 256  # response  and frame stuff
                    found = True
                    break
            assert found, f'request not found in {self.LOGFILE}'
    
        # send a paced curl download that aborts in the middle of the transfer
        def test_h2_008_03(self, env, repeat):
            path = '/data-100m'
            url = env.mkurl("https", "test1", f'{path}?03broken')
            r = env.curl_get(url, 5, options=[
                '--limit-rate', '2k', '-m', '2'
            ])
            assert r.exit_code != 0, f'{r}'
            # Restart for logs to be flushed out
            assert env.apache_restart() == 0
            found = False
            for line in open(TestRanges.LOGFILE).readlines():
                e = json.loads(line)
                log.info(f'inspecting logged request: {e["request"]}')
                if e['request'] == f'GET {path}?03broken HTTP/2.0':
                    assert e['bytes_rx_I'] > 0
                    assert e['bytes_resp_B'] == 100*1024*1024
                    assert e['bytes_tx_O'] > 1024
                    assert e['bytes_tx_O'] < 100*1024*1024  # curl buffers, but not that much
                    found = True
                    break
            assert found, f'request not found in {self.LOGFILE}'
    
        # test server-status reporting
        # see <https://bz.apache.org/bugzilla/show_bug.cgi?id=66801>
        def test_h2_008_04(self, env, repeat):
            path = '/data-100m'
            assert env.apache_restart() == 0
            stats = self.get_server_status(env)
            # we see the server uptime check request here
            assert 1 == int(stats['Total Accesses'])
            assert 1 == int(stats['Total kBytes'])
            count = 10
            url = env.mkurl("https", "test1", f'/data-100m?[0-{count-1}]')
            r = env.curl_get(url, 5, options=['--http2', '-H', f'Range: bytes=0-{4096}'])
            assert r.exit_code == 0, f'{r}'
            stats = self.get_server_status(env)
            # amount reported is larger than (count *4k), the net payload
            # but does not exceed an additional 4k
            assert (4*count)+1 <= int(stats['Total kBytes'])
            assert (4*(count+1))+1 > int(stats['Total kBytes'])
            # total requests is now at 1 from the start, plus the stat check,
            # plus the count transfers we did.
            assert (2+count) == int(stats['Total Accesses'])
    
        def get_server_status(self, env):
            status_url = env.mkurl("https", "test1", '/status?auto')
            r = env.curl_get(status_url, 5)
            assert r.exit_code == 0, f'{r}'
            stats = {}
            for line in r.stdout.splitlines():
                m = re.match(r'([^:]+): (.*)', line)
                if m:
                    stats[m.group(1)] = m.group(2)
            return stats
    
        # upload and GET again using curl, compare to original content
        def curl_upload_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/upload.py")
            fpath = os.path.join(env.gen_dir, fname)
            r = env.curl_upload(url, fpath, options=options)
            assert r.exit_code == 0, f"{r}"
            assert 200 <= r.response["status"] < 300
    
            r2 = env.curl_get(r.response["header"]["location"])
            assert r2.exit_code == 0
            assert r2.response["status"] == 200
            with open(os.path.join(TestRanges.SRCDIR, fpath), mode='rb') as file:
                src = file.read()
            assert src == r2.response["body"]
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_103_upgrade.py�������������������������������������������������0000664�0001751�0001751�00000011400�14643712504�021737� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestUpgrade:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_test1().add_vhost_test2().add_vhost_noh2(
            ).start_vhost(domains=[f"test3.{env.http_tld}"], port=env.https_port, doc_root="htdocs/test1"
            ).add(
                """
                Protocols h2 http/1.1
                Header unset Upgrade"""
            ).end_vhost(
            ).start_vhost(domains=[f"test1b.{env.http_tld}"], port=env.http_port, doc_root="htdocs/test1"
            ).add(
                """
                Protocols h2c http/1.1
                H2Upgrade off
                <Location /006.html>
                    H2Upgrade on
                </Location>"""
            ).end_vhost(
            ).install()
            assert env.apache_restart() == 0
    
        # accessing http://test1, will not try h2 and advertise h2 in the response
        def test_h2_103_01(self, env):
            url = env.mkurl("http", "test1", "/index.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert "upgrade" in r.response["header"]
            assert "h2c" == r.response["header"]["upgrade"]
            
        # accessing http://noh2, will not advertise, because noh2 host does not have it enabled
        def test_h2_103_02(self, env):
            url = env.mkurl("http", "noh2", "/index.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert "upgrade" not in r.response["header"]
            
        # accessing http://test2, will not advertise, because h2 has less preference than http/1.1
        def test_h2_103_03(self, env):
            url = env.mkurl("http", "test2", "/index.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert "upgrade" not in r.response["header"]
    
        # accessing https://noh2, will not advertise, because noh2 host does not have it enabled
        def test_h2_103_04(self, env):
            url = env.mkurl("https", "noh2", "/index.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert "upgrade" not in r.response["header"]
    
        # accessing https://test2, will not advertise, because h2 has less preference than http/1.1
        def test_h2_103_05(self, env):
            url = env.mkurl("https", "test2", "/index.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert "upgrade" not in r.response["header"]
            
        # accessing https://test1, will advertise h2 in the response
        def test_h2_103_06(self, env):
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_get(url, options=["--http1.1"])
            assert 0 == r.exit_code
            assert r.response
            assert "upgrade" in r.response["header"]
            assert "h2" == r.response["header"]["upgrade"]
            
        # accessing https://test3, will not send Upgrade since it is suppressed
        def test_h2_103_07(self, env):
            url = env.mkurl("https", "test3", "/index.html")
            r = env.curl_get(url, options=["--http1.1"])
            assert 0 == r.exit_code
            assert r.response
            assert "upgrade" not in r.response["header"]
    
        # upgrade to h2c for a request, where h2c is preferred
        def test_h2_103_20(self, env):
            url = env.mkurl("http", "test1", "/index.html")
            r = env.nghttp().get(url, options=["-u"])
            assert r.response["status"] == 200
            # check issue #272
            assert 'date' in r.response["header"], f'{r.response}'
            assert r.response["header"]["date"] != 'Sun, 00 Jan 1900 00:00:00 GMT', f'{r.response}'
    
        # upgrade to h2c for a request where http/1.1 is preferred, but the clients upgrade
        # wish is honored nevertheless
        def test_h2_103_21(self, env):
            url = env.mkurl("http", "test2", "/index.html")
            r = env.nghttp().get(url, options=["-u"])
            assert 404 == r.response["status"]
    
        # ugrade to h2c on a host where h2c is not enabled will fail
        def test_h2_103_22(self, env):
            url = env.mkurl("http", "noh2", "/index.html")
            r = env.nghttp().get(url, options=["-u"])
            assert not r.response
    
        # ugrade to h2c on a host where h2c is preferred, but Upgrade is disabled
        def test_h2_103_23(self, env):
            url = env.mkurl("http", "test1b", "/index.html")
            r = env.nghttp().get(url, options=["-u"])
            assert not r.response
    
        # ugrade to h2c on a host where h2c is preferred, but Upgrade is disabled on the server,
        # but allowed for a specific location
        def test_h2_103_24(self, env):
            url = env.mkurl("http", "test1b", "/006.html")
            r = env.nghttp().get(url, options=["-u"])
            assert r.response["status"] == 200
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_600_h2proxy.py�������������������������������������������������0000664�0001751�0001751�00000020257�14643712504�021737� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestH2Proxy:
    
        def test_h2_600_01(self, env):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    "SetEnvIf Host (.+) X_HOST=$1",
                ]
            })
            conf.add_vhost_cgi(h2proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2proxy/hello.py")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert r.response["json"]["protocol"] == "HTTP/2.0"
            assert r.response["json"]["https"] == "on"
            assert r.response["json"]["ssl_protocol"] != ""
            assert r.response["json"]["h2"] == "on"
            assert r.response["json"]["h2push"] == "off"
            assert r.response["json"]["host"] == f"cgi.{env.http_tld}:{env.https_port}"
    
        def test_h2_600_02(self, env):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    "SetEnvIf Host (.+) X_HOST=$1",
                    f"ProxyPreserveHost on",
                    f"ProxyPass /h2c/ h2c://127.0.0.1:{env.http_port}/",
                ]
            })
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2c/hello.py")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert r.response["json"]["protocol"] == "HTTP/2.0"
            assert r.response["json"]["https"] == ""
            # the proxied backend sees Host header as passed on front
            assert r.response["json"]["host"] == f"cgi.{env.http_tld}:{env.https_port}"
            assert r.response["json"]["h2_original_host"] == ""
    
        def test_h2_600_03(self, env):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    "SetEnvIf Host (.+) X_HOST=$1",
                    f"ProxyPreserveHost off",
                    f"ProxyPass /h2c/ h2c://127.0.0.1:{env.http_port}/",
                ]
            })
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2c/hello.py")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert r.response["json"]["protocol"] == "HTTP/2.0"
            assert r.response["json"]["https"] == ""
            # the proxied backend sees Host as using in connecting to it
            assert r.response["json"]["host"] == f"127.0.0.1:{env.http_port}"
            assert r.response["json"]["h2_original_host"] == ""
    
        # check that connection reuse actually happens as configured
        @pytest.mark.parametrize("enable_reuse", [ "on", "off" ])
        def test_h2_600_04(self, env, enable_reuse):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    f"ProxyPassMatch ^/h2proxy/([0-9]+)/(.*)$ "
                    f"  h2c://127.0.0.1:$1/$2 enablereuse={enable_reuse} keepalive=on",
                ]
            })
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", f"/h2proxy/{env.http_port}/hello.py")
            # httpd 2.5.0 disables reuse, not matter the config
            if enable_reuse == "on" and not env.httpd_is_at_least("2.4.60"):
                # reuse is not guaranteed for each request, but we expect some
                # to do it and run on a h2 stream id > 1
                reused = False
                count = 10
                r = env.curl_raw([url] * count, 5)
                response = r.response
                for n in range(count):
                    assert response["status"] == 200
                    if n == (count - 1):
                        break
                    response = response["previous"]
                assert r.json[0]["h2_stream_id"] == "1"
                for n in range(1, count):
                    if int(r.json[n]["h2_stream_id"]) > 1:
                        reused = True
                        break
                assert reused
            else:
                r = env.curl_raw([url, url], 5)
                assert r.response["previous"]["status"] == 200
                assert r.response["status"] == 200
                assert r.json[0]["h2_stream_id"] == "1"
                assert r.json[1]["h2_stream_id"] == "1"
    
        # do some flexible setup from #235 to proper connection selection
        @pytest.mark.parametrize("enable_reuse", [ "on", "off" ])
        def test_h2_600_05(self, env, enable_reuse):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    f"ProxyPassMatch ^/h2proxy/([0-9]+)/(.*)$ "
                    f"  h2c://127.0.0.1:$1/$2 enablereuse={enable_reuse} keepalive=on",
                ]
            })
            conf.add_vhost_cgi()
            conf.add([
                f'Listen {env.http_port2}',
                'UseCanonicalName On',
                'UseCanonicalPhysicalPort On'
            ])
            conf.start_vhost(domains=[f'cgi.{env.http_tld}'],
                             port=5004, doc_root="htdocs/cgi")
            conf.add("AddHandler cgi-script .py")
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", f"/h2proxy/{env.http_port}/hello.py")
            url2 = env.mkurl("https", "cgi", f"/h2proxy/{env.http_port2}/hello.py")
            r = env.curl_raw([url, url2], 5)
            assert r.response["previous"]["status"] == 200
            assert int(r.json[0]["port"]) == env.http_port
            assert r.response["status"] == 200
            exp_port = env.http_port if enable_reuse == "on" \
                                        and not env.httpd_is_at_least("2.4.60")\
                else env.http_port2
            assert int(r.json[1]["port"]) == exp_port
    
        # test X-Forwarded-* headers
        def test_h2_600_06(self, env):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    "SetEnvIf Host (.+) X_HOST=$1",
                    f"ProxyPreserveHost on",
                    f"ProxyPass /h2c/ h2c://127.0.0.1:{env.http_port}/",
                    f"ProxyPass /h1c/ http://127.0.0.1:{env.http_port}/",
                ]
            })
            conf.add_vhost_cgi(proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h1c/hello.py")
            r1 = env.curl_get(url, 5)
            assert r1.response["status"] == 200
            url = env.mkurl("https", "cgi", "/h2c/hello.py")
            r2 = env.curl_get(url, 5)
            assert r2.response["status"] == 200
            for key in ['x-forwarded-for', 'x-forwarded-host','x-forwarded-server']:
                assert r1.json[key] == r2.json[key], f'{key} differs proxy_http != proxy_http2'
    
        # lets do some error tests
        def test_h2_600_30(self, env):
            conf = H2Conf(env)
            conf.add_vhost_cgi(h2proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/error?status=500")
            r = env.curl_get(url)
            assert r.exit_code == 0, r
            assert r.response['status'] == 500
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/error?error=timeout")
            r = env.curl_get(url)
            assert r.exit_code == 0, r
            assert r.response['status'] == 408
    
        # produce an error during response body
        def test_h2_600_31(self, env, repeat):
            conf = H2Conf(env)
            conf.add_vhost_cgi(h2proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/error?body_error=timeout")
            r = env.curl_get(url)
            # depending on when the error is detect in proxying, if may RST the
            # stream (exit_code != 0) or give a 503 response.
            if r.exit_code == 0:
                assert r.response['status'] == 502
    
        # produce an error, fail to generate an error bucket
        def test_h2_600_32(self, env, repeat):
            conf = H2Conf(env)
            conf.add_vhost_cgi(h2proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/error?body_error=timeout&error_bucket=0")
            r = env.curl_get(url)
            # depending on when the error is detect in proxying, if may RST the
            # stream (exit_code != 0) or give a 503 response.
            if r.exit_code == 0:
                assert r.response['status'] in [502, 503]
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_009_timing.py��������������������������������������������������0000664�0001751�0001751�00000005371�14603620422�021607� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import json
    import os
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    @pytest.mark.skipif(not H2TestEnv().h2load_is_at_least('1.41.0'), reason="h2load misses --connect-to option")
    class TestTiming:
    
        LOGFILE = ""
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            TestTiming.LOGFILE = os.path.join(env.server_logs_dir, "test_009")
            if os.path.isfile(TestTiming.LOGFILE):
                os.remove(TestTiming.LOGFILE)
            conf = H2Conf(env=env)
            conf.add([
                "CustomLog logs/test_009 combined"
            ])
            conf.add_vhost_cgi()
            conf.add_vhost_test1()
            conf.install()
            assert env.apache_restart() == 0
    
        # check that we get a positive time_taken reported on a simple GET
        def test_h2_009_01(self, env):
            path = '/002.jpg'
            url = env.mkurl("https", "test1", f'{path}?01')
            args = [
                env.h2load, "-n", "1", "-c", "1", "-m", "1",
                f"--connect-to=localhost:{env.https_port}",
                f"--base-uri={url}", url
            ]
            r = env.run(args)
            # Restart for logs to be flushed out
            assert env.apache_restart() == 0
            found = False
            for line in open(TestTiming.LOGFILE).readlines():
                e = json.loads(line)
                if e['request'] == f'GET {path}?01 HTTP/2.0':
                    assert e['time_taken'] > 0
                    found = True
            assert found, f'request not found in {TestTiming.LOGFILE}'
    
        # test issue #253, where time_taken in a keepalive situation is not
        # reported until the next request arrives
        def test_h2_009_02(self, env):
            baseurl = env.mkurl("https", "test1", '/')
            tscript = os.path.join(env.gen_dir, 'h2load-timing-009_02')
            with open(tscript, 'w') as fd:
                fd.write('\n'.join([
                    f'0.0\t/002.jpg?02a',        # 1st request right away
                    f'1000.0\t/002.jpg?02b',     # 2nd a second later
                ]))
            args = [
                env.h2load,
                f'--timing-script-file={tscript}',
                f"--connect-to=localhost:{env.https_port}",
                f"--base-uri={baseurl}"
            ]
            r = env.run(args)
            # Restart for logs to be flushed out
            assert env.apache_restart() == 0
            found = False
            for line in open(TestTiming.LOGFILE).readlines():
                e = json.loads(line)
                if e['request'] == f'GET /002.jpg?02a HTTP/2.0':
                    assert e['time_taken'] > 0
                    assert e['time_taken'] < 500 * 1000, f'time for 1st request not reported correctly'
                    found = True
            assert found, f'request not found in {TestTiming.LOGFILE}'
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_200_header_invalid.py������������������������������������������0000664�0001751�0001751�00000025543�15032734701�023255� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestInvalidHeaders:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_cgi().install()
            assert env.apache_restart() == 0
    
        # let the hecho.py CGI echo chars < 0x20 in field name
        # for almost all such characters, the stream returns a 500
        # or in httpd >= 2.5.0 gets aborted with a h2 error
        # cr is handled special
        def test_h2_200_01(self, env):
            url = env.mkurl("https", "cgi", "/hecho.py")
            for x in range(1, 32):
                data = f'name=x%{x:02x}x&value=yz'
                r = env.curl_post_data(url, data)
                if x in [13]:
                    assert 0 == r.exit_code, f'unexpected exit code for char 0x{x:02}'
                    assert 200 == r.response["status"], f'unexpected status for char 0x{x:02}'
                elif x in [10] or env.httpd_is_at_least('2.5.0'):
                    assert 0 == r.exit_code, f'unexpected exit code for char 0x{x:02}'
                    assert 500 == r.response["status"], f'unexpected status for char 0x{x:02}'
                else:
                    assert 0 != r.exit_code, f'unexpected exit code for char 0x{x:02}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02429"   # Response header name contains invalid characters
                ],
                matches = [
                    r'.*malformed header from script \'hecho.py\': Bad header: x.*'
                ]
            )
    
        # let the hecho.py CGI echo chars < 0x20 in field value
        # for almost all such characters, the stream returns a 500
        # or in httpd >= 2.5.0 gets aborted with a h2 error
        # cr and lf are handled special
        def test_h2_200_02(self, env):
            url = env.mkurl("https", "cgi", "/hecho.py")
            for x in range(1, 32):
                if 9 != x:
                    r = env.curl_post_data(url, "name=x&value=y%%%02x" % x)
                    if x in [10, 13]:
                        assert 0 == r.exit_code, "unexpected exit code for char 0x%02x" % x
                        assert 200 == r.response["status"], "unexpected status for char 0x%02x" % x
                    elif env.httpd_is_at_least('2.5.0'):
                        assert 0 == r.exit_code, f'unexpected exit code for char 0x{x:02}'
                        assert 500 == r.response["status"], f'unexpected status for char 0x{x:02}'
                    else:
                        assert 0 != r.exit_code, "unexpected exit code for char 0x%02x" % x
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02430"   # Response header value contains invalid characters
                ]
            )
    
        # let the hecho.py CGI echo 0x10 and 0x7f in field name and value
        def test_h2_200_03(self, env):
            url = env.mkurl("https", "cgi", "/hecho.py")
            for h in ["10", "7f"]:
                r = env.curl_post_data(url, "name=x%%%s&value=yz" % h)
                if env.httpd_is_at_least('2.5.0'):
                    assert 0 == r.exit_code, f"unexpected exit code for char 0x{h:02}"
                    assert 500 == r.response["status"], f"unexpected exit code for char 0x{h:02}"
                else:
                    assert 0 != r.exit_code
                r = env.curl_post_data(url, "name=x&value=y%%%sz" % h)
                if env.httpd_is_at_least('2.5.0'):
                    assert 0 == r.exit_code, f"unexpected exit code for char 0x{h:02}"
                    assert 500 == r.response["status"], f"unexpected exit code for char 0x{h:02}"
                else:
                    assert 0 != r.exit_code
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02429",  # Response header name contains invalid characters
                    "AH02430"   # Response header value contains invalid characters
                ]
            )
    
        # test header field lengths check, LimitRequestLine
        def test_h2_200_10(self, env):
            conf = H2Conf(env)
            conf.add("""
                LimitRequestLine 1024
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            val = 200*"1234567890"
            url = env.mkurl("https", "cgi", f'/?{val[:1022]}')
            r = env.curl_get(url)
            assert r.response["status"] == 200
            url = env.mkurl("https", "cgi", f'/?{val[:1023]}')
            r = env.curl_get(url)
            # URI too long
            assert 414 == r.response["status"]
    
        # test header field lengths check, LimitRequestFieldSize (default 8190)
        def test_h2_200_11(self, env):
            conf = H2Conf(env)
            conf.add("""
                LimitRequestFieldSize 1024
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/")
            val = 200*"1234567890"
            # two fields, concatenated with ', '
            # LimitRequestFieldSize, one more char -> 400 in HTTP/1.1
            r = env.curl_get(url, options=[
                '-H', f'x: {val[:500]}', '-H', f'x: {val[:519]}'
            ])
            assert r.exit_code == 0, f'{r}'
            assert r.response["status"] == 200, f'{r}'
            r = env.curl_get(url, options=[
                '--http1.1', '-H', f'x: {val[:500]}', '-H', f'x: {val[:523]}'
            ])
            assert 400 == r.response["status"]
            r = env.curl_get(url, options=[
                '-H', f'x: {val[:500]}', '-H', f'x: {val[:520]}'
            ])
            assert 431 == r.response["status"]
    
        # test header field count, LimitRequestFields (default 100)
        # see #201: several headers with same name are merged and counted
        def test_h2_200_12(self, env):
            url = env.mkurl("https", "cgi", "/")
            opt = []
            # curl sends 3 headers itself (user-agent, accept, and our AP-Test-Name)
            for i in range(97):
                opt += ["-H", "x: 1"]
            r = env.curl_get(url, options=opt)
            assert r.response["status"] == 200
            r = env.curl_get(url, options=(opt + ["-H", "y: 2"]))
            assert r.response["status"] == 431
    
        # test header field count, LimitRequestFields (default 100)
        # different header names count each
        def test_h2_200_13(self, env):
            url = env.mkurl("https", "cgi", "/")
            opt = []
            # curl sends 3 headers itself (user-agent, accept, and our AP-Test-Name)
            for i in range(97):
                opt += ["-H", f"x{i}: 1"]
            r = env.curl_get(url, options=opt)
            assert r.response["status"] == 200
            r = env.curl_get(url, options=(opt + ["-H", "y: 2"]))
            assert 431 == r.response["status"]
    
        # test "LimitRequestFields 0" setting, see #200
        def test_h2_200_14(self, env):
            conf = H2Conf(env)
            conf.add("""
                LimitRequestFields 20
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/")
            opt = []
            for i in range(21):
                opt += ["-H", "x{0}: 1".format(i)]
            r = env.curl_get(url, options=opt)
            assert 431 == r.response["status"]
            conf = H2Conf(env)
            conf.add("""
                LimitRequestFields 0
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/")
            opt = []
            for i in range(100):
                opt += ["-H", "x{0}: 1".format(i)]
            r = env.curl_get(url, options=opt)
            assert r.response["status"] == 200
    
        # the uri limits
        def test_h2_200_15(self, env):
            conf = H2Conf(env)
            conf.add("""
                LimitRequestLine 48
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/")
            r = env.curl_get(url)
            assert r.response["status"] == 200
            url = env.mkurl("https", "cgi", "/" + (48*"x"))
            r = env.curl_get(url)
            assert 414 == r.response["status"]
            # nghttp sends the :method: header first (so far)
            # trigger a too long request line on it
            # the stream will RST and we get no response
            url = env.mkurl("https", "cgi", "/")
            opt = ["-H:method: {0}".format(100*"x")]
            r = env.nghttp().get(url, options=opt)
            assert r.exit_code == 0, r
            assert not r.response
    
        # invalid chars in method
        def test_h2_200_16(self, env):
            if not env.h2load_is_at_least('1.45.0'):
                pytest.skip(f'nhttp2 version too old')
            conf = H2Conf(env)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/hello.py")
            opt = ["-H:method: GET /hello.py"]
            r = env.nghttp().get(url, options=opt)
            assert r.exit_code == 0, r
            assert r.response is None
            url = env.mkurl("https", "cgi", "/proxy/hello.py")
            r = env.nghttp().get(url, options=opt)
            assert r.exit_code == 0, r
            assert r.response is None
    
        # test few failed headers, should
        def test_h2_200_17(self, env):
            url = env.mkurl("https", "cgi", "/")
    
        # test few failed headers, should give response
        def test_h2_200_17(self, env):
            conf = H2Conf(env)
            conf.add("""
                LimitRequestFieldSize 20
                LogLevel http2:debug
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            re_emitted = re.compile(r'.* (AH03401: .* shutdown,|'
                                    r'AH03066: .* FRAME\[GOAWAY.*) remote.emitted=1')
            url = env.mkurl("https", "cgi", "/")
            opt = []
            for i in range(10):
                opt += ["-H", f"x{i}: 012345678901234567890123456789"]
            r = env.curl_get(url, options=opt)
            assert r.response
            assert r.response["status"] == 431
            assert env.httpd_error_log.scan_recent(re_emitted)
    
        # test too many failed headers, should give RST
        def test_h2_200_18(self, env):
            conf = H2Conf(env)
            conf.add("""
                LimitRequestFieldSize 20
                LogLevel http2:debug
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            re_emitted = re.compile(r'.* (AH03401: .* shutdown,|'
                                    r'AH03066: .* FRAME\[GOAWAY.*) remote.emitted=1')
            url = env.mkurl("https", "cgi", "/")
            opt = []
            for i in range(100):
                opt += ["-H", f"x{i}: 012345678901234567890123456789"]
            r = env.curl_get(url, options=opt)
            assert r.response is None
            assert env.httpd_error_log.scan_recent(re_emitted)
    
        # test header 10 invalid headers, should trigger stream RST
        def test_h2_200_19(self, env):
            url = env.mkurl("https", "cgi", "/")
            opt = []
            invalid = '\x7f'
            for i in range(10):
                opt += ["-H", f"x{i}: {invalid}"]
            r = env.curl_get(url, options=opt)
            assert r.response is None
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/env.py��������������������������������������������������������������0000664�0001751�0001751�00000013314�14643712504�017464� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import logging
    import os
    import subprocess
    from shutil import copyfile
    from typing import Dict, Any
    
    from pyhttpd.certs import CertificateSpec
    from pyhttpd.conf import HttpdConf
    from pyhttpd.env import HttpdTestEnv, HttpdTestSetup
    
    log = logging.getLogger(__name__)
    
    
    class H2TestSetup(HttpdTestSetup):
    
        def __init__(self, env: 'HttpdTestEnv'):
            super().__init__(env=env)
            self.add_source_dir(os.path.dirname(inspect.getfile(H2TestSetup)))
            self.add_modules(["http2", "proxy_http2", "cgid", "autoindex", "ssl", "include"])
    
        def make(self):
            super().make()
            self._add_h2test()
            self._setup_data_1k_1m()
    
        def _add_h2test(self):
            local_dir = os.path.dirname(inspect.getfile(H2TestSetup))
            p = subprocess.run([self.env.apxs, '-c', 'mod_h2test.c'],
                               capture_output=True,
                               cwd=os.path.join(local_dir, 'mod_h2test'))
            rv = p.returncode
            if rv != 0:
                log.error(f"compiling md_h2test failed: {p.stderr}")
                raise Exception(f"compiling md_h2test failed: {p.stderr}")
    
            modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf')
            with open(modules_conf, 'a') as fd:
                # load our test module which is not installed
                fd.write(f"LoadModule h2test_module   \"{local_dir}/mod_h2test/.libs/mod_h2test.so\"\n")
    
        def _setup_data_1k_1m(self):
            s90 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n"
            with open(os.path.join(self.env.gen_dir, "data-1k"), 'w') as f:
                for i in range(10):
                    f.write(f"{i:09d}-{s90}")
            with open(os.path.join(self.env.gen_dir, "data-10k"), 'w') as f:
                for i in range(100):
                    f.write(f"{i:09d}-{s90}")
            with open(os.path.join(self.env.gen_dir, "data-100k"), 'w') as f:
                for i in range(1000):
                    f.write(f"{i:09d}-{s90}")
            with open(os.path.join(self.env.gen_dir, "data-1m"), 'w') as f:
                for i in range(10000):
                    f.write(f"{i:09d}-{s90}")
            test1_docs = os.path.join(self.env.server_docs_dir, 'test1')
            self.env.mkpath(test1_docs)
            for fname in ["data-1k", "data-10k", "data-100k", "data-1m"]:
                src = os.path.join(self.env.gen_dir, fname)
                dest = os.path.join(test1_docs, fname)
                copyfile(src, dest)
    
    
    class H2TestEnv(HttpdTestEnv):
    
        @classmethod
        @property
        def is_unsupported(cls):
            mpm_module = f"mpm_{os.environ['MPM']}" if 'MPM' in os.environ else 'mpm_event'
            return mpm_module == 'mpm_prefork'
    
        def __init__(self, pytestconfig=None):
            super().__init__(pytestconfig=pytestconfig)
            self.add_httpd_conf([
                "H2MinWorkers 1",
                "H2MaxWorkers 64",
                "Protocols h2 http/1.1 h2c",
            ])
            self.add_httpd_log_modules(["http2", "proxy_http2", "h2test", "proxy", "proxy_http"])
            self.add_cert_specs([
                CertificateSpec(domains=[
                    f"push.{self._http_tld}",
                    f"hints.{self._http_tld}",
                    f"ssl.{self._http_tld}",
                    f"pad0.{self._http_tld}",
                    f"pad1.{self._http_tld}",
                    f"pad2.{self._http_tld}",
                    f"pad3.{self._http_tld}",
                    f"pad8.{self._http_tld}",
                ]),
                CertificateSpec(domains=[f"noh2.{self.http_tld}"], key_type='rsa2048'),
            ])
    
        def setup_httpd(self, setup: HttpdTestSetup = None):
            super().setup_httpd(setup=H2TestSetup(env=self))
    
    
    class H2Conf(HttpdConf):
    
        def __init__(self, env: HttpdTestEnv, extras: Dict[str, Any] = None):
            super().__init__(env=env, extras=HttpdConf.merge_extras(extras, {
                f"cgi.{env.http_tld}": [
                    "SSLOptions +StdEnvVars",
                    "AddHandler cgi-script .py",
                    "<Location \"/h2test/echo\">",
                    "    SetHandler h2test-echo",
                    "</Location>",
                    "<Location \"/h2test/delay\">",
                    "    SetHandler h2test-delay",
                    "</Location>",
                    "<Location \"/h2test/error\">",
                    "    SetHandler h2test-error",
                    "</Location>",
                ]
            }))
    
        def start_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None,
                        ssl_module=None, with_certificates=None):
            super().start_vhost(domains=domains, port=port, doc_root=doc_root,
                                with_ssl=with_ssl, ssl_module=ssl_module,
                                with_certificates=with_certificates)
            if f"noh2.{self.env.http_tld}" in domains:
                protos = ["http/1.1"]
            elif port == self.env.https_port or with_ssl is True:
                protos = ["h2", "http/1.1"]
            else:
                protos = ["h2c", "http/1.1"]
            if f"test2.{self.env.http_tld}" in domains:
                protos = reversed(protos)
            self.add(f"Protocols {' '.join(protos)}")
            return self
    
        def add_vhost_noh2(self):
            domains = [f"noh2.{self.env.http_tld}", f"noh2-alias.{self.env.http_tld}"]
            self.start_vhost(domains=domains, port=self.env.https_port, doc_root="htdocs/noh2")
            self.add(["Protocols http/1.1", "SSLOptions +StdEnvVars"])
            self.end_vhost()
            self.start_vhost(domains=domains, port=self.env.http_port, doc_root="htdocs/noh2")
            self.add(["Protocols http/1.1", "SSLOptions +StdEnvVars"])
            self.end_vhost()
            return self
    
        def add_vhost_test1(self, proxy_self=False, h2proxy_self=False):
            return super().add_vhost_test1(proxy_self=proxy_self, h2proxy_self=h2proxy_self)
    
        def add_vhost_test2(self):
            return super().add_vhost_test2()
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_101_ssl_reneg.py�����������������������������������������������0000664�0001751�0001751�00000017321�14643712504�022277� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    @pytest.mark.skipif(H2TestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl")
    class TestSslRenegotiation:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            domain = f"ssl.{env.http_tld}"
            conf = H2Conf(env, extras={
                'base': [
                    "SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384",
                    f"<Directory \"{env.server_dir}/htdocs/ssl-client-verify\">",
                    "    Require all granted",
                    "    SSLVerifyClient require",
                    "    SSLVerifyDepth 0",
                    "</Directory>"
                ],
                domain: [
                    "Protocols h2 http/1.1",
                    "<Location /renegotiate/cipher>",
                    "    SSLCipherSuite ECDHE-RSA-CHACHA20-POLY1305",
                    "</Location>",
                    "<Location /renegotiate/err-doc-cipher>",
                    "    SSLCipherSuite ECDHE-RSA-CHACHA20-POLY1305",
                    "    ErrorDocument 403 /forbidden.html",
                    "</Location>",
                    "<Location /renegotiate/verify>",
                    "    SSLVerifyClient require",
                    "</Location>",
                    f"<Directory \"{env.server_dir}/htdocs/sslrequire\">",
                    "    SSLRequireSSL",
                    "</Directory>",
                    f"<Directory \"{env.server_dir}/htdocs/requiressl\">",
                    "    Require ssl",
                    "</Directory>",
            ]})
            conf.add_vhost(domains=[domain], port=env.https_port,
                           doc_root=f"{env.server_dir}/htdocs")
            conf.install()
            # the dir needs to exists for the configuration to have effect
            env.mkpath("%s/htdocs/ssl-client-verify" % env.server_dir)
            env.mkpath("%s/htdocs/renegotiate/cipher" % env.server_dir)
            env.mkpath("%s/htdocs/sslrequire" % env.server_dir)
            env.mkpath("%s/htdocs/requiressl" % env.server_dir)
            assert env.apache_restart() == 0
    
        # access a resource with SSL renegotiation, using HTTP/1.1
        def test_h2_101_01(self, env):
            url = env.mkurl("https", "ssl", "/renegotiate/cipher/")
            r = env.curl_get(url, options=["-v", "--http1.1", "--tlsv1.2", "--tls-max", "1.2"])
            assert 0 == r.exit_code, f"{r}"
            assert r.response
            assert 403 == r.response["status"]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH01276" # No matching DirectoryIndex found
                ]
            )
            
        # try to renegotiate the cipher, should fail with correct code
        def test_h2_101_02(self, env):
            if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
                pytest.skip("need curl != 8.1.x version")
            url = env.mkurl("https", "ssl", "/renegotiate/cipher/")
            r = env.curl_get(url, options=[
                "-vvv", "--tlsv1.2", "--tls-max", "1.2", "--ciphers", "ECDHE-RSA-AES256-GCM-SHA384"
            ])
            assert 0 != r.exit_code
            assert not r.response
            assert re.search(r'HTTP_1_1_REQUIRED \(err 13\)', r.stderr)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02261"   # Re-negotiation handshake failed
                ],
                matches = [
                    r'.*:tls_post_process_client_hello:.*',
                    r'.*SSL Library Error:.*:SSL routines::no shared cipher.*'
                ]
            )
            
        # try to renegotiate a client certificate from Location 
        # needs to fail with correct code
        def test_h2_101_03(self, env):
            if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
                pytest.skip("need curl != 8.1.x version")
            url = env.mkurl("https", "ssl", "/renegotiate/verify/")
            r = env.curl_get(url, options=["-vvv", "--tlsv1.2", "--tls-max", "1.2"])
            assert 0 != r.exit_code
            assert not r.response
            assert re.search(r'HTTP_1_1_REQUIRED \(err 13\)', r.stderr)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02261"   # Re-negotiation handshake failed
                ],
                matches = [
                    r'.*:tls_process_client_certificate:.*',
                    r'.*SSL Library Error:.*:SSL routines::peer did not return a certificate.*'
                ]
            )
            
        # try to renegotiate a client certificate from Directory 
        # needs to fail with correct code
        def test_h2_101_04(self, env):
            if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
                pytest.skip("need curl != 8.1.x version")
            url = env.mkurl("https", "ssl", "/ssl-client-verify/index.html")
            r = env.curl_get(url, options=["-vvv", "--tlsv1.2", "--tls-max", "1.2"])
            assert 0 != r.exit_code, f"{r}"
            assert not r.response
            assert re.search(r'HTTP_1_1_REQUIRED \(err 13\)', r.stderr)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02261"   # Re-negotiation handshake failed
                ],
                matches = [
                    r'.*:tls_process_client_certificate:.*',
                    r'.*SSL Library Error:.*:SSL routines::peer did not return a certificate.*'
                ]
            )
            
        # make 10 requests on the same connection, none should produce a status code
        # reported by erki@example.ee
        def test_h2_101_05(self, env):
            r = env.run([env.h2load, "-n", "10", "-c", "1", "-m", "1", "-vvvv",
                         f"{env.https_base_url}/ssl-client-verify/index.html"])
            assert 0 == r.exit_code
            r = env.h2load_status(r)
            assert 10 == r.results["h2load"]["requests"]["total"]
            assert 10 == r.results["h2load"]["requests"]["started"]
            assert 10 == r.results["h2load"]["requests"]["done"]
            assert 0 == r.results["h2load"]["requests"]["succeeded"]
            assert 0 == r.results["h2load"]["status"]["2xx"]
            assert 0 == r.results["h2load"]["status"]["3xx"]
            assert 0 == r.results["h2load"]["status"]["4xx"]
            assert 0 == r.results["h2load"]["status"]["5xx"]
    
        # Check that "SSLRequireSSL" works on h2 connections
        # See <https://bz.apache.org/bugzilla/show_bug.cgi?id=62654>
        def test_h2_101_10a(self, env):
            url = env.mkurl("https", "ssl", "/sslrequire/index.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert 404 == r.response["status"]
    
        # Check that "require ssl" works on h2 connections
        # See <https://bz.apache.org/bugzilla/show_bug.cgi?id=62654>
        def test_h2_101_10b(self, env):
            url = env.mkurl("https", "ssl", "/requiressl/index.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert 404 == r.response["status"]
            
        # Check that status works with ErrorDoc, see pull #174, fixes #172
        def test_h2_101_11(self, env):
            if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
                pytest.skip("need curl != 8.1.x version")
            url = env.mkurl("https", "ssl", "/renegotiate/err-doc-cipher")
            r = env.curl_get(url, options=[
                "-vvv", "--tlsv1.2", "--tls-max", "1.2", "--ciphers", "ECDHE-RSA-AES256-GCM-SHA384"
            ])
            assert 0 != r.exit_code
            assert not r.response
            assert re.search(r'HTTP_1_1_REQUIRED \(err 13\)', r.stderr)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH02261"   # Re-negotiation handshake failed
                ],
                matches = [
                    r'.*:tls_post_process_client_hello:.*',
                    r'.*SSL Library Error:.*:SSL routines::no shared cipher.*'
                ]
            )
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_106_shutdown.py������������������������������������������������0000664�0001751�0001751�00000005156�14643712504�022201� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # mod-h2 test suite
    # check HTTP/2 timeout behaviour
    #
    import time
    from threading import Thread
    
    import pytest
    
    from .env import H2Conf, H2TestEnv
    from pyhttpd.result import ExecResult
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestShutdown:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H2Conf(env)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
    
        def test_h2_106_01(self, env):
            url = env.mkurl("https", "cgi", "/necho.py")
            lines = 100000
            text = "123456789"
            wait2 = 1.0
            self.r = None
            def long_request():
                args = ["-vvv",
                        "-F", f"count={lines}",
                        "-F", f"text={text}",
                        "-F", f"wait2={wait2}",
                        ]
                self.r = env.curl_get(url, 5, options=args)
    
            t = Thread(target=long_request)
            t.start()
            time.sleep(0.5)
            assert env.apache_reload() == 0
            t.join()
            # noinspection PyTypeChecker
            time.sleep(1)
            r: ExecResult = self.r
            assert r.exit_code == 0
            assert r.response, f"no response via {r.args} in {r.stderr}\nstdout: {len(r.stdout)} bytes"
            assert r.response["status"] == 200, f"{r}"
            assert len(r.response["body"]) == (lines * (len(text)+1)), f"{r}"
    
        def test_h2_106_02(self, env):
            # PR65731: invalid GOAWAY frame at session start when
            # MaxRequestsPerChild is reached
            # Create a low limit and only 2 children, so we'll encounter this easily
            conf = H2Conf(env, extras={
                'base': [
                    "ServerLimit 2",
                    "MaxRequestsPerChild 3"
                ]
            })
            conf.add_vhost_test1()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "test1", "/index.html")
            for i in range(7):
                r = env.curl_get(url, options=['-v'])
                # requests should succeed, but rarely connections get closed
                # before the response is received
                if r.exit_code in [16, 55]:
                    # curl send error
                    assert r.response is None
                else:
                    assert r.exit_code == 0, f"failed on {i}. request: {r.stdout} {r.stderr}"
                    assert r.response["status"] == 200
                    assert "HTTP/2" == r.response["protocol"]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH03490"   # scoreboard is full, not at MaxRequestWorkers
                ]
            )������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_712_buffering.py�����������������������������������������������0000664�0001751�0001751�00000004645�14643712504�022302� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from datetime import timedelta
    
    import pytest
    
    from .env import H2Conf, H2TestEnv
    from pyhttpd.curl import CurlPiper
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestBuffering:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H2Conf(env)
            conf.add_vhost_cgi(h2proxy_self=True).install()
            assert env.apache_restart() == 0
    
        @pytest.mark.skip(reason="this test shows unreliable jitter")
        def test_h2_712_01(self, env):
            # test gRPC like requests that do not end, but give answers, see #207
            #
            # this test works like this:
            # - use curl to POST data to the server /h2test/echo
            # - feed curl the data in chunks, wait a bit between chunks
            # - since some buffering on curl's stdout to Python is involved,
            #   we will see the response data only at the end.
            # - therefore, we enable tracing with timestamps in curl on stderr
            #   and see when the response chunks arrive
            # - if the server sends the incoming data chunks back right away,
            #   as it should, we see receiving timestamps separated roughly by the
            #   wait time between sends.
            #
            url = env.mkurl("https", "cgi", "/h2test/echo")
            base_chunk = "0123456789"
            chunks = ["chunk-{0:03d}-{1}\n".format(i, base_chunk) for i in range(5)]
            stutter = timedelta(seconds=0.2)
            piper = CurlPiper(env=env, url=url)
            piper.stutter_check(chunks, stutter)
    
        def test_h2_712_02(self, env):
            # same as 712_01 but via mod_proxy_http2
            #
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo")
            base_chunk = "0123456789"
            chunks = ["chunk-{0:03d}-{1}\n".format(i, base_chunk) for i in range(3)]
            stutter = timedelta(seconds=0.4)  # need a bit more delay since we have the extra connection
            piper = CurlPiper(env=env, url=url)
            piper.stutter_check(chunks, stutter)
    
        def test_h2_712_03(self, env):
            # same as 712_02 but with smaller chunks
            #
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo")
            base_chunk = "0"
            chunks = ["ck{0}-{1}\n".format(i, base_chunk) for i in range(3)]
            stutter = timedelta(seconds=0.4)  # need a bit more delay since we have the extra connection
            piper = CurlPiper(env=env, url=url)
            piper.stutter_check(chunks, stutter)
    �������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_105_timeout.py�������������������������������������������������0000664�0001751�0001751�00000012750�14643712504�022011� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import socket
    import time
    
    import pytest
    
    from .env import H2Conf
    from pyhttpd.curl import CurlPiper
    
    
    class TestTimeout:
    
        # Check that base servers 'Timeout' setting is observed on SSL handshake
        def test_h2_105_01(self, env):
            conf = H2Conf(env)
            conf.add("""
                AcceptFilter http none
                Timeout 1.5
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            host = 'localhost'
            # read with a longer timeout than the server 
            sock = socket.create_connection((host, int(env.https_port)))
            try:
                # on some OS, the server does not see our connection until there is
                # something incoming
                sock.send(b'0')
                sock.settimeout(4)
                buff = sock.recv(1024)
                assert buff == b''
            except Exception as ex:
                print(f"server did not close in time: {ex}")
                assert False
            sock.close()
            # read with a shorter timeout than the server 
            sock = socket.create_connection((host, int(env.https_port)))
            try:
                sock.settimeout(0.5)
                sock.recv(1024)
                assert False
            except Exception as ex:
                print(f"as expected: {ex}")
            sock.close()
            #
            time.sleep(1) # let the log flush
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10373"   # SSL handshake was not completed
                ]
            )
    
        # Check that mod_reqtimeout handshake setting takes effect
        def test_h2_105_02(self, env):
            conf = H2Conf(env)
            conf.add("""
                AcceptFilter http none
                Timeout 10
                RequestReadTimeout handshake=1 header=5 body=10
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            host = 'localhost'
            # read with a longer timeout than the server 
            sock = socket.create_connection((host, int(env.https_port)))
            try:
                # on some OS, the server does not see our connection until there is
                # something incoming
                sock.send(b'0')
                sock.settimeout(4)
                buff = sock.recv(1024)
                assert buff == b''
            except Exception as ex:
                print(f"server did not close in time: {ex}")
                assert False
            sock.close()
            # read with a shorter timeout than the server 
            sock = socket.create_connection((host, int(env.https_port)))
            try:
                sock.settimeout(0.5)
                sock.recv(1024)
                assert False
            except Exception as ex:
                print(f"as expected: {ex}")
            sock.close()
            #
            time.sleep(1) # let the log flush
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10373"   # SSL handshake was not completed
                ]
            )
    
        # Check that mod_reqtimeout handshake setting do no longer apply to handshaked 
        # connections. See <https://github.com/icing/mod_h2/issues/196>.
        def test_h2_105_03(self, env):
            conf = H2Conf(env)
            conf.add("""
                Timeout 10
                RequestReadTimeout handshake=1 header=5 body=10
                """)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/necho.py")
            r = env.curl_get(url, 5, options=[
                "-vvv",
                "-F", ("count=%d" % 100),
                "-F", ("text=%s" % "abcdefghijklmnopqrstuvwxyz"),
                "-F", ("wait1=%f" % 1.5),
            ])
            assert r.response["status"] == 200
    
        def test_h2_105_10(self, env):
            # just a check without delays if all is fine
            conf = H2Conf(env)
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2test/delay")
            piper = CurlPiper(env=env, url=url)
            piper.start()
            stdout, stderr = piper.close()
            assert piper.exitcode == 0
            assert len("".join(stdout)) == 3 * 8192
    
        def test_h2_105_11(self, env):
            # short connection timeout, longer stream delay
            # connection timeout must not abort ongoing streams
            conf = H2Conf(env)
            conf.add_vhost_cgi()
            conf.add("Timeout 1")
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2test/delay?1200ms")
            piper = CurlPiper(env=env, url=url)
            piper.start()
            stdout, stderr = piper.close()
            assert len("".join(stdout)) == 3 * 8192
    
        def test_h2_105_12(self, env):
            # long connection timeout, short stream timeout
            # sending a slow POST
            if not env.curl_is_at_least('8.0.0'):
                pytest.skip(f'need at least curl v8.0.0 for this')
            if not env.httpd_is_at_least("2.5.0"):
                pytest.skip(f'need at least httpd 2.5.0 for this')
            conf = H2Conf(env)
            conf.add_vhost_cgi()
            conf.add("Timeout 10")
            conf.add("H2StreamTimeout 1")
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "cgi", "/h2test/delay?5")
            piper = CurlPiper(env=env, url=url)
            piper.start()
            for _ in range(3):
                time.sleep(2)
                try:
                    piper.send("0123456789\n")
                except BrokenPipeError:
                    break
            piper.close()
            assert piper.response, f'{piper}'
            assert piper.response['status'] == 408, f"{piper.response}"
    ������������������������httpd-2.4.64/test/modules/http2/test_700_load_get.py������������������������������������������������0000664�0001751�0001751�00000007557�14643712504�022113� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    @pytest.mark.skipif(not H2TestEnv().h2load_is_at_least('1.41.0'),
                        reason="h2load misses --connect-to option")
    class TestLoadGet:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_cgi().add_vhost_test1().install()
            assert env.apache_restart() == 0
    
        def check_h2load_ok(self, env, r, n):
            assert 0 == r.exit_code
            r = env.h2load_status(r)
            assert n == r.results["h2load"]["requests"]["total"], f'{r.results}'
            assert n == r.results["h2load"]["requests"]["started"], f'{r.results}'
            assert n == r.results["h2load"]["requests"]["done"], f'{r.results}'
            assert n == r.results["h2load"]["requests"]["succeeded"], f'{r.results}'
            assert n == r.results["h2load"]["status"]["2xx"], f'{r.results}'
            assert 0 == r.results["h2load"]["status"]["3xx"], f'{r.results}'
            assert 0 == r.results["h2load"]["status"]["4xx"], f'{r.results}'
            assert 0 == r.results["h2load"]["status"]["5xx"], f'{r.results}'
        
        # test load on cgi script, single connection, different sizes
        @pytest.mark.parametrize("start", [
            1000, 80000
        ])
        def test_h2_700_10(self, env, start):
            assert env.is_live()
            text = "X"
            chunk = 32
            for n in range(0, 5):
                args = [env.h2load, "-n", "%d" % chunk, "-c", "1", "-m", "10",
                        f"--connect-to=localhost:{env.https_port}",
                        f"--base-uri={env.mkurl('https', 'cgi', '/')}",
                ]
                for i in range(0, chunk):
                    args.append(env.mkurl("https", "cgi", ("/mnot164.py?count=%d&text=%s" % (start+(n*chunk)+i, text))))
                r = env.run(args)
                self.check_h2load_ok(env, r, chunk)
    
        # test load on cgi script, single connection
        @pytest.mark.parametrize("conns", [
            1, 2, 16
        ])
        def test_h2_700_11(self, env, conns):
            assert env.is_live()
            text = "X"
            start = 1200
            chunk = 64
            for n in range(0, 5):
                args = [env.h2load, "-n", "%d" % chunk, "-c", "%d" % conns, "-m", "10",
                        f"--connect-to=localhost:{env.https_port}",
                        f"--base-uri={env.mkurl('https', 'cgi', '/')}",
                ]
                for i in range(0, chunk):
                    args.append(env.mkurl("https", "cgi", ("/mnot164.py?count=%d&text=%s" % (start+(n*chunk)+i, text))))
                r = env.run(args)
                self.check_h2load_ok(env, r, chunk)
    
        # test window sizes, connection and stream
        @pytest.mark.parametrize("connbits,streambits", [
            [10, 16],  # 1k connection window, 64k stream windows
            [10, 30],  # 1k connection window, huge stream windows
            [30, 8],  # huge conn window, 256 bytes stream windows
        ])
        @pytest.mark.skip('awaiting mpm_event improvements')
        def test_h2_700_20(self, env, connbits, streambits):
            if not env.httpd_is_at_least("2.5.0"):
                pytest.skip(f'need at least httpd 2.5.0 for this')
            conf = H2Conf(env, extras={
                'base': [
                    'StartServers 1',
                ]
            })
            conf.add_vhost_cgi().add_vhost_test1().install()
            assert env.apache_restart() == 0
            assert env.is_live()
            n = 2000
            conns = 50
            parallel = 10
            args = [
                env.h2load,
                '-n', f'{n}', '-t', '1',
                '-c', f'{conns}', '-m', f'{parallel}',
                '-W', f'{connbits}',  # connection window bits
                '-w', f'{streambits}',  # stream window bits
                f'--connect-to=localhost:{env.https_port}',
                f'--base-uri={env.mkurl("https", "test1", "/")}',
                "/data-100k"
            ]
            r = env.run(args)
            self.check_h2load_ok(env, r, n)�������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/mod_h2test/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020374� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/mod_h2test/mod_h2test.h���������������������������������������������0000664�0001751�0001751�00000001533�14107751520�022607� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_H2TEST_H__
    #define __MOD_H2TEST_H__
    
    
    #endif
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/mod_h2test/mod_h2test.c���������������������������������������������0000664�0001751�0001751�00000045337�14436122317�022615� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <apr_optional_hooks.h>
    #include <apr_strings.h>
    #include <apr_cstr.h>
    #include <apr_time.h>
    #include <apr_want.h>
    
    #include <httpd.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    
    #include "mod_h2test.h"
    
    static void h2test_hooks(apr_pool_t *pool);
    
    AP_DECLARE_MODULE(h2test) = {
        STANDARD20_MODULE_STUFF,
        NULL, /* func to create per dir config */
        NULL,  /* func to merge per dir config */
        NULL, /* func to create per server config */
        NULL,  /* func to merge per server config */
        NULL,              /* command handlers */
        h2test_hooks,
    #if defined(AP_MODULE_FLAG_NONE)
        AP_MODULE_FLAG_ALWAYS_MERGE
    #endif
    };
    
    #define SECS_PER_HOUR      (60*60)
    #define SECS_PER_DAY       (24*SECS_PER_HOUR)
    
    static apr_status_t duration_parse(apr_interval_time_t *ptimeout, const char *value,
                                       const char *def_unit)
    {
        char *endp;
        apr_int64_t n;
    
        n = apr_strtoi64(value, &endp, 10);
        if (errno) {
            return errno;
        }
        if (!endp || !*endp) {
            if (!def_unit) def_unit = "s";
        }
        else if (endp == value) {
            return APR_EINVAL;
        }
        else {
            def_unit = endp;
        }
    
        switch (*def_unit) {
        case 'D':
        case 'd':
            *ptimeout = apr_time_from_sec(n * SECS_PER_DAY);
            break;
        case 's':
        case 'S':
            *ptimeout = (apr_interval_time_t) apr_time_from_sec(n);
            break;
        case 'h':
        case 'H':
            /* Time is in hours */
            *ptimeout = (apr_interval_time_t) apr_time_from_sec(n * SECS_PER_HOUR);
            break;
        case 'm':
        case 'M':
            switch (*(++def_unit)) {
            /* Time is in milliseconds */
            case 's':
            case 'S':
                *ptimeout = (apr_interval_time_t) n * 1000;
                break;
            /* Time is in minutes */
            case 'i':
            case 'I':
                *ptimeout = (apr_interval_time_t) apr_time_from_sec(n * 60);
                break;
            default:
                return APR_EGENERAL;
            }
            break;
        default:
            return APR_EGENERAL;
        }
        return APR_SUCCESS;
    }
    
    static int h2test_post_config(apr_pool_t *p, apr_pool_t *plog,
                                  apr_pool_t *ptemp, server_rec *s)
    {
        void *data = NULL;
        const char *mod_h2_init_key = "mod_h2test_init_counter";
        
        (void)plog;(void)ptemp;
    
        apr_pool_userdata_get(&data, mod_h2_init_key, s->process->pool);
        if ( data == NULL ) {
            /* dry run */
            apr_pool_userdata_set((const void *)1, mod_h2_init_key,
                                  apr_pool_cleanup_null, s->process->pool);
            return APR_SUCCESS;
        }
        
        
        return APR_SUCCESS;
    }
    
    static void h2test_child_init(apr_pool_t *pool, server_rec *s)
    {
        (void)pool;
        (void)s;
    }
    
    static int h2test_echo_handler(request_rec *r)
    {
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;
        char buffer[8192];
        const char *ct;
        long l;
        int i;
        apr_time_t chunk_delay = 0;
        apr_array_header_t *args = NULL;
        apr_size_t blen, fail_after = 0;
        int fail_requested = 0, error_bucket = 1;
    
        if (strcmp(r->handler, "h2test-echo")) {
            return DECLINED;
        }
        if (r->method_number != M_GET && r->method_number != M_POST) {
            return DECLINED;
        }
    
        if(r->args) {
            args = apr_cstr_split(r->args, "&", 1, r->pool);
            for(i = 0; i < args->nelts; ++i) {
                char *s, *val, *arg = APR_ARRAY_IDX(args, i, char*);
                s = strchr(arg, '=');
                if(s) {
                    *s = '\0';
                    val = s + 1;
                    if(!strcmp("id", arg)) {
                        /* accepted, but not processed */
                        continue;
                    }
                    else if(!strcmp("chunk_delay", arg)) {
                        rv = duration_parse(&chunk_delay, val, "s");
                        if(APR_SUCCESS == rv) {
                            continue;
                        }
                    }
                    else if(!strcmp("fail_after", arg)) {
                        fail_after = (int)apr_atoi64(val);
                        if(fail_after >= 0) {
                          fail_requested = 1;
                          continue;
                        }
                    }
                }
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "query parameter not "
                              "understood: '%s' in %s",
                              arg, r->args);
                ap_die(HTTP_BAD_REQUEST, r);
                return OK;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "echo_handler: processing request");
        r->status = 200;
        r->clength = -1;
        r->chunked = 1;
        apr_table_unset(r->headers_out, "Content-Length");
        /* Discourage content-encodings */
        apr_table_unset(r->headers_out, "Content-Encoding");
        apr_table_setn(r->subprocess_env, "no-brotli", "1");
        apr_table_setn(r->subprocess_env, "no-gzip", "1");
    
        ct = apr_table_get(r->headers_in, "content-type");
        ap_set_content_type(r, ct? ct : "application/octet-stream");
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
        /* copy any request body into the response */
        if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK))) goto cleanup;
        if (ap_should_client_block(r)) {
            while (0 < (l = ap_get_client_block(r, &buffer[0], sizeof(buffer)))) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "echo_handler: copying %ld bytes from request body", l);
                blen = (apr_size_t)l;
                if (fail_requested) {
                  if (blen > fail_after) {
                    blen = fail_after;
                  }
                  fail_after -= blen;
                }
                rv = apr_brigade_write(bb, NULL, NULL, buffer, blen);
                if (APR_SUCCESS != rv) goto cleanup;
                if (chunk_delay) {
                    apr_sleep(chunk_delay);
                }
                rv = ap_pass_brigade(r->output_filters, bb);
                if (APR_SUCCESS != rv) goto cleanup;
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "echo_handler: passed %ld bytes from request body", l);
                if (fail_requested && fail_after == 0) {
                  rv = APR_EINVAL;
                  goto cleanup;
                }
            }
        }
        /* we are done */
        b = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "echo_handler: request read");
    
        if (r->trailers_in && !apr_is_empty_table(r->trailers_in)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                          "echo_handler: seeing incoming trailers");
            apr_table_setn(r->trailers_out, "h2test-trailers-in", 
                           apr_itoa(r->pool, 1));
        }
        
        rv = ap_pass_brigade(r->output_filters, bb);
        
    cleanup:
        if (rv == APR_SUCCESS
            || r->status != HTTP_OK
            || c->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, "echo_handler: request handled");
            return OK;
        }
        else if (error_bucket) {
            int status = ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
            b = ap_bucket_error_create(status, NULL, r->pool, c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, b);
            ap_pass_brigade(r->output_filters, bb);
        }
        else {
            /* no way to know what type of error occurred */
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, "h2test_echo_handler failed");
            return AP_FILTER_ERROR;
        }
        return DECLINED;
    }
    
    static int h2test_delay_handler(request_rec *r)
    {
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;
        char buffer[8192];
        int i, chunks = 3;
        long l;
        apr_time_t delay = 0;
    
        if (strcmp(r->handler, "h2test-delay")) {
            return DECLINED;
        }
        if (r->method_number != M_GET && r->method_number != M_POST) {
            return DECLINED;
        }
    
        if (r->args) {
            rv = duration_parse(&delay, r->args, "s");
            if (APR_SUCCESS != rv) {
                ap_die(HTTP_BAD_REQUEST, r);
                return OK;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "delay_handler: processing request, %ds delay",
                      (int)apr_time_sec(delay));
        r->status = 200;
        r->clength = -1;
        r->chunked = 1;
        apr_table_unset(r->headers_out, "Content-Length");
        /* Discourage content-encodings */
        apr_table_unset(r->headers_out, "Content-Encoding");
        apr_table_setn(r->subprocess_env, "no-brotli", "1");
        apr_table_setn(r->subprocess_env, "no-gzip", "1");
    
        ap_set_content_type(r, "application/octet-stream");
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
        /* copy any request body into the response */
        if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK))) goto cleanup;
        if (ap_should_client_block(r)) {
            do {
                l = ap_get_client_block(r, &buffer[0], sizeof(buffer));
                if (l > 0) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                  "delay_handler: reading %ld bytes from request body", l);
                }
            } while (l > 0);
            if (l < 0) {
                return AP_FILTER_ERROR;
            }
        }
    
        memset(buffer, 0, sizeof(buffer));
        l = sizeof(buffer);
        for (i = 0; i < chunks; ++i) {
            rv = apr_brigade_write(bb, NULL, NULL, buffer, l);
            if (APR_SUCCESS != rv) goto cleanup;
            rv = ap_pass_brigade(r->output_filters, bb);
            if (APR_SUCCESS != rv) goto cleanup;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "delay_handler: passed %ld bytes as response body", l);
            if (delay) {
                apr_sleep(delay);
            }
        }
        /* we are done */
        b = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        rv = ap_pass_brigade(r->output_filters, bb);
        apr_brigade_cleanup(bb);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, "delay_handler: response passed");
    
    cleanup:
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r,
                      "delay_handler: request cleanup, r->status=%d, aborte=%d",
                      r->status, c->aborted);
        if (rv == APR_SUCCESS
            || r->status != HTTP_OK
            || c->aborted) {
            return OK;
        }
        return AP_FILTER_ERROR;
    }
    
    static int h2test_trailer_handler(request_rec *r)
    {
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;
        char buffer[8192];
        long l;
        int body_len = 0;
    
        if (strcmp(r->handler, "h2test-trailer")) {
            return DECLINED;
        }
        if (r->method_number != M_GET && r->method_number != M_POST) {
            return DECLINED;
        }
    
        if (r->args) {
            body_len = (int)apr_atoi64(r->args);
            if (body_len < 0) body_len = 0;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "trailer_handler: processing request, %d body length",
                      body_len);
        r->status = 200;
        r->clength = body_len;
        ap_set_content_length(r, body_len);
    
        ap_set_content_type(r, "application/octet-stream");
        apr_table_mergen(r->headers_out, "Trailer", "trailer-content-length");
        apr_table_set(r->trailers_out, "trailer-content-length",
                      apr_psprintf(r->pool, "%d", body_len));
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
        memset(buffer, 0, sizeof(buffer));
        while (body_len > 0) {
            l = (sizeof(buffer) > body_len)? body_len : sizeof(buffer);
            body_len -= l;
            rv = apr_brigade_write(bb, NULL, NULL, buffer, l);
            if (APR_SUCCESS != rv) goto cleanup;
            rv = ap_pass_brigade(r->output_filters, bb);
            if (APR_SUCCESS != rv) goto cleanup;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "trailer_handler: passed %ld bytes as response body", l);
        }
        /* we are done */
        b = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        rv = ap_pass_brigade(r->output_filters, bb);
        apr_brigade_cleanup(bb);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, "trailer_handler: response passed");
    
    cleanup:
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r,
                      "trailer_handler: request cleanup, r->status=%d, aborte=%d",
                      r->status, c->aborted);
        if (rv == APR_SUCCESS
            || r->status != HTTP_OK
            || c->aborted) {
            return OK;
        }
        return AP_FILTER_ERROR;
    }
    
    static int status_from_str(const char *s, apr_status_t *pstatus)
    {
        if (!strcmp("timeout", s)) {
            *pstatus = APR_TIMEUP;
            return 1;
        }
        else if (!strcmp("reset", s)) {
            *pstatus = APR_ECONNRESET;
            return 1;
        }
        return 0;
    }
    
    static int h2test_error_handler(request_rec *r)
    {
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;
        char buffer[8192];
        int i, chunks = 3, error_bucket = 1;
        long l;
        apr_time_t delay = 0, body_delay = 0;
        apr_array_header_t *args = NULL;
        int http_status = 200;
        apr_status_t error = APR_SUCCESS, body_error = APR_SUCCESS;
    
        if (strcmp(r->handler, "h2test-error")) {
            return DECLINED;
        }
        if (r->method_number != M_GET && r->method_number != M_POST) {
            return DECLINED;
        }
    
        if (r->args) {
            args = apr_cstr_split(r->args, "&", 1, r->pool);
            for (i = 0; i < args->nelts; ++i) {
                char *s, *val, *arg = APR_ARRAY_IDX(args, i, char*);
                s = strchr(arg, '=');
                if (s) {
                    *s = '\0';
                    val = s + 1;
                    if (!strcmp("status", arg)) {
                        http_status = (int)apr_atoi64(val);
                        if (val > 0) {
                            continue;
                        }
                    }
                    else if (!strcmp("error", arg)) {
                        if (status_from_str(val, &error)) {
                            continue;
                        }
                    }
                    else if (!strcmp("error_bucket", arg)) {
                        error_bucket = (int)apr_atoi64(val);
                        if (val >= 0) {
                            continue;
                        }
                    }
                    else if (!strcmp("body_error", arg)) {
                        if (status_from_str(val, &body_error)) {
                            continue;
                        }
                    }
                    else if (!strcmp("delay", arg)) {
                        rv = duration_parse(&delay, val, "s");
                        if (APR_SUCCESS == rv) {
                            continue;
                        }
                    }
                    else if (!strcmp("body_delay", arg)) {
                        rv = duration_parse(&body_delay, val, "s");
                        if (APR_SUCCESS == rv) {
                            continue;
                        }
                    }
                }
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "error_handler: "
                      "did not understand '%s'", arg);
                ap_die(HTTP_BAD_REQUEST, r);
                return OK;
            }
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "error_handler: processing request, %s",
                      r->args? r->args : "(no args)");
        r->status = http_status;
        r->clength = -1;
        r->chunked = 1;
        apr_table_unset(r->headers_out, "Content-Length");
        /* Discourage content-encodings */
        apr_table_unset(r->headers_out, "Content-Encoding");
        apr_table_setn(r->subprocess_env, "no-brotli", "1");
        apr_table_setn(r->subprocess_env, "no-gzip", "1");
    
        ap_set_content_type(r, "application/octet-stream");
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
    
        if (delay) {
            apr_sleep(delay);
        }
        if (error != APR_SUCCESS) {
            return ap_map_http_request_error(error, HTTP_BAD_REQUEST);
        }
        /* flush response */
        b = apr_bucket_flush_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        rv = ap_pass_brigade(r->output_filters, bb);
        if (APR_SUCCESS != rv) goto cleanup;
    
        memset(buffer, 'X', sizeof(buffer));
        l = sizeof(buffer);
        for (i = 0; i < chunks; ++i) {
            if (body_delay) {
                apr_sleep(body_delay);
            }
            rv = apr_brigade_write(bb, NULL, NULL, buffer, l);
            if (APR_SUCCESS != rv) goto cleanup;
            rv = ap_pass_brigade(r->output_filters, bb);
            if (APR_SUCCESS != rv) goto cleanup;
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                          "error_handler: passed %ld bytes as response body", l);
            if (body_error != APR_SUCCESS) {
                rv = body_error;
                goto cleanup;
            }
        }
        /* we are done */
        b = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        rv = ap_pass_brigade(r->output_filters, bb);
        apr_brigade_cleanup(bb);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, "error_handler: response passed");
    
    cleanup:
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r,
                      "error_handler: request cleanup, r->status=%d, aborted=%d",
                      r->status, c->aborted);
        if (rv == APR_SUCCESS) {
            return OK;
        }
        if (error_bucket) {
            http_status = ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
            b = ap_bucket_error_create(http_status, NULL, r->pool, c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, b);
            ap_pass_brigade(r->output_filters, bb);
        }
        return AP_FILTER_ERROR;
    }
    
    /* Install this module into the apache2 infrastructure.
     */
    static void h2test_hooks(apr_pool_t *pool)
    {
        static const char *const mod_h2[] = { "mod_h2.c", NULL};
        
        ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks and handlers");
        
        /* Run once after configuration is set, but before mpm children initialize.
         */
        ap_hook_post_config(h2test_post_config, mod_h2, NULL, APR_HOOK_MIDDLE);
        
        /* Run once after a child process has been created.
         */
        ap_hook_child_init(h2test_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    
        /* test h2 handlers */
        ap_hook_handler(h2test_echo_handler, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(h2test_delay_handler, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(h2test_trailer_handler, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_handler(h2test_error_handler, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_003_get.py�����������������������������������������������������0000664�0001751�0001751�00000023344�14473316336�021104� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestGet:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_cgi(
                proxy_self=True, h2proxy_self=True
            ).add_vhost_test1(
                proxy_self=True, h2proxy_self=True
            ).install()
            assert env.apache_restart() == 0
    
        # check SSL environment variables from CGI script
        def test_h2_003_01(self, env):
            url = env.mkurl("https", "cgi", "/hello.py")
            r = env.curl_get(url, 5, options=["--tlsv1.2"])
            assert r.response["status"] == 200
            assert r.response["json"]["protocol"] == "HTTP/2.0"
            assert r.response["json"]["https"] == "on"
            tls_version = r.response["json"]["ssl_protocol"]
            assert tls_version in ["TLSv1.2", "TLSv1.3"]
            assert r.response["json"]["h2"] == "on"
            assert r.response["json"]["h2push"] == "off"
    
            r = env.curl_get(url, 5, options=["--http1.1", "--tlsv1.2"])
            assert r.response["status"] == 200
            assert "HTTP/1.1" == r.response["json"]["protocol"]
            assert "on" == r.response["json"]["https"]
            tls_version = r.response["json"]["ssl_protocol"]
            assert tls_version in ["TLSv1.2", "TLSv1.3"]
            assert "" == r.response["json"]["h2"]
            assert "" == r.response["json"]["h2push"]
    
        # retrieve a html file from the server and compare it to its source
        def test_h2_003_02(self, env):
            with open(env.htdocs_src("test1/index.html"), mode='rb') as file:
                src = file.read()
    
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            assert src == r.response["body"]
    
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_get(url, 5, options=["--http1.1"])
            assert r.response["status"] == 200
            assert "HTTP/1.1" == r.response["protocol"]
            assert src == r.response["body"]
    
        # retrieve chunked content from a cgi script
        def check_necho(self, env, n, text):
            url = env.mkurl("https", "cgi", "/necho.py")
            r = env.curl_get(url, 5, options=["-F", f"count={n}", "-F", f"text={text}"])
            assert r.response["status"] == 200
            exp = ""
            for i in range(n):
                exp += text + "\n"
            assert exp == r.response["body"].decode('utf-8')
        
        def test_h2_003_10(self, env):
            self.check_necho(env, 10, "0123456789")
    
        def test_h2_003_11(self, env):
            self.check_necho(env, 100, "0123456789")
    
        def test_h2_003_12(self, env):
            self.check_necho(env, 1000, "0123456789")
    
        def test_h2_003_13(self, env):
            self.check_necho(env, 10000, "0123456789")
    
        def test_h2_003_14(self, env):
            self.check_necho(env, 100000, "0123456789")
    
        # github issue #126
        def test_h2_003_20(self, env):
            url = env.mkurl("https", "test1", "/006/")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            body = r.response["body"].decode('utf-8')
            # our doctype varies between branches and in time, lets not compare
            body = re.sub(r'^<!DOCTYPE[^>]+>', '', body)
            assert '''
    <html>
     <head>
      <title>Index of /006</title>
     </head>
     <body>
    <h1>Index of /006</h1>
    <ul><li><a href="/"> Parent Directory</a></li>
    <li><a href="006.css"> 006.css</a></li>
    <li><a href="006.js"> 006.js</a></li>
    <li><a href="header.html"> header.html</a></li>
    </ul>
    </body></html>
    ''' == body
    
        # github issue #133
        def clean_header(self, s):
            s = re.sub(r'\r\n', '\n', s, flags=re.MULTILINE)
            s = re.sub(r'^date:.*\n', '', s, flags=re.MULTILINE)
            s = re.sub(r'^server:.*\n', '', s, flags=re.MULTILINE)
            s = re.sub(r'^last-modified:.*\n', '', s, flags=re.MULTILINE)
            s = re.sub(r'^etag:.*\n', '', s, flags=re.MULTILINE)
            s = re.sub(r'^vary:.*\n', '', s, flags=re.MULTILINE)
            return re.sub(r'^accept-ranges:.*\n', '', s, flags=re.MULTILINE)
            
        def test_h2_003_21(self, env):
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_get(url, 5, options=["-I"])
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            s = self.clean_header(r.response["body"].decode('utf-8'))
            assert '''HTTP/2 200 
    content-length: 2007
    content-type: text/html
    
    ''' == s
    
            r = env.curl_get(url, 5, options=["-I", url])
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            s = self.clean_header(r.response["body"].decode('utf-8'))
            assert '''HTTP/2 200 
    content-length: 2007
    content-type: text/html
    
    HTTP/2 200 
    content-length: 2007
    content-type: text/html
    
    ''' == s
    
        # test conditionals: if-modified-since
        @pytest.mark.parametrize("path", [
            "/004.html", "/proxy/004.html", "/h2proxy/004.html"
        ])
        def test_h2_003_30(self, env, path):
            url = env.mkurl("https", "test1", path)
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            h = r.response["header"]
            assert "last-modified" in h
            lastmod = h["last-modified"]
            r = env.curl_get(url, 5, options=['-H', ("if-modified-since: %s" % lastmod)])
            assert 304 == r.response["status"]
    
        # test conditionals: if-etag
        @pytest.mark.parametrize("path", [
            "/004.html", "/proxy/004.html", "/h2proxy/004.html"
        ])
        def test_h2_003_31(self, env, path):
            url = env.mkurl("https", "test1", path)
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            h = r.response["header"]
            assert "etag" in h
            etag = h["etag"]
            r = env.curl_get(url, 5, options=['-H', ("if-none-match: %s" % etag)])
            assert 304 == r.response["status"]
    
        # test various response body lengths to work correctly 
        def test_h2_003_40(self, env):
            n = 1001
            while n <= 1025024:
                url = env.mkurl("https", "cgi", f"/mnot164.py?count={n}&text=X")
                r = env.curl_get(url, 5)
                assert r.response["status"] == 200
                assert "HTTP/2" == r.response["protocol"]
                assert n == len(r.response["body"])
                n *= 2
    
        # test various response body lengths to work correctly 
        @pytest.mark.parametrize("n", [
            0, 1, 1291, 1292, 80000, 80123, 81087, 98452
        ])
        def test_h2_003_41(self, env, n):
            url = env.mkurl("https", "cgi", f"/mnot164.py?count={n}&text=X")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            assert n == len(r.response["body"])
            
        # test ranges
        @pytest.mark.parametrize("path", [
            "/004.html", "/proxy/004.html", "/h2proxy/004.html"
        ])
        def test_h2_003_50(self, env, path, repeat):
            # check that the resource supports ranges and we see its raw content-length
            url = env.mkurl("https", "test1", path)
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/2" == r.response["protocol"]
            h = r.response["header"]
            assert "accept-ranges" in h
            assert "bytes" == h["accept-ranges"]
            assert "content-length" in h
            clen = h["content-length"]
            # get the first 1024 bytes of the resource, 206 status, but content-length as original
            r = env.curl_get(url, 5, options=["-H", "range: bytes=0-1023"])
            assert 206 == r.response["status"]
            assert "HTTP/2" == r.response["protocol"]
            assert 1024 == len(r.response["body"])
            assert "content-length" in h
            assert clen == h["content-length"]
    
        # use an invalid scheme
        def test_h2_003_51(self, env):
            url = env.mkurl("https", "cgi", "/")
            opt = ["-H:scheme: invalid"]
            r = env.nghttp().get(url, options=opt)
            assert r.exit_code == 0, r
            assert r.response['status'] == 400
    
        # use an differing scheme, but one that is acceptable
        def test_h2_003_52(self, env):
            url = env.mkurl("https", "cgi", "/")
            opt = ["-H:scheme: http"]
            r = env.nghttp().get(url, options=opt)
            assert r.exit_code == 0, r
            assert r.response['status'] == 200
    
        # Test that we get a proper `Date` and `Server` headers on responses
        def test_h2_003_60(self, env):
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_get(url)
            assert r.exit_code == 0, r
            assert r.response['status'] == 200
            assert 'date' in r.response['header']
            assert 'server' in r.response['header']
    
        # lets do some error tests
        def test_h2_003_70(self, env):
            url = env.mkurl("https", "cgi", "/h2test/error?status=500")
            r = env.curl_get(url)
            assert r.exit_code == 0, r
            assert r.response['status'] == 500
            url = env.mkurl("https", "cgi", "/h2test/error?error=timeout")
            r = env.curl_get(url)
            assert r.exit_code == 0, r
            assert r.response['status'] == 408
    
        # produce an error during response body
        def test_h2_003_71(self, env, repeat):
            url = env.mkurl("https", "cgi", "/h2test/error?body_error=timeout")
            r = env.curl_get(url)
            assert r.exit_code != 0, f"{r}"
            url = env.mkurl("https", "cgi", "/h2test/error?body_error=reset")
            r = env.curl_get(url)
            assert r.exit_code != 0, f"{r}"
    
        # produce an error, fail to generate an error bucket
        def test_h2_003_72(self, env, repeat):
            url = env.mkurl("https", "cgi", "/h2test/error?body_error=timeout&error_bucket=0")
            r = env.curl_get(url)
            assert r.exit_code != 0, f"{r}"
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/ws_server.py��������������������������������������������������������0000664�0001751�0001751�00000005634�14473316336�020725� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import argparse
    import asyncio
    import logging
    import os
    import sys
    import time
    
    import websockets.server as ws_server
    from websockets.exceptions import ConnectionClosedError
    
    log = logging.getLogger(__name__)
    
    logging.basicConfig(
        format="[%(asctime)s] %(message)s",
        level=logging.DEBUG,
    )
    
    
    async def echo(websocket):
        try:
            async for message in websocket:
                try:
                    log.info(f'got request {message}')
                except Exception as e:
                    log.error(f'error {e} getting path from {message}')
                await websocket.send(message)
        except ConnectionClosedError:
            pass
    
    
    async def on_async_conn(conn):
        rpath = str(conn.path)
        pcomps = rpath[1:].split('/')
        if len(pcomps) == 0:
            pcomps = ['echo']  # default handler
        log.info(f'connection for {pcomps}')
        if pcomps[0] == 'echo':
            log.info(f'/echo endpoint')
            for message in await conn.recv():
                await conn.send(message)
        elif pcomps[0] == 'text':
            await conn.send('hello!')
        elif pcomps[0] == 'file':
            if len(pcomps) < 2:
                conn.close(code=4999, reason='unknown file')
                return
            fpath = os.path.join('../', pcomps[1])
            if not os.path.exists(fpath):
                conn.close(code=4999, reason='file not found')
                return
            bufsize = 0
            if len(pcomps) > 2:
                bufsize = int(pcomps[2])
            if bufsize <= 0:
                bufsize = 16*1024
            delay_ms = 0
            if len(pcomps) > 3:
                delay_ms = int(pcomps[3])
            n = 1
            if len(pcomps) > 4:
                n = int(pcomps[4])
            for _ in range(n):
                with open(fpath, 'r+b') as fd:
                    while True:
                        buf = fd.read(bufsize)
                        if buf is None or len(buf) == 0:
                            break
                        await conn.send(buf)
                        if delay_ms > 0:
                            time.sleep(delay_ms/1000)
        else:
            log.info(f'unknown endpoint: {rpath}')
            await conn.close(code=4999, reason='path unknown')
        await conn.close(code=1000, reason='')
    
    
    async def run_server(port):
        log.info(f'starting server on port {port}')
        async with ws_server.serve(ws_handler=on_async_conn,
                                   host="localhost", port=port):
            await asyncio.Future()
    
    
    async def main():
        parser = argparse.ArgumentParser(prog='scorecard',
                                         description="Run a websocket echo server.")
        parser.add_argument("--port", type=int,
                            default=0, help="port to listen on")
        args = parser.parse_args()
    
        if args.port == 0:
            sys.stderr.write('need --port\n')
            sys.exit(1)
    
        logging.basicConfig(
            format="%(asctime)s %(message)s",
            level=logging.DEBUG,
        )
        await run_server(args.port)
    
    
    if __name__ == "__main__":
        asyncio.run(main())
    ����������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_007_ssi.py�����������������������������������������������������0000664�0001751�0001751�00000002152�14643712504�021115� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestSSI:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    'AddOutputFilter INCLUDES .html',
                    '<Location "/ssi">',
                    '  Options +Includes',
                    '</Location>',
                ],
            })
            conf.add_vhost_cgi(
                proxy_self=True, h2proxy_self=True
            ).add_vhost_test1(
                proxy_self=True, h2proxy_self=True
            ).install()
            assert env.apache_restart() == 0
    
        # SSI test from https://bz.apache.org/bugzilla/show_bug.cgi?id=66483
        def test_h2_007_01(self, env):
            url = env.mkurl("https", "cgi", "/ssi/test.html")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert r.stdout == '''<!doctype html>
    <html>
    <head><meta charset="UTF-8"></head>
    <body>
        test<br>
        Hello include<br>
    
        hello<br>
    </body>
    </html>
    ''' , f'{r}'
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_401_early_hints.py���������������������������������������������0000664�0001751�0001751�00000006453�14473316336�022652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    # The push tests depend on "nghttp"
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestEarlyHints:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            if not env.httpd_is_at_least('2.4.58'):
                pytest.skip(f'needs httpd 2.4.58')
            H2Conf(env).start_vhost(domains=[f"hints.{env.http_tld}"],
                                    port=env.https_port, doc_root="htdocs/test1"
            ).add("""
            H2EarlyHints on
            RewriteEngine on
            RewriteRule ^/006-(.*)?\\.html$ /006.html
            <Location /006-hints.html>
                H2PushResource "/006/006.css" critical
            </Location>
            <Location /006-nohints.html>
                Header add Link "</006/006.css>;rel=preload"
            </Location>
            <Location /006-early.html>
                H2EarlyHint Link "</006/006.css>;rel=preload;as=style"
            </Location>
            <Location /006-early-no-push.html>
                H2Push off
                H2EarlyHint Link "</006/006.css>;rel=preload;as=style"
            </Location>
            """).end_vhost(
            ).install()
            assert env.apache_restart() == 0
    
        # H2EarlyHints enabled in general, check that it works for H2PushResource
        def test_h2_401_31(self, env, repeat):
            url = env.mkurl("https", "hints", "/006-hints.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            early = r.response["previous"]
            assert early
            assert 103 == int(early["header"][":status"])
            assert early["header"]["link"]
    
        # H2EarlyHints enabled in general, but does not trigger on added response headers
        def test_h2_401_32(self, env, repeat):
            url = env.mkurl("https", "hints", "/006-nohints.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert "previous" not in r.response
    
        # H2EarlyHints enabled in general, check that it works for H2EarlyHint
        def test_h2_401_33(self, env, repeat):
            url = env.mkurl("https", "hints", "/006-early.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            early = r.response["previous"]
            assert early
            assert 103 == int(early["header"][":status"])
            assert early["header"]["link"] == '</006/006.css>;rel=preload;as=style'
    
        # H2EarlyHints enabled, no PUSH, check that it works for H2EarlyHint
        def test_h2_401_34(self, env, repeat):
            if not env.httpd_is_at_least('2.4.58'):
                pytest.skip(f'needs httpd 2.4.58')
            url = env.mkurl("https", "hints", "/006-early-no-push.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 0 == len(promises)
            early = r.response["previous"]
            assert early
            assert 103 == int(early["header"][":status"])
            assert early["header"]["link"] == '</006/006.css>;rel=preload;as=style'
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_107_frame_lengths.py�������������������������������������������0000664�0001751�0001751�00000003217�14447501300�023131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    def mk_text_file(fpath: str, lines: int):
        t110 = ""
        for _ in range(11):
            t110 += "0123456789"
        with open(fpath, "w") as fd:
            for i in range(lines):
                fd.write("{0:015d}: ".format(i))  # total 128 bytes per line
                fd.write(t110)
                fd.write("\n")
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestFrameLengths:
    
        URI_PATHS = []
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            docs_a = os.path.join(env.server_docs_dir, "cgi/files")
            for fsize in [10, 100]:
                fname = f'0-{fsize}k.txt'
                mk_text_file(os.path.join(docs_a, fname), 8 * fsize)
                self.URI_PATHS.append(f"/files/{fname}")
    
        @pytest.mark.parametrize("data_frame_len", [
            99, 1024, 8192
        ])
        def test_h2_107_01(self, env, data_frame_len):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    f'H2MaxDataFrameLen {data_frame_len}',
                ]
            })
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
            for p in self.URI_PATHS:
                url = env.mkurl("https", "cgi", p)
                r = env.nghttp().get(url, options=[
                    '--header=Accept-Encoding: none',
                ])
                assert r.response["status"] == 200
                assert len(r.results["data_lengths"]) > 0, f'{r}'
                too_large = [ x for x in r.results["data_lengths"] if x > data_frame_len]
                assert len(too_large) == 0, f'{p}: {r.results["data_lengths"]}'
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_005_files.py���������������������������������������������������0000664�0001751�0001751�00000002760�14356741666�021440� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    def mk_text_file(fpath: str, lines: int):
        t110 = ""
        for _ in range(11):
            t110 += "0123456789"
        with open(fpath, "w") as fd:
            for i in range(lines):
                fd.write("{0:015d}: ".format(i))  # total 128 bytes per line
                fd.write(t110)
                fd.write("\n")
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestFiles:
    
        URI_PATHS = []
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            docs_a = os.path.join(env.server_docs_dir, "cgi/files")
            uris = []
            file_count = 32
            file_sizes = [1, 10, 100, 10000]
            for i in range(file_count):
                fsize = file_sizes[i % len(file_sizes)]
                if fsize is None:
                    raise Exception("file sizes?: {0} {1}".format(i, fsize))
                fname = "{0}-{1}k.txt".format(i, fsize)
                mk_text_file(os.path.join(docs_a, fname), 8 * fsize)
                self.URI_PATHS.append(f"/files/{fname}")
    
            H2Conf(env).add_vhost_cgi(
                proxy_self=True, h2proxy_self=True
            ).add_vhost_test1(
                proxy_self=True, h2proxy_self=True
            ).install()
            assert env.apache_restart() == 0
    
        def test_h2_005_01(self, env):
            url = env.mkurl("https", "cgi", self.URI_PATHS[2])
            r = env.curl_get(url)
            assert r.response, r.stderr + r.stdout
            assert r.response["status"] == 200
    ����������������httpd-2.4.64/test/modules/http2/test_102_require.py�������������������������������������������������0000664�0001751�0001751�00000003015�14643712504�021766� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestRequire:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            domain = f"ssl.{env.http_tld}"
            conf = H2Conf(env)
            conf.start_vhost(domains=[domain], port=env.https_port)
            conf.add("""
                  Protocols h2 http/1.1
                  SSLOptions +StdEnvVars
                  <Location /h2only.html>
                    Require expr \"%{HTTP2} == 'on'\"
                  </Location>
                  <Location /noh2.html>
                    Require expr \"%{HTTP2} == 'off'\"
                  </Location>""")
            conf.end_vhost()
            conf.install()
            # the dir needs to exists for the configuration to have effect
            env.mkpath(f"{env.server_dir}/htdocs/ssl-client-verify")
            assert env.apache_restart() == 0
    
        def test_h2_102_01(self, env):
            url = env.mkurl("https", "ssl", "/h2only.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert 404 == r.response["status"]
            
        def test_h2_102_02(self, env):
            url = env.mkurl("https", "ssl", "/noh2.html")
            r = env.curl_get(url)
            assert 0 == r.exit_code
            assert r.response
            assert 403 == r.response["status"]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH01630"   # client denied by server configuration
                ]
            )
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_500_proxy.py���������������������������������������������������0000664�0001751�0001751�00000014534�14643712504�021505� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import os
    import re
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestProxy:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_cgi(proxy_self=True).install()
            assert env.apache_restart() == 0
    
        def local_src(self, fname):
            return os.path.join(os.path.dirname(inspect.getfile(TestProxy)), fname)
    
        def setup_method(self, method):
            print("setup_method: %s" % method.__name__)
    
        def teardown_method(self, method):
            print("teardown_method: %s" % method.__name__)
    
        def test_h2_500_01(self, env):
            url = env.mkurl("https", "cgi", "/proxy/hello.py")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/1.1" == r.response["json"]["protocol"]
            assert r.response["json"]["https"] == ""
            assert r.response["json"]["ssl_protocol"] == ""
            assert r.response["json"]["h2"] == ""
            assert r.response["json"]["h2push"] == ""
    
        # upload and GET again using curl, compare to original content
        def curl_upload_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/proxy/upload.py")
            fpath = os.path.join(env.gen_dir, fname)
            r = env.curl_upload(url, fpath, options=options)
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
    
            # why is the scheme wrong?
            r2 = env.curl_get(re.sub(r'http:', 'https:', r.response["header"]["location"]))
            assert r2.exit_code == 0
            assert r2.response["status"] == 200
            with open(self.local_src(fpath), mode='rb') as file:
                src = file.read()
            assert r2.response["body"] == src
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_500_10(self, env, name, repeat):
            self.curl_upload_and_verify(env, name, ["--http2"])
    
        def test_h2_500_11(self, env):
            self.curl_upload_and_verify(env, "data-1k", [
                "--http1.1", "-H", "Content-Length:", "-H", "Transfer-Encoding: chunked"
            ])
            self.curl_upload_and_verify(env, "data-1k", ["--http2", "-H", "Content-Length:"])
    
        # POST some data using nghttp and see it echo'ed properly back
        def nghttp_post_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/proxy/echo.py")
            fpath = os.path.join(env.gen_dir, fname)
            r = env.nghttp().upload(url, fpath, options=options)
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
            with open(self.local_src(fpath), mode='rb') as file:
                src = file.read()
            if r.response["body"] != src:
                with open(os.path.join(env.gen_dir, "nghttp.out"), 'w') as fd:
                    fd.write(r.outraw.decode())
                    fd.write("\nstderr:\n")
                    fd.write(r.stderr)
                assert r.response["body"] == src
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_500_20(self, env, name, repeat):
            self.nghttp_post_and_verify(env, name, [])
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_500_21(self, env, name, repeat):
            self.nghttp_post_and_verify(env, name, ["--no-content-length"])
    
        # upload and GET again using nghttp, compare to original content
        def nghttp_upload_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/proxy/upload.py")
            fpath = os.path.join(env.gen_dir, fname)
    
            r = env.nghttp().upload_file(url, fpath, options=options)
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
            assert r.response["header"]["location"]
    
            # why is the scheme wrong?
            r2 = env.nghttp().get(re.sub(r'http:', 'https:', r.response["header"]["location"]))
            assert r2.exit_code == 0
            assert r2.response["status"] == 200
            with open(self.local_src(fpath), mode='rb') as file:
                src = file.read()
            assert src == r2.response["body"]
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_500_22(self, env, name):
            self.nghttp_upload_and_verify(env, name, [])
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_500_23(self, env, name):
            self.nghttp_upload_and_verify(env, name, ["--no-content-length"])
    
        # upload using nghttp and check returned status
        def nghttp_upload_stat(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/proxy/upload.py")
            fpath = os.path.join(env.gen_dir, fname)
    
            r = env.nghttp().upload_file(url, fpath, options=options)
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
            assert r.response["header"]["location"]
    
        def test_h2_500_24(self, env):
            for i in range(50):
                self.nghttp_upload_stat(env, "data-1k", ["--no-content-length"])
    
        # lets do some error tests
        def test_h2_500_30(self, env):
            url = env.mkurl("https", "cgi", "/proxy/h2test/error?status=500")
            r = env.curl_get(url)
            assert r.exit_code == 0, r
            assert r.response['status'] == 500
            url = env.mkurl("https", "cgi", "/proxy/h2test/error?error=timeout")
            r = env.curl_get(url)
            assert r.exit_code == 0, r
            assert r.response['status'] == 408
    
        # produce an error during response body
        def test_h2_500_31(self, env, repeat):
            url = env.mkurl("https", "cgi", "/proxy/h2test/error?body_error=timeout")
            r = env.curl_get(url)
            assert r.exit_code != 0, r
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH01110"   # Network error reading response
                ]
            )
    
        # produce an error, fail to generate an error bucket
        def test_h2_500_32(self, env, repeat):
            url = env.mkurl("https", "cgi", "/proxy/h2test/error?body_error=timeout&error_bucket=0")
            r = env.curl_get(url)
            assert r.exit_code != 0, r
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH01110"   # Network error reading response
                ]
            )
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_104_padding.py�������������������������������������������������0000664�0001751�0001751�00000010310�14432674646�021730� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    def frame_padding(payload, padbits):
        mask = (1 << padbits) - 1
        return ((payload + 9 + mask) & ~mask) - (payload + 9)
            
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestPadding:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            def add_echo_handler(conf):
                conf.add([
                    "<Location \"/h2test/echo\">",
                    "    SetHandler h2test-echo",
                    "</Location>",
                ])
    
            conf = H2Conf(env)
            conf.start_vhost(domains=[f"ssl.{env.http_tld}"], port=env.https_port, doc_root="htdocs/cgi")
            add_echo_handler(conf)
            conf.end_vhost()
            conf.start_vhost(domains=[f"pad0.{env.http_tld}"], port=env.https_port, doc_root="htdocs/cgi")
            conf.add("H2Padding 0")
            add_echo_handler(conf)
            conf.end_vhost()
            conf.start_vhost(domains=[f"pad1.{env.http_tld}"], port=env.https_port, doc_root="htdocs/cgi")
            conf.add("H2Padding 1")
            add_echo_handler(conf)
            conf.end_vhost()
            conf.start_vhost(domains=[f"pad2.{env.http_tld}"], port=env.https_port, doc_root="htdocs/cgi")
            conf.add("H2Padding 2")
            add_echo_handler(conf)
            conf.end_vhost()
            conf.start_vhost(domains=[f"pad3.{env.http_tld}"], port=env.https_port, doc_root="htdocs/cgi")
            conf.add("H2Padding 3")
            add_echo_handler(conf)
            conf.end_vhost()
            conf.start_vhost(domains=[f"pad8.{env.http_tld}"], port=env.https_port, doc_root="htdocs/cgi")
            conf.add("H2Padding 8")
            add_echo_handler(conf)
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0
    
        # default paddings settings: 0 bits
        def test_h2_104_01(self, env, repeat):
            url = env.mkurl("https", "ssl", "/h2test/echo")
            # we get 2 frames back: one with data and an empty one with EOF
            # check the number of padding bytes is as expected
            for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]:
                r = env.nghttp().post_data(url, data, 5)
                assert r.response["status"] == 200
                for i in r.results["paddings"]:
                    assert i == frame_padding(len(data)+1, 0)
    
        # 0 bits of padding
        def test_h2_104_02(self, env):
            url = env.mkurl("https", "pad0", "/h2test/echo")
            for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]:
                r = env.nghttp().post_data(url, data, 5)
                assert r.response["status"] == 200
                for i in r.results["paddings"]:
                    assert i == 0
    
        # 1 bit of padding
        def test_h2_104_03(self, env):
            url = env.mkurl("https", "pad1", "/h2test/echo")
            for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]:
                r = env.nghttp().post_data(url, data, 5)
                assert r.response["status"] == 200
                for i in r.results["paddings"]:
                    assert i in range(0, 2)
    
        # 2 bits of padding
        def test_h2_104_04(self, env):
            url = env.mkurl("https", "pad2", "/h2test/echo")
            for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]:
                r = env.nghttp().post_data(url, data, 5)
                assert r.response["status"] == 200
                for i in r.results["paddings"]:
                    assert i in range(0, 4)
    
        # 3 bits of padding
        def test_h2_104_05(self, env):
            url = env.mkurl("https", "pad3", "/h2test/echo")
            for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]:
                r = env.nghttp().post_data(url, data, 5)
                assert r.response["status"] == 200
                for i in r.results["paddings"]:
                    assert i in range(0, 8)
    
        # 8 bits of padding
        def test_h2_104_06(self, env):
            url = env.mkurl("https", "pad8", "/h2test/echo")
            for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]:
                r = env.nghttp().post_data(url, data, 5)
                assert r.response["status"] == 200
                for i in r.results["paddings"]:
                    assert i in range(0, 256)
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_006_assets.py��������������������������������������������������0000664�0001751�0001751�00000005527�14356741666�021645� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestAssets:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_test1().install()
            assert env.apache_restart() == 0
    
        # single page without any assets
        def test_h2_006_01(self, env):
            url = env.mkurl("https", "test1", "/001.html")
            r = env.nghttp().assets(url,  options=["-Haccept-encoding: none"])
            assert 0 == r.exit_code
            assert 1 == len(r.assets)
            assert r.assets == [
                {"status": 200, "size": "251", "path": "/001.html"}
            ]
    
        # single image without any assets
        def test_h2_006_02(self, env):
            url = env.mkurl("https", "test1", "/002.jpg")
            r = env.nghttp().assets(url,  options=["-Haccept-encoding: none"])
            assert 0 == r.exit_code
            assert 1 == len(r.assets)
            assert r.assets == [
                {"status": 200, "size": "88K", "path": "/002.jpg"}
            ]
            
        # gophertiles, yea!
        def test_h2_006_03(self, env):
            # create the tiles files we originally had checked in
            exp_assets = [
                {"status": 200, "size": "10K", "path": "/004.html"},
                {"status": 200, "size": "742", "path": "/004/gophertiles.jpg"},
            ]
            for i in range(2, 181):
                with open(f"{env.server_docs_dir}/test1/004/gophertiles_{i:03d}.jpg", "w") as fd:
                    fd.write("0123456789\n")
                exp_assets.append(
                    {"status": 200, "size": "11", "path": f"/004/gophertiles_{i:03d}.jpg"},
                )
    
            url = env.mkurl("https", "test1", "/004.html")
            r = env.nghttp().assets(url, options=["-Haccept-encoding: none"])
            assert 0 == r.exit_code
            assert 181 == len(r.assets)
            assert r.assets == exp_assets
                
        # page with js and css
        def test_h2_006_04(self, env):
            url = env.mkurl("https", "test1", "/006.html")
            r = env.nghttp().assets(url, options=["-Haccept-encoding: none"])
            assert 0 == r.exit_code
            assert 3 == len(r.assets)
            assert r.assets == [
                {"status": 200, "size": "543", "path": "/006.html"},
                {"status": 200, "size": "216", "path": "/006/006.css"},
                {"status": 200, "size": "839", "path": "/006/006.js"}
            ]
    
        # page with image, try different window size
        def test_h2_006_05(self, env):
            url = env.mkurl("https", "test1", "/003.html")
            r = env.nghttp().assets(url, options=["--window-bits=24", "-Haccept-encoding: none"])
            assert 0 == r.exit_code
            assert 2 == len(r.assets)
            assert r.assets == [
                {"status": 200, "size": "316", "path": "/003.html"},
                {"status": 200, "size": "88K", "path": "/003/003_img.jpg"}
            ]
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_501_proxy_serverheader.py��������������������������������������0000664�0001751�0001751�00000002333�14356741666�024253� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestProxyServerHeader:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    "Header unset Server",
                    "Header always set Server cgi",
                ]
            })
            conf.add_vhost_cgi(proxy_self=True, h2proxy_self=False)
            conf.install()
            assert env.apache_restart() == 0
    
        def setup_method(self, method):
            print("setup_method: %s" % method.__name__)
    
        def teardown_method(self, method):
            print("teardown_method: %s" % method.__name__)
    
        def test_h2_501_01(self, env):
            url = env.mkurl("https", "cgi", "/proxy/hello.py")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/1.1" == r.response["json"]["protocol"]
            assert "" == r.response["json"]["https"]
            assert "" == r.response["json"]["ssl_protocol"]
            assert "" == r.response["json"]["h2"]
            assert "" == r.response["json"]["h2push"]
            assert "cgi" == r.response["header"]["server"]
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/__init__.py���������������������������������������������������������0000664�0001751�0001751�00000000000�14156077574�020431� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_800_websockets.py����������������������������������������������0000664�0001751�0001751�00000037464�14643712504�022507� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import logging
    import os
    import shutil
    import subprocess
    import time
    from datetime import timedelta, datetime
    from typing import Tuple, List
    import packaging.version
    
    import pytest
    import websockets
    from pyhttpd.result import ExecResult
    from pyhttpd.ws_util import WsFrameReader, WsFrame
    
    from .env import H2Conf, H2TestEnv
    
    
    log = logging.getLogger(__name__)
    
    ws_version = packaging.version.parse(websockets.version.version)
    ws_version_min = packaging.version.Version('10.4')
    
    
    def ws_run(env: H2TestEnv, path, authority=None, do_input=None, inbytes=None,
               send_close=True, timeout=5, scenario='ws-stdin',
               wait_close: float = 0.0) -> Tuple[ExecResult, List[str], List[WsFrame]]:
        """ Run the h2ws test client in various scenarios with given input and
            timings.
        :param env: the test environment
        :param path: the path on the Apache server to CONNECt to
        :param authority: the host:port to use as
        :param do_input: a Callable for sending input to h2ws
        :param inbytes: fixed bytes to send to h2ws, unless do_input is given
        :param send_close: send a CLOSE WebSockets frame at the end
        :param timeout: timeout for waiting on h2ws to finish
        :param scenario: name of scenario h2ws should run in
        :param wait_close: time to wait before closing input
        :return: ExecResult with exit_code/stdout/stderr of run
        """
        h2ws = os.path.join(env.clients_dir, 'h2ws')
        if not os.path.exists(h2ws):
            pytest.fail(f'test client not build: {h2ws}')
        if authority is None:
            authority = f'cgi.{env.http_tld}:{env.http_port}'
        args = [
            h2ws, '-vv', '-c', f'localhost:{env.http_port}',
            f'ws://{authority}{path}',
            scenario
        ]
        # we write all output to files, because we manipulate input timings
        # and would run in deadlock situations with h2ws blocking operations
        # because its output is not consumed
        start = datetime.now()
        with open(f'{env.gen_dir}/h2ws.stdout', 'w') as fdout:
            with open(f'{env.gen_dir}/h2ws.stderr', 'w') as fderr:
                proc = subprocess.Popen(args=args, stdin=subprocess.PIPE,
                                        stdout=fdout, stderr=fderr)
                if do_input is not None:
                    do_input(proc)
                elif inbytes is not None:
                    proc.stdin.write(inbytes)
                    proc.stdin.flush()
    
                if wait_close > 0:
                    time.sleep(wait_close)
                try:
                    inbytes = WsFrame.client_close(code=1000).to_network() if send_close else None
                    proc.communicate(input=inbytes, timeout=timeout)
                except subprocess.TimeoutExpired:
                    log.error(f'ws_run: timeout expired')
                    proc.kill()
                    proc.communicate(timeout=timeout)
        end = datetime.now()
        lines = open(f'{env.gen_dir}/h2ws.stdout').read().splitlines()
        infos = [line for line in lines if line.startswith('[1] ')]
        hex_content = ' '.join([line for line in lines if not line.startswith('[1] ')])
        if len(infos) > 0 and infos[0] == '[1] :status: 200':
            frames = WsFrameReader.parse(bytearray.fromhex(hex_content))
        else:
            frames = bytearray.fromhex(hex_content)
        return ExecResult(args=args, exit_code=proc.returncode,
                          stdout=b'', stderr=b'', duration=end - start), infos, frames
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    @pytest.mark.skipif(condition=not H2TestEnv().httpd_is_at_least("2.4.60"),
                        reason=f'need at least httpd 2.4.60 for this')
    @pytest.mark.skipif(condition=ws_version < ws_version_min,
                        reason=f'websockets is {ws_version}, need at least {ws_version_min}')
    class TestWebSockets:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            # Apache config that CONNECT proxies a WebSocket server for paths starting
            # with '/ws/'
            # The WebSocket server is started in pytest fixture 'ws_server' below.
            conf = H2Conf(env, extras={
                'base': [
                    'Timeout 1',
                ],
                f'cgi.{env.http_tld}': [
                  f'  H2WebSockets on',
                  f'  ProxyPass /ws/ http://127.0.0.1:{env.ws_port}/ \\',
                  f'           upgrade=websocket timeout=10',
                  f'  ReadBufferSize 65535'
                ]
            })
            conf.add_vhost_cgi(proxy_self=True, h2proxy_self=True).install()
            conf.add_vhost_test1(proxy_self=True, h2proxy_self=True).install()
            assert env.apache_restart() == 0
    
        def ws_check_alive(self, env, timeout=5):
            url = f'http://localhost:{env.ws_port}/'
            end = datetime.now() + timedelta(seconds=timeout)
            while datetime.now() < end:
                r = env.curl_get(url, 5)
                if r.exit_code == 0:
                    return True
                time.sleep(.1)
            return False
    
        def _mkpath(self, path):
            if not os.path.exists(path):
                return os.makedirs(path)
    
        def _rmrf(self, path):
            if os.path.exists(path):
                return shutil.rmtree(path)
    
        @pytest.fixture(autouse=True, scope='class')
        def ws_server(self, env):
            # Run our python websockets server that has some special behaviour
            # for the different path to CONNECT to.
            run_dir = os.path.join(env.gen_dir, 'ws-server')
            err_file = os.path.join(run_dir, 'stderr')
            self._rmrf(run_dir)
            self._mkpath(run_dir)
            with open(err_file, 'w') as cerr:
                cmd = os.path.join(os.path.dirname(inspect.getfile(TestWebSockets)),
                                   'ws_server.py')
                args = ['python3', cmd, '--port', str(env.ws_port)]
                p = subprocess.Popen(args=args, cwd=run_dir, stderr=cerr,
                                     stdout=cerr)
                if not self.ws_check_alive(env):
                    p.kill()
                    p.wait()
                    pytest.fail(f'ws_server did not start. stderr={open(err_file).readlines()}')
                yield
                p.terminate()
    
        # CONNECT with invalid :protocol header, must fail
        def test_h2_800_01_fail_proto(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/echo/', scenario='fail-proto')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 501', '[1] EOF'], f'{r}'
    
        # a correct CONNECT, send CLOSE, expect CLOSE, basic success
        def test_h2_800_02_ws_empty(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/echo/')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) == 1, f'{frames}'
            assert frames[0].opcode == WsFrame.CLOSE, f'{frames}'
    
        # CONNECT to a URL path that does not exist on the server
        def test_h2_800_03_not_found(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/does-not-exist')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 404', '[1] EOF'] or infos == ['[1] :status: 404', '[1] EOF', '[1] RST'], f'{r}'
    
        # CONNECT to a URL path that is a normal HTTP file resource
        # we do not want to receive the body of that
        def test_h2_800_04_non_ws_resource(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/alive.json')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 502', '[1] EOF'] or infos == ['[1] :status: 502', '[1] EOF', '[1] RST'], f'{r}'
            assert frames == b''
    
        # CONNECT to a URL path that sends a delayed HTTP response body
        # we do not want to receive the body of that
        def test_h2_800_05_non_ws_delay_resource(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/h2test/error?body_delay=100ms')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 502', '[1] EOF'] or infos == ['[1] :status: 502', '[1] EOF', '[1] RST'], f'{r}'
            assert frames == b''
    
        # CONNECT missing the sec-webSocket-version header
        def test_h2_800_06_miss_version(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/echo/', scenario='miss-version')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 400', '[1] EOF'], f'{r}'
    
        # CONNECT missing the :path header
        def test_h2_800_07_miss_path(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/echo/', scenario='miss-path')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] RST'], f'{r}'
    
        # CONNECT missing the :scheme header
        def test_h2_800_08_miss_scheme(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/echo/', scenario='miss-scheme')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] RST'], f'{r}'
    
        # CONNECT missing the :authority header
        def test_h2_800_09a_miss_authority(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/echo/', scenario='miss-authority')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] RST'], f'{r}'
    
        # CONNECT to authority with disabled websockets
        def test_h2_800_09b_unsupported(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/echo/',
                                      authority=f'test1.{env.http_tld}:{env.http_port}')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 501', '[1] EOF'] or infos == ['[1] :status: 501', '[1] EOF', '[1] RST'], f'{r}'
    
        # CONNECT and exchange a PING
        def test_h2_800_10_ws_ping(self, env: H2TestEnv, ws_server):
            ping = WsFrame.client_ping(b'12345')
            r, infos, frames = ws_run(env, path='/ws/echo/', inbytes=ping.to_network())
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) == 2, f'{frames}'
            assert frames[0].opcode == WsFrame.PONG, f'{frames}'
            assert frames[0].data == ping.data, f'{frames}'
            assert frames[1].opcode == WsFrame.CLOSE, f'{frames}'
    
        # CONNECT and send several PINGs with a delay of 200ms
        def test_h2_800_11_ws_timed_pings(self, env: H2TestEnv, ws_server):
            frame_count = 5
            ping = WsFrame.client_ping(b'12345')
    
            def do_send(proc):
                for _ in range(frame_count):
                    try:
                        proc.stdin.write(ping.to_network())
                        proc.stdin.flush()
                        proc.wait(timeout=0.2)
                    except subprocess.TimeoutExpired:
                        pass
    
            r, infos, frames = ws_run(env, path='/ws/echo/', do_input=do_send)
            assert r.exit_code == 0
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) == frame_count + 1, f'{frames}'
            assert frames[-1].opcode == WsFrame.CLOSE, f'{frames}'
            for i in range(frame_count):
                assert frames[i].opcode == WsFrame.PONG, f'{frames}'
                assert frames[i].data == ping.data, f'{frames}'
    
        # CONNECT to path that closes immediately
        def test_h2_800_12_ws_unknown(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/unknown')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) == 1, f'{frames}'
            # expect a CLOSE with code=4999, reason='path unknown'
            assert frames[0].opcode == WsFrame.CLOSE, f'{frames}'
            assert frames[0].data[2:].decode() == 'path unknown', f'{frames}'
    
        # CONNECT to a path that sends us 1 TEXT frame
        def test_h2_800_13_ws_text(self, env: H2TestEnv, ws_server):
            r, infos, frames = ws_run(env, path='/ws/text/')
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) == 2, f'{frames}'
            assert frames[0].opcode == WsFrame.TEXT, f'{frames}'
            assert frames[0].data.decode() == 'hello!', f'{frames}'
            assert frames[1].opcode == WsFrame.CLOSE, f'{frames}'
    
        # CONNECT to a path that sends us a named file in BINARY frames
        @pytest.mark.parametrize("fname,flen", [
            ("data-1k", 1000),
            ("data-10k", 10000),
            ("data-100k", 100*1000),
            ("data-1m", 1000*1000),
        ])
        def test_h2_800_14_ws_file(self, env: H2TestEnv, ws_server, fname, flen):
            r, infos, frames = ws_run(env, path=f'/ws/file/{fname}', wait_close=0.5)
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) > 0
            total_len = sum([f.data_len for f in frames if f.opcode == WsFrame.BINARY])
            assert total_len == flen, f'{frames}'
    
        # CONNECT to path with 1MB file and trigger varying BINARY frame lengths
        @pytest.mark.parametrize("frame_len", [
            1000 * 1024,
            100 * 1024,
            10 * 1024,
            1 * 1024,
            512,
        ])
        def test_h2_800_15_ws_frame_len(self, env: H2TestEnv, ws_server, frame_len):
            fname = "data-1m"
            flen = 1000*1000
            r, infos, frames = ws_run(env, path=f'/ws/file/{fname}/{frame_len}', wait_close=0.5)
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) > 0
            total_len = sum([f.data_len for f in frames if f.opcode == WsFrame.BINARY])
            assert total_len == flen, f'{frames}'
    
        # CONNECT to path with 1MB file and trigger delays between BINARY frame writes
        @pytest.mark.parametrize("frame_delay", [
            1,
            10,
            50,
            100,
        ])
        def test_h2_800_16_ws_frame_delay(self, env: H2TestEnv, ws_server, frame_delay):
            fname = "data-1m"
            flen = 1000*1000
            # adjust frame_len to allow for 1 second overall duration
            frame_len = int(flen / (1000 / frame_delay))
            r, infos, frames = ws_run(env, path=f'/ws/file/{fname}/{frame_len}/{frame_delay}',
                                      wait_close=1.5)
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) > 0
            total_len = sum([f.data_len for f in frames if f.opcode == WsFrame.BINARY])
            assert total_len == flen, f'{frames}\n{r}'
    
        # CONNECT to path with 1MB file and trigger delays between BINARY frame writes
        @pytest.mark.parametrize("frame_len", [
            64 * 1024,
            16 * 1024,
            1 * 1024,
        ])
        def test_h2_800_17_ws_throughput(self, env: H2TestEnv, ws_server, frame_len):
            fname = "data-1m"
            flen = 1000*1000
            ncount = 5
            r, infos, frames = ws_run(env, path=f'/ws/file/{fname}/{frame_len}/0/{ncount}',
                                      wait_close=0.1, send_close=False, timeout=30)
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) > 0
            total_len = sum([f.data_len for f in frames if f.opcode == WsFrame.BINARY])
            assert total_len == ncount * flen, f'{frames}\n{r}'
            # to see these logged, invoke: `pytest -o log_cli=true`
            log.info(f'throughput (frame-len={frame_len}): "'
                     f'"{(total_len / (1024*1024)) / r.duration.total_seconds():0.2f} MB/s')
    
        # Check that the tunnel timeout is observed, e.g. the longer holds and
        # the 1sec cleint conn timeout does not trigger
        def test_h2_800_18_timeout(self, env: H2TestEnv, ws_server):
            fname = "data-10k"
            frame_delay = 1500
            flen = 10*1000
            frame_len = 8192
            # adjust frame_len to allow for 1 second overall duration
            r, infos, frames = ws_run(env, path=f'/ws/file/{fname}/{frame_len}/{frame_delay}',
                                      wait_close=2)
            assert r.exit_code == 0, f'{r}'
            assert infos == ['[1] :status: 200', '[1] EOF'], f'{r}'
            assert len(frames) > 0
            total_len = sum([f.data_len for f in frames if f.opcode == WsFrame.BINARY])
            assert total_len == flen, f'{frames}\n{r}'
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_400_push.py����������������������������������������������������0000664�0001751�0001751�00000020201�14356741666�021302� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    # The push tests depend on "nghttp"
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestPush:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).start_vhost(domains=[f"push.{env.http_tld}"],
                                    port=env.https_port, doc_root="htdocs/test1"
            ).add(r"""
            RewriteEngine on
            RewriteRule ^/006-push(.*)?\.html$ /006.html
            <Location /006-push.html>
                Header add Link "</006/006.css>;rel=preload"
                Header add Link "</006/006.js>;rel=preloadX"
            </Location>
            <Location /006-push2.html>
                Header add Link "</006/006.css>;rel=preloadX, </006/006.js>; rel=preload"
            </Location>
            <Location /006-push3.html>
                Header add Link "</006/006.css>;rel=preloa,</006/006.js>;rel=preload"
            </Location>
            <Location /006-push4.html>
                Header add Link "</006/006.css;rel=preload, </006/006.js>; preload"
            </Location>
            <Location /006-push5.html>
                Header add Link '</006/006.css>;rel="preload push"'
            </Location>
            <Location /006-push6.html>
                Header add Link '</006/006.css>;rel="push preload"'
            </Location>
            <Location /006-push7.html>
                Header add Link '</006/006.css>;rel="abc preload push"'
            </Location>
            <Location /006-push8.html>
                Header add Link '</006/006.css>;rel="preload"; nopush'
            </Location>
            <Location /006-push20.html>
                H2PushResource "/006/006.css" critical
                H2PushResource "/006/006.js"
            </Location>    
            <Location /006-push30.html>
                H2Push off
                Header add Link '</006/006.css>;rel="preload"'
            </Location>
            <Location /006-push31.html>
                H2PushResource "/006/006.css" critical
            </Location>
            <Location /006-push32.html>
                Header add Link "</006/006.css>;rel=preload"
            </Location>
            """).end_vhost(
            ).install()
            assert env.apache_restart() == 0
    
        ############################
        # Link: header handling, various combinations
    
        # plain resource without configured pushes 
        def test_h2_400_00(self, env):
            url = env.mkurl("https", "push", "/006.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 0 == len(promises)
    
        # 2 link headers configured, only 1 triggers push
        def test_h2_400_01(self, env):
            url = env.mkurl("https", "push", "/006-push.html")
            r = env.nghttp().get(url, options=["-Haccept-encoding: none"])
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert '/006/006.css' == promises[0]["request"]["header"][":path"]
            assert 216 == len(promises[0]["response"]["body"])
    
        # Same as 400_01, but with single header line configured
        def test_h2_400_02(self, env):
            url = env.mkurl("https", "push", "/006-push2.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert '/006/006.js' == promises[0]["request"]["header"][":path"]
    
        # 2 Links, only one with correct rel attribute
        def test_h2_400_03(self, env):
            url = env.mkurl("https", "push", "/006-push3.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert '/006/006.js' == promises[0]["request"]["header"][":path"]
    
        # Missing > in Link header, PUSH not triggered
        def test_h2_400_04(self, env):
            url = env.mkurl("https", "push", "/006-push4.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 0 == len(promises)
    
        # More than one value in "rel" parameter
        def test_h2_400_05(self, env):
            url = env.mkurl("https", "push", "/006-push5.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert '/006/006.css' == promises[0]["request"]["header"][":path"]
    
        # Another "rel" parameter variation
        def test_h2_400_06(self, env):
            url = env.mkurl("https", "push", "/006-push6.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert '/006/006.css' == promises[0]["request"]["header"][":path"]
    
        # Another "rel" parameter variation
        def test_h2_400_07(self, env):
            url = env.mkurl("https", "push", "/006-push7.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert '/006/006.css' == promises[0]["request"]["header"][":path"]
    
        # Pushable link header with "nopush" attribute
        def test_h2_400_08(self, env):
            url = env.mkurl("https", "push", "/006-push8.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 0 == len(promises)
    
        # 2 H2PushResource config trigger on GET, but not on POST
        def test_h2_400_20(self, env):
            url = env.mkurl("https", "push", "/006-push20.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 2 == len(promises)
    
            fpath = os.path.join(env.gen_dir, "data-400-20")
            with open(fpath, 'w') as f:
                f.write("test upload data")
            r = env.nghttp().upload(url, fpath)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 0 == len(promises)
        
        # H2Push configured Off in location
        def test_h2_400_30(self, env):
            url = env.mkurl("https", "push", "/006-push30.html")
            r = env.nghttp().get(url)
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 0 == len(promises)
    
        # - suppress PUSH
        def test_h2_400_50(self, env):
            url = env.mkurl("https", "push", "/006-push.html")
            r = env.nghttp().get(url, options=['-H', 'accept-push-policy: none'])
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 0 == len(promises)
    
        # - default pushes desired
        def test_h2_400_51(self, env):
            url = env.mkurl("https", "push", "/006-push.html")
            r = env.nghttp().get(url, options=['-H', 'accept-push-policy: default'])
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
    
        # - HEAD pushes desired
        def test_h2_400_52(self, env):
            url = env.mkurl("https", "push", "/006-push.html")
            r = env.nghttp().get(url, options=['-H', 'accept-push-policy: head'])
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
            assert '/006/006.css' == promises[0]["request"]["header"][":path"]
            assert b"" == promises[0]["response"]["body"]
            assert 0 == len(promises[0]["response"]["body"])
    
        # - fast-load pushes desired
        def test_h2_400_53(self, env):
            url = env.mkurl("https", "push", "/006-push.html")
            r = env.nghttp().get(url, options=['-H', 'accept-push-policy: fast-load'])
            assert r.response["status"] == 200
            promises = r.results["streams"][r.response["id"]]["promises"]
            assert 1 == len(promises)
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_711_load_post_cgi.py�������������������������������������������0000664�0001751�0001751�00000004766�14356741666�023160� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    import os
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestLoadCgi:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_cgi(proxy_self=True, h2proxy_self=True).install()
            assert env.apache_restart() == 0
    
        def check_h2load_ok(self, env, r, n):
            assert 0 == r.exit_code
            r = env.h2load_status(r)
            assert n == r.results["h2load"]["requests"]["total"]
            assert n == r.results["h2load"]["requests"]["started"]
            assert n == r.results["h2load"]["requests"]["done"]
            assert n == r.results["h2load"]["requests"]["succeeded"]
            assert n == r.results["h2load"]["status"]["2xx"]
            assert 0 == r.results["h2load"]["status"]["3xx"]
            assert 0 == r.results["h2load"]["status"]["4xx"]
            assert 0 == r.results["h2load"]["status"]["5xx"]
        
        # test POST on cgi, where input is read
        def test_h2_711_10(self, env, repeat):
            assert env.is_live()
            url = env.mkurl("https", "test1", "/echo.py")
            n = 100
            m = 5
            conn = 1
            fname = "data-100k"
            args = [
                env.h2load, "-n", str(n), "-c", str(conn), "-m", str(m),
                f"--base-uri={env.https_base_url}",
                "-d", os.path.join(env.gen_dir, fname), url
            ]
            r = env.run(args)
            self.check_h2load_ok(env, r, n)
    
        # test POST on cgi via http/1.1 proxy, where input is read
        def test_h2_711_11(self, env, repeat):
            assert env.is_live()
            url = env.mkurl("https", "test1", "/proxy/echo.py")
            n = 100
            m = 5
            conn = 1
            fname = "data-100k"
            args = [
                env.h2load, "-n", str(n), "-c", str(conn), "-m", str(m),
                f"--base-uri={env.https_base_url}",
                "-d", os.path.join(env.gen_dir, fname), url
            ]
            r = env.run(args)
            self.check_h2load_ok(env, r, n)
    
        # test POST on cgi via h2proxy, where input is read
        def test_h2_711_12(self, env, repeat):
            assert env.is_live()
            url = env.mkurl("https", "test1", "/h2proxy/echo.py")
            n = 100
            m = 5
            conn = 1
            fname = "data-100k"
            args = [
                env.h2load, "-n", str(n), "-c", str(conn), "-m", str(m),
                f"--base-uri={env.https_base_url}",
                "-d", os.path.join(env.gen_dir, fname), url
            ]
            r = env.run(args)
            self.check_h2load_ok(env, r, n)
    ����������httpd-2.4.64/test/modules/http2/test_503_proxy_fwd.py�����������������������������������������������0000664�0001751�0001751�00000006037�14473316336�022353� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestProxyFwd:
    
        @classmethod
        def config_fwd_proxy(cls, env, h2_enabled=False):
            conf = H2Conf(env, extras={
                'base': [
                    f'Listen {env.proxy_port}',
                    'Protocols h2c http/1.1',
                    'LogLevel proxy_http2:trace2 proxy:trace2',
                ],
            })
            conf.add_vhost_cgi(proxy_self=False, h2proxy_self=False)
            conf.start_vhost(domains=[f"test1.{env.http_tld}"],
                             port=env.proxy_port, with_ssl=True)
            conf.add([
                'Protocols h2c http/1.1',
                'ProxyRequests on',
                f'H2ProxyRequests {"on" if h2_enabled else "off"}',
            ])
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(cls, env):
            cls.config_fwd_proxy(env)
    
        # test the HTTP/1.1 setup working
        def test_h2_503_01_proxy_fwd_h1(self, env):
            url = f'http://localhost:{env.http_port}/hello.py'
            proxy_host = f'test1.{env.http_tld}'
            options = [
                '--proxy', f'https://{proxy_host}:{env.proxy_port}',
                '--resolve', f'{proxy_host}:{env.proxy_port}:127.0.0.1',
                '--proxy-cacert', f'{env.get_ca_pem_file(proxy_host)}',
            ]
            r = env.curl_get(url, 5, options=options)
            assert r.exit_code == 0, f'{r}'
            assert r.response['status'] == 200
            assert r.json['port'] == f'{env.http_port}'
    
        def test_h2_503_02_fwd_proxy_h2_off(self, env):
            if not env.curl_is_at_least('8.1.0'):
                pytest.skip(f'need at least curl v8.1.0 for this')
            url = f'http://localhost:{env.http_port}/hello.py'
            proxy_host = f'test1.{env.http_tld}'
            options = [
                '--proxy-http2', '-v',
                '--proxy', f'https://{proxy_host}:{env.proxy_port}',
                '--resolve', f'{proxy_host}:{env.proxy_port}:127.0.0.1',
                '--proxy-cacert', f'{env.get_ca_pem_file(proxy_host)}',
            ]
            r = env.curl_get(url, 5, options=options)
            assert r.exit_code == 0, f'{r}'
            assert r.response['status'] == 404
    
        # test the HTTP/2 setup working
        def test_h2_503_03_proxy_fwd_h2_on(self, env):
            if not env.curl_is_at_least('8.1.0'):
                pytest.skip(f'need at least curl v8.1.0 for this')
            self.config_fwd_proxy(env, h2_enabled=True)
            url = f'http://localhost:{env.http_port}/hello.py'
            proxy_host = f'test1.{env.http_tld}'
            options = [
                '--proxy-http2', '-v',
                '--proxy', f'https://{proxy_host}:{env.proxy_port}',
                '--resolve', f'{proxy_host}:{env.proxy_port}:127.0.0.1',
                '--proxy-cacert', f'{env.get_ca_pem_file(proxy_host)}',
            ]
            r = env.curl_get(url, 5, options=options)
            assert r.exit_code == 0, f'{r}'
            assert r.response['status'] == 200
            assert r.json['port'] == f'{env.http_port}'
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_004_post.py����������������������������������������������������0000664�0001751�0001751�00000017633�14444301677�021317� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import difflib
    import email.parser
    import inspect
    import json
    import os
    import re
    import sys
    import time
    
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestPost:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            TestPost._local_dir = os.path.dirname(inspect.getfile(TestPost))
            conf = H2Conf(env, extras={
                f'cgi.{env.http_tld}': [
                    f'<Directory {env.server_docs_dir}/cgi/xxx>',
                    '  RewriteEngine On',
                    '  RewriteRule .* /proxy/echo.py [QSA]',
                    '</Directory>',
                ]
            })
            conf.add_vhost_cgi(proxy_self=True).install()
            assert env.apache_restart() == 0
    
        def local_src(self, fname):
            return os.path.join(TestPost._local_dir, fname)
    
        # upload and GET again using curl, compare to original content
        def curl_upload_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/upload.py")
            fpath = os.path.join(env.gen_dir, fname)
            r = env.curl_upload(url, fpath, options=options)
            assert r.exit_code == 0, f"{r}"
            assert 200 <= r.response["status"] < 300
    
            r2 = env.curl_get(r.response["header"]["location"])
            assert r2.exit_code == 0
            assert r2.response["status"] == 200
            with open(self.local_src(fpath), mode='rb') as file:
                src = file.read()
            assert src == r2.response["body"]
    
        def test_h2_004_01(self, env):
            self.curl_upload_and_verify(env, "data-1k", ["-vvv", "--http1.1"])
            self.curl_upload_and_verify(env, "data-1k", ["--http2"])
    
        def test_h2_004_02(self, env):
            self.curl_upload_and_verify(env, "data-10k", ["--http1.1"])
            self.curl_upload_and_verify(env, "data-10k", ["--http2"])
    
        def test_h2_004_03(self, env):
            self.curl_upload_and_verify(env, "data-100k", ["--http1.1"])
            self.curl_upload_and_verify(env, "data-100k", ["--http2"])
    
        def test_h2_004_04(self, env):
            self.curl_upload_and_verify(env, "data-1m", ["--http1.1"])
            self.curl_upload_and_verify(env, "data-1m", ["--http2"])
    
        def test_h2_004_05(self, env):
            self.curl_upload_and_verify(env, "data-1k", ["-v", "--http1.1", "-H", "Expect: 100-continue"])
            self.curl_upload_and_verify(env, "data-1k", ["-v", "--http2", "-H", "Expect: 100-continue"])
    
        def test_h2_004_06(self, env):
            self.curl_upload_and_verify(env, "data-1k", [
                "--http1.1", "-H", "Content-Length:", "-H", "Transfer-Encoding: chunked"
            ])
            self.curl_upload_and_verify(env, "data-1k", ["--http2", "-H", "Content-Length:"])
    
        @pytest.mark.parametrize("name, value", [
            ("HTTP2", "on"),
            ("H2PUSH", "off"),
            ("H2_PUSHED", ""),
            ("H2_PUSHED_ON", ""),
            ("H2_STREAM_ID", "1"),
            ("H2_STREAM_TAG", r'\d+-\d+-1'),
        ])
        def test_h2_004_07(self, env, name, value):
            url = env.mkurl("https", "cgi", "/env.py")
            r = env.curl_post_value(url, "name", name)
            assert r.exit_code == 0
            assert r.response["status"] == 200
            m = re.match("{0}=(.*)".format(name), r.response["body"].decode('utf-8'))
            assert m
            assert re.match(value, m.group(1)) 
    
        # POST some data using nghttp and see it echo'ed properly back
        def nghttp_post_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/echo.py")
            fpath = os.path.join(env.gen_dir, fname)
    
            r = env.nghttp().upload(url, fpath, options=options)
            assert r.exit_code == 0
            assert r.response["status"] >= 200 and r.response["status"] < 300
    
            with open(self.local_src(fpath), mode='rb') as file:
                src = file.read()
            assert 'request-length' in r.response["header"]
            assert int(r.response["header"]['request-length']) == len(src)
            if len(r.response["body"]) != len(src):
                sys.stderr.writelines(difflib.unified_diff(
                    src.decode().splitlines(True),
                    r.response["body"].decode().splitlines(True),
                    fromfile='source',
                    tofile='response'
                ))
                assert len(r.response["body"]) == len(src)
            assert r.response["body"] == src, f"expected '{src}', got '{r.response['body']}'"
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m"
        ])
        def test_h2_004_21(self, env, name):
            self.nghttp_post_and_verify(env, name, [])
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_004_22(self, env, name, repeat):
            self.nghttp_post_and_verify(env, name, ["--no-content-length"])
    
        # upload and GET again using nghttp, compare to original content
        def nghttp_upload_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/upload.py")
            fpath = os.path.join(env.gen_dir, fname)
    
            r = env.nghttp().upload_file(url, fpath, options=options)
            assert r.exit_code == 0
            assert r.response["status"] >= 200 and r.response["status"] < 300
            assert 'location' in r.response["header"], f'{r}'
            assert r.response["header"]["location"]
    
            r2 = env.nghttp().get(r.response["header"]["location"])
            assert r2.exit_code == 0
            assert r2.response["status"] == 200
            with open(self.local_src(fpath), mode='rb') as file:
                src = file.read()
            assert src == r2.response["body"], f'GET {r.response["header"]["location"]}'
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m"
        ])
        def test_h2_004_23(self, env, name, repeat):
            self.nghttp_upload_and_verify(env, name, [])
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m"
        ])
        def test_h2_004_24(self, env, name, repeat):
            self.nghttp_upload_and_verify(env, name, ["--expect-continue"])
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m"
        ])
        def test_h2_004_25(self, env, name, repeat):
            self.nghttp_upload_and_verify(env, name, ["--no-content-length"])
    
        def test_h2_004_40(self, env):
            # echo content using h2test_module "echo" handler
            def post_and_verify(fname, options=None):
                url = env.mkurl("https", "cgi", "/h2test/echo")
                fpath = os.path.join(env.gen_dir, fname)
                r = env.curl_upload(url, fpath, options=options)
                assert r.exit_code == 0
                assert r.response["status"] >= 200 and r.response["status"] < 300
                
                ct = r.response["header"]["content-type"]
                mail_hd = "Content-Type: " + ct + "\r\nMIME-Version: 1.0\r\n\r\n"
                mime_msg = mail_hd.encode() + r.response["body"]
                # this MIME API is from hell
                body = email.parser.BytesParser().parsebytes(mime_msg)
                assert body
                assert body.is_multipart()
                filepart = None
                for part in body.walk():
                    if fname == part.get_filename():
                        filepart = part
                assert filepart
                with open(self.local_src(fpath), mode='rb') as file:
                    src = file.read()
                assert src == filepart.get_payload(decode=True)
            
            post_and_verify("data-1k", [])
    
        def test_h2_004_41(self, env):
            # reproduce PR66597, double chunked encoding on redirects
            url = env.mkurl("https", "cgi", "/xxx/test.json")
            r = env.curl_post_data(url, data="0123456789", options=[])
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
            assert r.response['body'] == b'0123456789'
            r = env.curl_post_data(url, data="0123456789", options=["-H", "Content-Length:"])
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
            assert r.response['body'] == b'0123456789'
    �����������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_001_httpd_alive.py���������������������������������������������0000664�0001751�0001751�00000001317�14356741666�022632� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestBasicAlive:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_test1().install()
            assert env.apache_restart() == 0
    
        # we expect to see the document from the generic server
        def test_h2_001_01(self, env):
            url = env.mkurl("https", "test1", "/alive.json")
            r = env.curl_get(url, 5)
            assert r.exit_code == 0, r.stderr + r.stdout
            assert r.response["json"]
            assert r.response["json"]["alive"] is True
            assert r.response["json"]["host"] == "test1"
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_201_header_conditional.py��������������������������������������0000664�0001751�0001751�00000005670�14356741666�024152� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestConditionalHeaders:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add(
                """
                KeepAlive on
                MaxKeepAliveRequests 30
                KeepAliveTimeout 30"""
            ).add_vhost_test1().install()
            assert env.apache_restart() == 0
    
        # check handling of 'if-modified-since' header
        def test_h2_201_01(self, env):
            url = env.mkurl("https", "test1", "/006/006.css")
            r = env.curl_get(url)
            assert r.response["status"] == 200
            lm = r.response["header"]["last-modified"]
            assert lm
            r = env.curl_get(url, options=["-H", "if-modified-since: %s" % lm])
            assert 304 == r.response["status"]
            r = env.curl_get(url, options=["-H", "if-modified-since: Tue, 04 Sep 2010 11:51:59 GMT"])
            assert r.response["status"] == 200
    
        # check handling of 'if-none-match' header
        def test_h2_201_02(self, env):
            url = env.mkurl("https", "test1", "/006/006.css")
            r = env.curl_get(url)
            assert r.response["status"] == 200
            etag = r.response["header"]["etag"]
            assert etag
            r = env.curl_get(url, options=["-H", "if-none-match: %s" % etag])
            assert 304 == r.response["status"]
            r = env.curl_get(url, options=["-H", "if-none-match: dummy"])
            assert r.response["status"] == 200
            
        @pytest.mark.skipif(True, reason="304 misses the Vary header in trunk and 2.4.x")
        def test_h2_201_03(self, env):
            url = env.mkurl("https", "test1", "/006.html")
            r = env.curl_get(url, options=["-H", "Accept-Encoding: gzip"])
            assert r.response["status"] == 200
            for h in r.response["header"]:
                print("%s: %s" % (h, r.response["header"][h]))
            lm = r.response["header"]["last-modified"]
            assert lm
            assert "gzip" == r.response["header"]["content-encoding"]
            assert "Accept-Encoding" in r.response["header"]["vary"]
            
            r = env.curl_get(url, options=["-H", "if-modified-since: %s" % lm,
                                           "-H", "Accept-Encoding: gzip"])
            assert 304 == r.response["status"]
            for h in r.response["header"]:
                print("%s: %s" % (h, r.response["header"][h]))
            assert "vary" in r.response["header"]
    
        # Check if "Keep-Alive" response header is removed in HTTP/2.
        def test_h2_201_04(self, env):
            url = env.mkurl("https", "test1", "/006.html")
            r = env.curl_get(url, options=["--http1.1", "-H", "Connection: keep-alive"])
            assert r.response["status"] == 200
            assert "timeout=30, max=30" == r.response["header"]["keep-alive"]
            r = env.curl_get(url, options=["-H", "Connection: keep-alive"])
            assert r.response["status"] == 200
            assert "keep-alive" not in r.response["header"]
    ������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_502_proxy_port.py����������������������������������������������0000664�0001751�0001751�00000002675�14356741666�022572� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestProxyPort:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H2Conf(env, extras={
                'base': [
                    f'Listen {env.proxy_port}',
                    'Protocols h2c http/1.1',
                    'LogLevel proxy_http2:trace2 proxy:trace2',
                ],
                f'cgi.{env.http_tld}': [
                    "Header unset Server",
                    "Header always set Server cgi",
                ]
            })
            conf.add_vhost_cgi(proxy_self=False, h2proxy_self=False)
            conf.start_vhost(domains=[f"test1.{env.http_tld}"], port=env.proxy_port)
            conf.add([
                'Protocols h2c',
                'RewriteEngine On',
                'RewriteRule "^/(.*)$" "h2c://%{HTTP_HOST}/$1"[NC,P]',
                'ProxyPassMatch / "h2c://$1/"',
            ])
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0
    
        # Test PR 65881
        # h2c upgraded request via a dynamic proxy onto another port
        def test_h2_502_01(self, env):
            url = f'http://localhost:{env.http_port}/hello.py'
            r = env.curl_get(url, 5, options=['--http2',
                                              '--proxy', f'localhost:{env.proxy_port}'])
            assert r.response['status'] == 200
            assert r.json['port'] == f'{env.http_port}'
    �������������������������������������������������������������������httpd-2.4.64/test/modules/http2/.gitignore����������������������������������������������������������0000664�0001751�0001751�00000000033�14107751520�020300� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gen
    config.ini
    __pycache__
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_601_h2proxy_twisted.py�����������������������������������������0000664�0001751�0001751�00000007674�14473316336�023517� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import json
    import logging
    import os
    import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    log = logging.getLogger(__name__)
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestH2ProxyTwisted:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_cgi(proxy_self=True, h2proxy_self=True).install()
            assert env.apache_restart() == 0
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_601_01_echo_uploads(self, env, name):
            fpath = os.path.join(env.gen_dir, name)
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo")
            r = env.curl_upload(url, fpath, options=[])
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
            # we POST a form, so echoed input is larger than the file itself
            assert len(r.response["body"]) > os.path.getsize(fpath)
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_601_02_echo_delayed(self, env, name):
            fpath = os.path.join(env.gen_dir, name)
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo?chunk_delay=10ms")
            r = env.curl_upload(url, fpath, options=[])
            assert r.exit_code == 0
            assert 200 <= r.response["status"] < 300
            # we POST a form, so echoed input is larger than the file itself
            assert len(r.response["body"]) > os.path.getsize(fpath)
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_601_03_echo_fail_early(self, env, name):
            if not env.httpd_is_at_least('2.4.58'):
                pytest.skip(f'needs httpd 2.4.58')
            fpath = os.path.join(env.gen_dir, name)
            url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo?fail_after=512")
            r = env.curl_upload(url, fpath, options=[])
            # 92 is curl's CURLE_HTTP2_STREAM
            assert r.exit_code == 92 or r.response["status"] == 502
    
        @pytest.mark.parametrize("name", [
            "data-1k", "data-10k", "data-100k", "data-1m",
        ])
        def test_h2_601_04_echo_fail_late(self, env, name):
            if not env.httpd_is_at_least('2.4.58'):
                pytest.skip(f'needs httpd 2.4.58')
            fpath = os.path.join(env.gen_dir, name)
            url = env.mkurl("https", "cgi", f"/h2proxy/h2test/echo?fail_after={os.path.getsize(fpath)}")
            r = env.curl_upload(url, fpath, options=[])
            # 92 is curl's CURLE_HTTP2_STREAM
            if r.exit_code != 0:
                # H2 stream or partial file error
                assert r.exit_code == 92 or r.exit_code == 18, f'{r}'
            else:
                assert r.response["status"] == 502, f'{r}'
    
        def test_h2_601_05_echo_fail_many(self, env):
            if not env.httpd_is_at_least('2.4.58'):
                pytest.skip(f'needs httpd 2.4.58')
            if not env.curl_is_at_least('8.0.0'):
                pytest.skip(f'need at least curl v8.0.0 for this')
            count = 200
            fpath = os.path.join(env.gen_dir, "data-100k")
            args = [env.curl, '--parallel', '--parallel-max', '20']
            for i in range(count):
                if i > 0:
                    args.append('--next')
                url = env.mkurl("https", "cgi", f"/h2proxy/h2test/echo?id={i}&fail_after={os.path.getsize(fpath)}")
                args.extend(env.curl_resolve_args(url=url))
                args.extend([
                    '-o', '/dev/null', '-w', '%{json}\\n', '--form', f'file=@{fpath}', url
                ])
            log.error(f'run: {args}')
            r = env.run(args)
            stats = []
            for line in r.stdout.splitlines():
                stats.append(json.loads(line))
            assert len(stats) == count
            for st in stats:
                if st['exitcode'] != 0:
                    # H2 stream or partial file error
                    assert st['exitcode'] == 92 or st['exitcode'] == 18, f'{r}'
                else:
                    assert st['http_code'] == 502, f'{r}'
    ��������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_002_curl_basics.py���������������������������������������������0000664�0001751�0001751�00000005303�14356741666�022620� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestCurlBasics:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H2Conf(env)
            conf.add_vhost_test1()
            conf.add_vhost_test2()
            conf.install()
            assert env.apache_restart() == 0
    
        # check that we see the correct documents when using the test1 server name over http:
        def test_h2_002_01(self, env):
            url = env.mkurl("http", "test1", "/alive.json")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert "HTTP/1.1" == r.response["protocol"]
            assert r.response["json"]["alive"] is True
            assert r.response["json"]["host"] == "test1"
    
        # check that we see the correct documents when using the test1 server name over https:
        def test_h2_002_02(self, env):
            url = env.mkurl("https", "test1", "/alive.json")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert r.response["json"]["alive"] is True
            assert "test1" == r.response["json"]["host"]
            assert r.response["header"]["content-type"] == "application/json"
    
        # enforce HTTP/1.1
        def test_h2_002_03(self, env):
            url = env.mkurl("https", "test1", "/alive.json")
            r = env.curl_get(url, 5, options=["--http1.1"])
            assert r.response["status"] == 200
            assert r.response["protocol"] == "HTTP/1.1"
    
        # enforce HTTP/2
        def test_h2_002_04(self, env):
            url = env.mkurl("https", "test1", "/alive.json")
            r = env.curl_get(url, 5, options=["--http2"])
            assert r.response["status"] == 200
            assert r.response["protocol"] == "HTTP/2"
    
        # default is HTTP/2 on this host
        def test_h2_002_04b(self, env):
            url = env.mkurl("https", "test1", "/alive.json")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert r.response["protocol"] == "HTTP/2"
            assert r.response["json"]["host"] == "test1"
    
        # although, without ALPN, we cannot select it
        def test_h2_002_05(self, env):
            url = env.mkurl("https", "test1", "/alive.json")
            r = env.curl_get(url, 5, options=["--no-alpn"])
            assert r.response["status"] == 200
            assert r.response["protocol"] == "HTTP/1.1"
            assert r.response["json"]["host"] == "test1"
    
        # default is HTTP/1.1 on the other
        def test_h2_002_06(self, env):
            url = env.mkurl("https", "test2", "/alive.json")
            r = env.curl_get(url, 5)
            assert r.response["status"] == 200
            assert r.response["protocol"] == "HTTP/1.1"
            assert r.response["json"]["host"] == "test2"
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/test_300_interim.py�������������������������������������������������0000664�0001751�0001751�00000002737�14356741666�022007� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestInterimResponses:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_test1().add_vhost_cgi().install()
            assert env.apache_restart() == 0
    
        def setup_method(self, method):
            print("setup_method: %s" % method.__name__)
    
        def teardown_method(self, method):
            print("teardown_method: %s" % method.__name__)
    
        # check that we normally do not see an interim response
        def test_h2_300_01(self, env):
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_post_data(url, 'XYZ')
            assert r.response["status"] == 200
            assert "previous" not in r.response
    
        # check that we see an interim response when we ask for it
        def test_h2_300_02(self, env):
            url = env.mkurl("https", "cgi", "/echo.py")
            r = env.curl_post_data(url, 'XYZ', options=["-H", "expect: 100-continue"])
            assert r.response["status"] == 200
            assert "previous" in r.response
            assert 100 == r.response["previous"]["status"] 
    
        # check proper answer on unexpected
        def test_h2_300_03(self, env):
            url = env.mkurl("https", "cgi", "/echo.py")
            r = env.curl_post_data(url, 'XYZ', options=["-H", "expect: the-unexpected"])
            assert 417 == r.response["status"]
            assert "previous" not in r.response
    ���������������������������������httpd-2.4.64/test/modules/http2/test_710_load_post_static.py����������������������������������������0000664�0001751�0001751�00000004500�14356741666�023666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    import os
    
    from .env import H2Conf, H2TestEnv
    
    
    @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
    class TestLoadPostStatic:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H2Conf(env).add_vhost_test1().install()
            assert env.apache_restart() == 0
    
        def check_h2load_ok(self, env, r, n):
            assert 0 == r.exit_code
            r = env.h2load_status(r)
            assert n == r.results["h2load"]["requests"]["total"]
            assert n == r.results["h2load"]["requests"]["started"]
            assert n == r.results["h2load"]["requests"]["done"]
            assert n == r.results["h2load"]["requests"]["succeeded"]
            assert n == r.results["h2load"]["status"]["2xx"]
            assert 0 == r.results["h2load"]["status"]["3xx"]
            assert 0 == r.results["h2load"]["status"]["4xx"]
            assert 0 == r.results["h2load"]["status"]["5xx"]
        
        # test POST on static file, slurped in by server
        def test_h2_710_00(self, env, repeat):
            assert env.is_live()
            url = env.mkurl("https", "test1", "/index.html")
            n = 10
            m = 1
            conn = 1
            fname = "data-10k"
            args = [env.h2load, "-n", f"{n}", "-c", f"{conn}", "-m", f"{m}",
                    f"--base-uri={env.https_base_url}",
                    "-d", os.path.join(env.gen_dir, fname), url]
            r = env.run(args)
            self.check_h2load_ok(env, r, n)
    
        def test_h2_710_01(self, env, repeat):
            assert env.is_live()
            url = env.mkurl("https", "test1", "/index.html")
            n = 1000
            m = 100
            conn = 1
            fname = "data-1k"
            args = [env.h2load, "-n", f"{n}", "-c", f"{conn}", "-m", f"{m}",
                    f"--base-uri={env.https_base_url}",
                    "-d", os.path.join(env.gen_dir, fname), url]
            r = env.run(args)
            self.check_h2load_ok(env, r, n)
    
        def test_h2_710_02(self, env, repeat):
            assert env.is_live()
            url = env.mkurl("https", "test1", "/index.html")
            n = 100
            m = 50
            conn = 1
            fname = "data-100k"
            args = [env.h2load, "-n", f"{n}", "-c", f"{conn}", "-m", f"{m}",
                    f"--base-uri={env.https_base_url}",
                    "-d", os.path.join(env.gen_dir, fname), url]
            r = env.run(args)
            self.check_h2load_ok(env, r, n)
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http2/Makefile.in���������������������������������������������������������0000664�0001751�0001751�00000001000�14107751520�020350� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    # no targets: we don't want to build anything by default. if you want the
    # test programs, then "make test"
    TARGETS =
    
    bin_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: $(bin_PROGRAMS)
    
    # example for building a test proggie
    # dbu_OBJECTS = dbu.lo
    # dbu: $(dbu_OBJECTS)
    #	$(LINK) $(dbu_OBJECTS) $(PROGRAM_LDADD)
    httpd-2.4.64/test/modules/md/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015663� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/pebble/����������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017114� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/pebble/pebble.json.template��������������������������������������������0000664�0001751�0001751�00000001420�14750656217�023052� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
      "pebble": {
        "listenAddress": "0.0.0.0:14000",
        "managementListenAddress": "0.0.0.0:15000",
        "certificate": "${server_dir}/ca/localhost.rsa2048.cert.pem",
        "privateKey": "${server_dir}/ca/localhost.rsa2048.pkey.pem",
        "httpPort": ${http_port},
        "tlsPort": ${https_port},
        "ocspResponderURL": "",
        "externalAccountBindingRequired": false,
        "domainBlocklist": ["blocked-domain.example"],
        "retryAfter": {
            "authz": 3,
            "order": 5
        },
        "profiles": {
           "default": {
             "description": "The profile you know and love",
             "validityPeriod": 7776000
           },
           "shortlived": {
             "description": "A short-lived cert profile, without actual enforcement",
             "validityPeriod": 518400
           }
         }
      }
    }
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/pebble/pebble-eab.json.template����������������������������������������0000664�0001751�0001751�00000001546�14750656217�023610� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
      "pebble": {
        "listenAddress": "0.0.0.0:14000",
        "managementListenAddress": "0.0.0.0:15000",
        "certificate": "${server_dir}/ca/localhost.rsa2048.cert.pem",
        "privateKey": "${server_dir}/ca/localhost.rsa2048.pkey.pem",
        "httpPort": ${http_port},
        "tlsPort": ${https_port},
        "ocspResponderURL": "",
        "externalAccountBindingRequired": true,
        "externalAccountMACKeys": {
          "kid-1": "zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W",
          "kid-2": "b10lLJs8l1GPIzsLP0s6pMt8O0XVGnfTaCeROxQM0BIt2XrJMDHJZBM5NuQmQJQH"
        },
        "profiles": {
           "default": {
             "description": "The profile you know and love",
             "validityPeriod": 7776000
           },
           "shortlived": {
             "description": "A short-lived cert profile, without actual enforcement",
             "validityPeriod": 518400
           }
         }
      }
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/conftest.py������������������������������������������������������������0000775�0001751�0001751�00000003241�14750656217�020070� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import os
    import sys
    import pytest
    
    sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
    
    from .md_env import MDTestEnv
    from .md_acme import MDPebbleRunner, MDBoulderRunner
    
    
    def pytest_report_header(config):
        env = MDTestEnv()
        return "mod_md: [apache: {aversion}({prefix}), mod_{ssl}, ACME server: {acme}]".format(
            prefix=env.prefix,
            aversion=env.get_httpd_version(),
            ssl=env.ssl_module,
            acme=env.acme_server,
        )
    
    
    @pytest.fixture(scope="package")
    def env(pytestconfig) -> MDTestEnv:
        level = logging.INFO
        console = logging.StreamHandler()
        console.setLevel(level)
        console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
        logging.getLogger('').addHandler(console)
        logging.getLogger('').setLevel(level=level)
        env = MDTestEnv(pytestconfig=pytestconfig)
        env.setup_httpd()
        env.apache_access_log_clear()
        env.httpd_error_log.clear_log()
        yield env
        env.apache_stop()
    
    
    @pytest.fixture(autouse=True, scope="package")
    def _md_package_scope(env):
        env.httpd_error_log.add_ignored_lognos([
            "AH10085"   # There are no SSL certificates configured and no other module contributed any
        ])
    
    
    @pytest.fixture(scope="package")
    def acme(env):
        acme_server = None
        if env.acme_server == 'pebble':
            acme_server = MDPebbleRunner(env, configs={
                'default': os.path.join(env.gen_dir, 'pebble/pebble.json'),
                'eab': os.path.join(env.gen_dir, 'pebble/pebble-eab.json'),
            })
        elif env.acme_server == 'boulder':
            acme_server = MDBoulderRunner(env)
        yield acme_server
        if acme_server is not None:
            acme_server.stop()
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016574� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/����������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�021440� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�021736� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/����������������������������������������0000775�0001751�0001751�00000000000�15032766614�023300� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/accounts/�������������������������������0000775�0001751�0001751�00000000000�15032766614�025117� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/accounts/ACME-localhost-0000/�����������0000775�0001751�0001751�00000000000�15032766614�030167� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/accounts/ACME-localhost-0000/account.pem0000664�0001751�0001751�00000006532�14156100407�032320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN ENCRYPTED PRIVATE KEY-----
    MIIJnzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQI0s8pf5rIPTECAggA
    MB0GCWCGSAFlAwQBKgQQ2u9SobgmVMhhZxYkXf9kpwSCCVD04Xywr0m+b5f+2aE5
    qjGr8y6xlf4NC/+QL6mBCw+9tlsgt7Z9bBt7PR1eMUQ0Bz5a9veBT2JwqGFU8XLv
    Anfd4a8ciKRx4kdP7JL08rkKAqPxuwkzMin3TeOJwsoghyvt8zFrXrWEcHyhHd4L
    HAoA3ccCxDHH7ydORd7rhEQUOkcjbaJkZi6pzvv+C7kgSTMKYBaI1mlNzX5Oxm6I
    ziwmDcOtRgKb17z26zOYWjzbKHGopPlFe9/l32JxTr5UuCihR4NoPGiK08280OWQ
    HIwRxQ900AKyJZM1q3RkH4r0xtiik0lX0isx+UIiNEefA4Za/kXLCM7hHVCGwF1z
    eE8oX2yNcsX/sw7aVLhRyVDzrT8C5T7+s+K0eV/hfyYXXAZ0z0H+l3f3TRbMlLuq
    1FQnOmEtQy0CbfPGNlzbiK3glp2fc2ZHubTkprMoRTkEKWNiXD0Suhnsll9eV3d2
    cHZgsCQyD3LRz+Xj2v6P+fDOcu7IuM7om9GEjNQB1e7dzo6HOSTG2mIsQo6VByJw
    syoK1zzC70Jhj/G6aFALTh4dMceoBDyHZzOfiVwC3dGX1QEnNvGD7Za/woMNIx8S
    hiqjntDhlXPXCRX/Z/Zvg///6+Ip9FqkCVk74DRWjH9iUzdP7/E1GCyAH2BSdsdc
    PnK15p79Ff5TMV91IQmnVV37s57VqXIez2RtuLd530iUk4RtkJ1/PphybHd+JW/n
    avMj8gsuWB7RqaBsmbjLmSudSl0DNgy0IJKZs11UifrZmSkaUJH+JJ1W2hLHR980
    X75IujUmZasWYkVqq0nvdy8JConCaLd3TT8r8DcO73vZqjFnN+EEHENaEg7F7ig8
    xkp0wk4F3u1BEnkwd34aLonZ9DtSK3miDRqlWXqQGESMaQLYQvHUn9q4X57Tyz4T
    9ZVPeLJiuHwCGq6z2BJhgkAlGs7Eqra0pMpjVnRdylTQzx0Q2vLQbrZasyBpReeM
    zGdadxRR84PyhAGDGdLKR8VCVFhWX32ZBfqJQOjpyAT30Wu11ZDvEPASuTL4GdcD
    o5seucpUZdgzrivvjUhYLkRd0WOjgJyuvtWdillpSiweeGfDAnZvUZUFLd4EMmwH
    W+IUr7yIsjNuGZU3NW0pW/L9d9GuwgljP61WKhS6B7hRmx22YU3z2Y7islXiey3m
    kZ37mAqdK4EIQca2j9GmBQk7oUz+boYdm4vtk7tJI07LEDI79U95B8x1MpzjuIbj
    zlYmH1yw8UefsFrOfjJ4BpkDjVux+J2DmSqCFb5XBcjwWsYiY17niW6Qfrypd6vq
    bew1HgbBhdBNQoL1P8uS1fNNwoHmhJc6PNHFFxU3NP91yqB8Igj3khqk9+/VBcCt
    8xRc/1jR5mfAgvaCWyQgIZAsCgTLnvEXy91MG/DKR0ZdOLZJNas+1W9fjhcFvP6S
    nNmeMMrIAxaI85RVvnLqPEZhsb9AOlyaf6tKFJiCteyQlie6MOQTKSp4jjSOVW+w
    q/WtSZup9zXo8Ek+TnLhD0IJhpIbfR5is5iZaVY7lbcg4pc3Csh/SiMUJ4TJgiPS
    /End7LPoRIabRnw4PBtJRNCwf3ilsWUmi95HU3wLAmLpI1AtnbfQi+zva4UJdOTV
    HJxNN84ZGuey1gG7qZb3U6WpwzQDKvqTm5jK32nIS/LuNv1qpv0FdAmvulV9wBar
    M19CcD5kOlTvNZcf6B4Fkrr+x+Anji/kUV4slIvUbAaU9P4lMO0ORCTg1es7QvI7
    v0KRYYSULrO+G2CNYL7fN8Vf5tRpBZ3H1o6u3plw/P86MTQPOskppjK1VKsBBmL2
    isdeumWjLpFVr1vWxTm68f88f+iau3BRUkCDQXFEVTN7YuOhpexb6Js0T220HYTS
    9hmeVUnNlXii1BpnxLhBx/0O3heVOLc/C7b7vASg5PljieUQmpuyeJSUAJm1vKrI
    p2G/46MgBl+3/NkzLRGepzAH2IGAhhtXEk/zePdRptbVr29+vGDX6IzEWqZ5UYHG
    P5JYzaojrmLd0BNYwEbCrRBRHyM4jYFkRERs/kwCh5/Kle/eZpb+bjvIsAs0xcOC
    /uRF8RfHW1h8M8Bm9tR+rUX8CTxaIF3IY+N5qSPstNt8xGYLv7uvd+KoK0xVHAm+
    FAreqql7koa5D0ncLjTpQGnHiLBKsYmJWC4+TKC+a5m0eKmRgO/r5o+7mmoB9qCZ
    bI9GB9HoYeVW/QVWfmoH0W6rbQCmK/VcSB1dGwvz9rKU1DXHhXvGU2k1IAfPX11t
    RfwUmmLtrM9tjOWdBh74N4G8UvTk5FGygzJ+Eclm/ABeAChIFU7mLJFejOue/bKq
    CRAQul45+CskNyVyZWZvWTFT0UMN290b4E4sjUKoLbFZiA1Y/aU+ruG9iwPJ3yVS
    s09VqogNwKBLWYW5TclUzgf71AQTlnZpTudkqwr36ogIAXXaQpE1f6/HLQz3k1PA
    WmTaxoM//X00WvTq2UxxSmKf7mNPEg9UZ9m4ZTKe35a//ONxXVjBjtK23yN5MuHY
    YrgWF84xlLRPY3Um2ukCsRGb7yZRhlPmOBeYQvRod7BqEA0UmIR+ctnBWDwzSZw7
    JWuR+AZdjIfM+Ilh15fokpLI5IFnTAqvTYDoF0185kqYPkjtI2STAWpALA9XJp70
    aF/rbdbSrRPFI1+izTIvQjffYftro7EOfCFv62XZm6tj5RLHalfgTcWoUWw81ylL
    DOZZaKsv4bOW7HCM47pitFojwzNf9OaHd5VTaSPWts49siF/qCxcG8bwu51picbc
    96H1h3/npNhxDUA5qKzkBK9Bs7panzXt2kNJxPzHEiCjVVGq7t/ei4TZGoSw806D
    kNPFhztVoM1k2m7F7lu1EYOwJH/yXKJUgJYIycIoQyRMX7h0jb76U0oOHrdkw3A2
    9Helksl8kqz10td2PZyoj3K/EWu+33cFKgLtC9JrDATR3Lhdo2N3BQQAotW2+Tht
    HqHj/UzUoIWcEkzCZeJhRn9WRRbbLeWKwdXBxGl0ZESpJJ2+Ml6QkMkdZSUzDURD
    kxYl04U9JXk6vC2hT6780OBLnLivBqIaSUJ72DSkOFnifFoP/OeglWFVkJHWQjQP
    aGMcPD/xLLYhdRQlJND9K12FXtsazW2K/V+861y4rJOt6zJGSZwPrQBkLf7QBNAC
    DWiLOvp6tLT58pX8TSlplbITcQ==
    -----END ENCRYPTED PRIVATE KEY-----
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar  �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/accounts/ACME-localhost-0000/account.json���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/accounts/ACME-localhost-0000/account.jso0000664�0001751�0001751�00000000224�14156100407�032322� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
      "disabled": false,
      "url": "http://localhost:4000/acme/reg/494",
      "ca-url": "http://localhost:4000/directory",
      "id": "ACME-localhost-0000"
    }����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/archive/��������������������������������0000775�0001751�0001751�00000000000�15032766614�024721� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/archive/7007-1502285564.org.1/����������0000775�0001751�0001751�00000000000�15032766614�027326� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/archive/7007-1502285564.org.1/md.json���0000664�0001751�0001751�00000000537�14156100407�030612� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
      "name": "7007-1502285564.org",
      "domains": [
        "7007-1502285564.org"
      ],
      "contacts": [
        "mailto:admin@7007-1502285564.org"
      ],
      "transitive": 0,
      "ca": {
        "proto": "ACME",
        "url": "http://localhost:4000/directory",
        "agreement": "http://boulder:4000/terms/v1"
      },
      "state": 1,
      "renew-mode": 2,
      "renew-window": 1209600
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/challenges/�����������������������������0000775�0001751�0001751�00000000000�15032766614�025405� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/domains/��������������������������������0000775�0001751�0001751�00000000000�15032766614�024732� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/domains/7007-1502285564.org/������������0000775�0001751�0001751�00000000000�15032766614�027200� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/domains/7007-1502285564.org/md.json�����0000664�0001751�0001751�00000001030�14156100407�030451� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
      "name": "7007-1502285564.org",
      "domains": [
        "7007-1502285564.org"
      ],
      "contacts": [
        "mailto:admin@7007-1502285564.org"
      ],
      "transitive": 0,
      "ca": {
        "account": "ACME-localhost-0000",
        "proto": "ACME",
        "url": "http://localhost:4000/directory",
        "agreement": "http://boulder:4000/terms/v1"
      },
      "cert": {
        "url": "http://localhost:4000/acme/cert/ff0f19c7ed4f48fad0e3a32fe12bfd7b87af",
        "expires": "Tue, 07 Nov 2017 12:33:00 GMT"
      },
      "state": 2,
      "renew-mode": 2,
      "renew-window": 1209600
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/domains/7007-1502285564.org/chain.pem���0000664�0001751�0001751�00000003143�14156100407�030752� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN CERTIFICATE-----
    MIIEijCCA3KgAwIBAgICEk0wDQYJKoZIhvcNAQELBQAwKzEpMCcGA1UEAwwgY2Fj
    a2xpbmcgY3J5cHRvZ3JhcGhlciBmYWtlIFJPT1QwHhcNMTUxMDIxMjAxMTUyWhcN
    MjAxMDE5MjAxMTUyWjAfMR0wGwYDVQQDExRoYXBweSBoYWNrZXIgZmFrZSBDQTCC
    ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIKR3maBcUSsncXYzQT13D5
    Nr+Z3mLxMMh3TUdt6sACmqbJ0btRlgXfMtNLM2OU1I6a3Ju+tIZSdn2v21JBwvxU
    zpZQ4zy2cimIiMQDZCQHJwzC9GZn8HaW091iz9H0Go3A7WDXwYNmsdLNRi00o14U
    joaVqaPsYrZWvRKaIRqaU0hHmS0AWwQSvN/93iMIXuyiwywmkwKbWnnxCQ/gsctK
    FUtcNrwEx9Wgj6KlhwDTyI1QWSBbxVYNyUgPFzKxrSmwMO0yNff7ho+QT9x5+Y/7
    XE59S4Mc4ZXxcXKew/gSlN9U5mvT+D2BhDtkCupdfsZNCQWp27A+b/DmrFI9NqsC
    AwEAAaOCAcIwggG+MBIGA1UdEwEB/wQIMAYBAf8CAQAwQwYDVR0eBDwwOqE4MAaC
    BC5taWwwCocIAAAAAAAAAAAwIocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAyBggrBgEFBQcw
    AYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5jb20wOwYIKwYB
    BQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMvZHN0cm9vdGNh
    eDMucDdjMB8GA1UdIwQYMBaAFOmkP+6epeby1dd5YDyTpi4kjpeqMFQGA1UdIARN
    MEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUHAgEWImh0dHA6
    Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUwMzAxoC+gLYYr
    aHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JMLmNybDAdBgNV
    HQ4EFgQU+3hPEvlgFYMsnxd/NBmzLjbqQYkwDQYJKoZIhvcNAQELBQADggEBAA0Y
    AeLXOklx4hhCikUUl+BdnFfn1g0W5AiQLVNIOL6PnqXu0wjnhNyhqdwnfhYMnoy4
    idRh4lB6pz8Gf9pnlLd/DnWSV3gS+/I/mAl1dCkKby6H2V790e6IHmIK2KYm3jm+
    U++FIdGpBdsQTSdmiX/rAyuxMDM0adMkNBwTfQmZQCz6nGHw1QcSPZMvZpsC8Skv
    ekzxsjF1otOrMUPNPQvtTWrVx8GlR2qfx/4xbQa1v2frNvFBCmO59goz+jnWvfTt
    j2NjwDZ7vlMBsPm16dbKYC840uvRoZjxqsdc3ChCZjqimFqlNG/xoPA8+dTicZzC
    XE9ijPIcvW6y1aa3bGw=
    -----END CERTIFICATE-----
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/domains/7007-1502285564.org/cert.pem����0000664�0001751�0001751�00000003704�14156100407�030630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN CERTIFICATE-----
    MIIFkDCCBHigAwIBAgITAP8PGcftT0j60OOjL+Er/XuHrzANBgkqhkiG9w0BAQsF
    ADAfMR0wGwYDVQQDDBRoMnBweSBoMmNrZXIgZmFrZSBDQTAeFw0xNzA4MDkxMjMz
    MDBaFw0xNzExMDcxMjMzMDBaME0xHDAaBgNVBAMTEzcwMDctMTUwMjI4NTU2NC5v
    cmcxLTArBgNVBAUTJGZmMGYxOWM3ZWQ0ZjQ4ZmFkMGUzYTMyZmUxMmJmZDdiODdh
    ZjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMHuhVxT9Jpc6EpNAhrq
    RqzDJ4tWSG9BtguKZzh3sbY92EE5rqym7wpdb5DG5gwew4iD1R+YizY+99+00qlB
    3kNBUVsJCBnew0apmhPq4jjF8v8t3Qqq0ISn2Sdv5bt5mB9NWeO83h3zT1LW0rTm
    847nwxUuGxlIjLXxsibUvPunMfyGJUshflN5V9/Q3YQBOCnDWy5s4FKN2N34cHFE
    IgJo5ToBKZLp9eUaLm03mlfhTFc3/h0AtWwMZ5P2tRRB9EiijqI9nkrVzqyi1QTN
    Hn/XfgDgKRCyMp6i5kcK3hCXo4GjOIU0KA91ttf3IeKhXHKzC7ybc4hdJH2rWzoN
    srYq6tNZ+cOaa1E/H+v+OMSeIRaRrpM56c3nUssIzbneMIXuLHuOluaaL4baCjYp
    Pdc80bUlps06XcnVHysAbsfbtWAtUdzj2l4flVySruGoaqVDudl1GqYoYa+0oReM
    Zqd09Q+pCQvDNE+jiVq3An+JA4msux9EMMz7jkAwnl8iiWy0GMuQPsL5gp3TEXGY
    Cp1wQlzpmxZSdUZ+J6f4UkFOS/Zn6gS6nSxN8nj3XKbRYRbebPQMwRGYGttCyeZO
    dHiUY/3gQBUdpcMBJhAa5GFoabK0J5XPmK2E1P9cGQo7DbNn+Skojnz2WuUtCuyo
    m9la14Ruca9V8NmjBsu+4mXvAgMBAAGjggGVMIIBkTAOBgNVHQ8BAf8EBAMCBaAw
    HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYD
    VR0OBBYEFH426IYgY0KXUe9cLMZ3d8tipsDkMB8GA1UdIwQYMBaAFPt4TxL5YBWD
    LJ8XfzQZsy426kGJMGYGCCsGAQUFBwEBBFowWDAiBggrBgEFBQcwAYYWaHR0cDov
    LzEyNy4wLjAuMTo0MDAyLzAyBggrBgEFBQcwAoYmaHR0cDovLzEyNy4wLjAuMTo0
    MDAwL2FjbWUvaXNzdWVyLWNlcnQwHgYDVR0RBBcwFYITNzAwNy0xNTAyMjg1NTY0
    Lm9yZzAnBgNVHR8EIDAeMBygGqAYhhZodHRwOi8vZXhhbXBsZS5jb20vY3JsMGEG
    A1UdIARaMFgwCAYGZ4EMAQIBMEwGAyoDBDBFMCIGCCsGAQUFBwIBFhZodHRwOi8v
    ZXhhbXBsZS5jb20vY3BzMB8GCCsGAQUFBwICMBMMEURvIFdoYXQgVGhvdSBXaWx0
    MA0GCSqGSIb3DQEBCwUAA4IBAQBfqLXSJZ5Izs2I44cXWrAto631aTylValp0Fiy
    Zz1dj00FS6XN5DGtfIyq7Ymd3MMiOZCLkTOMMb7BrJAvcgeJteKwdk3ffXEDyKH0
    1ttXK7l46trEyGOB+f9PMMKxVMyhDhGKyb6ro4Y5WTK/w4862soqKcP1SjHvk65u
    lIkFws1fWYYzqPLKLij2ILm+4NjdGIl8qPQWP2PtbOaDTFspJBz6hvLmqRgmjVVv
    cENwBUML4LCkVY3TUqoBHXDhpocTZlVeAVRVsroosboQJlY5nIKz6cOjilILn4cT
    hgEKa5IRwK5lUveCoeQtYUyLoyp5ncbota+UxNxCnkl/0veK
    -----END CERTIFICATE-----
    ������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/domains/7007-1502285564.org/pkey.pem����0000664�0001751�0001751�00000006310�14156100407�030637� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN PRIVATE KEY-----
    MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDB7oVcU/SaXOhK
    TQIa6kaswyeLVkhvQbYLimc4d7G2PdhBOa6spu8KXW+QxuYMHsOIg9UfmIs2Pvff
    tNKpQd5DQVFbCQgZ3sNGqZoT6uI4xfL/Ld0KqtCEp9knb+W7eZgfTVnjvN4d809S
    1tK05vOO58MVLhsZSIy18bIm1Lz7pzH8hiVLIX5TeVff0N2EATgpw1subOBSjdjd
    +HBxRCICaOU6ASmS6fXlGi5tN5pX4UxXN/4dALVsDGeT9rUUQfRIoo6iPZ5K1c6s
    otUEzR5/134A4CkQsjKeouZHCt4Ql6OBoziFNCgPdbbX9yHioVxyswu8m3OIXSR9
    q1s6DbK2KurTWfnDmmtRPx/r/jjEniEWka6TOenN51LLCM253jCF7ix7jpbmmi+G
    2go2KT3XPNG1JabNOl3J1R8rAG7H27VgLVHc49peH5Vckq7hqGqlQ7nZdRqmKGGv
    tKEXjGandPUPqQkLwzRPo4latwJ/iQOJrLsfRDDM+45AMJ5fIolstBjLkD7C+YKd
    0xFxmAqdcEJc6ZsWUnVGfien+FJBTkv2Z+oEup0sTfJ491ym0WEW3mz0DMERmBrb
    QsnmTnR4lGP94EAVHaXDASYQGuRhaGmytCeVz5ithNT/XBkKOw2zZ/kpKI589lrl
    LQrsqJvZWteEbnGvVfDZowbLvuJl7wIDAQABAoICAQCVSZob0v1O/wpKeDGQqpwx
    TiHY31jvXHRZOffvviRtl/ora84NVoxZPEgv+Q0Kc3wuUN31bqZr4dlKupYYeX4x
    48xO+grkb1l/wfu8LWpsLeW7joDEP245UESYWUlOInJ6Vj9GUxPhlnWP3ZNicw83
    CS5h1ZZCxlibjy2HOukoCDMwo8t9pJDsjVKaFt0PSykC7UH54RJmOo+hgCh+6OYN
    WNZs6owobjY+YQMwTEdiMytjUNUrWmpOfNYXTyliKMt2RrzqI+kAzspElyzIf2Zl
    H2v+HJFAKw1QlTITqkf8Gd9iYlWWJOpZzFIuui25mmHiYfY9AKXVaW4313tomzbg
    L9Muc0pCmR8ge/hsC+C2QkVhHRFThakd5zU8rOEeXClzLKg1tjSVwcyNllXwd3Uy
    gQRtDqAWcWhXj2pqPzLc4v/wobjPE+xEpAbvDBvEof1fMy1PBeyKq7T4mIxswuWF
    takm9/Bt15K2TNBc7qNQV2x+MCS0Bi2Hd1yjLbIHllBDQR2ZsHRw1D38ckbL7ATE
    yDwnzI2gxlYYV7K/iQG9XkM54Ra5tNOFYv9GiCw+JPrLcQ5qmGsCCu6lfktMC8pN
    7VQRbHt60ZKaunE1muwWDmyYzP106qUXMw6nIVMyqX0ywTEPAgtRgWcucLWR33DD
    k1OBcq2tOceaZjA5Pbi4sQKCAQEA+MbI4HEbROlsPeQ7VMOoAHjJPWuhDNXqnz4Q
    c4z3X+W61TAWZINRENYDZd3c7D7wOWb9VBA+o62xrzYviul9qhTAjZ8dRfxagJpH
    OxNY348HNj+IxONj3RXr/7tfOXtzcjiFwzn85oPLRM56XfjYZ5lUgQBSEauXOue5
    +bpNBvrYZLPm7i5BM8RpBElH2wtCizLAE9BrKYUqTYWyl76miPfpeSVMv2JOpUwp
    josVrAWAOoQHeIrCLmSF43oqmtzJ9Aq1r/VeOQB/3TT4E0RhWhDWOg3zNuA20w+E
    VuKyl4J/XLo6T86Zc/PM4+vb8zPztjZHQVJj58Iq7N4/y5cBfQKCAQEAx5AP10sw
    C4kCwU/yXORhimMPlRldKx2h+8Ha/0whTkehXaJ0synCV0ZLh7jSgfe81Zx5/3RK
    KKRWVx7+wmQiOqfSIBJN4xWdpVDS7yndk/FW8sYqT1v2sgr2t1u41bQAY3qzezsK
    elNsjbRsUCVvVu9HZ5zH7Pvmf0Ma8P2t8EioQWJ2ptgF6imTXIrQORJPBqDEzp6W
    EjiHC9kuZ2E+uPGl+6oQcxRUjtFkxnI9LgpOQCjNNIhW6cEhJxV3z8YIUnUyd7vd
    i0eEfhKF+DXzrqbtve63iGGU7TFMiiNF59hPxKHkPvHnUlXNZjJ8om9M579i/9fm
    OHYWaWFuzb6g2wKCAQAIZ37FxkxriY80kA9JD8sPKQVzY71vF5Lzij84CB0bSkGD
    jjpTbvRAI1q+CD68ZGvtJIOOYXYcRXPpPWVhxf2Oz2Cp6CQvBxVvnsalQkQQWV6f
    AIp4TE5FW8Y7P3M6F+eQhkROkhjvGKi3TFpp7kwxQ8bNDNu46RkUzltECn0rrTG+
    RS2aAkoFm68IjAk3Zyv6U96VTMcyAeOp9shPxAsQOX/TreTn2kRZ5TbKL/ytcQoh
    7+/orJdexdqYErp5vNe9vNbieOGT/2ZSbMWssPSw/DygfXQn+G8htjZ8UPBDmg7/
    bPMnWw1oE2ZqlL87ehfTogXKOSRS4gZdNizljdZpAoIBADxSfZdUcOdruNt6MQaH
    Ojy8iN9G1XTM9kPFa080UfT5jfthuejWPJpo8zfJVEhY/EmNjQr8udXjJv4armNQ
    JVCZndh37/cud4KbFceZXhL0JpYn9G4cnEthKQZvwUVHrb5kPpCHXjlvsiZ7XSo0
    xpz+oxTcvUoTMq9RN3mVFNjG/aUWAEuajN8lRhf5FcvKjvyv6A2UvkQvthKMyYwS
    RwVcdhHGbEZ85Lpu7QlXSsr57oFSVAUHGU57RGwt/xNdBvL13hV3QhZxvcjmDHzk
    wg4PA1ogKHYfGQdBmaM/2kekiSgkz3t/X67xpK65oBbxkcuTfHddaYezmj6sZvPm
    JXUCggEBAO37OxP7B66FQghuBkfui8sPymY2oSFQIb3IRO5A17/wp9yW1f9X4Bu4
    dh7ln+6IEURZyldAZcVRSHbjrL8VWXtS86eDttnKD7L46BbqAytckc/pebA/5bu0
    tjsM8ulayPGuJzEl/g1F1bU1eduXkmq/O7636S0Q1KCVHldn9qNgkowfjpzANHNs
    ksSwxMIY8n4U2kckMmfCj2B6UrnqQ6Bs7IaijQJ5u/mGYke+gKEGQ99esx2Ts1Vl
    w8WDaDUOwHEywuFyqtGJzizX8BazIzwmSCh8hpedDtFVVnfjszLnf3Y+FOrb9XlM
    Wc8hH7giOwSubI2D2mauspM5CZlez7A=
    -----END PRIVATE KEY-----
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/staging/��������������������������������0000775�0001751�0001751�00000000000�15032766614�024734� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/tmp/������������������������������������0000775�0001751�0001751�00000000000�15032766614�024100� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/md_store.json���������������������������0000664�0001751�0001751�00000000216�14156100407�025772� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
      "version": "0.6.1-git",
      "store": {
        "version": 1.0
      },
      "key": "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphYmNkZWZnaGlqa2xtbm9wcXJzdHV2"
    }����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/store_migrate/1.0/sample1/httpd.json������������������������������0000664�0001751�0001751�00000000070�14156100407�025277� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
      "proto": {
        "http": true,
        "https": true
      }
    }������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/test_920/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020145� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/test_920/002.pubcert����������������������������������������������0000664�0001751�0001751�00000006762�14156100407�022033� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-----BEGIN CERTIFICATE-----
    MIIFYDCCBEigAwIBAgISAwOcRk1FTt55/NLK6Fn2aPJpMA0GCSqGSIb3DQEBCwUA
    MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
    ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTA1MzExNjA2MzVaFw0x
    OTA4MjkxNjA2MzVaMBYxFDASBgNVBAMTC2Vpc3Npbmcub3JnMIIBIjANBgkqhkiG
    9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9d5xZdknImIPfmiUaiiRhHLx4bvazWRTgA2+
    etRNKr42MRjkuLbAhvxGjhw4El0GJlbngKTfiSK0Vq0idW/ehUr++czRSDrRVfqq
    qcI/F4NXLIbIZfmR7/vG0IP8Xc8D9VyQCX0uDapCvw+A/U46p0VOZz4bIB/bl0BW
    /mqBvVhBU9owskUcPjwwI/tK6My933CUVKXuFpPZ4V7zoY0/8Xa6JmWC2q1+7XmE
    h51hPnU35dYH1bA7WblX8rVxnEPCyCOgABVLKb6NhWfTCEqy+yzr32KsoSR1xqe4
    T2EeTcoamwF2yhz2zRC4glX0LM4inJ1/ZOQ+nKbFZTOPVWEnLQIDAQABo4ICcjCC
    Am4wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
    AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTfO7pZGPLsa0NuPZMG4NGlr1TaWjAf
    BgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcBAQRjMGEw
    LgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlwdC5vcmcw
    LwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5vcmcv
    MCcGA1UdEQQgMB6CC2Vpc3Npbmcub3Jngg93d3cuZWlzc2luZy5vcmcwTAYDVR0g
    BEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0
    cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEFBgorBgEEAdZ5AgQCBIH2BIHzAPEA
    dwB0ftqDMa0zEJEhnM4lT0Jwwr/9XkIgCMY3NXnmEHvMVgAAAWsO24QlAAAEAwBI
    MEYCIQD8yd2uHl2DNgvnBkSiA8vsK5pOv204NixI9F89LWERwgIhAPMLLiZkFG2h
    DTpEwF50BbZ+laYH8VP03Teq5csk2lX0AHYAKTxRllTIOWW6qlD8WAfUt2+/WHop
    ctykwwz05UVH9HgAAAFrDtuEFgAABAMARzBFAiEA3bYpKSNigSe0HuDyH/kerTW2
    55ugvODp6d+vNbNmgZoCIGTd4cio769BTKfLJTqNbjc9sKK9T7XkHUO4JgQdY6Nq
    MA0GCSqGSIb3DQEBCwUAA4IBAQBeatZxh8leVmeFE/IYTKKqHyZqTccJKdugXIOr
    uIF6sLup/8Fv/2N0wZc+edkj+NCyWhxxkZULyW6xhlL7rtzcwLYbQBSxKvT4Utur
    01a5bwhM62MdMjzkFgCCa5nRKPQ7bc684RrUFNi94d0KSb5ArFv8wovqPW7jbmFp
    X50dYKCE+wohFPHcsQapnV0lXK4+5qJZSZkp/pHANdndLCvFfzRHhV4nqRA12G2T
    VVWjdHN6ShL2uykJVAnSBhu/XD4mh79Yq9TQtS1DHfP3HcKstLqR0nrwBFaB6087
    jXfIpJ46yObq001qHeUMhT+B3WI2YPp/hY7u8A9+hCmDyyq8
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
    MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
    DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
    SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
    GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
    AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
    q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
    SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
    Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
    a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
    /PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
    AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
    CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
    bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
    c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
    VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
    ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
    MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
    Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
    AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
    uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
    wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
    X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
    PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
    KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
    -----END CERTIFICATE-----
    ��������������httpd-2.4.64/test/modules/md/data/test_conf_validate/�����������������������������������������������0000775�0001751�0001751�00000000000�15032766614�022431� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/test_conf_validate/test_014.conf����������������������������������0000664�0001751�0001751�00000000242�14156100407�024625� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# global server name as managed domain name
    
    MDomain resistance.fritz.box www.example2.org
    
    <VirtualHost *:12346>
        ServerName www.example2.org
    
    </VirtualHost>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/test_drive/�������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020744� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/test_drive/test1.example.org.conf���������������������������������0000664�0001751�0001751�00000000272�14156100407�025060� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# A setup that required manual driving, e.g. invoking a2md outside apache
    #
    MDRenewMode manual
    
    MDomain test1.not-forbidden.org www.test1.not-forbidden.org mail.test1.not-forbidden.org
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/test_roundtrip/���������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�021661� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/data/test_roundtrip/temp.conf������������������������������������������0000664�0001751�0001751�00000001757�14156100407�023473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������  MDDriveMode manual
      MDCertificateAuthority http://localhost:4000/directory
      MDCertificateProtocol ACME
      MDCertificateAgreement http://boulder:4000/terms/v1
    
      ServerAdmin mailto:admin@test102-1499953506.org
    
      ManagedDomain test102-1499953506.org test-a.test102-1499953506.org test-b.test102-1499953506.org
    
    <VirtualHost *:5001>
        ServerName test-a.test102-1499953506.org
        DocumentRoot htdocs/a
    
        SSLEngine on
        SSLCertificateFile /Users/sei/projects/mod_md/test/gen/apache/md/domains/test102-1499953506.org/cert.pem
        SSLCertificateKeyFile /Users/sei/projects/mod_md/test/gen/apache/md/domains/test102-1499953506.org/pkey.pem
    </VirtualHost>
    
    <VirtualHost *:5001>
        ServerName test-b.test102-1499953506.org
        DocumentRoot htdocs/b
    
        SSLEngine on
        SSLCertificateFile /Users/sei/projects/mod_md/test/gen/apache/md/domains/test102-1499953506.org/cert.pem
        SSLCertificateKeyFile /Users/sei/projects/mod_md/test/gen/apache/md/domains/test102-1499953506.org/pkey.pem
    </VirtualHost>
    
    �����������������httpd-2.4.64/test/modules/md/test_300_conf_validate.py����������������������������������������������0000664�0001751�0001751�00000055175�14750656217�022474� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md basic configurations
    import os
    
    import re
    import time
    from datetime import datetime, timedelta
    
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestConf:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.purge_store()
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        # test case: just one MDomain definition
        def test_md_300_001(self, env):
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain
                ]
            )
    
        # test case: two MDomain definitions, non-overlapping
        def test_md_300_002(self, env):
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org
                MDomain example2.org www.example2.org mail.example2.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain
                ]
            )
    
        # test case: two MDomain definitions, exactly the same
        def test_md_300_003(self, env):
            assert env.apache_stop() == 0
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                """).install()
            assert env.apache_fail() == 0
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10038"   # two Managed Domains have an overlap in domain
                ]
            )
    
        # test case: two MDomain definitions, overlapping
        def test_md_300_004(self, env):
            assert env.apache_stop() == 0
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                MDomain example2.org test3.not-forbidden.org www.example2.org mail.example2.org
                """).install()
            assert env.apache_fail() == 0
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10038"   # two Managed Domains have an overlap in domain
                ]
            )
    
        # test case: two MDomains, one inside a virtual host
        def test_md_300_005(self, env):
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                <VirtualHost *:12346>
                    MDomain example2.org www.example2.org www.example3.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain
                ]
            )
    
        # test case: two MDomains, one correct vhost name
        def test_md_300_006(self, env):
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                <VirtualHost *:12346>
                    ServerName example2.org
                    MDomain example2.org www.example2.org www.example3.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain
                ]
            )
    
        # test case: two MDomains, two correct vhost names
        def test_md_300_007(self, env):
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                <VirtualHost *:12346>
                    ServerName example2.org
                    MDomain example2.org www.example2.org www.example3.org
                </VirtualHost>
                <VirtualHost *:12346>
                    ServerName www.example2.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain
                ]
            )
    
        # test case: two MDomains, overlapping vhosts
        def test_md_300_008(self, env):
            MDConf(env, text="""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                <VirtualHost *:12346>
                    ServerName example2.org
                    ServerAlias www.example3.org
                    MDomain example2.org www.example2.org www.example3.org
                </VirtualHost>
    
                <VirtualHost *:12346>
                    ServerName www.example2.org
                    ServerAlias example2.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain
                ]
            )
    
        # test case: vhosts with overlapping MDs
        def test_md_300_009(self, env):
            assert env.apache_stop() == 0
            conf = MDConf(env)
            conf.add("""
                MDMembers manual
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
                MDomain example2.org www.example2.org www.example3.org
                """)
            conf.add_vhost(port=12346, domains=["example2.org", "www.example3.org"], with_ssl=True)
            conf.add_vhost(port=12346, domains=["www.example2.org", "example2.org"], with_ssl=True)
            conf.add_vhost(port=12346, domains=["not-forbidden.org", "example2.org"], with_ssl=True)
            conf.install()
            assert env.apache_fail() == 0
            env.apache_stop()
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10238"   # 2 MDs match Virtualhost
                ]
            )
    
        # test case: MDomain, vhost with matching ServerAlias
        def test_md_300_010(self, env):
            conf = MDConf(env)
            conf.add("""
                MDomain not-forbidden.org www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
    
                <VirtualHost *:12346>
                    ServerName not-forbidden.org
                    ServerAlias test3.not-forbidden.org
                </VirtualHost>
                """)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # test case: MDomain, misses one ServerAlias
        def test_md_300_011a(self, env):
            env.apache_stop()
            conf = MDConf(env, text="""
                MDomain not-forbidden.org manual www.not-forbidden.org mail.not-forbidden.org test3.not-forbidden.org
            """)
            conf.add_vhost(port=env.https_port, domains=[
                "not-forbidden.org", "test3.not-forbidden.org", "test4.not-forbidden.org"
            ])
            conf.install()
            assert env.apache_fail() == 0
            env.apache_stop()
            env.httpd_error_log.ignore_recent([
                "AH10040"   # A requested MD certificate will not match ServerName
            ])
    
        # test case: MDomain, misses one ServerAlias, but auto add enabled
        def test_md_300_011b(self, env):
            env.apache_stop()
            MDConf(env, text="""
                MDomain not-forbidden.org auto mail.not-forbidden.org
    
                <VirtualHost *:%s>
                    ServerName not-forbidden.org
                    ServerAlias test3.not-forbidden.org
                    ServerAlias test4.not-forbidden.org
                </VirtualHost>
                """ % env.https_port).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # test case: MDomain does not match any vhost
        def test_md_300_012(self, env):
            MDConf(env, text="""
                MDomain example012.org www.example012.org
                <VirtualHost *:12346>
                    ServerName not-forbidden.org
                    ServerAlias test3.not-forbidden.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain
                ]
            )
    
        # test case: one md covers two vhosts
        def test_md_300_013(self, env):
            MDConf(env, text="""
                MDomain example2.org test-a.example2.org test-b.example2.org
                <VirtualHost *:12346>
                    ServerName test-a.example2.org
                </VirtualHost>
                <VirtualHost *:12346>
                    ServerName test-b.example2.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # test case: global server name as managed domain name
        def test_md_300_014(self, env):
            MDConf(env, text=f"""
                MDomain www.{env.http_tld} www.example2.org
                MDRenewMode manual
    
                <VirtualHost *:12346>
                    ServerName www.example2.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # test case: valid pkey specification
        def test_md_300_015(self, env):
            MDConf(env, text="""
                MDPrivateKeys Default
                MDPrivateKeys RSA
                MDPrivateKeys RSA 2048
                MDPrivateKeys RSA 3072
                MDPrivateKeys RSA 4096
                MDRenewMode manual
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # test case: invalid pkey specification
        @pytest.mark.parametrize("line,exp_err_msg", [
            ("MDPrivateKeys", "needs to specify the private key type"), 
            ("MDPrivateKeys Default RSA 1024", "'Default' allows no other parameter"),
            ("MDPrivateKeys RSA 1024", "must be 2048 or higher"),
            ("MDPrivateKeys RSA 1024", "must be 2048 or higher"),
            ("MDPrivateKeys rsa 2048 rsa 4096", "two keys of type 'RSA' are not possible"),
            ("MDPrivateKeys p-256 secp384r1 P-256", "two keys of type 'P-256' are not possible"),
            ])
        def test_md_300_016(self, env, line, exp_err_msg):
            MDConf(env, text=line).install()
            assert env.apache_fail() == 0
            assert exp_err_msg in env.apachectl_stderr
    
        # test case: invalid renew window directive
        @pytest.mark.parametrize("line,exp_err_msg", [
            ("MDRenewWindow dec-31", "has unrecognized format"), 
            ("MDRenewWindow 1y", "has unrecognized format"), 
            ("MDRenewWindow 10 d", "takes one argument"), 
            ("MDRenewWindow 102%", "a length of 100% or more is not allowed.")])
        def test_md_300_017(self, env, line, exp_err_msg):
            MDConf(env, text=line).install()
            assert env.apache_fail() == 0
            assert exp_err_msg in env.apachectl_stderr
    
        # test case: invalid uri for MDProxyPass
        @pytest.mark.parametrize("line,exp_err_msg", [
            ("MDHttpProxy", "takes one argument"), 
            ("MDHttpProxy localhost:8080", "scheme must be http or https"),
            ("MDHttpProxy https://127.0.0.1:-443", "invalid port"),
            ("MDHttpProxy HTTP localhost 8080", "takes one argument")])
        def test_md_300_018(self, env, line, exp_err_msg):
            MDConf(env, text=line).install()
            assert env.apache_fail() == 0, "Server accepted test config {}".format(line)
            assert exp_err_msg in env.apachectl_stderr
    
        # test case: invalid parameter for MDRequireHttps
        @pytest.mark.parametrize("line,exp_err_msg", [
            ("MDRequireHTTPS yes", "supported parameter values are 'temporary' and 'permanent'"),
            ("MDRequireHTTPS", "takes one argument")])
        def test_md_300_019(self, env, line, exp_err_msg):
            MDConf(env, text=line).install()
            assert env.apache_fail() == 0, "Server accepted test config {}".format(line)
            assert exp_err_msg in env.apachectl_stderr
    
        # test case: invalid parameter for MDMustStaple
        @pytest.mark.parametrize("line,exp_err_msg", [
            ("MDMustStaple", "takes one argument"), 
            ("MDMustStaple yes", "supported parameter values are 'on' and 'off'"),
            ("MDMustStaple true", "supported parameter values are 'on' and 'off'")])
        def test_md_300_020(self, env, line, exp_err_msg):
            MDConf(env, text=line).install()
            assert env.apache_fail() == 0, "Server accepted test config {}".format(line)
            assert exp_err_msg in env.apachectl_stderr
    
        # test case: alt-names incomplete detection, github isse #68
        def test_md_300_021(self, env):
            env.apache_stop()
            conf = MDConf(env, text="""
                MDMembers manual
                MDomain secret.com
                """)
            conf.add_vhost(port=12344, domains=[
                "not.secret.com", "secret.com"
            ])
            conf.install()
            assert env.apache_fail() == 0
            # this is unreliable on debian
            #assert env.httpd_error_log.scan_recent(
            #    re.compile(r'.*Virtual Host not.secret.com:0 matches Managed Domain \'secret.com\', '
            #               'but the name/alias not.secret.com itself is not managed. A requested '
            #               'MD certificate will not match ServerName.*'), timeout=10
            #)
    
        # test case: use MDRequireHttps in an <if> construct, but not in <Directory
        def test_md_300_022(self, env):
            MDConf(env, text="""
                MDomain secret.com
                <If "1 == 1">
                  MDRequireHttps temporary
                </If>
                <VirtualHost *:12344>
                    ServerName secret.com
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10105"   # MD secret.com does not match any VirtualHost with 'SSLEngine on'
                ]
            )
    
        # test case: use MDRequireHttps not in <Directory
        def test_md_300_023(self, env):
            conf = MDConf(env, text="""
                MDomain secret.com
                <Directory /tmp>
                  MDRequireHttps temporary
                </Directory>
                """)
            conf.add_vhost(port=12344, domains=["secret.com"])
            conf.install()
            assert env.apache_fail() == 0
    
        # test case: invalid parameter for MDCertificateAuthority
        @pytest.mark.parametrize("ca,exp_err_msg", [
            ("", "takes one argument"),
            ("yes", "The CA name 'yes' is not known "),
        ])
        def test_md_300_024(self, env, ca, exp_err_msg):
            conf = MDConf(env, text=f"""
                MDCertificateAuthority {ca}
                MDRenewMode manual  # lets not contact these in testing
            """)
            conf.install()
            assert env.apache_fail() == 0
            assert exp_err_msg in env.apachectl_stderr
    
        # test case: valid parameter for MDCertificateAuthority
        @pytest.mark.parametrize("ca, url", [
            ("LetsEncrypt", "https://acme-v02.api.letsencrypt.org/directory"),
            ("letsencrypt", "https://acme-v02.api.letsencrypt.org/directory"),
            ("letsencrypt-test", "https://acme-staging-v02.api.letsencrypt.org/directory"),
            ("LETSEncrypt-TESt", "https://acme-staging-v02.api.letsencrypt.org/directory"),
            ("buypass", "https://api.buypass.com/acme/directory"),
            ("buypass-test", "https://api.test4.buypass.no/acme/directory"),
        ])
        def test_md_300_025(self, env, ca, url):
            domain = f"test1.{env.http_tld}"
            conf = MDConf(env, text=f"""
                MDCertificateAuthority {ca}
                MDRenewMode manual
            """)
            conf.add_md([domain])
            conf.install()
            assert env.apache_restart() == 0, "Server did not accepted CA '{}'".format(ca)
            md = env.get_md_status(domain)
            assert md['ca']['urls'][0] == url, f"CA url '{url}' not set in {md}"
    
        # vhost on another address, see #278
        def test_md_300_026(self, env):
            assert env.apache_stop() == 0
            conf = MDConf(env)
            domain = f"t300-026.{env.http_tld}"
            conf.add(f"""
                MDomain {domain}
                """)
            conf.add_vhost(port=env.http_port, domains=[domain], with_ssl=False)
            conf.add(f"""
                <VirtualHost 10.0.0.1:{env.https_port}>
                  ServerName {domain}
                  ServerAlias xxx.{env.http_tld}
                  SSLEngine on
                </VirtualHost>
                <VirtualHost 10.0.0.1:12345>
                  ServerName {domain}
                  SSLEngine on
                </VirtualHost>
                """)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # test case: configure more than 1 CA
        @pytest.mark.parametrize("cas, should_work", [
            (["https://acme-v02.api.letsencrypt.org/directory"], True),
            (["https://acme-v02.api.letsencrypt.org/directory", "buypass"], True),
            (["x", "buypass"], False),
            (["letsencrypt", "abc"], False),
            (["letsencrypt", "buypass"], True),
        ])
        def test_md_300_027(self, env, cas, should_work):
            domain = f"test1.{env.http_tld}"
            conf = MDConf(env, text=f"""
                MDCertificateAuthority {' '.join(cas)}
                MDRenewMode manual
            """)
            conf.add_md([domain])
            conf.install()
            rv = env.apache_restart()
            if should_work:
                assert rv == 0, "Server did not accepted CAs '{}'".format(cas)
                md = env.get_md_status(domain)
                assert len(md['ca']['urls']) == len(cas)
            else:
                assert rv != 0, "Server should not have accepted CAs '{}'".format(cas)
    
        # messy ServerAliases, see #301
        def test_md_300_028(self, env):
            assert env.apache_stop() == 0
            conf = MDConf(env)
            domaina = f"t300-028a.{env.http_tld}"
            domainb = f"t300-028b.{env.http_tld}"
            dalias = f"t300-028alias.{env.http_tld}"
            conf.add_vhost(port=env.http_port, domains=[domaina, domainb, dalias], with_ssl=False)
            conf.add(f"""
                MDMembers manual
                MDomain {domaina} 
                MDomain {domainb} {dalias}
                """)
            conf.add(f"""
                <VirtualHost 10.0.0.1:{env.https_port}>
                  ServerName {domaina}
                  ServerAlias {dalias}
                  SSLEngine on
                </VirtualHost>
                <VirtualHost 10.0.0.1:{env.https_port}>
                  ServerName {domainb}
                  ServerAlias {dalias}
                  SSLEngine on
                </VirtualHost>
                """)
            conf.install()
            # This does not work as we have both MDs match domain's vhost
            assert env.apache_fail() == 0
            env.httpd_error_log.ignore_recent(
                lognos=[
                    "AH10238",   # 2 MDs match the same vhost
                ]
            )
            # It works, if we only match on ServerNames
            conf.add("MDMatchNames servernames")
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.httpd_error_log.ignore_recent(
                lognos=[
                    "AH10040",  # ServerAlias not covered
                ]
            )
    
        # wildcard and specfic MD overlaps
        def test_md_300_029(self, env):
            assert env.apache_stop() == 0
            conf = MDConf(env)
            domain = f"t300-029.{env.http_tld}"
            subdomain = f"sub.{domain}"
            conf.add_vhost(port=env.http_port, domains=[domain, subdomain], with_ssl=False)
            conf.add(f"""
                MDMembers manual
                MDomain {domain} *.{domain} 
                MDomain {subdomain}
                """)
            conf.add(f"""
                <VirtualHost 10.0.0.1:{env.https_port}>
                  ServerName {domain}
                  SSLEngine on
                </VirtualHost>
                <VirtualHost 10.0.0.1:{env.https_port}>
                  ServerName another.{domain}
                  SSLEngine on
                </VirtualHost>
                <VirtualHost 10.0.0.1:{env.https_port}>
                  ServerName {subdomain}
                  SSLEngine on
                </VirtualHost>
                """)
            conf.install()
            # This does not work as we have overlapping names in MDs
            assert env.apache_fail() == 0
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10038"   # 2 MDs overlap
                ]
            )
            # It works, if we only match on ServerNames
            conf.add("MDMatchNames servernames")
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            time.sleep(2)
            assert env.apache_stop() == 0
            # we need dns-01 challenge for the wildcard, which is not configured
            env.httpd_error_log.ignore_recent(matches=[
                r'.*None of offered challenge types.*are supported.*'
            ])
    
        # test case: corrupted md/httpd.json, see #369
        def test_md_300_030(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md(domains)
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            with open(os.path.join(env.store_dir, 'httpd.json'), 'w') as fd:
                fd.write('garbage\n')
            # self-repairing now
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.httpd_error_log.ignore_recent(matches=[
                r'.*failed to load JSON file.*'
            ])
    
        # test case: corrupted md/md_store.json, related to #369
        def test_md_300_031(self, env):
            env.purge_store()
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md(domains)
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            with open(os.path.join(env.store_dir, 'md_store.json'), 'w') as fd:
                fd.write('garbage\n')
            # not self-repairing, failing to start
            r = env.apache_restart()
            env.purge_store()
            assert r != 0, f'{env.apachectl_stderr}'
            env.httpd_error_log.ignore_recent(matches=[
                r'.*failed to load JSON file.*',
                r'.*init fs store at .*',
                f'.* The central store file .* seems to exist, but its content are not readable.*',
            ], lognos=[
                "AH10046" # setup store
            ])���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_202_acmev2_regs.py������������������������������������������������0000664�0001751�0001751�00000012666�14750656217�022072� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md ACMEv2 registrations
    
    import re
    import json
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestAcmeAcc:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
            env.APACHE_CONF_SRC = "data/test_drive"
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env):
            env.check_acme()
            env.clear_store()
    
        # test case: register a new account, vary length to check base64 encoding
        @pytest.mark.parametrize("contact", [
            "x@not-forbidden.org", "xx@not-forbidden.org", "xxx@not-forbidden.org"
        ])
        def test_md_202_000(self, env, contact):
            r = env.a2md(["-t", "accepted", "acme", "newreg", contact], raw=True)
            assert r.exit_code == 0, r
            m = re.match("registered: (.*)$", r.stdout)
            assert m, "did not match: {0}".format(r.stdout)
            acct = m.group(1)
            print("newreg: %s" % m.group(1))
            self._check_account(env, acct, ["mailto:" + contact])
    
        # test case: register a new account without accepting ToS, must fail
        def test_md_202_000b(self, env):
            r = env.a2md(["acme", "newreg", "x@not-forbidden.org"], raw=True)
            assert r.exit_code == 1
            m = re.match(".*must agree to terms of service.*", r.stderr)
            if m is None:
                # the pebble variant
                m = re.match(".*account did not agree to the terms of service.*", r.stderr)
            assert m, "did not match: {0}".format(r.stderr)
    
        # test case: respect 'mailto:' prefix in contact url
        def test_md_202_001(self, env):
            contact = "mailto:xx@not-forbidden.org"
            r = env.a2md(["-t", "accepted", "acme", "newreg", contact], raw=True)
            assert r.exit_code == 0
            m = re.match("registered: (.*)$", r.stdout)
            assert m
            acct = m.group(1)
            self._check_account(env, acct, [contact])
    
        # test case: fail on invalid contact url
        @pytest.mark.parametrize("invalid_contact", [
            "mehlto:xxx@not-forbidden.org", "no.at.char", "with blank@test.com",
            "missing.host@", "@missing.localpart.de",
            "double..dot@test.com", "double@at@test.com"
        ])
        def test_md_202_002(self, env, invalid_contact):
            assert env.a2md(["acme", "newreg", invalid_contact]).exit_code == 1
    
        # test case: use contact list
        def test_md_202_003(self, env):
            contact = ["xx@not-forbidden.org", "aa@not-forbidden.org"]
            r = env.a2md(["-t", "accepted", "acme", "newreg"] + contact, raw=True)
            assert r.exit_code == 0
            m = re.match("registered: (.*)$", r.stdout)
            assert m
            acct = m.group(1)
            self._check_account(env, acct, ["mailto:" + contact[0], "mailto:" + contact[1]])
    
        # test case: validate new account
        def test_md_202_100(self, env):
            acct = self._prepare_account(env, ["tmp@not-forbidden.org"])
            assert env.a2md(["acme", "validate", acct]).exit_code == 0
    
        # test case: fail on non-existing account
        def test_md_202_101(self, env):
            assert env.a2md(["acme", "validate", "ACME-localhost-1000"]).exit_code == 1
    
        # test case: report fail on request signing problem
        def test_md_202_102(self, env):
            acct = self._prepare_account(env, ["tmp@not-forbidden.org"])
            with open(env.path_account(acct)) as f:
                acctj = json.load(f)
            acctj['url'] = acctj['url'] + "0"
            open(env.path_account(acct), "w").write(json.dumps(acctj))
            assert env.a2md(["acme", "validate", acct]).exit_code == 1
    
        # test case: register and try delete an account, will fail without persistence
        def test_md_202_200(self, env):
            acct = self._prepare_account(env, ["tmp@not-forbidden.org"])
            assert env.a2md(["delreg", acct]).exit_code == 1
    
        # test case: register and try delete an account with persistence
        def test_md_202_201(self, env):
            acct = self._prepare_account(env, ["tmp@not-forbidden.org"])
            assert env.a2md(["acme", "delreg", acct]).exit_code == 0
            # check that store is clean
            r = env.run(["find", env.store_dir])
            assert re.match(env.store_dir, r.stdout)
    
        # test case: delete a persisted account without specifying url
        def test_md_202_202(self, env):
            acct = self._prepare_account(env, ["tmp@not-forbidden.org"])
            assert env.run([env.a2md_bin, "-d", env.store_dir, "acme", "delreg", acct]).exit_code == 0
    
        # test case: delete, then validate an account
        def test_md_202_203(self, env):
            acct = self._prepare_account(env, ["test014@not-forbidden.org"])
            assert env.a2md(["acme", "delreg", acct]).exit_code == 0
            # validate on deleted account fails
            assert env.a2md(["acme", "validate", acct]).exit_code == 1
    
        def _check_account(self, env, acct, contact):
            with open(env.path_account(acct)) as f:
                acctj = json.load(f)
            assert acctj['registration']['contact'] == contact
    
        def _prepare_account(self, env, contact):
            r = env.a2md(["-t", "accepted", "acme", "newreg"] + contact, raw=True)
            assert r.exit_code == 0
            return re.match("registered: (.*)$", r.stdout).group(1)
    ��������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_602_roundtrip.py��������������������������������������������������0000664�0001751�0001751�00000012001�14750656217�021706� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md basic configurations
    
    import os
    
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestRoundtripv2:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.APACHE_CONF_SRC = "data/test_roundtrip"
            env.clear_store()
            MDConf(env).install()
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.check_acme()
            self.test_domain = env.get_request_domain(request)
    
        # --------- add to store ---------
    
        def test_md_602_000(self, env):
            # test case: generate config with md -> restart -> drive -> generate config
            # with vhost and ssl -> restart -> check HTTPS access
            domain = self.test_domain
            domains = [domain, "www." + domain]
    
            # - generate config with one md
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md(domains)
            conf.install()
            # - restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # - drive
            assert env.a2md(["-v", "drive", domain]).exit_code == 0
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md_complete(domain)
            # - append vhost to config
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: SSL is running OK
            cert = env.get_cert(domain)
            assert domain in cert.get_san_list()
    
            # check file system permissions:
            env.check_file_permissions(domain)
    
        def test_md_602_001(self, env):
            # test case: same as test_600_000, but with two parallel managed domains
            domain_a = "a-" + self.test_domain
            domain_b = "b-" + self.test_domain
            # - generate config with one md
            domains_a = [domain_a, "www." + domain_a]
            domains_b = [domain_b, "www." + domain_b]
    
            conf = MDConf(env)
            conf.add_drive_mode("manual")
            conf.add_md(domains_a)
            conf.add_md(domains_b)
            conf.install()
    
            # - restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains_a)
            env.check_md(domains_b)
    
            # - drive
            assert env.a2md(["drive", domain_a]).exit_code == 0
            assert env.a2md(["drive", domain_b]).exit_code == 0
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md_complete(domain_a)
            env.check_md_complete(domain_b)
    
            # - append vhost to config
            conf.add_vhost(domains_a)
            conf.add_vhost(domains_b)
            conf.install()
    
            # check: SSL is running OK
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            cert_a = env.get_cert(domain_a)
            assert domains_a == cert_a.get_san_list()
            cert_b = env.get_cert(domain_b)
            assert domains_b == cert_b.get_san_list()
    
        def test_md_602_002(self, env):
            # test case: one md, that covers two vhosts
            domain = self.test_domain
            name_a = "a." + domain
            name_b = "b." + domain
            domains = [domain, name_a, name_b]
    
            # - generate config with one md
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md(domains)
            conf.install()
            
            # - restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
    
            # - drive
            assert env.a2md(["drive", domain]).exit_code == 0
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md_complete(domain)
    
            # - append vhost to config
            conf.add_vhost(name_a, doc_root="htdocs/a")
            conf.add_vhost(name_b, doc_root="htdocs/b")
            conf.install()
            
            # - create docRoot folder
            self._write_res_file(os.path.join(env.server_docs_dir, "a"), "name.txt", name_a)
            self._write_res_file(os.path.join(env.server_docs_dir, "b"), "name.txt", name_b)
    
            # check: SSL is running OK
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            cert_a = env.get_cert(name_a)
            assert name_a in cert_a.get_san_list()
            cert_b = env.get_cert(name_b)
            assert name_b in cert_b.get_san_list()
            assert cert_a.same_serial_as(cert_b)
            assert env.get_content(name_a, "/name.txt") == name_a
            assert env.get_content(name_b, "/name.txt") == name_b
    
        # --------- _utils_ ---------
    
        def _write_res_file(self, doc_root, name, content):
            if not os.path.exists(doc_root):
                os.makedirs(doc_root)
            open(os.path.join(doc_root, name), "w").write(content)
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_702_auto.py�������������������������������������������������������0000664�0001751�0001751�00000101677�14750656217�020653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import time
    from datetime import timedelta
    
    import pytest
    from pyhttpd.certs import CertificateSpec
    
    from pyhttpd.env import HttpdTestEnv
    from .md_cert_util import MDCertUtil
    from .md_env import MDTestEnv
    from .md_conf import MDConf
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestAutov2:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def _write_res_file(self, doc_root, name, content):
            if not os.path.exists(doc_root):
                os.makedirs(doc_root)
            open(os.path.join(doc_root, name), "w").write(content)
    
        # create a MD not used in any virtual host, auto drive should NOT pick it up
        def test_md_702_001(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.add_md(domains)
            conf.install()
            #
            # restart, check that MD is synched to store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            stat = env.get_md_status(domain)
            assert stat["watched"] == 0
            #
            # add vhost for MD, restart should drive it
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            stat = env.get_md_status(domain)
            assert stat["watched"] == 1
            cert = env.get_cert(domain)
            assert domain in cert.get_san_list()
            #
            # challenges should have been removed
            # file system needs to have correct permissions
            env.check_dir_empty(env.store_challenges())
            env.check_file_permissions(domain)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10045"   # No VirtualHost matches Managed Domain test-md-702-001-1688648129.org
                ]
            )
    
        # test case: same as test_702_001, but with two parallel managed domains
        def test_md_702_002(self, env):
            domain = self.test_domain
            domain_a = "a-" + domain
            domain_b = "b-" + domain
            #        
            # generate config with two MDs
            domains_a = [domain_a, "www." + domain_a]
            domains_b = [domain_b, "www." + domain_b]
            conf = MDConf(env)
            conf.add_drive_mode("auto")
            conf.add_md(domains_a)
            conf.add_md(domains_b)
            conf.add_vhost(domains_a)
            conf.add_vhost(domains_b)
            conf.install()
            #
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains_a)
            env.check_md(domains_b)
            #
            # await drive completion, do not restart
            assert env.await_completion([domain_a, domain_b], restart=False)
            # staged certificates are now visible on the status resources
            status = env.get_md_status(domain_a)
            assert 'renewal' in status
            assert 'cert' in status['renewal']
            assert 'rsa' in status['renewal']['cert']
            assert 'sha256-fingerprint' in status['renewal']['cert']['rsa']
            # check the non-staged status
            assert status['state'] == 1
            assert status['state-descr'] == "certificate(rsa) is missing"
    
            # restart and activate
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: SSL is running OK
            cert_a = env.get_cert(domain_a)
            assert domains_a == cert_a.get_san_list()
            cert_b = env.get_cert(domain_b)
            assert domains_b == cert_b.get_san_list()
            # check that we created only one account
            md_a = env.get_md_status(domain_a)
            md_b = env.get_md_status(domain_b)
            assert md_a['ca'] == md_b['ca']
    
        # test case: one MD, that covers two vhosts
        def test_md_702_003(self, env):
            domain = self.test_domain
            name_a = "test-a." + domain
            name_b = "test-b." + domain
            domains = [domain, name_a, name_b]
            #
            # generate 1 MD and 2 vhosts
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_md(domains)
            conf.add_vhost(name_a, doc_root="htdocs/a")
            conf.add_vhost(name_b, doc_root="htdocs/b")
            conf.install()
            #
            # create docRoot folder
            self._write_res_file(os.path.join(env.server_docs_dir, "a"), "name.txt", name_a)
            self._write_res_file(os.path.join(env.server_docs_dir, "b"), "name.txt", name_b)
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_completion([domain])
            md = env.check_md_complete(domain)
            assert md['ca']['url'], f"URL of CA used not set in md: {md}"
            #
            # check: SSL is running OK
            cert_a = env.get_cert(name_a)
            assert name_a in cert_a.get_san_list()
            cert_b = env.get_cert(name_b)
            assert name_b in cert_b.get_san_list()
            assert cert_a.same_serial_as(cert_b)
            #
            assert env.get_content(name_a, "/name.txt") == name_a
            assert env.get_content(name_b, "/name.txt") == name_b
    
        # test case: drive with using single challenge type explicitly
        @pytest.mark.parametrize("challenge_type", [
            "tls-alpn-01", "http-01",
        ])
        def test_md_702_004(self, env, challenge_type):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            #
            # generate 1 MD and 1 vhost
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("Protocols http/1.1 acme-tls/1")
            conf.add_drive_mode("auto")
            conf.add(f"MDCAChallenges {challenge_type}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            #        
            # check SSL running OK
            cert = env.get_cert(domain)
            assert domain in cert.get_san_list()
    
        # test case: drive_mode manual, check that server starts, but requests to domain are 503'd
        def test_md_702_005(self, env):
            domain = self.test_domain
            name_a = "test-a." + domain
            domains = [domain, name_a]
            #
            # generate 1 MD and 1 vhost
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md(domains)
            conf.add_vhost(name_a, doc_root="htdocs/a")
            conf.install()
            #
            # create docRoot folder
            self._write_res_file(os.path.join(env.server_docs_dir, "a"), "name.txt", name_a)
            #
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            #        
            # check: that request to domains give 503 Service Unavailable
            cert1 = env.get_cert(name_a)
            assert name_a in cert1.get_san_list()
            assert env.get_http_status(name_a, "/name.txt") == 503
            #
            # check temporary cert from server
            cert2 = MDCertUtil(env.path_fallback_cert(domain))
            assert cert1.same_serial_as(cert2), \
                "Unexpected temporary certificate on vhost %s. Expected cn: %s , "\
                "but found cn: %s" % (name_a, cert2.get_cn(), cert1.get_cn())
    
        # test case: drive MD with only invalid challenges, domains should stay 503'd
        def test_md_702_006(self, env):
            domain = self.test_domain
            name_a = "test-a." + domain
            domains = [domain, name_a]
            #
            # generate 1 MD, 1 vhost
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("MDCAChallenges invalid-01 invalid-02")
            conf.add_md(domains)
            conf.add_vhost(name_a, doc_root="htdocs/a")
            conf.install()
            #
            # create docRoot folder
            self._write_res_file(os.path.join(env.server_docs_dir, "a"), "name.txt", name_a)
            #
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'challenge-mismatch'
            assert 'account' not in md['ca']
            #
            # check: that request to domains give 503 Service Unavailable
            cert = env.get_cert(name_a)
            assert name_a in cert.get_san_list()
            assert env.get_http_status(name_a, "/name.txt") == 503
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # None of offered challenge types
                ],
                matches = [
                    r'.*problem\[challenge-mismatch\].*'
                ]
            )
    
        # Specify a non-working http proxy
        def test_md_702_008(self, env):
            domain = self.test_domain
            domains = [domain]
            #
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("always")
            conf.add("MDHttpProxy http://localhost:1")
            conf.add_md(domains)
            conf.install()
            #
            # - restart (-> drive)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # await drive completion
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['status-description'] == 'Connection refused'
            assert 'account' not in md['ca']
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # Unsuccessful in contacting ACME server
                ],
                matches = [
                    r'.*Unsuccessful in contacting ACME server at .*'
                ]
            )
    
        # Specify a valid http proxy
        def test_md_702_008a(self, env):
            domain = self.test_domain
            domains = [domain]
            #
            conf = MDConf(env, admin=f"admin@{domain}", proxy=True)
            conf.add_drive_mode("always")
            conf.add(f"MDHttpProxy http://localhost:{env.proxy_port}")
            conf.add_md(domains)
            conf.install()
            #
            # - restart (-> drive), check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md_complete(domain)
    
        # Force cert renewal due to critical remaining valid duration
        # Assert that new cert activation is delayed
        def test_md_702_009(self, env):
            domain = self.test_domain
            domains = [domain]
            #
            # prepare md
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.add_renew_window("10d")
            conf.add_md(domains)
            conf.add_vhost(domain)
            conf.install()
            #
            # restart (-> drive), check that md+cert is in store, TLS is up
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False)
            # Overwrite stages cert with one which has little remaining lifetime
            creds = env.create_self_signed_cert(CertificateSpec(domains=[domain]),
                                                valid_from=timedelta(days=-120),
                                                valid_to=timedelta(days=2),
                                                serial=7029)
            assert creds.certificate.serial_number == 7029
            creds.save_cert_pem(env.store_staged_file(domain, 'pubcert.pem'))
            creds.save_pkey_pem(env.store_staged_file(domain, 'privkey.pem'))
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_certificate_status(domain)
            assert creds.certificate.serial_number == int(stat['rsa']['serial'], 16)
            # cert should renew and be different afterwards
            assert env.await_completion([domain], must_renew=True)
            stat = env.get_certificate_status(domain)
            assert creds.certificate.serial_number != int(stat['rsa']['serial'], 16)
    
        # test case: drive with an unsupported challenge due to port availability 
        def test_md_702_010(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            #
            # generate 1 MD and 1 vhost, map port 80 to where the server does not listen
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.add("MDPortMap 80:99")        
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md["renewal"]["errors"] > 0
            #
            # now the same with a 80 mapped to a supported port 
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.add("MDCAChallenges http-01")
            conf.add("MDPortMap 80:%s" % env.http_port)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_completion([domain])
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10173",  # None of the ACME challenge methods configured for this domain are suitable
                    "AH10056"   # None of the ACME challenge methods configured for this domain are suitable
                ],
                matches = [
                    r'.*None of the ACME challenge methods configured for this domain are suitable.*'
                ]
            )
    
        def test_md_702_011(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            #
            # generate 1 MD and 1 vhost, map port 443 to where the server does not listen
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("Protocols http/1.1 acme-tls/1")
            conf.add_drive_mode("auto")
            conf.add("MDPortMap https:99 http:99")        
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md["renewal"]["errors"] > 0
            #
            # now the same with a 443 mapped to a supported port 
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("Protocols http/1.1 acme-tls/1")
            conf.add_drive_mode("auto")
            conf.add("MDCAChallenges tls-alpn-01")
            conf.add("MDPortMap https:%s" % env.https_port)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_completion([domain])
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10173",  # None of the ACME challenge methods configured for this domain are suitable
                    "AH10056"   # None of the ACME challenge methods configured for this domain are suitable
                ],
                matches = [
                    r'.*None of the ACME challenge methods configured for this domain are suitable.*'
                ]
            )
    
        # test case: one MD with several dns names. sign up. remove the *first* name
        # in the MD. restart. should find and keep the existing MD.
        # See: https://github.com/icing/mod_md/issues/68
        def test_md_702_030(self, env):
            domain = self.test_domain
            name_x = "test-x." + domain
            name_a = "test-a." + domain
            name_b = "test-b." + domain
            domains = [name_x, name_a, name_b]
            #
            # generate 1 MD and 2 vhosts
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_md(domains)
            conf.add_vhost(name_a)
            conf.add_vhost(name_b)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_completion([name_x])
            env.check_md_complete(name_x)
            #
            # check: SSL is running OK
            cert_a = env.get_cert(name_a)
            assert name_a in cert_a.get_san_list()
            cert_b = env.get_cert(name_b)
            assert name_b in cert_b.get_san_list()
            assert cert_a.same_serial_as(cert_b)
            #        
            # change MD by removing 1st name
            new_list = [name_a, name_b]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_md(new_list)
            conf.add_vhost(name_a)
            conf.add_vhost(name_b)
            conf.install()
            # restart, check that host still works and kept the cert
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(new_list)
            status = env.get_certificate_status(name_a)
            assert cert_a.same_serial_as(status['rsa']['serial'])
    
        # test case: Same as 7030, but remove *and* add another at the same time.
        # restart. should find and keep the existing MD and renew for additional name.
        # See: https://github.com/icing/mod_md/issues/68
        def test_md_702_031(self, env):
            domain = self.test_domain
            name_x = "test-x." + domain
            name_a = "test-a." + domain
            name_b = "test-b." + domain
            name_c = "test-c." + domain
            domains = [name_x, name_a, name_b]
            #
            # generate 1 MD and 2 vhosts
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_md(domains)
            conf.add_vhost(name_a)
            conf.add_vhost(name_b)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_completion([name_x])
            env.check_md_complete(name_x)
            #
            # check: SSL is running OK
            cert_a = env.get_cert(name_a)
            assert name_a in cert_a.get_san_list()
            cert_b = env.get_cert(name_b)
            assert name_b in cert_b.get_san_list()
            assert cert_a.same_serial_as(cert_b)
            #        
            # change MD by removing 1st name and adding another
            new_list = [name_a, name_b, name_c]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_md(new_list)
            conf.add_vhost(name_a)
            conf.add_vhost(name_b)
            conf.install()
            # restart, check that host still works and have new cert
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(new_list)
            assert env.await_completion([name_a])
            #
            cert_a2 = env.get_cert(name_a)
            assert name_a in cert_a2.get_san_list()
            assert not cert_a.same_serial_as(cert_a2)
    
        # test case: create two MDs, move them into one
        # see: <https://bz.apache.org/bugzilla/show_bug.cgi?id=62572>
        def test_md_702_032(self, env):
            domain = self.test_domain
            name1 = "server1." + domain
            name2 = "server2.b" + domain  # need a separate TLD to avoid rate limites
            #
            # generate 2 MDs and 2 vhosts
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("MDMembers auto")
            conf.add_md([name1])
            conf.add_md([name2])
            conf.add_vhost(name1)
            conf.add_vhost(name2)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md([name1])
            env.check_md([name2])
            assert env.await_completion([name1, name2])
            env.check_md_complete(name2)
            #
            # check: SSL is running OK
            cert1 = env.get_cert(name1)
            assert name1 in cert1.get_san_list()
            cert2 = env.get_cert(name2)
            assert name2 in cert2.get_san_list()
            #        
            # remove second md and vhost, add name2 to vhost1
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("MDMembers auto")
            conf.add_md([name1])
            conf.add_vhost([name1, name2])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md([name1, name2])
            assert env.await_completion([name1])
            #
            cert1b = env.get_cert(name1)
            assert name1 in cert1b.get_san_list()
            assert name2 in cert1b.get_san_list()
            assert not cert1.same_serial_as(cert1b)
    
        # test case: one MD on a vhost with ServerAlias. Renew.
        # Exchange ServerName and ServerAlias. Is the rename detected?
        # See: https://github.com/icing/mod_md/issues/338
        def test_md_702_033(self, env):
            domain = self.test_domain
            name_x = "test-x." + domain
            name_a = "test-a." + domain
            domains1 = [name_x, name_a]
            #
            # generate 1 MD and 2 vhosts
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_md(domains=[name_x])
            conf.add_vhost(domains=domains1)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains1)
            assert env.await_completion([name_x])
            env.check_md_complete(name_x)
            cert_x = env.get_cert(name_x)
            #
            # reverse ServerName and ServerAlias
            domains2 = [name_a, name_x]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_md(domains=[name_a])
            conf.add_vhost(domains=domains2)
            conf.install()
            # restart, check that host still works and kept the cert
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            status = env.get_certificate_status(name_a)
            assert cert_x.same_serial_as(status['rsa']['serial'])
    
    
        # test case: test "tls-alpn-01" challenge handling
        def test_md_702_040(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            #
            # generate 1 MD and 1 vhost
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("LogLevel core:debug")
            conf.add("Protocols http/1.1 acme-tls/1")
            conf.add_drive_mode("auto")
            conf.add("MDCAChallenges tls-alpn-01")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # check that acme-tls/1 is available for all domains
            stat = env.get_md_status(domain)
            assert stat["proto"]["acme-tls/1"] == domains
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            #        
            # check SSL running OK
            cert = env.get_cert(domain)
            assert domain in cert.get_san_list()
    
        # test case: test "tls-alpn-01" without enabling 'acme-tls/1' challenge protocol
        def test_md_702_041(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            #
            # generate 1 MD and 1 vhost
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("LogLevel core:debug")
            conf.add_drive_mode("auto")
            conf.add("MDCAChallenges tls-alpn-01")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            #
            # restart (-> drive), check that MD job shows errors 
            # and that missing proto is detected
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # check that acme-tls/1 is available for none of the domains
            stat = env.get_md_status(domain)
            assert stat["proto"]["acme-tls/1"] == []
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.httpd_error_log.ignore_recent(matches=[
                r'.*None of offered challenge types for domain.*',
            ], lognos=[
                "AH10056"  # challenges not available
            ])
    
        # test case: 2.4.40 mod_ssl stumbles over a SSLCertificateChainFile when installing
        # a fallback certificate
        @pytest.mark.skipif(HttpdTestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl")
        def test_md_702_042(self, env):
            domain = self.test_domain
            dns_list = [domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("LogLevel core:debug")
            cred = env.get_credentials_for_name(f"test1.{env.http_tld}")[0]
            conf.add(f"SSLCertificateChainFile {cred.cert_file}")
            conf.add_drive_mode("auto")
            conf.add_md(dns_list)
            conf.add_vhost(dns_list)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
    
        # test case: test "tls-alpn-01" without enabling 'acme-tls/1' challenge protocol
        # and fallback "http-01" configured, see https://github.com/icing/mod_md/issues/255
        def test_md_702_043(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            #
            # generate 1 MD and 1 vhost
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("LogLevel core:debug")
            conf.add_drive_mode("auto")
            conf.add("MDPortMap 80:%s" % env.http_port)
            conf.add("MDCAChallenges tls-alpn-01 http-01")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            #
            # restart (-> drive), check that MD job shows errors
            # and that missing proto is detected
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # check that acme-tls/1 is available for none of the domains
            stat = env.get_md_status(domain)
            assert stat["proto"]["acme-tls/1"] == []
            # but make sure it completes nevertheless
            assert env.await_completion([domain])
    
        # test case: drive with using single challenge type explicitly
        # and make sure that dns names not mapped to a VirtualHost also work
        @pytest.mark.parametrize("challenge_type", [
            "tls-alpn-01"  # , "http-01",
        ])
        def test_md_702_044(self, env, challenge_type):
            domain = self.test_domain
            md_domains = [domain, "mail." + domain]
            domains = [domain]
            #
            # generate 1 MD and 1 vhost
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("Protocols http/1.1 acme-tls/1")
            conf.add_drive_mode("auto")
            conf.add(f"MDCAChallenges {challenge_type}")
            conf.add_md(md_domains)
            conf.add_vhost(domains)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(md_domains)
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            #
            # check SSL running OK
            cert = env.get_cert(domain)
            assert md_domains[0] in cert.get_san_list()
            assert md_domains[1] in cert.get_san_list()
    
        # Make a setup using the base server. It will use http-01 challenge.
        def test_md_702_050(self, env):
            domain = self.test_domain
            conf = MDConf(env, admin=f"admin@{domain}")
            conf.add(f"""
                MDBaseServer on
                ServerName {domain}
                """)
            conf.add_md([domain])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
    
        # Make a setup using the base server without http:, will fail.
        def test_md_702_051(self, env):
            domain = self.test_domain
            conf = MDConf(env, admin=f"admin@{domain}")
            conf.add(f"""
                MDBaseServer on
                MDPortMap http:-
                ServerName {domain}
                """)
            conf.add_md([domain])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10173",  # None of the ACME challenge methods configured for this domain are suitable
                    "AH10056"   # None of the ACME challenge methods configured for this domain are suitable
                ],
                matches = [
                    r'.*None of the ACME challenge methods configured for this domain are suitable.*'
                ]
            )
    
        # Make a setup using the base server without http:, but with acme-tls/1, should work.
        def test_md_702_052(self, env):
            domain = self.test_domain
            conf = MDConf(env, std_vhosts=False, admin=f"admin@{domain}")
            conf.add([
                "MDBaseServer on",
                "MDPortMap http:-",
                "Protocols h2 http/1.1 acme-tls/1",
                f"ServerName {domain}",
                "<IfModule ssl_module>",
                "  SSLEngine on",
                "</IfModule>",
                "<IfModule tls_module>",
                f"  TLSEngine {env.https_port}",
                "</IfModule>",
            ])
            conf.add_md([domain])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_md_status(domain, via_domain=env.http_addr, use_https=False)
            assert stat["proto"]["acme-tls/1"] == [domain]
            assert env.await_completion([domain], via_domain=env.http_addr, use_https=False)
    
        # Test a domain name longer than 64 chars, but components < 64, see #227
        # Background: DNS has an official limit of 253 ASCII chars and components must be
        # of length [1, 63].
        # However the CN in a certificate is restricted too, see
        # <https://github.com/letsencrypt/boulder/issues/2093>.
        @pytest.mark.skipif(MDTestEnv.is_pebble(), reason="pebble differs here from boulder")
        @pytest.mark.parametrize("challenge_type", [
            "tls-alpn-01", "http-01"
        ])
        def test_md_702_060(self, env, challenge_type):
            domain = self.test_domain
            # use only too long names, this is expected to fail:
            # see <https://github.com/jetstack/cert-manager/issues/1462>
            long_domain = ("x" * (65 - len(domain))) + domain
            domains = [long_domain, "www." + long_domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("Protocols http/1.1 acme-tls/1")
            conf.add_drive_mode("auto")
            conf.add(f"MDCAChallenges {challenge_type}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_error(long_domain)
            # add a short domain to the SAN list, the CA should now use that one
            # and issue a cert.
            long_domain = ("y" * (65 - len(domain))) + domain
            domains = [long_domain, "www." + long_domain, "xxx." + domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("Protocols http/1.1 acme-tls/1")
            conf.add_drive_mode("auto")
            conf.add(f"MDCAChallenges {challenge_type}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([long_domain])
            env.check_md_complete(long_domain)
            #
            # check SSL running OK
            cert = env.get_cert(long_domain)
            assert long_domain in cert.get_san_list()
    
        # test case: fourth level domain
        def test_md_702_070(self, env):
            domain = self.test_domain
            name_a = "one.test." + domain
            name_b = "two.test." + domain
            domains = [name_a, name_b]
            #
            # generate 1 MD and 2 vhosts
            conf = MDConf(env)
            conf.add_admin("admin@" + domain)
            conf.add_md(domains)
            conf.add_vhost(name_a)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            env.check_md_complete(domains[0])
    
        # test case: fifth level domain
        def test_md_702_071(self, env):
            domain = self.test_domain
            name_a = "one.more.test." + domain
            name_b = "two.more.test." + domain
            domains = [name_a, name_b]
            #
            # generate 1 MD and 2 vhosts
            conf = MDConf(env)
            conf.add_admin("admin@" + domain)
            conf.add_md(domains)
            conf.add_vhost(name_a)
            conf.install()
            #
            # restart (-> drive), check that MD was synched and completes
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            env.check_md_complete(domains[0])
    
    �����������������������������������������������������������������httpd-2.4.64/test/modules/md/test_310_conf_store.py�������������������������������������������������0000664�0001751�0001751�00000114253�14750656217�022031� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md basic configurations
    import time
    
    import pytest
    import os
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    SEC_PER_DAY = 24 * 60 * 60
    MS_PER_DAY = SEC_PER_DAY * 1000
    NS_PER_DAY = MS_PER_DAY * 1000
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestConf:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        # test case: no md definitions in config
        def test_md_310_001(self, env):
            MDConf(env, text="").install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            r = env.a2md(["list"])
            assert 0 == len(r.json["output"])
    
        # test case: add md definitions on empty store
        @pytest.mark.parametrize("confline,dns_lists,md_count", [
            ("MDomain testdomain.org www.testdomain.org mail.testdomain.org", 
                [["testdomain.org", "www.testdomain.org", "mail.testdomain.org"]], 1),
            ("""MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDomain testdomain2.org www.testdomain2.org mail.testdomain2.org""", 
                [["testdomain.org", "www.testdomain.org", "mail.testdomain.org"],
                 ["testdomain2.org", "www.testdomain2.org", "mail.testdomain2.org"]], 2)
        ])
        def test_md_310_100(self, env, confline, dns_lists, md_count):
            MDConf(env, text=confline).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            for i in range(0, len(dns_lists)):
                env.check_md(dns_lists[i], state=1)
    
        # test case: add managed domains as separate steps
        def test_md_310_101(self, env):
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDomain testdomain2.org www.testdomain2.org mail.testdomain2.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
            env.check_md(["testdomain2.org", "www.testdomain2.org", "mail.testdomain2.org"], state=1)
    
        # test case: add dns to existing md
        def test_md_310_102(self, env):
            assert env.a2md(["add", "testdomain.org", "www.testdomain.org"]).exit_code == 0
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
    
        # test case: add new md definition with acme url, acme protocol, acme agreement
        def test_md_310_103(self, env):
            MDConf(env, text="""
                MDCertificateAuthority http://acme.test.org:4000/directory
                MDCertificateProtocol ACME
                MDCertificateAgreement http://acme.test.org:4000/terms/v1
    
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """, local_ca=False).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            name = "testdomain.org"
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         ca="http://acme.test.org:4000/directory", protocol="ACME",
                         agreement="http://acme.test.org:4000/terms/v1")
    
        # test case: add to existing md: acme url, acme protocol
        def test_md_310_104(self, env):
            name = "testdomain.org"
            MDConf(env, local_ca=False, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         ca="https://acme-v02.api.letsencrypt.org/directory", protocol="ACME")
            MDConf(env, local_ca=False, text="""
                MDCertificateAuthority http://acme.test.org:4000/directory
                MDCertificateProtocol ACME
                MDCertificateAgreement http://acme.test.org:4000/terms/v1
    
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         ca="http://acme.test.org:4000/directory", protocol="ACME",
                         agreement="http://acme.test.org:4000/terms/v1")
    
        # test case: add new md definition with server admin
        def test_md_310_105(self, env):
            MDConf(env, admin="admin@testdomain.org", text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            name = "testdomain.org"
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         contacts=["mailto:admin@testdomain.org"])
    
        # test case: add to existing md: server admin
        def test_md_310_106(self, env):
            name = "testdomain.org"
            assert env.a2md(["add", name, "www.testdomain.org", "mail.testdomain.org"]).exit_code == 0
            MDConf(env, admin="admin@testdomain.org", text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         contacts=["mailto:admin@testdomain.org"])
    
        # test case: assign separate contact info based on VirtualHost
        def test_md_310_107(self, env):
            MDConf(env, admin="", text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDomain testdomain2.org www.testdomain2.org mail.testdomain2.org
    
                <VirtualHost *:12346>
                    ServerName testdomain.org
                    ServerAlias www.testdomain.org
                    ServerAdmin mailto:admin@testdomain.org
                </VirtualHost>
    
                <VirtualHost *:12346>
                    ServerName testdomain2.org
                    ServerAlias www.testdomain2.org
                    ServerAdmin mailto:admin@testdomain2.org
                </VirtualHost>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            name1 = "testdomain.org"
            name2 = "testdomain2.org"
            env.check_md([name1, "www." + name1, "mail." + name1], state=1, contacts=["mailto:admin@" + name1])
            env.check_md([name2, "www." + name2, "mail." + name2], state=1, contacts=["mailto:admin@" + name2])
    
        # test case: normalize names - lowercase
        def test_md_310_108(self, env):
            MDConf(env, text="""
                MDomain testdomain.org WWW.testdomain.org MAIL.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
    
        # test case: default drive mode - auto
        def test_md_310_109(self, env):
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 1
    
        # test case: drive mode manual
        def test_md_310_110(self, env):
            MDConf(env, text="""
                MDRenewMode manual
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 0
    
        # test case: drive mode auto
        def test_md_310_111(self, env):
            MDConf(env, text="""
                MDRenewMode auto
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 1
    
        # test case: drive mode always
        def test_md_310_112(self, env):
            MDConf(env, text="""
                MDRenewMode always
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 2
    
        # test case: renew window - 14 days
        def test_md_310_113a(self, env):
            MDConf(env, text="""
                MDRenewWindow 14d
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-window'] == '14d'
    
        # test case: renew window - 10 percent
        def test_md_310_113b(self, env):
            MDConf(env, text="""
                MDRenewWindow 10%
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-window'] == '10%'
            
        # test case: ca challenge type - http-01
        def test_md_310_114(self, env):
            MDConf(env, text="""
                MDCAChallenges http-01
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['ca']['challenges'] == ['http-01']
    
        # test case: ca challenge type - http-01
        def test_md_310_115(self, env):
            MDConf(env, text="""
                MDCAChallenges tls-alpn-01
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['ca']['challenges'] == ['tls-alpn-01']
    
        # test case: ca challenge type - all
        def test_md_310_116(self, env):
            MDConf(env, text="""
                MDCAChallenges http-01 tls-alpn-01
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['ca']['challenges'] == ['http-01', 'tls-alpn-01']
    
        # test case: automatically collect md names from vhost config
        def test_md_310_117(self, env):
            conf = MDConf(env, text="""
                MDMember auto
                MDomain testdomain.org
                """)
            conf.add_vhost(port=12346, domains=[
                "testdomain.org", "test.testdomain.org", "mail.testdomain.org",
            ], with_ssl=True)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['domains'] == \
                   ['testdomain.org', 'test.testdomain.org', 'mail.testdomain.org']
    
        # add renew window to existing md
        def test_md_310_118(self, env):
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            MDConf(env, text="""
                MDRenewWindow 14d
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_md_status("testdomain.org")
            assert stat['renew-window'] == '14d'
    
        # test case: set RSA key length 2048
        def test_md_310_119(self, env):
            MDConf(env, text="""
                MDPrivateKeys RSA 2048
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['privkey'] == {
                "type": "RSA",
                "bits": 2048
            }
    
        # test case: set RSA key length 4096
        def test_md_310_120(self, env):
            MDConf(env, text="""
                MDPrivateKeys RSA 4096
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['privkey'] == {
                "type": "RSA",
                "bits": 4096
            }
    
        # test case: require HTTPS
        def test_md_310_121(self, env):
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDRequireHttps temporary
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['require-https'] == "temporary"
    
        # test case: require OCSP stapling
        def test_md_310_122(self, env):
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDMustStaple on
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['must-staple'] is True
    
        # test case: remove managed domain from config
        def test_md_310_200(self, env):
            dns_list = ["testdomain.org", "www.testdomain.org", "mail.testdomain.org"]
            env.a2md(["add"] + dns_list)
            env.check_md(dns_list, state=1)
            conf = MDConf(env,)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: md stays in store
            env.check_md(dns_list, state=1)
    
        # test case: remove alias DNS from managed domain
        def test_md_310_201(self, env):
            dns_list = ["testdomain.org", "test.testdomain.org", "www.testdomain.org", "mail.testdomain.org"]
            env.a2md(["add"] + dns_list)
            env.check_md(dns_list, state=1)
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: DNS has been removed from md in store
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
    
        # test case: remove primary name from managed domain
        def test_md_310_202(self, env):
            dns_list = ["name.testdomain.org", "testdomain.org", "www.testdomain.org", "mail.testdomain.org"]
            env.a2md(["add"] + dns_list)
            env.check_md(dns_list, state=1)
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: md overwrite previous name and changes name
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"],
                         md="testdomain.org", state=1)
    
        # test case: remove one md, keep another
        def test_md_310_203(self, env):
            dns_list1 = ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            dns_list2 = ["testdomain.org", "www.testdomain.org", "mail.testdomain.org"]
            env.a2md(["add"] + dns_list1)
            env.a2md(["add"] + dns_list2)
            env.check_md(dns_list1, state=1)
            env.check_md(dns_list2, state=1)
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # all mds stay in store
            env.check_md(dns_list1, state=1)
            env.check_md(dns_list2, state=1)
    
        # test case: remove ca info from md, should switch over to new defaults
        def test_md_310_204(self, env):
            name = "testdomain.org"
            MDConf(env, local_ca=False, text="""
                MDCertificateAuthority http://acme.test.org:4000/directory
                MDCertificateProtocol ACME
                MDCertificateAgreement http://acme.test.org:4000/terms/v1
    
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: sync with ca info removed
            MDConf(env, local_ca=False, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         ca="https://acme-v02.api.letsencrypt.org/directory", protocol="ACME")
    
        # test case: remove server admin from md
        def test_md_310_205(self, env):
            name = "testdomain.org"
            MDConf(env, admin="admin@testdomain.org", text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: sync with admin info removed
            MDConf(env, admin="", text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: md stays the same with previous admin info
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         contacts=["mailto:admin@testdomain.org"])
    
        # test case: remove renew window from conf -> fallback to default
        def test_md_310_206(self, env):
            MDConf(env, text="""
                MDRenewWindow 14d
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-window'] == '14d'
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: renew window not set
            assert env.a2md(["list"]).json['output'][0]['renew-window'] == '33%'
    
        # test case: remove drive mode from conf -> fallback to default (auto)
        @pytest.mark.parametrize("renew_mode,exp_code", [
            ("manual", 0), 
            ("auto", 1), 
            ("always", 2)
        ])
        def test_md_310_207(self, env, renew_mode, exp_code):
            MDConf(env, text="""
                MDRenewMode %s
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """ % renew_mode).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == exp_code
            #
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 1
    
        # test case: remove challenges from conf -> fallback to default (not set)
        def test_md_310_208(self, env):
            MDConf(env, text="""
                MDCAChallenges http-01
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['ca']['challenges'] == ['http-01']
            #
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert 'challenges' not in env.a2md(["list"]).json['output'][0]['ca']
    
        # test case: specify RSA key
        @pytest.mark.parametrize("key_size", ["2048", "4096"])
        def test_md_310_209(self, env, key_size):
            MDConf(env, text="""
                MDPrivateKeys RSA %s
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """ % key_size).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['privkey']['type'] == "RSA"
            #
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert "privkey" not in env.a2md(["list"]).json['output'][0]
    
        # test case: require HTTPS
        @pytest.mark.parametrize("mode", ["temporary", "permanent"])
        def test_md_310_210(self, env, mode):
            MDConf(env, text="""
                <MDomainSet testdomain.org>
                    MDMember www.testdomain.org mail.testdomain.org
                    MDRequireHttps %s
                </MDomainSet>
                """ % mode).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['require-https'] == mode, \
                "Unexpected HTTPS require mode in store. config: {}".format(mode)
            #
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert "require-https" not in env.a2md(["list"]).json['output'][0], \
                "HTTPS require still persisted in store. config: {}".format(mode)
    
        # test case: require OCSP stapling
        def test_md_310_211(self, env):
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDMustStaple on
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['must-staple'] is True
            #
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['must-staple'] is False
    
        # test case: reorder DNS names in md definition
        def test_md_310_300(self, env):
            dns_list = ["testdomain.org", "mail.testdomain.org", "www.testdomain.org"]
            env.a2md(["add"] + dns_list)
            env.check_md(dns_list, state=1)
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: dns list changes
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
    
        # test case: move DNS from one md to another
        def test_md_310_301(self, env):
            env.a2md(["add", "testdomain.org", "www.testdomain.org", "mail.testdomain.org", "mail.testdomain2.org"])
            env.a2md(["add", "testdomain2.org", "www.testdomain2.org"])
            env.check_md(["testdomain.org", "www.testdomain.org",
                          "mail.testdomain.org", "mail.testdomain2.org"], state=1)
            env.check_md(["testdomain2.org", "www.testdomain2.org"], state=1)        
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDomain testdomain2.org www.testdomain2.org mail.testdomain2.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
            env.check_md(["testdomain2.org", "www.testdomain2.org", "mail.testdomain2.org"], state=1)
    
        # test case: change ca info
        def test_md_310_302(self, env):
            name = "testdomain.org"
            MDConf(env, local_ca=False, text="""
                MDCertificateAuthority http://acme.test.org:4000/directory
                MDCertificateProtocol ACME
                MDCertificateAgreement http://acme.test.org:4000/terms/v1
    
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: sync with changed ca info
            MDConf(env, local_ca=False, admin="webmaster@testdomain.org",
                      text="""
                MDCertificateAuthority http://somewhere.com:6666/directory
                MDCertificateProtocol ACME
                MDCertificateAgreement http://somewhere.com:6666/terms/v1
    
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: md stays the same with previous ca info
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         ca="http://somewhere.com:6666/directory", protocol="ACME",
                         agreement="http://somewhere.com:6666/terms/v1")
    
        # test case: change server admin
        def test_md_310_303(self, env):
            name = "testdomain.org"
            MDConf(env, admin="admin@testdomain.org", text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: sync with changed admin info
            MDConf(env, local_ca=False, admin="webmaster@testdomain.org", text="""
                MDCertificateAuthority http://somewhere.com:6666/directory
                MDCertificateProtocol ACME
                MDCertificateAgreement http://somewhere.com:6666/terms/v1
    
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: md stays the same with previous admin info
            env.check_md([name, "www.testdomain.org", "mail.testdomain.org"], state=1,
                         contacts=["mailto:webmaster@testdomain.org"])
    
        # test case: change drive mode - manual -> auto -> always
        def test_md_310_304(self, env):
            MDConf(env, text="""
                MDRenewMode manual
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 0
            # test case: drive mode auto
            MDConf(env, text="""
                MDRenewMode auto
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 1
            # test case: drive mode always
            MDConf(env, text="""
                MDRenewMode always
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['renew-mode'] == 2
    
        # test case: change config value for renew window, use various syntax alternatives
        def test_md_310_305(self, env):
            MDConf(env, text="""
                MDRenewWindow 14d
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.a2md(["list"]).json['output'][0]
            assert md['renew-window'] == '14d'
            MDConf(env, text="""
                MDRenewWindow 10
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.a2md(["list"]).json['output'][0]
            assert md['renew-window'] == '10d'
            MDConf(env, text="""
                MDRenewWindow 10%
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.a2md(["list"]).json['output'][0]
            assert md['renew-window'] == '10%'
    
        # test case: change challenge types - http -> tls-sni -> all
        def test_md_310_306(self, env):
            MDConf(env, text="""
                MDCAChallenges http-01
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['ca']['challenges'] == ['http-01']
            # test case: drive mode auto
            MDConf(env, text="""
                MDCAChallenges tls-alpn-01
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['ca']['challenges'] == ['tls-alpn-01']
            # test case: drive mode always
            MDConf(env, text="""
                MDCAChallenges http-01 tls-alpn-01
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['ca']['challenges'] == ['http-01', 'tls-alpn-01']
    
        # test case:  RSA key length: 4096 -> 2048 -> 4096
        def test_md_310_307(self, env):
            MDConf(env, text="""
                MDPrivateKeys RSA 4096
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['privkey'] == {
                "type": "RSA",
                "bits": 4096
            }
            MDConf(env, text="""
                MDPrivateKeys RSA 2048
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['privkey'] == {
                "type": "RSA",
                "bits": 2048
            }
            MDConf(env, text="""
                MDPrivateKeys RSA 4096
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['privkey'] == {
                "type": "RSA",
                "bits": 4096
            }
    
        # test case: change HTTPS require settings on existing md
        def test_md_310_308(self, env):
            # setup: nothing set
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert "require-https" not in env.a2md(["list"]).json['output'][0]
            # test case: temporary redirect
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDRequireHttps temporary
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['require-https'] == "temporary"
            # test case: permanent redirect
            MDConf(env, text="""
                <MDomainSet testdomain.org>
                    MDMember www.testdomain.org mail.testdomain.org
                    MDRequireHttps permanent
                </MDomainSet>
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['require-https'] == "permanent"
    
        # test case: change OCSP stapling settings on existing md
        def test_md_310_309(self, env):
            # setup: nothing set
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['must-staple'] is False
            # test case: OCSP stapling on
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDMustStaple on
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['must-staple'] is True
            # test case: OCSP stapling off
            MDConf(env, text="""
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                MDMustStaple off
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'][0]['must-staple'] is False
    
        # test case: change renew window parameter
        @pytest.mark.parametrize("window", [
            "0%", "33d", "40%"
        ])
        def test_md_310_310(self, env, window):
            # non-default renewal setting
            domain = self.test_domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.start_md([domain])
            conf.add_drive_mode("manual")
            conf.add_renew_window(window)
            conf.end_md()
            conf.add_vhost(domains=domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_md_status(domain)
            assert stat["renew-window"] == window
    
        # test case: add dns name on existing valid md
        def test_md_310_400(self, env):
            # setup: create complete md in store
            domain = self.test_domain
            name = "www." + domain
            assert env.a2md(["add", name, "test1." + domain]).exit_code == 0
            assert env.a2md(["update", name, "contacts", "admin@" + name]).exit_code == 0
            assert env.a2md(["update", name, "agreement", env.acme_tos]).exit_code == 0
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
            # setup: drive it
            r = env.a2md(["-v", "drive", name])
            assert r.exit_code == 0, "drive not successful: {0}".format(r.stderr)
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_COMPLETE
    
            # remove one domain -> status stays COMPLETE
            assert env.a2md(["update", name, "domains", name]).exit_code == 0
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_COMPLETE
            
            # add other domain -> status INCOMPLETE
            assert env.a2md(["update", name, "domains", name, "test2." + domain]).exit_code == 0
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_INCOMPLETE
    
        # test case: change ca info
        def test_md_310_401(self, env):
            # setup: create complete md in store
            domain = self.test_domain
            name = "www." + domain
            assert env.a2md(["add", name]).exit_code == 0
            assert env.a2md(["update", name, "contacts", "admin@" + name]).exit_code == 0
            assert env.a2md(["update", name, "agreement", env.acme_tos]).exit_code == 0
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: drive it
            assert env.a2md(["drive", name]).exit_code == 0
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_COMPLETE
            # setup: change CA URL
            assert env.a2md(["update", name, "ca", env.acme_url]).exit_code == 0
            # check: state stays COMPLETE
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_COMPLETE
    
        # test case: change the store dir
        def test_md_310_500(self, env):
            MDConf(env, text="""
                MDStoreDir md-other
                MDomain testdomain.org www.testdomain.org mail.testdomain.org
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list"]).json['output'] == []
            env.set_store_dir("md-other")
            env.check_md(["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1)
            env.clear_store()
            env.set_store_dir_default()
    
        # test case: place an unexpected file into the store, check startup survival, see #218
        def test_md_310_501(self, env):
            # setup: create complete md in store
            domain = self.test_domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.start_md([domain])
            conf.end_md()
            conf.add_vhost(domains=[domain])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # add a file at top level
            assert env.await_completion([domain])
            fpath = os.path.join(env.store_domains(), "wrong.com")
            with open(fpath, 'w') as fd:
                fd.write("this does not belong here\n")
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # test case: add external account binding
        def test_md_310_601(self, env):
            domain = self.test_domain
            # directly set
            conf = MDConf(env, admin="admin@" + domain)
            conf.start_md([domain])
            conf.add_drive_mode("manual")
            conf.add("MDExternalAccountBinding k123 hash123")
            conf.end_md()
            conf.add_vhost(domains=domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_md_status(domain)
            assert stat["eab"] == {'kid': 'k123', 'hmac': '***'}
            # eab inherited
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("MDExternalAccountBinding k456 hash456")
            conf.start_md([domain])
            conf.add_drive_mode("manual")
            conf.end_md()
            conf.add_vhost(domains=domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_md_status(domain)
            assert stat["eab"] == {'kid': 'k456', 'hmac': '***'}
            # override eab inherited
            conf = MDConf(env, admin="admin@" + domain)
            conf.add("MDExternalAccountBinding k456 hash456")
            conf.start_md([domain])
            conf.add_drive_mode("manual")
            conf.add("MDExternalAccountBinding none")
            conf.end_md()
            conf.add_vhost(domains=domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_md_status(domain)
            assert "eab" not in stat
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_710_profiles.py���������������������������������������������������0000664�0001751�0001751�00000011541�14750656217�021513� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import datetime
    import email.utils
    import os
    from datetime import timedelta
    
    import pytest
    from pyhttpd.certs import CertificateSpec
    
    from pyhttpd.env import HttpdTestEnv
    from .md_cert_util import MDCertUtil
    from .md_env import MDTestEnv
    from .md_conf import MDConf
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestProfiles:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def _write_res_file(self, doc_root, name, content):
            if not os.path.exists(doc_root):
                os.makedirs(doc_root)
            open(os.path.join(doc_root, name), "w").write(content)
    
        # create a MD with 'default' profile, get cert
        def test_md_710_001(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.start_md(domains)
            conf.add(f'  MDProfile default')
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            #
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            stat = env.get_md_status(domain)
            assert stat["watched"] == 1
            assert stat["profile"] == "default", f'{stat}'
            assert stat['cert']['rsa']['valid']['until'], f'{stat}'
            ts = email.utils.parsedate_to_datetime(stat['cert']['rsa']['valid']['until'])
            valid = ts - datetime.datetime.now(datetime.UTC)
            assert valid.days in [89, 90]
    
        # create a MD with 'shortlived' profile, get cert
        def test_md_710_002(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.start_md(domains)
            conf.add(f'  MDProfile shortlived')
            conf.add(f'  MDProfileMandatory on')
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            #
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            stat = env.get_md_status(domain)
            assert stat["watched"] == 1
            assert stat["profile"] == "shortlived", f'{stat}'
            assert stat['cert']['rsa']['valid']['until'], f'{stat}'
            ts = email.utils.parsedate_to_datetime(stat['cert']['rsa']['valid']['until'])
            valid = ts - datetime.datetime.now(datetime.UTC)
            assert valid.days in [5, 6]
    
        # create a MD with unknown 'XXX' profile, get cert
        def test_md_710_003(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.start_md(domains)
            conf.add(f'  MDProfile XXX')
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            #
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            stat = env.get_md_status(domain)
            assert stat["watched"] == 1
            assert stat["profile"] == "XXX", f'{stat}'
    
        # create a MD with unknown 'XXX' profile, mandatory, fail
        def test_md_710_004(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("auto")
            conf.start_md(domains)
            conf.add(f'  MDProfile XXX')
            conf.add(f'  MDProfileMandatory on')
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            #
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            stat = env.get_md_status(domain)
            assert stat["watched"] == 1
            assert stat["profile"] == "XXX", f'{stat}'
            assert len(stat['cert']) == 0, f'{stat}'
            assert stat['renewal']['errors'] > 0, f'{stat}'
            assert stat['renewal']['last']['activity'] == 'Creating new order', f'{stat}'
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.httpd_error_log.ignore_recent(matches=[
                r'.*mandatory ACME profile \'XXX\' is not offered by CA.*',
            ], lognos=[
                "AH10056"  # processing failed
            ])
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_741_setup_errors.py�����������������������������������������������0000664�0001751�0001751�00000006127�14750656217�022434� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test ACME error responses and their processing
    import os
    
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestSetupErrors:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.mcmd = os.path.join(env.test_dir, "../modules/md/http_challenge_foobar.py")
            self.test_domain = env.get_request_domain(request)
    
        def test_md_741_001(self, env):
            # setup an MD with a MDMessageCmd that make the http-01 challenge file invalid
            # before the ACME server is asked to retrieve it. This will result in
            # an "invalid" domain authorization.
            # The certificate sign-up will be attempted again after 4 seconds and
            # of course fail again.
            # Verify that the error counter for the staging job increments, so
            # that our retry logic goes into proper delayed backoff.
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDCAChallenges http-01")
            conf.add(f"MDMessageCmd {self.mcmd} {env.store_dir}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain, errors=2, timeout=10)
            assert md
            assert md['renewal']['errors'] > 0
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # CA considers answer to challenge invalid
                ],
                matches = [
                    r'.*The key authorization file from the server did not match this challenge.*',
                    r'.*CA considers answer to challenge invalid.*'
                ]
            )
    
        # mess up the produced staging area before reload
        def test_md_741_002(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            assert env.await_completion([domain], restart=False)
            staged_md_path = env.store_staged_file(domain, 'md.json')
            with open(staged_md_path, 'w') as fd:
                fd.write('garbage\n')
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10069"   # failed to load JSON file
                ],
                matches = [
                    r'.*failed to load JSON file.*',
                ]
            )
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_740_acme_errors.py������������������������������������������������0000664�0001751�0001751�00000007136�14750656217�022201� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test ACME error responses and their processing
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestAcmeErrors:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        # -----------------------------------------------------------------------------------------------
        # test case: MD with 2 names, one invalid
        #
        def test_md_740_000(self, env):
            domain = self.test_domain
            domains = [domain, "invalid!." + domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            if env.acme_server == 'pebble':
                assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:malformed'
                assert md['renewal']['last']['detail'] == \
                       "Order included DNS identifier with a value containing an illegal character: '!'"
            else:
                assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:rejectedIdentifier'
                assert md['renewal']['last']['detail'] == (
                        "Error creating new order :: Cannot issue for "
                        "\"%s\": Domain name contains an invalid character" % domains[1])
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # Order included DNS identifier with a value containing an illegal character
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:malformed.*'
                ]
            )
    
        # test case: MD with 3 names, 2 invalid
        #
        def test_md_740_001(self, env):
            domain = self.test_domain
            domains = [domain, "invalid1!." + domain, "invalid2!." + domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            if env.acme_server == 'pebble':
                assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:malformed'
                assert md['renewal']['last']['detail'].startswith(
                    "Order included DNS identifier with a value containing an illegal character")
            else:
                assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:rejectedIdentifier'
                assert md['renewal']['last']['detail'].startswith(
                    "Error creating new order :: Cannot issue for")
                assert md['renewal']['last']['subproblems']
                assert len(md['renewal']['last']['subproblems']) == 2
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # Order included DNS identifier with a value containing an illegal character
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:malformed.*'
                ]
            )
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_780_tailscale.py��������������������������������������������������0000664�0001751�0001751�00000015502�14750656217�021641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import re
    import socket
    import sys
    from threading import Thread
    
    import pytest
    
    from .md_conf import MDConf
    
    
    class TailscaleFaker:
    
        def __init__(self, env, path):
            self.env = env
            self._uds_path = path
            self._done = False
    
        def start(self):
            def process(self):
                self._socket.listen(1)
                self._process()
    
            try:
                os.unlink(self._uds_path)
            except OSError:
                if os.path.exists(self._uds_path):
                    raise
            self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self._socket.bind(self._uds_path)
            self._thread = Thread(target=process, daemon=True, args=[self])
            self._thread.start()
    
        def stop(self):
            self._done = True
            self._socket.close()
    
        def send_error(self, c, status, reason):
            c.sendall(f"""HTTP/1.1 {status} {reason}\r
    Server: TailscaleFaker\r
    Content-Length: 0\r
    Connection: close\r
    \r
    """.encode())
    
        def send_data(self, c, ctype: str, data: bytes):
            c.sendall(f"""HTTP/1.1 200 OK\r
    Server: TailscaleFaker\r
    Content-Type: {ctype}\r
    Content-Length: {len(data)}\r
    Connection: close\r
    \r
    """.encode() + data)
    
        def _process(self):
            # a http server written on a sunny afternooon
            while self._done is False:
                try:
                    c, client_address = self._socket.accept()
                    try:
                        data = c.recv(1024)
                        lines = data.decode().splitlines()
                        m = re.match(r'^(?P<method>\w+)\s+(?P<uri>\S+)\s+HTTP/1.1', lines[0])
                        if m is None:
                            self.send_error(c, 400, "Bad Request")
                            continue
                        uri = m.group('uri')
                        m = re.match(r'/localapi/v0/cert/(?P<domain>\S+)\?type=(?P<type>\w+)', uri)
                        if m is None:
                            self.send_error(c, 404, "Not Found")
                            continue
                        domain = m.group('domain')
                        cred_type = m.group('type')
                        creds = self.env.get_credentials_for_name(domain)
                        sys.stderr.write(f"lookup domain={domain}, type={cred_type} -> {creds}\n")
                        if creds is None or len(creds) == 0:
                            self.send_error(c, 404, "Not Found")
                            continue
                        if cred_type == 'crt':
                            self.send_data(c, "text/plain", creds[0].cert_pem)
                            pass
                        elif cred_type == 'key':
                            self.send_data(c, "text/plain", creds[0].pkey_pem)
                        else:
                            self.send_error(c, 404, "Not Found")
                            continue
                    finally:
                        c.close()
    
                except ConnectionAbortedError:
                    self._done = True
    
    
    class TestTailscale:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            UDS_PATH = f"{env.gen_dir}/tailscale.sock"
            TestTailscale.UDS_PATH = UDS_PATH
            faker = TailscaleFaker(env=env, path=UDS_PATH)
            faker.start()
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            yield
            faker.stop()
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def _write_res_file(self, doc_root, name, content):
            if not os.path.exists(doc_root):
                os.makedirs(doc_root)
            open(os.path.join(doc_root, name), "w").write(content)
    
        # create a MD using `tailscale` as protocol, wrong path
        def test_md_780_001(self, env):
            domain = env.tailscale_domain
            # generate config with one MD
            domains = [domain]
            socket_path = '/xxx'
            conf = MDConf(env, admin="admin@" + domain)
            conf.start_md(domains)
            conf.add([
                "MDCertificateProtocol tailscale",
                f"MDCertificateAuthority file://{socket_path}",
            ])
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            # restart and watch it fail due to wrong tailscale unix socket path
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['status-description'] == 'No such file or directory'
            assert md['renewal']['last']['detail'] == \
                   f"tailscale socket not available, may not be up: {socket_path}"
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # retrieving certificate from tailscale
                ]
            )
    
        # create a MD using `tailscale` as protocol, path to faker, should succeed
        def test_md_780_002(self, env):
            domain = env.tailscale_domain
            # generate config with one MD
            domains = [domain]
            socket_path = '/xxx'
            conf = MDConf(env, admin="admin@" + domain)
            conf.start_md(domains)
            conf.add([
                "MDCertificateProtocol tailscale",
                f"MDCertificateAuthority file://{self.UDS_PATH}",
            ])
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            # restart and watch it fail due to wrong tailscale unix socket path
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md_complete(domain)
    
        # create a MD using `tailscale` as protocol, but domain name not assigned by tailscale
        def test_md_780_003(self, env):
            domain = "test.not-correct.ts.net"
            # generate config with one MD
            domains = [domain]
            socket_path = '/xxx'
            conf = MDConf(env, admin="admin@" + domain)
            conf.start_md(domains)
            conf.add([
                "MDCertificateProtocol tailscale",
                f"MDCertificateAuthority file://{self.UDS_PATH}",
            ])
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            # restart and watch it fail due to wrong tailscale unix socket path
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['status-description'] == 'No such file or directory'
            assert md['renewal']['last']['detail'] == "retrieving certificate from tailscale"
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # retrieving certificate from tailscale
                ]
            )
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_752_zerossl.py����������������������������������������������������0000664�0001751�0001751�00000016243�14750656217�021403� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import time
    
    import pytest
    
    from .md_conf import MDConf
    
    # set the environment variables
    #   ZEROSSL_TLD="<your registered dns name>"
    # these tests to become active
    #
    
    DEMO_ACME = "https://acme.zerossl.com/v2/DV90"
    DEMO_EAB_URL = "http://api.zerossl.com/acme/eab-credentials-email"
    DEMO_TLD = None
    
    
    def missing_tld():
        global DEMO_TLD
        if 'ZEROSSL_TLD' in os.environ:
            DEMO_TLD = os.environ['ZEROSSL_TLD']
        return DEMO_TLD is None
    
    
    def get_new_eab(env):
        r = env.curl_raw(DEMO_EAB_URL, options=[
            "-d", f"email=admin@zerossl.{DEMO_TLD}"
        ], force_resolve=False)
        assert r.exit_code == 0
        assert r.json
        assert r.json['success'] is True
        assert r.json['eab_kid']
        assert r.json['eab_hmac_key']
        return {'kid': r.json['eab_kid'], 'hmac': r.json['eab_hmac_key']}
    
    
    @pytest.mark.skipif(condition=missing_tld(), reason="env var ZEROSSL_TLD not set")
    class TestZeroSSL:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='eab')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            self.test_domain = env.get_request_domain(request)
    
        def test_md_752_001(self, env):
            # valid config, expect cert with correct chain
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            eab = get_new_eab(env)
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"""
                MDCertificateAuthority {DEMO_ACME}
                MDCertificateAgreement accepted
                MDContactEmail admin@zerossl.{DEMO_TLD}
                MDCACertificateFile none
                MDExternalAccountBinding {eab['kid']} {eab['hmac']}
            """)
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
    
        def test_md_752_002(self, env):
            # without EAB set
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"""
                MDCertificateAuthority {DEMO_ACME}
                MDCertificateAgreement accepted
                MDContactEmail admin@zerossl.{DEMO_TLD}
                MDCACertificateFile none
            """)
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            md = env.get_md_status(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:externalAccountRequired'
    
        def test_md_752_003(self, env):
            # with wrong EAB set
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"""
                MDCertificateAuthority {DEMO_ACME}
                MDCertificateAgreement accepted
                MDContactEmail admin@zerossl.{DEMO_TLD}
                MDCACertificateFile none
            """)
            conf.add(f"MDExternalAccountBinding YmxhYmxhYmxhCg YmxhYmxhYmxhCg")
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            md = env.get_md_status(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:malformed'
    
        def test_md_752_004(self, env):
            # valid config, get cert, add dns name, renew cert
            domain = f"test1.{DEMO_TLD}"
            domain2 = f"test2.{DEMO_TLD}"
            domains = [domain]
            eab = get_new_eab(env)
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"""
                MDCertificateAuthority {DEMO_ACME}
                MDCertificateAgreement accepted
                MDContactEmail admin@zerossl.{DEMO_TLD}
                MDCACertificateFile none
                MDExternalAccountBinding {eab['kid']} {eab['hmac']}
            """)
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
            r = env.curl_get(f"https://{domain2}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.exit_code != 0
            md1 = env.get_md_status(domain)
            acct1 = md1['ca']['account']
            # add the domain2 to the dns names
            domains = [domain, domain2]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"""
                MDCertificateAuthority {DEMO_ACME}
                MDCertificateAgreement accepted
                MDContactEmail admin@zerossl.{DEMO_TLD}
                MDCACertificateFile none
                MDExternalAccountBinding {eab['kid']} {eab['hmac']}
            """)
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain2}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
            md2 = env.get_md_status(domain)
            acct2 = md2['ca']['account']
            assert acct2 == acct1, f"ACME account was not reused: {acct1} became {acct2}"
    
        def test_md_752_020(self, env):
            # valid config, get cert, check OCSP status
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            eab = get_new_eab(env)
            conf = MDConf(env)
            conf.add("MDStapling on")
            conf.start_md(domains)
            conf.add(f"""
                MDCertificateAuthority {DEMO_ACME}
                MDCertificateAgreement accepted
                MDContactEmail admin@zerossl.{DEMO_TLD}
                MDCACertificateFile none
                MDExternalAccountBinding {eab['kid']} {eab['hmac']}
            """)
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
            time.sleep(1)
            for domain in domains:
                stat = env.await_ocsp_status(domain,
                                             ca_file=f"{env.test_dir}/data/sectigo-demo-root.pem")
                assert stat['ocsp'] == "successful (0x0)"
                assert stat['verify'] == "0 (ok)"
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_730_static.py�����������������������������������������������������0000664�0001751�0001751�00000012446�14750656217�021166� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    from datetime import timedelta
    
    import pytest
    from pyhttpd.certs import CertificateSpec
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestStatic:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def test_md_730_001(self, env):
            # MD with static cert files, will not be driven
            domain = self.test_domain
            domains = [domain, 'www.%s' % domain]
            testpath = os.path.join(env.gen_dir, 'test_730_001')
            env.mkpath(testpath)
            # cert that is only 10 more days valid
            creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
                                                valid_from=timedelta(days=-80),
                                                valid_to=timedelta(days=10),
                                                serial=730001)
            cert_file = os.path.join(testpath, 'pubcert.pem')
            pkey_file = os.path.join(testpath, 'privkey.pem')
            creds.save_cert_pem(cert_file)
            creds.save_pkey_pem(pkey_file)
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateFile {cert_file}")
            conf.add(f"MDCertificateKeyFile {pkey_file}")
            conf.end_md()
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            
            # check if the domain uses it, it appears in our stats and renewal is off
            cert = env.get_cert(domain)
            assert cert.same_serial_as(730001)
            stat = env.get_md_status(domain)
            assert stat
            assert 'cert' in stat
            assert stat['renew'] is True
            assert 'renewal' not in stat
    
        def test_md_730_002(self, env):
            # MD with static cert files, force driving
            domain = self.test_domain
            domains = [domain, 'www.%s' % domain]
            testpath = os.path.join(env.gen_dir, 'test_730_002')
            env.mkpath(testpath)
            # cert that is only 10 more days valid
            creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
                                                valid_from=timedelta(days=-80),
                                                valid_to=timedelta(days=10),
                                                serial=730001)
            cert_file = os.path.join(testpath, 'pubcert.pem')
            pkey_file = os.path.join(testpath, 'privkey.pem')
            creds.save_cert_pem(cert_file)
            creds.save_pkey_pem(pkey_file)
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDPrivateKeys secp384r1 rsa3072")
            conf.add(f"MDCertificateFile {cert_file}")
            conf.add(f"MDCertificateKeyFile {pkey_file}")
            conf.add("MDRenewMode always")
            conf.end_md()
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # this should enforce a renewal
            stat = env.get_md_status(domain)
            assert stat['renew'] is True, stat
            assert env.await_completion(domains, restart=False)
            # and show the newly created certificates
            stat = env.get_md_status(domain)
            assert 'renewal' in stat
            assert 'cert' in stat['renewal']
            assert 'secp384r1' in stat['renewal']['cert']
            assert 'rsa' in stat['renewal']['cert']
    
        def test_md_730_003(self, env):
            # just configuring one file will not work
            domain = self.test_domain
            domains = [domain, 'www.%s' % domain]
            testpath = os.path.join(env.gen_dir, 'test_730_003')
            env.mkpath(testpath)
            # cert that is only 10 more days valid
            creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
                                                valid_from=timedelta(days=-80),
                                                valid_to=timedelta(days=10),
                                                serial=730001)
            cert_file = os.path.join(testpath, 'pubcert.pem')
            pkey_file = os.path.join(testpath, 'privkey.pem')
            creds.save_cert_pem(cert_file)
            creds.save_pkey_pem(pkey_file)
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateFile {cert_file}")
            conf.end_md()
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_fail() == 0
            
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateKeyFile {pkey_file}")
            conf.end_md()
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_fail() == 0
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10170",  # Managed Domain needs one MDCertificateKeyFile for each MDCertificateFile
                    "AH10171"   # Managed Domain has MDCertificateKeyFile(s) but no MDCertificateFile
                ]
            )
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_751_sectigo.py����������������������������������������������������0000664�0001751�0001751�00000015055�14750656217�021336� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import re
    import time
    
    import pytest
    
    from .md_conf import MDConf
    
    # set the environment variables
    #   SECTIGO_EAB="$kid $hmac" for
    #   SECTIGO_TLD="<your registered dns name>"
    # these tests to become active
    #
    
    DEMO_ACME = "https://acme.demo.sectigo.com/"
    DEMO_TLD = None
    
    EABS = [
        {'kid': '0123', 'hmac': 'abcdef'},
    ]
    
    
    def missing_eab():
        global EABS
        if len(EABS) == 1 and 'SECTIGO_EAB' in os.environ:
            m = re.match(r'^\s*(\S+)\s+(\S+)\s*$', os.environ['SECTIGO_EAB'])
            if m:
                EABS.append({'kid': m.group(1), 'hmac': m.group(2)})
        return len(EABS) == 1
    
    
    def missing_tld():
        global DEMO_TLD
        if 'SECTIGO_TLD' in os.environ:
            DEMO_TLD = os.environ['SECTIGO_TLD']
        return DEMO_TLD is None
    
    
    @pytest.mark.skipif(condition=missing_tld(), reason="env var SECTIGO_TLD not set")
    @pytest.mark.skipif(condition=missing_eab(), reason="env var SECTIGO_EAB not set")
    class TestSectigo:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='eab')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def test_md_751_001(self, env):
            # valid config, expect cert with correct chain
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateAuthority {DEMO_ACME}")
            conf.add("MDCACertificateFile none")
            conf.add(f"MDExternalAccountBinding {EABS[1]['kid']} {EABS[1]['hmac']}")
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
    
        def test_md_751_002(self, env):
            # without EAB set
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateAuthority {DEMO_ACME}")
            conf.add("MDCACertificateFile none")
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            md = env.get_md_status(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:externalAccountRequired'
    
        def test_md_751_003(self, env):
            # with wrong EAB set
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateAuthority {DEMO_ACME}")
            conf.add("MDCACertificateFile none")
            conf.add(f"MDExternalAccountBinding xxxxxx aaaaaaaaaaaaasdddddsdasdsadsadsadasdsadsa")
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            md = env.get_md_status(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:unauthorized'
    
        def test_md_751_004(self, env):
            # valid config, get cert, add dns name, renew cert
            domain = f"test1.{DEMO_TLD}"
            domain2 = f"test2.{DEMO_TLD}"
            domains = [domain]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateAuthority {DEMO_ACME}")
            conf.add("MDCACertificateFile none")
            conf.add(f"MDExternalAccountBinding {EABS[1]['kid']} {EABS[1]['hmac']}")
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
            r = env.curl_get(f"https://{domain2}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.exit_code != 0
            md1 = env.get_md_status(domain)
            acct1 = md1['ca']['account']
            # add the domain2 to the dns names
            domains = [domain, domain2]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add(f"MDCertificateAuthority {DEMO_ACME}")
            conf.add("MDCACertificateFile none")
            conf.add(f"MDExternalAccountBinding {EABS[1]['kid']} {EABS[1]['hmac']}")
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain2}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
            md2 = env.get_md_status(domain)
            acct2 = md2['ca']['account']
            assert acct2 == acct1, f"ACME account was not reused: {acct1} became {acct2}"
    
        def test_md_751_020(self, env):
            # valid config, get cert, check OCSP status
            domain = f"test1.{DEMO_TLD}"
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDStapling on")
            conf.start_md(domains)
            conf.add(f"""
                MDCertificateAuthority {DEMO_ACME}
                MDCACertificateFile none
                MDExternalAccountBinding {EABS[1]['kid']} {EABS[1]['hmac']}
                """)
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            r = env.curl_get(f"https://{domain}:{env.https_port}", options=[
                "--cacert", f"{env.test_dir}/data/sectigo-demo-root.pem"
            ])
            assert r.response['status'] == 200
            time.sleep(1)
            for domain in domains:
                stat = env.await_ocsp_status(domain,
                                             ca_file=f"{env.test_dir}/data/sectigo-demo-root.pem")
                assert stat['ocsp'] == "successful (0x0)"
                assert stat['verify'] == "0 (ok)"
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_810_ec.py���������������������������������������������������������0000664�0001751�0001751�00000013656�14750656217�020271� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# tests with elliptic curve keys and certificates
    import logging
    
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestAutov2:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def set_get_pkeys(self, env, domain, pkeys, conf=None):
            domains = [domain]
            if conf is None:
                conf = MDConf(env)
                conf.add("MDPrivateKeys {0}".format(" ".join([p['spec'] for p in pkeys])))
                conf.add_md(domains)
                conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
    
        def check_pkeys(self, env, domain, pkeys):
            # check that files for all types have been created
            for p in [p for p in pkeys if len(p['spec'])]:
                env.check_md_complete(domain, p['spec'])
            # check that openssl client sees the cert with given keylength for cipher
            env.verify_cert_key_lenghts(domain, pkeys)
        
        def set_get_check_pkeys(self, env, domain, pkeys, conf=None):
            self.set_get_pkeys(env, domain, pkeys, conf=conf)
            self.check_pkeys(env, domain, pkeys)
            
        # one EC key, no RSA
        def test_md_810_001(self, env):
            domain = self.test_domain
            self.set_get_check_pkeys(env, domain, [
                {'spec': "secp256r1", 'ciphers': "ECDSA", 'keylen': 256},
                {'spec': "", 'ciphers': "RSA", 'keylen': 0},
            ])
    
        # set EC key type override on MD and get certificate
        def test_md_810_002(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDPrivateKeys secp256r1")
            conf.start_md(domains)
            conf.add("    MDPrivateKeys secp384r1")
            conf.end_md()
            conf.add_vhost(domains)
            self.set_get_check_pkeys(env, domain, [
                {'spec': "secp384r1", 'ciphers': "ECDSA", 'keylen': 384},
                {'spec': "", 'ciphers': "RSA", 'keylen': 0},
            ])
    
        # set two key spec, ec before rsa
        def test_md_810_003a(self, env):
            domain = self.test_domain
            self.set_get_check_pkeys(env, domain, [
                {'spec': "P-256", 'ciphers': "ECDSA", 'keylen': 256},
                {'spec': "RSA 3072", 'ciphers': "ECDHE-RSA-CHACHA20-POLY1305", 'keylen': 3072},
            ])
    
        # set two key spec, rsa before ec
        def test_md_810_003b(self, env):
            domain = self.test_domain
            self.set_get_check_pkeys(env, domain, [
                {'spec': "RSA 3072", 'ciphers': "ECDHE-RSA-CHACHA20-POLY1305", 'keylen': 3072},
                {'spec': "secp384r1", 'ciphers': "ECDSA", 'keylen': 384},
            ])
    
        # use a curve unsupported by LE
        # only works with mod_ssl as rustls refuses to load such a weak key
        @pytest.mark.skipif(MDTestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl")
        @pytest.mark.skipif(MDTestEnv.get_acme_server() != 'boulder', reason="only boulder rejects this")
        def test_md_810_004(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDPrivateKeys secp192r1")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:malformed'
    
        # set three key specs
        def test_md_810_005(self, env):
            domain = self.test_domain
            # behaviour differences, mod_ssl selects the strongest suitable,
            # mod_tls selects the first suitable
            ec_key_len = 384 if env.ssl_module == "mod_ssl" else 256
            self.set_get_check_pkeys(env, domain, [
                {'spec': "secp256r1", 'ciphers': "ECDSA", 'keylen': ec_key_len},
                {'spec': "RSA 4096", 'ciphers': "ECDHE-RSA-CHACHA20-POLY1305", 'keylen': 4096},
                {'spec': "P-384", 'ciphers': "ECDSA", 'keylen': ec_key_len},
            ])
    
        # set three key specs
        def test_md_810_006(self, env):
            domain = self.test_domain
            self.set_get_check_pkeys(env, domain, [
                {'spec': "rsa2048", 'ciphers': "ECDHE-RSA-CHACHA20-POLY1305", 'keylen': 2048},
                {'spec': "secp256r1", 'ciphers': "ECDSA", 'keylen': 256},
            ])
    
        # start with one pkey and add another one
        def test_md_810_007(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDPrivateKeys rsa3072")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            conf = MDConf(env)
            conf.add("MDPrivateKeys rsa3072 secp384r1")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            mds = env.get_md_status(domain, via_domain=domain, use_https=True)
            assert 'renew' in mds and mds['renew'] is True, f"{mds}"
            assert env.await_completion(domains)
            self.check_pkeys(env, domain, [
                {'spec': "rsa3072", 'ciphers': "ECDHE-RSA-CHACHA20-POLY1305", 'keylen': 3072},
                {'spec': "secp384r1", 'ciphers': "ECDSA", 'keylen': 384},
            ])
    
    ����������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_800_must_staple.py������������������������������������������������0000664�0001751�0001751�00000006745�14750656217�022242� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md must-staple support
    import pytest
    
    from .md_conf import MDConf
    from .md_cert_util import MDCertUtil
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestMustStaple:
        domain = None
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            self.domain = env.get_class_domain(self.__class__)
    
        def configure_httpd(self, env, domain, add_lines=""):
            conf = MDConf(env, admin="admin@" + domain)
            conf.add(add_lines)
            conf.add_md([domain])
            conf.add_vhost(domain)
            conf.install()
    
        # MD with default, e.g. not staple
        def test_md_800_001(self, env):
            self.configure_httpd(env, self.domain)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([self.domain])
            env.check_md_complete(self.domain)
            cert1 = MDCertUtil(env.store_domain_file(self.domain, 'pubcert.pem'))
            assert not cert1.get_must_staple()
    
        # MD that should explicitly not staple
        def test_md_800_002(self, env):
            self.configure_httpd(env, self.domain, "MDMustStaple off")
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md_complete(self.domain)
            cert1 = MDCertUtil(env.store_domain_file(self.domain, 'pubcert.pem'))
            assert not cert1.get_must_staple()
            stat = env.get_ocsp_status(self.domain)
            assert 'ocsp' not in stat or stat['ocsp'] == "no response sent"
    
        # MD that must staple and toggle off again
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_800_003(self, env):
            self.configure_httpd(env, self.domain, "MDMustStaple on")
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([self.domain])
            env.check_md_complete(self.domain)
            cert1 = MDCertUtil(env.store_domain_file(self.domain, 'pubcert.pem'))
            assert cert1.get_must_staple()
            self.configure_httpd(env, self.domain, "MDMustStaple off")
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([self.domain])
            env.check_md_complete(self.domain)
            cert1 = MDCertUtil(env.store_domain_file(self.domain, 'pubcert.pem'))
            assert not cert1.get_must_staple()
    
        # MD that must staple
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        @pytest.mark.skipif(MDTestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl")
        def test_md_800_004(self, env):
            # mod_ssl stapling is off, expect no stapling
            stat = env.get_ocsp_status(self.domain)
            assert stat['ocsp'] == "no response sent" 
            # turn mod_ssl stapling on, expect an answer
            self.configure_httpd(env, self.domain, """
                LogLevel ssl:trace2
                SSLUseStapling On
                SSLStaplingCache shmcb:stapling_cache(128000)
                """)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_ocsp_status(self.domain)
            assert stat['ocsp'] == "successful (0x0)" 
            assert stat['verify'] == "0 (ok)"
    ���������������������������httpd-2.4.64/test/modules/md/test_801_stapling.py���������������������������������������������������0000664�0001751�0001751�00000042510�14750656217�021512� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md stapling support
    
    import os
    import time
    from datetime import timedelta
    import pytest
    from pyhttpd.certs import CertificateSpec
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestStapling:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            domain = env.get_class_domain(self.__class__)
            mdA = "a-" + domain
            mdB = "b-" + domain
            self.configure_httpd(env, [mdA, mdB]).install()
            env.apache_stop()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([mdA, mdB])
            env.check_md_complete(mdA)
            env.check_md_complete(mdB)
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            self.domain = env.get_class_domain(self.__class__)
            self.mdA = "a-" + self.domain
            self.mdB = "b-" + self.domain
            yield
            env.apache_stop()
    
        def configure_httpd(self, env, domains=None, add_lines="", ssl_stapling=False):
            if not isinstance(domains, list):
                domains = [domains] if domains else []
            conf = MDConf(env)
            conf.add("""
            <IfModule tls_module>
                LogLevel tls:trace4
            </IfModule>
            <IfModule ssl_module>
                LogLevel ssl:trace4
            </IfModule>
                """)
            if ssl_stapling:
                conf.add("""
                <IfModule ssl_module>
                    SSLUseStapling On
                    SSLStaplingCache shmcb:stapling_cache(128000)
                </IfModule>
                    """)
            conf.add(add_lines)
            for domain in domains:
                conf.add_md([domain])
                conf.add_vhost(domain)
            return conf
    
        # MD with stapling on/off and mod_ssl stapling off
        # expect to only see stapling response when MD stapling is on
        def test_md_801_001(self, env):
            md = self.mdA
            self.configure_httpd(env, md).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_ocsp_status(md)
            if MDTestEnv.lacks_ocsp():
                assert 'ocsp' not in stat or stat['ocsp'] == "no response sent", f'{stat}'
            else:
                assert stat['ocsp'] == "no response sent"
            stat = env.get_md_status(md)
            assert not stat["stapling"]
            #
            # turn stapling on, wait for it to appear in connections
            self.configure_httpd(env, md, """
                MDStapling on
                LogLevel md:trace5
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            if MDTestEnv.lacks_ocsp():
                stat = env.get_md_status(md)
                assert 'ocsp' not in stat or stat['ocsp'] == "no response sent", f'{stat}'
            else:
                stat = env.await_ocsp_status(md)
                assert stat['ocsp'] == "successful (0x0)"
                assert stat['verify'] == "0 (ok)"
            stat = env.get_md_status(md)
            if MDTestEnv.lacks_ocsp():
                assert stat["stapling"]
                pkey = 'rsa'
                assert 'ocsp' not in stat["cert"][pkey], f'{stat}'
            else:
                assert stat["stapling"]
                pkey = 'rsa'
                assert stat["cert"][pkey]["ocsp"]["status"] == "good"
                assert stat["cert"][pkey]["ocsp"]["valid"]
            #
            # turn stapling off (explicitly) again, should disappear
            self.configure_httpd(env, md, "MDStapling off").install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_ocsp_status(md)
            if MDTestEnv.lacks_ocsp():
                assert 'ocsp' not in stat or stat['ocsp'] == "no response sent", f'{stat}'
            else:
                assert stat['ocsp'] == "no response sent"
            stat = env.get_md_status(md)
            assert not stat["stapling"]
            
        # MD with stapling on/off and mod_ssl stapling on
        # expect to see stapling response in all cases
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_002(self, env):
            md = self.mdA
            self.configure_httpd(env, md, ssl_stapling=True).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" if \
                env.ssl_module == "mod_ssl" else "no response sent"
            stat = env.get_md_status(md)
            assert not stat["stapling"]
            #
            # turn stapling on, wait for it to appear in connections
            self.configure_httpd(env, md, "MDStapling on", ssl_stapling=True).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" 
            assert stat['verify'] == "0 (ok)"
            stat = env.get_md_status(md)
            assert stat["stapling"]
            pkey = 'rsa'
            assert stat["cert"][pkey]["ocsp"]["status"] == "good"
            assert stat["cert"][pkey]["ocsp"]["valid"]
            #
            # turn stapling off (explicitly) again, should disappear
            self.configure_httpd(env, md, "MDStapling off", ssl_stapling=True).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" if \
                env.ssl_module == "mod_ssl" else "no response sent"
            stat = env.get_md_status(md)
            assert not stat["stapling"]
            
        # 2 MDs, one with md stapling on, one with default (off)
        def test_md_801_003(self, env):
            md_a = self.mdA
            md_b = self.mdB
            conf = self.configure_httpd(env)
            conf.add("""
                <MDomain %s>
                    MDStapling on
                </MDomain>
                <MDomain %s>
                </MDomain>
                """ % (md_a, md_b))
            conf.add_vhost(md_a)
            conf.add_vhost(md_b)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # mdA has stapling
            if MDTestEnv.lacks_ocsp():
                stat = env.get_ocsp_status(md_a)
                assert 'ocsp' not in stat or stat['ocsp'] == "no response sent", f'{stat}'
            else:
                stat = env.await_ocsp_status(md_a)
                assert stat['ocsp'] == "successful (0x0)"
            assert stat['verify'] == "0 (ok)"
            stat = env.get_md_status(md_a)
            assert stat["stapling"]
            if not MDTestEnv.lacks_ocsp():
                pkey = 'rsa'
                assert stat["cert"][pkey]["ocsp"]["status"] == "good"
                assert stat["cert"][pkey]["ocsp"]["valid"]
            # mdB has no stapling
            if not MDTestEnv.lacks_ocsp():
                stat = env.get_ocsp_status(md_b)
                assert stat['ocsp'] == "no response sent"
            stat = env.get_md_status(md_b)
            assert not stat["stapling"]
    
        # 2 MDs, md stapling on+off, ssl stapling on
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_004(self, env):
            md_a = self.mdA
            md_b = self.mdB
            conf = self.configure_httpd(env, ssl_stapling=True)
            conf.add("""
                <MDomain %s>
                    MDStapling on
                </MDomain>
                <MDomain %s>
                </MDomain>
                """ % (md_a, md_b))
            conf.add_vhost(md_a)
            conf.add_vhost(md_b)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # mdA has stapling
            stat = env.await_ocsp_status(md_a)
            assert stat['ocsp'] == "successful (0x0)"
            assert stat['verify'] == "0 (ok)"
            stat = env.get_md_status(md_a)
            assert stat["stapling"]
            pkey = 'rsa'
            assert stat["cert"][pkey]["ocsp"]["status"] == "good"
            assert stat["cert"][pkey]["ocsp"]["valid"]
            # mdB has no md stapling, but mod_ssl kicks in
            stat = env.get_ocsp_status(md_b)
            assert stat['ocsp'] == "successful (0x0)" if \
                env.ssl_module == "mod_ssl" else "no response sent"
            stat = env.get_md_status(md_b)
            assert not stat["stapling"]
    
        # MD, check that restart leaves response unchanged, reconfigure keep interval, 
        # should remove the file on restart and get a new one
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_005(self, env):
            # TODO: mod_watchdog seems to have problems sometimes with fast restarts
            # turn stapling on, wait for it to appear in connections
            md = self.mdA
            self.configure_httpd(env, md, "MDStapling on").install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" 
            assert stat['verify'] == "0 (ok)"
            # fine the file where the ocsp response is stored
            dirpath = os.path.join(env.store_dir, 'ocsp', md)
            files = os.listdir(dirpath)
            ocsp_file = None
            for name in files:
                if name.startswith("ocsp-"):
                    ocsp_file = os.path.join(dirpath, name)
            assert ocsp_file
            mtime1 = os.path.getmtime(ocsp_file)
            # wait a sec, restart and check that file does not change
            time.sleep(1)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" 
            mtime2 = os.path.getmtime(ocsp_file)
            assert mtime1 == mtime2
            # configure a keep time of 1 second, restart, the file is gone
            # (which is a side effec that we load it before the cleanup removes it.
            #  since it was valid, no new one needed fetching
            self.configure_httpd(env, md, """
                MDStapling on
                MDStaplingKeepResponse 1s
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)"
            assert not os.path.exists(ocsp_file)
            # if we restart again, a new file needs to appear
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)"
            mtime3 = os.path.getmtime(ocsp_file)
            assert mtime1 != mtime3
    
        # MD, check that stapling renew window works. Set a large window
        # that causes response to be retrieved all the time.
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_006(self, env):
            # turn stapling on, wait for it to appear in connections
            md = self.mdA
            self.configure_httpd(env, md, "MDStapling on").install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" 
            assert stat['verify'] == "0 (ok)"
            # fine the file where the ocsp response is stored
            dirpath = os.path.join(env.store_dir, 'ocsp', md)
            files = os.listdir(dirpath)
            ocsp_file = None
            for name in files:
                if name.startswith("ocsp-"):
                    ocsp_file = os.path.join(dirpath, name)
            assert ocsp_file
            mtime1 = os.path.getmtime(ocsp_file)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" 
            # wait a sec, restart and check that file does not change
            time.sleep(1)
            mtime2 = os.path.getmtime(ocsp_file)
            assert mtime1 == mtime2
            # configure a renew window of 10 days, restart, larger than any life time.
            self.configure_httpd(env, md, """
                MDStapling on
                MDStaplingRenewWindow 10d
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)"
            # wait a sec, restart and check that file does change
            time.sleep(1)
            mtime3 = os.path.getmtime(ocsp_file)
            assert mtime1 != mtime3
    
        # MD, make a MDomain with static files, check that stapling works
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_007(self, env):
            # turn stapling on, wait for it to appear in connections
            md = self.mdA
            conf = self.configure_httpd(env)
            conf.add("""
                <MDomain %s>
                    MDCertificateKeyFile %s
                    MDCertificateFile %s
                    MDStapling on
                </MDomain>
                """ % (md, env.store_domain_file(md, 'privkey.pem'),
                       env.store_domain_file(md, 'pubcert.pem')))
            conf.add_vhost(md)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" 
            assert stat['verify'] == "0 (ok)"
            # fine the file where the ocsp response is stored
            dirpath = os.path.join(env.store_dir, 'ocsp', md)
            files = os.listdir(dirpath)
            ocsp_file = None
            for name in files:
                if name.startswith("ocsp-"):
                    ocsp_file = os.path.join(dirpath, name)
            assert ocsp_file
    
        # Use certificate files in direct config, check that stapling works
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_008(self, env):
            # turn stapling on, wait for it to appear in connections
            md = self.mdA
            conf = self.configure_httpd(env)
            conf.add("MDStapling on")
            conf.start_vhost(md)
            conf.add_certificate(env.store_domain_file(md, 'pubcert.pem'),
                                 env.store_domain_file(md, 'privkey.pem'))
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.await_ocsp_status(md)
            assert stat['ocsp'] == "successful (0x0)" 
            assert stat['verify'] == "0 (ok)"
            # fine the file where the ocsp response is stored
            dirpath = os.path.join(env.store_dir, 'ocsp', 'other')
            files = os.listdir(dirpath)
            ocsp_file = None
            for name in files:
                if name.startswith("ocsp-"):
                    ocsp_file = os.path.join(dirpath, name)
            assert ocsp_file
    
        # Turn on stapling for a certificate without OCSP responder and issuer
        # (certificates without issuer prevent mod_ssl asking around for stapling)
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_009(self, env):
            md = self.mdA
            domains = [md]
            testpath = os.path.join(env.gen_dir, 'test_801_009')
            env.mkpath(testpath)
            # cert that is 30 more days valid
            creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
                                                valid_from=timedelta(days=-60),
                                                valid_to=timedelta(days=30),
                                                serial=801009)
            cert_file = os.path.join(testpath, 'pubcert.pem')
            pkey_file = os.path.join(testpath, 'privkey.pem')
            creds.save_cert_pem(cert_file)
            creds.save_pkey_pem(pkey_file)
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add("MDCertificateFile %s" % cert_file)
            conf.add("MDCertificateKeyFile %s" % pkey_file)
            conf.add("MDStapling on")
            conf.end_md()
            conf.add_vhost(md)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            time.sleep(1)
            stat = env.get_ocsp_status(md)
            assert stat['ocsp'] == "no response sent" 
    
        # Turn on stapling for an MDomain not used in any virtualhost
        # There was a crash in server-status in this case
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_010(self, env):
            env.clear_ocsp_store()
            md = self.mdA
            domains = [md]
            conf = MDConf(env)
            conf.start_md(domains)
            conf.add("MDStapling on")
            conf.end_md()
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_server_status()
            assert stat
    
        # add 7 mdomains that need OCSP stapling, once activated
        # we use at max 6 connections against the same OCSP responder and
        # this triggers our use of curl_multi_perform with iterative
        # scheduling.
        # This checks the mistaken assert() reported in
        # <https://bz.apache.org/bugzilla/show_bug.cgi?id=65567>
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_801_011(self, env):
            domains = [ f'test-801-011-{i}-{env.DOMAIN_SUFFIX}' for i in range(7)]
            self.configure_httpd(env, domains, """
                MDStapling on
                LogLevel md:trace2 ssl:warn
                """).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains, restart=False, timeout=120)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # now the certs are installed and ocsp will be retrieved
            time.sleep(1)
            for domain in domains:
                stat = env.await_ocsp_status(domain)
                assert stat['ocsp'] == "successful (0x0)"
                assert stat['verify'] == "0 (ok)"
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_900_notify.py�����������������������������������������������������0000664�0001751�0001751�00000011637�14750656217�021207� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md notify support
    
    import os
    import time
    
    import pytest
    
    from .md_conf import MDConf, MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestNotify:
        notify_cmd = None
        notify_log = None
        domain = None
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            self.domain = env.get_request_domain(request)
            self.notify_cmd = os.path.join(env.test_dir, "../modules/md/notify.py")
            self.notify_log = os.path.join(env.gen_dir, "notify.log")
            if os.path.isfile(self.notify_log):
                os.remove(self.notify_log)
    
        def configure_httpd(self, env, domain, add_lines=""):
            conf = MDConf(env)
            conf.add(add_lines)
            conf.add_md([domain])
            conf.add_vhost(domain)
            conf.install()
            return domain
        
        # test: invalid notify cmd, check error
        def test_md_900_001(self, env):
            command = "blablabla"
            args = ""
            self.configure_httpd(env, self.domain, f"""
                MDNotifyCmd {command} {args}
                """)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(self.domain)
            stat = env.get_md_status(self.domain)
            assert stat["renewal"]["last"]["problem"] == "urn:org:apache:httpd:log:AH10108:"
            #
            env.httpd_error_log.ignore_recent(
                matches = [
                    r'.*urn:org:apache:httpd:log:AH10108:.*'
                ]
            )
    
        # test: valid notify cmd that fails, check error
        def test_md_900_002(self, env):
            command = "%s/notifail.py" % env.test_dir
            args = ""
            self.configure_httpd(env, self.domain, f"""
                MDNotifyCmd {command} {args}
                """)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(self.domain)
            stat = env.get_md_status(self.domain)
            assert stat["renewal"]["last"]["problem"] == "urn:org:apache:httpd:log:AH10108:"
            #
            env.httpd_error_log.ignore_recent(
                matches = [
                    r'.*urn:org:apache:httpd:log:AH10108:.*',
                    r'.*urn:org:apache:httpd:log:AH10109:.*'
                    r'.*problem\[challenge-setup-failure\].*',
                ]
            )
    
        # test: valid notify that logs to file
        def test_md_900_010(self, env):
            command = self.notify_cmd
            args = self.notify_log
            self.configure_httpd(env, self.domain, f"""
                MDNotifyCmd {command} {args}
                """)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([self.domain], restart=False)
            time.sleep(1)
            stat = env.get_md_status(self.domain)
            assert stat["renewal"]["last"]["status"] == 0
            time.sleep(1)
            nlines = open(self.notify_log).readlines()
            assert 1 == len(nlines)
            assert ("['%s', '%s', '%s']" % (command, args, self.domain)) == nlines[0].strip()
    
        # test: signup with working notify cmd and see that it is called with the 
        #       configured extra arguments
        def test_md_900_011(self, env):
            command = self.notify_cmd
            args = self.notify_log
            extra_arg = "test_900_011_extra"
            self.configure_httpd(env, self.domain, f"""
                MDNotifyCmd {command} {args} {extra_arg}
                """)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([self.domain], restart=False)
            time.sleep(1)
            stat = env.get_md_status(self.domain)
            assert stat["renewal"]["last"]["status"] == 0
            nlines = open(self.notify_log).readlines()
            assert ("['%s', '%s', '%s', '%s']" % (command, args, extra_arg, self.domain)) == nlines[0].strip()
    
        # test: signup with working notify cmd for 2 MD and expect it to be called twice
        def test_md_900_012(self, env):
            md1 = "a-" + self.domain
            domains1 = [md1, "www." + md1]
            md2 = "b-" + self.domain
            domains2 = [md2, "www." + md2]
            command = self.notify_cmd
            args = self.notify_log
            conf = MDConf(env)
            conf.add(f"MDNotifyCmd {command} {args}")
            conf.add_md(domains1)
            conf.add_md(domains2)
            conf.add_vhost(domains1)
            conf.add_vhost(domains2)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([md1, md2], restart=False)
            time.sleep(1)
            stat = env.get_md_status(md1)
            assert stat["renewal"]["last"]["status"] == 0
            stat = env.get_md_status(md2)
            assert stat["renewal"]["last"]["status"] == 0
            nlines = open(args).readlines()
            assert 2 == len(nlines)
    �������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_910_cleanups.py���������������������������������������������������0000664�0001751�0001751�00000003330�14750656217�021501� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md cleanups and sanitation
    
    import os
    
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestCleanups:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def teardown_method(self, method):
            print("teardown_method: %s" % method.__name__)
    
        def test_md_910_01(self, env):
            # generate a simple MD
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add_drive_mode("manual")
            conf.add_md(domains)
            conf.add_vhost(domain)
            conf.install()
    
            # create valid/invalid challenges subdirs
            challenges_dir = env.store_challenges()
            dirs_before = ["aaa", "bbb", domain, "zzz"]
            for name in dirs_before:
                os.makedirs(os.path.join(challenges_dir, name))
    
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # the one we use is still there
            assert os.path.isdir(os.path.join(challenges_dir, domain))
            # and the others are gone
            missing_after = ["aaa", "bbb", "zzz"]
            for name in missing_after:
                assert not os.path.exists(os.path.join(challenges_dir, name))
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/md_cert_util.py��������������������������������������������������������0000775�0001751�0001751�00000016616�14672270657�020732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import re
    import socket
    import OpenSSL
    import time
    import sys
    
    from datetime import datetime
    from datetime import tzinfo
    from datetime import timedelta
    from http.client import HTTPConnection
    from urllib.parse import urlparse
    
    from cryptography import x509
    
    SEC_PER_DAY = 24 * 60 * 60
    
    
    log = logging.getLogger(__name__)
    
    
    class MDCertUtil(object):
        # Utility class for inspecting certificates in test cases
        # Uses PyOpenSSL: https://pyopenssl.org/en/stable/index.html
    
        @classmethod
        def load_server_cert(cls, host_ip, host_port, host_name, tls=None, ciphers=None):
            ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
            if tls is not None and tls != 1.0:
                ctx.set_options(OpenSSL.SSL.OP_NO_TLSv1)
            if tls is not None and tls != 1.1:
                ctx.set_options(OpenSSL.SSL.OP_NO_TLSv1_1)
            if tls is not None and tls != 1.2:
                ctx.set_options(OpenSSL.SSL.OP_NO_TLSv1_2)
            if tls is not None and tls != 1.3 and hasattr(OpenSSL.SSL, "OP_NO_TLSv1_3"):
                ctx.set_options(OpenSSL.SSL.OP_NO_TLSv1_3)
            if ciphers is not None:
                ctx.set_cipher_list(ciphers)
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            connection = OpenSSL.SSL.Connection(ctx, s)
            connection.connect((host_ip, int(host_port)))
            connection.setblocking(1)
            connection.set_tlsext_host_name(host_name.encode('utf-8'))
            connection.do_handshake()
            peer_cert = connection.get_peer_certificate()
            return MDCertUtil(None, cert=peer_cert)
    
        @classmethod
        def parse_pem_cert(cls, text):
            cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, text.encode('utf-8'))
            return MDCertUtil(None, cert=cert)
    
        @classmethod
        def get_plain(cls, url, timeout):
            server = urlparse(url)
            try_until = time.time() + timeout
            while time.time() < try_until:
                # noinspection PyBroadException
                try:
                    c = HTTPConnection(server.hostname, server.port, timeout=timeout)
                    c.request('GET', server.path)
                    resp = c.getresponse()
                    data = resp.read()
                    c.close()
                    return data
                except IOError:
                    log.debug("connect error:", sys.exc_info()[0])
                    time.sleep(.1)
                except:
                    log.error("Unexpected error:", sys.exc_info()[0])
            log.error("Unable to contact server after %d sec" % timeout)
            return None
    
        def __init__(self, cert_path, cert=None):
            if cert_path is not None:
                self.cert_path = cert_path
                # load certificate and private key
                if cert_path.startswith("http"):
                    cert_data = self.get_plain(cert_path, 1)
                else:
                    cert_data = MDCertUtil._load_binary_file(cert_path)
    
                for file_type in (OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.FILETYPE_ASN1):
                    try:
                        self.cert = OpenSSL.crypto.load_certificate(file_type, cert_data)
                    except Exception as error:
                        self.error = error
            if cert is not None:
                self.cert = cert
    
            if self.cert is None:
                raise self.error
    
        def get_issuer(self):
            return self.cert.get_issuer()
    
        def get_serial(self):
            # the string representation of a serial number is not unique. Some
            # add leading 0s to align with word boundaries.
            return ("%lx" % (self.cert.get_serial_number())).upper()
    
        @staticmethod
        def _get_serial(cert) -> int:
            if isinstance(cert, x509.Certificate):
                return cert.serial_number
            if isinstance(cert, MDCertUtil):
                return cert.get_serial_number()
            elif isinstance(cert, OpenSSL.crypto.X509):
                return cert.get_serial_number()
            elif isinstance(cert, str):
                # assume a hex number
                return int(cert, 16)
            elif isinstance(cert, int):
                return cert
            return 0
    
        def get_serial_number(self):
            return self._get_serial(self.cert)
    
        def same_serial_as(self, other):
            return self._get_serial(self.cert) == self._get_serial(other)
    
        def get_not_before(self):
            tsp = self.cert.get_notBefore()
            return self._parse_tsp(tsp)
    
        def get_not_after(self):
            tsp = self.cert.get_notAfter()
            return self._parse_tsp(tsp)
    
        def get_cn(self):
            return self.cert.get_subject().CN
    
        def get_key_length(self):
            return self.cert.get_pubkey().bits()
    
        def get_san_list(self):
            text = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_TEXT, self.cert).decode("utf-8")
            m = re.search(r"X509v3 Subject Alternative Name:(\s+critical)?\s*(.*)", text)
            sans_list = []
            if m:
                sans_list = m.group(2).split(",")
    
            def _strip_prefix(s):
                return s.split(":")[1] if s.strip().startswith("DNS:") else s.strip()
            return list(map(_strip_prefix, sans_list))
    
        def get_must_staple(self):
            text = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_TEXT, self.cert).decode("utf-8")
            m = re.search(r"1.3.6.1.5.5.7.1.24:\s*\n\s*0....", text)
            if not m:
                # Newer openssl versions print this differently
                m = re.search(r"TLS Feature:\s*\n\s*status_request\s*\n", text)
            return m is not None
    
        @classmethod
        def validate_privkey(cls, privkey_path, passphrase=None):
            privkey_data = cls._load_binary_file(privkey_path)
            if passphrase:
                privkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, privkey_data, passphrase)
            else:
                privkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, privkey_data)
            return privkey.check()
    
        def validate_cert_matches_priv_key(self, privkey_path):
            # Verifies that the private key and cert match.
            privkey_data = MDCertUtil._load_binary_file(privkey_path)
            privkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, privkey_data)
            context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
            context.use_privatekey(privkey)
            context.use_certificate(self.cert)
            context.check_privatekey()
    
        # --------- _utils_ ---------
    
        def astr(self, s):
            return s.decode('utf-8')
            
        def _parse_tsp(self, tsp):
            # timestampss returned by PyOpenSSL are bytes
            # parse date and time part
            s = ("%s-%s-%s %s:%s:%s" % (self.astr(tsp[0:4]), self.astr(tsp[4:6]), self.astr(tsp[6:8]),
                                        self.astr(tsp[8:10]), self.astr(tsp[10:12]), self.astr(tsp[12:14])))
            timestamp = datetime.strptime(s, '%Y-%m-%d %H:%M:%S')
            # adjust timezone
            tz_h, tz_m = 0, 0
            m = re.match(r"([+\-]\d{2})(\d{2})", self.astr(tsp[14:]))
            if m:
                tz_h, tz_m = int(m.group(1)),  int(m.group(2)) if tz_h > 0 else -1 * int(m.group(2))
            return timestamp.replace(tzinfo=self.FixedOffset(60 * tz_h + tz_m))
    
        @classmethod
        def _load_binary_file(cls, path):
            with open(path, mode="rb") as file:
                return file.read()
    
        class FixedOffset(tzinfo):
    
            def __init__(self, offset):
                self.__offset = timedelta(minutes=offset)
    
            def utcoffset(self, dt):
                return self.__offset
    
            def tzname(self, dt):
                return None
    
            def dst(self, dt):
                return timedelta(0)
    ������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/dns01_v2.py������������������������������������������������������������0000775�0001751�0001751�00000003432�14630343666�017577� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import subprocess
    import sys
    
    curl = "curl"
    challtestsrv = "localhost:8055"
    
    
    def run(args):
        sys.stderr.write(f"run: {' '.join(args)}\n")
        p = subprocess.Popen(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output, errput = p.communicate(None)
        rv = p.wait()
        if rv != 0:
            sys.stderr.write(errput.decode())
        sys.stdout.write(output.decode())
        return rv
    
    
    def teardown(domain):
        rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}"}}',
                  f'{challtestsrv}/clear-txt'])
        if rv == 0:
            rv = run([curl, '-s', '-d', f'{{"host":"{domain}"}}',
                      f'{challtestsrv}/set-txt'])
        return rv
    
    
    def setup(domain, challenge):
        teardown(domain)
        rv = run([curl, '-s', '-d', f'{{"host":"{domain}", "addresses":["127.0.0.1"]}}',
                  f'{challtestsrv}/set-txt'])
        if rv == 0:
            rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}.", "value":"{challenge}"}}',
                      f'{challtestsrv}/set-txt'])
        return rv
    
    
    def main(argv):
        if len(argv) > 1:
            if argv[1] == 'setup':
                if len(argv) != 4:
                    sys.stderr.write("wrong number of arguments: dns01.py setup <domain> <challenge>\n")
                    sys.exit(2)
                rv = setup(argv[2], argv[3])
            elif argv[1] == 'teardown':
                if len(argv) != 4:
                    sys.stderr.write("wrong number of arguments: dns01.py teardown <domain> <challenge>\n")
                    sys.exit(1)
                rv = teardown(argv[2])
            else:
                sys.stderr.write(f"unknown option {argv[1]}\n")
                rv = 2
        else:
            sys.stderr.write("dns01.py wrong number of arguments\n")
            rv = 2
        sys.exit(rv)
    
    
    if __name__ == "__main__":
        main(sys.argv)
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_110_reg_update.py�������������������������������������������������0000664�0001751�0001751�00000024611�14240433464�021772� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md acme terms-of-service handling
    
    import pytest
    
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestRegUpdate:
    
        NAME1 = "greenbytes2.de"
        NAME2 = "test-100.com"
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env):
            env.clear_store()
            # add managed domains
            domains = [ 
                [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
                [self.NAME2, "test-101.com", "test-102.com"]
            ]
            for dns in domains:
                env.a2md(["-a", env.acme_url, "add"] + dns)
    
        def teardown_method(self, method):
            print("teardown_method: %s" % method.__name__)
    
        # test case: update domains
        def test_md_110_000(self, env):
            dns = ["foo.de", "bar.de"]
            output1 = env.a2md(["-vvvv", "update", self.NAME1, "domains"] + dns).json['output']
            assert len(output1) == 1
            env.check_json_contains(output1[0], {
                "name": self.NAME1,
                "domains": dns,
                "contacts": [],
                "ca": {
                    "urls": [env.acme_url],
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
            assert env.a2md(["list"]).json['output'][0] == output1[0]
    
        # test case: remove all domains
        def test_md_110_001(self, env):
            assert env.a2md(["update", self.NAME1, "domains"]).exit_code == 1
    
        # test case: update domains with invalid DNS
        @pytest.mark.parametrize("invalid_dns", [
            "tld", "white sp.ace", "invalid.*.wildcard.com", "k\xc3ller.idn.com"
        ])
        def test_md_110_002(self, env, invalid_dns):
            assert env.a2md(["update", self.NAME1, "domains", invalid_dns]).exit_code == 1
    
        # test case: update domains with overlapping DNS list
        def test_md_110_003(self, env):
            dns = [self.NAME1, self.NAME2]
            assert env.a2md(["update", self.NAME1, "domains"] + dns).exit_code == 1
    
        # test case: update with subdomains
        def test_md_110_004(self, env):
            dns = ["test-foo.com", "sub.test-foo.com"]
            md = env.a2md(["update", self.NAME1, "domains"] + dns).json['output'][0]
            assert md['name'] == self.NAME1
            assert md['domains'] == dns
    
        # test case: update domains with duplicates
        def test_md_110_005(self, env):
            dns = [self.NAME1, self.NAME1, self.NAME1]
            md = env.a2md(["update", self.NAME1, "domains"] + dns).json['output'][0]
            assert md['name'] == self.NAME1
            assert md['domains'] == [self.NAME1]
    
        # test case: remove domains with punycode
        def test_md_110_006(self, env):
            dns = [self.NAME1, "xn--kller-jua.punycode.de"]
            md = env.a2md(["update", self.NAME1, "domains"] + dns).json['output'][0]
            assert md['name'] == self.NAME1
            assert md['domains'] == dns
    
        # test case: update non-existing managed domain
        def test_md_110_007(self, env):
            assert env.a2md(["update", "test-foo.com", "domains", "test-foo.com"]).exit_code == 1
    
        # test case: update domains with DNS wildcard
        @pytest.mark.parametrize("wild_dns", [
            "*.wildcard.com"
        ])
        def test_md_110_008(self, env, wild_dns):
            assert env.a2md(["update", self.NAME1, "domains", wild_dns]).exit_code == 0
        
        # --------- update ca ---------
    
        # test case: update CA URL
        def test_md_110_100(self, env):
            url = "http://localhost.com:9999"
            output = env.a2md(["update", self.NAME1, "ca", url]).json['output']
            assert len(output) == 1
            env.check_json_contains(output[0], {
                "name": self.NAME1,
                "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
                "contacts": [],
                "ca": {
                    "urls": [url],
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
    
        # test case: update CA with invalid URL
        @pytest.mark.parametrize("invalid_url", [
            "no.schema/path", "http://white space/path", "http://bad.port:-1/path"
        ])
        def test_md_110_101(self, env, invalid_url):
            assert env.a2md(["update", self.NAME1, "ca", invalid_url]).exit_code == 1
    
        # test case: update ca protocol
        def test_md_110_102(self, env):
            md = env.a2md(["update", self.NAME1, "ca", env.acme_url, "FOO"]).json['output'][0]
            env.check_json_contains(md['ca'], {
                "urls": [env.acme_url],
                "proto": "FOO"
            })
            assert md['state'] == 1
    
        # test case: update account ID
        def test_md_110_200(self, env):
            acc_id = "test.account.id"
            output = env.a2md(["update", self.NAME1, "account", acc_id]).json['output']
            assert len(output) == 1
            env.check_json_contains(output[0], {
                "name": self.NAME1,
                "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
                "contacts": [],
                "ca": {
                    "account": acc_id,
                    "urls": [env.acme_url],
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
    
        # test case: remove account ID
        def test_md_110_201(self, env):
            assert env.a2md(["update", self.NAME1, "account", "test.account.id"]).exit_code == 0
            md = env.a2md(["update", self.NAME1, "account"]).json['output'][0]
            env.check_json_contains(md['ca'], {
                "urls": [env.acme_url],
                "proto": "ACME"
            })
            assert md['state'] == 1
    
        # test case: change existing account ID
        def test_md_110_202(self, env):
            assert env.a2md(["update", self.NAME1, "account", "test.account.id"]).exit_code == 0
            md = env.a2md(["update", self.NAME1, "account", "foo.test.com"]).json['output'][0]
            env.check_json_contains(md['ca'], {
                "account": "foo.test.com",
                "urls": [env.acme_url],
                "proto": "ACME"
            })
            assert md['state'] == 1
    
        # test case: ignore additional argument
        def test_md_110_203(self, env):
            md = env.a2md(["update", self.NAME1, "account", "test.account.id",
                           "test2.account.id"]).json['output'][0]
            env.check_json_contains(md['ca'], {
                "account": "test.account.id",
                "urls": [env.acme_url],
                "proto": "ACME"
            })
            assert md['state'] == 1
    
        # test case: add contact info
        def test_md_110_300(self, env):
            mail = "test@greenbytes.de"
            output = env.a2md(["update", self.NAME1, "contacts", mail]).json['output']
            assert len(output) == 1
            env.check_json_contains(output[0], {
                "name": self.NAME1,
                "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
                "contacts": ["mailto:" + mail],
                "ca": {
                    "urls": [env.acme_url],
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
    
        # test case: add multiple contact info, preserve order
        def test_md_110_301(self, env):
            mail = ["xxx@greenbytes.de", "aaa@greenbytes.de"]
            md = env.a2md(["update", self.NAME1, "contacts"] + mail).json['output'][0]
            assert md['contacts'] == ["mailto:" + mail[0], "mailto:" + mail[1]]
            assert md['state'] == 1
    
        # test case: must not remove contact info
        def test_md_110_302(self, env):
            assert env.a2md(["update", self.NAME1, "contacts", "test@greenbytes.de"]).exit_code == 0
            assert env.a2md(["update", self.NAME1, "contacts"]).exit_code == 1
    
        # test case: replace existing contact info
        def test_md_110_303(self, env):
            assert env.a2md(["update", self.NAME1, "contacts", "test@greenbytes.de"]).exit_code == 0
            md = env.a2md(["update", self.NAME1, "contacts", "xxx@greenbytes.de"]).json['output'][0]
            assert md['contacts'] == ["mailto:xxx@greenbytes.de"]
            assert md['state'] == 1
    
        # test case: use invalid mail address
        @pytest.mark.parametrize("invalid_mail", [
            "no.at.char", "with blank@test.com", "missing.host@", "@missing.localpart.de",
            "double..dot@test.com", "double@at@test.com"
        ])
        def test_md_110_304(self, env, invalid_mail):
            # SEI: Uhm, es ist nicht sinnvoll, eine komplette verification von
            # https://tools.ietf.org/html/rfc822 zu bauen?
            assert env.a2md(["update", self.NAME1, "contacts", invalid_mail]).exit_code == 1
    
        # test case: respect urls as given
        @pytest.mark.parametrize("url", [
            "mailto:test@greenbytes.de", "wrong://schema@test.com"])
        def test_md_110_305(self, env, url):
            md = env.a2md(["update", self.NAME1, "contacts", url]).json['output'][0]
            assert md['contacts'] == [url]
            assert md['state'] == 1
    
        # test case: add tos agreement
        def test_md_110_400(self, env):
            output = env.a2md(["update", self.NAME1, "agreement", env.acme_tos]).json['output']
            assert len(output) == 1
            env.check_json_contains(output[0], {
                "name": self.NAME1,
                "domains": [self.NAME1, "www.greenbytes2.de", "mail.greenbytes2.de"],
                "contacts": [],
                "ca": {
                    "urls": [env.acme_url],
                    "proto": "ACME",
                    "agreement": env.acme_tos
                },
                "state": env.MD_S_INCOMPLETE
            })
    
        # test case: remove tos agreement
        def test_md_110_402(self, env):
            assert env.a2md(["update", self.NAME1, "agreement", env.acme_tos]).exit_code == 0
            md = env.a2md(["update", self.NAME1, "agreement"]).json['output'][0]
            env.check_json_contains(md['ca'], {
                "urls": [env.acme_url],
                "proto": "ACME"
            })
            assert md['state'] == 1
    
        # test case: ignore additional arguments
        def test_md_110_403(self, env):
            md = env.a2md(["update", self.NAME1, "agreement",
                           env.acme_tos, "http://invalid.tos/"]).json['output'][0]
            env.check_json_contains(md['ca'], {
                "urls": [env.acme_url],
                "proto": "ACME",
                "agreement": env.acme_tos
            })
            assert md['state'] == 1
    
        # test case: update agreement with invalid URL
        @pytest.mark.parametrize("invalid_url", [
            "no.schema/path", "http://white space/path", "http://bad.port:-1/path"
        ])
        def test_md_110_404(self, env, invalid_url):
            assert env.a2md(["update", self.NAME1, "agreement", invalid_url]).exit_code == 1
    �����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_901_message.py����������������������������������������������������0000664�0001751�0001751�00000034151�14750656217�021320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md message support
    
    import json
    import os
    import time
    from datetime import timedelta
    import pytest
    from pyhttpd.certs import CertificateSpec
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestMessage:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
            self.mcmd = os.path.join(env.test_dir, "../modules/md/message.py")
            self.mlog = os.path.join(env.gen_dir, "message.log")
            if os.path.isfile(self.mlog):
                os.remove(self.mlog)
    
        # test: signup with configured message cmd that is invalid
        def test_md_901_001(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add("MDMessageCmd blablabla")
            conf.add_drive_mode("auto")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_file(env.store_staged_file(domain, 'job.json'))
            stat = env.get_md_status(domain)
            # this command should have failed and logged an error
            assert stat["renewal"]["last"]["problem"] == "urn:org:apache:httpd:log:AH10109:"
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # None of the offered challenge types
                ],
                matches = [
                    r'.*urn:org:apache:httpd:log:AH10109:.*',
                    r'.*problem\[challenge-setup-failure\].*'
                ]
            )
    
        # test: signup with configured message cmd that is valid but returns != 0
        def test_md_901_002(self, env):
            mcmd = os.path.join(env.test_dir, "../modules/md/notifail.py")
            domain = self.test_domain
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {mcmd} {self.mlog}")
            conf.add_drive_mode("auto")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            stat = env.get_md_status(domain)
            # this command should have failed and logged an error
            assert stat["renewal"]["last"]["problem"] == "urn:org:apache:httpd:log:AH10109:"
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # None of the offered challenge types
                ],
                matches = [
                    r'.*urn:org:apache:httpd:log:AH10109:.*',
                    r'.*problem\[challenge-setup-failure\].*'
                ]
            )
    
        # test: signup with working message cmd and see that it logs the right things
        def test_md_901_003(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
            conf.add_drive_mode("auto")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False)
            time.sleep(1)
            stat = env.get_md_status(domain)
            # this command did not fail and logged itself the correct information
            assert stat["renewal"]["last"]["status"] == 0
            assert stat["renewal"]["log"]["entries"]
            assert stat["renewal"]["log"]["entries"][0]["type"] == "message-renewed"
            # shut down server to make sure that md has completed 
            assert env.apache_stop() == 0
            nlines = open(self.mlog).readlines()
            assert 3 == len(nlines)
            nlines = [s.strip() for s in nlines]
            assert "['{cmd}', '{logfile}', 'challenge-setup:http-01:{dns}', '{mdomain}']".format(
                cmd=self.mcmd, logfile=self.mlog, mdomain=domain, dns=domains[0]) in nlines
            assert "['{cmd}', '{logfile}', 'challenge-setup:http-01:{dns}', '{mdomain}']".format(
                cmd=self.mcmd, logfile=self.mlog, mdomain=domain, dns=domains[1]) in nlines
            assert nlines[2].strip() == "['{cmd}', '{logfile}', 'renewed', '{mdomain}']".format(
                cmd=self.mcmd, logfile=self.mlog, mdomain=domain)
    
        # test issue #145: 
        # - a server renews a valid certificate and is not restarted when recommended
        # - the job did not clear its next_run and was run over and over again
        # - the job logged the re-verifications again and again. which was saved.
        # - this eventually flushed out the "message-renew" log entry
        # - which caused the renew message handling to trigger again and again
        # the fix does:
        # - reset the next run
        # - no longer adds the re-validations to the log
        # - messages only once
        @pytest.mark.skipif(MDTestEnv.is_pebble(), reason="ACME server certs valid too long")
        def test_md_901_004(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            # force renew
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
            conf.add("MDRenewWindow 120d")
            conf.add("MDActivationDelay -7d")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False)
            env.get_md_status(domain)
            assert env.await_file(self.mlog)
            nlines = open(self.mlog).readlines()
            assert len(nlines) == 1
            assert nlines[0].strip() == f"['{self.mcmd}', '{self.mlog}', 'renewed', '{domain}']"
        
        def test_md_901_010(self, env):
            #  MD with static cert files, lifetime in renewal window, no message about renewal
            domain = self.test_domain
            domains = [domain, 'www.%s' % domain]
            testpath = os.path.join(env.gen_dir, 'test_901_010')
            env.mkpath(testpath)
            # cert that is only 20 more days valid
            creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
                                                valid_from=timedelta(days=-70),
                                                valid_to=timedelta(days=20),
                                                serial=901010)
            cert_file = os.path.join(testpath, 'pubcert.pem')
            pkey_file = os.path.join(testpath, 'privkey.pem')
            creds.save_cert_pem(cert_file)
            creds.save_pkey_pem(pkey_file)
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
            conf.start_md(domains)
            conf.add(f"MDCertificateFile {cert_file}")
            conf.add(f"MDCertificateKeyFile {pkey_file}")
            conf.end_md()
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert not os.path.isfile(self.mlog)
            
        def test_md_901_011(self, env):
            # MD with static cert files, lifetime in warn window, check message
            domain = self.test_domain
            domains = [domain, f'www.{domain}']
            testpath = os.path.join(env.gen_dir, 'test_901_011')
            env.mkpath(testpath)
            # cert that is only 5 more days valid
            creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
                                                valid_from=timedelta(days=-85),
                                                valid_to=timedelta(days=5),
                                                serial=901010)
            cert_file = os.path.join(testpath, 'pubcert.pem')
            pkey_file = os.path.join(testpath, 'privkey.pem')
            creds.save_cert_pem(cert_file)
            creds.save_pkey_pem(pkey_file)
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
            conf.start_md(domains)
            conf.add(f"MDCertificateFile {cert_file}")
            conf.add(f"MDCertificateKeyFile {pkey_file}")
            conf.end_md()
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_file(self.mlog)
            nlines = open(self.mlog).readlines()
            assert len(nlines) == 1
            assert nlines[0].strip() == f"['{self.mcmd}', '{self.mlog}', 'expiring', '{domain}']"
            # check that we do not get it resend right away again
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            time.sleep(1)
            nlines = open(self.mlog).readlines()
            assert len(nlines) == 1
            assert nlines[0].strip() == f"['{self.mcmd}', '{self.mlog}', 'expiring', '{domain}']"
    
        # MD, check messages from stapling
        @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder")
        def test_md_901_020(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
            conf.add_drive_mode("auto")
            conf.add_md(domains)
            conf.add("MDStapling on")
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            env.await_ocsp_status(domain)
            assert env.await_file(self.mlog)
            time.sleep(1)
            nlines = open(self.mlog).readlines()
            assert len(nlines) == 4
            assert nlines[0].strip() == \
                   f"['{self.mcmd}', '{self.mlog}', 'challenge-setup:http-01:{domain}', '{domain}']"
            assert nlines[1].strip() == \
                   f"['{self.mcmd}', '{self.mlog}', 'renewed', '{domain}']"
            assert nlines[2].strip() == \
                   f"['{self.mcmd}', '{self.mlog}', 'installed', '{domain}']"
            assert nlines[3].strip() == \
                   f"['{self.mcmd}', '{self.mlog}', 'ocsp-renewed', '{domain}']"
    
        # test: while testing gh issue #146, it was noted that a failed renew notification never
        # resets the MD activity.
        @pytest.mark.skipif(MDTestEnv.is_pebble(), reason="ACME server certs valid too long")
        def test_md_901_030(self, env):
            domain = self.test_domain
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            # set the warn window that triggers right away and a failing message command
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {env.test_dir}../modules/md/notifail.py {self.mlog}")
            conf.add_md(domains)
            conf.add("""
                MDWarnWindow 100d
                """)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.get_md_status(domain)
            # this command should have failed and logged an error
            # shut down server to make sure that md has completed
            assert env.await_file(env.store_staged_file(domain, 'job.json'))
            while True:
                with open(env.store_staged_file(domain, 'job.json')) as f:
                    job = json.load(f)
                    if job["errors"] > 0:
                        assert job["errors"] > 0,  "unexpected job result: {0}".format(job)
                        assert job["last"]["problem"] == "urn:org:apache:httpd:log:AH10109:"
                        break
                time.sleep(0.1)
    
            # reconfigure to a working notification command and restart
            conf = MDConf(env)
            conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
            conf.add_md(domains)
            conf.add("""
                MDWarnWindow 100d
                """)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_file(self.mlog)
            # we see the notification logged by the command
            nlines = open(self.mlog).readlines()
            assert len(nlines) == 1
            assert nlines[0].strip() == f"['{self.mcmd}', '{self.mlog}', 'expiring', '{domain}']"
            # the error needs to be gone
            assert env.await_file(env.store_staged_file(domain, 'job.json'))
            with open(env.store_staged_file(domain, 'job.json')) as f:
                job = json.load(f)
                assert job["errors"] == 0
    
        # MD, check a failed challenge setup
        def test_md_901_040(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            mcmd = os.path.join(env.test_dir, "../modules/md/msg_fail_on.py")
            conf.add(f"MDMessageCmd {mcmd} {self.mlog} challenge-setup")
            conf.add_drive_mode("auto")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            assert env.await_file(self.mlog)
            time.sleep(1)
            nlines = open(self.mlog).readlines()
            assert len(nlines) == 2
            assert nlines[0].strip() == \
                   f"['{mcmd}', '{self.mlog}', 'challenge-setup:http-01:{domain}', '{domain}']"
            assert nlines[1].strip() == \
                   f"['{mcmd}', '{self.mlog}', 'errored', '{domain}']"
            stat = env.get_md_status(domain)
            # this command should have failed and logged an error
            assert stat["renewal"]["last"]["problem"] == "challenge-setup-failure"
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # None of the offered challenge types
                ],
                matches = [
                    r'.*urn:org:apache:httpd:log:AH10109:.*',
                    r'.*problem\[challenge-setup-failure\].*'
                ]
            )
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/md_env.py��������������������������������������������������������������0000775�0001751�0001751�00000056575�14672270657�017540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import copy
    import inspect
    import json
    import logging
    from configparser import ConfigParser, ExtendedInterpolation
    
    import pytest
    import re
    import os
    import shutil
    import subprocess
    import time
    
    from datetime import datetime, timedelta
    from typing import Dict, Optional, Any
    
    from pyhttpd.certs import CertificateSpec, Credentials, HttpdTestCA
    from .md_cert_util import MDCertUtil
    from pyhttpd.env import HttpdTestSetup, HttpdTestEnv
    from pyhttpd.result import ExecResult
    
    log = logging.getLogger(__name__)
    
    
    class MDTestSetup(HttpdTestSetup):
    
        def __init__(self, env: 'MDTestEnv'):
            super().__init__(env=env)
            self.mdenv = env
            self.add_modules(["watchdog", "proxy_connect", "md"])
    
        def make(self):
            super().make()
            if "pebble" == self.mdenv.acme_server:
                self._make_pebble_conf()
            self.mdenv.clear_store()
    
        def _make_pebble_conf(self):
            our_dir = os.path.dirname(inspect.getfile(MDTestSetup))
            conf_src_dir = os.path.join(our_dir, 'pebble')
            conf_dest_dir = os.path.join(self.env.gen_dir, 'pebble')
            if not os.path.exists(conf_dest_dir):
                os.makedirs(conf_dest_dir)
            for name in os.listdir(conf_src_dir):
                src_path = os.path.join(conf_src_dir, name)
                m = re.match(r'(.+).template', name)
                if m:
                    self._make_template(src_path, os.path.join(conf_dest_dir, m.group(1)))
                elif os.path.isfile(src_path):
                    shutil.copy(src_path, os.path.join(conf_dest_dir, name))
    
    
    class MDTestEnv(HttpdTestEnv):
    
        MD_S_UNKNOWN = 0
        MD_S_INCOMPLETE = 1
        MD_S_COMPLETE = 2
        MD_S_EXPIRED = 3
        MD_S_ERROR = 4
    
        EMPTY_JOUT = {'status': 0, 'output': []}
    
        DOMAIN_SUFFIX = "%d.org" % time.time()
        LOG_FMT_TIGHT = '%(levelname)s: %(message)s'
    
        @classmethod
        def get_acme_server(cls):
            return os.environ['ACME'] if 'ACME' in os.environ else "pebble"
    
        @classmethod
        def has_acme_server(cls):
            return cls.get_acme_server() != 'none'
    
        @classmethod
        def has_acme_eab(cls):
            # Pebble, in v2.5.0 no longer supported HS256 for EAB, which
            # is the only thing mod_md supports. Issue opened at pebble:
            # https://github.com/letsencrypt/pebble/issues/455
            # is fixed in v2.6.0
            return cls.get_acme_server() == 'pebble'
    
        @classmethod
        def is_pebble(cls) -> bool:
            return cls.get_acme_server() == 'pebble'
    
        @classmethod
        def lacks_ocsp(cls):
            return cls.is_pebble()
    
        @classmethod
        def has_a2md(cls):
            d = os.path.dirname(inspect.getfile(HttpdTestEnv))
            config = ConfigParser(interpolation=ExtendedInterpolation())
            config.read(os.path.join(d, 'config.ini'))
            bin_dir = config.get('global', 'bindir')
            a2md_bin = os.path.join(bin_dir, 'a2md')
            return os.path.isfile(a2md_bin)
    
        def __init__(self, pytestconfig=None):
            super().__init__(pytestconfig=pytestconfig)
            self.add_httpd_log_modules(["md"])
            self._acme_server = self.get_acme_server()
            self._acme_tos = "accepted"
            self._acme_ca_pemfile = os.path.join(self.gen_dir, "apache/acme-ca.pem")
            if "pebble" == self._acme_server:
                self._acme_url = "https://localhost:14000/dir"
                self._acme_eab_url = "https://localhost:14001/dir"
            elif "boulder" == self._acme_server:
                self._acme_url = "http://localhost:4001/directory"
                self._acme_eab_url = None
            else:
                raise Exception(f"unknown ACME server type: {self._acme_server}")
            self._acme_server_down = False
            self._acme_server_ok = False
    
            self._a2md_bin = os.path.join(self.bin_dir, 'a2md')
            self._default_domain = f"test1.{self.http_tld}"
            self._tailscale_domain = "test.headless-chicken.ts.net"
            self._store_dir = "./md"
            self.set_store_dir_default()
    
            self.add_cert_specs([
                CertificateSpec(domains=[f"expired.{self._http_tld}"],
                                valid_from=timedelta(days=-100),
                                valid_to=timedelta(days=-10)),
                CertificateSpec(domains=["localhost"], key_type='rsa2048'),
                CertificateSpec(domains=[self._tailscale_domain]),
            ])
    
        def setup_httpd(self, setup: HttpdTestSetup = None):
            super().setup_httpd(setup=MDTestSetup(env=self))
    
        def set_store_dir_default(self):
            dirpath = "md"
            if self.httpd_is_at_least("2.5.0"):
                dirpath = os.path.join("state", dirpath)
            self.set_store_dir(dirpath)
    
        def set_store_dir(self, dirpath):
            self._store_dir = os.path.join(self.server_dir, dirpath)
            if self.acme_url:
                self.a2md_stdargs([self.a2md_bin, "-a", self.acme_url,
                                   "-d", self._store_dir,  "-C", self.acme_ca_pemfile, "-j"])
                self.a2md_rawargs([self.a2md_bin, "-a", self.acme_url,
                                   "-d", self._store_dir,  "-C", self.acme_ca_pemfile])
    
        def get_apxs_var(self, name: str) -> str:
            p = subprocess.run([self._apxs, "-q", name], capture_output=True, text=True)
            if p.returncode != 0:
                return ""
            return p.stdout.strip()
    
        @property
        def acme_server(self):
            return self._acme_server
    
        @property
        def acme_url(self):
            return self._acme_url
    
        @property
        def acme_tos(self):
            return self._acme_tos
    
        @property
        def a2md_bin(self):
            return self._a2md_bin
    
        @property
        def acme_ca_pemfile(self):
            return self._acme_ca_pemfile
    
        @property
        def store_dir(self):
            return self._store_dir
    
        @property
        def tailscale_domain(self):
            return self._tailscale_domain
    
        def get_request_domain(self, request):
            name = request.node.originalname if request.node.originalname else request.node.name
            return "%s-%s" % (re.sub(r'[_]', '-', name), MDTestEnv.DOMAIN_SUFFIX)
    
        def get_method_domain(self, method):
            return "%s-%s" % (re.sub(r'[_]', '-', method.__name__.lower()), MDTestEnv.DOMAIN_SUFFIX)
    
        def get_module_domain(self, module):
            return "%s-%s" % (re.sub(r'[_]', '-', module.__name__.lower()), MDTestEnv.DOMAIN_SUFFIX)
    
        def get_class_domain(self, c):
            return "%s-%s" % (re.sub(r'[_]', '-', c.__name__.lower()), MDTestEnv.DOMAIN_SUFFIX)
    
        # --------- cmd execution ---------
    
        _a2md_args = []
        _a2md_args_raw = []
    
        def a2md_stdargs(self, args):
            self._a2md_args = [] + args
    
        def a2md_rawargs(self, args):
            self._a2md_args_raw = [] + args
    
        def a2md(self, args, raw=False) -> ExecResult:
            preargs = self._a2md_args
            if raw:
                preargs = self._a2md_args_raw
            log.debug("running: {0} {1}".format(preargs, args))
            return self.run(preargs + args)
    
        def check_acme(self):
            if self._acme_server_ok:
                return True
            if self._acme_server_down:
                pytest.skip(msg="ACME server not running")
                return False
            if self.is_live(self.acme_url, timeout=timedelta(seconds=0.5)):
                self._acme_server_ok = True
                return True
            else:
                self._acme_server_down = True
                pytest.fail(msg="ACME server not running", pytrace=False)
                return False
    
        def get_ca_pem_file(self, hostname: str) -> Optional[str]:
            pem_file = super().get_ca_pem_file(hostname)
            if pem_file is None:
                pem_file = self.acme_ca_pemfile
            return pem_file
    
        # --------- access local store ---------
    
        def purge_store(self):
            log.debug("purge store dir: %s" % self._store_dir)
            assert len(self._store_dir) > 1
            if os.path.exists(self._store_dir):
                shutil.rmtree(self._store_dir, ignore_errors=False)
            os.makedirs(self._store_dir)
    
        def clear_store(self):
            log.debug("clear store dir: %s" % self._store_dir)
            assert len(self._store_dir) > 1
            if not os.path.exists(self._store_dir):
                os.makedirs(self._store_dir)
            for dirpath in ["challenges", "tmp", "archive", "domains", "accounts", "staging", "ocsp"]:
                shutil.rmtree(os.path.join(self._store_dir, dirpath), ignore_errors=True)
    
        def clear_ocsp_store(self):
            assert len(self._store_dir) > 1
            dirpath = os.path.join(self._store_dir, "ocsp")
            log.debug("clear ocsp store dir: %s" % dir)
            if os.path.exists(dirpath):
                shutil.rmtree(dirpath, ignore_errors=True)
    
        def authz_save(self, name, content):
            dirpath = os.path.join(self._store_dir, 'staging', name)
            os.makedirs(dirpath)
            open(os.path.join(dirpath, 'authz.json'), "w").write(content)
    
        def path_store_json(self):
            return os.path.join(self._store_dir, 'md_store.json')
    
        def path_account(self, acct):
            return os.path.join(self._store_dir, 'accounts', acct, 'account.json')
    
        def path_account_key(self, acct):
            return os.path.join(self._store_dir, 'accounts', acct, 'account.pem')
    
        def store_domains(self):
            return os.path.join(self._store_dir, 'domains')
    
        def store_archives(self):
            return os.path.join(self._store_dir, 'archive')
    
        def store_stagings(self):
            return os.path.join(self._store_dir, 'staging')
    
        def store_challenges(self):
            return os.path.join(self._store_dir, 'challenges')
    
        def store_domain_file(self, domain, filename):
            return os.path.join(self.store_domains(), domain, filename)
    
        def store_archived_file(self, domain, version, filename):
            return os.path.join(self.store_archives(), "%s.%d" % (domain, version), filename)
    
        def store_staged_file(self, domain, filename):
            return os.path.join(self.store_stagings(), domain, filename)
    
        def path_fallback_cert(self, domain):
            return os.path.join(self._store_dir, 'domains', domain, 'fallback-pubcert.pem')
    
        def path_job(self, domain):
            return os.path.join(self._store_dir, 'staging', domain, 'job.json')
    
        def replace_store(self, src):
            shutil.rmtree(self._store_dir, ignore_errors=False)
            shutil.copytree(src, self._store_dir)
    
        def list_accounts(self):
            return os.listdir(os.path.join(self._store_dir, 'accounts'))
    
        def check_md(self, domain, md=None, state=-1, ca=None, protocol=None, agreement=None, contacts=None):
            domains = None
            if isinstance(domain, list):
                domains = domain
                domain = domains[0]
            if md:
                domain = md
            path = self.store_domain_file(domain, 'md.json')
            with open(path) as f:
                md = json.load(f)
            assert md
            if domains:
                assert md['domains'] == domains
            if state >= 0:
                assert md['state'] == state
            if ca:
                assert len(md['ca']['urls']) == 1
                assert md['ca']['urls'][0] == ca
            if protocol:
                assert md['ca']['proto'] == protocol
            if agreement:
                assert md['ca']['agreement'] == agreement
            if contacts:
                assert md['contacts'] == contacts
    
        def pkey_fname(self, pkeyspec=None):
            if pkeyspec and not re.match(r'^rsa( ?\d+)?$', pkeyspec.lower()):
                return "privkey.{0}.pem".format(pkeyspec.lower())
            return 'privkey.pem'
    
        def cert_fname(self, pkeyspec=None):
            if pkeyspec and not re.match(r'^rsa( ?\d+)?$', pkeyspec.lower()):
                return "pubcert.{0}.pem".format(pkeyspec.lower())
            return 'pubcert.pem'
    
        def check_md_complete(self, domain, pkey=None):
            md = self.get_md_status(domain)
            assert md
            assert 'state' in md, "md is unexpected: {0}".format(md)
            assert md['state'] is MDTestEnv.MD_S_COMPLETE, f"unexpected state: {md['state']}"
            pkey_file = self.store_domain_file(domain, self.pkey_fname(pkey))
            cert_file = self.store_domain_file(domain, self.cert_fname(pkey))
            r = self.run(['ls', os.path.dirname(pkey_file)])
            if not os.path.isfile(pkey_file):
                assert False, f"pkey missing: {pkey_file}: {r.stdout}"
            if not os.path.isfile(cert_file):
                assert False, f"cert missing: {cert_file}: {r.stdout}"
            return md
    
        def check_md_credentials(self, domain):
            if isinstance(domain, list):
                domains = domain
                domain = domains[0]
            else:
                domains = [domain]
            # check private key, validate certificate, etc
            MDCertUtil.validate_privkey(self.store_domain_file(domain, 'privkey.pem'))
            cert = MDCertUtil(self.store_domain_file(domain, 'pubcert.pem'))
            cert.validate_cert_matches_priv_key(self.store_domain_file(domain, 'privkey.pem'))
            # No longer check CN, it may not be set or is not trusted anyway
            # assert cert.get_cn() == domain, f'CN: expected "{domain}", got {cert.get_cn()}'
            # check SANs
            # compare lists twice in opposite directions: SAN may not respect ordering
            san_list = list(cert.get_san_list())
            assert len(san_list) == len(domains)
            assert set(san_list).issubset(domains), f'{san_list} not subset of {domains}'
            assert set(domains).issubset(san_list), f'{domains} not subset of {san_list}'
            # check valid dates interval
            not_before = cert.get_not_before()
            not_after = cert.get_not_after()
            assert not_before < datetime.now(not_before.tzinfo)
            assert not_after > datetime.now(not_after.tzinfo)
    
        # --------- check utilities ---------
    
        def check_json_contains(self, actual, expected):
            # write all expected key:value bindings to a copy of the actual data ... 
            # ... assert it stays unchanged 
            test_json = copy.deepcopy(actual)
            test_json.update(expected)
            assert actual == test_json
    
        def check_file_access(self, path, exp_mask):
            actual_mask = os.lstat(path).st_mode & 0o777
            assert oct(actual_mask) == oct(exp_mask)
    
        def check_dir_empty(self, path):
            assert os.listdir(path) == []
    
        def get_http_status(self, domain, path, use_https=True):
            r = self.get_meta(domain, path, use_https, insecure=True)
            return r.response['status']
    
        def get_cert(self, domain, tls=None, ciphers=None):
            return MDCertUtil.load_server_cert(self._httpd_addr, self.https_port,
                                               domain, tls=tls, ciphers=ciphers)
    
        def get_server_cert(self, domain, proto=None, ciphers=None):
            args = [
                "openssl", "s_client", "-status",
                "-connect", "%s:%s" % (self._httpd_addr, self.https_port),
                "-CAfile", self.acme_ca_pemfile,
                "-servername", domain,
                "-showcerts"
            ]
            if proto is not None:
                args.extend(["-{0}".format(proto)])
            if ciphers is not None:
                args.extend(["-cipher", ciphers])
            r = self.run(args)
            # noinspection PyBroadException
            try:
                return MDCertUtil.parse_pem_cert(r.stdout)
            except:
                return None
    
        def verify_cert_key_lenghts(self, domain, pkeys):
            for p in pkeys:
                cert = self.get_server_cert(domain, proto="tls1_2", ciphers=p['ciphers'])
                if 0 == p['keylen']:
                    assert cert is None
                else:
                    assert cert, "no cert returned for cipher: {0}".format(p['ciphers'])
                    assert cert.get_key_length() == p['keylen'], "key length, expected {0}, got {1}".format(
                        p['keylen'], cert.get_key_length()
                    )
    
        def get_meta(self, domain, path, use_https=True, insecure=False):
            schema = "https" if use_https else "http"
            port = self.https_port if use_https else self.http_port
            r = self.curl_get(f"{schema}://{domain}:{port}{path}", insecure=insecure)
            assert r.exit_code == 0
            assert r.response
            assert r.response['header']
            return r
    
        def get_content(self, domain, path, use_https=True):
            schema = "https" if use_https else "http"
            port = self.https_port if use_https else self.http_port
            r = self.curl_get(f"{schema}://{domain}:{port}{path}")
            assert r.exit_code == 0
            return r.stdout
    
        def get_json_content(self, domain, path, use_https=True, insecure=False):
            schema = "https" if use_https else "http"
            port = self.https_port if use_https else self.http_port
            url = f"{schema}://{domain}:{port}{path}"
            r = self.curl_get(url, insecure=insecure)
            if r.exit_code != 0:
                log.error(f"curl get on {url} returned {r.exit_code}"
                          f"\nstdout: {r.stdout}"
                          f"\nstderr: {r.stderr}")
            assert r.exit_code == 0, r.stderr
            return r.json
    
        def get_certificate_status(self, domain) -> Dict:
            return self.get_json_content(domain, "/.httpd/certificate-status", insecure=True)
    
        def get_md_status(self, domain, via_domain=None, use_https=True) -> Dict:
            if via_domain is None:
                via_domain = self._default_domain
            return self.get_json_content(via_domain, f"/md-status/{domain}",
                                         use_https=use_https)
    
        def get_server_status(self, query="/", via_domain=None, use_https=True):
            if via_domain is None:
                via_domain = self._default_domain
            return self.get_content(via_domain, "/server-status%s" % query, use_https=use_https)
    
        def await_completion(self, names, must_renew=False, restart=True, timeout=60,
                             via_domain=None, use_https=True):
            try_until = time.time() + timeout
            renewals = {}
            names = names.copy()
            while len(names) > 0:
                if time.time() >= try_until:
                    return False
                for name in names:
                    mds = self.get_md_status(name, via_domain=via_domain, use_https=use_https)
                    if mds is None:
                        log.debug("not managed by md: %s" % name)
                        return False
    
                    if 'renewal' in mds:
                        renewal = mds['renewal']
                        renewals[name] = True
                        if 'finished' in renewal and renewal['finished'] is True:
                            if (not must_renew) or (name in renewals):
                                log.debug(f"domain cert was renewed: {name}")
                                names.remove(name)
    
                if len(names) != 0:
                    time.sleep(0.1)
            if restart:
                time.sleep(0.1)
                return self.apache_restart() == 0
            return True
    
        def is_renewing(self, name):
            stat = self.get_certificate_status(name)
            return 'renewal' in stat
    
        def await_renewal(self, names, timeout=60):
            try_until = time.time() + timeout
            while len(names) > 0:
                if time.time() >= try_until:
                    return False
                for name in names:
                    md = self.get_md_status(name)
                    if md is None:
                        log.debug("not managed by md: %s" % name)
                        return False
    
                    if 'renewal' in md:
                        names.remove(name)
    
                if len(names) != 0:
                    time.sleep(0.1)
            return True
    
        def await_error(self, domain, timeout=60, via_domain=None, use_https=True, errors=1):
            try_until = time.time() + timeout
            while True:
                if time.time() >= try_until:
                    return False
                md = self.get_md_status(domain, via_domain=via_domain, use_https=use_https)
                if md:
                    if 'state' in md and md['state'] == MDTestEnv.MD_S_ERROR:
                        return md
                    if 'renewal' in md and 'errors' in md['renewal'] \
                            and md['renewal']['errors'] >= errors:
                        return md
                time.sleep(0.1)
    
        def await_file(self, fpath, timeout=60):
            try_until = time.time() + timeout
            while True:
                if time.time() >= try_until:
                    return False
                if os.path.isfile(fpath):
                    return True
                time.sleep(0.1)
    
        def check_file_permissions(self, domain):
            dpath = os.path.join(self.store_dir, 'domains', domain)
            assert os.path.isdir(dpath)
            md = json.load(open(os.path.join(dpath, 'md.json')))
            assert md
            acct = md['ca']['account']
            assert acct
            self.check_file_access(self.path_store_json(), 0o600)
            # domains
            self.check_file_access(self.store_domains(), 0o700)
            self.check_file_access(os.path.join(self.store_domains(), domain), 0o700)
            self.check_file_access(self.store_domain_file(domain, 'privkey.pem'), 0o600)
            self.check_file_access(self.store_domain_file(domain, 'pubcert.pem'), 0o600)
            self.check_file_access(self.store_domain_file(domain, 'md.json'), 0o600)
            # archive
            self.check_file_access(self.store_archived_file(domain, 1, 'md.json'), 0o600)
            # accounts
            self.check_file_access(os.path.join(self._store_dir, 'accounts'), 0o755)
            self.check_file_access(os.path.join(self._store_dir, 'accounts', acct), 0o755)
            self.check_file_access(self.path_account(acct), 0o644)
            self.check_file_access(self.path_account_key(acct), 0o644)
            # staging
            self.check_file_access(self.store_stagings(), 0o755)
    
        def get_ocsp_status(self, domain, proto=None, cipher=None, ca_file=None):
            stat = {}
            args = [
                "openssl", "s_client", "-status",
                "-connect", "%s:%s" % (self._httpd_addr, self.https_port),
                "-CAfile", ca_file if ca_file else self.acme_ca_pemfile,
                "-servername", domain,
                "-showcerts"
            ]
            if proto is not None:
                args.extend(["-{0}".format(proto)])
            if cipher is not None:
                args.extend(["-cipher", cipher])
            r = self.run(args, debug_log=False)
            ocsp_regex = re.compile(r'OCSP response: +([^=\n]+)\n')
            matches = ocsp_regex.finditer(r.stdout)
            for m in matches:
                if m.group(1) != "":
                    stat['ocsp'] = m.group(1)
            if 'ocsp' not in stat:
                ocsp_regex = re.compile(r'OCSP Response Status:\s*(.+)')
                matches = ocsp_regex.finditer(r.stdout)
                for m in matches:
                    if m.group(1) != "":
                        stat['ocsp'] = m.group(1)
            verify_regex = re.compile(r'Verify return code:\s*(.+)')
            matches = verify_regex.finditer(r.stdout)
            for m in matches:
                if m.group(1) != "":
                    stat['verify'] = m.group(1)
            return stat
    
        def await_ocsp_status(self, domain, timeout=10, ca_file=None):
            try_until = time.time() + timeout
            while True:
                if time.time() >= try_until:
                    break
                stat = self.get_ocsp_status(domain, ca_file=ca_file)
                if 'ocsp' in stat and stat['ocsp'] != "no response sent":
                    return stat
                time.sleep(0.1)
            raise TimeoutError(f"ocsp respopnse not available: {domain}")
    
        def create_self_signed_cert(self, spec: CertificateSpec,
                                    valid_from: timedelta = timedelta(days=-1),
                                    valid_to: timedelta = timedelta(days=89),
                                    serial: Optional[int] = None) -> Credentials:
            key_type = spec.key_type if spec.key_type else 'rsa4096'
            return HttpdTestCA.create_credentials(spec=spec, issuer=None,
                                                  key_type=key_type,
                                                  valid_from=valid_from,
                                                  valid_to=valid_to,
                                                  serial=serial)
    �����������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_100_reg_add.py����������������������������������������������������0000664�0001751�0001751�00000012732�14240433464�021240� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md acme terms-of-service handling
    
    import pytest
    
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestRegAdd:
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env):
            env.purge_store()
    
        # test case: add a single dns managed domain
        def test_md_100_000(self, env):
            dns = "greenbytes.de"
            jout1 = env.a2md(["add", dns]).json
            env.check_json_contains(jout1['output'][0], {
                "name": dns,
                "domains": [dns],
                "contacts": [],
                "ca": {
                    "urls": [env.acme_url],
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
            assert env.a2md(["list"]).json == jout1
    
        # test case: add > 1 dns managed domain
        def test_md_100_001(self, env):
            dns = ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            jout1 = env.a2md(["add"] + dns).json
            env.check_json_contains(jout1['output'][0], {
                "name": dns[0],
                "domains": dns,
                "contacts": [],
                "ca": {
                    "urls": [env.acme_url],
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
            assert env.a2md(["list"]).json == jout1
    
        # test case: add second managed domain
        def test_md_100_002(self, env):
            dns1 = ["test100-002.com", "test100-002a.com", "test100-002b.com"]
            env.a2md(["add"] + dns1)
            # add second managed domain
            dns2 = ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            jout = env.a2md(["add"] + dns2).json
            # assert: output covers only changed md
            assert len(jout['output']) == 1
            env.check_json_contains(jout['output'][0], {
                "name": dns2[0],
                "domains": dns2,
                "contacts": [],
                "ca": {
                    "urls": [env.acme_url],
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
            assert len(env.a2md(["list"]).json['output']) == 2
    
        # test case: add existing domain 
        def test_md_100_003(self, env):
            dns = "greenbytes.de"
            assert env.a2md(["add", dns]).exit_code == 0
            assert env.a2md(["add", dns]).exit_code == 1
    
        # test case: add without CA URL
        def test_md_100_004(self, env):
            dns = "greenbytes.de"
            jout1 = env.run([env.a2md_bin, "-d", env.store_dir, "-j", "add", dns]).json
            assert len(jout1['output']) == 1
            env.check_json_contains(jout1['output'][0], {
                "name": dns,
                "domains": [dns],
                "contacts": [],
                "ca": {
                    "proto": "ACME"
                },
                "state": env.MD_S_INCOMPLETE
            })
            assert env.a2md(["list"]).json == jout1
    
        # test case: add with invalid DNS
        @pytest.mark.parametrize("invalid_dns", [
            "tld", "white sp.ace", "invalid.*.wildcard.com", "k\xc3ller.idn.com"
        ])
        def test_md_100_005(self, env, invalid_dns):
            assert env.a2md(["add", invalid_dns]).exit_code == 1
            assert env.a2md(["add", "test-100.de", invalid_dns]).exit_code == 1
    
        # test case: add with invalid ACME URL
        @pytest.mark.parametrize("invalid_url", [
            "no.schema/path", "http://white space/path", "http://bad.port:-1/path"])
        def test_md_100_006(self, env, invalid_url):
            args = [env.a2md_bin, "-a", invalid_url, "-d", env.store_dir, "-j"]
            dns = "greenbytes.de"
            args.extend(["add", dns])
            assert env.run(args).exit_code == 1
    
        # test case: add overlapping dns names
        def test_md_100_007(self, env):
            assert env.a2md(["add", "test-100.com", "test-101.com"]).exit_code == 0
            # 1: alternate DNS exists as primary name
            assert env.a2md(["add", "greenbytes2.de", "test-100.com"]).exit_code == 1
            # 2: alternate DNS exists as alternate DNS
            assert env.a2md(["add", "greenbytes2.de", "test-101.com"]).exit_code == 1
            # 3: primary name exists as alternate DNS
            assert env.a2md(["add", "test-101.com"]).exit_code == 1
    
        # test case: add subdomains as separate managed domain
        def test_md_100_008(self, env):
            assert env.a2md(["add", "test-100.com"]).exit_code == 0
            assert env.a2md(["add", "sub.test-100.com"]).exit_code == 0
    
        # test case: add duplicate domain
        def test_md_100_009(self, env):
            dns1 = "test-100.com"
            dns2 = "test-101.com"
            jout = env.a2md(["add", dns1, dns2, dns1, dns2]).json
            # DNS is only listed once
            assert len(jout['output']) == 1
            md = jout['output'][0]
            assert md['domains'] == [dns1, dns2]
    
        # test case: add pnuycode name
        def test_md_100_010(self, env):
            assert env.a2md(["add", "xn--kller-jua.punycode.de"]).exit_code == 0
    
        # test case: don't sort alternate names
        def test_md_100_011(self, env):
            dns = ["test-100.com", "test-xxx.com", "test-aaa.com"]
            jout = env.a2md(["add"] + dns).json
            # DNS is only listed as specified
            assert len(jout['output']) == 1
            md = jout['output'][0]
            assert md['domains'] == dns
    
        # test case: add DNS wildcard
        @pytest.mark.parametrize("wild_dns", [
            "*.wildcard.com"
        ])
        def test_md_100_012(self, env, wild_dns):
            assert env.a2md(["add", wild_dns]).exit_code == 0
    ��������������������������������������httpd-2.4.64/test/modules/md/test_001_store.py������������������������������������������������������0000664�0001751�0001751�00000017243�14240433464�021011� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md acme terms-of-service handling
    
    import re
    
    import pytest
    
    from .md_env import MDTestEnv
    
    
    def md_name(md):
        return md['name']
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    class TestStore:
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env):
            env.purge_store()
     
        # verify expected binary version
        def test_md_001_001(self, env: MDTestEnv):
            r = env.run([env.a2md_bin, "-V"])
            m = re.match(r'version: (\d+\.\d+\.\d+)(-git)?$', r.stdout)
            assert m, f"expected version info in '{r.stdout}'"
    
        # verify that store is clean
        def test_md_001_002(self, env: MDTestEnv):
            r = env.run(["find", env.store_dir])
            assert re.match(env.store_dir, r.stdout)
    
        # test case: add a single dns managed domain
        def test_md_001_100(self, env: MDTestEnv):
            dns = "greenbytes.de"
            env.check_json_contains(
                env.a2md(["store", "add", dns]).json['output'][0],
                {
                    "name": dns,
                    "domains": [dns],
                    "contacts": [],
                    "ca": {
                        "urls": [env.acme_url],
                        "proto": "ACME"
                    },
                    "state": 0
                })
    
        # test case: add > 1 dns managed domain
        def test_md_001_101(self, env: MDTestEnv):
            dns = ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            env.check_json_contains(
                env.a2md(["store", "add"] + dns).json['output'][0],
                {
                    "name": dns[0],
                    "domains": dns,
                    "contacts": [],
                    "ca": {
                        "urls": [env.acme_url],
                        "proto": "ACME"
                    },
                    "state": 0
                })
    
        # test case: add second managed domain
        def test_md_001_102(self, env: MDTestEnv):
            dns1 = ["test000-102.com", "test000-102a.com", "test000-102b.com"]
            assert env.a2md(["store", "add"] + dns1).exit_code == 0
            #
            # add second managed domain
            dns2 = ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            jout = env.a2md(["store", "add"] + dns2).json
            # assert: output covers only changed md
            assert len(jout['output']) == 1
            env.check_json_contains(jout['output'][0], {
                "name": dns2[0],
                "domains": dns2,
                "contacts": [],
                "ca": {
                    "urls": [env.acme_url],
                    "proto": "ACME"
                },
                "state": 0
            })
    
        # test case: add existing domain 
        def test_md_001_103(self, env: MDTestEnv):
            dns = "greenbytes.de"
            assert env.a2md(["store", "add", dns]).exit_code == 0
            # add same domain again
            assert env.a2md(["store", "add", dns]).exit_code == 1
    
        # test case: add without CA URL
        def test_md_001_104(self, env: MDTestEnv):
            dns = "greenbytes.de"
            args = [env.a2md_bin, "-d", env.store_dir, "-j", "store", "add", dns]
            jout = env.run(args).json
            assert len(jout['output']) == 1
            env.check_json_contains(jout['output'][0], {
                "name": dns,
                "domains": [dns],
                "contacts": [],
                "ca": {
                    "proto": "ACME"
                },
                "state": 0
            })
    
        # test case: list empty store
        def test_md_001_200(self, env: MDTestEnv):
            assert env.a2md(["store", "list"]).json == env.EMPTY_JOUT
    
        # test case: list two managed domains
        def test_md_001_201(self, env: MDTestEnv):
            domains = [ 
                ["test000-201.com", "test000-201a.com", "test000-201b.com"],
                ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            ]
            for dns in domains:
                assert env.a2md(["store", "add"] + dns).exit_code == 0
            #
            # list all store content
            jout = env.a2md(["store", "list"]).json
            assert len(jout['output']) == len(domains)
            domains.reverse()
            jout['output'] = sorted(jout['output'], key=md_name)
            for i in range(0, len(jout['output'])):
                env.check_json_contains(jout['output'][i], {
                    "name": domains[i][0],
                    "domains": domains[i],
                    "contacts": [],
                    "ca": {
                        "urls": [env.acme_url],
                        "proto": "ACME"
                    },
                    "state": 0
                })
    
        # test case: remove managed domain
        def test_md_001_300(self, env: MDTestEnv):
            dns = "test000-300.com"
            assert env.a2md(["store", "add", dns]).exit_code == 0
            assert env.a2md(["store", "remove", dns]).json == env.EMPTY_JOUT
            assert env.a2md(["store", "list"]).json == env.EMPTY_JOUT
    
        # test case: remove from list of managed domains 
        def test_md_001_301(self, env: MDTestEnv):
            dns1 = ["test000-301.com", "test000-301a.com", "test000-301b.com"]
            assert env.a2md(["store", "add"] + dns1).exit_code == 0
            #
            dns2 = ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            jout1 = env.a2md(["store", "add"] + dns2).json
            # remove managed domain
            assert env.a2md(["store", "remove", "test000-301.com"]).json == env.EMPTY_JOUT
            # list store content
            assert env.a2md(["store", "list"]).json == jout1
    
        # test case: remove nonexisting managed domain
        def test_md_001_302(self, env: MDTestEnv):
            dns1 = "test000-302.com"
            r = env.a2md(["store", "remove", dns1])
            assert r.exit_code == 1
            assert r.json == {
                'status': 2, 'description': 'No such file or directory', 'output': []
            }
    
        # test case: force remove nonexisting managed domain
        def test_md_001_303(self, env: MDTestEnv):
            dns1 = "test000-303.com"
            assert env.a2md(["store", "remove", "-f", dns1]).json == env.EMPTY_JOUT
    
        # test case: null change
        def test_md_001_400(self, env: MDTestEnv):
            dns = "test000-400.com"
            r1 = env.a2md(["store", "add", dns])
            assert env.a2md(["store", "update", dns]).json == r1.json
    
        # test case: add dns to managed domain
        def test_md_001_401(self, env: MDTestEnv):
            dns1 = "test000-401.com"
            env.a2md(["store", "add", dns1])
            dns2 = "test-101.com"
            args = ["store", "update", dns1, "domains", dns1, dns2]
            assert env.a2md(args).json['output'][0]['domains'] == [dns1, dns2]
    
        # test case: change CA URL
        def test_md_001_402(self, env: MDTestEnv):
            dns = "test000-402.com"
            args = ["store", "add", dns]
            assert env.a2md(args).json['output'][0]['ca']['urls'][0] == env.acme_url
            nurl = "https://foo.com/"
            args = [env.a2md_bin, "-a", nurl, "-d", env.store_dir, "-j", "store", "update", dns]
            assert env.run(args).json['output'][0]['ca']['urls'][0] == nurl
    
        # test case: update nonexisting managed domain
        def test_md_001_403(self, env: MDTestEnv):
            dns = "test000-403.com"
            assert env.a2md(["store", "update", dns]).exit_code == 1
    
        # test case: update domains, throw away md name
        def test_md_001_404(self, env: MDTestEnv):
            dns1 = "test000-404.com"
            dns2 = "greenbytes.com"
            args = ["store", "add", dns1]
            assert env.a2md(args).json['output'][0]['domains'] == [dns1]
            # override domains list
            args = ["store", "update", dns1, "domains", dns2]
            assert env.a2md(args).json['output'][0]['domains'] == [dns2]
    
        # test case: update domains with empty dns list
        def test_md_001_405(self, env: MDTestEnv):
            dns1 = "test000-405.com"
            assert env.a2md(["store", "add", dns1]).exit_code == 0
            assert env.a2md(["store", "update", dns1, "domains"]).exit_code == 1
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/__init__.py������������������������������������������������������������0000664�0001751�0001751�00000000000�14156100407�017746� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/dns01.py���������������������������������������������������������������0000775�0001751�0001751�00000003422�14156100407�017152� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import subprocess
    import sys
    
    curl = "curl"
    challtestsrv = "localhost:8055"
    
    
    def run(args):
        sys.stderr.write(f"run: {' '.join(args)}\n")
        p = subprocess.Popen(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output, errput = p.communicate(None)
        rv = p.wait()
        if rv != 0:
            sys.stderr.write(errput.decode())
        sys.stdout.write(output.decode())
        return rv
    
    
    def teardown(domain):
        rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}"}}',
                  f'{challtestsrv}/clear-txt'])
        if rv == 0:
            rv = run([curl, '-s', '-d', f'{{"host":"{domain}"}}',
                      f'{challtestsrv}/set-txt'])
        return rv
    
    
    def setup(domain, challenge):
        teardown(domain)
        rv = run([curl, '-s', '-d', f'{{"host":"{domain}", "addresses":["127.0.0.1"]}}',
                  f'{challtestsrv}/set-txt'])
        if rv == 0:
            rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}.", "value":"{challenge}"}}',
                      f'{challtestsrv}/set-txt'])
        return rv
    
    
    def main(argv):
        if len(argv) > 1:
            if argv[1] == 'setup':
                if len(argv) != 4:
                    sys.stderr.write("wrong number of arguments: dns01.py setup <domain> <challenge>\n")
                    sys.exit(2)
                rv = setup(argv[2], argv[3])
            elif argv[1] == 'teardown':
                if len(argv) != 3:
                    sys.stderr.write("wrong number of arguments: dns01.py teardown <domain>\n")
                    sys.exit(1)
                rv = teardown(argv[2])
            else:
                sys.stderr.write(f"unknown option {argv[1]}\n")
                rv = 2
        else:
            sys.stderr.write("dns01.py wrong number of arguments\n")
            rv = 2
        sys.exit(rv)
        
    
    if __name__ == "__main__":
        main(sys.argv)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_010_store_migrate.py����������������������������������������������0000664�0001751�0001751�00000003203�14750656217�022521� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md acme terms-of-service handling
    
    import os
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    class TestStoreMigrate:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # install old store, start a2md list, check files afterwards
        def test_md_010_000(self, env):
            domain = "7007-1502285564.org"
            env.replace_store(os.path.join(env.test_dir, "../modules/md/data/store_migrate/1.0/sample1"))
            #
            # use 1.0 file name for private key
            fpkey_1_0 = os.path.join(env.store_dir, 'domains', domain, 'pkey.pem')
            fpkey_1_1 = os.path.join(env.store_dir, 'domains', domain, 'privkey.pem')
            cert_1_0 = os.path.join(env.store_dir, 'domains', domain, 'cert.pem')
            cert_1_1 = os.path.join(env.store_dir, 'domains', domain, 'pubcert.pem')
            chain_1_0 = os.path.join(env.store_dir, 'domains', domain, 'chain.pem')
            #
            assert os.path.exists(fpkey_1_0)
            assert os.path.exists(cert_1_0)
            assert os.path.exists(chain_1_0)
            assert not os.path.exists(fpkey_1_1)
            assert not os.path.exists(cert_1_1)
            #
            md = env.a2md(["-vvv", "list", domain]).json['output'][0]
            assert domain == md["name"]
            #
            assert not os.path.exists(fpkey_1_0)
            assert os.path.exists(cert_1_0)
            assert os.path.exists(chain_1_0)
            assert os.path.exists(fpkey_1_1)
            assert os.path.exists(cert_1_1)
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_502_acmev2_drive.py�����������������������������������������������0000664�0001751�0001751�00000060341�14750656217�022237� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test driving the ACMEv2 protocol
    
    import base64
    import json
    import os.path
    import re
    from datetime import timedelta
    
    import pytest
    from pyhttpd.certs import CertificateSpec
    
    from .md_conf import MDConf
    from .md_cert_util import MDCertUtil
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestDrivev2:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
            env.APACHE_CONF_SRC = "data/test_drive"
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            MDConf(env).install()
            self.test_domain = env.get_request_domain(request)
    
        # --------- invalid precondition ---------
    
        def test_md_502_000(self, env):
            # test case: md without contact info
            domain = self.test_domain
            name = "www." + domain
            assert env.a2md(["add", name]).exit_code == 0
            r = env.a2md(["drive", name])
            assert r.exit_code == 1
            assert re.search("No contact information", r.stderr)
    
        def test_md_502_001(self, env):
            # test case: md with contact, but without TOS
            domain = self.test_domain
            name = "www." + domain
            assert env.a2md(["add", name]).exit_code == 0
            assert env.a2md( 
                ["update", name, "contacts", "admin@test1.not-forbidden.org"]
                ).exit_code == 0
            r = env.a2md(["drive", name])
            assert r.exit_code == 1
            assert re.search("the CA requires you to accept the terms-of-service as specified in ", r.stderr)
    
        # test_102 removed, was based on false assumption
        def test_md_502_003(self, env):
            # test case: md with unknown protocol FOO
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            assert env.a2md(
                ["update", name, "ca", env.acme_url, "FOO"]
                ).exit_code == 0
            r = env.a2md(["drive", name])
            assert r.exit_code == 1
            assert re.search("Unknown CA protocol", r.stderr)
    
        # --------- driving OK ---------
    
        def test_md_502_100(self, env):
            # test case: md with one domain
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # drive
            prev_md = env.a2md(["list", name]).json['output'][0]
            r = env.a2md(["-vv", "drive", "-c", "http-01", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            env.check_md_credentials([name])
            self._check_account_key(env, name)
    
            # check archive content
            store_md = json.loads(open(env.store_archived_file(name, 1, 'md.json')).read())
            for f in ['name', 'ca', 'domains', 'contacts', 'renew-mode', 'renew-window', 'must-staple']:
                assert store_md[f] == prev_md[f]
            
            # check file system permissions:
            env.check_file_permissions(name)
            # check: challenges removed
            env.check_dir_empty(env.store_challenges())
            # check how the challenge resources are answered in sevceral combinations 
            r = env.get_meta(domain, "/.well-known/acme-challenge", False)
            assert r.exit_code == 0
            assert r.response['status'] == 404
            r = env.get_meta(domain, "/.well-known/acme-challenge/", False)
            assert r.exit_code == 0
            assert r.response['status'] == 404
            r = env.get_meta(domain, "/.well-known/acme-challenge/123", False)
            assert r.exit_code == 0
            assert r.response['status'] == 404
            assert r.exit_code == 0
            cdir = os.path.join(env.store_challenges(), domain)
            os.makedirs(cdir)
            open(os.path.join(cdir, 'acme-http-01.txt'), "w").write("content-of-123")
            r = env.get_meta(domain, "/.well-known/acme-challenge/123", False)
            assert r.exit_code == 0
            assert r.response['status'] == 200
            assert r.response['header']['content-length'] == '14'
    
        def test_md_502_101(self, env):
            # test case: md with 2 domains
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name, "test." + domain])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # drive
            r = env.a2md(["-vv", "drive", "-c", "http-01", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            env.check_md_credentials([name, "test." + domain])
    
        # test_502_102 removed, as accounts without ToS are not allowed in ACMEv2
    
        def test_md_502_103(self, env):
            # test case: md with one domain, ACME account and TOS agreement on server
            # setup: create md
            domain = self.test_domain
            name = "www." + domain
            assert env.a2md(["add", name]).exit_code == 0
            assert env.a2md(["update", name, "contacts", "admin@" + domain]).exit_code == 0
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: create account on server
            r = env.a2md(["-t", "accepted", "acme", "newreg", "admin@" + domain], raw=True)
            assert r.exit_code == 0
            acct = re.match("registered: (.*)$", r.stdout).group(1)
            # setup: link md to account
            assert env.a2md(["update", name, "account", acct]).exit_code == 0
            # drive
            r = env.a2md(["-vv", "drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            env.check_md_credentials([name])
    
        # test_502_104 removed, order are created differently in ACMEv2
    
        def test_md_502_105(self, env):
            # test case: md with one domain, local TOS agreement and ACME account that is deleted (!) on server
            # setup: create md
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: create account on server
            r = env.a2md(["-t", "accepted", "acme", "newreg", "test@" + domain], raw=True)
            assert r.exit_code == 0
            acct = re.match("registered: (.*)$", r.stdout).group(1)
            # setup: link md to account
            assert env.a2md(["update", name, "account", acct]).exit_code == 0
            # setup: delete account on server
            assert env.a2md(["acme", "delreg", acct]).exit_code == 0
            # drive
            r = env.a2md(["drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            env.check_md_credentials([name])
    
        def test_md_502_107(self, env):
            # test case: drive again on COMPLETE md, then drive --force
            # setup: prepare md in store
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # drive
            r = env.a2md(["-vv", "drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            env.check_md_credentials([name])
            orig_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
    
            # drive again
            assert env.a2md(["-vv", "drive", name]).exit_code == 0
            env.check_md_credentials([name])
            cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            # check: cert not changed
            assert cert.same_serial_as(orig_cert)
    
            # drive --force
            assert env.a2md(["-vv", "drive", "--force", name]).exit_code == 0
            env.check_md_credentials([name])
            cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            # check: cert not changed
            assert not cert.same_serial_as(orig_cert)
            # check: previous cert was archived
            cert = MDCertUtil(env.store_archived_file(name, 2, 'pubcert.pem'))
            assert cert.same_serial_as(orig_cert)
    
        def test_md_502_108(self, env):
            # test case: drive via HTTP proxy
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            conf = MDConf(env, proxy=True)
            conf.add('LogLevel proxy:trace8')
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
            # drive it, with wrong proxy url -> FAIL
            r = env.a2md(["-p", "http://localhost:1", "drive", name])
            assert r.exit_code == 1
            assert "Connection refused" in r.stderr
    
            # drive it, working proxy url -> SUCCESS
            proxy_url = f"http://localhost:{env.proxy_port}"
            r = env.a2md(["-vv", "-p", proxy_url, "drive", name])
            assert 0 == r.exit_code, "a2md failed: {0}".format(r.stderr)
            env.check_md_credentials([name])
    
        def test_md_502_109(self, env):
            # test case: redirect on SSL-only domain
            # setup: prepare config
            domain = self.test_domain
            name = "www." + domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md([name])
            conf.add_vhost(name, port=env.http_port, doc_root="htdocs/test")
            conf.add_vhost(name, doc_root="htdocs/test")
            conf.install()
            # setup: create resource files
            self._write_res_file(os.path.join(env.server_docs_dir, "test"), "name.txt", name)
            self._write_res_file(os.path.join(env.server_docs_dir), "name.txt", "not-forbidden.org")
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
            # drive it
            assert env.a2md(["drive", name]).exit_code == 0
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # test HTTP access - no redirect
            jdata = env.get_json_content(f"test1.{env.http_tld}", "/alive.json", use_https=False)
            assert jdata['host']== "test1"
            assert env.get_content(name, "/name.txt", use_https=False) == name
            r = env.get_meta(name, "/name.txt", use_https=False)
            assert int(r.response['header']['content-length']) == len(name)
            assert "Location" not in r.response['header']
            # test HTTPS access
            assert env.get_content(name, "/name.txt", use_https=True) == name
    
            # test HTTP access again -> redirect to default HTTPS port
            conf.add("MDRequireHttps temporary")
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            r = env.get_meta(name, "/name.txt", use_https=False)
            assert r.response['status'] == 302
            exp_location = "https://%s/name.txt" % name
            assert r.response['header']['location'] == exp_location
            # should not see this
            assert 'strict-transport-security' not in r.response['header']
            # test default HTTP vhost -> still no redirect
            jdata = env.get_json_content(f"test1.{env.http_tld}", "/alive.json", use_https=False)
            assert jdata['host']== "test1"
            r = env.get_meta(name, "/name.txt", use_https=True)
            # also not for this
            assert 'strict-transport-security' not in r.response['header']
    
            # test HTTP access again -> redirect permanent
            conf.add("MDRequireHttps permanent")
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            r = env.get_meta(name, "/name.txt", use_https=False)
            assert r.response['status'] == 301
            exp_location = "https://%s/name.txt" % name
            assert r.response['header']['location'] == exp_location
            assert 'strict-transport-security' not in r.response['header']
            # should see this
            r = env.get_meta(name, "/name.txt", use_https=True)
            assert r.response['header']['strict-transport-security'] == 'max-age=15768000'
    
        def test_md_502_110(self, env):
            # test case: SSL-only domain, override headers generated by mod_md 
            # setup: prepare config
            domain = self.test_domain
            name = "www." + domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add("MDRequireHttps permanent")
            conf.add_md([name])
            conf.add_vhost(name, port=env.http_port)
            conf.add_vhost(name)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # drive it
            assert env.a2md(["drive", name]).exit_code == 0
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
            # test override HSTS header
            conf.add('Header set Strict-Transport-Security "max-age=10886400; includeSubDomains; preload"')
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            r = env.get_meta(name, "/name.txt", use_https=True)
            assert 'strict-transport-security' in r.response['header'], r.response['header']
            assert r.response['header']['strict-transport-security'] == \
                   'max-age=10886400; includeSubDomains; preload'
    
            # test override Location header
            conf.add('  Redirect /a /name.txt')
            conf.add('  Redirect seeother /b /name.txt')
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: default redirect by mod_md still works
            exp_location = "https://%s/name.txt" % name
            r = env.get_meta(name, "/name.txt", use_https=False)
            assert r.response['status'] == 301
            assert r.response['header']['location'] == exp_location
            # check: redirect as given by mod_alias
            exp_location = "https://%s/a" % name
            r = env.get_meta(name, "/a", use_https=False)
            assert r.response['status'] == 301    # FAIL: mod_alias generates Location header instead of mod_md
            assert r.response['header']['location'] == exp_location
    
        def test_md_502_111(self, env):
            # test case: vhost with parallel HTTP/HTTPS, check mod_alias redirects
            # setup: prepare config
            domain = self.test_domain
            name = "www." + domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md([name])
            conf.add("  LogLevel alias:debug")
            conf.add_vhost(name, port=env.http_port)
            conf.add_vhost(name)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # drive it
            r = env.a2md(["-v", "drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
            # setup: place redirect rules
            conf.add('  Redirect /a /name.txt')
            conf.add('  Redirect seeother /b /name.txt')
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # check: redirects on HTTP
            exp_location = "http://%s:%s/name.txt" % (name, env.http_port)
            r = env.get_meta(name, "/a", use_https=False)
            assert r.response['status'] == 302
            assert r.response['header']['location'] == exp_location
            r = env.get_meta(name, "/b", use_https=False)
            assert r.response['status'] == 303
            assert r.response['header']['location'] == exp_location
            # check: redirects on HTTPS
            exp_location = "https://%s:%s/name.txt" % (name, env.https_port)
            r = env.get_meta(name, "/a", use_https=True)
            assert r.response['status'] == 302
            assert r.response['header']['location'] == exp_location     # FAIL: expected 'https://...' but found 'http://...'
            r = env.get_meta(name, "/b", use_https=True)
            assert r.response['status'] == 303
            assert r.response['header']['location'] == exp_location
    
        def test_md_502_120(self, env):
            # test case: NP dereference reported by Daniel Caminada <daniel.caminada@ergon.ch>
            domain = self.test_domain
            name = "www." + domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_md([name])
            conf.add_vhost(name)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.run(["openssl", "s_client",
                     f"-connect", "localhost:{env.https_port}",
                     "-servername", "example.com", "-crlf"
                     ], intext="GET https:// HTTP/1.1\nHost: example.com\n\n")
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        # --------- critical state change -> drive again ---------
    
        def test_md_502_200(self, env):
            # test case: add dns name on existing valid md
            # setup: create md in store
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: drive it
            r = env.a2md(["drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            old_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            # setup: add second domain
            assert env.a2md(["update", name, "domains", name, "test." + domain]).exit_code == 0
            # drive
            r = env.a2md(["-vv", "drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            # check new cert
            env.check_md_credentials([name, "test." + domain])
            new_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            assert not old_cert.same_serial_as(new_cert.get_serial)
    
        @pytest.mark.parametrize("renew_window,test_data_list", [
            ("14d", [
                {"valid": {"notBefore": -5,   "notAfter": 180}, "renew": False},
                {"valid": {"notBefore": -200, "notAfter": 15}, "renew": False},
                {"valid": {"notBefore": -200, "notAfter": 13}, "renew": True},
            ]),
            ("30%", [
                {"valid": {"notBefore": -0,   "notAfter": 180}, "renew": False},
                {"valid": {"notBefore": -120, "notAfter": 60}, "renew": False},
                {"valid": {"notBefore": -126, "notAfter": 53}, "renew": True},
            ])
        ])
        def test_md_502_201(self, env, renew_window, test_data_list):
            # test case: trigger cert renew when entering renew window 
            # setup: prepare COMPLETE md
            domain = self.test_domain
            name = "www." + domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_renew_window(renew_window)
            conf.add_md([name])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_INCOMPLETE
            # setup: drive it
            r = env.a2md(["drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            cert1 = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_COMPLETE
    
            # replace cert by self-signed one -> check md status
            print("TRACE: start testing renew window: %s" % renew_window)
            for tc in test_data_list:
                print("TRACE: create self-signed cert: %s" % tc["valid"])
                creds = env.create_self_signed_cert(CertificateSpec(domains=[name]),
                                                    valid_from=timedelta(days=tc["valid"]["notBefore"]),
                                                    valid_to=timedelta(days=tc["valid"]["notAfter"]))
                assert creds.certificate.serial_number != cert1.get_serial_number()
                # copy it over, assess status again
                creds.save_cert_pem(env.store_domain_file(name, 'pubcert.pem'))
                md = env.a2md(["list", name]).json['output'][0]
                assert md["renew"] == tc["renew"], \
                    "Expected renew == {} indicator in {}, test case {}".format(tc["renew"], md, tc)
    
        @pytest.mark.parametrize("key_type,key_params,exp_key_length", [
            ("RSA", [2048], 2048),
            ("RSA", [3072], 3072),
            ("RSA", [4096], 4096),
            ("Default", [], 2048)
        ])
        def test_md_502_202(self, env, key_type, key_params, exp_key_length):
            # test case: specify RSA key length and verify resulting cert key 
            # setup: prepare md
            domain = self.test_domain
            name = "www." + domain
            conf = MDConf(env, admin="admin@" + domain)
            conf.add_drive_mode("manual")
            conf.add_private_key(key_type, key_params)
            conf.add_md([name])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_INCOMPLETE
            # setup: drive it
            r = env.a2md(["-vv", "drive", name])
            assert r.exit_code == 0, "drive for MDPrivateKeys {} {}: {}".format(key_type, key_params, r.stderr)
            assert env.a2md(["list", name]).json['output'][0]['state'] == env.MD_S_COMPLETE
            # check cert key length
            cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            assert cert.get_key_length() == exp_key_length
    
        # test_502_203 removed, as ToS agreement is not really checked in ACMEv2
    
        # --------- non-critical state change -> keep data ---------
    
        def test_md_502_300(self, env):
            # test case: remove one domain name from existing valid md
            # setup: create md in store
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name, "test." + domain, "xxx." + domain])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: drive it
            r = env.a2md(["drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            old_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            # setup: remove one domain
            assert env.a2md(["update", name, "domains"] + [name, "test." + domain]).exit_code == 0
            # drive
            assert env.a2md(["-vv", "drive", name]).exit_code == 0
            # compare cert serial
            new_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            assert old_cert.same_serial_as(new_cert)
    
        def test_md_502_301(self, env):
            # test case: change contact info on existing valid md
            # setup: create md in store
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # setup: drive it
            r = env.a2md(["drive", name])
            assert r.exit_code == 0, "a2md drive failed: {0}".format(r.stderr)
            old_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            # setup: add second domain
            assert env.a2md(["update", name, "contacts", "test@" + domain]).exit_code == 0
            # drive
            assert env.a2md(["drive", name]).exit_code == 0
            # compare cert serial
            new_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
            assert old_cert.same_serial_as(new_cert)
    
        # --------- network problems ---------
    
        def test_md_502_400(self, env):
            # test case: server not reachable
            domain = self.test_domain
            name = "www." + domain
            self._prepare_md(env, [name])
            assert env.a2md(
                ["update", name, "ca", "http://localhost:4711/directory"]
                ).exit_code == 0
            # drive
            r = env.a2md(["drive", name])
            assert r.exit_code == 1
            assert r.json['status'] != 0
            assert r.json['description'] == 'Connection refused'
    
        # --------- _utils_ ---------
    
        def _prepare_md(self, env, domains):
            assert env.a2md(["add"] + domains).exit_code == 0
            assert env.a2md(
                ["update", domains[0], "contacts", "admin@" + domains[0]]
                ).exit_code == 0
            assert env.a2md( 
                ["update", domains[0], "agreement", env.acme_tos]
                ).exit_code == 0
    
        def _write_res_file(self, doc_root, name, content):
            if not os.path.exists(doc_root):
                os.makedirs(doc_root)
            open(os.path.join(doc_root, name), "w").write(content)
    
        RE_MSG_OPENSSL_BAD_DECRYPT = re.compile('.*\'bad decrypt\'.*')
    
        def _check_account_key(self, env, name):
            # read encryption key
            md_store = json.loads(open(env.path_store_json(), 'r').read())
            encrypt_key = base64.urlsafe_b64decode(str(md_store['key']))
            # check: key file is encrypted PEM
            md = env.a2md(["list", name]).json['output'][0]
            acc = md['ca']['account']
            MDCertUtil.validate_privkey(env.path_account_key(acc), lambda *args: encrypt_key)
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_720_wildcard.py���������������������������������������������������0000664�0001751�0001751�00000023602�14750656217�021463� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test wildcard certifcates
    import os
    
    import pytest
    
    from .md_conf import MDConf, MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestWildcard:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        # test case: a wildcard certificate with ACMEv2, no dns-01 supported
        def test_md_720_001(self, env):
            domain = self.test_domain
            
            # generate config with DNS wildcard
            domains = [domain, "*." + domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'challenge-mismatch'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # None of offered challenge types
                ],
                matches = [
                    r'.*problem\[challenge-mismatch\].*'
                ]
            )
    
        # test case: a wildcard certificate with ACMEv2, only dns-01 configured, invalid command path
        def test_md_720_002(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01-not-found.py")
    
            domain = self.test_domain
            domains = [domain, "*." + domain]
            
            conf = MDConf(env)
            conf.add("MDCAChallenges dns-01")
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'challenge-setup-failure'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # None of offered challenge types
                ],
                matches = [
                    r'.*problem\[challenge-setup-failure\].*',
                    r'.*setup command failed to execute.*'
                ]
            )
    
        # variation, invalid cmd path, other challenges still get certificate for non-wildcard
        def test_md_720_002b(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01-not-found.py")
            domain = self.test_domain
            domains = [domain, "xxx." + domain]
            
            conf = MDConf(env)
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            # check: SSL is running OK
            cert_a = env.get_cert(domain)
            altnames = cert_a.get_san_list()
            for domain in domains:
                assert domain in altnames
    
        # test case: a wildcard certificate with ACMEv2, only dns-01 configured, invalid command option
        def test_md_720_003(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01.py fail")
            domain = self.test_domain
            domains = [domain, "*." + domain]
            
            conf = MDConf(env)
            conf.add("MDCAChallenges dns-01")
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            md = env.await_error(domain)
            assert md
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'challenge-setup-failure'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # None of offered challenge types
                ],
                matches = [
                    r'.*problem\[challenge-setup-failure\].*'
                ]
            )
    
        # test case: a wildcard name certificate with ACMEv2, only dns-01 configured
        def test_md_720_004(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01.py")
            domain = self.test_domain
            domains = [domain, "*." + domain]
            
            conf = MDConf(env)
            conf.add("MDCAChallenges dns-01")
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            # check: SSL is running OK
            cert_a = env.get_cert(domain)
            altnames = cert_a.get_san_list()
            for domain in domains:
                assert domain in altnames
    
        # test case: a wildcard name and 2nd normal vhost, not overlapping
        def test_md_720_005(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01.py")
            domain = self.test_domain
            domain2 = "www.x" + domain
            domains = [domain, "*." + domain, domain2]
            
            conf = MDConf(env)
            conf.add("MDCAChallenges dns-01")
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(domain2)
            conf.add_vhost(domains)
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            # check: SSL is running OK
            cert_a = env.get_cert(domain)
            altnames = cert_a.get_san_list()
            for domain in domains:
                assert domain in altnames
    
        # test case: a wildcard name and 2nd normal vhost, overlapping
        def test_md_720_006(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01.py")
            domain = self.test_domain
            dwild = "*." + domain
            domain2 = "www." + domain
            domains = [domain, dwild, domain2]
            
            conf = MDConf(env)
            conf.add("MDCAChallenges dns-01")
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(domain2)
            conf.add_vhost([domain, dwild])
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            # check: SSL is running OK
            cert_a = env.get_cert(domain)
            altnames = cert_a.get_san_list()
            for domain in [domain, dwild]:
                assert domain in altnames
    
        # test case: a MDomain with just a wildcard, see #239
        def test_md_720_007(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01.py")
            domain = self.test_domain
            dwild = "*." + domain
            wwwdomain = "www." + domain
            domains = [dwild]
    
            conf = MDConf(env)
            conf.add("MDCAChallenges dns-01")
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(wwwdomain)
            conf.install()
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            assert env.await_completion([wwwdomain])
            env.check_md_complete(dwild)
            # check: SSL is running OK
            cert_a = env.get_cert(wwwdomain)
            altnames = cert_a.get_san_list()
            assert domains == altnames
    
        # test case: a plain name, only dns-01 configured,
        # http-01 should not be intercepted. See #279
        def test_md_720_008(self, env):
            dns01cmd = os.path.join(env.test_dir, "../modules/md/dns01.py")
            domain = self.test_domain
            domains = [domain]
    
            conf = MDConf(env)
            conf.add("MDCAChallenges dns-01")
            conf.add(f"MDChallengeDns01 {dns01cmd}")
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.add("LogLevel http:trace4")
            conf.install()
    
            challengedir = os.path.join(env.server_dir, "htdocs/test1/.well-known/acme-challenge")
            env.mkpath(challengedir)
            content = b'not a challenge'
            with open(os.path.join(challengedir, "123456"), "wb") as fd:
                fd.write(content)
    
            # restart, check that md is in store
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md(domains)
            # await drive completion
            assert env.await_completion([domain], restart=False)
            # access a fake http-01 challenge on the domain
            r = env.curl_get(f"http://{domain}:{env.http_port}/.well-known/acme-challenge/123456")
            assert r.response['status'] == 200
            assert r.response['body'] == content
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            env.check_md_complete(domain)
    ������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_750_eab.py��������������������������������������������������������0000664�0001751�0001751�00000042523�14750656217�020427� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import json.encoder
    import os
    import re
    
    import pytest
    
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_eab(),
                        reason="ACME test server does not support External Account Binding")
    class TestEab:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='eab')
            env.check_acme()
            env.clear_store()
            MDConf(env).install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def test_md_750_001(self, env):
            # md without EAB configured
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:externalAccountRequired'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # ACME server policy requires newAccount requests must include a value for the 'externalAccountBinding' field
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:externalAccountRequired.*'
                ]
            )
    
        def test_md_750_002(self, env):
            # md with known EAB KID and non base64 hmac key configured
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding kid-1 äöüß")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'apache:eab-hmac-invalid'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # external account binding HMAC value is not valid base64
                ],
                matches = [
                    r'.*problem\[apache:eab-hmac-invalid\].*'
                ]
            )
    
        def test_md_750_003(self, env):
            # md with empty EAB KID configured
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding \" \" bm90IGEgdmFsaWQgaG1hYwo=")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] in [
                'urn:ietf:params:acme:error:unauthorized',
                'urn:ietf:params:acme:error:malformed',
            ]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # the field 'kid' references a key that is not known to the ACME server
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:(unauthorized|malformed).*'
                ]
            )
    
        def test_md_750_004(self, env):
            # md with unknown EAB KID configured
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding key-x bm90IGEgdmFsaWQgaG1hYwo=")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] in [
                'urn:ietf:params:acme:error:unauthorized',
                'urn:ietf:params:acme:error:malformed',
            ]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # the field 'kid' references a key that is not known to the ACME server
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:(unauthorized|malformed).*'
                ]
            )
    
        def test_md_750_005(self, env):
            # md with known EAB KID but wrong HMAC configured
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding kid-1 bm90IGEgdmFsaWQgaG1hYwo=")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] in [
                'urn:ietf:params:acme:error:unauthorized',
                'urn:ietf:params:acme:error:malformed',
            ]
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # external account binding JWS verification error: square/go-jose: error in cryptographic primitive
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:(unauthorized|malformed).*'
                ]
            )
    
        def test_md_750_010(self, env):
            # md with correct EAB configured
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            # this is one of the values in conf/pebble-eab.json
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
    
        def test_md_750_011(self, env):
            # first one md with EAB, then one without, works only for the first
            # as the second is unable to reuse the account
            domain_a = f"a{self.test_domain}"
            domain_b = f"b{self.test_domain}"
            conf = MDConf(env)
            conf.start_md([domain_a])
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.end_md()
            conf.add_vhost(domains=[domain_a])
            conf.add_md([domain_b])
            conf.add_vhost(domains=[domain_b])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain_a], restart=False)
            md = env.await_error(domain_b)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:externalAccountRequired'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # ACME server policy requires newAccount requests must include a value for the 'externalAccountBinding' field
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:externalAccountRequired.*'
                ]
            )
    
        def test_md_750_012(self, env):
            # first one md without EAB, then one with
            # first one fails, second works
            domain_a = f"a{self.test_domain}"
            domain_b = f"b{self.test_domain}"
            conf = MDConf(env)
            conf.add_md([domain_a])
            conf.add_vhost(domains=[domain_a])
            conf.start_md([domain_b])
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.end_md()
            conf.add_vhost(domains=[domain_b])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain_b], restart=False)
            md = env.await_error(domain_a)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:externalAccountRequired'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # ACME server policy requires newAccount requests must include a value for the 'externalAccountBinding' field
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:externalAccountRequired.*'
                ]
            )
    
        def test_md_750_013(self, env):
            # 2 mds with the same EAB, should one create a single account
            domain_a = f"a{self.test_domain}"
            domain_b = f"b{self.test_domain}"
            conf = MDConf(env)
            conf.start_md([domain_a])
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.end_md()
            conf.add_vhost(domains=[domain_a])
            conf.start_md([domain_b])
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.end_md()
            conf.add_vhost(domains=[domain_b])
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain_a, domain_b])
            md_a = env.get_md_status(domain_a)
            md_b = env.get_md_status(domain_b)
            assert md_a['ca'] == md_b['ca']
    
        def test_md_750_014(self, env):
            # md with correct EAB, get cert, change to another correct EAB
            # needs to create a new account
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            md_1 = env.get_md_status(domain)
            conf = MDConf(env)
            # this is another one of the values in conf/pebble-eab.json
            # add a dns name to force renewal
            domains = [domain, f'www.{domain}']
            conf.add("MDExternalAccountBinding kid-2 b10lLJs8l1GPIzsLP0s6pMt8O0XVGnfTaCeROxQM0BIt2XrJMDHJZBM5NuQmQJQH")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            md_2 = env.get_md_status(domain)
            assert md_1['ca'] != md_2['ca']
    
        def test_md_750_015(self, env):
            # md with correct EAB, get cert, change to no EAB
            # needs to fail
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            conf = MDConf(env)
            # this is another one of the values in conf/pebble-eab.json
            # add a dns name to force renewal
            domains = [domain, f'www.{domain}']
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:externalAccountRequired'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # ACME server policy requires newAccount requests must include a value for the 'externalAccountBinding' field
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:externalAccountRequired.*'
                ]
            )
    
        def test_md_750_016(self, env):
            # md with correct EAB, get cert, change to invalid EAB
            # needs to fail
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
            conf = MDConf(env)
            # this is another one of the values in conf/pebble-eab.json
            # add a dns name to force renewal
            domains = [domain, f'www.{domain}']
            conf.add("MDExternalAccountBinding kid-invalud blablabalbalbla")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_error(domain)
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:unauthorized'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # the field 'kid' references a key that is not known to the ACME server
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:unauthorized.*'
                ]
            )
    
        def test_md_750_017(self, env):
            # md without EAB explicitly set to none
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding kid-1 zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W")
            conf.start_md(domains)
            conf.add("MDExternalAccountBinding none")
            conf.end_md()
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            md = env.await_error(domain)
            assert md['renewal']['errors'] > 0
            assert md['renewal']['last']['problem'] == 'urn:ietf:params:acme:error:externalAccountRequired'
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # ACME server policy requires newAccount requests must include a value for the 'externalAccountBinding' field
                ],
                matches = [
                    r'.*urn:ietf:params:acme:error:externalAccountRequired.*'
                ]
            )
    
        def test_md_750_018(self, env):
            # md with EAB file that does not exist
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding does-not-exist")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_fail() == 0
            assert re.search(r'.*file not found:', env.apachectl_stderr), env.apachectl_stderr
    
        def test_md_750_019(self, env):
            # md with EAB file that is not valid JSON
            domain = self.test_domain
            domains = [domain]
            eab_file = os.path.join(env.server_dir, 'eab.json')
            with open(eab_file, 'w') as fd:
                fd.write("something not JSON\n")
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding eab.json")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_fail() == 0
            assert re.search(r'.*error reading JSON file.*', env.apachectl_stderr), env.apachectl_stderr
    
        def test_md_750_020(self, env):
            # md with EAB file that is JSON, but missind kid
            domain = self.test_domain
            domains = [domain]
            eab_file = os.path.join(env.server_dir, 'eab.json')
            with open(eab_file, 'w') as fd:
                eab = {'something': 1, 'other': 2}
                fd.write(json.encoder.JSONEncoder().encode(eab))
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding eab.json")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_fail() == 0
            assert re.search(r'.*JSON does not contain \'kid\' element.*', env.apachectl_stderr), env.apachectl_stderr
    
        def test_md_750_021(self, env):
            # md with EAB file that is JSON, but missind hmac
            domain = self.test_domain
            domains = [domain]
            eab_file = os.path.join(env.server_dir, 'eab.json')
            with open(eab_file, 'w') as fd:
                eab = {'kid': 'kid-1', 'other': 2}
                fd.write(json.encoder.JSONEncoder().encode(eab))
            conf = MDConf(env)
            conf.add("MDExternalAccountBinding eab.json")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_fail() == 0
            assert re.search(r'.*JSON does not contain \'hmac\' element.*', env.apachectl_stderr), env.apachectl_stderr
    
        def test_md_750_022(self, env):
            # md with EAB file that has correct values
            domain = self.test_domain
            domains = [domain]
            eab_file = os.path.join(env.server_dir, 'eab.json')
            with open(eab_file, 'w') as fd:
                eab = {'kid': 'kid-1', 'hmac': 'zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W'}
                fd.write(json.encoder.JSONEncoder().encode(eab))
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            # this is one of the values in conf/pebble-eab.json
            conf.add("MDExternalAccountBinding eab.json")
            conf.add_md(domains)
            conf.add_vhost(domains=domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion(domains)
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/message.py�������������������������������������������������������������0000775�0001751�0001751�00000001216�14156100407�017650� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import os
    import sys
    
    
    def main(argv):
        if len(argv) > 2:
            cmd = argv[2]
            if 'renewing' != cmd:
                f1 = open(argv[1], 'a+')
                f1.write(f'{argv}\n')
                if 'MD_VERSION' in os.environ:
                    f1.write(f'MD_VERSION={os.environ["MD_VERSION"]}\n')
                if 'MD_STORE' in os.environ:
                    f1.write(f'MD_STORE={os.environ["MD_STORE"]}\n')
                f1.close()
            sys.stderr.write("done, all fine.\n")
            sys.exit(0)
        else:
            sys.stderr.write(f"{argv[0]} without arguments")
            sys.exit(7)
        
    
    if __name__ == "__main__":
        main(sys.argv)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/md_acme.py�������������������������������������������������������������0000775�0001751�0001751�00000007373�14156100407�017623� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import os
    import shutil
    import subprocess
    import time
    from abc import ABCMeta, abstractmethod
    from datetime import datetime, timedelta
    from threading import Thread
    from typing import Dict
    
    from .md_env import MDTestEnv
    
    
    log = logging.getLogger(__name__)
    
    
    def monitor_proc(env: MDTestEnv, proc):
        _env = env
        proc.wait()
    
    
    class ACMEServer:
        __metaclass__ = ABCMeta
    
        @abstractmethod
        def start(self):
            raise NotImplementedError
    
        @abstractmethod
        def stop(self):
            raise NotImplementedError
    
        @abstractmethod
        def install_ca_bundle(self, dest):
            raise NotImplementedError
    
    
    class MDPebbleRunner(ACMEServer):
    
        def __init__(self, env: MDTestEnv, configs: Dict[str, str]):
            self.env = env
            self.configs = configs
            self._current = 'default'
            self._pebble = None
            self._challtestsrv = None
            self._log = None
    
        def start(self, config: str = None):
            if config is not None and config != self._current:
                # change, tear down and start again
                assert config in self.configs
                self.stop()
                self._current = config
            elif self._pebble is not None:
                # already running
                return
            args = ['pebble', '-config', self.configs[self._current], '-dnsserver', ':8053']
            env = {}
            env.update(os.environ)
            env['PEBBLE_VA_NOSLEEP'] = '1'
            self._log = open(f'{self.env.gen_dir}/pebble.log', 'w')
            self._pebble = subprocess.Popen(args=args, env=env,
                                            stdout=self._log, stderr=self._log)
            t = Thread(target=monitor_proc, args=(self.env, self._pebble))
            t.start()
    
            args = ['pebble-challtestsrv', '-http01', '', '-https01', '', '-tlsalpn01', '']
            self._challtestsrv = subprocess.Popen(args, stdout=self._log, stderr=self._log)
            t = Thread(target=monitor_proc, args=(self.env, self._challtestsrv))
            t.start()
            self.install_ca_bundle(self.env.acme_ca_pemfile)
            # disable ipv6 default address, this gives trouble inside docker
            end = datetime.now() + timedelta(seconds=5)
            while True:
                r = self.env.run(['curl', 'localhost:8055/'])
                if r.exit_code == 0:
                    break
                if datetime.now() > end:
                    raise TimeoutError(f'unable to contact pebble-challtestsrv on localhost:8055')
                time.sleep(.1)
            r = self.env.run(['curl', '-d', f'{{"ip":""}}',
                              'localhost:8055/set-default-ipv6'])
            assert r.exit_code == 0, f"{r}"
    
        def stop(self):
            if self._pebble:
                self._pebble.terminate()
                self._pebble = None
            if self._challtestsrv:
                self._challtestsrv.terminate()
                self._challtestsrv = None
            if self._log:
                self._log.close()
                self._log = None
    
        def install_ca_bundle(self, dest):
            shutil.copyfile(self.env.ca.cert_file, dest)
            end = datetime.now() + timedelta(seconds=20)
            while datetime.now() < end:
                r = self.env.curl_get('https://localhost:15000/roots/0', insecure=True)
                if r.exit_code == 0:
                    with open(dest, 'a') as fd:
                        fd.write(r.stdout)
                    break
    
    
    class MDBoulderRunner(ACMEServer):
    
        def __init__(self, env: MDTestEnv):
            self.env = env
            self.install_ca_bundle(self.env.acme_ca_pemfile)
    
        def start(self, config=None):
            pass
    
        def stop(self):
            pass
    
        def install_ca_bundle(self, dest):
            r = self.env.run([
                'docker', 'exec', 'boulder_boulder_1', 'bash', '-c', "cat /tmp/root*.pem"
            ])
            assert r.exit_code == 0
            with open(dest, 'w') as fd:
                fd.write(r.stdout)
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_790_failover.py���������������������������������������������������0000664�0001751�0001751�00000006557�14750656217�021522� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .md_env import MDTestEnv
    from .md_conf import MDConf
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestFailover:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
            conf = MDConf(env)
            conf.install()
    
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        # set 2 ACME certificata authority, valid + invalid
        def test_md_790_001(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add([
                "MDRetryDelay 200ms",  # speed up failovers
            ])
            conf.start_md(domains)
            conf.add([
                f"MDCertificateAuthority {env.acme_url} https://does-not-exist/dir"
            ])
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            env.check_md_complete(domain)
    
        # set 2 ACME certificata authority, invalid + valid
        def test_md_790_002(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add([
                "MDRetryDelay 100ms",  # speed up failovers
                "MDRetryFailover 2",
            ])
            conf.start_md(domains)
            conf.add([
                f"MDCertificateAuthority https://does-not-exist/dir {env.acme_url} "
            ])
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # Unsuccessful in contacting ACME server
                ],
                matches = [
                    r'.*Unsuccessful in contacting ACME server at .*'
                ]
            )
    
        # set 3 ACME certificata authority, invalid + invalid + valid
        def test_md_790_003(self, env):
            domain = self.test_domain
            # generate config with one MD
            domains = [domain, "www." + domain]
            conf = MDConf(env)
            conf.add([
                "MDRetryDelay 100ms",  # speed up failovers
                "MDRetryFailover 2",
            ])
            conf.start_md(domains)
            conf.add([
                f"MDCertificateAuthority https://does-not-exist/dir https://does-not-either/ "
                f"{env.acme_url} "
            ])
            conf.end_md()
            conf.add_vhost(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            env.check_md_complete(domain)
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH10056"   # Unsuccessful in contacting ACME server
                ],
                matches = [
                    r'.*Unsuccessful in contacting ACME server at .*'
                ]
            )
    �������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_820_locks.py������������������������������������������������������0000664�0001751�0001751�00000005250�14750656217�021005� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    
    import pytest
    from filelock import Timeout, FileLock
    
    from .md_cert_util import MDCertUtil
    from .md_conf import MDConf
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestLocks:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            env.APACHE_CONF_SRC = "data/test_auto"
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        def configure_httpd(self, env, domains, add_lines=""):
            conf = MDConf(env)
            conf.add(add_lines)
            conf.add_md(domains)
            conf.add_vhost(domains)
            conf.install()
    
        # normal renewal with store locks activated
        def test_md_820_001(self, env):
            domain = self.test_domain
            self.configure_httpd(env, [domain], add_lines=[
                "MDStoreLocks 1s"
            ])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
    
        # renewal, with global lock held during restert
        @pytest.mark.skip("does not work in our CI")
        def test_md_820_002(self, env):
            domain = self.test_domain
            self.configure_httpd(env, [domain], add_lines=[
                "MDStoreLocks 1s"
            ])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            # we have a cert now, add a dns name to force renewal
            certa = MDCertUtil(env.store_domain_file(domain, 'pubcert.pem'))
            self.configure_httpd(env, [domain, f"x.{domain}"], add_lines=[
                "MDStoreLocks 1s"
            ])
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # await new cert, but do not restart, keeps the cert in staging
            assert env.await_completion([domain], restart=False)
            # obtain global lock and restart
            lockfile = os.path.join(env.store_dir, "store.lock")
            with FileLock(lockfile):
                assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            # lock should have prevented staging from being activated,
            # meaning we will have the same cert
            certb = MDCertUtil(env.store_domain_file(domain, 'pubcert.pem'))
            assert certa.same_serial_as(certb)
            # now restart without lock
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            certc = MDCertUtil(env.store_domain_file(domain, 'pubcert.pem'))
            assert not certa.same_serial_as(certc)
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_920_status.py�����������������������������������������������������0000664�0001751�0001751�00000024002�14750656217�021212� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md status resources
    
    import os
    import re
    from datetime import timedelta
    
    import pytest
    from pyhttpd.certs import CertificateSpec
    
    from .md_conf import MDConf
    from shutil import copyfile
    
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestStatus:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env, acme):
            acme.start(config='default')
            env.check_acme()
            env.clear_store()
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env, request):
            env.clear_store()
            self.test_domain = env.get_request_domain(request)
    
        # simple MD, drive it, check status before activation
        def test_md_920_001(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False)
            # we started without a valid certificate, so we expect /.httpd/certificate-status
            # to not give information about one and - since we waited for the ACME signup
            # to complete - to give information in 'renewal' about the new cert.
            status = env.get_certificate_status(domain)
            assert 'sha256-fingerprint' not in status
            assert 'valid' not in status
            assert 'renewal' in status
            assert 'valid' in status['renewal']['cert']
            assert 'sha256-fingerprint' in status['renewal']['cert']['rsa']
            # restart and activate
            # once activated, the staging must be gone and attributes exist for the active cert
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            status = env.get_certificate_status(domain)
            assert 'renewal' not in status
            assert 'sha256-fingerprint' in status['rsa']
            assert 'valid' in status['rsa']
            assert 'from' in status['rsa']['valid']
    
        # simple MD, drive it, manipulate staged credentials and check status
        def test_md_920_002(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False)
            # copy a real certificate from LE over to staging
            staged_cert = os.path.join(env.store_dir, 'staging', domain, 'pubcert.pem')
            real_cert = os.path.join(env.test_dir, '../modules/md/data', 'test_920', '002.pubcert')
            assert copyfile(real_cert, staged_cert)
            status = env.get_certificate_status(domain)
            # status shows the copied cert's properties as staged
            assert 'renewal' in status
            assert 'Thu, 29 Aug 2019 16:06:35 GMT' == status['renewal']['cert']['rsa']['valid']['until']
            assert 'Fri, 31 May 2019 16:06:35 GMT' == status['renewal']['cert']['rsa']['valid']['from']
            assert '03039C464D454EDE79FCD2CAE859F668F269' == status['renewal']['cert']['rsa']['serial']
            assert 'sha256-fingerprint' in status['renewal']['cert']['rsa']
    
        # test if switching status off has effect
        def test_md_920_003(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add("MDCertificateStatus off")
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False)
            status = env.get_certificate_status(domain)
            assert not status
    
        def test_md_920_004(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add_md(domains)
            conf.add("MDCertificateStatus off")
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain])
            status = env.get_md_status("")
            assert "version" in status
            assert "managed-domains" in status
            assert 1 == len(status["managed-domains"])
    
        # get the status of a domain on base server
        def test_md_920_010(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env, std_vhosts=False, std_ports=False, text=f"""
    MDBaseServer on
    MDPortMap http:- https:{env.https_port}
    MDStapling on
    
    ServerName {domain}
    <IfModule ssl_module>
    SSLEngine on
    </IfModule>
    <IfModule tls_module>
    TLSListen {env.https_port}
    TLSStrictSNI off
    </IfModule>
    Protocols h2 http/1.1 acme-tls/1
    
    <Location "/server-status">
        SetHandler server-status
    </Location>
    <Location "/md-status">
        SetHandler md-status
    </Location>
    <VirtualHost *:{env.http_port}>
      SSLEngine off
    </VirtualHost>
                """)
            conf.add_md(domains)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False,
                                        via_domain=env.http_addr, use_https=False)
            status = env.get_md_status("", via_domain=env.http_addr, use_https=False)
            assert "version" in status
            assert "managed-domains" in status
            assert 1 == len(status["managed-domains"])
            # get the html page
            status = env.get_server_status(via_domain=env.http_addr, use_https=False)
            assert re.search(r'<h3>Managed Certificates</h3>', status, re.MULTILINE)
            # get the ascii summary
            status = env.get_server_status(query="?auto", via_domain=env.http_addr, use_https=False)
            m = re.search(r'ManagedCertificatesTotal: (\d+)', status, re.MULTILINE)
            assert m, status
            assert int(m.group(1)) == 1
            m = re.search(r'ManagedCertificatesOK: (\d+)', status, re.MULTILINE)
            assert int(m.group(1)) == 0
            m = re.search(r'ManagedCertificatesRenew: (\d+)', status, re.MULTILINE)
            assert int(m.group(1)) == 1
            m = re.search(r'ManagedCertificatesErrored: (\d+)', status, re.MULTILINE)
            assert int(m.group(1)) == 0
            m = re.search(r'ManagedCertificatesReady: (\d+)', status, re.MULTILINE)
            assert int(m.group(1)) == 1
            m = re.search(r'ManagedDomain\[0]Stapling: (on)', status, re.MULTILINE)
            assert m, f'{status}'
    
        def test_md_920_011(self, env):
            # MD with static cert files in base server, see issue #161
            domain = self.test_domain
            domains = [domain, 'www.%s' % domain]
            testpath = os.path.join(env.gen_dir, 'test_920_011')
            env.mkpath(testpath)
            # cert that is only 20 more days valid
            creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
                                                valid_from=timedelta(days=-70),
                                                valid_to=timedelta(days=20),
                                                serial=920011)
            cert_file = os.path.join(testpath, 'pubcert.pem')
            pkey_file = os.path.join(testpath, 'privkey.pem')
            creds.save_cert_pem(cert_file)
            creds.save_pkey_pem(pkey_file)
            conf = MDConf(env, std_vhosts=False, std_ports=False, text=f"""
            MDBaseServer on
            MDPortMap http:- https:{env.https_port}
    
            ServerName {domain}
            <IfModule ssl_module>
            SSLEngine on
            </IfModule>
            <IfModule tls_module>
            TLSListen {env.https_port}
            TLSStrictSNI off
            </IfModule>
            Protocols h2 http/1.1 acme-tls/1
    
            <Location "/server-status">
                SetHandler server-status
            </Location>
            <Location "/md-status">
                SetHandler md-status
            </Location>
                """)
            conf.start_md(domains)
            conf.add(f"MDCertificateFile {cert_file}")
            conf.add(f"MDCertificateKeyFile {pkey_file}")
            conf.end_md()
            conf.start_vhost([env.http_addr], port=env.http_port)
            conf.add("SSLEngine off")
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            status = env.get_md_status(domain, via_domain=env.http_addr, use_https=False)
            assert status
            assert 'renewal' not in status
            print(status)
            assert status['state'] == env.MD_S_COMPLETE
            assert status['renew-mode'] == 0  # manual
    
        # MD with 2 certificates
        def test_md_920_020(self, env):
            domain = self.test_domain
            domains = [domain]
            conf = MDConf(env)
            conf.add("MDStapling on")
            conf.add("MDPrivateKeys secp256r1 RSA")
            conf.add_md(domains)
            conf.add_vhost(domain)
            conf.install()
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            assert env.await_completion([domain], restart=False)
            # In the stats JSON, we expect 2 certificates under 'renewal'
            stat = env.get_md_status(domain)
            assert 'renewal' in stat
            assert 'cert' in stat['renewal']
            assert 'rsa' in stat['renewal']['cert']
            assert 'secp256r1' in stat['renewal']['cert']
            # In /.httpd/certificate-status 'renewal' we expect 2 certificates
            status = env.get_certificate_status(domain)
            assert 'renewal' in status
            assert 'cert' in status['renewal']
            assert 'secp256r1' in status['renewal']['cert']
            assert 'rsa' in status['renewal']['cert']
            # restart and activate
            # once activated, certs are listed in status
            assert env.apache_restart() == 0, f'{env.apachectl_stderr}'
            stat = env.get_md_status(domain)
            assert 'cert' in stat
            assert 'valid' in stat['cert']
            for ktype in ['rsa', 'secp256r1']:
                assert ktype in stat['cert']
                if env.acme_server == 'boulder':
                    assert 'ocsp' in stat['cert'][ktype]
            #
            env.httpd_error_log.ignore_recent(
                matches = [
                    r'.*certificate with serial \w+ has no OCSP responder URL.*'
                ]
            )
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/md_conf.py�������������������������������������������������������������0000775�0001751�0001751�00000005270�14240433464�017643� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .md_env import MDTestEnv
    from pyhttpd.conf import HttpdConf
    
    
    class MDConf(HttpdConf):
    
        def __init__(self, env: MDTestEnv, text=None, std_ports=True,
                     local_ca=True, std_vhosts=True, proxy=False,
                     admin=None):
            super().__init__(env=env)
    
            if admin is None:
                admin = f"admin@{env.http_tld}"
            if len(admin.strip()):
                self.add_admin(admin)
            self.add([
                "MDRetryDelay 1s",  # speed up testing a little
            ])
            if local_ca:
                self.add([
                    f"MDCertificateAuthority {env.acme_url}",
                    f"MDCertificateAgreement accepted",
                    f"MDCACertificateFile {env.server_dir}/acme-ca.pem",
                    "",
                    ])
            if std_ports:
                self.add(f"MDPortMap 80:{env.http_port} 443:{env.https_port}")
                if env.ssl_module == "mod_tls":
                    self.add(f"TLSListen {env.https_port}")
            self.add([
                "<Location /server-status>",
                "    SetHandler server-status",
                "</Location>",
                "<Location /md-status>",
                "    SetHandler md-status",
                "</Location>",
            ])
            if std_vhosts:
                self.add_vhost_test1()
            if proxy:
                self.add([
                    f"Listen {self.env.proxy_port}",
                    f"<VirtualHost *:{self.env.proxy_port}>",
                    "    ProxyRequests On",
                    "    ProxyVia On",
                    "    # be totally open",
                    "    AllowCONNECT 0-56535",
                    "    <Proxy *>",
                    "       # No require or other restrictions, this is just a test server",
                    "    </Proxy>",
                    "</VirtualHost>",
                ])
            if text is not None:
                self.add(text)
    
        def add_drive_mode(self, mode):
            self.add("MDRenewMode \"%s\"\n" % mode)
    
        def add_renew_window(self, window):
            self.add("MDRenewWindow %s\n" % window)
    
        def add_private_key(self, key_type, key_params):
            self.add("MDPrivateKeys %s %s\n" % (key_type, " ".join(map(lambda p: str(p), key_params))))
    
        def add_admin(self, email):
            self.add(f"ServerAdmin mailto:{email}")
    
        def add_md(self, domains):
            dlist = " ".join(domains)    # without quotes
            self.add(f"MDomain {dlist}\n")
    
        def start_md(self, domains):
            dlist = " ".join([f"\"{d}\"" for d in domains])  # with quotes, #257
            self.add(f"<MDomain {dlist}>\n")
            
        def end_md(self):
            self.add("</MDomain>\n")
    
        def start_md2(self, domains):
            self.add("<MDomainSet %s>\n" % " ".join(domains))
    
        def end_md2(self):
            self.add("</MDomainSet>\n")
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/test_120_reg_list.py���������������������������������������������������0000664�0001751�0001751�00000007452�14240433464�021470� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# test mod_md acme terms-of-service handling
    
    from shutil import copyfile
    
    import pytest
    
    from .md_env import MDTestEnv
    
    
    @pytest.mark.skipif(condition=not MDTestEnv.has_a2md(), reason="no a2md available")
    @pytest.mark.skipif(condition=not MDTestEnv.has_acme_server(),
                        reason="no ACME test server configured")
    class TestRegAdd:
    
        @pytest.fixture(autouse=True, scope='function')
        def _method_scope(self, env):
            env.clear_store()
    
        # test case: list empty store
        def test_md_120_000(self, env):
            assert env.a2md(["list"]).json == env.EMPTY_JOUT
    
        # test case: list two managed domains
        def test_md_120_001(self, env):
            domains = [ 
                ["test120-001.com", "test120-001a.com", "test120-001b.com"],
                ["greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de"]
            ]
            for dns in domains:
                assert env.a2md(["add"] + dns).exit_code == 0
            #
            # list all store content
            jout = env.a2md(["list"]).json
            assert len(jout['output']) == len(domains)
            domains.reverse()
            for i in range(0, len(jout['output'])):
                env.check_json_contains(jout['output'][i], {
                    "name": domains[i][0],
                    "domains": domains[i],
                    "contacts": [],
                    "ca": {
                        "urls": [env.acme_url],
                        "proto": "ACME"
                    },
                    "state": env.MD_S_INCOMPLETE
                })
            # list md by name
            for dns in ["test120-001.com", "greenbytes2.de"]:
                md = env.a2md(["list", dns]).json['output'][0]
                assert md['name'] == dns
    
        # test case: validate md state in store
        def test_md_120_002(self, env):
            # check: md without pkey/cert -> INCOMPLETE
            domain = f"test1.{env.http_tld}"
            assert env.a2md(["add", domain]).exit_code == 0
            assert env.a2md(["update", domain, "contacts", "admin@" + domain]).exit_code == 0
            assert env.a2md(["update", domain, "agreement", env.acme_tos]).exit_code == 0
            assert env.a2md(["list", domain]).json['output'][0]['state'] == env.MD_S_INCOMPLETE
            # check: valid pkey/cert -> COMPLETE
            cred = env.get_credentials_for_name(domain)[0]
            copyfile(cred.pkey_file, env.store_domain_file(domain, 'privkey.pem'))
            copyfile(cred.cert_file, env.store_domain_file(domain, 'pubcert.pem'))
            assert env.a2md(["list", domain]).json['output'][0]['state'] == env.MD_S_COMPLETE
            # check: expired cert -> EXPIRED
            cred = env.get_credentials_for_name(f"expired.{env.http_tld}")[0]
            copyfile(cred.pkey_file, env.store_domain_file(domain, 'privkey.pem'))
            copyfile(cred.cert_file, env.store_domain_file(domain, 'pubcert.pem'))
            out = env.a2md(["list", domain]).json['output'][0]
            assert out['state'] == env.MD_S_INCOMPLETE
            assert out['renew'] is True
    
        # test case: broken cert file
        def test_md_120_003(self, env):
            domain = f"test1.{env.http_tld}"
            assert env.a2md(["add", domain]).exit_code == 0
            assert env.a2md(["update", domain, "contacts", "admin@" + domain]).exit_code == 0
            assert env.a2md(["update", domain, "agreement", env.acme_tos]).exit_code == 0
            # check: valid pkey/cert -> COMPLETE
            cred = env.get_credentials_for_name(domain)[0]
            copyfile(cred.pkey_file, env.store_domain_file(domain, 'privkey.pem'))
            copyfile(cred.cert_file, env.store_domain_file(domain, 'pubcert.pem'))
            assert env.a2md(["list", domain]).json['output'][0]['state'] == env.MD_S_COMPLETE
            # check: replace cert by broken file -> ERROR
            with open(env.store_domain_file(domain, 'pubcert.pem'), 'w') as fd:
                fd.write("dummy\n")
            assert env.a2md(["list", domain]).json['output'][0]['state'] == env.MD_S_INCOMPLETE
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/http_challenge_foobar.py�����������������������������������������������0000775�0001751�0001751�00000001434�14156100407�022537� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os
    import re
    import sys
    
    
    def main(argv):
        if len(argv) < 4:
            sys.stderr.write(f"{argv[0]} without too few arguments")
            sys.exit(7)
        store_dir = argv[1]
        event = argv[2]
        mdomain = argv[3]
        m = re.match(r'(\S+):(\S+):(\S+)', event)
        if m and 'challenge-setup' == m.group(1) and 'http-01' == m.group(2):
            dns_name = m.group(3)
            challenge_file = f"{store_dir}/challenges/{dns_name}/acme-http-01.txt"
            if not os.path.isfile(challenge_file):
                sys.stderr.write(f"{argv[0]} does not exist: {challenge_file}")
                sys.exit(8)
            with open(challenge_file, 'w') as fd:
                fd.write('this_is_an_invalidated_http-01_challenge')
        sys.exit(0)
    
    
    if __name__ == "__main__":
        main(sys.argv)
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/msg_fail_on.py���������������������������������������������������������0000775�0001751�0001751�00000001201�14156100407�020473� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import os
    import sys
    
    
    def main(argv):
        if len(argv) > 3:
            log = argv[1]
            fail_on = argv[2]
            cmd = argv[3]
            domain = argv[4]
            if 'renewing' != cmd:
                f1 = open(log, 'a+')
                f1.write(f"{[argv[0], log, cmd, domain]}\n")
                f1.close()
            if cmd.startswith(fail_on):
                sys.stderr.write(f"failing on: {cmd}\n")
                sys.exit(1)
            sys.stderr.write("done, all fine.\n")
            sys.exit(0)
        else:
            sys.stderr.write("%s without arguments" % (argv[0]))
            sys.exit(7)
    
    
    if __name__ == "__main__":
        main(sys.argv)
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/md_certs.py������������������������������������������������������������0000775�0001751�0001751�00000042271�14156100407�020032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import re
    from datetime import timedelta, datetime
    from typing import List, Any, Optional
    
    from cryptography import x509
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import ec, rsa
    from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
    from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
    from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption, load_pem_private_key
    from cryptography.x509 import ExtendedKeyUsageOID, NameOID
    
    
    EC_SUPPORTED = {}
    EC_SUPPORTED.update([(curve.name.upper(), curve) for curve in [
        ec.SECP192R1,
        ec.SECP224R1,
        ec.SECP256R1,
        ec.SECP384R1,
    ]])
    
    
    def _private_key(key_type):
        if isinstance(key_type, str):
            key_type = key_type.upper()
            m = re.match(r'^(RSA)?(\d+)$', key_type)
            if m:
                key_type = int(m.group(2))
    
        if isinstance(key_type, int):
            return rsa.generate_private_key(
                public_exponent=65537,
                key_size=key_type,
                backend=default_backend()
            )
        if not isinstance(key_type, ec.EllipticCurve) and key_type in EC_SUPPORTED:
            key_type = EC_SUPPORTED[key_type]
        return ec.generate_private_key(
            curve=key_type,
            backend=default_backend()
        )
    
    
    class CertificateSpec:
    
        def __init__(self, name: str = None, domains: List[str] = None,
                     email: str = None,
                     key_type: str = None, single_file: bool = False,
                     valid_from: timedelta = timedelta(days=-1),
                     valid_to: timedelta = timedelta(days=89),
                     client: bool = False,
                     sub_specs: List['CertificateSpec'] = None):
            self._name = name
            self.domains = domains
            self.client = client
            self.email = email
            self.key_type = key_type
            self.single_file = single_file
            self.valid_from = valid_from
            self.valid_to = valid_to
            self.sub_specs = sub_specs
    
        @property
        def name(self) -> Optional[str]:
            if self._name:
                return self._name
            elif self.domains:
                return self.domains[0]
            return None
    
    
    class Credentials:
    
        def __init__(self, name: str, cert: Any, pkey: Any):
            self._name = name
            self._cert = cert
            self._pkey = pkey
            self._cert_file = None
            self._pkey_file = None
            self._store = None
    
        @property
        def name(self) -> str:
            return self._name
    
        @property
        def subject(self) -> x509.Name:
            return self._cert.subject
    
        @property
        def key_type(self):
            if isinstance(self._pkey, RSAPrivateKey):
                return f"rsa{self._pkey.key_size}"
            elif isinstance(self._pkey, EllipticCurvePrivateKey):
                return f"{self._pkey.curve.name}"
            else:
                raise Exception(f"unknown key type: {self._pkey}")
    
        @property
        def private_key(self) -> Any:
            return self._pkey
    
        @property
        def certificate(self) -> Any:
            return self._cert
    
        @property
        def cert_pem(self) -> bytes:
            return self._cert.public_bytes(Encoding.PEM)
    
        @property
        def pkey_pem(self) -> bytes:
            return self._pkey.private_bytes(
                Encoding.PEM,
                PrivateFormat.TraditionalOpenSSL if self.key_type.startswith('rsa') else PrivateFormat.PKCS8,
                NoEncryption())
    
        def set_store(self, store: 'CertStore'):
            self._store = store
    
        def set_files(self, cert_file: str, pkey_file: str = None):
            self._cert_file = cert_file
            self._pkey_file = pkey_file
    
        @property
        def cert_file(self) -> str:
            return self._cert_file
    
        @property
        def pkey_file(self) -> Optional[str]:
            return self._pkey_file
    
        def get_first(self, name) -> Optional['Credentials']:
            creds = self._store.get_credentials_for_name(name) if self._store else []
            return creds[0] if len(creds) else None
    
        def get_credentials_for_name(self, name) -> List['Credentials']:
            return self._store.get_credentials_for_name(name) if self._store else []
    
        def issue_certs(self, specs: List[CertificateSpec],
                        chain: List['Credentials'] = None) -> List['Credentials']:
            return [self.issue_cert(spec=spec, chain=chain) for spec in specs]
    
        def issue_cert(self, spec: CertificateSpec, chain: List['Credentials'] = None) -> 'Credentials':
            key_type = spec.key_type if spec.key_type else self.key_type
            creds = self._store.load_credentials(name=spec.name, key_type=key_type, single_file=spec.single_file) \
                if self._store else None
            if creds is None:
                creds = MDTestCA.create_credentials(spec=spec, issuer=self, key_type=key_type,
                                                    valid_from=spec.valid_from, valid_to=spec.valid_to)
                if self._store:
                    self._store.save(creds, single_file=spec.single_file)
    
            if spec.sub_specs:
                if self._store:
                    sub_store = CertStore(fpath=os.path.join(self._store.path, creds.name))
                    creds.set_store(sub_store)
                subchain = chain.copy() if chain else []
                subchain.append(self)
                creds.issue_certs(spec.sub_specs, chain=subchain)
            return creds
    
    
    class CertStore:
    
        def __init__(self, fpath: str):
            self._store_dir = fpath
            if not os.path.exists(self._store_dir):
                os.makedirs(self._store_dir)
            self._creds_by_name = {}
    
        @property
        def path(self) -> str:
            return self._store_dir
    
        def save(self, creds: Credentials, name: str = None,
                 chain: List[Credentials] = None,
                 single_file: bool = False) -> None:
            name = name if name is not None else creds.name
            cert_file = self.get_cert_file(name=name, key_type=creds.key_type)
            pkey_file = self.get_pkey_file(name=name, key_type=creds.key_type)
            if single_file:
                pkey_file = None
            with open(cert_file, "wb") as fd:
                fd.write(creds.cert_pem)
                if chain:
                    for c in chain:
                        fd.write(c.cert_pem)
                if pkey_file is None:
                    fd.write(creds.pkey_pem)
            if pkey_file is not None:
                with open(pkey_file, "wb") as fd:
                    fd.write(creds.pkey_pem)
            creds.set_files(cert_file, pkey_file)
            self._add_credentials(name, creds)
    
        def _add_credentials(self, name: str, creds: Credentials):
            if name not in self._creds_by_name:
                self._creds_by_name[name] = []
            self._creds_by_name[name].append(creds)
    
        def get_credentials_for_name(self, name) -> List[Credentials]:
            return self._creds_by_name[name] if name in self._creds_by_name else []
    
        def get_cert_file(self, name: str, key_type=None) -> str:
            key_infix = ".{0}".format(key_type) if key_type is not None else ""
            return os.path.join(self._store_dir, f'{name}{key_infix}.cert.pem')
    
        def get_pkey_file(self, name: str, key_type=None) -> str:
            key_infix = ".{0}".format(key_type) if key_type is not None else ""
            return os.path.join(self._store_dir, f'{name}{key_infix}.pkey.pem')
    
        def load_pem_cert(self, fpath: str) -> x509.Certificate:
            with open(fpath) as fd:
                return x509.load_pem_x509_certificate("".join(fd.readlines()).encode())
    
        def load_pem_pkey(self, fpath: str):
            with open(fpath) as fd:
                return load_pem_private_key("".join(fd.readlines()).encode(), password=None)
    
        def load_credentials(self, name: str, key_type=None, single_file: bool = False):
            cert_file = self.get_cert_file(name=name, key_type=key_type)
            pkey_file = cert_file if single_file else self.get_pkey_file(name=name, key_type=key_type)
            if os.path.isfile(cert_file) and os.path.isfile(pkey_file):
                cert = self.load_pem_cert(cert_file)
                pkey = self.load_pem_pkey(pkey_file)
                creds = Credentials(name=name, cert=cert, pkey=pkey)
                creds.set_store(self)
                creds.set_files(cert_file, pkey_file)
                self._add_credentials(name, creds)
                return creds
            return None
    
    
    class MDTestCA:
    
        @classmethod
        def create_root(cls, name: str, store_dir: str, key_type: str = "rsa2048") -> Credentials:
            store = CertStore(fpath=store_dir)
            creds = store.load_credentials(name="ca", key_type=key_type)
            if creds is None:
                creds = MDTestCA._make_ca_credentials(name=name, key_type=key_type)
                store.save(creds, name="ca")
                creds.set_store(store)
            return creds
    
        @staticmethod
        def create_credentials(spec: CertificateSpec, issuer: Credentials, key_type: Any,
                               valid_from: timedelta = timedelta(days=-1),
                               valid_to: timedelta = timedelta(days=89),
                               ) -> Credentials:
            """Create a certificate signed by this CA for the given domains.
            :returns: the certificate and private key PEM file paths
            """
            if spec.domains and len(spec.domains):
                creds = MDTestCA._make_server_credentials(name=spec.name, domains=spec.domains,
                                                          issuer=issuer, valid_from=valid_from,
                                                          valid_to=valid_to, key_type=key_type)
            elif spec.client:
                creds = MDTestCA._make_client_credentials(name=spec.name, issuer=issuer,
                                                          email=spec.email, valid_from=valid_from,
                                                          valid_to=valid_to, key_type=key_type)
            elif spec.name:
                creds = MDTestCA._make_ca_credentials(name=spec.name, issuer=issuer,
                                                      valid_from=valid_from, valid_to=valid_to,
                                                      key_type=key_type)
            else:
                raise Exception(f"unrecognized certificate specification: {spec}")
            return creds
    
        @staticmethod
        def _make_x509_name(org_name: str = None, common_name: str = None, parent: x509.Name = None) -> x509.Name:
            name_pieces = []
            if org_name:
                oid = NameOID.ORGANIZATIONAL_UNIT_NAME if parent else NameOID.ORGANIZATION_NAME
                name_pieces.append(x509.NameAttribute(oid, org_name))
            elif common_name:
                name_pieces.append(x509.NameAttribute(NameOID.COMMON_NAME, common_name))
            if parent:
                name_pieces.extend([rdn for rdn in parent])
            return x509.Name(name_pieces)
    
        @staticmethod
        def _make_csr(
                subject: x509.Name,
                pkey: Any,
                issuer_subject: Optional[Credentials],
                valid_from_delta: timedelta = None,
                valid_until_delta: timedelta = None
        ):
            pubkey = pkey.public_key()
            issuer_subject = issuer_subject if issuer_subject is not None else subject
    
            valid_from = datetime.now()
            if valid_until_delta is not None:
                valid_from += valid_from_delta
            valid_until = datetime.now()
            if valid_until_delta is not None:
                valid_until += valid_until_delta
    
            return (
                x509.CertificateBuilder()
                .subject_name(subject)
                .issuer_name(issuer_subject)
                .public_key(pubkey)
                .not_valid_before(valid_from)
                .not_valid_after(valid_until)
                .serial_number(x509.random_serial_number())
                .add_extension(
                    x509.SubjectKeyIdentifier.from_public_key(pubkey),
                    critical=False,
                )
            )
    
        @staticmethod
        def _add_ca_usages(csr: Any) -> Any:
            return csr.add_extension(
                x509.BasicConstraints(ca=True, path_length=9),
                critical=True,
            ).add_extension(
                x509.KeyUsage(
                    digital_signature=True,
                    content_commitment=False,
                    key_encipherment=False,
                    data_encipherment=False,
                    key_agreement=False,
                    key_cert_sign=True,
                    crl_sign=True,
                    encipher_only=False,
                    decipher_only=False),
                critical=True
            ).add_extension(
                x509.ExtendedKeyUsage([
                    ExtendedKeyUsageOID.CLIENT_AUTH,
                    ExtendedKeyUsageOID.SERVER_AUTH,
                    ExtendedKeyUsageOID.CODE_SIGNING,
                ]),
                critical=True
            )
    
        @staticmethod
        def _add_leaf_usages(csr: Any, domains: List[str], issuer: Credentials) -> Any:
            return csr.add_extension(
                x509.BasicConstraints(ca=False, path_length=None),
                critical=True,
            ).add_extension(
                x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
                    issuer.certificate.extensions.get_extension_for_class(
                        x509.SubjectKeyIdentifier).value),
                critical=False
            ).add_extension(
                x509.SubjectAlternativeName([x509.DNSName(domain) for domain in domains]),
                critical=True,
            ).add_extension(
                x509.ExtendedKeyUsage([
                    ExtendedKeyUsageOID.SERVER_AUTH,
                ]),
                critical=True
            )
    
        @staticmethod
        def _add_client_usages(csr: Any, issuer: Credentials, rfc82name: str = None) -> Any:
            cert = csr.add_extension(
                x509.BasicConstraints(ca=False, path_length=None),
                critical=True,
            ).add_extension(
                x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
                    issuer.certificate.extensions.get_extension_for_class(
                        x509.SubjectKeyIdentifier).value),
                critical=False
            )
            if rfc82name:
                cert.add_extension(
                    x509.SubjectAlternativeName([x509.RFC822Name(rfc82name)]),
                    critical=True,
                )
            cert.add_extension(
                x509.ExtendedKeyUsage([
                    ExtendedKeyUsageOID.CLIENT_AUTH,
                ]),
                critical=True
            )
            return cert
    
        @staticmethod
        def _make_ca_credentials(name, key_type: Any,
                                 issuer: Credentials = None,
                                 valid_from: timedelta = timedelta(days=-1),
                                 valid_to: timedelta = timedelta(days=89),
                                 ) -> Credentials:
            pkey = _private_key(key_type=key_type)
            if issuer is not None:
                issuer_subject = issuer.certificate.subject
                issuer_key = issuer.private_key
            else:
                issuer_subject = None
                issuer_key = pkey
            subject = MDTestCA._make_x509_name(org_name=name, parent=issuer.subject if issuer else None)
            csr = MDTestCA._make_csr(subject=subject,
                                     issuer_subject=issuer_subject, pkey=pkey,
                                     valid_from_delta=valid_from, valid_until_delta=valid_to)
            csr = MDTestCA._add_ca_usages(csr)
            cert = csr.sign(private_key=issuer_key,
                            algorithm=hashes.SHA256(),
                            backend=default_backend())
            return Credentials(name=name, cert=cert, pkey=pkey)
    
        @staticmethod
        def _make_server_credentials(name: str, domains: List[str], issuer: Credentials,
                                     key_type: Any,
                                     valid_from: timedelta = timedelta(days=-1),
                                     valid_to: timedelta = timedelta(days=89),
                                     ) -> Credentials:
            name = name
            pkey = _private_key(key_type=key_type)
            subject = MDTestCA._make_x509_name(common_name=name, parent=issuer.subject)
            csr = MDTestCA._make_csr(subject=subject,
                                     issuer_subject=issuer.certificate.subject, pkey=pkey,
                                     valid_from_delta=valid_from, valid_until_delta=valid_to)
            csr = MDTestCA._add_leaf_usages(csr, domains=domains, issuer=issuer)
            cert = csr.sign(private_key=issuer.private_key,
                            algorithm=hashes.SHA256(),
                            backend=default_backend())
            return Credentials(name=name, cert=cert, pkey=pkey)
    
        @staticmethod
        def _make_client_credentials(name: str,
                                     issuer: Credentials, email: Optional[str],
                                     key_type: Any,
                                     valid_from: timedelta = timedelta(days=-1),
                                     valid_to: timedelta = timedelta(days=89),
                                     ) -> Credentials:
            pkey = _private_key(key_type=key_type)
            subject = MDTestCA._make_x509_name(common_name=name, parent=issuer.subject)
            csr = MDTestCA._make_csr(subject=subject,
                                     issuer_subject=issuer.certificate.subject, pkey=pkey,
                                     valid_from_delta=valid_from, valid_until_delta=valid_to)
            csr = MDTestCA._add_client_usages(csr, issuer=issuer, rfc82name=email)
            cert = csr.sign(private_key=issuer.private_key,
                            algorithm=hashes.SHA256(),
                            backend=default_backend())
            return Credentials(name=name, cert=cert, pkey=pkey)
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/notify.py��������������������������������������������������������������0000775�0001751�0001751�00000000542�14156100407�017535� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import sys
    
    
    def main(argv):
        if len(argv) > 2:
            with open(argv[1], 'a+') as f1:
                f1.write(f"{argv}\n")
            sys.stderr.write("done, all fine.\n")
            sys.exit(0)
        else:
            sys.stderr.write(f"{argv[0]} without arguments")
            sys.exit(7)
        
    
    if __name__ == "__main__":
        main(sys.argv)
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/md/notifail.py������������������������������������������������������������0000775�0001751�0001751�00000000653�14156100407�020035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import sys
    
    
    def main(argv):
        if len(argv) > 1:
            msg = argv[2] if len(argv) > 2 else None
            # fail on later messaging stages, not the initial 'renewing' one.
            # we have test_901_030 that check that later stages are not invoked
            # when misconfigurations are detected early.
            sys.exit(1 if msg != "renewing" else 0)
        
    
    if __name__ == "__main__":
        main(sys.argv)
    �������������������������������������������������������������������������������������httpd-2.4.64/test/modules/core/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016213� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/core/conftest.py����������������������������������������������������������0000664�0001751�0001751�00000001675�14645322714�020421� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import os
    
    import pytest
    import sys
    
    from .env import CoreTestEnv
    from pyhttpd.env import HttpdTestEnv
    
    sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
    
    
    def pytest_report_header(config, startdir):
        env = CoreTestEnv()
        return f"core [apache: {env.get_httpd_version()}, mpm: {env.mpm_module}, {env.prefix}]"
    
    
    @pytest.fixture(scope="package")
    def env(pytestconfig) -> CoreTestEnv:
        level = logging.INFO
        console = logging.StreamHandler()
        console.setLevel(level)
        console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
        logging.getLogger('').addHandler(console)
        logging.getLogger('').setLevel(level=level)
        env = CoreTestEnv(pytestconfig=pytestconfig)
        env.setup_httpd()
        env.apache_access_log_clear()
        env.httpd_error_log.clear_log()
        return env
    
    @pytest.fixture(autouse=True, scope="package")
    def _stop_package_scope(env):
        yield
        assert env.apache_stop() == 0
    �������������������������������������������������������������������httpd-2.4.64/test/modules/core/__init__.py����������������������������������������������������������0000664�0001751�0001751�00000000001�14156101330�020273� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/core/test_002_restarts.py�������������������������������������������������0000664�0001751�0001751�00000013210�14643712504�022045� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import re
    import time
    from datetime import datetime, timedelta
    from threading import Thread
    
    import pytest
    
    from .env import CoreTestEnv
    from pyhttpd.conf import HttpdConf
    
    
    class Loader:
    
        def __init__(self, env, url: str, clients: int, req_per_client: int = 10):
            self.env = env
            self.url = url
            self.clients = clients
            self.req_per_client = req_per_client
            self.result = None
            self.total_request = 0
            self._thread = None
    
        def run(self):
            self.total_requests = self.clients * self.req_per_client
            conn_per_client = 5
            args = [self.env.h2load, f"--connect-to=localhost:{self.env.https_port}",
                    "--h1",                                 # use only http/1.1
                    "-n", str(self.total_requests),              # total # of requests to make
                    "-c", str(conn_per_client * self.clients),   # total # of connections to make
                    "-r", str(self.clients),                     # connections at a time
                    "--rate-period", "2",                   # create conns every 2 sec
                    self.url,
                    ]
            self.result = self.env.run(args)
    
        def start(self):
            self._thread = Thread(target=self.run)
            self._thread.start()
    
        def join(self):
            self._thread.join()
    
    
    class ChildDynamics:
    
        RE_DATE_TIME = re.compile(r'\[(?P<date_time>[^\]]+)\] .*')
        RE_TIME_FRAC = re.compile(r'(?P<dt>.* \d\d:\d\d:\d\d)(?P<frac>.(?P<micros>.\d+)) (?P<year>\d+)')
        RE_CHILD_CHANGE = re.compile(r'\[(?P<date_time>[^\]]+)\] '
                                     r'\[mpm_event:\w+\]'
                                     r' \[pid (?P<main_pid>\d+):tid \w+\] '
                                     r'.* Child (?P<child_no>\d+) (?P<action>\w+): '
                                     r'pid (?P<pid>\d+), gen (?P<generation>\d+), .*')
    
        def __init__(self, env: CoreTestEnv):
            self.env = env
            self.changes = list()
            self._start = None
            for l in open(env.httpd_error_log.path):
                m = self.RE_CHILD_CHANGE.match(l)
                if m:
                    self.changes.append({
                        'pid': int(m.group('pid')),
                        'child_no': int(m.group('child_no')),
                        'gen': int(m.group('generation')),
                        'action': m.group('action'),
                        'rtime' : self._rtime(m.group('date_time'))
                    })
                    continue
                if self._start is None:
                    m = self.RE_DATE_TIME.match(l)
                    if m:
                        self._rtime(m.group('date_time'))
    
        def _rtime(self, s: str) -> timedelta:
            micros = 0
            m = self.RE_TIME_FRAC.match(s)
            if m:
                micros = int(m.group('micros'))
                s = f"{m.group('dt')} {m.group('year')}"
            d = datetime.strptime(s, '%a %b %d %H:%M:%S %Y') + timedelta(microseconds=micros)
            if self._start is None:
                self._start = d
            delta = d - self._start
            return f"{delta.seconds:+02d}.{delta.microseconds:06d}"
    
    
    
    @pytest.mark.skipif(condition='STRESS_TEST' not in os.environ,
                        reason="STRESS_TEST not set in env")
    @pytest.mark.skipif(condition=not CoreTestEnv().h2load_is_at_least('1.41.0'),
                        reason="h2load unavailable or misses --connect-to option")
    class TestRestarts:
    
        def test_core_002_01(self, env):
            # Lets make a tight config that triggers dynamic child behaviour
            conf = HttpdConf(env, extras={
                'base': f"""
            StartServers            1
            ServerLimit             3
            ThreadLimit             4
            ThreadsPerChild         4
            MinSpareThreads         4
            MaxSpareThreads         6
            MaxRequestWorkers       12
            MaxConnectionsPerChild  0
    
            LogLevel mpm_event:trace6
                    """,
            })
            conf.add_vhost_cgi()
            conf.install()
    
            # clear logs and start server, start load
            env.httpd_error_log.clear_log()
            assert env.apache_restart() == 0
            # we should see a single child started
            cd = ChildDynamics(env)
            assert len(cd.changes) == 1, f"{cd.changes}"
            assert cd.changes[0]['action'] == 'started'
            # This loader simulates 6 clients, each making 10 requests.
            # delay.py sleeps for 1sec, so this should run for about 10 seconds
            loader = Loader(env=env, url=env.mkurl("https", "cgi", "/delay.py"),
                            clients=6, req_per_client=10)
            loader.start()
            # Expect 2 more children to have been started after half time
            time.sleep(5)
            cd = ChildDynamics(env)
            assert len(cd.changes) == 3, f"{cd.changes}"
            assert len([x for x in cd.changes if x['action'] == 'started']) == 3, f"{cd.changes}"
    
            # Trigger a server reload
            assert env.apache_reload() == 0
            # a graceful reload lets ongoing requests continue, but
            # after a while all gen 0 children should have stopped
            time.sleep(3)  # FIXME: this pbly depends on the runtime a lot, do we have expectations?
            cd = ChildDynamics(env)
            gen0 = [x for x in cd.changes if x['gen'] == 0]
            assert len([x for x in gen0 if x['action'] == 'stopped']) == 3
    
            # wait for the loader to finish and stop the server
            loader.join()
            env.apache_stop()
    
            # Similar to before the reload, we expect 3 children to have
            # been started and stopped again on server stop
            cd = ChildDynamics(env)
            gen1 = [x for x in cd.changes if x['gen'] == 1]
            assert len([x for x in gen1 if x['action'] == 'started']) == 3
            assert len([x for x in gen1 if x['action'] == 'stopped']) == 3
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/core/test_001_encoding.py�������������������������������������������������0000664�0001751�0001751�00000006712�14643712504�021774� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    from typing import List, Optional
    
    from pyhttpd.conf import HttpdConf
    
    
    class TestEncoding:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = HttpdConf(env, extras={
                'base': f"""
            <Directory "{env.gen_dir}">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Require all granted
            </Directory>
            """,
                f"test2.{env.http_tld}": "AllowEncodedSlashes on",
                f"test1.{env.http_tld}": f"ScriptAlias /cgi-bin/ {env.gen_dir}",
            })
            conf.add_vhost_test1()
            conf.add_vhost_test2()
            conf.add_vhost_cgi()
            conf.install()
            assert env.apache_restart() == 0
    
        # check handling of url encodings that are accepted
        @pytest.mark.parametrize("path", [
            "/006/006.css",
            "/%30%30%36/%30%30%36.css",
            "/nothing/../006/006.css",
            "/nothing/./../006/006.css",
            "/nothing/%2e%2e/006/006.css",
            "/nothing/%2e/%2e%2e/006/006.css",
            "/nothing/%2e/%2e%2e/006/006%2ecss",
        ])
        def test_core_001_01(self, env, path):
            url = env.mkurl("https", "test1", path)
            r = env.curl_get(url)
            assert r.response["status"] == 200
    
        # check handling of / normalization
        @pytest.mark.parametrize("path", [
            "/006//006.css",
            "/006//////////006.css",
            "/006////.//////006.css",
            "/006////%2e//////006.css",
            "/006////%2e//////006%2ecss",
            "/006/../006/006.css",
            "/006/%2e%2e/006/006.css",
        ])
        def test_core_001_03(self, env, path):
            url = env.mkurl("https", "test1", path)
            r = env.curl_get(url)
            assert r.response["status"] == 200
    
        # check path traversals
        @pytest.mark.parametrize(["path", "status", "lognos"], [
            ["/../echo.py", 400, ["AH10244"]],
            ["/nothing/../../echo.py", 400, ["AH10244"]],
            ["/cgi-bin/../../echo.py", 400, ["AH10244"]],
            ["/nothing/%2e%2e/%2e%2e/echo.py", 400, ["AH10244"]],
            ["/cgi-bin/%2e%2e/%2e%2e/echo.py", 400, ["AH10244"]],
            ["/nothing/%%32%65%%32%65/echo.py", 400, ["AH10244"]],
            ["/cgi-bin/%%32%65%%32%65/echo.py", 400, ["AH10244"]],
            ["/nothing/%%32%65%%32%65/%%32%65%%32%65/h2_env.py", 400, ["AH10244"]],
            ["/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/h2_env.py", 400, ["AH10244"]],
            ["/nothing/%25%32%65%25%32%65/echo.py", 404, ["AH01264"]],
            ["/cgi-bin/%25%32%65%25%32%65/echo.py", 404, ["AH01264"]],
            ["/nothing/%25%32%65%25%32%65/%25%32%65%25%32%65/h2_env.py", 404, ["AH01264"]],
            ["/cgi-bin/%25%32%65%25%32%65/%25%32%65%25%32%65/h2_env.py", 404, ["AH01264"]],
        ])
        def test_core_001_04(self, env, path, status, lognos: Optional[List[str]]):
            url = env.mkurl("https", "test1", path)
            r = env.curl_get(url)
            assert r.response["status"] == status
            #
            if lognos is not None:
                env.httpd_error_log.ignore_recent(lognos = lognos)
     
        # check handling of %2f url encodings that are not decoded by default
        @pytest.mark.parametrize(["host", "path", "status"], [
            ["test1", "/006%2f006.css", 404],
            ["test2", "/006%2f006.css", 200],
            ["test2", "/x%252f.test", 200],
            ["test2", "/10%25abnormal.txt", 200],
        ])
        def test_core_001_20(self, env, host, path, status):
            url = env.mkurl("https", host, path)
            r = env.curl_get(url)
            assert r.response["status"] == status
    ������������������������������������������������������httpd-2.4.64/test/modules/core/env.py���������������������������������������������������������������0000664�0001751�0001751�00000001225�14643712504�017351� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import logging
    import os
    
    from pyhttpd.env import HttpdTestEnv, HttpdTestSetup
    
    log = logging.getLogger(__name__)
    
    
    class CoreTestSetup(HttpdTestSetup):
    
        def __init__(self, env: 'HttpdTestEnv'):
            super().__init__(env=env)
            self.add_source_dir(os.path.dirname(inspect.getfile(CoreTestSetup)))
            self.add_modules(["cgid"])
    
    
    class CoreTestEnv(HttpdTestEnv):
    
        def __init__(self, pytestconfig=None):
            super().__init__(pytestconfig=pytestconfig)
            self.add_httpd_log_modules(["http", "core"])
    
        def setup_httpd(self, setup: HttpdTestSetup = None):
            super().setup_httpd(setup=CoreTestSetup(env=self))
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016323� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/htdocs/�������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017607� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/htdocs/cgi/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020351� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/htdocs/cgi/files/���������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�021453� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/htdocs/cgi/files/empty.txt������������������������������������������0000664�0001751�0001751�00000000000�14643712504�023334� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/htdocs/cgi/hello.py�������������������������������������������������0000775�0001751�0001751�00000000744�14643712504�022032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    
    import os
    
    print("Content-Type: application/json")
    print()
    print("{")
    print("  \"https\" : \"%s\"," % (os.getenv('HTTPS', '')))
    print("  \"host\" : \"%s\"," % (os.getenv('SERVER_NAME', '')))
    print("  \"protocol\" : \"%s\"," % (os.getenv('SERVER_PROTOCOL', '')))
    print("  \"ssl_protocol\" : \"%s\"," % (os.getenv('SSL_PROTOCOL', '')))
    print("  \"h2\" : \"%s\"," % (os.getenv('HTTP2', '')))
    print("  \"h2push\" : \"%s\"" % (os.getenv('H2PUSH', '')))
    print("}")
    
    ����������������������������httpd-2.4.64/test/modules/http1/htdocs/cgi/upload.py������������������������������������������������0000775�0001751�0001751�00000002766�14643712504�022221� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os
    import sys
    from requestparser import get_request_params
    
    
    forms, files = get_request_params()
    
    status = '200 Ok'
    
    # Test if the file was uploaded
    if 'file' in files:
        fitem = files['file']
        # strip leading path from file name to avoid directory traversal attacks
        fname = fitem.file_name
        fpath = f'{os.environ["DOCUMENT_ROOT"]}/files/{fname}'
        fitem.save_to(fpath)
        message = "The file %s was uploaded successfully" % (fname)
        print("Status: 201 Created")
        print("Content-Type: text/html")
        print("Location: %s://%s/files/%s" % (os.environ["REQUEST_SCHEME"], os.environ["HTTP_HOST"], fname))
        print("")
        print("<html><body><p>%s</p></body></html>" % (message))
    
    elif 'remove' in forms:
        remove = forms['remove']
        try:
            fname = os.path.basename(remove)
            os.remove('./files/' + fname)
            message = 'The file "' + fname + '" was removed successfully'
        except OSError as e:
            message = 'Error removing ' + fname + ': ' + e.strerror
            status = '404 File Not Found'
        print("Status: %s" % (status))
        print("""
    Content-Type: text/html
    
    <html><body>
    <p>%s</p>
    </body></html>""" % (message))
    
    else:
        message = '''\
            Upload File<form method="POST" enctype="multipart/form-data">
            <input type="file" name="file">
            <button type="submit">Upload</button></form>
            '''
        print("Status: %s" % (status))
        print("""\
    Content-Type: text/html
    
    <html><body>
    <p>%s</p>
    </body></html>""" % (message))
    
    ����������httpd-2.4.64/test/modules/http1/htdocs/cgi/requestparser.py�����������������������������������������0000664�0001751�0001751�00000003361�14643712504�023627� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python3
    import os
    import sys
    from urllib import parse
    import multipart # https://github.com/andrew-d/python-multipart (`apt install python3-multipart`)
    import shutil
    
    
    try:  # Windows needs stdio set for binary mode.
        import msvcrt
    
        msvcrt.setmode(0, os.O_BINARY)  # stdin  = 0
        msvcrt.setmode(1, os.O_BINARY)  # stdout = 1
    except ImportError:
        pass
    
    
    class FileItem:
    
        def __init__(self, mparse_item):
            self.item = mparse_item
    
        @property
        def file_name(self):
            return os.path.basename(self.item.file_name.decode())
    
        def save_to(self, destpath: str):
            fsrc = self.item.file_object
            fsrc.seek(0)
            with open(destpath, 'wb') as fd:
                shutil.copyfileobj(fsrc, fd)
    
    
    def get_request_params():
        oforms = {}
        ofiles = {}
        if "REQUEST_URI" in os.environ:
            qforms = parse.parse_qs(parse.urlsplit(os.environ["REQUEST_URI"]).query)
            for name, values in qforms.items():
                oforms[name] = values[0]
        if "CONTENT_TYPE" in os.environ:
            ctype = os.environ["CONTENT_TYPE"]
            if ctype == "application/x-www-form-urlencoded":
                s = sys.stdin.read()
                qforms = parse.parse_qs(s)
                for name, values in qforms.items():
                    oforms[name] = values[0]
            elif ctype.startswith("multipart/"):
                def on_field(field):
                    oforms[field.field_name.decode()] = field.value.decode()
                def on_file(file):
                    ofiles[file.field_name.decode()] = FileItem(file)
                multipart.parse_form(headers={"Content-Type": ctype},
                                     input_stream=sys.stdin.buffer,
                                     on_field=on_field, on_file=on_file)
        return oforms, ofiles
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/mod_h1test/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020372� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/mod_h1test/mod_h1test.slo�������������������������������������������0000664�0001751�0001751�00000000000�14643712504�023142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/mod_h1test/mod_h1test.c���������������������������������������������0000664�0001751�0001751�00000010652�14643712504�022605� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <apr_optional_hooks.h>
    #include <apr_strings.h>
    #include <apr_cstr.h>
    #include <apr_time.h>
    #include <apr_want.h>
    
    #include <httpd.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    
    static void h1test_hooks(apr_pool_t *pool);
    
    AP_DECLARE_MODULE(h1test) = {
        STANDARD20_MODULE_STUFF,
        NULL, /* func to create per dir config */
        NULL,  /* func to merge per dir config */
        NULL, /* func to create per server config */
        NULL,  /* func to merge per server config */
        NULL,              /* command handlers */
        h1test_hooks,
    #if defined(AP_MODULE_FLAG_NONE)
        AP_MODULE_FLAG_ALWAYS_MERGE
    #endif
    };
    
    
    static int h1test_echo_handler(request_rec *r)
    {
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;
        char buffer[8192];
        const char *ct;
        long l;
    
        if (strcmp(r->handler, "h1test-echo")) {
            return DECLINED;
        }
        if (r->method_number != M_GET && r->method_number != M_POST) {
            return DECLINED;
        }
    
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "echo_handler: processing request");
        r->status = 200;
        r->clength = -1;
        r->chunked = 1;
        ct = apr_table_get(r->headers_in, "content-type");
        ap_set_content_type(r, ct? ct : "application/octet-stream");
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
        /* copy any request body into the response */
        if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK))) goto cleanup;
        if (ap_should_client_block(r)) {
            while (0 < (l = ap_get_client_block(r, &buffer[0], sizeof(buffer)))) {
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "echo_handler: copying %ld bytes from request body", l);
                rv = apr_brigade_write(bb, NULL, NULL, buffer, l);
                if (APR_SUCCESS != rv) goto cleanup;
                rv = ap_pass_brigade(r->output_filters, bb);
                if (APR_SUCCESS != rv) goto cleanup;
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                              "echo_handler: passed %ld bytes from request body", l);
            }
        }
        /* we are done */
        b = apr_bucket_eos_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, b);
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "echo_handler: request read");
    
        if (r->trailers_in && !apr_is_empty_table(r->trailers_in)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                          "echo_handler: seeing incoming trailers");
            apr_table_setn(r->trailers_out, "h1test-trailers-in",
                           apr_itoa(r->pool, 1));
        }
        if (apr_table_get(r->headers_in, "Add-Trailer")) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                          "echo_handler: seeing incoming Add-Trailer header");
            apr_table_setn(r->trailers_out, "h1test-add-trailer",
                           apr_table_get(r->headers_in, "Add-Trailer"));
        }
    
        rv = ap_pass_brigade(r->output_filters, bb);
    
    cleanup:
        if (rv == APR_SUCCESS
            || r->status != HTTP_OK
            || c->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, "echo_handler: request handled");
            return OK;
        }
        else {
            /* no way to know what type of error occurred */
            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, "h1test_echo_handler failed");
            return AP_FILTER_ERROR;
        }
        return DECLINED;
    }
    
    
    /* Install this module into the apache2 infrastructure.
     */
    static void h1test_hooks(apr_pool_t *pool)
    {
        ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks and handlers");
    
        /* test h1 handlers */
        ap_hook_handler(h1test_echo_handler, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    ��������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/env.py��������������������������������������������������������������0000664�0001751�0001751�00000005531�14643712504�017465� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import logging
    import os
    import subprocess
    from typing import Dict, Any
    
    from pyhttpd.certs import CertificateSpec
    from pyhttpd.conf import HttpdConf
    from pyhttpd.env import HttpdTestEnv, HttpdTestSetup
    
    log = logging.getLogger(__name__)
    
    
    class H1TestSetup(HttpdTestSetup):
    
        def __init__(self, env: 'HttpdTestEnv'):
            super().__init__(env=env)
            self.add_source_dir(os.path.dirname(inspect.getfile(H1TestSetup)))
            self.add_modules(["cgid", "autoindex", "ssl"])
    
        def make(self):
            super().make()
            self._add_h1test()
            self._setup_data_1k_1m()
    
        def _add_h1test(self):
            local_dir = os.path.dirname(inspect.getfile(H1TestSetup))
            p = subprocess.run([self.env.apxs, '-c', 'mod_h1test.c'],
                               capture_output=True,
                               cwd=os.path.join(local_dir, 'mod_h1test'))
            rv = p.returncode
            if rv != 0:
                log.error(f"compiling md_h1test failed: {p.stderr}")
                raise Exception(f"compiling md_h1test failed: {p.stderr}")
    
            modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf')
            with open(modules_conf, 'a') as fd:
                # load our test module which is not installed
                fd.write(f"LoadModule h1test_module   \"{local_dir}/mod_h1test/.libs/mod_h1test.so\"\n")
    
        def _setup_data_1k_1m(self):
            s90 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n"
            with open(os.path.join(self.env.gen_dir, "data-1k"), 'w') as f:
                for i in range(10):
                    f.write(f"{i:09d}-{s90}")
            with open(os.path.join(self.env.gen_dir, "data-10k"), 'w') as f:
                for i in range(100):
                    f.write(f"{i:09d}-{s90}")
            with open(os.path.join(self.env.gen_dir, "data-100k"), 'w') as f:
                for i in range(1000):
                    f.write(f"{i:09d}-{s90}")
            with open(os.path.join(self.env.gen_dir, "data-1m"), 'w') as f:
                for i in range(10000):
                    f.write(f"{i:09d}-{s90}")
    
    
    class H1TestEnv(HttpdTestEnv):
    
        def __init__(self, pytestconfig=None):
            super().__init__(pytestconfig=pytestconfig)
            self.add_httpd_log_modules(["http", "core"])
    
        def setup_httpd(self, setup: HttpdTestSetup = None):
            super().setup_httpd(setup=H1TestSetup(env=self))
    
    
    class H1Conf(HttpdConf):
    
        def __init__(self, env: HttpdTestEnv, extras: Dict[str, Any] = None):
            super().__init__(env=env, extras=HttpdConf.merge_extras(extras, {
                "base": [
                    "LogLevel http:trace4",
                ],
                f"cgi.{env.http_tld}": [
                    "SSLOptions +StdEnvVars",
                    "AddHandler cgi-script .py",
                    "<Location \"/h1test/echo\">",
                    "    SetHandler h1test-echo",
                    "</Location>",
                ]
            }))
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/__init__.py���������������������������������������������������������0000664�0001751�0001751�00000000000�14643712504�020416� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/conftest.py���������������������������������������������������������0000664�0001751�0001751�00000002202�14645322714�020514� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import os
    
    import pytest
    import sys
    
    sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
    
    from .env import H1TestEnv
    
    
    def pytest_report_header(config, startdir):
        env = H1TestEnv()
        return f"mod_http [apache: {env.get_httpd_version()}, mpm: {env.mpm_module}, {env.prefix}]"
    
    
    def pytest_generate_tests(metafunc):
        if "repeat" in metafunc.fixturenames:
            count = int(metafunc.config.getoption("repeat"))
            metafunc.fixturenames.append('tmp_ct')
            metafunc.parametrize('repeat', range(count))
    
    
    @pytest.fixture(scope="package")
    def env(pytestconfig) -> H1TestEnv:
        level = logging.INFO
        console = logging.StreamHandler()
        console.setLevel(level)
        console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
        logging.getLogger('').addHandler(console)
        logging.getLogger('').setLevel(level=level)
        env = H1TestEnv(pytestconfig=pytestconfig)
        env.setup_httpd()
        env.apache_access_log_clear()
        env.httpd_error_log.clear_log()
        return env
    
    @pytest.fixture(autouse=True, scope="package")
    def _stop_package_scope(env):
        yield
        assert env.apache_stop() == 0
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/test_005_trailers.py������������������������������������������������0000664�0001751�0001751�00000003441�14643712504�022143� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import pytest
    
    from .env import H1Conf
    
    
    # The trailer tests depend on "nghttp" as no other client seems to be able to send those
    # rare things.
    class TestTrailers:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H1Conf(env).add_vhost_cgi(proxy_self=True).install()
            assert env.apache_restart() == 0
    
        # check that we get a trailer out when telling the handler to add one
        def test_h1_005_01(self, env):
            if not env.httpd_is_at_least("2.5.0"):
                pytest.skip(f'need at least httpd 2.5.0 for this')
            url = env.mkurl("https", "cgi", "/h1test/echo")
            host = f"cgi.{env.http_tld}"
            fpath = os.path.join(env.gen_dir, "data-1k")
            r = env.curl_upload(url, fpath, options=["--header", "Add-Trailer: 005_01"])
            assert r.exit_code == 0, f"{r}"
            assert 200 <= r.response["status"] < 300
            assert r.response["trailer"], f"no trailers received: {r}"
            assert "h1test-add-trailer" in r.response["trailer"]
            assert r.response["trailer"]["h1test-add-trailer"] == "005_01"
    
        # check that we get out trailers through the proxy
        def test_h1_005_02(self, env):
            if not env.httpd_is_at_least("2.5.0"):
                pytest.skip(f'need at least httpd 2.5.0 for this')
            url = env.mkurl("https", "cgi", "/proxy/h1test/echo")
            host = f"cgi.{env.http_tld}"
            fpath = os.path.join(env.gen_dir, "data-1k")
            r = env.curl_upload(url, fpath, options=["--header", "Add-Trailer: 005_01"])
            assert r.exit_code == 0, f"{r}"
            assert 200 <= r.response["status"] < 300
            assert r.response["trailer"], f"no trailers received: {r}"
            assert "h1test-add-trailer" in r.response["trailer"]
            assert r.response["trailer"]["h1test-add-trailer"] == "005_01"
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/test_004_post.py����������������������������������������������������0000664�0001751�0001751�00000003163�14643712504�021303� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import difflib
    import email.parser
    import inspect
    import json
    import os
    import sys
    
    import pytest
    
    from .env import H1Conf
    
    
    class TestPost:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            TestPost._local_dir = os.path.dirname(inspect.getfile(TestPost))
            H1Conf(env).add_vhost_cgi().install()
            assert env.apache_restart() == 0
    
        def local_src(self, fname):
            return os.path.join(TestPost._local_dir, fname)
    
        # upload and GET again using curl, compare to original content
        def curl_upload_and_verify(self, env, fname, options=None):
            url = env.mkurl("https", "cgi", "/upload.py")
            fpath = os.path.join(env.gen_dir, fname)
            r = env.curl_upload(url, fpath, options=options)
            assert r.exit_code == 0, f"{r}"
            assert 200 <= r.response["status"] < 300
    
            r2 = env.curl_get(r.response["header"]["location"])
            assert r2.exit_code == 0
            assert r2.response["status"] == 200
            with open(self.local_src(fpath), mode='rb') as file:
                src = file.read()
            assert src == r2.response["body"]
            return r
    
        def test_h1_004_01(self, env):
            self.curl_upload_and_verify(env, "data-1k", ["-vvv"])
    
        def test_h1_004_02(self, env):
            self.curl_upload_and_verify(env, "data-10k", [])
    
        def test_h1_004_03(self, env):
            self.curl_upload_and_verify(env, "data-100k", [])
    
        def test_h1_004_04(self, env):
            self.curl_upload_and_verify(env, "data-1m", [])
    
        def test_h1_004_05(self, env):
            r = self.curl_upload_and_verify(env, "data-1k", ["-vvv", "-H", "Expect: 100-continue"])
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/test_003_get.py�����������������������������������������������������0000664�0001751�0001751�00000001402�14643712504�021066� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import socket
    
    import pytest
    
    from .env import H1Conf
    
    
    class TestGet:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H1Conf(env).add_vhost_cgi(
                proxy_self=True
            ).add_vhost_test1(
                proxy_self=True
            ).install()
            assert env.apache_restart() == 0
    
        # check SSL environment variables from CGI script
        def test_h1_003_01(self, env):
            url = env.mkurl("https", "cgi", "/hello.py")
            r = env.curl_get(url)
            assert r.response["status"] == 200
            assert r.response["json"]["protocol"] == "HTTP/1.1"
            assert r.response["json"]["https"] == "on"
            tls_version = r.response["json"]["ssl_protocol"]
            assert tls_version in ["TLSv1.2", "TLSv1.3"]
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/test_007_strict.py��������������������������������������������������0000664�0001751�0001751�00000012265�14643712504�021634� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re
    import socket
    from typing import List, Optional
    
    import pytest
    
    from .env import H1Conf
    
    
    class TestRequestStrict:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H1Conf(env)
            conf.add([
                "HttpProtocolOptions Strict",
            ])
            conf.install()
            assert env.apache_restart() == 0
    
        # strict tests from t/apache/http_strict.t
        # possible expected results:
        #   0:       any HTTP error
        #   1:       any HTTP success
        #   200-500: specific HTTP status code
        #   undef:   HTTPD should drop connection without error message
        @pytest.mark.parametrize(["intext", "status"], [
            ["GET / HTTP/1.0\n\n", 400],
            ["G/T / HTTP/1.0\r\n\r\n", 400],
            ["GET / HTTP/1.0  \r\nHost: localhost\r\n\r\n", 400],
            ["GET / HTTP/1.0\r\nFoo: b\x01ar\r\n\r\n", 400],
            ["GET / HTTP/1.0\r\nF\x01o: bar\r\n\r\n", 400],
            ["GET / HTTP/1.0\r\r", None],
            ["GET / HTTP/1.0\r\nHost: localhost\r\nHost: localhost\r\n\r\n", 400],
            ["GET http://017700000001/ HTTP/1.0\r\n\r\n", 400],
            ["GET http://0x7f.1/ HTTP/1.0\r\n\r\n", 400],
            ["GET http://127.01.0.1/ HTTP/1.0\r\n\r\n", 400],
            ["GET http://%3127.0.0.1/ HTTP/1.0\r\n\r\n", 400],
            ["GET / HTTP/1.0\r\nHost: localhost:80\r\nHost: localhost:80\r\n\r\n", 400],
            ["GET http://foo@localhost:80/ HTTP/1.0\r\n\r\n", 400],
            ["GET / HTTP/1.0\r\nHost: 4714::abcd:8001\r\n\r\n", 400],
            ["GET / HTTP/1.0\r\nHost: abc\xa0\r\n\r\n", 400],
            ["GET / HTTP/1.0\r\nHost: foo_bar.example.com\r\n\r\n", 200],
            ["GET http://foo_bar/ HTTP/1.0\r\n\r\n", 200],
        ])
        def test_h1_007_01(self, env, intext, status: Optional[int]):
            with socket.create_connection(('localhost', int(env.http_port))) as sock:
                # on some OS, the server does not see our connection until there is
                # something incoming
                sock.sendall(intext.encode())
                sock.shutdown(socket.SHUT_WR)
                buff = sock.recv(1024)
                msg = buff.decode()
                if status is None:
                    assert len(msg) == 0, f"unexpected answer: {msg}"
                else:
                    assert len(msg) > 0, "no answer from server"
                    rlines = msg.splitlines()
                    response = rlines[0]
                    m = re.match(r'^HTTP/1.1 (\d+)\s+(\S+)', response)
                    assert m, f"unrecognized response: {rlines}"
                    if status == 1:
                        assert int(m.group(1)) >= 200
                    elif status == 90:
                        assert len(rlines) >= 1, f"{rlines}"
                    elif status > 0:
                        assert int(m.group(1)) == status, f"{rlines}"
                    else:
                        assert int(m.group(1)) >= 400, f"{rlines}"
    
        @pytest.mark.parametrize(["hvalue", "expvalue", "status", "lognos"], [
            ['"123"', '123', 200, None],
            ['"123 "', '123 ', 200, None],       # trailing space stays
            ['"123\t"', '123\t', 200, None],     # trailing tab stays
            ['" 123"', '123', 200, None],        # leading space is stripped
            ['"          123"', '123', 200, None],  # leading spaces are stripped
            ['"\t123"', '123', 200, None],       # leading tab is stripped
            ['"expr=%{unescape:123%0A 123}"', '', 500, ["AH02430"]],  # illegal char
            ['" \t "', '', 200, None],           # just ws
        ])
        def test_h1_007_02(self, env, hvalue, expvalue, status, lognos: Optional[List[str]]):
            hname = 'ap-test-007'
            conf = H1Conf(env, extras={
                f'test1.{env.http_tld}': [
                    '<Location /index.html>',
                    f'Header add {hname} {hvalue}',
                    '</Location>',
                ]
            })
            conf.add_vhost_test1(proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "test1", "/index.html")
            r = env.curl_get(url, options=['--http1.1'])
            assert r.response["status"] == status
            if int(status) < 400:
                assert r.response["header"][hname] == expvalue
            #
            if lognos is not None:
                env.httpd_error_log.ignore_recent(lognos = lognos)
    
        @pytest.mark.parametrize(["hvalue", "expvalue"], [
            ['123', '123'],
            ['123 ', '123'],    # trailing space is stripped
            ['123\t', '123'],    # trailing tab is stripped
            [' 123', '123'],    # leading space is stripped
            ['          123', '123'],  # leading spaces are stripped
            ['\t123', '123'],  # leading tab is stripped
        ])
        def test_h1_007_03(self, env, hvalue, expvalue):
            # same as 007_02, but http1 proxied
            hname = 'ap-test-007'
            conf = H1Conf(env, extras={
                f'test1.{env.http_tld}': [
                    '<Location /index.html>',
                    f'Header add {hname} "{hvalue}"',
                    '</Location>',
                ]
            })
            conf.add_vhost_test1(proxy_self=True)
            conf.install()
            assert env.apache_restart() == 0
            url = env.mkurl("https", "test1", "/proxy/index.html")
            r = env.curl_get(url, options=['--http1.1'])
            assert r.response["status"] == 200
            assert r.response["header"][hname] == expvalue
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/test_001_alive.py���������������������������������������������������0000664�0001751�0001751�00000001144�14643712504�021410� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import pytest
    
    from .env import H1Conf
    
    
    class TestBasicAlive:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            H1Conf(env).add_vhost_test1().install()
            assert env.apache_restart() == 0
    
        # we expect to see the document from the generic server
        def test_h1_001_01(self, env):
            url = env.mkurl("https", "test1", "/alive.json")
            r = env.curl_get(url, 5)
            assert r.exit_code == 0, r.stderr + r.stdout
            assert r.response["json"]
            assert r.response["json"]["alive"] is True
            assert r.response["json"]["host"] == "test1"
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/http1/test_006_unsafe.py��������������������������������������������������0000664�0001751�0001751�00000015402�14643712504�021600� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re
    import socket
    from typing import List, Optional
    
    import pytest
    
    from .env import H1Conf
    
    class TestRequestUnsafe:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            conf = H1Conf(env)
            conf.add([
                "HttpProtocolOptions Unsafe",
            ])
            conf.install()
            assert env.apache_restart() == 0
    
        # unsafe tests from t/apache/http_strict.t
        # possible expected results:
        #   0:       any HTTP error
        #   1:       any HTTP success
        #   200-500: specific HTTP status code
        #   None:   HTTPD should drop connection without error message
        @pytest.mark.parametrize(["intext", "status", "lognos"], [
            ["GET / HTTP/1.0\r\n\r\n", 1, None],
            ["GET / HTTP/1.0\n\n", 1, None],
            ["get / HTTP/1.0\r\n\r\n", 501, ["AH00135"]],
            ["G ET / HTTP/1.0\r\n\r\n", 400, None],
            ["G\0ET / HTTP/1.0\r\n\r\n", 400, None],
            ["G/T / HTTP/1.0\r\n\r\n", 501, ["AH00135"]],
            ["GET /\0 HTTP/1.0\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\0\r\n\r\n", 400, None],
            ["GET\f/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET\r/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET\t/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET / HTT/1.0\r\n\r\n", 0, None],
            ["GET / HTTP/1.0\r\nHost: localhost\r\n\r\n", 1, None],
            ["GET / HTTP/2.0\r\nHost: localhost\r\n\r\n", 1, None],
            ["GET / HTTP/1.2\r\nHost: localhost\r\n\r\n", 1, None],
            ["GET / HTTP/1.11\r\nHost: localhost\r\n\r\n", 400, None],
            ["GET / HTTP/10.0\r\nHost: localhost\r\n\r\n", 400, None],
            ["GET / HTTP/1.0  \r\nHost: localhost\r\n\r\n", 200, None],
            ["GET / HTTP/1.0 x\r\nHost: localhost\r\n\r\n", 400, None],
            ["GET / HTTP/\r\nHost: localhost\r\n\r\n", 0, None],
            ["GET / HTTP/0.9\r\n\r\n", 0, None],
            ["GET / HTTP/0.8\r\n\r\n", 0, None],
            ["GET /\x01 HTTP/1.0\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nFoo: bar\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nFoo:bar\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nFoo: b\0ar\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nFoo: b\x01ar\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nFoo\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nFoo bar\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\n: bar\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nX: bar\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nFoo bar:bash\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nFoo :bar\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\n Foo:bar\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nF\x01o: bar\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nF\ro: bar\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nF\to: bar\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nFo: b\tar\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nFo: bar\r\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\r", None, None],
            ["GET /\r\n", 0, None],
            ["GET /#frag HTTP/1.0\r\n", 400, None],
            ["GET / HTTP/1.0\r\nHost: localhost\r\nHost: localhost\r\n\r\n", 200, None],
            ["GET http://017700000001/ HTTP/1.0\r\n\r\n", 200, None],
            ["GET http://0x7f.1/ HTTP/1.0\r\n\r\n", 200, None],
            ["GET http://127.0.0.1/ HTTP/1.0\r\n\r\n", 200, None],
            ["GET http://127.01.0.1/ HTTP/1.0\r\n\r\n", 200, None],
            ["GET http://%3127.0.0.1/ HTTP/1.0\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nHost: localhost:80\r\nHost: localhost:80\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nHost: localhost:80 x\r\n\r", 400, None],
            ["GET http://localhost:80/ HTTP/1.0\r\n\r\n", 200, None],
            ["GET http://localhost:80x/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET http://localhost:80:80/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET http://localhost::80/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET http://foo@localhost:80/ HTTP/1.0\r\n\r\n", 200, None],
            ["GET http://[::1]/ HTTP/1.0\r\n\r\n", 1, None],
            ["GET http://[::1:2]/ HTTP/1.0\r\n\r\n", 1, None],
            ["GET http://[4712::abcd]/ HTTP/1.0\r\n\r\n", 1, None],
            ["GET http://[4712::abcd:1]/ HTTP/1.0\r\n\r\n", 1, None],
            ["GET http://[4712::abcd::]/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET http://[4712:abcd::,]/ HTTP/1.0\r\n\r\n", 1, None],
            ["GET http://[4712::abcd]:8000/ HTTP/1.0\r\n\r\n", 1, None],
            ["GET http://4713::abcd:8001/ HTTP/1.0\r\n\r\n", 400, None],
            ["GET / HTTP/1.0\r\nHost: [::1]\r\n\r\n", 1, None],
            ["GET / HTTP/1.0\r\nHost: [::1:2]\r\n\r\n", 1, None],
            ["GET / HTTP/1.0\r\nHost: [4711::abcd]\r\n\r\n", 1, None],
            ["GET / HTTP/1.0\r\nHost: [4711::abcd:1]\r\n\r\n", 1, None],
            ["GET / HTTP/1.0\r\nHost: [4711:abcd::]\r\n\r\n", 1, None],
            ["GET / HTTP/1.0\r\nHost: [4711::abcd]:8000\r\n\r\n", 1, None],
            ["GET / HTTP/1.0\r\nHost: 4714::abcd:8001\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nHost: abc\xa0\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nHost: abc\\foo\r\n\r\n", 400, None],
            ["GET http://foo/ HTTP/1.0\r\nHost: bar\r\n\r\n", 200, None],
            ["GET http://foo:81/ HTTP/1.0\r\nHost: bar\r\n\r\n", 200, None],
            ["GET http://[::1]:81/ HTTP/1.0\r\nHost: bar\r\n\r\n", 200, None],
            ["GET http://10.0.0.1:81/ HTTP/1.0\r\nHost: bar\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nHost: foo-bar.example.com\r\n\r\n", 200, None],
            ["GET / HTTP/1.0\r\nHost: foo_bar.example.com\r\n\r\n", 200, None],
            ["GET http://foo_bar/ HTTP/1.0\r\n\r\n", 200, None],
        ])
        def test_h1_006_01(self, env, intext, status: Optional[int], lognos: Optional[List[str]]):
            with socket.create_connection(('localhost', int(env.http_port))) as sock:
                # on some OS, the server does not see our connection until there is
                # something incoming
                sock.sendall(intext.encode())
                sock.shutdown(socket.SHUT_WR)
                buff = sock.recv(1024)
                msg = buff.decode()
                if status is None:
                    assert len(msg) == 0, f"unexpected answer: {msg}"
                else:
                    assert len(msg) > 0, "no answer from server"
                    rlines = msg.splitlines()
                    response = rlines[0]
                    m = re.match(r'^HTTP/1.1 (\d+)\s+(\S+)', response)
                    assert m or status == 0, f"unrecognized response: {rlines}"
                    if status == 1:
                        assert int(m.group(1)) >= 200
                    elif status == 0:
                        # headerless 0.9 response, yuk
                        assert len(rlines) >= 1, f"{rlines}"
                    elif status > 0:
                        assert int(m.group(1)) == status, f"{rlines}"
                    else:
                        assert int(m.group(1)) >= 400, f"{rlines}"
                    #
                    if lognos is not None:
                        env.httpd_error_log.ignore_recent(lognos = lognos)
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/proxy/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016444� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/proxy/conftest.py���������������������������������������������������������0000664�0001751�0001751�00000001711�14645322714�020641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import os
    import sys
    import pytest
    
    from .env import ProxyTestEnv
    
    sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
    
    
    def pytest_report_header(config, startdir):
        env = ProxyTestEnv()
        return "mod_proxy: [apache: {aversion}({prefix})]".format(
            prefix=env.prefix,
            aversion=env.get_httpd_version(),
        )
    
    
    @pytest.fixture(scope="package")
    def env(pytestconfig) -> ProxyTestEnv:
        level = logging.INFO
        console = logging.StreamHandler()
        console.setLevel(level)
        console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
        logging.getLogger('').addHandler(console)
        logging.getLogger('').setLevel(level=level)
        env = ProxyTestEnv(pytestconfig=pytestconfig)
        env.setup_httpd()
        env.apache_access_log_clear()
        env.httpd_error_log.clear_log()
        return env
    
    @pytest.fixture(autouse=True, scope="package")
    def _stop_package_scope(env):
        yield
        assert env.apache_stop() == 0
    �������������������������������������������������������httpd-2.4.64/test/modules/proxy/__init__.py���������������������������������������������������������0000664�0001751�0001751�00000000000�14272156577�020551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/proxy/test_01_http.py�����������������������������������������������������0000664�0001751�0001751�00000007147�14424160200�021324� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import time
    
    import pytest
    
    from pyhttpd.conf import HttpdConf
    
    
    class TestProxyHttp:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            # setup 3 vhosts on https: for reverse, forward and mixed proxying
            # setup 3 vhosts on http: with different document roots
            conf = HttpdConf(env)
            conf.add("ProxyPreserveHost on")
            conf.start_vhost(domains=[env.d_reverse], port=env.https_port)
            conf.add([
                f"ProxyPass / http://127.0.0.1:{env.http_port}/"
            ])
            conf.end_vhost()
            conf.add_vhost(domains=[env.d_reverse], port=env.http_port, doc_root='htdocs/test1')
    
            conf.start_vhost(domains=[env.d_forward], port=env.https_port)
            conf.add([
                "ProxyRequests on"
            ])
            conf.end_vhost()
            conf.add_vhost(domains=[env.d_forward], port=env.http_port, doc_root='htdocs/test2')
    
            conf.start_vhost(domains=[env.d_mixed], port=env.https_port)
            conf.add([
                f"ProxyPass / http://127.0.0.1:{env.http_port}/",
                "ProxyRequests on"
            ])
            conf.end_vhost()
            conf.add_vhost(domains=[env.d_mixed], port=env.http_port, doc_root='htdocs')
            conf.install()
            assert env.apache_restart() == 0
    
        @pytest.mark.parametrize(["via", "seen"], [
            ["reverse", "test1"],
            ["mixed", "generic"],
        ])
        def test_proxy_01_001(self, env, via, seen):
            # make requests to a reverse proxy https: vhost to the http: vhost
            # check that we see the document we expect there (host matching worked)
            r = env.curl_get(f"https://{via}.{env.http_tld}:{env.https_port}/alive.json", 5)
            assert r.response["status"] == 200
            assert r.json['host'] == seen
    
        @pytest.mark.parametrize(["via", "seen"], [
            ["reverse", "test1"],
            ["forward", "test2"],
            ["mixed", "generic"],
        ])
        def test_proxy_01_002(self, env, via, seen):
            # make requests to a forward proxy https: vhost to the http: vhost
            # check that we see the document we expect there (host matching worked)
            # we need to explicitly provide a Host: header since mod_proxy cannot
            # resolve the name via DNS.
            if not env.curl_is_at_least('8.0.0'):
                pytest.skip(f'need at least curl v8.0.0 for this')
            domain = f"{via}.{env.http_tld}"
            r = env.curl_get(f"http://127.0.0.1:{env.http_port}/alive.json", 5, options=[
                '-H', f"Host: {domain}",
                '--proxy', f"https://{domain}:{env.https_port}/",
                '--resolve', f"{domain}:{env.https_port}:127.0.0.1",
                '--proxy-cacert', f"{env.get_ca_pem_file(domain)}",
    
            ])
            assert r.exit_code == 0, f"{r.stdout}{r.stderr}"
            assert r.response["status"] == 200
            assert r.json['host'] == seen
    
        def test_proxy_01_003(self, env):
            domain = f"test1.{env.http_tld}"
            conf = HttpdConf(env)
            conf.add([
                "ProxyPreserveHost on",
                "<Proxy balancer://backends>",
                f"  BalancerMember https://localhost:{env.https_port}",
                "  SSLProxyEngine on",
                "</Proxy>",
            ])
            conf.start_vhost(domains=[domain], port=env.https_port, doc_root="htdocs/test1")
            conf.add([
                "ProxyPass /proxy balancer://backends",
                "ProxyPassReverse /proxy balancer://backends",
            ])
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0
            r = env.curl_get(f"https://{domain}:{env.https_port}/proxy/alive.json", 5)
            assert r.response["status"] == 200
            assert r.json['host'] == "test1"
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/proxy/test_02_unix.py�����������������������������������������������������0000664�0001751�0001751�00000014531�14643712504�021341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import re
    import socket
    from threading import Thread
    
    import pytest
    
    from pyhttpd.conf import HttpdConf
    from pyhttpd.result import ExecResult
    
    
    class UDSFaker:
    
        def __init__(self, path):
            self._uds_path = path
            self._done = False
    
        def start(self):
            def process(self):
                self._socket.listen(1)
                self._process()
    
            try:
                os.unlink(self._uds_path)
            except OSError:
                if os.path.exists(self._uds_path):
                    raise
            self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self._socket.bind(self._uds_path)
            self._thread = Thread(target=process, daemon=True, args=[self])
            self._thread.start()
    
        def stop(self):
            self._done = True
            self._socket.close()
    
        def _process(self):
            while self._done is False:
                try:
                    c, client_address = self._socket.accept()
                    try:
                        data = c.recv(16)
                        c.sendall("""HTTP/1.1 200 Ok
    Server: UdsFaker
    Content-Type: application/json
    Content-Length: 19
    
    { "host": "faked" }""".encode())
                    finally:
                        c.close()
    
                except ConnectionAbortedError:
                    self._done = True
    
    
    class TestProxyUds:
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            # setup 3 vhosts on https: for reverse, forward and
            # mixed proxying to a unix: domain socket
            # We setup a UDSFaker running that returns a fixed response
            UDS_PATH = f"{env.gen_dir}/proxy_02.sock"
            TestProxyUds.UDS_PATH = UDS_PATH
            faker = UDSFaker(path=UDS_PATH)
            faker.start()
    
            conf = HttpdConf(env)
            conf.add("ProxyPreserveHost on")
            conf.start_vhost(domains=[env.d_reverse], port=env.https_port)
            conf.add([
                f"ProxyPass / unix:{UDS_PATH}|http://127.0.0.1:{env.http_port}/"
            ])
            conf.end_vhost()
    
            conf.start_vhost(domains=[env.d_forward], port=env.https_port)
            conf.add([
                "ProxyRequests on"
            ])
            conf.end_vhost()
    
            conf.start_vhost(domains=[env.d_mixed], port=env.https_port)
            conf.add([
                f"ProxyPass / unix:{UDS_PATH}|http://127.0.0.1:{env.http_port}/",
                "ProxyRequests on"
            ])
            conf.end_vhost()
            conf.install()
            assert env.apache_restart() == 0
            yield
            faker.stop()
    
        @pytest.mark.parametrize(["via", "seen"], [
            ["reverse", "faked"],
            ["mixed", "faked"],
        ])
        def test_proxy_02_001(self, env, via, seen):
            # make requests to a reverse proxy https: vhost to the http: vhost
            # check that we see the document we expect there (host matching worked)
            r = env.curl_get(f"https://{via}.{env.http_tld}:{env.https_port}/alive.json", 5)
            assert r.response["status"] == 200
            assert r.json['host'] == seen
    
        @pytest.mark.parametrize(["via", "seen"], [
            ["forward", "generic"],
            ["mixed", "faked"],
        ])
        def test_proxy_02_002(self, env, via, seen):
            # make requests to a forward proxy https: vhost to the http: vhost
            # check that we see the document we expect there (host matching worked)
            # we need to explicitly provide a Host: header since mod_proxy cannot
            # resolve the name via DNS.
            if not env.curl_is_at_least('8.0.0'):
                pytest.skip(f'need at least curl v8.0.0 for this')
            domain = f"{via}.{env.http_tld}"
            r = env.curl_get(f"http://127.0.0.1:{env.http_port}/alive.json", 5, options=[
                '-H', f"Host: {domain}",
                '--proxy', f"https://{domain}:{env.https_port}/",
                '--resolve', f"{domain}:{env.https_port}:127.0.0.1",
                '--proxy-cacert', f"{env.get_ca_pem_file(domain)}",
    
            ])
            assert r.exit_code == 0, f"{r.stdout}{r.stderr}"
            assert r.response["status"] == 200
            assert r.json['host'] == seen
    
        @pytest.mark.parametrize(["via", "exp_status"], [
            ["reverse", 400],
            ["forward", 500],
            ["mixed", 500],
        ])
        def test_proxy_02_003(self, env, via, exp_status):
            # make requests to a forward proxy https: vhost and GET
            # a URL which carries the unix: domain socket.
            # This needs to fail.
            domain = f"{via}.{env.http_tld}"
            r = env.run(args=[
                'openssl', 's_client', '-connect', f"127.0.0.1:{env.https_port}",
                '-servername', domain,
                '-crlf', '-ign_eof',
                '-CAfile', env.get_ca_pem_file(domain)
            ], intext=f"""GET unix:{TestProxyUds.UDS_PATH}|http://127.0.0.1:{env.http_port}/alive.json HTTP/1.1
    Host: {domain}
    
    """)
            assert r.exit_code == 0, f"{r.stdout}{r.stderr}"
            lines = r.stdout.split('\n')
            rlines = None
            for idx, l in enumerate(lines):
                if l.startswith('HTTP/'):
                    rlines = lines[idx:]
            assert rlines, f"No response found in: {r.stdout}"
            r2 = self.parse_response(rlines)
            assert r2.response
            assert r2.response['status'] == exp_status
            #
            env.httpd_error_log.ignore_recent(
                lognos = [
                    "AH01144"   #  No protocol handler was valid for the URL
                ]
            )
    
        def parse_response(self, lines) -> ExecResult:
            exp_body = False
            exp_stat = True
            r = ExecResult(args=[], exit_code=0, stdout=b'', stderr=b'')
            header = {}
            body = []
            for line in lines:
                if exp_stat:
                    m = re.match(r'^(\S+) (\d+) (.*)$', line)
                    assert m, f"first line no HTTP status line: {line}"
                    r.add_response({
                        "protocol": m.group(1),
                        "status": int(m.group(2)),
                        "description": m.group(3),
                        "body": r.outraw
                    })
                    header = {}
                    exp_stat = False
                    exp_body = False
                elif re.match(r'^\r?$', line):
                    exp_body = True
                elif exp_body:
                    body.append(line)
                else:
                    m = re.match(r'^([^:]+):\s*(.*)$', line)
                    assert m, f"not a header line: {line}"
                    header[m.group(1).lower()] = m.group(2)
            if r.response:
                r.response["header"] = header
                r.response["body"] = body
            return r
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/modules/proxy/env.py��������������������������������������������������������������0000664�0001751�0001751�00000003036�14643712504�017604� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import inspect
    import logging
    import os
    import subprocess
    from typing import Dict, Any
    
    from pyhttpd.certs import CertificateSpec
    from pyhttpd.conf import HttpdConf
    from pyhttpd.env import HttpdTestEnv, HttpdTestSetup
    
    log = logging.getLogger(__name__)
    
    
    class ProxyTestSetup(HttpdTestSetup):
    
        def __init__(self, env: 'HttpdTestEnv'):
            super().__init__(env=env)
            self.add_source_dir(os.path.dirname(inspect.getfile(ProxyTestSetup)))
            self.add_modules(["proxy", "proxy_http", "proxy_balancer", "lbmethod_byrequests"])
    
    
    class ProxyTestEnv(HttpdTestEnv):
    
        def __init__(self, pytestconfig=None):
            super().__init__(pytestconfig=pytestconfig)
            self.add_httpd_conf([
                             ])
            self._d_reverse = f"reverse.{self.http_tld}"
            self._d_forward = f"forward.{self.http_tld}"
            self._d_mixed = f"mixed.{self.http_tld}"
    
            self.add_httpd_log_modules(["proxy", "proxy_http", "proxy_balancer", "lbmethod_byrequests", "ssl"])
            self.add_cert_specs([
                CertificateSpec(domains=[
                    self._d_forward, self._d_reverse, self._d_mixed
                ]),
                CertificateSpec(domains=[f"noh2.{self.http_tld}"], key_type='rsa2048'),
            ])
    
        def setup_httpd(self, setup: HttpdTestSetup = None):
            super().setup_httpd(setup=ProxyTestSetup(env=self))
    
        @property
        def d_forward(self):
            return self._d_forward
    
        @property
        def d_reverse(self):
            return self._d_reverse
    
        @property
        def d_mixed(self):
            return self._d_mixed
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015307� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/conf/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016234� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/conf/httpd.conf.template��������������������������������������������������0000664�0001751�0001751�00000003015�14436122317�022030� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ServerName localhost
    ServerRoot "${server_dir}"
    
    Include "conf/modules.conf"
    
    DocumentRoot "${server_dir}/htdocs"
    
    <IfModule log_config_module>
        LogFormat "{ \"request\": \"%r\", \"status\": %>s, \"bytes_resp_B\": %B, \"bytes_tx_O\": %O, \"bytes_rx_I\": %I, \"bytes_rx_tx_S\": %S, \"time_taken\": %D }" combined
        LogFormat "%h %l %u %t \"%r\" %>s %b" common
        CustomLog "logs/access_log" combined
    
    </IfModule>
    
    TypesConfig "${gen_dir}/apache/conf/mime.types"
    
    Listen ${http_port}
    Listen ${https_port}
    
    <IfModule mod_ssl.c>
        # provide some default
        SSLSessionCache "shmcb:ssl_gcache_data(32000)"
    </IfModule>
    
    # Insert our test specific configuration before the first vhost,
    # so that its vhosts can be the default one. This is relevant in
    # certain behaviours, such as protocol selection during SSL ALPN
    # negotiation.
    #
    Include "conf/test.conf"
    
    RequestReadTimeout header=10 body=10
    
    <IfModule deflate_module>
      AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    </IfModule>
    <IfModule brotli_module>
      AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
    </IfModule>
    
    <VirtualHost *:${http_port}>
        ServerName ${http_tld}
        ServerAlias www.${http_tld}
        <IfModule ssl_module>
          SSLEngine off
        </IfModule>
        DocumentRoot "${server_dir}/htdocs"
    </VirtualHost>
    
    <Directory "${server_dir}/htdocs/cgi">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    
        AddHandler cgi-script .py
        AddHandler cgi-script .cgi
        Options +ExecCGI
    </Directory>
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/conf/stop.conf.template���������������������������������������������������0000664�0001751�0001751�00000002151�14156077574�021707� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# a config safe to use for stopping the server
    # this allows us to stop the server even when+
    # the config in the file is borked (as test cases may try to do that)
    #
    ServerName localhost
    ServerRoot "${server_dir}"
    
    Include "conf/modules.conf"
    
    DocumentRoot "${server_dir}/htdocs"
    
    <IfModule log_config_module>
        LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %k" combined
        LogFormat "%h %l %u %t \"%r\" %>s %b" common
        CustomLog "logs/access_log" combined
    
    </IfModule>
    
    TypesConfig "${gen_dir}/apache/conf/mime.types"
    
    Listen ${http_port}
    Listen ${https_port}
    
    <IfModule mod_ssl.c>
        # provide some default
        SSLSessionCache "shmcb:ssl_gcache_data(32000)"
    </IfModule>
    
    <VirtualHost *:${http_port}>
        ServerName ${http_tld}
        ServerAlias www.${http_tld}
        <IfModule ssl_module>
          SSLEngine off
        </IfModule>
        DocumentRoot "${server_dir}/htdocs"
    </VirtualHost>
    
    <Directory "${server_dir}/htdocs/cgi">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    
        AddHandler cgi-script .py
        AddHandler cgi-script .cgi
        Options +ExecCGI
    </Directory>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/conf/test.conf������������������������������������������������������������0000664�0001751�0001751�00000000065�14156077574�020071� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty placeholder for test specific configurations
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/conf/mime.types�����������������������������������������������������������0000664�0001751�0001751�00000147446�14743443462�020272� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This file maps Internet media types to unique file extension(s).
    # Although created for httpd, this file is used by many software systems
    # and has been placed in the public domain for unlimited redistribution.
    #
    # The table below contains both registered and (common) unregistered types.
    # A type that has no unique extension can be ignored -- they are listed
    # here to guide configurations toward known types and to make it easier to
    # identify "new" types.  File extensions are also commonly used to indicate
    # content languages and encodings, so choose them carefully.
    #
    # Internet media types should be registered as described in RFC 4288.
    # The registry is at <http://www.iana.org/assignments/media-types/>.
    #
    # MIME type (lowercased)			Extensions
    # ============================================	==========
    # application/1d-interleaved-parityfec
    # application/3gpp-ims+xml
    # application/activemessage
    application/andrew-inset			ez
    # application/applefile
    application/applixware				aw
    application/atom+xml				atom
    application/atomcat+xml				atomcat
    # application/atomicmail
    application/atomsvc+xml				atomsvc
    # application/auth-policy+xml
    # application/batch-smtp
    # application/beep+xml
    # application/calendar+xml
    # application/cals-1840
    # application/ccmp+xml
    application/ccxml+xml				ccxml
    application/cdmi-capability			cdmia
    application/cdmi-container			cdmic
    application/cdmi-domain				cdmid
    application/cdmi-object				cdmio
    application/cdmi-queue				cdmiq
    # application/cea-2018+xml
    # application/cellml+xml
    # application/cfw
    # application/cnrp+xml
    # application/commonground
    # application/conference-info+xml
    # application/cpl+xml
    # application/csta+xml
    # application/cstadata+xml
    application/cu-seeme				cu
    # application/cybercash
    application/davmount+xml			davmount
    # application/dca-rft
    # application/dec-dx
    # application/dialog-info+xml
    # application/dicom
    # application/dns
    application/docbook+xml				dbk
    # application/dskpp+xml
    application/dssc+der				dssc
    application/dssc+xml				xdssc
    # application/dvcs
    application/ecmascript				ecma
    # application/edi-consent
    # application/edi-x12
    # application/edifact
    application/emma+xml				emma
    # application/epp+xml
    application/epub+zip				epub
    # application/eshop
    # application/example
    application/exi					exi
    # application/fastinfoset
    # application/fastsoap
    # application/fits
    application/font-tdpfr				pfr
    # application/framework-attributes+xml
    application/gml+xml				gml
    application/gpx+xml				gpx
    application/gxf					gxf
    # application/h224
    # application/held+xml
    # application/http
    application/hyperstudio				stk
    # application/ibe-key-request+xml
    # application/ibe-pkg-reply+xml
    # application/ibe-pp-data
    # application/iges
    # application/im-iscomposing+xml
    # application/index
    # application/index.cmd
    # application/index.obj
    # application/index.response
    # application/index.vnd
    application/inkml+xml				ink inkml
    # application/iotp
    application/ipfix				ipfix
    # application/ipp
    # application/isup
    application/java-archive			jar
    application/java-serialized-object		ser
    application/java-vm				class
    application/javascript				js
    application/json				json
    application/jsonml+json				jsonml
    # application/kpml-request+xml
    # application/kpml-response+xml
    application/lost+xml				lostxml
    application/mac-binhex40			hqx
    application/mac-compactpro			cpt
    # application/macwriteii
    application/mads+xml				mads
    application/marc				mrc
    application/marcxml+xml				mrcx
    application/mathematica				ma nb mb
    # application/mathml-content+xml
    # application/mathml-presentation+xml
    application/mathml+xml				mathml
    # application/mbms-associated-procedure-description+xml
    # application/mbms-deregister+xml
    # application/mbms-envelope+xml
    # application/mbms-msk+xml
    # application/mbms-msk-response+xml
    # application/mbms-protection-description+xml
    # application/mbms-reception-report+xml
    # application/mbms-register+xml
    # application/mbms-register-response+xml
    # application/mbms-user-service-description+xml
    application/mbox				mbox
    # application/media_control+xml
    application/mediaservercontrol+xml		mscml
    application/metalink+xml			metalink
    application/metalink4+xml			meta4
    application/mets+xml				mets
    # application/mikey
    application/mods+xml				mods
    # application/moss-keys
    # application/moss-signature
    # application/mosskey-data
    # application/mosskey-request
    application/mp21				m21 mp21
    application/mp4					mp4s
    # application/mpeg4-generic
    # application/mpeg4-iod
    # application/mpeg4-iod-xmt
    # application/msc-ivr+xml
    # application/msc-mixer+xml
    application/msword				doc dot
    application/mxf					mxf
    # application/nasdata
    # application/news-checkgroups
    # application/news-groupinfo
    # application/news-transmission
    # application/nss
    # application/ocsp-request
    # application/ocsp-response
    application/octet-stream	bin dms lrf mar so dist distz pkg bpk dump elc deploy
    application/oda					oda
    application/oebps-package+xml			opf
    application/ogg					ogx
    application/omdoc+xml				omdoc
    application/onenote				onetoc onetoc2 onetmp onepkg
    application/oxps				oxps
    # application/parityfec
    application/patch-ops-error+xml			xer
    application/pdf					pdf
    application/pgp-encrypted			pgp
    # application/pgp-keys
    application/pgp-signature			asc sig
    application/pics-rules				prf
    # application/pidf+xml
    # application/pidf-diff+xml
    application/pkcs10				p10
    application/pkcs7-mime				p7m p7c
    application/pkcs7-signature			p7s
    application/pkcs8				p8
    application/pkix-attr-cert			ac
    application/pkix-cert				cer
    application/pkix-crl				crl
    application/pkix-pkipath			pkipath
    application/pkixcmp				pki
    application/pls+xml				pls
    # application/poc-settings+xml
    application/postscript				ai eps ps
    # application/prs.alvestrand.titrax-sheet
    application/prs.cww				cww
    # application/prs.nprend
    # application/prs.plucker
    # application/prs.rdf-xml-crypt
    # application/prs.xsf+xml
    application/pskc+xml				pskcxml
    # application/qsig
    application/rdf+xml				rdf
    application/reginfo+xml				rif
    application/relax-ng-compact-syntax		rnc
    # application/remote-printing
    application/resource-lists+xml			rl
    application/resource-lists-diff+xml		rld
    # application/riscos
    # application/rlmi+xml
    application/rls-services+xml			rs
    application/rpki-ghostbusters			gbr
    application/rpki-manifest			mft
    application/rpki-roa				roa
    # application/rpki-updown
    application/rsd+xml				rsd
    application/rss+xml				rss
    application/rtf					rtf
    # application/rtx
    # application/samlassertion+xml
    # application/samlmetadata+xml
    application/sbml+xml				sbml
    application/scvp-cv-request			scq
    application/scvp-cv-response			scs
    application/scvp-vp-request			spq
    application/scvp-vp-response			spp
    application/sdp					sdp
    # application/set-payment
    application/set-payment-initiation		setpay
    # application/set-registration
    application/set-registration-initiation		setreg
    # application/sgml
    # application/sgml-open-catalog
    application/shf+xml				shf
    # application/sieve
    # application/simple-filter+xml
    # application/simple-message-summary
    # application/simplesymbolcontainer
    # application/slate
    # application/smil
    application/smil+xml				smi smil
    # application/soap+fastinfoset
    # application/soap+xml
    application/sparql-query			rq
    application/sparql-results+xml			srx
    # application/spirits-event+xml
    application/srgs				gram
    application/srgs+xml				grxml
    application/sru+xml				sru
    application/ssdl+xml				ssdl
    application/ssml+xml				ssml
    # application/tamp-apex-update
    # application/tamp-apex-update-confirm
    # application/tamp-community-update
    # application/tamp-community-update-confirm
    # application/tamp-error
    # application/tamp-sequence-adjust
    # application/tamp-sequence-adjust-confirm
    # application/tamp-status-query
    # application/tamp-status-response
    # application/tamp-update
    # application/tamp-update-confirm
    application/tei+xml				tei teicorpus
    application/thraud+xml				tfi
    # application/timestamp-query
    # application/timestamp-reply
    application/timestamped-data			tsd
    # application/tve-trigger
    # application/ulpfec
    # application/vcard+xml
    # application/vemmi
    # application/vividence.scriptfile
    # application/vnd.3gpp.bsf+xml
    application/vnd.3gpp.pic-bw-large		plb
    application/vnd.3gpp.pic-bw-small		psb
    application/vnd.3gpp.pic-bw-var			pvb
    # application/vnd.3gpp.sms
    # application/vnd.3gpp2.bcmcsinfo+xml
    # application/vnd.3gpp2.sms
    application/vnd.3gpp2.tcap			tcap
    application/vnd.3m.post-it-notes		pwn
    application/vnd.accpac.simply.aso		aso
    application/vnd.accpac.simply.imp		imp
    application/vnd.acucobol			acu
    application/vnd.acucorp				atc acutc
    application/vnd.adobe.air-application-installer-package+zip	air
    application/vnd.adobe.formscentral.fcdt		fcdt
    application/vnd.adobe.fxp			fxp fxpl
    # application/vnd.adobe.partial-upload
    application/vnd.adobe.xdp+xml			xdp
    application/vnd.adobe.xfdf			xfdf
    # application/vnd.aether.imp
    # application/vnd.ah-barcode
    application/vnd.ahead.space			ahead
    application/vnd.airzip.filesecure.azf		azf
    application/vnd.airzip.filesecure.azs		azs
    application/vnd.amazon.ebook			azw
    application/vnd.americandynamics.acc		acc
    application/vnd.amiga.ami			ami
    # application/vnd.amundsen.maze+xml
    application/vnd.android.package-archive		apk
    application/vnd.anser-web-certificate-issue-initiation	cii
    application/vnd.anser-web-funds-transfer-initiation	fti
    application/vnd.antix.game-component		atx
    application/vnd.apple.installer+xml		mpkg
    application/vnd.apple.mpegurl			m3u8
    # application/vnd.arastra.swi
    application/vnd.aristanetworks.swi		swi
    application/vnd.astraea-software.iota		iota
    application/vnd.audiograph			aep
    # application/vnd.autopackage
    # application/vnd.avistar+xml
    application/vnd.blueice.multipass		mpm
    # application/vnd.bluetooth.ep.oob
    application/vnd.bmi				bmi
    application/vnd.businessobjects			rep
    # application/vnd.cab-jscript
    # application/vnd.canon-cpdl
    # application/vnd.canon-lips
    # application/vnd.cendio.thinlinc.clientconf
    application/vnd.chemdraw+xml			cdxml
    application/vnd.chipnuts.karaoke-mmd		mmd
    application/vnd.cinderella			cdy
    # application/vnd.cirpack.isdn-ext
    application/vnd.claymore			cla
    application/vnd.cloanto.rp9			rp9
    application/vnd.clonk.c4group			c4g c4d c4f c4p c4u
    application/vnd.cluetrust.cartomobile-config		c11amc
    application/vnd.cluetrust.cartomobile-config-pkg	c11amz
    # application/vnd.collection+json
    # application/vnd.commerce-battelle
    application/vnd.commonspace			csp
    application/vnd.contact.cmsg			cdbcmsg
    application/vnd.cosmocaller			cmc
    application/vnd.crick.clicker			clkx
    application/vnd.crick.clicker.keyboard		clkk
    application/vnd.crick.clicker.palette		clkp
    application/vnd.crick.clicker.template		clkt
    application/vnd.crick.clicker.wordbank		clkw
    application/vnd.criticaltools.wbs+xml		wbs
    application/vnd.ctc-posml			pml
    # application/vnd.ctct.ws+xml
    # application/vnd.cups-pdf
    # application/vnd.cups-postscript
    application/vnd.cups-ppd			ppd
    # application/vnd.cups-raster
    # application/vnd.cups-raw
    # application/vnd.curl
    application/vnd.curl.car			car
    application/vnd.curl.pcurl			pcurl
    # application/vnd.cybank
    application/vnd.dart				dart
    application/vnd.data-vision.rdz			rdz
    application/vnd.dece.data			uvf uvvf uvd uvvd
    application/vnd.dece.ttml+xml			uvt uvvt
    application/vnd.dece.unspecified		uvx uvvx
    application/vnd.dece.zip			uvz uvvz
    application/vnd.denovo.fcselayout-link		fe_launch
    # application/vnd.dir-bi.plate-dl-nosuffix
    application/vnd.dna				dna
    application/vnd.dolby.mlp			mlp
    # application/vnd.dolby.mobile.1
    # application/vnd.dolby.mobile.2
    application/vnd.dpgraph				dpg
    application/vnd.dreamfactory			dfac
    application/vnd.ds-keypoint			kpxx
    application/vnd.dvb.ait				ait
    # application/vnd.dvb.dvbj
    # application/vnd.dvb.esgcontainer
    # application/vnd.dvb.ipdcdftnotifaccess
    # application/vnd.dvb.ipdcesgaccess
    # application/vnd.dvb.ipdcesgaccess2
    # application/vnd.dvb.ipdcesgpdd
    # application/vnd.dvb.ipdcroaming
    # application/vnd.dvb.iptv.alfec-base
    # application/vnd.dvb.iptv.alfec-enhancement
    # application/vnd.dvb.notif-aggregate-root+xml
    # application/vnd.dvb.notif-container+xml
    # application/vnd.dvb.notif-generic+xml
    # application/vnd.dvb.notif-ia-msglist+xml
    # application/vnd.dvb.notif-ia-registration-request+xml
    # application/vnd.dvb.notif-ia-registration-response+xml
    # application/vnd.dvb.notif-init+xml
    # application/vnd.dvb.pfr
    application/vnd.dvb.service			svc
    # application/vnd.dxr
    application/vnd.dynageo				geo
    # application/vnd.easykaraoke.cdgdownload
    # application/vnd.ecdis-update
    application/vnd.ecowin.chart			mag
    # application/vnd.ecowin.filerequest
    # application/vnd.ecowin.fileupdate
    # application/vnd.ecowin.series
    # application/vnd.ecowin.seriesrequest
    # application/vnd.ecowin.seriesupdate
    # application/vnd.emclient.accessrequest+xml
    application/vnd.enliven				nml
    # application/vnd.eprints.data+xml
    application/vnd.epson.esf			esf
    application/vnd.epson.msf			msf
    application/vnd.epson.quickanime		qam
    application/vnd.epson.salt			slt
    application/vnd.epson.ssf			ssf
    # application/vnd.ericsson.quickcall
    application/vnd.eszigno3+xml			es3 et3
    # application/vnd.etsi.aoc+xml
    # application/vnd.etsi.cug+xml
    # application/vnd.etsi.iptvcommand+xml
    # application/vnd.etsi.iptvdiscovery+xml
    # application/vnd.etsi.iptvprofile+xml
    # application/vnd.etsi.iptvsad-bc+xml
    # application/vnd.etsi.iptvsad-cod+xml
    # application/vnd.etsi.iptvsad-npvr+xml
    # application/vnd.etsi.iptvservice+xml
    # application/vnd.etsi.iptvsync+xml
    # application/vnd.etsi.iptvueprofile+xml
    # application/vnd.etsi.mcid+xml
    # application/vnd.etsi.overload-control-policy-dataset+xml
    # application/vnd.etsi.sci+xml
    # application/vnd.etsi.simservs+xml
    # application/vnd.etsi.tsl+xml
    # application/vnd.etsi.tsl.der
    # application/vnd.eudora.data
    application/vnd.ezpix-album			ez2
    application/vnd.ezpix-package			ez3
    # application/vnd.f-secure.mobile
    application/vnd.fdf				fdf
    application/vnd.fdsn.mseed			mseed
    application/vnd.fdsn.seed			seed dataless
    # application/vnd.ffsns
    # application/vnd.fints
    application/vnd.flographit			gph
    application/vnd.fluxtime.clip			ftc
    # application/vnd.font-fontforge-sfd
    application/vnd.framemaker			fm frame maker book
    application/vnd.frogans.fnc			fnc
    application/vnd.frogans.ltf			ltf
    application/vnd.fsc.weblaunch			fsc
    application/vnd.fujitsu.oasys			oas
    application/vnd.fujitsu.oasys2			oa2
    application/vnd.fujitsu.oasys3			oa3
    application/vnd.fujitsu.oasysgp			fg5
    application/vnd.fujitsu.oasysprs		bh2
    # application/vnd.fujixerox.art-ex
    # application/vnd.fujixerox.art4
    # application/vnd.fujixerox.hbpl
    application/vnd.fujixerox.ddd			ddd
    application/vnd.fujixerox.docuworks		xdw
    application/vnd.fujixerox.docuworks.binder	xbd
    # application/vnd.fut-misnet
    application/vnd.fuzzysheet			fzs
    application/vnd.genomatix.tuxedo		txd
    # application/vnd.geocube+xml
    application/vnd.geogebra.file			ggb
    application/vnd.geogebra.tool			ggt
    application/vnd.geometry-explorer		gex gre
    application/vnd.geonext				gxt
    application/vnd.geoplan				g2w
    application/vnd.geospace			g3w
    # application/vnd.globalplatform.card-content-mgt
    # application/vnd.globalplatform.card-content-mgt-response
    application/vnd.gmx				gmx
    application/vnd.google-earth.kml+xml		kml
    application/vnd.google-earth.kmz		kmz
    application/vnd.grafeq				gqf gqs
    # application/vnd.gridmp
    application/vnd.groove-account			gac
    application/vnd.groove-help			ghf
    application/vnd.groove-identity-message		gim
    application/vnd.groove-injector			grv
    application/vnd.groove-tool-message		gtm
    application/vnd.groove-tool-template		tpl
    application/vnd.groove-vcard			vcg
    # application/vnd.hal+json
    application/vnd.hal+xml				hal
    application/vnd.handheld-entertainment+xml	zmm
    application/vnd.hbci				hbci
    # application/vnd.hcl-bireports
    application/vnd.hhe.lesson-player		les
    application/vnd.hp-hpgl				hpgl
    application/vnd.hp-hpid				hpid
    application/vnd.hp-hps				hps
    application/vnd.hp-jlyt				jlt
    application/vnd.hp-pcl				pcl
    application/vnd.hp-pclxl			pclxl
    # application/vnd.httphone
    application/vnd.hydrostatix.sof-data		sfd-hdstx
    # application/vnd.hzn-3d-crossword
    # application/vnd.ibm.afplinedata
    # application/vnd.ibm.electronic-media
    application/vnd.ibm.minipay			mpy
    application/vnd.ibm.modcap			afp listafp list3820
    application/vnd.ibm.rights-management		irm
    application/vnd.ibm.secure-container		sc
    application/vnd.iccprofile			icc icm
    application/vnd.igloader			igl
    application/vnd.immervision-ivp			ivp
    application/vnd.immervision-ivu			ivu
    # application/vnd.informedcontrol.rms+xml
    # application/vnd.informix-visionary
    # application/vnd.infotech.project
    # application/vnd.infotech.project+xml
    # application/vnd.innopath.wamp.notification
    application/vnd.insors.igm			igm
    application/vnd.intercon.formnet		xpw xpx
    application/vnd.intergeo			i2g
    # application/vnd.intertrust.digibox
    # application/vnd.intertrust.nncp
    application/vnd.intu.qbo			qbo
    application/vnd.intu.qfx			qfx
    # application/vnd.iptc.g2.conceptitem+xml
    # application/vnd.iptc.g2.knowledgeitem+xml
    # application/vnd.iptc.g2.newsitem+xml
    # application/vnd.iptc.g2.newsmessage+xml
    # application/vnd.iptc.g2.packageitem+xml
    # application/vnd.iptc.g2.planningitem+xml
    application/vnd.ipunplugged.rcprofile		rcprofile
    application/vnd.irepository.package+xml		irp
    application/vnd.is-xpr				xpr
    application/vnd.isac.fcs			fcs
    application/vnd.jam				jam
    # 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.jcp.javame.midlet-rms		rms
    application/vnd.jisp				jisp
    application/vnd.joost.joda-archive		joda
    application/vnd.kahootz				ktz ktr
    application/vnd.kde.karbon			karbon
    application/vnd.kde.kchart			chrt
    application/vnd.kde.kformula			kfo
    application/vnd.kde.kivio			flw
    application/vnd.kde.kontour			kon
    application/vnd.kde.kpresenter			kpr kpt
    application/vnd.kde.kspread			ksp
    application/vnd.kde.kword			kwd kwt
    application/vnd.kenameaapp			htke
    application/vnd.kidspiration			kia
    application/vnd.kinar				kne knp
    application/vnd.koan				skp skd skt skm
    application/vnd.kodak-descriptor		sse
    application/vnd.las.las+xml			lasxml
    # application/vnd.liberty-request+xml
    application/vnd.llamagraphics.life-balance.desktop	lbd
    application/vnd.llamagraphics.life-balance.exchange+xml	lbe
    application/vnd.lotus-1-2-3			123
    application/vnd.lotus-approach			apr
    application/vnd.lotus-freelance			pre
    application/vnd.lotus-notes			nsf
    application/vnd.lotus-organizer			org
    application/vnd.lotus-screencam			scm
    application/vnd.lotus-wordpro			lwp
    application/vnd.macports.portpkg		portpkg
    # application/vnd.marlin.drm.actiontoken+xml
    # application/vnd.marlin.drm.conftoken+xml
    # application/vnd.marlin.drm.license+xml
    # application/vnd.marlin.drm.mdcf
    application/vnd.mcd				mcd
    application/vnd.medcalcdata			mc1
    application/vnd.mediastation.cdkey		cdkey
    # application/vnd.meridian-slingshot
    application/vnd.mfer				mwf
    application/vnd.mfmp				mfm
    application/vnd.micrografx.flo			flo
    application/vnd.micrografx.igx			igx
    application/vnd.mif				mif
    # application/vnd.minisoft-hp3000-save
    # application/vnd.mitsubishi.misty-guard.trustweb
    application/vnd.mobius.daf			daf
    application/vnd.mobius.dis			dis
    application/vnd.mobius.mbk			mbk
    application/vnd.mobius.mqy			mqy
    application/vnd.mobius.msl			msl
    application/vnd.mobius.plc			plc
    application/vnd.mobius.txf			txf
    application/vnd.mophun.application		mpn
    application/vnd.mophun.certificate		mpc
    # 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.motorola.iprm
    application/vnd.mozilla.xul+xml			xul
    application/vnd.ms-artgalry			cil
    # application/vnd.ms-asf
    application/vnd.ms-cab-compressed		cab
    # application/vnd.ms-color.iccprofile
    application/vnd.ms-excel			xls xlm xla xlc xlt xlw
    application/vnd.ms-excel.addin.macroenabled.12		xlam
    application/vnd.ms-excel.sheet.binary.macroenabled.12	xlsb
    application/vnd.ms-excel.sheet.macroenabled.12		xlsm
    application/vnd.ms-excel.template.macroenabled.12	xltm
    application/vnd.ms-fontobject			eot
    application/vnd.ms-htmlhelp			chm
    application/vnd.ms-ims				ims
    application/vnd.ms-lrm				lrm
    # application/vnd.ms-office.activex+xml
    application/vnd.ms-officetheme			thmx
    # application/vnd.ms-opentype
    # application/vnd.ms-package.obfuscated-opentype
    application/vnd.ms-pki.seccat			cat
    application/vnd.ms-pki.stl			stl
    # application/vnd.ms-playready.initiator+xml
    application/vnd.ms-powerpoint			ppt pps pot
    application/vnd.ms-powerpoint.addin.macroenabled.12		ppam
    application/vnd.ms-powerpoint.presentation.macroenabled.12	pptm
    application/vnd.ms-powerpoint.slide.macroenabled.12		sldm
    application/vnd.ms-powerpoint.slideshow.macroenabled.12		ppsm
    application/vnd.ms-powerpoint.template.macroenabled.12		potm
    # application/vnd.ms-printing.printticket+xml
    application/vnd.ms-project			mpp mpt
    # application/vnd.ms-tnef
    # application/vnd.ms-wmdrm.lic-chlg-req
    # application/vnd.ms-wmdrm.lic-resp
    # application/vnd.ms-wmdrm.meter-chlg-req
    # application/vnd.ms-wmdrm.meter-resp
    application/vnd.ms-word.document.macroenabled.12	docm
    application/vnd.ms-word.template.macroenabled.12	dotm
    application/vnd.ms-works			wps wks wcm wdb
    application/vnd.ms-wpl				wpl
    application/vnd.ms-xpsdocument			xps
    application/vnd.mseq				mseq
    # application/vnd.msign
    # application/vnd.multiad.creator
    # application/vnd.multiad.creator.cif
    # application/vnd.music-niff
    application/vnd.musician			mus
    application/vnd.muvee.style			msty
    application/vnd.mynfc				taglet
    # application/vnd.ncd.control
    # application/vnd.ncd.reference
    # application/vnd.nervana
    # application/vnd.netfpx
    application/vnd.neurolanguage.nlu		nlu
    application/vnd.nitf				ntf nitf
    application/vnd.noblenet-directory		nnd
    application/vnd.noblenet-sealer			nns
    application/vnd.noblenet-web			nnw
    # application/vnd.nokia.catalogs
    # application/vnd.nokia.conml+wbxml
    # application/vnd.nokia.conml+xml
    # application/vnd.nokia.isds-radio-presets
    # application/vnd.nokia.iptv.config+xml
    # application/vnd.nokia.landmark+wbxml
    # application/vnd.nokia.landmark+xml
    # application/vnd.nokia.landmarkcollection+xml
    # application/vnd.nokia.n-gage.ac+xml
    application/vnd.nokia.n-gage.data		ngdat
    application/vnd.nokia.n-gage.symbian.install	n-gage
    # application/vnd.nokia.ncd
    # application/vnd.nokia.pcd+wbxml
    # application/vnd.nokia.pcd+xml
    application/vnd.nokia.radio-preset		rpst
    application/vnd.nokia.radio-presets		rpss
    application/vnd.novadigm.edm			edm
    application/vnd.novadigm.edx			edx
    application/vnd.novadigm.ext			ext
    # application/vnd.ntt-local.file-transfer
    # application/vnd.ntt-local.sip-ta_remote
    # application/vnd.ntt-local.sip-ta_tcp_stream
    application/vnd.oasis.opendocument.chart		odc
    application/vnd.oasis.opendocument.chart-template	otc
    application/vnd.oasis.opendocument.database		odb
    application/vnd.oasis.opendocument.formula		odf
    application/vnd.oasis.opendocument.formula-template	odft
    application/vnd.oasis.opendocument.graphics		odg
    application/vnd.oasis.opendocument.graphics-template	otg
    application/vnd.oasis.opendocument.image		odi
    application/vnd.oasis.opendocument.image-template	oti
    application/vnd.oasis.opendocument.presentation		odp
    application/vnd.oasis.opendocument.presentation-template	otp
    application/vnd.oasis.opendocument.spreadsheet		ods
    application/vnd.oasis.opendocument.spreadsheet-template	ots
    application/vnd.oasis.opendocument.text			odt
    application/vnd.oasis.opendocument.text-master		odm
    application/vnd.oasis.opendocument.text-template	ott
    application/vnd.oasis.opendocument.text-web		oth
    # application/vnd.obn
    # application/vnd.oftn.l10n+json
    # application/vnd.oipf.contentaccessdownload+xml
    # application/vnd.oipf.contentaccessstreaming+xml
    # application/vnd.oipf.cspg-hexbinary
    # application/vnd.oipf.dae.svg+xml
    # application/vnd.oipf.dae.xhtml+xml
    # application/vnd.oipf.mippvcontrolmessage+xml
    # application/vnd.oipf.pae.gem
    # application/vnd.oipf.spdiscovery+xml
    # application/vnd.oipf.spdlist+xml
    # application/vnd.oipf.ueprofile+xml
    # application/vnd.oipf.userprofile+xml
    application/vnd.olpc-sugar			xo
    # application/vnd.oma-scws-config
    # application/vnd.oma-scws-http-request
    # application/vnd.oma-scws-http-response
    # application/vnd.oma.bcast.associated-procedure-parameter+xml
    # application/vnd.oma.bcast.drm-trigger+xml
    # application/vnd.oma.bcast.imd+xml
    # application/vnd.oma.bcast.ltkm
    # application/vnd.oma.bcast.notification+xml
    # application/vnd.oma.bcast.provisioningtrigger
    # application/vnd.oma.bcast.sgboot
    # application/vnd.oma.bcast.sgdd+xml
    # application/vnd.oma.bcast.sgdu
    # application/vnd.oma.bcast.simple-symbol-container
    # application/vnd.oma.bcast.smartcard-trigger+xml
    # application/vnd.oma.bcast.sprov+xml
    # application/vnd.oma.bcast.stkm
    # application/vnd.oma.cab-address-book+xml
    # application/vnd.oma.cab-feature-handler+xml
    # application/vnd.oma.cab-pcc+xml
    # application/vnd.oma.cab-user-prefs+xml
    # application/vnd.oma.dcd
    # application/vnd.oma.dcdc
    application/vnd.oma.dd2+xml			dd2
    # application/vnd.oma.drm.risd+xml
    # application/vnd.oma.group-usage-list+xml
    # application/vnd.oma.pal+xml
    # application/vnd.oma.poc.detailed-progress-report+xml
    # application/vnd.oma.poc.final-report+xml
    # application/vnd.oma.poc.groups+xml
    # application/vnd.oma.poc.invocation-descriptor+xml
    # application/vnd.oma.poc.optimized-progress-report+xml
    # application/vnd.oma.push
    # application/vnd.oma.scidm.messages+xml
    # application/vnd.oma.xcap-directory+xml
    # application/vnd.omads-email+xml
    # application/vnd.omads-file+xml
    # application/vnd.omads-folder+xml
    # application/vnd.omaloc-supl-init
    application/vnd.openofficeorg.extension		oxt
    # application/vnd.openxmlformats-officedocument.custom-properties+xml
    # application/vnd.openxmlformats-officedocument.customxmlproperties+xml
    # application/vnd.openxmlformats-officedocument.drawing+xml
    # application/vnd.openxmlformats-officedocument.drawingml.chart+xml
    # application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml
    # application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml
    # application/vnd.openxmlformats-officedocument.extended-properties+xml
    # application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml
    # application/vnd.openxmlformats-officedocument.presentationml.comments+xml
    # application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml
    # application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml
    # application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml
    application/vnd.openxmlformats-officedocument.presentationml.presentation	pptx
    # application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
    # application/vnd.openxmlformats-officedocument.presentationml.presprops+xml
    application/vnd.openxmlformats-officedocument.presentationml.slide	sldx
    # application/vnd.openxmlformats-officedocument.presentationml.slide+xml
    # application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml
    # application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml
    application/vnd.openxmlformats-officedocument.presentationml.slideshow	ppsx
    # application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
    # application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml
    # application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml
    # application/vnd.openxmlformats-officedocument.presentationml.tags+xml
    application/vnd.openxmlformats-officedocument.presentationml.template	potx
    # application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
    # application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet	xlsx
    # application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml
    application/vnd.openxmlformats-officedocument.spreadsheetml.template	xltx
    # application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml
    # application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
    # application/vnd.openxmlformats-officedocument.theme+xml
    # application/vnd.openxmlformats-officedocument.themeoverride+xml
    # application/vnd.openxmlformats-officedocument.vmldrawing
    # application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
    application/vnd.openxmlformats-officedocument.wordprocessingml.document	docx
    # application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
    application/vnd.openxmlformats-officedocument.wordprocessingml.template	dotx
    # application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
    # application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml
    # application/vnd.openxmlformats-package.core-properties+xml
    # application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
    # application/vnd.openxmlformats-package.relationships+xml
    # application/vnd.quobject-quoxdocument
    # application/vnd.osa.netdeploy
    application/vnd.osgeo.mapguide.package		mgp
    # application/vnd.osgi.bundle
    application/vnd.osgi.dp				dp
    application/vnd.osgi.subsystem			esa
    # application/vnd.otps.ct-kip+xml
    application/vnd.palm				pdb pqa oprc
    # application/vnd.paos.xml
    application/vnd.pawaafile			paw
    application/vnd.pg.format			str
    application/vnd.pg.osasli			ei6
    # application/vnd.piaccess.application-licence
    application/vnd.picsel				efif
    application/vnd.pmi.widget			wg
    # application/vnd.poc.group-advertisement+xml
    application/vnd.pocketlearn			plf
    application/vnd.powerbuilder6			pbd
    # application/vnd.powerbuilder6-s
    # application/vnd.powerbuilder7
    # application/vnd.powerbuilder7-s
    # application/vnd.powerbuilder75
    # application/vnd.powerbuilder75-s
    # application/vnd.preminet
    application/vnd.previewsystems.box		box
    application/vnd.proteus.magazine		mgz
    application/vnd.publishare-delta-tree		qps
    application/vnd.pvi.ptid1			ptid
    # application/vnd.pwg-multiplexed
    # application/vnd.pwg-xhtml-print+xml
    # application/vnd.qualcomm.brew-app-res
    application/vnd.quark.quarkxpress		qxd qxt qwd qwt qxl qxb
    # application/vnd.radisys.moml+xml
    # application/vnd.radisys.msml+xml
    # application/vnd.radisys.msml-audit+xml
    # application/vnd.radisys.msml-audit-conf+xml
    # application/vnd.radisys.msml-audit-conn+xml
    # application/vnd.radisys.msml-audit-dialog+xml
    # application/vnd.radisys.msml-audit-stream+xml
    # application/vnd.radisys.msml-conf+xml
    # application/vnd.radisys.msml-dialog+xml
    # application/vnd.radisys.msml-dialog-base+xml
    # application/vnd.radisys.msml-dialog-fax-detect+xml
    # application/vnd.radisys.msml-dialog-fax-sendrecv+xml
    # application/vnd.radisys.msml-dialog-group+xml
    # application/vnd.radisys.msml-dialog-speech+xml
    # application/vnd.radisys.msml-dialog-transform+xml
    # application/vnd.rainstor.data
    # application/vnd.rapid
    application/vnd.realvnc.bed			bed
    application/vnd.recordare.musicxml		mxl
    application/vnd.recordare.musicxml+xml		musicxml
    # application/vnd.renlearn.rlprint
    application/vnd.rig.cryptonote			cryptonote
    application/vnd.rim.cod				cod
    application/vnd.rn-realmedia			rm
    application/vnd.rn-realmedia-vbr		rmvb
    application/vnd.route66.link66+xml		link66
    # application/vnd.rs-274x
    # application/vnd.ruckus.download
    # application/vnd.s3sms
    application/vnd.sailingtracker.track		st
    # application/vnd.sbm.cid
    # application/vnd.sbm.mid2
    # application/vnd.scribus
    # application/vnd.sealed.3df
    # application/vnd.sealed.csf
    # application/vnd.sealed.doc
    # application/vnd.sealed.eml
    # application/vnd.sealed.mht
    # application/vnd.sealed.net
    # application/vnd.sealed.ppt
    # application/vnd.sealed.tiff
    # application/vnd.sealed.xls
    # application/vnd.sealedmedia.softseal.html
    # application/vnd.sealedmedia.softseal.pdf
    application/vnd.seemail				see
    application/vnd.sema				sema
    application/vnd.semd				semd
    application/vnd.semf				semf
    application/vnd.shana.informed.formdata		ifm
    application/vnd.shana.informed.formtemplate	itp
    application/vnd.shana.informed.interchange	iif
    application/vnd.shana.informed.package		ipk
    application/vnd.simtech-mindmapper		twd twds
    application/vnd.smaf				mmf
    # application/vnd.smart.notebook
    application/vnd.smart.teacher			teacher
    # application/vnd.software602.filler.form+xml
    # application/vnd.software602.filler.form-xml-zip
    application/vnd.solent.sdkm+xml			sdkm sdkd
    application/vnd.spotfire.dxp			dxp
    application/vnd.spotfire.sfs			sfs
    # application/vnd.sss-cod
    # application/vnd.sss-dtf
    # application/vnd.sss-ntf
    application/vnd.stardivision.calc		sdc
    application/vnd.stardivision.draw		sda
    application/vnd.stardivision.impress		sdd
    application/vnd.stardivision.math		smf
    application/vnd.stardivision.writer		sdw vor
    application/vnd.stardivision.writer-global	sgl
    application/vnd.stepmania.package		smzip
    application/vnd.stepmania.stepchart		sm
    # application/vnd.street-stream
    application/vnd.sun.xml.calc			sxc
    application/vnd.sun.xml.calc.template		stc
    application/vnd.sun.xml.draw			sxd
    application/vnd.sun.xml.draw.template		std
    application/vnd.sun.xml.impress			sxi
    application/vnd.sun.xml.impress.template	sti
    application/vnd.sun.xml.math			sxm
    application/vnd.sun.xml.writer			sxw
    application/vnd.sun.xml.writer.global		sxg
    application/vnd.sun.xml.writer.template		stw
    # application/vnd.sun.wadl+xml
    application/vnd.sus-calendar			sus susp
    application/vnd.svd				svd
    # application/vnd.swiftview-ics
    application/vnd.symbian.install			sis sisx
    application/vnd.syncml+xml			xsm
    application/vnd.syncml.dm+wbxml			bdm
    application/vnd.syncml.dm+xml			xdm
    # application/vnd.syncml.dm.notification
    # application/vnd.syncml.ds.notification
    application/vnd.tao.intent-module-archive	tao
    application/vnd.tcpdump.pcap			pcap cap dmp
    application/vnd.tmobile-livetv			tmo
    application/vnd.trid.tpt			tpt
    application/vnd.triscape.mxs			mxs
    application/vnd.trueapp				tra
    # application/vnd.truedoc
    # application/vnd.ubisoft.webplayer
    application/vnd.ufdl				ufd ufdl
    application/vnd.uiq.theme			utz
    application/vnd.umajin				umj
    application/vnd.unity				unityweb
    application/vnd.uoml+xml			uoml
    # 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				vcx
    # application/vnd.vd-study
    # application/vnd.vectorworks
    # application/vnd.verimatrix.vcas
    # application/vnd.vidsoft.vidconference
    application/vnd.visio				vsd vst vss vsw
    application/vnd.visionary			vis
    # application/vnd.vividence.scriptfile
    application/vnd.vsf				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			wtb
    # application/vnd.wfa.wsc
    # application/vnd.wmc
    # application/vnd.wmf.bootstrap
    # application/vnd.wolfram.mathematica
    # application/vnd.wolfram.mathematica.package
    application/vnd.wolfram.player			nbp
    application/vnd.wordperfect			wpd
    application/vnd.wqd				wqd
    # application/vnd.wrq-hp3000-labelled
    application/vnd.wt.stf				stf
    # application/vnd.wv.csp+wbxml
    # application/vnd.wv.csp+xml
    # application/vnd.wv.ssp+xml
    application/vnd.xara				xar
    application/vnd.xfdl				xfdl
    # application/vnd.xfdl.webform
    # application/vnd.xmi+xml
    # application/vnd.xmpie.cpkg
    # application/vnd.xmpie.dpkg
    # application/vnd.xmpie.plan
    # application/vnd.xmpie.ppkg
    # application/vnd.xmpie.xlim
    application/vnd.yamaha.hv-dic			hvd
    application/vnd.yamaha.hv-script		hvs
    application/vnd.yamaha.hv-voice			hvp
    application/vnd.yamaha.openscoreformat			osf
    application/vnd.yamaha.openscoreformat.osfpvg+xml	osfpvg
    # application/vnd.yamaha.remote-setup
    application/vnd.yamaha.smaf-audio		saf
    application/vnd.yamaha.smaf-phrase		spf
    # application/vnd.yamaha.through-ngn
    # application/vnd.yamaha.tunnel-udpencap
    application/vnd.yellowriver-custom-menu		cmp
    application/vnd.zul				zir zirz
    application/vnd.zzazz.deck+xml			zaz
    application/voicexml+xml			vxml
    # application/vq-rtcpxr
    # application/watcherinfo+xml
    # application/whoispp-query
    # application/whoispp-response
    application/widget				wgt
    application/winhlp				hlp
    # application/wita
    # application/wordperfect5.1
    application/wsdl+xml				wsdl
    application/wspolicy+xml			wspolicy
    application/x-7z-compressed			7z
    application/x-abiword				abw
    application/x-ace-compressed			ace
    # application/x-amf
    application/x-apple-diskimage			dmg
    application/x-authorware-bin			aab x32 u32 vox
    application/x-authorware-map			aam
    application/x-authorware-seg			aas
    application/x-bcpio				bcpio
    application/x-bittorrent			torrent
    application/x-blorb				blb blorb
    application/x-bzip				bz
    application/x-bzip2				bz2 boz
    application/x-cbr				cbr cba cbt cbz cb7
    application/x-cdlink				vcd
    application/x-cfs-compressed			cfs
    application/x-chat				chat
    application/x-chess-pgn				pgn
    application/x-conference			nsc
    # application/x-compress
    application/x-cpio				cpio
    application/x-csh				csh
    application/x-debian-package			deb udeb
    application/x-dgc-compressed			dgc
    application/x-director			dir dcr dxr cst cct cxt w3d fgd swa
    application/x-doom				wad
    application/x-dtbncx+xml			ncx
    application/x-dtbook+xml			dtb
    application/x-dtbresource+xml			res
    application/x-dvi				dvi
    application/x-envoy				evy
    application/x-eva				eva
    application/x-font-bdf				bdf
    # application/x-font-dos
    # application/x-font-framemaker
    application/x-font-ghostscript			gsf
    # application/x-font-libgrx
    application/x-font-linux-psf			psf
    application/x-font-otf				otf
    application/x-font-pcf				pcf
    application/x-font-snf				snf
    # application/x-font-speedo
    # application/x-font-sunos-news
    application/x-font-ttf				ttf ttc
    application/x-font-type1			pfa pfb pfm afm
    application/x-font-woff				woff
    # application/x-font-vfont
    application/x-freearc				arc
    application/x-futuresplash			spl
    application/x-gca-compressed			gca
    application/x-glulx				ulx
    application/x-gnumeric				gnumeric
    application/x-gramps-xml			gramps
    application/x-gtar				gtar
    # application/x-gzip
    application/x-hdf				hdf
    application/x-install-instructions		install
    application/x-iso9660-image			iso
    application/x-java-jnlp-file			jnlp
    application/x-latex				latex
    application/x-lzh-compressed			lzh lha
    application/x-mie				mie
    application/x-mobipocket-ebook			prc mobi
    application/x-ms-application			application
    application/x-ms-shortcut			lnk
    application/x-ms-wmd				wmd
    application/x-ms-wmz				wmz
    application/x-ms-xbap				xbap
    application/x-msaccess				mdb
    application/x-msbinder				obd
    application/x-mscardfile			crd
    application/x-msclip				clp
    application/x-msdownload			exe dll com bat msi
    application/x-msmediaview			mvb m13 m14
    application/x-msmetafile			wmf wmz emf emz
    application/x-msmoney				mny
    application/x-mspublisher			pub
    application/x-msschedule			scd
    application/x-msterminal			trm
    application/x-mswrite				wri
    application/x-netcdf				nc cdf
    application/x-nzb				nzb
    application/x-pkcs12				p12 pfx
    application/x-pkcs7-certificates		p7b spc
    application/x-pkcs7-certreqresp			p7r
    application/x-rar-compressed			rar
    application/x-research-info-systems		ris
    application/x-sh				sh
    application/x-shar				shar
    application/x-shockwave-flash			swf
    application/x-silverlight-app			xap
    application/x-sql				sql
    application/x-stuffit				sit
    application/x-stuffitx				sitx
    application/x-subrip				srt
    application/x-sv4cpio				sv4cpio
    application/x-sv4crc				sv4crc
    application/x-t3vm-image			t3
    application/x-tads				gam
    application/x-tar				tar
    application/x-tcl				tcl
    application/x-tex				tex
    application/x-tex-tfm				tfm
    application/x-texinfo				texinfo texi
    application/x-tgif				obj
    application/x-ustar				ustar
    application/x-wais-source			src
    application/x-x509-ca-cert			der crt
    application/x-xfig				fig
    application/x-xliff+xml				xlf
    application/x-xpinstall				xpi
    application/x-xz				xz
    application/x-zmachine				z1 z2 z3 z4 z5 z6 z7 z8
    # application/x400-bp
    application/xaml+xml				xaml
    # application/xcap-att+xml
    # application/xcap-caps+xml
    application/xcap-diff+xml			xdf
    # application/xcap-el+xml
    # application/xcap-error+xml
    # application/xcap-ns+xml
    # application/xcon-conference-info-diff+xml
    # application/xcon-conference-info+xml
    application/xenc+xml				xenc
    application/xhtml+xml				xhtml xht
    # application/xhtml-voice+xml
    application/xml					xml xsl
    application/xml-dtd				dtd
    # application/xml-external-parsed-entity
    # application/xmpp+xml
    application/xop+xml				xop
    application/xproc+xml				xpl
    application/xslt+xml				xslt
    application/xspf+xml				xspf
    application/xv+xml				mxml xhvml xvml xvm
    application/yang				yang
    application/yin+xml				yin
    application/zip					zip
    # audio/1d-interleaved-parityfec
    # audio/32kadpcm
    # audio/3gpp
    # audio/3gpp2
    # audio/ac3
    audio/adpcm					adp
    # audio/amr
    # audio/amr-wb
    # audio/amr-wb+
    # audio/asc
    # audio/atrac-advanced-lossless
    # audio/atrac-x
    # audio/atrac3
    audio/basic					au snd
    # audio/bv16
    # audio/bv32
    # audio/clearmode
    # audio/cn
    # audio/dat12
    # audio/dls
    # audio/dsr-es201108
    # audio/dsr-es202050
    # audio/dsr-es202211
    # audio/dsr-es202212
    # audio/dv
    # audio/dvi4
    # audio/eac3
    # audio/evrc
    # audio/evrc-qcp
    # audio/evrc0
    # audio/evrc1
    # audio/evrcb
    # audio/evrcb0
    # audio/evrcb1
    # audio/evrcwb
    # audio/evrcwb0
    # audio/evrcwb1
    # audio/example
    # audio/fwdred
    # audio/g719
    # audio/g722
    # audio/g7221
    # audio/g723
    # audio/g726-16
    # audio/g726-24
    # audio/g726-32
    # audio/g726-40
    # audio/g728
    # audio/g729
    # audio/g7291
    # audio/g729d
    # audio/g729e
    # audio/gsm
    # audio/gsm-efr
    # audio/gsm-hr-08
    # audio/ilbc
    # audio/ip-mr_v2.5
    # audio/isac
    # audio/l16
    # audio/l20
    # audio/l24
    # audio/l8
    # audio/lpc
    audio/midi					mid midi kar rmi
    # audio/mobile-xmf
    audio/mp4					mp4a
    # audio/mp4a-latm
    # audio/mpa
    # audio/mpa-robust
    audio/mpeg					mpga mp2 mp2a mp3 m2a m3a
    # audio/mpeg4-generic
    # audio/musepack
    audio/ogg					oga ogg spx
    # audio/opus
    # audio/parityfec
    # audio/pcma
    # audio/pcma-wb
    # audio/pcmu-wb
    # audio/pcmu
    # audio/prs.sid
    # audio/qcelp
    # audio/red
    # audio/rtp-enc-aescm128
    # audio/rtp-midi
    # audio/rtx
    audio/s3m					s3m
    audio/silk					sil
    # audio/smv
    # audio/smv0
    # audio/smv-qcp
    # audio/sp-midi
    # audio/speex
    # audio/t140c
    # audio/t38
    # audio/telephone-event
    # audio/tone
    # audio/uemclip
    # audio/ulpfec
    # audio/vdvi
    # audio/vmr-wb
    # audio/vnd.3gpp.iufp
    # audio/vnd.4sb
    # audio/vnd.audiokoz
    # audio/vnd.celp
    # audio/vnd.cisco.nse
    # audio/vnd.cmles.radio-events
    # audio/vnd.cns.anp1
    # audio/vnd.cns.inf1
    audio/vnd.dece.audio				uva uvva
    audio/vnd.digital-winds				eol
    # audio/vnd.dlna.adts
    # audio/vnd.dolby.heaac.1
    # audio/vnd.dolby.heaac.2
    # audio/vnd.dolby.mlp
    # audio/vnd.dolby.mps
    # audio/vnd.dolby.pl2
    # audio/vnd.dolby.pl2x
    # audio/vnd.dolby.pl2z
    # audio/vnd.dolby.pulse.1
    audio/vnd.dra					dra
    audio/vnd.dts					dts
    audio/vnd.dts.hd				dtshd
    # audio/vnd.dvb.file
    # audio/vnd.everad.plj
    # audio/vnd.hns.audio
    audio/vnd.lucent.voice				lvp
    audio/vnd.ms-playready.media.pya		pya
    # audio/vnd.nokia.mobile-xmf
    # audio/vnd.nortel.vbk
    audio/vnd.nuera.ecelp4800			ecelp4800
    audio/vnd.nuera.ecelp7470			ecelp7470
    audio/vnd.nuera.ecelp9600			ecelp9600
    # audio/vnd.octel.sbc
    # audio/vnd.qcelp
    # audio/vnd.rhetorex.32kadpcm
    audio/vnd.rip					rip
    # audio/vnd.sealedmedia.softseal.mpeg
    # audio/vnd.vmx.cvsd
    # audio/vorbis
    # audio/vorbis-config
    audio/webm					weba
    audio/x-aac					aac
    audio/x-aiff					aif aiff aifc
    audio/x-caf					caf
    audio/x-flac					flac
    audio/x-matroska				mka
    audio/x-mpegurl					m3u
    audio/x-ms-wax					wax
    audio/x-ms-wma					wma
    audio/x-pn-realaudio				ram ra
    audio/x-pn-realaudio-plugin			rmp
    # audio/x-tta
    audio/x-wav					wav
    audio/xm					xm
    chemical/x-cdx					cdx
    chemical/x-cif					cif
    chemical/x-cmdf					cmdf
    chemical/x-cml					cml
    chemical/x-csml					csml
    # chemical/x-pdb
    chemical/x-xyz					xyz
    image/bmp					bmp
    image/cgm					cgm
    # image/example
    # image/fits
    image/g3fax					g3
    image/gif					gif
    image/ief					ief
    # image/jp2
    image/jpeg					jpeg jpg jpe
    # image/jpm
    # image/jpx
    image/jxl					jxl
    image/ktx					ktx
    # image/naplps
    image/png					png
    image/prs.btif					btif
    # image/prs.pti
    image/sgi					sgi
    image/svg+xml					svg svgz
    # image/t38
    image/tiff					tiff tif
    # image/tiff-fx
    image/vnd.adobe.photoshop			psd
    # image/vnd.cns.inf2
    image/vnd.dece.graphic				uvi uvvi uvg uvvg
    image/vnd.dvb.subtitle				sub
    image/vnd.djvu					djvu djv
    image/vnd.dwg					dwg
    image/vnd.dxf					dxf
    image/vnd.fastbidsheet				fbs
    image/vnd.fpx					fpx
    image/vnd.fst					fst
    image/vnd.fujixerox.edmics-mmr			mmr
    image/vnd.fujixerox.edmics-rlc			rlc
    # image/vnd.globalgraphics.pgb
    # image/vnd.microsoft.icon
    # image/vnd.mix
    image/vnd.ms-modi				mdi
    image/vnd.ms-photo				wdp
    image/vnd.net-fpx				npx
    # image/vnd.radiance
    # image/vnd.sealed.png
    # image/vnd.sealedmedia.softseal.gif
    # image/vnd.sealedmedia.softseal.jpg
    # image/vnd.svf
    image/vnd.wap.wbmp				wbmp
    image/vnd.xiff					xif
    image/webp					webp
    image/x-3ds					3ds
    image/x-cmu-raster				ras
    image/x-cmx					cmx
    image/x-freehand				fh fhc fh4 fh5 fh7
    image/x-icon					ico
    image/x-mrsid-image				sid
    image/x-pcx					pcx
    image/x-pict					pic pct
    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-tga					tga
    image/x-xbitmap					xbm
    image/x-xpixmap					xpm
    image/x-xwindowdump				xwd
    # message/cpim
    # message/delivery-status
    # message/disposition-notification
    # message/example
    # message/external-body
    # message/feedback-report
    # message/global
    # message/global-delivery-status
    # message/global-disposition-notification
    # message/global-headers
    # message/http
    # message/imdn+xml
    # message/news
    # message/partial
    message/rfc822					eml mime
    # message/s-http
    # message/sip
    # message/sipfrag
    # message/tracking-status
    # message/vnd.si.simp
    # model/example
    model/iges					igs iges
    model/mesh					msh mesh silo
    model/vnd.collada+xml				dae
    model/vnd.dwf					dwf
    # model/vnd.flatland.3dml
    model/vnd.gdl					gdl
    # model/vnd.gs-gdl
    # model/vnd.gs.gdl
    model/vnd.gtw					gtw
    # model/vnd.moml+xml
    model/vnd.mts					mts
    # model/vnd.parasolid.transmit.binary
    # model/vnd.parasolid.transmit.text
    model/vnd.vtu					vtu
    model/vrml					wrl vrml
    model/x3d+binary				x3db x3dbz
    model/x3d+vrml					x3dv x3dvz
    model/x3d+xml					x3d x3dz
    # multipart/alternative
    # multipart/appledouble
    # multipart/byteranges
    # multipart/digest
    # multipart/encrypted
    # multipart/example
    # multipart/form-data
    # multipart/header-set
    # multipart/mixed
    # multipart/parallel
    # multipart/related
    # multipart/report
    # multipart/signed
    # multipart/voice-message
    # text/1d-interleaved-parityfec
    text/cache-manifest				appcache
    text/calendar					ics ifb
    text/css					css
    text/csv					csv
    # text/directory
    # text/dns
    # text/ecmascript
    # text/enriched
    # text/example
    # text/fwdred
    text/html					html htm
    # text/javascript
    text/n3						n3
    # text/parityfec
    text/plain					txt text conf def list log in
    # text/prs.fallenstein.rst
    text/prs.lines.tag				dsc
    # text/vnd.radisys.msml-basic-layout
    # text/red
    # text/rfc822-headers
    text/richtext					rtx
    # text/rtf
    # text/rtp-enc-aescm128
    # text/rtx
    text/sgml					sgml sgm
    # text/t140
    text/tab-separated-values			tsv
    text/troff					t tr roff man me ms
    text/turtle					ttl
    # text/ulpfec
    text/uri-list					uri uris urls
    text/vcard					vcard
    # text/vnd.abc
    text/vnd.curl					curl
    text/vnd.curl.dcurl				dcurl
    text/vnd.curl.scurl				scurl
    text/vnd.curl.mcurl				mcurl
    # text/vnd.dmclientscript
    text/vnd.dvb.subtitle				sub
    # text/vnd.esmertec.theme-descriptor
    text/vnd.fly					fly
    text/vnd.fmi.flexstor				flx
    text/vnd.graphviz				gv
    text/vnd.in3d.3dml				3dml
    text/vnd.in3d.spot				spot
    # text/vnd.iptc.newsml
    # text/vnd.iptc.nitf
    # text/vnd.latex-z
    # text/vnd.motorola.reflex
    # text/vnd.ms-mediapackage
    # text/vnd.net2phone.commcenter.command
    # text/vnd.si.uricatalogue
    text/vnd.sun.j2me.app-descriptor		jad
    # text/vnd.trolltech.linguist
    # text/vnd.wap.si
    # text/vnd.wap.sl
    text/vnd.wap.wml				wml
    text/vnd.wap.wmlscript				wmls
    text/x-asm					s asm
    text/x-c					c cc cxx cpp h hh dic
    text/x-fortran					f for f77 f90
    text/x-java-source				java
    text/x-opml					opml
    text/x-pascal					p pas
    text/x-nfo					nfo
    text/x-setext					etx
    text/x-sfv					sfv
    text/x-uuencode					uu
    text/x-vcalendar				vcs
    text/x-vcard					vcf
    # text/xml
    # text/xml-external-parsed-entity
    # video/1d-interleaved-parityfec
    video/3gpp					3gp
    # video/3gpp-tt
    video/3gpp2					3g2
    # video/bmpeg
    # video/bt656
    # video/celb
    # video/dv
    # video/example
    video/h261					h261
    video/h263					h263
    # video/h263-1998
    # video/h263-2000
    video/h264					h264
    # video/h264-rcdo
    # video/h264-svc
    video/jpeg					jpgv
    # video/jpeg2000
    video/jpm					jpm jpgm
    video/mj2					mj2 mjp2
    # video/mp1s
    # video/mp2p
    # video/mp2t
    video/mp4					mp4 mp4v mpg4
    # video/mp4v-es
    video/mpeg					mpeg mpg mpe m1v m2v
    # video/mpeg4-generic
    # video/mpv
    # video/nv
    video/ogg					ogv
    # video/parityfec
    # video/pointer
    video/quicktime					qt mov
    # video/raw
    # video/rtp-enc-aescm128
    # video/rtx
    # video/smpte292m
    # video/ulpfec
    # video/vc1
    # video/vnd.cctv
    video/vnd.dece.hd				uvh uvvh
    video/vnd.dece.mobile				uvm uvvm
    # video/vnd.dece.mp4
    video/vnd.dece.pd				uvp uvvp
    video/vnd.dece.sd				uvs uvvs
    video/vnd.dece.video				uvv uvvv
    # video/vnd.directv.mpeg
    # video/vnd.directv.mpeg-tts
    # video/vnd.dlna.mpeg-tts
    video/vnd.dvb.file				dvb
    video/vnd.fvt					fvt
    # video/vnd.hns.video
    # video/vnd.iptvforum.1dparityfec-1010
    # video/vnd.iptvforum.1dparityfec-2005
    # video/vnd.iptvforum.2dparityfec-1010
    # video/vnd.iptvforum.2dparityfec-2005
    # video/vnd.iptvforum.ttsavc
    # video/vnd.iptvforum.ttsmpeg2
    # video/vnd.motorola.video
    # video/vnd.motorola.videop
    video/vnd.mpegurl				mxu m4u
    video/vnd.ms-playready.media.pyv		pyv
    # video/vnd.nokia.interleaved-multimedia
    # video/vnd.nokia.videovoip
    # video/vnd.objectvideo
    # video/vnd.sealed.mpeg1
    # video/vnd.sealed.mpeg4
    # video/vnd.sealed.swf
    # video/vnd.sealedmedia.softseal.mov
    video/vnd.uvvu.mp4				uvu uvvu
    video/vnd.vivo					viv
    video/webm					webm
    video/x-f4v					f4v
    video/x-fli					fli
    video/x-flv					flv
    video/x-m4v					m4v
    video/x-matroska				mkv mk3d mks
    video/x-mng					mng
    video/x-ms-asf					asf asx
    video/x-ms-vob					vob
    video/x-ms-wm					wm
    video/x-ms-wmv					wmv
    video/x-ms-wmx					wmx
    video/x-ms-wvx					wvx
    video/x-msvideo					avi
    video/x-sgi-movie				movie
    video/x-smv					smv
    x-conference/x-cooltalk				ice
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/mod_aptest/���������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017446� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/mod_aptest/mod_aptest.c���������������������������������������������������0000664�0001751�0001751�00000004105�14356741666�021761� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <apr_optional_hooks.h>
    #include <apr_strings.h>
    #include <apr_cstr.h>
    #include <apr_want.h>
    
    #include <httpd.h>
    #include <http_protocol.h>
    #include <http_request.h>
    #include <http_log.h>
    
    static void aptest_hooks(apr_pool_t *pool);
    
    AP_DECLARE_MODULE(aptest) = {
        STANDARD20_MODULE_STUFF,
        NULL, /* func to create per dir config */
        NULL,  /* func to merge per dir config */
        NULL, /* func to create per server config */
        NULL,  /* func to merge per server config */
        NULL,              /* command handlers */
        aptest_hooks,
    #if defined(AP_MODULE_FLAG_NONE)
        AP_MODULE_FLAG_ALWAYS_MERGE
    #endif
    };
    
    
    static int aptest_post_read_request(request_rec *r)
    {
        const char *test_name = apr_table_get(r->headers_in, "AP-Test-Name");
        if (test_name) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "test[%s]: %s",
                          test_name, r->the_request);
        }
        return DECLINED;
    }
    
    /* Install this module into the apache2 infrastructure.
     */
    static void aptest_hooks(apr_pool_t *pool)
    {
        ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool,
                      "installing hooks and handlers");
    
        /* test case monitoring */
        ap_hook_post_read_request(aptest_post_read_request, NULL,
                                  NULL, APR_HOOK_MIDDLE);
    
    }
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/�������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016573� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/�������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017633� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/003/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020135� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/003/003_img.jpg����������������������������������������������0000664�0001751�0001751�00000260374�14156077574�022017� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF�,,��XICC_PROFILE���HLino��mntrRGB XYZ ��	��1��acspMSFT����IEC sRGB������������������-HP  �����������������������������������������������cprt��P���3desc�����lwtpt�����bkpt�����rXYZ�����gXYZ��,���bXYZ��@���dmnd��T���pdmdd�����vued��L���view�����$lumi�����meas�����$tech��0���rTRC��<��gTRC��<��bTRC��<��text����Copyright (c) 1998 Hewlett-Packard Company��desc�������sRGB IEC61966-2.1�����������sRGB IEC61966-2.1��������������������������������������������������XYZ ������Q����XYZ ����������������XYZ ������o��8��XYZ ������b����XYZ ������$����desc�������IEC http://www.iec.ch�����������IEC http://www.iec.ch����������������������������������������������desc�������.IEC 61966-2.1 Default RGB colour space - sRGB�����������.IEC 61966-2.1 Default RGB colour space - sRGB����������������������desc�������,Reference Viewing Condition in IEC61966-2.1�����������,Reference Viewing Condition in IEC61966-2.1��������������������������view������_.����\���XYZ �����L	V�P���Wmeas����������������������������sig ����CRT curv�����������
    �����#�(�-�2�7�;�@�E�J�O�T�Y�^�c�h�m�r�w�|�������������������������
    %+28>ELRY`gnu|&/8AKT]gqz�!-8COZfr~ -;HUcq~
    +:IXgw'7HYj{+=Oat2FZn		%	:	O	d	y						
    
    '
    =
    T
    j
    
    
    
    
    
    "9Qi*C\u
    
    
    &
    @
    Z
    t
    
    
    
    
    .Id	%A^z	&Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l   !!H!u!!!"'"U"""#
    #8#f###$$M$|$$%	%8%h%%%&'&W&&&''I'z''(
    (?(q(())8)k))**5*h**++6+i++,,9,n,,--A-v--..L.../$/Z///050l0011J1112*2c223
    3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<'<e<<="=a==> >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JKKSKKL*LrLMMJMMN%NnNO�OIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G
    k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4
    uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-�u`ֲK³8%yhYѹJº;.!
    zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs
    2F[p(@Xr4Pm8Ww)KmExif��MM�*������������������b�������j(�������1�������r2�������i�����������-��'�-��'Adobe Photoshop CS2 Macintosh�2007:11:07 14:38:51���������������@������?��������������������������&(�������������.�������������H������H����JFIF���H�H���Adobe_CM��Adobe�d�����			
    
    
    
    ���"���
    ?����������	
    ���������	
    �3�!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw�5�!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw���?�Α;tCKӯҥm_g�/g�c�:_K�}O�IOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�tPl�[0zwQ/}J*Y;){꥖8~zU]�$?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$+}*έ4=:ZxѮ*ѿ�r697˂.0A�z_?3a%^ru���z??VJr�q�p�k�@o[ǡknm,_�|N<CVŰa#QT_ë[��_�|ʮV��!N/?Ɨ.c�m*��X�|uʤ$L:8GI @LRZǣ�g�'�%txi[	%KGį3s-l�	
    C{gǖ12c7_f�A_͋ȩ(w=b츺7z7_�.[?F�k?eB9nO$J7qI$JR?�Ŭ~7;�pg.V��!r��V1?Ɨ.c�m9Uv�Ɨ.c�m?6fihuf?g1qTwI&:7ypc@y)$y)&;<w[-l�+Oߔ-lQl�	#jr_Û?1HP&:ԯ5�RXQ�'嗓/g�z$J
    ۢI%QYd`o�ׂ~�7;�???7u_�}3�]W�L��B?Ɨ.c�m*��X�|usW}RX]PqXpKnlWcv%<JK?h?gݑ�R$�vOIOO"ҰZ_7u9~}HV`fct;CZ}[HG$R^CI�+>*�V}?U%>^gZ}nͣcvf�I»,obc�Vs}a5bzack{Cu=~rJ|%?ğ³�ҫ`?X>`?u�'^S/P$�vOT'_xWw.[}lIyeّ]{Smڒ<I{U,~cuk/8nqyfclmu9h?gݓ�RS/O$�vGY_CEoٝ69zOmKoܒu_�}3�]W�L��BJ?Ɨ.c�mO#ci�?t_C&gLg6l�Sխ%>fc鿴-e>sKvΌ�SO�.�U{Y\
    }V-2]Q[$IHzoүvGMĹ5?'׺wG~ezW[ewfI-}7Q7mǽi�ScGuC}}<2[`O_XzXyWn
    ב]WKYouN{IHUZg7eb�Q.1
    >C�O?/ܻ�yR�SO�.�dcҰ{z-,ײmu?oHe�t?�wԺzOX4\R/}Ϸժj羪�]��=㤧�[>?�-))_^}\޼zװG>8kzJzRhn-�em5Շkuvzk�c�
    �ޤǐ?G1r
    ˒SL`(Y�l7�z?]~Bޘa͕k�נ_iԮ
    Fok,}wlIO.V��!YWQ̊Nn1uePF>̯O
    9"I�Jpijƿ.H߱䵞~%??Ɨ.c�m/UcmcK\5uK�}O�IM��/߳�&�e�o�TIM˺YS~~M<C}sHS\U{[v=}+qk{a	$�9_4o��ɪ)$GVUrs/A5kqj}C>gWk1
    1}@v@I%)ym {>}Og~RclǪ=:^9[ $әnId7=D-v	$3+&܆m{ `yvϠRc\wZ\lvK/Tg+,�N,ysK89Irk��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*+cfwQ>%gK'e4�e2+w,k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S.V��!?5^��fQ8>%gK}7TeW>,o$4Photoshop 3.0�8BIM%���������������������8BIM����<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>com.apple.print.PageFormat.PMHorizontalRes</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMHorizontalRes</key>
    				<real>72</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMOrientation</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMOrientation</key>
    				<integer>1</integer>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMScaling</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMScaling</key>
    				<real>1</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMVerticalRes</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMVerticalRes</key>
    				<real>72</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMVerticalScaling</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMVerticalScaling</key>
    				<real>1</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.subTicket.paper_info_ticket</key>
    	<dict>
    		<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.printingmanager</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
    					<array>
    						<real>0.0</real>
    						<real>0.0</real>
    						<real>783</real>
    						<real>559</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.printingmanager</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
    					<array>
    						<real>-18</real>
    						<real>-18</real>
    						<real>824</real>
    						<real>577</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.PMPaperName</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.PMPaperName</key>
    					<string>iso-a4</string>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.print.pm.PostScript</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2003-07-01T17:49:36Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>1</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
    					<array>
    						<real>0.0</real>
    						<real>0.0</real>
    						<real>783</real>
    						<real>559</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
    					<array>
    						<real>-18</real>
    						<real>-18</real>
    						<real>824</real>
    						<real>577</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
    					<string>A4</string>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.print.pm.PostScript</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2003-07-01T17:49:36Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>1</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.ticket.APIVersion</key>
    		<string>00.20</string>
    		<key>com.apple.print.ticket.privateLock</key>
    		<false/>
    		<key>com.apple.print.ticket.type</key>
    		<string>com.apple.print.PaperInfoTicket</string>
    	</dict>
    	<key>com.apple.print.ticket.APIVersion</key>
    	<string>00.20</string>
    	<key>com.apple.print.ticket.privateLock</key>
    	<false/>
    	<key>com.apple.print.ticket.type</key>
    	<string>com.apple.print.PageFormatTicket</string>
    </dict>
    </plist>
    8BIM�����x����H�H����/8Ag{����H�H����(����d���������������������h������ ��������������������������8BIM�����,����,����8BIM&���������������?��8BIM
    ��������x8BIM��������8BIM�����	���������8BIM
    �������8BIM'�����
    ��������8BIM�����H�/ff��lff�������/ff���������2����Z���������5����-��������8BIM�����p����������������8BIM����������@��@����8BIM���������8BIM����I�������������?��@���
    �U�n�t�i�t�l�e�d�-�1��������������������������������@��?��������������������������������������������null������boundsObjc���������Rct1�������Top long��������Leftlong��������Btomlong��?����Rghtlong��@���slicesVlLs���Objc��������slice������sliceIDlong�������groupIDlong�������originenum���ESliceOrigin���
    autoGenerated����Typeenum���
    ESliceType����Img ���boundsObjc���������Rct1�������Top long��������Leftlong��������Btomlong��?����Rghtlong��@���urlTEXT���������nullTEXT���������MsgeTEXT��������altTagTEXT��������cellTextIsHTMLbool���cellTextTEXT��������	horzAlignenum���ESliceHorzAlign���default���	vertAlignenum���ESliceVertAlign���default���bgColorTypeenum���ESliceBGColorType����None���	topOutsetlong�������
    leftOutsetlong�������bottomOutsetlong�������rightOutsetlong�����8BIM(��������?������8BIM��������8BIM����������������,������JFIF���H�H���Adobe_CM��Adobe�d�����			
    
    
    
    ���"���
    ?����������	
    ���������	
    �3�!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw�5�!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw���?�Α;tCKӯҥm_g�/g�c�:_K�}O�IOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�tPl�[0zwQ/}J*Y;){꥖8~zU]�$?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$+}*έ4=:ZxѮ*ѿ�r697˂.0A�z_?3a%^ru���z??VJr�q�p�k�@o[ǡknm,_�|N<CVŰa#QT_ë[��_�|ʮV��!N/?Ɨ.c�m*��X�|uʤ$L:8GI @LRZǣ�g�'�%txi[	%KGį3s-l�	
    C{gǖ12c7_f�A_͋ȩ(w=b츺7z7_�.[?F�k?eB9nO$J7qI$JR?�Ŭ~7;�pg.V��!r��V1?Ɨ.c�m9Uv�Ɨ.c�m?6fihuf?g1qTwI&:7ypc@y)$y)&;<w[-l�+Oߔ-lQl�	#jr_Û?1HP&:ԯ5�RXQ�'嗓/g�z$J
    ۢI%QYd`o�ׂ~�7;�???7u_�}3�]W�L��B?Ɨ.c�m*��X�|usW}RX]PqXpKnlWcv%<JK?h?gݑ�R$�vOIOO"ҰZ_7u9~}HV`fct;CZ}[HG$R^CI�+>*�V}?U%>^gZ}nͣcvf�I»,obc�Vs}a5bzack{Cu=~rJ|%?ğ³�ҫ`?X>`?u�'^S/P$�vOT'_xWw.[}lIyeّ]{Smڒ<I{U,~cuk/8nqyfclmu9h?gݓ�RS/O$�vGY_CEoٝ69zOmKoܒu_�}3�]W�L��BJ?Ɨ.c�mO#ci�?t_C&gLg6l�Sխ%>fc鿴-e>sKvΌ�SO�.�U{Y\
    }V-2]Q[$IHzoүvGMĹ5?'׺wG~ezW[ewfI-}7Q7mǽi�ScGuC}}<2[`O_XzXyWn
    ב]WKYouN{IHUZg7eb�Q.1
    >C�O?/ܻ�yR�SO�.�dcҰ{z-,ײmu?oHe�t?�wԺzOX4\R/}Ϸժj羪�]��=㤧�[>?�-))_^}\޼zװG>8kzJzRhn-�em5Շkuvzk�c�
    �ޤǐ?G1r
    ˒SL`(Y�l7�z?]~Bޘa͕k�נ_iԮ
    Fok,}wlIO.V��!YWQ̊Nn1uePF>̯O
    9"I�Jpijƿ.H߱䵞~%??Ɨ.c�m/UcmcK\5uK�}O�IM��/߳�&�e�o�TIM˺YS~~M<C}sHS\U{[v=}+qk{a	$�9_4o��ɪ)$GVUrs/A5kqj}C>gWk1
    1}@v@I%)ym {>}Og~RclǪ=:^9[ $әnId7=D-v	$3+&܆m{ `yvϠRc\wZ\lvK/Tg+,�N,ysK89Irk��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*+cfwQ>%gK'e4�e2+w,k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S.V��!?5^��fQ8>%gK}7TeW>,o$�8BIM!�����U�������A�d�o�b�e� �P�h�o�t�o�s�h�o�p����A�d�o�b�e� �P�h�o�t�o�s�h�o�p� �C�S�2����8BIM�����������C��C�?@�����������
    	�����������	����������������������������������������������������������������������������������������������������������������������������������1D�������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4�����������������������������������X(-�����������������2c@�����	ܰ�I����������������������������������5ܠ�����������������R*F�����3�i!�����������������������������������5p;�����������������
    Qp\u!�����&cr
    $2�����������������������������������fr����������������J.1�����nX�a@����������������������������������wP�����������������)EÕqԆ#�������4�����������������������������������YX8�����������������(r:`�����1`�����������������������������������3]k@�����������������UR�����f7,�0C ����������������������������������fk`w(�����������������ʸC�����LHd�����������������������������������,wy�����������������\9WHb0�����	ܰ�I����������������������������������5ܠ�����������������R*F�����3�i!�����������������������������������5p;�����������������
    Qp\u!�����&cr
    $2�����������������������������������fr����������������J.1�����nX�a@����������������������������������wP�����������������)EÕqԆ#�������4�����������������������������������YX8�����������������(r:`�����1`�����������������������������������3]k@�����������������UR�����f7,�0C ����������������������������������fk`w(�����������������ʸC�����LHd��������������������սO|x@<=|�Axgu��5p;�����������������
    Qp\u!�����&cr
    $2��������������������F7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4��������������������	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��������������������$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��������������������M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2��������������������F7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4��������������������	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ��������������������$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��������������������M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2��������������������F7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4��������������������	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ����������z7m�����95C�$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I���������~f�������ɥq�HTN�����������
    inp�YX8�����������������(r:`�����1`����������Vշ�������+J)\�M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2����������2o�������WKR,#G曅S8�����������)fk`w(�����������������ʸC�����LHd����������{e[7V0�������=+pXF7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4����������ʶn`������],zWJnO�����������`x/�5ܠ�����������������R*F�����3�i!����������=l[|������X2`	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��>@����xU�Uum�������
    cҸW$hp}'�����������4}�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ��$܀����.(`{e[7V0�������=+pXF7
    p�����������SKo0<ߋwP�����������������)EÕqԆ#�������4���	9ƅ ����"JVշ�������+J)\�M©������������5p;�����������������
    Qp\u!�����&cr
    $2���~Nqm����jR�Uum�������
    cҸW$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ��$܀����.(`{e[7V0�������=+pXF7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4���	9ƅ ����"JVշ�������+J)\�M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2���~Nqm����jR�Uum�������
    cҸW$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��$܀����.(`{e[7V0�������=+pXF7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4���	9ƅ ����"JVշ�������+J)L�M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2���~Nqm����jR�Uum�������
    cҸW$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��^`����#>@~`뛜��|>\rXp,i������������Ps}�,uth]�����������������;s.?X�����nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd���ݝ/y�������#G@�d�������~"t)(�띎,���������?)[6�mϖ`�������|G������f7,�0C ���L���������$@-Rd���������?#O�����������y CP���������AU������3�i!���j@�����������
    ���������)	!�����������!@KZ���������Gq�����f7,�0C ��7D����������Vs`;����������3p4|������������3i���������f �������4��>�������3]�%ذR3b�������RN�p`P4(w%����;u%����;u�SB8�������K2�����1`���,��������7�Qs`�������v0By3ph���@�3ph���@�8g4.?@�������l.�����1`���,��������7<cy�Qs`�������v0Bz�3ph���@�3ph���@�8g4.?@�������lz:J2������LHd���Fހ #��������\(n	oE6,Eu������cH3
    �A���
    ��A���
    ��wи�������	(�����3�i!��z�@�������?(/1`
    ,c�������	^S84���84���3�A�������6v%������&cr
    $2���X#o@����������x͌U6<G�������4(w=���4�w=���4�wfSB3�������Ξ\'c �����nX�a@��m1�����������&qg���Gy$g#lj<D,�
    �A���
    ��A���
    ��wиq_�������jŞz:J2������LHd���Fހ #�����������k(��������><�g����g����p;h\����������td�������4��`�@F ���]�����<Y	יc@��������%gBz�3ph���@�3ph���@�8g4.����������:J2������LHd���Fހ #����@����%�{c$Cڞ$�������9
    �A���
    ��A���
    ��wи����������(�����3�i!��z�@���ۼ+����&=����}=	f{dz$3=I@8g;@����;@����;3?)pȌ�������OH�����1`���,����=����[���������m#�p`P4(w=���4�w=���4�wfSB3������������1`���,����?t��#Z%xлχҰ@�������4s=`Щp���������yMp�������/@:J2������LHd���Fހ #��������\(n	oE6,Eu������cH3
    �A���
    ��A���
    ��wи��������B�c �����nX�a@��m1��������F0^cb\X�������4=@Щp���������yMp�������/@:J2[õ�_QGo&�1`���,��������7<cy�Qc�������v0By3ph���@�3ph���@�8g4.3?�������lP�($x9VkO+|7W`f7,�0C ��nX˜x�����uiP\e@���}��XǶ|S84���84���3��������6(^td6ss.[3Ś1�&cr
    $2���h����������2Xn@���������,G(S84���84���3��������6&^td62rLu	ܰ�I������������?;���������TfNg����g����p;h\f�������ءz�1Q@gd#tJ&^
    F�1`���;z0��������s !;p\��������	2A`;@����;@����;3?)p��������b�IF@;
    m~O=IN1�&cr
    $2����$}>�}>�}iq@�W-Ϡ}���&Uc�%�z����%�z����%> Ȯ�������]c߀R�YPVt0p˖�LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�d،�����������������������������������������������������������&�������������������������������������������������������������������������������������������������������������������������������3������7 50@Pp1346`G���'~occccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccӂ�?UAaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aa�r�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1SWG=GAa�p~~L=y};q0g:G=GAa�p~~L=y};q0g:G=GAa�p~~L=y};q0g:G=GAa�p~~L=y};q0xbhMCW٫vj;5z^fCW٫vj;5z^fCW٫vj;5z^fCW٫vj;5z^fKB8z:{`y.t#0ç}B8z:{`y.t#0ç}B8z:{`y.t#0ç}B8z:{`y.t#0ç}B8z:{`y.t#0ç}B8zbUh+N2ӌB!zq8^d/N2ӌB!zq8^d/N2ӌB!<:F{Ͼp~~L=yֻ[JZ=<g:G}k^{Ͼp~~L=yֻ[JZ=<g:G}k^{Ͼp~~L=yֻ[JZ=<g:G}k^{Ͼp~~L=yɢ�ΓX5
    @jP,`X5
    @jP*
    ZC^{Ͼp~~L=yɫn+׹ht\=GAaj�?94;[JZ=<g:G|k}ҽ{O}>;q0&sC^{Ͼp~~L=yɫn+׹ht\=GAaj�?94;[JZ=<g:G|k}ҽ{O}>;q0&sC^{Ͼp~~L=yɫn+׹ht\=GAaj�?94;[JZ=<g:G|k}ҽ{O}>;q0&sC^{Ͼp~~L=yɫn+׹ht\=GAahlB
    *kB
    *kB
    *kB
    hVt0)hx1bŊ3(X1bŊ3(X1bՊ3V(X1bՊ3(X1bŊ3V(X1<5fKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRxh:\j^,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *	褣n#0D8zC0D8zC0D8zC0D8zC0D8zC0n{Zeku%tp
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    M{!w[P+z]%~n5K'p
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    TXҧ- 29;6.qjVZ)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)RhIXů�pIn͊ʝ
    ](](](](](](](](](](](](](](](](](](](](]*BUo�'zF8z?qdwb/v
    `YM#Qk^$6JKcSXV-)gCV|\Uj^W5jri?zE@bSK+l
    q0*c7@[(mCg�yմjF@SˆM9
    g3lak-YХpk7N>&-Acug{&<䰙RCQF-ZƣxH<<<=eT5v#b~mfMYQbѻ~q0$UGJO�jWnRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRUJ'J.\dRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRU";}>7ڨHuQHuQHuQHuQHuQHuQHuQHuQHuQHuQHuVS)?$TVFȤ:::::::::::)W
    _aU߁SSSSSSSSSSSSSSSSSSSSSЍjC[#GGFmGAaDRY�~Ywii!؋ۓ]a}]}˰ϵÛPғL=yKһg/]f}Kb/nOu9v{.>ۛnۛ@jJNq0$K5/+J|!u}-_}>7ۏpgq_nok9_no�I);G|,Լ+Z>>*.>Q8xbꢐ֖5wYwii!ҹ$Gu\CCC~Jo'u9v{.>ۛnۛ@jJNq0$K5/+Jͼ\<&]RXFkQSKuo ̏CNmU\\ޚFq_n=×aku7t	5}'B8z%wX6npD.>E-^Nn_
    5h *k3=tt7Si,P8}XoVBpqSXXWᦲ‰V,mӄ˕o(ēWTk}6ۏpgq_nok9_k~(ȲƲȲȲȲȲȲȲȲȲȲȲƲƲȲȲȲȲȲƲȃ,v�[}'B8z%w[g]}Զ]U*Y	ӫ6؍wm}9v{.>ۛnm'B8z%w)W6H H H H H H H H H H H H H H ;/#tdI=Z(/T%|t|wXon=×akǸr3}Rw#0"YyZWrs/h`<mUIϢ[4WMUZCiu?{WxuiUw.UZ~..UUBq_n=×aku7ғL=yKһ~C�*ժ�j7Bd,P*
    5?
    N4?ʥ~*Jt_m?;rV�teh-Q[8QH^�
    Wx{i/R.о{.>ۏpgs{]atUUUUUUUUUUUUUUUUUUUUTk);G|,Լ+N9ϗ:~r}7o˰ϵ9vXsp-da#>Hj^VܪfYzzzzzzzzzzڤI\U�::�:l8N_ܟF
    Ǹr3}]}7/7Kf!}'B8z%wJ_sKI_ܟB
    Ǹr3}]}7/7Kf!}'B8z%wJ_sKI_ܟB
    Ǹr3}]}7/7Kf!}'zD				>e_РHpfn,apAaDRjzYwii!؋ۓ]a}]}˰ϵÛl$/N9-h7(z{^Czzk;5*xbȁDgZeYAaG5H{mSo�:�:�:�:�:�:�:�::�::�:�:�:�:�:�:�:�:�:�:WYGP4^܄������������������qe~q�a}]}˰ϵÛl$/Û*ީW5ݠ+ZHhL=y=Uw-<:;-jVqة<~wxu9v{.>ۛnۛۥLғn.�l\Y拾^SbK꼏geG|%Ch9&J՘J,chV7/˰ϵ9vXsp-dspwB2z?c�jWBZT)+ZZHhL=ym_Q2Sz_'ag-] )ְgWh*5Nh$7߾Bq_n=×aku7٦H_iI}7q(QmqijRC@a#>cyjz͕&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&dҴᱧl۵n7QEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa<fG-?C:8777i9n	QbޢޢޟL%Gezzz7sR}TXoQXoQXoOQ&�zWZХg5<ɽxiItOD#F9lfq{mO}0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zCٍCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCY9V{1_/R�I��	
    �����7PU 5qrs!6T`0@pt1A2"#Qa�?�Z,GQ\>2Gq٠)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ&ĨVRR�<
    0̇a@ɋ`D[-y dV-Zfp02bX+Kk38AH1y蕋x֙ $tJżRL}L^k�%b)mug>&/5]o3}䁓.X[]i@ɋ`D[-y dV-Zfp02bX+Kk38AH1y蕋x֙ $tJżRL}L^k�%b)mug>&/5]o3tRE1,paNS<99z?s`.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F(oNBx`qܜ�zy3I&/5]o3t$K*qjJKdƒL^k�%b)mug>IU-:.$tJżRL}Г,sŨ[U).u\3H1y蕋x֙ 'YVӋPR\`n42bX+Kk38ABOt?mTpi dV-Zfpe[N-BکIs@ɋ`D[-	=ʷ0ZRY1.X[]i{na8j%βcI&/5]o3t$K*qjJKdƒL^k�%b)mug>IU-:.$tJżRLu1Q#$vDS-πOXMЏ:a?&oNފL8'oE|EvS"_)g诔ȳvWdYa;z+2,߱CqNފL8'oE|EvS";	_)g诔ȳvWdYa;z+2,㰝o؎ފL8'oE|EvS";	_)g诓`*hCV(0iܟyNh œ,sŨ[U).u\3H1y蕋x֙ V)I(҄_qdK*qjJKdƒL^k�%b)mug:ՊRJa"}4:|\Y=ʷ0ZR[q.X[]ibnM(NOt?mTApi dV-ZfpX$f'J!~8wœ,sŨ[U).u\3H1y蕋x֙ V)I(҄_qdK*qjJKdƒL^k�%b)mug:ՊRJa"}4:|\Y=ʷ0ZRY1.X[]iW(yC)@WJjݠ_+5
    n/Қ7hMBtMSP])Sv|)@WJjݠ_+5
    n/Қ7hMBtMQL\F:a;_RJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZR[q.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iU
    +DaD2s@tW,67aU
    m7Xm{iobhM{E^oذ*|ņW,67aU
    m7Xm{iobhM{xX#h'ArPQ	9f1l|0l0tҜkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL&UcIAtAr0a%r+֣7)�Aq!N;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂ5%G['+4POM<à8Ӡ
    y`1S)Ջdr/'r,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ&ܖ	hB Gg!0tC�[Qڈ~C�~3χD8?hQڈ{}wOO]?N'It%KK:KKQ}?�8��	�����4 PRSq2@`0p!A1ar�?�ZkP,Q-Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0QH)5Qy:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�XuT�?+8U+U+8U+U+8U+U+8U+8U+U+U+U+U+U+8U+8U+U+8U+U+U+U+U+U+U+U+U+U+U+U+U+U+U+8U
    S,`�iG,'AY*OMκ=e)>G
    85́R|nu7.I?i.nl
    sAYp
    ON
    isp`T6tz
    ˀR|pkKo\~ ӃZ\,'nu7.I?i.nl
    sAYp
    ON
    isp`T6tz
    ˀR|pkKo\~ ӃZ\,'nu7.I7ZJIF?}VG1	Y<%ds`}VG1	Y<%ds`}VG1	Y<%ds`}VG1	Y<%ds`}VG1	Y<%ds`}3izQ_ZpkKo\oV̘a�-85́R|nu7.I7J
    i{fD0-85́R|nu7.I7J
    i{fD0-85́R|]x#z֗dCӃZ\,'ͦ]x#z֗dCӃZ\,'ͦ]x#z֗dCӃZ\,'ͦ]x#pҬ4tK.zzg�~+8i^J�Wpҽ3?f4L٥zg�~+8i^J�Wpҽ3?fL,hS.҃Z^ّ:N
    isp T#iG,'&a4>]FJ
    i{fD0-85́R|]x#pxxu-(5ï,֗72I6tz
    ˀR|fAUl֗dCӃZ\,'nu7.I7	zMǁWQ҃Z^ّ:N
    isp`T6tz
    ˀR|fAUl֗dCӃZ\,'nu7.I7	zMǁWQ҃Z^ّ:N
    isp`T6tz
    ˀR|fAUl֗dCӃZ\,'ͦ]x#pxxu-(5ï,֗76IiG,'&a4>]FJ
    i{fD0-85́R|nu7.I7	zMǁWQ҃Z^ّ:N
    isp`T6tz
    ˀR|fAUl֗dYi.nl
    sAYp
    OLh<}v<
    ̈aZpkKo\n0]e"uf>m7:ŗ�jW
    UrҬ;aܴXw-*ùiVJZUrҬ;aܴXw-*ùh̡(t6Z*/HTUP=G#QX(g,vu3;
    :LŽraGS9cQX(g,vu3;
    :LŽraGS9cQX(g,vu3;
    :jRQA-%W(�u3ŽrQR
    :[aGS9Kl(g)mL-u3ŽrQR
    :[aGS9Kl(g)mL-u3ŽrQR
    :[aGS9Kl(g)mL-u3ŽrQR
    :[aGS9Kl(g)mL-=E&�<"�@0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0ŒVT�~ځP?d==========j?�w�_�����6 v!014@qrt"35APps#27QaR`$Bbu%CS&cDE��?�ڔ:MdEc|A2>,R-���
     �jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Kt{&ǧG1.)r
    S�Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗T^5HIuslt@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@Ϩ;T 2d)yr2�x"^?qOOiHxgː0)/|{JC8^\qLOo(7SSR/g3eD*~yF!"Ґ!{>aS._%S1
    pr�/JQnȧ<3^Ϙg˗zTCu>E=!/.B|8\Kҧ7b))yr2�x"^?qOOiHxgː0)/|{JC8^\qLOo(7SSR/g3eD*~yF!"Ґ!{>aS._%S1
    pr�/JQnȧ<3^Ϙg˗zTCu>E=!/.B|8\PsX"jNrCK6~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D˚F9D@
    e>)M^?qOOiHxgː0)/Mꜙ�'&K藥Oo(7SSR/g3eez& ɒ%S1
    prYtީɟ/rdzTCu>E=!/.B|8\]7rg/^?qOOiHxgː0)/Mꜙ�'&K藥Oo(7SSR/g3eez& ɒ%S1
    prYtީɟ/rdzTCu>E=!/.B|8\]7rg/^?qOOiHxgː0)/Mꜙ�'&K藥Oo(7SSR/g3eez& ɒ%S1
    pry$va	u"}zGש}zGש}zGש}zש}zGש}zGש}zGש}zGש}zGש}zGש}zD].ࠅПNߎNLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2$:81nnnnnnnnnnnnnnaHc�ٵP;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    ez& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    prF J"?l+l+l+l+l+l+l+ QQe`C:(w#mmmmmmmmmmmmmmmmmmmmmb(N)n8zꦊ`U.T?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v}UF1nTHrɬ!}EIs	iZl?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';?#BSt Q<{JC8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._TF
    -ž%ówW!lts}يG
    0d٠r.&/	iځqo^
    -#iHT5]`z"FLP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_6,KeGWֵehs[F!D,:4PP�(1e"./ΪhO.h~ a,	iRk(=Hui[b<͊sN-[t:*Zɔt-/_̟Ya|*vL/܀5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    L[9W{ZۧeԖ#у{9"ޝQ�?ebn$= OI[1[WI�V|8*�c4wq8�@-D-�D.RgG#EjzV�*�\L:nڳR?.dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZkɇ@mۻJc]<.P6@/�;UȑHq[xs(]\_~\9BDoX3�{c!Xi~հ =�6Y3MSr6'�!)Zv(ZrWY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i*2<Nc#DP벏DIS"a>v@[3s*jBGPN#tܛH
    r�mIyr27bjd!ֈAll([v(D
    ؂
    1HP<j^ձA 
    muE7?EƓH+鉴_l":cQ0kD Q%X[ɝJ"rtBoCta/Qإ;Zֻ>1h`2=Gtm( P:\5H~iWgCU%e!W5K�ќ�/y/	<΢yi[ph*$xD>>.܀([&PuzDER&G\iSG�+=<aɓJti&+	7M(I=Ÿ}Tт"ZZ!wqqwEwvvw $(Z)J_yG\rs\zAGc1-'D-k?2�r/g3ehLoHF2&M]0k-]0~vd[d,dS
    AvxSN֑n֞Kcu*se#ʘU*6I"ܓJw6[!&wGuH
    S�t~6ΏT_^vՠ53&n̿*%tT/Oh�k`hn
    `u#)I"e(ix� WtMO+&\PLk]ZQ
    1L%G1)EKjP-[*e8C P9&B+b#nEPw!Д/Z4aU
     6IBݓOZݫ{NC8^\qL}J
    KIXU�e"Agg'b7w7r:R
    (�Zvz9RegtL2<`!~EHC)L(JP)JPm"bM!ǨSҷVJ$gY8
    ;]ht0Ns?I^>K_|j�ݹ-Kax)�
    j((x)0[)|B7w	7T-c$PcSiHxgː0)/X%5'A]k`/'h1`wA(RUU#\h(VaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaURu);r	�0	4&~ɕ|1wl.fwwM@0jC}VaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUw	>X|74r*
    AhA!ۼq;6Hp#䔔wg"[GGL	jֈk]UGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuV�aFѮw폤4^.	v^IIIqߡv~R EtqDΠHh6ڛYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUiiFh~CE	ހڷjMh.钉wBU6Gp;hґ49 e 
    �k~MM	V=Y*'54%ZfPЕj՚BzSBUOVjhJ	M	V=Y*'54%ZfPЕj՚BzSBUOVjhJ	M	V=Y*'54%ZfPЕj՚NcozE`yy*$vԺ1D�([�JEA)rc8ú""#Ґ!{>aS._RA yd|9k9py5`LfC_{8#]6h%q;6Hp#8OYCvkp8Tז/ݍ|d~^XBK)y>p_m)yr2+IÞ6OV
    dd>:|EkN6R[ód?X:7`6uK(n~myb{6Gp;wt/kX�u{Ґ!{>aS._RA yd|9k9py5`LfC_{8#]6h%q;6Hp#8OYCvkp8Tז/ݍ|d~^XBK)y>p_m)yr2+IÞ6 :fui<i-Թ	97
    M¬:=C'M:YzCɋtW`0fC_{8#]6BM�u{S]b�D&pYuVVaUUGUhqgHK
    _!wntN-۸&l|Gp8Tז8q>;e
    /ͯ,_Of~3k�R|ᎿtR/g3eV5?,1<mL`(vmmpz�#y5J"Z*;"aMc[8w)I~Lp=YI$b\|szTm"a0��cK-%ރ	
    6SV@P5yU0(Eܶ%9LSnDHp#8OYCvkp8Tז/ݍ|d~^XBK)y>p_m)yr2+IÞ6QB$2dtxyUBݑ4tb!0)()|aGA~Ί)sm;/>`Xpgg*wBbi�\XHSJYĪ#v؀r\[ڰqom�
    -c1'~+i~Lr_ˡ0
    b�0a&PܡDvt)vM?N⡃{"֞I-~J,sh7<@JÞc~-秸јduɟ8AC1E/m	]cf("F5Ĩrkf8p]avttS!?]q{0JEM�\cswUOK[]wD@U%GޘN/$nbn.uK(n~mycP݂lw%/G~R'8Lg]4+�oكw'IfPN}>&=A:M{0zta7oهw'IfP^}&}A:M{0t`7	oهw'IfPN}>&}AzM$.kC1P}r\�w=/'M!/.B|8\c\>A8sއ'IUEֹ6 �]]�kmGâ�wx500~cŞ7P8~x3晄Α{W!n>#\VM
    dM�Z0i8\/�ycP݂'q,c_)8z|ᎿtR/g3eV5?,1<jpwGhQGweӺݐꔦa#]3E+C<]3E+C<]3E+C<]3E+C<]3E+C<]3E+C<]3E+C<胬W3㹍0?:H
    OLbb$t>2NE2qx_#4eT^==0ZB`#ݐJrh{m$I"�\6{a@E1P"08\B$p_'q,8OYCvkƾSٲ?q߶~鴤<3^Ϙg˗Ԭk;Y'�cx�N\Ճo2%ث"$6zrWC0遮L-mk3.;GHA+	_ ّ5vɸ6qr9e^=2�he86ihM!/k0!KDx3m~bJ�-v#H5Kg6EKl^ӛEhF}}0k^PXBT*�tIG48|Yf*dQS%2?ݛ$p_'q,8OYCvkƾSٲ?q߶~鴤<3^Ϙg˗Ԭk;Y'�cx�N\Ճo2ӬN kw_i$GIpv"L+Z}L[$NpkѦG{gaOs.Dk5X�!K�L>Bܘp"ZmH6zV$=D4|LCpJޤUau݂P5̟FL{T}cKs(Liл�F sjK"=w+GwPܽEn-\-gC~v?"kVďBkQΤ<h{T<,M(d^}QmRyc=F&?rpf.uK(n~mycP݂lw?D;Gxn\h۵`xe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v3ZtC�uq\].L$06S8c6prp{$c˓Wm&WnΘ6R[ód?X:7`6uK(n~myb{6Gp;c_){~鴤<3^Ϙg˗Ԭk;Y'�cxݟpy@P00ktUveK\fZUveK\fZUveK\fZUveK\fZUveK\fY5&w3$!	4m&W+JҮxT]u{+ݮ:<*[dǃn2c7x1iiF{j=k\*kN6R[ód?X:7`6uK(n~myb{6Gp;c_){~鴤<3^Ϙg˗Ԭk;Y'�cx\->8^MX6+ِc'M:`9Io,oG͒8\/�ycP݂'q,c_)8ז/ݍ|kH|/wu{Ґ!{>aS._RA yd|9k9py5`LfC_{8#]6h%q;6Hp#8OYCvkp8Tז/ݍ|d~^Xv5!GO1YR2qrx<0ɕD@LqD뜺R9uvrJ'?\T>D`2fz1%ЇpRh<QYpMH)DY3,Ky~#VUn
    �@M2i{b6[؆Mfbŗ\ΰwIMAI3}bF\mڴ!7#;Twv~U]^@nQk*#>+yr2+IÞ6OV
    dd>:|EkN6R[ód?X:7`6uK(n~myb{6Gp;c_){~$vWM4x9HZ8ZP.SU4Y`^6XKUbz[v"}vikI%:? Ty+w]~kE?ٵnޞ5<|P;4D(	;L--&RKqESuyX0*nd1kG,i`.xbhB_OD-{"h'ԡhpL
    -
    "ԡØ]]CȺ f8#]/d<3^Ϙg˗ԤG(TAr<
    )Q5Zb b}	S"T
    oܜtۼLz
    &Lx=&<wAɏdǃn2c7x1L&Lx=&<�cwAɏdǃn2c7x1Lz
    &Lx=&<wAɏ,T&+n66m޺ƸI^ ntTD{6?]_xȹt]w'T4w9Z:U
    &Dki5HnO+wAɏdǃn2c7x1Lz
    &Lx=&<wAɏdǟn2c7x1Lz
    &Ly&<wAɏdǃn2c7x1#S&W'v.
    {֝ѻ
    G�-l|Gp8Tז8q>;e
    /ͯ,_Of~~k;ZC{8c/,w{?
    {T(#oA�])4,"0Tks#&?Š,q՘^ʪ:2")&碪6,
    2ɏiKɧKyr2"(Lr5!bEaI,l7+&c~Nn&`	i3MŽ� 4qփeC U76(8ŜS:*[w'"C`.莲(
    E+Eܶ?͒8\/�ycP݂'q,c_)8ז/ݍ|kH|/wu{38q>;g
    cҢ_rE/LMM4f5ֆKBg3hf9�3&tTG!r145]1|}E
    >/QS:86p*7'tխ+BU8o|t!{>aS._S5N{ѥָI؍F.wtbbQBEQC&3$ hZ^#	@	lG-B�f7
    wA2Ҫ
    w*7J* dGH�;q4tՋ^րGL6B߁GHu(?D^~|\BNs#8q>;e
    /ͯ,q|wR_^Xv5͑3ybv"y>p_^Y8cSt@I(\i#Ż�w8O:^2g4xz_Q;)]DO+�]m'nMф@
    oqC"wtXCLssli:|EC8^\qL}Nii3dUQ'rvr+%d~W:7DF!{pz#
    (CʑI4t iUWF02}nMh]@PHN)<1(56s[@7 ')zuYWgeJtC�  {B$[f=D@�NO4>Þ] (òJ�-~BewnFaJTǀQDr^P-"E[j-n+`O/:�ٲG,q|wR_^X:7`6~k=#8gi=E|Ꮏt?qߚ'q�v%2HB
    2E�k�$4_Iqgg uTw�/c\>AݧKyr2^ؗ#h"`~QԊ~�nMk-hR?ܔl-k"xJ	Qo	1
    -8&!E%(b[pLBxN	Qo	A1
    -8&!E'(b[PLBxN	Qo	A1
    -(&!E'(Lӑܓ0'P]xݰ[cQH]bO>#k
    2 *hsk[:XkZbr-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC,(FgҎ溺vpPgs퀁Rф-ސDғbCI:Ga(}kE>ԥҮC-J]*;2ԥҮC-Vq<)CpЁmTD-z5HɱTL!*i*SZ)MJ]*;2ԥҮC-J]*;2gQ#Ȫn=
    NBD"&S}2CDpAvi*SZ)MJ]*;2ԥҮC-J]*;2б T;cBt)mSMY:&4$A�EtAO֭hjRW!ٖ.rjRW!ٖN&0`X!�lhZ.E-z
    z�Խ0;d9rz2@TtũK\fZUveK\fZ!2${EE^J2$^2YYI"86x)M\Jrb{Z轟o+mTMB.n)YsGMUD5ְZL@ΑY>u+:K8L4�A(N`)wP"Dx)XLXM7xBnTL;{!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._pٶ+"s3A\ёYU=ɖр5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}(BH|wpLrWAEP%XL6QE��0�����!1�A@Qa pq0P`񀠐��?!�4D ��0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`
    ?CDBP��������������������������������������������������������69fP~^yyyyyyyyyyyy綬YG~� �� �� �� �� �� �� �� �H|vۇnݻv۷nݻv۷nݻv÷nݮ?o~k�j��Z� �k�j��Z� �k�j��Z�#R,۷nݮv۷nݻv۷jFg1YKqj�;yj�;yj�;yj�;yj�;yj�;yj��38�$fvյ�rPk�nV�C �҆'o-[X@�;w/NZ�v_J\ma��ܾ1;yj�۹}(bvյ�rPk�nV�C �҆'o-[X@�;w/NZ�8h5?v]h5?v]h5?v]h5?A)a$Pbؿ}v/]bؿ}v/wbgZ_;~_N_d$e̔P!J*TRJ*TRJ*TRJ*TRsR08M\5&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ%
    X6R'Y������������������
    NX
    E]aε8b˗.\r˗.\r˗.^'Є9pfѿh04K0h8RѥE9̠U?I([5۔29b˗.\r˗.\r˗/+1gzS(FZ0*Ȩa>Nh)&C7o"8&0r˗.\r˗.\r˗.\r煦\/cy5r9C6ED,A\؂yٵ%]N+"MЦoU`d1r˗.\r˗.\r˗7H
    "$Ji1Va�}	F�Ƨh0WPBI0fV/KB1
    ϭƂp&<
    2+lyfO\jb��&#@-HU<۴nY�uP�lqIZ0P:"e��WD/(C'"2,ƠDc iRqPƋUl
    aIPdkGxbȖ@z"(w
    $ E!!+�`-`wxM8HVIJ@�:<ʉ9
    Q�@�8֙>"̡7n4I:�B�0pd]P6F|qHD!(\0"87V8 �!9ZŜ8{|�X0\y\RB%pԩRJ*TRJ*TRI 
    H`a H8jTRJ*TRJ*TR
    ?"9B@+g0GåJ*TRJ0|B+>q*TRJ*T@bYgB9v$PB
    (PB
    (PBi
    ﲪ�`�t$천$E�
    }:BNvYN�q$'e;,	p�_iJ
    dR ,-U|iRzL6D^6Sb#J)HJ	(De .��k"{�0Jэ=*gQ
    4S&H%`LFfDWD55rIR?]I(iԡߧ'e;,	p�__c8h.7$C#MLhoKEs"('w,jwDϕ]nQVhl+;ًs䫺Λ݊Ɲk$d'+C
    ڹcfr
    Jus
    Y37G0_A+cM>9\K8>YIFQO6|Dex;fPC(xSV0bj+pR 
    L~{�e"]Ā1I.99ј@�N-]�_	'e;,\��FPO @ @3\AITt�8´/-L[�
    ZETTki#ēS��kDkLoZpD3Ue!Hytu
    3QqFƎ˧攛:w
    R,]TB,	{ST;OpJ#T@Aj߄AL PDe�m)Z{1s:]#}6)�\&RäG`Ԭ[-6V`MZa]HaC"v>:C52�CyNF_kO+p>˙iWFx
     R`-
    9@VdV"ԹBfw"\"vStBuNRJ*TRJ*TRJn/r�HBIN)9�Au"~<x
    	=|kxHÈQyyВASsp�_N䐁Ssp�_N䐁Ssp)\fsL2nqJs.G,q1<D%xqAfPr`D5@GCc�
    }RBNvYNn*$"m椘KbE/Tj7T16Yd@BA9VJo>|%�Pp@�	8"!`惱RJ*TSԩRJ*T`l$bAIFf^Bq>J*TRJ<5?xj`TRD4HıOSsrtq
    	49�U%RBע["[B1ÜB3
    r�djhr#lL獇>*-56/nP
    FQ|jiQQC@Deܝ;Ing#~0qbc>R:(O-d<3�L^r?�@ 	!AB@
    C*aqG"%@@mDDeܝ8ɵ=ɓjULi#H�&KdI|C5�$!9"2@�
    KgGma &F- Y2ddmB�"	OPYkIRZ>HzQ>)s6,V&&ASsrt w#6<r04�s$3h̹8 �J}JW$AZxH	|ydMeYYgYyf3nzX#(2c&Tu*™B6#-Up|xᏆ><xᏏ<xZi
    1UUUr`SXlg,O<I/	1BsPdy<x#[ &b+/W,>CFx*_-�lfoO<)K0-8`ydcm11bŞ(z
    `(\.&K>Wǿhc7CPʂYճfeDgVH.'\=:���������������������������������������������������������������������������������UUML0'lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳff͛6lٳf͛6lٳf͛6lٳf͛<UUML������������������������������������������������������������������������������������������������������������������������������������I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������deYmId2H���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`��������������������������������������������������������`��������������������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    �����������������������������������;m[mm�`�����������
    ������������������������������������������ �`�����������
    ������������������������������������������0�`�����������������������������������������������������0�`�����������
    ������������������������������������������0�`�����������
    ������������������������������������������0�`�����������
    ������������������������������������������0�`�����������
    ���������������������������I$I$��������0�`�����������
    ����������������������������������������0�`�����������
    �����������������������������������������`�����������
    ����������������������������������������0�`�����������
    ����������������������������������������0�`�����������
    ����������������������������������������0�`�����������
    �����������������������������������������`�����������
    ����������������������������������������0�`�����������
    ����������������������������������������0�`�����������
    �����������������������������������������`�����������
    ����������������������������������������0�`�����������
    ���������������������������������������� �`�����������
    ����������������������������������������0�`���������������������������������������������������0�`�����������
    ����������������������������������������mmmm������������������P���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������I$I$I �I$I$I ��I$I$I$I���I$I$I$��������������������� �������������������������$�������������������������������� ���������@������������� ������������������������������ ����������� ����������������������@�����������I$I$I ��I$I$I �� �I$I��I$I���I$I$I �@��������������������������������������� ����� ������������������������������������������� ����� ����� ��������������������������������������������@ ����� ����� ������������������������������ ����������������� ����� ������������������������������������$�������� ����� ����� ��������������������������������� ���2	$��$������� ����� ���m�]����������������������������������� ����� ����� ��������������������������������������������� ����� ����� ����������������������������@������I��������@������ ����� ����������������������������P�������H$�$�������� ����� ��I$I$I ���������������������������������� ����� ����� ������������������������������ �`���������@������ ����� ��������������������������������������������������� ����� �������������������������������������������������� ����� ������������$��������������� ����������������� ����� ������������(������yvi4��i�������� ����� ��������������$�����	����������������������������� ����� ������������� ���������������������������������� ����� ��������������� ��������������������������������� ����� �������������������������}��������� �����������$�����������@� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,��������Q1p!`@ 0APa�?�iGBE
    +Se*
    (PB
    (PB
    (PB
    (PB
    (PB
    (PB|V=u_(+"+"+"+"#Ǣ=OcBed(PB
    hУB
    hѣBhѡ�`:C~acVF5acVF`F5acVF5acVF5aҋ]SOM<z<xǏZ<xj:SNb-W6ՄU%F5aIQxERTcVTՄU%F5aIQXE9hP"tb_ɜirK-.Z\irK(6gڊJj)j)*1~
    Ƭ",6gڊJj)j)*1~
    Ƭ",6gڊJj)j)*1~
    Ƭ",6�gٚJj((�cǁ<x1cǁ<Kq1PH (P_M>|ϟ>|ϟ>|ɚh
     �
    R/n�6T!bPPpÇ8pÇ8pÇ8pÇ=LAX%uK>^zׯ^zׯ^zׯ^zׯ^zׯ^z׮<iUbZzh{z5M~Pkڃ_hw*dY,K%dY,K%dY,OC:ٝFܧ2h;Q-zSYJs)̬e)̬e)̧2SNee+)Nee+)N~%9VR92e)̧2s+)Nee)j;QG2s)̧2s2s)̧2s)̧2s)̧29�@a�/��������Q a!1@P`p0Aq�?�{bDP0ݖe-nv[ݖe-nv[ݖe-nv[ݖe-nv[ݖe-nv[ݖe-nv[3B7`ELc0Lz	TT1ꊘ&=QSǪ*`ELc0Lz	TT1ꊘ&=P0!88m#lVЍ[B6m+lVحB6m+lVح[bm+lVح[b� "DÁ&	@__f1;ؘ&=U~a}Ǡj/b`
    UlLC1;ؘ&=U~a}Ǡj/b`
    U	&0̀xGMaaaaaA(p�s'
    ~a}ǓUYtխ0;ؘ&<C+;ؘ&<C+;=LMUfUlLMUfUlLMUfUlL%T G@$G$䣒J9(䣒J9(䣒J9(䣒5MWWvz&<Jv	:jC1U5O
    fU	oxk50LxMs|Yt|%~a}ljT7<5MWWvz&<Jv	:jC͉cĪk`C+;ؘ&<Jv	:jC͉cĪk`C+;ؘ&<Jv	:jC͉cĪk`Ci__f1U5O
    fUlL%S\;j5_	__f1U n7O՛ftY~?Vn7O՛ftP$Cd#yOK'dzY=,OK'dzY=,OK'dq&�A2	O�$qM+&JɥdҲiY4VM+&JɥdҲiY4VM+&JɥdҲiY4VM+&JɥdҲiY4VF Aq8Ǘ\c0dvY;,N'edvY;,N'edvY;,N'edvY;,N'edvY;,N'edvY;,N'e�y܎_pzz?Ts "QeBn!7M&q	Bn!EYa7M&q
    ,\x??%%/L0�O."J"J"_DDDDDDDDDD(((((|QQQQQQQQQQQQQ"$$$$$%�T_((((((1QQQQQQQQQQQQ��-������!1@Q APp0`aq��?�F&@ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|MO18pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ`kpTOn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڙhbuɝɝɝɝɝɝɝbْdΕi|߿D߿~߿~ߢ~R&w8q}gskw8q}gskw8q}gsX!i2dɓ&JY2dɓ&L2dɒ	X.63Â>3Â>3Â>3Â>3Â>3Â>3É2@	6QdJy<r9GQ(y<r9Gr	t>a;@p}gs8}P.s;8w9vkùT\pZw8ps>3Çs>a;@p}gs8}P.s;8w9vkùL\�3kj5x
    ^Wj5x
    ^lFĆ6sib(vnݻvlBv۷nػu$tD;-d(	|߿~߿~߿~߿~"HISLBu>G.\r˗.\r˗.\r˗.\r˗.\r˗.\rCQxH!&g8pÇ8pÇ8pwOF3@V�pʷAm8pÇ8pÇ8pY9fqV0�i*�@�D^Bφ"v=%`/0$M\8pÇ8pÇ8pʴqr56P}IIe*E_Brbk	Ӳb?i	U|�%B,Ç8pÇ8pÇ8pÇJ%FYRcr%Yn˙QBpCr	ОT24	
    ڸpÇ8pÇ8pÇae?WdbMIKF/S&G9kP'"fQP! 0"@/D[i[,# >nAOHP" z900Ne[e	1RY5$TC�kʪ8
    5uDAI2{,Ge&Q_CÈ?�"� !Ё"I@9|Ërzx"$`R E)C؉wy"R%iIZ:}	_A#59iM@?Ph'�&z,U(K5/MHN@,,%wsBT|ÚDȝ,M��oD`,�띔2FRyP$���Yb&6	tz!D'�_(,#xɚ$H^PZ"�p6IUB@JQz
    ӱR	Mڹr˗.\r˗.\rːZEʐP4DI
    .\r˗.\r˗.\v7WsD'iR~C.\r˗.Fp&�JN`?-Lpƕ'9r˗.\r-ILAcLT%D`\	OWSm7 ~߿~߿~CvP4D€GVQr8pE7\\JzL¸A^g=sl=sts})`53
    ZZN\qqq積+ٿ+TE@0) w	UUr~UֶȦwCΐlܬUC˗1=[J`"F7\\
    L¸Og
    `@tǼX~!2* E b܍wL8@}Q,!A<lˣ HH:AC$\) Qa"ùa㣞?S8Wi"h@yPD"#<
    ohPH0&(@B�@Bȅ9
    $#p}dDd�@5�
    SP.8N
    =dP(N	IATae5HȂ"JFP@h)I{ <-J�	^p!nz�!- ɺk�}Zb3�d!"A%l{{{[t\l$bDH1'	Hʐbs,j8psD-<1&!%IiOj]Ys==G=>+B|'
    (PB
    (PZI2
    CP65lN`2'*1pBlqqq/3
    r[_utP*nazN5bJ%Fb@XJAGՙ!"lLwx`!V\@Byj%6KP�T7(oRd{{{}i8Wweu?['ZE햋,>BE7HM&	(uծ(426�T!]JG:pʭkx`/&0d�@�*p"axzn
    s	CjPT(	uPF[s�>_لDQEJP5
    @@P׏ȣ-d{Z7\\~Eɓ&L2dɓ&L2dɓ&Lv;.,L¸j\\~?Jp\!Z&iB"(PB
    V}YP	"lN΀9nLta]Zs}R/e'!zql-3
    ZZAuqqqZg
    0a㣞=CVDAFH1h%U (kBElM*B.6E	)	ۆ
    RGS
    zAuqqqyLejH	f'�x(�Gc51u8^*zdD`*vEP6AX(]a[Sڂ88r$Z	Ȣ+�Sm8p»
    8pÇ8N2*H)ksZGqV,,mhAmgZ:5\#
    .8pÇWa]8p9KZ@b@Mn6:9:s|->@_ӂ=L@֧e$ t^1z�>QJ$m9J>@"zTKx(N#ݶ0=uuB\IDI5!@okaA3CuqqqiegO@
    !&XBP'a�*[|Ăڅ8qk߼߸]UP�PA	@OXvBd
    &%9[&��luqqqi.X%.0\SP‹bElbFn8D."4CЂhhW_Q3(=b�jߘ"8ZO>YA}T-bB=gH{{{\	OZքHBU&rFCP
    ȨS!$BXu`A1uH>vվN	ӽ4i	`*uC!(d0#)J3`cml-A%h(P
    (P
    (Pm5&pqB
    )9eE]Uo/Ji勱(G&PBܝq<!O C%~V#ZaJ([o)~2_$kp!R �[덙
    9 PBiX[mX3z@!�=~|&OײZ%/ˏ27lِC0۩h6e�zcIP�vMrF=v$TSa
    (  fG]8�xÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇKGICRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*[TRJ*TRJ*TRJ*TRׂ4?��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/004/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020136� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/004/gophertiles.jpg������������������������������������������0000664�0001751�0001751�00000001346�14156077574�023177� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    
    
    
    
    		
    
    �� � "�����������	
    ���}�!1AQa"q2#BR$3br	
    %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz�������	
    ��w�!1AQaq"2B	#3Rbr
    $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz���?�*74^5uG?]O8&կmQo7R}GL*ojE]y~'?yx�Sw+nWRCjkFy,h5W栛#������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/006/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020140� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/006/header.html����������������������������������������������0000664�0001751�0001751�00000000037�14156077574�022264� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<title>My Header Title</title>
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/006/006.js���������������������������������������������������0000664�0001751�0001751�00000001507�14156077574�021014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**
     * JavaScript Functions File
     */
    function returnDate()
    {
      var currentDate;
      currentDate=new Date();
      var dateString=(currentDate.getMonth()+1)+'/'+currentDate.getDate()+'/'+currentDate.getFullYear();
      return dateString;
    }
    
    function returnHour()
    {
      var currentDate;
      currentDate=new Date();
      var hourString=currentDate.getHours()+':'+currentDate.getMinutes()+':'+currentDate.getSeconds();
      return hourString; 
    }
    
    function javaScriptMessage(){
    	return 'This section is generated under JavaScript:<br>';
    }
    
    function mainJavascript(){
    	document.write(javaScriptMessage())
    	document.write('<ul class="listElements">');
    	document.write('<li>Current date (dd/mm/yyyy): ' + returnDate());
    	document.write('<br>');	
    	document.write('<li>Current time (hh:mm:ss): '+returnHour());
    	document.write('</ul>');
    }�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/006/006.css��������������������������������������������������0000664�0001751�0001751�00000000330�14156077574�021161� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@CHARSET "ISO-8859-1";
    body{
    	background:HoneyDew;
    }
    p{
    color:#0000FF;
    text-align:left;
    }
    
    h1{
    color:#FF0000;
    text-align:center;
    }
    
    .listTitle{
    	font-size:large;
    }
    
    .listElements{
    	color:#3366FF
    }��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/007/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020141� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/007/007.py���������������������������������������������������0000664�0001751�0001751�00000001264�14156077574�021032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import cgi, sys
    import cgitb; cgitb.enable()
    
    print "Content-Type: text/html;charset=UTF-8"
    print
    
    print """\
    	<!DOCTYPE html><html><head>
    	<title>HTML/2.0 Test File: 007 (received data)</title></head>
    	<body><h1>HTML/2.0 Test File: 007</h1>"""
    
    # alternative output: parsed form params <-> plain POST body
    parseContent = True		# <-> False
    
    if parseContent:
    	print '<h2>Data processed:</h2><ul>'
    	form = cgi.FieldStorage()
    	for name in form:
    		print '<li>', name, ': ', form[name].value, '</li>'
    	print '</ul>'
    else:
    	print '<h2>POST data output:</h2><div><pre>'
    	data = sys.stdin.read()
    	print data
    	print '</pre></div>'
    	
    print '</body></html>'��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/001.html�����������������������������������������������������0000664�0001751�0001751�00000000373�14156077574�021032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML> 
     <html>
       <head>
         <title>HTML/2.0 Test File: 001</title>
       </head>
       <body>
         <p><h1>HTML/2.0 Test File: 001</h1></p>
         <p>This file only contains a simple HTML structure with plain text.</p>
       </body>
    </html>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/003.html�����������������������������������������������������0000664�0001751�0001751�00000000474�14156077574�021036� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML> 
     <html>
       <head>
         <title>HTML/2.0 Test File: 003</title>
       </head>
       <body>
         <p><h1>HTML/2.0 Test File: 003</h1></p>
         <p>This is a text HTML file with a big image:</p>
    	 <p><img src="003/003_img.jpg" alt="GSMA Logo" style="width:269px;height:249px"></p>
       </body>
    </html>
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/009.py�������������������������������������������������������0000664�0001751�0001751�00000000770�14156077574�020527� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import cgi, sys, time
    import cgitb; cgitb.enable()
    
    print "Content-Type: text/html;charset=UTF-8"
    print
    
    print """\
    	<!DOCTYPE html><html><head>
    	<title>HTML/2.0 Test File: 009 (server time)</title></head>
    	<body><h1>HTML/2.0 Test File: 009</h1>
        <p>60 seconds of server time, one by one.</p>"""
    
    for i in range(60):
    	s = time.strftime("%Y-%m-%d %H:%M:%S")
    	print "<div>", s, "</div>"
    	sys.stdout.flush()
    	time.sleep(1)
    
    print "<p>done.</p></body></html>"��������httpd-2.4.64/test/pyhttpd/htdocs/test1/007.html�����������������������������������������������������0000664�0001751�0001751�00000001450�14156077574�021035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html>
    <html>
    <head>
    <meta charset="ISO-8859-1">
    <title>HTML/2.0 Test File: 007</title>
    </head>
    <body>
    	<h1>HTML/2.0 Test File: 007</h1>
        <div><p>This page is used to send data from the client to the server:</p>
    		<FORM ACTION="007/007.py" METHOD="post" ENCTYPE="multipart/form-data">
    			<input type="hidden" name="pageName" value="007.html">
    			Name:<input type="text" name="pName" value="Write your name here." size="30" maxlength="30"><br>
    			Age:<input type="text" name="pAge" value="00" size="2" maxlength="2"><br>
    			Gender: Male<input type="radio" name="pGender" VALUE="Male">
    					Female<input type="radio" name="pGender" VALUE="Female"><br>
    			<input type="submit" name="userForm" value="Send">
    			<input type="reset" value="Clear">
    		</FORM> 
    	</div>
    </body>
    </html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/002.jpg������������������������������������������������������0000664�0001751�0001751�00000260374�14156077574�020660� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF�,,��XICC_PROFILE���HLino��mntrRGB XYZ ��	��1��acspMSFT����IEC sRGB������������������-HP  �����������������������������������������������cprt��P���3desc�����lwtpt�����bkpt�����rXYZ�����gXYZ��,���bXYZ��@���dmnd��T���pdmdd�����vued��L���view�����$lumi�����meas�����$tech��0���rTRC��<��gTRC��<��bTRC��<��text����Copyright (c) 1998 Hewlett-Packard Company��desc�������sRGB IEC61966-2.1�����������sRGB IEC61966-2.1��������������������������������������������������XYZ ������Q����XYZ ����������������XYZ ������o��8��XYZ ������b����XYZ ������$����desc�������IEC http://www.iec.ch�����������IEC http://www.iec.ch����������������������������������������������desc�������.IEC 61966-2.1 Default RGB colour space - sRGB�����������.IEC 61966-2.1 Default RGB colour space - sRGB����������������������desc�������,Reference Viewing Condition in IEC61966-2.1�����������,Reference Viewing Condition in IEC61966-2.1��������������������������view������_.����\���XYZ �����L	V�P���Wmeas����������������������������sig ����CRT curv�����������
    �����#�(�-�2�7�;�@�E�J�O�T�Y�^�c�h�m�r�w�|�������������������������
    %+28>ELRY`gnu|&/8AKT]gqz�!-8COZfr~ -;HUcq~
    +:IXgw'7HYj{+=Oat2FZn		%	:	O	d	y						
    
    '
    =
    T
    j
    
    
    
    
    
    "9Qi*C\u
    
    
    &
    @
    Z
    t
    
    
    
    
    .Id	%A^z	&Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l   !!H!u!!!"'"U"""#
    #8#f###$$M$|$$%	%8%h%%%&'&W&&&''I'z''(
    (?(q(())8)k))**5*h**++6+i++,,9,n,,--A-v--..L.../$/Z///050l0011J1112*2c223
    3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<'<e<<="=a==> >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JKKSKKL*LrLMMJMMN%NnNO�OIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G
    k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4
    uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-�u`ֲK³8%yhYѹJº;.!
    zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs
    2F[p(@Xr4Pm8Ww)KmExif��MM�*������������������b�������j(�������1�������r2�������i�����������-��'�-��'Adobe Photoshop CS2 Macintosh�2007:11:07 14:38:51���������������@������?��������������������������&(�������������.�������������H������H����JFIF���H�H���Adobe_CM��Adobe�d�����			
    
    
    
    ���"���
    ?����������	
    ���������	
    �3�!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw�5�!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw���?�Α;tCKӯҥm_g�/g�c�:_K�}O�IOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�tPl�[0zwQ/}J*Y;){꥖8~zU]�$?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$+}*έ4=:ZxѮ*ѿ�r697˂.0A�z_?3a%^ru���z??VJr�q�p�k�@o[ǡknm,_�|N<CVŰa#QT_ë[��_�|ʮV��!N/?Ɨ.c�m*��X�|uʤ$L:8GI @LRZǣ�g�'�%txi[	%KGį3s-l�	
    C{gǖ12c7_f�A_͋ȩ(w=b츺7z7_�.[?F�k?eB9nO$J7qI$JR?�Ŭ~7;�pg.V��!r��V1?Ɨ.c�m9Uv�Ɨ.c�m?6fihuf?g1qTwI&:7ypc@y)$y)&;<w[-l�+Oߔ-lQl�	#jr_Û?1HP&:ԯ5�RXQ�'嗓/g�z$J
    ۢI%QYd`o�ׂ~�7;�???7u_�}3�]W�L��B?Ɨ.c�m*��X�|usW}RX]PqXpKnlWcv%<JK?h?gݑ�R$�vOIOO"ҰZ_7u9~}HV`fct;CZ}[HG$R^CI�+>*�V}?U%>^gZ}nͣcvf�I»,obc�Vs}a5bzack{Cu=~rJ|%?ğ³�ҫ`?X>`?u�'^S/P$�vOT'_xWw.[}lIyeّ]{Smڒ<I{U,~cuk/8nqyfclmu9h?gݓ�RS/O$�vGY_CEoٝ69zOmKoܒu_�}3�]W�L��BJ?Ɨ.c�mO#ci�?t_C&gLg6l�Sխ%>fc鿴-e>sKvΌ�SO�.�U{Y\
    }V-2]Q[$IHzoүvGMĹ5?'׺wG~ezW[ewfI-}7Q7mǽi�ScGuC}}<2[`O_XzXyWn
    ב]WKYouN{IHUZg7eb�Q.1
    >C�O?/ܻ�yR�SO�.�dcҰ{z-,ײmu?oHe�t?�wԺzOX4\R/}Ϸժj羪�]��=㤧�[>?�-))_^}\޼zװG>8kzJzRhn-�em5Շkuvzk�c�
    �ޤǐ?G1r
    ˒SL`(Y�l7�z?]~Bޘa͕k�נ_iԮ
    Fok,}wlIO.V��!YWQ̊Nn1uePF>̯O
    9"I�Jpijƿ.H߱䵞~%??Ɨ.c�m/UcmcK\5uK�}O�IM��/߳�&�e�o�TIM˺YS~~M<C}sHS\U{[v=}+qk{a	$�9_4o��ɪ)$GVUrs/A5kqj}C>gWk1
    1}@v@I%)ym {>}Og~RclǪ=:^9[ $әnId7=D-v	$3+&܆m{ `yvϠRc\wZ\lvK/Tg+,�N,ysK89Irk��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*+cfwQ>%gK'e4�e2+w,k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S.V��!?5^��fQ8>%gK}7TeW>,o$4Photoshop 3.0�8BIM%���������������������8BIM����<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>com.apple.print.PageFormat.PMHorizontalRes</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMHorizontalRes</key>
    				<real>72</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMOrientation</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMOrientation</key>
    				<integer>1</integer>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMScaling</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMScaling</key>
    				<real>1</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMVerticalRes</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMVerticalRes</key>
    				<real>72</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.PageFormat.PMVerticalScaling</key>
    	<dict>
    		<key>com.apple.print.ticket.creator</key>
    		<string>com.apple.printingmanager</string>
    		<key>com.apple.print.ticket.itemArray</key>
    		<array>
    			<dict>
    				<key>com.apple.print.PageFormat.PMVerticalScaling</key>
    				<real>1</real>
    				<key>com.apple.print.ticket.client</key>
    				<string>com.apple.printingmanager</string>
    				<key>com.apple.print.ticket.modDate</key>
    				<date>2007-11-07T14:36:21Z</date>
    				<key>com.apple.print.ticket.stateFlag</key>
    				<integer>0</integer>
    			</dict>
    		</array>
    	</dict>
    	<key>com.apple.print.subTicket.paper_info_ticket</key>
    	<dict>
    		<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.printingmanager</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
    					<array>
    						<real>0.0</real>
    						<real>0.0</real>
    						<real>783</real>
    						<real>559</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.printingmanager</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
    					<array>
    						<real>-18</real>
    						<real>-18</real>
    						<real>824</real>
    						<real>577</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.PMPaperName</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.PMPaperName</key>
    					<string>iso-a4</string>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.print.pm.PostScript</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2003-07-01T17:49:36Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>1</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
    					<array>
    						<real>0.0</real>
    						<real>0.0</real>
    						<real>783</real>
    						<real>559</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
    					<array>
    						<real>-18</real>
    						<real>-18</real>
    						<real>824</real>
    						<real>577</real>
    					</array>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.printingmanager</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2007-11-07T14:36:21Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>0</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
    		<dict>
    			<key>com.apple.print.ticket.creator</key>
    			<string>com.apple.print.pm.PostScript</string>
    			<key>com.apple.print.ticket.itemArray</key>
    			<array>
    				<dict>
    					<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
    					<string>A4</string>
    					<key>com.apple.print.ticket.client</key>
    					<string>com.apple.print.pm.PostScript</string>
    					<key>com.apple.print.ticket.modDate</key>
    					<date>2003-07-01T17:49:36Z</date>
    					<key>com.apple.print.ticket.stateFlag</key>
    					<integer>1</integer>
    				</dict>
    			</array>
    		</dict>
    		<key>com.apple.print.ticket.APIVersion</key>
    		<string>00.20</string>
    		<key>com.apple.print.ticket.privateLock</key>
    		<false/>
    		<key>com.apple.print.ticket.type</key>
    		<string>com.apple.print.PaperInfoTicket</string>
    	</dict>
    	<key>com.apple.print.ticket.APIVersion</key>
    	<string>00.20</string>
    	<key>com.apple.print.ticket.privateLock</key>
    	<false/>
    	<key>com.apple.print.ticket.type</key>
    	<string>com.apple.print.PageFormatTicket</string>
    </dict>
    </plist>
    8BIM�����x����H�H����/8Ag{����H�H����(����d���������������������h������ ��������������������������8BIM�����,����,����8BIM&���������������?��8BIM
    ��������x8BIM��������8BIM�����	���������8BIM
    �������8BIM'�����
    ��������8BIM�����H�/ff��lff�������/ff���������2����Z���������5����-��������8BIM�����p����������������8BIM����������@��@����8BIM���������8BIM����I�������������?��@���
    �U�n�t�i�t�l�e�d�-�1��������������������������������@��?��������������������������������������������null������boundsObjc���������Rct1�������Top long��������Leftlong��������Btomlong��?����Rghtlong��@���slicesVlLs���Objc��������slice������sliceIDlong�������groupIDlong�������originenum���ESliceOrigin���
    autoGenerated����Typeenum���
    ESliceType����Img ���boundsObjc���������Rct1�������Top long��������Leftlong��������Btomlong��?����Rghtlong��@���urlTEXT���������nullTEXT���������MsgeTEXT��������altTagTEXT��������cellTextIsHTMLbool���cellTextTEXT��������	horzAlignenum���ESliceHorzAlign���default���	vertAlignenum���ESliceVertAlign���default���bgColorTypeenum���ESliceBGColorType����None���	topOutsetlong�������
    leftOutsetlong�������bottomOutsetlong�������rightOutsetlong�����8BIM(��������?������8BIM��������8BIM����������������,������JFIF���H�H���Adobe_CM��Adobe�d�����			
    
    
    
    ���"���
    ?����������	
    ���������	
    �3�!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw�5�!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw���?�Α;tCKӯҥm_g�/g�c�:_K�}O�IOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�/t��I%=W:_^����t�?U$_}{�?�y�KY��ιTS�,�K�/g�c�:RIOU�׿�1�tPl�[0zwQ/}J*Y;){꥖8~zU]�$?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$+}*έ4=:ZxѮ*ѿ�r697˂.0A�z_?3a%^ru���z??VJr�q�p�k�@o[ǡknm,_�|N<CVŰa#QT_ë[��_�|ʮV��!N/?Ɨ.c�m*��X�|uʤ$L:8GI @LRZǣ�g�'�%txi[	%KGį3s-l�	
    C{gǖ12c7_f�A_͋ȩ(w=b츺7z7_�.[?F�k?eB9nO$J7qI$JR?�Ŭ~7;�pg.V��!r��V1?Ɨ.c�m9Uv�Ɨ.c�m?6fihuf?g1qTwI&:7ypc@y)$y)&;<w[-l�+Oߔ-lQl�	#jr_Û?1HP&:ԯ5�RXQ�'嗓/g�z$J
    ۢI%QYd`o�ׂ~�7;�???7u_�}3�]W�L��B?Ɨ.c�m*��X�|usW}RX]PqXpKnlWcv%<JK?h?gݑ�R$�vOIOO"ҰZ_7u9~}HV`fct;CZ}[HG$R^CI�+>*�V}?U%>^gZ}nͣcvf�I»,obc�Vs}a5bzack{Cu=~rJ|%?ğ³�ҫ`?X>`?u�'^S/P$�vOT'_xWw.[}lIyeّ]{Smڒ<I{U,~cuk/8nqyfclmu9h?gݓ�RS/O$�vGY_CEoٝ69zOmKoܒu_�}3�]W�L��BJ?Ɨ.c�mO#ci�?t_C&gLg6l�Sխ%>fc鿴-e>sKvΌ�SO�.�U{Y\
    }V-2]Q[$IHzoүvGMĹ5?'׺wG~ezW[ewfI-}7Q7mǽi�ScGuC}}<2[`O_XzXyWn
    ב]WKYouN{IHUZg7eb�Q.1
    >C�O?/ܻ�yR�SO�.�dcҰ{z-,ײmu?oHe�t?�wԺzOX4\R/}Ϸժj羪�]��=㤧�[>?�-))_^}\޼zװG>8kzJzRhn-�em5Շkuvzk�c�
    �ޤǐ?G1r
    ˒SL`(Y�l7�z?]~Bޘa͕k�נ_iԮ
    Fok,}wlIO.V��!YWQ̊Nn1uePF>̯O
    9"I�Jpijƿ.H߱䵞~%??Ɨ.c�m/UcmcK\5uK�}O�IM��/߳�&�e�o�TIM˺YS~~M<C}sHS\U{[v=}+qk{a	$�9_4o��ɪ)$GVUrs/A5kqj}C>gWk1
    1}@v@I%)ym {>}Og~RclǪ=:^9[ $әnId7=D-v	$3+&܆m{ `yvϠRc\wZ\lvK/Tg+,�N,ysK89Irk��IO?Ɨ.c�m*��X�|uʤ$I)I$JRI$I$$I)I$JRI$I$.V��!r��IO?Ɨ.c�m*+cfwQ>%gK'e4�e2+w,k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S$k~o��ƷV��]%<K�ƷV��]/k~o�S.V��!?5^��fQ8>%gK}7TeW>,o$�8BIM!�����U�������A�d�o�b�e� �P�h�o�t�o�s�h�o�p����A�d�o�b�e� �P�h�o�t�o�s�h�o�p� �C�S�2����8BIM�����������C��C�?@�����������
    	�����������	����������������������������������������������������������������������������������������������������������������������������������1D�������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4������������������������������������������������������������&cr
    $2������������������������������������������������������������	ܰ�I�����������������������������������������������������������f7,�0C �������������������������������������������������������������4�����������������������������������X(-�����������������2c@�����	ܰ�I����������������������������������5ܠ�����������������R*F�����3�i!�����������������������������������5p;�����������������
    Qp\u!�����&cr
    $2�����������������������������������fr����������������J.1�����nX�a@����������������������������������wP�����������������)EÕqԆ#�������4�����������������������������������YX8�����������������(r:`�����1`�����������������������������������3]k@�����������������UR�����f7,�0C ����������������������������������fk`w(�����������������ʸC�����LHd�����������������������������������,wy�����������������\9WHb0�����	ܰ�I����������������������������������5ܠ�����������������R*F�����3�i!�����������������������������������5p;�����������������
    Qp\u!�����&cr
    $2�����������������������������������fr����������������J.1�����nX�a@����������������������������������wP�����������������)EÕqԆ#�������4�����������������������������������YX8�����������������(r:`�����1`�����������������������������������3]k@�����������������UR�����f7,�0C ����������������������������������fk`w(�����������������ʸC�����LHd��������������������սO|x@<=|�Axgu��5p;�����������������
    Qp\u!�����&cr
    $2��������������������F7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4��������������������	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��������������������$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��������������������M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2��������������������F7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4��������������������	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ��������������������$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��������������������M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2��������������������F7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4��������������������	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ����������z7m�����95C�$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I���������~f�������ɥq�HTN�����������
    inp�YX8�����������������(r:`�����1`����������Vշ�������+J)\�M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2����������2o�������WKR,#G曅S8�����������)fk`w(�����������������ʸC�����LHd����������{e[7V0�������=+pXF7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4����������ʶn`������],zWJnO�����������`x/�5ܠ�����������������R*F�����3�i!����������=l[|������X2`	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��>@����xU�Uum�������
    cҸW$hp}'�����������4}�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ��$܀����.(`{e[7V0�������=+pXF7
    p�����������SKo0<ߋwP�����������������)EÕqԆ#�������4���	9ƅ ����"JVշ�������+J)\�M©������������5p;�����������������
    Qp\u!�����&cr
    $2���~Nqm����jR�Uum�������
    cҸW$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_~.�3]k@�����������������UR�����f7,�0C ��$܀����.(`{e[7V0�������=+pXF7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4���	9ƅ ����"JVշ�������+J)\�M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2���~Nqm����jR�Uum�������
    cҸW$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��$܀����.(`{e[7V0�������=+pXF7
    p�����������SKw0<݋wP�����������������)EÕqԆ#�������4���	9ƅ ����"JVշ�������+J)L�M©�����������b�5p;�����������������
    Qp\u!�����&cr
    $2���~Nqm����jR�Uum�������
    cҸW$hp}'�����������4s}ظ�,wy�����������������\9WHb0�����	ܰ�I��h[r����(k=l[|������X2`	?4*I����������M-_v.�3]k@�����������������UR�����f7,�0C ��^`����#>@~`뛜��|>\rXp,i������������Ps}�,uth]�����������������;s.?X�����nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd���ݝ/y�������#G@�d�������~"t)(�띎,���������?)[6�mϖ`�������|G������f7,�0C ���L���������$@-Rd���������?#O�����������y CP���������AU������3�i!���j@�����������
    ���������)	!�����������!@KZ���������Gq�����f7,�0C ��7D����������Vs`;����������3p4|������������3i���������f �������4��>�������3]�%ذR3b�������RN�p`P4(w%����;u%����;u�SB8�������K2�����1`���,��������7�Qs`�������v0By3ph���@�3ph���@�8g4.?@�������l.�����1`���,��������7<cy�Qs`�������v0Bz�3ph���@�3ph���@�8g4.?@�������lz:J2������LHd���Fހ #��������\(n	oE6,Eu������cH3
    �A���
    ��A���
    ��wи�������	(�����3�i!��z�@�������?(/1`
    ,c�������	^S84���84���3�A�������6v%������&cr
    $2���X#o@����������x͌U6<G�������4(w=���4�w=���4�wfSB3�������Ξ\'c �����nX�a@��m1�����������&qg���Gy$g#lj<D,�
    �A���
    ��A���
    ��wиq_�������jŞz:J2������LHd���Fހ #�����������k(��������><�g����g����p;h\����������td�������4��`�@F ���]�����<Y	יc@��������%gBz�3ph���@�3ph���@�8g4.����������:J2������LHd���Fހ #����@����%�{c$Cڞ$�������9
    �A���
    ��A���
    ��wи����������(�����3�i!��z�@���ۼ+����&=����}=	f{dz$3=I@8g;@����;@����;3?)pȌ�������OH�����1`���,����=����[���������m#�p`P4(w=���4�w=���4�wfSB3������������1`���,����?t��#Z%xлχҰ@�������4s=`Щp���������yMp�������/@:J2������LHd���Fހ #��������\(n	oE6,Eu������cH3
    �A���
    ��A���
    ��wи��������B�c �����nX�a@��m1��������F0^cb\X�������4=@Щp���������yMp�������/@:J2[õ�_QGo&�1`���,��������7<cy�Qc�������v0By3ph���@�3ph���@�8g4.3?�������lP�($x9VkO+|7W`f7,�0C ��nX˜x�����uiP\e@���}��XǶ|S84���84���3��������6(^td6ss.[3Ś1�&cr
    $2���h����������2Xn@���������,G(S84���84���3��������6&^td62rLu	ܰ�I������������?;���������TfNg����g����p;h\f�������ءz�1Q@gd#tJ&^
    F�1`���;z0��������s !;p\��������	2A`;@����;@����;3?)p��������b�IF@;
    m~O=IN1�&cr
    $2����$}>�}>�}iq@�W-Ϡ}���&Uc�%�z����%�z����%> Ȯ�������]c߀R�YPVt0p˖�LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�a@�����������������������������������������������������������3�i!������������������������������������������������������������LHd������������������������������������������������������������1`������������������������������������������������������������nX�d،�����������������������������������������������������������&�������������������������������������������������������������������������������������������������������������������������������3������7 50@Pp1346`G���'~occccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccӂ�?UAaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aaq0Aa�r�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1V�X`U1SWG=GAa�p~~L=y};q0g:G=GAa�p~~L=y};q0g:G=GAa�p~~L=y};q0g:G=GAa�p~~L=y};q0xbhMCW٫vj;5z^fCW٫vj;5z^fCW٫vj;5z^fCW٫vj;5z^fKB8z:{`y.t#0ç}B8z:{`y.t#0ç}B8z:{`y.t#0ç}B8z:{`y.t#0ç}B8z:{`y.t#0ç}B8zbUh+N2ӌB!zq8^d/N2ӌB!zq8^d/N2ӌB!<:F{Ͼp~~L=yֻ[JZ=<g:G}k^{Ͼp~~L=yֻ[JZ=<g:G}k^{Ͼp~~L=yֻ[JZ=<g:G}k^{Ͼp~~L=yɢ�ΓX5
    @jP,`X5
    @jP*
    ZC^{Ͼp~~L=yɫn+׹ht\=GAaj�?94;[JZ=<g:G|k}ҽ{O}>;q0&sC^{Ͼp~~L=yɫn+׹ht\=GAaj�?94;[JZ=<g:G|k}ҽ{O}>;q0&sC^{Ͼp~~L=yɫn+׹ht\=GAaj�?94;[JZ=<g:G|k}ҽ{O}>;q0&sC^{Ͼp~~L=yɫn+׹ht\=GAahlB
    *kB
    *kB
    *kB
    hVt0)hx1bŊ3(X1bŊ3(X1bՊ3V(X1bՊ3(X1bŊ3V(X1<5fKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRKe,]vRxh:\j^,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *,B
    *	褣n#0D8zC0D8zC0D8zC0D8zC0D8zC0n{Zeku%tp
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    M{!w[P+z]%~n5K'p
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    P
    TXҧ- 29;6.qjVZ)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)B)RhIXů�pIn͊ʝ
    ](](](](](](](](](](](](](](](](](](](](]*BUo�'zF8z?qdwb/v
    `YM#Qk^$6JKcSXV-)gCV|\Uj^W5jri?zE@bSK+l
    q0*c7@[(mCg�yմjF@SˆM9
    g3lak-YХpk7N>&-Acug{&<䰙RCQF-ZƣxH<<<=eT5v#b~mfMYQbѻ~q0$UGJO�jWnRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRUJ'J.\dRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRTRU";}>7ڨHuQHuQHuQHuQHuQHuQHuQHuQHuQHuQHuVS)?$TVFȤ:::::::::::)W
    _aU߁SSSSSSSSSSSSSSSSSSSSSЍjC[#GGFmGAaDRY�~Ywii!؋ۓ]a}]}˰ϵÛPғL=yKһg/]f}Kb/nOu9v{.>ۛnۛ@jJNq0$K5/+J|!u}-_}>7ۏpgq_nok9_no�I);G|,Լ+Z>>*.>Q8xbꢐ֖5wYwii!ҹ$Gu\CCC~Jo'u9v{.>ۛnۛ@jJNq0$K5/+Jͼ\<&]RXFkQSKuo ̏CNmU\\ޚFq_n=×aku7t	5}'B8z%wX6npD.>E-^Nn_
    5h *k3=tt7Si,P8}XoVBpqSXXWᦲ‰V,mӄ˕o(ēWTk}6ۏpgq_nok9_k~(ȲƲȲȲȲȲȲȲȲȲȲȲƲƲȲȲȲȲȲƲȃ,v�[}'B8z%w[g]}Զ]U*Y	ӫ6؍wm}9v{.>ۛnm'B8z%w)W6H H H H H H H H H H H H H H ;/#tdI=Z(/T%|t|wXon=×akǸr3}Rw#0"YyZWrs/h`<mUIϢ[4WMUZCiu?{WxuiUw.UZ~..UUBq_n=×aku7ғL=yKһ~C�*ժ�j7Bd,P*
    5?
    N4?ʥ~*Jt_m?;rV�teh-Q[8QH^�
    Wx{i/R.о{.>ۏpgs{]atUUUUUUUUUUUUUUUUUUUUTk);G|,Լ+N9ϗ:~r}7o˰ϵ9vXsp-da#>Hj^VܪfYzzzzzzzzzzڤI\U�::�:l8N_ܟF
    Ǹr3}]}7/7Kf!}'B8z%wJ_sKI_ܟB
    Ǹr3}]}7/7Kf!}'B8z%wJ_sKI_ܟB
    Ǹr3}]}7/7Kf!}'zD				>e_РHpfn,apAaDRjzYwii!؋ۓ]a}]}˰ϵÛl$/N9-h7(z{^Czzk;5*xbȁDgZeYAaG5H{mSo�:�:�:�:�:�:�:�::�::�:�:�:�:�:�:�:�:�:�:WYGP4^܄������������������qe~q�a}]}˰ϵÛl$/Û*ީW5ݠ+ZHhL=y=Uw-<:;-jVqة<~wxu9v{.>ۛnۛۥLғn.�l\Y拾^SbK꼏geG|%Ch9&J՘J,chV7/˰ϵ9vXsp-dspwB2z?c�jWBZT)+ZZHhL=ym_Q2Sz_'ag-] )ְgWh*5Nh$7߾Bq_n=×aku7٦H_iI}7q(QmqijRC@a#>cyjz͕&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&e&dҴᱧl۵n7QEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa<fG-?C:8777i9n	QbޢޢޟL%Gezzz7sR}TXoQXoQXoOQ&�zWZХg5<ɽxiItOD#F9lfq{mO}0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zC0D8zCٍCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCYCY9V{1_/R�I��	
    �����7PU 5qrs!6T`0@pt1A2"#Qa�?�Z,GQ\>2Gq٠)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ)e6;xQ`9FSaeMÞ&ĨVRR�<
    0̇a@ɋ`D[-y dV-Zfp02bX+Kk38AH1y蕋x֙ $tJżRL}L^k�%b)mug>&/5]o3}䁓.X[]i@ɋ`D[-y dV-Zfp02bX+Kk38AH1y蕋x֙ $tJżRL}L^k�%b)mug>&/5]o3tRE1,paNS<99z?s`.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F.jqZHN+ZitkM#`n58il
    4\ⵦ7KV6sS֚F(oNBx`qܜ�zy3I&/5]o3t$K*qjJKdƒL^k�%b)mug>IU-:.$tJżRL}Г,sŨ[U).u\3H1y蕋x֙ 'YVӋPR\`n42bX+Kk38ABOt?mTpi dV-Zfpe[N-BکIs@ɋ`D[-	=ʷ0ZRY1.X[]i{na8j%βcI&/5]o3t$K*qjJKdƒL^k�%b)mug>IU-:.$tJżRLu1Q#$vDS-πOXMЏ:a?&oNފL8'oE|EvS"_)g诔ȳvWdYa;z+2,߱CqNފL8'oE|EvS";	_)g诔ȳvWdYa;z+2,㰝o؎ފL8'oE|EvS";	_)g诓`*hCV(0iܟyNh œ,sŨ[U).u\3H1y蕋x֙ V)I(҄_qdK*qjJKdƒL^k�%b)mug:ՊRJa"}4:|\Y=ʷ0ZR[q.X[]ibnM(NOt?mTApi dV-ZfpX$f'J!~8wœ,sŨ[U).u\3H1y蕋x֙ V)I(҄_qdK*qjJKdƒL^k�%b)mug:ՊRJa"}4:|\Y=ʷ0ZRY1.X[]iW(yC)@WJjݠ_+5
    n/Қ7hMBtMSP])Sv|)@WJjݠ_+5
    n/Қ7hMBtMQL\F:a;_RJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZR[q.X[]iReMhw'BwRJa"}4:|\Y=ʷ0ZRY1.X[]iU
    +DaD2s@tW,67aU
    m7Xm{iobhM{E^oذ*|ņW,67aU
    m7Xm{iobhM{xX#h'ArPQ	9f1l|0l0tҜkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL)>rkL&UcIAtAr0a%r+֣7)�Aq!N;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂN;=PH/uĂ5%G['+4POM<à8Ӡ
    y`1S)Ջdr/'r,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ,5.'
    be	Xk"x&ZȻ&ܖ	hB Gg!0tC�[Qڈ~C�~3χD8?hQڈ{}wOO]?N'It%KK:KKQ}?�8��	�����4 PRSq2@`0p!A1ar�?�ZkP,Q-Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0Q`G㙂3f
    ?~9(s0QH)5Qy:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�:ŗ�XuT�?+8U+U+8U+U+8U+U+8U+8U+U+U+U+U+U+8U+8U+U+8U+U+U+U+U+U+U+U+U+U+U+U+U+U+U+8U
    S,`�iG,'AY*OMκ=e)>G
    85́R|nu7.I?i.nl
    sAYp
    ON
    isp`T6tz
    ˀR|pkKo\~ ӃZ\,'nu7.I?i.nl
    sAYp
    ON
    isp`T6tz
    ˀR|pkKo\~ ӃZ\,'nu7.I7ZJIF?}VG1	Y<%ds`}VG1	Y<%ds`}VG1	Y<%ds`}VG1	Y<%ds`}VG1	Y<%ds`}3izQ_ZpkKo\oV̘a�-85́R|nu7.I7J
    i{fD0-85́R|nu7.I7J
    i{fD0-85́R|]x#z֗dCӃZ\,'ͦ]x#z֗dCӃZ\,'ͦ]x#z֗dCӃZ\,'ͦ]x#pҬ4tK.zzg�~+8i^J�Wpҽ3?f4L٥zg�~+8i^J�Wpҽ3?fL,hS.҃Z^ّ:N
    isp T#iG,'&a4>]FJ
    i{fD0-85́R|]x#pxxu-(5ï,֗72I6tz
    ˀR|fAUl֗dCӃZ\,'nu7.I7	zMǁWQ҃Z^ّ:N
    isp`T6tz
    ˀR|fAUl֗dCӃZ\,'nu7.I7	zMǁWQ҃Z^ّ:N
    isp`T6tz
    ˀR|fAUl֗dCӃZ\,'ͦ]x#pxxu-(5ï,֗76IiG,'&a4>]FJ
    i{fD0-85́R|nu7.I7	zMǁWQ҃Z^ّ:N
    isp`T6tz
    ˀR|fAUl֗dYi.nl
    sAYp
    OLh<}v<
    ̈aZpkKo\n0]e"uf>m7:ŗ�jW
    UrҬ;aܴXw-*ùiVJZUrҬ;aܴXw-*ùh̡(t6Z*/HTUP=G#QX(g,vu3;
    :LŽraGS9cQX(g,vu3;
    :LŽraGS9cQX(g,vu3;
    :jRQA-%W(�u3ŽrQR
    :[aGS9Kl(g)mL-u3ŽrQR
    :[aGS9Kl(g)mL-u3ŽrQR
    :[aGS9Kl(g)mL-u3ŽrQR
    :[aGS9Kl(g)mL-=E&�<"�@0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0Ž0ŒVT�~ځP?d==========j?�w�_�����6 v!014@qrt"35APps#27QaR`$Bbu%CS&cDE��?�ڔ:MdEc|A2>,R-���
     �jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Nu8sƧh}5<CqZsO':jy9ևSδ>Kt{&ǧG1.)r
    S�Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗T^5HIuslt@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@t@Ϩ;T 2d)yr2�x"^?qOOiHxgː0)/|{JC8^\qLOo(7SSR/g3eD*~yF!"Ґ!{>aS._%S1
    pr�/JQnȧ<3^Ϙg˗zTCu>E=!/.B|8\Kҧ7b))yr2�x"^?qOOiHxgː0)/|{JC8^\qLOo(7SSR/g3eD*~yF!"Ґ!{>aS._%S1
    pr�/JQnȧ<3^Ϙg˗zTCu>E=!/.B|8\PsX"jNrCK6~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D~D˚F9D@
    e>)M^?qOOiHxgː0)/Mꜙ�'&K藥Oo(7SSR/g3eez& ɒ%S1
    prYtީɟ/rdzTCu>E=!/.B|8\]7rg/^?qOOiHxgː0)/Mꜙ�'&K藥Oo(7SSR/g3eez& ɒ%S1
    prYtީɟ/rdzTCu>E=!/.B|8\]7rg/^?qOOiHxgː0)/Mꜙ�'&K藥Oo(7SSR/g3eez& ɒ%S1
    pry$va	u"}zGש}zGש}zGש}zש}zGש}zGש}zGש}zGש}zGש}zGש}zD].ࠅПNߎNLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2Gk'=NLA%Kҧ7b))yr2$:81nnnnnnnnnnnnnnaHc�ٵP;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    ez& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    pr>\P;Y>^1]7rg/^?qOOiHxgː0)/#Kͼ/
    z& ɒ%S1
    prF J"?l+l+l+l+l+l+l+ QQe`C:(w#mmmmmmmmmmmmmmmmmmmmmb(N)n8zꦊ`U.T?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v?o	>v}UF1nTHrɬ!}EIs	iZl?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';l?i';?#BSt Q<{JC8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._TF
    -ž%ówW!lts}يG
    0d٠r.&/	iځqo^
    -#iHT5]`z"FLP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_6,KeGWֵehs[F!D,:4PP�(1e"./ΪhO.h~ a,	iRk(=Hui[b<͊sN-[t:*Zɔt-/_̟Ya|*vL/܀5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    MAEP`~+$_5
    L[9W{ZۧeԖ#у{9"ޝQ�?ebn$= OI[1[WI�V|8*�c4wq8�@-D-�D.RgG#EjzV�*�\L:nڳR?.dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZkɇ@mۻJc]<.P6@/�;UȑHq[xs(]\_~\9BDoX3�{c!Xi~հ =�6Y3MSr6'�!)Zv(ZrWY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i0VHZj/֚dY"i*2<Nc#DP벏DIS"a>v@[3s*jBGPN#tܛH
    r�mIyr27bjd!ֈAll([v(D
    ؂
    1HP<j^ձA 
    muE7?EƓH+鉴_l":cQ0kD Q%X[ɝJ"rtBoCta/Qإ;Zֻ>1h`2=Gtm( P:\5H~iWgCU%e!W5K�ќ�/y/	<΢yi[ph*$xD>>.܀([&PuzDER&G\iSG�+=<aɓJti&+	7M(I=Ÿ}Tт"ZZ!wqqwEwvvw $(Z)J_yG\rs\zAGc1-'D-k?2�r/g3ehLoHF2&M]0k-]0~vd[d,dS
    AvxSN֑n֞Kcu*se#ʘU*6I"ܓJw6[!&wGuH
    S�t~6ΏT_^vՠ53&n̿*%tT/Oh�k`hn
    `u#)I"e(ix� WtMO+&\PLk]ZQ
    1L%G1)EKjP-[*e8C P9&B+b#nEPw!Д/Z4aU
     6IBݓOZݫ{NC8^\qL}J
    KIXU�e"Agg'b7w7r:R
    (�Zvz9RegtL2<`!~EHC)L(JP)JPm"bM!ǨSҷVJ$gY8
    ;]ht0Ns?I^>K_|j�ݹ-Kax)�
    j((x)0[)|B7w	7T-c$PcSiHxgː0)/X%5'A]k`/'h1`wA(RUU#\h(VaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaURu);r	�0	4&~ɕ|1wl.fwwM@0jC}VaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUw	>X|74r*
    AhA!ۼq;6Hp#䔔wg"[GGL	jֈk]UGUjnfZYuVVaUUGUjnfZYuVVaUUGUjnfZYuV�aFѮw폤4^.	v^IIIqߡv~R EtqDΠHh6ڛYuVVaUUGUjnfZYuVVaUUGUjnfZYuVVaUUGUiiFh~CE	ހڷjMh.钉wBU6Gp;hґ49 e 
    �k~MM	V=Y*'54%ZfPЕj՚BzSBUOVjhJ	M	V=Y*'54%ZfPЕj՚BzSBUOVjhJ	M	V=Y*'54%ZfPЕj՚NcozE`yy*$vԺ1D�([�JEA)rc8ú""#Ґ!{>aS._RA yd|9k9py5`LfC_{8#]6h%q;6Hp#8OYCvkp8Tז/ݍ|d~^XBK)y>p_m)yr2+IÞ6OV
    dd>:|EkN6R[ód?X:7`6uK(n~myb{6Gp;wt/kX�u{Ґ!{>aS._RA yd|9k9py5`LfC_{8#]6h%q;6Hp#8OYCvkp8Tז/ݍ|d~^XBK)y>p_m)yr2+IÞ6 :fui<i-Թ	97
    M¬:=C'M:YzCɋtW`0fC_{8#]6BM�u{S]b�D&pYuVVaUUGUhqgHK
    _!wntN-۸&l|Gp8Tז8q>;e
    /ͯ,_Of~3k�R|ᎿtR/g3eV5?,1<mL`(vmmpz�#y5J"Z*;"aMc[8w)I~Lp=YI$b\|szTm"a0��cK-%ރ	
    6SV@P5yU0(Eܶ%9LSnDHp#8OYCvkp8Tז/ݍ|d~^XBK)y>p_m)yr2+IÞ6QB$2dtxyUBݑ4tb!0)()|aGA~Ί)sm;/>`Xpgg*wBbi�\XHSJYĪ#v؀r\[ڰqom�
    -c1'~+i~Lr_ˡ0
    b�0a&PܡDvt)vM?N⡃{"֞I-~J,sh7<@JÞc~-秸јduɟ8AC1E/m	]cf("F5Ĩrkf8p]avttS!?]q{0JEM�\cswUOK[]wD@U%GޘN/$nbn.uK(n~mycP݂lw%/G~R'8Lg]4+�oكw'IfPN}>&=A:M{0zta7oهw'IfP^}&}A:M{0t`7	oهw'IfPN}>&}AzM$.kC1P}r\�w=/'M!/.B|8\c\>A8sއ'IUEֹ6 �]]�kmGâ�wx500~cŞ7P8~x3晄Α{W!n>#\VM
    dM�Z0i8\/�ycP݂'q,c_)8z|ᎿtR/g3eV5?,1<jpwGhQGweӺݐꔦa#]3E+C<]3E+C<]3E+C<]3E+C<]3E+C<]3E+C<]3E+C<胬W3㹍0?:H
    OLbb$t>2NE2qx_#4eT^==0ZB`#ݐJrh{m$I"�\6{a@E1P"08\B$p_'q,8OYCvkƾSٲ?q߶~鴤<3^Ϙg˗Ԭk;Y'�cx�N\Ճo2%ث"$6zrWC0遮L-mk3.;GHA+	_ ّ5vɸ6qr9e^=2�he86ihM!/k0!KDx3m~bJ�-v#H5Kg6EKl^ӛEhF}}0k^PXBT*�tIG48|Yf*dQS%2?ݛ$p_'q,8OYCvkƾSٲ?q߶~鴤<3^Ϙg˗Ԭk;Y'�cx�N\Ճo2ӬN kw_i$GIpv"L+Z}L[$NpkѦG{gaOs.Dk5X�!K�L>Bܘp"ZmH6zV$=D4|LCpJޤUau݂P5̟FL{T}cKs(Liл�F sjK"=w+GwPܽEn-\-gC~v?"kVďBkQΤ<h{T<,M(d^}QmRyc=F&?rpf.uK(n~mycP݂lw?D;Gxn\h۵`xe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v7<XM&Vn}ɕۤxe`v3ZtC�uq\].L$06S8c6prp{$c˓Wm&WnΘ6R[ód?X:7`6uK(n~myb{6Gp;c_){~鴤<3^Ϙg˗Ԭk;Y'�cxݟpy@P00ktUveK\fZUveK\fZUveK\fZUveK\fZUveK\fY5&w3$!	4m&W+JҮxT]u{+ݮ:<*[dǃn2c7x1iiF{j=k\*kN6R[ód?X:7`6uK(n~myb{6Gp;c_){~鴤<3^Ϙg˗Ԭk;Y'�cx\->8^MX6+ِc'M:`9Io,oG͒8\/�ycP݂'q,c_)8ז/ݍ|kH|/wu{Ґ!{>aS._RA yd|9k9py5`LfC_{8#]6h%q;6Hp#8OYCvkp8Tז/ݍ|d~^Xv5!GO1YR2qrx<0ɕD@LqD뜺R9uvrJ'?\T>D`2fz1%ЇpRh<QYpMH)DY3,Ky~#VUn
    �@M2i{b6[؆Mfbŗ\ΰwIMAI3}bF\mڴ!7#;Twv~U]^@nQk*#>+yr2+IÞ6OV
    dd>:|EkN6R[ód?X:7`6uK(n~myb{6Gp;c_){~$vWM4x9HZ8ZP.SU4Y`^6XKUbz[v"}vikI%:? Ty+w]~kE?ٵnޞ5<|P;4D(	;L--&RKqESuyX0*nd1kG,i`.xbhB_OD-{"h'ԡhpL
    -
    "ԡØ]]CȺ f8#]/d<3^Ϙg˗ԤG(TAr<
    )Q5Zb b}	S"T
    oܜtۼLz
    &Lx=&<wAɏdǃn2c7x1L&Lx=&<�cwAɏdǃn2c7x1Lz
    &Lx=&<wAɏ,T&+n66m޺ƸI^ ntTD{6?]_xȹt]w'T4w9Z:U
    &Dki5HnO+wAɏdǃn2c7x1Lz
    &Lx=&<wAɏdǟn2c7x1Lz
    &Ly&<wAɏdǃn2c7x1#S&W'v.
    {֝ѻ
    G�-l|Gp8Tז8q>;e
    /ͯ,_Of~~k;ZC{8c/,w{?
    {T(#oA�])4,"0Tks#&?Š,q՘^ʪ:2")&碪6,
    2ɏiKɧKyr2"(Lr5!bEaI,l7+&c~Nn&`	i3MŽ� 4qփeC U76(8ŜS:*[w'"C`.莲(
    E+Eܶ?͒8\/�ycP݂'q,c_)8ז/ݍ|kH|/wu{38q>;g
    cҢ_rE/LMM4f5ֆKBg3hf9�3&tTG!r145]1|}E
    >/QS:86p*7'tխ+BU8o|t!{>aS._S5N{ѥָI؍F.wtbbQBEQC&3$ hZ^#	@	lG-B�f7
    wA2Ҫ
    w*7J* dGH�;q4tՋ^րGL6B߁GHu(?D^~|\BNs#8q>;e
    /ͯ,q|wR_^Xv5͑3ybv"y>p_^Y8cSt@I(\i#Ż�w8O:^2g4xz_Q;)]DO+�]m'nMф@
    oqC"wtXCLssli:|EC8^\qL}Nii3dUQ'rvr+%d~W:7DF!{pz#
    (CʑI4t iUWF02}nMh]@PHN)<1(56s[@7 ')zuYWgeJtC�  {B$[f=D@�NO4>Þ] (òJ�-~BewnFaJTǀQDr^P-"E[j-n+`O/:�ٲG,q|wR_^X:7`6~k=#8gi=E|Ꮏt?qߚ'q�v%2HB
    2E�k�$4_Iqgg uTw�/c\>AݧKyr2^ؗ#h"`~QԊ~�nMk-hR?ܔl-k"xJ	Qo	1
    -8&!E%(b[pLBxN	Qo	A1
    -8&!E'(b[PLBxN	Qo	A1
    -(&!E'(Lӑܓ0'P]xݰ[cQH]bO>#k
    2 *hsk[:XkZbr-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC-J]*;2ԥҮC,(FgҎ溺vpPgs퀁Rф-ސDғbCI:Ga(}kE>ԥҮC-J]*;2ԥҮC-Vq<)CpЁmTD-z5HɱTL!*i*SZ)MJ]*;2ԥҮC-J]*;2gQ#Ȫn=
    NBD"&S}2CDpAvi*SZ)MJ]*;2ԥҮC-J]*;2б T;cBt)mSMY:&4$A�EtAO֭hjRW!ٖ.rjRW!ٖN&0`X!�lhZ.E-z
    z�Խ0;d9rz2@TtũK\fZUveK\fZ!2${EE^J2$^2YYI"86x)M\Jrb{Z轟o+mTMB.n)YsGMUD5ְZL@ΑY>u+:K8L4�A(N`)wP"Dx)XLXM7xBnTL;{!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._prh<3^Ϙg˗G!/.B|8\9yr2xgː0)/C8^\qL4r/g3e!{>aS._pٶ+"s3A\ёYU=ɖр5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}5ځcX~}(BH|wpLrWAEP%XL6QE��0�����!1�A@Qa pq0P`񀠐��?!�4D ��0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`0`
    ?CDBP��������������������������������������������������������69fP~^yyyyyyyyyyyy綬YG~� �� �� �� �� �� �� �� �H|vۇnݻv۷nݻv۷nݻv÷nݮ?o~k�j��Z� �k�j��Z� �k�j��Z�#R,۷nݮv۷nݻv۷jFg1YKqj�;yj�;yj�;yj�;yj�;yj�;yj��38�$fvյ�rPk�nV�C �҆'o-[X@�;w/NZ�v_J\ma��ܾ1;yj�۹}(bvյ�rPk�nV�C �҆'o-[X@�;w/NZ�8h5?v]h5?v]h5?v]h5?A)a$Pbؿ}v/]bؿ}v/wbgZ_;~_N_d$e̔P!J*TRJ*TRJ*TRJ*TRsR08M\5&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ%
    X6R'Y������������������
    NX
    E]aε8b˗.\r˗.\r˗.^'Є9pfѿh04K0h8RѥE9̠U?I([5۔29b˗.\r˗.\r˗/+1gzS(FZ0*Ȩa>Nh)&C7o"8&0r˗.\r˗.\r˗.\r煦\/cy5r9C6ED,A\؂yٵ%]N+"MЦoU`d1r˗.\r˗.\r˗7H
    "$Ji1Va�}	F�Ƨh0WPBI0fV/KB1
    ϭƂp&<
    2+lyfO\jb��&#@-HU<۴nY�uP�lqIZ0P:"e��WD/(C'"2,ƠDc iRqPƋUl
    aIPdkGxbȖ@z"(w
    $ E!!+�`-`wxM8HVIJ@�:<ʉ9
    Q�@�8֙>"̡7n4I:�B�0pd]P6F|qHD!(\0"87V8 �!9ZŜ8{|�X0\y\RB%pԩRJ*TRJ*TRI 
    H`a H8jTRJ*TRJ*TR
    ?"9B@+g0GåJ*TRJ0|B+>q*TRJ*T@bYgB9v$PB
    (PB
    (PBi
    ﲪ�`�t$천$E�
    }:BNvYN�q$'e;,	p�_iJ
    dR ,-U|iRzL6D^6Sb#J)HJ	(De .��k"{�0Jэ=*gQ
    4S&H%`LFfDWD55rIR?]I(iԡߧ'e;,	p�__c8h.7$C#MLhoKEs"('w,jwDϕ]nQVhl+;ًs䫺Λ݊Ɲk$d'+C
    ڹcfr
    Jus
    Y37G0_A+cM>9\K8>YIFQO6|Dex;fPC(xSV0bj+pR 
    L~{�e"]Ā1I.99ј@�N-]�_	'e;,\��FPO @ @3\AITt�8´/-L[�
    ZETTki#ēS��kDkLoZpD3Ue!Hytu
    3QqFƎ˧攛:w
    R,]TB,	{ST;OpJ#T@Aj߄AL PDe�m)Z{1s:]#}6)�\&RäG`Ԭ[-6V`MZa]HaC"v>:C52�CyNF_kO+p>˙iWFx
     R`-
    9@VdV"ԹBfw"\"vStBuNRJ*TRJ*TRJn/r�HBIN)9�Au"~<x
    	=|kxHÈQyyВASsp�_N䐁Ssp�_N䐁Ssp)\fsL2nqJs.G,q1<D%xqAfPr`D5@GCc�
    }RBNvYNn*$"m椘KbE/Tj7T16Yd@BA9VJo>|%�Pp@�	8"!`惱RJ*TSԩRJ*T`l$bAIFf^Bq>J*TRJ<5?xj`TRD4HıOSsrtq
    	49�U%RBע["[B1ÜB3
    r�djhr#lL獇>*-56/nP
    FQ|jiQQC@Deܝ;Ing#~0qbc>R:(O-d<3�L^r?�@ 	!AB@
    C*aqG"%@@mDDeܝ8ɵ=ɓjULi#H�&KdI|C5�$!9"2@�
    KgGma &F- Y2ddmB�"	OPYkIRZ>HzQ>)s6,V&&ASsrt w#6<r04�s$3h̹8 �J}JW$AZxH	|ydMeYYgYyf3nzX#(2c&Tu*™B6#-Up|xᏆ><xᏏ<xZi
    1UUUr`SXlg,O<I/	1BsPdy<x#[ &b+/W,>CFx*_-�lfoO<)K0-8`ydcm11bŞ(z
    `(\.&K>Wǿhc7CPʂYճfeDgVH.'\=:���������������������������������������������������������������������������������UUML0'lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳff͛6lٳf͛6lٳf͛6lٳf͛<UUML������������������������������������������������������������������������������������������������������������������������������������I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������deYmId2H���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`��������������������������������������������������������`��������������������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    ���������������������������������������������`�����������
    �����������������������������������;m[mm�`�����������
    ������������������������������������������ �`�����������
    ������������������������������������������0�`�����������������������������������������������������0�`�����������
    ������������������������������������������0�`�����������
    ������������������������������������������0�`�����������
    ������������������������������������������0�`�����������
    ���������������������������I$I$��������0�`�����������
    ����������������������������������������0�`�����������
    �����������������������������������������`�����������
    ����������������������������������������0�`�����������
    ����������������������������������������0�`�����������
    ����������������������������������������0�`�����������
    �����������������������������������������`�����������
    ����������������������������������������0�`�����������
    ����������������������������������������0�`�����������
    �����������������������������������������`�����������
    ����������������������������������������0�`�����������
    ���������������������������������������� �`�����������
    ����������������������������������������0�`���������������������������������������������������0�`�����������
    ����������������������������������������mmmm������������������P���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������I$I$I �I$I$I ��I$I$I$I���I$I$I$��������������������� �������������������������$�������������������������������� ���������@������������� ������������������������������ ����������� ����������������������@�����������I$I$I ��I$I$I �� �I$I��I$I���I$I$I �@��������������������������������������� ����� ������������������������������������������� ����� ����� ��������������������������������������������@ ����� ����� ������������������������������ ����������������� ����� ������������������������������������$�������� ����� ����� ��������������������������������� ���2	$��$������� ����� ���m�]����������������������������������� ����� ����� ��������������������������������������������� ����� ����� ����������������������������@������I��������@������ ����� ����������������������������P�������H$�$�������� ����� ��I$I$I ���������������������������������� ����� ����� ������������������������������ �`���������@������ ����� ��������������������������������������������������� ����� �������������������������������������������������� ����� ������������$��������������� ����������������� ����� ������������(������yvi4��i�������� ����� ��������������$�����	����������������������������� ����� ������������� ���������������������������������� ����� ��������������� ��������������������������������� ����� �������������������������}��������� �����������$�����������@� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,��������Q1p!`@ 0APa�?�iGBE
    +Se*
    (PB
    (PB
    (PB
    (PB
    (PB
    (PB|V=u_(+"+"+"+"#Ǣ=OcBed(PB
    hУB
    hѣBhѡ�`:C~acVF5acVF`F5acVF5acVF5aҋ]SOM<z<xǏZ<xj:SNb-W6ՄU%F5aIQxERTcVTՄU%F5aIQXE9hP"tb_ɜirK-.Z\irK(6gڊJj)j)*1~
    Ƭ",6gڊJj)j)*1~
    Ƭ",6gڊJj)j)*1~
    Ƭ",6�gٚJj((�cǁ<x1cǁ<Kq1PH (P_M>|ϟ>|ϟ>|ɚh
     �
    R/n�6T!bPPpÇ8pÇ8pÇ8pÇ=LAX%uK>^zׯ^zׯ^zׯ^zׯ^zׯ^z׮<iUbZzh{z5M~Pkڃ_hw*dY,K%dY,K%dY,OC:ٝFܧ2h;Q-zSYJs)̬e)̬e)̧2SNee+)Nee+)N~%9VR92e)̧2s+)Nee)j;QG2s)̧2s2s)̧2s)̧2s)̧29�@a�/��������Q a!1@P`p0Aq�?�{bDP0ݖe-nv[ݖe-nv[ݖe-nv[ݖe-nv[ݖe-nv[ݖe-nv[3B7`ELc0Lz	TT1ꊘ&=QSǪ*`ELc0Lz	TT1ꊘ&=P0!88m#lVЍ[B6m+lVحB6m+lVح[bm+lVح[b� "DÁ&	@__f1;ؘ&=U~a}Ǡj/b`
    UlLC1;ؘ&=U~a}Ǡj/b`
    U	&0̀xGMaaaaaA(p�s'
    ~a}ǓUYtխ0;ؘ&<C+;ؘ&<C+;=LMUfUlLMUfUlLMUfUlL%T G@$G$䣒J9(䣒J9(䣒J9(䣒5MWWvz&<Jv	:jC1U5O
    fU	oxk50LxMs|Yt|%~a}ljT7<5MWWvz&<Jv	:jC͉cĪk`C+;ؘ&<Jv	:jC͉cĪk`C+;ؘ&<Jv	:jC͉cĪk`Ci__f1U5O
    fUlL%S\;j5_	__f1U n7O՛ftY~?Vn7O՛ftP$Cd#yOK'dzY=,OK'dzY=,OK'dq&�A2	O�$qM+&JɥdҲiY4VM+&JɥdҲiY4VM+&JɥdҲiY4VM+&JɥdҲiY4VF Aq8Ǘ\c0dvY;,N'edvY;,N'edvY;,N'edvY;,N'edvY;,N'edvY;,N'e�y܎_pzz?Ts "QeBn!7M&q	Bn!EYa7M&q
    ,\x??%%/L0�O."J"J"_DDDDDDDDDD(((((|QQQQQQQQQQQQQ"$$$$$%�T_((((((1QQQQQQQQQQQQ��-������!1@Q APp0`aq��?�F&@ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|MO18pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ`kpTOn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڳn՛v۵fݫ6YjͻVmڙhbuɝɝɝɝɝɝɝbْdΕi|߿D߿~߿~ߢ~R&w8q}gskw8q}gskw8q}gsX!i2dɓ&JY2dɓ&L2dɒ	X.63Â>3Â>3Â>3Â>3Â>3Â>3É2@	6QdJy<r9GQ(y<r9Gr	t>a;@p}gs8}P.s;8w9vkùT\pZw8ps>3Çs>a;@p}gs8}P.s;8w9vkùL\�3kj5x
    ^Wj5x
    ^lFĆ6sib(vnݻvlBv۷nػu$tD;-d(	|߿~߿~߿~߿~"HISLBu>G.\r˗.\r˗.\r˗.\r˗.\r˗.\rCQxH!&g8pÇ8pÇ8pwOF3@V�pʷAm8pÇ8pÇ8pY9fqV0�i*�@�D^Bφ"v=%`/0$M\8pÇ8pÇ8pʴqr56P}IIe*E_Brbk	Ӳb?i	U|�%B,Ç8pÇ8pÇ8pÇJ%FYRcr%Yn˙QBpCr	ОT24	
    ڸpÇ8pÇ8pÇae?WdbMIKF/S&G9kP'"fQP! 0"@/D[i[,# >nAOHP" z900Ne[e	1RY5$TC�kʪ8
    5uDAI2{,Ge&Q_CÈ?�"� !Ё"I@9|Ërzx"$`R E)C؉wy"R%iIZ:}	_A#59iM@?Ph'�&z,U(K5/MHN@,,%wsBT|ÚDȝ,M��oD`,�띔2FRyP$���Yb&6	tz!D'�_(,#xɚ$H^PZ"�p6IUB@JQz
    ӱR	Mڹr˗.\r˗.\rːZEʐP4DI
    .\r˗.\r˗.\v7WsD'iR~C.\r˗.Fp&�JN`?-Lpƕ'9r˗.\r-ILAcLT%D`\	OWSm7 ~߿~߿~CvP4D€GVQr8pE7\\JzL¸A^g=sl=sts})`53
    ZZN\qqq積+ٿ+TE@0) w	UUr~UֶȦwCΐlܬUC˗1=[J`"F7\\
    L¸Og
    `@tǼX~!2* E b܍wL8@}Q,!A<lˣ HH:AC$\) Qa"ùa㣞?S8Wi"h@yPD"#<
    ohPH0&(@B�@Bȅ9
    $#p}dDd�@5�
    SP.8N
    =dP(N	IATae5HȂ"JFP@h)I{ <-J�	^p!nz�!- ɺk�}Zb3�d!"A%l{{{[t\l$bDH1'	Hʐbs,j8psD-<1&!%IiOj]Ys==G=>+B|'
    (PB
    (PZI2
    CP65lN`2'*1pBlqqq/3
    r[_utP*nazN5bJ%Fb@XJAGՙ!"lLwx`!V\@Byj%6KP�T7(oRd{{{}i8Wweu?['ZE햋,>BE7HM&	(uծ(426�T!]JG:pʭkx`/&0d�@�*p"axzn
    s	CjPT(	uPF[s�>_لDQEJP5
    @@P׏ȣ-d{Z7\\~Eɓ&L2dɓ&L2dɓ&Lv;.,L¸j\\~?Jp\!Z&iB"(PB
    V}YP	"lN΀9nLta]Zs}R/e'!zql-3
    ZZAuqqqZg
    0a㣞=CVDAFH1h%U (kBElM*B.6E	)	ۆ
    RGS
    zAuqqqyLejH	f'�x(�Gc51u8^*zdD`*vEP6AX(]a[Sڂ88r$Z	Ȣ+�Sm8p»
    8pÇ8N2*H)ksZGqV,,mhAmgZ:5\#
    .8pÇWa]8p9KZ@b@Mn6:9:s|->@_ӂ=L@֧e$ t^1z�>QJ$m9J>@"zTKx(N#ݶ0=uuB\IDI5!@okaA3CuqqqiegO@
    !&XBP'a�*[|Ăڅ8qk߼߸]UP�PA	@OXvBd
    &%9[&��luqqqi.X%.0\SP‹bElbFn8D."4CЂhhW_Q3(=b�jߘ"8ZO>YA}T-bB=gH{{{\	OZքHBU&rFCP
    ȨS!$BXu`A1uH>vվN	ӽ4i	`*uC!(d0#)J3`cml-A%h(P
    (P
    (Pm5&pqB
    )9eE]Uo/Ji勱(G&PBܝq<!O C%~V#ZaJ([o)~2_$kp!R �[덙
    9 PBiX[mX3z@!�=~|&OײZ%/ˏ27lِC0۩h6e�zcIP�vMrF=v$TSa
    (  fG]8�xÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇ8pÇKGICRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*[TRJ*TRJ*TRJ*TRׂ4?��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/004.html�����������������������������������������������������0000664�0001751�0001751�00000025134�14156077574�021037� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html>
    	<head>
    		<title>HTML/2.0 Test File: 004</title>
    	</head>
    	<body>
    		<p><h1>HTML/2.0 Test File: 004</h1>
    		This file contains plain text with a bunch of images.<br>
    		<img src="004/gophertiles_142.jpg" height="32" width="32"><img src="004/gophertiles_084.jpg" height="32" width="32"><img src="004/gophertiles_052.jpg" height="32" width="32"><img src="004/gophertiles_077.jpg" height="32" width="32"><img src="004/gophertiles_030.jpg" height="32" width="32"><img src="004/gophertiles_027.jpg" height="32" width="32"><img src="004/gophertiles_039.jpg" height="32" width="32"><img src="004/gophertiles_025.jpg" height="32" width="32"><img src="004/gophertiles_017.jpg" height="32" width="32"><img src="004/gophertiles_179.jpg" height="32" width="32"><img src="004/gophertiles_032.jpg" height="32" width="32"><img src="004/gophertiles_161.jpg" height="32" width="32"><img src="004/gophertiles_088.jpg" height="32" width="32"><img src="004/gophertiles_022.jpg" height="32" width="32"><img src="004/gophertiles_146.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_102.jpg" height="32" width="32"><img src="004/gophertiles_009.jpg" height="32" width="32"><img src="004/gophertiles_132.jpg" height="32" width="32"><img src="004/gophertiles_137.jpg" height="32" width="32"><img src="004/gophertiles_055.jpg" height="32" width="32"><img src="004/gophertiles_036.jpg" height="32" width="32"><img src="004/gophertiles_127.jpg" height="32" width="32"><img src="004/gophertiles_145.jpg" height="32" width="32"><img src="004/gophertiles_147.jpg" height="32" width="32"><img src="004/gophertiles_153.jpg" height="32" width="32"><img src="004/gophertiles_105.jpg" height="32" width="32"><img src="004/gophertiles_103.jpg" height="32" width="32"><img src="004/gophertiles_033.jpg" height="32" width="32"><img src="004/gophertiles_054.jpg" height="32" width="32"><img src="004/gophertiles_015.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_016.jpg" height="32" width="32"><img src="004/gophertiles_072.jpg" height="32" width="32"><img src="004/gophertiles_115.jpg" height="32" width="32"><img src="004/gophertiles_108.jpg" height="32" width="32"><img src="004/gophertiles_148.jpg" height="32" width="32"><img src="004/gophertiles_070.jpg" height="32" width="32"><img src="004/gophertiles_083.jpg" height="32" width="32"><img src="004/gophertiles_118.jpg" height="32" width="32"><img src="004/gophertiles_053.jpg" height="32" width="32"><img src="004/gophertiles_021.jpg" height="32" width="32"><img src="004/gophertiles_059.jpg" height="32" width="32"><img src="004/gophertiles_130.jpg" height="32" width="32"><img src="004/gophertiles_163.jpg" height="32" width="32"><img src="004/gophertiles_098.jpg" height="32" width="32"><img src="004/gophertiles_064.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_018.jpg" height="32" width="32"><img src="004/gophertiles_058.jpg" height="32" width="32"><img src="004/gophertiles_167.jpg" height="32" width="32"><img src="004/gophertiles_082.jpg" height="32" width="32"><img src="004/gophertiles_056.jpg" height="32" width="32"><img src="004/gophertiles_180.jpg" height="32" width="32"><img src="004/gophertiles_046.jpg" height="32" width="32"><img src="004/gophertiles_093.jpg" height="32" width="32"><img src="004/gophertiles_106.jpg" height="32" width="32"><img src="004/gophertiles_065.jpg" height="32" width="32"><img src="004/gophertiles_175.jpg" height="32" width="32"><img src="004/gophertiles_139.jpg" height="32" width="32"><img src="004/gophertiles_101.jpg" height="32" width="32"><img src="004/gophertiles_099.jpg" height="32" width="32"><img src="004/gophertiles_051.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_140.jpg" height="32" width="32"><img src="004/gophertiles_134.jpg" height="32" width="32"><img src="004/gophertiles_149.jpg" height="32" width="32"><img src="004/gophertiles_049.jpg" height="32" width="32"><img src="004/gophertiles_095.jpg" height="32" width="32"><img src="004/gophertiles_075.jpg" height="32" width="32"><img src="004/gophertiles_066.jpg" height="32" width="32"><img src="004/gophertiles_090.jpg" height="32" width="32"><img src="004/gophertiles_035.jpg" height="32" width="32"><img src="004/gophertiles_114.jpg" height="32" width="32"><img src="004/gophertiles_160.jpg" height="32" width="32"><img src="004/gophertiles_079.jpg" height="32" width="32"><img src="004/gophertiles_062.jpg" height="32" width="32"><img src="004/gophertiles_096.jpg" height="32" width="32"><img src="004/gophertiles_100.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_104.jpg" height="32" width="32"><img src="004/gophertiles_057.jpg" height="32" width="32"><img src="004/gophertiles_037.jpg" height="32" width="32"><img src="004/gophertiles_086.jpg" height="32" width="32"><img src="004/gophertiles_168.jpg" height="32" width="32"><img src="004/gophertiles_138.jpg" height="32" width="32"><img src="004/gophertiles_045.jpg" height="32" width="32"><img src="004/gophertiles_141.jpg" height="32" width="32"><img src="004/gophertiles_029.jpg" height="32" width="32"><img src="004/gophertiles_165.jpg" height="32" width="32"><img src="004/gophertiles_110.jpg" height="32" width="32"><img src="004/gophertiles_063.jpg" height="32" width="32"><img src="004/gophertiles_158.jpg" height="32" width="32"><img src="004/gophertiles_122.jpg" height="32" width="32"><img src="004/gophertiles_068.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_170.jpg" height="32" width="32"><img src="004/gophertiles_120.jpg" height="32" width="32"><img src="004/gophertiles_117.jpg" height="32" width="32"><img src="004/gophertiles_031.jpg" height="32" width="32"><img src="004/gophertiles_113.jpg" height="32" width="32"><img src="004/gophertiles_074.jpg" height="32" width="32"><img src="004/gophertiles_129.jpg" height="32" width="32"><img src="004/gophertiles_019.jpg" height="32" width="32"><img src="004/gophertiles_060.jpg" height="32" width="32"><img src="004/gophertiles_109.jpg" height="32" width="32"><img src="004/gophertiles_080.jpg" height="32" width="32"><img src="004/gophertiles_097.jpg" height="32" width="32"><img src="004/gophertiles_116.jpg" height="32" width="32"><img src="004/gophertiles_085.jpg" height="32" width="32"><img src="004/gophertiles_050.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_151.jpg" height="32" width="32"><img src="004/gophertiles_094.jpg" height="32" width="32"><img src="004/gophertiles_067.jpg" height="32" width="32"><img src="004/gophertiles_128.jpg" height="32" width="32"><img src="004/gophertiles_034.jpg" height="32" width="32"><img src="004/gophertiles_135.jpg" height="32" width="32"><img src="004/gophertiles_012.jpg" height="32" width="32"><img src="004/gophertiles_010.jpg" height="32" width="32"><img src="004/gophertiles_152.jpg" height="32" width="32"><img src="004/gophertiles_171.jpg" height="32" width="32"><img src="004/gophertiles_087.jpg" height="32" width="32"><img src="004/gophertiles_126.jpg" height="32" width="32"><img src="004/gophertiles_048.jpg" height="32" width="32"><img src="004/gophertiles_023.jpg" height="32" width="32"><img src="004/gophertiles_078.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_071.jpg" height="32" width="32"><img src="004/gophertiles_131.jpg" height="32" width="32"><img src="004/gophertiles_073.jpg" height="32" width="32"><img src="004/gophertiles_143.jpg" height="32" width="32"><img src="004/gophertiles_173.jpg" height="32" width="32"><img src="004/gophertiles_154.jpg" height="32" width="32"><img src="004/gophertiles_061.jpg" height="32" width="32"><img src="004/gophertiles_178.jpg" height="32" width="32"><img src="004/gophertiles_013.jpg" height="32" width="32"><img src="004/gophertiles_028.jpg" height="32" width="32"><img src="004/gophertiles_157.jpg" height="32" width="32"><img src="004/gophertiles_038.jpg" height="32" width="32"><img src="004/gophertiles_069.jpg" height="32" width="32"><img src="004/gophertiles_174.jpg" height="32" width="32"><img src="004/gophertiles_076.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_155.jpg" height="32" width="32"><img src="004/gophertiles_107.jpg" height="32" width="32"><img src="004/gophertiles_136.jpg" height="32" width="32"><img src="004/gophertiles_144.jpg" height="32" width="32"><img src="004/gophertiles_091.jpg" height="32" width="32"><img src="004/gophertiles_024.jpg" height="32" width="32"><img src="004/gophertiles_014.jpg" height="32" width="32"><img src="004/gophertiles_159.jpg" height="32" width="32"><img src="004/gophertiles_011.jpg" height="32" width="32"><img src="004/gophertiles_176.jpg" height="32" width="32"><img src="004/gophertiles_162.jpg" height="32" width="32"><img src="004/gophertiles_156.jpg" height="32" width="32"><img src="004/gophertiles_081.jpg" height="32" width="32"><img src="004/gophertiles_119.jpg" height="32" width="32"><img src="004/gophertiles_026.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_133.jpg" height="32" width="32"><img src="004/gophertiles_020.jpg" height="32" width="32"><img src="004/gophertiles_044.jpg" height="32" width="32"><img src="004/gophertiles_125.jpg" height="32" width="32"><img src="004/gophertiles_150.jpg" height="32" width="32"><img src="004/gophertiles_172.jpg" height="32" width="32"><img src="004/gophertiles_002.jpg" height="32" width="32"><img src="004/gophertiles_169.jpg" height="32" width="32"><img src="004/gophertiles_007.jpg" height="32" width="32"><img src="004/gophertiles_008.jpg" height="32" width="32"><img src="004/gophertiles_042.jpg" height="32" width="32"><img src="004/gophertiles_041.jpg" height="32" width="32"><img src="004/gophertiles_166.jpg" height="32" width="32"><img src="004/gophertiles_005.jpg" height="32" width="32"><img src="004/gophertiles_089.jpg" height="32" width="32"><br>
    		<img src="004/gophertiles_177.jpg" height="32" width="32"><img src="004/gophertiles_092.jpg" height="32" width="32"><img src="004/gophertiles_043.jpg" height="32" width="32"><img src="004/gophertiles_111.jpg" height="32" width="32"><img src="004/gophertiles_047.jpg" height="32" width="32"><img src="004/gophertiles.jpg" height="32" width="32"><img src="004/gophertiles_006.jpg" height="32" width="32"><img src="004/gophertiles_121.jpg" height="32" width="32"><img src="004/gophertiles_004.jpg" height="32" width="32"><img src="004/gophertiles_124.jpg" height="32" width="32"><img src="004/gophertiles_123.jpg" height="32" width="32"><img src="004/gophertiles_112.jpg" height="32" width="32"><img src="004/gophertiles_040.jpg" height="32" width="32"><img src="004/gophertiles_164.jpg" height="32" width="32"><img src="004/gophertiles_003.jpg" height="32" width="32"><br>
    		<hr>This page is developed using this template:<a href="https://http2.golang.org/">HTTP/2 demo server</a>
    		</p>
    	</body>
    </html>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/006.html�����������������������������������������������������0000664�0001751�0001751�00000001037�14156077574�021035� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML> 
     <html>
       <head>
         <title>HTML/2.0 Test File: 006</title>
         <link rel="stylesheet" type="text/css" href="006/006.css">
         <script type="text/javascript" src="006/006.js"></script>
       </head>
       <body>
         <h1>HTML/2.0 Test File: 006</h1>
         <div class="listTitle">This page contains:
    	     <ul class="listElements">
    			<li>HTML
    			<li>CSS
    			<li>JavaScript
    		</ul> 
    	</div>
    	<div class="listTitle">
    		<script type="text/javascript">
    		 mainJavascript();
    		</script>
    	</div>
       </body>
    </html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/alive.json���������������������������������������������������0000664�0001751�0001751�00000000056�14156077574�021635� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
        "host" : "test1",
        "alive" : true
    }
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test1/index.html���������������������������������������������������0000664�0001751�0001751�00000003727�14156077574�021647� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html>
        <head>
            <title>mod_h2 test site</title>
        </head>
        <body>
            <h1>mod_h2 test site</h1>
            <p></p>
            <h2>served directly</h2>
            <ul>
                <li><a href="001.html">01: html</a></li>
                <li><a href="002.jpg">02: image</a></li>
                <li><a href="003.html">03: html+image</a></li>
                <li><a href="004.html">04: tiled image</a></li>
                <li><a href="005.txt">05: large text</a></li>
                <li><a href="006.html">06: html/js/css</a></li>
                <li><a href="007.html">07: form submit</a></li>
                <li><a href="upload.py">08: upload</a></li>
                <li><a href="009.py">09: small chunks</a></li>
            </ul>
            <h2>mod_proxyied</h2>
            <ul>
                <li><a href="proxy/001.html">01: html</a></li>
                <li><a href="proxy/002.jpg">02: image</a></li>
                <li><a href="proxy/003.html">03: html+image</a></li>
                <li><a href="proxy/004.html">04: tiled image</a></li>
                <li><a href="proxy/005.txt">05: large text</a></li>
                <li><a href="proxy/006.html">06: html/js/css</a></li>
                <li><a href="proxy/007.html">07: form submit</a></li>
                <li><a href="proxy/upload.py">08: upload</a></li>
                <li><a href="proxy/009.py">09: small chunks</a></li>
            </ul>
            <h2>mod_rewritten</h2>
            <ul>
                <li><a href="rewrite/001.html">01: html</a></li>
                <li><a href="rewrite/002.jpg">02: image</a></li>
                <li><a href="rewrite/003.html">03: html+image</a></li>
                <li><a href="rewrite/004.html">04: tiled image</a></li>
                <li><a href="rewrite/005.txt">05: large text</a></li>
                <li><a href="rewrite/006.html">06: html/js/css</a></li>
                <li><a href="rewrite/007.html">07: form submit</a></li>
                <li><a href="rewrite/upload.py">08: upload</a></li>
                <li><a href="rewrite/009.py">09: small chunks</a></li>
            </ul>
        </body>
    </html>
    
    �����������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test2/�������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�017634� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test2/006/���������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�020141� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test2/006/006.css��������������������������������������������������0000775�0001751�0001751�00000000330�14156077574�021165� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@CHARSET "ISO-8859-1";
    body{
    	background:HoneyDew;
    }
    p{
    color:#0000FF;
    text-align:left;
    }
    
    h1{
    color:#FF0000;
    text-align:center;
    }
    
    .listTitle{
    	font-size:large;
    }
    
    .listElements{
    	color:#3366FF
    }��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test2/10%abnormal.txt����������������������������������������������0000664�0001751�0001751�00000000000�14156077574�022372� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test2/alive.json���������������������������������������������������0000664�0001751�0001751�00000000055�14156077574�021635� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
        "host" : "test2",
        "alive" : true
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/test2/x%2f.test����������������������������������������������������0000664�0001751�0001751�00000000000�14156077574�021275� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/index.html���������������������������������������������������������0000664�0001751�0001751�00000000230�14156077574�020571� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html>
        <head>
            <title>mod_h2 test site generic</title>
        </head>
        <body>
            <h1>mod_h2 test site generic</h1>
        </body>
    </html>
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/alive.json���������������������������������������������������������0000664�0001751�0001751�00000000057�14156077574�020576� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{
        "host" : "generic",
        "alive" : true
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/htdocs/forbidden.html�����������������������������������������������������0000664�0001751�0001751�00000000313�14156077574�021420� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html>
        <head>
            <title>403 - Forbidden</title>
        </head>
        <body>
            <h1>403 - Forbidden</h1>
            <p>
                An example of an error document.
            </p>
        </body>
    </html>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/curl.py�������������������������������������������������������������������0000664�0001751�0001751�00000011464�14643712504�016630� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import datetime
    import re
    import subprocess
    import sys
    import time
    from threading import Thread
    
    from .env import HttpdTestEnv
    
    
    class CurlPiper:
    
        def __init__(self, env: HttpdTestEnv, url: str):
            self.env = env
            self.url = url
            self.proc = None
            self.args = None
            self.headerfile = None
            self._stderr = []
            self._stdout = []
            self.stdout_thread = None
            self.stderr_thread = None
            self._exitcode = -1
            self._r = None
    
        @property
        def exitcode(self):
            return self._exitcode
    
        @property
        def response(self):
            return self._r.response if self._r else None
    
        def __repr__(self):
            return f'CurlPiper[exitcode={self._exitcode}, stderr={self._stderr}, stdout={self._stdout}]'
    
        def start(self):
            self.args, self.headerfile = self.env.curl_complete_args([self.url], timeout=5, options=[
                "-T", "-", "-X", "POST", "--trace-ascii", "%", "--trace-time"
            ])
            self.args.append(self.url)
            sys.stderr.write("starting: {0}\n".format(self.args))
            self.proc = subprocess.Popen(self.args, stdin=subprocess.PIPE,
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.PIPE,
                                         bufsize=0)
    
            def read_output(fh, buffer):
                while True:
                    chunk = fh.read()
                    if not chunk:
                        break
                    buffer.append(chunk.decode())
    
            # collect all stdout and stderr until we are done
            # use separate threads to not block ourself
            self._stderr = []
            self._stdout = []
            if self.proc.stderr:
                self.stderr_thread = Thread(target=read_output, args=(self.proc.stderr, self._stderr))
                self.stderr_thread.start()
            if self.proc.stdout:
                self.stdout_thread = Thread(target=read_output, args=(self.proc.stdout, self._stdout))
                self.stdout_thread.start()
            return self.proc
    
        def send(self, data: str):
            self.proc.stdin.write(data.encode())
            self.proc.stdin.flush()
    
        def close(self) -> ([str], [str]):
            self.proc.stdin.close()
            self.stdout_thread.join()
            self.stderr_thread.join()
            self._end()
            return self._stdout, self._stderr
    
        def _end(self):
            if self.proc:
                # noinspection PyBroadException
                try:
                    if self.proc.stdin:
                        # noinspection PyBroadException
                        try:
                            self.proc.stdin.close()
                        except Exception:
                            pass
                    if self.proc.stdout:
                        self.proc.stdout.close()
                    if self.proc.stderr:
                        self.proc.stderr.close()
                except Exception:
                    self.proc.terminate()
                finally:
                    self.proc.wait()
                    self.stdout_thread = None
                    self.stderr_thread = None
                    self._exitcode = self.proc.returncode
                    self.proc = None
                    self._r = self.env.curl_parse_headerfile(self.headerfile)
    
        def stutter_check(self, chunks: [str], stutter: datetime.timedelta):
            if not self.proc:
                self.start()
            for chunk in chunks:
                self.send(chunk)
                time.sleep(stutter.total_seconds())
            recv_out, recv_err = self.close()
            # assert we got everything back
            assert "".join(chunks) == "".join(recv_out)
            # now the tricky part: check *when* we got everything back
            recv_times = []
            for line in "".join(recv_err).split('\n'):
                m = re.match(r'^\s*(\d+:\d+:\d+(\.\d+)?) <= Recv data, (\d+) bytes.*', line)
                if m and int(m.group(3)) > 0:
                    recv_times.append(datetime.time.fromisoformat(m.group(1)))
            # received as many chunks as we sent
            assert len(chunks) == len(recv_times), "received response not in {0} chunks, but {1}".format(
                len(chunks), len(recv_times))
    
            def microsecs(tdelta):
                return ((tdelta.hour * 60 + tdelta.minute) * 60 + tdelta.second) * 1000000 + tdelta.microsecond
    
            recv_deltas = []
            last_mics = microsecs(recv_times[0])
            for ts in recv_times[1:]:
                mics = microsecs(ts)
                delta_mics = mics - last_mics
                if delta_mics < 0:
                    delta_mics += datetime.time(23, 59, 59, 999999)
                recv_deltas.append(datetime.timedelta(microseconds=delta_mics))
                last_mics = mics
            stutter_td = datetime.timedelta(seconds=stutter.total_seconds() * 0.75)  # 25% leeway
            for idx, td in enumerate(recv_deltas[1:]):
                assert stutter_td < td, \
                    f"chunk {idx} arrived too early \n{recv_deltas}\nafter {td}\n{recv_err}"
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/conf.py�������������������������������������������������������������������0000664�0001751�0001751�00000025362�14643712504�016612� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from typing import Dict, Any
    
    from pyhttpd.env import HttpdTestEnv
    
    
    class HttpdConf(object):
    
        def __init__(self, env: HttpdTestEnv, extras: Dict[str, Any] = None):
            """ Create a new httpd configuration.
            :param env: then environment this operates in
            :param extras: extra configuration directive with ServerName as key and
                           'base' as special key for global configuration additions.
            """
            self.env = env
            self._indents = 0
            self._lines = []
            self._extras = extras.copy() if extras else {}
            if 'base' in self._extras:
                self.add(self._extras['base'])
            self._tls_engine_ports = set()
    
        def __repr__(self):
            s = '\n'.join(self._lines)
            return f"HttpdConf[{s}]"
    
        def install(self):
            self.env.install_test_conf(self._lines)
    
        def replacetlsstr(self, line):
                l = line.replace("TLS_", "")
                l = l.replace("\n", " ")
                l = l.replace("\\", " ")
                l = " ".join(l.split())
                l = l.replace(" ", ":")
                l = l.replace("_", "-")
                l = l.replace("-WITH", "")
                l = l.replace("AES-", "AES")
                l = l.replace("POLY1305-SHA256", "POLY1305")
                return l
    
        def replaceinstr(self, line):
            if line.startswith("TLSCiphersPrefer"):
                # the "TLS_" are changed into "".
                l = self.replacetlsstr(line)
                l = l.replace("TLSCiphersPrefer:", "SSLCipherSuite ")
            elif line.startswith("TLSCiphersSuppress"):
                # like SSLCipherSuite but with :!
                l = self.replacetlsstr(line)
                l = l.replace("TLSCiphersSuppress:", "SSLCipherSuite !")
                l = l.replace(":", ":!")
            elif line.startswith("TLSCertificate"):
                l = line.replace("TLSCertificate", "SSLCertificateFile")
            elif line.startswith("TLSProtocol"):
                # mod_ssl is different (+ no supported and 0x code have to be translated)
                l = line.replace("TLSProtocol", "SSLProtocol")
                l = l.replace("+", "")
                l = l.replace("default", "all")
                l = l.replace("0x0303", "1.2") # need to check 1.3 and 1.1
            elif line.startswith("SSLProtocol"):
                l = line # we have that in test/modules/tls/test_05_proto.py
            elif line.startswith("TLSHonorClientOrder"):
                # mod_ssl has SSLHonorCipherOrder on = use server off = use client.
                l = line.lower()
                if "on" in l:
                    l = "SSLHonorCipherOrder off"
                else:
                    l = "SSLHonorCipherOrder on"
            elif line.startswith("TLSEngine"):
                # In fact it should go in the corresponding VirtualHost... Not sure how to do that.
                l = "SSLEngine On"
            else:
                if line != "":
                    l = line.replace("TLS", "SSL")
                else:
                    l = line
            return l
    
        def add(self, line: Any):
            # make we transform the TLS to SSL if we are using mod_ssl
            if isinstance(line, str):
                if not HttpdTestEnv.has_shared_module("tls"):
                    line = self.replaceinstr(line)
                if self._indents > 0:
                    line = f"{'  ' * self._indents}{line}"
                self._lines.append(line)
            else:
                if not HttpdTestEnv.has_shared_module("tls"):
                    new = []
                    previous = ""
                    for l in line:
                        if previous.startswith("SSLCipherSuite"):
                            if l.startswith("TLSCiphersPrefer") or l.startswith("TLSCiphersSuppress"):
                                # we need to merge it   
                                l = self.replaceinstr(l)
                                l = l.replace("SSLCipherSuite ", ":")
                                previous = previous + l
                                continue
                            else:
                                if self._indents > 0:
                                    previous = f"{'  ' * self._indents}{previous}"
                                new.append(previous)
                                previous = ""
                        l = self.replaceinstr(l)
                        if l.startswith("SSLCipherSuite"):
                            previous = l
                            continue
                        if self._indents > 0:
                            l = f"{'  ' * self._indents}{l}"
                        new.append(l)
                    if previous != "":
                        if self._indents > 0:
                            previous = f"{'  ' * self._indents}{previous}"
                        new.append(previous)
                    self._lines.extend(new)
                else:
                    if self._indents > 0:
                        line = [f"{'  ' * self._indents}{l}" for l in line]
                    self._lines.extend(line)
            return self
    
        def add_certificate(self, cert_file, key_file, ssl_module=None):
            if ssl_module is None:
                ssl_module = self.env.ssl_module
            if ssl_module == 'mod_ssl':
                self.add([
                    f"SSLCertificateFile {cert_file}",
                    f"SSLCertificateKeyFile {key_file if key_file else cert_file}",
                ])
            elif ssl_module == 'mod_tls':
                self.add(f"TLSCertificate {cert_file} {key_file if key_file else ''}")
            elif ssl_module == 'mod_gnutls':
                self.add([
                    f"GnuTLSCertificateFile {cert_file}",
                    f"GnuTLSKeyFile {key_file if key_file else cert_file}",
                ])
            else:
                raise Exception(f"unsupported ssl module: {ssl_module}")
    
        def add_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None,
                      with_certificates=None, ssl_module=None):
            self.start_vhost(domains=domains, port=port, doc_root=doc_root,
                             with_ssl=with_ssl, with_certificates=with_certificates,
                             ssl_module=ssl_module)
            self.end_vhost()
            return self
    
        def start_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None,
                        ssl_module=None, with_certificates=None):
            if not isinstance(domains, list):
                domains = [domains]
            if port is None:
                port = self.env.https_port
            if ssl_module is None:
                ssl_module = self.env.ssl_module
            if with_ssl is None:
                with_ssl = self.env.https_port == port
            if with_ssl and ssl_module == 'mod_tls' and port not in self._tls_engine_ports:
                self.add(f"TLSEngine {port}")
                self._tls_engine_ports.add(port)
            self.add("")
            self.add(f"<VirtualHost *:{port}>")
            self._indents += 1
            self.add(f"ServerName {domains[0]}")
            for alias in domains[1:]:
                self.add(f"ServerAlias {alias}")
            self.add(f"DocumentRoot {doc_root}")
            if with_ssl:
                if ssl_module == 'mod_ssl':
                    self.add("SSLEngine on")
                elif ssl_module == 'mod_gnutls':
                    self.add("GnuTLSEnable on")
                if with_certificates is not False:
                    for cred in self.env.get_credentials_for_name(domains[0]):
                        self.add_certificate(cred.cert_file, cred.pkey_file, ssl_module=ssl_module)
            if domains[0] in self._extras:
                self.add(self._extras[domains[0]])
            return self
                      
        def end_vhost(self):
            self._indents -= 1
            self.add("</VirtualHost>")
            self.add("")
            return self
    
        def add_proxies(self, host, proxy_self=False, h2proxy_self=False):
            if proxy_self or h2proxy_self:
                self.add("ProxyPreserveHost on")
            if proxy_self:
                self.add([
                    f"ProxyPass /proxy/ http://127.0.0.1:{self.env.http_port}/",
                    f"ProxyPassReverse /proxy/ http://{host}.{self.env.http_tld}:{self.env.http_port}/",
                ])
            if h2proxy_self:
                self.add([
                    f"ProxyPass /h2proxy/ h2://127.0.0.1:{self.env.https_port}/",
                    f"ProxyPassReverse /h2proxy/ https://{host}.{self.env.http_tld}:self.env.https_port/",
                ])
            return self
        
        def add_vhost_test1(self, proxy_self=False, h2proxy_self=False):
            domain = f"test1.{self.env.http_tld}"
            self.start_vhost(domains=[domain, f"www1.{self.env.http_tld}"],
                             port=self.env.http_port, doc_root="htdocs/test1")
            self.end_vhost()
            self.start_vhost(domains=[domain, f"www1.{self.env.http_tld}"],
                             port=self.env.https_port, doc_root="htdocs/test1")
            self.add([
                "<Location /006>",
                "    Options +Indexes",
                "</Location>",
            ])
            self.add_proxies("test1", proxy_self, h2proxy_self)
            self.end_vhost()
            return self
    
        def add_vhost_test2(self):
            domain = f"test2.{self.env.http_tld}"
            self.start_vhost(domains=[domain, f"www2.{self.env.http_tld}"],
                             port=self.env.http_port, doc_root="htdocs/test2")
            self.end_vhost()
            self.start_vhost(domains=[domain, f"www2.{self.env.http_tld}"],
                             port=self.env.https_port, doc_root="htdocs/test2")
            self.add([
                "<Location /006>",
                "    Options +Indexes",
                "</Location>",
            ])
            self.end_vhost()
            return self
    
        def add_vhost_cgi(self, proxy_self=False, h2proxy_self=False):
            domain = f"cgi.{self.env.http_tld}"
            if proxy_self:
                self.add(["ProxyStatus on", "ProxyTimeout 5",
                          "SSLProxyEngine on", "SSLProxyVerify none"])
            if h2proxy_self:
                self.add(["SSLProxyEngine on", "SSLProxyCheckPeerName off"])
            self.start_vhost(domains=[domain, f"cgi-alias.{self.env.http_tld}"],
                             port=self.env.https_port, doc_root="htdocs/cgi")
            self.add_proxies("cgi", proxy_self=proxy_self, h2proxy_self=h2proxy_self)
            self.end_vhost()
            self.start_vhost(domains=[domain, f"cgi-alias.{self.env.http_tld}"],
                             port=self.env.http_port, doc_root="htdocs/cgi")
            self.add("AddHandler cgi-script .py")
            self.add_proxies("cgi", proxy_self=proxy_self, h2proxy_self=h2proxy_self)
            self.end_vhost()
            return self
    
        @staticmethod
        def merge_extras(e1: Dict[str, Any], e2: Dict[str, Any]) -> Dict[str, Any]:
            def _concat(v1, v2):
                if isinstance(v1, str):
                    v1 = [v1]
                if isinstance(v2, str):
                    v2 = [v2]
                v1.extend(v2)
                return v1
    
            if e1 is None:
                return e2.copy() if e2 else None
            if e2 is None:
                return e1.copy()
            e3 = e1.copy()
            for name, val in e2.items():
                if name in e3:
                    e3[name] = _concat(e3[name], val)
                else:
                    e3[name] = val
            return e3
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/config.ini.in�������������������������������������������������������������0000664�0001751�0001751�00000001111�14473316336�017654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[global]
    curl_bin = curl
    nghttp = nghttp
    h2load = h2load
    
    prefix = @prefix@
    exec_prefix = @exec_prefix@
    bindir = @bindir@
    sbindir = @sbindir@
    libdir = @libdir@
    libexecdir = @libexecdir@
    
    apr_bindir = @APR_BINDIR@
    apxs = @bindir@/apxs
    apachectl = @sbindir@/apachectl
    
    [httpd]
    version = @HTTPD_VERSION@
    name = @progname@
    dso_modules = @DSO_MODULES@
    mpm_modules = @MPM_MODULES@
    
    [test]
    gen_dir = @abs_srcdir@/../gen
    http_port = 5002
    https_port = 5001
    proxy_port = 5003
    http_port2 = 5004
    ws_port = 5100
    http_tld = tests.httpd.apache.org
    test_dir = @abs_srcdir@
    test_src_dir = @abs_srcdir@
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/__init__.py���������������������������������������������������������������0000664�0001751�0001751�00000000000�14156077574�017414� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/nghttp.py�����������������������������������������������������������������0000664�0001751�0001751�00000027202�14636506340�017165� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re
    import os
    import subprocess
    from datetime import datetime
    from typing import Dict
    
    from urllib.parse import urlparse
    
    from .result import ExecResult
    
    
    def _get_path(x):
        return x["path"]
        
    
    class Nghttp:
    
        def __init__(self, path, connect_addr=None, tmp_dir="/tmp",
                     test_name: str = None):
            self.NGHTTP = path
            self.CONNECT_ADDR = connect_addr
            self.TMP_DIR = tmp_dir
            self._test_name = test_name
    
        @staticmethod
        def get_stream(streams, sid):
            sid = int(sid)
            if sid not in streams:
                streams[sid] = {
                        "id": sid,
                        "header": {},
                        "request": {
                            "id": sid,
                            "body": b''
                        },
                        "response": {
                            "id": sid,
                            "body": b''
                        },
                        "data_lengths": [],
                        "paddings": [],
                        "promises": []
                }
            return streams[sid] if sid in streams else None
    
        def run(self, urls, timeout, options):
            return self._baserun(urls, timeout, options)
    
        def complete_args(self, url, _timeout, options: [str]) -> [str]:
            if not isinstance(url, list):
                url = [url]
            u = urlparse(url[0])
            args = [self.NGHTTP]
            if self.CONNECT_ADDR:
                connect_host = self.CONNECT_ADDR
                args.append("--header=host: %s:%s" % (u.hostname, u.port))
            else:
                connect_host = u.hostname
            if options:
                args.extend(options)
            for xurl in url:
                xu = urlparse(xurl)
                nurl = "%s://%s:%s/%s" % (u.scheme, connect_host, xu.port, xu.path)
                if xu.query:
                    nurl = "%s?%s" % (nurl, xu.query)
                args.append(nurl)
            return args
    
        def _baserun(self, url, timeout, options):
            return self._run(self.complete_args(url, timeout, options))
        
        def parse_output(self, btext) -> Dict:
            # getting meta data and response body out of nghttp's output
            # is a bit tricky. Without '-v' we just get the body. With '-v' meta
            # data and timings in both directions are listed. 
            # We rely on response :status: to be unique and on 
            # response body not starting with space.
            # Something not good enough for general purpose, but for these tests.
            output = {}
            body = ''
            streams = {}
            skip_indents = True
            # chunk output into lines. nghttp mixes text
            # meta output with bytes from the response body.
            lines = [l.decode() for l in btext.split(b'\n')]
    
            for lidx, l in enumerate(lines):
                if len(l) == 0:
                    body += '\n'
                    continue
                m = re.match(r'(.*)\[.*] recv \(stream_id=(\d+)\) (\S+): (\S*)', l)
                if m:
                    body += m.group(1)
                    s = self.get_stream(streams, m.group(2))
                    hname = m.group(3)
                    hval = m.group(4)
                    print("stream %d header %s: %s" % (s["id"], hname, hval))
                    header = s["header"]
                    if hname in header: 
                        header[hname] += ", %s" % hval
                    else:
                        header[hname] = hval
                    continue
    
                m = re.match(r'(.*)\[.*] recv HEADERS frame <.* stream_id=(\d+)>', l)
                if m:
                    body += m.group(1)
                    s = self.get_stream(streams, m.group(2))
                    if s:
                        print("stream %d: recv %d header" % (s["id"], len(s["header"])))
                        response = s["response"]
                        hkey = "header"
                        if "header" in response:
                            h = response["header"]
                            if ":status" in h and int(h[":status"]) >= 200:
                                hkey = "trailer"
                            else:
                                prev = {
                                    "header": h
                                }
                                if "previous" in response:
                                    prev["previous"] = response["previous"]
                                response["previous"] = prev
                        response[hkey] = s["header"]
                        s["header"] = {}
                        body = ''
                    continue
                
                m = re.match(r'(.*)\[.*] recv DATA frame <length=(\d+), .*stream_id=(\d+)>', l)
                if m:
                    body += m.group(1)
                    s = self.get_stream(streams, m.group(3))
                    blen = int(m.group(2))
                    if s:
                        print(f'stream {s["id"]}: {blen} DATA bytes added via "{l}"')
                        padlen = 0
                        if len(lines) > lidx + 2:
                            mpad = re.match(r' +\(padlen=(\d+)\)', lines[lidx+2])
                            if mpad: 
                                padlen = int(mpad.group(1))
                        s["data_lengths"].append(blen)
                        s["paddings"].append(padlen)
                        blen -= padlen
                        s["response"]["body"] += body[-blen:].encode()
                    body = ''
                    skip_indents = True
                    continue
                    
                m = re.match(r'(.*)\[.*] recv PUSH_PROMISE frame <.* stream_id=(\d+)>', l)
                if m:
                    body += m.group(1)
                    s = self.get_stream(streams, m.group(2))
                    if s:
                        # headers we have are request headers for the PUSHed stream
                        # these have been received on the originating stream, the promised
                        # stream id it mentioned in the following lines
                        print("stream %d: %d PUSH_PROMISE header" % (s["id"], len(s["header"])))
                        if len(lines) > lidx+2:
                            m2 = re.match(r'\s+\(.*promised_stream_id=(\d+)\)', lines[lidx+2])
                            if m2:
                                s2 = self.get_stream(streams, m2.group(1))
                                s2["request"]["header"] = s["header"]
                                s["promises"].append(s2)
                        s["header"] = {} 
                    continue
                        
                m = re.match(r'(.*)\[.*] recv (\S+) frame <length=(\d+), .*stream_id=(\d+)>', l)
                if m:
                    print("recv frame %s on stream %s" % (m.group(2), m.group(4)))
                    body += m.group(1)
                    skip_indents = True
                    continue
                    
                m = re.match(r'(.*)\[.*] send (\S+) frame <length=(\d+), .*stream_id=(\d+)>', l)
                if m:
                    print("send frame %s on stream %s" % (m.group(2), m.group(4)))
                    body += m.group(1)
                    skip_indents = True
                    continue
                    
                if skip_indents and l.startswith('      '):
                    continue
                
                if '[' != l[0]:
                    skip_indents = None
                    body += l + '\n'
    
            # the main request is done on the lowest odd numbered id
            main_stream = 99999999999
            for sid in streams:
                s = streams[sid]
                if "header" in s["response"] and ":status" in s["response"]["header"]:
                    s["response"]["status"] = int(s["response"]["header"][":status"])
                if (sid % 2) == 1 and sid < main_stream:
                    main_stream = sid
            
            output["streams"] = streams
            if main_stream in streams:
                output["response"] = streams[main_stream]["response"]
                output["paddings"] = streams[main_stream]["paddings"]
                output["data_lengths"] = streams[main_stream]["data_lengths"]
            return output
    
        def _raw(self, url, timeout, options):
            args = ["-v"]
            if self._test_name is not None:
                args.append(f'--header=AP-Test-Name: {self._test_name}')
            if options:
                args.extend(options)
            r = self._baserun(url, timeout, args)
            if 0 == r.exit_code:
                r.add_results(self.parse_output(r.outraw))
            return r
    
        def get(self, url, timeout=5, options=None):
            return self._raw(url, timeout, options)
    
        def assets(self, url, timeout=5, options=None):
            if not options:
                options = []
            options.extend(["-ans"])
            r = self._baserun(url, timeout, options)
            assets = []
            if 0 == r.exit_code:
                lines = re.findall(r'[^\n]*\n', r.stdout, re.MULTILINE)
                for lidx, l in enumerate(lines):
                    m = re.match(r'\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+/*(/.*)', l)
                    if m:
                        assets.append({
                            "path": m.group(7),
                            "status": int(m.group(5)),
                            "size": m.group(6)
                        })
            assets.sort(key=_get_path)
            r.add_assets(assets)
            return r
    
        def post_data(self, url, data, timeout=5, options=None):
            reqbody = ("%s/nghttp.req.body" % self.TMP_DIR)
            with open(reqbody, 'wb') as f:
                f.write(data.encode('utf-8'))
            if not options:
                options = []
            options.extend(["--data=%s" % reqbody])
            return self._raw(url, timeout, options)
    
        def post_name(self, url, name, timeout=5, options=None):
            reqbody = ("%s/nghttp.req.body" % self.TMP_DIR)
            with open(reqbody, 'w') as f:
                f.write("--DSAJKcd9876\r\n")
                f.write("Content-Disposition: form-data; name=\"value\"; filename=\"xxxxx\"\r\n")
                f.write("Content-Type: text/plain\r\n")
                f.write(f"\r\n{name}")
                f.write("\r\n--DSAJKcd9876\r\n")
            if not options:
                options = []
            options.extend([ 
                "--data=%s" % reqbody, 
                "-HContent-Type: multipart/form-data; boundary=DSAJKcd9876"])
            return self._raw(url, timeout, options)
    
        def upload(self, url, fpath, timeout=5, options=None):
            if not options:
                options = []
            options.extend(["--data=%s" % fpath])
            return self._raw(url, timeout, options)
    
        def upload_file(self, url, fpath, timeout=5, options=None):
            fname = os.path.basename(fpath)
            reqbody = ("%s/nghttp.req.body" % self.TMP_DIR)
            with open(fpath, 'rb') as fin:
                with open(reqbody, 'wb') as f:
                    preamble = [
                        '--DSAJKcd9876',
                        'Content-Disposition: form-data; name="xxx"; filename="xxxxx"',
                        'Content-Type: text/plain',
                        '',
                        'testing mod_h2',
                        '\r\n--DSAJKcd9876',
                        f'Content-Disposition: form-data; name="file"; filename="{fname}"',
                        'Content-Type: application/octet-stream',
                        'Content-Transfer-Encoding: binary',
                        '', ''
                    ]
                    f.write('\r\n'.join(preamble).encode('utf-8'))
                    f.write(fin.read())
                    f.write('\r\n'.join([
                        '\r\n--DSAJKcd9876', ''
                    ]).encode('utf-8'))
            if not options:
                options = []
            options.extend([ 
                "--data=%s" % reqbody, 
                "--expect-continue", 
                "-HContent-Type: multipart/form-data; boundary=DSAJKcd9876"])
            return self._raw(url, timeout, options)
    
        def _run(self, args) -> ExecResult:
            print(("execute: %s" % " ".join(args)))
            start = datetime.now()
            p = subprocess.run(args, capture_output=True, text=False)
            return ExecResult(args=args, exit_code=p.returncode,
                              stdout=p.stdout, stderr=p.stderr,
                              duration=datetime.now() - start)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/certs.py������������������������������������������������������������������0000664�0001751�0001751�00000047430�14672270657�017017� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import re
    from datetime import timedelta, datetime
    from typing import List, Any, Optional
    
    from cryptography import x509
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import ec, rsa
    from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
    from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
    from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption, load_pem_private_key
    from cryptography.x509 import ExtendedKeyUsageOID, NameOID
    
    
    EC_SUPPORTED = {}
    EC_SUPPORTED.update([(curve.name.upper(), curve) for curve in [
        ec.SECP192R1,
        ec.SECP224R1,
        ec.SECP256R1,
        ec.SECP384R1,
    ]])
    
    
    def _private_key(key_type):
        if isinstance(key_type, str):
            key_type = key_type.upper()
            m = re.match(r'^(RSA)?(\d+)$', key_type)
            if m:
                key_type = int(m.group(2))
    
        if isinstance(key_type, int):
            return rsa.generate_private_key(
                public_exponent=65537,
                key_size=key_type,
                backend=default_backend()
            )
        if not isinstance(key_type, ec.EllipticCurve) and key_type in EC_SUPPORTED:
            key_type = EC_SUPPORTED[key_type]
        return ec.generate_private_key(
            curve=key_type,
            backend=default_backend()
        )
    
    
    class CertificateSpec:
    
        def __init__(self, name: str = None, domains: List[str] = None,
                     email: str = None,
                     key_type: str = None, single_file: bool = False,
                     valid_from: timedelta = timedelta(days=-1),
                     valid_to: timedelta = timedelta(days=89),
                     client: bool = False,
                     sub_specs: List['CertificateSpec'] = None):
            self._name = name
            self.domains = domains
            self.client = client
            self.email = email
            self.key_type = key_type
            self.single_file = single_file
            self.valid_from = valid_from
            self.valid_to = valid_to
            self.sub_specs = sub_specs
    
        @property
        def name(self) -> Optional[str]:
            if self._name:
                return self._name
            elif self.domains:
                return self.domains[0]
            return None
    
        @property
        def type(self) -> Optional[str]:
            if self.domains and len(self.domains):
                return "server"
            elif self.client:
                return "client"
            elif self.name:
                return "ca"
            return None
    
    
    class Credentials:
    
        def __init__(self, name: str, cert: Any, pkey: Any, issuer: 'Credentials' = None):
            self._name = name
            self._cert = cert
            self._pkey = pkey
            self._issuer = issuer
            self._cert_file = None
            self._pkey_file = None
            self._store = None
    
        @property
        def name(self) -> str:
            return self._name
    
        @property
        def subject(self) -> x509.Name:
            return self._cert.subject
    
        @property
        def key_type(self):
            if isinstance(self._pkey, RSAPrivateKey):
                return f"rsa{self._pkey.key_size}"
            elif isinstance(self._pkey, EllipticCurvePrivateKey):
                return f"{self._pkey.curve.name}"
            else:
                raise Exception(f"unknown key type: {self._pkey}")
    
        @property
        def private_key(self) -> Any:
            return self._pkey
    
        @property
        def certificate(self) -> Any:
            return self._cert
    
        @property
        def cert_pem(self) -> bytes:
            return self._cert.public_bytes(Encoding.PEM)
    
        @property
        def pkey_pem(self) -> bytes:
            return self._pkey.private_bytes(
                Encoding.PEM,
                PrivateFormat.TraditionalOpenSSL if self.key_type.startswith('rsa') else PrivateFormat.PKCS8,
                NoEncryption())
    
        @property
        def issuer(self) -> Optional['Credentials']:
            return self._issuer
    
        def set_store(self, store: 'CertStore'):
            self._store = store
    
        def set_files(self, cert_file: str, pkey_file: str = None):
            self._cert_file = cert_file
            self._pkey_file = pkey_file
    
        @property
        def cert_file(self) -> str:
            return self._cert_file
    
        @property
        def pkey_file(self) -> Optional[str]:
            return self._pkey_file
    
        def get_first(self, name) -> Optional['Credentials']:
            creds = self._store.get_credentials_for_name(name) if self._store else []
            return creds[0] if len(creds) else None
    
        def get_credentials_for_name(self, name) -> List['Credentials']:
            return self._store.get_credentials_for_name(name) if self._store else []
    
        def issue_certs(self, specs: List[CertificateSpec],
                        chain: List['Credentials'] = None) -> List['Credentials']:
            return [self.issue_cert(spec=spec, chain=chain) for spec in specs]
    
        def issue_cert(self, spec: CertificateSpec, chain: List['Credentials'] = None) -> 'Credentials':
            key_type = spec.key_type if spec.key_type else self.key_type
            creds = None
            if self._store:
                creds = self._store.load_credentials(
                    name=spec.name, key_type=key_type, single_file=spec.single_file, issuer=self)
            if creds is None:
                creds = HttpdTestCA.create_credentials(spec=spec, issuer=self, key_type=key_type,
                                                       valid_from=spec.valid_from, valid_to=spec.valid_to)
                if self._store:
                    self._store.save(creds, single_file=spec.single_file)
                    if spec.type == "ca":
                        self._store.save_chain(creds, "ca", with_root=True)
    
            if spec.sub_specs:
                if self._store:
                    sub_store = CertStore(fpath=os.path.join(self._store.path, creds.name))
                    creds.set_store(sub_store)
                subchain = chain.copy() if chain else []
                subchain.append(self)
                creds.issue_certs(spec.sub_specs, chain=subchain)
            return creds
    
        def save_cert_pem(self, fpath):
            with open(fpath, "wb") as fd:
                fd.write(self.cert_pem)
    
        def save_pkey_pem(self, fpath):
            with open(fpath, "wb") as fd:
                fd.write(self.pkey_pem)
    
    
    class CertStore:
    
        def __init__(self, fpath: str):
            self._store_dir = fpath
            if not os.path.exists(self._store_dir):
                os.makedirs(self._store_dir)
            self._creds_by_name = {}
    
        @property
        def path(self) -> str:
            return self._store_dir
    
        def save(self, creds: Credentials, name: str = None,
                 chain: List[Credentials] = None,
                 single_file: bool = False) -> None:
            name = name if name is not None else creds.name
            cert_file = self.get_cert_file(name=name, key_type=creds.key_type)
            pkey_file = self.get_pkey_file(name=name, key_type=creds.key_type)
            if single_file:
                pkey_file = None
            with open(cert_file, "wb") as fd:
                fd.write(creds.cert_pem)
                if chain:
                    for c in chain:
                        fd.write(c.cert_pem)
                if pkey_file is None:
                    fd.write(creds.pkey_pem)
            if pkey_file is not None:
                with open(pkey_file, "wb") as fd:
                    fd.write(creds.pkey_pem)
            creds.set_files(cert_file, pkey_file)
            self._add_credentials(name, creds)
    
        def save_chain(self, creds: Credentials, infix: str, with_root=False):
            name = creds.name
            chain = [creds]
            while creds.issuer is not None:
                creds = creds.issuer
                chain.append(creds)
            if not with_root and len(chain) > 1:
                chain = chain[:-1]
            chain_file = os.path.join(self._store_dir, f'{name}-{infix}.pem')
            with open(chain_file, "wb") as fd:
                for c in chain:
                    fd.write(c.cert_pem)
    
        def _add_credentials(self, name: str, creds: Credentials):
            if name not in self._creds_by_name:
                self._creds_by_name[name] = []
            self._creds_by_name[name].append(creds)
    
        def get_credentials_for_name(self, name) -> List[Credentials]:
            return self._creds_by_name[name] if name in self._creds_by_name else []
    
        def get_cert_file(self, name: str, key_type=None) -> str:
            key_infix = ".{0}".format(key_type) if key_type is not None else ""
            return os.path.join(self._store_dir, f'{name}{key_infix}.cert.pem')
    
        def get_pkey_file(self, name: str, key_type=None) -> str:
            key_infix = ".{0}".format(key_type) if key_type is not None else ""
            return os.path.join(self._store_dir, f'{name}{key_infix}.pkey.pem')
    
        def load_pem_cert(self, fpath: str) -> x509.Certificate:
            with open(fpath) as fd:
                return x509.load_pem_x509_certificate("".join(fd.readlines()).encode())
    
        def load_pem_pkey(self, fpath: str):
            with open(fpath) as fd:
                return load_pem_private_key("".join(fd.readlines()).encode(), password=None)
    
        def load_credentials(self, name: str, key_type=None, single_file: bool = False, issuer: Credentials = None):
            cert_file = self.get_cert_file(name=name, key_type=key_type)
            pkey_file = cert_file if single_file else self.get_pkey_file(name=name, key_type=key_type)
            if os.path.isfile(cert_file) and os.path.isfile(pkey_file):
                cert = self.load_pem_cert(cert_file)
                pkey = self.load_pem_pkey(pkey_file)
                creds = Credentials(name=name, cert=cert, pkey=pkey, issuer=issuer)
                creds.set_store(self)
                creds.set_files(cert_file, pkey_file)
                self._add_credentials(name, creds)
                return creds
            return None
    
    
    class HttpdTestCA:
    
        @classmethod
        def create_root(cls, name: str, store_dir: str, key_type: str = "rsa2048") -> Credentials:
            store = CertStore(fpath=store_dir)
            creds = store.load_credentials(name="ca", key_type=key_type, issuer=None)
            if creds is None:
                creds = HttpdTestCA._make_ca_credentials(name=name, key_type=key_type)
                store.save(creds, name="ca")
                creds.set_store(store)
            return creds
    
        @staticmethod
        def create_credentials(spec: CertificateSpec, issuer: Credentials, key_type: Any,
                               valid_from: timedelta = timedelta(days=-1),
                               valid_to: timedelta = timedelta(days=89),
                               serial: Optional[int] = None,
                               ) -> Credentials:
            """Create a certificate signed by this CA for the given domains.
            :returns: the certificate and private key PEM file paths
            """
            if spec.domains and len(spec.domains):
                creds = HttpdTestCA._make_server_credentials(name=spec.name, domains=spec.domains,
                                                             issuer=issuer, valid_from=valid_from,
                                                             valid_to=valid_to, key_type=key_type,
                                                             serial=serial)
            elif spec.client:
                creds = HttpdTestCA._make_client_credentials(name=spec.name, issuer=issuer,
                                                             email=spec.email, valid_from=valid_from,
                                                             valid_to=valid_to, key_type=key_type,
                                                             serial=serial)
            elif spec.name:
                creds = HttpdTestCA._make_ca_credentials(name=spec.name, issuer=issuer,
                                                         valid_from=valid_from, valid_to=valid_to,
                                                         key_type=key_type,
                                                         serial=serial)
            else:
                raise Exception(f"unrecognized certificate specification: {spec}")
            return creds
    
        @staticmethod
        def _make_x509_name(org_name: str = None, common_name: str = None, parent: x509.Name = None) -> x509.Name:
            name_pieces = []
            if org_name:
                oid = NameOID.ORGANIZATIONAL_UNIT_NAME if parent else NameOID.ORGANIZATION_NAME
                name_pieces.append(x509.NameAttribute(oid, org_name))
            elif common_name:
                name_pieces.append(x509.NameAttribute(NameOID.COMMON_NAME, common_name))
            if parent:
                name_pieces.extend([rdn for rdn in parent])
            return x509.Name(name_pieces)
    
        @staticmethod
        def _make_csr(
                subject: x509.Name,
                pkey: Any,
                issuer_subject: Optional[Credentials],
                valid_from_delta: timedelta = None,
                valid_until_delta: timedelta = None,
                serial: Optional[int] = None
        ):
            pubkey = pkey.public_key()
            issuer_subject = issuer_subject if issuer_subject is not None else subject
    
            valid_from = datetime.now()
            if valid_until_delta is not None:
                valid_from += valid_from_delta
            valid_until = datetime.now()
            if valid_until_delta is not None:
                valid_until += valid_until_delta
            if serial is None:
                serial = x509.random_serial_number()
            return (
                x509.CertificateBuilder()
                .subject_name(subject)
                .issuer_name(issuer_subject)
                .public_key(pubkey)
                .not_valid_before(valid_from)
                .not_valid_after(valid_until)
                .serial_number(serial)
                .add_extension(
                    x509.SubjectKeyIdentifier.from_public_key(pubkey),
                    critical=False,
                )
            )
    
        @staticmethod
        def _add_ca_usages(csr: Any) -> Any:
            return csr.add_extension(
                x509.BasicConstraints(ca=True, path_length=9),
                critical=True,
            ).add_extension(
                x509.KeyUsage(
                    digital_signature=True,
                    content_commitment=False,
                    key_encipherment=False,
                    data_encipherment=False,
                    key_agreement=False,
                    key_cert_sign=True,
                    crl_sign=True,
                    encipher_only=False,
                    decipher_only=False),
                critical=True
            ).add_extension(
                x509.ExtendedKeyUsage([
                    ExtendedKeyUsageOID.CLIENT_AUTH,
                    ExtendedKeyUsageOID.SERVER_AUTH,
                    ExtendedKeyUsageOID.CODE_SIGNING,
                ]),
                critical=True
            )
    
        @staticmethod
        def _add_leaf_usages(csr: Any, domains: List[str], issuer: Credentials) -> Any:
            csr = csr.add_extension(
                x509.BasicConstraints(ca=False, path_length=None),
                critical=True,
            )
            if issuer is not None:
                csr = csr.add_extension(
                    x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
                        issuer.certificate.extensions.get_extension_for_class(
                            x509.SubjectKeyIdentifier).value),
                    critical=False
                )
            csr = csr.add_extension(
                x509.SubjectAlternativeName([x509.DNSName(domain) for domain in domains]),
                critical=True,
            )
            csr = csr.add_extension(
                x509.ExtendedKeyUsage([
                    ExtendedKeyUsageOID.SERVER_AUTH,
                ]),
                critical=True
            )
            return csr
    
        @staticmethod
        def _add_client_usages(csr: Any, issuer: Credentials, rfc82name: str = None) -> Any:
            cert = csr.add_extension(
                x509.BasicConstraints(ca=False, path_length=None),
                critical=True,
            ).add_extension(
                x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
                    issuer.certificate.extensions.get_extension_for_class(
                        x509.SubjectKeyIdentifier).value),
                critical=False
            )
            if rfc82name:
                cert.add_extension(
                    x509.SubjectAlternativeName([x509.RFC822Name(rfc82name)]),
                    critical=True,
                )
            cert.add_extension(
                x509.ExtendedKeyUsage([
                    ExtendedKeyUsageOID.CLIENT_AUTH,
                ]),
                critical=True
            )
            return cert
    
        @staticmethod
        def _make_ca_credentials(name, key_type: Any,
                                 issuer: Credentials = None,
                                 valid_from: timedelta = timedelta(days=-1),
                                 valid_to: timedelta = timedelta(days=89),
                                 serial: Optional[int] = None,
                                 ) -> Credentials:
            pkey = _private_key(key_type=key_type)
            if issuer is not None:
                issuer_subject = issuer.certificate.subject
                issuer_key = issuer.private_key
            else:
                issuer_subject = None
                issuer_key = pkey
            subject = HttpdTestCA._make_x509_name(org_name=name, parent=issuer.subject if issuer else None)
            csr = HttpdTestCA._make_csr(subject=subject,
                                        issuer_subject=issuer_subject, pkey=pkey,
                                        valid_from_delta=valid_from, valid_until_delta=valid_to,
                                        serial=serial)
            csr = HttpdTestCA._add_ca_usages(csr)
            cert = csr.sign(private_key=issuer_key,
                            algorithm=hashes.SHA256(),
                            backend=default_backend())
            return Credentials(name=name, cert=cert, pkey=pkey, issuer=issuer)
    
        @staticmethod
        def _make_server_credentials(name: str, domains: List[str], issuer: Credentials,
                                     key_type: Any,
                                     valid_from: timedelta = timedelta(days=-1),
                                     valid_to: timedelta = timedelta(days=89),
                                     serial: Optional[int] = None,
                                     ) -> Credentials:
            name = name
            pkey = _private_key(key_type=key_type)
            if issuer is not None:
                issuer_subject = issuer.certificate.subject
                issuer_key = issuer.private_key
            else:
                issuer_subject = None
                issuer_key = pkey
            subject = HttpdTestCA._make_x509_name(common_name=name, parent=issuer_subject)
            csr = HttpdTestCA._make_csr(subject=subject,
                                        issuer_subject=issuer_subject, pkey=pkey,
                                        valid_from_delta=valid_from, valid_until_delta=valid_to,
                                        serial=serial)
            csr = HttpdTestCA._add_leaf_usages(csr, domains=domains, issuer=issuer)
            cert = csr.sign(private_key=issuer_key,
                            algorithm=hashes.SHA256(),
                            backend=default_backend())
            return Credentials(name=name, cert=cert, pkey=pkey, issuer=issuer)
    
        @staticmethod
        def _make_client_credentials(name: str,
                                     issuer: Credentials, email: Optional[str],
                                     key_type: Any,
                                     valid_from: timedelta = timedelta(days=-1),
                                     valid_to: timedelta = timedelta(days=89),
                                     serial: Optional[int] = None,
                                     ) -> Credentials:
            pkey = _private_key(key_type=key_type)
            if issuer is not None:
                issuer_subject = issuer.certificate.subject
                issuer_key = issuer.private_key
            else:
                issuer_subject = None
                issuer_key = pkey
            subject = HttpdTestCA._make_x509_name(common_name=name, parent=issuer_subject)
            csr = HttpdTestCA._make_csr(subject=subject,
                                        issuer_subject=issuer_subject, pkey=pkey,
                                        valid_from_delta=valid_from, valid_until_delta=valid_to,
                                        serial=serial)
            csr = HttpdTestCA._add_client_usages(csr, issuer=issuer, rfc82name=email)
            cert = csr.sign(private_key=issuer_key,
                            algorithm=hashes.SHA256(),
                            backend=default_backend())
            return Credentials(name=name, cert=cert, pkey=pkey, issuer=issuer)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/result.py�����������������������������������������������������������������0000664�0001751�0001751�00000004774�14424160200�017172� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import json
    from datetime import timedelta
    from typing import Optional, Dict, List
    
    
    class ExecResult:
    
        def __init__(self, args: List[str], exit_code: int,
                     stdout: bytes, stderr: bytes = None,
                     stdout_as_list: List[bytes] = None,
                     duration: timedelta = None):
            self._args = args
            self._exit_code = exit_code
            self._stdout = stdout if stdout is not None else b''
            self._stderr = stderr if stderr is not None else b''
            self._duration = duration if duration is not None else timedelta()
            self._response = None
            self._results = {}
            self._assets = []
            # noinspection PyBroadException
            try:
                if stdout_as_list is None:
                    out = self._stdout.decode()
                else:
                    out = "[" + ','.join(stdout_as_list) + "]"
                self._json_out = json.loads(out)
            except:
                self._json_out = None
    
        def __repr__(self):
            out = [
                f"ExecResult[code={self.exit_code}, args={self._args}\n",
                "----stdout---------------------------------------\n",
                self._stdout.decode(),
                "----stderr---------------------------------------\n",
                self._stderr.decode()
            ]
            return ''.join(out)
    
        @property
        def exit_code(self) -> int:
            return self._exit_code
    
        @property
        def args(self) -> List[str]:
            return self._args
    
        @property
        def outraw(self) -> bytes:
            return self._stdout
    
        @property
        def stdout(self) -> str:
            return self._stdout.decode()
    
        @property
        def json(self) -> Optional[Dict]:
            """Output as JSON dictionary or None if not parseable."""
            return self._json_out
    
        @property
        def stderr(self) -> str:
            return self._stderr.decode()
    
        @property
        def duration(self) -> timedelta:
            return self._duration
    
        @property
        def response(self) -> Optional[Dict]:
            return self._response
    
        @property
        def results(self) -> Dict:
            return self._results
    
        @property
        def assets(self) -> List:
            return self._assets
    
        def add_response(self, resp: Dict):
            if self._response:
                resp['previous'] = self._response
            self._response = resp
    
        def add_results(self, results: Dict):
            self._results.update(results)
            if 'response' in results:
                self.add_response(results['response'])
    
        def add_assets(self, assets: List):
            self._assets.extend(assets)
    ����httpd-2.4.64/test/pyhttpd/log.py��������������������������������������������������������������������0000664�0001751�0001751�00000012761�14643712504�016445� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os
    import re
    import time
    from datetime import datetime, timedelta
    from io import SEEK_END
    from typing import List, Tuple, Any
    
    
    class HttpdErrorLog:
        """Checking the httpd error log for errors and warnings, including
           limiting checks from a recent known position forward.
        """
    
        RE_ERRLOG_WARN = re.compile(r'.*\[[^:]+:warn].*')
        RE_ERRLOG_ERROR = re.compile(r'.*\[[^:]+:error].*')
        RE_APLOGNO = re.compile(r'.*\[[^:]+:(error|warn)].* (?P<aplogno>AH\d+): .+')
    
        def __init__(self, path: str):
            self._path = path
            self._ignored_matches = []
            self._ignored_lognos = set()
            # remember the file position we started with
            self._start_pos = 0
            if os.path.isfile(self._path):
                with open(self._path) as fd:
                    self._start_pos = fd.seek(0, SEEK_END)
            self._recent_pos = self._start_pos
            self._recent_errors = []
            self._recent_warnings = []
            self._caught_errors = set()
            self._caught_warnings = set()
            self._caught_matches = set()
    
        def __repr__(self):
            return f"HttpdErrorLog[{self._path}, errors: {' '.join(self._recent_errors)}, " \
                   f"warnings: {' '.join(self._recent_warnings)}]"
    
        @property
        def path(self) -> str:
            return self._path
    
        def clear_log(self):
            if os.path.isfile(self.path):
                os.truncate(self.path, 0)
            self._start_pos = self._recent_pos = 0
            self._recent_errors = []
            self._recent_warnings = []
            self._caught_errors = set()
            self._caught_warnings = set()
            self._caught_matches = set()
    
        def _lookup_matches(self, line: str, matches: List[str]) -> bool:
            for m in matches:
                if re.match(m, line):
                    return True
            return False
    
        def _lookup_lognos(self, line: str, lognos: set) -> bool:
            if len(lognos) > 0:
                m = self.RE_APLOGNO.match(line)
                if m and m.group('aplogno') in lognos:
                    return True
            return False
    
        def clear_ignored_matches(self):
            self._ignored_matches = []
    
        def add_ignored_matches(self, matches: List[str]):
            for m in matches:
                self._ignored_matches.append(re.compile(m))
    
        def clear_ignored_lognos(self):
            self._ignored_lognos = set()
    
        def add_ignored_lognos(self, lognos: List[str]):
            for l in lognos:
                self._ignored_lognos.add(l)
    
        def _is_ignored(self, line: str) -> bool:
            if self._lookup_matches(line, self._ignored_matches):
                return True
            if self._lookup_lognos(line, self._ignored_lognos):
                return True
            return False
    
        def ignore_recent(self, lognos: List[str] = [], matches: List[str] = []):
            """After a test case triggered errors/warnings on purpose, add
               those to our 'caught' list so the do not get reported as 'missed'.
               """
            self._recent_errors = []
            self._recent_warnings = []
            if os.path.isfile(self._path):
                with open(self._path) as fd:
                    fd.seek(self._recent_pos, os.SEEK_SET)
                    lognos_set = set(lognos)
                    for line in fd:
                        if self._is_ignored(line):
                            continue
                        if self._lookup_matches(line, matches):
                            self._caught_matches.add(line)
                            continue
                        m = self.RE_ERRLOG_WARN.match(line)
                        if m and self._lookup_lognos(line, lognos_set):
                            self._caught_warnings.add(line)
                            continue
                        m = self.RE_ERRLOG_ERROR.match(line)
                        if m and self._lookup_lognos(line, lognos_set):
                            self._caught_errors.add(line)
                            continue
                    self._recent_pos = fd.tell()
    
        def get_missed(self) -> Tuple[List[str], List[str]]:
            errors = []
            warnings = []
            self._recent_errors = []
            self._recent_warnings = []
            if os.path.isfile(self._path):
                with open(self._path) as fd:
                    fd.seek(self._start_pos, os.SEEK_SET)
                    for line in fd:
                        if self._is_ignored(line):
                            continue
                        if line in self._caught_matches:
                            continue
                        m = self.RE_ERRLOG_WARN.match(line)
                        if m and line not in self._caught_warnings:
                            warnings.append(line)
                            continue
                        m = self.RE_ERRLOG_ERROR.match(line)
                        if m and line not in self._caught_errors:
                            errors.append(line)
                            continue
                    self._start_pos = self._recent_pos = fd.tell()
            self._caught_errors = set()
            self._caught_warnings = set()
            self._caught_matches = set()
            return errors, warnings
    
        def scan_recent(self, pattern: re.Pattern, timeout=10):
            if not os.path.isfile(self.path):
                return False
            with open(self.path) as fd:
                end = datetime.now() + timedelta(seconds=timeout)
                while True:
                    fd.seek(self._recent_pos, os.SEEK_SET)
                    for line in fd:
                        if pattern.match(line):
                            return True
                    if datetime.now() > end:
                        raise TimeoutError(f"pattern not found in error log after {timeout} seconds")
                    time.sleep(.1)
            return False
    ���������������httpd-2.4.64/test/pyhttpd/env.py��������������������������������������������������������������������0000664�0001751�0001751�00000100445�14643712504�016451� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import importlib
    import inspect
    import logging
    import re
    import os
    import shutil
    import stat
    import subprocess
    import sys
    import time
    from datetime import datetime, timedelta
    from string import Template
    from typing import List, Optional
    
    from configparser import ConfigParser, ExtendedInterpolation
    from urllib.parse import urlparse
    
    from .certs import Credentials, HttpdTestCA, CertificateSpec
    from .log import HttpdErrorLog
    from .nghttp import Nghttp
    from .result import ExecResult
    
    
    log = logging.getLogger(__name__)
    
    
    class Dummy:
        pass
    
    
    class HttpdTestSetup:
    
        # the modules we want to load
        MODULES = [
            "log_config",
            "logio",
            "unixd",
            "version",
            "watchdog",
            "authn_core",
            "authz_host",
            "authz_groupfile",
            "authz_user",
            "authz_core",
            "access_compat",
            "auth_basic",
            "cache",
            "cache_disk",
            "cache_socache",
            "socache_shmcb",
            "dumpio",
            "reqtimeout",
            "filter",
            "mime",
            "env",
            "headers",
            "setenvif",
            "slotmem_shm",
            "status",
            "dir",
            "alias",
            "rewrite",
            "deflate",
            "proxy",
            "proxy_http",
        ]
    
        CURL_STDOUT_SEPARATOR = "===CURL_STDOUT_SEPARATOR==="
    
        def __init__(self, env: 'HttpdTestEnv'):
            self.env = env
            self._source_dirs = [os.path.dirname(inspect.getfile(HttpdTestSetup))]
            self._modules = HttpdTestSetup.MODULES.copy()
            self._optional_modules = []
    
        def add_source_dir(self, source_dir):
            self._source_dirs.append(source_dir)
    
        def add_modules(self, modules: List[str]):
            self._modules.extend(modules)
    
        def add_optional_modules(self, modules: List[str]):
            self._optional_modules.extend(modules)
    
        def make(self):
            self._make_dirs()
            self._make_conf()
            if self.env.mpm_module is not None \
                    and self.env.mpm_module in self.env.mpm_modules:
                self.add_modules([self.env.mpm_module])
            if self.env.ssl_module is not None:
                self.add_modules([self.env.ssl_module])
            self._make_modules_conf()
            self._make_htdocs()
            self._add_aptest()
            self._build_clients()
            self.env.clear_curl_headerfiles()
    
        def _make_dirs(self):
            if not os.path.exists(self.env.gen_dir):
                os.makedirs(self.env.gen_dir)
            if not os.path.exists(self.env.server_logs_dir):
                os.makedirs(self.env.server_logs_dir)
    
        def _make_conf(self):
            # remove anything from another run/test suite
            conf_dest_dir = os.path.join(self.env.server_dir, 'conf')
            if os.path.isdir(conf_dest_dir):
                shutil.rmtree(conf_dest_dir)
            for d in self._source_dirs:
                conf_src_dir = os.path.join(d, 'conf')
                if os.path.isdir(conf_src_dir):
                    if not os.path.exists(conf_dest_dir):
                        os.makedirs(conf_dest_dir)
                    for name in os.listdir(conf_src_dir):
                        src_path = os.path.join(conf_src_dir, name)
                        m = re.match(r'(.+).template', name)
                        if m:
                            self._make_template(src_path, os.path.join(conf_dest_dir, m.group(1)))
                        elif os.path.isfile(src_path):
                            shutil.copy(src_path, os.path.join(conf_dest_dir, name))
    
        def _make_template(self, src, dest):
            var_map = dict()
            for name, value in HttpdTestEnv.__dict__.items():
                if isinstance(value, property):
                    var_map[name] = value.fget(self.env)
            t = Template(''.join(open(src).readlines()))
            with open(dest, 'w') as fd:
                fd.write(t.substitute(var_map))
    
        def _make_modules_conf(self):
            loaded = set()
            modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf')
            with open(modules_conf, 'w') as fd:
                # issue load directives for all modules we want that are shared
                missing_mods = list()
                for m in self._modules:
                    match = re.match(r'^mod_(.+)$', m)
                    if match:
                        m = match.group(1)
                    if m in loaded:
                        continue
                    mod_path = os.path.join(self.env.libexec_dir, f"mod_{m}.so")
                    if os.path.isfile(mod_path):
                        fd.write(f"LoadModule {m}_module   \"{mod_path}\"\n")
                    elif m in self.env.dso_modules:
                        missing_mods.append(m)
                    else:
                        fd.write(f"#built static: LoadModule {m}_module   \"{mod_path}\"\n")
                    loaded.add(m)
                for m in self._optional_modules:
                    match = re.match(r'^mod_(.+)$', m)
                    if match:
                        m = match.group(1)
                    if m in loaded:
                        continue
                    mod_path = os.path.join(self.env.libexec_dir, f"mod_{m}.so")
                    if os.path.isfile(mod_path):
                        fd.write(f"LoadModule {m}_module   \"{mod_path}\"\n")
                        loaded.add(m)
            if len(missing_mods) > 0:
                raise Exception(f"Unable to find modules: {missing_mods} "
                                f"DSOs: {self.env.dso_modules}")
    
        def _make_htdocs(self):
            if not os.path.exists(self.env.server_docs_dir):
                os.makedirs(self.env.server_docs_dir)
            dest_dir = os.path.join(self.env.server_dir, 'htdocs')
            # remove anything from another run/test suite
            if os.path.isdir(dest_dir):
                shutil.rmtree(dest_dir)
            for d in self._source_dirs:
                srcdocs = os.path.join(d, 'htdocs')
                if os.path.isdir(srcdocs):
                    shutil.copytree(srcdocs, dest_dir, dirs_exist_ok=True)
            # make all contained .py scripts executable
            for dirpath, _dirnames, filenames in os.walk(dest_dir):
                for fname in filenames:
                    if re.match(r'.+\.py', fname):
                        py_file = os.path.join(dirpath, fname)
                        st = os.stat(py_file)
                        os.chmod(py_file, st.st_mode | stat.S_IEXEC)
    
        def _add_aptest(self):
            local_dir = os.path.dirname(inspect.getfile(HttpdTestSetup))
            p = subprocess.run([self.env.apxs, '-c', 'mod_aptest.c'],
                               capture_output=True,
                               cwd=os.path.join(local_dir, 'mod_aptest'))
            rv = p.returncode
            if rv != 0:
                log.error(f"compiling mod_aptest failed: {p.stderr}")
                raise Exception(f"compiling mod_aptest failed: {p.stderr}")
    
            modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf')
            with open(modules_conf, 'a') as fd:
                # load our test module which is not installed
                fd.write(f"LoadModule aptest_module   \"{local_dir}/mod_aptest/.libs/mod_aptest.so\"\n")
    
        def _build_clients(self):
            clients_dir = os.path.join(
                os.path.dirname(os.path.dirname(inspect.getfile(HttpdTestSetup))),
                'clients')
            p = subprocess.run(['make'], capture_output=True, cwd=clients_dir)
            rv = p.returncode
            if rv != 0:
                log.error(f"compiling test clients failed: {p.stderr}")
                raise Exception(f"compiling test clients failed: {p.stderr}")
    
    
    class HttpdTestEnv:
    
        LIBEXEC_DIR = None
    
        @classmethod
        def has_python_package(cls, name: str) -> bool:
            if name in sys.modules:
                # already loaded
                return True
            elif (spec := importlib.util.find_spec(name)) is not None:
                module = importlib.util.module_from_spec(spec)
                sys.modules[name] = module
                spec.loader.exec_module(module)
                return True
            else:
                return False
    
        @classmethod
        def get_ssl_module(cls):
            return os.environ['SSL'] if 'SSL' in os.environ else 'mod_ssl'
    
        @classmethod
        def has_shared_module(cls, name):
            if cls.LIBEXEC_DIR is None:
                env = HttpdTestEnv()  # will initialized it
            path = os.path.join(cls.LIBEXEC_DIR, f"mod_{name}.so")
            return os.path.isfile(path)
    
        def __init__(self, pytestconfig=None):
            self._our_dir = os.path.dirname(inspect.getfile(Dummy))
            self.config = ConfigParser(interpolation=ExtendedInterpolation())
            self.config.read(os.path.join(self._our_dir, 'config.ini'))
    
            self._bin_dir = self.config.get('global', 'bindir')
            self._apxs = self.config.get('global', 'apxs')
            self._prefix = self.config.get('global', 'prefix')
            self._apachectl = self.config.get('global', 'apachectl')
            if HttpdTestEnv.LIBEXEC_DIR is None:
                HttpdTestEnv.LIBEXEC_DIR = self._libexec_dir = self.get_apxs_var('LIBEXECDIR')
            self._curl = self.config.get('global', 'curl_bin')
            if 'CURL' in os.environ:
                self._curl = os.environ['CURL']
            self._nghttp = self.config.get('global', 'nghttp')
            if self._nghttp is None:
                self._nghttp = 'nghttp'
            self._h2load = self.config.get('global', 'h2load')
            if self._h2load is None:
                self._h2load = 'h2load'
    
            self._http_port = int(self.config.get('test', 'http_port'))
            self._http_port2 = int(self.config.get('test', 'http_port2'))
            self._https_port = int(self.config.get('test', 'https_port'))
            self._proxy_port = int(self.config.get('test', 'proxy_port'))
            self._ws_port = int(self.config.get('test', 'ws_port'))
            self._http_tld = self.config.get('test', 'http_tld')
            self._test_dir = self.config.get('test', 'test_dir')
            self._clients_dir = os.path.join(os.path.dirname(self._test_dir), 'clients')
            self._gen_dir = self.config.get('test', 'gen_dir')
            self._server_dir = os.path.join(self._gen_dir, 'apache')
            self._server_conf_dir = os.path.join(self._server_dir, "conf")
            self._server_docs_dir = os.path.join(self._server_dir, "htdocs")
            self._server_logs_dir = os.path.join(self.server_dir, "logs")
            self._server_access_log = os.path.join(self._server_logs_dir, "access_log")
            self._error_log = HttpdErrorLog(os.path.join(self._server_logs_dir, "error_log"))
            self._apachectl_stderr = None
    
            self._dso_modules = self.config.get('httpd', 'dso_modules').split(' ')
            self._mpm_modules = self.config.get('httpd', 'mpm_modules').split(' ')
            self._mpm_module = f"mpm_{os.environ['MPM']}" if 'MPM' in os.environ else 'mpm_event'
            self._ssl_module = self.get_ssl_module()
            if len(self._ssl_module.strip()) == 0:
                self._ssl_module = None
    
            self._httpd_addr = "127.0.0.1"
            self._http_base = f"http://{self._httpd_addr}:{self.http_port}"
            self._https_base = f"https://{self._httpd_addr}:{self.https_port}"
    
            self._verbosity = pytestconfig.option.verbose if pytestconfig is not None else 0
            self._test_conf = os.path.join(self._server_conf_dir, "test.conf")
            self._httpd_base_conf = []
            self._httpd_log_modules = ['aptest']
            self._log_interesting = None
            self._setup = None
    
            self._ca = None
            self._cert_specs = [CertificateSpec(domains=[
                f"test1.{self._http_tld}",
                f"test2.{self._http_tld}",
                f"test3.{self._http_tld}",
                f"cgi.{self._http_tld}",
            ], key_type='rsa4096')]
    
            self._verify_certs = False
            self._curl_headerfiles_n = 0
            self._curl_version = None
            self._h2load_version = None
            self._current_test = None
    
        def add_httpd_conf(self, lines: List[str]):
            self._httpd_base_conf.extend(lines)
    
        def add_httpd_log_modules(self, modules: List[str]):
            self._httpd_log_modules.extend(modules)
    
        def issue_certs(self):
            if self._ca is None:
                self._ca = HttpdTestCA.create_root(name=self.http_tld,
                                                   store_dir=os.path.join(self.server_dir, 'ca'),
                                                   key_type="rsa4096")
            self._ca.issue_certs(self._cert_specs)
    
        def setup_httpd(self, setup: HttpdTestSetup = None):
            """Create the server environment with config, htdocs and certificates"""
            self._setup = setup if setup is not None else HttpdTestSetup(env=self)
            self._setup.make()
            self.issue_certs()
            if self._httpd_log_modules:
                if self._verbosity >= 2:
                    log_level = "trace2"
                elif self._verbosity >= 1:
                    log_level = "debug"
                else:
                    log_level = "info"
                self._log_interesting = "LogLevel"
                for name in self._httpd_log_modules:
                    self._log_interesting += f" {name}:{log_level}"
    
        def check_error_log(self):
            errors, warnings = self._error_log.get_missed()
            assert (len(errors), len(warnings)) == (0, 0),\
                    f"apache logged {len(errors)} errors and {len(warnings)} warnings: \n"\
                    "{0}\n{1}\n".format("\n".join(errors), "\n".join(warnings))
    
        @property
        def curl(self) -> str:
            return self._curl
    
        @property
        def apxs(self) -> str:
            return self._apxs
    
        @property
        def verbosity(self) -> int:
            return self._verbosity
    
        @property
        def prefix(self) -> str:
            return self._prefix
    
        @property
        def mpm_module(self) -> str:
            return self._mpm_module
    
        @property
        def ssl_module(self) -> str:
            return self._ssl_module
    
        @property
        def http_addr(self) -> str:
            return self._httpd_addr
    
        @property
        def http_port(self) -> int:
            return self._http_port
    
        @property
        def http_port2(self) -> int:
            return self._http_port2
    
        @property
        def https_port(self) -> int:
            return self._https_port
    
        @property
        def proxy_port(self) -> int:
            return self._proxy_port
    
        @property
        def ws_port(self) -> int:
            return self._ws_port
    
        @property
        def http_tld(self) -> str:
            return self._http_tld
    
        @property
        def http_base_url(self) -> str:
            return self._http_base
    
        @property
        def https_base_url(self) -> str:
            return self._https_base
    
        @property
        def bin_dir(self) -> str:
            return self._bin_dir
    
        @property
        def gen_dir(self) -> str:
            return self._gen_dir
    
        @property
        def test_dir(self) -> str:
            return self._test_dir
    
        @property
        def clients_dir(self) -> str:
            return self._clients_dir
    
        @property
        def server_dir(self) -> str:
            return self._server_dir
    
        @property
        def server_logs_dir(self) -> str:
            return self._server_logs_dir
    
        @property
        def libexec_dir(self) -> str:
            return HttpdTestEnv.LIBEXEC_DIR
    
        @property
        def dso_modules(self) -> List[str]:
            return self._dso_modules
    
        @property
        def mpm_modules(self) -> List[str]:
            return self._mpm_modules
    
        @property
        def server_conf_dir(self) -> str:
            return self._server_conf_dir
    
        @property
        def server_docs_dir(self) -> str:
            return self._server_docs_dir
    
        @property
        def httpd_error_log(self) -> HttpdErrorLog:
            return self._error_log
    
        def htdocs_src(self, path):
            return os.path.join(self._our_dir, 'htdocs', path)
    
        @property
        def h2load(self) -> str:
            return self._h2load
    
        @property
        def ca(self) -> Credentials:
            return self._ca
    
        @property
        def current_test_name(self) -> str:
            return self._current_test
    
        def set_current_test_name(self, val) -> None:
            self._current_test = val
    
        @property
        def apachectl_stderr(self):
            return self._apachectl_stderr
    
        def add_cert_specs(self, specs: List[CertificateSpec]):
            self._cert_specs.extend(specs)
    
        def get_credentials_for_name(self, dns_name) -> List['Credentials']:
            for spec in [s for s in self._cert_specs if s.domains is not None]:
                if dns_name in spec.domains:
                    return self.ca.get_credentials_for_name(spec.domains[0])
            return []
    
        def _versiontuple(self, v):
            v = re.sub(r'(\d+\.\d+(\.\d+)?)(-\S+)?', r'\1', v)
            return tuple(map(int, v.split('.')))
    
        def httpd_is_at_least(self, minv):
            hv = self._versiontuple(self.get_httpd_version())
            return hv >= self._versiontuple(minv)
    
        def has_h2load(self):
            return self._h2load != ""
    
        def h2load_is_at_least(self, minv):
            if not self.has_h2load():
                return False
            if self._h2load_version is None:
                p = subprocess.run([self._h2load, '--version'], capture_output=True, text=True)
                if p.returncode != 0:
                    return False
                s = p.stdout.strip()
                m = re.match(r'h2load nghttp2/(\S+)', s)
                if m:
                    self._h2load_version = self._versiontuple(m.group(1))
            if self._h2load_version is not None:
                return self._h2load_version >= self._versiontuple(minv)
            return False
    
        def curl_is_at_least(self, minv):
            if self._curl_version is None:
                p = subprocess.run([self._curl, '-V'], capture_output=True, text=True)
                if p.returncode != 0:
                    return False
                for l in p.stdout.splitlines():
                    m = re.match(r'curl ([0-9.]+)[- ].*', l)
                    if m:
                        self._curl_version = self._versiontuple(m.group(1))
                        break
            if self._curl_version is not None:
                return self._curl_version >= self._versiontuple(minv)
            return False
    
        def curl_is_less_than(self, version):
            if self._curl_version is None:
                p = subprocess.run([self._curl, '-V'], capture_output=True, text=True)
                if p.returncode != 0:
                    return False
                for l in p.stdout.splitlines():
                    m = re.match(r'curl ([0-9.]+)[- ].*', l)
                    if m:
                        self._curl_version = self._versiontuple(m.group(1))
                        break
            if self._curl_version is not None:
                return self._curl_version < self._versiontuple(version)
            return False
    
        def has_nghttp(self):
            return self._nghttp != ""
    
        def has_nghttp_get_assets(self):
            if not self.has_nghttp():
                return False
            args = [self._nghttp, "-a"]
            p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
            rv = p.returncode
            if rv != 0:
                return False
            return p.stderr == ""
    
        def get_apxs_var(self, name: str) -> str:
            p = subprocess.run([self._apxs, "-q", name], capture_output=True, text=True)
            if p.returncode != 0:
                return ""
            return p.stdout.strip()
    
        def get_httpd_version(self) -> str:
            return self.get_apxs_var("HTTPD_VERSION")
    
        def mkpath(self, path):
            if not os.path.exists(path):
                return os.makedirs(path)
    
        def run(self, args, stdout_list=False, intext=None, inbytes=None, debug_log=True):
            if debug_log:
                log.debug(f"run: {args}")
            start = datetime.now()
            if intext is not None:
                inbytes = intext.encode()
            p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
                               input=inbytes)
            stdout_as_list = None
            if stdout_list:
                try:
                    out = p.stdout.decode()
                    if HttpdTestSetup.CURL_STDOUT_SEPARATOR in out:
                        stdout_as_list = out.split(HttpdTestSetup.CURL_STDOUT_SEPARATOR)
                        if not stdout_as_list[len(stdout_as_list) - 1]:
                            stdout_as_list.pop()
                    p.stdout.replace(HttpdTestSetup.CURL_STDOUT_SEPARATOR.encode(), b'')
                except:
                    pass
            return ExecResult(args=args, exit_code=p.returncode,
                              stdout=p.stdout, stderr=p.stderr,
                              stdout_as_list=stdout_as_list,
                              duration=datetime.now() - start)
    
        def mkurl(self, scheme, hostname, path='/'):
            port = self.https_port if scheme == 'https' else self.http_port
            return f"{scheme}://{hostname}.{self.http_tld}:{port}{path}"
    
        def install_test_conf(self, lines: List[str]):
            self.apache_stop()
            with open(self._test_conf, 'w') as fd:
                fd.write('\n'.join(self._httpd_base_conf))
                fd.write('\n')
                fd.write(f"CoreDumpDirectory {self._server_dir}\n")
                fd.write('\n')
                if self._verbosity >= 3:
                    fd.write(f"LogLevel trace7 ssl:trace6\n")
                    fd.write(f"DumpIoOutput on\n")
                    fd.write(f"DumpIoInput on\n")
                elif self._verbosity >= 2:
                    fd.write(f"LogLevel debug core:trace5 {self.mpm_module}:trace5 ssl:trace5 http:trace5\n")
                elif self._verbosity >= 1:
                    fd.write(f"LogLevel info\n")
                else:
                    fd.write(f"LogLevel warn\n")
                if self._log_interesting:
                    fd.write(self._log_interesting)
                fd.write('\n\n')
                fd.write('\n'.join(lines))
                fd.write('\n')
    
        def is_live(self, url: str = None, timeout: timedelta = None):
            if url is None:
                url = self._http_base
            if timeout is None:
                timeout = timedelta(seconds=5)
            try_until = datetime.now() + timeout
            last_err = ""
            while datetime.now() < try_until:
                # noinspection PyBroadException
                try:
                    r = self.curl_get(url, insecure=True)
                    if r.exit_code == 0:
                        return True
                    time.sleep(.1)
                except ConnectionRefusedError:
                    log.debug("connection refused")
                    time.sleep(.1)
                except:
                    if last_err != str(sys.exc_info()[0]):
                        last_err = str(sys.exc_info()[0])
                        log.debug("Unexpected error: %s", last_err)
                    time.sleep(.1)
            log.debug(f"Unable to contact server after {timeout}")
            return False
    
        def is_dead(self, url: str = None, timeout: timedelta = None):
            if url is None:
                url = self._http_base
            if timeout is None:
                timeout = timedelta(seconds=5)
            try_until = datetime.now() + timeout
            last_err = None
            while datetime.now() < try_until:
                # noinspection PyBroadException
                try:
                    r = self.curl_get(url)
                    if r.exit_code != 0:
                        return True
                    time.sleep(.1)
                except ConnectionRefusedError:
                    log.debug("connection refused")
                    return True
                except:
                    if last_err != str(sys.exc_info()[0]):
                        last_err = str(sys.exc_info()[0])
                        log.debug("Unexpected error: %s", last_err)
                    time.sleep(.1)
            log.debug(f"Server still responding after {timeout}")
            return False
    
        def _run_apachectl(self, cmd) -> ExecResult:
            conf_file = 'stop.conf' if cmd == 'stop' else 'httpd.conf'
            args = [self._apachectl,
                    "-d", self.server_dir,
                    "-f", os.path.join(self._server_dir, f'conf/{conf_file}'),
                    "-k", cmd]
            r = self.run(args)
            self._apachectl_stderr = r.stderr
            if r.exit_code != 0:
                log.warning(f"failed: {r}")
            return r
    
        def apache_reload(self):
            r = self._run_apachectl("graceful")
            if r.exit_code == 0:
                timeout = timedelta(seconds=10)
                return 0 if self.is_live(self._http_base, timeout=timeout) else -1
            return r.exit_code
    
        def apache_restart(self):
            self.apache_stop()
            r = self._run_apachectl("start")
            if r.exit_code == 0:
                timeout = timedelta(seconds=10)
                return 0 if self.is_live(self._http_base, timeout=timeout) else -1
            return r.exit_code
            
        def apache_stop(self):
            r = self._run_apachectl("stop")
            if r.exit_code == 0:
                timeout = timedelta(seconds=10)
                return 0 if self.is_dead(self._http_base, timeout=timeout) else -1
            return r
    
        def apache_graceful_stop(self):
            log.debug("stop apache")
            self._run_apachectl("graceful-stop")
            return 0 if self.is_dead() else -1
    
        def apache_fail(self):
            log.debug("expect apache fail")
            self._run_apachectl("stop")
            rv = self._run_apachectl("start")
            if rv == 0:
                rv = 0 if self.is_dead() else -1
            else:
                rv = 0
            return rv
    
        def apache_access_log_clear(self):
            if os.path.isfile(self._server_access_log):
                os.remove(self._server_access_log)
    
        def get_ca_pem_file(self, hostname: str) -> Optional[str]:
            if len(self.get_credentials_for_name(hostname)) > 0:
                return self.ca.cert_file
            return None
    
        def clear_curl_headerfiles(self):
            for fname in os.listdir(path=self.gen_dir):
                if re.match(r'curl\.headers\.\d+', fname):
                    os.remove(os.path.join(self.gen_dir, fname))
            self._curl_headerfiles_n = 0
    
        def curl_resolve_args(self, url, insecure=False, force_resolve=True, options=None):
            u = urlparse(url)
    
            args = [
            ]
            if u.scheme == 'http':
                pass
            elif insecure:
                args.append('--insecure')
            elif options and "--cacert" in options:
                pass
            elif u.hostname:
                ca_pem = self.get_ca_pem_file(u.hostname)
                if ca_pem:
                    args.extend(["--cacert", ca_pem])
    
            if force_resolve and u.hostname and u.hostname != 'localhost' \
                    and u.hostname != self._httpd_addr \
                    and not re.match(r'^(\d+|\[|:).*', u.hostname):
                assert u.port, f"port not in url: {url}"
                args.extend(["--resolve", f"{u.hostname}:{u.port}:{self._httpd_addr}"])
            return args
    
        def curl_complete_args(self, urls, stdout_list=False,
                               timeout=None, options=None,
                               insecure=False, force_resolve=True):
            headerfile = f"{self.gen_dir}/curl.headers.{self._curl_headerfiles_n}"
            self._curl_headerfiles_n += 1
    
            args = [
                self._curl, "-s", "--path-as-is", "-D", headerfile,
            ]
            args.extend(self.curl_resolve_args(urls[0], insecure=insecure,
                                               force_resolve=force_resolve,
                                               options=options))
            if stdout_list:
                args.extend(['-w', '%{stdout}' + HttpdTestSetup.CURL_STDOUT_SEPARATOR])
            if self._current_test is not None:
                args.extend(["-H", f'AP-Test-Name: {self._current_test}'])
            if timeout is not None and int(timeout) > 0:
                args.extend(["--connect-timeout", str(int(timeout))])
            if options:
                args.extend(options)
            return args, headerfile
    
        def curl_parse_headerfile(self, headerfile: str, r: ExecResult = None) -> ExecResult:
            lines = open(headerfile).readlines()
            if r is None:
                r = ExecResult(args=[], exit_code=0, stdout=b'', stderr=b'')
    
            response = None
            def fin_response(response):
                if response:
                    r.add_response(response)
    
            expected = ['status']
            for line in lines:
                if re.match(r'^$', line):
                    if 'trailer' in expected:
                        # end of trailers
                        fin_response(response)
                        response = None
                        expected = ['status']
                    elif 'header' in expected:
                        # end of header, another status or trailers might follow
                        expected = ['status', 'trailer']
                    else:
                        assert False, f"unexpected line: {line}"
                    continue
                if 'status' in expected:
                    log.debug("reading 1st response line: %s", line)
                    m = re.match(r'^(\S+) (\d+) (.*)$', line)
                    if m:
                        fin_response(response)
                        response = {
                            "protocol": m.group(1),
                            "status": int(m.group(2)),
                            "description": m.group(3),
                            "header": {},
                            "trailer": {},
                            "body": r.outraw
                        }
                        expected = ['header']
                        continue
                if 'trailer' in expected:
                    m = re.match(r'^([^:]+):\s*(.*)$', line)
                    if m:
                        response['trailer'][m.group(1).lower()] = m.group(2)
                        continue
                if 'header' in expected:
                    m = re.match(r'^([^:]+):\s*(.*)$', line)
                    if m:
                        response['header'][m.group(1).lower()] = m.group(2)
                        continue
                assert False, f"unexpected line: {line}"
    
            fin_response(response)
            return r
    
        def curl_raw(self, urls, timeout=10, options=None, insecure=False,
                     force_resolve=True, no_stdout_list=False):
            if not isinstance(urls, list):
                urls = [urls]
            stdout_list = False
            if len(urls) > 1 and not no_stdout_list:
                stdout_list = True
            args, headerfile = self.curl_complete_args(
                urls=urls, stdout_list=stdout_list,
                timeout=timeout, options=options, insecure=insecure,
                force_resolve=force_resolve)
            args += urls
            r = self.run(args, stdout_list=stdout_list)
            if r.exit_code == 0:
                self.curl_parse_headerfile(headerfile, r=r)
                if r.json:
                    r.response["json"] = r.json
            if os.path.isfile(headerfile):
                os.remove(headerfile)
            return r
    
        def curl_get(self, url, insecure=False, options=None):
            return self.curl_raw([url], insecure=insecure, options=options)
    
        def curl_upload(self, url, fpath, timeout=5, options=None):
            if not options:
                options = []
            options.extend([
                "--form", ("file=@%s" % fpath)
            ])
            return self.curl_raw(urls=[url], timeout=timeout, options=options)
    
        def curl_post_data(self, url, data="", timeout=5, options=None):
            if not options:
                options = []
            options.extend(["--data", "%s" % data])
            return self.curl_raw(url, timeout, options)
    
        def curl_post_value(self, url, key, value, timeout=5, options=None):
            if not options:
                options = []
            options.extend(["--form", "{0}={1}".format(key, value)])
            return self.curl_raw(url, timeout, options)
    
        def curl_protocol_version(self, url, timeout=5, options=None):
            if not options:
                options = []
            options.extend(["-w", "%{http_version}\n", "-o", "/dev/null"])
            r = self.curl_raw(url, timeout=timeout, options=options)
            if r.exit_code == 0 and r.response:
                return r.response["body"].decode('utf-8').rstrip()
            return -1
            
        def nghttp(self):
            return Nghttp(self._nghttp, connect_addr=self._httpd_addr,
                          tmp_dir=self.gen_dir, test_name=self._current_test)
    
        def h2load_status(self, run: ExecResult):
            stats = {}
            m = re.search(
                r'requests: (\d+) total, (\d+) started, (\d+) done, (\d+) succeeded'
                r', (\d+) failed, (\d+) errored, (\d+) timeout', run.stdout)
            if m:
                stats["requests"] = {
                    "total": int(m.group(1)),
                    "started": int(m.group(2)),
                    "done": int(m.group(3)),
                    "succeeded": int(m.group(4))
                }
                m = re.search(r'status codes: (\d+) 2xx, (\d+) 3xx, (\d+) 4xx, (\d+) 5xx',
                              run.stdout)
                if m:
                    stats["status"] = {
                        "2xx": int(m.group(1)),
                        "3xx": int(m.group(2)),
                        "4xx": int(m.group(3)),
                        "5xx": int(m.group(4))
                    }
                run.add_results({"h2load": stats})
            return run
    
        def make_data_file(self, indir: str, fname: str, fsize: int) -> str:
            fpath = os.path.join(indir, fname)
            s10 = "0123456789"
            s = (101 * s10) + s10[0:3]
            with open(fpath, 'w') as fd:
                for i in range(int(fsize / 1024)):
                    fd.write(f"{i:09d}-{s}\n")
                remain = int(fsize % 1024)
                if remain != 0:
                    i = int(fsize / 1024) + 1
                    s = f"{i:09d}-{s}\n"
                    fd.write(s[0:remain])
            return fpath
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/pyhttpd/ws_util.py����������������������������������������������������������������0000664�0001751�0001751�00000006767�14473316336�017367� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import logging
    import struct
    
    
    log = logging.getLogger(__name__)
    
    
    class WsFrame:
    
        CONT = 0
        TEXT = 1
        BINARY = 2
        RSVD3 = 3
        RSVD4 = 4
        RSVD5 = 5
        RSVD6 = 6
        RSVD7 = 7
        CLOSE = 8
        PING = 9
        PONG = 10
        RSVD11 = 11
        RSVD12 = 12
        RSVD13 = 13
        RSVD14 = 14
        RSVD15 = 15
    
        OP_NAMES = [
            "CONT",
            "TEXT",
            "BINARY",
            "RSVD3",
            "RSVD4",
            "RSVD5",
            "RSVD6",
            "RSVD7",
            "CLOSE",
            "PING",
            "PONG",
            "RSVD11",
            "RSVD12",
            "RSVD13",
            "RSVD14",
            "RSVD15",
        ]
    
        def __init__(self, opcode: int, fin: bool, mask: bytes, data: bytes):
            self.opcode = opcode
            self.fin = fin
            self.mask = mask
            self.data = data
            self.length = len(data)
    
        def __repr__(self):
            return f'WsFrame[{self.OP_NAMES[self.opcode]} fin={self.fin}, mask={self.mask}, len={len(self.data)}]'
    
        @property
        def data_len(self) -> int:
            return len(self.data) if self.data else 0
    
        def to_network(self) -> bytes:
            nd = bytearray()
            h1 = self.opcode
            if self.fin:
                h1 |= 0x80
            nd.extend(struct.pack("!B", h1))
            mask_bit = 0x80 if self.mask is not None else 0x0
            h2 = self.data_len
            if h2 > 65535:
                nd.extend(struct.pack("!BQ", 127|mask_bit, h2))
            elif h2 > 126:
                nd.extend(struct.pack("!BH", 126|mask_bit, h2))
            else:
                nd.extend(struct.pack("!B", h2|mask_bit))
            if self.mask is not None:
                nd.extend(self.mask)
            if self.data is not None:
                nd.extend(self.data)
            return nd
    
        @classmethod
        def client_ping(cls, data: bytes, mask: bytes = None) -> 'WsFrame':
            if mask is None:
                mask = bytes.fromhex('00 00 00 00')
            return WsFrame(opcode=WsFrame.PING, fin=True, mask=mask, data=data)
    
        @classmethod
        def client_close(cls, code: int, reason: str = None,
                         mask: bytes = None) -> 'WsFrame':
            data = bytearray(struct.pack("!H", code))
            if reason is not None:
                data.extend(reason.encode())
            if mask is None:
                mask = bytes.fromhex('00 00 00 00')
            return WsFrame(opcode=WsFrame.CLOSE, fin=True, mask=mask, data=data)
    
    
    class WsFrameReader:
    
        def __init__(self, data: bytes):
            self.data = data
    
        def _read(self, n: int):
            if len(self.data) < n:
                raise EOFError(f'have {len(self.data)} bytes left, but {n} requested')
            elif n == 0:
                return b''
            chunk = self.data[:n]
            del self.data[:n]
            return chunk
    
        def next_frame(self):
            data = self._read(2)
            h1, h2 = struct.unpack("!BB", data)
            log.debug(f'parsed h1={h1} h2={h2} from {data}')
            fin = True if h1 & 0x80 else False
            opcode = h1 & 0xf
            has_mask = True if h2 & 0x80 else False
            mask = None
            dlen = h2 & 0x7f
            if dlen == 126:
                (dlen,) = struct.unpack("!H", self._read(2))
            elif dlen == 127:
                (dlen,) = struct.unpack("!Q", self._read(8))
            if has_mask:
                mask = self._read(4)
            return WsFrame(opcode=opcode, fin=fin, mask=mask, data=self._read(dlen))
    
        def eof(self):
            return len(self.data) == 0
    
        @classmethod
        def parse(cls, data: bytes):
            frames = []
            reader = WsFrameReader(data=data)
            while not reader.eof():
                frames.append(reader.next_frame())
            return frames
    ���������httpd-2.4.64/test/clients/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015254� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/clients/.gitignore����������������������������������������������������������������0000664�0001751�0001751�00000000004�14473316336�017236� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h2ws����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/clients/h2ws.c��������������������������������������������������������������������0000664�0001751�0001751�00000101703�14737240630�016301� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <assert.h>
    #include <inttypes.h>
    #include <stdlib.h>
    #ifdef APR_HAVE_UNISTD_H
    #  include <unistd.h>
    #endif /* HAVE_UNISTD_H */
    #ifdef APR_HAVE_FCNTL_H
    #  include <fcntl.h>
    #endif /* HAVE_FCNTL_H */
    #include <sys/types.h>
    #include <sys/time.h>
    #ifdef APR_HAVE_SYS_SOCKET_H
    #  include <sys/socket.h>
    #endif /* HAVE_SYS_SOCKET_H */
    #ifdef APR_HAVE_NETDB_H
    #  include <netdb.h>
    #endif /* HAVE_NETDB_H */
    #ifdef APR_HAVE_NETINET_IN_H
    #  include <netinet/in.h>
    #endif /* HAVE_NETINET_IN_H */
    #include <netinet/tcp.h>
    #include <poll.h>
    #include <signal.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <errno.h>
    
    #include <nghttp2/nghttp2.h>
    
    #define MAKE_NV(NAME, VALUE)                                                   \
      {                                                                            \
        (uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1,    \
            NGHTTP2_NV_FLAG_NONE                                                   \
      }
    
    #define MAKE_NV_CS(NAME, VALUE)                                                \
      {                                                                            \
        (uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE),        \
            NGHTTP2_NV_FLAG_NONE                                                   \
      }
    
    
    static int verbose;
    static const char *cmd;
    
    static void log_out(const char *level, const char *where, const char *msg)
    {
        struct timespec tp;
        struct tm tm;
        char timebuf[128];
    
        clock_gettime(CLOCK_REALTIME, &tp);
        localtime_r(&tp.tv_sec, &tm);
        strftime(timebuf, sizeof(timebuf)-1, "%H:%M:%S", &tm);
        fprintf(stderr, "[%s.%09lu][%s][%s] %s\n", timebuf, tp.tv_nsec, level, where, msg);
    }
    
    static void log_err(const char *where, const char *msg)
    {
        log_out("ERROR", where, msg);
    }
    
    static void log_info(const char *where, const char *msg)
    {
        if (verbose)
            log_out("INFO", where, msg);
    }
    
    static void log_debug(const char *where, const char *msg)
    {
        if (verbose > 1)
            log_out("DEBUG", where, msg);
    }
    
    #if defined(__GNUC__)
        __attribute__((format(printf, 2, 3)))
    #endif
    static void log_errf(const char *where, const char *msg, ...)
    {
        char buffer[8*1024];
        va_list ap;
    
        va_start(ap, msg);
        vsnprintf(buffer, sizeof(buffer), msg, ap);
        va_end(ap);
        log_err(where, buffer);
    }
    
    #if defined(__GNUC__)
        __attribute__((format(printf, 2, 3)))
    #endif
    static void log_infof(const char *where, const char *msg, ...)
    {
        if (verbose) {
            char buffer[8*1024];
            va_list ap;
    
            va_start(ap, msg);
            vsnprintf(buffer, sizeof(buffer), msg, ap);
            va_end(ap);
            log_info(where, buffer);
        }
    }
    
    #if defined(__GNUC__)
        __attribute__((format(printf, 2, 3)))
    #endif
    static void log_debugf(const char *where, const char *msg, ...)
    {
        if (verbose > 1) {
            char buffer[8*1024];
            va_list ap;
    
            va_start(ap, msg);
            vsnprintf(buffer, sizeof(buffer), msg, ap);
            va_end(ap);
            log_debug(where, buffer);
        }
    }
    
    static int parse_host_port(const char **phost, uint16_t *pport,
                               int *pipv6, size_t *pconsumed,
                               const char *s, size_t len, uint16_t def_port)
    {
        size_t i, offset=0;
        char *host = NULL;
        int port = 0;
        int rv = 1, ipv6 = 0;
    
        if (!len)
            goto leave;
        if (s[offset] == '[') {
            ipv6 = 1;
            for (i = offset++; i < len; ++i) {
                if (s[i] == ']')
                  break;
            }
            if (i >= len || i == offset)
                goto leave;
            host = strndup(s + offset, i - offset);
            offset = i + 1;
        }
        else {
            for (i = offset; i < len; ++i) {
                if (strchr(":/?#", s[i]))
                  break;
            }
            if (i == offset) {
                log_debugf("parse_uri", "empty host name in '%.*s", (int)len, s);
                goto leave;
            }
            host = strndup(s + offset, i - offset);
            offset = i;
        }
        if (offset < len && s[offset] == ':') {
            port = 0;
            ++offset;
            for (i = offset; i < len; ++i) {
                if (strchr("/?#", s[i]))
                    break;
                if (s[i] < '0' || s[i] > '9') {
                    log_debugf("parse_uri", "invalid port char '%c'", s[i]);
                    goto leave;
                }
                port *= 10;
                port += s[i] - '0';
                if (port > 65535) {
                    log_debugf("parse_uri", "invalid port number '%d'", port);
                    goto leave;
                }
            }
            offset = i;
        }
        rv = 0;
    
    leave:
        *phost = rv? NULL : host;
        *pport = rv? 0 : (port? (uint16_t)port : def_port);
        if (pipv6)
          *pipv6 = ipv6;
        if (pconsumed)
          *pconsumed = offset;
        return rv;
    }
    
    struct uri {
      const char *scheme;
      const char *host;
      const char *authority;
      const char *path;
      uint16_t port;
      int ipv6;
    };
    
    static int parse_uri(struct uri *uri, const char *s, size_t len)
    {
        char tmp[8192];
        size_t n, offset = 0;
        uint16_t def_port = 0;
        int rv = 1;
    
        /* NOT A REAL URI PARSER */
        memset(uri, 0, sizeof(*uri));
        if (len > 5 && !memcmp("ws://", s, 5)) {
            uri->scheme = "ws";
            def_port = 80;
            offset = 5;
        }
        else if (len > 6 && !memcmp("wss://", s, 6)) {
            uri->scheme = "wss";
            def_port = 443;
            offset = 6;
        }
        else {
            /* not a scheme we process */
            goto leave;
        }
    
        if (parse_host_port(&uri->host, &uri->port, &uri->ipv6, &n, s + offset,
                            len - offset, def_port))
            goto leave;
        offset += n;
    
        if (uri->port == def_port)
          uri->authority = uri->host;
        else if (uri->ipv6) {
          snprintf(tmp, sizeof(tmp), "[%s]:%u", uri->host, uri->port);
          uri->authority = strdup(tmp);
        }
        else {
          snprintf(tmp, sizeof(tmp), "%s:%u", uri->host, uri->port);
          uri->authority = strdup(tmp);
        }
    
        if (offset < len) {
            uri->path = strndup(s + offset, len - offset);
        }
        rv = 0;
    
    leave:
        return rv;
    }
    
    static int sock_nonblock_nodelay(int fd) {
      int flags, rv;
      int val = 1;
    
      while ((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR)
          ;
      if (flags == -1) {
          log_errf("sock_nonblock_nodelay", "fcntl get error %d (%s)",
                   errno, strerror(errno));
          return -1;
      }
      while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR)
        ;
      if (rv == -1) {
          log_errf("sock_nonblock_nodelay", "fcntl set error %d (%s)",
                   errno, strerror(errno));
          return -1;
      }
      rv = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, (socklen_t)sizeof(val));
      if (rv == -1) {
          log_errf("sock_nonblock_nodelay", "set nodelay error %d (%s)",
                   errno, strerror(errno));
          return -1;
      }
      return 0;
    }
    
    static int open_connection(const char *host, uint16_t port)
    {
        char service[NI_MAXSERV];
        struct addrinfo hints;
        struct addrinfo *res = NULL, *rp;
        int rv, fd = -1;
    
        memset(&hints, 0, sizeof(hints));
        snprintf(service, sizeof(service), "%u", port);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        rv = getaddrinfo(host, service, &hints, &res);
        if (rv) {
          log_err("getaddrinfo", gai_strerror(rv));
          goto leave;
        }
    
        for (rp = res; rp; rp = rp->ai_next) {
          fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
          if (fd == -1) {
            continue;
          }
          while ((rv = connect(fd, rp->ai_addr, rp->ai_addrlen)) == -1 &&
                 errno == EINTR)
            ;
          if (!rv) /* connected */
              break;
          close(fd);
          fd = -1;
        }
    
    leave:
        if (res)
          freeaddrinfo(res);
        return fd;
    }
    
    struct h2_stream;
    
    #define IO_WANT_NONE   0
    #define IO_WANT_READ   1
    #define IO_WANT_WRITE  2
    
    struct h2_session {
        const char *server_name;
        const char *connect_host;
        uint16_t connect_port;
        int fd;
        nghttp2_session *ngh2;
        struct h2_stream *streams;
        int aborted;
        int want_io;
    };
    
    typedef void h2_stream_closed_cb(struct h2_stream *stream);
    typedef void h2_stream_recv_data(struct h2_stream *stream,
                                     const uint8_t *data, size_t len);
    
    struct h2_stream {
        struct h2_stream *next;
        struct uri *uri;
        int32_t id;
        int fdin;
        int http_status;
        uint32_t error_code;
        unsigned input_closed : 1;
        unsigned closed : 1;
        unsigned reset : 1;
        h2_stream_closed_cb *on_close;
        h2_stream_recv_data *on_recv_data;
    };
    
    static void h2_session_stream_add(struct h2_session *session,
                                      struct h2_stream *stream)
    {
        struct h2_stream *s;
        for (s = session->streams; s; s = s->next) {
            if (s == stream)  /* already there? */
                return;
        }
        stream->next = session->streams;
        session->streams = stream;
    }
    
    static void h2_session_stream_remove(struct h2_session *session,
                                         struct h2_stream *stream)
    {
        struct h2_stream *s, **pnext;
        pnext = &session->streams;
        s = session->streams;
        while (s) {
            if (s == stream) {
                *pnext = s->next;
                s->next = NULL;
                break;
            }
            pnext = &s->next;
            s = s->next;
        }
    }
    
    static struct h2_stream *h2_session_stream_get(struct h2_session *session,
                                                   int32_t id)
    {
        struct h2_stream *s;
        for (s = session->streams; s; s = s->next) {
            if (s->id == id)
                return s;
        }
        return NULL;
    }
    
    static ssize_t h2_session_send(nghttp2_session *ngh2, const uint8_t *data,
                                   size_t length, int flags, void *user_data)
    {
        struct h2_session *session = user_data;
        ssize_t nwritten;
        (void)ngh2;
        (void)flags;
    
        session->want_io = IO_WANT_NONE;
        nwritten = send(session->fd, data, length, 0);
        if (nwritten < 0) {
          int err = errno;
          if ((EWOULDBLOCK == err) || (EAGAIN == err) ||
              (EINTR == err) || (EINPROGRESS == err)) {
              return NGHTTP2_ERR_WOULDBLOCK;
          }
          log_errf("h2_session_send", "error sending %ld bytes: %d (%s)",
                   (long)length, err, strerror(err));
          return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        return nwritten;
    }
    
    static ssize_t h2_session_recv(nghttp2_session *ngh2, uint8_t *buf,
                                   size_t length, int flags, void *user_data)
    {
        struct h2_session *session = user_data;
        ssize_t nread;
        (void)ngh2;
        (void)flags;
    
        session->want_io = IO_WANT_NONE;
        nread = recv(session->fd, buf, length, 0);
        if (nread < 0) {
          int err = errno;
          if ((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)) {
              return NGHTTP2_ERR_WOULDBLOCK;
          }
          log_errf("h2_session_recv", "error reading %ld bytes: %d (%s)",
                   (long)length, err, strerror(err));
          return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        return nread;
    }
    
    static int h2_session_on_frame_send(nghttp2_session *session,
                                        const nghttp2_frame *frame,
                                        void *user_data)
    {
        size_t i;
        (void)user_data;
    
        switch (frame->hd.type) {
        case NGHTTP2_HEADERS:
          if (nghttp2_session_get_stream_user_data(session, frame->hd.stream_id)) {
            const nghttp2_nv *nva = frame->headers.nva;
            log_infof("frame send", "FRAME[HEADERS, stream=%d",
                      frame->hd.stream_id);
            for (i = 0; i < frame->headers.nvlen; ++i) {
                log_infof("frame send", "  %.*s: %.*s",
                          (int)nva[i].namelen, nva[i].name,
                          (int)nva[i].valuelen, nva[i].value);
            }
            log_infof("frame send", "]");
          }
          break;
        case NGHTTP2_DATA:
            log_infof("frame send", "FRAME[DATA, stream=%d, length=%d, flags=%d]",
                      frame->hd.stream_id, (int)frame->hd.length,
                      (int)frame->hd.flags);
            break;
        case NGHTTP2_RST_STREAM:
            log_infof("frame send", "FRAME[RST, stream=%d]",
                      frame->hd.stream_id);
            break;
        case NGHTTP2_WINDOW_UPDATE:
            log_infof("frame send", "FRAME[WINDOW_UPDATE, stream=%d]",
                      frame->hd.stream_id);
            break;
        case NGHTTP2_GOAWAY:
            log_infof("frame send", "FRAME[GOAWAY]");
            break;
        }
        return 0;
    }
    
    static int h2_session_on_frame_recv(nghttp2_session *ngh2,
                                        const nghttp2_frame *frame,
                                        void *user_data)
    {
        (void)user_data;
    
        switch (frame->hd.type) {
        case NGHTTP2_HEADERS:
            if (frame->headers.cat == NGHTTP2_HCAT_RESPONSE) {
              log_infof("frame recv", "FRAME[HEADERS, stream=%d]",
                        frame->hd.stream_id);
            }
            break;
        case NGHTTP2_DATA:
            log_infof("frame recv", "FRAME[DATA, stream=%d, len=%lu, eof=%d]",
                      frame->hd.stream_id, frame->hd.length,
                      (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) != 0);
            break;
        case NGHTTP2_RST_STREAM:
            log_infof("frame recv", "FRAME[RST, stream=%d]",
                      frame->hd.stream_id);
            fprintf(stdout, "[%d] RST\n", frame->hd.stream_id);
            break;
        case NGHTTP2_GOAWAY:
            log_infof("frame recv", "FRAME[GOAWAY]");
            break;
        }
        return 0;
    }
    
    static int h2_session_on_header(nghttp2_session *ngh2,
                                    const nghttp2_frame *frame,
                                    const uint8_t *name, size_t namelen,
                                    const uint8_t *value, size_t valuelen,
                                    uint8_t flags, void *user_data)
    {
        struct h2_session *session = user_data;
        struct h2_stream *stream;
        (void)flags;
        (void)user_data;
        log_infof("frame recv", "stream=%d, HEADER   %.*s: %.*s",
                  frame->hd.stream_id, (int)namelen, name,
                  (int)valuelen, value);
        stream = h2_session_stream_get(session, frame->hd.stream_id);
        if (stream) {
            if (namelen == 7 && !strncmp(":status", (const char *)name, namelen)) {
                stream->http_status = 0;
                if (valuelen < 10) {
                    char tmp[10], *endp;
                    memcpy(tmp, value, valuelen);
                    tmp[valuelen] = 0;
                    stream->http_status = (int)strtol(tmp, &endp, 10);
                }
                if (stream->http_status < 100 || stream->http_status >= 600) {
                    log_errf("on header recv", "stream=%d, invalid :status: %.*s",
                              frame->hd.stream_id, (int)valuelen, value);
                    return NGHTTP2_ERR_CALLBACK_FAILURE;
                }
                else {
                    fprintf(stdout, "[%d] :status: %d\n", stream->id,
                            stream->http_status);
                }
            }
        }
        return 0;
    }
    
    static int h2_session_on_stream_close(nghttp2_session *ngh2, int32_t stream_id,
                                          uint32_t error_code, void *user_data)
    {
        struct h2_session *session = user_data;
        struct h2_stream *stream;
    
        stream = h2_session_stream_get(session, stream_id);
        if (stream) {
            /* closed known stream */
            stream->error_code = error_code;
            stream->closed = 1;
            if (error_code)
                stream->reset = 1;
            if (error_code) {
                log_errf("stream close", "stream %d closed with error %d",
                         stream_id, error_code);
            }
    
            h2_session_stream_remove(session, stream);
            if (stream->on_close)
                stream->on_close(stream);
            /* last one? */
            if (!session->streams) {
                int rv;
                rv = nghttp2_session_terminate_session(ngh2, NGHTTP2_NO_ERROR);
                if (rv) {
                    log_errf("terminate session", "error %d (%s)",
                             rv, nghttp2_strerror(rv));
                    session->aborted = 1;
                }
            }
        }
        return 0;
    }
    
    static int h2_session_on_data_chunk_recv(nghttp2_session *ngh2, uint8_t flags,
                                             int32_t stream_id, const uint8_t *data,
                                             size_t len, void *user_data) {
        struct h2_session *session = user_data;
        struct h2_stream *stream;
    
        stream = h2_session_stream_get(session, stream_id);
        if (stream && stream->on_recv_data) {
            stream->on_recv_data(stream, data, len);
        }
        return 0;
    }
    
    static int h2_session_open(struct h2_session *session, const char *server_name,
                               const char *host, uint16_t port)
    {
        nghttp2_session_callbacks *cbs = NULL;
        nghttp2_settings_entry settings[2];
        int rv = -1;
    
        memset(session, 0, sizeof(*session));
        session->server_name = server_name;
        session->connect_host = host;
        session->connect_port = port;
        /* establish socket */
        session->fd = open_connection(session->connect_host, session->connect_port);
        if (session->fd < 0) {
          log_errf(cmd, "could not connect to %s:%u",
                   session->connect_host, session->connect_port);
          goto leave;
        }
        if (sock_nonblock_nodelay(session->fd))
            goto leave;
        session->want_io = IO_WANT_NONE;
    
        log_infof(cmd, "connected to %s via %s:%u", session->server_name,
                  session->connect_host, session->connect_port);
    
        rv = nghttp2_session_callbacks_new(&cbs);
        if (rv) {
            log_errf("setup callbacks", "error_code=%d, msg=%s\n", rv,
                     nghttp2_strerror(rv));
            rv = -1;
            goto leave;
        }
        /* setup session callbacks */
        nghttp2_session_callbacks_set_send_callback(cbs, h2_session_send);
        nghttp2_session_callbacks_set_recv_callback(cbs, h2_session_recv);
        nghttp2_session_callbacks_set_on_frame_send_callback(
            cbs, h2_session_on_frame_send);
        nghttp2_session_callbacks_set_on_frame_recv_callback(
            cbs, h2_session_on_frame_recv);
        nghttp2_session_callbacks_set_on_header_callback(
            cbs, h2_session_on_header);
        nghttp2_session_callbacks_set_on_stream_close_callback(
            cbs, h2_session_on_stream_close);
        nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
            cbs, h2_session_on_data_chunk_recv);
        /* create the ngh2 session */
        rv = nghttp2_session_client_new(&session->ngh2, cbs, session);
        if (rv) {
            log_errf("client new", "error_code=%d, msg=%s\n", rv,
                     nghttp2_strerror(rv));
            rv = -1;
            goto leave;
        }
        /* submit initial settings */
        settings[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
        settings[0].value = 100;
        settings[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
        settings[1].value = 10 * 1024 * 1024;
    
        rv = nghttp2_submit_settings(session->ngh2, NGHTTP2_FLAG_NONE, settings, 2);
        if (rv) {
            log_errf("submit settings", "error_code=%d, msg=%s\n", rv,
                     nghttp2_strerror(rv));
            rv = -1;
            goto leave;
        }
        rv = nghttp2_session_set_local_window_size(session->ngh2, NGHTTP2_FLAG_NONE,
                                                   0, 10 * 1024 * 1024);
        if (rv) {
            log_errf("set connection window size", "error_code=%d, msg=%s\n", rv,
                     nghttp2_strerror(rv));
            rv = -1;
            goto leave;
        }
        rv = 0;
    
    leave:
        if (cbs)
            nghttp2_session_callbacks_del(cbs);
        return rv;
    }
    
    static int h2_session_io(struct h2_session *session) {
        int rv;
        rv = nghttp2_session_recv(session->ngh2);
        if (rv) {
            log_errf("session recv", "error_code=%d, msg=%s\n", rv,
                     nghttp2_strerror(rv));
            return 1;
        }
        rv = nghttp2_session_send(session->ngh2);
        if (rv) {
            log_errf("session send", "error_code=%d, msg=%s\n", rv,
                     nghttp2_strerror(rv));
        }
        return 0;
    }
    
    struct h2_poll_ctx;
    typedef int h2_poll_ev_cb(struct h2_poll_ctx *pctx, struct pollfd *pfd);
    
    struct h2_poll_ctx {
        struct h2_session *session;
        struct h2_stream *stream;
        h2_poll_ev_cb *on_ev;
    };
    
    static int h2_session_ev(struct h2_poll_ctx *pctx, struct pollfd *pfd)
    {
        if (pfd->revents & (POLLIN | POLLOUT)) {
            h2_session_io(pctx->session);
        }
        else if (pfd->revents & POLLHUP) {
            log_errf("session run", "connection closed");
            return -1;
        }
        else if (pfd->revents & POLLERR) {
            log_errf("session run", "connection error");
            return -1;
        }
        return 0;
    }
    
    static int h2_stream_ev(struct h2_poll_ctx *pctx, struct pollfd *pfd)
    {
        if (pfd->revents & (POLLIN | POLLHUP)) {
            nghttp2_session_resume_data(pctx->session->ngh2, pctx->stream->id);
        }
        else if (pfd->revents & (POLLERR)) {
            nghttp2_submit_rst_stream(pctx->session->ngh2, NGHTTP2_FLAG_NONE,
                                      pctx->stream->id, NGHTTP2_STREAM_CLOSED);
        }
        return 0;
    }
    
    static nfds_t h2_session_set_poll(struct h2_session *session,
                                      struct h2_poll_ctx *pollctxs,
                                      struct pollfd *pfds)
    {
        nfds_t n = 0;
        int want_read, want_write;
        struct h2_stream *stream;
    
        want_read = (nghttp2_session_want_read(session->ngh2) ||
                     session->want_io == IO_WANT_READ);
        want_write = (nghttp2_session_want_write(session->ngh2) ||
                      session->want_io == IO_WANT_WRITE);
        if (want_read || want_write) {
            pollctxs[n].session = session;
            pollctxs[n].stream = NULL;
            pollctxs[n].on_ev = h2_session_ev;
            pfds[n].fd = session->fd;
            pfds[n].events = pfds[n].revents = 0;
            if (want_read)
                pfds[n].events |= (POLLIN | POLLHUP);
            if (want_write)
                pfds[n].events |= (POLLOUT | POLLERR);
            ++n;
        }
    
        for (stream = session->streams; stream; stream = stream->next) {
            if (stream->fdin >= 0 && !stream->input_closed && !stream->closed) {
                pollctxs[n].session = session;
                pollctxs[n].stream = stream;
                pollctxs[n].on_ev = h2_stream_ev;
                pfds[n].fd = stream->fdin;
                pfds[n].revents = 0;
                pfds[n].events = (POLLIN | POLLHUP);
                ++n;
            }
        }
        return n;
    }
    
    static void h2_session_run(struct h2_session *session)
    {
      struct h2_poll_ctx pollctxs[5];
      struct pollfd pfds[5];
      nfds_t npollfds, i;
    
      npollfds  = h2_session_set_poll(session, pollctxs, pfds);
      while (npollfds) {
        if (poll(pfds, npollfds, -1) == -1) {
            log_errf("session run", "poll error %d (%s)", errno, strerror(errno));
            break;
        }
        for (i = 0; i < npollfds; ++i) {
            if (pfds[i].revents) {
                if (pollctxs[i].on_ev(&pollctxs[i], &pfds[i])) {
                    break;
                }
            }
        }
        npollfds = h2_session_set_poll(session, pollctxs, pfds);
        if (!session->streams)
            break;
      }
    }
    
    static void h2_session_close(struct h2_session *session)
    {
        log_infof(cmd, "closed session to %s:%u",
                  session->connect_host, session->connect_port);
    }
    
    /* websocket stream */
    
    struct ws_stream {
      struct h2_stream s;
    };
    
    static void ws_stream_on_close(struct h2_stream *stream)
    {
        log_infof("ws stream", "stream %d closed", stream->id);
        if (!stream->reset)
            fprintf(stdout, "[%d] EOF\n", stream->id);
    }
    
    static void ws_stream_on_recv_data(struct h2_stream *stream,
                                const uint8_t *data, size_t len)
    {
        size_t i;
    
        log_infof("ws stream", "stream %d recv %lu data bytes",
                  stream->id, (unsigned long)len);
        for (i = 0; i < len; ++i) {
            fprintf(stdout, "%s%02x", (i&0xf)? " " : (i? "\n" : ""), data[i]);
        }
        fprintf(stdout, "\n");
    }
    
    static int ws_stream_create(struct ws_stream **pstream, struct uri *uri)
    {
        struct ws_stream *stream;
    
        stream = calloc(1, sizeof(*stream));
        if (!stream) {
            log_errf("ws stream create", "out of memory");
            *pstream = NULL;
            return -1;
        }
        stream->s.uri = uri;
        stream->s.id = -1;
        stream->s.on_close = ws_stream_on_close;
        stream->s.on_recv_data = ws_stream_on_recv_data;
        *pstream = stream;
        return 0;
    }
    
    static ssize_t ws_stream_read_req_body(nghttp2_session *ngh2,
                                           int32_t stream_id,
                                           uint8_t *buf, size_t buflen,
                                           uint32_t *pflags,
                                           nghttp2_data_source *source,
                                           void *user_data)
    {
        struct h2_session *session = user_data;
        struct ws_stream *stream;
        ssize_t nread = 0;
        int eof = 0;
    
        stream = (struct ws_stream *)h2_session_stream_get(session, stream_id);
        if (!stream) {
             log_errf("stream req body", "stream not known");
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
    
        (void)source;
        assert(stream->s.fdin >= 0);
        nread = read(stream->s.fdin, buf, buflen);
        log_debugf("stream req body", "fread(len=%lu) -> %ld",
                   (unsigned long)buflen, (long)nread);
    
        if (nread < 0) {
            if (errno == EAGAIN) {
                nread = 0;
            }
            else {
                log_errf("stream req body", "error on input");
                return NGHTTP2_ERR_CALLBACK_FAILURE;
            }
        }
        else if (nread == 0) {
          eof = 1;
          stream->s.input_closed = 1;
        }
    
        *pflags = stream->s.input_closed? NGHTTP2_DATA_FLAG_EOF : 0;
        if (nread == 0 && !eof) {
          return NGHTTP2_ERR_DEFERRED;
        }
        return nread;
    }
    
    static int ws_stream_submit(struct ws_stream *stream,
                                struct h2_session *session,
                                const nghttp2_nv *nva, size_t nvalen,
                                int fdin)
    {
        nghttp2_data_provider provider, *req_body = NULL;
    
        if (fdin >= 0) {
            sock_nonblock_nodelay(fdin);
            stream->s.fdin = fdin;
            provider.read_callback = ws_stream_read_req_body;
            provider.source.ptr = NULL;
            req_body = &provider;
        }
        else {
            stream->s.input_closed = 1;
        }
    
        stream->s.id = nghttp2_submit_request(session->ngh2, NULL, nva, nvalen,
                                              req_body, stream);
        if (stream->s.id < 0) {
            log_errf("ws stream submit", "nghttp2_submit_request: error %d",
                     stream->s.id);
            return -1;
        }
    
        h2_session_stream_add(session, &stream->s);
        log_infof("ws stream submit", "stream %d opened for %s%s",
                  stream->s.id, stream->s.uri->authority, stream->s.uri->path);
        return 0;
    }
    
    static void usage(const char *msg)
    {
        if(msg)
            fprintf(stderr, "%s\n", msg);
        fprintf(stderr,
            "usage: [options] ws-uri scenario\n"
            "  run a websocket scenario to the ws-uri, options:\n"
            "  -c host:port connect to host:port\n"
            "  -v         increase verbosity\n"
            "scenarios are:\n"
            "  * fail-proto: CONNECT using wrong :protocol\n"
            "  * miss-authority: CONNECT without :authority header\n"
            "  * miss-path: CONNECT without :path header\n"
            "  * miss-scheme: CONNECT without :scheme header\n"
            "  * miss-version: CONNECT without sec-webSocket-version header\n"
            "  * ws-empty: open valid websocket, do not send anything\n"
        );
    }
    
    int main(int argc, char *argv[])
    {
        const char *host = NULL, *scenario;
        uint16_t port = 80;
        struct uri uri;
        struct h2_session session;
        struct ws_stream *stream;
        char ch;
    
        cmd = argv[0];
        while((ch = getopt(argc, argv, "c:vh")) != -1) {
            switch(ch) {
            case 'c':
                if (parse_host_port(&host, &port, NULL, NULL,
                                    optarg, strlen(optarg), 80)) {
                    log_errf(cmd, "could not parse connect '%s'", optarg);
                    return 1;
                }
                break;
            case 'h':
                usage(NULL);
                return 2;
                break;
            case 'v':
                ++verbose;
                break;
            default:
               usage("invalid option");
               return 1;
            }
        }
        argc -= optind;
        argv += optind;
    
        if (argc < 1) {
            usage("need URL");
            return 1;
        }
        if (argc < 2) {
            usage("need scenario");
            return 1;
        }
        if (parse_uri(&uri, argv[0], strlen(argv[0]))) {
            log_errf(cmd, "could not parse uri '%s'", argv[0]);
            return 1;
        }
        log_debugf(cmd, "normalized uri: %s://%s:%u%s", uri.scheme, uri.host,
                   uri.port, uri.path? uri.path : "");
        scenario = argv[1];
    
        if (!host) {
            host = uri.host;
            port = uri.port;
        }
    
        if (h2_session_open(&session, uri.host, host, port))
            return 1;
    
        if (ws_stream_create(&stream, &uri))
            return 1;
    
        if (!strcmp(scenario, "ws-stdin")) {
            const nghttp2_nv nva[] = {
                MAKE_NV(":method", "CONNECT"),
                MAKE_NV_CS(":path", stream->s.uri->path),
                MAKE_NV_CS(":scheme", "http"),
                MAKE_NV_CS(":authority", stream->s.uri->authority),
                MAKE_NV_CS(":protocol", "websocket"),
                MAKE_NV("accept", "*/*"),
                MAKE_NV("user-agent", "mod_h2/h2ws-test"),
                MAKE_NV("sec-webSocket-version", "13"),
                MAKE_NV("sec-webSocket-protocol", "chat"),
            };
            if (ws_stream_submit(stream, &session,
                                 nva, sizeof(nva) / sizeof(nva[0]), 0))
                return 1;
        }
        else if (!strcmp(scenario, "fail-proto")) {
            const nghttp2_nv nva[] = {
                MAKE_NV(":method", "CONNECT"),
                MAKE_NV_CS(":path", stream->s.uri->path),
                MAKE_NV_CS(":scheme", "http"),
                MAKE_NV_CS(":authority", stream->s.uri->authority),
                MAKE_NV_CS(":protocol", "websockets"),
                MAKE_NV("accept", "*/*"),
                MAKE_NV("user-agent", "mod_h2/h2ws-test"),
                MAKE_NV("sec-webSocket-version", "13"),
                MAKE_NV("sec-webSocket-protocol", "chat"),
            };
            if (ws_stream_submit(stream, &session,
                                 nva, sizeof(nva) / sizeof(nva[0]), -1))
                return 1;
        }
        else if (!strcmp(scenario, "miss-version")) {
            const nghttp2_nv nva[] = {
                MAKE_NV(":method", "CONNECT"),
                MAKE_NV_CS(":path", stream->s.uri->path),
                MAKE_NV_CS(":scheme", "http"),
                MAKE_NV_CS(":authority", stream->s.uri->authority),
                MAKE_NV_CS(":protocol", "websocket"),
                MAKE_NV("accept", "*/*"),
                MAKE_NV("user-agent", "mod_h2/h2ws-test"),
                MAKE_NV("sec-webSocket-protocol", "chat"),
            };
            if (ws_stream_submit(stream, &session,
                                 nva, sizeof(nva) / sizeof(nva[0]), -1))
                return 1;
        }
        else if (!strcmp(scenario, "miss-path")) {
            const nghttp2_nv nva[] = {
                MAKE_NV(":method", "CONNECT"),
                MAKE_NV_CS(":scheme", "http"),
                MAKE_NV_CS(":authority", stream->s.uri->authority),
                MAKE_NV_CS(":protocol", "websocket"),
                MAKE_NV("accept", "*/*"),
                MAKE_NV("user-agent", "mod_h2/h2ws-test"),
                MAKE_NV("sec-webSocket-version", "13"),
                MAKE_NV("sec-webSocket-protocol", "chat"),
            };
            if (ws_stream_submit(stream, &session,
                                 nva, sizeof(nva) / sizeof(nva[0]), -1))
                return 1;
        }
        else if (!strcmp(scenario, "miss-scheme")) {
            const nghttp2_nv nva[] = {
                MAKE_NV(":method", "CONNECT"),
                MAKE_NV_CS(":path", stream->s.uri->path),
                MAKE_NV_CS(":authority", stream->s.uri->authority),
                MAKE_NV_CS(":protocol", "websocket"),
                MAKE_NV("accept", "*/*"),
                MAKE_NV("user-agent", "mod_h2/h2ws-test"),
                MAKE_NV("sec-webSocket-version", "13"),
                MAKE_NV("sec-webSocket-protocol", "chat"),
            };
            if (ws_stream_submit(stream, &session,
                                 nva, sizeof(nva) / sizeof(nva[0]), -1))
                return 1;
        }
        else if (!strcmp(scenario, "miss-authority")) {
            const nghttp2_nv nva[] = {
                MAKE_NV(":method", "CONNECT"),
                MAKE_NV_CS(":path", stream->s.uri->path),
                MAKE_NV_CS(":scheme", "http"),
                MAKE_NV_CS(":protocol", "websocket"),
                MAKE_NV("accept", "*/*"),
                MAKE_NV("user-agent", "mod_h2/h2ws-test"),
                MAKE_NV("sec-webSocket-version", "13"),
                MAKE_NV("sec-webSocket-protocol", "chat"),
            };
            if (ws_stream_submit(stream, &session,
                                 nva, sizeof(nva) / sizeof(nva[0]), -1))
                return 1;
        }
        else {
            log_errf(cmd, "unknown scenario: %s", scenario);
            return 1;
        }
    
        h2_session_run(&session);
        h2_session_close(&session);
        return 0;
    }
    �������������������������������������������������������������httpd-2.4.64/test/clients/Makefile.in���������������������������������������������������������������0000664�0001751�0001751�00000001152�14473316336�017320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������DISTCLEAN_TARGETS = h2ws
    
    CLEAN_TARGETS = h2ws
    
    bin_PROGRAMS = h2ws
    TARGETS  = $(bin_PROGRAMS)
    
    PROGRAM_LDADD        = $(UTIL_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) $(AP_LIBS)
    PROGRAM_DEPENDENCIES =
    
    include $(top_builddir)/build/rules.mk
    
    h2ws.lo: h2ws.c
    	$(LIBTOOL) --mode=compile $(CC) $(ab_CFLAGS) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
    	    $(ALL_INCLUDES) $(PICFLAGS) $(LTCFLAGS) -c $< && touch $@
    h2ws_OBJECTS = h2ws.lo
    h2ws_LDADD = -lnghttp2
    h2ws: $(h2ws_OBJECTS)
    	$(LIBTOOL) --mode=link $(CC) $(ALL_CFLAGS) $(PILDFLAGS) \
    	    $(LT_LDFLAGS) $(ALL_LDFLAGS) -o $@ $(h2ws_LTFLAGS) $(h2ws_OBJECTS) $(h2ws_LDADD)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/travis_before_linux.sh������������������������������������������������������������0000775�0001751�0001751�00000013675�14775514025�020237� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash -xe
    
    if test -v CLEAR_CACHE; then
        rm -rf $HOME/root
    fi
    
    : Travis tag = ${TRAVIS_TAG}
    : Travis branch = ${TRAVIS_BRANCH}
    
    : /etc/hosts --
    cat /etc/hosts
    : -- ends
    
    # ### FIXME: This is a workaround, non-x86 builds have an IPv6
    # configuration which somehow breaks the test suite runs.  Appears
    # that Apache::Test only configures the server to Listen on 0.0.0.0
    # (that is hard-coded), but then Apache::TestSerer::wait_till_is_up()
    # tries to connect via ::1, which fails/times out.
    if grep ip6-localhost /etc/hosts; then
        sudo sed -i "/ip6-/d" /etc/hosts
        cat /etc/hosts
    fi
    
    function install_apx() {
        local name=$1
        local version=$2
        local prefix=${HOME}/root/${name}-${version}
        local build=${HOME}/build/${name}-${version}
        local giturl=https://github.com/apache/${name}.git
        local config=$3
        local buildconf=$4
    
        case $version in
        trunk|*.x) ref=refs/heads/${version} ;;
        *) ref=refs/tags/${version} ;;
        esac
    
        # Fetch the object ID (hash) of latest commit
        local commit=`git ls-remote ${giturl} ${ref} | cut -f1`
        if test -z "$commit"; then
            : Could not determine latest commit hash for ${ref} in ${giturl} - check branch is valid?
            exit 1
        fi
    
        # Blow away the cached install root if the cached install is stale
        # or doesn't match the expected configuration.
        grep -q "${version} ${commit} ${config} CC=$CC" ${HOME}/root/.key-${name} || rm -rf ${prefix}
    
        if test -d ${prefix}; then
            return 0
        fi
    
        git init -q ${build}
        pushd $build
             # Clone and checkout the commit identified above.
             git remote add origin ${giturl}
             git fetch -q --depth=1 origin ${commit}
             git checkout ${commit}
             ./buildconf ${buildconf}
             ./configure --prefix=${prefix} ${config}
             make -j2
             make install
        popd
    
        echo ${version} ${commit} "${config}" "CC=${CC}" > ${HOME}/root/.key-${name}
    }
    
    # Allow to load $HOME/build/apache/httpd/.gdbinit
    echo "add-auto-load-safe-path $HOME/work/httpd/httpd/.gdbinit" >> $HOME/.gdbinit
    
    # Unless either SKIP_TESTING or NO_TEST_FRAMEWORK are set, install
    # CPAN modules required to run the Perl test framework.
    if ! test -v SKIP_TESTING -o -v NO_TEST_FRAMEWORK; then
        # Clear CPAN cache if necessary
        if [ -v CLEAR_CACHE ]; then rm -rf ~/perl5; fi
    
        if ! perl -V > perlver; then
            : Perl binary broken
            perl -V
            exit 1
        fi
    
        # Compare the current "perl -V" output with the output at the time
        # the cache was built; flush the cache if it's changed to avoid
        # failure later when /usr/bin/perl refuses to load a mismatched XS
        # module.
        if ! cmp -s perlver ~/perl5/.perlver; then
            : Purging cache since "perl -V" output has changed
            rm -rf ~/perl5
        fi
        
        cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
    
        pkgs="Net::SSL LWP::Protocol::https                                 \
               LWP::Protocol::AnyEvent::http ExtUtils::Embed Test::More     \
               AnyEvent DateTime HTTP::DAV FCGI                             \
               AnyEvent::WebSocket::Client Apache::Test"
    
        # CPAN modules are to be used with the system Perl and always with
        # CC=gcc, e.g. for the CC="gcc -m32" case the builds are not correct
        # otherwise.
        CC=gcc cpanm --notest $pkgs
        unset pkgs
    
        # Cache the perl -V output for future verification.
        mv perlver ~/perl5/.perlver
    
        # Make a shallow clone of httpd-tests git repo.
        git clone -q --depth=1 https://github.com/apache/httpd-tests.git test/perl-framework
    fi
    
    # For LDAP testing, run slapd listening on port 8389 and populate the
    # directory as described in t/modules/ldap.t in the test framework:
    if test -v TEST_LDAP -a -x test/perl-framework/scripts/ldap-init.sh; then
        docker build -t httpd_ldap -f test/travis_Dockerfile_slapd.centos test/
        pushd test/perl-framework
           ./scripts/ldap-init.sh
        popd
    fi
    
    if test -v TEST_SSL; then
        pushd test/perl-framework
           ./scripts/memcached-init.sh
           ./scripts/redis-init.sh
        popd
    fi
    
    if test -v TEST_OPENSSL3; then
        # Build the requested version of OpenSSL if it's not already
        # installed in the cached ~/root
        if ! test -f $HOME/root/openssl-is-${TEST_OPENSSL3}; then
            # Remove any previous install.
            rm -rf $HOME/root/openssl3
    
            mkdir -p build/openssl
            pushd build/openssl
               curl "https://www.openssl.org/source/openssl-${TEST_OPENSSL3}.tar.gz" |
                  tar -xzf -
               cd openssl-${TEST_OPENSSL3}
               ./Configure --prefix=$HOME/root/openssl3 shared no-tests
               make $MFLAGS
               make install_sw
               touch $HOME/root/openssl-is-${TEST_OPENSSL3}
           popd
        fi
    
        # Point APR/APR-util at the installed version of OpenSSL.
        if test -v APU_VERSION; then
            APU_CONFIG="${APU_CONFIG} --with-openssl=$HOME/root/openssl3"
        elif test -v APR_VERSION; then
            APR_CONFIG="${APR_CONFIG} --with-openssl=$HOME/root/openssl3"
        else
            : Non-system APR/APR-util must be used to build with OpenSSL 3 to avoid mismatch with system libraries
            exit 1
        fi
    fi
    
    if test -v APR_VERSION; then
        install_apx apr ${APR_VERSION} "${APR_CONFIG}"
        ldd $HOME/root/apr-${APR_VERSION}/lib/libapr-?.so || true
        APU_CONFIG="$APU_CONFIG --with-apr=$HOME/root/apr-${APR_VERSION}"
    fi
    
    if test -v APU_VERSION; then
        install_apx apr-util ${APU_VERSION} "${APU_CONFIG}" --with-apr=$HOME/build/apr-${APR_VERSION}
        ldd $HOME/root/apr-util-${APU_VERSION}/lib/libaprutil-?.so || true
    fi
    
    # Since librustls is not a package (yet) on any platform, we
    # build the version we want from source
    if test -v TEST_MOD_TLS -a -v RUSTLS_VERSION; then
        if ! test -d $HOME/root/rustls; then
            RUSTLS_HOME="$HOME/build/rustls-ffi"
            git clone -q --depth=1 -b "$RUSTLS_VERSION" https://github.com/rustls/rustls-ffi.git "$RUSTLS_HOME"
            pushd "$RUSTLS_HOME"
                make install DESTDIR="$HOME/root/rustls"
            popd
        fi
    fi
    �������������������������������������������������������������������httpd-2.4.64/test/travis_Dockerfile_slapd.centos����������������������������������������������������0000664�0001751�0001751�00000000436�14747160155�021655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������FROM quay.io/centos/centos:stream9
    RUN rpm -q openldap-servers || (dnf install --refresh -y epel-release && \
        dnf install --nobest -y openldap-clients openldap-servers openldap-devel && \
        dnf -y clean all --enablerepo='*')
    CMD /usr/sbin/slapd -u ldap -d1 '-h ldap:// ldapi:///'
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/README.ci�������������������������������������������������������������������������0000664�0001751�0001751�00000013516�14400071506�015056� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    Variables
    ---------
    
    The CI scripts use the following environment variables:
    
    * APR_VERSION - if set, APR of this version is built and installed in
      $HOME/root/apr-$APR_VERSION - a value of "trunk" means trunk is
      used, "*.x" means a branch, otherwise a tagged version is implied.
    
    * APR_CONFIG - arguments to pass when running APR's configure script
      if APR_VERSION is set
    
    * APU_VERSION - if set, APR-util of this version is built and
      installed in $HOME/root/apr-util-$APU_VERSION - a value of "*.x"
      means a branch, otherwise a tagged version is implied.  (Since there
      is no "trunk" for apr-util, that value cannot be used here.)
    
    * APU_CONFIG - arguments to pass when running APR-util's configure
      script if APU_VERSION is set
    
    * CONFIG - arguments to pass to httpd's configure script.
    
    * BUILDCONFIG - arguments to pass when running httpd's ./buildconf script
    
    * MFLAGS - arguments to pass when running "make" for httpd.
    
    * SKIP_TESTING - if set, the Perl test framework is not run for the
      build.
    
    * TEST_UBSAN - set for job using UBSan ("Undefined Behaviour Sanitizer")
    
    * TEST_MALLOC - set for job using enhanced malloc debugging.
    
    * TEST_INSTALL - set for job testing "make install"
    
    * TEST_VPATH - set for job testing srcdir!=builddir 
    
    * TEST_LDAP - set for job with slapd, running LDAP tests
    
    * TEST_SSL - set for job with SSL/TLS testing variants
    
    * TESTS - a list of Perl framework tests to run
    
    * TEST_ARGS - arguments to pass to ./t/TEST in the Perl test framework
    
    * CLEAR_CACHE - if set, the cached $HOME/root is removed before each build
    
    Caching -- NOTE, BROKEN IN GITHUB ACTIONS --
    -------
    
    Perl modules installed in $HOME/perl5 are cached.
    
    Anything installed into the $HOME/root directory is cached - notably,
    versions of APR/APR-util are installed here and cached across httpd
    build jobs without needing to be rebuilt every time.
    
    The cached installs of APR/APR-util are refreshed if the
    last-changed-revision of the build is stale.
    
    If APR_VERSION and APU_VERSION are both set to 1.x versions, then
    CLEAR_CACHE should also be set to disable APR* caching.  APR-util can
    only be rebuilt if an APR checkout is present, so a APR-util cannot be
    built from source alone.  (i.e. the scripts do not handle the case of
    cached, fresh APR plus a cached but stale APR-util)
    
    Travis to Github Actions Migration TODO
    ---------------------------------------
    
    * better path filtering so e.g. CHANGES changes don't trigger CI
    * support branch conditionals again (some tests are 2.4.x only, some trunk only)
    * make caching work properly for APR + CPAN modules
      - this is using the wrong model at the moment
      - the cache key needs to be based off (source code, job configuration)
      - rather than done on the fly in test/travis_before_linux.sh
      - pebble + Rustls builds should also be cached
    * turn on failure notifications?
    * test across different Ubuntu versions again
     - and test against OpenSSL 1.x since we're now ONLY building against 3.x
    * update the docs below for testing from PRs/feature branches
    * introduce some job ordering rather than having a flat/concurrent
      set, if the default "./configure && make && test" works *then* start
      jobs doing 200 different variations on ./configure --enable-XXX 
      i.e. stop burning CPU time for a typo which breaks every job
    
    TODO list
    ---------
    
    * non-x86 builds
    * MacOS build
    * Windows build
    * clang-on-Linux build
    * Use containers for non-Ubuntu-based Linux testing
    
    Known Failures
    --------------
    
    Some known failures:
    
    * prefork, and more rarely non-prefork testing sometimes catches child
      segfaults under pool-debug from assert()s in (e.g.)
      __pthread_tpp_change_priority where one child is destroying threads
      which another is waiting for, or iterating through via
      apr_pool_walk_tree().
    
      See dev@httpd threads:
      msg <5f4abde1b5789_13fde2ecacb40795a1@travis-tasks-5b566d48fc-drkb9.mail>
      msg <73060f7b-df7f-ad3c-a9fa-dd666a59b31e@kippdata.de> and
      https://bz.apache.org/bugzilla/show_bug.cgi?id=63098
      https://bz.apache.org/bugzilla/show_bug.cgi?id=46185
    
      Not clear if there is a real bug here which can be reproduced
      outside of pool-debug.
    
    Testing from a Feature Branch [*** N/A FOR GITHUB ACTIONS ***]
    -----------------------------
    
    An SVN branch off trunk should be mirrored to github, and will be
    tested in the same way that trunk is in CI, so this workflow is
    available for those familiar with using Subversion and the standard
    ASF/httpd repository layout.
    
    Tested branches are listed at: https://travis-ci.com/github/apache/httpd/branches
    
    Travis will also run the tests for a PR filed against the httpd Github
    repository at https://github.com/apache/httpd or from a fork of this
    repository if enabled for the Travis user.
    
    A workflow to enable testing would be as follows, substituting
    $USERNAME for your github username:
    
      $ git clone https://github.com/apache/httpd
      $ cd httpd
      $ git remote add $USERNAME git@github.com:$USERNAME/httpd.git
      $ git checkout -b my-feature origin/trunk
      ... do some work ...
      $ git commit ...
      $ git push -u $USERNAME my-feature:my-feature
    
    To enable testing for a fork, visit the settings page at
    https://travis-ci.com/$USERNAME/httpd/settings - you may need to sync
    your account via https://travis-ci.com/account/repositories for a
    freshly created fork.
    
    To create a Pull Request, go to the URL produced in the "git push"
    command output when pushing to your fork, which is something like:
    https://github.com/apache/httpd/compare/trunk...$USERNAME:trunk
    
    Once a PR has been created, travis will run the tests and link the
    results from a PR comment. All tested PRs are listed here:
    https://travis-ci.com/github/apache/httpd/pull_requests
    
    To merge from github back to SVN trunk, create a patch from e.g.:
    
      $ git diff origin/trunk..my-feature
    
    and then apply it in SVN.  To rebase a feature once trunk has
    diverged, from a feature branch run:
    
      $ git pull
      $ git rebase -i origin/trunk
    
    and follow the standard rebase steps.
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/Makefile.in�����������������������������������������������������������������������0000664�0001751�0001751�00000001071�14156077574�015665� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    # no targets: we don't want to build anything by default. if you want the
    # test programs, then "make test"
    TARGETS =
    
    bin_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: $(bin_PROGRAMS)
    
    # example for building a test proggie
    # dbu_OBJECTS = dbu.lo
    # dbu: $(dbu_OBJECTS)
    #	$(LINK) $(dbu_OBJECTS) $(PROGRAM_LDADD)
    
    clean:
    	rm -rf gen
    
    distclean:
    	rm -f pyhttpd/config.ini�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/README.pytest���������������������������������������������������������������������0000664�0001751�0001751�00000011652�14411771130�016014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Apache httpd pytest suite
    =========================
    Using pytest (<https://docs.pytest.org/en/6.2.x/>) and a Python >= 3.8
    for a more flexible testing of Apache httpd.
    
    Install
    -------
    If not already installed, you will need to install 'pytest' and 'OpenSSL' for
    python:
    > apt install python3-pip
    > pip install -U pytest
    > pip install -U pyopenssl
    
    And for 'h2load':
    > apt install nghttp2-client
    
    
    Usage
    -----
    In your httpd source checkout, do:
    
    > make install
    > pytest
    
    and all tests defined run on the installed executable and modules.
    > pytest test/modules/core
    runs all the core tests. You can run tests also by name selection:
    > pytest -k test_core
    runs all test cases starting with 'test_core'. Similar:
    > pytest -k test_core_001_04
    runs the test cases starting with that.
    
    Test output gets more verbose, by adding one or several '-v'. This
    also raises the error log level of the tested modules.
    > pytest -vvv -k test_h2_004_01
    run the specific test with mod_http2 at log level TRACE2.
    
    By default, test cases will configure httpd with mpm_event. You
    can change that with the invocation:
    > MPM=worker pytest test/modules/http2
    
    Some tests rely on additional tools installed in your environment
    and will 'skip' if those are not present. In a non-verbose run,
    these will appear as 's' in the output. If you run pytest more
    verbose, the skipped test cases will mention a reason for why
    they are disabled.
    
    For example, most tests in test/modules/md require an installation
    of 'pebble', an ACME test server, and look for it in $PATH.
    
    
    Workings
    --------
    All tests start httpd on their own and try hard to shut it down
    afterwards. You can abort tests with ^C and they clean up.
    
    httpd is started/stopped repeatedly in testing as configurations
    for individual test cases are changed. This is a main difference to
    the Perl test framework which starts the server with all possible
    combinations configured that are needed by tests.
    
    In test/gen/apache a server root is created with config, logs and htdocs
    directories. test/gen/apache/logs/error_log will be the log.
    Configs start in test/gen/apache/conf/httpd.conf. modules.conf is
    dynamically created for the list of modules that a test suite needs.
    
    Test cases write their specific setup in test.conf and reload/restart
    the httpd process. This makes for a small configuration in a test case.
    
    
    Development
    -----------
    
    Adding a test in an existing file is done by adding a method. Its name
    must start with 'test_' and the common practice is to have the name
    of the test suite there as well. All http2 tests start with 'test_h2_'.
    
    Following this can be any characters. If you make test cases of a
    certain feature with a common prefix, it is easier to invoke just
    them using the '-k' selector on the command line.
    
    You can also add just a new file to a test suite, if you do a new
    range of test cases that do not fit anywhere else. A very simple
    one is found in test/modules/http2/test_001_httpd_alive.py.
    
    There is a python class defined with 2 methods. One is the test
    method itself and the other one ' is
    
        @pytest.fixture(autouse=True, scope='class')
        def _class_scope(self, env):
            code
    
    is marked as a pytest 'fixture'. This is some pytest magic.
    'autouse=True' means that this fixture is run, even though
    no test case uses it directly. scope='class' means that it
    is run once for all test cases in this class.
    
    As you see, this fixture gets a parameter named 'env' and
    that is the name of another pytest fixture, defined in the
    file 'conftest.py' in the same directory.
    
        @pytest.fixture(scope="package")
        def env(pytestconfig) -> H2TestEnv:
            code
    
    This one runs one time per 'package', meaning for all test
    cases in this directory. And it gets the 'pytestconfig'
    as parameter which is a standard pytest fixture.
    
    So, when you run 'pytest -k test_h2_004', pytest will look
    at _all_ test cases defined and collect those with that
    prefix. For each directory with test cases found, it will
    process the 'conftest.py', boot-strapping the 'env' fixture,
    and the process the files with active test cases.
    
    As a result, if you invoke just a single test case, only
    the fixtures needed for that test case are created. This
    gives good turn around times when debugging a test case.
    
    If you want to add a new test suite, create a new directory.
    Add the files '__init__.py', 'conftest.py' and a first
    'test_suitename_something.py'. test/modules/core is the
    simplest example. 'test/modules/http2' shows how you load
    other modules. 'test/modules/md' checks and starts external
    processes (an ACME test server).
    
    
    Infrastructure
    --------------
    The test cases rely on the classes provided in 'test/pyhttpd'
    for common code in managing a httpd test instance and do
    provide some base setups:
    - a small set of virtual hosts with some files
    - access to paths and definitions (env fixture)
    - start/stop httpd and inspect the error log
    - run clients like curl and nghttp
    - create certificates for your hosts and make curl use
      the root certs (so no --insecure calls by curl).
    
    ��������������������������������������������������������������������������������������httpd-2.4.64/test/time-sem.c������������������������������������������������������������������������0000664�0001751�0001751�00000034740�14205766164�015510� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <errno.h>
    #include <sys/time.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/wait.h>
    #include <sys/mman.h>
    #include <signal.h>
    
    #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 <sys/file.h>
    
    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 <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    
    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 <pthread.h>
    
    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 <ulocks.h>
    
    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 <sys/types.h>
    #include <sys/ipc.h>
    #ifdef HAVE_SYS_MUTEX_H
    #include <sys/mutex.h>
    #endif
    #include <sys/shm.h>
    
    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 <sched.h>
    #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");
                accept_mutex_off ();
                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!");
            accept_mutex_off ();
            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);
    }
    
    ��������������������������������httpd-2.4.64/test/conftest.py�����������������������������������������������������������������������0000664�0001751�0001751�00000001647�14356741666�016032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import sys
    import os
    
    import pytest
    
    sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
    
    from pyhttpd.env import HttpdTestEnv
    
    def pytest_report_header(config, startdir):
        env = HttpdTestEnv()
        return f"[apache httpd: {env.get_httpd_version()}, mpm: {env.mpm_module}, {env.prefix}]"
    
    def pytest_addoption(parser):
        parser.addoption("--repeat", action="store", type=int, default=1,
                         help='Number of times to repeat each test')
        parser.addoption("--all", action="store_true")
    
    
    def pytest_generate_tests(metafunc):
        if "repeat" in metafunc.fixturenames:
            count = int(metafunc.config.getoption("repeat"))
            metafunc.fixturenames.append('tmp_ct')
            metafunc.parametrize('repeat', range(count))
    
    @pytest.fixture(autouse=True, scope="function")
    def _function_scope(env, request):
        env.set_current_test_name(request.node.name)
        yield
        env.set_current_test_name(None)
    
    �����������������������������������������������������������������������������������������httpd-2.4.64/test/travis_Dockerfile_slapd�����������������������������������������������������������0000664�0001751�0001751�00000001054�13672376043�020361� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������FROM ubuntu:bionic
    RUN echo slapd slapd/password1 password travis | debconf-set-selections
    RUN echo slapd slapd/password2 password travis | debconf-set-selections
    RUN echo slapd slapd/internal/adminpw password travis | debconf-set-selections
    RUN echo slapd slapd/internal/generated_adminpw password travis | debconf-set-selections
    RUN echo slapd slapd/domain string example.com | debconf-set-selections
    RUN apt-get update && apt-get -y install slapd ldap-utils
    # With -d passed, slapd stays in the foreground
    CMD /usr/sbin/slapd -d1 '-h ldap:// ldapi:///'
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/test_select.c���������������������������������������������������������������������0000664�0001751�0001751�00000002665�10455005461�016274� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdio.h>
    #include <stdlib.h>
    #include <sys/time.h>
    
    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);
    }
    ���������������������������������������������������������������������������httpd-2.4.64/test/check_chunked���������������������������������������������������������������������0000664�0001751�0001751�00000003271�10455012627�016307� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl -w
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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";
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/test_parser.c���������������������������������������������������������������������0000664�0001751�0001751�00000004112�10455005461�016276� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdio.h>
    #include <stdlib.h>
    #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);
    }
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/.indent.pro�����������������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�015667� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/test_limits.c���������������������������������������������������������������������0000664�0001751�0001751�00000013451�13623622544�016320� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************
     * 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 <BUGTRAQ@netspace.org>
     * From: Dag-Erling Coidan =?ISO-8859-1?Q?Sm=F8rgrav?= <finrod@EWOX.ORG>
     * 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 without 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 <sys/types.h>
    #include <sys/uio.h>
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #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);
        }
        memset(&sin, sizeof(sin));
        memcpy((char *)&sin.sin_addr, he->h_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);
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/cls.c�����������������������������������������������������������������������������0000664�0001751�0001751�00000011005�10455005461�014523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <ctype.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    /*
     * Compare a string to a mask
     * Mask characters:
     *   @ - uppercase letter
     *   # - lowercase letter
     *   & - hex digit
     *   # - digit
     *   * - swallow remaining characters
     *  <x> - 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;
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/README����������������������������������������������������������������������������0000664�0001751�0001751�00000000255�10150161574�014463� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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.
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/test-writev.c���������������������������������������������������������������������0000664�0001751�0001751�00000006132�10455005461�016244� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/uio.h>
    #include <errno.h>
    
    #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);
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/travis_run_linux.sh���������������������������������������������������������������0000775�0001751�0001751�00000020133�14672262503�017561� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash -ex
    
    # Test for APLOGNO() macro errors (duplicates, empty args) etc.  For
    # trunk, run the updater script to see if it fails.  If it succeeds
    # and changes any files (because there was a missing argument), the
    # git diff will be non-empty, so fail for that case too.  For
    # non-trunk use a grep and only catch the empty argument case.
    if test -v TEST_LOGNO; then
        if test -f docs/log-message-tags/update-log-msg-tags; then
            find server modules os -name \*.c | \
                xargs perl docs/log-message-tags/update-log-msg-tags
            git diff --exit-code .
            : PASSED
            exit 0
        else
            set -o pipefail
            if find server modules os -name \*.c | \
                    xargs grep -C1 --color=always 'APLOGNO()'; then
                : FAILED
                exit 1
            else
                : PASSED
                exit 0
            fi
        fi
    fi
    
    ### Installed apr/apr-util don't include the *.m4 files but the
    ### Debian packages helpfully install them, so use the system APR to buildconf
    ./buildconf --with-apr=/usr/bin/apr-1-config ${BUILDCONFIG}
    
    PREFIX=${PREFIX:-$HOME/build/httpd-root}
    
    # If perl-framework testing is required it is checked out here by
    # _before_linux.sh:
    if test -d test/perl-framework; then
        CONFIG="$CONFIG --enable-load-all-modules"
        if grep -q ^check: Makefile.in; then
            CONFIG="--with-test-suite=test/perl-framework $CONFIG"
            WITH_TEST_SUITE=1
        fi
    
        # Use the CPAN environment.
        eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
    fi
    if test -v APR_VERSION; then
        CONFIG="$CONFIG --with-apr=$HOME/root/apr-${APR_VERSION}"
    else
        CONFIG="$CONFIG --with-apr=/usr"
    fi
    if test -v APU_VERSION; then
        CONFIG="$CONFIG --with-apr-util=$HOME/root/apr-util-${APU_VERSION}"
    else
        CONFIG="$CONFIG --with-apr-util=/usr"
    fi
    
    # Pick up the rustls install built previously.
    if test -v TEST_MOD_TLS -a RUSTLS_VERSION; then
      CONFIG="$CONFIG --with-tls --with-rustls=$HOME/root/rustls"
    fi
    
    if test -v TEST_OPENSSL3; then
        CONFIG="$CONFIG --with-ssl=$HOME/root/openssl3"
        export LD_LIBRARY_PATH=$HOME/root/openssl3/lib:$HOME/root/openssl3/lib64
    fi
    
    srcdir=$PWD
    
    if test -v TEST_VPATH; then
        mkdir ../vpath
        cd ../vpath
    fi
    
    $srcdir/configure --prefix=$PREFIX $CONFIG
    make $MFLAGS
    
    if test -v TEST_INSTALL; then
       make install
       pushd $PREFIX
         test `./bin/apxs -q PREFIX` = $PREFIX
         test `$PWD/bin/apxs -q PREFIX` = $PREFIX
         ./bin/apxs -g -n foobar
         cd foobar; make
       popd
    fi
    
    if ! test -v SKIP_TESTING; then
        set +e
        RV=0
    
        if test -v TEST_MALLOC; then
            # Enable enhanced glibc malloc debugging, see mallopt(3)
            export MALLOC_PERTURB_=65 MALLOC_CHECK_=3
            export LIBC_FATAL_STDERR_=1
        fi
    
        if test -v TEST_UBSAN; then
            export UBSAN_OPTIONS="log_path=$PWD/ubsan.log"
        fi
    
        if test -v TEST_ASAN; then
            export ASAN_OPTIONS="log_path=$PWD/asan.log:detect_leaks=0"
        fi
    
        # Try to keep all potential coredumps from all processes
        sudo sysctl -w kernel.core_uses_pid=1 2>/dev/null || true
        # Systemd based systems might process core dumps via systemd-coredump.
        # But we want to have local unprocessed files.
        sudo sysctl -w kernel.core_pattern=core || true
        ulimit -c unlimited 2>/dev/null || true
    
        if test -v WITH_TEST_SUITE; then
            make check TESTS="${TESTS}" TEST_CONFIG="${TEST_ARGS}"
            RV=$?
        else
            test -v TEST_INSTALL || make install
            pushd test/perl-framework
                perl Makefile.PL -apxs $PREFIX/bin/apxs
                make test APACHE_TEST_EXTRA_ARGS="${TEST_ARGS} ${TESTS}" | tee test.log
                RV=${PIPESTATUS[0]}
                # re-run failing tests with -v, avoiding set -e
                if [ $RV -ne 0 ]; then
                    #mv t/logs/error_log t/logs/error_log_save
                    FAILERS=""
                    while read FAILER; do
                        FAILERS="$FAILERS $FAILER"
                    done < <(awk '/Failed:/{print $1}' test.log)
                    if [ -n "$FAILERS" ]; then
                        t/TEST -v $FAILERS || true
                    fi
                    # set -e would have killed us after the original t/TEST
                    rm -f test.log
                    #mv t/logs/error_log_save t/logs/error_log
                    false
                fi
            popd
        fi
    
        # Skip further testing if a core dump was created during the test
        # suite run above.
        if test $RV -eq 0 && test -n "`ls test/perl-framework/t/core{,.*} 2>/dev/null`"; then
            RV=4
        fi
    
        if test -v TEST_SSL -a $RV -eq 0; then
            pushd test/perl-framework
                # Test loading encrypted private keys
                ./t/TEST -defines "TEST_SSL_DES3_KEY TEST_SSL_PASSPHRASE_EXEC" t/ssl
                RV=$?
    
                # Log the OpenSSL version.
                grep 'mod_ssl.*compiled against' t/logs/error_log | tail -n 1
                
                # Test various session cache backends
                for cache in shmcb redis:localhost:6379 memcache:localhost:11211; do
                    test $RV -eq 0 || break
    
                    SSL_SESSCACHE=$cache ./t/TEST -sslproto TLSv1.2 -defines TEST_SSL_SESSCACHE -start
                    ./t/TEST t/ssl
                    RV=$?
                    ./t/TEST -stop
                    SRV=$?
                    if test $RV -eq 0 -a $SRV -ne 0; then
                        RV=$SRV
                    fi
                done
            popd
        fi
    
        if test -v LITMUS -a $RV -eq 0; then
            pushd test/perl-framework
               mkdir -p t/htdocs/modules/dav
               ./t/TEST -start
               # litmus uses $TESTS, so unset it.
               unset TESTS
               litmus http://localhost:8529/modules/dav/
               RV=$?
               ./t/TEST -stop
            popd
        fi
    
        if test $RV -ne 0 && test -f test/perl-framework/t/logs/error_log; then
            grep -v ':\(debug\|trace[12345678]\)\]' test/perl-framework/t/logs/error_log
        fi
    
        if test -v TEST_CORE -a $RV -eq 0; then
            # Run HTTP/2 tests.
            MPM=event py.test-3 test/modules/core
            RV=$?
        fi
    
        if test -v TEST_H2 -a $RV -eq 0; then
            # Build the test clients
            (cd test/clients && make)
            # Run HTTP/2 tests.
            MPM=event py.test-3 test/modules/http2
            RV=$?
            if test $RV -eq 0; then
              MPM=worker py.test-3 test/modules/http2
              RV=$?
            fi
        fi
    
        if test -v TEST_MD -a $RV -eq 0; then
            # Run ACME tests.
            # need the go based pebble as ACME test server
            # which is a package on debian sid, but not on focal
            export GOPATH=${PREFIX}/gocode
            mkdir -p "${GOPATH}"
            export PATH="${GOROOT}/bin:${GOPATH}/bin:${PATH}"
            go get -u github.com/letsencrypt/pebble/...
            (cd $GOPATH/src/github.com/letsencrypt/pebble && go install ./...)
    
            py.test-3 test/modules/md
            RV=$?
        fi
    
        # Catch cases where abort()s get logged to stderr by libraries but
        # only cause child processes to terminate e.g. during shutdown,
        # which may not otherwise trigger test failures.
    
        # "glibc detected": printed with LIBC_FATAL_STDERR_/MALLOC_CHECK_
        # glibc will abort when malloc errors are detected.  This will get
        # caught by the segfault grep as well.
    
        # "pool concurrency check": printed by APR built with
        # --enable-thread-debug when an APR pool concurrency check aborts
    
        for phrase in 'Segmentation fault' 'glibc detected' 'pool concurrency check:' 'Assertion.*failed'; do
            # Ignore IO/debug logs
            if grep -v ':\(debug\|trace[12345678]\)\]' test/perl-framework/t/logs/error_log | grep -q "$phrase"; then
                grep --color=always -C5 "$phrase" test/perl-framework/t/logs/error_log
                RV=2
            fi
        done
    
        if test -v TEST_UBSAN && test -n "`ls ubsan.log.* 2>/dev/null`"; then
            cat ubsan.log.*
            RV=3
        fi
    
        if test -v TEST_ASAN && test -n "`ls asan.log.* 2>/dev/null`"; then
            cat asan.log.*
    
            # ASan can report memory leaks, fail on errors only
            if grep -q "ERROR: AddressSanitizer:" `ls asan.log.*`; then
                RV=4
            fi
        fi
    
        for core in `ls test/perl-framework/t/core{,.*} test/gen/apache/core{,.*} 2>/dev/null`; do
            gdb -ex 'thread apply all backtrace full' -batch ./httpd "$core"
            RV=5
        done
    
        exit $RV
    fi
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/test_travis_conditions.sh���������������������������������������������������������0000775�0001751�0001751�00000002425�14211363564�020750� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh -e
    # Script to test whether travis conditions match correctly.
    # "gem install travis-conditions". Tests .travis.yml in the cwd.
    
    cond_24x="`sed -n '/&condition_24x_only/{s/.*condition_24x_only//;p;q;}' .travis.yml`"
    cond_not_24x="`sed -n '/&condition_not_24x/{s/.*condition_not_24x//;p;q;}' .travis.yml`"
    
    echo Condition 2.4.x: ${cond_24x}
    echo Condition not 2.4.x: ${cond_not_24x}
    
    function testit()
    {
        local data=$1
        local expect=$2
    
        is_24x=`travis-conditions eval "$cond_24x" --data "${data}"`
        not_24x=`travis-conditions eval "$cond_not_24x" --data "${data}"`
    
        if [ $is_24x = $not_24x ]; then
            echo FAIL: Tests as both 2.4.x and not 2.4.x for "$data"
            return 1
        elif [ $expect = 2.4.x -a $is_24x = true ]; then
            echo PASS
        elif [ $expect = trunk ]; then
            echo PASS
        else
            echo FAIL for "$data"
            return 1
        fi
        return 0
    }
    
    testit '{"tag": "2.4.49"}' 2.4.x
    testit '{"tag": "2.5.59"}' trunk
    testit '{"branch": "2.4.x"}' 2.4.x
    testit '{"branch": "candidate-2.4.49"}' 2.4.x
    testit '{"branch": "2.4.55-candidate"}' 2.4.x
    testit '{"branch": "2.4-backport-branch"}' 2.4.x
    testit '{"branch": "2.4.x-something"}' 2.4.x
    testit '{"branch": "2.5.0"}' trunk
    testit '{"branch": "2.5.x"}' trunk
    testit '{"branch": "trunk"}' trunk
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/make_sni.sh�����������������������������������������������������������������������0000664�0001751�0001751�00000030353�13623622544�015736� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 populate a directory 'sni' with 3 sites, httpd.conf
    # and certificates as to facilitate testing of TLS server name 
    # indication support (RFC 4366) or SNI.
    #
    #
    OPENSSL=${OPENSSL:-openssl}
    DOMAIN=${DOMAIN:-my-sni-test.org}
    DIR=${DIR:-$PWD/sni}
    
    # List of hostnames automatically created by default.
    NAMES=${NAMES:-ape nut pear apple banana}
    
    # IP address these hostnames are bound to.
    IP=${IP:-127.0.0.1}
    
    # A certificate password for the .p12 files of the client
    # authentication test. Normally not set. However some browsers
    # require a password of at least 4 characters.
    #
    PASSWD=${PASSWD:-}
    
    args=`getopt a:fd:D:p: $*`
    if [ $? != 0 ]; then
        echo "Syntax: $0 [-f] [-a IPaddress] [-d outdir] [-D domain ] [two or more vhost names ]"
        echo "    -f        Force overwriting of outdir (default is $DIR)"
        echo "    -d dir    Directory to create the SNI test server in (default is $DIR)"
        echo "    -D domain Domain name to use for this test (default is $DOMAIN)"
        echo "    -a IP     IP address to use for this virtual host (default is $IP)"
        echo "    -p str    Password for the client certificate test (some browsers require a set password)"
        echo "    [names]   List of optional vhost names (default is $NAMES)"
        echo 
        echo "Example:"
        echo "    $0 -D SecureBlogsAreUs.com peter fred mary jane ardy"
        echo
        echo "Which will create peter.SecureBlogsAreUs.com, fred.SecureBlogsAreUs.com and"
        echo "so on. Note that the _first_ FQDN is also the default for non SNI hosts. It"
        echo "may make sense to give this host a generic name - and allow each of the real"
        echo "SNI site as sub directories/URI's of this generic name; thus allowing the "
        echo "few non-SNI browsers access."
        exit 1
    fi
    set -- $args
    for i
    do
        case "$i"
        in
            -f)
                FORCE=1
                shift;;
            -a)
                IP=$2; shift
                shift;;
            -d)
                DIR=$2; shift
                shift;;
            -p)
                PASSWD=$2; shift
                shift;;
            -D)
                DOMAIN=$2; shift
                shift;;
            --) 
                shift; break;
        esac
    done
    
    if [ $# = 1 ]; then
        echo "Aborted - just specifying one vhost makes no sense for SNI testing. Go wild !"
        exit 1
    fi
    
    if [ $# -gt 0 ]; then
        NAMES=$*
    fi
    
    if ! openssl version | grep -q OpenSSL; then
        echo Aborted - your openssl is very old or misconfigured.
        exit 1
    fi
    
    set `openssl version`
    if test "0$2" \< "00.9"; then
        echo Aborted - version of openssl too old, 0.9 or up required.
        exit 1 
    fi
    
    if test -d ${DIR} -a "x$FORCE" != "x1"; then
        echo Aborted - already an ${DIR} directory. Use the -f flag to overwrite.
        exit 1
    fi
    
    mkdir -p ${DIR} || exit 1
    mkdir -p ${DIR}/ssl ${DIR}/htdocs ${DIR}/logs || exit 1
            
    # Create a 'CA' - keep using different serial numbers
    # as the browsers get upset if they see an identical 
    # serial with a different pub-key.
    #
    # Note that we're not relying on the 'v3_ca' section as
    # in the default openssl.conf file - so the certificate
    # will be without the basicConstraints = CA:true and
    # keyUsage = cRLSign, keyCertSign values. This is fine
    # for most browsers.
    #
    serial=$RANDOM$$
    
    openssl req -new -nodes -batch \
        -x509  \
        -days 10 -subj '/CN=Da Root/O=SNI testing/' -set_serial $serial \
        -keyout ${DIR}/root.key -out ${DIR}/root.pem  \
        || exit 2
    
    CDIR=${DIR}/client-xs-control
    mkdir -p ${CDIR}
    # Create some certificate authorities for testing client controls
    #
    openssl req -new -nodes -batch \
        -x509  \
        -days 10 -subj '/CN=Da Second Root/O=SNI user access I/' -set_serial 2$serial$$\
        -keyout ${CDIR}/xs-root-1.key -out ${CDIR}/xs-root-1.pem  \
        || exit 2
    
    openssl req -new -nodes -batch \
        -x509  \
        -days 10 -subj '/CN=Da Second Root/O=SNI user access II/' -set_serial 3$serial$$ \
        -keyout ${CDIR}/xs-root-2.key -out ${CDIR}/xs-root-2.pem  \
        || exit 2
    
    # Create a chain of just the two access authorities:
    cat ${CDIR}/xs-root-2.pem ${CDIR}/xs-root-1.pem > ${CDIR}/xs-root-chain.pem
    
    # And likewise a directory with the same information (using the
    # required 'hash' naming format
    #
    mkdir -p ${CDIR}/xs-root-dir || exit 1
    rm -f {$CDIR}/*.0
    ln ${CDIR}/xs-root-1.pem ${CDIR}/xs-root-dir/`openssl x509 -noout -hash -in ${CDIR}/xs-root-1.pem`.0
    ln ${CDIR}/xs-root-2.pem ${CDIR}/xs-root-dir/`openssl x509 -noout -hash -in ${CDIR}/xs-root-2.pem`.0
    
    # Use the above two client certificate authorities to make a few users
    for i in 1 2
    do
        # Create a certificate request for a test user.
        #
        openssl req -new -nodes -batch \
            -days 9 -subj "/CN=User $i/O=SNI Test Crash Dummy Dept/" \
            -keyout ${CDIR}/client-$i.key -out ${CDIR}/client-$i.req -batch  \
                    || exit 3
    
        # And get it signed by either our client cert issuing root authority.
        #
        openssl x509 -text -req \
            -CA ${CDIR}/xs-root-$i.pem -CAkey ${CDIR}/xs-root-$i.key \
            -set_serial 3$serial$$ -in ${CDIR}/client-$i.req -out ${CDIR}/client-$i.pem \
                    || exit 4
    
        # And create a pkcs#12 version for easy browser import.
        #
        openssl pkcs12 -export \
            -inkey ${CDIR}/client-$i.key -in ${CDIR}/client-$i.pem -name "Client $i" \
            -caname "Issuing client root $i" -certfile ${CDIR}/xs-root-$i.pem  \
            -out ${CDIR}/client.p12 -passout pass:"$PASSWD" || exit 5
    
        rm ${CDIR}/client-$i.req 
    done
    
    # Create the header for the example '/etc/hosts' file.
    #
    echo '# To append to your hosts file' > ${DIR}/hosts
    
    # Create a header for the httpd.conf snipped.
    #
    cat > ${DIR}/httpd-sni.conf << EOM
    # To append to your httpd.conf file'
    Listen ${IP}:443
    NameVirtualHost ${IP}:443
    
    LoadModule ssl_module modules/mod_ssl.so
    
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
    
    LogLevel debug
    TransferLog ${DIR}/logs/access_log
    ErrorLog ${DIR}/logs/error_log
    
    # You'll get a warning about this.
    #
    SSLSessionCache none
    
    # Note that this SSL configuration is far
    # from complete - you probably will want
    # to configure SSLSession Caches at the 
    # very least.
    
    <Directory />
        Options None
        AllowOverride None
        Require all denied
    </Directory>
    
    <Directory "${DIR}/htdocs">
        allow from all
        Require all granted
    </Directory>
    
    # This first entry is also the default for non SNI
    # supporting clients.
    #
    EOM
    
    # Create the header of a sample BIND zone file.
    #
    (
            echo "; Configuration sample to be added to the $DOMAIN zone file of BIND."
            echo "\$ORIGIN $DOMAIN."
    ) > ${DIR}/zone-file
    
    ZADD="IN A $IP"
    INFO="and also the site you see when the browser does not support SNI."
    
    set -- ${NAMES}
    DEFAULT=$1
    
    for n in ${NAMES}
    do
        FQDN=$n.$DOMAIN
        serial=`expr $serial + 1`
    
        # Create a certificate request for this host.
        #
        openssl req -new -nodes -batch \
            -days 9 -subj "/CN=$FQDN/O=SNI Testing/" \
            -keyout ${DIR}/$n.key -out ${DIR}/$n.req -batch  \
                    || exit 3
    
        # And get it signed by our root authority.
        #
        openssl x509 -text -req \
            -CA ${DIR}/root.pem -CAkey ${DIR}/root.key \
            -set_serial $serial -in ${DIR}/$n.req -out ${DIR}/$n.pem \
                    || exit 4
    
        # Combine the key and certificate in one file.
        #
        cat ${DIR}/$n.pem ${DIR}/$n.key > ${DIR}/ssl/$n.crt
        rm ${DIR}/$n.req ${DIR}/$n.key ${DIR}/$n.pem
    
        LST="$LST
        https://$FQDN/index.html"
    
        # Create a /etc/host and bind-zone file example
        #
        echo "${IP}         $FQDN $n" >> ${DIR}/hosts
        echo "$n    $ZADD" >> ${DIR}/zone-file
        ZADD="IN CNAME $DEFAULT"
    
        # Create and populate a docroot for this host.
        #
        mkdir -p ${DIR}/htdocs/$n || exit 1
        echo We are $FQDN $INFO > ${DIR}/htdocs/$n/index.html || exit 1
    
        # And change the info text - so that only the default/fallback site
        # gets marked as such.
        #
        INFO="and you'd normally only see this site when there is proper SNI support."
    
        # And create a configuration snipped.
        #
        cat >> ${DIR}/httpd-sni.conf << EOM
    <VirtualHost ${IP}:443>
        SSLEngine On
        ServerName $FQDN:443
        DocumentRoot ${DIR}/htdocs/$n
        SSLCertificateChainFile ${DIR}/root.pem
        SSLCertificateFile ${DIR}/ssl/$n.crt
    
        # Uncomment the following lines if you
        # want to only allow access to clients with
        # a certificate issued/signed by some 
        # selection of the issuing authorities
        #
        # SSLCACertificate ${CDIR}/xs-root-1.pem # just root 1
        # SSLCACertificate ${CDIR}/xs-root-2.pem # just root 2
        # SSLCACertificate ${CDIR}/xs-root-chain.pem # 1 & 2 
        # SSLCACertificateDir ${CDIR}/xs-root-dir # 1 & 2 - but as a directory.
        #
        # SSLVerifyClient require
        # SSLVerifyDepth 2
        # 
        TransferLog ${DIR}/logs/access_$n
    </VirtualHost>
    
    EOM
    
    done
    
    cat << EOM
    SNI Files generated
    ===================
    
    The directory ${DIR}/sni has been populated with the following
    
    -       root.key|pem    Certificate authority root and key. (You could
                            import the root.pem key into your browser to
                            quell warnings about an unknown authority).
    
    -       hosts           /etc/hosts file with fake entries for the hosts
    
    -       htdocs          directory with one docroot for each domain,
                            each with a small sample file.
    
    -       ssl             directory with an ssl cert (signed by root)
                            for each of the domains).
    
    -       logs            logfiles, one for each domain and an
                            access_log for any misses.
    
    The directory ${CDIR} contains optional test files to allow client
    authentication testing:
    
    -       client*pem/p12  Files for client authentication testing. These
                            need to be imported into the browser.
    
    -       xs-root-1/2     Certificate authority which has issued above
                            client authentication certificates.
    
    -       xs-root-dir     A directory specific for the SSLCACertificateDir
                            directive.
    
    -       xs-root-chain   A chain of the two client xs authorities for the
                            SSLCACertificate directive.
    
    SNI Test
    ========
    
    A directory ${DIR}/sni has been created. Run an apache
    server against it with
    
        .../httpd -f ${DIR}/httpd-sni.conf
    
    and keep an eye on ${DIR}/logs/error_log. When everything 
    is fine you will see entries like:
    
        Feb 11 16:12:26 2008] [debug] Init: 
            SSL server IP/port overlap: ape.*:443 (httpd-sni.conf:24) vs. jane.*:443 (httpd-sni.conf:42)
    
    for each vhost configured and a concluding warning:
    
        [Mon Feb 11 16:12:26 2008] [warn] Init: 
            Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)
    
    HOWEVER - If you see an entry like:
    
        [Mon Feb 11 15:41:41 2008] [warn] Init: 
            You should not use name-based virtual hosts in conjunction with SSL!!
    
    then you are either using an OpenSSL which is too old and/or you need to ensure that the
    TLS Extensions are compiled into openssl with the 'enable-tlsext' flag. Once you have
    recompiled or reinstalled OpenSSL with TLS Extensions you will have to recompile mod_ssl
    to allow it to recognize SNI support.
    
    Meanwhile add 'hosts' to your c:\windows\system32\drivers\etc\hosts
    or /etc/hosts file as to point the various URL's to your server:
    $LST
    
    and verify that each returns its own name (and an entry in its
    own ${DIR}/logs) file).
    
    NOTE
    ====
    
    Note that in the generated example the 'first' domain is special - and is the
    catch all for non-SNI browsers. Depending on your circumstances it may make
    sense to use a generic name - and have each of the SNI domains as subdirectories
    (and hence URI's under this generic name). Thus allowing non SNI browsers also
    access to those sites.
    EOM
    exit 0
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/test_find.c�����������������������������������������������������������������������0000664�0001751�0001751�00000004253�10455005461�015730� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdio.h>
    #include <stdlib.h>
    #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);
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/test/tcpdumpscii.txt�������������������������������������������������������������������0000664�0001751�0001751�00000002315�10150161574�016667� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    From marcs@znep.com Fri Apr 17 15:16:16 1998
    Date: Sat, 22 Nov 1997 20:44:10 -0700 (MST)
    From: Marc Slemko <marcs@znep.com>
    To: TLOSAP <new-httpd@apache.org>
    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 <fenner@parc.xerox.com>
    To: Nate Williams <nate@mt.sri.com>
    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 (<TCPDUMP>) {
    	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;
    }
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/��������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014143� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�014733� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/event/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016054� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/event/config3.m4������������������������������������������������������������0000664�0001751�0001751�00000000337�13243014561�017636� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl ## XXX - Need a more thorough check of the proper flags to use
    
    APACHE_SUBST(MOD_MPM_EVENT_LDADD)
    
    APACHE_MPM_MODULE(event, $enable_mpm_event, event.lo,[
        AC_CHECK_FUNCS(pthread_kill)
    ], , [\$(MOD_MPM_EVENT_LDADD)])
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/event/mpm_default.h���������������������������������������������������������0000664�0001751�0001751�00000003137�11711754075�020524� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    
    /**
     * @file  event/mpm_default.h
     * @brief Event MPM defaults
     *
     * @defgroup APACHE_MPM_EVENT Event MPM
     * @ingroup APACHE_INTERNAL
     * @{
     */
    
    #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
    
    #endif /* AP_MPM_DEFAULT_H */
    /** @} */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/event/config.m4�������������������������������������������������������������0000664�0001751�0001751�00000001265�12241750026�017554� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_MSG_CHECKING(if event MPM supports this platform)
    if test $forking_mpms_supported != yes; then
        AC_MSG_RESULT(no - This is not a forking platform)
    elif test $ac_cv_define_APR_HAS_THREADS != yes; then
        AC_MSG_RESULT(no - APR does not support threads)
    elif test $have_threaded_sig_graceful != yes; then
        AC_MSG_RESULT(no - SIG_GRACEFUL cannot be used with a threaded MPM)
    elif test $ac_cv_have_threadsafe_pollset != yes; then
        AC_MSG_RESULT(no - APR_POLLSET_THREADSAFE is not supported)
    elif test $apr_has_skiplist != yes; then
        AC_MSG_RESULT(no - APR skiplist is not available, need APR 1.5.x or later)
    else
        AC_MSG_RESULT(yes)
        APACHE_MPM_SUPPORTED(event, yes, yes)
    fi
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/event/event.c���������������������������������������������������������������0000664�0001751�0001751�00000466733�14651200711�017347� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
     * significant 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 Listening sockets,
     * and all sockets that are in a Keep Alive status.
     *
     * The MPM assumes the underlying apr_pollset implementation 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 does not perform 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_poll.h"
    #include "apr_ring.h"
    #include "apr_queue.h"
    #include "apr_atomic.h"
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    #include "apr_version.h"
    
    #include <stdlib.h>
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if APR_HAVE_SYS_SOCKET_H
    #include <sys/socket.h>
    #endif
    #if APR_HAVE_SYS_WAIT_H
    #include <sys/wait.h>
    #endif
    #ifdef HAVE_SYS_PROCESSOR_H
    #include <sys/processor.h>      /* for bindprocessor() */
    #endif
    
    #if !APR_HAS_THREADS
    #error The Event MPM requires APR threads, but they are unavailable.
    #endif
    
    #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 "http_protocol.h"
    #include "ap_mpm.h"
    #include "mpm_common.h"
    #include "ap_listen.h"
    #include "scoreboard.h"
    #include "mpm_fdqueue.h"
    #include "mpm_default.h"
    #include "http_vhost.h"
    #include "unixd.h"
    #include "apr_skiplist.h"
    
    #include <signal.h>
    #include <limits.h>             /* 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
    
    #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
    
    #if !APR_VERSION_AT_LEAST(1,4,0)
    #define apr_time_from_msec(x) (x * 1000)
    #endif
    
    #define CONN_STATE_IS_LINGERING_CLOSE(s) ((s) >= CONN_STATE_LINGER && \
                                              (s) <= CONN_STATE_LINGER_SHORT)
    #ifndef MAX_SECS_TO_LINGER
    #define MAX_SECS_TO_LINGER 30
    #endif
    #define SECONDS_TO_LINGER  2
    
    /*
     * Actual definitions of config globals
     */
    
    #ifndef DEFAULT_WORKER_FACTOR
    #define DEFAULT_WORKER_FACTOR 2
    #endif
    #define WORKER_FACTOR_SCALE   16  /* scale factor to allow fractional values */
    static unsigned int worker_factor = DEFAULT_WORKER_FACTOR * WORKER_FACTOR_SCALE;
        /* AsyncRequestWorkerFactor * 16 */
    
    static int threads_per_child = 0;           /* ThreadsPerChild */
    static int ap_daemons_to_start = 0;         /* StartServers */
    static int min_spare_threads = 0;           /* MinSpareThreads */
    static int max_spare_threads = 0;           /* MaxSpareThreads */
    static int active_daemons_limit = 0;        /* MaxRequestWorkers / ThreadsPerChild */
    static int max_workers = 0;                 /* MaxRequestWorkers */
    static int server_limit = 0;                /* ServerLimit */
    static int thread_limit = 0;                /* ThreadLimit */
    static int had_healthy_child = 0;
    static volatile int dying = 0;
    static volatile int workers_may_exit = 0;
    static volatile int start_thread_may_exit = 0;
    static volatile int listener_may_exit = 0;
    static int listener_is_wakeable = 0;        /* Pollset supports APR_POLLSET_WAKEABLE */
    static int num_listensocks = 0;
    static apr_int32_t conns_this_child;        /* MaxConnectionsPerChild, only access
                                                   in listener thread */
    static apr_uint32_t connection_count = 0;   /* Number of open connections */
    static apr_uint32_t lingering_count = 0;    /* Number of connections in lingering close */
    static apr_uint32_t suspended_count = 0;    /* Number of suspended connections */
    static apr_uint32_t clogged_count = 0;      /* Number of threads processing ssl conns */
    static apr_uint32_t threads_shutdown = 0;   /* Number of threads that have shutdown
                                                   early during graceful termination */
    static int resource_shortage = 0;
    static fd_queue_t *worker_queue;
    static fd_queue_info_t *worker_queue_info;
    
    static apr_thread_mutex_t *timeout_mutex;
    
    module AP_MODULE_DECLARE_DATA mpm_event_module;
    
    /* forward declare */
    struct event_srv_cfg_s;
    typedef struct event_srv_cfg_s event_srv_cfg;
    
    static apr_pollfd_t *listener_pollfd;
    
    /*
     * The pollset for sockets that are in any of the timeout queues. Currently
     * we use the timeout_mutex to make sure that connections are added/removed
     * atomically to/from both event_pollset and a timeout queue. Otherwise
     * some confusion can happen under high load if timeout queues and pollset
     * get out of sync.
     * XXX: It should be possible to make the lock unnecessary in many or even all
     * XXX: cases.
     */
    static apr_pollset_t *event_pollset;
    
    typedef struct event_conn_state_t event_conn_state_t;
    
    /*
     * The chain of connections to be shutdown by a worker thread (deferred),
     * linked list updated atomically.
     */
    static event_conn_state_t *volatile defer_linger_chain;
    
    struct event_conn_state_t {
        /** APR_RING of expiration timeouts */
        APR_RING_ENTRY(event_conn_state_t) timeout_list;
        /** the time when the entry was queued */
        apr_time_t queue_timestamp;
        /** connection record this struct refers to */
        conn_rec *c;
        /** request record (if any) this struct refers to */
        request_rec *r;
        /** server config this struct refers to */
        event_srv_cfg *sc;
        /** scoreboard handle for the conn_rec */
        ap_sb_handle_t *sbh;
        /** is the current conn_rec suspended?  (disassociated with
         * a particular MPM thread; for suspend_/resume_connection
         * hooks)
         */
        int suspended;
        /** memory pool to allocate from */
        apr_pool_t *p;
        /** bucket allocator */
        apr_bucket_alloc_t *bucket_alloc;
        /** poll file descriptor information */
        apr_pollfd_t pfd;
        /** public parts of the connection state */
        conn_state_t pub;
        /** chaining in defer_linger_chain */
        struct event_conn_state_t *chain;
        unsigned int 
            /** Is lingering close from defer_lingering_close()? */
            deferred_linger :1,
            /** Has ap_start_lingering_close() been called? */
            linger_started  :1;
    };
    
    APR_RING_HEAD(timeout_head_t, event_conn_state_t);
    
    struct timeout_queue {
        struct timeout_head_t head;
        apr_interval_time_t timeout;
        apr_uint32_t count;         /* for this queue */
        apr_uint32_t *total;        /* for all chained/related queues */
        struct timeout_queue *next; /* chaining */
    };
    /*
     * Several timeout queues that use different timeouts, so that we always can
     * simply append to the end.
     *   waitio_q           uses vhost's TimeOut
     *   write_completion_q uses vhost's TimeOut
     *   keepalive_q        uses vhost's KeepAliveTimeOut
     *   linger_q           uses MAX_SECS_TO_LINGER
     *   short_linger_q     uses SECONDS_TO_LINGER
     */
    static struct timeout_queue *waitio_q,
                                *write_completion_q,
                                *keepalive_q,
                                *linger_q,
                                *short_linger_q;
    static volatile apr_time_t  queues_next_expiry;
    
    /* Prevent extra poll/wakeup calls for timeouts close in the future (queues
     * have the granularity of a second anyway).
     * XXX: Wouldn't 0.5s (instead of 0.1s) be "enough"?
     */
    #define TIMEOUT_FUDGE_FACTOR apr_time_from_msec(100)
    
    /*
     * Macros for accessing struct timeout_queue.
     * For TO_QUEUE_APPEND and TO_QUEUE_REMOVE, timeout_mutex must be held.
     */
    static void TO_QUEUE_APPEND(struct timeout_queue *q, event_conn_state_t *el)
    {
        apr_time_t elem_expiry;
        apr_time_t next_expiry;
    
        APR_RING_INSERT_TAIL(&q->head, el, event_conn_state_t, timeout_list);
        ++*q->total;
        ++q->count;
    
        /* Cheaply update the global queues_next_expiry with the one of the
         * first entry of this queue (oldest) if it expires before.
         */
        el = APR_RING_FIRST(&q->head);
        elem_expiry = el->queue_timestamp + q->timeout;
        next_expiry = queues_next_expiry;
        if (!next_expiry || next_expiry > elem_expiry + TIMEOUT_FUDGE_FACTOR) {
            queues_next_expiry = elem_expiry;
            /* Unblock the poll()ing listener for it to update its timeout. */
            if (listener_is_wakeable) {
                apr_pollset_wakeup(event_pollset);
            }
        }
    }
    
    static void TO_QUEUE_REMOVE(struct timeout_queue *q, event_conn_state_t *el)
    {
        APR_RING_REMOVE(el, timeout_list);
        APR_RING_ELEM_INIT(el, timeout_list);
        --*q->total;
        --q->count;
    }
    
    static struct timeout_queue *TO_QUEUE_MAKE(apr_pool_t *p, apr_time_t t,
                                               struct timeout_queue *ref)
    {
        struct timeout_queue *q;
                                               
        q = apr_pcalloc(p, sizeof *q);
        APR_RING_INIT(&q->head, event_conn_state_t, timeout_list);
        q->total = (ref) ? ref->total : apr_pcalloc(p, sizeof *q->total);
        q->timeout = t;
    
        return q;
    }
    
    #define TO_QUEUE_ELEM_INIT(el) \
        APR_RING_ELEM_INIT((el), timeout_list)
    
    /* The structure used to pass unique initialization info to each thread */
    typedef struct
    {
        int pslot;  /* process slot */
        int tslot;  /* worker slot of the thread */
    } 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;
        void *baton;
    } listener_poll_type;
    
    /* data retained by event across load/unload of the module
     * allocated on first call to pre-config hook; located on
     * subsequent calls to pre-config hook
     */
    typedef struct event_retained_data {
        ap_unixd_mpm_retained_data *mpm;
    
        int first_server_limit;
        int first_thread_limit;
        int sick_child_detected;
        int maxclients_reported;
        int near_maxclients_reported;
        /*
         * The max child slot ever assigned, preserved across restarts.  Necessary
         * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts.
         * We use this value to optimize routines that have to scan the entire
         * scoreboard.
         */
        int max_daemon_used;
    
        /*
         * All running workers, active and shutting down, including those that
         * may be left from before a graceful restart.
         * Not kept up-to-date when shutdown is pending.
         */
        int total_daemons;
        /*
         * Workers that still active, i.e. are not shutting down gracefully.
         */
        int active_daemons;
        /*
         * 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
         * maintained per listeners bucket, doubled up to MAX_SPAWN_RATE, and
         * reset only when a cycle goes by without the need to spawn.
         */
        int *idle_spawn_rate;
    #ifndef MAX_SPAWN_RATE
    #define MAX_SPAWN_RATE        (32)
    #endif
        int hold_off_on_exponential_spawning;
    } event_retained_data;
    static event_retained_data *retained;
     
    typedef struct event_child_bucket {
        ap_pod_t *pod;
        ap_listen_rec *listeners;
    } event_child_bucket;
    static event_child_bucket *all_buckets, /* All listeners buckets */
                              *my_bucket;   /* Current child bucket */
    
    struct event_srv_cfg_s {
        struct timeout_queue *io_q,
                             *wc_q,
                             *ka_q;
    };
    
    #define ID_FROM_CHILD_THREAD(c, t)    ((c * thread_limit) + t)
    
    /* The event 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 apr_pool_t *pruntime;    /* Pool for MPM threads 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;
    
    static int ap_child_slot;       /* Current child process slot in scoreboard */
    
    /* 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 volatile apr_uint32_t listensocks_disabled;
    
    static void disable_listensocks(void)
    {
        int i;
        if (apr_atomic_cas32(&listensocks_disabled, 1, 0) != 0) {
            return;
        }
        if (event_pollset) {
            for (i = 0; i < num_listensocks; i++) {
                apr_pollset_remove(event_pollset, &listener_pollfd[i]);
            }
        }
        ap_scoreboard_image->parent[ap_child_slot].not_accepting = 1;
    }
    
    static void enable_listensocks(void)
    {
        int i;
        if (listener_may_exit
                || apr_atomic_cas32(&listensocks_disabled, 0, 1) != 1) {
            return;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00457)
                     "Accepting new connections again: "
                     "%u active conns (%u lingering/%u clogged/%u suspended), "
                     "%u idle workers",
                     apr_atomic_read32(&connection_count),
                     apr_atomic_read32(&lingering_count),
                     apr_atomic_read32(&clogged_count),
                     apr_atomic_read32(&suspended_count),
                     ap_queue_info_num_idlers(worker_queue_info));
        for (i = 0; i < num_listensocks; i++)
            apr_pollset_add(event_pollset, &listener_pollfd[i]);
        /*
         * XXX: This is not yet optimal. If many workers suddenly become available,
         * XXX: the parent may kill some processes off too soon.
         */
        ap_scoreboard_image->parent[ap_child_slot].not_accepting = 0;
    }
    
    static APR_INLINE apr_uint32_t listeners_disabled(void)
    {
        return apr_atomic_read32(&listensocks_disabled);
    }
    
    static APR_INLINE int connections_above_limit(int *busy)
    {
        apr_uint32_t i_count = ap_queue_info_num_idlers(worker_queue_info);
        if (i_count > 0) {
            apr_uint32_t c_count = apr_atomic_read32(&connection_count);
            apr_uint32_t l_count = apr_atomic_read32(&lingering_count);
            if (c_count <= l_count
                    /* Off by 'listeners_disabled()' to avoid flip flop */
                    || c_count - l_count < (apr_uint32_t)threads_per_child +
                                           (i_count - listeners_disabled()) *
                                           (worker_factor / WORKER_FACTOR_SCALE)) {
                return 0;
            }
        }
        else if (busy) {
            *busy = 1;
        }
        return 1;
    }
    
    static APR_INLINE int should_enable_listensocks(void)
    {
        return !dying && listeners_disabled() && !connections_above_limit(NULL);
    }
    
    static void close_socket_nonblocking_(apr_socket_t *csd,
                                          const char *from, int line)
    {
        apr_status_t rv;
        apr_os_sock_t fd = -1;
    
        /* close_worker_sockets() may have closed it already */
        rv = apr_os_sock_get(&fd, csd);
        ap_log_error(APLOG_MARK, APLOG_TRACE8, 0, ap_server_conf,
                    "closing socket %i/%pp from %s:%i", (int)fd, csd, from, line);
        if (rv == APR_SUCCESS && fd == -1) {
            return;
        }
    
        apr_socket_timeout_set(csd, 0);
        rv = apr_socket_close(csd);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00468)
                         "error closing socket");
            AP_DEBUG_ASSERT(0);
        }
    }
    #define close_socket_nonblocking(csd) \
        close_socket_nonblocking_(csd, __FUNCTION__, __LINE__)
    
    static void close_worker_sockets(void)
    {
        int i;
        for (i = 0; i < threads_per_child; i++) {
            apr_socket_t *csd = worker_sockets[i];
            if (csd) {
                worker_sockets[i] = NULL;
                close_socket_nonblocking(csd);
            }
        }
    }
    
    static void wakeup_listener(void)
    {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                     "wake up listener%s", listener_may_exit ? " again" : "");
    
        listener_may_exit = 1;
        disable_listensocks();
    
        /* Unblock the listener if it's poll()ing */
        if (event_pollset && listener_is_wakeable) {
            apr_pollset_wakeup(event_pollset);
        }
    
        /* unblock the listener if it's waiting for a worker */
        if (worker_queue_info) {
            ap_queue_info_term(worker_queue_info);
        }
    
        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;
        retained->mpm->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);
            close_worker_sockets(); /* forcefully kill all current connections */
        }
    
        ap_run_child_stopping(pchild, mode == ST_GRACEFUL);
    }
    
    static int event_query(int query_code, int *result, apr_status_t *rv)
    {
        *rv = APR_SUCCESS;
        switch (query_code) {
        case AP_MPMQ_MAX_DAEMON_USED:
            *result = retained->max_daemon_used;
            break;
        case AP_MPMQ_IS_THREADED:
            *result = AP_MPMQ_STATIC;
            break;
        case AP_MPMQ_IS_FORKED:
            *result = AP_MPMQ_DYNAMIC;
            break;
        case AP_MPMQ_IS_ASYNC:
            *result = 1;
            break;
        case AP_MPMQ_HARD_LIMIT_DAEMONS:
            *result = server_limit;
            break;
        case AP_MPMQ_HARD_LIMIT_THREADS:
            *result = thread_limit;
            break;
        case AP_MPMQ_MAX_THREADS:
            *result = threads_per_child;
            break;
        case AP_MPMQ_MIN_SPARE_DAEMONS:
            *result = 0;
            break;
        case AP_MPMQ_MIN_SPARE_THREADS:
            *result = min_spare_threads;
            break;
        case AP_MPMQ_MAX_SPARE_DAEMONS:
            *result = 0;
            break;
        case AP_MPMQ_MAX_SPARE_THREADS:
            *result = max_spare_threads;
            break;
        case AP_MPMQ_MAX_REQUESTS_DAEMON:
            *result = ap_max_requests_per_child;
            break;
        case AP_MPMQ_MAX_DAEMONS:
            *result = active_daemons_limit;
            break;
        case AP_MPMQ_MPM_STATE:
            *result = retained->mpm->mpm_state;
            break;
        case AP_MPMQ_GENERATION:
            *result = retained->mpm->my_generation;
            break;
        case AP_MPMQ_CAN_WAITIO:
            *result = 1;
            break;
        default:
            *rv = APR_ENOTIMPL;
            break;
        }
        return OK;
    }
    
    static void event_note_child_stopped(int slot, pid_t pid, ap_generation_t gen)
    {
        if (slot != -1) { /* child had a scoreboard slot? */
            process_score *ps = &ap_scoreboard_image->parent[slot];
            int i;
    
            pid = ps->pid;
            gen = ps->generation;
            for (i = 0; i < threads_per_child; i++) {
                ap_update_child_status_from_indexes(slot, i, SERVER_DEAD, NULL);
            }
            ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_EXITED);
            if (ps->quiescing != 2) { /* vs perform_idle_server_maintenance() */
                retained->active_daemons--;
            }
            retained->total_daemons--;
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                         "Child %d stopped: pid %d, gen %d, "
                         "active %d/%d, total %d/%d/%d, quiescing %d",
                         slot, (int)pid, (int)gen,
                         retained->active_daemons, active_daemons_limit,
                         retained->total_daemons, retained->max_daemon_used,
                         server_limit, ps->quiescing);
            ps->not_accepting = 0;
            ps->quiescing = 0;
            ps->pid = 0;
        }
        else {
            ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
        }
    }
    
    static void event_note_child_started(int slot, pid_t pid)
    {
        ap_generation_t gen = retained->mpm->my_generation;
    
        retained->total_daemons++;
        retained->active_daemons++;
        ap_scoreboard_image->parent[slot].pid = pid;
        ap_scoreboard_image->parent[slot].generation = gen;
        ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_STARTED);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                     "Child %d started: pid %d, gen %d, "
                     "active %d/%d, total %d/%d/%d",
                     slot, (int)pid, (int)gen,
                     retained->active_daemons, active_daemons_limit,
                     retained->total_daemons, retained->max_daemon_used,
                     server_limit);
    }
    
    static const char *event_get_name(void)
    {
        return "event";
    }
    
    /* 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)
    {
        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
        if (terminate_mode == ST_INIT) {
            ap_run_child_stopping(pchild, 0);
        }
    
        if (pchild) {
            apr_pool_destroy(pchild);
        }
    
        if (one_process) {
            event_note_child_stopped(/* slot */ 0, 0, 0);
        }
    
        exit(code);
    }
    
    static void just_die(int sig)
    {
        clean_child_exit(0);
    }
    
    /*****************************************************************
     * Connection structures and accounting...
     */
    
    static int child_fatal;
    
    static apr_status_t decrement_connection_count(void *cs_)
    {
        int is_last_connection;
        event_conn_state_t *cs = cs_;
        ap_log_cerror(APLOG_MARK, APLOG_TRACE8, 0, cs->c,
                      "cleanup connection from state %i", (int)cs->pub.state);
        switch (cs->pub.state) {
            case CONN_STATE_LINGER:
            case CONN_STATE_LINGER_NORMAL:
            case CONN_STATE_LINGER_SHORT:
                apr_atomic_dec32(&lingering_count);
                break;
            case CONN_STATE_SUSPENDED:
                apr_atomic_dec32(&suspended_count);
                break;
            default:
                break;
        }
        /* Unblock the listener if it's waiting for connection_count = 0,
         * or if the listening sockets were disabled due to limits and can
         * now accept new connections.
         */
        is_last_connection = !apr_atomic_dec32(&connection_count);
        if (listener_is_wakeable
                && ((is_last_connection && listener_may_exit)
                    || should_enable_listensocks())) {
            apr_pollset_wakeup(event_pollset);
        }
        if (dying) {
            /* Help worker_thread_should_exit_early() */
            ap_queue_interrupt_one(worker_queue);
        }
        return APR_SUCCESS;
    }
    
    static void notify_suspend(event_conn_state_t *cs)
    {
        ap_run_suspend_connection(cs->c, cs->r);
        cs->c->sbh = NULL;
        cs->suspended = 1;
    }
    
    static void notify_resume(event_conn_state_t *cs, int cleanup)
    {
        cs->suspended = 0;
        cs->c->sbh = cleanup ? NULL : cs->sbh;
        ap_run_resume_connection(cs->c, cs->r);
    }
    
    /*
     * Defer flush and close of the connection by adding it to defer_linger_chain,
     * for a worker to grab it and do the job (should that be blocking).
     * Pre-condition: nonblocking, can be called from anywhere provided cs is not
     *                in any timeout queue or in the pollset.
     */
    static int defer_lingering_close(event_conn_state_t *cs)
    {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, cs->c,
                      "deferring close from state %i", (int)cs->pub.state);
    
        /* The connection is not shutdown() yet strictly speaking, but it's not
         * in any queue nor handled by a worker either (will be very soon), so
         * to account for it somewhere we bump lingering_count now (and set
         * deferred_linger for process_lingering_close() to know).
         */
        cs->pub.state = CONN_STATE_LINGER;
        apr_atomic_inc32(&lingering_count);
        cs->deferred_linger = 1;
        for (;;) {
            event_conn_state_t *chain = cs->chain = defer_linger_chain;
            if (apr_atomic_casptr((void *)&defer_linger_chain, cs,
                                  chain) != chain) {
                /* Race lost, try again */
                continue;
            }
            return 1;
        }
    }
    
    /* Close the connection and release its resources (ptrans), either because an
     * unrecoverable error occured (queues or pollset add/remove) or more usually
     * if lingering close timed out.
     * Pre-condition: nonblocking, can be called from anywhere provided cs is not
     *                in any timeout queue or in the pollset.
     */
    static void close_connection(event_conn_state_t *cs)
    {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, cs->c,
                      "closing connection from state %i", (int)cs->pub.state);
    
        close_socket_nonblocking(cs->pfd.desc.s);
        ap_queue_info_push_pool(worker_queue_info, cs->p);
    }
    
    /* Shutdown the connection in case of timeout, error or resources shortage.
     * This starts short lingering close if not already there, or directly closes
     * the connection otherwise.
     * Pre-condition: nonblocking, can be called from anywhere provided cs is not
     *                in any timeout queue or in the pollset.
     */
    static int shutdown_connection(event_conn_state_t *cs)
    {
        if (!CONN_STATE_IS_LINGERING_CLOSE(cs->pub.state)) {
            apr_table_setn(cs->c->notes, "short-lingering-close", "1");
            defer_lingering_close(cs);
        }
        else {
            close_connection(cs);
        }
        return 1;
    }
    
    /*
     * This runs before any non-MPM cleanup code on the connection;
     * if the connection is currently suspended as far as modules
     * know, provide notification of resumption.
     */
    static apr_status_t ptrans_pre_cleanup(void *dummy)
    {
        event_conn_state_t *cs = dummy;
    
        if (cs->suspended) {
            notify_resume(cs, 1);
        }
        return APR_SUCCESS;
    }
    
    /*
     * event_pre_read_request() and event_request_cleanup() track the
     * current r for a given connection.
     */
    static apr_status_t event_request_cleanup(void *dummy)
    {
        conn_rec *c = dummy;
        event_conn_state_t *cs = ap_get_module_config(c->conn_config,
                                                      &mpm_event_module);
    
        cs->r = NULL;
        return APR_SUCCESS;
    }
    
    static void event_pre_read_request(request_rec *r, conn_rec *c)
    {
        event_conn_state_t *cs = ap_get_module_config(c->conn_config,
                                                      &mpm_event_module);
    
        cs->r = r;
        cs->sc = ap_get_module_config(ap_server_conf->module_config,
                                      &mpm_event_module);
        apr_pool_cleanup_register(r->pool, c, event_request_cleanup,
                                  apr_pool_cleanup_null);
    }
    
    /*
     * event_post_read_request() tracks the current server config for a
     * given request.
     */
    static int event_post_read_request(request_rec *r)
    {
        conn_rec *c = r->connection;
        event_conn_state_t *cs = ap_get_module_config(c->conn_config,
                                                      &mpm_event_module);
    
        /* To preserve legacy behaviour (consistent with other MPMs), use
         * the keepalive timeout from the base server (first on this IP:port)
         * when none is explicitly configured on this server.
         */
        if (r->server->keep_alive_timeout_set) {
            cs->sc = ap_get_module_config(r->server->module_config,
                                          &mpm_event_module);
        }
        else {
            cs->sc = ap_get_module_config(c->base_server->module_config,
                                          &mpm_event_module);
        }
        return OK;
    }
    
    /* Forward declare */
    static void process_lingering_close(event_conn_state_t *cs);
    
    static void update_reqevents_from_sense(event_conn_state_t *cs,
                                            int default_sense)
    {
        int sense = default_sense;
    
        if (cs->pub.sense != CONN_SENSE_DEFAULT) {
            sense = cs->pub.sense;
    
            /* Reset to default for the next round */
            cs->pub.sense = CONN_SENSE_DEFAULT;
        }
    
        if (sense == CONN_SENSE_WANT_READ) {
            cs->pfd.reqevents = APR_POLLIN | APR_POLLHUP;
        }
        else {
            cs->pfd.reqevents = APR_POLLOUT;
        }
        /* POLLERR is usually returned event only, but some pollset
         * backends may require it in reqevents to do the right thing,
         * so it shouldn't hurt (ignored otherwise).
         */
        cs->pfd.reqevents |= APR_POLLERR;
    }
    
    /*
     * process one connection in the worker
     */
    static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * sock,
                              event_conn_state_t * cs, int my_child_num,
                              int my_thread_num)
    {
        conn_rec *c;
        long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
        int clogging = 0;
        apr_status_t rv;
        int rc = OK;
    
        if (cs == NULL) {           /* This is a new connection */
            listener_poll_type *pt = apr_pcalloc(p, sizeof(*pt));
            cs = apr_pcalloc(p, sizeof(event_conn_state_t));
            cs->bucket_alloc = apr_bucket_alloc_create(p);
            ap_create_sb_handle(&cs->sbh, p, my_child_num, my_thread_num);
            c = ap_run_create_connection(p, ap_server_conf, sock,
                                         conn_id, cs->sbh, cs->bucket_alloc);
            if (!c) {
                ap_queue_info_push_pool(worker_queue_info, p);
                return;
            }
            apr_atomic_inc32(&connection_count);
            apr_pool_cleanup_register(c->pool, cs, decrement_connection_count,
                                      apr_pool_cleanup_null);
            ap_set_module_config(c->conn_config, &mpm_event_module, cs);
            c->current_thread = thd;
            c->cs = &cs->pub;
            cs->c = c;
            cs->p = p;
            cs->sc = ap_get_module_config(ap_server_conf->module_config,
                                          &mpm_event_module);
            cs->pfd.desc_type = APR_POLL_SOCKET;
            cs->pfd.desc.s = sock;
            pt->type = PT_CSD;
            pt->baton = cs;
            cs->pfd.client_data = pt;
            apr_pool_pre_cleanup_register(p, cs, ptrans_pre_cleanup);
            TO_QUEUE_ELEM_INIT(cs);
    
            ap_update_vhost_given_ip(c);
    
            rc = ap_pre_connection(c, sock);
            if (rc != OK && rc != DONE) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(00469)
                              "process_socket: connection aborted");
                close_connection(cs);
                return;
            }
    
            /**
             * 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
             * with the state set to CONN_STATE_KEEPALIVE
             *
             * 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->pub.state = CONN_STATE_PROCESSING;
            cs->pub.sense = CONN_SENSE_DEFAULT;
        }
        else {
            c = cs->c;
            ap_update_sb_handle(cs->sbh, my_child_num, my_thread_num);
            notify_resume(cs, 0);
            c->current_thread = thd;
            /* Subsequent request on a conn, and thread number is part of ID */
            c->id = conn_id;
        }
    
        if (CONN_STATE_IS_LINGERING_CLOSE(cs->pub.state)) {
            goto lingering_close;
        }
    
        if (cs->pub.state == CONN_STATE_PROCESSING
            /* If we have an input filter which 'clogs' the input stream,
             * like mod_ssl used to, lets just do the normal read from input
             * filters, like the Worker MPM does. Filters that need to write
             * where they would otherwise read, or read where they would
             * otherwise write, should set the sense appropriately.
             */
             || c->clogging_input_filters) {
     process_connection:
            cs->pub.state = CONN_STATE_PROCESSING;
    
            clogging = c->clogging_input_filters;
            if (clogging) {
                apr_atomic_inc32(&clogged_count);
            }
            rc = ap_run_process_connection(c);
            if (clogging) {
                apr_atomic_dec32(&clogged_count);
            }
            /*
             * The process_connection hooks should set the appropriate connection
             * state upon return, for event MPM to either:
             * - CONN_STATE_LINGER: do lingering close;
             * - CONN_STATE_WRITE_COMPLETION: flush pending outputs using Timeout
             *   and wait for next incoming data using KeepAliveTimeout, then come
             *   back to process_connection() hooks;
             * - CONN_STATE_SUSPENDED: suspend the connection such that it now
             *   interacts with the MPM through suspend/resume_connection() hooks,
             *   and/or registered poll callbacks (PT_USER), and/or registered
             *   timed callbacks triggered by timer events;
             * - CONN_STATE_ASYNC_WAITIO: wait for read/write-ability of the underlying
             *   socket using Timeout and come back to process_connection() hooks when
             *   ready;
             * - CONN_STATE_KEEPALIVE: now handled by CONN_STATE_WRITE_COMPLETION
             *   to flush before waiting for next data (that might depend on it).
             * If a process_connection hook returns an error or no hook sets the state
             * to one of the above expected value, forcibly close the connection w/
             * CONN_STATE_LINGER.  This covers the cases where no process_connection
             * hook executes (DECLINED), or one returns OK w/o touching the state (i.e.
             * CONN_STATE_PROCESSING remains after the call) which can happen with
             * third-party modules not updated to work specifically with event MPM
             * while this was expected to do lingering close unconditionally with
             * worker or prefork MPMs for instance.
             */
            switch (rc) {
            case DONE:
                rc = OK; /* same as OK, fall through */
            case OK:
                if (cs->pub.state == CONN_STATE_PROCESSING) {
                    cs->pub.state = CONN_STATE_LINGER;
                }
                else if (cs->pub.state == CONN_STATE_KEEPALIVE) {
                    cs->pub.state = CONN_STATE_WRITE_COMPLETION;
                }
                break;
            }
            if (rc != OK || (cs->pub.state != CONN_STATE_LINGER
                             && cs->pub.state != CONN_STATE_ASYNC_WAITIO
                             && cs->pub.state != CONN_STATE_WRITE_COMPLETION
                             && cs->pub.state != CONN_STATE_SUSPENDED)) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10111)
                              "process_socket: connection processing returned %i "
                              "(%sstate %i): closing",
                              rc, rc ? "" : "unexpected ", (int)cs->pub.state);
                cs->pub.state = CONN_STATE_LINGER;
            }
            else if (c->aborted) {
                cs->pub.state = CONN_STATE_LINGER;
            }
            if (cs->pub.state == CONN_STATE_LINGER) {
                goto lingering_close;
            }
        }
    
        if (cs->pub.state == CONN_STATE_ASYNC_WAITIO) {
            /* Set a read/write timeout for this connection, and let the
             * event thread poll for read/writeability.
             */
            cs->queue_timestamp = apr_time_now();
            notify_suspend(cs);
    
            ap_update_child_status(cs->sbh, SERVER_BUSY_READ, NULL);
    
            /* Modules might set c->cs->sense to CONN_SENSE_WANT_WRITE,
             * the default is CONN_SENSE_WANT_READ still.
             */
            update_reqevents_from_sense(cs, CONN_SENSE_WANT_READ);
            apr_thread_mutex_lock(timeout_mutex);
            TO_QUEUE_APPEND(cs->sc->io_q, cs);
            rv = apr_pollset_add(event_pollset, &cs->pfd);
            if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
                AP_DEBUG_ASSERT(0);
                TO_QUEUE_REMOVE(cs->sc->io_q, cs);
                apr_thread_mutex_unlock(timeout_mutex);
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(10503)
                             "process_socket: apr_pollset_add failure in "
                             "CONN_STATE_ASYNC_WAITIO");
                close_connection(cs);
                signal_threads(ST_GRACEFUL);
            }
            else {
                apr_thread_mutex_unlock(timeout_mutex);
            }
            return;
        }
    
        if (cs->pub.state == CONN_STATE_WRITE_COMPLETION) {
            ap_filter_t *output_filter = c->output_filters;
            apr_status_t rv;
    
            /* Flush all pending outputs before going to CONN_STATE_KEEPALIVE or
             * straight to CONN_STATE_PROCESSING if inputs are pending already.
             */
            
            ap_update_child_status(cs->sbh, SERVER_BUSY_WRITE, NULL);
            while (output_filter->next != NULL) {
                output_filter = output_filter->next;
            }
            rv = output_filter->frec->filter_func.out_func(output_filter, NULL);
            if (rv != APR_SUCCESS) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(00470)
                              "network write failure in core output filter");
                cs->pub.state = CONN_STATE_LINGER;
                goto lingering_close;
            }
            if (c->data_in_output_filters || cs->pub.sense == CONN_SENSE_WANT_READ) {
                /* Still in WRITE_COMPLETION_STATE:
                 * Set a read/write timeout for this connection, and let the
                 * event thread poll for read/writeability.
                 */
                cs->queue_timestamp = apr_time_now();
                notify_suspend(cs);
    
                /* Add work to pollset. */
                update_reqevents_from_sense(cs, CONN_SENSE_WANT_WRITE);
                apr_thread_mutex_lock(timeout_mutex);
                TO_QUEUE_APPEND(cs->sc->wc_q, cs);
                rv = apr_pollset_add(event_pollset, &cs->pfd);
                if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
                    AP_DEBUG_ASSERT(0);
                    TO_QUEUE_REMOVE(cs->sc->wc_q, cs);
                    apr_thread_mutex_unlock(timeout_mutex);
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03465)
                                 "process_socket: apr_pollset_add failure in "
                                 "CONN_STATE_WRITE_COMPLETION");
                    close_connection(cs);
                    signal_threads(ST_GRACEFUL);
                }
                else {
                    apr_thread_mutex_unlock(timeout_mutex);
                }
                return;
            }
            if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted) {
                cs->pub.state = CONN_STATE_LINGER;
                goto lingering_close;
            }
            if (c->data_in_input_filters) {
                goto process_connection;
            }
            if (listener_may_exit) {
                cs->pub.state = CONN_STATE_LINGER;
                goto lingering_close;
            }
    
            /* Fall through */
            cs->pub.state = CONN_STATE_KEEPALIVE;
        }
    
        if (cs->pub.state == CONN_STATE_KEEPALIVE) {
            ap_update_child_status(cs->sbh, SERVER_BUSY_KEEPALIVE, NULL);
    
            /* It greatly simplifies the logic to use a single timeout value per q
             * 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->queue_timestamp = apr_time_now();
            notify_suspend(cs);
    
            /* Add work to pollset. */
            cs->pub.sense = CONN_SENSE_DEFAULT;
            update_reqevents_from_sense(cs, CONN_SENSE_WANT_READ);
            apr_thread_mutex_lock(timeout_mutex);
            TO_QUEUE_APPEND(cs->sc->ka_q, cs);
            rv = apr_pollset_add(event_pollset, &cs->pfd);
            if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
                AP_DEBUG_ASSERT(0);
                TO_QUEUE_REMOVE(cs->sc->ka_q, cs);
                apr_thread_mutex_unlock(timeout_mutex);
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03093)
                             "process_socket: apr_pollset_add failure for "
                             "keep alive");
                close_connection(cs);
                signal_threads(ST_GRACEFUL);
            }
            else {
                apr_thread_mutex_unlock(timeout_mutex);
            }
            return;
        }
    
        if (cs->pub.state == CONN_STATE_SUSPENDED) {
            apr_atomic_inc32(&suspended_count);
            notify_suspend(cs);
            return;
        }
    
     lingering_close:
        /* CONN_STATE_LINGER[_*] fall through process_lingering_close() */
        process_lingering_close(cs);
    }
    
    /* conns_this_child has gone to zero or below.  See if the admin coded
       "MaxConnectionsPerChild 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) {
            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                         "Stopping process due to MaxConnectionsPerChild");
            signal_threads(ST_GRACEFUL);
        }
        /* keep going */
        conns_this_child = APR_INT32_MAX;
    }
    
    static int close_listeners(int *closed)
    {
        ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
                     "clos%s listeners (connection_count=%u)",
                     *closed ? "ed" : "ing", apr_atomic_read32(&connection_count));
        if (!*closed) {
            int i;
    
            ap_close_listeners_ex(my_bucket->listeners);
            *closed = 1; /* once */
    
            dying = 1;
            ap_scoreboard_image->parent[ap_child_slot].quiescing = 1;
            for (i = 0; i < threads_per_child; ++i) {
                ap_update_child_status_from_indexes(ap_child_slot, i,
                                                    SERVER_GRACEFUL, NULL);
            }
            /* wake up the main thread */
            kill(ap_my_pid, SIGTERM);
    
            ap_queue_info_free_idle_pools(worker_queue_info);
            ap_queue_interrupt_all(worker_queue);
    
            return 1;
        }
        return 0;
    }
    
    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 push_timer2worker(timer_event_t* te)
    {
        return ap_queue_push_timer(worker_queue, te);
    }
    
    /*
     * Pre-condition: cs is neither in event_pollset nor a timeout queue
     * this function may only be called by the listener
     */
    static apr_status_t push2worker(event_conn_state_t *cs, apr_socket_t *csd,
                                    apr_pool_t *ptrans)
    {
        apr_status_t rc;
    
        if (cs) {
            csd = cs->pfd.desc.s;
            ptrans = cs->p;
        }
        rc = ap_queue_push_socket(worker_queue, csd, cs, ptrans);
        if (rc != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf, APLOGNO(00471)
                         "push2worker: ap_queue_push_socket failed");
            /* trash the connection; we couldn't queue the connected
             * socket to a worker
             */
            if (cs) {
                shutdown_connection(cs);
            }
            else {
                if (csd) {
                    close_socket_nonblocking(csd);
                }
                if (ptrans) {
                    ap_queue_info_push_pool(worker_queue_info, ptrans);
                }
            }
            signal_threads(ST_GRACEFUL);
        }
    
        return rc;
    }
    
    /* get_worker:
     *     If *have_idle_worker_p == 0, reserve a worker thread, and set
     *     *have_idle_worker_p = 1.
     *     If *have_idle_worker_p is already 1, will do nothing.
     *     If blocking == 1, block if all workers are currently busy.
     *     If no worker was available immediately, will set *all_busy to 1.
     *     XXX: If there are no workers, we should not block immediately but
     *     XXX: close all keep-alive connections first.
     */
    static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy)
    {
        apr_status_t rc;
    
        if (*have_idle_worker_p) {
            /* already reserved a worker thread - must have hit a
             * transient error on a previous pass
             */
            return;
        }
    
        if (blocking)
            rc = ap_queue_info_wait_for_idler(worker_queue_info, all_busy);
        else
            rc = ap_queue_info_try_get_idler(worker_queue_info);
    
        if (rc == APR_SUCCESS || APR_STATUS_IS_EOF(rc)) {
            *have_idle_worker_p = 1;
        }
        else if (!blocking && rc == APR_EAGAIN) {
            *all_busy = 1;
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(00472)
                         "ap_queue_info_wait_for_idler failed.  "
                         "Attempting to shutdown process gracefully");
            signal_threads(ST_GRACEFUL);
        }
    }
    
    /* Structures to reuse */
    static timer_event_t timer_free_ring;
    
    static apr_skiplist *timer_skiplist;
    static volatile apr_time_t timers_next_expiry;
    
    /* Same goal as for TIMEOUT_FUDGE_FACTOR (avoid extra poll calls), but applied
     * to timers. Since their timeouts are custom (user defined), we can't be too
     * approximative here (hence using 0.01s).
     */
    #define EVENT_FUDGE_FACTOR apr_time_from_msec(10)
    
    /* The following compare function is used by apr_skiplist_insert() to keep the
     * elements (timers) sorted and provide O(log n) complexity (this is also true
     * for apr_skiplist_{find,remove}(), but those are not used in MPM event where
     * inserted timers are not searched nor removed, but with apr_skiplist_pop()
     * which does use any compare function).  It is meant to return 0 when a == b,
     * <0 when a < b, and >0 when a > b.  However apr_skiplist_insert() will not
     * add duplicates (i.e. a == b), and apr_skiplist_add() is only available in
     * APR 1.6, yet multiple timers could possibly be created in the same micro-
     * second (duplicates with regard to apr_time_t); therefore we implement the
     * compare function to return +1 instead of 0 when compared timers are equal,
     * thus duplicates are still added after each other (in order of insertion).
     */
    static int timer_comp(void *a, void *b)
    {
        apr_time_t t1 = (apr_time_t) ((timer_event_t *)a)->when;
        apr_time_t t2 = (apr_time_t) ((timer_event_t *)b)->when;
        AP_DEBUG_ASSERT(t1);
        AP_DEBUG_ASSERT(t2);
        return ((t1 < t2) ? -1 : 1);
    }
    
    static apr_thread_mutex_t *g_timer_skiplist_mtx;
    
    static apr_status_t event_register_timed_callback(apr_time_t t,
                                                      ap_mpm_callback_fn_t *cbfn,
                                                      void *baton)
    {
        timer_event_t *te;
        /* oh yeah, and make locking smarter/fine grained. */
        apr_thread_mutex_lock(g_timer_skiplist_mtx);
    
        if (!APR_RING_EMPTY(&timer_free_ring.link, timer_event_t, link)) {
            te = APR_RING_FIRST(&timer_free_ring.link);
            APR_RING_REMOVE(te, link);
        }
        else {
            te = apr_skiplist_alloc(timer_skiplist, sizeof(timer_event_t));
            APR_RING_ELEM_INIT(te, link);
        }
    
        te->cbfunc = cbfn;
        te->baton = baton;
        /* XXXXX: optimize */
        te->when = t + apr_time_now();
    
        { 
            apr_time_t next_expiry;
    
            /* Okay, add sorted by when.. */
            apr_skiplist_insert(timer_skiplist, te);
    
            /* Cheaply update the global timers_next_expiry with this event's
             * if it expires before.
             */
            next_expiry = timers_next_expiry;
            if (!next_expiry || next_expiry > te->when + EVENT_FUDGE_FACTOR) {
                timers_next_expiry = te->when;
                /* Unblock the poll()ing listener for it to update its timeout. */
                if (listener_is_wakeable) {
                    apr_pollset_wakeup(event_pollset);
                }
            }
        }
    
        apr_thread_mutex_unlock(g_timer_skiplist_mtx);
    
        return APR_SUCCESS;
    }
    
    
    /*
     * Flush data and close our side of the connection, then drain incoming data.
     * If the latter would block put the connection in one of the linger timeout
     * queues to be called back when ready, and repeat until it's closed by peer.
     * Only to be called in the worker thread, and since it's in immediate call
     * stack, we can afford a comfortable buffer size to consume data quickly.
     * Pre-condition: cs is not in any timeout queue and not in the pollset,
     *                timeout_mutex is not locked
     */
    #define LINGERING_BUF_SIZE (32 * 1024)
    static void process_lingering_close(event_conn_state_t *cs)
    {
        apr_socket_t *csd = ap_get_conn_socket(cs->c);
        char dummybuf[LINGERING_BUF_SIZE];
        apr_size_t nbytes;
        apr_status_t rv;
        struct timeout_queue *q;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, cs->c,
                      "lingering close from state %i", (int)cs->pub.state);
        AP_DEBUG_ASSERT(CONN_STATE_IS_LINGERING_CLOSE(cs->pub.state));
    
        if (!cs->linger_started) {
            cs->pub.state = CONN_STATE_LINGER;
            cs->linger_started = 1;
    
            /* defer_lingering_close() may have bumped lingering_count already */
            if (!cs->deferred_linger) {
                apr_atomic_inc32(&lingering_count);
            }
    
            apr_socket_timeout_set(csd, apr_time_from_sec(SECONDS_TO_LINGER));
            if (ap_start_lingering_close(cs->c)) {
                notify_suspend(cs);
                close_connection(cs);
                return;
            }
            
            /* All nonblocking from now, no need for APR_INCOMPLETE_READ either */
            apr_socket_timeout_set(csd, 0);
            apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 0);
    
            /*
             * If some module requested a shortened waiting period, only wait for
             * 2s (SECONDS_TO_LINGER). This is useful for mitigating certain
             * DoS attacks.
             */
            if (apr_table_get(cs->c->notes, "short-lingering-close")) {
                cs->pub.state = CONN_STATE_LINGER_SHORT;
            }
            else {
                cs->pub.state = CONN_STATE_LINGER_NORMAL;
            }
            cs->pub.sense = CONN_SENSE_DEFAULT;
            notify_suspend(cs);
    
            /* One timestamp/duration for the whole lingering close time.
             * XXX: This makes the (short_)linger_q not sorted/ordered by expiring
             * timeouts whenever multiple schedules are necessary (EAGAIN below),
             * but we probabaly don't care since these connections do not count
             * for connections_above_limit() and all of them will be killed when
             * busy or gracefully stopping anyway.
             */
            cs->queue_timestamp = apr_time_now();
        }
    
        do {
            nbytes = sizeof(dummybuf);
            rv = apr_socket_recv(csd, dummybuf, &nbytes);
        } while (rv == APR_SUCCESS);
    
        if (!APR_STATUS_IS_EAGAIN(rv)) {
            close_connection(cs);
            return;
        }
    
        /* (Re)queue the connection to come back when readable */
        update_reqevents_from_sense(cs, CONN_SENSE_WANT_READ);
        q = (cs->pub.state == CONN_STATE_LINGER_SHORT) ? short_linger_q : linger_q;
        apr_thread_mutex_lock(timeout_mutex);
        TO_QUEUE_APPEND(q, cs);
        rv = apr_pollset_add(event_pollset, &cs->pfd);
        if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
            AP_DEBUG_ASSERT(0);
            TO_QUEUE_REMOVE(q, cs);
            apr_thread_mutex_unlock(timeout_mutex);
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03092)
                         "process_lingering_close: apr_pollset_add failure");
            close_connection(cs);
            signal_threads(ST_GRACEFUL);
            return;
        }
        apr_thread_mutex_unlock(timeout_mutex);
    }
    
    /* call 'func' for all elements of 'q' above 'expiry'.
     * Pre-condition: timeout_mutex must already be locked
     * Post-condition: timeout_mutex will be locked again
     */
    static void process_timeout_queue(struct timeout_queue *q, apr_time_t expiry,
                                      int (*func)(event_conn_state_t *))
    {
        apr_uint32_t total = 0, count;
        event_conn_state_t *first, *cs, *last;
        struct event_conn_state_t trash;
        struct timeout_queue *qp;
        apr_status_t rv;
    
        if (!*q->total) {
            return;
        }
    
        APR_RING_INIT(&trash.timeout_list, event_conn_state_t, timeout_list);
        for (qp = q; qp; qp = qp->next) {
            count = 0;
            cs = first = last = APR_RING_FIRST(&qp->head);
            while (cs != APR_RING_SENTINEL(&qp->head, event_conn_state_t,
                                           timeout_list)) {
                /* Trash the entry if:
                 * - no expiry was given (zero means all), or
                 * - it expired (according to the queue timeout), or
                 * - the system clock skewed in the past: no entry should be
                 *   registered above the given expiry (~now) + the queue
                 *   timeout, we won't keep any here (eg. for centuries).
                 *
                 * Otherwise stop, no following entry will match thanks to the
                 * single timeout per queue (entries are added to the end!).
                 * This allows maintenance in O(1).
                 */
                if (expiry && cs->queue_timestamp + qp->timeout > expiry
                           && cs->queue_timestamp < expiry + qp->timeout) {
                    /* Since this is the next expiring entry of this queue, update
                     * the global queues_next_expiry if it's later than this one.
                     */
                    apr_time_t elem_expiry = cs->queue_timestamp + qp->timeout;
                    apr_time_t next_expiry = queues_next_expiry;
                    if (!next_expiry
                            || next_expiry > elem_expiry + TIMEOUT_FUDGE_FACTOR) {
                        queues_next_expiry = elem_expiry;
                    }
                    break;
                }
    
                last = cs;
                rv = apr_pollset_remove(event_pollset, &cs->pfd);
                if (rv != APR_SUCCESS && !APR_STATUS_IS_NOTFOUND(rv)) {
                    AP_DEBUG_ASSERT(0);
                    ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, cs->c, APLOGNO(00473)
                                  "apr_pollset_remove failed");
                }
                cs = APR_RING_NEXT(cs, timeout_list);
                count++;
            }
            if (!count)
                continue;
    
            APR_RING_UNSPLICE(first, last, timeout_list);
            APR_RING_SPLICE_TAIL(&trash.timeout_list, first, last, event_conn_state_t,
                                 timeout_list);
            AP_DEBUG_ASSERT(*q->total >= count && qp->count >= count);
            *q->total -= count;
            qp->count -= count;
            total += count;
        }
        if (!total)
            return;
    
        apr_thread_mutex_unlock(timeout_mutex);
        first = APR_RING_FIRST(&trash.timeout_list);
        do {
            cs = APR_RING_NEXT(first, timeout_list);
            TO_QUEUE_ELEM_INIT(first);
            func(first);
            first = cs;
        } while (--total);
        apr_thread_mutex_lock(timeout_mutex);
    }
    
    static void process_keepalive_queue(apr_time_t expiry)
    {
        /* If all workers are busy, we kill older keep-alive connections so
         * that they may connect to another process.
         */
        if (!expiry && *keepalive_q->total) {
            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                         "All workers are busy or dying, will shutdown %u "
                         "keep-alive connections", *keepalive_q->total);
        }
        process_timeout_queue(keepalive_q, expiry, shutdown_connection);
    }
    
    static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
    {
        apr_status_t rc;
        proc_info *ti = dummy;
        int process_slot = ti->pslot;
        struct process_score *ps = ap_get_scoreboard_process(process_slot);
        int closed = 0;
        int have_idle_worker = 0;
        apr_time_t last_log;
    
        last_log = apr_time_now();
        free(ti);
    
        /* Unblock the signal used to wake this thread up, and set a handler for
         * it.
         */
        apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
        unblock_signal(LISTENER_SIGNAL);
    
        for (;;) {
            timer_event_t *te;
            const apr_pollfd_t *out_pfd;
            apr_int32_t num = 0;
            apr_interval_time_t timeout;
            apr_time_t now, expiry = -1;
            int workers_were_busy = 0;
    
            if (conns_this_child <= 0)
                check_infinite_requests();
    
            if (listener_may_exit) {
                int first_close = close_listeners(&closed);
    
                if (terminate_mode == ST_UNGRACEFUL
                    || apr_atomic_read32(&connection_count) == 0)
                    break;
    
                /* Don't wait in poll() for the first close (i.e. dying now), we
                 * want to maintain the queues and schedule defer_linger_chain ASAP
                 * to kill kept-alive connection and shutdown the workers and child
                 * faster.
                 */
                if (first_close) {
                    goto do_maintenance; /* with expiry == -1 */
                }
            }
    
            now = apr_time_now();
            if (APLOGtrace6(ap_server_conf)) {
                /* trace log status every second */
                if (now - last_log > apr_time_from_sec(1)) {
                    ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf,
                                 "connections: %u (waitio:%u write-completion:%u"
                                 "keep-alive:%u lingering:%u suspended:%u clogged:%u), "
                                 "workers: %u/%u shutdown",
                                 apr_atomic_read32(&connection_count),
                                 apr_atomic_read32(waitio_q->total),
                                 apr_atomic_read32(write_completion_q->total),
                                 apr_atomic_read32(keepalive_q->total),
                                 apr_atomic_read32(&lingering_count),
                                 apr_atomic_read32(&suspended_count),
                                 apr_atomic_read32(&clogged_count),
                                 apr_atomic_read32(&threads_shutdown),
                                 threads_per_child);
                    last_log = now;
                }
            }
    
            /* Start with an infinite poll() timeout and update it according to
             * the next expiring timer or queue entry. If there are none, either
             * the listener is wakeable and it can poll() indefinitely until a wake
             * up occurs, otherwise periodic checks (maintenance, shutdown, ...)
             * must be performed.
             */
            now = apr_time_now();
            timeout = -1;
    
            /* Push expired timers to a worker, the first remaining one determines
             * the maximum time to poll() below, if any.
             */
            expiry = timers_next_expiry;
            if (expiry && expiry < now) {
                apr_thread_mutex_lock(g_timer_skiplist_mtx);
                while ((te = apr_skiplist_peek(timer_skiplist))) {
                    if (te->when > now) {
                        timers_next_expiry = te->when;
                        timeout = te->when - now;
                        break;
                    }
                    apr_skiplist_pop(timer_skiplist, NULL);
                    push_timer2worker(te);
                }
                if (!te) {
                    timers_next_expiry = 0;
                }
                apr_thread_mutex_unlock(g_timer_skiplist_mtx);
            }
    
            /* Same for queues, use their next expiry, if any. */
            expiry = queues_next_expiry;
            if (expiry
                    && (timeout < 0
                        || expiry <= now
                        || timeout > expiry - now)) {
                timeout = expiry > now ? expiry - now : 0;
            }
    
            /* When non-wakeable, don't wait more than 100 ms, in any case. */
    #define NON_WAKEABLE_POLL_TIMEOUT apr_time_from_msec(100)
            if (!listener_is_wakeable
                    && (timeout < 0
                        || timeout > NON_WAKEABLE_POLL_TIMEOUT)) {
                timeout = NON_WAKEABLE_POLL_TIMEOUT;
            }
            else if (timeout > 0) {
                /* apr_pollset_poll() might round down the timeout to milliseconds,
                 * let's forcibly round up here to never return before the timeout.
                 */
                timeout = apr_time_from_msec(
                    apr_time_as_msec(timeout + apr_time_from_msec(1) - 1)
                );
            }
    
            ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, ap_server_conf,
                         "polling with timeout=%" APR_TIME_T_FMT
                         " queues_timeout=%" APR_TIME_T_FMT
                         " timers_timeout=%" APR_TIME_T_FMT,
                         timeout, queues_next_expiry - now,
                         timers_next_expiry - now);
    
            rc = apr_pollset_poll(event_pollset, timeout, &num, &out_pfd);
            if (rc != APR_SUCCESS) {
                if (!APR_STATUS_IS_EINTR(rc) && !APR_STATUS_IS_TIMEUP(rc)) {
                    ap_log_error(APLOG_MARK, APLOG_CRIT, rc, ap_server_conf,
                                 "apr_pollset_poll failed.  Attempting to "
                                 "shutdown process gracefully");
                    signal_threads(ST_GRACEFUL);
                }
                num = 0;
            }
    
            if (APLOGtrace7(ap_server_conf)) {
                now = apr_time_now();
                ap_log_error(APLOG_MARK, APLOG_TRACE7, rc, ap_server_conf,
                             "polled with num=%u exit=%d/%d conns=%d"
                             " queues_timeout=%" APR_TIME_T_FMT
                             " timers_timeout=%" APR_TIME_T_FMT,
                             num, listener_may_exit, dying,
                             apr_atomic_read32(&connection_count),
                             queues_next_expiry - now, timers_next_expiry - now);
            }
    
            /* XXX possible optimization: stash the current time for use as
             * r->request_time for new requests or queues maintenance
             */
    
            for (; num; --num, ++out_pfd) {
                listener_poll_type *pt = (listener_poll_type *) out_pfd->client_data;
                if (pt->type == PT_CSD) {
                    /* one of the sockets is readable */
                    event_conn_state_t *cs = (event_conn_state_t *) pt->baton;
                    struct timeout_queue *remove_from_q = NULL;
                    /* don't wait for a worker for a keepalive request or
                     * lingering close processing. */
                    int blocking = 0;
    
                    switch (cs->pub.state) {
                    case CONN_STATE_WRITE_COMPLETION:
                        remove_from_q = cs->sc->wc_q;
                        blocking = 1;
                        break;
    
                    case CONN_STATE_ASYNC_WAITIO:
                        cs->pub.state = CONN_STATE_PROCESSING;
                        remove_from_q = cs->sc->io_q;
                        blocking = 1;
                        break;
    
                    case CONN_STATE_KEEPALIVE:
                        cs->pub.state = CONN_STATE_PROCESSING;
                        remove_from_q = cs->sc->ka_q;
                        break;
    
                    case CONN_STATE_LINGER_NORMAL:
                        remove_from_q = linger_q;
                        break;
    
                    case CONN_STATE_LINGER_SHORT:
                        remove_from_q = short_linger_q;
                        break;
    
                    default:
                        ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
                                     ap_server_conf, APLOGNO(03096)
                                     "event_loop: unexpected state %d",
                                     cs->pub.state);
                        ap_assert(0);
                    }
    
                    if (remove_from_q) {
                        apr_thread_mutex_lock(timeout_mutex);
                        TO_QUEUE_REMOVE(remove_from_q, cs);
                        rc = apr_pollset_remove(event_pollset, &cs->pfd);
                        apr_thread_mutex_unlock(timeout_mutex);
                        /*
                         * 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 && !APR_STATUS_IS_NOTFOUND(rc)) {
                            AP_DEBUG_ASSERT(0);
                            ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf,
                                         APLOGNO(03094) "pollset remove failed");
                            close_connection(cs);
                            signal_threads(ST_GRACEFUL);
                            break;
                        }
    
                        /* If we don't get a worker immediately (nonblocking), we
                         * close the connection; the client can re-connect to a
                         * different process for keepalive, and for lingering close
                         * the connection will be shutdown so the choice is to favor
                         * incoming/alive connections.
                         */
                        get_worker(&have_idle_worker, blocking,
                                   &workers_were_busy);
                        if (!have_idle_worker) {
                            shutdown_connection(cs);
                        }
                        else if (push2worker(cs, NULL, NULL) == APR_SUCCESS) {
                            have_idle_worker = 0;
                        }
                    }
                }
                else if (pt->type == PT_ACCEPT && !listeners_disabled()) {
                    /* A Listener Socket is ready for an accept() */
                    if (workers_were_busy) {
                        disable_listensocks();
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                                     "All workers busy, not accepting new conns "
                                     "in this process");
                    }
                    else if (connections_above_limit(&workers_were_busy)) {
                        disable_listensocks();
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                                     "Too many open connections (%u), "
                                     "not accepting new conns in this process",
                                     apr_atomic_read32(&connection_count));
                        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                                     "Idle workers: %u",
                                     ap_queue_info_num_idlers(worker_queue_info));
                    }
                    else if (!listener_may_exit) {
                        void *csd = NULL;
                        ap_listen_rec *lr = (ap_listen_rec *) pt->baton;
                        apr_pool_t *ptrans;         /* Pool for per-transaction stuff */
                        ap_queue_info_pop_pool(worker_queue_info, &ptrans);
    
                        if (ptrans == NULL) {
                            /* create a new transaction pool for each accepted socket */
                            apr_allocator_t *allocator = NULL;
    
                            rc = apr_allocator_create(&allocator);
                            if (rc == APR_SUCCESS) {
                                apr_allocator_max_free_set(allocator,
                                                           ap_max_mem_free);
                                rc = apr_pool_create_ex(&ptrans, pconf, NULL,
                                                        allocator);
                                if (rc == APR_SUCCESS) {
                                    apr_pool_tag(ptrans, "transaction");
                                    apr_allocator_owner_set(allocator, ptrans);
                                }
                            }
                            if (rc != APR_SUCCESS) {
                                ap_log_error(APLOG_MARK, APLOG_CRIT, rc,
                                             ap_server_conf, APLOGNO(03097)
                                             "Failed to create transaction pool");
                                if (allocator) {
                                    apr_allocator_destroy(allocator);
                                }
                                resource_shortage = 1;
                                signal_threads(ST_GRACEFUL);
                                continue;
                            }
                        }
    
                        get_worker(&have_idle_worker, 1, &workers_were_busy);
                        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) {
                            conns_this_child--;
                            if (push2worker(NULL, csd, ptrans) == APR_SUCCESS) {
                                have_idle_worker = 0;
                            }
                        }
                        else {
                            ap_queue_info_push_pool(worker_queue_info, ptrans);
                        }
                    }
                }               /* if:else on pt->type */
            } /* for processing poll */
    
            /* We process the timeout queues here only when the global
             * queues_next_expiry is passed. This happens accurately since
             * adding to the queues (in workers) can only decrease this expiry,
             * while latest ones are only taken into account here (in listener)
             * during queues' processing, with the lock held. This works both
             * with and without wake-ability.
             */
            expiry = queues_next_expiry;
    do_maintenance:
            if (expiry && expiry < (now = apr_time_now())) {
                ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, ap_server_conf,
                             "queues maintenance with timeout=%" APR_TIME_T_FMT,
                             expiry > 0 ? expiry - now : -1);
                apr_thread_mutex_lock(timeout_mutex);
    
                /* Steps below will recompute this. */
                queues_next_expiry = 0;
    
                /* Step 1: keepalive queue timeouts are closed */
                if (workers_were_busy || dying) {
                    process_keepalive_queue(0); /* kill'em all \m/ */
                }
                else {
                    process_keepalive_queue(now);
                }
    
                /* Step 2: waitio queue timeouts are flushed */
                process_timeout_queue(waitio_q, now, defer_lingering_close);
    
                /* Step 3: write completion queue timeouts are flushed */
                process_timeout_queue(write_completion_q, now, defer_lingering_close);
    
                /* Step 4: normal lingering close queue timeouts are closed */
                if (dying && linger_q->timeout > short_linger_q->timeout) {
                    /* Dying, force short timeout for normal lingering close */
                    linger_q->timeout = short_linger_q->timeout;
                }
                process_timeout_queue(linger_q, now, shutdown_connection);
    
                /* Step 5: short lingering close queue timeouts are closed */
                process_timeout_queue(short_linger_q, now, shutdown_connection);
    
                apr_thread_mutex_unlock(timeout_mutex);
                ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, ap_server_conf,
                             "queues maintained with timeout=%" APR_TIME_T_FMT,
                             queues_next_expiry > now ? queues_next_expiry - now
                                                      : -1);
    
                ps->wait_io = apr_atomic_read32(waitio_q->total);
                ps->write_completion = apr_atomic_read32(write_completion_q->total);
                ps->keep_alive = apr_atomic_read32(keepalive_q->total);
                ps->lingering_close = apr_atomic_read32(&lingering_count);
                ps->suspended = apr_atomic_read32(&suspended_count);
                ps->connections = apr_atomic_read32(&connection_count);
            }
            else if ((workers_were_busy || dying)
                     && apr_atomic_read32(keepalive_q->total)) {
                apr_thread_mutex_lock(timeout_mutex);
                process_keepalive_queue(0); /* kill'em all \m/ */
                apr_thread_mutex_unlock(timeout_mutex);
                ps->keep_alive = 0;
            }
    
            /* If there are some lingering closes to defer (to a worker), schedule
             * them now. We might wakeup a worker spuriously if another one empties
             * defer_linger_chain in the meantime, but there also may be no active
             * or all busy workers for an undefined time.  In any case a deferred
             * lingering close can't starve if we do that here since the chain is
             * filled only above in the listener and it's emptied only in the
             * worker(s); thus a NULL here means it will stay so while the listener
             * waits (possibly indefinitely) in poll().
             */
            if (defer_linger_chain) {
                get_worker(&have_idle_worker, 0, &workers_were_busy);
                if (have_idle_worker
                        && defer_linger_chain /* re-test */
                        && push2worker(NULL, NULL, NULL) == APR_SUCCESS) {
                    have_idle_worker = 0;
                }
            }
    
            if (!workers_were_busy && should_enable_listensocks()) {
                enable_listensocks();
            }
        } /* listener main loop */
    
        ap_queue_term(worker_queue);
    
        apr_thread_exit(thd, APR_SUCCESS);
        return NULL;
    }
    
    /*
     * During graceful shutdown, if there are more running worker threads than
     * open connections, exit one worker thread.
     *
     * return 1 if thread should exit, 0 if it should continue running.
     */
    static int worker_thread_should_exit_early(void)
    {
        for (;;) {
            apr_uint32_t conns = apr_atomic_read32(&connection_count);
            apr_uint32_t dead = apr_atomic_read32(&threads_shutdown);
            apr_uint32_t newdead;
    
            AP_DEBUG_ASSERT(dead <= threads_per_child);
            if (conns >= threads_per_child - dead)
                return 0;
    
            newdead = dead + 1;
            if (apr_atomic_cas32(&threads_shutdown, newdead, dead) == dead) {
                /*
                 * No other thread has exited in the mean time, safe to exit
                 * this one.
                 */
                return 1;
            }
        }
    }
    
    /* 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->pslot;
        int thread_slot = ti->tslot;
        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].tid = apr_os_thread_current();
        ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->mpm->my_generation;
        ap_update_child_status_from_indexes(process_slot, thread_slot,
                                            SERVER_STARTING, NULL);
    
        for (;;) {
            apr_socket_t *csd = NULL;
            event_conn_state_t *cs;
            timer_event_t *te = NULL;
            apr_pool_t *ptrans;         /* Pool for per-transaction stuff */
    
            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;
                }
                /* A new idler may have changed connections_above_limit(),
                 * let the listener know and decide.
                 */
                if (listener_is_wakeable && should_enable_listensocks()) {
                    apr_pollset_wakeup(event_pollset);
                }
                is_idle = 1;
            }
    
            ap_update_child_status_from_indexes(process_slot, thread_slot,
                                                dying ? SERVER_GRACEFUL
                                                      : SERVER_READY, NULL);
          worker_pop:
            if (workers_may_exit) {
                break;
            }
            if (dying && worker_thread_should_exit_early()) {
                break;
            }
    
            rv = ap_queue_pop_something(worker_queue, &csd, (void **)&cs,
                                        &ptrans, &te);
    
            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,
                                 APLOGNO(03099) "ap_queue_pop_socket failed");
                }
                continue;
            }
            if (te != NULL) {
                te->cbfunc(te->baton);
    
                {
                    apr_thread_mutex_lock(g_timer_skiplist_mtx);
                    APR_RING_INSERT_TAIL(&timer_free_ring.link, te, timer_event_t, link);
                    apr_thread_mutex_unlock(g_timer_skiplist_mtx);
                }
            }
            else {
                is_idle = 0;
                if (csd != NULL) {
                    worker_sockets[thread_slot] = csd;
                    process_socket(thd, ptrans, csd, cs, process_slot, thread_slot);
                    worker_sockets[thread_slot] = NULL;
                }
            }
    
            /* If there are deferred lingering closes, handle them now. */
            while (!workers_may_exit) {
                cs = defer_linger_chain;
                if (!cs) {
                    break;
                }
                if (apr_atomic_casptr((void *)&defer_linger_chain, cs->chain,
                                      cs) != cs) {
                    /* Race lost, try again */
                    continue;
                }
                cs->chain = NULL;
                AP_DEBUG_ASSERT(cs->pub.state == CONN_STATE_LINGER);
    
                worker_sockets[thread_slot] = csd = cs->pfd.desc.s;
                process_socket(thd, cs->p, csd, cs, process_slot, thread_slot);
                worker_sockets[thread_slot] = NULL;
            }
        }
    
        ap_update_child_status_from_indexes(process_slot, thread_slot,
                                            dying ? SERVER_DEAD
                                                  : SERVER_GRACEFUL, 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 *) ap_malloc(sizeof(proc_info));
        my_info->pslot = my_child_num;
        my_info->tslot = -1;      /* listener thread doesn't have a thread slot */
        rv = ap_thread_create(&ts->listener, thread_attr, listener_thread,
                              my_info, pruntime);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(00474)
                         "ap_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);
    }
    
    static void setup_threads_runtime(void)
    {
        apr_status_t rv;
        ap_listen_rec *lr;
        apr_pool_t *pskip = NULL;
        int max_recycled_pools = -1, i;
        const int good_methods[] = { APR_POLLSET_KQUEUE,
                                     APR_POLLSET_PORT,
                                     APR_POLLSET_EPOLL };
        /* XXX: K-A or lingering close connection included in the async factor */
        const apr_uint32_t async_factor = worker_factor / WORKER_FACTOR_SCALE;
        const apr_uint32_t pollset_size = (apr_uint32_t)num_listensocks +
                                          (apr_uint32_t)threads_per_child *
                                          (async_factor > 2 ? async_factor : 2);
        int pollset_flags;
    
        /* Event's skiplist operations will happen concurrently with other modules'
         * runtime so they need their own pool for allocations, and its lifetime
         * should be at least the one of the connections (ptrans). Thus pskip is
         * created as a subpool of pconf like/before ptrans (before so that it's
         * destroyed after). In forked mode pconf is never destroyed so we are good
         * anyway, but in ONE_PROCESS mode this ensures that the skiplist works
         * from connection/ptrans cleanups (even after pchild is destroyed).
         */
        apr_pool_create(&pskip, pconf);
        apr_pool_tag(pskip, "mpm_skiplist");
        apr_thread_mutex_create(&g_timer_skiplist_mtx, APR_THREAD_MUTEX_DEFAULT, pskip);
        APR_RING_INIT(&timer_free_ring.link, timer_event_t, link);
        apr_skiplist_init(&timer_skiplist, pskip);
        apr_skiplist_set_compare(timer_skiplist, timer_comp, timer_comp);
    
        /* All threads (listener, workers) and synchronization objects (queues,
         * pollset, mutexes...) created here should have at least the lifetime of
         * the connections they handle (i.e. ptrans). We can't use this thread's
         * self pool because all these objects survive it, nor use pchild or pconf
         * directly because this starter thread races with other modules' runtime,
         * nor finally pchild (or subpool thereof) because it is killed explicitly
         * before pconf (thus connections/ptrans can live longer, which matters in
         * ONE_PROCESS mode). So this leaves us with a subpool of pconf, created
         * before any ptrans hence destroyed after.
         */
        apr_pool_create(&pruntime, pconf);
        apr_pool_tag(pruntime, "mpm_runtime");
    
        /* We must create the fd queues before we start up the listener
         * and worker threads. */
        rv = ap_queue_create(&worker_queue, threads_per_child, pruntime);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03100)
                         "ap_queue_create() failed");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED) {
            /* If we want to conserve memory, let's not keep an unlimited number of
             * pools & allocators.
             * XXX: This should probably be a separate config directive
             */
            max_recycled_pools = threads_per_child * 3 / 4 ;
        }
        rv = ap_queue_info_create(&worker_queue_info, pruntime,
                                  threads_per_child, max_recycled_pools);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03101)
                         "ap_queue_info_create() failed");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        /* Create the timeout mutex and main pollset before the listener
         * thread starts.
         */
        rv = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT,
                                     pruntime);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03102)
                         "creation of the timeout mutex failed.");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        /* Create the main pollset. When APR_POLLSET_WAKEABLE is asked we account
         * for the wakeup pipe explicitely with pollset_size+1 because some pollset
         * implementations don't do it implicitely in APR.
         */
        pollset_flags = APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY |
                        APR_POLLSET_WAKEABLE | APR_POLLSET_NODEFAULT;
        for (i = 0; i < sizeof(good_methods) / sizeof(good_methods[0]); i++) {
            rv = apr_pollset_create_ex(&event_pollset, pollset_size + 1, pruntime,
                                       pollset_flags, good_methods[i]);
            if (rv == APR_SUCCESS) {
                listener_is_wakeable = 1;
                break;
            }
        }
        if (rv != APR_SUCCESS) {
            pollset_flags &= ~APR_POLLSET_NODEFAULT;
            rv = apr_pollset_create(&event_pollset, pollset_size + 1, pruntime,
                                    pollset_flags);
            if (rv == APR_SUCCESS) {
                listener_is_wakeable = 1;
            }
            else {
                pollset_flags &= ~APR_POLLSET_WAKEABLE;
                rv = apr_pollset_create(&event_pollset, pollset_size, pruntime,
                                        pollset_flags);
            }
        }
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(03103)
                         "apr_pollset_create with Thread Safety failed.");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        /* Add listeners to the main pollset */
        listener_pollfd = apr_pcalloc(pruntime, num_listensocks *
                                                sizeof(apr_pollfd_t));
        for (i = 0, lr = my_bucket->listeners; lr; lr = lr->next, i++) {
            apr_pollfd_t *pfd;
            listener_poll_type *pt;
    
            AP_DEBUG_ASSERT(i < num_listensocks);
            pfd = &listener_pollfd[i];
    
            pfd->reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;
            pfd->desc_type = APR_POLL_SOCKET;
            pfd->desc.s = lr->sd;
    
            pt = apr_pcalloc(pruntime, sizeof(*pt));
            pfd->client_data = pt;
            pt->type = PT_ACCEPT;
            pt->baton = lr;
    
            apr_socket_opt_set(pfd->desc.s, APR_SO_NONBLOCK, 1);
            apr_pollset_add(event_pollset, pfd);
    
            lr->accept_func = ap_unixd_accept;
        }
    
        worker_sockets = apr_pcalloc(pruntime, threads_per_child *
                                               sizeof(apr_socket_t *));
    }
    
    /* 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 my_child_num = ts->child_num_arg;
        proc_info *my_info;
        apr_status_t rv;
        int threads_created = 0;
        int listener_started = 0;
        int prev_threads_created;
        int loops, i;
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02471)
                     "start_threads: Using %s (%swakeable)",
                     apr_pollset_method_name(event_pollset),
                     listener_is_wakeable ? "" : "not ");
    
        loops = prev_threads_created = 0;
        while (1) {
            /* threads_per_child does not include the listener thread */
            for (i = 0; i < threads_per_child; i++) {
                int status =
                    ap_scoreboard_image->servers[my_child_num][i].status;
    
                if (status != SERVER_DEAD) {
                    continue;
                }
    
                my_info = (proc_info *) ap_malloc(sizeof(proc_info));
                my_info->pslot = my_child_num;
                my_info->tslot = i;
    
                /* 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 = ap_thread_create(&threads[i], thread_attr,
                                      worker_thread, my_info, pruntime);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
                                 APLOGNO(03104)
                                 "ap_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 == 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,
                                 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 (!dying) {
                apr_sleep(apr_time_from_msec(500));
                if (dying || ++iter > 10) {
                    break;
                }
                /* listener has not stopped accepting yet */
                ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                             "listener has not stopped accepting yet (%d iter)", iter);
                wakeup_listener();
            }
            if (iter > 10) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00475)
                             "the listener thread didn't stop accepting");
            }
            else {
                rv = apr_thread_join(&thread_rv, listener);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00476)
                                 "apr_thread_join: unable to join listener thread");
                }
            }
        }
    
        for (i = 0; i < 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, APLOGNO(00477)
                                 "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, APLOGNO(00478)
                         "apr_thread_join: unable to join the start " "thread");
        }
    }
    
    static void child_main(int child_num_arg, int child_bucket)
    {
        apr_thread_t **threads;
        apr_status_t rv;
        thread_starter *ts;
        apr_threadattr_t *thread_attr;
        apr_thread_t *start_thread_id;
        int i;
    
        /* for benefit of any hooks that run as this child initializes */
        retained->mpm->mpm_state = AP_MPMQ_STARTING;
    
        ap_my_pid = getpid();
        ap_child_slot = child_num_arg;
        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_pool_create(&pchild, pconf);
        apr_pool_tag(pchild, "pchild");
    
    #if AP_HAS_THREAD_LOCAL
        if (!one_process) {
            apr_thread_t *thd = NULL;
            if ((rv = ap_thread_main_create(&thd, pchild))) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(10377)
                             "Couldn't initialize child main thread");
                clean_child_exit(APEXIT_CHILDFATAL);
            }
        }
    #endif
    
        /* close unused listeners and pods */
        for (i = 0; i < retained->mpm->num_buckets; i++) {
            if (i != child_bucket) {
                ap_close_listeners_ex(all_buckets[i].listeners);
                ap_mpm_podx_close(all_buckets[i].pod);
            }
        }
    
        /*stuff to do before we switch id's, so we have permissions. */
        ap_reopen_scoreboard(pchild, NULL, 0);
    
        /* done with init critical section */
        if (ap_run_drop_privileges(pchild, ap_server_conf)) {
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        /* 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. Let's also do this before
         * child_init() hooks are called and possibly create threads that
         * otherwise could "steal" (implicitly) MPM's signals.
         */
        rv = apr_setup_signal_thread();
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00479)
                         "Couldn't initialize signal thread");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        ap_run_child_init(pchild, ap_server_conf);
    
        if (ap_max_requests_per_child) {
            conns_this_child = ap_max_requests_per_child;
        }
        else {
            /* coding a value of zero means infinity */
            conns_this_child = APR_INT32_MAX;
        }
    
        /* Setup threads */
    
        /* Globals used by signal_threads() so to be initialized before */
        setup_threads_runtime();
    
        /* 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 = ap_calloc(threads_per_child, sizeof(apr_thread_t *));
        ts = 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) {
            rv = apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
            if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(02436)
                             "WARNING: ThreadStackSize of %" APR_SIZE_T_FMT " is "
                             "inappropriate, using default", 
                             ap_thread_stacksize);
            }
        }
    
        ts->threads = threads;
        ts->listener = NULL;
        ts->child_num_arg = child_num_arg;
        ts->threadattr = thread_attr;
    
        rv = ap_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, APLOGNO(00480)
                         "ap_thread_create: unable to create worker thread");
            /* let the parent decide how bad this really is */
            clean_child_exit(APEXIT_CHILDSICK);
        }
    
        retained->mpm->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 MaxConnectionsPerChild) it will send us SIGTERM
             */
            apr_signal(SIGTERM, dummy_signal_handler);
            unblock_signal(SIGTERM);
            /* Watch for any messages from the parent over the POD */
            while (1) {
                rv = ap_mpm_podx_check(my_bucket->pod);
                if (rv == AP_MPM_PODX_NORESTART) {
                    /* see if termination was triggered while we slept */
                    switch (terminate_mode) {
                    case ST_GRACEFUL:
                        rv = AP_MPM_PODX_GRACEFUL;
                        break;
                    case ST_UNGRACEFUL:
                        rv = AP_MPM_PODX_RESTART;
                        break;
                    }
                }
                if (rv == AP_MPM_PODX_GRACEFUL || rv == AP_MPM_PODX_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_MPM_PODX_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).
             */
            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                         "%s termination received, joining workers",
                         rv == AP_MPM_PODX_GRACEFUL ? "graceful" : "ungraceful");
            join_workers(ts->listener, threads);
            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                         "%s termination, workers joined, exiting",
                         rv == AP_MPM_PODX_GRACEFUL ? "graceful" : "ungraceful");
        }
    
        free(threads);
    
        clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
    }
    
    static int make_child(server_rec * s, int slot, int bucket)
    {
        int pid;
    
        if (slot + 1 > retained->max_daemon_used) {
            retained->max_daemon_used = slot + 1;
        }
    
        if (ap_scoreboard_image->parent[slot].pid != 0) {
            /* XXX replace with assert or remove ? */
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(03455)
                     "BUG: Scoreboard slot %d should be empty but is "
                     "in use by pid %" APR_PID_T_FMT,
                     slot, ap_scoreboard_image->parent[slot].pid);
            return -1;
        }
    
        if (one_process) {
            my_bucket = &all_buckets[0];
    
            event_note_child_started(slot, getpid());
            child_main(slot, 0);
            /* NOTREACHED */
            ap_assert(0);
            return -1;
        }
    
        if ((pid = fork()) == -1) {
            ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, APLOGNO(00481)
                         "fork: Unable to fork new process");
    
            /* fork didn't succeed.  There's no need to touch the scoreboard;
             * if we were trying to replace a failed child process, then
             * server_main_loop() marked its workers SERVER_DEAD, and if
             * we were trying to replace a child process that exited normally,
             * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
             */
    
            /* 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) {
    #if AP_HAS_THREAD_LOCAL
            ap_thread_current_after_fork();
    #endif
    
            my_bucket = &all_buckets[bucket];
    
    #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_DEBUG, errno,
                             ap_server_conf, APLOGNO(00482)
                             "processor unbind failed");
    #endif
            RAISE_SIGSTOP(MAKE_CHILD);
    
            apr_signal(SIGTERM, just_die);
            child_main(slot, bucket);
            /* NOTREACHED */
            ap_assert(0);
            return -1;
        }
    
        event_note_child_started(slot, 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 < server_limit; ++i) {
            if (ap_scoreboard_image->parent[i].pid != 0) {
                continue;
            }
            if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
                break;
            }
            --number_to_start;
        }
    }
    
    static void perform_idle_server_maintenance(int child_bucket,
                                                int *max_daemon_used)
    {
        int num_buckets = retained->mpm->num_buckets;
        int idle_thread_count = 0;
        process_score *ps;
        int free_length = 0;
        int free_slots[MAX_SPAWN_RATE];
        int last_non_dead = -1;
        int active_thread_count = 0;
        int i, j;
    
        for (i = 0; i < server_limit; ++i) {
            if (num_buckets > 1 && (i % num_buckets) != child_bucket) {
                /* We only care about child_bucket in this call */
                continue;
            }
            if (i >= retained->max_daemon_used &&
                free_length == retained->idle_spawn_rate[child_bucket]) {
                /* short cut if all active processes have been examined and
                 * enough empty scoreboard slots have been found
                 */
                break;
            }
    
            ps = &ap_scoreboard_image->parent[i];
            if (ps->pid != 0) {
                int child_threads_active = 0;
                if (ps->quiescing == 1) {
                    ps->quiescing = 2;
                    retained->active_daemons--;
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                                 "Child %d quiescing: pid %d, gen %d, "
                                 "active %d/%d, total %d/%d/%d",
                                 i, (int)ps->pid, (int)ps->generation,
                                 retained->active_daemons, active_daemons_limit,
                                 retained->total_daemons, retained->max_daemon_used,
                                 server_limit);
                }
                for (j = 0; j < threads_per_child; j++) {
                    int status = ap_scoreboard_image->servers[i][j].status;
    
                    /* 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 && !ps->quiescing && !ps->not_accepting
                        && ps->generation == retained->mpm->my_generation) {
                        ++idle_thread_count;
                    }
                    if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
                        ++child_threads_active;
                    }
                }
                active_thread_count += child_threads_active;
                if (child_threads_active == threads_per_child) {
                    had_healthy_child = 1;
                }
                last_non_dead = i;
            }
            else if (free_length < retained->idle_spawn_rate[child_bucket]) {
                free_slots[free_length++] = i;
            }
        }
        if (*max_daemon_used < last_non_dead + 1) {
            *max_daemon_used = last_non_dead + 1;
        }
    
        if (retained->sick_child_detected) {
            if (had_healthy_child) {
                /* Assume this is a transient error, even though it may not be.  Leave
                 * the server up in case it is able to serve some requests or the
                 * problem will be resolved.
                 */
                retained->sick_child_detected = 0;
            }
            else if (child_bucket < num_buckets - 1) {
                /* check for had_healthy_child up to the last child bucket */
                return;
            }
            else {
                /* looks like a basket case, as no child ever fully initialized; give up.
                 */
                retained->mpm->shutdown_pending = 1;
                child_fatal = 1;
                ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
                             ap_server_conf, APLOGNO(02324)
                             "A resource shortage or other unrecoverable failure "
                             "was encountered before any child process initialized "
                             "successfully... httpd is exiting!");
                /* the child already logged the failure details */
                return;
            }
        }
    
        AP_DEBUG_ASSERT(retained->active_daemons <= retained->total_daemons
                        && retained->total_daemons <= retained->max_daemon_used
                        && retained->max_daemon_used <= server_limit);
    
        if (idle_thread_count > max_spare_threads / num_buckets) {
            /*
             * Child processes that we ask to shut down won't die immediately
             * but may stay around for a long time when they finish their
             * requests. If the server load changes many times, many such
             * gracefully finishing processes may accumulate, filling up the
             * scoreboard. To avoid running out of scoreboard entries, we
             * don't shut down more processes if there are stopping ones
             * already (i.e. active_daemons != total_daemons) and not enough
             * slack space in the scoreboard for a graceful restart.
             *
             * XXX It would be nice if we could
             * XXX - kill processes without keepalive connections first
             * XXX - tell children to stop accepting new connections, and
             * XXX   depending on server load, later be able to resurrect them
             *       or kill them
             */
            int do_kill = (retained->active_daemons == retained->total_daemons
                           || (server_limit - retained->total_daemons >
                               active_daemons_limit));
            ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
                         "%shutting down one child: "
                         "active %d/%d, total %d/%d/%d, "
                         "idle threads %d, max workers %d",
                         (do_kill) ? "S" : "Not s",
                         retained->active_daemons, active_daemons_limit,
                         retained->total_daemons, retained->max_daemon_used,
                         server_limit, idle_thread_count, max_workers);
            if (do_kill) {
                ap_mpm_podx_signal(all_buckets[child_bucket].pod,
                                   AP_MPM_PODX_GRACEFUL);
            }
            else {
                /* Wait for dying daemon(s) to exit */
            }
            retained->idle_spawn_rate[child_bucket] = 1;
        }
        else if (idle_thread_count < min_spare_threads / num_buckets) {
            if (active_thread_count >= max_workers / num_buckets) {
                if (0 == idle_thread_count) { 
                    if (!retained->maxclients_reported) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00484)
                                     "server reached MaxRequestWorkers setting, "
                                     "consider raising the MaxRequestWorkers "
                                     "setting");
                        retained->maxclients_reported = 1;
                    }
                 }
                 else { 
                    if (!retained->near_maxclients_reported) {
                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(10159)
                                "server is within MinSpareThreads of "
                                "MaxRequestWorkers, consider raising the "
                                "MaxRequestWorkers setting");
                        retained->near_maxclients_reported = 1;
                    }
                }
                retained->idle_spawn_rate[child_bucket] = 1;
            }
            else if (free_length == 0) { /* scoreboard is full, can't fork */
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(03490)
                             "scoreboard is full, not at MaxRequestWorkers."
                             "Increase ServerLimit.");
                retained->idle_spawn_rate[child_bucket] = 1;
            }
            else {
                if (free_length > retained->idle_spawn_rate[child_bucket]) {
                    free_length = retained->idle_spawn_rate[child_bucket];
                }
                if (free_length + retained->active_daemons > active_daemons_limit) {
                    if (retained->active_daemons < active_daemons_limit) {
                        free_length = active_daemons_limit - retained->active_daemons;
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                                     "server is at active daemons limit, spawning "
                                     "of %d children cancelled: active %d/%d, "
                                     "total %d/%d/%d, rate %d", free_length,
                                     retained->active_daemons, active_daemons_limit,
                                     retained->total_daemons, retained->max_daemon_used,
                                     server_limit, retained->idle_spawn_rate[child_bucket]);
                        /* reset the spawning rate and prevent its growth below */
                        retained->idle_spawn_rate[child_bucket] = 1;
                        ++retained->hold_off_on_exponential_spawning;
                        free_length = 0;
                    }
                }
                if (retained->idle_spawn_rate[child_bucket] >= 8) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00486)
                                 "server seems busy, (you may need "
                                 "to increase StartServers, ThreadsPerChild "
                                 "or Min/MaxSpareThreads), "
                                 "spawning %d children, there are around %d idle "
                                 "threads, %d active children, and %d children "
                                 "that are shutting down", free_length,
                                 idle_thread_count, retained->active_daemons,
                                 retained->total_daemons);
                }
                for (i = 0; i < free_length; ++i) {
                    int slot = free_slots[i];
                    if (make_child(ap_server_conf, slot, child_bucket) < 0) {
                        continue;
                    }
                    if (*max_daemon_used < slot + 1) {
                        *max_daemon_used = slot + 1;
                    }
                }
                /* 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 (retained->hold_off_on_exponential_spawning) {
                    --retained->hold_off_on_exponential_spawning;
                }
                else if (retained->idle_spawn_rate[child_bucket]
                         < MAX_SPAWN_RATE / num_buckets) {
                    retained->idle_spawn_rate[child_bucket] *= 2;
                }
            }
        }
        else {
            retained->idle_spawn_rate[child_bucket] = 1;
        }
    }
    
    static void server_main_loop(int remaining_children_to_start)
    {
        int num_buckets = retained->mpm->num_buckets;
        int max_daemon_used = 0;
        int successive_kills = 0;
        int child_slot;
        apr_exit_why_e exitwhy;
        int status, processed_status;
        apr_proc_t pid;
        int i;
    
        while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) {
            ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
    
            if (pid.pid != -1) {
                processed_status = ap_process_child_status(&pid, exitwhy, status);
                child_slot = ap_find_child_by_pid(&pid);
                if (processed_status == APEXIT_CHILDFATAL) {
                    /* fix race condition found in PR 39311
                     * A child created at the same time as a graceful happens 
                     * can find the lock missing and create a fatal error.
                     * It is not fatal for the last generation to be in this state.
                     */
                    if (child_slot < 0
                        || ap_get_scoreboard_process(child_slot)->generation
                           == retained->mpm->my_generation) {
                        retained->mpm->shutdown_pending = 1;
                        child_fatal = 1;
                        /*
                         * total_daemons counting will be off now, but as we
                         * are shutting down, that is not an issue anymore.
                         */
                        return;
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(00487)
                                     "Ignoring fatal error in child of previous "
                                     "generation (pid %ld).",
                                     (long)pid.pid);
                        retained->sick_child_detected = 1;
                    }
                }
                else if (processed_status == APEXIT_CHILDSICK) {
                    /* tell perform_idle_server_maintenance to check into this
                     * on the next timer pop
                     */
                    retained->sick_child_detected = 1;
                }
                /* non-fatal death... note that it's gone in the scoreboard. */
                if (child_slot >= 0) {
                    event_note_child_stopped(child_slot, 0, 0);
    
                    if (processed_status == APEXIT_CHILDSICK) {
                        /* resource shortage, minimize the fork rate */
                        retained->idle_spawn_rate[child_slot % num_buckets] = 1;
                    }
                    else if (remaining_children_to_start) {
                        /* we're still doing a 1-for-1 replacement of dead
                         * children with new children
                         */
                        make_child(ap_server_conf, child_slot,
                                   child_slot % num_buckets);
                        --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 (retained->mpm->was_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, APLOGNO(00488)
                                 "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.  If a child is
                 * killed by a signal (faulting) we want to restart it ASAP
                 * though, up to 3 successive faults or we stop this until
                 * a timeout happens again (to avoid the flood of fork()ed
                 * processes that keep being killed early).
                 */
                if (child_slot < 0 || !APR_PROC_CHECK_SIGNALED(exitwhy)) {
                    continue;
                }
                if (++successive_kills >= 3) {
                    if (successive_kills % 10 == 3) {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
                                     ap_server_conf, APLOGNO(10392)
                                     "children are killed successively!");
                    }
                    continue;
                }
                ++remaining_children_to_start;
            }
            else {
                successive_kills = 0;
            }
    
            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;
            }
    
            max_daemon_used = 0;
            for (i = 0; i < num_buckets; i++) {
                perform_idle_server_maintenance(i, &max_daemon_used);
            }
            retained->max_daemon_used = max_daemon_used;
        }
    }
    
    static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
    {
        int num_buckets = retained->mpm->num_buckets;
        int remaining_children_to_start;
        int i;
    
        ap_log_pid(pconf, ap_pid_fname);
    
        if (!retained->mpm->was_graceful) {
            if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
                retained->mpm->mpm_state = AP_MPMQ_STOPPING;
                return !OK;
            }
            /* fix the generation number in the global score; we just got a new,
             * cleared scoreboard
             */
            ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
        }
    
        ap_unixd_mpm_set_signals(pconf, one_process);
    
        /* Don't thrash since num_buckets depends on the
         * system and the number of online CPU cores...
         */
        if (active_daemons_limit < num_buckets)
            active_daemons_limit = num_buckets;
        if (ap_daemons_to_start < num_buckets)
            ap_daemons_to_start = num_buckets;
        /* We want to create as much children at a time as the number of buckets,
         * so to optimally accept connections (evenly distributed across buckets).
         * Thus min_spare_threads should at least maintain num_buckets children,
         * and max_spare_threads allow num_buckets more children w/o triggering
         * immediately (e.g. num_buckets idle threads margin, one per bucket).
         */
        if (min_spare_threads < threads_per_child * (num_buckets - 1) + num_buckets)
            min_spare_threads = threads_per_child * (num_buckets - 1) + num_buckets;
        if (max_spare_threads < min_spare_threads + (threads_per_child + 1) * num_buckets)
            max_spare_threads = min_spare_threads + (threads_per_child + 1) * num_buckets;
    
        /* 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 may start a new one, until
         * there are at least min_spare_threads idle threads, counting across
         * all children.  But we may be permitted to start more children 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 > active_daemons_limit) {
            remaining_children_to_start = active_daemons_limit;
        }
        if (!retained->mpm->was_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 */
            retained->hold_off_on_exponential_spawning = 10;
        }
    
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00489)
                     "%s configured -- resuming normal operations",
                     ap_get_server_description());
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00490)
                     "Server built: %s", ap_get_server_built());
        ap_log_command_line(plog, s);
        ap_log_mpm_common(s);
    
        retained->mpm->mpm_state = AP_MPMQ_RUNNING;
    
        server_main_loop(remaining_children_to_start);
        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
    
        if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) {
            /* Time to shut down:
             * Kill child processes, tell them to call child_exit, etc...
             */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
                                   AP_MPM_PODX_RESTART);
            }
            ap_reclaim_child_processes(1, /* Start with SIGTERM */
                                       event_note_child_stopped);
    
            if (!child_fatal) {
                /* cleanup pid file on normal shutdown */
                ap_remove_pid(pconf, ap_pid_fname);
                ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
                             ap_server_conf, APLOGNO(00491) "caught SIGTERM, shutting down");
            }
    
            return DONE;
        }
    
        if (retained->mpm->shutdown_pending) {
            /* Time to gracefully shut down:
             * Kill child processes, tell them to call child_exit, etc...
             */
            int active_children;
            int index;
            apr_time_t cutoff = 0;
    
            /* Close our listeners, and then ask our children to do same */
            ap_close_listeners();
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
                                   AP_MPM_PODX_GRACEFUL);
            }
            ap_relieve_child_processes(event_note_child_stopped);
    
            if (!child_fatal) {
                /* cleanup pid file on normal shutdown */
                ap_remove_pid(pconf, ap_pid_fname);
                ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00492)
                             "caught " AP_SIG_GRACEFUL_STOP_STRING
                             ", shutting down gracefully");
            }
    
            if (ap_graceful_shutdown_timeout) {
                cutoff = apr_time_now() +
                         apr_time_from_sec(ap_graceful_shutdown_timeout);
            }
    
            /* Don't really exit until each child has finished */
            retained->mpm->shutdown_pending = 0;
            do {
                /* Pause for a second */
                apr_sleep(apr_time_from_sec(1));
    
                /* Relieve any children which have now exited */
                ap_relieve_child_processes(event_note_child_stopped);
    
                active_children = 0;
                for (index = 0; index < retained->max_daemon_used; ++index) {
                    if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
                        active_children = 1;
                        /* Having just one child is enough to stay around */
                        break;
                    }
                }
            } while (!retained->mpm->shutdown_pending && active_children &&
                     (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
    
            /* We might be here because we received SIGTERM, either
             * way, try and make sure that all of our processes are
             * really dead.
             */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
                                   AP_MPM_PODX_RESTART);
            }
            ap_reclaim_child_processes(1, event_note_child_stopped);
    
            return DONE;
        }
    
        /* we've been told to restart */
        if (one_process) {
            /* not worth thinking about */
            return DONE;
        }
    
        /* 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.
         */
        ++retained->mpm->my_generation;
        ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
    
        if (!retained->mpm->is_ungraceful) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493)
                         AP_SIG_GRACEFUL_STRING " received.  Doing graceful restart");
            /* wake up the children...time to die.  But we'll have more soon */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
                                   AP_MPM_PODX_GRACEFUL);
            }
    
            /* This is mostly for debugging... so that we know what is still
             * gracefully dealing with existing request.
             */
    
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494)
                         "SIGHUP received.  Attempting to restart");
            /* 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.
             */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
                                   AP_MPM_PODX_RESTART);
            }
    
            ap_reclaim_child_processes(1,  /* Start with SIGTERM */
                                       event_note_child_stopped);
        }
    
        return OK;
    }
    
    static void setup_slave_conn(conn_rec *c, void *csd) 
    {
        event_conn_state_t *mcs;
        event_conn_state_t *cs;
        
        mcs = ap_get_module_config(c->master->conn_config, &mpm_event_module);
        
        cs = apr_pcalloc(c->pool, sizeof(*cs));
        cs->c = c;
        cs->r = NULL;
        cs->sc = mcs->sc;
        cs->suspended = 0;
        cs->p = c->pool;
        cs->bucket_alloc = c->bucket_alloc;
        cs->pfd = mcs->pfd;
        cs->pub = mcs->pub;
        cs->pub.state = CONN_STATE_PROCESSING;
        cs->pub.sense = CONN_SENSE_DEFAULT;
        
        c->cs = &(cs->pub);
        ap_set_module_config(c->conn_config, &mpm_event_module, cs);
    }
    
    static int event_pre_connection(conn_rec *c, void *csd)
    {
        if (c->master && (!c->cs || c->cs == c->master->cs)) {
            setup_slave_conn(c, csd);
        }
        return OK;
    }
    
    static int event_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
                                     const char *protocol)
    {
        if (!r && s) {
            /* connection based switching of protocol, set the correct server
             * configuration, so that timeouts, keepalives and such are used
             * for the server that the connection was switched on.
             * Normally, we set this on post_read_request, but on a protocol
             * other than http/1.1, this might never happen.
             */
            event_conn_state_t *cs;
            
            cs = ap_get_module_config(c->conn_config, &mpm_event_module);
            cs->sc = ap_get_module_config(s->module_config, &mpm_event_module);
        }
        return DECLINED;
    }
    
    /* 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 event_open_logs(apr_pool_t * p, apr_pool_t * plog,
                               apr_pool_t * ptemp, server_rec * s)
    {
        int startup = 0;
        int level_flags = 0;
        int num_buckets = 0;
        ap_listen_rec **listen_buckets;
        apr_status_t rv;
        int i;
    
        pconf = p;
    
        /* the reverse of pre_config, we want this only the first time around */
        if (retained->mpm->module_loads == 1) {
            startup = 1;
            level_flags |= APLOG_STARTUP;
        }
    
        if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
            ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
                         (startup ? NULL : s),
                         "no listening sockets available, shutting down");
            return !OK;
        }
    
        if (one_process) {
            num_buckets = 1;
        }
        else if (retained->mpm->was_graceful) {
            /* Preserve the number of buckets on graceful restarts. */
            num_buckets = retained->mpm->num_buckets;
        }
        if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
                                         &listen_buckets, &num_buckets))) {
            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                         (startup ? NULL : s),
                         "could not duplicate listeners");
            return !OK;
        }
    
        all_buckets = apr_pcalloc(pconf, num_buckets * sizeof(*all_buckets));
        for (i = 0; i < num_buckets; i++) {
            if (!one_process && /* no POD in one_process mode */
                    (rv = ap_mpm_podx_open(pconf, &all_buckets[i].pod))) {
                ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                             (startup ? NULL : s),
                             "could not open pipe-of-death");
                return !OK;
            }
            all_buckets[i].listeners = listen_buckets[i];
        }
    
        if (retained->mpm->max_buckets < num_buckets) {
            int new_max, *new_ptr;
            new_max = retained->mpm->max_buckets * 2;
            if (new_max < num_buckets) {
                new_max = num_buckets;
            }
            new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
            if (retained->idle_spawn_rate) /* NULL at startup */
                memcpy(new_ptr, retained->idle_spawn_rate,
                       retained->mpm->num_buckets * sizeof(int));
            retained->idle_spawn_rate = new_ptr;
            retained->mpm->max_buckets = new_max;
        }
        if (retained->mpm->num_buckets < num_buckets) {
            int rate_max = 1;
            /* If new buckets are added, set their idle spawn rate to
             * the highest so far, so that they get filled as quickly
             * as the existing ones.
             */
            for (i = 0; i < retained->mpm->num_buckets; i++) {
                if (rate_max < retained->idle_spawn_rate[i]) {
                    rate_max = retained->idle_spawn_rate[i];
                }
            }
            for (/* up to date i */; i < num_buckets; i++) {
                retained->idle_spawn_rate[i] = rate_max;
            }
        }
        retained->mpm->num_buckets = num_buckets;
    
        /* for skiplist */
        srand((unsigned int)apr_time_now());
        return OK;
    }
    
    static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
                                apr_pool_t * ptemp)
    {
        int no_detach, debug, foreground;
        apr_status_t rv;
        const char *userdata_key = "mpm_event_module";
        int test_atomics = 0;
    
        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");
        }
    
        retained = ap_retained_data_get(userdata_key);
        if (!retained) {
            retained = ap_retained_data_create(userdata_key, sizeof(*retained));
            retained->mpm = ap_unixd_mpm_get_retained_data();
            if (retained->mpm->module_loads) {
                test_atomics = 1;
            }
        }
        retained->mpm->mpm_state = AP_MPMQ_STARTING;
        if (retained->mpm->baton != retained) {
            retained->mpm->was_graceful = 0;
            retained->mpm->baton = retained;
        }
        ++retained->mpm->module_loads;
    
        /* test once for correct operation of fdqueue */
        if (test_atomics || retained->mpm->module_loads == 2) {
            static apr_uint32_t foo1, foo2;
    
            apr_atomic_set32(&foo1, 100);
            foo2 = apr_atomic_add32(&foo1, -10);
            if (foo2 != 100 || foo1 != 90) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(02405)
                             "atomics not working as expected - add32 of negative number");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        /* sigh, want this only the second time around */
        if (retained->mpm->module_loads == 2) {
            rv = apr_pollset_create(&event_pollset, 1, plog,
                                    APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00495)
                             "Couldn't create a Thread Safe Pollset. "
                             "Is it supported on your platform?"
                             "Also check system or user limits!");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            apr_pollset_destroy(event_pollset);
    
            if (!one_process && !foreground) {
                /* before we detach, setup crash handlers to log to errorlog */
                ap_fatal_signal_setup(ap_server_conf, pconf);
                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, APLOGNO(00496)
                                 "apr_proc_detach failed");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
        }
    
        parent_pid = ap_my_pid = getpid();
    
        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;
        server_limit = DEFAULT_SERVER_LIMIT;
        thread_limit = DEFAULT_THREAD_LIMIT;
        active_daemons_limit = server_limit;
        threads_per_child = DEFAULT_THREADS_PER_CHILD;
        max_workers = active_daemons_limit * threads_per_child;
        defer_linger_chain = NULL;
        had_healthy_child = 0;
        ap_extended_status = 0;
    
        event_pollset = NULL;
        worker_queue_info = NULL;
        listener_os_thread = NULL;
        listensocks_disabled = 0;
        listener_is_wakeable = 0;
    
        return OK;
    }
    
    static int event_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                 apr_pool_t *ptemp, server_rec *s)
    {
        struct {
            struct timeout_queue *tail, *q;
            apr_hash_t *hash;
        } io, wc, ka;
    
        /* Not needed in pre_config stage */
        if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            return OK;
        }
    
        io.hash = apr_hash_make(ptemp);
        wc.hash = apr_hash_make(ptemp);
        ka.hash = apr_hash_make(ptemp);
        io.tail = wc.tail = ka.tail = NULL;
    
        linger_q = TO_QUEUE_MAKE(pconf, apr_time_from_sec(MAX_SECS_TO_LINGER),
                                 NULL);
        short_linger_q = TO_QUEUE_MAKE(pconf, apr_time_from_sec(SECONDS_TO_LINGER),
                                       NULL);
    
        for (; s; s = s->next) {
            event_srv_cfg *sc = apr_pcalloc(pconf, sizeof *sc);
    
            ap_set_module_config(s->module_config, &mpm_event_module, sc);
            if (!io.tail) {
                /* The main server uses the global queues */
                io.q = TO_QUEUE_MAKE(pconf, s->timeout, NULL);
                apr_hash_set(io.hash, &s->timeout, sizeof s->timeout, io.q);
                io.tail = waitio_q = io.q;
    
                wc.q = TO_QUEUE_MAKE(pconf, s->timeout, NULL);
                apr_hash_set(wc.hash, &s->timeout, sizeof s->timeout, wc.q);
                wc.tail = write_completion_q = wc.q;
    
                ka.q = TO_QUEUE_MAKE(pconf, s->keep_alive_timeout, NULL);
                apr_hash_set(ka.hash, &s->keep_alive_timeout,
                             sizeof s->keep_alive_timeout, ka.q);
                ka.tail = keepalive_q = ka.q;
            }
            else {
                /* The vhosts use any existing queue with the same timeout,
                 * or their own queue(s) if there isn't */
                io.q = apr_hash_get(io.hash, &s->timeout, sizeof s->timeout);
                if (!io.q) {
                    io.q = TO_QUEUE_MAKE(pconf, s->timeout, io.tail);
                    apr_hash_set(io.hash, &s->timeout, sizeof s->timeout, io.q);
                    io.tail = io.tail->next = io.q;
                }
    
                wc.q = apr_hash_get(wc.hash, &s->timeout, sizeof s->timeout);
                if (!wc.q) {
                    wc.q = TO_QUEUE_MAKE(pconf, s->timeout, wc.tail);
                    apr_hash_set(wc.hash, &s->timeout, sizeof s->timeout, wc.q);
                    wc.tail = wc.tail->next = wc.q;
                }
    
                ka.q = apr_hash_get(ka.hash, &s->keep_alive_timeout,
                                    sizeof s->keep_alive_timeout);
                if (!ka.q) {
                    ka.q = TO_QUEUE_MAKE(pconf, s->keep_alive_timeout, ka.tail);
                    apr_hash_set(ka.hash, &s->keep_alive_timeout,
                                 sizeof s->keep_alive_timeout, ka.q);
                    ka.tail = ka.tail->next = ka.q;
                }
            }
            sc->io_q = io.q;
            sc->wc_q = wc.q;
            sc->ka_q = ka.q;
        }
    
        return OK;
    }
    
    static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
                                  apr_pool_t *ptemp, server_rec *s)
    {
        int startup = 0;
    
        /* the reverse of pre_config, we want this only the first time around */
        if (retained->mpm->module_loads == 1) {
            startup = 1;
        }
    
        if (server_limit > MAX_SERVER_LIMIT) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00497)
                             "WARNING: ServerLimit of %d exceeds compile-time "
                             "limit of %d servers, decreasing to %d.",
                             server_limit, MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00498)
                             "ServerLimit of %d exceeds compile-time limit "
                             "of %d, decreasing to match",
                             server_limit, MAX_SERVER_LIMIT);
            }
            server_limit = MAX_SERVER_LIMIT;
        }
        else if (server_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00499)
                             "WARNING: ServerLimit of %d not allowed, "
                             "increasing to 1.", server_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00500)
                             "ServerLimit of %d not allowed, increasing to 1",
                             server_limit);
            }
            server_limit = 1;
        }
    
        /* you cannot change ServerLimit across a restart; ignore
         * any such attempts
         */
        if (!retained->first_server_limit) {
            retained->first_server_limit = server_limit;
        }
        else if (server_limit != retained->first_server_limit) {
            /* don't need a startup console version here */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00501)
                         "changing ServerLimit to %d from original value of %d "
                         "not allowed during restart",
                         server_limit, retained->first_server_limit);
            server_limit = retained->first_server_limit;
        }
    
        if (thread_limit > MAX_THREAD_LIMIT) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00502)
                             "WARNING: ThreadLimit of %d exceeds compile-time "
                             "limit of %d threads, decreasing to %d.",
                             thread_limit, MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00503)
                             "ThreadLimit of %d exceeds compile-time limit "
                             "of %d, decreasing to match",
                             thread_limit, MAX_THREAD_LIMIT);
            }
            thread_limit = MAX_THREAD_LIMIT;
        }
        else if (thread_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00504)
                             "WARNING: ThreadLimit of %d not allowed, "
                             "increasing to 1.", thread_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00505)
                             "ThreadLimit of %d not allowed, increasing to 1",
                             thread_limit);
            }
            thread_limit = 1;
        }
    
        /* you cannot change ThreadLimit across a restart; ignore
         * any such attempts
         */
        if (!retained->first_thread_limit) {
            retained->first_thread_limit = thread_limit;
        }
        else if (thread_limit != retained->first_thread_limit) {
            /* don't need a startup console version here */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00506)
                         "changing ThreadLimit to %d from original value of %d "
                         "not allowed during restart",
                         thread_limit, retained->first_thread_limit);
            thread_limit = retained->first_thread_limit;
        }
    
        if (threads_per_child > thread_limit) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00507)
                             "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
                             "of %d threads, decreasing to %d. "
                             "To increase, please see the ThreadLimit directive.",
                             threads_per_child, thread_limit, thread_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00508)
                             "ThreadsPerChild of %d exceeds ThreadLimit "
                             "of %d, decreasing to match",
                             threads_per_child, thread_limit);
            }
            threads_per_child = thread_limit;
        }
        else if (threads_per_child < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00509)
                             "WARNING: ThreadsPerChild of %d not allowed, "
                             "increasing to 1.", threads_per_child);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00510)
                             "ThreadsPerChild of %d not allowed, increasing to 1",
                             threads_per_child);
            }
            threads_per_child = 1;
        }
    
        if (max_workers < threads_per_child) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00511)
                             "WARNING: MaxRequestWorkers of %d is less than "
                             "ThreadsPerChild of %d, increasing to %d. "
                             "MaxRequestWorkers must be at least as large "
                             "as the number of threads in a single server.",
                             max_workers, threads_per_child, threads_per_child);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00512)
                             "MaxRequestWorkers of %d is less than ThreadsPerChild "
                             "of %d, increasing to match",
                             max_workers, threads_per_child);
            }
            max_workers = threads_per_child;
        }
    
        active_daemons_limit = max_workers / threads_per_child;
    
        if (max_workers % threads_per_child) {
            int tmp_max_workers = active_daemons_limit * threads_per_child;
    
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00513)
                             "WARNING: MaxRequestWorkers of %d is not an integer "
                             "multiple of ThreadsPerChild of %d, decreasing to nearest "
                             "multiple %d, for a maximum of %d servers.",
                             max_workers, threads_per_child, tmp_max_workers,
                             active_daemons_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00514)
                             "MaxRequestWorkers of %d is not an integer multiple "
                             "of ThreadsPerChild of %d, decreasing to nearest "
                             "multiple %d", max_workers, threads_per_child,
                             tmp_max_workers);
            }
            max_workers = tmp_max_workers;
        }
    
        if (active_daemons_limit > server_limit) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00515)
                             "WARNING: MaxRequestWorkers of %d would require %d servers "
                             "and would exceed ServerLimit of %d, decreasing to %d. "
                             "To increase, please see the ServerLimit directive.",
                             max_workers, active_daemons_limit, server_limit,
                             server_limit * threads_per_child);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00516)
                             "MaxRequestWorkers of %d would require %d servers and "
                             "exceed ServerLimit of %d, decreasing to %d",
                             max_workers, active_daemons_limit, server_limit,
                             server_limit * threads_per_child);
            }
            active_daemons_limit = server_limit;
        }
    
        /* ap_daemons_to_start > active_daemons_limit checked in ap_mpm_run() */
        if (ap_daemons_to_start < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00517)
                             "WARNING: StartServers of %d not allowed, "
                             "increasing to 1.", ap_daemons_to_start);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00518)
                             "StartServers of %d not allowed, increasing to 1",
                             ap_daemons_to_start);
            }
            ap_daemons_to_start = 1;
        }
    
        if (min_spare_threads < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00519)
                             "WARNING: MinSpareThreads of %d not allowed, "
                             "increasing to 1 to avoid almost certain server "
                             "failure. Please read the documentation.",
                             min_spare_threads);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00520)
                             "MinSpareThreads of %d not allowed, increasing to 1",
                             min_spare_threads);
            }
            min_spare_threads = 1;
        }
    
        /* max_spare_threads < min_spare_threads + threads_per_child
         * checked in ap_mpm_run()
         */
    
        return OK;
    }
    
    static void event_hooks(apr_pool_t * p)
    {
        /* Our open_logs hook function 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(event_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
        /* 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(event_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
        ap_hook_post_config(event_post_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
                                            APR_HOOK_MIDDLE);
        ap_hook_pre_read_request(event_pre_read_request, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_post_read_request(event_post_read_request, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
    
        ap_hook_pre_connection(event_pre_connection, NULL, NULL, APR_HOOK_REALLY_FIRST);
        ap_hook_protocol_switch(event_protocol_switch, 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);
        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_workers(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(cmd->cmd->name, "MaxClients")) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(00521)
                         "MaxClients is deprecated, use MaxRequestWorkers "
                         "instead.");
        }
        max_workers = atoi(arg);
        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;
        }
    
        threads_per_child = atoi(arg);
        return NULL;
    }
    static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
    
        server_limit = 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;
        }
    
        thread_limit = atoi(arg);
        return NULL;
    }
    
    static const char *set_worker_factor(cmd_parms * cmd, void *dummy,
                                         const char *arg)
    {
        double val;
        char *endptr;
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
    
        val = strtod(arg, &endptr);
        if (*endptr)
            return "error parsing value";
    
        if (val <= 0)
            return "AsyncRequestWorkerFactor argument must be a positive number";
    
        worker_factor = val * WORKER_FACTOR_SCALE;
        if (worker_factor < WORKER_FACTOR_SCALE) {
            worker_factor = WORKER_FACTOR_SCALE;
        }
        return NULL;
    }
    
    
    static const command_rec event_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("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_workers, NULL, RSRC_CONF,
                      "Deprecated name of MaxRequestWorkers"),
        AP_INIT_TAKE1("MaxRequestWorkers", set_max_workers, 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"),
        AP_INIT_TAKE1("AsyncRequestWorkerFactor", set_worker_factor, NULL, RSRC_CONF,
                      "How many additional connects will be accepted per idle "
                      "worker thread"),
        AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
        {NULL}
    };
    
    AP_DECLARE_MODULE(mpm_event) = {
        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 */
        event_cmds,                 /* command apr_table_t */
        event_hooks                 /* register_hooks */
    };
    �������������������������������������httpd-2.4.64/server/mpm/event/Makefile.in�����������������������������������������������������������0000664�0001751�0001751�00000000047�11274040000�020074� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/build/special.mk
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/worker/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016244� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/worker/worker.c�������������������������������������������������������������0000664�0001751�0001751�00000270272�14643761242�017732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    #include <stdlib.h>
    
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if APR_HAVE_SYS_SOCKET_H
    #include <sys/socket.h>
    #endif
    #if APR_HAVE_SYS_WAIT_H
    #include <sys/wait.h>
    #endif
    #ifdef HAVE_SYS_PROCESSOR_H
    #include <sys/processor.h> /* for bindprocessor() */
    #endif
    
    #if !APR_HAS_THREADS
    #error The Worker MPM requires APR threads, but they are unavailable.
    #endif
    
    #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_fdqueue.h"
    #include "mpm_default.h"
    #include "util_mutex.h"
    #include "unixd.h"
    
    #include <signal.h>
    #include <limits.h>             /* 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
     */
    
    static int 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 max_workers = 0;
    static int server_limit = 0;
    static int thread_limit = 0;
    static int had_healthy_child = 0;
    static volatile int dying = 0;
    static int workers_may_exit = 0;
    static int start_thread_may_exit = 0;
    static int listener_may_exit = 0;
    static int listener_is_wakeable = 0; /* Pollset supports APR_POLLSET_WAKEABLE */
    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 apr_pollset_t *worker_pollset;
    
    
    /* data retained by worker across load/unload of the module
     * allocated on first call to pre-config hook; located on
     * subsequent calls to pre-config hook
     */
    typedef struct worker_retained_data {
        ap_unixd_mpm_retained_data *mpm;
    
        int first_server_limit;
        int first_thread_limit;
        int sick_child_detected;
        int maxclients_reported;
        int near_maxclients_reported;
        /*
         * The max child slot ever assigned, preserved across restarts.  Necessary
         * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts.
         * We use this value to optimize routines that have to scan the entire
         * scoreboard.
         */
        int max_daemons_limit;
        /*
         * 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
         * maintained per listeners bucket, doubled up to MAX_SPAWN_RATE, and
         * reset only when a cycle goes by without the need to spawn.
         */
        int *idle_spawn_rate;
    #ifndef MAX_SPAWN_RATE
    #define MAX_SPAWN_RATE        (32)
    #endif
        int hold_off_on_exponential_spawning;
    } worker_retained_data;
    static worker_retained_data *retained;
    
    typedef struct worker_child_bucket {
        ap_pod_t *pod;
        ap_listen_rec *listeners;
        apr_proc_mutex_t *mutex;
    } worker_child_bucket;
    static worker_child_bucket *all_buckets, /* All listeners buckets */
                               *my_bucket;   /* Current child bucket */
    
    #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
    
    /* 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 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 apr_pool_t *pruntime;              /* Pool for MPM threads 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;
    
    #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
    
    /* The WORKER_SIGNAL signal will be sent from the main thread to the
     * worker threads during an ungraceful restart or shutdown.
     * This ensures that on systems (i.e., Linux) where closing the worker
     * socket doesn't awake the worker thread when it is polling on the socket
     * (especially in apr_wait_for_io_or_timeout() when handling
     * Keep-Alive connections), close_worker_sockets() and join_workers()
     * still function in timely manner and allow ungraceful shutdowns to
     * proceed to completion.  Otherwise join_workers() doesn't return
     * before the main process decides the child process is non-responsive
     * and sends a SIGKILL.
     */
    #define WORKER_SIGNAL       AP_SIG_GRACEFUL
    
    /* 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 < 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;
    
        /* Unblock the listener if it's poll()ing */
        if (worker_pollset && listener_is_wakeable) {
            apr_pollset_wakeup(worker_pollset);
        }
    
        /* unblock the listener if it's waiting for a worker */
        ap_queue_info_term(worker_queue_info);
    
        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;
        retained->mpm->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);
            close_worker_sockets(); /* forcefully kill all current connections */
        }
    
        ap_run_child_stopping(pchild, mode == ST_GRACEFUL);
    }
    
    static int worker_query(int query_code, int *result, apr_status_t *rv)
    {
        *rv = APR_SUCCESS;
        switch (query_code) {
            case AP_MPMQ_MAX_DAEMON_USED:
                *result = retained->max_daemons_limit;
                break;
            case AP_MPMQ_IS_THREADED:
                *result = AP_MPMQ_STATIC;
                break;
            case AP_MPMQ_IS_FORKED:
                *result = AP_MPMQ_DYNAMIC;
                break;
            case AP_MPMQ_HARD_LIMIT_DAEMONS:
                *result = server_limit;
                break;
            case AP_MPMQ_HARD_LIMIT_THREADS:
                *result = thread_limit;
                break;
            case AP_MPMQ_MAX_THREADS:
                *result = threads_per_child;
                break;
            case AP_MPMQ_MIN_SPARE_DAEMONS:
                *result = 0;
                break;
            case AP_MPMQ_MIN_SPARE_THREADS:
                *result = min_spare_threads;
                break;
            case AP_MPMQ_MAX_SPARE_DAEMONS:
                *result = 0;
                break;
            case AP_MPMQ_MAX_SPARE_THREADS:
                *result = max_spare_threads;
                break;
            case AP_MPMQ_MAX_REQUESTS_DAEMON:
                *result = ap_max_requests_per_child;
                break;
            case AP_MPMQ_MAX_DAEMONS:
                *result = ap_daemons_limit;
                break;
            case AP_MPMQ_MPM_STATE:
                *result = retained->mpm->mpm_state;
                break;
            case AP_MPMQ_GENERATION:
                *result = retained->mpm->my_generation;
                break;
            default:
                *rv = APR_ENOTIMPL;
                break;
        }
        return OK;
    }
    
    static void worker_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
    {
        if (childnum != -1) { /* child had a scoreboard slot? */
            ap_run_child_status(ap_server_conf,
                                ap_scoreboard_image->parent[childnum].pid,
                                ap_scoreboard_image->parent[childnum].generation,
                                childnum, MPM_CHILD_EXITED);
            ap_scoreboard_image->parent[childnum].pid = 0;
        }
        else {
            ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
        }
    }
    
    static void worker_note_child_started(int slot, pid_t pid)
    {
        ap_generation_t gen = retained->mpm->my_generation;
        ap_scoreboard_image->parent[slot].pid = pid;
        ap_scoreboard_image->parent[slot].generation = gen;
        ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_STARTED);
    }
    
    static void worker_note_child_lost_slot(int slot, pid_t newpid)
    {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00263)
                     "pid %" APR_PID_T_FMT " taking over scoreboard slot from "
                     "%" APR_PID_T_FMT "%s",
                     newpid,
                     ap_scoreboard_image->parent[slot].pid,
                     ap_scoreboard_image->parent[slot].quiescing ?
                     " (quiescing)" : "");
        ap_run_child_status(ap_server_conf,
                            ap_scoreboard_image->parent[slot].pid,
                            ap_scoreboard_image->parent[slot].generation,
                            slot, MPM_CHILD_LOST_SLOT);
        /* 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_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid,
                                      ap_scoreboard_image->parent[slot].generation);
    }
    
    static const char *worker_get_name(void)
    {
        return "worker";
    }
    
    /* 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)
    {
        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
        if (terminate_mode == ST_INIT) {
            ap_run_child_stopping(pchild, 0);
        }
    
        if (pchild) {
            apr_pool_destroy(pchild);
        }
    
        if (one_process) {
            worker_note_child_killed(/* slot */ 0, 0, 0);
        }
    
        exit(code);
    }
    
    static void just_die(int sig)
    {
        clean_child_exit(0);
    }
    
    /*****************************************************************
     * Connection structures and accounting...
     */
    
    static int child_fatal;
    
    /*****************************************************************
     * Here follows a long bunch of generic server bookkeeping stuff...
     */
    
    /*****************************************************************
     * Child process main loop.
     */
    
    static void process_socket(apr_thread_t *thd, 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);
        ap_sb_handle_t *sbh;
    
        ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
    
        current_conn = ap_run_create_connection(p, ap_server_conf, sock,
                                                conn_id, sbh, bucket_alloc);
        if (current_conn) {
            current_conn->current_thread = thd;
            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
       "MaxConnectionsPerChild 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 {
            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 accept_mutex_error(const char *func, apr_status_t rv, int process_slot)
    {
        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 */
        }
        else if (requests_this_child == INT_MAX
            || ((requests_this_child == ap_max_requests_per_child)
                && ap_max_requests_per_child)) {
            ap_log_error(APLOG_MARK, level, rv, ap_server_conf, APLOGNO(00272)
                         "apr_proc_mutex_%s failed "
                         "before this child process served any requests.",
                         func);
            clean_child_exit(APEXIT_CHILDSICK);
        }
        ap_log_error(APLOG_MARK, level, rv, ap_server_conf, APLOGNO(00273)
                     "apr_proc_mutex_%s failed. Attempting to "
                     "shutdown process gracefully.", func);
        signal_threads(ST_GRACEFUL);
    }
    
    static void * APR_THREAD_FUNC listener_thread(apr_thread_t *thd, void * dummy)
    {
        proc_info * ti = dummy;
        int process_slot = ti->pid;
        void *csd = NULL;
        apr_pool_t *ptrans = NULL;            /* Pool for per-transaction stuff */
        apr_status_t rv;
        ap_listen_rec *lr = NULL;
        int have_idle_worker = 0;
        int last_poll_idx = 0;
    
        free(ti);
    
        /* Unblock the signal used to wake this thread up, and set a handler for
         * it.
         */
        apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
        unblock_signal(LISTENER_SIGNAL);
    
        /* 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, NULL);
                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(my_bucket->mutex)))
                != APR_SUCCESS) {
    
                if (!listener_may_exit) {
                    accept_mutex_error("lock", rv, process_slot);
                }
                break;                    /* skip the lock release */
            }
    
            if (!my_bucket->listeners->next) {
                /* Only one listener, so skip the poll */
                lr = my_bucket->listeners;
            }
            else {
                while (!listener_may_exit) {
                    apr_int32_t numdesc;
                    const apr_pollfd_t *pdesc;
    
                    rv = apr_pollset_poll(worker_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, ap_server_conf, APLOGNO(03137)
                                     "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) {
                /* the following pops a recycled ptrans pool off a stack */
                ap_queue_info_pop_pool(worker_queue_info, &ptrans);
                if (ptrans == NULL) {
                    /* we can't use a recycled transaction pool this time.
                     * create a new transaction pool */
                    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);
                    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(my_bucket->mutex)))
                    != APR_SUCCESS) {
    
                    if (listener_may_exit) {
                        break;
                    }
                    accept_mutex_error("unlock", rv, process_slot);
                }
                if (csd != NULL) {
                    rv = ap_queue_push_socket(worker_queue, csd, NULL, 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, APLOGNO(03138)
                                     "ap_queue_push_socket failed");
                    }
                    else {
                        have_idle_worker = 0;
                    }
                }
            }
            else {
                if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(my_bucket->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, APLOGNO(00274)
                                 "apr_proc_mutex_unlock failed. Attempting to "
                                 "shutdown process gracefully.");
                    signal_threads(ST_GRACEFUL);
                }
                break;
            }
        }
    
        ap_close_listeners_ex(my_bucket->listeners);
        ap_queue_info_free_idle_pools(worker_queue_info);
        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].tid = apr_os_thread_current();
        ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->mpm->my_generation;
        ap_update_child_status_from_indexes(process_slot, thread_slot,
                                            SERVER_STARTING, NULL);
    
    #ifdef HAVE_PTHREAD_KILL
        apr_signal(WORKER_SIGNAL, dummy_signal_handler);
        unblock_signal(WORKER_SIGNAL);
    #endif
    
        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_socket(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, APLOGNO(03139)
                                 "ap_queue_pop_socket failed");
                }
                continue;
            }
            is_idle = 0;
            worker_sockets[thread_slot] = csd;
            bucket_alloc = apr_bucket_alloc_create(ptrans);
            process_socket(thd, ptrans, csd, process_slot, thread_slot, bucket_alloc);
            worker_sockets[thread_slot] = NULL;
            requests_this_child--;
            apr_pool_clear(ptrans);
            last_ptrans = ptrans;
        }
    
        ap_update_child_status_from_indexes(process_slot, thread_slot,
                                            dying ? SERVER_DEAD
                                                  : SERVER_GRACEFUL, 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 *)ap_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 = ap_thread_create(&ts->listener, thread_attr, listener_thread,
                              my_info, pruntime);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(00275)
                         "ap_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);
    }
    
    static void setup_threads_runtime(void)
    {
        ap_listen_rec *lr;
        int pollset_flags;
        apr_status_t rv;
    
        /* All threads (listener, workers) and synchronization objects (queues,
         * pollset, mutexes...) created here should have at least the lifetime of
         * the connections they handle (i.e. ptrans). We can't use this thread's
         * self pool because all these objects survive it, nor use pchild or pconf
         * directly because this starter thread races with other modules' runtime,
         * nor finally pchild (or subpool thereof) because it is killed explicitly
         * before pconf (thus connections/ptrans can live longer, which matters in
         * ONE_PROCESS mode). So this leaves us with a subpool of pconf, created
         * before any ptrans hence destroyed after.
         */
        apr_pool_create(&pruntime, pconf);
        apr_pool_tag(pruntime, "mpm_runtime");
    
        /* We must create the fd queues before we start up the listener
         * and worker threads. */
        rv = ap_queue_create(&worker_queue, threads_per_child, pruntime);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03140)
                         "ap_queue_create() failed");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        rv = ap_queue_info_create(&worker_queue_info, pruntime,
                                  threads_per_child, -1);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03141)
                         "ap_queue_info_create() failed");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        /* Create the main pollset. When APR_POLLSET_WAKEABLE is asked we account
         * for the wakeup pipe explicitely with num_listensocks+1 because some
         * pollset implementations don't do it implicitely in APR.
         */
        pollset_flags = APR_POLLSET_NOCOPY | APR_POLLSET_WAKEABLE;
        rv = apr_pollset_create(&worker_pollset, num_listensocks + 1, pruntime,
                                pollset_flags);
        if (rv == APR_SUCCESS) {
            listener_is_wakeable = 1;
        }
        else {
            pollset_flags &= ~APR_POLLSET_WAKEABLE;
            rv = apr_pollset_create(&worker_pollset, num_listensocks, pruntime,
                                    pollset_flags);
        }
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(03285)
                         "Couldn't create pollset in thread;"
                         " check system or user limits");
            /* let the parent decide how bad this really is */
            clean_child_exit(APEXIT_CHILDSICK);
        }
    
        for (lr = my_bucket->listeners; lr != NULL; lr = lr->next) {
            apr_pollfd_t *pfd = apr_pcalloc(pruntime, sizeof *pfd);
    
            pfd->desc_type = APR_POLL_SOCKET;
            pfd->desc.s = lr->sd;
            pfd->reqevents = APR_POLLIN;
            pfd->client_data = lr;
    
            rv = apr_pollset_add(worker_pollset, pfd);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(03286)
                             "Couldn't create add listener to pollset;"
                             " check system or user limits");
                /* let the parent decide how bad this really is */
                clean_child_exit(APEXIT_CHILDSICK);
            }
    
            lr->accept_func = ap_unixd_accept;
        }
    
        worker_sockets = apr_pcalloc(pruntime, threads_per_child *
                                               sizeof(apr_socket_t *));
    }
    
    /* 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 my_child_num = ts->child_num_arg;
        proc_info *my_info;
        apr_status_t rv;
        int threads_created = 0;
        int listener_started = 0;
        int prev_threads_created;
        int loops, i;
    
        loops = prev_threads_created = 0;
        while (1) {
            /* threads_per_child does not include the listener thread */
            for (i = 0; i < threads_per_child; i++) {
                int status = ap_scoreboard_image->servers[my_child_num][i].status;
    
                if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
                    continue;
                }
    
                my_info = (proc_info *)ap_malloc(sizeof(proc_info));
                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 = ap_thread_create(&threads[i], thread_attr,
                                      worker_thread, my_info, pruntime);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03142)
                                 "ap_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 == 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, 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 mode)
    {
        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 (!dying) {
                apr_sleep(apr_time_from_msec(500));
                if (dying || ++iter > 10) {
                    break;
                }
                /* listener has not stopped accepting yet */
                ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
                             "listener has not stopped accepting yet (%d iter)", iter);
                wakeup_listener();
            }
            if (iter > 10) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00276)
                             "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, APLOGNO(00277)
                                 "apr_thread_join: unable to join listener thread");
                }
            }
        }
    
        for (i = 0; i < threads_per_child; i++) {
            if (threads[i]) { /* if we ever created this thread */
                if (mode != ST_GRACEFUL) {
    #ifdef HAVE_PTHREAD_KILL
                    apr_os_thread_t *worker_os_thread;
    
                    apr_os_thread_get(&worker_os_thread, threads[i]);
                    pthread_kill(*worker_os_thread, WORKER_SIGNAL);
    #endif
                }
    
                rv = apr_thread_join(&thread_rv, threads[i]);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00278)
                                 "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, APLOGNO(00279)
                         "apr_thread_join: unable to join the start "
                         "thread");
        }
    }
    
    static void child_main(int child_num_arg, int child_bucket)
    {
        apr_thread_t **threads;
        apr_status_t rv;
        thread_starter *ts;
        apr_threadattr_t *thread_attr;
        apr_thread_t *start_thread_id;
        int i;
    
        /* for benefit of any hooks that run as this child initializes */
        retained->mpm->mpm_state = AP_MPMQ_STARTING;
    
        ap_my_pid = getpid();
        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_pool_create(&pchild, pconf);
        apr_pool_tag(pchild, "pchild");
    
    #if AP_HAS_THREAD_LOCAL
        if (!one_process) {
            apr_thread_t *thd = NULL;
            if ((rv = ap_thread_main_create(&thd, pchild))) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(10375)
                             "Couldn't initialize child main thread");
                clean_child_exit(APEXIT_CHILDFATAL);
            }
        }
    #endif
    
        /* close unused listeners and pods */
        for (i = 0; i < retained->mpm->num_buckets; i++) {
            if (i != child_bucket) {
                ap_close_listeners_ex(all_buckets[i].listeners);
                ap_mpm_podx_close(all_buckets[i].pod);
            }
        }
    
        /*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(&my_bucket->mutex,
                                        apr_proc_mutex_lockfile(my_bucket->mutex),
                                        pchild));
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00280)
                         "Couldn't initialize cross-process lock in child");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        /* done with init critical section */
        if (ap_run_drop_privileges(pchild, ap_server_conf)) {
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        /* 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. Let's also do this before
         * child_init() hooks are called and possibly create threads that
         * otherwise could "steal" (implicitly) MPM's signals.
         */
        rv = apr_setup_signal_thread();
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00281)
                         "Couldn't initialize signal thread");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        ap_run_child_init(pchild, ap_server_conf);
    
        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 threads */
    
        /* Globals used by signal_threads() so to be initialized before */
        setup_threads_runtime();
    
        /* 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 **)ap_calloc(1,
                                      sizeof(apr_thread_t *) * threads_per_child);
        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) {
            rv = apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
            if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(02435)
                             "WARNING: ThreadStackSize of %" APR_SIZE_T_FMT " is "
                             "inappropriate, using default", 
                             ap_thread_stacksize);
            }
        }
    
        ts->threads = threads;
        ts->listener = NULL;
        ts->child_num_arg = child_num_arg;
        ts->threadattr = thread_attr;
    
        rv = ap_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, APLOGNO(00282)
                         "ap_thread_create: unable to create worker thread");
            /* let the parent decide how bad this really is */
            clean_child_exit(APEXIT_CHILDSICK);
        }
    
        retained->mpm->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, ST_UNGRACEFUL);
        }
        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 MaxConnectionsPerChild) it will send us SIGTERM
             */
            apr_signal(SIGTERM, dummy_signal_handler);
            unblock_signal(SIGTERM);
            /* Watch for any messages from the parent over the POD */
            while (1) {
                rv = ap_mpm_podx_check(my_bucket->pod);
                if (rv == AP_MPM_PODX_NORESTART) {
                    /* see if termination was triggered while we slept */
                    switch(terminate_mode) {
                    case ST_GRACEFUL:
                        rv = AP_MPM_PODX_GRACEFUL;
                        break;
                    case ST_UNGRACEFUL:
                        rv = AP_MPM_PODX_RESTART;
                        break;
                    }
                }
                if (rv == AP_MPM_PODX_GRACEFUL || rv == AP_MPM_PODX_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_MPM_PODX_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,
                         rv == AP_MPM_PODX_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
        }
    
        free(threads);
    
        clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
    }
    
    static int make_child(server_rec *s, int slot, int bucket)
    {
        int pid;
    
        if (slot + 1 > retained->max_daemons_limit) {
            retained->max_daemons_limit = slot + 1;
        }
    
        if (one_process) {
            my_bucket = &all_buckets[0];
    
            worker_note_child_started(slot, getpid());
            child_main(slot, 0);
            /* NOTREACHED */
            ap_assert(0);
            return -1;
        }
    
        if ((pid = fork()) == -1) {
            ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, APLOGNO(00283)
                         "fork: Unable to fork new process");
            /* fork didn't succeed.  There's no need to touch the scoreboard;
             * if we were trying to replace a failed child process, then
             * server_main_loop() marked its workers SERVER_DEAD, and if
             * we were trying to replace a child process that exited normally,
             * its worker_thread()s left SERVER_DEAD or SERVER_GRACEFUL behind.
             */
    
            /* 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) {
    #if AP_HAS_THREAD_LOCAL
            ap_thread_current_after_fork();
    #endif
    
            my_bucket = &all_buckets[bucket];
    
    #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_DEBUG, errno,
                             ap_server_conf, APLOGNO(00284)
                             "processor unbind failed");
    #endif
            RAISE_SIGSTOP(MAKE_CHILD);
    
            apr_signal(SIGTERM, just_die);
            child_main(slot, bucket);
            /* NOTREACHED */
            ap_assert(0);
            return -1;
        }
    
        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.
             */
            worker_note_child_lost_slot(slot, pid);
        }
        ap_scoreboard_image->parent[slot].quiescing = 0;
        worker_note_child_started(slot, 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, i % retained->mpm->num_buckets) < 0) {
                break;
            }
            --number_to_start;
        }
    }
    
    static void perform_idle_server_maintenance(int child_bucket)
    {
        int num_buckets = retained->mpm->num_buckets;
        int idle_thread_count;
        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;
        int i, j;
    
        /* 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 threads_per_child is always > 0 */
            int any_dying_threads = 0;
            int any_dead_threads = 0;
            int all_dead_threads = 1;
            int child_threads_active = 0;
    
            if (num_buckets > 1 && (i % num_buckets) != child_bucket) {
                /* We only care about child_bucket in this call */
                continue;
            }
            if (i >= retained->max_daemons_limit &&
                totally_free_length == retained->idle_spawn_rate[child_bucket]) {
                /* short cut if all active processes have been examined and
                 * enough empty scoreboard slots have been found
                 */
                break;
            }
            ps = &ap_scoreboard_image->parent[i];
            for (j = 0; j < threads_per_child; j++) {
                int status = ap_scoreboard_image->servers[i][j].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 &&
                            !ps->quiescing &&
                            ps->generation == retained->mpm->my_generation) {
                        ++idle_thread_count;
                    }
                    if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
                        ++child_threads_active;
                    }
                }
            }
            active_thread_count += child_threads_active;
            if (any_dead_threads
                    && totally_free_length < retained->idle_spawn_rate[child_bucket]
                    && free_length < MAX_SPAWN_RATE / num_buckets
                    && (!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;
            }
            else if (child_threads_active == threads_per_child) {
                had_healthy_child = 1;
            }
            /* XXX if (!ps->quiescing)     is probably more reliable  GLA */
            if (!any_dying_threads) {
                ++total_non_dead;
            }
            if (ps->pid != 0) {
                last_non_dead = i;
            }
        }
    
        retained->max_daemons_limit = last_non_dead + 1;
    
        if (retained->sick_child_detected) {
            if (had_healthy_child) {
                /* Assume this is a transient error, even though it may not be.  Leave
                 * the server up in case it is able to serve some requests or the
                 * problem will be resolved.
                 */
                retained->sick_child_detected = 0;
            }
            else if (child_bucket < num_buckets - 1) {
                /* check for had_healthy_child up to the last child bucket */
                return;
            }
            else {
                /* looks like a basket case, as no child ever fully initialized; give up.
                 */
                retained->mpm->shutdown_pending = 1;
                child_fatal = 1;
                ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
                             ap_server_conf, APLOGNO(02325)
                             "A resource shortage or other unrecoverable failure "
                             "was encountered before any child process initialized "
                             "successfully... httpd is exiting!");
                /* the child already logged the failure details */
                return;
            }
        }
    
        if (idle_thread_count > max_spare_threads / num_buckets) {
            /* Kill off one child */
            ap_mpm_podx_signal(all_buckets[child_bucket].pod,
                               AP_MPM_PODX_GRACEFUL);
            retained->idle_spawn_rate[child_bucket] = 1;
        }
        else if (idle_thread_count < min_spare_threads / num_buckets) {
            /* terminate the free list */
            if (free_length == 0) { /* scoreboard is full, can't fork */
    
                if (active_thread_count >= max_workers / num_buckets) {
                    /* no threads are "inactive" - starting, stopping, etc. */
                    /* have we reached MaxRequestWorkers, or just getting close? */
                    if (0 == idle_thread_count) {
                        if (!retained->maxclients_reported) {
                            /* only report this condition once */
                            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00286)
                                         "server reached MaxRequestWorkers "
                                         "setting, consider raising the "
                                         "MaxRequestWorkers setting");
                            retained->maxclients_reported = 1;
                        }
                    } else {
                        if (!retained->near_maxclients_reported) {
                            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00287)
                                         "server is within MinSpareThreads of "
                                         "MaxRequestWorkers, consider raising the "
                                         "MaxRequestWorkers setting");
                            retained->near_maxclients_reported = 1;
                        }
                    }
                }
                else {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                                 ap_server_conf, APLOGNO(00288)
                                 "scoreboard is full, not at MaxRequestWorkers");
                }
                retained->idle_spawn_rate[child_bucket] = 1;
            }
            else {
                if (free_length > retained->idle_spawn_rate[child_bucket]) {
                    free_length = retained->idle_spawn_rate[child_bucket];
                }
                if (retained->idle_spawn_rate[child_bucket] >= 8) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0,
                                 ap_server_conf, APLOGNO(00289)
                                 "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], child_bucket);
                }
                /* 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 (retained->hold_off_on_exponential_spawning) {
                    --retained->hold_off_on_exponential_spawning;
                }
                else if (retained->idle_spawn_rate[child_bucket]
                         < MAX_SPAWN_RATE / num_buckets) {
                    retained->idle_spawn_rate[child_bucket] *= 2;
                }
            }
        }
        else {
            retained->idle_spawn_rate[child_bucket] = 1;
        }
    }
    
    static void server_main_loop(int remaining_children_to_start)
    {
        int num_buckets = retained->mpm->num_buckets;
        int successive_kills = 0;
        ap_generation_t old_gen;
        int child_slot;
        apr_exit_why_e exitwhy;
        int status, processed_status;
        apr_proc_t pid;
        int i;
    
        while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) {
            ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
    
            if (pid.pid != -1) {
                processed_status = ap_process_child_status(&pid, exitwhy, status);
                child_slot = ap_find_child_by_pid(&pid);
                if (processed_status == APEXIT_CHILDFATAL) {
                    /* fix race condition found in PR 39311
                     * A child created at the same time as a graceful happens 
                     * can find the lock missing and create a fatal error.
                     * It is not fatal for the last generation to be in this state.
                     */
                    if (child_slot < 0
                        || ap_get_scoreboard_process(child_slot)->generation
                           == retained->mpm->my_generation) {
                        retained->mpm->shutdown_pending = 1;
                        child_fatal = 1;
                        return;
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(00290)
                                     "Ignoring fatal error in child of previous "
                                     "generation (pid %ld).",
                                     (long)pid.pid);
                        retained->sick_child_detected = 1;
                    }
                }
                else if (processed_status == APEXIT_CHILDSICK) {
                    /* tell perform_idle_server_maintenance to check into this
                     * on the next timer pop
                     */
                    retained->sick_child_detected = 1;
                }
                /* non-fatal death... note that it's gone in the scoreboard. */
                if (child_slot >= 0) {
                    process_score *ps;
    
                    for (i = 0; i < threads_per_child; i++)
                        ap_update_child_status_from_indexes(child_slot, i,
                                                            SERVER_DEAD, NULL);
    
                    worker_note_child_killed(child_slot, 0, 0);
                    ps = &ap_scoreboard_image->parent[child_slot];
                    ps->quiescing = 0;
                    if (processed_status == APEXIT_CHILDSICK) {
                        /* resource shortage, minimize the fork rate */
                        retained->idle_spawn_rate[child_slot % num_buckets] = 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,
                                   child_slot % num_buckets);
                        --remaining_children_to_start;
                    }
                }
                else if (ap_unregister_extra_mpm_process(pid.pid, &old_gen) == 1) {
                    worker_note_child_killed(-1, /* already out of the scoreboard */
                                             pid.pid, old_gen);
                    if (processed_status == APEXIT_CHILDSICK
                        && old_gen == retained->mpm->my_generation) {
                        /* resource shortage, minimize the fork rate */
                        for (i = 0; i < num_buckets; i++) {
                            retained->idle_spawn_rate[i] = 1;
                        }
                    }
    #if APR_HAS_OTHER_CHILD
                }
                else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
                                                    status) == 0) {
                    /* handled */
    #endif
                }
                else if (retained->mpm->was_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, APLOGNO(00291)
                                 "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.  If a child is
                 * killed by a signal (faulting) we want to restart it ASAP
                 * though, up to 3 successive faults or we stop this until
                 * a timeout happens again (to avoid the flood of fork()ed
                 * processes that keep being killed early).
                 */
                if (child_slot < 0 || !APR_PROC_CHECK_SIGNALED(exitwhy)) {
                    continue;
                }
                if (++successive_kills >= 3) {
                    if (successive_kills % 10 == 3) {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
                                     ap_server_conf, APLOGNO(10393)
                                     "children are killed successively!");
                    }
                    continue;
                }
                ++remaining_children_to_start;
            }
            else {
                successive_kills = 0;
            }
    
            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;
            }
    
            for (i = 0; i < num_buckets; i++) {
                perform_idle_server_maintenance(i);
            }
        }
    }
    
    static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
    {
        int num_buckets = retained->mpm->num_buckets;
        int remaining_children_to_start;
        int i;
    
        ap_log_pid(pconf, ap_pid_fname);
    
        if (!retained->mpm->was_graceful) {
            if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
                retained->mpm->mpm_state = AP_MPMQ_STOPPING;
                return !OK;
            }
            /* fix the generation number in the global score; we just got a new,
             * cleared scoreboard
             */
            ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
        }
    
        ap_unixd_mpm_set_signals(pconf, one_process);
    
        /* Don't thrash since num_buckets depends on the
         * system and the number of online CPU cores...
         */
        if (ap_daemons_limit < num_buckets)
            ap_daemons_limit = num_buckets;
        if (ap_daemons_to_start < num_buckets)
            ap_daemons_to_start = num_buckets;
        /* We want to create as much children at a time as the number of buckets,
         * so to optimally accept connections (evenly distributed across buckets).
         * Thus min_spare_threads should at least maintain num_buckets children,
         * and max_spare_threads allow num_buckets more children w/o triggering
         * immediately (e.g. num_buckets idle threads margin, one per bucket).
         */
        if (min_spare_threads < threads_per_child * (num_buckets - 1) + num_buckets)
            min_spare_threads = threads_per_child * (num_buckets - 1) + num_buckets;
        if (max_spare_threads < min_spare_threads + (threads_per_child + 1) * num_buckets)
            max_spare_threads = min_spare_threads + (threads_per_child + 1) * num_buckets;
    
        /* 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 may start a new one, until
         * there are at least min_spare_threads idle threads, counting across
         * all children.  But we may be permitted to start more children 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 (!retained->mpm->was_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 */
            retained->hold_off_on_exponential_spawning = 10;
        }
    
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00292)
                    "%s configured -- resuming normal operations",
                    ap_get_server_description());
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00293)
                    "Server built: %s", ap_get_server_built());
        ap_log_command_line(plog, s);
        ap_log_mpm_common(s);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00294)
                    "Accept mutex: %s (default: %s)",
                    (all_buckets[0].mutex)
                        ? apr_proc_mutex_name(all_buckets[0].mutex)
                        : "none",
                    apr_proc_mutex_defname());
        retained->mpm->mpm_state = AP_MPMQ_RUNNING;
    
        server_main_loop(remaining_children_to_start);
        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
    
        if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) {
            /* Time to shut down:
             * Kill child processes, tell them to call child_exit, etc...
             */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
                                   AP_MPM_PODX_RESTART);
            }
            ap_reclaim_child_processes(1, /* Start with SIGTERM */
                                       worker_note_child_killed);
    
            if (!child_fatal) {
                /* cleanup pid file on normal shutdown */
                ap_remove_pid(pconf, ap_pid_fname);
                ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
                             ap_server_conf, APLOGNO(00295) "caught SIGTERM, shutting down");
            }
            return DONE;
        }
    
        if (retained->mpm->shutdown_pending) {
            /* Time to gracefully shut down:
             * Kill child processes, tell them to call child_exit, etc...
             */
            int active_children;
            int index;
            apr_time_t cutoff = 0;
    
            /* Close our listeners, and then ask our children to do same */
            ap_close_listeners();
    
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
                                   AP_MPM_PODX_GRACEFUL);
            }
            ap_relieve_child_processes(worker_note_child_killed);
    
            if (!child_fatal) {
                /* cleanup pid file on normal shutdown */
                ap_remove_pid(pconf, ap_pid_fname);
                ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00296)
                             "caught " AP_SIG_GRACEFUL_STOP_STRING
                             ", shutting down gracefully");
            }
    
            if (ap_graceful_shutdown_timeout) {
                cutoff = apr_time_now() +
                         apr_time_from_sec(ap_graceful_shutdown_timeout);
            }
    
            /* Don't really exit until each child has finished */
            retained->mpm->shutdown_pending = 0;
            do {
                /* Pause for a second */
                apr_sleep(apr_time_from_sec(1));
    
                /* Relieve any children which have now exited */
                ap_relieve_child_processes(worker_note_child_killed);
    
                active_children = 0;
                for (index = 0; index < ap_daemons_limit; ++index) {
                    if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
                        active_children = 1;
                        /* Having just one child is enough to stay around */
                        break;
                    }
                }
            } while (!retained->mpm->shutdown_pending && active_children &&
                     (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
    
            /* We might be here because we received SIGTERM, either
             * way, try and make sure that all of our processes are
             * really dead.
             */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
                                   AP_MPM_PODX_RESTART);
            }
            ap_reclaim_child_processes(1, worker_note_child_killed);
    
            return DONE;
        }
    
        /* we've been told to restart */
        if (one_process) {
            /* not worth thinking about */
            return DONE;
        }
    
        /* 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.
         */
        ++retained->mpm->my_generation;
        ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
    
        if (!retained->mpm->is_ungraceful) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00297)
                         AP_SIG_GRACEFUL_STRING " received.  Doing graceful restart");
            /* wake up the children...time to die.  But we'll have more soon */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
                                   AP_MPM_PODX_GRACEFUL);
            }
    
            /* 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.
             */
            for (i = 0; i < num_buckets; i++) {
                ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
                                   AP_MPM_PODX_RESTART);
            }
    
            ap_reclaim_child_processes(1, /* Start with SIGTERM */
                                       worker_note_child_killed);
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00298)
                        "SIGHUP received.  Attempting to restart");
        }
    
        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 worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
    {
        int startup = 0;
        int level_flags = 0;
        int num_buckets = 0;
        ap_listen_rec **listen_buckets;
        apr_status_t rv;
        char id[16];
        int i;
    
        pconf = p;
    
        /* the reverse of pre_config, we want this only the first time around */
        if (retained->mpm->module_loads == 1) {
            startup = 1;
            level_flags |= APLOG_STARTUP;
        }
    
        if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
            ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
                         (startup ? NULL : s),
                         "no listening sockets available, shutting down");
            return !OK;
        }
    
        if (one_process) {
            num_buckets = 1;
        }
        else if (retained->mpm->was_graceful) {
            /* Preserve the number of buckets on graceful restarts. */
            num_buckets = retained->mpm->num_buckets;
        }
        if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
                                         &listen_buckets, &num_buckets))) {
            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                         (startup ? NULL : s),
                         "could not duplicate listeners");
            return !OK;
        }
    
        all_buckets = apr_pcalloc(pconf, num_buckets * sizeof(*all_buckets));
        for (i = 0; i < num_buckets; i++) {
            if (!one_process && /* no POD in one_process mode */
                    (rv = ap_mpm_podx_open(pconf, &all_buckets[i].pod))) {
                ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                             (startup ? NULL : s),
                             "could not open pipe-of-death");
                return !OK;
            }
            /* Initialize cross-process accept lock (safe accept needed only) */
            if ((rv = SAFE_ACCEPT((apr_snprintf(id, sizeof id, "%i", i),
                                   ap_proc_mutex_create(&all_buckets[i].mutex,
                                                        NULL, AP_ACCEPT_MUTEX_TYPE,
                                                        id, s, pconf, 0))))) {
                ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                             (startup ? NULL : s),
                             "could not create accept mutex");
                return !OK;
            }
            all_buckets[i].listeners = listen_buckets[i];
        }
    
        if (retained->mpm->max_buckets < num_buckets) {
            int new_max, *new_ptr;
            new_max = retained->mpm->max_buckets * 2;
            if (new_max < num_buckets) {
                new_max = num_buckets;
            }
            new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
            if (retained->idle_spawn_rate) /* NULL at startup */
                memcpy(new_ptr, retained->idle_spawn_rate,
                       retained->mpm->num_buckets * sizeof(int));
            retained->idle_spawn_rate = new_ptr;
            retained->mpm->max_buckets = new_max;
        }
        if (retained->mpm->num_buckets < num_buckets) {
            int rate_max = 1;
            /* If new buckets are added, set their idle spawn rate to
             * the highest so far, so that they get filled as quickly
             * as the existing ones.
             */
            for (i = 0; i < retained->mpm->num_buckets; i++) {
                if (rate_max < retained->idle_spawn_rate[i]) {
                    rate_max = retained->idle_spawn_rate[i];
                }
            }
            for (/* up to date i */; i < num_buckets; i++) {
                retained->idle_spawn_rate[i] = rate_max;
            }
        }
        retained->mpm->num_buckets = num_buckets;
    
        return OK;
    }
    
    static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                 apr_pool_t *ptemp)
    {
        int no_detach, debug, foreground;
        apr_status_t rv;
        const char *userdata_key = "mpm_worker_module";
    
        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");
        }
    
        ap_mutex_register(pconf, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
    
        retained = ap_retained_data_get(userdata_key);
        if (!retained) {
            retained = ap_retained_data_create(userdata_key, sizeof(*retained));
            retained->mpm = ap_unixd_mpm_get_retained_data();
        }
        retained->mpm->mpm_state = AP_MPMQ_STARTING;
        if (retained->mpm->baton != retained) {
            retained->mpm->was_graceful = 0;
            retained->mpm->baton = retained;
        }
        ++retained->mpm->module_loads;
    
        /* sigh, want this only the second time around */
        if (retained->mpm->module_loads == 2) {
            if (!one_process && !foreground) {
                /* before we detach, setup crash handlers to log to errorlog */
                ap_fatal_signal_setup(ap_server_conf, pconf);
                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, APLOGNO(00299)
                                 "apr_proc_detach failed");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
        }
    
        parent_pid = ap_my_pid = getpid();
    
        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;
        server_limit = DEFAULT_SERVER_LIMIT;
        thread_limit = DEFAULT_THREAD_LIMIT;
        ap_daemons_limit = server_limit;
        threads_per_child = DEFAULT_THREADS_PER_CHILD;
        max_workers = ap_daemons_limit * threads_per_child;
        had_healthy_child = 0;
        ap_extended_status = 0;
    
        return OK;
    }
    
    static int worker_check_config(apr_pool_t *p, apr_pool_t *plog,
                                   apr_pool_t *ptemp, server_rec *s)
    {
        int startup = 0;
    
        /* the reverse of pre_config, we want this only the first time around */
        if (retained->mpm->module_loads == 1) {
            startup = 1;
        }
    
        if (server_limit > MAX_SERVER_LIMIT) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00300)
                             "WARNING: ServerLimit of %d exceeds compile-time "
                             "limit of %d servers, decreasing to %d.",
                             server_limit, MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00301)
                             "ServerLimit of %d exceeds compile-time limit "
                             "of %d, decreasing to match",
                             server_limit, MAX_SERVER_LIMIT);
            }
            server_limit = MAX_SERVER_LIMIT;
        }
        else if (server_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00302)
                             "WARNING: ServerLimit of %d not allowed, "
                             "increasing to 1.", server_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00303)
                             "ServerLimit of %d not allowed, increasing to 1",
                             server_limit);
            }
            server_limit = 1;
        }
    
        /* you cannot change ServerLimit across a restart; ignore
         * any such attempts
         */
        if (!retained->first_server_limit) {
            retained->first_server_limit = server_limit;
        }
        else if (server_limit != retained->first_server_limit) {
            /* don't need a startup console version here */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00304)
                         "changing ServerLimit to %d from original value of %d "
                         "not allowed during restart",
                         server_limit, retained->first_server_limit);
            server_limit = retained->first_server_limit;
        }
    
        if (thread_limit > MAX_THREAD_LIMIT) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00305)
                             "WARNING: ThreadLimit of %d exceeds compile-time "
                             "limit of %d threads, decreasing to %d.",
                             thread_limit, MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00306)
                             "ThreadLimit of %d exceeds compile-time limit "
                             "of %d, decreasing to match",
                             thread_limit, MAX_THREAD_LIMIT);
            }
            thread_limit = MAX_THREAD_LIMIT;
        }
        else if (thread_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00307)
                             "WARNING: ThreadLimit of %d not allowed, "
                             "increasing to 1.", thread_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00308)
                             "ThreadLimit of %d not allowed, increasing to 1",
                             thread_limit);
            }
            thread_limit = 1;
        }
    
        /* you cannot change ThreadLimit across a restart; ignore
         * any such attempts
         */
        if (!retained->first_thread_limit) {
            retained->first_thread_limit = thread_limit;
        }
        else if (thread_limit != retained->first_thread_limit) {
            /* don't need a startup console version here */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00309)
                         "changing ThreadLimit to %d from original value of %d "
                         "not allowed during restart",
                         thread_limit, retained->first_thread_limit);
            thread_limit = retained->first_thread_limit;
        }
    
        if (threads_per_child > thread_limit) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00310)
                             "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
                             "of %d threads, decreasing to %d. "
                             "To increase, please see the ThreadLimit directive.",
                             threads_per_child, thread_limit, thread_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00311)
                             "ThreadsPerChild of %d exceeds ThreadLimit "
                             "of %d, decreasing to match",
                             threads_per_child, thread_limit);
            }
            threads_per_child = thread_limit;
        }
        else if (threads_per_child < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00312)
                             "WARNING: ThreadsPerChild of %d not allowed, "
                             "increasing to 1.", threads_per_child);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00313)
                             "ThreadsPerChild of %d not allowed, increasing to 1",
                             threads_per_child);
            }
            threads_per_child = 1;
        }
    
        if (max_workers < threads_per_child) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00314)
                             "WARNING: MaxRequestWorkers of %d is less than "
                             "ThreadsPerChild of %d, increasing to %d. "
                             "MaxRequestWorkers must be at least as large "
                             "as the number of threads in a single server.",
                             max_workers, threads_per_child, threads_per_child);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00315)
                             "MaxRequestWorkers of %d is less than ThreadsPerChild "
                             "of %d, increasing to match",
                             max_workers, threads_per_child);
            }
            max_workers = threads_per_child;
        }
    
        ap_daemons_limit = max_workers / threads_per_child;
    
        if (max_workers % threads_per_child) {
            int tmp_max_workers = ap_daemons_limit * threads_per_child;
    
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00316)
                             "WARNING: MaxRequestWorkers of %d is not an integer "
                             "multiple of ThreadsPerChild of %d, decreasing to nearest "
                             "multiple %d, for a maximum of %d servers.",
                             max_workers, threads_per_child, tmp_max_workers,
                             ap_daemons_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00317)
                             "MaxRequestWorkers of %d is not an integer multiple of "
                             "ThreadsPerChild of %d, decreasing to nearest "
                             "multiple %d", max_workers, threads_per_child,
                             tmp_max_workers);
            }
            max_workers = tmp_max_workers;
        }
    
        if (ap_daemons_limit > server_limit) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00318)
                             "WARNING: MaxRequestWorkers of %d would require %d "
                             "servers and would exceed ServerLimit of %d, decreasing to %d. "
                             "To increase, please see the ServerLimit directive.",
                             max_workers, ap_daemons_limit, server_limit,
                             server_limit * threads_per_child);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00319)
                             "MaxRequestWorkers of %d would require %d servers and "
                             "exceed ServerLimit of %d, decreasing to %d",
                             max_workers, ap_daemons_limit, server_limit,
                             server_limit * threads_per_child);
            }
            ap_daemons_limit = server_limit;
        }
    
        /* ap_daemons_to_start > ap_daemons_limit checked in worker_run() */
        if (ap_daemons_to_start < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00320)
                             "WARNING: StartServers of %d not allowed, "
                             "increasing to 1.", ap_daemons_to_start);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00321)
                             "StartServers of %d not allowed, increasing to 1",
                             ap_daemons_to_start);
            }
            ap_daemons_to_start = 1;
        }
    
        if (min_spare_threads < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00322)
                             "WARNING: MinSpareThreads of %d not allowed, "
                             "increasing to 1 to avoid almost certain server failure. "
                             "Please read the documentation.", min_spare_threads);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00323)
                             "MinSpareThreads of %d not allowed, increasing to 1",
                             min_spare_threads);
            }
            min_spare_threads = 1;
        }
    
        /* max_spare_threads < min_spare_threads + threads_per_child
         * checked in worker_run()
         */
    
        return OK;
    }
    
    static void worker_hooks(apr_pool_t *p)
    {
        /* Our open_logs hook function 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_REALLY_FIRST);
        /* 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);
        ap_hook_check_config(worker_check_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm(worker_run, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_query(worker_query, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_get_name(worker_get_name, 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;
        }
    
        min_spare_threads = atoi(arg);
        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_workers (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(cmd->cmd->name, "MaxClients")) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(00324)
                         "MaxClients is deprecated, use MaxRequestWorkers "
                         "instead.");
        }
        max_workers = atoi(arg);
        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;
        }
    
        threads_per_child = atoi(arg);
        return NULL;
    }
    
    static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
    
        server_limit = 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;
        }
    
        thread_limit = atoi(arg);
        return NULL;
    }
    
    static const command_rec worker_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 threads, to handle request spikes"),
    AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
      "Maximum number of idle threads"),
    AP_INIT_TAKE1("MaxRequestWorkers", set_max_workers, NULL, RSRC_CONF,
      "Maximum number of threads alive at the same time"),
    AP_INIT_TAKE1("MaxClients", set_max_workers, NULL, RSRC_CONF,
      "Deprecated name of MaxRequestWorkers"),
    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"),
    AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
    { NULL }
    };
    
    AP_DECLARE_MODULE(mpm_worker) = {
        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 */
        worker_cmds,                /* command apr_table_t */
        worker_hooks                /* register_hooks */
    };
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/worker/config.m4������������������������������������������������������������0000664�0001751�0001751�00000000711�11173774721�017752� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_MSG_CHECKING(if worker MPM supports this platform)
    if test $forking_mpms_supported != yes; then
        AC_MSG_RESULT(no - This is not a forking platform)
    elif test $ac_cv_define_APR_HAS_THREADS != yes; then
        AC_MSG_RESULT(no - APR does not support threads)
    elif test $have_threaded_sig_graceful != yes; then
        AC_MSG_RESULT(no - SIG_GRACEFUL cannot be used with a threaded MPM)
    else
        AC_MSG_RESULT(yes)
        APACHE_MPM_SUPPORTED(worker, yes, yes)
    fi
    �������������������������������������������������������httpd-2.4.64/server/mpm/worker/mpm_default.h��������������������������������������������������������0000664�0001751�0001751�00000003142�11711754075�020710� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  worker/mpm_default.h
     * @brief Worker MPM defaults
     *
     * @defgroup APACHE_MPM_WORKER Worker MPM
     * @ingroup APACHE_INTERNAL
     * @{
     */
    
    #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
    
    #endif /* AP_MPM_DEFAULT_H */
    /** @} */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/worker/config3.m4�����������������������������������������������������������0000664�0001751�0001751�00000000242�13243014561�020021� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl ## XXX - Need a more thorough check of the proper flags to use
    
    APACHE_MPM_MODULE(worker, $enable_mpm_worker, worker.lo,[
        AC_CHECK_FUNCS(pthread_kill)
    ])
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/worker/Makefile.in����������������������������������������������������������0000664�0001751�0001751�00000000050�11274040000�020256� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    include $(top_srcdir)/build/special.mk
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/prefork/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016403� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/prefork/config3.m4����������������������������������������������������������0000664�0001751�0001751�00000000060�11274040000�020143� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������APACHE_MPM_MODULE(prefork, $enable_mpm_prefork)
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/prefork/mpm_default.h�������������������������������������������������������0000664�0001751�0001751�00000003027�11711754075�021051� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  prefork/mpm_default.h
     * @brief Prefork MPM defaults
     *
     * @defgroup APACHE_MPM_PREFORK Prefork MPM
     * @ingroup APACHE_INTERNAL
     * @{
     */
    
    #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
    
    #endif /* AP_MPM_DEFAULT_H */
    /** @} */
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/prefork/prefork.c�����������������������������������������������������������0000664�0001751�0001751�00000157015�14207134173�020220� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <unistd.h>
    #endif
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    
    #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 "util_mutex.h"
    #include "unixd.h"
    #include "mpm_common.h"
    #include "ap_listen.h"
    #include "ap_mmn.h"
    #include "apr_poll.h"
    
    #include <stdlib.h>
    
    #ifdef HAVE_TIME_H
    #include <time.h>
    #endif
    #ifdef HAVE_SYS_PROCESSOR_H
    #include <sys/processor.h> /* for bindprocessor() */
    #endif
    
    #include <signal.h>
    #include <sys/times.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 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 */
    
    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;      /* MaxRequestWorkers */
    static int server_limit = 0;
    
    /* data retained by prefork across load/unload of the module
     * allocated on first call to pre-config hook; located on
     * subsequent calls to pre-config hook
     */
    typedef struct prefork_retained_data {
        ap_unixd_mpm_retained_data *mpm;
    
        int first_server_limit;
        int maxclients_reported;
        /*
         * The max child slot ever assigned, preserved across restarts.  Necessary
         * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts.  We
         * use this value to optimize routines that have to scan the entire scoreboard.
         */
        int max_daemons_limit;
        /*
         * 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.
         */
        int idle_spawn_rate;
    #ifndef MAX_SPAWN_RATE
    #define MAX_SPAWN_RATE  (32)
    #endif
        int hold_off_on_exponential_spawning;
    } prefork_retained_data;
    static prefork_retained_data *retained;
    
    typedef struct prefork_child_bucket {
        ap_pod_t *pod;
        ap_listen_rec *listeners;
        apr_proc_mutex_t *mutex;
    } prefork_child_bucket;
    static prefork_child_bucket *all_buckets, /* All listeners buckets */
                                *my_bucket;   /* Current child bucket */
    
    #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
    
    /* 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;
    static int my_child_num;
    
    #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_core_module_config(ap_server_conf->module_config);
        char *dir = sconf->gprof_dir;
        const char *use_dir;
    
        if(dir) {
            apr_status_t res;
            char *buf = NULL ;
            int len = strlen(sconf->gprof_dir) - 1;
            if(*(dir + len) == '%') {
                dir[len] = '\0';
                buf = ap_append_pid(pconf, dir, "gprof.");
            }
            use_dir = ap_server_root_relative(pconf, buf ? 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, APLOGNO(00142)
                             "gprof: error creating directory %s", dir);
            }
        }
        else {
            use_dir = ap_runtime_dir_relative(pconf, "");
        }
    
        chdir(use_dir);
    }
    #else
    #define chdir_for_gprof()
    #endif
    
    static void prefork_note_child_killed(int childnum, pid_t pid,
                                          ap_generation_t gen)
    {
        AP_DEBUG_ASSERT(childnum != -1); /* no scoreboard squatting with this MPM */
        ap_run_child_status(ap_server_conf,
                            ap_scoreboard_image->parent[childnum].pid,
                            ap_scoreboard_image->parent[childnum].generation,
                            childnum, MPM_CHILD_EXITED);
        ap_scoreboard_image->parent[childnum].pid = 0;
    }
    
    static void prefork_note_child_started(int slot, pid_t pid)
    {
        ap_generation_t gen = retained->mpm->my_generation;
        ap_scoreboard_image->parent[slot].pid = pid;
        ap_scoreboard_image->parent[slot].generation = gen;
        ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_STARTED);
    }
    
    /* 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)
    {
        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
    
        apr_signal(SIGHUP, SIG_IGN);
        apr_signal(SIGTERM, SIG_IGN);
    
        if (code == 0) {
            ap_run_child_stopping(pchild, 0);
        }
    
        if (pchild) {
            apr_pool_destroy(pchild);
        }
    
        if (one_process) {
            prefork_note_child_killed(/* slot */ 0, 0, 0);
        }
    
        ap_mpm_pod_close(my_bucket->pod);
        chdir_for_gprof();
        exit(code);
    }
    
    static apr_status_t accept_mutex_on(void)
    {
        apr_status_t rv = apr_proc_mutex_lock(my_bucket->mutex);
        if (rv != APR_SUCCESS) {
            const char *msg = "couldn't grab the accept mutex";
    
            if (retained->mpm->my_generation !=
                ap_scoreboard_image->global->running_generation) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00143) "%s", msg);
                clean_child_exit(0);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00144) "%s", msg);
                exit(APEXIT_CHILDFATAL);
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t accept_mutex_off(void)
    {
        apr_status_t rv = apr_proc_mutex_unlock(my_bucket->mutex);
        if (rv != APR_SUCCESS) {
            const char *msg = "couldn't release the accept mutex";
    
            if (retained->mpm->my_generation !=
                ap_scoreboard_image->global->running_generation) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00145) "%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, ap_server_conf, APLOGNO(00146) "%s", msg);
                exit(APEXIT_CHILDFATAL);
            }
        }
        return APR_SUCCESS;
    }
    
    /* 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) (ap_listeners->next ? (stmt) : APR_SUCCESS)
    #else
    #define SAFE_ACCEPT(stmt) (stmt)
    #endif
    
    static int prefork_query(int query_code, int *result, apr_status_t *rv)
    {
        *rv = APR_SUCCESS;
        switch(query_code){
        case AP_MPMQ_MAX_DAEMON_USED:
            *result = ap_daemons_limit;
            break;
        case AP_MPMQ_IS_THREADED:
            *result = AP_MPMQ_NOT_SUPPORTED;
            break;
        case AP_MPMQ_IS_FORKED:
            *result = AP_MPMQ_DYNAMIC;
            break;
        case AP_MPMQ_HARD_LIMIT_DAEMONS:
            *result = server_limit;
            break;
        case AP_MPMQ_HARD_LIMIT_THREADS:
            *result = HARD_THREAD_LIMIT;
            break;
        case AP_MPMQ_MAX_THREADS:
            *result = 1;
            break;
        case AP_MPMQ_MIN_SPARE_DAEMONS:
            *result = ap_daemons_min_free;
            break;
        case AP_MPMQ_MIN_SPARE_THREADS:
            *result = 0;
            break;
        case AP_MPMQ_MAX_SPARE_DAEMONS:
            *result = ap_daemons_max_free;
            break;
        case AP_MPMQ_MAX_SPARE_THREADS:
            *result = 0;
            break;
        case AP_MPMQ_MAX_REQUESTS_DAEMON:
            *result = ap_max_requests_per_child;
            break;
        case AP_MPMQ_MAX_DAEMONS:
            *result = ap_daemons_limit;
            break;
        case AP_MPMQ_MPM_STATE:
            *result = retained->mpm->mpm_state;
            break;
        case AP_MPMQ_GENERATION:
            *result = retained->mpm->my_generation;
            break;
        default:
            *rv = APR_ENOTIMPL;
            break;
        }
        return OK;
    }
    
    static const char *prefork_get_name(void)
    {
        return "prefork";
    }
    
    /*****************************************************************
     * Connection structures and accounting...
     */
    
    static void just_die(int sig)
    {
        clean_child_exit(0);
    }
    
    /* volatile because it's updated from a signal handler */
    static int volatile die_now = 0;
    
    static void stop_listening(int sig)
    {
        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
        ap_close_listeners_ex(my_bucket->listeners);
    
        /* For a graceful stop, we want the child to exit when done */
        die_now = 1;
    }
    
    /*****************************************************************
     * 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;
    
    #if APR_HAS_THREADS
    static void child_sigmask(sigset_t *new_mask, sigset_t *old_mask)
    {
    #if defined(SIGPROCMASK_SETS_THREAD_MASK)
        sigprocmask(SIG_SETMASK, new_mask, old_mask);
    #else
        pthread_sigmask(SIG_SETMASK, new_mask, old_mask);
    #endif
    }
    #endif
    
    static void child_main(int child_num_arg, int child_bucket)
    {
    #if APR_HAS_THREADS
        apr_thread_t *thd = NULL;
        sigset_t sig_mask;
    #endif
        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;
        const char *lockfile;
    
        /* for benefit of any hooks that run as this child initializes */
        retained->mpm->mpm_state = AP_MPMQ_STARTING;
    
        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_tag(pchild, "pchild");
    
    #if AP_HAS_THREAD_LOCAL
        if (one_process) {
            thd = ap_thread_current();
        }
        else if ((status = ap_thread_main_create(&thd, pchild))) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(10378)
                         "Couldn't initialize child main thread");
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    #elif APR_HAS_THREADS
        {
            apr_os_thread_t osthd = apr_os_thread_current();
            apr_os_thread_put(&thd, &osthd, pchild);
        }
    #endif
    #if APR_HAS_THREADS
        ap_assert(thd != NULL);
    #endif
    
        apr_pool_create(&ptrans, pchild);
        apr_pool_tag(ptrans, "transaction");
    
        /* close unused listeners and pods */
        for (i = 0; i < retained->mpm->num_buckets; i++) {
            if (i != child_bucket) {
                ap_close_listeners_ex(all_buckets[i].listeners);
                ap_mpm_pod_close(all_buckets[i].pod);
            }
        }
    
        /* needs to be done before we switch UIDs so we have permissions */
        ap_reopen_scoreboard(pchild, NULL, 0);
        status = SAFE_ACCEPT(apr_proc_mutex_child_init(&my_bucket->mutex,
                                        apr_proc_mutex_lockfile(my_bucket->mutex),
                                        pchild));
        if (status != APR_SUCCESS) {
            lockfile = apr_proc_mutex_lockfile(my_bucket->mutex);
            ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00155)
                         "Couldn't initialize cross-process lock in child "
                         "(%s) (%s)",
                         lockfile ? lockfile : "none",
                         apr_proc_mutex_name(my_bucket->mutex));
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
        if (ap_run_drop_privileges(pchild, ap_server_conf)) {
            clean_child_exit(APEXIT_CHILDFATAL);
        }
    
    #if APR_HAS_THREADS
        /* Save the signal mask and block all the signals from being received by
         * threads potentially created in child_init() hooks (e.g. mod_watchdog).
         */
        child_sigmask(NULL, &sig_mask);
        {
            apr_status_t rv;
            rv = apr_setup_signal_thread();
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(10271)
                             "Couldn't initialize signal thread");
                clean_child_exit(APEXIT_CHILDFATAL);
            }
        }
    #endif /* APR_HAS_THREADS */
    
        ap_run_child_init(pchild, ap_server_conf);
    
    #if APR_HAS_THREADS
        /* Restore the original signal mask for this main thread, the only one
         * that should possibly get interrupted by signals.
         */
        child_sigmask(&sig_mask, NULL);
    #endif
    
        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 */
        status = apr_pollset_create(&pollset, num_listensocks, pchild,
                                    APR_POLLSET_NOCOPY);
        if (status != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00156)
                         "Couldn't create pollset in child; check system or user limits");
            clean_child_exit(APEXIT_CHILDSICK); /* assume temporary resource issue */
        }
    
        for (lr = my_bucket->listeners, i = num_listensocks; i--; lr = lr->next) {
            apr_pollfd_t *pfd = apr_pcalloc(pchild, sizeof *pfd);
    
            pfd->desc_type = APR_POLL_SOCKET;
            pfd->desc.s = lr->sd;
            pfd->reqevents = APR_POLLIN;
            pfd->client_data = lr;
    
            status = apr_pollset_add(pollset, pfd);
            if (status != APR_SUCCESS) {
                /* If the child processed a SIGWINCH before setting up the
                 * pollset, this error path is expected and harmless,
                 * since the listener fd was already closed; so don't
                 * pollute the logs in that case. */
                if (!die_now) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00157)
                                 "Couldn't add listener to pollset; check system or user limits");
                    clean_child_exit(APEXIT_CHILDSICK);
                }
                clean_child_exit(0);
            }
    
            lr->accept_func = ap_unixd_accept;
        }
    
        retained->mpm->mpm_state = AP_MPMQ_RUNNING;
    
        bucket_alloc = apr_bucket_alloc_create(pchild);
    
        /* die_now is set when AP_SIG_GRACEFUL is received in the child;
         * {shutdown,restart}_pending are set when a signal is received while
         * running in single process mode.
         */
        while (!die_now
               && !retained->mpm->shutdown_pending
               && !retained->mpm->restart_pending) {
            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 = my_bucket->listeners;
            }
            else {
                /* multiple listening sockets - need to poll */
                for (;;) {
                    apr_int32_t numdesc;
                    const apr_pollfd_t *pdesc;
    
                    /* check for termination first so we don't sleep for a while in
                     * poll if already signalled
                     */
                    if (die_now         /* in graceful stop/restart */
                            || retained->mpm->shutdown_pending
                            || retained->mpm->restart_pending) {
                        SAFE_ACCEPT(accept_mutex_off());
                        clean_child_exit(0);
                    }
    
                    /* timeout == 10 seconds to avoid a hang at graceful restart/stop
                     * caused by the closing of sockets by the signal handler
                     */
                    status = apr_pollset_poll(pollset, apr_time_from_sec(10),
                                              &numdesc, &pdesc);
                    if (status != APR_SUCCESS) {
                        if (APR_STATUS_IS_TIMEUP(status) ||
                            APR_STATUS_IS_EINTR(status)) {
                            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, APLOGNO(00158) "apr_pollset_poll: (listen)");
                        SAFE_ACCEPT(accept_mutex_off());
                        clean_child_exit(APEXIT_CHILDSICK);
                    }
    
                    /* 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 occurred */
                clean_child_exit(APEXIT_CHILDSICK);
            }
            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) {
    #if APR_HAS_THREADS
                current_conn->current_thread = thd;
    #endif
                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(my_bucket->pod) == APR_SUCCESS) { /* selected as idle? */
                die_now = 1;
            }
            else if (retained->mpm->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;
            }
        }
        apr_pool_clear(ptrans); /* kludge to avoid crash in APR reslist cleanup code */
        clean_child_exit(0);
    }
    
    
    static int make_child(server_rec *s, int slot)
    {
        int bucket = slot % retained->mpm->num_buckets;
        int pid;
    
        if (slot + 1 > retained->max_daemons_limit) {
            retained->max_daemons_limit = slot + 1;
        }
    
        if (one_process) {
            my_bucket = &all_buckets[0];
    
            prefork_note_child_started(slot, getpid());
            child_main(slot, 0);
            /* NOTREACHED */
            ap_assert(0);
            return -1;
        }
    
        (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(ap_unixd_config.user_name)) == -1) {
    #else
        if ((pid = fork()) == -1) {
    #endif
            ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, APLOGNO(00159) "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) {
    #if AP_HAS_THREAD_LOCAL
            ap_thread_current_after_fork();
    #endif
    
            my_bucket = &all_buckets[bucket];
    
    #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_DEBUG, errno,
                             ap_server_conf, APLOGNO(00160) "processor unbind failed");
            }
    #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);
            /* Ignore SIGINT in child. This fixes race-conditions in signals
             * handling when httpd is running on foreground and user hits ctrl+c.
             * In this case, SIGINT is sent to all children followed by SIGTERM
             * from the main process, which interrupts the SIGINT handler and
             * leads to inconsistency.
             */
            apr_signal(SIGINT, SIG_IGN);
            /* The child process just closes listeners on AP_SIG_GRACEFUL.
             * The pod is used for signalling the graceful restart.
             */
            apr_signal(AP_SIG_GRACEFUL, stop_listening);
            child_main(slot, bucket);
        }
    
        prefork_note_child_started(slot, 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;
        }
    }
    
    static void perform_idle_server_maintenance(apr_pool_t *p)
    {
        int i;
        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;
    
        idle_count = 0;
        last_non_dead = -1;
        total_non_dead = 0;
    
        for (i = 0; i < ap_daemons_limit; ++i) {
            int status;
    
            if (i >= retained->max_daemons_limit && free_length == retained->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 < retained->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;
                }
    
                ++total_non_dead;
                last_non_dead = i;
            }
        }
        retained->max_daemons_limit = last_non_dead + 1;
        if (idle_count > ap_daemons_max_free) {
            static int bucket_kill_child_record = -1;
            /* 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
             */
            bucket_kill_child_record = (bucket_kill_child_record + 1) % retained->mpm->num_buckets;
            ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
            retained->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 */
                if (!retained->maxclients_reported) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00161)
                                "server reached MaxRequestWorkers setting, consider"
                                " raising the MaxRequestWorkers setting");
                    retained->maxclients_reported = 1;
                }
                retained->idle_spawn_rate = 1;
            }
            else {
                if (retained->idle_spawn_rate >= 8) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00162)
                        "server seems busy, (you may need "
                        "to increase StartServers, or Min/MaxSpareServers), "
                        "spawning %d children, there are %d idle, and "
                        "%d total children", retained->idle_spawn_rate,
                        idle_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 (retained->hold_off_on_exponential_spawning) {
                    --retained->hold_off_on_exponential_spawning;
                }
                else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) {
                    retained->idle_spawn_rate *= 2;
                }
            }
        }
        else {
            retained->idle_spawn_rate = 1;
        }
    }
    
    /*****************************************************************
     * Executive routines.
     */
    
    static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
    {
        int index;
        int remaining_children_to_start;
        int i;
    
        ap_log_pid(pconf, ap_pid_fname);
    
        if (!retained->mpm->was_graceful) {
            if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
                retained->mpm->mpm_state = AP_MPMQ_STOPPING;
                return !OK;
            }
            /* fix the generation number in the global score; we just got a new,
             * cleared scoreboard
             */
            ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
        }
    
        ap_unixd_mpm_set_signals(pconf, one_process);
    
        if (one_process) {
            AP_MONCONTROL(1);
            make_child(ap_server_conf, 0);
            /* NOTREACHED */
            ap_assert(0);
            return !OK;
        }
    
        /* Don't thrash since num_buckets depends on the
         * system and the number of online CPU cores...
         */
        if (ap_daemons_limit < retained->mpm->num_buckets)
            ap_daemons_limit = retained->mpm->num_buckets;
        if (ap_daemons_to_start < retained->mpm->num_buckets)
            ap_daemons_to_start = retained->mpm->num_buckets;
        if (ap_daemons_min_free < retained->mpm->num_buckets)
            ap_daemons_min_free = retained->mpm->num_buckets;
        if (ap_daemons_max_free < ap_daemons_min_free + retained->mpm->num_buckets)
            ap_daemons_max_free = ap_daemons_min_free + retained->mpm->num_buckets;
    
        /* 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 (!retained->mpm->was_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
             */
            retained->hold_off_on_exponential_spawning = 10;
        }
    
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00163)
                    "%s configured -- resuming normal operations",
                    ap_get_server_description());
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00164)
                    "Server built: %s", ap_get_server_built());
        ap_log_command_line(plog, s);
        ap_log_mpm_common(s);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00165)
                    "Accept mutex: %s (default: %s)",
                    (all_buckets[0].mutex)
                        ? apr_proc_mutex_name(all_buckets[0].mutex)
                        : "none",
                    apr_proc_mutex_defname());
    
        retained->mpm->mpm_state = AP_MPMQ_RUNNING;
    
        while (!retained->mpm->restart_pending && !retained->mpm->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, ap_server_conf);
    
            /* 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);
                child_slot = ap_find_child_by_pid(&pid);
                if (processed_status == APEXIT_CHILDFATAL) {
                    /* fix race condition found in PR 39311
                     * A child created at the same time as a graceful happens 
                     * can find the lock missing and create a fatal error.
                     * It is not fatal for the last generation to be in this state.
                     */
                    if (child_slot < 0
                        || ap_get_scoreboard_process(child_slot)->generation
                           == retained->mpm->my_generation) {
                        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
                        return !OK;
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(00166)
                                     "Ignoring fatal error in child of previous "
                                     "generation (pid %ld).",
                                     (long)pid.pid);
                    }
                }
    
                /* non-fatal death... note that it's gone in the scoreboard. */
                if (child_slot >= 0) {
                    (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD,
                                                               (request_rec *) NULL);
                    prefork_note_child_killed(child_slot, 0, 0);
                    if (processed_status == APEXIT_CHILDSICK) {
                        /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc)
                         * cut the fork rate to the minimum
                         */
                        retained->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 (retained->mpm->was_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, APLOGNO(00167)
                                "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);
        }
    
        retained->mpm->mpm_state = AP_MPMQ_STOPPING;
    
        if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) {
            /* Time to shut down:
             * Kill child processes, tell them to call child_exit, etc...
             */
            if (ap_unixd_killpg(getpgrp(), SIGTERM) < 0) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00168) "killpg SIGTERM");
            }
            ap_reclaim_child_processes(1, /* Start with SIGTERM */
                                       prefork_note_child_killed);
    
            /* cleanup pid file on normal shutdown */
            ap_remove_pid(pconf, ap_pid_fname);
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00169)
                        "caught SIGTERM, shutting down");
    
            return DONE;
        }
    
        if (retained->mpm->shutdown_pending) {
            /* Time to perform a graceful shut down:
             * Reap the inactive children, and ask the active ones
             * to close their listeners, then wait until they are
             * all done to exit.
             */
            int active_children;
            apr_time_t cutoff = 0;
    
            /* Stop listening */
            ap_close_listeners();
    
            /* kill off the idle ones */
            for (i = 0; i < retained->mpm->num_buckets; i++) {
                ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit);
            }
    
            /* Send SIGUSR1 to the active children */
            active_children = 0;
            for (index = 0; index < ap_daemons_limit; ++index) {
                if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {
                    /* Ask each child to close its listeners. */
                    ap_mpm_safe_kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL);
                    active_children++;
                }
            }
    
            /* Allow each child which actually finished to exit */
            ap_relieve_child_processes(prefork_note_child_killed);
    
            /* cleanup pid file */
            ap_remove_pid(pconf, ap_pid_fname);
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00170)
               "caught " AP_SIG_GRACEFUL_STOP_STRING ", shutting down gracefully");
    
            if (ap_graceful_shutdown_timeout) {
                cutoff = apr_time_now() +
                         apr_time_from_sec(ap_graceful_shutdown_timeout);
            }
    
            /* Don't really exit until each child has finished */
            retained->mpm->shutdown_pending = 0;
            do {
                /* Pause for a second */
                sleep(1);
    
                /* Relieve any children which have now exited */
                ap_relieve_child_processes(prefork_note_child_killed);
    
                active_children = 0;
                for (index = 0; index < ap_daemons_limit; ++index) {
                    if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
                        active_children = 1;
                        /* Having just one child is enough to stay around */
                        break;
                    }
                }
            } while (!retained->mpm->shutdown_pending && active_children &&
                     (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
    
            /* We might be here because we received SIGTERM, either
             * way, try and make sure that all of our processes are
             * really dead.
             */
            ap_unixd_killpg(getpgrp(), SIGTERM);
    
            return DONE;
        }
    
        /* we've been told to restart */
        if (one_process) {
            /* not worth thinking about */
            return DONE;
        }
    
        /* 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.
         */
        ++retained->mpm->my_generation;
        ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
    
        if (!retained->mpm->is_ungraceful) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00171)
                        "Graceful restart requested, doing restart");
    
            /* kill off the idle ones */
            for (i = 0; i < retained->mpm->num_buckets; i++) {
                ap_mpm_pod_killpg(all_buckets[i].pod, retained->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;
                    /* Ask each child to close its listeners.
                     *
                     * NOTE: we use the scoreboard, because if we send SIGUSR1
                     * to every process in the group, this may include CGI's,
                     * piped loggers, etc. They almost certainly won't handle
                     * it gracefully.
                     */
                    ap_mpm_safe_kill(ap_scoreboard_image->parent[index].pid, AP_SIG_GRACEFUL);
                }
            }
        }
        else {
            /* Kill 'em off */
            if (ap_unixd_killpg(getpgrp(), SIGHUP) < 0) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00172) "killpg SIGHUP");
            }
            ap_reclaim_child_processes(0, /* Not when just starting up */
                                       prefork_note_child_killed);
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00173)
                        "SIGHUP received.  Attempting to restart");
        }
    
        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 prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
    {
        int startup = 0;
        int level_flags = 0;
        ap_listen_rec **listen_buckets;
        apr_status_t rv;
        char id[16];
        int i;
    
        pconf = p;
    
        /* the reverse of pre_config, we want this only the first time around */
        if (retained->mpm->module_loads == 1) {
            startup = 1;
            level_flags |= APLOG_STARTUP;
        }
    
        if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
            ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
                         (startup ? NULL : s),
                         "no listening sockets available, shutting down");
            return !OK;
        }
    
        if (one_process) {
            retained->mpm->num_buckets = 1;
        }
        else if (!retained->mpm->was_graceful) {
            /* Preserve the number of buckets on graceful restarts. */
            retained->mpm->num_buckets = 0;
        }
        if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
                                         &listen_buckets, &retained->mpm->num_buckets))) {
            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                         (startup ? NULL : s),
                         "could not duplicate listeners");
            return !OK;
        }
        all_buckets = apr_pcalloc(pconf, retained->mpm->num_buckets *
                                         sizeof(prefork_child_bucket));
        for (i = 0; i < retained->mpm->num_buckets; i++) {
            if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) {
                ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                             (startup ? NULL : s),
                             "could not open pipe-of-death");
                return !OK;
            }
            /* Initialize cross-process accept lock (safe accept needed only) */
            if ((rv = SAFE_ACCEPT((apr_snprintf(id, sizeof id, "%i", i),
                                   ap_proc_mutex_create(&all_buckets[i].mutex,
                                                        NULL, AP_ACCEPT_MUTEX_TYPE,
                                                        id, s, pconf, 0))))) {
                ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
                             (startup ? NULL : s),
                             "could not create accept mutex");
                return !OK;
            }
            all_buckets[i].listeners = listen_buckets[i];
        }
    
        return OK;
    }
    
    static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
    {
        int no_detach, debug, foreground;
        apr_status_t rv;
        const char *userdata_key = "mpm_prefork_module";
    
        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");
        }
    
        ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
    
        retained = ap_retained_data_get(userdata_key);
        if (!retained) {
            retained = ap_retained_data_create(userdata_key, sizeof(*retained));
            retained->mpm = ap_unixd_mpm_get_retained_data();
            retained->idle_spawn_rate = 1;
        }
        retained->mpm->mpm_state = AP_MPMQ_STARTING;
        if (retained->mpm->baton != retained) {
            retained->mpm->was_graceful = 0;
            retained->mpm->baton = retained;
        }
        ++retained->mpm->module_loads;
    
        /* sigh, want this only the second time around */
        if (retained->mpm->module_loads == 2) {
            if (!one_process && !foreground) {
                /* before we detach, setup crash handlers to log to errorlog */
                ap_fatal_signal_setup(ap_server_conf, p /* == pconf */);
                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, APLOGNO(00174)
                                 "apr_proc_detach failed");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
        }
    
        parent_pid = ap_my_pid = getpid();
    
        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;
        server_limit = DEFAULT_SERVER_LIMIT;
        ap_daemons_limit = server_limit;
        ap_extended_status = 0;
    
        return OK;
    }
    
    static int prefork_check_config(apr_pool_t *p, apr_pool_t *plog,
                                    apr_pool_t *ptemp, server_rec *s)
    {
        int startup = 0;
    
        /* the reverse of pre_config, we want this only the first time around */
        if (retained->mpm->module_loads == 1) {
            startup = 1;
        }
    
        if (server_limit > MAX_SERVER_LIMIT) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00175)
                             "WARNING: ServerLimit of %d exceeds compile-time "
                             "limit of %d servers, decreasing to %d.",
                             server_limit, MAX_SERVER_LIMIT, MAX_SERVER_LIMIT);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00176)
                             "ServerLimit of %d exceeds compile-time limit "
                             "of %d, decreasing to match",
                             server_limit, MAX_SERVER_LIMIT);
            }
            server_limit = MAX_SERVER_LIMIT;
        }
        else if (server_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00177)
                             "WARNING: ServerLimit of %d not allowed, "
                             "increasing to 1.", server_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00178)
                             "ServerLimit of %d not allowed, increasing to 1",
                             server_limit);
            }
            server_limit = 1;
        }
    
        /* you cannot change ServerLimit across a restart; ignore
         * any such attempts
         */
        if (!retained->first_server_limit) {
            retained->first_server_limit = server_limit;
        }
        else if (server_limit != retained->first_server_limit) {
            /* don't need a startup console version here */
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00179)
                         "changing ServerLimit to %d from original value of %d "
                         "not allowed during restart",
                         server_limit, retained->first_server_limit);
            server_limit = retained->first_server_limit;
        }
    
        if (ap_daemons_limit > server_limit) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00180)
                             "WARNING: MaxRequestWorkers of %d exceeds ServerLimit "
                             "value of %d servers, decreasing MaxRequestWorkers to %d. "
                             "To increase, please see the ServerLimit directive.",
                             ap_daemons_limit, server_limit, server_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00181)
                             "MaxRequestWorkers of %d exceeds ServerLimit value "
                             "of %d, decreasing to match",
                             ap_daemons_limit, server_limit);
            }
            ap_daemons_limit = server_limit;
        }
        else if (ap_daemons_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00182)
                             "WARNING: MaxRequestWorkers of %d not allowed, "
                             "increasing to 1.", ap_daemons_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00183)
                             "MaxRequestWorkers of %d not allowed, increasing to 1",
                             ap_daemons_limit);
            }
            ap_daemons_limit = 1;
        }
    
        /* ap_daemons_to_start > ap_daemons_limit checked in prefork_run() */
        if (ap_daemons_to_start < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00184)
                             "WARNING: StartServers of %d not allowed, "
                             "increasing to 1.", ap_daemons_to_start);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00185)
                             "StartServers of %d not allowed, increasing to 1",
                             ap_daemons_to_start);
            }
            ap_daemons_to_start = 1;
        }
    
        if (ap_daemons_min_free < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00186)
                             "WARNING: MinSpareServers of %d not allowed, "
                             "increasing to 1 to avoid almost certain server failure. "
                             "Please read the documentation.", ap_daemons_min_free);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00187)
                             "MinSpareServers of %d not allowed, increasing to 1",
                             ap_daemons_min_free);
            }
            ap_daemons_min_free = 1;
        }
    
        /* ap_daemons_max_free < ap_daemons_min_free + 1 checked in prefork_run() */
    
        return OK;
    }
    
    static void prefork_hooks(apr_pool_t *p)
    {
        /* Our open_logs hook function 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_open_logs(prefork_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
        /* 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);
        ap_hook_check_config(prefork_check_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm(prefork_run, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_query(prefork_query, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_get_name(prefork_get_name, 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_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);
        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;
        }
        if (!strcasecmp(cmd->cmd->name, "MaxClients")) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(00188)
                         "MaxClients is deprecated, use MaxRequestWorkers "
                         "instead.");
        }
        ap_daemons_limit = atoi(arg);
        return NULL;
    }
    
    static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
    
        server_limit = atoi(arg);
        return NULL;
    }
    
    static const command_rec prefork_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("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,
                  "Deprecated name of MaxRequestWorkers"),
    AP_INIT_TAKE1("MaxRequestWorkers", 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 MaxRequestWorkers for this run of Apache"),
    AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
    { NULL }
    };
    
    AP_DECLARE_MODULE(mpm_prefork) = {
        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 */
        prefork_cmds,               /* command apr_table_t */
        prefork_hooks,              /* register hooks */
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/prefork/config.m4�����������������������������������������������������������0000664�0001751�0001751�00000000345�11172132604�020077� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_MSG_CHECKING(if prefork MPM supports this platform)
    if test $forking_mpms_supported != yes; then
        AC_MSG_RESULT(no - This is not a forking platform)
    else
        AC_MSG_RESULT(yes)
        APACHE_MPM_SUPPORTED(prefork, yes, no)
    fi
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/prefork/Makefile.in���������������������������������������������������������0000664�0001751�0001751�00000000047�11274040000�020423� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/build/special.mk
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016072� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/nt_eventlog.c���������������������������������������������������������0000664�0001751�0001751�00000012731�14037102164�020552� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mpm_winnt.h"
    #include "apr_strings.h"
    #include "apr_lib.h"
    #include "apr_portable.h"
    #include "ap_regkey.h"
    
    static const 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);
        apr_pool_tag(p, "service_stderr_thread");
    
        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(&regkey, 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 %lu 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(const char *argv0, apr_pool_t *p)
    {
        SECURITY_ATTRIBUTES sa;
        HANDLE hPipeRead = NULL;
        HANDLE hPipeWrite = NULL;
        DWORD  threadid;
        apr_file_t *eventlog_file;
        apr_file_t *stderr_file;
    
        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, 65536, service_stderr_thread,
                                     (LPVOID)hPipeRead, stack_res_flag, &threadid);
        ap_assert(stderr_ready && stderr_thread);
    
        WaitForSingleObject(stderr_ready, INFINITE);
    
        if ((apr_file_open_stderr(&stderr_file, p)
                 == APR_SUCCESS)
         && (apr_os_file_put(&eventlog_file, &hPipeWrite, APR_WRITE, p)
                 == APR_SUCCESS))
            apr_file_dup2(stderr_file, eventlog_file, p);
    
        /* 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);
    }
    ���������������������������������������httpd-2.4.64/server/mpm/winnt/Makefile.in�����������������������������������������������������������0000664�0001751�0001751�00000000047�11274040000�020112� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/build/special.mk
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/mpm_winnt.c�����������������������������������������������������������0000664�0001751�0001751�00000202716�14037675642�020262� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "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 "apr_general.h"
    #include "ap_config.h"
    #include "ap_listen.h"
    #include "mpm_default.h"
    #include "mpm_winnt.h"
    #include "mpm_common.h"
    #include <malloc.h>
    #include "apr_atomic.h"
    #include "scoreboard.h"
    
    #ifdef __WATCOMC__
    #define _environ environ
    #endif
    
    #ifndef STACK_SIZE_PARAM_IS_A_RESERVATION /* missing on MinGW */
    #define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
    #endif
    
    /* Because ap_setup_listeners() is skipped in the child, any merging
     * of [::]:80 and 0.0.0.0:80 for AP_ENABLE_V4_MAPPED in the parent
     * won't have taken place in the child, so the child will expect to
     * read two sockets for "Listen 80" but the parent will send only
     * one.
     */
    #ifdef AP_ENABLE_V4_MAPPED
    #error The WinNT MPM does not currently support AP_ENABLE_V4_MAPPED
    #endif
    
    /* 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;
    
    /* my_generation is returned to the scoreboard code */
    static volatile ap_generation_t my_generation=0;
    
    /* 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 int one_process = 0;
    static char const* signal_arg = NULL;
    
    OSVERSIONINFO osver; /* VER_PLATFORM_WIN32_NT */
    
    /* set by child_main to STACK_SIZE_PARAM_IS_A_RESERVATION for NT >= 5.1 (XP/2003) */
    DWORD stack_res_flag;
    
    static DWORD parent_pid;
    DWORD my_pid;
    
    /* used by parent to signal the child to start and exit */
    apr_proc_mutex_t *start_mutex;
    HANDLE exit_event;
    
    int ap_threads_per_child = 0;
    static int thread_limit = 0;
    static int first_thread_limit = 0;
    int winnt_mpm_state = AP_MPMQ_STARTING;
    
    /* shared by service.c as global, although
     * perhaps it should be private.
     */
    apr_pool_t *pconf;
    
    /* Only one of these, the pipe from our parent, meant only for
     * one child worker's consumption (not to be inherited!)
     * XXX: decorate this name for the trunk branch, was left simplified
     *      only to make the 2.2 patch trivial to read.
     */
    static HANDLE pipe;
    
    /*
     * Command processors
     */
    
    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);
        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;
        }
    
        thread_limit = atoi(arg);
        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"),
    { NULL }
    };
    
    static void winnt_note_child_started(int slot, pid_t pid)
    {
        ap_scoreboard_image->parent[slot].pid = pid;
        ap_scoreboard_image->parent[slot].generation = my_generation;
        ap_run_child_status(ap_server_conf,
                            ap_scoreboard_image->parent[slot].pid,
                            my_generation, slot, MPM_CHILD_STARTED);
    }
    
    static void winnt_note_child_killed(int slot)
    {
        ap_run_child_status(ap_server_conf,
                            ap_scoreboard_image->parent[slot].pid,
                            ap_scoreboard_image->parent[slot].generation,
                            slot, MPM_CHILD_EXITED);
        ap_scoreboard_image->parent[slot].pid = 0;
    }
    
    /*
     * 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 */
    static char signal_name_prefix[MAX_SIGNAL_NAME];
    static char signal_restart_name[MAX_SIGNAL_NAME];
    static char signal_shutdown_name[MAX_SIGNAL_NAME];
    static 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);
    }
    
    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:
               {
                   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;
               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, APLOGNO(00382)
                         "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, APLOGNO(00383)
                         "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]
     */
    static 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 hScore;
        HANDLE ready_event;
        HANDLE os_start;
        DWORD BytesRead;
        void *sb_shared;
        apr_status_t rv;
    
        /* *** We now do this way back in winnt_rewrite_args
         * 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, APLOGNO(00384)
                         "Child: Unable to retrieve the ready event from the parent");
            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, APLOGNO(00385)
                         "Child: Unable to retrieve the exit event from the parent");
            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, APLOGNO(00386)
                         "Child: Unable to retrieve the start_mutex from the parent");
            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, APLOGNO(00387)
                         "Child: Unable to access the start_mutex from the parent");
            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, APLOGNO(00388)
                         "Child: Unable to retrieve the scoreboard from the parent");
            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, APLOGNO(00389)
                         "Child: Unable to access the scoreboard from the parent");
            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, ap_server_conf, APLOGNO(00390)
                         "Child: Unable to reopen the scoreboard from the parent");
            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, APLOGNO(00391)
                     "Child: Retrieved our scoreboard from the parent.");
    }
    
    
    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 ((rv = apr_file_write_full(child_in, &my_generation,
                                      sizeof(my_generation), NULL))
                != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(02964)
                         "Parent: Unable to send its generation to the child");
            return -1;
        }
        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, APLOGNO(00392)
                         "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, APLOGNO(00393)
                         "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, APLOGNO(00394)
                         "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, APLOGNO(00395)
                         "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, APLOGNO(00396)
                         "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, APLOGNO(00397)
                         "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, APLOGNO(00398)
                         "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, APLOGNO(00399)
                         "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, APLOGNO(00400)
                         "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, APLOGNO(00401)
                         "Parent: Unable to send the scoreboard handle to the child");
            return -1;
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00402)
                     "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 available in the child.
     */
    static void get_listeners_from_parent(server_rec *s)
    {
        WSAPROTOCOL_INFO WSAProtocolInfo;
        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.
         *
         * *** We now do this way back in winnt_rewrite_args
         * pipe = GetStdHandle(STD_INPUT_HANDLE);
         */
        for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00403)
                         "Child: Waiting for data for listening socket %pI",
                         lr->bind_addr);
            if (!ReadFile(pipe, &WSAProtocolInfo, sizeof(WSAPROTOCOL_INFO),
                          &BytesRead, (LPOVERLAPPED) NULL)) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, APLOGNO(00404)
                             "Child: 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, APLOGNO(00405)
                             "Child: WSASocket failed to open the inherited socket");
                exit(APEXIT_CHILDINIT);
            }
    
            if (!SetHandleInformation((HANDLE)nsd, HANDLE_FLAG_INHERIT, 0)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), ap_server_conf, APLOGNO(00406)
                             "Child: SetHandleInformation failed");
            }
            apr_os_sock_put(&lr->sd, &nsd, s->process->pool);
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00407)
                     "Child: retrieved %d listeners from parent", 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_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00408)
                         "Parent: Duplicating socket %d (%pI) and sending it to child process %lu",
                         nsd, lr->bind_addr, dwProcessId);
            if (WSADuplicateSocket(nsd, dwProcessId,
                                   lpWSAProtocolInfo) == SOCKET_ERROR) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf, APLOGNO(00409)
                             "Parent: WSADuplicateSocket failed for socket %d. Check the FAQ.", nsd);
                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, APLOGNO(00410)
                             "Parent: Unable to write duplicated socket %d to the child.", nsd);
                return -1;
            }
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00411)
                     "Parent: Sent %d listeners to child %lu", 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 pidbuf[28];
    
        apr_status_t rv;
        apr_pool_t *ptemp;
        apr_procattr_t *attr;
        apr_proc_t new_child;
        HANDLE hExitEvent;
        HANDLE waitlist[2];  /* see waitlist_e */
        char *cmd;
        char *cwd;
        char **env;
        int envc;
    
        apr_pool_create_ex(&ptemp, p, NULL, NULL);
        apr_pool_tag(ptemp, "create_process");
    
        /* Build the command line. Should look something like this:
         * C:/apache/bin/httpd.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, APLOGNO(00412)
                         "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, APLOGNO(00413)
                             "Parent: Failed to get full path of %s",
                             ap_server_conf->process->argv[0]);
                apr_pool_destroy(ptemp);
                return -1;
            }
    
            args = ap_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] = ap_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, APLOGNO(00414)
                            "Parent: Unable to create child stdin pipe.");
            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, APLOGNO(00415)
                         "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, APLOGNO(00416)
                         "Parent: Could not create exit event for child process");
            apr_pool_destroy(ptemp);
            CloseHandle(waitlist[waitlist_ready]);
            return -1;
        }
    
        /* Build the env array */
        for (envc = 0; _environ[envc]; ++envc) {
            ;
        }
        env = apr_palloc(ptemp, (envc + 2) * sizeof (char*));
        memcpy(env, _environ, envc * sizeof (char*));
        apr_snprintf(pidbuf, sizeof(pidbuf), "AP_PARENT_PID=%lu", parent_pid);
        env[envc] = pidbuf;
        env[envc + 1] = NULL;
    
        rv = apr_proc_create(&new_child, cmd, (const char * const *)args,
                             (const char * const *)env, attr, ptemp);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, APLOGNO(00417)
                         "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, APLOGNO(00418)
                     "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;
        }
    
        apr_file_close(new_child.in);
    
        *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 MaxConnectionsPerChild.
     *
     * 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
     * condition.
     *
     * 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 child_created;
        int restart_pending;
        int shutdown_pending;
        HANDLE child_exit_event;
        HANDLE event_handles[NUM_WAIT_HANDLES];
        DWORD child_pid;
    
        child_created = 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, APLOGNO(00419)
                         "master_main: create child process failed. Exiting.");
            shutdown_pending = 1;
            goto die_now;
        }
    
        child_created = 1;
    
        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;
        winnt_note_child_started(/* slot */ 0, 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, APLOGNO(00420)
                         "master_main: WaitForMultipleObjects 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, APLOGNO(00421)
                         "master_main: WaitForMultipleObjects 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, APLOGNO(00422)
                         "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, APLOGNO(00423)
                             "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, APLOGNO(00424)
                         "Parent: Received restart signal -- Restarting the server.");
            if (ResetEvent(restart_event) == 0) {
                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, APLOGNO(00425)
                             "Parent: ResetEvent(restart_event) failed.");
            }
            if (SetEvent(child_exit_event) == 0) {
                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, APLOGNO(00426)
                             "Parent: SetEvent for child process event %pp 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, APLOGNO(00427)
                             "Parent: child process %lu exited with status %lu -- Aborting.",
                             child_pid, exitcode);
                shutdown_pending = 1;
            }
            else {
                int i;
                restart_pending = 1;
                ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00428)
                             "Parent: child process %lu exited with status %lu -- Restarting.",
                             child_pid, 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;
        }
    
        winnt_note_child_killed(/* slot */ 0);
    
        if (restart_pending) {
            ++my_generation;
            ap_scoreboard_image->global->running_generation = my_generation;
        }
    die_now:
        if (shutdown_pending)
        {
            int timeout = 30000;  /* Timeout is milliseconds */
            winnt_mpm_state = AP_MPMQ_STOPPING;
    
            if (!child_created) {
                return 0;  /* Tell the caller we do not want to restart */
            }
    
            /* 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, APLOGNO(00429)
                                 "Parent: SetEvent for child process event %pp 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, APLOGNO(00430)
                                 "Parent: Child process %lu exited successfully.", child_pid);
                    CloseHandle(event_handles[CHILD_HANDLE]);
                    event_handles[CHILD_HANDLE] = NULL;
                }
                else {
                    ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00431)
                                 "Parent: Forcing termination of child process %lu",
                                 child_pid);
                    TerminateProcess(event_handles[CHILD_HANDLE], 1);
                    CloseHandle(event_handles[CHILD_HANDLE]);
                    event_handles[CHILD_HANDLE] = NULL;
                }
            }
            CloseHandle(child_exit_event);
            return 0;  /* Tell the caller we do not want to restart */
        }
        winnt_mpm_state = AP_MPMQ_STARTING;
        CloseHandle(child_exit_event);
        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.
     */
    
    static int winnt_query(int query_code, int *result, apr_status_t *rv)
    {
        *rv = APR_SUCCESS;
        switch (query_code) {
            case AP_MPMQ_MAX_DAEMON_USED:
                *result = MAXIMUM_WAIT_OBJECTS;
                break;
            case AP_MPMQ_IS_THREADED:
                *result = AP_MPMQ_STATIC;
                break;
            case AP_MPMQ_IS_FORKED:
                *result = AP_MPMQ_NOT_SUPPORTED;
                break;
            case AP_MPMQ_HARD_LIMIT_DAEMONS:
                *result = HARD_SERVER_LIMIT;
                break;
            case AP_MPMQ_HARD_LIMIT_THREADS:
                *result = thread_limit;
                break;
            case AP_MPMQ_MAX_THREADS:
                *result = ap_threads_per_child;
                break;
            case AP_MPMQ_MIN_SPARE_DAEMONS:
                *result = 0;
                break;
            case AP_MPMQ_MIN_SPARE_THREADS:
                *result = 0;
                break;
            case AP_MPMQ_MAX_SPARE_DAEMONS:
                *result = 0;
                break;
            case AP_MPMQ_MAX_SPARE_THREADS:
                *result = 0;
                break;
            case AP_MPMQ_MAX_REQUESTS_DAEMON:
                *result = ap_max_requests_per_child;
                break;
            case AP_MPMQ_MAX_DAEMONS:
                *result = 1;
                break;
            case AP_MPMQ_MPM_STATE:
                *result = winnt_mpm_state;
                break;
            case AP_MPMQ_GENERATION:
                *result = my_generation;
                break;
            default:
                *rv = APR_ENOTIMPL;
                break;
        }
        return OK;
    }
    
    static const char *winnt_get_name(void)
    {
        return "WinNT";
    }
    
    #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 const char *service_name = NULL;
    
    static void winnt_rewrite_args(process_rec *process)
    {
        /* Handle the following SCM aspects in this phase:
         *
         *   -k runservice [transition in service context only]
         *   -k install
         *   -k config
         *   -k uninstall
         *   -k stop
         *   -k shutdown (same as -k stop). Maintained for backward compatibility.
         *
         * 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 *opt_arg;
        int fixed_args;
        char *pid;
        apr_getopt_t *opt;
        int running_as_service = 1;
        int errout = 0;
        apr_file_t *nullfile;
    
        pconf = process->pconf;
    
        osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        GetVersionEx(&osver);
    
        /* We wish this was *always* a reservation, but sadly it wasn't so and
         * we couldn't break a hard limit prior to NT Kernel 5.1
         */
        if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT
            && ((osver.dwMajorVersion > 5)
             || ((osver.dwMajorVersion == 5) && (osver.dwMinorVersion > 0)))) {
            stack_res_flag = STACK_SIZE_PARAM_IS_A_RESERVATION;
        }
    
        /* AP_PARENT_PID is only valid in the child */
        pid = getenv("AP_PARENT_PID");
        if (pid)
        {
            HANDLE filehand;
            HANDLE hproc = GetCurrentProcess();
            DWORD BytesRead;
    
            /* This is the child */
            my_pid = GetCurrentProcessId();
            parent_pid = (DWORD) atol(pid);
    
            /* Prevent holding open the (nonexistent) console */
            ap_real_exit_code = 0;
    
            /* The parent gave us stdin, we need to remember this
             * handle, and no longer inherit it at our children
             * (we can't slurp it up now, we just aren't ready yet).
             * The original handle is closed below, at apr_file_dup2()
             */
            pipe = GetStdHandle(STD_INPUT_HANDLE);
            if (DuplicateHandle(hproc, pipe,
                                hproc, &filehand, 0, FALSE,
                                DUPLICATE_SAME_ACCESS)) {
                pipe = filehand;
            }
    
            /* The parent gave us stdout of the NUL device,
             * and expects us to suck up stdin of all of our
             * shared handles and data from the parent.
             * Don't infect child processes with our stdin
             * handle, use another handle to NUL!
             */
            {
                apr_file_t *infile, *outfile;
                if ((apr_file_open_stdout(&outfile, process->pool) == APR_SUCCESS)
                 && (apr_file_open_stdin(&infile, process->pool) == APR_SUCCESS))
                    apr_file_dup2(infile, outfile, process->pool);
            }
    
            /* This child needs the existing stderr opened for logging,
             * already
             */
    
            /* Read this child's generation number as soon as now,
             * so that further hooks can query it.
             */
            if (!ReadFile(pipe, &my_generation, sizeof(my_generation),
                          &BytesRead, (LPOVERLAPPED) NULL)
                    || (BytesRead != sizeof(my_generation))) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), NULL, APLOGNO(02965)
                             "Child: Unable to retrieve my generation from the parent");
                exit(APEXIT_CHILDINIT);
            }
    
            /* 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, APLOGNO(00432)
                         "Failed to get the full path of %s", process->argv[0]);
            exit(APEXIT_INIT);
        }
        /* WARNING: There is an implicit 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, process->argv);
        opt->errfn = NULL;
        while ((rv = apr_getopt(opt, "wn:k:" AP_SERVER_BASEARGS,
                                optbuf + 1, &opt_arg)) == 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,
                                                   opt_arg);
                break;
    
            case 'k':
                signal_arg = opt_arg;
                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 (opt_arg) {
                    *(const char **)apr_array_push(mpm_new_argv) = opt_arg;
                }
                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 (!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;
            }
    
            /* Open a null handle to soak stdout in this process.
             * Windows service processes are missing any file handle
             * usable for stdin/out/err.  This was the cause of later
             * trouble with invocations of apr_file_open_stdout()
             */
            if ((rv = apr_file_open(&nullfile, "NUL",
                                    APR_READ | APR_WRITE, APR_OS_DEFAULT,
                                    process->pool)) == APR_SUCCESS) {
                apr_file_t *nullstdout;
                if (apr_file_open_stdout(&nullstdout, process->pool)
                        == APR_SUCCESS)
                    apr_file_dup2(nullstdout, nullfile, process->pool);
                apr_file_close(nullfile);
            }
        }
    
        /* 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, APLOGNO(00433)
                     "%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, APLOGNO(00434)
                                 "Using ConfigArgs of the installed service "
                                 "\"%s\".", service_name);
                }
                else  {
                    ap_log_error(APLOG_MARK,APLOG_WARNING, rv, NULL, APLOGNO(00435)
                                 "No installed ConfigArgs for the service "
                                 "\"%s\", using Apache defaults.", service_name);
                }
            }
            else
            {
                ap_log_error(APLOG_MARK,APLOG_ERR, service_set, NULL, APLOGNO(00436)
                     "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, APLOGNO(00437)
                 "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;
    
        /* XXX: presume proper privileges; one nice thing would be
         * a loud emit if running as "LocalSystem"/"SYSTEM" to indicate
         * they should change to a user with write access to logs/ alone.
         */
        ap_sys_privileges_handlers(1);
    
        if (!strcasecmp(signal_arg, "runservice")
                && (service_to_start_success != APR_SUCCESS)) {
            ap_log_error(APLOG_MARK,APLOG_CRIT, service_to_start_success, NULL, APLOGNO(00438)
                         "%s: Unable to start the service manager.",
                         service_name);
            exit(APEXIT_INIT);
        }
        else if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_NORMAL
                 && !one_process && !my_generation) {
            /* Open a null handle to soak stdout in this process.
             * We need to emulate apr_proc_detach, unix performs this
             * same check in the pre_config hook (although it is
             * arguably premature).  Services already fixed this.
             */
            apr_file_t *nullfile;
            apr_status_t rv;
            apr_pool_t *pproc = apr_pool_parent_get(pconf);
    
            if ((rv = apr_file_open(&nullfile, "NUL",
                                    APR_READ | APR_WRITE, APR_OS_DEFAULT,
                                    pproc)) == APR_SUCCESS) {
                apr_file_t *nullstdout;
                if (apr_file_open_stdout(&nullstdout, pproc)
                        == APR_SUCCESS)
                    apr_file_dup2(nullstdout, nullfile, pproc);
                apr_file_close(nullfile);
            }
        }
    
        ap_listen_pre_config();
        thread_limit = DEFAULT_THREAD_LIMIT;
        ap_threads_per_child = DEFAULT_THREADS_PER_CHILD;
    
        return OK;
    }
    
    static int winnt_check_config(apr_pool_t *pconf, apr_pool_t *plog,
                                  apr_pool_t *ptemp, server_rec* s)
    {
        int is_parent;
        int startup = 0;
    
        /* We want this only in the parent and only the first time around */
        is_parent = (parent_pid == my_pid);
        if (is_parent &&
            ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
            startup = 1;
        }
    
        if (thread_limit > MAX_THREAD_LIMIT) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00439)
                             "WARNING: ThreadLimit of %d exceeds compile-time "
                             "limit of %d threads, decreasing to %d.",
                             thread_limit, MAX_THREAD_LIMIT, MAX_THREAD_LIMIT);
            } else if (is_parent) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00440)
                             "ThreadLimit of %d exceeds compile-time limit "
                             "of %d, decreasing to match",
                             thread_limit, MAX_THREAD_LIMIT);
            }
            thread_limit = MAX_THREAD_LIMIT;
        }
        else if (thread_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00441)
                             "WARNING: ThreadLimit of %d not allowed, "
                             "increasing to 1.", thread_limit);
            } else if (is_parent) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00442)
                             "ThreadLimit of %d not allowed, increasing to 1",
                             thread_limit);
            }
            thread_limit = 1;
        }
    
        /* You cannot change ThreadLimit across a restart; ignore
         * any such attempts.
         */
        if (!first_thread_limit) {
            first_thread_limit = thread_limit;
        }
        else if (thread_limit != first_thread_limit) {
            /* Don't need a startup console version here */
            if (is_parent) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00443)
                             "changing ThreadLimit to %d from original value "
                             "of %d not allowed during restart",
                             thread_limit, first_thread_limit);
            }
            thread_limit = first_thread_limit;
        }
    
        if (ap_threads_per_child > thread_limit) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00444)
                             "WARNING: ThreadsPerChild of %d exceeds ThreadLimit "
                             "of %d threads, decreasing to %d. To increase, please "
                             "see the ThreadLimit directive.",
                             ap_threads_per_child, thread_limit, thread_limit);
            } else if (is_parent) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00445)
                             "ThreadsPerChild of %d exceeds ThreadLimit "
                             "of %d, decreasing to match",
                             ap_threads_per_child, thread_limit);
            }
            ap_threads_per_child = thread_limit;
        }
        else if (ap_threads_per_child < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00446)
                             "WARNING: ThreadsPerChild of %d not allowed, "
                             "increasing to 1.", ap_threads_per_child);
            } else if (is_parent) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00447)
                             "ThreadsPerChild of %d not allowed, increasing to 1",
                             ap_threads_per_child);
            }
            ap_threads_per_child = 1;
        }
    
        return OK;
    }
    
    static int winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec* s)
    {
        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 (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG
                && ap_state_query(AP_SQ_CONFIG_GEN) == 1)
            {
                /* This code should be run once in the parent and not run
                 * across a restart
                 */
                setup_signal_names(apr_psprintf(pconf, "ap%lu", 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(NULL, FALSE, FALSE, signal_shutdown_name);
                if (!shutdown_event) {
                    ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, APLOGNO(00448)
                                 "Parent: Cannot create shutdown event %s", signal_shutdown_name);
                    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(NULL, 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, APLOGNO(00449)
                                 "Parent: Cannot create restart event %s", signal_restart_name);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
    
                /* Create the start mutex, as an unnamed object for security.
                 * The 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, APLOGNO(00450)
                                 "%s: Unable to create the start_mutex.",
                                 service_name);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
            }
            /* Always reset our console handler to be the first, even on a restart
            *  because some modules (e.g. mod_perl) might have set a console
            *  handler to terminate the process.
            */
            if (strcasecmp(signal_arg, "runservice"))
                mpm_start_console_handler();
        }
        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.
         */
        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, APLOGNO(00451) "no listening sockets available, shutting down");
            return !OK;
        }
    
        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%lu", 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);
    
            /* Done reading from the parent, close that channel */
            CloseHandle(pipe);
        }
        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, APLOGNO(00452)
                             "%s child: Unable to init the start_mutex.",
                             service_name);
                exit(APEXIT_CHILDINIT);
            }
    
            /* Borrow the shutdown_even as our _child_ loop exit event */
            exit_event = shutdown_event;
        }
    }
    
    
    static int winnt_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
    {
        static int restart = 0;            /* Default is "not a restart" */
    
        /* ### 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 !OK;
            }
        }
    
        if ((parent_pid != my_pid) || one_process)
        {
            /* The child process or in one_process (debug) mode
             */
            ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00453)
                         "Child process is running");
    
            child_main(pconf, parent_pid);
    
            ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00454)
                         "Child process is exiting");
            return DONE;
        }
        else
        {
            /* A real-honest to goodness parent */
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00455)
                         "%s configured -- resuming normal operations",
                         ap_get_server_description());
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00456)
                         "Server built: %s", ap_get_server_built());
            ap_log_command_line(plog, s);
            ap_log_mpm_common(s);
    
            restart = master_main(ap_server_conf, shutdown_event, restart_event);
    
            if (!restart)
            {
                /* Shutting down. Clean up... */
                ap_remove_pid(pconf, ap_pid_fname);
                apr_proc_mutex_destroy(start_mutex);
    
                CloseHandle(restart_event);
                CloseHandle(shutdown_event);
    
                return DONE;
            }
        }
    
        return OK; /* Restart */
    }
    
    static void winnt_hooks(apr_pool_t *p)
    {
        /* Our open_logs hook function 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_check_config(winnt_check_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_REALLY_FIRST);
        ap_hook_mpm(winnt_run, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_query(winnt_query, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_get_name(winnt_get_name, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    AP_DECLARE_MODULE(mpm_winnt) = {
        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 */
    ��������������������������������������������������httpd-2.4.64/server/mpm/winnt/mpm_default.h���������������������������������������������������������0000664�0001751�0001751�00000004037�11711754075�020542� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  winnt/mpm_default.h
     * @brief win32 MPM defaults
     *
     * @defgroup APACHE_MPM_WINNT WinNT MPM
     * @ingroup APACHE_INTERNAL
     * @{
     */
    
    #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
    
    #endif /* AP_MPM_DEFAULT_H */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/child.c���������������������������������������������������������������0000664�0001751�0001751�00000142274�14207134173�017323� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <process.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 "http_vhost.h"   /* for ap_update_vhost_given_ip */
    #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 <malloc.h>
    #include "apr_atomic.h"
    #include "apr_buckets.h"
    #include "scoreboard.h"
    
    #ifdef __MINGW32__
    #include <mswsock.h>
    
    #ifndef WSAID_ACCEPTEX
    #define WSAID_ACCEPTEX \
      {0xb5367df1, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
    typedef BOOL (WINAPI *LPFN_ACCEPTEX)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED);
    #endif /* WSAID_ACCEPTEX */
    
    #ifndef WSAID_GETACCEPTEXSOCKADDRS
    #define WSAID_GETACCEPTEXSOCKADDRS \
      {0xb5367df2, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
    typedef VOID (WINAPI *LPFN_GETACCEPTEXSOCKADDRS)(PVOID, DWORD, DWORD, DWORD,
                                                     struct sockaddr **, LPINT,
                                                     struct sockaddr **, LPINT);
    #endif /* WSAID_GETACCEPTEXSOCKADDRS */
    
    #endif /* __MINGW32__ */
    
    /*
     * The Windows 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 *)( \
                                                      (char *)(address) - \
                                                      (char *)(&((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
    
    APLOG_USE_MODULE(mpm_winnt);
    
    /* Queue for managing the passing of winnt_conn_ctx_t between
     * the accept and worker threads.
     */
    typedef struct winnt_conn_ctx_t_s {
        struct winnt_conn_ctx_t_s *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;
        apr_bucket *data;
    #if APR_HAVE_IPV6
        short socket_family;
    #endif
    } winnt_conn_ctx_t;
    
    typedef enum {
        IOCP_CONNECTION_ACCEPTED = 1,
        IOCP_WAIT_FOR_RECEIVE = 2,
        IOCP_WAIT_FOR_TRANSMITFILE = 3,
        IOCP_SHUTDOWN = 4
    } io_state_e;
    
    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 winnt_conn_ctx_t *qhead = NULL;
    static winnt_conn_ctx_t *qtail = NULL;
    static apr_uint32_t num_completion_contexts = 0;
    static apr_uint32_t max_num_completion_contexts = 0;
    static HANDLE ThreadDispatchIOCP = NULL;
    static HANDLE qwait_event = NULL;
    
    static void mpm_recycle_completion_context(winnt_conn_ctx_t *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) {
            HANDLE saved_event;
    
            apr_pool_clear(context->ptrans);
            context->ba = apr_bucket_alloc_create(context->ptrans);
            context->next = NULL;
    
            saved_event = context->overlapped.hEvent;
            memset(&context->overlapped, 0, sizeof(context->overlapped));
            context->overlapped.hEvent = saved_event;
            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);
        }
    }
    
    static winnt_conn_ctx_t *mpm_get_completion_context(int *timeout)
    {
        apr_status_t rv;
        winnt_conn_ctx_t *context = NULL;
    
        *timeout = 0;
        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_ERR, 0, ap_server_conf, APLOGNO(00326)
                                     "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 {
                        if (rv == WAIT_TIMEOUT) {
                            /* somewhat-normal condition where threads are busy */
                            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00327)
                                         "mpm_get_completion_context: Failed to get a "
                                         "free context within 1 second");
                            *timeout = 1;
                        }
                        else {
                            /* should be the unexpected, generic WAIT_FAILED */
                            ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
                                         ap_server_conf, APLOGNO(00328)
                                         "mpm_get_completion_context: "
                                         "WaitForSingleObject failed to get free context");
                        }
                        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 = (winnt_conn_ctx_t *)apr_pcalloc(pchild,
                                                         sizeof(winnt_conn_ctx_t));
    
    
                    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, APLOGNO(00329)
                                     "mpm_get_completion_context: "
                                     "CreateEvent failed.");
    
                        apr_thread_mutex_unlock(child_lock);
                        return NULL;
                    }
    
                    /* Create the transaction 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, APLOGNO(00330)
                                     "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(context->ptrans);
                    apr_atomic_inc32(&num_completion_contexts);
    
                    apr_thread_mutex_unlock(child_lock);
                    break;
                }
            } else {
                /* Got a context from the queue */
                break;
            }
        }
    
        return context;
    }
    
    typedef enum {
        ACCEPT_FILTER_NONE = 0,
        ACCEPT_FILTER_CONNECT = 1
    } accept_filter_e;
    
    static const char * accept_filter_to_string(accept_filter_e accf)
    {
        switch (accf) {
        case ACCEPT_FILTER_NONE:
            return "none";
        case ACCEPT_FILTER_CONNECT:
            return "connect";
        default:
            return "";
        }
    }
    
    static accept_filter_e get_accept_filter(const char *protocol)
    {
        core_server_config *core_sconf;
        const char *name;
    
        core_sconf = ap_get_core_module_config(ap_server_conf->module_config);
        name = apr_table_get(core_sconf->accf_map, protocol);
        if (!name) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf,
                         APLOGNO(02531) "winnt_accept: Listen protocol '%s' has "
                         "no known accept filter. Using 'none' instead",
                         protocol);
            return ACCEPT_FILTER_NONE;
        }
        else if (strcmp(name, "data") == 0) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
                         APLOGNO(03458) "winnt_accept: 'data' accept filter is no "
                         "longer supported. Using 'connect' instead");
            return ACCEPT_FILTER_CONNECT;
        }
        else if (strcmp(name, "connect") == 0) {
            return ACCEPT_FILTER_CONNECT;
        }
        else if (strcmp(name, "none") == 0) {
            return ACCEPT_FILTER_NONE;
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(00331)
                         "winnt_accept: unrecognized AcceptFilter '%s', "
                         "only 'data', 'connect' or 'none' are valid. "
                         "Using 'none' instead", name);
            return ACCEPT_FILTER_NONE;
        }
    }
    
    /* 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 10
    
    static unsigned int __stdcall winnt_accept(void *lr_)
    {
        ap_listen_rec *lr = (ap_listen_rec *)lr_;
        apr_os_sock_info_t sockinfo;
        winnt_conn_ctx_t *context = NULL;
        DWORD BytesRead = 0;
        SOCKET nlsd;
        LPFN_ACCEPTEX lpfnAcceptEx = NULL;
        LPFN_GETACCEPTEXSOCKADDRS lpfnGetAcceptExSockaddrs = NULL;
        GUID GuidAcceptEx = WSAID_ACCEPTEX;
        GUID GuidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
        int rv;
        accept_filter_e accf;
        int err_count = 0;
        HANDLE events[3];
    #if APR_HAVE_IPV6
        SOCKADDR_STORAGE ss_listen;
        int namelen = sizeof(ss_listen);
    #endif
        u_long zero = 0;
    
        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, APLOGNO(00332)
                         "winnt_accept: getsockname error on listening socket, "
                         "is IPv6 available?");
            return 1;
       }
    #endif
    
        accf = get_accept_filter(lr->protocol);
        if (accf == ACCEPT_FILTER_CONNECT)
        {
            if (WSAIoctl(nlsd, SIO_GET_EXTENSION_FUNCTION_POINTER,
                         &GuidAcceptEx, sizeof GuidAcceptEx, 
                         &lpfnAcceptEx, sizeof lpfnAcceptEx, 
                         &BytesRead, NULL, NULL) == SOCKET_ERROR) {
                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(),
                             ap_server_conf, APLOGNO(02322)
                             "winnt_accept: failed to retrieve AcceptEx, try 'AcceptFilter none'");
                return 1;
            }
            if (WSAIoctl(nlsd, SIO_GET_EXTENSION_FUNCTION_POINTER,
                         &GuidGetAcceptExSockaddrs, sizeof GuidGetAcceptExSockaddrs,
                         &lpfnGetAcceptExSockaddrs, sizeof lpfnGetAcceptExSockaddrs,
                         &BytesRead, NULL, NULL) == SOCKET_ERROR) {
                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(),
                             ap_server_conf, APLOGNO(02323)
                             "winnt_accept: failed to retrieve GetAcceptExSockaddrs, try 'AcceptFilter none'");
                return 1;
            }
            /* first, high priority event is an already accepted connection */
            events[1] = exit_event;
            events[2] = max_requests_per_child_event;
        }
        else /* accf == ACCEPT_FILTER_NONE */
        {
    reinit: /* target of connect upon too many AcceptEx failures */
    
            /* last, low priority event is a not yet accepted connection */
            events[0] = exit_event;
            events[1] = max_requests_per_child_event;
            events[2] = CreateEvent(NULL, FALSE, FALSE, NULL);
    
            /* The event needs to be removed from the accepted socket,
             * if not removed from the listen socket prior to accept(),
             */
            rv = WSAEventSelect(nlsd, events[2], FD_ACCEPT);
            if (rv) {
                ap_log_error(APLOG_MARK, APLOG_ERR,
                             apr_get_netos_error(), ap_server_conf, APLOGNO(00333)
                             "WSAEventSelect() failed.");
                CloseHandle(events[2]);
                return 1;
            }
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00334)
                     "Child: Accept thread listening on %pI using AcceptFilter %s",
                     lr->bind_addr, accept_filter_to_string(accf));
    
        while (!shutdown_in_progress) {
            if (!context) {
                int timeout;
    
                context = mpm_get_completion_context(&timeout);
                if (!context) {
                    if (!timeout) {
                        /* Hopefully a temporary condition in the provider? */
                        ++err_count;
                        if (err_count > MAX_ACCEPTEX_ERR_COUNT) {
                            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(00335)
                                         "winnt_accept: Too many failures grabbing a "
                                         "connection ctx.  Aborting.");
                            break;
                        }
                    }
                    Sleep(100);
                    continue;
                }
            }
    
            if (accf == ACCEPT_FILTER_CONNECT)
            {
                char *buf;
    
                /* 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;
                }
    #else
                if (context->accept_socket == INVALID_SOCKET)
                    context->accept_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    #endif
    
                if (context->accept_socket == INVALID_SOCKET) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(),
                                 ap_server_conf, APLOGNO(00336)
                                 "winnt_accept: Failed to allocate an accept socket. "
                                 "Temporary resource constraint? Try again.");
                    Sleep(100);
                    continue;
                }
    
                buf = context->buff;
    
                /* AcceptEx on the completion context. The completion context will be
                 * signaled when a connection is accepted.
                 */
                if (!lpfnAcceptEx(nlsd, context->accept_socket, buf, 0,
                                  PADDED_ADDR_SIZE, PADDED_ADDR_SIZE, &BytesRead,
                                  &context->overlapped)) {
                    rv = apr_get_netos_error();
                    if ((rv == APR_FROM_OS_ERROR(WSAECONNRESET)) ||
                        (rv == APR_FROM_OS_ERROR(WSAEACCES))) {
                        /* We can get here when:
                         * 1) the client disconnects early
                         * 2) handshake was incomplete
                         */
                        closesocket(context->accept_socket);
                        context->accept_socket = INVALID_SOCKET;
                        continue;
                    }
                    else if ((rv == APR_FROM_OS_ERROR(WSAEINVAL)) ||
                             (rv == APR_FROM_OS_ERROR(WSAENOTSOCK))) {
                        /* We can get here when:
                         * 1) TransmitFile does not properly recycle the accept socket (typically
                         *    because the client disconnected)
                         * 2) there is VPN or Firewall software installed with
                         *    buggy WSAAccept or WSADuplicateSocket implementation
                         * 3) the dynamic address / adapter has changed
                         * Give five chances, then fall back on AcceptFilter 'none'
                         */
                        closesocket(context->accept_socket);
                        context->accept_socket = INVALID_SOCKET;
                        ++err_count;
                        if (err_count > MAX_ACCEPTEX_ERR_COUNT) {
                            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00337)
                                         "Child: Encountered too many AcceptEx "
                                         "faults accepting client connections. "
                                         "Possible causes: dynamic address renewal, "
                                         "or incompatible VPN or firewall software. ");
                            ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, ap_server_conf, APLOGNO(00338)
                                         "winnt_mpm: falling back to "
                                         "'AcceptFilter none'.");
                            err_count = 0;
                            accf = ACCEPT_FILTER_NONE;
                        }
                        continue;
                    }
                    else if ((rv != APR_FROM_OS_ERROR(ERROR_IO_PENDING)) &&
                             (rv != APR_FROM_OS_ERROR(WSA_IO_PENDING))) {
                        closesocket(context->accept_socket);
                        context->accept_socket = INVALID_SOCKET;
                        ++err_count;
                        if (err_count > MAX_ACCEPTEX_ERR_COUNT) {
                            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00339)
                                         "Child: Encountered too many AcceptEx "
                                         "faults accepting client connections.");
                            ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, ap_server_conf, APLOGNO(00340)
                                         "winnt_mpm: falling back to "
                                         "'AcceptFilter none'.");
                            err_count = 0;
                            accf = ACCEPT_FILTER_NONE;
                            goto reinit;
                        }
                        continue;
                    }
    
                    err_count = 0;
                    events[0] = context->overlapped.hEvent;
    
                    do {
                        rv = WaitForMultipleObjectsEx(3, events, FALSE, INFINITE, TRUE);
                    } while (rv == WAIT_IO_COMPLETION);
    
                    if (rv == WAIT_OBJECT_0) {
                        if ((context->accept_socket != INVALID_SOCKET) &&
                            !GetOverlappedResult((HANDLE)context->accept_socket,
                                                 &context->overlapped,
                                                 &BytesRead, FALSE)) {
                            ap_log_error(APLOG_MARK, APLOG_WARNING,
                                         apr_get_os_error(), ap_server_conf, APLOGNO(00341)
                                 "winnt_accept: Asynchronous AcceptEx failed.");
                            closesocket(context->accept_socket);
                            context->accept_socket = INVALID_SOCKET;
                        }
                    }
                    else {
                        /* exit_event triggered or event handle was closed */
                        closesocket(context->accept_socket);
                        context->accept_socket = INVALID_SOCKET;
                        break;
                    }
    
                    if (context->accept_socket == INVALID_SOCKET) {
                        continue;
                    }
                }
                err_count = 0;
    
                /* Potential optimization; consider handing off to the worker */
    
                /* 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, APLOGNO(00342)
                                 "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed.");
                    /* Not a failure condition. Keep running. */
                }
    
                /* Get the local & remote address
                 * TODO; error check
                 */
                lpfnGetAcceptExSockaddrs(buf, 0, PADDED_ADDR_SIZE, PADDED_ADDR_SIZE,
                                         &context->sa_server, &context->sa_server_len,
                                         &context->sa_client, &context->sa_client_len);
            }
            else /* accf == ACCEPT_FILTER_NONE */
            {
                /* There is no socket reuse without AcceptEx() */
                if (context->accept_socket != INVALID_SOCKET)
                    closesocket(context->accept_socket);
    
                /* This could be a persistent event per-listener rather than
                 * per-accept.  However, the event needs to be removed from
                 * the target socket if not removed from the listen socket
                 * prior to accept(), or the event select is inherited.
                 * and must be removed from the accepted socket.
                 */
    
                do {
                    rv = WaitForMultipleObjectsEx(3, events, FALSE, INFINITE, TRUE);
                } while (rv == WAIT_IO_COMPLETION);
    
    
                if (rv != WAIT_OBJECT_0 + 2) {
                    /* not FD_ACCEPT;
                     * exit_event triggered or event handle was closed
                     */
                    break;
                }
    
                context->sa_server = (void *) context->buff;
                context->sa_server_len = sizeof(context->buff) / 2;
                context->sa_client_len = context->sa_server_len;
                context->sa_client = (void *) (context->buff
                                             + context->sa_server_len);
    
                context->accept_socket = accept(nlsd, context->sa_server,
                                                &context->sa_server_len);
    
                if (context->accept_socket == INVALID_SOCKET) {
    
                    rv = apr_get_netos_error();
                    if (   rv == APR_FROM_OS_ERROR(WSAECONNRESET)
                        || rv == APR_FROM_OS_ERROR(WSAEINPROGRESS)
                        || rv == APR_FROM_OS_ERROR(WSAEWOULDBLOCK) ) {
                        ap_log_error(APLOG_MARK, APLOG_DEBUG,
                                     rv, ap_server_conf, APLOGNO(00343)
                                     "accept() failed, retrying.");
                        continue;
                    }
    
                    /* A more serious error than 'retry', log it */
                    ap_log_error(APLOG_MARK, APLOG_WARNING,
                                 rv, ap_server_conf, APLOGNO(00344)
                                 "accept() failed.");
    
                    if (   rv == APR_FROM_OS_ERROR(WSAEMFILE)
                        || rv == APR_FROM_OS_ERROR(WSAENOBUFS) ) {
                        /* Hopefully a temporary condition in the provider? */
                        Sleep(100);
                        ++err_count;
                        if (err_count > MAX_ACCEPTEX_ERR_COUNT) {
                            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00345)
                                         "Child: Encountered too many accept() "
                                         "resource faults, aborting.");
                            break;
                        }
                        continue;
                    }
                    break;
                }
                /* Per MSDN, cancel the inherited association of this socket
                 * to the WSAEventSelect API, and restore the state corresponding
                 * to apr_os_sock_make's default assumptions (really, a flaw within
                 * os_sock_make and os_sock_put that it does not query).
                 */
                WSAEventSelect(context->accept_socket, 0, 0);
                err_count = 0;
    
                context->sa_server_len = sizeof(context->buff) / 2;
                if (getsockname(context->accept_socket, context->sa_server,
                                &context->sa_server_len) == SOCKET_ERROR) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, APLOGNO(00346)
                                 "getsockname failed");
                    continue;
                }
                if ((getpeername(context->accept_socket, context->sa_client,
                                 &context->sa_client_len)) == SOCKET_ERROR) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, APLOGNO(00347)
                                 "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;
            sockinfo.protocol = IPPROTO_TCP;
            /* Restore the state corresponding to apr_os_sock_make's default
             * assumption of timeout -1 (really, a flaw of os_sock_make and
             * os_sock_put that it does not query to determine ->timeout).
             * XXX: Upon a fix to APR, these three statements should disappear.
             */
            ioctlsocket(context->accept_socket, FIONBIO, &zero);
            setsockopt(context->accept_socket, SOL_SOCKET, SO_RCVTIMEO,
                       (char *) &zero, sizeof(zero));
            setsockopt(context->accept_socket, SOL_SOCKET, SO_SNDTIMEO,
                       (char *) &zero, sizeof(zero));
            apr_os_sock_make(&context->sock, &sockinfo, context->ptrans);
    
            /* When a connection is received, send an io completion notification
             * to the ThreadDispatchIOCP.
             */
            PostQueuedCompletionStatus(ThreadDispatchIOCP, BytesRead,
                                       IOCP_CONNECTION_ACCEPTED,
                                       &context->overlapped);
            context = NULL;
        }
        if (accf == ACCEPT_FILTER_NONE)
            CloseHandle(events[2]);
    
        if (!shutdown_in_progress) {
            /* Yow, hit an irrecoverable error! Tell the child to die. */
            SetEvent(exit_event);
        }
    
        ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00348)
                     "Child: Accept thread exiting.");
        return 0;
    }
    
    
    static winnt_conn_ctx_t *winnt_get_connection(winnt_conn_ctx_t *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, APLOGNO(00349)
                             "Child: GetQueuedCompletionStatus returned %d",
                             rc);
                continue;
            }
    
            switch (CompKey) {
            case IOCP_CONNECTION_ACCEPTED:
                context = CONTAINING_RECORD(pol, winnt_conn_ctx_t, 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 DWORD __stdcall worker_main(void *thread_num_val)
    {
        apr_thread_t *thd = NULL;
        apr_os_thread_t osthd = NULL;
        static int requests_this_child = 0;
        winnt_conn_ctx_t *context = NULL;
        int thread_num = (int)thread_num_val;
        ap_sb_handle_t *sbh;
        conn_rec *c;
        apr_int32_t disconnected;
    
    #if AP_HAS_THREAD_LOCAL
        if (ap_thread_current_create(&thd, NULL, pchild) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(10376)
                         "Couldn't initialize worker thread, thread locals won't "
                         "be available");
            osthd = apr_os_thread_current();
        }
    #else
        osthd = apr_os_thread_current();
    #endif
    
        while (1) {
    
            ap_update_child_status_from_indexes(0, thread_num, SERVER_READY, NULL);
    
            /* Grab a connection off the network */
            context = winnt_get_connection(context);
    
            if (!context) {
                /* Time for the thread to exit */
                break;
            }
    
            /* Have we hit MaxConnectionsPerChild 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_run_create_connection closes the socket on failure */
                context->accept_socket = INVALID_SOCKET;
                continue;
            }
    
            if (osthd) {
                thd = NULL;
                apr_os_thread_put(&thd, &osthd, context->ptrans);
            }
            c->current_thread = thd;
    
            ap_process_connection(c, context->sock);
    
            ap_lingering_close(c);
    
            apr_socket_opt_get(context->sock, APR_SO_DISCONNECTED, &disconnected);
            if (!disconnected) {
                context->accept_socket = INVALID_SOCKET;
            }
        }
    
        ap_update_child_status_from_indexes(0, thread_num, SERVER_DEAD, NULL);
    
    #if AP_HAS_THREAD_LOCAL
        if (!osthd) {
            apr_pool_destroy(apr_thread_pool_get(thd));
        }
    #endif
    
        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(void)
    {
        unsigned tid;
        int num_listeners = 0;
        /* 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) {
                /* A smaller stack is sufficient.
                 * To convert to CreateThread, the returned handle cannot be
                 * ignored, it must be closed/joined.
                 */
                _beginthreadex(NULL, 65536, winnt_accept,
                               (void *) lr, stack_res_flag, &tid);
            }
        }
    }
    
    
    void child_main(apr_pool_t *pconf, DWORD parent_pid)
    {
        apr_status_t status;
        apr_hash_t *ht;
        ap_listen_rec *lr;
        HANDLE child_events[3];
        HANDLE *child_handles;
        int listener_started = 0;
        int threads_created = 0;
        int watch_thread;
        int time_remains;
        int cld;
        DWORD tid;
        int rv;
        int i;
        int num_events;
    
        /* Get a sub context for global allocations in this child, so that
         * we can have cleanups occur when the child exits.
         */
        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, APLOGNO(00350)
                         "Child: Failed to create a max_requests event.");
            exit(APEXIT_CHILDINIT);
        }
        child_events[0] = exit_event;
        child_events[1] = max_requests_per_child_event;
    
        if (parent_pid != my_pid) {
            child_events[2] = OpenProcess(SYNCHRONIZE, FALSE, parent_pid);
            if (child_events[2] == NULL) {
                num_events = 2;
                ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), ap_server_conf, APLOGNO(02643)
                             "Child: Failed to open handle to parent process %ld; "
                             "will not react to abrupt parent termination", parent_pid);
            }
            else {
                num_events = 3;
            }
        }
        else {
            /* presumably -DONE_PROCESS */
            child_events[2] = NULL;
            num_events = 2;
        }
    
        /*
         * 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, APLOGNO(00351)
                         "Child: Failed to acquire the start_mutex. "
                         "Process will exit.");
            exit(APEXIT_CHILDINIT);
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00352)
                     "Child: Acquired the start mutex.");
    
        /*
         * Create the worker thread dispatch IOCompletionPort
         */
        /* Create the worker thread dispatch IOCP */
        ThreadDispatchIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
                                                    NULL, 0, 0);
        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, APLOGNO(00353)
                         "Child: Failed to create a qwait event.");
            exit(APEXIT_CHILDINIT);
        }
    
        /*
         * Create the pool of worker threads
         */
        ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00354)
                     "Child: Starting %d worker threads.", 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] = CreateThread(NULL, ap_thread_stacksize,
                                                worker_main, (void *) i,
                                                stack_res_flag, &tid);
                if (child_handles[i] == 0) {
                    ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(),
                                 ap_server_conf, APLOGNO(00355)
                                 "Child: CreateThread failed. Unable to "
                                 "create all worker threads. Created %d of the %d "
                                 "threads requested with the ThreadsPerChild "
                                 "configuration directive.",
                                 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 these 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 MaxConnectionsPerChild connections.
         *
         * parent process exiting
         *
         * 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(num_events, (HANDLE *)child_events, FALSE, INFINITE);
            cld = rv - WAIT_OBJECT_0;
    #else
            /* THIS IS THE EXPECTED BUILD VARIATION -- APR_HAS_OTHER_CHILD */
            rv = WaitForMultipleObjects(num_events, (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, APLOGNO(00356)
                             "Child: WAIT_FAILED -- shutting down server");
                /* check handle validity to identify a possible culprit */
                for (i = 0; i < num_events; i++) {
                    DWORD out_flags;
    
                    if (0 == GetHandleInformation(child_events[i], &out_flags)) {
                        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(),
                                     ap_server_conf, APLOGNO(02644)
                                     "Child: Event handle #%d (%pp) is invalid",
                                     i, child_events[i]);
                    }
                }
                break;
            }
            else if (cld == 0) {
                /* Exit event was signaled */
                ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00357)
                             "Child: Exit event signaled. Child process is "
                             "ending.");
                break;
            }
            else if (cld == 2) {
                /* The parent is dead.  Shutdown the child process. */
                ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(02538)
                             "Child: Parent process exited abruptly. Child process "
                             "is ending");
                break;
            }
            else {
                /* MaxConnectionsPerChild event set by the worker threads.
                 * Signal the parent to restart
                 */
                ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00358)
                             "Child: Process exiting because it reached "
                             "MaxConnectionsPerChild. Signaling the parent to "
                             "restart a new child process.");
                ap_signal_parent(SIGNAL_PARENT_RESTART);
                break;
            }
        }
    
        /*
         * Time to shutdown the child process
         */
    
     shutdown:
    
        winnt_mpm_state = AP_MPMQ_STOPPING;
    
        /* 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 sockets
         * 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_DEBUG, rv, ap_server_conf, APLOGNO(00359)
                         "Child: Released the start mutex");
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00360)
                         "Child: Failure releasing the start mutex");
        }
    
        /* Shutdown the worker threads
         * Post worker threads blocked on the ThreadDispatch IOCompletion port
         */
        while (g_blocked_threads > 0) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00361)
                         "Child: %d threads blocked on the completion port",
                         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 threads a chance to service their connections
         * (no more than the global server timeout period which
         * we track in msec remaining).
         */
        watch_thread = 0;
        time_remains = (int)(ap_server_conf->timeout / APR_TIME_C(1000));
    
        while (threads_created)
        {
            int nFailsafe = MAXIMUM_WAIT_OBJECTS;
            DWORD dwRet;
    
            /* Every time we roll over to wait on the first group
             * of MAXIMUM_WAIT_OBJECTS threads, take a breather,
             * and infrequently update the error log.
             */
            if (watch_thread >= threads_created) {
                if ((time_remains -= 100) < 0)
                    break;
    
                /* Every 30 seconds give an update */
                if ((time_remains % 30000) == 0) {
                    ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS,
                                 ap_server_conf, APLOGNO(00362)
                                 "Child: Waiting %d more seconds "
                                 "for %d worker threads to finish.",
                                 time_remains / 1000, threads_created);
                }
                /* We'll poll from the top, 10 times per second */
                Sleep(100);
                watch_thread = 0;
            }
    
            /* Fairness, on each iteration we will pick up with the thread
             * after the one we just removed, even if it's a single thread.
             * We don't block here.
             */
            dwRet = WaitForMultipleObjects(min(threads_created - watch_thread,
                                               MAXIMUM_WAIT_OBJECTS),
                                           child_handles + watch_thread, 0, 0);
    
            if (dwRet == WAIT_FAILED) {
                break;
            }
            if (dwRet == WAIT_TIMEOUT) {
                /* none ready */
                watch_thread += MAXIMUM_WAIT_OBJECTS;
                continue;
            }
            else if (dwRet >= WAIT_ABANDONED_0) {
                /* We just got the ownership of the object, which
                 * should happen at most MAXIMUM_WAIT_OBJECTS times.
                 * It does NOT mean that the object is signaled.
                 */
                if ((nFailsafe--) < 1)
                    break;
            }
            else {
                watch_thread += (dwRet - WAIT_OBJECT_0);
                if (watch_thread >= threads_created)
                    break;
                cleanup_thread(child_handles, &threads_created, watch_thread);
            }
        }
    
        /* Kill remaining threads off the hard way */
        if (threads_created) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00363)
                         "Child: Terminating %d threads that failed to exit.",
                         threads_created);
        }
        for (i = 0; i < threads_created; i++) {
            int *idx;
            TerminateThread(child_handles[i], 1);
            CloseHandle(child_handles[i]);
            /* Reset the scoreboard entry for the thread we just whacked */
            idx = apr_hash_get(ht, &child_handles[i], sizeof(HANDLE));
            if (idx) {
                ap_update_child_status_from_indexes(0, *idx, SERVER_DEAD, NULL);
            }
        }
        ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00364)
                     "Child: All worker threads have exited.");
    
        apr_thread_mutex_destroy(child_lock);
        apr_thread_mutex_destroy(qlock);
        CloseHandle(qwait_event);
        CloseHandle(ThreadDispatchIOCP);
    
        apr_pool_destroy(pchild);
        CloseHandle(exit_event);
        if (child_events[2] != NULL) {
            CloseHandle(child_events[2]);
        }
    }
    
    #endif /* def WIN32 */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/mpm_winnt.h�����������������������������������������������������������0000664�0001751�0001751�00000005626�12763577432�020272� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mpm_winnt.h
     * @brief WinNT MPM specific
     *
     * @addtogroup APACHE_MPM_WINNT
     * @{
     */
    
    #ifndef APACHE_MPM_WINNT_H
    #define APACHE_MPM_WINNT_H
    
    #include "apr_proc_mutex.h"
    #include "ap_listen.h"
    
    /* From service.c: */
    
    #define SERVICE_APACHE_RESTART 128
    
    #ifndef AP_DEFAULT_SERVICE_NAME
    #define AP_DEFAULT_SERVICE_NAME "Apache2.4"
    #endif
    
    #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(const char *display_name, apr_pool_t *p);
    void mpm_nt_eventlog_stderr_flush(void);
    
    /* From mpm_winnt.c: */
    
    extern module AP_MODULE_DECLARE_DATA mpm_winnt_module;
    extern int ap_threads_per_child;
    
    extern DWORD my_pid;
    extern apr_proc_mutex_t *start_mutex;
    extern HANDLE exit_event;
    
    extern int winnt_mpm_state;
    extern OSVERSIONINFO osver;
    extern DWORD stack_res_flag;
    
    extern void clean_child_exit(int);
    
    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);
    
    void hold_console_open_on_error(void);
    
    /* From child.c: */
    void child_main(apr_pool_t *pconf, DWORD parent_pid);
    
    #endif /* APACHE_MPM_WINNT_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/config.m4�������������������������������������������������������������0000664�0001751�0001751�00000000326�11172132604�017565� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_MSG_CHECKING(if WinNT MPM supports this platform)
    case $host in
        *mingw32*)
            AC_MSG_RESULT(yes)
            APACHE_MPM_SUPPORTED(winnt, no, yes)
            ;;
        *)
            AC_MSG_RESULT(no)
            ;;
    esac
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/service.c�������������������������������������������������������������0000664�0001751�0001751�00000123512�13623622544�017677� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _WINUSER_
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_lib.h"
    #if APR_HAS_UNICODE_FS
    #include "arch/win32/apr_arch_utf8.h"
    #include "arch/win32/apr_arch_misc.h"
    #include <wchar.h>
    #endif
    
    #include "httpd.h"
    #include "http_log.h"
    #include "mpm_winnt.h"
    #include "ap_regkey.h"
    
    #ifdef NOUSER
    #undef NOUSER
    #endif
    #undef _WINUSER_
    #include <winuser.h>
    #include <time.h>
    
    APLOG_USE_MODULE(mpm_winnt);
    
    /* Todo; clear up statics */
    static char *mpm_service_name = NULL;
    static char *mpm_display_name = NULL;
    
    #if APR_HAS_UNICODE_FS
    static apr_wchar_t *mpm_service_name_w;
    #endif
    
    typedef struct nt_service_ctx_t
    {
        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;
    } nt_service_ctx_t;
    
    static nt_service_ctx_t globdat;
    
    static int ReportStatusToSCMgr(int currentState, int waitHint,
                                   nt_service_ctx_t *ctx);
    
    /* Rather than repeat this logic throughout, create an either-or wide or narrow
     * implementation because we don't actually pass strings to OpenSCManager.
     * This election is based on build time defines and runtime os version test.
     */
    #undef OpenSCManager
    typedef SC_HANDLE (WINAPI *fpt_OpenSCManager)(const void *lpMachine,
                                                  const void *lpDatabase,
                                                  DWORD dwAccess);
    static fpt_OpenSCManager pfn_OpenSCManager = NULL;
    static APR_INLINE SC_HANDLE OpenSCManager(const void *lpMachine,
                                              const void *lpDatabase,
                                              DWORD dwAccess)
    {
        if (!pfn_OpenSCManager) {
    #if APR_HAS_UNICODE_FS
            IF_WIN_OS_IS_UNICODE
                pfn_OpenSCManager = (fpt_OpenSCManager)OpenSCManagerW;
    #endif
    #if APR_HAS_ANSI_FS
            ELSE_WIN_OS_IS_ANSI
                pfn_OpenSCManager = (fpt_OpenSCManager)OpenSCManagerA;
    #endif
        }
        return (*(pfn_OpenSCManager))(lpMachine, lpDatabase, dwAccess); 
    }
    
    /* 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 undesirable 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 <ESC> 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...",
                    (int)remains); /* 30 or less, so can't overflow int */
            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 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.
                 */
                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);
    }
    
    
    void mpm_start_child_console_handler(void)
    {
        FreeConsole();
    }
    
    
    /**********************************
      WinNT service control management
     **********************************/
    
    static int ReportStatusToSCMgr(int currentState, int waitHint,
                                   nt_service_ctx_t *ctx)
    {
        int rv = APR_SUCCESS;
    
        if (ctx->hServiceStatus)
        {
            if (currentState == SERVICE_RUNNING) {
                ctx->ssStatus.dwWaitHint = 0;
                ctx->ssStatus.dwCheckPoint = 0;
                ctx->ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP
                                                 | SERVICE_ACCEPT_SHUTDOWN;
            }
            else if (currentState == SERVICE_STOPPED) {
                ctx->ssStatus.dwWaitHint = 0;
                ctx->ssStatus.dwCheckPoint = 0;
                /* An unexpected exit?  Better to error! */
                if (ctx->ssStatus.dwCurrentState != SERVICE_STOP_PENDING
                        && !ctx->ssStatus.dwServiceSpecificExitCode)
                    ctx->ssStatus.dwServiceSpecificExitCode = 1;
                if (ctx->ssStatus.dwServiceSpecificExitCode)
                    ctx->ssStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
            }
            else {
                ++ctx->ssStatus.dwCheckPoint;
                ctx->ssStatus.dwControlsAccepted = 0;
                if(waitHint)
                    ctx->ssStatus.dwWaitHint = waitHint;
            }
    
            ctx->ssStatus.dwCurrentState = currentState;
    
            rv = SetServiceStatus(ctx->hServiceStatus, &ctx->ssStatus);
        }
        return(rv);
    }
    
    /* Note this works on Win2000 and later due to ChangeServiceConfig2
     * Continue to test its existence, but at least drop the feature
     * of revising service description tags prior to Win2000.
     */
    
    /* borrowed from mpm_winnt.c */
    extern apr_pool_t *pconf;
    
    static void set_service_description(void)
    {
        const char *full_description;
        SC_HANDLE schSCManager;
    
        /* 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_description();
    
        if ((ChangeServiceConfig2) &&
            (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)))
        {
            SC_HANDLE schService;
    
    #if APR_HAS_UNICODE_FS
            IF_WIN_OS_IS_UNICODE
            {
                schService = OpenServiceW(schSCManager,
                                          (LPCWSTR)mpm_service_name_w,
                                          SERVICE_CHANGE_CONFIG);
            }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
            ELSE_WIN_OS_IS_ANSI
            {
                schService = OpenService(schSCManager, mpm_service_name,
                                         SERVICE_CHANGE_CONFIG);
            }
    #endif
            if (schService) {
                /* Cast is necessary, ChangeServiceConfig2 handles multiple
                 * object types, some volatile, some not.
                 */
    #if APR_HAS_UNICODE_FS
                IF_WIN_OS_IS_UNICODE
                {
                    apr_size_t slen = strlen(full_description) + 1;
                    apr_size_t wslen = slen;
                    apr_wchar_t *full_description_w = 
                        (apr_wchar_t*)apr_palloc(pconf, 
                                                 wslen * sizeof(apr_wchar_t));
                    apr_status_t rv = apr_conv_utf8_to_ucs2(full_description, &slen,
                                                            full_description_w,
                                                            &wslen);
                    if ((rv != APR_SUCCESS) || slen
                            || ChangeServiceConfig2W(schService, 1
                                                     /*SERVICE_CONFIG_DESCRIPTION*/,
                                                     (LPVOID) &full_description_w))
                        full_description = NULL;
                }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
                ELSE_WIN_OS_IS_ANSI
                {
                    if (ChangeServiceConfig2(schService,
                                             1 /* SERVICE_CONFIG_DESCRIPTION */,
                                             (LPVOID) &full_description))
                        full_description = NULL;
                }
    #endif
                CloseServiceHandle(schService);
            }
            CloseServiceHandle(schSCManager);
        }
    }
    
    /* handle the SCM's ControlService() callbacks to our service */
    
    static DWORD WINAPI service_nt_ctrl(DWORD dwCtrlCode, DWORD dwEventType,
                                        LPVOID lpEventData, LPVOID lpContext)
    {
        nt_service_ctx_t *ctx = lpContext;
    
        /* SHUTDOWN is offered before STOP, accept the first opportunity */
        if ((dwCtrlCode == SERVICE_CONTROL_STOP)
             || (dwCtrlCode == SERVICE_CONTROL_SHUTDOWN))
        {
            ap_signal_parent(SIGNAL_PARENT_SHUTDOWN);
            ReportStatusToSCMgr(SERVICE_STOP_PENDING, 30000, ctx);
            return (NO_ERROR);
        }
        if (dwCtrlCode == SERVICE_APACHE_RESTART)
        {
            ap_signal_parent(SIGNAL_PARENT_RESTART);
            ReportStatusToSCMgr(SERVICE_START_PENDING, 30000, ctx);
            return (NO_ERROR);
        }
        if (dwCtrlCode == SERVICE_CONTROL_INTERROGATE) {
            ReportStatusToSCMgr(globdat.ssStatus.dwCurrentState, 0, ctx);
            return (NO_ERROR);
        }
    
        return (ERROR_CALL_NOT_IMPLEMENTED);
    }
    
    
    /* 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;
    
    #if APR_HAS_UNICODE_FS
    static void __stdcall service_nt_main_fn_w(DWORD argc, LPWSTR *argv)
    {
        const char *ignored;
        nt_service_ctx_t *ctx = &globdat;
        char *service_name;
        apr_size_t wslen = wcslen(argv[0]) + 1;
        apr_size_t slen = wslen * 3 - 2;
    
        service_name = malloc(slen);
        (void)apr_conv_ucs2_to_utf8(argv[0], &wslen, service_name, &slen);
    
        /* args and service names live in the same pool */
        mpm_service_set_name(mpm_new_argv->pool, &ignored, service_name);
    
        memset(&ctx->ssStatus, 0, sizeof(ctx->ssStatus));
        ctx->ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
        ctx->ssStatus.dwCurrentState = SERVICE_START_PENDING;
        ctx->ssStatus.dwCheckPoint = 1;
        if (!(ctx->hServiceStatus = 
                  RegisterServiceCtrlHandlerExW(argv[0], service_nt_ctrl, ctx)))
        {
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 
                         apr_get_os_error(), NULL, 
                         APLOGNO(00365) "Failure registering service handler");
            return;
        }
    
        /* Report status, no errors, and buy 3 more seconds */
        ReportStatusToSCMgr(SERVICE_START_PENDING, 30000, ctx);
    
        /* We need to append all the command arguments passed via StartService()
         * to our running service... which just got here via the SCM...
         * but we have no interest in argv[0] for the mpm_new_argv list.
         */
        if (argc > 1)
        {
            char **cmb_data, **cmb;
            DWORD i;
    
            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));
    
            cmb = cmb_data + mpm_new_argv->nelts;
    
            for (i = 1; i < argc; ++i)
            {
                wslen = wcslen(argv[i]) + 1;
                slen = wslen * 3 - 2;
                service_name = malloc(slen);
                (void)apr_conv_ucs2_to_utf8(argv[i], &wslen, *(cmb++), &slen);
            }
    
            /* 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(ctx->service_init);
    
        WaitForSingleObject(ctx->service_term, INFINITE);
    }
    #endif /* APR_HAS_UNICODE_FS */
    
    
    #if APR_HAS_ANSI_FS
    static void __stdcall service_nt_main_fn(DWORD argc, LPSTR *argv)
    {
        const char *ignored;
        nt_service_ctx_t *ctx = &globdat;
    
        /* args and service names live in the same pool */
        mpm_service_set_name(mpm_new_argv->pool, &ignored, argv[0]);
    
        memset(&ctx->ssStatus, 0, sizeof(ctx->ssStatus));
        ctx->ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
        ctx->ssStatus.dwCurrentState = SERVICE_START_PENDING;
        ctx->ssStatus.dwCheckPoint = 1;
    
        if (!(ctx->hServiceStatus = 
                  RegisterServiceCtrlHandlerExA(argv[0], service_nt_ctrl, ctx)))
            {
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 
                         apr_get_os_error(), NULL, 
                         APLOGNO(10008) "Failure registering service handler");
            return;
        }
    
        /* Report status, no errors, and buy 3 more seconds */
        ReportStatusToSCMgr(SERVICE_START_PENDING, 30000, ctx);
    
        /* We need to append all the command arguments passed via StartService()
         * to our running service... which just got here via the SCM...
         * but we have 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(ctx->service_init);
    
        WaitForSingleObject(ctx->service_term, INFINITE);
    }
    #endif
    
    
     static DWORD WINAPI service_nt_dispatch_thread(LPVOID nada)
     {
    #if APR_HAS_UNICODE_FS
        SERVICE_TABLE_ENTRYW dispatchTable_w[] =
        {
            { L"", service_nt_main_fn_w },
            { NULL, NULL }
        };
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
        SERVICE_TABLE_ENTRYA dispatchTable[] =
        {
            { "", service_nt_main_fn },
            { NULL, NULL }
        };
    #endif
        apr_status_t rv;
     
    #if APR_HAS_UNICODE_FS
        IF_WIN_OS_IS_UNICODE
            rv = StartServiceCtrlDispatcherW(dispatchTable_w);
    #endif
    #if APR_HAS_ANSI_FS
        ELSE_WIN_OS_IS_ANSI
             rv = StartServiceCtrlDispatcherA(dispatchTable);
    #endif
        if (rv) {
            rv = APR_SUCCESS;
        }
        else {
            /* This is a genuine failure of the SCM. */
            rv = apr_get_os_error();
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,
                         APLOGNO(00366) "Error starting Windows service control "
                         "dispatcher");
        }
        return (rv);
    }
    
    
    /* The service configuration's is stored under the following trees:
     *
     * HKLM\System\CurrentControlSet\Services\[service name]
     *
     *     \DisplayName
     *     \ImagePath
     *     \Parameters\ConfigArgs
     */
    
    
    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);
    #if APR_HAS_UNICODE_FS
        IF_WIN_OS_IS_UNICODE
        {
            apr_size_t slen = strlen(mpm_service_name) + 1;
            apr_size_t wslen = slen;
            mpm_service_name_w = apr_palloc(p, wslen * sizeof(apr_wchar_t));
            rv = apr_conv_utf8_to_ucs2(mpm_service_name, &slen,
                                       mpm_service_name_w, &wslen);
            if (rv != APR_SUCCESS)
                return rv;
            else if (slen)
                return APR_ENAMETOOLONG;
        }
    #endif /* APR_HAS_UNICODE_FS */
    
        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, APLOGNO(00367)
                             "No ConfigArgs registered for the '%s' service, "
                             "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;
    }
    
    
    static void service_stopped(void)
    {
        /* Still have a thread & window to clean up, so signal now */
        if (globdat.service_thread)
        {
            /* 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, 0, &globdat);
    
            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;
        }
    
        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, 65536,
                                              service_nt_dispatch_thread,
                                              NULL, stack_res_flag,
                                              &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();
        ReportStatusToSCMgr(SERVICE_RUNNING, 0, &globdat);
        return APR_SUCCESS;
    }
    
    
    void mpm_service_stopping(void)
    {
        ReportStatusToSCMgr(SERVICE_STOP_PENDING, 30000, &globdat);
    }
    
    
    apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc,
                                     const char * const * argv, int reconfig)
    {
        char key_name[MAX_PATH];
        char *launch_cmd;
        ap_regkey_t *key;
        apr_status_t rv;
        SC_HANDLE   schService;
        SC_HANDLE   schSCManager;
        DWORD       rc;
    #if APR_HAS_UNICODE_FS
        apr_wchar_t *display_name_w;
        apr_wchar_t *launch_cmd_w;
    #endif
    
        fprintf(stderr, reconfig ? "Reconfiguring the '%s' service\n"
                                 : "Installing the '%s' service\n",
                        mpm_display_name);
    
    #if APR_HAS_UNICODE_FS
        IF_WIN_OS_IS_UNICODE
        {
            apr_size_t slen = strlen(mpm_display_name) + 1;
            apr_size_t wslen = slen;
            display_name_w = apr_palloc(ptemp, wslen * sizeof(apr_wchar_t));
            rv = apr_conv_utf8_to_ucs2(mpm_display_name, &slen,
                                       display_name_w, &wslen);
            if (rv != APR_SUCCESS)
                return rv;
            else if (slen)
                return APR_ENAMETOOLONG;
    
            launch_cmd_w = apr_palloc(ptemp, (MAX_PATH + 17) * sizeof(apr_wchar_t));
            launch_cmd_w[0] = L'"';
            rc = GetModuleFileNameW(NULL, launch_cmd_w + 1, MAX_PATH);
            wcscpy(launch_cmd_w + rc + 1, L"\" -k runservice");
        }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
        ELSE_WIN_OS_IS_ANSI
        {
            launch_cmd = apr_palloc(ptemp, MAX_PATH + 17);
            launch_cmd[0] = '"';
            rc = GetModuleFileName(NULL, launch_cmd + 1, MAX_PATH);
            strcpy(launch_cmd + rc + 1, "\" -k runservice");
        }
    #endif
        if (rc == 0) {
            rv = apr_get_os_error();
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,
                         APLOGNO(00368) "GetModuleFileName failed");
            return rv;
        }
    
        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,
                         APLOGNO(00369)  "Failed to open the Windows service "
                         "manager, perhaps you forgot to log in as Administrator?");
            return (rv);
        }
    
        if (reconfig) {
    #if APR_HAS_UNICODE_FS
            IF_WIN_OS_IS_UNICODE
            {
                schService = OpenServiceW(schSCManager, mpm_service_name_w,
                                          SERVICE_CHANGE_CONFIG);
            }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
            ELSE_WIN_OS_IS_ANSI
            {
                schService = OpenService(schSCManager, mpm_service_name,
                                         SERVICE_CHANGE_CONFIG);
            }
    #endif
            if (!schService) {
                rv = apr_get_os_error();
                CloseServiceHandle(schSCManager);
                ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,
                             APLOGNO(00373) "Failed to open the '%s' service",
                             mpm_display_name);
                return (rv);
            }
    
    #if APR_HAS_UNICODE_FS
            IF_WIN_OS_IS_UNICODE
            {
                rc = ChangeServiceConfigW(schService,
                                          SERVICE_WIN32_OWN_PROCESS,
                                          SERVICE_AUTO_START,
                                          SERVICE_ERROR_NORMAL,
                                          launch_cmd_w, NULL, NULL,
                                          L"Tcpip\0Afd\0", NULL, NULL,
                                          display_name_w);
            }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
            ELSE_WIN_OS_IS_ANSI
            {
                rc = ChangeServiceConfig(schService,
                                         SERVICE_WIN32_OWN_PROCESS,
                                         SERVICE_AUTO_START,
                                         SERVICE_ERROR_NORMAL,
                                         launch_cmd, NULL, NULL,
                                         "Tcpip\0Afd\0", NULL, NULL,
                                         mpm_display_name);
            }
    #endif
            if (!rc) {
                ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP,
                             apr_get_os_error(), NULL,
                             APLOGNO(02652) "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.
             */
    #if APR_HAS_UNICODE_FS
            IF_WIN_OS_IS_UNICODE
            {
                schService = CreateServiceW(schSCManager,    // SCManager database
                                     mpm_service_name_w,   // name of service
                                     display_name_w,   // 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_w,         // service's binary
                                     NULL,                 // no load svc group
                                     NULL,                 // no tag identifier
                                     L"Tcpip\0Afd\0",      // dependencies
                                     NULL,                 // use SYSTEM account
                                     NULL);                // no password
            }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
            ELSE_WIN_OS_IS_ANSI
            {
                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
            }
    #endif
            if (!schService)
            {
                rv = apr_get_os_error();
                ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,
                             APLOGNO(00370) "Failed to create the '%s' service",
                             mpm_display_name);
                CloseServiceHandle(schSCManager);
                return (rv);
            }
        }
    
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
    
        set_service_description();
    
        /* 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,
                         APLOGNO(00371) "Failed to store ConfigArgs for the "
                         "'%s' service 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)
    {
        apr_status_t rv;
        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,
                         APLOGNO(10009)  "Failed to open the Windows service "
                         "manager, perhaps you forgot to log in as Administrator?");
            return (rv);
        }
    
    #if APR_HAS_UNICODE_FS
        IF_WIN_OS_IS_UNICODE
        {
            schService = OpenServiceW(schSCManager, mpm_service_name_w, DELETE);
        }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
        ELSE_WIN_OS_IS_ANSI
        {
            schService = OpenService(schSCManager, mpm_service_name, DELETE);
        }
    #endif
        if (!schService) {
            rv = apr_get_os_error();
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,
                         APLOGNO(10010) "Failed to open the '%s' service",
                         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,
                         APLOGNO(00374) "Failed to delete the '%s' service",
                         mpm_display_name);
            return (rv);
        }
    
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
    
        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;
        SC_HANDLE   schService;
        SC_HANDLE   schSCManager;
    
        fprintf(stderr, "Starting 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,
                         APLOGNO(10011)  "Failed to open the Windows service "
                         "manager, perhaps you forgot to log in as Administrator?");
            return (rv);
        }
    
    #if APR_HAS_UNICODE_FS
        IF_WIN_OS_IS_UNICODE
        {
            schService = OpenServiceW(schSCManager, mpm_service_name_w,
                                      SERVICE_START | SERVICE_QUERY_STATUS);
        }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
        ELSE_WIN_OS_IS_ANSI
        {
            schService = OpenService(schSCManager, mpm_service_name,
                                     SERVICE_START | SERVICE_QUERY_STATUS);
        }
    #endif
        if (!schService) {
            rv = apr_get_os_error();
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, 
                         APLOGNO(10012) "Failed to open the '%s' 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,
                         APLOGNO(00377) "The '%s' service is already started!",
                         mpm_display_name);
            CloseServiceHandle(schService);
            CloseServiceHandle(schSCManager);
            return 0;
        }
    
        rv = APR_EINIT;
    #if APR_HAS_UNICODE_FS
        IF_WIN_OS_IS_UNICODE
        {
            LPWSTR *start_argv_w = malloc((argc + 1) * sizeof(LPCWSTR));
            int i;
    
            for (i = 0; i < argc; ++i)
            {
                apr_size_t slen = strlen(argv[i]) + 1;
                apr_size_t wslen = slen;
                start_argv_w[i] = malloc(wslen * sizeof(WCHAR));
                rv = apr_conv_utf8_to_ucs2(argv[i], &slen, start_argv_w[i], &wslen);
                if (rv != APR_SUCCESS)
                    return rv;
                else if (slen)
                    return APR_ENAMETOOLONG;
            }
            start_argv_w[argc] = NULL;
    
            if (StartServiceW(schService, argc, start_argv_w)
                && signal_service_transition(schService, 0, /* test only */
                                             SERVICE_START_PENDING,
                                             SERVICE_RUNNING))
                    rv = APR_SUCCESS;
        }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
        ELSE_WIN_OS_IS_ANSI
        {
            char **start_argv = malloc((argc + 1) * sizeof(const char *));
            memcpy(start_argv, argv, argc * sizeof(const char *));
            start_argv[argc] = NULL;
    
            if (StartService(schService, argc, start_argv)
                && signal_service_transition(schService, 0, /* test only */
                                             SERVICE_START_PENDING,
                                             SERVICE_RUNNING))
                    rv = APR_SUCCESS;
        }
    #endif
        if (rv != APR_SUCCESS)
            rv = apr_get_os_error();
    
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
    
        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, APLOGNO(00378)
                         "Failed to start the '%s' service",
                         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;
        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,
                         APLOGNO(10013)  "Failed to open the Windows service "
                         "manager, perhaps you forgot to log in as Administrator?");
            return;
        }
    
    #if APR_HAS_UNICODE_FS
        IF_WIN_OS_IS_UNICODE
        {
            schService = OpenServiceW(schSCManager, mpm_service_name_w,
                                      SERVICE_INTERROGATE | SERVICE_QUERY_STATUS |
                                      SERVICE_USER_DEFINED_CONTROL |
                                      SERVICE_START | SERVICE_STOP);
        }
    #endif /* APR_HAS_UNICODE_FS */
    #if APR_HAS_ANSI_FS
        ELSE_WIN_OS_IS_ANSI
        {
            schService = OpenService(schSCManager, mpm_service_name,
                                     SERVICE_INTERROGATE | SERVICE_QUERY_STATUS |
                                     SERVICE_USER_DEFINED_CONTROL |
                                     SERVICE_START | SERVICE_STOP);
        }
    #endif
        if (schService == NULL) {
            /* Could not open the service */
            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP,
                         apr_get_os_error(), NULL,
                         APLOGNO(10014) "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,
                         APLOGNO(00381) "Query of the '%s' service 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, signal ? "The '%s' service is restarting.\n"
                               : "The '%s' service is stopping.\n",
                        mpm_display_name);
    
        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);
    
        if (success)
            fprintf(stderr, signal ? "The '%s' service has restarted.\n"
                                   : "The '%s' service has stopped.\n",
                            mpm_display_name);
        else
            fprintf(stderr, signal ? "Failed to restart the '%s' service.\n"
                                   : "Failed to stop the '%s' service.\n",
                            mpm_display_name);
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/winnt/config3.m4������������������������������������������������������������0000664�0001751�0001751�00000000174�11274040000�017640� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������winnt_objects="child.lo mpm_winnt.lo nt_eventlog.lo service.lo"
    APACHE_MPM_MODULE(winnt, $enable_mpm_winnt, $winnt_objects)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/mpmt_os2/�������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016473� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/mpmt_os2/mpmt_os2_child.c���������������������������������������������������0000664�0001751�0001751�00000036035�14037102164�021535� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_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 "scoreboard.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 <os2.h>
    #include <process.h>
    
    APLOG_USE_MODULE(mpm_mpmt_os2);
    
    /* 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);
        apr_pool_tag(pchild, "pchild");
    
        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, APLOGNO(00189)
                         "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, APLOGNO(00190)
                         "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, APLOGNO(00191)
                         "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, APLOGNO(00192)
                         "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, APLOGNO(00193)
                         "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);
            apr_pool_tag(pconn, "transaction");
            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, APLOGNO(00194)
                                 "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; c<HARD_THREAD_LIMIT; c++) {
                if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) {
                    DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0);
                }
            }
    
            do {
                someleft = 0;
    
                for (c=0; c<HARD_THREAD_LIMIT; c++) {
                    if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) {
                        someleft = 1;
                        DosSleep(1000);
                        break;
                    }
                }
            } while (someleft);
        } else {
            DosPurgeQueue(workq);
    
            for (c=0; c<HARD_THREAD_LIMIT; c++) {
                if (ap_scoreboard_image->servers[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;
        int stacksize = ap_thread_stacksize == 0 ? 128*1024 : ap_thread_stacksize;
    
        /* 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, stacksize, (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, APLOGNO(00195)
                         "caught exception in worker thread, initiating child shutdown pid=%d", getpid());
            for (c=0; c<HARD_THREAD_LIMIT; c++) {
                if (ap_scoreboard_image->servers[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)
    {
        apr_thread_t *thd = NULL;
        apr_os_thread_t osthd;
        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( &reg_rec );
    
        osthd = apr_os_thread_current();
        apr_os_thread_put(&thd, &osthd, pchild);
    
        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, APLOGNO(00196)
                         "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) {
                current_conn->current_thread = thd;
                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, APLOGNO(00197)
                         "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, APLOGNO(00198) "sigaction(SIGTERM)");
    
        sa.sa_handler = sig_hup;
    
        if (sigaction(SIGHUP, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00199) "sigaction(SIGHUP)");
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/mpmt_os2/config.m4����������������������������������������������������������0000664�0001751�0001751�00000000334�11274030073�020165� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_MSG_CHECKING(if mpmt_os2 MPM supports this platform)
    case $host in
        *os2-emx*)
            AC_MSG_RESULT(yes)
            APACHE_MPM_SUPPORTED(mpmt_os2, no, yes)
            ;;
        *)
            AC_MSG_RESULT(no)
            ;;
    esac
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/mpmt_os2/mpmt_os2.c���������������������������������������������������������0000664�0001751�0001751�00000044270�14155621751�020403� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 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 maintenance
     * thread so that the number of idle threads is kept between
     * min_spare_threads & max_spare_threads.
     *
     */
    
    /*
     Todo list
     - Enforce MaxRequestWorkers somehow
    */
    #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 "ap_mpm.h"
    #include "ap_listen.h"
    #include "apr_portable.h"
    #include "mpm_common.h"
    #include "scoreboard.h"
    #include "apr_strings.h"
    #include <os2.h>
    #include <process.h>
    
    /* 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 */
    
    /* Config globals */
    static int one_process = 0;
    static int ap_daemons_to_start = 0;
    static int ap_thread_limit = 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 = 0;
    
    /* 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 int master_main();
    static void spawn_child(int slot);
    void ap_mpm_child_main(apr_pool_t *pconf);
    static void set_signals();
    
    
    static int mpmt_os2_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 DONE;
        }
        else {
            /* Parent process */
            int rc;
            is_parent_process = TRUE;
    
            if (ap_setup_listeners(ap_server_conf) < 1) {
                ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, APLOGNO(00200)
                             "no listening sockets available, shutting down");
                return !OK;
            }
    
            ap_log_pid(pconf, ap_pid_fname);
    
            rc = master_main();
            ++ap_my_generation;
            ap_scoreboard_image->global->running_generation = ap_my_generation;
    
            if (rc != OK) {
                ap_remove_pid(pconf, ap_pid_fname);
                ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00201)
                             "caught %s, shutting down",
                             (rc == DONE) ? "SIGTERM" : "error");
                return rc;
            }
        }  /* Parent process */
    
        return OK; /* Restart */
    }
    
    
    
    /* Main processing of the parent process
     * returns TRUE if restarting
     */
    static int 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_description());
        set_signals();
    
        if (ap_setup_listeners(ap_server_conf) < 1) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, APLOGNO(00202)
                         "no listening sockets available, shutting down");
            return !OK;
        }
    
        /* 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, APLOGNO(00203)
                         "failure allocating shared memory, shutting down");
            return !OK;
        }
    
        /* 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, APLOGNO(00204)
                         "failure creating accept mutex, shutting down");
            return !OK;
        }
    
        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, APLOGNO(00205)
                             "unable to allocate shared memory for scoreboard , exiting");
                return !OK;
            }
    
            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, APLOGNO(00206)
                    "%s configured -- resuming normal operations",
                    ap_get_server_description());
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00207)
                    "Server built: %s", ap_get_server_built());
        if (one_process) {
            ap_scoreboard_image->parent[0].pid = getpid();
            ap_mpm_child_main(pconf);
            return DONE;
        }
    
        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; slot<HARD_SERVER_LIMIT; slot++) {
          kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
        }
    
        DosFreeMem(parent_info);
        return restart_pending ? OK : DONE;
    }
    
    
    
    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, APLOGNO(00208)
                         "error spawning child, slot %d", slot);
        }
    
        if (slot + 1 > ap_max_daemons_limit) {
            ap_max_daemons_limit = slot + 1;
        }
    
        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, APLOGNO(00209) "sigaction(SIGTERM)");
    
        if (sigaction(SIGINT, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00210) "sigaction(SIGINT)");
    
        sa.sa_handler = sig_restart;
    
        if (sigaction(SIGHUP, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00211) "sigaction(SIGHUP)");
        if (sigaction(SIGUSR1, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00212) "sigaction(SIGUSR1)");
    }
    
    
    
    /* Enquiry functions used get MPM status info */
    
    static apr_status_t mpmt_os2_query(int query_code, int *result, apr_status_t *rv)
    {
        *rv = APR_SUCCESS;
    
        switch (query_code) {
            case AP_MPMQ_MAX_DAEMON_USED:
                *result = ap_max_daemons_limit;
                break;
    
            case AP_MPMQ_IS_THREADED:
                *result = AP_MPMQ_DYNAMIC;
                break;
    
            case AP_MPMQ_IS_FORKED:
                *result = AP_MPMQ_NOT_SUPPORTED;
                break;
    
            case AP_MPMQ_HARD_LIMIT_DAEMONS:
                *result = HARD_SERVER_LIMIT;
                break;
    
            case AP_MPMQ_HARD_LIMIT_THREADS:
                *result = HARD_THREAD_LIMIT;
                break;
    
            case AP_MPMQ_MIN_SPARE_DAEMONS:
                *result = 0;
                break;
    
            case AP_MPMQ_MAX_SPARE_DAEMONS:
                *result = 0;
                break;
    
            case AP_MPMQ_MAX_REQUESTS_DAEMON:
                *result = ap_max_requests_per_child;
                break;
    
            case AP_MPMQ_GENERATION:
                *result = ap_my_generation;
                break;
    
            default:
                *rv = APR_ENOTIMPL;
                break;
        }
    
        return OK;
    }
    
    
    
    
    static const char *mpmt_os2_get_name(void)
    {
        return "mpmt_os2";
    }
    
    
    
    
    /* 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_extended_status = 0;
        ap_min_spare_threads = DEFAULT_MIN_SPARE_THREAD;
        ap_max_spare_threads = DEFAULT_MAX_SPARE_THREAD;
        ap_sys_privileges_handlers(1);
    
        return OK;
    }
    
    
    
    static int mpmt_os2_check_config(apr_pool_t *p, apr_pool_t *plog,
                                     apr_pool_t *ptemp, server_rec *s)
    {
        static int restart_num = 0;
        int startup = 0;
    
        /* we want this only the first time around */
        if (restart_num++ == 0) {
            startup = 1;
        }
    
        if (ap_daemons_to_start < 0) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00213)
                             "WARNING: StartServers of %d not allowed, "
                             "increasing to 1.", ap_daemons_to_start);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00214)
                             "StartServers of %d not allowed, increasing to 1",
                             ap_daemons_to_start);
            }
            ap_daemons_to_start = 1;
        }
    
        if (ap_min_spare_threads < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00215)
                             "WARNING: MinSpareThreads of %d not allowed, "
                             "increasing to 1 to avoid almost certain server failure. "
                             "Please read the documentation.", ap_min_spare_threads);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00216)
                             "MinSpareThreads of %d not allowed, increasing to 1",
                             ap_min_spare_threads);
            }
            ap_min_spare_threads = 1;
        }
    
        return OK;
    }
    
    
    
    static void mpmt_os2_hooks(apr_pool_t *p)
    {
        ap_hook_pre_config(mpmt_os2_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_config(mpmt_os2_check_config, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm(mpmt_os2_run, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_query(mpmt_os2_query, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_get_name(mpmt_os2_get_name, 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);
        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 }
    };
    
    AP_DECLARE_MODULE(mpm_mpmt_os2) = {
        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 */
    };
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/mpmt_os2/config5.m4���������������������������������������������������������0000664�0001751�0001751�00000000160�11274040000�020236� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������APACHE_MPM_MODULE(mpmt_os2, $enable_mpm_mpmt_os2, mpmt_os2.lo mpmt_os2_child.lo,[
        APR_ADDTO(CFLAGS,-Zmt)
    ])
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/mpmt_os2/Makefile.in��������������������������������������������������������0000664�0001751�0001751�00000000047�11274040000�020513� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/build/special.mk
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/mpmt_os2/mpm_default.h������������������������������������������������������0000664�0001751�0001751�00000003152�11711754075�021140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  mpmt_os2/mpm_default.h
     * @brief os2 MPM defaults
     *
     * @defgroup APACHE_MPM_OS2 OS/2 MPM
     * @ingroup APACHE_INTERNAL
     * @{
     */
    
    #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
    
    /*
     * Interval, in microseconds, between scoreboard maintenance.
     */
    #ifndef SCOREBOARD_MAINTENANCE_INTERVAL
    #define SCOREBOARD_MAINTENANCE_INTERVAL 1000000
    #endif
    
    #endif /* AP_MPM_DEFAULT_H */
    /** @} */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/netware/��������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�016400� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/netware/mpm_default.h�������������������������������������������������������0000664�0001751�0001751�00000004432�11711754075�021047� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  netware/mpm_default.h
     * @brief Defaults for Netware MPM
     *
     * @defgroup APACHE_MPM_NETWARE Netware MPM
     * @ingroup APACHE_INTERNAL
     * @{
     */
    #ifndef APACHE_MPM_DEFAULT_H
    #define APACHE_MPM_DEFAULT_H
    
    /* 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
    
    /*
     * Interval, in microseconds, between scoreboard maintenance.
     */
    #ifndef SCOREBOARD_MAINTENANCE_INTERVAL
    #define SCOREBOARD_MAINTENANCE_INTERVAL 1000000
    #endif
    
    /* Default stack size allocated for each worker thread.
     */
    #ifndef DEFAULT_THREAD_STACKSIZE
    #define DEFAULT_THREAD_STACKSIZE 65536
    #endif
    
    #endif /* AP_MPM_DEFAULT_H */
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/netware/mpm_netware.c�������������������������������������������������������0000664�0001751�0001751�00000126775�14037102164�021070� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <unistd.h>
    #endif
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    
    #ifndef USE_WINSOCK
    #include <sys/select.h>
    #endif
    
    #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 <time.h>
    #endif
    
    #include <signal.h>
    
    #include <netware.h>
    #include <nks/netware.h>
    #include <library.h>
    #include <screen.h>
    
    int nlmUnloadSignaled(int wait);
    
    /* 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
    
    #define MPM_HARD_LIMITS_FILE "/mpm_default.h"
    
    /* *Non*-shared http_main globals... */
    
    static 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 MaxRequestWorkers changes across SIGWINCH restarts.  We use this
     * value to optimize routines that have to scan the entire scoreboard.
     */
    static int ap_max_workers_limit = -1;
    
    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;
    static 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);
    }
    
    /* proper cleanup when returning from ap_mpm_run() */
    static void mpm_main_cleanup(void)
    {
        if (pmain) {
            apr_pool_destroy(pmain);
        }
    }
    
    static int netware_query(int query_code, int *result, apr_status_t *rv)
    {
        *rv = APR_SUCCESS;
        switch(query_code){
            case AP_MPMQ_MAX_DAEMON_USED:
                *result = 1;
                break;
            case AP_MPMQ_IS_THREADED:
                *result = AP_MPMQ_DYNAMIC;
                break;
            case AP_MPMQ_IS_FORKED:
                *result = AP_MPMQ_NOT_SUPPORTED;
                break;
            case AP_MPMQ_HARD_LIMIT_DAEMONS:
                *result = HARD_SERVER_LIMIT;
                break;
            case AP_MPMQ_HARD_LIMIT_THREADS:
                *result = HARD_THREAD_LIMIT;
                break;
            case AP_MPMQ_MAX_THREADS:
                *result = ap_threads_limit;
                break;
            case AP_MPMQ_MIN_SPARE_DAEMONS:
                *result = 0;
                break;
            case AP_MPMQ_MIN_SPARE_THREADS:
                *result = ap_threads_min_free;
                break;
            case AP_MPMQ_MAX_SPARE_DAEMONS:
                *result = 0;
                break;
            case AP_MPMQ_MAX_SPARE_THREADS:
                *result = ap_threads_max_free;
                break;
            case AP_MPMQ_MAX_REQUESTS_DAEMON:
                *result = ap_max_requests_per_child;
                break;
            case AP_MPMQ_MAX_DAEMONS:
                *result = 1;
                break;
            case AP_MPMQ_MPM_STATE:
                *result = mpm_state;
                break;
            case AP_MPMQ_GENERATION:
                *result = ap_my_generation;
                break;
            default:
                *rv = APR_ENOTIMPL;
                break;
        }
        return OK;
    }
    
    static const char *netware_get_name(void)
    {
        return "NetWare";
    }
    
    /*****************************************************************
     * 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.
     */
    
    
    #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_allocator_t *allocator;
        apr_bucket_alloc_t *bucket_alloc;
        conn_rec *current_conn;
        apr_status_t stat = APR_EINIT;
        ap_sb_handle_t *sbh;
        apr_thread_t *thd = NULL;
        apr_os_thread_t osthd;
    
        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;
    
        osthd = apr_os_thread_current();
        apr_os_thread_put(&thd, &osthd, pmain);
    
        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, APLOGNO(00217)
                            "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, APLOGNO(00218)
                                "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, APLOGNO(00219)
                                "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) {
                current_conn->current_thread = thd;
                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 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;
    
        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;
                }
    
                ++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, APLOGNO(00220)
                        "server reached MaxRequestWorkers setting, consider"
                        " raising the MaxRequestWorkers setting");
                    reported = 1;
                }
                idle_spawn_rate = 1;
            }
            else {
                if (idle_spawn_rate >= 8) {
                    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00221)
                        "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_description());
    
        for (i=0;i<SERVER_NUM_STATUS;i++) {
            status_array[i] = 0;
        }
    
        for (i = 0; i < ap_threads_limit; ++i) {
            status = (ap_scoreboard_image->servers[0][i]).status;
            status_array[status]++;
        }
    
        for (i=0;i<SERVER_NUM_STATUS;i++) {
            switch(i)
            {
            case SERVER_DEAD:
                printf ("Available:\t%d\n", status_array[i]);
                break;
            case SERVER_STARTING:
                printf ("Starting:\t%d\n", status_array[i]);
                break;
            case SERVER_READY:
                printf ("Ready:\t\t%d\n", status_array[i]);
                break;
            case SERVER_BUSY_READ:
                printf ("Busy:\t\t%d\n", status_array[i]);
                break;
            case SERVER_BUSY_WRITE:
                printf ("Busy Write:\t%d\n", status_array[i]);
                break;
            case SERVER_BUSY_KEEPALIVE:
                printf ("Busy Keepalive:\t%d\n", status_array[i]);
                break;
            case SERVER_BUSY_LOG:
                printf ("Busy Log:\t%d\n", status_array[i]);
                break;
            case SERVER_BUSY_DNS:
                printf ("Busy DNS:\t%d\n", status_array[i]);
                break;
            case SERVER_CLOSING:
                printf ("Closing:\t%d\n", status_array[i]);
                break;
            case SERVER_GRACEFUL:
                printf ("Restart:\t%d\n", status_array[i]);
                break;
            case SERVER_IDLE_KILL:
                printf ("Idle Kill:\t%d\n", status_array[i]);
                break;
            default:
                printf ("Unknown Status:\t%d\n", status_array[i]);
                break;
            }
            if (i != SERVER_DEAD)
                total+=status_array[i];
        }
        printf ("Total Running:\t%d\tout of: \t%d\n", total, ap_threads_limit);
        printf ("Requests per interval:\t%d\n", reqs);
    
    #ifdef DBINFO_ON
        printf ("Would blocks:\t%d\n", wblock);
        printf ("Successful retries:\t%d\n", retry_success);
        printf ("Failed retries:\t%d\n", retry_fail);
        printf ("Avg retries:\t%d\n", retry_success == 0 ? 0 : avg_retries / retry_success);
    #endif
    }
    
    static void show_server_data()
    {
        ap_listen_rec *lr;
        module **m;
    
        printf("%s\n", ap_get_server_description());
        if (ap_my_addrspace && (ap_my_addrspace[0] != 'O') && (ap_my_addrspace[1] != 'S'))
            printf("   Running in address space %s\n", ap_my_addrspace);
    
    
        /* Display listening ports */
        printf("   Listening on port(s):");
        lr = ap_listeners;
        do {
           printf(" %d", lr->bind_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, APLOGNO(00222)
                "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.
     */
    
    static int netware_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, APLOGNO(00223)
                "no listening sockets available, shutting down");
            return !OK;
        }
    
        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 !OK;
            }
        }
    
        /* Only set slot 0 since that is all NetWare will ever have. */
        ap_scoreboard_image->parent[0].pid = getpid();
        ap_scoreboard_image->parent[0].generation = ap_my_generation;
        ap_run_child_status(ap_server_conf,
                            ap_scoreboard_image->parent[0].pid,
                            ap_my_generation,
                            0,
                            MPM_CHILD_STARTED);
    
        set_signals();
    
        apr_pool_create(&pmain, pconf);
        apr_pool_tag(pmain, "pmain");
        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, APLOGNO(00224)
                "%s configured -- resuming normal operations",
                ap_get_server_description());
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00225)
                "Server built: %s", ap_get_server_built());
        ap_log_command_line(plog, s);
        ap_log_mpm_common(s);
        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;
    
        ap_run_child_status(ap_server_conf,
                            ap_scoreboard_image->parent[0].pid,
                            ap_my_generation,
                            0,
                            MPM_CHILD_EXITED);
    
        /* 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, APLOGNO(00226)
                "caught SIGTERM, shutting down");
    
            while (worker_thread_count > 0) {
                printf ("\rShutdown pending. Waiting for %lu thread(s) to terminate...",
                        worker_thread_count);
                apr_thread_yield();
            }
    
            mpm_main_cleanup();
            return DONE;
        }
        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, APLOGNO(00227)
                    "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 %lu thread(s) to terminate...",
                        worker_thread_count);
                apr_thread_yield();
            }
            printf ("\nRestarting...\n");
        }
    
        mpm_main_cleanup();
        return OK;
    }
    
    static int netware_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
    {
        char *addrname = NULL;
    
        mpm_state = AP_MPMQ_STARTING;
    
        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_extended_status = 0;
    
        /* override core's default thread stacksize */
        ap_thread_stacksize = DEFAULT_THREAD_STACKSIZE;
    
        return OK;
    }
    
    static int netware_check_config(apr_pool_t *p, apr_pool_t *plog,
                                    apr_pool_t *ptemp, server_rec *s)
    {
        static int restart_num = 0;
        int startup = 0;
    
        /* we want this only the first time around */
        if (restart_num++ == 0) {
            startup = 1;
        }
    
        if (ap_threads_limit > HARD_THREAD_LIMIT) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00228)
                             "WARNING: MaxThreads of %d exceeds compile-time "
                             "limit of %d threads, decreasing to %d. "
                             "To increase, please see the HARD_THREAD_LIMIT "
                             "define in server/mpm/netware%s.",
                             ap_threads_limit, HARD_THREAD_LIMIT, HARD_THREAD_LIMIT,
                             MPM_HARD_LIMITS_FILE);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00229)
                             "MaxThreads of %d exceeds compile-time limit "
                             "of %d, decreasing to match",
                             ap_threads_limit, HARD_THREAD_LIMIT);
            }
            ap_threads_limit = HARD_THREAD_LIMIT;
        }
        else if (ap_threads_limit < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00230)
                             "WARNING: MaxThreads of %d not allowed, "
                             "increasing to 1.", ap_threads_limit);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02661)
                             "MaxThreads of %d not allowed, increasing to 1",
                             ap_threads_limit);
            }
            ap_threads_limit = 1;
        }
    
        /* ap_threads_to_start > ap_threads_limit effectively checked in
         * call to startup_workers(ap_threads_to_start) in ap_mpm_run()
         */
        if (ap_threads_to_start < 0) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00231)
                             "WARNING: StartThreads of %d not allowed, "
                             "increasing to 1.", ap_threads_to_start);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00232)
                             "StartThreads of %d not allowed, increasing to 1",
                             ap_threads_to_start);
            }
            ap_threads_to_start = 1;
        }
    
        if (ap_threads_min_free < 1) {
            if (startup) {
                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00233)
                             "WARNING: MinSpareThreads of %d not allowed, "
                             "increasing to 1 to avoid almost certain server failure. "
                             "Please read the documentation.", ap_threads_min_free);
            } else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00234)
                             "MinSpareThreads of %d not allowed, increasing to 1",
                             ap_threads_min_free);
            }
            ap_threads_min_free = 1;
        }
    
        /* ap_threads_max_free < ap_threads_min_free + 1 checked in ap_mpm_run() */
    
        return OK;
    }
    
    static void netware_mpm_hooks(apr_pool_t *p)
    {
        /* Run the pre-config hook after core's so that it can override the
         * default setting of ThreadStackSize for NetWare.
         */
        static const char * const predecessors[] = {"core.c", NULL};
    
        ap_hook_pre_config(netware_pre_config, predecessors, NULL, APR_HOOK_MIDDLE);
        ap_hook_check_config(netware_check_config, NULL, NULL, APR_HOOK_MIDDLE);
        //ap_hook_post_config(netware_post_config, NULL, NULL, 0);
        //ap_hook_child_init(netware_child_init, NULL, NULL, APR_HOOK_MIDDLE);
        //ap_hook_open_logs(netware_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
        ap_hook_mpm(netware_run, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_query(netware_query, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_mpm_get_name(netware_get_name, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    static 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, 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;
    
        apr_cpystrn(szcommandLine, commandLine, sizeof(szcommandLine));
    
        /*  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 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_description());
                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 <instance ID>]\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);
        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);
        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 }
    };
    
    AP_DECLARE_MODULE(mpm_netware) = {
        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 */
    };
    ���httpd-2.4.64/server/mpm/MPM.NAMING������������������������������������������������������������������0000664�0001751�0001751�00000001401�11657416441�016252� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    The following MPMs currently exist:
    
      prefork ....... Multi  Process Model with Preforking (Apache 1.3)
      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
      event ......... Multi Process model with threads.  One acceptor thread,
                      multiple worker threads, separate poller threads for idle
                      connections and asynchoneous write completion.
      worker ........ Multi Process model with threads.  One acceptor thread,
                      multiple worker threads.
      netware ....... Multi-threaded MPM for Netware
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/config.m4�������������������������������������������������������������������0000664�0001751�0001751�00000006073�12604740165�016443� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl common platform checks needed by MPMs, methods for MPMs to state
    dnl their support for the platform, functions to query MPM properties
    
    APR_CHECK_APR_DEFINE(APR_HAS_THREADS)
    
    have_threaded_sig_graceful=yes
    case $host in
        *-linux-*)
            case `uname -r` in
              2.0* )
                dnl Threaded MPM's are not supported on Linux 2.0
                dnl as on 2.0 the linuxthreads library uses SIGUSR1
                dnl and SIGUSR2 internally
                have_threaded_sig_graceful=no
              ;;
            esac
        ;;
    esac
    
    dnl See if APR supports APR_POLLSET_THREADSAFE.
    dnl XXX This hack tests for the underlying functions used by APR when it supports
    dnl XXX APR_POLLSET_THREADSAFE, and duplicates APR's Darwin version check.
    dnl A run-time check for
    dnl     apr_pollset_create(,,APR_POLLSET_THREADSAFE) == APR_SUCCESS
    dnl would be great but an in-tree apr (srclib/apr) hasn't been built yet.
    
    AC_CACHE_CHECK([whether APR supports thread-safe pollsets], [ac_cv_have_threadsafe_pollset], [
        case $host in
            *-apple-darwin[[1-9]].*)
                APR_SETIFNULL(ac_cv_func_kqueue, [no])
                ;;
        esac
        AC_CHECK_FUNCS(kqueue port_create epoll_create)
        if test "$ac_cv_func_kqueue$ac_cv_func_port_create$ac_cv_func_epoll_create" != "nonono"; then
            ac_cv_have_threadsafe_pollset=yes
        else
            ac_cv_have_threadsafe_pollset=no
        fi
    ])
    
    dnl See if APR has skiplist
    dnl The base httpd prereq is APR 1.4.x, so we don't have to consider
    dnl earlier versions.
    case $APR_VERSION in
        1.4*)
            apr_has_skiplist=no
            ;;
        *)
            apr_has_skiplist=yes
    esac
    
    dnl See if this is a forking platform w.r.t. MPMs
    case $host in
        *mingw32* | *os2-emx*)
            forking_mpms_supported=no
            ;;
        *)
            forking_mpms_supported=yes
            ;;
    esac
    
    dnl APACHE_MPM_SUPPORTED(name, supports-shared, is_threaded)
    AC_DEFUN([APACHE_MPM_SUPPORTED],[
        if test "$2" = "yes"; then
            eval "ap_supported_mpm_$1=shared"
            ap_supported_shared_mpms="$ap_supported_shared_mpms $1 "
        else
            eval "ap_supported_mpm_$1=static"
        fi
        if test "$3" = "yes"; then
            eval "ap_threaded_mpm_$1=yes"
        fi
    ])dnl
    
    dnl APACHE_MPM_ENABLED(name)
    AC_DEFUN([APACHE_MPM_ENABLED],[
        if ap_mpm_is_enabled $1; then
            :
        else
            eval "ap_enabled_mpm_$1=yes"
            ap_enabled_mpms="$ap_enabled_mpms $1 "
        fi
    ])dnl
    
    ap_mpm_is_supported ()
    {
        eval "tmp=\$ap_supported_mpm_$1"
        if test -z "$tmp"; then
            return 1
        else
            return 0
        fi
    }
    
    ap_mpm_supports_shared ()
    {
        eval "tmp=\$ap_supported_mpm_$1"
        if test "$tmp" = "shared"; then
            return 0
        else
            return 1
        fi
    }
    
    ap_mpm_is_threaded ()
    {
        if test "$mpm_build" = "shared" -a ac_cv_define_APR_HAS_THREADS = "yes"; then
            return 0
        fi
    
        for mpm in $ap_enabled_mpms; do
            eval "tmp=\$ap_threaded_mpm_$mpm"
            if test "$tmp" = "yes"; then
                return 0
            fi
        done
        return 1
    }
    
    ap_mpm_is_enabled ()
    {
        eval "tmp=\$ap_enabled_mpm_$1"
        if test "$tmp" = "yes"; then
            return 0
        else
            return 1
        fi
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/Makefile.in�����������������������������������������������������������������0000664�0001751�0001751�00000000102�11273675556�017000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    SUBDIRS = $(MPM_SUBDIRS)
    
    include $(top_builddir)/build/rules.mk
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm/config2.m4������������������������������������������������������������������0000664�0001751�0001751�00000005550�11657416441�016530� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_MSG_CHECKING(which MPM to use by default)
    AC_ARG_WITH(mpm,
    APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use by default.
                              MPM={event|worker|prefork|winnt}
                              This will be statically linked as the only available MPM unless
                              --enable-mpms-shared is also specified.
    ),[
        default_mpm=$withval
        AC_MSG_RESULT($withval);
    ],[
        dnl Order of preference for default MPM: 
        dnl   The Windows and OS/2 MPMs are used on those platforms.
        dnl   Everywhere else: event, worker, prefork
        if ap_mpm_is_supported "winnt"; then
            default_mpm=winnt
            AC_MSG_RESULT(winnt)
        elif ap_mpm_is_supported "mpmt_os2"; then
            default_mpm=mpmt_os2
            AC_MSG_RESULT(mpmt_os2)
        elif ap_mpm_is_supported "event"; then
            default_mpm=event
            AC_MSG_RESULT(event)
        elif ap_mpm_is_supported "worker"; then
            default_mpm=worker
            AC_MSG_RESULT(worker - event is not supported)
        else
            default_mpm=prefork
            AC_MSG_RESULT(prefork - event and worker are not supported)
        fi
    ])
    
    APACHE_MPM_ENABLED($default_mpm)
    
    AC_ARG_ENABLE(mpms-shared,
    APACHE_HELP_STRING(--enable-mpms-shared=MPM-LIST,Space-separated list of MPM modules to enable for dynamic loading.  MPM-LIST=list | "all"),[
        if test "$enableval" = "no"; then
            mpm_build=static
        else
            mpm_build=shared
    dnl     Build just the default MPM if --enable-mpms-shared has no argument.
            if test "$enableval" = "yes"; then
                enableval=$default_mpm
            fi
            for i in $enableval; do
                if test "$i" = "all"; then
                    for j in $ap_supported_shared_mpms; do
                        eval "enable_mpm_$j=shared"
                        APACHE_MPM_ENABLED($j)
                    done
                else
                    i=`echo $i | sed 's/-/_/g'`
                    if ap_mpm_supports_shared $i; then
                        eval "enable_mpm_$i=shared"
                        APACHE_MPM_ENABLED($i)
                    else
                        AC_MSG_ERROR([MPM $i does not support dynamic loading.])
                    fi
                fi
            done
        fi
    ], [mpm_build=static])
    
    for i in $ap_enabled_mpms; do
        if ap_mpm_is_supported $i; then
            :
        else
            AC_MSG_ERROR([MPM $i is not supported on this platform.])
        fi
    done
    
    if test $mpm_build = "shared"; then
        eval "tmp=\$enable_mpm_$default_mpm"
        if test "$tmp" != "shared"; then
            AC_MSG_ERROR([The default MPM ($default_mpm) must be included in --enable-mpms-shared.  Use --with-mpm to change the default MPM.])
        fi
    fi
    
    APACHE_FAST_OUTPUT(server/mpm/Makefile)
    
    if test $mpm_build = "shared"; then
        MPM_LIB=""
    else
        MPM_LIB=server/mpm/$default_mpm/lib${default_mpm}.la
        MODLIST="$MODLIST mpm_${default_mpm}"
    fi
    
    MPM_SUBDIRS=$ap_enabled_mpms
    APACHE_SUBST(MPM_SUBDIRS)
    APACHE_SUBST(MPM_LIB)
    ��������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/scoreboard.c��������������������������������������������������������������������0000664�0001751�0001751�00000054111�15017773674�016442� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <sys/types.h>
    #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 "http_protocol.h"
    #include "ap_mpm.h"
    
    #include "scoreboard.h"
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    AP_DECLARE_DATA scoreboard *ap_scoreboard_image = NULL;
    AP_DECLARE_DATA const char *ap_scoreboard_fname = NULL;
    static ap_scoreboard_e scoreboard_type;
    
    const char * ap_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;
    }
    
    /* Default to false when mod_status is not loaded */
    AP_DECLARE_DATA int ap_extended_status = 0;
    
    const char *ap_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;
    }
    
    AP_DECLARE_DATA int ap_mod_status_reqtail = 0;
    
    const char *ap_set_reqtail(cmd_parms *cmd, void *dummy, int arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
        ap_mod_status_reqtail = arg;
        return NULL;
    }
    
    #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_logio_get_last_bytes)
                                    *pfn_ap_logio_get_last_bytes;
    
    struct ap_sb_handle_t {
        int child_num;
        int thread_num;
    };
    
    static int server_limit, thread_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;
    }
    
    #define SIZE_OF_scoreboard    APR_ALIGN_DEFAULT(sizeof(scoreboard))
    #define SIZE_OF_global_score  APR_ALIGN_DEFAULT(sizeof(global_score))
    #define SIZE_OF_process_score APR_ALIGN_DEFAULT(sizeof(process_score))
    #define SIZE_OF_worker_score  APR_ALIGN_DEFAULT(sizeof(worker_score))
    
    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);
    
        scoreboard_size  = SIZE_OF_global_score;
        scoreboard_size += SIZE_OF_process_score * server_limit;
        scoreboard_size += SIZE_OF_worker_score * server_limit * thread_limit;
    
        return scoreboard_size;
    }
    
    AP_DECLARE(void) ap_init_scoreboard(void *shared_score)
    {
        char *more_storage;
        int i;
    
        pfn_ap_logio_get_last_bytes = APR_RETRIEVE_OPTIONAL_FN(ap_logio_get_last_bytes);
        if (!shared_score) {
            return;
        }
        
        ap_calc_scoreboard_size();
        ap_scoreboard_image =
            ap_calloc(1, SIZE_OF_scoreboard + server_limit * sizeof(worker_score *));
        more_storage = shared_score;
        ap_scoreboard_image->global = (global_score *)more_storage;
        more_storage += SIZE_OF_global_score;
        ap_scoreboard_image->parent = (process_score *)more_storage;
        more_storage += SIZE_OF_process_score * server_limit;
        ap_scoreboard_image->servers =
            (worker_score **)((char*)ap_scoreboard_image + SIZE_OF_scoreboard);
        for (i = 0; i < server_limit; i++) {
            ap_scoreboard_image->servers[i] = (worker_score *)more_storage;
            more_storage += thread_limit * SIZE_OF_worker_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;
    }
    
    /**
     * 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, ap_server_conf, APLOGNO(00001)
                         "unable to create or access 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, ap_server_conf, APLOGNO(00002)
                         "Fatal error: unable to create global pool "
                         "for use 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, ap_server_conf, APLOGNO(00003)
                             "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, ap_server_conf, APLOGNO(00004)
                             "Unable to create or access 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 separate child process,
     * if zero, it is a forked child.
     */
    AP_DECLARE(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, ap_server_conf, APLOGNO(00005)
                         "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 (scoreboard_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 i;
    #if APR_HAS_SHARED_MEMORY
        apr_status_t rv;
    #endif
    
        if (ap_scoreboard_image) {
            ap_scoreboard_image->global->restart_time = apr_time_now();
            memset(ap_scoreboard_image->parent, 0,
                   SIZE_OF_process_score * server_limit);
            for (i = 0; i < server_limit; i++) {
                memset(ap_scoreboard_image->servers[i], 0,
                       SIZE_OF_worker_score * thread_limit);
            }
            ap_init_scoreboard(NULL);
            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 = ap_calloc(1, scoreboard_size);
            ap_init_scoreboard(sb_mem);
        }
    
        scoreboard_type = sb_type;
        ap_scoreboard_image->global->running_generation = 0;
        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_set_conn_count(ap_sb_handle_t *sb, request_rec *r, 
                                       unsigned short conn_count)
    {
        worker_score *ws;
    
        if (!sb)
            return;
    
        ws = &ap_scoreboard_image->servers[sb->child_num][sb->thread_num];
        ws->conn_count = conn_count;
    }
    
    AP_DECLARE(void) ap_increment_counts(ap_sb_handle_t *sb, request_rec *r)
    {
        worker_score *ws;
        apr_off_t bytes;
    
        if (!sb)
            return;
    
        ws = &ap_scoreboard_image->servers[sb->child_num][sb->thread_num];
        if (pfn_ap_logio_get_last_bytes != NULL) {
            bytes = pfn_ap_logio_get_last_bytes(r->connection);
        }
        else if (r->method_number == M_GET && r->method && r->method[0] == 'H') {
            bytes = 0;
        }
        else {
            bytes = r->bytes_sent;
        }
    
    #ifdef HAVE_TIMES
        times(&ws->times);
    #endif
        ws->access_count++;
        ws->my_access_count++;
        ws->conn_count++;
        ws->bytes_served += bytes;
        ws->my_bytes_served += bytes;
        ws->conn_bytes += bytes;
    }
    
    AP_DECLARE(int) ap_find_child_by_pid(apr_proc_t *pid)
    {
        int i;
        int max_daemons_limit = 0;
    
        ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &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_update_sb_handle(ap_sb_handle_t *sbh,
                                         int child_num, int thread_num)
    {
        sbh->child_num = child_num;
        sbh->thread_num = thread_num;
    }
    
    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));
        ap_update_sb_handle(*new_sbh, child_num, thread_num);
    }
    
    static void copy_request(char *rbuf, apr_size_t rbuflen, request_rec *r)
    {
        char *p;
    
        if (r->the_request == NULL) {
            apr_cpystrn(rbuf, "NULL", rbuflen);
            return; /* short circuit below */
        }
    
        if (r->parsed_uri.password == NULL) {
            p = r->the_request;
        }
        else {
            /* Don't reveal the password in the server-status view */
            p = apr_pstrcat(r->pool, r->method, " ",
                            apr_uri_unparse(r->pool, &r->parsed_uri,
                            APR_URI_UNP_OMITPASSWORD),
                            r->assbackwards ? NULL : " ", r->protocol, NULL);
        }
    
        /* now figure out if we copy over the 1st rbuflen chars or the last */
        if (!ap_mod_status_reqtail) {
            apr_cpystrn(rbuf, p, rbuflen);
        }
        else {
            apr_size_t slen = strlen(p);
            if (slen < rbuflen) {
                /* it all fits anyway */
                apr_cpystrn(rbuf, p, rbuflen);
            }
            else {
                apr_cpystrn(rbuf, p+(slen-rbuflen+1), rbuflen);
            }
        }
    }
    
    static int update_child_status_internal(int child_num,
                                            int thread_num,
                                            int status,
                                            conn_rec *c,
                                            server_rec *s,
                                            request_rec *r,
                                            const char *descr)
    {
        int old_status;
        worker_score *ws;
        int mpm_generation;
    
        ws = &ap_scoreboard_image->servers[child_num][thread_num];
        old_status = ws->status;
        ws->status = status;
        
        if (status == SERVER_READY
            && old_status == SERVER_STARTING) {
            process_score *ps = &ap_scoreboard_image->parent[child_num];
            ws->thread_num = child_num * thread_limit + thread_num;
            ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
            ps->generation = mpm_generation;
        }
    
        if (ap_extended_status) {
            const char *val;
            
            if (status == SERVER_READY || status == SERVER_DEAD) {
                /*
                 * Reset individual counters
                 */
                if (status == SERVER_DEAD) {
                    ws->my_access_count = 0L;
                    ws->my_bytes_served = 0L;
    #ifdef HAVE_TIMES
                    ws->times.tms_utime = 0;
                    ws->times.tms_stime = 0;
                    ws->times.tms_cutime = 0;
                    ws->times.tms_cstime = 0;
    #endif
                }
                ws->conn_count = 0;
                ws->conn_bytes = 0;
                ws->last_used = apr_time_now();
            }
    
            if (descr) {
                apr_cpystrn(ws->request, descr, sizeof(ws->request));
            }
            else if (r) {
                copy_request(ws->request, sizeof(ws->request), r);
            }
            else if (c) {
                ws->request[0]='\0';
            }
    
            if (r && r->useragent_ip) {
                if (!(val = ap_get_useragent_host(r, REMOTE_NOLOOKUP, NULL))) {
                    apr_cpystrn(ws->client, r->useragent_ip, sizeof(ws->client)); /* DEPRECATE */
                    apr_cpystrn(ws->client64, r->useragent_ip, sizeof(ws->client64));
                }
                else {
                    apr_cpystrn(ws->client, val, sizeof(ws->client)); /* DEPRECATE */
                    apr_cpystrn(ws->client64, val, sizeof(ws->client64));
                }
            }
            else if (c) {
                if (!(val = ap_get_remote_host(c, c->base_server->lookup_defaults,
                                               REMOTE_NOLOOKUP, NULL))) {
                    apr_cpystrn(ws->client, c->client_ip, sizeof(ws->client)); /* DEPRECATE */
                    apr_cpystrn(ws->client64, c->client_ip, sizeof(ws->client64));
                }
                else {
                    apr_cpystrn(ws->client, val, sizeof(ws->client)); /* DEPRECATE */
                    apr_cpystrn(ws->client64, val, sizeof(ws->client64));
                }
            }
    
            if (s) {
                if (c) {
                    apr_snprintf(ws->vhost, sizeof(ws->vhost), "%s:%d",
                                 s->server_hostname, c->local_addr->port);
                }
                else {
                    apr_cpystrn(ws->vhost, s->server_hostname, sizeof(ws->vhost));
                }
            }
            else if (c) {
                ws->vhost[0]='\0';
            }
    
            if (c) {
                val = ap_get_protocol(c);
                apr_cpystrn(ws->protocol, val, sizeof(ws->protocol));
            }
        }
    
        return old_status;
    }
    
    AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num,
                                                        int thread_num,
                                                        int status,
                                                        request_rec *r)
    {
        if (child_num < 0) {
            return -1;
        }
    
        return update_child_status_internal(child_num, thread_num, status,
                                            r ? r->connection : NULL,
                                            r ? r->server : NULL,
                                            r, NULL);
    }
    
    AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status,
                                          request_rec *r)
    {
        if (!sbh || (sbh->child_num < 0))
            return -1;
    
        return update_child_status_internal(sbh->child_num, sbh->thread_num,
                                            status,
                                            r ? r->connection : NULL,
                                            r ? r->server : NULL,
                                            r, NULL);
    }
    
    AP_DECLARE(int) ap_update_child_status_from_conn(ap_sb_handle_t *sbh, int status,
                                                     conn_rec *c)
    {
        if (!sbh || (sbh->child_num < 0))
            return -1;
    
        return update_child_status_internal(sbh->child_num, sbh->thread_num,
                                            status, c, NULL, NULL, NULL);
    }
    
    AP_DECLARE(int) ap_update_child_status_from_server(ap_sb_handle_t *sbh, int status, 
                                                       conn_rec *c, server_rec *s)
    {
        if (!sbh || (sbh->child_num < 0))
            return -1;
    
        return update_child_status_internal(sbh->child_num, sbh->thread_num,
                                            status, c, s, NULL, NULL);
    }
    
    AP_DECLARE(int) ap_update_child_status_descr(ap_sb_handle_t *sbh, int status, const char *descr)
    {
        if (!sbh || (sbh->child_num < 0))
            return -1;
    
        return update_child_status_internal(sbh->child_num, sbh->thread_num,
                                            status, NULL, NULL, NULL, descr);
    }
    
    AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status)
    {
        worker_score *ws;
    
        if (!sbh)
            return;
    
        if (sbh->child_num < 0) {
            return;
        }
    
        ws = &ap_scoreboard_image->servers[sbh->child_num][sbh->thread_num];
    
        if (status == START_PREQUEST) {
            ws->start_time = ws->last_used = apr_time_now();
        }
        else if (status == STOP_PREQUEST) {
            ws->stop_time = ws->last_used = apr_time_now();
            if (ap_extended_status) {
                ws->duration += ws->stop_time - ws->start_time;
            }
        }
    }
    
    AP_DECLARE(void) ap_set_time_process_request(ap_sb_handle_t* const sbh,
    		const apr_time_t timebeg,const apr_time_t timeend)
    {
        worker_score *ws;
        if (!sbh || sbh->child_num < 0)
            return;
    
        ws = &ap_scoreboard_image->servers[sbh->child_num][sbh->thread_num];
        
        ws->start_time = timebeg;
        ws->stop_time = ws->last_used = timeend;
        
        if (ap_extended_status)
    	ws->duration += timeend - timebeg;
    }
    
    AP_DECLARE(int) ap_update_global_status(void)
    {
    #ifdef HAVE_TIMES
        if (ap_scoreboard_image == NULL) {
            return APR_SUCCESS;
        }
        times(&ap_scoreboard_image->global->times);
    #endif
        return APR_SUCCESS;
    }
    
    AP_DECLARE(worker_score *) ap_get_scoreboard_worker_from_indexes(int x, int y)
    {
        if (((x < 0) || (x >= server_limit)) ||
            ((y < 0) || (y >= thread_limit))) {
            return(NULL); /* Out of range */
        }
        return &ap_scoreboard_image->servers[x][y];
    }
    
    AP_DECLARE(worker_score *) ap_get_scoreboard_worker(ap_sb_handle_t *sbh)
    {
        if (!sbh)
            return NULL;
    
        return ap_get_scoreboard_worker_from_indexes(sbh->child_num,
                                                     sbh->thread_num);
    }
    
    AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, 
                                               int child_num,
                                               int thread_num)
    {
        worker_score *ws = ap_get_scoreboard_worker_from_indexes(child_num, thread_num);
    
        memcpy(dest, ws, sizeof *ws);
    
        /* For extra safety, NUL-terminate the strings returned, though it
         * should be true those last bytes are always zero anyway. */
        dest->client[sizeof(dest->client) - 1] = '\0';
        dest->client64[sizeof(dest->client64) - 1] = '\0';
        dest->request[sizeof(dest->request) - 1] = '\0';
        dest->vhost[sizeof(dest->vhost) - 1] = '\0';
        dest->protocol[sizeof(dest->protocol) - 1] = '\0';
    }
    
    AP_DECLARE(process_score *) ap_get_scoreboard_process(int x)
    {
        if ((x < 0) || (x >= server_limit)) {
            return(NULL); /* Out of range */
        }
        return &ap_scoreboard_image->parent[x];
    }
    
    AP_DECLARE(global_score *) ap_get_scoreboard_global(void)
    {
        return ap_scoreboard_image->global;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/listen.c������������������������������������������������������������������������0000664�0001751�0001751�00000111367�15020012305�015567� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_version.h"
    
    #include "ap_config.h"
    #include "httpd.h"
    #include "http_main.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "ap_listen.h"
    #include "http_log.h"
    #include "mpm_common.h"
    
    #include <stdlib.h>
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    AP_DECLARE_DATA ap_listen_rec *ap_listeners = NULL;
    
    /* Let ap_num_listen_buckets be global so that it can
     * be printed by ap_log_mpm_common(), but keep the listeners
     * buckets static since it is used only here to close them
     * all (including duplicated) with ap_close_listeners().
     */
    AP_DECLARE_DATA int ap_num_listen_buckets;
    static ap_listen_rec **ap_listen_buckets;
    
    /* Determine once, at runtime, whether or not SO_REUSEPORT
     * is usable on this platform, and hence whether or not
     * listeners can be duplicated (if configured).
     */
    AP_DECLARE_DATA int ap_have_so_reuseport = -1;
    
    static ap_listen_rec *old_listeners;
    static int ap_listenbacklog;
    static int ap_listencbratio;
    static int send_buffer_size;
    static int receive_buffer_size;
    #ifdef HAVE_SYSTEMD
    static int use_systemd = -1;
    #endif
    
    /* 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, int do_bind_listen)
    {
        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, APLOGNO(00067)
                          "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, APLOGNO(00068)
                          "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)",
                          server->bind_addr);
            apr_socket_close(s);
            return stat;
        }
    
        /*
         * 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 <johnh@isi.edu> 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, APLOGNO(00070)
                              "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, APLOGNO(00071)
                              "make_sock: failed to set ReceiveBufferSize for "
                              "address %pI, using default",
                              server->bind_addr);
                /* not a fatal error */
            }
        }
    
    #if APR_TCP_NODELAY_INHERITED
        ap_sock_disable_nagle(s);
    #endif
    
    #if defined(SO_REUSEPORT)
        if (ap_have_so_reuseport && ap_listencbratio > 0) {
            int thesock;
            apr_os_sock_get(&thesock, s);
            if (setsockopt(thesock, SOL_SOCKET, SO_REUSEPORT,
                           (void *)&one, sizeof(int)) < 0) {
                stat = apr_get_netos_error();
                ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02638)
                              "make_sock: for address %pI, apr_socket_opt_set: "
                              "(SO_REUSEPORT)",
                              server->bind_addr);
                apr_socket_close(s);
                return stat;
            }
        }
    #endif
    
        if (do_bind_listen) {
    #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, APLOGNO(00069)
                                  "make_sock: for address %pI, apr_socket_opt_set: "
                                  "(IPV6_V6ONLY)",
                                  server->bind_addr);
                    apr_socket_close(s);
                    return stat;
                }
            }
    #endif
    
            if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
                ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
                              "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, APLOGNO(00073)
                              "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, APLOGNO(00074)
                        "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
                         server->bind_addr);
            apr_socket_close(s);
            return stat;
        }
    #endif
    
        server->sd = s;
        server->active = 1;
    
        server->accept_func = NULL;
    
        return APR_SUCCESS;
    }
    
    static const char* find_accf_name(server_rec *s, const char *proto)
    {
        const char* accf;
        core_server_config *conf = ap_get_core_module_config(s->module_config);
        if (!proto) {
            return NULL;
        }
    
        accf = apr_table_get(conf->accf_map, proto);
    
        if (accf && !strcmp("none", accf)) {
            return NULL;
        }
    
        return accf;
    }
    
    static void ap_apply_accept_filter(apr_pool_t *p, ap_listen_rec *lis,
                                               server_rec *server)
    {
        apr_socket_t *s = lis->sd;
        const char *accf;
        apr_status_t rv;
        const char *proto;
    
        proto = lis->protocol;
    
        if (!proto) {
            proto = ap_get_server_protocol(server);
        }
    
    
        accf = find_accf_name(server, proto);
    
        if (accf) {
    #if APR_HAS_SO_ACCEPTFILTER
            /* In APR 1.x, the 2nd and 3rd parameters are char * instead of 
             * const char *, so make a copy of those args here.
             */
            rv = apr_socket_accept_filter(s, apr_pstrdup(p, accf),
                                          apr_pstrdup(p, ""));
            if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
                ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p, APLOGNO(00075)
                              "Failed to enable the '%s' Accept Filter",
                              accf);
            }
    #else
            rv = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 30);
            if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
                ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p, APLOGNO(00076)
                                  "Failed to enable APR_TCP_DEFER_ACCEPT");
            }
    #endif
        }
    }
    
    static apr_status_t close_listeners_on_exec(void *v)
    {
        ap_close_listeners();
        return APR_SUCCESS;
    }
    
    #ifdef HAVE_SYSTEMD
    
    static apr_status_t alloc_systemd_listener(process_rec * process,
                                               int fd, const char *proto,
                                               ap_listen_rec **out_rec)
    {
        apr_status_t rv;
        struct sockaddr sa;
        socklen_t len = sizeof(struct sockaddr);
        apr_os_sock_info_t si;
        ap_listen_rec *rec;
        *out_rec = NULL;
    
        memset(&si, 0, sizeof(si));
    
        rv = getsockname(fd, &sa, &len);
    
        if (rv != 0) {
            rv = apr_get_netos_error();
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489)
                          "getsockname on %d failed.", fd);
            return rv;
        }
    
        si.os_sock = &fd;
        si.family = sa.sa_family;
        si.local = &sa;
        si.type = SOCK_STREAM;
        si.protocol = APR_PROTO_TCP;
    
        rec = apr_pcalloc(process->pool, sizeof(ap_listen_rec));
    
    
        rv = apr_os_sock_make(&rec->sd, &si, process->pool);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490)
                          "apr_os_sock_make on %d failed.", fd);
            return rv;
        }
    
        rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd);
        if (rv != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491)
                          "apr_socket_addr_get on %d failed.", fd);
            return rv;
        }
    
        rec->protocol = apr_pstrdup(process->pool, proto);
    
        *out_rec = rec;
    
        return make_sock(process->pool, rec, 0);
    }
    
    static const char *set_systemd_listener(process_rec *process, apr_port_t port,
                                            const char *proto)
    {
        ap_listen_rec *last, *new;
        apr_status_t rv;
        APR_OPTIONAL_FN_TYPE(ap_find_systemd_socket) *find_systemd_socket;
        int fd;
    
        find_systemd_socket = APR_RETRIEVE_OPTIONAL_FN(ap_find_systemd_socket);
    
        if (!find_systemd_socket)
           return "Systemd socket activation is used, but mod_systemd is probably "
                   "not loaded";
    
        fd = find_systemd_socket(process, port);
        if (fd < 0) {
            return "Systemd socket activation is used, but this port is not "
                    "configured in systemd";
        }
    
        last = ap_listeners;
        while (last && last->next) {
            last = last->next;
        }
    
        rv = alloc_systemd_listener(process, fd, proto, &new);
        if (rv != APR_SUCCESS) {
            return "Failed to setup socket passed by systemd using socket activation";
        }
    
        if (last == NULL) {
            ap_listeners = new;
        }
        else {
            last->next = new;
        }
    
        return NULL;
    }
    #endif /* HAVE_SYSTEMD */
    
    /* Returns non-zero if socket address SA matches hostname, port and
     * scope_id.  p is used for temporary allocations. */
    static int match_address(const apr_sockaddr_t *sa,
                             const char *hostname, apr_port_t port,
                             const char *scope_id, apr_pool_t *p)
    {
        const char *old_scope = NULL;
    
    #if APR_VERSION_AT_LEAST(1,7,0)
        /* To be clever here we could correctly match numeric and
         * non-numeric zone ids.  Ignore failure, old_scope will be left
         * as NULL. */
        (void) apr_sockaddr_zone_get(sa, &old_scope, NULL, p);
    #endif
        
        return port == sa->port
            && ((!hostname && !sa->hostname)
                || (hostname && sa->hostname && !strcmp(sa->hostname, hostname)))
            && ((!scope_id && !old_scope)
                || (scope_id && old_scope && !strcmp(scope_id, old_scope)));            
    }
    
    /* ### This logic doesn't cope with DNS changes across a restart. */
    static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
                              const char *addr, apr_port_t port,
                              const char *scope_id, apr_pool_t *temp_pool)
    {
        int found = 0;
    
        while (*from) {
            apr_sockaddr_t *sa = (*from)->bind_addr;
    
            /* Some listeners are not real so they will not have a bind_addr. */
            if (sa) {
                ap_listen_rec *new;
    
                /* Re-use the existing record if it matches completely
                 * against an existing listener. */
                if (match_address(sa, addr, port, scope_id, temp_pool)) {
                    found = 1;
                    if (!to) {
                        break;
                    }
                    new = *from;
                    *from = new->next;
                    new->next = *to;
                    *to = new;
                    continue;
                }
            }
    
            from = &(*from)->next;
        }
    
        return found;
    }
    
    static const char *alloc_listener(process_rec *process, const char *addr,
                                      apr_port_t port, const char* proto,
                                      const char *scope_id, void *slave,
                                      apr_pool_t *temp_pool)
    {
        ap_listen_rec *last;
        apr_status_t status;
        apr_sockaddr_t *sa;
    
        /* see if we've got a listener for this address:port, which is an error */
        if (find_listeners(&ap_listeners, NULL, addr, port, scope_id, temp_pool)) {
            return "Cannot define multiple Listeners on the same IP:port";
        }
    
        /* see if we've got an old listener for this address:port */
        if (find_listeners(&old_listeners, &ap_listeners, addr, port,
                           scope_id, temp_pool)) {
            if (ap_listeners->slave != slave) {
                return "Cannot define a slave on the same IP:port as a 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, APLOGNO(00077)
                          "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;
            new->protocol = apr_pstrdup(process->pool, proto);
    
            /* 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, APLOGNO(00078)
                              "alloc_listener: failed to get a socket for %s",
                              addr);
                return "Listen setup failed";
            }
    
    #if APR_VERSION_AT_LEAST(1,7,0)
            if (scope_id) {
                status = apr_sockaddr_zone_set(new->bind_addr, scope_id);
                if (status) {
                    ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, APLOGNO(10102)
                                  "alloc_listener: failed to set scope for %pI to %s",
                                  new->bind_addr, scope_id);
                    return "Listen step failed";
                }
            }
    #endif
    
            /* We need to preserve the order returned by getaddrinfo() */
            if (last == NULL) {
                ap_listeners = last = new;
            } else {
                last->next = new;
                last = new;
            }
            new->slave = slave;
        }
    
        return NULL;
    }
    /* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
     * IPv4 match-any-address, 0.0.0.0. */
    #define IS_INADDR_ANY(addr) ((addr)->family == APR_INET \
                                 && (addr)->sa.sin.sin_addr.s_addr == INADDR_ANY)
    
    /* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
     * IPv6 match-any-address, [::]. */
    #define IS_IN6ADDR_ANY(addr) ((addr)->family == APR_INET6 \
                                  && IN6_IS_ADDR_UNSPECIFIED(&(addr)->sa.sin6.sin6_addr))
    
    /**
     * 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;
    #if AP_NONBLOCK_WHEN_MULTI_LISTEN
        int use_nonblock;
    #endif
    
        /* 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
                ap_listen_rec *cur;
                int v6only_setting;
                int skip = 0;
    
                /* If we have the unspecified IPv4 address (0.0.0.0) and
                 * the unspecified IPv6 address (::) is next, we need to
                 * swap the order of these in the list. We always try to
                 * bind to IPv6 first, then IPv4, since an IPv6 socket
                 * might be able to receive IPv4 packets if V6ONLY is not
                 * enabled, but never the other way around.
                 * Note: In some configurations, the unspecified IPv6 address
                 * could be even later in the list.  This logic only corrects
                 * the situation where it is next in the list, such as when
                 * apr_sockaddr_info_get() returns an IPv4 and an IPv6 address,
                 * in that order.
                 */
                if (lr->next != NULL
                    && IS_INADDR_ANY(lr->bind_addr)
                    && lr->bind_addr->port == lr->next->bind_addr->port
                    && IS_IN6ADDR_ANY(lr->next->bind_addr)) {
                    /* Exchange lr and lr->next */
                    next = lr->next;
                    lr->next = next->next;
                    next->next = lr;
                    if (previous) {
                        previous->next = next;
                    }
                    else {
                        ap_listeners = next;
                    }
                    lr = next;
                }
    
                /* If we are trying to bind to 0.0.0.0 and a 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 (IS_INADDR_ANY(lr->bind_addr) && previous) {
                    for (cur = ap_listeners; cur != lr; cur = cur->next) {
                        if (lr->bind_addr->port == cur->bind_addr->port
                            && IS_IN6ADDR_ANY(cur->bind_addr)
                            && apr_socket_opt_get(cur->sd, APR_IPV6_V6ONLY,
                                                  &v6only_setting) == APR_SUCCESS
                            && v6only_setting == 0) {
    
                            /* Remove the current listener from the list */
                            previous->next = lr->next;
                            lr = previous; /* maintain current value of previous after
                                            * post-loop expression is evaluated
                                            */
                            skip = 1;
                            break;
                        }
                    }
                    if (skip) {
                        continue;
                    }
                }
    #endif
                if (make_sock(pool, lr, 1) == APR_SUCCESS) {
                    ++num_open;
                }
                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
                        && IS_IN6ADDR_ANY(lr->bind_addr)
                        && lr->bind_addr->port == lr->next->bind_addr->port
                        && IS_INADDR_ANY(lr->next->bind_addr)) {
    
                        /* 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 */
        ap_close_listeners_ex(old_listeners);
        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
         */
        use_nonblock = (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, use_nonblock);
            if (status != APR_SUCCESS) {
                ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, status, pool, APLOGNO(00079)
                              "unable to control socket non-blocking status");
                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)
    {
        server_rec *ls;
        server_addr_rec *addr;
        ap_listen_rec *lr;
        int num_listeners = 0;
        const char* proto;
        int found;
    #ifdef HAVE_SYSTEMD
        APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
    #endif
    
        for (ls = s; ls; ls = ls->next) {
            proto = ap_get_server_protocol(ls);
            if (!proto) {
                found = 0;
                /* No protocol was set for this vhost,
                 * use the default for this listener.
                 */
                for (addr = ls->addrs; addr && !found; addr = addr->next) {
                    for (lr = ap_listeners; lr; lr = lr->next) {
                        if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
                            lr->bind_addr->port == addr->host_port) {
                            ap_set_server_protocol(ls, lr->protocol);
                            found = 1;
                            break;
                        }
                    }
                }
    
                if (!found) {
                    /* TODO: set protocol defaults per-Port, eg 25=smtp */
                    ap_set_server_protocol(ls, "http");
                }
            }
        }
    
    
    #ifdef HAVE_SYSTEMD
        if (use_systemd) {
            const char *userdata_key = "ap_open_systemd_listeners";
            void *data;
            /* clear the enviroment on our second run
            * so that none of our future children get confused.
            */
            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);
            }
            else {
                systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
                if (systemd_listen_fds != NULL) {
                    systemd_listen_fds(1);
                }
            }        
        }
        else
    #endif
        {
            if (open_listeners(s->process->pool)) {
                return 0;
            }
        }
    
        for (lr = ap_listeners; lr; lr = lr->next) {
            num_listeners++;
            found = 0;
            for (ls = s; ls && !found; ls = ls->next) {
                for (addr = ls->addrs; addr && !found; addr = addr->next) {
                    if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
                        lr->bind_addr->port == addr->host_port) {
                        found = 1;
                        ap_apply_accept_filter(s->process->pool, lr, ls);
                    }
                }
            }
    
            if (!found) {
                ap_apply_accept_filter(s->process->pool, lr, s);
            }
        }
    
        return num_listeners;
    }
    
    AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
                                                    ap_listen_rec ***buckets,
                                                    int *num_buckets)
    {
        static int warn_once;
        int i;
        apr_status_t stat;
        int use_nonblock = 0;
        ap_listen_rec *lr;
    
        if (*num_buckets < 1) {
            *num_buckets = 1;
            if (ap_listencbratio > 0) {
    #ifdef _SC_NPROCESSORS_ONLN
                if (ap_have_so_reuseport) {
                    int num_online_cores = sysconf(_SC_NPROCESSORS_ONLN),
                        val = num_online_cores / ap_listencbratio;
                    if (val > 1) {
                        *num_buckets = val;
                    }
                    ap_log_perror(APLOG_MARK, APLOG_INFO, 0, p, APLOGNO(02819)
                                  "Using %i listeners bucket(s) based on %i "
                                  "online CPU cores and a ratio of %i",
                                  *num_buckets, num_online_cores,
                                  ap_listencbratio);
                }
                else
    #endif
                if (!warn_once) {
                    ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p, APLOGNO(02820)
                                  "ListenCoresBucketsRatio ignored without "
                                  "SO_REUSEPORT and _SC_NPROCESSORS_ONLN "
                                  "support: using a single listeners bucket");
                    warn_once = 1;
                }
            }
        }
    
        *buckets = apr_pcalloc(p, *num_buckets * sizeof(ap_listen_rec *));
        (*buckets)[0] = ap_listeners;
    
        for (i = 1; i < *num_buckets; i++) {
            ap_listen_rec *last = NULL;
            lr = ap_listeners;
            while (lr) {
                ap_listen_rec *duplr;
                char *hostname;
                apr_port_t port;
                apr_sockaddr_t *sa;
    #ifdef HAVE_SYSTEMD
                if (use_systemd) {
                    int thesock;
                    apr_os_sock_get(&thesock, lr->sd);
                    if ((stat = alloc_systemd_listener(s->process, thesock,
                        lr->protocol, &duplr)) != APR_SUCCESS) {
                        return stat;
                    }
                }
                else
    #endif
                {
                    duplr  = apr_palloc(p, sizeof(ap_listen_rec));
                    duplr->slave = NULL;
                    duplr->protocol = apr_pstrdup(p, lr->protocol);
                    hostname = apr_pstrdup(p, lr->bind_addr->hostname);
                    port = lr->bind_addr->port;
                    apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, p);
                    duplr->bind_addr = sa;
                    duplr->next = NULL;
                    if ((stat = apr_socket_create(&duplr->sd, duplr->bind_addr->family,
                                                SOCK_STREAM, 0, p)) != APR_SUCCESS) {
                        ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, p, APLOGNO(02640)
                                    "ap_duplicate_socket: for address %pI, "
                                    "cannot duplicate a new socket!",
                                    duplr->bind_addr);
                        return stat;
                    }
                    make_sock(p, duplr, 1);
                }
    #if AP_NONBLOCK_WHEN_MULTI_LISTEN
                use_nonblock = (ap_listeners && ap_listeners->next);
                stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock);
                if (stat != APR_SUCCESS) {
                    ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02641)
                                  "unable to control socket non-blocking status");
                    return stat;
                }
    #endif
                ap_apply_accept_filter(p, duplr, s);
    
                if (last == NULL) {
                    (*buckets)[i] = last = duplr;
                }
                else {
                    last->next = duplr;
                    last = duplr;
                }
                lr = lr->next;
            }
        }
    
        ap_listen_buckets = *buckets;
        ap_num_listen_buckets = *num_buckets;
        return APR_SUCCESS;
    }
    
    AP_DECLARE_NONSTD(void) ap_close_listeners(void)
    {
        int i;
    
        ap_close_listeners_ex(ap_listeners);
    
        /* Start from index 1 since either ap_duplicate_listeners()
         * was called and ap_listen_buckets[0] == ap_listeners, or
         * it wasn't and ap_num_listen_buckets == 0.
         */
        for (i = 1; i < ap_num_listen_buckets; i++) {
            ap_close_listeners_ex(ap_listen_buckets[i]);
        }
    }
    
    AP_DECLARE_NONSTD(void) ap_close_listeners_ex(ap_listen_rec *listeners)
    {
        ap_listen_rec *lr;
        for (lr = listeners; lr; lr = lr->next) {
            apr_socket_close(lr->sd);
            lr->active = 0;
        }
    }
    
    AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *slave)
    {
        ap_listen_rec *lr;
        int n = 0;
    
        for (lr = ap_listeners; lr; lr = lr->next) {
            if (lr->slave != slave) {
                apr_socket_close(lr->sd);
                lr->active = 0;
            }
            else {
                ++n;
            }
        }
        return n;
    }
    
    AP_DECLARE(void) ap_listen_pre_config(void)
    {
        old_listeners = ap_listeners;
        ap_listeners = NULL;
        ap_listen_buckets = NULL;
        ap_num_listen_buckets = 0;
        ap_listenbacklog = DEFAULT_LISTENBACKLOG;
        ap_listencbratio = 0;
    
        /* Check once whether or not SO_REUSEPORT is supported. */
        if (ap_have_so_reuseport < 0) {
            /* This is limited to Linux with defined SO_REUSEPORT (ie. 3.9+) for
             * now since the implementation evenly distributes connections across
             * all the listening threads/processes.
             *
             * *BSDs have SO_REUSEPORT too but with a different semantic: the first
             * wildcard address bound socket or the last non-wildcard address bound
             * socket will receive connections (no evenness guarantee); the rest of
             * the sockets bound to the same port will not.
             * This can't (always) work for httpd.
             *
             * TODO: latests DragonFlyBSD's SO_REUSEPORT (seems to?) have the same
             * semantic as Linux, so we may need HAVE_SO_REUSEPORT available from
             * configure.in some day.
             */
    #if defined(SO_REUSEPORT) && defined(__linux__)
            apr_socket_t *sock;
            if (apr_socket_create(&sock, APR_UNSPEC, SOCK_STREAM, 0,
                                  ap_pglobal) == APR_SUCCESS) {
                int thesock, on = 1;
                apr_os_sock_get(&thesock, sock);
                ap_have_so_reuseport = (setsockopt(thesock, SOL_SOCKET,
                                                   SO_REUSEPORT, (void *)&on,
                                                   sizeof(int)) == 0);
                apr_socket_close(sock);
            }
            else
    #endif
            ap_have_so_reuseport = 0;
    
        }
    }
    
    AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
                                                    int argc, char *const argv[])
    {
        char *host, *scope_id, *proto;
        apr_port_t port;
        apr_status_t rv;
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    #ifdef HAVE_SYSTEMD
        APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
    #endif
    
        if (err != NULL) {
            return err;
        }
    
        if (argc < 1 || argc > 2) {
            return "Listen requires 1 or 2 arguments.";
        }
    #ifdef HAVE_SYSTEMD
        if (use_systemd == -1) {
            systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
            if (systemd_listen_fds != NULL) {
                use_systemd = systemd_listen_fds(0) > 0;
            } else {
                use_systemd = 0;
            }
        }
    #endif
    
        rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
        if (rv != APR_SUCCESS) {
            return "Invalid address or port";
        }
    
        if (host && !strcmp(host, "*")) {
            host = NULL;
        }
    
    #if !APR_VERSION_AT_LEAST(1,7,0)
        if (scope_id) {
            return apr_pstrcat(cmd->pool,
                               "Scope ID in address '", argv[0],
                               "' not supported with APR " APR_VERSION_STRING,
                               NULL);
        }
    #endif
    
        if (!port) {
            return "Port must be specified";
        }
    
        if (argc != 2) {
            if (port == 443) {
                proto = "https";
            } else {
                proto = "http";
            }
        }
        else {
            proto = apr_pstrdup(cmd->pool, argv[1]);
            ap_str_tolower(proto);
        }
    
    #ifdef HAVE_SYSTEMD
        if (use_systemd) {
            return set_systemd_listener(cmd->server->process, port, proto);
        }
    #endif
    
        return alloc_listener(cmd->server->process, host, port, proto,
                              scope_id, NULL, cmd->temp_pool);
    }
    
    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_listencbratio(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 "ListenCoresBucketsRatio must be > 0";
        }
    
        ap_listencbratio = 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;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_mutex.c��������������������������������������������������������������������0000664�0001751�0001751�00000040366�13262704500�016503� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_mutex.c: Useful functions for determining allowable
     *               mutexes and mutex settings
     */
    
    
    #include "apr.h"
    #include "apr_hash.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_main.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "http_log.h"
    #include "util_mutex.h"
    #if AP_NEED_SET_MUTEX_PERMS
    #include "unixd.h"
    #endif
    #ifdef HAVE_UNISTD_H
    #include <unistd.h> /* getpid() */
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool,
                                            apr_lockmech_e *mutexmech,
                                            const char **mutexfile)
    {
        /* Split arg into meth and file */
        char *meth = apr_pstrdup(pool, arg);
        char *file = strchr(meth, ':');
        if (file) {
            *(file++) = '\0';
            if (!*file) {
                file = NULL;
            }
        }
    
        /* APR determines temporary filename unless overridden below,
         * we presume file indicates an mutexfile is a file path
         * unless the method sets mutexfile=file and NULLs file
         */
        *mutexfile = NULL;
    
        if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) {
            return APR_ENOLOCK;
        }
    
        /* NOTE: previously, 'yes' implied 'sem' */
        if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) {
            *mutexmech = APR_LOCK_DEFAULT;
        }
    #if APR_HAS_FCNTL_SERIALIZE
        else if (!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) {
            *mutexmech = APR_LOCK_FCNTL;
        }
    #endif
    #if APR_HAS_FLOCK_SERIALIZE
        else if (!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) {
            *mutexmech = APR_LOCK_FLOCK;
        }
    #endif
    #if APR_HAS_POSIXSEM_SERIALIZE
        else if (!strcasecmp(meth, "posixsem") || !strcasecmp(meth, "sem")) {
            *mutexmech = 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) {
                *mutexfile = apr_pstrdup(pool, file);
    
                file = NULL;
            }
        }
    #endif
    #if APR_HAS_SYSVSEM_SERIALIZE
        else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) {
            *mutexmech = APR_LOCK_SYSVSEM;
        }
    #endif
    #if APR_HAS_PROC_PTHREAD_SERIALIZE
        else if (!strcasecmp(meth, "pthread")) {
            *mutexmech = APR_LOCK_PROC_PTHREAD;
        }
    #endif
        else {
            return APR_ENOTIMPL;
        }
    
        /* Unless the method above assumed responsibility for setting up
         * mutexfile and NULLing out file, presume it is a file we
         * are looking to use
         */
        if (file) {
            *mutexfile = ap_server_root_relative(pool, file);
            if (!*mutexfile) {
                return APR_BADARG;
            }
        }
    
        return APR_SUCCESS;
    }
    
    typedef struct {
        apr_int32_t options;
        int set;
        int none;
        int omit_pid;
        apr_lockmech_e mech;
        const char *dir;
    } mutex_cfg_t;
    
    /* hash is created the first time a module calls ap_mutex_register(),
     * rather than attempting to be the REALLY_REALLY_FIRST pre-config
     * hook; it is cleaned up when the associated pool goes away; assume
     * pconf is the pool passed to ap_mutex_register()
     */
    static apr_hash_t *mxcfg_by_type;
    
    AP_DECLARE_NONSTD(void) ap_mutex_init(apr_pool_t *p)
    {
        mutex_cfg_t *def;
    
        if (mxcfg_by_type) {
            return;
        }
    
        mxcfg_by_type = apr_hash_make(p);
        apr_pool_cleanup_register(p, &mxcfg_by_type, ap_pool_cleanup_set_null,
            apr_pool_cleanup_null);
    
        /* initialize default mutex configuration */
        def = apr_pcalloc(p, sizeof *def);
        def->mech = APR_LOCK_DEFAULT;
        def->dir = ap_runtime_dir_relative(p, "");
        apr_hash_set(mxcfg_by_type, "default", APR_HASH_KEY_STRING, def);
    }
    
    AP_DECLARE_NONSTD(const char *)ap_set_mutex(cmd_parms *cmd, void *dummy,
                                                const char *arg)
    {
        apr_pool_t *p = cmd->pool;
        apr_pool_t *ptemp = cmd->temp_pool;
        const char **elt;
        const char *mechdir;
        int no_mutex = 0, omit_pid = 0;
        apr_array_header_t *type_list;
        apr_lockmech_e mech;
        apr_status_t rv;
        const char *mutexdir;
        mutex_cfg_t *mxcfg;
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    
        if (err != NULL) {
            return err;
        }
    
        mechdir = ap_getword_conf(cmd->pool, &arg);
        if (*mechdir == '\0') {
            return "Mutex requires at least a mechanism argument ("
                   AP_ALL_AVAILABLE_MUTEXES_STRING ")";
        }
    
        rv = ap_parse_mutex(mechdir, p, &mech, &mutexdir);
        if (rv == APR_ENOTIMPL) {
            return apr_pstrcat(p, "Invalid Mutex argument ", mechdir,
                               " (" AP_ALL_AVAILABLE_MUTEXES_STRING ")", NULL);
        }
        else if (rv == APR_BADARG
                 || (mutexdir && !ap_is_directory(ptemp, mutexdir))) {
            return apr_pstrcat(p, "Invalid Mutex directory in argument ",
                               mechdir, NULL);
        }
        else if (rv == APR_ENOLOCK) { /* "none" */
            no_mutex = 1;
        }
    
        /* "OmitPID" can appear at the end of the list, so build a list of
         * mutex type names while looking for "OmitPID" (anywhere) or the end
         */
        type_list = apr_array_make(cmd->pool, 4, sizeof(const char *));
        while (*arg) {
            const char *s = ap_getword_conf(cmd->pool, &arg);
    
            if (!strcasecmp(s, "omitpid")) {
                omit_pid = 1;
            }
            else {
                const char **new_type = (const char **)apr_array_push(type_list);
                *new_type = s;
            }
        }
    
        if (apr_is_empty_array(type_list)) { /* no mutex type?  assume "default" */
            const char **new_type = (const char **)apr_array_push(type_list);
            *new_type = "default";
        }
    
        while ((elt = (const char **)apr_array_pop(type_list)) != NULL) {
            const char *type = *elt;
            mxcfg = apr_hash_get(mxcfg_by_type, type, APR_HASH_KEY_STRING);
            if (!mxcfg) {
                return apr_psprintf(p, "Mutex type %s is not valid", type);
            }
    
            mxcfg->none = 0; /* in case that was the default */
            mxcfg->omit_pid = omit_pid;
    
            mxcfg->set = 1;
            if (no_mutex) {
                if (!(mxcfg->options & AP_MUTEX_ALLOW_NONE)) {
                    return apr_psprintf(p,
                                        "None is not allowed for mutex type %s",
                                        type);
                }
                mxcfg->none = 1;
            }
            else {
                mxcfg->mech = mech;
                if (mutexdir) { /* retain mutex default if not configured */
                    mxcfg->dir = mutexdir;
                }
            }
        }
    
        return NULL;
    }
    
    AP_DECLARE(apr_status_t) ap_mutex_register(apr_pool_t *pconf,
                                               const char *type,
                                               const char *default_dir,
                                               apr_lockmech_e default_mech,
                                               apr_int32_t options)
    {
        mutex_cfg_t *mxcfg = apr_pcalloc(pconf, sizeof *mxcfg);
    
        if ((options & ~(AP_MUTEX_ALLOW_NONE | AP_MUTEX_DEFAULT_NONE))) {
            return APR_EINVAL;
        }
    
        ap_mutex_init(pconf); /* in case this mod's pre-config ran before core's */
    
        mxcfg->options = options;
        if (options & AP_MUTEX_DEFAULT_NONE) {
            mxcfg->none = 1;
        }
        mxcfg->dir = default_dir; /* usually NULL */
        mxcfg->mech = default_mech; /* usually APR_LOCK_DEFAULT */
        apr_hash_set(mxcfg_by_type, type, APR_HASH_KEY_STRING, mxcfg);
    
        return APR_SUCCESS;
    }
    
    static int mutex_needs_file(apr_lockmech_e mech)
    {
        if (mech != APR_LOCK_FLOCK
            && mech != APR_LOCK_FCNTL
    #if APR_USE_FLOCK_SERIALIZE || APR_USE_FCNTL_SERIALIZE
            && mech != APR_LOCK_DEFAULT
    #endif
            ) {
            return 0;
        }
        return 1;
    }
    
    static const char *get_mutex_filename(apr_pool_t *p, mutex_cfg_t *mxcfg,
                                          const char *type,
                                          const char *instance_id)
    {
        const char *pid_suffix = "";
    
        if (!mutex_needs_file(mxcfg->mech)) {
            return NULL;
        }
    
    #if HAVE_UNISTD_H
        if (!mxcfg->omit_pid) {
            pid_suffix = apr_psprintf(p, ".%" APR_PID_T_FMT, getpid());
        }
    #endif
    
        return ap_server_root_relative(p,
                                       apr_pstrcat(p,
                                                   mxcfg->dir,
                                                   "/",
                                                   type,
                                                   instance_id ? "-" : "",
                                                   instance_id ? instance_id : "",
                                                   pid_suffix,
                                                   NULL));
    }
    
    static mutex_cfg_t *mxcfg_lookup(apr_pool_t *p, const char *type)
    {
        mutex_cfg_t *defcfg, *mxcfg, *newcfg;
    
        defcfg = apr_hash_get(mxcfg_by_type, "default", APR_HASH_KEY_STRING);
    
        /* MUST exist in table, or wasn't registered */
        mxcfg = apr_hash_get(mxcfg_by_type, type, APR_HASH_KEY_STRING);
        if (!mxcfg) {
            return NULL;
        }
    
        /* order of precedence:
         * 1. Mutex directive for this mutex
         * 2. Mutex directive for "default"
         * 3. Defaults for this mutex from ap_mutex_register()
         * 4. Global defaults
         */
    
        if (mxcfg->set) {
            newcfg = mxcfg;
        }
        else if (defcfg->set) {
            newcfg = defcfg;
        }
        else if (mxcfg->none || mxcfg->mech != APR_LOCK_DEFAULT) {
            newcfg = mxcfg;
        }
        else {
            newcfg = defcfg;
        }
    
        if (!newcfg->none && mutex_needs_file(newcfg->mech) && !newcfg->dir) {
            /* a file-based mutex mechanism was configured, but
             * without a mutex file directory; go back through
             * the chain to find the directory, store in new
             * mutex cfg structure
             */
            newcfg = apr_pmemdup(p, newcfg, sizeof *newcfg);
    
            /* !true if dir not already set: mxcfg->set && defcfg->dir */
            if (defcfg->set && defcfg->dir) {
                newcfg->dir = defcfg->dir;
            }
            else if (mxcfg->dir) {
                newcfg->dir = mxcfg->dir;
            }
            else {
                newcfg->dir = defcfg->dir;
            }
        }
    
        return newcfg;
    }
    
    static void log_bad_create_options(server_rec *s, const char *type)
    {
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(00021)
                     "Invalid options were specified when creating the %s mutex",
                     type);
    }
    
    static void log_unknown_type(server_rec *s, const char *type)
    {
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(00022)
                     "Can't create mutex of unknown type %s", type);
    }
    
    static void log_create_failure(apr_status_t rv, server_rec *s, const char *type,
                                   const char *fname)
    {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(00023)
                     "Couldn't create the %s mutex %s%s%s", type,
                     fname ? "(file " : "",
                     fname ? fname : "",
                     fname ? ")" : "");
    }
    
    #ifdef AP_NEED_SET_MUTEX_PERMS
    static void log_perms_failure(apr_status_t rv, server_rec *s, const char *type)
    {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(00024)
                     "Couldn't set permissions on the %s mutex; "
                     "check User and Group directives",
                     type);
    }
    #endif
    
    AP_DECLARE(apr_status_t) ap_global_mutex_create(apr_global_mutex_t **mutex,
                                                    const char **name,
                                                    const char *type,
                                                    const char *instance_id,
                                                    server_rec *s, apr_pool_t *p,
                                                    apr_int32_t options)
    {
        apr_status_t rv;
        const char *fname;
        mutex_cfg_t *mxcfg = mxcfg_lookup(p, type);
    
        if (options) {
            log_bad_create_options(s, type);
            return APR_EINVAL;
        }
    
        if (!mxcfg) {
            log_unknown_type(s, type);
            return APR_EINVAL;
        }
    
        if (mxcfg->none) {
            *mutex = NULL;
            return APR_SUCCESS;
        }
    
        fname = get_mutex_filename(p, mxcfg, type, instance_id);
    
        rv = apr_global_mutex_create(mutex, fname, mxcfg->mech, p);
        if (rv != APR_SUCCESS) {
            log_create_failure(rv, s, type, fname);
            return rv;
        }
    
        if (name)
            *name = fname;
    
    #ifdef AP_NEED_SET_MUTEX_PERMS
        rv = ap_unixd_set_global_mutex_perms(*mutex);
        if (rv != APR_SUCCESS) {
            log_perms_failure(rv, s, type);
        }
    #endif
    
        return rv;
    }
    
    AP_DECLARE(apr_status_t) ap_proc_mutex_create(apr_proc_mutex_t **mutex,
                                                  const char **name,
                                                  const char *type,
                                                  const char *instance_id,
                                                  server_rec *s, apr_pool_t *p,
                                                  apr_int32_t options)
    {
        apr_status_t rv;
        const char *fname;
        mutex_cfg_t *mxcfg = mxcfg_lookup(p, type);
    
        if (options) {
            log_bad_create_options(s, type);
            return APR_EINVAL;
        }
    
        if (!mxcfg) {
            log_unknown_type(s, type);
            return APR_EINVAL;
        }
    
        if (mxcfg->none) {
            *mutex = NULL;
            return APR_SUCCESS;
        }
    
        fname = get_mutex_filename(p, mxcfg, type, instance_id);
    
        rv = apr_proc_mutex_create(mutex, fname, mxcfg->mech, p);
        if (rv != APR_SUCCESS) {
            log_create_failure(rv, s, type, fname);
            return rv;
        }
    
        if (name)
            *name = fname;
    
    #ifdef AP_NEED_SET_MUTEX_PERMS
        rv = ap_unixd_set_proc_mutex_perms(*mutex);
        if (rv != APR_SUCCESS) {
            log_perms_failure(rv, s, type);
        }
    #endif
    
        return rv;
    }
    
    AP_CORE_DECLARE(void) ap_dump_mutexes(apr_pool_t *p, server_rec *s, apr_file_t *out)
    {
        apr_hash_index_t *idx;
        mutex_cfg_t *defcfg = apr_hash_get(mxcfg_by_type, "default", APR_HASH_KEY_STRING);
        for (idx = apr_hash_first(p, mxcfg_by_type); idx; idx = apr_hash_next(idx))
        {
            mutex_cfg_t *mxcfg;
            const char *name, *mech = "<unknown>";
            const void *name_;
            const char *dir = "";
            apr_hash_this(idx, &name_, NULL, NULL);
            name = name_;
            mxcfg = mxcfg_lookup(p, name);
            if (mxcfg == defcfg && strcmp(name, "default") != 0) {
                apr_file_printf(out, "Mutex %s: using_defaults\n", name);
                continue;
            }
            if (mxcfg->none) {
                apr_file_printf(out, "Mutex %s: none\n", name);
                continue;
            }
            switch (mxcfg->mech) {
            case APR_LOCK_DEFAULT:
                mech = "default";
                break;
    #if APR_HAS_FCNTL_SERIALIZE
            case APR_LOCK_FCNTL:
                mech = "fcntl";
                break;
    #endif
    #if APR_HAS_FLOCK_SERIALIZE
            case APR_LOCK_FLOCK:
                mech = "flock";
                break;
    #endif
    #if APR_HAS_POSIXSEM_SERIALIZE
            case APR_LOCK_POSIXSEM:
                mech = "posixsem";
                break;
    #endif
    #if APR_HAS_SYSVSEM_SERIALIZE
            case APR_LOCK_SYSVSEM:
                mech = "sysvsem";
                break;
    #endif
    #if APR_HAS_PROC_PTHREAD_SERIALIZE
            case APR_LOCK_PROC_PTHREAD:
                mech = "pthread";
                break;
    #endif
            default:
                ap_assert(0);
            }
    
            if (mxcfg->dir)
                dir = ap_server_root_relative(p, mxcfg->dir);
    
            apr_file_printf(out, "Mutex %s: dir=\"%s\" mechanism=%s %s\n", name, dir, mech,
                            mxcfg->omit_pid ? "[OmitPid]" : "");
        }
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_expr_eval.c����������������������������������������������������������������0000664�0001751�0001751�00000161713�15032733516�017334� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*                      _             _
     *  ap_expr_eval.c, based on ssl_expr_eval.c from mod_ssl
     */
    
    #include "httpd.h"
    #include "http_log.h"
    #include "http_core.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "http_ssl.h"
    #include "ap_provider.h"
    #include "util_expr_private.h"
    #include "util_md5.h"
    
    #include "apr_lib.h"
    #include "apr_fnmatch.h"
    #include "apr_base64.h"
    #include "apr_sha1.h"
    #include "apr_version.h"
    #if APR_VERSION_AT_LEAST(1,5,0)
    #include "apr_escape.h"
    #endif
    
    #include <limits.h>     /* for INT_MAX */
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(expr_lookup)
    )
    
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, expr_lookup, (ap_expr_lookup_parms *parms),
                                (parms), DECLINED)
    
    #define  LOG_MARK(info)  __FILE__, __LINE__, (info)->module_index
    
    static const char *ap_expr_eval_string_func(ap_expr_eval_ctx_t *ctx,
                                                const ap_expr_t *info,
                                                const ap_expr_t *args);
    static const char *ap_expr_eval_re_backref(ap_expr_eval_ctx_t *ctx,
                                               unsigned int n);
    static const char *ap_expr_eval_var(ap_expr_eval_ctx_t *ctx,
                                        ap_expr_var_func_t *func,
                                        const void *data);
    
    /* define AP_EXPR_DEBUG to log the parse tree when parsing an expression */
    #ifdef AP_EXPR_DEBUG
    static void expr_dump_tree(const ap_expr_t *e, const server_rec *s,
                               int loglevel, int indent);
    #endif
    
    /*
     * To reduce counting overhead, we only count calls to
     * ap_expr_eval_word() and ap_expr_eval(). The max number of
     * stack frames is larger by some factor.
     */
    #define AP_EXPR_MAX_RECURSION   20
    static int inc_rec(ap_expr_eval_ctx_t *ctx)
    {
        if (ctx->reclvl < AP_EXPR_MAX_RECURSION) {
            ctx->reclvl++;
            return 0;
        }
        *ctx->err = "Recursion limit reached";
        /* short circuit further evaluation */
        ctx->reclvl = INT_MAX;
        return 1;
    }
    
    static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx,
                                         const ap_expr_t *node)
    {
        const char *result = "";
        if (inc_rec(ctx))
            return result;
        switch (node->node_op) {
        case op_Digit:
        case op_String:
            result = node->node_arg1;
            break;
        case op_Var:
            result = ap_expr_eval_var(ctx, (ap_expr_var_func_t *)node->node_arg1,
                                      node->node_arg2);
            break;
        case op_Concat:
            if (((ap_expr_t *)node->node_arg2)->node_op != op_Concat &&
                ((ap_expr_t *)node->node_arg1)->node_op != op_Concat) {
                const char *s1 = ap_expr_eval_word(ctx, node->node_arg1);
                const char *s2 = ap_expr_eval_word(ctx, node->node_arg2);
                if (!*s1)
                    result = s2;
                else if (!*s2)
                    result = s1;
                else
                    result = apr_pstrcat(ctx->p, s1, s2, NULL);
            }
            else if (((ap_expr_t *)node->node_arg1)->node_op == op_Concat) {
                const ap_expr_t *nodep = node;
                int n;
                int i = 1;
                struct iovec *vec;
                do {
                    nodep = nodep->node_arg1;
                    i++;
                } while (nodep->node_op == op_Concat);
                vec = apr_palloc(ctx->p, i * sizeof(struct iovec));
                n = i;
                nodep = node;
                i--;
                do {
                    vec[i].iov_base = (void *)ap_expr_eval_word(ctx,
                                                                nodep->node_arg2);
                    vec[i].iov_len = strlen(vec[i].iov_base);
                    i--;
                    nodep = nodep->node_arg1;
                } while (nodep->node_op == op_Concat);
                vec[i].iov_base = (void *)ap_expr_eval_word(ctx, nodep);
                vec[i].iov_len = strlen(vec[i].iov_base);
                result = apr_pstrcatv(ctx->p, vec, n, NULL);
            }
            else {
                const ap_expr_t *nodep = node;
                int i = 1;
                struct iovec *vec;
                do {
                    nodep = nodep->node_arg2;
                    i++;
                } while (nodep->node_op == op_Concat);
                vec = apr_palloc(ctx->p, i * sizeof(struct iovec));
                nodep = node;
                i = 0;
                do {
                    vec[i].iov_base = (void *)ap_expr_eval_word(ctx,
                                                                nodep->node_arg1);
                    vec[i].iov_len = strlen(vec[i].iov_base);
                    i++;
                    nodep = nodep->node_arg2;
                } while (nodep->node_op == op_Concat);
                vec[i].iov_base = (void *)ap_expr_eval_word(ctx, nodep);
                vec[i].iov_len = strlen(vec[i].iov_base);
                i++;
                result = apr_pstrcatv(ctx->p, vec, i, NULL);
            }
            break;
        case op_StringFuncCall: {
            const ap_expr_t *info = node->node_arg1;
            const ap_expr_t *args = node->node_arg2;
            result = ap_expr_eval_string_func(ctx, info, args);
            break;
        }
        case op_RegexBackref: {
            const unsigned int *np = node->node_arg1;
            result = ap_expr_eval_re_backref(ctx, *np);
            break;
        }
        default:
            *ctx->err = "Internal evaluation error: Unknown word expression node";
            break;
        }
        if (!result)
            result = "";
        ctx->reclvl--;
        return result;
    }
    
    static const char *ap_expr_eval_var(ap_expr_eval_ctx_t *ctx,
                                        ap_expr_var_func_t *func,
                                        const void *data)
    {
        AP_DEBUG_ASSERT(func != NULL);
        AP_DEBUG_ASSERT(data != NULL);
        return (*func)(ctx, data);
    }
    
    static const char *ap_expr_eval_re_backref(ap_expr_eval_ctx_t *ctx, unsigned int n)
    {
        int len;
    
        if (!ctx->re_pmatch || !ctx->re_source || !*ctx->re_source
            || **ctx->re_source == '\0' || ctx->re_nmatch < n + 1)
            return "";
    
        len = ctx->re_pmatch[n].rm_eo - ctx->re_pmatch[n].rm_so;
        if (len == 0)
            return "";
    
        return apr_pstrndup(ctx->p, *ctx->re_source + ctx->re_pmatch[n].rm_so, len);
    }
    
    static const char *ap_expr_eval_string_func(ap_expr_eval_ctx_t *ctx,
                                                const ap_expr_t *info,
                                                const ap_expr_t *arg)
    {
        ap_expr_string_func_t *func = (ap_expr_string_func_t *)info->node_arg1;
        const void *data = info->node_arg2;
    
        AP_DEBUG_ASSERT(info->node_op == op_StringFuncInfo);
        AP_DEBUG_ASSERT(func != NULL);
        AP_DEBUG_ASSERT(data != NULL);
        return (*func)(ctx, data, ap_expr_eval_word(ctx, arg));
    }
    
    static int intstrcmp(const char *s1, const char *s2)
    {
        apr_int64_t i1 = apr_atoi64(s1);
        apr_int64_t i2 = apr_atoi64(s2);
    
        if (i1 < i2)
            return -1;
        else if (i1 == i2)
            return 0;
        else
            return 1;
    }
    
    static int ap_expr_eval_comp(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node)
    {
        const ap_expr_t *e1 = node->node_arg1;
        const ap_expr_t *e2 = node->node_arg2;
        switch (node->node_op) {
        case op_EQ:
            return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) == 0);
        case op_NE:
            return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) != 0);
        case op_LT:
            return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <  0);
        case op_LE:
            return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <= 0);
        case op_GT:
            return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >  0);
        case op_GE:
            return (intstrcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >= 0);
        case op_STR_EQ:
            return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) == 0);
        case op_STR_NE:
            return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) != 0);
        case op_STR_LT:
            return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <  0);
        case op_STR_LE:
            return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <= 0);
        case op_STR_GT:
            return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >  0);
        case op_STR_GE:
            return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >= 0);
        case op_IN: {
                const char *needle = ap_expr_eval_word(ctx, e1);
                if (e2->node_op == op_ListElement) {
                    do {
                        const ap_expr_t *val = e2->node_arg1;
                        AP_DEBUG_ASSERT(e2->node_op == op_ListElement);
                        if (strcmp(needle, ap_expr_eval_word(ctx, val)) == 0)
                            return 1;
                        e2 = e2->node_arg2;
                    } while (e2 != NULL);
                }
                else if (e2->node_op == op_ListFuncCall) {
                    const ap_expr_t *info = e2->node_arg1;
                    const ap_expr_t *arg = e2->node_arg2;
                    ap_expr_list_func_t *func = (ap_expr_list_func_t *)info->node_arg1;
                    apr_array_header_t *haystack;
    
                    AP_DEBUG_ASSERT(func != NULL);
                    AP_DEBUG_ASSERT(info->node_op == op_ListFuncInfo);
                    haystack = (*func)(ctx, info->node_arg2, ap_expr_eval_word(ctx, arg));
                    if (haystack == NULL) {
                        return 0;
                    }
                    if (ap_array_str_contains(haystack, needle)) {
                        return 1;
                    }
                }
                return 0;
            }
        case op_REG:
        case op_NRE: {
                const char *word = ap_expr_eval_word(ctx, e1);
                const ap_regex_t *regex = e2->node_arg1;
                int result;
    
                /*
                 * $0 ... $9 may contain stuff the user wants to keep. Therefore
                 * we only set them if there are capturing parens in the regex.
                 */
                if (regex->re_nsub > 0) {
                    result = (0 == ap_regexec(regex, word, ctx->re_nmatch,
                                              ctx->re_pmatch, 0));
                    *ctx->re_source = result ? word : NULL;
                }
                else {
                    result = (0 == ap_regexec(regex, word, 0, NULL, 0));
                }
    
                if (node->node_op == op_REG)
                    return result;
                else
                    return !result;
            }
        default:
            *ctx->err = "Internal evaluation error: Unknown comp expression node";
            return -1;
        }
    }
    
    /* combined string/int comparison for compatibility with ssl_expr */
    static int strcmplex(const char *str1, const char *str2)
    {
        apr_size_t i, n1, n2;
    
        if (str1 == NULL)
            return -1;
        if (str2 == NULL)
            return +1;
        n1 = strlen(str1);
        n2 = strlen(str2);
        if (n1 > n2)
            return 1;
        if (n1 < n2)
            return -1;
        for (i = 0; i < n1; i++) {
            if (str1[i] > str2[i])
                return 1;
            if (str1[i] < str2[i])
                return -1;
        }
        return 0;
    }
    
    static int ssl_expr_eval_comp(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node)
    {
        const ap_expr_t *e1 = node->node_arg1;
        const ap_expr_t *e2 = node->node_arg2;
        switch (node->node_op) {
        case op_EQ:
        case op_STR_EQ:
            return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) == 0);
        case op_NE:
        case op_STR_NE:
            return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) != 0);
        case op_LT:
        case op_STR_LT:
            return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <  0);
        case op_LE:
        case op_STR_LE:
            return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) <= 0);
        case op_GT:
        case op_STR_GT:
            return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >  0);
        case op_GE:
        case op_STR_GE:
            return (strcmplex(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >= 0);
        default:
            return ap_expr_eval_comp(ctx, node);
        }
    }
    
    AP_DECLARE_NONSTD(int) ap_expr_lookup_default(ap_expr_lookup_parms *parms)
    {
        return ap_run_expr_lookup(parms);
    }
    
    AP_DECLARE(const char *) ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp,
                                           ap_expr_info_t *info, const char *expr,
                                           ap_expr_lookup_fn_t *lookup_fn)
    {
        ap_expr_parse_ctx_t ctx;
        int rc;
    
        ctx.pool     = pool;
        ctx.ptemp    = ptemp;
        ctx.inputbuf = expr;
        ctx.inputlen = strlen(expr);
        ctx.inputptr = ctx.inputbuf;
        ctx.expr     = NULL;
        ctx.error    = NULL;        /* generic bison error message (XXX: usually not very useful, should be axed) */
        ctx.error2   = NULL;        /* additional error message */
        ctx.flags    = info->flags;
        ctx.scan_del    = '\0';
        ctx.scan_buf[0] = '\0';
        ctx.scan_ptr    = ctx.scan_buf;
        ctx.lookup_fn   = lookup_fn ? lookup_fn : ap_expr_lookup_default;
        ctx.at_start    = 1;
    
        ap_expr_yylex_init(&ctx.scanner);
        ap_expr_yyset_extra(&ctx, ctx.scanner);
        rc = ap_expr_yyparse(&ctx);
        ap_expr_yylex_destroy(ctx.scanner);
        if (ctx.error) {
            if (ctx.error2)
                return apr_psprintf(pool, "%s: %s", ctx.error, ctx.error2);
            else
                return ctx.error;
        }
        else if (ctx.error2) {
            return ctx.error2;
        }
    
        if (rc) /* XXX can this happen? */
            return "syntax error";
    
    #ifdef AP_EXPR_DEBUG
        if (ctx.expr)
            expr_dump_tree(ctx.expr, NULL, APLOG_NOTICE, 2);
    #endif
    
        info->root_node = ctx.expr;
    
        return NULL;
    }
    
    AP_DECLARE(ap_expr_info_t*) ap_expr_parse_cmd_mi(const cmd_parms *cmd,
                                                     const char *expr,
                                                     unsigned int flags,
                                                     const char **err,
                                                     ap_expr_lookup_fn_t *lookup_fn,
                                                     int module_index)
    {
        ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
        info->filename = cmd->directive->filename;
        info->line_number = cmd->directive->line_num;
        info->flags = flags;
        info->module_index = module_index;
        *err = ap_expr_parse(cmd->pool, cmd->temp_pool, info, expr, lookup_fn);
    
        if (*err)
            return NULL;
    
        return info;
    }
    
    ap_expr_t *ap_expr_make(ap_expr_node_op_e op, const void *a1, const void *a2,
                          ap_expr_parse_ctx_t *ctx)
    {
        ap_expr_t *node = apr_palloc(ctx->pool, sizeof(ap_expr_t));
        node->node_op   = op;
        node->node_arg1 = a1;
        node->node_arg2 = a2;
        return node;
    }
    
    static ap_expr_t *ap_expr_info_make(int type, const char *name,
                                      ap_expr_parse_ctx_t *ctx,
                                      const ap_expr_t *arg)
    {
        ap_expr_t *info = apr_palloc(ctx->pool, sizeof(ap_expr_t));
        ap_expr_lookup_parms parms;
        parms.type  = type;
        parms.flags = ctx->flags;
        parms.pool  = ctx->pool;
        parms.ptemp = ctx->ptemp;
        parms.name  = name;
        parms.func  = &info->node_arg1;
        parms.data  = &info->node_arg2;
        parms.err   = &ctx->error2;
        parms.arg   = (arg && arg->node_op == op_String) ? arg->node_arg1 : NULL;
        if (ctx->lookup_fn(&parms) != OK)
            return NULL;
        return info;
    }
    
    ap_expr_t *ap_expr_str_func_make(const char *name, const ap_expr_t *arg,
                                   ap_expr_parse_ctx_t *ctx)
    {
        ap_expr_t *info = ap_expr_info_make(AP_EXPR_FUNC_STRING, name, ctx, arg);
        if (!info)
            return NULL;
    
        info->node_op = op_StringFuncInfo;
        return ap_expr_make(op_StringFuncCall, info, arg, ctx);
    }
    
    ap_expr_t *ap_expr_list_func_make(const char *name, const ap_expr_t *arg,
                                    ap_expr_parse_ctx_t *ctx)
    {
        ap_expr_t *info = ap_expr_info_make(AP_EXPR_FUNC_LIST, name, ctx, arg);
        if (!info)
            return NULL;
    
        info->node_op = op_ListFuncInfo;
        return ap_expr_make(op_ListFuncCall, info, arg, ctx);
    }
    
    ap_expr_t *ap_expr_unary_op_make(const char *name, const ap_expr_t *arg,
                                   ap_expr_parse_ctx_t *ctx)
    {
        ap_expr_t *info = ap_expr_info_make(AP_EXPR_FUNC_OP_UNARY, name, ctx, arg);
        if (!info)
            return NULL;
    
        info->node_op = op_UnaryOpInfo;
        return ap_expr_make(op_UnaryOpCall, info, arg, ctx);
    }
    
    ap_expr_t *ap_expr_binary_op_make(const char *name, const ap_expr_t *arg1,
                                    const ap_expr_t *arg2, ap_expr_parse_ctx_t *ctx)
    {
        ap_expr_t *args;
        ap_expr_t *info = ap_expr_info_make(AP_EXPR_FUNC_OP_BINARY, name, ctx,
                                            arg2);
        if (!info)
            return NULL;
    
        info->node_op = op_BinaryOpInfo;
        args = ap_expr_make(op_BinaryOpArgs, arg1, arg2, ctx);
        return ap_expr_make(op_BinaryOpCall, info, args, ctx);
    }
    
    
    ap_expr_t *ap_expr_var_make(const char *name, ap_expr_parse_ctx_t *ctx)
    {
        ap_expr_t *node = ap_expr_info_make(AP_EXPR_FUNC_VAR, name, ctx, NULL);
        if (!node)
            return NULL;
    
        node->node_op = op_Var;
        return node;
    }
    
    #ifdef AP_EXPR_DEBUG
    
    #define MARK                        APLOG_MARK,loglevel,0,s
    #define DUMP_E_E(op, e1, e2)                                                \
        do { ap_log_error(MARK,"%*s%s: %pp %pp", indent, " ", op, e1, e2);      \
             if (e1) expr_dump_tree(e1, s, loglevel, indent + 2);               \
             if (e2) expr_dump_tree(e2, s, loglevel, indent + 2);               \
        } while (0)
    #define DUMP_S_E(op, s1, e1)                                                    \
        do { ap_log_error(MARK,"%*s%s: '%s' %pp", indent, " ", op, (char *)s1, e1); \
             if (e1) expr_dump_tree(e1, s, loglevel, indent + 2);                   \
        } while (0)
    #define DUMP_S_P(op, s1, p1)                                                \
        ap_log_error(MARK,"%*s%s: '%s' %pp", indent, " ", op, (char *)s1, p1);
    #define DUMP_P_P(op, p1, p2)                                                \
        ap_log_error(MARK,"%*s%s: %pp %pp", indent, " ", op, p1, p2);
    #define DUMP_S_S(op, s1, s2)                                                       \
        ap_log_error(MARK,"%*s%s: '%s' '%s'", indent, " ", op, (char *)s1, (char *)s2)
    #define DUMP_P(op, p1)                                                      \
        ap_log_error(MARK,"%*s%s: %pp", indent, " ", op, p1);
    #define DUMP_IP(op, p1)                                                     \
        ap_log_error(MARK,"%*s%s: %d", indent, " ", op, *(int *)p1);
    #define DUMP_S(op, s1)                                                      \
        ap_log_error(MARK,"%*s%s: '%s'", indent, " ", op, (char *)s1)
    
    #define CASE_OP(op)                  case op: name = #op ; break;
    
    static void expr_dump_tree(const ap_expr_t *e, const server_rec *s,
                               int loglevel, int indent)
    {
        switch (e->node_op) {
        /* no arg */
        case op_NOP:
        case op_True:
        case op_False:
            {
                char *name;
                switch (e->node_op) {
                CASE_OP(op_NOP);
                CASE_OP(op_True);
                CASE_OP(op_False);
                default:
                    ap_assert(0);
                }
                ap_log_error(MARK, "%*s%s", indent, " ", name);
            }
            break;
    
        /* arg1: string, arg2: expr */
        case op_UnaryOpCall:
        case op_BinaryOpCall:
        case op_BinaryOpArgs:
            {
                char *name;
                switch (e->node_op) {
                CASE_OP(op_BinaryOpCall);
                CASE_OP(op_UnaryOpCall);
                CASE_OP(op_BinaryOpArgs);
                default:
                    ap_assert(0);
                }
                DUMP_S_E(name, e->node_arg1, e->node_arg2);
            }
            break;
    
        /* arg1: expr, arg2: expr */
        case op_Comp:
        case op_Not:
        case op_Or:
        case op_And:
        case op_EQ:
        case op_NE:
        case op_LT:
        case op_LE:
        case op_GT:
        case op_GE:
        case op_STR_EQ:
        case op_STR_NE:
        case op_STR_LT:
        case op_STR_LE:
        case op_STR_GT:
        case op_STR_GE:
        case op_IN:
        case op_REG:
        case op_NRE:
        case op_Concat:
        case op_StringFuncCall:
        case op_ListFuncCall:
        case op_ListElement:
            {
                char *name;
                switch (e->node_op) {
                CASE_OP(op_Comp);
                CASE_OP(op_Not);
                CASE_OP(op_Or);
                CASE_OP(op_And);
                CASE_OP(op_EQ);
                CASE_OP(op_NE);
                CASE_OP(op_LT);
                CASE_OP(op_LE);
                CASE_OP(op_GT);
                CASE_OP(op_GE);
                CASE_OP(op_STR_EQ);
                CASE_OP(op_STR_NE);
                CASE_OP(op_STR_LT);
                CASE_OP(op_STR_LE);
                CASE_OP(op_STR_GT);
                CASE_OP(op_STR_GE);
                CASE_OP(op_IN);
                CASE_OP(op_REG);
                CASE_OP(op_NRE);
                CASE_OP(op_Concat);
                CASE_OP(op_StringFuncCall);
                CASE_OP(op_ListFuncCall);
                CASE_OP(op_ListElement);
                default:
                    ap_assert(0);
                }
                DUMP_E_E(name, e->node_arg1, e->node_arg2);
            }
            break;
        /* arg1: string */
        case op_Digit:
        case op_String:
            {
                char *name;
                switch (e->node_op) {
                CASE_OP(op_Digit);
                CASE_OP(op_String);
                default:
                    ap_assert(0);
                }
                DUMP_S(name, e->node_arg1);
            }
            break;
        /* arg1: pointer, arg2: pointer */
        case op_Var:
        case op_StringFuncInfo:
        case op_UnaryOpInfo:
        case op_BinaryOpInfo:
        case op_ListFuncInfo:
            {
                char *name;
                switch (e->node_op) {
                CASE_OP(op_Var);
                CASE_OP(op_StringFuncInfo);
                CASE_OP(op_UnaryOpInfo);
                CASE_OP(op_BinaryOpInfo);
                CASE_OP(op_ListFuncInfo);
                default:
                    ap_assert(0);
                }
                DUMP_P_P(name, e->node_arg1, e->node_arg2);
            }
            break;
        /* arg1: pointer */
        case op_Regex:
            DUMP_P("op_Regex", e->node_arg1);
            break;
        /* arg1: pointer to int */
        case op_RegexBackref:
            DUMP_IP("op_RegexBackref", e->node_arg1);
            break;
        default:
            ap_log_error(MARK, "%*sERROR: INVALID OP %d", indent, " ", e->node_op);
            break;
        }
    }
    #endif /* AP_EXPR_DEBUG */
    
    static int ap_expr_eval_unary_op(ap_expr_eval_ctx_t *ctx, const ap_expr_t *info,
                                     const ap_expr_t *arg)
    {
        ap_expr_op_unary_t *op_func = (ap_expr_op_unary_t *)info->node_arg1;
        const void *data = info->node_arg2;
    
        AP_DEBUG_ASSERT(info->node_op == op_UnaryOpInfo);
        AP_DEBUG_ASSERT(op_func != NULL);
        AP_DEBUG_ASSERT(data != NULL);
        return (*op_func)(ctx, data, ap_expr_eval_word(ctx, arg));
    }
    
    static int ap_expr_eval_binary_op(ap_expr_eval_ctx_t *ctx,
                                      const ap_expr_t *info,
                                      const ap_expr_t *args)
    {
        ap_expr_op_binary_t *op_func = (ap_expr_op_binary_t *)info->node_arg1;
        const void *data = info->node_arg2;
        const ap_expr_t *a1 = args->node_arg1;
        const ap_expr_t *a2 = args->node_arg2;
    
        AP_DEBUG_ASSERT(info->node_op == op_BinaryOpInfo);
        AP_DEBUG_ASSERT(args->node_op == op_BinaryOpArgs);
        AP_DEBUG_ASSERT(op_func != NULL);
        AP_DEBUG_ASSERT(data != NULL);
        return (*op_func)(ctx, data, ap_expr_eval_word(ctx, a1),
                          ap_expr_eval_word(ctx, a2));
    }
    
    
    static int ap_expr_eval(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node)
    {
        const ap_expr_t *e1 = node->node_arg1;
        const ap_expr_t *e2 = node->node_arg2;
        int result = FALSE;
        if (inc_rec(ctx))
            return result;
        while (1) {
            switch (node->node_op) {
            case op_True:
                result ^= TRUE;
                goto out;
            case op_False:
                result ^= FALSE;
                goto out;
            case op_Not:
                result = !result;
                node = e1;
                break;
            case op_Or:
                do {
                    if (e1->node_op == op_Not) {
                        if (!ap_expr_eval(ctx, e1->node_arg1)) {
                            result ^= TRUE;
                            goto out;
                        }
                    }
                    else {
                        if (ap_expr_eval(ctx, e1)) {
                            result ^= TRUE;
                            goto out;
                        }
                    }
                    node = node->node_arg2;
                    e1 = node->node_arg1;
                } while (node->node_op == op_Or);
                break;
            case op_And:
                do {
                    if (e1->node_op == op_Not) {
                        if (ap_expr_eval(ctx, e1->node_arg1)) {
                            result ^= FALSE;
                            goto out;
                        }
                    }
                    else {
                        if (!ap_expr_eval(ctx, e1)) {
                            result ^= FALSE;
                            goto out;
                        }
                    }
                    node = node->node_arg2;
                    e1 = node->node_arg1;
                } while (node->node_op == op_And);
                break;
            case op_UnaryOpCall:
                result ^= ap_expr_eval_unary_op(ctx, e1, e2);
                goto out;
            case op_BinaryOpCall:
                result ^= ap_expr_eval_binary_op(ctx, e1, e2);
                goto out;
            case op_Comp:
                if (ctx->info->flags & AP_EXPR_FLAG_SSL_EXPR_COMPAT)
                    result ^= ssl_expr_eval_comp(ctx, e1);
                else
                    result ^= ap_expr_eval_comp(ctx, e1);
                goto out;
            default:
                *ctx->err = "Internal evaluation error: Unknown expression node";
                goto out;
            }
            e1 = node->node_arg1;
            e2 = node->node_arg2;
        }
    out:
        ctx->reclvl--;
        return result;
    }
    
    AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *info,
                                 const char **err)
    {
        return ap_expr_exec_re(r, info, 0, NULL, NULL, err);
    }
    
    AP_DECLARE(int) ap_expr_exec_ctx(ap_expr_eval_ctx_t *ctx)
    {
        int rc;
    
        AP_DEBUG_ASSERT(ctx->p != NULL);
        /* XXX: allow r, c == NULL */
        AP_DEBUG_ASSERT(ctx->r != NULL);
        AP_DEBUG_ASSERT(ctx->c != NULL);
        AP_DEBUG_ASSERT(ctx->s != NULL);
        AP_DEBUG_ASSERT(ctx->err != NULL);
        AP_DEBUG_ASSERT(ctx->info != NULL);
        if (ctx->re_pmatch) {
            AP_DEBUG_ASSERT(ctx->re_source != NULL);
            AP_DEBUG_ASSERT(ctx->re_nmatch > 0);
        }
        ctx->reclvl = 0;
    
        *ctx->err = NULL;
        if (ctx->info->flags & AP_EXPR_FLAG_STRING_RESULT) {
            *ctx->result_string = ap_expr_eval_word(ctx, ctx->info->root_node);
            if (*ctx->err != NULL) {
                ap_log_rerror(LOG_MARK(ctx->info), APLOG_ERR, 0, ctx->r,
                              "Evaluation of expression from %s:%d failed: %s",
                              ctx->info->filename, ctx->info->line_number, *ctx->err);
                return -1;
            } else {
                ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE4, 0, ctx->r,
                              "Evaluation of string expression from %s:%d gave: %s",
                              ctx->info->filename, ctx->info->line_number,
                              *ctx->result_string);
                return 1;
            }
        }
        else {
            rc = ap_expr_eval(ctx, ctx->info->root_node);
            if (*ctx->err != NULL) {
                ap_log_rerror(LOG_MARK(ctx->info), APLOG_ERR, 0, ctx->r,
                              "Evaluation of expression from %s:%d failed: %s",
                              ctx->info->filename, ctx->info->line_number, *ctx->err);
                return -1;
            } else {
                rc = rc ? 1 : 0;
                ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE4, 0, ctx->r,
                              "Evaluation of expression from %s:%d gave: %d",
                              ctx->info->filename, ctx->info->line_number, rc);
    
                if (ctx->vary_this && *ctx->vary_this)
                    apr_table_merge(ctx->r->headers_out, "Vary", *ctx->vary_this);
    
                return rc;
            }
        }
    }
    
    AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *info,
                                    apr_size_t nmatch, ap_regmatch_t *pmatch,
                                    const char **source, const char **err)
    {
        ap_expr_eval_ctx_t ctx;
        int dont_vary = (info->flags & AP_EXPR_FLAG_DONT_VARY);
        const char *tmp_source = NULL, *vary_this = NULL;
        ap_regmatch_t tmp_pmatch[AP_MAX_REG_MATCH];
    
        AP_DEBUG_ASSERT((info->flags & AP_EXPR_FLAG_STRING_RESULT) == 0);
    
        ctx.r = r;
        ctx.c = r->connection;
        ctx.s = r->server;
        ctx.p = r->pool;
        ctx.err  = err;
        ctx.info = info;
        ctx.re_nmatch = nmatch;
        ctx.re_pmatch = pmatch;
        ctx.re_source = source;
        ctx.vary_this = dont_vary ? NULL : &vary_this;
        ctx.data = NULL;
    
        if (!pmatch) {
            ctx.re_nmatch = AP_MAX_REG_MATCH;
            ctx.re_pmatch = tmp_pmatch;
            ctx.re_source = &tmp_source;
        }
    
        return ap_expr_exec_ctx(&ctx);
    }
    
    AP_DECLARE(const char *) ap_expr_str_exec_re(request_rec *r,
                                                 const ap_expr_info_t *info,
                                                 apr_size_t nmatch,
                                                 ap_regmatch_t *pmatch,
                                                 const char **source,
                                                 const char **err)
    {
        ap_expr_eval_ctx_t ctx;
        int dont_vary, rc;
        const char *tmp_source, *vary_this;
        ap_regmatch_t tmp_pmatch[AP_MAX_REG_MATCH];
        const char *result;
    
        AP_DEBUG_ASSERT(info->flags & AP_EXPR_FLAG_STRING_RESULT);
    
        if (info->root_node->node_op == op_String) {
            /* short-cut for constant strings */
            *err = NULL;
            return (const char *)info->root_node->node_arg1;
        }
    
        tmp_source = NULL;
        vary_this = NULL;
    
        dont_vary = (info->flags & AP_EXPR_FLAG_DONT_VARY);
    
        ctx.r = r;
        ctx.c = r->connection;
        ctx.s = r->server;
        ctx.p = r->pool;
        ctx.err  = err;
        ctx.info = info;
        ctx.re_nmatch = nmatch;
        ctx.re_pmatch = pmatch;
        ctx.re_source = source;
        ctx.vary_this = dont_vary ? NULL : &vary_this;
        ctx.data = NULL;
        ctx.result_string = &result;
    
        if (!pmatch) {
            ctx.re_nmatch = AP_MAX_REG_MATCH;
            ctx.re_pmatch = tmp_pmatch;
            ctx.re_source = &tmp_source;
        }
    
        rc = ap_expr_exec_ctx(&ctx);
        if (rc > 0)
            return result;
        else if (rc < 0)
            return NULL;
        else
            ap_assert(0);
        /* Not reached */
        return NULL;
    }
    
    AP_DECLARE(const char *) ap_expr_str_exec(request_rec *r,
                                              const ap_expr_info_t *info,
                                              const char **err)
    {
        return ap_expr_str_exec_re(r, info, 0, NULL, NULL, err);
    }
    
    
    static void add_vary(ap_expr_eval_ctx_t *ctx, const char *name)
    {
        if (!ctx->vary_this)
            return;
    
        if (*ctx->vary_this) {
            *ctx->vary_this = apr_pstrcat(ctx->p, *ctx->vary_this, ", ", name,
                                          NULL);
        }
        else {
            *ctx->vary_this = name;
        }
    }
    
    static const char *req_table_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                      const char *arg)
    {
        const char *name = (const char *)data;
        apr_table_t *t;
        if (!ctx->r)
            return "";
    
        if (name[2] == 's') {           /* resp */
            /* Try r->headers_out first, fall back on err_headers_out. */
            const char *v = apr_table_get(ctx->r->headers_out, arg);
            if (v) {
                return v;
            }
            t = ctx->r->err_headers_out;
        }
        else if (name[0] == 'n')        /* notes */
            t = ctx->r->notes;
        else if (name[3] == 'e')        /* reqenv */
            t = ctx->r->subprocess_env;
        else if (name[3] == '_')        /* req_novary */
            t = ctx->r->headers_in;
        else {                          /* req, http */
            t = ctx->r->headers_in;
            /* Skip the 'Vary: Host' header combination
             * as indicated in rfc7231 section-7.1.4
             */
            if (strcasecmp(arg, "Host")){
                add_vary(ctx, arg);
            }
        }
        return apr_table_get(t, arg);
    }
    
    static const char *env_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                const char *arg)
    {
        const char *res;
        /* this order is for ssl_expr compatibility */
        if (ctx->r) {
            if ((res = apr_table_get(ctx->r->notes, arg)) != NULL)
                return res;
            else if ((res = apr_table_get(ctx->r->subprocess_env, arg)) != NULL)
                return res;
        }
        return getenv(arg);
    }
    
    static const char *osenv_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                  const char *arg)
    {
        return getenv(arg);
    }
    
    static const char *tolower_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                    const char *arg)
    {
        char *result = apr_pstrdup(ctx->p, arg);
        ap_str_tolower(result);
        return result;
    }
    
    static const char *toupper_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                    const char *arg)
    {
        char *result = apr_pstrdup(ctx->p, arg);
        ap_str_toupper(result);
        return result;
    }
    
    static const char *escape_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                   const char *arg)
    {
        return ap_escape_uri(ctx->p, arg);
    }
    
    static const char *base64_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                   const char *arg)
    {
        return ap_pbase64encode(ctx->p, (char *)arg);
    }
    
    static const char *unbase64_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                   const char *arg)
    {
        return ap_pbase64decode(ctx->p, arg);
    }
    
    static const char *sha1_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                   const char *arg)
    {
        apr_sha1_ctx_t context;
        apr_byte_t sha1[APR_SHA1_DIGESTSIZE];
        char *out;
    
        out = apr_palloc(ctx->p, APR_SHA1_DIGESTSIZE*2+1);
    
        apr_sha1_init(&context);
        apr_sha1_update(&context, arg, (unsigned int)strlen(arg));
        apr_sha1_final(sha1, &context);
    
        ap_bin2hex(sha1, APR_SHA1_DIGESTSIZE, out);
    
        return out;
    }
    
    static const char *md5_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                   const char *arg)
    {
        return ap_md5(ctx->p, (const unsigned char *)arg);
    }
    
    #if APR_VERSION_AT_LEAST(1,6,0)
    static const char *ldap_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                   const char *arg)
    {
        return apr_pescape_ldap(ctx->p, arg, APR_ESCAPE_STRING, APR_ESCAPE_LDAP_ALL);
    }
    #endif
    
    #define MAX_FILE_SIZE 10*1024*1024
    static const char *file_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                 char *arg)
    {
        apr_file_t *fp;
        char *buf;
        apr_off_t offset;
        apr_size_t len;
        apr_finfo_t finfo;
    
        if (apr_file_open(&fp, arg, APR_READ|APR_BUFFERED,
                          APR_OS_DEFAULT, ctx->p) != APR_SUCCESS) {
            *ctx->err = apr_psprintf(ctx->p, "Cannot open file %s", arg);
            return "";
        }
        apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
        if (finfo.size > MAX_FILE_SIZE) {
            *ctx->err = apr_psprintf(ctx->p, "File %s too large", arg);
            apr_file_close(fp);
            return "";
        }
        len = (apr_size_t)finfo.size;
        if (len == 0) {
            apr_file_close(fp);
            return "";
        }
        else {
            if ((buf = (char *)apr_palloc(ctx->p, sizeof(char)*(len+1))) == NULL) {
                *ctx->err = "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) {
                *ctx->err = apr_psprintf(ctx->p, "Cannot read from file %s", arg);
                apr_file_close(fp);
                return "";
            }
            buf[len] = '\0';
        }
        apr_file_close(fp);
        return buf;
    }
    
    static apr_status_t stat_check(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
        apr_status_t rv = APR_SUCCESS;
        if (APR_SUCCESS != (rv = ap_stat_check(arg, ctx->p))) {
            *ctx->err = apr_psprintf(ctx->p, "stat of %s not allowed", arg);
        }
        return rv;
    }
    static const char *filesize_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                      char *arg)
    {
        apr_finfo_t sb;
        if (APR_SUCCESS != stat_check(ctx, data, arg)) {
            return "";
        }
        if (apr_stat(&sb, arg, APR_FINFO_MIN, ctx->p) == APR_SUCCESS
            && sb.filetype == APR_REG && sb.size > 0)
            return apr_psprintf(ctx->p, "%" APR_OFF_T_FMT, sb.size);
        else
            return "0";
    }
    
    static const char *unescape_func(ap_expr_eval_ctx_t *ctx, const void *data,
                                     const char *arg)
    {
        char *result = apr_pstrdup(ctx->p, arg);
        int ret = ap_unescape_url_keep2f(result, 0);
        if (ret == OK)
            return result;
        ap_log_rerror(LOG_MARK(ctx->info), APLOG_DEBUG, 0, ctx->r, APLOGNO(00538)
                      "%s %% escape in unescape('%s') at %s:%d",
                      ret == HTTP_BAD_REQUEST ? "Bad" : "Forbidden", arg,
                      ctx->info->filename, ctx->info->line_number);
        return "";
    }
    
    static int op_nz(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
        const char *name = (const char *)data;
        if (name[0] == 'z')
            return (arg[0] == '\0');
        else
            return (arg[0] != '\0');
    }
    
    static int op_file_min(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
        apr_finfo_t sb;
        const char *name = (const char *)data;
        if (APR_SUCCESS != stat_check(ctx, data, arg)) {
            return FALSE;
        }
        if (apr_stat(&sb, arg, APR_FINFO_MIN, ctx->p) != APR_SUCCESS)
            return FALSE;
        switch (name[0]) {
        case 'd':
            return (sb.filetype == APR_DIR);
        case 'e':
            return TRUE;
        case 'f':
            return (sb.filetype == APR_REG);
        case 's':
            return (sb.filetype == APR_REG && sb.size > 0);
        default:
            ap_assert(0);
        }
        return FALSE;
    }
    
    static int op_file_link(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
    #if !defined(OS2)
        apr_finfo_t sb;
        if (APR_SUCCESS != stat_check(ctx, data, arg)) {
            return FALSE;
        }
        if (apr_stat(&sb, arg, APR_FINFO_MIN | APR_FINFO_LINK, ctx->p) == APR_SUCCESS
            && sb.filetype == APR_LNK) {
            return TRUE;
        }
    #endif
        return FALSE;
    }
    
    static int op_file_xbit(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
        apr_finfo_t sb;
        if (APR_SUCCESS != stat_check(ctx, data, arg)) {
            return FALSE;
        }
        if (apr_stat(&sb, arg, APR_FINFO_PROT| APR_FINFO_LINK, ctx->p) == APR_SUCCESS
            && (sb.protection & (APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE))) {
            return TRUE;
        }
        return FALSE;
    }
    
    static int op_url_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
        int rc = FALSE;
        request_rec  *rsub, *r = ctx->r;
        if (!r)
            return FALSE;
        /* avoid some infinite recursions */
        if (r->main && r->main->uri && r->uri && strcmp(r->main->uri, r->uri) == 0)
            return FALSE;
    
        rsub = ap_sub_req_lookup_uri(arg, r, NULL);
        if (rsub->status < 400) {
                rc = TRUE;
        }
        ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE5, 0, r,
                      "Subrequest for -U %s at %s:%d gave status: %d",
                      arg, ctx->info->filename, ctx->info->line_number,
                      rsub->status);
        ap_destroy_sub_req(rsub);
        return rc;
    }
    
    static int op_file_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
        int rc = FALSE;
        apr_finfo_t sb;
        request_rec *rsub, *r = ctx->r;
        if (!r)
            return FALSE;
        if (APR_SUCCESS != stat_check(ctx, data, arg)) {
            return FALSE;
        }
        rsub = ap_sub_req_lookup_file(arg, r, NULL);
        if (rsub->status < 300 &&
            /* double-check that file exists since default result is 200 */
            apr_stat(&sb, rsub->filename, APR_FINFO_MIN, ctx->p) == APR_SUCCESS) {
            rc = TRUE;
        }
        ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE5, 0, r,
                      "Subrequest for -F %s at %s:%d gave status: %d",
                      arg, ctx->info->filename, ctx->info->line_number,
                      rsub->status);
        ap_destroy_sub_req(rsub);
        return rc;
    }
    
    
    APR_DECLARE_OPTIONAL_FN(int, http2_is_h2, (conn_rec *));
    static APR_OPTIONAL_FN_TYPE(http2_is_h2) *is_http2 = NULL;
    
    static const char *const conn_var_names[] = {
        "HTTPS",                    /*  0 */
        "IPV6",                     /*  1 */
        "CONN_LOG_ID",              /*  2 */
        "CONN_REMOTE_ADDR",         /*  3 */
        "HTTP2",                    /*  4 */
        NULL
    };
    
    static const char *conn_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
    {
        int index = ((const char **)data - conn_var_names);
        conn_rec *c = ctx->c;
        if (!c)
            return "";
    
        switch (index) {
        case 0:
            if (ap_ssl_conn_is_ssl(c))
                return "on";
            else
                return "off";
        case 1:
    #if APR_HAVE_IPV6
            {
                apr_sockaddr_t *addr = c->client_addr;
                if (addr->family == AF_INET6
                    && !IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr))
                    return "on";
                else
                    return "off";
            }
    #else
            return "off";
    #endif
        case 2:
            return c->log_id;
        case 3:
            return c->client_ip;
        case 4:
            if (is_http2 && is_http2(c))
                return "on";
            else
                return "off";
        default:
            ap_assert(0);
            return NULL;
        }
    }
    
    static const char *const request_var_names[] = {
        "REQUEST_METHOD",           /*  0 */
        "REQUEST_SCHEME",           /*  1 */
        "REQUEST_URI",              /*  2 */
        "REQUEST_FILENAME",         /*  3 */
        "REMOTE_HOST",              /*  4 */
        "REMOTE_IDENT",             /*  5 */
        "REMOTE_USER",              /*  6 */
        "SERVER_ADMIN",             /*  7 */
        "SERVER_NAME",              /*  8 */
        "SERVER_PORT",              /*  9 */
        "SERVER_PROTOCOL",          /* 10 */
        "SCRIPT_FILENAME",          /* 11 */
        "PATH_INFO",                /* 12 */
        "QUERY_STRING",             /* 13 */
        "IS_SUBREQ",                /* 14 */
        "DOCUMENT_ROOT",            /* 15 */
        "AUTH_TYPE",                /* 16 */
        "THE_REQUEST",              /* 17 */
        "CONTENT_TYPE",             /* 18 */
        "HANDLER",                  /* 19 */
        "REQUEST_LOG_ID",           /* 20 */
        "SCRIPT_USER",              /* 21 */
        "SCRIPT_GROUP",             /* 22 */
        "DOCUMENT_URI",             /* 23 */
        "LAST_MODIFIED",            /* 24 */
        "CONTEXT_PREFIX",           /* 25 */
        "CONTEXT_DOCUMENT_ROOT",    /* 26 */
        "REQUEST_STATUS",           /* 27 */
        "REMOTE_ADDR",              /* 28 */
        "REMOTE_PORT",              /* 29 */
        NULL
    };
    
    static const char *request_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
    {
        int index = ((const char **)data - request_var_names);
        request_rec *r = ctx->r;
        if (!r)
            return "";
    
        switch (index) {
        case 0:
            return r->method;
        case 1:
            return ap_http_scheme(r);
        case 2:
            return r->uri;
        case 3:
            return r->filename;
        case 4:
            return ap_get_useragent_host(r, REMOTE_NAME, NULL);
        case 5:
            return ap_get_remote_logname(r);
        case 6:
            return r->user;
        case 7:
            return r->server->server_admin;
        case 8:
            return ap_get_server_name_for_url(r);
        case 9:
            return apr_psprintf(ctx->p, "%u", ap_get_server_port(r));
        case 10:
            return r->protocol;
        case 11:
            return r->filename;
        case 12:
            return r->path_info;
        case 13:
            return r->args;
        case 14:
            return (r->main != NULL ? "true" : "false");
        case 15:
            return ap_document_root(r);
        case 16:
            return r->ap_auth_type;
        case 17:
            return r->the_request;
        case 18:
            return r->content_type;
        case 19:
            return r->handler;
        case 20:
            return r->log_id;
        case 21:
            {
                char *result = "";
                if (r->finfo.valid & APR_FINFO_USER)
                    apr_uid_name_get(&result, r->finfo.user, ctx->p);
                return result;
            }
        case 22:
            {
                char *result = "";
                if (r->finfo.valid & APR_FINFO_USER)
                    apr_gid_name_get(&result, r->finfo.group, ctx->p);
                return result;
            }
        case 23:
            {
                const char *uri = apr_table_get(r->subprocess_env, "DOCUMENT_URI");
                return uri ? uri : r->uri;
            }
        case 24:
            {
                apr_time_exp_t tm;
                apr_time_exp_lt(&tm, r->mtime);
                return apr_psprintf(ctx->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);
            }
        case 25:
            return ap_context_prefix(r);
        case 26:
            return ap_context_document_root(r);
        case 27:
            return r->status ? apr_psprintf(ctx->p, "%d", r->status) : "";
        case 28:
            return r->useragent_ip;
        case 29:
            return apr_psprintf(ctx->p, "%u", ctx->c->client_addr->port);
        default:
            ap_assert(0);
            return NULL;
        }
    }
    
    static const char *const req_header_var_names[] = {
        "HTTP_USER_AGENT",       /* 0 */
        "HTTP_PROXY_CONNECTION", /* 1 */
        "HTTP_REFERER",          /* 2 */
        "HTTP_COOKIE",           /* 3 */
        "HTTP_FORWARDED",        /* 4 */
        "HTTP_HOST",             /* 5 */
        "HTTP_ACCEPT",           /* 6 */
        NULL
    };
    
    static const char *const req_header_header_names[] = {
        "User-Agent",
        "Proxy-Connection",
        "Referer",
        "Cookie",
        "Forwarded",
        "Host",
        "Accept"
    };
    
    static const char *req_header_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
    {
        const char **const varname = (const char **)data;
        int index = (varname - req_header_var_names);
        const char *name;
    
        AP_DEBUG_ASSERT(index < 7);
        if (!ctx->r)
            return "";
    
        name = req_header_header_names[index];
        /* Skip the 'Vary: Host' header combination
         * as indicated in rfc7231 section-7.1.4
         */
        if (strcasecmp(name, "Host")){
            add_vary(ctx, name);
        }
        return apr_table_get(ctx->r->headers_in, name);
    }
    
    static const char *const misc_var_names[] = {
        "TIME_YEAR",        /* 0 */
        "TIME_MON",         /* 1 */
        "TIME_DAY",         /* 2 */
        "TIME_HOUR",        /* 3 */
        "TIME_MIN",         /* 4 */
        "TIME_SEC",         /* 5 */
        "TIME_WDAY",        /* 6 */
        "TIME",             /* 7 */
        "SERVER_SOFTWARE",  /* 8 */
        "API_VERSION",      /* 9 */
        NULL
    };
    
    static const char *misc_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
    {
        apr_time_exp_t tm;
        int index = ((const char **)data - misc_var_names);
        apr_time_exp_lt(&tm, apr_time_now());
    
        switch (index) {
        case 0:
            return apr_psprintf(ctx->p, "%02d%02d", (tm.tm_year / 100) + 19,
                                tm.tm_year % 100);
        case 1:
            return apr_psprintf(ctx->p, "%02d", tm.tm_mon+1);
        case 2:
            return apr_psprintf(ctx->p, "%02d", tm.tm_mday);
        case 3:
            return apr_psprintf(ctx->p, "%02d", tm.tm_hour);
        case 4:
            return apr_psprintf(ctx->p, "%02d", tm.tm_min);
        case 5:
            return apr_psprintf(ctx->p, "%02d", tm.tm_sec);
        case 6:
            return apr_psprintf(ctx->p, "%d", tm.tm_wday);
        case 7:
            return apr_psprintf(ctx->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);
        case 8:
            return ap_get_server_banner();
        case 9:
            return apr_itoa(ctx->p, MODULE_MAGIC_NUMBER_MAJOR);
        default:
            ap_assert(0);
        }
    
        return NULL;
    }
    
    static int subnet_parse_arg(ap_expr_lookup_parms *parms)
    {
        apr_ipsubnet_t *subnet;
        const char *addr = parms->arg;
        const char *mask;
        apr_status_t ret;
    
        if (!parms->arg) {
            *parms->err = apr_psprintf(parms->ptemp,
                                       "-%s requires subnet/netmask as constant argument",
                                       parms->name);
            return !OK;
        }
    
        mask = ap_strchr_c(addr, '/');
        if (mask) {
            addr = apr_pstrmemdup(parms->ptemp, addr, mask - addr);
            mask++;
        }
    
        ret = apr_ipsubnet_create(&subnet, addr, mask, parms->pool);
        if (ret != APR_SUCCESS) {
            *parms->err = "parsing of subnet/netmask failed";
            return !OK;
        }
    
        *parms->data = subnet;
        return OK;
    }
    
    static int op_ipmatch(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg1,
                    const char *arg2)
    {
        apr_ipsubnet_t *subnet = (apr_ipsubnet_t *)data;
        apr_sockaddr_t *saddr;
    
        AP_DEBUG_ASSERT(subnet != NULL);
    
        /* maybe log an error if this goes wrong? */
        if (apr_sockaddr_info_get(&saddr, arg1, APR_UNSPEC, 0, 0, ctx->p) != APR_SUCCESS)
            return FALSE;
    
        return apr_ipsubnet_test(subnet, saddr);
    }
    
    static int op_R(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg1)
    {
        apr_ipsubnet_t *subnet = (apr_ipsubnet_t *)data;
    
        AP_DEBUG_ASSERT(subnet != NULL);
    
        if (!ctx->r)
            return FALSE;
    
        return apr_ipsubnet_test(subnet, ctx->r->useragent_addr);
    }
    
    static int op_T(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg)
    {
        switch (arg[0]) {
        case '\0':
            return FALSE;
        case 'o':
        case 'O':
            return strcasecmp(arg, "off") == 0 ? FALSE : TRUE;
        case 'n':
        case 'N':
            return strcasecmp(arg, "no") == 0 ? FALSE : TRUE;
        case 'f':
        case 'F':
            return strcasecmp(arg, "false") == 0 ? FALSE : TRUE;
        case '0':
            return arg[1] == '\0' ? FALSE : TRUE;
        default:
            return TRUE;
        }
    }
    
    static int op_fnmatch(ap_expr_eval_ctx_t *ctx, const void *data,
                          const char *arg1, const char *arg2)
    {
        return (APR_SUCCESS == apr_fnmatch(arg2, arg1, APR_FNM_PATHNAME));
    }
    
    static int op_strmatch(ap_expr_eval_ctx_t *ctx, const void *data,
                           const char *arg1, const char *arg2)
    {
        return (APR_SUCCESS == apr_fnmatch(arg2, arg1, 0));
    }
    
    static int op_strcmatch(ap_expr_eval_ctx_t *ctx, const void *data,
                            const char *arg1, const char *arg2)
    {
        return (APR_SUCCESS == apr_fnmatch(arg2, arg1, APR_FNM_CASE_BLIND));
    }
    
    struct expr_provider_single {
        const void *func;
        const char *name;
        ap_expr_lookup_fn_t *arg_parsing_func;
        int restricted;
    };
    
    struct expr_provider_multi {
        const void *func;
        const char *const *names;
    };
    
    static const struct expr_provider_multi var_providers[] = {
        { misc_var_fn, misc_var_names },
        { req_header_var_fn, req_header_var_names },
        { request_var_fn, request_var_names },
        { conn_var_fn, conn_var_names },
        { NULL, NULL }
    };
    
    static const struct expr_provider_single string_func_providers[] = {
        { osenv_func,           "osenv",          NULL, 0 },
        { env_func,             "env",            NULL, 0 },
        { req_table_func,       "resp",           NULL, 0 },
        { req_table_func,       "req",            NULL, 0 },
        /* 'http' as alias for 'req' for compatibility with ssl_expr */
        { req_table_func,       "http",           NULL, 0 },
        { req_table_func,       "note",           NULL, 0 },
        { req_table_func,       "reqenv",         NULL, 0 },
        { req_table_func,       "req_novary",     NULL, 0 },
        { tolower_func,         "tolower",        NULL, 0 },
        { toupper_func,         "toupper",        NULL, 0 },
        { escape_func,          "escape",         NULL, 0 },
        { unescape_func,        "unescape",       NULL, 0 },
        { file_func,            "file",           NULL, 1 },
        { filesize_func,        "filesize",       NULL, 1 },
        { base64_func,          "base64",         NULL, 0 },
        { unbase64_func,        "unbase64",       NULL, 0 },
        { sha1_func,            "sha1",           NULL, 0 },
        { md5_func,             "md5",            NULL, 0 },
    #if APR_VERSION_AT_LEAST(1,6,0)
        { ldap_func,            "ldap",           NULL, 0 },
    #endif
        { NULL, NULL, NULL}
    };
    
    static const struct expr_provider_single unary_op_providers[] = {
        { op_nz,        "n", NULL,             0 },
        { op_nz,        "z", NULL,             0 },
        { op_R,         "R", subnet_parse_arg, 0 },
        { op_T,         "T", NULL,             0 },
        { op_file_min,  "d", NULL,             1 },
        { op_file_min,  "e", NULL,             1 },
        { op_file_min,  "f", NULL,             1 },
        { op_file_min,  "s", NULL,             1 },
        { op_file_link, "L", NULL,             1 },
        { op_file_link, "h", NULL,             1 },
        { op_file_xbit, "x", NULL,             1 },
        { op_file_subr, "F", NULL,             0 },
        { op_url_subr,  "U", NULL,             0 },
        { op_url_subr,  "A", NULL,             0 },
        { NULL, NULL, NULL }
    };
    
    static const struct expr_provider_single binary_op_providers[] = {
        { op_ipmatch,   "ipmatch",      subnet_parse_arg, 0 },
        { op_fnmatch,   "fnmatch",      NULL,             0 },
        { op_strmatch,  "strmatch",     NULL,             0 },
        { op_strcmatch, "strcmatch",    NULL,             0 },
        { NULL, NULL, NULL }
    };
    
    static int core_expr_lookup(ap_expr_lookup_parms *parms)
    {
        switch (parms->type) {
        case AP_EXPR_FUNC_VAR: {
                const struct expr_provider_multi *prov = var_providers;
                while (prov->func) {
                    const char *const *name = prov->names;
                    while (*name) {
                        if (ap_cstr_casecmp(*name, parms->name) == 0) {
                            *parms->func = prov->func;
                            *parms->data = name;
                            return OK;
                        }
                        name++;
                    }
                    prov++;
                }
            }
            break;
        case AP_EXPR_FUNC_STRING:
        case AP_EXPR_FUNC_OP_UNARY:
        case AP_EXPR_FUNC_OP_BINARY: {
                const struct expr_provider_single *prov = NULL;
                switch (parms->type) {
                case AP_EXPR_FUNC_STRING:
                    prov = string_func_providers;
                    break;
                case AP_EXPR_FUNC_OP_UNARY:
                    prov = unary_op_providers;
                    break;
                case AP_EXPR_FUNC_OP_BINARY:
                    prov = binary_op_providers;
                    break;
                default:
                    ap_assert(0);
                }
                while (prov && prov->func) {
                    int match;
                    if (parms->type == AP_EXPR_FUNC_OP_UNARY)
                        match = !strcmp(prov->name, parms->name);
                    else
                        match = !ap_cstr_casecmp(prov->name, parms->name);
                    if (match) {
                        if ((parms->flags & AP_EXPR_FLAG_RESTRICTED)
                            && prov->restricted) {
                            *parms->err =
                                apr_psprintf(parms->ptemp,
                                             "%s%s not available in restricted context",
                                             (parms->type == AP_EXPR_FUNC_STRING) ? "" : "-",
                                             prov->name);
                            return !OK;
                        }
                        *parms->func = prov->func;
                        if (prov->arg_parsing_func) {
                            return prov->arg_parsing_func(parms);
                        }
                        else {
                            *parms->data = prov->name;
                            return OK;
                        }
                    }
                    prov++;
                }
            }
            break;
        default:
            break;
        }
        return DECLINED;
    }
    
    static int expr_lookup_not_found(ap_expr_lookup_parms *parms)
    {
        const char *type;
        const char *prefix = "";
    
        switch (parms->type) {
        case AP_EXPR_FUNC_VAR:
            type = "Variable";
            break;
        case AP_EXPR_FUNC_STRING:
            type = "Function";
            break;
        case AP_EXPR_FUNC_LIST:
            type = "List-returning function";
            break;
        case AP_EXPR_FUNC_OP_UNARY:
            type = "Unary operator";
            break;
        case AP_EXPR_FUNC_OP_BINARY:
            type = "Binary operator";
            break;
        default:
            *parms->err = "Invalid expression type in expr_lookup";
            return !OK;
        }
        if (   parms->type == AP_EXPR_FUNC_OP_UNARY
            || parms->type == AP_EXPR_FUNC_OP_BINARY) {
            prefix = "-";
        }
        *parms->err = apr_psprintf(parms->ptemp, "%s '%s%s' does not exist", type,
                                   prefix, parms->name);
        return !OK;
    }
    
    static int ap_expr_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                   apr_pool_t *ptemp, server_rec *s)
    {
        is_http2 = APR_RETRIEVE_OPTIONAL_FN(http2_is_h2);
        return OK;
    }
    
    void ap_expr_init(apr_pool_t *p)
    {
        ap_hook_expr_lookup(core_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_expr_lookup(expr_lookup_not_found, NULL, NULL, APR_HOOK_REALLY_LAST);
        ap_hook_post_config(ap_expr_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    �����������������������������������������������������httpd-2.4.64/server/util_script.c�������������������������������������������������������������������0000664�0001751�0001751�00000100664�14737240630�016652� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <stdlib.h>
    #endif
    
    #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 <os2.h>
    #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 dependencies
     * where there don't have to be).
     */
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    static char *http2env(request_rec *r, const char *w)
    {
        char *res = (char *)apr_palloc(r->pool, 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++ = apr_toupper(c);
            }
            else if (c == '-') {
                *cp++ = '_';
            }
            else {
                if (APLOGrtrace1(r))
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                "Not exporting header with invalid name as envvar: %s",
                                ap_escape_logitem(r->pool, w));
                return NULL;
            }
        }
        *cp = 0;
    
        return res;
    }
    
    static void add_unless_null(apr_table_t *table, const char *name, const char *val)
    {
        if (name && val) {
            apr_table_addn(table, name, val);
        }
    }
    
    /* Sets variable @name in table @dest from r->subprocess_env if
     * available, else from the environment, else from @fallback if
     * non-NULL. */
    static void env2env(apr_table_t *dest, request_rec *r,
                        const char *name, const char *fallback)
    {
        const char *val;
    
        val = apr_table_get(r->subprocess_env, name);
        if (!val)
            val = apr_pstrdup(r->pool, getenv(name));
        if (!val)
            val = apr_pstrdup(r->pool, fallback);
        if (val)
            apr_table_addn(dest, name, val);
    }
    
    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 != '=') {
    #ifdef WIN32
                if (!apr_isalnum(*whack) && *whack != '(' && *whack != ')') {
    #else
                if (!apr_isalnum(*whack)) {
    #endif
                    *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;
        core_dir_config *conf =
            (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
        const char *env_temp;
        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;
        char *q;
    
        /* 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 (!ap_cstr_casecmp(hdrs[i].key, "Content-type")) {
                apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
            }
            else if (!ap_cstr_casecmp(hdrs[i].key, "Content-length")) {
                apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
            }
            /* HTTP_PROXY collides with a popular envvar used to configure
             * proxies, don't let clients set/override it.  But, if you must...
             */
    #ifndef SECURITY_HOLE_PASS_PROXY
            else if (!ap_cstr_casecmp(hdrs[i].key, "Proxy")) {
                ;
            }
    #endif
            /*
             * 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 (!ap_cstr_casecmp(hdrs[i].key, "Authorization")
                     || !ap_cstr_casecmp(hdrs[i].key, "Proxy-Authorization")) {
                if (conf->cgi_pass_auth == AP_CGI_PASS_AUTH_ON) {
                    add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
                }
            }
    #endif
            else
                add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
        }
    
        env2env(e, r, "PATH", DEFAULT_PATH);
    #if defined(WIN32)
        env2env(e, r, "SystemRoot", NULL);
        env2env(e, r, "COMSPEC", NULL);
        env2env(e, r, "PATHEXT", NULL);
        env2env(e, r, "WINDIR", NULL);
    #elif defined(OS2)
        env2env(e, r, "COMSPEC", NULL);
        env2env(e, r, "ETC", NULL);
        env2env(e, r, "DPATH", NULL);
        env2env(e, r, "PERLLIB_PREFIX", NULL);
    #elif defined(BEOS)
        env2env(e, r, "LIBRARY_PATH", NULL);
    #elif defined(DARWIN)
        env2env(e, r, "DYLD_LIBRARY_PATH", NULL);
    #elif defined(_AIX)
        env2env(e, r, "LIBPATH", NULL);
    #elif defined(__HPUX__)
        /* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
        env2env(e, r, "SHLIB_PATH", NULL);
        env2env(e, r, "LD_LIBRARY_PATH", NULL);
    #else /* Some Unix */
        env2env(e, r, "LD_LIBRARY_PATH", NULL);
    #endif
    
        apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
        apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_banner());
        apr_table_addn(e, "SERVER_NAME",
                       ap_escape_html(r->pool, ap_get_server_name_for_url(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)));
        add_unless_null(e, "REMOTE_HOST",
                        ap_get_useragent_host(r, REMOTE_HOST, NULL));
        apr_table_addn(e, "REMOTE_ADDR", r->useragent_ip);
        apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));    /* Apache */
        apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r));
        apr_table_addn(e, "CONTEXT_PREFIX", ap_context_prefix(r));
        apr_table_addn(e, "CONTEXT_DOCUMENT_ROOT", ap_context_document_root(r));
        apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
        if (apr_table_get(r->notes, "proxy-noquery") && (q = ap_strchr(r->filename, '?'))) {
            char *script_filename = apr_pstrmemdup(r->pool, r->filename, q - r->filename);
            apr_table_addn(e, "SCRIPT_FILENAME", script_filename);
        }
        else {
            apr_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */
        }
    
        rport = c->client_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;
            }
        }
        add_unless_null(e, "AUTH_TYPE", r->ap_auth_type);
        env_temp = ap_get_remote_logname(r);
        if (env_temp) {
            apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, env_temp));
        }
    
        /* Apache custom error responses. If we have redirected set two new vars */
    
        if (r->prev) {
            if (conf->qualify_redirect_url != AP_CORE_CONFIG_ON) { 
                add_unless_null(e, "REDIRECT_URL", r->prev->uri);
            }
            else { 
                /* PR#57785: reconstruct full URL here */
                apr_uri_t *uri = &r->prev->parsed_uri;
                if (!uri->scheme) {
                    uri->scheme = (char*)ap_http_scheme(r->prev);
                }
                if (!uri->port) {
                    uri->port = ap_get_server_port(r->prev);
                    uri->port_str = apr_psprintf(r->pool, "%u", uri->port);
                }
                if (!uri->hostname) {
                    uri->hostname = (char*)ap_get_server_name_for_url(r->prev);
                }
                add_unless_null(e, "REDIRECT_URL",
                                apr_uri_unparse(r->pool, uri, 0));
            }
            add_unless_null(e, "REDIRECT_QUERY_STRING", r->prev->args);
        }
    
        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 (path_info[lp] == '/') {
                while (lu && uri[lu-1] == '/') lu--;
            }
        }
    
        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;
        core_dir_config *conf =
            (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
        int request_uri_from_original = 1;
        const char *request_uri_rule;
    
        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 : "");
    
        if (conf->cgi_var_rules) {
            request_uri_rule = apr_hash_get(conf->cgi_var_rules, "REQUEST_URI",
                                            APR_HASH_KEY_STRING);
            if (request_uri_rule && !strcmp(request_uri_rule, "current-uri")) {
                request_uri_from_original = 0;
            }
        }
        apr_table_setn(e, "REQUEST_URI",
                       request_uri_from_original ? original_uri(r) : r->uri);
    
        /* 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;
    }
    
    #define HTTP_UNSET (-HTTP_OK)
    #define SCRIPT_LOG_MARK  __FILE__,__LINE__,module_index
    
    AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer,
                                           int (*getsfunc) (char *, int, void *),
                                           void *getsfunc_data,
                                           int module_index)
    {
        char x[MAX_STRING_LEN];
        char *w, *l;
        apr_size_t p;
        int cgi_status = HTTP_UNSET;
        apr_table_t *merge;
        apr_table_t *cookie_table;
        int trace_log = APLOG_R_MODULE_IS_LEVEL(r, module_index, APLOG_TRACE1);
        int first_header = 1;
    
        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) {
    
            int rv = (*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data);
            if (rv == 0) {
                const char *msg = "Premature end of script headers";
                if (first_header)
                    msg = "End of script output before headers";
                /* Intentional no APLOGNO */
                ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r,
                              "%s: %s", msg,
                              apr_filepath_name_get(r->filename));
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            else if (rv == -1) {
                /* Intentional no APLOGNO */
                ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r,
                              "Script timed out before returning headers: %s",
                              apr_filepath_name_get(r->filename));
                return HTTP_GATEWAY_TIME_OUT;
            }
    
            /* 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;
    
                /* PR#38070: This fails because it gets confused when a
                 * CGI Status header overrides ap_meets_conditions.
                 *
                 * We can fix that by dropping ap_meets_conditions when
                 * Status has been set.  Since this is the only place
                 * cgi_status gets used, let's test it explicitly.
                 *
                 * The alternative would be to ignore CGI Status when
                 * ap_meets_conditions returns anything interesting.
                 * That would be safer wrt HTTP, but would break CGI.
                 */
                if ((cgi_status == HTTP_UNSET) && (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 (trace_log) {
                if (first_header)
                    ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE4, 0, r,
                                  "Headers from script '%s':",
                                  apr_filepath_name_get(r->filename));
                ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE4, 0, r, "  %s", w);
            }
    
            /* 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(SCRIPT_LOG_MARK, APLOG_ERR, 0, r->server,
                                 APLOGNO(02660) "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, ':'))) {
                if (!buffer) {
                    /* Soak up all the script output - may save an outright kill */
                    while ((*getsfunc)(w, MAX_STRING_LEN - 1, getsfunc_data) > 0) {
                        continue;
                    }
                }
    
                /* Intentional no APLOGNO */
                ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r,
                              "malformed header from script '%s': Bad header: %.30s",
                              apr_filepath_name_get(r->filename), w);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            *l++ = '\0';
            while (apr_isspace(*l)) {
                ++l;
            }
    
            if (!ap_cstr_casecmp(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 (!ap_cstr_casecmp(w, "Status")) {
                r->status = cgi_status = atoi(l);
                if (!ap_is_HTTP_VALID_RESPONSE(cgi_status))
                    /* Intentional no APLOGNO */
                    ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r,
                                  "Invalid status line from script '%s': %.30s",
                                  apr_filepath_name_get(r->filename), l);
                else
                    if (APLOGrtrace1(r))
                       ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r,
                                     "Status line from script '%s': %.30s",
                                     apr_filepath_name_get(r->filename), l);
                r->status_line = apr_pstrdup(r->pool, l);
            }
            else if (!ap_cstr_casecmp(w, "Location")) {
                apr_table_set(r->headers_out, w, l);
            }
            else if (!ap_cstr_casecmp(w, "Content-Length")) {
                apr_table_set(r->headers_out, w, l);
            }
            else if (!ap_cstr_casecmp(w, "Content-Range")) {
                apr_table_set(r->headers_out, w, l);
            }
            else if (!ap_cstr_casecmp(w, "Transfer-Encoding")) {
                apr_table_set(r->headers_out, w, l);
            }
            else if (!ap_cstr_casecmp(w, "ETag")) {
                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 or invalid values.
             */
            else if (!ap_cstr_casecmp(w, "Last-Modified")) {
                apr_time_t parsed_date = apr_date_parse_http(l);
                if (parsed_date != APR_DATE_BAD) {
                    ap_update_mtime(r, parsed_date);
                    ap_set_last_modified(r);
                    if (APLOGrtrace1(r)) {
                        apr_time_t last_modified_date = apr_date_parse_http(apr_table_get(r->headers_out,
                                                                                          "Last-Modified"));
                        /*
                         * A Last-Modified header value coming from a (F)CGI source
                         * is considered HTTP input so we assume the GMT timezone.
                         * The following logs should inform the admin about violations
                         * and related actions taken by httpd.
                         * The apr_date_parse_rfc function is 'timezone aware'
                         * and it will be used to generate a more informative set of logs
                         * (we don't use it as a replacement of apr_date_parse_http
                         * for the aforementioned reason).
                         */
                        apr_time_t parsed_date_tz_aware = apr_date_parse_rfc(l);
    
                        /* 
                         * The parsed Last-Modified header datestring has been replaced by httpd.
                         */
                        if (parsed_date > last_modified_date) {
                            ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r,
                                          "The Last-Modified header value %s (%s) "
                                          "has been replaced with '%s'", l,
                                          parsed_date != parsed_date_tz_aware ? "not in GMT"
                                                                              : "in the future",
                                          apr_table_get(r->headers_out, "Last-Modified"));
                        /* 
                         * Last-Modified header datestring not in GMT and not considered in the future
                         * by httpd (like now() + 1 hour in the PST timezone). No action is taken but
                         * the admin is warned about the violation.
                         */
                        } else if (parsed_date != parsed_date_tz_aware) {
                            ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r,
                                          "The Last-Modified header value is not set "
                                          "within the GMT timezone (as required)");
                        }
                    }
                }
                else {
                    ap_log_rerror(SCRIPT_LOG_MARK, APLOG_INFO, 0, r, APLOGNO(10247)
                                  "Ignored invalid header value: Last-Modified: '%s'", l);
                }
            }
            else if (!ap_cstr_casecmp(w, "Set-Cookie")) {
                apr_table_add(cookie_table, w, l);
            }
            else {
                apr_table_add(merge, w, l);
            }
            first_header = 0;
        }
        /* never reached - we leave this function within the while loop above */
        return OK;
    }
    
    AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer,
                                           int (*getsfunc) (char *, int, void *),
                                           void *getsfunc_data)
    {
        return ap_scan_script_header_err_core_ex(r, buffer, getsfunc,
                                                 getsfunc_data,
                                                 APLOG_MODULE_INDEX);
    }
    
    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_ex(r, buffer, getsfunc_FILE, f,
                                                 APLOG_MODULE_INDEX);
    }
    
    AP_DECLARE(int) ap_scan_script_header_err_ex(request_rec *r, apr_file_t *f,
                                              char *buffer, int module_index)
    {
        return ap_scan_script_header_err_core_ex(r, buffer, getsfunc_FILE, f,
                                                 module_index);
    }
    
    
    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 && e != APR_BRIGADE_SENTINEL(bb)
               && !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)) {
                *dst = '\0';
                return APR_STATUS_IS_TIMEUP(rv) ? -1 : 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_delete(e);
            e = next;
        }
        *dst = 0;
        return done;
    }
    
    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_ex(r, buffer, getsfunc_BRIGADE, bb,
                                                 APLOG_MODULE_INDEX);
    }
    
    AP_DECLARE(int) ap_scan_script_header_err_brigade_ex(request_rec *r,
                                                         apr_bucket_brigade *bb,
                                                         char *buffer,
                                                         int module_index)
    {
        return ap_scan_script_header_err_core_ex(r, buffer, getsfunc_BRIGADE, bb,
                                                 module_index);
    }
    
    
    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;
        apr_size_t t;
    
        if (!strs->curpos || !*strs->curpos) {
            w[0] = '\0';
            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_ex(request_rec *r,
                                                             char *buffer,
                                                             int module_index,
                                                             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_ex(r, buffer, getsfunc_STRING,
                                                (void *) &strs, module_index);
        if (termch)
            *termch = strs.curpos;
        if (termarg)
            *termarg = strs.arg;
        va_end(strs.args);
        return res;
    }
    
    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_ex(r, buffer, getsfunc_STRING,
                                                (void *) &strs, APLOG_MODULE_INDEX);
        if (termch)
            *termch = strs.curpos;
        if (termarg)
            *termarg = strs.arg;
        va_end(strs.args);
        return res;
    }
    
    static void
    argstr_to_table(char *str, apr_table_t *parms)
    {
        char *key;
        char *value;
        char *strtok_state;
    
        if (str == NULL) {
            return;
        }
    
        key = apr_strtok(str, "&", &strtok_state);
        while (key) {
            value = strchr(key, '=');
            if (value) {
                *value = '\0';      /* Split the string in two */
                value++;            /* Skip passed the = */
            }
            else {
                value = "1";
            }
            ap_unescape_url(key);
            ap_unescape_url(value);
            apr_table_set(parms, key, value);
            key = apr_strtok(NULL, "&", &strtok_state);
        }
    }
    
    AP_DECLARE(void) ap_args_to_table(request_rec *r, apr_table_t **table)
    {
        apr_table_t *t = apr_table_make(r->pool, 10);
        argstr_to_table(apr_pstrdup(r->pool, r->args), t);
        *table = t;
    }
    ����������������������������������������������������������������������������httpd-2.4.64/server/core.c��������������������������������������������������������������������������0000664�0001751�0001751�00000571003�15032733516�015237� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_random.h"
    
    #include "apr_version.h"
    #if APR_MAJOR_VERSION < 2
    #include "apu_version.h"
    #endif
    
    #define APR_WANT_IOVEC
    #define APR_WANT_STRFUNC
    #define APR_WANT_MEMFUNC
    #include "apr_want.h"
    
    #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_ssl.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 "util_mutex.h"
    #include "util_time.h"
    #include "mpm_common.h"
    #include "scoreboard.h"
    #include "mod_core.h"
    #include "mod_proxy.h"
    #include "ap_listen.h"
    #include "ap_regex.h"
    
    #include "mod_so.h" /* for ap_find_loaded_module_symbol */
    
    #if defined(RLIMIT_CPU) || defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) || defined (RLIMIT_NPROC)
    #include "unixd.h"
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* LimitRequestBody handling */
    #define AP_LIMIT_REQ_BODY_UNSET         ((apr_off_t) -1)
    #define AP_DEFAULT_LIMIT_REQ_BODY       ((apr_off_t) 1<<30) /* 1GB */
    
    /* LimitXMLRequestBody handling */
    #define AP_LIMIT_UNSET                  ((long) -1)
    #define AP_DEFAULT_LIMIT_XML_BODY       ((apr_size_t)1000000)
    /* Hard limit for ap_escape_html2() */
    #define AP_MAX_LIMIT_XML_BODY           ((apr_size_t)(APR_SIZE_MAX / 6 - 1))
    
    #define AP_MIN_SENDFILE_BYTES           (256)
    
    /* maximum include nesting level */
    #ifndef AP_MAX_INCLUDE_DEPTH
    #define AP_MAX_INCLUDE_DEPTH            (128)
    #endif
    
    /* valid in core-conf, but not in runtime r->used_path_info */
    #define AP_ACCEPT_PATHINFO_UNSET 3
    
    #define AP_CONTENT_MD5_OFF   0
    #define AP_CONTENT_MD5_ON    1
    #define AP_CONTENT_MD5_UNSET 2
    
    #define AP_FLUSH_MAX_THRESHOLD 65535
    #define AP_FLUSH_MAX_PIPELINED 4
    
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(get_mgmt_items)
        APR_HOOK_LINK(insert_network_bucket)
        APR_HOOK_LINK(get_pollfd_from_conn)
    )
    
    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)
    
    AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, insert_network_bucket,
                                (conn_rec *c, apr_bucket_brigade *bb,
                                 apr_socket_t *socket),
                                (c, bb, socket), AP_DECLINED)
    
    AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, get_pollfd_from_conn,
                                (conn_rec *c, struct apr_pollfd_t *pfd,
                                 apr_interval_time_t *ptimeout),
                                  (c, pfd, ptimeout), APR_ENOTIMPL)
    
    /* 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., to handle just enough
     * to allow a server with the core module ONLY to actually serve documents.
     *
     * This file could almost be mod_core.c, except for the stuff which affects
     * the http_conf_globals.
     */
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    /* 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_core_input_filter_handle;
    
    /* Provide ap_document_root_check storage and default value = true */
    AP_DECLARE_DATA int ap_document_root_check = 1;
    
    /* magic pointer for ErrorDocument xxx "default" */
    static char errordocument_default;
    
    /* Global state allocated out of pconf: variables here MUST be
     * cleared/reset in reset_config(), a pconf cleanup, to avoid the
     * variable getting reused after the pool is cleared. */
    static apr_array_header_t *saved_server_config_defines = NULL;
    static apr_table_t *server_config_defined_vars = NULL;
    AP_DECLARE_DATA const char *ap_runtime_dir = NULL;
    
    AP_DECLARE_DATA int ap_main_state = AP_SQ_MS_INITIAL_STARTUP;
    AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN;
    AP_DECLARE_DATA int ap_config_generation = 0;
    
    static void *create_core_dir_config(apr_pool_t *a, char *dir)
    {
        core_dir_config *conf;
    
        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_SYM_LINKS;
        conf->opts_add = conf->opts_remove = OPT_NONE;
        conf->override = OR_UNSET|OR_NONE;
        conf->override_opts = OPT_UNSET | OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
    
        conf->content_md5 = AP_CONTENT_MD5_UNSET;
        conf->accept_path_info = AP_ACCEPT_PATHINFO_UNSET;
    
        conf->use_canonical_name = USE_CANONICAL_NAME_UNSET;
        conf->use_canonical_phys_port = USE_CANONICAL_PHYS_PORT_UNSET;
    
        conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET;
    
        /*
         * left as NULL (we use apr_pcalloc):
         * conf->limit_cpu = NULL;
         * conf->limit_mem = NULL;
         * conf->limit_nproc = NULL;
         * conf->sec_file = NULL;
         * conf->sec_if   = NULL;
         */
    
        conf->limit_req_body = AP_LIMIT_REQ_BODY_UNSET;
        conf->limit_xml_body = AP_LIMIT_UNSET;
    
        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
         * Set NULL by apr_pcalloc:
         * 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;
        conf->decode_encoded_slashes = 0;
    
        conf->max_ranges = AP_MAXRANGES_UNSET;
        conf->max_overlaps = AP_MAXRANGES_UNSET;
        conf->max_reversals = AP_MAXRANGES_UNSET;
    
        conf->cgi_pass_auth = AP_CGI_PASS_AUTH_UNSET;
        conf->qualify_redirect_url = AP_CORE_CONFIG_UNSET; 
    
        return (void *)conf;
    }
    
    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;
    
        /* Create this conf by duplicating the base, replacing elements
         * (or creating copies for merging) where new-> values exist.
         */
        conf = (core_dir_config *)apr_pmemdup(a, 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;
        conf->refs = new->refs;
        conf->condition = new->condition;
    
        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 Includes was enabled with exec in the base config, but
             * was enabled without exec in the new config, then disable
             * exec in the merged set. */
            if (((base->opts & (OPT_INCLUDES|OPT_INC_WITH_EXEC))
                 == (OPT_INCLUDES|OPT_INC_WITH_EXEC))
                && ((new->opts & (OPT_INCLUDES|OPT_INC_WITH_EXEC))
                    == OPT_INCLUDES)) {
                conf->opts &= ~OPT_INC_WITH_EXEC;
            }
        }
        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->override_list != NULL) {
            conf->override_list = new->override_list;
        }
    
        if (conf->response_code_exprs == NULL) {
            conf->response_code_exprs = new->response_code_exprs;
        }
        else if (new->response_code_exprs != NULL) {
            conf->response_code_exprs = apr_hash_overlay(a,
                    new->response_code_exprs, conf->response_code_exprs);
        }
        /* Otherwise we simply use the base->response_code_exprs array
         */
    
        if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET) {
            conf->hostname_lookups = new->hostname_lookups;
        }
    
        if (new->content_md5 != AP_CONTENT_MD5_UNSET) {
            conf->content_md5 = new->content_md5;
        }
    
        if (new->accept_path_info != AP_ACCEPT_PATHINFO_UNSET) {
            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;
        }
    
        if (new->use_canonical_phys_port != USE_CANONICAL_PHYS_PORT_UNSET) {
            conf->use_canonical_phys_port = new->use_canonical_phys_port;
        }
    
    #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;
    
        if (!conf->sec_file) {
            conf->sec_file = new->sec_file;
        }
        else if (new->sec_file) {
            /* If we merge, the merge-result must have its own array
             */
            conf->sec_file = apr_array_append(a, base->sec_file, new->sec_file);
        }
        /* Otherwise we simply use the base->sec_file array
         */
    
        if (!conf->sec_if) {
            conf->sec_if = new->sec_if;
        }
        else if (new->sec_if) {
            /* If we merge, the merge-result must have its own array
             */
            conf->sec_if = apr_array_append(a, base->sec_if, new->sec_if);
        }
        /* Otherwise we simply use the base->sec_if array
         */
    
        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->expr_handler) {
            conf->expr_handler = new->expr_handler;
        }
    
        if (new->output_filters) {
            conf->output_filters = new->output_filters;
        }
    
        if (new->input_filters) {
            conf->input_filters = new->input_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->etag_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;
        }
     
        if (new->read_buf_size) {
            conf->read_buf_size = new->read_buf_size;
        }
        else {
            conf->read_buf_size = base->read_buf_size;
        }
    
        conf->allow_encoded_slashes = new->allow_encoded_slashes;
        conf->decode_encoded_slashes = new->decode_encoded_slashes;
    
        if (new->log) {
            if (!conf->log) {
                conf->log = new->log;
            }
            else {
                conf->log = ap_new_log_config(a, new->log);
                ap_merge_log_config(base->log, conf->log);
            }
        }
    
        conf->max_ranges = new->max_ranges != AP_MAXRANGES_UNSET ? new->max_ranges : base->max_ranges;
        conf->max_overlaps = new->max_overlaps != AP_MAXRANGES_UNSET ? new->max_overlaps : base->max_overlaps;
        conf->max_reversals = new->max_reversals != AP_MAXRANGES_UNSET ? new->max_reversals : base->max_reversals;
    
        conf->cgi_pass_auth = new->cgi_pass_auth != AP_CGI_PASS_AUTH_UNSET ? new->cgi_pass_auth : base->cgi_pass_auth;
    
        if (new->cgi_var_rules) {
            if (!conf->cgi_var_rules) {
                conf->cgi_var_rules = new->cgi_var_rules;
            }
            else {
                conf->cgi_var_rules = apr_hash_overlay(a, new->cgi_var_rules, conf->cgi_var_rules);
            }
        }
    
        AP_CORE_MERGE_FLAG(qualify_redirect_url, conf, base, new);
    
        return (void*)conf;
    }
    
    #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
    #endif
    
    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));
    
        /* global-default / global-only settings */
    
        if (!is_virtual) {
            conf->ap_document_root = DOCUMENT_LOCATION;
            conf->access_name = DEFAULT_ACCESS_FNAME;
    
            /* A mapping only makes sense in the global context */
            conf->accf_map = apr_table_make(a, 5);
    #if APR_HAS_SO_ACCEPTFILTER
            apr_table_setn(conf->accf_map, "http", ACCEPT_FILTER_NAME);
            apr_table_setn(conf->accf_map, "https", "dataready");
    #elif defined(WIN32)
            /* 'data' is disabled on Windows due to a DoS vuln (PR 59970) */
            apr_table_setn(conf->accf_map, "http", "connect");
            apr_table_setn(conf->accf_map, "https", "connect");
    #else
            apr_table_setn(conf->accf_map, "http", "data");
            apr_table_setn(conf->accf_map, "https", "data");
    #endif
    
            conf->flush_max_threshold = AP_FLUSH_MAX_THRESHOLD;
            conf->flush_max_pipelined = AP_FLUSH_MAX_PIPELINED;
        }
        else {
            /* Use main ErrorLogFormat while the vhost is loading */
            core_server_config *main_conf =
                ap_get_core_module_config(ap_server_conf->module_config);
            conf->error_log_format = main_conf->error_log_format;
    
            conf->flush_max_pipelined = -1;
        }
    
        /* initialization, no special case for global context */
    
        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 *));
    
        /* pcalloc'ed - we have NULL's/0's
        conf->gprof_dir = NULL;
    
        ** recursion stopper; 0 == unset
        conf->redirect_limit = 0;
        conf->subreq_limit = 0;
    
        conf->protocol = NULL;
         */
    
        conf->trace_enable = AP_TRACE_UNSET;
    
        conf->protocols = apr_array_make(a, 5, sizeof(const char *));
        conf->protocols_honor_order = -1;
        conf->merge_slashes = AP_CORE_CONFIG_UNSET; 
        
        conf->strict_host_check= AP_CORE_CONFIG_UNSET; 
    
        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 = (core_server_config *)
                                   apr_pmemdup(p, base, sizeof(core_server_config));
    
        if (virt->ap_document_root)
            conf->ap_document_root = virt->ap_document_root;
    
        if (virt->access_name)
            conf->access_name = virt->access_name;
    
        /* XXX optimize to keep base->sec_ pointers if virt->sec_ array is empty */
        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);
    
        if (virt->redirect_limit)
            conf->redirect_limit = virt->redirect_limit;
    
        if (virt->subreq_limit)
            conf->subreq_limit = virt->subreq_limit;
    
        if (virt->trace_enable != AP_TRACE_UNSET)
            conf->trace_enable = virt->trace_enable;
    
        if (virt->http09_enable != AP_HTTP09_UNSET)
            conf->http09_enable = virt->http09_enable;
    
        if (virt->http_conformance != AP_HTTP_CONFORMANCE_UNSET)
            conf->http_conformance = virt->http_conformance;
    
        if (virt->http_methods != AP_HTTP_METHODS_UNSET)
            conf->http_methods = virt->http_methods;
    
        /* no action for virt->accf_map, not allowed per-vhost */
    
        if (virt->protocol)
            conf->protocol = virt->protocol;
    
        if (virt->gprof_dir)
            conf->gprof_dir = virt->gprof_dir;
    
        if (virt->error_log_format)
            conf->error_log_format = virt->error_log_format;
    
        if (virt->error_log_conn)
            conf->error_log_conn = virt->error_log_conn;
    
        if (virt->error_log_req)
            conf->error_log_req = virt->error_log_req;
    
        conf->merge_trailers = (virt->merge_trailers != AP_MERGE_TRAILERS_UNSET)
                               ? virt->merge_trailers
                               : base->merge_trailers;
    
        conf->protocols = ((virt->protocols->nelts > 0)? 
                           virt->protocols : base->protocols);
        conf->protocols_honor_order = ((virt->protocols_honor_order < 0)?
                                           base->protocols_honor_order :
                                           virt->protocols_honor_order);
        AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt);
        
    
        conf->flush_max_threshold = (virt->flush_max_threshold)
                                      ? virt->flush_max_threshold
                                      : base->flush_max_threshold;
        conf->flush_max_pipelined = (virt->flush_max_pipelined >= 0)
                                      ? virt->flush_max_pipelined
                                      : base->flush_max_pipelined;
    
        conf->strict_host_check = (virt->strict_host_check != AP_CORE_CONFIG_UNSET)
                                  ? virt->strict_host_check 
                                  : base->strict_host_check;
    
        AP_CORE_MERGE_FLAG(strict_host_check, conf, base, virt);
    
        return conf;
    }
    
    /* Add per-directory configuration entry (for <directory> 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_core_module_config(s->module_config);
        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_core_module_config(s->module_config);
        void **new_space = (void **)apr_array_push(sconf->sec_url);
    
        *new_space = url_config;
    }
    
    AP_CORE_DECLARE(void) ap_add_file_conf(apr_pool_t *p, core_dir_config *conf,
                                           void *url_config)
    {
        void **new_space;
    
        if (!conf->sec_file)
            conf->sec_file = apr_array_make(p, 2, sizeof(ap_conf_vector_t *));
    
        new_space = (void **)apr_array_push(conf->sec_file);
        *new_space = url_config;
    }
    
    AP_CORE_DECLARE(const char *) ap_add_if_conf(apr_pool_t *p,
                                                 core_dir_config *conf,
                                                 void *if_config)
    {
        void **new_space;
        core_dir_config *new = ap_get_module_config(if_config, &core_module);
    
        if (!conf->sec_if) {
            conf->sec_if = apr_array_make(p, 2, sizeof(ap_conf_vector_t *));
        }
        if (new->condition_ifelse & AP_CONDITION_ELSE) {
            int have_if = 0;
            if (conf->sec_if->nelts > 0) {
                core_dir_config *last;
                ap_conf_vector_t *lastelt = APR_ARRAY_IDX(conf->sec_if,
                                                          conf->sec_if->nelts - 1,
                                                          ap_conf_vector_t *);
                last = ap_get_module_config(lastelt, &core_module);
                if (last->condition_ifelse & AP_CONDITION_IF)
                    have_if = 1;
            }
            if (!have_if)
                return "<Else> or <ElseIf> section without previous <If> or "
                       "<ElseIf> section in same scope";
        }
    
        new_space = (void **)apr_array_push(conf->sec_if);
        *new_space = if_config;
        return NULL;
    }
    
    
    /* 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_core_module_config(a->elt);
        core_b = ap_get_core_module_config(b->elt);
    
        /* 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_core_module_config(s->module_config);
        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);
        apr_pool_tag(tmp, "core_reorder_directories");
        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_core_module_config(r->per_dir_config);
    
        return conf->opts;
    }
    
    AP_DECLARE(int) ap_allow_overrides(request_rec *r)
    {
        core_dir_config *conf;
        conf = (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
    
        return conf->override;
    }
    
    /*
     * Optional function coming from mod_authn_core, used for
     * retrieving the type of authorization
     */
    static APR_OPTIONAL_FN_TYPE(authn_ap_auth_type) *authn_ap_auth_type;
    
    AP_DECLARE(const char *) ap_auth_type(request_rec *r)
    {
        if (authn_ap_auth_type) {
            return authn_ap_auth_type(r);
        }
        return NULL;
    }
    
    /*
     * Optional function coming from mod_authn_core, used for
     * retrieving the authorization realm
     */
    static APR_OPTIONAL_FN_TYPE(authn_ap_auth_name) *authn_ap_auth_name;
    
    AP_DECLARE(const char *) ap_auth_name(request_rec *r)
    {
        if (authn_ap_auth_name) {
            return authn_ap_auth_name(r);
        }
        return NULL;
    }
    
    /*
     * Optional function coming from mod_access_compat, used to determine how
       access control interacts with authentication/authorization
     */
    static APR_OPTIONAL_FN_TYPE(access_compat_ap_satisfies) *access_compat_ap_satisfies;
    
    AP_DECLARE(int) ap_satisfies(request_rec *r)
    {
        if (access_compat_ap_satisfies) {
            return access_compat_ap_satisfies(r);
        }
        return SATISFY_NOSPEC;
    }
    
    AP_DECLARE(const char *) ap_document_root(request_rec *r) /* Don't use this! */
    {
        core_server_config *sconf;
        core_request_config *rconf = ap_get_core_module_config(r->request_config);
        if (rconf->document_root)
            return rconf->document_root;
        sconf = ap_get_core_module_config(r->server->module_config);
        return sconf->ap_document_root;
    }
    
    AP_DECLARE(const char *) ap_context_prefix(request_rec *r)
    {
        core_request_config *conf = ap_get_core_module_config(r->request_config);
        if (conf->context_prefix)
            return conf->context_prefix;
        else
            return "";
    }
    
    AP_DECLARE(const char *) ap_context_document_root(request_rec *r)
    {
        core_request_config *conf = ap_get_core_module_config(r->request_config);
        if (conf->context_document_root)
            return conf->context_document_root;
        else
            return ap_document_root(r);
    }
    
    AP_DECLARE(void) ap_set_document_root(request_rec *r, const char *document_root)
    {
        core_request_config *conf = ap_get_core_module_config(r->request_config);
        conf->document_root = document_root;
    }
    
    AP_DECLARE(void) ap_set_context_info(request_rec *r, const char *context_prefix,
                                         const char *context_document_root)
    {
        core_request_config *conf = ap_get_core_module_config(r->request_config);
        if (context_prefix)
            conf->context_prefix = context_prefix;
        if (context_document_root)
            conf->context_document_root = context_document_root;
    }
    
    /* 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 = ap_get_core_module_config(r->request_config);
        const char *err;
        const char *response;
        ap_expr_info_t *expr;
    
        /* check for string registered via ap_custom_response() first */
        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 = ap_get_core_module_config(r->per_dir_config);
    
        if (!dirconf->response_code_exprs) {
            return NULL;
        }
    
        expr = apr_hash_get(dirconf->response_code_exprs, &error_index,
                sizeof(error_index));
        if (!expr) {
            return NULL;
        }
    
        /* special token to indicate revert back to default */
        if ((char *) expr == &errordocument_default) {
            return NULL;
        }
    
        err = NULL;
        response = ap_expr_str_exec(r, expr, &err);
        if (err) {
            ap_log_rerror(
                    APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02841) "core: ErrorDocument: can't "
                    "evaluate require expression: %s", err);
            return NULL;
        }
    
        /* alas, duplication required as we return not-const */
        return apr_pstrdup(r->pool, response);
    }
    
    
    /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
    static APR_INLINE int do_double_reverse (int double_reverse,
                                             const char *remote_host,
                                             apr_sockaddr_t *client_addr,
                                             apr_pool_t *pool)
    {
        apr_sockaddr_t *sa;
        apr_status_t rv;
    
        if (double_reverse) {
            /* already done */
            return double_reverse;
        }
    
        if (remote_host == NULL || remote_host[0] == '\0') {
            /* single reverse failed, so don't bother */
            return -1;
        }
    
        rv = apr_sockaddr_info_get(&sa, remote_host, APR_UNSPEC, 0, 0, pool);
        if (rv == APR_SUCCESS) {
            while (sa) {
                if (apr_sockaddr_equal(sa, client_addr)) {
                    return 1;
                }
    
                sa = sa->next;
            }
        }
    
        return -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_core_module_config(dir_config))
                               ->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->client_addr, 0)
                == APR_SUCCESS) {
                ap_str_tolower(conn->remote_host);
    
                if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
                    conn->double_reverse = do_double_reverse(conn->double_reverse,
                                                             conn->remote_host,
                                                             conn->client_addr,
                                                             conn->pool);
                    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) {
            conn->double_reverse = do_double_reverse(conn->double_reverse,
                                                     conn->remote_host,
                                                     conn->client_addr, conn->pool);
            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->client_ip;
            }
        }
    }
    
    AP_DECLARE(const char *) ap_get_useragent_host(request_rec *r,
                                                   int type, int *str_is_ip)
    {
        conn_rec *conn = r->connection;
        int hostname_lookups;
        int ignored_str_is_ip;
    
        /* Guard here when examining the host before the read_request hook
         * has populated an r->useragent_addr
         */
        if (!r->useragent_addr || (r->useragent_addr == conn->client_addr)) {
            return ap_get_remote_host(conn, r->per_dir_config, type, str_is_ip);
        }
    
        if (!str_is_ip) { /* caller doesn't want to know */
            str_is_ip = &ignored_str_is_ip;
        }
        *str_is_ip = 0;
    
        hostname_lookups = ((core_dir_config *)
                            ap_get_core_module_config(r->per_dir_config))
                                ->hostname_lookups;
        if (hostname_lookups == HOSTNAME_LOOKUP_UNSET) {
            hostname_lookups = HOSTNAME_LOOKUP_OFF;
        }
    
        if (type != REMOTE_NOLOOKUP
            && r->useragent_host == NULL
            && (type == REMOTE_DOUBLE_REV
            || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
    
            if (apr_getnameinfo(&r->useragent_host, r->useragent_addr, 0)
                == APR_SUCCESS) {
                ap_str_tolower(r->useragent_host);
    
                if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
                    r->double_reverse = do_double_reverse(r->double_reverse,
                                                          r->useragent_host,
                                                          r->useragent_addr,
                                                          r->pool);
                    if (r->double_reverse != 1) {
                        r->useragent_host = NULL;
                    }
                }
            }
    
            /* if failed, set it to the NULL string to indicate error */
            if (r->useragent_host == NULL) {
                r->useragent_host = "";
            }
        }
    
        if (type == REMOTE_DOUBLE_REV) {
            r->double_reverse = do_double_reverse(r->double_reverse,
                                                  r->useragent_host,
                                                  r->useragent_addr, r->pool);
            if (r->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 (r->useragent_host != NULL && r->useragent_host[0] != '\0') {
            return r->useragent_host;
        }
        else {
            if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) {
                return NULL;
            }
            else {
                *str_is_ip = 1;
                return r->useragent_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.
     *
     * 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;
        const char *retval;
    
        d = (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
    
        switch (d->use_canonical_name) {
            case USE_CANONICAL_NAME_ON:
                retval = r->server->server_hostname;
                break;
            case 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);
                    }
                }
                retval = conn->local_host;
                break;
            case USE_CANONICAL_NAME_OFF:
            case USE_CANONICAL_NAME_UNSET:
                retval = r->hostname ? r->hostname : r->server->server_hostname;
                break;
            default:
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00109)
                             "ap_get_server_name: Invalid UCN Option somehow");
                retval = "localhost";
                break;
        }
        return retval;
    }
    
    /*
     * 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]").
     */
    AP_DECLARE(const char *) ap_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_pstrcat(r->pool, "[", plain_server_name, "]", NULL);
        }
    #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_core_module_config(r->per_dir_config);
    
        switch (d->use_canonical_name) {
            case USE_CANONICAL_NAME_OFF:
            case USE_CANONICAL_NAME_DNS:
            case USE_CANONICAL_NAME_UNSET:
                if (d->use_canonical_phys_port == USE_CANONICAL_PHYS_PORT_ON)
                    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 /* USE_CANONICAL_PHYS_PORT_OFF or USE_CANONICAL_PHYS_PORT_UNSET */
                    port = r->parsed_uri.port_str ? r->parsed_uri.port :
                           r->server->port ? r->server->port :
                           ap_default_port(r);
                break;
            case 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.
                 */
                if (d->use_canonical_phys_port == USE_CANONICAL_PHYS_PORT_ON)
                    port = r->server->port ? r->server->port :
                           r->connection->local_addr->port ? r->connection->local_addr->port :
                           ap_default_port(r);
                else /* USE_CANONICAL_PHYS_PORT_OFF or USE_CANONICAL_PHYS_PORT_UNSET */
                    port = r->server->port ? r->server->port :
                           ap_default_port(r);
                break;
            default:
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00110)
                             "ap_get_server_port: Invalid UCN Option somehow");
                port = ap_default_port(r);
                break;
        }
    
        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 = ap_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_core_module_config(r->per_dir_config);
    
        if (d->limit_req_body == AP_LIMIT_REQ_BODY_UNSET) {
            return AP_DEFAULT_LIMIT_REQ_BODY;
        }
    
        return d->limit_req_body;
    }
    
    AP_DECLARE(apr_size_t) ap_get_read_buf_size(const request_rec *r)
    {
        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
    
        return d->read_buf_size ? d->read_buf_size : AP_IOBUFSIZE;
    }
    
    
    /*****************************************************************
     *
     * Commands... this module handles almost all of the NCSA httpd.conf
     * commands, but most of the old srm.conf is in 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 (ap_cstr_casecmp(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 <VirtualHost> section", NULL);
        }
    
        if ((forbidden & NOT_IN_DIR_CONTEXT) && cmd->limited != -1) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
                               " cannot occur within <Limit> or <LimitExcept> "
                               "section", NULL);
        }
    
        if ((forbidden & NOT_IN_HTACCESS) && (cmd->pool == cmd->temp_pool)) {
             return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
                                " cannot occur within htaccess files", 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 directory context", 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, "<Directory"))
                 || (found = find_parent(cmd->directive, "<DirectoryMatch"))))
            || ((forbidden & NOT_IN_LOCATION)
                && ((found = find_parent(cmd->directive, "<Location"))
                    || (found = find_parent(cmd->directive, "<LocationMatch"))))
            || ((forbidden & NOT_IN_FILES)
                && ((found = find_parent(cmd->directive, "<Files"))
                    || (found = find_parent(cmd->directive, "<FilesMatch"))
                    || (found = find_parent(cmd->directive, "<If"))
                    || (found = find_parent(cmd->directive, "<ElseIf"))
                    || (found = find_parent(cmd->directive, "<Else"))))
            || ((forbidden & NOT_IN_PROXY)
                && ((found = find_parent(cmd->directive, "<Proxy"))
                    || (found = find_parent(cmd->directive, "<ProxyMatch"))))) {
            return apr_pstrcat(cmd->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_core_module_config(sconf);
    
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        if (err != NULL) {
            return err;
        }
    
        conf->access_name = apr_pstrdup(cmd->pool, arg);
        return NULL;
    }
    
    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+2, '}'))) {
                    char *name = apr_pstrmemdup(p, s+2, e-s-2);
                    word = NULL;
                    if (server_config_defined_vars)
                        word = apr_table_get(server_config_defined_vars, name);
                    if (!word)
                        word = apr_pstrdup(p, getenv(name));
                    if (word) {
                        current->string = word;
                        current->len = strlen(word);
                        outlen += current->len;
                    }
                    else {
                        if (ap_strchr(name, ':') == 0)
                            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(00111)
                                         "Config variable ${%s} is not defined",
                                         name);
                        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;
    }
    
    static int reset_config_defines(void *dummy)
    {
        ap_server_config_defines = saved_server_config_defines;
        saved_server_config_defines = NULL;
        server_config_defined_vars = NULL;
        ap_runtime_dir = NULL;
        return OK;
    }
    
    /*
     * Make sure we can revert the effects of Define/UnDefine when restarting.
     * This function must be called once per loading of the config, before
     * ap_server_config_defines is changed. This may be during reading of the
     * config, which is even before the pre_config hook is run (due to
     * EXEC_ON_READ for Define/UnDefine).
     */
    static void init_config_defines(apr_pool_t *pconf)
    {
        saved_server_config_defines = ap_server_config_defines;
        /* Use apr_array_copy instead of apr_array_copy_hdr because it does not
         * protect from the way unset_define removes entries.
         */
        ap_server_config_defines = apr_array_copy(pconf, ap_server_config_defines);
    }
    
    static const char *set_define(cmd_parms *cmd, void *dummy,
                                  const char *name, const char *value)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return err;
        if (ap_strchr_c(name, ':') != NULL) {
            return "Variable name must not contain ':'";
        }
    
        if (!saved_server_config_defines) {
            init_config_defines(cmd->pool);
        }
        if (!ap_exists_config_define(name)) {
            *(const char **)apr_array_push(ap_server_config_defines) = name;
        }
        if (value) {
            if (!server_config_defined_vars) {
                server_config_defined_vars = apr_table_make(cmd->pool, 5);
            }
            apr_table_setn(server_config_defined_vars, name, value);
        }
    
        return NULL;
    }
    
    static const char *unset_define(cmd_parms *cmd, void *dummy,
                                    const char *name)
    {
        int i;
        const char **defines;
        const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
        if (err)
            return err;
        if (ap_strchr_c(name, ':') != NULL) {
            return "Variable name must not contain ':'";
        }
    
        if (!saved_server_config_defines) {
            init_config_defines(cmd->pool);
        }
    
        defines = (const char **)ap_server_config_defines->elts;
        for (i = 0; i < ap_server_config_defines->nelts; i++) {
            if (strcmp(defines[i], name) == 0) {
                defines[i] = *(const char **)apr_array_pop(ap_server_config_defines);
                break;
            }
        }
    
        if (server_config_defined_vars) {
            apr_table_unset(server_config_defined_vars, name);
        }
    
        return NULL;
    }
    
    static const char *generate_error(cmd_parms *cmd, void *dummy,
                                      const char *arg)
    {
        if (!arg || !*arg) {
            return "The Error directive was used with no message.";
        }
    
        if (*arg == '"' || *arg == '\'') { /* strip off quotes */
            apr_size_t len = strlen(arg);
            char last = *(arg + len - 1);
    
            if (*arg == last) {
                return apr_pstrndup(cmd->pool, arg + 1, len - 2);
            }
        }
    
        return arg;
    }
    
    #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_core_module_config(sconf);
    
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        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_;
    
        if (!ap_cstr_casecmp(arg, "Off")) {
           d->add_default_charset = ADD_DEFAULT_CHARSET_OFF;
        }
        else if (!ap_cstr_casecmp(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_core_module_config(sconf);
    
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        if (err != NULL) {
            return err;
        }
    
        /* When ap_document_root_check is false; skip all the stuff below */
        if (!ap_document_root_check) {
           conf->ap_document_root = arg;
           return NULL;
        }
    
        /* Make it absolute, relative to ServerRoot */
        arg = ap_server_root_relative(cmd->pool, arg);
        if (arg == NULL) {
            return "DocumentRoot must be a directory";
        }
    
        /* TODO: ap_configtestonly */
        if (apr_filepath_merge((char**)&conf->ap_document_root, NULL, arg,
                               APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS
            || !ap_is_directory(cmd->temp_pool, arg)) {
            if (cmd->server->is_virtual) {
                ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0,
                              cmd->pool, APLOGNO(00112)
                              "Warning: DocumentRoot [%s] does not exist",
                              arg);
                conf->ap_document_root = arg;
            }
            else {
                return apr_psprintf(cmd->pool, 
                                    "DocumentRoot '%s' is not a directory, or is not readable",
                                    arg);
            }
        }
        return NULL;
    }
    
    AP_DECLARE(void) ap_custom_response(request_rec *r, int status,
                                        const char *string)
    {
        core_request_config *conf = ap_get_core_module_config(r->request_config);
        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;
    
        /* 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, APLOGNO(00113)
                         "%s:%d cannot use a full URL in a 401 ErrorDocument "
                         "directive --- ignoring!", cmd->directive->filename, cmd->directive->line_num);
        }
        else { /* Store it... */
            if (conf->response_code_exprs == NULL) {
                conf->response_code_exprs = apr_hash_make(cmd->pool);
            }
    
            if (ap_cstr_casecmp(msg, "default") == 0) {
                /* special case: ErrorDocument 404 default restores the
                 * canned server error response
                 */
                apr_hash_set(conf->response_code_exprs,
                        apr_pmemdup(cmd->pool, &index_number, sizeof(index_number)),
                        sizeof(index_number), &errordocument_default);
            }
            else {
                ap_expr_info_t *expr;
                const char *expr_err = NULL;
    
                /* 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.
                 */
                const char *response =
                        (what == MSG) ? apr_pstrcat(cmd->pool, "\"", msg, NULL) :
                                apr_pstrdup(cmd->pool, msg);
    
                expr = ap_expr_parse_cmd(cmd, response, AP_EXPR_FLAG_STRING_RESULT,
                        &expr_err, NULL);
    
                if (expr_err) {
                    return apr_pstrcat(cmd->temp_pool,
                                       "Cannot parse expression in ErrorDocument: ",
                                       expr_err, NULL);
                }
    
                apr_hash_set(conf->response_code_exprs,
                        apr_pmemdup(cmd->pool, &index_number, sizeof(index_number)),
                        sizeof(index_number), expr);
    
            }
        }
    
        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 (!ap_cstr_casecmp(w, "Indexes")) {
                opt = OPT_INDEXES;
            }
            else if (!ap_cstr_casecmp(w, "Includes")) {
                /* If Includes is permitted, both Includes and
                 * IncludesNOEXEC may be changed. */
                opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC);
            }
            else if (!ap_cstr_casecmp(w, "IncludesNOEXEC")) {
                opt = OPT_INCLUDES;
            }
            else if (!ap_cstr_casecmp(w, "FollowSymLinks")) {
                opt = OPT_SYM_LINKS;
            }
            else if (!ap_cstr_casecmp(w, "SymLinksIfOwnerMatch")) {
                opt = OPT_SYM_OWNER;
            }
            else if (!ap_cstr_casecmp(w, "ExecCGI")) {
                opt = OPT_EXECCGI;
            }
            else if (!ap_cstr_casecmp(w, "MultiViews")) {
                opt = OPT_MULTI;
            }
            else if (!ap_cstr_casecmp(w, "RunScripts")) { /* AI backcompat. Yuck */
                opt = OPT_MULTI|OPT_EXECCGI;
            }
            else if (!ap_cstr_casecmp(w, "None")) {
                opt = OPT_NONE;
            }
            else if (!ap_cstr_casecmp(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;
    
        /* Throw a warning if we're in <Location> or <Files> */
        if (ap_check_cmd_context(cmd, NOT_IN_LOCATION | NOT_IN_FILES)) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00114)
                         "Useless use of AllowOverride in line %d of %s.",
                         cmd->directive->line_num, cmd->directive->filename);
        }
        if ((err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS)) != NULL)
            return err;
    
        d->override = OR_NONE;
        while (l[0]) {
            w = ap_getword_conf(cmd->temp_pool, &l);
    
            k = w;
            v = strchr(k, '=');
            if (v) {
                    *v++ = '\0';
            }
    
            if (!ap_cstr_casecmp(w, "Limit")) {
                d->override |= OR_LIMIT;
            }
            else if (!ap_cstr_casecmp(k, "Options")) {
                d->override |= OR_OPTIONS;
                if (v) {
                    if ((err = set_allow_opts(cmd, &(d->override_opts), v)) != NULL)
                        return err;
                }
                else
                    d->override_opts = OPT_ALL;
            }
            else if (!ap_cstr_casecmp(w, "FileInfo")) {
                d->override |= OR_FILEINFO;
            }
            else if (!ap_cstr_casecmp(w, "AuthConfig")) {
                d->override |= OR_AUTHCFG;
            }
            else if (!ap_cstr_casecmp(w, "Indexes")) {
                d->override |= OR_INDEXES;
            }
            else if (!ap_cstr_casecmp(w, "Nonfatal")) {
                if (!v) {
                    return apr_pstrcat(cmd->pool, "=Override, =Unknown or =All expected after ", w, NULL);
                }
                else if (!ap_cstr_casecmp(v, "Override")) {
                    d->override |= NONFATAL_OVERRIDE;
                }
                else if (!ap_cstr_casecmp(v, "Unknown")) {
                    d->override |= NONFATAL_UNKNOWN;
                }
                else if (!ap_cstr_casecmp(v, "All")) {
                    d->override |= NONFATAL_ALL;
                }
            }
            else if (!ap_cstr_casecmp(w, "None")) {
                d->override = OR_NONE;
            }
            else if (!ap_cstr_casecmp(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_cgi_pass_auth(cmd_parms *cmd, void *d_, int flag)
    {
        core_dir_config *d = d_;
    
        d->cgi_pass_auth = flag ? AP_CGI_PASS_AUTH_ON : AP_CGI_PASS_AUTH_OFF;
    
        return NULL;
    }
    
    static const char *set_cgi_var(cmd_parms *cmd, void *d_,
                                   const char *var, const char *rule_)
    {
        core_dir_config *d = d_;
        char *rule = apr_pstrdup(cmd->pool, rule_);
    
        ap_str_tolower(rule);
    
        if (!strcmp(var, "REQUEST_URI")) {
            if (strcmp(rule, "current-uri") && strcmp(rule, "original-uri")) {
                return "Valid rules for REQUEST_URI are 'current-uri' and 'original-uri'";
            }
        }
        else {
            return apr_pstrcat(cmd->pool, "Unrecognized CGI variable: \"",
                               var, "\"", NULL);
        }
    
        if (!d->cgi_var_rules) {
            d->cgi_var_rules = apr_hash_make(cmd->pool);
        }
        apr_hash_set(d->cgi_var_rules, var, APR_HASH_KEY_STRING, rule);
        return NULL;
    }
    
    static const char *set_qualify_redirect_url(cmd_parms *cmd, void *d_, int flag)
    {
        core_dir_config *d = d_;
    
        d->qualify_redirect_url = flag ? AP_CORE_CONFIG_ON : AP_CORE_CONFIG_OFF;
    
        return NULL;
    }
    
    static const char *set_core_server_flag(cmd_parms *cmd, void *s_, int flag)
    {
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
        return ap_set_flag_slot(cmd, conf, flag);
    }
    
    static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
    {
        core_dir_config *d = d_;
        int i;
        const char *err;
    
        /* Throw a warning if we're in <Location> or <Files> */
        if (ap_check_cmd_context(cmd, NOT_IN_LOCATION | NOT_IN_FILES)) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00115)
                         "Useless use of AllowOverrideList at %s:%d",
                         cmd->directive->filename, cmd->directive->line_num);
        }
        if ((err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS)) != NULL)
            return err;
    
        d->override_list = apr_table_make(cmd->pool, argc);
    
        for (i = 0; i < argc; i++) {
            if (!ap_cstr_casecmp(argv[i], "None")) {
                if (argc != 1) {
                    return "'None' not allowed with other directives in "
                           "AllowOverrideList";
                }
                return NULL;
            }
            else {
                const command_rec *result = NULL;
                module *mod = ap_top_module;
    
                result = ap_find_command_in_modules(argv[i], &mod);
                if (result == NULL) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
                                 APLOGNO(00116) "Discarding unrecognized "
                                 "directive `%s' in AllowOverrideList at %s:%d",
                                 argv[i], cmd->directive->filename,
                                 cmd->directive->line_num);
                    continue;
                }
                else if ((result->req_override & (OR_ALL|ACCESS_CONF)) == 0) {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
                                 APLOGNO(02304) "Discarding directive `%s' not "
                                 "allowed in AllowOverrideList at %s:%d",
                                 argv[i], cmd->directive->filename,
                                 cmd->directive->line_num);
                    continue;
                }
                else {
                    apr_table_setn(d->override_list, argv[i], "1");
                }
            }
        }
    
        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;
        int merge = 0;
        int all_none = 0;
        char action;
    
        while (l[0]) {
            char *w = ap_getword_conf(cmd->temp_pool, &l);
            action = '\0';
    
            if (*w == '+' || *w == '-') {
                action = *(w++);
                if (!merge && !first && !all_none) {
                    return "Either all Options must start with + or -, or no Option may.";
                }
                merge = 1;
            }
            else if (first) {
                d->opts = OPT_NONE;
            }
            else if (merge) {
                return "Either all Options must start with + or -, or no Option may.";
            }
    
            if (!ap_cstr_casecmp(w, "Indexes")) {
                opt = OPT_INDEXES;
            }
            else if (!ap_cstr_casecmp(w, "Includes")) {
                opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC);
            }
            else if (!ap_cstr_casecmp(w, "IncludesNOEXEC")) {
                opt = OPT_INCLUDES;
            }
            else if (!ap_cstr_casecmp(w, "FollowSymLinks")) {
                opt = OPT_SYM_LINKS;
            }
            else if (!ap_cstr_casecmp(w, "SymLinksIfOwnerMatch")) {
                opt = OPT_SYM_OWNER;
            }
            else if (!ap_cstr_casecmp(w, "ExecCGI")) {
                opt = OPT_EXECCGI;
            }
            else if (!ap_cstr_casecmp(w, "MultiViews")) {
                opt = OPT_MULTI;
            }
            else if (!ap_cstr_casecmp(w, "RunScripts")) { /* AI backcompat. Yuck */
                opt = OPT_MULTI|OPT_EXECCGI;
            }
            else if (!ap_cstr_casecmp(w, "None")) {
                if (!first) {
                    return "'Options None' must be the first Option given.";
                }
                else if (merge) { /* Only works since None may not follow any other option. */
                    return "You may not use 'Options +None' or 'Options -None'.";
                }
                opt = OPT_NONE;
                all_none = 1;
            }
            else if (!ap_cstr_casecmp(w, "All")) {
                if (!first) {
                    return "'Options All' must be the first option given.";
                }
                else if (merge) { /* Only works since All may not follow any other option. */
                    return "You may not use 'Options +All' or 'Options -All'.";
                }
                opt = OPT_ALL;
                all_none = 1;
            }
            else {
                return apr_pstrcat(cmd->pool, "Illegal option ", w, NULL);
            }
    
            if ( (cmd->override_opts & opt) != opt ) {
                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;
            }
    
            first = 0;
        }
    
        return NULL;
    }
    
    static const char *set_default_type(cmd_parms *cmd, void *d_,
                                       const char *arg)
    {
        if ((ap_cstr_casecmp(arg, "off") != 0) && (ap_cstr_casecmp(arg, "none") != 0)) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00117)
                  "Ignoring deprecated use of DefaultType in line %d of %s.",
                         cmd->directive->line_num, cmd->directive->filename);
        }
    
        return NULL;
    }
    
    static const char *set_sethandler(cmd_parms *cmd,
                                         void *d_,
                                         const char *arg_)
    {
        core_dir_config *dirconf = d_;
        const char *err;
        dirconf->expr_handler = ap_expr_parse_cmd(cmd, arg_,
                                              AP_EXPR_FLAG_STRING_RESULT,
                                              &err, NULL);
        if (err) {
            return apr_pstrcat(cmd->pool,
                    "Can't parse expression : ", err, NULL);
        }
        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->temp_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 (ap_cstr_casecmp(token, "None") == 0) {
                if (action != '*') {
                    valid = 0;
                }
                else {
                    cfg->etag_bits = bit = ETAG_NONE;
                    explicit = 1;
                }
            }
            else if (ap_cstr_casecmp(token, "All") == 0) {
                if (action != '*') {
                    valid = 0;
                }
                else {
                    explicit = 1;
                    cfg->etag_bits = bit = ETAG_ALL;
                }
            }
            else if (ap_cstr_casecmp(token, "Size") == 0) {
                bit = ETAG_SIZE;
            }
            else if ((ap_cstr_casecmp(token, "LMTime") == 0)
                     || (ap_cstr_casecmp(token, "MTime") == 0)
                     || (ap_cstr_casecmp(token, "LastModified") == 0)) {
                bit = ETAG_MTIME;
            }
            else if (ap_cstr_casecmp(token, "INode") == 0) {
                bit = ETAG_INODE;
            }
            else if (ap_cstr_casecmp(token, "Digest") == 0) {
                bit = ETAG_DIGEST;
            }
            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_;
    
        if (ap_cstr_casecmp(arg, "on") == 0) {
            d->enable_mmap = ENABLE_MMAP_ON;
        }
        else if (ap_cstr_casecmp(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_;
    
        if (ap_cstr_casecmp(arg, "on") == 0) {
            d->enable_sendfile = ENABLE_SENDFILE_ON;
        }
        else if (ap_cstr_casecmp(arg, "off") == 0) {
            d->enable_sendfile = ENABLE_SENDFILE_OFF;
        }
        else {
            return "parameter must be 'on' or 'off'";
        }
    
        return NULL;
    }
    
    static const char *set_read_buf_size(cmd_parms *cmd, void *d_,
                                         const char *arg)
    {
        core_dir_config *d = d_;
        apr_off_t size;
        char *end;
    
        if (apr_strtoff(&size, arg, &end, 10)
                || *end || size < 0 || size > APR_UINT32_MAX)
            return apr_pstrcat(cmd->pool,
                               "parameter must be a number between 0 and "
                               APR_STRINGIFY(APR_UINT32_MAX) "): ",
                               arg, NULL);
    
        d->read_buf_size = (apr_size_t)size;
    
        return NULL;
    }
    
    static const char *set_flush_max_threshold(cmd_parms *cmd, void *d_,
                                               const char *arg)
    {
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
        apr_off_t size;
        char *end;
    
        if (apr_strtoff(&size, arg, &end, 10)
                || *end || size < 0 || size > APR_UINT32_MAX)
            return apr_pstrcat(cmd->pool,
                               "parameter must be a number between 0 and "
                               APR_STRINGIFY(APR_UINT32_MAX) "): ",
                               arg, NULL);
    
        conf->flush_max_threshold = (apr_size_t)size;
    
        return NULL;
    }
    
    static const char *set_flush_max_pipelined(cmd_parms *cmd, void *d_,
                                               const char *arg)
    {
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
        apr_off_t num;
        char *end;
    
        if (apr_strtoff(&num, arg, &end, 10)
                || *end || num < -1 || num > APR_INT32_MAX)
            return apr_pstrcat(cmd->pool,
                               "parameter must be a number between -1 and "
                               APR_STRINGIFY(APR_INT32_MAX) ": ",
                               arg, NULL);
    
        conf->flush_max_pipelined = (apr_int32_t)num;
    
        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 '<Foo >' 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;
        apr_int64_t old_limited = cmd->limited;
        const char *errmsg;
    
        if (endp == NULL) {
            return unclosed_directive(cmd);
        }
    
        limited_methods = apr_pstrmemdup(cmd->temp_pool, arg, endp - arg);
    
        if (!limited_methods[0]) {
            return missing_container_arg(cmd);
        }
    
        while (limited_methods[0]) {
            char *method = ap_getword_conf(cmd->temp_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 <Limit>, see TraceEnable";
            }
            else if (methnum == M_INVALID) {
                /* method has not been registered yet, but resource restriction
                 * is always checked before method handling, so register it.
                 */
                if (cmd->pool == cmd->temp_pool) {
                    /* In .htaccess, we can't globally register new methods. */
                    return apr_psprintf(cmd->pool, "Could not register method '%s' "
                                       "for %s from .htaccess configuration",
                                        method, cmd->cmd->name);
                }
                methnum = ap_method_register(cmd->pool,
                                             apr_pstrdup(cmd->pool, method));
            }
    
            limited |= (AP_METHOD_BIT << methnum);
        }
    
        /* Killing two features with one function,
         * if (tog == NULL) <Limit>, else <LimitExcept>
         */
        limited = tog ? ~limited : limited;
    
        if (!(old_limited & limited)) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               "> directive excludes all methods", NULL);
        }
        else if ((old_limited & limited) == old_limited) {
            return apr_pstrcat(cmd->pool, cmd->cmd->name,
                               "> directive specifies methods already excluded",
                               NULL);
        }
    
        cmd->limited &= limited;
    
        errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context);
    
        cmd->limited = old_limited;
    
        return errmsg;
    }
    
    /* XXX: Bogus - need to do this differently (at least OS2/Netware suffer
     * the same problem!!!
     * We use this in <DirectoryMatch> and <FilesMatch>, 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_CONTEXT);
        if (err != NULL) {
            return err;
        }
    
        if (endp == NULL) {
            return unclosed_directive(cmd);
        }
    
        arg = apr_pstrndup(cmd->temp_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 (!strcmp(cmd->path, "~")) {
            cmd->path = ap_getword_conf(cmd->pool, &arg);
            if (!cmd->path)
                return "<Directory ~ > 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) { /* <DirectoryMatch> */
            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, "<Directory \"", cmd->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);
    
        if (r) {
            conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
            ap_regname(r, conf->refs, AP_REG_MATCH, 1);
        }
    
        /* 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_CONTEXT);
        if (err != NULL) {
            return err;
        }
    
        if (endp == NULL) {
            return unclosed_directive(cmd);
        }
    
        arg = apr_pstrndup(cmd->temp_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) { /* <LocationMatch> */
            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;
    
        if (r) {
            conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
            ap_regname(r, conf->refs, AP_REG_MATCH, 1);
        }
    
        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;
        ap_conf_vector_t *new_file_conf = ap_create_per_dir_config(cmd->pool);
        const char *err = ap_check_cmd_context(cmd,
                                               NOT_IN_LOCATION | NOT_IN_LIMIT);
    
        if (err != NULL) {
            return err;
        }
    
        if (endp == NULL) {
            return unclosed_directive(cmd);
        }
    
        arg = apr_pstrndup(cmd->temp_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) { /* <FilesMatch> */
            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, "<Files \"", cmd->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;
    
        if (r) {
            conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
            ap_regname(r, conf->refs, AP_REG_MATCH, 1);
        }
    
        ap_add_file_conf(cmd->pool, (core_dir_config *)mconfig, 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;
    }
    
    #define COND_IF      ((void *)1)
    #define COND_ELSE    ((void *)2)
    #define COND_ELSEIF  ((void *)3)
    
    static const char *ifsection(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;
        const command_rec *thiscmd = cmd->cmd;
        ap_conf_vector_t *new_if_conf = ap_create_per_dir_config(cmd->pool);
        const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
        const char *condition;
        const char *expr_err;
    
        if (err != NULL) {
            return err;
        }
    
        if (endp == NULL) {
            return unclosed_directive(cmd);
        }
    
        arg = apr_pstrndup(cmd->temp_pool, arg, endp - arg);
    
        /*
         * Set a dummy value so that other directives notice that they are inside
         * a config section.
         */
        cmd->path = "*If";
        /* Only if not an .htaccess file */
        if (!old_path) {
            cmd->override = OR_ALL|ACCESS_CONF;
        }
    
        /* initialize our config and fetch it */
        conf = ap_set_config_vectors(cmd->server, new_if_conf, cmd->path,
                                     &core_module, cmd->pool);
    
        if (cmd->cmd->cmd_data == COND_IF)
            conf->condition_ifelse = AP_CONDITION_IF;
        else if (cmd->cmd->cmd_data == COND_ELSEIF)
            conf->condition_ifelse = AP_CONDITION_ELSEIF;
        else if (cmd->cmd->cmd_data == COND_ELSE)
            conf->condition_ifelse = AP_CONDITION_ELSE;
        else
            ap_assert(0);
    
        if (conf->condition_ifelse == AP_CONDITION_ELSE) {
            if (arg[0])
                return "<Else> does not take an argument";
        }
        else {
            if (!arg[0])
                return missing_container_arg(cmd);
            condition = ap_getword_conf(cmd->pool, &arg);
            conf->condition = ap_expr_parse_cmd(cmd, condition, 0, &expr_err, NULL);
            if (expr_err)
                return apr_psprintf(cmd->pool, "Cannot parse condition clause: %s",
                                    expr_err);
        }
    
        errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_if_conf);
        if (errmsg != NULL)
            return errmsg;
    
        conf->d = cmd->path;
        conf->d_is_fnmatch = 0;
        conf->r = NULL;
    
        errmsg = ap_add_if_conf(cmd->pool, (core_dir_config *)mconfig, new_if_conf);
        if (errmsg != NULL)
            return errmsg;
    
        if (*arg != '\0') {
            return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name,
                               "> arguments not supported.", NULL);
        }
    
        cmd->path = old_path;
        cmd->override = old_overrides;
    
        return NULL;
    }
    
    static module *find_module(server_rec *s, const char *name)
    {
        module *found = ap_find_linked_module(name);
    
        /* search prelinked stuff */
        if (!found) {
            ap_module_symbol_t *current = ap_prelinked_module_symbols;
    
            for (; current->name; ++current) {
                if (!strcmp(current->name, name)) {
                    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) {
                /*
                 * There are two phases where calling ap_find_loaded_module_symbol
                 * is problematic:
                 *
                 * During reading of the config, ap_server_conf is invalid but s
                 * points to the main server config, if passed from cmd->server
                 * of an EXEC_ON_READ directive.
                 *
                 * During config parsing, s may be a virtual host that would cause
                 * a segfault in mod_so if passed to ap_find_loaded_module_symbol,
                 * because mod_so's server config for vhosts is initialized later.
                 * But ap_server_conf is already set at this time.
                 *
                 * Therefore we use s if it is not virtual and ap_server_conf if
                 * s is virtual.
                 */
                found = check_symbol(s->is_virtual ? ap_server_conf : s, name);
            }
        }
    
        return found;
    }
    
    /* Callback function type used by start_cond_section. */
    typedef int (*test_cond_section_fn)(cmd_parms *cmd, const char *arg);
    
    /* Implementation of <IfXXXXX>-style conditional sections.  Callback
     * to test condition must be in cmd->info, matching function type
     * test_cond_section_fn. */
    static const char *start_cond_section(cmd_parms *cmd, void *mconfig, const char *arg)
    {
        const char *endp = ap_strrchr_c(arg, '>');
        int result, not = (arg[0] == '!');
        test_cond_section_fn testfn = (test_cond_section_fn)cmd->info;
        const char *arg1;
    
        if (endp == NULL) {
            return unclosed_directive(cmd);
        }
    
        arg = apr_pstrmemdup(cmd->temp_pool, arg, endp - arg);
    
        if (not) {
            arg++;
        }
    
        arg1 = ap_getword_conf(cmd->temp_pool, &arg);
    
        if (!arg1[0]) {
            return missing_container_arg(cmd);
        }
    
        result = testfn(cmd, arg1);
    
        if ((!not && result) || (not && !result)) {
            ap_directive_t *parent = NULL;
            ap_directive_t *current = NULL;
            const char *retval;
    
            retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd,
                                          &current, &parent, (char *)cmd->cmd->name);
            *(ap_directive_t **)mconfig = current;
            return retval;
        }
        else {
            *(ap_directive_t **)mconfig = NULL;
            return ap_soak_end_container(cmd, (char *)cmd->cmd->name);
        }
    }
    
    /* Callback to implement <IfModule> test for start_cond_section. */
    static int test_ifmod_section(cmd_parms *cmd, const char *arg)
    {
        return find_module(cmd->server, arg) != NULL;
    }
    
    AP_DECLARE(int) ap_exists_config_define(const char *name)
    {
        return ap_array_str_contains(ap_server_config_defines, name);
    }
    
    static int test_ifdefine_section(cmd_parms *cmd, const char *arg)
    {
        return ap_exists_config_define(arg);
    }
    
    static int test_iffile_section(cmd_parms *cmd, const char *arg)
    {
        const char *relative;
        apr_finfo_t sb;
    
        /*
         * At least on Windows, if the path we are testing is not valid (for example
         * a path on a USB key that is not plugged), 'ap_server_root_relative()' will
         * return NULL. In such a case, consider that the file is not there and that
         * the section should be skipped.
         */
        relative = ap_server_root_relative(cmd->temp_pool, arg);
        return (relative &&
               (apr_stat(&sb, relative, APR_FINFO_TYPE, cmd->temp_pool) == APR_SUCCESS));
    }
    
    static int test_ifdirective_section(cmd_parms *cmd, const char *arg)
    {
        return ap_exists_directive(cmd->temp_pool, arg);
    }
    
    static int test_ifsection_section(cmd_parms *cmd, const char *arg)
    {
        const char *name = apr_pstrcat(cmd->temp_pool, "<", arg, NULL);
        return ap_exists_directive(cmd->temp_pool, name);
    }
    
    /* httpd.conf commands... beginning with the <VirtualHost> 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->temp_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 <VirtualHost>
            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 "<VirtualHost> 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_regex_default_options(cmd_parms *cmd,
                                                 void *dummy,
                                                 const char *arg)
    {
        const command_rec *thiscmd = cmd->cmd;
        int cflags, cflag;
    
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
    
        cflags = ap_regcomp_get_default_cflags();
        while (*arg) {
            const char *name = ap_getword_conf(cmd->pool, &arg);
            int how = 0;
    
            if (strcasecmp(name, "none") == 0) {
                cflags = 0;
                continue;
            }
    
            if (*name == '+') {
                name++;
                how = +1;
            }
            else if (*name == '-') {
                name++;
                how = -1;
            }
    
            cflag = ap_regcomp_default_cflag_by_name(name);
            if (!cflag) {
                return apr_psprintf(cmd->pool, "%s: option '%s' unknown",
                                    thiscmd->name, name);
            }
    
            if (how > 0) {
                cflags |= cflag;
            }
            else if (how < 0) {
                cflags &= ~cflag;
            }
            else {
                cflags = cflag;
            }
        }
        ap_regcomp_set_default_cflags(cflags);
    
        return NULL;
    }
    
    static const char *set_server_alias(cmd_parms *cmd, void *dummy,
                                        const char *arg)
    {
        if (!cmd->server->names) {
            return "ServerAlias only used in <VirtualHost>";
        }
    
        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_accf_map(cmd_parms *cmd, void *dummy,
                                    const char *iproto, const char* iaccf)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
        char* proto;
        char* accf;
        if (err != NULL) {
            return err;
        }
    
        proto = apr_pstrdup(cmd->pool, iproto);
        ap_str_tolower(proto);
        accf = apr_pstrdup(cmd->pool, iaccf);
        ap_str_tolower(accf);
        apr_table_setn(conf->accf_map, proto, accf);
    
        return NULL;
    }
    
    AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s)
    {
        core_server_config *conf = ap_get_core_module_config(s->module_config);
        return conf->protocol;
    }
    
    AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto)
    {
        core_server_config *conf = ap_get_core_module_config(s->module_config);
        conf->protocol = proto;
    }
    
    static const char *set_protocol(cmd_parms *cmd, void *dummy,
                                    const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
        char* proto;
    
        if (err != NULL) {
            return err;
        }
    
        proto = apr_pstrdup(cmd->pool, arg);
        ap_str_tolower(proto);
        conf->protocol = proto;
    
        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_CONTEXT);
        if (err != NULL) {
            return err;
        }
    
        *(const char **)(struct_ptr + offset) = arg;
        return NULL;
    }
    
    /*
     * The ServerName directive takes one argument with format
     * [scheme://]fully-qualified-domain-name[:port], for instance
     * ServerName www.example.com
     * ServerName www.example.com:80
     * ServerName https://www.example.com:443
     */
    
    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_CONTEXT);
        const char *portstr, *part;
        char *scheme;
        int port;
    
        if (err != NULL) {
            return err;
        }
    
        if (apr_fnmatch_test(arg))
            return apr_pstrcat(cmd->temp_pool, "Invalid ServerName \"", arg,
                    "\" use ServerAlias to set multiple server names.", NULL);
    
        part = ap_strstr_c(arg, "://");
    
        if (part) {
          scheme = apr_pstrndup(cmd->pool, arg, part - arg);
          ap_str_tolower(scheme);
          cmd->server->server_scheme = (const char *)scheme;
          part += 3;
        } else {
          part = arg;
        }
    
        portstr = ap_strchr_c(part, ':');
        if (portstr) {
            cmd->server->server_hostname = apr_pstrndup(cmd->pool, part,
                                                        portstr - part);
            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, part);
            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_;
    
        if (ap_cstr_casecmp(arg, "On") == 0) {
            d->server_signature = srv_sig_on;
        }
        else if (ap_cstr_casecmp(arg, "Off") == 0) {
            d->server_signature = srv_sig_off;
        }
        else if (ap_cstr_casecmp(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->temp_pool, ap_server_root)) {
            return "ServerRoot must be a valid directory";
        }
    
        return NULL;
    }
    
    static const char *set_runtime_dir(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_runtime_dir, NULL,
                                ap_server_root_relative(cmd->temp_pool, arg),
                                APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS)
            || !ap_is_directory(cmd->temp_pool, ap_runtime_dir)) {
            return "DefaultRuntimeDir must be a valid directory, absolute or relative to ServerRoot";
        }
    
        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_CONTEXT);
    
        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_, const char *arg)
    {
        core_dir_config *d = d_;
    
        if (0 == ap_cstr_casecmp(arg, "on")) {
            d->allow_encoded_slashes = 1;
            d->decode_encoded_slashes = 1; /* for compatibility with 2.0 & 2.2 */
        } else if (0 == ap_cstr_casecmp(arg, "off")) {
            d->allow_encoded_slashes = 0;
            d->decode_encoded_slashes = 0;
        } else if (0 == ap_cstr_casecmp(arg, "nodecode")) {
            d->allow_encoded_slashes = 1;
            d->decode_encoded_slashes = 0;
        } else {
            return apr_pstrcat(cmd->pool,
                               cmd->cmd->name, " must be On, Off, or NoDecode",
                               NULL);
        }
        return NULL;
    }
    
    static const char *set_hostname_lookups(cmd_parms *cmd, void *d_,
                                            const char *arg)
    {
        core_dir_config *d = d_;
    
        if (!ap_cstr_casecmp(arg, "on")) {
            d->hostname_lookups = HOSTNAME_LOOKUP_ON;
        }
        else if (!ap_cstr_casecmp(arg, "off")) {
            d->hostname_lookups = HOSTNAME_LOOKUP_OFF;
        }
        else if (!ap_cstr_casecmp(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_CONTEXT);
    
        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_;
    
        d->content_md5 = arg ? AP_CONTENT_MD5_ON : AP_CONTENT_MD5_OFF;
        return NULL;
    }
    
    static const char *set_accept_path_info(cmd_parms *cmd, void *d_, const char *arg)
    {
        core_dir_config *d = d_;
    
        if (ap_cstr_casecmp(arg, "on") == 0) {
            d->accept_path_info = AP_REQ_ACCEPT_PATH_INFO;
        }
        else if (ap_cstr_casecmp(arg, "off") == 0) {
            d->accept_path_info = AP_REQ_REJECT_PATH_INFO;
        }
        else if (ap_cstr_casecmp(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_;
    
        if (ap_cstr_casecmp(arg, "on") == 0) {
            d->use_canonical_name = USE_CANONICAL_NAME_ON;
        }
        else if (ap_cstr_casecmp(arg, "off") == 0) {
            d->use_canonical_name = USE_CANONICAL_NAME_OFF;
        }
        else if (ap_cstr_casecmp(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 *set_use_canonical_phys_port(cmd_parms *cmd, void *d_,
                                              const char *arg)
    {
        core_dir_config *d = d_;
    
        if (ap_cstr_casecmp(arg, "on") == 0) {
            d->use_canonical_phys_port = USE_CANONICAL_PHYS_PORT_ON;
        }
        else if (ap_cstr_casecmp(arg, "off") == 0) {
            d->use_canonical_phys_port = USE_CANONICAL_PHYS_PORT_OFF;
        }
        else {
            return "parameter must be 'on' or 'off'";
        }
    
        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;
        int optional = cmd->cmd->cmd_data ? 1 : 0;
        void *data;
    
        /* NOTE: ap_include_sentinel is also used by ap_process_resource_config()
         * during DUMP_INCLUDES; don't change its type or remove it without updating
         * the other.
         */
        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, "
                                "There appears to be a recursion.",
                                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);
        }
    
        if (ap_exists_config_define("DUMP_INCLUDES")) {
            unsigned *line_number;
    
            /* NOTE: ap_include_lineno is used by ap_process_resource_config()
             * during DUMP_INCLUDES; don't change its type or remove it without
             * updating the other.
             */
            apr_pool_userdata_get(&data, "ap_include_lineno", cmd->pool);
            if (data) {
                line_number = data;
            } else {
                data = line_number = apr_palloc(cmd->pool, sizeof(*line_number));
                apr_pool_userdata_setn(data, "ap_include_lineno", NULL, cmd->pool);
            }
    
            *line_number = cmd->config_file->line_number;
        }
    
        error = ap_process_fnmatch_configs(cmd->server, conffile, &conftree,
                                           cmd->pool, cmd->temp_pool,
                                           optional);
        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 *config_, const char *arg_)
    {
        char *level_str;
        int level;
        module *module;
        char *arg = apr_pstrdup(cmd->temp_pool, arg_);
        struct ap_logconf *log;
        const char *err;
    
        if (cmd->path) {
            core_dir_config *dconf = config_;
            if (!dconf->log) {
                dconf->log = ap_new_log_config(cmd->pool, NULL);
            }
            log = dconf->log;
        }
        else {
            log = &cmd->server->log;
        }
    
        if (arg == NULL)
            return "LogLevel requires level keyword or module loglevel specifier";
    
        level_str = ap_strrchr(arg, ':');
    
        if (level_str == NULL) {
            err = ap_parse_log_level(arg, &log->level);
            if (err != NULL)
                return err;
            ap_reset_module_loglevels(log, APLOG_NO_MODULE);
            ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, cmd->server,
                         "Setting LogLevel for all modules to %s", arg);
            return NULL;
        }
    
        *level_str++ = '\0';
        if (!*level_str) {
            return apr_psprintf(cmd->temp_pool, "Module specifier '%s' must be "
                                "followed by a log level keyword", arg);
        }
    
        err = ap_parse_log_level(level_str, &level);
        if (err != NULL)
            return apr_psprintf(cmd->temp_pool, "%s:%s: %s", arg, level_str, err);
    
        if ((module = find_module(cmd->server, arg)) == NULL) {
            char *name = apr_psprintf(cmd->temp_pool, "%s_module", arg);
            ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, cmd->server,
                         "Cannot find module '%s', trying '%s'", arg, name);
            module = find_module(cmd->server, name);
        }
    
        if (module == NULL) {
            return apr_psprintf(cmd->temp_pool, "Cannot find module %s", arg);
        }
    
        ap_set_module_loglevel(cmd->pool, log, module->module_index, level);
        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, cmd->server,
                     "Setting LogLevel for module %s to %s", module->name,
                     level_str);
    
        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_core_module_config(r->per_dir_config);
        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, "<address>",
                               ap_get_server_banner(),
                               " Server at <a href=\"",
                               ap_is_url(r->server->server_admin) ? "" : "mailto:",
                               ap_escape_html(r->pool, r->server->server_admin),
                               "\">",
                               ap_escape_html(r->pool, ap_get_server_name(r)),
                               "</a> Port ", sport,
                               "</address>\n", NULL);
        }
    
        return apr_pstrcat(r->pool, prefix, "<address>", ap_get_server_banner(),
                           " Server at ",
                           ap_escape_html(r->pool, ap_get_server_name(r)),
                           " Port ", sport,
                           "</address>\n", 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_banner = NULL;
    static int banner_locked = 0;
    static const char *server_description = NULL;
    
    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_banner(void *dummy)
    {
        banner_locked = 0;
        ap_server_tokens = SrvTk_FULL;
        server_banner = NULL;
        server_description = 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_description(void)
    {
        return server_description ? server_description :
            AP_SERVER_BASEVERSION " (" PLATFORM ")";
    }
    
    AP_DECLARE(const char *) ap_get_server_banner(void)
    {
        return server_banner ? server_banner : AP_SERVER_BASEVERSION;
    }
    
    AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component)
    {
        if (! banner_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_banner == NULL) {
                apr_pool_cleanup_register(pconf, NULL, reset_banner,
                                          apr_pool_cleanup_null);
                server_banner = apr_pstrdup(pconf, component);
            }
            else {
                /*
                 * Tack the given component identifier to the end of
                 * the existing string.
                 */
                server_banner = apr_pstrcat(pconf, server_banner, " ",
                                            component, NULL);
            }
        }
        server_description = apr_pstrcat(pconf, server_description, " ",
                                         component, NULL);
    }
    
    /*
     * This routine adds the real server base identity to the banner string,
     * and then locks out changes until the next reconfig.
     */
    static void set_banner(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_banner string if we're not displaying
         * the full set of tokens
         */
        if (ap_server_tokens != SrvTk_FULL) {
            banner_locked++;
        }
        server_description = AP_SERVER_BASEVERSION " (" PLATFORM ")";
    }
    
    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 (!ap_cstr_casecmp(arg, "OS")) {
            ap_server_tokens = SrvTk_OS;
        }
        else if (!ap_cstr_casecmp(arg, "Min") || !ap_cstr_casecmp(arg, "Minimal")) {
            ap_server_tokens = SrvTk_MINIMAL;
        }
        else if (!ap_cstr_casecmp(arg, "Major")) {
            ap_server_tokens = SrvTk_MAJOR;
        }
        else if (!ap_cstr_casecmp(arg, "Minor") ) {
            ap_server_tokens = SrvTk_MINOR;
        }
        else if (!ap_cstr_casecmp(arg, "Prod") || !ap_cstr_casecmp(arg, "ProductOnly")) {
            ap_server_tokens = SrvTk_PRODUCT_ONLY;
        }
        else if (!ap_cstr_casecmp(arg, "Full")) {
            ap_server_tokens = SrvTk_FULL;
        }
        else {
            return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', or '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_CONTEXT);
        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_CONTEXT);
        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_CONTEXT);
        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_;
        char *errp;
    
        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_;
    
        conf->limit_xml_body = atol(arg);
        if (conf->limit_xml_body < 0)
            return "LimitXMLRequestBody requires a non-negative integer.";
    
        /* zero is AP_MAX_LIMIT_XML_BODY (implicitly) */
        if ((apr_size_t)conf->limit_xml_body > AP_MAX_LIMIT_XML_BODY)
            return apr_psprintf(cmd->pool, "LimitXMLRequestBody must not exceed "
                                "%" APR_SIZE_T_FMT, AP_MAX_LIMIT_XML_BODY);
    
        return NULL;
    }
    
    static const char *set_max_ranges(cmd_parms *cmd, void *conf_, const char *arg)
    {
        core_dir_config *conf = conf_;
        int val = 0;
    
        if (!ap_cstr_casecmp(arg, "none")) {
            val = AP_MAXRANGES_NORANGES;
        }
        else if (!ap_cstr_casecmp(arg, "default")) {
            val = AP_MAXRANGES_DEFAULT;
        }
        else if (!ap_cstr_casecmp(arg, "unlimited")) {
            val = AP_MAXRANGES_UNLIMITED;
        }
        else {
            val = atoi(arg);
            if (val <= 0)
                return "MaxRanges requires 'none', 'default', 'unlimited' or "
                       "a positive integer";
        }
    
        conf->max_ranges = val;
    
        return NULL;
    }
    
    static const char *set_max_overlaps(cmd_parms *cmd, void *conf_, const char *arg)
    {
        core_dir_config *conf = conf_;
        int val = 0;
    
        if (!ap_cstr_casecmp(arg, "none")) {
            val = AP_MAXRANGES_NORANGES;
        }
        else if (!ap_cstr_casecmp(arg, "default")) {
            val = AP_MAXRANGES_DEFAULT;
        }
        else if (!ap_cstr_casecmp(arg, "unlimited")) {
            val = AP_MAXRANGES_UNLIMITED;
        }
        else {
            val = atoi(arg);
            if (val <= 0)
                return "MaxRangeOverlaps requires 'none', 'default', 'unlimited' or "
                "a positive integer";
        }
    
        conf->max_overlaps = val;
    
        return NULL;
    }
    
    static const char *set_max_reversals(cmd_parms *cmd, void *conf_, const char *arg)
    {
        core_dir_config *conf = conf_;
        int val = 0;
    
        if (!ap_cstr_casecmp(arg, "none")) {
            val = AP_MAXRANGES_NORANGES;
        }
        else if (!ap_cstr_casecmp(arg, "default")) {
            val = AP_MAXRANGES_DEFAULT;
        }
        else if (!ap_cstr_casecmp(arg, "unlimited")) {
            val = AP_MAXRANGES_UNLIMITED;
        }
        else {
            val = atoi(arg);
            if (val <= 0)
                return "MaxRangeReversals requires 'none', 'default', 'unlimited' or "
                "a positive integer";
        }
    
        conf->max_reversals = val;
    
        return NULL;
    }
    
    AP_DECLARE(apr_size_t) ap_get_limit_xml_body(const request_rec *r)
    {
        core_dir_config *conf;
    
        conf = ap_get_core_module_config(r->per_dir_config);
        if (conf->limit_xml_body == AP_LIMIT_UNSET)
            return AP_DEFAULT_LIMIT_XML_BODY;
        if (conf->limit_xml_body == 0)
            return AP_MAX_LIMIT_XML_BODY;
    
        return (apr_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, APLOGNO(00118)
                    "%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_;
    
        ap_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)
        ap_unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2 ,RLIMIT_AS);
    #elif defined(RLIMIT_DATA)
        ap_unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_DATA);
    #elif defined(RLIMIT_VMEM)
        ap_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_;
    
        ap_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_core_module_config(cmd->server->module_config);
        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, APLOGNO(00119)
                         "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, APLOGNO(00120)
                             "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)
    {
        if (APLOGrdebug(r)) {
            const request_rec *top = r;
    
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00121)
                          "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, APLOGNO(00122)
                                  "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, APLOGNO(00123)
                                  "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_core_module_config(r->server->module_config);
        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, APLOGNO(00124)
                                  "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, APLOGNO(00125)
                                  "Request exceeded the limit of %d subrequest "
                                  "nesting levels due to probable configuration "
                                  "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 *set_trace_enable(cmd_parms *cmd, void *dummy,
                                        const char *arg1)
    {
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
    
        if (ap_cstr_casecmp(arg1, "on") == 0) {
            conf->trace_enable = AP_TRACE_ENABLE;
        }
        else if (ap_cstr_casecmp(arg1, "off") == 0) {
            conf->trace_enable = AP_TRACE_DISABLE;
        }
        else if (ap_cstr_casecmp(arg1, "extended") == 0) {
            conf->trace_enable = AP_TRACE_EXTENDED;
        }
        else {
            return "TraceEnable must be one of 'on', 'off', or 'extended'";
        }
    
        return NULL;
    }
    
    static const char *set_protocols(cmd_parms *cmd, void *dummy,
                                     const char *arg)
    {
        core_server_config *conf =
        ap_get_core_module_config(cmd->server->module_config);
        const char **np;
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
    
        if (err) {
            return err;
        }
        
        np = (const char **)apr_array_push(conf->protocols);
        *np = arg;
    
        return NULL;
    }
    
    static const char *set_protocols_honor_order(cmd_parms *cmd, void *dummy,
                                                 const char *arg)
    {
        core_server_config *conf =
        ap_get_core_module_config(cmd->server->module_config);
        const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
        
        if (err) {
            return err;
        }
        
        if (ap_cstr_casecmp(arg, "on") == 0) {
            conf->protocols_honor_order = 1;
        }
        else if (ap_cstr_casecmp(arg, "off") == 0) {
            conf->protocols_honor_order = 0;
        }
        else {
            return "ProtocolsHonorOrder must be 'on' or 'off'";
        }
        
        return NULL;
    }
    
    static const char *set_http_protocol_options(cmd_parms *cmd, void *dummy,
                                                 const char *arg)
    {
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
    
        if (strcasecmp(arg, "allow0.9") == 0)
            conf->http09_enable |= AP_HTTP09_ENABLE;
        else if (strcasecmp(arg, "require1.0") == 0)
            conf->http09_enable |= AP_HTTP09_DISABLE;
        else if (strcasecmp(arg, "strict") == 0)
            conf->http_conformance |= AP_HTTP_CONFORMANCE_STRICT;
        else if (strcasecmp(arg, "unsafe") == 0)
            conf->http_conformance |= AP_HTTP_CONFORMANCE_UNSAFE;
        else if (strcasecmp(arg, "registeredmethods") == 0)
            conf->http_methods |= AP_HTTP_METHODS_REGISTERED;
        else if (strcasecmp(arg, "lenientmethods") == 0)
            conf->http_methods |= AP_HTTP_METHODS_LENIENT;
        else
            return "HttpProtocolOptions accepts "
                   "'Unsafe' or 'Strict' (default), "
                   "'RegisteredMethods' or 'LenientMethods' (default), and "
                   "'Require1.0' or 'Allow0.9' (default)";
    
        if ((conf->http09_enable & AP_HTTP09_ENABLE)
                && (conf->http09_enable & AP_HTTP09_DISABLE))
            return "HttpProtocolOptions 'Allow0.9' and 'Require1.0'"
                   " are mutually exclusive";
    
        if ((conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT)
                && (conf->http_conformance & AP_HTTP_CONFORMANCE_UNSAFE))
            return "HttpProtocolOptions 'Strict' and 'Unsafe'"
                   " are mutually exclusive";
    
        if ((conf->http_methods & AP_HTTP_METHODS_REGISTERED)
                && (conf->http_methods & AP_HTTP_METHODS_LENIENT))
            return "HttpProtocolOptions 'RegisteredMethods' and 'LenientMethods'"
                   " are mutually exclusive";
    
        return NULL;
    }
    
    static const char *set_http_method(cmd_parms *cmd, void *conf, const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL)
            return err;
        ap_method_register(cmd->pool, arg);
        return NULL;
    }
    
    static apr_hash_t *errorlog_hash;
    
    static int log_constant_item(const ap_errorlog_info *info, const char *arg,
                                 char *buf, int buflen)
    {
        char *end = apr_cpystrn(buf, arg, buflen);
        return end - buf;
    }
    
    static char *parse_errorlog_misc_string(apr_pool_t *p,
                                            ap_errorlog_format_item *it,
                                            const char **sa)
    {
        const char *s;
        char scratch[MAX_STRING_LEN];
        char *d = scratch;
        /*
         * non-leading white space terminates this string to allow the next field
         * separator to be inserted
         */
        int at_start = 1;
    
        it->func = log_constant_item;
        s = *sa;
    
        while (*s && *s != '%' && (*s != ' ' || at_start) && d < scratch + MAX_STRING_LEN) {
            if (*s != '\\') {
                if (*s != ' ') {
                    at_start = 0;
                }
                *d++ = *s++;
            }
            else {
                s++;
                switch (*s) {
                case 'r':
                    *d++ = '\r';
                    s++;
                    break;
                case 'n':
                    *d++ = '\n';
                    s++;
                    break;
                case 't':
                    *d++ = '\t';
                    s++;
                    break;
                case '\0':
                    /* handle end of string */
                    *d++ = '\\';
                    break;
                default:
                    /* copy next char verbatim */
                    *d++ = *s++;
                    break;
                }
            }
        }
        *d = '\0';
        it->arg = apr_pstrdup(p, scratch);
    
        *sa = s;
        return NULL;
    }
    
    static char *parse_errorlog_item(apr_pool_t *p, ap_errorlog_format_item *it,
                                     const char **sa)
    {
        const char *s = *sa;
        ap_errorlog_handler *handler;
        int i;
    
        if (*s != '%') {
            if (*s == ' ') {
                it->flags |= AP_ERRORLOG_FLAG_FIELD_SEP;
            }
            return parse_errorlog_misc_string(p, it, sa);
        }
    
        ++s;
    
        if (*s == ' ') {
            /* percent-space (% ) is a field separator */
            it->flags |= AP_ERRORLOG_FLAG_FIELD_SEP;
            *sa = ++s;
            /* recurse */
            return parse_errorlog_item(p, it, sa);
        }
        else if (*s == '%') {
            it->arg = "%";
            it->func = log_constant_item;
            *sa = ++s;
            return NULL;
        }
    
        while (*s) {
            switch (*s) {
            case '{':
                ++s;
                it->arg = ap_getword(p, &s, '}');
                break;
            case '+':
                ++s;
                it->flags |= AP_ERRORLOG_FLAG_REQUIRED;
                break;
            case '-':
                ++s;
                it->flags |= AP_ERRORLOG_FLAG_NULL_AS_HYPHEN;
                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';
                it->min_loglevel = i;
                break;
            case 'M':
                it->func = NULL;
                it->flags |= AP_ERRORLOG_FLAG_MESSAGE;
                *sa = ++s;
                return NULL;
            default:
                handler = (ap_errorlog_handler *)apr_hash_get(errorlog_hash, s, 1);
                if (!handler) {
                    char dummy[2];
    
                    dummy[0] = *s;
                    dummy[1] = '\0';
                    return apr_pstrcat(p, "Unrecognized error log format directive %",
                                   dummy, NULL);
                }
                it->func = handler->func;
                *sa = ++s;
                return NULL;
            }
        }
    
        return "Ran off end of error log format parsing args to some directive";
    }
    
    static apr_array_header_t *parse_errorlog_string(apr_pool_t *p,
                                                     const char *s,
                                                     const char **err,
                                                     int is_main_fmt)
    {
        apr_array_header_t *a = apr_array_make(p, 30,
                                               sizeof(ap_errorlog_format_item));
        char *res;
        int seen_msg_fmt = 0;
    
        while (s && *s) {
            ap_errorlog_format_item *item =
                (ap_errorlog_format_item *)apr_array_push(a);
            memset(item, 0, sizeof(*item));
            res = parse_errorlog_item(p, item, &s);
            if (res) {
                *err = res;
                return NULL;
            }
            if (item->flags & AP_ERRORLOG_FLAG_MESSAGE) {
                if (!is_main_fmt) {
                    *err = "%M cannot be used in once-per-request or "
                           "once-per-connection formats";
                    return NULL;
                }
                seen_msg_fmt = 1;
            }
            if (is_main_fmt && item->flags & AP_ERRORLOG_FLAG_REQUIRED) {
                *err = "The '+' flag cannot be used in the main error log format";
                return NULL;
            }
            if (!is_main_fmt && item->min_loglevel) {
                *err = "The loglevel cannot be used as a condition in "
                       "once-per-request or once-per-connection formats";
                return NULL;
            }
            if (item->min_loglevel > APLOG_TRACE8) {
                *err = "The specified loglevel modifier is out of range";
                return NULL;
            }
        }
    
        if (is_main_fmt && !seen_msg_fmt) {
            *err = "main ErrorLogFormat must contain message format string '%M'";
            return NULL;
        }
    
        return a;
    }
    
    static const char *set_errorlog_format(cmd_parms *cmd, void *dummy,
                                           const char *arg1, const char *arg2)
    {
        const char *err_string = NULL;
        core_server_config *conf =
            ap_get_core_module_config(cmd->server->module_config);
    
        if (!arg2) {
            conf->error_log_format = parse_errorlog_string(cmd->pool, arg1,
                                                           &err_string, 1);
        }
        else if (!ap_cstr_casecmp(arg1, "connection")) {
            if (!conf->error_log_conn) {
                conf->error_log_conn = apr_array_make(cmd->pool, 5,
                                                      sizeof(apr_array_header_t *));
            }
    
            if (*arg2) {
                apr_array_header_t **e;
                e = (apr_array_header_t **) apr_array_push(conf->error_log_conn);
                *e = parse_errorlog_string(cmd->pool, arg2, &err_string, 0);
            }
        }
        else if (!ap_cstr_casecmp(arg1, "request")) {
            if (!conf->error_log_req) {
                conf->error_log_req = apr_array_make(cmd->pool, 5,
                                                     sizeof(apr_array_header_t *));
            }
    
            if (*arg2) {
                apr_array_header_t **e;
                e = (apr_array_header_t **) apr_array_push(conf->error_log_req);
                *e = parse_errorlog_string(cmd->pool, arg2, &err_string, 0);
            }
        }
        else {
            err_string = "ErrorLogFormat type must be one of request, connection";
        }
    
        return err_string;
    }
    
    AP_DECLARE(void) ap_register_errorlog_handler(apr_pool_t *p, char *tag,
                                                  ap_errorlog_handler_fn_t *handler,
                                                  int flags)
    {
        ap_errorlog_handler *log_struct = apr_palloc(p, sizeof(*log_struct));
        log_struct->func = handler;
        log_struct->flags = flags;
    
        apr_hash_set(errorlog_hash, tag, 1, (const void *)log_struct);
    }
    
    
    static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg)
    {
        core_server_config *conf = ap_get_module_config(cmd->server->module_config,
                                                        &core_module);
        conf->merge_trailers = (arg ? AP_MERGE_TRAILERS_ENABLE :
                AP_MERGE_TRAILERS_DISABLE);
    
        return NULL;
    }
    
    #ifdef WIN32
    static const char *set_unc_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
    {
        core_server_config *sconf = ap_get_core_module_config(cmd->server->module_config);
        int i;
        const char *err;
    
        if ((err = ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST)) != NULL)
            return err;
    
        sconf->unc_list = apr_array_make(cmd->pool, argc, sizeof(char *));
    
        for (i = 0; i < argc; i++) {
            *(char **)apr_array_push(sconf->unc_list) = apr_pstrdup(cmd->pool, argv[i]);
        }
    
        return NULL;
    }
    #endif
    /* 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("<Directory", dirsection, NULL, RSRC_CONF,
      "Container for directives affecting resources located in the specified "
      "directories"),
    AP_INIT_RAW_ARGS("<Location", urlsection, NULL, RSRC_CONF,
      "Container for directives affecting resources accessed through the "
      "specified URL paths"),
    AP_INIT_RAW_ARGS("<VirtualHost", virtualhost_section, NULL, RSRC_CONF,
      "Container to map directives to a particular virtual host, takes one or "
      "more host addresses"),
    AP_INIT_RAW_ARGS("<Files", filesection, NULL, OR_ALL,
      "Container for directives affecting files matching specified patterns"),
    AP_INIT_RAW_ARGS("<Limit", ap_limit_section, NULL, OR_LIMIT | OR_AUTHCFG,
      "Container for authentication directives when accessed using specified HTTP "
      "methods"),
    AP_INIT_RAW_ARGS("<LimitExcept", ap_limit_section, (void*)1,
                     OR_LIMIT | OR_AUTHCFG,
      "Container for authentication directives to be applied when any HTTP "
      "method other than those specified is used to access the resource"),
    AP_INIT_RAW_ARGS("<IfModule", start_cond_section, (void *)test_ifmod_section,
                  EXEC_ON_READ | OR_ALL,
      "Container for directives based on existence of specified modules"),
    AP_INIT_RAW_ARGS("<IfDefine", start_cond_section, (void *)test_ifdefine_section,
                  EXEC_ON_READ | OR_ALL,
      "Container for directives based on existence of command line defines"),
    AP_INIT_RAW_ARGS("<IfFile", start_cond_section, (void *)test_iffile_section,
                  EXEC_ON_READ | OR_ALL,
      "Container for directives based on existence of files on disk"),
    AP_INIT_RAW_ARGS("<IfDirective", start_cond_section, (void *)test_ifdirective_section,
                  EXEC_ON_READ | OR_ALL,
      "Container for directives based on existence of named directive"),
    AP_INIT_RAW_ARGS("<IfSection", start_cond_section, (void *)test_ifsection_section,
                  EXEC_ON_READ | OR_ALL,
      "Container for directives based on existence of named section"),
    AP_INIT_RAW_ARGS("<DirectoryMatch", dirsection, (void*)1, RSRC_CONF,
      "Container for directives affecting resources located in the "
      "specified directories"),
    AP_INIT_RAW_ARGS("<LocationMatch", urlsection, (void*)1, RSRC_CONF,
      "Container for directives affecting resources accessed through the "
      "specified URL paths"),
    AP_INIT_RAW_ARGS("<FilesMatch", filesection, (void*)1, OR_ALL,
      "Container for directives affecting files matching specified patterns"),
    #ifdef GPROF
    AP_INIT_TAKE1("GprofDir", set_gprof_dir, NULL, RSRC_CONF,
      "Directory to plop gmon.out files"),
    #endif
    AP_INIT_TAKE1("AddDefaultCharset", set_add_default_charset, NULL, OR_FILEINFO,
      "The name of the default charset to add to any Content-Type without one or 'Off' to disable"),
    AP_INIT_TAKE1("AcceptPathInfo", set_accept_path_info, NULL, OR_FILEINFO,
      "Set to on or off for PATH_INFO to be accepted by handlers, or default for the per-handler preference"),
    AP_INIT_TAKE12("Define", set_define, NULL, EXEC_ON_READ|ACCESS_CONF|RSRC_CONF,
                  "Define a variable, optionally to a value.  Same as passing -D to the command line."),
    AP_INIT_TAKE1("UnDefine", unset_define, NULL, EXEC_ON_READ|ACCESS_CONF|RSRC_CONF,
                  "Undefine the existence of a variable. Undo a Define."),
    AP_INIT_RAW_ARGS("Error", generate_error, NULL, OR_ALL,
                     "Generate error message from within configuration"),
    AP_INIT_RAW_ARGS("<If", ifsection, COND_IF, OR_ALL,
      "Container for directives to be conditionally applied"),
    AP_INIT_RAW_ARGS("<ElseIf", ifsection, COND_ELSEIF, OR_ALL,
      "Container for directives to be conditionally applied"),
    AP_INIT_RAW_ARGS("<Else", ifsection, COND_ELSE, OR_ALL,
      "Container for directives to be conditionally applied"),
    
    /* Old resource config file commands */
    
    AP_INIT_RAW_ARGS("AccessFileName", set_access_name, NULL, RSRC_CONF,
      "Name(s) of per-directory config files (default: .htaccess)"),
    AP_INIT_TAKE1("DocumentRoot", set_document_root, NULL, RSRC_CONF,
      "Root directory of the document tree"),
    AP_INIT_TAKE2("ErrorDocument", set_error_document, NULL, OR_FILEINFO,
      "Change responses for HTTP errors"),
    AP_INIT_RAW_ARGS("AllowOverride", set_override, NULL, ACCESS_CONF,
      "Controls what groups of directives can be configured by per-directory "
      "config files"),
    AP_INIT_TAKE_ARGV("AllowOverrideList", set_override_list, NULL, ACCESS_CONF,
      "Controls what individual directives can be configured by per-directory "
      "config files"),
    AP_INIT_RAW_ARGS("Options", set_options, NULL, OR_OPTIONS,
      "Set a number of attributes for a given directory"),
    AP_INIT_TAKE1("DefaultType", set_default_type, NULL, OR_FILEINFO,
      "the default media type for otherwise untyped files (DEPRECATED)"),
    AP_INIT_RAW_ARGS("FileETag", set_etag_bits, NULL, OR_FILEINFO,
      "Specify components used to construct a file's ETag"),
    AP_INIT_TAKE1("EnableMMAP", set_enable_mmap, NULL, OR_FILEINFO,
      "Controls whether memory-mapping may be used to read files"),
    AP_INIT_TAKE1("EnableSendfile", set_enable_sendfile, NULL, OR_FILEINFO,
      "Controls whether sendfile may be used to transmit files"),
    AP_INIT_TAKE1("ReadBufferSize", set_read_buf_size, NULL, ACCESS_CONF|RSRC_CONF,
      "Size (in bytes) of the memory buffers used to read data"),
    AP_INIT_TAKE1("FlushMaxThreshold", set_flush_max_threshold, NULL, RSRC_CONF,
      "Maximum threshold above which pending data are flushed to the network"),
    AP_INIT_TAKE1("FlushMaxPipelined", set_flush_max_pipelined, NULL, RSRC_CONF,
      "Maximum number of pipelined responses (pending) above which they are "
      "flushed to the network"),
    #ifdef WIN32
    AP_INIT_TAKE_ARGV("UNCList", set_unc_list, NULL, RSRC_CONF|EXEC_ON_READ,
      "Controls what UNC hosts may be looked up"),
    #endif
    
    /* Old server config file commands */
    
    AP_INIT_TAKE1("Protocol", set_protocol, NULL, RSRC_CONF,
      "Set the Protocol for httpd to use."),
    AP_INIT_TAKE2("AcceptFilter", set_accf_map, NULL, RSRC_CONF,
      "Set the Accept Filter to use for a protocol"),
    AP_INIT_TAKE1("Port", ap_set_deprecated, NULL, RSRC_CONF,
      "Port was replaced with Listen in Apache 2.0"),
    AP_INIT_TAKE1("HostnameLookups", set_hostname_lookups, NULL,
      ACCESS_CONF|RSRC_CONF,
      "\"on\" to enable, \"off\" to disable reverse DNS lookups, or \"double\" to "
      "enable double-reverse DNS lookups"),
    AP_INIT_TAKE1("ServerAdmin", set_server_string_slot,
      (void *)APR_OFFSETOF(server_rec, server_admin), RSRC_CONF,
      "The email address of the server administrator"),
    AP_INIT_TAKE1("ServerName", server_hostname_port, NULL, RSRC_CONF,
      "The hostname and port of the server"),
    AP_INIT_TAKE1("ServerSignature", set_signature_flag, NULL, OR_ALL,
      "En-/disable server signature (on|off|email)"),
    AP_INIT_TAKE1("ServerRoot", set_server_root, NULL, RSRC_CONF | EXEC_ON_READ,
      "Common directory of server-related files (logs, confs, etc.)"),
    AP_INIT_TAKE1("DefaultRuntimeDir", set_runtime_dir, NULL, RSRC_CONF | EXEC_ON_READ,
      "Common directory for run-time files (shared memory, locks, etc.)"),
    AP_INIT_TAKE1("ErrorLog", set_server_string_slot,
      (void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF,
      "The filename of the error log"),
    AP_INIT_TAKE12("ErrorLogFormat", set_errorlog_format, NULL, RSRC_CONF,
      "Format string for the ErrorLog"),
    AP_INIT_RAW_ARGS("ServerAlias", set_server_alias, NULL, RSRC_CONF,
      "A name or names alternately used to access the server"),
    AP_INIT_TAKE1("ServerPath", set_serverpath, NULL, RSRC_CONF,
      "The pathname the server can be reached at"),
    AP_INIT_TAKE1("Timeout", set_timeout, NULL, RSRC_CONF,
      "Timeout duration (sec)"),
    AP_INIT_FLAG("ContentDigest", set_content_md5, NULL, OR_OPTIONS,
      "whether or not to send a Content-MD5 header with each request"),
    AP_INIT_TAKE1("UseCanonicalName", set_use_canonical_name, NULL,
      RSRC_CONF|ACCESS_CONF,
      "How to work out the ServerName : Port when constructing URLs"),
    AP_INIT_TAKE1("UseCanonicalPhysicalPort", set_use_canonical_phys_port, NULL,
      RSRC_CONF|ACCESS_CONF,
      "Whether to use the physical Port when constructing URLs"),
    /* TODO: RlimitFoo should all be part of mod_cgi, not in the core */
    /* TODO: ListenBacklog in MPM */
    AP_INIT_TAKE1("Include", include_config, NULL,
      (RSRC_CONF | ACCESS_CONF | EXEC_ON_READ),
      "Name(s) of the config file(s) to be included; fails if the wildcard does "
      "not match at least one file"),
    AP_INIT_TAKE1("IncludeOptional", include_config, (void*)1,
      (RSRC_CONF | ACCESS_CONF | EXEC_ON_READ),
      "Name or pattern of the config file(s) to be included; ignored if the file "
      "does not exist or the pattern does not match any files"),
    AP_INIT_ITERATE("LogLevel", set_loglevel, NULL, RSRC_CONF|ACCESS_CONF,
      "Level of verbosity in error logging"),
    AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF,
      "A numeric IP address:port, or the name of a host"),
    AP_INIT_TAKE1("ServerTokens", set_serv_tokens, NULL, RSRC_CONF,
      "Determine tokens displayed in the Server: header - Min(imal), "
      "Major, Minor, Prod(uctOnly), OS, or Full"),
    AP_INIT_TAKE1("LimitRequestLine", set_limit_req_line, NULL, RSRC_CONF,
      "Limit on maximum size of an HTTP request line"),
    AP_INIT_TAKE1("LimitRequestFieldsize", set_limit_req_fieldsize, NULL,
      RSRC_CONF,
      "Limit on maximum size of an HTTP request header field"),
    AP_INIT_TAKE1("LimitRequestFields", set_limit_req_fields, NULL, RSRC_CONF,
      "Limit (0 = unlimited) on max number of header fields in a request message"),
    AP_INIT_TAKE1("LimitRequestBody", set_limit_req_body,
      (void*)APR_OFFSETOF(core_dir_config, limit_req_body), OR_ALL,
      "Limit (in bytes) on maximum size of request message body"),
    AP_INIT_TAKE1("LimitXMLRequestBody", set_limit_xml_req_body, NULL, OR_ALL,
                  "Limit (in bytes) on maximum size of an XML-based request "
                  "body"),
    AP_INIT_RAW_ARGS("Mutex", ap_set_mutex, NULL, RSRC_CONF,
                     "mutex (or \"default\") and mechanism"),
    
    AP_INIT_TAKE1("MaxRanges", set_max_ranges, NULL, RSRC_CONF|ACCESS_CONF,
                  "Maximum number of Ranges in a request before returning the entire "
                  "resource, or 0 for unlimited"),
    AP_INIT_TAKE1("MaxRangeOverlaps", set_max_overlaps, NULL, RSRC_CONF|ACCESS_CONF,
                  "Maximum number of overlaps in Ranges in a request before returning the entire "
                  "resource, or 0 for unlimited"),
    AP_INIT_TAKE1("MaxRangeReversals", set_max_reversals, NULL, RSRC_CONF|ACCESS_CONF,
                  "Maximum number of reversals in Ranges in a request before returning the entire "
                  "resource, or 0 for unlimited"),
    /* System Resource Controls */
    #ifdef RLIMIT_CPU
    AP_INIT_TAKE12("RLimitCPU", set_limit_cpu,
      (void*)APR_OFFSETOF(core_dir_config, limit_cpu),
      OR_ALL, "Soft/hard limits for max CPU usage in seconds"),
    #else
    AP_INIT_TAKE12("RLimitCPU", no_set_limit, NULL,
      OR_ALL, "Soft/hard limits for max CPU usage in seconds"),
    #endif
    #if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined (RLIMIT_AS)
    AP_INIT_TAKE12("RLimitMEM", set_limit_mem,
      (void*)APR_OFFSETOF(core_dir_config, limit_mem),
      OR_ALL, "Soft/hard limits for max memory usage per process"),
    #else
    AP_INIT_TAKE12("RLimitMEM", no_set_limit, NULL,
      OR_ALL, "Soft/hard limits for max memory usage per process"),
    #endif
    #ifdef RLIMIT_NPROC
    AP_INIT_TAKE12("RLimitNPROC", set_limit_nproc,
      (void*)APR_OFFSETOF(core_dir_config, limit_nproc),
      OR_ALL, "soft/hard limits for max number of processes per uid"),
    #else
    AP_INIT_TAKE12("RLimitNPROC", no_set_limit, NULL,
       OR_ALL, "soft/hard limits for max number of processes per uid"),
    #endif
    
    AP_INIT_RAW_ARGS("RegexDefaultOptions", set_regex_default_options, NULL, RSRC_CONF,
                     "default options for regexes (prefixed by '+' to add, '-' to del)"),
    
    /* internal recursion stopper */
    AP_INIT_TAKE12("LimitInternalRecursion", set_recursion_limit, NULL, RSRC_CONF,
                  "maximum recursion depth of internal redirects and subrequests"),
    
    AP_INIT_FLAG("CGIPassAuth", set_cgi_pass_auth, NULL, OR_AUTHCFG,
                 "Controls whether HTTP authorization headers, normally hidden, will "
                 "be passed to scripts"),
    AP_INIT_TAKE2("CGIVar", set_cgi_var, NULL, OR_FILEINFO,
                  "Controls how some CGI variables are set"),
    AP_INIT_FLAG("QualifyRedirectURL", set_qualify_redirect_url, NULL, OR_FILEINFO,
                 "Controls whether the REDIRECT_URL environment variable is fully "
                 "qualified"),
    AP_INIT_FLAG("StrictHostCheck", set_core_server_flag, 
                 (void *)APR_OFFSETOF(core_server_config, strict_host_check),  
                 RSRC_CONF,
                 "Controls whether a hostname match is required"),
    AP_INIT_TAKE1("ForceType", ap_set_string_slot_lower,
           (void *)APR_OFFSETOF(core_dir_config, mime_type), OR_FILEINFO,
         "a mime type that overrides other configured type"),
    AP_INIT_TAKE1("SetHandler", set_sethandler, NULL, OR_FILEINFO,
       "a handler name that overrides any other configured handler"),
    AP_INIT_TAKE1("SetOutputFilter", ap_set_string_slot,
           (void *)APR_OFFSETOF(core_dir_config, output_filters), OR_FILEINFO,
       "filter (or ; delimited list of filters) to be run on the request content"),
    AP_INIT_TAKE1("SetInputFilter", ap_set_string_slot,
           (void *)APR_OFFSETOF(core_dir_config, input_filters), OR_FILEINFO,
       "filter (or ; delimited list of filters) to be run on the request body"),
    AP_INIT_TAKE1("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF,
                 "Allow URLs containing '/' encoded as '%2F'"),
    
    /* scoreboard.c directives */
    AP_INIT_TAKE1("ScoreBoardFile", ap_set_scoreboard, NULL, RSRC_CONF,
                  "A file for Apache to maintain runtime process management information"),
    AP_INIT_FLAG("ExtendedStatus", ap_set_extended_status, NULL, RSRC_CONF,
                 "\"On\" to track extended status information, \"Off\" to disable"),
    AP_INIT_FLAG("SeeRequestTail", ap_set_reqtail, NULL, RSRC_CONF,
                 "For extended status, \"On\" to see the last 63 chars of "
                 "the request line, \"Off\" (default) to see the first 63"),
    
    /*
     * These are default configuration directives that mpms can/should
     * pay attention to.
     * XXX These are not for all platforms, and even some Unix MPMs might not want
     * some directives.
     */
    AP_INIT_TAKE1("PidFile",  ap_mpm_set_pidfile, NULL, RSRC_CONF,
                  "A file for logging the server process ID"),
    AP_INIT_TAKE1("MaxRequestsPerChild", ap_mpm_set_max_requests, NULL, RSRC_CONF,
                  "Maximum number of connections a particular child serves before "
                  "dying. (DEPRECATED, use MaxConnectionsPerChild)"),
    AP_INIT_TAKE1("MaxConnectionsPerChild", ap_mpm_set_max_requests, NULL, RSRC_CONF,
                  "Maximum number of connections a particular child serves before dying."),
    AP_INIT_TAKE1("CoreDumpDirectory", ap_mpm_set_coredumpdir, NULL, RSRC_CONF,
                  "The location of the directory Apache changes to before dumping core"),
    AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF,
                  "Maximum number of 1k blocks a particular child's allocator may hold."),
    AP_INIT_TAKE1("ThreadStackSize", ap_mpm_set_thread_stacksize, NULL, RSRC_CONF,
                  "Size in bytes of stack used by threads handling client connections"),
    #if AP_ENABLE_EXCEPTION_HOOK
    AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF,
                  "Controls whether exception hook may be called after a crash"),
    #endif
    AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF,
                  "'on' (default), 'off' or 'extended' to trace request body content"),
    AP_INIT_FLAG("MergeTrailers", set_merge_trailers, NULL, RSRC_CONF,
                  "merge request trailers into request headers or not"),
    AP_INIT_ITERATE("Protocols", set_protocols, NULL, RSRC_CONF,
                    "Controls which protocols are allowed"),
    AP_INIT_TAKE1("ProtocolsHonorOrder", set_protocols_honor_order, NULL, RSRC_CONF,
                  "'off' (default) or 'on' to respect given order of protocols, "
                  "by default the client specified order determines selection"),
    AP_INIT_ITERATE("HttpProtocolOptions", set_http_protocol_options, NULL, RSRC_CONF,
                    "'Allow0.9' or 'Require1.0' (default); "
                    "'RegisteredMethods' or 'LenientMethods' (default); "
                    "'Unsafe' or 'Strict' (default). Sets HTTP acceptance rules"),
    AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
                    "Registers non-standard HTTP methods"),
    AP_INIT_FLAG("MergeSlashes", set_core_server_flag, 
                 (void *)APR_OFFSETOF(core_server_config, merge_slashes),  
                 RSRC_CONF,
                 "Controls whether consecutive slashes in the URI path are merged"),
    { NULL }
    };
    
    /*****************************************************************
     *
     * Core handlers for various phases of server operation...
     */
    
    AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r)
    {
        apr_status_t rv;
        char *path;
    
        /* 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, APLOGNO(00126)
                         "Invalid URI in request '%s' '%s'", r->uri, 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'))
        {
            path = r->uri + r->server->pathlen;
        }
        else {
            path = r->uri;
        }
        /*
         * 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.
         */
        while (*path == '/') {
            ++path;
        }
        if ((rv = apr_filepath_merge(&r->filename, ap_document_root(r), path,
                                     APR_FILEPATH_TRUENAME
                                   | APR_FILEPATH_SECUREROOT, r->pool))
                    != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00127)
                         "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_core_module_config(r->per_dir_config);
    
        /* Check for overrides with ForceType / SetHandler
         */
        if (conf->mime_type && strcmp(conf->mime_type, "none"))
            ap_set_content_type_ex(r, (char*) conf->mime_type, 1);
    
        if (conf->expr_handler) { 
            const char *err;
            const char *val;
            val = ap_expr_str_exec(r, conf->expr_handler, &err);
            if (err) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03154)
                              "Can't evaluate handler expression: %s", err);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
    
            if (val != ap_strstr_c(val, "proxy:unix")) { 
                /* Retained for compatibility --  but not for UDS */
                char *tmp = apr_pstrdup(r->pool, val);
                ap_str_tolower(tmp);
                val = tmp;
            }
    
            if (strcmp(val, "none")) { 
                r->handler = val;
            }
        }
        else 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 (here!), 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 AP_REQ_DEFAULT_PATH_INFO.
         * (which the module may interpret to its own customary behavior.)
         * It won't be touched if the value is no longer AP_ACCEPT_PATHINFO_UNSET,
         * 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 != AP_ACCEPT_PATHINFO_UNSET)) {
            /* No module knew better, and the user coded AcceptPathInfo */
            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_core_module_config(r->per_dir_config);
        bld_content_md5 = (d->content_md5 == AP_CONTENT_MD5_ON)
                          && 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 == APR_NOFILE) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00128)
                              "File does not exist: %s",
                              apr_pstrcat(r->pool, r->filename, r->path_info, NULL));
                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_INFO, 0, r, APLOGNO(00129)
                              "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_INFO, 0, r, APLOGNO(00130)
                              "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_core_module_config(r->request_config);
                if (!req_cfg->deliver_script) {
                    /* The flag hasn't been set for this request. Punt. */
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00131)
                                  "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
                                | AP_SENDFILE_ENABLED(d->enable_sendfile)
    #endif
                                        , 0, r->pool)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00132)
                              "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_fd(r, fd);
            ap_set_accept_ranges(r);
            ap_set_content_length(r, r->finfo.size);
            if (bld_content_md5) {
                apr_table_setn(r->headers_out, "Content-MD5",
                               ap_md5digest(r->pool, fd));
            }
    
            bb = apr_brigade_create(r->pool, c->bucket_alloc);
    
            if ((errstatus = ap_meets_conditions(r)) != OK) {
                apr_file_close(fd);
                r->status = errstatus;
            }
            else {
                e = apr_brigade_insert_file(bb, fd, 0, r->finfo.size, r->pool);
    
    #if APR_HAS_MMAP
                if (d->enable_mmap == ENABLE_MMAP_OFF) {
                    (void)apr_bucket_file_enable_mmap(e, 0);
                }
    #endif
    #if APR_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6)
                if (d->read_buf_size) {
                    apr_bucket_file_set_buf_size(e, d->read_buf_size);
                }
    #endif
            }
    
            e = apr_bucket_eos_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(bb, e);
    
            status = ap_pass_brigade(r->output_filters, bb);
            apr_brigade_cleanup(bb);
    
            if (status == APR_SUCCESS
                || r->status != HTTP_OK
                || c->aborted) {
                return OK;
            }
            else {
                /* no way to know what type of error occurred */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(00133)
                              "default_handler: ap_pass_brigade returned %i",
                              status);
                return AP_FILTER_ERROR;
            }
        }
        else {              /* unusual method (not GET or POST) */
            if (r->method_number == M_INVALID) {
                /* See if this looks like an undecrypted SSL handshake attempt.
                 * It's safe to look a couple bytes into the_request if it exists, as it's
                 * always allocated at least MIN_LINE_ALLOC (80) bytes.
                 */
                if (r->the_request
                    && r->the_request[0] == 0x16
                    && (r->the_request[1] == 0x2 || r->the_request[1] == 0x3)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00134)
                                  "Invalid method in request %s - possible attempt to establish SSL connection on non-SSL port", r->the_request);
                } else {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00135)
                                  "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) *ap__logio_add_bytes_out;
    APR_OPTIONAL_FN_TYPE(authz_some_auth_required) *ap__authz_ap_some_auth_required;
    
    /* Insist that at least one module will undertake to provide system
     * security by dropping startup privileges.
     */
    static int sys_privileges = 0;
    AP_DECLARE(int) ap_sys_privileges_handlers(int inc)
    {
        sys_privileges += inc;
        return sys_privileges;
    }
    
    static int check_errorlog_dir(apr_pool_t *p, server_rec *s)
    {
        if (!s->error_fname || s->error_fname[0] == '|'
            || strcmp(s->error_fname, "syslog") == 0
            || strncmp(s->error_fname, "syslog:", 7) == 0) {
            return APR_SUCCESS;
        }
        else {
            char *abs = ap_server_root_relative(p, s->error_fname);
            char *dir = ap_make_dirstr_parent(p, abs);
            apr_finfo_t finfo;
            apr_status_t rv = apr_stat(&finfo, dir, APR_FINFO_TYPE, p);
            if (rv == APR_SUCCESS && finfo.filetype != APR_DIR)
                rv = APR_ENOTDIR;
            if (rv != APR_SUCCESS) {
                const char *desc = "main error log";
                if (s->defn_name)
                    desc = apr_psprintf(p, "error log of vhost defined at %s:%d",
                                        s->defn_name, s->defn_line_number);
                ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, rv,
                              ap_server_conf, APLOGNO(02291)
                             "Cannot access directory '%s' for %s", dir, desc);
                return !OK;
            }
        }
        return OK;
    }
    
    static int core_check_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
    {
        int rv = OK;
        while (s) {
            if (check_errorlog_dir(ptemp, s) != OK)
                rv = !OK;
            s = s->next;
        }
        return rv;
    }
    
    
    static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
    {
        ap_mutex_init(pconf);
    
        if (!saved_server_config_defines)
            init_config_defines(pconf);
        apr_pool_cleanup_register(pconf, NULL, reset_config_defines,
                                  apr_pool_cleanup_null);
    
        ap_regcomp_set_default_cflags(AP_REG_DEFAULT);
    
        mpm_common_pre_config(pconf);
    
        return OK;
    }
    
    static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
    {
        ap__logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out);
        ident_lookup = APR_RETRIEVE_OPTIONAL_FN(ap_ident_lookup);
        ap__authz_ap_some_auth_required = APR_RETRIEVE_OPTIONAL_FN(authz_some_auth_required);
        authn_ap_auth_type = APR_RETRIEVE_OPTIONAL_FN(authn_ap_auth_type);
        authn_ap_auth_name = APR_RETRIEVE_OPTIONAL_FN(authn_ap_auth_name);
        access_compat_ap_satisfies = APR_RETRIEVE_OPTIONAL_FN(access_compat_ap_satisfies);
    
        set_banner(pconf);
        ap_setup_make_content_type(pconf);
        ap_setup_auth_internal(ptemp);
        ap_setup_ssl_optional_fns(pconf);
        if (!sys_privileges) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(00136)
                         "Server MUST relinquish startup privileges before "
                         "accepting connections.  Please ensure mod_unixd "
                         "or other system security module is loaded.");
            return !OK;
        }
        apr_pool_cleanup_register(pconf, NULL, ap_mpm_end_gen_helper,
                                  apr_pool_cleanup_null);
        return OK;
    }
    
    static void core_insert_filter(request_rec *r)
    {
        core_dir_config *conf = (core_dir_config *)
                                ap_get_core_module_config(r->per_dir_config);
        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_core_module_config(r->request_config);
    
        if (!req_cfg) {
            return NULL;
        }
    
        return &(req_cfg->notes[note_num]);
    }
    
    AP_DECLARE(apr_socket_t *) ap_get_conn_socket(conn_rec *c)
    {
        return ap_get_core_module_config(c->conn_config);
    }
    
    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_core_module_config(r->main->request_config);
            req_cfg->bb = main_req_cfg->bb;
        }
        else {
            req_cfg->bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        }
    
        ap_set_core_module_config(r->request_config, req_cfg);
    
        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;
        ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL);
    
        /* Got a connection structure, so initialize what fields we can
         * (the rest are zeroed out by pcalloc).
         */
        c->pool = ptrans;
        c->conn_config = ap_create_conn_config(ptrans);
        c->notes = apr_table_make(ptrans, 5);
    
        if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd))
            != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, APLOGNO(00137)
                         "apr_socket_addr_get(APR_LOCAL)");
            apr_socket_close(csd);
            return NULL;
        }
        if (apr_sockaddr_ip_get(&c->local_ip, c->local_addr)) {
    #if APR_HAVE_SOCKADDR_UN
            if (c->local_addr->family == APR_UNIX) {
                c->local_ip = apr_pstrndup(c->pool, c->local_addr->ipaddr_ptr,
                                           c->local_addr->ipaddr_len);
            }
            else
    #endif
            c->local_ip = apr_pstrdup(c->pool, "unknown");
        }
    
        if ((rv = apr_socket_addr_get(&c->client_addr, APR_REMOTE, csd))
            != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, APLOGNO(00138)
                         "apr_socket_addr_get(APR_REMOTE)");
            apr_socket_close(csd);
            return NULL;
        }
        if (apr_sockaddr_ip_get(&c->client_ip, c->client_addr)) {
    #if APR_HAVE_SOCKADDR_UN
            if (c->client_addr->family == APR_UNIX) {
                c->client_ip = apr_pstrndup(c->pool, c->client_addr->ipaddr_ptr,
                                            c->client_addr->ipaddr_len);
            }
            else
    #endif
            c->client_ip = apr_pstrdup(c->pool, "unknown");
        }
    
        c->base_server = server;
    
        c->id = id;
        c->bucket_alloc = alloc;
    
        c->clogging_input_filters = 0;
    
        return c;
    }
    
    static int core_pre_connection(conn_rec *c, void *csd)
    {
        core_net_rec *net;
        apr_status_t rv;
    
        if (c->master) {
            return DONE;
        }
        
        net = apr_palloc(c->pool, sizeof(*net));
        /* 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, APLOGNO(00139)
                          "apr_socket_opt_set(APR_TCP_NODELAY)");
        }
    
        /* The core filter requires the timeout mode to be set, which
         * incidentally sets the socket to be nonblocking.  If this
         * is not initialized correctly, Linux - for example - will
         * be initially blocking, while Solaris will be non blocking
         * and any initial read will fail.
         */
        rv = apr_socket_timeout_set(csd, c->base_server->timeout);
        if (rv != APR_SUCCESS) {
            /* expected cause is that the client disconnected already */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(00140)
                          "apr_socket_timeout_set");
        }
    
        net->c = c;
        net->in_ctx = NULL;
        net->out_ctx = NULL;
        net->client_socket = csd;
    
        ap_set_core_module_config(net->c->conn_config, 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;
    }
    
    AP_DECLARE(int) ap_pre_connection(conn_rec *c, void *csd)
    {
        int rc = OK;
    
        rc = ap_run_pre_connection(c, csd);
        if (rc != OK && rc != DONE) {
            c->aborted = 1;
            /*
             * In case we errored, the pre_connection hook of the core
             * module maybe did not run (it is APR_HOOK_REALLY_LAST) and
             * hence we missed to
             *
             * - Put the socket in c->conn_config
             * - Setup core output and input filters
             * - Set socket options and timeouts
             *
             * Hence call it in this case.
             */
            if (!ap_get_conn_socket(c)) {
                core_pre_connection(c, csd);
            }
        }
        return rc;
    }
    
    AP_DECLARE(int) ap_state_query(int query)
    {
        switch (query) {
        case AP_SQ_MAIN_STATE:
            return ap_main_state;
        case AP_SQ_RUN_MODE:
            return ap_run_mode;
        case AP_SQ_CONFIG_GEN:
            return ap_config_generation;
        default:
            return AP_SQ_NOT_SUPPORTED;
        }
    }
    
    static apr_random_t *rng = NULL;
    #if APR_HAS_THREADS
    static apr_thread_mutex_t *rng_mutex = NULL;
    #endif
    
    static void core_child_init(apr_pool_t *pchild, server_rec *s)
    {
        apr_proc_t proc;
    #if APR_HAS_THREADS
        int threaded_mpm;
        if (ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded_mpm) == APR_SUCCESS
            && threaded_mpm)
        {
            apr_thread_mutex_create(&rng_mutex, APR_THREAD_MUTEX_DEFAULT, pchild);
        }
    #endif
        /* The MPMs use plain fork() and not apr_proc_fork(), so we have to call
         * apr_random_after_fork() manually in the child
         */
        proc.pid = getpid();
        apr_random_after_fork(&proc);
    }
    
    static void core_optional_fn_retrieve(void)
    {
        ap_init_scoreboard(NULL);
    }
    
    AP_CORE_DECLARE(void) ap_random_parent_after_fork(void)
    {
        /*
         * To ensure that the RNG state in the parent changes after the fork, we
         * pull some data from the RNG and discard it. This ensures that the RNG
         * states in the children are different even after the pid wraps around.
         * As we only use apr_random for insecure random bytes, pulling 2 bytes
         * should be enough.
         * XXX: APR should probably have some dedicated API to do this, but it
         * XXX: currently doesn't.
         */
        apr_uint16_t data;
        apr_random_insecure_bytes(rng, &data, sizeof(data));
    }
    
    AP_CORE_DECLARE(void) ap_init_rng(apr_pool_t *p)
    {
        unsigned char seed[8];
        apr_status_t rv;
        rng = apr_random_standard_new(p);
        do {
            rv = apr_generate_random_bytes(seed, sizeof(seed));
            if (rv != APR_SUCCESS)
                goto error;
            apr_random_add_entropy(rng, seed, sizeof(seed));
            rv = apr_random_insecure_ready(rng);
        } while (rv == APR_ENOTENOUGHENTROPY);
        if (rv == APR_SUCCESS)
            return;
    error:
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00141)
                     "Could not initialize random number generator");
        exit(1);
    }
    
    AP_DECLARE(void) ap_random_insecure_bytes(void *buf, apr_size_t size)
    {
    #if APR_HAS_THREADS
        if (rng_mutex)
            apr_thread_mutex_lock(rng_mutex);
    #endif
        /* apr_random_insecure_bytes can only fail with APR_ENOTENOUGHENTROPY,
         * and we have ruled that out during initialization. Therefore we don't
         * need to check the return code.
         */
        apr_random_insecure_bytes(rng, buf, size);
    #if APR_HAS_THREADS
        if (rng_mutex)
            apr_thread_mutex_unlock(rng_mutex);
    #endif
    }
    
    /*
     * Finding a random number in a range.
     *      n' = a + n(b-a+1)/(M+1)
     * where:
     *      n' = random number in range
     *      a  = low end of range
     *      b  = high end of range
     *      n  = random number of 0..M
     *      M  = maxint
     * Algorithm 'borrowed' from PHP's rand() function.
     */
    #define RAND_RANGE(__n, __min, __max, __tmax) \
    (__n) = (__min) + (long) ((double) ((__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0)))
    AP_DECLARE(apr_uint32_t) ap_random_pick(apr_uint32_t min, apr_uint32_t max)
    {
        apr_uint32_t number;
    #if (!__GNUC__ || __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || \
         !__sparc__ || APR_SIZEOF_VOIDP != 8)
        /* This triggers a gcc bug on sparc/64bit with gcc < 4.8, PR 52900 */
        if (max < 16384) {
            apr_uint16_t num16;
            ap_random_insecure_bytes(&num16, sizeof(num16));
            RAND_RANGE(num16, min, max, APR_UINT16_MAX);
            number = num16;
        }
        else
    #endif
        {
            ap_random_insecure_bytes(&number, sizeof(number));
            RAND_RANGE(number, min, max, APR_UINT32_MAX);
        }
        return number;
    }
    
    static apr_status_t core_insert_network_bucket(conn_rec *c,
                                                   apr_bucket_brigade *bb,
                                                   apr_socket_t *socket)
    {
        apr_bucket *e = apr_bucket_socket_create(socket, c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, e);
        return APR_SUCCESS;
    }
    
    static apr_status_t core_dirwalk_stat(apr_finfo_t *finfo, request_rec *r,
                                          apr_int32_t wanted)
    {
        apr_status_t rv = ap_stat_check(r->filename, r->pool);
        if (rv == APR_SUCCESS) {
            rv = apr_stat(finfo, r->filename, wanted, r->pool);
        }
        return rv;
    }
    
    static void core_dump_config(apr_pool_t *p, server_rec *s)
    {
        core_server_config *sconf = ap_get_core_module_config(s->module_config);
        apr_file_t *out = NULL;
        const char *tmp;
        const char **defines;
        int i;
        if (!ap_exists_config_define("DUMP_RUN_CFG"))
            return;
    
        apr_file_open_stdout(&out, p);
        apr_file_printf(out, "ServerRoot: \"%s\"\n", ap_server_root);
        tmp = ap_server_root_relative(p, sconf->ap_document_root);
        apr_file_printf(out, "Main DocumentRoot: \"%s\"\n", tmp);
        if (s->error_fname[0] != '|'
            && strcmp(s->error_fname, "syslog") != 0
            && strncmp(s->error_fname, "syslog:", 7) != 0)
            tmp = ap_server_root_relative(p, s->error_fname);
        else
            tmp = s->error_fname;
        apr_file_printf(out, "Main ErrorLog: \"%s\"\n", tmp);
        if (ap_scoreboard_fname) {
            tmp = ap_server_root_relative(p, ap_scoreboard_fname);
            apr_file_printf(out, "ScoreBoardFile: \"%s\"\n", tmp);
        }
        ap_dump_mutexes(p, s, out);
        ap_mpm_dump_pidfile(p, out);
    
        defines = (const char **)ap_server_config_defines->elts;
        for (i = 0; i < ap_server_config_defines->nelts; i++) {
            const char *name = defines[i];
            const char *val = NULL;
            if (server_config_defined_vars)
               val = apr_table_get(server_config_defined_vars, name);
            if (val)
                apr_file_printf(out, "Define: %s=%s\n", name, val);
            else
                apr_file_printf(out, "Define: %s\n", name);
        }
    }
    
    static int core_upgrade_handler(request_rec *r)
    {
        conn_rec *c = r->connection;
        const char *upgrade;
    
        if (c->master) {
            /* Not possible to perform an HTTP/1.1 upgrade from a slave
             * connection. */
            return DECLINED;
        }
        
        upgrade = apr_table_get(r->headers_in, "Upgrade");
        if (upgrade && *upgrade) {
            const char *conn = apr_table_get(r->headers_in, "Connection");
            if (ap_find_token(r->pool, conn, "upgrade")) {
                apr_array_header_t *offers = NULL;
                const char *err;
                
                err = ap_parse_token_list_strict(r->pool, upgrade, &offers, 0);
                if (err) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02910)
                                  "parsing Upgrade header: %s", err);
                    return DECLINED;
                }
                
                if (offers && offers->nelts > 0) {
                    const char *protocol = ap_select_protocol(c, r, NULL, offers);
                    if (protocol && strcmp(protocol, ap_get_protocol(c))) {
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02909)
                                      "Upgrade selects '%s'", protocol);
                        /* Let the client know what we are upgrading to. */
                        apr_table_clear(r->headers_out);
                        apr_table_setn(r->headers_out, "Upgrade", protocol);
                        apr_table_setn(r->headers_out, "Connection", "Upgrade");
                        
                        r->status = HTTP_SWITCHING_PROTOCOLS;
                        r->status_line = ap_get_status_line(r->status);
                        ap_send_interim_response(r, 1);
    
                        ap_switch_protocol(c, r, r->server, protocol);
    
                        /* make sure httpd closes the connection after this */
                        c->keepalive = AP_CONN_CLOSE;
                        return DONE;
                    }
                }
            }
        }
        else if (!c->keepalives) {
            /* first request on a master connection, if we have protocols other
             * than the current one enabled here, announce them to the
             * client. If the client is already talking a protocol with requests
             * on slave connections, leave it be. */
            const apr_array_header_t *upgrades;
            ap_get_protocol_upgrades(c, r, NULL, 0, &upgrades);
            if (upgrades && upgrades->nelts > 0) {
                char *protocols = apr_array_pstrcat(r->pool, upgrades, ',');
                apr_table_setn(r->headers_out, "Upgrade", protocols);
                apr_table_setn(r->headers_out, "Connection", "Upgrade");
            }
        }
        
        return DECLINED;
    }
    
    static int core_upgrade_storage(request_rec *r)
    {
        if ((r->method_number == M_OPTIONS) && r->uri && (r->uri[0] == '*') &&
            (r->uri[1] == '\0')) {
            return core_upgrade_handler(r);
        }
        return DECLINED;
    }
    
    static apr_status_t core_get_pollfd_from_conn(conn_rec *c,
                                                  struct apr_pollfd_t *pfd,
                                                  apr_interval_time_t *ptimeout)
    {
        if (c && !c->master) {
            pfd->desc_type = APR_POLL_SOCKET;
            pfd->desc.s = ap_get_conn_socket(c);
            if (ptimeout) {
                apr_socket_timeout_get(pfd->desc.s, ptimeout);
            }
            return APR_SUCCESS;
        }
        return APR_ENOTIMPL;
    }
    
    AP_CORE_DECLARE(apr_status_t) ap_get_pollfd_from_conn(conn_rec *c,
                                          struct apr_pollfd_t *pfd,
                                          apr_interval_time_t *ptimeout)
    {
        return ap_run_get_pollfd_from_conn(c, pfd, ptimeout);
    }
    
    #ifdef WIN32
    static apr_status_t check_unc(const char *path, apr_pool_t *p)
    {
        int i;
        char *s, *teststring;
        apr_status_t rv = APR_EACCES;
        core_server_config *sconf = NULL;
    
        if (!ap_server_conf) {
            return APR_SUCCESS; /* this early, if we have a UNC, it's specified by an admin */
        }
    
        if (!path || (path != ap_strstr_c(path, "\\\\") && 
                    path != ap_strstr_c(path, "//"))) { 
            return APR_SUCCESS; /* not a UNC */
        }
    
        sconf = ap_get_core_module_config(ap_server_conf->module_config);
        s = teststring = apr_pstrdup(p, path);
        *s++ = '/';
        *s++ = '/';
    
        ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, 
                     "check_unc: check converted path %s allowed %d", 
                     teststring,
                     sconf->unc_list ? sconf->unc_list->nelts : 0);
    
        for (i = 0; sconf->unc_list && i < sconf->unc_list->nelts; i++) {
            char *configured_unc = ((char **)sconf->unc_list->elts)[i];
            apr_uri_t uri;
            if (APR_SUCCESS == apr_uri_parse(p, teststring, &uri) &&
                    (uri.hostinfo == NULL || 
                     !ap_cstr_casecmp(uri.hostinfo, configured_unc))) { 
                rv = APR_SUCCESS;
                ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, 
                             "check_unc: match %s %s", 
                             uri.hostinfo, configured_unc);
                break;
            }
            else { 
                ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, 
                             "check_unc: no match %s %s", uri.hostinfo, 
                             configured_unc);
            }
        }
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(10504)
                         "check_unc: UNC path %s not allowed by UNCList", teststring);
        }
    
        return rv;
    }
    #endif
    
    AP_DECLARE(apr_status_t) ap_filepath_merge(char **newpath,
                                                const char *rootpath,
                                                const char *addpath,
                                                apr_int32_t flags,
                                                apr_pool_t *p)
    {
    #ifdef WIN32
        apr_status_t rv;
    
        if (APR_SUCCESS != (rv = check_unc(rootpath, p))) {
            return rv;
        }
        if (APR_SUCCESS != (rv = check_unc(addpath, p))) {
            return rv;
        }
    #undef apr_filepath_merge
    #endif
        return apr_filepath_merge(newpath, rootpath, addpath, flags, p);
    #ifdef WIN32
    #define apr_filepath_merge ap_filepath_merge
    #endif
    }
    
    #ifdef WIN32
    AP_DECLARE(apr_status_t) ap_stat_check(const char *path, apr_pool_t *p)
    {
       return check_unc(path, p);
    }
    #else
    AP_DECLARE(apr_status_t) ap_stat_check(const char *path, apr_pool_t *p)
    {
        return APR_SUCCESS;
    }
    #endif
    
    static void register_hooks(apr_pool_t *p)
    {
        errorlog_hash = apr_hash_make(p);
        ap_register_log_hooks(p);
        ap_register_config_hooks(p);
        ap_expr_init(p);
    
        /* create_connection and pre_connection should always be hooked
         * APR_HOOK_REALLY_LAST by core 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_pre_config(core_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
        ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST);
        ap_hook_check_config(core_check_config,NULL,NULL,APR_HOOK_FIRST);
        ap_hook_test_config(core_dump_config,NULL,NULL,APR_HOOK_FIRST);
        ap_hook_translate_name(ap_core_translate,NULL,NULL,APR_HOOK_REALLY_LAST);
        ap_hook_map_to_storage(core_upgrade_storage,NULL,NULL,APR_HOOK_REALLY_FIRST);
        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(core_child_init,NULL,NULL,APR_HOOK_REALLY_FIRST);
        ap_hook_child_init(ap_logs_child_init,NULL,NULL,APR_HOOK_MIDDLE);
        ap_hook_handler(core_upgrade_handler,NULL,NULL,APR_HOOK_REALLY_FIRST);
        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_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);
        ap_hook_child_status(ap_core_child_status, NULL, NULL, APR_HOOK_MIDDLE);
        ap_hook_insert_network_bucket(core_insert_network_bucket, NULL, NULL,
                                      APR_HOOK_REALLY_LAST);
        ap_hook_dirwalk_stat(core_dirwalk_stat, NULL, NULL, APR_HOOK_REALLY_LAST);
        ap_hook_open_htaccess(ap_open_htaccess, NULL, NULL, APR_HOOK_REALLY_LAST);
        ap_hook_optional_fn_retrieve(core_optional_fn_retrieve, NULL, NULL,
                                     APR_HOOK_MIDDLE);
        ap_hook_get_pollfd_from_conn(core_get_pollfd_from_conn, NULL, NULL,
                                     APR_HOOK_REALLY_LAST);
    
        /* 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_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_MODULE(core) = {
        MPM20_MODULE_STUFF,
        AP_PLATFORM_REWRITE_ARGS_HOOK, /* hook to run before apache parses args */
        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 */
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_expr_parse.c���������������������������������������������������������������0000664�0001751�0001751�00000172515�15032766627�017532� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.5.  */
    
    /* Bison implementation for Yacc-like parsers in C
       
          Copyright (C) 1984, 1989-1990, 2000-2011 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.  */
    
    /* As a special exception, you may create a larger work that contains
       part or all of the Bison parser skeleton and distribute that work
       under terms of your choice, so long as that work isn't itself a
       parser generator using the skeleton or a modified version thereof
       as a parser skeleton.  Alternatively, if you modify or redistribute
       the parser skeleton itself, you may (at your option) remove this
       special exception, which will cause the skeleton and the resulting
       Bison output files to be licensed under the GNU General Public
       License without this special exception.
       
       This special exception was added by the Free Software Foundation in
       version 2.2 of Bison.  */
    
    /* C LALR(1) parser skeleton written by Richard Stallman, by
       simplifying the original so-called "semantic" parser.  */
    
    /* All symbols defined below should begin with yy or YY, to avoid
       infringing on user name space.  This should be done even for local
       variables, as they might otherwise be expanded by user macros.
       There are some unavoidable exceptions within include files to
       define necessary library symbols; they are noted "INFRINGES ON
       USER NAME SPACE" below.  */
    
    /* Identify Bison output.  */
    #define YYBISON 1
    
    /* Bison version.  */
    #define YYBISON_VERSION "2.5"
    
    /* Skeleton name.  */
    #define YYSKELETON_NAME "yacc.c"
    
    /* Pure parsers.  */
    #define YYPURE 1
    
    /* Push parsers.  */
    #define YYPUSH 0
    
    /* Pull parsers.  */
    #define YYPULL 1
    
    /* Using locations.  */
    #define YYLSP_NEEDED 0
    
    /* Substitute the variable and function names.  */
    #define yyparse         ap_expr_yyparse
    #define yylex           ap_expr_yylex
    #define yyerror         ap_expr_yyerror
    #define yylval          ap_expr_yylval
    #define yychar          ap_expr_yychar
    #define yydebug         ap_expr_yydebug
    #define yynerrs         ap_expr_yynerrs
    
    
    /* Copy the first part of user declarations.  */
    
    /* Line 268 of yacc.c  */
    #line 31 "util_expr_parse.y"
    
    #include "util_expr_private.h"
    
    
    /* Line 268 of yacc.c  */
    #line 84 "util_expr_parse.c"
    
    /* Enabling traces.  */
    #ifndef YYDEBUG
    # define YYDEBUG 0
    #endif
    
    /* Enabling verbose error messages.  */
    #ifdef YYERROR_VERBOSE
    # undef YYERROR_VERBOSE
    # define YYERROR_VERBOSE 1
    #else
    # define YYERROR_VERBOSE 1
    #endif
    
    /* Enabling the token table.  */
    #ifndef YYTOKEN_TABLE
    # define YYTOKEN_TABLE 0
    #endif
    
    
    /* Tokens.  */
    #ifndef YYTOKENTYPE
    # define YYTOKENTYPE
       /* Put the tokens into the symbol table, so that GDB and other debuggers
          know about them.  */
       enum yytokentype {
         T_TRUE = 258,
         T_FALSE = 259,
         T_EXPR_BOOL = 260,
         T_EXPR_STRING = 261,
         T_ERROR = 262,
         T_DIGIT = 263,
         T_ID = 264,
         T_STRING = 265,
         T_REGEX = 266,
         T_REGEX_I = 267,
         T_REGEX_BACKREF = 268,
         T_OP_UNARY = 269,
         T_OP_BINARY = 270,
         T_STR_BEGIN = 271,
         T_STR_END = 272,
         T_VAR_BEGIN = 273,
         T_VAR_END = 274,
         T_OP_EQ = 275,
         T_OP_NE = 276,
         T_OP_LT = 277,
         T_OP_LE = 278,
         T_OP_GT = 279,
         T_OP_GE = 280,
         T_OP_REG = 281,
         T_OP_NRE = 282,
         T_OP_IN = 283,
         T_OP_STR_EQ = 284,
         T_OP_STR_NE = 285,
         T_OP_STR_LT = 286,
         T_OP_STR_LE = 287,
         T_OP_STR_GT = 288,
         T_OP_STR_GE = 289,
         T_OP_CONCAT = 290,
         T_OP_OR = 291,
         T_OP_AND = 292,
         T_OP_NOT = 293
       };
    #endif
    
    
    
    #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
    typedef union YYSTYPE
    {
    
    /* Line 293 of yacc.c  */
    #line 35 "util_expr_parse.y"
    
        char      *cpVal;
        ap_expr_t *exVal;
        int        num;
    
    
    
    /* Line 293 of yacc.c  */
    #line 166 "util_expr_parse.c"
    } YYSTYPE;
    # define YYSTYPE_IS_TRIVIAL 1
    # define yystype YYSTYPE /* obsolescent; will be withdrawn */
    # define YYSTYPE_IS_DECLARED 1
    #endif
    
    
    /* Copy the second part of user declarations.  */
    
    /* Line 343 of yacc.c  */
    #line 102 "util_expr_parse.y"
    
    #include "util_expr_private.h"
    #define yyscanner ctx->scanner
    
    int ap_expr_yylex(YYSTYPE *lvalp, void *scanner);
    
    
    /* Line 343 of yacc.c  */
    #line 186 "util_expr_parse.c"
    
    #ifdef short
    # undef short
    #endif
    
    #ifdef YYTYPE_UINT8
    typedef YYTYPE_UINT8 yytype_uint8;
    #else
    typedef unsigned char yytype_uint8;
    #endif
    
    #ifdef YYTYPE_INT8
    typedef YYTYPE_INT8 yytype_int8;
    #elif (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    typedef signed char yytype_int8;
    #else
    typedef short int yytype_int8;
    #endif
    
    #ifdef YYTYPE_UINT16
    typedef YYTYPE_UINT16 yytype_uint16;
    #else
    typedef unsigned short int yytype_uint16;
    #endif
    
    #ifdef YYTYPE_INT16
    typedef YYTYPE_INT16 yytype_int16;
    #else
    typedef short int yytype_int16;
    #endif
    
    #ifndef YYSIZE_T
    # ifdef __SIZE_TYPE__
    #  define YYSIZE_T __SIZE_TYPE__
    # elif defined size_t
    #  define YYSIZE_T size_t
    # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
    #  define YYSIZE_T size_t
    # else
    #  define YYSIZE_T unsigned int
    # endif
    #endif
    
    #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
    
    #ifndef YY_
    # if defined YYENABLE_NLS && YYENABLE_NLS
    #  if ENABLE_NLS
    #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
    #   define YY_(msgid) dgettext ("bison-runtime", msgid)
    #  endif
    # endif
    # ifndef YY_
    #  define YY_(msgid) msgid
    # endif
    #endif
    
    /* Suppress unused-variable warnings by "using" E.  */
    #if ! defined lint || defined __GNUC__
    # define YYUSE(e) ((void) (e))
    #else
    # define YYUSE(e) /* empty */
    #endif
    
    /* Identity function, used to suppress warnings about constant conditions.  */
    #ifndef lint
    # define YYID(n) (n)
    #else
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static int
    YYID (int yyi)
    #else
    static int
    YYID (yyi)
        int yyi;
    #endif
    {
      return yyi;
    }
    #endif
    
    #if ! defined yyoverflow || YYERROR_VERBOSE
    
    /* The parser invokes alloca or malloc; define the necessary symbols.  */
    
    # ifdef YYSTACK_USE_ALLOCA
    #  if YYSTACK_USE_ALLOCA
    #   ifdef __GNUC__
    #    define YYSTACK_ALLOC __builtin_alloca
    #   elif defined __BUILTIN_VA_ARG_INCR
    #    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
    #   elif defined _AIX
    #    define YYSTACK_ALLOC __alloca
    #   elif defined _MSC_VER
    #    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
    #    define alloca _alloca
    #   else
    #    define YYSTACK_ALLOC alloca
    #    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
    #     ifndef EXIT_SUCCESS
    #      define EXIT_SUCCESS 0
    #     endif
    #    endif
    #   endif
    #  endif
    # endif
    
    # ifdef YYSTACK_ALLOC
       /* Pacify GCC's `empty if-body' warning.  */
    #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
    #  ifndef YYSTACK_ALLOC_MAXIMUM
        /* The OS might guarantee only one guard page at the bottom of the stack,
           and a page size can be as small as 4096 bytes.  So we cannot safely
           invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
           to allow for a few compiler-allocated temporary stack slots.  */
    #   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
    #  endif
    # else
    #  define YYSTACK_ALLOC YYMALLOC
    #  define YYSTACK_FREE YYFREE
    #  ifndef YYSTACK_ALLOC_MAXIMUM
    #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
    #  endif
    #  if (defined __cplusplus && ! defined EXIT_SUCCESS \
           && ! ((defined YYMALLOC || defined malloc) \
    	     && (defined YYFREE || defined free)))
    #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
    #   ifndef EXIT_SUCCESS
    #    define EXIT_SUCCESS 0
    #   endif
    #  endif
    #  ifndef YYMALLOC
    #   define YYMALLOC malloc
    #   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
    #   endif
    #  endif
    #  ifndef YYFREE
    #   define YYFREE free
    #   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    void free (void *); /* INFRINGES ON USER NAME SPACE */
    #   endif
    #  endif
    # endif
    #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
    
    
    #if (! defined yyoverflow \
         && (! defined __cplusplus \
    	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
    
    /* A type that is properly aligned for any stack member.  */
    union yyalloc
    {
      yytype_int16 yyss_alloc;
      YYSTYPE yyvs_alloc;
    };
    
    /* The size of the maximum gap between one aligned stack and the next.  */
    # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
    
    /* The size of an array large to enough to hold all stacks, each with
       N elements.  */
    # define YYSTACK_BYTES(N) \
         ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
          + YYSTACK_GAP_MAXIMUM)
    
    # define YYCOPY_NEEDED 1
    
    /* Relocate STACK from its old location to the new one.  The
       local variables YYSIZE and YYSTACKSIZE give the old and new number of
       elements in the stack, and YYPTR gives the new location of the
       stack.  Advance YYPTR to a properly aligned location for the next
       stack.  */
    # define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
        do									\
          {									\
    	YYSIZE_T yynewbytes;						\
    	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
    	Stack = &yyptr->Stack_alloc;					\
    	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
    	yyptr += yynewbytes / sizeof (*yyptr);				\
          }									\
        while (YYID (0))
    
    #endif
    
    #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
    /* Copy COUNT objects from FROM to TO.  The source and destination do
       not overlap.  */
    # ifndef YYCOPY
    #  if defined __GNUC__ && 1 < __GNUC__
    #   define YYCOPY(To, From, Count) \
          __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
    #  else
    #   define YYCOPY(To, From, Count)		\
          do					\
    	{					\
    	  YYSIZE_T yyi;				\
    	  for (yyi = 0; yyi < (Count); yyi++)	\
    	    (To)[yyi] = (From)[yyi];		\
    	}					\
          while (YYID (0))
    #  endif
    # endif
    #endif /* !YYCOPY_NEEDED */
    
    /* YYFINAL -- State number of the termination state.  */
    #define YYFINAL  28
    /* YYLAST -- Last index in YYTABLE.  */
    #define YYLAST   128
    
    /* YYNTOKENS -- Number of terminals.  */
    #define YYNTOKENS  45
    /* YYNNTS -- Number of nonterminals.  */
    #define YYNNTS  14
    /* YYNRULES -- Number of rules.  */
    #define YYNRULES  53
    /* YYNRULES -- Number of states.  */
    #define YYNSTATES  96
    
    /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
    #define YYUNDEFTOK  2
    #define YYMAXUTOK   293
    
    #define YYTRANSLATE(YYX)						\
      ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
    
    /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
    static const yytype_uint8 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,     2,     2,     2,
          39,    40,     2,     2,    43,     2,     2,     2,     2,     2,
           2,     2,     2,     2,     2,     2,     2,     2,    44,     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,    41,     2,    42,     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,     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
    };
    
    #if YYDEBUG
    /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
       YYRHS.  */
    static const yytype_uint8 yyprhs[] =
    {
           0,     0,     3,     6,     9,    11,    13,    15,    18,    22,
          26,    28,    31,    35,    39,    41,    45,    49,    53,    57,
          61,    65,    69,    73,    77,    81,    85,    89,    93,    97,
         101,   103,   107,   109,   113,   116,   118,   120,   122,   124,
         126,   130,   136,   138,   142,   144,   146,   148,   152,   155,
         157,   159,   161,   166
    };
    
    /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
    static const yytype_int8 yyrhs[] =
    {
          46,     0,    -1,     5,    47,    -1,     6,    51,    -1,     7,
          -1,     3,    -1,     4,    -1,    38,    47,    -1,    47,    36,
          47,    -1,    47,    37,    47,    -1,    48,    -1,    14,    54,
          -1,    54,    15,    54,    -1,    39,    47,    40,    -1,     7,
          -1,    54,    20,    54,    -1,    54,    21,    54,    -1,    54,
          22,    54,    -1,    54,    23,    54,    -1,    54,    24,    54,
          -1,    54,    25,    54,    -1,    54,    29,    54,    -1,    54,
          30,    54,    -1,    54,    31,    54,    -1,    54,    32,    54,
          -1,    54,    33,    54,    -1,    54,    34,    54,    -1,    54,
          28,    49,    -1,    54,    26,    55,    -1,    54,    27,    55,
          -1,    57,    -1,    41,    50,    42,    -1,    54,    -1,    50,
          43,    54,    -1,    51,    52,    -1,    52,    -1,     7,    -1,
          10,    -1,    53,    -1,    56,    -1,    18,     9,    19,    -1,
          18,     9,    44,    51,    19,    -1,     8,    -1,    54,    35,
          54,    -1,    53,    -1,    56,    -1,    58,    -1,    16,    51,
          17,    -1,    16,    17,    -1,    11,    -1,    12,    -1,    13,
          -1,     9,    39,    54,    40,    -1,     9,    39,    54,    40,
          -1
    };
    
    /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
    static const yytype_uint8 yyrline[] =
    {
           0,   112,   112,   113,   114,   117,   118,   119,   120,   121,
         122,   123,   124,   125,   126,   129,   130,   131,   132,   133,
         134,   135,   136,   137,   138,   139,   140,   141,   142,   143,
         146,   147,   150,   151,   154,   155,   156,   159,   160,   161,
         164,   165,   168,   169,   170,   171,   172,   173,   174,   177,
         186,   197,   204,   207
    };
    #endif
    
    #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
    /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
       First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
    static const char *const yytname[] =
    {
      "$end", "error", "$undefined", "T_TRUE", "T_FALSE", "T_EXPR_BOOL",
      "T_EXPR_STRING", "T_ERROR", "T_DIGIT", "T_ID", "T_STRING", "T_REGEX",
      "T_REGEX_I", "T_REGEX_BACKREF", "T_OP_UNARY", "T_OP_BINARY",
      "T_STR_BEGIN", "T_STR_END", "T_VAR_BEGIN", "T_VAR_END", "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_STR_EQ", "T_OP_STR_NE", "T_OP_STR_LT",
      "T_OP_STR_LE", "T_OP_STR_GT", "T_OP_STR_GE", "T_OP_CONCAT", "T_OP_OR",
      "T_OP_AND", "T_OP_NOT", "'('", "')'", "'{'", "'}'", "','", "':'",
      "$accept", "root", "expr", "comparison", "wordlist", "words", "string",
      "strpart", "var", "word", "regex", "backref", "lstfunccall",
      "strfunccall", 0
    };
    #endif
    
    # ifdef YYPRINT
    /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
       token YYLEX-NUM.  */
    static const yytype_uint16 yytoknum[] =
    {
           0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
         265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
         275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
         285,   286,   287,   288,   289,   290,   291,   292,   293,    40,
          41,   123,   125,    44,    58
    };
    # endif
    
    /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
    static const yytype_uint8 yyr1[] =
    {
           0,    45,    46,    46,    46,    47,    47,    47,    47,    47,
          47,    47,    47,    47,    47,    48,    48,    48,    48,    48,
          48,    48,    48,    48,    48,    48,    48,    48,    48,    48,
          49,    49,    50,    50,    51,    51,    51,    52,    52,    52,
          53,    53,    54,    54,    54,    54,    54,    54,    54,    55,
          55,    56,    57,    58
    };
    
    /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
    static const yytype_uint8 yyr2[] =
    {
           0,     2,     2,     2,     1,     1,     1,     2,     3,     3,
           1,     2,     3,     3,     1,     3,     3,     3,     3,     3,
           3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
           1,     3,     1,     3,     2,     1,     1,     1,     1,     1,
           3,     5,     1,     3,     1,     1,     1,     3,     2,     1,
           1,     1,     4,     4
    };
    
    /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
       Performed when YYTABLE doesn't specify something else to do.  Zero
       means the default is an error.  */
    static const yytype_uint8 yydefact[] =
    {
           0,     0,     0,     4,     0,     5,     6,    14,    42,     0,
          51,     0,     0,     0,     0,     0,     2,    10,    44,     0,
          45,    46,    36,    37,     3,    35,    38,    39,     1,     0,
          11,    48,     0,     0,     7,     0,     0,     0,     0,     0,
           0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
           0,     0,     0,     0,     0,    34,     0,    47,    40,     0,
          13,     8,     9,    12,    15,    16,    17,    18,    19,    20,
          49,    50,    28,    29,     0,     0,    27,    30,    21,    22,
          23,    24,    25,    26,    43,    53,     0,     0,     0,    32,
          41,     0,    31,     0,    52,    33
    };
    
    /* YYDEFGOTO[NTERM-NUM].  */
    static const yytype_int8 yydefgoto[] =
    {
          -1,     4,    16,    17,    76,    88,    24,    25,    18,    19,
          72,    20,    77,    21
    };
    
    /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
       STATE-NUM.  */
    #define YYPACT_NINF -35
    static const yytype_int8 yypact[] =
    {
          48,    60,    73,   -35,     7,   -35,   -35,   -35,   -35,   -34,
         -35,    43,     8,    11,    60,    60,    86,   -35,   -35,    80,
         -35,   -35,   -35,   -35,   108,   -35,   -35,   -35,   -35,    43,
          25,   -35,    79,   -17,   -35,    -8,    60,    60,    43,    43,
          43,    43,    43,    43,    43,     5,     5,     0,    43,    43,
          43,    43,    43,    43,    43,   -35,   -27,   -35,   -35,    73,
         -35,    86,     3,    25,    25,    25,    25,    25,    25,    25,
         -35,   -35,   -35,   -35,    23,    43,   -35,   -35,    25,    25,
          25,    25,    25,    25,    25,   -35,   106,    43,    85,    25,
         -35,   -21,   -35,    43,   -35,    25
    };
    
    /* YYPGOTO[NTERM-NUM].  */
    static const yytype_int8 yypgoto[] =
    {
         -35,   -35,    57,   -35,   -35,   -35,    -9,   -20,    -2,    -5,
          -4,    -1,   -35,   -35
    };
    
    /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
       positive, shift that token.  If negative, reduce the rule which
       number is the opposite.  If YYTABLE_NINF, syntax error.  */
    #define YYTABLE_NINF -1
    static const yytype_uint8 yytable[] =
    {
          26,    27,    58,    32,    55,    29,    30,    28,    54,    74,
          26,    27,    55,    85,    54,    22,    70,    71,    23,    94,
          33,    10,    26,    27,    56,    31,    13,    59,    36,    37,
          26,    27,    60,    63,    64,    65,    66,    67,    68,    69,
          37,    75,    73,    78,    79,    80,    81,    82,    83,    84,
          86,     8,     9,     1,     2,     3,    10,    26,    27,    12,
          54,    13,    87,     5,     6,     0,    55,     7,     8,     9,
          89,    34,    35,    10,    11,     0,    12,     0,    13,     0,
          22,     0,    91,    23,    26,    27,    10,     0,    95,    23,
           0,    13,    10,    61,    62,    38,    57,    13,    14,    15,
          39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
          49,    50,    51,    52,    53,    54,    23,     0,    23,    10,
           0,    10,    36,    37,    13,    90,    13,    92,    93
    };
    
    #define yypact_value_is_default(yystate) \
      ((yystate) == (-35))
    
    #define yytable_value_is_error(yytable_value) \
      YYID (0)
    
    static const yytype_int8 yycheck[] =
    {
           2,     2,    19,    12,    24,    39,    11,     0,    35,     9,
          12,    12,    32,    40,    35,     7,    11,    12,    10,    40,
           9,    13,    24,    24,    29,    17,    18,    44,    36,    37,
          32,    32,    40,    38,    39,    40,    41,    42,    43,    44,
          37,    41,    46,    48,    49,    50,    51,    52,    53,    54,
          59,     8,     9,     5,     6,     7,    13,    59,    59,    16,
          35,    18,    39,     3,     4,    -1,    86,     7,     8,     9,
          75,    14,    15,    13,    14,    -1,    16,    -1,    18,    -1,
           7,    -1,    87,    10,    86,    86,    13,    -1,    93,    10,
          -1,    18,    13,    36,    37,    15,    17,    18,    38,    39,
          20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
          30,    31,    32,    33,    34,    35,    10,    -1,    10,    13,
          -1,    13,    36,    37,    18,    19,    18,    42,    43
    };
    
    /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
       symbol of state STATE-NUM.  */
    static const yytype_uint8 yystos[] =
    {
           0,     5,     6,     7,    46,     3,     4,     7,     8,     9,
          13,    14,    16,    18,    38,    39,    47,    48,    53,    54,
          56,    58,     7,    10,    51,    52,    53,    56,     0,    39,
          54,    17,    51,     9,    47,    47,    36,    37,    15,    20,
          21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
          31,    32,    33,    34,    35,    52,    54,    17,    19,    44,
          40,    47,    47,    54,    54,    54,    54,    54,    54,    54,
          11,    12,    55,    55,     9,    41,    49,    57,    54,    54,
          54,    54,    54,    54,    54,    40,    51,    39,    50,    54,
          19,    54,    42,    43,    40,    54
    };
    
    #define yyerrok		(yyerrstatus = 0)
    #define yyclearin	(yychar = YYEMPTY)
    #define YYEMPTY		(-2)
    #define YYEOF		0
    
    #define YYACCEPT	goto yyacceptlab
    #define YYABORT		goto yyabortlab
    #define YYERROR		goto yyerrorlab
    
    
    /* Like YYERROR except do call 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.  However,
       YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
       in Bison 2.4.2's NEWS entry, where a plan to phase it out is
       discussed.  */
    
    #define YYFAIL		goto yyerrlab
    #if defined YYFAIL
      /* This is here to suppress warnings from the GCC cpp's
         -Wunused-macros.  Normally we don't worry about that warning, but
         some users do, and we want to make it easy for users to remove
         YYFAIL uses, which will produce warnings from Bison 2.5.  */
    #endif
    
    #define YYRECOVERING()  (!!yyerrstatus)
    
    #define YYBACKUP(Token, Value)					\
    do								\
      if (yychar == YYEMPTY && yylen == 1)				\
        {								\
          yychar = (Token);						\
          yylval = (Value);						\
          YYPOPSTACK (1);						\
          goto yybackup;						\
        }								\
      else								\
        {								\
          yyerror (ctx, YY_("syntax error: cannot back up")); \
          YYERROR;							\
        }								\
    while (YYID (0))
    
    
    #define YYTERROR	1
    #define YYERRCODE	256
    
    
    /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
       If N is 0, then set CURRENT to the empty location which ends
       the previous symbol: RHS[0] (always defined).  */
    
    #define YYRHSLOC(Rhs, K) ((Rhs)[K])
    #ifndef YYLLOC_DEFAULT
    # define YYLLOC_DEFAULT(Current, Rhs, N)				\
        do									\
          if (YYID (N))                                                    \
    	{								\
    	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
    	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
    	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
    	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
    	}								\
          else								\
    	{								\
    	  (Current).first_line   = (Current).last_line   =		\
    	    YYRHSLOC (Rhs, 0).last_line;				\
    	  (Current).first_column = (Current).last_column =		\
    	    YYRHSLOC (Rhs, 0).last_column;				\
    	}								\
        while (YYID (0))
    #endif
    
    
    /* This macro is provided for backward compatibility. */
    
    #ifndef YY_LOCATION_PRINT
    # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
    #endif
    
    
    /* YYLEX -- calling `yylex' with the right arguments.  */
    
    #ifdef YYLEX_PARAM
    # define YYLEX yylex (&yylval, YYLEX_PARAM)
    #else
    # define YYLEX yylex (&yylval, yyscanner)
    #endif
    
    /* Enable debugging if requested.  */
    #if YYDEBUG
    
    # ifndef YYFPRINTF
    #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
    #  define YYFPRINTF fprintf
    # endif
    
    # define YYDPRINTF(Args)			\
    do {						\
      if (yydebug)					\
        YYFPRINTF Args;				\
    } while (YYID (0))
    
    # define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
    do {									  \
      if (yydebug)								  \
        {									  \
          YYFPRINTF (stderr, "%s ", Title);					  \
          yy_symbol_print (stderr,						  \
    		  Type, Value, ctx); \
          YYFPRINTF (stderr, "\n");						  \
        }									  \
    } while (YYID (0))
    
    
    /*--------------------------------.
    | Print this symbol on YYOUTPUT.  |
    `--------------------------------*/
    
    /*ARGSUSED*/
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static void
    yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ap_expr_parse_ctx_t *ctx)
    #else
    static void
    yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx)
        FILE *yyoutput;
        int yytype;
        YYSTYPE const * const yyvaluep;
        ap_expr_parse_ctx_t *ctx;
    #endif
    {
      if (!yyvaluep)
        return;
      YYUSE (ctx);
    # ifdef YYPRINT
      if (yytype < YYNTOKENS)
        YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
    # else
      YYUSE (yyoutput);
    # endif
      switch (yytype)
        {
          default:
    	break;
        }
    }
    
    
    /*--------------------------------.
    | Print this symbol on YYOUTPUT.  |
    `--------------------------------*/
    
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static void
    yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ap_expr_parse_ctx_t *ctx)
    #else
    static void
    yy_symbol_print (yyoutput, yytype, yyvaluep, ctx)
        FILE *yyoutput;
        int yytype;
        YYSTYPE const * const yyvaluep;
        ap_expr_parse_ctx_t *ctx;
    #endif
    {
      if (yytype < YYNTOKENS)
        YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
      else
        YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
    
      yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx);
      YYFPRINTF (yyoutput, ")");
    }
    
    /*------------------------------------------------------------------.
    | yy_stack_print -- Print the state stack from its BOTTOM up to its |
    | TOP (included).                                                   |
    `------------------------------------------------------------------*/
    
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static void
    yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
    #else
    static void
    yy_stack_print (yybottom, yytop)
        yytype_int16 *yybottom;
        yytype_int16 *yytop;
    #endif
    {
      YYFPRINTF (stderr, "Stack now");
      for (; yybottom <= yytop; yybottom++)
        {
          int yybot = *yybottom;
          YYFPRINTF (stderr, " %d", yybot);
        }
      YYFPRINTF (stderr, "\n");
    }
    
    # define YY_STACK_PRINT(Bottom, Top)				\
    do {								\
      if (yydebug)							\
        yy_stack_print ((Bottom), (Top));				\
    } while (YYID (0))
    
    
    /*------------------------------------------------.
    | Report that the YYRULE is going to be reduced.  |
    `------------------------------------------------*/
    
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static void
    yy_reduce_print (YYSTYPE *yyvsp, int yyrule, ap_expr_parse_ctx_t *ctx)
    #else
    static void
    yy_reduce_print (yyvsp, yyrule, ctx)
        YYSTYPE *yyvsp;
        int yyrule;
        ap_expr_parse_ctx_t *ctx;
    #endif
    {
      int yynrhs = yyr2[yyrule];
      int yyi;
      unsigned long int yylno = yyrline[yyrule];
      YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
    	     yyrule - 1, yylno);
      /* The symbols being reduced.  */
      for (yyi = 0; yyi < yynrhs; yyi++)
        {
          YYFPRINTF (stderr, "   $%d = ", yyi + 1);
          yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
    		       &(yyvsp[(yyi + 1) - (yynrhs)])
    		       		       , ctx);
          YYFPRINTF (stderr, "\n");
        }
    }
    
    # define YY_REDUCE_PRINT(Rule)		\
    do {					\
      if (yydebug)				\
        yy_reduce_print (yyvsp, Rule, ctx); \
    } while (YYID (0))
    
    /* Nonzero means print parse trace.  It is left uninitialized so that
       multiple parsers can coexist.  */
    int yydebug;
    #else /* !YYDEBUG */
    # define YYDPRINTF(Args)
    # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
    # define YY_STACK_PRINT(Bottom, Top)
    # define YY_REDUCE_PRINT(Rule)
    #endif /* !YYDEBUG */
    
    
    /* YYINITDEPTH -- initial size of the parser's stacks.  */
    #ifndef	YYINITDEPTH
    # define YYINITDEPTH 200
    #endif
    
    /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
       if the built-in stack extension method is used).
    
       Do not make this value too large; the results are undefined if
       YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
       evaluated with infinite-precision integer arithmetic.  */
    
    #ifndef YYMAXDEPTH
    # define YYMAXDEPTH 10000
    #endif
    
    
    #if YYERROR_VERBOSE
    
    # ifndef yystrlen
    #  if defined __GLIBC__ && defined _STRING_H
    #   define yystrlen strlen
    #  else
    /* Return the length of YYSTR.  */
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static YYSIZE_T
    yystrlen (const char *yystr)
    #else
    static YYSIZE_T
    yystrlen (yystr)
        const char *yystr;
    #endif
    {
      YYSIZE_T yylen;
      for (yylen = 0; yystr[yylen]; yylen++)
        continue;
      return yylen;
    }
    #  endif
    # endif
    
    # ifndef yystpcpy
    #  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
    #   define yystpcpy stpcpy
    #  else
    /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
       YYDEST.  */
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static char *
    yystpcpy (char *yydest, const char *yysrc)
    #else
    static char *
    yystpcpy (yydest, yysrc)
        char *yydest;
        const char *yysrc;
    #endif
    {
      char *yyd = yydest;
      const char *yys = yysrc;
    
      while ((*yyd++ = *yys++) != '\0')
        continue;
    
      return yyd - 1;
    }
    #  endif
    # endif
    
    # ifndef yytnamerr
    /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
       quotes and backslashes, so that it's suitable for yyerror.  The
       heuristic is that double-quoting is unnecessary unless the string
       contains an apostrophe, a comma, or backslash (other than
       backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
       null, do not copy; instead, return the length of what the result
       would have been.  */
    static YYSIZE_T
    yytnamerr (char *yyres, const char *yystr)
    {
      if (*yystr == '"')
        {
          YYSIZE_T yyn = 0;
          char const *yyp = yystr;
    
          for (;;)
    	switch (*++yyp)
    	  {
    	  case '\'':
    	  case ',':
    	    goto do_not_strip_quotes;
    
    	  case '\\':
    	    if (*++yyp != '\\')
    	      goto do_not_strip_quotes;
    	    /* Fall through.  */
    	  default:
    	    if (yyres)
    	      yyres[yyn] = *yyp;
    	    yyn++;
    	    break;
    
    	  case '"':
    	    if (yyres)
    	      yyres[yyn] = '\0';
    	    return yyn;
    	  }
        do_not_strip_quotes: ;
        }
    
      if (! yyres)
        return yystrlen (yystr);
    
      return yystpcpy (yyres, yystr) - yyres;
    }
    # endif
    
    /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
       about the unexpected token YYTOKEN for the state stack whose top is
       YYSSP.
    
       Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
       not large enough to hold the message.  In that case, also set
       *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
       required number of bytes is too large to store.  */
    static int
    yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                    yytype_int16 *yyssp, int yytoken)
    {
      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
      YYSIZE_T yysize = yysize0;
      YYSIZE_T yysize1;
      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
      /* Internationalized format string. */
      const char *yyformat = 0;
      /* Arguments of yyformat. */
      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
      /* Number of reported tokens (one for the "unexpected", one per
         "expected"). */
      int yycount = 0;
    
      /* There are many possibilities here to consider:
         - Assume YYFAIL is not used.  It's too flawed to consider.  See
           <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
           for details.  YYERROR is fine as it does not invoke this
           function.
         - If this state is a consistent state with a default action, then
           the only way this function was invoked is if the default action
           is an error action.  In that case, don't check for expected
           tokens because there are none.
         - The only way there can be no lookahead present (in yychar) is if
           this state is a consistent state with a default action.  Thus,
           detecting the absence of a lookahead is sufficient to determine
           that there is no unexpected or expected token to report.  In that
           case, just report a simple "syntax error".
         - Don't assume there isn't a lookahead just because this state is a
           consistent state with a default action.  There might have been a
           previous inconsistent state, consistent state with a non-default
           action, or user semantic action that manipulated yychar.
         - Of course, the expected token list depends on states to have
           correct lookahead information, and it depends on the parser not
           to perform extra reductions after fetching a lookahead from the
           scanner and before detecting a syntax error.  Thus, state merging
           (from LALR or IELR) and default reductions corrupt the expected
           token list.  However, the list is correct for canonical LR with
           one exception: it will still contain any token that will not be
           accepted due to an error action in a later state.
      */
      if (yytoken != YYEMPTY)
        {
          int yyn = yypact[*yyssp];
          yyarg[yycount++] = yytname[yytoken];
          if (!yypact_value_is_default (yyn))
            {
              /* Start YYX at -YYN if negative to avoid negative indexes in
                 YYCHECK.  In other words, skip the first -YYN actions for
                 this state because they are default actions.  */
              int yyxbegin = yyn < 0 ? -yyn : 0;
              /* Stay within bounds of both yycheck and yytname.  */
              int yychecklim = YYLAST - yyn + 1;
              int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
              int yyx;
    
              for (yyx = yyxbegin; yyx < yyxend; ++yyx)
                if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
                    && !yytable_value_is_error (yytable[yyx + yyn]))
                  {
                    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
                      {
                        yycount = 1;
                        yysize = yysize0;
                        break;
                      }
                    yyarg[yycount++] = yytname[yyx];
                    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
                    if (! (yysize <= yysize1
                           && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
                      return 2;
                    yysize = yysize1;
                  }
            }
        }
    
      switch (yycount)
        {
    # define YYCASE_(N, S)                      \
          case N:                               \
            yyformat = S;                       \
          break
          YYCASE_(0, YY_("syntax error"));
          YYCASE_(1, YY_("syntax error, unexpected %s"));
          YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
          YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
          YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
          YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
    # undef YYCASE_
        }
    
      yysize1 = yysize + yystrlen (yyformat);
      if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
        return 2;
      yysize = yysize1;
    
      if (*yymsg_alloc < yysize)
        {
          *yymsg_alloc = 2 * yysize;
          if (! (yysize <= *yymsg_alloc
                 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
            *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
          return 1;
        }
    
      /* Avoid sprintf, as that infringes on the user's name space.
         Don't have undefined behavior even if the translation
         produced a string with the wrong number of "%s"s.  */
      {
        char *yyp = *yymsg;
        int yyi = 0;
        while ((*yyp = *yyformat) != '\0')
          if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
            {
              yyp += yytnamerr (yyp, yyarg[yyi++]);
              yyformat += 2;
            }
          else
            {
              yyp++;
              yyformat++;
            }
      }
      return 0;
    }
    #endif /* YYERROR_VERBOSE */
    
    /*-----------------------------------------------.
    | Release the memory associated to this symbol.  |
    `-----------------------------------------------*/
    
    /*ARGSUSED*/
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    static void
    yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, ap_expr_parse_ctx_t *ctx)
    #else
    static void
    yydestruct (yymsg, yytype, yyvaluep, ctx)
        const char *yymsg;
        int yytype;
        YYSTYPE *yyvaluep;
        ap_expr_parse_ctx_t *ctx;
    #endif
    {
      YYUSE (yyvaluep);
      YYUSE (ctx);
    
      if (!yymsg)
        yymsg = "Deleting";
      YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
    
      switch (yytype)
        {
    
          default:
    	break;
        }
    }
    
    
    /* Prevent warnings from -Wmissing-prototypes.  */
    #ifdef YYPARSE_PARAM
    #if defined __STDC__ || defined __cplusplus
    int yyparse (void *YYPARSE_PARAM);
    #else
    int yyparse ();
    #endif
    #else /* ! YYPARSE_PARAM */
    #if defined __STDC__ || defined __cplusplus
    int yyparse (ap_expr_parse_ctx_t *ctx);
    #else
    int yyparse ();
    #endif
    #endif /* ! YYPARSE_PARAM */
    
    
    /*----------.
    | yyparse.  |
    `----------*/
    
    #ifdef YYPARSE_PARAM
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    int
    yyparse (void *YYPARSE_PARAM)
    #else
    int
    yyparse (YYPARSE_PARAM)
        void *YYPARSE_PARAM;
    #endif
    #else /* ! YYPARSE_PARAM */
    #if (defined __STDC__ || defined __C99__FUNC__ \
         || defined __cplusplus || defined _MSC_VER)
    int
    yyparse (ap_expr_parse_ctx_t *ctx)
    #else
    int
    yyparse (ctx)
        ap_expr_parse_ctx_t *ctx;
    #endif
    #endif
    {
    /* The lookahead symbol.  */
    int yychar;
    
    /* The semantic value of the lookahead symbol.  */
    YYSTYPE yylval;
    
        /* Number of syntax errors so far.  */
        int yynerrs;
    
        int yystate;
        /* Number of tokens to shift before error messages enabled.  */
        int yyerrstatus;
    
        /* The stacks and their tools:
           `yyss': related to states.
           `yyvs': related to semantic values.
    
           Refer to the stacks thru separate pointers, to allow yyoverflow
           to reallocate them elsewhere.  */
    
        /* The state stack.  */
        yytype_int16 yyssa[YYINITDEPTH];
        yytype_int16 *yyss;
        yytype_int16 *yyssp;
    
        /* The semantic value stack.  */
        YYSTYPE yyvsa[YYINITDEPTH];
        YYSTYPE *yyvs;
        YYSTYPE *yyvsp;
    
        YYSIZE_T yystacksize;
    
      int yyn;
      int yyresult;
      /* Lookahead token as an internal (translated) token number.  */
      int yytoken;
      /* The variables used to return semantic value and location from the
         action routines.  */
      YYSTYPE yyval;
    
    #if YYERROR_VERBOSE
      /* Buffer for error messages, and its allocated size.  */
      char yymsgbuf[128];
      char *yymsg = yymsgbuf;
      YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
    #endif
    
    #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
    
      /* The number of symbols on the RHS of the reduced rule.
         Keep to zero when no symbol should be popped.  */
      int yylen = 0;
    
      yytoken = 0;
      yyss = yyssa;
      yyvs = yyvsa;
      yystacksize = YYINITDEPTH;
    
      YYDPRINTF ((stderr, "Starting parse\n"));
    
      yystate = 0;
      yyerrstatus = 0;
      yynerrs = 0;
      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.  */
      yyssp = yyss;
      yyvsp = yyvs;
    
      goto yysetstate;
    
      /* TODO: compiler warning that this is unused, and it seems to */
      (void)yynerrs;
    /*------------------------------------------------------------.
    | yynewstate -- Push a new state, which is found in yystate.  |
    `------------------------------------------------------------*/
     yynewstate:
      /* In all cases, when you get here, the value and location stacks
         have just been pushed.  So pushing a state here evens the stacks.  */
      yyssp++;
    
     yysetstate:
      *yyssp = yystate;
    
      if (yyss + yystacksize - 1 <= yyssp)
        {
          /* Get the current used size of the three stacks, in elements.  */
          YYSIZE_T yysize = yyssp - yyss + 1;
    
    #ifdef yyoverflow
          {
    	/* 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 *yyvs1 = yyvs;
    	yytype_int16 *yyss1 = yyss;
    
    	/* Each stack pointer address is followed by the size of the
    	   data in use in that stack, in bytes.  This used to be a
    	   conditional around just the two extra args, but that might
    	   be undefined if yyoverflow is a macro.  */
    	yyoverflow (YY_("memory exhausted"),
    		    &yyss1, yysize * sizeof (*yyssp),
    		    &yyvs1, yysize * sizeof (*yyvsp),
    		    &yystacksize);
    
    	yyss = yyss1;
    	yyvs = yyvs1;
          }
    #else /* no yyoverflow */
    # ifndef YYSTACK_RELOCATE
          goto yyexhaustedlab;
    # else
          /* Extend the stack our own way.  */
          if (YYMAXDEPTH <= yystacksize)
    	goto yyexhaustedlab;
          yystacksize *= 2;
          if (YYMAXDEPTH < yystacksize)
    	yystacksize = YYMAXDEPTH;
    
          {
    	yytype_int16 *yyss1 = yyss;
    	union yyalloc *yyptr =
    	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
    	if (! yyptr)
    	  goto yyexhaustedlab;
    	YYSTACK_RELOCATE (yyss_alloc, yyss);
    	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
    #  undef YYSTACK_RELOCATE
    	if (yyss1 != yyssa)
    	  YYSTACK_FREE (yyss1);
          }
    # endif
    #endif /* no yyoverflow */
    
          yyssp = yyss + yysize - 1;
          yyvsp = yyvs + yysize - 1;
    
          YYDPRINTF ((stderr, "Stack size increased to %lu\n",
    		  (unsigned long int) yystacksize));
    
          if (yyss + yystacksize - 1 <= yyssp)
    	YYABORT;
        }
    
      YYDPRINTF ((stderr, "Entering state %d\n", yystate));
    
      if (yystate == YYFINAL)
        YYACCEPT;
    
      goto yybackup;
    
    /*-----------.
    | yybackup.  |
    `-----------*/
    yybackup:
    
      /* Do appropriate processing given the current state.  Read a
         lookahead token if we need one and don't already have one.  */
    
      /* First try to decide what to do without reference to lookahead token.  */
      yyn = yypact[yystate];
      if (yypact_value_is_default (yyn))
        goto yydefault;
    
      /* Not known => get a lookahead token if don't already have one.  */
    
      /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
      if (yychar == YYEMPTY)
        {
          YYDPRINTF ((stderr, "Reading a token: "));
          yychar = YYLEX;
        }
    
      if (yychar <= YYEOF)
        {
          yychar = yytoken = YYEOF;
          YYDPRINTF ((stderr, "Now at end of input.\n"));
        }
      else
        {
          yytoken = YYTRANSLATE (yychar);
          YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
        }
    
      /* If the proper action on seeing token YYTOKEN is to reduce or to
         detect an error, take that action.  */
      yyn += yytoken;
      if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
        goto yydefault;
      yyn = yytable[yyn];
      if (yyn <= 0)
        {
          if (yytable_value_is_error (yyn))
            goto yyerrlab;
          yyn = -yyn;
          goto yyreduce;
        }
    
      /* Count tokens shifted since error; after three, turn off error
         status.  */
      if (yyerrstatus)
        yyerrstatus--;
    
      /* Shift the lookahead token.  */
      YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
    
      /* Discard the shifted token.  */
      yychar = YYEMPTY;
    
      yystate = yyn;
      *++yyvsp = yylval;
    
      goto yynewstate;
    
    
    /*-----------------------------------------------------------.
    | yydefault -- do the default action for the current state.  |
    `-----------------------------------------------------------*/
    yydefault:
      yyn = yydefact[yystate];
      if (yyn == 0)
        goto yyerrlab;
      goto yyreduce;
    
    
    /*-----------------------------.
    | yyreduce -- Do a reduction.  |
    `-----------------------------*/
    yyreduce:
      /* yyn is the number of a rule to reduce with.  */
      yylen = yyr2[yyn];
    
      /* If YYLEN is nonzero, implement the default value of the action:
         `$$ = $1'.
    
         Otherwise, the following line sets YYVAL to garbage.
         This behavior is undocumented and Bison
         users should not rely upon it.  Assigning to YYVAL
         unconditionally makes the parser a bit smaller, and it avoids a
         GCC warning that YYVAL may be used uninitialized.  */
      yyval = yyvsp[1-yylen];
    
    
      YY_REDUCE_PRINT (yyn);
      switch (yyn)
        {
            case 2:
    
    /* Line 1806 of yacc.c  */
    #line 112 "util_expr_parse.y"
        { ctx->expr = (yyvsp[(2) - (2)].exVal); }
        break;
    
      case 3:
    
    /* Line 1806 of yacc.c  */
    #line 113 "util_expr_parse.y"
        { ctx->expr = (yyvsp[(2) - (2)].exVal); }
        break;
    
      case 4:
    
    /* Line 1806 of yacc.c  */
    #line 114 "util_expr_parse.y"
        { YYABORT; }
        break;
    
      case 5:
    
    /* Line 1806 of yacc.c  */
    #line 117 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_True,        NULL, NULL, ctx); }
        break;
    
      case 6:
    
    /* Line 1806 of yacc.c  */
    #line 118 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_False,       NULL, NULL, ctx); }
        break;
    
      case 7:
    
    /* Line 1806 of yacc.c  */
    #line 119 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_Not,         (yyvsp[(2) - (2)].exVal),   NULL, ctx); }
        break;
    
      case 8:
    
    /* Line 1806 of yacc.c  */
    #line 120 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_Or,          (yyvsp[(1) - (3)].exVal),   (yyvsp[(3) - (3)].exVal),   ctx); }
        break;
    
      case 9:
    
    /* Line 1806 of yacc.c  */
    #line 121 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_And,         (yyvsp[(1) - (3)].exVal),   (yyvsp[(3) - (3)].exVal),   ctx); }
        break;
    
      case 10:
    
    /* Line 1806 of yacc.c  */
    #line 122 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_Comp,        (yyvsp[(1) - (1)].exVal),   NULL, ctx); }
        break;
    
      case 11:
    
    /* Line 1806 of yacc.c  */
    #line 123 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_unary_op_make(       (yyvsp[(1) - (2)].cpVal),   (yyvsp[(2) - (2)].exVal),   ctx); }
        break;
    
      case 12:
    
    /* Line 1806 of yacc.c  */
    #line 124 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_binary_op_make((yyvsp[(2) - (3)].cpVal),   (yyvsp[(1) - (3)].exVal),   (yyvsp[(3) - (3)].exVal),   ctx); }
        break;
    
      case 13:
    
    /* Line 1806 of yacc.c  */
    #line 125 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
        break;
    
      case 14:
    
    /* Line 1806 of yacc.c  */
    #line 126 "util_expr_parse.y"
        { YYABORT; }
        break;
    
      case 15:
    
    /* Line 1806 of yacc.c  */
    #line 129 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_EQ,      (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 16:
    
    /* Line 1806 of yacc.c  */
    #line 130 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_NE,      (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 17:
    
    /* Line 1806 of yacc.c  */
    #line 131 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_LT,      (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 18:
    
    /* Line 1806 of yacc.c  */
    #line 132 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_LE,      (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 19:
    
    /* Line 1806 of yacc.c  */
    #line 133 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_GT,      (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 20:
    
    /* Line 1806 of yacc.c  */
    #line 134 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_GE,      (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 21:
    
    /* Line 1806 of yacc.c  */
    #line 135 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_STR_EQ,  (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 22:
    
    /* Line 1806 of yacc.c  */
    #line 136 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_STR_NE,  (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 23:
    
    /* Line 1806 of yacc.c  */
    #line 137 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_STR_LT,  (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 24:
    
    /* Line 1806 of yacc.c  */
    #line 138 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_STR_LE,  (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 25:
    
    /* Line 1806 of yacc.c  */
    #line 139 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_STR_GT,  (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 26:
    
    /* Line 1806 of yacc.c  */
    #line 140 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_STR_GE,  (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 27:
    
    /* Line 1806 of yacc.c  */
    #line 141 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_IN,      (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 28:
    
    /* Line 1806 of yacc.c  */
    #line 142 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_REG,     (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 29:
    
    /* Line 1806 of yacc.c  */
    #line 143 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_NRE,     (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
        break;
    
      case 30:
    
    /* Line 1806 of yacc.c  */
    #line 146 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
        break;
    
      case 31:
    
    /* Line 1806 of yacc.c  */
    #line 147 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
        break;
    
      case 32:
    
    /* Line 1806 of yacc.c  */
    #line 150 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(1) - (1)].exVal), NULL, ctx); }
        break;
    
      case 33:
    
    /* Line 1806 of yacc.c  */
    #line 151 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(3) - (3)].exVal), (yyvsp[(1) - (3)].exVal),   ctx); }
        break;
    
      case 34:
    
    /* Line 1806 of yacc.c  */
    #line 154 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (2)].exVal), (yyvsp[(2) - (2)].exVal), ctx); }
        break;
    
      case 35:
    
    /* Line 1806 of yacc.c  */
    #line 155 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
        break;
    
      case 36:
    
    /* Line 1806 of yacc.c  */
    #line 156 "util_expr_parse.y"
        { YYABORT; }
        break;
    
      case 37:
    
    /* Line 1806 of yacc.c  */
    #line 159 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_String, (yyvsp[(1) - (1)].cpVal), NULL, ctx); }
        break;
    
      case 38:
    
    /* Line 1806 of yacc.c  */
    #line 160 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
        break;
    
      case 39:
    
    /* Line 1806 of yacc.c  */
    #line 161 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
        break;
    
      case 40:
    
    /* Line 1806 of yacc.c  */
    #line 164 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); }
        break;
    
      case 41:
    
    /* Line 1806 of yacc.c  */
    #line 165 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(2) - (5)].cpVal), (yyvsp[(4) - (5)].exVal), ctx); }
        break;
    
      case 42:
    
    /* Line 1806 of yacc.c  */
    #line 168 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_Digit,  (yyvsp[(1) - (1)].cpVal), NULL, ctx); }
        break;
    
      case 43:
    
    /* Line 1806 of yacc.c  */
    #line 169 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal),   ctx); }
        break;
    
      case 44:
    
    /* Line 1806 of yacc.c  */
    #line 170 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
        break;
    
      case 45:
    
    /* Line 1806 of yacc.c  */
    #line 171 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
        break;
    
      case 46:
    
    /* Line 1806 of yacc.c  */
    #line 172 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
        break;
    
      case 47:
    
    /* Line 1806 of yacc.c  */
    #line 173 "util_expr_parse.y"
        { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
        break;
    
      case 48:
    
    /* Line 1806 of yacc.c  */
    #line 174 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_make(op_String, "", NULL, ctx); }
        break;
    
      case 49:
    
    /* Line 1806 of yacc.c  */
    #line 177 "util_expr_parse.y"
        {
                    ap_regex_t *regex;
                    if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
                                             AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
                        ctx->error = "Failed to compile regular expression";
                        YYERROR;
                    }
                    (yyval.exVal) = ap_expr_make(op_Regex, regex, NULL, ctx);
                }
        break;
    
      case 50:
    
    /* Line 1806 of yacc.c  */
    #line 186 "util_expr_parse.y"
        {
                    ap_regex_t *regex;
                    if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
                                             AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
                        ctx->error = "Failed to compile regular expression";
                        YYERROR;
                    }
                    (yyval.exVal) = ap_expr_make(op_Regex, regex, NULL, ctx);
                }
        break;
    
      case 51:
    
    /* Line 1806 of yacc.c  */
    #line 197 "util_expr_parse.y"
        {
                    int *n = apr_palloc(ctx->pool, sizeof(int));
                    *n = (yyvsp[(1) - (1)].num);
                    (yyval.exVal) = ap_expr_make(op_RegexBackref, n, NULL, ctx);
                }
        break;
    
      case 52:
    
    /* Line 1806 of yacc.c  */
    #line 204 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_list_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); }
        break;
    
      case 53:
    
    /* Line 1806 of yacc.c  */
    #line 207 "util_expr_parse.y"
        { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); }
        break;
    
    
    
    /* Line 1806 of yacc.c  */
    #line 1891 "util_expr_parse.c"
          default: break;
        }
      /* User semantic actions sometimes alter yychar, and that requires
         that yytoken be updated with the new translation.  We take the
         approach of translating immediately before every use of yytoken.
         One alternative is translating here after every semantic action,
         but that translation would be missed if the semantic action invokes
         YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
         if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
         incorrect destructor might then be invoked immediately.  In the
         case of YYERROR or YYBACKUP, subsequent parser actions might lead
         to an incorrect destructor call or verbose syntax error message
         before the lookahead is translated.  */
      YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
    
      YYPOPSTACK (yylen);
      yylen = 0;
      YY_STACK_PRINT (yyss, yyssp);
    
      *++yyvsp = yyval;
    
      /* 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.  */
    
      yyn = yyr1[yyn];
    
      yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
      if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
        yystate = yytable[yystate];
      else
        yystate = yydefgoto[yyn - YYNTOKENS];
    
      goto yynewstate;
    
    
    /*------------------------------------.
    | yyerrlab -- here on detecting error |
    `------------------------------------*/
    yyerrlab:
      /* Make sure we have latest lookahead translation.  See comments at
         user semantic actions for why this is necessary.  */
      yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
    
      /* If not already recovering from an error, report this error.  */
      if (!yyerrstatus)
        {
          ++yynerrs;
    #if ! YYERROR_VERBOSE
          yyerror (ctx, YY_("syntax error"));
    #else
    # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
                                            yyssp, yytoken)
          {
            char const *yymsgp = YY_("syntax error");
            int yysyntax_error_status;
            yysyntax_error_status = YYSYNTAX_ERROR;
            if (yysyntax_error_status == 0)
              yymsgp = yymsg;
            else if (yysyntax_error_status == 1)
              {
                if (yymsg != yymsgbuf)
                  YYSTACK_FREE (yymsg);
                yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
                if (!yymsg)
                  {
                    yymsg = yymsgbuf;
                    yymsg_alloc = sizeof yymsgbuf;
                    yysyntax_error_status = 2;
                  }
                else
                  {
                    yysyntax_error_status = YYSYNTAX_ERROR;
                    yymsgp = yymsg;
                  }
              }
            yyerror (ctx, yymsgp);
            if (yysyntax_error_status == 2)
              goto yyexhaustedlab;
          }
    # undef YYSYNTAX_ERROR
    #endif
        }
    
    
    
      if (yyerrstatus == 3)
        {
          /* If just tried and failed to reuse lookahead token after an
    	 error, discard it.  */
    
          if (yychar <= YYEOF)
    	{
    	  /* Return failure if at end of input.  */
    	  if (yychar == YYEOF)
    	    YYABORT;
    	}
          else
    	{
    	  yydestruct ("Error: discarding",
    		      yytoken, &yylval, ctx);
    	  yychar = YYEMPTY;
    	}
        }
    
      /* Else will try to reuse lookahead token after shifting the error
         token.  */
      goto yyerrlab1;
    
    
    /*---------------------------------------------------.
    | yyerrorlab -- error raised explicitly by YYERROR.  |
    `---------------------------------------------------*/
    yyerrorlab:
    
      /* Pacify compilers like GCC when the user code never invokes
         YYERROR and the label yyerrorlab therefore never appears in user
         code.  */
      if (/*CONSTCOND*/ 0)
         goto yyerrorlab;
    
      /* Do not reclaim the symbols of the rule which action triggered
         this YYERROR.  */
      YYPOPSTACK (yylen);
      yylen = 0;
      YY_STACK_PRINT (yyss, yyssp);
      yystate = *yyssp;
      goto yyerrlab1;
    
    
    /*-------------------------------------------------------------.
    | yyerrlab1 -- common code for both syntax error and YYERROR.  |
    `-------------------------------------------------------------*/
    yyerrlab1:
      yyerrstatus = 3;	/* Each real token shifted decrements this.  */
    
      for (;;)
        {
          yyn = yypact[yystate];
          if (!yypact_value_is_default (yyn))
    	{
    	  yyn += YYTERROR;
    	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
    	    {
    	      yyn = yytable[yyn];
    	      if (0 < yyn)
    		break;
    	    }
    	}
    
          /* Pop the current state because it cannot handle the error token.  */
          if (yyssp == yyss)
    	YYABORT;
    
    
          yydestruct ("Error: popping",
    		  yystos[yystate], yyvsp, ctx);
          YYPOPSTACK (1);
          yystate = *yyssp;
          YY_STACK_PRINT (yyss, yyssp);
        }
    
      *++yyvsp = yylval;
    
    
      /* Shift the error token.  */
      YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
    
      yystate = yyn;
      goto yynewstate;
    
    
    /*-------------------------------------.
    | yyacceptlab -- YYACCEPT comes here.  |
    `-------------------------------------*/
    yyacceptlab:
      yyresult = 0;
      goto yyreturn;
    
    /*-----------------------------------.
    | yyabortlab -- YYABORT comes here.  |
    `-----------------------------------*/
    yyabortlab:
      yyresult = 1;
      goto yyreturn;
    
    #if !defined(yyoverflow) || YYERROR_VERBOSE
    /*-------------------------------------------------.
    | yyexhaustedlab -- memory exhaustion comes here.  |
    `-------------------------------------------------*/
    yyexhaustedlab:
      yyerror (ctx, YY_("memory exhausted"));
      yyresult = 2;
      /* Fall through.  */
    #endif
    
    yyreturn:
      if (yychar != YYEMPTY)
        {
          /* Make sure we have latest lookahead translation.  See comments at
             user semantic actions for why this is necessary.  */
          yytoken = YYTRANSLATE (yychar);
          yydestruct ("Cleanup: discarding lookahead",
                      yytoken, &yylval, ctx);
        }
      /* Do not reclaim the symbols of the rule which action triggered
         this YYABORT or YYACCEPT.  */
      YYPOPSTACK (yylen);
      YY_STACK_PRINT (yyss, yyssp);
      while (yyssp != yyss)
        {
          yydestruct ("Cleanup: popping",
    		  yystos[*yyssp], yyvsp, ctx);
          YYPOPSTACK (1);
        }
    #ifndef yyoverflow
      if (yyss != yyssa)
        YYSTACK_FREE (yyss);
    #endif
    #if YYERROR_VERBOSE
      if (yymsg != yymsgbuf)
        YYSTACK_FREE (yymsg);
    #endif
      /* Make sure YYID is used.  */
      return YYID (yyresult);
    }
    
    
    
    /* Line 2067 of yacc.c  */
    #line 210 "util_expr_parse.y"
    
    
    void yyerror(ap_expr_parse_ctx_t *ctx, const char *s)
    {
        /* s is allocated on the stack */
        ctx->error = apr_pstrdup(ctx->ptemp, s);
    }
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/config.c������������������������������������������������������������������������0000664�0001751�0001751�00000240007�14636331332�015550� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 auxiliary 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"
    
    #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 "util_varbuf.h"
    #include "mpm_common.h"
    
    #define APLOG_UNSET   (APLOG_NO_MODULE - 1)
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    AP_DECLARE_DATA const char *ap_server_argv0 = NULL;
    AP_DECLARE_DATA const char *ap_server_root = NULL;
    AP_DECLARE_DATA server_rec *ap_server_conf = NULL;
    AP_DECLARE_DATA apr_pool_t *ap_pglobal = 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(check_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)
               APR_HOOK_LINK(open_htaccess)
    )
    
    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_RUN_ALL(int, check_config,
                              (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(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_RUN_FIRST(apr_status_t, open_htaccess,
                                (request_rec *r, const char *dir_name, const char *access_name,
                                 ap_configfile_t **conffile, const char **full_name),
                                (r, dir_name, access_name, conffile, full_name),
                                AP_DECLINED)
    
    /* hooks with no args are implemented last, after disabling APR hook probes */
    #if defined(APR_HOOK_PROBES_ENABLED)
    #undef APR_HOOK_PROBES_ENABLED
    #undef APR_HOOK_PROBE_ENTRY
    #define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
    #undef APR_HOOK_PROBE_RETURN
    #define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
    #undef APR_HOOK_PROBE_INVOKE
    #define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
    #undef APR_HOOK_PROBE_COMPLETE
    #define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
    #undef APR_HOOK_INT_DCL_UD
    #define APR_HOOK_INT_DCL_UD
    #endif
    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;
    
    /* The maximum possible value for total_modules, i.e. number of static
     * modules plus DYNAMIC_MODULE_LIMIT.
     */
    static int max_modules = 0;
    
    /* The number of elements we need to alloc for config vectors. Before loading
     * of dynamic modules, we must be liberal and set this to max_modules. After
     * loading of dynamic modules, we can trim it down to total_modules. On
     * restart, reset to max_modules.
     */
    static int conf_vector_length = 0;
    
    static int reserved_module_slots = 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;
    
    /* a list of the module symbol names with the trailing "_module"removed */
    static char **ap_module_short_names = 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 *);
    
    /* A list of the merge_dir_config functions of all loaded modules, sorted
     * by module_index.
     * Using this list in ap_merge_per_dir_configs() is faster than following
     * the module->next linked list because of better memory locality (resulting
     * in better cache usage).
     */
    static merger_func *merger_func_cache;
    
    /* 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 *) * conf_vector_length);
        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 *) * conf_vector_length);
        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 *) * conf_vector_length);
        void **base_vector = (void **)base;
        void **new_vector = (void **)new_conf;
        int i;
    
        for (i = 0; i < total_modules; i++) {
            if (!new_vector[i]) {
                conf_vector[i] = base_vector[i];
            }
            else {
                const merger_func df = merger_func_cache[i];
                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 *) * conf_vector_length);
        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,
                                     server_rec *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_config;
        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]) {
                if (df && modp->create_server_config
                       && (ap_get_module_flags(modp) &
                           AP_MODULE_FLAG_ALWAYS_MERGE)) {
                    virt_vector[i] = (*modp->create_server_config)(p, virt);
                }
                else {
                    virt_vector[i] = base_vector[i];
                    df = NULL;
                }
            }
            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);
    }
    
    /* Invoke the filter_init_func for all filters with FILTERS where f->r
     * matches R.  Restricting to a matching R avoids re-running init
     * functions for filters configured for r->main where r is a
     * subrequest.  */
    static int invoke_filter_init(request_rec *r, ap_filter_t *filters)
    {
        while (filters) {
            if (filters->frec->filter_init_func && filters->r == r) {
                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;
        const char *ignore;
    
        /*
         * 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 = invoke_filter_init(r, r->input_filters);
        if (result != OK) {
            return result;
        }
        result = invoke_filter_init(r, r->output_filters);
        if (result != OK) {
            return result;
        }
    
        if (!r->handler) {
            if (r->content_type && AP_REQUEST_IS_TRUSTED_CT(r)) {
                handler = r->content_type;
                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;
    
                    /* exclude media type arguments */
                    while (p2 > handler && p2[-1] == ' ')
                        --p2; /* strip trailing spaces */
    
                    *p2='\0';
                }
            }
            else {
                handler = AP_DEFAULT_HANDLER_NAME;
            }
    
            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, APLOGNO(00523)
                "handler \"%s\" not found for: %s", r->handler, r->filename);
        }
        if ((result != OK) && (result != DONE) && (result != DECLINED) && (result != SUSPENDED)
            && (result != AP_FILTER_ERROR) /* ap_die() knows about this specifically */
            && !ap_is_HTTP_VALID_RESPONSE(result)) {
            /* If a module is deliberately returning something else
             * (request_rec in non-HTTP or proprietary extension?)
             * let it set a note to allow it explicitly.
             * Otherwise, a return code that is neither reserved nor HTTP
             * is a bug, as in PR#31759.
             */
            ignore = apr_table_get(r->notes, "HTTP_IGNORE_RANGE");
            if (!ignore) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00524)
                              "Handler for %s returned invalid result code %d",
                              r->handler, result);
                result = HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    
        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 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, &ap_config_hash, ap_pool_cleanup_set_null,
                                  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,
                                           const char *sym_name)
    {
        ap_module_symbol_t *sym = ap_prelinked_module_symbols;
    
        /* 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->module_index == -1) {
            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);
            }
            /*
             * If this fails some module forgot to call ap_reserve_module_slots*.
             */
            ap_assert(total_modules < conf_vector_length);
    
            m->module_index = total_modules++;
            dynamic_modules++;
    
        }
        else if (!sym_name) {
            while (sym->modp != NULL) {
                if (sym->modp == m) {
                    sym_name = sym->name;
                    break;
                }
                sym++;
            }
        }
    
        if (m->next == NULL) {
            m->next = ap_top_module;
            ap_top_module = m;
        }
    
        if (sym_name) {
            int len = strlen(sym_name);
            int slen = strlen("_module");
            if (len > slen && !strcmp(sym_name + len - slen, "_module")) {
                len -= slen;
            }
    
            ap_module_short_names[m->module_index] = ap_malloc(len + 1);
            memcpy(ap_module_short_names[m->module_index], sym_name, len);
            ap_module_short_names[m->module_index][len] = '\0';
            merger_func_cache[m->module_index] = m->merge_dir_config;
        }
    
    
        /* 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 = ap_malloc(strlen(m->name)); /* FIXME: memory leak, albeit a small one */
            memcpy(tmp, m->name, strlen(m->name)-1);
            tmp[strlen(m->name)-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, APLOGNO(00525)
                             "Cannot remove module %s: not found in module list",
                             m->name);
                return;
            }
    
            /* Eliminate us from the module list */
            modp->next = modp->next->next;
        }
    
        free(ap_module_short_names[m->module_index]);
        ap_module_short_names[m->module_index] = NULL;
        merger_func_cache[m->module_index] = NULL;
    
        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,
                                                  const char *short_name)
    {
        module **m;
        const char *error;
    
        /*
         *  Add module pointer to top of chained module list
         */
        error = ap_add_module(mod, p, short_name);
        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 explicitly 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++;
    
        max_modules = total_modules + DYNAMIC_MODULE_LIMIT + 1;
        conf_vector_length = max_modules;
    
        /*
         *  Initialise list of loaded modules and short names
         */
        ap_loaded_modules = (module **)apr_palloc(process->pool,
            sizeof(module *) * conf_vector_length);
        if (!ap_module_short_names)
            ap_module_short_names = ap_calloc(sizeof(char *), conf_vector_length);
    
        if (!merger_func_cache)
            merger_func_cache = ap_calloc(sizeof(merger_func), conf_vector_length);
    
        if (ap_loaded_modules == NULL || ap_module_short_names == NULL
            || merger_func_cache == 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, NULL);
            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(const char *) ap_find_module_short_name(int module_index)
    {
            if (module_index < 0 || module_index >= conf_vector_length)
                    return NULL;
            return ap_module_short_names[module_index];
    }
    
    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)
    {
        int override_list_ok = 0;
        char *w, *w2, *w3;
        const char *errmsg = NULL;
    
        /* Have we been provided a list of acceptable directives? */
        if (parms->override_list != NULL) { 
             if (apr_table_get(parms->override_list, cmd->name) != NULL) { 
                  override_list_ok = 1;
             }
        }
    
        if ((parms->override & cmd->req_override) == 0 && !override_list_ok) {
            if (parms->override & NONFATAL_OVERRIDE) {
                ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, parms->temp_pool,
                              APLOGNO(02295)
                              "%s in .htaccess forbidden by AllowOverride",
                              cmd->name);
                return NULL;
            }
            else if (parms->directive && parms->directive->parent) {
                return apr_pstrcat(parms->pool, cmd->name, " not allowed in ",
                                   parms->directive->parent->directive, ">",
                                   " context", NULL);
            }
            else {
                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:
            w = ap_getword_conf(parms->pool, &args);
            
            if (*w == '\0')
                return apr_pstrcat(parms->pool, cmd->name,
                                   " requires at least one argument",
                                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
    
            while (*w != '\0') {
                errmsg = cmd->AP_TAKE1(parms, mconfig, w);
    
                if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
                    return errmsg;
    
                w = ap_getword_conf(parms->pool, &args);
            }
    
            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:
            /*
             * This is safe to use temp_pool here, because the 'flag' itself is not
             * forwarded as-is
             */
            w = ap_getword_conf(parms->temp_pool, &args);
    
            if (*w == '\0' || (ap_cstr_casecmp(w, "on") && ap_cstr_casecmp(w, "off")))
                return apr_pstrcat(parms->pool, cmd->name, " must be On or Off",
                                   NULL);
    
            return cmd->AP_FLAG(parms, mconfig, ap_cstr_casecmp(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 (!ap_cstr_casecmp(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;
        const command_rec *cmd;
        ap_mod_list *ml;
        char *lname;
    
        if (*l == '#' || *l == '\0')
            return NULL;
    
    #if RESOLVE_ENV_PER_TOKEN
        args = l;
    #else
        args = ap_resolve_env(temp_pool, l);
    #endif
    
        /* The first word is the name of a directive.  We can safely use the
         * 'temp_pool' for it.  If it matches the name of a known directive, we
         * can reference the string within the module if needed.  Otherwise, we
         * can still make a copy in the 'p' pool. */
        cmd_name = ap_getword_conf(temp_pool, &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->args = apr_pstrdup(p, args);
    
        lname = apr_pstrdup(temp_pool, cmd_name);
        ap_str_tolower(lname);
        ml = apr_hash_get(ap_config_hash, lname, APR_HASH_KEY_STRING);
    
        if (ml && (cmd = ml->cmd) != NULL) {
            newdir->directive = cmd->name;
            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;
            }
        }
        else {
            /* No known directive found?  Make a copy of what we have parsed. */
            newdir->directive = apr_pstrdup(p, cmd_name);
        }
    
    
        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 (ap_cstr_casecmp(cmd_name + 2,
                               (*curr_parent)->directive + 1) != 0) {
                    parms->err_directive = newdir;
                    return apr_pstrcat(p, "Expected </",
                                       (*curr_parent)->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;
    }
    
    #define VARBUF_INIT_LEN 200
    #define VARBUF_MAX_LEN  (16*1024*1024)
    
    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 *bracket;
        const char *retval;
        ap_directive_t *sub_tree = NULL;
        apr_status_t rc;
        struct ap_varbuf vb;
        apr_size_t max_len = VARBUF_MAX_LEN;
        if (p == temp_pool)
            max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
    
        bracket = apr_pstrcat(temp_pool, orig_directive + 1, ">", NULL);
        ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
    
        while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
               == APR_SUCCESS) {
            if (!memcmp(vb.buf, "</", 2)
                && (ap_cstr_casecmp(vb.buf + 2, bracket) == 0)
                && (*curr_parent == NULL)) {
                break;
            }
            retval = ap_build_config_sub(p, temp_pool, vb.buf, parms, current,
                                         curr_parent, &sub_tree);
            if (retval != NULL)
                return retval;
    
            if (sub_tree == NULL) {
                sub_tree = *curr_parent;
            }
    
            if (sub_tree == NULL) {
                sub_tree = *current;
            }
        }
        ap_varbuf_free(&vb);
        if (rc != APR_EOF && rc != APR_SUCCESS)
            return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
    
        *current = sub_tree;
        return NULL;
    }
    
    static const char *ap_walk_config_sub(const ap_directive_t *current,
                                          cmd_parms *parms,
                                          ap_conf_vector_t *section_vector)
    {
        const command_rec *cmd;
        ap_mod_list *ml;
        char *dir = apr_pstrdup(parms->temp_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;
            if (parms->override & NONFATAL_UNKNOWN) {
                ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, parms->temp_pool,
                              APLOGNO(02296) "Unknown directive %s "
                              "perhaps misspelled or defined by a module "
                              "not included in the server configuration", dir);
                return NULL;
            }
            else {
                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 occurring 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;
        const char *errmsg;
        ap_directive_t **last_ptr = NULL;
        apr_status_t rc;
        struct ap_varbuf vb;
        apr_size_t max_len = VARBUF_MAX_LEN;
        if (p == temp_pool)
            max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
    
        ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
    
        if (current != NULL) {
            /* If we have to traverse the whole tree again for every included
             * config file, the required time grows as O(n^2) with the number of
             * files. This can be a significant delay for large configurations.
             * Therefore we cache a pointer to the last node.
             */
            last_ptr = &(current->last);
    
            if (last_ptr && *last_ptr) {
                current = *last_ptr;
            }
    
            while (current->next) {
                current = current->next;
            }
    
            if (last_ptr) {
                /* update cached pointer to last node */
                *last_ptr = current;
            }
        }
    
        while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
               == APR_SUCCESS) {
            errmsg = ap_build_config_sub(p, temp_pool, vb.buf, parms,
                                         &current, &curr_parent, conftree);
            if (errmsg != NULL)
                return errmsg;
    
            if (*conftree == NULL && curr_parent != NULL) {
                *conftree = curr_parent;
            }
    
            if (*conftree == NULL && current != NULL) {
                *conftree = current;
            }
        }
        ap_varbuf_free(&vb);
        if (rc != APR_EOF && rc != APR_SUCCESS)
            return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
    
        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_flag_slot_char(cmd_parms *cmd,
                                                          void *struct_ptr_v, int arg)
    {
        int offset = (int)(long)cmd->info;
        char *struct_ptr = (char *)struct_ptr_v;
    
        *(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, cmd->cmd->name, ": 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;
    }
    
    AP_DECLARE(void) ap_reset_module_loglevels(struct ap_logconf *l, int val)
    {
        if (l->module_levels)
            memset(l->module_levels, val, conf_vector_length);
    }
    
    AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *pool, struct ap_logconf *l,
                                            int index, int level)
    {
        if (!l->module_levels) {
            l->module_levels = apr_palloc(pool, conf_vector_length);
            if (l->level == APLOG_UNSET) {
                    ap_reset_module_loglevels(l, APLOG_UNSET);
            }
            else {
                    ap_reset_module_loglevels(l, APLOG_NO_MODULE);
            }
        }
    
        l->module_levels[index] = level;
    }
    
    /*****************************************************************
     *
     * Reading whole config files...
     */
    
    static cmd_parms default_parms =
    {NULL, 0, 0, NULL, -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(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *file)
    {
        char *newpath = NULL;
        apr_status_t rv;
        const char *runtime_dir = ap_runtime_dir ? ap_runtime_dir : ap_server_root_relative(p, DEFAULT_REL_RUNTIMEDIR);
    
        rv = apr_filepath_merge(&newpath, runtime_dir, 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)
    {
        struct ap_varbuf vb;
        const char *args;
        char *cmd_name;
        apr_status_t rc;
        apr_size_t max_len = VARBUF_MAX_LEN;
        if (cmd->pool == cmd->temp_pool)
            max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
    
        ap_varbuf_init(cmd->temp_pool, &vb, VARBUF_INIT_LEN);
    
        while ((rc = ap_varbuf_cfg_getline(&vb, cmd->config_file, max_len))
               == APR_SUCCESS) {
            args = vb.buf;
    
            cmd_name = ap_getword_conf(cmd->temp_pool, &args);
            if (cmd_name[0] == '<') {
                if (cmd_name[1] == '/') {
                    cmd_name[strlen(cmd_name) - 1] = '\0';
    
                    if (ap_cstr_casecmp(cmd_name + 2, directive + 1) != 0) {
                        return apr_pstrcat(cmd->pool, "Expected </",
                                           directive + 1, "> but saw ",
                                           cmd_name, ">", NULL);
                    }
    
                    ap_varbuf_free(&vb);
                    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;
                    }
                }
            }
        }
        if (rc != APR_EOF && rc != APR_SUCCESS)
            return ap_pcfg_strerror(cmd->temp_pool, cmd->config_file, rc);
    
        return apr_pstrcat(cmd->pool, "Expected </",
                           directive + 1, "> 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->temp_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 apr_status_t arr_elts_getstr(void *buf, apr_size_t bufsiz, void *param)
    {
        arr_elts_param_t *arr_param = (arr_elts_param_t *)param;
        const char *elt;
    
        /* End of array reached? */
        if (++arr_param->curr_idx > arr_param->array->nelts)
            return APR_EOF;
    
        /* return the line */
        elt = ((const char **)arr_param->array->elts)[arr_param->curr_idx - 1];
        if (apr_cpystrn(buf, elt, bufsiz) - (char *)buf >= bufsiz - 1)
            return APR_ENOSPC;
        return APR_SUCCESS;
    }
    
    
    /* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */
    static apr_status_t 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 APR_SUCCESS;
    }
    
    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_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;
    }
    
    /**
     * Used by -D DUMP_INCLUDES to output the config file "tree".
     */
    static void dump_config_name(const char *fname, apr_pool_t *p)
    {
        unsigned i, recursion, line_number;
        void *data;
        apr_file_t *out = NULL;
    
        apr_file_open_stdout(&out, p);
    
        /* ap_include_sentinel is defined by the core Include directive; use it to
         * figure out how deep in the stack we are.
         */
        apr_pool_userdata_get(&data, "ap_include_sentinel", p);
    
        if (data) {
            recursion = *(unsigned *)data;
        } else {
            recursion = 0;
        }
    
        /* Indent once for each level. */
        for (i = 0; i < (recursion + 1); ++i) {
            apr_file_printf(out, "  ");
        }
    
        /* ap_include_lineno is similarly defined to tell us where in the last
         * config file we were.
         */
        apr_pool_userdata_get(&data, "ap_include_lineno", p);
    
        if (data) {
            line_number = *(unsigned *)data;
        } else {
            line_number = 0;
        }
    
        /* Print the line number and the name of the parsed file. */
        if (line_number > 0) {
            apr_file_printf(out, "(%u)", line_number);
        } else {
            apr_file_printf(out, "(*)");
        }
    
        apr_file_printf(out, " %s\n", fname);
    }
    
    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)
    {
        ap_configfile_t *cfp;
        cmd_parms parms;
        apr_status_t rv;
        const char *error;
    
        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_SYM_OWNER | OPT_MULTI;
    
        rv = ap_pcfg_openfile(&cfp, p, fname);
        if (rv != APR_SUCCESS) {
            return apr_psprintf(p, "Could not open configuration file %s: %pm",
                                fname, &rv);
        }
    
        if (ap_exists_config_define("DUMP_INCLUDES")) {
            dump_config_name(fname, p);
        }
    
        parms.config_file = cfp;
        error = ap_build_config(&parms, p, ptemp, conftree);
        ap_cfg_closefile(cfp);
    
        if (error) {
            if (parms.err_directive)
                return apr_psprintf(p, "Syntax error on line %d of %s: %s",
                                    parms.err_directive->line_num,
                                    parms.err_directive->filename, error);
            else
                return error;
        }
    
        return NULL;
    }
    
    typedef struct {
        server_rec *s;
        ap_directive_t **conftree;
    } configs;
    
    static const char *process_resource_config_cb(ap_dir_match_t *w, const char *fname)
    {
        configs *cfgs = w->ctx;
        return ap_process_resource_config(cfgs->s, fname, cfgs->conftree, w->p, w->ptemp);
    }
    
    AP_DECLARE(const char *) ap_process_fnmatch_configs(server_rec *s,
                                                        const char *fname,
                                                        ap_directive_t **conftree,
                                                        apr_pool_t *p,
                                                        apr_pool_t *ptemp,
                                                        int optional)
    {
        configs cfgs;
        ap_dir_match_t w;
    
        cfgs.s = s;
        cfgs.conftree = conftree;
    
        w.prefix = "Include/IncludeOptional: ";
        w.p = p;
        w.ptemp = ptemp;
        w.flags = (optional ? AP_DIR_FLAG_OPTIONAL : AP_DIR_FLAG_NONE) | AP_DIR_FLAG_RECURSIVE;
        w.cb = process_resource_config_cb;
        w.ctx = &cfgs;
        w.depth = 0;
    
        /* 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(ptemp, SERVER_CONFIG_FILE)))) {
            apr_finfo_t finfo;
    
            if (apr_stat(&finfo, fname, APR_FINFO_LINK | APR_FINFO_TYPE, ptemp) != APR_SUCCESS)
                return NULL;
        }
    
        if (!apr_fnmatch_test(fname)) {
            return ap_dir_nofnmatch(&w, fname);
        }
        else {
            apr_status_t status;
            const char *rootpath, *filepath = fname;
    
            /* locate the start of the directories proper */
            status = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, ptemp);
    
            /* we allow APR_SUCCESS and APR_EINCOMPLETE */
            if (APR_ERELATIVE == status) {
                return apr_pstrcat(p, "Include must have an absolute path, ", fname, NULL);
            }
            else if (APR_EBADPATH == status) {
                return apr_pstrcat(p, "Include has a bad path, ", fname, NULL);
            }
    
            /* walk the filepath */
            return ap_dir_fnmatch(&w, rootpath, filepath);
        }
    }
    
    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_SYM_OWNER | OPT_MULTI;
        parms.limited = -1;
    
        errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults);
        if (errmsg) {
            if (parms.err_directive)
                ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, APLOGNO(00526)
                              "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;
    }
    
    apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name,
                                  const char *access_name,
                                  ap_configfile_t **conffile,
                                  const char **full_name)
    {
        *full_name = ap_make_full_path(r->pool, dir_name, access_name);
        return ap_pcfg_openfile(conffile, r->pool, *full_name);
    }
    
    AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
                                           request_rec *r, int override,
                                           int override_opts, apr_table_t *override_list,
                                           const char *d, const char *access_names)
    {
        ap_configfile_t *f = NULL;
        cmd_parms parms;
        const char *filename;
        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.override_list = override_list;
        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_names[0]) {
            const char *access_name = ap_getword_conf(r->pool, &access_names);
    
            filename = NULL;
            status = ap_run_open_htaccess(r, d, access_name, &f, &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, APLOGNO(00529)
                                  "%s pcfg_openfile: unable to check htaccess file, "
                                  "ensure it is readable and that '%s' "
                                  "is executable",
                                  filename, d);
                    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->server_scheme = 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->log.level = APLOG_UNSET;
        s->log.module_levels = NULL;
        /* 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(struct ap_logconf *) ap_new_log_config(apr_pool_t *p,
                                                      const struct ap_logconf *old)
    {
        struct ap_logconf *l = apr_pcalloc(p, sizeof(struct ap_logconf));
        if (old) {
            l->level = old->level;
            if (old->module_levels) {
                l->module_levels =
                    apr_pmemdup(p, old->module_levels, conf_vector_length);
            }
        }
        else {
            l->level = APLOG_UNSET;
        }
        return l;
    }
    
    AP_DECLARE(void) ap_merge_log_config(const struct ap_logconf *old_conf,
                                         struct ap_logconf *new_conf)
    {
        if (new_conf->level != APLOG_UNSET) {
            /* Setting the main loglevel resets all per-module log levels.
             * I.e. if new->level has been set, we must ignore old->module_levels.
             */
            return;
        }
    
        new_conf->level = old_conf->level;
        if (new_conf->module_levels == NULL) {
            new_conf->module_levels = old_conf->module_levels;
        }
        else if (old_conf->module_levels != NULL) {
            int i;
            for (i = 0; i < conf_vector_length; i++) {
                if (new_conf->module_levels[i] == APLOG_UNSET)
                    new_conf->module_levels[i] = old_conf->module_levels[i];
            }
        }
    }
    
    AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server)
    {
        server_rec *virt;
        core_dir_config *dconf =
            ap_get_core_module_config(main_server->lookup_defaults);
        dconf->log = &main_server->log;
    
        for (virt = main_server->next; virt; virt = virt->next) {
            merge_server_configs(p, main_server->module_config, virt);
    
            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;
    
            ap_merge_log_config(&main_server->log, &virt->log);
    
            dconf = ap_get_core_module_config(virt->lookup_defaults);
            dconf->log = &virt->log;
    
            /* 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->server_scheme = NULL;
        s->error_fname = DEFAULT_ERRORLOG;
        s->log.level = DEFAULT_LOGLEVEL;
        s->log.module_levels = NULL;
        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_UNSPEC, 0, 0, p);
        if (rv != APR_SUCCESS) {
            /* should we test here for rv being an EAIERR? */
            ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, rv, NULL, APLOGNO(00530)
                         "initialisation: bug or getaddrinfo fail");
            return NULL;
        }
    
        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;
    }
    
    
    static apr_status_t reset_conf_vector_length(void *dummy)
    {
        reserved_module_slots = 0;
        conf_vector_length = max_modules;
        return APR_SUCCESS;
    }
    
    static int conf_vector_length_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                                             apr_pool_t *ptemp)
    {
        /*
         * We have loaded all modules that are loaded by EXEC_ON_READ directives.
         * From now on we reduce the size of the config vectors to what we need,
         * plus what has been reserved (e.g. by mod_perl) for additional modules
         * loaded later on.
         * If max_modules is too small, ap_add_module() will abort.
         */
        if (total_modules + reserved_module_slots < max_modules) {
            conf_vector_length = total_modules + reserved_module_slots;
        }
        apr_pool_cleanup_register(pconf, NULL, reset_conf_vector_length,
                                  apr_pool_cleanup_null);
        return OK;
    }
    
    
    AP_CORE_DECLARE(void) ap_register_config_hooks(apr_pool_t *p)
    {
        ap_hook_pre_config(conf_vector_length_pre_config, NULL, NULL,
                           APR_HOOK_REALLY_LAST);
    }
    
    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);
        if (s == NULL) {
            return s;
        }
        if (ap_server_conf == NULL) {
            ap_server_conf = s;
        }
    
        init_config_globals(p);
    
        if (ap_exists_config_define("DUMP_INCLUDES")) {
            apr_file_t *out = NULL;
            apr_file_open_stdout(&out, p);
    
            /* Included files will be dumped as the config is walked; print a
             * header.
             */
            apr_file_printf(out, "Included configuration files:\n");
        }
    
        /* 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, APLOGNO(00532) "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 = ap_check_mpm();
        if (error) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, APLOGNO(00534)
                         "%s: Configuration error: %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 <Directory> or <Location> --> 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 <Directory>, <Files>, <Location>, or <If>");
        }
        else {
            printf("only inside <Directory>, <Files>, <Location>, or <If>");
        }
    
        /* Warn if the directive is allowed inside <Directory> 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(int) ap_exists_directive(apr_pool_t *p, const char *name)
    {
        char *lname = apr_pstrdup(p, name);
    
        ap_str_tolower(lname);
        
        return ap_config_hash &&
            apr_hash_get(ap_config_hash, lname, APR_HASH_KEY_STRING) != NULL;
    }
    
    AP_DECLARE(void *) ap_retained_data_get(const char *key)
    {
        void *retained;
    
        apr_pool_userdata_get((void *)&retained, key, ap_pglobal);
        return retained;
    }
    
    AP_DECLARE(void *) ap_retained_data_create(const char *key, apr_size_t size)
    {
        void *retained;
    
        retained = apr_pcalloc(ap_pglobal, size);
        apr_pool_userdata_set((const void *)retained, key, apr_pool_cleanup_null, ap_pglobal);
        return retained;
    }
    
    static int count_directives_sub(const char *directive, ap_directive_t *current)
    {
        int count = 0;
        while (current != NULL) {
            if (current->first_child != NULL)
                count += count_directives_sub(directive, current->first_child);
            if (ap_cstr_casecmp(current->directive, directive) == 0)
                count++;
            current = current->next;
        }
        return count;
    }
    
    AP_DECLARE(void) ap_reserve_module_slots(int count)
    {
        reserved_module_slots += count;
    }
    
    AP_DECLARE(void) ap_reserve_module_slots_directive(const char *directive)
    {
        ap_reserve_module_slots(count_directives_sub(directive, ap_conftree));
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/NWGNUmakefile�������������������������������������������������������������������0000664�0001751�0001751�00000010765�14554221314�016461� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	=
    
    #
    # 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 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 = \
    	$(PRELUDE) \
    	$(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 dependencies (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
    #
    
    # Make sure that the build doesn't attempt to regenerate the shipping files.
    # This requires a 'touch' utility.  Can be downloaded from 'coreutils' at
    #  http://sourceforge.net/projects/gnuwin32/
    util_expr_parse.h : util_expr_parse.y
    	touch util_expr_parse.h
    util_expr_parse.c : util_expr_parse.y
    	touch util_expr_parse.c
    util_expr_scan.c : util_expr_scan.l
    	touch util_expr_scan.c
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
                              
    �����������httpd-2.4.64/server/core_filters.c������������������������������������������������������������������0000664�0001751�0001751�00000074172�14455323126�016774� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  core_filters.c
     * @brief 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_version.h"
    
    #define APR_WANT_IOVEC
    #define APR_WANT_STRFUNC
    #define APR_WANT_MEMFUNC
    #include "apr_want.h"
    
    #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_common.h"
    #include "scoreboard.h"
    #include "mod_core.h"
    #include "ap_listen.h"
    
    #include "mod_so.h" /* for ap_find_loaded_module_symbol */
    
    #define AP_MIN_SENDFILE_BYTES           (256)
    
    /**
     * 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)
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    struct core_output_filter_ctx {
        apr_bucket_brigade *buffered_bb;
        apr_pool_t *deferred_write_pool;
        apr_size_t bytes_written;
        struct iovec *vec;
        apr_size_t nvec;
    };
    
    
    apr_status_t 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 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)
        {
            net->in_ctx = ctx = apr_palloc(f->c->pool, sizeof(*ctx));
            ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
            ctx->tmpbb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
            /* seed the brigade with the client socket. */
            rv = ap_run_insert_network_bucket(f->c, ctx->b, net->client_socket);
            if (rv != APR_SUCCESS)
                return rv;
        }
        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) && block == APR_NONBLOCK_READ) {
                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.  FWLIW, this would be needed by an MPM like Perchild;
         * such an 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) && block == APR_NONBLOCK_READ) {
                /* getting EAGAIN for a blocking read is an error; for a
                 * non-blocking read, return an empty brigade. */
                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;
            }
    
            /* Have we read as much data as we wanted (be greedy)? */
            if (len < readbytes) {
                apr_size_t bucket_len;
    
                rv = APR_SUCCESS;
                /* We already registered the data in e in len */
                e = APR_BUCKET_NEXT(e);
                while ((len < readbytes) && (rv == APR_SUCCESS)
                       && (e != APR_BRIGADE_SENTINEL(ctx->b))) {
                    /* Check for the availability of buckets with known length */
                    if (e->length != (apr_size_t)-1) {
                        len += e->length;
                        e = APR_BUCKET_NEXT(e);
                    }
                    else {
                        /*
                         * Read from bucket, but non blocking. If there isn't any
                         * more data, well than this is fine as well, we will
                         * not wait for more since we already got some and we are
                         * only checking if there isn't more.
                         */
                        rv = apr_bucket_read(e, &str, &bucket_len,
                                             APR_NONBLOCK_READ);
                        if (rv == APR_SUCCESS) {
                            len += bucket_len;
                            e = APR_BUCKET_NEXT(e);
                        }
                    }
                }
            }
    
            /* 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 */
            ctx->tmpbb = apr_brigade_split_ex(ctx->b, e, ctx->tmpbb);
    
            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, &copy_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 void setaside_remaining_output(ap_filter_t *f,
                                          core_output_filter_ctx_t *ctx,
                                          apr_bucket_brigade *bb,
                                          conn_rec *c);
    
    static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
                                                 apr_bucket_brigade *bb,
                                                 core_output_filter_ctx_t *ctx,
                                                 conn_rec *c);
    
    static apr_status_t writev_nonblocking(apr_socket_t *s,
                                           apr_bucket_brigade *bb,
                                           core_output_filter_ctx_t *ctx,
                                           apr_size_t bytes_to_write,
                                           apr_size_t nvec,
                                           conn_rec *c);
    
    #if APR_HAS_SENDFILE
    static apr_status_t sendfile_nonblocking(apr_socket_t *s,
                                             apr_bucket *bucket,
                                             core_output_filter_ctx_t *ctx,
                                             conn_rec *c);
    #endif
    
    /* XXX: Should these be configurable parameters? */
    #define THRESHOLD_MIN_WRITE 4096
    
    /* Optional function coming from mod_logio, used for logging of output
     * traffic
     */
    extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *ap__logio_add_bytes_out;
    
    static int should_send_brigade(apr_bucket_brigade *bb, conn_rec *c, int *flush)
    {
        core_server_config *conf =
            ap_get_core_module_config(c->base_server->module_config);
        apr_size_t total_bytes = 0, non_file_bytes = 0;
        apr_uint32_t eor_buckets = 0;
        apr_bucket *bucket;
        int need_flush = 0;
    
        /* Scan through the brigade and decide whether we need to flush it,
         * based on the following rules:
         *
         *  a) The brigade contains a flush bucket: Do a blocking write
         *     of everything up that point.
         *
         *  b) The request is in CONN_STATE_HANDLER state, and the brigade
         *     contains at least flush_max_threshold bytes in non-file
         *     buckets: Do blocking writes until the amount of data in the
         *     buffer is less than flush_max_threshold.  (The point of this
         *     rule is to provide flow control, in case a handler is
         *     streaming out lots of data faster than the data can be
         *     sent to the client.)
         *
         *  c) The request is in CONN_STATE_HANDLER state, and the brigade
         *     contains at least flush_max_pipelined EOR buckets:
         *     Do blocking writes until less than flush_max_pipelined EOR
         *     buckets are left. (The point of this rule is to prevent too many
         *     FDs being kept open by pipelined requests, possibly allowing a
         *     DoS).
         *
         *  d) The brigade contains a morphing bucket: otherwise ap_save_brigade()
         *     could read the whole bucket into memory.
         */
        for (bucket = APR_BRIGADE_FIRST(bb);
             bucket != APR_BRIGADE_SENTINEL(bb);
             bucket = APR_BUCKET_NEXT(bucket)) {
    
            if (!APR_BUCKET_IS_METADATA(bucket)) {
                if (bucket->length == (apr_size_t)-1) {
                    if (flush) {
                        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, c,
                                      "core_output_filter: flushing because "
                                      "of morphing bucket");
                    }
                    need_flush = 1;
                    break;
                }
    
                total_bytes += bucket->length;
                if (!APR_BUCKET_IS_FILE(bucket)) {
                    non_file_bytes += bucket->length;
                    if (non_file_bytes > conf->flush_max_threshold) {
                        if (flush) {
                            ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, c,
                                          "core_output_filter: flushing because "
                                          "of max threshold");
                        }
                        need_flush = 1;
                        break;
                    }
                }
            }
            else if (APR_BUCKET_IS_FLUSH(bucket)) {
                if (flush) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, c,
                                  "core_output_filter: flushing because "
                                  "of FLUSH bucket");
                }
                need_flush = 1;
                break;
            }
            else if (AP_BUCKET_IS_EOR(bucket)
                     && conf->flush_max_pipelined >= 0
                     && ++eor_buckets > conf->flush_max_pipelined) {
                if (flush) {
                    ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, c,
                                  "core_output_filter: flushing because "
                                  "of max pipelined");
                }
                need_flush = 1;
                break;
            }
        }
        if (flush) {
            *flush = need_flush;
        }
    
        /* Also send if above flush_min_threshold, or if there are FILE buckets */
        return (need_flush
                || total_bytes >= THRESHOLD_MIN_WRITE
                || total_bytes > non_file_bytes);
    }
    
    apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
    {
        conn_rec *c = f->c;
        core_net_rec *net = f->ctx;
        core_output_filter_ctx_t *ctx = net->out_ctx;
        apr_bucket_brigade *bb = NULL;
        apr_status_t rv = APR_SUCCESS;
    
        /* Fail quickly if the connection has already been aborted. */
        if (c->aborted) {
            if (new_bb != NULL) {
                apr_brigade_cleanup(new_bb);
            }
            return APR_ECONNABORTED;
        }
    
        if (ctx == NULL) {
            ctx = apr_pcalloc(c->pool, sizeof(*ctx));
            net->out_ctx = (core_output_filter_ctx_t *)ctx;
            /*
             * Need to create buffered_bb brigade with correct lifetime. Passing
             * NULL to ap_save_brigade() would result in a brigade
             * allocated from bb->pool which might be wrong.
             */
            ctx->buffered_bb = apr_brigade_create(c->pool, c->bucket_alloc);
        }
    
        if (new_bb != NULL)
            bb = new_bb;
    
        if ((ctx->buffered_bb != NULL) &&
            !APR_BRIGADE_EMPTY(ctx->buffered_bb)) {
            if (new_bb != NULL) {
                APR_BRIGADE_PREPEND(bb, ctx->buffered_bb);
            }
            else {
                bb = ctx->buffered_bb;
            }
        }
        else if (new_bb == NULL) {
            c->data_in_output_filters = 0;
            return APR_SUCCESS;
        }
    
        if (!new_bb || should_send_brigade(bb, c, NULL)) {
            apr_socket_t *sock = net->client_socket;
            apr_interval_time_t sock_timeout = 0;
    
            /* Non-blocking writes on the socket in any case. */
            apr_socket_timeout_get(sock, &sock_timeout);
            apr_socket_timeout_set(sock, 0);
    
            do {
                rv = send_brigade_nonblocking(sock, bb, ctx, c);
                if (new_bb && APR_STATUS_IS_EAGAIN(rv)) {
                    /* Scan through the brigade and decide whether we must absolutely
                     * flush the remaining data, based on should_send_brigade() &flush
                     * rules. If so, wait for writability and retry, otherwise we did
                     * our best already and can wait for the next call.
                     */
                    int flush;
                    (void)should_send_brigade(bb, c, &flush);
                    if (flush) {
                        apr_int32_t nfd;
                        apr_pollfd_t pfd;
                        memset(&pfd, 0, sizeof(pfd));
                        pfd.reqevents = APR_POLLOUT;
                        pfd.desc_type = APR_POLL_SOCKET;
                        pfd.desc.s = sock;
                        pfd.p = c->pool;
                        do {
                            rv = apr_poll(&pfd, 1, &nfd, sock_timeout);
                        } while (APR_STATUS_IS_EINTR(rv));
                    }
                }
            } while (rv == APR_SUCCESS && !APR_BRIGADE_EMPTY(bb));
    
            /* Restore original socket timeout before leaving. */
            apr_socket_timeout_set(sock, sock_timeout);
        }
    
        if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
            /* The client has aborted the connection */
            ap_log_cerror(
                    APLOG_MARK, APLOG_TRACE1, rv, c,
                    "core_output_filter: writing data to the network");
            /*
             * Set c->aborted before apr_brigade_cleanup to have the correct status
             * when logging the request as apr_brigade_cleanup triggers the logging
             * of the request if it contains an EOR bucket.
             */
            c->aborted = 1;
            apr_brigade_cleanup(bb);
            return rv;
        }
    
        setaside_remaining_output(f, ctx, bb, c);
        return APR_SUCCESS;
    }
    
    /*
     * This function assumes that either ctx->buffered_bb == NULL, or
     * ctx->buffered_bb is empty, or ctx->buffered_bb == bb
     */
    static void setaside_remaining_output(ap_filter_t *f,
                                          core_output_filter_ctx_t *ctx,
                                          apr_bucket_brigade *bb,
                                          conn_rec *c)
    {
        apr_bucket *bucket;
    
        /* Don't set aside leading empty buckets, all previous data have been
         * consumed so it's safe to delete them now.
         */
        while (((bucket = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) &&
               (APR_BUCKET_IS_METADATA(bucket) || (bucket->length == 0))) {
            apr_bucket_delete(bucket);
        }
    
        c->data_in_output_filters = 0;
        if (!APR_BRIGADE_EMPTY(bb)) {
            c->data_in_output_filters = 1;
            if (bb != ctx->buffered_bb) {
                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->buffered_bb), &bb,
                                ctx->deferred_write_pool);
            }
        }
        else if (ctx->deferred_write_pool) {
            /*
             * There are no more requests in the pipeline. We can just clear the
             * pool.
             */
            apr_pool_clear(ctx->deferred_write_pool);
        }
    }
    
    #ifndef APR_MAX_IOVEC_SIZE
    #define NVEC_MIN 16
    #define NVEC_MAX NVEC_MIN
    #else
    #if APR_MAX_IOVEC_SIZE > 16
    #define NVEC_MIN 16
    #else
    #define NVEC_MIN APR_MAX_IOVEC_SIZE
    #endif
    #define NVEC_MAX APR_MAX_IOVEC_SIZE
    #endif
    
    static APR_INLINE int is_in_memory_bucket(apr_bucket *b)
    {
        /* These buckets' data are already in memory. */
        return APR_BUCKET_IS_HEAP(b)
               || APR_BUCKET_IS_POOL(b)
               || APR_BUCKET_IS_TRANSIENT(b)
               || APR_BUCKET_IS_IMMORTAL(b);
    }
    
    #if APR_HAS_SENDFILE
    static APR_INLINE int can_sendfile_bucket(apr_bucket *b)
    {
        /* Use sendfile to send the bucket unless:
         *   - the bucket is not a file bucket, or
         *   - the file is too small for sendfile to be useful, or
         *   - sendfile is disabled in the httpd config via "EnableSendfile off".
         */
        if (APR_BUCKET_IS_FILE(b) && b->length >= AP_MIN_SENDFILE_BYTES) {
            apr_file_t *file = ((apr_bucket_file *)b->data)->fd;
            return apr_file_flags_get(file) & APR_SENDFILE_ENABLED;
        }
        else {
            return 0;
        }
    }
    #endif
    
    #if defined(WIN32) && (APR_MAJOR_VERSION == 1 && APR_MINOR_VERSION <= 7)
    #undef APR_TCP_NOPUSH_FLAG
    #define APR_TCP_NOPUSH_FLAG 0
    #endif
    
    static APR_INLINE void sock_nopush(apr_socket_t *s, int to)
    {
        /* Disable TCP_NOPUSH handling on OSX since unsetting it won't push
         * retained data, which might introduce delays if further data don't
         * come soon enough or cause the last chunk to be sent only when the
         * connection is shutdown (e.g. after KeepAliveTimeout).
         */
    #if APR_TCP_NOPUSH_FLAG && !defined(__APPLE__)
        (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, to);
    #endif
    }
    
    static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
                                                 apr_bucket_brigade *bb,
                                                 core_output_filter_ctx_t *ctx,
                                                 conn_rec *c)
    {
        apr_status_t rv = APR_SUCCESS;
        core_server_config *conf =
            ap_get_core_module_config(c->base_server->module_config);
        apr_size_t nvec = 0, nbytes = 0;
        apr_bucket *bucket, *next;
        const char *data;
        apr_size_t length;
    
        for (bucket = APR_BRIGADE_FIRST(bb);
             bucket != APR_BRIGADE_SENTINEL(bb);
             bucket = next) {
            next = APR_BUCKET_NEXT(bucket);
    
    #if APR_HAS_SENDFILE
            if (can_sendfile_bucket(bucket)) {
                if (nvec > 0) {
                    sock_nopush(s, 1);
                    rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
                    if (rv != APR_SUCCESS) {
                        goto cleanup;
                    }
                    nbytes = 0;
                    nvec = 0;
                }
                rv = sendfile_nonblocking(s, bucket, ctx, c);
                if (rv != APR_SUCCESS) {
                    goto cleanup;
                }
                continue;
            }
    #endif /* APR_HAS_SENDFILE */
    
            if (bucket->length) {
                /* Non-blocking read first, in case this is a morphing
                 * bucket type. */
                rv = apr_bucket_read(bucket, &data, &length, APR_NONBLOCK_READ);
                if (APR_STATUS_IS_EAGAIN(rv)) {
                    /* Read would block; flush any pending data and retry. */
                    if (nvec) {
                        rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
                        if (rv != APR_SUCCESS) {
                            goto cleanup;
                        }
                        nbytes = 0;
                        nvec = 0;
                    }
                    sock_nopush(s, 0);
    
                    rv = apr_bucket_read(bucket, &data, &length, APR_BLOCK_READ);
                }
                if (rv != APR_SUCCESS) {
                    goto cleanup;
                }
    
                /* reading may have split the bucket, so recompute next: */
                next = APR_BUCKET_NEXT(bucket);
            }
    
            if (!bucket->length) {
                /* Don't delete empty buckets until all the previous ones have been
                 * sent (nvec == 0); this must happen in sequence since metabuckets
                 * like EOR could free the data still pointed to by the iovec. So
                 * unless the latter is empty, let writev_nonblocking() cleanup the
                 * brigade in order.
                 */
                if (!nvec) {
                    apr_bucket_delete(bucket);
                }
            }
            else {
                /* Make sure that these new data fit in our iovec. */
                if (nvec == ctx->nvec) {
                    if (nvec == NVEC_MAX) {
                        sock_nopush(s, 1);
                        rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
                        if (rv != APR_SUCCESS) {
                            goto cleanup;
                        }
                        nbytes = 0;
                        nvec = 0;
                    }
                    else {
                        struct iovec *newvec;
                        apr_size_t newn = nvec * 2;
                        if (newn < NVEC_MIN) {
                            newn = NVEC_MIN;
                        }
                        else if (newn > NVEC_MAX) {
                            newn = NVEC_MAX;
                        }
                        newvec = apr_palloc(c->pool, newn * sizeof(struct iovec));
                        if (nvec) {
                            memcpy(newvec, ctx->vec, nvec * sizeof(struct iovec));
                        }
                        ctx->vec = newvec;
                        ctx->nvec = newn;
                    }
                }
                nbytes += length;
                ctx->vec[nvec].iov_base = (void *)data;
                ctx->vec[nvec].iov_len = length;
                nvec++;
            }
    
            /* Flush above max threshold, unless the brigade still contains in
             * memory buckets which we want to try writing in the same pass (if
             * we are at the end of the brigade, the write will happen outside
             * the loop anyway).
             */
            if (nbytes > conf->flush_max_threshold
                    && next != APR_BRIGADE_SENTINEL(bb)
                    && next->length && !is_in_memory_bucket(next)) {
                sock_nopush(s, 1);
                rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
                if (rv != APR_SUCCESS) {
                    goto cleanup;
                }
                nbytes = 0;
                nvec = 0;
            }
        }
        if (nvec > 0) {
            rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
        }
    
    cleanup:
        sock_nopush(s, 0);
        return rv;
    }
    
    static apr_status_t writev_nonblocking(apr_socket_t *s,
                                           apr_bucket_brigade *bb,
                                           core_output_filter_ctx_t *ctx,
                                           apr_size_t bytes_to_write,
                                           apr_size_t nvec,
                                           conn_rec *c)
    {
        apr_status_t rv;
        struct iovec *vec = ctx->vec;
        apr_size_t bytes_written = 0;
        apr_size_t i, offset = 0;
    
        do {
            apr_size_t n = 0;
            rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
            bytes_written += n;
    
            for (i = offset; i < nvec; ) {
                apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
                if (!bucket->length) {
                    apr_bucket_delete(bucket);
                }
                else if (n >= vec[i].iov_len) {
                    apr_bucket_delete(bucket);
                    n -= vec[i++].iov_len;
                    offset++;
                }
                else {
                    if (n) {
                        apr_bucket_split(bucket, n);
                        apr_bucket_delete(bucket);
                        vec[i].iov_len -= n;
                        vec[i].iov_base = (char *) vec[i].iov_base + n;
                    }
                    break;
                }
            }
        } while (rv == APR_SUCCESS && bytes_written < bytes_to_write);
    
        if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) {
            ap__logio_add_bytes_out(c, bytes_written);
        }
        ctx->bytes_written += bytes_written;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, rv, c,
                      "writev_nonblocking: %"APR_SIZE_T_FMT"/%"APR_SIZE_T_FMT,
                      bytes_written, bytes_to_write);
        return rv;
    }
    
    #if APR_HAS_SENDFILE
    
    static apr_status_t sendfile_nonblocking(apr_socket_t *s,
                                             apr_bucket *bucket,
                                             core_output_filter_ctx_t *ctx,
                                             conn_rec *c)
    {
        apr_status_t rv;
        apr_file_t *file = ((apr_bucket_file *)bucket->data)->fd;
        apr_size_t bytes_written = bucket->length; /* bytes_to_write for now */
        apr_off_t file_offset = bucket->start;
    
        rv = apr_socket_sendfile(s, file, NULL, &file_offset, &bytes_written, 0);
        if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) {
            ap__logio_add_bytes_out(c, bytes_written);
        }
        ctx->bytes_written += bytes_written;
    
        ap_log_cerror(APLOG_MARK, APLOG_TRACE6, rv, c,
                      "sendfile_nonblocking: %" APR_SIZE_T_FMT "/%" APR_SIZE_T_FMT,
                      bytes_written, bucket->length);
        if (bytes_written >= bucket->length) {
            apr_bucket_delete(bucket);
        }
        else if (bytes_written > 0) {
            apr_bucket_split(bucket, bytes_written);
            apr_bucket_delete(bucket);
            if (rv == APR_SUCCESS) {
                rv = APR_EAGAIN;
            }
        }
        return rv;
    }
    
    #endif
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/gen_test_char.mak���������������������������������������������������������������0000664�0001751�0001751�00000012272�12674411515�017441� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on gen_test_char.dsp
    !IF "$(CFG)" == ""
    CFG=gen_test_char - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to gen_test_char - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "gen_test_char - Win32 Release" && "$(CFG)" != "gen_test_char - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "gen_test_char - Win32 Release"
    
    OUTDIR=.
    INTDIR=.\Release
    # Begin Custom Macros
    OutDir=.
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\gen_test_char.exe"
    
    !ELSE 
    
    ALL : "libapr - Win32 Release" "$(OUTDIR)\gen_test_char.exe"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\gen_test_char.idb"
    	-@erase "$(INTDIR)\gen_test_char.obj"
    	-@erase "$(OUTDIR)\gen_test_char.exe"
    
    "$(INTDIR)" :
        if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\gen_test_char" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen_test_char.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\Release\gen_test_char.pdb" /out:"$(OUTDIR)\gen_test_char.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\gen_test_char.obj" \
    	"..\srclib\apr\Release\libapr-1.lib"
    
    "$(OUTDIR)\gen_test_char.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    !ELSEIF  "$(CFG)" == "gen_test_char - Win32 Debug"
    
    OUTDIR=.
    INTDIR=.\Debug
    # Begin Custom Macros
    OutDir=.
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\gen_test_char.exe"
    
    !ELSE 
    
    ALL : "libapr - Win32 Debug" "$(OUTDIR)\gen_test_char.exe"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\gen_test_char.idb"
    	-@erase "$(INTDIR)\gen_test_char.obj"
    	-@erase "$(OUTDIR)\Debug\gen_test_char.pdb"
    	-@erase "$(OUTDIR)\gen_test_char.exe"
    
    "$(INTDIR)" :
        if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "..\include" /I "..\srclib\apr\include" /I "..\srclib\apr-util\include" /I "..\os\win32" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\gen_test_char" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen_test_char.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\Debug\gen_test_char.pdb" /debug /out:"$(OUTDIR)\gen_test_char.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\gen_test_char.obj" \
    	"..\srclib\apr\Debug\libapr-1.lib"
    
    "$(OUTDIR)\gen_test_char.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("gen_test_char.dep")
    !INCLUDE "gen_test_char.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "gen_test_char.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "gen_test_char - Win32 Release" || "$(CFG)" == "gen_test_char - Win32 Debug"
    
    !IF  "$(CFG)" == "gen_test_char - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\..\server"
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\server"
    
    !ELSEIF  "$(CFG)" == "gen_test_char - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\..\server"
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\server"
    
    !ENDIF 
    
    SOURCE=.\gen_test_char.c
    
    "$(INTDIR)\gen_test_char.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_expr_scan.l����������������������������������������������������������������0000664�0001751�0001751�00000021734�15032766626�017350� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     *  ap_expr_scan.l, based on ssl_expr_scan.l from mod_ssl
     */
    
    /*  _________________________________________________________________
    **
    **  Expression Scanner
    **  _________________________________________________________________
    */
    
    %pointer
    %option batch
    %option never-interactive
    %option nodefault
    %option noyywrap
    %option reentrant
    %option bison-bridge
    %option warn
    %option noinput nounput noyy_top_state
    %option stack
    %x str
    %x var
    %x vararg
    %x regex regex_flags
    
    %{
    #include "util_expr_private.h"
    #include "util_expr_parse.h"
    
    #undef  YY_INPUT
    #define YY_INPUT(buf,result,max_size)                       \
    {                                                           \
        if ((result = MIN(max_size, yyextra->inputbuf           \
                                  + yyextra->inputlen           \
                                  - yyextra->inputptr)) <= 0)   \
        {                                                       \
            result = YY_NULL;                                   \
        }                                                       \
        else {                                                  \
            memcpy(buf, yyextra->inputptr, result);             \
            yyextra->inputptr += result;                        \
        }                                                       \
    }
    
    #define YY_EXTRA_TYPE ap_expr_parse_ctx_t*
    
    #define PERROR(msg) do { yyextra->error2 = msg ; return T_ERROR; } while (0)
    
    #define str_ptr     (yyextra->scan_ptr)
    #define str_buf     (yyextra->scan_buf)
    #define str_del     (yyextra->scan_del)
    
    #define STR_APPEND(c) do {                          \
            *str_ptr++ = (c);                           \
            if (str_ptr >= str_buf + sizeof(str_buf))   \
                PERROR("String too long");              \
        } while (0)
    
    %}
    
    
    %%
    
      char  regex_buf[MAX_STRING_LEN];
      char *regex_ptr = NULL;
      char  regex_del = '\0';
    
    %{
     /*
      * Set initial state for string expressions
      */
      if (yyextra->at_start) {
        yyextra->at_start = 0;
        if (yyextra->flags & AP_EXPR_FLAG_STRING_RESULT) {
            BEGIN(str);
            return T_EXPR_STRING;
        }
        else {
            return T_EXPR_BOOL;
        }
      }
    %}
    
     /*
      * Whitespaces
      */
    [ \t\n]+ { 
        /* NOP */
    }
    
     /*
      * strings ("..." and '...')
      */
    ["'] {
        str_ptr = str_buf;
        str_del = yytext[0];
        BEGIN(str);
        return T_STR_BEGIN;
    }
    <str>["'] {
        if (yytext[0] == str_del) {
            if (YY_START == var) {
                PERROR("Unterminated variable in string");
            }
            else if (str_ptr == str_buf) {
                BEGIN(INITIAL);
                return T_STR_END;
            }
            else {
                /* return what we have so far and scan delimiter again */
                *str_ptr = '\0';
                yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
                yyless(0);
                str_ptr = str_buf;
                return T_STRING;
            }
        }
        else {
            STR_APPEND(yytext[0]);
        }
    }
    <str,var,vararg>\n {
        PERROR("Unterminated string or variable");
    }
    <var,vararg><<EOF>> {
        PERROR("Unterminated string or variable");
    }
    <str><<EOF>> {
        if (!(yyextra->flags & AP_EXPR_FLAG_STRING_RESULT)) {
            PERROR("Unterminated string or variable");
        }
        else {
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            str_ptr = str_buf;
            BEGIN(INITIAL);
            return T_STRING;
        }
    }
    
    <str,vararg>\\[0-7]{1,3} {
        int result;
    
        (void)sscanf(yytext+1, "%o", &result);
        if (result > 0xff) {
            PERROR("Escape sequence out of bound");
        }
        else {
            STR_APPEND(result);
        }
    }
    <str,vararg>\\[0-9]+ {
        PERROR("Bad escape sequence");
    }
    <str,vararg>\\n      { STR_APPEND('\n'); }
    <str,vararg>\\r      { STR_APPEND('\r'); }
    <str,vararg>\\t      { STR_APPEND('\t'); }
    <str,vararg>\\b      { STR_APPEND('\b'); }
    <str,vararg>\\f      { STR_APPEND('\f'); }
    <str,vararg>\\(.|\n) { STR_APPEND(yytext[1]); }
    
     /* regexp backref inside string/arg */
    <str,vararg>[$][0-9] {
        if (str_ptr != str_buf) {
            /* return what we have so far and scan '$x' again */
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            str_ptr = str_buf;
            yyless(0);
            return T_STRING;
        }
        else {
            yylval->num = yytext[1] - '0';
            return T_REGEX_BACKREF;
        }
    }
    
    <str,vararg>[^\\\n"'%}$]+ {
        char *cp = yytext;
        while (*cp != '\0') {
            STR_APPEND(*cp);
            cp++;
        }
    }
    
     /* variable inside string/arg */
    <str,vararg>%\{ {
        if (str_ptr != str_buf) {
            /* return what we have so far and scan '%{' again */
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            yyless(0);
            str_ptr = str_buf;
            return T_STRING;
        }
        else {
            yy_push_state(var, yyscanner);
            return T_VAR_BEGIN;
        }
    }
    
    <vararg>[%$] {
         STR_APPEND(yytext[0]);
    }
    
    <str>[%}$] {
         STR_APPEND(yytext[0]);
    }
    
    %\{ {
        yy_push_state(var, yyscanner);
        return T_VAR_BEGIN;
    }
    
    [$][0-9] {
        yylval->num = yytext[1] - '0';
        return T_REGEX_BACKREF;
    }
    
     /*
      * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
      */
    <var>[a-zA-Z][a-zA-Z0-9_]* {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
        return T_ID;
    }
    
    <var>\} {
        yy_pop_state(yyscanner);
        return T_VAR_END;
    }
    
    <var>: {
        BEGIN(vararg);
        return yytext[0];
    }
    
    <var>.|\n {
        char *msg = apr_psprintf(yyextra->pool,
                                 "Invalid character in variable name '%c'", yytext[0]);
        PERROR(msg);
    }
    
    <vararg>\} {
        if (str_ptr != str_buf) {
            /* return what we have so far and scan '}' again */
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            str_ptr = str_buf;
            yyless(0);
            return T_STRING;
        }
        else {
            yy_pop_state(yyscanner);
            return T_VAR_END;
        }
    }
    
     /*
      * Regular Expression
      */
    "m"[/#$%^,;:_\?\|\^\-\!\.\'\"] {
        regex_del = yytext[1];
        regex_ptr = regex_buf;
        BEGIN(regex);
    }
    "/" {
        regex_del = yytext[0];
        regex_ptr = regex_buf;
        BEGIN(regex);
    }
    <regex>.|\n {
        if (yytext[0] == regex_del) {
            *regex_ptr = '\0';
            BEGIN(regex_flags);
        }
        else {
            *regex_ptr++ = yytext[0];
            if (regex_ptr >= regex_buf + sizeof(regex_buf))
                PERROR("Regexp too long");
        }
    }
    <regex_flags>i {
        yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
        BEGIN(INITIAL);
        return T_REGEX_I;
    }
    <regex_flags>.|\n {
        yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
        yyless(0);
        BEGIN(INITIAL);
        return T_REGEX;
    }
    <regex_flags><<EOF>> {
        yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
        BEGIN(INITIAL);
        return T_REGEX;
    }
    
     /*
      * Operators
      */
    ==?   { return T_OP_STR_EQ; }
    "!="  { return T_OP_STR_NE; }
    "<"   { return T_OP_STR_LT; }
    "<="  { return T_OP_STR_LE; }
    ">"   { return T_OP_STR_GT; }
    ">="  { return T_OP_STR_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; }
    "."   { return T_OP_CONCAT; }
    "-in"  { return T_OP_IN; }
    "-eq"  { return T_OP_EQ; }
    "-ne"  { return T_OP_NE; }
    "-ge"  { return T_OP_GE; }
    "-le"  { return T_OP_LE; }
    "-gt"  { return T_OP_GT; }
    "-lt"  { return T_OP_LT; }
    
     /* for compatibility with ssl_expr */
    "lt"  { return T_OP_LT; }
    "le"  { return T_OP_LE; }
    "gt"  { return T_OP_GT; }
    "ge"  { return T_OP_GE; }
    "ne"  { return T_OP_NE; }
    "eq"  { return T_OP_EQ; }
    "in"  { return T_OP_IN; }
    
    "-"[a-zA-Z_] {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
        return T_OP_UNARY;
    }
    
    "-"[a-zA-Z_][a-zA-Z_0-9]+ {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
        return T_OP_BINARY;
    }
    
     /*
      * Specials
      */
    "true"  { return T_TRUE; }
    "false" { return T_FALSE; }
    
     /*
      * Digits
      */
    -?[0-9]+ {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
        return T_DIGIT;
    }
    
     /*
      * Identifiers
      */
    [a-zA-Z][a-zA-Z0-9_]* {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
        return T_ID;
    }
    
     /*
      * These are parts of the grammar and are returned as is
      */
    [(){},:] {
        return yytext[0];
    }
    
     /*
      * Anything else is an error
      */
    .|\n {
        char *msg = apr_psprintf(yyextra->pool, "Parse error near '%c'", yytext[0]);
        PERROR(msg);
    }
    
    %%
    
    
    ������������������������������������httpd-2.4.64/server/gen_test_char.dep���������������������������������������������������������������0000664�0001751�0001751�00000000331�12674411515�017432� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by gen_test_char.mak
    
    .\gen_test_char.c : \
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_ebcdic.c�������������������������������������������������������������������0000664�0001751�0001751�00000006564�12411243364�016555� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    apr_status_t ap_init_ebcdic(apr_pool_t *pool)
    {
        apr_status_t rv;
    
        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, APLOGNO(00040)
                         "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, APLOGNO(00041)
                         "apr_xlate_open() failed");
            return rv;
        }
    
        rv = apr_MD5InitEBCDIC(ap_hdrs_to_ascii);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00042)
                         "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, APLOGNO(00043)
                         "apr_base64init_ebcdic() failed");
            return rv;
        }
    
        rv = apr_SHA1InitEBCDIC(ap_hdrs_to_ascii);
        if (rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00044)
                         "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_pstrmemdup(r->pool, s, len);
            ap_xlate_proto_to_ascii(ascii_s, len);
            if (ap_rputs(ascii_s, r) < 0) {
                va_end(va);
                return -1;
            }
            written += len;
        }
        va_end(va);
    
        return written;
    }
    #endif /* APR_CHARSET_EBCDIC */
    ��������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_expr_private.h�������������������������������������������������������������0000664�0001751�0001751�00000011116�11644654166�020063� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_EXPR_PRIVATE_H__
    #define __AP_EXPR_PRIVATE_H__
    
    #include "httpd.h"
    #include "apr_strings.h"
    #include "apr_tables.h"
    #include "ap_expr.h"
    
    #ifndef YY_NULL
    #define YY_NULL 0
    #endif
    
    #ifndef MIN
    #define MIN(a,b) (((a)<(b))?(a):(b))
    #endif
    
    #if !APR_HAVE_UNISTD_H
    #define YY_NO_UNISTD_H
    #endif
    
    #ifdef _MSC_VER
    /* Avoid some warnings with Visual Studio (likely due to a bug in bison) */
    #define YYMALLOC malloc
    #define YYFREE   free
    #endif
    
    #ifndef YYDEBUG
    #define YYDEBUG 0
    #endif
    
    /** The operations in a parse tree node */
    typedef enum {
        op_NOP,
        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_STR_EQ, op_STR_NE, op_STR_LT, op_STR_LE, op_STR_GT, op_STR_GE,
        op_Concat,
        op_Digit, op_String, op_Regex, op_RegexBackref,
        op_Var,
        op_ListElement,
        /*
         * call external functions/operators.
         * The info node contains the function pointer and some function specific
         * info.
         * For Binary operators, the Call node links to the Info node and the
         * Args node, which in turn links to the left and right operand.
         * For all other variants, the Call node links to the Info node and the
         * argument.
         */
        op_UnaryOpCall, op_UnaryOpInfo,
        op_BinaryOpCall, op_BinaryOpInfo, op_BinaryOpArgs,
        op_StringFuncCall, op_StringFuncInfo,
        op_ListFuncCall, op_ListFuncInfo
    } ap_expr_node_op_e;
    
    /** The basic parse tree node */
    struct ap_expr_node {
        ap_expr_node_op_e node_op;
        const void *node_arg1;
        const void *node_arg2;
    };
    
    /** The context used by scanner and parser */
    typedef struct {
        /* internal state of the scanner */
        const char        *inputbuf;
        int                inputlen;
        const char        *inputptr;
        void              *scanner;
        char              *scan_ptr;
        char               scan_buf[MAX_STRING_LEN];
        char               scan_del;
        int                at_start;
    
        /* pools for result and temporary usage */
        apr_pool_t        *pool;
        apr_pool_t        *ptemp;
    
        /* The created parse tree */
        ap_expr_t         *expr;
    
        const char        *error;
        const char        *error2;
        unsigned           flags;
    
        /*
         * The function to use to lookup provider functions for variables
         * and funtctions
         */
        ap_expr_lookup_fn_t *lookup_fn;
    } ap_expr_parse_ctx_t;
    
    /* flex/bison functions */
    int  ap_expr_yyparse(ap_expr_parse_ctx_t *context);
    void ap_expr_yyerror(ap_expr_parse_ctx_t *context, const char *err);
    int  ap_expr_yylex_init(void **scanner);
    int  ap_expr_yylex_destroy(void *scanner);
    void ap_expr_yyset_extra(ap_expr_parse_ctx_t *context, void *scanner);
    
    /* create a parse tree node */
    ap_expr_t *ap_expr_make(ap_expr_node_op_e op, const void *arg1,
                            const void *arg2, ap_expr_parse_ctx_t *ctx);
    /* create parse tree node for the string-returning function 'name' */
    ap_expr_t *ap_expr_str_func_make(const char *name, const ap_expr_t *arg,
                                   ap_expr_parse_ctx_t *ctx);
    /* create parse tree node for the list-returning function 'name' */
    ap_expr_t *ap_expr_list_func_make(const char *name, const ap_expr_t *arg,
                                    ap_expr_parse_ctx_t *ctx);
    /* create parse tree node for the variable 'name' */
    ap_expr_t *ap_expr_var_make(const char *name, ap_expr_parse_ctx_t *ctx);
    /* create parse tree node for the unary operator 'name' */
    ap_expr_t *ap_expr_unary_op_make(const char *name, const ap_expr_t *arg,
                                   ap_expr_parse_ctx_t *ctx);
    /* create parse tree node for the binary operator 'name' */
    ap_expr_t *ap_expr_binary_op_make(const char *name, const ap_expr_t *arg1,
                                      const ap_expr_t *arg2,
                                      ap_expr_parse_ctx_t *ctx);
    
    
    #endif /* __AP_EXPR_PRIVATE_H__ */
    /** @} */
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/eoc_bucket.c��������������������������������������������������������������������0000664�0001751�0001751�00000003303�10455005461�016376� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_expr_parse.y���������������������������������������������������������������0000664�0001751�0001751�00000017025�15032766626�017551� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 ap_expr_parse.y from mod_ssl */
    
    /*  _________________________________________________________________
    **
    **  Expression Parser
    **  _________________________________________________________________
    */
    
    %pure-parser
    %error-verbose
    %defines
    %lex-param   { void *yyscanner }
    %parse-param { ap_expr_parse_ctx_t *ctx }
    
    %{
    #include "util_expr_private.h"
    %}
    
    %union {
        char      *cpVal;
        ap_expr_t *exVal;
        int        num;
    }
    
    %token  T_TRUE
    %token  T_FALSE
    
    %token  T_EXPR_BOOL
    %token  T_EXPR_STRING
    
    %token  <cpVal> T_ERROR
    
    %token  <cpVal> T_DIGIT
    %token  <cpVal> T_ID
    %token  <cpVal> T_STRING
    %token  <cpVal> T_REGEX
    %token  <cpVal> T_REGEX_I
    %token  <num>   T_REGEX_BACKREF
    %token  <cpVal> T_OP_UNARY
    %token  <cpVal> T_OP_BINARY
    
    %token  T_STR_BEGIN
    %token  T_STR_END
    %token  T_VAR_BEGIN
    %token  T_VAR_END
    
    %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_STR_EQ
    %token  T_OP_STR_NE
    %token  T_OP_STR_LT
    %token  T_OP_STR_LE
    %token  T_OP_STR_GT
    %token  T_OP_STR_GE
    %token  T_OP_CONCAT
    
    %token  T_OP_OR
    %token  T_OP_AND
    %token  T_OP_NOT
    
    %right  T_OP_OR
    %right  T_OP_AND
    %right  T_OP_NOT
    %right  T_OP_CONCAT
    
    %type   <exVal>   expr
    %type   <exVal>   comparison
    %type   <exVal>   strfunccall
    %type   <exVal>   lstfunccall
    %type   <exVal>   regex
    %type   <exVal>   words
    %type   <exVal>   wordlist
    %type   <exVal>   word
    %type   <exVal>   string
    %type   <exVal>   strpart
    %type   <exVal>   var
    %type   <exVal>   backref
    
    %{
    #include "util_expr_private.h"
    #define yyscanner ctx->scanner
    
    int ap_expr_yylex(YYSTYPE *lvalp, void *scanner);
    %}
    
    
    %%
    
    root      : T_EXPR_BOOL   expr           { ctx->expr = $2; }
              | T_EXPR_STRING string         { ctx->expr = $2; }
              | T_ERROR                      { YYABORT; }
              ;
    
    expr      : T_TRUE                       { $$ = ap_expr_make(op_True,        NULL, NULL, ctx); }
              | T_FALSE                      { $$ = ap_expr_make(op_False,       NULL, NULL, ctx); }
              | T_OP_NOT expr                { $$ = ap_expr_make(op_Not,         $2,   NULL, ctx); }
              | expr T_OP_OR expr            { $$ = ap_expr_make(op_Or,          $1,   $3,   ctx); }
              | expr T_OP_AND expr           { $$ = ap_expr_make(op_And,         $1,   $3,   ctx); }
              | comparison                   { $$ = ap_expr_make(op_Comp,        $1,   NULL, ctx); }
              | T_OP_UNARY word              { $$ = ap_expr_unary_op_make(       $1,   $2,   ctx); }
              | word T_OP_BINARY word        { $$ = ap_expr_binary_op_make($2,   $1,   $3,   ctx); }
              | '(' expr ')'                 { $$ = $2; }
              | T_ERROR                      { YYABORT; }
              ;
    
    comparison: word T_OP_EQ word            { $$ = ap_expr_make(op_EQ,      $1, $3, ctx); }
              | word T_OP_NE word            { $$ = ap_expr_make(op_NE,      $1, $3, ctx); }
              | word T_OP_LT word            { $$ = ap_expr_make(op_LT,      $1, $3, ctx); }
              | word T_OP_LE word            { $$ = ap_expr_make(op_LE,      $1, $3, ctx); }
              | word T_OP_GT word            { $$ = ap_expr_make(op_GT,      $1, $3, ctx); }
              | word T_OP_GE word            { $$ = ap_expr_make(op_GE,      $1, $3, ctx); }
              | word T_OP_STR_EQ word        { $$ = ap_expr_make(op_STR_EQ,  $1, $3, ctx); }
              | word T_OP_STR_NE word        { $$ = ap_expr_make(op_STR_NE,  $1, $3, ctx); }
              | word T_OP_STR_LT word        { $$ = ap_expr_make(op_STR_LT,  $1, $3, ctx); }
              | word T_OP_STR_LE word        { $$ = ap_expr_make(op_STR_LE,  $1, $3, ctx); }
              | word T_OP_STR_GT word        { $$ = ap_expr_make(op_STR_GT,  $1, $3, ctx); }
              | word T_OP_STR_GE word        { $$ = ap_expr_make(op_STR_GE,  $1, $3, ctx); }
              | word T_OP_IN wordlist        { $$ = ap_expr_make(op_IN,      $1, $3, ctx); }
              | word T_OP_REG regex          { $$ = ap_expr_make(op_REG,     $1, $3, ctx); }
              | word T_OP_NRE regex          { $$ = ap_expr_make(op_NRE,     $1, $3, ctx); }
              ;
    
    wordlist  : lstfunccall                  { $$ = $1; }
              | '{' words '}'                { $$ = $2; }
              ;
    
    words     : word                         { $$ = ap_expr_make(op_ListElement, $1, NULL, ctx); }
              | words ',' word               { $$ = ap_expr_make(op_ListElement, $3, $1,   ctx); }
              ;
    
    string    : string strpart               { $$ = ap_expr_make(op_Concat, $1, $2, ctx); }
              | strpart                      { $$ = $1; }
              | T_ERROR                      { YYABORT; }
              ;
    
    strpart   : T_STRING                     { $$ = ap_expr_make(op_String, $1, NULL, ctx); }
              | var                          { $$ = $1; }
              | backref                      { $$ = $1; }
              ;
    
    var       : T_VAR_BEGIN T_ID T_VAR_END            { $$ = ap_expr_var_make($2, ctx); }
              | T_VAR_BEGIN T_ID ':' string T_VAR_END { $$ = ap_expr_str_func_make($2, $4, ctx); }
              ;
    
    word      : T_DIGIT                      { $$ = ap_expr_make(op_Digit,  $1, NULL, ctx); }
              | word T_OP_CONCAT word        { $$ = ap_expr_make(op_Concat, $1, $3,   ctx); }
              | var                          { $$ = $1; }
              | backref                      { $$ = $1; }
              | strfunccall                  { $$ = $1; }
              | T_STR_BEGIN string T_STR_END { $$ = $2; }
              | T_STR_BEGIN T_STR_END        { $$ = ap_expr_make(op_String, "", NULL, ctx); }
              ;
    
    regex     : T_REGEX {
                    ap_regex_t *regex;
                    if ((regex = ap_pregcomp(ctx->pool, $1,
                                             AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
                        ctx->error = "Failed to compile regular expression";
                        YYERROR;
                    }
                    $$ = ap_expr_make(op_Regex, regex, NULL, ctx);
                }
              | T_REGEX_I {
                    ap_regex_t *regex;
                    if ((regex = ap_pregcomp(ctx->pool, $1,
                                             AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
                        ctx->error = "Failed to compile regular expression";
                        YYERROR;
                    }
                    $$ = ap_expr_make(op_Regex, regex, NULL, ctx);
                }
              ;
    
    backref     : T_REGEX_BACKREF   {
                    int *n = apr_palloc(ctx->pool, sizeof(int));
                    *n = $1;
                    $$ = ap_expr_make(op_RegexBackref, n, NULL, ctx);
                }
                ;
    
    lstfunccall : T_ID '(' word ')' { $$ = ap_expr_list_func_make($1, $3, ctx); }
                ;
    
    strfunccall : T_ID '(' word ')' { $$ = ap_expr_str_func_make($1, $3, ctx); }
                ;
    
    %%
    
    void yyerror(ap_expr_parse_ctx_t *ctx, const char *s)
    {
        /* s is allocated on the stack */
        ctx->error = apr_pstrdup(ctx->ptemp, s);
    }
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/config.m4�����������������������������������������������������������������������0000664�0001751�0001751�00000000721�11515016742�015641� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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)
    
    dnl Add expr header files to INCLUDES
    # util_expr needs header files in server source dir
    APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/server])
    �����������������������������������������������httpd-2.4.64/server/log.c���������������������������������������������������������������������������0000664�0001751�0001751�00000174455�14635307332�015103� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_portable.h"
    #include "apr_base64.h"
    
    #define APR_WANT_STDIO
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    #if APR_HAVE_STDARG_H
    #include <stdarg.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if APR_HAVE_PROCESS_H
    #include <process.h>            /* for getpid() on Win32 */
    #endif
    
    #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"
    #include "ap_listen.h"
    
    #ifdef HAVE_SYS_GETTID
    #include <sys/syscall.h>
    #include <sys/types.h>
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    #ifndef DEFAULT_LOG_TID
    #define DEFAULT_LOG_TID NULL
    #endif
    
    typedef struct {
        const char *t_name;
        int t_val;
    } TRANS;
    
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(error_log)
        APR_HOOK_LINK(generate_log_id)
    )
    
    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},
        {"trace1",  APLOG_TRACE1},
        {"trace2",  APLOG_TRACE2},
        {"trace3",  APLOG_TRACE3},
        {"trace4",  APLOG_TRACE4},
        {"trace5",  APLOG_TRACE5},
        {"trace6",  APLOG_TRACE6},
        {"trace7",  APLOG_TRACE7},
        {"trace8",  APLOG_TRACE8},
        {NULL,      -1},
    };
    
    static apr_pool_t *stderr_pool = NULL;
    
    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;
    
    /**
     * @brief 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 *read_fd, *write_fd;
    #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;
        /** How to reinvoke program when it must be replaced */
        apr_cmdtype_e cmdtype;
    #endif
    };
    
    AP_DECLARE(apr_file_t *) ap_piped_log_read_fd(piped_log *pl)
    {
        return pl->read_fd;
    }
    
    AP_DECLARE(apr_file_t *) ap_piped_log_write_fd(piped_log *pl)
    {
        return pl->write_fd;
    }
    
    /* remember to close this handle in the child process
     *
     * On Win32 this makes zero sense, because we don't
     * take the parent process's child procs.
     * If the win32 parent instead passed each and every
     * logger write handle from itself down to the child,
     * and the parent manages all aspects of keeping the
     * reliable pipe log children alive, this would still
     * make no sense :)  Cripple it on Win32.
     */
    static void close_handle_in_child(apr_pool_t *p, apr_file_t *f)
    {
    #ifndef WIN32
        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;
    #endif
    }
    
    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, ap_server_conf, APLOGNO(00085) "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, ap_server_conf, APLOGNO(00086)
                         "%s: could not open error log file %s.",
                         ap_server_argv0, fname);
            return rc;
        }
        if (!stderr_pool) {
            /* This is safe provided we revert it when we are finished.
             * We don't manager the callers pool!
             */
            stderr_pool = p;
        }
        if ((rc = apr_file_open_stderr(&stderr_log, stderr_pool))
                == APR_SUCCESS) {
            apr_file_flush(stderr_log);
            if ((rc = apr_file_dup2(stderr_log, stderr_file, stderr_pool))
                    == APR_SUCCESS) {
                apr_file_close(stderr_file);
                /*
                 * You might ponder why stderr_pool should survive?
                 * The trouble is, stderr_pool may have s_main->error_log,
                 * so we aren't in a position to destroy stderr_pool until
                 * the next recycle.  There's also an apparent bug which
                 * is not; if some folk decided to call this function before
                 * the core open error logs hook, this pool won't survive.
                 * Neither does the stderr logger, so this isn't a problem.
                 */
            }
        }
        /* Revert, see above */
        if (stderr_pool == p)
            stderr_pool = NULL;
    
        if (rc != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, rc, NULL, APLOGNO(00087)
                         "unable to replace stderr with error log file");
        }
        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, APLOGNO(00088)
                     "%s", description);
    }
    
    /* Create a child process running PROGNAME with a pipe connected to
     * the child's stdin.  The write-end of the pipe will be placed in
     * *FPIN on successful return.  If dummy_stderr is non-zero, the
     * stderr for the child will be the same as the stdout of the parent.
     * Otherwise the child will inherit the stderr from the parent. */
    static int log_child(apr_pool_t *p, const char *progname,
                         apr_file_t **fpin, apr_cmdtype_e cmdtype,
                         int dummy_stderr)
    {
        /* 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;
        apr_file_t *errfile;
    
        if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS)
            && ((rc = apr_procattr_dir_set(procattr,
                                           ap_server_root)) == APR_SUCCESS)
            && ((rc = apr_procattr_cmdtype_set(procattr, cmdtype)) == 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;
    
            apr_tokenize_to_argv(progname, &args, p);
            procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew));
    
            if (dummy_stderr) {
                if ((rc = apr_file_open_stdout(&errfile, p)) == APR_SUCCESS)
                    rc = apr_procattr_child_err_set(procattr, errfile, NULL);
            }
    
            if (rc == APR_SUCCESS) {
                rc = apr_proc_create(procnew, args[0], (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;
    }
    
    /* Open the error log for the given server_rec.  If IS_MAIN is
     * non-zero, s is the main server. */
    static int open_error_log(server_rec *s, int is_main, apr_pool_t *p)
    {
        const char *fname;
        int rc;
    
        if (*s->error_fname == '|') {
            apr_file_t *dummy = NULL;
            apr_cmdtype_e cmdtype = APR_PROGRAM_ENV;
            fname = s->error_fname + 1;
    
            /* In 2.4 favor PROGRAM_ENV, accept "||prog" syntax for compatibility
             * and "|$cmd" to override the default.
             * Any 2.2 backport would continue to favor SHELLCMD_ENV so there
             * accept "||prog" to override, and "|$cmd" to ease conversion.
             */
            if (*fname == '|')
                ++fname;
            if (*fname == '$') {
                cmdtype = APR_SHELLCMD_ENV;
                ++fname;
            }
    
            /* Spawn a new child logger.  If this is the main server_rec,
             * the new child must use a dummy stderr since the current
             * stderr might be a pipe to the old logger.  Otherwise, the
             * child inherits the parents stderr. */
            rc = log_child(p, fname, &dummy, cmdtype, is_main);
            if (rc != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, ap_server_conf, APLOGNO(00089)
                             "Couldn't start ErrorLog process '%s'.",
                             s->error_fname + 1);
                return DONE;
            }
    
            s->error_log = dummy;
        }
    
    #ifdef HAVE_SYSLOG
        else if (strcmp(s->error_fname, "syslog") == 0
                 || strncmp(s->error_fname, "syslog:", 7) == 0) {
            if ((fname = strchr(s->error_fname, ':'))) {
                /* s->error_fname could be [level]:[tag] (see #60525) */
                const char *tag;
                apr_size_t flen;
                const TRANS *fac;
    
                fname++;
                tag = ap_strchr_c(fname, ':');
                if (tag) {
                    flen = tag - fname;
                    tag++;
                    if (*tag == '\0') {
                        tag = ap_server_argv0;
                    }
                } else {
                    flen = strlen(fname);
                    tag = ap_server_argv0;
                }
                if (flen == 0) {
                    /* Was something like syslog::foobar */
                    openlog(tag, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7);
                } else {
                    for (fac = facilities; fac->t_name; fac++) {
                        if (!strncasecmp(fname, fac->t_name, flen)) {
                            openlog(tag, LOG_NDELAY|LOG_CONS|LOG_PID,
                                    fac->t_val);
                            s->error_log = NULL;
                            return OK;
                        }
                    }
                    /* Huh? Invalid level name? */
                    ap_log_error(APLOG_MARK, APLOG_STARTUP, APR_EBADPATH, NULL, APLOGNO(10036)
                                 "%s: could not open syslog error log %s.",
                                  ap_server_argv0, fname);
                    return DONE;
                }
            }
            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, ap_server_conf, APLOGNO(00090)
                             "%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, ap_server_conf, APLOGNO(00091)
                             "%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_pool_t *stderr_p;
        server_rec *virt, *q;
        int replace_stderr;
    
    
        /* Register to throw away the read_handles list when we
         * cleanup plog.  Upon fork() for the apache children,
         * this read_handles list is closed so only the parent
         * can relaunch a lost log child.  These read handles
         * are always closed on exec.
         * We won't care what happens to our stderr log child
         * between log phases, so we don't mind losing stderr's
         * read_handle a little bit early.
         */
        apr_pool_cleanup_register(p, &read_handles, ap_pool_cleanup_set_null,
                                  apr_pool_cleanup_null);
    
        /* HERE we need a stdout log that outlives plog.
         * We *presume* the parent of plog is a process
         * or global pool which spans server restarts.
         * Create our stderr_pool as a child of the plog's
         * parent pool.
         */
        apr_pool_create(&stderr_p, apr_pool_parent_get(p));
        apr_pool_tag(stderr_p, "stderr_pool");
    
        if (open_error_log(s_main, 1, stderr_p) != OK) {
            return DONE;
        }
    
        replace_stderr = 1;
        if (s_main->error_log) {
            apr_status_t rv;
    
            /* Replace existing stderr with new log. */
            apr_file_flush(s_main->error_log);
            rv = apr_file_dup2(stderr_log, s_main->error_log, stderr_p);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s_main, APLOGNO(00092)
                             "unable to replace stderr with error_log");
            }
            else {
                /* We are done with stderr_pool, close it, killing
                 * the previous generation's stderr logger
                 */
                if (stderr_pool)
                    apr_pool_destroy(stderr_pool);
                stderr_pool = stderr_p;
                replace_stderr = 0;
                /*
                 * Now that we have dup'ed s_main->error_log to stderr_log
                 * close it and set s_main->error_log to stderr_log. This avoids
                 * this fd being inherited by the next piped logger who would
                 * keep open the writing end of the pipe that this one uses
                 * as stdin. This in turn would prevent the piped logger from
                 * exiting.
                 */
                apr_file_close(s_main->error_log);
                s_main->error_log = stderr_log;
            }
        }
        /* 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
         *      errno-as-apr_status_t is also non-portable
         */
    
    #ifdef WIN32
    #define NULL_DEVICE "nul"
    #else
    #define NULL_DEVICE "/dev/null"
    #endif
    
        if (replace_stderr && freopen(NULL_DEVICE, "w", stderr) == NULL) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s_main, APLOGNO(00093)
                         "unable to replace stderr with %s", NULL_DEVICE);
        }
    
        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, 0, 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 int cpystrn(char *buf, const char *arg, int buflen)
    {
        char *end;
        if (!arg)
            return 0;
        end = apr_cpystrn(buf, arg, buflen);
        return end - buf;
    }
    
    
    static int log_remote_address(const ap_errorlog_info *info, const char *arg,
                                  char *buf, int buflen)
    {
        if (info->r && !(arg && *arg == 'c'))
            return apr_snprintf(buf, buflen, "%s:%d", info->r->useragent_ip,
                                info->r->useragent_addr ? info->r->useragent_addr->port : 0);
        else if (info->c)
            return apr_snprintf(buf, buflen, "%s:%d", info->c->client_ip,
                                info->c->client_addr ? info->c->client_addr->port : 0);
        else
            return 0;
    }
    
    static int log_local_address(const ap_errorlog_info *info, const char *arg,
                                 char *buf, int buflen)
    {
        if (info->c)
            return apr_snprintf(buf, buflen, "%s:%d", info->c->local_ip,
                                info->c->local_addr->port);
        else
            return 0;
    }
    
    static int log_pid(const ap_errorlog_info *info, const char *arg,
                       char *buf, int buflen)
    {
        pid_t pid = getpid();
        return apr_snprintf(buf, buflen, "%" APR_PID_T_FMT, pid);
    }
    
    static int log_tid(const ap_errorlog_info *info, const char *arg,
                       char *buf, int buflen)
    {
    #if APR_HAS_THREADS
        int result;
    #endif
    #if defined(HAVE_GETTID) || defined(HAVE_SYS_GETTID)
        if (arg && *arg == 'g') {
    #ifdef HAVE_GETTID
            pid_t tid = gettid();
    #else
            pid_t tid = syscall(SYS_gettid);
    #endif
            if (tid == -1)
                return 0;
            return apr_snprintf(buf, buflen, "%"APR_PID_T_FMT, tid);
        }
    #endif /* HAVE_GETTID || HAVE_SYS_GETTID */
    #if APR_HAS_THREADS
        if (ap_mpm_query(AP_MPMQ_IS_THREADED, &result) == APR_SUCCESS
            && result != AP_MPMQ_NOT_SUPPORTED)
        {
            apr_os_thread_t tid = apr_os_thread_current();
            return apr_snprintf(buf, buflen, "%pT", &tid);
        }
    #endif
        return 0;
    }
    
    static int log_ctime(const ap_errorlog_info *info, const char *arg,
                         char *buf, int buflen)
    {
        int time_len = buflen;
        int option = AP_CTIME_OPTION_NONE;
    
        if (arg) {
            if (arg[0] == 'u' && !arg[1]) { /* no ErrorLogFormat (fast path) */
                option |= AP_CTIME_OPTION_USEC;
            }
            else if (!ap_strchr_c(arg, '%')) { /* special "%{cuz}t" formats */
                while (*arg) {
                    switch (*arg++) {
                    case 'u':
                        option |= AP_CTIME_OPTION_USEC;
                        break;
                    case 'c':
                        option |= AP_CTIME_OPTION_COMPACT;
                        break;
                    case 'z':
                        option |= AP_CTIME_OPTION_GMTOFF;
                        break;
                    }
                }
            }
            else { /* "%{strftime %-format}t" */
                apr_size_t len = 0;
                apr_time_exp_t expt;
                ap_explode_recent_localtime(&expt, apr_time_now());
                apr_strftime(buf, &len, buflen, arg, &expt);
                return (int)len;
            }
        }
    
        ap_recent_ctime_ex(buf, apr_time_now(), option, &time_len);
    
        /* ap_recent_ctime_ex includes the trailing \0 in time_len */
        return time_len - 1;
    }
    
    static int log_loglevel(const ap_errorlog_info *info, const char *arg,
                            char *buf, int buflen)
    {
        if (info->level < 0)
            return 0;
        else
            return cpystrn(buf, priorities[info->level].t_name, buflen);
    }
    
    static int log_log_id(const ap_errorlog_info *info, const char *arg,
                          char *buf, int buflen)
    {
        /*
         * C: log conn log_id if available,
         * c: log conn log id if available and not a once-per-request log line
         * else: log request log id if available
         */
        if (arg && !strcasecmp(arg, "c")) {
            if (info->c && (*arg != 'C' || !info->r)) {
                return cpystrn(buf, info->c->log_id, buflen);
            }
        }
        else if (info->rmain) {
            return cpystrn(buf, info->rmain->log_id, buflen);
        }
        return 0;
    }
    
    static int log_keepalives(const ap_errorlog_info *info, const char *arg,
                              char *buf, int buflen)
    {
        if (!info->c)
            return 0;
    
        return apr_snprintf(buf, buflen, "%d", info->c->keepalives);
    }
    
    static int log_module_name(const ap_errorlog_info *info, const char *arg,
                               char *buf, int buflen)
    {
        return cpystrn(buf, ap_find_module_short_name(info->module_index), buflen);
    }
    
    static int log_file_line(const ap_errorlog_info *info, const char *arg,
                             char *buf, int buflen)
    {
        if (info->file == NULL) {
            return 0;
        }
        else {
            const char *file = info->file;
    #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 */
            return apr_snprintf(buf, buflen, "%s(%d)", file, info->line);
        }
    }
    
    static int log_apr_status(const ap_errorlog_info *info, const char *arg,
                              char *buf, int buflen)
    {
        apr_status_t status = info->status;
        int len;
        if (!status)
            return 0;
    
        if (status < APR_OS_START_EAIERR) {
            len = apr_snprintf(buf, buflen, "(%d)", status);
        }
        else if (status < APR_OS_START_SYSERR) {
            len = apr_snprintf(buf, buflen, "(EAI %d)",
                               status - APR_OS_START_EAIERR);
        }
        else if (status < 100000 + APR_OS_START_SYSERR) {
            len = apr_snprintf(buf, buflen, "(OS %d)",
                               status - APR_OS_START_SYSERR);
        }
        else {
            len = apr_snprintf(buf, buflen, "(os 0x%08x)",
                               status - APR_OS_START_SYSERR);
        }
        apr_strerror(status, buf + len, buflen - len);
        len += strlen(buf + len);
        return len;
    }
    
    static int log_server_name(const ap_errorlog_info *info, const char *arg,
                               char *buf, int buflen)
    {
        if (info->r)
            return cpystrn(buf, ap_get_server_name((request_rec *)info->r), buflen);
    
        return 0;
    }
    
    static int log_virtual_host(const ap_errorlog_info *info, const char *arg,
                                char *buf, int buflen)
    {
        if (info->s)
            return cpystrn(buf, info->s->server_hostname, buflen);
    
        return 0;
    }
    
    
    static int log_table_entry(const apr_table_t *table, const char *name,
                               char *buf, int buflen)
    {
    #ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED
        const char *value;
        char scratch[MAX_STRING_LEN];
    
        if ((value = apr_table_get(table, name)) != NULL) {
            ap_escape_errorlog_item(scratch, value, MAX_STRING_LEN);
            return cpystrn(buf, scratch, buflen);
        }
    
        return 0;
    #else
        return cpystrn(buf, apr_table_get(table, name), buflen);
    #endif
    }
    
    static int log_header(const ap_errorlog_info *info, const char *arg,
                          char *buf, int buflen)
    {
        if (info->r)
            return log_table_entry(info->r->headers_in, arg, buf, buflen);
    
        return 0;
    }
    
    static int log_note(const ap_errorlog_info *info, const char *arg,
                          char *buf, int buflen)
    {
        /* XXX: maybe escaping the entry is not necessary for notes? */
        if (info->r)
            return log_table_entry(info->r->notes, arg, buf, buflen);
    
        return 0;
    }
    
    static int log_env_var(const ap_errorlog_info *info, const char *arg,
                          char *buf, int buflen)
    {
        if (info->r)
            return log_table_entry(info->r->subprocess_env, arg, buf, buflen);
    
        return 0;
    }
    
    static int core_generate_log_id(const conn_rec *c, const request_rec *r,
                                     const char **idstring)
    {
        apr_uint64_t id, tmp;
        pid_t pid;
        int len;
        char *encoded;
    
        if (r && r->request_time) {
            id = (apr_uint64_t)r->request_time;
        }
        else {
            id = (apr_uint64_t)apr_time_now();
        }
    
        pid = getpid();
        if (sizeof(pid_t) > 2) {
            tmp = pid;
            tmp = tmp << 40;
            id ^= tmp;
            pid = pid >> 24;
            tmp = pid;
            tmp = tmp << 56;
            id ^= tmp;
        }
        else {
            tmp = pid;
            tmp = tmp << 40;
            id ^= tmp;
        }
    #if APR_HAS_THREADS
        {
            apr_uintptr_t tmp2 = (apr_uintptr_t)c->current_thread;
            tmp = tmp2;
            tmp = tmp << 32;
            id ^= tmp;
        }
    #endif
    
        len = apr_base64_encode_len(sizeof(id)); /* includes trailing \0 */
        encoded = apr_palloc(r ? r->pool : c->pool, len);
        apr_base64_encode(encoded, (char *)&id, sizeof(id));
    
        /* Skip the last char, it is always '=' */
        encoded[len - 2] = '\0';
    
        *idstring = encoded;
    
        return OK;
    }
    
    static void add_log_id(const conn_rec *c, const request_rec *r)
    {
        const char **id;
        /* need to cast const away */
        if (r) {
            id = &((request_rec *)r)->log_id;
        }
        else {
            id = &((conn_rec *)c)->log_id;
        }
    
        ap_run_generate_log_id(c, r, id);
    }
    
    AP_DECLARE(void) ap_register_log_hooks(apr_pool_t *p)
    {
        ap_hook_generate_log_id(core_generate_log_id, NULL, NULL,
                                APR_HOOK_REALLY_LAST);
    
        ap_register_errorlog_handler(p, "a", log_remote_address, 0);
        ap_register_errorlog_handler(p, "A", log_local_address, 0);
        ap_register_errorlog_handler(p, "e", log_env_var, 0);
        ap_register_errorlog_handler(p, "E", log_apr_status, 0);
        ap_register_errorlog_handler(p, "F", log_file_line, 0);
        ap_register_errorlog_handler(p, "i", log_header, 0);
        ap_register_errorlog_handler(p, "k", log_keepalives, 0);
        ap_register_errorlog_handler(p, "l", log_loglevel, 0);
        ap_register_errorlog_handler(p, "L", log_log_id, 0);
        ap_register_errorlog_handler(p, "m", log_module_name, 0);
        ap_register_errorlog_handler(p, "n", log_note, 0);
        ap_register_errorlog_handler(p, "P", log_pid, 0);
        ap_register_errorlog_handler(p, "t", log_ctime, 0);
        ap_register_errorlog_handler(p, "T", log_tid, 0);
        ap_register_errorlog_handler(p, "v", log_virtual_host, 0);
        ap_register_errorlog_handler(p, "V", log_server_name, 0);
    }
    
    /*
     * This is used if no error log format is defined and during startup.
     * It automatically omits the timestamp if logging to syslog.
     */
    static int do_errorlog_default(const ap_errorlog_info *info, char *buf,
                                   int buflen, int *errstr_start, int *errstr_end,
                                   const char *errstr_fmt, va_list args)
    {
        int len = 0;
        int field_start = 0;
        int item_len;
    #ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED
        char scratch[MAX_STRING_LEN];
    #endif
    
        if (!info->using_syslog && !info->startup) {
            buf[len++] = '[';
            len += log_ctime(info, "u", buf + len, buflen - len);
            buf[len++] = ']';
            buf[len++] = ' ';
        }
    
        if (!info->startup) {
            buf[len++] = '[';
            len += log_module_name(info, NULL, buf + len, buflen - len);
            buf[len++] = ':';
            len += log_loglevel(info, NULL, buf + len, buflen - len);
            len += cpystrn(buf + len, "] [pid ", buflen - len);
    
            len += log_pid(info, NULL, buf + len, buflen - len);
    #if APR_HAS_THREADS
            field_start = len;
            len += cpystrn(buf + len, ":tid ", buflen - len);
            item_len = log_tid(info, DEFAULT_LOG_TID, buf + len, buflen - len);
            if (!item_len)
                len = field_start;
            else
                len += item_len;
    #endif
            buf[len++] = ']';
            buf[len++] = ' ';
        }
    
        if (info->level >= APLOG_DEBUG) {
            item_len = log_file_line(info, NULL, buf + len, buflen - len);
            if (item_len) {
                len += item_len;
                len += cpystrn(buf + len, ": ", buflen - len);
            }
        }
    
        if (info->status) {
            item_len = log_apr_status(info, NULL, buf + len, buflen - len);
            if (item_len) {
                len += item_len;
                len += cpystrn(buf + len, ": ", buflen - len);
            }
        }
    
        /*
         * useragent_ip/client_ip can be client or backend server. If we have
         * a scoreboard handle, it is likely a client.
         */
        if (info->r) {
            len += apr_snprintf(buf + len, buflen - len,
                                info->r->connection->sbh ? "[client %s:%d] " : "[remote %s:%d] ",
                                info->r->useragent_ip,
                                info->r->useragent_addr ? info->r->useragent_addr->port : 0);
        }
        else if (info->c) {
            len += apr_snprintf(buf + len, buflen - len,
                                info->c->sbh ? "[client %s:%d] " : "[remote %s:%d] ",
                                info->c->client_ip,
                                info->c->client_addr ? info->c->client_addr->port : 0);
        }
    
        /* the actual error message */
        *errstr_start = len;
    #ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED
        if (apr_vsnprintf(scratch, MAX_STRING_LEN, errstr_fmt, args)) {
            len += ap_escape_errorlog_item(buf + len, scratch,
                                           buflen - len);
    
        }
    #else
        len += apr_vsnprintf(buf + len, buflen - len, errstr_fmt, args);
    #endif
        *errstr_end = len;
    
        field_start = len;
        len += cpystrn(buf + len, ", referer: ", buflen - len);
        item_len = log_header(info, "Referer", buf + len, buflen - len);
        if (item_len)
            len += item_len;
        else
            len = field_start;
    
        return len;
    }
    
    static int do_errorlog_format(apr_array_header_t *fmt, ap_errorlog_info *info,
                                  char *buf, int buflen, int *errstr_start,
                                  int *errstr_end, const char *err_fmt, va_list args)
    {
    #ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED
        char scratch[MAX_STRING_LEN];
    #endif
        int i;
        int len = 0;
        int field_start = 0;
        int skipping = 0;
        ap_errorlog_format_item *items = (ap_errorlog_format_item *)fmt->elts;
    
        AP_DEBUG_ASSERT(fmt->nelts > 0);
        for (i = 0; i < fmt->nelts; ++i) {
            ap_errorlog_format_item *item = &items[i];
            if (item->flags & AP_ERRORLOG_FLAG_FIELD_SEP) {
                if (skipping) {
                    skipping = 0;
                }
                else {
                    field_start = len;
                }
            }
    
            if (item->flags & AP_ERRORLOG_FLAG_MESSAGE) {
                /* the actual error message */
                *errstr_start = len;
    #ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED
                if (apr_vsnprintf(scratch, MAX_STRING_LEN, err_fmt, args)) {
                    len += ap_escape_errorlog_item(buf + len, scratch,
                                                   buflen - len);
    
                }
    #else
                len += apr_vsnprintf(buf + len, buflen - len, err_fmt, args);
    #endif
                *errstr_end = len;
            }
            else if (skipping) {
                continue;
            }
            else if (info->level != -1 && (int)item->min_loglevel > info->level) {
                len = field_start;
                skipping = 1;
            }
            else {
                int item_len = (*item->func)(info, item->arg, buf + len,
                                             buflen - len);
                if (!item_len) {
                    if (item->flags & AP_ERRORLOG_FLAG_REQUIRED) {
                        /* required item is empty. skip whole line */
                        buf[0] = '\0';
                        return 0;
                    }
                    else if (item->flags & AP_ERRORLOG_FLAG_NULL_AS_HYPHEN) {
                        buf[len++] = '-';
                    }
                    else {
                        len = field_start;
                        skipping = 1;
                    }
                }
                else {
                    len += item_len;
                }
            }
        }
        return len;
    }
    
    static void write_logline(char *errstr, apr_size_t len, apr_file_t *logf,
                              int level)
    {
        /* 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 < LOG_PRIMASK ? level : APLOG_DEBUG, "%.*s",
                   (int)len, errstr);
        }
    #endif
    }
    
    static void log_error_core(const char *file, int line, int module_index,
                               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];
        apr_file_t *logf = NULL;
        int level_and_mask = level & APLOG_LEVELMASK;
        const request_rec *rmain = NULL;
        core_server_config *sconf = NULL;
        ap_errorlog_info info;
    
        /* do we need to log once-per-req or once-per-conn info? */
        int log_conn_info = 0, log_req_info = 0;
        apr_array_header_t **lines = NULL;
        int done = 0;
        int line_number = 0;
    
        if (r) {
            AP_DEBUG_ASSERT(r->connection != NULL);
            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
             */
    #ifndef DEBUG
            if ((level_and_mask != APLOG_NOTICE)
                && (level_and_mask > ap_default_loglevel)) {
                return;
            }
    #endif
    
            logf = stderr_log;
    
            /* Use the main ErrorLogFormat if any */
            if (ap_server_conf) {
                sconf = ap_get_core_module_config(ap_server_conf->module_config);
            }
        }
        else {
            int configured_level = r ? ap_get_request_module_loglevel(r, module_index)        :
                                   c ? ap_get_conn_server_module_loglevel(c, s, module_index) :
                                       ap_get_server_module_loglevel(s, module_index);
            if (s->error_log) {
                /*
                 * If we are doing normal logging, don't log messages that are
                 * above the module's log level unless it is a startup/shutdown notice
                 */
                if ((level_and_mask != APLOG_NOTICE)
                    && (level_and_mask > configured_level)) {
                    return;
                }
    
                logf = s->error_log;
            }
            else {
                /*
                 * If we are doing syslog logging, don't log messages that are
                 * above the module's log level (including a startup/shutdown notice)
                 */
                if (level_and_mask > configured_level) {
                    return;
                }
            }
    
            /* the faked server_rec from mod_cgid does not have s->module_config */
            if (s->module_config) {
                sconf = ap_get_core_module_config(s->module_config);
                if (c && !c->log_id) {
                    add_log_id(c, NULL);
                    if (sconf->error_log_conn && sconf->error_log_conn->nelts > 0)
                        log_conn_info = 1;
                }
                if (r) {
                    if (r->main)
                        rmain = r->main;
                    else
                        rmain = r;
    
                    if (!rmain->log_id) {
                        /* XXX: do we need separate log ids for subrequests? */
                        if (sconf->error_log_req && sconf->error_log_req->nelts > 0)
                            log_req_info = 1;
                        /*
                         * XXX: potential optimization: only create log id if %L is
                         * XXX: actually used
                         */
                        add_log_id(c, rmain);
                    }
                }
            }
            else if (ap_server_conf) {
                /* Use the main ErrorLogFormat if any */
                sconf = ap_get_core_module_config(ap_server_conf->module_config);
            }
        }
    
        info.s             = s;
        info.c             = c;
        info.pool          = pool;
        info.file          = NULL;
        info.line          = 0;
        info.status        = 0;
        info.using_syslog  = (logf == NULL);
        info.startup       = ((level & APLOG_STARTUP) == APLOG_STARTUP);
        info.format        = fmt;
    
        while (!done) {
            apr_array_header_t *log_format;
            int len = 0, errstr_start = 0, errstr_end = 0;
            /* XXX: potential optimization: format common prefixes only once */
            if (log_conn_info) {
                /* once-per-connection info */
                if (line_number == 0) {
                    lines = (apr_array_header_t **)sconf->error_log_conn->elts;
                    info.r = NULL;
                    info.rmain = NULL;
                    info.level = -1;
                    info.module_index = APLOG_NO_MODULE;
                }
    
                log_format = lines[line_number++];
    
                if (line_number == sconf->error_log_conn->nelts) {
                    /* this is the last line of once-per-connection info */
                    line_number = 0;
                    log_conn_info = 0;
                }
            }
            else if (log_req_info) {
                /* once-per-request info */
                if (line_number == 0) {
                    lines = (apr_array_header_t **)sconf->error_log_req->elts;
                    info.r = rmain;
                    info.rmain = rmain;
                    info.level = -1;
                    info.module_index = APLOG_NO_MODULE;
                }
    
                log_format = lines[line_number++];
    
                if (line_number == sconf->error_log_req->nelts) {
                    /* this is the last line of once-per-request info */
                    line_number = 0;
                    log_req_info = 0;
                }
            }
            else {
                /* the actual error message */
                info.r            = r;
                info.rmain        = rmain;
                info.level        = level_and_mask;
                info.module_index = module_index;
                info.file         = file;
                info.line         = line;
                info.status       = status;
                log_format = sconf ? sconf->error_log_format : NULL;
                done = 1;
            }
    
            /*
             * prepare and log one line
             */
    
            if (log_format && !info.startup) {
                len += do_errorlog_format(log_format, &info, errstr + len,
                                          MAX_STRING_LEN - len,
                                          &errstr_start, &errstr_end, fmt, args);
            }
            else {
                len += do_errorlog_default(&info, errstr + len, MAX_STRING_LEN - len,
                                           &errstr_start, &errstr_end, fmt, args);
            }
    
            if (!*errstr) {
                /*
                 * Don't log empty lines. This can happen with once-per-conn/req
                 * info if an item with AP_ERRORLOG_FLAG_REQUIRED is NULL.
                 */
                continue;
            }
            write_logline(errstr, len, logf, level_and_mask);
    
            if (done) {
                /*
                 * We don't call the error_log hook for per-request/per-conn
                 * lines, and we only pass the actual log message, not the
                 * prefix and suffix.
                 */
                errstr[errstr_end] = '\0';
                ap_run_error_log(&info, errstr + errstr_start);
            }
    
            *errstr = '\0';
        }
    }
    
    /* For internal calls to log_error_core with self-composed arg lists */
    static void log_error_va_glue(const char *file, int line, int module_index,
                                  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;
    
        va_start(args, fmt);
        log_error_core(file, line, module_index, level, status, s, c, r, pool,
                       fmt, args);
        va_end(args);
    }
    
    AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index,
                                   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, module_index, level, status, s, NULL, NULL,
                       NULL, fmt, args);
        va_end(args);
    }
    
    AP_DECLARE(void) ap_log_perror_(const char *file, int line, int module_index,
                                    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, module_index, level, status, NULL, NULL, NULL,
                       p, fmt, args);
        va_end(args);
    }
    
    AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
                                    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, module_index, 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_cserror_(const char *file, int line, int module_index,
                                     int level, apr_status_t status,
                                     const conn_rec *c, const server_rec *s,
                                     const char *fmt, ...)
    {
        va_list args;
    
        va_start(args, fmt);
        log_error_core(file, line, module_index, level, status, s, c,
                       NULL, NULL, fmt, args);
        va_end(args);
    }
    
    AP_DECLARE(void) ap_log_cerror_(const char *file, int line, int module_index,
                                    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, module_index, level, status, c->base_server, c,
                       NULL, NULL, fmt, args);
        va_end(args);
    }
    
    #define BYTES_LOGGED_PER_LINE 16
    #define LOG_BYTES_BUFFER_SIZE (BYTES_LOGGED_PER_LINE * 3 + 2)
    
    static void fmt_data(unsigned char *buf, const void *vdata, apr_size_t len, apr_size_t *off)
    {
        const unsigned char *data = (const unsigned char *)vdata;
        unsigned char *chars;
        unsigned char *hex;
        apr_size_t this_time = 0;
    
        memset(buf, ' ', LOG_BYTES_BUFFER_SIZE - 1);
        buf[LOG_BYTES_BUFFER_SIZE - 1] = '\0';
        
        chars = buf; /* start character dump here */
        hex   = buf + BYTES_LOGGED_PER_LINE + 1; /* start hex dump here */
        while (*off < len && this_time < BYTES_LOGGED_PER_LINE) {
            unsigned char c = data[*off];
    
            if (apr_isprint(c)
                && c != '\\') {  /* backslash will be escaped later, which throws
                                  * off the formatting
                                  */
                *chars = c;
            }
            else {
                *chars = '.';
            }
    
            if ((c >> 4) >= 10) {
                *hex = 'a' + ((c >> 4) - 10);
            }
            else {
                *hex = '0' + (c >> 4);
            }
    
            if ((c & 0x0F) >= 10) {
                *(hex + 1) = 'a' + ((c & 0x0F) - 10);
            }
            else {
                *(hex + 1) = '0' + (c & 0x0F);
            }
    
            chars += 1;
            hex += 2;
            *off += 1;
            ++this_time;
        }
    }
    
    static void log_data_core(const char *file, int line, int module_index,
                              int level, const server_rec *s,
                              const conn_rec *c, const request_rec *r,
                              const char *label, const void *data, apr_size_t len,
                              unsigned int flags)
    {
        unsigned char buf[LOG_BYTES_BUFFER_SIZE];
        apr_size_t off;
        char prefix[20];
    
        if (!(flags & AP_LOG_DATA_SHOW_OFFSET)) {
            prefix[0] = '\0';
        }
    
        if (len > 0xffff) { /* bug in caller? */
            len = 0xffff;
        }
    
        if (label) {
            log_error_va_glue(file, line, module_index, level, APR_SUCCESS, s,
                              c, r, NULL, "%s (%" APR_SIZE_T_FMT " bytes)",
                              label, len);
        }
    
        off = 0;
        while (off < len) {
            if (flags & AP_LOG_DATA_SHOW_OFFSET) {
                apr_snprintf(prefix, sizeof prefix, "%04x: ", (unsigned int)off);
            }
            fmt_data(buf, data, len, &off);
            log_error_va_glue(file, line, module_index, level, APR_SUCCESS, s,
                              c, r, NULL, "%s%s", prefix, buf);
        }
    }
    
    AP_DECLARE(void) ap_log_data_(const char *file, int line, 
                                  int module_index, int level,
                                  const server_rec *s, const char *label,
                                  const void *data, apr_size_t len,
                                  unsigned int flags)
    {
        log_data_core(file, line, module_index, level, s, NULL, NULL, label,
                      data, len, flags);
    }
    
    AP_DECLARE(void) ap_log_rdata_(const char *file, int line,
                                   int module_index, int level,
                                   const request_rec *r, const char *label,
                                   const void *data, apr_size_t len,
                                   unsigned int flags)
    {
        log_data_core(file, line, module_index, level, r->server, NULL, r, label,
                      data, len, flags);
    }
    
    AP_DECLARE(void) ap_log_cdata_(const char *file, int line,
                                   int module_index, int level,
                                   const conn_rec *c, const char *label,
                                   const void *data, apr_size_t len,
                                   unsigned int flags)
    {
        log_data_core(file, line, module_index, level, c->base_server, c, NULL,
                      label, data, len, flags);
    }
    
    AP_DECLARE(void) ap_log_csdata_(const char *file, int line, int module_index,
                                    int level, const conn_rec *c, const server_rec *s,
                                    const char *label, const void *data,
                                    apr_size_t len, unsigned int flags)
    {
        log_data_core(file, line, module_index, level, s, c, NULL, label, data,
                      len, flags);
    }
    
    AP_DECLARE(void) ap_log_command_line(apr_pool_t *plog, server_rec *s)
    {
        int i;
        process_rec *process = s->process;
        char *result;
        int len_needed = 0;
    
        /* Piece together the command line from the pieces
         * in process->argv, with spaces in between.
         */
        for (i = 0; i < process->argc; i++) {
            len_needed += strlen(process->argv[i]) + 1;
        }
    
        result = (char *) apr_palloc(plog, len_needed);
        *result = '\0';
    
        for (i = 0; i < process->argc; i++) {
            strcat(result, process->argv[i]);
            if ((i+1)< process->argc) {
                strcat(result, " ");
            }
        }
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(00094)
                     "Command line: '%s'", result);
    }
    
    /* grab bag function to log commonly logged and shared info */
    AP_DECLARE(void) ap_log_mpm_common(server_rec *s)
    {
        ap_log_error(APLOG_MARK, APLOG_DEBUG , 0, s, APLOGNO(02639)
                     "Using SO_REUSEPORT: %s (%d)",
                     ap_have_so_reuseport ? "yes" : "no",
                     ap_num_listen_buckets);
    }
    
    AP_DECLARE(void) ap_remove_pid(apr_pool_t *p, const char *rel_fname)
    {
        apr_status_t rv;
        const char *fname = ap_server_root_relative(p, rel_fname);
    
        if (fname != NULL) {
            rv = apr_file_remove(fname, p);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00095)
                             "failed to remove PID file %s", fname);
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00096)
                             "removed PID file %s (pid=%" APR_PID_T_FMT ")",
                             fname, getpid());
            }
        }
    }
    
    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;
        char *temp_fname;
        apr_fileperms_t perms;
        char pidstr[64];
    
        if (!filename) {
            return;
        }
    
        fname = ap_server_root_relative(p, filename);
        if (!fname) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, APR_EBADPATH,
                         ap_server_conf, APLOGNO(00097) "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, APLOGNO(00098)
                          "pid file %s overwritten -- Unclean "
                          "shutdown of previous Apache run?",
                          fname);
        }
    
        temp_fname = apr_pstrcat(p, fname, ".XXXXXX", NULL);
        rv = apr_file_mktemp(&pid_file, temp_fname,
                             APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE, p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00099)
                         "could not create %s", temp_fname);
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00100)
                         "%s: could not log pid to file %s",
                         ap_server_argv0, fname);
            exit(1);
        }
    
        apr_snprintf(pidstr, sizeof pidstr, "%" APR_PID_T_FMT APR_EOL_STR, mypid);
    
        perms = APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD;
        if (((rv = apr_file_perms_set(temp_fname, perms)) != APR_SUCCESS && rv != APR_ENOTIMPL)
            || (rv = apr_file_write_full(pid_file, pidstr, strlen(pidstr), NULL)) != APR_SUCCESS
            || (rv = apr_file_close(pid_file)) != APR_SUCCESS
            || (rv = apr_file_rename(temp_fname, fname, p)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(10231)
                         "%s: Failed creating pid file %s",
                         ap_server_argv0, temp_fname);
            exit(1);
        }
    
        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,
                         ap_server_conf, APLOGNO(00101) "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, APLOGNO(00102)
                     "[%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_dir_set(procattr, ap_server_root))
             != APR_SUCCESS) ||
            ((status = apr_procattr_cmdtype_set(procattr, pl->cmdtype))
             != APR_SUCCESS) ||
            ((status = apr_procattr_child_in_set(procattr,
                                                 pl->read_fd,
                                                 pl->write_fd))
             != APR_SUCCESS) ||
            ((status = apr_procattr_child_errfn_set(procattr, log_child_errfn))
             != APR_SUCCESS) ||
            ((status = apr_procattr_error_check_set(procattr, 1)) != APR_SUCCESS)) {
            /* Something bad happened, give up and go away. */
            ap_log_error(APLOG_MARK, APLOG_STARTUP, status, ap_server_conf, APLOGNO(00103)
                         "piped_log_spawn: unable to setup child process '%s'",
                         pl->program);
        }
        else {
            char **args;
    
            apr_tokenize_to_argv(pl->program, &args, pl->p);
            procnew = apr_pcalloc(pl->p, sizeof(apr_proc_t));
            status = apr_proc_create(procnew, args[0], (const char * const *) args,
                                     NULL, procattr, pl->p);
    
            if (status == APR_SUCCESS) {
                pl->pid = procnew;
                /* procnew->in was dup2'd from pl->write_fd;
                 * 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,
                                              pl->write_fd, pl->p);
                close_handle_in_child(pl->p, pl->read_fd);
            }
            else {
                /* Something bad happened, give up and go away. */
                ap_log_error(APLOG_MARK, APLOG_STARTUP, status, ap_server_conf, APLOGNO(00104)
                             "unable to start piped log program '%s'",
                             pl->program);
            }
        }
    
        return status;
    }
    
    
    static void piped_log_maintenance(int reason, void *data, apr_wait_t status)
    {
        piped_log *pl = data;
        apr_status_t rv;
        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);
            rv = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state);
            if (rv != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00105)
                             "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, APLOGNO(00106)
                             "piped log program '%s' failed unexpectedly",
                             pl->program);
                if ((rv = piped_log_spawn(pl)) != APR_SUCCESS) {
                    /* what can we do?  This could be the error log we're having
                     * problems opening up... */
                    ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, NULL, APLOGNO(00107)
                                 "piped_log_maintenance: unable to respawn '%s'",
                                 pl->program);
                }
            }
            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(pl->read_fd);
        apr_file_close(pl->write_fd);
        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_ex(apr_pool_t *p,
                                                 const char *program,
                                                 apr_cmdtype_e cmdtype)
    {
        piped_log *pl;
    
        pl = apr_palloc(p, sizeof (*pl));
        pl->p = p;
        pl->program = apr_pstrdup(p, program);
        pl->pid = NULL;
        pl->cmdtype = cmdtype;
        if (apr_file_pipe_create_ex(&pl->read_fd,
                                    &pl->write_fd,
                                    APR_FULL_BLOCK, 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(pl->read_fd);
            apr_file_close(pl->write_fd);
            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(pl->write_fd);
        return APR_SUCCESS;
    }
    
    AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p,
                                                 const char *program,
                                                 apr_cmdtype_e cmdtype)
    {
        piped_log *pl;
        apr_file_t *dummy = NULL;
        int rc;
    
        rc = log_child(p, program, &dummy, cmdtype, 0);
        if (rc != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, ap_server_conf, APLOGNO(00108)
                         "Couldn't start piped log process '%s'.",
                         (program == NULL) ? "NULL" : program);
            return NULL;
        }
    
        pl = apr_palloc(p, sizeof (*pl));
        pl->p = p;
        pl->read_fd = NULL;
        pl->write_fd = dummy;
        apr_pool_cleanup_register(p, pl, piped_log_cleanup, piped_log_cleanup);
    
        return pl;
    }
    
    #endif
    
    AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p,
                                              const char *program)
    {
        apr_cmdtype_e cmdtype = APR_PROGRAM_ENV;
    
        /* In 2.4 favor PROGRAM_ENV, accept "||prog" syntax for compatibility
         * and "|$cmd" to override the default.
         * Any 2.2 backport would continue to favor SHELLCMD_ENV so there
         * accept "||prog" to override, and "|$cmd" to ease conversion.
         */
        if (*program == '|')
            ++program;
        if (*program == '$') {
            cmdtype = APR_SHELLCMD_ENV;
            ++program;
        }
    
        return ap_open_piped_log_ex(p, program, cmdtype);
    }
    
    AP_DECLARE(void) ap_close_piped_log(piped_log *pl)
    {
        apr_pool_cleanup_run(pl->p, pl, piped_log_cleanup);
    }
    
    AP_DECLARE(const char *) ap_parse_log_level(const char *str, int *val)
    {
        const char *err = "Log level keyword must be one of emerg/alert/crit/error/"
                          "warn/notice/info/debug/trace1/.../trace8";
        int i = 0;
    
        if (str == NULL)
            return err;
    
        while (priorities[i].t_name != NULL) {
            if (!strcasecmp(str, priorities[i].t_name)) {
                *val = priorities[i].t_val;
                return NULL;
            }
            i++;
        }
        return err;
    }
    
    AP_IMPLEMENT_HOOK_VOID(error_log,
                           (const ap_errorlog_info *info, const char *errstr),
                           (info, errstr))
    
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, generate_log_id,
                                (const conn_rec *c, const request_rec *r,
                                 const char **id),
                                (c, r, id), DECLINED)
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/main.c��������������������������������������������������������������������������0000664�0001751�0001751�00000071236�14455327713�015244� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_time.h"
    #include "apr_thread_proc.h"
    #include "apr_version.h"
    #include "apu_version.h"
    
    #define APR_WANT_STDIO
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    #include "ap_config.h"
    #include "httpd.h"
    #include "http_main.h"
    #include "http_log.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "mod_core.h"
    #include "http_request.h"
    #include "http_vhost.h"
    #include "apr_uri.h"
    #include "util_ebcdic.h"
    #include "ap_mpm.h"
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* 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_description());
        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);
    #if APR_MAJOR_VERSION >= 2
        printf("Server loaded:  APR %s, PCRE %s\n",
               apr_version_string(), ap_pcre_version_string(AP_REG_PCRE_LOADED));
        printf("Compiled using: APR %s, PCRE %s\n",
               APR_VERSION_STRING, ap_pcre_version_string(AP_REG_PCRE_COMPILED));
    #else
        printf("Server loaded:  APR %s, APR-UTIL %s, PCRE %s\n",
               apr_version_string(), apu_version_string(),
               ap_pcre_version_string(AP_REG_PCRE_LOADED));
        printf("Compiled using: APR %s, APR-UTIL %s, PCRE %s\n",
               APR_VERSION_STRING, APU_VERSION_STRING,
               ap_pcre_version_string(AP_REG_PCRE_COMPILED));
    #endif
        /* 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 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
    
        printf(" -D DYNAMIC_MODULE_LIMIT=%ld\n",(long)DYNAMIC_MODULE_LIMIT);
    
    #if APR_CHARSET_EBCDIC
        printf(" -D APR_CHARSET_EBCDIC\n");
    #endif
    
    #ifdef NEED_HASHBANG_EMUL
        printf(" -D NEED_HASHBANG_EMUL\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
    
    #ifdef DEFAULT_PIDLOG
        printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n");
    #endif
    
    #ifdef DEFAULT_SCOREBOARD
        printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\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
    }
    
    #define TASK_SWITCH_SLEEP 10000
    
    static void destroy_and_exit_process(process_rec *process,
                                         int process_exit_value)
    {
        /*
         * Sleep for TASK_SWITCH_SLEEP micro seconds to cause a task switch on
         * OS layer and thus give possibly started piped loggers a chance to
         * process their input. Otherwise it is possible that they get killed
         * by us before they can do so. In this case maybe valuable log messages
         * might get lost.
         */
        apr_sleep(TASK_SWITCH_SLEEP);
        ap_main_state = AP_SQ_MS_EXITING;
        apr_pool_destroy(process->pool); /* and destroy all descendent pools */
        apr_terminate();
        exit(process_exit_value);
    }
    
    /* APR callback invoked if allocation fails. */
    static int abort_on_oom(int retcode)
    {
        ap_abort_on_oom();
        return retcode; /* unreachable, hopefully. */
    }
    
    /* Deregister all hooks when clearing pconf (pre_cleanup).
     * TODO: have a hook to deregister and run them from here?
     *       ap_clear_auth_internal() is already a candidate.
     */
    static apr_status_t deregister_all_hooks(void *unused)
    {
        (void)unused;
        ap_clear_auth_internal();
        apr_hook_deregister_all();
        return APR_SUCCESS;
    }
    
    static void reset_process_pconf(process_rec *process)
    {
        if (process->pconf) {
            apr_pool_clear(process->pconf);
            ap_server_conf = NULL;
        }
        else {
            apr_pool_create(&process->pconf, process->pool);
            apr_pool_tag(process->pconf, "pconf");
        }
        apr_pool_pre_cleanup_register(process->pconf, NULL, deregister_all_hooks);
    }
    
    static process_rec *init_process(int *argc, const char * const * *argv)
    {
        process_rec *process;
        apr_pool_t *cntx;
        apr_status_t stat;
        const char *failed = "apr_app_initialize()";
    
        stat = apr_app_initialize(argc, argv, NULL);
        if (stat == APR_SUCCESS) {
            failed = "apr_pool_create()";
            stat = apr_pool_create(&cntx, NULL);
        }
    
        if (stat != APR_SUCCESS) {
            /* For all intents and purposes, this is impossibly unlikely,
             * but APR doesn't exist yet, we can't use it for reporting
             * these earliest two failures;
             *
             * XXX: Note the apr_ctime() and apr_time_now() calls.  These
             * work, today, against an uninitialized APR, but in the future
             * (if they relied on global pools or mutexes, for example) then
             * the datestamp logic will need to be replaced.
             */
            char ctimebuff[APR_CTIME_LEN];
            apr_ctime(ctimebuff, apr_time_now());
            fprintf(stderr, "[%s] [crit] (%d) %s: %s failed "
                            "to initial context, exiting\n",
                            ctimebuff, stat, (*argv)[0], failed);
            apr_terminate();
            exit(1);
        }
    
        apr_pool_abort_set(abort_on_oom, cntx);
        apr_pool_tag(cntx, "process");
        ap_open_stderr_log(cntx);
    
        /* Now we have initialized apr and our logger, no more
         * exceptional error reporting required for the lifetime
         * of this server process.
         */
    
        process = apr_palloc(cntx, sizeof(process_rec));
        process->pool = cntx;
    
        process->pconf = NULL;
        reset_process_pconf(process);
    
        process->argc = *argc;
        process->argv = *argv;
        process->short_name = apr_filepath_name_get((*argv)[0]);
    
    #if AP_HAS_THREAD_LOCAL
        {
            apr_status_t rv;
            apr_thread_t *thd = NULL;
            if ((rv = ap_thread_main_create(&thd, process->pool))) {
                char ctimebuff[APR_CTIME_LEN];
                apr_ctime(ctimebuff, apr_time_now());
                fprintf(stderr, "[%s] [crit] (%d) %s: failed "
                                "to initialize thread context, exiting\n",
                                ctimebuff, rv, (*argv)[0]);
                apr_terminate();
                exit(1);
            }
        }
    #endif
    
        return process;
    }
    
    static void usage(process_rec *process)
    {
        const char *bin = process->argv[0];
        int pad_len = strlen(bin);
    
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "Usage: %s [-D name] [-d directory] [-f file]", bin);
    
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "       %*s [-C \"directive\"] [-c \"directive\"]", pad_len, " ");
    
    #ifdef WIN32
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "       %*s [-w] [-k start|restart|stop|shutdown] [-n service_name]",
                     pad_len, " ");
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "       %*s [-k install|config|uninstall] [-n service_name]",
                     pad_len, " ");
    #else
    /* XXX not all MPMs support signalling the server in general or graceful-stop
     * in particular
     */
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "       %*s [-k start|restart|graceful|graceful-stop|stop]",
                     pad_len, " ");
    #endif
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "       %*s [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]",
                     pad_len, " ");
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "Options:");
    
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "  -D name            : define a name for use in "
                     "<IfDefine name> 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 and ServerRoot");
        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 vhost settings");
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "  -t -D DUMP_RUN_CFG : show parsed run settings");
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "  -S                 : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG");
        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 -D DUMP_INCLUDES: show all included configuration files");
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "  -t                 : run syntax check for config files");
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "  -T                 : start without DocumentRoot(s) check");
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "  -X                 : debug mode (only one worker, do not detach)");
    
        destroy_and_exit_process(process, 1);
    }
    
    int main(int argc, const char * const argv[])
    {
        char c;
        int showcompile = 0, showdirectives = 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;
        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 *opt_arg;
        APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server;
        int rc = OK;
    
        AP_MONCONTROL(0); /* turn off profiling of startup */
    
        process = init_process(&argc, &argv);
        ap_pglobal = process->pool;
        pconf = process->pconf;
        ap_server_argv0 = process->short_name;
        ap_init_rng(ap_pglobal);
    
        /* Set up the OOM callback in the global pool, so all pools should
         * by default inherit it. */
        apr_pool_abort_set(abort_on_oom, apr_pool_parent_get(process->pool));
    
    #if APR_CHARSET_EBCDIC
        if (ap_init_ebcdic(ap_pglobal) != APR_SUCCESS) {
            destroy_and_exit_process(process, 1);
        }
    #endif
    
        apr_pool_create(&pcommands, ap_pglobal);
        apr_pool_tag(pcommands, "pcommands");
        ap_server_pre_read_config  = apr_array_make(pcommands, 1,
                                                    sizeof(const char *));
        ap_server_post_read_config = apr_array_make(pcommands, 1,
                                                    sizeof(const char *));
        ap_server_config_defines   = apr_array_make(pcommands, 1,
                                                    sizeof(const char *));
    
        error = ap_setup_prelinked_modules(process);
        if (error) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, 0, NULL, APLOGNO(00012)
                         "%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, &opt_arg))
                == APR_SUCCESS) {
            const char **new;
    
            switch (c) {
            case 'c':
                new = (const char **)apr_array_push(ap_server_post_read_config);
                *new = apr_pstrdup(pcommands, opt_arg);
                break;
    
            case 'C':
                new = (const char **)apr_array_push(ap_server_pre_read_config);
                *new = apr_pstrdup(pcommands, opt_arg);
                break;
    
            case 'd':
                def_server_root = opt_arg;
                break;
    
            case 'D':
                new = (const char **)apr_array_push(ap_server_config_defines);
                *new = apr_pstrdup(pcommands, opt_arg);
                /* Setting -D DUMP_VHOSTS should work like setting -S */
                if (strcmp(opt_arg, "DUMP_VHOSTS") == 0)
                    ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                /* Setting -D DUMP_RUN_CFG should work like setting -S */
                else if (strcmp(opt_arg, "DUMP_RUN_CFG") == 0)
                    ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                /* Setting -D DUMP_MODULES is equivalent to setting -M */
                else if (strcmp(opt_arg, "DUMP_MODULES") == 0)
                    ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                /* Setting -D DUMP_INCLUDES is a type of configuration dump */
                else if (strcmp(opt_arg, "DUMP_INCLUDES") == 0)
                    ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                break;
    
            case 'e':
                if (ap_parse_log_level(opt_arg, &ap_default_loglevel) != NULL)
                    usage(process);
                break;
    
            case 'E':
                temp_error_log = apr_pstrdup(process->pool, opt_arg);
                break;
    
            case 'X':
                new = (const char **)apr_array_push(ap_server_config_defines);
                *new = "DEBUG";
                break;
    
            case 'f':
                confname = opt_arg;
                break;
    
            case 'v':
                printf("Server version: %s\n", ap_get_server_description());
                printf("Server built:   %s\n", ap_get_server_built());
                destroy_and_exit_process(process, 0);
    
            case 'l':
                ap_show_modules();
                destroy_and_exit_process(process, 0);
    
            case 'L':
                ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                showdirectives = 1;
                break;
    
            case 't':
                if (ap_run_mode == AP_SQ_RM_UNKNOWN)
                    ap_run_mode = AP_SQ_RM_CONFIG_TEST;
                break;
    
           case 'T':
               ap_document_root_check = 0;
               break;
    
            case 'S':
                ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                new = (const char **)apr_array_push(ap_server_config_defines);
                *new = "DUMP_VHOSTS";
                new = (const char **)apr_array_push(ap_server_config_defines);
                *new = "DUMP_RUN_CFG";
                break;
    
            case 'M':
                ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                new = (const char **)apr_array_push(ap_server_config_defines);
                *new = "DUMP_MODULES";
                break;
    
            case 'V':
                if (strcmp(ap_show_mpm(), "")) { /* MPM built-in? */
                    show_compile_settings();
                    destroy_and_exit_process(process, 0);
                }
                else {
                    showcompile = 1;
                    ap_run_mode = AP_SQ_RM_CONFIG_DUMP;
                }
                break;
    
            case 'h':
            case '?':
                usage(process);
            }
        }
    
        if (ap_run_mode == AP_SQ_RM_UNKNOWN)
            ap_run_mode = AP_SQ_RM_NORMAL;
    
        /* bad cmdline option?  then we die */
        if (rv != APR_EOF || opt->ind < opt->argc) {
            usage(process);
        }
    
        ap_main_state = AP_SQ_MS_CREATE_PRE_CONFIG;
        apr_pool_create(&plog, ap_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);
        }
        ap_server_conf = NULL; /* set early by ap_read_config() for logging */
        if (!ap_read_config(process, ptemp, confname, &ap_conftree)) {
            if (showcompile) {
                /* Well, we tried. Show as much as we can, but exit nonzero to
                 * indicate that something's not right. The cause should have
                 * already been logged. */
                show_compile_settings();
            }
            destroy_and_exit_process(process, 1);
        }
        ap_assert(ap_server_conf != NULL);
        apr_pool_cleanup_register(pconf, &ap_server_conf, ap_pool_cleanup_set_null,
                                  apr_pool_cleanup_null);
    
        if (showcompile) { /* deferred due to dynamically loaded MPM */
            show_compile_settings();
            destroy_and_exit_process(process, 0);
        }
    
        /* sort hooks here to make sure pre_config hooks are sorted properly */
        apr_hook_sort_all();
    
        if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
                         NULL, APLOGNO(00013) "Pre-configuration failed");
            destroy_and_exit_process(process, 1);
        }
    
        rv = ap_process_config_tree(ap_server_conf, ap_conftree,
                                    process->pconf, ptemp);
        if (rv == OK) {
            ap_fixup_virtual_hosts(pconf, ap_server_conf);
            ap_fini_vhost_config(pconf, ap_server_conf);
            /*
             * Sort hooks again because ap_process_config_tree may have add modules
             * and hence hooks. This happens with mod_perl and modules written in
             * perl.
             */
            apr_hook_sort_all();
    
            if (ap_run_check_config(pconf, plog, ptemp, ap_server_conf) != OK) {
                ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
                             NULL, APLOGNO(00014) "Configuration check failed");
                destroy_and_exit_process(process, 1);
            }
    
            if (ap_run_mode != AP_SQ_RM_NORMAL) {
                if (showdirectives) { /* deferred in case of DSOs */
                    ap_show_directives();
                    destroy_and_exit_process(process, 0);
                }
                else {
                    ap_run_test_config(pconf, ap_server_conf);
                    if (ap_run_mode == AP_SQ_RM_CONFIG_TEST)
                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK");
                }
                destroy_and_exit_process(process, 0);
            }
        }
    
        /* If our config failed, deal with that here. */
        if (rv != OK) {
            destroy_and_exit_process(process, 1);
        }
    
        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);
            }
        }
    
        apr_pool_clear(plog);
    
        if ( ap_run_open_logs(pconf, plog, ptemp, ap_server_conf) != OK) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
                         0, NULL, APLOGNO(00015) "Unable to open logs");
            destroy_and_exit_process(process, 1);
        }
    
        if ( ap_run_post_config(pconf, plog, ptemp, ap_server_conf) != OK) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
                         NULL, APLOGNO(00016) "Configuration Failed");
            destroy_and_exit_process(process, 1);
        }
    
        apr_pool_destroy(ptemp);
    
        do {
            ap_main_state = AP_SQ_MS_DESTROY_CONFIG;
            reset_process_pconf(process);
    
            ap_main_state = AP_SQ_MS_CREATE_CONFIG;
            ap_config_generation++;
            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;
            ap_server_conf = NULL; /* set early by ap_read_config() for logging */
            if (!ap_read_config(process, ptemp, confname, &ap_conftree)) {
                destroy_and_exit_process(process, 1);
            }
            ap_assert(ap_server_conf != NULL);
            apr_pool_cleanup_register(pconf, &ap_server_conf,
                                      ap_pool_cleanup_set_null, apr_pool_cleanup_null);
            /* sort hooks here to make sure pre_config hooks are sorted properly */
            apr_hook_sort_all();
    
            if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL,
                             APLOGNO(00017) "Pre-configuration failed, exiting");
                destroy_and_exit_process(process, 1);
            }
    
            if (ap_process_config_tree(ap_server_conf, ap_conftree, process->pconf,
                                       ptemp) != OK) {
                destroy_and_exit_process(process, 1);
            }
            ap_fixup_virtual_hosts(pconf, ap_server_conf);
            ap_fini_vhost_config(pconf, ap_server_conf);
            /*
             * Sort hooks again because ap_process_config_tree may have add modules
             * and hence hooks. This happens with mod_perl and modules written in
             * perl.
             */
            apr_hook_sort_all();
    
            if (ap_run_check_config(pconf, plog, ptemp, ap_server_conf) != OK) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL,
                             APLOGNO(00018) "Configuration check failed, exiting");
                destroy_and_exit_process(process, 1);
            }
    
            apr_pool_clear(plog);
            if (ap_run_open_logs(pconf, plog, ptemp, ap_server_conf) != OK) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL,
                             APLOGNO(00019) "Unable to open logs, exiting");
                destroy_and_exit_process(process, 1);
            }
    
            if (ap_run_post_config(pconf, plog, ptemp, ap_server_conf) != OK) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL,
                             APLOGNO(00020) "Configuration Failed, exiting");
                destroy_and_exit_process(process, 1);
            }
    
            apr_pool_destroy(ptemp);
            apr_pool_lock(pconf, 1);
    
            ap_run_optional_fn_retrieve();
    
            ap_main_state = AP_SQ_MS_RUN_MPM;
            rc = ap_run_mpm(pconf, plog, ap_server_conf);
    
            apr_pool_lock(pconf, 0);
    
        } while (rc == OK);
    
        if (rc == DONE) {
            rc = OK;
        }
        else if (rc != OK) {
            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02818)
                         "MPM run failed, exiting");
        }
        destroy_and_exit_process(process, rc);
    
        /* NOTREACHED */
        return !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 *ap_suck_in_APR(void);
    const void *ap_suck_in_APR(void)
    {
        extern const void *ap_ugly_hack;
    
        return ap_ugly_hack;
    }
    #endif
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_xml.c����������������������������������������������������������������������0000664�0001751�0001751�00000010327�14211415526�016135� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
    
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    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) {
                result = ap_map_http_request_error(status, HTTP_BAD_REQUEST);
                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 (total_read > limit_xml_body) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00539)
                                  "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, APLOGNO(00540)
                          "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, APLOGNO(00541)
                      "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;
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/vhost.c�������������������������������������������������������������������������0000664�0001751�0001751�00000120617�14636263311�015453� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  vhost.c
     * @brief functions pertaining to virtual host addresses
     *        (configuration and run-time)
     */
    
    #include "apr.h"
    #include "apr_strings.h"
    #include "apr_lib.h"
    #include "apr_version.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_vhost.h"
    #include "http_protocol.h"
    #include "http_core.h"
    #include "http_main.h"
    
    #if APR_HAVE_ARPA_INET_H
    #include <arpa/inet.h>
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    /*
     * 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 */
        name_chain *initialnames;   /* no runtime use, temporary storage of first
                                     * NVH'es names */
    };
    
    /* 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;
    
    /* whether a config error was seen */
    static int config_error = 0;
    
    /* config check function */
    static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
                                  apr_pool_t *ptemp, server_rec *s);
    
    /*
     * 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;
        ap_hook_check_config(vhost_check_config, NULL, NULL, APR_HOOK_MIDDLE);
    }
    
    
    /*
     * Parses a host of the form <address>[: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;
    
        wlen = strlen(w_);                   /* wlen must be > 0 at this point */
        w = apr_pstrmemdup(p, w_, wlen);
        /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
        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 !APR_VERSION_AT_LEAST(1,7,0)
        if (scope_id) {
            return apr_pstrcat(p,
                               "Scope ID in address '", w,
                               "' not supported with APR " APR_VERSION_STRING,
                               NULL);
        }
    #endif
        if (!port && !wild_port) {
            port = default_port;
        }
    
        if (strcmp(host, "*") == 0 || strcasecmp(host, "_default_") == 0) {
            rv = apr_sockaddr_info_get(&my_addr, NULL, APR_UNSPEC, port, 0, p);
            if (rv) {
                return "Could not determine a wildcard address ('0.0.0.0') -- "
                    "check resolver configuration.";
            }
        }
        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, APLOGNO(00547)
                    "Could not resolve host name %s -- ignoring!", host);
                return NULL;
            }
    #if APR_VERSION_AT_LEAST(1,7,0)
            if (scope_id) {
                rv = apr_sockaddr_zone_set(my_addr, scope_id);
                if (rv) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(10103)
                                 "Could not set scope ID %s for %pI -- ignoring!",
                                 scope_id, my_addr);
                    return NULL;
                }
            }
    #endif
        }
    
        /* 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 <VirtualHost> 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 addresses */
        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;
    }
    
    
    AP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
                                                            void *dummy,
                                                            const char *arg)
    {
        static int warnonce = 0;
        if (++warnonce == 1) {
            ap_log_error(APLOG_MARK, APLOG_NOTICE|APLOG_STARTUP, APR_SUCCESS, NULL, APLOGNO(00548)
                         "NameVirtualHost has no effect and will be removed in the "
                         "next release %s:%d",
                         cmd->directive->filename,
                         cmd->directive->line_num);
        }
    
        return NULL;
    }
    
    
    /* 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),
                               APLOGNO(03235) "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]);
        /* Intentional no APLOGNO */
        /* buf provides APLOGNO */
        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->initialnames = 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 = NULL;
        ipaddr_chain *wild_match = NULL;
    
        /* 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 == sa->port) {
                if (apr_sockaddr_equal(cur, sa)) {
                    return trav;
                }
            }
            if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) {
                if (apr_sockaddr_equal(cur, sa)) {
                    /* don't break, continue looking for an exact match */
                    wild_match = trav;
                }
            }
        }
        return wild_match;
    }
    
    static ipaddr_chain *find_default_server(apr_port_t port)
    {
        server_addr_rec *sar;
        ipaddr_chain *trav = NULL;
        ipaddr_chain *wild_match = NULL;
    
        for (trav = default_list; trav; trav = trav->next) {
            sar = trav->sar;
            if (sar->host_port == port) {
                /* match! */
                return trav;
            }
            if (wild_match == NULL && sar->host_port == 0) {
                /* don't break, continue looking for an exact match */
                wild_match = trav;
            }
        }
        return wild_match;
    }
    
    #if APR_HAVE_IPV6
    #define IS_IN6_ANYADDR(ad) ((ad)->family == APR_INET6                   \
                                && IN6_IS_ADDR_UNSPECIFIED(&(ad)->sa.sin6.sin6_addr))
    #else
    #define IS_IN6_ANYADDR(ad) (0)
    #endif
    
    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 == INADDR_ANY)
            || IS_IN6_ANYADDR(ha)) {
            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);
            if (nc->server->names) {
                apr_array_header_t *names = nc->server->names;
                char **name = (char **)names->elts;
                int i;
                for (i = 0; i < names->nelts; ++i) {
                    if (name[i]) {
                        apr_file_printf(f, "%16s alias %s\n", "", name[i]);
                    }
                }
            }
            if (nc->server->wild_names) {
                apr_array_header_t *names = nc->server->wild_names;
                char **name = (char **)names->elts;
                int i;
                for (i = 0; i < names->nelts; ++i) {
                    if (name[i]) {
                        apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
                    }
                }
            }
        }
    }
    
    static void dump_vhost_config(apr_file_t *f)
    {
        ipaddr_chain *ic;
        int i;
    
        apr_file_printf(f, "VirtualHost configuration:\n");
    
        /* non-wildcard servers */
        for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
            for (ic = iphash_table[i]; ic; ic = ic->next) {
                dump_a_vhost(f, ic);
            }
        }
    
        /* wildcard servers */
        for (ic = default_list; ic; ic = ic->next) {
            dump_a_vhost(f, ic);
        }
    }
    
    
    /*
     * When a second or later virtual host maps to the same IP chain,
     * add the relevant server names to the chain.  Special care is taken
     * to avoid adding ic->names until we're sure there are multiple VH'es.
     */
    static void add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
                                     server_rec *s, server_addr_rec *sar,
                                     ipaddr_chain *ic)
    {
    
       name_chain *nc = new_name_chain(p, s, sar);
       nc->next = ic->names;
    
       /* iterating backwards, so each one we see becomes the current default server */
       ic->server = s;
    
       if (ic->names == NULL) {
           if (ic->initialnames == NULL) {
               /* first pass, set these names aside in case we see another VH.
                * Until then, this looks like an IP-based VH to runtime.
                */
               ic->initialnames = nc;
           }
           else {
               /* second pass through this chain -- this really is an NVH, and we
                * have two sets of names to link in.
                */
               nc->next = ic->initialnames;
               ic->names = nc;
               ic->initialnames = NULL;
           }
       }
       else {
           /* 3rd or more -- just keep stacking the names */
           ic->names = nc;
       }
    }
    
    /* 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];
    
        /* 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 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 occurred 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) {
            server_addr_rec *sar_prev = NULL;
            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 */
                /* XXX: this treats 0.0.0.0 as a "default" server which matches no-exact-match for IPv6 */
                if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
                    ic = find_default_server(sar->host_port);
    
                    if (ic && sar->host_port == ic->sar->host_port) { /* we're a match for an existing "default server"  */
                        if (!sar_prev || memcmp(sar_prev->host_addr->ipaddr_ptr, inaddr_any, sar_prev->host_addr->ipaddr_len)
                                      || sar_prev->host_port != sar->host_port) { 
                            add_name_vhost_config(p, main_s, s, sar, ic);
                        }
                    }
                    else { 
                        /* No default server, or we found a default server but
                        ** exactly one of us is a wildcard port, which means we want
                        ** two ip-based vhosts not an NVH with two names
                        */
                        ic = new_ipaddr_chain(p, s, sar);
                        ic->next = default_list;
                        default_list = ic;
                        add_name_vhost_config(p, main_s, s, sar, ic);
                    }
                    has_default_vhost_addr = 1;
                }
                else {
                    /* see if it matches something we've already got */
                    ic = find_ipaddr(sar->host_addr);
    
                    if (!ic || sar->host_port != ic->sar->host_port) {
                        /* No matching server, or we found a matching server but
                        ** exactly one of us is a wildcard port, which means we want
                        ** two ip-based vhosts not an NVH with two names
                        */
                        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;
                    }
                    add_name_vhost_config(p, main_s, s, sar, ic);
                }
                sar_prev = sar;
            }
    
            /* 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, APLOGNO(00549)
                                     "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");
                    }
                }
            }
        }
    
    #ifdef IPHASH_STATISTICS
        dump_iphash_statistics(main_s);
    #endif
        if (ap_exists_config_define("DUMP_VHOSTS")) {
            apr_file_t *thefile = NULL;
            apr_file_open_stdout(&thefile, p);
            dump_vhost_config(thefile);
        }
    }
    
    static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
                                  apr_pool_t *ptemp, server_rec *s)
    {
        return config_error ? !OK : OK;
    }
    
    /*****************************************************************************
     * run-time vhost matching functions
     */
    
    static apr_status_t fix_hostname_v6_literal(request_rec *r, char *host)
    {
        char *dst;
        int double_colon = 0;
    
        for (dst = host; *dst; dst++) {
            if (apr_isxdigit(*dst)) {
                if (apr_isupper(*dst)) {
                    *dst = apr_tolower(*dst);
                }
            }
            else if (*dst == ':') {
                if (*(dst + 1) == ':') {
                    if (double_colon)
                        return APR_EINVAL;
                    double_colon = 1;
                }
                else if (*(dst + 1) == '.') {
                    return APR_EINVAL;
                }
            }
            else if (*dst == '.') {
                /* For IPv4-mapped IPv6 addresses like ::FFFF:129.144.52.38 */
                if (*(dst + 1) == ':' || *(dst + 1) == '.')
                    return APR_EINVAL;
            }
            else {
                return APR_EINVAL;
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t fix_hostname_non_v6(request_rec *r, char *host)
    {
        char *dst;
    
        for (dst = host; *dst; dst++) {
            if (apr_islower(*dst)) {
                /* leave char unchanged */
            }
            else if (*dst == '.') {
                if (*(dst + 1) == '.') {
                    return APR_EINVAL;
                }
            }
            else if (apr_isupper(*dst)) {
                *dst = apr_tolower(*dst);
            }
            else if (*dst == '/' || *dst == '\\') {
                return APR_EINVAL;
            }
        }
        /* strip trailing gubbins */
        if (dst > host && dst[-1] == '.') {
            dst[-1] = '\0';
        }
        return APR_SUCCESS;
    }
    
    /*
     * If strict mode ever becomes the default, this should be folded into
     * fix_hostname_non_v6()
     */
    static apr_status_t strict_hostname_check(request_rec *r, char *host)
    {
        char *ch;
        int is_dotted_decimal = 1, leading_zeroes = 0, dots = 0;
    
        for (ch = host; *ch; ch++) {
            if (apr_isalpha(*ch) || *ch == '-' || *ch == '_') {
                is_dotted_decimal = 0;
            }
            else if (ch[0] == '.') {
                dots++;
                if (ch[1] == '0' && apr_isdigit(ch[2]))
                    leading_zeroes = 1;
            }
            else if (!apr_isdigit(*ch)) {
               /* also takes care of multiple Host headers by denying commas */
                goto bad;
            }
        }
        if (is_dotted_decimal) {
            if (host[0] == '.' || (host[0] == '0' && apr_isdigit(host[1])))
                leading_zeroes = 1;
            if (leading_zeroes || dots != 3) {
                /* RFC 3986 7.4 */
                goto bad;
            }
        }
        else {
            /* The top-level domain must start with a letter (RFC 1123 2.1) */
            while (ch > host && *ch != '.')
                ch--;
            if (ch[0] == '.' && ch[1] != '\0' && !apr_isalpha(ch[1]))
                goto bad;
        }
        return APR_SUCCESS;
    
    bad:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02415)
                      "[strict] Invalid host name '%s'%s%.6s",
                      host, *ch ? ", problem near: " : "", ch);
        return APR_EINVAL;
    }
    
    /* 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 int fix_hostname(request_rec *r, const char *host_header,
                            unsigned http_conformance)
    {
        const char *src;
        char *host, *scope_id;
        apr_port_t port;
        apr_status_t rv;
        const char *c;
        int is_v6literal = 0;
        int strict = (http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
    
        src = host_header ? host_header : r->hostname;
    
        /* According to RFC 2616, Host header field CAN be blank */
        if (!*src) {
            return is_v6literal;
        }
    
        /* apr_parse_addr_port will interpret a bare integer as a port
         * which is incorrect in this context.  So treat it separately.
         */
        for (c = src; apr_isdigit(*c); ++c);
        if (!*c) {
            /* pure integer */
            if (strict) {
                /* RFC 3986 7.4 */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02416)
                             "[strict] purely numeric host names not allowed: %s",
                             src);
                goto bad_nolog;
            }
            r->hostname = src;
            return is_v6literal;
        }
    
        if (host_header) {
            rv = apr_parse_addr_port(&host, &scope_id, &port, src, r->pool);
            if (rv != APR_SUCCESS || scope_id)
                goto bad;
            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 (host_header[0] == '[')
                is_v6literal = 1;
        }
        else {
            /*
             * Already parsed, surrounding [ ] (if IPv6 literal) and :port have
             * already been removed.
             */
            host = apr_pstrdup(r->pool, r->hostname);
            if (ap_strchr(host, ':') != NULL)
                is_v6literal = 1;
        }
    
        if (is_v6literal) {
            rv = fix_hostname_v6_literal(r, host);
        }
        else {
            rv = fix_hostname_non_v6(r, host);
            if (strict && rv == APR_SUCCESS)
                rv = strict_hostname_check(r, host);
        }
        if (rv != APR_SUCCESS)
            goto bad;
    
        r->hostname = host;
        return is_v6literal;
    
    bad:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00550)
                      "Client sent malformed Host header: %s",
                      src);
    bad_nolog:
        r->status = HTTP_BAD_REQUEST;
        return is_v6literal;
    }
    
    /* 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 <VirtualHost> values */
        /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
         * consider:
         *
         *     NameVirtualHost 10.1.1.1
         *     <VirtualHost 10.1.1.1>
         *     ServerName v1
         *     </VirtualHost>
         *     <VirtualHost 10.1.1.1>
         *     ServerName v2
         *     </VirtualHost>
         *
         * 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);
    }
    
    
    /*
     * Updates r->server from ServerName/ServerAlias. Per the interaction
     * of ip and name-based vhosts, it only looks in the best match from the
     * connection-level ip-based matching.
     * Returns HTTP_BAD_REQUEST if there was no match.
     */
    static int update_server_from_aliases(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 *virthost_s;
        server_rec *last_s;
        name_chain *src;
    
        virthost_s = NULL;
        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;
    
            /* If we still need to do ServerName and ServerAlias checks for this
             * server, do them now.
             */
            if (s != last_s) {
                /* does it match any ServerName or ServerAlias directive? */
                if (matches_aliases(s, host)) {
                    goto found;
                }
            }
    
            /* Fallback: does it match the virthost from the sar? */
            if (!strcasecmp(host, sar->virthost)) {
                /* only the first match is used */
                if (virthost_s == NULL) {
                    virthost_s = s;
                }
            }
    
            last_s = s;
        }
    
        /* If ServerName and ServerAlias check failed, we end up here.  If it
         * matches a VirtualHost, virthost_s is set. Use that as fallback
         */
        if (virthost_s) {
            s = virthost_s;
            goto found;
        }
    
        if (!r->connection->vhost_lookup_data) { 
            if (matches_aliases(r->server, host)) {
                s = r->server;
                goto found;
            }
        }
        return HTTP_BAD_REQUEST;
    
    found:
        /* s is the first matching server, we're done */
        r->server = s;
        return HTTP_OK;
    }
    
    
    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 update_server_from_aliases 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;
            }
        }
    }
    
    static APR_INLINE const char *construct_host_header(request_rec *r,
                                                        int is_v6literal)
    {
        struct iovec iov[5];
        apr_size_t nvec = 0;
        /*
         * We cannot use ap_get_server_name/port here, because we must
         * ignore UseCanonicalName/Port.
         */
        if (is_v6literal) {
            iov[nvec].iov_base = "[";
            iov[nvec].iov_len = 1;
            nvec++;
        }
        iov[nvec].iov_base = (void *)r->hostname;
        iov[nvec].iov_len = strlen(r->hostname);
        nvec++;
        if (is_v6literal) {
            iov[nvec].iov_base = "]";
            iov[nvec].iov_len = 1;
            nvec++;
        }
        if (r->parsed_uri.port_str) {
            iov[nvec].iov_base = ":";
            iov[nvec].iov_len = 1;
            nvec++;
            iov[nvec].iov_base = r->parsed_uri.port_str;
            iov[nvec].iov_len = strlen(r->parsed_uri.port_str);
            nvec++;
        }
        return apr_pstrcatv(r->pool, iov, nvec, NULL);
    }
    
    AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
    {
        ap_update_vhost_from_headers_ex(r, 0);
    }
    
    AP_DECLARE(int) ap_update_vhost_from_headers_ex(request_rec *r, int require_match)
    {
        core_server_config *conf = ap_get_core_module_config(r->server->module_config);
        const char *host_header = apr_table_get(r->headers_in, "Host");
        int is_v6literal = 0;
        int have_hostname_from_url = 0;
        int rc = HTTP_OK;
    
        if (r->hostname) {
            /*
             * If there was a host part in the Request-URI, ignore the 'Host'
             * header.
             */
            have_hostname_from_url = 1;
            is_v6literal = fix_hostname(r, NULL, conf->http_conformance);
        }
        else if (host_header != NULL) {
            is_v6literal = fix_hostname(r, host_header, conf->http_conformance);
        }
        if (!require_match && r->status != HTTP_OK)
            return HTTP_OK;
    
        if (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE) {
            /*
             * If we have both hostname from an absoluteURI and a Host header,
             * we must ignore the Host header (RFC 2616 5.2).
             * To enforce this, we reset the Host header to the value from the
             * request line.
             */
            if (have_hostname_from_url && host_header != NULL) {
                const char *repl = construct_host_header(r, is_v6literal);
                apr_table_setn(r->headers_in, "Host", repl);
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
                              "Replacing host header '%s' with host '%s' given "
                              "in the request uri", host_header, repl);
            }
        }
    
        /* check if we tucked away a name_chain */
        if (r->connection->vhost_lookup_data) {
            if (r->hostname)
                rc = update_server_from_aliases(r);
            else
                check_serverpath(r);
        }
        else if (require_match && r->hostname) { 
            /* check the base server config */
            rc = update_server_from_aliases(r);
        }
        
        return rc;
    }
    
    /**
     * 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;
    }
    �����������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm_unix.c����������������������������������������������������������������������0000664�0001751�0001751�00000100553�14526656145�016152� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 WIN32
    
    #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_core.h"
    #include "http_log.h"
    #include "http_main.h"
    #include "mpm_common.h"
    #include "ap_mpm.h"
    #include "ap_listen.h"
    #include "scoreboard.h"
    #include "util_mutex.h"
    
    #ifdef HAVE_PWD_H
    #include <pwd.h>
    #endif
    #ifdef HAVE_GRP_H
    #include <grp.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    typedef enum {
        DO_NOTHING,
        SEND_SIGTERM,
        SEND_SIGTERM_NOLOG,
        SEND_SIGKILL,
        GIVEUP
    } action_t;
    
    typedef struct extra_process_t {
        struct extra_process_t *next;
        pid_t pid;
        ap_generation_t gen;
    } extra_process_t;
    
    static extra_process_t *extras;
    
    AP_DECLARE(void) ap_register_extra_mpm_process(pid_t pid, ap_generation_t gen)
    {
        extra_process_t *p = (extra_process_t *)ap_malloc(sizeof(extra_process_t));
    
        p->next = extras;
        p->pid = pid;
        p->gen = gen;
        extras = p;
    }
    
    AP_DECLARE(int) ap_unregister_extra_mpm_process(pid_t pid, ap_generation_t *old_gen)
    {
        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;
            }
            *old_gen = cur->gen;
            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;
        apr_exit_why_e why;
        int status;
    
        /* Ensure pid sanity. */
        if (pid < 1) {
            return 1;
        }
    
        proc.pid = pid;
        waitret = apr_proc_wait(&proc, &status, &why, APR_NOWAIT);
        if (waitret != APR_CHILD_NOTDONE) {
            if (waitret == APR_CHILD_DONE)
                ap_process_child_status(&proc, why, status);
            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, APLOGNO(00045)
                         "child process %" APR_PID_T_FMT
                         " still did not exit, "
                         "sending a SIGTERM",
                         pid);
            /* FALLTHROUGH */
        case SEND_SIGTERM_NOLOG:
            kill(pid, SIGTERM);
            break;
    
        case SEND_SIGKILL:
            ap_log_error(APLOG_MARK, APLOG_ERR,
                         0, ap_server_conf, APLOGNO(00046)
                         "child process %" APR_PID_T_FMT
                         " still did not exit, "
                         "sending a SIGKILL",
                         pid);
            kill(pid, SIGKILL);
            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, APLOGNO(00047)
                         "could not make child process %" APR_PID_T_FMT
                         " exit, "
                         "attempting to continue anyway",
                         pid);
            break;
        }
    
        return 0;
    }
    
    AP_DECLARE(void) ap_reclaim_child_processes(int terminate,
                                                ap_reclaim_callback_fn_t *mpm_callback)
    {
        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_NOLOG, 0}, /* skipped if terminate == 0 */
            {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 = terminate ? 1 : 2; /* index of first real action */
    
        ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);
    
        do {
            if (action_table[next_action].action_time > 0) {
                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) {
                process_score *ps = ap_get_scoreboard_process(i);
                pid_t pid = ps->pid;
    
                if (pid == 0) {
                    continue; /* not every scoreboard entry is in use */
                }
    
                if (reclaim_one_pid(pid, action_table[cur_action].action)) {
                    mpm_callback(i, 0, 0);
                }
                else {
                    ++not_dead_yet;
                }
            }
    
            cur_extra = extras;
            while (cur_extra) {
                ap_generation_t old_gen;
                extra_process_t *next = cur_extra->next;
                pid_t pid = cur_extra->pid;
    
                if (reclaim_one_pid(pid, action_table[cur_action].action)) {
                    if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
                        /* cur_extra dangling pointer from here. */
                        mpm_callback(-1, pid, old_gen);
                    }
                    else {
                        AP_DEBUG_ASSERT(1 == 0);
                    }
                }
                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);
    }
    
    AP_DECLARE(void) ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callback)
    {
        int i;
        extra_process_t *cur_extra;
        int max_daemons;
    
        ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);
    
        /* now see who is done */
        for (i = 0; i < max_daemons; ++i) {
            process_score *ps = ap_get_scoreboard_process(i);
            pid_t pid = ps->pid;
    
            if (pid == 0) {
                continue; /* not every scoreboard entry is in use */
            }
    
            if (reclaim_one_pid(pid, DO_NOTHING)) {
                mpm_callback(i, 0, 0);
            }
        }
    
        cur_extra = extras;
        while (cur_extra) {
            ap_generation_t old_gen;
            extra_process_t *next = cur_extra->next;
            pid_t pid = cur_extra->pid;
    
            if (reclaim_one_pid(pid, DO_NOTHING)) {
                if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
                    /* cur_extra dangling pointer from here. */
                    mpm_callback(-1, pid, old_gen);
                }
                else {
                    AP_DEBUG_ASSERT(1 == 0);
                }
            }
            cur_extra = next;
        }
    }
    
    /* Before sending the signal to the pid this function verifies that
     * the pid is a member of the current process group; either using
     * apr_proc_wait(), where waitpid() guarantees to fail for non-child
     * processes; or by using getpgid() directly, if available. */
    AP_DECLARE(apr_status_t) ap_mpm_safe_kill(pid_t pid, int sig)
    {
    #ifndef HAVE_GETPGID
        apr_proc_t proc;
        apr_status_t rv;
        apr_exit_why_e why;
        int status;
    
        /* Ensure pid sanity */
        if (pid < 1) {
            return APR_EINVAL;
        }
    
        proc.pid = pid;
        rv = apr_proc_wait(&proc, &status, &why, APR_NOWAIT);
        if (rv == APR_CHILD_DONE) {
            /* The child already died - log the termination status if
             * necessary: */
            ap_process_child_status(&proc, why, status);
            return APR_EINVAL;
        }
        else if (rv != APR_CHILD_NOTDONE) {
            /* The child is already dead and reaped, or was a bogus pid -
             * log this either way. */
            ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, ap_server_conf, APLOGNO(00048)
                         "cannot send signal %d to pid %ld (non-child or "
                         "already dead)", sig, (long)pid);
            return APR_EINVAL;
        }
    #else
        pid_t pg;
    
        /* Ensure pid sanity. */
        if (pid < 1) {
            return APR_EINVAL;
        }
    
        pg = getpgid(pid);
        if (pg == -1) {
            /* Process already dead... */
            return errno;
        }
    
        if (pg != getpgrp()) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, APLOGNO(00049)
                         "refusing to send signal %d to pid %ld outside "
                         "process group", sig, (long)pid);
            return APR_EINVAL;
        }
    #endif
    
        return kill(pid, sig) ? errno : APR_SUCCESS;
    }
    
    
    AP_DECLARE(int) ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why,
                                            int status)
    {
        int signum = status;
        const char *sigdesc;
    
        /* 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, APLOGNO(00050)
                             "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)) {
            sigdesc = apr_signal_description_get(signum);
    
            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, APLOGNO(00051)
                                 "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, APLOGNO(00052)
                                 "child pid %ld exit signal %s (%d)",
                                 (long)pid->pid, sigdesc, signum);
                }
            }
        }
        return 0;
    }
    
    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_ex(&((*pod)->pod_in), &((*pod)->pod_out),
                                     APR_WRITE_BLOCK, 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, APLOGNO(00053)
                         "write pipe_of_death");
        }
    
        return rv;
    }
    
    AP_DECLARE(apr_status_t) ap_mpm_podx_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_podx_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 AP_MPM_PODX_RESTART_CHAR:
                    return AP_MPM_PODX_RESTART;
                case AP_MPM_PODX_GRACEFUL_CHAR:
                    return AP_MPM_PODX_GRACEFUL;
            }
        }
        return AP_MPM_PODX_NORESTART;
    }
    
    AP_DECLARE(apr_status_t) ap_mpm_podx_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 podx_signal_internal(ap_pod_t *pod,
                                            ap_podx_restart_t graceful)
    {
        apr_status_t rv;
        apr_size_t one = 1;
        char char_of_death = ' ';
        switch (graceful) {
            case AP_MPM_PODX_RESTART:
                char_of_death = AP_MPM_PODX_RESTART_CHAR;
                break;
            case AP_MPM_PODX_GRACEFUL:
                char_of_death = AP_MPM_PODX_GRACEFUL_CHAR;
                break;
            case AP_MPM_PODX_NORESTART:
                break;
        }
    
        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, APLOGNO(02404)
                         "write pipe_of_death");
        }
        return rv;
    }
    
    AP_DECLARE(apr_status_t) ap_mpm_podx_signal(ap_pod_t * pod,
                                                ap_podx_restart_t graceful)
    {
        return podx_signal_internal(pod, graceful);
    }
    
    AP_DECLARE(void) ap_mpm_podx_killpg(ap_pod_t * pod, int num,
                                        ap_podx_restart_t graceful)
    {
        int i;
        apr_status_t rv = APR_SUCCESS;
    
        for (i = 0; i < num && rv == APR_SUCCESS; i++) {
            rv = podx_signal_internal(pod, graceful);
        }
    }
    
    /* This function connects to the server and sends enough data to
     * ensure the child wakes up and processes a new 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)
    {
        const char *data;
        apr_status_t rv;
        apr_socket_t *sock;
        apr_pool_t *p;
        apr_size_t len;
        ap_listen_rec *lp;
    
        /* 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;
        }
        apr_pool_tag(p, "dummy_connection");
    
        /* If possible, find a listener which is configured for
         * plain-HTTP, not SSL; using an SSL port would either be
         * expensive to do correctly (performing a complete SSL handshake)
         * or cause log spam by doing incorrectly (simply sending EOF). */
        lp = ap_listeners;
        while (lp && lp->protocol && ap_cstr_casecmp(lp->protocol, "http") != 0) {
            lp = lp->next;
        }
        if (!lp) {
            lp = ap_listeners;
        }
    
        rv = apr_socket_create(&sock, lp->bind_addr->family, SOCK_STREAM, 0, p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00054)
                         "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, APLOGNO(00055)
                         "set timeout on socket to connect to listener");
            apr_socket_close(sock);
            apr_pool_destroy(p);
            return rv;
        }
    
        rv = apr_socket_connect(sock, lp->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, APLOGNO(00056)
                         "connect to listener on %pI", lp->bind_addr);
            apr_pool_destroy(p);
            return rv;
        }
    
        if (lp->protocol && ap_cstr_casecmp(lp->protocol, "https") == 0) {
            /* Send a TLS 1.0 close_notify alert.  This is perhaps the
             * "least wrong" way to open and cleanly terminate an SSL
             * connection.  It should "work" without noisy error logs if
             * the server actually expects SSLv3/TLSv1.  With
             * SSLv23_server_method() OpenSSL's SSL_accept() fails
             * ungracefully on receipt of this message, since it requires
             * an 11-byte ClientHello message and this is too short. */
            static const unsigned char tls10_close_notify[7] = {
                '\x15',         /* TLSPlainText.type = Alert (21) */
                '\x03', '\x01', /* TLSPlainText.version = {3, 1} */
                '\x00', '\x02', /* TLSPlainText.length = 2 */
                '\x01',         /* Alert.level = warning (1) */
                '\x00'          /* Alert.description = close_notify (0) */
            };
            data = (const char *)tls10_close_notify;
            len = sizeof(tls10_close_notify);
        }
        else /* ... XXX other request types here? */ {
            /* Create an HTTP request string.  We include a User-Agent so
             * that administrators can track down the cause of the
             * odd-looking requests in their logs.  A complete request is
             * used since kernel-level filtering may require that much
             * data before returning from accept(). */
            data = apr_pstrcat(p, "OPTIONS * HTTP/1.0\r\nUser-Agent: ",
                               ap_get_server_description(),
                               " (internal dummy connection)\r\n\r\n", NULL);
            len = strlen(data);
        }
    
        apr_socket_send(sock, data, &len);
        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)
         */
        /* Recall: we only worry about IDLE child processes here */
        for (i = 0; i < num && rv == APR_SUCCESS; i++) {
            if (ap_scoreboard_image->servers[i][0].status != SERVER_READY ||
                ap_scoreboard_image->servers[i][0].pid == 0) {
                continue;
            }
            rv = dummy_connection(pod);
        }
    }
    
    static const char *dash_k_arg = NULL;
    static const char *dash_k_arg_noarg = "noarg";
    
    static int send_signal(pid_t pid, int sig)
    {
        if (kill(pid, sig) < 0) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP, errno, NULL, APLOGNO(00057)
                         "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;
        const char *status;
    
        *exit_status = 0;
    
        rv = ap_read_pid(pconf, ap_pid_fname, &otherpid);
        if (rv != APR_SUCCESS) {
            if (!APR_STATUS_IS_ENOENT(rv)) {
                ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, NULL, APLOGNO(00058)
                             "Error retrieving pid file %s", ap_pid_fname);
                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00059)
                             "Remove it before continuing if it is corrupted.");
                *exit_status = 1;
                return 1;
            }
            status = "httpd (no pid file) not running";
        }
        else {
            /* With containerization, httpd may get the same PID at each startup,
             * handle it as if it were not running (it obviously can't).
             */
            if (otherpid != getpid() && 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") || dash_k_arg == dash_k_arg_noarg) {
            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, AP_SIG_GRACEFUL);
                return 1;
            }
        }
    
        if (!strcmp(dash_k_arg, "graceful-stop")) {
            if (!running) {
                printf("%s\n", status);
            }
            else {
                *exit_status = send_signal(otherpid, AP_SIG_GRACEFUL_STOP);
            }
            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;
    
        mpm_new_argv = apr_array_make(process->pool, process->argc,
                                      sizeof(const char **));
        *(const char **)apr_array_push(mpm_new_argv) = process->argv[0];
        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") ||
                        !strcmp(optarg, "graceful-stop")) {
                        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 (NULL == dash_k_arg) {
            dash_k_arg = dash_k_arg_noarg;
        }
    
        APR_REGISTER_OPTIONAL_FN(ap_signal_server);
    }
    
    static pid_t parent_pid, my_pid;
    static 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 <VirtualHost>";
        }
    
        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;
    }
    
    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, APLOGNO(00060)
                         "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.
         */
    }
    
    AP_DECLARE(apr_status_t) ap_fatal_signal_child_setup(server_rec *s)
    {
        my_pid = getpid();
        return APR_SUCCESS;
    }
    
    /* We can't call sig_coredump (ap_log_error) once pconf is destroyed, so
     * avoid double faults by restoring each default signal handler on cleanup.
     */
    static apr_status_t fatal_signal_cleanup(void *unused)
    {
        (void)unused;
    
        apr_signal(SIGSEGV, SIG_DFL);
    #ifdef SIGBUS
        apr_signal(SIGBUS, SIG_DFL);
    #endif /* SIGBUS */
    #ifdef SIGABORT
        apr_signal(SIGABORT, SIG_DFL);
    #endif /* SIGABORT */
    #ifdef SIGABRT
        apr_signal(SIGABRT, SIG_DFL);
    #endif /* SIGABRT */
    #ifdef SIGILL
        apr_signal(SIGILL, SIG_DFL);
    #endif /* SIGILL */
    #ifdef SIGFPE
        apr_signal(SIGFPE, SIG_DFL);
    #endif /* SIGFPE */
    
        return APR_SUCCESS;
    }
    
    AP_DECLARE(apr_status_t) ap_fatal_signal_setup(server_rec *s,
                                                   apr_pool_t *in_pconf)
    {
    #ifndef NO_USE_SIGACTION
        struct sigaction sa;
    
        memset(&sa, 0, sizeof sa);
        sigemptyset(&sa.sa_mask);
    
    #if defined(SA_ONESHOT)
        sa.sa_flags = SA_ONESHOT;
    #elif defined(SA_RESETHAND)
        sa.sa_flags = SA_RESETHAND;
    #endif
    
        sa.sa_handler = sig_coredump;
        if (sigaction(SIGSEGV, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00061) "sigaction(SIGSEGV)");
    #ifdef SIGBUS
        if (sigaction(SIGBUS, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00062) "sigaction(SIGBUS)");
    #endif
    #ifdef SIGABORT
        if (sigaction(SIGABORT, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00063) "sigaction(SIGABORT)");
    #endif
    #ifdef SIGABRT
        if (sigaction(SIGABRT, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00064) "sigaction(SIGABRT)");
    #endif
    #ifdef SIGILL
        if (sigaction(SIGILL, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00065) "sigaction(SIGILL)");
    #endif
    #ifdef SIGFPE
        if (sigaction(SIGFPE, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, APLOGNO(00066) "sigaction(SIGFPE)");
    #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 */
    #ifdef SIGFPE
        apr_signal(SIGFPE, sig_coredump);
    #endif /* SIGFPE */
    
    #endif /* NO_USE_SIGACTION */
    
        pconf = in_pconf;
        parent_pid = my_pid = getpid();
        apr_pool_cleanup_register(pconf, NULL, fatal_signal_cleanup,
                                  fatal_signal_cleanup);
    
        return APR_SUCCESS;
    }
    
    #endif /* WIN32 */
    �����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/connection.c��������������������������������������������������������������������0000664�0001751�0001751�00000016116�14152434370�016443� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "ap_config.h"
    #include "httpd.h"
    #include "http_connection.h"
    #include "http_request.h"
    #include "http_protocol.h"
    #include "ap_mpm.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)
                APR_HOOK_LINK(pre_close_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)
    AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_close_connection,(conn_rec *c),(c),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(apr_status_t) ap_shutdown_conn(conn_rec *c, int flush)
    {
        apr_status_t rv;
        apr_bucket_brigade *bb;
        apr_bucket *b;
    
        bb = apr_brigade_create(c->pool, c->bucket_alloc);
    
        if (flush) {
            /* 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);
    
        rv = ap_pass_brigade(c->output_filters, bb);
        apr_brigade_destroy(bb);
        return rv;
    }
    
    AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c)
    {
        (void)ap_shutdown_conn(c, 1);
    }
    
    AP_DECLARE(int) ap_prep_lingering_close(conn_rec *c)
    {
        /* Give protocol handlers one last chance to raise their voice */
        ap_run_pre_close_connection(c);
        
        if (c->sbh) {
            ap_update_child_status(c->sbh, SERVER_CLOSING, NULL);
        }
        return 0;
    }
    
    /* 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://tools.ietf.org/html/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(int) ap_start_lingering_close(conn_rec *c)
    {
        apr_socket_t *csd = ap_get_conn_socket(c);
    
        ap_assert(csd != NULL);
    
        if (ap_prep_lingering_close(c)) {
            return 1;
        }
        
        /* 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);
    
    #ifdef NO_LINGCLOSE
        return 1;
    #else
        /* Shut down the socket for write, which will send a FIN
         * to the peer.
         */
        return (c->aborted || apr_socket_shutdown(csd, APR_SHUTDOWN_WRITE));
    #endif
    }
    
    AP_DECLARE(void) ap_lingering_close(conn_rec *c)
    {
        char dummybuf[512];
        apr_size_t nbytes;
        apr_time_t now, timeup = 0;
        apr_socket_t *csd = ap_get_conn_socket(c);
    
        if (!csd) {
            /* Be safe with third-party modules that:
             *   ap_set_core_module_config(c->conn_config, NULL)
             * to no-op ap_lingering_close().
             */
            c->aborted = 1;
            return;
        }
    
        if (ap_start_lingering_close(c)) {
            apr_socket_close(csd);
            return;
        }
    
        /* Read available data from the client whilst it continues sending
         * it, for a maximum time of MAX_SECS_TO_LINGER.  If the client
         * does not send any data within 2 seconds (a value pulled from
         * Apache 1.3 which seems to work well), give up.
         */
        apr_socket_timeout_set(csd, apr_time_from_sec(SECONDS_TO_LINGER));
        apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
    
        /* The common path here is that the initial apr_socket_recv() call
         * will return 0 bytes read; so that case must avoid the expensive
         * apr_time_now() call and time arithmetic. */
    
        do {
            nbytes = sizeof(dummybuf);
            if (apr_socket_recv(csd, dummybuf, &nbytes) || nbytes == 0)
                break;
    
            now = apr_time_now();
            if (timeup == 0) {
                /*
                 * First time through;
                 * calculate now + 30 seconds (MAX_SECS_TO_LINGER).
                 *
                 * If some module requested a shortened waiting period, only wait for
                 * 2s (SECONDS_TO_LINGER). This is useful for mitigating certain
                 * DoS attacks.
                 */
                if (apr_table_get(c->notes, "short-lingering-close")) {
                    timeup = now + apr_time_from_sec(SECONDS_TO_LINGER);
                }
                else {
                    timeup = now + apr_time_from_sec(MAX_SECS_TO_LINGER);
                }
                continue;
            }
        } while (now < timeup);
    
        apr_socket_close(csd);
    }
    
    AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, void *csd)
    {
        ap_update_vhost_given_ip(c);
    
        ap_pre_connection(c, csd);
    
        if (!c->aborted) {
            ap_run_process_connection(c);
        }
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/ssl.c���������������������������������������������������������������������������0000664�0001751�0001751�00000025240�14116423257�015105� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * ssl.c --- routines for SSL/TLS server infrastructure.
     *
     */
    
    #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"
    
    #include "util_filter.h"
    #include "ap_config.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "http_connection.h"
    #include "http_protocol.h"
    #include "http_request.h"
    #include "http_main.h"
    #include "http_ssl.h"
    #include "http_log.h"           /* For errors detected in basic auth common
                                     * support code... */
    #include "mod_core.h"
    
    
    #if APR_HAVE_STDARG_H
    #include <stdarg.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(ssl_conn_is_ssl)
        APR_HOOK_LINK(ssl_var_lookup)
        APR_HOOK_LINK(ssl_add_cert_files)
        APR_HOOK_LINK(ssl_add_fallback_cert_files)
        APR_HOOK_LINK(ssl_answer_challenge)
        APR_HOOK_LINK(ssl_ocsp_prime_hook)
        APR_HOOK_LINK(ssl_ocsp_get_resp_hook)
        APR_HOOK_LINK(ssl_bind_outgoing)
    )
    
    APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
    static APR_OPTIONAL_FN_TYPE(ssl_is_https) *module_ssl_is_https;
    APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
    static APR_OPTIONAL_FN_TYPE(ssl_proxy_enable) *module_ssl_proxy_enable;
    APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
    static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *module_ssl_engine_disable;
    APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *,
                                                  ap_conf_vector_t *,
                                                  int proxy, int enable));
    static APR_OPTIONAL_FN_TYPE(ssl_engine_set) *module_ssl_engine_set;
    
    
    static int ssl_is_https(conn_rec *c)
    {
        /* Someone retrieved the optional function., not knowing about the
         * new API. We redirect them to what they should have invoked. */
        return ap_ssl_conn_is_ssl(c);
    }
    
    AP_DECLARE(int) ap_ssl_conn_is_ssl(conn_rec *c)
    {
        int r = (ap_run_ssl_conn_is_ssl(c) == OK);
        if (r == 0 && module_ssl_is_https) {
            r = module_ssl_is_https(c);
        }
        return r;
    }
    
    static int ssl_engine_set(conn_rec *c,
                              ap_conf_vector_t *per_dir_config,
                              int proxy, int enable)
    {
        if (proxy) {
            return ap_ssl_bind_outgoing(c, per_dir_config, enable) == OK;
        }
        else if (module_ssl_engine_set) {
            return module_ssl_engine_set(c, per_dir_config, 0, enable);
        }
        else if (enable && module_ssl_proxy_enable) {
            return module_ssl_proxy_enable(c);
        }
        else if (!enable && module_ssl_engine_disable) {
            return module_ssl_engine_disable(c);
        }
        return 0;
    }
    
    static int ssl_proxy_enable(conn_rec *c)
    {
        return ap_ssl_bind_outgoing(c, NULL, 1);
    }
    
    static int ssl_engine_disable(conn_rec *c)
    {
        return ap_ssl_bind_outgoing(c, NULL, 0);
    }
    
    AP_DECLARE(int) ap_ssl_bind_outgoing(conn_rec *c, struct ap_conf_vector_t *dir_conf,
                                         int enable_ssl)
    {
        int rv, enabled = 0;
    
        c->outgoing = 1;
        rv = ap_run_ssl_bind_outgoing(c, dir_conf, enable_ssl);
        enabled = (rv == OK);
        if (enable_ssl && !enabled) {
            /* the hooks did not take over. Is there an old skool optional that will? */
            if (module_ssl_engine_set) {
                enabled = module_ssl_engine_set(c, dir_conf, 1, 1);
            }
            else if (module_ssl_proxy_enable) {
                enabled = module_ssl_proxy_enable(c);
            }
        }
        else {
            /* !enable_ssl || enabled
             * any existing optional funcs need to not enable here */
            if (module_ssl_engine_set) {
                module_ssl_engine_set(c, dir_conf, 1, 0);
            }
            else if (module_ssl_engine_disable) {
                module_ssl_engine_disable(c);
            }
        }
        if (enable_ssl && !enabled) {
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0,
                          c, APLOGNO(01961) " failed to enable ssl support "
                          "[Hint: if using mod_ssl, see SSLProxyEngine]");
            return DECLINED;
        }
        return OK;
    }
    
    AP_DECLARE(int) ap_ssl_has_outgoing_handlers(void)
    {
        apr_array_header_t *hooks = ap_hook_get_ssl_bind_outgoing();
        return (hooks && hooks->nelts > 0)
            || module_ssl_engine_set || module_ssl_proxy_enable;
    }
    
    APR_DECLARE_OPTIONAL_FN(const char *, ssl_var_lookup,
                            (apr_pool_t *p, server_rec *s,
                             conn_rec *c, request_rec *r,
                             const char *name));
    static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *module_ssl_var_lookup;
    
    static const char *ssl_var_lookup(apr_pool_t *p, server_rec *s,
                                      conn_rec *c, request_rec *r,
                                      const char *name)
    {
        /* Someone retrieved the optional function., not knowing about the
         * new API. We redirect them to what they should have invoked. */
        return ap_ssl_var_lookup(p, s, c, r, name);
    }
    
    AP_DECLARE(const char *) ap_ssl_var_lookup(apr_pool_t *p, server_rec *s,
                                               conn_rec *c, request_rec *r,
                                               const char *name)
    {
        const char *val = ap_run_ssl_var_lookup(p, s, c, r, name);
        if (val == NULL && module_ssl_var_lookup) {
            val = module_ssl_var_lookup(p, s, c, r, name);
        }
        return val;
    }
    
    AP_DECLARE(void) ap_setup_ssl_optional_fns(apr_pool_t *pool)
    {
        /* Run as core's very early 'post config' hook, check for any already
         * installed optional functions related to SSL and save them. Install
         * our own instances that invoke the new hooks. */
        APR_OPTIONAL_FN_TYPE(ssl_is_https) *fn_is_https;
        APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *fn_ssl_var_lookup;
    
        fn_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
        module_ssl_is_https = (fn_is_https
            && fn_is_https != ssl_is_https)? fn_is_https : NULL;
        APR_REGISTER_OPTIONAL_FN(ssl_is_https);
    
        fn_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
        module_ssl_var_lookup = (fn_ssl_var_lookup
            && fn_ssl_var_lookup != ssl_var_lookup)? fn_ssl_var_lookup : NULL;
        APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
    
        module_ssl_proxy_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable);
        APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
        module_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
        APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
        module_ssl_engine_set = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_set);
        APR_REGISTER_OPTIONAL_FN(ssl_engine_set);
    }
    
    AP_DECLARE(apr_status_t) ap_ssl_add_cert_files(server_rec *s, apr_pool_t *p,
                                                   apr_array_header_t *cert_files,
                                                   apr_array_header_t *key_files)
    {
        int rv = ap_run_ssl_add_cert_files(s, p, cert_files, key_files);
        return (rv == OK || rv == DECLINED)? APR_SUCCESS : APR_EGENERAL;
    }
    
    AP_DECLARE(apr_status_t) ap_ssl_add_fallback_cert_files(server_rec *s, apr_pool_t *p,
                                                            apr_array_header_t *cert_files,
                                                            apr_array_header_t *key_files)
    {
        int rv = ap_run_ssl_add_fallback_cert_files(s, p, cert_files, key_files);
        return (rv == OK || rv == DECLINED)? APR_SUCCESS : APR_EGENERAL;
    }
    
    AP_DECLARE(int) ap_ssl_answer_challenge(conn_rec *c, const char *server_name,
                                            const char **pcert_pem, const char **pkey_pem)
    {
        return (ap_run_ssl_answer_challenge(c, server_name, pcert_pem, pkey_pem) == OK);
    }
    
    AP_DECLARE(apr_status_t) ap_ssl_ocsp_prime(server_rec *s, apr_pool_t *p,
                                               const char *id, apr_size_t id_len,
                                               const char *pem)
    {
        int rv = ap_run_ssl_ocsp_prime_hook(s, p, id, id_len, pem);
        return rv == OK? APR_SUCCESS : (rv == DECLINED? APR_ENOENT : APR_EGENERAL);
    }
    
    AP_DECLARE(apr_status_t) ap_ssl_ocsp_get_resp(server_rec *s, conn_rec *c,
                                                  const char *id, apr_size_t id_len,
                                                  ap_ssl_ocsp_copy_resp *cb, void *userdata)
    {
        int rv = ap_run_ssl_ocsp_get_resp_hook(s, c, id, id_len, cb, userdata);
        return rv == OK? APR_SUCCESS : (rv == DECLINED? APR_ENOENT : APR_EGENERAL);
    }
    
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_conn_is_ssl,
                                (conn_rec *c), (c), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,ssl_var_lookup,
            (apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name),
            (p, s, c, r, name), NULL)
    AP_IMPLEMENT_HOOK_RUN_ALL(int, ssl_add_cert_files,
            (server_rec *s, apr_pool_t *p,
             apr_array_header_t *cert_files, apr_array_header_t *key_files),
            (s, p, cert_files, key_files), OK, DECLINED)
    AP_IMPLEMENT_HOOK_RUN_ALL(int, ssl_add_fallback_cert_files,
            (server_rec *s, apr_pool_t *p,
             apr_array_header_t *cert_files, apr_array_header_t *key_files),
            (s, p, cert_files, key_files), OK, DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_answer_challenge,
            (conn_rec *c, const char *server_name, const char **pcert_pem, const char **pkey_pem),
            (c, server_name, pcert_pem, pkey_pem), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_ocsp_prime_hook,
            (server_rec *s, apr_pool_t *p, const char *id, apr_size_t id_len, const char *pem),
            (s, p, id, id_len, pem), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_ocsp_get_resp_hook,
             (server_rec *s, conn_rec *c, const char *id, apr_size_t id_len,
              ap_ssl_ocsp_copy_resp *cb, void *userdata),
             (s, c, id, id_len, cb, userdata), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int,ssl_bind_outgoing,(conn_rec *c, ap_conf_vector_t *dir_conf, int require_ssl),
                                (c, dir_conf, require_ssl), DECLINED)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/Makefile.in���������������������������������������������������������������������0000664�0001751�0001751�00000007653�14046725222�016214� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    CLEAN_TARGETS = gen_test_char test_char.h \
    	ApacheCoreOS2.def httpd.exp export_files \
    	exports.c export_vars.h
    
    SUBDIRS = mpm
    
    LTLIBRARY_NAME    = libmain.la
    LTLIBRARY_SOURCES = \
    	config.c log.c main.c vhost.c util.c util_fcgi.c \
    	util_script.c util_md5.c util_cfgtree.c util_ebcdic.c util_time.c \
    	connection.c listen.c util_mutex.c \
    	mpm_common.c mpm_unix.c mpm_fdqueue.c \
    	util_charset.c util_cookies.c util_debug.c util_xml.c \
    	util_filter.c util_pcre.c util_regex.c exports.c \
    	scoreboard.c error_bucket.c protocol.c core.c request.c ssl.c provider.c \
    	eoc_bucket.c eor_bucket.c core_filters.c \
    	util_expr_parse.c util_expr_scan.c util_expr_eval.c
    
    LTLIBRARY_DEPENDENCIES = test_char.h
    
    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
    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)
    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:
    	( for dir in $(EXPORT_DIRS); do \
    	      ls $$dir/*.h ; \
    	  done; \
    	  echo "$(top_srcdir)/server/mpm_fdqueue.h"; \
    	  for dir in $(EXPORT_DIRS_APR); do \
    	      ls $$dir/ap[ru].h $$dir/ap[ru]_*.h 2>/dev/null; \
    	  done; \
    	) | sed -e s,//,/,g | sort -u > $@
    
    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' >> $@
    
    
    #   developer stuff
    #   (we really don't expect end users to use these targets!)
    #
    util_expr_scan.c util_expr_parse.c util_expr_parse.h: util_expr_scan.l util_expr_parse.y
    	bison -pap_expr_yy --defines=$(builddir)/util_expr_parse.h \
    	    -o $(builddir)/util_expr_parse.c $(srcdir)/util_expr_parse.y
    	flex -Pap_expr_yy -o $(builddir)/util_expr_scan.c $(srcdir)/util_expr_scan.l
    	set -e ; \
    	for f in util_expr_scan.c util_expr_parse.c util_expr_parse.h ; do \
    		sed -e "s|\"$(builddir)/|\"|g" < $(builddir)/$$f > \
    			$(builddir)/$$f.$$$$ && \
    		mv $(builddir)/$$f.$$$$ $(builddir)/$$f ; \
    	done
    	# work around flex bug
    	# http://sourceforge.net/tracker/?func=detail&aid=3029024&group_id=97492&atid=618177
    	perl -0777 -p -i -e 's,\n(void|int) ap_expr_yy[gs]et_column[^\n]+\)\n.*?\n\},,gs' \
    		$(builddir)/util_expr_scan.c
    �������������������������������������������������������������������������������������httpd-2.4.64/server/eor_bucket.c��������������������������������������������������������������������0000664�0001751�0001751�00000007012�13500427330�016413� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_request.h"
    #include "http_protocol.h"
    #include "scoreboard.h"
    
    typedef struct {
        apr_bucket_refcount refcount;
        request_rec *data;
    } ap_bucket_eor;
    
    static apr_status_t eor_bucket_cleanup(void *data)
    {
        request_rec **rp = data;
    
        if (*rp) {
            request_rec *r = *rp;
            /*
             * If eor_bucket_destroy is called after us, this prevents
             * eor_bucket_destroy from trying to destroy the pool again.
             */
            *rp = NULL;
            /* Update child status and log the transaction */
            ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r);
            ap_run_log_transaction(r);
            if (ap_extended_status) {
                ap_increment_counts(r->connection->sbh, r);
            }
        }
        return APR_SUCCESS;
    }
    
    static apr_status_t eor_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_eor_make(apr_bucket *b, request_rec *r)
    {
        ap_bucket_eor *h;
    
        h = apr_bucket_alloc(sizeof(*h), b->list);
        h->data = r;
    
        b = apr_bucket_shared_make(b, h, 0, 0);
        b->type = &ap_bucket_type_eor;
        return b;
    }
    
    AP_DECLARE(apr_bucket *) ap_bucket_eor_create(apr_bucket_alloc_t *list,
                                                  request_rec *r)
    {
        apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
    
        APR_BUCKET_INIT(b);
        b->free = apr_bucket_free;
        b->list = list;
        b = ap_bucket_eor_make(b, r);
        if (r) {
            ap_bucket_eor *h = b->data;
            /*
             * Register a cleanup for the request pool as the eor bucket could
             * have been allocated from a different pool then the request pool
             * e.g. the parent pool of the request pool. In this case
             * eor_bucket_destroy might be called at a point of time when the
             * request pool had been already destroyed.
             * We need to use a pre-cleanup here because a module may create a
             * sub-pool which is still needed during the log_transaction hook.
             */
            apr_pool_pre_cleanup_register(r->pool, &h->data, eor_bucket_cleanup);
        }
        return b;
    }
    
    static void eor_bucket_destroy(void *data)
    {
        ap_bucket_eor *h = data;
    
        if (apr_bucket_shared_destroy(h)) {
            request_rec *r = h->data;
            if (r) {
                /* eor_bucket_cleanup will be called when the pool gets destroyed */
                apr_pool_destroy(r->pool);
            }
            apr_bucket_free(h);
        }
    }
    
    AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_eor = {
        "EOR", 5, APR_BUCKET_METADATA,
        eor_bucket_destroy,
        eor_bucket_read,
        apr_bucket_setaside_noop,
        apr_bucket_split_notimpl,
        apr_bucket_shared_copy
    };
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util.c��������������������������������������������������������������������������0000664�0001751�0001751�00000333251�14637026057�015272� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <unistd.h>
    #endif
    #if APR_HAVE_PROCESS_H
    #include <process.h>            /* for getpid() on Win32 */
    #endif
    #if APR_HAVE_NETDB_H
    #include <netdb.h>              /* for gethostbyname() */
    #endif
    
    #include "ap_config.h"
    #include "apr_base64.h"
    #include "apr_fnmatch.h"
    #include "httpd.h"
    #include "http_main.h"
    #include "http_log.h"
    #include "http_protocol.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "util_ebcdic.h"
    #include "util_varbuf.h"
    
    #ifdef HAVE_PWD_H
    #include <pwd.h>
    #endif
    #ifdef HAVE_GRP_H
    #include <grp.h>
    #endif
    #ifdef HAVE_SYS_LOADAVG_H
    #include <sys/loadavg.h>
    #endif
    
    #include "ap_mpm.h"
    
    /* 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 know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    /* maximum nesting level for config directories */
    #ifndef AP_MAX_FNMATCH_DIR_DEPTH
    #define AP_MAX_FNMATCH_DIR_DEPTH (128)
    #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_pstrmemdup(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)
    {
        apr_size_t x, y;
    
        for (x = 0, y = 0; expected[y]; ++y, ++x) {
            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 (!str[x])
                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)
    {
        apr_size_t 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)
    {
        for (; *str; str++)
            if ((*str == '*') || (*str == '?'))
                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);
        int err = ap_regcomp(preg, pattern, cflags);
        if (err) {
            if (err == AP_REG_ESPACE)
                ap_abort_on_oom();
            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.
     *
     * nmatch must be <=AP_MAX_REG_MATCH (10).
     *
     * input should be the string with the $-expressions, source should be the
     * string that was matched against.
     *
     * It returns the substituted string, or NULL if a vbuf is used.
     * On errors, returns the orig string.
     *
     * Parts of this code are based on Henry Spencer's regsub(), from his
     * AT&T V8 regexp package.
     */
    
    static apr_status_t regsub_core(apr_pool_t *p, char **result,
                                    struct ap_varbuf *vb, const char *input,
                                    const char *source, apr_size_t nmatch,
                                    ap_regmatch_t pmatch[], apr_size_t maxlen)
    {
        const char *src = input;
        char *dst;
        char c;
        apr_size_t no;
        apr_size_t len = 0;
    
        AP_DEBUG_ASSERT((result && p && !vb) || (vb && !p && !result));
        if (!source || nmatch>AP_MAX_REG_MATCH)
            return APR_EINVAL;
        if (!nmatch) {
            len = strlen(src);
            if (maxlen > 0 && len >= maxlen)
                return APR_ENOMEM;
            if (!vb) {
                *result = apr_pstrmemdup(p, src, len);
                return APR_SUCCESS;
            }
            else {
                ap_varbuf_strmemcat(vb, src, len);
                return APR_SUCCESS;
            }
        }
    
        /* First pass, find the size */
        while ((c = *src++) != '\0') {
            if (c == '$' && apr_isdigit(*src))
                no = *src++ - '0';
            else
                no = AP_MAX_REG_MATCH;
    
            if (no >= AP_MAX_REG_MATCH) {  /* Ordinary character. */
                if (c == '\\' && *src)
                    src++;
                len++;
            }
            else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) {
                if (APR_SIZE_MAX - len <= pmatch[no].rm_eo - pmatch[no].rm_so)
                    return APR_ENOMEM;
                len += pmatch[no].rm_eo - pmatch[no].rm_so;
            }
    
        }
    
        if (len >= maxlen && maxlen > 0)
            return APR_ENOMEM;
    
        if (!vb) {
            *result = dst = apr_palloc(p, len + 1);
        }
        else {
            if (vb->strlen == AP_VARBUF_UNKNOWN)
                vb->strlen = strlen(vb->buf);
            ap_varbuf_grow(vb, vb->strlen + len);
            dst = vb->buf + vb->strlen;
            vb->strlen += len;
        }
    
        /* Now actually fill in the string */
    
        src = input;
    
        while ((c = *src++) != '\0') {
            if (c == '$' && apr_isdigit(*src))
                no = *src++ - '0';
            else
                no = AP_MAX_REG_MATCH;
    
            if (no >= AP_MAX_REG_MATCH) {  /* Ordinary character. */
                if (c == '\\' && *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 APR_SUCCESS;
    }
    
    #ifndef AP_PREGSUB_MAXLEN
    #define AP_PREGSUB_MAXLEN   (HUGE_STRING_LEN * 8)
    #endif
    AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input,
                                  const char *source, apr_size_t nmatch,
                                  ap_regmatch_t pmatch[])
    {
        char *result;
        apr_status_t rc = regsub_core(p, &result, NULL, input, source, nmatch,
                                      pmatch, AP_PREGSUB_MAXLEN);
        if (rc != APR_SUCCESS)
            result = NULL;
        return result;
    }
    
    AP_DECLARE(apr_status_t) ap_pregsub_ex(apr_pool_t *p, char **result,
                                           const char *input, const char *source,
                                           apr_size_t nmatch, ap_regmatch_t pmatch[],
                                           apr_size_t maxlen)
    {
        apr_status_t rc = regsub_core(p, result, NULL, input, source, nmatch,
                                      pmatch, maxlen);
        if (rc != APR_SUCCESS)
            *result = NULL;
        return rc;
    }
    
    /* Forward declare */
    static char x2c(const char *what);
    
    #define IS_SLASH_OR_NUL(s) (s == '\0' || AP_IS_SLASH(s))
    
    /*
     * Inspired by mod_jk's jk_servlet_normalize().
     */
    AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags)
    {
        int ret = 1;
        apr_size_t l = 1, w = 1, n;
        int decode_unreserved = (flags & AP_NORMALIZE_DECODE_UNRESERVED) != 0;
        int merge_slashes = (flags & AP_NORMALIZE_MERGE_SLASHES) != 0;
    
        if (!AP_IS_SLASH(path[0])) {
            /* Besides "OPTIONS *", a request-target should start with '/'
             * per RFC 7230 section 5.3, so anything else is invalid.
             */
            if (path[0] == '*' && path[1] == '\0') {
                return 1;
            }
            /* However, AP_NORMALIZE_ALLOW_RELATIVE can be used to bypass
             * this restriction (e.g. for subrequest file lookups).
             */
            if (!(flags & AP_NORMALIZE_ALLOW_RELATIVE) || path[0] == '\0') {
                return 0;
            }
    
            l = w = 0;
        }
    
        while (path[l] != '\0') {
            /* RFC-3986 section 2.3:
             *  For consistency, percent-encoded octets in the ranges of
             *  ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D),
             *  period (%2E), underscore (%5F), or tilde (%7E) should [...]
             *  be decoded to their corresponding unreserved characters by
             *  URI normalizers.
             */
            if (decode_unreserved && path[l] == '%') {
                if (apr_isxdigit(path[l + 1]) && apr_isxdigit(path[l + 2])) {
                    const char c = x2c(&path[l + 1]);
                    if (TEST_CHAR(c, T_URI_UNRESERVED)) {
                        /* Replace last char and fall through as the current
                         * read position */
                        l += 2;
                        path[l] = c;
                    }
                }
                else {
                    /* Invalid encoding */
                    ret = 0;
                }
            }
    
            if (w == 0 || AP_IS_SLASH(path[w - 1])) {
                /* Collapse ///// sequences to / */
                if (merge_slashes && AP_IS_SLASH(path[l])) {
                    do {
                        l++;
                    } while (AP_IS_SLASH(path[l]));
                    continue;
                }
    
                if (path[l] == '.') {
                    /* Remove /./ segments */
                    if (IS_SLASH_OR_NUL(path[l + 1])) {
                        l++;
                        if (path[l]) {
                            l++;
                        }
                        continue;
                    }
    
                    /* Remove /xx/../ segments (or /xx/.%2e/ when
                     * AP_NORMALIZE_DECODE_UNRESERVED is set since we
                     * decoded only the first dot above).
                     */
                    n = l + 1;
                    if ((path[n] == '.' || (decode_unreserved
                                            && path[n] == '%'
                                            && path[++n] == '2'
                                            && (path[++n] == 'e'
                                                || path[n] == 'E')))
                            && IS_SLASH_OR_NUL(path[n + 1])) {
                        /* Wind w back to remove the previous segment */
                        if (w > 1) {
                            do {
                                w--;
                            } while (w && !AP_IS_SLASH(path[w - 1]));
                        }
                        else {
                            /* Already at root, ignore and return a failure
                             * if asked to.
                             */
                            if (flags & AP_NORMALIZE_NOT_ABOVE_ROOT) {
                                ret = 0;
                            }
                        }
    
                        /* Move l forward to the next segment */
                        l = n + 1;
                        if (path[l]) {
                            l++;
                        }
                        continue;
                    }
                }
            }
    
            path[w++] = path[l++];
        }
        path[w] = '\0';
    
        return ret;
    }
    
    /*
     * Parse .. so we don't compromise security
     */
    AP_DECLARE(void) ap_getparents(char *name)
    {
        if (!ap_normalize_path(name, AP_NORMALIZE_NOT_ABOVE_ROOT |
                                     AP_NORMALIZE_ALLOW_RELATIVE)) {
            name[0] = '\0';
        }
    }
    
    AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path)
    {
    
        char *d, *s;
    
        if (!*name) {
            return;
        }
    
        s = d = name;
    
    #ifdef HAVE_UNC_PATHS
        /* Check for UNC names.  Leave leading two slashes. */
        if (is_fs_path && s[0] == '/' && s[1] == '/')
            *d++ = *s++;
    #endif
    
        while (*s) {
            if ((*d++ = *s) == '/') {
                do {
                    ++s;
                } while (*s == '/');
            }
            else {
                ++s;
            }
        }
        *d = '\0';
    }
    
    AP_DECLARE(void) ap_no2slash(char *name)
    {
        ap_no2slash_ex(name, 1);
    }
    
    /*
     * 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 ap_directory_walk in server/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_pstrmemdup(p, s, l);
    
        return (d);
    }
    
    
    AP_DECLARE(int) ap_count_dirs(const char *path)
    {
        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 = apr_pstrmemdup(atrans, *line, len);
    
        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 = apr_pstrmemdup(atrans, *line, len);
    
        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) {
            apr_size_t len = strlen(*line);
            res = apr_pstrmemdup(atrans, *line, len);
            *line += len;
            return res;
        }
    
        res = apr_pstrmemdup(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 + 1);
        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 (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 (apr_isspace(*strend))
            ++strend;
        *line = strend;
        return res;
    }
    
    AP_DECLARE(char *) ap_getword_conf2_nc(apr_pool_t *p, char **line)
    {
        return ap_getword_conf2(p, (const char **) line);
    }
    
    AP_DECLARE(char *) ap_getword_conf2(apr_pool_t *p, const char **line)
    {
        const char *str = *line, *strend;
        char *res;
        char quote;
        int count = 1;
    
        while (apr_isspace(*str))
            ++str;
    
        if (!*str) {
            *line = str;
            return "";
        }
    
        if ((quote = *str) == '"' || quote == '\'')
            return ap_getword_conf(p, line);
    
        if (quote == '{') {
            strend = str + 1;
            while (*strend) {
                if (*strend == '}' && !--count)
                    break;
                if (*strend == '{')
                    ++count;
                if (*strend == '\\' && strend[1] && strend[1] == '\\') {
                    ++strend;
                }
                ++strend;
            }
            res = substring_conf(p, str + 1, strend - str - 1, 0);
    
            if (*strend == '}')
                ++strend;
        }
        else {
            strend = str;
            while (*strend && !apr_isspace(*strend))
                ++strend;
    
            res = substring_conf(p, str, strend - str, 0);
        }
    
        while (apr_isspace(*strend))
            ++strend;
        *line = strend;
        return res;
    }
    
    AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp)
    {
    #ifdef DEBUG
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(00551)
            "Done with config file %s", cfp->name);
    #endif
        return (cfp->close == NULL) ? 0 : cfp->close(cfp->param);
    }
    
    /* we can't use apr_file_* directly because of linking issues on Windows */
    static apr_status_t cfg_close(void *param)
    {
        return apr_file_close(param);
    }
    
    static apr_status_t cfg_getch(char *ch, void *param)
    {
        return apr_file_getc(ch, param);
    }
    
    static apr_status_t cfg_getstr(void *buf, apr_size_t bufsiz, void *param)
    {
        return apr_file_gets(buf, bufsiz, param);
    }
    
    /* 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, APLOGNO(00552)
                   "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, APLOGNO(00553)
                    "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)
            ap_cstr_casecmp(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, APLOGNO(00554)
                         "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 = cfg_getch;
        new_cfg->getstr = cfg_getstr;
        new_cfg->close = 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,
                apr_status_t (*getc_func) (char *ch, void *param),
                apr_status_t (*gets_func) (void *buf, apr_size_t bufsize, void *param),
                apr_status_t (*close_func) (void *param))
    {
        ap_configfile_t *new_cfg = apr_palloc(p, sizeof(*new_cfg));
        new_cfg->param = param;
        new_cfg->name = descr;
        new_cfg->getch = getc_func;
        new_cfg->getstr = gets_func;
        new_cfg->close = close_func;
        new_cfg->line_number = 0;
        return new_cfg;
    }
    
    /* Read one character from a configfile_t */
    AP_DECLARE(apr_status_t) ap_cfg_getc(char *ch, ap_configfile_t *cfp)
    {
        apr_status_t rc = cfp->getch(ch, cfp->param);
        if (rc == APR_SUCCESS && *ch == LF)
            ++cfp->line_number;
        return rc;
    }
    
    AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp,
                                              apr_status_t rc)
    {
        if (rc == APR_SUCCESS)
            return NULL;
    
        if (rc == APR_ENOSPC)
            return apr_psprintf(p, "Error reading %s at line %d: Line too long",
                                cfp->name, cfp->line_number);
    
        return apr_psprintf(p, "Error reading %s at line %d: %pm",
                            cfp->name, cfp->line_number, &rc);
    }
    
    /* 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 */
    static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize,
                                            apr_size_t offset, ap_configfile_t *cfp)
    {
        apr_status_t rc;
        /* If a "get string" function is defined, use it */
        if (cfp->getstr != NULL) {
            char *cp;
            char *cbuf = buf + offset;
            apr_size_t cbufsize = bufsize - offset;
    
            while (1) {
                ++cfp->line_number;
                rc = cfp->getstr(cbuf, cbufsize, cfp->param);
                if (rc == APR_EOF) {
                    if (cbuf != buf + offset) {
                        *cbuf = '\0';
                        break;
                    }
                    else {
                        return APR_EOF;
                    }
                }
                if (rc != APR_SUCCESS) {
                    return rc;
                }
    
                /*
                 *  check for line continuation,
                 *  i.e. match [^\\]\\[\r]\n only
                 */
                cp = cbuf;
                cp += strlen(cp);
                if (cp > buf && cp[-1] == LF) {
                    cp--;
                    if (cp > buf && cp[-1] == CR)
                        cp--;
                    if (cp > buf && cp[-1] == '\\') {
                        cp--;
                        /*
                         * line continuation requested -
                         * then remove backslash and continue
                         */
                        cbufsize -= (cp-cbuf);
                        cbuf = cp;
                        continue;
                    }
                }
                else if (cp - buf >= bufsize - 1) {
                    return APR_ENOSPC;
                }
                break;
            }
        } else {
            /* No "get string" function defined; read character by character */
            apr_size_t i = offset;
    
            if (bufsize < 2) {
                /* too small, assume caller is crazy */
                return APR_EINVAL;
            }
            buf[offset] = '\0';
    
            while (1) {
                char c;
                rc = cfp->getch(&c, cfp->param);
                if (rc == APR_EOF) {
                    if (i > offset)
                        break;
                    else
                        return APR_EOF;
                }
                if (rc != APR_SUCCESS)
                    return rc;
                if (c == LF) {
                    ++cfp->line_number;
                    /* check for line continuation */
                    if (i > 0 && buf[i-1] == '\\') {
                        i--;
                        continue;
                    }
                    else {
                        break;
                    }
                }
                buf[i] = c;
                ++i;
                if (i >= bufsize - 1) {
                    return APR_ENOSPC;
                }
            }
            buf[i] = '\0';
        }
        return APR_SUCCESS;
    }
    
    static int cfg_trim_line(char *buf)
    {
        char *start, *end;
        /*
         * Leading and trailing white space is eliminated completely
         */
        start = buf;
        while (apr_isspace(*start))
            ++start;
        /* blast trailing whitespace */
        end = &start[strlen(start)];
        while (--end >= start && apr_isspace(*end))
            *end = '\0';
        /* Zap leading whitespace by shifting */
        if (start != buf)
            memmove(buf, start, end - start + 2);
    #ifdef DEBUG_CFG_LINES
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, APLOGNO(00555) "Read config: '%s'", buf);
    #endif
        return end - start + 1;
    }
    
    /* 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(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize,
                                            ap_configfile_t *cfp)
    {
        apr_status_t rc = ap_cfg_getline_core(buf, bufsize, 0, cfp);
        if (rc == APR_SUCCESS)
            cfg_trim_line(buf);
        return rc;
    }
    
    AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb,
                                                   ap_configfile_t *cfp,
                                                   apr_size_t max_len)
    {
        apr_status_t rc;
        apr_size_t new_len;
        vb->strlen = 0;
        *vb->buf = '\0';
    
        if (vb->strlen == AP_VARBUF_UNKNOWN)
            vb->strlen = strlen(vb->buf);
        if (vb->avail - vb->strlen < 3) {
            new_len = vb->avail * 2;
            if (new_len > max_len)
                new_len = max_len;
            else if (new_len < 3)
                new_len = 3;
            ap_varbuf_grow(vb, new_len);
        }
    
        for (;;) {
            rc = ap_cfg_getline_core(vb->buf, vb->avail, vb->strlen, cfp);
            if (rc == APR_ENOSPC || rc == APR_SUCCESS)
                vb->strlen += strlen(vb->buf + vb->strlen);
            if (rc != APR_ENOSPC)
                break;
            if (vb->avail >= max_len)
                return APR_ENOSPC;
            new_len = vb->avail * 2;
            if (new_len > max_len)
                new_len = max_len;
            ap_varbuf_grow(vb, new_len);
            --cfp->line_number;
        }
        if (vb->strlen > max_len)
            return APR_ENOSPC;
        if (rc == APR_SUCCESS)
            vb->strlen = cfg_trim_line(vb->buf);
        return rc;
    }
    
    /* 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;
    }
    
    typedef enum ap_etag_e {
        AP_ETAG_NONE,
        AP_ETAG_WEAK,
        AP_ETAG_STRONG
    } ap_etag_e;
    
    /* 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.
     */
    static int find_list_item(apr_pool_t *p, const char *line,
                                      const char *tok, ap_etag_e type)
    {
        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;
        }
        if (type == AP_ETAG_STRONG && *tok != '\"') {
            return 0;
        }
        if (type == AP_ETAG_WEAK) {
            if (*tok == 'W' && (*(tok+1)) == '/' && (*(tok+2)) == '\"') {
                tok += 2;
            }
            else if (*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;
            }
    
            /* Account for strong or weak Etags, depending on our search */
            if (type == AP_ETAG_STRONG && *ptr != '\"') {
                break;
            }
            if (type == AP_ETAG_WEAK) {
                if (*ptr == 'W' && (*(ptr+1)) == '/' && (*(ptr+2)) == '\"') {
                    ptr += 2;
                }
                else if (*ptr != '\"') {
                    break;
                }
            }
    
            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
                                           && (apr_tolower(*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;
    }
    
    /* 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)
    {
        return find_list_item(p, line, tok, AP_ETAG_NONE);
    }
    
    /* Find a strong Etag in canonical form (lowercase, no extra spaces) within
     * an HTTP field value list.  Returns 1 if found, 0 if not found.
     */
    AP_DECLARE(int) ap_find_etag_strong(apr_pool_t *p, const char *line,
                                        const char *tok)
    {
        return find_list_item(p, line, tok, AP_ETAG_STRONG);
    }
    
    /* Find a weak ETag in canonical form (lowercase, no extra spaces) within
     * an HTTP field value list.  Returns 1 if found, 0 if not found.
     */
    AP_DECLARE(int) ap_find_etag_weak(apr_pool_t *p, const char *line,
                                      const char *tok)
    {
        return find_list_item(p, line, tok, AP_ETAG_WEAK);
    }
    
    /* Grab a list of tokens of the format 1#token (from RFC7230) */
    AP_DECLARE(const char *) ap_parse_token_list_strict(apr_pool_t *p,
                                                    const char *str_in,
                                                    apr_array_header_t **tokens,
                                                    int skip_invalid)
    {
        int in_leading_space = 1;
        int in_trailing_space = 0;
        int string_end = 0;
        const char *tok_begin;
        const char *cur;
    
        if (!str_in) {
            return NULL;
        }
    
        tok_begin = cur = str_in;
    
        while (!string_end) {
            const unsigned char c = (unsigned char)*cur;
    
            if (!TEST_CHAR(c, T_HTTP_TOKEN_STOP)) {
                /* Non-separator character; we are finished with leading
                 * whitespace. We must never have encountered any trailing
                 * whitespace before the delimiter (comma) */
                in_leading_space = 0;
                if (in_trailing_space) {
                    return "Encountered illegal whitespace in token";
                }
            }
            else if (c == ' ' || c == '\t') {
                /* "Linear whitespace" only includes ASCII CRLF, space, and tab;
                 * we can't get a CRLF since headers are split on them already,
                 * so only look for a space or a tab */
                if (in_leading_space) {
                    /* We're still in leading whitespace */
                    ++tok_begin;
                }
                else {
                    /* We must be in trailing whitespace */
                    ++in_trailing_space;
                }
            }
            else if (c == ',' || c == '\0') {
                if (!in_leading_space) {
                    /* If we're out of the leading space, we know we've read some
                     * characters of a token */
                    if (*tokens == NULL) {
                        *tokens = apr_array_make(p, 4, sizeof(char *));
                    }
                    APR_ARRAY_PUSH(*tokens, char *) =
                        apr_pstrmemdup((*tokens)->pool, tok_begin,
                                       (cur - tok_begin) - in_trailing_space);
                }
                /* We're allowed to have null elements, just don't add them to the
                 * array */
    
                tok_begin = cur + 1;
                in_leading_space = 1;
                in_trailing_space = 0;
                string_end = (c == '\0');
            }
            else {
                /* Encountered illegal separator char */
                if (skip_invalid) {
                    /* Skip to the next separator */
                    const char *temp;
                    temp = ap_strchr_c(cur, ',');
                    if(!temp) {
                        temp = ap_strchr_c(cur, '\0');
                    }
    
                    /* Act like we haven't seen a token so we reset */
                    cur = temp - 1;
                    in_leading_space = 1;
                    in_trailing_space = 0;
                }
                else {
                    return apr_psprintf(p, "Encountered illegal separator "
                                        "'\\x%.2x'", (unsigned int)c);
                }
            }
    
            ++cur;
        }
    
        return NULL;
    }
    
    /* Scan a string for HTTP VCHAR/obs-text characters including HT and SP
     * (as used in header values, for example, in RFC 7230 section 3.2)
     * returning the pointer to the first non-HT ASCII ctrl character.
     */
    AP_DECLARE(const char *) ap_scan_http_field_content(const char *ptr)
    {
        for ( ; !TEST_CHAR(*ptr, T_HTTP_CTRLS); ++ptr) ;
    
        return ptr;
    }
    
    /* Scan a string for HTTP token characters, returning the pointer to
     * the first non-token character.
     */
    AP_DECLARE(const char *) ap_scan_http_token(const char *ptr)
    {
        for ( ; !TEST_CHAR(*ptr, T_HTTP_TOKEN_STOP); ++ptr) ;
    
        return ptr;
    }
    
    /* Scan a string for visible ASCII (0x21-0x7E) or obstext (0x80+)
     * and return a pointer to the first ctrl/space character encountered.
     */
    AP_DECLARE(const char *) ap_scan_vchar_obstext(const char *ptr)
    {
        for ( ; TEST_CHAR(*ptr, T_VCHAR_OBSTEXT); ++ptr) ;
    
        return ptr;
    }
    
    /* 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;
    
        /* Find first non-white byte */
    
        while (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;
        }
    
        token = apr_pstrmemdup(p, tok_start, ptr - tok_start);
    
        /* Advance accept_line pointer to the next non-white byte */
    
        while (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 */
            while (*s && 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 (!ap_cstr_casecmpn((const char *)start_token, (const char *)tok,
                             s - start_token)) {
                return 1;
            }
            if (!*s) {
                return 0;
            }
        }
    }
    
    static const char *find_last_token(apr_pool_t *p, const char *line,
                                const char *tok)
    {
        int llen, tlen, lidx;
    
        if (!line)
            return NULL;
    
        llen = strlen(line);
        tlen = strlen(tok);
        lidx = llen - tlen;
    
        if (lidx < 0 ||
            (lidx > 0 && !(apr_isspace(line[lidx - 1]) || line[lidx - 1] == ',')))
            return NULL;
    
        if (ap_cstr_casecmpn(&line[lidx], tok, tlen) == 0) { 
            return &line[lidx];
        }
       return NULL;
    }
    
    AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line,
                                       const char *tok)
    {
        return find_last_token(p, line, tok) != NULL;
    }
    
    AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line)
    {
        const char *s;
    
        if (!line) 
            return 0;
        if (!ap_cstr_casecmp(line, "chunked")) { 
            return 1;
        }
    
        s = find_last_token(p, line, "chunked");
    
        if (!s) return 0;
     
        /* eat spaces right-to-left to see what precedes "chunked" */
        while (--s > line) { 
            if (*s != ' ') break;
        }
    
        /* found delim, or leading ws (input wasn't parsed by httpd as a header) */
        if (*s == ',' || *s == ' ') { 
            return 1;
        }
        return 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)
    {
        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, leaving reserved characters intact.
     * Returns 0 on success, non-zero on error
     * Failure is due to
     *   bad % escape       returns HTTP_BAD_REQUEST
     *
     *   decoding %00 or a forbidden character returns HTTP_NOT_FOUND
     */
    
    static int unescape_url(char *url, const char *forbid, const char *reserved,
                            unsigned int flags)
    {
        const int keep_slashes = (flags & AP_UNESCAPE_URL_KEEP_SLASHES) != 0,
                  forbid_slashes = (flags & AP_UNESCAPE_URL_FORBID_SLASHES) != 0,
                  keep_unreserved = (flags & AP_UNESCAPE_URL_KEEP_UNRESERVED) != 0;
        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')
                        || (forbid_slashes && AP_IS_SLASH(decoded))
                        || (forbid && ap_strchr_c(forbid, decoded))) {
                        badpath = 1;
                        *x = decoded;
                        y += 2;
                    }
                    else if ((keep_unreserved && TEST_CHAR(decoded,
                                                           T_URI_UNRESERVED))
                             || (keep_slashes && AP_IS_SLASH(decoded))
                             || (reserved && ap_strchr_c(reserved, decoded))) {
                        *x++ = *y++;
                        *x++ = *y++;
                        *x = *y;
                    }
                    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(int) ap_unescape_url(char *url)
    {
        /* Traditional */
        return unescape_url(url, AP_SLASHES, NULL, 0);
    }
    AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes)
    {
        /* AllowEncodedSlashes (corrected) */
        if (decode_slashes) {
            /* no chars reserved */
            return unescape_url(url, NULL, NULL, 0);
        } else {
            /* reserve (do not decode) encoded slashes */
            return unescape_url(url, NULL, AP_SLASHES, 0);
        }
    }
    AP_DECLARE(int) ap_unescape_url_ex(char *url, unsigned int flags)
    {
        return unescape_url(url, NULL, NULL, flags);
    }
    
    #ifdef NEW_APIS
    /* IFDEF these out until they've been thought through.
     * Just a germ of an API extension for now
     */
    AP_DECLARE(int) ap_unescape_url_proxy(char *url)
    {
        /* leave RFC1738 reserved characters intact, * so proxied URLs
         * don't get mangled.  Where does that leave encoded '&' ?
         */
        return unescape_url(url, NULL, "/;?", 0);
    }
    AP_DECLARE(int) ap_unescape_url_reserved(char *url, const char *reserved)
    {
        return unescape_url(url, NULL, reserved);
    }
    #endif
    
    AP_DECLARE(int) ap_unescape_urlencoded(char *query)
    {
        char *slider;
    
        /* replace plus with a space */
        if (query) {
            for (slider = query; *slider; slider++) {
                if (*slider == '+') {
                    *slider = ' ';
                }
            }
        }
    
        /* unescape everything else */
        return unescape_url(query, NULL, NULL, 0);
    }
    
    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);
        }
    }
    
    AP_DECLARE(int) ap_unescape_all(char *url)
    {
        return unescape_url(url, NULL, NULL, 0);
    }
    
    /* 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 prefix,
                                         unsigned char *where)
    {
    #if APR_CHARSET_EBCDIC
        what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what);
    #endif /*APR_CHARSET_EBCDIC*/
        *where++ = prefix;
        *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_buffer(char *copy, const char *segment)
    {
        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_escape_path_segment(apr_pool_t *p, const char *segment)
    {
        return ap_escape_path_segment_buffer(apr_palloc(p, 3 * strlen(segment) + 1), segment);
    }
    
    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_DECLARE(char *) ap_escape_urlencoded_buffer(char *copy, const char *buffer)
    {
        const unsigned char *s = (const unsigned char *)buffer;
        unsigned char *d = (unsigned char *)copy;
        unsigned c;
    
        while ((c = *s)) {
            if (TEST_CHAR(c, T_ESCAPE_URLENCODED)) {
                d = c2x(c, '%', d);
            }
            else if (c == ' ') {
                *d++ = '+';
            }
            else {
                *d++ = c;
            }
            ++s;
        }
        *d = '\0';
        return copy;
    }
    
    AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *buffer)
    {
        return ap_escape_urlencoded_buffer(apr_palloc(p, 3 * strlen(buffer) + 1), buffer);
    }
    
    /* ap_escape_uri is now a macro for os_escape_path */
    
    AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc)
    {
        apr_size_t i, j;
        char *x;
    
        /* first, count the number of extra characters */
        for (i = 0, j = 0; s[i] != '\0'; i++) {
            if (i + j > APR_SIZE_MAX - 6) {
                abort();
            }
            if (s[i] == '<' || s[i] == '>')
                j += 3;
            else if (s[i] == '&')
                j += 4;
            else if (s[i] == '"')
                j += 5;
            else if (toasc && !apr_isascii(s[i]))
                j += 5;
        }
    
        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], "&lt;", 4);
                j += 3;
            }
            else if (s[i] == '>') {
                memcpy(&x[j], "&gt;", 4);
                j += 3;
            }
            else if (s[i] == '&') {
                memcpy(&x[j], "&amp;", 5);
                j += 4;
            }
            else if (s[i] == '"') {
                memcpy(&x[j], "&quot;", 6);
                j += 5;
            }
            else if (toasc && !apr_isascii(s[i])) {
                char *esc = apr_psprintf(p, "&#%3.3d;", (unsigned char)s[i]);
                memcpy(&x[j], esc, 6);
                j += 5;
            }
            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;
        apr_size_t length, escapes = 0;
    
        if (!str) {
            return NULL;
        }
    
        /* Compute how many characters need to be escaped */
        s = (const unsigned char *)str;
        for (; *s; ++s) {
            if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
                escapes++;
            }
        }
        
        /* Compute the length of the input string, including NULL */
        length = s - (const unsigned char *)str + 1;
        
        /* Fast path: nothing to escape */
        if (escapes == 0) {
            return apr_pmemdup(p, str, length);
        }
        
        /* Each escaped character needs up to 3 extra bytes (0 --> \x00) */
        ret = apr_palloc(p, length + 3 * escapes);
        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, 'x', d);
                    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, 'x', d);
                    d += 3;
                }
            }
            else {
                *d++ = *s;
            }
        }
        *d = '\0';
    
        return (d - (unsigned char *)dest);
    }
    
    AP_DECLARE(void) ap_bin2hex(const void *src, apr_size_t srclen, char *dest)
    {
        const unsigned char *in = src;
        apr_size_t i;
    
        for (i = 0; i < srclen; i++) {
            *dest++ = c2x_table[in[i] >> 4];
            *dest++ = c2x_table[in[i] & 0xf];
        }
        *dest = '\0';
    }
    
    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)
    {
        int x;
    
        for (x = 0; u[x] != ':'; x++) {
            if ((!u[x]) ||
                ((!apr_isalnum(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;
        }
    }
    
    AP_DECLARE(void) ap_str_toupper(char *str)
    {
        while (*str) {
            *str = apr_toupper(*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, APLOGNO(00556)
                         "%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, APLOGNO(00557)
                             "%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, APLOGNO(00558)
                     "%s: Could not reliably determine the server's fully qualified "
                     "domain name, using %s. Set the 'ServerName' directive globally "
                     "to suppress this message",
                     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;
    
        decoded = (char *) apr_palloc(p, apr_base64_decode_len(bufcoded));
        apr_base64_decode(decoded, bufcoded);
    
        return decoded;
    }
    
    AP_DECLARE(char *) ap_pbase64encode(apr_pool_t *p, char *string)
    {
        char *encoded;
        int l = strlen(string);
    
        encoded = (char *) apr_palloc(p, apr_base64_encode_len(l));
        apr_base64_encode(encoded, string, l);
    
        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';
        }
    
        ap_str_tolower(str);
    
        if (semi) {
            *semi = ';';
        }
    }
    
    /*
     * Given a string, replace any bare " with \" .
     */
    AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring)
    {
        apr_size_t size, extra = 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') {
            if (*inchr == '"') {
                extra++;
            }
            /*
             * If we find a slosh, and it's not the last byte in the string,
             * it's escaping something - advance past both bytes.
             */
            else if ((*inchr == '\\') && (inchr[1] != '\0')) {
                inchr++;
            }
            inchr++;
        }
    
        if (!extra) {
            return apr_pstrdup(p, instring);
        }
    
        /* How large will the string become, once we escaped all the quotes?
         * The tricky cases are
         * - an `instring` that is already longer than `ptrdiff_t`
         *   can hold (which is an undefined case in C, as C defines ptrdiff_t as
         *   a signed difference between pointers into the same array and one index
         *   beyond).
         * - an `instring` that, including the `extra` chars we want to add, becomes
         *   even larger than apr_size_t can handle.
         * Since this function was not designed to ever return NULL for failure, we
         * can only trigger a hard assertion failure. It seems more a programming
         * mistake (or failure to verify the input causing this) that leads to this
         * situation.
         */
        ap_assert(inchr - instring > 0);
        size = ((apr_size_t)(inchr - instring)) + 1;
        ap_assert(size + extra > size);
    
        outstring = apr_palloc(p, size + extra);
        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 == '"') {
                *outchr++ = '\\';
            }
            else if ((*inchr == '\\') && (inchr[1] != '\0')) {
                *outchr++ = *inchr++;
            }
            *outchr++ = *inchr++;
        }
        *outchr = '\0';
        return outstring;
    }
    
    /*
     * Given a string, append the PID deliminated by delim.
     * Usually used to create a pid-appended filepath name
     * (eg: /a/b/foo -> /a/b/foo.6726). A function, and not
     * a macro, to avoid unistd.h dependency
     */
    AP_DECLARE(char *) ap_append_pid(apr_pool_t *p, const char *string,
                                        const char *delim)
    {
        return apr_psprintf(p, "%s%s%" APR_PID_T_FMT, string,
                            delim, getpid());
    
    }
    
    /**
     * Parse a given timeout parameter string into an apr_interval_time_t value.
     * The unit of the time interval is given as postfix string to the numeric
     * string. Currently the following units are understood:
     *
     * ms    : milliseconds
     * s     : seconds
     * mi[n] : minutes
     * h     : hours
     *
     * If no unit is contained in the given timeout parameter the default_time_unit
     * will be used instead.
     * @param timeout_parameter The string containing the timeout parameter.
     * @param timeout The timeout value to be returned.
     * @param default_time_unit The default time unit to use if none is specified
     * in timeout_parameter.
     * @return Status value indicating whether the parsing was successful or not.
     */
    #define CHECK_OVERFLOW(a, b) if (a > b) return APR_EGENERAL
    AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
                                                   const char *timeout_parameter,
                                                   apr_interval_time_t *timeout,
                                                   const char *default_time_unit)
    {
        char *endp;
        const char *time_str;
        apr_int64_t tout;
        apr_uint64_t check;
    
        tout = apr_strtoi64(timeout_parameter, &endp, 10);
        if (errno) {
            return errno;
        }
        if (!endp || !*endp) {
            time_str = default_time_unit;
        }
        else {
            time_str = endp;
        }
    
        if (tout < 0) { 
            return APR_EGENERAL;
        }
    
        switch (*time_str) {
            /* Time is in seconds */
        case 's':
            CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX));
            check = apr_time_from_sec(tout);
            break;
            /* Time is in hours */
        case 'h':
            CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX / 3600));
            check = apr_time_from_sec(tout * 3600);
            break;
        case 'm':
            switch (*(++time_str)) {
            /* Time is in milliseconds */
            case 's':
                CHECK_OVERFLOW(tout, apr_time_as_msec(APR_INT64_MAX));
                check = apr_time_from_msec(tout);
                break;
            /* Time is in minutes */
            case 'i':
                CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX / 60));
                check = apr_time_from_sec(tout * 60);
                break;
            default:
                return APR_EGENERAL;
            }
            break;
        default:
            return APR_EGENERAL;
        }
    
        *timeout = (apr_interval_time_t)check;
        return APR_SUCCESS;
    }
    #undef CHECK_OVERFLOW
    
    AP_DECLARE(int) ap_parse_strict_length(apr_off_t *len, const char *str)
    {
        char *end;
    
        return (apr_isdigit(*str)
                && apr_strtoff(len, str, &end, 10) == APR_SUCCESS
                && *end == '\0');
    }
    
    /**
     * Determine if a request has a request body or not.
     *
     * @param r the request_rec of the request
     * @return truth value
     */
    AP_DECLARE(int) ap_request_has_body(request_rec *r)
    {
        apr_off_t cl;
        const char *cls;
    
        return (!r->header_only
                && (r->kept_body
                    || apr_table_get(r->headers_in, "Transfer-Encoding")
                    || ((cls = apr_table_get(r->headers_in, "Content-Length"))
                        && ap_parse_strict_length(&cl, cls) && cl > 0)));
    }
    
    AP_DECLARE_NONSTD(apr_status_t) ap_pool_cleanup_set_null(void *data_)
    {
        void **ptr = (void **)data_;
        *ptr = NULL;
        return APR_SUCCESS;
    }
    
    AP_DECLARE(apr_status_t) ap_str2_alnum(const char *src, char *dest) {
    
        for ( ; *src; src++, dest++)
        {
            if (!apr_isprint(*src))
                *dest = 'x';
            else if (!apr_isalnum(*src))
                *dest = '_';
            else
                *dest = (char)*src;
        }
        *dest = '\0';
        return APR_SUCCESS;
    
    }
    
    AP_DECLARE(apr_status_t) ap_pstr2_alnum(apr_pool_t *p, const char *src,
                                            const char **dest)
    {
        char *new = apr_palloc(p, strlen(src)+1);
        if (!new)
            return APR_ENOMEM;
        *dest = new;
        return ap_str2_alnum(src, new);
    }
    
    /**
     * Read the body and parse any form found, which must be of the
     * type application/x-www-form-urlencoded.
     *
     * Name/value pairs are returned in an array, with the names as
     * strings with a maximum length of HUGE_STRING_LEN, and the
     * values as bucket brigades. This allows values to be arbitrarily
     * large.
     *
     * All url-encoding is removed from both the names and the values
     * on the fly. The names are interpreted as strings, while the
     * values are interpreted as blocks of binary data, that may
     * contain the 0 character.
     *
     * In order to ensure that resource limits are not exceeded, a
     * maximum size must be provided. If the sum of the lengths of
     * the names and the values exceed this size, this function
     * will return HTTP_REQUEST_ENTITY_TOO_LARGE.
     *
     * An optional number of parameters can be provided, if the number
     * of parameters provided exceeds this amount, this function will
     * return HTTP_REQUEST_ENTITY_TOO_LARGE. If this value is negative,
     * no limit is imposed, and the number of parameters is in turn
     * constrained by the size parameter above.
     *
     * This function honours any kept_body configuration, and the
     * original raw request body will be saved to the kept_body brigade
     * if so configured, just as ap_discard_request_body does.
     *
     * NOTE: File upload is not yet supported, but can be without change
     * to the function call.
     */
    
    /* form parsing stuff */
    typedef enum {
        FORM_NORMAL,
        FORM_AMP,
        FORM_NAME,
        FORM_VALUE,
        FORM_PERCENTA,
        FORM_PERCENTB,
        FORM_ABORT
    } ap_form_type_t;
    
    AP_DECLARE(int) ap_parse_form_data(request_rec *r, ap_filter_t *f,
                                       apr_array_header_t **ptr,
                                       apr_size_t num, apr_size_t usize)
    {
        apr_bucket_brigade *bb = NULL;
        int seen_eos = 0;
        char buffer[HUGE_STRING_LEN + 1];
        const char *ct;
        apr_size_t offset = 0;
        apr_ssize_t size;
        ap_form_type_t state = FORM_NAME, percent = FORM_NORMAL;
        ap_form_pair_t *pair = NULL;
        apr_array_header_t *pairs = apr_array_make(r->pool, 4, sizeof(ap_form_pair_t));
        char escaped_char[2] = { 0 };
    
        *ptr = pairs;
    
        /* sanity check - we only support forms for now */
        ct = apr_table_get(r->headers_in, "Content-Type");
        if (!ct || ap_cstr_casecmpn("application/x-www-form-urlencoded", ct, 33)) {
            return ap_discard_request_body(r);
        }
    
        if (usize > APR_SIZE_MAX >> 1)
            size = APR_SIZE_MAX >> 1;
        else
            size = usize;
    
        if (!f) {
            f = r->input_filters;
        }
    
        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        do {
            apr_bucket *bucket = NULL, *last = NULL;
    
            int rv = ap_get_brigade(f, bb, AP_MODE_READBYTES,
                                    APR_BLOCK_READ, HUGE_STRING_LEN);
            if (rv != APR_SUCCESS) {
                apr_brigade_destroy(bb);
                return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
            }
    
            for (bucket = APR_BRIGADE_FIRST(bb);
                 bucket != APR_BRIGADE_SENTINEL(bb);
                 last = bucket, bucket = APR_BUCKET_NEXT(bucket)) {
                const char *data;
                apr_size_t len, slide;
    
                if (last) {
                    apr_bucket_delete(last);
                }
                if (APR_BUCKET_IS_EOS(bucket)) {
                    seen_eos = 1;
                    break;
                }
                if (bucket->length == 0) {
                    continue;
                }
    
                rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
                if (rv != APR_SUCCESS) {
                    apr_brigade_destroy(bb);
                    return HTTP_BAD_REQUEST;
                }
    
                slide = len;
                while (state != FORM_ABORT && slide-- > 0 && size >= 0 && num != 0) {
                    char c = *data++;
                    if ('+' == c) {
                        c = ' ';
                    }
                    else if ('&' == c) {
                        state = FORM_AMP;
                    }
                    if ('%' == c) {
                        percent = FORM_PERCENTA;
                        continue;
                    }
                    if (FORM_PERCENTA == percent) {
                        escaped_char[0] = c;
                        percent = FORM_PERCENTB;
                        continue;
                    }
                    if (FORM_PERCENTB == percent) {
                        escaped_char[1] = c;
                        c = x2c(escaped_char);
                        percent = FORM_NORMAL;
                    }
                    switch (state) {
                        case FORM_AMP:
                            if (pair) {
                                const char *tmp = apr_pmemdup(r->pool, buffer, offset);
                                apr_bucket *b = apr_bucket_pool_create(tmp, offset, r->pool, r->connection->bucket_alloc);
                                APR_BRIGADE_INSERT_TAIL(pair->value, b);
                            }
                            state = FORM_NAME;
                            pair = NULL;
                            offset = 0;
                            num--;
                            break;
                        case FORM_NAME:
                            if (offset < HUGE_STRING_LEN) {
                                if ('=' == c) {
                                    pair = (ap_form_pair_t *) apr_array_push(pairs);
                                    pair->name = apr_pstrmemdup(r->pool, buffer, offset);
                                    pair->value = apr_brigade_create(r->pool, r->connection->bucket_alloc);
                                    state = FORM_VALUE;
                                    offset = 0;
                                }
                                else {
                                    buffer[offset++] = c;
                                    size--;
                                }
                            }
                            else {
                                state = FORM_ABORT;
                            }
                            break;
                        case FORM_VALUE:
                            if (offset >= HUGE_STRING_LEN) {
                                const char *tmp = apr_pmemdup(r->pool, buffer, offset);
                                apr_bucket *b = apr_bucket_pool_create(tmp, offset, r->pool, r->connection->bucket_alloc);
                                APR_BRIGADE_INSERT_TAIL(pair->value, b);
                                offset = 0;
                            }
                            buffer[offset++] = c;
                            size--;
                            break;
                        default:
                            break;
                    }
                }
    
            }
    
            apr_brigade_cleanup(bb);
        } while (!seen_eos);
    
        if (FORM_ABORT == state || size < 0 || num == 0) {
            return HTTP_REQUEST_ENTITY_TOO_LARGE;
        }
        else if (FORM_VALUE == state && pair && offset > 0) {
            const char *tmp = apr_pmemdup(r->pool, buffer, offset);
            apr_bucket *b = apr_bucket_pool_create(tmp, offset, r->pool, r->connection->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(pair->value, b);
        }
    
        return OK;
    
    }
    
    #define VARBUF_SMALL_SIZE 2048
    #define VARBUF_MAX_SIZE   (APR_SIZE_MAX - 1 -                                \
                               APR_ALIGN_DEFAULT(sizeof(struct ap_varbuf_info)))
    
    struct ap_varbuf_info {
        struct apr_memnode_t *node;
        apr_allocator_t *allocator;
    };
    
    static apr_status_t varbuf_cleanup(void *info_)
    {
        struct ap_varbuf_info *info = info_;
        info->node->next = NULL;
        apr_allocator_free(info->allocator, info->node);
        return APR_SUCCESS;
    }
    
    static const char nul = '\0';
    static char * const varbuf_empty = (char *)&nul;
    
    AP_DECLARE(void) ap_varbuf_init(apr_pool_t *p, struct ap_varbuf *vb,
                                    apr_size_t init_size)
    {
        vb->buf = varbuf_empty;
        vb->avail = 0;
        vb->strlen = AP_VARBUF_UNKNOWN;
        vb->pool = p;
        vb->info = NULL;
    
        ap_varbuf_grow(vb, init_size);
    }
    
    AP_DECLARE(void) ap_varbuf_grow(struct ap_varbuf *vb, apr_size_t new_len)
    {
        apr_memnode_t *new_node = NULL;
        apr_allocator_t *allocator;
        struct ap_varbuf_info *new_info;
        char *new;
    
        AP_DEBUG_ASSERT(vb->strlen == AP_VARBUF_UNKNOWN || vb->avail >= vb->strlen);
    
        if (new_len <= vb->avail)
            return;
    
        if (new_len < 2 * vb->avail && vb->avail < VARBUF_MAX_SIZE/2) {
            /* at least double the size, to avoid repeated reallocations */
            new_len = 2 * vb->avail;
        }
        else if (new_len > VARBUF_MAX_SIZE) {
            apr_abortfunc_t abort_fn = apr_pool_abort_get(vb->pool);
            ap_assert(abort_fn != NULL);
            abort_fn(APR_ENOMEM);
            return;
        }
    
        new_len++;  /* add space for trailing \0 */
        if (new_len <= VARBUF_SMALL_SIZE) {
            new_len = APR_ALIGN_DEFAULT(new_len);
            new = apr_palloc(vb->pool, new_len);
            if (vb->avail && vb->strlen != 0) {
                AP_DEBUG_ASSERT(vb->buf != NULL);
                AP_DEBUG_ASSERT(vb->buf != varbuf_empty);
                if (new == vb->buf + vb->avail + 1) {
                    /* We are lucky: the new memory lies directly after our old
                     * buffer, we can now use both.
                     */
                    vb->avail += new_len;
                    return;
                }
                else {
                    /* copy up to vb->strlen + 1 bytes */
                    memcpy(new, vb->buf, vb->strlen == AP_VARBUF_UNKNOWN ?
                                         vb->avail + 1 : vb->strlen + 1);
                }
            }
            else {
                *new = '\0';
            }
            vb->avail = new_len - 1;
            vb->buf = new;
            return;
        }
    
        /* The required block is rather larger. Use allocator directly so that
         * the memory can be freed independently from the pool. */
        allocator = apr_pool_allocator_get(vb->pool);
        /* Happens if APR was compiled with APR_POOL_DEBUG */
        if (allocator == NULL) {
            apr_allocator_create(&allocator);
            ap_assert(allocator != NULL);
        }
        if (new_len <= VARBUF_MAX_SIZE)
            new_node = apr_allocator_alloc(allocator,
                                           new_len + APR_ALIGN_DEFAULT(sizeof(*new_info)));
        if (!new_node) {
            apr_abortfunc_t abort_fn = apr_pool_abort_get(vb->pool);
            ap_assert(abort_fn != NULL);
            abort_fn(APR_ENOMEM);
            return;
        }
        new_info = (struct ap_varbuf_info *)new_node->first_avail;
        new_node->first_avail += APR_ALIGN_DEFAULT(sizeof(*new_info));
        new_info->node = new_node;
        new_info->allocator = allocator;
        new = new_node->first_avail;
        AP_DEBUG_ASSERT(new_node->endp - new_node->first_avail >= new_len);
        new_len = new_node->endp - new_node->first_avail;
    
        if (vb->avail && vb->strlen != 0)
            memcpy(new, vb->buf, vb->strlen == AP_VARBUF_UNKNOWN ?
                                 vb->avail + 1 : vb->strlen + 1);
        else
            *new = '\0';
        if (vb->info)
            apr_pool_cleanup_run(vb->pool, vb->info, varbuf_cleanup);
        apr_pool_cleanup_register(vb->pool, new_info, varbuf_cleanup,
                                  apr_pool_cleanup_null);
        vb->info = new_info;
        vb->buf = new;
        vb->avail = new_len - 1;
    }
    
    AP_DECLARE(void) ap_varbuf_strmemcat(struct ap_varbuf *vb, const char *str,
                                         int len)
    {
        if (len == 0)
            return;
        if (!vb->avail) {
            ap_varbuf_grow(vb, len);
            memcpy(vb->buf, str, len);
            vb->buf[len] = '\0';
            vb->strlen = len;
            return;
        }
        if (vb->strlen == AP_VARBUF_UNKNOWN)
            vb->strlen = strlen(vb->buf);
        ap_varbuf_grow(vb, vb->strlen + len);
        memcpy(vb->buf + vb->strlen, str, len);
        vb->strlen += len;
        vb->buf[vb->strlen] = '\0';
    }
    
    AP_DECLARE(void) ap_varbuf_free(struct ap_varbuf *vb)
    {
        if (vb->info) {
            apr_pool_cleanup_run(vb->pool, vb->info, varbuf_cleanup);
            vb->info = NULL;
        }
        vb->buf = NULL;
    }
    
    AP_DECLARE(char *) ap_varbuf_pdup(apr_pool_t *p, struct ap_varbuf *buf,
                                      const char *prepend, apr_size_t prepend_len,
                                      const char *append, apr_size_t append_len,
                                      apr_size_t *new_len)
    {
        apr_size_t i = 0;
        struct iovec vec[3];
    
        if (prepend) {
            vec[i].iov_base = (void *)prepend;
            vec[i].iov_len = prepend_len;
            i++;
        }
        if (buf->avail && buf->strlen) {
            if (buf->strlen == AP_VARBUF_UNKNOWN)
                buf->strlen = strlen(buf->buf);
            vec[i].iov_base = (void *)buf->buf;
            vec[i].iov_len = buf->strlen;
            i++;
        }
        if (append) {
            vec[i].iov_base = (void *)append;
            vec[i].iov_len = append_len;
            i++;
        }
        if (i)
            return apr_pstrcatv(p, vec, i, new_len);
    
        if (new_len)
            *new_len = 0;
        return "";
    }
    
    AP_DECLARE(apr_status_t) ap_varbuf_regsub(struct ap_varbuf *vb,
                                              const char *input,
                                              const char *source,
                                              apr_size_t nmatch,
                                              ap_regmatch_t pmatch[],
                                              apr_size_t maxlen)
    {
        return regsub_core(NULL, NULL, vb, input, source, nmatch, pmatch, maxlen);
    }
    
    static const char * const oom_message = "[crit] Memory allocation failed, "
                                            "aborting process." APR_EOL_STR;
    
    AP_DECLARE(void) ap_abort_on_oom(void)
    {
        int written, count = strlen(oom_message);
        const char *buf = oom_message;
        do {
            written = write(STDERR_FILENO, buf, count);
            if (written == count)
                break;
            if (written > 0) {
                buf += written;
                count -= written;
            }
        } while (written >= 0 || errno == EINTR);
        abort();
    }
    
    AP_DECLARE(void *) ap_malloc(size_t size)
    {
        void *p = malloc(size);
        if (p == NULL && size != 0)
            ap_abort_on_oom();
        return p;
    }
    
    AP_DECLARE(void *) ap_calloc(size_t nelem, size_t size)
    {
        void *p = calloc(nelem, size);
        if (p == NULL && nelem != 0 && size != 0)
            ap_abort_on_oom();
        return p;
    }
    
    AP_DECLARE(void *) ap_realloc(void *ptr, size_t size)
    {
        void *p = realloc(ptr, size);
        if (p == NULL && size != 0)
            ap_abort_on_oom();
        return p;
    }
    
    #if APR_HAS_THREADS
    
    #if APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL)
    
    #define ap_thread_current_create apr_thread_current_create
    
    #else /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */
    
    #if AP_HAS_THREAD_LOCAL
    
    struct thread_ctx {
        apr_thread_start_t func;
        void *data;
    };
    
    static AP_THREAD_LOCAL apr_thread_t *current_thread = NULL;
    
    static void *APR_THREAD_FUNC thread_start(apr_thread_t *thread, void *data)
    {
        struct thread_ctx *ctx = data;
    
        current_thread = thread;
        return ctx->func(thread, ctx->data);
    }
    
    AP_DECLARE(apr_status_t) ap_thread_create(apr_thread_t **thread, 
                                              apr_threadattr_t *attr, 
                                              apr_thread_start_t func, 
                                              void *data, apr_pool_t *pool)
    {
        struct thread_ctx *ctx = apr_palloc(pool, sizeof(*ctx));
    
        ctx->func = func;
        ctx->data = data;
        return apr_thread_create(thread, attr, thread_start, ctx, pool);
    }
    
    #endif /* AP_HAS_THREAD_LOCAL */
    
    AP_DECLARE(apr_status_t) ap_thread_current_create(apr_thread_t **current,
                                                      apr_threadattr_t *attr,
                                                      apr_pool_t *pool)
    {
        apr_status_t rv;
        apr_abortfunc_t abort_fn = apr_pool_abort_get(pool);
        apr_allocator_t *allocator;
        apr_os_thread_t osthd;
        apr_pool_t *p;
    
        *current = ap_thread_current();
        if (*current) {
            return APR_EEXIST;
        }
    
        rv = apr_allocator_create(&allocator);
        if (rv != APR_SUCCESS) {
            if (abort_fn)
                abort_fn(rv);
            return rv;
        }
        rv = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator);
        if (rv != APR_SUCCESS) {
            apr_allocator_destroy(allocator);
            return rv;
        }
        apr_allocator_owner_set(allocator, p);
    
        osthd = apr_os_thread_current();
        rv = apr_os_thread_put(current, &osthd, p);
        if (rv != APR_SUCCESS) {
            apr_pool_destroy(p);
            return rv;
        }
    
    #if AP_HAS_THREAD_LOCAL
        current_thread = *current;
    #endif
        return APR_SUCCESS;
    }
    
    AP_DECLARE(void) ap_thread_current_after_fork(void)
    {
    #if AP_HAS_THREAD_LOCAL
        current_thread = NULL;
    #endif
    }
    
    AP_DECLARE(apr_thread_t *) ap_thread_current(void)
    {
    #if AP_HAS_THREAD_LOCAL
        return current_thread;
    #else
        return NULL;
    #endif
    }
    
    #endif /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */
    
    static apr_status_t main_thread_cleanup(void *arg)
    {
        apr_thread_t *thd = arg;
        apr_pool_destroy(apr_thread_pool_get(thd));
        return APR_SUCCESS;
    }
    
    AP_DECLARE(apr_status_t) ap_thread_main_create(apr_thread_t **thread,
                                                   apr_pool_t *pool)
    {
        apr_status_t rv;
        apr_threadattr_t *attr = NULL;
    
        /* Create an apr_thread_t for the main child thread to set up its Thread
         * Local Storage. Since it's detached and won't apr_thread_exit(), destroy
         * its pool before exiting via a cleanup of the given pool.
         */
        if ((rv = apr_threadattr_create(&attr, pool))
                || (rv = apr_threadattr_detach_set(attr, 1))
                || (rv = ap_thread_current_create(thread, attr, pool))) {
            *thread = NULL;
            return rv;
        }
    
        apr_pool_cleanup_register(pool, *thread, main_thread_cleanup,
                                  apr_pool_cleanup_null);
        return APR_SUCCESS;
    }
    
    #endif /* APR_HAS_THREADS */
    
    AP_DECLARE(void) ap_get_sload(ap_sload_t *ld)
    {
        int i, j, server_limit, thread_limit;
        int ready = 0;
        int busy = 0;
        int total;
        ap_generation_t mpm_generation;
    
        /* preload errored fields, we overwrite */
        ld->idle = -1;
        ld->busy = -1;
        ld->bytes_served = 0;
        ld->access_count = 0;
    
        ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
        ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
    
        for (i = 0; i < server_limit; i++) {
            process_score *ps;
            ps = ap_get_scoreboard_process(i);
    
            for (j = 0; j < thread_limit; j++) {
                int res;
                worker_score *ws = NULL;
                ws = &ap_scoreboard_image->servers[i][j];
                res = ws->status;
    
                if (!ps->quiescing && ps->pid) {
                    if (res == SERVER_READY && ps->generation == mpm_generation) {
                        ready++;
                    }
                    else if (res != SERVER_DEAD &&
                             res != SERVER_STARTING && res != SERVER_IDLE_KILL &&
                             ps->generation == mpm_generation) {
                        busy++;
                    }   
                }
    
                if (ap_extended_status && !ps->quiescing && ps->pid) {
                    if (ws->access_count != 0 
                        || (res != SERVER_READY && res != SERVER_DEAD)) {
                        ld->access_count += ws->access_count;
                        ld->bytes_served += ws->bytes_served;
                    }
                }
            }
        }
        total = busy + ready;
        if (total) {
            ld->idle = ready * 100 / total;
            ld->busy = busy * 100 / total;
        }
    }
    
    AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld)
    {
        /* preload errored fields, we overwrite */
        ld->loadavg = -1.0;
        ld->loadavg5 = -1.0;
        ld->loadavg15 = -1.0;
    
    #if HAVE_GETLOADAVG
        {
            double la[3];
            int num;
    
            num = getloadavg(la, 3);
            if (num > 0) {
                ld->loadavg = (float)la[0];
            }
            if (num > 1) {
                ld->loadavg5 = (float)la[1];
            }
            if (num > 2) {
                ld->loadavg15 = (float)la[2];
            }
        }
    #endif
    }
    
    AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p,
                                        const char *cmd,
                                        const char * const * argv)
    {
        char buf[MAX_STRING_LEN];
        apr_procattr_t *procattr;
        apr_proc_t *proc;
        apr_file_t *fp;
        apr_size_t nbytes = 1;
        char c;
        int k;
    
        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;
        proc = apr_pcalloc(p, sizeof(apr_proc_t));
        if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
            return NULL;
        fp = proc->out;
    
        if (fp == 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] = '\0'; 
        apr_file_close(fp);
    
        return apr_pstrndup(p, buf, k);
    }
    
    AP_DECLARE(int) ap_array_str_index(const apr_array_header_t *array, 
                                       const char *s,
                                       int start)
    {
        if (start >= 0) {
            int i;
            
            for (i = start; i < array->nelts; i++) {
                const char *p = APR_ARRAY_IDX(array, i, const char *);
                if (!strcmp(p, s)) {
                    return i;
                }
            }
        }
        
        return -1;
    }
    
    AP_DECLARE(int) ap_array_str_contains(const apr_array_header_t *array, 
                                          const char *s)
    {
        return (ap_array_str_index(array, s, 0) >= 0);
    }
    
    #if !APR_CHARSET_EBCDIC
    /*
     * Our own known-fast translation table for casecmp by character.
     * Only ASCII alpha characters 41-5A are folded to 61-7A, other
     * octets (such as extended latin alphabetics) are never case-folded.
     * NOTE: Other than Alpha A-Z/a-z, each code point is unique!
     */
    static const short ucharmap[] = {
        0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
        0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
        0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
        0x40,  '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', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
        0x60,  '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', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
        0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
        0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
        0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
        0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
        0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
        0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
        0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
        0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
        0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
        0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
        0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
        0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
        0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
        0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
    };
    #else /* APR_CHARSET_EBCDIC */
    /*
     * Derived from apr-iconv/ccs/cp037.c for EBCDIC case comparison,
     * provides unique identity of every char value (strict ISO-646
     * conformance, arbitrary election of an ISO-8859-1 ordering, and
     * very arbitrary control code assignments into C1 to achieve
     * identity and a reversible mapping of code points),
     * then folding the equivalences of ASCII 41-5A into 61-7A, 
     * presenting comparison results in a somewhat ISO/IEC 10646
     * (ASCII-like) order, depending on the EBCDIC code page in use.
     *
     * NOTE: Other than Alpha A-Z/a-z, each code point is unique!
     */
    static const short ucharmap[] = {
        0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F,
        0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
        0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87,
        0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F,
        0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B,
        0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07,
        0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
        0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A,
        0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5,
        0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
        0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF,
        0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC,
        0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5,
        0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
        0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF,
        0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
        0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
        0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1,
        0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
        0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4,
        0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
        0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE,
        0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC,
        0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7,
        0x7B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
        0x68, 0x69, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5,
        0x7D, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
        0x71, 0x72, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF,
        0x5C, 0xF7, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
        0x79, 0x7A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F
    };
    #endif
    
    AP_DECLARE(int) ap_cstr_casecmp(const char *s1, const char *s2)
    {
        const unsigned char *str1 = (const unsigned char *)s1;
        const unsigned char *str2 = (const unsigned char *)s2;
        for (;;)
        {
            const int c1 = (int)(*str1);
            const int c2 = (int)(*str2);
            const int cmp = ucharmap[c1] - ucharmap[c2];
            /* Not necessary to test for !c2, this is caught by cmp */
            if (cmp || !c1)
                return cmp;
            str1++;
            str2++;
        }
    }
    
    AP_DECLARE(int) ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n)
    {
        const unsigned char *str1 = (const unsigned char *)s1;
        const unsigned char *str2 = (const unsigned char *)s2;
        while (n--)
        {
            const int c1 = (int)(*str1);
            const int c2 = (int)(*str2);
            const int cmp = ucharmap[c1] - ucharmap[c2];
            /* Not necessary to test for !c2, this is caught by cmp */
            if (cmp || !c1)
                return cmp;
            str1++;
            str2++;
        }
        return 0;
    }
    
    typedef struct {
        const 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);
    }
    
    AP_DECLARE(ap_dir_match_t *)ap_dir_cfgmatch(cmd_parms *cmd, int flags,
            const char *(*cb)(ap_dir_match_t *w, const char *fname), void *ctx)
    {
        ap_dir_match_t *w = apr_palloc(cmd->temp_pool, sizeof(*w));
    
        w->prefix = apr_pstrcat(cmd->pool, cmd->cmd->name, ": ", NULL);
        w->p = cmd->pool;
        w->ptemp = cmd->temp_pool;
        w->flags = flags;
        w->cb = cb;
        w->ctx = ctx;
        w->depth = 0;
    
        return w;
    }
    
    AP_DECLARE(const char *)ap_dir_nofnmatch(ap_dir_match_t *w, const char *fname)
    {
        const char *error;
        apr_status_t rv;
    
        if ((w->flags & AP_DIR_FLAG_RECURSIVE) && ap_is_directory(w->ptemp, fname)) {
            apr_dir_t *dirp;
            apr_finfo_t dirent;
            int current;
            apr_array_header_t *candidates = NULL;
            fnames *fnew;
            char *path = apr_pstrdup(w->ptemp, fname);
    
            if (++w->depth > AP_MAX_FNMATCH_DIR_DEPTH) {
                return apr_psprintf(w->p, "%sDirectory '%s' exceeds the maximum include "
                        "directory nesting level of %u. You have "
                        "probably a recursion somewhere.", w->prefix ? w->prefix : "", path,
                        AP_MAX_FNMATCH_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, w->ptemp);
            if (rv != APR_SUCCESS) {
                return apr_psprintf(w->p, "%sCould not open directory %s: %pm",
                        w->prefix ? w->prefix : "", path, &rv);
            }
    
            candidates = apr_array_make(w->ptemp, 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(w->ptemp, 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 = ap_dir_nofnmatch(w, fnew->fname);
                    if (error) {
                        return error;
                    }
                }
            }
    
            w->depth--;
    
            return NULL;
        }
        else if (w->flags & AP_DIR_FLAG_OPTIONAL) {
            /* If the optional flag is set (like for IncludeOptional) we can
             * tolerate that no file or directory is present and bail out.
             */
            apr_finfo_t finfo;
            if (apr_stat(&finfo, fname, APR_FINFO_TYPE, w->ptemp) != APR_SUCCESS
                || finfo.filetype == APR_NOFILE)
                return NULL;
        }
    
        return w->cb(w, fname);
    }
    
    AP_DECLARE(const char *)ap_dir_fnmatch(ap_dir_match_t *w, const char *path,
            const char *fname)
    {
        const char *rest;
        apr_status_t rv;
        apr_dir_t *dirp;
        apr_finfo_t dirent;
        apr_array_header_t *candidates = NULL;
        fnames *fnew;
        int current;
    
        /* find the first part of the filename */
        rest = ap_strchr_c(fname, '/');
        if (rest) {
            fname = apr_pstrmemdup(w->ptemp, fname, rest - fname);
            rest++;
        }
    
        /* optimisation - if the filename isn't a wildcard, process it directly */
        if (!apr_fnmatch_test(fname)) {
            path = path ? ap_make_full_path(w->ptemp, path, fname) : fname;
            if (!rest) {
                return ap_dir_nofnmatch(w, path);
            }
            else {
                return ap_dir_fnmatch(w, path, rest);
            }
        }
    
        /*
         * 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, w->ptemp);
        if (rv != APR_SUCCESS) {
            /* If the directory doesn't exist and the optional flag is set
             * there is no need to return an error.
             */
            if (rv == APR_ENOENT && (w->flags & AP_DIR_FLAG_OPTIONAL)) {
                return NULL;
            }
            return apr_psprintf(w->p, "%sCould not open directory %s: %pm",
                    w->prefix ? w->prefix : "", path, &rv);
        }
    
        candidates = apr_array_make(w->ptemp, 1, sizeof(fnames));
        while (apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_TYPE, dirp) == APR_SUCCESS) {
            /* strip out '.' and '..' */
            if (strcmp(dirent.name, ".")
                && strcmp(dirent.name, "..")
                && (apr_fnmatch(fname, dirent.name,
                                APR_FNM_PERIOD) == APR_SUCCESS)) {
                const char *full_path = ap_make_full_path(w->ptemp, path, dirent.name);
                /* If matching internal to path, and we happen to match something
                 * other than a directory, skip it
                 */
                if (rest && (dirent.filetype != APR_DIR)) {
                    continue;
                }
                fnew = (fnames *) apr_array_push(candidates);
                fnew->fname = full_path;
            }
        }
    
        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];
                if (!rest) {
                    error = ap_dir_nofnmatch(w, fnew->fname);
                }
                else {
                    error = ap_dir_fnmatch(w, fnew->fname, rest);
                }
                if (error) {
                    return error;
                }
            }
        }
        else {
    
            if (!(w->flags & AP_DIR_FLAG_OPTIONAL)) {
                return apr_psprintf(w->p, "%sNo matches for the wildcard '%s' in '%s', failing",
                        w->prefix ? w->prefix : "", fname, path);
            }
        }
    
        return NULL;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/buildmark.c���������������������������������������������������������������������0000664�0001751�0001751�00000002074�14557153357�016270� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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(void)
    {
        return server_built;
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_time.c���������������������������������������������������������������������0000664�0001751�0001751�00000026560�14455327713�016313� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    
    /* Number of characters needed to format the microsecond part of a timestamp.
     * Microseconds have 6 digits plus one separator character makes 7.
     *   */
    #define AP_CTIME_USEC_LENGTH      7
    
    /* Length of ISO 8601 date/time (including trailing '\0') */
    #define AP_CTIME_COMPACT_LEN      20
    
    /* Length of timezone offset from GMT ([+-]hhmm) plus leading space */
    #define AP_CTIME_GMTOFF_LEN       6
    
    /* 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)
    {
        int len = APR_CTIME_LEN;
        return ap_recent_ctime_ex(date_str, t, AP_CTIME_OPTION_NONE, &len);
    }
    
    AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
                                                int option, int *len)
    {
        /* ### 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;
        int needed;
    
    
        /* Calculate the needed buffer length */
        if (option & AP_CTIME_OPTION_COMPACT)
            needed = AP_CTIME_COMPACT_LEN;
        else
            needed = APR_CTIME_LEN;
    
        if (option & AP_CTIME_OPTION_USEC) {
            needed += AP_CTIME_USEC_LENGTH;
        }
    
        if (option & AP_CTIME_OPTION_GMTOFF) {
            needed += AP_CTIME_GMTOFF_LEN;
        }
    
        /* Check the provided buffer length (note: above AP_CTIME_COMPACT_LEN
         * and APR_CTIME_LEN include the trailing '\0'; so does 'needed' then).
         */
        if (len && *len >= needed) {
            *len = needed;
        }
        else {
            if (len != NULL) {
                *len = 0;
            }
            return APR_ENOMEM;
        }
    
        /* example without options: "Wed Jun 30 21:49:08 1993" */
        /* example for compact format: "1993-06-30 21:49:08" */
        /* example for compact+usec+gmtoff format:
         *     "1993-06-30 22:49:08.123456 +0100"
         */
    
        ap_explode_recent_localtime(&xt, t);
        real_year = 1900 + xt.tm_year;
        if (option & AP_CTIME_OPTION_COMPACT) {
            int real_month = xt.tm_mon + 1;
            *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++ = real_month / 10 + '0';
            *date_str++ = real_month % 10 + '0';
            *date_str++ = '-';
        }
        else {
            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';
        if (option & AP_CTIME_OPTION_USEC) {
            int div;
            int usec = (int)xt.tm_usec;
            *date_str++ = '.';
            for (div=100000; div>0; div=div/10) {
                *date_str++ = usec / div + '0';
                usec = usec % div;
            }
        }
        if (!(option & AP_CTIME_OPTION_COMPACT)) {
            *date_str++ = ' ';
            *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';
        }
        if (option & AP_CTIME_OPTION_GMTOFF) {
            int off = xt.tm_gmtoff, off_hh, off_mm;
            char sign = '+';
            if (off < 0) {
                off = -off;
                sign = '-';
            }
            off_hh = off / 3600;
            off_mm = off % 3600 / 60;
            *date_str++ = ' ';
            *date_str++ = sign;
            *date_str++ = off_hh / 10 + '0';
            *date_str++ = off_hh % 10 + '0';
            *date_str++ = off_mm / 10 + '0';
            *date_str++ = off_mm % 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;
    }
    ������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_pcre.c���������������������������������������������������������������������0000664�0001751�0001751�00000041371�14207134173�016272� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 code is based on pcreposix.c from the PCRE Library distribution,
     * as originally written by Philip Hazel <ph10@cam.ac.uk>, and forked by
     * the Apache HTTP Server project to provide POSIX-style regex function
     * wrappers around underlying PCRE library functions for httpd.
     * 
     * The original source file pcreposix.c is copyright and licensed as follows;
    
               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 "apr_tables.h"
    #include "apr_thread_proc.h"
    
    #ifdef HAVE_PCRE2
    #define PCRE2_CODE_UNIT_WIDTH 8
    #include "pcre2.h"
    #define PCREn(x) PCRE2_ ## x
    #else
    #include "pcre.h"
    #define PCREn(x) PCRE_ ## x
    #endif
    
    /* PCRE_DUPNAMES is only present since version 6.7 of PCRE */
    #if !defined(PCRE_DUPNAMES) && !defined(HAVE_PCRE2)
    #error PCRE Version 6.7 or later required!
    #else
    
    #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(const char *) ap_pcre_version_string(int which)
    {
    #ifdef HAVE_PCRE2
        static char buf[80];
    #endif
        switch (which) {
        case AP_REG_PCRE_COMPILED:
            return APR_STRINGIFY(PCREn(MAJOR)) "." APR_STRINGIFY(PCREn(MINOR)) " " APR_STRINGIFY(PCREn(DATE));
        case AP_REG_PCRE_LOADED:
    #ifdef HAVE_PCRE2
            pcre2_config(PCRE2_CONFIG_VERSION, buf);
            return buf;
    #else
            return pcre_version();
    #endif
        default:
            return "Unknown";
        }
    }
    
    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, errbuf_size, "%s%s%-6d", message, addmessage,
                             (int)preg->re_erroffset);
            else
                apr_cpystrn(errbuf, message, errbuf_size);
        }
    
        return length + addlength;
    }
    
    
    
    
    /*************************************************
     *           Free store held by a regex          *
     *************************************************/
    
    AP_DECLARE(void) ap_regfree(ap_regex_t *preg)
    {
    #ifdef HAVE_PCRE2
        pcre2_code_free(preg->re_pcre);
    #else
        (pcre_free)(preg->re_pcre);
    #endif
    }
    
    
    
    
    /*************************************************
     *            Compile a regular expression       *
     *************************************************/
    
    static int default_cflags = AP_REG_DEFAULT;
    
    AP_DECLARE(int) ap_regcomp_get_default_cflags(void)
    {
        return default_cflags;
    }
    
    AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags)
    {
        default_cflags = cflags;
    }
    
    AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name)
    {
        int cflag = 0;
    
        if (ap_cstr_casecmp(name, "ICASE") == 0) {
            cflag = AP_REG_ICASE;
        }
        else if (ap_cstr_casecmp(name, "DOTALL") == 0) {
            cflag = AP_REG_DOTALL;
        }
        else if (ap_cstr_casecmp(name, "DOLLAR_ENDONLY") == 0) {
            cflag = AP_REG_DOLLAR_ENDONLY;
        }
        else if (ap_cstr_casecmp(name, "EXTENDED") == 0) {
            cflag = AP_REG_EXTENDED;
        }
    
        return cflag;
    }
    
    /*
     * 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)
    {
    #ifdef HAVE_PCRE2
        uint32_t capcount;
        size_t erroffset;
    #else
        const char *errorptr;
        int erroffset;
    #endif
        int errcode = 0;
        int options = PCREn(DUPNAMES);
    
        if ((cflags & AP_REG_NO_DEFAULT) == 0)
            cflags |= default_cflags;
    
        if ((cflags & AP_REG_ICASE) != 0)
            options |= PCREn(CASELESS);
        if ((cflags & AP_REG_NEWLINE) != 0)
            options |= PCREn(MULTILINE);
        if ((cflags & AP_REG_DOTALL) != 0)
            options |= PCREn(DOTALL);
        if ((cflags & AP_REG_DOLLAR_ENDONLY) != 0)
            options |= PCREn(DOLLAR_ENDONLY);
    
    #ifdef HAVE_PCRE2
        preg->re_pcre = pcre2_compile((const unsigned char *)pattern,
                                      PCRE2_ZERO_TERMINATED, options, &errcode,
                                      &erroffset, NULL);
    #else
        preg->re_pcre = pcre_compile2(pattern, options, &errcode,
                                      &errorptr, &erroffset, NULL);
    #endif
    
        preg->re_erroffset = erroffset;
        if (preg->re_pcre == NULL) {
            /* Internal ERR21 is "failed to get memory" according to pcreapi(3) */
            if (errcode == 21)
                return AP_REG_ESPACE;
            return AP_REG_INVARG;
        }
    
    #ifdef HAVE_PCRE2
        pcre2_pattern_info((const pcre2_code *)preg->re_pcre,
                           PCRE2_INFO_CAPTURECOUNT, &capcount);
        preg->re_nsub = capcount;
    #else
        pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
                      PCRE_INFO_CAPTURECOUNT, &(preg->re_nsub));
    #endif
        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.
     * Yet more unfortunately, PCRE2 wants an opaque context by providing the API
     * to allocate and free it, so to minimize these calls we maintain one opaque
     * context per thread (in Thread Local Storage, TLS) grown as needed, and while
     * at it we do the same for PCRE1 ints vectors. Note that this requires a fast
     * TLS mechanism to be worth it, which is the case of apr_thread_data_get/set()
     * from/to ap_thread_current() when AP_HAS_THREAD_LOCAL; otherwise we'll do
     * the allocation and freeing for each ap_regexec().
     */
    
    #ifdef HAVE_PCRE2
    typedef pcre2_match_data* match_data_pt;
    typedef size_t*           match_vector_pt;
    #else
    typedef int*              match_data_pt;
    typedef int*              match_vector_pt;
    #endif
    
    static APR_INLINE
    match_data_pt alloc_match_data(apr_size_t size,
                                   match_vector_pt small_vector)
    {
        match_data_pt data;
    
    #ifdef HAVE_PCRE2
        data = pcre2_match_data_create(size, NULL);
    #else
        if (size > POSIX_MALLOC_THRESHOLD) {
            data = malloc(size * sizeof(int) * 3);
        }
        else {
            data = small_vector;
        }
    #endif
    
        return data;
    }
    
    static APR_INLINE
    void free_match_data(match_data_pt data, apr_size_t size)
    {
    #ifdef HAVE_PCRE2
        pcre2_match_data_free(data);
    #else
        if (size > POSIX_MALLOC_THRESHOLD) {
            free(data);
        }
    #endif
    }
    
    #if AP_HAS_THREAD_LOCAL && !defined(APREG_NO_THREAD_LOCAL)
    
    struct apreg_tls {
        match_data_pt data;
        apr_size_t size;
    };
    
    #ifdef HAVE_PCRE2
    static apr_status_t apreg_tls_cleanup(void *arg)
    {
        struct apreg_tls *tls = arg;
        pcre2_match_data_free(tls->data); /* NULL safe */
        return APR_SUCCESS;
    }
    #endif
    
    static match_data_pt get_match_data(apr_size_t size,
                                        match_vector_pt small_vector,
                                        int *to_free)
    {
        apr_thread_t *current;
        struct apreg_tls *tls = NULL;
    
        /* Even though AP_HAS_THREAD_LOCAL, we may still be called by a
         * native/non-apr thread, let's fall back to alloc/free in this case.
         */
        current = ap_thread_current();
        if (!current) {
            *to_free = 1;
            return alloc_match_data(size, small_vector);
        }
    
        apr_thread_data_get((void **)&tls, "apreg", current);
        if (!tls || tls->size < size) {
            apr_pool_t *tp = apr_thread_pool_get(current);
            if (!tls) {
                tls = apr_pcalloc(tp, sizeof(*tls));
    #ifdef HAVE_PCRE2
                apr_thread_data_set(tls, "apreg", apreg_tls_cleanup, current);
    #else
                apr_thread_data_set(tls, "apreg", NULL, current);
    #endif
            }
    
            tls->size *= 2;
            if (tls->size < size) {
                tls->size = size;
                if (tls->size < POSIX_MALLOC_THRESHOLD) {
                    tls->size = POSIX_MALLOC_THRESHOLD;
                }
            }
    
    #ifdef HAVE_PCRE2
            pcre2_match_data_free(tls->data); /* NULL safe */
            tls->data = pcre2_match_data_create(tls->size, NULL);
            if (!tls->data) {
                tls->size = 0;
                return NULL;
            }
    #else
            tls->data = apr_palloc(tp, tls->size * sizeof(int) * 3);
    #endif
        }
    
        return tls->data;
    }
    
    #else /* AP_HAS_THREAD_LOCAL && !defined(APREG_NO_THREAD_LOCAL) */
    
    static APR_INLINE match_data_pt get_match_data(apr_size_t size,
                                                   match_vector_pt small_vector,
                                                   int *to_free)
    {
        *to_free = 1;
        return alloc_match_data(size, small_vector);
    }
    
    #endif /* AP_HAS_THREAD_LOCAL && !defined(APREG_NO_THREAD_LOCAL) */
    
    AP_DECLARE(int) ap_regexec(const ap_regex_t *preg, const char *string,
                               apr_size_t nmatch, ap_regmatch_t *pmatch,
                               int eflags)
    {
        return ap_regexec_len(preg, string, strlen(string), nmatch, pmatch,
                              eflags);
    }
    
    AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
                                   apr_size_t len, apr_size_t nmatch,
                                   ap_regmatch_t *pmatch, int eflags)
    {
        int rc;
        int options = 0, to_free = 0;
        match_vector_pt ovector = NULL;
        apr_size_t ncaps = (apr_size_t)preg->re_nsub + 1;
    #ifdef HAVE_PCRE2
        match_data_pt data = get_match_data(ncaps, NULL, &to_free);
    #else
        int small_vector[POSIX_MALLOC_THRESHOLD * 3];
        match_data_pt data = get_match_data(ncaps, small_vector, &to_free);
    #endif
    
        if (!data) {
            return AP_REG_ESPACE;
        }
    
        if ((eflags & AP_REG_NOTBOL) != 0)
            options |= PCREn(NOTBOL);
        if ((eflags & AP_REG_NOTEOL) != 0)
            options |= PCREn(NOTEOL);
    
    #ifdef HAVE_PCRE2
        rc = pcre2_match((const pcre2_code *)preg->re_pcre,
                         (const unsigned char *)buff, len,
                         0, options, data, NULL);
        ovector = pcre2_get_ovector_pointer(data);
    #else
        ovector = data;
        rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
                       0, options, ovector, ncaps * 3);
    #endif
    
        if (rc >= 0) {
            apr_size_t n = rc, i;
            if (n == 0 || n > nmatch)
                rc = n = nmatch; /* All capture slots were filled in */
            for (i = 0; i < n; i++) {
                pmatch[i].rm_so = ovector[i * 2];
                pmatch[i].rm_eo = ovector[i * 2 + 1];
            }
            for (; i < nmatch; i++)
                pmatch[i].rm_so = pmatch[i].rm_eo = -1;
            if (to_free) {
                free_match_data(data, ncaps);
            }
            return 0;
        }
        else {
            if (to_free) {
                free_match_data(data, ncaps);
            }
    #ifdef HAVE_PCRE2
            if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21)
                return AP_REG_INVARG;
    #endif
            switch (rc) {
            case PCREn(ERROR_NOMATCH):
                return AP_REG_NOMATCH;
            case PCREn(ERROR_NULL):
                return AP_REG_INVARG;
            case PCREn(ERROR_BADOPTION):
                return AP_REG_INVARG;
            case PCREn(ERROR_BADMAGIC):
                return AP_REG_INVARG;
            case PCREn(ERROR_NOMEMORY):
                return AP_REG_ESPACE;
    #if defined(HAVE_PCRE2) || defined(PCRE_ERROR_MATCHLIMIT)
            case PCREn(ERROR_MATCHLIMIT):
                return AP_REG_ESPACE;
    #endif
    #if defined(PCRE_ERROR_UNKNOWN_NODE)
            case PCRE_ERROR_UNKNOWN_NODE:
                return AP_REG_ASSERT;
    #endif
    #if defined(PCRE_ERROR_BADUTF8)
            case PCREn(ERROR_BADUTF8):
                return AP_REG_INVARG;
    #endif
    #if defined(PCRE_ERROR_BADUTF8_OFFSET)
            case PCREn(ERROR_BADUTF8_OFFSET):
                return AP_REG_INVARG;
    #endif
            default:
                return AP_REG_ASSERT;
            }
        }
    }
    
    AP_DECLARE(int) ap_regname(const ap_regex_t *preg,
                               apr_array_header_t *names, const char *prefix,
                               int upper)
    {
        char *nametable;
    
    #ifdef HAVE_PCRE2
        uint32_t namecount;
        uint32_t nameentrysize;
        uint32_t i;
        pcre2_pattern_info((const pcre2_code *)preg->re_pcre,
                           PCRE2_INFO_NAMECOUNT, &namecount);
        pcre2_pattern_info((const pcre2_code *)preg->re_pcre,
                           PCRE2_INFO_NAMEENTRYSIZE, &nameentrysize);
        pcre2_pattern_info((const pcre2_code *)preg->re_pcre,
                           PCRE2_INFO_NAMETABLE, &nametable);
    #else
        int namecount;
        int nameentrysize;
        int i;
        pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
                      PCRE_INFO_NAMECOUNT, &namecount);
        pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
                      PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
        pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
                      PCRE_INFO_NAMETABLE, &nametable);
    #endif
    
        for (i = 0; i < namecount; i++) {
            const char *offset = nametable + i * nameentrysize;
            int capture = ((offset[0] << 8) + offset[1]);
            while (names->nelts <= capture) {
                apr_array_push(names);
            }
            if (upper || prefix) {
                char *name = ((char **) names->elts)[capture] =
                        prefix ? apr_pstrcat(names->pool, prefix, offset + 2,
                                NULL) :
                                apr_pstrdup(names->pool, offset + 2);
                if (upper) {
                    ap_str_toupper(name);
                }
            }
            else {
                ((const char **)names->elts)[capture] = offset + 2;
            }
        }
    
        return namecount;
    }
    
    #endif /* PCRE_DUPNAMES defined */
    
    /* End of pcreposix.c */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/request.c�����������������������������������������������������������������������0000664�0001751�0001751�00000270025�14127563677�016014� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * @file  request.c
     * @brief functions to get and process requests
     *
     * @author 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"
    
    #include "ap_config.h"
    #include "ap_provider.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 "ap_expr.h"
    #include "mod_request.h"
    
    #include "mod_core.h"
    #include "mod_auth.h"
    
    #if APR_HAVE_STDARG_H
    #include <stdarg.h>
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(pre_translate_name)
        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(access_checker_ex)
        APR_HOOK_LINK(auth_checker)
        APR_HOOK_LINK(insert_filter)
        APR_HOOK_LINK(create_request)
        APR_HOOK_LINK(post_perdir_config)
        APR_HOOK_LINK(dirwalk_stat)
        APR_HOOK_LINK(force_authn)
    )
    
    AP_IMPLEMENT_HOOK_RUN_FIRST(int,pre_translate_name,
                                (request_rec *r), (r), DECLINED)
    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,access_checker_ex,
                              (request_rec *r), (r), 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)
    AP_IMPLEMENT_HOOK_RUN_ALL(int, post_perdir_config,
                              (request_rec *r), (r), OK, DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t,dirwalk_stat,
                                (apr_finfo_t *finfo, request_rec *r, apr_int32_t wanted),
                                (finfo, r, wanted), AP_DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int,force_authn,
                                (request_rec *r), (r), DECLINED)
    
    static int auth_internal_per_conf = 0;
    static int auth_internal_per_conf_hooks = 0;
    static int auth_internal_per_conf_providers = 0;
    
    
    static int decl_die(int status, const char *phase, request_rec *r)
    {
        if (status == DECLINED) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(00025)
                          "configuration error:  couldn't %s: %s", phase, r->uri);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                          "auth phase '%s' gave status %d: %s", phase,
                          status, r->uri);
            return status;
        }
    }
    
    AP_DECLARE(int) ap_some_authn_required(request_rec *r)
    {
        int access_status;
        char *olduser = r->user;
        int rv = FALSE;
    
        switch (ap_satisfies(r)) {
        case SATISFY_ALL:
        case SATISFY_NOSPEC:
            if ((access_status = ap_run_access_checker(r)) != OK) {
                break;
            }
    
            access_status = ap_run_access_checker_ex(r);
            if (access_status == DECLINED) {
                rv = TRUE;
            }
    
            break;
        case SATISFY_ANY:
            if ((access_status = ap_run_access_checker(r)) == OK) {
                break;
            }
    
            access_status = ap_run_access_checker_ex(r);
            if (access_status == DECLINED) {
                rv = TRUE;
            }
    
            break;
        }
    
        r->user = olduser;
        return rv;
    }
    
    static int walk_location_and_if(request_rec *r)
    {
        int access_status;
        core_dir_config *d;
    
        if ((access_status = ap_location_walk(r))) {
            return access_status;
        }
        if ((access_status = ap_if_walk(r))) {
            return access_status;
        }
    
        d = ap_get_core_module_config(r->per_dir_config);
        if (d->log)
            r->log = d->log;
    
        return OK;
    }
    
    /* 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 access_status = DECLINED;
        int file_req = (r->main && r->filename);
        core_server_config *sconf =
            ap_get_core_module_config(r->server->module_config);
        unsigned int normalize_flags;
    
        normalize_flags = AP_NORMALIZE_NOT_ABOVE_ROOT;
        if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { 
            normalize_flags |= AP_NORMALIZE_MERGE_SLASHES;
        }
        if (file_req) {
            /* File subrequests can have a relative path. */
            normalize_flags |= AP_NORMALIZE_ALLOW_RELATIVE;
        }
    
        if (r->parsed_uri.path) {
            /* Normalize: remove /./ and shrink /../ segments, plus
             * decode unreserved chars (first time only to avoid
             * double decoding after ap_unescape_url() below).
             */
            if (!ap_normalize_path(r->parsed_uri.path,
                                   normalize_flags |
                                   AP_NORMALIZE_DECODE_UNRESERVED)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10244)
                              "invalid URI path (%s)", r->unparsed_uri);
                return HTTP_BAD_REQUEST;
            }
        }
    
        /* 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 (pre_)translate_name kill the request.
         */
        if (!file_req) {
            ap_conf_vector_t *per_dir_config = r->per_dir_config;
    
            if ((access_status = walk_location_and_if(r))) {
                return access_status;
            }
    
            /* Let pre_translate_name hooks work with non-decoded URIs, and
             * eventually prevent further URI transformations (return DONE).
             */
            access_status = ap_run_pre_translate_name(r);
            if (ap_is_HTTP_ERROR(access_status)) {
                return access_status;
            }
    
            /* Throw away pre_trans only merging */
            r->per_dir_config = per_dir_config;
        }
    
        /* Ignore URL unescaping for translated URIs already */
        if (access_status != DONE && r->parsed_uri.path) {
            core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
            /* Unreserved chars were already decoded by ap_normalize_path() */
            unsigned int unescape_flags = AP_UNESCAPE_URL_KEEP_UNRESERVED;
            if (!d->allow_encoded_slashes) {
                unescape_flags |= AP_UNESCAPE_URL_FORBID_SLASHES;
            }
            else if (!d->decode_encoded_slashes) {
                unescape_flags |= AP_UNESCAPE_URL_KEEP_SLASHES;
            }
            access_status = ap_unescape_url_ex(r->parsed_uri.path, unescape_flags);
            if (access_status) {
                if (access_status == HTTP_NOT_FOUND) {
                    if (! d->allow_encoded_slashes) {
                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00026)
                                      "found %%2f (encoded '/') in URI path (%s), "
                                      "returning 404", r->unparsed_uri);
                    }
                }
                return access_status;
            }
    
            if (d->allow_encoded_slashes && d->decode_encoded_slashes) {
                /* Decoding slashes might have created new // or /./ or /../
                 * segments (e.g. "/.%2F/"), so re-normalize.
                 */
                ap_normalize_path(r->parsed_uri.path, normalize_flags);
            }
        }
    
        /* Same, translate_name is not suited for file subrequests */
        if (!file_req) {
            if ((access_status = walk_location_and_if(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;
        }
    
        /* Rerun the location walk, which overrides any map_to_storage config.
         */
        if ((access_status = walk_location_and_if(r))) {
            return access_status;
        }
    
        if ((access_status = ap_run_post_perdir_config(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->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 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 {
            /* A module using a confusing API (ap_get_basic_auth_pw) caused
            ** r->user to be filled out prior to check_authn hook. We treat
            ** it is inadvertent.
            */
            if (r->user && apr_table_get(r->notes, AP_GET_BASIC_AUTH_PW_NOTE)) { 
                r->user = NULL;
            }
    
            switch (ap_satisfies(r)) {
            case SATISFY_ALL:
            case SATISFY_NOSPEC:
                if ((access_status = ap_run_access_checker(r)) != OK) {
                    return decl_die(access_status,
                                    "check access (with Satisfy All)", r);
                }
    
                access_status = ap_run_access_checker_ex(r);
                if (access_status == DECLINED
                    || (access_status == OK && ap_run_force_authn(r) == OK)) {
                    if ((access_status = ap_run_check_user_id(r)) != OK) {
                        return decl_die(access_status, "check user", r);
                    }
                    if (r->user == NULL) {
                        /* don't let buggy authn module crash us in authz */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00027)
                                      "No authentication done but request not "
                                      "allowed without authentication for %s. "
                                      "Authentication not configured?",
                                      r->uri);
                        access_status = HTTP_INTERNAL_SERVER_ERROR;
                        return decl_die(access_status, "check user", r);
                    }
                    if ((access_status = ap_run_auth_checker(r)) != OK) {
                        return decl_die(access_status, "check authorization", r);
                    }
                }
                else if (access_status == OK) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                                  "request authorized without authentication by "
                                  "access_checker_ex hook: %s", r->uri);
                }
                else {
                    return decl_die(access_status, "check access", r);
                }
                break;
            case SATISFY_ANY:
                if ((access_status = ap_run_access_checker(r)) == OK) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                                  "request authorized without authentication by "
                                  "access_checker hook and 'Satisfy any': %s",
                                  r->uri);
                    break;
                }
    
                access_status = ap_run_access_checker_ex(r);
                if (access_status == DECLINED
                    || (access_status == OK && ap_run_force_authn(r) == OK)) {
                    if ((access_status = ap_run_check_user_id(r)) != OK) {
                        return decl_die(access_status, "check user", r);
                    }
                    if (r->user == NULL) {
                        /* don't let buggy authn module crash us in authz */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00028)
                                      "No authentication done but request not "
                                      "allowed without authentication for %s. "
                                      "Authentication not configured?",
                                      r->uri);
                        access_status = HTTP_INTERNAL_SERVER_ERROR;
                        return decl_die(access_status, "check user", r);
                    }
                    if ((access_status = ap_run_auth_checker(r)) != OK) {
                        return decl_die(access_status, "check authorization", r);
                    }
                }
                else if (access_status == OK) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
                                  "request authorized without authentication by "
                                  "access_checker_ex hook: %s", r->uri);
                }
                else {
                    return decl_die(access_status, "check access", 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)) != OK) {
            return decl_die(access_status, "find types", r);
        }
    
        if ((access_status = ap_run_fixups(r)) != OK) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "fixups hook gave %d: %s",
                          access_status, r->uri);
            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 */
        struct walk_cache_t *prev; /* Prev cache of same call in this (sub)req */
        int count; /* Number of prev invocations of same call in this (sub)req */
    } walk_cache_t;
    
    static walk_cache_t *prep_walk_cache(apr_size_t t, request_rec *r)
    {
        void **note, **inherit_note;
        walk_cache_t *cache, *prev_cache, *copy_cache;
        int count;
    
        /* Find the most relevant, recent walk cache to work from and provide
         * a copy the caller is allowed to munge.  In the case of a sub-request
         * or internal redirect, this is the cache corresponding to the equivalent
         * invocation of the same function call in the "parent" request, if such
         * a cache exists.  Otherwise it is the walk cache of the previous
         * invocation of the same function call in the current request, if
         * that exists; if not, then create a new walk cache.
         */
        note = ap_get_request_note(r, t);
        AP_DEBUG_ASSERT(note != NULL);
    
        copy_cache = prev_cache = *note;
        count = prev_cache ? (prev_cache->count + 1) : 0;
    
        if ((r->prev
             && (inherit_note = ap_get_request_note(r->prev, t))
             && *inherit_note)
            || (r->main
                && (inherit_note = ap_get_request_note(r->main, t))
                && *inherit_note)) {
            walk_cache_t *inherit_cache = *inherit_note;
    
            while (inherit_cache->count > count) {
                inherit_cache = inherit_cache->prev;
            }
            if (inherit_cache->count == count) {
                copy_cache = inherit_cache;
            }
        }
    
        if (copy_cache) {
            cache = apr_pmemdup(r->pool, copy_cache, sizeof(*cache));
            cache->walked = apr_array_copy(r->pool, cache->walked);
            cache->prev = prev_cache;
            cache->count = count;
        }
        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;
        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 OPT_SYM_OWNER is unset, we only need to check target accessible */
        if (!(opts & OPT_SYM_OWNER)) {
            if (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 (apr_stat(lfi, d, lfi->valid | APR_FINFO_LINK | APR_FINFO_OWNER, p)
                != APR_SUCCESS)
            {
                return HTTP_FORBIDDEN;
            }
        }
    
        if (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;
            apr_table_t *override_list;
    } 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_core_module_config(sec);
    
        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;
            opts->override_opts = this_dir->override_opts;
        }
    
        if (this_dir->override_list != NULL) {
            opts->override_list = this_dir->override_list;
        }
    }
    
    
    /*****************************************************************
     *
     * 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_core_module_config(r->server->module_config);
        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;
        int cached;
    
        /* 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, APLOGNO(00029)
                          "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, APLOGNO(00030)
                          "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);
        cached = (cache->cached != NULL);
    
        /* 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 == APR_NOFILE || r->finfo.filetype == APR_LNK) {
            rv = ap_run_dirwalk_stat(&r->finfo, r, APR_FINFO_MIN);
    
            /* 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 != APR_NOFILE &&
                 (r->finfo.filetype != APR_DIR) &&
                 (r->filename[strlen(r->filename) - 1] == '/'))) {
                 r->finfo.filetype = APR_NOFILE; /* 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 (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)) {
            int familiar = 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) {
                familiar = 1;
            }
    
            if (r->per_dir_config == cache->dir_conf_merged) {
                r->per_dir_config = cache->per_dir_result;
                familiar = 1;
            }
    
            if (familiar) {
                apr_finfo_t thisinfo;
                int res;
                allow_options_t opts;
                core_dir_config *this_dir;
    
                this_dir = ap_get_core_module_config(r->per_dir_config);
                opts = this_dir->opts;
                /*
                 * If Symlinks are allowed in general we do not need the following
                 * check.
                 */
                if (!(opts & OPT_SYM_LINKS)) {
                    rv = ap_run_dirwalk_stat(&thisinfo, r,
                                             APR_FINFO_MIN | APR_FINFO_NAME | APR_FINFO_LINK);
                    /*
                     * APR_INCOMPLETE is as fine as result as APR_SUCCESS as we
                     * have added APR_FINFO_NAME to the wanted parameter of
                     * apr_stat above. On Unix platforms this means that apr_stat
                     * is always going to return APR_INCOMPLETE in the case that
                     * the call to the native stat / lstat did not fail.
                     */
                    if ((rv != APR_INCOMPLETE) && (rv != APR_SUCCESS)) {
                        /*
                         * This should never happen, because we did a stat on the
                         * same file, resolving a possible symlink several lines
                         * above. Therefore do not make a detailed analysis of rv
                         * in this case for the reason of the failure, just bail out
                         * with a HTTP_FORBIDDEN in case we hit a race condition
                         * here.
                         */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00031)
                                      "access to %s failed; stat of '%s' failed.",
                                      r->uri, r->filename);
                        return r->status = HTTP_FORBIDDEN;
                    }
                    if (thisinfo.filetype == APR_LNK) {
                        /* Is this a possibly acceptable symlink? */
                        if ((res = resolve_symlink(r->filename, &thisinfo,
                                                   opts, r->pool)) != OK) {
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00032)
                                          "Symbolic link not allowed "
                                          "or link target not accessible: %s",
                                          r->filename);
                            return r->status = res;
                        }
                    }
                }
                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;
            int cached_matches = matches;
            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;
            apr_pool_t *rxpool = NULL;
    
            /* 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
    
            cached &= auth_internal_per_conf;
    
            /*
             * 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_core_module_config(r->per_dir_config);
            opts.opts = this_dir->opts;
            opts.add = this_dir->opts_add;
            opts.remove = this_dir->opts_remove;
            opts.override = this_dir->override;
            opts.override_opts = this_dir->override_opts;
            opts.override_list = this_dir->override_list;
    
            /* 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 definition, 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, APLOGNO(00033)
                                  "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, APLOGNO(00034)
                              "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 <Directory> 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_core_module_config(entry_config);
    
                    /* 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
                     * <Directory >, and <Directory "/"> 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;
                        cached = 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 
                        && apr_is_empty_table(opts.override_list)
                        )) {
                        break;
                    }
    
    
                    res = ap_parse_htaccess(&htaccess_conf, r, opts.override,
                                            opts.override_opts, opts.override_list,
                                            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;
                        cached = 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) {
                    apr_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 {
                    apr_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 != APR_NOFILE
    #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 = ap_run_dirwalk_stat(&thisinfo, r,
                                         APR_FINFO_MIN | APR_FINFO_NAME | APR_FINFO_LINK);
    
                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, APLOGNO(00035)
                                  "access to %s denied (filesystem path '%s') "
                                  "because search permissions are missing on a "
                                  "component of the path", r->uri, r->filename);
                    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, APLOGNO(00036)
                                  "access to %s failed (filesystem path '%s')", 
                                  r->uri, r->filename);
                    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, APLOGNO(00037)
                                      "Symbolic link not allowed "
                                      "or link target not accessible: %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, APLOGNO(00038)
                                  "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 == APR_NOFILE || 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) {
    
                int nmatch = 0;
                int i;
                ap_regmatch_t *pmatch = NULL;
    
                core_dir_config *entry_core;
                entry_core = ap_get_core_module_config(sec_ent[sec_idx]);
    
                if (!entry_core->r) {
                    continue;
                }
    
                if (entry_core->refs && entry_core->refs->nelts) {
                    if (!rxpool) {
                        apr_pool_create(&rxpool, r->pool);
                        apr_pool_tag(rxpool, "directory_walk_rxpool");
                    }
                    nmatch = entry_core->refs->nelts;
                    pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
                }
    
                if (ap_regexec(entry_core->r, r->filename, nmatch, pmatch, 0)) {
                    continue;
                }
    
                for (i = 0; i < nmatch; i++) {
                    if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 &&
                        ((const char **)entry_core->refs->elts)[i]) {
                        apr_table_setn(r->subprocess_env, 
                                       ((const char **)entry_core->refs->elts)[i],
                                       apr_pstrndup(r->pool,
                                       r->filename + pmatch[i].rm_so,
                                       pmatch[i].rm_eo - pmatch[i].rm_so));
                    }
                }
    
                /* 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;
                    cached = 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 (rxpool) {
                apr_pool_destroy(rxpool);
            }
    
            /* Whoops - everything matched in sequence, but either the original
             * walk found some additional matches (which we need to truncate), or
             * this walk found some additional matches.
             */
            if (matches) {
                cache->walked->nelts -= matches;
                cached = 0;
            }
            else if (cache->walked->nelts > cached_matches) {
                cached = 0;
            }
        }
    
    /* 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 = apr_pstrdup(r->pool, r->filename);
        }
        else {
            cache->cached = ap_make_dirstr_parent(r->pool, r->filename);
        }
    
        if (cached
            && r->per_dir_config == cache->dir_conf_merged) {
            r->per_dir_config = cache->per_dir_result;
            return OK;
        }
    
        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_core_module_config(r->server->module_config);
        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;
        int cached;
    
        /* No tricks here, there are no <Locations > to parse in this vhost.
         * We won't destroy the cache, just in case _this_ redirect is later
         * redirected again to a vhost with <Location > blocks to optimize.
         */
        if (!num_sec) {
            return OK;
        }
    
        cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r);
        cached = (cache->cached != NULL);
    
       /*
        * When merge_slashes is set to AP_CORE_CONFIG_OFF the slashes in r->uri
        * have not been merged. But for Location walks we always go with merged
        * slashes no matter what merge_slashes is set to.
        */
        if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) {
            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 (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 (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;
            int cached_matches = matches;
            walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
            apr_pool_t *rxpool = NULL;
    
            cached &= auth_internal_per_conf;
            cache->cached = apr_pstrdup(r->pool, 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_core_module_config(sec_ent[sec_idx]);
    
                /* ### 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 <Location > 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) {
    
                    int nmatch = 0;
                    int i;
                    ap_regmatch_t *pmatch = NULL;
    
                    if (entry_core->refs && entry_core->refs->nelts) {
                        if (!rxpool) {
                            apr_pool_create(&rxpool, r->pool);
                            apr_pool_tag(rxpool, "location_walk_rxpool");
                        }
                        nmatch = entry_core->refs->nelts;
                        pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
                    }
    
                    if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) {
                        continue;
                    }
    
                    for (i = 0; i < nmatch; i++) {
                        if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 && 
                            ((const char **)entry_core->refs->elts)[i]) {
                            apr_table_setn(r->subprocess_env,
                                           ((const char **)entry_core->refs->elts)[i],
                                           apr_pstrndup(r->pool,
                                           r->uri + pmatch[i].rm_so,
                                           pmatch[i].rm_eo - pmatch[i].rm_so));
                        }
                    }
    
                }
                else {
    
                    if ((entry_core->d_is_fnmatch
                       ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
                       : (strncmp(entry_core->d, cache->cached, len)
                          || (len > 0
                              && 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;
                    cached = 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 (rxpool) {
                apr_pool_destroy(rxpool);
            }
    
            /* Whoops - everything matched in sequence, but either the original
             * walk found some additional matches (which we need to truncate), or
             * this walk found some additional matches.
             */
            if (matches) {
                cache->walked->nelts -= matches;
                cached = 0;
            }
            else if (cache->walked->nelts > cached_matches) {
                cached = 0;
            }
        }
    
        if (cached
            && r->per_dir_config == cache->dir_conf_merged) {
            r->per_dir_config = cache->per_dir_result;
            return OK;
        }
    
        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_core_module_config(r->per_dir_config);
        ap_conf_vector_t **sec_ent = NULL;
        int num_sec = 0;
        walk_cache_t *cache;
        const char *test_file;
        int cached;
    
        if (dconf->sec_file) {
            sec_ent = (ap_conf_vector_t **)dconf->sec_file->elts;
            num_sec = dconf->sec_file->nelts;
        }
    
        /* 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;
        }
    
        /* No tricks here, there are just no <Files > 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 <Files >.
         */
        if (!num_sec) {
            return OK;
        }
    
        cache = prep_walk_cache(AP_NOTE_FILE_WALK, r);
        cached = (cache->cached != NULL);
    
        /* 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 (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 (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;
            int cached_matches = matches;
            walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
            apr_pool_t *rxpool = NULL;
    
            cached &= auth_internal_per_conf;
            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_core_module_config(sec_ent[sec_idx]);
    
                if (entry_core->r) {
    
                    int nmatch = 0;
                    int i;
                    ap_regmatch_t *pmatch = NULL;
    
                    if (entry_core->refs && entry_core->refs->nelts) {
                        if (!rxpool) {
                            apr_pool_create(&rxpool, r->pool);
                            apr_pool_tag(rxpool, "file_walk_rxpool");
                        }
                        nmatch = entry_core->refs->nelts;
                        pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
                    }
    
                    if (ap_regexec(entry_core->r, cache->cached, nmatch, pmatch, 0)) {
                        continue;
                    }
    
                    for (i = 0; i < nmatch; i++) {
                        if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 && 
                            ((const char **)entry_core->refs->elts)[i]) {
                            apr_table_setn(r->subprocess_env,
                                           ((const char **)entry_core->refs->elts)[i],
                                           apr_pstrndup(r->pool,
                                           cache->cached + pmatch[i].rm_so,
                                           pmatch[i].rm_eo - pmatch[i].rm_so));
                        }
                    }
    
                }
                else {
                    if ((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;
                    cached = 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 (rxpool) {
                apr_pool_destroy(rxpool);
            }
    
            /* Whoops - everything matched in sequence, but either the original
             * walk found some additional matches (which we need to truncate), or
             * this walk found some additional matches.
             */
            if (matches) {
                cache->walked->nelts -= matches;
                cached = 0;
            }
            else if (cache->walked->nelts > cached_matches) {
                cached = 0;
            }
        }
    
        if (cached
            && r->per_dir_config == cache->dir_conf_merged) {
            r->per_dir_config = cache->per_dir_result;
            return OK;
        }
    
        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;
    }
    
    static int ap_if_walk_sub(request_rec *r, core_dir_config* dconf)
    {
        ap_conf_vector_t *now_merged = NULL;
        ap_conf_vector_t **sec_ent = NULL;
        int num_sec = 0;
        walk_cache_t *cache;
        int cached;
        int sec_idx;
        int matches;
        int cached_matches;
        int prev_result = -1;
        walk_walked_t *last_walk;
    
        if (dconf && dconf->sec_if) {
            sec_ent = (ap_conf_vector_t **)dconf->sec_if->elts;
            num_sec = dconf->sec_if->nelts;
        }
    
        /* No tricks here, there are just no <If > 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 >.
         */
        if (!num_sec) {
            return OK;
        }
    
        cache = prep_walk_cache(AP_NOTE_IF_WALK, r);
        cached = (cache->cached != NULL);
        cache->cached = (void *)1;
        matches = cache->walked->nelts;
        cached_matches = matches;
        last_walk = (walk_walked_t*)cache->walked->elts;
    
        cached &= auth_internal_per_conf;
    
        /* Go through the if entries, and check for matches  */
        for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) {
            const char *err = NULL;
            core_dir_config *entry_core;
            int rc;
            entry_core = ap_get_core_module_config(sec_ent[sec_idx]);
    
            AP_DEBUG_ASSERT(entry_core->condition_ifelse != 0);
            if (entry_core->condition_ifelse & AP_CONDITION_ELSE) {
                AP_DEBUG_ASSERT(prev_result != -1);
                if (prev_result == 1)
                    continue;
            }
    
            if (entry_core->condition_ifelse & AP_CONDITION_IF) {
                rc = ap_expr_exec(r, entry_core->condition, &err);
                if (rc <= 0) {
                    if (rc < 0)
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00039)
                                      "Failed to evaluate <If > condition: %s",
                                      err);
                    prev_result = 0;
                    continue;
                }
                prev_result = 1;
            }
            else {
                prev_result = -1;
            }
    
            /* 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;
                cached = 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;
        }
    
        /* Everything matched in sequence, but it may be that the original
         * walk found some additional matches (which we need to truncate), or
         * this walk found some additional matches.
         */
        if (matches) {
            cache->walked->nelts -= matches;
            cached = 0;
        }
        else if (cache->walked->nelts > cached_matches) {
            cached = 0;
        }
    
        if (cached
            && r->per_dir_config == cache->dir_conf_merged) {
            r->per_dir_config = cache->per_dir_result;
            return OK;
        }
    
        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;
    
        if (now_merged) {
            core_dir_config *dconf_merged = ap_get_core_module_config(now_merged);
    
            /* Allow nested <If>s and their configs to get merged
             * with the current one.
             */
            return ap_if_walk_sub(r, dconf_merged);
        }
    
        return OK;
    }
    
    AP_DECLARE(int) ap_if_walk(request_rec *r)
    {
        core_dir_config *dconf = ap_get_core_module_config(r->per_dir_config);
        int status = ap_if_walk_sub(r, dconf);
        return status;
    }
    
    /*****************************************************************
     *
     * 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->log            = r->log;
    
        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) {
            ap_filter_t *scan = 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;
            while (scan && (scan != r->proto_output_filters)) {
                if (scan->frec == ap_subreq_core_filter_handle) {
                    break;
                }
                scan = scan->next;
            }
            if (!scan || scan == 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;
        }
    
        rnew->useragent_addr = r->useragent_addr;
        rnew->useragent_ip = r->useragent_ip;
    
        /* 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);
    
        /* Begin by presuming any module can make its own path_info assumptions,
         * until some module interjects and changes the value.
         */
        rnew->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
    
        /* Pass on the kept body (if any) into the new request. */
        rnew->kept_body = r->kept_body;
    
        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;
    }
    
    extern APR_OPTIONAL_FN_TYPE(authz_some_auth_required) *ap__authz_ap_some_auth_required;
    
    AP_DECLARE(int) ap_some_auth_required(request_rec *r)
    {
        /* Is there a require line configured for the type of *this* req? */
        if (ap__authz_ap_some_auth_required) {
            return ap__authz_ap_some_auth_required(r);
        }
        else
            return 0;
    }
    
    AP_DECLARE(void) ap_clear_auth_internal(void)
    {
        auth_internal_per_conf_hooks = 0;
        auth_internal_per_conf_providers = 0;
    }
    
    AP_DECLARE(void) ap_setup_auth_internal(apr_pool_t *ptemp)
    {
        int total_auth_hooks = 0;
        int total_auth_providers = 0;
    
        auth_internal_per_conf = 0;
    
        if (_hooks.link_access_checker) {
            total_auth_hooks += _hooks.link_access_checker->nelts;
        }
        if (_hooks.link_access_checker_ex) {
            total_auth_hooks += _hooks.link_access_checker_ex->nelts;
        }
        if (_hooks.link_check_user_id) {
            total_auth_hooks += _hooks.link_check_user_id->nelts;
        }
        if (_hooks.link_auth_checker) {
            total_auth_hooks += _hooks.link_auth_checker->nelts;
        }
    
        if (total_auth_hooks > auth_internal_per_conf_hooks) {
            return;
        }
    
        total_auth_providers +=
            ap_list_provider_names(ptemp, AUTHN_PROVIDER_GROUP,
                                   AUTHN_PROVIDER_VERSION)->nelts;
        total_auth_providers +=
            ap_list_provider_names(ptemp, AUTHZ_PROVIDER_GROUP,
                                   AUTHZ_PROVIDER_VERSION)->nelts;
    
        if (total_auth_providers > auth_internal_per_conf_providers) {
            return;
        }
    
        auth_internal_per_conf = 1;
    }
    
    AP_DECLARE(apr_status_t) ap_register_auth_provider(apr_pool_t *pool,
                                                       const char *provider_group,
                                                       const char *provider_name,
                                                       const char *provider_version,
                                                       const void *provider,
                                                       int type)
    {
        if ((type & AP_AUTH_INTERNAL_MASK) == AP_AUTH_INTERNAL_PER_CONF) {
            ++auth_internal_per_conf_providers;
        }
    
        return ap_register_provider(pool, provider_group, provider_name,
                                    provider_version, provider);
    }
    
    AP_DECLARE(void) ap_hook_check_access(ap_HOOK_access_checker_t *pf,
                                          const char * const *aszPre,
                                          const char * const *aszSucc,
                                          int nOrder, int type)
    {
        if ((type & AP_AUTH_INTERNAL_MASK) == AP_AUTH_INTERNAL_PER_CONF) {
            ++auth_internal_per_conf_hooks;
        }
    
        ap_hook_access_checker(pf, aszPre, aszSucc, nOrder);
    }
    
    AP_DECLARE(void) ap_hook_check_access_ex(ap_HOOK_access_checker_ex_t *pf,
                                          const char * const *aszPre,
                                          const char * const *aszSucc,
                                          int nOrder, int type)
    {
        if ((type & AP_AUTH_INTERNAL_MASK) == AP_AUTH_INTERNAL_PER_CONF) {
            ++auth_internal_per_conf_hooks;
        }
    
        ap_hook_access_checker_ex(pf, aszPre, aszSucc, nOrder);
    }
    
    AP_DECLARE(void) ap_hook_check_authn(ap_HOOK_check_user_id_t *pf,
                                         const char * const *aszPre,
                                         const char * const *aszSucc,
                                         int nOrder, int type)
    {
        if ((type & AP_AUTH_INTERNAL_MASK) == AP_AUTH_INTERNAL_PER_CONF) {
            ++auth_internal_per_conf_hooks;
        }
    
        ap_hook_check_user_id(pf, aszPre, aszSucc, nOrder);
    }
    
    AP_DECLARE(void) ap_hook_check_authz(ap_HOOK_auth_checker_t *pf,
                                         const char * const *aszPre,
                                         const char * const *aszSucc,
                                         int nOrder, int type)
    {
        if ((type & AP_AUTH_INTERNAL_MASK) == AP_AUTH_INTERNAL_PER_CONF) {
            ++auth_internal_per_conf_hooks;
        }
    
        ap_hook_auth_checker(pf, aszPre, aszSucc, nOrder);
    }
    
    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;
        /* Initialise res, to avoid a gcc warning */
        int res = HTTP_INTERNAL_SERVER_ERROR;
        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.
         *
         * If next_filter is NULL we are expecting to be
         * internal_fast_redirect'ed to the subrequest, or the subrequest will
         * never be invoked. We need to make sure that the quickhandler is not
         * invoked by any lookups. Since an internal_fast_redirect will always
         * occur too late for the quickhandler to handle the request.
         */
        if (next_filter) {
            res = ap_run_quick_handler(rnew, 1);
        }
    
        if (next_filter == NULL || 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 = APR_NOFILE;
                }
            }
            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 = APR_NOFILE;
                }
            }
        }
        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.
             */
            strcat(rnew->filename, "/");
            if (!rnew->path_info || !*rnew->path_info) {
                strcat(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 = APR_NOFILE;
                }
            }
            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 = APR_NOFILE;
                }
            }
    
            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 != APR_NOFILE)) {
            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 */
    }
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm_fdqueue.h�������������������������������������������������������������������0000664�0001751�0001751�00000010265�14104431754�016617� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  server/mpm_fdqueue.h
     * @brief fd queue declarations
     *
     * @addtogroup APACHE_MPM_EVENT
     * @{
     */
    
    #ifndef MPM_FDQUEUE_H
    #define MPM_FDQUEUE_H
    
    #include <apr.h>
    
    /* This code is not AP_DECLARE()ed/exported, and used by MPMs event/worker
     * only (for now), not worth thinking about w/o threads either...
     */
    #if APR_HAS_THREADS
    
    #include "ap_mpm.h"
    
    #include <apr_ring.h>
    #include <apr_pools.h>
    #include <apr_thread_mutex.h>
    #include <apr_thread_cond.h>
    #include <apr_network_io.h>
    
    struct fd_queue_info_t; /* opaque */
    struct fd_queue_elem_t; /* opaque */
    typedef struct fd_queue_info_t fd_queue_info_t;
    typedef struct fd_queue_elem_t fd_queue_elem_t;
    
    AP_DECLARE(apr_status_t) ap_queue_info_create(fd_queue_info_t **queue_info,
                                                  apr_pool_t *pool, int max_idlers,
                                                  int max_recycled_pools);
    AP_DECLARE(apr_status_t) ap_queue_info_set_idle(fd_queue_info_t *queue_info,
                                                    apr_pool_t *pool_to_recycle);
    AP_DECLARE(apr_status_t) ap_queue_info_try_get_idler(fd_queue_info_t *queue_info);
    AP_DECLARE(apr_status_t) ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info,
                                                          int *had_to_block);
    AP_DECLARE(apr_uint32_t) ap_queue_info_num_idlers(fd_queue_info_t *queue_info);
    AP_DECLARE(apr_status_t) ap_queue_info_term(fd_queue_info_t *queue_info);
    
    AP_DECLARE(void) ap_queue_info_pop_pool(fd_queue_info_t *queue_info,
                                            apr_pool_t **recycled_pool);
    AP_DECLARE(void) ap_queue_info_push_pool(fd_queue_info_t *queue_info,
                                             apr_pool_t *pool_to_recycle);
    AP_DECLARE(void) ap_queue_info_free_idle_pools(fd_queue_info_t *queue_info);
    
    struct timer_event_t
    {
        APR_RING_ENTRY(timer_event_t) link;
        apr_time_t when;
        ap_mpm_callback_fn_t *cbfunc;
        void *baton;
        int canceled;
        apr_array_header_t *remove;
    };
    typedef struct timer_event_t timer_event_t;
    
    struct fd_queue_t
    {
        APR_RING_HEAD(timers_t, timer_event_t) timers;
        fd_queue_elem_t *data;
        unsigned int nelts;
        unsigned int bounds;
        unsigned int in;
        unsigned int out;
        apr_thread_mutex_t *one_big_mutex;
        apr_thread_cond_t *not_empty;
        volatile int terminated;
    };
    typedef struct fd_queue_t fd_queue_t;
    
    AP_DECLARE(apr_status_t) ap_queue_create(fd_queue_t **pqueue,
                                             int capacity, apr_pool_t *p);
    AP_DECLARE(apr_status_t) ap_queue_push_socket(fd_queue_t *queue,
                                                  apr_socket_t *sd, void *sd_baton,
                                                  apr_pool_t *p);
    AP_DECLARE(apr_status_t) ap_queue_push_timer(fd_queue_t *queue,
                                                 timer_event_t *te);
    AP_DECLARE(apr_status_t) ap_queue_pop_something(fd_queue_t *queue,
                                                    apr_socket_t **sd, void **sd_baton,
                                                    apr_pool_t **p, timer_event_t **te);
    #define                  ap_queue_pop_socket(q_, s_, p_) \
                                ap_queue_pop_something((q_), (s_), NULL, (p_), NULL)
    
    AP_DECLARE(apr_status_t) ap_queue_interrupt_all(fd_queue_t *queue);
    AP_DECLARE(apr_status_t) ap_queue_interrupt_one(fd_queue_t *queue);
    AP_DECLARE(apr_status_t) ap_queue_term(fd_queue_t *queue);
    
    #endif /* APR_HAS_THREADS */
    
    #endif /* MPM_FDQUEUE_H */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_regex.c��������������������������������������������������������������������0000664�0001751�0001751�00000015721�13623224567�016463� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_pools.h"
    #include "apr_strings.h"
    #include "ap_config.h"
    #include "ap_regex.h"
    #include "httpd.h"
    
    static apr_status_t rxplus_cleanup(void *preg)
    {
        ap_regfree((ap_regex_t *) preg);
        return APR_SUCCESS;
    }
    
    AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool,
                                               const char *pattern)
    {
        /* perl style patterns
         * add support for more as and when wanted
         * substitute: s/rx/subs/
         * match: m/rx/ or just /rx/
         */
    
        /* allow any nonalnum delimiter as first or second char.
         * If we ever use this with non-string pattern we'll need an extra check
         */
        const char *endp = 0;
        const char *str = pattern;
        const char *rxstr;
        ap_rxplus_t *ret = apr_pcalloc(pool, sizeof(ap_rxplus_t));
        char delim = 0;
        enum { SUBSTITUTE = 's', MATCH = 'm'} action = MATCH;
    
        if (!apr_isalnum(pattern[0])) {
            delim = *str++;
        }
        else if (pattern[0] == 's' && !apr_isalnum(pattern[1])) {
            action = SUBSTITUTE;
            delim = pattern[1];
            str += 2;
        }
        else if (pattern[0] == 'm' && !apr_isalnum(pattern[1])) {
            delim = pattern[1];
            str += 2;
        }
        /* TODO: support perl's after/before */
        /* FIXME: fix these simplminded delims */
    
        /* we think there's a delimiter.  Allow for it not to be if unmatched */
        if (delim) {
            endp = ap_strchr_c(str, delim);
        }
        if (!endp) { /* there's no delim or flags */
            if (ap_regcomp(&ret->rx, pattern, 0) == 0) {
                apr_pool_cleanup_register(pool, &ret->rx, rxplus_cleanup,
                                          apr_pool_cleanup_null);
                return ret;
            }
            else {
                return NULL;
            }
        }
    
        /* We have a delimiter.  Use it to extract the regexp */
        rxstr = apr_pstrmemdup(pool, str, endp-str);
    
        /* If it's a substitution, we need the replacement string
         * TODO: possible future enhancement - support other parsing
         * in the replacement string.
         */
        if (action == SUBSTITUTE) {
            str = endp+1;
            if (!*str || (endp = ap_strchr_c(str, delim), !endp)) {
                /* missing replacement string is an error */
                return NULL;
            }
            ret->subs = apr_pstrmemdup(pool, str, endp-str);
        }
    
        /* anything after the current delimiter is flags */
        ret->flags = ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY;
        while (*++endp) {
            switch (*endp) {
            case 'i': ret->flags |= AP_REG_ICASE; break;
            case 'm': ret->flags |= AP_REG_NEWLINE; break;
            case 'n': ret->flags |= AP_REG_NOMEM; break;
            case 'g': ret->flags |= AP_REG_MULTI; break;
            case 's': ret->flags |= AP_REG_DOTALL; break;
            case '^': ret->flags |= AP_REG_NOTBOL; break;
            case '$': ret->flags |= AP_REG_NOTEOL; break;
            default: break; /* we should probably be stricter here */
            }
        }
        if (ap_regcomp(&ret->rx, rxstr, AP_REG_NO_DEFAULT | ret->flags) == 0) {
            apr_pool_cleanup_register(pool, &ret->rx, rxplus_cleanup,
                                      apr_pool_cleanup_null);
        }
        else {
            return NULL;
        }
        if (!(ret->flags & AP_REG_NOMEM)) {
            /* count size of memory required, starting at 1 for the whole-match
             * Simpleminded should be fine 'cos regcomp already checked syntax
             */
            ret->nmatch = 1;
            while (*rxstr) {
                switch (*rxstr++) {
                case '\\':  /* next char is escaped - skip it */
                    if (*rxstr != 0) {
                        ++rxstr;
                    }
                    break;
                case '(':   /* unescaped bracket implies memory */
                    ++ret->nmatch;
                    break;
                default:
                    break;
                }
            }
            ret->pmatch = apr_palloc(pool, ret->nmatch*sizeof(ap_regmatch_t));
        }
        return ret;
    }
    
    AP_DECLARE(int) ap_rxplus_exec(apr_pool_t *pool, ap_rxplus_t *rx,
                                   const char *pattern, char **newpattern)
    {
        int ret = 1;
        int startl, oldl, newl, diffsz;
        const char *remainder;
        char *subs;
    /* snrf process_regexp from mod_headers */
        if (ap_regexec(&rx->rx, pattern, rx->nmatch, rx->pmatch, rx->flags) != 0) {
            rx->match = NULL;
            return 0; /* no match, nothing to do */
        }
        rx->match = pattern;
        if (rx->subs) {
            *newpattern = ap_pregsub(pool, rx->subs, pattern,
                                     rx->nmatch, rx->pmatch);
            if (!*newpattern) {
                return 0; /* FIXME - should we do more to handle error? */
            }
            startl = rx->pmatch[0].rm_so;
            oldl = rx->pmatch[0].rm_eo - startl;
            newl = strlen(*newpattern);
            diffsz = newl - oldl;
            remainder = pattern + startl + oldl;
            if (rx->flags & AP_REG_MULTI) {
                /* recurse to do any further matches */
                ret += ap_rxplus_exec(pool, rx, remainder, &subs);
                if (ret > 1) {
                    /* a further substitution happened */
                    diffsz += strlen(subs) - strlen(remainder);
                    remainder = subs;
                }
            }
            subs  = apr_palloc(pool, strlen(pattern) + 1 + diffsz);
            memcpy(subs, pattern, startl);
            memcpy(subs+startl, *newpattern, newl);
            strcpy(subs+startl+newl, remainder);
            *newpattern = subs;
        }
        return ret;
    }
    #ifdef DOXYGEN
    AP_DECLARE(int) ap_rxplus_nmatch(ap_rxplus_t *rx)
    {
        return (rx->match != NULL) ? rx->nmatch : 0;
    }
    #endif
    
    /* If this blows up on you, see the notes in the header/apidoc
     * rx->match is a pointer and it's your responsibility to ensure
     * it hasn't gone out-of-scope since the last ap_rxplus_exec
     */
    AP_DECLARE(void) ap_rxplus_match(ap_rxplus_t *rx, int n, int *len,
                                     const char **match)
    {
        if (n >= 0 && n < ap_rxplus_nmatch(rx)) {
            *match = rx->match + rx->pmatch[n].rm_so;
            *len = rx->pmatch[n].rm_eo - rx->pmatch[n].rm_so;
        }
        else {
            *len = -1;
            *match = NULL;
        }
    }
    AP_DECLARE(char*) ap_rxplus_pmatch(apr_pool_t *pool, ap_rxplus_t *rx, int n)
    {
        int len;
        const char *match;
        ap_rxplus_match(rx, n, &len, &match);
        return apr_pstrndup(pool, match, len);
    }
    �����������������������������������������������httpd-2.4.64/server/util_fcgi.c���������������������������������������������������������������������0000664�0001751�0001751�00000021612�13034776412�016252� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_core.h"
    #include "http_log.h"
    #include "util_fcgi.h"
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    AP_DECLARE(void) ap_fcgi_header_to_array(ap_fcgi_header *h,
                                             unsigned char a[])
    {
        a[AP_FCGI_HDR_VERSION_OFFSET]        = h->version;
        a[AP_FCGI_HDR_TYPE_OFFSET]           = h->type;
        a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET]  = h->requestIdB1;
        a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET]  = h->requestIdB0;
        a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET] = h->contentLengthB1;
        a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET] = h->contentLengthB0;
        a[AP_FCGI_HDR_PADDING_LEN_OFFSET]    = h->paddingLength;
        a[AP_FCGI_HDR_RESERVED_OFFSET]       = h->reserved;
    }
    
    AP_DECLARE(void) ap_fcgi_header_from_array(ap_fcgi_header *h,
                                               unsigned char a[])
    {
        h->version         = a[AP_FCGI_HDR_VERSION_OFFSET];
        h->type            = a[AP_FCGI_HDR_TYPE_OFFSET];
        h->requestIdB1     = a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET];
        h->requestIdB0     = a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET];
        h->contentLengthB1 = a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET];
        h->contentLengthB0 = a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET];
        h->paddingLength   = a[AP_FCGI_HDR_PADDING_LEN_OFFSET];
        h->reserved        = a[AP_FCGI_HDR_RESERVED_OFFSET];
    }
    
    AP_DECLARE(void) ap_fcgi_header_fields_from_array(unsigned char *version,
                                                      unsigned char *type,
                                                      apr_uint16_t *request_id,
                                                      apr_uint16_t *content_len,
                                                      unsigned char *padding_len,
                                                      unsigned char a[])
    {
        *version         = a[AP_FCGI_HDR_VERSION_OFFSET];
        *type            = a[AP_FCGI_HDR_TYPE_OFFSET];
        *request_id      = (a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET] << 8)
                         +  a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET];
        *content_len     = (a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET] << 8)
                         +  a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET];
        *padding_len     = a[AP_FCGI_HDR_PADDING_LEN_OFFSET];
    }
    
    AP_DECLARE(void) ap_fcgi_begin_request_body_to_array(ap_fcgi_begin_request_body *h,
                                                         unsigned char a[])
    {
        a[AP_FCGI_BRB_ROLEB1_OFFSET]    = h->roleB1;
        a[AP_FCGI_BRB_ROLEB0_OFFSET]    = h->roleB0;
        a[AP_FCGI_BRB_FLAGS_OFFSET]     = h->flags;
        a[AP_FCGI_BRB_RESERVED0_OFFSET] = h->reserved[0];
        a[AP_FCGI_BRB_RESERVED1_OFFSET] = h->reserved[1];
        a[AP_FCGI_BRB_RESERVED2_OFFSET] = h->reserved[2];
        a[AP_FCGI_BRB_RESERVED3_OFFSET] = h->reserved[3];
        a[AP_FCGI_BRB_RESERVED4_OFFSET] = h->reserved[4];
    }
    
    AP_DECLARE(void) ap_fcgi_fill_in_header(ap_fcgi_header *header,
                                            unsigned char type,
                                            apr_uint16_t request_id,
                                            apr_uint16_t content_len,
                                            unsigned char padding_len)
    {
        header->version = AP_FCGI_VERSION_1;
    
        header->type = type;
    
        header->requestIdB1 = ((request_id >> 8) & 0xff);
        header->requestIdB0 = ((request_id) & 0xff);
    
        header->contentLengthB1 = ((content_len >> 8) & 0xff);
        header->contentLengthB0 = ((content_len) & 0xff);
    
        header->paddingLength = padding_len;
    
        header->reserved = 0;
    }
    
    AP_DECLARE(void) ap_fcgi_fill_in_request_body(ap_fcgi_begin_request_body *brb,
                                                  int role,
                                                  unsigned char flags)
    {
        brb->roleB1 = ((role >> 8) & 0xff);
        brb->roleB0 = (role & 0xff);
        brb->flags = flags;
        brb->reserved[0] = 0;
        brb->reserved[1] = 0;
        brb->reserved[2] = 0;
        brb->reserved[3] = 0;
        brb->reserved[4] = 0;
    }
    
    AP_DECLARE(apr_size_t) ap_fcgi_encoded_env_len(apr_table_t *env,
                                                   apr_size_t maxlen,
                                                   int *starting_elem)
    {
        const apr_array_header_t *envarr;
        const apr_table_entry_t *elts;
        apr_size_t envlen, actualenvlen;
        int i;
    
        if (maxlen > AP_FCGI_MAX_CONTENT_LEN) {
            maxlen = AP_FCGI_MAX_CONTENT_LEN;
        }
    
        envarr = apr_table_elts(env);
        elts = (const apr_table_entry_t *) envarr->elts;
    
        /* envlen - speculative, may overflow the limit
         * actualenvlen - len required without overflowing
         */
        envlen = actualenvlen = 0;
        for (i = *starting_elem; i < envarr->nelts; ) {
            apr_size_t keylen, vallen;
    
            if (!elts[i].key) {
                (*starting_elem)++;
                i++;
                continue;
            }
    
            keylen = strlen(elts[i].key);
    
            if (keylen >> 7 == 0) {
                envlen += 1;
            }
            else {
                envlen += 4;
            }
    
            envlen += keylen;
    
            vallen = elts[i].val ? strlen(elts[i].val) : 0;
    
            if (vallen >> 7 == 0) {
                envlen += 1;
            }
            else {
                envlen += 4;
            }
    
            envlen += vallen;
    
            if (envlen > maxlen) {
                break;
            }
    
            actualenvlen = envlen;
            (*starting_elem)++;
            i++;
        }
    
        return actualenvlen;
    }
    
    AP_DECLARE(apr_status_t) ap_fcgi_encode_env(request_rec *r,
                                                apr_table_t *env,
                                                void *buffer,
                                                apr_size_t buflen,
                                                int *starting_elem)
    {
        apr_status_t rv = APR_SUCCESS;
        const apr_array_header_t *envarr;
        const apr_table_entry_t *elts;
        char *itr;
        int i;
    
        envarr = apr_table_elts(env);
        elts = (const apr_table_entry_t *) envarr->elts;
    
        itr = buffer;
    
        for (i = *starting_elem; i < envarr->nelts; ) {
            apr_size_t keylen, vallen;
    
            if (!elts[i].key) {
                (*starting_elem)++;
                i++;
                continue;
            }
    
            keylen = strlen(elts[i].key);
    
            if (keylen >> 7 == 0) {
                if (buflen < 1) {
                    rv = APR_ENOSPC; /* overflow */
                    break;
                }
                itr[0] = keylen & 0xff;
                itr += 1;
                buflen -= 1;
            }
            else {
                if (buflen < 4) {
                    rv = APR_ENOSPC; /* overflow */
                    break;
                }
                itr[0] = ((keylen >> 24) & 0xff) | 0x80;
                itr[1] = ((keylen >> 16) & 0xff);
                itr[2] = ((keylen >> 8) & 0xff);
                itr[3] = ((keylen) & 0xff);
                itr += 4;
                buflen -= 4;
            }
    
            vallen = elts[i].val ? strlen(elts[i].val) : 0;
    
            if (vallen >> 7 == 0) {
                if (buflen < 1) {
                    rv = APR_ENOSPC; /* overflow */
                    break;
                }
                itr[0] = vallen & 0xff;
                itr += 1;
                buflen -= 1;
            }
            else {
                if (buflen < 4) {
                    rv = APR_ENOSPC; /* overflow */
                    break;
                }
                itr[0] = ((vallen >> 24) & 0xff) | 0x80;
                itr[1] = ((vallen >> 16) & 0xff);
                itr[2] = ((vallen >> 8) & 0xff);
                itr[3] = ((vallen) & 0xff);
                itr += 4;
                buflen -= 4;
            }
    
            if (buflen < keylen) {
                rv = APR_ENOSPC; /* overflow */
                break;
            }
            memcpy(itr, elts[i].key, keylen);
            itr += keylen;
            buflen -= keylen;
    
            if (buflen < vallen) {
                rv = APR_ENOSPC; /* overflow */
                break;
            }
    
            if (elts[i].val) {
                memcpy(itr, elts[i].val, vallen);
                itr += vallen;
            }
    
            if (buflen == vallen) {
                (*starting_elem)++;
                i++;
                break; /* filled up predicted space, as expected */
            }
    
            buflen -= vallen;
    
            (*starting_elem)++;
            i++;
        }
    
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02492)
                          "ap_fcgi_encode_env: out of space "
                          "encoding environment");
        }
    
        return rv;
    }
    ����������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/error_bucket.c������������������������������������������������������������������0000664�0001751�0001751�00000004557�12532143363�016777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <strings.h>
    #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 = apr_pstrdup(p, buf);
    
        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;
        if (!ap_is_HTTP_VALID_RESPONSE(error)) {
            error = HTTP_INTERNAL_SERVER_ERROR;
        }
        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
    };
    �������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/protocol.c����������������������������������������������������������������������0000664�0001751�0001751�00000263444�14357263011�016154� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * 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"
    
    #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 <stdarg.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(pre_read_request)
        APR_HOOK_LINK(post_read_request)
        APR_HOOK_LINK(log_transaction)
        APR_HOOK_LINK(http_scheme)
        APR_HOOK_LINK(default_port)
        APR_HOOK_LINK(note_auth_failure)
        APR_HOOK_LINK(protocol_propose)
        APR_HOOK_LINK(protocol_switch)
        APR_HOOK_LINK(protocol_get)
    )
    
    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 or "", return NULL (do not set content-type).
     *    - 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_core_module_config(r->per_dir_config);
        core_request_config *request_conf;
        apr_size_t type_len;
    
        if (!type || *type == '\0') {
            return NULL;
        }
    
        if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) {
            return type;
        }
    
        request_conf = ap_get_core_module_config(r->request_config);
        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;
    }
    
    /* 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.
     * 
     * Pulls from r->proto_input_filters instead of r->input_filters for
     * stricter protocol adherence and better input filter behavior during
     * chunked trailer processing (for http).
     *
     * 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 [CR]LF are *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 flags, 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;
        int fold = flags & AP_GETLINE_FOLD;
        int crlf = flags & AP_GETLINE_CRLF;
        int nospc_eol = flags & AP_GETLINE_NOSPC_EOL;
        int saw_eol = 0, saw_nospc = 0;
    
        if (!n) {
            /* Needs room for NUL byte at least */
            *read = 0;
            return APR_BADARG;
        }
    
        /*
         * Initialize last_char as otherwise a random value will be compared
         * against APR_ASCII_LF at the end of the loop if bb only contains
         * zero-length buckets.
         */
        if (last_char)
            *last_char = '\0';
    
        do {
            apr_brigade_cleanup(bb);
            rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_GETLINE,
                                APR_BLOCK_READ, 0);
            if (rv != APR_SUCCESS) {
                goto cleanup;
            }
    
            /* Something horribly wrong happened.  Someone didn't block! 
             * (this also happens at the end of each keepalive connection)
             */
            if (APR_BRIGADE_EMPTY(bb)) {
                rv = APR_EGENERAL;
                goto cleanup;
            }
    
            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) {
                    goto cleanup;
                }
    
                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) {
                    /* Before we die, let's fill the buffer up to its limit (i.e.
                     * fall through with the remaining length, if any), setting
                     * saw_eol on LF to stop the outer loop appropriately; we may
                     * come back here once the buffer is filled (no LF seen), and
                     * either be done at that time or continue to wait for LF here
                     * if nospc_eol is set.
                     *
                     * But there is also a corner cases which we want to address,
                     * namely if the buffer is overrun by the final LF only (i.e.
                     * the CR fits in); this is not really an overrun since we'll
                     * strip the CR finally (and use it for NUL byte), but anyway
                     * we have to handle the case so that it's not returned to the
                     * caller as part of the truncated line (it's not!). This is
                     * easier to consider that LF is out of counting and thus fall
                     * through with no error (saw_eol is set to 2 so that we later
                     * ignore LF handling already done here), while folding and
                     * nospc_eol logics continue to work (or fail) appropriately.
                     */
                    saw_eol = (str[len - 1] == APR_ASCII_LF);
                    if (/* First time around */
                        saw_eol && !saw_nospc
                        /*  Single LF completing the buffered CR, */
                        && ((len == 1 && ((*s)[bytes_handled - 1] == APR_ASCII_CR))
                        /*  or trailing CRLF overuns by LF only */
                            || (len > 1 && str[len - 2] == APR_ASCII_CR
                                && n - bytes_handled + 1 == len))) {
                        /* In both cases *last_char is (to be) the CR stripped by
                         * later 'bytes_handled = last_char - *s'.
                         */
                        saw_eol = 2;
                    }
                    else {
                        /* In any other case we'd lose data. */
                        rv = APR_ENOSPC;
                        saw_nospc = 1;
                    }
                    len = n - bytes_handled;
                    if (!len) {
                        if (saw_eol) {
                            break;
                        }
                        if (nospc_eol) {
                            continue;
                        }
                        goto cleanup;
                    }
                }
    
                /* 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;
                        *s = apr_palloc(r->pool, current_alloc + 1);
                    }
                    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 + 1);
    
                        /* 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)) {
                saw_eol = 1;
            }
        } while (!saw_eol);
    
        if (rv != APR_SUCCESS) {
            /* End of line after APR_ENOSPC above */
            goto cleanup;
        }
    
        /* Now terminate the string at the end of the line;
         * if the last-but-one character is a CR, terminate there.
         * LF is handled above (not accounted) when saw_eol == 2,
         * the last char is CR to terminate at still.
         */
        if (saw_eol < 2) {
            if (last_char > *s && last_char[-1] == APR_ASCII_CR) {
                last_char--;
            }
            else if (crlf) {
                rv = APR_EINVAL;
                goto cleanup;
            }
        }
        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->proto_input_filters, bb, AP_MODE_SPECULATIVE,
                                    APR_BLOCK_READ, 1);
                if (rv != APR_SUCCESS) {
                    goto cleanup;
                }
    
                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);
                    goto cleanup;
                }
    
                /* 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) {
                        rv = APR_ENOSPC;
                        goto cleanup;
                    }
                    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 {
                            tmp = last_char;
                        }
    
                        next_size = n - bytes_handled;
    
                        rv = ap_rgetline_core(&tmp, next_size, &next_len, r,
                                              flags & ~AP_GETLINE_FOLD, bb);
                        if (rv != APR_SUCCESS) {
                            goto cleanup;
                        }
    
                        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);
                            *s = new_buffer;
                        }
    
                        last_char += next_len;
                        bytes_handled += next_len;
                    }
                }
                else { /* next character is not tab or space */
                    break;
                }
            }
        }
    
    cleanup:
        if (bytes_handled >= n) {
            bytes_handled = n - 1;
        }
    
        *read = bytes_handled;
        if (*s) {
            /* ensure the string is NUL terminated */
            (*s)[*read] = '\0';
    
            /* PR#43039: We shouldn't accept NULL bytes within the line */
            bytes_handled = strlen(*s);
            if (bytes_handled < *read) {
                ap_log_data(APLOG_MARK, APLOG_DEBUG, ap_server_conf,
                            "NULL bytes in header", *s, *read, 0);
                *read = bytes_handled;
                if (rv == APR_SUCCESS) {
                    rv = APR_EINVAL;
                }
            }
        }
        return rv;
    }
    
    #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 ensure 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 || APR_STATUS_IS_ENOSPC(rv)) {
            ap_xlate_proto_from_ascii(*s, *read);
        }
        return rv;
    }
    #endif
    
    AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int flags)
    {
        char *tmp_s = s;
        apr_status_t rv;
        apr_size_t len;
        apr_bucket_brigade *tmp_bb;
    
        if (n < 1) {
            /* Can't work since we always NUL terminate */
            return -1;
        }
    
        tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        rv = ap_rgetline(&tmp_s, n, &len, r, flags, 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 normalizing 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 {
            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
                && !ap_cstr_casecmp(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;
            if (r->parsed_uri.path) {
                r->uri = r->parsed_uri.path;
            }
            else if (r->method_number == M_OPTIONS) {
                r->uri = apr_pstrdup(r->pool, "*");
            }
            else {
                r->uri = 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);
        }
    }
    
    /* get the length of the field name for logging, but no more than 80 bytes */
    #define LOG_NAME_MAX_LEN 80
    static int field_name_len(const char *field)
    {
        const char *end = ap_strchr_c(field, ':');
        if (end == NULL || end - field > LOG_NAME_MAX_LEN)
            return LOG_NAME_MAX_LEN;
        return end - field;
    }
    
    static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
    {
        apr_size_t len;
        int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
        core_server_config *conf = ap_get_core_module_config(r->server->module_config);
        int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
    
        /* 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;
    
            /* ensure 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, strict ? AP_GETLINE_CRLF : 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 (APR_STATUS_IS_ENOSPC(rv)) {
                    r->status = HTTP_REQUEST_URI_TOO_LARGE;
                }
                else if (APR_STATUS_IS_TIMEUP(rv)) {
                    r->status = HTTP_REQUEST_TIME_OUT;
                }
                else if (APR_STATUS_IS_EINVAL(rv)) {
                    r->status = HTTP_BAD_REQUEST;
                }
                r->proto_num = HTTP_VERSION(1,0);
                r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
                return 0;
            }
        } while ((len <= 0) && (--num_blank_lines >= 0));
    
        /* Set r->request_time before any logging, mod_unique_id needs it. */
        r->request_time = apr_time_now();
    
        if (APLOGrtrace5(r)) {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r,
                          "Request received from client: %s",
                          ap_escape_logitem(r->pool, r->the_request));
        }
    
        return 1;
    }
    
    AP_DECLARE(int) ap_parse_request_line(request_rec *r)
    {
        core_server_config *conf = ap_get_core_module_config(r->server->module_config);
        int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
        enum {
            rrl_none, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace,
            rrl_missinguri, rrl_baduri, rrl_badprotocol, rrl_trailingtext,
            rrl_badmethod09, rrl_reject09
        } deferred_error = rrl_none;
        apr_size_t len = 0;
        char *uri, *ll;
    
        r->method = r->the_request;
    
        /* If there is whitespace before a method, skip it and mark in error */
        if (apr_isspace(*r->method)) {
            deferred_error = rrl_badwhitespace; 
            for ( ; apr_isspace(*r->method); ++r->method)
                ; 
        }
    
        /* Scan the method up to the next whitespace, ensure it contains only
         * valid http-token characters, otherwise mark in error
         */
        if (strict) {
            ll = (char*) ap_scan_http_token(r->method);
        }
        else {
            ll = (char*) ap_scan_vchar_obstext(r->method);
        }
    
        if (((ll == r->method) || (*ll && !apr_isspace(*ll)))
                && deferred_error == rrl_none) {
            deferred_error = rrl_badmethod;
            ll = strpbrk(ll, "\t\n\v\f\r ");
        }
    
        /* Verify method terminated with a single SP, or mark as specific error */
        if (!ll) {
            if (deferred_error == rrl_none)
                deferred_error = rrl_missinguri;
            r->protocol = uri = "";
            goto rrl_done;
        }
        else if (strict && ll[0] && apr_isspace(ll[1])
                 && deferred_error == rrl_none) {
            deferred_error = rrl_excesswhitespace; 
        }
    
        /* Advance uri pointer over leading whitespace, NUL terminate the method
         * If non-SP whitespace is encountered, mark as specific error
         */
        for (uri = ll; apr_isspace(*uri); ++uri) 
            if (*uri != ' ' && deferred_error == rrl_none)
                deferred_error = rrl_badwhitespace; 
        *ll = '\0';
    
        if (!*uri && deferred_error == rrl_none)
            deferred_error = rrl_missinguri;
    
        /* Scan the URI up to the next whitespace, ensure it contains no raw
         * control characters, otherwise mark in error
         */
        ll = (char*) ap_scan_vchar_obstext(uri);
        if (ll == uri || (*ll && !apr_isspace(*ll))) {
            deferred_error = rrl_baduri;
            ll = strpbrk(ll, "\t\n\v\f\r ");
        }
    
        /* Verify URI terminated with a single SP, or mark as specific error */
        if (!ll) {
            r->protocol = "";
            goto rrl_done;
        }
        else if (strict && ll[0] && apr_isspace(ll[1])
                 && deferred_error == rrl_none) {
            deferred_error = rrl_excesswhitespace; 
        }
    
        /* Advance protocol pointer over leading whitespace, NUL terminate the uri
         * If non-SP whitespace is encountered, mark as specific error
         */
        for (r->protocol = ll; apr_isspace(*r->protocol); ++r->protocol) 
            if (*r->protocol != ' ' && deferred_error == rrl_none)
                deferred_error = rrl_badwhitespace; 
        *ll = '\0';
    
        /* Scan the protocol up to the next whitespace, validation comes later */
        if (!(ll = (char*) ap_scan_vchar_obstext(r->protocol))) {
            len = strlen(r->protocol);
            goto rrl_done;
        }
        len = ll - r->protocol;
    
        /* Advance over trailing whitespace, if found mark in error,
         * determine if trailing text is found, unconditionally mark in error,
         * finally NUL terminate the protocol string
         */
        if (*ll && !apr_isspace(*ll)) {
            deferred_error = rrl_badprotocol;
        }
        else if (strict && *ll) {
            deferred_error = rrl_excesswhitespace;
        }
        else {
            for ( ; apr_isspace(*ll); ++ll)
                if (*ll != ' ' && deferred_error == rrl_none)
                    deferred_error = rrl_badwhitespace; 
            if (*ll && deferred_error == rrl_none)
                deferred_error = rrl_trailingtext;
        }
        *((char *)r->protocol + len) = '\0';
    
    rrl_done:
        /* For internal integrity and palloc efficiency, reconstruct the_request
         * in one palloc, using only single SP characters, per spec.
         */
        r->the_request = apr_pstrcat(r->pool, r->method, *uri ? " " : NULL, uri,
                                     *r->protocol ? " " : NULL, r->protocol, NULL);
    
        if (len == 8
                && r->protocol[0] == 'H' && r->protocol[1] == 'T'
                && r->protocol[2] == 'T' && r->protocol[3] == 'P'
                && r->protocol[4] == '/' && apr_isdigit(r->protocol[5])
                && r->protocol[6] == '.' && apr_isdigit(r->protocol[7])
                && r->protocol[5] != '0') {
            r->assbackwards = 0;
            r->proto_num = HTTP_VERSION(r->protocol[5] - '0', r->protocol[7] - '0');
        }
        else if (len == 8
                     && (r->protocol[0] == 'H' || r->protocol[0] == 'h')
                     && (r->protocol[1] == 'T' || r->protocol[1] == 't')
                     && (r->protocol[2] == 'T' || r->protocol[2] == 't')
                     && (r->protocol[3] == 'P' || r->protocol[3] == 'p')
                     && r->protocol[4] == '/' && apr_isdigit(r->protocol[5])
                     && r->protocol[6] == '.' && apr_isdigit(r->protocol[7])
                     && r->protocol[5] != '0') {
            r->assbackwards = 0;
            r->proto_num = HTTP_VERSION(r->protocol[5] - '0', r->protocol[7] - '0');
            if (strict && deferred_error == rrl_none)
                deferred_error = rrl_badprotocol;
            else
                memcpy((char*)r->protocol, "HTTP", 4);
        }
        else if (r->protocol[0]) {
            r->proto_num = HTTP_VERSION(0, 9);
            /* Defer setting the r->protocol string till error msg is composed */
            if (deferred_error == rrl_none)
                deferred_error = rrl_badprotocol;
        }
        else {
            r->assbackwards = 1;
            r->protocol  = apr_pstrdup(r->pool, "HTTP/0.9");
            r->proto_num = HTTP_VERSION(0, 9);
        }
    
        /* Determine the method_number and parse the uri prior to invoking error
         * handling, such that these fields are available for substitution
         */
        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 (r->status == HTTP_OK
                && (r->parsed_uri.path != NULL)
                && (r->parsed_uri.path[0] != '/')
                && (r->method_number != M_OPTIONS
                    || strcmp(r->parsed_uri.path, "*") != 0)) {
            /* Invalid request-target per RFC 7230 section 5.3 */
            r->status = HTTP_BAD_REQUEST;
        }
    
        /* With the request understood, we can consider HTTP/0.9 specific errors */
        if (r->proto_num == HTTP_VERSION(0, 9) && deferred_error == rrl_none) {
            if (conf->http09_enable == AP_HTTP09_DISABLE)
                deferred_error = rrl_reject09;
            else if (strict && (r->method_number != M_GET || r->header_only))
                deferred_error = rrl_badmethod09;
        }
    
        /* Now that the method, uri and protocol are all processed,
         * we can safely resume any deferred error reporting
         */
        if (deferred_error != rrl_none) {
            if (deferred_error == rrl_badmethod)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03445)
                              "HTTP Request Line; Invalid method token: '%.*s'",
                              field_name_len(r->method), r->method);
            else if (deferred_error == rrl_badmethod09)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03444)
                              "HTTP Request Line; Invalid method token: '%.*s'"
                              " (only GET is allowed for HTTP/0.9 requests)",
                              field_name_len(r->method), r->method);
            else if (deferred_error == rrl_missinguri)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03446)
                              "HTTP Request Line; Missing URI");
            else if (deferred_error == rrl_baduri)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03454)
                              "HTTP Request Line; URI incorrectly encoded: '%.*s'",
                              field_name_len(r->unparsed_uri), r->unparsed_uri);
            else if (deferred_error == rrl_badwhitespace)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03447)
                              "HTTP Request Line; Invalid whitespace");
            else if (deferred_error == rrl_excesswhitespace)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03448)
                              "HTTP Request Line; Excess whitespace "
                              "(disallowed by HttpProtocolOptions Strict)");
            else if (deferred_error == rrl_trailingtext)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03449)
                              "HTTP Request Line; Extraneous text found '%.*s' "
                              "(perhaps whitespace was injected?)",
                              field_name_len(ll), ll);
            else if (deferred_error == rrl_reject09)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02401)
                              "HTTP Request Line; Rejected HTTP/0.9 request");
            else if (deferred_error == rrl_badprotocol)
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02418)
                              "HTTP Request Line; Unrecognized protocol '%.*s' "
                              "(perhaps whitespace was injected?)",
                              field_name_len(r->protocol), r->protocol);
            r->status = HTTP_BAD_REQUEST;
            goto rrl_failed;
        }
    
        if (conf->http_methods == AP_HTTP_METHODS_REGISTERED
                && r->method_number == M_INVALID) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02423)
                          "HTTP Request Line; Unrecognized HTTP method: '%.*s' "
                          "(disallowed by RegisteredMethods)",
                          field_name_len(r->method), r->method);
            r->status = HTTP_NOT_IMPLEMENTED;
            /* This can't happen in an HTTP/0.9 request, we verified GET above */
            return 0;
        }
    
        if (r->status != HTTP_OK) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03450)
                          "HTTP Request Line; Unable to parse URI: '%.*s'",
                          field_name_len(r->uri), r->uri);
            goto rrl_failed;
        }
    
        if (strict) {
            if (r->parsed_uri.fragment) {
                /* RFC3986 3.5: no fragment */
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02421)
                              "HTTP Request Line; URI must not contain a fragment");
                r->status = HTTP_BAD_REQUEST;
                goto rrl_failed;
            }
            if (r->parsed_uri.user || r->parsed_uri.password) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02422)
                              "HTTP Request Line; URI must not contain a "
                              "username/password");
                r->status = HTTP_BAD_REQUEST;
                goto rrl_failed;
            }
        }
    
        return 1;
    
    rrl_failed:
        if (r->proto_num == HTTP_VERSION(0, 9)) {
            /* Send all parsing and protocol error response with 1.x behavior,
             * and reserve 505 errors for actual HTTP protocols presented.
             * As called out in RFC7230 3.5, any errors parsing the protocol
             * from the request line are nearly always misencoded HTTP/1.x
             * requests. Only a valid 0.9 request with no parsing errors
             * at all may be treated as a simple request, if allowed.
             */
            r->assbackwards = 0;
            r->connection->keepalive = AP_CONN_CLOSE;
            r->proto_num = HTTP_VERSION(1, 0);
            r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
        }
        return 0;
    }
    
    AP_DECLARE(int) ap_check_request_header(request_rec *r)
    {
        core_server_config *conf;
        int strict_host_check;
        const char *expect;
        int access_status;
    
        conf = ap_get_core_module_config(r->server->module_config);
    
        /* update what we think the virtual host is based on the headers we've
         * now read. may update status.
         */
        strict_host_check = (conf->strict_host_check == AP_CORE_CONFIG_ON);
        access_status = ap_update_vhost_from_headers_ex(r, strict_host_check);
        if (strict_host_check && access_status != HTTP_OK) { 
            if (r->server == ap_server_conf) { 
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10156)
                              "Requested hostname '%s' did not match any ServerName/ServerAlias "
                              "in the global server configuration ", r->hostname);
            }
            else { 
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10157)
                              "Requested hostname '%s' did not match any ServerName/ServerAlias "
                              "in the matching virtual host (default vhost for "
                              "current connection is %s:%u)", 
                              r->hostname, r->server->defn_name, r->server->defn_line_number);
            }
            r->status = access_status;
        }
        if (r->status != HTTP_OK) { 
            return 0;
        }
    
        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.
             */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00569)
                          "client sent HTTP/1.1 request without hostname "
                          "(see RFC2616 section 14.23): %s", r->uri);
            r->status = HTTP_BAD_REQUEST;
            return 0;
        }
    
        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 (ap_cstr_casecmp(expect, "100-continue") == 0) {
                r->expecting_100 = 1;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00570)
                              "client sent an unrecognized expectation value "
                              "of Expect: %s", expect);
                r->status = HTTP_EXPECTATION_FAILED;
                return 0;
            }
        }
    
        return 1;
    }
    
    static int table_do_fn_check_lengths(void *r_, const char *key,
                                         const char *value)
    {
        request_rec *r = r_;
        if (value == NULL || r->server->limit_req_fieldsize >= strlen(value) )
            return 1;
    
        r->status = HTTP_BAD_REQUEST;
        apr_table_setn(r->notes, "error-notes",
                       "Size of a request header field exceeds server limit.");
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00560) "Request "
                      "header exceeds LimitRequestFieldSize after merging: %.*s",
                      field_name_len(key), key);
        return 0;
    }
    
    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;
        core_server_config *conf = ap_get_core_module_config(r->server->module_config);
        int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
    
        /*
         * 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;
    
            field = NULL;
            rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2,
                             &len, r, strict ? AP_GETLINE_CRLF : 0, bb);
    
            if (rv != APR_SUCCESS) {
                if (APR_STATUS_IS_TIMEUP(rv)) {
                    r->status = HTTP_REQUEST_TIME_OUT;
                }
                else {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, 
                                  "Failed to read request header line %s", field);
                    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) {
                    apr_table_setn(r->notes, "error-notes",
                                   "Size of a request header field "
                                   "exceeds server limit.");
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00561)
                                  "Request header exceeds LimitRequestFieldSize%s"
                                  "%.*s",
                                  (field && *field) ? ": " : "",
                                  (field) ? field_name_len(field) : 0,
                                  (field) ? field : "");
                }
                return;
            }
    
            /* For all header values, and all obs-fold lines, the presence of
             * additional whitespace is a no-op, so collapse trailing whitespace
             * to save buffer allocation and optimize copy operations.
             * Do not remove the last single whitespace under any condition.
             */
            while (len > 1 && (field[len-1] == '\t' || field[len-1] == ' ')) {
                field[--len] = '\0';
            } 
    
            if (*field == '\t' || *field == ' ') {
    
                /* Append any newly-read obs-fold line onto the preceding
                 * last_field line we are processing
                 */
                apr_size_t fold_len;
    
                if (last_field == NULL) {
                    r->status = HTTP_BAD_REQUEST;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03442)
                                  "Line folding encountered before first"
                                  " header line");
                    return;
                }
    
                if (field[1] == '\0') {
                    r->status = HTTP_BAD_REQUEST;
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03443)
                                  "Empty folded line encountered");
                    return;
                }
    
                /* Leading whitespace on an obs-fold line can be
                 * similarly discarded */
                while (field[1] == '\t' || field[1] == ' ') {
                    ++field; --len;
                }
    
                /* 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.
                 */
                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",
                                   "Size of a request header field "
                                   "exceeds server limit.");
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00562)
                                  "Request header exceeds LimitRequestFieldSize "
                                  "after folding: %.*s",
                                  field_name_len(last_field), last_field);
                    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 */
                /* Replace obs-fold w/ SP per RFC 7230 3.2.4 */
                last_field[last_len] = ' ';
                last_len += len;
    
                /* We've appended this obs-fold line to last_len, proceed to
                 * read the next input line
                 */
                continue;
            }
            else if (last_field != NULL) {
    
                /* Process the previous last_field header line with all obs-folded
                 * segments already concatenated (this is not operating on the
                 * most recently read input 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.");
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00563)
                                  "Number of request headers exceeds "
                                  "LimitRequestFields");
                    return;
                }
    
                if (!strict)
                {
                    /* Not Strict ('Unsafe' mode), using the legacy parser */
    
                    if (!(value = strchr(last_field, ':'))) { /* Find ':' or */
                        r->status = HTTP_BAD_REQUEST;   /* abort bad request */
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00564)
                                      "Request header field is missing ':' "
                                      "separator: %.*s", (int)LOG_NAME_MAX_LEN,
                                      last_field);
                        return;
                    }
    
                    if (value == last_field) {
                        r->status = HTTP_BAD_REQUEST;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03453)
                                      "Request header field name was empty");
                        return;
                    }
    
                    *value++ = '\0'; /* NUL-terminate at colon */
    
                    if (strpbrk(last_field, "\t\n\v\f\r ")) {
                        r->status = HTTP_BAD_REQUEST;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03452)
                                      "Request header field name presented"
                                      " invalid whitespace");
                        return;
                    }
    
                    while (*value == ' ' || *value == '\t') {
                         ++value;            /* Skip to start of value   */
                    }
    
                    if (strpbrk(value, "\n\v\f\r")) {
                        r->status = HTTP_BAD_REQUEST;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03451)
                                      "Request header field value presented"
                                      " bad whitespace");
                        return;
                    }
                }
                else /* Using strict RFC7230 parsing */
                {
                    /* Ensure valid token chars before ':' per RFC 7230 3.2.4 */
                    value = (char *)ap_scan_http_token(last_field);
                    if ((value == last_field) || *value != ':') {
                        r->status = HTTP_BAD_REQUEST;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02426)
                                      "Request header field name is malformed: "
                                      "%.*s", (int)LOG_NAME_MAX_LEN, last_field);
                        return;
                    }
    
                    *value++ = '\0'; /* NUL-terminate last_field name at ':' */
    
                    while (*value == ' ' || *value == '\t') {
                        ++value;     /* Skip LWS of value */
                    }
    
                    /* Find invalid, non-HT ctrl char, or the trailing NULL */
                    tmp_field = (char *)ap_scan_http_field_content(value);
    
                    /* Reject value for all garbage input (CTRLs excluding HT)
                     * e.g. only VCHAR / SP / HT / obs-text are allowed per
                     * RFC7230 3.2.6 - leave all more explicit rule enforcement
                     * for specific header handler logic later in the cycle
                     */
                    if (*tmp_field != '\0') {
                        r->status = HTTP_BAD_REQUEST;
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02427)
                                      "Request header value is malformed: "
                                      "%.*s", (int)LOG_NAME_MAX_LEN, value);
                        return;
                    }
                }
    
                apr_table_addn(r->headers_in, last_field, value);
    
                /* This last_field header is now stored in headers_in,
                 * resume processing of the current input line.
                 */
            }
    
            /* Found the terminating empty end-of-headers line, stop. */
            if (len == 0) {
                break;
            }
    
            /* Keep track of this new header line so that we can extend it across
             * any obs-fold or parse it on the next loop iteration. We referenced
             * our previously allocated buffer in r->headers_in,
             * so allocate a fresh buffer if required.
             */
            alloc_len = 0;
            last_field = field;
            last_len = len;
        }
    
        /* Combine multiple message-header fields with the same
         * field-name, following RFC 2616, 4.2.
         */
        apr_table_compress(r->headers_in, APR_OVERLAP_TABLES_MERGE);
    
        /* enforce LimitRequestFieldSize for merged headers */
        apr_table_do(table_do_fn_check_lengths, r, r->headers_in, NULL);
    }
    
    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);
    }
    
    AP_DECLARE(request_rec *) ap_create_request(conn_rec *conn)
    {
        request_rec *r;
        apr_pool_t *p;
    
        apr_pool_create(&p, conn->pool);
        apr_pool_tag(p, "request");
        r = apr_pcalloc(p, sizeof(request_rec));
        AP_READ_REQUEST_ENTRY((intptr_t)r, (uintptr_t)conn);
        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->trailers_in     = apr_table_make(r->pool, 5);
        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->trailers_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_OK;  /* Until further notice */
        r->header_only     = 0;
        r->the_request     = NULL;
    
        /* 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;
    
        r->useragent_addr = conn->client_addr;
        r->useragent_ip = conn->client_ip;
    
        return r;
    }
    
    /* Apply the server's timeout/config to the connection/request. */
    static void apply_server_config(request_rec *r)
    {
        apr_socket_t *csd;
    
        csd = ap_get_conn_socket(r->connection);
        apr_socket_timeout_set(csd, r->server->timeout);
    
        r->per_dir_config = r->server->lookup_defaults;
    }
    
    request_rec *ap_read_request(conn_rec *conn)
    {
        int access_status;
        apr_bucket_brigade *tmp_bb;
    
        request_rec *r = ap_create_request(conn);
    
        tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        conn->keepalive = AP_CONN_UNKNOWN;
    
        ap_run_pre_read_request(r, conn);
    
        /* Get the request... */
        if (!read_request_line(r, tmp_bb) || !ap_parse_request_line(r)) {
            apr_brigade_cleanup(tmp_bb);
            switch (r->status) {
            case HTTP_REQUEST_URI_TOO_LARGE:
            case HTTP_BAD_REQUEST:
            case HTTP_VERSION_NOT_SUPPORTED:
            case HTTP_NOT_IMPLEMENTED:
                if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00565)
                                  "request failed: client's request-line exceeds LimitRequestLine (longer than %d)",
                                  r->server->limit_req_line);
                }
                else if (r->method == NULL) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00566)
                                  "request failed: malformed request line");
                }
                access_status = r->status;
                goto die_unusable_input;
    
            case HTTP_REQUEST_TIME_OUT:
                /* Just log, no further action on this connection. */
                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
                if (!r->connection->keepalives)
                    ap_run_log_transaction(r);
                break;
            }
            /* Not worth dying with. */
            conn->keepalive = AP_CONN_CLOSE;
            apr_pool_destroy(r->pool);
            goto ignore;
        }
        apr_brigade_cleanup(tmp_bb);
    
        /* We may have been in keep_alive_timeout mode, so toggle back
         * to the normal timeout mode as we fetch the header lines,
         * as necessary.
         */
        apply_server_config(r);
    
        if (!r->assbackwards) {
            const char *tenc, *clen;
    
            ap_get_mime_headers_core(r, tmp_bb);
            apr_brigade_cleanup(tmp_bb);
            if (r->status != HTTP_OK) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00567)
                              "request failed: error reading the headers");
                access_status = r->status;
                goto die_unusable_input;
            }
    
            clen = apr_table_get(r->headers_in, "Content-Length");
            if (clen) {
                apr_off_t cl;
    
                if (!ap_parse_strict_length(&cl, clen)) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10242)
                                  "client sent invalid Content-Length "
                                  "(%s): %s", clen, r->uri);
                    access_status = HTTP_BAD_REQUEST;
                    goto die_unusable_input;
                }
            }
    
            tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
            if (tenc) {
                /* https://tools.ietf.org/html/rfc7230
                 * Section 3.3.3.3: "If a Transfer-Encoding header field is
                 * present in a request and the chunked transfer coding is not
                 * the final encoding ...; the server MUST respond with the 400
                 * (Bad Request) status code and then close the connection".
                 */
                if (!ap_is_chunked(r->pool, tenc)) {
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02539)
                                  "client sent unknown Transfer-Encoding "
                                  "(%s): %s", tenc, r->uri);
                    access_status = HTTP_BAD_REQUEST;
                    goto die_unusable_input;
                }
    
                /* https://tools.ietf.org/html/rfc7230
                 * Section 3.3.3.3: "If a message is received with both a
                 * Transfer-Encoding and a Content-Length header field, the
                 * Transfer-Encoding overrides the Content-Length. ... A sender
                 * MUST remove the received Content-Length field".
                 */
                if (clen) {
                    apr_table_unset(r->headers_in, "Content-Length");
    
                    /* Don't reuse this connection anyway to avoid confusion with
                     * intermediaries and request/reponse spltting.
                     */
                    conn->keepalive = AP_CONN_CLOSE;
                }
            }
        }
    
        /*
         * Add the HTTP_IN filter here to ensure that ap_discard_request_body
         * called by ap_die and by ap_send_error_response works correctly on
         * status codes that do not cause the connection to be dropped and
         * in situations where the connection should be kept alive.
         */
        ap_add_input_filter_handle(ap_http_input_filter_handle,
                                   NULL, r, r->connection);
    
        /* Validate Host/Expect headers and select vhost. */
        if (!ap_check_request_header(r)) {
            /* we may have switched to another server still */
            apply_server_config(r);
            access_status = r->status;
            goto die_before_hooks;
        }
    
        /* we may have switched to another server */
        apply_server_config(r);
    
        if ((access_status = ap_post_read_request(r))) {
            goto die;
        }
    
        AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method,
                                (char *)r->uri, (char *)r->server->defn_name,
                                r->status);
        return r;
    
        /* Everything falls through on failure */
    
    die_unusable_input:
        /* Input filters are in an undeterminate state, cleanup (including
         * CORE_IN's socket) such that any further attempt to read is EOF.
         */
        {
            ap_filter_t *f = conn->input_filters;
            while (f) {
                if (f->frec == ap_core_input_filter_handle) {
                    core_net_rec *net = f->ctx;
                    apr_brigade_cleanup(net->in_ctx->b);
                    break;
                }
                ap_remove_input_filter(f);
                f = f->next;
            }
            conn->input_filters = r->input_filters = f;
            conn->keepalive = AP_CONN_CLOSE;
        }
    
    die_before_hooks:
        /* First call to ap_die() (non recursive) */
        r->status = HTTP_OK;
    
    die:
        ap_die(access_status, r);
    
        /* ap_die() sent the response through the output filters, we must now
         * end the request with an EOR bucket for stream/pipeline accounting.
         */
        {
            apr_bucket_brigade *eor_bb;
            eor_bb = apr_brigade_create(conn->pool, conn->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(eor_bb,
                                    ap_bucket_eor_create(conn->bucket_alloc, r));
            ap_pass_brigade(conn->output_filters, eor_bb);
            apr_brigade_cleanup(eor_bb);
        }
    
    ignore:
        r = NULL;
        AP_READ_REQUEST_FAILURE((uintptr_t)r);
        return NULL;
    }
    
    AP_DECLARE(int) ap_post_read_request(request_rec *r)
    {
        int status;
    
        if ((status = ap_run_post_read_request(r))) {
            return status;
        }
    
        /* Enforce http(s) only scheme for non-forward-proxy requests */
        if (!r->proxyreq
                && r->parsed_uri.scheme
                && (ap_cstr_casecmpn(r->parsed_uri.scheme, "http", 4) != 0
                    || (r->parsed_uri.scheme[4] != '\0'
                        && (apr_tolower(r->parsed_uri.scheme[4]) != 's'
                            || r->parsed_uri.scheme[5] != '\0')))) {
            return HTTP_BAD_REQUEST;
        }
    
        return OK;
    }
    
    /* if a request with a body creates a subrequest, remove original request's
     * input headers which pertain to the body which has already been read.
     * out-of-line helper function for ap_set_sub_req_protocol.
     */
    
    static void strip_headers_request_body(request_rec *rnew)
    {
        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;
    
        rnew->headers_in      = apr_table_copy(rnew->pool, r->headers_in);
        rnew->trailers_in     = apr_table_copy(rnew->pool, r->trailers_in);
    
        /* 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 (!r->kept_body && (apr_table_get(r->headers_in, "Content-Length")
            || apr_table_get(r->headers_in, "Transfer-Encoding"))) {
            strip_headers_request_body(rnew);
        }
        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->trailers_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, int status)
    {
        conn_rec *c = r->connection;
        apr_bucket_brigade *bb;
        apr_bucket *b;
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
        if (status != OK) {
            b = ap_bucket_error_create(status, NULL, 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);
    
        ap_pass_brigade(r->output_filters, bb);
        apr_brigade_cleanup(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, OK);
        }
    }
    
    /* 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)
    {
        int status = ap_discard_request_body(r);
    
        /* tell the filter chain there is no more content coming */
        if (!r->eos_sent) {
            end_output_stream(r, status);
        }
    }
    
    /*
     * 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) {
            ap_run_note_auth_failure(r, type);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00571)
                          "need AuthType to note auth failure: %s", r->uri);
        }
    }
    
    AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r)
    {
        ap_note_auth_failure(r);
    }
    
    AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r)
    {
        ap_note_auth_failure(r);
    }
    
    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)) || ap_cstr_casecmp(t, "Basic"))
            return DECLINED;
    
        if (!ap_auth_name(r)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00572) 
                          "need AuthName: %s", r->uri);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    
        if (!auth_line) {
            ap_note_auth_failure(r);
            return HTTP_UNAUTHORIZED;
        }
    
        if (ap_cstr_casecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
            /* Client tried to authenticate using wrong auth scheme */
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00573)
                          "client used wrong authentication scheme: %s", r->uri);
            ap_note_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, ':');
        apr_table_setn(r->notes, AP_GET_BASIC_AUTH_PW_NOTE, "1");
        r->ap_auth_type = "Basic";
    
        *pw = t;
    
        return OK;
    }
    
    AP_DECLARE(apr_status_t) ap_get_basic_auth_components(const request_rec *r,
                                                          const char **username,
                                                          const char **password)
    {
        const char *auth_header;
        const char *credentials;
        const char *decoded;
        const char *user;
    
        auth_header = (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authorization"
                                                      : "Authorization";
        credentials = apr_table_get(r->headers_in, auth_header);
    
        if (!credentials) {
            /* No auth header. */
            return APR_EINVAL;
        }
    
        if (ap_cstr_casecmp(ap_getword(r->pool, &credentials, ' '), "Basic")) {
            /* These aren't Basic credentials. */
            return APR_EINVAL;
        }
    
        while (*credentials == ' ' || *credentials == '\t') {
            credentials++;
        }
    
        /* XXX Our base64 decoding functions don't actually error out if the string
         * we give it isn't base64; they'll just silently stop and hand us whatever
         * they've parsed up to that point.
         *
         * Since this function is supposed to be a drop-in replacement for the
         * deprecated ap_get_basic_auth_pw(), don't fix this for 2.4.x.
         */
        decoded = ap_pbase64decode(r->pool, credentials);
        user = ap_getword_nulls(r->pool, &decoded, ':');
    
        if (username) {
            *username = user;
        }
        if (password) {
            *password = decoded;
        }
    
        return APR_SUCCESS;
    }
    
    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
                         */
        apr_bucket_brigade *tmpbb;
    };
    
    /* 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;
            ctx->tmpbb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
        }
    
        /* Loop through the brigade to count the length. To avoid
         * arbitrary memory consumption with morphing bucket types, this
         * loop will stop and pass on the brigade when necessary. */
        e = APR_BRIGADE_FIRST(b);
        while (e != APR_BRIGADE_SENTINEL(b)) {
            apr_status_t rv;
    
            if (APR_BUCKET_IS_EOS(e)) {
                eos = 1;
                break;
            }
            /* For a flush bucket, fall through to pass the brigade and
             * flush now. */
            else if (APR_BUCKET_IS_FLUSH(e)) {
                e = APR_BUCKET_NEXT(e);
            }
            /* For metadata bucket types other than FLUSH, loop. */
            else if (APR_BUCKET_IS_METADATA(e)) {
                e = APR_BUCKET_NEXT(e);
                continue;
            }
            /* For determinate length data buckets, count the length and
             * continue. */
            else if (e->length != (apr_size_t)-1) {
                r->bytes_sent += e->length;
                e = APR_BUCKET_NEXT(e);
                continue;
            }
            /* For indeterminate length data buckets, perform one read. */
            else /* e->length == (apr_size_t)-1 */ {
                apr_size_t len;
                const char *ignored;
            
                rv = apr_bucket_read(e, &ignored, &len, eblock);
                if ((rv != APR_SUCCESS) && !APR_STATUS_IS_EAGAIN(rv)) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00574)
                                  "ap_content_length_filter: "
                                  "apr_bucket_read() failed");
                    return rv;
                }
                if (rv == APR_SUCCESS) {
                    eblock = APR_NONBLOCK_READ;
                    e = APR_BUCKET_NEXT(e);
                    r->bytes_sent += len;
                }
                else if (APR_STATUS_IS_EAGAIN(rv)) {
                    apr_bucket *flush;
    
                    /* Next read must block. */
                    eblock = APR_BLOCK_READ;
    
                    /* Ensure the last bucket to pass down is a flush if
                     * the next read will block. */
                    flush = apr_bucket_flush_create(f->c->bucket_alloc);
                    APR_BUCKET_INSERT_BEFORE(e, flush);
                }
            }
    
            /* Optimization: if the next bucket is EOS (directly after a
             * bucket morphed to the heap, or a flush), short-cut to
             * handle EOS straight away - allowing C-L to be determined
             * for content which is already entirely in memory. */
            if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
                continue;
            }
    
            /* On reaching here, pass on everything in the brigade up to
             * this point. */
            apr_brigade_split_ex(b, e, ctx->tmpbb);
            
            rv = ap_pass_brigade(f->next, b);
            if (rv != APR_SUCCESS) {
                return rv;
            }
            else if (f->c->aborted) {
                return APR_ECONNABORTED;
            }
            apr_brigade_cleanup(b);
            APR_BRIGADE_CONCAT(b, ctx->tmpbb);
            e = APR_BRIGADE_FIRST(b);
            
            ctx->data_sent = 1;
        }
    
        /* 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 &&
            /* don't whack the C-L if it has already been set for a HEAD
             * by something like proxy.  the brigade only has an EOS bucket
             * in this case, making r->bytes_sent zero.
             *
             * if r->bytes_sent > 0 we have a (temporary) body whose length may
             * have been changed by a filter.  the C-L header might not have been
             * updated so we do it here.  long term it would be cleaner to have
             * such filters update or remove the C-L header, and just use it
             * if present.
             */
            !((r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status)) && r->bytes_sent == 0 &&
                apr_table_get(r->headers_out, "Content-Length"))) {
            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_status_t rv;
    
        bb = apr_brigade_create(r->pool, c->bucket_alloc);
    
        apr_brigade_insert_file(bb, fd, offset, len, r->pool);
    
        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(apr_size_t) ap_send_mmap(apr_mmap_t *mm,
                                        request_rec *r,
                                        apr_size_t offset,
                                        apr_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;
        apr_bucket_brigade *tmpbb;
    } 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 != NULL) {
            /* 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_PREPEND(bb, ctx->bb);
        }
    
        return ap_pass_brigade(f->next, bb);
    }
    
    static ap_filter_t *insert_old_write_filter(request_rec *r)
    {
        ap_filter_t *f;
        old_write_filter_ctx *ctx;
    
        /* 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));
            ctx->tmpbb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
            ap_add_output_filter("OLD_WRITE", ctx, r, r->connection);
            f = r->output_filters;
        }
    
        return f;
    }
    
    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;
    
        f = insert_old_write_filter(r);
        ctx = f->ctx;
    
        /* 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_status_t rv;
            apr_bucket *b = apr_bucket_transient_create(str, len, c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, b);
    
            rv = ap_pass_brigade(r->output_filters, ctx->tmpbb);
            apr_brigade_cleanup(ctx->tmpbb);
            return rv;
        }
    
        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_rwrite(const void *buf, int nbyte, request_rec *r)
    {
        if (nbyte < 0)
            return -1;
    
        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;
    };
    
    /* Flush callback for apr_vformatter; returns -1 on error. */
    static int 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 0;
    }
    
    AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
    {
        int 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);
    
        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) {
                va_end(va);
                return -1;
            }
    
            written += len;
        }
        va_end(va);
    
        return written;
    }
    
    AP_DECLARE(int) ap_rflush(request_rec *r)
    {
        conn_rec *c = r->connection;
        apr_bucket *b;
        ap_filter_t *f;
        old_write_filter_ctx *ctx;
        apr_status_t rv;
    
        f = insert_old_write_filter(r);
        ctx = f->ctx;
    
        b = apr_bucket_flush_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, b);
    
        rv = ap_pass_brigade(r->output_filters, ctx->tmpbb);
        apr_brigade_cleanup(ctx->tmpbb);
        if (rv != 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);
        }
    }
    
    typedef struct hdr_ptr {
        ap_filter_t *f;
        apr_bucket_brigade *bb;
    } hdr_ptr;
     
    #if APR_CHARSET_EBCDIC
    static int send_header(void *data, const char *key, const char *val)
    {
        char *header_line = NULL;
        hdr_ptr *hdr = (hdr_ptr*)data;
    
        header_line = apr_pstrcat(hdr->bb->p, key, ": ", val, CRLF, NULL);
        ap_xlate_proto_to_ascii(header_line, strlen(header_line));
        ap_fputs(hdr->f, hdr->bb, header_line);
        return 1;
    }
    #else
    static int send_header(void *data, const char *key, const char *val)
    {
         ap_fputstrs(((hdr_ptr*)data)->f, ((hdr_ptr*)data)->bb,
                     key, ": ", val, CRLF, NULL);
         return 1;
     }
    #endif
    
    AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers)
    {
        hdr_ptr x;
        char *response_line = NULL;
        const char *status_line;
        request_rec *rr;
    
        if (r->proto_num < HTTP_VERSION(1,1)) {
            /* don't send interim response to HTTP/1.0 Client */
            return;
        }
        if (!ap_is_HTTP_INFO(r->status)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00575)
                          "Status is %d - not sending interim response", r->status);
            return;
        }
        if (r->status == HTTP_CONTINUE) {
            if (!r->expecting_100) {
                /*
                 * Don't send 100-Continue when there was no Expect: 100-continue
                 * in the request headers. For origin servers this is a SHOULD NOT
                 * for proxies it is a MUST NOT according to RFC 2616 8.2.3
                 */
                return;
            }
    
            /* if we send an interim response, we're no longer in a state of
             * expecting one.  Also, this could feasibly be in a subrequest,
             * so we need to propagate the fact that we responded.
             */
            for (rr = r; rr != NULL; rr = rr->main) {
                rr->expecting_100 = 0;
            }
        }
    
        status_line = r->status_line;
        if (status_line == NULL) {
            status_line = ap_get_status_line_ex(r->pool, r->status);
        }
        response_line = apr_pstrcat(r->pool,
                                    AP_SERVER_PROTOCOL " ", status_line, CRLF,
                                    NULL);
        ap_xlate_proto_to_ascii(response_line, strlen(response_line));
    
        x.f = r->connection->output_filters;
        x.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    
        ap_fputs(x.f, x.bb, response_line);
        if (send_headers) {
            apr_table_do(send_header, &x, r->headers_out, NULL);
            apr_table_clear(r->headers_out);
        }
        ap_fputs(x.f, x.bb, CRLF_ASCII);
        ap_fflush(x.f, x.bb);
        apr_brigade_destroy(x.bb);
    }
    
    /*
     * Compare two protocol identifier. Result is similar to strcmp():
     * 0 gives same precedence, >0 means proto1 is preferred.
     */
    static int protocol_cmp(const apr_array_header_t *preferences,
                            const char *proto1,
                            const char *proto2)
    {
        if (preferences && preferences->nelts > 0) {
            int index1 = ap_array_str_index(preferences, proto1, 0);
            int index2 = ap_array_str_index(preferences, proto2, 0);
            if (index2 > index1) {
                return (index1 >= 0) ? 1 : -1;
            }
            else if (index1 > index2) {
                return (index2 >= 0) ? -1 : 1;
            }
        }
        /* both have the same index (maybe -1 or no pref configured) and we compare
         * the names so that spdy3 gets precedence over spdy2. That makes
         * the outcome at least deterministic. */
        return strcmp(proto1, proto2);
    }
    
    AP_DECLARE(const char *) ap_get_protocol(conn_rec *c)
    {
        const char *protocol = ap_run_protocol_get(c);
        return protocol? protocol : AP_PROTOCOL_HTTP1;
    }
    
    AP_DECLARE(apr_status_t) ap_get_protocol_upgrades(conn_rec *c, request_rec *r, 
                                                      server_rec *s, int report_all, 
                                                      const apr_array_header_t **pupgrades)
    {
        apr_pool_t *pool = r? r->pool : c->pool;
        core_server_config *conf;
        const char *existing;
        apr_array_header_t *upgrades = NULL;
    
        if (!s) {
            s = (r? r->server : c->base_server);
        }
        conf = ap_get_core_module_config(s->module_config);
        
        if (conf->protocols->nelts > 0) {
            existing = ap_get_protocol(c);
            if (conf->protocols->nelts > 1 
                || !ap_array_str_contains(conf->protocols, existing)) {
                int i;
                
                /* possibly more than one choice or one, but not the
                 * existing. (TODO: maybe 426 and Upgrade then?) */
                upgrades = apr_array_make(pool, conf->protocols->nelts + 1, 
                                          sizeof(char *));
                for (i = 0; i < conf->protocols->nelts; i++) {
                    const char *p = APR_ARRAY_IDX(conf->protocols, i, char *);
                    if (strcmp(existing, p)) {
                        /* not the one we have and possible, add in this order */
                        APR_ARRAY_PUSH(upgrades, const char*) = p;
                    }
                    else if (!report_all) {
                        break;
                    }
                }
            }
        }
        
        *pupgrades = upgrades;
        return APR_SUCCESS;
    }
    
    AP_DECLARE(const char *) ap_select_protocol(conn_rec *c, request_rec *r, 
                                                server_rec *s,
                                                const apr_array_header_t *choices)
    {
        apr_pool_t *pool = r? r->pool : c->pool;
        core_server_config *conf;
        const char *protocol = NULL, *existing;
        apr_array_header_t *proposals;
    
        if (!s) {
            s = (r? r->server : c->base_server);
        }
        conf = ap_get_core_module_config(s->module_config);
        
        if (APLOGcdebug(c)) {
            const char *p = apr_array_pstrcat(pool, conf->protocols, ',');
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03155) 
                          "select protocol from %s, choices=%s for server %s", 
                          p, apr_array_pstrcat(pool, choices, ','),
                          s->server_hostname);
        }
    
        if (conf->protocols->nelts <= 0) {
            /* nothing configured, by default, we only allow http/1.1 here.
             * For now...
             */
            if (ap_array_str_contains(choices, AP_PROTOCOL_HTTP1)) {
                return AP_PROTOCOL_HTTP1;
            }
            else {
                return NULL;
            }
        }
    
        proposals = apr_array_make(pool, choices->nelts + 1, sizeof(char *));
        ap_run_protocol_propose(c, r, s, choices, proposals);
    
        /* If the existing protocol has not been proposed, but is a choice,
         * add it to the proposals implicitly.
         */
        existing = ap_get_protocol(c);
        if (!ap_array_str_contains(proposals, existing)
            && ap_array_str_contains(choices, existing)) {
            APR_ARRAY_PUSH(proposals, const char*) = existing;
        }
    
        if (proposals->nelts > 0) {
            int i;
            const apr_array_header_t *prefs = NULL;
    
            /* Default for protocols_honor_order is 'on' or != 0 */
            if (conf->protocols_honor_order == 0 && choices->nelts > 0) {
                prefs = choices;
            }
            else {
                prefs = conf->protocols;
            }
    
            /* Select the most preferred protocol */
            if (APLOGcdebug(c)) {
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03156) 
                              "select protocol, proposals=%s preferences=%s configured=%s", 
                              apr_array_pstrcat(pool, proposals, ','),
                              apr_array_pstrcat(pool, prefs, ','),
                              apr_array_pstrcat(pool, conf->protocols, ','));
            }
            for (i = 0; i < proposals->nelts; ++i) {
                const char *p = APR_ARRAY_IDX(proposals, i, const char *);
                if (!ap_array_str_contains(conf->protocols, p)) {
                    /* not a configured protocol here */
                    continue;
                }
                else if (!protocol 
                         || (protocol_cmp(prefs, protocol, p) < 0)) {
                    /* none selected yet or this one has preference */
                    protocol = p;
                }
            }
        }
        if (APLOGcdebug(c)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03157)
                          "selected protocol=%s", 
                          protocol? protocol : "(none)");
        }
    
        return protocol;
    }
    
    AP_DECLARE(apr_status_t) ap_switch_protocol(conn_rec *c, request_rec *r, 
                                                server_rec *s,
                                                const char *protocol)
    {
        const char *current = ap_get_protocol(c);
        int rc;
        
        if (!strcmp(current, protocol)) {
            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(02906)
                          "already at it, protocol_switch to %s", 
                          protocol);
            return APR_SUCCESS;
        }
        
        rc = ap_run_protocol_switch(c, r, s, protocol);
        switch (rc) {
            case DECLINED:
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02907)
                              "no implementation for protocol_switch to %s", 
                              protocol);
                return APR_ENOTIMPL;
            case OK:
            case DONE:
                return APR_SUCCESS;
            default:
                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02905)
                              "unexpected return code %d from protocol_switch to %s"
                              , rc, protocol);
                return APR_EOF;
        }    
    }
    
    AP_DECLARE(int) ap_is_allowed_protocol(conn_rec *c, request_rec *r,
                                           server_rec *s, const char *protocol)
    {
        core_server_config *conf;
    
        if (!s) {
            s = (r? r->server : c->base_server);
        }
        conf = ap_get_core_module_config(s->module_config);
        
        if (conf->protocols->nelts > 0) {
            return ap_array_str_contains(conf->protocols, protocol);
        }
        return !strcmp(AP_PROTOCOL_HTTP1, protocol);
    }
    
    
    AP_IMPLEMENT_HOOK_VOID(pre_read_request,
                           (request_rec *r, conn_rec *c),
                           (r, c))
    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)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, note_auth_failure,
                                (request_rec *r, const char *auth_type),
                                (r, auth_type), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_ALL(int,protocol_propose,
                              (conn_rec *c, request_rec *r, server_rec *s,
                               const apr_array_header_t *offers,
                               apr_array_header_t *proposals), 
                              (c, r, s, offers, proposals), OK, DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int,protocol_switch,
                                (conn_rec *c, request_rec *r, server_rec *s,
                                 const char *protocol), 
                                (c, r, s, protocol), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,protocol_get,
                                (const conn_rec *c), (c), NULL)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_filter.c�������������������������������������������������������������������0000664�0001751�0001751�00000056066�14131241651�016631� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_config.h"
    #include "http_core.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 "ap_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
     */
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    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,
                               &registered_input_filters);
    }
    
    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,
                              &registered_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 = frec->ftype < AP_FTYPE_CONNECTION && 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_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00080)
                              "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_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00081)
                              "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 must always be NULL for connection filters */
        f->r = frec->ftype < AP_FTYPE_CONNECTION ? r : NULL;
        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_cerror(APLOG_MARK, APLOG_ERR, 0, r ? r->connection : c, APLOGNO(00082)
                      "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);
    }
    
    AP_DECLARE(apr_status_t) ap_remove_input_filter_byhandle(ap_filter_t *next,
                                                             const char *handle)
    {
        ap_filter_t *found = NULL;
        ap_filter_rec_t *filter;
    
        if (!handle) {
            return APR_EINVAL;
        }
        filter = ap_get_input_filter_handle(handle);
        if (!filter) {
            return APR_NOTFOUND;
        }
    
        while (next) {
            if (next->frec == filter) {
                found = next;
                break;
            }
            next = next->next;
        }
        if (found) {
            ap_remove_input_filter(found);
            return APR_SUCCESS;
        }
        return APR_NOTFOUND;
    }
    
    AP_DECLARE(apr_status_t) ap_remove_output_filter_byhandle(ap_filter_t *next,
                                                              const char *handle)
    {
        ap_filter_t *found = NULL;
        ap_filter_rec_t *filter;
    
        if (!handle) {
            return APR_EINVAL;
        }
        filter = ap_get_output_filter_handle(handle);
        if (!filter) {
            return APR_NOTFOUND;
        }
    
        while (next) {
            if (next->frec == filter) {
                found = next;
                break;
            }
            next = next->next;
        }
        if (found) {
            ap_remove_output_filter(found);
            return APR_SUCCESS;
        }
        return APR_NOTFOUND;
    }
    
    
    /*
     * 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 = APR_BRIGADE_LAST(bb);
    
            if (e != APR_BRIGADE_SENTINEL(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;
    }
    
    /* Pass the buckets to the next filter in the filter stack
     * checking return status for filter errors.
     * returns: OK if ap_pass_brigade returns APR_SUCCESS
     *          AP_FILTER_ERROR if filter error exists
     *          HTTP_INTERNAL_SERVER_ERROR for all other cases
     *          logged with optional errmsg
     */
    AP_DECLARE(apr_status_t) ap_pass_brigade_fchk(request_rec *r,
                                                  apr_bucket_brigade *bb,
                                                  const char *fmt,
                                                  ...)
    {
        apr_status_t rv;
    
        rv = ap_pass_brigade(r->output_filters, bb);
        if (rv != APR_SUCCESS) {
            if (rv != AP_FILTER_ERROR) {
                if (!fmt)
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(00083)
                                  "ap_pass_brigade returned %d", rv);
                else {
                    va_list ap;
                    const char *res;
                    va_start(ap, fmt);
                    res = apr_pvsprintf(r->pool, fmt, ap);
                    va_end(ap);
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(03158)
                                  "%s", res);
                }
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            return AP_FILTER_ERROR;
        }
        return OK;
    }
    
    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;
        apr_status_t rv;
    
        rv = ap_pass_brigade(f, bb);
    
        /* Before invocation of the flush callback, apr_brigade_write et
         * al may place transient buckets in the brigade, which will fall
         * out of scope after returning.  Empty the brigade here, to avoid
         * issues with leaving such buckets in the brigade if some filter
         * fails and leaves a non-empty brigade. */
        apr_brigade_cleanup(bb);
    
        return rv;
    }
    
    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 ;
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm_common.c��������������������������������������������������������������������0000664�0001751�0001751�00000043037�14104436037�016446� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_core.h"
    #include "http_log.h"
    #include "http_main.h"
    #include "mpm_common.h"
    #include "mod_core.h"
    #include "ap_mpm.h"
    #include "ap_listen.h"
    #include "util_mutex.h"
    
    #include "scoreboard.h"
    
    #ifdef HAVE_PWD_H
    #include <pwd.h>
    #endif
    #ifdef HAVE_GRP_H
    #include <grp.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    #define DEFAULT_HOOK_LINKS \
        APR_HOOK_LINK(monitor) \
        APR_HOOK_LINK(drop_privileges) \
        APR_HOOK_LINK(mpm) \
        APR_HOOK_LINK(mpm_query) \
        APR_HOOK_LINK(mpm_register_timed_callback) \
        APR_HOOK_LINK(mpm_get_name) \
        APR_HOOK_LINK(end_generation) \
        APR_HOOK_LINK(child_status) \
        APR_HOOK_LINK(suspend_connection) \
        APR_HOOK_LINK(resume_connection) \
        APR_HOOK_LINK(child_stopping)
    
    #if AP_ENABLE_EXCEPTION_HOOK
    APR_HOOK_STRUCT(
        APR_HOOK_LINK(fatal_exception)
        DEFAULT_HOOK_LINKS
    )
    AP_IMPLEMENT_HOOK_RUN_ALL(int, fatal_exception,
                              (ap_exception_info_t *ei), (ei), OK, DECLINED)
    #else
    APR_HOOK_STRUCT(
        DEFAULT_HOOK_LINKS
    )
    #endif
    AP_IMPLEMENT_HOOK_RUN_ALL(int, monitor,
                              (apr_pool_t *p, server_rec *s), (p, s), OK, DECLINED)
    AP_IMPLEMENT_HOOK_RUN_ALL(int, drop_privileges,
                              (apr_pool_t * pchild, server_rec * s),
                              (pchild, s), OK, DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, mpm,
                                (apr_pool_t *pconf, apr_pool_t *plog, server_rec *s),
                                (pconf, plog, s), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(int, mpm_query,
                                (int query_code, int *result, apr_status_t *_rv),
                                (query_code, result, _rv), DECLINED)
    AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_timed_callback,
                                (apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton),
                                (t, cbfn, baton), APR_ENOTIMPL)
    AP_IMPLEMENT_HOOK_VOID(end_generation,
                           (server_rec *s, ap_generation_t gen),
                           (s, gen))
    AP_IMPLEMENT_HOOK_VOID(child_status,
                           (server_rec *s, pid_t pid, ap_generation_t gen, int slot, mpm_child_status status),
                           (s,pid,gen,slot,status))
    AP_IMPLEMENT_HOOK_VOID(suspend_connection,
                           (conn_rec *c, request_rec *r),
                           (c, r))
    AP_IMPLEMENT_HOOK_VOID(resume_connection,
                           (conn_rec *c, request_rec *r),
                           (c, r))
    AP_IMPLEMENT_HOOK_VOID(child_stopping,
                           (apr_pool_t *pchild, int graceful),
                           (pchild, graceful))
    
    /* hooks with no args are implemented last, after disabling APR hook probes */
    #if defined(APR_HOOK_PROBES_ENABLED)
    #undef APR_HOOK_PROBES_ENABLED
    #undef APR_HOOK_PROBE_ENTRY
    #define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
    #undef APR_HOOK_PROBE_RETURN
    #define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
    #undef APR_HOOK_PROBE_INVOKE
    #define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
    #undef APR_HOOK_PROBE_COMPLETE
    #define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
    #undef APR_HOOK_INT_DCL_UD
    #define APR_HOOK_INT_DCL_UD
    #endif
    AP_IMPLEMENT_HOOK_RUN_FIRST(const char *, mpm_get_name,
                                (void),
                                (), NULL)
    
    typedef struct mpm_gen_info_t {
        APR_RING_ENTRY(mpm_gen_info_t) link;
        int gen;          /* which gen? */
        int active;       /* number of active processes */
        int done;         /* gen finished? (whether or not active processes) */
    } mpm_gen_info_t;
    
    APR_RING_HEAD(mpm_gen_info_head_t, mpm_gen_info_t);
    static struct mpm_gen_info_head_t *geninfo, *unused_geninfo;
    static int gen_head_init; /* yuck */
    
    /* variables representing config directives implemented here */
    AP_DECLARE_DATA const char *ap_pid_fname;
    AP_DECLARE_DATA int ap_max_requests_per_child;
    AP_DECLARE_DATA char ap_coredump_dir[MAX_STRING_LEN];
    AP_DECLARE_DATA int ap_coredumpdir_configured;
    AP_DECLARE_DATA int ap_graceful_shutdown_timeout;
    AP_DECLARE_DATA apr_uint32_t ap_max_mem_free;
    AP_DECLARE_DATA apr_size_t ap_thread_stacksize;
    
    #define ALLOCATOR_MAX_FREE_DEFAULT (2048*1024)
    
    /* Set defaults for config directives implemented here.  This is
     * called from core's pre-config hook, so MPMs which need to override
     * one of these should run their pre-config hook after that of core.
     */
    void mpm_common_pre_config(apr_pool_t *pconf)
    {
        ap_pid_fname = DEFAULT_PIDLOG;
        ap_max_requests_per_child = 0; /* unlimited */
        apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
        ap_coredumpdir_configured = 0;
        ap_graceful_shutdown_timeout = 0; /* unlimited */
        ap_max_mem_free = ALLOCATOR_MAX_FREE_DEFAULT;
        ap_thread_stacksize = 0; /* use system default */
    }
    
    /* 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;
    
    AP_DECLARE(void) ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode,
                                        apr_proc_t *ret, apr_pool_t *p,
                                        server_rec *s)
    {
        apr_status_t rv;
    
        ++wait_or_timeout_counter;
        if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) {
            wait_or_timeout_counter = 0;
            ap_run_monitor(p, s);
        }
    
        rv = apr_proc_wait_all_procs(ret, exitcode, status, APR_NOWAIT, p);
        ap_update_global_status();
    
        if (APR_STATUS_IS_EINTR(rv)) {
            ret->pid = -1;
            return;
        }
    
        if (APR_STATUS_IS_CHILD_DONE(rv)) {
            return;
        }
    
        apr_sleep(apr_time_from_sec(1));
        ret->pid = -1;
    }
    
    #if defined(TCP_NODELAY)
    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, APLOGNO(00542)
                         "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, APLOGNO(00543)
                         "%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, APLOGNO(00544)
                         "%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(_OSD_POSIX) || defined(OS2) || defined(WIN32) || defined(NETWARE)
        return 0;
    #else
        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
    }
    #endif /* def HAVE_INITGROUPS */
    
    /* standard mpm configuration handling */
    
    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 <VirtualHost>";
        }
    
        ap_pid_fname = arg;
        return NULL;
    }
    
    void ap_mpm_dump_pidfile(apr_pool_t *p, apr_file_t *out)
    {
        apr_file_printf(out, "PidFile: \"%s\"\n",
                        ap_server_root_relative(p, ap_pid_fname));
    }
    
    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;
        }
    
        if (!strcasecmp(cmd->cmd->name, "MaxRequestsPerChild")) {
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(00545)
                         "MaxRequestsPerChild is deprecated, use "
                         "MaxConnectionsPerChild instead.");
        }
    
        ap_max_requests_per_child = atoi(arg);
    
        return NULL;
    }
    
    const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy,
                                       const char *arg)
    {
        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->temp_pool, arg);
        if (!fname) {
            return apr_pstrcat(cmd->pool, "Invalid CoreDumpDirectory path ",
                               arg, NULL);
        }
        if (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;
    }
    
    AP_DECLARE(const char *)ap_mpm_set_graceful_shutdown(cmd_parms *cmd,
                                                         void *dummy,
                                                         const char *arg)
    {
        const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
        if (err != NULL) {
            return err;
        }
        ap_graceful_shutdown_timeout = atoi(arg);
        return NULL;
    }
    
    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;
        }
    
        errno = 0;
        value = strtol(arg, NULL, 10);
        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;
    }
    
    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;
        }
    
        errno = 0;
        value = strtol(arg, NULL, 10);
        if (value < 0 || errno == ERANGE)
            return apr_pstrcat(cmd->pool, "Invalid ThreadStackSize value: ",
                               arg, NULL);
    
        ap_thread_stacksize = (apr_size_t)value;
    
        return NULL;
    }
    
    AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
    {
        apr_status_t rv;
    
        if (ap_run_mpm_query(query_code, result, &rv) == DECLINED) {
            rv = APR_EGENERAL;
        }
    
        return rv;
    }
    
    static void end_gen(mpm_gen_info_t *gi)
    {
        ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
                     "end of generation %d", gi->gen);
        ap_run_end_generation(ap_server_conf, gi->gen);
        APR_RING_REMOVE(gi, link);
        APR_RING_INSERT_HEAD(unused_geninfo, gi, mpm_gen_info_t, link);
    }
    
    apr_status_t ap_mpm_end_gen_helper(void *unused) /* cleanup on pconf */
    {
        int gen = ap_config_generation - 1; /* differs from MPM generation */
        mpm_gen_info_t *cur;
    
        if (geninfo == NULL) {
            /* initial pconf teardown, MPM hasn't run */
            return APR_SUCCESS;
        }
    
        cur = APR_RING_FIRST(geninfo);
        while (cur != APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link) &&
               cur->gen != gen) {
            cur = APR_RING_NEXT(cur, link);
        }
    
        if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) {
            /* last child of generation already exited */
            ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
                         "no record of generation %d", gen);
        }
        else {
            cur->done = 1;
            if (cur->active == 0) {
                end_gen(cur);
            }
        }
    
        return APR_SUCCESS;
    }
    
    /* core's child-status hook
     * tracks number of remaining children per generation and
     * runs the end-generation hook when the last child of
     * a generation exits
     */
    void ap_core_child_status(server_rec *s, pid_t pid,
                              ap_generation_t gen, int slot,
                              mpm_child_status status)
    {
        mpm_gen_info_t *cur;
        const char *status_msg = "unknown status";
    
        if (!gen_head_init) { /* where to run this? */
            gen_head_init = 1;
            geninfo = apr_pcalloc(s->process->pool, sizeof *geninfo);
            unused_geninfo = apr_pcalloc(s->process->pool, sizeof *unused_geninfo);
            APR_RING_INIT(geninfo, mpm_gen_info_t, link);
            APR_RING_INIT(unused_geninfo, mpm_gen_info_t, link);
        }
    
        cur = APR_RING_FIRST(geninfo);
        while (cur != APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link) &&
               cur->gen != gen) {
            cur = APR_RING_NEXT(cur, link);
        }
    
        switch(status) {
        case MPM_CHILD_STARTED:
            status_msg = "started";
            if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) {
                /* first child for this generation */
                if (!APR_RING_EMPTY(unused_geninfo, mpm_gen_info_t, link)) {
                    cur = APR_RING_FIRST(unused_geninfo);
                    APR_RING_REMOVE(cur, link);
                    cur->active = cur->done = 0;
                }
                else {
                    cur = apr_pcalloc(s->process->pool, sizeof *cur);
                }
                cur->gen = gen;
                APR_RING_ELEM_INIT(cur, link);
                APR_RING_INSERT_HEAD(geninfo, cur, mpm_gen_info_t, link);
            }
            ap_random_parent_after_fork();
            ++cur->active;
            break;
        case MPM_CHILD_EXITED:
            ap_update_global_status();
            status_msg = "exited";
            if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00546)
                             "no record of generation %d of exiting child %" APR_PID_T_FMT,
                             gen, pid);
            }
            else {
                --cur->active;
                if (!cur->active && cur->done) { /* no children, server has stopped/restarted */
                    end_gen(cur);
                }
            }
            break;
        case MPM_CHILD_LOST_SLOT:
            status_msg = "lost slot";
            /* we don't track by slot, so it doesn't matter */
            break;
        }
        ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, s,
                     "mpm child %" APR_PID_T_FMT " (gen %d/slot %d) %s",
                     pid, gen, slot, status_msg);
    }
    
    AP_DECLARE(apr_status_t) ap_mpm_register_timed_callback(apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton)
    {
        return ap_run_mpm_register_timed_callback(t, cbfn, baton);
    }
    
    AP_DECLARE(const char *)ap_show_mpm(void)
    {
        const char *name = ap_run_mpm_get_name();
    
        if (!name) {
            name = "";
        }
    
        return name;
    }
    
    AP_DECLARE(const char *)ap_check_mpm(void)
    {
        static const char *last_mpm_name = NULL;
    
        if (!_hooks.link_mpm || _hooks.link_mpm->nelts == 0)
            return "No MPM loaded.";
        else if (_hooks.link_mpm->nelts > 1)
            return "More than one MPM loaded.";
    
        if (last_mpm_name) {
            if (strcmp(last_mpm_name, ap_show_mpm())) {
                return "The MPM cannot be changed during restart.";
            }
        }
        else {
            last_mpm_name = apr_pstrdup(ap_pglobal, ap_show_mpm());
        }
    
        return NULL;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/provider.c����������������������������������������������������������������������0000664�0001751�0001751�00000015313�14021717204�016127� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_tables.h"
    #include "apr_strings.h"
    
    #include "ap_provider.h"
    
    static apr_hash_t *global_providers = NULL;
    static apr_hash_t *global_providers_names = NULL;
    
    
    static apr_status_t cleanup_global_providers(void *ctx)
    {
        global_providers = NULL;
        global_providers_names = 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, *provider_version_hash;
    
        if (global_providers == NULL) {
            global_providers = apr_hash_make(pool);
            global_providers_names = apr_hash_make(pool);
            apr_pool_cleanup_register(pool, NULL, cleanup_global_providers,
                                      apr_pool_cleanup_null);
        }
    
        /* First, deal with storing the provider away */
        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);
    
        /* Now, tuck away the provider names in an easy-to-get format */
        provider_group_hash = apr_hash_get(global_providers_names, provider_group,
                                           APR_HASH_KEY_STRING);
    
        if (!provider_group_hash) {
            provider_group_hash = apr_hash_make(pool);
            apr_hash_set(global_providers_names, provider_group, APR_HASH_KEY_STRING,
                         provider_group_hash);
        }
    
        provider_version_hash = apr_hash_get(provider_group_hash, provider_version,
                                             APR_HASH_KEY_STRING);
    
        if (!provider_version_hash) {
            provider_version_hash = apr_hash_make(pool);
            apr_hash_set(provider_group_hash, provider_version, APR_HASH_KEY_STRING,
                         provider_version_hash);
        }
    
        /* just set it. no biggy if it was there before. */
        apr_hash_set(provider_version_hash, provider_name, APR_HASH_KEY_STRING,
                     provider_name);
    
        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);
    }
    
    AP_DECLARE(apr_array_header_t *) ap_list_provider_names(apr_pool_t *pool,
                                                  const char *provider_group,
                                                  const char *provider_version)
    {
        apr_array_header_t *ret = NULL;
        ap_list_provider_names_t *entry;
        apr_hash_t *provider_group_hash, *h;
        apr_hash_index_t *hi;
        char *val;
    
        if (global_providers_names == NULL) {
            goto out;
        }
    
        provider_group_hash = apr_hash_get(global_providers_names, provider_group,
                                           APR_HASH_KEY_STRING);
    
        if (provider_group_hash == NULL) {
            goto out;
        }
    
        h = apr_hash_get(provider_group_hash, provider_version, APR_HASH_KEY_STRING);
    
        if (h == NULL) {
            goto out;
        }
    
        ret = apr_array_make(pool, apr_hash_count(h), sizeof(ap_list_provider_names_t));
        for (hi = apr_hash_first(pool, h); hi; hi = apr_hash_next(hi)) {
            apr_hash_this(hi, NULL, NULL, (void *)&val);
            entry = apr_array_push(ret);
            entry->provider_name = apr_pstrdup(pool, val);
        }
        
    out:
        if (ret == NULL) {
            ret = apr_array_make(pool, 1, sizeof(ap_list_provider_names_t));
        }
        return ret;
    }
    
    AP_DECLARE(apr_array_header_t *) ap_list_provider_groups(apr_pool_t *pool)
    {
        apr_array_header_t *ret = apr_array_make(pool, 10, sizeof(ap_list_provider_groups_t));
        ap_list_provider_groups_t *entry;
        apr_hash_t *provider_group_hash;
        apr_hash_index_t *groups_hi, *vers_hi;
        char *group, *version;
    
        if (global_providers_names == NULL)
            return ret;
    
        for (groups_hi = apr_hash_first(pool, global_providers_names);
             groups_hi;
             groups_hi = apr_hash_next(groups_hi))
        {
            apr_hash_this(groups_hi, (void *)&group, NULL, (void *)&provider_group_hash);
            if (provider_group_hash == NULL)
                continue;
            for (vers_hi = apr_hash_first(pool, provider_group_hash);
                 vers_hi;
                 vers_hi = apr_hash_next(vers_hi))
            {
                apr_hash_this(vers_hi, (void *)&version, NULL, NULL);
    
                entry = apr_array_push(ret);
                entry->provider_group = group;
                entry->provider_version = version;
            }
        }
        return ret;
    }
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_cookies.c������������������������������������������������������������������0000664�0001751�0001751�00000021613�13012316274�016767� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_cookies.h"
    #include "apr_lib.h"
    #include "apr_strings.h"
    #include "http_config.h"
    #include "http_core.h"
    #include "http_log.h"
    
    #define LOG_PREFIX "ap_cookie: "
    
    /* we know core's module_index is 0 */
    #undef APLOG_MODULE_INDEX
    #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
    
    /**
     * Write an RFC2109 compliant cookie.
     *
     * @param r The request
     * @param name The name of the cookie.
     * @param val The value to place in the cookie.
     * @param attrs The string containing additional cookie attributes. If NULL, the
     *              DEFAULT_ATTRS will be used.
     * @param maxage If non zero, a Max-Age header will be added to the cookie.
     */
    AP_DECLARE(apr_status_t) ap_cookie_write(request_rec * r, const char *name, const char *val,
                                             const char *attrs, long maxage, ...)
    {
    
        const char *buffer;
        const char *rfc2109;
        apr_table_t *t;
        va_list vp;
    
        /* handle expiry */
        buffer = "";
        if (maxage) {
            buffer = apr_pstrcat(r->pool, "Max-Age=", apr_ltoa(r->pool, maxage), ";", NULL);
        }
    
        /* create RFC2109 compliant cookie */
        rfc2109 = apr_pstrcat(r->pool, name, "=", val, ";", buffer,
                              attrs && *attrs ? attrs : DEFAULT_ATTRS, NULL);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00007) LOG_PREFIX
                      "user '%s' set cookie: '%s'", r->user, rfc2109);
    
        /* write the cookie to the header table(s) provided */
        va_start(vp, maxage);
        while ((t = va_arg(vp, apr_table_t *))) {
            apr_table_addn(t, SET_COOKIE, rfc2109);
        }
        va_end(vp);
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Write an RFC2965 compliant cookie.
     *
     * @param r The request
     * @param name2 The name of the cookie.
     * @param val The value to place in the cookie.
     * @param attrs2 The string containing additional cookie attributes. If NULL, the
     *               DEFAULT_ATTRS will be used.
     * @param maxage If non zero, a Max-Age header will be added to the cookie.
     */
    AP_DECLARE(apr_status_t) ap_cookie_write2(request_rec * r, const char *name2, const char *val,
                                              const char *attrs2, long maxage, ...)
    {
    
        const char *buffer;
        const char *rfc2965;
        apr_table_t *t;
        va_list vp;
    
        /* handle expiry */
        buffer = "";
        if (maxage) {
            buffer = apr_pstrcat(r->pool, "Max-Age=", apr_ltoa(r->pool, maxage), ";", NULL);
        }
    
        /* create RFC2965 compliant cookie */
        rfc2965 = apr_pstrcat(r->pool, name2, "=", val, ";", buffer,
                              attrs2 && *attrs2 ? attrs2 : DEFAULT_ATTRS, NULL);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00008) LOG_PREFIX
                      "user '%s' set cookie2: '%s'", r->user, rfc2965);
    
        /* write the cookie to the header table(s) provided */
        va_start(vp, maxage);
        while ((t = va_arg(vp, apr_table_t *))) {
            apr_table_addn(t, SET_COOKIE2, rfc2965);
        }
        va_end(vp);
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Remove an RFC2109 compliant cookie.
     *
     * @param r The request
     * @param name The name of the cookie.
     */
    AP_DECLARE(apr_status_t) ap_cookie_remove(request_rec * r, const char *name, const char *attrs, ...)
    {
        apr_table_t *t;
        va_list vp;
    
        /* create RFC2109 compliant cookie */
        const char *rfc2109 = apr_pstrcat(r->pool, name, "=;Max-Age=0;",
                                    attrs ? attrs : CLEAR_ATTRS, NULL);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00009) LOG_PREFIX
                      "user '%s' removed cookie: '%s'", r->user, rfc2109);
    
        /* write the cookie to the header table(s) provided */
        va_start(vp, attrs);
        while ((t = va_arg(vp, apr_table_t *))) {
            apr_table_addn(t, SET_COOKIE, rfc2109);
        }
        va_end(vp);
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Remove an RFC2965 compliant cookie.
     *
     * @param r The request
     * @param name2 The name of the cookie.
     */
    AP_DECLARE(apr_status_t) ap_cookie_remove2(request_rec * r, const char *name2, const char *attrs2, ...)
    {
        apr_table_t *t;
        va_list vp;
    
        /* create RFC2965 compliant cookie */
        const char *rfc2965 = apr_pstrcat(r->pool, name2, "=;Max-Age=0;",
                                    attrs2 ? attrs2 : CLEAR_ATTRS, NULL);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00010) LOG_PREFIX
                      "user '%s' removed cookie2: '%s'", r->user, rfc2965);
    
        /* write the cookie to the header table(s) provided */
        va_start(vp, attrs2);
        while ((t = va_arg(vp, apr_table_t *))) {
            apr_table_addn(t, SET_COOKIE2, rfc2965);
        }
        va_end(vp);
    
        return APR_SUCCESS;
    
    }
    
    /* Iterate through the cookies, isolate our cookie and then remove it.
     *
     * If our cookie appears two or more times, but with different values,
     * remove it twice and set the duplicated flag to true. Remove any
     * $path or other attributes following our cookie if present. If we end
     * up with an empty cookie, remove the whole header.
     */
    static int extract_cookie_line(void *varg, const char *key, const char *val)
    {
        ap_cookie_do *v = varg;
        char *last1, *last2;
        char *cookie = apr_pstrdup(v->r->pool, val);
        const char *name = apr_pstrcat(v->r->pool, v->name ? v->name : "", "=", NULL);
        apr_size_t len = strlen(name);
        const char *new_cookie = "";
        const char *comma = ",";
        char *next1;
        const char *semi = ";";
        char *next2;
        const char *sep = "";
        int cookies = 0;
    
        /* find the cookie called name */
        int eat = 0;
        next1 = apr_strtok(cookie, comma, &last1);
        while (next1) {
            next2 = apr_strtok(next1, semi, &last2);
            while (next2) {
                char *trim = next2;
                while (apr_isspace(*trim)) {
                    trim++;
                }
                if (!strncmp(trim, name, len)) {
                    if (v->encoded) {
                        if (strcmp(v->encoded, trim + len)) {
                            v->duplicated = 1;
                        }
                    }
                    v->encoded = apr_pstrdup(v->r->pool, trim + len);
                    eat = 1;
                }
                else {
                    if (*trim != '$') {
                        cookies++;
                        eat = 0;
                    }
                    if (!eat) {
                        new_cookie = apr_pstrcat(v->r->pool, new_cookie, sep, next2, NULL);
                    }
                }
                next2 = apr_strtok(NULL, semi, &last2);
                sep = semi;
            }
    
            next1 = apr_strtok(NULL, comma, &last1);
            sep = comma;
        }
    
        /* any cookies left over? */
        if (cookies) {
            apr_table_addn(v->new_cookies, key, new_cookie);
        }
    
        return 1;
    }
    
    /**
     * Read a cookie called name, placing its value in val.
     *
     * Both the Cookie and Cookie2 headers are scanned for the cookie.
     *
     * If the cookie is duplicated, this function returns APR_EGENERAL. If found,
     * and if remove is non zero, the cookie will be removed from the headers, and
     * thus kept private from the backend.
     */
    AP_DECLARE(apr_status_t) ap_cookie_read(request_rec * r, const char *name, const char **val,
                                            int remove)
    {
    
        ap_cookie_do v;
        v.r = r;
        v.encoded = NULL;
        v.new_cookies = apr_table_make(r->pool, 10);
        v.duplicated = 0;
        v.name = name;
    
        apr_table_do(extract_cookie_line, &v, r->headers_in,
                     "Cookie", "Cookie2", NULL);
        if (v.duplicated) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00011) LOG_PREFIX
             "client submitted cookie '%s' more than once: %s", v.name, r->uri);
            return APR_EGENERAL;
        }
    
        /* remove our cookie(s), and replace them */
        if (remove) {
            apr_table_unset(r->headers_in, "Cookie");
            apr_table_unset(r->headers_in, "Cookie2");
            r->headers_in = apr_table_overlay(r->pool, r->headers_in, v.new_cookies);
        }
    
        *val = v.encoded;
    
        return APR_SUCCESS;
    
    }
    
    /**
     * Sanity check a given string that it exists, is not empty,
     * and does not contain the special characters '=', ';' and '&'.
     *
     * It is used to sanity check the cookie names.
     */
    AP_DECLARE(apr_status_t) ap_cookie_check_string(const char *string)
    {
        if (!string || !*string || ap_strchr_c(string, '=') || ap_strchr_c(string, '&') ||
            ap_strchr_c(string, ';')) {
            return APR_EGENERAL;
        }
        return APR_SUCCESS;
    }
    ���������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_charset.c������������������������������������������������������������������0000664�0001751�0001751�00000001777�12425122625�016777� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    
    apr_xlate_t *ap_hdrs_to_ascii, *ap_hdrs_from_ascii;
    
    #endif /*APR_CHARSET_EBCDIC */
    �httpd-2.4.64/server/util_expr_scan.c����������������������������������������������������������������0000664�0001751�0001751�00000217233�15032766627�017341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "util_expr_scan.c"
    
    #line 4 "util_expr_scan.c"
    
    #define  YY_INT_ALIGNED short int
    
    /* A lexical scanner generated by flex */
    
    #define FLEX_SCANNER
    #define YY_FLEX_MAJOR_VERSION 2
    #define YY_FLEX_MINOR_VERSION 5
    #define YY_FLEX_SUBMINOR_VERSION 35
    #if YY_FLEX_SUBMINOR_VERSION > 0
    #define FLEX_BETA
    #endif
    
    /* First, we deal with  platform-specific or compiler-specific issues. */
    
    /* begin standard C headers. */
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <stdlib.h>
    
    /* end standard C headers. */
    
    /* flex integer type definitions */
    
    #ifndef FLEXINT_H
    #define FLEXINT_H
    
    /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
    
    #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
    
    /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
     * if you want the limit (max/min) macros for int types. 
     */
    #ifndef __STDC_LIMIT_MACROS
    #define __STDC_LIMIT_MACROS 1
    #endif
    
    #include <inttypes.h>
    typedef int8_t flex_int8_t;
    typedef uint8_t flex_uint8_t;
    typedef int16_t flex_int16_t;
    typedef uint16_t flex_uint16_t;
    typedef int32_t flex_int32_t;
    typedef uint32_t flex_uint32_t;
    #else
    typedef signed char flex_int8_t;
    typedef short int flex_int16_t;
    typedef int flex_int32_t;
    typedef unsigned char flex_uint8_t; 
    typedef unsigned short int flex_uint16_t;
    typedef unsigned int flex_uint32_t;
    
    /* Limits of integral types. */
    #ifndef INT8_MIN
    #define INT8_MIN               (-128)
    #endif
    #ifndef INT16_MIN
    #define INT16_MIN              (-32767-1)
    #endif
    #ifndef INT32_MIN
    #define INT32_MIN              (-2147483647-1)
    #endif
    #ifndef INT8_MAX
    #define INT8_MAX               (127)
    #endif
    #ifndef INT16_MAX
    #define INT16_MAX              (32767)
    #endif
    #ifndef INT32_MAX
    #define INT32_MAX              (2147483647)
    #endif
    #ifndef UINT8_MAX
    #define UINT8_MAX              (255U)
    #endif
    #ifndef UINT16_MAX
    #define UINT16_MAX             (65535U)
    #endif
    #ifndef UINT32_MAX
    #define UINT32_MAX             (4294967295U)
    #endif
    
    #endif /* ! C99 */
    
    #endif /* ! FLEXINT_H */
    
    #ifdef __cplusplus
    
    /* The "const" storage-class-modifier is valid. */
    #define YY_USE_CONST
    
    #else	/* ! __cplusplus */
    
    /* C99 requires __STDC__ to be defined as 1. */
    #if defined (__STDC__)
    
    #define YY_USE_CONST
    
    #endif	/* defined (__STDC__) */
    #endif	/* ! __cplusplus */
    
    #ifdef YY_USE_CONST
    #define yyconst const
    #else
    #define yyconst
    #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)
    
    /* An opaque pointer. */
    #ifndef YY_TYPEDEF_YY_SCANNER_T
    #define YY_TYPEDEF_YY_SCANNER_T
    typedef void* yyscan_t;
    #endif
    
    /* For convenience, these vars (plus the bison vars far below)
       are macros in the reentrant scanner. */
    #define yyin yyg->yyin_r
    #define yyout yyg->yyout_r
    #define yyextra yyg->yyextra_r
    #define yyleng yyg->yyleng_r
    #define yytext yyg->yytext_r
    #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
    #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
    #define yy_flex_debug yyg->yy_flex_debug_r
    
    /* 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 yyg->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 ((yyg->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 ap_expr_yyrestart(yyin ,yyscanner )
    
    #define YY_END_OF_BUFFER_CHAR 0
    
    /* Size of default input buffer. */
    #ifndef YY_BUF_SIZE
    #ifdef __ia64__
    /* On IA-64, the buffer size is 16k, not 8k.
     * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
     * Ditto for the __ia64__ case accordingly.
     */
    #define YY_BUF_SIZE 32768
    #else
    #define YY_BUF_SIZE 16384
    #endif /* __ia64__ */
    #endif
    
    /* The state buf must be large enough to hold one state per character in the main buffer.
     */
    #define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
    
    #ifndef YY_TYPEDEF_YY_BUFFER_STATE
    #define YY_TYPEDEF_YY_BUFFER_STATE
    typedef struct yy_buffer_state *YY_BUFFER_STATE;
    #endif
    
    #define EOB_ACT_CONTINUE_SCAN 0
    #define EOB_ACT_END_OF_FILE 1
    #define EOB_ACT_LAST_MATCH 2
    
        #define YY_LESS_LINENO(n)
        
    /* Return all but the first "n" matched characters back to the input stream. */
    #define yyless(n) \
    	do \
    		{ \
    		/* Undo effects of setting up yytext. */ \
            int yyless_macro_arg = (n); \
            YY_LESS_LINENO(yyless_macro_arg);\
    		*yy_cp = yyg->yy_hold_char; \
    		YY_RESTORE_YY_MORE_OFFSET \
    		yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
    		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
    		} \
    	while ( 0 )
    
    #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
    
    #ifndef YY_TYPEDEF_YY_SIZE_T
    #define YY_TYPEDEF_YY_SIZE_T
    typedef size_t yy_size_t;
    #endif
    
    #ifndef YY_STRUCT_YY_BUFFER_STATE
    #define YY_STRUCT_YY_BUFFER_STATE
    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;
    
        int yy_bs_lineno; /**< The line count. */
        int yy_bs_column; /**< The column count. */
        
    	/* 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 ap_expr_yyrestart()), so that the user can continue scanning by
    	 * just pointing yyin at a new input file.
    	 */
    #define YY_BUFFER_EOF_PENDING 2
    
    	};
    #endif /* !YY_STRUCT_YY_BUFFER_STATE */
    
    /* 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".
     *
     * Returns the top of the stack, or NULL.
     */
    #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
                              ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
                              : NULL)
    
    /* Same as previous macro, but useful when we know that the buffer stack is not
     * NULL or when we need an lvalue. For internal use only.
     */
    #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
    
    void ap_expr_yyrestart (FILE *input_file ,yyscan_t yyscanner );
    void ap_expr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
    YY_BUFFER_STATE ap_expr_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
    void ap_expr_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
    void ap_expr_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
    void ap_expr_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
    void ap_expr_yypop_buffer_state (yyscan_t yyscanner );
    
    static void ap_expr_yyensure_buffer_stack (yyscan_t yyscanner );
    static void ap_expr_yy_load_buffer_state (yyscan_t yyscanner );
    static void ap_expr_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
    
    #define YY_FLUSH_BUFFER ap_expr_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
    
    YY_BUFFER_STATE ap_expr_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
    YY_BUFFER_STATE ap_expr_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
    YY_BUFFER_STATE ap_expr_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
    
    void *ap_expr_yyalloc (yy_size_t ,yyscan_t yyscanner );
    void *ap_expr_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
    void ap_expr_yyfree (void * ,yyscan_t yyscanner );
    
    #define yy_new_buffer ap_expr_yy_create_buffer
    
    #define yy_set_interactive(is_interactive) \
    	{ \
    	if ( ! YY_CURRENT_BUFFER ){ \
            ap_expr_yyensure_buffer_stack (yyscanner); \
    		YY_CURRENT_BUFFER_LVALUE =    \
                ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
    	} \
    	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
    	}
    
    #define yy_set_bol(at_bol) \
    	{ \
    	if ( ! YY_CURRENT_BUFFER ){\
            ap_expr_yyensure_buffer_stack (yyscanner); \
    		YY_CURRENT_BUFFER_LVALUE =    \
                ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
    	} \
    	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
    	}
    
    #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
    
    /* Begin user sect3 */
    
    #define ap_expr_yywrap(n) 1
    #define YY_SKIP_YYWRAP
    
    typedef unsigned char YY_CHAR;
    
    typedef int yy_state_type;
    
    #define yytext_ptr yytext_r
    
    static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
    static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
    static int yy_get_next_buffer (yyscan_t yyscanner );
    static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
    
    /* Done after the current pattern has been matched and before the
     * corresponding action - sets up yytext.
     */
    #define YY_DO_BEFORE_ACTION \
    	yyg->yytext_ptr = yy_bp; \
    	yyleng = (size_t) (yy_cp - yy_bp); \
    	yyg->yy_hold_char = *yy_cp; \
    	*yy_cp = '\0'; \
    	yyg->yy_c_buf_p = yy_cp;
    
    #define YY_NUM_RULES 67
    #define YY_END_OF_BUFFER 68
    /* This struct is not used in this scanner,
       but its presence is necessary. */
    struct yy_trans_info
    	{
    	flex_int32_t yy_verify;
    	flex_int32_t yy_nxt;
    	};
    static yyconst flex_int16_t yy_accept[124] =
        {   0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,   68,   66,    1,   43,    2,   66,   66,   66,
           65,   66,   44,   26,   63,   32,   30,   34,   64,   64,
           64,   64,   64,   64,   64,   64,   64,   64,   64,   66,
           14,    4,    3,   17,   17,   67,   17,   23,    4,   22,
           20,   21,   67,   16,   16,   24,   27,   29,   28,    1,
           31,   37,   19,   18,   39,   63,   59,   59,   59,   59,
           59,   59,   33,   30,   36,   35,   64,   64,   57,   64,
           55,   54,   58,   53,   52,   25,   25,   56,   64,   40,
           64,   41,   14,   13,   15,   12,    5,    6,   10,   11,
    
            7,    8,    9,   20,   60,   46,   48,   50,   45,   49,
           51,   47,   38,   64,   42,   64,    5,    6,   64,   61,
            5,   62,    0
        } ;
    
    static yyconst flex_int32_t 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,    6,    7,    8,    9,    5,   10,
           10,    1,    1,   11,   12,   13,   14,   15,   15,   15,
           15,   15,   15,   15,   15,   16,   16,   17,    6,   18,
           19,   20,    6,    1,   21,   21,   21,   21,   21,   21,
           21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
           21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
            1,   22,    1,    6,   23,    1,   24,   25,   21,   26,
    
           27,   28,   29,   21,   30,   21,   21,   31,   32,   33,
           34,   21,   35,   36,   37,   38,   39,   21,   21,   21,
           21,   21,   40,   41,   42,   43,    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 flex_int32_t yy_meta[44] =
        {   0,
            1,    1,    2,    1,    2,    1,    2,    2,    1,    1,
            1,    1,    1,    1,    3,    3,    1,    1,    1,    1,
            3,    2,    3,    3,    3,    3,    3,    3,    3,    3,
            3,    3,    3,    3,    3,    3,    3,    3,    3,    1,
            1,    2,    1
        } ;
    
    static yyconst flex_int16_t yy_base[133] =
        {   0,
            0,    0,   41,   47,   89,    0,  130,  136,    0,    0,
          147,  146,  175,  275,   54,   28,  275,   43,  134,  164,
          275,  164,  275,  275,   45,  152,   32,  151,    0,  136,
          133,  143,   26,  133,   35,  194,   38,  129,  128,  122,
            0,  275,  275,   51,  122,  221,  275,  275,  275,  275,
            0,  275,  275,   61,  121,  275,  275,  275,  275,   76,
          275,  275,  275,  275,  275,   65,    0,  125,   47,  126,
          107,  130,  275,  275,  275,  275,    0,  130,    0,  124,
            0,    0,    0,    0,    0,  275,    0,    0,  104,    0,
          101,  275,    0,  275,  275,  275,   71,  131,  275,  275,
    
          275,  275,  275,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,   99,    0,   61,  133,  135,   57,    0,
          138,    0,  275,  259,  262,  265,   79,   67,  268,  271,
           65,   42
        } ;
    
    static yyconst flex_int16_t yy_def[133] =
        {   0,
          123,    1,  124,  124,  123,    5,  124,  124,  125,  125,
          126,  126,  123,  123,  123,  123,  123,  123,  123,  123,
          123,  127,  123,  123,  123,  123,  123,  123,  128,  128,
          128,  128,  128,  128,  128,  128,  128,  128,  128,  123,
          129,  123,  123,  123,  123,  130,  123,  123,  123,  123,
          131,  123,  123,  123,  123,  123,  123,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  132,  132,  132,  132,
          132,  132,  123,  123,  123,  123,  128,  128,  128,  128,
          128,  128,  128,  128,  128,  123,  128,  128,  128,  128,
          128,  123,  129,  123,  123,  123,  123,  123,  123,  123,
    
          123,  123,  123,  131,  132,  132,  132,  132,  132,  132,
          132,  132,  128,  128,  128,  128,  123,  123,  128,  128,
          123,  128,    0,  123,  123,  123,  123,  123,  123,  123,
          123,  123
        } ;
    
    static yyconst flex_int16_t yy_nxt[319] =
        {   0,
           14,   15,   15,   16,   17,   14,   18,   19,   20,   21,
           21,   22,   23,   24,   25,   25,   21,   26,   27,   28,
           29,   14,   14,   30,   29,   29,   31,   32,   33,   34,
           35,   36,   37,   38,   29,   29,   29,   39,   29,   21,
           40,   21,   14,   42,  105,   43,   61,   44,   45,   42,
           74,   43,   81,   44,   45,   60,   60,   63,   63,   66,
           66,   84,   46,   82,   88,   94,   94,  104,   46,   77,
           62,   89,   85,  107,   75,   94,   94,   60,   60,   66,
           66,   67,   47,  122,  108,  117,  118,  120,   47,   48,
           48,   49,   48,   48,   48,   48,   48,   48,   48,   48,
    
           48,   48,   48,   48,   48,   50,   48,   48,   48,   51,
           48,   48,   51,   51,   51,   51,   51,   51,   51,   51,
           51,   51,   51,   51,   51,   51,   51,   51,   48,   48,
           52,   48,   42,  110,   53,  119,   54,   55,   42,  116,
           53,  115,   54,   55,  111,  118,  118,  121,  118,  118,
          118,   46,  118,  118,  114,  113,  112,   46,  109,  106,
           95,   95,   92,   91,   90,   83,   80,   79,   78,   76,
           73,   56,   65,   64,  123,   59,   59,   56,   66,   66,
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
           68,  123,   69,   70,   71,  123,   72,   86,   86,   86,
    
           86,   86,  123,  123,   86,   86,   86,   86,  123,  123,
           86,  123,  123,  123,  123,  123,   87,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
          123,  123,  123,  123,   86,   97,   98,  123,  123,  123,
          123,  123,  123,  123,  123,   99,  123,  123,  100,  123,
          123,  123,  123,  101,  123,  123,  102,  123,  103,   41,
           41,   41,   57,   57,   57,   58,   58,   58,   93,  123,
           93,   96,   96,   96,   13,  123,  123,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
    
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  123,  123
        } ;
    
    static yyconst flex_int16_t yy_chk[319] =
        {   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,    1,    1,    1,    1,    1,    1,    1,    1,
            1,    1,    1,    3,  132,    3,   16,    3,    3,    4,
           27,    4,   33,    4,    4,   15,   15,   18,   18,   25,
           25,   35,    3,   33,   37,   44,   44,  131,    4,  128,
           16,   37,   35,   69,   27,   54,   54,   60,   60,   66,
           66,  127,    3,  119,   69,   97,   97,  116,    4,    5,
            5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
    
            5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
            5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
            5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
            5,    5,    7,   71,    7,  114,    7,    7,    8,   91,
            8,   89,    8,    8,   71,   98,   98,  117,  117,  118,
          118,    7,  121,  121,   80,   78,   72,    8,   70,   68,
           55,   45,   40,   39,   38,   34,   32,   31,   30,   28,
           26,    7,   20,   19,   13,   12,   11,    8,   22,   22,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           22,    0,   22,   22,   22,    0,   22,   36,   36,   36,
    
           36,   36,    0,    0,   36,   36,   36,   36,    0,    0,
           36,    0,    0,    0,    0,    0,   36,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,   36,   46,   46,    0,    0,    0,
            0,    0,    0,    0,    0,   46,    0,    0,   46,    0,
            0,    0,    0,   46,    0,    0,   46,    0,   46,  124,
          124,  124,  125,  125,  125,  126,  126,  126,  129,    0,
          129,  130,  130,  130,  123,  123,  123,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
    
          123,  123,  123,  123,  123,  123,  123,  123,  123,  123,
          123,  123,  123,  123,  123,  123,  123,  123
        } ;
    
    /* 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
    #line 1 "util_expr_scan.l"
    /* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    /*
     *  ap_expr_scan.l, based on ssl_expr_scan.l from mod_ssl
     */
    /*  _________________________________________________________________
    **
    **  Expression Scanner
    **  _________________________________________________________________
    */
    #define YY_NO_INPUT 1
    
    
    
    
    #line 43 "util_expr_scan.l"
    #include "util_expr_private.h"
    #include "util_expr_parse.h"
    
    #undef  YY_INPUT
    #define YY_INPUT(buf,result,max_size)                       \
    {                                                           \
        if ((result = MIN(max_size, yyextra->inputbuf           \
                                  + yyextra->inputlen           \
                                  - yyextra->inputptr)) <= 0)   \
        {                                                       \
            result = YY_NULL;                                   \
        }                                                       \
        else {                                                  \
            memcpy(buf, yyextra->inputptr, result);             \
            yyextra->inputptr += result;                        \
        }                                                       \
    }
    
    #define YY_EXTRA_TYPE ap_expr_parse_ctx_t*
    
    #define PERROR(msg) do { yyextra->error2 = msg ; return T_ERROR; } while (0)
    
    #define str_ptr     (yyextra->scan_ptr)
    #define str_buf     (yyextra->scan_buf)
    #define str_del     (yyextra->scan_del)
    
    #define STR_APPEND(c) do {                          \
            *str_ptr++ = (c);                           \
            if (str_ptr >= str_buf + sizeof(str_buf))   \
                PERROR("String too long");              \
        } while (0)
    
    #line 615 "util_expr_scan.c"
    
    #define INITIAL 0
    #define str 1
    #define var 2
    #define vararg 3
    #define regex 4
    #define regex_flags 5
    
    #ifndef YY_NO_UNISTD_H
    /* Special case for "unistd.h", since it is non-ANSI. We include it way
     * down here because we want the user's section 1 to have been scanned first.
     * The user has a chance to override it with an option.
     */
    #include <unistd.h>
    #endif
    
    #ifndef YY_EXTRA_TYPE
    #define YY_EXTRA_TYPE void *
    #endif
    
    /* Holds the entire state of the reentrant scanner. */
    struct yyguts_t
        {
    
        /* User-defined. Not touched by flex. */
        YY_EXTRA_TYPE yyextra_r;
    
        /* The rest are the same as the globals declared in the non-reentrant scanner. */
        FILE *yyin_r, *yyout_r;
        size_t yy_buffer_stack_top; /**< index of top of stack. */
        size_t yy_buffer_stack_max; /**< capacity of stack. */
        YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
        char yy_hold_char;
        int yy_n_chars;
        int yyleng_r;
        char *yy_c_buf_p;
        int yy_init;
        int yy_start;
        int yy_did_buffer_switch_on_eof;
        int yy_start_stack_ptr;
        int yy_start_stack_depth;
        int *yy_start_stack;
        yy_state_type yy_last_accepting_state;
        char* yy_last_accepting_cpos;
    
        int yylineno_r;
        int yy_flex_debug_r;
    
        char *yytext_r;
        int yy_more_flag;
        int yy_more_len;
    
        YYSTYPE * yylval_r;
    
        }; /* end struct yyguts_t */
    
    static int yy_init_globals (yyscan_t yyscanner );
    
        /* This must go here because YYSTYPE and YYLTYPE are included
         * from bison output in section 1.*/
        #    define yylval yyg->yylval_r
        
    int ap_expr_yylex_init (yyscan_t* scanner);
    
    int ap_expr_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
    
    /* Accessor methods to globals.
       These are made visible to non-reentrant scanners for convenience. */
    
    int ap_expr_yylex_destroy (yyscan_t yyscanner );
    
    int ap_expr_yyget_debug (yyscan_t yyscanner );
    
    void ap_expr_yyset_debug (int debug_flag ,yyscan_t yyscanner );
    
    YY_EXTRA_TYPE ap_expr_yyget_extra (yyscan_t yyscanner );
    
    void ap_expr_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
    
    FILE *ap_expr_yyget_in (yyscan_t yyscanner );
    
    void ap_expr_yyset_in  (FILE * in_str ,yyscan_t yyscanner );
    
    FILE *ap_expr_yyget_out (yyscan_t yyscanner );
    
    void ap_expr_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
    
    int ap_expr_yyget_leng (yyscan_t yyscanner );
    
    char *ap_expr_yyget_text (yyscan_t yyscanner );
    
    int ap_expr_yyget_lineno (yyscan_t yyscanner );
    
    void ap_expr_yyset_lineno (int line_number ,yyscan_t yyscanner );
    
    YYSTYPE * ap_expr_yyget_lval (yyscan_t yyscanner );
    
    void ap_expr_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
    
    /* Macros after this point can all be overridden by user definitions in
     * section 1.
     */
    
    #ifndef YY_SKIP_YYWRAP
    #ifdef __cplusplus
    extern "C" int ap_expr_yywrap (yyscan_t yyscanner );
    #else
    extern int ap_expr_yywrap (yyscan_t yyscanner );
    #endif
    #endif
    
    #ifndef yytext_ptr
    static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
    #endif
    
    #ifdef YY_NEED_STRLEN
    static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
    #endif
    
    #ifndef YY_NO_INPUT
    
    #ifdef __cplusplus
    static int yyinput (yyscan_t yyscanner );
    #else
    static int input (yyscan_t yyscanner );
    #endif
    
    #endif
    
        static void yy_push_state (int new_state ,yyscan_t yyscanner);
        
        static void yy_pop_state (yyscan_t yyscanner );
        
    /* Amount of stuff to slurp up with each read. */
    #ifndef YY_READ_BUF_SIZE
    #ifdef __ia64__
    /* On IA-64, the buffer size is 16k, not 8k */
    #define YY_READ_BUF_SIZE 16384
    #else
    #define YY_READ_BUF_SIZE 8192
    #endif /* __ia64__ */
    #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 do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
    #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_LVALUE->yy_is_interactive ) \
    		{ \
    		int c = '*'; \
    		size_t 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 \
    		{ \
    		errno=0; \
    		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
    			{ \
    			if( errno != EINTR) \
    				{ \
    				YY_FATAL_ERROR( "input in flex scanner failed" ); \
    				break; \
    				} \
    			errno=0; \
    			clearerr(yyin); \
    			} \
    		}\
    \
    
    #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 , yyscanner)
    #endif
    
    /* end tables serialization structures and prototypes */
    
    /* Default declaration of generated scanner - a define so the user can
     * easily add parameters.
     */
    #ifndef YY_DECL
    #define YY_DECL_IS_OURS 1
    
    extern int ap_expr_yylex \
                   (YYSTYPE * yylval_param ,yyscan_t yyscanner);
    
    #define YY_DECL int ap_expr_yylex \
                   (YYSTYPE * yylval_param , yyscan_t yyscanner)
    #endif /* !YY_DECL */
    
    /* 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
    
    /** The main scanner function which does all the work.
     */
    YY_DECL
    {
    	register yy_state_type yy_current_state;
    	register char *yy_cp, *yy_bp;
    	register int yy_act;
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    #line 78 "util_expr_scan.l"
    
    
      char  regex_buf[MAX_STRING_LEN];
      char *regex_ptr = NULL;
      char  regex_del = '\0';
    
    
     /*
      * Set initial state for string expressions
      */
      if (yyextra->at_start) {
        yyextra->at_start = 0;
        if (yyextra->flags & AP_EXPR_FLAG_STRING_RESULT) {
            BEGIN(str);
            return T_EXPR_STRING;
        }
        else {
            return T_EXPR_BOOL;
        }
      }
    
    
     /*
      * Whitespaces
      */
    #line 886 "util_expr_scan.c"
    
        yylval = yylval_param;
    
    	if ( !yyg->yy_init )
    		{
    		yyg->yy_init = 1;
    
    #ifdef YY_USER_INIT
    		YY_USER_INIT;
    #endif
    
    		if ( ! yyg->yy_start )
    			yyg->yy_start = 1;	/* first start state */
    
    		if ( ! yyin )
    			yyin = stdin;
    
    		if ( ! yyout )
    			yyout = stdout;
    
    		if ( ! YY_CURRENT_BUFFER ) {
    			ap_expr_yyensure_buffer_stack (yyscanner);
    			YY_CURRENT_BUFFER_LVALUE =
    				ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
    		}
    
    		ap_expr_yy_load_buffer_state(yyscanner );
    		}
    
    	while ( 1 )		/* loops until end-of-file is reached */
    		{
    		yy_cp = yyg->yy_c_buf_p;
    
    		/* Support of yytext. */
    		*yy_cp = yyg->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 = yyg->yy_start;
    yy_match:
    		do
    			{
    			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
    			if ( yy_accept[yy_current_state] )
    				{
    				yyg->yy_last_accepting_state = yy_current_state;
    				yyg->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 >= 124 )
    					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 != 123 );
    		yy_cp = yyg->yy_last_accepting_cpos;
    		yy_current_state = yyg->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 = yyg->yy_hold_char;
    			yy_cp = yyg->yy_last_accepting_cpos;
    			yy_current_state = yyg->yy_last_accepting_state;
    			goto yy_find_action;
    
    case 1:
    /* rule 1 can match eol */
    YY_RULE_SETUP
    #line 103 "util_expr_scan.l"
    { 
        /* NOP */
    }
    	YY_BREAK
    /*
      * strings ("..." and '...')
      */
    case 2:
    YY_RULE_SETUP
    #line 110 "util_expr_scan.l"
    {
        str_ptr = str_buf;
        str_del = yytext[0];
        BEGIN(str);
        return T_STR_BEGIN;
    }
    	YY_BREAK
    case 3:
    YY_RULE_SETUP
    #line 116 "util_expr_scan.l"
    {
        if (yytext[0] == str_del) {
            if (YY_START == var) {
                PERROR("Unterminated variable in string");
            }
            else if (str_ptr == str_buf) {
                BEGIN(INITIAL);
                return T_STR_END;
            }
            else {
                /* return what we have so far and scan delimiter again */
                *str_ptr = '\0';
                yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
                yyless(0);
                str_ptr = str_buf;
                return T_STRING;
            }
        }
        else {
            STR_APPEND(yytext[0]);
        }
    }
    	YY_BREAK
    case 4:
    /* rule 4 can match eol */
    YY_RULE_SETUP
    #line 138 "util_expr_scan.l"
    {
        PERROR("Unterminated string or variable");
    }
    	YY_BREAK
    case YY_STATE_EOF(var):
    case YY_STATE_EOF(vararg):
    #line 141 "util_expr_scan.l"
    {
        PERROR("Unterminated string or variable");
    }
    	YY_BREAK
    case YY_STATE_EOF(str):
    #line 144 "util_expr_scan.l"
    {
        if (!(yyextra->flags & AP_EXPR_FLAG_STRING_RESULT)) {
            PERROR("Unterminated string or variable");
        }
        else {
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            str_ptr = str_buf;
            BEGIN(INITIAL);
            return T_STRING;
        }
    }
    	YY_BREAK
    case 5:
    YY_RULE_SETUP
    #line 157 "util_expr_scan.l"
    {
        int result;
    
        (void)sscanf(yytext+1, "%o", &result);
        if (result > 0xff) {
            PERROR("Escape sequence out of bound");
        }
        else {
            STR_APPEND(result);
        }
    }
    	YY_BREAK
    case 6:
    YY_RULE_SETUP
    #line 168 "util_expr_scan.l"
    {
        PERROR("Bad escape sequence");
    }
    	YY_BREAK
    case 7:
    YY_RULE_SETUP
    #line 171 "util_expr_scan.l"
    { STR_APPEND('\n'); }
    	YY_BREAK
    case 8:
    YY_RULE_SETUP
    #line 172 "util_expr_scan.l"
    { STR_APPEND('\r'); }
    	YY_BREAK
    case 9:
    YY_RULE_SETUP
    #line 173 "util_expr_scan.l"
    { STR_APPEND('\t'); }
    	YY_BREAK
    case 10:
    YY_RULE_SETUP
    #line 174 "util_expr_scan.l"
    { STR_APPEND('\b'); }
    	YY_BREAK
    case 11:
    YY_RULE_SETUP
    #line 175 "util_expr_scan.l"
    { STR_APPEND('\f'); }
    	YY_BREAK
    case 12:
    /* rule 12 can match eol */
    YY_RULE_SETUP
    #line 176 "util_expr_scan.l"
    { STR_APPEND(yytext[1]); }
    	YY_BREAK
    /* regexp backref inside string/arg */
    case 13:
    YY_RULE_SETUP
    #line 179 "util_expr_scan.l"
    {
        if (str_ptr != str_buf) {
            /* return what we have so far and scan '$x' again */
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            str_ptr = str_buf;
            yyless(0);
            return T_STRING;
        }
        else {
            yylval->num = yytext[1] - '0';
            return T_REGEX_BACKREF;
        }
    }
    	YY_BREAK
    case 14:
    YY_RULE_SETUP
    #line 194 "util_expr_scan.l"
    {
        char *cp = yytext;
        while (*cp != '\0') {
            STR_APPEND(*cp);
            cp++;
        }
    }
    	YY_BREAK
    /* variable inside string/arg */
    case 15:
    YY_RULE_SETUP
    #line 203 "util_expr_scan.l"
    {
        if (str_ptr != str_buf) {
            /* return what we have so far and scan '%{' again */
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            yyless(0);
            str_ptr = str_buf;
            return T_STRING;
        }
        else {
            yy_push_state(var, yyscanner);
            return T_VAR_BEGIN;
        }
    }
    	YY_BREAK
    case 16:
    YY_RULE_SETUP
    #line 218 "util_expr_scan.l"
    {
         STR_APPEND(yytext[0]);
    }
    	YY_BREAK
    case 17:
    YY_RULE_SETUP
    #line 222 "util_expr_scan.l"
    {
         STR_APPEND(yytext[0]);
    }
    	YY_BREAK
    case 18:
    YY_RULE_SETUP
    #line 226 "util_expr_scan.l"
    {
        yy_push_state(var, yyscanner);
        return T_VAR_BEGIN;
    }
    	YY_BREAK
    case 19:
    YY_RULE_SETUP
    #line 231 "util_expr_scan.l"
    {
        yylval->num = yytext[1] - '0';
        return T_REGEX_BACKREF;
    }
    	YY_BREAK
    /*
      * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
      */
    case 20:
    YY_RULE_SETUP
    #line 239 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
        return T_ID;
    }
    	YY_BREAK
    case 21:
    YY_RULE_SETUP
    #line 244 "util_expr_scan.l"
    {
        yy_pop_state(yyscanner);
        return T_VAR_END;
    }
    	YY_BREAK
    case 22:
    YY_RULE_SETUP
    #line 249 "util_expr_scan.l"
    {
        BEGIN(vararg);
        return yytext[0];
    }
    	YY_BREAK
    case 23:
    /* rule 23 can match eol */
    YY_RULE_SETUP
    #line 254 "util_expr_scan.l"
    {
        char *msg = apr_psprintf(yyextra->pool,
                                 "Invalid character in variable name '%c'", yytext[0]);
        PERROR(msg);
    }
    	YY_BREAK
    case 24:
    YY_RULE_SETUP
    #line 260 "util_expr_scan.l"
    {
        if (str_ptr != str_buf) {
            /* return what we have so far and scan '}' again */
            *str_ptr = '\0';
            yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
            str_ptr = str_buf;
            yyless(0);
            return T_STRING;
        }
        else {
            yy_pop_state(yyscanner);
            return T_VAR_END;
        }
    }
    	YY_BREAK
    /*
      * Regular Expression
      */
    case 25:
    YY_RULE_SETUP
    #line 278 "util_expr_scan.l"
    {
        regex_del = yytext[1];
        regex_ptr = regex_buf;
        BEGIN(regex);
    }
    	YY_BREAK
    case 26:
    YY_RULE_SETUP
    #line 283 "util_expr_scan.l"
    {
        regex_del = yytext[0];
        regex_ptr = regex_buf;
        BEGIN(regex);
    }
    	YY_BREAK
    case 27:
    /* rule 27 can match eol */
    YY_RULE_SETUP
    #line 288 "util_expr_scan.l"
    {
        if (yytext[0] == regex_del) {
            *regex_ptr = '\0';
            BEGIN(regex_flags);
        }
        else {
            *regex_ptr++ = yytext[0];
            if (regex_ptr >= regex_buf + sizeof(regex_buf))
                PERROR("Regexp too long");
        }
    }
    	YY_BREAK
    case 28:
    YY_RULE_SETUP
    #line 299 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
        BEGIN(INITIAL);
        return T_REGEX_I;
    }
    	YY_BREAK
    case 29:
    /* rule 29 can match eol */
    YY_RULE_SETUP
    #line 304 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
        yyless(0);
        BEGIN(INITIAL);
        return T_REGEX;
    }
    	YY_BREAK
    case YY_STATE_EOF(regex_flags):
    #line 310 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
        BEGIN(INITIAL);
        return T_REGEX;
    }
    	YY_BREAK
    /*
      * Operators
      */
    case 30:
    YY_RULE_SETUP
    #line 319 "util_expr_scan.l"
    { return T_OP_STR_EQ; }
    	YY_BREAK
    case 31:
    YY_RULE_SETUP
    #line 320 "util_expr_scan.l"
    { return T_OP_STR_NE; }
    	YY_BREAK
    case 32:
    YY_RULE_SETUP
    #line 321 "util_expr_scan.l"
    { return T_OP_STR_LT; }
    	YY_BREAK
    case 33:
    YY_RULE_SETUP
    #line 322 "util_expr_scan.l"
    { return T_OP_STR_LE; }
    	YY_BREAK
    case 34:
    YY_RULE_SETUP
    #line 323 "util_expr_scan.l"
    { return T_OP_STR_GT; }
    	YY_BREAK
    case 35:
    YY_RULE_SETUP
    #line 324 "util_expr_scan.l"
    { return T_OP_STR_GE; }
    	YY_BREAK
    case 36:
    YY_RULE_SETUP
    #line 325 "util_expr_scan.l"
    { return T_OP_REG; }
    	YY_BREAK
    case 37:
    YY_RULE_SETUP
    #line 326 "util_expr_scan.l"
    { return T_OP_NRE; }
    	YY_BREAK
    case 38:
    YY_RULE_SETUP
    #line 327 "util_expr_scan.l"
    { return T_OP_AND; }
    	YY_BREAK
    case 39:
    YY_RULE_SETUP
    #line 328 "util_expr_scan.l"
    { return T_OP_AND; }
    	YY_BREAK
    case 40:
    YY_RULE_SETUP
    #line 329 "util_expr_scan.l"
    { return T_OP_OR; }
    	YY_BREAK
    case 41:
    YY_RULE_SETUP
    #line 330 "util_expr_scan.l"
    { return T_OP_OR; }
    	YY_BREAK
    case 42:
    YY_RULE_SETUP
    #line 331 "util_expr_scan.l"
    { return T_OP_NOT; }
    	YY_BREAK
    case 43:
    YY_RULE_SETUP
    #line 332 "util_expr_scan.l"
    { return T_OP_NOT; }
    	YY_BREAK
    case 44:
    YY_RULE_SETUP
    #line 333 "util_expr_scan.l"
    { return T_OP_CONCAT; }
    	YY_BREAK
    case 45:
    YY_RULE_SETUP
    #line 334 "util_expr_scan.l"
    { return T_OP_IN; }
    	YY_BREAK
    case 46:
    YY_RULE_SETUP
    #line 335 "util_expr_scan.l"
    { return T_OP_EQ; }
    	YY_BREAK
    case 47:
    YY_RULE_SETUP
    #line 336 "util_expr_scan.l"
    { return T_OP_NE; }
    	YY_BREAK
    case 48:
    YY_RULE_SETUP
    #line 337 "util_expr_scan.l"
    { return T_OP_GE; }
    	YY_BREAK
    case 49:
    YY_RULE_SETUP
    #line 338 "util_expr_scan.l"
    { return T_OP_LE; }
    	YY_BREAK
    case 50:
    YY_RULE_SETUP
    #line 339 "util_expr_scan.l"
    { return T_OP_GT; }
    	YY_BREAK
    case 51:
    YY_RULE_SETUP
    #line 340 "util_expr_scan.l"
    { return T_OP_LT; }
    	YY_BREAK
    /* for compatibility with ssl_expr */
    case 52:
    YY_RULE_SETUP
    #line 343 "util_expr_scan.l"
    { return T_OP_LT; }
    	YY_BREAK
    case 53:
    YY_RULE_SETUP
    #line 344 "util_expr_scan.l"
    { return T_OP_LE; }
    	YY_BREAK
    case 54:
    YY_RULE_SETUP
    #line 345 "util_expr_scan.l"
    { return T_OP_GT; }
    	YY_BREAK
    case 55:
    YY_RULE_SETUP
    #line 346 "util_expr_scan.l"
    { return T_OP_GE; }
    	YY_BREAK
    case 56:
    YY_RULE_SETUP
    #line 347 "util_expr_scan.l"
    { return T_OP_NE; }
    	YY_BREAK
    case 57:
    YY_RULE_SETUP
    #line 348 "util_expr_scan.l"
    { return T_OP_EQ; }
    	YY_BREAK
    case 58:
    YY_RULE_SETUP
    #line 349 "util_expr_scan.l"
    { return T_OP_IN; }
    	YY_BREAK
    case 59:
    YY_RULE_SETUP
    #line 351 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
        return T_OP_UNARY;
    }
    	YY_BREAK
    case 60:
    YY_RULE_SETUP
    #line 356 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
        return T_OP_BINARY;
    }
    	YY_BREAK
    /*
      * Specials
      */
    case 61:
    YY_RULE_SETUP
    #line 364 "util_expr_scan.l"
    { return T_TRUE; }
    	YY_BREAK
    case 62:
    YY_RULE_SETUP
    #line 365 "util_expr_scan.l"
    { return T_FALSE; }
    	YY_BREAK
    /*
      * Digits
      */
    case 63:
    YY_RULE_SETUP
    #line 370 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
        return T_DIGIT;
    }
    	YY_BREAK
    /*
      * Identifiers
      */
    case 64:
    YY_RULE_SETUP
    #line 378 "util_expr_scan.l"
    {
        yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
        return T_ID;
    }
    	YY_BREAK
    /*
      * These are parts of the grammar and are returned as is
      */
    case 65:
    YY_RULE_SETUP
    #line 386 "util_expr_scan.l"
    {
        return yytext[0];
    }
    	YY_BREAK
    /*
      * Anything else is an error
      */
    case 66:
    /* rule 66 can match eol */
    YY_RULE_SETUP
    #line 393 "util_expr_scan.l"
    {
        char *msg = apr_psprintf(yyextra->pool, "Parse error near '%c'", yytext[0]);
        PERROR(msg);
    }
    	YY_BREAK
    case 67:
    YY_RULE_SETUP
    #line 398 "util_expr_scan.l"
    YY_FATAL_ERROR( "flex scanner jammed" );
    	YY_BREAK
    #line 1523 "util_expr_scan.c"
    case YY_STATE_EOF(INITIAL):
    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 - yyg->yytext_ptr) - 1;
    
    		/* Undo the effects of YY_DO_BEFORE_ACTION. */
    		*yy_cp = yyg->yy_hold_char;
    		YY_RESTORE_YY_MORE_OFFSET
    
    		if ( YY_CURRENT_BUFFER_LVALUE->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
    			 * ap_expr_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.
    			 */
    			yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
    			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
    			YY_CURRENT_BUFFER_LVALUE->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 ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
    			{ /* This was really a NUL. */
    			yy_state_type yy_next_state;
    
    			yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
    
    			yy_current_state = yy_get_previous_state( yyscanner );
    
    			/* 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 , yyscanner);
    
    			yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
    
    			if ( yy_next_state )
    				{
    				/* Consume the NUL. */
    				yy_cp = ++yyg->yy_c_buf_p;
    				yy_current_state = yy_next_state;
    				goto yy_match;
    				}
    
    			else
    				{
    				yy_cp = yyg->yy_last_accepting_cpos;
    				yy_current_state = yyg->yy_last_accepting_state;
    				goto yy_find_action;
    				}
    			}
    
    		else switch ( yy_get_next_buffer( yyscanner ) )
    			{
    			case EOB_ACT_END_OF_FILE:
    				{
    				yyg->yy_did_buffer_switch_on_eof = 0;
    
    				if ( ap_expr_yywrap(yyscanner ) )
    					{
    					/* 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.
    					 */
    					yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
    
    					yy_act = YY_STATE_EOF(YY_START);
    					goto do_action;
    					}
    
    				else
    					{
    					if ( ! yyg->yy_did_buffer_switch_on_eof )
    						YY_NEW_FILE;
    					}
    				break;
    				}
    
    			case EOB_ACT_CONTINUE_SCAN:
    				yyg->yy_c_buf_p =
    					yyg->yytext_ptr + yy_amount_of_matched_text;
    
    				yy_current_state = yy_get_previous_state( yyscanner );
    
    				yy_cp = yyg->yy_c_buf_p;
    				yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
    				goto yy_match;
    
    			case EOB_ACT_LAST_MATCH:
    				yyg->yy_c_buf_p =
    				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
    
    				yy_current_state = yy_get_previous_state( yyscanner );
    
    				yy_cp = yyg->yy_c_buf_p;
    				yy_bp = yyg->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 ap_expr_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 (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
    	register char *source = yyg->yytext_ptr;
    	register int number_to_move, i;
    	int ret_val;
    
    	if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
    		YY_FATAL_ERROR(
    		"fatal flex scanner internal error--end of buffer missed" );
    
    	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
    		{ /* Don't try to fill the buffer, so this is an EOF. */
    		if ( yyg->yy_c_buf_p - yyg->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) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
    
    	for ( i = 0; i < number_to_move; ++i )
    		*(dest++) = *(source++);
    
    	if ( YY_CURRENT_BUFFER_LVALUE->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_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
    
    	else
    		{
    			int num_to_read =
    			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
    
    		while ( num_to_read <= 0 )
    			{ /* Not enough room in the buffer - grow it. */
    
    			/* just a shorter name for the current buffer */
    			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
    
    			int yy_c_buf_p_offset =
    				(int) (yyg->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. */
    					ap_expr_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
    				}
    			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" );
    
    			yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
    
    			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
    						number_to_move - 1;
    
    			}
    
    		if ( num_to_read > YY_READ_BUF_SIZE )
    			num_to_read = YY_READ_BUF_SIZE;
    
    		/* Read in more data. */
    		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
    			yyg->yy_n_chars, (size_t) num_to_read );
    
    		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
    		}
    
    	if ( yyg->yy_n_chars == 0 )
    		{
    		if ( number_to_move == YY_MORE_ADJ )
    			{
    			ret_val = EOB_ACT_END_OF_FILE;
    			ap_expr_yyrestart(yyin  ,yyscanner);
    			}
    
    		else
    			{
    			ret_val = EOB_ACT_LAST_MATCH;
    			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
    				YY_BUFFER_EOF_PENDING;
    			}
    		}
    
    	else
    		ret_val = EOB_ACT_CONTINUE_SCAN;
    
    	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
    		/* Extend the array by 50%, plus the number we really need. */
    		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
    		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ap_expr_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
    		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
    			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
    	}
    
    	yyg->yy_n_chars += number_to_move;
    	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
    	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
    
    	yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->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 (yyscan_t yyscanner)
    {
    	register yy_state_type yy_current_state;
    	register char *yy_cp;
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    	yy_current_state = yyg->yy_start;
    
    	for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->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] )
    			{
    			yyg->yy_last_accepting_state = yy_current_state;
    			yyg->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 >= 124 )
    				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 );
     */
        static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
    {
    	register int yy_is_jam;
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
    	register char *yy_cp = yyg->yy_c_buf_p;
    
    	register YY_CHAR yy_c = 1;
    	if ( yy_accept[yy_current_state] )
    		{
    		yyg->yy_last_accepting_state = yy_current_state;
    		yyg->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 >= 124 )
    			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 == 123);
    
    	return yy_is_jam ? 0 : yy_current_state;
    }
    
    #ifndef YY_NO_INPUT
    #ifdef __cplusplus
        static int yyinput (yyscan_t yyscanner)
    #else
        static int input  (yyscan_t yyscanner)
    #endif
    
    {
    	int c;
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    	*yyg->yy_c_buf_p = yyg->yy_hold_char;
    
    	if ( *yyg->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 ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
    			/* This was really a NUL. */
    			*yyg->yy_c_buf_p = '\0';
    
    		else
    			{ /* need more input */
    			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
    			++yyg->yy_c_buf_p;
    
    			switch ( yy_get_next_buffer( yyscanner ) )
    				{
    				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. */
    					ap_expr_yyrestart(yyin ,yyscanner);
    
    					/*FALLTHROUGH*/
    
    				case EOB_ACT_END_OF_FILE:
    					{
    					if ( ap_expr_yywrap(yyscanner ) )
    						return EOF;
    
    					if ( ! yyg->yy_did_buffer_switch_on_eof )
    						YY_NEW_FILE;
    #ifdef __cplusplus
    					return yyinput(yyscanner);
    #else
    					return input(yyscanner);
    #endif
    					}
    
    				case EOB_ACT_CONTINUE_SCAN:
    					yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
    					break;
    				}
    			}
    		}
    
    	c = *(unsigned char *) yyg->yy_c_buf_p;	/* cast for 8-bit char's */
    	*yyg->yy_c_buf_p = '\0';	/* preserve yytext */
    	yyg->yy_hold_char = *++yyg->yy_c_buf_p;
    
    	return c;
    }
    #endif	/* ifndef YY_NO_INPUT */
    
    /** Immediately switch to a different input stream.
     * @param input_file A readable stream.
     * @param yyscanner The scanner object.
     * @note This function does not reset the start condition to @c INITIAL .
     */
        void ap_expr_yyrestart  (FILE * input_file , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    	if ( ! YY_CURRENT_BUFFER ){
            ap_expr_yyensure_buffer_stack (yyscanner);
    		YY_CURRENT_BUFFER_LVALUE =
                ap_expr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
    	}
    
    	ap_expr_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
    	ap_expr_yy_load_buffer_state(yyscanner );
    }
    
    /** Switch to a different input buffer.
     * @param new_buffer The new input buffer.
     * @param yyscanner The scanner object.
     */
        void ap_expr_yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    	/* TODO. We should be able to replace this entire function body
    	 * with
    	 *		ap_expr_yypop_buffer_state();
    	 *		ap_expr_yypush_buffer_state(new_buffer);
         */
    	ap_expr_yyensure_buffer_stack (yyscanner);
    	if ( YY_CURRENT_BUFFER == new_buffer )
    		return;
    
    	if ( YY_CURRENT_BUFFER )
    		{
    		/* Flush out information for old buffer. */
    		*yyg->yy_c_buf_p = yyg->yy_hold_char;
    		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
    		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
    		}
    
    	YY_CURRENT_BUFFER_LVALUE = new_buffer;
    	ap_expr_yy_load_buffer_state(yyscanner );
    
    	/* We don't actually know whether we did this switch during
    	 * EOF (ap_expr_yywrap()) processing, but the only time this flag
    	 * is looked at is after ap_expr_yywrap() is called, so it's safe
    	 * to go ahead and always set it.
    	 */
    	yyg->yy_did_buffer_switch_on_eof = 1;
    }
    
    static void ap_expr_yy_load_buffer_state  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    	yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
    	yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
    	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
    	yyg->yy_hold_char = *yyg->yy_c_buf_p;
    }
    
    /** Allocate and initialize an input buffer state.
     * @param file A readable stream.
     * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
     * @param yyscanner The scanner object.
     * @return the allocated buffer state.
     */
        YY_BUFFER_STATE ap_expr_yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
    {
    	YY_BUFFER_STATE b;
        
    	b = (YY_BUFFER_STATE) ap_expr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
    	if ( ! b )
    		YY_FATAL_ERROR( "out of dynamic memory in ap_expr_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 *) ap_expr_yyalloc(b->yy_buf_size + 2 ,yyscanner );
    	if ( ! b->yy_ch_buf )
    		YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_create_buffer()" );
    
    	b->yy_is_our_buffer = 1;
    
    	ap_expr_yy_init_buffer(b,file ,yyscanner);
    
    	return b;
    }
    
    /** Destroy the buffer.
     * @param b a buffer created with ap_expr_yy_create_buffer()
     * @param yyscanner The scanner object.
     */
        void ap_expr_yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    	if ( ! b )
    		return;
    
    	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
    		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
    
    	if ( b->yy_is_our_buffer )
    		ap_expr_yyfree((void *) b->yy_ch_buf ,yyscanner );
    
    	ap_expr_yyfree((void *) b ,yyscanner );
    }
    
    /* Initializes or reinitializes a buffer.
     * This function is sometimes called more than once on the same buffer,
     * such as during a ap_expr_yyrestart() or at EOF.
     */
        static void ap_expr_yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
    
    {
    	int oerrno = errno;
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    	ap_expr_yy_flush_buffer(b ,yyscanner);
    
    	b->yy_input_file = file;
    	b->yy_fill_buffer = 1;
    
        /* If b is the current buffer, then ap_expr_yy_init_buffer was _probably_
         * called from ap_expr_yyrestart() or through yy_get_next_buffer.
         * In that case, we don't want to reset the lineno or column.
         */
        if (b != YY_CURRENT_BUFFER){
            b->yy_bs_lineno = 1;
            b->yy_bs_column = 0;
        }
    
            b->yy_is_interactive = 0;
        
    	errno = oerrno;
    }
    
    /** Discard all buffered characters. On the next scan, YY_INPUT will be called.
     * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
     * @param yyscanner The scanner object.
     */
        void ap_expr_yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    	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 )
    		ap_expr_yy_load_buffer_state(yyscanner );
    }
    
    /** Pushes the new state onto the stack. The new state becomes
     *  the current state. This function will allocate the stack
     *  if necessary.
     *  @param new_buffer The new state.
     *  @param yyscanner The scanner object.
     */
    void ap_expr_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    	if (new_buffer == NULL)
    		return;
    
    	ap_expr_yyensure_buffer_stack(yyscanner);
    
    	/* This block is copied from ap_expr_yy_switch_to_buffer. */
    	if ( YY_CURRENT_BUFFER )
    		{
    		/* Flush out information for old buffer. */
    		*yyg->yy_c_buf_p = yyg->yy_hold_char;
    		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
    		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
    		}
    
    	/* Only push if top exists. Otherwise, replace top. */
    	if (YY_CURRENT_BUFFER)
    		yyg->yy_buffer_stack_top++;
    	YY_CURRENT_BUFFER_LVALUE = new_buffer;
    
    	/* copied from ap_expr_yy_switch_to_buffer. */
    	ap_expr_yy_load_buffer_state(yyscanner );
    	yyg->yy_did_buffer_switch_on_eof = 1;
    }
    
    /** Removes and deletes the top of the stack, if present.
     *  The next element becomes the new top.
     *  @param yyscanner The scanner object.
     */
    void ap_expr_yypop_buffer_state (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    	if (!YY_CURRENT_BUFFER)
    		return;
    
    	ap_expr_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
    	YY_CURRENT_BUFFER_LVALUE = NULL;
    	if (yyg->yy_buffer_stack_top > 0)
    		--yyg->yy_buffer_stack_top;
    
    	if (YY_CURRENT_BUFFER) {
    		ap_expr_yy_load_buffer_state(yyscanner );
    		yyg->yy_did_buffer_switch_on_eof = 1;
    	}
    }
    
    /* Allocates the stack if it does not exist.
     *  Guarantees space for at least one push.
     */
    static void ap_expr_yyensure_buffer_stack (yyscan_t yyscanner)
    {
    	int num_to_alloc;
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
    	if (!yyg->yy_buffer_stack) {
    
    		/* First allocation is just for 2 elements, since we don't know if this
    		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
    		 * immediate realloc on the next call.
             */
    		num_to_alloc = 1;
    		yyg->yy_buffer_stack = (struct yy_buffer_state**)ap_expr_yyalloc
    								(num_to_alloc * sizeof(struct yy_buffer_state*)
    								, yyscanner);
    		if ( ! yyg->yy_buffer_stack )
    			YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yyensure_buffer_stack()" );
    								  
    		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
    				
    		yyg->yy_buffer_stack_max = num_to_alloc;
    		yyg->yy_buffer_stack_top = 0;
    		return;
    	}
    
    	if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
    
    		/* Increase the buffer to prepare for a possible push. */
    		int grow_size = 8 /* arbitrary grow size */;
    
    		num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
    		yyg->yy_buffer_stack = (struct yy_buffer_state**)ap_expr_yyrealloc
    								(yyg->yy_buffer_stack,
    								num_to_alloc * sizeof(struct yy_buffer_state*)
    								, yyscanner);
    		if ( ! yyg->yy_buffer_stack )
    			YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yyensure_buffer_stack()" );
    
    		/* zero only the new slots.*/
    		memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
    		yyg->yy_buffer_stack_max = num_to_alloc;
    	}
    }
    
    /** Setup the input buffer state to scan directly from a user-specified character buffer.
     * @param base the character buffer
     * @param size the size in bytes of the character buffer
     * @param yyscanner The scanner object.
     * @return the newly allocated buffer state object. 
     */
    YY_BUFFER_STATE ap_expr_yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
    {
    	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) ap_expr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
    	if ( ! b )
    		YY_FATAL_ERROR( "out of dynamic memory in ap_expr_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;
    
    	ap_expr_yy_switch_to_buffer(b ,yyscanner );
    
    	return b;
    }
    
    /** Setup the input buffer state to scan a string. The next call to ap_expr_yylex() will
     * scan from a @e copy of @a str.
     * @param yystr a NUL-terminated string to scan
     * @param yyscanner The scanner object.
     * @return the newly allocated buffer state object.
     * @note If you want to scan bytes that may contain NUL values, then use
     *       ap_expr_yy_scan_bytes() instead.
     */
    YY_BUFFER_STATE ap_expr_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
    {
        
    	return ap_expr_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
    }
    
    /** Setup the input buffer state to scan the given bytes. The next call to ap_expr_yylex() will
     * scan from a @e copy of @a bytes.
     * @param yybytes the byte buffer to scan
     * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
     * @param yyscanner The scanner object.
     * @return the newly allocated buffer state object.
     */
    YY_BUFFER_STATE ap_expr_yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
    {
    	YY_BUFFER_STATE b;
    	char *buf;
    	yy_size_t n;
    	int i;
        
    	/* Get memory for full buffer, including space for trailing EOB's. */
    	n = _yybytes_len + 2;
    	buf = (char *) ap_expr_yyalloc(n ,yyscanner );
    	if ( ! buf )
    		YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_scan_bytes()" );
    
    	for ( i = 0; i < _yybytes_len; ++i )
    		buf[i] = yybytes[i];
    
    	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
    
    	b = ap_expr_yy_scan_buffer(buf,n ,yyscanner);
    	if ( ! b )
    		YY_FATAL_ERROR( "bad buffer in ap_expr_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;
    }
    
        static void yy_push_state (int  new_state , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    	if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth )
    		{
    		yy_size_t new_size;
    
    		yyg->yy_start_stack_depth += YY_START_STACK_INCR;
    		new_size = yyg->yy_start_stack_depth * sizeof( int );
    
    		if ( ! yyg->yy_start_stack )
    			yyg->yy_start_stack = (int *) ap_expr_yyalloc(new_size ,yyscanner );
    
    		else
    			yyg->yy_start_stack = (int *) ap_expr_yyrealloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
    
    		if ( ! yyg->yy_start_stack )
    			YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
    		}
    
    	yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START;
    
    	BEGIN(new_state);
    }
    
        static void yy_pop_state  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    	if ( --yyg->yy_start_stack_ptr < 0 )
    		YY_FATAL_ERROR( "start-condition stack underflow" );
    
    	BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]);
    }
    
    #ifndef YY_EXIT_FAILURE
    #define YY_EXIT_FAILURE 2
    #endif
    
    static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
    {
        	(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. */ \
            int yyless_macro_arg = (n); \
            YY_LESS_LINENO(yyless_macro_arg);\
    		yytext[yyleng] = yyg->yy_hold_char; \
    		yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
    		yyg->yy_hold_char = *yyg->yy_c_buf_p; \
    		*yyg->yy_c_buf_p = '\0'; \
    		yyleng = yyless_macro_arg; \
    		} \
    	while ( 0 )
    
    /* Accessor  methods (get/set functions) to struct members. */
    
    /** Get the user-defined data for this scanner.
     * @param yyscanner The scanner object.
     */
    YY_EXTRA_TYPE ap_expr_yyget_extra  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        return yyextra;
    }
    
    /** Get the current line number.
     * @param yyscanner The scanner object.
     */
    int ap_expr_yyget_lineno  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        
            if (! YY_CURRENT_BUFFER)
                return 0;
        
        return yylineno;
    }
    
    /** Get the current column number.
     * @param yyscanner The scanner object.
     */
    
    /** Get the input stream.
     * @param yyscanner The scanner object.
     */
    FILE *ap_expr_yyget_in  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        return yyin;
    }
    
    /** Get the output stream.
     * @param yyscanner The scanner object.
     */
    FILE *ap_expr_yyget_out  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        return yyout;
    }
    
    /** Get the length of the current token.
     * @param yyscanner The scanner object.
     */
    int ap_expr_yyget_leng  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        return yyleng;
    }
    
    /** Get the current token.
     * @param yyscanner The scanner object.
     */
    
    char *ap_expr_yyget_text  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        return yytext;
    }
    
    /** Set the user-defined data. This data is never touched by the scanner.
     * @param user_defined The data to be associated with this scanner.
     * @param yyscanner The scanner object.
     */
    void ap_expr_yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        yyextra = user_defined ;
    }
    
    /** Set the current line number.
     * @param line_number
     * @param yyscanner The scanner object.
     */
    void ap_expr_yyset_lineno (int  line_number , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
            /* lineno is only valid if an input buffer exists. */
            if (! YY_CURRENT_BUFFER )
               yy_fatal_error( "ap_expr_yyset_lineno called with no buffer" , yyscanner); 
        
        yylineno = line_number;
    }
    
    /** Set the current column.
     * @param line_number
     * @param yyscanner The scanner object.
     */
    
    /** Set the input stream. This does not discard the current
     * input buffer.
     * @param in_str A readable stream.
     * @param yyscanner The scanner object.
     * @see ap_expr_yy_switch_to_buffer
     */
    void ap_expr_yyset_in (FILE *  in_str , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        yyin = in_str ;
    }
    
    void ap_expr_yyset_out (FILE *  out_str , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        yyout = out_str ;
    }
    
    int ap_expr_yyget_debug  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        return yy_flex_debug;
    }
    
    void ap_expr_yyset_debug (int  bdebug , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        yy_flex_debug = bdebug ;
    }
    
    /* Accessor methods for yylval and yylloc */
    
    YYSTYPE * ap_expr_yyget_lval  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        return yylval;
    }
    
    void ap_expr_yyset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        yylval = yylval_param;
    }
    
    /* User-visible API */
    
    /* ap_expr_yylex_init is special because it creates the scanner itself, so it is
     * the ONLY reentrant function that doesn't take the scanner as the last argument.
     * That's why we explicitly handle the declaration, instead of using our macros.
     */
    
    int ap_expr_yylex_init(yyscan_t* ptr_yy_globals)
    
    {
        if (ptr_yy_globals == NULL){
            errno = EINVAL;
            return 1;
        }
    
        *ptr_yy_globals = (yyscan_t) ap_expr_yyalloc ( sizeof( struct yyguts_t ), NULL );
    
        if (*ptr_yy_globals == NULL){
            errno = ENOMEM;
            return 1;
        }
    
        /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
        memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
    
        return yy_init_globals ( *ptr_yy_globals );
    }
    
    /* ap_expr_yylex_init_extra has the same functionality as ap_expr_yylex_init, but follows the
     * convention of taking the scanner as the last argument. Note however, that
     * this is a *pointer* to a scanner, as it will be allocated by this call (and
     * is the reason, too, why this function also must handle its own declaration).
     * The user defined value in the first argument will be available to ap_expr_yyalloc in
     * the yyextra field.
     */
    
    int ap_expr_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
    
    {
        struct yyguts_t dummy_yyguts;
    
        ap_expr_yyset_extra (yy_user_defined, &dummy_yyguts);
    
        if (ptr_yy_globals == NULL){
            errno = EINVAL;
            return 1;
        }
    	
        *ptr_yy_globals = (yyscan_t) ap_expr_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
    	
        if (*ptr_yy_globals == NULL){
            errno = ENOMEM;
            return 1;
        }
        
        /* By setting to 0xAA, we expose bugs in
        yy_init_globals. Leave at 0x00 for releases. */
        memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
        
        ap_expr_yyset_extra (yy_user_defined, *ptr_yy_globals);
        
        return yy_init_globals ( *ptr_yy_globals );
    }
    
    static int yy_init_globals (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        /* Initialization is the same as for the non-reentrant scanner.
         * This function is called from ap_expr_yylex_destroy(), so don't allocate here.
         */
    
        yyg->yy_buffer_stack = 0;
        yyg->yy_buffer_stack_top = 0;
        yyg->yy_buffer_stack_max = 0;
        yyg->yy_c_buf_p = (char *) 0;
        yyg->yy_init = 0;
        yyg->yy_start = 0;
    
        yyg->yy_start_stack_ptr = 0;
        yyg->yy_start_stack_depth = 0;
        yyg->yy_start_stack =  NULL;
    
    /* Defined in main.c */
    #ifdef YY_STDINIT
        yyin = stdin;
        yyout = stdout;
    #else
        yyin = (FILE *) 0;
        yyout = (FILE *) 0;
    #endif
    
        /* For future reference: Set errno on error, since we are called by
         * ap_expr_yylex_init()
         */
        return 0;
    }
    
    /* ap_expr_yylex_destroy is for both reentrant and non-reentrant scanners. */
    int ap_expr_yylex_destroy  (yyscan_t yyscanner)
    {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
    
        /* Pop the buffer stack, destroying each element. */
    	while(YY_CURRENT_BUFFER){
    		ap_expr_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
    		YY_CURRENT_BUFFER_LVALUE = NULL;
    		ap_expr_yypop_buffer_state(yyscanner);
    	}
    
    	/* Destroy the stack itself. */
    	ap_expr_yyfree(yyg->yy_buffer_stack ,yyscanner);
    	yyg->yy_buffer_stack = NULL;
    
        /* Destroy the start condition stack. */
            ap_expr_yyfree(yyg->yy_start_stack ,yyscanner );
            yyg->yy_start_stack = NULL;
    
        /* Reset the globals. This is important in a non-reentrant scanner so the next time
         * ap_expr_yylex() is called, initialization will occur. */
        yy_init_globals( yyscanner);
    
        /* Destroy the main struct (reentrant only). */
        ap_expr_yyfree ( yyscanner , yyscanner );
        yyscanner = NULL;
        return 0;
    }
    
    /*
     * Internal utility routines.
     */
    
    #ifndef yytext_ptr
    static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
    {
    	register int i;
    	for ( i = 0; i < n; ++i )
    		s1[i] = s2[i];
    }
    #endif
    
    #ifdef YY_NEED_STRLEN
    static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
    {
    	register int n;
    	for ( n = 0; s[n]; ++n )
    		;
    
    	return n;
    }
    #endif
    
    void *ap_expr_yyalloc (yy_size_t  size , yyscan_t yyscanner)
    {
    	return (void *) malloc( size );
    }
    
    void *ap_expr_yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
    {
    	/* 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 );
    }
    
    void ap_expr_yyfree (void * ptr , yyscan_t yyscanner)
    {
    	free( (char *) ptr );	/* see ap_expr_yyrealloc() for (char *) cast */
    }
    
    #define YYTABLES_NAME "yytables"
    
    #line 398 "util_expr_scan.l"
    
    
    
    
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_cfgtree.c������������������������������������������������������������������0000664�0001751�0001751�00000003033�10776375527�016772� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_cfgtree.h"
    #include <stdlib.h>
    
    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;
    }
    
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/gen_test_char.c�����������������������������������������������������������������0000664�0001751�0001751�00000015311�14127563677�017124� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 CROSS_COMPILE
    
    #include <ctype.h>
    #define apr_isalnum(c) (isalnum(((unsigned char)(c))))
    #define apr_isalpha(c) (isalpha(((unsigned char)(c))))
    #define apr_iscntrl(c) (iscntrl(((unsigned char)(c))))
    #define apr_isprint(c) (isprint(((unsigned char)(c))))
    #define APR_HAVE_STDIO_H 1
    #define APR_HAVE_STRING_H 1
    
    #else
    
    #include "apr.h"
    #include "apr_lib.h"
    
    #endif
    
    #if defined(WIN32) || defined(OS2)
    #define NEED_ENHANCED_ESCAPES
    #endif
    
    #if APR_HAVE_STDIO_H
    #include <stdio.h>
    #endif
    #if APR_HAVE_STRING_H
    #include <string.h>
    #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)
    #define T_ESCAPE_URLENCODED   (0x40)
    #define T_HTTP_CTRLS          (0x80)
    #define T_VCHAR_OBSTEXT      (0x100)
    #define T_URI_UNRESERVED     (0x200)
    
    int main(int argc, char *argv[])
    {
        unsigned c;
        unsigned short 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"
               "#define T_ESCAPE_URLENCODED    (%u)\n"
               "#define T_HTTP_CTRLS           (%u)\n"
               "#define T_VCHAR_OBSTEXT        (%u)\n"
               "#define T_URI_UNRESERVED       (%u)\n"
               "\n"
               "static const unsigned short 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,
               T_ESCAPE_URLENCODED,
               T_HTTP_CTRLS,
               T_VCHAR_OBSTEXT,
               T_URI_UNRESERVED
            );
    
        for (c = 0; c < 256; ++c) {
            flags = 0;
            if (c % 8 == 0)
                printf("\n    ");
    
            /* escape_shell_cmd */
    #ifdef NEED_ENHANCED_ESCAPES
            /* 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 similarly 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;
            }
    
            if (!apr_isalnum(c) && !strchr(".-*_ ", c)) {
                flags |= T_ESCAPE_URLENCODED;
            }
    
            /* Stop for any non-'token' character, including ctrls, obs-text,
             * and "tspecials" (RFC2068) a.k.a. "separators" (RFC2616), which
             * is easier to express as characters remaining in the ASCII token set
             */
            if (!c || !(apr_isalnum(c) || strchr("!#$%&'*+-.^_`|~", c))) {
                flags |= T_HTTP_TOKEN_STOP;
            }
    
            /* Catch CTRLs other than VCHAR, HT and SP, and obs-text (RFC7230 3.2)
             * This includes only the C0 plane, not C1 (which is obs-text itself.)
             * XXX: We should verify that all ASCII C0 ctrls/DEL corresponding to
             * the current EBCDIC translation are captured, and ASCII C1 ctrls
             * corresponding are all permitted (as they fall under obs-text rule)
             */
            if (!c || (apr_iscntrl(c) && c != '\t')) {
                flags |= T_HTTP_CTRLS;
            }
    
            /* From RFC3986, the specific sets of gen-delims, sub-delims (2.2),
             * and unreserved (2.3) that are possible somewhere within a URI.
             * Spec requires all others to be %XX encoded, including obs-text.
             */
            if (c && !apr_iscntrl(c) && c != ' ') {
                flags |= T_VCHAR_OBSTEXT;
            }
    
            /* 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;
            }
    
            /* Characters in the RFC 3986 "unreserved" set.
             * https://datatracker.ietf.org/doc/html/rfc3986#section-2.3 */
            if (c && (apr_isalnum(c) || strchr("-._~", c))) {
                flags |= T_URI_UNRESERVED;
            }
            
            printf("0x%03x%c", flags, (c < 255) ? ',' : ' ');
        }
    
        printf("\n};\n\n");
    
        printf(
          "/* we assume the folks using this ensure 0 <= c < 256... which means\n"
          " * you need a cast to (unsigned char) first, you can't just plug a\n"
          " * char in here and get it to work, because if char is signed then it\n"
          " * will first be sign extended.\n"
          " */\n"
          "#define TEST_CHAR(c, f) (test_char_table[(unsigned char)(c)] & (f))\n"
        );
    
        return 0;
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/mpm_fdqueue.c�������������������������������������������������������������������0000664�0001751�0001751�00000037621�14104431754�016617� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "mpm_fdqueue.h"
    
    #if APR_HAS_THREADS
    
    #include <apr_atomic.h>
    
    static const apr_uint32_t zero_pt = APR_UINT32_MAX/2;
    
    struct recycled_pool
    {
        apr_pool_t *pool;
        struct recycled_pool *next;
    };
    
    struct fd_queue_info_t
    {
        apr_uint32_t volatile idlers; /**
                                       * >= zero_pt: number of idle worker threads
                                       * <  zero_pt: 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;
        int max_recycled_pools;
        apr_uint32_t recycled_pools_count;
        struct recycled_pool *volatile recycled_pools;
    };
    
    struct fd_queue_elem_t
    {
        apr_socket_t *sd;
        void *sd_baton;
        apr_pool_t *p;
    };
    
    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((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,
                                      int max_recycled_pools)
    {
        apr_status_t rv;
        fd_queue_info_t *qi;
    
        qi = apr_pcalloc(pool, 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_recycled_pools = max_recycled_pools;
        qi->max_idlers = max_idlers;
        qi->idlers = zero_pt;
        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;
    
        ap_queue_info_push_pool(queue_info, pool_to_recycle);
    
        /* If other threads are waiting on a worker, wake one up */
        if (apr_atomic_inc32(&queue_info->idlers) < zero_pt) {
            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_try_get_idler(fd_queue_info_t *queue_info)
    {
        /* Don't block if there isn't any idle worker. */
        for (;;) {
            apr_uint32_t idlers = queue_info->idlers;
            if (idlers <= zero_pt) {
                return APR_EAGAIN;
            }
            if (apr_atomic_cas32(&queue_info->idlers, idlers - 1,
                                 idlers) == idlers) {
                return APR_SUCCESS;
            }
        }
    }
    
    apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info,
                                              int *had_to_block)
    {
        apr_status_t rv;
    
        /* Block if there isn't any idle worker.
         * apr_atomic_add32(x, -1) does the same as dec32(x), except
         * that it returns the previous value (unlike dec32's bool).
         */
        if (apr_atomic_add32(&queue_info->idlers, -1) <= zero_pt) {
            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" (relative to zero_pt) in
             *     queue_info->idlers tells how many
             *     threads are waiting on an idle worker.
             */
            if (queue_info->idlers < zero_pt) {
                if (had_to_block) {
                    *had_to_block = 1;
                }
                rv = apr_thread_cond_wait(queue_info->wait_for_idler,
                                          queue_info->idlers_mutex);
                if (rv != APR_SUCCESS) {
                    AP_DEBUG_ASSERT(0);
                    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;
            }
        }
    
        if (queue_info->terminated) {
            return APR_EOF;
        }
        else {
            return APR_SUCCESS;
        }
    }
    
    apr_uint32_t ap_queue_info_num_idlers(fd_queue_info_t *queue_info)
    {
        apr_uint32_t val;
        val = apr_atomic_read32(&queue_info->idlers);
        return (val > zero_pt) ? val - zero_pt : 0;
    }
    
    void ap_queue_info_push_pool(fd_queue_info_t *queue_info,
                                 apr_pool_t *pool_to_recycle)
    {
        struct recycled_pool *new_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)
            return;
    
        if (queue_info->max_recycled_pools >= 0) {
            apr_uint32_t n = apr_atomic_read32(&queue_info->recycled_pools_count);
            if (n >= queue_info->max_recycled_pools) {
                apr_pool_destroy(pool_to_recycle);
                return;
            }
            apr_atomic_inc32(&queue_info->recycled_pools_count);
        }
    
        apr_pool_clear(pool_to_recycle);
        new_recycle = apr_palloc(pool_to_recycle, sizeof *new_recycle);
        new_recycle->pool = pool_to_recycle;
        for (;;) {
            /*
             * Save queue_info->recycled_pool in local variable next because
             * new_recycle->next can be changed after apr_atomic_casptr
             * function call. For gory details see PR 44402.
             */
            struct recycled_pool *next = queue_info->recycled_pools;
            new_recycle->next = next;
            if (apr_atomic_casptr((void *)&queue_info->recycled_pools,
                                  new_recycle, next) == next)
                break;
        }
    }
    
    void ap_queue_info_pop_pool(fd_queue_info_t *queue_info,
                                apr_pool_t **recycled_pool)
    {
        /* 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((void *)&queue_info->recycled_pools,
                                  first_pool->next, first_pool) == first_pool) {
                *recycled_pool = first_pool->pool;
                if (queue_info->max_recycled_pools >= 0)
                    apr_atomic_dec32(&queue_info->recycled_pools_count);
                break;
            }
        }
    }
    
    void ap_queue_info_free_idle_pools(fd_queue_info_t *queue_info)
    {
        apr_pool_t *p;
    
        queue_info->max_recycled_pools = 0;
        for (;;) {
            ap_queue_info_pop_pool(queue_info, &p);
            if (p == NULL)
                break;
            apr_pool_destroy(p);
        }
        apr_atomic_set32(&queue_info->recycled_pools_count, 0);
    }
    
    
    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 && \
                                   APR_RING_EMPTY(&queue->timers, \
                                                  timer_event_t, link))
    
    /**
     * 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_create(fd_queue_t **pqueue, int capacity, apr_pool_t *p)
    {
        apr_status_t rv;
        fd_queue_t *queue;
    
        queue = apr_pcalloc(p, sizeof *queue);
    
        if ((rv = apr_thread_mutex_create(&queue->one_big_mutex,
                                          APR_THREAD_MUTEX_DEFAULT,
                                          p)) != APR_SUCCESS) {
            return rv;
        }
        if ((rv = apr_thread_cond_create(&queue->not_empty, p)) != APR_SUCCESS) {
            return rv;
        }
    
        APR_RING_INIT(&queue->timers, timer_event_t, link);
    
        queue->data = apr_pcalloc(p, capacity * sizeof(fd_queue_elem_t));
        queue->bounds = capacity;
    
        apr_pool_cleanup_register(p, queue, ap_queue_destroy,
                                  apr_pool_cleanup_null);
        *pqueue = queue;
    
        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_socket(fd_queue_t *queue,
                                      apr_socket_t *sd, void *sd_baton,
                                      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->in++];
        if (queue->in >= queue->bounds)
            queue->in -= queue->bounds;
        elem->sd = sd;
        elem->sd_baton = sd_baton;
        elem->p = p;
        queue->nelts++;
    
        apr_thread_cond_signal(queue->not_empty);
    
        return apr_thread_mutex_unlock(queue->one_big_mutex);
    }
    
    apr_status_t ap_queue_push_timer(fd_queue_t *queue, timer_event_t *te)
    {
        apr_status_t rv;
    
        if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) {
            return rv;
        }
    
        AP_DEBUG_ASSERT(!queue->terminated);
    
        APR_RING_INSERT_TAIL(&queue->timers, te, timer_event_t, link);
    
        apr_thread_cond_signal(queue->not_empty);
    
        return apr_thread_mutex_unlock(queue->one_big_mutex);
    }
    
    /**
     * 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_something(fd_queue_t *queue,
                                        apr_socket_t **sd, void **sd_baton,
                                        apr_pool_t **p, timer_event_t **te_out)
    {
        fd_queue_elem_t *elem;
        timer_event_t *te;
        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;
                }
            }
        }
    
        te = NULL;
        if (te_out) {
            if (!APR_RING_EMPTY(&queue->timers, timer_event_t, link)) {
                te = APR_RING_FIRST(&queue->timers);
                APR_RING_REMOVE(te, link);
            }
            *te_out = te;
        }
        if (!te) {
            elem = &queue->data[queue->out++];
            if (queue->out >= queue->bounds)
                queue->out -= queue->bounds;
            queue->nelts--;
    
            *sd = elem->sd;
            if (sd_baton) {
                *sd_baton = elem->sd_baton;
            }
            *p = elem->p;
    #ifdef AP_DEBUG
            elem->sd = NULL;
            elem->p = NULL;
    #endif /* AP_DEBUG */
        }
    
        return apr_thread_mutex_unlock(queue->one_big_mutex);
    }
    
    static apr_status_t queue_interrupt(fd_queue_t *queue, int all, int term)
    {
        apr_status_t rv;
    
        if (queue->terminated) {
            return APR_EOF;
        }
    
        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
         */
        if (term) {
            queue->terminated = 1;
        }
        if (all)
            apr_thread_cond_broadcast(queue->not_empty);
        else
            apr_thread_cond_signal(queue->not_empty);
    
        return apr_thread_mutex_unlock(queue->one_big_mutex);
    }
    
    apr_status_t ap_queue_interrupt_all(fd_queue_t *queue)
    {
        return queue_interrupt(queue, 1, 0);
    }
    
    apr_status_t ap_queue_interrupt_one(fd_queue_t *queue)
    {
        return queue_interrupt(queue, 0, 0);
    }
    
    apr_status_t ap_queue_term(fd_queue_t *queue)
    {
        return queue_interrupt(queue, 1, 1);
    }
    
    #endif /* APR_HAS_THREADS */
    ���������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_md5.c����������������������������������������������������������������������0000664�0001751�0001751�00000013700�14001067336�016017� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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)
    {
        apr_md5_ctx_t my_md5;
        unsigned char hash[APR_MD5_DIGESTSIZE];
        char *result;
    
        /*
         * 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);
    
        result = apr_palloc(p, 2 * APR_MD5_DIGESTSIZE + 1);
        ap_bin2hex(hash, APR_MD5_DIGESTSIZE, result); /* sets final '\0' */
        return result;
    }
    
    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);
    }
    
    ����������������������������������������������������������������httpd-2.4.64/server/util_debug.c��������������������������������������������������������������������0000664�0001751�0001751�00000015045�13226425175�016433� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "http_core.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];
    }
    
    AP_DECLARE(int) ap_get_module_flags(const module *m)
    {
        if (m->version < AP_MODULE_FLAGS_MMN_MAJOR
                || (m->version == AP_MODULE_FLAGS_MMN_MAJOR
                    && (m->minor_version < AP_MODULE_FLAGS_MMN_MINOR))) {
            return 0;
        }
    
        return m->flags;
    }
    
    #if defined(ap_get_core_module_config)
    #undef ap_get_core_module_config
    AP_DECLARE(void *) ap_get_core_module_config(const ap_conf_vector_t *cv);
    #endif
    
    AP_DECLARE(void *) ap_get_core_module_config(const ap_conf_vector_t *cv)
    {
        return ((void **)cv)[AP_CORE_MODULE_INDEX];
    }
    
    
    #if defined(ap_get_server_module_loglevel)
    #undef ap_get_server_module_loglevel
    AP_DECLARE(int) ap_get_server_module_loglevel(const server_rec *s, int module_index);
    #endif
    
    AP_DECLARE(int) ap_get_server_module_loglevel(const server_rec *s, int module_index)
    {
        if (module_index < 0 || s->log.module_levels == NULL ||
            s->log.module_levels[module_index] < 0)
        {
            return s->log.level;
        }
    
        return s->log.module_levels[module_index];
    }
    
    #if defined(ap_get_conn_module_loglevel)
    #undef ap_get_conn_module_loglevel
    AP_DECLARE(int) ap_get_conn_module_loglevel(const conn_rec *c, int module_index);
    #endif
    
    AP_DECLARE(int) ap_get_conn_module_loglevel(const conn_rec *c, int module_index)
    {
        const struct ap_logconf *l = (c)->log ? (c)->log : &(c)->base_server->log;
        if (module_index < 0 || l->module_levels == NULL ||
            l->module_levels[module_index] < 0)
        {
            return l->level;
        }
    
        return l->module_levels[module_index];
    }
    
    #if defined(ap_get_conn_server_module_loglevel)
    #undef ap_get_conn_server_module_loglevel
    AP_DECLARE(int) ap_get_conn_server_module_loglevel(const conn_rec *c,
                                                       const server_rec *s,
                                                       int module_index);
    #endif
    
    AP_DECLARE(int) ap_get_conn_server_module_loglevel(const conn_rec *c,
                                                       const server_rec *s,
                                                       int module_index)
    {
        const struct ap_logconf *l = (c->log && c->log != &c->base_server->log) ?
                                     c->log : &s->log;
        if (module_index < 0 || l->module_levels == NULL ||
            l->module_levels[module_index] < 0)
        {
            return l->level;
        }
    
        return l->module_levels[module_index];
    }
    
    #if defined(ap_get_request_module_loglevel)
    #undef ap_get_request_module_loglevel
    AP_DECLARE(int) ap_get_request_module_loglevel(const request_rec *c, int module_index);
    #endif
    
    AP_DECLARE(int) ap_get_request_module_loglevel(const request_rec *r, int module_index)
    {
        const struct ap_logconf *l = r->log             ? r->log             :
                                     r->connection->log ? r->connection->log :
                                     &r->server->log;
        if (module_index < 0 || l->module_levels == NULL ||
            l->module_levels[module_index] < 0)
        {
            return l->level;
        }
    
        return l->module_levels[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
     * @fn 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;
    }
    
    
    #if defined(ap_set_core_module_config)
    #undef ap_set_core_module_config
    AP_DECLARE(void) ap_set_core_module_config(ap_conf_vector_t *cv, void *val);
    #endif
    
    AP_DECLARE(void) ap_set_core_module_config(ap_conf_vector_t *cv, void *val)
    {
        ((void **)cv)[AP_CORE_MODULE_INDEX] = val;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/util_expr_parse.h���������������������������������������������������������������0000664�0001751�0001751�00000005550�15032766627�017531� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.5.  */
    
    /* Bison interface for Yacc-like parsers in C
       
          Copyright (C) 1984, 1989-1990, 2000-2011 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.  */
    
    /* As a special exception, you may create a larger work that contains
       part or all of the Bison parser skeleton and distribute that work
       under terms of your choice, so long as that work isn't itself a
       parser generator using the skeleton or a modified version thereof
       as a parser skeleton.  Alternatively, if you modify or redistribute
       the parser skeleton itself, you may (at your option) remove this
       special exception, which will cause the skeleton and the resulting
       Bison output files to be licensed under the GNU General Public
       License without this special exception.
       
       This special exception was added by the Free Software Foundation in
       version 2.2 of Bison.  */
    
    
    /* Tokens.  */
    #ifndef YYTOKENTYPE
    # define YYTOKENTYPE
       /* Put the tokens into the symbol table, so that GDB and other debuggers
          know about them.  */
       enum yytokentype {
         T_TRUE = 258,
         T_FALSE = 259,
         T_EXPR_BOOL = 260,
         T_EXPR_STRING = 261,
         T_ERROR = 262,
         T_DIGIT = 263,
         T_ID = 264,
         T_STRING = 265,
         T_REGEX = 266,
         T_REGEX_I = 267,
         T_REGEX_BACKREF = 268,
         T_OP_UNARY = 269,
         T_OP_BINARY = 270,
         T_STR_BEGIN = 271,
         T_STR_END = 272,
         T_VAR_BEGIN = 273,
         T_VAR_END = 274,
         T_OP_EQ = 275,
         T_OP_NE = 276,
         T_OP_LT = 277,
         T_OP_LE = 278,
         T_OP_GT = 279,
         T_OP_GE = 280,
         T_OP_REG = 281,
         T_OP_NRE = 282,
         T_OP_IN = 283,
         T_OP_STR_EQ = 284,
         T_OP_STR_NE = 285,
         T_OP_STR_LT = 286,
         T_OP_STR_LE = 287,
         T_OP_STR_GT = 288,
         T_OP_STR_GE = 289,
         T_OP_CONCAT = 290,
         T_OP_OR = 291,
         T_OP_AND = 292,
         T_OP_NOT = 293
       };
    #endif
    
    
    
    #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
    typedef union YYSTYPE
    {
    
    /* Line 2068 of yacc.c  */
    #line 35 "util_expr_parse.y"
    
        char      *cpVal;
        ap_expr_t *exVal;
        int        num;
    
    
    
    /* Line 2068 of yacc.c  */
    #line 96 "util_expr_parse.h"
    } YYSTYPE;
    # define YYSTYPE_IS_TRIVIAL 1
    # define yystype YYSTYPE /* obsolescent; will be withdrawn */
    # define YYSTYPE_IS_DECLARED 1
    #endif
    
    
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/gen_test_char.dsp���������������������������������������������������������������0000664�0001751�0001751�00000006430�10424053377�017455� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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"
    # SUBTRACT BASE LINK32 /pdb:none
    # ADD LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\gen_test_char.pdb" /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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /pdbtype:sept
    # SUBTRACT BASE LINK32 /pdb:none
    # ADD LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\gen_test_char.pdb" /debug
    # 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
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/server/.indent.pro���������������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�016216� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/changes-entries/�����������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766614�015713� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/���������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766624�013734� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/rpm/�����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014532� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/rpm/httpd.logrotate��������������������������������������������������������������0000664�0001751�0001751�00000000227�11546730664�017601� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/var/log/httpd/*log {
        missingok
        notifempty
        sharedscripts
        postrotate
    	/sbin/service httpd graceful 2> /dev/null || true
        endscript
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/rpm/httpd.spec.in����������������������������������������������������������������0000664�0001751�0001751�00000041670�13451102213�017123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%define contentdir /var/www
    %define suexec_caller apache
    %define mmn APACHE_MMN
    
    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.bz2
    License: Apache License, Version 2.0
    Group: System Environment/Daemons
    BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
    BuildRequires: autoconf, perl, pkgconfig, findutils
    BuildRequires: zlib-devel, libselinux-devel, libuuid-devel
    BuildRequires: apr-devel >= 1.4.0, apr-util-devel >= 1.4.0, pcre-devel >= 5.0
    Requires: initscripts >= 8.36, /etc/mime.types
    Obsoletes: httpd-suexec
    Requires(pre): /usr/sbin/useradd
    Requires(post): chkconfig
    Provides: webserver
    Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release}
    Provides: httpd-mmn = %{mmn}
    
    %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: apr-devel, apr-util-devel, pkgconfig, libtool
    Requires: httpd = %{version}-%{release}
    
    %description devel
    The httpd-devel package contains the APXS binary and other files
    that you need to build Dynamic Shared Objects (DSOs) for the
    Apache HTTP Server.
    
    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.
    Requires: httpd = :%{version}-%{release}
    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 tools
    Group: System Environment/Daemons
    Summary: Tools for use with the Apache HTTP Server
    
    %description tools
    The httpd-tools package contains tools which can be used with 
    the Apache HTTP Server.
    
    %package -n mod_authnz_ldap
    Group: System Environment/Daemons
    Summary: LDAP modules for the Apache HTTP server
    BuildRequires: openldap-devel
    Requires: httpd = %{version}-%{release}, httpd-mmn = %{mmn}, apr-util-ldap
    
    %description -n mod_authnz_ldap
    The mod_authnz_ldap module for the Apache HTTP server provides
    authentication and authorization against an LDAP server, while
    mod_ldap provides an LDAP cache.
    
    %package -n mod_lua
    Group: System Environment/Daemons
    Summary: Lua language module for the Apache HTTP server
    BuildRequires: lua-devel
    Requires: httpd = %{version}-%{release}, httpd-mmn = %{mmn}
    
    %description -n mod_lua
    The mod_lua module for the Apache HTTP server allows the server to be
    extended with scripts written in the Lua programming language.
    
    %package -n mod_proxy_html
    Group: System Environment/Daemons
    Summary: Proxy HTML filter modules for the Apache HTTP server
    Epoch: 1
    BuildRequires: libxml2-devel
    Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmn}
    
    %description -n mod_proxy_html
    The mod_proxy_html module for the Apache HTTP server provides
    a filter to rewrite HTML links within web content when used within
    a reverse proxy environment. The mod_xml2enc module provides
    enhanced charset/internationalisation support for mod_proxy_html.
    
    %package -n mod_ssl
    Group: System Environment/Daemons
    Summary: SSL/TLS module for the Apache HTTP server
    Epoch: 1
    BuildRequires: openssl-devel
    Requires(post): openssl, /bin/cat
    Requires(pre): httpd
    Requires: httpd = 0:%{version}-%{release}, 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 include/ap_mmn.h | sed -n '
    /^2/p'`
    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
    
    %build
    # forcibly prevent use of bundled apr, apr-util, pcre
    rm -rf srclib/{apr,apr-util,pcre}
    
    %configure \
    	--enable-layout=RPM \
    	--libdir=%{_libdir} \
    	--sysconfdir=%{_sysconfdir}/httpd/conf \
    	--includedir=%{_includedir}/httpd \
    	--libexecdir=%{_libdir}/httpd/modules \
    	--datadir=%{contentdir} \
            --with-installbuilddir=%{_libdir}/httpd/build \
            --enable-mpms-shared=all \
            --with-apr=%{_prefix} --with-apr-util=%{_prefix} \
    	--enable-suexec --with-suexec \
    	--with-suexec-caller=%{suexec_caller} \
    	--with-suexec-docroot=%{contentdir} \
    	--with-suexec-logfile=%{_localstatedir}/log/httpd/suexec.log \
    	--with-suexec-bin=%{_sbindir}/suexec \
    	--with-suexec-uidmin=500 --with-suexec-gidmin=100 \
            --enable-pie \
            --with-pcre \
            --enable-mods-shared=all \
            --enable-ssl --with-ssl --enable-bucketeer \
            --enable-case-filter --enable-case-filter-in \
            --disable-imagemap
    
    make %{?_smp_mflags}
    
    %install
    rm -rf $RPM_BUILD_ROOT
    make DESTDIR=$RPM_BUILD_ROOT install
    
    # 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}
    
    # Make the MMN accessible to module packages
    echo %{mmn} > $RPM_BUILD_ROOT%{_includedir}/httpd/.mmn
    
    # Set up /var directories
    mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/log/httpd
    mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd/cache-root
    
    # 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
    mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d
    
    # 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
    install -m755 ./build/rpm/htcacheclean.init \
            $RPM_BUILD_ROOT/etc/rc.d/init.d/htcacheclean
    
    # 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}/cgi-bin/* 
    
    # Make suexec a+rw so it can be stripped.  %%files lists real permissions
    chmod 755 $RPM_BUILD_ROOT%{_sbindir}/suexec
    
    %pre
    # Add the "apache" user
    /usr/sbin/useradd -c "Apache" -u 48 \
    	-s /sbin/nologin -r -d %{contentdir} apache 2> /dev/null || :
    
    %post
    # Register the httpd service
    /sbin/chkconfig --add httpd
    /sbin/chkconfig --add htcacheclean
    
    %preun
    if [ $1 = 0 ]; then
    	/sbin/service httpd stop > /dev/null 2>&1
            /sbin/service htcacheclean stop > /dev/null 2>&1
    	/sbin/chkconfig --del httpd
            /sbin/chkconfig --del htcacheclean
    fi
    
    %post -n mod_ssl
    umask 077
    
    if [ ! -f %{_sysconfdir}/httpd/conf/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/server.key 2> /dev/null
    fi
    
    FQDN=`hostname`
    if [ "x${FQDN}" = "x" ]; then
       FQDN=localhost.localdomain
    fi
    
    if [ ! -f %{_sysconfdir}/httpd/conf/server.crt ] ; then
    cat << EOF | %{_bindir}/openssl req -new -key %{_sysconfdir}/httpd/conf/server.key -x509 -days 365 -out %{_sysconfdir}/httpd/conf/server.crt 2>/dev/null
    --
    SomeState
    SomeCity
    SomeOrganization
    SomeOrganizationalUnit
    ${FQDN}
    root@${FQDN}
    EOF
    fi
    
    %check
    # Check the built modules are all PIC
    if readelf -d $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so | grep TEXTREL; then
       : modules contain non-relocatable code
       exit 1
    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
    %dir %{_sysconfdir}/httpd/conf.d
    %config(noreplace) %{_sysconfdir}/httpd/conf/httpd.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/magic
    %config(noreplace) %{_sysconfdir}/httpd/conf/mime.types
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-autoindex.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-dav.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-default.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-info.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-languages.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-manual.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-mpm.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-multilang-errordoc.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-userdir.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-vhosts.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/proxy-html.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-autoindex.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-dav.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-default.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-info.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-languages.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-manual.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-mpm.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-multilang-errordoc.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-userdir.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-vhosts.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/proxy-html.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/httpd.conf
    
    %config %{_sysconfdir}/logrotate.d/httpd
    %config %{_sysconfdir}/rc.d/init.d/httpd
    %config %{_sysconfdir}/rc.d/init.d/htcacheclean
    
    %{_sbindir}/fcgistarter
    %{_sbindir}/htcacheclean
    %{_sbindir}/httpd
    %{_sbindir}/apachectl
    %attr(4510,root,%{suexec_caller}) %{_sbindir}/suexec
    
    %dir %{_libdir}/httpd
    %dir %{_libdir}/httpd/modules
    %{_libdir}/httpd/modules/mod_access_compat.so
    %{_libdir}/httpd/modules/mod_actions.so
    %{_libdir}/httpd/modules/mod_alias.so
    %{_libdir}/httpd/modules/mod_allowmethods.so
    %{_libdir}/httpd/modules/mod_asis.so
    %{_libdir}/httpd/modules/mod_auth_basic.so
    %{_libdir}/httpd/modules/mod_auth_digest.so
    %{_libdir}/httpd/modules/mod_auth_form.so
    %{_libdir}/httpd/modules/mod_authn_anon.so
    %{_libdir}/httpd/modules/mod_authn_core.so
    %{_libdir}/httpd/modules/mod_authn_dbd.so
    %{_libdir}/httpd/modules/mod_authn_dbm.so
    %{_libdir}/httpd/modules/mod_authn_file.so
    %{_libdir}/httpd/modules/mod_authn_socache.so
    %{_libdir}/httpd/modules/mod_authz_core.so
    %{_libdir}/httpd/modules/mod_authz_dbd.so
    %{_libdir}/httpd/modules/mod_authz_dbm.so
    %{_libdir}/httpd/modules/mod_authz_groupfile.so
    %{_libdir}/httpd/modules/mod_authz_host.so
    %{_libdir}/httpd/modules/mod_authz_owner.so
    %{_libdir}/httpd/modules/mod_authz_user.so
    %{_libdir}/httpd/modules/mod_autoindex.so
    %{_libdir}/httpd/modules/mod_bucketeer.so
    %{_libdir}/httpd/modules/mod_buffer.so
    %{_libdir}/httpd/modules/mod_cache_disk.so
    %{_libdir}/httpd/modules/mod_cache_socache.so
    %{_libdir}/httpd/modules/mod_cache.so
    %{_libdir}/httpd/modules/mod_case_filter.so
    %{_libdir}/httpd/modules/mod_case_filter_in.so
    %{_libdir}/httpd/modules/mod_cgid.so
    %{_libdir}/httpd/modules/mod_charset_lite.so
    %{_libdir}/httpd/modules/mod_data.so
    %{_libdir}/httpd/modules/mod_dav_fs.so
    %{_libdir}/httpd/modules/mod_dav_lock.so
    %{_libdir}/httpd/modules/mod_dav.so
    %{_libdir}/httpd/modules/mod_dbd.so
    %{_libdir}/httpd/modules/mod_deflate.so
    %{_libdir}/httpd/modules/mod_dialup.so
    %{_libdir}/httpd/modules/mod_dir.so
    %{_libdir}/httpd/modules/mod_dumpio.so
    %{_libdir}/httpd/modules/mod_echo.so
    %{_libdir}/httpd/modules/mod_env.so
    %{_libdir}/httpd/modules/mod_expires.so
    %{_libdir}/httpd/modules/mod_ext_filter.so
    %{_libdir}/httpd/modules/mod_file_cache.so
    %{_libdir}/httpd/modules/mod_filter.so
    %{_libdir}/httpd/modules/mod_headers.so
    %{_libdir}/httpd/modules/mod_heartbeat.so
    %{_libdir}/httpd/modules/mod_heartmonitor.so
    %{_libdir}/httpd/modules/mod_include.so
    %{_libdir}/httpd/modules/mod_info.so
    %{_libdir}/httpd/modules/mod_lbmethod_bybusyness.so
    %{_libdir}/httpd/modules/mod_lbmethod_byrequests.so
    %{_libdir}/httpd/modules/mod_lbmethod_bytraffic.so
    %{_libdir}/httpd/modules/mod_lbmethod_heartbeat.so
    %{_libdir}/httpd/modules/mod_log_config.so
    %{_libdir}/httpd/modules/mod_log_debug.so
    %{_libdir}/httpd/modules/mod_log_forensic.so
    %{_libdir}/httpd/modules/mod_logio.so
    %{_libdir}/httpd/modules/mod_macro.so
    %{_libdir}/httpd/modules/mod_mime_magic.so
    %{_libdir}/httpd/modules/mod_mime.so
    %{_libdir}/httpd/modules/mod_mpm_event.so
    %{_libdir}/httpd/modules/mod_mpm_prefork.so
    %{_libdir}/httpd/modules/mod_mpm_worker.so
    %{_libdir}/httpd/modules/mod_negotiation.so
    %{_libdir}/httpd/modules/mod_proxy_ajp.so
    %{_libdir}/httpd/modules/mod_proxy_balancer.so
    %{_libdir}/httpd/modules/mod_proxy_connect.so
    %{_libdir}/httpd/modules/mod_proxy_express.so
    %{_libdir}/httpd/modules/mod_proxy_fcgi.so
    %{_libdir}/httpd/modules/mod_proxy_fdpass.so
    %{_libdir}/httpd/modules/mod_proxy_ftp.so
    %{_libdir}/httpd/modules/mod_proxy_http.so
    %{_libdir}/httpd/modules/mod_proxy_scgi.so
    %{_libdir}/httpd/modules/mod_proxy_uwsgi.so
    %{_libdir}/httpd/modules/mod_proxy_wstunnel.so
    %{_libdir}/httpd/modules/mod_proxy_hcheck.so
    %{_libdir}/httpd/modules/mod_proxy.so
    %{_libdir}/httpd/modules/mod_ratelimit.so
    %{_libdir}/httpd/modules/mod_reflector.so
    %{_libdir}/httpd/modules/mod_remoteip.so
    %{_libdir}/httpd/modules/mod_reqtimeout.so
    %{_libdir}/httpd/modules/mod_request.so
    %{_libdir}/httpd/modules/mod_rewrite.so
    %{_libdir}/httpd/modules/mod_sed.so
    %{_libdir}/httpd/modules/mod_session_cookie.so
    %{_libdir}/httpd/modules/mod_session_crypto.so
    %{_libdir}/httpd/modules/mod_session_dbd.so
    %{_libdir}/httpd/modules/mod_session.so
    %{_libdir}/httpd/modules/mod_setenvif.so
    %{_libdir}/httpd/modules/mod_slotmem_plain.so
    %{_libdir}/httpd/modules/mod_slotmem_shm.so
    %{_libdir}/httpd/modules/mod_socache_dbm.so
    %{_libdir}/httpd/modules/mod_socache_memcache.so
    %{_libdir}/httpd/modules/mod_socache_redis.so
    %{_libdir}/httpd/modules/mod_socache_shmcb.so
    %{_libdir}/httpd/modules/mod_speling.so
    %{_libdir}/httpd/modules/mod_status.so
    %{_libdir}/httpd/modules/mod_substitute.so
    %{_libdir}/httpd/modules/mod_suexec.so
    %{_libdir}/httpd/modules/mod_unique_id.so
    %{_libdir}/httpd/modules/mod_unixd.so
    %{_libdir}/httpd/modules/mod_userdir.so
    %{_libdir}/httpd/modules/mod_usertrack.so
    %{_libdir}/httpd/modules/mod_version.so
    %{_libdir}/httpd/modules/mod_vhost_alias.so
    %{_libdir}/httpd/modules/mod_watchdog.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
    %{contentdir}/html/index.html
    %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
    %attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd/cache-root
    
    %{_mandir}/man1/*
    %{_mandir}/man8/suexec*
    %{_mandir}/man8/apachectl.8*
    %{_mandir}/man8/httpd.8*
    %{_mandir}/man8/htcacheclean.8*
    %{_mandir}/man8/fcgistarter.8*
    
    %files manual
    %defattr(-,root,root)
    %{contentdir}/manual
    %{contentdir}/error/README
    
    %files tools
    %defattr(-,root,root)
    %{_bindir}/ab
    %{_bindir}/htdbm
    %{_bindir}/htdigest
    %{_bindir}/htpasswd
    %{_bindir}/logresolve
    %{_bindir}/httxt2dbm
    %{_sbindir}/rotatelogs
    %{_mandir}/man1/htdbm.1*
    %{_mandir}/man1/htdigest.1*
    %{_mandir}/man1/htpasswd.1*
    %{_mandir}/man1/httxt2dbm.1*
    %{_mandir}/man1/ab.1*
    %{_mandir}/man1/logresolve.1*
    %{_mandir}/man8/rotatelogs.8*
    %doc LICENSE NOTICE
    
    %files -n mod_authnz_ldap
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_ldap.so
    %{_libdir}/httpd/modules/mod_authnz_ldap.so
    
    %files -n mod_lua
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_lua.so
    
    %files -n mod_proxy_html
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_proxy_html.so
    %{_libdir}/httpd/modules/mod_xml2enc.so
    
    %files -n mod_ssl
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_ssl.so
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-ssl.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-ssl.conf
    %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
    %{_bindir}/apxs
    %{_sbindir}/checkgid
    %{_bindir}/dbmmanage
    %{_sbindir}/envvars*
    %{_mandir}/man1/dbmmanage.1*
    %{_mandir}/man1/apxs.1*
    %dir %{_libdir}/httpd/build
    %{_libdir}/httpd/build/*.mk
    %{_libdir}/httpd/build/instdso.sh
    %{_libdir}/httpd/build/config.nice
    %{_libdir}/httpd/build/mkdir.sh
    
    ������������������������������������������������������������������������httpd-2.4.64/build/rpm/httpd.init�������������������������������������������������������������������0000775�0001751�0001751�00000010432�12002527420�016524� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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        Startup script for the Apache Web Server
    #
    # chkconfig: - 85 15
    # description: The Apache HTTP Server is an efficient and extensible  \
    #             server implementing the current HTTP standards.
    # processname: httpd
    # pidfile: /var/run/httpd.pid
    # config: /etc/sysconfig/httpd
    #
    ### BEGIN INIT INFO
    # Provides: httpd
    # Required-Start: $local_fs $remote_fs $network $named
    # Required-Stop: $local_fs $remote_fs $network
    # Should-Start: distcache
    # Short-Description: start and stop Apache HTTP Server
    # Description: The Apache HTTP Server is an extensible server 
    #  implementing the current HTTP standards.
    ### END INIT INFO
    
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    # What were we called? Multiple instances of the same daemon can be
    # created by creating suitably named symlinks to this startup script
    prog=$(basename $0 | sed -e 's/^[SK][0-9][0-9]//')
    
    if [ -f /etc/sysconfig/${prog} ]; then
            . /etc/sysconfig/${prog}
    fi
    
    # Start httpd in the C locale by default.
    HTTPD_LANG=${HTTPD_LANG-"C"}
    
    # 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.
    
    httpd=${HTTPD-/usr/sbin/httpd}
    pidfile=${PIDFILE-/var/run/${prog}.pid}
    lockfile=${LOCKFILE-/var/lock/subsys/${prog}}
    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
            LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
            RETVAL=$?
            echo
            [ $RETVAL = 0 ] && touch ${lockfile}
            return $RETVAL
    }
    stop() {
    	echo -n $"Stopping $prog: "
    	killproc -p ${pidfile} -d 10 $httpd
    	RETVAL=$?
    	echo
    	[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
    }
    reload() {
    	echo -n $"Reloading $prog: "
    	check13 || exit 1
    	killproc -p ${pidfile} $httpd -HUP
    	RETVAL=$?
    	echo
    }
    
    # See how we were called.
    case "$1" in
      start)
    	start
    	;;
      stop)
    	stop
    	;;
      status)
            if ! test -f ${pidfile}; then
                echo $prog is stopped
                RETVAL=3
            else  
                status -p ${pidfile} $httpd
                RETVAL=$?
            fi
            ;;
      restart)
    	stop
    	start
    	;;
      condrestart)
    	if test -f ${pidfile} && status -p ${pidfile} $httpd >&/dev/null; then
    		stop
    		start
    	fi
    	;;
      reload)
            reload
    	;;
      configtest)
            LANG=$HTTPD_LANG $httpd $OPTIONS -t
            RETVAL=$?
            ;;
      graceful)
            echo -n $"Gracefully restarting $prog: "
            LANG=$HTTPD_LANG $httpd $OPTIONS -k $@
            RETVAL=$?
            echo
            ;;
      *)
    	echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|graceful|help|configtest}"
    	exit 1
    esac
    
    exit $RETVAL
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/rpm/htcacheclean.init������������������������������������������������������������0000775�0001751�0001751�00000005376�12002527672�020027� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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    Startup script for the Apache cache cleaner
    #
    # chkconfig: - 85 15
    # description: The Apache htcacheclean daemon maintains and prunes the
    #              size of the mod_cache_disk cache directory.
    # processname: htcacheclean
    # pidfile: /var/log/httpd/htcacheclean.pid
    # config: /etc/sysconfig/htcacheclean
    #
    ### BEGIN INIT INFO
    # Provides: htcacheclean
    # Required-Start: $local_fs $remote_fs $network
    # Required-Stop: $local_fs $remote_fs $network
    # Should-Start: httpd
    # Short-Description: start and stop Apache htcacheclean
    # Description: The Apache htcacheclean daemon maintains a mod_cache_disk
    ### END INIT INFO
    
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    # What were we called? Multiple instances of the same daemon can be
    # created by creating suitably named symlinks to this startup script
    prog=$(basename $0 | sed -e 's/^[SK][0-9][0-9]//')
    
    if [ -f /etc/sysconfig/${prog} ]; then
            . /etc/sysconfig/${prog}
    fi
    
    # Path to htcacheclean, server binary, and short-form for messages.
    htcacheclean=${HTTPD-/usr/sbin/htcacheclean}
    lockfile=${LOCKFILE-/var/lock/subsys/${prog}}
    pidfile=/var/run/${prog}.pid
    interval=${INTERVAL-10}
    cachepath=${CACHEPATH-/var/cache/httpd/cache-root}
    limit=${LIMIT-100M}
    RETVAL=0
    
    start() {
            echo -n $"Starting $prog: "
            daemon --pidfile=${pidfile} $htcacheclean -d "$interval" -p "$cachepath" -l "$limit" -P "$pidfile" $OPTIONS
            RETVAL=$?
            echo
            [ $RETVAL = 0 ] && touch ${lockfile}
            return $RETVAL
    }
    stop() {
    	echo -n $"Stopping $prog: "
    	killproc -p ${pidfile} $htcacheclean
    	RETVAL=$?
    	echo
    	[ $RETVAL = 0 ] && rm -f ${lockfile}
    }
    
    # See how we were called.
    case "$1" in
      start)
    	start
    	;;
      stop)
    	stop
    	;;
      status)
            status -p ${pidfile} $htcacheclean
    	RETVAL=$?
    	;;
      restart)
    	stop
    	start
    	;;
      condrestart)
    	if status -p ${pidfile} $htcacheclean >&/dev/null; then
    		stop
    		start
    	fi
    	;;
      *)
    	echo $"Usage: $prog {start|stop|restart|condrestart|status|help}"
    	exit 1
    esac
    
    exit $RETVAL
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/win32/���������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014676� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/win32/apache.ico�����������������������������������������������������������������0000664�0001751�0001751�00000002066�10151220336�016575� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������  �������&��������(����(��� ���@������������������������������������������������������������������������������������������������������������������������������������������������������������������������ݐ������������	P������������D@����������	D����������DM���������	DMِ���������Dِ��������	Dِ���������DMٙ���������	Dِ���������DMٙ���������	Dݙ���������	Mٙ����������Dݙ����������	Dݐ����������	Dݙ�����������M������������M�����������������������������������;=������������X�������������X�������������������������������������������������������������?�?�����?�??(������ ������������������������������������������������������������������������������	�����	P�����D����	M���M���	Dِ���
    ����Dِ���	M����	ِ����M����������U�����Y������P������������������������?����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/win32/httpd.rc�������������������������������������������������������������������0000664�0001751�0001751�00000005243�12242535256�016346� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_release.h"
    
    #define AP_SERVER_LICENSE_RCSTR \
      "Licensed under the Apache License, Version 2.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."
    
    
    #ifdef ICON_FILE
    1 ICON DISCARDABLE APR_STRINGIFY(ICON_FILE)
    #endif
    
    #define LONG_NAME_STR APR_STRINGIFY(LONG_NAME)
    #define BIN_NAME_STR APR_STRINGIFY(BIN_NAME)
    
    1 VERSIONINFO
     FILEVERSION AP_SERVER_PATCHLEVEL_CSV,0
     PRODUCTVERSION AP_SERVER_PATCHLEVEL_CSV,0
     FILEFLAGSMASK 0x3fL
    #if AP_SERVER_DEVBUILD_BOOLEAN
    #if defined(_DEBUG)
     FILEFLAGS 0x03L
    #else
     FILEFLAGS 0x02L
    #endif
    #else
    #if defined(_DEBUG)
     FILEFLAGS 0x01L
    #else
     FILEFLAGS 0x00L
    #endif
    #endif
    #if defined(WINNT) || defined(WIN64)
     FILEOS 0x40004L
    #else
     FILEOS 0x4L
    #endif
    #if defined(APP_FILE)
     FILETYPE 0x1L
    #else
     FILETYPE 0x2L
    #endif
     FILESUBTYPE 0x0L
    BEGIN
      BLOCK "StringFileInfo"
      BEGIN
        BLOCK "040904b0"
        BEGIN
          VALUE "Comments", AP_SERVER_LICENSE_RCSTR "\0"
          VALUE "CompanyName", AP_SERVER_BASEVENDOR "\0"
          VALUE "FileDescription", LONG_NAME_STR "\0"
          VALUE "FileVersion", AP_SERVER_BASEREVISION "\0"
          VALUE "InternalName", BIN_NAME_STR "\0"
          VALUE "LegalCopyright", AP_SERVER_COPYRIGHT "\0"
          VALUE "OriginalFilename", BIN_NAME_STR "\0"
          VALUE "ProductName", "Apache HTTP Server\0"
          VALUE "ProductVersion", AP_SERVER_BASEREVISION "\0"
        END
      END
      BLOCK "VarFileInfo"
      BEGIN
        VALUE "Translation", 0x409, 1200
      END
    END
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/aix/�����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014515� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/aix/mkinstallp.ksh���������������������������������������������������������������0000775�0001751�0001751�00000013523�12206332076�017377� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/ksh
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    #
    
    # minstallp.ksh # create an installp image of ${NAME} (defined in aixinfo)
    # from TEMPDIR using mkinstallp (part of bos.adt.insttools)
    
    [[ $# == 0 ]] && echo $0: Syntax error && echo "Syntax: $0 <BaseDirectory>" && exit -1
    
    umask 022
    TEMPDIR=$1
    BASE=`pwd`
    cd ${TEMPDIR}
    [[ $? != 0 ]] && echo $0: ${TEMPDIR} -- bad directory && exit -1
    
    # clean up side-effects from DEBUG passes - usr/local might be there as
    # a circular link i.e. usr/local points at /usr/local
    # as we are not using /usr/local for ASF packaging, remove it!
    # mkinstallp seems to make usr/local -> /usr/local 
    [[ -f usr/local ]] && rm -f usr/local && echo removed unexpected usr/local !!
    [[ -L usr/local ]] && rm -f usr/local && echo removed unexpected usr/local !!
    [[ -d usr/local ]] && rm -rf usr/local && echo removed unexpected usr/local !!
    
    # use the aixinfo for PKG NAME VERSION etc labels
    cd ${BASE}
    . build/aix/aixinfo
    # INFO=${BASE}/build/aix/.info
    # mkdir -p $INFO
    INFO=${BASE}/build/aix
    template=${INFO}/${PKG}.${NAME}.${VERSION}.template
    >$template
    
    # mkinstallp template definitions
    # TODO: add AIX oslevel/uname information for package filename
    package=$PKG
    name=$NAME
    vrmf=$VERSION
    release=$RELEASE
    descr="$NAME version ${VERSION} for $ARCH ${VENDOR}"
    
    # copy LICENSE information
    # TODO: setup template so that license acceptance is required
    # TODO: add Copyright Information for display during install
    mkdir -p ${TEMPDIR}/usr/swlag/en_US
    cp ${BASE}/LICENSE ${TEMPDIR}/usr/swlag/en_US/${PKG}.${NAME}.la
    
    cd ${TEMPDIR}
    # remove files we do not want as "part" possibly
    # left-over from a previous packaging
    rm -rf .info lpp_name tmp usr/lpp
    [[ $? -ne 0 ]] && echo $cmd: cleanup error && pwd && ls -ltr && exit -1
    
    #if we are going to add extra symbolic links - do it now
    [[ -r build/aix/aixlinks ]] && ksh build/aix/aixlinks
    
    # get the directory sizes in blocks
    for d in etc opt var
    do
    	if [[ -d $d/${NAME} ]]
    	then
    		set `du -s $d/${NAME}`
    	else
    		[[ -d $d ]] && set `du -s $d`
    	fi
    	# make sure the argument exists before using setting values
    	if [[ -d $d ]]
    	then
    		eval nm$d=/"$2"
    		let sz$d=$1
    	fi
    done
    
    files=./${NAME}.${VERSION}
    cd ${TEMPDIR}/..
    find ${files} -type d -exec chmod og+rx {} \;
    chmod -R go+r ${files}
    chown -R 0.0 ${files}
    
    cat - <<EOF >>$template
    Package Name: ${PKG}.${NAME}
    Package VRMF: ${VERSION}.${RELEASE}
    Update: N
    Fileset
      Fileset Name: ${PKG}.${NAME}.rte
      Fileset VRMF: ${VERSION}.${RELEASE}
      Fileset Description: ${descr}
      USRLIBLPPFiles
      EOUSRLIBLPPFiles
      Bosboot required: N
      License agreement acceptance required: N
      Name of license agreement: 
      Include license files in this package: N
      Requisites:
    EOF
    
    [[ $szetc -ne 0 ]] && echo "        Upsize: ${nmetc} $szetc;" >> $template
    [[ $szopt -ne 0 ]] && echo "        Upsize: ${nmopt} $szopt;" >> $template
    [[ $szvar -ne 0 ]] && echo "        Upsize: ${nmvar} $szvar;" >> $template
    echo "  USRFiles" >> $template
    
    # USR part -- i.e. files in /usr and /opt
    cd ${TEMPDIR}/..
    find ${files}/usr/swlag ${files}/opt \
    	| sed -e s#^${files}## | sed -e "/^$/d" >>$template
    echo "  EOUSRFiles" >> $template
    
    if [[ $szetc -gt 0 || $szvar -gt 0 ]]
    then
    INSTROOT=${TEMPDIR}/usr/lpp/${PKG}.${NAME}/inst_root
    mkdir -p ${INSTROOT}
    cd ${TEMPDIR}
    [[ $szetc -gt 0 ]] && find ./etc -type d | backup -if - | (cd ${INSTROOT}; restore -xqf -) >/dev/null
    [[ $szvar -gt 0 ]] && find ./var -type d | backup -if - | (cd ${INSTROOT}; restore -xqf -) >/dev/null
    cat - <<EOF >>$template
      ROOT Part: Y
      ROOTFiles
    EOF
    
    # ROOT part 
    cd ${TEMPDIR}/..
    find ${files}/etc ${files}/var \
    	| sed -e s#^${files}## | sed -e "/^$/d" >>$template
    else
    # no ROOT parts to include
    cat - <<EOF >>$template
      ROOT Part: N
      ROOTFiles
    EOF
    fi
    cat - <<EOF >>$template
      EOROOTFiles
      Relocatable: N
    EOFileset
    EOF
    # man pages as separate fileset
    cd ${TEMPDIR}
    if [[ -d usr/share/man ]]
    then
    	# manual pages, space required calculation
    	set `du -s usr/share/man`
    	szman=$1
    	descr="$NAME ${VERSION} man pages ${VENDOR}"
    	cat - <<EOF >>$template
    Fileset
      Fileset Name: ${PKG}.${NAME}.man.en_US
      Fileset VRMF: ${VERSION}.${RELEASE}
      Fileset Description: ${descr}
      USRLIBLPPFiles
      EOUSRLIBLPPFiles
      Bosboot required: N
      License agreement acceptance required: N
      Name of license agreement:
      Include license files in this package: N
      Requisites:
    EOF
    
    	echo "        Upsize: /usr/share/man ${szman};" >> $template
    	echo "  USRFiles" >> $template
    	cd ${TEMPDIR}/..
    	find ${files}/usr/share | sed -e s#^${files}## | sed -e "/^$/d" >>$template
    	cat - <<EOF >>$template
      EOUSRFiles
      ROOT Part: N
      ROOTFiles
      EOROOTFiles
      Relocatable: N
    EOFileset
    
    EOF
    fi
    
    # use mkinstallp to create the fileset. result is in ${TEMPDIR}/tmp
    # must actually sit in TEMPDIR for ROOT part processing to succeed
    # also - need "empty" directories to exist, as they do not get copied
    # in the inst_root part
    cd ${TEMPDIR}
    mkinstallp -d ${TEMPDIR} -T ${template}
    [[ $? -ne 0 ]] && echo mkinstallp returned error status && exit -1
    
    # copy package to build/aix
    # create TOC
    cp ${TEMPDIR}/tmp/$PKG.$NAME.$VERSION.0.bff ${BASE}/build/aix
    cd ${BASE}/build/aix
    rm -f $PKG.$NAME.$VERSION.$ARCH.I
    mv $PKG.$NAME.$VERSION.0.bff $PKG.$NAME.$ARCH.$VERSION.I
    rm -f .toc
    inutoc .
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/aix/aixinfo����������������������������������������������������������������������0000664�0001751�0001751�00000000666�11737125415�016100� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    PKG="ASF"
    NAME="httpd"
    ARCH="powerpc"
    VERSION="2.2.22"
    CATEGORY="application"
    VENDOR="Apache Software Foundation"
    EMAIL="dev@httpd.apache.org"
    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=0
    fi
    ��������������������������������������������������������������������������httpd-2.4.64/build/aix/aixproto.ksh�����������������������������������������������������������������0000775�0001751�0001751�00000003164�11737125415�017073� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/ksh
    TEMPDIR=$1
    BUILD=`pwd`
    . build/aix/pkginfo
    
    package=$PKG
    name=$NAME
    vrmf=$VERSION
    descr="$VENDOR $NAME for $ARCH"
    umask 022
    INFO=$BUILD/build/aix/.info
    mkdir -p $INFO
    
    template=${INFO}/${PKG}.${NAME}.${vrmf}.template
    >$template
    
    cd ${TEMPDIR}
    rm -rf .info lpp_name tmp
    # get the directory sizes in blocks
    for d in etc opt var
    do
            set `du -s $d/${NAME}`
            let sz$d=$1+1
    done
    set `du -s usr/share/man`
    szman=$1+1
    
    files=./httpd-root
    cd ${TEMPDIR}/..
    find ${files} -type d -exec chmod og+rx {} \;
    chmod -R go+r ${files}
    chown -R 0:0 ${files}
    
    cat - <<EOF >>$template
    Package Name: ${package}.${NAME}
    Package VRMF: ${vrmf}.0
    Update: N
    Fileset
      Fileset Name: ${package}.${NAME}.rte
      Fileset VRMF: ${vrmf}.0
      Fileset Description: ${descr}
      USRLIBLPPFiles
      EOUSRLIBLPPFiles
      Bosboot required: N
      License agreement acceptance required: N
      Include license files in this package: N
      Requisites:
            Upsize: /usr/share/man ${szman};
            Upsize: /etc/${NAME} $szetc;
            Upsize: /opt/${NAME} $szopt;
            Upsize: /var/${NAME} $szvar;
      USRFiles
    EOF
    
    find ${files} | sed -e s#^${files}## | sed -e "/^$/d" >>$template
    
    cat - <<EOF >>$template
      EOUSRFiles
      ROOT Part: N
      ROOTFiles
      EOROOTFiles
      Relocatable: N
    EOFileset
    EOF
    
    cp ${template} ${BUILD}/build/aix
    
    # use mkinstallp to create the fileset. result is in ${TEMPDIR}/tmp
    mkinstallp -d ${TEMPDIR} -T ${template}
    
    cp ${TEMPDIR}/tmp/$PKG.$NAME.$VERSION.0.bff ${BUILD}/build/aix
    cd $BUILD/build/aix
    rm -f $PKG.$NAME.$VERSION.$ARCH.I
    mv $PKG.$NAME.$VERSION.0.bff $PKG.$NAME.$VERSION.$ARCH.I
    rm .toc
    inutoc .
    installp -d . -ap ${PKG}.${NAME}
    installp -d . -L
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/aix/README�����������������������������������������������������������������������0000664�0001751�0001751�00000005234�11737125415�015374� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������The script buildaix.ksh will attempt to build a AIX installp fileset
    out of a source tree for ASF project
    
    REQUIREMENTS:
      Fileset                      Level  State  Type  Description (Uninstaller)
      ----------------------------------------------------------------------------
      bos.adt.insttools          5.3.7.2    C     F    Tool to Create installp
                                                       Packages
      Fileset                      Level  State  Type  Description (Uninstaller)
      ----------------------------------------------------------------------------
      rpm.rte                   3.0.5.41    C     F    RPM Package Manager
    
    Additional:
    Preferred: download zlib sources and copy zlib.h and zconf.h to /opt/include
    and, if configure cannot find them directly, add symbolic links from /usr/include to /opt/include
    
    To build a package, make sure you are in the root of the source tree,
    and run:
    
    build/aix/buildaix.ksh
    
    An AIX fileset named $PKG.$NAME.$ARCH.$VERSION.I will be
    created in the build/aix directory. the .template file created is also there.
    
    KNOWN issues:
    on AIX libtool is known to have issues with the install command.
    Some of these issues have been resolved by extracting the apr/apu utilities
    from the projects (i.e. NOT using the embedded version)
    In case of problems I recommend that you install the GNU 'install' program (part of coreutils)
    If make DESTDIR=$TEMPDIR install command continues to fail, try 'make install' and then run
    the buildaix.ksh command again
    
    TODO
    Add Copyright display/banner
    Add Apache LICENSE to fileset and require acceptance
    Add special instructions for TCB - to ignore /etc/* /var/httpd/htdocs/*
    Add _config_i scripts to setup autostart
    Add _pre_i scripts to verify pre-requisites, required users/groups, etc.
    
    # This layout is intended to put customizeable data in /etc and /var
    # the file listing will be used to create an exceptions file to modify
    # the behavior of syschk checksum generation.
    # AIX layout
    <Layout AIX>
        prefix:        /opt/httpd
        exec_prefix:   /opt/httpd
        bindir:        ${exec_prefix}/bin
        sbindir:       ${exec_prefix}/sbin
        libdir:        ${exec_prefix}/lib
        libexecdir:    ${exec_prefix}/libexec
        mandir:        /usr/share/man
        sysconfdir:    /etc/httpd
        datadir:       /var/httpd
        installbuilddir: ${datadir}/build
        errordir:      ${datadir}/error
        htdocsdir:     ${datadir}/htdocs
        cgidir:        ${datadir}/cgi-bin
        iconsdir:      ${prefix}/icons
        manualdir:     ${prefix}/manual
        includedir:    ${prefix}/include
        localstatedir: /var/httpd
        runtimedir:    ${localstatedir}/run
        logfiledir:    ${localstatedir}/logs
        proxycachedir: ${localstatedir}/proxy
    </Layout>
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/aix/buildaix.ksh�����������������������������������������������������������������0000775�0001751�0001751�00000007062�11737125415�017030� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/ksh
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    #
    
    # buildaix.ksh: This script builds an AIX fileset of Apache httpd
    
    # if arguments - try to run fast
    cmd=$0
    
    export CFLAGS='-O2 -qlanglvl=extc99'
    
    lslpp -L bos.adt.insttools >/dev/null
     [[ $? -ne 0 ]] && echo "must have bos.adt.insttools installed" && exit -1
    
    apr_config=`which apr-1-config`
    apu_config=`which apu-1-config`
    
    if [[ -z ${apr_config} && -z ${apu_config} ]]
    then
    	export PATH=/opt/bin:${PATH}
    	apr_config=`which apr-1-config`
    	apu_config=`which apu-1-config`
    fi
    
    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
      argc--
    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 "If available, install the ASF.apu.rte and ASF.apr.rte filesets"
      echo "Usage: $cmd [--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 "If available, install the ASF.apu.rte and ASF.apr.rte filesets"
      echo "Usage: $cmd [--with-apr=[dir|file]] [--with-apr-util=[dir|file]]"
      exit 1
    fi
    
    . build/aix/aixinfo
    LAYOUT=AIX
    TEMPDIR=/var/tmp/$USER/${NAME}.${VERSION}
    rm -rf $TEMPDIR
    
    if [[ ! -e ./Makefile ]] # if Makefile exists go faster
    then
    #		--with-mpm=worker \n\
    	echo "+ ./configure \n\
    		--enable-layout=$LAYOUT \n\
    		--with-apr=$apr_config \n\
    		--with-apr-util=$apu_config \n\
    		--enable-mpms-shared=all \n\
    		--enable-mods-shared=all \n\
    		--disable-lua > build/aix/configure.out"
    
    #		--with-mpm=worker \
    	./configure \
    		--enable-layout=$LAYOUT \
    		--with-apr=$apr_config \
    		--with-apr-util=$apu_config \
    		--enable-mpms-shared=all \
    		--enable-mods-shared=all \
    		--disable-lua > build/aix/configure.out
    		 [[ $? -ne 0 ]] && echo './configure' returned an error && exit -1
    else
    	echo $0: using existing Makefile
    	echo $0: run make distclean to get a standard AIX configure
    	echo
    	ls -l ./Makefile config.*
    	echo
    fi
    
    echo "+ make > build/aix/make.out"
    make > build/aix/make.out
     [[ $? -ne 0 ]] && echo 'make' returned an error && exit -1
    
    echo "+ make install DESTDIR=$TEMPDIR > build/aix/install.out"
    make install DESTDIR=$TEMPDIR > build/aix/install.out
     [[ $? -ne 0 ]] && echo 'make install' returned an error && exit -1
    
    echo "+ build/aix/mkinstallp.ksh $TEMPDIR > build/aix/mkinstallp.out"
    build/aix/mkinstallp.ksh $TEMPDIR > build/aix/mkinstallp.out
     [[ $? -ne 0 ]] && echo mkinstallp.ksh returned an error && exit -1
    
    rm -rf $TEMPDIR
    
    # list installable fileset(s)
    echo ========================
    installp -d build/aix -L
    echo ========================
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/PrintPath������������������������������������������������������������������������0000775�0001751�0001751�00000006145�15032766624�015601� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    #
    # Look for program[s] somewhere in $PATH.
    #
    # Options:
    #  -s
    #    Do not print out full pathname. (silent)
    #  -pPATHNAME
    #    Look in PATHNAME instead of $PATH
    #
    # Usage:
    #  PrintPath [-s] [-pPATHNAME] program [program ...]
    #
    # Initially written by Jim Jagielski for the Apache configuration mechanism
    #  (with kudos to Kernighan/Pike)
    
    ##
    # Some "constants"
    ##
    pathname=$PATH
    echo="yes"
    
    ##
    # Find out what OS we are running for later on
    ##
    os=`(uname) 2>/dev/null`
    
    ##
    # Parse command line
    ##
    for args in $*
    do
        case $args in
    	-s  ) echo="no" ;;
    	-p* ) pathname="`echo $args | sed 's/^..//'`" ;;
    	*   ) programs="$programs $args" ;;
        esac
    done
    
    ##
    # Now we make the adjustments required for OS/2 and everyone
    # else :)
    #
    # First of all, all OS/2 programs have the '.exe' extension.
    # Next, we adjust PATH (or what was given to us as PATH) to
    # be whitespace separated directories.
    # Finally, we try to determine the best flag to use for
    # test/[] to look for an executable file. OS/2 just has '-r'
    # but with other OSs, we do some funny stuff to check to see
    # if test/[] knows about -x, which is the prefered flag.
    ##
    
    if [ "x$os" = "xOS/2" ]
    then
        ext=".exe"
        pathname=`echo -E $pathname |
         sed 's/^;/.;/
    	  s/;;/;.;/g
    	  s/;$/;./
    	  s/;/ /g
    	  s/\\\\/\\//g' `
        test_exec_flag="-r"
    else
        ext=""	# No default extensions
        pathname=`echo $pathname |
         sed 's/^:/.:/
    	  s/::/:.:/g
    	  s/:$/:./
    	  s/:/ /g' `
        # Here is how we test to see if test/[] can handle -x
        testfile="pp.t.$$"
    
        cat > $testfile <<ENDTEST
    #!/bin/sh
    if [ -x / ] || [ -x /bin ] || [ -x /bin/ls ]; then
        exit 0
    fi
    exit 1
    ENDTEST
    
        if `/bin/sh $testfile 2>/dev/null`; then
    	test_exec_flag="-x"
        else
    	test_exec_flag="-r"
        fi
        rm -f $testfile
    fi
    
    for program in $programs
    do
        for path in $pathname
        do
    	if [ $test_exec_flag $path/${program}${ext} ] && \
    	   [ ! -d $path/${program}${ext} ]; then
    	    if [ "x$echo" = "xyes" ]; then
    		echo $path/${program}${ext}
    	    fi
    	    exit 0
    	fi
    
    # Next try without extension (if one was used above)
    	if [ "x$ext" != "x" ]; then
                if [ $test_exec_flag $path/${program} ] && \
                   [ ! -d $path/${program} ]; then
                    if [ "x$echo" = "xyes" ]; then
                        echo $path/${program}
                    fi
                    exit 0
                fi
            fi
        done
    done
    exit 1
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/modules.c.in���������������������������������������������������������������������0000664�0001751�0001751�00000001717�15022007067�016147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
     * modules.c --- automatically generated by Apache
     * configuration script.  DO NOT HAND EDIT!!!!!
     */
    
    #include "ap_config.h"
    #include "httpd.h"
    #include "http_config.h"
    
    @MODULES_EXTERN@
    /*
     *  Modules which implicitly form the
     *  list of activated modules on startup,
     *  i.e. these are the modules which are
     *  initially linked into the Apache processing
     *  [extendable under run-time via AddModule]
     */
    AP_DECLARE_DATA module *ap_prelinked_modules[] = {
    @MODULES_PRELINK@
      NULL
    };
    
    /*
     *  We need the symbols as strings for <IfModule> containers
     */
    ap_module_symbol_t ap_prelinked_module_symbols[] = {
    @MODULES_SYMBOLS@
      {NULL, NULL}
    };
    
    /*
     *  Modules which initially form the
     *  list of available modules on startup,
     *  i.e. these are the modules which are
     *  initially loaded into the Apache process
     *  [extendable under run-time via LoadModule]
     */
    module *ap_preloaded_modules[] = {
    @MODULES_PRELOAD@
      NULL
    };
    �������������������������������������������������httpd-2.4.64/build/nw_export.inc��������������������������������������������������������������������0000664�0001751�0001751�00000003642�14046725222�016452� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* 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. */
    #undef  AP_DECLARE
    #define AP_DECLARE                 AP_DECLARE
    #undef  AP_CORE_DECLARE
    #define AP_CORE_DECLARE            AP_CORE_DECLARE
    #undef  AP_DECLARE_NONSTD
    #define AP_DECLARE_NONSTD          AP_DECLARE_NONSTD
    #undef  AP_CORE_DECLARE_NONSTD
    #define AP_CORE_DECLARE_NONSTD     AP_CORE_DECLARE_NONSTD
    #undef  AP_DECLARE_HOOK
    #define AP_DECLARE_HOOK            AP_DECLARE_HOOK
    #undef  AP_DECLARE_DATA
    #define AP_DECLARE_DATA            AP_DECLARE_DATA
    #undef  APR_DECLARE_OPTIONAL_FN
    #define APR_DECLARE_OPTIONAL_FN    APR_DECLARE_OPTIONAL_FN
    #undef  APR_DECLARE_EXTERNAL_HOOK
    #define APR_DECLARE_EXTERNAL_HOOK  APR_DECLARE_EXTERNAL_HOOK
    #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 "ap_expr.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_ssl.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_cookies.h"
    #include "util_ebcdic.h"
    #include "util_fcgi.h"
    #include "util_filter.h"
    /*#include "util_ldap.h"*/
    #include "util_md5.h"
    #include "util_mutex.h"
    #include "util_script.h"
    #include "util_time.h"
    #include "util_varbuf.h"
    #include "util_xml.h"
    
    #include "mod_core.h"
    #include "mod_auth.h"
    #include "mod_watchdog.h"
    
    ����������������������������������������������������������������������������������������������httpd-2.4.64/build/build-modules-c.cmake������������������������������������������������������������0000664�0001751�0001751�00000002376�15022007067�017717� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function(generate_builtin_modules_c output_filename module_list)
      list(PREPEND module_list "core")
    
      foreach(module ${module_list})
        string(APPEND MODULES_EXTERN "extern module ${module}_module;\n")
        string(APPEND MODULES_PRELINK "  &${module}_module,\n")
        string(APPEND MODULES_SYMBOLS "  {\"${module}_module\", &${module}_module},\n")
        string(APPEND MODULES_PRELOAD "  &${module}_module,\n")
      endforeach()
    
      configure_file("build/modules.c.in" ${output_filename})
    endfunction()
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/pkg/�����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014515� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/pkg/pkginfo.in�������������������������������������������������������������������0000664�0001751�0001751�00000000343�10200230015�016446� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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"
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/pkg/buildpkg.sh������������������������������������������������������������������0000775�0001751�0001751�00000005321�10455010104�016631� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/pkg/README�����������������������������������������������������������������������0000664�0001751�0001751�00000001053�10166516103�015360� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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-<version>-<architecture>-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
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/NWGNUtail.inc��������������������������������������������������������������������0000664�0001751�0001751�00000021571�12400620033�016160� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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.
    #
    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 = Licensed under the Apache License, Version 2.0
    endif
    
    ifeq "$(NLM_FLAGS)" ""
    NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION
    endif
    
    ifeq "$(NLM_STACK_SIZE)" ""
    NLM_STACK_SIZE = 65536
    endif
    
    ifeq "$(NLM_ENTRY_SYM)" ""
    NLM_ENTRY_SYM = _LibCPrelude
    endif
    
    ifeq "$(NLM_EXIT_SYM)" ""
    NLM_EXIT_SYM = _LibCPostlude
    endif
    
    ifeq "$(NLM_VERSION)" ""
    NLM_VERSION = $(VERSION)
    endif
    
    #
    # Create dependency lists based on the files available
    #
    
    STANDARD_DEPENDS	= \
    				$(APBUILD)/NWGNUhead.inc \
    				$(APBUILD)/NWGNUenvironment.inc \
    				$(APBUILD)/NWGNUtail.inc \
    				$(CUSTOM_INI) \
    				$(EOLIST)
    
    CCOPT_DEPENDS	= $(STANDARD_DEPENDS)
    
    $(NLM_NAME)_LINKOPT_DEPENDS	= \
    				$(TARGET_lib) \
    				$(STANDARD_DEPENDS) \
    				$(VERSION_INC) \
    				$(EOLIST)
    
    ifeq "$(words $(strip $(TARGET_lib)))" "1"
    LIB_NAME			= $(basename $(notdir $(TARGET_lib)))
    $(LIB_NAME)_LIBLST_DEPENDS	= \
    				$(FILES_lib_objs) \
    				$(STANDARD_DEPENDS) \
    				$(CUSTOM_INI) \
    				$(EOLIST)
    endif
    
    ifeq "$(wildcard NWGNU$(LIB_NAME))" "NWGNU$(LIB_NAME)"
    $(LIB_NAME)_LIBLST_DEPENDS	+= NWGNU$(LIB_NAME)
    CCOPT_DEPENDS	+= NWGNU$(LIB_NAME)
    else
    CCOPT_DEPENDS	+= NWGNUmakefile
    endif
    
    ifeq "$(wildcard NWGNU$(NLM_NAME))" "NWGNU$(NLM_NAME)"
    $(NLM_NAME)_LINKOPT_DEPENDS	+= NWGNU$(NLM_NAME)
    CCOPT_DEPENDS	+= NWGNU$(NLM_NAME)
    else
    CCOPT_DEPENDS	+= NWGNUmakefile
    endif
    
    CPPOPT_DEPENDS	= $(CCOPT_DEPENDS)
    
    #
    # Generic compiler rules
    #
    
    ifneq "$(MAKECMDGOALS)" "clean"
    ifneq "$(findstring clobber_,$(MAKECMDGOALS))" "clobber_"
    $(APBUILD)/NWGNUversion.inc: $(APBUILD)/nw_ver.awk $(SRC)/include/ap_release.h
    	@echo $(DL)GEN  $@$(DL)
    	$(AWK) -f $^ $(SRC)/.svn/all-wcprops > $@
    
    -include $(APBUILD)/NWGNUversion.inc
    
    ifneq "$(strip $(VERSION_STR))" ""
    VERSION_INC = $(APBUILD)/NWGNUversion.inc
    else
    VERSION		= 2,4,0
    VERSION_STR	= 2.4.0
    VERSION_MAJMIN	= 24
    endif
    endif
    endif
    ifeq "$(USE_SVNREV)" "1"
    ifneq "$(strip $(SVN_REVISION))" ""
    CFLAGS	+= -DAP_SERVER_ADD_STRING=\"$(SVN_REVISION)\"
    endif
    endif
    
    
    ifeq "$(words $(strip $(TARGET_nlm)))" "1"
    
    $(OBJDIR)/%.o: %.c $(OBJDIR)/$(NLM_NAME)_cc.opt
    	@echo $(DL)CC   $<$(DL)
    	$(CC) -o $@ $< @$(word 2, $^)
    
    $(OBJDIR)/$(NLM_NAME)_cc.opt: $(CCOPT_DEPENDS)
    	$(call DEL,$@)
    	@echo $(DL)GEN  $@$(DL)
    ifneq "$(strip $(CFLAGS))" ""
    	@echo $(DL)$(CFLAGS)$(DL)>> $@
    endif
    ifneq "$(strip $(XCFLAGS))" ""
    	@echo $(DL)$(XCFLAGS)$(DL)>> $@
    endif
    ifneq "$(strip $(XINCDIRS))" ""
    	@echo $(DL)$(foreach xincdir,$(strip $(subst ;,$(SPACE),$(XINCDIRS))),-I$(xincdir))$(DL)>> $@
    endif
    ifneq "$(strip $(INCDIRS))" ""
    	@echo $(DL)$(foreach incdir,$(strip $(subst ;,$(SPACE),$(INCDIRS))),-I$(incdir))$(DL)>> $@
    endif
    ifneq "$(strip $(DEFINES))" ""
    	@echo $(DL)$(DEFINES)$(DL)>> $@
    endif
    ifneq "$(strip $(XDEFINES))" ""
    	@echo $(DL)$(XDEFINES)$(DL)>> $@
    endif
    
    $(OBJDIR)/%.o: %.cpp $(OBJDIR)/$(NLM_NAME)_cpp.opt
    	@echo $(DL)CC   $<$(DL)
    	$(CC) -o $@ $< @$(word 2, $^)
    
    $(OBJDIR)/$(NLM_NAME)_cpp.opt: $(CPPOPT_DEPENDS)
    	$(call DEL,$@)
    	@echo $(DL)GEN  $@$(DL)
    ifneq "$(strip $(CFLAGS))" ""
    	@echo $(DL)$(CFLAGS)$(DL)>> $@
    endif
    ifneq "$(strip $(XCFLAGS))" ""
    	@echo $(DL)$(XCFLAGS)$(DL)>> $@
    endif
    ifneq "$(strip $(XINCDIRS))" ""
    	@echo $(DL)$(foreach xincdir,$(strip $(subst ;,$(SPACE),$(XINCDIRS))),-I$(xincdir))$(DL)>> $@
    endif
    ifneq "$(strip $(INCDIRS))" ""
    	@echo $(DL)$(foreach incdir,$(strip $(subst ;,$(SPACE),$(INCDIRS))),-I$(incdir))$(DL)>> $@
    endif
    ifneq "$(strip $(DEFINES))" ""
    	@echo $(DL)$(DEFINES)$(DL)>> $@
    endif
    ifneq "$(strip $(XDEFINES))" ""
    	@echo $(DL)$(XDEFINES)$(DL)>> $@
    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
    	$(call DEL,$@)
    	@echo $(DL)AR   $@$(DL)
    	$(LIB) -o $@ @$<
    
    $(OBJDIR)/$(LIB_NAME)_lib.lst: $($(LIB_NAME)_LIBLST_DEPENDS)
    	$(call DEL,$@)
    ifneq "$(strip $(FILES_lib_objs))" ""
    	@echo $(DL)GEN  $@$(DL)
    	@echo $(DL)$(FILES_lib_objs)$(DL)>> $@
    endif
    
    else # We must have more than one target library so load the individual makefiles
    
    $(OBJDIR)/%.lib: NWGNU% $(STANDARD_DEPENDS) FORCE
    	@echo $(DL)Calling $<$(DL)
    	$(MAKE) -f $< $(MAKECMDGOALS) RELEASE=$(RELEASE)
    
    endif
    
    #
    # Rules to build nlms.
    #
    
    # 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 $(DL)LINK $@$(DL)
    	$(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)
    	$(call DEL,$@)
    	$(call DEL,$(@:.opt=.def))
    	@echo $(DL)GEN  $@$(DL)
    	@echo $(DL)-nlmversion=$(NLM_VERSION)$(DL)>> $@
    	@echo $(DL)-warnings off$(DL)>> $@
    	@echo $(DL)-zerobss$(DL)>> $@
    	@echo $(DL)-o $(TARGET_nlm)$(DL)>> $@
    ifneq "$(FILE_nlm_copyright)" ""
    	@$(CAT) $(FILE_nlm_copyright)>> $@
    endif
    ifeq "$(RELEASE)" "debug"
    	@echo $(DL)-g$(DL)>> $@
    	@echo $(DL)-sym internal$(DL)>> $@
    	@echo $(DL)-sym codeview4$(DL)>> $@
    	@echo $(DL)-osym $(OBJDIR)/$(NLM_NAME).sym$(DL)>> $@
    else
    	@echo $(DL)-sym internal$(DL)>> $@
    endif
    	@echo $(DL)-l $(SRC)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(HTTPD)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(SERVER)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(STDMOD)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(NWOS)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(NWOS)$(DL)>> $@
    	@echo $(DL)-l $(APR)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(APR)$(DL)>> $@
    	@echo $(DL)-l $(APRUTIL)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(PCRE)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l "$(METROWERKS)/Novell Support/Metrowerks Support/Libraries/Runtime"$(DL)>> $@
    	@echo $(DL)-l "$(METROWERKS)/Novell Support/Metrowerks Support/Libraries/MSL C++"$(DL)>> $@
    ifneq "$(IPV6)" ""
    	@echo $(DL)-l $(NOVELLLIBC)/include/winsock/IPV6$(DL)>> $@
    endif
    	@echo $(DL)-l $(NOVELLLIBC)/imports$(DL)>> $@
    ifneq "$(LDAPSDK)" ""
    	@echo $(DL)-l $(LDAPSDK)/imports$(DL)>> $@
    endif
    	@echo $(DL)-l $(APULDAP)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(XML)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-l $(SRC)/$(OBJDIR)$(DL)>> $@
    	@echo $(DL)-nodefaults$(DL)>> $@
    	@echo $(DL)-map $(OBJDIR)/$(NLM_NAME).map$(DL)>> $@
    ifneq "$(strip $(XLFLAGS))" ""
    	@echo $(DL)$(XLFLAGS)$(DL)>> $@
    endif
    ifneq "$(strip $(FILES_nlm_objs))" ""
    	@echo $(DL)$(foreach objfile,$(strip $(FILES_nlm_objs)),$(objfile))$(DL)>> $@
    endif
    ifneq "$(FILES_nlm_libs)" ""
    	@echo $(DL)$(foreach libfile, $(notdir $(strip $(FILES_nlm_libs))),-l$(libfile))$(DL)>> $@
    endif
    	@echo $(DL)-commandfile $(@:.opt=.def)$(DL)>> $@
    	@echo $(DL)# Do not edit this file - it is created by make!$(DL)> $(@:.opt=.def) 
    	@echo $(DL)# All your changes will be lost!!$(DL)>> $(@:.opt=.def) 
    ifneq "$(FILE_nlm_msg)" ""
    	@echo $(DL)Messages $(FILE_nlm_msg)$(DL)>> $(@:.opt=.def)
    endif
    ifneq "$(FILE_nlm_hlp)" ""
    	@echo $(DL)Help $(FILE_nlm_hlp)$(DL)>> $(@:.opt=.def)
    endif
    ifeq "$(FILE_nlm_copyright)" ""
    	@echo $(DL)copyright "$(NLM_COPYRIGHT)"$(DL)>> $(@:.opt=.def)
    endif
    	@echo $(DL)description "$(NLM_DESCRIPTION)"$(DL)>> $(@:.opt=.def)
    	@echo $(DL)threadname "$(NLM_THREAD_NAME)"$(DL)>> $(@:.opt=.def)
    	@echo $(DL)screenname "$(NLM_SCREEN_NAME)"$(DL)>> $(@:.opt=.def)
    	@echo $(DL)stacksize $(subst K,000,$(subst k,K,$(strip $(NLM_STACK_SIZE))))$(DL)>> $(@:.opt=.def)
    #	@echo $(DL)version $(NLM_VERSION) $(DL)>> $(@:.opt=.def)
    	@echo $(DL)start $(NLM_ENTRY_SYM)$(DL)>> $(@:.opt=.def)
    	@echo $(DL)exit $(NLM_EXIT_SYM)$(DL)>> $(@:.opt=.def)
    ifneq "$(NLM_CHECK_SYM)" ""
    	@echo $(DL)check $(NLM_CHECK_SYM)$(DL)>> $(@:.opt=.def)
    endif
    	@echo $(DL)$(strip $(NLM_FLAGS))$(DL)>> $(@:.opt=.def)
    ifneq "$(FILES_nlm_modules)" ""
    	@echo $(DL)module $(foreach module,$(subst $(SPACE),$(COMMA),$(strip $(FILES_nlm_modules))),$(module))$(DL)>> $(@:.opt=.def)
    endif
    ifneq "$(FILES_nlm_Ximports)" ""
    	@echo $(DL)import $(foreach import,$(subst $(SPACE),$(COMMA),$(strip $(FILES_nlm_Ximports))),$(import))$(DL)>> $(@:.opt=.def)
    endif
    ifneq "$(FILES_nlm_exports)" ""
    	@echo $(DL)export $(foreach export,$(subst $(SPACE),$(COMMA),$(strip $(FILES_nlm_exports))),$(export))$(DL)>> $(@:.opt=.def)
    endif
    # if APACHE_UNIPROC is defined, don't include XDCData
    ifndef APACHE_UNIPROC
    ifneq "$(string $(XDCDATA))" ""
    	@echo $(DL)xdcdata $(XDCDATA)$(DL)>> $(@:.opt=.def)
    else
    	@echo $(DL)xdcdata apache.xdc$(DL)>> $(@:.opt=.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% $($(NLM_NAME)_LINKOPT_DEPENDS) FORCE
    	@echo $(DL)Calling $<$(DL)
    	$(MAKE) -f $< $(MAKECMDGOALS) RELEASE=$(RELEASE)
    	@$(ECHONL)
    
    else
    
    $(TARGET_nlm):
    
    endif # NO_LICENSE_FILE
    
    endif
    
    ���������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/cpR_noreplace.pl�����������������������������������������������������������������0000664�0001751�0001751�00000004171�12241162036�017032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl -w
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 File::Basename;
    use File::Copy;
    use File::Find;
    use File::Path qw(mkpath);
    
    require 5.010;
    
    my $srcdir;
    my $destdir;
    
    sub process_file {
        return if $_ =~ /^\./;
    
        my $rel_to_srcdir = substr($File::Find::name, length($srcdir));
        my $destfile = "$destdir$rel_to_srcdir";
    
        if (-d $File::Find::name) {
            # If the directory is empty, it won't get created.
            # Otherwise it will get created when copying a file.
        }
        else {
            if (-f $destfile) {
                # Preserve it.
            }
            else {
                # Create it.
                my $dir = dirname($destfile);
                if (! -e $dir) {
                    mkpath($dir) or die "Failed to create directory $dir: $!";
                }
                copy($File::Find::name, $destfile) or die "Copy $File::Find::name->$destfile failed: $!";
            }
        }
    }
    
    $srcdir = shift;
    $destdir = shift;
    if (scalar(@ARGV) > 0) {
        my $mode = shift;
        if ($mode eq "ifdestmissing") {
            # Normally the check for possible overwrite is performed on a
            # file-by-file basis.  If "ifdestmissing" is specified and the
            # destination directory exists, bail out.
            if (-d $destdir) {
                print "[PRESERVING EXISTING SUBDIR $destdir]\n";
                exit(0);
            }
        }
        else {
            die "bad mode $mode";
        }
    }
    find(\&process_file, ($srcdir));
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/find_apu.m4����������������������������������������������������������������������0000664�0001751�0001751�00000017765�15032766624�016003� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl -------------------------------------------------------- -*- autoconf -*-
    dnl Licensed to the Apache Software Foundation (ASF) under one or more
    dnl contributor license agreements.  See the NOTICE file distributed with
    dnl this work for additional information regarding copyright ownership.
    dnl The ASF licenses this file to You under the Apache License, Version 2.0
    dnl (the "License"); you may not use this file except in compliance with
    dnl the License.  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.
    
    dnl
    dnl find_apu.m4 : locate the APR-util (APU) include files and libraries
    dnl
    dnl This macro file can be used by applications to find and use the APU
    dnl library. It provides a standardized mechanism for using APU. It supports
    dnl embedding APU into the application source, or locating an installed
    dnl copy of APU.
    dnl
    dnl APR_FIND_APU(srcdir, builddir, implicit-install-check, acceptable-majors,
    dnl              detailed-check)
    dnl
    dnl   where srcdir is the location of the bundled APU source directory, or
    dnl   empty if source is not bundled.
    dnl
    dnl   where builddir is the location where the bundled APU will be built,
    dnl   or empty if the build will occur in the srcdir.
    dnl
    dnl   where implicit-install-check set to 1 indicates if there is no
    dnl   --with-apr-util option specified, we will look for installed copies.
    dnl
    dnl   where acceptable-majors is a space separated list of acceptable major
    dnl   version numbers. Often only a single major version will be acceptable.
    dnl   If multiple versions are specified, and --with-apr-util=PREFIX or the
    dnl   implicit installed search are used, then the first (leftmost) version
    dnl   in the list that is found will be used.  Currently defaults to [0 1].
    dnl
    dnl   where detailed-check is an M4 macro which sets the apu_acceptable to
    dnl   either "yes" or "no". The macro will be invoked for each installed
    dnl   copy of APU found, with the apu_config variable set appropriately.
    dnl   Only installed copies of APU which are considered acceptable by
    dnl   this macro will be considered found. If no installed copies are
    dnl   considered acceptable by this macro, apu_found will be set to either
    dnl   either "no" or "reconfig".
    dnl
    dnl Sets the following variables on exit:
    dnl
    dnl   apu_found : "yes", "no", "reconfig"
    dnl
    dnl   apu_config : If the apu-config tool exists, this refers to it.  If
    dnl                apu_found is "reconfig", then the bundled directory
    dnl                should be reconfigured *before* using apu_config.
    dnl
    dnl Note: this macro file assumes that apr-config has been installed; it
    dnl       is normally considered a required part of an APR installation.
    dnl
    dnl Note: At this time, we cannot find *both* a source dir and a build dir.
    dnl       If both are available, the build directory should be passed to
    dnl       the --with-apr-util switch.
    dnl
    dnl Note: the installation layout is presumed to follow the standard
    dnl       PREFIX/lib and PREFIX/include pattern. If the APU config file
    dnl       is available (and can be found), then non-standard layouts are
    dnl       possible, since it will be described in the config file.
    dnl
    dnl If a bundled source directory is available and needs to be (re)configured,
    dnl then apu_found is set to "reconfig". The caller should reconfigure the
    dnl (passed-in) source directory, placing the result in the build directory,
    dnl as appropriate.
    dnl
    dnl If apu_found is "yes" or "reconfig", then the caller should use the
    dnl value of apu_config to fetch any necessary build/link information.
    dnl
    
    AC_DEFUN([APR_FIND_APU], [
      apu_found="no"
    
      if test "$target_os" = "os2-emx"; then
        # Scripts don't pass test -x on OS/2
        TEST_X="test -f"
      else
        TEST_X="test -x"
      fi
    
      ifelse([$4], [],
      [
        ifdef(AC_WARNING,([$0: missing argument 4 (acceptable-majors): Defaulting to APU 0.x then APU 1.x]))
        acceptable_majors="0 1"
      ], [acceptable_majors="$4"])
    
      apu_temp_acceptable_apu_config=""
      for apu_temp_major in $acceptable_majors
      do
        case $apu_temp_major in
          0)
          apu_temp_acceptable_apu_config="$apu_temp_acceptable_apu_config apu-config"
          ;;
          *)
          apu_temp_acceptable_apu_config="$apu_temp_acceptable_apu_config apu-$apu_temp_major-config"
          ;;
        esac
      done
    
      AC_MSG_CHECKING(for APR-util)
      AC_ARG_WITH(apr-util,
      [  --with-apr-util=PATH    prefix for installed APU or the full path to 
                                 apu-config],
      [
        if test "$withval" = "no" || test "$withval" = "yes"; then
          AC_MSG_ERROR([--with-apr-util requires a directory or file to be provided])
        fi
    
        for apu_temp_apu_config_file in $apu_temp_acceptable_apu_config
        do
          for lookdir in "$withval/bin" "$withval"
          do
            if $TEST_X "$lookdir/$apu_temp_apu_config_file"; then
              apu_config="$lookdir/$apu_temp_apu_config_file"
              ifelse([$5], [], [], [
              apu_acceptable="yes"
              $5
              if test "$apu_acceptable" != "yes"; then
                AC_MSG_WARN([Found APU in $apu_config, but it is considered unacceptable])
                continue
              fi])
              apu_found="yes"
              break 2
            fi
          done
        done
    
        if test "$apu_found" != "yes" && $TEST_X "$withval" && $withval --help > /dev/null 2>&1 ; then
          apu_config="$withval"
          ifelse([$5], [], [apu_found="yes"], [
              apu_acceptable="yes"
              $5
              if test "$apu_acceptable" = "yes"; then
                    apu_found="yes"
              fi])
        fi
    
        dnl if --with-apr-util is used, it is a fatal error for its argument
        dnl to be invalid
        if test "$apu_found" != "yes"; then
          AC_MSG_ERROR([the --with-apr-util parameter is incorrect. It must specify an install prefix, a build directory, or an apu-config file.])
        fi
      ],[
        if test -n "$3" && test "$3" = "1"; then
          for apu_temp_apu_config_file in $apu_temp_acceptable_apu_config
          do
            if $apu_temp_apu_config_file --help > /dev/null 2>&1 ; then
              apu_config="$apu_temp_apu_config_file" 
              ifelse([$5], [], [], [
              apu_acceptable="yes"
              $5
              if test "$apu_acceptable" != "yes"; then
                AC_MSG_WARN([skipped APR-util at $apu_config, version not acceptable])
                continue
              fi])
              apu_found="yes"
              break
            else
              dnl look in some standard places (apparently not in builtin/default)
              for lookdir in /usr /usr/local /usr/local/apr /opt/apr; do
                if $TEST_X "$lookdir/bin/$apu_temp_apu_config_file"; then
                  apu_config="$lookdir/bin/$apu_temp_apu_config_file"
                  ifelse([$5], [], [], [
                  apu_acceptable="yes"
                  $5
                  if test "$apu_acceptable" != "yes"; then
                    AC_MSG_WARN([skipped APR-util at $apu_config, version not acceptable])
                    continue
                  fi])
                  apu_found="yes"
                  break 2
                fi
              done
            fi
          done
        fi
        dnl if we have not found anything yet and have bundled source, use that
        if test "$apu_found" = "no" && test -d "$1"; then
          apu_temp_abs_srcdir="`cd \"$1\" && pwd`"
          apu_found="reconfig"
          apu_bundled_major="`sed -n '/#define.*APU_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \"$1/include/apu_version.h\"`"
          case $apu_bundled_major in
            "")
              AC_MSG_ERROR([failed to find major version of bundled APU])
            ;;
            0)
              apu_temp_apu_config_file="apu-config"
            ;;
            *)
              apu_temp_apu_config_file="apu-$apu_bundled_major-config"
            ;;
          esac
          if test -n "$2"; then
            apu_config="$2/$apu_temp_apu_config_file"
          else
            apu_config="$1/$apu_temp_apu_config_file"
          fi
        fi
      ])
    
      AC_MSG_RESULT($apu_found)
    ])
    �����������httpd-2.4.64/build/installwinconf.awk���������������������������������������������������������������0000664�0001751�0001751�00000036264�13446445467�017513� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # InstallConf.awk Apache HTTP 2.x script to rewrite the @@ServerRoot@@
    # tags in httpd.conf.in to original\httpd.conf - then duplicate the
    # conf files to the 'live' configuration if they don't already exist.
    #
    # Note that we -don't- want the ARGV file list, so no additional {} blocks
    # are coded.  Use explicit args (more reliable on Win32) and use the fact
    # that ARGV[] params are -not- '\' escaped to process the C:\Foo\Bar Win32
    # path format.  Note that awk var=path would not succeed, since it -does-
    # escape backslashes in the assignment.  Note also, a trailing space is
    # required for paths, or the trailing quote following the backslash is
    # escaped, rather than parsed.
    #
    BEGIN {
        domainname = ARGV[1];
        servername = ARGV[2];
        serveradmin = ARGV[3];
        serverport = ARGV[4];
        serversslport = ARGV[5];
        serverroot = ARGV[6];
        sourceroot = ARGV[7];
    
        delete ARGV[7];
        delete ARGV[6];
        delete ARGV[5];
        delete ARGV[4];
        delete ARGV[3];
        delete ARGV[2];
        delete ARGV[1];
    
        gsub( /\\/, "/", serverroot );
        gsub( /[ \/]+$/, "", serverroot );
        tstfl = serverroot "/logs/install.log"
        confroot = serverroot "/conf/";
        confdefault = confroot "original/";
    
        if ( sourceroot != "docs/conf/" ) {
            sourceroot = serverroot "/" sourceroot;
        }
    
        usertree = ENVIRON["USERPROFILE"]
        if ( usertree > "" ) {
            gsub( /\\/, "/", usertree );
            gsub( /\/[^\/]+$/, "", usertree );
        } else {
            usertree = "C:/Documents and Settings";
        }
    
        print "Installing Apache HTTP Server 2.x with" >tstfl;
        print " DomainName    = " domainname >tstfl;
        print " ServerName    = " servername >tstfl;
        print " ServerAdmin   = " serveradmin >tstfl;
        print " ServerPort    = " serverport >tstfl;
        print " ServerSslPort = " serversslport >tstfl;
        print " ServerRoot    = " serverroot >tstfl;
    
        filelist["httpd.conf"] = "httpd.conf.in";
        filelist["httpd-autoindex.conf"] = "httpd-autoindex.conf.in";
        filelist["httpd-dav.conf"] = "httpd-dav.conf.in";
        filelist["httpd-default.conf"] = "httpd-default.conf.in";
        filelist["httpd-info.conf"] = "httpd-info.conf.in";
        filelist["httpd-languages.conf"] = "httpd-languages.conf.in";
        filelist["httpd-manual.conf"] = "httpd-manual.conf.in";
        filelist["httpd-mpm.conf"] = "httpd-mpm.conf.in";
        filelist["httpd-multilang-errordoc.conf"] = "httpd-multilang-errordoc.conf.in";
        filelist["httpd-ssl.conf"] = "httpd-ssl.conf.in";
        filelist["httpd-userdir.conf"] = "httpd-userdir.conf.in";
        filelist["httpd-vhosts.conf"] = "httpd-vhosts.conf.in";
        filelist["proxy-html.conf"] = "proxy-html.conf.in";
    
        for ( conffile in filelist ) {
    
          if ( conffile == "httpd.conf" ) {
            srcfl = sourceroot filelist[conffile];
            dstfl = confdefault conffile;
            bswarning = 1;
          } else {
            srcfl = sourceroot "extra/" filelist[conffile];
            dstfl = confdefault "extra/" conffile;
            bswarning = 0;
          }
    
          while ( ( getline < srcfl ) > 0 ) {
    
            if ( bswarning && /^$/ ) {
              print "#" > dstfl;
              print "# NOTE: Where filenames are specified, you must use forward slashes" > dstfl;
              print "# instead of backslashes (e.g., \"c:/apache\" instead of \"c:\\apache\")." > dstfl;
              print "# If a drive letter is omitted, the drive on which httpd.exe is located" > dstfl;
              print "# will be used by default.  It is recommended that you always supply" > dstfl;
              print "# an explicit drive letter in absolute paths to avoid confusion." > dstfl;
              bswarning = 0;
            }
            if ( /@@LoadModule@@/ ) {
              print "LoadModule access_compat_module modules/mod_access_compat.so" > dstfl;
              print "LoadModule actions_module modules/mod_actions.so" > dstfl;
              print "LoadModule alias_module modules/mod_alias.so" > dstfl;
              print "LoadModule allowmethods_module modules/mod_allowmethods.so" > dstfl;
              print "LoadModule asis_module modules/mod_asis.so" > dstfl;
              print "LoadModule auth_basic_module modules/mod_auth_basic.so" > dstfl;
              print "#LoadModule auth_digest_module modules/mod_auth_digest.so" > dstfl;
              print "#LoadModule auth_form_module modules/mod_auth_form.so" > dstfl;
              print "#LoadModule authn_anon_module modules/mod_authn_anon.so" > dstfl;
              print "LoadModule authn_core_module modules/mod_authn_core.so" > dstfl;
              print "#LoadModule authn_dbd_module modules/mod_authn_dbd.so" > dstfl;
              print "#LoadModule authn_dbm_module modules/mod_authn_dbm.so" > dstfl;
              print "LoadModule authn_file_module modules/mod_authn_file.so" > dstfl;
              print "#LoadModule authn_socache_module modules/mod_authn_socache.so" > dstfl;
              print "#LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so" > dstfl;
              print "#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so" > dstfl;
              print "LoadModule authz_core_module modules/mod_authz_core.so" > dstfl;
              print "#LoadModule authz_dbd_module modules/mod_authz_dbd.so" > dstfl;
              print "#LoadModule authz_dbm_module modules/mod_authz_dbm.so" > dstfl;
              print "LoadModule authz_groupfile_module modules/mod_authz_groupfile.so" > dstfl;
              print "LoadModule authz_host_module modules/mod_authz_host.so" > dstfl;
              print "#LoadModule authz_owner_module modules/mod_authz_owner.so" > dstfl;
              print "LoadModule authz_user_module modules/mod_authz_user.so" > dstfl;
              print "LoadModule autoindex_module modules/mod_autoindex.so" > dstfl;
              print "#LoadModule brotli_module modules/mod_brotli.so" > dstfl;
              print "#LoadModule buffer_module modules/mod_buffer.so" > dstfl;
              print "#LoadModule cache_module modules/mod_cache.so" > dstfl;
              print "#LoadModule cache_disk_module modules/mod_cache_disk.so" > dstfl;
              print "#LoadModule cache_socache_module modules/mod_cache_socache.so" > dstfl;
              print "#LoadModule cern_meta_module modules/mod_cern_meta.so" > dstfl;
              print "LoadModule cgi_module modules/mod_cgi.so" > dstfl;
              print "#LoadModule charset_lite_module modules/mod_charset_lite.so" > dstfl;
              print "#LoadModule data_module modules/mod_data.so" > dstfl;
              print "#LoadModule dav_module modules/mod_dav.so" > dstfl;
              print "#LoadModule dav_fs_module modules/mod_dav_fs.so" > dstfl;
              print "#LoadModule dav_lock_module modules/mod_dav_lock.so" > dstfl;
              print "#LoadModule dbd_module modules/mod_dbd.so" > dstfl;
              print "#LoadModule deflate_module modules/mod_deflate.so" > dstfl;
              print "LoadModule dir_module modules/mod_dir.so" > dstfl;
              print "#LoadModule dumpio_module modules/mod_dumpio.so" > dstfl;
              print "LoadModule env_module modules/mod_env.so" > dstfl;
              print "#LoadModule expires_module modules/mod_expires.so" > dstfl;
              print "#LoadModule ext_filter_module modules/mod_ext_filter.so" > dstfl;
              print "#LoadModule file_cache_module modules/mod_file_cache.so" > dstfl;
              print "#LoadModule filter_module modules/mod_filter.so" > dstfl;
              print "#LoadModule http2_module modules/mod_http2.so" > dstfl;
              print "#LoadModule headers_module modules/mod_headers.so" > dstfl;
              print "#LoadModule heartbeat_module modules/mod_heartbeat.so" > dstfl;
              print "#LoadModule heartmonitor_module modules/mod_heartmonitor.so" > dstfl;
              print "#LoadModule ident_module modules/mod_ident.so" > dstfl;
              print "#LoadModule imagemap_module modules/mod_imagemap.so" > dstfl;
              print "LoadModule include_module modules/mod_include.so" > dstfl;
              print "#LoadModule info_module modules/mod_info.so" > dstfl;
              print "LoadModule isapi_module modules/mod_isapi.so" > dstfl;
              print "#LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so" > dstfl;
              print "#LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so" > dstfl;
              print "#LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so" > dstfl;
              print "#LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so" > dstfl;
              print "#LoadModule ldap_module modules/mod_ldap.so" > dstfl;
              print "#LoadModule logio_module modules/mod_logio.so" > dstfl;
              print "LoadModule log_config_module modules/mod_log_config.so" > dstfl;
              print "#LoadModule log_debug_module modules/mod_log_debug.so" > dstfl;
              print "#LoadModule log_forensic_module modules/mod_log_forensic.so" > dstfl;
              print "#LoadModule lua_module modules/mod_lua.so" > dstfl;
              print "#LoadModule macro_module modules/mod_macro.so" > dstfl;
              print "#LoadModule md_module modules/mod_md.so" > dstfl;
              print "LoadModule mime_module modules/mod_mime.so" > dstfl;
              print "#LoadModule mime_magic_module modules/mod_mime_magic.so" > dstfl;
              print "LoadModule negotiation_module modules/mod_negotiation.so" > dstfl;
              print "#LoadModule proxy_module modules/mod_proxy.so" > dstfl;
              print "#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so" > dstfl;
              print "#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so" > dstfl;
              print "#LoadModule proxy_connect_module modules/mod_proxy_connect.so" > dstfl;
              print "#LoadModule proxy_express_module modules/mod_proxy_express.so" > dstfl;
              print "#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so" > dstfl;
              print "#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so" > dstfl;
              print "#LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so" > dstfl;
              print "#LoadModule proxy_html_module modules/mod_proxy_html.so" > dstfl;
              print "#LoadModule proxy_http_module modules/mod_proxy_http.so" > dstfl;
              print "#LoadModule proxy_http2_module modules/mod_proxy_http2.so" > dstfl;
              print "#LoadModule proxy_scgi_module modules/mod_proxy_scgi.so" > dstfl;
              print "#LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so" > dstfl;
              print "#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so" > dstfl;
              print "#LoadModule ratelimit_module modules/mod_ratelimit.so" > dstfl;
              print "#LoadModule reflector_module modules/mod_reflector.so" > dstfl;
              print "#LoadModule remoteip_module modules/mod_remoteip.so" > dstfl;
              print "#LoadModule request_module modules/mod_request.so" > dstfl;
              print "#LoadModule reqtimeout_module modules/mod_reqtimeout.so" > dstfl;
              print "#LoadModule rewrite_module modules/mod_rewrite.so" > dstfl;
              print "#LoadModule sed_module modules/mod_sed.so" > dstfl;
              print "#LoadModule session_module modules/mod_session.so" > dstfl;
              print "#LoadModule session_cookie_module modules/mod_session_cookie.so" > dstfl;
              print "#LoadModule session_crypto_module modules/mod_session_crypto.so" > dstfl;
              print "#LoadModule session_dbd_module modules/mod_session_dbd.so" > dstfl;
              print "LoadModule setenvif_module modules/mod_setenvif.so" > dstfl;
              print "#LoadModule slotmem_plain_module modules/mod_slotmem_plain.so" > dstfl;
              print "#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so" > dstfl;
              print "#LoadModule socache_dbm_module modules/mod_socache_dbm.so" > dstfl;
              print "#LoadModule socache_memcache_module modules/mod_socache_memcache.so" > dstfl;
              print "#LoadModule socache_redis_module modules/mod_socache_redis.so" > dstfl;
              print "#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so" > dstfl;
              print "#LoadModule speling_module modules/mod_speling.so" > dstfl;
              print "#LoadModule ssl_module modules/mod_ssl.so" > dstfl;
              print "#LoadModule status_module modules/mod_status.so" > dstfl;
              print "#LoadModule substitute_module modules/mod_substitute.so" > dstfl;
              print "#LoadModule unique_id_module modules/mod_unique_id.so" > dstfl;
              print "#LoadModule userdir_module modules/mod_userdir.so" > dstfl;
              print "#LoadModule usertrack_module modules/mod_usertrack.so" > dstfl;
              print "#LoadModule version_module modules/mod_version.so" > dstfl;
              print "#LoadModule vhost_alias_module modules/mod_vhost_alias.so" > dstfl;
              print "#LoadModule watchdog_module modules/mod_watchdog.so" > dstfl;
              print "#LoadModule xml2enc_module modules/mod_xml2enc.so" > dstfl;
              continue;
            }
            if ( /^ServerRoot / ) {
              print "Define SRVROOT \"" serverroot "\"" > dstfl;
              print "" > dstfl;
            }
            gsub( /@@ServerRoot@@/,   "\${SRVROOT}" );
            gsub( /@exp_cgidir@/,     "\${SRVROOT}" "/cgi-bin" );
            gsub( /@exp_sysconfdir@/, "\${SRVROOT}" "/conf" );
            gsub( /@exp_errordir@/,   "\${SRVROOT}" "/error" );
            gsub( /@exp_htdocsdir@/,  "\${SRVROOT}" "/htdocs" );
            gsub( /@exp_iconsdir@/,   "\${SRVROOT}" "/icons" );
            gsub( /@exp_manualdir@/,  "\${SRVROOT}" "/manual" );
            gsub( /@exp_runtimedir@/, "\${SRVROOT}" "/logs" );
            if ( gsub( /@exp_logfiledir@/, "\${SRVROOT}" "/logs" ) ||
                 gsub( /@rel_logfiledir@/, "logs" ) ) {
              gsub( /_log"/, ".log\"" )
            }
            gsub( /@rel_runtimedir@/, "logs" );
            gsub( /@rel_sysconfdir@/, "conf" );
            gsub( /\/home\/\*\/public_html/, \
                  usertree "/*/My Documents/My Website" );
            gsub( /UserDir public_html/, "UserDir \"My Documents/My Website\"" );
            gsub( /@@ServerName@@|www.example.com/,  servername );
            gsub( /@@ServerAdmin@@|you@example.com/, serveradmin );
            gsub( /@@DomainName@@|example.com/,      domainname );
            gsub( /@@Port@@/,                        serverport );
            gsub( /@@SSLPort@@|443/,                 serversslport );
            print $0 > dstfl;
          }
          close(srcfl);
    
          if ( close(dstfl) >= 0 ) {
            print "Rewrote " srcfl "\n to " dstfl > tstfl;
            if ( sourceroot != "docs/conf/" ) {
              gsub(/\//, "\\", srcfl);
              if (system("del 2>NUL \"" srcfl "\"")) {
                print "Failed to remove " srcfl > tstfl;
              } else {
                print "Successfully removed " srcfl > tstfl;
              }
            }
          } else {
            print "Failed to rewrite " srcfl "\n to " dstfl > tstfl;
          }
          filelist[conffile] = "extra/";
        }
    
        filelist["httpd.conf"] = "";
        filelist["charset.conv"] = "";
        filelist["magic"] = "";
        filelist["mime.types"] = "";
    
        for ( conffile in filelist ) {
          srcfl = confdefault filelist[conffile] conffile;
          dstfl = confroot filelist[conffile] conffile;
          if ( ( getline < dstfl ) < 0 ) {
            while ( ( getline < srcfl ) > 0 ) {
              print $0 > dstfl;
            }
            print "Duplicated " srcfl "\n to " dstfl > tstfl;
          } else {
            print "Existing file " dstfl " preserved" > tstfl;
          }
          close(srcfl);
          close(dstfl);
        }
    
        if ( sourceroot != "docs/conf/" ) {
          srcfl = confdefault "installwinconf.awk";
          gsub(/\//, "\\", srcfl);
          if (system("del 2>NUL \"" srcfl "\"")) {
            print "Failed to remove " srcfl > tstfl;
          } else {
            print "Successfully removed " srcfl > tstfl;
          }
        }
        close(tstfl);
    }
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/config-stubs���������������������������������������������������������������������0000775�0001751�0001751�00000001265�12262534731�016263� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/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 os server modules support -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
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/NWGNUenvironment.inc�������������������������������������������������������������0000664�0001751�0001751�00000020477�12602235527�017615� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    ifneq "$(wildcard $(NOVELLLIBC)/include/ndkvers.h)" "$(NOVELLLIBC)/include/ndkvers.h"
    $(error NOVELLLIBC does not point to a valid Novell LIBC SDK) 
    endif
    
    ifndef LDAPSDK
    LDAPSDK = C:/novell/ndk/cldapsdk/NetWare/libc
    endif
    ifneq "$(wildcard $(LDAPSDK)/inc/ldap.h)" "$(LDAPSDK)/inc/ldap.h"
    $(error LDAPSDK does not point to a valid Novell CLDAP SDK) 
    endif
    
    ifdef WITH_HTTP2
    ifneq "$(wildcard $(NGH2SRC)/lib/nghttp2_hd.h)" "$(NGH2SRC)/lib/nghttp2_hd.h"
    $(error NGH2SRC does not point to a valid NGHTTP2 source tree)
    endif
    endif
    
    ifndef PCRESRC
    PCRESRC = $(AP_WORK)/srclib/pcre
    endif
    ifneq "$(wildcard $(PCRESRC)/pcre-config.in)" "$(PCRESRC)/pcre-config.in"
    $(error PCRESRC does not point to a valid PCRE source tree) 
    endif
    
    # This is a placeholder
    # ifndef ZLIBSDK
    # ZLIBSDK = C:/novell/ndk/zlibsdk
    # endif
    
    ifndef METROWERKS
    METROWERKS = $(ProgramFiles)\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
    #  release	- optimization switches are set (default)
    
    ifdef reltype
    RELEASE = $(reltype)
    endif    
    
    ifdef RELTYPE
    RELEASE = $(RELTYPE)
    endif
    
    ifdef debug
    RELEASE = debug
    endif
    
    ifdef DEBUG
    RELEASE = debug
    endif
    
    ifdef noopt
    RELEASE = noopt
    endif
    
    ifdef NOOPT
    RELEASE = noopt
    endif
    
    ifdef optimized
    RELEASE = release
    endif
    
    ifdef OPTIMIZED
    RELEASE = release
    endif
    
    ifndef RELEASE
    RELEASE = release
    endif
    
    OBJDIR = obj_$(RELEASE)
    
    # Define minimum APR version to check for
    APR_WANTED = 1004000
    
    #
    # Setup compiler information
    #
    
    # MetroWerks NLM tools
    CC	= mwccnlm
    CPP	= mwccnlm
    LINK	= mwldnlm
    LIB	= mwldnlm -type library -w nocmdline
    WIN_CC	= mwcc
    
    # Setup build tools
    AWK	= awk
    
    # Setup distribution tools
    ZIP	= zip -qr9
    7ZA	= 7za >NUL a
    
    #
    # Declare Command and tool macros here
    #
    
    ifeq ($(findstring /sh,$(SHELL)),/sh)
    DEL	= rm -f $1
    RMDIR	= rm -fr $1
    MKDIR	= mkdir -p $1
    COPY	= -cp -afv $1 $2
    #COPYR	= -cp -afr $1/* $2
    COPYR	= -rsync -aC $1/* $2
    TOUCH	= -touch $1
    ECHONL	= echo ""
    DL	= '
    CAT	= cat
    else
    ifeq "$(OS)" "Windows_NT"
    DEL	= $(shell if exist $(subst /,\,$1) del /q /f 2>NUL $(subst /,\,$1))
    RMDIR	= $(shell if exist $(subst /,\,$1)\NUL rd /q /s 2>NUL $(subst /,\,$1))
    else
    DEL	= $(shell if exist $(subst /,\,$1) del 2>NUL $(subst /,\,$1))
    RMDIR	= $(shell if exist $(subst /,\,$1)\NUL deltree /y 2>NUL $(subst /,\,$1))
    endif
    ECHONL	= $(ComSpec) /c echo.
    MKDIR	= $(shell if not exist $(subst /,\,$1)\NUL md 2>NUL $(subst /,\,$1))
    COPY	= -copy /y 2>NUL $(subst /,\,$1) $(subst /,\,$2)
    COPYR	= -xcopy /q /y /e 2>NUL $(subst /,\,$1) $(subst /,\,$2)
    TOUCH	= -copy /b 2>&1>NUL $(subst /,\,$1) +,,
    CAT	= type
    endif
    
    ifdef IPV6
    ifndef USE_STDSOCKETS
    USE_STDSOCKETS=1
    endif
    endif
    
    NOVI	= $(NOVELLLIBC)/imports
    PRELUDE	= $(NOVI)/libcpre.o
    
    INCDIRS	= $(NOVELLLIBC)/include;
    ifndef USE_STDSOCKETS
    INCDIRS	+= $(NOVELLLIBC)/include/winsock;
    endif
    ifneq "$(LDAPSDK)" ""
    INCDIRS += $(LDAPSDK)/inc;
    endif
    ifneq "$(ZLIBSDK)" ""
    INCDIRS += $(ZLIBSDK);
    endif
    ifneq "$(PCRESRC)" ""
    INCDIRS += $(PCRESRC);
    endif
    
    DEFINES	= -DNETWARE 
    ifndef USE_STDSOCKETS
    DEFINES	+= -DUSE_WINSOCK
    endif
    ifndef DEBUG
    DEFINES	+= -DNDEBUG
    endif
    
    ifdef USE_STDSOCKETS
    VERSION_SKT = (BSDSOCK)
    else
    VERSION_SKT = (WINSOCK)
    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
    
    ifeq "$(OS)" "Windows_NT"
    # MetroWerks Win32 build flags to create build tools
    MWCW_MSL         = "$(METROWERKS)/MSL"
    MWCW_W32         = "$(METROWERKS)/Win32-x86 Support"
    CC_FOR_BUILD     = $(WIN_CC)
    CFLAGS_FOR_BUILD =  -O2 -gccinc -nodefaults -proc 586 -w off
    CFLAGS_FOR_BUILD += -ir $(MWCW_MSL) -ir $(MWCW_W32) -lr $(MWCW_MSL) -lr $(MWCW_W32)
    CFLAGS_FOR_BUILD += -lMSL_All_x86.lib -lkernel32.lib -luser32.lib
    else
    # GNUC build flags to create build tools
    CC_FOR_BUILD     = gcc
    CFLAGS_FOR_BUILD = -Wall -O2
    endif
    
    # Base compile flags
    # and prefix or precompiled header added here.
    
    # The default flags are as follows:
    #
    # -c                    compile only, no link
    # -gccinc               search directory of referencing file first for #includes
    # -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 -w nocmdline -gccinc -Cpp_exceptions off -RTTI off -align 4 -proc PII
    
    ifdef CC_MAX_ERRORS
    CFLAGS += -maxerrors $(CC_MAX_ERRORS)
    else
    CFLAGS += -maxerrors 1
    endif
    
    ifeq "$(REQUIRE_PROTOTYPES)" "1"
    CFLAGS += -r
    endif
    
    # -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)" "release"
    CFLAGS += -O4,p
    endif
    
    # -prefix pre_nw.h      #include pre_nw.h for all files
    CFLAGS += -prefix pre_nw.h
    
    
    ifneq ($(findstring /sh,$(SHELL)),/sh)
    PATH:=$(PATH);$(METROWERKS)\bin;$(METROWERKS)\Other Metrowerks Tools\Command Line Tools
    endif
    
    #
    # Declare major project deliverables output directories here
    #
    
    ifndef PORT
    PORT = 80
    endif
    
    ifndef SSLPORT
    SSLPORT = 443
    endif
    
    ifdef DEST
    INSTALL = $(subst \,/,$(DEST))
    ifeq (/, $(findstring /,$(INSTALL)))
    INSTDIRS = $(INSTALL)
    endif
    endif
    
    ifdef dest
    INSTALL = $(subst \,/,$(dest))
    ifeq (/, $(findstring /,$(INSTALL)))
    INSTDIRS = $(INSTALL)
    endif
    endif
    
    ifndef INSTALL
    INSTALL = $(AP_WORK)/Dist
    INSTDIRS = $(INSTALL)
    endif
    
    ifeq ($(MAKECMDGOALS),installdev)
    ifndef BASEDIR
    export BASEDIR = apache_$(VERSION_STR)-sdk
    endif
    else
    ifndef BASEDIR
    export BASEDIR = Apache$(VERSION_MAJMIN)
    endif
    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
    
    INSTALLBASE = $(INSTALL)/$(BASEDIR)
    
    INSTDEVDIRS = \
    	$(INSTALL) \
    	$(INSTALLBASE) \
    	$(INSTALLBASE)/build \
    	$(INSTALLBASE)/include \
    	$(INSTALLBASE)/lib \
    	$(EOLIST) 
    
    INSTDIRS += \
    	$(INSTALLBASE) \
    	$(INSTALLBASE)/bin \
    	$(INSTALLBASE)/cgi-bin \
    	$(INSTALLBASE)/conf \
    	$(INSTALLBASE)/conf/extra \
    	$(INSTALLBASE)/error \
    	$(INSTALLBASE)/htdocs \
    	$(INSTALLBASE)/icons \
    	$(INSTALLBASE)/logs \
    	$(INSTALLBASE)/man \
    	$(INSTALLBASE)/manual \
    	$(INSTALLBASE)/modules \
    	$(EOLIST) 
    
    #
    # Common directories
    #
    
    SRC		= $(subst \,/,$(AP_WORK))
    APR		= $(subst \,/,$(APR_WORK))
    APRUTIL		= $(subst \,/,$(APU_WORK))
    APBUILD		= $(SRC)/build
    STDMOD		= $(SRC)/modules
    HTTPD		= $(SRC)/modules/http
    DAV		= $(SRC)/modules/dav
    NWOS		= $(SRC)/os/netware
    SERVER		= $(SRC)/server
    SUPMOD		= $(SRC)/support
    APULDAP		= $(APRUTIL)/ldap
    XML		= $(APRUTIL)/xml
    APRTEST		= $(APR)/test
    PCRE		= $(PCRESRC)
    
    PREBUILD_INST	= $(SRC)/nwprebuild
    
    #
    # Internal Libraries
    #
    
    APRLIB		= $(APR)/$(OBJDIR)/aprlib.lib
    APRUTLIB	= $(APRUTIL)/$(OBJDIR)/aprutil.lib
    APULDAPLIB	= $(APULDAP)/$(OBJDIR)/apuldap.lib
    STMODLIB	= $(STDMOD)/$(OBJDIR)/stdmod.lib
    PCRELIB		= $(SRC)/$(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
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/NWGNUhead.inc��������������������������������������������������������������������0000664�0001751�0001751�00000005250�12143211133�016125� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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) ::
    	$(call MKDIR,$@)
    
    $(INSTDEVDIRS) ::
    	$(call MKDIR,$@)
    
    endif #NO_LICENSE_FILE check
    
    help :
    	@echo $(DL)targets for RELEASE=$(RELEASE):$(DL)
    	@echo $(DL)(default) . . . . libs nlms$(DL)
    	@echo $(DL)all . . . . . . . does everything (libs nlms install)$(DL)
    	@echo $(DL)libs. . . . . . . builds all libs$(DL)
    	@echo $(DL)nlms. . . . . . . builds all nlms$(DL)
    	@echo $(DL)install . . . . . builds libs and nlms and copies install files to$(DL)
    	@echo $(DL)                  "$(INSTALL)"$(DL)
    	@echo $(DL)installdev. . . . copies headers and files needed for development to$(DL)
    	@echo $(DL)                  "$(INSTALL)"$(DL)
    	@echo $(DL)clean . . . . . . deletes $(OBJDIR) dirs, *.err, and *.map$(DL)
    	@echo $(DL)clobber_all . . . deletes all possible output from the make$(DL)
    	@echo $(DL)clobber_install . deletes all files in $(INSTALL)$(DL)
    	@$(ECHONL)
    	@echo $(DL)Multiple targets can be used on a single nmake command line -$(DL)
    	@echo $(DL)(i.e. $(MAKE) clean all)$(DL)
    	@$(ECHONL)
    	@echo $(DL)You can also specify RELEASE=debug, RELEASE=noopt, or RELEASE=optimized$(DL)
    	@echo $(DL)The default is RELEASE=optimized$(DL)
    
    clobber_all :: clean clobber_install clobber_prebuild
    
    clobber_install ::
    	$(call RMDIR,$(INSTALL))
            
    clobber_prebuild ::
    	$(call RMDIR,$(PREBUILD_INST))
    
    #
    # build recursive targets
    #
    
    $(SUBDIRS) : FORCE
    ifneq "$(MAKECMDGOALS)" "clean"
    ifneq "$(findstring clobber_,$(MAKECMDGOALS))" "clobber_"
    	@$(ECHONL)
    	@echo $(DL)Building $(CURDIR)/$@$(DL)
    endif
    endif
    	$(MAKE) -C $@ $(MAKECMDGOALS) -f NWGNUmakefile RELEASE=$(RELEASE) DEST="$(INSTALL)" LM_LICENSE_FILE="$(LM_LICENSE_FILE)"
    	@$(ECHONL)
    
    FORCE:
    
    #
    # Standard targets
    #
    
    clean :: $(SUBDIRS)
    	@echo $(DL)Cleaning up $(CURDIR)$(DL)
    	$(call RMDIR,$(OBJDIR))
    	$(call DEL,*.err)
    	$(call DEL,*.map)
    	$(call DEL,*.tmp)
    #	$(call DEL,*.d)
    
    $(OBJDIR) ::
    	$(call MKDIR,$@)
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/mkdep.perl�����������������������������������������������������������������������0000664�0001751�0001751�00000004345�11737125415�015721� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl
    #
    # 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 (<F>)
        {
            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";
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/rules.mk.in����������������������������������������������������������������������0000664�0001751�0001751�00000017017�12030610607�016012� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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.
    # The "MOD_" prefixed variable are provided to allow modules to insert their
    # (per-subdirectory) settings through definitions in modules.mk, with highest
    # precedence.
    #
    ALL_CFLAGS   = $(MOD_CFLAGS) $(EXTRA_CFLAGS) $(NOTEST_CFLAGS) $(CFLAGS)
    ALL_CPPFLAGS = $(DEFS) $(INTERNAL_CPPFLAGS) $(MOD_CPPFLAGS) $(EXTRA_CPPFLAGS) $(NOTEST_CPPFLAGS) $(CPPFLAGS)
    ALL_CXXFLAGS = $(MOD_CXXFLAGS) $(EXTRA_CXXFLAGS) $(NOTEST_CXXFLAGS) $(CXXFLAGS)
    ALL_LDFLAGS  = $(MOD_LDFLAGS) $(EXTRA_LDFLAGS) $(NOTEST_LDFLAGS) $(LDFLAGS)
    ALL_LIBS     = $(MOD_LIBS) $(EXTRA_LIBS) $(NOTEST_LIBS) $(LIBS)
    ALL_INCLUDES = $(MOD_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
    
    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; \
    		sed 's/\.lo:/.slo:/' < .deps > .deps.$$; \
    		cat .deps.$$ >> .deps; \
    		rm -f .deps.$$; \
    	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 '$(bin_PROGRAMS)'; then \
    	    test -d $(DESTDIR)$(bindir) || $(MKINSTALLDIRS) $(DESTDIR)$(bindir); \
    	    list='$(bin_PROGRAMS)'; for i in $$list; do \
    	        $(INSTALL_PROGRAM) $$i $(DESTDIR)$(bindir); \
    	    done; \
    	fi
    	@if test -n '$(sbin_PROGRAMS)'; then \
    	    test -d $(DESTDIR)$(sbindir) || $(MKINSTALLDIRS) $(DESTDIR)$(sbindir); \
    	    list='$(sbin_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 docs $(INSTALL_TARGETS)
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/make_nw_export.awk���������������������������������������������������������������0000664�0001751�0001751�00000006446�11733744063�017471� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 {
    }
    
    function add_symbol(sym_name) {
        sub(" ", "", sym_name)
        exports[++idx] = sym_name
    }
    
    # List of functions that we don't support, yet??
    #/ap_some_name/{next}
    /ap_mpm_pod_/{next}
    
    /^[ \t]*(AP|DAV|CACHE)([RU]|_CORE)?_DECLARE[^(]*[(][^)]*[)]([^ ]* )*[^(]+[(]/ {
        sub("[ \t]*(AP|DAV|CACHE)([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]*AP[RU]?_DECLARE_EXTERNAL_HOOK[^(]*[(][^)]*/ {
        split($0, args, ",")
        prefix = args[1]
        sub("^.*[(]", "", prefix)
        symbol = args[4]
        sub("^[ \t]+", "", symbol)
        sub("[ \t]+$", "", symbol)
        add_symbol(prefix "_hook_" symbol)
        add_symbol(prefix "_hook_get_" symbol)
        add_symbol(prefix "_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 .*;/ {
        gsub(/[*;\n\r]/, "")
        gsub(/\[.*\]/, "")
        add_symbol($NF)
    }
    
    
    END {
        printf("Added %d symbols to export list.\n", idx) > "/dev/stderr"
        # sort symbols with shell sort
        increment = int(idx / 2)
        while (increment > 0) {
            for (i = increment+1; i <= idx; i++) {
                j = i
                temp = exports[i]
                while ((j >= increment+1) && (exports[j-increment] > temp)) {
                    exports[j] = exports[j-increment]
                    j -= increment
                }
                exports[j] = temp
            }
            if (increment == 2)
                increment = 1
            else
                increment = int(increment*5/11)
        }
        # print the array
        printf(" (%s)\n", EXPPREFIX)
        while (x < idx - 1) {
            printf(" %s,\n", exports[++x])
        }
        printf(" %s\n", exports[++x])
    }
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/make_exports.awk�����������������������������������������������������������������0000664�0001751�0001751�00000007204�10776375527�017154� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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")
        
        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
    }
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/library.mk�����������������������������������������������������������������������0000664�0001751�0001751�00000002044�10455012627�015720� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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)
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/mkconfNW.awk���������������������������������������������������������������������0000664�0001751�0001751�00000014221�12114453434�016150� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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"] = "\${SRVROOT}"
        A["Port"] = PORT
        A["SSLPort"] = SSLPORT
        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["logfiledir"] = A["logfiledir"]
        B["sysconfdir"] = A["sysconfdir"]
        B["runtimedir"] = A["runtimedir"]
    }
    
    /^ServerRoot / {
        print "Define SRVROOT \"SYS:/" BDIR "\""
        print ""
    }
    /@@LoadModule@@/ {
        print "#LoadModule access_compat_module modules/accesscompat.nlm"
        print "#LoadModule actions_module modules/actions.nlm"
        print "#LoadModule allowmethods_module modules/allowmethods.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_dbd_module modules/authndbd.nlm"
        print "#LoadModule authn_dbm_module modules/authndbm.nlm"
        print "#LoadModule authn_file_module modules/authnfil.nlm"
        print "#LoadModule authz_dbd_module modules/authzdbd.nlm"
        print "#LoadModule authz_dbm_module modules/authzdbm.nlm"
        print "#LoadModule authz_groupfile_module modules/authzgrp.nlm"
        print "#LoadModule authz_user_module modules/authzusr.nlm"
        print "#LoadModule authnz_ldap_module modules/authnzldap.nlm"
        print "#LoadModule ldap_module modules/utilldap.nlm"
        print "#LoadModule asis_module modules/mod_asis.nlm"
        print "LoadModule autoindex_module modules/autoindex.nlm"
        print "#LoadModule buffer_module modules/modbuffer.nlm"
        print "#LoadModule cern_meta_module modules/cernmeta.nlm"
        print "LoadModule cgi_module modules/mod_cgi.nlm"
        print "#LoadModule data_module modules/mod_data.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 filter_module modules/mod_filter.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"
        if (MODSSL) {
           print "#LoadModule socache_dbm_module modules/socachedbm.nlm"
           print "#LoadModule socache_shmcb_module modules/socacheshmcb.nlm"
           print "#LoadModule ssl_module modules/mod_ssl.nlm"
        }
        print ""
        next
    }
    
    match ($0,/^#SSLSessionCache +"dbm:/) {
        sub(/^#/, "")
    }
    
    match ($0,/^SSLSessionCache +"shmcb:/) {
        sub(/^SSLSessionCache/, "#SSLSessionCache")
    }
    
    match ($0,/^# Mutex +default +file:@rel_runtimedir@/) {
        sub(/file:@rel_runtimedir@/, "default")
    }
    
    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)
    }
    
    match ($0,/^<IfModule cgid_module>$/) {
        print "#"
        print "# CGIMapExtension: Technique for locating the interpreter for CGI scripts."
        print "# The special interpreter path \"OS\" can be used for NLM CGIs."
        print "#"
        print "#CGIMapExtension OS .cgi"
        print "CGIMapExtension SYS:/perl/Perlcgi/perlcgi.nlm .pl"
        print ""
    }
    
    {
        print
    }
    
    END {
        if ((ARGV[1] ~ /httpd.conf.in/) && !BSDSKT) {
           print ""
           print "#"
           print "# SecureListen: Allows you to securely bind Apache to specific IP addresses "
           print "# and/or ports (mod_nwssl)."
           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 "SSLPORT" \"SSL CertificateDNS\""
        }
        print ""
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/NWGNUscripts.inc�����������������������������������������������������������������0000664�0001751�0001751�00000003764�11737125415�016742� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Include for creating start/stop/restart NCF scripts.
    
    instscripts:: FORCE $(INSTALLBASE)/ap2start.ncf $(INSTALLBASE)/ap2auto.ncf $(INSTALLBASE)/ap2rest.ncf $(INSTALLBASE)/ap2stop.ncf
    
    $(INSTALLBASE)/ap2start.ncf:
    	@echo $(DL)# NCF to start Apache 2.x in own address space$(DL)> $@
    	@echo $(DL)# Make sure that httpstk is not listening on 80$(DL)>> $@
    	@echo $(DL)# httpcloseport 80 /silent$(DL)>> $@
    	@echo $(DL)# search add SYS:/$(BASEDIR)$(DL)>> $@
    	@echo $(DL)load address space = $(BASEDIR) SYS:/$(BASEDIR)/apache2$(DL)>> $@
    	@echo $(DL)# If you have problems with 3rd-party modules try to load in OS space.$(DL)>> $@
    	@echo $(DL)# load SYS:/$(BASEDIR)/apache2$(DL)>> $@
    	@$(ECHONL)>> $@
    
    $(INSTALLBASE)/ap2auto.ncf:
    	@echo $(DL)# NCF to start Apache 2.x in own address space$(DL)> $@
    	@echo $(DL)# and let automatically restart in case it crashes$(DL)>> $@
    	@echo $(DL)# Make sure that httpstk is not listening on 80$(DL)>> $@
    	@echo $(DL)# httpcloseport 80 /silent$(DL)>> $@
    	@echo $(DL)# search add SYS:/$(BASEDIR)$(DL)>> $@
    	@echo $(DL)restart address space = $(BASEDIR) SYS:/$(BASEDIR)/apache2$(DL)>> $@
    	@$(ECHONL)>> $@
    
    $(INSTALLBASE)/ap2rest.ncf:
    	@echo $(DL)# NCF to restart Apache 2.x in own address space$(DL)> $@
    	@echo $(DL)apache2 restart -p $(BASEDIR)$(DL)>> $@
    	@echo $(DL)# If you have loaded Apache2.x in OS space use the line below.$(DL)>> $@
    	@echo $(DL)# apache2 restart$(DL)>> $@
    	@$(ECHONL)>> $@
    
    $(INSTALLBASE)/ap2stop.ncf:
    	@echo $(DL)# NCF to stop Apache 2.x in own address space$(DL)> $@
    	@echo $(DL)apache2 shutdown -p $(BASEDIR)$(DL)>> $@
    	@echo $(DL)# If you have loaded Apache2.x in OS space use the line below.$(DL)>> $@
    	@echo $(DL)# apache2 shutdown$(DL)>> $@
    	@$(ECHONL)>> $@
    
    $(INSTALLBASE)/ap2prod.ncf:
    	@echo $(DL)# NCF to create a product record for Apache 2.x in product database$(DL)> $@
    	@echo $(DL)PRODSYNC DEL APACHE$(VERSION_MAJMIN)$(DL)>> $@
    	@echo $(DL)PRODSYNC ADD APACHE$(VERSION_MAJMIN) ProductRecord "$(VERSION_STR)" "Apache $(VERSION_STR) Webserver"$(DL)>> $@
    	@$(ECHONL)>> $@
    
    ������������httpd-2.4.64/build/get-version.sh�������������������������������������������������������������������0000775�0001751�0001751�00000004143�11402455347�016531� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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" = "epoch"; then
      printf "%02d%02d%03d" ${major} ${minor} ${patch}
    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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/bsd_makefile���������������������������������������������������������������������0000775�0001751�0001751�00000002236�10455012627�016261� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/install.sh�����������������������������������������������������������������������0000775�0001751�0001751�00000006357�10455010104�015727� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 <rse apache.org>
    
    #
    #   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
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/fastgen.sh�����������������������������������������������������������������������0000775�0001751�0001751�00000004430�10455010104�015676� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 <<EOF |sed 's/^include \(.*\)/.include "\1"/' >$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 <<EOF >$makefile
    top_srcdir   = $top_srcdir
    top_builddir = $top_builddir
    srcdir       = $real_srcdir
    builddir     = $real_builddir
    VPATH        = $real_srcdir
    EOF
    
        touch $dir/.deps
      done
    fi
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/make_var_export.awk��������������������������������������������������������������0000664�0001751�0001751�00000003416�10455010104�017605� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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)
    }
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/binbuild.sh����������������������������������������������������������������������0000775�0001751�0001751�00000017320�10455010104�016041� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    # 	
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/instdso.sh�����������������������������������������������������������������������0000775�0001751�0001751�00000006027�11534233136�015751� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    
    case $SYS in
        SunOS|HP-UX)
            INSTALL_CMD=cp
            ;;
        *)
            type install >/dev/null 2>&1 && INSTALL_CMD=install || INSTALL_CMD=cp
            ;;
    esac
    
    CMD="$SH_LIBTOOL --mode=install $INSTALL_CMD $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
    
    if test -s "$TARGETDIR/$DSOARCHIVE_BASENAME"
    then
      DLNAME=`sed -n "/^dlname=/{s/.*='\([^']*\)'/\1/;p;}" $TARGETDIR/$DSOARCHIVE_BASENAME`
      LIBRARY_NAMES=`sed -n "/^library_names/{s/library_names='\([^']*\)'/\1/;p;}" $TARGETDIR/$DSOARCHIVE_BASENAME`
      LIBRARY_NAMES=`echo $LIBRARY_NAMES | sed -e "s/ *$DLNAME//g"`
    fi
    
    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
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/sysv_makefile��������������������������������������������������������������������0000775�0001751�0001751�00000002236�10455012627�016515� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/ltlib.mk�������������������������������������������������������������������������0000664�0001751�0001751�00000001667�10455012627�015374� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    
    �������������������������������������������������������������������������httpd-2.4.64/build/mkdir.sh�������������������������������������������������������������������������0000775�0001751�0001751�00000003174�10455010104�015361� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 <friedman@prep.ai.mit.edu>
    # 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 <rse apache.org>
    
    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
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/buildinfo.sh���������������������������������������������������������������������0000775�0001751�0001751�00000012155�10455010104�016225� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/find_apr.m4����������������������������������������������������������������������0000664�0001751�0001751�00000017056�15032766624�015771� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl -------------------------------------------------------- -*- autoconf -*-
    dnl Licensed to the Apache Software Foundation (ASF) under one or more
    dnl contributor license agreements.  See the NOTICE file distributed with
    dnl this work for additional information regarding copyright ownership.
    dnl The ASF licenses this file to You under the Apache License, Version 2.0
    dnl (the "License"); you may not use this file except in compliance with
    dnl the License.  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.
    
    dnl
    dnl find_apr.m4 : locate the APR include files and libraries
    dnl
    dnl This macro file can be used by applications to find and use the APR
    dnl library. It provides a standardized mechanism for using APR. It supports
    dnl embedding APR into the application source, or locating an installed
    dnl copy of APR.
    dnl
    dnl APR_FIND_APR(srcdir, builddir, implicit-install-check, acceptable-majors,
    dnl              detailed-check)
    dnl
    dnl   where srcdir is the location of the bundled APR source directory, or
    dnl   empty if source is not bundled.
    dnl
    dnl   where builddir is the location where the bundled APR will will be built,
    dnl   or empty if the build will occur in the srcdir.
    dnl
    dnl   where implicit-install-check set to 1 indicates if there is no
    dnl   --with-apr option specified, we will look for installed copies.
    dnl
    dnl   where acceptable-majors is a space separated list of acceptable major
    dnl   version numbers. Often only a single major version will be acceptable.
    dnl   If multiple versions are specified, and --with-apr=PREFIX or the
    dnl   implicit installed search are used, then the first (leftmost) version
    dnl   in the list that is found will be used.  Currently defaults to [0 1].
    dnl
    dnl   where detailed-check is an M4 macro which sets the apr_acceptable to
    dnl   either "yes" or "no". The macro will be invoked for each installed
    dnl   copy of APR found, with the apr_config variable set appropriately.
    dnl   Only installed copies of APR which are considered acceptable by
    dnl   this macro will be considered found. If no installed copies are
    dnl   considered acceptable by this macro, apr_found will be set to either
    dnl   either "no" or "reconfig".
    dnl
    dnl Sets the following variables on exit:
    dnl
    dnl   apr_found : "yes", "no", "reconfig"
    dnl
    dnl   apr_config : If the apr-config tool exists, this refers to it. If
    dnl                apr_found is "reconfig", then the bundled directory
    dnl                should be reconfigured *before* using apr_config.
    dnl
    dnl Note: this macro file assumes that apr-config has been installed; it
    dnl       is normally considered a required part of an APR installation.
    dnl
    dnl If a bundled source directory is available and needs to be (re)configured,
    dnl then apr_found is set to "reconfig". The caller should reconfigure the
    dnl (passed-in) source directory, placing the result in the build directory,
    dnl as appropriate.
    dnl
    dnl If apr_found is "yes" or "reconfig", then the caller should use the
    dnl value of apr_config to fetch any necessary build/link information.
    dnl
    
    AC_DEFUN([APR_FIND_APR], [
      apr_found="no"
    
      if test "$target_os" = "os2-emx"; then
        # Scripts don't pass test -x on OS/2
        TEST_X="test -f"
      else
        TEST_X="test -x"
      fi
    
      ifelse([$4], [], [
             ifdef(AC_WARNING,AC_WARNING([$0: missing argument 4 (acceptable-majors): Defaulting to APR 0.x then APR 1.x]))
             acceptable_majors="0 1"],
             [acceptable_majors="$4"])
    
      apr_temp_acceptable_apr_config=""
      for apr_temp_major in $acceptable_majors
      do
        case $apr_temp_major in
          0)
          apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-config"
          ;;
          *)
          apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-$apr_temp_major-config"
          ;;
        esac
      done
    
      AC_MSG_CHECKING(for APR)
      AC_ARG_WITH(apr,
      [  --with-apr=PATH         prefix for installed APR or the full path to 
                                 apr-config],
      [
        if test "$withval" = "no" || test "$withval" = "yes"; then
          AC_MSG_ERROR([--with-apr requires a directory or file to be provided])
        fi
    
        for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config
        do
          for lookdir in "$withval/bin" "$withval"
          do
            if $TEST_X "$lookdir/$apr_temp_apr_config_file"; then
              apr_config="$lookdir/$apr_temp_apr_config_file"
              ifelse([$5], [], [], [
              apr_acceptable="yes"
              $5
              if test "$apr_acceptable" != "yes"; then
                AC_MSG_WARN([Found APR in $apr_config, but we think it is considered unacceptable])
                continue
              fi])
              apr_found="yes"
              break 2
            fi
          done
        done
    
        if test "$apr_found" != "yes" && $TEST_X "$withval" && $withval --help > /dev/null 2>&1 ; then
          apr_config="$withval"
          ifelse([$5], [], [apr_found="yes"], [
              apr_acceptable="yes"
              $5
              if test "$apr_acceptable" = "yes"; then
                    apr_found="yes"
              fi])
        fi
    
        dnl if --with-apr is used, it is a fatal error for its argument
        dnl to be invalid
        if test "$apr_found" != "yes"; then
          AC_MSG_ERROR([the --with-apr parameter is incorrect. It must specify an install prefix, a build directory, or an apr-config file.])
        fi
      ],[
        dnl If we allow installed copies, check those before using bundled copy.
        if test -n "$3" && test "$3" = "1"; then
          for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config
          do
            if $apr_temp_apr_config_file --help > /dev/null 2>&1 ; then
              apr_config="$apr_temp_apr_config_file"
              ifelse([$5], [], [], [
              apr_acceptable="yes"
              $5
              if test "$apr_acceptable" != "yes"; then
                AC_MSG_WARN([skipped APR at $apr_config, version not acceptable])
                continue
              fi])
              apr_found="yes"
              break
            else
              dnl look in some standard places
              for lookdir in /usr /usr/local /usr/local/apr /opt/apr; do
                if $TEST_X "$lookdir/bin/$apr_temp_apr_config_file"; then
                  apr_config="$lookdir/bin/$apr_temp_apr_config_file"
                  ifelse([$5], [], [], [
                  apr_acceptable="yes"
                  $5
                  if test "$apr_acceptable" != "yes"; then
                    AC_MSG_WARN([skipped APR at $apr_config, version not acceptable])
                    continue
                  fi])
                  apr_found="yes"
                  break 2
                fi
              done
            fi
          done
        fi
        dnl if we have not found anything yet and have bundled source, use that
        if test "$apr_found" = "no" && test -d "$1"; then
          apr_temp_abs_srcdir="`cd \"$1\" && pwd`"
          apr_found="reconfig"
          apr_bundled_major="`sed -n '/#define.*APR_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \"$1/include/apr_version.h\"`"
          case $apr_bundled_major in
            "")
              AC_MSG_ERROR([failed to find major version of bundled APR])
            ;;
            0)
              apr_temp_apr_config_file="apr-config"
            ;;
            *)
              apr_temp_apr_config_file="apr-$apr_bundled_major-config"
            ;;
          esac
          if test -n "$2"; then
            apr_config="$2/$apr_temp_apr_config_file"
          else
            apr_config="$1/$apr_temp_apr_config_file"
          fi
        fi
      ])
    
      AC_MSG_RESULT($apr_found)
    ])
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/config_vars.sh.in����������������������������������������������������������������0000664�0001751�0001751�00000005007�13160167044�017166� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! @SHELL@
    # -*- sh -*-
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    # config_vars.sh is generated by configure, and is run by the "install-build"
    # target to generate a version of config_vars.mk which is suitable to be
    # installed.  Such a file cannot be generated at configure-time, since it
    # requires the output of the *installed* ap*-config scripts.
    
    # For a DESTDIR=... installation using the bundled copies of 
    # apr/apr-util, the installed ap?-config scripts must be found 
    # in the DESTDIR-relocated install tree.  For a DESTDIR=... 
    # installation when using *external* copies of apr/apr-util,
    # the absolute path must be used, not DESTDIR-relocated.
    
    if test -f ${DESTDIR}@APR_CONFIG@; then
       APR_CONFIG=${DESTDIR}@APR_CONFIG@
       APU_CONFIG=${DESTDIR}@APU_CONFIG@
    else
       APR_CONFIG=@APR_CONFIG@
       APU_CONFIG=@APU_CONFIG@
    fi
    
    APR_LIBTOOL="`${APR_CONFIG} --apr-libtool`"
    APR_INCLUDEDIR="`${APR_CONFIG} --includedir`"
    test -n "@APU_CONFIG@" && APU_INCLUDEDIR="`${APU_CONFIG} --includedir`"
    
    installbuilddir="@exp_installbuilddir@"
    
    exec sed "
    /^[A-Z0-9_]*_LDADD/d
    /MPM_LIB/d
    /APACHECTL_ULIMIT/d
    /[a-z]*_LTFLAGS/d
    /^MPM_MODULES/d
    /^ENABLED_MPM_MODULE/d
    /^DSO_MODULES/d
    /^MODULE_/d
    /^PORT/d
    /^SSLPORT/d
    /^nonssl_/d
    /^CORE_IMPLIB/d
    /^rel_/d
    /^abs_srcdir/d
    /^BUILTIN_LIBS/d
    /^[A-Z]*_SHARED_CMDS/d
    /^shared_build/d
    /^OS_DIR/d
    /^AP_LIBS/d
    /^OS_SPECIFIC_VARS/d
    /^MPM_SUBDIRS/d
    /^EXTRA_INCLUDES/{ 
      s, = , = -I\$(includedir) ,
      s, -I\$(top_srcdir)/[^ ]*,,g
      s, -I\$(top_builddir)/[^ ]*,,g
    }
    /^MKINSTALLDIRS/s,\$(abs_srcdir)/build,$installbuilddir,
    /^INSTALL /s,\$(abs_srcdir)/build,$installbuilddir,
    /^HTTPD_LDFLAGS/d
    /^UTIL_LDFLAGS/d
    /^APR_INCLUDEDIR.*$/s,.*,APR_INCLUDEDIR = ${APR_INCLUDEDIR},
    /^APU_INCLUDEDIR.*$/s,.*,APU_INCLUDEDIR = ${APU_INCLUDEDIR},
    /^LIBTOOL.*$/s,/[^ ]*/libtool \(.*\),${APR_LIBTOOL} @LTFLAGS@,
    "
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/nw_ver.awk�����������������������������������������������������������������������0000664�0001751�0001751�00000004171�12144305165�015731� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 write them to STDOUT
    
      while ((getline < ARGV[1]) > 0) {
        if (match ($0, /^#define AP_SERVER_COPYRIGHT \\/)) {
          if (((getline < ARGV[1]) > 0) && (split($0, c, "\"") == 3)) {
            copyright_str = c[2];
          }
        }
        else 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_DEVBUILD_BOOLEAN/)) {
          ver_devbuild = $3;
        }
      }
    
      if (ver_devbuild) {
        ver_dev = "-dev"
        if (ARGV[2]) {
          while ((getline < ARGV[2]) > 0) {
            if (match ($0, /^\/repos\/asf\/!svn\/ver\/[0-9]+\/httpd\/httpd\/(trunk|branches\/[0-9]\.[0-9]\.x)$/)) {
              gsub(/^\/repos\/asf\/!svn\/ver\/|\/httpd\/httpd\/(trunk|branches\/[0-9]\.[0-9]\.x)$/, "", $0)
              ver_dev = svn_rev = "-r" $0
            }
          }
        }
      }
    
      ver_nlm = ver_major "," ver_minor "," ver_patch;
      ver_str = ver_major "." ver_minor "." ver_patch ver_dev;
    
      print "VERSION = " ver_nlm "";
      print "VERSION_STR = " ver_str "";
      print "VERSION_MAJMIN = " ver_major ver_minor "";
      print "COPYRIGHT_STR = " copyright_str "";
      print "SVN_REVISION = " svn_rev "";
    
    }
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/NWGNUmakefile��������������������������������������������������������������������0000664�0001751�0001751�00000007051�11750052732�016245� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # Declare the sub-directories to be built here
    #
    
    SUBDIRS = \
    	$(APR_WORK)/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
    
    FILES_prebuild_headers = \
    	$(SRC)/include/ap_config_layout.h \
    	$(NWOS)/test_char.h \
    	$(PCRE)/config.h \
    	$(PCRE)/pcre.h \
    	$(EOLIST) 
        
    nlms :: libs $(NWOS)/httpd.imp $(DAV)/main/dav.imp $(STDMOD)/cache/mod_cache.imp
    
    libs :: chkapr $(NWOS)/chartables.c
    
    $(DAV)/main/dav.imp : make_nw_export.awk $(DAV)/main/mod_dav.h
    	@echo $(DL)GEN  $@$(DL)
    	$(AWK) -v EXPPREFIX=AP$(VERSION_MAJMIN) -f $^ >$@
    
    $(STDMOD)/cache/mod_cache.imp: make_nw_export.awk $(STDMOD)/cache/mod_cache.h $(STDMOD)/cache/cache_util.h
    	@echo $(DL)GEN  $@$(DL)
    	$(AWK) -v EXPPREFIX=AP$(VERSION_MAJMIN) -f $^ >$@
    
    $(NWOS)/httpd.imp : make_nw_export.awk nw_export.i
    	@echo $(DL)GEN  $@$(DL)
    	$(AWK) -v EXPPREFIX=AP$(VERSION_MAJMIN) -f $^ >$@
        
    nw_export.i : nw_export.inc $(FILES_prebuild_headers) cc.opt
    	@echo $(DL)GEN  $@$(DL)
    	$(CC) $< @cc.opt
    
    cc.opt : NWGNUmakefile $(APBUILD)/NWGNUenvironment.inc $(APBUILD)/NWGNUtail.inc $(APBUILD)/NWGNUhead.inc
    	@echo $(DL)-P$(DL)> $@
    	@echo $(DL)-EP$(DL)>> $@
    	@echo $(DL)-nosyspath$(DL)>> $@
    	@echo $(DL)-w nocmdline$(DL)>> $@
    	@echo $(DL)$(DEFINES)$(DL)>> $@
    	@echo $(DL)-I$(SRC)/include$(DL)>> $@
    	@echo $(DL)-I$(HTTPD)$(DL)>> $@
    	@echo $(DL)-I$(STDMOD)/aaa$(DL)>> $@
    	@echo $(DL)-I$(STDMOD)/core$(DL)>> $@
    	@echo $(DL)-I$(NWOS)$(DL)>> $@
    	@echo $(DL)-I$(SERVER)/mpm/netware$(DL)>> $@
    	@echo $(DL)-I$(APR)/include$(DL)>> $@
    	@echo $(DL)-I$(APRUTIL)/include$(DL)>> $@
    	@echo $(DL)-ir $(NOVELLLIBC)$(DL)>> $@
    
    $(SRC)/include/ap_config_layout.h: $(NWOS)/netware_config_layout.h
    	@echo Creating $@
    	$(call COPY,$<,$@)
    
    $(PCRE)/%.h: $(PCRE)/%.h.generic
    	@echo Creating $@
    	$(call COPY,$<,$@)
    
    $(PCRE)/%.h: $(PCRE)/%.hw
    	@echo Creating $@
    	$(call COPY,$<,$@)
    
    ifneq "$(BUILDTOOL_AS_NLM)" "1"
    
    $(NWOS)/chartables.c: dftables.exe $(PCRE)/dftables.c
    	@echo $(DL)GEN  $@$(DL)
    	$< $@
    
    %.exe: $(PCRE)/%.c $(PCRE)/config.h $(PCRE)/pcre.h
    	@echo $(DL)Creating Build Helper $@$(DL)
    	$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -DHAVE_CONFIG_H $< -o $@
    
    $(NWOS)/test_char.h: gen_test_char.exe $(SERVER)/gen_test_char.c
    	@echo $(DL)GEN  $@$(DL)
    	$< > $@
    
    %.exe: $(SERVER)/%.c
    	@echo $(DL)Creating Build Helper $@$(DL)
    	$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -DCROSS_COMPILE $< -o $@
    
    else
    
    ifneq "$(wildcard $(NWOS)/chartables.c)" "$(NWOS)/chartables.c"
    $(error Error: required source $(NWOS)/chartables.c not found!)
    endif
    
    ifneq "$(wildcard $(NWOS)/test_char.h)" "$(NWOS)/test_char.h"
    $(error Error: required header $(NWOS)/test_char.h not found!)
    endif
    
    endif
    
    #
    # Check for minimum APR version
    #
    chkapr: $(APR)/build/nw_ver.awk $(APR)/include/apr_version.h
    	@echo $(DL)Checking for APR version...$(DL)
    	$(AWK) -v WANTED=$(APR_WANTED) -f $^
    
    #
    # You can use this target if all that is needed is to copy files to the
    # installation area
    #
    install :: nlms FORCE
    
    clean ::
    	$(call DEL,$(SRC)/include/ap_config_layout.h)
    	$(call DEL,$(PCRE)/config.h)
    	$(call DEL,$(PCRE)/pcre.h)
    	$(call DEL,$(STDMOD)/cache/mod_cache.imp)
    	$(call DEL,$(DAV)/main/dav.imp)
    	$(call DEL,$(NWOS)/httpd.imp)
    	$(call DEL,nw_export.i)
    	$(call DEL,cc.opt)
    	$(call DEL,NWGNUversion.inc)
    ifneq "$(BUILDTOOL_AS_NLM)" "1"
    	$(call DEL,$(NWOS)/chartables.c)
    	$(call DEL,$(NWOS)/test_char.h)
    	$(call DEL,dftables.exe)
    	$(call DEL,gen_test_char.exe)
    endif
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
        
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/build-modules-c.awk��������������������������������������������������������������0000664�0001751�0001751�00000005270�11573243040�017415� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 = " "
        # the core module must come first
        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 "#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 ""
    }
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/special.mk�����������������������������������������������������������������������0000664�0001751�0001751�00000002374�10455062414�015701� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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_DSO)
    
    include $(top_builddir)/build/rules.mk
    
    install-modules-yes: $(SHARED_TARGETS)
    	@$(MKINSTALLDIRS) $(DESTDIR)$(libexecdir)
    	@list='$(shared)'; for i in $$list; do \
    	  $(top_srcdir)/build/instdso.sh SH_LIBTOOL='$(SH_LIBTOOL)' $$i $(DESTDIR)$(libexecdir); \
    	done
    
    install-modules-no:
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/program.mk�����������������������������������������������������������������������0000664�0001751�0001751�00000002010�10455012627�015714� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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)
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/install-bindist.sh.in������������������������������������������������������������0000775�0001751�0001751�00000011752�10455010104�017761� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 " "
    ����������������������httpd-2.4.64/build/default.pl�����������������������������������������������������������������������0000664�0001751�0001751�00000025553�10151220336�015705� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<<
    # 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        = '&copy 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</title>
      </head>
      <frameset cols="190,*">
        <frame src="master.html"  name="Master Index" noresize>
        <frame src="packages.html" name="Documentation">
        <noframes>
          <body bgcolor="$bgcolor2" stylesrc="index.html">
            <p>Some Documentation</p>
          </body>
        </noframes>
      </frameset>
    </html>
    <<
    
    ######################################################################
    
    ## Begin generating master index file (left-hand frame).
    
    file "master.html";
    >><html>
      <head>
        <title>Master Index</title>
      </head>
      <body bgcolor="$bgcolor1" text=#0000ff link=#0020ff vlink=#0020ff>
        <center><img src="${image_directory}ScanDocSmall.jpg" border="0" /></center>
        <p>
        <a href="packages.html" target="Documentation">Master Index</a>
        </p>
        <p>
          <font size="2">
            <nobr>
    <<
    
    ## For each package, generate an index entry.
    
    foreach $p (packages()) {
      $_ = $p->url;
      s/\s/%20/g;
      >><a href="$_" target="Documentation"><b>$(p.name)</b></a><br>
        <dir>
      <<
      foreach $e ($p->classes()) {
        $_ = $e->url;
        s/\s/%20/g;
        >><li><a href="$_" target="Documentation">$(e.fullname)</a>
        <<
      }
      foreach $e ($p->globals()) {
        $_ = $e->url;
        s/\s/%20/g;
        >><li><a href="$_" target="Documentation">$(e.fullname)</a>
        <<
      }
      >></dir><<
    }
    
    >>
              <a href="to-do.html" target="Documentation"><b>To-Do List</b></a><br>
            </nobr>
          </font>
        </p>
      </body>
    </html>
    <<
    
    ######################################################################
    
    ## Begin generating package index file
    
    file "packages.html";
    >><html>
      <head>
        <title>$project_name -- Packages</title>
      </head>
      <body bgcolor="$bgcolor2">
    
        <center>$company_logo
        <h1>Documentation for $project_name</h1>
        </center>
        <h2>Package List</h2>
    <<
    
    ## For each package, generate an index entry.
    
    foreach $p (packages()) {
      $_ = $p->url;
      s/\s/%20/g;
      >><a href = "$_">$(p.name)</a><br>
      <<
    }
    
    >>
        <p>
        <hr size=4>
        $copyright<br>
        Generated by <a href="$scandocURL"><b>ScanDoc $majorVersion.$minorVersion</b></a><br>
        Last Updated: $date<br>
      </body>
    </html>
    
    <<
    
    ######################################################################
    
    ## Generate "To-do list"
    
    file "to-do.html";
    >><html>
      <head>
        <title>$project_name -- To-Do list</title>
      </head>
      <body bgcolor="$bgcolor2">
    
        $company_logo
    
        <h1>To-do list for $project_name</h1>
    <<
    
    if (&todolistFiles()) {
      >><hr size=4><p>
      <<
      foreach $f (&todolistFiles()) {
        my @m = &todolistEntries( $f );
        if ($f =~ /([^\/]+)$/) { $f = $1; }
        >><b>$f:</b><ul>
        <<
        foreach $text (@m) {
          if ($text) {
            print "<li>", &processDescription( $text ), "\n";
          }
        }
        >></ul>
        <<
      }
    }
    
    >>
        <hr size=4>
        $copyright<br>
        Generated by <a href="$scandocURL"><b>ScanDoc $majorVersion.$minorVersion</b></a><br>
        Last Updated: $date<br>
      </body>
    </html>
    <<
    
    ######################################################################
    
    ## Generate individual files for each package.
    
    my $p;
    foreach $p (packages()) {
      file $p->name() . ".html";
      >><html>
      <head>
        <title>$project_name -- $(p.name)</title>
      </head>
      <body bgcolor="$bgcolor2">
        <center>
          <font size=6><b>$project_name</b></font>
          <hr size=4><p>
        </center>
    
        <h2>Package Name: $(p.name)</h2>
        <b>
    <<
    
    ## Generate class and member index at the top of the file.
    
    foreach $c ($p->classes()) {
      >><h3><img src="$bullet1_image" width=18 height=17 align=texttop>
        <a href="$(c.url)">$(c.fullname)</h3></a>
        <ul>
      <<
      foreach $m ($c->members()) {
        >><li><a href="$(m.url)">$(m.longname)</a>
        <<
      }
      >></ul>
      <<
    }
    
    >>
    </b>
    <<
    
    ## Generate detailed class documentation
    foreach $c ($p->classes()) {
     ## Output searchable keyword list
     if ($c->keywords()) {
       print "<!-- ", $c->keywords(), " -->\n";
     }
    
     >><hr size="4">
       <a name="$(c.anchor)"></a>
       <h1>$(c.fullname)</h1>
       <table bgcolor="ffffff" border="0" cellspacing="4">
         <tr>
           <th align=center colspan=2>
           </th>
         </tr>
      <<
      
      # Output author tag
      if ($c->author()) {
        >><tr><th width=20% align=right>Author:</th><<
        >><td>$(c.author)</td></tr><<
      }
    
      # Output package version
      if ($c->version()) {
        >><tr><th width=20% align=right>Version:</th><<
        >><td>$(c.version)</td></tr><<
      }
    
      # Output Source file
      if ($c->sourcefile()) {
        >><tr><th width=20% align=right>Source:</th><<
        >><td>$(c.sourcefile)</td></tr><<
      }
    
      # Output base class list
      if ($c->baseclasses()) {
        >><tr><th width=20% align=right>Base classes:</th>
        <td><<
        my @t = ();
        foreach $b ($c->baseclasses()) {
          my $name = $b->name();
          if ($url = $b->url()) {
            push @t, "<a href=\"$url\">$name</a>";
          }
          else { push @t, $name; }
        }
        print join( ', ', @t );
        >></td></tr>
        <<
      }	
    
      # Output subclasses list
      if ($c->subclasses()) {
        >><tr><th width=20% align=right>Subclasses:</th>
          <td><<
        my @t = ();
        foreach $s ($c->subclasses()) {
          my $name = $s->name();
          if ($url = $s->url()) {
            push @t, "<a href=\"$url\">$name</a>";
          }
          else { push @t, $name; }
        }
        print join( ', ', @t );
        >></td></tr><<
      }
    
      # Output main class description
      >></tr>
      </table>
      <p>
      <<
      print &processDescription( $c->description() );
    	
      # Output "see also" information
      if ($c->seealso()) {
        >><p><dt><b>See Also</b><dd>
        <<
        my @r = ();
        foreach $a ($c->seealso()) {
          my $name = $a->name();
          if ($url = $a->url()) {
            push @r, "<a href=\"$url\">$name</a>";
          }
          else { push @r, $name; }
        }
        print join( ',', @r );
        >><p>
        <<
      }
    
      # Output class member index
      if ($c->members()) {
        print "<h2>Member Index</h2>\n";
        print "<ul>";
        foreach $m ($c->members()) {
          >><li><a href="$(m.url)">$(m.fullname)</a>
    	<<
        }
        >></ul><<
      }
     
      # Output class member variable documentation
      if ($c->membervars()) {
        print "<h2>Class Variables</h2>\n";
        print "<blockquote>\n";
        foreach $m ($c->membervars()) { &variable( $m ); }
        print "</blockquote>\n";
      }
    
      # Output class member function documentation
      if ($c->memberfuncs()) {
        print "<h2>Class Methods</h2>\n";
        print "<blockquote>\n";
        foreach $m ($c->memberfuncs()) { &function( $m ); }
        print "</blockquote>\n";
      }
    }
    
    # Output global variables
    if ($p->globalvars()) {
      >><h2>Global Variables</h2>
        <blockquote>
      <<
      foreach $m ($p->globalvars()) { &variable( $m ); }
      print "</blockquote>\n";
    }
    
    # Output global functions
    if ($p->globalfuncs()) {
      >><h2>Global Functions</h2>
        <blockquote>
      <<
      foreach $m ($p->globalfuncs()) { &function( $m ); }
      print "</blockquote>\n";
    }
    
    >>
        <hr size=4>
        $copyright<br>
        Generated by <a href="$scandocURL"><b>ScanDoc $majorVersion.$minorVersion</b></a><br>
        Last Updated: $date<br>
      </body>
    </html>
    <<
    } # end of foreach (packages) loop
    
    ######################################################################
    
    ## Subroutine to generate documentation for a member function or global function
    
    sub function {
      local ($f) = @_;
      
      if ($f->keywords()) {
        >><!-- $(f.keywords) -->
          <<
      }
      >>
      <a name="$(f.anchor)"></a>
      <dl>
        <dt>
         <b><img src="$bullet2_image" width=19 height=17 align=texttop>$(f.fullname);</b>
        <dd>
      <<
      print &processDescription( $f->description() );
      >>
      <p><dl>
      <<
      if ($f->params()) {
        >>
          <dt><b>Parameters</b><dd>
    	<table width="85%">
        <<
        foreach $a ($f->params()) {
          >><tr valign=top><th align=right>
    	$(a.name)</th><td><<
          print &processDescription( $a->description() );
          >></td></tr>
          <<
        }
        >></table>
          <<
      }
    	
      if ($f->returnValue()) {
        >><dt><b>Return Value</b>
          <dd><<
        print &processDescription( $f->returnValue() );
        >><p><<
      }
      
      if ($f->exceptions()) {
        >><dt><b>Exceptions</b><dd>
          <table width=85%><tr><td colspan=2><hr size=3></td></tr>
        <<
        foreach $a ($f->exceptions()) {
          >><tr valign=top><th align=right>
    	$(a.name)</th><td><<
    	  print &processDescription( $a->description() );
          >></td></tr>
          <<
        }
        >><tr><td colspan=2><hr size=3></td></tr></table>
        <<
      }
    	
      if ($f->seealso()) {
        >><dt><b>See Also</b><dd>
          <<
        my @r = ();
        foreach $a ($f->seealso()) {
          my $name = $a->name();
          if ($url = $a->url()) {
    	push @r, "<a href=\"$url\">$name</a>";
          }
          else { push @r, $name; }
        }
        print join( ',', @r );
        >><p><<
      }
      >></dl></dl>
      <<
    }
    
    ######################################################################
    
    ## Subroutine to generate documentation for a member variable or global variable.
    
    sub variable {
      local ($v) = @_;
      
      if ($v->keywords()) {
        print "<!-- $(v.keywords) -->";
      }
    
      >>
        <a name="$(v.name)"></a>
          <dl><dt>
    	<b><img src="$bullet2_image" width=19 height=17 align=texttop>$(v.fullname);</b>
      <dd>
      <<print &processDescription( $v->description() );>>
      <p><dl>
      <<
      if ($v->seealso()) {
        >><dt><b>See Also</b><dd>
          <<
    	$comma = 0;
        foreach $a ($v->seealso()) {
          if ($comma) { print ","; }
          $comma = 1;
          >><a href="$(a.url)">$(a.name)</a>
    	<<
        }
        >><p>
        <<
      }
      >></dl></dl>
      <<
    }
    
    ######################################################################
    
    sub processDescription {
      local ($_) = @_;
      
      s/^\s+//;				# Remove whitespace from beginning
      s/\s+$/\n/;				# Remove whitespace from end
      s/\n\n/<p>\n/g;			# Replace multiple CR's with paragraph markers
      s:\@heading(.*)\n:<p><h2>$1</h2>:;	# Handle heading text
      
      # Handle embedded image tags
      s:\@caution:<p><img src=\"${image_directory}/caution.gif\" align=left>:;
      s:\@warning:<p><img src=\"${image_directory}/warning.gif\" align=left>:;
      s:\@bug:<p><img src=\"${image_directory}/bug.gif\">:;
      s:\@tip:<p><img src=\"${image_directory}/tip.gif\">:;
    
      return $_;
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/config.guess���������������������������������������������������������������������0000775�0001751�0001751�00000143067�15032766624�016267� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh
    # Attempt to guess a canonical system name.
    #   Copyright 1992-2024 Free Software Foundation, Inc.
    
    # shellcheck disable=SC2006,SC2268 # see below for rationale
    
    timestamp='2024-07-27'
    
    # This file 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 3 of the License, 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, see <https://www.gnu.org/licenses/>.
    #
    # As a special exception to the GNU General Public License, if you
    # distribute this file as part of a program that contains a
    # configuration script generated by Autoconf, you may include it under
    # the same distribution terms that you use for the rest of that
    # program.  This Exception is an additional permission under section 7
    # of the GNU General Public License, version 3 ("GPLv3").
    #
    # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
    #
    # You can get the latest version of this script from:
    # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
    #
    # Please send patches to <config-patches@gnu.org>.
    
    
    # The "shellcheck disable" line above the timestamp inhibits complaints
    # about features and limitations of the classic Bourne shell that were
    # superseded or lifted in POSIX.  However, this script identifies a wide
    # variety of pre-POSIX systems that do not have POSIX shells at all, and
    # even some reasonably current systems (Solaris 10 as case-in-point) still
    # have a pre-POSIX /bin/sh.
    
    
    me=`echo "$0" | sed -e 's,.*/,,'`
    
    usage="\
    Usage: $0 [OPTION]
    
    Output the configuration name of the system '$me' is run on.
    
    Options:
      -h, --help         print this help, then exit
      -t, --time-stamp   print date of last modification, then exit
      -v, --version      print version number, then exit
    
    Report bugs and patches to <config-patches@gnu.org>."
    
    version="\
    GNU config.guess ($timestamp)
    
    Originally written by Per Bothner.
    Copyright 1992-2024 Free Software Foundation, Inc.
    
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
    
    help="
    Try '$me --help' for more information."
    
    # Parse command line
    while test $# -gt 0 ; do
      case $1 in
        --time-stamp | --time* | -t )
           echo "$timestamp" ; exit ;;
        --version | -v )
           echo "$version" ; exit ;;
        --help | --h* | -h )
           echo "$usage"; exit ;;
        -- )     # Stop option processing
           shift; break ;;
        - )	# Use stdin as input.
           break ;;
        -* )
           echo "$me: invalid option $1$help" >&2
           exit 1 ;;
        * )
           break ;;
      esac
    done
    
    if test $# != 0; then
      echo "$me: too many arguments$help" >&2
      exit 1
    fi
    
    # Just in case it came from the environment.
    GUESS=
    
    # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
    # compiler to aid in system detection is discouraged as it requires
    # temporary files to be created and, as you can see below, it is a
    # headache to deal with in a portable fashion.
    
    # Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
    # use 'HOST_CC' if defined, but it is deprecated.
    
    # Portable tmp directory creation inspired by the Autoconf team.
    
    tmp=
    # shellcheck disable=SC2172
    trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
    
    set_cc_for_build() {
        # prevent multiple calls if $tmp is already set
        test "$tmp" && return 0
        : "${TMPDIR=/tmp}"
        # shellcheck disable=SC2039,SC3028
        { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
    	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
    	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
    	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
        dummy=$tmp/dummy
        case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
    	,,)    echo "int x;" > "$dummy.c"
    	       for driver in cc gcc c17 c99 c89 ; do
    		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
    		       CC_FOR_BUILD=$driver
    		       break
    		   fi
    	       done
    	       if test x"$CC_FOR_BUILD" = x ; then
    		   CC_FOR_BUILD=no_compiler_found
    	       fi
    	       ;;
    	,,*)   CC_FOR_BUILD=$CC ;;
    	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
        esac
    }
    
    # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
    # (ghazi@noc.rutgers.edu 1994-08-24)
    if test -f /.attbin/uname ; then
    	PATH=$PATH:/.attbin ; export PATH
    fi
    
    UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
    UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
    UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
    UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
    
    case $UNAME_SYSTEM in
    Linux|GNU|GNU/*)
    	LIBC=unknown
    
    	set_cc_for_build
    	cat <<-EOF > "$dummy.c"
    	#if defined(__ANDROID__)
    	LIBC=android
    	#else
    	#include <features.h>
    	#if defined(__UCLIBC__)
    	LIBC=uclibc
    	#elif defined(__dietlibc__)
    	LIBC=dietlibc
    	#elif defined(__GLIBC__)
    	LIBC=gnu
    	#elif defined(__LLVM_LIBC__)
    	LIBC=llvm
    	#else
    	#include <stdarg.h>
    	/* First heuristic to detect musl libc.  */
    	#ifdef __DEFINED_va_list
    	LIBC=musl
    	#endif
    	#endif
    	#endif
    	EOF
    	cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
    	eval "$cc_set_libc"
    
    	# Second heuristic to detect musl libc.
    	if [ "$LIBC" = unknown ] &&
    	   command -v ldd >/dev/null &&
    	   ldd --version 2>&1 | grep -q ^musl; then
    		LIBC=musl
    	fi
    
    	# If the system lacks a compiler, then just pick glibc.
    	# We could probably try harder.
    	if [ "$LIBC" = unknown ]; then
    		LIBC=gnu
    	fi
    	;;
    esac
    
    # Note: order is significant - the case branches are not exclusive.
    
    case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
        *:NetBSD:*:*)
    	# NetBSD (nbsd) targets should (where applicable) match one or
    	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
    	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
    	# switched to ELF, *-*-netbsd* would select the old
    	# object file format.  This provides both forward
    	# compatibility and a consistent mechanism for selecting the
    	# object file format.
    	#
    	# Note: NetBSD doesn't particularly care about the vendor
    	# portion of the name.  We always set it to "unknown".
    	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
    	    /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
    	    /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
    	    echo unknown)`
    	case $UNAME_MACHINE_ARCH in
    	    aarch64eb) machine=aarch64_be-unknown ;;
    	    armeb) machine=armeb-unknown ;;
    	    arm*) machine=arm-unknown ;;
    	    sh3el) machine=shl-unknown ;;
    	    sh3eb) machine=sh-unknown ;;
    	    sh5el) machine=sh5le-unknown ;;
    	    earmv*)
    		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
    		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
    		machine=${arch}${endian}-unknown
    		;;
    	    *) machine=$UNAME_MACHINE_ARCH-unknown ;;
    	esac
    	# The Operating System including object format, if it has switched
    	# to ELF recently (or will in the future) and ABI.
    	case $UNAME_MACHINE_ARCH in
    	    earm*)
    		os=netbsdelf
    		;;
    	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
    		set_cc_for_build
    		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
    			| grep -q __ELF__
    		then
    		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
    		    # Return netbsd for either.  FIX?
    		    os=netbsd
    		else
    		    os=netbsdelf
    		fi
    		;;
    	    *)
    		os=netbsd
    		;;
    	esac
    	# Determine ABI tags.
    	case $UNAME_MACHINE_ARCH in
    	    earm*)
    		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
    		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
    		;;
    	esac
    	# The OS release
    	# Debian GNU/NetBSD machines have a different userland, and
    	# thus, need a distinct triplet. However, they do not need
    	# kernel version information, so it can be replaced with a
    	# suitable tag, in the style of linux-gnu.
    	case $UNAME_VERSION in
    	    Debian*)
    		release='-gnu'
    		;;
    	    *)
    		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
    		;;
    	esac
    	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
    	# contains redundant information, the shorter form:
    	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
    	GUESS=$machine-${os}${release}${abi-}
    	;;
        *:Bitrig:*:*)
    	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
    	GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
    	;;
        *:OpenBSD:*:*)
    	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
    	GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
    	;;
        *:SecBSD:*:*)
    	UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
    	GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
    	;;
        *:LibertyBSD:*:*)
    	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
    	GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
    	;;
        *:MidnightBSD:*:*)
    	GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
    	;;
        *:ekkoBSD:*:*)
    	GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
    	;;
        *:SolidBSD:*:*)
    	GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
    	;;
        *:OS108:*:*)
    	GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
    	;;
        macppc:MirBSD:*:*)
    	GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
    	;;
        *:MirBSD:*:*)
    	GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
    	;;
        *:Sortix:*:*)
    	GUESS=$UNAME_MACHINE-unknown-sortix
    	;;
        *:Twizzler:*:*)
    	GUESS=$UNAME_MACHINE-unknown-twizzler
    	;;
        *:Redox:*:*)
    	GUESS=$UNAME_MACHINE-unknown-redox
    	;;
        mips:OSF1:*.*)
    	GUESS=mips-dec-osf1
    	;;
        alpha:OSF1:*:*)
    	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
    	trap '' 0
    	case $UNAME_RELEASE in
    	*4.0)
    		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
    		;;
    	*5.*)
    		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
    		;;
    	esac
    	# According to Compaq, /usr/sbin/psrinfo has been available on
    	# OSF/1 and Tru64 systems produced since 1995.  I hope that
    	# covers most systems running today.  This code pipes the CPU
    	# types through head -n 1, so we only detect the type of CPU 0.
    	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
    	case $ALPHA_CPU_TYPE in
    	    "EV4 (21064)")
    		UNAME_MACHINE=alpha ;;
    	    "EV4.5 (21064)")
    		UNAME_MACHINE=alpha ;;
    	    "LCA4 (21066/21068)")
    		UNAME_MACHINE=alpha ;;
    	    "EV5 (21164)")
    		UNAME_MACHINE=alphaev5 ;;
    	    "EV5.6 (21164A)")
    		UNAME_MACHINE=alphaev56 ;;
    	    "EV5.6 (21164PC)")
    		UNAME_MACHINE=alphapca56 ;;
    	    "EV5.7 (21164PC)")
    		UNAME_MACHINE=alphapca57 ;;
    	    "EV6 (21264)")
    		UNAME_MACHINE=alphaev6 ;;
    	    "EV6.7 (21264A)")
    		UNAME_MACHINE=alphaev67 ;;
    	    "EV6.8CB (21264C)")
    		UNAME_MACHINE=alphaev68 ;;
    	    "EV6.8AL (21264B)")
    		UNAME_MACHINE=alphaev68 ;;
    	    "EV6.8CX (21264D)")
    		UNAME_MACHINE=alphaev68 ;;
    	    "EV6.9A (21264/EV69A)")
    		UNAME_MACHINE=alphaev69 ;;
    	    "EV7 (21364)")
    		UNAME_MACHINE=alphaev7 ;;
    	    "EV7.9 (21364A)")
    		UNAME_MACHINE=alphaev79 ;;
    	esac
    	# A Pn.n version is a patched version.
    	# A Vn.n version is a released version.
    	# A Tn.n version is a released field test version.
    	# A Xn.n version is an unreleased experimental baselevel.
    	# 1.2 uses "1.2" for uname -r.
    	OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
    	GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
    	;;
        Amiga*:UNIX_System_V:4.0:*)
    	GUESS=m68k-unknown-sysv4
    	;;
        *:[Aa]miga[Oo][Ss]:*:*)
    	GUESS=$UNAME_MACHINE-unknown-amigaos
    	;;
        *:[Mm]orph[Oo][Ss]:*:*)
    	GUESS=$UNAME_MACHINE-unknown-morphos
    	;;
        *:OS/390:*:*)
    	GUESS=i370-ibm-openedition
    	;;
        *:z/VM:*:*)
    	GUESS=s390-ibm-zvmoe
    	;;
        *:OS400:*:*)
    	GUESS=powerpc-ibm-os400
    	;;
        arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
    	GUESS=arm-acorn-riscix$UNAME_RELEASE
    	;;
        arm*:riscos:*:*|arm*:RISCOS:*:*)
    	GUESS=arm-unknown-riscos
    	;;
        SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
    	GUESS=hppa1.1-hitachi-hiuxmpp
    	;;
        Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
    	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
    	case `(/bin/universe) 2>/dev/null` in
    	    att) GUESS=pyramid-pyramid-sysv3 ;;
    	    *)   GUESS=pyramid-pyramid-bsd   ;;
    	esac
    	;;
        NILE*:*:*:dcosx)
    	GUESS=pyramid-pyramid-svr4
    	;;
        DRS?6000:unix:4.0:6*)
    	GUESS=sparc-icl-nx6
    	;;
        DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
    	case `/usr/bin/uname -p` in
    	    sparc) GUESS=sparc-icl-nx7 ;;
    	esac
    	;;
        s390x:SunOS:*:*)
    	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
    	GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
    	;;
        sun4H:SunOS:5.*:*)
    	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
    	GUESS=sparc-hal-solaris2$SUN_REL
    	;;
        sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
    	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
    	GUESS=sparc-sun-solaris2$SUN_REL
    	;;
        i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
    	GUESS=i386-pc-auroraux$UNAME_RELEASE
    	;;
        i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
    	set_cc_for_build
    	SUN_ARCH=i386
    	# If there is a compiler, see if it is configured for 64-bit objects.
    	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
    	# This test works for both compilers.
    	if test "$CC_FOR_BUILD" != no_compiler_found; then
    	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
    		(CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
    		grep IS_64BIT_ARCH >/dev/null
    	    then
    		SUN_ARCH=x86_64
    	    fi
    	fi
    	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
    	GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
    	;;
        sun4*:SunOS:6*:*)
    	# According to config.sub, this is the proper way to canonicalize
    	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
    	# it's likely to be more like Solaris than SunOS4.
    	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
    	GUESS=sparc-sun-solaris3$SUN_REL
    	;;
        sun4*:SunOS:*:*)
    	case `/usr/bin/arch -k` in
    	    Series*|S4*)
    		UNAME_RELEASE=`uname -v`
    		;;
    	esac
    	# Japanese Language versions have a version number like '4.1.3-JL'.
    	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
    	GUESS=sparc-sun-sunos$SUN_REL
    	;;
        sun3*:SunOS:*:*)
    	GUESS=m68k-sun-sunos$UNAME_RELEASE
    	;;
        sun*:*:4.2BSD:*)
    	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
    	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
    	case `/bin/arch` in
    	    sun3)
    		GUESS=m68k-sun-sunos$UNAME_RELEASE
    		;;
    	    sun4)
    		GUESS=sparc-sun-sunos$UNAME_RELEASE
    		;;
    	esac
    	;;
        aushp:SunOS:*:*)
    	GUESS=sparc-auspex-sunos$UNAME_RELEASE
    	;;
        # The situation for MiNT is a little confusing.  The machine name
        # can be virtually everything (everything which is not
        # "atarist" or "atariste" at least should have a processor
        # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
        # to the lowercase version "mint" (or "freemint").  Finally
        # the system name "TOS" denotes a system which is actually not
        # MiNT.  But MiNT is downward compatible to TOS, so this should
        # be no problem.
        atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
    	GUESS=m68k-atari-mint$UNAME_RELEASE
    	;;
        atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
    	GUESS=m68k-atari-mint$UNAME_RELEASE
    	;;
        *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
    	GUESS=m68k-atari-mint$UNAME_RELEASE
    	;;
        milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
    	GUESS=m68k-milan-mint$UNAME_RELEASE
    	;;
        hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
    	GUESS=m68k-hades-mint$UNAME_RELEASE
    	;;
        *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
    	GUESS=m68k-unknown-mint$UNAME_RELEASE
    	;;
        m68k:machten:*:*)
    	GUESS=m68k-apple-machten$UNAME_RELEASE
    	;;
        powerpc:machten:*:*)
    	GUESS=powerpc-apple-machten$UNAME_RELEASE
    	;;
        RISC*:Mach:*:*)
    	GUESS=mips-dec-mach_bsd4.3
    	;;
        RISC*:ULTRIX:*:*)
    	GUESS=mips-dec-ultrix$UNAME_RELEASE
    	;;
        VAX*:ULTRIX*:*:*)
    	GUESS=vax-dec-ultrix$UNAME_RELEASE
    	;;
        2020:CLIX:*:* | 2430:CLIX:*:*)
    	GUESS=clipper-intergraph-clix$UNAME_RELEASE
    	;;
        mips:*:*:UMIPS | mips:*:*:RISCos)
    	set_cc_for_build
    	sed 's/^	//' << EOF > "$dummy.c"
    #ifdef __cplusplus
    #include <stdio.h>  /* for printf() prototype */
    	int main (int argc, char *argv[]) {
    #else
    	int main (argc, argv) int argc; char *argv[]; {
    #endif
    	#if defined (host_mips) && defined (MIPSEB)
    	#if defined (SYSTYPE_SYSV)
    	  printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
    	#endif
    	#if defined (SYSTYPE_SVR4)
    	  printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
    	#endif
    	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
    	  printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
    	#endif
    	#endif
    	  exit (-1);
    	}
    EOF
    	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
    	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
    	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
    	    { echo "$SYSTEM_NAME"; exit; }
    	GUESS=mips-mips-riscos$UNAME_RELEASE
    	;;
        Motorola:PowerMAX_OS:*:*)
    	GUESS=powerpc-motorola-powermax
    	;;
        Motorola:*:4.3:PL8-*)
    	GUESS=powerpc-harris-powermax
    	;;
        Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
    	GUESS=powerpc-harris-powermax
    	;;
        Night_Hawk:Power_UNIX:*:*)
    	GUESS=powerpc-harris-powerunix
    	;;
        m88k:CX/UX:7*:*)
    	GUESS=m88k-harris-cxux7
    	;;
        m88k:*:4*:R4*)
    	GUESS=m88k-motorola-sysv4
    	;;
        m88k:*:3*:R3*)
    	GUESS=m88k-motorola-sysv3
    	;;
        AViiON:dgux:*:*)
    	# DG/UX returns AViiON for all architectures
    	UNAME_PROCESSOR=`/usr/bin/uname -p`
    	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
    	then
    	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
    	       test "$TARGET_BINARY_INTERFACE"x = x
    	    then
    		GUESS=m88k-dg-dgux$UNAME_RELEASE
    	    else
    		GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
    	    fi
    	else
    	    GUESS=i586-dg-dgux$UNAME_RELEASE
    	fi
    	;;
        M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
    	GUESS=m88k-dolphin-sysv3
    	;;
        M88*:*:R3*:*)
    	# Delta 88k system running SVR3
    	GUESS=m88k-motorola-sysv3
    	;;
        XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
    	GUESS=m88k-tektronix-sysv3
    	;;
        Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
    	GUESS=m68k-tektronix-bsd
    	;;
        *:IRIX*:*:*)
    	IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
    	GUESS=mips-sgi-irix$IRIX_REL
    	;;
        ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
    	GUESS=romp-ibm-aix    # uname -m gives an 8 hex-code CPU id
    	;;                    # Note that: echo "'`uname -s`'" gives 'AIX '
        i*86:AIX:*:*)
    	GUESS=i386-ibm-aix
    	;;
        ia64:AIX:*:*)
    	if test -x /usr/bin/oslevel ; then
    		IBM_REV=`/usr/bin/oslevel`
    	else
    		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
    	fi
    	GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
    	;;
        *:AIX:2:3)
    	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
    		set_cc_for_build
    		sed 's/^		//' << EOF > "$dummy.c"
    		#include <sys/systemcfg.h>
    
    		int
    		main ()
    			{
    			if (!__power_pc())
    				exit(1);
    			puts("powerpc-ibm-aix3.2.5");
    			exit(0);
    			}
    EOF
    		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
    		then
    			GUESS=$SYSTEM_NAME
    		else
    			GUESS=rs6000-ibm-aix3.2.5
    		fi
    	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
    		GUESS=rs6000-ibm-aix3.2.4
    	else
    		GUESS=rs6000-ibm-aix3.2
    	fi
    	;;
        *:AIX:*:[4567])
    	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
    	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
    		IBM_ARCH=rs6000
    	else
    		IBM_ARCH=powerpc
    	fi
    	if test -x /usr/bin/lslpp ; then
    		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
    			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
    	else
    		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
    	fi
    	GUESS=$IBM_ARCH-ibm-aix$IBM_REV
    	;;
        *:AIX:*:*)
    	GUESS=rs6000-ibm-aix
    	;;
        ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
    	GUESS=romp-ibm-bsd4.4
    	;;
        ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
    	GUESS=romp-ibm-bsd$UNAME_RELEASE    # 4.3 with uname added to
    	;;                                  # report: romp-ibm BSD 4.3
        *:BOSX:*:*)
    	GUESS=rs6000-bull-bosx
    	;;
        DPX/2?00:B.O.S.:*:*)
    	GUESS=m68k-bull-sysv3
    	;;
        9000/[34]??:4.3bsd:1.*:*)
    	GUESS=m68k-hp-bsd
    	;;
        hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
    	GUESS=m68k-hp-bsd4.4
    	;;
        9000/[34678]??:HP-UX:*:*)
    	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
    	case $UNAME_MACHINE in
    	    9000/31?)            HP_ARCH=m68000 ;;
    	    9000/[34]??)         HP_ARCH=m68k ;;
    	    9000/[678][0-9][0-9])
    		if test -x /usr/bin/getconf; then
    		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
    		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
    		    case $sc_cpu_version in
    		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
    		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
    		      532)                      # CPU_PA_RISC2_0
    			case $sc_kernel_bits in
    			  32) HP_ARCH=hppa2.0n ;;
    			  64) HP_ARCH=hppa2.0w ;;
    			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
    			esac ;;
    		    esac
    		fi
    		if test "$HP_ARCH" = ""; then
    		    set_cc_for_build
    		    sed 's/^		//' << EOF > "$dummy.c"
    
    		#define _HPUX_SOURCE
    		#include <stdlib.h>
    		#include <unistd.h>
    
    		int
    		main ()
    		{
    		#if defined(_SC_KERNEL_BITS)
    		    long bits = sysconf(_SC_KERNEL_BITS);
    		#endif
    		    long cpu  = sysconf (_SC_CPU_VERSION);
    
    		    switch (cpu)
    			{
    			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
    			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
    			case CPU_PA_RISC2_0:
    		#if defined(_SC_KERNEL_BITS)
    			    switch (bits)
    				{
    				case 64: puts ("hppa2.0w"); break;
    				case 32: puts ("hppa2.0n"); break;
    				default: puts ("hppa2.0"); break;
    				} break;
    		#else  /* !defined(_SC_KERNEL_BITS) */
    			    puts ("hppa2.0"); break;
    		#endif
    			default: puts ("hppa1.0"); break;
    			}
    		    exit (0);
    		}
    EOF
    		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
    		    test -z "$HP_ARCH" && HP_ARCH=hppa
    		fi ;;
    	esac
    	if test "$HP_ARCH" = hppa2.0w
    	then
    	    set_cc_for_build
    
    	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
    	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
    	    # generating 64-bit code.  GNU and HP use different nomenclature:
    	    #
    	    # $ CC_FOR_BUILD=cc ./config.guess
    	    # => hppa2.0w-hp-hpux11.23
    	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
    	    # => hppa64-hp-hpux11.23
    
    	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
    		grep -q __LP64__
    	    then
    		HP_ARCH=hppa2.0w
    	    else
    		HP_ARCH=hppa64
    	    fi
    	fi
    	GUESS=$HP_ARCH-hp-hpux$HPUX_REV
    	;;
        ia64:HP-UX:*:*)
    	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
    	GUESS=ia64-hp-hpux$HPUX_REV
    	;;
        3050*:HI-UX:*:*)
    	set_cc_for_build
    	sed 's/^	//' << EOF > "$dummy.c"
    	#include <unistd.h>
    	int
    	main ()
    	{
    	  long cpu = sysconf (_SC_CPU_VERSION);
    	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
    	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
    	     results, however.  */
    	  if (CPU_IS_PA_RISC (cpu))
    	    {
    	      switch (cpu)
    		{
    		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
    		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
    		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
    		  default: puts ("hppa-hitachi-hiuxwe2"); break;
    		}
    	    }
    	  else if (CPU_IS_HP_MC68K (cpu))
    	    puts ("m68k-hitachi-hiuxwe2");
    	  else puts ("unknown-hitachi-hiuxwe2");
    	  exit (0);
    	}
    EOF
    	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
    		{ echo "$SYSTEM_NAME"; exit; }
    	GUESS=unknown-hitachi-hiuxwe2
    	;;
        9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
    	GUESS=hppa1.1-hp-bsd
    	;;
        9000/8??:4.3bsd:*:*)
    	GUESS=hppa1.0-hp-bsd
    	;;
        *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
    	GUESS=hppa1.0-hp-mpeix
    	;;
        hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
    	GUESS=hppa1.1-hp-osf
    	;;
        hp8??:OSF1:*:*)
    	GUESS=hppa1.0-hp-osf
    	;;
        i*86:OSF1:*:*)
    	if test -x /usr/sbin/sysversion ; then
    	    GUESS=$UNAME_MACHINE-unknown-osf1mk
    	else
    	    GUESS=$UNAME_MACHINE-unknown-osf1
    	fi
    	;;
        parisc*:Lites*:*:*)
    	GUESS=hppa1.1-hp-lites
    	;;
        C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
    	GUESS=c1-convex-bsd
    	;;
        C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
    	if getsysinfo -f scalar_acc
    	then echo c32-convex-bsd
    	else echo c2-convex-bsd
    	fi
    	exit ;;
        C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
    	GUESS=c34-convex-bsd
    	;;
        C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
    	GUESS=c38-convex-bsd
    	;;
        C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
    	GUESS=c4-convex-bsd
    	;;
        CRAY*Y-MP:*:*:*)
    	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
    	GUESS=ymp-cray-unicos$CRAY_REL
    	;;
        CRAY*[A-Z]90:*:*:*)
    	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
    	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
    	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
    	      -e 's/\.[^.]*$/.X/'
    	exit ;;
        CRAY*TS:*:*:*)
    	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
    	GUESS=t90-cray-unicos$CRAY_REL
    	;;
        CRAY*T3E:*:*:*)
    	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
    	GUESS=alphaev5-cray-unicosmk$CRAY_REL
    	;;
        CRAY*SV1:*:*:*)
    	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
    	GUESS=sv1-cray-unicos$CRAY_REL
    	;;
        *:UNICOS/mp:*:*)
    	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
    	GUESS=craynv-cray-unicosmp$CRAY_REL
    	;;
        F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
    	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
    	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
    	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
    	GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
    	;;
        5000:UNIX_System_V:4.*:*)
    	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
    	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
    	GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
    	;;
        i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
    	GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
    	;;
        sparc*:BSD/OS:*:*)
    	GUESS=sparc-unknown-bsdi$UNAME_RELEASE
    	;;
        *:BSD/OS:*:*)
    	GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
    	;;
        arm:FreeBSD:*:*)
    	UNAME_PROCESSOR=`uname -p`
    	set_cc_for_build
    	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
    	    | grep -q __ARM_PCS_VFP
    	then
    	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
    	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
    	else
    	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
    	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
    	fi
    	;;
        *:FreeBSD:*:*)
    	UNAME_PROCESSOR=`uname -p`
    	case $UNAME_PROCESSOR in
    	    amd64)
    		UNAME_PROCESSOR=x86_64 ;;
    	    i386)
    		UNAME_PROCESSOR=i586 ;;
    	esac
    	FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
    	GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
    	;;
        i*:CYGWIN*:*)
    	GUESS=$UNAME_MACHINE-pc-cygwin
    	;;
        *:MINGW64*:*)
    	GUESS=$UNAME_MACHINE-pc-mingw64
    	;;
        *:MINGW*:*)
    	GUESS=$UNAME_MACHINE-pc-mingw32
    	;;
        *:MSYS*:*)
    	GUESS=$UNAME_MACHINE-pc-msys
    	;;
        i*:PW*:*)
    	GUESS=$UNAME_MACHINE-pc-pw32
    	;;
        *:SerenityOS:*:*)
            GUESS=$UNAME_MACHINE-pc-serenity
            ;;
        *:Interix*:*)
    	case $UNAME_MACHINE in
    	    x86)
    		GUESS=i586-pc-interix$UNAME_RELEASE
    		;;
    	    authenticamd | genuineintel | EM64T)
    		GUESS=x86_64-unknown-interix$UNAME_RELEASE
    		;;
    	    IA64)
    		GUESS=ia64-unknown-interix$UNAME_RELEASE
    		;;
    	esac ;;
        i*:UWIN*:*)
    	GUESS=$UNAME_MACHINE-pc-uwin
    	;;
        amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
    	GUESS=x86_64-pc-cygwin
    	;;
        prep*:SunOS:5.*:*)
    	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
    	GUESS=powerpcle-unknown-solaris2$SUN_REL
    	;;
        *:GNU:*:*)
    	# the GNU system
    	GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
    	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
    	GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
    	;;
        *:GNU/*:*:*)
    	# other systems with GNU libc and userland
    	GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
    	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
    	GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
    	;;
        x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
    	GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
    	;;
        *:[Mm]anagarm:*:*)
    	GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
    	;;
        *:Minix:*:*)
    	GUESS=$UNAME_MACHINE-unknown-minix
    	;;
        aarch64:Linux:*:*)
    	set_cc_for_build
    	CPU=$UNAME_MACHINE
    	LIBCABI=$LIBC
    	if test "$CC_FOR_BUILD" != no_compiler_found; then
    	    ABI=64
    	    sed 's/^	    //' << EOF > "$dummy.c"
    	    #ifdef __ARM_EABI__
    	    #ifdef __ARM_PCS_VFP
    	    ABI=eabihf
    	    #else
    	    ABI=eabi
    	    #endif
    	    #endif
    EOF
    	    cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
    	    eval "$cc_set_abi"
    	    case $ABI in
    		eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
    	    esac
    	fi
    	GUESS=$CPU-unknown-linux-$LIBCABI
    	;;
        aarch64_be:Linux:*:*)
    	UNAME_MACHINE=aarch64_be
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        alpha:Linux:*:*)
    	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
    	  EV5)   UNAME_MACHINE=alphaev5 ;;
    	  EV56)  UNAME_MACHINE=alphaev56 ;;
    	  PCA56) UNAME_MACHINE=alphapca56 ;;
    	  PCA57) UNAME_MACHINE=alphapca56 ;;
    	  EV6)   UNAME_MACHINE=alphaev6 ;;
    	  EV67)  UNAME_MACHINE=alphaev67 ;;
    	  EV68*) UNAME_MACHINE=alphaev68 ;;
    	esac
    	objdump --private-headers /bin/sh | grep -q ld.so.1
    	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        arm*:Linux:*:*)
    	set_cc_for_build
    	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
    	    | grep -q __ARM_EABI__
    	then
    	    GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	else
    	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
    		| grep -q __ARM_PCS_VFP
    	    then
    		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
    	    else
    		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
    	    fi
    	fi
    	;;
        avr32*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        cris:Linux:*:*)
    	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
    	;;
        crisv32:Linux:*:*)
    	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
    	;;
        e2k:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        frv:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        hexagon:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        i*86:Linux:*:*)
    	GUESS=$UNAME_MACHINE-pc-linux-$LIBC
    	;;
        ia64:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        k1om:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        kvx:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        kvx:cos:*:*)
    	GUESS=$UNAME_MACHINE-unknown-cos
    	;;
        kvx:mbr:*:*)
    	GUESS=$UNAME_MACHINE-unknown-mbr
    	;;
        loongarch32:Linux:*:* | loongarch64:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        m32r*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        m68*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        mips:Linux:*:* | mips64:Linux:*:*)
    	set_cc_for_build
    	IS_GLIBC=0
    	test x"${LIBC}" = xgnu && IS_GLIBC=1
    	sed 's/^	//' << EOF > "$dummy.c"
    	#undef CPU
    	#undef mips
    	#undef mipsel
    	#undef mips64
    	#undef mips64el
    	#if ${IS_GLIBC} && defined(_ABI64)
    	LIBCABI=gnuabi64
    	#else
    	#if ${IS_GLIBC} && defined(_ABIN32)
    	LIBCABI=gnuabin32
    	#else
    	LIBCABI=${LIBC}
    	#endif
    	#endif
    
    	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
    	CPU=mipsisa64r6
    	#else
    	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
    	CPU=mipsisa32r6
    	#else
    	#if defined(__mips64)
    	CPU=mips64
    	#else
    	CPU=mips
    	#endif
    	#endif
    	#endif
    
    	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
    	MIPS_ENDIAN=el
    	#else
    	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
    	MIPS_ENDIAN=
    	#else
    	MIPS_ENDIAN=
    	#endif
    	#endif
    EOF
    	cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
    	eval "$cc_set_vars"
    	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
    	;;
        mips64el:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        openrisc*:Linux:*:*)
    	GUESS=or1k-unknown-linux-$LIBC
    	;;
        or32:Linux:*:* | or1k*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        padre:Linux:*:*)
    	GUESS=sparc-unknown-linux-$LIBC
    	;;
        parisc64:Linux:*:* | hppa64:Linux:*:*)
    	GUESS=hppa64-unknown-linux-$LIBC
    	;;
        parisc:Linux:*:* | hppa:Linux:*:*)
    	# Look for CPU level
    	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
    	  PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
    	  PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
    	  *)    GUESS=hppa-unknown-linux-$LIBC ;;
    	esac
    	;;
        ppc64:Linux:*:*)
    	GUESS=powerpc64-unknown-linux-$LIBC
    	;;
        ppc:Linux:*:*)
    	GUESS=powerpc-unknown-linux-$LIBC
    	;;
        ppc64le:Linux:*:*)
    	GUESS=powerpc64le-unknown-linux-$LIBC
    	;;
        ppcle:Linux:*:*)
    	GUESS=powerpcle-unknown-linux-$LIBC
    	;;
        riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        s390:Linux:*:* | s390x:Linux:*:*)
    	GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
    	;;
        sh64*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        sh*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        sparc:Linux:*:* | sparc64:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        tile*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        vax:Linux:*:*)
    	GUESS=$UNAME_MACHINE-dec-linux-$LIBC
    	;;
        x86_64:Linux:*:*)
    	set_cc_for_build
    	CPU=$UNAME_MACHINE
    	LIBCABI=$LIBC
    	if test "$CC_FOR_BUILD" != no_compiler_found; then
    	    ABI=64
    	    sed 's/^	    //' << EOF > "$dummy.c"
    	    #ifdef __i386__
    	    ABI=x86
    	    #else
    	    #ifdef __ILP32__
    	    ABI=x32
    	    #endif
    	    #endif
    EOF
    	    cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
    	    eval "$cc_set_abi"
    	    case $ABI in
    		x86) CPU=i686 ;;
    		x32) LIBCABI=${LIBC}x32 ;;
    	    esac
    	fi
    	GUESS=$CPU-pc-linux-$LIBCABI
    	;;
        xtensa*:Linux:*:*)
    	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
    	;;
        i*86:DYNIX/ptx:4*:*)
    	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
    	# earlier versions are messed up and put the nodename in both
    	# sysname and nodename.
    	GUESS=i386-sequent-sysv4
    	;;
        i*86:UNIX_SV:4.2MP:2.*)
    	# Unixware is an offshoot of SVR4, but it has its own version
    	# number series starting with 2...
    	# I am not positive that other SVR4 systems won't match this,
    	# I just have to hope.  -- rms.
    	# Use sysv4.2uw... so that sysv4* matches it.
    	GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
    	;;
        i*86:OS/2:*:*)
    	# If we were able to find 'uname', then EMX Unix compatibility
    	# is probably installed.
    	GUESS=$UNAME_MACHINE-pc-os2-emx
    	;;
        i*86:XTS-300:*:STOP)
    	GUESS=$UNAME_MACHINE-unknown-stop
    	;;
        i*86:atheos:*:*)
    	GUESS=$UNAME_MACHINE-unknown-atheos
    	;;
        i*86:syllable:*:*)
    	GUESS=$UNAME_MACHINE-pc-syllable
    	;;
        i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
    	GUESS=i386-unknown-lynxos$UNAME_RELEASE
    	;;
        i*86:*DOS:*:*)
    	GUESS=$UNAME_MACHINE-pc-msdosdjgpp
    	;;
        i*86:*:4.*:*)
    	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
    	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
    		GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
    	else
    		GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
    	fi
    	;;
        i*86:*:5:[678]*)
    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
    	case `/bin/uname -X | grep "^Machine"` in
    	    *486*)	     UNAME_MACHINE=i486 ;;
    	    *Pentium)	     UNAME_MACHINE=i586 ;;
    	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
    	esac
    	GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
    	;;
        i*86:*:3.2:*)
    	if test -f /usr/options/cb.name; then
    		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
    		GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
    	elif /bin/uname -X 2>/dev/null >/dev/null ; then
    		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
    		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
    		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
    			&& UNAME_MACHINE=i586
    		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
    			&& UNAME_MACHINE=i686
    		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
    			&& UNAME_MACHINE=i686
    		GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
    	else
    		GUESS=$UNAME_MACHINE-pc-sysv32
    	fi
    	;;
        pc:*:*:*)
    	# Left here for compatibility:
    	# uname -m prints for DJGPP always 'pc', but it prints nothing about
    	# the processor, so we play safe by assuming i586.
    	# Note: whatever this is, it MUST be the same as what config.sub
    	# prints for the "djgpp" host, or else GDB configure will decide that
    	# this is a cross-build.
    	GUESS=i586-pc-msdosdjgpp
    	;;
        Intel:Mach:3*:*)
    	GUESS=i386-pc-mach3
    	;;
        paragon:*:*:*)
    	GUESS=i860-intel-osf1
    	;;
        i860:*:4.*:*) # i860-SVR4
    	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
    	  GUESS=i860-stardent-sysv$UNAME_RELEASE    # Stardent Vistra i860-SVR4
    	else # Add other i860-SVR4 vendors below as they are discovered.
    	  GUESS=i860-unknown-sysv$UNAME_RELEASE     # Unknown i860-SVR4
    	fi
    	;;
        mini*:CTIX:SYS*5:*)
    	# "miniframe"
    	GUESS=m68010-convergent-sysv
    	;;
        mc68k:UNIX:SYSTEM5:3.51m)
    	GUESS=m68k-convergent-sysv
    	;;
        M680?0:D-NIX:5.3:*)
    	GUESS=m68k-diab-dnix
    	;;
        M68*:*:R3V[5678]*:*)
    	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
        3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
    	OS_REL=''
    	test -r /etc/.relid \
    	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
    	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
    	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
    	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
    	  && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
        3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
    	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
    	  && { echo i486-ncr-sysv4; exit; } ;;
        NCR*:*:4.2:* | MPRAS*:*:4.2:*)
    	OS_REL='.3'
    	test -r /etc/.relid \
    	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
    	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
    	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
    	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
    	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
    	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
    	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
        m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
    	GUESS=m68k-unknown-lynxos$UNAME_RELEASE
    	;;
        mc68030:UNIX_System_V:4.*:*)
    	GUESS=m68k-atari-sysv4
    	;;
        TSUNAMI:LynxOS:2.*:*)
    	GUESS=sparc-unknown-lynxos$UNAME_RELEASE
    	;;
        rs6000:LynxOS:2.*:*)
    	GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
    	;;
        PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
    	GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
    	;;
        SM[BE]S:UNIX_SV:*:*)
    	GUESS=mips-dde-sysv$UNAME_RELEASE
    	;;
        RM*:ReliantUNIX-*:*:*)
    	GUESS=mips-sni-sysv4
    	;;
        RM*:SINIX-*:*:*)
    	GUESS=mips-sni-sysv4
    	;;
        *:SINIX-*:*:*)
    	if uname -p 2>/dev/null >/dev/null ; then
    		UNAME_MACHINE=`(uname -p) 2>/dev/null`
    		GUESS=$UNAME_MACHINE-sni-sysv4
    	else
    		GUESS=ns32k-sni-sysv
    	fi
    	;;
        PENTIUM:*:4.0*:*)	# Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
    			# says <Richard.M.Bartel@ccMail.Census.GOV>
    	GUESS=i586-unisys-sysv4
    	;;
        *:UNIX_System_V:4*:FTX*)
    	# From Gerald Hewes <hewes@openmarket.com>.
    	# How about differentiating between stratus architectures? -djm
    	GUESS=hppa1.1-stratus-sysv4
    	;;
        *:*:*:FTX*)
    	# From seanf@swdc.stratus.com.
    	GUESS=i860-stratus-sysv4
    	;;
        i*86:VOS:*:*)
    	# From Paul.Green@stratus.com.
    	GUESS=$UNAME_MACHINE-stratus-vos
    	;;
        *:VOS:*:*)
    	# From Paul.Green@stratus.com.
    	GUESS=hppa1.1-stratus-vos
    	;;
        mc68*:A/UX:*:*)
    	GUESS=m68k-apple-aux$UNAME_RELEASE
    	;;
        news*:NEWS-OS:6*:*)
    	GUESS=mips-sony-newsos6
    	;;
        R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
    	if test -d /usr/nec; then
    		GUESS=mips-nec-sysv$UNAME_RELEASE
    	else
    		GUESS=mips-unknown-sysv$UNAME_RELEASE
    	fi
    	;;
        BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
    	GUESS=powerpc-be-beos
    	;;
        BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
    	GUESS=powerpc-apple-beos
    	;;
        BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
    	GUESS=i586-pc-beos
    	;;
        BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
    	GUESS=i586-pc-haiku
    	;;
        ppc:Haiku:*:*)	# Haiku running on Apple PowerPC
    	GUESS=powerpc-apple-haiku
    	;;
        *:Haiku:*:*)	# Haiku modern gcc (not bound by BeOS compat)
    	GUESS=$UNAME_MACHINE-unknown-haiku
    	;;
        SX-4:SUPER-UX:*:*)
    	GUESS=sx4-nec-superux$UNAME_RELEASE
    	;;
        SX-5:SUPER-UX:*:*)
    	GUESS=sx5-nec-superux$UNAME_RELEASE
    	;;
        SX-6:SUPER-UX:*:*)
    	GUESS=sx6-nec-superux$UNAME_RELEASE
    	;;
        SX-7:SUPER-UX:*:*)
    	GUESS=sx7-nec-superux$UNAME_RELEASE
    	;;
        SX-8:SUPER-UX:*:*)
    	GUESS=sx8-nec-superux$UNAME_RELEASE
    	;;
        SX-8R:SUPER-UX:*:*)
    	GUESS=sx8r-nec-superux$UNAME_RELEASE
    	;;
        SX-ACE:SUPER-UX:*:*)
    	GUESS=sxace-nec-superux$UNAME_RELEASE
    	;;
        Power*:Rhapsody:*:*)
    	GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
    	;;
        *:Rhapsody:*:*)
    	GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
    	;;
        arm64:Darwin:*:*)
    	GUESS=aarch64-apple-darwin$UNAME_RELEASE
    	;;
        *:Darwin:*:*)
    	UNAME_PROCESSOR=`uname -p`
    	case $UNAME_PROCESSOR in
    	    unknown) UNAME_PROCESSOR=powerpc ;;
    	esac
    	if command -v xcode-select > /dev/null 2> /dev/null && \
    		! xcode-select --print-path > /dev/null 2> /dev/null ; then
    	    # Avoid executing cc if there is no toolchain installed as
    	    # cc will be a stub that puts up a graphical alert
    	    # prompting the user to install developer tools.
    	    CC_FOR_BUILD=no_compiler_found
    	else
    	    set_cc_for_build
    	fi
    	if test "$CC_FOR_BUILD" != no_compiler_found; then
    	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
    		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
    		   grep IS_64BIT_ARCH >/dev/null
    	    then
    		case $UNAME_PROCESSOR in
    		    i386) UNAME_PROCESSOR=x86_64 ;;
    		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
    		esac
    	    fi
    	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
    	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
    		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
    		   grep IS_PPC >/dev/null
    	    then
    		UNAME_PROCESSOR=powerpc
    	    fi
    	elif test "$UNAME_PROCESSOR" = i386 ; then
    	    # uname -m returns i386 or x86_64
    	    UNAME_PROCESSOR=$UNAME_MACHINE
    	fi
    	GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
    	;;
        *:procnto*:*:* | *:QNX:[0123456789]*:*)
    	UNAME_PROCESSOR=`uname -p`
    	if test "$UNAME_PROCESSOR" = x86; then
    		UNAME_PROCESSOR=i386
    		UNAME_MACHINE=pc
    	fi
    	GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
    	;;
        *:QNX:*:4*)
    	GUESS=i386-pc-qnx
    	;;
        NEO-*:NONSTOP_KERNEL:*:*)
    	GUESS=neo-tandem-nsk$UNAME_RELEASE
    	;;
        NSE-*:NONSTOP_KERNEL:*:*)
    	GUESS=nse-tandem-nsk$UNAME_RELEASE
    	;;
        NSR-*:NONSTOP_KERNEL:*:*)
    	GUESS=nsr-tandem-nsk$UNAME_RELEASE
    	;;
        NSV-*:NONSTOP_KERNEL:*:*)
    	GUESS=nsv-tandem-nsk$UNAME_RELEASE
    	;;
        NSX-*:NONSTOP_KERNEL:*:*)
    	GUESS=nsx-tandem-nsk$UNAME_RELEASE
    	;;
        *:NonStop-UX:*:*)
    	GUESS=mips-compaq-nonstopux
    	;;
        BS2000:POSIX*:*:*)
    	GUESS=bs2000-siemens-sysv
    	;;
        DS/*:UNIX_System_V:*:*)
    	GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
    	;;
        *:Plan9:*:*)
    	# "uname -m" is not consistent, so use $cputype instead. 386
    	# is converted to i386 for consistency with other x86
    	# operating systems.
    	if test "${cputype-}" = 386; then
    	    UNAME_MACHINE=i386
    	elif test "x${cputype-}" != x; then
    	    UNAME_MACHINE=$cputype
    	fi
    	GUESS=$UNAME_MACHINE-unknown-plan9
    	;;
        *:TOPS-10:*:*)
    	GUESS=pdp10-unknown-tops10
    	;;
        *:TENEX:*:*)
    	GUESS=pdp10-unknown-tenex
    	;;
        KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
    	GUESS=pdp10-dec-tops20
    	;;
        XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
    	GUESS=pdp10-xkl-tops20
    	;;
        *:TOPS-20:*:*)
    	GUESS=pdp10-unknown-tops20
    	;;
        *:ITS:*:*)
    	GUESS=pdp10-unknown-its
    	;;
        SEI:*:*:SEIUX)
    	GUESS=mips-sei-seiux$UNAME_RELEASE
    	;;
        *:DragonFly:*:*)
    	DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
    	GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
    	;;
        *:*VMS:*:*)
    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
    	case $UNAME_MACHINE in
    	    A*) GUESS=alpha-dec-vms ;;
    	    I*) GUESS=ia64-dec-vms ;;
    	    V*) GUESS=vax-dec-vms ;;
    	esac ;;
        *:XENIX:*:SysV)
    	GUESS=i386-pc-xenix
    	;;
        i*86:skyos:*:*)
    	SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
    	GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
    	;;
        i*86:rdos:*:*)
    	GUESS=$UNAME_MACHINE-pc-rdos
    	;;
        i*86:Fiwix:*:*)
    	GUESS=$UNAME_MACHINE-pc-fiwix
    	;;
        *:AROS:*:*)
    	GUESS=$UNAME_MACHINE-unknown-aros
    	;;
        x86_64:VMkernel:*:*)
    	GUESS=$UNAME_MACHINE-unknown-esx
    	;;
        amd64:Isilon\ OneFS:*:*)
    	GUESS=x86_64-unknown-onefs
    	;;
        *:Unleashed:*:*)
    	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
    	;;
        *:Ironclad:*:*)
    	GUESS=$UNAME_MACHINE-unknown-ironclad
    	;;
    esac
    
    # Do we have a guess based on uname results?
    if test "x$GUESS" != x; then
        echo "$GUESS"
        exit
    fi
    
    # No uname command or uname output not recognized.
    set_cc_for_build
    cat > "$dummy.c" <<EOF
    #ifdef _SEQUENT_
    #include <sys/types.h>
    #include <sys/utsname.h>
    #endif
    #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
    #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
    #include <signal.h>
    #if defined(_SIZE_T_) || defined(SIGLOST)
    #include <sys/utsname.h>
    #endif
    #endif
    #endif
    int
    main ()
    {
    #if defined (sony)
    #if defined (MIPSEB)
      /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
         I don't know....  */
      printf ("mips-sony-bsd\n"); exit (0);
    #else
    #include <sys/param.h>
      printf ("m68k-sony-newsos%s\n",
    #ifdef NEWSOS4
      "4"
    #else
      ""
    #endif
      ); exit (0);
    #endif
    #endif
    
    #if defined (NeXT)
    #if !defined (__ARCHITECTURE__)
    #define __ARCHITECTURE__ "m68k"
    #endif
      int version;
      version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
      if (version < 4)
        printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
      else
        printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
      exit (0);
    #endif
    
    #if defined (MULTIMAX) || defined (n16)
    #if defined (UMAXV)
      printf ("ns32k-encore-sysv\n"); exit (0);
    #else
    #if defined (CMU)
      printf ("ns32k-encore-mach\n"); exit (0);
    #else
      printf ("ns32k-encore-bsd\n"); exit (0);
    #endif
    #endif
    #endif
    
    #if defined (__386BSD__)
      printf ("i386-pc-bsd\n"); exit (0);
    #endif
    
    #if defined (sequent)
    #if defined (i386)
      printf ("i386-sequent-dynix\n"); exit (0);
    #endif
    #if defined (ns32000)
      printf ("ns32k-sequent-dynix\n"); exit (0);
    #endif
    #endif
    
    #if defined (_SEQUENT_)
      struct utsname un;
    
      uname(&un);
      if (strncmp(un.version, "V2", 2) == 0) {
        printf ("i386-sequent-ptx2\n"); exit (0);
      }
      if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
        printf ("i386-sequent-ptx1\n"); exit (0);
      }
      printf ("i386-sequent-ptx\n"); exit (0);
    #endif
    
    #if defined (vax)
    #if !defined (ultrix)
    #include <sys/param.h>
    #if defined (BSD)
    #if BSD == 43
      printf ("vax-dec-bsd4.3\n"); exit (0);
    #else
    #if BSD == 199006
      printf ("vax-dec-bsd4.3reno\n"); exit (0);
    #else
      printf ("vax-dec-bsd\n"); exit (0);
    #endif
    #endif
    #else
      printf ("vax-dec-bsd\n"); exit (0);
    #endif
    #else
    #if defined(_SIZE_T_) || defined(SIGLOST)
      struct utsname un;
      uname (&un);
      printf ("vax-dec-ultrix%s\n", un.release); exit (0);
    #else
      printf ("vax-dec-ultrix\n"); exit (0);
    #endif
    #endif
    #endif
    #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
    #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
    #if defined(_SIZE_T_) || defined(SIGLOST)
      struct utsname *un;
      uname (&un);
      printf ("mips-dec-ultrix%s\n", un.release); exit (0);
    #else
      printf ("mips-dec-ultrix\n"); exit (0);
    #endif
    #endif
    #endif
    
    #if defined (alliant) && defined (i860)
      printf ("i860-alliant-bsd\n"); exit (0);
    #endif
    
      exit (1);
    }
    EOF
    
    $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
    	{ echo "$SYSTEM_NAME"; exit; }
    
    # Apollos put the system type in the environment.
    test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
    
    echo "$0: unable to guess system type" >&2
    
    case $UNAME_MACHINE:$UNAME_SYSTEM in
        mips:Linux | mips64:Linux)
    	# If we got here on MIPS GNU/Linux, output extra information.
    	cat >&2 <<EOF
    
    NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
    the system type. Please install a C compiler and try again.
    EOF
    	;;
    esac
    
    cat >&2 <<EOF
    
    This script (version $timestamp), has failed to recognize the
    operating system you are using. If your script is old, overwrite *all*
    copies of config.guess and config.sub with the latest versions from:
    
      https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
    and
      https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
    EOF
    
    our_year=`echo $timestamp | sed 's,-.*,,'`
    thisyear=`date +%Y`
    # shellcheck disable=SC2003
    script_age=`expr "$thisyear" - "$our_year"`
    if test "$script_age" -lt 3 ; then
       cat >&2 <<EOF
    
    If $0 has already been updated, send the following data and any
    information you think might be pertinent to config-patches@gnu.org to
    provide the necessary information to handle your system.
    
    config.guess timestamp = $timestamp
    
    uname -m = `(uname -m) 2>/dev/null || echo unknown`
    uname -r = `(uname -r) 2>/dev/null || echo unknown`
    uname -s = `(uname -s) 2>/dev/null || echo unknown`
    uname -v = `(uname -v) 2>/dev/null || echo unknown`
    
    /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
    /bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
    
    hostinfo               = `(hostinfo) 2>/dev/null`
    /bin/universe          = `(/bin/universe) 2>/dev/null`
    /usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
    /bin/arch              = `(/bin/arch) 2>/dev/null`
    /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
    /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
    
    UNAME_MACHINE = "$UNAME_MACHINE"
    UNAME_RELEASE = "$UNAME_RELEASE"
    UNAME_SYSTEM  = "$UNAME_SYSTEM"
    UNAME_VERSION = "$UNAME_VERSION"
    EOF
    fi
    
    exit 1
    
    # Local variables:
    # eval: (add-hook 'before-save-hook 'time-stamp)
    # time-stamp-start: "timestamp='"
    # time-stamp-format: "%:y-%02m-%02d"
    # time-stamp-end: "'"
    # End:
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/config.sub�����������������������������������������������������������������������0000775�0001751�0001751�00000115441�15032766624�015725� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh
    # Configuration validation subroutine script.
    #   Copyright 1992-2024 Free Software Foundation, Inc.
    
    # shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale
    
    timestamp='2024-05-27'
    
    # This file 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 3 of the License, 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, see <https://www.gnu.org/licenses/>.
    #
    # As a special exception to the GNU General Public License, if you
    # distribute this file as part of a program that contains a
    # configuration script generated by Autoconf, you may include it under
    # the same distribution terms that you use for the rest of that
    # program.  This Exception is an additional permission under section 7
    # of the GNU General Public License, version 3 ("GPLv3").
    
    
    # Please send patches to <config-patches@gnu.org>.
    #
    # Configuration subroutine to validate and canonicalize a configuration type.
    # Supply the specified configuration type as an argument.
    # If it is invalid, we print an error message on stderr and exit with code 1.
    # Otherwise, we print the canonical config type on stdout and succeed.
    
    # You can get the latest version of this script from:
    # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
    
    # This file is supposed to be the same for all GNU packages
    # and recognize all the CPU types, system types and aliases
    # that are meaningful with *any* GNU software.
    # Each package is responsible for reporting which valid configurations
    # it does not support.  The user should be able to distinguish
    # a failure to support a valid configuration from a meaningless
    # configuration.
    
    # The goal of this file is to map all the various variations of a given
    # machine specification into a single specification in the form:
    #	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
    # or in some cases, the newer four-part form:
    #	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
    # It is wrong to echo any other type of specification.
    
    # The "shellcheck disable" line above the timestamp inhibits complaints
    # about features and limitations of the classic Bourne shell that were
    # superseded or lifted in POSIX.  However, this script identifies a wide
    # variety of pre-POSIX systems that do not have POSIX shells at all, and
    # even some reasonably current systems (Solaris 10 as case-in-point) still
    # have a pre-POSIX /bin/sh.
    
    me=`echo "$0" | sed -e 's,.*/,,'`
    
    usage="\
    Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
    
    Canonicalize a configuration name.
    
    Options:
      -h, --help         print this help, then exit
      -t, --time-stamp   print date of last modification, then exit
      -v, --version      print version number, then exit
    
    Report bugs and patches to <config-patches@gnu.org>."
    
    version="\
    GNU config.sub ($timestamp)
    
    Copyright 1992-2024 Free Software Foundation, Inc.
    
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
    
    help="
    Try '$me --help' for more information."
    
    # Parse command line
    while test $# -gt 0 ; do
      case $1 in
        --time-stamp | --time* | -t )
           echo "$timestamp" ; exit ;;
        --version | -v )
           echo "$version" ; exit ;;
        --help | --h* | -h )
           echo "$usage"; exit ;;
        -- )     # Stop option processing
           shift; break ;;
        - )	# Use stdin as input.
           break ;;
        -* )
           echo "$me: invalid option $1$help" >&2
           exit 1 ;;
    
        *local*)
           # First pass through any local machine types.
           echo "$1"
           exit ;;
    
        * )
           break ;;
      esac
    done
    
    case $# in
     0) echo "$me: missing argument$help" >&2
        exit 1;;
     1) ;;
     *) echo "$me: too many arguments$help" >&2
        exit 1;;
    esac
    
    # Split fields of configuration type
    saved_IFS=$IFS
    IFS="-" read field1 field2 field3 field4 <<EOF
    $1
    EOF
    IFS=$saved_IFS
    
    # Separate into logical components for further validation
    case $1 in
    	*-*-*-*-*)
    		echo "Invalid configuration '$1': more than four components" >&2
    		exit 1
    		;;
    	*-*-*-*)
    		basic_machine=$field1-$field2
    		basic_os=$field3-$field4
    		;;
    	*-*-*)
    		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
    		# parts
    		maybe_os=$field2-$field3
    		case $maybe_os in
    			  cloudabi*-eabi* \
    			| kfreebsd*-gnu* \
    			| knetbsd*-gnu* \
    			| kopensolaris*-gnu* \
    			| linux-* \
    			| managarm-* \
    			| netbsd*-eabi* \
    			| netbsd*-gnu* \
    			| nto-qnx* \
    			| os2-emx* \
    			| rtmk-nova* \
    			| storm-chaos* \
    			| uclinux-gnu* \
    			| uclinux-uclibc* \
    			| windows-* )
    				basic_machine=$field1
    				basic_os=$maybe_os
    				;;
    			android-linux)
    				basic_machine=$field1-unknown
    				basic_os=linux-android
    				;;
    			*)
    				basic_machine=$field1-$field2
    				basic_os=$field3
    				;;
    		esac
    		;;
    	*-*)
    		case $field1-$field2 in
    			# Shorthands that happen to contain a single dash
    			convex-c[12] | convex-c3[248])
    				basic_machine=$field2-convex
    				basic_os=
    				;;
    			decstation-3100)
    				basic_machine=mips-dec
    				basic_os=
    				;;
    			*-*)
    				# Second component is usually, but not always the OS
    				case $field2 in
    					# Do not treat sunos as a manufacturer
    					sun*os*)
    						basic_machine=$field1
    						basic_os=$field2
    						;;
    					# Manufacturers
    					  3100* \
    					| 32* \
    					| 3300* \
    					| 3600* \
    					| 7300* \
    					| acorn \
    					| altos* \
    					| apollo \
    					| apple \
    					| atari \
    					| att* \
    					| axis \
    					| be \
    					| bull \
    					| cbm \
    					| ccur \
    					| cisco \
    					| commodore \
    					| convergent* \
    					| convex* \
    					| cray \
    					| crds \
    					| dec* \
    					| delta* \
    					| dg \
    					| digital \
    					| dolphin \
    					| encore* \
    					| gould \
    					| harris \
    					| highlevel \
    					| hitachi* \
    					| hp \
    					| ibm* \
    					| intergraph \
    					| isi* \
    					| knuth \
    					| masscomp \
    					| microblaze* \
    					| mips* \
    					| motorola* \
    					| ncr* \
    					| news \
    					| next \
    					| ns \
    					| oki \
    					| omron* \
    					| pc533* \
    					| rebel \
    					| rom68k \
    					| rombug \
    					| semi \
    					| sequent* \
    					| siemens \
    					| sgi* \
    					| siemens \
    					| sim \
    					| sni \
    					| sony* \
    					| stratus \
    					| sun \
    					| sun[234]* \
    					| tektronix \
    					| tti* \
    					| ultra \
    					| unicom* \
    					| wec \
    					| winbond \
    					| wrs)
    						basic_machine=$field1-$field2
    						basic_os=
    						;;
    					zephyr*)
    						basic_machine=$field1-unknown
    						basic_os=$field2
    						;;
    					*)
    						basic_machine=$field1
    						basic_os=$field2
    						;;
    				esac
    			;;
    		esac
    		;;
    	*)
    		# Convert single-component short-hands not valid as part of
    		# multi-component configurations.
    		case $field1 in
    			386bsd)
    				basic_machine=i386-pc
    				basic_os=bsd
    				;;
    			a29khif)
    				basic_machine=a29k-amd
    				basic_os=udi
    				;;
    			adobe68k)
    				basic_machine=m68010-adobe
    				basic_os=scout
    				;;
    			alliant)
    				basic_machine=fx80-alliant
    				basic_os=
    				;;
    			altos | altos3068)
    				basic_machine=m68k-altos
    				basic_os=
    				;;
    			am29k)
    				basic_machine=a29k-none
    				basic_os=bsd
    				;;
    			amdahl)
    				basic_machine=580-amdahl
    				basic_os=sysv
    				;;
    			amiga)
    				basic_machine=m68k-unknown
    				basic_os=
    				;;
    			amigaos | amigados)
    				basic_machine=m68k-unknown
    				basic_os=amigaos
    				;;
    			amigaunix | amix)
    				basic_machine=m68k-unknown
    				basic_os=sysv4
    				;;
    			apollo68)
    				basic_machine=m68k-apollo
    				basic_os=sysv
    				;;
    			apollo68bsd)
    				basic_machine=m68k-apollo
    				basic_os=bsd
    				;;
    			aros)
    				basic_machine=i386-pc
    				basic_os=aros
    				;;
    			aux)
    				basic_machine=m68k-apple
    				basic_os=aux
    				;;
    			balance)
    				basic_machine=ns32k-sequent
    				basic_os=dynix
    				;;
    			blackfin)
    				basic_machine=bfin-unknown
    				basic_os=linux
    				;;
    			cegcc)
    				basic_machine=arm-unknown
    				basic_os=cegcc
    				;;
    			cray)
    				basic_machine=j90-cray
    				basic_os=unicos
    				;;
    			crds | unos)
    				basic_machine=m68k-crds
    				basic_os=
    				;;
    			da30)
    				basic_machine=m68k-da30
    				basic_os=
    				;;
    			decstation | pmax | pmin | dec3100 | decstatn)
    				basic_machine=mips-dec
    				basic_os=
    				;;
    			delta88)
    				basic_machine=m88k-motorola
    				basic_os=sysv3
    				;;
    			dicos)
    				basic_machine=i686-pc
    				basic_os=dicos
    				;;
    			djgpp)
    				basic_machine=i586-pc
    				basic_os=msdosdjgpp
    				;;
    			ebmon29k)
    				basic_machine=a29k-amd
    				basic_os=ebmon
    				;;
    			es1800 | OSE68k | ose68k | ose | OSE)
    				basic_machine=m68k-ericsson
    				basic_os=ose
    				;;
    			gmicro)
    				basic_machine=tron-gmicro
    				basic_os=sysv
    				;;
    			go32)
    				basic_machine=i386-pc
    				basic_os=go32
    				;;
    			h8300hms)
    				basic_machine=h8300-hitachi
    				basic_os=hms
    				;;
    			h8300xray)
    				basic_machine=h8300-hitachi
    				basic_os=xray
    				;;
    			h8500hms)
    				basic_machine=h8500-hitachi
    				basic_os=hms
    				;;
    			harris)
    				basic_machine=m88k-harris
    				basic_os=sysv3
    				;;
    			hp300 | hp300hpux)
    				basic_machine=m68k-hp
    				basic_os=hpux
    				;;
    			hp300bsd)
    				basic_machine=m68k-hp
    				basic_os=bsd
    				;;
    			hppaosf)
    				basic_machine=hppa1.1-hp
    				basic_os=osf
    				;;
    			hppro)
    				basic_machine=hppa1.1-hp
    				basic_os=proelf
    				;;
    			i386mach)
    				basic_machine=i386-mach
    				basic_os=mach
    				;;
    			isi68 | isi)
    				basic_machine=m68k-isi
    				basic_os=sysv
    				;;
    			m68knommu)
    				basic_machine=m68k-unknown
    				basic_os=linux
    				;;
    			magnum | m3230)
    				basic_machine=mips-mips
    				basic_os=sysv
    				;;
    			merlin)
    				basic_machine=ns32k-utek
    				basic_os=sysv
    				;;
    			mingw64)
    				basic_machine=x86_64-pc
    				basic_os=mingw64
    				;;
    			mingw32)
    				basic_machine=i686-pc
    				basic_os=mingw32
    				;;
    			mingw32ce)
    				basic_machine=arm-unknown
    				basic_os=mingw32ce
    				;;
    			monitor)
    				basic_machine=m68k-rom68k
    				basic_os=coff
    				;;
    			morphos)
    				basic_machine=powerpc-unknown
    				basic_os=morphos
    				;;
    			moxiebox)
    				basic_machine=moxie-unknown
    				basic_os=moxiebox
    				;;
    			msdos)
    				basic_machine=i386-pc
    				basic_os=msdos
    				;;
    			msys)
    				basic_machine=i686-pc
    				basic_os=msys
    				;;
    			mvs)
    				basic_machine=i370-ibm
    				basic_os=mvs
    				;;
    			nacl)
    				basic_machine=le32-unknown
    				basic_os=nacl
    				;;
    			ncr3000)
    				basic_machine=i486-ncr
    				basic_os=sysv4
    				;;
    			netbsd386)
    				basic_machine=i386-pc
    				basic_os=netbsd
    				;;
    			netwinder)
    				basic_machine=armv4l-rebel
    				basic_os=linux
    				;;
    			news | news700 | news800 | news900)
    				basic_machine=m68k-sony
    				basic_os=newsos
    				;;
    			news1000)
    				basic_machine=m68030-sony
    				basic_os=newsos
    				;;
    			necv70)
    				basic_machine=v70-nec
    				basic_os=sysv
    				;;
    			nh3000)
    				basic_machine=m68k-harris
    				basic_os=cxux
    				;;
    			nh[45]000)
    				basic_machine=m88k-harris
    				basic_os=cxux
    				;;
    			nindy960)
    				basic_machine=i960-intel
    				basic_os=nindy
    				;;
    			mon960)
    				basic_machine=i960-intel
    				basic_os=mon960
    				;;
    			nonstopux)
    				basic_machine=mips-compaq
    				basic_os=nonstopux
    				;;
    			os400)
    				basic_machine=powerpc-ibm
    				basic_os=os400
    				;;
    			OSE68000 | ose68000)
    				basic_machine=m68000-ericsson
    				basic_os=ose
    				;;
    			os68k)
    				basic_machine=m68k-none
    				basic_os=os68k
    				;;
    			paragon)
    				basic_machine=i860-intel
    				basic_os=osf
    				;;
    			parisc)
    				basic_machine=hppa-unknown
    				basic_os=linux
    				;;
    			psp)
    				basic_machine=mipsallegrexel-sony
    				basic_os=psp
    				;;
    			pw32)
    				basic_machine=i586-unknown
    				basic_os=pw32
    				;;
    			rdos | rdos64)
    				basic_machine=x86_64-pc
    				basic_os=rdos
    				;;
    			rdos32)
    				basic_machine=i386-pc
    				basic_os=rdos
    				;;
    			rom68k)
    				basic_machine=m68k-rom68k
    				basic_os=coff
    				;;
    			sa29200)
    				basic_machine=a29k-amd
    				basic_os=udi
    				;;
    			sei)
    				basic_machine=mips-sei
    				basic_os=seiux
    				;;
    			sequent)
    				basic_machine=i386-sequent
    				basic_os=
    				;;
    			sps7)
    				basic_machine=m68k-bull
    				basic_os=sysv2
    				;;
    			st2000)
    				basic_machine=m68k-tandem
    				basic_os=
    				;;
    			stratus)
    				basic_machine=i860-stratus
    				basic_os=sysv4
    				;;
    			sun2)
    				basic_machine=m68000-sun
    				basic_os=
    				;;
    			sun2os3)
    				basic_machine=m68000-sun
    				basic_os=sunos3
    				;;
    			sun2os4)
    				basic_machine=m68000-sun
    				basic_os=sunos4
    				;;
    			sun3)
    				basic_machine=m68k-sun
    				basic_os=
    				;;
    			sun3os3)
    				basic_machine=m68k-sun
    				basic_os=sunos3
    				;;
    			sun3os4)
    				basic_machine=m68k-sun
    				basic_os=sunos4
    				;;
    			sun4)
    				basic_machine=sparc-sun
    				basic_os=
    				;;
    			sun4os3)
    				basic_machine=sparc-sun
    				basic_os=sunos3
    				;;
    			sun4os4)
    				basic_machine=sparc-sun
    				basic_os=sunos4
    				;;
    			sun4sol2)
    				basic_machine=sparc-sun
    				basic_os=solaris2
    				;;
    			sun386 | sun386i | roadrunner)
    				basic_machine=i386-sun
    				basic_os=
    				;;
    			sv1)
    				basic_machine=sv1-cray
    				basic_os=unicos
    				;;
    			symmetry)
    				basic_machine=i386-sequent
    				basic_os=dynix
    				;;
    			t3e)
    				basic_machine=alphaev5-cray
    				basic_os=unicos
    				;;
    			t90)
    				basic_machine=t90-cray
    				basic_os=unicos
    				;;
    			toad1)
    				basic_machine=pdp10-xkl
    				basic_os=tops20
    				;;
    			tpf)
    				basic_machine=s390x-ibm
    				basic_os=tpf
    				;;
    			udi29k)
    				basic_machine=a29k-amd
    				basic_os=udi
    				;;
    			ultra3)
    				basic_machine=a29k-nyu
    				basic_os=sym1
    				;;
    			v810 | necv810)
    				basic_machine=v810-nec
    				basic_os=none
    				;;
    			vaxv)
    				basic_machine=vax-dec
    				basic_os=sysv
    				;;
    			vms)
    				basic_machine=vax-dec
    				basic_os=vms
    				;;
    			vsta)
    				basic_machine=i386-pc
    				basic_os=vsta
    				;;
    			vxworks960)
    				basic_machine=i960-wrs
    				basic_os=vxworks
    				;;
    			vxworks68)
    				basic_machine=m68k-wrs
    				basic_os=vxworks
    				;;
    			vxworks29k)
    				basic_machine=a29k-wrs
    				basic_os=vxworks
    				;;
    			xbox)
    				basic_machine=i686-pc
    				basic_os=mingw32
    				;;
    			ymp)
    				basic_machine=ymp-cray
    				basic_os=unicos
    				;;
    			*)
    				basic_machine=$1
    				basic_os=
    				;;
    		esac
    		;;
    esac
    
    # Decode 1-component or ad-hoc basic machines
    case $basic_machine in
    	# Here we handle the default manufacturer of certain CPU types.  It is in
    	# some cases the only manufacturer, in others, it is the most popular.
    	w89k)
    		cpu=hppa1.1
    		vendor=winbond
    		;;
    	op50n)
    		cpu=hppa1.1
    		vendor=oki
    		;;
    	op60c)
    		cpu=hppa1.1
    		vendor=oki
    		;;
    	ibm*)
    		cpu=i370
    		vendor=ibm
    		;;
    	orion105)
    		cpu=clipper
    		vendor=highlevel
    		;;
    	mac | mpw | mac-mpw)
    		cpu=m68k
    		vendor=apple
    		;;
    	pmac | pmac-mpw)
    		cpu=powerpc
    		vendor=apple
    		;;
    
    	# Recognize the various machine names and aliases which stand
    	# for a CPU type and a company and sometimes even an OS.
    	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
    		cpu=m68000
    		vendor=att
    		;;
    	3b*)
    		cpu=we32k
    		vendor=att
    		;;
    	bluegene*)
    		cpu=powerpc
    		vendor=ibm
    		basic_os=cnk
    		;;
    	decsystem10* | dec10*)
    		cpu=pdp10
    		vendor=dec
    		basic_os=tops10
    		;;
    	decsystem20* | dec20*)
    		cpu=pdp10
    		vendor=dec
    		basic_os=tops20
    		;;
    	delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300)
    		cpu=m68k
    		vendor=motorola
    		;;
    	# This used to be dpx2*, but that gets the RS6000-based
    	# DPX/20 and the x86-based DPX/2-100 wrong.  See
    	# https://oldskool.silicium.org/stations/bull_dpx20.htm
    	# https://www.feb-patrimoine.com/english/bull_dpx2.htm
    	# https://www.feb-patrimoine.com/english/unix_and_bull.htm
    	dpx2 | dpx2[23]00 | dpx2[23]xx)
    		cpu=m68k
    		vendor=bull
    		;;
    	dpx2100 | dpx21xx)
    		cpu=i386
    		vendor=bull
    		;;
    	dpx20)
    		cpu=rs6000
    		vendor=bull
    		;;
    	encore | umax | mmax)
    		cpu=ns32k
    		vendor=encore
    		;;
    	elxsi)
    		cpu=elxsi
    		vendor=elxsi
    		basic_os=${basic_os:-bsd}
    		;;
    	fx2800)
    		cpu=i860
    		vendor=alliant
    		;;
    	genix)
    		cpu=ns32k
    		vendor=ns
    		;;
    	h3050r* | hiux*)
    		cpu=hppa1.1
    		vendor=hitachi
    		basic_os=hiuxwe2
    		;;
    	hp3k9[0-9][0-9] | hp9[0-9][0-9])
    		cpu=hppa1.0
    		vendor=hp
    		;;
    	hp9k2[0-9][0-9] | hp9k31[0-9])
    		cpu=m68000
    		vendor=hp
    		;;
    	hp9k3[2-9][0-9])
    		cpu=m68k
    		vendor=hp
    		;;
    	hp9k6[0-9][0-9] | hp6[0-9][0-9])
    		cpu=hppa1.0
    		vendor=hp
    		;;
    	hp9k7[0-79][0-9] | hp7[0-79][0-9])
    		cpu=hppa1.1
    		vendor=hp
    		;;
    	hp9k78[0-9] | hp78[0-9])
    		# FIXME: really hppa2.0-hp
    		cpu=hppa1.1
    		vendor=hp
    		;;
    	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
    		# FIXME: really hppa2.0-hp
    		cpu=hppa1.1
    		vendor=hp
    		;;
    	hp9k8[0-9][13679] | hp8[0-9][13679])
    		cpu=hppa1.1
    		vendor=hp
    		;;
    	hp9k8[0-9][0-9] | hp8[0-9][0-9])
    		cpu=hppa1.0
    		vendor=hp
    		;;
    	i*86v32)
    		cpu=`echo "$1" | sed -e 's/86.*/86/'`
    		vendor=pc
    		basic_os=sysv32
    		;;
    	i*86v4*)
    		cpu=`echo "$1" | sed -e 's/86.*/86/'`
    		vendor=pc
    		basic_os=sysv4
    		;;
    	i*86v)
    		cpu=`echo "$1" | sed -e 's/86.*/86/'`
    		vendor=pc
    		basic_os=sysv
    		;;
    	i*86sol2)
    		cpu=`echo "$1" | sed -e 's/86.*/86/'`
    		vendor=pc
    		basic_os=solaris2
    		;;
    	j90 | j90-cray)
    		cpu=j90
    		vendor=cray
    		basic_os=${basic_os:-unicos}
    		;;
    	iris | iris4d)
    		cpu=mips
    		vendor=sgi
    		case $basic_os in
    		    irix*)
    			;;
    		    *)
    			basic_os=irix4
    			;;
    		esac
    		;;
    	miniframe)
    		cpu=m68000
    		vendor=convergent
    		;;
    	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
    		cpu=m68k
    		vendor=atari
    		basic_os=mint
    		;;
    	news-3600 | risc-news)
    		cpu=mips
    		vendor=sony
    		basic_os=newsos
    		;;
    	next | m*-next)
    		cpu=m68k
    		vendor=next
    		;;
    	np1)
    		cpu=np1
    		vendor=gould
    		;;
    	op50n-* | op60c-*)
    		cpu=hppa1.1
    		vendor=oki
    		basic_os=proelf
    		;;
    	pa-hitachi)
    		cpu=hppa1.1
    		vendor=hitachi
    		basic_os=hiuxwe2
    		;;
    	pbd)
    		cpu=sparc
    		vendor=tti
    		;;
    	pbb)
    		cpu=m68k
    		vendor=tti
    		;;
    	pc532)
    		cpu=ns32k
    		vendor=pc532
    		;;
    	pn)
    		cpu=pn
    		vendor=gould
    		;;
    	power)
    		cpu=power
    		vendor=ibm
    		;;
    	ps2)
    		cpu=i386
    		vendor=ibm
    		;;
    	rm[46]00)
    		cpu=mips
    		vendor=siemens
    		;;
    	rtpc | rtpc-*)
    		cpu=romp
    		vendor=ibm
    		;;
    	sde)
    		cpu=mipsisa32
    		vendor=sde
    		basic_os=${basic_os:-elf}
    		;;
    	simso-wrs)
    		cpu=sparclite
    		vendor=wrs
    		basic_os=vxworks
    		;;
    	tower | tower-32)
    		cpu=m68k
    		vendor=ncr
    		;;
    	vpp*|vx|vx-*)
    		cpu=f301
    		vendor=fujitsu
    		;;
    	w65)
    		cpu=w65
    		vendor=wdc
    		;;
    	w89k-*)
    		cpu=hppa1.1
    		vendor=winbond
    		basic_os=proelf
    		;;
    	none)
    		cpu=none
    		vendor=none
    		;;
    	leon|leon[3-9])
    		cpu=sparc
    		vendor=$basic_machine
    		;;
    	leon-*|leon[3-9]-*)
    		cpu=sparc
    		vendor=`echo "$basic_machine" | sed 's/-.*//'`
    		;;
    
    	*-*)
    		saved_IFS=$IFS
    		IFS="-" read cpu vendor <<EOF
    $basic_machine
    EOF
    		IFS=$saved_IFS
    		;;
    	# We use 'pc' rather than 'unknown'
    	# because (1) that's what they normally are, and
    	# (2) the word "unknown" tends to confuse beginning users.
    	i*86 | x86_64)
    		cpu=$basic_machine
    		vendor=pc
    		;;
    	# These rules are duplicated from below for sake of the special case above;
    	# i.e. things that normalized to x86 arches should also default to "pc"
    	pc98)
    		cpu=i386
    		vendor=pc
    		;;
    	x64 | amd64)
    		cpu=x86_64
    		vendor=pc
    		;;
    	# Recognize the basic CPU types without company name.
    	*)
    		cpu=$basic_machine
    		vendor=unknown
    		;;
    esac
    
    unset -v basic_machine
    
    # Decode basic machines in the full and proper CPU-Company form.
    case $cpu-$vendor in
    	# Here we handle the default manufacturer of certain CPU types in canonical form.
    	# It is in some cases the only manufacturer, in others, it is the most popular.
    	c[12]-convex | c[12]-unknown | c3[248]-convex | c3[248]-unknown)
    		vendor=convex
    		basic_os=${basic_os:-bsd}
    		;;
    	craynv-unknown)
    		vendor=cray
    		basic_os=${basic_os:-unicosmp}
    		;;
    	c90-unknown | c90-cray)
    		vendor=cray
    		basic_os=${basic_os:-unicos}
    		;;
    	fx80-unknown)
    		vendor=alliant
    		;;
    	romp-unknown)
    		vendor=ibm
    		;;
    	mmix-unknown)
    		vendor=knuth
    		;;
    	microblaze-unknown | microblazeel-unknown)
    		vendor=xilinx
    		;;
    	rs6000-unknown)
    		vendor=ibm
    		;;
    	vax-unknown)
    		vendor=dec
    		;;
    	pdp11-unknown)
    		vendor=dec
    		;;
    	we32k-unknown)
    		vendor=att
    		;;
    	cydra-unknown)
    		vendor=cydrome
    		;;
    	i370-ibm*)
    		vendor=ibm
    		;;
    	orion-unknown)
    		vendor=highlevel
    		;;
    	xps-unknown | xps100-unknown)
    		cpu=xps100
    		vendor=honeywell
    		;;
    
    	# Here we normalize CPU types with a missing or matching vendor
    	armh-unknown | armh-alt)
    		cpu=armv7l
    		vendor=alt
    		basic_os=${basic_os:-linux-gnueabihf}
    		;;
    
    	# Normalized CPU+vendor pairs that imply an OS, if not otherwise specified
    	m68k-isi)
    		basic_os=${basic_os:-sysv}
    		;;
    	m68k-sony)
    		basic_os=${basic_os:-newsos}
    		;;
    	m68k-tektronix)
    		basic_os=${basic_os:-bsd}
    		;;
    	m88k-harris)
    		basic_os=${basic_os:-sysv3}
    		;;
    	i386-bull | m68k-bull)
    		basic_os=${basic_os:-sysv3}
    		;;
    	rs6000-bull)
    		basic_os=${basic_os:-bosx}
    		;;
    	mips-sni)
    		basic_os=${basic_os:-sysv4}
    		;;
    
    	# Here we normalize CPU types irrespective of the vendor
    	amd64-*)
    		cpu=x86_64
    		;;
    	blackfin-*)
    		cpu=bfin
    		basic_os=${basic_os:-linux}
    		;;
    	c54x-*)
    		cpu=tic54x
    		;;
    	c55x-*)
    		cpu=tic55x
    		;;
    	c6x-*)
    		cpu=tic6x
    		;;
    	e500v[12]-*)
    		cpu=powerpc
    		basic_os=${basic_os}"spe"
    		;;
    	mips3*-*)
    		cpu=mips64
    		;;
    	ms1-*)
    		cpu=mt
    		;;
    	m68knommu-*)
    		cpu=m68k
    		basic_os=${basic_os:-linux}
    		;;
    	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
    		cpu=s12z
    		;;
    	openrisc-*)
    		cpu=or32
    		;;
    	parisc-*)
    		cpu=hppa
    		basic_os=${basic_os:-linux}
    		;;
    	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
    		cpu=i586
    		;;
    	pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)
    		cpu=i686
    		;;
    	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
    		cpu=i686
    		;;
    	pentium4-*)
    		cpu=i786
    		;;
    	ppc-* | ppcbe-*)
    		cpu=powerpc
    		;;
    	ppcle-* | powerpclittle-*)
    		cpu=powerpcle
    		;;
    	ppc64-*)
    		cpu=powerpc64
    		;;
    	ppc64le-* | powerpc64little-*)
    		cpu=powerpc64le
    		;;
    	sb1-*)
    		cpu=mipsisa64sb1
    		;;
    	sb1el-*)
    		cpu=mipsisa64sb1el
    		;;
    	sh5e[lb]-*)
    		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
    		;;
    	spur-*)
    		cpu=spur
    		;;
    	strongarm-* | thumb-*)
    		cpu=arm
    		;;
    	tx39-*)
    		cpu=mipstx39
    		;;
    	tx39el-*)
    		cpu=mipstx39el
    		;;
    	xscale-* | xscalee[bl]-*)
    		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
    		;;
    	arm64-* | aarch64le-*)
    		cpu=aarch64
    		;;
    
    	# Recognize the canonical CPU Types that limit and/or modify the
    	# company names they are paired with.
    	cr16-*)
    		basic_os=${basic_os:-elf}
    		;;
    	crisv32-* | etraxfs*-*)
    		cpu=crisv32
    		vendor=axis
    		;;
    	cris-* | etrax*-*)
    		cpu=cris
    		vendor=axis
    		;;
    	crx-*)
    		basic_os=${basic_os:-elf}
    		;;
    	neo-tandem)
    		cpu=neo
    		vendor=tandem
    		;;
    	nse-tandem)
    		cpu=nse
    		vendor=tandem
    		;;
    	nsr-tandem)
    		cpu=nsr
    		vendor=tandem
    		;;
    	nsv-tandem)
    		cpu=nsv
    		vendor=tandem
    		;;
    	nsx-tandem)
    		cpu=nsx
    		vendor=tandem
    		;;
    	mipsallegrexel-sony)
    		cpu=mipsallegrexel
    		vendor=sony
    		;;
    	tile*-*)
    		basic_os=${basic_os:-linux-gnu}
    		;;
    
    	*)
    		# Recognize the canonical CPU types that are allowed with any
    		# company name.
    		case $cpu in
    			  1750a \
    			| 580 \
    			| [cjt]90 \
    			| a29k \
    			| aarch64 \
    			| aarch64_be \
    			| aarch64c \
    			| abacus \
    			| alpha \
    			| alpha64 \
    			| alpha64ev56 \
    			| alpha64ev6[78] \
    			| alpha64ev[4-8] \
    			| alpha64pca5[67] \
    			| alphaev56 \
    			| alphaev6[78] \
    			| alphaev[4-8] \
    			| alphapca5[67] \
    			| am33_2.0 \
    			| amdgcn \
    			| arc \
    			| arc32 \
    			| arc64 \
    			| arceb \
    			| arm \
    			| arm64e \
    			| arm64ec \
    			| arm[lb]e \
    			| arme[lb] \
    			| armv* \
    			| asmjs \
    			| avr \
    			| avr32 \
    			| ba \
    			| be32 \
    			| be64 \
    			| bfin \
    			| bpf \
    			| bs2000 \
    			| c30 \
    			| c4x \
    			| c8051 \
    			| c[123]* \
    			| clipper \
    			| craynv \
    			| csky \
    			| cydra \
    			| d10v \
    			| d30v \
    			| dlx \
    			| dsp16xx \
    			| e2k \
    			| elxsi \
    			| epiphany \
    			| f30[01] \
    			| f700 \
    			| fido \
    			| fr30 \
    			| frv \
    			| ft32 \
    			| fx80 \
    			| h8300 \
    			| h8500 \
    			| hexagon \
    			| hppa \
    			| hppa1.[01] \
    			| hppa2.0 \
    			| hppa2.0[nw] \
    			| hppa64 \
    			| i*86 \
    			| i370 \
    			| i860 \
    			| i960 \
    			| ia16 \
    			| ia64 \
    			| ip2k \
    			| iq2000 \
    			| javascript \
    			| k1om \
    			| kvx \
    			| le32 \
    			| le64 \
    			| lm32 \
    			| loongarch32 \
    			| loongarch64 \
    			| m32c \
    			| m32r \
    			| m32rle \
    			| m5200 \
    			| m68000 \
    			| m680[012346]0 \
    			| m6811 \
    			| m6812 \
    			| m68360 \
    			| m683?2 \
    			| m68hc11 \
    			| m68hc12 \
    			| m68hcs12x \
    			| m68k \
    			| m88110 \
    			| m88k \
    			| maxq \
    			| mb \
    			| mcore \
    			| mep \
    			| metag \
    			| microblaze \
    			| microblazeel \
    			| mips* \
    			| mmix \
    			| mn10200 \
    			| mn10300 \
    			| moxie \
    			| msp430 \
    			| mt \
    			| nanomips* \
    			| nds32 \
    			| nds32be \
    			| nds32le \
    			| nfp \
    			| nios \
    			| nios2 \
    			| nios2eb \
    			| nios2el \
    			| none \
    			| np1 \
    			| ns16k \
    			| ns32k \
    			| nvptx \
    			| open8 \
    			| or1k* \
    			| or32 \
    			| orion \
    			| pdp10 \
    			| pdp11 \
    			| picochip \
    			| pj \
    			| pjl \
    			| pn \
    			| power \
    			| powerpc \
    			| powerpc64 \
    			| powerpc64le \
    			| powerpcle \
    			| powerpcspe \
    			| pru \
    			| pyramid \
    			| riscv \
    			| riscv32 \
    			| riscv32be \
    			| riscv64 \
    			| riscv64be \
    			| rl78 \
    			| romp \
    			| rs6000 \
    			| rx \
    			| s390 \
    			| s390x \
    			| score \
    			| sh \
    			| sh64 \
    			| sh64le \
    			| sh[12345][lb]e \
    			| sh[1234] \
    			| sh[1234]e[lb] \
    			| sh[23]e \
    			| sh[23]ele \
    			| sh[24]a \
    			| sh[24]ae[lb] \
    			| sh[lb]e \
    			| she[lb] \
    			| shl \
    			| sparc \
    			| sparc64 \
    			| sparc64b \
    			| sparc64v \
    			| sparc86x \
    			| sparclet \
    			| sparclite \
    			| sparcv8 \
    			| sparcv9 \
    			| sparcv9b \
    			| sparcv9v \
    			| spu \
    			| sv1 \
    			| sx* \
    			| tahoe \
    			| thumbv7* \
    			| tic30 \
    			| tic4x \
    			| tic54x \
    			| tic55x \
    			| tic6x \
    			| tic80 \
    			| tron \
    			| ubicom32 \
    			| v70 \
    			| v810 \
    			| v850 \
    			| v850e \
    			| v850e1 \
    			| v850e2 \
    			| v850e2v3 \
    			| v850es \
    			| vax \
    			| vc4 \
    			| visium \
    			| w65 \
    			| wasm32 \
    			| wasm64 \
    			| we32k \
    			| x86 \
    			| x86_64 \
    			| xc16x \
    			| xgate \
    			| xps100 \
    			| xstormy16 \
    			| xtensa* \
    			| ymp \
    			| z80 \
    			| z8k)
    				;;
    
    			*)
    				echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2
    				exit 1
    				;;
    		esac
    		;;
    esac
    
    # Here we canonicalize certain aliases for manufacturers.
    case $vendor in
    	digital*)
    		vendor=dec
    		;;
    	commodore*)
    		vendor=cbm
    		;;
    	*)
    		;;
    esac
    
    # Decode manufacturer-specific aliases for certain operating systems.
    
    if test x"$basic_os" != x
    then
    
    # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
    # set os.
    obj=
    case $basic_os in
    	gnu/linux*)
    		kernel=linux
    		os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
    		;;
    	os2-emx)
    		kernel=os2
    		os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
    		;;
    	nto-qnx*)
    		kernel=nto
    		os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
    		;;
    	*-*)
    		saved_IFS=$IFS
    		IFS="-" read kernel os <<EOF
    $basic_os
    EOF
    		IFS=$saved_IFS
    		;;
    	# Default OS when just kernel was specified
    	nto*)
    		kernel=nto
    		os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
    		;;
    	linux*)
    		kernel=linux
    		os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
    		;;
    	managarm*)
    		kernel=managarm
    		os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
    		;;
    	*)
    		kernel=
    		os=$basic_os
    		;;
    esac
    
    # Now, normalize the OS (knowing we just have one component, it's not a kernel,
    # etc.)
    case $os in
    	# First match some system type aliases that might get confused
    	# with valid system types.
    	# solaris* is a basic system type, with this one exception.
    	auroraux)
    		os=auroraux
    		;;
    	bluegene*)
    		os=cnk
    		;;
    	solaris1 | solaris1.*)
    		os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
    		;;
    	solaris)
    		os=solaris2
    		;;
    	unixware*)
    		os=sysv4.2uw
    		;;
    	# The marketing names for NeXT's operating systems were
    	# NeXTSTEP, NeXTSTEP 2, OpenSTEP 3, OpenSTEP 4.  'openstep' is
    	# mapped to 'openstep3', but 'openstep1' and 'openstep2' are
    	# mapped to 'nextstep' and 'nextstep2', consistent with the
    	# treatment of SunOS/Solaris.
    	ns | ns1 | nextstep | nextstep1 | openstep1)
    		os=nextstep
    		;;
    	ns2 | nextstep2 | openstep2)
    		os=nextstep2
    		;;
    	ns3 | nextstep3 | openstep | openstep3)
    		os=openstep3
    		;;
    	ns4 | nextstep4 | openstep4)
    		os=openstep4
    		;;
    	# es1800 is here to avoid being matched by es* (a different OS)
    	es1800*)
    		os=ose
    		;;
    	# Some version numbers need modification
    	chorusos*)
    		os=chorusos
    		;;
    	isc)
    		os=isc2.2
    		;;
    	sco6)
    		os=sco5v6
    		;;
    	sco5)
    		os=sco3.2v5
    		;;
    	sco4)
    		os=sco3.2v4
    		;;
    	sco3.2.[4-9]*)
    		os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
    		;;
    	sco*v* | scout)
    		# Don't match below
    		;;
    	sco*)
    		os=sco3.2v2
    		;;
    	psos*)
    		os=psos
    		;;
    	qnx*)
    		os=qnx
    		;;
    	hiux*)
    		os=hiuxwe2
    		;;
    	lynx*178)
    		os=lynxos178
    		;;
    	lynx*5)
    		os=lynxos5
    		;;
    	lynxos*)
    		# don't get caught up in next wildcard
    		;;
    	lynx*)
    		os=lynxos
    		;;
    	mac[0-9]*)
    		os=`echo "$os" | sed -e 's|mac|macos|'`
    		;;
    	opened*)
    		os=openedition
    		;;
    	os400*)
    		os=os400
    		;;
    	sunos5*)
    		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
    		;;
    	sunos6*)
    		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
    		;;
    	wince*)
    		os=wince
    		;;
    	utek*)
    		os=bsd
    		vendor=`echo "$vendor" | sed -e 's|^unknown$|tektronix|'`
    		;;
    	dynix*)
    		os=bsd
    		;;
    	acis*)
    		os=aos
    		;;
    	atheos*)
    		os=atheos
    		;;
    	syllable*)
    		os=syllable
    		;;
    	386bsd)
    		os=bsd
    		;;
    	ctix*)
    		os=sysv
    		vendor=`echo "$vendor" | sed -e 's|^unknown$|convergent|'`
    		;;
    	uts*)
    		os=sysv
    		;;
    	nova*)
    		kernel=rtmk
    		os=nova
    		;;
    	# Preserve the version number of sinix5.
    	sinix5.*)
    		os=`echo "$os" | sed -e 's|sinix|sysv|'`
    		vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'`
    		;;
    	sinix*)
    		os=sysv4
    		vendor=`echo "$vendor" | sed -e 's|^unknown$|sni|'`
    		;;
    	tpf*)
    		os=tpf
    		;;
    	triton*)
    		os=sysv3
    		;;
    	oss*)
    		os=sysv3
    		;;
    	svr4*)
    		os=sysv4
    		;;
    	svr3)
    		os=sysv3
    		;;
    	sysvr4)
    		os=sysv4
    		;;
    	ose*)
    		os=ose
    		;;
    	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
    		os=mint
    		;;
    	dicos*)
    		os=dicos
    		;;
    	pikeos*)
    		# Until real need of OS specific support for
    		# particular features comes up, bare metal
    		# configurations are quite functional.
    		case $cpu in
    		    arm*)
    			os=eabi
    			;;
    		    *)
    			os=
    			obj=elf
    			;;
    		esac
    		;;
    	aout* | coff* | elf* | pe*)
    		# These are machine code file formats, not OSes
    		obj=$os
    		os=
    		;;
    	*)
    		# No normalization, but not necessarily accepted, that comes below.
    		;;
    esac
    
    else
    
    # Here we handle the default operating systems that come with various machines.
    # The value should be what the vendor currently ships out the door with their
    # machine or put another way, the most popular os provided with the machine.
    
    # Note that if you're going to try to match "-MANUFACTURER" here (say,
    # "-sun"), then you have to tell the case statement up towards the top
    # that MANUFACTURER isn't an operating system.  Otherwise, code above
    # will signal an error saying that MANUFACTURER isn't an operating
    # system, and we'll never get to this point.
    
    kernel=
    obj=
    case $cpu-$vendor in
    	score-*)
    		os=
    		obj=elf
    		;;
    	spu-*)
    		os=
    		obj=elf
    		;;
    	*-acorn)
    		os=riscix1.2
    		;;
    	arm*-rebel)
    		kernel=linux
    		os=gnu
    		;;
    	arm*-semi)
    		os=
    		obj=aout
    		;;
    	c4x-* | tic4x-*)
    		os=
    		obj=coff
    		;;
    	c8051-*)
    		os=
    		obj=elf
    		;;
    	clipper-intergraph)
    		os=clix
    		;;
    	hexagon-*)
    		os=
    		obj=elf
    		;;
    	tic54x-*)
    		os=
    		obj=coff
    		;;
    	tic55x-*)
    		os=
    		obj=coff
    		;;
    	tic6x-*)
    		os=
    		obj=coff
    		;;
    	# This must come before the *-dec entry.
    	pdp10-*)
    		os=tops20
    		;;
    	pdp11-*)
    		os=none
    		;;
    	*-dec | vax-*)
    		os=ultrix4.2
    		;;
    	m68*-apollo)
    		os=domain
    		;;
    	i386-sun)
    		os=sunos4.0.2
    		;;
    	m68000-sun)
    		os=sunos3
    		;;
    	m68*-cisco)
    		os=
    		obj=aout
    		;;
    	mep-*)
    		os=
    		obj=elf
    		;;
    	# The -sgi and -siemens entries must be before the mips- entry
    	# or we get the wrong os.
    	*-sgi)
    		os=irix
    		;;
    	*-siemens)
    		os=sysv4
    		;;
    	mips*-cisco)
    		os=
    		obj=elf
    		;;
    	mips*-*|nanomips*-*)
    		os=
    		obj=elf
    		;;
    	or32-*)
    		os=
    		obj=coff
    		;;
    	# This must be before the sparc-* entry or we get the wrong os.
    	*-tti)
    		os=sysv3
    		;;
    	sparc-* | *-sun)
    		os=sunos4.1.1
    		;;
    	pru-*)
    		os=
    		obj=elf
    		;;
    	*-be)
    		os=beos
    		;;
    	*-ibm)
    		os=aix
    		;;
    	*-knuth)
    		os=mmixware
    		;;
    	*-wec)
    		os=proelf
    		;;
    	*-winbond)
    		os=proelf
    		;;
    	*-oki)
    		os=proelf
    		;;
    	*-hp)
    		os=hpux
    		;;
    	*-hitachi)
    		os=hiuxwe2
    		;;
    	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
    		os=sysv
    		;;
    	*-cbm)
    		os=amigaos
    		;;
    	*-dg)
    		os=dgux
    		;;
    	*-dolphin)
    		os=sysv3
    		;;
    	m68k-ccur)
    		os=rtu
    		;;
    	m88k-omron*)
    		os=luna
    		;;
    	*-next)
    		os=nextstep
    		;;
    	*-sequent)
    		os=ptx
    		;;
    	*-crds)
    		os=unos
    		;;
    	*-ns)
    		os=genix
    		;;
    	i370-*)
    		os=mvs
    		;;
    	*-gould)
    		os=sysv
    		;;
    	*-highlevel)
    		os=bsd
    		;;
    	*-encore)
    		os=bsd
    		;;
    	*-masscomp)
    		os=rtu
    		;;
    	f30[01]-fujitsu | f700-fujitsu)
    		os=uxpv
    		;;
    	*-rom68k)
    		os=
    		obj=coff
    		;;
    	*-*bug)
    		os=
    		obj=coff
    		;;
    	*-apple)
    		os=macos
    		;;
    	*-atari*)
    		os=mint
    		;;
    	*-wrs)
    		os=vxworks
    		;;
    	*)
    		os=none
    		;;
    esac
    
    fi
    
    # Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
    
    case $os in
    	# Sometimes we do "kernel-libc", so those need to count as OSes.
    	llvm* | musl* | newlib* | relibc* | uclibc*)
    		;;
    	# Likewise for "kernel-abi"
    	eabi* | gnueabi*)
    		;;
    	# VxWorks passes extra cpu info in the 4th filed.
    	simlinux | simwindows | spe)
    		;;
    	# See `case $cpu-$os` validation below
    	ghcjs)
    		;;
    	# Now accept the basic system types.
    	# Each alternative MUST end in a * to match a version number.
    	  abug \
    	| aix* \
    	| amdhsa* \
    	| amigados* \
    	| amigaos* \
    	| android* \
    	| aof* \
    	| aos* \
    	| aros* \
    	| atheos* \
    	| auroraux* \
    	| aux* \
    	| beos* \
    	| bitrig* \
    	| bme* \
    	| bosx* \
    	| bsd* \
    	| cegcc* \
    	| chorusos* \
    	| chorusrdb* \
    	| clix* \
    	| cloudabi* \
    	| cnk* \
    	| conix* \
    	| cos* \
    	| cxux* \
    	| cygwin* \
    	| darwin* \
    	| dgux* \
    	| dicos* \
    	| dnix* \
    	| domain* \
    	| dragonfly* \
    	| drops* \
    	| ebmon* \
    	| ecoff* \
    	| ekkobsd* \
    	| emscripten* \
    	| emx* \
    	| es* \
    	| fiwix* \
    	| freebsd* \
    	| fuchsia* \
    	| genix* \
    	| genode* \
    	| glidix* \
    	| gnu* \
    	| go32* \
    	| haiku* \
    	| hcos* \
    	| hiux* \
    	| hms* \
    	| hpux* \
    	| ieee* \
    	| interix* \
    	| ios* \
    	| iris* \
    	| irix* \
    	| ironclad* \
    	| isc* \
    	| its* \
    	| l4re* \
    	| libertybsd* \
    	| lites* \
    	| lnews* \
    	| luna* \
    	| lynxos* \
    	| mach* \
    	| macos* \
    	| magic* \
    	| mbr* \
    	| midipix* \
    	| midnightbsd* \
    	| mingw32* \
    	| mingw64* \
    	| minix* \
    	| mint* \
    	| mirbsd* \
    	| mks* \
    	| mlibc* \
    	| mmixware* \
    	| mon960* \
    	| morphos* \
    	| moss* \
    	| moxiebox* \
    	| mpeix* \
    	| mpw* \
    	| msdos* \
    	| msys* \
    	| mvs* \
    	| nacl* \
    	| netbsd* \
    	| netware* \
    	| newsos* \
    	| nextstep* \
    	| nindy* \
    	| nonstopux* \
    	| nova* \
    	| nsk* \
    	| nucleus* \
    	| nx6 \
    	| nx7 \
    	| oabi* \
    	| ohos* \
    	| onefs* \
    	| openbsd* \
    	| openedition* \
    	| openstep* \
    	| os108* \
    	| os2* \
    	| os400* \
    	| os68k* \
    	| os9* \
    	| ose* \
    	| osf* \
    	| oskit* \
    	| osx* \
    	| palmos* \
    	| phoenix* \
    	| plan9* \
    	| powermax* \
    	| powerunix* \
    	| proelf* \
    	| psos* \
    	| psp* \
    	| ptx* \
    	| pw32* \
    	| qnx* \
    	| rdos* \
    	| redox* \
    	| rhapsody* \
    	| riscix* \
    	| riscos* \
    	| rtems* \
    	| rtmk* \
    	| rtu* \
    	| scout* \
    	| secbsd* \
    	| sei* \
    	| serenity* \
    	| sim* \
    	| skyos* \
    	| solaris* \
    	| solidbsd* \
    	| sortix* \
    	| storm-chaos* \
    	| sunos \
    	| sunos[34]* \
    	| superux* \
    	| syllable* \
    	| sym* \
    	| sysv* \
    	| tenex* \
    	| tirtos* \
    	| toppers* \
    	| tops10* \
    	| tops20* \
    	| tpf* \
    	| tvos* \
    	| twizzler* \
    	| uclinux* \
    	| udi* \
    	| udk* \
    	| ultrix* \
    	| unicos* \
    	| uniplus* \
    	| unleashed* \
    	| unos* \
    	| uwin* \
    	| uxpv* \
    	| v88r* \
    	|*vms* \
    	| vos* \
    	| vsta* \
    	| vxsim* \
    	| vxworks* \
    	| wasi* \
    	| watchos* \
    	| wince* \
    	| windiss* \
    	| windows* \
    	| winnt* \
    	| xenix* \
    	| xray* \
    	| zephyr* \
    	| zvmoe* )
    		;;
    	# This one is extra strict with allowed versions
    	sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
    		# Don't forget version if it is 3.2v4 or newer.
    		;;
    	# This refers to builds using the UEFI calling convention
    	# (which depends on the architecture) and PE file format.
    	# Note that this is both a different calling convention and
    	# different file format than that of GNU-EFI
    	# (x86_64-w64-mingw32).
    	uefi)
    		;;
    	none)
    		;;
    	kernel* | msvc* )
    		# Restricted further below
    		;;
    	'')
    		if test x"$obj" = x
    		then
    			echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
    		fi
    		;;
    	*)
    		echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
    		exit 1
    		;;
    esac
    
    case $obj in
    	aout* | coff* | elf* | pe*)
    		;;
    	'')
    		# empty is fine
    		;;
    	*)
    		echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
    		exit 1
    		;;
    esac
    
    # Here we handle the constraint that a (synthetic) cpu and os are
    # valid only in combination with each other and nowhere else.
    case $cpu-$os in
    	# The "javascript-unknown-ghcjs" triple is used by GHC; we
    	# accept it here in order to tolerate that, but reject any
    	# variations.
    	javascript-ghcjs)
    		;;
    	javascript-* | *-ghcjs)
    		echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
    		exit 1
    		;;
    esac
    
    # As a final step for OS-related things, validate the OS-kernel combination
    # (given a valid OS), if there is a kernel.
    case $kernel-$os-$obj in
    	linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \
    		    | linux-mlibc*- | linux-musl*- | linux-newlib*- \
    		    | linux-relibc*- | linux-uclibc*- | linux-ohos*- )
    		;;
    	uclinux-uclibc*- | uclinux-gnu*- )
    		;;
    	managarm-mlibc*- | managarm-kernel*- )
    		;;
    	windows*-msvc*-)
    		;;
    	-dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \
    		    | -uclibc*- )
    		# These are just libc implementations, not actual OSes, and thus
    		# require a kernel.
    		echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
    		exit 1
    		;;
    	-kernel*- )
    		echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
    		exit 1
    		;;
    	*-kernel*- )
    		echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
    		exit 1
    		;;
    	*-msvc*- )
    		echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
    		exit 1
    		;;
    	kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-)
    		;;
    	vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
    		;;
    	nto-qnx*-)
    		;;
    	os2-emx-)
    		;;
    	rtmk-nova-)
    		;;
    	*-eabi*- | *-gnueabi*-)
    		;;
    	none--*)
    		# None (no kernel, i.e. freestanding / bare metal),
    		# can be paired with an machine code file format
    		;;
    	-*-)
    		# Blank kernel with real OS is always fine.
    		;;
    	--*)
    		# Blank kernel and OS with real machine code file format is always fine.
    		;;
    	*-*-*)
    		echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
    		exit 1
    		;;
    esac
    
    # Here we handle the case where we know the os, and the CPU type, but not the
    # manufacturer.  We pick the logical manufacturer.
    case $vendor in
    	unknown)
    		case $cpu-$os in
    			*-riscix*)
    				vendor=acorn
    				;;
    			*-sunos* | *-solaris*)
    				vendor=sun
    				;;
    			*-cnk* | *-aix*)
    				vendor=ibm
    				;;
    			*-beos*)
    				vendor=be
    				;;
    			*-hpux*)
    				vendor=hp
    				;;
    			*-mpeix*)
    				vendor=hp
    				;;
    			*-hiux*)
    				vendor=hitachi
    				;;
    			*-unos*)
    				vendor=crds
    				;;
    			*-dgux*)
    				vendor=dg
    				;;
    			*-luna*)
    				vendor=omron
    				;;
    			*-genix*)
    				vendor=ns
    				;;
    			*-clix*)
    				vendor=intergraph
    				;;
    			*-mvs* | *-opened*)
    				vendor=ibm
    				;;
    			*-os400*)
    				vendor=ibm
    				;;
    			s390-* | s390x-*)
    				vendor=ibm
    				;;
    			*-ptx*)
    				vendor=sequent
    				;;
    			*-tpf*)
    				vendor=ibm
    				;;
    			*-vxsim* | *-vxworks* | *-windiss*)
    				vendor=wrs
    				;;
    			*-aux*)
    				vendor=apple
    				;;
    			*-hms*)
    				vendor=hitachi
    				;;
    			*-mpw* | *-macos*)
    				vendor=apple
    				;;
    			*-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
    				vendor=atari
    				;;
    			*-vos*)
    				vendor=stratus
    				;;
    		esac
    		;;
    esac
    
    echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
    exit
    
    # Local variables:
    # eval: (add-hook 'before-save-hook 'time-stamp)
    # time-stamp-start: "timestamp='"
    # time-stamp-format: "%:y-%02m-%02d"
    # time-stamp-end: "'"
    # End:
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/apr_common.m4��������������������������������������������������������������������0000664�0001751�0001751�00000066061�15032766624�016341� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl -------------------------------------------------------- -*- autoconf -*-
    dnl Licensed to the Apache Software Foundation (ASF) under one or more
    dnl contributor license agreements.  See the NOTICE file distributed with
    dnl this work for additional information regarding copyright ownership.
    dnl The ASF licenses this file to You under the Apache License, Version 2.0
    dnl (the "License"); you may not use this file except in compliance with
    dnl the License.  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.
    
    dnl
    dnl apr_common.m4: APR's general-purpose autoconf macros
    dnl
    
    dnl
    dnl APR_CONFIG_NICE(filename)
    dnl
    dnl Saves a snapshot of the configure command-line for later reuse
    dnl
    AC_DEFUN([APR_CONFIG_NICE], [
      rm -f $1
      cat >$1<<EOF
    #! /bin/sh
    #
    # Created by configure
    
    EOF
      if test -n "$CC"; then
        echo "CC=\"$CC\"; export CC" >> $1
      fi
      if test -n "$CFLAGS"; then
        echo "CFLAGS=\"$CFLAGS\"; export CFLAGS" >> $1
      fi
      if test -n "$CPPFLAGS"; then
        echo "CPPFLAGS=\"$CPPFLAGS\"; export CPPFLAGS" >> $1
      fi
      if test -n "$LDFLAGS"; then
        echo "LDFLAGS=\"$LDFLAGS\"; export LDFLAGS" >> $1
      fi
      if test -n "$LTFLAGS"; then
        echo "LTFLAGS=\"$LTFLAGS\"; export LTFLAGS" >> $1
      fi
      if test -n "$LIBS"; then
        echo "LIBS=\"$LIBS\"; export LIBS" >> $1
      fi
      if test -n "$INCLUDES"; then
        echo "INCLUDES=\"$INCLUDES\"; export INCLUDES" >> $1
      fi
      if test -n "$NOTEST_CFLAGS"; then
        echo "NOTEST_CFLAGS=\"$NOTEST_CFLAGS\"; export NOTEST_CFLAGS" >> $1
      fi
      if test -n "$NOTEST_CPPFLAGS"; then
        echo "NOTEST_CPPFLAGS=\"$NOTEST_CPPFLAGS\"; export NOTEST_CPPFLAGS" >> $1
      fi
      if test -n "$NOTEST_LDFLAGS"; then
        echo "NOTEST_LDFLAGS=\"$NOTEST_LDFLAGS\"; export NOTEST_LDFLAGS" >> $1
      fi
      if test -n "$NOTEST_LIBS"; then
        echo "NOTEST_LIBS=\"$NOTEST_LIBS\"; export NOTEST_LIBS" >> $1
      fi
    
      # Retrieve command-line arguments.
      eval "set x $[0] $ac_configure_args"
      shift
    
      for arg
      do
        APR_EXPAND_VAR(arg, $arg)
        echo "\"[$]arg\" \\" >> $1
      done
      echo '"[$]@"' >> $1
      chmod +x $1
    ])dnl
    
    dnl APR_MKDIR_P_CHECK(fallback-mkdir-p)
    dnl checks whether mkdir -p works
    AC_DEFUN([APR_MKDIR_P_CHECK], [
      AC_CACHE_CHECK(for working mkdir -p, ac_cv_mkdir_p,[
        test -d conftestdir && rm -rf conftestdir
        mkdir -p conftestdir/somedir >/dev/null 2>&1
        if test -d conftestdir/somedir; then
          ac_cv_mkdir_p=yes
        else
          ac_cv_mkdir_p=no
        fi
        rm -rf conftestdir
      ])
      if test "$ac_cv_mkdir_p" = "yes"; then
          mkdir_p="mkdir -p"
      else
          mkdir_p="$1"
      fi
    ])
    
    dnl
    dnl APR_SUBDIR_CONFIG(dir [, sub-package-cmdline-args, args-to-drop])
    dnl
    dnl dir: directory to find configure in
    dnl sub-package-cmdline-args: arguments to add to the invocation (optional)
    dnl args-to-drop: arguments to drop from the invocation (optional)
    dnl
    dnl Note: This macro relies on ac_configure_args being set properly.
    dnl
    dnl The args-to-drop argument is shoved into a case statement, so
    dnl multiple arguments can be separated with a |.
    dnl
    dnl Note: Older versions of autoconf do not single-quote args, while 2.54+
    dnl places quotes around every argument.  So, if you want to drop the
    dnl argument called --enable-layout, you must pass the third argument as:
    dnl [--enable-layout=*|\'--enable-layout=*]
    dnl
    dnl Trying to optimize this is left as an exercise to the reader who wants
    dnl to put up with more autoconf craziness.  I give up.
    dnl
    AC_DEFUN([APR_SUBDIR_CONFIG], [
      # save our work to this point; this allows the sub-package to use it
      AC_CACHE_SAVE
    
      echo "configuring package in $1 now"
      ac_popdir=`pwd`
      apr_config_subdirs="$1"
      test -d $1 || $mkdir_p $1
      ac_abs_srcdir=`(cd $srcdir/$1 && pwd)`
      cd $1
    
    changequote(, )dnl
          # A "../" for each directory in /$config_subdirs.
          ac_dots=`echo $apr_config_subdirs|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
    changequote([, ])dnl
    
      # Make the cache file pathname absolute for the subdirs
      # required to correctly handle subdirs that might actually
      # be symlinks
      case "$cache_file" in
      /*) # already absolute
        ac_sub_cache_file=$cache_file ;;
      *)  # Was relative path.
        ac_sub_cache_file="$ac_popdir/$cache_file" ;;
      esac
    
      ifelse($3, [], [apr_configure_args=$ac_configure_args],[
      apr_configure_args=
      apr_sep=
      for apr_configure_arg in $ac_configure_args
      do
        case "$apr_configure_arg" in
          $3)
            continue ;;
        esac
        apr_configure_args="$apr_configure_args$apr_sep'$apr_configure_arg'"
        apr_sep=" "
      done
      ])
    
      dnl autoconf doesn't add --silent to ac_configure_args; explicitly pass it
      test "x$silent" = "xyes" && apr_configure_args="$apr_configure_args --silent"
    
      dnl AC_CONFIG_SUBDIRS silences option warnings, emulate this for 2.62
      apr_configure_args="--disable-option-checking $apr_configure_args" 
    
      dnl The eval makes quoting arguments work - specifically the second argument
      dnl where the quoting mechanisms used is "" rather than [].
      dnl
      dnl We need to execute another shell because some autoconf/shell combinations
      dnl will choke after doing repeated APR_SUBDIR_CONFIG()s.  (Namely Solaris
      dnl and autoconf-2.54+)
      if eval $SHELL $ac_abs_srcdir/configure $apr_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_abs_srcdir $2
      then :
        echo "$1 configured properly"
      else
        echo "configure failed for $1"
        exit 1
      fi
    
      cd $ac_popdir
    
      # grab any updates from the sub-package
      AC_CACHE_LOAD
    ])dnl
    
    dnl
    dnl APR_SAVE_THE_ENVIRONMENT(variable_name)
    dnl
    dnl Stores the variable (usually a Makefile macro) for later restoration
    dnl
    AC_DEFUN([APR_SAVE_THE_ENVIRONMENT], [
      apr_ste_save_$1="$$1"
    ])dnl
    
    dnl
    dnl APR_RESTORE_THE_ENVIRONMENT(variable_name, prefix_)
    dnl
    dnl Uses the previously saved variable content to figure out what configure
    dnl has added to the variable, moving the new bits to prefix_variable_name
    dnl and restoring the original variable contents.  This makes it possible
    dnl for a user to override configure when it does something stupid.
    dnl
    AC_DEFUN([APR_RESTORE_THE_ENVIRONMENT], [
    dnl Check whether $apr_ste_save_$1 is empty or
    dnl only whitespace. The verbatim "X" is token number 1,
    dnl the following whitespace will be ignored.
    set X $apr_ste_save_$1
    if test ${#} -eq 1; then
      $2$1="$$1"
      $1=
    else
      if test "x$apr_ste_save_$1" = "x$$1"; then
        $2$1=
      else
        $2$1=`echo "$$1" | sed -e "s%${apr_ste_save_$1}%%"`
        $1="$apr_ste_save_$1"
      fi
    fi
    if test "x$silent" != "xyes"; then
      echo "  restoring $1 to \"$$1\""
      echo "  setting $2$1 to \"$$2$1\""
    fi
    AC_SUBST($2$1)
    ])dnl
    
    dnl
    dnl APR_SETIFNULL(variable, value)
    dnl
    dnl  Set variable iff it's currently null
    dnl
    AC_DEFUN([APR_SETIFNULL], [
      if test -z "$$1"; then
        test "x$silent" != "xyes" && echo "  setting $1 to \"$2\""
        $1="$2"
      fi
    ])dnl
    
    dnl
    dnl APR_SETVAR(variable, value)
    dnl
    dnl  Set variable no matter what
    dnl
    AC_DEFUN([APR_SETVAR], [
      test "x$silent" != "xyes" && echo "  forcing $1 to \"$2\""
      $1="$2"
    ])dnl
    
    dnl
    dnl APR_ADDTO(variable, value)
    dnl
    dnl  Add value to variable
    dnl
    AC_DEFUN([APR_ADDTO], [
      if test "x$$1" = "x"; then
        test "x$silent" != "xyes" && echo "  setting $1 to \"$2\""
        $1="$2"
      else
        apr_addto_bugger="$2"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $$1; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to $1"
            $1="$$1 $i"
          fi
        done
      fi
    ])dnl
    
    dnl
    dnl APR_REMOVEFROM(variable, value)
    dnl
    dnl Remove a value from a variable
    dnl
    AC_DEFUN([APR_REMOVEFROM], [
      if test "x$$1" = "x$2"; then
        test "x$silent" != "xyes" && echo "  nulling $1"
        $1=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $$1; do
          if test "x$i" != "x$2"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"$2\" from $1"
          $1=$apr_new_bugger
        fi
      fi
    ]) dnl
    
    dnl
    dnl APR_CHECK_DEFINE_FILES( symbol, header_file [header_file ...] )
    dnl
    AC_DEFUN([APR_CHECK_DEFINE_FILES], [
      AC_CACHE_CHECK([for $1 in $2],ac_cv_define_$1,[
        ac_cv_define_$1=no
        for curhdr in $2
        do
          AC_EGREP_CPP(YES_IS_DEFINED, [
    #include <$curhdr>
    #ifdef $1
    YES_IS_DEFINED
    #endif
          ], ac_cv_define_$1=yes)
        done
      ])
      if test "$ac_cv_define_$1" = "yes"; then
        AC_DEFINE(HAVE_$1, 1, [Define if $1 is defined])
      fi
    ])
    
    
    dnl
    dnl APR_CHECK_DEFINE(symbol, header_file)
    dnl
    AC_DEFUN([APR_CHECK_DEFINE], [
      AC_CACHE_CHECK([for $1 in $2],ac_cv_define_$1,[
        AC_EGREP_CPP(YES_IS_DEFINED, [
    #include <$2>
    #ifdef $1
    YES_IS_DEFINED
    #endif
        ], ac_cv_define_$1=yes, ac_cv_define_$1=no)
      ])
      if test "$ac_cv_define_$1" = "yes"; then
        AC_DEFINE(HAVE_$1, 1, [Define if $1 is defined in $2])
      fi
    ])
    
    dnl
    dnl APR_CHECK_APR_DEFINE( symbol )
    dnl
    AC_DEFUN([APR_CHECK_APR_DEFINE], [
    apr_old_cppflags=$CPPFLAGS
    CPPFLAGS="$CPPFLAGS $INCLUDES"
    AC_EGREP_CPP(YES_IS_DEFINED, [
    #include <apr.h>
    #if $1
    YES_IS_DEFINED
    #endif
    ], ac_cv_define_$1=yes, ac_cv_define_$1=no)
    CPPFLAGS=$apr_old_cppflags
    ])
    
    dnl APR_CHECK_FILE(filename); set ac_cv_file_filename to
    dnl "yes" if 'filename' is readable, else "no".
    dnl @deprecated! - use AC_CHECK_FILE instead
    AC_DEFUN([APR_CHECK_FILE], [
    dnl Pick a safe variable name
    define([apr_cvname], ac_cv_file_[]translit([$1], [./+-], [__p_]))
    AC_CACHE_CHECK([for $1], [apr_cvname],
    [if test -r $1; then
       apr_cvname=yes
     else
       apr_cvname=no
     fi])
    ])
    
    define(APR_IFALLYES,[dnl
    ac_rc=yes
    for ac_spec in $1; do
        ac_type=`echo "$ac_spec" | sed -e 's/:.*$//'`
        ac_item=`echo "$ac_spec" | sed -e 's/^.*://'`
        case $ac_type in
            header )
                ac_item=`echo "$ac_item" | sed 'y%./+-%__p_%'`
                ac_var="ac_cv_header_$ac_item"
                ;;
            file )
                ac_item=`echo "$ac_item" | sed 'y%./+-%__p_%'`
                ac_var="ac_cv_file_$ac_item"
                ;;
            func )   ac_var="ac_cv_func_$ac_item"   ;;
            struct ) ac_var="ac_cv_struct_$ac_item" ;;
            define ) ac_var="ac_cv_define_$ac_item" ;;
            custom ) ac_var="$ac_item" ;;
        esac
        eval "ac_val=\$$ac_var"
        if test ".$ac_val" != .yes; then
            ac_rc=no
            break
        fi
    done
    if test ".$ac_rc" = .yes; then
        :
        $2
    else
        :
        $3
    fi
    ])
    
    
    define(APR_BEGIN_DECISION,[dnl
    ac_decision_item='$1'
    ac_decision_msg='FAILED'
    ac_decision=''
    ])
    
    
    AC_DEFUN([APR_DECIDE],[dnl
    dnl Define the flag (or not) in apr_private.h via autoheader
    AH_TEMPLATE($1, [Define if $2 will be used])
    ac_decision='$1'
    ac_decision_msg='$2'
    ac_decision_$1=yes
    ac_decision_$1_msg='$2'
    ])
    
    
    define(APR_DECISION_OVERRIDE,[dnl
        ac_decision=''
        for ac_item in $1; do
             eval "ac_decision_this=\$ac_decision_${ac_item}"
             if test ".$ac_decision_this" = .yes; then
                 ac_decision=$ac_item
                 eval "ac_decision_msg=\$ac_decision_${ac_item}_msg"
             fi
        done
    ])
    
    
    define(APR_DECISION_FORCE,[dnl
    ac_decision="$1"
    eval "ac_decision_msg=\"\$ac_decision_${ac_decision}_msg\""
    ])
    
    
    define(APR_END_DECISION,[dnl
    if test ".$ac_decision" = .; then
        echo "[$]0:Error: decision on $ac_decision_item failed" 1>&2
        exit 1
    else
        if test ".$ac_decision_msg" = .; then
            ac_decision_msg="$ac_decision"
        fi
        AC_DEFINE_UNQUOTED(${ac_decision_item})
        AC_MSG_RESULT([decision on $ac_decision_item... $ac_decision_msg])
    fi
    ])
    
    
    dnl
    dnl APR_TRY_COMPILE_NO_WARNING(INCLUDES, FUNCTION-BODY,
    dnl             [ACTIONS-IF-NO-WARNINGS], [ACTIONS-IF-WARNINGS])
    dnl
    dnl Tries a compile test with warnings activated so that the result
    dnl is false if the code doesn't compile cleanly.  For compilers
    dnl where it is not known how to activate a "fail-on-error" mode,
    dnl it is undefined which of the sets of actions will be run.
    dnl
    AC_DEFUN([APR_TRY_COMPILE_NO_WARNING],
    [apr_save_CFLAGS=$CFLAGS
     CFLAGS="$CFLAGS $CFLAGS_WARN"
     if test "$ac_cv_prog_gcc" = "yes"; then 
       CFLAGS="$CFLAGS -Werror"
     fi
     AC_COMPILE_IFELSE(
      [AC_LANG_SOURCE(
       [
    #ifndef PACKAGE_NAME
    #include "confdefs.h"
    #endif
       ]
       [[$1]]
       [int main(int argc, const char *const *argv) {]
       [[$2]]
       [   return 0; }]
      )], [CFLAGS=$apr_save_CFLAGS
    $3],  [CFLAGS=$apr_save_CFLAGS
    $4])
    ])
    
    dnl
    dnl APR_CHECK_STRERROR_R_RC
    dnl
    dnl  Decide which style of retcode is used by this system's 
    dnl  strerror_r().  It either returns int (0 for success, -1
    dnl  for failure), or it returns a pointer to the error 
    dnl  string.
    dnl
    dnl
    AC_DEFUN([APR_CHECK_STRERROR_R_RC], [
    AC_CACHE_CHECK([whether return code from strerror_r has type int],
    [ac_cv_strerror_r_rc_int],
    [AC_TRY_RUN([
    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
      char buf[1024];
      if (strerror_r(ERANGE, buf, sizeof buf) < 1) {
        exit(0);
      }
      else {
        exit(1);
      }
    }], [
        ac_cv_strerror_r_rc_int=yes ], [
        ac_cv_strerror_r_rc_int=no ], [
        ac_cv_strerror_r_rc_int=no ] ) ] )
    if test "x$ac_cv_strerror_r_rc_int" = xyes; then
      AC_DEFINE(STRERROR_R_RC_INT, 1, [Define if strerror returns int])
    fi
    ] )
    
    dnl
    dnl APR_CHECK_DIRENT_INODE
    dnl
    dnl  Decide if d_fileno or d_ino are available in the dirent
    dnl  structure on this platform.  Single UNIX Spec says d_ino,
    dnl  BSD uses d_fileno.  Undef to find the real beast.
    dnl
    AC_DEFUN([APR_CHECK_DIRENT_INODE], [
    AC_CACHE_CHECK([for inode member of struct dirent], apr_cv_dirent_inode, [
    apr_cv_dirent_inode=no
    AC_TRY_COMPILE([
    #include <sys/types.h>
    #include <dirent.h>
    ],[
    #ifdef d_ino
    #undef d_ino
    #endif
    struct dirent de; de.d_fileno;
    ], apr_cv_dirent_inode=d_fileno)
    if test "$apr_cv_dirent_inode" = "no"; then
    AC_TRY_COMPILE([
    #include <sys/types.h>
    #include <dirent.h>
    ],[
    #ifdef d_fileno
    #undef d_fileno
    #endif
    struct dirent de; de.d_ino;
    ], apr_cv_dirent_inode=d_ino)
    fi
    ])
    if test "$apr_cv_dirent_inode" != "no"; then
      AC_DEFINE_UNQUOTED(DIRENT_INODE, $apr_cv_dirent_inode, 
        [Define if struct dirent has an inode member])
    fi
    ])
    
    dnl
    dnl APR_CHECK_DIRENT_TYPE
    dnl
    dnl  Decide if d_type is available in the dirent structure 
    dnl  on this platform.  Not part of the Single UNIX Spec.
    dnl  Note that this is worthless without DT_xxx macros, so
    dnl  look for one while we are at it.
    dnl
    AC_DEFUN([APR_CHECK_DIRENT_TYPE], [
    AC_CACHE_CHECK([for file type member of struct dirent], apr_cv_dirent_type,[
    apr_cv_dirent_type=no
    AC_TRY_COMPILE([
    #include <sys/types.h>
    #include <dirent.h>
    ],[
    struct dirent de; de.d_type = DT_REG;
    ], apr_cv_dirent_type=d_type)
    ])
    if test "$apr_cv_dirent_type" != "no"; then
      AC_DEFINE_UNQUOTED(DIRENT_TYPE, $apr_cv_dirent_type, 
        [Define if struct dirent has a d_type member]) 
    fi
    ])
    
    dnl the following is a newline, a space, a tab, and a backslash (the
    dnl backslash is used by the shell to skip newlines, but m4 sees it;
    dnl treat it like whitespace).
    dnl WARNING: don't reindent these lines, or the space/tab will be lost!
    define([apr_whitespace],[
     	\])
    
    dnl
    dnl APR_COMMA_ARGS(ARG1 ...)
    dnl  convert the whitespace-separated arguments into comman-separated
    dnl  arguments.
    dnl
    dnl APR_FOREACH(CODE-BLOCK, ARG1, ARG2, ...)
    dnl  subsitute CODE-BLOCK for each ARG[i]. "eachval" will be set to ARG[i]
    dnl  within each iteration.
    dnl
    changequote({,})
    define({APR_COMMA_ARGS},{patsubst([$}{1],[[}apr_whitespace{]+],[,])})
    define({APR_FOREACH},
      {ifelse($}{2,,,
              [define([eachval],
                      $}{2)$}{1[]APR_FOREACH([$}{1],
                                             builtin([shift],
                                                     builtin([shift], $}{@)))])})
    changequote([,])
    
    dnl APR_FLAG_HEADERS(HEADER-FILE ... [, FLAG-TO-SET ] [, "yes" ])
    dnl  we set FLAG-TO-SET to 1 if we find HEADER-FILE, otherwise we set to 0
    dnl  if FLAG-TO-SET is null, we automagically determine it's name
    dnl  by changing all "/" to "_" in the HEADER-FILE and dropping
    dnl  all "." and "-" chars. If the 3rd parameter is "yes" then instead of
    dnl  setting to 1 or 0, we set FLAG-TO-SET to yes or no.
    dnl  
    AC_DEFUN([APR_FLAG_HEADERS], [
    AC_CHECK_HEADERS($1)
    for aprt_i in $1
    do
        ac_safe=`echo "$aprt_i" | sed 'y%./+-%__p_%'`
        aprt_2=`echo "$aprt_i" | sed -e 's%/%_%g' -e 's/\.//g' -e 's/-//g'`
        if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
           eval "ifelse($2,,$aprt_2,$2)=ifelse($3,yes,yes,1)"
        else
           eval "ifelse($2,,$aprt_2,$2)=ifelse($3,yes,no,0)"
        fi
    done
    ])
    
    dnl APR_FLAG_FUNCS(FUNC ... [, FLAG-TO-SET] [, "yes" ])
    dnl  if FLAG-TO-SET is null, we automagically determine it's name
    dnl  prepending "have_" to the function name in FUNC, otherwise
    dnl  we use what's provided as FLAG-TO-SET. If the 3rd parameter
    dnl  is "yes" then instead of setting to 1 or 0, we set FLAG-TO-SET
    dnl  to yes or no.
    dnl
    AC_DEFUN([APR_FLAG_FUNCS], [
    AC_CHECK_FUNCS($1)
    for aprt_j in $1
    do
        aprt_3="have_$aprt_j"
        if eval "test \"`echo '$ac_cv_func_'$aprt_j`\" = yes"; then
           eval "ifelse($2,,$aprt_3,$2)=ifelse($3,yes,yes,1)"
        else
           eval "ifelse($2,,$aprt_3,$2)=ifelse($3,yes,no,0)"
        fi
    done
    ])
    
    dnl Iteratively interpolate the contents of the second argument
    dnl until interpolation offers no new result. Then assign the
    dnl final result to $1.
    dnl
    dnl Example:
    dnl
    dnl foo=1
    dnl bar='${foo}/2'
    dnl baz='${bar}/3'
    dnl APR_EXPAND_VAR(fraz, $baz)
    dnl   $fraz is now "1/2/3"
    dnl 
    AC_DEFUN([APR_EXPAND_VAR], [
    ap_last=
    ap_cur="$2"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    $1="${ap_cur}"
    ])
    
    dnl
    dnl Removes the value of $3 from the string in $2, strips of any leading
    dnl slashes, and returns the value in $1.
    dnl
    dnl Example:
    dnl orig_path="${prefix}/bar"
    dnl APR_PATH_RELATIVE(final_path, $orig_path, $prefix)
    dnl    $final_path now contains "bar"
    AC_DEFUN([APR_PATH_RELATIVE], [
    ap_stripped=`echo $2 | sed -e "s#^$3##"`
    # check if the stripping was successful
    if test "x$2" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        $1="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        $1="$2"
    fi
    ])
    
    dnl APR_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.  When using this macro with a multi-line RHS, ensure
    dnl that you surround the macro invocation with []s
    AC_DEFUN([APR_HELP_STRING], [ifelse(regexp(AC_ACVERSION, 2\.1), -1, AC_HELP_STRING([$1],[$2]),[  ][$1] substr([                       ],len($1))[$2])])
    
    dnl
    dnl APR_LAYOUT(configlayout, layoutname [, extravars])
    dnl
    AC_DEFUN([APR_LAYOUT], [
      if test ! -f $srcdir/config.layout; then
        echo "** Error: Layout file $srcdir/config.layout not found"
        echo "** Error: Cannot use undefined layout '$LAYOUT'"
        exit 1
      fi
      # Catch layout names including a slash which will otherwise
      # confuse the heck out of the sed script.
      case $2 in
      */*) 
        echo "** Error: $2 is not a valid layout name"
        exit 1 ;;
      esac
      pldconf=./config.pld
      changequote({,})
      sed -e "1s/[ 	]*<[lL]ayout[ 	]*$2[ 	]*>[ 	]*//;1t" \
          -e "1,/[ 	]*<[lL]ayout[ 	]*$2[ 	]*>[ 	]*/d" \
          -e '/[ 	]*<\/Layout>[ 	]*/,$d' \
          -e "s/^[ 	]*//g" \
          -e "s/:[ 	]*/=\'/g" \
          -e "s/[ 	]*$/'/g" \
          $1 > $pldconf
      layout_name=$2
      if test ! -s $pldconf; then
        echo "** Error: unable to find layout $layout_name"
        exit 1
      fi
      . $pldconf
      rm $pldconf
      for var in prefix exec_prefix bindir sbindir libexecdir mandir \
                 sysconfdir datadir includedir localstatedir runtimedir \
                 logfiledir libdir installbuilddir libsuffix $3; do
        eval "val=\"\$$var\""
        case $val in
          *+)
            val=`echo $val | sed -e 's;\+$;;'`
            eval "$var=\"\$val\""
            autosuffix=yes
            ;;
          *)
            autosuffix=no
            ;;
        esac
        val=`echo $val | sed -e 's:\(.\)/*$:\1:'`
        val=`echo $val | sed -e 's:[\$]\([a-z_]*\):${\1}:g'`
        if test "$autosuffix" = "yes"; then
          if echo $val | grep apache >/dev/null; then
            addtarget=no
          else
            addtarget=yes
          fi
          if test "$addtarget" = "yes"; then
            val="$val/apache2"
          fi
        fi
        eval "$var='$val'"
      done
      changequote([,])
    ])dnl
    
    dnl
    dnl APR_ENABLE_LAYOUT(default layout name [, extra vars])
    dnl
    AC_DEFUN([APR_ENABLE_LAYOUT], [
    AC_ARG_ENABLE(layout,
    [  --enable-layout=LAYOUT],[
      LAYOUT=$enableval
    ])
    
    if test -z "$LAYOUT"; then
      LAYOUT="$1"
    fi
    APR_LAYOUT($srcdir/config.layout, $LAYOUT, $2)
    
    AC_MSG_CHECKING(for chosen layout)
    AC_MSG_RESULT($layout_name)
    ])
    
    
    dnl
    dnl APR_PARSE_ARGUMENTS
    dnl a reimplementation of autoconf's argument parser,
    dnl used here to allow us to co-exist layouts and argument based
    dnl set ups.
    AC_DEFUN([APR_PARSE_ARGUMENTS], [
    ac_prev=
    # Retrieve the command-line arguments.  The eval is needed because
    # the arguments are quoted to preserve accuracy.
    eval "set x $ac_configure_args"
    shift
    for ac_option
    do
      # If the previous option needs an argument, assign it.
      if test -n "$ac_prev"; then
        eval "$ac_prev=\$ac_option"
        ac_prev=
        continue
      fi
    
      ac_optarg=`expr "x$ac_option" : 'x[[^=]]*=\(.*\)'`
    
      case $ac_option in
    
      -bindir | --bindir | --bindi | --bind | --bin | --bi)
        ac_prev=bindir ;;
      -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
        bindir="$ac_optarg" ;;
    
      -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
        ac_prev=datadir ;;
      -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
      | --da=*)
        datadir="$ac_optarg" ;;
    
      -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
      | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
      | --exec | --exe | --ex)
        ac_prev=exec_prefix ;;
      -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
      | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
      | --exec=* | --exe=* | --ex=*)
        exec_prefix="$ac_optarg" ;;
    
      -includedir | --includedir | --includedi | --included | --include \
      | --includ | --inclu | --incl | --inc)
        ac_prev=includedir ;;
      -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
      | --includ=* | --inclu=* | --incl=* | --inc=*)
        includedir="$ac_optarg" ;;
    
      -infodir | --infodir | --infodi | --infod | --info | --inf)
        ac_prev=infodir ;;
      -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
        infodir="$ac_optarg" ;;
    
      -libdir | --libdir | --libdi | --libd)
        ac_prev=libdir ;;
      -libdir=* | --libdir=* | --libdi=* | --libd=*)
        libdir="$ac_optarg" ;;
    
      -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
      | --libexe | --libex | --libe)
        ac_prev=libexecdir ;;
      -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
      | --libexe=* | --libex=* | --libe=*)
        libexecdir="$ac_optarg" ;;
    
      -localstatedir | --localstatedir | --localstatedi | --localstated \
      | --localstate | --localstat | --localsta | --localst \
      | --locals | --local | --loca | --loc | --lo)
        ac_prev=localstatedir ;;
      -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
      | --localstate=* | --localstat=* | --localsta=* | --localst=* \
      | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
        localstatedir="$ac_optarg" ;;
    
      -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
        ac_prev=mandir ;;
      -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
        mandir="$ac_optarg" ;;
    
      -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
        ac_prev=prefix ;;
      -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
        prefix="$ac_optarg" ;;
    
      -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
        ac_prev=sbindir ;;
      -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
      | --sbi=* | --sb=*)
        sbindir="$ac_optarg" ;;
    
      -sharedstatedir | --sharedstatedir | --sharedstatedi \
      | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
      | --sharedst | --shareds | --shared | --share | --shar \
      | --sha | --sh)
        ac_prev=sharedstatedir ;;
      -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
      | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
      | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
      | --sha=* | --sh=*)
        sharedstatedir="$ac_optarg" ;;
    
      -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
      | --syscon | --sysco | --sysc | --sys | --sy)
        ac_prev=sysconfdir ;;
      -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
      | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
        sysconfdir="$ac_optarg" ;;
    
      esac
    done
    
    # Be sure to have absolute paths.
    for ac_var in exec_prefix prefix
    do
      eval ac_val=$`echo $ac_var`
      case $ac_val in
        [[\\/$]]* | ?:[[\\/]]* | NONE | '' ) ;;
        *)  AC_MSG_ERROR([expected an absolute path for --$ac_var: $ac_val]);;
      esac
    done
    
    ])dnl
    
    dnl
    dnl APR_CHECK_DEPEND
    dnl
    dnl Determine what program we can use to generate .deps-style dependencies
    dnl
    AC_DEFUN([APR_CHECK_DEPEND], [
    dnl Try to determine what depend program we can use
    dnl All GCC-variants should have -MM.
    dnl If not, then we can check on those, too.
    if test "$GCC" = "yes"; then
      MKDEP='$(CC) -MM'
    else
      rm -f conftest.c
    dnl <sys/types.h> should be available everywhere!
      cat > conftest.c <<EOF
    #include <sys/types.h>
      int main(int argc, const char *argv[]) { return 0; }
    EOF
      MKDEP="true"
      for i in "$CC -MM" "$CC -M" "$CPP -MM" "$CPP -M" "cpp -M"; do
        AC_MSG_CHECKING([if $i can create proper make dependencies])
        if $i conftest.c 2>/dev/null | grep 'conftest.o: conftest.c' >/dev/null; then
          MKDEP=$i
          AC_MSG_RESULT(yes)
          break;
        fi
        AC_MSG_RESULT(no)
      done
      rm -f conftest.c
    fi
    
    AC_SUBST(MKDEP)
    ])
    
    dnl
    dnl APR_CHECK_TYPES_FMT_COMPATIBLE(TYPE-1, TYPE-2, FMT-TAG, 
    dnl                                [ACTION-IF-TRUE], [ACTION-IF-FALSE])
    dnl
    dnl Try to determine whether two types are the same and accept the given
    dnl printf formatter (bare token, e.g. literal d, ld, etc).
    dnl
    AC_DEFUN([APR_CHECK_TYPES_FMT_COMPATIBLE], [
    define([apr_cvname], apr_cv_typematch_[]translit([$1], [ ], [_])_[]translit([$2], [ ], [_])_[][$3])
    AC_CACHE_CHECK([whether $1 and $2 use fmt %$3], apr_cvname, [
    APR_TRY_COMPILE_NO_WARNING([#include <sys/types.h>
    #include <stdio.h>
    #ifdef HAVE_STDINT_H
    #include <stdint.h>
    #endif
    ], [
        $1 chk1, *ptr1;
        $2 chk2, *ptr2 = &chk1;
        ptr1 = &chk2;
        *ptr1 = *ptr2 = 0;
        printf("%$3 %$3", chk1, chk2);
    ], [apr_cvname=yes], [apr_cvname=no])])
    if test "$apr_cvname" = "yes"; then
        :
        $4
    else
        :
        $5
    fi
    ])
    
    dnl
    dnl APR_CHECK_TYPES_COMPATIBLE(TYPE-1, TYPE-2, [ACTION-IF-TRUE])
    dnl
    dnl Try to determine whether two types are the same. Only works
    dnl for gcc and icc.
    dnl
    dnl @deprecated @see APR_CHECK_TYPES_FMT_COMPATIBLE
    dnl
    AC_DEFUN([APR_CHECK_TYPES_COMPATIBLE], [
    define([apr_cvname], apr_cv_typematch_[]translit([$1], [ ], [_])_[]translit([$2], [ ], [_]))
    AC_CACHE_CHECK([whether $1 and $2 are the same], apr_cvname, [
    AC_TRY_COMPILE(AC_INCLUDES_DEFAULT, [
        int foo[0 - !__builtin_types_compatible_p($1, $2)];
    ], [apr_cvname=yes
    $3], [apr_cvname=no])])
    ])
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/build/ltmain.sh������������������������������������������������������������������������0000755�0001751�0001751�00001212375�15032766624�015570� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /usr/bin/env sh
    ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
    ##               by inline-source v2019-02-19.15
    
    # libtool (GNU libtool) 2.4.7
    # Provide generalized library-building support services.
    # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
    
    # Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc.
    # This is free software; see the source for copying conditions.  There is NO
    # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    # GNU Libtool 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 of the License, or
    # (at your option) any later version.
    #
    # As a special exception to the GNU General Public License,
    # if you distribute this file as part of a program or library that
    # is built using GNU Libtool, you may include this file under the
    # same distribution terms that you use for the rest of that program.
    #
    # GNU Libtool 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, see <http://www.gnu.org/licenses/>.
    
    
    PROGRAM=libtool
    PACKAGE=libtool
    VERSION="2.4.7 Debian-2.4.7-7build1"
    package_revision=2.4.7
    
    
    ## ------ ##
    ## Usage. ##
    ## ------ ##
    
    # Run './libtool --help' for help with using this script from the
    # command line.
    
    
    ## ------------------------------- ##
    ## User overridable command paths. ##
    ## ------------------------------- ##
    
    # After configure completes, it has a better idea of some of the
    # shell tools we need than the defaults used by the functions shared
    # with bootstrap, so set those here where they can still be over-
    # ridden by the user, but otherwise take precedence.
    
    : ${AUTOCONF="autoconf"}
    : ${AUTOMAKE="automake"}
    
    
    ## -------------------------- ##
    ## Source external libraries. ##
    ## -------------------------- ##
    
    # Much of our low-level functionality needs to be sourced from external
    # libraries, which are installed to $pkgauxdir.
    
    # Set a version string for this script.
    scriptversion=2019-02-19.15; # UTC
    
    # General shell script boiler plate, and helper functions.
    # Written by Gary V. Vaughan, 2004
    
    # This is free software.  There is NO warranty; not even for
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    #
    # Copyright (C) 2004-2019, 2021 Bootstrap Authors
    #
    # This file is dual licensed under the terms of the MIT license
    # <https://opensource.org/license/MIT>, and GPL version 2 or later
    # <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
    # these licenses when using or redistributing this software or any of
    # the files within it.  See the URLs above, or the file `LICENSE`
    # included in the Bootstrap distribution for the full license texts.
    
    # Please report bugs or propose patches to:
    # <https://github.com/gnulib-modules/bootstrap/issues>
    
    
    ## ------ ##
    ## Usage. ##
    ## ------ ##
    
    # Evaluate this file near the top of your script to gain access to
    # the functions and variables defined here:
    #
    #   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
    #
    # If you need to override any of the default environment variable
    # settings, do that before evaluating this file.
    
    
    ## -------------------- ##
    ## Shell normalisation. ##
    ## -------------------- ##
    
    # Some shells need a little help to be as Bourne compatible as possible.
    # Before doing anything else, make sure all that help has been provided!
    
    DUALCASE=1; export DUALCASE # for MKS sh
    if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
      emulate sh
      NULLCMD=:
      # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
      # is contrary to our usage.  Disable this feature.
      alias -g '${1+"$@"}'='"$@"'
      setopt NO_GLOB_SUBST
    else
      case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
    fi
    
    # NLS nuisances: We save the old values in case they are required later.
    _G_user_locale=
    _G_safe_locale=
    for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
    do
      eval "if test set = \"\${$_G_var+set}\"; then
              save_$_G_var=\$$_G_var
              $_G_var=C
    	  export $_G_var
    	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
    	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
    	fi"
    done
    # These NLS vars are set unconditionally (bootstrap issue #24).  Unset those
    # in case the environment reset is needed later and the $save_* variant is not
    # defined (see the code above).
    LC_ALL=C
    LANGUAGE=C
    export LANGUAGE LC_ALL
    
    # Make sure IFS has a sensible default
    sp=' '
    nl='
    '
    IFS="$sp	$nl"
    
    # There are apparently some retarded systems that use ';' as a PATH separator!
    if test "${PATH_SEPARATOR+set}" != set; then
      PATH_SEPARATOR=:
      (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
        (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
          PATH_SEPARATOR=';'
      }
    fi
    
    
    # func_unset VAR
    # --------------
    # Portably unset VAR.
    # In some shells, an 'unset VAR' statement leaves a non-zero return
    # status if VAR is already unset, which might be problematic if the
    # statement is used at the end of a function (thus poisoning its return
    # value) or when 'set -e' is active (causing even a spurious abort of
    # the script in this case).
    func_unset ()
    {
        { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }
    }
    
    
    # Make sure CDPATH doesn't cause `cd` commands to output the target dir.
    func_unset CDPATH
    
    # Make sure ${,E,F}GREP behave sanely.
    func_unset GREP_OPTIONS
    
    
    ## ------------------------- ##
    ## Locate command utilities. ##
    ## ------------------------- ##
    
    
    # func_executable_p FILE
    # ----------------------
    # Check that FILE is an executable regular file.
    func_executable_p ()
    {
        test -f "$1" && test -x "$1"
    }
    
    
    # func_path_progs PROGS_LIST CHECK_FUNC [PATH]
    # --------------------------------------------
    # Search for either a program that responds to --version with output
    # containing "GNU", or else returned by CHECK_FUNC otherwise, by
    # trying all the directories in PATH with each of the elements of
    # PROGS_LIST.
    #
    # CHECK_FUNC should accept the path to a candidate program, and
    # set $func_check_prog_result if it truncates its output less than
    # $_G_path_prog_max characters.
    func_path_progs ()
    {
        _G_progs_list=$1
        _G_check_func=$2
        _G_PATH=${3-"$PATH"}
    
        _G_path_prog_max=0
        _G_path_prog_found=false
        _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
        for _G_dir in $_G_PATH; do
          IFS=$_G_save_IFS
          test -z "$_G_dir" && _G_dir=.
          for _G_prog_name in $_G_progs_list; do
            for _exeext in '' .EXE; do
              _G_path_prog=$_G_dir/$_G_prog_name$_exeext
              func_executable_p "$_G_path_prog" || continue
              case `"$_G_path_prog" --version 2>&1` in
                *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
                *)     $_G_check_func $_G_path_prog
    		   func_path_progs_result=$func_check_prog_result
    		   ;;
              esac
              $_G_path_prog_found && break 3
            done
          done
        done
        IFS=$_G_save_IFS
        test -z "$func_path_progs_result" && {
          echo "no acceptable sed could be found in \$PATH" >&2
          exit 1
        }
    }
    
    
    # We want to be able to use the functions in this file before configure
    # has figured out where the best binaries are kept, which means we have
    # to search for them ourselves - except when the results are already set
    # where we skip the searches.
    
    # Unless the user overrides by setting SED, search the path for either GNU
    # sed, or the sed that truncates its output the least.
    test -z "$SED" && {
      _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
      for _G_i in 1 2 3 4 5 6 7; do
        _G_sed_script=$_G_sed_script$nl$_G_sed_script
      done
      echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
      _G_sed_script=
    
      func_check_prog_sed ()
      {
        _G_path_prog=$1
    
        _G_count=0
        printf 0123456789 >conftest.in
        while :
        do
          cat conftest.in conftest.in >conftest.tmp
          mv conftest.tmp conftest.in
          cp conftest.in conftest.nl
          echo '' >> conftest.nl
          "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
          diff conftest.out conftest.nl >/dev/null 2>&1 || break
          _G_count=`expr $_G_count + 1`
          if test "$_G_count" -gt "$_G_path_prog_max"; then
            # Best one so far, save it but keep looking for a better one
            func_check_prog_result=$_G_path_prog
            _G_path_prog_max=$_G_count
          fi
          # 10*(2^10) chars as input seems more than enough
          test 10 -lt "$_G_count" && break
        done
        rm -f conftest.in conftest.tmp conftest.nl conftest.out
      }
    
      func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"
      rm -f conftest.sed
      SED=$func_path_progs_result
    }
    
    
    # Unless the user overrides by setting GREP, search the path for either GNU
    # grep, or the grep that truncates its output the least.
    test -z "$GREP" && {
      func_check_prog_grep ()
      {
        _G_path_prog=$1
    
        _G_count=0
        _G_path_prog_max=0
        printf 0123456789 >conftest.in
        while :
        do
          cat conftest.in conftest.in >conftest.tmp
          mv conftest.tmp conftest.in
          cp conftest.in conftest.nl
          echo 'GREP' >> conftest.nl
          "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
          diff conftest.out conftest.nl >/dev/null 2>&1 || break
          _G_count=`expr $_G_count + 1`
          if test "$_G_count" -gt "$_G_path_prog_max"; then
            # Best one so far, save it but keep looking for a better one
            func_check_prog_result=$_G_path_prog
            _G_path_prog_max=$_G_count
          fi
          # 10*(2^10) chars as input seems more than enough
          test 10 -lt "$_G_count" && break
        done
        rm -f conftest.in conftest.tmp conftest.nl conftest.out
      }
    
      func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"
      GREP=$func_path_progs_result
    }
    
    
    ## ------------------------------- ##
    ## User overridable command paths. ##
    ## ------------------------------- ##
    
    # All uppercase variable names are used for environment variables.  These
    # variables can be overridden by the user before calling a script that
    # uses them if a suitable command of that name is not already available
    # in the command search PATH.
    
    : ${CP="cp -f"}
    : ${ECHO="printf %s\n"}
    : ${EGREP="$GREP -E"}
    : ${FGREP="$GREP -F"}
    : ${LN_S="ln -s"}
    : ${MAKE="make"}
    : ${MKDIR="mkdir"}
    : ${MV="mv -f"}
    : ${RM="rm -f"}
    : ${SHELL="${CONFIG_SHELL-/bin/sh}"}
    
    
    ## -------------------- ##
    ## Useful sed snippets. ##
    ## -------------------- ##
    
    sed_dirname='s|/[^/]*$||'
    sed_basename='s|^.*/||'
    
    # Sed substitution that helps us do robust quoting.  It backslashifies
    # metacharacters that are still active within double-quoted strings.
    sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
    
    # Same as above, but do not quote variable references.
    sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
    
    # Sed substitution that turns a string into a regex matching for the
    # string literally.
    sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
    
    # Sed substitution that converts a w32 file name or path
    # that contains forward slashes, into one that contains
    # (escaped) backslashes.  A very naive implementation.
    sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
    
    # Re-'\' parameter expansions in output of sed_double_quote_subst that
    # were '\'-ed in input to the same.  If an odd number of '\' preceded a
    # '$' in input to sed_double_quote_subst, that '$' was protected from
    # expansion.  Since each input '\' is now two '\'s, look for any number
    # of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
    _G_bs='\\'
    _G_bs2='\\\\'
    _G_bs4='\\\\\\\\'
    _G_dollar='\$'
    sed_double_backslash="\
      s/$_G_bs4/&\\
    /g
      s/^$_G_bs2$_G_dollar/$_G_bs&/
      s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
      s/\n//g"
    
    # require_check_ifs_backslash
    # ---------------------------
    # Check if we can use backslash as IFS='\' separator, and set
    # $check_ifs_backshlash_broken to ':' or 'false'.
    require_check_ifs_backslash=func_require_check_ifs_backslash
    func_require_check_ifs_backslash ()
    {
      _G_save_IFS=$IFS
      IFS='\'
      _G_check_ifs_backshlash='a\\b'
      for _G_i in $_G_check_ifs_backshlash
      do
      case $_G_i in
      a)
        check_ifs_backshlash_broken=false
        ;;
      '')
        break
        ;;
      *)
        check_ifs_backshlash_broken=:
        break
        ;;
      esac
      done
      IFS=$_G_save_IFS
      require_check_ifs_backslash=:
    }
    
    
    ## ----------------- ##
    ## Global variables. ##
    ## ----------------- ##
    
    # Except for the global variables explicitly listed below, the following
    # functions in the '^func_' namespace, and the '^require_' namespace
    # variables initialised in the 'Resource management' section, sourcing
    # this file will not pollute your global namespace with anything
    # else. There's no portable way to scope variables in Bourne shell
    # though, so actually running these functions will sometimes place
    # results into a variable named after the function, and often use
    # temporary variables in the '^_G_' namespace. If you are careful to
    # avoid using those namespaces casually in your sourcing script, things
    # should continue to work as you expect. And, of course, you can freely
    # overwrite any of the functions or variables defined here before
    # calling anything to customize them.
    
    EXIT_SUCCESS=0
    EXIT_FAILURE=1
    EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
    EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
    
    # Allow overriding, eg assuming that you follow the convention of
    # putting '$debug_cmd' at the start of all your functions, you can get
    # bash to show function call trace with:
    #
    #    debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
    debug_cmd=${debug_cmd-":"}
    exit_cmd=:
    
    # By convention, finish your script with:
    #
    #    exit $exit_status
    #
    # so that you can set exit_status to non-zero if you want to indicate
    # something went wrong during execution without actually bailing out at
    # the point of failure.
    exit_status=$EXIT_SUCCESS
    
    # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
    # is ksh but when the shell is invoked as "sh" and the current value of
    # the _XPG environment variable is not equal to 1 (one), the special
    # positional parameter $0, within a function call, is the name of the
    # function.
    progpath=$0
    
    # The name of this program.
    progname=`$ECHO "$progpath" |$SED "$sed_basename"`
    
    # Make sure we have an absolute progpath for reexecution:
    case $progpath in
      [\\/]*|[A-Za-z]:\\*) ;;
      *[\\/]*)
         progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
         progdir=`cd "$progdir" && pwd`
         progpath=$progdir/$progname
         ;;
      *)
         _G_IFS=$IFS
         IFS=${PATH_SEPARATOR-:}
         for progdir in $PATH; do
           IFS=$_G_IFS
           test -x "$progdir/$progname" && break
         done
         IFS=$_G_IFS
         test -n "$progdir" || progdir=`pwd`
         progpath=$progdir/$progname
         ;;
    esac
    
    
    ## ----------------- ##
    ## Standard options. ##
    ## ----------------- ##
    
    # The following options affect the operation of the functions defined
    # below, and should be set appropriately depending on run-time para-
    # meters passed on the command line.
    
    opt_dry_run=false
    opt_quiet=false
    opt_verbose=false
    
    # Categories 'all' and 'none' are always available.  Append any others
    # you will pass as the first argument to func_warning from your own
    # code.
    warning_categories=
    
    # By default, display warnings according to 'opt_warning_types'.  Set
    # 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
    # treat the next displayed warning as a fatal error.
    warning_func=func_warn_and_continue
    
    # Set to 'all' to display all warnings, 'none' to suppress all
    # warnings, or a space delimited list of some subset of
    # 'warning_categories' to display only the listed warnings.
    opt_warning_types=all
    
    
    ## -------------------- ##
    ## Resource management. ##
    ## -------------------- ##
    
    # This section contains definitions for functions that each ensure a
    # particular resource (a file, or a non-empty configuration variable for
    # example) is available, and if appropriate to extract default values
    # from pertinent package files. Call them using their associated
    # 'require_*' variable to ensure that they are executed, at most, once.
    #
    # It's entirely deliberate that calling these functions can set
    # variables that don't obey the namespace limitations obeyed by the rest
    # of this file, in order that that they be as useful as possible to
    # callers.
    
    
    # require_term_colors
    # -------------------
    # Allow display of bold text on terminals that support it.
    require_term_colors=func_require_term_colors
    func_require_term_colors ()
    {
        $debug_cmd
    
        test -t 1 && {
          # COLORTERM and USE_ANSI_COLORS environment variables take
          # precedence, because most terminfo databases neglect to describe
          # whether color sequences are supported.
          test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
    
          if test 1 = "$USE_ANSI_COLORS"; then
            # Standard ANSI escape sequences
            tc_reset=''
            tc_bold='';   tc_standout=''
            tc_red='';   tc_green=''
            tc_blue='';  tc_cyan=''
          else
            # Otherwise trust the terminfo database after all.
            test -n "`tput sgr0 2>/dev/null`" && {
              tc_reset=`tput sgr0`
              test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
              tc_standout=$tc_bold
              test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
              test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
              test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
              test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
              test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
            }
          fi
        }
    
        require_term_colors=:
    }
    
    
    ## ----------------- ##
    ## Function library. ##
    ## ----------------- ##
    
    # This section contains a variety of useful functions to call in your
    # scripts. Take note of the portable wrappers for features provided by
    # some modern shells, which will fall back to slower equivalents on
    # less featureful shells.
    
    
    # func_append VAR VALUE
    # ---------------------
    # Append VALUE onto the existing contents of VAR.
    
      # _G_HAVE_PLUSEQ_OP
      # Can be empty, in which case the shell is probed, "yes" if += is
      # useable or anything else if it does not work.
      if test -z "$_G_HAVE_PLUSEQ_OP" &&  \
          __PLUSEQ_TEST="a" &&  \
          __PLUSEQ_TEST+=" b" 2>/dev/null &&  \
          test "a b" = "$__PLUSEQ_TEST"; then
        _G_HAVE_PLUSEQ_OP=yes
      fi
    
    if test yes = "$_G_HAVE_PLUSEQ_OP"
    then
      # This is an XSI compatible shell, allowing a faster implementation...
      eval 'func_append ()
      {
        $debug_cmd
    
        eval "$1+=\$2"
      }'
    else
      # ...otherwise fall back to using expr, which is often a shell builtin.
      func_append ()
      {
        $debug_cmd
    
        eval "$1=\$$1\$2"
      }
    fi
    
    
    # func_append_quoted VAR VALUE
    # ----------------------------
    # Quote VALUE and append to the end of shell variable VAR, separated
    # by a space.
    if test yes = "$_G_HAVE_PLUSEQ_OP"; then
      eval 'func_append_quoted ()
      {
        $debug_cmd
    
        func_quote_arg pretty "$2"
        eval "$1+=\\ \$func_quote_arg_result"
      }'
    else
      func_append_quoted ()
      {
        $debug_cmd
    
        func_quote_arg pretty "$2"
        eval "$1=\$$1\\ \$func_quote_arg_result"
      }
    fi
    
    
    # func_append_uniq VAR VALUE
    # --------------------------
    # Append unique VALUE onto the existing contents of VAR, assuming
    # entries are delimited by the first character of VALUE.  For example:
    #
    #   func_append_uniq options " --another-option option-argument"
    #
    # will only append to $options if " --another-option option-argument "
    # is not already present somewhere in $options already (note spaces at
    # each end implied by leading space in second argument).
    func_append_uniq ()
    {
        $debug_cmd
    
        eval _G_current_value='`$ECHO $'$1'`'
        _G_delim=`expr "$2" : '\(.\)'`
    
        case $_G_delim$_G_current_value$_G_delim in
          *"$2$_G_delim"*) ;;
          *) func_append "$@" ;;
        esac
    }
    
    
    # func_arith TERM...
    # ------------------
    # Set func_arith_result to the result of evaluating TERMs.
      test -z "$_G_HAVE_ARITH_OP" \
        && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
        && _G_HAVE_ARITH_OP=yes
    
    if test yes = "$_G_HAVE_ARITH_OP"; then
      eval 'func_arith ()
      {
        $debug_cmd
    
        func_arith_result=$(( $* ))
      }'
    else
      func_arith ()
      {
        $debug_cmd
    
        func_arith_result=`expr "$@"`
      }
    fi
    
    
    # func_basename FILE
    # ------------------
    # Set func_basename_result to FILE with everything up to and including
    # the last / stripped.
    if test yes = "$_G_HAVE_XSI_OPS"; then
      # If this shell supports suffix pattern removal, then use it to avoid
      # forking. Hide the definitions single quotes in case the shell chokes
      # on unsupported syntax...
      _b='func_basename_result=${1##*/}'
      _d='case $1 in
            */*) func_dirname_result=${1%/*}$2 ;;
            *  ) func_dirname_result=$3        ;;
          esac'
    
    else
      # ...otherwise fall back to using sed.
      _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
      _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
          if test "X$func_dirname_result" = "X$1"; then
            func_dirname_result=$3
          else
            func_append func_dirname_result "$2"
          fi'
    fi
    
    eval 'func_basename ()
    {
        $debug_cmd
    
        '"$_b"'
    }'
    
    
    # func_dirname FILE APPEND NONDIR_REPLACEMENT
    # -------------------------------------------
    # Compute the dirname of FILE.  If nonempty, add APPEND to the result,
    # otherwise set result to NONDIR_REPLACEMENT.
    eval 'func_dirname ()
    {
        $debug_cmd
    
        '"$_d"'
    }'
    
    
    # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
    # --------------------------------------------------------
    # Perform func_basename and func_dirname in a single function
    # call:
    #   dirname:  Compute the dirname of FILE.  If nonempty,
    #             add APPEND to the result, otherwise set result
    #             to NONDIR_REPLACEMENT.
    #             value returned in "$func_dirname_result"
    #   basename: Compute filename of FILE.
    #             value retuned in "$func_basename_result"
    # For efficiency, we do not delegate to the functions above but instead
    # duplicate the functionality here.
    eval 'func_dirname_and_basename ()
    {
        $debug_cmd
    
        '"$_b"'
        '"$_d"'
    }'
    
    
    # func_echo ARG...
    # ----------------
    # Echo program name prefixed message.
    func_echo ()
    {
        $debug_cmd
    
        _G_message=$*
    
        func_echo_IFS=$IFS
        IFS=$nl
        for _G_line in $_G_message; do
          IFS=$func_echo_IFS
          $ECHO "$progname: $_G_line"
        done
        IFS=$func_echo_IFS
    }
    
    
    # func_echo_all ARG...
    # --------------------
    # Invoke $ECHO with all args, space-separated.
    func_echo_all ()
    {
        $ECHO "$*"
    }
    
    
    # func_echo_infix_1 INFIX ARG...
    # ------------------------------
    # Echo program name, followed by INFIX on the first line, with any
    # additional lines not showing INFIX.
    func_echo_infix_1 ()
    {
        $debug_cmd
    
        $require_term_colors
    
        _G_infix=$1; shift
        _G_indent=$_G_infix
        _G_prefix="$progname: $_G_infix: "
        _G_message=$*
    
        # Strip color escape sequences before counting printable length
        for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
        do
          test -n "$_G_tc" && {
            _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
            _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
          }
        done
        _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes
    
        func_echo_infix_1_IFS=$IFS
        IFS=$nl
        for _G_line in $_G_message; do
          IFS=$func_echo_infix_1_IFS
          $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
          _G_prefix=$_G_indent
        done
        IFS=$func_echo_infix_1_IFS
    }
    
    
    # func_error ARG...
    # -----------------
    # Echo program name prefixed message to standard error.
    func_error ()
    {
        $debug_cmd
    
        $require_term_colors
    
        func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2
    }
    
    
    # func_fatal_error ARG...
    # -----------------------
    # Echo program name prefixed message to standard error, and exit.
    func_fatal_error ()
    {
        $debug_cmd
    
        func_error "$*"
        exit $EXIT_FAILURE
    }
    
    
    # func_grep EXPRESSION FILENAME
    # -----------------------------
    # Check whether EXPRESSION matches any line of FILENAME, without output.
    func_grep ()
    {
        $debug_cmd
    
        $GREP "$1" "$2" >/dev/null 2>&1
    }
    
    
    # func_len STRING
    # ---------------
    # Set func_len_result to the length of STRING. STRING may not
    # start with a hyphen.
      test -z "$_G_HAVE_XSI_OPS" \
        && (eval 'x=a/b/c;
          test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
        && _G_HAVE_XSI_OPS=yes
    
    if test yes = "$_G_HAVE_XSI_OPS"; then
      eval 'func_len ()
      {
        $debug_cmd
    
        func_len_result=${#1}
      }'
    else
      func_len ()
      {
        $debug_cmd
    
        func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
      }
    fi
    
    
    # func_mkdir_p DIRECTORY-PATH
    # ---------------------------
    # Make sure the entire path to DIRECTORY-PATH is available.
    func_mkdir_p ()
    {
        $debug_cmd
    
        _G_directory_path=$1
        _G_dir_list=
    
        if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
    
          # Protect directory names starting with '-'
          case $_G_directory_path in
            -*) _G_directory_path=./$_G_directory_path ;;
          esac
    
          # While some portion of DIR does not yet exist...
          while test ! -d "$_G_directory_path"; do
            # ...make a list in topmost first order.  Use a colon delimited
    	# list incase some portion of path contains whitespace.
            _G_dir_list=$_G_directory_path:$_G_dir_list
    
            # If the last portion added has no slash in it, the list is done
            case $_G_directory_path in */*) ;; *) break ;; esac
    
            # ...otherwise throw away the child directory and loop
            _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
          done
          _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
    
          func_mkdir_p_IFS=$IFS; IFS=:
          for _G_dir in $_G_dir_list; do
    	IFS=$func_mkdir_p_IFS
            # mkdir can fail with a 'File exist' error if two processes
            # try to create one of the directories concurrently.  Don't
            # stop in that case!
            $MKDIR "$_G_dir" 2>/dev/null || :
          done
          IFS=$func_mkdir_p_IFS
    
          # Bail out if we (or some other process) failed to create a directory.
          test -d "$_G_directory_path" || \
            func_fatal_error "Failed to create '$1'"
        fi
    }
    
    
    # func_mktempdir [BASENAME]
    # -------------------------
    # Make a temporary directory that won't clash with other running
    # libtool processes, and avoids race conditions if possible.  If
    # given, BASENAME is the basename for that directory.
    func_mktempdir ()
    {
        $debug_cmd
    
        _G_template=${TMPDIR-/tmp}/${1-$progname}
    
        if test : = "$opt_dry_run"; then
          # Return a directory name, but don't create it in dry-run mode
          _G_tmpdir=$_G_template-$$
        else
    
          # If mktemp works, use that first and foremost
          _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
    
          if test ! -d "$_G_tmpdir"; then
            # Failing that, at least try and use $RANDOM to avoid a race
            _G_tmpdir=$_G_template-${RANDOM-0}$$
    
            func_mktempdir_umask=`umask`
            umask 0077
            $MKDIR "$_G_tmpdir"
            umask $func_mktempdir_umask
          fi
    
          # If we're not in dry-run mode, bomb out on failure
          test -d "$_G_tmpdir" || \
            func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
        fi
    
        $ECHO "$_G_tmpdir"
    }
    
    
    # func_normal_abspath PATH
    # ------------------------
    # Remove doubled-up and trailing slashes, "." path components,
    # and cancel out any ".." path components in PATH after making
    # it an absolute path.
    func_normal_abspath ()
    {
        $debug_cmd
    
        # These SED scripts presuppose an absolute path with a trailing slash.
        _G_pathcar='s|^/\([^/]*\).*$|\1|'
        _G_pathcdr='s|^/[^/]*||'
        _G_removedotparts=':dotsl
    		s|/\./|/|g
    		t dotsl
    		s|/\.$|/|'
        _G_collapseslashes='s|/\{1,\}|/|g'
        _G_finalslash='s|/*$|/|'
    
        # Start from root dir and reassemble the path.
        func_normal_abspath_result=
        func_normal_abspath_tpath=$1
        func_normal_abspath_altnamespace=
        case $func_normal_abspath_tpath in
          "")
            # Empty path, that just means $cwd.
            func_stripname '' '/' "`pwd`"
            func_normal_abspath_result=$func_stripname_result
            return
            ;;
          # The next three entries are used to spot a run of precisely
          # two leading slashes without using negated character classes;
          # we take advantage of case's first-match behaviour.
          ///*)
            # Unusual form of absolute path, do nothing.
            ;;
          //*)
            # Not necessarily an ordinary path; POSIX reserves leading '//'
            # and for example Cygwin uses it to access remote file shares
            # over CIFS/SMB, so we conserve a leading double slash if found.
            func_normal_abspath_altnamespace=/
            ;;
          /*)
            # Absolute path, do nothing.
            ;;
          *)
            # Relative path, prepend $cwd.
            func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
            ;;
        esac
    
        # Cancel out all the simple stuff to save iterations.  We also want
        # the path to end with a slash for ease of parsing, so make sure
        # there is one (and only one) here.
        func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
              -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
        while :; do
          # Processed it all yet?
          if test / = "$func_normal_abspath_tpath"; then
            # If we ascended to the root using ".." the result may be empty now.
            if test -z "$func_normal_abspath_result"; then
              func_normal_abspath_result=/
            fi
            break
          fi
          func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
              -e "$_G_pathcar"`
          func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
              -e "$_G_pathcdr"`
          # Figure out what to do with it
          case $func_normal_abspath_tcomponent in
            "")
              # Trailing empty path component, ignore it.
              ;;
            ..)
              # Parent dir; strip last assembled component from result.
              func_dirname "$func_normal_abspath_result"
              func_normal_abspath_result=$func_dirname_result
              ;;
            *)
              # Actual path component, append it.
              func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
              ;;
          esac
        done
        # Restore leading double-slash if one was found on entry.
        func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
    }
    
    
    # func_notquiet ARG...
    # --------------------
    # Echo program name prefixed message only when not in quiet mode.
    func_notquiet ()
    {
        $debug_cmd
    
        $opt_quiet || func_echo ${1+"$@"}
    
        # A bug in bash halts the script if the last line of a function
        # fails when set -e is in force, so we need another command to
        # work around that:
        :
    }
    
    
    # func_relative_path SRCDIR DSTDIR
    # --------------------------------
    # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
    func_relative_path ()
    {
        $debug_cmd
    
        func_relative_path_result=
        func_normal_abspath "$1"
        func_relative_path_tlibdir=$func_normal_abspath_result
        func_normal_abspath "$2"
        func_relative_path_tbindir=$func_normal_abspath_result
    
        # Ascend the tree starting from libdir
        while :; do
          # check if we have found a prefix of bindir
          case $func_relative_path_tbindir in
            $func_relative_path_tlibdir)
              # found an exact match
              func_relative_path_tcancelled=
              break
              ;;
            $func_relative_path_tlibdir*)
              # found a matching prefix
              func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
              func_relative_path_tcancelled=$func_stripname_result
              if test -z "$func_relative_path_result"; then
                func_relative_path_result=.
              fi
              break
              ;;
            *)
              func_dirname $func_relative_path_tlibdir
              func_relative_path_tlibdir=$func_dirname_result
              if test -z "$func_relative_path_tlibdir"; then
                # Have to descend all the way to the root!
                func_relative_path_result=../$func_relative_path_result
                func_relative_path_tcancelled=$func_relative_path_tbindir
                break
              fi
              func_relative_path_result=../$func_relative_path_result
              ;;
          esac
        done
    
        # Now calculate path; take care to avoid doubling-up slashes.
        func_stripname '' '/' "$func_relative_path_result"
        func_relative_path_result=$func_stripname_result
        func_stripname '/' '/' "$func_relative_path_tcancelled"
        if test -n "$func_stripname_result"; then
          func_append func_relative_path_result "/$func_stripname_result"
        fi
    
        # Normalisation. If bindir is libdir, return '.' else relative path.
        if test -n "$func_relative_path_result"; then
          func_stripname './' '' "$func_relative_path_result"
          func_relative_path_result=$func_stripname_result
        fi
    
        test -n "$func_relative_path_result" || func_relative_path_result=.
    
        :
    }
    
    
    # func_quote_portable EVAL ARG
    # ----------------------------
    # Internal function to portably implement func_quote_arg.  Note that we still
    # keep attention to performance here so we as much as possible try to avoid
    # calling sed binary (so far O(N) complexity as long as func_append is O(1)).
    func_quote_portable ()
    {
        $debug_cmd
    
        $require_check_ifs_backslash
    
        func_quote_portable_result=$2
    
        # one-time-loop (easy break)
        while true
        do
          if $1; then
            func_quote_portable_result=`$ECHO "$2" | $SED \
              -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
            break
          fi
    
          # Quote for eval.
          case $func_quote_portable_result in
            *[\\\`\"\$]*)
              # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string
              # contains the shell wildcard characters.
              case $check_ifs_backshlash_broken$func_quote_portable_result in
                :*|*[\[\*\?]*)
                  func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
                      | $SED "$sed_quote_subst"`
                  break
                  ;;
              esac
    
              func_quote_portable_old_IFS=$IFS
              for _G_char in '\' '`' '"' '$'
              do
                # STATE($1) PREV($2) SEPARATOR($3)
                set start "" ""
                func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
                IFS=$_G_char
                for _G_part in $func_quote_portable_result
                do
                  case $1 in
                  quote)
                    func_append func_quote_portable_result "$3$2"
                    set quote "$_G_part" "\\$_G_char"
                    ;;
                  start)
                    set first "" ""
                    func_quote_portable_result=
                    ;;
                  first)
                    set quote "$_G_part" ""
                    ;;
                  esac
                done
              done
              IFS=$func_quote_portable_old_IFS
              ;;
            *) ;;
          esac
          break
        done
    
        func_quote_portable_unquoted_result=$func_quote_portable_result
        case $func_quote_portable_result in
          # double-quote args containing shell metacharacters to delay
          # word splitting, command substitution and variable expansion
          # for a subsequent eval.
          # many bourne shells cannot handle close brackets correctly
          # in scan sets, so we specify it separately.
          *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
            func_quote_portable_result=\"$func_quote_portable_result\"
            ;;
        esac
    }
    
    
    # func_quotefast_eval ARG
    # -----------------------
    # Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
    # but optimized for speed.  Result is stored in $func_quotefast_eval.
    if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
      printf -v _GL_test_printf_tilde %q '~'
      if test '\~' = "$_GL_test_printf_tilde"; then
        func_quotefast_eval ()
        {
          printf -v func_quotefast_eval_result %q "$1"
        }
      else
        # Broken older Bash implementations.  Make those faster too if possible.
        func_quotefast_eval ()
        {
          case $1 in
            '~'*)
              func_quote_portable false "$1"
              func_quotefast_eval_result=$func_quote_portable_result
              ;;
            *)
              printf -v func_quotefast_eval_result %q "$1"
              ;;
          esac
        }
      fi
    else
      func_quotefast_eval ()
      {
        func_quote_portable false "$1"
        func_quotefast_eval_result=$func_quote_portable_result
      }
    fi
    
    
    # func_quote_arg MODEs ARG
    # ------------------------
    # Quote one ARG to be evaled later.  MODEs argument may contain zero or more
    # specifiers listed below separated by ',' character.  This function returns two
    # values:
    #   i) func_quote_arg_result
    #      double-quoted (when needed), suitable for a subsequent eval
    #  ii) func_quote_arg_unquoted_result
    #      has all characters that are still active within double
    #      quotes backslashified.  Available only if 'unquoted' is specified.
    #
    # Available modes:
    # ----------------
    # 'eval' (default)
    #       - escape shell special characters
    # 'expand'
    #       - the same as 'eval';  but do not quote variable references
    # 'pretty'
    #       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
    #         be used later in func_quote to get output like: 'echo "a b"' instead
    #         of 'echo a\ b'.  This is slower than default on some shells.
    # 'unquoted'
    #       - produce also $func_quote_arg_unquoted_result which does not contain
    #         wrapping double-quotes.
    #
    # Examples for 'func_quote_arg pretty,unquoted string':
    #
    #   string      | *_result              | *_unquoted_result
    #   ------------+-----------------------+-------------------
    #   "           | \"                    | \"
    #   a b         | "a b"                 | a b
    #   "a b"       | "\"a b\""             | \"a b\"
    #   *           | "*"                   | *
    #   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
    #
    # Examples for 'func_quote_arg pretty,unquoted,expand string':
    #
    #   string        |   *_result          |  *_unquoted_result
    #   --------------+---------------------+--------------------
    #   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
    func_quote_arg ()
    {
        _G_quote_expand=false
        case ,$1, in
          *,expand,*)
            _G_quote_expand=:
            ;;
        esac
    
        case ,$1, in
          *,pretty,*|*,expand,*|*,unquoted,*)
            func_quote_portable $_G_quote_expand "$2"
            func_quote_arg_result=$func_quote_portable_result
            func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
            ;;
          *)
            # Faster quote-for-eval for some shells.
            func_quotefast_eval "$2"
            func_quote_arg_result=$func_quotefast_eval_result
            ;;
        esac
    }
    
    
    # func_quote MODEs ARGs...
    # ------------------------
    # Quote all ARGs to be evaled later and join them into single command.  See
    # func_quote_arg's description for more info.
    func_quote ()
    {
        $debug_cmd
        _G_func_quote_mode=$1 ; shift
        func_quote_result=
        while test 0 -lt $#; do
          func_quote_arg "$_G_func_quote_mode" "$1"
          if test -n "$func_quote_result"; then
            func_append func_quote_result " $func_quote_arg_result"
          else
            func_append func_quote_result "$func_quote_arg_result"
          fi
          shift
        done
    }
    
    
    # func_stripname PREFIX SUFFIX NAME
    # ---------------------------------
    # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
    # PREFIX and SUFFIX must not contain globbing or regex special
    # characters, hashes, percent signs, but SUFFIX may contain a leading
    # dot (in which case that matches only a dot).
    if test yes = "$_G_HAVE_XSI_OPS"; then
      eval 'func_stripname ()
      {
        $debug_cmd
    
        # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
        # positional parameters, so assign one to ordinary variable first.
        func_stripname_result=$3
        func_stripname_result=${func_stripname_result#"$1"}
        func_stripname_result=${func_stripname_result%"$2"}
      }'
    else
      func_stripname ()
      {
        $debug_cmd
    
        case $2 in
          .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
          *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
        esac
      }
    fi
    
    
    # func_show_eval CMD [FAIL_EXP]
    # -----------------------------
    # Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
    # not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
    # is given, then evaluate it.
    func_show_eval ()
    {
        $debug_cmd
    
        _G_cmd=$1
        _G_fail_exp=${2-':'}
    
        func_quote_arg pretty,expand "$_G_cmd"
        eval "func_notquiet $func_quote_arg_result"
    
        $opt_dry_run || {
          eval "$_G_cmd"
          _G_status=$?
          if test 0 -ne "$_G_status"; then
    	eval "(exit $_G_status); $_G_fail_exp"
          fi
        }
    }
    
    
    # func_show_eval_locale CMD [FAIL_EXP]
    # ------------------------------------
    # Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
    # not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
    # is given, then evaluate it.  Use the saved locale for evaluation.
    func_show_eval_locale ()
    {
        $debug_cmd
    
        _G_cmd=$1
        _G_fail_exp=${2-':'}
    
        $opt_quiet || {
          func_quote_arg expand,pretty "$_G_cmd"
          eval "func_echo $func_quote_arg_result"
        }
    
        $opt_dry_run || {
          eval "$_G_user_locale
    	    $_G_cmd"
          _G_status=$?
          eval "$_G_safe_locale"
          if test 0 -ne "$_G_status"; then
    	eval "(exit $_G_status); $_G_fail_exp"
          fi
        }
    }
    
    
    # func_tr_sh
    # ----------
    # Turn $1 into a string suitable for a shell variable name.
    # Result is stored in $func_tr_sh_result.  All characters
    # not in the set a-zA-Z0-9_ are replaced with '_'. Further,
    # if $1 begins with a digit, a '_' is prepended as well.
    func_tr_sh ()
    {
        $debug_cmd
    
        case $1 in
        [0-9]* | *[!a-zA-Z0-9_]*)
          func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
          ;;
        * )
          func_tr_sh_result=$1
          ;;
        esac
    }
    
    
    # func_verbose ARG...
    # -------------------
    # Echo program name prefixed message in verbose mode only.
    func_verbose ()
    {
        $debug_cmd
    
        $opt_verbose && func_echo "$*"
    
        :
    }
    
    
    # func_warn_and_continue ARG...
    # -----------------------------
    # Echo program name prefixed warning message to standard error.
    func_warn_and_continue ()
    {
        $debug_cmd
    
        $require_term_colors
    
        func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
    }
    
    
    # func_warning CATEGORY ARG...
    # ----------------------------
    # Echo program name prefixed warning message to standard error. Warning
    # messages can be filtered according to CATEGORY, where this function
    # elides messages where CATEGORY is not listed in the global variable
    # 'opt_warning_types'.
    func_warning ()
    {
        $debug_cmd
    
        # CATEGORY must be in the warning_categories list!
        case " $warning_categories " in
          *" $1 "*) ;;
          *) func_internal_error "invalid warning category '$1'" ;;
        esac
    
        _G_category=$1
        shift
    
        case " $opt_warning_types " in
          *" $_G_category "*) $warning_func ${1+"$@"} ;;
        esac
    }
    
    
    # func_sort_ver VER1 VER2
    # -----------------------
    # 'sort -V' is not generally available.
    # Note this deviates from the version comparison in automake
    # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
    # but this should suffice as we won't be specifying old
    # version formats or redundant trailing .0 in bootstrap.conf.
    # If we did want full compatibility then we should probably
    # use m4_version_compare from autoconf.
    func_sort_ver ()
    {
        $debug_cmd
    
        printf '%s\n%s\n' "$1" "$2" \
          | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
    }
    
    # func_lt_ver PREV CURR
    # ---------------------
    # Return true if PREV and CURR are in the correct order according to
    # func_sort_ver, otherwise false.  Use it like this:
    #
    #  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
    func_lt_ver ()
    {
        $debug_cmd
    
        test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
    }
    
    
    # Local variables:
    # mode: shell-script
    # sh-indentation: 2
    # eval: (add-hook 'before-save-hook 'time-stamp)
    # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
    # time-stamp-time-zone: "UTC"
    # End:
    #! /bin/sh
    
    # A portable, pluggable option parser for Bourne shell.
    # Written by Gary V. Vaughan, 2010
    
    # This is free software.  There is NO warranty; not even for
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    #
    # Copyright (C) 2010-2019, 2021 Bootstrap Authors
    #
    # This file is dual licensed under the terms of the MIT license
    # <https://opensource.org/license/MIT>, and GPL version 2 or later
    # <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
    # these licenses when using or redistributing this software or any of
    # the files within it.  See the URLs above, or the file `LICENSE`
    # included in the Bootstrap distribution for the full license texts.
    
    # Please report bugs or propose patches to:
    # <https://github.com/gnulib-modules/bootstrap/issues>
    
    # Set a version string for this script.
    scriptversion=2019-02-19.15; # UTC
    
    
    ## ------ ##
    ## Usage. ##
    ## ------ ##
    
    # This file is a library for parsing options in your shell scripts along
    # with assorted other useful supporting features that you can make use
    # of too.
    #
    # For the simplest scripts you might need only:
    #
    #   #!/bin/sh
    #   . relative/path/to/funclib.sh
    #   . relative/path/to/options-parser
    #   scriptversion=1.0
    #   func_options ${1+"$@"}
    #   eval set dummy "$func_options_result"; shift
    #   ...rest of your script...
    #
    # In order for the '--version' option to work, you will need to have a
    # suitably formatted comment like the one at the top of this file
    # starting with '# Written by ' and ending with '# Copyright'.
    #
    # For '-h' and '--help' to work, you will also need a one line
    # description of your script's purpose in a comment directly above the
    # '# Written by ' line, like the one at the top of this file.
    #
    # The default options also support '--debug', which will turn on shell
    # execution tracing (see the comment above debug_cmd below for another
    # use), and '--verbose' and the func_verbose function to allow your script
    # to display verbose messages only when your user has specified
    # '--verbose'.
    #
    # After sourcing this file, you can plug in processing for additional
    # options by amending the variables from the 'Configuration' section
    # below, and following the instructions in the 'Option parsing'
    # section further down.
    
    ## -------------- ##
    ## Configuration. ##
    ## -------------- ##
    
    # You should override these variables in your script after sourcing this
    # file so that they reflect the customisations you have added to the
    # option parser.
    
    # The usage line for option parsing errors and the start of '-h' and
    # '--help' output messages. You can embed shell variables for delayed
    # expansion at the time the message is displayed, but you will need to
    # quote other shell meta-characters carefully to prevent them being
    # expanded when the contents are evaled.
    usage='$progpath [OPTION]...'
    
    # Short help message in response to '-h' and '--help'.  Add to this or
    # override it after sourcing this library to reflect the full set of
    # options your script accepts.
    usage_message="\
           --debug        enable verbose shell tracing
       -W, --warnings=CATEGORY
                          report the warnings falling in CATEGORY [all]
       -v, --verbose      verbosely report processing
           --version      print version information and exit
       -h, --help         print short or long help message and exit
    "
    
    # Additional text appended to 'usage_message' in response to '--help'.
    long_help_message="
    Warning categories include:
           'all'          show all warnings
           'none'         turn off all the warnings
           'error'        warnings are treated as fatal errors"
    
    # Help message printed before fatal option parsing errors.
    fatal_help="Try '\$progname --help' for more information."
    
    
    
    ## ------------------------- ##
    ## Hook function management. ##
    ## ------------------------- ##
    
    # This section contains functions for adding, removing, and running hooks
    # in the main code.  A hook is just a list of function names that can be
    # run in order later on.
    
    # func_hookable FUNC_NAME
    # -----------------------
    # Declare that FUNC_NAME will run hooks added with
    # 'func_add_hook FUNC_NAME ...'.
    func_hookable ()
    {
        $debug_cmd
    
        func_append hookable_fns " $1"
    }
    
    
    # func_add_hook FUNC_NAME HOOK_FUNC
    # ---------------------------------
    # Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
    # first have been declared "hookable" by a call to 'func_hookable'.
    func_add_hook ()
    {
        $debug_cmd
    
        case " $hookable_fns " in
          *" $1 "*) ;;
          *) func_fatal_error "'$1' does not accept hook functions." ;;
        esac
    
        eval func_append ${1}_hooks '" $2"'
    }
    
    
    # func_remove_hook FUNC_NAME HOOK_FUNC
    # ------------------------------------
    # Remove HOOK_FUNC from the list of hook functions to be called by
    # FUNC_NAME.
    func_remove_hook ()
    {
        $debug_cmd
    
        eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
    }
    
    
    # func_propagate_result FUNC_NAME_A FUNC_NAME_B
    # ---------------------------------------------
    # If the *_result variable of FUNC_NAME_A _is set_, assign its value to
    # *_result variable of FUNC_NAME_B.
    func_propagate_result ()
    {
        $debug_cmd
    
        func_propagate_result_result=:
        if eval "test \"\${${1}_result+set}\" = set"
        then
          eval "${2}_result=\$${1}_result"
        else
          func_propagate_result_result=false
        fi
    }
    
    
    # func_run_hooks FUNC_NAME [ARG]...
    # ---------------------------------
    # Run all hook functions registered to FUNC_NAME.
    # It's assumed that the list of hook functions contains nothing more
    # than a whitespace-delimited list of legal shell function names, and
    # no effort is wasted trying to catch shell meta-characters or preserve
    # whitespace.
    func_run_hooks ()
    {
        $debug_cmd
    
        _G_rc_run_hooks=false
    
        case " $hookable_fns " in
          *" $1 "*) ;;
          *) func_fatal_error "'$1' does not support hook functions." ;;
        esac
    
        eval _G_hook_fns=\$$1_hooks; shift
    
        for _G_hook in $_G_hook_fns; do
          func_unset "${_G_hook}_result"
          eval $_G_hook '${1+"$@"}'
          func_propagate_result $_G_hook func_run_hooks
          if $func_propagate_result_result; then
            eval set dummy "$func_run_hooks_result"; shift
          fi
        done
    }
    
    
    
    ## --------------- ##
    ## Option parsing. ##
    ## --------------- ##
    
    # In order to add your own option parsing hooks, you must accept the
    # full positional parameter list from your hook function.  You may remove
    # or edit any options that you action, and then pass back the remaining
    # unprocessed options in '<hooked_function_name>_result', escaped
    # suitably for 'eval'.
    #
    # The '<hooked_function_name>_result' variable is automatically unset
    # before your hook gets called; for best performance, only set the
    # *_result variable when necessary (i.e. don't call the 'func_quote'
    # function unnecessarily because it can be an expensive operation on some
    # machines).
    #
    # Like this:
    #
    #    my_options_prep ()
    #    {
    #        $debug_cmd
    #
    #        # Extend the existing usage message.
    #        usage_message=$usage_message'
    #      -s, --silent       don'\''t print informational messages
    #    '
    #        # No change in '$@' (ignored completely by this hook).  Leave
    #        # my_options_prep_result variable intact.
    #    }
    #    func_add_hook func_options_prep my_options_prep
    #
    #
    #    my_silent_option ()
    #    {
    #        $debug_cmd
    #
    #        args_changed=false
    #
    #        # Note that, for efficiency, we parse as many options as we can
    #        # recognise in a loop before passing the remainder back to the
    #        # caller on the first unrecognised argument we encounter.
    #        while test $# -gt 0; do
    #          opt=$1; shift
    #          case $opt in
    #            --silent|-s) opt_silent=:
    #                         args_changed=:
    #                         ;;
    #            # Separate non-argument short options:
    #            -s*)         func_split_short_opt "$_G_opt"
    #                         set dummy "$func_split_short_opt_name" \
    #                             "-$func_split_short_opt_arg" ${1+"$@"}
    #                         shift
    #                         args_changed=:
    #                         ;;
    #            *)           # Make sure the first unrecognised option "$_G_opt"
    #                         # is added back to "$@" in case we need it later,
    #                         # if $args_changed was set to 'true'.
    #                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
    #          esac
    #        done
    #
    #        # Only call 'func_quote' here if we processed at least one argument.
    #        if $args_changed; then
    #          func_quote eval ${1+"$@"}
    #          my_silent_option_result=$func_quote_result
    #        fi
    #    }
    #    func_add_hook func_parse_options my_silent_option
    #
    #
    #    my_option_validation ()
    #    {
    #        $debug_cmd
    #
    #        $opt_silent && $opt_verbose && func_fatal_help "\
    #    '--silent' and '--verbose' options are mutually exclusive."
    #    }
    #    func_add_hook func_validate_options my_option_validation
    #
    # You'll also need to manually amend $usage_message to reflect the extra
    # options you parse.  It's preferable to append if you can, so that
    # multiple option parsing hooks can be added safely.
    
    
    # func_options_finish [ARG]...
    # ----------------------------
    # Finishing the option parse loop (call 'func_options' hooks ATM).
    func_options_finish ()
    {
        $debug_cmd
    
        func_run_hooks func_options ${1+"$@"}
        func_propagate_result func_run_hooks func_options_finish
    }
    
    
    # func_options [ARG]...
    # ---------------------
    # All the functions called inside func_options are hookable. See the
    # individual implementations for details.
    func_hookable func_options
    func_options ()
    {
        $debug_cmd
    
        _G_options_quoted=false
    
        for my_func in options_prep parse_options validate_options options_finish
        do
          func_unset func_${my_func}_result
          func_unset func_run_hooks_result
          eval func_$my_func '${1+"$@"}'
          func_propagate_result func_$my_func func_options
          if $func_propagate_result_result; then
            eval set dummy "$func_options_result"; shift
            _G_options_quoted=:
          fi
        done
    
        $_G_options_quoted || {
          # As we (func_options) are top-level options-parser function and
          # nobody quoted "$@" for us yet, we need to do it explicitly for
          # caller.
          func_quote eval ${1+"$@"}
          func_options_result=$func_quote_result
        }
    }
    
    
    # func_options_prep [ARG]...
    # --------------------------
    # All initialisations required before starting the option parse loop.
    # Note that when calling hook functions, we pass through the list of
    # positional parameters.  If a hook function modifies that list, and
    # needs to propagate that back to rest of this script, then the complete
    # modified list must be put in 'func_run_hooks_result' before returning.
    func_hookable func_options_prep
    func_options_prep ()
    {
        $debug_cmd
    
        # Option defaults:
        opt_verbose=false
        opt_warning_types=
    
        func_run_hooks func_options_prep ${1+"$@"}
        func_propagate_result func_run_hooks func_options_prep
    }
    
    
    # func_parse_options [ARG]...
    # ---------------------------
    # The main option parsing loop.
    func_hookable func_parse_options
    func_parse_options ()
    {
        $debug_cmd
    
        _G_parse_options_requote=false
        # this just eases exit handling
        while test $# -gt 0; do
          # Defer to hook functions for initial option parsing, so they
          # get priority in the event of reusing an option name.
          func_run_hooks func_parse_options ${1+"$@"}
          func_propagate_result func_run_hooks func_parse_options
          if $func_propagate_result_result; then
            eval set dummy "$func_parse_options_result"; shift
            # Even though we may have changed "$@", we passed the "$@" array
            # down into the hook and it quoted it for us (because we are in
            # this if-branch).  No need to quote it again.
            _G_parse_options_requote=false
          fi
    
          # Break out of the loop if we already parsed every option.
          test $# -gt 0 || break
    
          # We expect that one of the options parsed in this function matches
          # and thus we remove _G_opt from "$@" and need to re-quote.
          _G_match_parse_options=:
          _G_opt=$1
          shift
          case $_G_opt in
            --debug|-x)   debug_cmd='set -x'
                          func_echo "enabling shell trace mode" >&2
                          $debug_cmd
                          ;;
    
            --no-warnings|--no-warning|--no-warn)
                          set dummy --warnings none ${1+"$@"}
                          shift
    		      ;;
    
            --warnings|--warning|-W)
                          if test $# = 0 && func_missing_arg $_G_opt; then
                            _G_parse_options_requote=:
                            break
                          fi
                          case " $warning_categories $1" in
                            *" $1 "*)
                              # trailing space prevents matching last $1 above
                              func_append_uniq opt_warning_types " $1"
                              ;;
                            *all)
                              opt_warning_types=$warning_categories
                              ;;
                            *none)
                              opt_warning_types=none
                              warning_func=:
                              ;;
                            *error)
                              opt_warning_types=$warning_categories
                              warning_func=func_fatal_error
                              ;;
                            *)
                              func_fatal_error \
                                 "unsupported warning category: '$1'"
                              ;;
                          esac
                          shift
                          ;;
    
            --verbose|-v) opt_verbose=: ;;
            --version)    func_version ;;
            -\?|-h)       func_usage ;;
            --help)       func_help ;;
    
    	# Separate optargs to long options (plugins may need this):
    	--*=*)        func_split_equals "$_G_opt"
    	              set dummy "$func_split_equals_lhs" \
                              "$func_split_equals_rhs" ${1+"$@"}
                          shift
                          ;;
    
           # Separate optargs to short options:
            -W*)
                          func_split_short_opt "$_G_opt"
                          set dummy "$func_split_short_opt_name" \
                              "$func_split_short_opt_arg" ${1+"$@"}
                          shift
                          ;;
    
            # Separate non-argument short options:
            -\?*|-h*|-v*|-x*)
                          func_split_short_opt "$_G_opt"
                          set dummy "$func_split_short_opt_name" \
                              "-$func_split_short_opt_arg" ${1+"$@"}
                          shift
                          ;;
    
            --)           _G_parse_options_requote=: ; break ;;
            -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
            *)            set dummy "$_G_opt" ${1+"$@"}; shift
                          _G_match_parse_options=false
                          break
                          ;;
          esac
    
          if $_G_match_parse_options; then
            _G_parse_options_requote=:
          fi
        done
    
        if $_G_parse_options_requote; then
          # save modified positional parameters for caller
          func_quote eval ${1+"$@"}
          func_parse_options_result=$func_quote_result
        fi
    }
    
    
    # func_validate_options [ARG]...
    # ------------------------------
    # Perform any sanity checks on option settings and/or unconsumed
    # arguments.
    func_hookable func_validate_options
    func_validate_options ()
    {
        $debug_cmd
    
        # Display all warnings if -W was not given.
        test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
    
        func_run_hooks func_validate_options ${1+"$@"}
        func_propagate_result func_run_hooks func_validate_options
    
        # Bail if the options were screwed!
        $exit_cmd $EXIT_FAILURE
    }
    
    
    
    ## ----------------- ##
    ## Helper functions. ##
    ## ----------------- ##
    
    # This section contains the helper functions used by the rest of the
    # hookable option parser framework in ascii-betical order.
    
    
    # func_fatal_help ARG...
    # ----------------------
    # Echo program name prefixed message to standard error, followed by
    # a help hint, and exit.
    func_fatal_help ()
    {
        $debug_cmd
    
        eval \$ECHO \""Usage: $usage"\"
        eval \$ECHO \""$fatal_help"\"
        func_error ${1+"$@"}
        exit $EXIT_FAILURE
    }
    
    
    # func_help
    # ---------
    # Echo long help message to standard output and exit.
    func_help ()
    {
        $debug_cmd
    
        func_usage_message
        $ECHO "$long_help_message"
        exit 0
    }
    
    
    # func_missing_arg ARGNAME
    # ------------------------
    # Echo program name prefixed message to standard error and set global
    # exit_cmd.
    func_missing_arg ()
    {
        $debug_cmd
    
        func_error "Missing argument for '$1'."
        exit_cmd=exit
    }
    
    
    # func_split_equals STRING
    # ------------------------
    # Set func_split_equals_lhs and func_split_equals_rhs shell variables
    # after splitting STRING at the '=' sign.
    test -z "$_G_HAVE_XSI_OPS" \
        && (eval 'x=a/b/c;
          test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
        && _G_HAVE_XSI_OPS=yes
    
    if test yes = "$_G_HAVE_XSI_OPS"
    then
      # This is an XSI compatible shell, allowing a faster implementation...
      eval 'func_split_equals ()
      {
          $debug_cmd
    
          func_split_equals_lhs=${1%%=*}
          func_split_equals_rhs=${1#*=}
          if test "x$func_split_equals_lhs" = "x$1"; then
            func_split_equals_rhs=
          fi
      }'
    else
      # ...otherwise fall back to using expr, which is often a shell builtin.
      func_split_equals ()
      {
          $debug_cmd
    
          func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
          func_split_equals_rhs=
          test "x$func_split_equals_lhs=" = "x$1" \
            || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
      }
    fi #func_split_equals
    
    
    # func_split_short_opt SHORTOPT
    # -----------------------------
    # Set func_split_short_opt_name and func_split_short_opt_arg shell
    # variables after splitting SHORTOPT after the 2nd character.
    if test yes = "$_G_HAVE_XSI_OPS"
    then
      # This is an XSI compatible shell, allowing a faster implementation...
      eval 'func_split_short_opt ()
      {
          $debug_cmd
    
          func_split_short_opt_arg=${1#??}
          func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
      }'
    else
      # ...otherwise fall back to using expr, which is often a shell builtin.
      func_split_short_opt ()
      {
          $debug_cmd
    
          func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'`
          func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
      }
    fi #func_split_short_opt
    
    
    # func_usage
    # ----------
    # Echo short help message to standard output and exit.
    func_usage ()
    {
        $debug_cmd
    
        func_usage_message
        $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
        exit 0
    }
    
    
    # func_usage_message
    # ------------------
    # Echo short help message to standard output.
    func_usage_message ()
    {
        $debug_cmd
    
        eval \$ECHO \""Usage: $usage"\"
        echo
        $SED -n 's|^# ||
            /^Written by/{
              x;p;x
            }
    	h
    	/^Written by/q' < "$progpath"
        echo
        eval \$ECHO \""$usage_message"\"
    }
    
    
    # func_version
    # ------------
    # Echo version message to standard output and exit.
    # The version message is extracted from the calling file's header
    # comments, with leading '# ' stripped:
    #   1. First display the progname and version
    #   2. Followed by the header comment line matching  /^# Written by /
    #   3. Then a blank line followed by the first following line matching
    #      /^# Copyright /
    #   4. Immediately followed by any lines between the previous matches,
    #      except lines preceding the intervening completely blank line.
    # For example, see the header comments of this file.
    func_version ()
    {
        $debug_cmd
    
        printf '%s\n' "$progname $scriptversion"
        $SED -n '
            /^# Written by /!b
            s|^# ||; p; n
    
            :fwd2blnk
            /./ {
              n
              b fwd2blnk
            }
            p; n
    
            :holdwrnt
            s|^# ||
            s|^# *$||
            /^Copyright /!{
              /./H
              n
              b holdwrnt
            }
    
            s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
            G
            s|\(\n\)\n*|\1|g
            p; q' < "$progpath"
    
        exit $?
    }
    
    
    # Local variables:
    # mode: shell-script
    # sh-indentation: 2
    # eval: (add-hook 'before-save-hook 'time-stamp)
    # time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC"
    # time-stamp-time-zone: "UTC"
    # End:
    
    # Set a version string.
    scriptversion='(GNU libtool) 2.4.7'
    
    
    # func_echo ARG...
    # ----------------
    # Libtool also displays the current mode in messages, so override
    # funclib.sh func_echo with this custom definition.
    func_echo ()
    {
        $debug_cmd
    
        _G_message=$*
    
        func_echo_IFS=$IFS
        IFS=$nl
        for _G_line in $_G_message; do
          IFS=$func_echo_IFS
          $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
        done
        IFS=$func_echo_IFS
    }
    
    
    # func_warning ARG...
    # -------------------
    # Libtool warnings are not categorized, so override funclib.sh
    # func_warning with this simpler definition.
    func_warning ()
    {
        $debug_cmd
    
        $warning_func ${1+"$@"}
    }
    
    
    ## ---------------- ##
    ## Options parsing. ##
    ## ---------------- ##
    
    # Hook in the functions to make sure our own options are parsed during
    # the option parsing loop.
    
    usage='$progpath [OPTION]... [MODE-ARG]...'
    
    # Short help message in response to '-h'.
    usage_message="Options:
           --config             show all configuration variables
           --debug              enable verbose shell tracing
       -n, --dry-run            display commands without modifying any files
           --features           display basic configuration information and exit
           --mode=MODE          use operation mode MODE
           --no-warnings        equivalent to '-Wnone'
           --preserve-dup-deps  don't remove duplicate dependency libraries
           --quiet, --silent    don't print informational messages
           --tag=TAG            use configuration variables from tag TAG
       -v, --verbose            print more informational messages than default
           --version            print version information
       -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
       -h, --help, --help-all   print short, long, or detailed help message
    "
    
    # Additional text appended to 'usage_message' in response to '--help'.
    func_help ()
    {
        $debug_cmd
    
        func_usage_message
        $ECHO "$long_help_message
    
    MODE must be one of the following:
    
           clean           remove files from the build directory
           compile         compile a source file into a libtool object
           execute         automatically set library path, then run a program
           finish          complete the installation of libtool libraries
           install         install libraries or executables
           link            create a library or an executable
           uninstall       remove libraries from an installed directory
    
    MODE-ARGS vary depending on the MODE.  When passed as first option,
    '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
    Try '$progname --help --mode=MODE' for a more detailed description of MODE.
    
    When reporting a bug, please describe a test case to reproduce it and
    include the following information:
    
           host-triplet:   $host
           shell:          $SHELL
           compiler:       $LTCC
           compiler flags: $LTCFLAGS
           linker:         $LD (gnu? $with_gnu_ld)
           version:        $progname $scriptversion Debian-2.4.7-7build1
           automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
           autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
    
    Report bugs to <bug-libtool@gnu.org>.
    GNU libtool home page: <http://www.gnu.org/s/libtool/>.
    General help using GNU software: <http://www.gnu.org/gethelp/>."
        exit 0
    }
    
    
    # func_lo2o OBJECT-NAME
    # ---------------------
    # Transform OBJECT-NAME from a '.lo' suffix to the platform specific
    # object suffix.
    
    lo2o=s/\\.lo\$/.$objext/
    o2lo=s/\\.$objext\$/.lo/
    
    if test yes = "$_G_HAVE_XSI_OPS"; then
      eval 'func_lo2o ()
      {
        case $1 in
          *.lo) func_lo2o_result=${1%.lo}.$objext ;;
          *   ) func_lo2o_result=$1               ;;
        esac
      }'
    
      # func_xform LIBOBJ-OR-SOURCE
      # ---------------------------
      # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
      # suffix to a '.lo' libtool-object suffix.
      eval 'func_xform ()
      {
        func_xform_result=${1%.*}.lo
      }'
    else
      # ...otherwise fall back to using sed.
      func_lo2o ()
      {
        func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
      }
    
      func_xform ()
      {
        func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
      }
    fi
    
    
    # func_fatal_configuration ARG...
    # -------------------------------
    # Echo program name prefixed message to standard error, followed by
    # a configuration failure hint, and exit.
    func_fatal_configuration ()
    {
        func_fatal_error ${1+"$@"} \
          "See the $PACKAGE documentation for more information." \
          "Fatal configuration error."
    }
    
    
    # func_config
    # -----------
    # Display the configuration for all the tags in this script.
    func_config ()
    {
        re_begincf='^# ### BEGIN LIBTOOL'
        re_endcf='^# ### END LIBTOOL'
    
        # Default configuration.
        $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
    
        # Now print the configurations for the tags.
        for tagname in $taglist; do
          $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
        done
    
        exit $?
    }
    
    
    # func_features
    # -------------
    # Display the features supported by this script.
    func_features ()
    {
        echo "host: $host"
        if test yes = "$build_libtool_libs"; then
          echo "enable shared libraries"
        else
          echo "disable shared libraries"
        fi
        if test yes = "$build_old_libs"; then
          echo "enable static libraries"
        else
          echo "disable static libraries"
        fi
    
        exit $?
    }
    
    
    # func_enable_tag TAGNAME
    # -----------------------
    # Verify that TAGNAME is valid, and either flag an error and exit, or
    # enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
    # variable here.
    func_enable_tag ()
    {
        # Global variable:
        tagname=$1
    
        re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
        re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
        sed_extractcf=/$re_begincf/,/$re_endcf/p
    
        # Validate tagname.
        case $tagname in
          *[!-_A-Za-z0-9,/]*)
            func_fatal_error "invalid tag name: $tagname"
            ;;
        esac
    
        # Don't test for the "default" C tag, as we know it's
        # there but not specially marked.
        case $tagname in
            CC) ;;
        *)
            if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
    	  taglist="$taglist $tagname"
    
    	  # Evaluate the configuration.  Be careful to quote the path
    	  # and the sed script, to avoid splitting on whitespace, but
    	  # also don't use non-portable quotes within backquotes within
    	  # quotes we have to do it in 2 steps:
    	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
    	  eval "$extractedcf"
            else
    	  func_error "ignoring unknown tag $tagname"
            fi
            ;;
        esac
    }
    
    
    # func_check_version_match
    # ------------------------
    # Ensure that we are using m4 macros, and libtool script from the same
    # release of libtool.
    func_check_version_match ()
    {
        if test "$package_revision" != "$macro_revision"; then
          if test "$VERSION" != "$macro_version"; then
            if test -z "$macro_version"; then
              cat >&2 <<_LT_EOF
    $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
    $progname: definition of this LT_INIT comes from an older release.
    $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
    $progname: and run autoconf again.
    _LT_EOF
            else
              cat >&2 <<_LT_EOF
    $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
    $progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
    $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
    $progname: and run autoconf again.
    _LT_EOF
            fi
          else
            cat >&2 <<_LT_EOF
    $progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
    $progname: but the definition of this LT_INIT comes from revision $macro_revision.
    $progname: You should recreate aclocal.m4 with macros from revision $package_revision
    $progname: of $PACKAGE $VERSION and run autoconf again.
    _LT_EOF
          fi
    
          exit $EXIT_MISMATCH
        fi
    }
    
    
    # libtool_options_prep [ARG]...
    # -----------------------------
    # Preparation for options parsed by libtool.
    libtool_options_prep ()
    {
        $debug_mode
    
        # Option defaults:
        opt_config=false
        opt_dlopen=
        opt_dry_run=false
        opt_help=false
        opt_mode=
        opt_preserve_dup_deps=false
        opt_quiet=false
    
        nonopt=
        preserve_args=
    
        _G_rc_lt_options_prep=:
    
        _G_rc_lt_options_prep=:
    
        # Shorthand for --mode=foo, only valid as the first argument
        case $1 in
        clean|clea|cle|cl)
          shift; set dummy --mode clean ${1+"$@"}; shift
          ;;
        compile|compil|compi|comp|com|co|c)
          shift; set dummy --mode compile ${1+"$@"}; shift
          ;;
        execute|execut|execu|exec|exe|ex|e)
          shift; set dummy --mode execute ${1+"$@"}; shift
          ;;
        finish|finis|fini|fin|fi|f)
          shift; set dummy --mode finish ${1+"$@"}; shift
          ;;
        install|instal|insta|inst|ins|in|i)
          shift; set dummy --mode install ${1+"$@"}; shift
          ;;
        link|lin|li|l)
          shift; set dummy --mode link ${1+"$@"}; shift
          ;;
        uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
          shift; set dummy --mode uninstall ${1+"$@"}; shift
          ;;
        *)
          _G_rc_lt_options_prep=false
          ;;
        esac
    
        if $_G_rc_lt_options_prep; then
          # Pass back the list of options.
          func_quote eval ${1+"$@"}
          libtool_options_prep_result=$func_quote_result
        fi
    }
    func_add_hook func_options_prep libtool_options_prep
    
    
    # libtool_parse_options [ARG]...
    # ---------------------------------
    # Provide handling for libtool specific options.
    libtool_parse_options ()
    {
        $debug_cmd
    
        _G_rc_lt_parse_options=false
    
        # Perform our own loop to consume as many options as possible in
        # each iteration.
        while test $# -gt 0; do
          _G_match_lt_parse_options=:
          _G_opt=$1
          shift
          case $_G_opt in
            --dry-run|--dryrun|-n)
                            opt_dry_run=:
                            ;;
    
            --config)       func_config ;;
    
            --dlopen|-dlopen)
                            opt_dlopen="${opt_dlopen+$opt_dlopen
    }$1"
                            shift
                            ;;
    
            --preserve-dup-deps)
                            opt_preserve_dup_deps=: ;;
    
            --features)     func_features ;;
    
            --finish)       set dummy --mode finish ${1+"$@"}; shift ;;
    
            --help)         opt_help=: ;;
    
            --help-all)     opt_help=': help-all' ;;
    
            --mode)         test $# = 0 && func_missing_arg $_G_opt && break
                            opt_mode=$1
                            case $1 in
                              # Valid mode arguments:
                              clean|compile|execute|finish|install|link|relink|uninstall) ;;
    
                              # Catch anything else as an error
                              *) func_error "invalid argument for $_G_opt"
                                 exit_cmd=exit
                                 break
                                 ;;
                            esac
                            shift
                            ;;
    
            --no-silent|--no-quiet)
                            opt_quiet=false
                            func_append preserve_args " $_G_opt"
                            ;;
    
            --no-warnings|--no-warning|--no-warn)
                            opt_warning=false
                            func_append preserve_args " $_G_opt"
                            ;;
    
            --no-verbose)
                            opt_verbose=false
                            func_append preserve_args " $_G_opt"
                            ;;
    
            --silent|--quiet)
                            opt_quiet=:
                            opt_verbose=false
                            func_append preserve_args " $_G_opt"
                            ;;
    
            --tag)          test $# = 0 && func_missing_arg $_G_opt && break
                            opt_tag=$1
                            func_append preserve_args " $_G_opt $1"
                            func_enable_tag "$1"
                            shift
                            ;;
    
            --verbose|-v)   opt_quiet=false
                            opt_verbose=:
                            func_append preserve_args " $_G_opt"
                            ;;
    
            # An option not handled by this hook function:
            *)              set dummy "$_G_opt" ${1+"$@"} ; shift
                            _G_match_lt_parse_options=false
                            break
                            ;;
          esac
          $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
        done
    
        if $_G_rc_lt_parse_options; then
          # save modified positional parameters for caller
          func_quote eval ${1+"$@"}
          libtool_parse_options_result=$func_quote_result
        fi
    }
    func_add_hook func_parse_options libtool_parse_options
    
    
    
    # libtool_validate_options [ARG]...
    # ---------------------------------
    # Perform any sanity checks on option settings and/or unconsumed
    # arguments.
    libtool_validate_options ()
    {
        # save first non-option argument
        if test 0 -lt $#; then
          nonopt=$1
          shift
        fi
    
        # preserve --debug
        test : = "$debug_cmd" || func_append preserve_args " --debug"
    
        case $host in
          # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
          # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
          *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
            # don't eliminate duplications in $postdeps and $predeps
            opt_duplicate_compiler_generated_deps=:
            ;;
          *)
            opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
            ;;
        esac
    
        $opt_help || {
          # Sanity checks first:
          func_check_version_match
    
          test yes != "$build_libtool_libs" \
            && test yes != "$build_old_libs" \
            && func_fatal_configuration "not configured to build any kind of library"
    
          # Darwin sucks
          eval std_shrext=\"$shrext_cmds\"
    
          # Only execute mode is allowed to have -dlopen flags.
          if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
            func_error "unrecognized option '-dlopen'"
            $ECHO "$help" 1>&2
            exit $EXIT_FAILURE
          fi
    
          # Change the help message to a mode-specific one.
          generic_help=$help
          help="Try '$progname --help --mode=$opt_mode' for more information."
        }
    
        # Pass back the unparsed argument list
        func_quote eval ${1+"$@"}
        libtool_validate_options_result=$func_quote_result
    }
    func_add_hook func_validate_options libtool_validate_options
    
    
    # Process options as early as possible so that --help and --version
    # can return quickly.
    func_options ${1+"$@"}
    eval set dummy "$func_options_result"; shift
    
    
    
    ## ----------- ##
    ##    Main.    ##
    ## ----------- ##
    
    magic='%%%MAGIC variable%%%'
    magic_exe='%%%MAGIC EXE variable%%%'
    
    # Global variables.
    extracted_archives=
    extracted_serial=0
    
    # If this variable is set in any of the actions, the command in it
    # will be execed at the end.  This prevents here-documents from being
    # left over by shells.
    exec_cmd=
    
    
    # A function that is used when there is no print builtin or printf.
    func_fallback_echo ()
    {
      eval 'cat <<_LTECHO_EOF
    $1
    _LTECHO_EOF'
    }
    
    # func_generated_by_libtool
    # True iff stdin has been generated by Libtool. This function is only
    # a basic sanity check; it will hardly flush out determined imposters.
    func_generated_by_libtool_p ()
    {
      $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
    }
    
    # func_lalib_p file
    # True iff FILE is a libtool '.la' library or '.lo' object file.
    # This function is only a basic sanity check; it will hardly flush out
    # determined imposters.
    func_lalib_p ()
    {
        test -f "$1" &&
          $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
    }
    
    # func_lalib_unsafe_p file
    # True iff FILE is a libtool '.la' library or '.lo' object file.
    # This function implements the same check as func_lalib_p without
    # resorting to external programs.  To this end, it redirects stdin and
    # closes it afterwards, without saving the original file descriptor.
    # As a safety measure, use it only where a negative result would be
    # fatal anyway.  Works if 'file' does not exist.
    func_lalib_unsafe_p ()
    {
        lalib_p=no
        if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
    	for lalib_p_l in 1 2 3 4
    	do
    	    read lalib_p_line
    	    case $lalib_p_line in
    		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
    	    esac
    	done
    	exec 0<&5 5<&-
        fi
        test yes = "$lalib_p"
    }
    
    # func_ltwrapper_script_p file
    # True iff FILE is a libtool wrapper script
    # This function is only a basic sanity check; it will hardly flush out
    # determined imposters.
    func_ltwrapper_script_p ()
    {
        test -f "$1" &&
          $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
    }
    
    # func_ltwrapper_executable_p file
    # True iff FILE is a libtool wrapper executable
    # This function is only a basic sanity check; it will hardly flush out
    # determined imposters.
    func_ltwrapper_executable_p ()
    {
        func_ltwrapper_exec_suffix=
        case $1 in
        *.exe) ;;
        *) func_ltwrapper_exec_suffix=.exe ;;
        esac
        $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
    }
    
    # func_ltwrapper_scriptname file
    # Assumes file is an ltwrapper_executable
    # uses $file to determine the appropriate filename for a
    # temporary ltwrapper_script.
    func_ltwrapper_scriptname ()
    {
        func_dirname_and_basename "$1" "" "."
        func_stripname '' '.exe' "$func_basename_result"
        func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
    }
    
    # func_ltwrapper_p file
    # True iff FILE is a libtool wrapper script or wrapper executable
    # This function is only a basic sanity check; it will hardly flush out
    # determined imposters.
    func_ltwrapper_p ()
    {
        func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
    }
    
    
    # func_execute_cmds commands fail_cmd
    # Execute tilde-delimited COMMANDS.
    # If FAIL_CMD is given, eval that upon failure.
    # FAIL_CMD may read-access the current command in variable CMD!
    func_execute_cmds ()
    {
        $debug_cmd
    
        save_ifs=$IFS; IFS='~'
        for cmd in $1; do
          IFS=$sp$nl
          eval cmd=\"$cmd\"
          IFS=$save_ifs
          func_show_eval "$cmd" "${2-:}"
        done
        IFS=$save_ifs
    }
    
    
    # func_source file
    # Source FILE, adding directory component if necessary.
    # Note that it is not necessary on cygwin/mingw to append a dot to
    # FILE even if both FILE and FILE.exe exist: automatic-append-.exe
    # behavior happens only for exec(3), not for open(2)!  Also, sourcing
    # 'FILE.' does not work on cygwin managed mounts.
    func_source ()
    {
        $debug_cmd
    
        case $1 in
        */* | *\\*)	. "$1" ;;
        *)		. "./$1" ;;
        esac
    }
    
    
    # func_resolve_sysroot PATH
    # Replace a leading = in PATH with a sysroot.  Store the result into
    # func_resolve_sysroot_result
    func_resolve_sysroot ()
    {
      func_resolve_sysroot_result=$1
      case $func_resolve_sysroot_result in
      =*)
        func_stripname '=' '' "$func_resolve_sysroot_result"
        func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
        ;;
      esac
    }
    
    # func_replace_sysroot PATH
    # If PATH begins with the sysroot, replace it with = and
    # store the result into func_replace_sysroot_result.
    func_replace_sysroot ()
    {
      case $lt_sysroot:$1 in
      ?*:"$lt_sysroot"*)
        func_stripname "$lt_sysroot" '' "$1"
        func_replace_sysroot_result='='$func_stripname_result
        ;;
      *)
        # Including no sysroot.
        func_replace_sysroot_result=$1
        ;;
      esac
    }
    
    # func_infer_tag arg
    # Infer tagged configuration to use if any are available and
    # if one wasn't chosen via the "--tag" command line option.
    # Only attempt this if the compiler in the base compile
    # command doesn't match the default compiler.
    # arg is usually of the form 'gcc ...'
    func_infer_tag ()
    {
        $debug_cmd
    
        if test -n "$available_tags" && test -z "$tagname"; then
          CC_quoted=
          for arg in $CC; do
    	func_append_quoted CC_quoted "$arg"
          done
          CC_expanded=`func_echo_all $CC`
          CC_quoted_expanded=`func_echo_all $CC_quoted`
          case $@ in
          # Blanks in the command may have been stripped by the calling shell,
          # but not from the CC environment variable when configure was run.
          " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
          " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
          # Blanks at the start of $base_compile will cause this to fail
          # if we don't check for them as well.
          *)
    	for z in $available_tags; do
    	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
    	    # Evaluate the configuration.
    	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
    	    CC_quoted=
    	    for arg in $CC; do
    	      # Double-quote args containing other shell metacharacters.
    	      func_append_quoted CC_quoted "$arg"
    	    done
    	    CC_expanded=`func_echo_all $CC`
    	    CC_quoted_expanded=`func_echo_all $CC_quoted`
    	    case "$@ " in
    	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
    	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
    	      # The compiler in the base compile command matches
    	      # the one in the tagged configuration.
    	      # Assume this is the tagged configuration we want.
    	      tagname=$z
    	      break
    	      ;;
    	    esac
    	  fi
    	done
    	# If $tagname still isn't set, then no tagged configuration
    	# was found and let the user know that the "--tag" command
    	# line option must be used.
    	if test -z "$tagname"; then
    	  func_echo "unable to infer tagged configuration"
    	  func_fatal_error "specify a tag with '--tag'"
    #	else
    #	  func_verbose "using $tagname tagged configuration"
    	fi
    	;;
          esac
        fi
    }
    
    
    
    # func_write_libtool_object output_name pic_name nonpic_name
    # Create a libtool object file (analogous to a ".la" file),
    # but don't create it if we're doing a dry run.
    func_write_libtool_object ()
    {
        write_libobj=$1
        if test yes = "$build_libtool_libs"; then
          write_lobj=\'$2\'
        else
          write_lobj=none
        fi
    
        if test yes = "$build_old_libs"; then
          write_oldobj=\'$3\'
        else
          write_oldobj=none
        fi
    
        $opt_dry_run || {
          cat >${write_libobj}T <<EOF
    # $write_libobj - a libtool object file
    # Generated by $PROGRAM (GNU $PACKAGE) $VERSION
    #
    # Please DO NOT delete this file!
    # It is necessary for linking the library.
    
    # Name of the PIC object.
    pic_object=$write_lobj
    
    # Name of the non-PIC object
    non_pic_object=$write_oldobj
    
    EOF
          $MV "${write_libobj}T" "$write_libobj"
        }
    }
    
    
    ##################################################
    # FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
    ##################################################
    
    # func_convert_core_file_wine_to_w32 ARG
    # Helper function used by file name conversion functions when $build is *nix,
    # and $host is mingw, cygwin, or some other w32 environment. Relies on a
    # correctly configured wine environment available, with the winepath program
    # in $build's $PATH.
    #
    # ARG is the $build file name to be converted to w32 format.
    # Result is available in $func_convert_core_file_wine_to_w32_result, and will
    # be empty on error (or when ARG is empty)
    func_convert_core_file_wine_to_w32 ()
    {
      $debug_cmd
    
      func_convert_core_file_wine_to_w32_result=$1
      if test -n "$1"; then
        # Unfortunately, winepath does not exit with a non-zero error code, so we
        # are forced to check the contents of stdout. On the other hand, if the
        # command is not found, the shell will set an exit code of 127 and print
        # *an error message* to stdout. So we must check for both error code of
        # zero AND non-empty stdout, which explains the odd construction:
        func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
        if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
          func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
            $SED -e "$sed_naive_backslashify"`
        else
          func_convert_core_file_wine_to_w32_result=
        fi
      fi
    }
    # end: func_convert_core_file_wine_to_w32
    
    
    # func_convert_core_path_wine_to_w32 ARG
    # Helper function used by path conversion functions when $build is *nix, and
    # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
    # configured wine environment available, with the winepath program in $build's
    # $PATH. Assumes ARG has no leading or trailing path separator characters.
    #
    # ARG is path to be converted from $build format to win32.
    # Result is available in $func_convert_core_path_wine_to_w32_result.
    # Unconvertible file (directory) names in ARG are skipped; if no directory names
    # are convertible, then the result may be empty.
    func_convert_core_path_wine_to_w32 ()
    {
      $debug_cmd
    
      # unfortunately, winepath doesn't convert paths, only file names
      func_convert_core_path_wine_to_w32_result=
      if test -n "$1"; then
        oldIFS=$IFS
        IFS=:
        for func_convert_core_path_wine_to_w32_f in $1; do
          IFS=$oldIFS
          func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
          if test -n "$func_convert_core_file_wine_to_w32_result"; then
            if test -z "$func_convert_core_path_wine_to_w32_result"; then
              func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
            else
              func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
            fi
          fi
        done
        IFS=$oldIFS
      fi
    }
    # end: func_convert_core_path_wine_to_w32
    
    
    # func_cygpath ARGS...
    # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
    # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
    # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
    # (2), returns the Cygwin file name or path in func_cygpath_result (input
    # file name or path is assumed to be in w32 format, as previously converted
    # from $build's *nix or MSYS format). In case (3), returns the w32 file name
    # or path in func_cygpath_result (input file name or path is assumed to be in
    # Cygwin format). Returns an empty string on error.
    #
    # ARGS are passed to cygpath, with the last one being the file name or path to
    # be converted.
    #
    # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
    # environment variable; do not put it in $PATH.
    func_cygpath ()
    {
      $debug_cmd
    
      if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
        func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
        if test "$?" -ne 0; then
          # on failure, ensure result is empty
          func_cygpath_result=
        fi
      else
        func_cygpath_result=
        func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
      fi
    }
    #end: func_cygpath
    
    
    # func_convert_core_msys_to_w32 ARG
    # Convert file name or path ARG from MSYS format to w32 format.  Return
    # result in func_convert_core_msys_to_w32_result.
    func_convert_core_msys_to_w32 ()
    {
      $debug_cmd
    
      # awkward: cmd appends spaces to result
      func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
        $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
    }
    #end: func_convert_core_msys_to_w32
    
    
    # func_convert_file_check ARG1 ARG2
    # Verify that ARG1 (a file name in $build format) was converted to $host
    # format in ARG2. Otherwise, emit an error message, but continue (resetting
    # func_to_host_file_result to ARG1).
    func_convert_file_check ()
    {
      $debug_cmd
    
      if test -z "$2" && test -n "$1"; then
        func_error "Could not determine host file name corresponding to"
        func_error "  '$1'"
        func_error "Continuing, but uninstalled executables may not work."
        # Fallback:
        func_to_host_file_result=$1
      fi
    }
    # end func_convert_file_check
    
    
    # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
    # Verify that FROM_PATH (a path in $build format) was converted to $host
    # format in TO_PATH. Otherwise, emit an error message, but continue, resetting
    # func_to_host_file_result to a simplistic fallback value (see below).
    func_convert_path_check ()
    {
      $debug_cmd
    
      if test -z "$4" && test -n "$3"; then
        func_error "Could not determine the host path corresponding to"
        func_error "  '$3'"
        func_error "Continuing, but uninstalled executables may not work."
        # Fallback.  This is a deliberately simplistic "conversion" and
        # should not be "improved".  See libtool.info.
        if test "x$1" != "x$2"; then
          lt_replace_pathsep_chars="s|$1|$2|g"
          func_to_host_path_result=`echo "$3" |
            $SED -e "$lt_replace_pathsep_chars"`
        else
          func_to_host_path_result=$3
        fi
      fi
    }
    # end func_convert_path_check
    
    
    # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
    # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
    # and appending REPL if ORIG matches BACKPAT.
    func_convert_path_front_back_pathsep ()
    {
      $debug_cmd
    
      case $4 in
      $1 ) func_to_host_path_result=$3$func_to_host_path_result
        ;;
      esac
      case $4 in
      $2 ) func_append func_to_host_path_result "$3"
        ;;
      esac
    }
    # end func_convert_path_front_back_pathsep
    
    
    ##################################################
    # $build to $host FILE NAME CONVERSION FUNCTIONS #
    ##################################################
    # invoked via '$to_host_file_cmd ARG'
    #
    # In each case, ARG is the path to be converted from $build to $host format.
    # Result will be available in $func_to_host_file_result.
    
    
    # func_to_host_file ARG
    # Converts the file name ARG from $build format to $host format. Return result
    # in func_to_host_file_result.
    func_to_host_file ()
    {
      $debug_cmd
    
      $to_host_file_cmd "$1"
    }
    # end func_to_host_file
    
    
    # func_to_tool_file ARG LAZY
    # converts the file name ARG from $build format to toolchain format. Return
    # result in func_to_tool_file_result.  If the conversion in use is listed
    # in (the comma separated) LAZY, no conversion takes place.
    func_to_tool_file ()
    {
      $debug_cmd
    
      case ,$2, in
        *,"$to_tool_file_cmd",*)
          func_to_tool_file_result=$1
          ;;
        *)
          $to_tool_file_cmd "$1"
          func_to_tool_file_result=$func_to_host_file_result
          ;;
      esac
    }
    # end func_to_tool_file
    
    
    # func_convert_file_noop ARG
    # Copy ARG to func_to_host_file_result.
    func_convert_file_noop ()
    {
      func_to_host_file_result=$1
    }
    # end func_convert_file_noop
    
    
    # func_convert_file_msys_to_w32 ARG
    # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
    # conversion to w32 is not available inside the cwrapper.  Returns result in
    # func_to_host_file_result.
    func_convert_file_msys_to_w32 ()
    {
      $debug_cmd
    
      func_to_host_file_result=$1
      if test -n "$1"; then
        func_convert_core_msys_to_w32 "$1"
        func_to_host_file_result=$func_convert_core_msys_to_w32_result
      fi
      func_convert_file_check "$1" "$func_to_host_file_result"
    }
    # end func_convert_file_msys_to_w32
    
    
    # func_convert_file_cygwin_to_w32 ARG
    # Convert file name ARG from Cygwin to w32 format.  Returns result in
    # func_to_host_file_result.
    func_convert_file_cygwin_to_w32 ()
    {
      $debug_cmd
    
      func_to_host_file_result=$1
      if test -n "$1"; then
        # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
        # LT_CYGPATH in this case.
        func_to_host_file_result=`cygpath -m "$1"`
      fi
      func_convert_file_check "$1" "$func_to_host_file_result"
    }
    # end func_convert_file_cygwin_to_w32
    
    
    # func_convert_file_nix_to_w32 ARG
    # Convert file name ARG from *nix to w32 format.  Requires a wine environment
    # and a working winepath. Returns result in func_to_host_file_result.
    func_convert_file_nix_to_w32 ()
    {
      $debug_cmd
    
      func_to_host_file_result=$1
      if test -n "$1"; then
        func_convert_core_file_wine_to_w32 "$1"
        func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
      fi
      func_convert_file_check "$1" "$func_to_host_file_result"
    }
    # end func_convert_file_nix_to_w32
    
    
    # func_convert_file_msys_to_cygwin ARG
    # Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
    # Returns result in func_to_host_file_result.
    func_convert_file_msys_to_cygwin ()
    {
      $debug_cmd
    
      func_to_host_file_result=$1
      if test -n "$1"; then
        func_convert_core_msys_to_w32 "$1"
        func_cygpath -u "$func_convert_core_msys_to_w32_result"
        func_to_host_file_result=$func_cygpath_result
      fi
      func_convert_file_check "$1" "$func_to_host_file_result"
    }
    # end func_convert_file_msys_to_cygwin
    
    
    # func_convert_file_nix_to_cygwin ARG
    # Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
    # in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
    # in func_to_host_file_result.
    func_convert_file_nix_to_cygwin ()
    {
      $debug_cmd
    
      func_to_host_file_result=$1
      if test -n "$1"; then
        # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
        func_convert_core_file_wine_to_w32 "$1"
        func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
        func_to_host_file_result=$func_cygpath_result
      fi
      func_convert_file_check "$1" "$func_to_host_file_result"
    }
    # end func_convert_file_nix_to_cygwin
    
    
    #############################################
    # $build to $host PATH CONVERSION FUNCTIONS #
    #############################################
    # invoked via '$to_host_path_cmd ARG'
    #
    # In each case, ARG is the path to be converted from $build to $host format.
    # The result will be available in $func_to_host_path_result.
    #
    # Path separators are also converted from $build format to $host format.  If
    # ARG begins or ends with a path separator character, it is preserved (but
    # converted to $host format) on output.
    #
    # All path conversion functions are named using the following convention:
    #   file name conversion function    : func_convert_file_X_to_Y ()
    #   path conversion function         : func_convert_path_X_to_Y ()
    # where, for any given $build/$host combination the 'X_to_Y' value is the
    # same.  If conversion functions are added for new $build/$host combinations,
    # the two new functions must follow this pattern, or func_init_to_host_path_cmd
    # will break.
    
    
    # func_init_to_host_path_cmd
    # Ensures that function "pointer" variable $to_host_path_cmd is set to the
    # appropriate value, based on the value of $to_host_file_cmd.
    to_host_path_cmd=
    func_init_to_host_path_cmd ()
    {
      $debug_cmd
    
      if test -z "$to_host_path_cmd"; then
        func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
        to_host_path_cmd=func_convert_path_$func_stripname_result
      fi
    }
    
    
    # func_to_host_path ARG
    # Converts the path ARG from $build format to $host format. Return result
    # in func_to_host_path_result.
    func_to_host_path ()
    {
      $debug_cmd
    
      func_init_to_host_path_cmd
      $to_host_path_cmd "$1"
    }
    # end func_to_host_path
    
    
    # func_convert_path_noop ARG
    # Copy ARG to func_to_host_path_result.
    func_convert_path_noop ()
    {
      func_to_host_path_result=$1
    }
    # end func_convert_path_noop
    
    
    # func_convert_path_msys_to_w32 ARG
    # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
    # conversion to w32 is not available inside the cwrapper.  Returns result in
    # func_to_host_path_result.
    func_convert_path_msys_to_w32 ()
    {
      $debug_cmd
    
      func_to_host_path_result=$1
      if test -n "$1"; then
        # Remove leading and trailing path separator characters from ARG.  MSYS
        # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
        # and winepath ignores them completely.
        func_stripname : : "$1"
        func_to_host_path_tmp1=$func_stripname_result
        func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
        func_to_host_path_result=$func_convert_core_msys_to_w32_result
        func_convert_path_check : ";" \
          "$func_to_host_path_tmp1" "$func_to_host_path_result"
        func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
      fi
    }
    # end func_convert_path_msys_to_w32
    
    
    # func_convert_path_cygwin_to_w32 ARG
    # Convert path ARG from Cygwin to w32 format.  Returns result in
    # func_to_host_file_result.
    func_convert_path_cygwin_to_w32 ()
    {
      $debug_cmd
    
      func_to_host_path_result=$1
      if test -n "$1"; then
        # See func_convert_path_msys_to_w32:
        func_stripname : : "$1"
        func_to_host_path_tmp1=$func_stripname_result
        func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
        func_convert_path_check : ";" \
          "$func_to_host_path_tmp1" "$func_to_host_path_result"
        func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
      fi
    }
    # end func_convert_path_cygwin_to_w32
    
    
    # func_convert_path_nix_to_w32 ARG
    # Convert path ARG from *nix to w32 format.  Requires a wine environment and
    # a working winepath.  Returns result in func_to_host_file_result.
    func_convert_path_nix_to_w32 ()
    {
      $debug_cmd
    
      func_to_host_path_result=$1
      if test -n "$1"; then
        # See func_convert_path_msys_to_w32:
        func_stripname : : "$1"
        func_to_host_path_tmp1=$func_stripname_result
        func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
        func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
        func_convert_path_check : ";" \
          "$func_to_host_path_tmp1" "$func_to_host_path_result"
        func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
      fi
    }
    # end func_convert_path_nix_to_w32
    
    
    # func_convert_path_msys_to_cygwin ARG
    # Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
    # Returns result in func_to_host_file_result.
    func_convert_path_msys_to_cygwin ()
    {
      $debug_cmd
    
      func_to_host_path_result=$1
      if test -n "$1"; then
        # See func_convert_path_msys_to_w32:
        func_stripname : : "$1"
        func_to_host_path_tmp1=$func_stripname_result
        func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
        func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
        func_to_host_path_result=$func_cygpath_result
        func_convert_path_check : : \
          "$func_to_host_path_tmp1" "$func_to_host_path_result"
        func_convert_path_front_back_pathsep ":*" "*:" : "$1"
      fi
    }
    # end func_convert_path_msys_to_cygwin
    
    
    # func_convert_path_nix_to_cygwin ARG
    # Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
    # a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
    # func_to_host_file_result.
    func_convert_path_nix_to_cygwin ()
    {
      $debug_cmd
    
      func_to_host_path_result=$1
      if test -n "$1"; then
        # Remove leading and trailing path separator characters from
        # ARG. msys behavior is inconsistent here, cygpath turns them
        # into '.;' and ';.', and winepath ignores them completely.
        func_stripname : : "$1"
        func_to_host_path_tmp1=$func_stripname_result
        func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
        func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
        func_to_host_path_result=$func_cygpath_result
        func_convert_path_check : : \
          "$func_to_host_path_tmp1" "$func_to_host_path_result"
        func_convert_path_front_back_pathsep ":*" "*:" : "$1"
      fi
    }
    # end func_convert_path_nix_to_cygwin
    
    
    # func_dll_def_p FILE
    # True iff FILE is a Windows DLL '.def' file.
    # Keep in sync with _LT_DLL_DEF_P in libtool.m4
    func_dll_def_p ()
    {
      $debug_cmd
    
      func_dll_def_p_tmp=`$SED -n \
        -e 's/^[	 ]*//' \
        -e '/^\(;.*\)*$/d' \
        -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
        -e q \
        "$1"`
      test DEF = "$func_dll_def_p_tmp"
    }
    
    
    # func_mode_compile arg...
    func_mode_compile ()
    {
        $debug_cmd
    
        # Get the compilation command and the source file.
        base_compile=
        srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
        suppress_opt=yes
        suppress_output=
        arg_mode=normal
        libobj=
        later=
        pie_flag=
    
        for arg
        do
          case $arg_mode in
          arg  )
    	# do not "continue".  Instead, add this to base_compile
    	lastarg=$arg
    	arg_mode=normal
    	;;
    
          target )
    	libobj=$arg
    	arg_mode=normal
    	continue
    	;;
    
          normal )
    	# Accept any command-line options.
    	case $arg in
    	-o)
    	  test -n "$libobj" && \
    	    func_fatal_error "you cannot specify '-o' more than once"
    	  arg_mode=target
    	  continue
    	  ;;
    
    	-pie | -fpie | -fPIE)
              func_append pie_flag " $arg"
    	  continue
    	  ;;
    
    	-shared | -static | -prefer-pic | -prefer-non-pic)
    	  func_append later " $arg"
    	  continue
    	  ;;
    
    	-no-suppress)
    	  suppress_opt=no
    	  continue
    	  ;;
    
    	-Xcompiler)
    	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
    	  continue      #  The current "srcfile" will either be retained or
    	  ;;            #  replaced later.  I would guess that would be a bug.
    
    	-Wc,*)
    	  func_stripname '-Wc,' '' "$arg"
    	  args=$func_stripname_result
    	  lastarg=
    	  save_ifs=$IFS; IFS=,
    	  for arg in $args; do
    	    IFS=$save_ifs
    	    func_append_quoted lastarg "$arg"
    	  done
    	  IFS=$save_ifs
    	  func_stripname ' ' '' "$lastarg"
    	  lastarg=$func_stripname_result
    
    	  # Add the arguments to base_compile.
    	  func_append base_compile " $lastarg"
    	  continue
    	  ;;
    
    	*)
    	  # Accept the current argument as the source file.
    	  # The previous "srcfile" becomes the current argument.
    	  #
    	  lastarg=$srcfile
    	  srcfile=$arg
    	  ;;
    	esac  #  case $arg
    	;;
          esac    #  case $arg_mode
    
          # Aesthetically quote the previous argument.
          func_append_quoted base_compile "$lastarg"
        done # for arg
    
        case $arg_mode in
        arg)
          func_fatal_error "you must specify an argument for -Xcompile"
          ;;
        target)
          func_fatal_error "you must specify a target with '-o'"
          ;;
        *)
          # Get the name of the library object.
          test -z "$libobj" && {
    	func_basename "$srcfile"
    	libobj=$func_basename_result
          }
          ;;
        esac
    
        # Recognize several different file suffixes.
        # If the user specifies -o file.o, it is replaced with file.lo
        case $libobj in
        *.[cCFSifmso] | \
        *.ada | *.adb | *.ads | *.asm | \
        *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
        *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
          func_xform "$libobj"
          libobj=$func_xform_result
          ;;
        esac
    
        case $libobj in
        *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
        *)
          func_fatal_error "cannot determine name of library object from '$libobj'"
          ;;
        esac
    
        func_infer_tag $base_compile
    
        for arg in $later; do
          case $arg in
          -shared)
    	test yes = "$build_libtool_libs" \
    	  || func_fatal_configuration "cannot build a shared library"
    	build_old_libs=no
    	continue
    	;;
    
          -static)
    	build_libtool_libs=no
    	build_old_libs=yes
    	continue
    	;;
    
          -prefer-pic)
    	pic_mode=yes
    	continue
    	;;
    
          -prefer-non-pic)
    	pic_mode=no
    	continue
    	;;
          esac
        done
    
        func_quote_arg pretty "$libobj"
        test "X$libobj" != "X$func_quote_arg_result" \
          && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
          && func_warning "libobj name '$libobj' may not contain shell special characters."
        func_dirname_and_basename "$obj" "/" ""
        objname=$func_basename_result
        xdir=$func_dirname_result
        lobj=$xdir$objdir/$objname
    
        test -z "$base_compile" && \
          func_fatal_help "you must specify a compilation command"
    
        # Delete any leftover library objects.
        if test yes = "$build_old_libs"; then
          removelist="$obj $lobj $libobj ${libobj}T"
        else
          removelist="$lobj $libobj ${libobj}T"
        fi
    
        # On Cygwin there's no "real" PIC flag so we must build both object types
        case $host_os in
        cygwin* | mingw* | pw32* | os2* | cegcc*)
          pic_mode=default
          ;;
        esac
        if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
          # non-PIC code in shared libraries is not supported
          pic_mode=default
        fi
    
        # Calculate the filename of the output object if compiler does
        # not support -o with -c
        if test no = "$compiler_c_o"; then
          output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
          lockfile=$output_obj.lock
        else
          output_obj=
          need_locks=no
          lockfile=
        fi
    
        # Lock this critical section if it is needed
        # We use this script file to make the link, it avoids creating a new file
        if test yes = "$need_locks"; then
          until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
    	func_echo "Waiting for $lockfile to be removed"
    	sleep 2
          done
        elif test warn = "$need_locks"; then
          if test -f "$lockfile"; then
    	$ECHO "\
    *** ERROR, $lockfile exists and contains:
    `cat $lockfile 2>/dev/null`
    
    This indicates that another process is trying to use the same
    temporary object file, and libtool could not work around it because
    your compiler does not support '-c' and '-o' together.  If you
    repeat this compilation, it may succeed, by chance, but you had better
    avoid parallel builds (make -j) in this platform, or get a better
    compiler."
    
    	$opt_dry_run || $RM $removelist
    	exit $EXIT_FAILURE
          fi
          func_append removelist " $output_obj"
          $ECHO "$srcfile" > "$lockfile"
        fi
    
        $opt_dry_run || $RM $removelist
        func_append removelist " $lockfile"
        trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
    
        func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
        srcfile=$func_to_tool_file_result
        func_quote_arg pretty "$srcfile"
        qsrcfile=$func_quote_arg_result
    
        # Only build a PIC object if we are building libtool libraries.
        if test yes = "$build_libtool_libs"; then
          # Without this assignment, base_compile gets emptied.
          fbsd_hideous_sh_bug=$base_compile
    
          if test no != "$pic_mode"; then
    	command="$base_compile $qsrcfile $pic_flag"
          else
    	# Don't build PIC code
    	command="$base_compile $qsrcfile"
          fi
    
          func_mkdir_p "$xdir$objdir"
    
          if test -z "$output_obj"; then
    	# Place PIC objects in $objdir
    	func_append command " -o $lobj"
          fi
    
          func_show_eval_locale "$command"	\
              'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
    
          if test warn = "$need_locks" &&
    	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
    	$ECHO "\
    *** ERROR, $lockfile contains:
    `cat $lockfile 2>/dev/null`
    
    but it should contain:
    $srcfile
    
    This indicates that another process is trying to use the same
    temporary object file, and libtool could not work around it because
    your compiler does not support '-c' and '-o' together.  If you
    repeat this compilation, it may succeed, by chance, but you had better
    avoid parallel builds (make -j) in this platform, or get a better
    compiler."
    
    	$opt_dry_run || $RM $removelist
    	exit $EXIT_FAILURE
          fi
    
          # Just move the object if needed, then go on to compile the next one
          if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
    	func_show_eval '$MV "$output_obj" "$lobj"' \
    	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
          fi
    
          # Allow error messages only from the first compilation.
          if test yes = "$suppress_opt"; then
    	suppress_output=' >/dev/null 2>&1'
          fi
        fi
    
        # Only build a position-dependent object if we build old libraries.
        if test yes = "$build_old_libs"; then
          if test yes != "$pic_mode"; then
    	# Don't build PIC code
    	command="$base_compile $qsrcfile$pie_flag"
          else
    	command="$base_compile $qsrcfile $pic_flag"
          fi
          if test yes = "$compiler_c_o"; then
    	func_append command " -o $obj"
          fi
    
          # Suppress compiler output if we already did a PIC compilation.
          func_append command "$suppress_output"
          func_show_eval_locale "$command" \
            '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
    
          if test warn = "$need_locks" &&
    	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
    	$ECHO "\
    *** ERROR, $lockfile contains:
    `cat $lockfile 2>/dev/null`
    
    but it should contain:
    $srcfile
    
    This indicates that another process is trying to use the same
    temporary object file, and libtool could not work around it because
    your compiler does not support '-c' and '-o' together.  If you
    repeat this compilation, it may succeed, by chance, but you had better
    avoid parallel builds (make -j) in this platform, or get a better
    compiler."
    
    	$opt_dry_run || $RM $removelist
    	exit $EXIT_FAILURE
          fi
    
          # Just move the object if needed
          if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
    	func_show_eval '$MV "$output_obj" "$obj"' \
    	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
          fi
        fi
    
        $opt_dry_run || {
          func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
    
          # Unlock the critical section if it was locked
          if test no != "$need_locks"; then
    	removelist=$lockfile
            $RM "$lockfile"
          fi
        }
    
        exit $EXIT_SUCCESS
    }
    
    $opt_help || {
      test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
    }
    
    func_mode_help ()
    {
        # We need to display help for each of the modes.
        case $opt_mode in
          "")
            # Generic help is extracted from the usage comments
            # at the start of this file.
            func_help
            ;;
    
          clean)
            $ECHO \
    "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
    
    Remove files from the build directory.
    
    RM is the name of the program to use to delete files associated with each FILE
    (typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
    to RM.
    
    If FILE is a libtool library, object or program, all the files associated
    with it are deleted. Otherwise, only FILE itself is deleted using RM."
            ;;
    
          compile)
          $ECHO \
    "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
    
    Compile a source file into a libtool library object.
    
    This mode accepts the following additional options:
    
      -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
      -no-suppress      do not suppress compiler output for multiple passes
      -prefer-pic       try to build PIC objects only
      -prefer-non-pic   try to build non-PIC objects only
      -shared           do not build a '.o' file suitable for static linking
      -static           only build a '.o' file suitable for static linking
      -Wc,FLAG
      -Xcompiler FLAG   pass FLAG directly to the compiler
    
    COMPILE-COMMAND is a command to be used in creating a 'standard' object file
    from the given SOURCEFILE.
    
    The output file name is determined by removing the directory component from
    SOURCEFILE, then substituting the C source code suffix '.c' with the
    library object suffix, '.lo'."
            ;;
    
          execute)
            $ECHO \
    "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
    
    Automatically set library path, then run a program.
    
    This mode accepts the following additional options:
    
      -dlopen FILE      add the directory containing FILE to the library path
    
    This mode sets the library path environment variable according to '-dlopen'
    flags.
    
    If any of the ARGS are libtool executable wrappers, then they are translated
    into their corresponding uninstalled binary, and any of their required library
    directories are added to the library path.
    
    Then, COMMAND is executed, with ARGS as arguments."
            ;;
    
          finish)
            $ECHO \
    "Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
    
    Complete the installation of libtool libraries.
    
    Each LIBDIR is a directory that contains libtool libraries.
    
    The commands that this mode executes may require superuser privileges.  Use
    the '--dry-run' option if you just want to see what would be executed."
            ;;
    
          install)
            $ECHO \
    "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
    
    Install executables or libraries.
    
    INSTALL-COMMAND is the installation command.  The first component should be
    either the 'install' or 'cp' program.
    
    The following components of INSTALL-COMMAND are treated specially:
    
      -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
    
    The rest of the components are interpreted as arguments to that command (only
    BSD-compatible install options are recognized)."
            ;;
    
          link)
            $ECHO \
    "Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
    
    Link object files or libraries together to form another library, or to
    create an executable program.
    
    LINK-COMMAND is a command using the C compiler that you would use to create
    a program from several object files.
    
    The following components of LINK-COMMAND are treated specially:
    
      -all-static       do not do any dynamic linking at all
      -avoid-version    do not add a version suffix if possible
      -bindir BINDIR    specify path to binaries directory (for systems where
                        libraries must be found in the PATH setting at runtime)
      -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
      -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
      -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
      -export-symbols SYMFILE
                        try to export only the symbols listed in SYMFILE
      -export-symbols-regex REGEX
                        try to export only the symbols matching REGEX
      -LLIBDIR          search LIBDIR for required installed libraries
      -lNAME            OUTPUT-FILE requires the installed library libNAME
      -module           build a library that can dlopened
      -no-fast-install  disable the fast-install mode
      -no-install       link a not-installable executable
      -no-undefined     declare that a library does not refer to external symbols
      -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
      -objectlist FILE  use a list of object files found in FILE to specify objects
      -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
      -precious-files-regex REGEX
                        don't remove output files matching REGEX
      -release RELEASE  specify package release information
      -rpath LIBDIR     the created library will eventually be installed in LIBDIR
      -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
      -shared           only do dynamic linking of libtool libraries
      -shrext SUFFIX    override the standard shared library file extension
      -static           do not do any dynamic linking of uninstalled libtool libraries
      -static-libtool-libs
                        do not do any dynamic linking of libtool libraries
      -version-info CURRENT[:REVISION[:AGE]]
                        specify library version info [each variable defaults to 0]
      -weak LIBNAME     declare that the target provides the LIBNAME interface
      -Wc,FLAG
      -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
      -Wa,FLAG
      -Xassembler FLAG  pass linker-specific FLAG directly to the assembler
      -Wl,FLAG
      -Xlinker FLAG     pass linker-specific FLAG directly to the linker
      -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
    
    All other options (arguments beginning with '-') are ignored.
    
    Every other argument is treated as a filename.  Files ending in '.la' are
    treated as uninstalled libtool libraries, other files are standard or library
    object files.
    
    If the OUTPUT-FILE ends in '.la', then a libtool library is created,
    only library objects ('.lo' files) may be specified, and '-rpath' is
    required, except when creating a convenience library.
    
    If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
    using 'ar' and 'ranlib', or on Windows using 'lib'.
    
    If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
    is created, otherwise an executable program is created."
            ;;
    
          uninstall)
            $ECHO \
    "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
    
    Remove libraries from an installation directory.
    
    RM is the name of the program to use to delete files associated with each FILE
    (typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
    to RM.
    
    If FILE is a libtool library, all the files associated with it are deleted.
    Otherwise, only FILE itself is deleted using RM."
            ;;
    
          *)
            func_fatal_help "invalid operation mode '$opt_mode'"
            ;;
        esac
    
        echo
        $ECHO "Try '$progname --help' for more information about other modes."
    }
    
    # Now that we've collected a possible --mode arg, show help if necessary
    if $opt_help; then
      if test : = "$opt_help"; then
        func_mode_help
      else
        {
          func_help noexit
          for opt_mode in compile link execute install finish uninstall clean; do
    	func_mode_help
          done
        } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
        {
          func_help noexit
          for opt_mode in compile link execute install finish uninstall clean; do
    	echo
    	func_mode_help
          done
        } |
        $SED '1d
          /^When reporting/,/^Report/{
    	H
    	d
          }
          $x
          /information about other modes/d
          /more detailed .*MODE/d
          s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
      fi
      exit $?
    fi
    
    
    # func_mode_execute arg...
    func_mode_execute ()
    {
        $debug_cmd
    
        # The first argument is the command name.
        cmd=$nonopt
        test -z "$cmd" && \
          func_fatal_help "you must specify a COMMAND"
    
        # Handle -dlopen flags immediately.
        for file in $opt_dlopen; do
          test -f "$file" \
    	|| func_fatal_help "'$file' is not a file"
    
          dir=
          case $file in
          *.la)
    	func_resolve_sysroot "$file"
    	file=$func_resolve_sysroot_result
    
    	# Check to see that this really is a libtool archive.
    	func_lalib_unsafe_p "$file" \
    	  || func_fatal_help "'$lib' is not a valid libtool archive"
    
    	# Read the libtool library.
    	dlname=
    	library_names=
    	func_source "$file"
    
    	# Skip this library if it cannot be dlopened.
    	if test -z "$dlname"; then
    	  # Warn if it was a shared library.
    	  test -n "$library_names" && \
    	    func_warning "'$file' was not linked with '-export-dynamic'"
    	  continue
    	fi
    
    	func_dirname "$file" "" "."
    	dir=$func_dirname_result
    
    	if test -f "$dir/$objdir/$dlname"; then
    	  func_append dir "/$objdir"
    	else
    	  if test ! -f "$dir/$dlname"; then
    	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
    	  fi
    	fi
    	;;
    
          *.lo)
    	# Just add the directory containing the .lo file.
    	func_dirname "$file" "" "."
    	dir=$func_dirname_result
    	;;
    
          *)
    	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
    	continue
    	;;
          esac
    
          # Get the absolute pathname.
          absdir=`cd "$dir" && pwd`
          test -n "$absdir" && dir=$absdir
    
          # Now add the directory to shlibpath_var.
          if eval "test -z \"\$$shlibpath_var\""; then
    	eval "$shlibpath_var=\"\$dir\""
          else
    	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
          fi
        done
    
        # This variable tells wrapper scripts just to set shlibpath_var
        # rather than running their programs.
        libtool_execute_magic=$magic
    
        # Check if any of the arguments is a wrapper script.
        args=
        for file
        do
          case $file in
          -* | *.la | *.lo ) ;;
          *)
    	# Do a test to see if this is really a libtool program.
    	if func_ltwrapper_script_p "$file"; then
    	  func_source "$file"
    	  # Transform arg to wrapped name.
    	  file=$progdir/$program
    	elif func_ltwrapper_executable_p "$file"; then
    	  func_ltwrapper_scriptname "$file"
    	  func_source "$func_ltwrapper_scriptname_result"
    	  # Transform arg to wrapped name.
    	  file=$progdir/$program
    	fi
    	;;
          esac
          # Quote arguments (to preserve shell metacharacters).
          func_append_quoted args "$file"
        done
    
        if $opt_dry_run; then
          # Display what would be done.
          if test -n "$shlibpath_var"; then
    	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
    	echo "export $shlibpath_var"
          fi
          $ECHO "$cmd$args"
          exit $EXIT_SUCCESS
        else
          if test -n "$shlibpath_var"; then
    	# Export the shlibpath_var.
    	eval "export $shlibpath_var"
          fi
    
          # Restore saved environment variables
          for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
          do
    	eval "if test \"\${save_$lt_var+set}\" = set; then
                    $lt_var=\$save_$lt_var; export $lt_var
    	      else
    		$lt_unset $lt_var
    	      fi"
          done
    
          # Now prepare to actually exec the command.
          exec_cmd=\$cmd$args
        fi
    }
    
    test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
    
    
    # func_mode_finish arg...
    func_mode_finish ()
    {
        $debug_cmd
    
        libs=
        libdirs=
        admincmds=
    
        for opt in "$nonopt" ${1+"$@"}
        do
          if test -d "$opt"; then
    	func_append libdirs " $opt"
    
          elif test -f "$opt"; then
    	if func_lalib_unsafe_p "$opt"; then
    	  func_append libs " $opt"
    	else
    	  func_warning "'$opt' is not a valid libtool archive"
    	fi
    
          else
    	func_fatal_error "invalid argument '$opt'"
          fi
        done
    
        if test -n "$libs"; then
          if test -n "$lt_sysroot"; then
            sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
            sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
          else
            sysroot_cmd=
          fi
    
          # Remove sysroot references
          if $opt_dry_run; then
            for lib in $libs; do
              echo "removing references to $lt_sysroot and '=' prefixes from $lib"
            done
          else
            tmpdir=`func_mktempdir`
            for lib in $libs; do
    	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
    	    > $tmpdir/tmp-la
    	  mv -f $tmpdir/tmp-la $lib
    	done
            ${RM}r "$tmpdir"
          fi
        fi
    
        if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
          for libdir in $libdirs; do
    	if test -n "$finish_cmds"; then
    	  # Do each command in the finish commands.
    	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
    '"$cmd"'"'
    	fi
    	if test -n "$finish_eval"; then
    	  # Do the single finish_eval.
    	  eval cmds=\"$finish_eval\"
    	  $opt_dry_run || eval "$cmds" || func_append admincmds "
           $cmds"
    	fi
          done
        fi
    
        # Exit here if they wanted silent mode.
        $opt_quiet && exit $EXIT_SUCCESS
    
        if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
          echo "----------------------------------------------------------------------"
          echo "Libraries have been installed in:"
          for libdir in $libdirs; do
    	$ECHO "   $libdir"
          done
          echo
          echo "If you ever happen to want to link against installed libraries"
          echo "in a given directory, LIBDIR, you must either use libtool, and"
          echo "specify the full pathname of the library, or use the '-LLIBDIR'"
          echo "flag during linking and do at least one of the following:"
          if test -n "$shlibpath_var"; then
    	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
    	echo "     during execution"
          fi
          if test -n "$runpath_var"; then
    	echo "   - add LIBDIR to the '$runpath_var' environment variable"
    	echo "     during linking"
          fi
          if test -n "$hardcode_libdir_flag_spec"; then
    	libdir=LIBDIR
    	eval flag=\"$hardcode_libdir_flag_spec\"
    
    	$ECHO "   - use the '$flag' linker flag"
          fi
          if test -n "$admincmds"; then
    	$ECHO "   - have your system administrator run these commands:$admincmds"
          fi
          if test -f /etc/ld.so.conf; then
    	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
          fi
          echo
    
          echo "See any operating system documentation about shared libraries for"
          case $host in
    	solaris2.[6789]|solaris2.1[0-9])
    	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
    	  echo "pages."
    	  ;;
    	*)
    	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
    	  ;;
          esac
          echo "----------------------------------------------------------------------"
        fi
        exit $EXIT_SUCCESS
    }
    
    test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
    
    
    # func_mode_install arg...
    func_mode_install ()
    {
        $debug_cmd
    
        # There may be an optional sh(1) argument at the beginning of
        # install_prog (especially on Windows NT).
        if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
           # Allow the use of GNU shtool's install command.
           case $nonopt in *shtool*) :;; *) false;; esac
        then
          # Aesthetically quote it.
          func_quote_arg pretty "$nonopt"
          install_prog="$func_quote_arg_result "
          arg=$1
          shift
        else
          install_prog=
          arg=$nonopt
        fi
    
        # The real first argument should be the name of the installation program.
        # Aesthetically quote it.
        func_quote_arg pretty "$arg"
        func_append install_prog "$func_quote_arg_result"
        install_shared_prog=$install_prog
        case " $install_prog " in
          *[\\\ /]cp\ *) install_cp=: ;;
          *) install_cp=false ;;
        esac
    
        # We need to accept at least all the BSD install flags.
        dest=
        files=
        opts=
        prev=
        install_type=
        isdir=false
        stripme=
        no_mode=:
        for arg
        do
          arg2=
          if test -n "$dest"; then
    	func_append files " $dest"
    	dest=$arg
    	continue
          fi
    
          case $arg in
          -d) isdir=: ;;
          -f)
    	if $install_cp; then :; else
    	  prev=$arg
    	fi
    	;;
          -g | -m | -o)
    	prev=$arg
    	;;
          -s)
    	stripme=" -s"
    	continue
    	;;
          -*)
    	;;
          *)
    	# If the previous option needed an argument, then skip it.
    	if test -n "$prev"; then
    	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
    	    arg2=$install_override_mode
    	    no_mode=false
    	  fi
    	  prev=
    	else
    	  dest=$arg
    	  continue
    	fi
    	;;
          esac
    
          # Aesthetically quote the argument.
          func_quote_arg pretty "$arg"
          func_append install_prog " $func_quote_arg_result"
          if test -n "$arg2"; then
    	func_quote_arg pretty "$arg2"
          fi
          func_append install_shared_prog " $func_quote_arg_result"
        done
    
        test -z "$install_prog" && \
          func_fatal_help "you must specify an install program"
    
        test -n "$prev" && \
          func_fatal_help "the '$prev' option requires an argument"
    
        if test -n "$install_override_mode" && $no_mode; then
          if $install_cp; then :; else
    	func_quote_arg pretty "$install_override_mode"
    	func_append install_shared_prog " -m $func_quote_arg_result"
          fi
        fi
    
        if test -z "$files"; then
          if test -z "$dest"; then
    	func_fatal_help "no file or destination specified"
          else
    	func_fatal_help "you must specify a destination"
          fi
        fi
    
        # Strip any trailing slash from the destination.
        func_stripname '' '/' "$dest"
        dest=$func_stripname_result
    
        # Check to see that the destination is a directory.
        test -d "$dest" && isdir=:
        if $isdir; then
          destdir=$dest
          destname=
        else
          func_dirname_and_basename "$dest" "" "."
          destdir=$func_dirname_result
          destname=$func_basename_result
    
          # Not a directory, so check to see that there is only one file specified.
          set dummy $files; shift
          test "$#" -gt 1 && \
    	func_fatal_help "'$dest' is not a directory"
        fi
        case $destdir in
        [\\/]* | [A-Za-z]:[\\/]*) ;;
        *)
          for file in $files; do
    	case $file in
    	*.lo) ;;
    	*)
    	  func_fatal_help "'$destdir' must be an absolute directory name"
    	  ;;
    	esac
          done
          ;;
        esac
    
        # This variable tells wrapper scripts just to set variables rather
        # than running their programs.
        libtool_install_magic=$magic
    
        staticlibs=
        future_libdirs=
        current_libdirs=
        for file in $files; do
    
          # Do each installation.
          case $file in
          *.$libext)
    	# Do the static libraries later.
    	func_append staticlibs " $file"
    	;;
    
          *.la)
    	func_resolve_sysroot "$file"
    	file=$func_resolve_sysroot_result
    
    	# Check to see that this really is a libtool archive.
    	func_lalib_unsafe_p "$file" \
    	  || func_fatal_help "'$file' is not a valid libtool archive"
    
    	library_names=
    	old_library=
    	relink_command=
    	func_source "$file"
    
    	# Add the libdir to current_libdirs if it is the destination.
    	if test "X$destdir" = "X$libdir"; then
    	  case "$current_libdirs " in
    	  *" $libdir "*) ;;
    	  *) func_append current_libdirs " $libdir" ;;
    	  esac
    	else
    	  # Note the libdir as a future libdir.
    	  case "$future_libdirs " in
    	  *" $libdir "*) ;;
    	  *) func_append future_libdirs " $libdir" ;;
    	  esac
    	fi
    
    	func_dirname "$file" "/" ""
    	dir=$func_dirname_result
    	func_append dir "$objdir"
    
    	if test -n "$relink_command"; then
    	  # Determine the prefix the user has applied to our future dir.
    	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
    
    	  # Don't allow the user to place us outside of our expected
    	  # location b/c this prevents finding dependent libraries that
    	  # are installed to the same prefix.
    	  # At present, this check doesn't affect windows .dll's that
    	  # are installed into $libdir/../bin (currently, that works fine)
    	  # but it's something to keep an eye on.
    	  test "$inst_prefix_dir" = "$destdir" && \
    	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
    
    	  if test -n "$inst_prefix_dir"; then
    	    # Stick the inst_prefix_dir data into the link command.
    	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
    	  else
    	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
    	  fi
    
    	  func_warning "relinking '$file'"
    	  func_show_eval "$relink_command" \
    	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
    	fi
    
    	# See the names of the shared library.
    	set dummy $library_names; shift
    	if test -n "$1"; then
    	  realname=$1
    	  shift
    
    	  srcname=$realname
    	  test -n "$relink_command" && srcname=${realname}T
    
    	  # Install the shared library and build the symlinks.
    	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
    	      'exit $?'
    	  tstripme=$stripme
    	  case $host_os in
    	  cygwin* | mingw* | pw32* | cegcc*)
    	    case $realname in
    	    *.dll.a)
    	      tstripme=
    	      ;;
    	    esac
    	    ;;
    	  os2*)
    	    case $realname in
    	    *_dll.a)
    	      tstripme=
    	      ;;
    	    esac
    	    ;;
    	  esac
    	  if test -n "$tstripme" && test -n "$striplib"; then
    	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
    	  fi
    
    	  if test "$#" -gt 0; then
    	    # Delete the old symlinks, and create new ones.
    	    # Try 'ln -sf' first, because the 'ln' binary might depend on
    	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
    	    # so we also need to try rm && ln -s.
    	    for linkname
    	    do
    	      test "$linkname" != "$realname" \
    		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
    	    done
    	  fi
    
    	  # Do each command in the postinstall commands.
    	  lib=$destdir/$realname
    	  func_execute_cmds "$postinstall_cmds" 'exit $?'
    	fi
    
    	# Install the pseudo-library for information purposes.
    	func_basename "$file"
    	name=$func_basename_result
    	instname=$dir/${name}i
    	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
    
    	# Maybe install the static library, too.
    	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
    	;;
    
          *.lo)
    	# Install (i.e. copy) a libtool object.
    
    	# Figure out destination file name, if it wasn't already specified.
    	if test -n "$destname"; then
    	  destfile=$destdir/$destname
    	else
    	  func_basename "$file"
    	  destfile=$func_basename_result
    	  destfile=$destdir/$destfile
    	fi
    
    	# Deduce the name of the destination old-style object file.
    	case $destfile in
    	*.lo)
    	  func_lo2o "$destfile"
    	  staticdest=$func_lo2o_result
    	  ;;
    	*.$objext)
    	  staticdest=$destfile
    	  destfile=
    	  ;;
    	*)
    	  func_fatal_help "cannot copy a libtool object to '$destfile'"
    	  ;;
    	esac
    
    	# Install the libtool object if requested.
    	test -n "$destfile" && \
    	  func_show_eval "$install_prog $file $destfile" 'exit $?'
    
    	# Install the old object if enabled.
    	if test yes = "$build_old_libs"; then
    	  # Deduce the name of the old-style object file.
    	  func_lo2o "$file"
    	  staticobj=$func_lo2o_result
    	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
    	fi
    	exit $EXIT_SUCCESS
    	;;
    
          *)
    	# Figure out destination file name, if it wasn't already specified.
    	if test -n "$destname"; then
    	  destfile=$destdir/$destname
    	else
    	  func_basename "$file"
    	  destfile=$func_basename_result
    	  destfile=$destdir/$destfile
    	fi
    
    	# If the file is missing, and there is a .exe on the end, strip it
    	# because it is most likely a libtool script we actually want to
    	# install
    	stripped_ext=
    	case $file in
    	  *.exe)
    	    if test ! -f "$file"; then
    	      func_stripname '' '.exe' "$file"
    	      file=$func_stripname_result
    	      stripped_ext=.exe
    	    fi
    	    ;;
    	esac
    
    	# Do a test to see if this is really a libtool program.
    	case $host in
    	*cygwin* | *mingw*)
    	    if func_ltwrapper_executable_p "$file"; then
    	      func_ltwrapper_scriptname "$file"
    	      wrapper=$func_ltwrapper_scriptname_result
    	    else
    	      func_stripname '' '.exe' "$file"
    	      wrapper=$func_stripname_result
    	    fi
    	    ;;
    	*)
    	    wrapper=$file
    	    ;;
    	esac
    	if func_ltwrapper_script_p "$wrapper"; then
    	  notinst_deplibs=
    	  relink_command=
    
    	  func_source "$wrapper"
    
    	  # Check the variables that should have been set.
    	  test -z "$generated_by_libtool_version" && \
    	    func_fatal_error "invalid libtool wrapper script '$wrapper'"
    
    	  finalize=:
    	  for lib in $notinst_deplibs; do
    	    # Check to see that each library is installed.
    	    libdir=
    	    if test -f "$lib"; then
    	      func_source "$lib"
    	    fi
    	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
    	    if test -n "$libdir" && test ! -f "$libfile"; then
    	      func_warning "'$lib' has not been installed in '$libdir'"
    	      finalize=false
    	    fi
    	  done
    
    	  relink_command=
    	  func_source "$wrapper"
    
    	  outputname=
    	  if test no = "$fast_install" && test -n "$relink_command"; then
    	    $opt_dry_run || {
    	      if $finalize; then
    	        tmpdir=`func_mktempdir`
    		func_basename "$file$stripped_ext"
    		file=$func_basename_result
    	        outputname=$tmpdir/$file
    	        # Replace the output file specification.
    	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
    
    	        $opt_quiet || {
    	          func_quote_arg expand,pretty "$relink_command"
    		  eval "func_echo $func_quote_arg_result"
    	        }
    	        if eval "$relink_command"; then :
    	          else
    		  func_error "error: relink '$file' with the above command before installing it"
    		  $opt_dry_run || ${RM}r "$tmpdir"
    		  continue
    	        fi
    	        file=$outputname
    	      else
    	        func_warning "cannot relink '$file'"
    	      fi
    	    }
    	  else
    	    # Install the binary that we compiled earlier.
    	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
    	  fi
    	fi
    
    	# remove .exe since cygwin /usr/bin/install will append another
    	# one anyway
    	case $install_prog,$host in
    	*/usr/bin/install*,*cygwin*)
    	  case $file:$destfile in
    	  *.exe:*.exe)
    	    # this is ok
    	    ;;
    	  *.exe:*)
    	    destfile=$destfile.exe
    	    ;;
    	  *:*.exe)
    	    func_stripname '' '.exe' "$destfile"
    	    destfile=$func_stripname_result
    	    ;;
    	  esac
    	  ;;
    	esac
    	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
    	$opt_dry_run || if test -n "$outputname"; then
    	  ${RM}r "$tmpdir"
    	fi
    	;;
          esac
        done
    
        for file in $staticlibs; do
          func_basename "$file"
          name=$func_basename_result
    
          # Set up the ranlib parameters.
          oldlib=$destdir/$name
          func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
          tool_oldlib=$func_to_tool_file_result
    
          func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
    
          if test -n "$stripme" && test -n "$old_striplib"; then
    	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
          fi
    
          # Do each command in the postinstall commands.
          func_execute_cmds "$old_postinstall_cmds" 'exit $?'
        done
    
        test -n "$future_libdirs" && \
          func_warning "remember to run '$progname --finish$future_libdirs'"
    
        if test -n "$current_libdirs"; then
          # Maybe just do a dry run.
          $opt_dry_run && current_libdirs=" -n$current_libdirs"
          exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
        else
          exit $EXIT_SUCCESS
        fi
    }
    
    test install = "$opt_mode" && func_mode_install ${1+"$@"}
    
    
    # func_generate_dlsyms outputname originator pic_p
    # Extract symbols from dlprefiles and create ${outputname}S.o with
    # a dlpreopen symbol table.
    func_generate_dlsyms ()
    {
        $debug_cmd
    
        my_outputname=$1
        my_originator=$2
        my_pic_p=${3-false}
        my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
        my_dlsyms=
    
        if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
          if test -n "$NM" && test -n "$global_symbol_pipe"; then
    	my_dlsyms=${my_outputname}S.c
          else
    	func_error "not configured to extract global symbols from dlpreopened files"
          fi
        fi
    
        if test -n "$my_dlsyms"; then
          case $my_dlsyms in
          "") ;;
          *.c)
    	# Discover the nlist of each of the dlfiles.
    	nlist=$output_objdir/$my_outputname.nm
    
    	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
    
    	# Parse the name list into a source file.
    	func_verbose "creating $output_objdir/$my_dlsyms"
    
    	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
    /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
    /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
    
    #ifdef __cplusplus
    extern \"C\" {
    #endif
    
    #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
    #pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
    #endif
    
    /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
    #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
    /* DATA imports from DLLs on WIN32 can't be const, because runtime
       relocations are performed -- see ld's documentation on pseudo-relocs.  */
    # define LT_DLSYM_CONST
    #elif defined __osf__
    /* This system does not cope well with relocations in const data.  */
    # define LT_DLSYM_CONST
    #else
    # define LT_DLSYM_CONST const
    #endif
    
    #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
    
    /* External symbol declarations for the compiler. */\
    "
    
    	if test yes = "$dlself"; then
    	  func_verbose "generating symbol list for '$output'"
    
    	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
    
    	  # Add our own program objects to the symbol list.
    	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
    	  for progfile in $progfiles; do
    	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
    	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
    	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
    	  done
    
    	  if test -n "$exclude_expsyms"; then
    	    $opt_dry_run || {
    	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
    	      eval '$MV "$nlist"T "$nlist"'
    	    }
    	  fi
    
    	  if test -n "$export_symbols_regex"; then
    	    $opt_dry_run || {
    	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
    	      eval '$MV "$nlist"T "$nlist"'
    	    }
    	  fi
    
    	  # Prepare the list of exported symbols
    	  if test -z "$export_symbols"; then
    	    export_symbols=$output_objdir/$outputname.exp
    	    $opt_dry_run || {
    	      $RM $export_symbols
    	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
    	      case $host in
    	      *cygwin* | *mingw* | *cegcc* )
                    eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
                    eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
    	        ;;
    	      esac
    	    }
    	  else
    	    $opt_dry_run || {
    	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
    	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
    	      eval '$MV "$nlist"T "$nlist"'
    	      case $host in
    	        *cygwin* | *mingw* | *cegcc* )
    	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
    	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
    	          ;;
    	      esac
    	    }
    	  fi
    	fi
    
    	for dlprefile in $dlprefiles; do
    	  func_verbose "extracting global C symbols from '$dlprefile'"
    	  func_basename "$dlprefile"
    	  name=$func_basename_result
              case $host in
    	    *cygwin* | *mingw* | *cegcc* )
    	      # if an import library, we need to obtain dlname
    	      if func_win32_import_lib_p "$dlprefile"; then
    	        func_tr_sh "$dlprefile"
    	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
    	        dlprefile_dlbasename=
    	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
    	          # Use subshell, to avoid clobbering current variable values
    	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
    	          if test -n "$dlprefile_dlname"; then
    	            func_basename "$dlprefile_dlname"
    	            dlprefile_dlbasename=$func_basename_result
    	          else
    	            # no lafile. user explicitly requested -dlpreopen <import library>.
    	            $sharedlib_from_linklib_cmd "$dlprefile"
    	            dlprefile_dlbasename=$sharedlib_from_linklib_result
    	          fi
    	        fi
    	        $opt_dry_run || {
    	          if test -n "$dlprefile_dlbasename"; then
    	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
    	          else
    	            func_warning "Could not compute DLL name from $name"
    	            eval '$ECHO ": $name " >> "$nlist"'
    	          fi
    	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
    	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
    	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
    	        }
    	      else # not an import lib
    	        $opt_dry_run || {
    	          eval '$ECHO ": $name " >> "$nlist"'
    	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
    	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
    	        }
    	      fi
    	    ;;
    	    *)
    	      $opt_dry_run || {
    	        eval '$ECHO ": $name " >> "$nlist"'
    	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
    	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
    	      }
    	    ;;
              esac
    	done
    
    	$opt_dry_run || {
    	  # Make sure we have at least an empty file.
    	  test -f "$nlist" || : > "$nlist"
    
    	  if test -n "$exclude_expsyms"; then
    	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
    	    $MV "$nlist"T "$nlist"
    	  fi
    
    	  # Try sorting and uniquifying the output.
    	  if $GREP -v "^: " < "$nlist" |
    	      if sort -k 3 </dev/null >/dev/null 2>&1; then
    		sort -k 3
    	      else
    		sort +2
    	      fi |
    	      uniq > "$nlist"S; then
    	    :
    	  else
    	    $GREP -v "^: " < "$nlist" > "$nlist"S
    	  fi
    
    	  if test -f "$nlist"S; then
    	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
    	  else
    	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
    	  fi
    
    	  func_show_eval '$RM "${nlist}I"'
    	  if test -n "$global_symbol_to_import"; then
    	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
    	  fi
    
    	  echo >> "$output_objdir/$my_dlsyms" "\
    
    /* The mapping between symbol names and symbols.  */
    typedef struct {
      const char *name;
      void *address;
    } lt_dlsymlist;
    extern LT_DLSYM_CONST lt_dlsymlist
    lt_${my_prefix}_LTX_preloaded_symbols[];\
    "
    
    	  if test -s "$nlist"I; then
    	    echo >> "$output_objdir/$my_dlsyms" "\
    static void lt_syminit(void)
    {
      LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
      for (; symbol->name; ++symbol)
        {"
    	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
    	    echo >> "$output_objdir/$my_dlsyms" "\
        }
    }"
    	  fi
    	  echo >> "$output_objdir/$my_dlsyms" "\
    LT_DLSYM_CONST lt_dlsymlist
    lt_${my_prefix}_LTX_preloaded_symbols[] =
    { {\"$my_originator\", (void *) 0},"
    
    	  if test -s "$nlist"I; then
    	    echo >> "$output_objdir/$my_dlsyms" "\
      {\"@INIT@\", (void *) &lt_syminit},"
    	  fi
    
    	  case $need_lib_prefix in
    	  no)
    	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
    	    ;;
    	  *)
    	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
    	    ;;
    	  esac
    	  echo >> "$output_objdir/$my_dlsyms" "\
      {0, (void *) 0}
    };
    
    /* This works around a problem in FreeBSD linker */
    #ifdef FREEBSD_WORKAROUND
    static const void *lt_preloaded_setup() {
      return lt_${my_prefix}_LTX_preloaded_symbols;
    }
    #endif
    
    #ifdef __cplusplus
    }
    #endif\
    "
    	} # !$opt_dry_run
    
    	pic_flag_for_symtable=
    	case "$compile_command " in
    	*" -static "*) ;;
    	*)
    	  case $host in
    	  # compiling the symbol table file with pic_flag works around
    	  # a FreeBSD bug that causes programs to crash when -lm is
    	  # linked before any other PIC object.  But we must not use
    	  # pic_flag when linking with -static.  The problem exists in
    	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
    	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
    	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
    	  *-*-hpux*)
    	    pic_flag_for_symtable=" $pic_flag"  ;;
    	  *)
    	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
    	    ;;
    	  esac
    	  ;;
    	esac
    	symtab_cflags=
    	for arg in $LTCFLAGS; do
    	  case $arg in
    	  -pie | -fpie | -fPIE) ;;
    	  *) func_append symtab_cflags " $arg" ;;
    	  esac
    	done
    
    	# Now compile the dynamic symbol file.
    	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
    
    	# Clean up the generated files.
    	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
    
    	# Transform the symbol file into the correct name.
    	symfileobj=$output_objdir/${my_outputname}S.$objext
    	case $host in
    	*cygwin* | *mingw* | *cegcc* )
    	  if test -f "$output_objdir/$my_outputname.def"; then
    	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
    	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
    	  else
    	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
    	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
    	  fi
    	  ;;
    	*)
    	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
    	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
    	  ;;
    	esac
    	;;
          *)
    	func_fatal_error "unknown suffix for '$my_dlsyms'"
    	;;
          esac
        else
          # We keep going just in case the user didn't refer to
          # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
          # really was required.
    
          # Nullify the symbol file.
          compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
          finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
        fi
    }
    
    # func_cygming_gnu_implib_p ARG
    # This predicate returns with zero status (TRUE) if
    # ARG is a GNU/binutils-style import library. Returns
    # with nonzero status (FALSE) otherwise.
    func_cygming_gnu_implib_p ()
    {
      $debug_cmd
    
      func_to_tool_file "$1" func_convert_file_msys_to_w32
      func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
      test -n "$func_cygming_gnu_implib_tmp"
    }
    
    # func_cygming_ms_implib_p ARG
    # This predicate returns with zero status (TRUE) if
    # ARG is an MS-style import library. Returns
    # with nonzero status (FALSE) otherwise.
    func_cygming_ms_implib_p ()
    {
      $debug_cmd
    
      func_to_tool_file "$1" func_convert_file_msys_to_w32
      func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
      test -n "$func_cygming_ms_implib_tmp"
    }
    
    # func_win32_libid arg
    # return the library type of file 'arg'
    #
    # Need a lot of goo to handle *both* DLLs and import libs
    # Has to be a shell function in order to 'eat' the argument
    # that is supplied when $file_magic_command is called.
    # Despite the name, also deal with 64 bit binaries.
    func_win32_libid ()
    {
      $debug_cmd
    
      win32_libid_type=unknown
      win32_fileres=`file -L $1 2>/dev/null`
      case $win32_fileres in
      *ar\ archive\ import\ library*) # definitely import
        win32_libid_type="x86 archive import"
        ;;
      *ar\ archive*) # could be an import, or static
        # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
        if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
           $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
          case $nm_interface in
          "MS dumpbin")
    	if func_cygming_ms_implib_p "$1" ||
    	   func_cygming_gnu_implib_p "$1"
    	then
    	  win32_nmres=import
    	else
    	  win32_nmres=
    	fi
    	;;
          *)
    	func_to_tool_file "$1" func_convert_file_msys_to_w32
    	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
    	  $SED -n -e '
    	    1,100{
    		/ I /{
    		    s|.*|import|
    		    p
    		    q
    		}
    	    }'`
    	;;
          esac
          case $win32_nmres in
          import*)  win32_libid_type="x86 archive import";;
          *)        win32_libid_type="x86 archive static";;
          esac
        fi
        ;;
      *DLL*)
        win32_libid_type="x86 DLL"
        ;;
      *executable*) # but shell scripts are "executable" too...
        case $win32_fileres in
        *MS\ Windows\ PE\ Intel*)
          win32_libid_type="x86 DLL"
          ;;
        esac
        ;;
      esac
      $ECHO "$win32_libid_type"
    }
    
    # func_cygming_dll_for_implib ARG
    #
    # Platform-specific function to extract the
    # name of the DLL associated with the specified
    # import library ARG.
    # Invoked by eval'ing the libtool variable
    #    $sharedlib_from_linklib_cmd
    # Result is available in the variable
    #    $sharedlib_from_linklib_result
    func_cygming_dll_for_implib ()
    {
      $debug_cmd
    
      sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
    }
    
    # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
    #
    # The is the core of a fallback implementation of a
    # platform-specific function to extract the name of the
    # DLL associated with the specified import library LIBNAME.
    #
    # SECTION_NAME is either .idata$6 or .idata$7, depending
    # on the platform and compiler that created the implib.
    #
    # Echos the name of the DLL associated with the
    # specified import library.
    func_cygming_dll_for_implib_fallback_core ()
    {
      $debug_cmd
    
      match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
      $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
        $SED '/^Contents of section '"$match_literal"':/{
          # Place marker at beginning of archive member dllname section
          s/.*/====MARK====/
          p
          d
        }
        # These lines can sometimes be longer than 43 characters, but
        # are always uninteresting
        /:[	 ]*file format pe[i]\{,1\}-/d
        /^In archive [^:]*:/d
        # Ensure marker is printed
        /^====MARK====/p
        # Remove all lines with less than 43 characters
        /^.\{43\}/!d
        # From remaining lines, remove first 43 characters
        s/^.\{43\}//' |
        $SED -n '
          # Join marker and all lines until next marker into a single line
          /^====MARK====/ b para
          H
          $ b para
          b
          :para
          x
          s/\n//g
          # Remove the marker
          s/^====MARK====//
          # Remove trailing dots and whitespace
          s/[\. \t]*$//
          # Print
          /./p' |
        # we now have a list, one entry per line, of the stringified
        # contents of the appropriate section of all members of the
        # archive that possess that section. Heuristic: eliminate
        # all those that have a first or second character that is
        # a '.' (that is, objdump's representation of an unprintable
        # character.) This should work for all archives with less than
        # 0x302f exports -- but will fail for DLLs whose name actually
        # begins with a literal '.' or a single character followed by
        # a '.'.
        #
        # Of those that remain, print the first one.
        $SED -e '/^\./d;/^.\./d;q'
    }
    
    # func_cygming_dll_for_implib_fallback ARG
    # Platform-specific function to extract the
    # name of the DLL associated with the specified
    # import library ARG.
    #
    # This fallback implementation is for use when $DLLTOOL
    # does not support the --identify-strict option.
    # Invoked by eval'ing the libtool variable
    #    $sharedlib_from_linklib_cmd
    # Result is available in the variable
    #    $sharedlib_from_linklib_result
    func_cygming_dll_for_implib_fallback ()
    {
      $debug_cmd
    
      if func_cygming_gnu_implib_p "$1"; then
        # binutils import library
        sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
      elif func_cygming_ms_implib_p "$1"; then
        # ms-generated import library
        sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
      else
        # unknown
        sharedlib_from_linklib_result=
      fi
    }
    
    
    # func_extract_an_archive dir oldlib
    func_extract_an_archive ()
    {
        $debug_cmd
    
        f_ex_an_ar_dir=$1; shift
        f_ex_an_ar_oldlib=$1
        if test yes = "$lock_old_archive_extraction"; then
          lockfile=$f_ex_an_ar_oldlib.lock
          until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
    	func_echo "Waiting for $lockfile to be removed"
    	sleep 2
          done
        fi
        func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
    		   'stat=$?; rm -f "$lockfile"; exit $stat'
        if test yes = "$lock_old_archive_extraction"; then
          $opt_dry_run || rm -f "$lockfile"
        fi
        if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
         :
        else
          func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
        fi
    }
    
    
    # func_extract_archives gentop oldlib ...
    func_extract_archives ()
    {
        $debug_cmd
    
        my_gentop=$1; shift
        my_oldlibs=${1+"$@"}
        my_oldobjs=
        my_xlib=
        my_xabs=
        my_xdir=
    
        for my_xlib in $my_oldlibs; do
          # Extract the objects.
          case $my_xlib in
    	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
    	*) my_xabs=`pwd`"/$my_xlib" ;;
          esac
          func_basename "$my_xlib"
          my_xlib=$func_basename_result
          my_xlib_u=$my_xlib
          while :; do
            case " $extracted_archives " in
    	*" $my_xlib_u "*)
    	  func_arith $extracted_serial + 1
    	  extracted_serial=$func_arith_result
    	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
    	*) break ;;
    	esac
          done
          extracted_archives="$extracted_archives $my_xlib_u"
          my_xdir=$my_gentop/$my_xlib_u
    
          func_mkdir_p "$my_xdir"
    
          case $host in
          *-darwin*)
    	func_verbose "Extracting $my_xabs"
    	# Do not bother doing anything if just a dry run
    	$opt_dry_run || {
    	  darwin_orig_dir=`pwd`
    	  cd $my_xdir || exit $?
    	  darwin_archive=$my_xabs
    	  darwin_curdir=`pwd`
    	  func_basename "$darwin_archive"
    	  darwin_base_archive=$func_basename_result
    	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
    	  if test -n "$darwin_arches"; then
    	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
    	    darwin_arch=
    	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
    	    for darwin_arch in  $darwin_arches; do
    	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
    	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
    	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
    	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
    	      cd "$darwin_curdir"
    	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
    	    done # $darwin_arches
                ## Okay now we've a bunch of thin objects, gotta fatten them up :)
    	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
    	    darwin_file=
    	    darwin_files=
    	    for darwin_file in $darwin_filelist; do
    	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
    	      $LIPO -create -output "$darwin_file" $darwin_files
    	    done # $darwin_filelist
    	    $RM -rf unfat-$$
    	    cd "$darwin_orig_dir"
    	  else
    	    cd $darwin_orig_dir
    	    func_extract_an_archive "$my_xdir" "$my_xabs"
    	  fi # $darwin_arches
    	} # !$opt_dry_run
    	;;
          *)
            func_extract_an_archive "$my_xdir" "$my_xabs"
    	;;
          esac
          my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
        done
    
        func_extract_archives_result=$my_oldobjs
    }
    
    
    # func_emit_wrapper [arg=no]
    #
    # Emit a libtool wrapper script on stdout.
    # Don't directly open a file because we may want to
    # incorporate the script contents within a cygwin/mingw
    # wrapper executable.  Must ONLY be called from within
    # func_mode_link because it depends on a number of variables
    # set therein.
    #
    # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
    # variable will take.  If 'yes', then the emitted script
    # will assume that the directory where it is stored is
    # the $objdir directory.  This is a cygwin/mingw-specific
    # behavior.
    func_emit_wrapper ()
    {
    	func_emit_wrapper_arg1=${1-no}
    
    	$ECHO "\
    #! $SHELL
    
    # $output - temporary wrapper script for $objdir/$outputname
    # Generated by $PROGRAM (GNU $PACKAGE) $VERSION
    #
    # The $output program cannot be directly executed until all the libtool
    # libraries that it depends on are installed.
    #
    # This wrapper script should never be moved out of the build directory.
    # If it is, it will not operate correctly.
    
    # Sed substitution that helps us do robust quoting.  It backslashifies
    # metacharacters that are still active within double-quoted strings.
    sed_quote_subst='$sed_quote_subst'
    
    # Be Bourne compatible
    if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
      emulate sh
      NULLCMD=:
      # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
      # is contrary to our usage.  Disable this feature.
      alias -g '\${1+\"\$@\"}'='\"\$@\"'
      setopt NO_GLOB_SUBST
    else
      case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
    fi
    BIN_SH=xpg4; export BIN_SH # for Tru64
    DUALCASE=1; export DUALCASE # for MKS sh
    
    # The HP-UX ksh and POSIX shell print the target directory to stdout
    # if CDPATH is set.
    (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
    
    relink_command=\"$relink_command\"
    
    # This environment variable determines our operation mode.
    if test \"\$libtool_install_magic\" = \"$magic\"; then
      # install mode needs the following variables:
      generated_by_libtool_version='$macro_version'
      notinst_deplibs='$notinst_deplibs'
    else
      # When we are sourced in execute mode, \$file and \$ECHO are already set.
      if test \"\$libtool_execute_magic\" != \"$magic\"; then
        file=\"\$0\""
    
        func_quote_arg pretty "$ECHO"
        qECHO=$func_quote_arg_result
        $ECHO "\
    
    # A function that is used when there is no print builtin or printf.
    func_fallback_echo ()
    {
      eval 'cat <<_LTECHO_EOF
    \$1
    _LTECHO_EOF'
    }
        ECHO=$qECHO
      fi
    
    # Very basic option parsing. These options are (a) specific to
    # the libtool wrapper, (b) are identical between the wrapper
    # /script/ and the wrapper /executable/ that is used only on
    # windows platforms, and (c) all begin with the string "--lt-"
    # (application programs are unlikely to have options that match
    # this pattern).
    #
    # There are only two supported options: --lt-debug and
    # --lt-dump-script. There is, deliberately, no --lt-help.
    #
    # The first argument to this parsing function should be the
    # script's $0 value, followed by "$@".
    lt_option_debug=
    func_parse_lt_options ()
    {
      lt_script_arg0=\$0
      shift
      for lt_opt
      do
        case \"\$lt_opt\" in
        --lt-debug) lt_option_debug=1 ;;
        --lt-dump-script)
            lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
            test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
            lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
            cat \"\$lt_dump_D/\$lt_dump_F\"
            exit 0
          ;;
        --lt-*)
            \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
            exit 1
          ;;
        esac
      done
    
      # Print the debug banner immediately:
      if test -n \"\$lt_option_debug\"; then
        echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
      fi
    }
    
    # Used when --lt-debug. Prints its arguments to stdout
    # (redirection is the responsibility of the caller)
    func_lt_dump_args ()
    {
      lt_dump_args_N=1;
      for lt_arg
      do
        \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
        lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
      done
    }
    
    # Core function for launching the target application
    func_exec_program_core ()
    {
    "
      case $host in
      # Backslashes separate directories on plain windows
      *-*-mingw | *-*-os2* | *-cegcc*)
        $ECHO "\
          if test -n \"\$lt_option_debug\"; then
            \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
            func_lt_dump_args \${1+\"\$@\"} 1>&2
          fi
          exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
    "
        ;;
    
      *)
        $ECHO "\
          if test -n \"\$lt_option_debug\"; then
            \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
            func_lt_dump_args \${1+\"\$@\"} 1>&2
          fi
          exec \"\$progdir/\$program\" \${1+\"\$@\"}
    "
        ;;
      esac
      $ECHO "\
          \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
          exit 1
    }
    
    # A function to encapsulate launching the target application
    # Strips options in the --lt-* namespace from \$@ and
    # launches target application with the remaining arguments.
    func_exec_program ()
    {
      case \" \$* \" in
      *\\ --lt-*)
        for lt_wr_arg
        do
          case \$lt_wr_arg in
          --lt-*) ;;
          *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
          esac
          shift
        done ;;
      esac
      func_exec_program_core \${1+\"\$@\"}
    }
    
      # Parse options
      func_parse_lt_options \"\$0\" \${1+\"\$@\"}
    
      # Find the directory that this script lives in.
      thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
      test \"x\$thisdir\" = \"x\$file\" && thisdir=.
    
      # Follow symbolic links until we get to the real thisdir.
      file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
      while test -n \"\$file\"; do
        destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
    
        # If there was a directory component, then change thisdir.
        if test \"x\$destdir\" != \"x\$file\"; then
          case \"\$destdir\" in
          [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
          *) thisdir=\"\$thisdir/\$destdir\" ;;
          esac
        fi
    
        file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
        file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
      done
    
      # Usually 'no', except on cygwin/mingw when embedded into
      # the cwrapper.
      WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
      if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
        # special case for '.'
        if test \"\$thisdir\" = \".\"; then
          thisdir=\`pwd\`
        fi
        # remove .libs from thisdir
        case \"\$thisdir\" in
        *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
        $objdir )   thisdir=. ;;
        esac
      fi
    
      # Try to get the absolute directory name.
      absdir=\`cd \"\$thisdir\" && pwd\`
      test -n \"\$absdir\" && thisdir=\"\$absdir\"
    "
    
    	if test yes = "$fast_install"; then
    	  $ECHO "\
      program=lt-'$outputname'$exeext
      progdir=\"\$thisdir/$objdir\"
    
      if test ! -f \"\$progdir/\$program\" ||
         { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
           test \"X\$file\" != \"X\$progdir/\$program\"; }; then
    
        file=\"\$\$-\$program\"
    
        if test ! -d \"\$progdir\"; then
          $MKDIR \"\$progdir\"
        else
          $RM \"\$progdir/\$file\"
        fi"
    
    	  $ECHO "\
    
        # relink executable if necessary
        if test -n \"\$relink_command\"; then
          if relink_command_output=\`eval \$relink_command 2>&1\`; then :
          else
    	\$ECHO \"\$relink_command_output\" >&2
    	$RM \"\$progdir/\$file\"
    	exit 1
          fi
        fi
    
        $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
        { $RM \"\$progdir/\$program\";
          $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
        $RM \"\$progdir/\$file\"
      fi"
    	else
    	  $ECHO "\
      program='$outputname'
      progdir=\"\$thisdir/$objdir\"
    "
    	fi
    
    	$ECHO "\
    
      if test -f \"\$progdir/\$program\"; then"
    
    	# fixup the dll searchpath if we need to.
    	#
    	# Fix the DLL searchpath if we need to.  Do this before prepending
    	# to shlibpath, because on Windows, both are PATH and uninstalled
    	# libraries must come first.
    	if test -n "$dllsearchpath"; then
    	  $ECHO "\
        # Add the dll search path components to the executable PATH
        PATH=$dllsearchpath:\$PATH
    "
    	fi
    
    	# Export our shlibpath_var if we have one.
    	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
    	  $ECHO "\
        # Add our own library path to $shlibpath_var
        $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
    
        # Some systems cannot cope with colon-terminated $shlibpath_var
        # The second colon is a workaround for a bug in BeOS R4 sed
        $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
    
        export $shlibpath_var
    "
    	fi
    
    	$ECHO "\
        if test \"\$libtool_execute_magic\" != \"$magic\"; then
          # Run the actual program with our arguments.
          func_exec_program \${1+\"\$@\"}
        fi
      else
        # The program doesn't exist.
        \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
        \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
        \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
        exit 1
      fi
    fi\
    "
    }
    
    
    # func_emit_cwrapperexe_src
    # emit the source code for a wrapper executable on stdout
    # Must ONLY be called from within func_mode_link because
    # it depends on a number of variable set therein.
    func_emit_cwrapperexe_src ()
    {
    	cat <<EOF
    
    /* $cwrappersource - temporary wrapper executable for $objdir/$outputname
       Generated by $PROGRAM (GNU $PACKAGE) $VERSION
    
       The $output program cannot be directly executed until all the libtool
       libraries that it depends on are installed.
    
       This wrapper executable should never be moved out of the build directory.
       If it is, it will not operate correctly.
    */
    EOF
    	    cat <<"EOF"
    #ifdef _MSC_VER
    # define _CRT_SECURE_NO_DEPRECATE 1
    #endif
    #include <stdio.h>
    #include <stdlib.h>
    #ifdef _MSC_VER
    # include <direct.h>
    # include <process.h>
    # include <io.h>
    #else
    # include <unistd.h>
    # include <stdint.h>
    # ifdef __CYGWIN__
    #  include <io.h>
    # endif
    #endif
    #include <malloc.h>
    #include <stdarg.h>
    #include <assert.h>
    #include <string.h>
    #include <ctype.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    
    #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
    
    /* declarations of non-ANSI functions */
    #if defined __MINGW32__
    # ifdef __STRICT_ANSI__
    int _putenv (const char *);
    # endif
    #elif defined __CYGWIN__
    # ifdef __STRICT_ANSI__
    char *realpath (const char *, char *);
    int putenv (char *);
    int setenv (const char *, const char *, int);
    # endif
    /* #elif defined other_platform || defined ... */
    #endif
    
    /* portability defines, excluding path handling macros */
    #if defined _MSC_VER
    # define setmode _setmode
    # define stat    _stat
    # define chmod   _chmod
    # define getcwd  _getcwd
    # define putenv  _putenv
    # define S_IXUSR _S_IEXEC
    #elif defined __MINGW32__
    # define setmode _setmode
    # define stat    _stat
    # define chmod   _chmod
    # define getcwd  _getcwd
    # define putenv  _putenv
    #elif defined __CYGWIN__
    # define HAVE_SETENV
    # define FOPEN_WB "wb"
    /* #elif defined other platforms ... */
    #endif
    
    #if defined PATH_MAX
    # define LT_PATHMAX PATH_MAX
    #elif defined MAXPATHLEN
    # define LT_PATHMAX MAXPATHLEN
    #else
    # define LT_PATHMAX 1024
    #endif
    
    #ifndef S_IXOTH
    # define S_IXOTH 0
    #endif
    #ifndef S_IXGRP
    # define S_IXGRP 0
    #endif
    
    /* path handling portability macros */
    #ifndef DIR_SEPARATOR
    # define DIR_SEPARATOR '/'
    # define PATH_SEPARATOR ':'
    #endif
    
    #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
      defined __OS2__
    # define HAVE_DOS_BASED_FILE_SYSTEM
    # define FOPEN_WB "wb"
    # ifndef DIR_SEPARATOR_2
    #  define DIR_SEPARATOR_2 '\\'
    # endif
    # ifndef PATH_SEPARATOR_2
    #  define PATH_SEPARATOR_2 ';'
    # endif
    #endif
    
    #ifndef DIR_SEPARATOR_2
    # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
    #else /* DIR_SEPARATOR_2 */
    # define IS_DIR_SEPARATOR(ch) \
    	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
    #endif /* DIR_SEPARATOR_2 */
    
    #ifndef PATH_SEPARATOR_2
    # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
    #else /* PATH_SEPARATOR_2 */
    # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
    #endif /* PATH_SEPARATOR_2 */
    
    #ifndef FOPEN_WB
    # define FOPEN_WB "w"
    #endif
    #ifndef _O_BINARY
    # define _O_BINARY 0
    #endif
    
    #define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
    #define XFREE(stale) do { \
      if (stale) { free (stale); stale = 0; } \
    } while (0)
    
    #if defined LT_DEBUGWRAPPER
    static int lt_debug = 1;
    #else
    static int lt_debug = 0;
    #endif
    
    const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
    
    void *xmalloc (size_t num);
    char *xstrdup (const char *string);
    const char *base_name (const char *name);
    char *find_executable (const char *wrapper);
    char *chase_symlinks (const char *pathspec);
    int make_executable (const char *path);
    int check_executable (const char *path);
    char *strendzap (char *str, const char *pat);
    void lt_debugprintf (const char *file, int line, const char *fmt, ...);
    void lt_fatal (const char *file, int line, const char *message, ...);
    static const char *nonnull (const char *s);
    static const char *nonempty (const char *s);
    void lt_setenv (const char *name, const char *value);
    char *lt_extend_str (const char *orig_value, const char *add, int to_end);
    void lt_update_exe_path (const char *name, const char *value);
    void lt_update_lib_path (const char *name, const char *value);
    char **prepare_spawn (char **argv);
    void lt_dump_script (FILE *f);
    EOF
    
    	    cat <<EOF
    #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
    # define externally_visible volatile
    #else
    # define externally_visible __attribute__((externally_visible)) volatile
    #endif
    externally_visible const char * MAGIC_EXE = "$magic_exe";
    const char * LIB_PATH_VARNAME = "$shlibpath_var";
    EOF
    
    	    if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
                  func_to_host_path "$temp_rpath"
    	      cat <<EOF
    const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
    EOF
    	    else
    	      cat <<"EOF"
    const char * LIB_PATH_VALUE   = "";
    EOF
    	    fi
    
    	    if test -n "$dllsearchpath"; then
                  func_to_host_path "$dllsearchpath:"
    	      cat <<EOF
    const char * EXE_PATH_VARNAME = "PATH";
    const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
    EOF
    	    else
    	      cat <<"EOF"
    const char * EXE_PATH_VARNAME = "";
    const char * EXE_PATH_VALUE   = "";
    EOF
    	    fi
    
    	    if test yes = "$fast_install"; then
    	      cat <<EOF
    const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
    EOF
    	    else
    	      cat <<EOF
    const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
    EOF
    	    fi
    
    
    	    cat <<"EOF"
    
    #define LTWRAPPER_OPTION_PREFIX         "--lt-"
    
    static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
    static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
    static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
    
    int
    main (int argc, char *argv[])
    {
      char **newargz;
      int  newargc;
      char *tmp_pathspec;
      char *actual_cwrapper_path;
      char *actual_cwrapper_name;
      char *target_name;
      char *lt_argv_zero;
      int rval = 127;
    
      int i;
    
      program_name = (char *) xstrdup (base_name (argv[0]));
      newargz = XMALLOC (char *, (size_t) argc + 1);
    
      /* very simple arg parsing; don't want to rely on getopt
       * also, copy all non cwrapper options to newargz, except
       * argz[0], which is handled differently
       */
      newargc=0;
      for (i = 1; i < argc; i++)
        {
          if (STREQ (argv[i], dumpscript_opt))
    	{
    EOF
    	    case $host in
    	      *mingw* | *cygwin* )
    		# make stdout use "unix" line endings
    		echo "          setmode(1,_O_BINARY);"
    		;;
    	      esac
    
    	    cat <<"EOF"
    	  lt_dump_script (stdout);
    	  return 0;
    	}
          if (STREQ (argv[i], debug_opt))
    	{
              lt_debug = 1;
              continue;
    	}
          if (STREQ (argv[i], ltwrapper_option_prefix))
            {
              /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
                 namespace, but it is not one of the ones we know about and
                 have already dealt with, above (inluding dump-script), then
                 report an error. Otherwise, targets might begin to believe
                 they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
                 namespace. The first time any user complains about this, we'll
                 need to make LTWRAPPER_OPTION_PREFIX a configure-time option
                 or a configure.ac-settable value.
               */
              lt_fatal (__FILE__, __LINE__,
    		    "unrecognized %s option: '%s'",
                        ltwrapper_option_prefix, argv[i]);
            }
          /* otherwise ... */
          newargz[++newargc] = xstrdup (argv[i]);
        }
      newargz[++newargc] = NULL;
    
    EOF
    	    cat <<EOF
      /* The GNU banner must be the first non-error debug message */
      lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
    EOF
    	    cat <<"EOF"
      lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
      lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
    
      tmp_pathspec = find_executable (argv[0]);
      if (tmp_pathspec == NULL)
        lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
      lt_debugprintf (__FILE__, __LINE__,
                      "(main) found exe (before symlink chase) at: %s\n",
    		  tmp_pathspec);
    
      actual_cwrapper_path = chase_symlinks (tmp_pathspec);
      lt_debugprintf (__FILE__, __LINE__,
                      "(main) found exe (after symlink chase) at: %s\n",
    		  actual_cwrapper_path);
      XFREE (tmp_pathspec);
    
      actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
      strendzap (actual_cwrapper_path, actual_cwrapper_name);
    
      /* wrapper name transforms */
      strendzap (actual_cwrapper_name, ".exe");
      tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
      XFREE (actual_cwrapper_name);
      actual_cwrapper_name = tmp_pathspec;
      tmp_pathspec = 0;
    
      /* target_name transforms -- use actual target program name; might have lt- prefix */
      target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
      strendzap (target_name, ".exe");
      tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
      XFREE (target_name);
      target_name = tmp_pathspec;
      tmp_pathspec = 0;
    
      lt_debugprintf (__FILE__, __LINE__,
    		  "(main) libtool target name: %s\n",
    		  target_name);
    EOF
    
    	    cat <<EOF
      newargz[0] =
        XMALLOC (char, (strlen (actual_cwrapper_path) +
    		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
      strcpy (newargz[0], actual_cwrapper_path);
      strcat (newargz[0], "$objdir");
      strcat (newargz[0], "/");
    EOF
    
    	    cat <<"EOF"
      /* stop here, and copy so we don't have to do this twice */
      tmp_pathspec = xstrdup (newargz[0]);
    
      /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
      strcat (newargz[0], actual_cwrapper_name);
    
      /* DO want the lt- prefix here if it exists, so use target_name */
      lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
      XFREE (tmp_pathspec);
      tmp_pathspec = NULL;
    EOF
    
    	    case $host_os in
    	      mingw*)
    	    cat <<"EOF"
      {
        char* p;
        while ((p = strchr (newargz[0], '\\')) != NULL)
          {
    	*p = '/';
          }
        while ((p = strchr (lt_argv_zero, '\\')) != NULL)
          {
    	*p = '/';
          }
      }
    EOF
    	    ;;
    	    esac
    
    	    cat <<"EOF"
      XFREE (target_name);
      XFREE (actual_cwrapper_path);
      XFREE (actual_cwrapper_name);
    
      lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
      lt_setenv ("DUALCASE", "1");  /* for MSK sh */
      /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
         be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
         because on Windows, both *_VARNAMEs are PATH but uninstalled
         libraries must come first. */
      lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
      lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
    
      lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
    		  nonnull (lt_argv_zero));
      for (i = 0; i < newargc; i++)
        {
          lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
    		      i, nonnull (newargz[i]));
        }
    
    EOF
    
    	    case $host_os in
    	      mingw*)
    		cat <<"EOF"
      /* execv doesn't actually work on mingw as expected on unix */
      newargz = prepare_spawn (newargz);
      rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
      if (rval == -1)
        {
          /* failed to start process */
          lt_debugprintf (__FILE__, __LINE__,
    		      "(main) failed to launch target \"%s\": %s\n",
    		      lt_argv_zero, nonnull (strerror (errno)));
          return 127;
        }
      return rval;
    EOF
    		;;
    	      *)
    		cat <<"EOF"
      execv (lt_argv_zero, newargz);
      return rval; /* =127, but avoids unused variable warning */
    EOF
    		;;
    	    esac
    
    	    cat <<"EOF"
    }
    
    void *
    xmalloc (size_t num)
    {
      void *p = (void *) malloc (num);
      if (!p)
        lt_fatal (__FILE__, __LINE__, "memory exhausted");
    
      return p;
    }
    
    char *
    xstrdup (const char *string)
    {
      return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
    			  string) : NULL;
    }
    
    const char *
    base_name (const char *name)
    {
      const char *base;
    
    #if defined HAVE_DOS_BASED_FILE_SYSTEM
      /* Skip over the disk name in MSDOS pathnames. */
      if (isalpha ((unsigned char) name[0]) && name[1] == ':')
        name += 2;
    #endif
    
      for (base = name; *name; name++)
        if (IS_DIR_SEPARATOR (*name))
          base = name + 1;
      return base;
    }
    
    int
    check_executable (const char *path)
    {
      struct stat st;
    
      lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
                      nonempty (path));
      if ((!path) || (!*path))
        return 0;
    
      if ((stat (path, &st) >= 0)
          && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
        return 1;
      else
        return 0;
    }
    
    int
    make_executable (const char *path)
    {
      int rval = 0;
      struct stat st;
    
      lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
                      nonempty (path));
      if ((!path) || (!*path))
        return 0;
    
      if (stat (path, &st) >= 0)
        {
          rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
        }
      return rval;
    }
    
    /* Searches for the full path of the wrapper.  Returns
       newly allocated full path name if found, NULL otherwise
       Does not chase symlinks, even on platforms that support them.
    */
    char *
    find_executable (const char *wrapper)
    {
      int has_slash = 0;
      const char *p;
      const char *p_next;
      /* static buffer for getcwd */
      char tmp[LT_PATHMAX + 1];
      size_t tmp_len;
      char *concat_name;
    
      lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
                      nonempty (wrapper));
    
      if ((wrapper == NULL) || (*wrapper == '\0'))
        return NULL;
    
      /* Absolute path? */
    #if defined HAVE_DOS_BASED_FILE_SYSTEM
      if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
        {
          concat_name = xstrdup (wrapper);
          if (check_executable (concat_name))
    	return concat_name;
          XFREE (concat_name);
        }
      else
        {
    #endif
          if (IS_DIR_SEPARATOR (wrapper[0]))
    	{
    	  concat_name = xstrdup (wrapper);
    	  if (check_executable (concat_name))
    	    return concat_name;
    	  XFREE (concat_name);
    	}
    #if defined HAVE_DOS_BASED_FILE_SYSTEM
        }
    #endif
    
      for (p = wrapper; *p; p++)
        if (*p == '/')
          {
    	has_slash = 1;
    	break;
          }
      if (!has_slash)
        {
          /* no slashes; search PATH */
          const char *path = getenv ("PATH");
          if (path != NULL)
    	{
    	  for (p = path; *p; p = p_next)
    	    {
    	      const char *q;
    	      size_t p_len;
    	      for (q = p; *q; q++)
    		if (IS_PATH_SEPARATOR (*q))
    		  break;
    	      p_len = (size_t) (q - p);
    	      p_next = (*q == '\0' ? q : q + 1);
    	      if (p_len == 0)
    		{
    		  /* empty path: current directory */
    		  if (getcwd (tmp, LT_PATHMAX) == NULL)
    		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
                                  nonnull (strerror (errno)));
    		  tmp_len = strlen (tmp);
    		  concat_name =
    		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
    		  memcpy (concat_name, tmp, tmp_len);
    		  concat_name[tmp_len] = '/';
    		  strcpy (concat_name + tmp_len + 1, wrapper);
    		}
    	      else
    		{
    		  concat_name =
    		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
    		  memcpy (concat_name, p, p_len);
    		  concat_name[p_len] = '/';
    		  strcpy (concat_name + p_len + 1, wrapper);
    		}
    	      if (check_executable (concat_name))
    		return concat_name;
    	      XFREE (concat_name);
    	    }
    	}
          /* not found in PATH; assume curdir */
        }
      /* Relative path | not found in path: prepend cwd */
      if (getcwd (tmp, LT_PATHMAX) == NULL)
        lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
                  nonnull (strerror (errno)));
      tmp_len = strlen (tmp);
      concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
      memcpy (concat_name, tmp, tmp_len);
      concat_name[tmp_len] = '/';
      strcpy (concat_name + tmp_len + 1, wrapper);
    
      if (check_executable (concat_name))
        return concat_name;
      XFREE (concat_name);
      return NULL;
    }
    
    char *
    chase_symlinks (const char *pathspec)
    {
    #ifndef S_ISLNK
      return xstrdup (pathspec);
    #else
      char buf[LT_PATHMAX];
      struct stat s;
      char *tmp_pathspec = xstrdup (pathspec);
      char *p;
      int has_symlinks = 0;
      while (strlen (tmp_pathspec) && !has_symlinks)
        {
          lt_debugprintf (__FILE__, __LINE__,
    		      "checking path component for symlinks: %s\n",
    		      tmp_pathspec);
          if (lstat (tmp_pathspec, &s) == 0)
    	{
    	  if (S_ISLNK (s.st_mode) != 0)
    	    {
    	      has_symlinks = 1;
    	      break;
    	    }
    
    	  /* search backwards for last DIR_SEPARATOR */
    	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
    	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
    	    p--;
    	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
    	    {
    	      /* no more DIR_SEPARATORS left */
    	      break;
    	    }
    	  *p = '\0';
    	}
          else
    	{
    	  lt_fatal (__FILE__, __LINE__,
    		    "error accessing file \"%s\": %s",
    		    tmp_pathspec, nonnull (strerror (errno)));
    	}
        }
      XFREE (tmp_pathspec);
    
      if (!has_symlinks)
        {
          return xstrdup (pathspec);
        }
    
      tmp_pathspec = realpath (pathspec, buf);
      if (tmp_pathspec == 0)
        {
          lt_fatal (__FILE__, __LINE__,
    		"could not follow symlinks for %s", pathspec);
        }
      return xstrdup (tmp_pathspec);
    #endif
    }
    
    char *
    strendzap (char *str, const char *pat)
    {
      size_t len, patlen;
    
      assert (str != NULL);
      assert (pat != NULL);
    
      len = strlen (str);
      patlen = strlen (pat);
    
      if (patlen <= len)
        {
          str += len - patlen;
          if (STREQ (str, pat))
    	*str = '\0';
        }
      return str;
    }
    
    void
    lt_debugprintf (const char *file, int line, const char *fmt, ...)
    {
      va_list args;
      if (lt_debug)
        {
          (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
          va_start (args, fmt);
          (void) vfprintf (stderr, fmt, args);
          va_end (args);
        }
    }
    
    static void
    lt_error_core (int exit_status, const char *file,
    	       int line, const char *mode,
    	       const char *message, va_list ap)
    {
      fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
      vfprintf (stderr, message, ap);
      fprintf (stderr, ".\n");
    
      if (exit_status >= 0)
        exit (exit_status);
    }
    
    void
    lt_fatal (const char *file, int line, const char *message, ...)
    {
      va_list ap;
      va_start (ap, message);
      lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
      va_end (ap);
    }
    
    static const char *
    nonnull (const char *s)
    {
      return s ? s : "(null)";
    }
    
    static const char *
    nonempty (const char *s)
    {
      return (s && !*s) ? "(empty)" : nonnull (s);
    }
    
    void
    lt_setenv (const char *name, const char *value)
    {
      lt_debugprintf (__FILE__, __LINE__,
    		  "(lt_setenv) setting '%s' to '%s'\n",
                      nonnull (name), nonnull (value));
      {
    #ifdef HAVE_SETENV
        /* always make a copy, for consistency with !HAVE_SETENV */
        char *str = xstrdup (value);
        setenv (name, str, 1);
    #else
        size_t len = strlen (name) + 1 + strlen (value) + 1;
        char *str = XMALLOC (char, len);
        sprintf (str, "%s=%s", name, value);
        if (putenv (str) != EXIT_SUCCESS)
          {
            XFREE (str);
          }
    #endif
      }
    }
    
    char *
    lt_extend_str (const char *orig_value, const char *add, int to_end)
    {
      char *new_value;
      if (orig_value && *orig_value)
        {
          size_t orig_value_len = strlen (orig_value);
          size_t add_len = strlen (add);
          new_value = XMALLOC (char, add_len + orig_value_len + 1);
          if (to_end)
            {
              strcpy (new_value, orig_value);
              strcpy (new_value + orig_value_len, add);
            }
          else
            {
              strcpy (new_value, add);
              strcpy (new_value + add_len, orig_value);
            }
        }
      else
        {
          new_value = xstrdup (add);
        }
      return new_value;
    }
    
    void
    lt_update_exe_path (const char *name, const char *value)
    {
      lt_debugprintf (__FILE__, __LINE__,
    		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
                      nonnull (name), nonnull (value));
    
      if (name && *name && value && *value)
        {
          char *new_value = lt_extend_str (getenv (name), value, 0);
          /* some systems can't cope with a ':'-terminated path #' */
          size_t len = strlen (new_value);
          while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
            {
              new_value[--len] = '\0';
            }
          lt_setenv (name, new_value);
          XFREE (new_value);
        }
    }
    
    void
    lt_update_lib_path (const char *name, const char *value)
    {
      lt_debugprintf (__FILE__, __LINE__,
    		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
                      nonnull (name), nonnull (value));
    
      if (name && *name && value && *value)
        {
          char *new_value = lt_extend_str (getenv (name), value, 0);
          lt_setenv (name, new_value);
          XFREE (new_value);
        }
    }
    
    EOF
    	    case $host_os in
    	      mingw*)
    		cat <<"EOF"
    
    /* Prepares an argument vector before calling spawn().
       Note that spawn() does not by itself call the command interpreter
         (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
          ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
             GetVersionEx(&v);
             v.dwPlatformId == VER_PLATFORM_WIN32_NT;
          }) ? "cmd.exe" : "command.com").
       Instead it simply concatenates the arguments, separated by ' ', and calls
       CreateProcess().  We must quote the arguments since Win32 CreateProcess()
       interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
       special way:
       - Space and tab are interpreted as delimiters. They are not treated as
         delimiters if they are surrounded by double quotes: "...".
       - Unescaped double quotes are removed from the input. Their only effect is
         that within double quotes, space and tab are treated like normal
         characters.
       - Backslashes not followed by double quotes are not special.
       - But 2*n+1 backslashes followed by a double quote become
         n backslashes followed by a double quote (n >= 0):
           \" -> "
           \\\" -> \"
           \\\\\" -> \\"
     */
    #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
    #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
    char **
    prepare_spawn (char **argv)
    {
      size_t argc;
      char **new_argv;
      size_t i;
    
      /* Count number of arguments.  */
      for (argc = 0; argv[argc] != NULL; argc++)
        ;
    
      /* Allocate new argument vector.  */
      new_argv = XMALLOC (char *, argc + 1);
    
      /* Put quoted arguments into the new argument vector.  */
      for (i = 0; i < argc; i++)
        {
          const char *string = argv[i];
    
          if (string[0] == '\0')
    	new_argv[i] = xstrdup ("\"\"");
          else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
    	{
    	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
    	  size_t length;
    	  unsigned int backslashes;
    	  const char *s;
    	  char *quoted_string;
    	  char *p;
    
    	  length = 0;
    	  backslashes = 0;
    	  if (quote_around)
    	    length++;
    	  for (s = string; *s != '\0'; s++)
    	    {
    	      char c = *s;
    	      if (c == '"')
    		length += backslashes + 1;
    	      length++;
    	      if (c == '\\')
    		backslashes++;
    	      else
    		backslashes = 0;
    	    }
    	  if (quote_around)
    	    length += backslashes + 1;
    
    	  quoted_string = XMALLOC (char, length + 1);
    
    	  p = quoted_string;
    	  backslashes = 0;
    	  if (quote_around)
    	    *p++ = '"';
    	  for (s = string; *s != '\0'; s++)
    	    {
    	      char c = *s;
    	      if (c == '"')
    		{
    		  unsigned int j;
    		  for (j = backslashes + 1; j > 0; j--)
    		    *p++ = '\\';
    		}
    	      *p++ = c;
    	      if (c == '\\')
    		backslashes++;
    	      else
    		backslashes = 0;
    	    }
    	  if (quote_around)
    	    {
    	      unsigned int j;
    	      for (j = backslashes; j > 0; j--)
    		*p++ = '\\';
    	      *p++ = '"';
    	    }
    	  *p = '\0';
    
    	  new_argv[i] = quoted_string;
    	}
          else
    	new_argv[i] = (char *) string;
        }
      new_argv[argc] = NULL;
    
      return new_argv;
    }
    EOF
    		;;
    	    esac
    
                cat <<"EOF"
    void lt_dump_script (FILE* f)
    {
    EOF
    	    func_emit_wrapper yes |
    	      $SED -n -e '
    s/^\(.\{79\}\)\(..*\)/\1\
    \2/
    h
    s/\([\\"]\)/\\\1/g
    s/$/\\n/
    s/\([^\n]*\).*/  fputs ("\1", f);/p
    g
    D'
                cat <<"EOF"
    }
    EOF
    }
    # end: func_emit_cwrapperexe_src
    
    # func_win32_import_lib_p ARG
    # True if ARG is an import lib, as indicated by $file_magic_cmd
    func_win32_import_lib_p ()
    {
        $debug_cmd
    
        case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
        *import*) : ;;
        *) false ;;
        esac
    }
    
    # func_suncc_cstd_abi
    # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
    # Several compiler flags select an ABI that is incompatible with the
    # Cstd library. Avoid specifying it if any are in CXXFLAGS.
    func_suncc_cstd_abi ()
    {
        $debug_cmd
    
        case " $compile_command " in
        *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
          suncc_use_cstd_abi=no
          ;;
        *)
          suncc_use_cstd_abi=yes
          ;;
        esac
    }
    
    # func_mode_link arg...
    func_mode_link ()
    {
        $debug_cmd
    
        case $host in
        *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
          # It is impossible to link a dll without this setting, and
          # we shouldn't force the makefile maintainer to figure out
          # what system we are compiling for in order to pass an extra
          # flag for every libtool invocation.
          # allow_undefined=no
    
          # FIXME: Unfortunately, there are problems with the above when trying
          # to make a dll that has undefined symbols, in which case not
          # even a static library is built.  For now, we need to specify
          # -no-undefined on the libtool link line when we can be certain
          # that all symbols are satisfied, otherwise we get a static library.
          allow_undefined=yes
          ;;
        *)
          allow_undefined=yes
          ;;
        esac
        libtool_args=$nonopt
        base_compile="$nonopt $@"
        compile_command=$nonopt
        finalize_command=$nonopt
    
        compile_rpath=
        finalize_rpath=
        compile_shlibpath=
        finalize_shlibpath=
        convenience=
        old_convenience=
        deplibs=
        old_deplibs=
        compiler_flags=
        linker_flags=
        dllsearchpath=
        lib_search_path=`pwd`
        inst_prefix_dir=
        new_inherited_linker_flags=
    
        avoid_version=no
        bindir=
        dlfiles=
        dlprefiles=
        dlself=no
        export_dynamic=no
        export_symbols=
        export_symbols_regex=
        generated=
        libobjs=
        ltlibs=
        module=no
        no_install=no
        objs=
        os2dllname=
        non_pic_objects=
        precious_files_regex=
        prefer_static_libs=no
        preload=false
        prev=
        prevarg=
        release=
        rpath=
        xrpath=
        perm_rpath=
        temp_rpath=
        thread_safe=no
        vinfo=
        vinfo_number=no
        weak_libs=
        single_module=$wl-single_module
        func_infer_tag $base_compile
    
        # We need to know -static, to get the right output filenames.
        for arg
        do
          case $arg in
          -shared)
    	test yes != "$build_libtool_libs" \
    	  && func_fatal_configuration "cannot build a shared library"
    	build_old_libs=no
    	break
    	;;
          -all-static | -static | -static-libtool-libs)
    	case $arg in
    	-all-static)
    	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
    	    func_warning "complete static linking is impossible in this configuration"
    	  fi
    	  if test -n "$link_static_flag"; then
    	    dlopen_self=$dlopen_self_static
    	  fi
    	  prefer_static_libs=yes
    	  ;;
    	-static)
    	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
    	    dlopen_self=$dlopen_self_static
    	  fi
    	  prefer_static_libs=built
    	  ;;
    	-static-libtool-libs)
    	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
    	    dlopen_self=$dlopen_self_static
    	  fi
    	  prefer_static_libs=yes
    	  ;;
    	esac
    	build_libtool_libs=no
    	build_old_libs=yes
    	break
    	;;
          esac
        done
    
        # See if our shared archives depend on static archives.
        test -n "$old_archive_from_new_cmds" && build_old_libs=yes
    
        # Go through the arguments, transforming them on the way.
        while test "$#" -gt 0; do
          arg=$1
          shift
          func_quote_arg pretty,unquoted "$arg"
          qarg=$func_quote_arg_unquoted_result
          func_append libtool_args " $func_quote_arg_result"
    
          # If the previous option needs an argument, assign it.
          if test -n "$prev"; then
    	case $prev in
    	output)
    	  func_append compile_command " @OUTPUT@"
    	  func_append finalize_command " @OUTPUT@"
    	  ;;
    	esac
    
    	case $prev in
    	bindir)
    	  bindir=$arg
    	  prev=
    	  continue
    	  ;;
    	dlfiles|dlprefiles)
    	  $preload || {
    	    # Add the symbol object into the linking commands.
    	    func_append compile_command " @SYMFILE@"
    	    func_append finalize_command " @SYMFILE@"
    	    preload=:
    	  }
    	  case $arg in
    	  *.la | *.lo) ;;  # We handle these cases below.
    	  force)
    	    if test no = "$dlself"; then
    	      dlself=needless
    	      export_dynamic=yes
    	    fi
    	    prev=
    	    continue
    	    ;;
    	  self)
    	    if test dlprefiles = "$prev"; then
    	      dlself=yes
    	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
    	      dlself=yes
    	    else
    	      dlself=needless
    	      export_dynamic=yes
    	    fi
    	    prev=
    	    continue
    	    ;;
    	  *)
    	    if test dlfiles = "$prev"; then
    	      func_append dlfiles " $arg"
    	    else
    	      func_append dlprefiles " $arg"
    	    fi
    	    prev=
    	    continue
    	    ;;
    	  esac
    	  ;;
    	expsyms)
    	  export_symbols=$arg
    	  test -f "$arg" \
    	    || func_fatal_error "symbol file '$arg' does not exist"
    	  prev=
    	  continue
    	  ;;
    	expsyms_regex)
    	  export_symbols_regex=$arg
    	  prev=
    	  continue
    	  ;;
    	framework)
    	  case $host in
    	    *-*-darwin*)
    	      case "$deplibs " in
    		*" $qarg.ltframework "*) ;;
    		*) func_append deplibs " $qarg.ltframework" # this is fixed later
    		   ;;
    	      esac
    	      ;;
    	  esac
    	  prev=
    	  continue
    	  ;;
    	inst_prefix)
    	  inst_prefix_dir=$arg
    	  prev=
    	  continue
    	  ;;
    	mllvm)
    	  # Clang does not use LLVM to link, so we can simply discard any
    	  # '-mllvm $arg' options when doing the link step.
    	  prev=
    	  continue
    	  ;;
    	objectlist)
    	  if test -f "$arg"; then
    	    save_arg=$arg
    	    moreargs=
    	    for fil in `cat "$save_arg"`
    	    do
    #	      func_append moreargs " $fil"
    	      arg=$fil
    	      # A libtool-controlled object.
    
    	      # Check to see that this really is a libtool object.
    	      if func_lalib_unsafe_p "$arg"; then
    		pic_object=
    		non_pic_object=
    
    		# Read the .lo file
    		func_source "$arg"
    
    		if test -z "$pic_object" ||
    		   test -z "$non_pic_object" ||
    		   test none = "$pic_object" &&
    		   test none = "$non_pic_object"; then
    		  func_fatal_error "cannot find name of object for '$arg'"
    		fi
    
    		# Extract subdirectory from the argument.
    		func_dirname "$arg" "/" ""
    		xdir=$func_dirname_result
    
    		if test none != "$pic_object"; then
    		  # Prepend the subdirectory the object is found in.
    		  pic_object=$xdir$pic_object
    
    		  if test dlfiles = "$prev"; then
    		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
    		      func_append dlfiles " $pic_object"
    		      prev=
    		      continue
    		    else
    		      # If libtool objects are unsupported, then we need to preload.
    		      prev=dlprefiles
    		    fi
    		  fi
    
    		  # CHECK ME:  I think I busted this.  -Ossama
    		  if test dlprefiles = "$prev"; then
    		    # Preload the old-style object.
    		    func_append dlprefiles " $pic_object"
    		    prev=
    		  fi
    
    		  # A PIC object.
    		  func_append libobjs " $pic_object"
    		  arg=$pic_object
    		fi
    
    		# Non-PIC object.
    		if test none != "$non_pic_object"; then
    		  # Prepend the subdirectory the object is found in.
    		  non_pic_object=$xdir$non_pic_object
    
    		  # A standard non-PIC object
    		  func_append non_pic_objects " $non_pic_object"
    		  if test -z "$pic_object" || test none = "$pic_object"; then
    		    arg=$non_pic_object
    		  fi
    		else
    		  # If the PIC object exists, use it instead.
    		  # $xdir was prepended to $pic_object above.
    		  non_pic_object=$pic_object
    		  func_append non_pic_objects " $non_pic_object"
    		fi
    	      else
    		# Only an error if not doing a dry-run.
    		if $opt_dry_run; then
    		  # Extract subdirectory from the argument.
    		  func_dirname "$arg" "/" ""
    		  xdir=$func_dirname_result
    
    		  func_lo2o "$arg"
    		  pic_object=$xdir$objdir/$func_lo2o_result
    		  non_pic_object=$xdir$func_lo2o_result
    		  func_append libobjs " $pic_object"
    		  func_append non_pic_objects " $non_pic_object"
    	        else
    		  func_fatal_error "'$arg' is not a valid libtool object"
    		fi
    	      fi
    	    done
    	  else
    	    func_fatal_error "link input file '$arg' does not exist"
    	  fi
    	  arg=$save_arg
    	  prev=
    	  continue
    	  ;;
    	os2dllname)
    	  os2dllname=$arg
    	  prev=
    	  continue
    	  ;;
    	precious_regex)
    	  precious_files_regex=$arg
    	  prev=
    	  continue
    	  ;;
    	release)
    	  release=-$arg
    	  prev=
    	  continue
    	  ;;
    	rpath | xrpath)
    	  # We need an absolute path.
    	  case $arg in
    	  [\\/]* | [A-Za-z]:[\\/]*) ;;
    	  *)
    	    func_fatal_error "only absolute run-paths are allowed"
    	    ;;
    	  esac
    	  if test rpath = "$prev"; then
    	    case "$rpath " in
    	    *" $arg "*) ;;
    	    *) func_append rpath " $arg" ;;
    	    esac
    	  else
    	    case "$xrpath " in
    	    *" $arg "*) ;;
    	    *) func_append xrpath " $arg" ;;
    	    esac
    	  fi
    	  prev=
    	  continue
    	  ;;
    	shrext)
    	  shrext_cmds=$arg
    	  prev=
    	  continue
    	  ;;
    	weak)
    	  func_append weak_libs " $arg"
    	  prev=
    	  continue
    	  ;;
    	xassembler)
    	  func_append compiler_flags " -Xassembler $qarg"
    	  prev=
    	  func_append compile_command " -Xassembler $qarg"
    	  func_append finalize_command " -Xassembler $qarg"
    	  continue
    	  ;;
    	xcclinker)
    	  func_append linker_flags " $qarg"
    	  func_append compiler_flags " $qarg"
    	  prev=
    	  func_append compile_command " $qarg"
    	  func_append finalize_command " $qarg"
    	  continue
    	  ;;
    	xcompiler)
    	  func_append compiler_flags " $qarg"
    	  prev=
    	  func_append compile_command " $qarg"
    	  func_append finalize_command " $qarg"
    	  continue
    	  ;;
    	xlinker)
    	  func_append linker_flags " $qarg"
    	  func_append compiler_flags " $wl$qarg"
    	  prev=
    	  func_append compile_command " $wl$qarg"
    	  func_append finalize_command " $wl$qarg"
    	  continue
    	  ;;
    	*)
    	  eval "$prev=\"\$arg\""
    	  prev=
    	  continue
    	  ;;
    	esac
          fi # test -n "$prev"
    
          prevarg=$arg
    
          case $arg in
          -all-static)
    	if test -n "$link_static_flag"; then
    	  # See comment for -static flag below, for more details.
    	  func_append compile_command " $link_static_flag"
    	  func_append finalize_command " $link_static_flag"
    	fi
    	continue
    	;;
    
          -allow-undefined)
    	# FIXME: remove this flag sometime in the future.
    	func_fatal_error "'-allow-undefined' must not be used because it is the default"
    	;;
    
          -avoid-version)
    	avoid_version=yes
    	continue
    	;;
    
          -bindir)
    	prev=bindir
    	continue
    	;;
    
          -dlopen)
    	prev=dlfiles
    	continue
    	;;
    
          -dlpreopen)
    	prev=dlprefiles
    	continue
    	;;
    
          -export-dynamic)
    	export_dynamic=yes
    	continue
    	;;
    
          -export-symbols | -export-symbols-regex)
    	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
    	  func_fatal_error "more than one -exported-symbols argument is not allowed"
    	fi
    	if test X-export-symbols = "X$arg"; then
    	  prev=expsyms
    	else
    	  prev=expsyms_regex
    	fi
    	continue
    	;;
    
          -framework)
    	prev=framework
    	continue
    	;;
    
          -inst-prefix-dir)
    	prev=inst_prefix
    	continue
    	;;
    
          # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
          # so, if we see these flags be careful not to treat them like -L
          -L[A-Z][A-Z]*:*)
    	case $with_gcc/$host in
    	no/*-*-irix* | /*-*-irix*)
    	  func_append compile_command " $arg"
    	  func_append finalize_command " $arg"
    	  ;;
    	esac
    	continue
    	;;
    
          -L*)
    	func_stripname "-L" '' "$arg"
    	if test -z "$func_stripname_result"; then
    	  if test "$#" -gt 0; then
    	    func_fatal_error "require no space between '-L' and '$1'"
    	  else
    	    func_fatal_error "need path for '-L' option"
    	  fi
    	fi
    	func_resolve_sysroot "$func_stripname_result"
    	dir=$func_resolve_sysroot_result
    	# We need an absolute path.
    	case $dir in
    	[\\/]* | [A-Za-z]:[\\/]*) ;;
    	*)
    	  absdir=`cd "$dir" && pwd`
    	  test -z "$absdir" && \
    	    func_fatal_error "cannot determine absolute directory name of '$dir'"
    	  dir=$absdir
    	  ;;
    	esac
    	case "$deplibs " in
    	*" -L$dir "* | *" $arg "*)
    	  # Will only happen for absolute or sysroot arguments
    	  ;;
    	*)
    	  # Preserve sysroot, but never include relative directories
    	  case $dir in
    	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
    	    *) func_append deplibs " -L$dir" ;;
    	  esac
    	  func_append lib_search_path " $dir"
    	  ;;
    	esac
    	case $host in
    	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
    	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
    	  case :$dllsearchpath: in
    	  *":$dir:"*) ;;
    	  ::) dllsearchpath=$dir;;
    	  *) func_append dllsearchpath ":$dir";;
    	  esac
    	  case :$dllsearchpath: in
    	  *":$testbindir:"*) ;;
    	  ::) dllsearchpath=$testbindir;;
    	  *) func_append dllsearchpath ":$testbindir";;
    	  esac
    	  ;;
    	esac
    	continue
    	;;
    
          -l*)
    	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
    	  case $host in
    	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
    	    # These systems don't actually have a C or math library (as such)
    	    continue
    	    ;;
    	  *-*-os2*)
    	    # These systems don't actually have a C library (as such)
    	    test X-lc = "X$arg" && continue
    	    ;;
    	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*)
    	    # Do not include libc due to us having libc/libc_r.
    	    test X-lc = "X$arg" && continue
    	    ;;
    	  *-*-rhapsody* | *-*-darwin1.[012])
    	    # Rhapsody C and math libraries are in the System framework
    	    func_append deplibs " System.ltframework"
    	    continue
    	    ;;
    	  *-*-sco3.2v5* | *-*-sco5v6*)
    	    # Causes problems with __ctype
    	    test X-lc = "X$arg" && continue
    	    ;;
    	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
    	    # Compiler inserts libc in the correct place for threads to work
    	    test X-lc = "X$arg" && continue
    	    ;;
    	  esac
    	elif test X-lc_r = "X$arg"; then
    	 case $host in
    	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*)
    	   # Do not include libc_r directly, use -pthread flag.
    	   continue
    	   ;;
    	 esac
    	fi
    	func_append deplibs " $arg"
    	continue
    	;;
    
          -mllvm)
    	prev=mllvm
    	continue
    	;;
    
          -module)
    	module=yes
    	continue
    	;;
    
          # Tru64 UNIX uses -model [arg] to determine the layout of C++
          # classes, name mangling, and exception handling.
          # Darwin uses the -arch flag to determine output architecture.
          -model|-arch|-isysroot|--sysroot)
    	func_append compiler_flags " $arg"
    	func_append compile_command " $arg"
    	func_append finalize_command " $arg"
    	prev=xcompiler
    	continue
    	;;
         # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199.
         -pthread)
    	case $host in
    	  *solaris2*) ;;
    	  *)
    	    case "$new_inherited_linker_flags " in
    	        *" $arg "*) ;;
    	        * ) func_append new_inherited_linker_flags " $arg" ;;
    	    esac
    	  ;;
    	esac
    	continue
    	;;
          -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \
          |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
    	func_append compiler_flags " $arg"
    	func_append compile_command " $arg"
    	func_append finalize_command " $arg"
    	case "$new_inherited_linker_flags " in
    	    *" $arg "*) ;;
    	    * ) func_append new_inherited_linker_flags " $arg" ;;
    	esac
    	continue
    	;;
    
          -multi_module)
    	single_module=$wl-multi_module
    	continue
    	;;
    
          -no-fast-install)
    	fast_install=no
    	continue
    	;;
    
          -no-install)
    	case $host in
    	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
    	  # The PATH hackery in wrapper scripts is required on Windows
    	  # and Darwin in order for the loader to find any dlls it needs.
    	  func_warning "'-no-install' is ignored for $host"
    	  func_warning "assuming '-no-fast-install' instead"
    	  fast_install=no
    	  ;;
    	*) no_install=yes ;;
    	esac
    	continue
    	;;
    
          -no-undefined)
    	allow_undefined=no
    	continue
    	;;
    
          -objectlist)
    	prev=objectlist
    	continue
    	;;
    
          -os2dllname)
    	prev=os2dllname
    	continue
    	;;
    
          -o) prev=output ;;
    
          -precious-files-regex)
    	prev=precious_regex
    	continue
    	;;
    
          -release)
    	prev=release
    	continue
    	;;
    
          -rpath)
    	prev=rpath
    	continue
    	;;
    
          -R)
    	prev=xrpath
    	continue
    	;;
    
          -R*)
    	func_stripname '-R' '' "$arg"
    	dir=$func_stripname_result
    	# We need an absolute path.
    	case $dir in
    	[\\/]* | [A-Za-z]:[\\/]*) ;;
    	=*)
    	  func_stripname '=' '' "$dir"
    	  dir=$lt_sysroot$func_stripname_result
    	  ;;
    	*)
    	  func_fatal_error "only absolute run-paths are allowed"
    	  ;;
    	esac
    	case "$xrpath " in
    	*" $dir "*) ;;
    	*) func_append xrpath " $dir" ;;
    	esac
    	continue
    	;;
    
          -shared)
    	# The effects of -shared are defined in a previous loop.
    	continue
    	;;
    
          -shrext)
    	prev=shrext
    	continue
    	;;
    
          -static | -static-libtool-libs)
    	# The effects of -static are defined in a previous loop.
    	# We used to do the same as -all-static on platforms that
    	# didn't have a PIC flag, but the assumption that the effects
    	# would be equivalent was wrong.  It would break on at least
    	# Digital Unix and AIX.
    	continue
    	;;
    
          -thread-safe)
    	thread_safe=yes
    	continue
    	;;
    
          -version-info)
    	prev=vinfo
    	continue
    	;;
    
          -version-number)
    	prev=vinfo
    	vinfo_number=yes
    	continue
    	;;
    
          -weak)
            prev=weak
    	continue
    	;;
    
          -Wc,*)
    	func_stripname '-Wc,' '' "$arg"
    	args=$func_stripname_result
    	arg=
    	save_ifs=$IFS; IFS=,
    	for flag in $args; do
    	  IFS=$save_ifs
              func_quote_arg pretty "$flag"
    	  func_append arg " $func_quote_arg_result"
    	  func_append compiler_flags " $func_quote_arg_result"
    	done
    	IFS=$save_ifs
    	func_stripname ' ' '' "$arg"
    	arg=$func_stripname_result
    	;;
    
          -Wl,*)
    	func_stripname '-Wl,' '' "$arg"
    	args=$func_stripname_result
    	arg=
    	save_ifs=$IFS; IFS=,
    	for flag in $args; do
    	  IFS=$save_ifs
              func_quote_arg pretty "$flag"
    	  func_append arg " $wl$func_quote_arg_result"
    	  func_append compiler_flags " $wl$func_quote_arg_result"
    	  func_append linker_flags " $func_quote_arg_result"
    	done
    	IFS=$save_ifs
    	func_stripname ' ' '' "$arg"
    	arg=$func_stripname_result
    	;;
    
          -Xassembler)
            prev=xassembler
            continue
            ;;
    
          -Xcompiler)
    	prev=xcompiler
    	continue
    	;;
    
          -Xlinker)
    	prev=xlinker
    	continue
    	;;
    
          -XCClinker)
    	prev=xcclinker
    	continue
    	;;
    
          # -msg_* for osf cc
          -msg_*)
    	func_quote_arg pretty "$arg"
    	arg=$func_quote_arg_result
    	;;
    
          # Flags to be passed through unchanged, with rationale:
          # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
          # -r[0-9][0-9]*        specify processor for the SGI compiler
          # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
          # +DA*, +DD*           enable 64-bit mode for the HP compiler
          # -q*                  compiler args for the IBM compiler
          # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
          # -F/path              path to uninstalled frameworks, gcc on darwin
          # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
          # -fstack-protector*   stack protector flags for GCC
          # @file                GCC response files
          # -tp=*                Portland pgcc target processor selection
          # --sysroot=*          for sysroot support
          # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
          # -specs=*             GCC specs files
          # -stdlib=*            select c++ std lib with clang
          # -fsanitize=*         Clang/GCC memory and address sanitizer
          # -fuse-ld=*           Linker select flags for GCC
          # -static-*            direct GCC to link specific libraries statically
          # -fcilkplus           Cilk Plus language extension features for C/C++
          # -Wa,*                Pass flags directly to the assembler
          -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
          -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
          -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
          -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus|-Wa,*)
            func_quote_arg pretty "$arg"
    	arg=$func_quote_arg_result
            func_append compile_command " $arg"
            func_append finalize_command " $arg"
            func_append compiler_flags " $arg"
            continue
            ;;
    
          -Z*)
            if test os2 = "`expr $host : '.*\(os2\)'`"; then
              # OS/2 uses -Zxxx to specify OS/2-specific options
    	  compiler_flags="$compiler_flags $arg"
    	  func_append compile_command " $arg"
    	  func_append finalize_command " $arg"
    	  case $arg in
    	  -Zlinker | -Zstack)
    	    prev=xcompiler
    	    ;;
    	  esac
    	  continue
            else
    	  # Otherwise treat like 'Some other compiler flag' below
    	  func_quote_arg pretty "$arg"
    	  arg=$func_quote_arg_result
            fi
    	;;
    
          # Some other compiler flag.
          -* | +*)
            func_quote_arg pretty "$arg"
    	arg=$func_quote_arg_result
    	;;
    
          *.$objext)
    	# A standard object.
    	func_append objs " $arg"
    	;;
    
          *.lo)
    	# A libtool-controlled object.
    
    	# Check to see that this really is a libtool object.
    	if func_lalib_unsafe_p "$arg"; then
    	  pic_object=
    	  non_pic_object=
    
    	  # Read the .lo file
    	  func_source "$arg"
    
    	  if test -z "$pic_object" ||
    	     test -z "$non_pic_object" ||
    	     test none = "$pic_object" &&
    	     test none = "$non_pic_object"; then
    	    func_fatal_error "cannot find name of object for '$arg'"
    	  fi
    
    	  # Extract subdirectory from the argument.
    	  func_dirname "$arg" "/" ""
    	  xdir=$func_dirname_result
    
    	  test none = "$pic_object" || {
    	    # Prepend the subdirectory the object is found in.
    	    pic_object=$xdir$pic_object
    
    	    if test dlfiles = "$prev"; then
    	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
    		func_append dlfiles " $pic_object"
    		prev=
    		continue
    	      else
    		# If libtool objects are unsupported, then we need to preload.
    		prev=dlprefiles
    	      fi
    	    fi
    
    	    # CHECK ME:  I think I busted this.  -Ossama
    	    if test dlprefiles = "$prev"; then
    	      # Preload the old-style object.
    	      func_append dlprefiles " $pic_object"
    	      prev=
    	    fi
    
    	    # A PIC object.
    	    func_append libobjs " $pic_object"
    	    arg=$pic_object
    	  }
    
    	  # Non-PIC object.
    	  if test none != "$non_pic_object"; then
    	    # Prepend the subdirectory the object is found in.
    	    non_pic_object=$xdir$non_pic_object
    
    	    # A standard non-PIC object
    	    func_append non_pic_objects " $non_pic_object"
    	    if test -z "$pic_object" || test none = "$pic_object"; then
    	      arg=$non_pic_object
    	    fi
    	  else
    	    # If the PIC object exists, use it instead.
    	    # $xdir was prepended to $pic_object above.
    	    non_pic_object=$pic_object
    	    func_append non_pic_objects " $non_pic_object"
    	  fi
    	else
    	  # Only an error if not doing a dry-run.
    	  if $opt_dry_run; then
    	    # Extract subdirectory from the argument.
    	    func_dirname "$arg" "/" ""
    	    xdir=$func_dirname_result
    
    	    func_lo2o "$arg"
    	    pic_object=$xdir$objdir/$func_lo2o_result
    	    non_pic_object=$xdir$func_lo2o_result
    	    func_append libobjs " $pic_object"
    	    func_append non_pic_objects " $non_pic_object"
    	  else
    	    func_fatal_error "'$arg' is not a valid libtool object"
    	  fi
    	fi
    	;;
    
          *.$libext)
    	# An archive.
    	func_append deplibs " $arg"
    	func_append old_deplibs " $arg"
    	continue
    	;;
    
          *.la)
    	# A libtool-controlled library.
    
    	func_resolve_sysroot "$arg"
    	if test dlfiles = "$prev"; then
    	  # This library was specified with -dlopen.
    	  func_append dlfiles " $func_resolve_sysroot_result"
    	  prev=
    	elif test dlprefiles = "$prev"; then
    	  # The library was specified with -dlpreopen.
    	  func_append dlprefiles " $func_resolve_sysroot_result"
    	  prev=
    	else
    	  func_append deplibs " $func_resolve_sysroot_result"
    	fi
    	continue
    	;;
    
          # Some other compiler argument.
          *)
    	# Unknown arguments in both finalize_command and compile_command need
    	# to be aesthetically quoted because they are evaled later.
    	func_quote_arg pretty "$arg"
    	arg=$func_quote_arg_result
    	;;
          esac # arg
    
          # Now actually substitute the argument into the commands.
          if test -n "$arg"; then
    	func_append compile_command " $arg"
    	func_append finalize_command " $arg"
          fi
        done # argument parsing loop
    
        test -n "$prev" && \
          func_fatal_help "the '$prevarg' option requires an argument"
    
        if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
          eval arg=\"$export_dynamic_flag_spec\"
          func_append compile_command " $arg"
          func_append finalize_command " $arg"
        fi
    
        oldlibs=
        # calculate the name of the file, without its directory
        func_basename "$output"
        outputname=$func_basename_result
        libobjs_save=$libobjs
    
        if test -n "$shlibpath_var"; then
          # get the directories listed in $shlibpath_var
          eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
        else
          shlib_search_path=
        fi
        eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
        eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
    
        # Definition is injected by LT_CONFIG during libtool generation.
        func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
    
        func_dirname "$output" "/" ""
        output_objdir=$func_dirname_result$objdir
        func_to_tool_file "$output_objdir/"
        tool_output_objdir=$func_to_tool_file_result
        # Create the object directory.
        func_mkdir_p "$output_objdir"
    
        # Determine the type of output
        case $output in
        "")
          func_fatal_help "you must specify an output file"
          ;;
        *.$libext) linkmode=oldlib ;;
        *.lo | *.$objext) linkmode=obj ;;
        *.la) linkmode=lib ;;
        *) linkmode=prog ;; # Anything else should be a program.
        esac
    
        specialdeplibs=
    
        libs=
        # Find all interdependent deplibs by searching for libraries
        # that are linked more than once (e.g. -la -lb -la)
        for deplib in $deplibs; do
          if $opt_preserve_dup_deps; then
    	case "$libs " in
    	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
    	esac
          fi
          func_append libs " $deplib"
        done
    
        if test lib = "$linkmode"; then
          libs="$predeps $libs $compiler_lib_search_path $postdeps"
    
          # Compute libraries that are listed more than once in $predeps
          # $postdeps and mark them as special (i.e., whose duplicates are
          # not to be eliminated).
          pre_post_deps=
          if $opt_duplicate_compiler_generated_deps; then
    	for pre_post_dep in $predeps $postdeps; do
    	  case "$pre_post_deps " in
    	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
    	  esac
    	  func_append pre_post_deps " $pre_post_dep"
    	done
          fi
          pre_post_deps=
        fi
    
        deplibs=
        newdependency_libs=
        newlib_search_path=
        need_relink=no # whether we're linking any uninstalled libtool libraries
        notinst_deplibs= # not-installed libtool libraries
        notinst_path= # paths that contain not-installed libtool libraries
    
        case $linkmode in
        lib)
    	passes="conv dlpreopen link"
    	for file in $dlfiles $dlprefiles; do
    	  case $file in
    	  *.la) ;;
    	  *)
    	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
    	    ;;
    	  esac
    	done
    	;;
        prog)
    	compile_deplibs=
    	finalize_deplibs=
    	alldeplibs=false
    	newdlfiles=
    	newdlprefiles=
    	passes="conv scan dlopen dlpreopen link"
    	;;
        *)  passes="conv"
    	;;
        esac
    
        for pass in $passes; do
          # The preopen pass in lib mode reverses $deplibs; put it back here
          # so that -L comes before libs that need it for instance...
          if test lib,link = "$linkmode,$pass"; then
    	## FIXME: Find the place where the list is rebuilt in the wrong
    	##        order, and fix it there properly
            tmp_deplibs=
    	for deplib in $deplibs; do
    	  tmp_deplibs="$deplib $tmp_deplibs"
    	done
    	deplibs=$tmp_deplibs
          fi
    
          if test lib,link = "$linkmode,$pass" ||
    	 test prog,scan = "$linkmode,$pass"; then
    	libs=$deplibs
    	deplibs=
          fi
          if test prog = "$linkmode"; then
    	case $pass in
    	dlopen) libs=$dlfiles ;;
    	dlpreopen) libs=$dlprefiles ;;
    	link)
    	  libs="$deplibs %DEPLIBS%"
    	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
    	  ;;
    	esac
          fi
          if test lib,dlpreopen = "$linkmode,$pass"; then
    	# Collect and forward deplibs of preopened libtool libs
    	for lib in $dlprefiles; do
    	  # Ignore non-libtool-libs
    	  dependency_libs=
    	  func_resolve_sysroot "$lib"
    	  case $lib in
    	  *.la)	func_source "$func_resolve_sysroot_result" ;;
    	  esac
    
    	  # Collect preopened libtool deplibs, except any this library
    	  # has declared as weak libs
    	  for deplib in $dependency_libs; do
    	    func_basename "$deplib"
                deplib_base=$func_basename_result
    	    case " $weak_libs " in
    	    *" $deplib_base "*) ;;
    	    *) func_append deplibs " $deplib" ;;
    	    esac
    	  done
    	done
    	libs=$dlprefiles
          fi
          if test dlopen = "$pass"; then
    	# Collect dlpreopened libraries
    	save_deplibs=$deplibs
    	deplibs=
          fi
    
          for deplib in $libs; do
    	lib=
    	found=false
    	case $deplib in
    	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
            |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
    	  if test prog,link = "$linkmode,$pass"; then
    	    compile_deplibs="$deplib $compile_deplibs"
    	    finalize_deplibs="$deplib $finalize_deplibs"
    	  else
    	    func_append compiler_flags " $deplib"
    	    if test lib = "$linkmode"; then
    		case "$new_inherited_linker_flags " in
    		    *" $deplib "*) ;;
    		    * ) func_append new_inherited_linker_flags " $deplib" ;;
    		esac
    	    fi
    	  fi
    	  continue
    	  ;;
    	-l*)
    	  if test lib != "$linkmode" && test prog != "$linkmode"; then
    	    func_warning "'-l' is ignored for archives/objects"
    	    continue
    	  fi
    	  func_stripname '-l' '' "$deplib"
    	  name=$func_stripname_result
    	  if test lib = "$linkmode"; then
    	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
    	  else
    	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
    	  fi
    	  for searchdir in $searchdirs; do
    	    for search_ext in .la $std_shrext .so .a; do
    	      # Search the libtool library
    	      lib=$searchdir/lib$name$search_ext
    	      if test -f "$lib"; then
    		if test .la = "$search_ext"; then
    		  found=:
    		else
    		  found=false
    		fi
    		break 2
    	      fi
    	    done
    	  done
    	  if $found; then
    	    # deplib is a libtool library
    	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
    	    # We need to do some special things here, and not later.
    	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then
    	      case " $predeps $postdeps " in
    	      *" $deplib "*)
    		if func_lalib_p "$lib"; then
    		  library_names=
    		  old_library=
    		  func_source "$lib"
    		  for l in $old_library $library_names; do
    		    ll=$l
    		  done
    		  if test "X$ll" = "X$old_library"; then # only static version available
    		    found=false
    		    func_dirname "$lib" "" "."
    		    ladir=$func_dirname_result
    		    lib=$ladir/$old_library
    		    if test prog,link = "$linkmode,$pass"; then
    		      compile_deplibs="$deplib $compile_deplibs"
    		      finalize_deplibs="$deplib $finalize_deplibs"
    		    else
    		      deplibs="$deplib $deplibs"
    		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
    		    fi
    		    continue
    		  fi
    		fi
    		;;
    	      *) ;;
    	      esac
    	    fi
    	  else
    	    # deplib doesn't seem to be a libtool library
    	    if test prog,link = "$linkmode,$pass"; then
    	      compile_deplibs="$deplib $compile_deplibs"
    	      finalize_deplibs="$deplib $finalize_deplibs"
    	    else
    	      deplibs="$deplib $deplibs"
    	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
    	    fi
    	    continue
    	  fi
    	  ;; # -l
    	*.ltframework)
    	  if test prog,link = "$linkmode,$pass"; then
    	    compile_deplibs="$deplib $compile_deplibs"
    	    finalize_deplibs="$deplib $finalize_deplibs"
    	  else
    	    deplibs="$deplib $deplibs"
    	    if test lib = "$linkmode"; then
    		case "$new_inherited_linker_flags " in
    		    *" $deplib "*) ;;
    		    * ) func_append new_inherited_linker_flags " $deplib" ;;
    		esac
    	    fi
    	  fi
    	  continue
    	  ;;
    	-L*)
    	  case $linkmode in
    	  lib)
    	    deplibs="$deplib $deplibs"
    	    test conv = "$pass" && continue
    	    newdependency_libs="$deplib $newdependency_libs"
    	    func_stripname '-L' '' "$deplib"
    	    func_resolve_sysroot "$func_stripname_result"
    	    func_append newlib_search_path " $func_resolve_sysroot_result"
    	    ;;
    	  prog)
    	    if test conv = "$pass"; then
    	      deplibs="$deplib $deplibs"
    	      continue
    	    fi
    	    if test scan = "$pass"; then
    	      deplibs="$deplib $deplibs"
    	    else
    	      compile_deplibs="$deplib $compile_deplibs"
    	      finalize_deplibs="$deplib $finalize_deplibs"
    	    fi
    	    func_stripname '-L' '' "$deplib"
    	    func_resolve_sysroot "$func_stripname_result"
    	    func_append newlib_search_path " $func_resolve_sysroot_result"
    	    ;;
    	  *)
    	    func_warning "'-L' is ignored for archives/objects"
    	    ;;
    	  esac # linkmode
    	  continue
    	  ;; # -L
    	-R*)
    	  if test link = "$pass"; then
    	    func_stripname '-R' '' "$deplib"
    	    func_resolve_sysroot "$func_stripname_result"
    	    dir=$func_resolve_sysroot_result
    	    # Make sure the xrpath contains only unique directories.
    	    case "$xrpath " in
    	    *" $dir "*) ;;
    	    *) func_append xrpath " $dir" ;;
    	    esac
    	  fi
    	  deplibs="$deplib $deplibs"
    	  continue
    	  ;;
    	*.la)
    	  func_resolve_sysroot "$deplib"
    	  lib=$func_resolve_sysroot_result
    	  ;;
    	*.$libext)
    	  if test conv = "$pass"; then
    	    deplibs="$deplib $deplibs"
    	    continue
    	  fi
    	  case $linkmode in
    	  lib)
    	    # Linking convenience modules into shared libraries is allowed,
    	    # but linking other static libraries is non-portable.
    	    case " $dlpreconveniencelibs " in
    	    *" $deplib "*) ;;
    	    *)
    	      valid_a_lib=false
    	      case $deplibs_check_method in
    		match_pattern*)
    		  set dummy $deplibs_check_method; shift
    		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
    		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
    		    | $EGREP "$match_pattern_regex" > /dev/null; then
    		    valid_a_lib=:
    		  fi
    		;;
    		pass_all)
    		  valid_a_lib=:
    		;;
    	      esac
    	      if $valid_a_lib; then
    		echo
    		$ECHO "*** Warning: Linking the shared library $output against the"
    		$ECHO "*** static library $deplib is not portable!"
    		deplibs="$deplib $deplibs"
    	      else
    		echo
    		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
    		echo "*** I have the capability to make that library automatically link in when"
    		echo "*** you link to this library.  But I can only do this if you have a"
    		echo "*** shared version of the library, which you do not appear to have"
    		echo "*** because the file extensions .$libext of this argument makes me believe"
    		echo "*** that it is just a static archive that I should not use here."
    	      fi
    	      ;;
    	    esac
    	    continue
    	    ;;
    	  prog)
    	    if test link != "$pass"; then
    	      deplibs="$deplib $deplibs"
    	    else
    	      compile_deplibs="$deplib $compile_deplibs"
    	      finalize_deplibs="$deplib $finalize_deplibs"
    	    fi
    	    continue
    	    ;;
    	  esac # linkmode
    	  ;; # *.$libext
    	*.lo | *.$objext)
    	  if test conv = "$pass"; then
    	    deplibs="$deplib $deplibs"
    	  elif test prog = "$linkmode"; then
    	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
    	      # If there is no dlopen support or we're linking statically,
    	      # we need to preload.
    	      func_append newdlprefiles " $deplib"
    	      compile_deplibs="$deplib $compile_deplibs"
    	      finalize_deplibs="$deplib $finalize_deplibs"
    	    else
    	      func_append newdlfiles " $deplib"
    	    fi
    	  fi
    	  continue
    	  ;;
    	%DEPLIBS%)
    	  alldeplibs=:
    	  continue
    	  ;;
    	esac # case $deplib
    
    	$found || test -f "$lib" \
    	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
    
    	# Check to see that this really is a libtool archive.
    	func_lalib_unsafe_p "$lib" \
    	  || func_fatal_error "'$lib' is not a valid libtool archive"
    
    	func_dirname "$lib" "" "."
    	ladir=$func_dirname_result
    
    	dlname=
    	dlopen=
    	dlpreopen=
    	libdir=
    	library_names=
    	old_library=
    	inherited_linker_flags=
    	# If the library was installed with an old release of libtool,
    	# it will not redefine variables installed, or shouldnotlink
    	installed=yes
    	shouldnotlink=no
    	avoidtemprpath=
    
    
    	# Read the .la file
    	func_source "$lib"
    
    	# Convert "-framework foo" to "foo.ltframework"
    	if test -n "$inherited_linker_flags"; then
    	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
    	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
    	    case " $new_inherited_linker_flags " in
    	      *" $tmp_inherited_linker_flag "*) ;;
    	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
    	    esac
    	  done
    	fi
    	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
    	if test lib,link = "$linkmode,$pass" ||
    	   test prog,scan = "$linkmode,$pass" ||
    	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then
    	  test -n "$dlopen" && func_append dlfiles " $dlopen"
    	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
    	fi
    
    	if test conv = "$pass"; then
    	  # Only check for convenience libraries
    	  deplibs="$lib $deplibs"
    	  if test -z "$libdir"; then
    	    if test -z "$old_library"; then
    	      func_fatal_error "cannot find name of link library for '$lib'"
    	    fi
    	    # It is a libtool convenience library, so add in its objects.
    	    func_append convenience " $ladir/$objdir/$old_library"
    	    func_append old_convenience " $ladir/$objdir/$old_library"
    	    tmp_libs=
    	    for deplib in $dependency_libs; do
    	      deplibs="$deplib $deplibs"
    	      if $opt_preserve_dup_deps; then
    		case "$tmp_libs " in
    		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
    		esac
    	      fi
    	      func_append tmp_libs " $deplib"
    	    done
    	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
    	    func_fatal_error "'$lib' is not a convenience library"
    	  fi
    	  continue
    	fi # $pass = conv
    
    
    	# Get the name of the library we link against.
    	linklib=
    	if test -n "$old_library" &&
    	   { test yes = "$prefer_static_libs" ||
    	     test built,no = "$prefer_static_libs,$installed"; }; then
    	  linklib=$old_library
    	else
    	  for l in $old_library $library_names; do
    	    linklib=$l
    	  done
    	fi
    	if test -z "$linklib"; then
    	  func_fatal_error "cannot find name of link library for '$lib'"
    	fi
    
    	# This library was specified with -dlopen.
    	if test dlopen = "$pass"; then
    	  test -z "$libdir" \
    	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
    	  if test -z "$dlname" ||
    	     test yes != "$dlopen_support" ||
    	     test no = "$build_libtool_libs"
    	  then
    	    # If there is no dlname, no dlopen support or we're linking
    	    # statically, we need to preload.  We also need to preload any
    	    # dependent libraries so libltdl's deplib preloader doesn't
    	    # bomb out in the load deplibs phase.
    	    func_append dlprefiles " $lib $dependency_libs"
    	  else
    	    func_append newdlfiles " $lib"
    	  fi
    	  continue
    	fi # $pass = dlopen
    
    	# We need an absolute path.
    	case $ladir in
    	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
    	*)
    	  abs_ladir=`cd "$ladir" && pwd`
    	  if test -z "$abs_ladir"; then
    	    func_warning "cannot determine absolute directory name of '$ladir'"
    	    func_warning "passing it literally to the linker, although it might fail"
    	    abs_ladir=$ladir
    	  fi
    	  ;;
    	esac
    	func_basename "$lib"
    	laname=$func_basename_result
    
    	# Find the relevant object directory and library name.
    	if test yes = "$installed"; then
    	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
    	    func_warning "library '$lib' was moved."
    	    dir=$ladir
    	    absdir=$abs_ladir
    	    libdir=$abs_ladir
    	  else
    	    dir=$lt_sysroot$libdir
    	    absdir=$lt_sysroot$libdir
    	  fi
    	  test yes = "$hardcode_automatic" && avoidtemprpath=yes
    	else
    	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
    	    dir=$ladir
    	    absdir=$abs_ladir
    	    # Remove this search path later
    	    func_append notinst_path " $abs_ladir"
    	  else
    	    dir=$ladir/$objdir
    	    absdir=$abs_ladir/$objdir
    	    # Remove this search path later
    	    func_append notinst_path " $abs_ladir"
    	  fi
    	fi # $installed = yes
    	func_stripname 'lib' '.la' "$laname"
    	name=$func_stripname_result
    
    	# This library was specified with -dlpreopen.
    	if test dlpreopen = "$pass"; then
    	  if test -z "$libdir" && test prog = "$linkmode"; then
    	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
    	  fi
    	  case $host in
    	    # special handling for platforms with PE-DLLs.
    	    *cygwin* | *mingw* | *cegcc* )
    	      # Linker will automatically link against shared library if both
    	      # static and shared are present.  Therefore, ensure we extract
    	      # symbols from the import library if a shared library is present
    	      # (otherwise, the dlopen module name will be incorrect).  We do
    	      # this by putting the import library name into $newdlprefiles.
    	      # We recover the dlopen module name by 'saving' the la file
    	      # name in a special purpose variable, and (later) extracting the
    	      # dlname from the la file.
    	      if test -n "$dlname"; then
    	        func_tr_sh "$dir/$linklib"
    	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
    	        func_append newdlprefiles " $dir/$linklib"
    	      else
    	        func_append newdlprefiles " $dir/$old_library"
    	        # Keep a list of preopened convenience libraries to check
    	        # that they are being used correctly in the link pass.
    	        test -z "$libdir" && \
    	          func_append dlpreconveniencelibs " $dir/$old_library"
    	      fi
    	    ;;
    	    * )
    	      # Prefer using a static library (so that no silly _DYNAMIC symbols
    	      # are required to link).
    	      if test -n "$old_library"; then
    	        func_append newdlprefiles " $dir/$old_library"
    	        # Keep a list of preopened convenience libraries to check
    	        # that they are being used correctly in the link pass.
    	        test -z "$libdir" && \
    	          func_append dlpreconveniencelibs " $dir/$old_library"
    	      # Otherwise, use the dlname, so that lt_dlopen finds it.
    	      elif test -n "$dlname"; then
    	        func_append newdlprefiles " $dir/$dlname"
    	      else
    	        func_append newdlprefiles " $dir/$linklib"
    	      fi
    	    ;;
    	  esac
    	fi # $pass = dlpreopen
    
    	if test -z "$libdir"; then
    	  # Link the convenience library
    	  if test lib = "$linkmode"; then
    	    deplibs="$dir/$old_library $deplibs"
    	  elif test prog,link = "$linkmode,$pass"; then
    	    compile_deplibs="$dir/$old_library $compile_deplibs"
    	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
    	  else
    	    deplibs="$lib $deplibs" # used for prog,scan pass
    	  fi
    	  continue
    	fi
    
    
    	if test prog = "$linkmode" && test link != "$pass"; then
    	  func_append newlib_search_path " $ladir"
    	  deplibs="$lib $deplibs"
    
    	  linkalldeplibs=false
    	  if test no != "$link_all_deplibs" || test -z "$library_names" ||
    	     test no = "$build_libtool_libs"; then
    	    linkalldeplibs=:
    	  fi
    
    	  tmp_libs=
    	  for deplib in $dependency_libs; do
    	    case $deplib in
    	    -L*) func_stripname '-L' '' "$deplib"
    	         func_resolve_sysroot "$func_stripname_result"
    	         func_append newlib_search_path " $func_resolve_sysroot_result"
    		 ;;
    	    esac
    	    # Need to link against all dependency_libs?
    	    if $linkalldeplibs; then
    	      deplibs="$deplib $deplibs"
    	    else
    	      # Need to hardcode shared library paths
    	      # or/and link against static libraries
    	      newdependency_libs="$deplib $newdependency_libs"
    	    fi
    	    if $opt_preserve_dup_deps; then
    	      case "$tmp_libs " in
    	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
    	      esac
    	    fi
    	    func_append tmp_libs " $deplib"
    	  done # for deplib
    	  continue
    	fi # $linkmode = prog...
    
    	if test prog,link = "$linkmode,$pass"; then
    	  if test -n "$library_names" &&
    	     { { test no = "$prefer_static_libs" ||
    	         test built,yes = "$prefer_static_libs,$installed"; } ||
    	       test -z "$old_library"; }; then
    	    # We need to hardcode the library path
    	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
    	      # Make sure the rpath contains only unique directories.
    	      case $temp_rpath: in
    	      *"$absdir:"*) ;;
    	      *) func_append temp_rpath "$absdir:" ;;
    	      esac
    	    fi
    
    	    # Hardcode the library path.
    	    # Skip directories that are in the system default run-time
    	    # search path.
    	    case " $sys_lib_dlsearch_path " in
    	    *" $absdir "*) ;;
    	    *)
    	      case "$compile_rpath " in
    	      *" $absdir "*) ;;
    	      *) func_append compile_rpath " $absdir" ;;
    	      esac
    	      ;;
    	    esac
    	    case " $sys_lib_dlsearch_path " in
    	    *" $libdir "*) ;;
    	    *)
    	      case "$finalize_rpath " in
    	      *" $libdir "*) ;;
    	      *) func_append finalize_rpath " $libdir" ;;
    	      esac
    	      ;;
    	    esac
    	  fi # $linkmode,$pass = prog,link...
    
    	  if $alldeplibs &&
    	     { test pass_all = "$deplibs_check_method" ||
    	       { test yes = "$build_libtool_libs" &&
    		 test -n "$library_names"; }; }; then
    	    # We only need to search for static libraries
    	    continue
    	  fi
    	fi
    
    	link_static=no # Whether the deplib will be linked statically
    	use_static_libs=$prefer_static_libs
    	if test built = "$use_static_libs" && test yes = "$installed"; then
    	  use_static_libs=no
    	fi
    	if test -n "$library_names" &&
    	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
    	  case $host in
    	  *cygwin* | *mingw* | *cegcc* | *os2*)
    	      # No point in relinking DLLs because paths are not encoded
    	      func_append notinst_deplibs " $lib"
    	      need_relink=no
    	    ;;
    	  *)
    	    if test no = "$installed"; then
    	      func_append notinst_deplibs " $lib"
    	      need_relink=yes
    	    fi
    	    ;;
    	  esac
    	  # This is a shared library
    
    	  # Warn about portability, can't link against -module's on some
    	  # systems (darwin).  Don't bleat about dlopened modules though!
    	  dlopenmodule=
    	  for dlpremoduletest in $dlprefiles; do
    	    if test "X$dlpremoduletest" = "X$lib"; then
    	      dlopenmodule=$dlpremoduletest
    	      break
    	    fi
    	  done
    	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
    	    echo
    	    if test prog = "$linkmode"; then
    	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
    	    else
    	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
    	    fi
    	    $ECHO "*** $linklib is not portable!"
    	  fi
    	  if test lib = "$linkmode" &&
    	     test yes = "$hardcode_into_libs"; then
    	    # Hardcode the library path.
    	    # Skip directories that are in the system default run-time
    	    # search path.
    	    case " $sys_lib_dlsearch_path " in
    	    *" $absdir "*) ;;
    	    *)
    	      case "$compile_rpath " in
    	      *" $absdir "*) ;;
    	      *) func_append compile_rpath " $absdir" ;;
    	      esac
    	      ;;
    	    esac
    	    case " $sys_lib_dlsearch_path " in
    	    *" $libdir "*) ;;
    	    *)
    	      case "$finalize_rpath " in
    	      *" $libdir "*) ;;
    	      *) func_append finalize_rpath " $libdir" ;;
    	      esac
    	      ;;
    	    esac
    	  fi
    
    	  if test -n "$old_archive_from_expsyms_cmds"; then
    	    # figure out the soname
    	    set dummy $library_names
    	    shift
    	    realname=$1
    	    shift
    	    libname=`eval "\\$ECHO \"$libname_spec\""`
    	    # use dlname if we got it. it's perfectly good, no?
    	    if test -n "$dlname"; then
    	      soname=$dlname
    	    elif test -n "$soname_spec"; then
    	      # bleh windows
    	      case $host in
    	      *cygwin* | mingw* | *cegcc* | *os2*)
    	        func_arith $current - $age
    		major=$func_arith_result
    		versuffix=-$major
    		;;
    	      esac
    	      eval soname=\"$soname_spec\"
    	    else
    	      soname=$realname
    	    fi
    
    	    # Make a new name for the extract_expsyms_cmds to use
    	    soroot=$soname
    	    func_basename "$soroot"
    	    soname=$func_basename_result
    	    func_stripname 'lib' '.dll' "$soname"
    	    newlib=libimp-$func_stripname_result.a
    
    	    # If the library has no export list, then create one now
    	    if test -f "$output_objdir/$soname-def"; then :
    	    else
    	      func_verbose "extracting exported symbol list from '$soname'"
    	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
    	    fi
    
    	    # Create $newlib
    	    if test -f "$output_objdir/$newlib"; then :; else
    	      func_verbose "generating import library for '$soname'"
    	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
    	    fi
    	    # make sure the library variables are pointing to the new library
    	    dir=$output_objdir
    	    linklib=$newlib
    	  fi # test -n "$old_archive_from_expsyms_cmds"
    
    	  if test prog = "$linkmode" || test relink != "$opt_mode"; then
    	    add_shlibpath=
    	    add_dir=
    	    add=
    	    lib_linked=yes
    	    case $hardcode_action in
    	    immediate | unsupported)
    	      if test no = "$hardcode_direct"; then
    		add=$dir/$linklib
    		case $host in
    		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
    		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
    		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
    		    *-*-unixware7*) add_dir=-L$dir ;;
    		  *-*-darwin* )
    		    # if the lib is a (non-dlopened) module then we cannot
    		    # link against it, someone is ignoring the earlier warnings
    		    if /usr/bin/file -L $add 2> /dev/null |
    			 $GREP ": [^:]* bundle" >/dev/null; then
    		      if test "X$dlopenmodule" != "X$lib"; then
    			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
    			if test -z "$old_library"; then
    			  echo
    			  echo "*** And there doesn't seem to be a static archive available"
    			  echo "*** The link will probably fail, sorry"
    			else
    			  add=$dir/$old_library
    			fi
    		      elif test -n "$old_library"; then
    			add=$dir/$old_library
    		      fi
    		    fi
    		esac
    	      elif test no = "$hardcode_minus_L"; then
    		case $host in
    		*-*-sunos*) add_shlibpath=$dir ;;
    		esac
    		add_dir=-L$dir
    		add=-l$name
    	      elif test no = "$hardcode_shlibpath_var"; then
    		add_shlibpath=$dir
    		add=-l$name
    	      else
    		lib_linked=no
    	      fi
    	      ;;
    	    relink)
    	      if test yes = "$hardcode_direct" &&
    	         test no = "$hardcode_direct_absolute"; then
    		add=$dir/$linklib
    	      elif test yes = "$hardcode_minus_L"; then
    		add_dir=-L$absdir
    		# Try looking first in the location we're being installed to.
    		if test -n "$inst_prefix_dir"; then
    		  case $libdir in
    		    [\\/]*)
    		      func_append add_dir " -L$inst_prefix_dir$libdir"
    		      ;;
    		  esac
    		fi
    		add=-l$name
    	      elif test yes = "$hardcode_shlibpath_var"; then
    		add_shlibpath=$dir
    		add=-l$name
    	      else
    		lib_linked=no
    	      fi
    	      ;;
    	    *) lib_linked=no ;;
    	    esac
    
    	    if test yes != "$lib_linked"; then
    	      func_fatal_configuration "unsupported hardcode properties"
    	    fi
    
    	    if test -n "$add_shlibpath"; then
    	      case :$compile_shlibpath: in
    	      *":$add_shlibpath:"*) ;;
    	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
    	      esac
    	    fi
    	    if test prog = "$linkmode"; then
    	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
    	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
    	    else
    	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
    	      test -n "$add" && deplibs="$add $deplibs"
    	      if test yes != "$hardcode_direct" &&
    		 test yes != "$hardcode_minus_L" &&
    		 test yes = "$hardcode_shlibpath_var"; then
    		case :$finalize_shlibpath: in
    		*":$libdir:"*) ;;
    		*) func_append finalize_shlibpath "$libdir:" ;;
    		esac
    	      fi
    	    fi
    	  fi
    
    	  if test prog = "$linkmode" || test relink = "$opt_mode"; then
    	    add_shlibpath=
    	    add_dir=
    	    add=
    	    # Finalize command for both is simple: just hardcode it.
    	    if test yes = "$hardcode_direct" &&
    	       test no = "$hardcode_direct_absolute"; then
    	      add=$libdir/$linklib
    	    elif test yes = "$hardcode_minus_L"; then
    	      add_dir=-L$libdir
    	      add=-l$name
    	    elif test yes = "$hardcode_shlibpath_var"; then
    	      case :$finalize_shlibpath: in
    	      *":$libdir:"*) ;;
    	      *) func_append finalize_shlibpath "$libdir:" ;;
    	      esac
    	      add=-l$name
    	    elif test yes = "$hardcode_automatic"; then
    	      if test -n "$inst_prefix_dir" &&
    		 test -f "$inst_prefix_dir$libdir/$linklib"; then
    		add=$inst_prefix_dir$libdir/$linklib
    	      else
    		add=$libdir/$linklib
    	      fi
    	    else
    	      # We cannot seem to hardcode it, guess we'll fake it.
    	      add_dir=-L$libdir
    	      # Try looking first in the location we're being installed to.
    	      if test -n "$inst_prefix_dir"; then
    		case $libdir in
    		  [\\/]*)
    		    func_append add_dir " -L$inst_prefix_dir$libdir"
    		    ;;
    		esac
    	      fi
    	      add=-l$name
    	    fi
    
    	    if test prog = "$linkmode"; then
    	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
    	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
    	    else
    	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
    	      test -n "$add" && deplibs="$add $deplibs"
    	    fi
    	  fi
    	elif test prog = "$linkmode"; then
    	  # Here we assume that one of hardcode_direct or hardcode_minus_L
    	  # is not unsupported.  This is valid on all known static and
    	  # shared platforms.
    	  if test unsupported != "$hardcode_direct"; then
    	    test -n "$old_library" && linklib=$old_library
    	    compile_deplibs="$dir/$linklib $compile_deplibs"
    	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
    	  else
    	    compile_deplibs="-l$name -L$dir $compile_deplibs"
    	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
    	  fi
    	elif test yes = "$build_libtool_libs"; then
    	  # Not a shared library
    	  if test pass_all != "$deplibs_check_method"; then
    	    # We're trying link a shared library against a static one
    	    # but the system doesn't support it.
    
    	    # Just print a warning and add the library to dependency_libs so
    	    # that the program can be linked against the static library.
    	    echo
    	    $ECHO "*** Warning: This system cannot link to static lib archive $lib."
    	    echo "*** I have the capability to make that library automatically link in when"
    	    echo "*** you link to this library.  But I can only do this if you have a"
    	    echo "*** shared version of the library, which you do not appear to have."
    	    if test yes = "$module"; then
    	      echo "*** But as you try to build a module library, libtool will still create "
    	      echo "*** a static module, that should work as long as the dlopening application"
    	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
    	      if test -z "$global_symbol_pipe"; then
    		echo
    		echo "*** However, this would only work if libtool was able to extract symbol"
    		echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
    		echo "*** not find such a program.  So, this module is probably useless."
    		echo "*** 'nm' from GNU binutils and a full rebuild may help."
    	      fi
    	      if test no = "$build_old_libs"; then
    		build_libtool_libs=module
    		build_old_libs=yes
    	      else
    		build_libtool_libs=no
    	      fi
    	    fi
    	  else
    	    deplibs="$dir/$old_library $deplibs"
    	    link_static=yes
    	  fi
    	fi # link shared/static library?
    
    	if test lib = "$linkmode"; then
    	  if test -n "$dependency_libs" &&
    	     { test yes != "$hardcode_into_libs" ||
    	       test yes = "$build_old_libs" ||
    	       test yes = "$link_static"; }; then
    	    # Extract -R from dependency_libs
    	    temp_deplibs=
    	    for libdir in $dependency_libs; do
    	      case $libdir in
    	      -R*) func_stripname '-R' '' "$libdir"
    	           temp_xrpath=$func_stripname_result
    		   case " $xrpath " in
    		   *" $temp_xrpath "*) ;;
    		   *) func_append xrpath " $temp_xrpath";;
    		   esac;;
    	      *) func_append temp_deplibs " $libdir";;
    	      esac
    	    done
    	    dependency_libs=$temp_deplibs
    	  fi
    
    	  func_append newlib_search_path " $absdir"
    	  # Link against this library
    	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
    	  # ... and its dependency_libs
    	  tmp_libs=
    	  for deplib in $dependency_libs; do
    	    newdependency_libs="$deplib $newdependency_libs"
    	    case $deplib in
                  -L*) func_stripname '-L' '' "$deplib"
                       func_resolve_sysroot "$func_stripname_result";;
                  *) func_resolve_sysroot "$deplib" ;;
                esac
    	    if $opt_preserve_dup_deps; then
    	      case "$tmp_libs " in
    	      *" $func_resolve_sysroot_result "*)
                    func_append specialdeplibs " $func_resolve_sysroot_result" ;;
    	      esac
    	    fi
    	    func_append tmp_libs " $func_resolve_sysroot_result"
    	  done
    
    	  if test no != "$link_all_deplibs"; then
    	    # Add the search paths of all dependency libraries
    	    for deplib in $dependency_libs; do
    	      path=
    	      case $deplib in
    	      -L*) path=$deplib ;;
    	      *.la)
    	        func_resolve_sysroot "$deplib"
    	        deplib=$func_resolve_sysroot_result
    	        func_dirname "$deplib" "" "."
    		dir=$func_dirname_result
    		# We need an absolute path.
    		case $dir in
    		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
    		*)
    		  absdir=`cd "$dir" && pwd`
    		  if test -z "$absdir"; then
    		    func_warning "cannot determine absolute directory name of '$dir'"
    		    absdir=$dir
    		  fi
    		  ;;
    		esac
    		if $GREP "^installed=no" $deplib > /dev/null; then
    		case $host in
    		*-*-darwin*)
    		  depdepl=
    		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
    		  if test -n "$deplibrary_names"; then
    		    for tmp in $deplibrary_names; do
    		      depdepl=$tmp
    		    done
    		    if test -f "$absdir/$objdir/$depdepl"; then
    		      depdepl=$absdir/$objdir/$depdepl
    		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
                          if test -z "$darwin_install_name"; then
                              darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
                          fi
    		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
    		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
    		      path=
    		    fi
    		  fi
    		  ;;
    		*)
    		  path=-L$absdir/$objdir
    		  ;;
    		esac
    		else
    		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
    		  test -z "$libdir" && \
    		    func_fatal_error "'$deplib' is not a valid libtool archive"
    		  test "$absdir" != "$libdir" && \
    		    func_warning "'$deplib' seems to be moved"
    
    		  path=-L$absdir
    		fi
    		;;
    	      esac
    	      case " $deplibs " in
    	      *" $path "*) ;;
    	      *) deplibs="$path $deplibs" ;;
    	      esac
    	    done
    	  fi # link_all_deplibs != no
    	fi # linkmode = lib
          done # for deplib in $libs
          if test link = "$pass"; then
    	if test prog = "$linkmode"; then
    	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
    	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
    	else
    	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
    	fi
          fi
          dependency_libs=$newdependency_libs
          if test dlpreopen = "$pass"; then
    	# Link the dlpreopened libraries before other libraries
    	for deplib in $save_deplibs; do
    	  deplibs="$deplib $deplibs"
    	done
          fi
          if test dlopen != "$pass"; then
    	test conv = "$pass" || {
    	  # Make sure lib_search_path contains only unique directories.
    	  lib_search_path=
    	  for dir in $newlib_search_path; do
    	    case "$lib_search_path " in
    	    *" $dir "*) ;;
    	    *) func_append lib_search_path " $dir" ;;
    	    esac
    	  done
    	  newlib_search_path=
    	}
    
    	if test prog,link = "$linkmode,$pass"; then
    	  vars="compile_deplibs finalize_deplibs"
    	else
    	  vars=deplibs
    	fi
    	for var in $vars dependency_libs; do
    	  # Add libraries to $var in reverse order
    	  eval tmp_libs=\"\$$var\"
    	  new_libs=
    	  for deplib in $tmp_libs; do
    	    # FIXME: Pedantically, this is the right thing to do, so
    	    #        that some nasty dependency loop isn't accidentally
    	    #        broken:
    	    #new_libs="$deplib $new_libs"
    	    # Pragmatically, this seems to cause very few problems in
    	    # practice:
    	    case $deplib in
    	    -L*) new_libs="$deplib $new_libs" ;;
    	    -R*) ;;
    	    *)
    	      # And here is the reason: when a library appears more
    	      # than once as an explicit dependence of a library, or
    	      # is implicitly linked in more than once by the
    	      # compiler, it is considered special, and multiple
    	      # occurrences thereof are not removed.  Compare this
    	      # with having the same library being listed as a
    	      # dependency of multiple other libraries: in this case,
    	      # we know (pedantically, we assume) the library does not
    	      # need to be listed more than once, so we keep only the
    	      # last copy.  This is not always right, but it is rare
    	      # enough that we require users that really mean to play
    	      # such unportable linking tricks to link the library
    	      # using -Wl,-lname, so that libtool does not consider it
    	      # for duplicate removal.
    	      case " $specialdeplibs " in
    	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
    	      *)
    		case " $new_libs " in
    		*" $deplib "*) ;;
    		*) new_libs="$deplib $new_libs" ;;
    		esac
    		;;
    	      esac
    	      ;;
    	    esac
    	  done
    	  tmp_libs=
    	  for deplib in $new_libs; do
    	    case $deplib in
    	    -L*)
    	      case " $tmp_libs " in
    	      *" $deplib "*) ;;
    	      *) func_append tmp_libs " $deplib" ;;
    	      esac
    	      ;;
    	    *) func_append tmp_libs " $deplib" ;;
    	    esac
    	  done
    	  eval $var=\"$tmp_libs\"
    	done # for var
          fi
    
          # Add Sun CC postdeps if required:
          test CXX = "$tagname" && {
            case $host_os in
            linux*)
              case `$CC -V 2>&1 | $SED 5q` in
              *Sun\ C*) # Sun C++ 5.9
                func_suncc_cstd_abi
    
                if test no != "$suncc_use_cstd_abi"; then
                  func_append postdeps ' -library=Cstd -library=Crun'
                fi
                ;;
              esac
              ;;
    
            solaris*)
              func_cc_basename "$CC"
              case $func_cc_basename_result in
              CC* | sunCC*)
                func_suncc_cstd_abi
    
                if test no != "$suncc_use_cstd_abi"; then
                  func_append postdeps ' -library=Cstd -library=Crun'
                fi
                ;;
              esac
              ;;
            esac
          }
    
          # Last step: remove runtime libs from dependency_libs
          # (they stay in deplibs)
          tmp_libs=
          for i in $dependency_libs; do
    	case " $predeps $postdeps $compiler_lib_search_path " in
    	*" $i "*)
    	  i=
    	  ;;
    	esac
    	if test -n "$i"; then
    	  func_append tmp_libs " $i"
    	fi
          done
          dependency_libs=$tmp_libs
        done # for pass
        if test prog = "$linkmode"; then
          dlfiles=$newdlfiles
        fi
        if test prog = "$linkmode" || test lib = "$linkmode"; then
          dlprefiles=$newdlprefiles
        fi
    
        case $linkmode in
        oldlib)
          if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
    	func_warning "'-dlopen' is ignored for archives"
          fi
    
          case " $deplibs" in
          *\ -l* | *\ -L*)
    	func_warning "'-l' and '-L' are ignored for archives" ;;
          esac
    
          test -n "$rpath" && \
    	func_warning "'-rpath' is ignored for archives"
    
          test -n "$xrpath" && \
    	func_warning "'-R' is ignored for archives"
    
          test -n "$vinfo" && \
    	func_warning "'-version-info/-version-number' is ignored for archives"
    
          test -n "$release" && \
    	func_warning "'-release' is ignored for archives"
    
          test -n "$export_symbols$export_symbols_regex" && \
    	func_warning "'-export-symbols' is ignored for archives"
    
          # Now set the variables for building old libraries.
          build_libtool_libs=no
          oldlibs=$output
          func_append objs "$old_deplibs"
          ;;
    
        lib)
          # Make sure we only generate libraries of the form 'libNAME.la'.
          case $outputname in
          lib*)
    	func_stripname 'lib' '.la' "$outputname"
    	name=$func_stripname_result
    	eval shared_ext=\"$shrext_cmds\"
    	eval libname=\"$libname_spec\"
    	;;
          *)
    	test no = "$module" \
    	  && func_fatal_help "libtool library '$output' must begin with 'lib'"
    
    	if test no != "$need_lib_prefix"; then
    	  # Add the "lib" prefix for modules if required
    	  func_stripname '' '.la' "$outputname"
    	  name=$func_stripname_result
    	  eval shared_ext=\"$shrext_cmds\"
    	  eval libname=\"$libname_spec\"
    	else
    	  func_stripname '' '.la' "$outputname"
    	  libname=$func_stripname_result
    	fi
    	;;
          esac
    
          if test -n "$objs"; then
    	if test pass_all != "$deplibs_check_method"; then
    	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
    	else
    	  echo
    	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
    	  $ECHO "*** objects $objs is not portable!"
    	  func_append libobjs " $objs"
    	fi
          fi
    
          test no = "$dlself" \
    	|| func_warning "'-dlopen self' is ignored for libtool libraries"
    
          set dummy $rpath
          shift
          test 1 -lt "$#" \
    	&& func_warning "ignoring multiple '-rpath's for a libtool library"
    
          install_libdir=$1
    
          oldlibs=
          if test -z "$rpath"; then
    	if test yes = "$build_libtool_libs"; then
    	  # Building a libtool convenience library.
    	  # Some compilers have problems with a '.al' extension so
    	  # convenience libraries should have the same extension an
    	  # archive normally would.
    	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
    	  build_libtool_libs=convenience
    	  build_old_libs=yes
    	fi
    
    	test -n "$vinfo" && \
    	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"
    
    	test -n "$release" && \
    	  func_warning "'-release' is ignored for convenience libraries"
          else
    
    	# Parse the version information argument.
    	save_ifs=$IFS; IFS=:
    	set dummy $vinfo 0 0 0
    	shift
    	IFS=$save_ifs
    
    	test -n "$7" && \
    	  func_fatal_help "too many parameters to '-version-info'"
    
    	# convert absolute version numbers to libtool ages
    	# this retains compatibility with .la files and attempts
    	# to make the code below a bit more comprehensible
    
    	case $vinfo_number in
    	yes)
    	  number_major=$1
    	  number_minor=$2
    	  number_revision=$3
    	  #
    	  # There are really only two kinds -- those that
    	  # use the current revision as the major version
    	  # and those that subtract age and use age as
    	  # a minor version.  But, then there is irix
    	  # that has an extra 1 added just for fun
    	  #
    	  case $version_type in
    	  # correct linux to gnu/linux during the next big refactor
    	  darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none)
    	    func_arith $number_major + $number_minor
    	    current=$func_arith_result
    	    age=$number_minor
    	    revision=$number_revision
    	    ;;
    	  freebsd-aout|qnx|sunos)
    	    current=$number_major
    	    revision=$number_minor
    	    age=0
    	    ;;
    	  irix|nonstopux)
    	    func_arith $number_major + $number_minor
    	    current=$func_arith_result
    	    age=$number_minor
    	    revision=$number_minor
    	    lt_irix_increment=no
    	    ;;
    	  *)
    	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
    	    ;;
    	  esac
    	  ;;
    	no)
    	  current=$1
    	  revision=$2
    	  age=$3
    	  ;;
    	esac
    
    	# Check that each of the things are valid numbers.
    	case $current in
    	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
    	*)
    	  func_error "CURRENT '$current' must be a nonnegative integer"
    	  func_fatal_error "'$vinfo' is not valid version information"
    	  ;;
    	esac
    
    	case $revision in
    	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
    	*)
    	  func_error "REVISION '$revision' must be a nonnegative integer"
    	  func_fatal_error "'$vinfo' is not valid version information"
    	  ;;
    	esac
    
    	case $age in
    	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
    	*)
    	  func_error "AGE '$age' must be a nonnegative integer"
    	  func_fatal_error "'$vinfo' is not valid version information"
    	  ;;
    	esac
    
    	if test "$age" -gt "$current"; then
    	  func_error "AGE '$age' is greater than the current interface number '$current'"
    	  func_fatal_error "'$vinfo' is not valid version information"
    	fi
    
    	# Calculate the version variables.
    	major=
    	versuffix=
    	verstring=
    	case $version_type in
    	none) ;;
    
    	darwin)
    	  # Like Linux, but with the current version available in
    	  # verstring for coding it into the library header
    	  func_arith $current - $age
    	  major=.$func_arith_result
    	  versuffix=$major.$age.$revision
    	  # Darwin ld doesn't like 0 for these options...
    	  func_arith $current + 1
    	  minor_current=$func_arith_result
    	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
    	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
              # On Darwin other compilers
              case $CC in
                  nagfor*)
                      verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
                      ;;
                  *)
                      verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
                      ;;
              esac
    	  ;;
    
    	freebsd-aout)
    	  major=.$current
    	  versuffix=.$current.$revision
    	  ;;
    
    	freebsd-elf | midnightbsd-elf)
    	  func_arith $current - $age
    	  major=.$func_arith_result
    	  versuffix=$major.$age.$revision
    	  ;;
    
    	irix | nonstopux)
    	  if test no = "$lt_irix_increment"; then
    	    func_arith $current - $age
    	  else
    	    func_arith $current - $age + 1
    	  fi
    	  major=$func_arith_result
    
    	  case $version_type in
    	    nonstopux) verstring_prefix=nonstopux ;;
    	    *)         verstring_prefix=sgi ;;
    	  esac
    	  verstring=$verstring_prefix$major.$revision
    
    	  # Add in all the interfaces that we are compatible with.
    	  loop=$revision
    	  while test 0 -ne "$loop"; do
    	    func_arith $revision - $loop
    	    iface=$func_arith_result
    	    func_arith $loop - 1
    	    loop=$func_arith_result
    	    verstring=$verstring_prefix$major.$iface:$verstring
    	  done
    
    	  # Before this point, $major must not contain '.'.
    	  major=.$major
    	  versuffix=$major.$revision
    	  ;;
    
    	linux) # correct to gnu/linux during the next big refactor
    	  func_arith $current - $age
    	  major=.$func_arith_result
    	  versuffix=$major.$age.$revision
    	  ;;
    
    	osf)
    	  func_arith $current - $age
    	  major=.$func_arith_result
    	  versuffix=.$current.$age.$revision
    	  verstring=$current.$age.$revision
    
    	  # Add in all the interfaces that we are compatible with.
    	  loop=$age
    	  while test 0 -ne "$loop"; do
    	    func_arith $current - $loop
    	    iface=$func_arith_result
    	    func_arith $loop - 1
    	    loop=$func_arith_result
    	    verstring=$verstring:$iface.0
    	  done
    
    	  # Make executables depend on our current version.
    	  func_append verstring ":$current.0"
    	  ;;
    
    	qnx)
    	  major=.$current
    	  versuffix=.$current
    	  ;;
    
    	sco)
    	  major=.$current
    	  versuffix=.$current
    	  ;;
    
    	sunos)
    	  major=.$current
    	  versuffix=.$current.$revision
    	  ;;
    
    	windows)
    	  # Use '-' rather than '.', since we only want one
    	  # extension on DOS 8.3 file systems.
    	  func_arith $current - $age
    	  major=$func_arith_result
    	  versuffix=-$major
    	  ;;
    
    	*)
    	  func_fatal_configuration "unknown library version type '$version_type'"
    	  ;;
    	esac
    
    	# Clear the version info if we defaulted, and they specified a release.
    	if test -z "$vinfo" && test -n "$release"; then
    	  major=
    	  case $version_type in
    	  darwin)
    	    # we can't check for "0.0" in archive_cmds due to quoting
    	    # problems, so we reset it completely
    	    verstring=
    	    ;;
    	  *)
    	    verstring=0.0
    	    ;;
    	  esac
    	  if test no = "$need_version"; then
    	    versuffix=
    	  else
    	    versuffix=.0.0
    	  fi
    	fi
    
    	# Remove version info from name if versioning should be avoided
    	if test yes,no = "$avoid_version,$need_version"; then
    	  major=
    	  versuffix=
    	  verstring=
    	fi
    
    	# Check to see if the archive will have undefined symbols.
    	if test yes = "$allow_undefined"; then
    	  if test unsupported = "$allow_undefined_flag"; then
    	    if test yes = "$build_old_libs"; then
    	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"
    	      build_libtool_libs=no
    	    else
    	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"
    	    fi
    	  fi
    	else
    	  # Don't allow undefined symbols.
    	  allow_undefined_flag=$no_undefined_flag
    	fi
    
          fi
    
          func_generate_dlsyms "$libname" "$libname" :
          func_append libobjs " $symfileobj"
          test " " = "$libobjs" && libobjs=
    
          if test relink != "$opt_mode"; then
    	# Remove our outputs, but don't remove object files since they
    	# may have been created when compiling PIC objects.
    	removelist=
    	tempremovelist=`$ECHO "$output_objdir/*"`
    	for p in $tempremovelist; do
    	  case $p in
    	    *.$objext | *.gcno)
    	       ;;
    	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
    	       if test -n "$precious_files_regex"; then
    		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
    		 then
    		   continue
    		 fi
    	       fi
    	       func_append removelist " $p"
    	       ;;
    	    *) ;;
    	  esac
    	done
    	test -n "$removelist" && \
    	  func_show_eval "${RM}r \$removelist"
          fi
    
          # Now set the variables for building old libraries.
          if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
    	func_append oldlibs " $output_objdir/$libname.$libext"
    
    	# Transform .lo files to .o files.
    	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
          fi
    
          # Eliminate all temporary directories.
          #for path in $notinst_path; do
          #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
          #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
          #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
          #done
    
          if test -n "$xrpath"; then
    	# If the user specified any rpath flags, then add them.
    	temp_xrpath=
    	for libdir in $xrpath; do
    	  func_replace_sysroot "$libdir"
    	  func_append temp_xrpath " -R$func_replace_sysroot_result"
    	  case "$finalize_rpath " in
    	  *" $libdir "*) ;;
    	  *) func_append finalize_rpath " $libdir" ;;
    	  esac
    	done
    	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
    	  dependency_libs="$temp_xrpath $dependency_libs"
    	fi
          fi
    
          # Make sure dlfiles contains only unique files that won't be dlpreopened
          old_dlfiles=$dlfiles
          dlfiles=
          for lib in $old_dlfiles; do
    	case " $dlprefiles $dlfiles " in
    	*" $lib "*) ;;
    	*) func_append dlfiles " $lib" ;;
    	esac
          done
    
          # Make sure dlprefiles contains only unique files
          old_dlprefiles=$dlprefiles
          dlprefiles=
          for lib in $old_dlprefiles; do
    	case "$dlprefiles " in
    	*" $lib "*) ;;
    	*) func_append dlprefiles " $lib" ;;
    	esac
          done
    
          if test yes = "$build_libtool_libs"; then
    	if test -n "$rpath"; then
    	  case $host in
    	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
    	    # these systems don't actually have a c library (as such)!
    	    ;;
    	  *-*-rhapsody* | *-*-darwin1.[012])
    	    # Rhapsody C library is in the System framework
    	    func_append deplibs " System.ltframework"
    	    ;;
    	  *-*-netbsd*)
    	    # Don't link with libc until the a.out ld.so is fixed.
    	    ;;
    	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)
    	    # Do not include libc due to us having libc/libc_r.
    	    ;;
    	  *-*-sco3.2v5* | *-*-sco5v6*)
    	    # Causes problems with __ctype
    	    ;;
    	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
    	    # Compiler inserts libc in the correct place for threads to work
    	    ;;
    	  *)
    	    # Add libc to deplibs on all other systems if necessary.
    	    if test yes = "$build_libtool_need_lc"; then
    	      func_append deplibs " -lc"
    	    fi
    	    ;;
    	  esac
    	fi
    
    	# Transform deplibs into only deplibs that can be linked in shared.
    	name_save=$name
    	libname_save=$libname
    	release_save=$release
    	versuffix_save=$versuffix
    	major_save=$major
    	# I'm not sure if I'm treating the release correctly.  I think
    	# release should show up in the -l (ie -lgmp5) so we don't want to
    	# add it in twice.  Is that correct?
    	release=
    	versuffix=
    	major=
    	newdeplibs=
    	droppeddeps=no
    	case $deplibs_check_method in
    	pass_all)
    	  # Don't check for shared/static.  Everything works.
    	  # This might be a little naive.  We might want to check
    	  # whether the library exists or not.  But this is on
    	  # osf3 & osf4 and I'm not really sure... Just
    	  # implementing what was already the behavior.
    	  newdeplibs=$deplibs
    	  ;;
    	test_compile)
    	  # This code stresses the "libraries are programs" paradigm to its
    	  # limits. Maybe even breaks it.  We compile a program, linking it
    	  # against the deplibs as a proxy for the library.  Then we can check
    	  # whether they linked in statically or dynamically with ldd.
    	  $opt_dry_run || $RM conftest.c
    	  cat > conftest.c <<EOF
    	  int main() { return 0; }
    EOF
    	  $opt_dry_run || $RM conftest
    	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
    	    ldd_output=`ldd conftest`
    	    for i in $deplibs; do
    	      case $i in
    	      -l*)
    		func_stripname -l '' "$i"
    		name=$func_stripname_result
    		if test yes = "$allow_libtool_libs_with_static_runtimes"; then
    		  case " $predeps $postdeps " in
    		  *" $i "*)
    		    func_append newdeplibs " $i"
    		    i=
    		    ;;
    		  esac
    		fi
    		if test -n "$i"; then
    		  libname=`eval "\\$ECHO \"$libname_spec\""`
    		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
    		  set dummy $deplib_matches; shift
    		  deplib_match=$1
    		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
    		    func_append newdeplibs " $i"
    		  else
    		    droppeddeps=yes
    		    echo
    		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
    		    echo "*** I have the capability to make that library automatically link in when"
    		    echo "*** you link to this library.  But I can only do this if you have a"
    		    echo "*** shared version of the library, which I believe you do not have"
    		    echo "*** because a test_compile did reveal that the linker did not use it for"
    		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
    		  fi
    		fi
    		;;
    	      *)
    		func_append newdeplibs " $i"
    		;;
    	      esac
    	    done
    	  else
    	    # Error occurred in the first compile.  Let's try to salvage
    	    # the situation: Compile a separate program for each library.
    	    for i in $deplibs; do
    	      case $i in
    	      -l*)
    		func_stripname -l '' "$i"
    		name=$func_stripname_result
    		$opt_dry_run || $RM conftest
    		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
    		  ldd_output=`ldd conftest`
    		  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
    		    case " $predeps $postdeps " in
    		    *" $i "*)
    		      func_append newdeplibs " $i"
    		      i=
    		      ;;
    		    esac
    		  fi
    		  if test -n "$i"; then
    		    libname=`eval "\\$ECHO \"$libname_spec\""`
    		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
    		    set dummy $deplib_matches; shift
    		    deplib_match=$1
    		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
    		      func_append newdeplibs " $i"
    		    else
    		      droppeddeps=yes
    		      echo
    		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
    		      echo "*** I have the capability to make that library automatically link in when"
    		      echo "*** you link to this library.  But I can only do this if you have a"
    		      echo "*** shared version of the library, which you do not appear to have"
    		      echo "*** because a test_compile did reveal that the linker did not use this one"
    		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
    		    fi
    		  fi
    		else
    		  droppeddeps=yes
    		  echo
    		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
    		  echo "*** make it link in!  You will probably need to install it or some"
    		  echo "*** library that it depends on before this library will be fully"
    		  echo "*** functional.  Installing it before continuing would be even better."
    		fi
    		;;
    	      *)
    		func_append newdeplibs " $i"
    		;;
    	      esac
    	    done
    	  fi
    	  ;;
    	file_magic*)
    	  set dummy $deplibs_check_method; shift
    	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
    	  for a_deplib in $deplibs; do
    	    case $a_deplib in
    	    -l*)
    	      func_stripname -l '' "$a_deplib"
    	      name=$func_stripname_result
    	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
    		case " $predeps $postdeps " in
    		*" $a_deplib "*)
    		  func_append newdeplibs " $a_deplib"
    		  a_deplib=
    		  ;;
    		esac
    	      fi
    	      if test -n "$a_deplib"; then
    		libname=`eval "\\$ECHO \"$libname_spec\""`
    		if test -n "$file_magic_glob"; then
    		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
    		else
    		  libnameglob=$libname
    		fi
    		test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
    		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
    		  if test yes = "$want_nocaseglob"; then
    		    shopt -s nocaseglob
    		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
    		    $nocaseglob
    		  else
    		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
    		  fi
    		  for potent_lib in $potential_libs; do
    		      # Follow soft links.
    		      if ls -lLd "$potent_lib" 2>/dev/null |
    			 $GREP " -> " >/dev/null; then
    			continue
    		      fi
    		      # The statement above tries to avoid entering an
    		      # endless loop below, in case of cyclic links.
    		      # We might still enter an endless loop, since a link
    		      # loop can be closed while we follow links,
    		      # but so what?
    		      potlib=$potent_lib
    		      while test -h "$potlib" 2>/dev/null; do
    			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
    			case $potliblink in
    			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
    			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
    			esac
    		      done
    		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
    			 $SED -e 10q |
    			 $EGREP "$file_magic_regex" > /dev/null; then
    			func_append newdeplibs " $a_deplib"
    			a_deplib=
    			break 2
    		      fi
    		  done
    		done
    	      fi
    	      if test -n "$a_deplib"; then
    		droppeddeps=yes
    		echo
    		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
    		echo "*** I have the capability to make that library automatically link in when"
    		echo "*** you link to this library.  But I can only do this if you have a"
    		echo "*** shared version of the library, which you do not appear to have"
    		echo "*** because I did check the linker path looking for a file starting"
    		if test -z "$potlib"; then
    		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
    		else
    		  $ECHO "*** with $libname and none of the candidates passed a file format test"
    		  $ECHO "*** using a file magic. Last file checked: $potlib"
    		fi
    	      fi
    	      ;;
    	    *)
    	      # Add a -L argument.
    	      func_append newdeplibs " $a_deplib"
    	      ;;
    	    esac
    	  done # Gone through all deplibs.
    	  ;;
    	match_pattern*)
    	  set dummy $deplibs_check_method; shift
    	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
    	  for a_deplib in $deplibs; do
    	    case $a_deplib in
    	    -l*)
    	      func_stripname -l '' "$a_deplib"
    	      name=$func_stripname_result
    	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
    		case " $predeps $postdeps " in
    		*" $a_deplib "*)
    		  func_append newdeplibs " $a_deplib"
    		  a_deplib=
    		  ;;
    		esac
    	      fi
    	      if test -n "$a_deplib"; then
    		libname=`eval "\\$ECHO \"$libname_spec\""`
    		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
    		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
    		  for potent_lib in $potential_libs; do
    		    potlib=$potent_lib # see symlink-check above in file_magic test
    		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
    		       $EGREP "$match_pattern_regex" > /dev/null; then
    		      func_append newdeplibs " $a_deplib"
    		      a_deplib=
    		      break 2
    		    fi
    		  done
    		done
    	      fi
    	      if test -n "$a_deplib"; then
    		droppeddeps=yes
    		echo
    		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
    		echo "*** I have the capability to make that library automatically link in when"
    		echo "*** you link to this library.  But I can only do this if you have a"
    		echo "*** shared version of the library, which you do not appear to have"
    		echo "*** because I did check the linker path looking for a file starting"
    		if test -z "$potlib"; then
    		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
    		else
    		  $ECHO "*** with $libname and none of the candidates passed a file format test"
    		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
    		fi
    	      fi
    	      ;;
    	    *)
    	      # Add a -L argument.
    	      func_append newdeplibs " $a_deplib"
    	      ;;
    	    esac
    	  done # Gone through all deplibs.
    	  ;;
    	none | unknown | *)
    	  newdeplibs=
    	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
    	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
    	    for i in $predeps $postdeps; do
    	      # can't use Xsed below, because $i might contain '/'
    	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
    	    done
    	  fi
    	  case $tmp_deplibs in
    	  *[!\	\ ]*)
    	    echo
    	    if test none = "$deplibs_check_method"; then
    	      echo "*** Warning: inter-library dependencies are not supported in this platform."
    	    else
    	      echo "*** Warning: inter-library dependencies are not known to be supported."
    	    fi
    	    echo "*** All declared inter-library dependencies are being dropped."
    	    droppeddeps=yes
    	    ;;
    	  esac
    	  ;;
    	esac
    	versuffix=$versuffix_save
    	major=$major_save
    	release=$release_save
    	libname=$libname_save
    	name=$name_save
    
    	case $host in
    	*-*-rhapsody* | *-*-darwin1.[012])
    	  # On Rhapsody replace the C library with the System framework
    	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
    	  ;;
    	esac
    
    	if test yes = "$droppeddeps"; then
    	  if test yes = "$module"; then
    	    echo
    	    echo "*** Warning: libtool could not satisfy all declared inter-library"
    	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
    	    echo "*** a static module, that should work as long as the dlopening"
    	    echo "*** application is linked with the -dlopen flag."
    	    if test -z "$global_symbol_pipe"; then
    	      echo
    	      echo "*** However, this would only work if libtool was able to extract symbol"
    	      echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
    	      echo "*** not find such a program.  So, this module is probably useless."
    	      echo "*** 'nm' from GNU binutils and a full rebuild may help."
    	    fi
    	    if test no = "$build_old_libs"; then
    	      oldlibs=$output_objdir/$libname.$libext
    	      build_libtool_libs=module
    	      build_old_libs=yes
    	    else
    	      build_libtool_libs=no
    	    fi
    	  else
    	    echo "*** The inter-library dependencies that have been dropped here will be"
    	    echo "*** automatically added whenever a program is linked with this library"
    	    echo "*** or is declared to -dlopen it."
    
    	    if test no = "$allow_undefined"; then
    	      echo
    	      echo "*** Since this library must not contain undefined symbols,"
    	      echo "*** because either the platform does not support them or"
    	      echo "*** it was explicitly requested with -no-undefined,"
    	      echo "*** libtool will only create a static version of it."
    	      if test no = "$build_old_libs"; then
    		oldlibs=$output_objdir/$libname.$libext
    		build_libtool_libs=module
    		build_old_libs=yes
    	      else
    		build_libtool_libs=no
    	      fi
    	    fi
    	  fi
    	fi
    	# Done checking deplibs!
    	deplibs=$newdeplibs
          fi
          # Time to change all our "foo.ltframework" stuff back to "-framework foo"
          case $host in
    	*-*-darwin*)
    	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
    	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
    	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
    	  ;;
          esac
    
          # move library search paths that coincide with paths to not yet
          # installed libraries to the beginning of the library search list
          new_libs=
          for path in $notinst_path; do
    	case " $new_libs " in
    	*" -L$path/$objdir "*) ;;
    	*)
    	  case " $deplibs " in
    	  *" -L$path/$objdir "*)
    	    func_append new_libs " -L$path/$objdir" ;;
    	  esac
    	  ;;
    	esac
          done
          for deplib in $deplibs; do
    	case $deplib in
    	-L*)
    	  case " $new_libs " in
    	  *" $deplib "*) ;;
    	  *) func_append new_libs " $deplib" ;;
    	  esac
    	  ;;
    	*) func_append new_libs " $deplib" ;;
    	esac
          done
          deplibs=$new_libs
    
          # All the library-specific variables (install_libdir is set above).
          library_names=
          old_library=
          dlname=
    
          # Test again, we may have decided not to build it any more
          if test yes = "$build_libtool_libs"; then
    	# Remove $wl instances when linking with ld.
    	# FIXME: should test the right _cmds variable.
    	case $archive_cmds in
    	  *\$LD\ *) wl= ;;
            esac
    	if test yes = "$hardcode_into_libs"; then
    	  # Hardcode the library paths
    	  hardcode_libdirs=
    	  dep_rpath=
    	  rpath=$finalize_rpath
    	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath
    	  for libdir in $rpath; do
    	    if test -n "$hardcode_libdir_flag_spec"; then
    	      if test -n "$hardcode_libdir_separator"; then
    		func_replace_sysroot "$libdir"
    		libdir=$func_replace_sysroot_result
    		if test -z "$hardcode_libdirs"; then
    		  hardcode_libdirs=$libdir
    		else
    		  # Just accumulate the unique libdirs.
    		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
    		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
    		    ;;
    		  *)
    		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
    		    ;;
    		  esac
    		fi
    	      else
    		eval flag=\"$hardcode_libdir_flag_spec\"
    		func_append dep_rpath " $flag"
    	      fi
    	    elif test -n "$runpath_var"; then
    	      case "$perm_rpath " in
    	      *" $libdir "*) ;;
    	      *) func_append perm_rpath " $libdir" ;;
    	      esac
    	    fi
    	  done
    	  # Substitute the hardcoded libdirs into the rpath.
    	  if test -n "$hardcode_libdir_separator" &&
    	     test -n "$hardcode_libdirs"; then
    	    libdir=$hardcode_libdirs
    	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
    	  fi
    	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
    	    # We should set the runpath_var.
    	    rpath=
    	    for dir in $perm_rpath; do
    	      func_append rpath "$dir:"
    	    done
    	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
    	  fi
    	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
    	fi
    
    	shlibpath=$finalize_shlibpath
    	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
    	if test -n "$shlibpath"; then
    	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
    	fi
    
    	# Get the real and link names of the library.
    	eval shared_ext=\"$shrext_cmds\"
    	eval library_names=\"$library_names_spec\"
    	set dummy $library_names
    	shift
    	realname=$1
    	shift
    
    	if test -n "$soname_spec"; then
    	  eval soname=\"$soname_spec\"
    	else
    	  soname=$realname
    	fi
    	if test -z "$dlname"; then
    	  dlname=$soname
    	fi
    
    	lib=$output_objdir/$realname
    	linknames=
    	for link
    	do
    	  func_append linknames " $link"
    	done
    
    	# Use standard objects if they are pic
    	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
    	test "X$libobjs" = "X " && libobjs=
    
    	delfiles=
    	if test -n "$export_symbols" && test -n "$include_expsyms"; then
    	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
    	  export_symbols=$output_objdir/$libname.uexp
    	  func_append delfiles " $export_symbols"
    	fi
    
    	orig_export_symbols=
    	case $host_os in
    	cygwin* | mingw* | cegcc*)
    	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
    	    # exporting using user supplied symfile
    	    func_dll_def_p "$export_symbols" || {
    	      # and it's NOT already a .def file. Must figure out
    	      # which of the given symbols are data symbols and tag
    	      # them as such. So, trigger use of export_symbols_cmds.
    	      # export_symbols gets reassigned inside the "prepare
    	      # the list of exported symbols" if statement, so the
    	      # include_expsyms logic still works.
    	      orig_export_symbols=$export_symbols
    	      export_symbols=
    	      always_export_symbols=yes
    	    }
    	  fi
    	  ;;
    	esac
    
    	# Prepare the list of exported symbols
    	if test -z "$export_symbols"; then
    	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
    	    func_verbose "generating symbol list for '$libname.la'"
    	    export_symbols=$output_objdir/$libname.exp
    	    $opt_dry_run || $RM $export_symbols
    	    cmds=$export_symbols_cmds
    	    save_ifs=$IFS; IFS='~'
    	    for cmd1 in $cmds; do
    	      IFS=$save_ifs
    	      # Take the normal branch if the nm_file_list_spec branch
    	      # doesn't work or if tool conversion is not needed.
    	      case $nm_file_list_spec~$to_tool_file_cmd in
    		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
    		  try_normal_branch=yes
    		  eval cmd=\"$cmd1\"
    		  func_len " $cmd"
    		  len=$func_len_result
    		  ;;
    		*)
    		  try_normal_branch=no
    		  ;;
    	      esac
    	      if test yes = "$try_normal_branch" \
    		 && { test "$len" -lt "$max_cmd_len" \
    		      || test "$max_cmd_len" -le -1; }
    	      then
    		func_show_eval "$cmd" 'exit $?'
    		skipped_export=false
    	      elif test -n "$nm_file_list_spec"; then
    		func_basename "$output"
    		output_la=$func_basename_result
    		save_libobjs=$libobjs
    		save_output=$output
    		output=$output_objdir/$output_la.nm
    		func_to_tool_file "$output"
    		libobjs=$nm_file_list_spec$func_to_tool_file_result
    		func_append delfiles " $output"
    		func_verbose "creating $NM input file list: $output"
    		for obj in $save_libobjs; do
    		  func_to_tool_file "$obj"
    		  $ECHO "$func_to_tool_file_result"
    		done > "$output"
    		eval cmd=\"$cmd1\"
    		func_show_eval "$cmd" 'exit $?'
    		output=$save_output
    		libobjs=$save_libobjs
    		skipped_export=false
    	      else
    		# The command line is too long to execute in one step.
    		func_verbose "using reloadable object file for export list..."
    		skipped_export=:
    		# Break out early, otherwise skipped_export may be
    		# set to false by a later but shorter cmd.
    		break
    	      fi
    	    done
    	    IFS=$save_ifs
    	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
    	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
    	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
    	    fi
    	  fi
    	fi
    
    	if test -n "$export_symbols" && test -n "$include_expsyms"; then
    	  tmp_export_symbols=$export_symbols
    	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
    	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
    	fi
    
    	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
    	  # The given exports_symbols file has to be filtered, so filter it.
    	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
    	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
    	  # 's' commands, which not all seds can handle. GNU sed should be fine
    	  # though. Also, the filter scales superlinearly with the number of
    	  # global variables. join(1) would be nice here, but unfortunately
    	  # isn't a blessed tool.
    	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
    	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
    	  export_symbols=$output_objdir/$libname.def
    	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
    	fi
    
    	tmp_deplibs=
    	for test_deplib in $deplibs; do
    	  case " $convenience " in
    	  *" $test_deplib "*) ;;
    	  *)
    	    func_append tmp_deplibs " $test_deplib"
    	    ;;
    	  esac
    	done
    	deplibs=$tmp_deplibs
    
    	if test -n "$convenience"; then
    	  if test -n "$whole_archive_flag_spec" &&
    	    test yes = "$compiler_needs_object" &&
    	    test -z "$libobjs"; then
    	    # extract the archives, so we have objects to list.
    	    # TODO: could optimize this to just extract one archive.
    	    whole_archive_flag_spec=
    	  fi
    	  if test -n "$whole_archive_flag_spec"; then
    	    save_libobjs=$libobjs
    	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
    	    test "X$libobjs" = "X " && libobjs=
    	  else
    	    gentop=$output_objdir/${outputname}x
    	    func_append generated " $gentop"
    
    	    func_extract_archives $gentop $convenience
    	    func_append libobjs " $func_extract_archives_result"
    	    test "X$libobjs" = "X " && libobjs=
    	  fi
    	fi
    
    	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
    	  eval flag=\"$thread_safe_flag_spec\"
    	  func_append linker_flags " $flag"
    	fi
    
    	# Make a backup of the uninstalled library when relinking
    	if test relink = "$opt_mode"; then
    	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
    	fi
    
    	# Do each of the archive commands.
    	if test yes = "$module" && test -n "$module_cmds"; then
    	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
    	    eval test_cmds=\"$module_expsym_cmds\"
    	    cmds=$module_expsym_cmds
    	  else
    	    eval test_cmds=\"$module_cmds\"
    	    cmds=$module_cmds
    	  fi
    	else
    	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
    	    eval test_cmds=\"$archive_expsym_cmds\"
    	    cmds=$archive_expsym_cmds
    	  else
    	    eval test_cmds=\"$archive_cmds\"
    	    cmds=$archive_cmds
    	  fi
    	fi
    
    	if test : != "$skipped_export" &&
    	   func_len " $test_cmds" &&
    	   len=$func_len_result &&
    	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
    	  :
    	else
    	  # The command line is too long to link in one step, link piecewise
    	  # or, if using GNU ld and skipped_export is not :, use a linker
    	  # script.
    
    	  # Save the value of $output and $libobjs because we want to
    	  # use them later.  If we have whole_archive_flag_spec, we
    	  # want to use save_libobjs as it was before
    	  # whole_archive_flag_spec was expanded, because we can't
    	  # assume the linker understands whole_archive_flag_spec.
    	  # This may have to be revisited, in case too many
    	  # convenience libraries get linked in and end up exceeding
    	  # the spec.
    	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
    	    save_libobjs=$libobjs
    	  fi
    	  save_output=$output
    	  func_basename "$output"
    	  output_la=$func_basename_result
    
    	  # Clear the reloadable object creation command queue and
    	  # initialize k to one.
    	  test_cmds=
    	  concat_cmds=
    	  objlist=
    	  last_robj=
    	  k=1
    
    	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
    	    output=$output_objdir/$output_la.lnkscript
    	    func_verbose "creating GNU ld script: $output"
    	    echo 'INPUT (' > $output
    	    for obj in $save_libobjs
    	    do
    	      func_to_tool_file "$obj"
    	      $ECHO "$func_to_tool_file_result" >> $output
    	    done
    	    echo ')' >> $output
    	    func_append delfiles " $output"
    	    func_to_tool_file "$output"
    	    output=$func_to_tool_file_result
    	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
    	    output=$output_objdir/$output_la.lnk
    	    func_verbose "creating linker input file list: $output"
    	    : > $output
    	    set x $save_libobjs
    	    shift
    	    firstobj=
    	    if test yes = "$compiler_needs_object"; then
    	      firstobj="$1 "
    	      shift
    	    fi
    	    for obj
    	    do
    	      func_to_tool_file "$obj"
    	      $ECHO "$func_to_tool_file_result" >> $output
    	    done
    	    func_append delfiles " $output"
    	    func_to_tool_file "$output"
    	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
    	  else
    	    if test -n "$save_libobjs"; then
    	      func_verbose "creating reloadable object files..."
    	      output=$output_objdir/$output_la-$k.$objext
    	      eval test_cmds=\"$reload_cmds\"
    	      func_len " $test_cmds"
    	      len0=$func_len_result
    	      len=$len0
    
    	      # Loop over the list of objects to be linked.
    	      for obj in $save_libobjs
    	      do
    		func_len " $obj"
    		func_arith $len + $func_len_result
    		len=$func_arith_result
    		if test -z "$objlist" ||
    		   test "$len" -lt "$max_cmd_len"; then
    		  func_append objlist " $obj"
    		else
    		  # The command $test_cmds is almost too long, add a
    		  # command to the queue.
    		  if test 1 -eq "$k"; then
    		    # The first file doesn't have a previous command to add.
    		    reload_objs=$objlist
    		    eval concat_cmds=\"$reload_cmds\"
    		  else
    		    # All subsequent reloadable object files will link in
    		    # the last one created.
    		    reload_objs="$objlist $last_robj"
    		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
    		  fi
    		  last_robj=$output_objdir/$output_la-$k.$objext
    		  func_arith $k + 1
    		  k=$func_arith_result
    		  output=$output_objdir/$output_la-$k.$objext
    		  objlist=" $obj"
    		  func_len " $last_robj"
    		  func_arith $len0 + $func_len_result
    		  len=$func_arith_result
    		fi
    	      done
    	      # Handle the remaining objects by creating one last
    	      # reloadable object file.  All subsequent reloadable object
    	      # files will link in the last one created.
    	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
    	      reload_objs="$objlist $last_robj"
    	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"
    	      if test -n "$last_robj"; then
    	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
    	      fi
    	      func_append delfiles " $output"
    
    	    else
    	      output=
    	    fi
    
    	    ${skipped_export-false} && {
    	      func_verbose "generating symbol list for '$libname.la'"
    	      export_symbols=$output_objdir/$libname.exp
    	      $opt_dry_run || $RM $export_symbols
    	      libobjs=$output
    	      # Append the command to create the export file.
    	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
    	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
    	      if test -n "$last_robj"; then
    		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
    	      fi
    	    }
    
    	    test -n "$save_libobjs" &&
    	      func_verbose "creating a temporary reloadable object file: $output"
    
    	    # Loop through the commands generated above and execute them.
    	    save_ifs=$IFS; IFS='~'
    	    for cmd in $concat_cmds; do
    	      IFS=$save_ifs
    	      $opt_quiet || {
    		  func_quote_arg expand,pretty "$cmd"
    		  eval "func_echo $func_quote_arg_result"
    	      }
    	      $opt_dry_run || eval "$cmd" || {
    		lt_exit=$?
    
    		# Restore the uninstalled library and exit
    		if test relink = "$opt_mode"; then
    		  ( cd "$output_objdir" && \
    		    $RM "${realname}T" && \
    		    $MV "${realname}U" "$realname" )
    		fi
    
    		exit $lt_exit
    	      }
    	    done
    	    IFS=$save_ifs
    
    	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
    	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
    	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
    	    fi
    	  fi
    
              ${skipped_export-false} && {
    	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
    	      tmp_export_symbols=$export_symbols
    	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
    	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
    	    fi
    
    	    if test -n "$orig_export_symbols"; then
    	      # The given exports_symbols file has to be filtered, so filter it.
    	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
    	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
    	      # 's' commands, which not all seds can handle. GNU sed should be fine
    	      # though. Also, the filter scales superlinearly with the number of
    	      # global variables. join(1) would be nice here, but unfortunately
    	      # isn't a blessed tool.
    	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
    	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
    	      export_symbols=$output_objdir/$libname.def
    	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
    	    fi
    	  }
    
    	  libobjs=$output
    	  # Restore the value of output.
    	  output=$save_output
    
    	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
    	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
    	    test "X$libobjs" = "X " && libobjs=
    	  fi
    	  # Expand the library linking commands again to reset the
    	  # value of $libobjs for piecewise linking.
    
    	  # Do each of the archive commands.
    	  if test yes = "$module" && test -n "$module_cmds"; then
    	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
    	      cmds=$module_expsym_cmds
    	    else
    	      cmds=$module_cmds
    	    fi
    	  else
    	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
    	      cmds=$archive_expsym_cmds
    	    else
    	      cmds=$archive_cmds
    	    fi
    	  fi
    	fi
    
    	if test -n "$delfiles"; then
    	  # Append the command to remove temporary files to $cmds.
    	  eval cmds=\"\$cmds~\$RM $delfiles\"
    	fi
    
    	# Add any objects from preloaded convenience libraries
    	if test -n "$dlprefiles"; then
    	  gentop=$output_objdir/${outputname}x
    	  func_append generated " $gentop"
    
    	  func_extract_archives $gentop $dlprefiles
    	  func_append libobjs " $func_extract_archives_result"
    	  test "X$libobjs" = "X " && libobjs=
    	fi
    
    	save_ifs=$IFS; IFS='~'
    	for cmd in $cmds; do
    	  IFS=$sp$nl
    	  eval cmd=\"$cmd\"
    	  IFS=$save_ifs
    	  $opt_quiet || {
    	    func_quote_arg expand,pretty "$cmd"
    	    eval "func_echo $func_quote_arg_result"
    	  }
    	  $opt_dry_run || eval "$cmd" || {
    	    lt_exit=$?
    
    	    # Restore the uninstalled library and exit
    	    if test relink = "$opt_mode"; then
    	      ( cd "$output_objdir" && \
    	        $RM "${realname}T" && \
    		$MV "${realname}U" "$realname" )
    	    fi
    
    	    exit $lt_exit
    	  }
    	done
    	IFS=$save_ifs
    
    	# Restore the uninstalled library and exit
    	if test relink = "$opt_mode"; then
    	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
    
    	  if test -n "$convenience"; then
    	    if test -z "$whole_archive_flag_spec"; then
    	      func_show_eval '${RM}r "$gentop"'
    	    fi
    	  fi
    
    	  exit $EXIT_SUCCESS
    	fi
    
    	# Create links to the real library.
    	for linkname in $linknames; do
    	  if test "$realname" != "$linkname"; then
    	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
    	  fi
    	done
    
    	# If -module or -export-dynamic was specified, set the dlname.
    	if test yes = "$module" || test yes = "$export_dynamic"; then
    	  # On all known operating systems, these are identical.
    	  dlname=$soname
    	fi
          fi
          ;;
    
        obj)
          if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
    	func_warning "'-dlopen' is ignored for objects"
          fi
    
          case " $deplibs" in
          *\ -l* | *\ -L*)
    	func_warning "'-l' and '-L' are ignored for objects" ;;
          esac
    
          test -n "$rpath" && \
    	func_warning "'-rpath' is ignored for objects"
    
          test -n "$xrpath" && \
    	func_warning "'-R' is ignored for objects"
    
          test -n "$vinfo" && \
    	func_warning "'-version-info' is ignored for objects"
    
          test -n "$release" && \
    	func_warning "'-release' is ignored for objects"
    
          case $output in
          *.lo)
    	test -n "$objs$old_deplibs" && \
    	  func_fatal_error "cannot build library object '$output' from non-libtool objects"
    
    	libobj=$output
    	func_lo2o "$libobj"
    	obj=$func_lo2o_result
    	;;
          *)
    	libobj=
    	obj=$output
    	;;
          esac
    
          # Delete the old objects.
          $opt_dry_run || $RM $obj $libobj
    
          # Objects from convenience libraries.  This assumes
          # single-version convenience libraries.  Whenever we create
          # different ones for PIC/non-PIC, this we'll have to duplicate
          # the extraction.
          reload_conv_objs=
          gentop=
          # if reload_cmds runs $LD directly, get rid of -Wl from
          # whole_archive_flag_spec and hope we can get by with turning comma
          # into space.
          case $reload_cmds in
            *\$LD[\ \$]*) wl= ;;
          esac
          if test -n "$convenience"; then
    	if test -n "$whole_archive_flag_spec"; then
    	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
    	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
    	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
    	else
    	  gentop=$output_objdir/${obj}x
    	  func_append generated " $gentop"
    
    	  func_extract_archives $gentop $convenience
    	  reload_conv_objs="$reload_objs $func_extract_archives_result"
    	fi
          fi
    
          # If we're not building shared, we need to use non_pic_objs
          test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
    
          # Create the old-style object.
          reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
    
          output=$obj
          func_execute_cmds "$reload_cmds" 'exit $?'
    
          # Exit if we aren't doing a library object file.
          if test -z "$libobj"; then
    	if test -n "$gentop"; then
    	  func_show_eval '${RM}r "$gentop"'
    	fi
    
    	exit $EXIT_SUCCESS
          fi
    
          test yes = "$build_libtool_libs" || {
    	if test -n "$gentop"; then
    	  func_show_eval '${RM}r "$gentop"'
    	fi
    
    	# Create an invalid libtool object if no PIC, so that we don't
    	# accidentally link it into a program.
    	# $show "echo timestamp > $libobj"
    	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
    	exit $EXIT_SUCCESS
          }
    
          if test -n "$pic_flag" || test default != "$pic_mode"; then
    	# Only do commands if we really have different PIC objects.
    	reload_objs="$libobjs $reload_conv_objs"
    	output=$libobj
    	func_execute_cmds "$reload_cmds" 'exit $?'
          fi
    
          if test -n "$gentop"; then
    	func_show_eval '${RM}r "$gentop"'
          fi
    
          exit $EXIT_SUCCESS
          ;;
    
        prog)
          case $host in
    	*cygwin*) func_stripname '' '.exe' "$output"
    	          output=$func_stripname_result.exe;;
          esac
          test -n "$vinfo" && \
    	func_warning "'-version-info' is ignored for programs"
    
          test -n "$release" && \
    	func_warning "'-release' is ignored for programs"
    
          $preload \
    	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
    	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
    
          case $host in
          *-*-rhapsody* | *-*-darwin1.[012])
    	# On Rhapsody replace the C library is the System framework
    	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
    	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
    	;;
          esac
    
          case $host in
          *-*-darwin*)
    	# Don't allow lazy linking, it breaks C++ global constructors
    	# But is supposedly fixed on 10.4 or later (yay!).
    	if test CXX = "$tagname"; then
    	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
    	    10.[0123])
    	      func_append compile_command " $wl-bind_at_load"
    	      func_append finalize_command " $wl-bind_at_load"
    	    ;;
    	  esac
    	fi
    	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
    	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
    	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
    	;;
          esac
    
    
          # move library search paths that coincide with paths to not yet
          # installed libraries to the beginning of the library search list
          new_libs=
          for path in $notinst_path; do
    	case " $new_libs " in
    	*" -L$path/$objdir "*) ;;
    	*)
    	  case " $compile_deplibs " in
    	  *" -L$path/$objdir "*)
    	    func_append new_libs " -L$path/$objdir" ;;
    	  esac
    	  ;;
    	esac
          done
          for deplib in $compile_deplibs; do
    	case $deplib in
    	-L*)
    	  case " $new_libs " in
    	  *" $deplib "*) ;;
    	  *) func_append new_libs " $deplib" ;;
    	  esac
    	  ;;
    	*) func_append new_libs " $deplib" ;;
    	esac
          done
          compile_deplibs=$new_libs
    
    
          func_append compile_command " $compile_deplibs"
          func_append finalize_command " $finalize_deplibs"
    
          if test -n "$rpath$xrpath"; then
    	# If the user specified any rpath flags, then add them.
    	for libdir in $rpath $xrpath; do
    	  # This is the magic to use -rpath.
    	  case "$finalize_rpath " in
    	  *" $libdir "*) ;;
    	  *) func_append finalize_rpath " $libdir" ;;
    	  esac
    	done
          fi
    
          # Now hardcode the library paths
          rpath=
          hardcode_libdirs=
          for libdir in $compile_rpath $finalize_rpath; do
    	if test -n "$hardcode_libdir_flag_spec"; then
    	  if test -n "$hardcode_libdir_separator"; then
    	    if test -z "$hardcode_libdirs"; then
    	      hardcode_libdirs=$libdir
    	    else
    	      # Just accumulate the unique libdirs.
    	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
    	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
    		;;
    	      *)
    		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
    		;;
    	      esac
    	    fi
    	  else
    	    eval flag=\"$hardcode_libdir_flag_spec\"
    	    func_append rpath " $flag"
    	  fi
    	elif test -n "$runpath_var"; then
    	  case "$perm_rpath " in
    	  *" $libdir "*) ;;
    	  *) func_append perm_rpath " $libdir" ;;
    	  esac
    	fi
    	case $host in
    	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
    	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
    	  case :$dllsearchpath: in
    	  *":$libdir:"*) ;;
    	  ::) dllsearchpath=$libdir;;
    	  *) func_append dllsearchpath ":$libdir";;
    	  esac
    	  case :$dllsearchpath: in
    	  *":$testbindir:"*) ;;
    	  ::) dllsearchpath=$testbindir;;
    	  *) func_append dllsearchpath ":$testbindir";;
    	  esac
    	  ;;
    	esac
          done
          # Substitute the hardcoded libdirs into the rpath.
          if test -n "$hardcode_libdir_separator" &&
    	 test -n "$hardcode_libdirs"; then
    	libdir=$hardcode_libdirs
    	eval rpath=\" $hardcode_libdir_flag_spec\"
          fi
          compile_rpath=$rpath
    
          rpath=
          hardcode_libdirs=
          for libdir in $finalize_rpath; do
    	if test -n "$hardcode_libdir_flag_spec"; then
    	  if test -n "$hardcode_libdir_separator"; then
    	    if test -z "$hardcode_libdirs"; then
    	      hardcode_libdirs=$libdir
    	    else
    	      # Just accumulate the unique libdirs.
    	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
    	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
    		;;
    	      *)
    		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
    		;;
    	      esac
    	    fi
    	  else
    	    eval flag=\"$hardcode_libdir_flag_spec\"
    	    func_append rpath " $flag"
    	  fi
    	elif test -n "$runpath_var"; then
    	  case "$finalize_perm_rpath " in
    	  *" $libdir "*) ;;
    	  *) func_append finalize_perm_rpath " $libdir" ;;
    	  esac
    	fi
          done
          # Substitute the hardcoded libdirs into the rpath.
          if test -n "$hardcode_libdir_separator" &&
    	 test -n "$hardcode_libdirs"; then
    	libdir=$hardcode_libdirs
    	eval rpath=\" $hardcode_libdir_flag_spec\"
          fi
          finalize_rpath=$rpath
    
          if test -n "$libobjs" && test yes = "$build_old_libs"; then
    	# Transform all the library objects into standard objects.
    	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
    	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
          fi
    
          func_generate_dlsyms "$outputname" "@PROGRAM@" false
    
          # template prelinking step
          if test -n "$prelink_cmds"; then
    	func_execute_cmds "$prelink_cmds" 'exit $?'
          fi
    
          wrappers_required=:
          case $host in
          *cegcc* | *mingw32ce*)
            # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
            wrappers_required=false
            ;;
          *cygwin* | *mingw* )
            test yes = "$build_libtool_libs" || wrappers_required=false
            ;;
          *)
            if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
              wrappers_required=false
            fi
            ;;
          esac
          $wrappers_required || {
    	# Replace the output file specification.
    	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
    	link_command=$compile_command$compile_rpath
    
    	# We have no uninstalled library dependencies, so finalize right now.
    	exit_status=0
    	func_show_eval "$link_command" 'exit_status=$?'
    
    	if test -n "$postlink_cmds"; then
    	  func_to_tool_file "$output"
    	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
    	  func_execute_cmds "$postlink_cmds" 'exit $?'
    	fi
    
    	# Delete the generated files.
    	if test -f "$output_objdir/${outputname}S.$objext"; then
    	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
    	fi
    
    	exit $exit_status
          }
    
          if test -n "$compile_shlibpath$finalize_shlibpath"; then
    	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
          fi
          if test -n "$finalize_shlibpath"; then
    	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
          fi
    
          compile_var=
          finalize_var=
          if test -n "$runpath_var"; then
    	if test -n "$perm_rpath"; then
    	  # We should set the runpath_var.
    	  rpath=
    	  for dir in $perm_rpath; do
    	    func_append rpath "$dir:"
    	  done
    	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
    	fi
    	if test -n "$finalize_perm_rpath"; then
    	  # We should set the runpath_var.
    	  rpath=
    	  for dir in $finalize_perm_rpath; do
    	    func_append rpath "$dir:"
    	  done
    	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
    	fi
          fi
    
          if test yes = "$no_install"; then
    	# We don't need to create a wrapper script.
    	link_command=$compile_var$compile_command$compile_rpath
    	# Replace the output file specification.
    	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
    	# Delete the old output file.
    	$opt_dry_run || $RM $output
    	# Link the executable and exit
    	func_show_eval "$link_command" 'exit $?'
    
    	if test -n "$postlink_cmds"; then
    	  func_to_tool_file "$output"
    	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
    	  func_execute_cmds "$postlink_cmds" 'exit $?'
    	fi
    
    	exit $EXIT_SUCCESS
          fi
    
          case $hardcode_action,$fast_install in
            relink,*)
    	  # Fast installation is not supported
    	  link_command=$compile_var$compile_command$compile_rpath
    	  relink_command=$finalize_var$finalize_command$finalize_rpath
    
    	  func_warning "this platform does not like uninstalled shared libraries"
    	  func_warning "'$output' will be relinked during installation"
    	  ;;
            *,yes)
    	  link_command=$finalize_var$compile_command$finalize_rpath
    	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
              ;;
    	*,no)
    	  link_command=$compile_var$compile_command$compile_rpath
    	  relink_command=$finalize_var$finalize_command$finalize_rpath
              ;;
    	*,needless)
    	  link_command=$finalize_var$compile_command$finalize_rpath
    	  relink_command=
              ;;
          esac
    
          # Replace the output file specification.
          link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
    
          # Delete the old output files.
          $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
    
          func_show_eval "$link_command" 'exit $?'
    
          if test -n "$postlink_cmds"; then
    	func_to_tool_file "$output_objdir/$outputname"
    	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
    	func_execute_cmds "$postlink_cmds" 'exit $?'
          fi
    
          # Now create the wrapper script.
          func_verbose "creating $output"
    
          # Quote the relink command for shipping.
          if test -n "$relink_command"; then
    	# Preserve any variables that may affect compiler behavior
    	for var in $variables_saved_for_relink; do
    	  if eval test -z \"\${$var+set}\"; then
    	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
    	  elif eval var_value=\$$var; test -z "$var_value"; then
    	    relink_command="$var=; export $var; $relink_command"
    	  else
    	    func_quote_arg pretty "$var_value"
    	    relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
    	  fi
    	done
    	func_quote eval cd "`pwd`"
    	func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)"
    	relink_command=$func_quote_arg_unquoted_result
          fi
    
          # Only actually do things if not in dry run mode.
          $opt_dry_run || {
    	# win32 will think the script is a binary if it has
    	# a .exe suffix, so we strip it off here.
    	case $output in
    	  *.exe) func_stripname '' '.exe' "$output"
    	         output=$func_stripname_result ;;
    	esac
    	# test for cygwin because mv fails w/o .exe extensions
    	case $host in
    	  *cygwin*)
    	    exeext=.exe
    	    func_stripname '' '.exe' "$outputname"
    	    outputname=$func_stripname_result ;;
    	  *) exeext= ;;
    	esac
    	case $host in
    	  *cygwin* | *mingw* )
    	    func_dirname_and_basename "$output" "" "."
    	    output_name=$func_basename_result
    	    output_path=$func_dirname_result
    	    cwrappersource=$output_path/$objdir/lt-$output_name.c
    	    cwrapper=$output_path/$output_name.exe
    	    $RM $cwrappersource $cwrapper
    	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
    
    	    func_emit_cwrapperexe_src > $cwrappersource
    
    	    # The wrapper executable is built using the $host compiler,
    	    # because it contains $host paths and files. If cross-
    	    # compiling, it, like the target executable, must be
    	    # executed on the $host or under an emulation environment.
    	    $opt_dry_run || {
    	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
    	      $STRIP $cwrapper
    	    }
    
    	    # Now, create the wrapper script for func_source use:
    	    func_ltwrapper_scriptname $cwrapper
    	    $RM $func_ltwrapper_scriptname_result
    	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
    	    $opt_dry_run || {
    	      # note: this script will not be executed, so do not chmod.
    	      if test "x$build" = "x$host"; then
    		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
    	      else
    		func_emit_wrapper no > $func_ltwrapper_scriptname_result
    	      fi
    	    }
    	  ;;
    	  * )
    	    $RM $output
    	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
    
    	    func_emit_wrapper no > $output
    	    chmod +x $output
    	  ;;
    	esac
          }
          exit $EXIT_SUCCESS
          ;;
        esac
    
        # See if we need to build an old-fashioned archive.
        for oldlib in $oldlibs; do
    
          case $build_libtool_libs in
            convenience)
    	  oldobjs="$libobjs_save $symfileobj"
    	  addlibs=$convenience
    	  build_libtool_libs=no
    	  ;;
    	module)
    	  oldobjs=$libobjs_save
    	  addlibs=$old_convenience
    	  build_libtool_libs=no
              ;;
    	*)
    	  oldobjs="$old_deplibs $non_pic_objects"
    	  $preload && test -f "$symfileobj" \
    	    && func_append oldobjs " $symfileobj"
    	  addlibs=$old_convenience
    	  ;;
          esac
    
          if test -n "$addlibs"; then
    	gentop=$output_objdir/${outputname}x
    	func_append generated " $gentop"
    
    	func_extract_archives $gentop $addlibs
    	func_append oldobjs " $func_extract_archives_result"
          fi
    
          # Do each command in the archive commands.
          if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
    	cmds=$old_archive_from_new_cmds
          else
    
    	# Add any objects from preloaded convenience libraries
    	if test -n "$dlprefiles"; then
    	  gentop=$output_objdir/${outputname}x
    	  func_append generated " $gentop"
    
    	  func_extract_archives $gentop $dlprefiles
    	  func_append oldobjs " $func_extract_archives_result"
    	fi
    
    	# POSIX demands no paths to be encoded in archives.  We have
    	# to avoid creating archives with duplicate basenames if we
    	# might have to extract them afterwards, e.g., when creating a
    	# static archive out of a convenience library, or when linking
    	# the entirety of a libtool archive into another (currently
    	# not supported by libtool).
    	if (for obj in $oldobjs
    	    do
    	      func_basename "$obj"
    	      $ECHO "$func_basename_result"
    	    done | sort | sort -uc >/dev/null 2>&1); then
    	  :
    	else
    	  echo "copying selected object files to avoid basename conflicts..."
    	  gentop=$output_objdir/${outputname}x
    	  func_append generated " $gentop"
    	  func_mkdir_p "$gentop"
    	  save_oldobjs=$oldobjs
    	  oldobjs=
    	  counter=1
    	  for obj in $save_oldobjs
    	  do
    	    func_basename "$obj"
    	    objbase=$func_basename_result
    	    case " $oldobjs " in
    	    " ") oldobjs=$obj ;;
    	    *[\ /]"$objbase "*)
    	      while :; do
    		# Make sure we don't pick an alternate name that also
    		# overlaps.
    		newobj=lt$counter-$objbase
    		func_arith $counter + 1
    		counter=$func_arith_result
    		case " $oldobjs " in
    		*[\ /]"$newobj "*) ;;
    		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
    		esac
    	      done
    	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
    	      func_append oldobjs " $gentop/$newobj"
    	      ;;
    	    *) func_append oldobjs " $obj" ;;
    	    esac
    	  done
    	fi
    	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
    	tool_oldlib=$func_to_tool_file_result
    	eval cmds=\"$old_archive_cmds\"
    
    	func_len " $cmds"
    	len=$func_len_result
    	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
    	  cmds=$old_archive_cmds
    	elif test -n "$archiver_list_spec"; then
    	  func_verbose "using command file archive linking..."
    	  for obj in $oldobjs
    	  do
    	    func_to_tool_file "$obj"
    	    $ECHO "$func_to_tool_file_result"
    	  done > $output_objdir/$libname.libcmd
    	  func_to_tool_file "$output_objdir/$libname.libcmd"
    	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
    	  cmds=$old_archive_cmds
    	else
    	  # the command line is too long to link in one step, link in parts
    	  func_verbose "using piecewise archive linking..."
    	  save_RANLIB=$RANLIB
    	  RANLIB=:
    	  objlist=
    	  concat_cmds=
    	  save_oldobjs=$oldobjs
    	  oldobjs=
    	  # Is there a better way of finding the last object in the list?
    	  for obj in $save_oldobjs
    	  do
    	    last_oldobj=$obj
    	  done
    	  eval test_cmds=\"$old_archive_cmds\"
    	  func_len " $test_cmds"
    	  len0=$func_len_result
    	  len=$len0
    	  for obj in $save_oldobjs
    	  do
    	    func_len " $obj"
    	    func_arith $len + $func_len_result
    	    len=$func_arith_result
    	    func_append objlist " $obj"
    	    if test "$len" -lt "$max_cmd_len"; then
    	      :
    	    else
    	      # the above command should be used before it gets too long
    	      oldobjs=$objlist
    	      if test "$obj" = "$last_oldobj"; then
    		RANLIB=$save_RANLIB
    	      fi
    	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
    	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
    	      objlist=
    	      len=$len0
    	    fi
    	  done
    	  RANLIB=$save_RANLIB
    	  oldobjs=$objlist
    	  if test -z "$oldobjs"; then
    	    eval cmds=\"\$concat_cmds\"
    	  else
    	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
    	  fi
    	fi
          fi
          func_execute_cmds "$cmds" 'exit $?'
        done
    
        test -n "$generated" && \
          func_show_eval "${RM}r$generated"
    
        # Now create the libtool archive.
        case $output in
        *.la)
          old_library=
          test yes = "$build_old_libs" && old_library=$libname.$libext
          func_verbose "creating $output"
    
          # Preserve any variables that may affect compiler behavior
          for var in $variables_saved_for_relink; do
    	if eval test -z \"\${$var+set}\"; then
    	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
    	elif eval var_value=\$$var; test -z "$var_value"; then
    	  relink_command="$var=; export $var; $relink_command"
    	else
    	  func_quote_arg pretty,unquoted "$var_value"
    	  relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
    	fi
          done
          # Quote the link command for shipping.
          func_quote eval cd "`pwd`"
          relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
          func_quote_arg pretty,unquoted "$relink_command"
          relink_command=$func_quote_arg_unquoted_result
          if test yes = "$hardcode_automatic"; then
    	relink_command=
          fi
    
          # Only create the output if not a dry run.
          $opt_dry_run || {
    	for installed in no yes; do
    	  if test yes = "$installed"; then
    	    if test -z "$install_libdir"; then
    	      break
    	    fi
    	    output=$output_objdir/${outputname}i
    	    # Replace all uninstalled libtool libraries with the installed ones
    	    newdependency_libs=
    	    for deplib in $dependency_libs; do
    	      case $deplib in
    	      *.la)
    		func_basename "$deplib"
    		name=$func_basename_result
    		func_resolve_sysroot "$deplib"
    		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
    		test -z "$libdir" && \
    		  func_fatal_error "'$deplib' is not a valid libtool archive"
    		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
    		;;
    	      -L*)
    		func_stripname -L '' "$deplib"
    		func_replace_sysroot "$func_stripname_result"
    		func_append newdependency_libs " -L$func_replace_sysroot_result"
    		;;
    	      -R*)
    		func_stripname -R '' "$deplib"
    		func_replace_sysroot "$func_stripname_result"
    		func_append newdependency_libs " -R$func_replace_sysroot_result"
    		;;
    	      *) func_append newdependency_libs " $deplib" ;;
    	      esac
    	    done
    	    dependency_libs=$newdependency_libs
    	    newdlfiles=
    
    	    for lib in $dlfiles; do
    	      case $lib in
    	      *.la)
    	        func_basename "$lib"
    		name=$func_basename_result
    		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
    		test -z "$libdir" && \
    		  func_fatal_error "'$lib' is not a valid libtool archive"
    		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
    		;;
    	      *) func_append newdlfiles " $lib" ;;
    	      esac
    	    done
    	    dlfiles=$newdlfiles
    	    newdlprefiles=
    	    for lib in $dlprefiles; do
    	      case $lib in
    	      *.la)
    		# Only pass preopened files to the pseudo-archive (for
    		# eventual linking with the app. that links it) if we
    		# didn't already link the preopened objects directly into
    		# the library:
    		func_basename "$lib"
    		name=$func_basename_result
    		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
    		test -z "$libdir" && \
    		  func_fatal_error "'$lib' is not a valid libtool archive"
    		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
    		;;
    	      esac
    	    done
    	    dlprefiles=$newdlprefiles
    	  else
    	    newdlfiles=
    	    for lib in $dlfiles; do
    	      case $lib in
    		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
    		*) abs=`pwd`"/$lib" ;;
    	      esac
    	      func_append newdlfiles " $abs"
    	    done
    	    dlfiles=$newdlfiles
    	    newdlprefiles=
    	    for lib in $dlprefiles; do
    	      case $lib in
    		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
    		*) abs=`pwd`"/$lib" ;;
    	      esac
    	      func_append newdlprefiles " $abs"
    	    done
    	    dlprefiles=$newdlprefiles
    	  fi
    	  $RM $output
    	  # place dlname in correct position for cygwin
    	  # In fact, it would be nice if we could use this code for all target
    	  # systems that can't hard-code library paths into their executables
    	  # and that have no shared library path variable independent of PATH,
    	  # but it turns out we can't easily determine that from inspecting
    	  # libtool variables, so we have to hard-code the OSs to which it
    	  # applies here; at the moment, that means platforms that use the PE
    	  # object format with DLL files.  See the long comment at the top of
    	  # tests/bindir.at for full details.
    	  tdlname=$dlname
    	  case $host,$output,$installed,$module,$dlname in
    	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
    	      # If a -bindir argument was supplied, place the dll there.
    	      if test -n "$bindir"; then
    		func_relative_path "$install_libdir" "$bindir"
    		tdlname=$func_relative_path_result/$dlname
    	      else
    		# Otherwise fall back on heuristic.
    		tdlname=../bin/$dlname
    	      fi
    	      ;;
    	  esac
    	  $ECHO > $output "\
    # $outputname - a libtool library file
    # Generated by $PROGRAM (GNU $PACKAGE) $VERSION
    #
    # Please DO NOT delete this file!
    # It is necessary for linking the library.
    
    # The name that we can dlopen(3).
    dlname='$tdlname'
    
    # Names of this library.
    library_names='$library_names'
    
    # The name of the static archive.
    old_library='$old_library'
    
    # Linker flags that cannot go in dependency_libs.
    inherited_linker_flags='$new_inherited_linker_flags'
    
    # Libraries that this one depends upon.
    dependency_libs='$dependency_libs'
    
    # Names of additional weak libraries provided by this library
    weak_library_names='$weak_libs'
    
    # Version information for $libname.
    current=$current
    age=$age
    revision=$revision
    
    # Is this an already installed library?
    installed=$installed
    
    # Should we warn about portability when linking against -modules?
    shouldnotlink=$module
    
    # Files to dlopen/dlpreopen
    dlopen='$dlfiles'
    dlpreopen='$dlprefiles'
    
    # Directory that this library needs to be installed in:
    libdir='$install_libdir'"
    	  if test no,yes = "$installed,$need_relink"; then
    	    $ECHO >> $output "\
    relink_command=\"$relink_command\""
    	  fi
    	done
          }
    
          # Do a symbolic link so that the libtool archive can be found in
          # LD_LIBRARY_PATH before the program is installed.
          func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
          ;;
        esac
        exit $EXIT_SUCCESS
    }
    
    if test link = "$opt_mode" || test relink = "$opt_mode"; then
      func_mode_link ${1+"$@"}
    fi
    
    
    # func_mode_uninstall arg...
    func_mode_uninstall ()
    {
        $debug_cmd
    
        RM=$nonopt
        files=
        rmforce=false
        exit_status=0
    
        # This variable tells wrapper scripts just to set variables rather
        # than running their programs.
        libtool_install_magic=$magic
    
        for arg
        do
          case $arg in
          -f) func_append RM " $arg"; rmforce=: ;;
          -*) func_append RM " $arg" ;;
          *) func_append files " $arg" ;;
          esac
        done
    
        test -z "$RM" && \
          func_fatal_help "you must specify an RM program"
    
        rmdirs=
    
        for file in $files; do
          func_dirname "$file" "" "."
          dir=$func_dirname_result
          if test . = "$dir"; then
    	odir=$objdir
          else
    	odir=$dir/$objdir
          fi
          func_basename "$file"
          name=$func_basename_result
          test uninstall = "$opt_mode" && odir=$dir
    
          # Remember odir for removal later, being careful to avoid duplicates
          if test clean = "$opt_mode"; then
    	case " $rmdirs " in
    	  *" $odir "*) ;;
    	  *) func_append rmdirs " $odir" ;;
    	esac
          fi
    
          # Don't error if the file doesn't exist and rm -f was used.
          if { test -L "$file"; } >/dev/null 2>&1 ||
    	 { test -h "$file"; } >/dev/null 2>&1 ||
    	 test -f "$file"; then
    	:
          elif test -d "$file"; then
    	exit_status=1
    	continue
          elif $rmforce; then
    	continue
          fi
    
          rmfiles=$file
    
          case $name in
          *.la)
    	# Possibly a libtool archive, so verify it.
    	if func_lalib_p "$file"; then
    	  func_source $dir/$name
    
    	  # Delete the libtool libraries and symlinks.
    	  for n in $library_names; do
    	    func_append rmfiles " $odir/$n"
    	  done
    	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
    
    	  case $opt_mode in
    	  clean)
    	    case " $library_names " in
    	    *" $dlname "*) ;;
    	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
    	    esac
    	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
    	    ;;
    	  uninstall)
    	    if test -n "$library_names"; then
    	      # Do each command in the postuninstall commands.
    	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
    	    fi
    
    	    if test -n "$old_library"; then
    	      # Do each command in the old_postuninstall commands.
    	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
    	    fi
    	    # FIXME: should reinstall the best remaining shared library.
    	    ;;
    	  esac
    	fi
    	;;
    
          *.lo)
    	# Possibly a libtool object, so verify it.
    	if func_lalib_p "$file"; then
    
    	  # Read the .lo file
    	  func_source $dir/$name
    
    	  # Add PIC object to the list of files to remove.
    	  if test -n "$pic_object" && test none != "$pic_object"; then
    	    func_append rmfiles " $dir/$pic_object"
    	  fi
    
    	  # Add non-PIC object to the list of files to remove.
    	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then
    	    func_append rmfiles " $dir/$non_pic_object"
    	  fi
    	fi
    	;;
    
          *)
    	if test clean = "$opt_mode"; then
    	  noexename=$name
    	  case $file in
    	  *.exe)
    	    func_stripname '' '.exe' "$file"
    	    file=$func_stripname_result
    	    func_stripname '' '.exe' "$name"
    	    noexename=$func_stripname_result
    	    # $file with .exe has already been added to rmfiles,
    	    # add $file without .exe
    	    func_append rmfiles " $file"
    	    ;;
    	  esac
    	  # Do a test to see if this is a libtool program.
    	  if func_ltwrapper_p "$file"; then
    	    if func_ltwrapper_executable_p "$file"; then
    	      func_ltwrapper_scriptname "$file"
    	      relink_command=
    	      func_source $func_ltwrapper_scriptname_result
    	      func_append rmfiles " $func_ltwrapper_scriptname_result"
    	    else
    	      relink_command=
    	      func_source $dir/$noexename
    	    fi
    
    	    # note $name still contains .exe if it was in $file originally
    	    # as does the version of $file that was added into $rmfiles
    	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"
    	    if test yes = "$fast_install" && test -n "$relink_command"; then
    	      func_append rmfiles " $odir/lt-$name"
    	    fi
    	    if test "X$noexename" != "X$name"; then
    	      func_append rmfiles " $odir/lt-$noexename.c"
    	    fi
    	  fi
    	fi
    	;;
          esac
          func_show_eval "$RM $rmfiles" 'exit_status=1'
        done
    
        # Try to remove the $objdir's in the directories where we deleted files
        for dir in $rmdirs; do
          if test -d "$dir"; then
    	func_show_eval "rmdir $dir >/dev/null 2>&1"
          fi
        done
    
        exit $exit_status
    }
    
    if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
      func_mode_uninstall ${1+"$@"}
    fi
    
    test -z "$opt_mode" && {
      help=$generic_help
      func_fatal_help "you must specify a MODE"
    }
    
    test -z "$exec_cmd" && \
      func_fatal_help "invalid operation mode '$opt_mode'"
    
    if test -n "$exec_cmd"; then
      eval exec "$exec_cmd"
      exit $EXIT_FAILURE
    fi
    
    exit $exit_status
    
    
    # The TAGs below are defined such that we never get into a situation
    # where we disable both kinds of libraries.  Given conflicting
    # choices, we go for a static library, that is the most portable,
    # since we can't tell whether shared libraries were disabled because
    # the user asked for that or because the platform doesn't support
    # them.  This is particularly important on AIX, because we don't
    # support having both static and shared libraries enabled at the same
    # time on that platform, so we default to a shared-only configuration.
    # If a disable-shared tag is given, we'll fallback to a static-only
    # configuration.  But we'll never go from static-only to shared-only.
    
    # ### BEGIN LIBTOOL TAG CONFIG: disable-shared
    build_libtool_libs=no
    build_old_libs=yes
    # ### END LIBTOOL TAG CONFIG: disable-shared
    
    # ### BEGIN LIBTOOL TAG CONFIG: disable-static
    build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
    # ### END LIBTOOL TAG CONFIG: disable-static
    
    # Local Variables:
    # mode:shell-script
    # sh-indentation:2
    # End:
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/Makefile.in����������������������������������������������������������������������������0000664�0001751�0001751�00000027335�15032717356�014712� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    SUBDIRS = srclib os server modules support
    CLEAN_SUBDIRS = test
    
    PROGRAM_NAME         = $(progname)
    PROGRAM_SOURCES      = modules.c
    PROGRAM_LDADD        = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(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
    
    sbin_PROGRAMS   = $(PROGRAM_NAME)
    TARGETS         = $(sbin_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 \
    	include/apache_probes.h \
    	modules.c config.cache config.log config.status build/config_vars.mk \
    	build/rules.mk docs/conf/httpd.conf docs/conf/extra/*.conf shlibtool \
    	build/pkg/pkginfo build/config_vars.sh
    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
    	@$(MKINSTALLDIRS) $(DESTDIR)$(sysconfdir) $(DESTDIR)$(sysconfdir)/extra
    	@$(MKINSTALLDIRS) $(DESTDIR)$(sysconfdir)/original/extra
    	@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/*.conf; do \
    	    	if [ -f $$i ] ; then \
    	    	( \
    	    		n_lm=`awk 'BEGIN {n=0} /@@LoadModule@@/ {n+=1} END {print n}' < $$i`; \
    	    		if test $$n_lm -eq 0 -o "x$(MPM_MODULES)$(DSO_MODULES)" = "x"; then \
    	    			sed -e 's#@@ServerRoot@@#$(prefix)#g' \
    	    				-e 's#@@Port@@#$(PORT)#g' \
    	    				-e 's#@@SSLPort@@#$(SSLPORT)#g' \
    	    				-e '/@@LoadModule@@/d' \
    	    				< $$i; \
    	    		else \
    	    			sed -n -e '/@@LoadModule@@/q' \
    	    				-e 's#@@ServerRoot@@#$(prefix)#g' \
    	    				-e 's#@@Port@@#$(PORT)#g' \
    	    				-e 's#@@SSLPort@@#$(SSLPORT)#g' \
    	    				-e 'p' \
    	    				< $$i; \
    	    			if echo " $(DSO_MODULES) "|$(EGREP) " cgi " > /dev/null ; then \
    	    				have_cgi="1"; \
    	    			else \
    	    				have_cgi="0"; \
    	    			fi; \
    	    			if echo " $(DSO_MODULES) "|$(EGREP) " cgid " > /dev/null ; then \
    	    				have_cgid="1"; \
    	    			else \
    	    				have_cgid="0"; \
    	    			fi; \
    	    			for j in $(MPM_MODULES) "^EOL^"; do \
    	    				if test $$j != "^EOL^"; then \
    	    					if echo ",$(ENABLED_MPM_MODULE),"|$(EGREP) ",$$j," > /dev/null ; then \
    	    						loading_disabled=""; \
    	    					else \
    	    						loading_disabled="#"; \
    	    					fi; \
    						echo "$${loading_disabled}LoadModule $${j}_module $(rel_libexecdir)/mod_$${j}.so"; \
    					fi; \
    	    			done; \
    	    			for j in $(DSO_MODULES) "^EOL^"; do \
    	    				if test $$j != "^EOL^"; then \
    	    					if echo ",$(ENABLED_DSO_MODULES),"|$(EGREP) ",$$j," > /dev/null ; then \
    	    						loading_disabled=""; \
    	    					else \
    	    						loading_disabled="#"; \
    		    					if test "$(LOAD_ALL_MODULES)" = "yes"; then \
    		    						loading_disabled=""; \
    	    						fi; \
    	    					fi; \
    						if test $$j = "cgid" -a "$$have_cgi" = "1"; then \
    							echo "<IfModule !mpm_prefork_module>"; \
    							echo "	$${loading_disabled}LoadModule $${j}_module $(rel_libexecdir)/mod_$${j}.so"; \
    							echo "</IfModule>"; \
    						elif test $$j = "cgi" -a "$$have_cgid" = "1"; then \
    							echo "<IfModule mpm_prefork_module>"; \
    							echo "	$${loading_disabled}LoadModule $${j}_module $(rel_libexecdir)/mod_$${j}.so"; \
    							echo "</IfModule>"; \
    						else \
    							echo "$${loading_disabled}LoadModule $${j}_module $(rel_libexecdir)/mod_$${j}.so"; \
    						fi; \
    					fi; \
    	    			done; \
    	    			sed -e '1,/@@LoadModule@@/d' \
    	    				-e '/@@LoadModule@@/d' \
    	    				-e 's#@@ServerRoot@@#$(prefix)#g' \
    	    				-e 's#@@Port@@#$(PORT)#g' \
    	    				-e 's#@@SSLPort@@#$(SSLPORT)#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; \
    	    	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
    
    # Create a sanitized config_vars.mk
    build/config_vars.out: build/config_vars.mk build/config_vars.sh
    	@$(SHELL) build/config_vars.sh < build/config_vars.mk > build/config_vars.out
    
    install-build: build/config_vars.out
    	@echo Installing build system files 
    	@$(MKINSTALLDIRS) $(DESTDIR)$(installbuilddir) 
    	@for f in $(top_srcdir)/build/*.mk build/*.mk; do \
    	 $(INSTALL_DATA) $$f $(DESTDIR)$(installbuilddir); \
    	done
    	@for f in $(top_builddir)/config.nice \
    		  $(top_srcdir)/build/mkdir.sh \
    		  $(top_srcdir)/build/instdso.sh; do \
    	 $(INSTALL_PROGRAM) $$f $(DESTDIR)$(installbuilddir); \
    	done
    	@$(INSTALL_DATA) build/config_vars.out $(DESTDIR)$(installbuilddir)/config_vars.mk
    	@rm build/config_vars.out
    
    htdocs-srcdir = $(top_srcdir)/docs/docroot
    
    docs:
    	@if test -d $(top_srcdir)/docs/manual/build; then \
    	    cd $(top_srcdir)/docs/manual/build && ./build.sh all; \
    	else \
    	    echo 'For details on generating the docs, please read:'; \
    	    echo '  http://httpd.apache.org/docs-project/docsformat.html'; \
    	fi
    
    update-changes:
    	@find changes-entries -type f | while read -r i ; do \
    	    cp CHANGES CHANGES.tmp ; \
    	    awk -v fname="$$i" 'BEGIN{done = 0; active = 0} \
    	                    done == 0 && active == 0 && /^Changes with Apache /{ active = 1; print; next}; \
    	                    /^( *\*|Changes with Apache )/ && active == 1 && done == 0{rec=$$0; while((getline<fname) > 0){if (! ($$0 ~ /^ *$$/)){print}}printf "\n";print rec; active = 0; done = 1; next} //;' \
    	    CHANGES.tmp > CHANGES ; \
    	    rm CHANGES.tmp ; \
    	    if [ -n "$(SVN)" ] ; then \
    	        if ! $(SVN) rm "$$i" 2>/dev/null ; then \
    	            $(RM) "$$i" ; \
    	        fi ; \
    	    else \
    	        $(RM) "$$i" ; \
    	    fi ; \
    	done ; \
    	if [ -n "$(SVN)" ] ; then \
    	    $(SVN) diff CHANGES ; \
    	fi
    
    validate-xml:
    	@if test -d $(top_srcdir)/docs/manual/build; then \
    	    cd $(top_srcdir)/docs/manual/build && ./build.sh validate-xml; \
    	else \
    	    echo 'For details on generating the docs, please read:'; \
    	    echo '  http://httpd.apache.org/docs-project/docsformat.html'; \
    	fi
    
    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) ; \
    	    if test -d $(htdocs-srcdir) && test "x$(RSYNC)" != "x" && test -x $(RSYNC) ; then \
    		$(RSYNC) --exclude .svn -rlpt --numeric-ids $(htdocs-srcdir)/ $(DESTDIR)$(htdocsdir)/; \
    	    else \
    		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; \
    	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_HEADERS = \
    	include/*.h \
    	$(srcdir)/include/*.h \
    	$(srcdir)/os/$(OS_DIR)/os.h \
    	$(srcdir)/modules/arch/unix/mod_unixd.h \
    	$(srcdir)/modules/core/mod_so.h \
    	$(srcdir)/modules/core/mod_watchdog.h \
    	$(srcdir)/modules/cache/mod_cache.h \
    	$(srcdir)/modules/cache/cache_common.h \
    	$(srcdir)/modules/database/mod_dbd.h \
    	$(srcdir)/modules/dav/main/mod_dav.h \
    	$(srcdir)/modules/http2/mod_http2.h \
    	$(srcdir)/modules/filters/mod_include.h \
    	$(srcdir)/modules/filters/mod_xml2enc.h \
    	$(srcdir)/modules/generators/mod_cgi.h \
    	$(srcdir)/modules/generators/mod_status.h \
    	$(srcdir)/modules/loggers/mod_log_config.h \
    	$(srcdir)/modules/mappers/mod_rewrite.h \
    	$(srcdir)/modules/proxy/mod_proxy.h \
            $(srcdir)/modules/session/mod_session.h \
    	$(srcdir)/modules/ssl/mod_ssl.h \
    	$(srcdir)/modules/ssl/mod_ssl_openssl.h \
    	$(srcdir)/os/$(OS_DIR)/*.h
    
    install-include:
    	@echo Installing header files
    	@$(MKINSTALLDIRS) $(DESTDIR)$(includedir)
    	@for hdr in $(INSTALL_HEADERS); do \
    	  $(INSTALL_DATA) $$hdr $(DESTDIR)$(includedir); \
    	done
    
    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
    	@if test "x$(RSYNC)" != "x" && test -x $(RSYNC) ; then \
    	  $(RSYNC) --exclude .svn -rlpt --numeric-ids $(top_srcdir)/docs/manual/ $(DESTDIR)$(manualdir)/; \
    	else \
    	  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; \
    	fi
    
    install-suexec: install-suexec-$(INSTALL_SUEXEC)
    
    install-suexec-binary:
    	@if test -f $(builddir)/support/suexec; then \
                test -d $(DESTDIR)$(sbindir) || $(MKINSTALLDIRS) $(DESTDIR)$(sbindir); \
                $(INSTALL_PROGRAM) $(top_builddir)/support/suexec $(DESTDIR)$(sbindir); \
    	fi
    
    install-suexec-setuid: install-suexec-binary
    	@if test -f $(builddir)/support/suexec; then \
    	    chmod 4755 $(DESTDIR)$(sbindir)/suexec; \
    	fi
    
    install-suexec-caps: install-suexec-binary
    	@if test -f $(builddir)/support/suexec; then \
                setcap 'cap_setuid,cap_setgid+pe' $(DESTDIR)$(sbindir)/suexec; \
    	fi
    
    suexec:
    	cd support && $(MAKE) suexec
    
    x-local-distclean:
    	@rm -rf autom4te.cache
    
    # XXX: This looks awfully platform-specific [read: bad form and style]
    include $(top_srcdir)/os/os2/core.mk
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/CMakeLists.txt�������������������������������������������������������������������������0000664�0001751�0001751�00000136607�15022007067�015376� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    # Read README.cmake before using this.
    
    PROJECT(HTTPD C)
    
    CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
    
    INCLUDE(CheckSymbolExists)
    INCLUDE(CheckCSourceCompiles)
    INCLUDE("build/build-modules-c.cmake")
    
    FIND_PACKAGE(LibXml2)
    FIND_PACKAGE(Lua51)
    FIND_PACKAGE(OpenSSL)
    FIND_PACKAGE(ZLIB)
    FIND_PACKAGE(CURL)
    FIND_PACKAGE(PCRE2 COMPONENTS 8BIT)
    
    # Options for support libraries not supported by cmake-bundled FindFOO
    
    # Default to using APR trunk (libapr-2.lib) if it exists in PREFIX/lib;
    # otherwise, default to APR 1.x + APR-util 1.x
    IF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/libapr-2.lib")
      SET(default_apr_libraries "${CMAKE_INSTALL_PREFIX}/lib/libapr-2.lib")
    ELSEIF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/libapr-1.lib")
      SET(ldaplib "${CMAKE_INSTALL_PREFIX}/lib/apr_ldap-1.lib")
      IF(NOT EXISTS ${ldaplib})
        SET(ldaplib)
      ENDIF()
      SET(default_apr_libraries ${CMAKE_INSTALL_PREFIX}/lib/libapr-1.lib ${CMAKE_INSTALL_PREFIX}/lib/libaprutil-1.lib ${ldaplib})
    ELSE()
      SET(default_apr_libraries)
    ENDIF()
    
    # PCRE names its libraries differently for debug vs. release builds.
    # We can't query our own CMAKE_BUILD_TYPE at configure time.
    # If the debug version exists in PREFIX/lib, default to that one.
    IF(PCRE2_FOUND)
      SET(default_pcre_libraries "PCRE2::8BIT")
      SET(default_pcre_cflags "-DHAVE_PCRE2")
    ELSEIF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/pcre2-8d.lib")
      SET(default_pcre_libraries ${CMAKE_INSTALL_PREFIX}/lib/pcre2-8d.lib)
      SET(default_pcre_cflags "-DHAVE_PCRE2")
    ELSEIF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/pcre2-8.lib")
      SET(default_pcre_libraries ${CMAKE_INSTALL_PREFIX}/lib/pcre2-8.lib)
      SET(default_pcre_cflags "-DHAVE_PCRE2")
    ELSEIF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/pcred.lib")
      SET(default_pcre_libraries ${CMAKE_INSTALL_PREFIX}/lib/pcred.lib)
    ELSE()
      SET(default_pcre_libraries ${CMAKE_INSTALL_PREFIX}/lib/pcre.lib)
    ENDIF()
    
    IF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/nghttp2d.lib")
      SET(default_nghttp2_libraries "${CMAKE_INSTALL_PREFIX}/lib/nghttp2d.lib")
    ELSE()
      SET(default_nghttp2_libraries "${CMAKE_INSTALL_PREFIX}/lib/nghttp2.lib")
    ENDIF()
    
    IF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/brotlienc.lib")
      SET(default_brotli_libraries "${CMAKE_INSTALL_PREFIX}/lib/brotlienc.lib" "${CMAKE_INSTALL_PREFIX}/lib/brotlicommon.lib")
    ELSE()
      SET(default_brotli_libraries)
    ENDIF()
    
    IF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/libcurl_imp.lib")
      SET(default_curl_libraries "${CMAKE_INSTALL_PREFIX}/lib/libcurl_imp.lib")
    ELSEIF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/libcurl.lib")
      SET(default_curl_libraries "${CMAKE_INSTALL_PREFIX}/lib/libcurl.lib")
    ELSE()
      SET(default_curl_libraries)
    ENDIF()
    
    IF(EXISTS "${CMAKE_INSTALL_PREFIX}/lib/jansson.lib")
      SET(default_jansson_libraries "${CMAKE_INSTALL_PREFIX}/lib/jansson.lib")
    ELSE()
      SET(default_jansson_libraries)
    ENDIF()
    
    SET(APR_INCLUDE_DIR       "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Directory with APR[-Util] include files")
    SET(APR_LIBRARIES         ${default_apr_libraries}       CACHE STRING "APR libraries to link with")
    SET(NGHTTP2_INCLUDE_DIR   "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Directory with NGHTTP2 include files within nghttp2 subdirectory")
    SET(NGHTTP2_LIBRARIES     ${default_nghttp2_libraries}   CACHE STRING "NGHTTP2 libraries to link with")
    SET(PCRE_CFLAGS           "${default_pcre_cflags}"       CACHE STRING "PCRE flags for util_pcre.c compilation")
    SET(PCRE_INCLUDE_DIR      "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Directory with PCRE include files")
    SET(PCRE_LIBRARIES        ${default_pcre_libraries}      CACHE STRING "PCRE libraries to link with")
    SET(LIBXML2_ICONV_INCLUDE_DIR     ""                     CACHE STRING "Directory with iconv include files for libxml2")
    SET(LIBXML2_ICONV_LIBRARIES       ""                     CACHE STRING "iconv libraries to link with for libxml2")
    SET(BROTLI_INCLUDE_DIR    "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Directory with include files for Brotli")
    SET(BROTLI_LIBRARIES      ${default_brotli_libraries}    CACHE STRING "Brotli libraries to link with")
    SET(CURL_INCLUDE_DIR      "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Directory with include files for cURL")
    SET(CURL_LIBRARIES        ${default_curl_libraries}         CACHE STRING "cURL libraries to link with")
    SET(JANSSON_INCLUDE_DIR   "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Directory with include files for jansson")
    SET(JANSSON_LIBRARIES     "${default_jansson_libraries}" CACHE STRING "Jansson libraries to link with")
    # end support library configuration
    
    # Misc. options
    OPTION(INSTALL_PDB        "Install .pdb files (if generated)"  ON)
    OPTION(INSTALL_MANUAL     "Install manual"                     ON)
    
    SET(ENABLE_MODULES        "O"                            CACHE STRING "Minimum module enablement (e.g., \"i\" to build all but those without prerequisites)")
    SET(WITH_MODULES          ""                             CACHE STRING "comma-separated paths to single-file modules to statically link into the server")
    SET(EXTRA_INCLUDES        ""                             CACHE STRING "Extra include directories")
    SET(EXTRA_LIBS            ""                             CACHE STRING "Extra libraries")
    SET(EXTRA_COMPILE_FLAGS   ""                             CACHE STRING "Extra compile flags")
    
    IF(NOT EXISTS "${APR_INCLUDE_DIR}/apr.h")
      MESSAGE(FATAL_ERROR "APR include directory ${APR_INCLUDE_DIR} is not correct.")
    ENDIF()
    FOREACH(onelib ${APR_LIBRARIES})
      IF(NOT EXISTS ${onelib})
        MESSAGE(FATAL_ERROR "APR library ${onelib} was not found.")
      ENDIF()
    ENDFOREACH()
    
    MACRO(DEFINE_WITH_BLANKS output_definition input_symbol input_value)
      IF(MSVC_IDE OR ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} VERSION_GREATER 2.8.11)
        SET(${output_definition} "-D${input_symbol}=\"${input_value}\"")
      ELSE()
        # command-line tool + older cmake, where extra quotes must be added and
        # escaped to survive
        SET(${output_definition} "-D${input_symbol}=\"\\\"${input_value}\\\"\"")
      ENDIF()
    ENDMACRO()
    
    MACRO(GET_MOD_ENABLE_RANK macro_modname macro_mod_enable_val macro_output_rank)
      IF(${macro_mod_enable_val} STREQUAL "O")
        SET(${macro_output_rank} 0)
      ELSEIF(${macro_mod_enable_val} STREQUAL "i")
        SET(${macro_output_rank} 1)
      ELSEIF(${macro_mod_enable_val} STREQUAL "I")
        SET(${macro_output_rank} 2)
      ELSEIF(${macro_mod_enable_val} STREQUAL "a")
        SET(${macro_output_rank} 3)
      ELSEIF(${macro_mod_enable_val} STREQUAL "A")
        SET(${macro_output_rank} 4)
      ELSE()
        MESSAGE(FATAL_ERROR "Unexpected enablement value \"${macro_mod_enable_val}\" for ${macro_modname}")
      ENDIF()
    ENDMACRO()
    
    GET_MOD_ENABLE_RANK("ENABLE_MODULES setting" ${ENABLE_MODULES} enable_modules_rank)
    
    # Figure out what APR/APU features are available
    #
    # CHECK_APR_FEATURE checks for features defined to 1 or 0 in apr.h or apu.h
    # The symbol representing the feature will be set to TRUE or FALSE for 
    # compatibility with the feature tests set by FindFooPackage.
    #
    # (unclear why CHECK_SYMBOL_EXISTS is needed, but I was getting "found" for anything 
    # not defined to either 1 or 0)
    
    MACRO(CHECK_APR_FEATURE which_define)
      SET(CMAKE_REQUIRED_INCLUDES "${APR_INCLUDE_DIR}")
      CHECK_SYMBOL_EXISTS(${which_define} "apr.h;apu.h" tmp_${which_define})
      IF(${tmp_${which_define}})
        CHECK_C_SOURCE_COMPILES("#include \"${APR_INCLUDE_DIR}/apr.h\"
          #include \"${APR_INCLUDE_DIR}/apu.h\"
          int main() {
          #ifndef ${which_define}
          #error gobble
          #endif
          #if !${which_define}
          #error gobble
          #endif
          return 1;}" ${which_define})
      ELSE()
        SET(${which_define})
      ENDIF()
      IF(${${which_define}})
        SET(${which_define} TRUE)
      ELSE()
        SET(${which_define} FALSE)
      ENDIF()
    ENDMACRO()
    
    CHECK_APR_FEATURE(APR_HAS_XLATE)
    CHECK_APR_FEATURE(APU_HAVE_CRYPTO)
    
    # APR_HAS_LDAP is defined in apr_ldap.h, which exists only in apr 1.x, so use
    # special code instead of CHECK_APR_FEATURE()
    # As with CHECK_APR_FEATURE(), convert to a TRUE/FALSE result.
    CHECK_C_SOURCE_COMPILES("#include \"${APR_INCLUDE_DIR}/apr.h\"
    #include \"${APR_INCLUDE_DIR}/apr_ldap.h\"
    int main() {
    #if !APR_HAS_LDAP
    #error gobble
    #endif
    return 1;}" APR_HAS_LDAP)
    IF(${APR_HAS_LDAP})
      SET(APR_HAS_LDAP TRUE)
    ELSE()
      SET(APR_HAS_LDAP FALSE)
    ENDIF()
    
    # See if nghttp2 exists in a configured or defaulted location
    SET(NGHTTP2_FOUND TRUE)
    IF(EXISTS "${NGHTTP2_INCLUDE_DIR}/nghttp2/nghttp2.h")
      FOREACH(onelib ${NGHTTP2_LIBRARIES})
        IF(NOT EXISTS ${onelib})
          SET(NGHTTP2_FOUND FALSE)
        ENDIF()
      ENDFOREACH()
    ELSE()
      SET(NGHTTP2_FOUND FALSE)
    ENDIF()
    
    # See if we have Brotli
    SET(BROTLI_FOUND TRUE)
    IF(EXISTS "${BROTLI_INCLUDE_DIR}/brotli/encode.h")
      FOREACH(onelib ${BROTLI_LIBRARIES})
        IF(NOT EXISTS ${onelib})
          SET(BROTLI_FOUND FALSE)
        ENDIF()
      ENDFOREACH()
    ELSE()
      SET(BROTLI_FOUND FALSE)
    ENDIF()
    
    # See if we have Jansson
    SET(JANSSON_FOUND TRUE)
    IF(EXISTS "${JANSSON_INCLUDE_DIR}/jansson.h")
      FOREACH(onelib ${JANSSON_LIBRARIES})
        IF(NOT EXISTS ${onelib})
          SET(JANSSON_FOUND FALSE)
        ENDIF()
      ENDFOREACH()
    ELSE()
      SET(JANSSON_FOUND FALSE)
    ENDIF()
    
    
    MESSAGE(STATUS "")
    MESSAGE(STATUS "Summary of feature detection:")
    MESSAGE(STATUS "")
    MESSAGE(STATUS "LIBXML2_FOUND ............ : ${LIBXML2_FOUND}")
    MESSAGE(STATUS "LUA51_FOUND .............. : ${LUA51_FOUND}")
    MESSAGE(STATUS "NGHTTP2_FOUND ............ : ${NGHTTP2_FOUND}")
    MESSAGE(STATUS "OPENSSL_FOUND ............ : ${OPENSSL_FOUND}")
    MESSAGE(STATUS "ZLIB_FOUND ............... : ${ZLIB_FOUND}")
    MESSAGE(STATUS "BROTLI_FOUND ............. : ${BROTLI_FOUND}")
    MESSAGE(STATUS "CURL_FOUND ............... : ${CURL_FOUND}")
    MESSAGE(STATUS "JANSSON_FOUND ............ : ${JANSSON_FOUND}")
    MESSAGE(STATUS "APR_HAS_LDAP ............. : ${APR_HAS_LDAP}")
    MESSAGE(STATUS "APR_HAS_XLATE ............ : ${APR_HAS_XLATE}")
    MESSAGE(STATUS "APU_HAVE_CRYPTO .......... : ${APU_HAVE_CRYPTO}")
    MESSAGE(STATUS "")
    
    # Options for each available module
    #   "A" ("A"ctive) means installed and active in default .conf, fail if can't be built
    #   "I" ("I"nactive) means installed and inactive (LoadModule commented out) in default .conf, fail if can't be built
    #   "O" ("O"mit) means not installed, no LoadModule
    #   "a" - like "A", but ignore with a warning if any prereqs aren't available
    #   "i" - like "I", but ignore with a warning if any prereqs aren't available
    
    # Current heuristic for default enablement:
    #
    #   Module requires a prereq and           -> O
    #   finding/usingprereq isn't implemented
    #   yet
    #
    #   Module is included by default in       -> a if it has prereqs, A otherwise
    #   autoconf-based build 
    #
    #   Module is included in                  -> i if it has prereqs, I otherwise
    #   --enable-modules=most 
    #
    #   Otherwise                              -> O
    #
    SET(MODULE_LIST
      "modules/aaa/mod_access_compat+A+mod_access compatibility"
      "modules/aaa/mod_allowmethods+I+restrict allowed HTTP methods"
      "modules/aaa/mod_auth_basic+A+basic authentication"
      "modules/aaa/mod_auth_digest+I+RFC2617 Digest authentication"
      "modules/aaa/mod_auth_form+I+form authentication"
      "modules/aaa/mod_authn_anon+I+anonymous user authentication control"
      "modules/aaa/mod_authn_core+A+core authentication module"
      "modules/aaa/mod_authn_dbd+I+SQL-based authentication control"
      "modules/aaa/mod_authn_dbm+I+DBM-based authentication control"
      "modules/aaa/mod_authn_file+A+file-based authentication control"
      "modules/aaa/mod_authn_socache+I+Cached authentication control"
      "modules/aaa/mod_authnz_fcgi+I+FastCGI authorizer-based authentication and authorization"
      "modules/aaa/mod_authnz_ldap+i+LDAP based authentication"
      "modules/aaa/mod_authz_core+A+core authorization provider vector module"
      "modules/aaa/mod_authz_dbd+I+SQL based authorization and Login/Session support"
      "modules/aaa/mod_authz_dbm+I+DBM-based authorization control"
      "modules/aaa/mod_authz_groupfile+A+'require group' authorization control"
      "modules/aaa/mod_authz_host+A+host-based authorization control"
      "modules/aaa/mod_authz_owner+I+'require file-owner' authorization control"
      "modules/aaa/mod_authz_user+A+'require user' authorization control"
      "modules/arch/win32/mod_isapi+I+isapi extension support"
      "modules/cache/mod_cache+I+dynamic file caching.  At least one storage management module (e.g. mod_cache_disk) is also necessary."
      "modules/cache/mod_cache_disk+I+disk caching module"
      "modules/cache/mod_cache_socache+I+shared object caching module"
      "modules/cache/mod_file_cache+I+File cache"
      "modules/cache/mod_socache_dbm+I+dbm small object cache provider"
      "modules/cache/mod_socache_dc+O+distcache small object cache provider"
      "modules/cache/mod_socache_memcache+I+memcache small object cache provider"
      "modules/cache/mod_socache_shmcb+I+ shmcb small object cache provider"
      "modules/cache/mod_socache_redis+I+redis small object cache provider"
      "modules/cluster/mod_heartbeat+I+Generates Heartbeats"
      "modules/cluster/mod_heartmonitor+I+Collects Heartbeats"
      "modules/core/mod_macro+I+Define and use macros in configuration files"
      "modules/core/mod_watchdog+I+Watchdog module"
      "modules/database/mod_dbd+I+Apache DBD Framework"
      "modules/dav/fs/mod_dav_fs+I+DAV provider for the filesystem."
      "modules/dav/lock/mod_dav_lock+I+DAV provider for generic locking"
      "modules/dav/main/mod_dav+I+WebDAV protocol handling."
      "modules/debugging/mod_bucketeer+O+buckets manipulation filter.  Useful only for developers and testing purposes."
      "modules/debugging/mod_dumpio+I+I/O dump filter"
      "modules/echo/mod_echo+O+ECHO server"
      "modules/examples/mod_case_filter+O+Example uppercase conversion filter"
      "modules/examples/mod_case_filter_in+O+Example uppercase conversion input filter"
      "modules/examples/mod_example_hooks+O+Example hook callback handler module"
      "modules/examples/mod_example_ipc+O+Example of shared memory and mutex usage"
      "modules/filters/mod_brotli+i+Brotli compression support"
      "modules/filters/mod_buffer+I+Filter Buffering"
      "modules/filters/mod_charset_lite+i+character set translation"
      "modules/filters/mod_data+O+RFC2397 data encoder"
      "modules/filters/mod_deflate+i+Deflate transfer encoding support"
      "modules/filters/mod_ext_filter+I+external filter module"
      "modules/filters/mod_filter+A+Smart Filtering"
      "modules/filters/mod_include+I+Server Side Includes"
      "modules/filters/mod_proxy_html+i+Fix HTML Links in a Reverse Proxy"
      "modules/filters/mod_ratelimit+I+Output Bandwidth Limiting"
      "modules/filters/mod_reflector+O+Reflect request through the output filter stack"
      "modules/filters/mod_reqtimeout+A+Limit time waiting for request from client"
      "modules/filters/mod_request+I+Request Body Filtering"
      "modules/filters/mod_sed+I+filter request and/or response bodies through sed"
      "modules/filters/mod_substitute+I+response content rewrite-like filtering"
      "modules/filters/mod_xml2enc+i+i18n support for markup filters"
      "modules/generators/mod_asis+I+as-is filetypes"
      "modules/generators/mod_autoindex+A+directory listing"
      "modules/generators/mod_cgi+I+CGI scripts"
      "modules/generators/mod_info+I+server information"
      "modules/generators/mod_status+I+process/thread monitoring"
      "modules/http/mod_mime+A+mapping of file-extension to MIME.  Disabling this module is normally not recommended."
      "modules/http2/mod_http2+i+HTTP/2 protocol support"
      "modules/ldap/mod_ldap+i+LDAP caching and connection pooling services"
      "modules/loggers/mod_log_config+A+logging configuration.  You won't be able to log requests to the server without this module."
      "modules/loggers/mod_log_debug+I+configurable debug logging"
      "modules/loggers/mod_log_forensic+I+forensic logging"
      "modules/loggers/mod_logio+I+input and output logging"
      "modules/lua/mod_lua+i+Apache Lua Framework"
      "modules/md/mod_md+i+Apache Managed Domains (Certificates)"
      "modules/mappers/mod_actions+I+Action triggering on requests"
      "modules/mappers/mod_alias+A+mapping of requests to different filesystem parts"
      "modules/mappers/mod_dir+A+directory request handling"
      "modules/mappers/mod_imagemap+I+server-side imagemaps"
      "modules/mappers/mod_negotiation+I+content negotiation"
      "modules/mappers/mod_rewrite+I+rule based URL manipulation"
      "modules/mappers/mod_speling+I+correct common URL misspellings"
      "modules/mappers/mod_userdir+I+mapping of requests to user-specific directories"
      "modules/mappers/mod_vhost_alias+I+mass virtual hosting module"
      "modules/metadata/mod_cern_meta+O+CERN-type meta files"
      "modules/metadata/mod_env+A+clearing/setting of ENV vars"
      "modules/metadata/mod_expires+I+Expires header control"
      "modules/metadata/mod_headers+A+HTTP header control"
      "modules/metadata/mod_ident+O+RFC 1413 identity check"
      "modules/metadata/mod_mime_magic+O+automagically determining MIME type"
      "modules/metadata/mod_remoteip+I+translate header contents to an apparent client remote_ip"
      "modules/metadata/mod_setenvif+A+basing ENV vars on headers"
      "modules/metadata/mod_unique_id+I+per-request unique ids"
      "modules/metadata/mod_usertrack+I+user-session tracking"
      "modules/metadata/mod_version+A+determining httpd version in config files"
      "modules/proxy/balancers/mod_lbmethod_bybusyness+I+Apache proxy Load balancing by busyness"
      "modules/proxy/balancers/mod_lbmethod_byrequests+I+Apache proxy Load balancing by request counting"
      "modules/proxy/balancers/mod_lbmethod_bytraffic+I+Apache proxy Load balancing by traffic counting"
      "modules/proxy/balancers/mod_lbmethod_heartbeat+I+Apache proxy Load balancing from Heartbeats"
      "modules/proxy/mod_proxy_ajp+I+Apache proxy AJP module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy_balancer+I+Apache proxy BALANCER module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy+I+Apache proxy module"
      "modules/proxy/mod_proxy_connect+I+Apache proxy CONNECT module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy_express+I+mass reverse-proxy module. Requires --enable-proxy."
      "modules/proxy/mod_proxy_fcgi+I+Apache proxy FastCGI module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy_ftp+I+Apache proxy FTP module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy_http+I+Apache proxy HTTP module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy_hcheck+I+Apache proxy health check module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy_scgi+I+Apache proxy SCGI module.  Requires and is enabled by --enable-proxy."
      "modules/proxy/mod_proxy_wstunnel+I+Apache proxy Websocket Tunnel module.  Requires and is enabled by --enable-proxy."
      "modules/http2/mod_proxy_http2+i+Apache proxy HTTP/2 module.  Requires --enable-proxy."
      "modules/session/mod_session+I+session module"
      "modules/session/mod_session_cookie+I+session cookie module"
      "modules/session/mod_session_crypto+i+session crypto module"
      "modules/session/mod_session_dbd+I+session dbd module"
      "modules/slotmem/mod_slotmem_plain+I+slotmem provider that uses plain memory"
      "modules/slotmem/mod_slotmem_shm+I+slotmem provider that uses shared memory"
      "modules/ssl/mod_ssl+i+SSL/TLS support"
      "modules/test/mod_dialup+O+rate limits static files to dialup modem speeds"
      "modules/test/mod_optional_fn_export+O+example optional function exporter"
      "modules/test/mod_optional_fn_import+O+example optional function importer"
      "modules/test/mod_optional_hook_export+O+example optional hook exporter"
      "modules/test/mod_optional_hook_import+O+example optional hook importer"
    )
    
    # Track which modules actually built have APIs to link against.
    SET(installed_mod_libs_exps)
    
    # Define extra definitions, sources, headers, etc. required by some modules.
    # This could be included in the master list of modules above, though it 
    # certainly would get a lot more unreadable.
    SET(mod_apreq_extra_defines          APREQ_DECLARE_EXPORT)
    SET(mod_apreq_extra_sources          modules/apreq/handle.c)
    SET(mod_apreq_main_source            modules/apreq/filter.c)
    SET(mod_authz_dbd_extra_defines      AUTHZ_DBD_DECLARE_EXPORT)
    SET(mod_authnz_ldap_requires         APR_HAS_LDAP)
    SET(mod_authnz_ldap_extra_libs       mod_ldap)
    SET(mod_cache_extra_defines          CACHE_DECLARE_EXPORT)
    SET(mod_cache_extra_sources
      modules/cache/cache_storage.c      modules/cache/cache_util.c
    )
    SET(mod_cache_install_lib 1)
    SET(mod_cache_disk_extra_libs        mod_cache)
    SET(mod_cache_socache_extra_libs     mod_cache)
    SET(mod_charset_lite_requires        APR_HAS_XLATE)
    SET(mod_dav_extra_defines            DAV_DECLARE_EXPORT)
    SET(mod_dav_extra_sources
      modules/dav/main/liveprop.c        modules/dav/main/props.c
      modules/dav/main/std_liveprop.c    modules/dav/main/providers.c
      modules/dav/main/util.c            modules/dav/main/util_lock.c
    )
    SET(mod_dav_install_lib 1)
    SET(mod_dav_fs_extra_sources
      modules/dav/fs/dbm.c               modules/dav/fs/lock.c
      modules/dav/fs/repos.c
    )
    SET(mod_dav_fs_extra_libs            mod_dav)
    SET(mod_dav_lock_extra_sources       modules/dav/lock/locks.c)
    SET(mod_dav_lock_extra_libs          mod_dav)
    SET(mod_dbd_extra_defines            DBD_DECLARE_EXPORT)
    SET(mod_deflate_requires             ZLIB_FOUND)
    IF(ZLIB_FOUND)
      SET(mod_deflate_extra_includes       ${ZLIB_INCLUDE_DIR})
      SET(mod_deflate_extra_libs           ${ZLIB_LIBRARIES})
    ENDIF()
    SET(mod_brotli_requires              BROTLI_FOUND)
    IF(BROTLI_FOUND)
      SET(mod_brotli_extra_includes        ${BROTLI_INCLUDE_DIR})
      SET(mod_brotli_extra_libs            ${BROTLI_LIBRARIES})
    ENDIF()
    SET(mod_firehose_requires            SOMEONE_TO_MAKE_IT_COMPILE_ON_WINDOWS)
    SET(mod_heartbeat_extra_libs         mod_watchdog)
    SET(mod_http2_requires               NGHTTP2_FOUND)
    SET(mod_http2_extra_defines          ssize_t=long)
    SET(mod_http2_extra_includes         ${NGHTTP2_INCLUDE_DIR})
    SET(mod_http2_extra_libs             ${NGHTTP2_LIBRARIES})
    SET(mod_http2_extra_sources
      modules/http2/h2_bucket_beam.c     modules/http2/h2_bucket_eos.c
      modules/http2/h2_c1.c              modules/http2/h2_c1_io.c
      modules/http2/h2_c2.c              modules/http2/h2_c2_filter.c
      modules/http2/h2_config.c          modules/http2/h2_conn_ctx.c
      modules/http2/h2_mplx.c            modules/http2/h2_headers.c
      modules/http2/h2_protocol.c        modules/http2/h2_push.c
      modules/http2/h2_request.c         modules/http2/h2_session.c
      modules/http2/h2_stream.c          modules/http2/h2_switch.c
      modules/http2/h2_util.c            modules/http2/h2_workers.c
      modules/http2/h2_ws.c
    )
    SET(mod_ldap_extra_defines           LDAP_DECLARE_EXPORT)
    SET(mod_ldap_extra_libs              wldap32)
    SET(mod_ldap_extra_sources
      modules/ldap/util_ldap_cache.c     modules/ldap/util_ldap_cache_mgr.c
    )
    SET(mod_ldap_main_source             modules/ldap/util_ldap.c)
    SET(mod_ldap_requires                APR_HAS_LDAP)
    SET(mod_lua_extra_defines            AP_LUA_DECLARE_EXPORT)
    SET(mod_lua_extra_includes           ${LUA_INCLUDE_DIR})
    SET(mod_lua_extra_libs               ${LUA_LIBRARIES})
    SET(mod_lua_extra_sources
      modules/lua/lua_apr.c              modules/lua/lua_config.c
      modules/lua/lua_passwd.c           modules/lua/lua_request.c
      modules/lua/lua_vmprep.c           modules/lua/lua_dbd.c
    )
    SET(mod_lua_requires                 LUA51_FOUND)
    SET(mod_md_requires                  OPENSSL_FOUND CURL_FOUND JANSSON_FOUND)
    SET(mod_md_extra_includes            ${OPENSSL_INCLUDE_DIR} ${CURL_INCLUDE_DIR} ${JANSSON_INCLUDE_DIR})
    SET(mod_md_extra_libs                ${OPENSSL_LIBRARIES} ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} mod_watchdog)
    SET(mod_md_extra_sources
      modules/md/md_acme.c               modules/md/md_acme_acct.c
      modules/md/md_acme_authz.c         modules/md/md_acme_drive.c
      modules/md/md_acmev2_drive.c       modules/md/md_event.c
      modules/md/md_acme_order.c         modules/md/md_core.c
      modules/md/md_curl.c               modules/md/md_crypt.c
      modules/md/md_http.c               modules/md/md_json.c
      modules/md/md_jws.c                modules/md/md_log.c
      modules/md/md_result.c             modules/md/md_reg.c
      modules/md/md_status.c             modules/md/md_store.c
      modules/md/md_store_fs.c           modules/md/md_time.c
      modules/md/md_ocsp.c               modules/md/md_util.c               
      modules/md/mod_md_config.c         modules/md/mod_md_drive.c
      modules/md/mod_md_os.c             modules/md/mod_md_status.c
      modules/md/mod_md_ocsp.c           modules/md/md_tailscale.c
    )
    SET(mod_optional_hook_export_extra_defines AP_DECLARE_EXPORT) # bogus reuse of core API prefix
    SET(mod_proxy_extra_defines          PROXY_DECLARE_EXPORT)
    SET(mod_proxy_extra_sources          modules/proxy/proxy_util.c)
    SET(mod_proxy_install_lib 1)
    SET(mod_proxy_ajp_extra_sources
      modules/proxy/ajp_header.c         modules/proxy/ajp_link.c
      modules/proxy/ajp_msg.c            modules/proxy/ajp_utils.c
    )
    SET(mod_proxy_ajp_extra_libs         mod_proxy)
    SET(mod_proxy_balancer_extra_libs    mod_proxy)
    SET(mod_proxy_connect_extra_libs     mod_proxy)
    SET(mod_proxy_express_extra_libs     mod_proxy)
    SET(mod_proxy_fcgi_extra_libs        mod_proxy)
    SET(mod_proxy_ftp_extra_libs         mod_proxy)
    SET(mod_proxy_hcheck_extra_libs      mod_proxy)
    SET(mod_proxy_http_extra_libs        mod_proxy)
    SET(mod_proxy_html_requires          LIBXML2_FOUND)
    IF(LIBXML2_FOUND)
      SET(mod_proxy_html_extra_includes    "${LIBXML2_INCLUDE_DIR};${LIBXML2_ICONV_INCLUDE_DIR}")
      SET(mod_proxy_html_extra_libs        "${LIBXML2_LIBRARIES};${LIBXML2_ICONV_LIBRARIES}")
    ENDIF()
    SET(mod_proxy_scgi_extra_libs        mod_proxy)
    SET(mod_proxy_wstunnel_extra_libs    mod_proxy)
    SET(mod_proxy_http2_requires               NGHTTP2_FOUND)
    SET(mod_proxy_http2_extra_defines          ssize_t=long)
    SET(mod_proxy_http2_extra_includes         ${NGHTTP2_INCLUDE_DIR})
    SET(mod_proxy_http2_extra_libs             ${NGHTTP2_LIBRARIES} mod_proxy)
    SET(mod_proxy_http2_extra_sources
      modules/http2/h2_proxy_session.c   modules/http2/h2_proxy_util.c
    )
    SET(mod_ratelimit_extra_defines      AP_RL_DECLARE_EXPORT)
    SET(mod_sed_extra_sources
      modules/filters/regexp.c           modules/filters/sed0.c
      modules/filters/sed1.c
    )
    SET(mod_serf_requires                AN_UNIMPLEMENTED_SUPPORT_LIBRARY_REQUIREMENT)
    SET(mod_session_extra_defines        SESSION_DECLARE_EXPORT)
    SET(mod_session_install_lib 1)
    SET(mod_session_cookie_extra_libs    mod_session)
    SET(mod_session_crypto_requires      APU_HAVE_CRYPTO)
    SET(mod_session_crypto_extra_libs    mod_session)
    SET(mod_session_dbd_extra_libs       mod_session)
    SET(mod_socache_dc_requires          AN_UNIMPLEMENTED_SUPPORT_LIBRARY_REQUIREMENT)
    SET(mod_ssl_extra_defines            SSL_DECLARE_EXPORT)
    SET(mod_ssl_requires                 OPENSSL_FOUND)
    IF(OPENSSL_FOUND)
      SET(mod_ssl_extra_includes           ${OPENSSL_INCLUDE_DIR})
      SET(mod_ssl_extra_libs               ${OPENSSL_LIBRARIES})
    ENDIF()
    SET(mod_ssl_extra_sources
      modules/ssl/ssl_engine_config.c
      modules/ssl/ssl_engine_init.c      modules/ssl/ssl_engine_io.c
      modules/ssl/ssl_engine_kernel.c    modules/ssl/ssl_engine_log.c
      modules/ssl/ssl_engine_mutex.c     modules/ssl/ssl_engine_ocsp.c
      modules/ssl/ssl_engine_pphrase.c   modules/ssl/ssl_engine_rand.c
      modules/ssl/ssl_engine_vars.c      modules/ssl/ssl_scache.c
      modules/ssl/ssl_util.c             modules/ssl/ssl_util_ocsp.c
      modules/ssl/ssl_util_ssl.c         modules/ssl/ssl_util_stapling.c
    )
    SET(mod_status_extra_defines         STATUS_DECLARE_EXPORT)
    SET(mod_watchdog_install_lib 1)
    SET(mod_xml2enc_requires             LIBXML2_FOUND)
    IF(LIBXML2_FOUND)
      SET(mod_xml2enc_extra_includes     "${LIBXML2_INCLUDE_DIR};${LIBXML2_ICONV_INCLUDE_DIR}")
      SET(mod_xml2enc_extra_libs         "${LIBXML2_LIBRARIES};${LIBXML2_ICONV_LIBRARIES}")
    ENDIF()
    SET(mod_watchdog_extra_defines       AP_WD_DECLARE_EXPORT)
    
    SET(MODULE_PATHS)
    FOREACH (modinfo ${MODULE_LIST})
      STRING(REGEX REPLACE "([^+]*)\\+([^+]*)\\+([^+]*)" "\\1;\\2;\\3" modinfolist ${modinfo})
      SET(path_to_module)
      SET(defaultenable)
      SET(helptext)
      FOREACH(i ${modinfolist})
        IF("${path_to_module}" STREQUAL "")
          SET(path_to_module ${i})
        ELSEIF("${defaultenable}" STREQUAL "")
          SET(defaultenable ${i})
        ELSEIF("${helptext}" STREQUAL "")
          SET(helptext ${i})
        ELSE()
          MESSAGE(FATAL_ERROR "Unexpected field or plus sign in >${modinfo}<")
        ENDIF()
      ENDFOREACH()
    
      # MESSAGE("       path to module: ${path_to_module}")
      # MESSAGE("enablement by default: ${defaultenable}")
      # MESSAGE("            help text: ${helptext}")
    
      STRING(REGEX REPLACE ".*/(mod_[^\\+]+)" "\\1" mod_name       ${path_to_module})
      STRING(REGEX REPLACE "mod_(.*)"         "\\1" mod_shortname  ${mod_name})
    
      STRING(TOUPPER "ENABLE_${mod_shortname}" mod_option_name)
    
      SET(${mod_option_name} ${defaultenable} CACHE STRING ${helptext})
      SET(MODULE_PATHS "${MODULE_PATHS};${path_to_module}")
    
    ENDFOREACH()
    
    SET(install_targets)
    SET(install_bin_pdb)
    SET(install_modules) # special handling vs. other installed targets
    SET(install_modules_pdb)
    SET(builtin_module_shortnames)
    LIST(APPEND builtin_module_shortnames "win32" "mpm_winnt" "http" "so") # core added automatically
    SET(extra_builtin_modules) # the ones specified with -DWITH_MODULES=
    
    STRING(REPLACE "," ";" WITH_MODULE_LIST "${WITH_MODULES}")
    FOREACH(static_mod ${WITH_MODULE_LIST})
      STRING(REGEX MATCH   "[^/]+\\.c"           mod_basename    ${static_mod})
      STRING(REGEX REPLACE "^mod_(.*)\\.c" "\\1" mod_module_name ${mod_basename})
      LIST(APPEND builtin_module_shortnames "${mod_module_name}")
      CONFIGURE_FILE(${static_mod} ${PROJECT_BINARY_DIR}/ COPYONLY)
      SET(extra_builtin_modules ${extra_builtin_modules} ${PROJECT_BINARY_DIR}/${mod_basename})
    ENDFOREACH()
    
    generate_builtin_modules_c("${PROJECT_BINARY_DIR}/modules.c" "${builtin_module_shortnames}")
    
    # for easy reference from .dll/.so builds
    CONFIGURE_FILE(os/win32/BaseAddr.ref ${PROJECT_BINARY_DIR}/ COPYONLY)
    
    ADD_EXECUTABLE(gen_test_char server/gen_test_char.c)
    ADD_CUSTOM_COMMAND(
      COMMENT "Generating character tables, test_char.h, for current locale"
      DEPENDS gen_test_char
      COMMAND $<TARGET_FILE:gen_test_char> > ${PROJECT_BINARY_DIR}/test_char.h
      OUTPUT ${PROJECT_BINARY_DIR}/test_char.h
    )
    ADD_CUSTOM_TARGET(
      test_char_header ALL
      DEPENDS ${PROJECT_BINARY_DIR}/test_char.h
    )
    
    SET(HTTPD_MAIN_SOURCES
      server/main.c
    )
    
    SET(LIBHTTPD_SOURCES
      ${extra_builtin_modules}
      ${PROJECT_BINARY_DIR}/modules.c
      modules/arch/win32/mod_win32.c
      modules/core/mod_so.c
      modules/http/byterange_filter.c
      modules/http/chunk_filter.c
      modules/http/http_core.c
      modules/http/http_etag.c
      modules/http/http_filters.c
      modules/http/http_protocol.c
      modules/http/http_request.c
      os/win32/ap_regkey.c
      os/win32/util_win32.c
      server/buildmark.c
      server/config.c
      server/connection.c
      server/core.c
      server/core_filters.c
      server/eoc_bucket.c
      server/eor_bucket.c
      server/error_bucket.c
      server/listen.c
      server/log.c
      server/mpm/winnt/child.c
      server/mpm/winnt/mpm_winnt.c
      server/mpm/winnt/nt_eventlog.c
      server/mpm/winnt/service.c
      server/mpm_common.c
      server/protocol.c
      server/provider.c
      server/request.c
      server/ssl.c
      server/scoreboard.c
      server/util.c
      server/util_cfgtree.c
      server/util_cookies.c
      server/util_debug.c
      server/util_expr_eval.c
      server/util_expr_parse.c
      server/util_fcgi.c
      server/util_expr_scan.c
      server/util_filter.c
      server/util_md5.c
      server/util_mutex.c
      server/util_pcre.c
      server/util_regex.c
      server/util_script.c
      server/util_time.c
      server/util_xml.c
      server/vhost.c
    )
    
    CONFIGURE_FILE(os/win32/win32_config_layout.h
                   ${PROJECT_BINARY_DIR}/ap_config_layout.h)
    
    SET(HTTPD_INCLUDE_DIRECTORIES
      ${PROJECT_BINARY_DIR}
      ${EXTRA_INCLUDES}
      # see discussion in cmake bug 13188 regarding oddities with relative paths
      ${CMAKE_CURRENT_SOURCE_DIR}/include
      ${CMAKE_CURRENT_SOURCE_DIR}/os/win32
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/core
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/database
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/dav/main
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/filters
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/generators
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/http2
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/md
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/proxy
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/session
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/ssl
      ${CMAKE_CURRENT_SOURCE_DIR}/server
      ${CMAKE_CURRENT_SOURCE_DIR}/server/mpm/winnt
      ${APR_INCLUDE_DIR}
      ${PCRE_INCLUDE_DIR}
    )
    
    # The .h files we install from outside the main include directory
    # largely parallel the include directories above.
    SET(other_installed_h
      ${PROJECT_BINARY_DIR}/ap_config_layout.h
      ${CMAKE_CURRENT_SOURCE_DIR}/os/win32/os.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/cache/mod_cache.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/cache/cache_common.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/core/mod_so.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/core/mod_watchdog.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/database/mod_dbd.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/dav/main/mod_dav.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/filters/mod_include.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/filters/mod_xml2enc.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/generators/mod_cgi.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/generators/mod_status.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/http2/mod_http2.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/loggers/mod_log_config.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/mappers/mod_rewrite.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/proxy/mod_proxy.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/session/mod_session.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/ssl/mod_ssl.h
      ${CMAKE_CURRENT_SOURCE_DIR}/modules/ssl/mod_ssl_openssl.h
    )
    # When mod_serf is buildable, don't forget to copy modules/proxy/mod_serf.h
    
    INCLUDE_DIRECTORIES(${HTTPD_INCLUDE_DIRECTORIES})
    
    SET(HTTPD_SYSTEM_LIBS
      ws2_32
      mswsock
    )
    
    ###########   HTTPD MODULES     ############
    SET(LoadModules)
    SET(mods_built_and_loaded)
    SET(mods_built_but_not_loaded)
    SET(mods_omitted)
    FOREACH (mod ${MODULE_PATHS})
      # Build different forms of the module name; e.g., 
      #   mod_name->mod_cgi, mod_module_name->cgi_module, mod_shortname->cgi
      STRING(REGEX REPLACE ".*/(mod_[^\\+]+)" "\\1"        mod_name        ${mod})
      STRING(REGEX REPLACE "mod_(.*)"         "\\1_module" mod_module_name ${mod_name})
      STRING(REGEX REPLACE "mod_(.*)"         "\\1"        mod_shortname   ${mod_name})
    
      # Is it enabled?
      STRING(TOUPPER "ENABLE_${mod_shortname}" enable_mod)
      SET(enable_mod_val ${${enable_mod}})
    
      # Is ENABLE_MODULES set to a higher value?
      GET_MOD_ENABLE_RANK(${mod_name} ${enable_mod_val} this_mod_rank)
      IF(this_mod_rank LESS enable_modules_rank)
        # Use the value from ENABLE_MODULES
        SET(enable_mod_val ${ENABLE_MODULES})
      ENDIF()
    
      IF(NOT ${enable_mod_val} STREQUAL "O") # build of module is desired
        SET(mod_requires "${mod_name}_requires")
        STRING(TOUPPER ${enable_mod_val} enable_mod_val_upper)
        IF(NOT "${${mod_requires}}" STREQUAL "") # module has some prerequisite
          FOREACH (required ${${mod_requires}})
            IF(NOT ${required}) # prerequisite doesn't exist
              IF(NOT ${enable_mod_val} STREQUAL ${enable_mod_val_upper}) # lower case, so optional based on prereq
                MESSAGE(STATUS "${mod_name} was requested but couldn't be built due to a missing prerequisite (${required})")
                SET(enable_mod_val_upper "O") # skip due to missing prerequisite
              ELSE() # must be upper case "A" or "I" (or coding error above)
                MESSAGE(FATAL_ERROR "${mod_name} was requested but couldn't be built due to a missing prerequisite (${required})")
              ENDIF()
            ENDIF()
          ENDFOREACH()
        ENDIF()
        # map a->A, i->I, O->O for remaining logic since prereq checking is over
        SET(enable_mod_val ${enable_mod_val_upper})
      ENDIF()
      
      IF(${enable_mod_val} STREQUAL "O")
        # ignore
        SET(mods_omitted ${mods_omitted} ${mod_name})
      ELSE()
        # Handle whether or not the LoadModule is commented out.
        IF(${enable_mod_val} STREQUAL "A")
          SET(LoadModules "${LoadModules}LoadModule ${mod_module_name} modules/${mod_name}.so\n")
          SET(mods_built_and_loaded ${mods_built_and_loaded} ${mod_name})
        ELSEIF(${enable_mod_val} STREQUAL "I")
          SET(LoadModules "${LoadModules}# LoadModule ${mod_module_name} modules/${mod_name}.so\n")
          SET(mods_built_but_not_loaded ${mods_built_but_not_loaded} ${mod_name})
        ELSE()
          MESSAGE(FATAL_ERROR "${enable_mod} must be set to \"A\", \"I\", or \"O\" instead of \"${enable_mod_val}\"")
        ENDIF()
    
        # Handle building it.
        SET(mod_main_source "${mod_name}_main_source")
        SET(mod_extra_sources "${mod_name}_extra_sources")
    
        IF("${${mod_main_source}}" STREQUAL "")
          SET(tmp_mod_main_source "${mod}.c")
        ELSE()
          SET(tmp_mod_main_source ${${mod_main_source}})
        ENDIF()
        SET(all_mod_sources ${tmp_mod_main_source} ${${mod_extra_sources}})
        ADD_LIBRARY(${mod_name} SHARED ${all_mod_sources} build/win32/httpd.rc)
        SET(install_modules ${install_modules} ${mod_name})
        SET(install_modules_pdb ${install_modules_pdb} "$<TARGET_PDB_FILE:${mod_name}>")
        IF("${${mod_name}_install_lib}")
          SET(installed_mod_libs_exps
              ${installed_mod_libs_exps}
              "$<TARGET_LINKER_FILE:${mod_name}>"
              "$<TARGET_LINKER_FILE_DIR:${mod_name}>/${mod_name}.exp"
          )
        ENDIF()
        SET(mod_extra_libs "${mod_name}_extra_libs")
        SET_TARGET_PROPERTIES(${mod_name} PROPERTIES
          SUFFIX .so
          LINK_FLAGS /base:@${PROJECT_BINARY_DIR}/BaseAddr.ref,${mod_name}.so
        )
        TARGET_LINK_LIBRARIES(${mod_name} ${${mod_extra_libs}} libhttpd ${EXTRA_LIBS} ${APR_LIBRARIES} ${HTTPD_SYSTEM_LIBS})
        DEFINE_WITH_BLANKS(define_long_name "LONG_NAME" "${mod_name} for Apache HTTP Server")
        SET_TARGET_PROPERTIES(${mod_name} PROPERTIES COMPILE_FLAGS "${define_long_name} -DBIN_NAME=${mod_name}.so ${EXTRA_COMPILE_FLAGS}")
    
        # Extra defines?
        SET(mod_extra_defines "${mod_name}_extra_defines")
        IF(NOT ${${mod_extra_defines}} STREQUAL "")
          SET_TARGET_PROPERTIES(${mod_name} PROPERTIES COMPILE_DEFINITIONS ${${mod_extra_defines}})
        ENDIF()
    
        # Extra includes?
        SET(mod_extra_includes "${mod_name}_extra_includes")
        IF(NOT "${${mod_extra_includes}}" STREQUAL "")
          SET(tmp_includes ${HTTPD_INCLUDE_DIRECTORIES} ${${mod_extra_includes}})
          SET_TARGET_PROPERTIES(${mod_name} PROPERTIES INCLUDE_DIRECTORIES "${tmp_includes}")
          GET_PROPERTY(tmp_includes TARGET ${mod_name} PROPERTY INCLUDE_DIRECTORIES)
        ENDIF()
    
      ENDIF()
    ENDFOREACH()
    
    ###########   HTTPD LIBRARIES   ############
    ADD_LIBRARY(libhttpd SHARED ${LIBHTTPD_SOURCES} build/win32/httpd.rc)
    SET_TARGET_PROPERTIES(libhttpd PROPERTIES
      LINK_FLAGS /base:@${PROJECT_BINARY_DIR}/BaseAddr.ref,libhttpd.dll
    )
    SET(install_targets ${install_targets} libhttpd)
    SET(install_bin_pdb ${install_bin_pdb} $<TARGET_PDB_FILE:libhttpd>)
    TARGET_LINK_LIBRARIES(libhttpd ${EXTRA_LIBS} ${APR_LIBRARIES} ${PCRE_LIBRARIES} ${HTTPD_SYSTEM_LIBS})
    DEFINE_WITH_BLANKS(define_long_name "LONG_NAME" "Apache HTTP Server Core")
    SET_TARGET_PROPERTIES(libhttpd PROPERTIES COMPILE_FLAGS "-DAP_DECLARE_EXPORT ${define_long_name} ${PCRE_CFLAGS} -DBIN_NAME=libhttpd.dll ${EXTRA_COMPILE_FLAGS}")
    ADD_DEPENDENCIES(libhttpd test_char_header)
    
    ###########   HTTPD EXECUTABLES   ##########
    ADD_EXECUTABLE(httpd server/main.c build/win32/httpd.rc)
    SET(install_targets ${install_targets} httpd)
    SET(install_bin_pdb ${install_bin_pdb} $<TARGET_PDB_FILE:httpd>)
    DEFINE_WITH_BLANKS(define_long_name "LONG_NAME" "Apache HTTP Server")
    SET_TARGET_PROPERTIES(httpd PROPERTIES COMPILE_FLAGS "-DAPP_FILE ${define_long_name} -DBIN_NAME=httpd.exe -DICON_FILE=${CMAKE_SOURCE_DIR}/build/win32/apache.ico ${EXTRA_COMPILE_FLAGS}")
    TARGET_LINK_LIBRARIES(httpd libhttpd ${EXTRA_LIBS})
    
    SET(standard_support
      ab
      htcacheclean
      htdbm
      htdigest
      htpasswd
      httxt2dbm
      logresolve
      rotatelogs
    )
    
    SET(htdbm_extra_sources support/passwd_common.c)
    SET(htpasswd_extra_sources support/passwd_common.c)
    
    FOREACH(pgm ${standard_support})
      SET(extra_sources ${pgm}_extra_sources)
      ADD_EXECUTABLE(${pgm} support/${pgm}.c ${${extra_sources}} build/win32/httpd.rc)
      SET(install_targets ${install_targets} ${pgm})
      SET(install_bin_pdb ${install_bin_pdb} $<TARGET_PDB_FILE:${pgm}>)
      DEFINE_WITH_BLANKS(define_long_name "LONG_NAME" "Apache HTTP Server ${pgm} program")
      SET_TARGET_PROPERTIES(${pgm} PROPERTIES COMPILE_FLAGS "-DAPP_FILE ${define_long_name} -DBIN_NAME=${pgm}.exe ${EXTRA_COMPILE_FLAGS}")
      TARGET_LINK_LIBRARIES(${pgm} ${EXTRA_LIBS} ${APR_LIBRARIES})
    ENDFOREACH()
    
    IF(OPENSSL_FOUND)
      ADD_EXECUTABLE(abs support/ab.c build/win32/httpd.rc)
      SET(install_targets ${install_targets} abs)
      SET(install_bin_pdb ${install_bin_pdb} $<TARGET_PDB_FILE:abs>)
      SET_TARGET_PROPERTIES(abs PROPERTIES COMPILE_DEFINITIONS HAVE_OPENSSL)
      SET(tmp_includes ${HTTPD_INCLUDE_DIRECTORIES} ${OPENSSL_INCLUDE_DIR})
      SET_TARGET_PROPERTIES(abs PROPERTIES INCLUDE_DIRECTORIES "${tmp_includes}")
      DEFINE_WITH_BLANKS(define_long_name "LONG_NAME" "Apache HTTP Server ab/SSL program")
      SET_TARGET_PROPERTIES(abs PROPERTIES COMPILE_FLAGS "-DAPP_FILE ${define_long_name} -DBIN_NAME=abs.exe ${EXTRA_COMPILE_FLAGS}")
      TARGET_LINK_LIBRARIES(abs ${EXTRA_LIBS} ${APR_LIBRARIES} ${OPENSSL_LIBRARIES})
    ENDIF()
    GET_PROPERTY(tmp_includes TARGET ab PROPERTY INCLUDE_DIRECTORIES)
    
    # getting duplicate manifest error with ApacheMonitor
    # ADD_EXECUTABLE(ApacheMonitor support/win32/ApacheMonitor.c support/win32/ApacheMonitor.rc)
    # SET(install_targets ${install_targets} ApacheMonitor)
    # SET(install_bin_pdb ${install_bin_pdb} $<TARGET_PDB_FILE:ApacheMonitor>)
    # SET_TARGET_PROPERTIES(ApacheMonitor PROPERTIES WIN32_EXECUTABLE TRUE)
    # SET_TARGET_PROPERTIES(ApacheMonitor PROPERTIES COMPILE_FLAGS "-DAPP_FILE -DLONG_NAME=ApacheMonitor -DBIN_NAME=ApacheMonitor.exe ${EXTRA_COMPILE_FLAGS}")
    # TARGET_LINK_LIBRARIES(ApacheMonitor ${EXTRA_LIBS} ${HTTPD_SYSTEM_LIBS} comctl32 wtsapi32)
    
    ###########  CONFIGURATION FILES ###########
    # Set up variables used in the .conf file templates
    SET(LoadModule          "${LoadModules}")
    SET(Port                "80" CACHE STRING "http port to listen on")
    SET(SSLPort             "443" CACHE STRING "https port to listen on")
    SET(ServerRoot          "${CMAKE_INSTALL_PREFIX}")
    SET(exp_cgidir          "${CMAKE_INSTALL_PREFIX}/cgi-bin")
    SET(exp_htdocsdir       "${CMAKE_INSTALL_PREFIX}/htdocs")
    SET(exp_iconsdir        "${CMAKE_INSTALL_PREFIX}/icons")
    SET(exp_errordir        "${CMAKE_INSTALL_PREFIX}/error")
    SET(exp_manualdir       "${CMAKE_INSTALL_PREFIX}/manual")
    SET(rel_logfiledir      "logs")
    SET(rel_runtimedir      "logs")
    SET(rel_sysconfdir      "conf")
    FILE(GLOB_RECURSE conffiles RELATIVE ${CMAKE_SOURCE_DIR}/docs/conf "docs/conf/*")
    FOREACH(template ${conffiles})
      STRING(REPLACE ".conf.in" ".conf" conf ${template})
      FILE(READ "docs/conf/${template}" template_text)
        IF(template MATCHES ".conf.in$")
          # substitute @var@/@@var@@ in .conf.in
          STRING(REPLACE "@@" "@" template_text ${template_text})
          STRING(CONFIGURE "${template_text}" template_text @ONLY)
        ENDIF()
      FILE(WRITE ${CMAKE_BINARY_DIR}/conf/original/${conf} "${template_text}")
      FILE(WRITE ${CMAKE_BINARY_DIR}/conf/${conf} "${template_text}")
    ENDFOREACH()
    
    ###########   INSTALLATION   ###########
    INSTALL(TARGETS ${install_targets}
            RUNTIME DESTINATION bin
            LIBRARY DESTINATION lib
            ARCHIVE DESTINATION lib
           )
    INSTALL(TARGETS ${install_modules}
            RUNTIME DESTINATION modules
           )
    
    IF(INSTALL_PDB)
      INSTALL(FILES ${install_bin_pdb}
              DESTINATION bin
              CONFIGURATIONS RelWithDebInfo Debug)
    
      INSTALL(FILES ${install_modules_pdb}
              DESTINATION modules
              CONFIGURATIONS RelWithDebInfo Debug)
    ENDIF()
    
    INSTALL(DIRECTORY include/ DESTINATION include
        FILES_MATCHING PATTERN "*.h"
    )
    INSTALL(FILES ${other_installed_h} DESTINATION include)
    INSTALL(FILES ${installed_mod_libs_exps} DESTINATION lib)
    INSTALL(FILES "$<TARGET_LINKER_FILE_DIR:libhttpd>/libhttpd.exp" DESTINATION LIB)
    
    IF(INSTALL_MANUAL) # Silly?  This takes a while, and a dev doesn't need it.
      INSTALL(DIRECTORY docs/manual/ DESTINATION manual)
    ENDIF()
    
    INSTALL(DIRECTORY DESTINATION logs)
    INSTALL(DIRECTORY DESTINATION cgi-bin)
    
    INSTALL(CODE "EXECUTE_PROCESS(COMMAND perl \"${CMAKE_CURRENT_SOURCE_DIR}/build/cpR_noreplace.pl\" \"${CMAKE_CURRENT_SOURCE_DIR}/docs/error\" \"${CMAKE_INSTALL_PREFIX}/error\" ifdestmissing)")
    
    INSTALL(CODE "EXECUTE_PROCESS(COMMAND perl \"${CMAKE_CURRENT_SOURCE_DIR}/build/cpR_noreplace.pl\" \"${CMAKE_CURRENT_SOURCE_DIR}/docs/docroot\" \"${CMAKE_INSTALL_PREFIX}/htdocs\" ifdestmissing)")
    
    INSTALL(CODE "EXECUTE_PROCESS(COMMAND perl \"${CMAKE_CURRENT_SOURCE_DIR}/build/cpR_noreplace.pl\" \"${CMAKE_CURRENT_SOURCE_DIR}/docs/icons\" \"${CMAKE_INSTALL_PREFIX}/icons\" ifdestmissing)")
    
    # Copy generated .conf files from the build directory to the install,
    # without overwriting stuff already there.
    INSTALL(CODE "EXECUTE_PROCESS(COMMAND perl \"${CMAKE_CURRENT_SOURCE_DIR}/build/cpR_noreplace.pl\" \"${CMAKE_BINARY_DIR}/conf\" \"${CMAKE_INSTALL_PREFIX}/conf\")")
    # But conf/original is supposed to be overwritten.
    # Note: FILE(TO_NATIVE_PATH ...) leaves the backslashes unescaped, which
    #       generates warnings.  Just do it manually since this build only supports
    #       Windows anyway.
    STRING(REPLACE "/" "\\\\" native_src ${CMAKE_BINARY_DIR}/conf/original)
    STRING(REPLACE "/" "\\\\" native_dest ${CMAKE_INSTALL_PREFIX}/conf/original)
    INSTALL(CODE "EXECUTE_PROCESS(COMMAND xcopy \"${native_src}\" \"${native_dest}\" /Q /S /Y)")
    
    STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype)
    MESSAGE(STATUS "")
    MESSAGE(STATUS "")
    MESSAGE(STATUS "Apache httpd configuration summary:")
    MESSAGE(STATUS "")
    MESSAGE(STATUS "  Build type ...................... : ${CMAKE_BUILD_TYPE}")
    MESSAGE(STATUS "  Install .pdb (if available)...... : ${INSTALL_PDB}")
    MESSAGE(STATUS "  Install manual .................. : ${INSTALL_MANUAL}")
    MESSAGE(STATUS "  Install prefix .................. : ${CMAKE_INSTALL_PREFIX}")
    MESSAGE(STATUS "  C compiler ...................... : ${CMAKE_C_COMPILER}")
    MESSAGE(STATUS "  APR include directory ........... : ${APR_INCLUDE_DIR}")
    MESSAGE(STATUS "  APR libraries ................... : ${APR_LIBRARIES}")
    MESSAGE(STATUS "  OpenSSL include directory ....... : ${OPENSSL_INCLUDE_DIR}")
    MESSAGE(STATUS "  OpenSSL libraries ............... : ${OPENSSL_LIBRARIES}")
    MESSAGE(STATUS "  PCRE include directory .......... : ${PCRE_INCLUDE_DIR}")
    MESSAGE(STATUS "  PCRE libraries .................. : ${PCRE_LIBRARIES}")
    MESSAGE(STATUS "  libxml2 iconv prereq include dir. : ${LIBXML2_ICONV_INCLUDE_DIR}")
    MESSAGE(STATUS "  libxml2 iconv prereq libraries .. : ${LIBXML2_ICONV_LIBRARIES}")
    MESSAGE(STATUS "  Brotli include directory......... : ${BROTLI_INCLUDE_DIR}")
    MESSAGE(STATUS "  Brotli libraries ................ : ${BROTLI_LIBRARIES}")
    MESSAGE(STATUS "  Curl include directory........... : ${CURL_INCLUDE_DIR}")
    MESSAGE(STATUS "  Curl libraries .................. : ${CURL_LIBRARIES}")
    MESSAGE(STATUS "  Jansson include directory ....... : ${JANSSON_INCLUDE_DIR}")
    MESSAGE(STATUS "  Jansson libraries ............... : ${JANSSON_LIBRARIES}")
    MESSAGE(STATUS "  Extra include directories ....... : ${EXTRA_INCLUDES}")
    MESSAGE(STATUS "  Extra compile flags ............. : ${EXTRA_COMPILE_FLAGS}")
    MESSAGE(STATUS "  Extra libraries ................. : ${EXTRA_LIBS}")
    
    MESSAGE(STATUS "  Modules built and loaded:")
    FOREACH(mod ${mods_built_and_loaded})
      MESSAGE(STATUS "    ${mod}")
    ENDFOREACH()
    
    MESSAGE(STATUS "  Modules built but not loaded:")
    FOREACH(mod ${mods_built_but_not_loaded})
      MESSAGE(STATUS "    ${mod}")
    ENDFOREACH()
    
    MESSAGE(STATUS "  Modules not built:")
    FOREACH(mod ${mods_omitted})
      MESSAGE(STATUS "    ${mod}")
    ENDFOREACH()
    �������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/.github/�������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014175� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/.github/workflows/���������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�016232� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/.github/workflows/windows.yml����������������������������������������������������������0000664�0001751�0001751�00000004064�14653662072�020453� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������name: Windows
    
    on:
      push:
        branches: [ "*" ]
        paths-ignore:
          - 'docs/**'
          - STATUS
          - CHANGES
          - changes-entries/*
      pull_request:
        branches: [ "trunk", "2.4.x" ]
        paths-ignore:
          - 'docs/**'
          - STATUS
          - CHANGES
          - changes-entries/*
    
    jobs:
      build:
        strategy:
          fail-fast: false
          matrix:
            include:
              - name: Default
                triplet: x64-windows
                arch: x64
                build-type: Debug
                generator: "Ninja"
    
        runs-on: windows-latest
        timeout-minutes: 30
        name: ${{ matrix.name }}
        env: 
          VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
        steps:
          - name: Export GitHub Actions cache environment variables
            uses: actions/github-script@v7
            with:
              script: |
                  core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
                  core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
    
          - name: Install dependencies
            run: vcpkg install --triplet ${{ matrix.triplet }} apr[private-headers] apr-util pcre2 openssl
    
          - uses: actions/checkout@v3
    
          - name: Configure CMake
            shell: cmd
            run: |
                call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=${{ matrix.arch }}
                cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} ^
                    -G "${{ matrix.generator }}" ^
                    -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake ^
                    -DAPR_INCLUDE_DIR=C:/vcpkg/installed/${{ matrix.triplet }}/include ^
                    "-DAPR_LIBRARIES=C:/vcpkg/installed/${{ matrix.triplet }}/lib/libapr-1.lib;C:/vcpkg/installed/${{ matrix.triplet }}/lib/libaprutil-1.lib"
    
          - name: Build
            shell: cmd
            run: |
                call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=${{ matrix.arch }}
                cmake --build ${{github.workspace}}/build --config ${{ matrix.build-type }}
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/.github/workflows/linux.yml������������������������������������������������������������0000664�0001751�0001751�00000031437�14775515021�020120� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������name: Linux
    
    on:
      push:
        branches: [ "*" ]
        paths-ignore:
          - 'docs/**'
          - STATUS
          - CHANGES
          - changes-entries/*
        tags:
          - 2.*
      pull_request:
        branches: [ "trunk", "2.4.x" ]
        paths-ignore:
          - 'docs/**'
          - STATUS
          - CHANGES
          - changes-entries/*
    
    env:
      MARGS: "-j2"
      CFLAGS: "-g"
      # This will need updating as the ubuntu-latest image changes:
      PHP_FPM: "/usr/sbin/php-fpm8.1"
    
    jobs:
      build:
        strategy:
          fail-fast: false
          matrix:
            include:
              # -------------------------------------------------------------------------
              - name: Empty APLOGNO() test
                env: |
                  SKIP_TESTING=1
                  TEST_LOGNO=1
              # -------------------------------------------------------------------------
              - name: Default
              # -------------------------------------------------------------------------
              - name: All-static modules
                config: --enable-mods-static=reallyall
              # -------------------------------------------------------------------------
              - name: Prefork MPM, all-modules (except cgid)
                config: --enable-mods-shared=reallyall --with-mpm=prefork --disable-cgid
              # -------------------------------------------------------------------------
              - name: Worker MPM, all-modules
                config: --enable-mods-shared=reallyall --with-mpm=worker
              # -------------------------------------------------------------------------
              - name: Shared MPMs, all-modules
                config: --enable-mods-shared=reallyall --enable-mpms-shared=all
              # -------------------------------------------------------------------------
              - name: Event MPM, all-modules, mod_cgid fdpassing
                config: --enable-mods-shared=reallyall --with-mpm=event --disable-cgi --enable-cgid-fdpassing
              # -------------------------------------------------------------------------
              - name: Shared MPMs, all-modules, 64-bit ARM
                config: --enable-mods-shared=reallyall --enable-mpms-shared=all
                os: ubuntu-24.04-arm
              # -------------------------------------------------------------------------
              - name: Event MPM, all-modules, mod_cgid w/o fdpassing
                config: --enable-mods-shared=reallyall --with-mpm=event --disable-cgi
              # -------------------------------------------------------------------------
              - name: Default, all-modules + install
                config: --enable-mods-shared=reallyall
                env: |
                  TEST_INSTALL=1
                  APACHE_TEST_EXTRA_ARGS=-v
              # -------------------------------------------------------------------------
              - name: Default, all-modules, random test order
                config: --enable-mods-shared=reallyall
                env: |
                  TEST_ARGS=-order=random
              # -------------------------------------------------------------------------
              - name: GCC 12 maintainer-mode w/-Werror, install + VPATH
                config: --enable-mods-shared=reallyall --enable-maintainer-mode
                notest-cflags: -Werror -O2
                env: |
                  CC=gcc-12
                  TEST_VPATH=1
                  TEST_INSTALL=1
                  SKIP_TESTING=1
              # -------------------------------------------------------------------------
              - name: All-modules, APR 1.7.4, APR-util 1.6.3
                config: --enable-mods-shared=reallyall
                env: |
                  APR_VERSION=1.7.4
                  APU_VERSION=1.6.3
                  APU_CONFIG="--with-crypto --with-ldap"
              # -------------------------------------------------------------------------
              - name: APR 1.8.x, APR-util 1.7.x
                config: --enable-mods-shared=reallyall
                env: |
                  APR_VERSION=1.8.x
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              - name: Pool-debug
                config: --enable-mods-shared=reallyall
                env: |
                  APR_VERSION=1.7.x
                  APR_CONFIG="--enable-pool-debug"
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_MALLOC=1
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              - name: Shared MPMs (event), pool-debug, SSL/TLS variants
                config: --enable-mods-shared=reallyall --enable-mpms-shared=all --with-mpm=event
                env: |
                  APR_VERSION=1.7.x
                  APR_CONFIG="--enable-pool-debug"
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_MALLOC=1
                  TEST_SSL=1
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              - name: Shared MPMs (worker), pool-debug, SSL/TLS variants
                config: --enable-mods-shared=reallyall --enable-mpms-shared=all --with-mpm=worker
                env: |
                  APR_VERSION=1.7.x
                  APR_CONFIG="--enable-pool-debug"
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_MALLOC=1
                  TEST_SSL=1
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              - name: Shared MPMs (prefork), pool-debug, SSL/TLS variants
                config: --enable-mods-shared=reallyall --enable-mpms-shared=all --with-mpm=prefork
                env: |
                  APR_VERSION=1.7.x
                  APR_CONFIG="--enable-pool-debug"
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_MALLOC=1
                  TEST_SSL=1
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              - name: litmus WebDAV tests
                config: --enable-dav --enable-dav-fs
                env: |
                  LITMUS=1
                  TESTS="t/modules/dav.t"
                pkgs: litmus
              # -------------------------------------------------------------------------
              - name: APR 1.7.4, APR-util 1.6.3, LDAP
                config: --enable-mods-shared=reallyall
                pkgs: ldap-utils
                env: |
                  APR_VERSION=1.7.4
                  APU_VERSION=1.6.3
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_MALLOC=1
                  TEST_LDAP=1
                  TEST_ARGS="-defines LDAP"
                  TESTS="t/modules/"
              # -------------------------------------------------------------------------
              - name: APR 1.7.x, APR-util 1.7.x, LDAP
                config: --enable-mods-shared=reallyall
                pkgs: ldap-utils
                env: |
                  APR_VERSION=1.7.x
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_MALLOC=1
                  TEST_LDAP=1
                  TEST_ARGS="-defines LDAP"
                  TESTS="t/modules/"
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              ### TODO: if: *condition_not_24x
              - name: APR trunk thread debugging
                config: --enable-mods-shared=reallyall --with-mpm=event
                env: |
                  APR_VERSION=trunk
                  APR_CONFIG="--with-crypto --enable-thread-debug"
              # -------------------------------------------------------------------------
              - name: ASan
                notest-cflags: -ggdb -fsanitize=address -fno-sanitize-recover=address -fno-omit-frame-pointer
                config: --enable-mods-shared=reallyall
                env: |
                  APR_VERSION=1.7.x
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_ASAN=1
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              - name: ASan, pool-debug
                notest-cflags: -ggdb -fsanitize=address -fno-sanitize-recover=address -fno-omit-frame-pointer
                config: --enable-mods-shared=reallyall
                env: |
                  APR_VERSION=1.7.x
                  APR_CONFIG="--enable-pool-debug"
                  APU_VERSION=1.7.x
                  APU_CONFIG="--with-crypto --with-ldap"
                  TEST_ASAN=1
                  CLEAR_CACHE=1
              # -------------------------------------------------------------------------
              - name: HTTP/2 test suite
                config: --enable-mods-shared=reallyall --with-mpm=event --enable-mpms-shared=all
                pkgs: curl python3-pytest nghttp2-client python3-cryptography python3-requests python3-multipart python3-filelock python3-websockets
                env: |
                  APR_VERSION=1.7.4
                  APU_VERSION=1.6.3
                  APU_CONFIG="--with-crypto"
                  NO_TEST_FRAMEWORK=1
                  TEST_INSTALL=1
                  TEST_H2=1
                  TEST_CORE=1
                  TEST_PROXY=1
              # -------------------------------------------------------------------------
              ### TODO: if: *condition_not_24x
              ### TODO: pebble install is broken.
              # - name: ACME test suite
              #   config: --enable-mods-shared=reallyall --with-mpm=event --enable-mpms-shared=event
              #   pkgs: >-
              #     python3-pytest nghttp2-client python3-cryptography python3-requests python3-filelock
              #     golang-1.17 curl
              #   env: |
              #     APR_VERSION=1.7.4
              #     APU_VERSION=1.6.3
              #     APU_CONFIG="--with-crypto"
              #     GOROOT=/usr/lib/go-1.17
              #     NO_TEST_FRAMEWORK=1
              #     TEST_INSTALL=1
              #     TEST_MD=1
              # -------------------------------------------------------------------------
              ### TODO: if: *condition_not_24x
              # -------------------------------------------------------------------------
              ### TODO if: *condition_not_24x
              ### TODO: Fails because :i386 packages are not being found.
              # - name: i386 Shared MPMs, most modules, maintainer-mode w/-Werror
              #   config: --enable-mods-shared=reallyall --disable-xml2enc --disable-proxy-html --enable-mpms-shared=all --enable-maintainer-mode
              #   pkgs: >-
              #     cpanminus libc6-dev-i386 gcc-multilib libexpat1-dev:i386 libssl-dev:i386
              #     lib32z1-dev libbrotli-dev:i386 libpcre2-dev:i386 libldap2-dev:i386 libtool-bin
              #     perl-doc libapr1-dev libbrotli-dev:i386
              #   env: |
              #     PKG_CONFIG_PATH="/usr/lib/i386-linux-gnu/pkgconfig"
              #     NOTEST_CFLAGS="-Werror"
              #     CC="gcc -m32"
              #     APR_VERSION=1.7.3
              #     APU_VERSION=1.6.3
              # APU_CONFIG="--with-crypto --with-ldap"
        runs-on: ${{ matrix.os == '' && 'ubuntu-latest' || matrix.os }}
        timeout-minutes: 30
        env:
          NOTEST_CFLAGS: ${{ matrix.notest-cflags }}
          CONFIG: ${{ matrix.config }}
        name: ${{ matrix.name }}
        steps:
        # JOBID is used in the cache keys, created here as a hash of all
        # properties of the environment, including the image OS version,
        # compiler flags and any job-specific properties.
        - name: Set environment variables
          run: |
            echo "${{ matrix.env }}" >> $GITHUB_ENV
            echo JOBID=`echo "OS=$ImageOS ${{ matrix.notest-cflags }} ${{ matrix.env }} ${{ matrix.config }}" \
               | md5sum - | sed 's/ .*//'` >> $GITHUB_ENV
        # https://github.com/actions/runner-images/issues/9491#issuecomment-1989718917
        - name: Workaround ASAN issue in Ubuntu 22.04
          run: sudo sysctl vm.mmap_rnd_bits=28
        - name: apt refresh
          run: sudo apt-get -o Acquire::Retries=5 update
        - name: Install prerequisites
          run: sudo apt-get install -o Acquire::Retries=5
                        cpanminus libtool-bin libapr1-dev libaprutil1-dev
                        liblua5.3-dev libbrotli-dev libcurl4-openssl-dev     
                        libnghttp2-dev libjansson-dev libpcre2-dev gdb
                        perl-doc libsasl2-dev ${{ matrix.pkgs }}
        - uses: actions/checkout@v4
        - name: Cache installed libraries
          uses: actions/cache@v4
          with:
            path: ~/root
            key: cache-libs-${{ env.JOBID }}
        - name: Cache CPAN modules
          uses: actions/cache@v4
          with:
            path: ~/perl5
            key: cache-cpan-${{ env.JOBID }}
        - name: Configure environment
          run: ./test/travis_before_linux.sh
          timeout-minutes: 15
        - uses: actions/upload-artifact@v4
          if: failure()
          with:
            name: config.log-${{ env.JOBID }}
            path: |
              /home/runner/build/**/config.log
        - name: Build and test
          run: ./test/travis_run_linux.sh
        - uses: actions/upload-artifact@v4
          if: failure()
          with:
            name: error_log-${{ env.JOBID }}
            path: |
              **/config.log
              test/perl-framework/t/logs/error_log
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/�������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014351� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htdigest.dsp�������������������������������������������������������������������0000664�0001751�0001751�00000010330�12520036522�016653� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/htdigest.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htdigest.exe" /d LONG_NAME="Apache htdigest command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\htdigest.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/htdigest.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htdigest.exe" /d LONG_NAME="Apache htdigest command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\htdigest.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "htdigest - Win32 Release"
    # Name "htdigest - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\htdigest.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htcacheclean.dsp���������������������������������������������������������������0000664�0001751�0001751�00000010460�12520036522�017446� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="htcacheclean" - Package Owner=<4>
    # Microsoft Developer Studio Generated Build File, Format Version 6.00
    # ** DO NOT EDIT **
    
    # TARGTYPE "Win32 (x86) Console Application" 0x0103
    
    CFG=htcacheclean - 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 "htcacheclean.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 "htcacheclean.mak" CFG="htcacheclean - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "htcacheclean - Win32 Release" (based on "Win32 (x86) Console Application")
    !MESSAGE "htcacheclean - 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)" == "htcacheclean - 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/htcacheclean_src" /FD /c
    # ADD BASE RSC /l 0x409 /d "NDEBUG"
    # ADD RSC /l 0x409 /fo"Release/htcacheclean.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htcacheclean.exe" /d LONG_NAME="Apache htcacheclean command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\htcacheclean.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "htcacheclean - 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 /EHsc /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 /EHsc /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/htcacheclean_src" /FD /c
    # ADD BASE RSC /l 0x409 /d "_DEBUG"
    # ADD RSC /l 0x409 /fo"Debug/htcacheclean.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htcacheclean.exe" /d LONG_NAME="Apache htcacheclean command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\htcacheclean.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "htcacheclean - Win32 Release"
    # Name "htcacheclean - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\htcacheclean.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/split-logfile.in���������������������������������������������������������������0000664�0001751�0001751�00000004553�12454751535�017462� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!@perlbin@
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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.
    #
    use strict;
    use warnings;
    
    my %log_file = ();
    
    while (my $log_line = <STDIN>) {
        #
        # Get the first token from the log record; it's the
        # identity of the virtual host to which the record
        # applies.
        #
        my ($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) || "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 (! $log_file{$vhost}) {
            open $log_file{$vhost}, ">>${vhost}.log"
                or die ("Can't open ${vhost}.log");
        }
        #
        # 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+//;
        print {$log_file{$vhost}} $log_line;
    }
    exit 0;
    �����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/apachectl.in�������������������������������������������������������������������0000664�0001751�0001751�00000006531�11712132720�016613� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    #
    ACMD="$1"
    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 $ACMD in
    start|stop|restart|graceful|graceful-stop)
        $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 "$@"
        ERROR=$?
    esac
    
    exit $ERROR
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/list_hooks.pl������������������������������������������������������������������0000775�0001751�0001751�00000005531�11046106416�017057� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl -w
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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(<F>) {
    	next if /\#define/;
    	next if /\@deffunc/;
    	if(/AP_DECLARE_HOOK\s*\(/) {
    	    my($ret,$name,$args);
    	    while(!(($ret,$name,$args)=
    		   /AP_DECLARE_HOOK\s*\(\s*([^,]+)\s*,\s*([^,\s]+)\s*,\s*\((.*?)\)\)/s)) {
    		chomp;
    		# swallow subsequent lines if needed to get all the required info
    		my $l=<F>;
    		return unless defined $l;
    		$l=~s/^\s*/ /;
    		$_.=$l;
    	    }
    	    $ret=~s/\s*$//;
    	    $args=~s/^\s*//; $args=~s/\s*$//;
    #	    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;
    	}
    	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;
    	}
        }
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUlogres��������������������������������������������������������������������0000664�0001751�0001751�00000010661�11540546347�016410� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	=
    
    #
    # 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		= 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 = \
       	$(PRELUDE) \
    	$(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 = \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    �������������������������������������������������������������������������������httpd-2.4.64/support/SHA1/��������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�015045� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/SHA1/ldif-sha1.example���������������������������������������������������������0000664�0001751�0001751�00000000624�10150161574�020161� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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
    ������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/SHA1/htpasswd-sha1.pl����������������������������������������������������������0000664�0001751�0001751�00000001330�13623622544�020062� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/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 usage:
    # 	./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]) );
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/SHA1/README.sha1���������������������������������������������������������������0000664�0001751�0001751�00000002321�10150161574�016543� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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 <clintdw@netcom.com>.
    
    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.
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/SHA1/convert-sha1.pl�����������������������������������������������������������0000664�0001751�0001751�00000001646�10150161574�017710� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/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";
    }
    
    ������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/�������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�015313� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/wintty.mak���������������������������������������������������������������0000664�0001751�0001751�00000020250�12701473373�017336� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on wintty.dsp
    !IF "$(CFG)" == ""
    CFG=wintty - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to wintty - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "wintty - Win32 Release" && "$(CFG)" != "wintty - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "wintty - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\wintty.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\wintty.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\wintty.obj"
    	-@erase "$(INTDIR)\wintty.res"
    	-@erase "$(INTDIR)\wintty_src.idb"
    	-@erase "$(INTDIR)\wintty_src.pdb"
    	-@erase "$(OUTDIR)\wintty.exe"
    	-@erase "$(OUTDIR)\wintty.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\wintty_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\wintty.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="wintty.exe" /d LONG_NAME="Apache wintty console pipe" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\wintty.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\wintty.pdb" /debug /out:"$(OUTDIR)\wintty.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\wintty.obj" \
    	"$(INTDIR)\wintty.res" \
    	"..\..\srclib\apr\LibR\apr-1.lib" \
    	"..\..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\wintty.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\wintty.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\wintty.exe"
       if exist .\Release\wintty.exe.manifest mt.exe -manifest .\Release\wintty.exe.manifest -outputresource:.\Release\wintty.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "wintty - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\wintty.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\wintty.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\wintty.obj"
    	-@erase "$(INTDIR)\wintty.res"
    	-@erase "$(INTDIR)\wintty_src.idb"
    	-@erase "$(INTDIR)\wintty_src.pdb"
    	-@erase "$(OUTDIR)\wintty.exe"
    	-@erase "$(OUTDIR)\wintty.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\wintty_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\wintty.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="wintty.exe" /d LONG_NAME="Apache wintty console pipe" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\wintty.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\wintty.pdb" /debug /out:"$(OUTDIR)\wintty.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\wintty.obj" \
    	"$(INTDIR)\wintty.res" \
    	"..\..\srclib\apr\LibD\apr-1.lib" \
    	"..\..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\wintty.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\wintty.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\wintty.exe"
       if exist .\Debug\wintty.exe.manifest mt.exe -manifest .\Debug\wintty.exe.manifest -outputresource:.\Debug\wintty.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("wintty.dep")
    !INCLUDE "wintty.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "wintty.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "wintty - Win32 Release" || "$(CFG)" == "wintty - Win32 Debug"
    
    !IF  "$(CFG)" == "wintty - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support\win32"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ELSEIF  "$(CFG)" == "wintty - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support\win32"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "wintty - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support\win32"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ELSEIF  "$(CFG)" == "wintty - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support\win32"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ENDIF 
    
    SOURCE=..\..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "wintty - Win32 Release"
    
    
    "$(INTDIR)\wintty.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\wintty.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="wintty.exe" /d LONG_NAME="Apache wintty console pipe" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "wintty - Win32 Debug"
    
    
    "$(INTDIR)\wintty.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\wintty.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="wintty.exe" /d LONG_NAME="Apache wintty console pipe" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\wintty.c
    
    "$(INTDIR)\wintty.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.rc���������������������������������������������������������0000664�0001751�0001751�00000010445�11231026034�020353� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <windows.h>
    
    #include "ApacheMonitor.h"
    
    #define LONG_NAME Apache HTTP Server Monitor
    
    #include "../../build/win32/httpd.rc"
    
    
    IDI_APSRVMON            ICON    DISCARDABLE     "ApacheMonitor.ico"
    IDI_ICOSTOP             ICON    DISCARDABLE     "apstop.ico"
    IDI_ICORUN              ICON    DISCARDABLE     "aprun.ico"
    CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST  "ApacheMonitor.manifest"
    
    IDD_DLGSERVICES DIALOGEX 0, 0, 350, 192
    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
        PUSHBUTTON      "OK",IDCANCEL,298,161,50,14
        CONTROL         IDB_BMPHEADER,IDC_STATIC,"Static",SS_BITMAP,0,0,349,38
        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,49,50,14
        PUSHBUTTON      "S&top",IDC_SSTOP,298,65,50,14
        PUSHBUTTON      "&Restart",IDC_SRESTART,298,81,50,14
        PUSHBUTTON      "Ser&vices",IDC_SMANAGER,298,97,50,14
        PUSHBUTTON      "&Connect",IDC_SCONNECT,298,113,50,14
        PUSHBUTTON      "&Disconnect",IDC_SDISCONN,298,129,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_OK              "OK"
        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
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.dsp��������������������������������������������������������0000664�0001751�0001751�00000011460�11023777214�020547� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /EHsc /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
    # ADD CPP /nologo /MD /W3 /EHsc /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/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" /I "../../srclib/apr/include" /d "NDEBUG" /d "APP_FILE"
    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 wtsapi32.lib /nologo /subsystem:windows
    # ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib wtsapi32.lib /nologo /subsystem:windows /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\ApacheMonitor.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
    # ADD CPP /nologo /MDd /W3 /Gm /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/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" /I "../../srclib/apr/include" /d "_DEBUG" /d "APP_FILE"
    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 wtsapi32.lib /nologo /subsystem:windows /debug
    # ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib wtsapi32.lib /nologo /subsystem:windows /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\ApacheMonitor.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/srun.bmp�����������������������������������������������������������������0000664�0001751�0001751�00000000366�10150161574�016774� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BM�������v���(�����������������������������������������������������������������������//��//��//��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.mak��������������������������������������������������������0000664�0001751�0001751�00000020137�12674411515�020534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on ApacheMonitor.dsp
    !IF "$(CFG)" == ""
    CFG=ApacheMonitor - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to ApacheMonitor - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "ApacheMonitor - Win32 Release" && "$(CFG)" != "ApacheMonitor - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "ApacheMonitor - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\ApacheMonitor.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\ApacheMonitor.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ApacheMonitor.obj"
    	-@erase "$(INTDIR)\ApacheMonitor.res"
    	-@erase "$(INTDIR)\ApacheMonitor_src.idb"
    	-@erase "$(INTDIR)\ApacheMonitor_src.pdb"
    	-@erase "$(OUTDIR)\ApacheMonitor.exe"
    	-@erase "$(OUTDIR)\ApacheMonitor.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "STRICT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\ApacheMonitor_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ApacheMonitor.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\ApacheMonitor.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib wtsapi32.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\ApacheMonitor.pdb" /debug /out:"$(OUTDIR)\ApacheMonitor.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\ApacheMonitor.obj" \
    	"$(INTDIR)\ApacheMonitor.res" \
    	"..\..\srclib\apr\LibR\apr-1.lib" \
    	"..\..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\ApacheMonitor.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\ApacheMonitor.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\ApacheMonitor.exe"
       if exist .\Release\ApacheMonitor.exe.manifest mt.exe -manifest .\Release\ApacheMonitor.exe.manifest -outputresource:.\Release\ApacheMonitor.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "ApacheMonitor - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\ApacheMonitor.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\ApacheMonitor.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ApacheMonitor.obj"
    	-@erase "$(INTDIR)\ApacheMonitor.res"
    	-@erase "$(INTDIR)\ApacheMonitor_src.idb"
    	-@erase "$(INTDIR)\ApacheMonitor_src.pdb"
    	-@erase "$(OUTDIR)\ApacheMonitor.exe"
    	-@erase "$(OUTDIR)\ApacheMonitor.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Gm /Zi /Od /I "../../include" /I "../../srclib/apr/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "STRICT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\ApacheMonitor_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ApacheMonitor.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\ApacheMonitor.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib wtsapi32.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\ApacheMonitor.pdb" /debug /out:"$(OUTDIR)\ApacheMonitor.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\ApacheMonitor.obj" \
    	"$(INTDIR)\ApacheMonitor.res" \
    	"..\..\srclib\apr\LibD\apr-1.lib" \
    	"..\..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\ApacheMonitor.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\ApacheMonitor.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\ApacheMonitor.exe"
       if exist .\Debug\ApacheMonitor.exe.manifest mt.exe -manifest .\Debug\ApacheMonitor.exe.manifest -outputresource:.\Debug\ApacheMonitor.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("ApacheMonitor.dep")
    !INCLUDE "ApacheMonitor.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "ApacheMonitor.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "ApacheMonitor - Win32 Release" || "$(CFG)" == "ApacheMonitor - Win32 Debug"
    
    !IF  "$(CFG)" == "ApacheMonitor - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support\win32"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ELSEIF  "$(CFG)" == "ApacheMonitor - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support\win32"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "ApacheMonitor - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support\win32"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ELSEIF  "$(CFG)" == "ApacheMonitor - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support\win32"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support\win32"
    
    !ENDIF 
    
    SOURCE=.\ApacheMonitor.c
    
    "$(INTDIR)\ApacheMonitor.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=.\ApacheMonitor.rc
    
    "$(INTDIR)\ApacheMonitor.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) $(RSC_PROJ) $(SOURCE)
    
    
    
    !ENDIF 
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.h����������������������������������������������������������0000664�0001751�0001751�00000006457�11174007527�020222� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  ApacheMonitor.h
     * @brief Resource definitions for ApacheMonitor.rc and ApacheMonitor.c
     */
    #define BIN_NAME  ApacheMonitor.exe
    
    #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_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_OK                      278
    #define IDS_MSG_LAST                    278
    #define IDM_SM_SERVICE                  0x1100
    #define IDM_SM_START                    0x1200
    #define IDM_SM_STOP                     0x1400
    #define IDM_SM_RESTART                  0x1800
    #define IDC_STATIC                      -1
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/apstop.ico���������������������������������������������������������������0000664�0001751�0001751�00000000476�10150161574�017311� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(�����(������ �����������������������������������������������������������������������������������������������	G��	wwp��M����������U�����Y������P������΁΁ud�F�������������{��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/apache_header.bmp��������������������������������������������������������0000664�0001751�0001751�00000014542�10150161574�020537� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BMb������6��(�����>��������,��#��#������������������1��1�9�1�!))��J��R��{��1Z�)�R�!�{��Rk�ck�1BB�R��J�J�J�{�k�k�RRR�ccc�{{{����1�1���������)��!��9�c��c��{��B��c�B��B��k��k��������������R��)��R��{������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"����������	����
    M����"��.0001��12272���77::���49;98
    �5�'���&�(
    &�%����$$$�"*	+�---�M����#��0111�2��777:��3;9;85%�%(�&�����$$$�"*�� �    �M����$�
    1	23��77::��399;95%�%(��&���$$$�"*\����%�12/��77:7634��99;;9'�99555�%(�����$$$�"*S����&�1.�2/��77�
    :<��8999��9955�%(�
    �$$$�"*+ S����(�1�.����2	��77::3
    �:<<<��8;99���9995�	�%(����
    �$$$�"*�!!!�"
    S����)��/111.��2
    ��777:��8<<<���
    8999�%999'�
    �%(��&���$$$�"*\����*��.111/�2��77::3	4<	��
    '9994999'�%(�&����$$$�"*
    
    ��M����+��.1112//��23333677:46<<<8��49'�'(
    &�����$$$�"*	+�-- �M�������(.%������'�%�%�%%%%����
    !�))
    �M������E�
    55'����%&(&&%''&&&�	�������',))-) 
    %55''&%%5(('%&��'%'&((%%&&#	�������f�
    ),)
    
    ,,
    --+
    495'%((&%&&%55(%5''&&&%&&&%(5'&(('#		�������p "  )
    ,-,
    
    -+)--))899'%55('(&&555%55'5((&%5((55'%(&55('&&##������
    ��y+ +)
    ,--)-,
     --,))49993555''55('499499'555(%555''55%5('855'(&&&'	#������
    ��
    ��
    )�q-- 
    ,--
    - 6;;8%9954995'8;98;8'9955'995''99455(899%5(((''&&&%&			��������), �����%��
    
    
      66<49;96;;987;:7<8�9�8999'8;94%9954;94�5�/'(5(%(&%(&&&'&&%	
    �������,-,)-,") 
    ���c3�3664776777:;;;8<<;;88;;3;994<;%9955'555'5('5(%(&5(((&&%��}������))
     +---)+--"",++
    
    
    
    ��338867:<<<3<<3;;;3:<3�9�3%995555555555'5'55'(&&&&%**�{������#),--,)
    ,-, ---*
    )-,/110..���N366<:7:6<;;934;94994993%95'9'955'5(%%(&&&&&$*
    x������*
    ),-,
    ,--+
    ,)67722122111/21/..���E�334:<<<<:<;8<;89998;899'555555(((&&&&*
    �t������3))
    
    ,--),)8;<<:68<<:7/777222.1000...���<�363<<::<<;;43<34<;;899'95'555(((&%%&&&	$s������:),,)
    ), %555994'999;8;;<<:72211211/21110/..�� 366:::77:::43;944;989955�(55(%	$$
    n���??�4>�)
    &&&((&&(5''5559986:772772/77722/21�
    0.000.���53222777<<:<;;;99'9555555(&&
    =�j?��??�6>>?&&(('8;<<6<<:4<<<:777722/1�./111..��/227::::<<<;89�%4999((&&$i?��??�K>==?>
    #'999;6899%999;;4<:::7/377227722010./110..���,27777:::64<;;98;;93'5((%&&&=h?��?*?�G>
    %'((555%(5''(555''9;;;:6<::36<::6/2212221110000.����(/337733:<<<::<<46955%55(%&&f?��?.?�=��*&&&&%&&%'5599'8;;<38;;;4677/4:7�221//111000...���%23/777::7::66;99'3955%%55	�?`?��?0?�!%&((5(5599�5�$:<:8;<<<:6772772//1111110..��%/377227367<;83;99895%&&???>�?>Z?��?2?�M>	
    **$$	&%((5%&((';;8%5599988<::8::7722/221/.00000.�
    ��(/12//7::8:<;:;9%%55??????Z?��?6?�N>>?=%&&''554'&(5554'9;;39;;6:77677711/111..00.��$113767776<<495((???>?==Z?��?=?�D>	&((&&&'5593559;<;3<<:3222211111.0�.��$/2222237736;;95??=>>V?��?B?�K>			
    "*$&&(((&((999489;8:76772/2211110000..��� /11/227:<;8??===V?��?F?�>=
    	**$		��%555''55';<4<::6:77�21�1110..���011773:??=�W?��?L?�J#
      
    
    &&&%'(((8989;;::<<337773222/22111/.0..	��1263?>�X?��?R?�
    ��'�!(5559998999<<<:�7�6777221110...��1??�=Y?��?\?�@>=�!$$	&(&(555'559'9;;34<::6<::773221100..
    �����Z?��?a?�?=
    "*$	&&&((5599'9;;<8;;;<<77722211100..��Y?��?g?�"=#&&(555'999459�44<:77/722211100	��>�_?��?k?�	&&&'�5'5�9;;<<::377721110.�	�]?��?n?� > $$&&((&&((('9�44;:<:::/72/11??�
    �[?��?s?�&��&%�5�'994;;<:7:723/7?>��=X?��?w?�8
    &&((((5'59993<;::6:?>�V?��?{?�	#
    $$�#'&(%555'99;34;9;?=??>��>T?��?~?�/=*+***
    #&&(('55'5'59?=�?>�>R?��??�>"$$$#	��%((5'(((=?>>=�?�>P?��??�*
    
    
    $$##&&%'%??>>?�>��>N?��??�"=
    *$#	??>>=>?=�M?��??�$	
    *#?�	>>>>�
    ?����=K?��??�=
    
    ===�?�
    =?>=?�=���J?��??�
    =?=?�>�I?��??�
    >>??==??H?��??>c?��??d?���������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.dep��������������������������������������������������������0000664�0001751�0001751�00000000600�12674411515�020525� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by ApacheMonitor.mak
    
    .\ApacheMonitor.c : \
    	".\ApacheMonitor.h"\
    	
    
    .\ApacheMonitor.rc : \
    	"..\..\build\win32\httpd.rc"\
    	"..\..\include\ap_release.h"\
    	".\apache_header.bmp"\
    	".\ApacheMonitor.h"\
    	".\ApacheMonitor.ico"\
    	".\ApacheMonitor.manifest"\
    	".\aprun.ico"\
    	".\apstop.ico"\
    	".\srun.bmp"\
    	".\sstop.bmp"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.manifest���������������������������������������������������0000664�0001751�0001751�00000001041�11231026034�021545� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity version="3.1.0.0" processorArchitecture="*" name="Apache.ApacheMonitor" type="win32" /> 
    <description>Apache Service Monitor</description> 
    <dependency> 
    <dependentAssembly> 
    <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> 
    </dependentAssembly> 
    </dependency> 
    </assembly> 
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.c����������������������������������������������������������0000664�0001751�0001751�00000153222�13303773120�020201� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <mturk mappingsoft.com>
     *
     * 05 Aug 2001
     * ====================================================================
     */
    
    #define _WIN32_WINNT 0x0500
    #ifndef STRICT
    #define STRICT
    #endif
    #ifndef OEMRESOURCE
    #define OEMRESOURCE
    #endif
    
    #if defined(_MSC_VER) && _MSC_VER >= 1400
    #define _CRT_SECURE_NO_DEPRECATE
    #endif
    
    #include <windows.h>
    #include <windowsx.h>
    #include <commctrl.h>
    #include <objbase.h>
    #include <shlobj.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <WtsApi32.h>
    #include <tchar.h>
    #include "ApacheMonitor.h"
    
    #ifndef AM_STRINGIFY
    /** Properly quote a value as a string in the C preprocessor */
    #define AM_STRINGIFY(n) AM_STRINGIFY_HELPER(n)
    /** Helper macro for AM_STRINGIFY */
    #define AM_STRINGIFY_HELPER(n) #n
    #endif
    
    #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
    {
        LPTSTR   szServiceName;
        LPTSTR   szDisplayName;
        LPTSTR   szDescription;
        LPTSTR   szImagePath;
        LPTSTR   szComputerName;
        DWORD    dwPid;
    } ST_APACHE_SERVICE;
    
    typedef struct _st_MONITORED_COMPUTERS
    {
        LPTSTR  szComputerName;
        HKEY    hRegistry;
    } ST_MONITORED_COMP;
    
    /* Global variables */
    HINSTANCE         g_hInstance = NULL;
    TCHAR            *g_szTitle;          /* The title bar text */
    TCHAR            *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;
    
    LANGID            g_LangID;
    CRITICAL_SECTION  g_stcSection;
    LPTSTR            g_szLocalHost;
    
    /* locale language support */
    static TCHAR *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(LPTSTR szComputerName)
    {
        int i = 0;
        while (g_stComputers[i].szComputerName != NULL) {
            if (_tcscmp(g_stComputers[i].szComputerName, szComputerName) == 0) {
                return TRUE;
            }
            ++i;
        }
        return FALSE;
    }
    
    
    void am_DisconnectComputer(LPTSTR szComputerName)
    {
        int i = 0, j;
        while (g_stComputers[i].szComputerName != NULL) {
            if (_tcscmp(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[j].szComputerName= g_stComputers[j+1].szComputerName;
                g_stComputers[j].hRegistry = g_stComputers[j+1].hRegistry;
            }
            g_stComputers[j].szComputerName = NULL;
            g_stComputers[j].hRegistry = NULL;
        }
    }
    
    
    void ErrorMessage(LPCTSTR 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,
                          (LPTSTR) &lpMsgBuf, 0, NULL);
            MessageBox(NULL, (LPCTSTR)lpMsgBuf,
                       g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST],
                       MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION));
            LocalFree(lpMsgBuf);
        }
        if (bFatal) {
            PostQuitMessage(0);
        }
    }
    
    
    int am_RespawnAsUserAdmin(HWND hwnd, DWORD op, LPCTSTR szService,
                              LPCTSTR szComputerName)
    {
        TCHAR args[MAX_PATH + MAX_COMPUTERNAME_LENGTH + 12];
    
        if (g_dwOSVersion < OS_VERSION_WIN2K) {
            ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], FALSE);
            return 0;
        }
    
        _sntprintf(args, sizeof(args) / sizeof(TCHAR),
                   _T("%d \"%s\" \"%s\""), op, szService,
                   szComputerName ? szComputerName : _T(""));
        if (!ShellExecute(hwnd, _T("runas"), __targv[0], args, NULL, SW_NORMAL)) {
            ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
                         FALSE);
            return 0;
        }
    
        return 1;
    }
    
    
    BOOL am_ConnectComputer(LPTSTR szComputerName)
    {
        int i = 0;
        HKEY hKeyRemote;
        TCHAR szTmp[MAX_PATH];
    
        while (g_stComputers[i].szComputerName != NULL) {
            if (_tcscmp(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) {
            _sntprintf(szTmp, sizeof(szTmp) / sizeof(TCHAR),
                       g_lpMsg[IDS_MSG_ECONNECT - IDS_MSG_FIRST],
                       szComputerName);
            ErrorMessage(szTmp, FALSE);
            return FALSE;
        }
        else {
            g_stComputers[i].szComputerName = _tcsdup(szComputerName);
            g_stComputers[i].hRegistry = hKeyRemote;
            return TRUE;
        }
    }
    
    
    LPTSTR GetStringRes(int id)
    {
        static TCHAR 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 >= 5)
                *dwVersion = OS_VERSION_WIN2K;
            else
                *dwVersion = OS_VERSION_WINNT;
            break;
    
        case VER_PLATFORM_WIN32_WINDOWS:
        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) {
            _tcscpy(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGALL - IDS_MSG_FIRST]);
        }
        else if (n) {
            _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR),
                      g_lpMsg[IDS_MSG_RUNNING - IDS_MSG_FIRST], n, i);
        }
        else if (i) {
            _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR),
                      g_lpMsg[IDS_MSG_RUNNINGNONE - IDS_MSG_FIRST], i);
        }
        else {
            _tcscpy(nid.szTip, g_lpMsg[IDS_MSG_NOSERVICES - IDS_MSG_FIRST]);
        }
        Shell_NotifyIcon(dwMessage, &nid);
    }
    
    
    void appendMenuItem(HMENU hMenu, UINT uMenuId, LPTSTR 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 (_tcslen(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,
                           LPTSTR 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);
            appendMenuItem(hMenu, IDC_SMANAGER,
                           g_lpMsg[IDS_MSG_MNUSERVICES - IDS_MSG_FIRST],
                           FALSE, TRUE);
            appendMenuItem(hMenu, 0, _T(""), 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, LPTSTR 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, LPTSTR 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));
    
    }
    
    
    BOOL ApacheManageService(LPCTSTR szServiceName, LPCTSTR szImagePath,
                             LPTSTR szComputerName, DWORD dwCommand)
    {
        TCHAR szMsg[MAX_PATH];
        BOOL retValue;
        SC_HANDLE schService;
        SC_HANDLE schSCManager;
        SERVICE_STATUS schSStatus;
        int ticks;
    
        schSCManager = OpenSCManager(szComputerName, NULL,
                                     SC_MANAGER_CONNECT);
        if (!schSCManager) {
            ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
                         FALSE);
            return FALSE;
        }
    
        schService = OpenService(schSCManager, szServiceName,
                                 SERVICE_QUERY_STATUS | SERVICE_START |
                                 SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
        if (schService == NULL)
        {
            /* Avoid recursion of ImagePath NULL (from this Respawn) */
            if (szImagePath) {
                am_RespawnAsUserAdmin(g_hwndMain, dwCommand,
                                      szServiceName, szComputerName);
            }
            else {
                ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
                             FALSE);
            }
            CloseServiceHandle(schSCManager);
            return FALSE;
        }
        else
        {
            retValue = FALSE;
            g_bConsoleRun = TRUE;
            SetCursor(g_hCursorHourglass);
            switch (dwCommand)
            {
              case SERVICE_CONTROL_STOP:
                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
                           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;
                        _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
                                   g_lpMsg[IDS_MSG_SRVSTOPPED - IDS_MSG_FIRST],
                                   szServiceName);
                        addListBoxString(g_hwndStdoutList, szMsg);
                    }
                }
                break;
    
              case SERVICE_CONTROL_CONTINUE:
                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
                           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;
                        _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
                                   g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST],
                                   szServiceName);
                        addListBoxString(g_hwndStdoutList, szMsg);
                    }
                }
                break;
    
              case SERVICE_APACHE_RESTART:
                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
                           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;
                    _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
                               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;
        }
        return FALSE;
    }
    
    
    BOOL IsServiceRunning(LPCTSTR szServiceName, LPCTSTR szComputerName,
                          LPDWORD lpdwPid)
    {
        DWORD dwPid;
        SC_HANDLE schService;
        SC_HANDLE schSCManager;
        SERVICE_STATUS schSStatus;
    
        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;
    }
    
    
    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()
    {
        TCHAR szKey[MAX_PATH];
        TCHAR achKey[MAX_PATH];
        TCHAR szImagePath[MAX_PATH];
        TCHAR szBuf[MAX_PATH];
        TCHAR 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,
                                   _T("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)
                {
                    _tcscpy(szKey, _T("System\\CurrentControlSet\\Services\\"));
                    _tcscat(szKey, achKey);
    
                    if (RegOpenKeyEx(hKeyRemote, szKey, 0,
                                     KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
                    {
                        dwBufLen = MAX_PATH;
                        rv = RegQueryValueEx(hSubKey, _T("ImagePath"), NULL,
                                             &dwKeyType, (LPBYTE)szImagePath, &dwBufLen);
    
                        if (rv == ERROR_SUCCESS
                                && (dwKeyType == REG_SZ
                                 || dwKeyType == REG_EXPAND_SZ)
                                && dwBufLen)
                        {
                            _tcscpy(szBuf, szImagePath);
                            CharLower(szBuf);
                            /* the service name could be httpd*.exe or Apache*.exe */
                            if (((_tcsstr(szBuf, _T("\\apache")) != NULL)
                                 || (_tcsstr(szBuf, _T("\\httpd")) != NULL))
                                    && _tcsstr(szBuf, _T(".exe"))
                                    && (_tcsstr(szBuf, _T("--ntservice")) != NULL
                                           || _tcsstr(szBuf, _T("-k ")) != NULL))
                            {
                                g_stServices[stPos].szServiceName = _tcsdup(achKey);
                                g_stServices[stPos].szImagePath = _tcsdup(szImagePath);
                                g_stServices[stPos].szComputerName =
                                    _tcsdup(g_stComputers[computers].szComputerName);
                                dwBufLen = MAX_PATH;
                                if (RegQueryValueEx(hSubKey, _T("Description"), NULL,
                                                    &dwKeyType, (LPBYTE)szBuf, &dwBufLen)
                                        == ERROR_SUCCESS) {
                                    g_stServices[stPos].szDescription = _tcsdup(szBuf);
                                }
                                dwBufLen = MAX_PATH;
                                if (RegQueryValueEx(hSubKey, _T("DisplayName"), NULL,
                                                    &dwKeyType, (LPBYTE)szBuf, &dwBufLen)
                                        == ERROR_SUCCESS)
                                {
                                    if (_tcscmp(g_stComputers[computers]
                                            .szComputerName, g_szLocalHost) != 0)
                                    {
                                        _tcscpy(szTmp, g_stComputers[computers]
                                                          .szComputerName + 2);
                                        _tcscat(szTmp, _T("@"));
                                        _tcscat(szTmp, szBuf);
                                    }
                                    else {
                                        _tcscpy(szTmp, szBuf);
                                    }
                                    g_stServices[stPos].szDisplayName = _tcsdup(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)
    {
        TCHAR 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, sizeof(szCmp));
                _tcscpy(szCmp, _T("\\\\"));
                SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), WM_GETTEXT,
                            (WPARAM) MAX_COMPUTERNAME_LENGTH,
                            (LPARAM) szCmp+2);
    
                _tcsupr(szCmp);
                if (_tcslen(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      = _T("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 (SUCCEEDED(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)
    {
        TCHAR 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, sizeof(szBuf));
        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, IDCANCEL),
                          g_lpMsg[IDS_MSG_OK - IDS_MSG_FIRST]);
            hListBox = GetDlgItem(hDlg, IDL_SERVICES);
            g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT);
            hStatusBar = CreateStatusWindow(0x0800 /* SBT_TOOLTIPS */
                                          | WS_CHILD | WS_VISIBLE,
                                            _T(""), 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)_T(""));
            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_FOCUS:
            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_SetStyle(GetDlgItem(hDlg, IDC_SSTART), BS_DEFPUSHBUTTON, 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_SetStyle(GetDlgItem(hDlg, IDC_SSTOP), BS_DEFPUSHBUTTON, 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 (_tcscmp(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)_T(""));
                    }
                    if (lpdis->itemState & ODS_FOCUS) {
                        SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
                        SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
                        FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHT+1));
                    }
                    else {
                        SetTextColor(lpdis->hDC, GetSysColor(COLOR_INACTIVECAPTIONTEXT));
                        SetBkColor(lpdis->hDC, GetSysColor(COLOR_INACTIVECAPTION));
                        FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_INACTIVECAPTION+1));
                    }
                }
                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)_tcslen(szBuf));
                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 IDCANCEL:
                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, _T("open"), _T("services.msc"), _T("/s"),
                                 NULL, SW_NORMAL);
                }
                else {
                    WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
                }
                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:
            {
                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, _T("open"), _T("services.msc"), _T("/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;
    }
    
    
    static int KillAWindow(HWND appwindow)
    {
        HANDLE appproc;
        DWORD procid;
        BOOL postres;
    
        SetLastError(0);
        GetWindowThreadProcessId(appwindow, &procid);
        if (GetLastError())
            return(2);
    
        appproc = OpenProcess(SYNCHRONIZE, 0, procid);
        postres = PostMessage(appwindow, WM_COMMAND, IDM_EXIT, 0);
        if (appproc && postres) {
            if (WaitForSingleObject(appproc, 10 /* seconds */ * 1000)
                    == WAIT_OBJECT_0) {
                CloseHandle(appproc);
                return (0);
            }
        }
        if (appproc)
            CloseHandle(appproc);
    
        if ((appproc = OpenProcess(PROCESS_TERMINATE, 0, procid)) != NULL) {
            if (TerminateProcess(appproc, 0)) {
                CloseHandle(appproc);
                return (0);
            }
            CloseHandle(appproc);
        }
    
        /* Perhaps we were short of permissions? */
        return (2);
    }
    
    
    static int KillAllMonitors(void)
    {
        HWND appwindow;
        int exitcode = 0;
        PWTS_PROCESS_INFO tsProcs;
        DWORD tsProcCount, i;
        DWORD thisProcId;
    
        /* This is graceful, close our own Window, clearing the icon */
        if ((appwindow = FindWindow(g_szWindowClass, g_szTitle)) != NULL)
            exitcode = KillAWindow(appwindow);
    
        if (g_dwOSVersion < OS_VERSION_WIN2K)
            return exitcode;
    
        thisProcId = GetCurrentProcessId();
    
        if (!WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1,
                                   &tsProcs, &tsProcCount))
            return exitcode;
    
        /* This is ungraceful; close other Windows, with a lingering icon.
         * Since on terminal server it's not possible to post the message
         * to exit across sessions, we have to suffer this side effect
         * of a taskbar 'icon' which will evaporate the next time that
         * the user hovers over it or when the taskbar area is updated.
         */
        for (i = 0; i < tsProcCount; ++i) {
            if (_tcscmp(tsProcs[i].pProcessName, _T(AM_STRINGIFY(BIN_NAME))) == 0
                    && tsProcs[i].ProcessId != thisProcId)
                WTSTerminateProcess(WTS_CURRENT_SERVER_HANDLE,
                                    tsProcs[i].ProcessId, 1);
        }
        WTSFreeMemory(tsProcs);
        return exitcode;
    }
    
    
    /* Create main invisible window */
    HWND CreateMainWindow(HINSTANCE hInstance)
    {
        HWND hWnd = NULL;
        WNDCLASSEX wcex;
    
        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;
    }
    
    
    #ifndef UNICODE
    /* Borrowed from CRT internal.h for _MBCS argc/argv parsing in this GUI app */
    int  __cdecl _setargv(void);
    #endif
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine, int nCmdShow)
    {
        TCHAR szTmp[MAX_LOADSTRING];
        TCHAR szCmp[MAX_COMPUTERNAME_LENGTH+4];
        MSG msg;
        /* existing window */
        HWND appwindow;
        DWORD dwControl;
        int i;
        DWORD d;
    
        if (!GetSystemOSVersion(&g_dwOSVersion))
        {
            ErrorMessage(NULL, TRUE);
            return 1;
        }
    
        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] = _tcsdup(szTmp);
        }
        LoadString(hInstance, IDS_APMONITORTITLE, szTmp, MAX_LOADSTRING);
        d = MAX_COMPUTERNAME_LENGTH+1;
        _tcscpy(szCmp, _T("\\\\"));
        GetComputerName(szCmp + 2, &d);
        _tcsupr(szCmp);
        g_szLocalHost = _tcsdup(szCmp);
    
        memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS);
        g_stComputers[0].szComputerName = _tcsdup(szCmp);
        g_stComputers[0].hRegistry = HKEY_LOCAL_MACHINE;
        g_szTitle = _tcsdup(szTmp);
        LoadString(hInstance, IDS_APMONITORCLASS, szTmp, MAX_LOADSTRING);
        g_szWindowClass = _tcsdup(szTmp);
    
        appwindow = FindWindow(g_szWindowClass, g_szTitle);
    
    #ifdef UNICODE
        __wargv = CommandLineToArgvW(GetCommandLineW(), &__argc);
    #else
    #if defined(_MSC_VER) && _MSC_VER < 1800 
        _setargv();
    #endif
    #endif
    
        if ((__argc == 2) && (_tcscmp(__targv[1], _T("--kill")) == 0))
        {
            /* Off to chase and close up every ApacheMonitor taskbar window */
            return KillAllMonitors();
        }
        else if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K))
        {
            dwControl = _ttoi(__targv[1]);
            if ((dwControl != SERVICE_CONTROL_CONTINUE) &&
                (dwControl != SERVICE_APACHE_RESTART) &&
                (dwControl != SERVICE_CONTROL_STOP))
            {
                return 1;
            }
    
            /* Chase down and close up our session's previous window */
            if ((appwindow) != NULL)
                KillAWindow(appwindow);
        }
        else if (__argc != 1) {
            return 1;
        }
        else if (appwindow)
        {
            ErrorMessage(g_lpMsg[IDS_MSG_APPRUNNING - IDS_MSG_FIRST], FALSE);
            return 0;
        }
    
        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);
    
        memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES);
        CoInitialize(NULL);
        InitCommonControls();
        g_hInstance = hInstance;
        g_hwndMain = CreateMainWindow(hInstance);
        g_bUiTaskbarCreated = RegisterWindowMessage(_T("TaskbarCreated"));
        InitializeCriticalSection(&g_stcSection);
        g_hwndServiceDlg = NULL;
        if (g_hwndMain != NULL)
        {
            /* To avoid recursion, pass ImagePath NULL (a noop on NT and later) */
            if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K))
                ApacheManageService(__targv[2], NULL, __targv[3], dwControl);
    
            while (GetMessage(&msg, NULL, 0, 0) == TRUE)
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            am_ClearServicesSt();
        }
        am_ClearComputersSt();
        DeleteCriticalSection(&g_stcSection);
        DestroyIcon(g_icoStop);
        DestroyIcon(g_icoRun);
        DestroyCursor(g_hCursorHourglass);
        DestroyCursor(g_hCursorArrow);
        DeleteObject(g_hBmpStart);
        DeleteObject(g_hBmpStop);
        CoUninitialize();
        return 0;
    }
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/wintty.dep���������������������������������������������������������������0000664�0001751�0001751�00000000220�12674411515�017330� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by wintty.mak
    
    ..\..\build\win32\httpd.rc : \
    	"..\..\include\ap_release.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/wintty.dsp���������������������������������������������������������������0000664�0001751�0001751�00000010117�11023777214�017352� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/wintty.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="wintty.exe" /d LONG_NAME="Apache wintty console pipe"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\wintty.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/wintty.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="wintty.exe" /d LONG_NAME="Apache wintty console pipe"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\wintty.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "wintty - Win32 Release"
    # Name "wintty - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\wintty.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/ApacheMonitor.ico��������������������������������������������������������0000664�0001751�0001751�00000002066�10150161574�020531� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������  �������&��������(����(��� ���@������������������������������������������������������������������������������������������������������������������������������������������������������������?�������D�������?��������������������	�����������	A�������DM�����	Dݑ������	Mٙ������Dݙ����������	Dݐ����������	Dݙ�����������M������������M�����������������������������������;=������������X�������������X����������������������������������������������������������������������������?� �??(������ �������������������������������������������������������������������������������������	�����	����D��	M����	ِ����M����������U�����Y������P������΁΁�������������������?���������΁��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/aprun.ico����������������������������������������������������������������0000664�0001751�0001751�00000000476�10150161574�017130� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(�����(������ �����������������������������������������������������������������������������������/��"��"/��"��/����	H��	و��M����������U�����Y������P���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/win32/wintty.c�����������������������������������������������������������������0000664�0001751�0001751�00000031757�10455005461�017017� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /* --------------------------------------------------------------------
     *
     * wintty : a Apache/WinNT support utility for monitoring and
     *          reflecting user feedback from the Apache process via
     *          stdin/stdout, even as running within the service context.
     *
     * Originally contributed by William Rowe <wrowe covalent.net>
     *
     * 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 <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #if defined(_MSC_VER) && _MSC_VER >= 1400
    #define _CRT_SECURE_NO_DEPRECATE
    #pragma warning(disable: 4996)
    #endif
    
    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;
    }
    �����������������httpd-2.4.64/support/win32/sstop.bmp����������������������������������������������������������������0000664�0001751�0001751�00000000366�10150161574�017155� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BM�������v���(�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htdbm.c������������������������������������������������������������������������0000664�0001751�0001751�00000033742�14571614732�015623� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <mturk mappingsoft.com>
     * 12 Oct 2001
     */
    
    #include "passwd_common.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"
    #include "apr_getopt.h"
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_STRING_H
    #include <string.h>
    #endif
    #if APR_HAVE_STRINGS_H
    #include <strings.h>
    #endif
    #include <time.h>
    
    #if APR_CHARSET_EBCDIC
    #include "apr_xlate.h"
    #endif /*APR_CHARSET_EBCDIC*/
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if APR_HAVE_CRYPT_H
    #include <crypt.h>
    #endif
    
    
    typedef struct htdbm_t htdbm_t;
    
    struct htdbm_t {
        apr_dbm_t               *dbm;
        struct passwd_ctx       ctx;
    #if APR_CHARSET_EBCDIC
        apr_xlate_t             *to_ascii;
    #endif
        char                    *filename;
        char                    *username;
        char                    *comment;
        char                    *type;
        int                     create;
        int                     rdonly;
    };
    
    
    #define HTDBM_MAKE   0
    #define HTDBM_DELETE 1
    #define HTDBM_VERIFY 2
    #define HTDBM_LIST   3
    #define HTDBM_NOFILE 4
    
    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_pool_abort_set(abort_on_oom, *pool);
        apr_file_open_stderr(&errfile, *pool);
        apr_signal(SIGINT, (void (*)(int)) htdbm_interrupted);
    
        (*hdbm) = (htdbm_t *)apr_pcalloc(*pool, sizeof(htdbm_t));
        (*hdbm)->ctx.pool = *pool;
    
    #if APR_CHARSET_EBCDIC
        rv = apr_xlate_open(&((*hdbm)->to_ascii), "ISO-8859-1", APR_DEFAULT_CHARSET, (*hdbm)->ctx.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)->ctx.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->ctx.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->ctx.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->ctx.passwd);
        if (!htdbm->comment)
            val.dptr  = htdbm->ctx.passwd;
        else {
            val.dptr = apr_pstrcat(htdbm->ctx.pool, htdbm->ctx.passwd, ":",
                                   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;
        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->ctx.pool, val.dptr, val.dsize);
        cmnt = strchr(rec, ':');
        if (cmnt)
            pwd = apr_pstrndup(htdbm->ctx.pool, rec, cmnt - rec);
        else
            pwd = apr_pstrdup(htdbm->ctx.pool, rec);
        return apr_password_validate(htdbm->ctx.passwd, pwd);
    }
    
    static apr_status_t htdbm_list(htdbm_t *htdbm)
    {
        apr_status_t rv;
        apr_datum_t key, val;
        char *cmnt;
        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;
        }
        fprintf(stderr, "Dumping records from database -- %s\n", htdbm->filename);
        fprintf(stderr, "    %-32s Comment\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;
            }
            /* Note: we don't store \0-terminators on our dbm data */
            fprintf(stderr, "    %-32.*s", (int)key.dsize, key.dptr);
            cmnt = memchr(val.dptr, ':', val.dsize);
            if (cmnt)
                fprintf(stderr, " %.*s", (int)(val.dptr+val.dsize - (cmnt+1)), 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 int htdbm_make(htdbm_t *htdbm)
    {
        char cpw[MAX_STRING_LEN];
        int ret;
    
        htdbm->ctx.out = cpw;
        htdbm->ctx.out_len = sizeof(cpw);
        ret = mkhash(&htdbm->ctx);
        if (ret != 0) {
            fprintf(stderr, "Error: %s\n", htdbm->ctx.errstr);
            return ret;
        }
        htdbm->ctx.passwd = apr_pstrdup(htdbm->ctx.pool, cpw);
        return 0;
    }
    
    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)
    {
        fprintf(stderr,
            "htdbm -- program for manipulating DBM password databases.\n\n"
            "Usage: htdbm   [-cimBdpstvx] [-C cost] [-TDBTYPE] database username\n"
            "                -b[cmBdptsv] [-C cost] [-TDBTYPE] database username password\n"
            "                -n[imBdpst]  [-C cost] username\n"
            "                -nb[mBdpst]  [-C cost] username password\n"
            "                -v[imBdps]   [-C cost] [-TDBTYPE] database username\n"
            "                -vb[mBdps]   [-C cost] [-TDBTYPE] database username password\n"
            "                -x                     [-TDBTYPE] database username\n"
            "                -l                     [-TDBTYPE] database\n"
            "Options:\n"
            "   -c   Create a new database.\n"
            "   -n   Don't update database; display results on stdout.\n"
            "   -b   Use the password from the command line rather than prompting for it.\n"
            "   -i   Read password from stdin without verification (for script usage).\n"
            "   -m   Force MD5 hashing of the password (default).\n"
            "   -B   Force BCRYPT hashing of the password (very secure).\n"
            "   -C   Set the computing time used for the bcrypt algorithm\n"
            "        (higher is more secure but slower, default: %d, valid: 4 to 31).\n"
            "   -d   Force CRYPT hashing of the password (8 chars max, insecure).\n"
            "   -s   Force SHA hashing of the password (insecure).\n"
            "   -p   Do not hash the password (plaintext, insecure).\n"
            "   -T   DBM Type (SDBM|GDBM|DB|default).\n"
            "   -l   Display usernames from database on stdout.\n"
            "   -v   Verify the username/password.\n"
            "   -x   Remove the username record from database.\n"
            "   -t   The last param is username comment.\n"
            "The SHA algorithm does not use a salt and is less secure than the "
            "MD5 algorithm.\n",
            BCRYPT_DEFAULT_COST);
        exit(ERR_SYNTAX);
    }
    
    int main(int argc, const char * const argv[])
    {
        apr_pool_t *pool;
        apr_status_t rv;
        char errbuf[MAX_STRING_LEN];
        int  need_file = 1;
        int  need_user = 1;
        int  need_pwd  = 1;
        int  need_cmnt = 0;
        int  changed = 0;
        int  cmd = HTDBM_MAKE;
        int  i, ret, args_left = 2;
        apr_getopt_t *state;
        char opt;
        const char *opt_arg;
    
        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);
        }
    
        rv = apr_getopt_init(&state, pool, argc, argv);
        if (rv != APR_SUCCESS)
            exit(ERR_SYNTAX);
    
        while ((rv = apr_getopt(state, "cnmspdBbtivxlC:T:", &opt, &opt_arg)) == APR_SUCCESS) {
            switch (opt) {
            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->ctx.pool, opt_arg);
                break;
            case 'v':
                h->rdonly = 1;
                cmd = HTDBM_VERIFY;
                break;
            case 'x':
                need_pwd = 0;
                cmd = HTDBM_DELETE;
                break;
            default:
                ret = parse_common_options(&h->ctx, opt, opt_arg);
                if (ret) {
                    fprintf(stderr, "Error: %s\n", h->ctx.errstr);
                    exit(ret);
                }
            }
        }
        if (h->ctx.passwd_src == PW_ARG) {
                need_pwd = 0;
                args_left++;
        }
        /*
         * Make sure we still have exactly the right number of arguments left
         * (the filename, the username, and possibly the password if -b was
         * specified).
         */
        i = state->ind;
        if (rv != APR_EOF || argc - i != args_left)
            htdbm_usage();
    
        if (need_file) {
            h->filename = apr_pstrdup(h->ctx.pool, argv[i++]);
            if ((rv = htdbm_open(h)) != APR_SUCCESS) {
                fprintf(stderr, "Error opening database %s\n", h->filename);
                apr_strerror(rv, errbuf, sizeof(errbuf));
                fprintf(stderr,"%s\n",errbuf);
                exit(ERR_FILEPERM);
            }
        }
        if (need_user) {
            h->username = apr_pstrdup(pool, argv[i++]);
            if (htdbm_valid_username(h) != APR_SUCCESS)
                exit(ERR_BADUSER);
        }
        if (h->ctx.passwd_src == PW_ARG)
            h->ctx.passwd = apr_pstrdup(pool, argv[i++]);
    
        if (need_pwd) {
            ret = get_password(&h->ctx);
            if (ret) {
                fprintf(stderr, "Error: %s\n", h->ctx.errstr);
                exit(ret);
            }
        }
        if (need_cmnt)
            h->comment = apr_pstrdup(pool, argv[i++]);
    
        switch (cmd) {
            case HTDBM_VERIFY:
                if ((rv = htdbm_verify(h)) != APR_SUCCESS) {
                    if (APR_STATUS_IS_ENOENT(rv)) {
                        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:
                ret = htdbm_make(h);
                if (ret)
                    exit(ret);
                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->ctx.passwd);
            }
            else {
                fprintf(stderr, "%s:%s:%s\n", h->username, h->ctx.passwd,
                        h->comment);
            }
        }
        htdbm_terminate(h);
    
        return 0; /* Suppress compiler warning. */
    }
    ������������������������������httpd-2.4.64/support/httxt2dbm.dep������������������������������������������������������������������0000664�0001751�0001751�00000001536�12674411515�016763� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by httxt2dbm.mak
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    
    .\httxt2dbm.c : \
    	"..\srclib\apr-util\include\apr_dbm.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/rotatelogs.dep�����������������������������������������������������������������0000664�0001751�0001751�00000001665�12674411515�017231� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by rotatelogs.mak
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    
    .\rotatelogs.c : \
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_network_io.h"\
    	"..\srclib\apr\include\apr_poll.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_signal.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_thread_proc.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    ���������������������������������������������������������������������������httpd-2.4.64/support/fcgistarter.dep����������������������������������������������������������������0000664�0001751�0001751�00000001750�12674411515�017356� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by fcgistarter.mak
    
    .\fcgistarter.c : \
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_dso.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_global_mutex.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_network_io.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_portable.h"\
    	"..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\srclib\apr\include\apr_shm.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_thread_proc.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    ������������������������httpd-2.4.64/support/log_server_status.in�����������������������������������������������������������0000664�0001751�0001751�00000004610�11747074131�020446� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!@perlbin@
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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.
    #
    use IO::Socket;
    use strict;
    use warnings;
    
    my $wherelog = "@exp_logfiledir@/";  # Logs will be like "@exp_logfiledir@/19960312"
    my $server   = "localhost";        # Name of server, could be "www.foo.com"
    my $port     = "@PORT@";               # Port on server
    my $request = "/server-status/?auto";    # Request to send
    
    my @ltime = localtime(time);
    
    my $day =
        $ltime[5] + 1900
      . sprintf( "%02d", $ltime[4] + 1 )
      . sprintf( "%02d", $ltime[3] );
    
    my $time =
        sprintf( "%02d", $ltime[2] )
      . sprintf( "%02d", $ltime[1] )
      . sprintf( "%02d", $ltime[0] );
    
    open(OUT,">>$wherelog$day");
    
    my $socket = new IO::Socket::INET(
        PeerAddr => $server,
        PeerPort => $port,
        Proto    => "tcp",
        Type     => SOCK_STREAM
      )
      or do {
        print OUT "$time:-1:-1:-1:-1:$@\n";
        close OUT;
        die "Couldn't connect to $server:$port : $@\n";
      };
    $| = 1;
    
    print $socket
      "GET $request HTTP/1.1\r\nHost: $server\r\nConnection: close\r\n\r\n\r\n";
    
    my ( $requests, $idle, $number, $cpu );
    while (<$socket>) {
        $requests = $1 if (m|^BusyWorkers:\ (\S+)|);
        $idle     = $1 if (m|^IdleWorkers:\ (\S+)|);
        $number   = $1 if (m|sses:\ (\S+)|);
        $cpu      = $1 if (m|^CPULoad:\ (\S+)|);
    }
    print OUT "$time:$requests:$idle:$number:$cpu\n";
    close OUT;
    
    ������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUhttxt2dbm�����������������������������������������������������������������0000664�0001751�0001751�00000010457�11540546347�017040� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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		= httxt2dbm
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache $(VERSION_STR) HT Text to DBM Conversion Utility for NetWare
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= httxt2dbm
    
    #
    # This is used by the '-screenname' directive.  If left blank,
    # 'Apache for NetWare' Thread will be used.
    #
    NLM_SCREEN_NAME = httxt2dbm Conversion Utility
    
    #
    # 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	=
    
    #
    # 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		= 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)/httxt2dbm.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)/httxt2dbm.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 = \
       	$(PRELUDE) \
    	$(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 = \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/rotatelogs.c�������������������������������������������������������������������0000664�0001751�0001751�00000063632�14400401053�016666� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "apr_errno.h"
    #include "apr_file_io.h"
    #include "apr_file_info.h"
    #include "apr_general.h"
    #include "apr_time.h"
    #include "apr_getopt.h"
    #include "apr_thread_proc.h"
    #include "apr_signal.h"
    #if APR_FILES_AS_SOCKETS
    #include "apr_poll.h"
    #endif
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #define APR_WANT_STRFUNC
    #include "apr_want.h"
    
    #define BUFSIZE         65536
    
    #define ROTATE_NONE     0
    #define ROTATE_NEW      1
    #define ROTATE_TIME     2
    #define ROTATE_SIZE     3
    #define ROTATE_FORCE    4
    
    static const char *const ROTATE_REASONS[] = {
        "None",
        "Open a new file",
        "Time interval expired",
        "Maximum size reached",
        "Forced rotation",
        NULL
    };
    
    typedef struct rotate_config rotate_config_t;
    
    struct rotate_config {
        unsigned int sRotation;
        int tRotation;
        int utc_offset;
        int use_localtime;
        int use_strftime;
        int force_open;
        int verbose;
        int echo;
        char *szLogRoot;
        int truncate;
        int truncate_rotated_only;
        const char *linkfile;
        const char *postrotate_prog;
    #if APR_FILES_AS_SOCKETS
        int create_empty;
    #endif
        int num_files;
        int create_path;
    };
    
    typedef struct rotate_status rotate_status_t;
    
    /* "adjusted_time_t" is used to store Unix time (seconds since epoch)
     * which has been adjusted for some timezone fudge factor.  It should
     * be used for storing the return values from get_now().  A typedef is
     * used since this type is similar to time_t, but different. */
    typedef long adjusted_time_t;
    
    /* Structure to contain relevant logfile state: fd, pool and
     * filename. */
    struct logfile {
        apr_pool_t *pool;
        apr_file_t *fd;
        char name[APR_PATH_MAX];
    };
    
    struct rotate_status {
        struct logfile current; /* current logfile. */
        apr_pool_t *pool; /* top-level pool */
        int rotateReason;
        adjusted_time_t tLogEnd;
        int nMessCount;
        int fileNum;
    };
    
    static rotate_config_t config;
    static rotate_status_t status;
    
    static void usage(const char *argv0, const char *reason)
    {
        if (reason) {
            fprintf(stderr, "%s\n", reason);
        }
        fprintf(stderr,
    #if APR_FILES_AS_SOCKETS
                "Usage: %s [-vlfDtTec] [-L linkname] [-p prog] [-n number] <logfile> "
    #else
                "Usage: %s [-vlfDtTe] [-L linkname] [-p prog] [-n number] <logfile> "
    #endif
                "{<rotation time in seconds>|<rotation size>(B|K|M|G)} "
                "[offset minutes from UTC]\n\n",
                argv0);
    #ifdef OS2
        fprintf(stderr,
                "Add this:\n\nTransferLog \"|%s.exe /some/where 86400\"\n\n",
                argv0);
    #else
        fprintf(stderr,
                "Add this:\n\nTransferLog \"|%s /some/where 86400\"\n\n",
                argv0);
        fprintf(stderr,
                "or \n\nTransferLog \"|%s /some/where 5M\"\n\n", argv0);
    #endif
        fprintf(stderr,
                "to httpd.conf. By default, the generated name will be\n"
                "<logfile>.nnnn where nnnn is the system time at which the log\n"
                "nominally starts (N.B. if using a rotation time, the time will\n"
                "always be a multiple of the rotation time, so you can synchronize\n"
                "cron scripts with it). If <logfile> contains strftime conversion\n"
                "specifications, those will be used instead. At the end of each\n"
                "rotation time or when the file size is reached a new log is\n"
                "started.\n"
                "\n"
                "Options:\n"
                "  -v       Verbose operation. Messages are written to stderr.\n"
                "  -l       Base rotation on local time instead of UTC.\n"
                "  -L path  Create hard link from current log to specified path.\n"
                "  -p prog  Run specified program after opening a new log file. See below.\n"
                "  -f       Force opening of log on program start.\n"
                "  -D       Create parent directories of log file.\n" 
                "  -t       Truncate logfile instead of rotating, tail friendly.\n"
                "  -T       Truncate logfiles opened for rotation, but not the initial logfile.\n"
                "  -e       Echo log to stdout for further processing.\n"
    #if APR_FILES_AS_SOCKETS
                "  -c       Create log even if it is empty.\n"
    #endif
                "  -n num   Rotate file by adding suffixes '.1', '.2', ..., '.num'.\n"
                "\n"
                "The program for '-p' is invoked as \"[prog] <curfile> [<prevfile>]\"\n"
                "where <curfile> is the filename of the newly opened logfile, and\n"
                "<prevfile>, if given, is the filename of the previously used logfile.\n"
                "\n");
        exit(1);
    }
    
    /* This function returns the current Unix time (time_t) adjusted for
     * any configured or derived local time offset.  The offset applied is
     * returned via *offset. */
    static adjusted_time_t get_now(rotate_config_t *config, apr_int32_t *offset)
    {
        apr_time_t tNow = apr_time_now();
        apr_int32_t utc_offset;
    
        if (config->use_localtime) {
            /* Check for our UTC offset before using it, since it might
             * change if there's a switch between standard and daylight
             * savings time.
             */
            apr_time_exp_t lt;
            apr_time_exp_lt(&lt, tNow);
            utc_offset = lt.tm_gmtoff;
        }
        else {
            utc_offset = config->utc_offset;
        }
    
        if (offset)
            *offset = utc_offset;
    
        return apr_time_sec(tNow) + utc_offset;
    }
    
    /*
     * Close a file and destroy the associated pool.
     */
    static void close_logfile(rotate_config_t *config, struct logfile *logfile)
    {
        if (config->verbose) {
            fprintf(stderr, "Closing file %s\n", logfile->name);
        }
        apr_file_close(logfile->fd);
        apr_pool_destroy(logfile->pool);
    }
    
    /*
     * Dump the configuration parsing result to STDERR.
     */
    static void dumpConfig (rotate_config_t *config)
    {
        fprintf(stderr, "Rotation time interval:      %12d\n", config->tRotation);
        fprintf(stderr, "Rotation size interval:      %12d\n", config->sRotation);
        fprintf(stderr, "Rotation time UTC offset:    %12d\n", config->utc_offset);
        fprintf(stderr, "Rotation based on localtime: %12s\n", config->use_localtime ? "yes" : "no");
        fprintf(stderr, "Rotation file date pattern:  %12s\n", config->use_strftime ? "yes" : "no");
        fprintf(stderr, "Rotation file forced open:   %12s\n", config->force_open ? "yes" : "no");
        fprintf(stderr, "Create parent directories:   %12s\n", config->create_path ? "yes" : "no");
        fprintf(stderr, "Rotation verbose:            %12s\n", config->verbose ? "yes" : "no");
    #if APR_FILES_AS_SOCKETS
        fprintf(stderr, "Rotation create empty logs:  %12s\n", config->create_empty ? "yes" : "no");
    #endif
        fprintf(stderr, "Rotation file name: %21s\n", config->szLogRoot);
        fprintf(stderr, "Post-rotation prog: %21s\n", config->postrotate_prog ? config->postrotate_prog : "not used");
    }
    
    /*
     * Check whether we need to rotate.
     * Possible reasons are:
     * - No log file open (ROTATE_NEW)
     * - User forces us to rotate (ROTATE_FORCE)
     * - Our log file size is already bigger than the
     *   allowed maximum (ROTATE_SIZE)
     * - The next log time interval expired (ROTATE_TIME)
     *
     * When size and time constraints are both given,
     * it suffices that one of them is fulfilled.
     */
    static void checkRotate(rotate_config_t *config, rotate_status_t *status)
    {
        if (status->current.fd == NULL) {
            status->rotateReason = ROTATE_NEW;
        }
        else if (config->sRotation) {
            apr_finfo_t finfo;
            apr_off_t current_size = -1;
    
            if (apr_file_info_get(&finfo, APR_FINFO_SIZE, status->current.fd) == APR_SUCCESS) {
                current_size = finfo.size;
            }
    
            if (current_size > config->sRotation) {
                status->rotateReason = ROTATE_SIZE;
            }
            else if (config->tRotation) {
                if (get_now(config, NULL) >= status->tLogEnd) {
                    status->rotateReason = ROTATE_TIME;
                }
            }
        }
        else if (config->tRotation) {
            if (get_now(config, NULL) >= status->tLogEnd) {
                status->rotateReason = ROTATE_TIME;
            }
        }
        else {
            fprintf(stderr, "No rotation time or size specified\n");
            exit(2);
        }
    
        if (status->rotateReason != ROTATE_NONE && config->verbose) {
            fprintf(stderr, "File rotation needed, reason: %s\n", ROTATE_REASONS[status->rotateReason]);
        }
    }
    
    /*
     * Handle post-rotate processing.
     */
    static void post_rotate(apr_pool_t *pool, struct logfile *newlog,
                            rotate_config_t *config, rotate_status_t *status)
    {
        apr_status_t rv;
        char error[120];
        apr_procattr_t *pattr;
        const char *argv[4];
        apr_proc_t proc;
    
        /* Handle link file, if configured. */
        if (config->linkfile) {
            apr_file_remove(config->linkfile, newlog->pool);
            if (config->verbose) {
                fprintf(stderr, "Linking %s to %s\n", newlog->name, config->linkfile);
            }
            rv = apr_file_link(newlog->name, config->linkfile);
            if (rv != APR_SUCCESS) {
                apr_strerror(rv, error, sizeof error);
                fprintf(stderr, "Error linking file %s to %s (%s)\n",
                        newlog->name, config->linkfile, error);
                exit(2);
            }
        }
    
        if (!config->postrotate_prog) {
            /* Nothing more to do. */
            return;
        }
    
        /* Collect any zombies from a previous run, but don't wait. */
        while (apr_proc_wait_all_procs(&proc, NULL, NULL, APR_NOWAIT, pool) == APR_CHILD_DONE)
            /* noop */;
    
        if ((rv = apr_procattr_create(&pattr, pool)) != APR_SUCCESS) {
            fprintf(stderr,
                    "post_rotate: apr_procattr_create failed for '%s': %s\n",
                    config->postrotate_prog,
                    apr_strerror(rv, error, sizeof(error)));
            return;
        }
    
        rv = apr_procattr_error_check_set(pattr, 1);
        if (rv == APR_SUCCESS)
            rv = apr_procattr_cmdtype_set(pattr, APR_PROGRAM_ENV);
    
        if (rv != APR_SUCCESS) {
            fprintf(stderr,
                    "post_rotate: could not set up process attributes for '%s': %s\n",
                    config->postrotate_prog,
                    apr_strerror(rv, error, sizeof(error)));
            return;
        }
    
        argv[0] = config->postrotate_prog;
        argv[1] = newlog->name;
        if (status->current.fd) {
            argv[2] = status->current.name;
            argv[3] = NULL;
        }
        else {
            argv[2] = NULL;
        }
    
        if (config->verbose)
            fprintf(stderr, "Calling post-rotate program: %s\n", argv[0]);
    
        rv = apr_proc_create(&proc, argv[0], argv, NULL, pattr, pool);
        if (rv != APR_SUCCESS) {
            fprintf(stderr, "Could not spawn post-rotate process '%s': %s\n",
                    config->postrotate_prog,
                    apr_strerror(rv, error, sizeof(error)));
            return;
        }
    }
    
    /* After a error, truncate the current file and write out an error
     * message, which must be contained in message.  The process is
     * terminated on failure.  */
    static void truncate_and_write_error(rotate_status_t *status, const char *message)
    {
        apr_size_t buflen = strlen(message);
    
        if (apr_file_trunc(status->current.fd, 0) != APR_SUCCESS) {
            fprintf(stderr, "Error truncating the file %s\n", status->current.name);
            exit(2);
        }
        if (apr_file_write_full(status->current.fd, message, buflen, NULL) != APR_SUCCESS) {
            fprintf(stderr, "Error writing error (%s) to the file %s\n", 
                    message, status->current.name);
            exit(2);
        }
    }
    
    /*
     * Open a new log file, and if successful
     * also close the old one.
     *
     * The timestamp for the calculation of the file
     * name of the new log file will be the actual millisecond
     * timestamp, except when a regular rotation based on a time
     * interval is configured and the previous interval
     * is over. Then the timestamp is the starting time
     * of the actual interval.
     */
    static void doRotate(rotate_config_t *config, rotate_status_t *status)
    {
        apr_int32_t offset;
        adjusted_time_t now, tLogStart;
        apr_status_t rv;
        struct logfile newlog;
        int thisLogNum = -1;
        int oldreason = status->rotateReason;
        int truncate = config->truncate;
    
        /* Retrieve local-time-adjusted-Unix-time. */
        now = get_now(config, &offset);
    
        status->rotateReason = ROTATE_NONE;
    
        if (config->tRotation) {
            adjusted_time_t tLogEnd;
    
            tLogStart = (now / config->tRotation) * config->tRotation;
            tLogEnd = tLogStart + config->tRotation;
            /*
             * Check if rotation was forced and the last rotation
             * interval is not yet over. Use the value of now instead
             * of the time interval boundary for the file name then.
             */
            if (tLogStart < status->tLogEnd) {
                tLogStart = now;
            }
            status->tLogEnd = tLogEnd;
        }
        else {
            tLogStart = now;
        }
    
        if (config->use_strftime) {
            apr_time_t tNow = apr_time_from_sec(tLogStart);
            apr_time_exp_t e;
            apr_size_t rs;
    
            /* Explode the local-time-adjusted-Unix-time into a struct tm,
             * first *reversing* local-time-adjustment applied by
             * get_now() if we are using localtime. */
            if (config->use_localtime)
                apr_time_exp_lt(&e, tNow - apr_time_from_sec(offset));
            else
                apr_time_exp_gmt(&e, tNow);
            apr_strftime(newlog.name, &rs, sizeof(newlog.name), config->szLogRoot, &e);
        }
        else {
            if (config->truncate) {
                apr_snprintf(newlog.name, sizeof(newlog.name), "%s", config->szLogRoot);
            }
            else if (config->num_files > 0) { 
                if (status->fileNum == -1 || status->fileNum == (config->num_files - 1)) {
                    thisLogNum = 0;
                    apr_snprintf(newlog.name, sizeof(newlog.name), "%s", config->szLogRoot);
                }
                else { 
                    thisLogNum = status->fileNum + 1;
                    apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%d", config->szLogRoot, thisLogNum);
                }
            }
            else {
                apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%010ld", config->szLogRoot,
                             tLogStart);
            }
        }
        apr_pool_create(&newlog.pool, status->pool);
        if (config->create_path) {
            char *ptr = strrchr(newlog.name, '/');
            if (ptr && ptr > newlog.name) {
                char *path = apr_pstrmemdup(newlog.pool, newlog.name, ptr - newlog.name);
                if (config->verbose) {
                    fprintf(stderr, "Creating directory tree %s\n", path);
                }
                rv = apr_dir_make_recursive(path, APR_FPROT_OS_DEFAULT, newlog.pool);
                if (rv != APR_SUCCESS) {
                    char error[120];
    
                    apr_strerror(rv, error, sizeof error);
                    fprintf(stderr, "Could not create directory '%s' (%s)\n", path, error);
                    exit(2);
                }
            }
        }
        if (config->verbose) {
            fprintf(stderr, "Opening file %s\n", newlog.name);
        }
    
        if (!truncate) {
            /* -n and -T truncate subsequent files only. */
            if (status->current.fd &&
                   (config->num_files > 0 || config->truncate_rotated_only)) {
                truncate = 1;
            }
        }
        rv = apr_file_open(&newlog.fd, newlog.name,
                           APR_WRITE | APR_CREATE | APR_APPEND
                           | (truncate ? APR_TRUNCATE : 0),
                           APR_OS_DEFAULT, newlog.pool);
        if (rv == APR_SUCCESS) {
            /* Handle post-rotate processing. */
            post_rotate(newlog.pool, &newlog, config, status);
    
            status->fileNum = thisLogNum;
            /* Close out old (previously 'current') logfile, if any. */
            if (status->current.fd) {
                close_logfile(config, &status->current);
            }
    
            /* New log file is now 'current'. */
            status->current = newlog;
    
            /* The first write to the initial file hasn't checked for size.
             * In the normalized timestamp case and the custom strftime case with
             * any reasonable accuracy, it's futile as the rotation will pick the
             * same filename again. 
             * For -n, when not truncating, check and rotate.
             */
            if (config->num_files > 0 && oldreason == ROTATE_NEW && !config->truncate) {
                checkRotate(config, status);
                if (status->rotateReason != ROTATE_NONE) {
                    doRotate(config, status);
                }
            }
        }
        else {
            char *error = apr_psprintf(newlog.pool, "%pm", &rv);
            char *message;
    
            /* 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 (status->current.fd == NULL) {
                fprintf(stderr, "Could not open log file '%s' (%s)\n", newlog.name, error);
                exit(2);
            }
    
            /* Try to keep this error message constant length
             * in case it occurs several times. */
            message = apr_psprintf(newlog.pool,
                                   "Resetting log file due to error opening "
                                   "new log file, %10d messages lost: %-25.25s\n",
                                   status->nMessCount, error);
    
            truncate_and_write_error(status, message);
    
            /* Throw away new state; it isn't going to be used. */
            apr_pool_destroy(newlog.pool);
        }
    
        status->nMessCount = 0;
    }
    
    /*
     * Get a size or time param from a string.
     * Parameter 'last' indicates, whether the
     * argument is the last commandline argument.
     * UTC offset is only allowed as a last argument
     * in order to make is distinguishable from the
     * rotation interval time.
     */
    static const char *get_time_or_size(rotate_config_t *config,
                                        const char *arg, int last) {
        char *ptr = NULL;
        /* Byte multiplier */
        unsigned int mult = 1;
        if ((ptr = strchr(arg, 'B')) != NULL) { /* Found KB size */
            mult = 1;
        }
        else if ((ptr = strchr(arg, 'K')) != NULL) { /* Found KB size */
            mult = 1024;
        }
        else if ((ptr = strchr(arg, 'M')) != NULL) { /* Found MB size */
            mult = 1024 * 1024;
        }
        else if ((ptr = strchr(arg, 'G')) != NULL) { /* Found GB size */
            mult = 1024 * 1024 * 1024;
        }
        if (ptr) { /* rotation based on file size */
            if (config->sRotation > 0) {
                return "Rotation size parameter allowed only once";
            }
            if (*(ptr+1) == '\0') {
                config->sRotation = atoi(arg) * mult;
            }
            if (config->sRotation == 0) {
                return "Invalid rotation size parameter";
            }
        }
        else if ((config->sRotation > 0 || config->tRotation > 0) && last) {
            /* rotation based on elapsed time */
            if (config->use_localtime) {
                return "UTC offset parameter is not valid with -l";
            }
            config->utc_offset = atoi(arg) * 60;
        }
        else { /* rotation based on elapsed time */
            if (config->tRotation > 0) {
                return "Rotation time parameter allowed only once";
            }
            config->tRotation = atoi(arg);
            if (config->tRotation <= 0) {
                return "Invalid rotation time parameter";
            }
        }
        return NULL;
    }
    
    int main (int argc, const char * const argv[])
    {
        char buf[BUFSIZE];
        apr_size_t nRead, nWrite;
        apr_file_t *f_stdin;
        apr_file_t *f_stdout;
        apr_getopt_t *opt;
        apr_status_t rv;
        char c;
        const char *opt_arg;
        const char *err = NULL;
    #if APR_FILES_AS_SOCKETS
        apr_pollfd_t pollfd = { 0 };
        apr_status_t pollret = APR_SUCCESS;
        long polltimeout;
    #endif
    
        apr_app_initialize(&argc, &argv, NULL);
        atexit(apr_terminate);
    
        memset(&config, 0, sizeof config);
        memset(&status, 0, sizeof status);
        status.rotateReason = ROTATE_NONE;
    
        apr_pool_create(&status.pool, NULL);
        apr_getopt_init(&opt, status.pool, argc, argv);
    #if APR_FILES_AS_SOCKETS
        while ((rv = apr_getopt(opt, "lL:p:fDtTvecn:", &c, &opt_arg)) == APR_SUCCESS) {
    #else
        while ((rv = apr_getopt(opt, "lL:p:fDtTven:", &c, &opt_arg)) == APR_SUCCESS) {
    #endif
            switch (c) {
            case 'l':
                config.use_localtime = 1;
                break;
            case 'L':
                config.linkfile = opt_arg;
                break;
            case 'p':
                config.postrotate_prog = opt_arg;
    #ifdef SIGCHLD
                /* Prevent creation of zombies (on modern Unix systems). */
                apr_signal(SIGCHLD, SIG_IGN);
    #endif
                break;
            case 'f':
                config.force_open = 1;
                break;
            case 'D':
                config.create_path = 1;
                break;
            case 't':
                config.truncate = 1;
                break;
            case 'T':
                config.truncate_rotated_only = 1;
                break;
            case 'v':
                config.verbose = 1;
                break;
            case 'e':
                config.echo = 1;
                break;
    #if APR_FILES_AS_SOCKETS
            case 'c':
                config.create_empty = 1;
                break;
    #endif
            case 'n':
                config.num_files = atoi(opt_arg);
                status.fileNum = -1;
                break;
            }
        }
    
        if (rv != APR_EOF) {
            usage(argv[0], NULL /* specific error message already issued */ );
        }
    
        /*
         * After the initial flags we need 2 to 4 arguments,
         * the file name, either the rotation interval time or size
         * or both of them, and optionally the UTC offset.
         */
        if ((argc - opt->ind < 2) || (argc - opt->ind > 4) ) {
            usage(argv[0], "Incorrect number of arguments");
        }
    
        rv = apr_filepath_merge(&config.szLogRoot, "", argv[opt->ind++],
                                APR_FILEPATH_TRUENAME, status.pool);
        if (rv != APR_SUCCESS && rv != APR_EPATHWILD) {
            usage(argv[0], "Invalid filename given");
        }
    
        /* Read in the remaining flags, namely time, size and UTC offset. */
        for(; opt->ind < argc; opt->ind++) {
            if ((err = get_time_or_size(&config, argv[opt->ind],
                                        opt->ind < argc - 1 ? 0 : 1)) != NULL) {
                usage(argv[0], err);
            }
        }
    
        config.use_strftime = (strchr(config.szLogRoot, '%') != NULL);
    
        if (config.use_strftime && config.num_files > 0) { 
            fprintf(stderr, "Cannot use -n with %% in filename\n");
            exit(1);
        }
    
        if (status.fileNum == -1 && config.num_files < 1) { 
            fprintf(stderr, "Invalid -n argument\n");
            exit(1);
        }
    
        if (apr_file_open_stdin(&f_stdin, status.pool) != APR_SUCCESS) {
            fprintf(stderr, "Unable to open stdin\n");
            exit(1);
        }
    
        if (apr_file_open_stdout(&f_stdout, status.pool) != APR_SUCCESS) {
            fprintf(stderr, "Unable to open stdout\n");
            exit(1);
        }
    
        /*
         * Write out result of config parsing if verbose is set.
         */
        if (config.verbose) {
            dumpConfig(&config);
        }
    
    #if APR_FILES_AS_SOCKETS
        if (config.create_empty && config.tRotation) {
            pollfd.p = status.pool;
            pollfd.desc_type = APR_POLL_FILE;
            pollfd.reqevents = APR_POLLIN;
            pollfd.desc.f = f_stdin;
        }
    #endif
    
        /*
         * Immediately open the logfile as we start, if we were forced
         * to do so via '-f'.
         */
        if (config.force_open) {
            doRotate(&config, &status);
        }
    
        for (;;) {
            nRead = sizeof(buf);
    #if APR_FILES_AS_SOCKETS
            if (config.create_empty && config.tRotation) {
                polltimeout = status.tLogEnd ? status.tLogEnd - get_now(&config, NULL) : config.tRotation;
                if (polltimeout <= 0) {
                    pollret = APR_TIMEUP;
                }
                else {
                    pollret = apr_poll(&pollfd, 1, &pollret, apr_time_from_sec(polltimeout));
                }
            }
            if (pollret == APR_SUCCESS) {
                rv = apr_file_read(f_stdin, buf, &nRead);
                if (APR_STATUS_IS_EOF(rv)) {
                    break;
                }
                else if (rv != APR_SUCCESS) {
                    exit(3);
                }
            }
            else if (pollret == APR_TIMEUP) {
                *buf = 0;
                nRead = 0;
            }
            else {
                fprintf(stderr, "Unable to poll stdin\n");
                exit(5);
            }
    #else /* APR_FILES_AS_SOCKETS */
            rv = apr_file_read(f_stdin, buf, &nRead);
            if (APR_STATUS_IS_EOF(rv)) {
                break;
            }
            else if (rv != APR_SUCCESS) {
                exit(3);
            }
    #endif /* APR_FILES_AS_SOCKETS */
            checkRotate(&config, &status);
            if (status.rotateReason != ROTATE_NONE) {
                doRotate(&config, &status);
            }
    
            nWrite = nRead;
            rv = apr_file_write_full(status.current.fd, buf, nWrite, &nWrite);
            if (nWrite != nRead) {
                apr_off_t cur_offset;
                apr_pool_t *pool;
                char *error;
    
                cur_offset = 0;
                if (apr_file_seek(status.current.fd, APR_CUR, &cur_offset) != APR_SUCCESS) {
                    cur_offset = -1;
                }
                status.nMessCount++;
                apr_pool_create(&pool, status.pool);
                error = apr_psprintf(pool, "Error %d writing to log file at offset %"
                                     APR_OFF_T_FMT ". %10d messages lost (%pm)\n",
                                     rv, cur_offset, status.nMessCount, &rv);
    
                truncate_and_write_error(&status, error);
                apr_pool_destroy(pool);
            }
            else {
                status.nMessCount++;
            }
            if (config.echo) {
                if (apr_file_write_full(f_stdout, buf, nRead, &nWrite)) {
                    fprintf(stderr, "Unable to write to stdout\n");
                    exit(4);
                }
            }
        }
    
        return 0; /* reached only at stdin EOF. */
    }
    ������������������������������������������������������������������������������������������������������httpd-2.4.64/support/dbmmanage.in�������������������������������������������������������������������0000664�0001751�0001751�00000021246�14571614732�016620� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!@perlbin@
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 <DBMfile> <command> <user> <password> <groups> <comment>
    
    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 <<SYNTAX;
    Usage: dbmmanage [enc] dbname command [username [pw [group[,group] [comment]]]]
    
        where enc is  -d for crypt hashing (default except on Win32, Netware)
                      -m for MD5 hashing (default on Win32, Netware)
                      -s for SHA1 hashing
                      -p for plaintext
    
        command is one of: $cmds
    
        pw of . for update command retains the old password
        pw of - (or blank) for update command prompts for the password
    
        groups or comment of . (or blank) for update command retains old values
        groups or comment of - for update command clears the existing value
        groups or comment of - for add and adduser commands is the empty value
    SYNTAX
    }
    
    sub need_sha1_hash {
        if (!eval ('require "Digest/SHA1.pm";')) {
            print STDERR <<SHAERR;
    dbmmanage SHA1 passwords require the interface or the module Digest::SHA1
    available from CPAN:
    
        http://www.cpan.org/modules/by-module/Digest/Digest-MD5-2.12.tar.gz
    
    Please install Digest::SHA1 and try again, or use a different hashing option:
    
    SHAERR
            usage();
        }
    }
    
    sub need_md5_hash {
        if (!eval ('require "Crypt/PasswdMD5.pm";')) {
            print STDERR <<MD5ERR;
    dbmmanage MD5 passwords require the module Crypt::PasswdMD5 available from CPAN
    
        http://www.cpan.org/modules/by-module/Crypt/Crypt-PasswdMD5-1.1.tar.gz
    
    Please install Crypt::PasswdMD5 and try again, or use a different hashing option:
    
    MD5ERR
            usage();
        }
    }
    
    # if your osname is in $newstyle_salt, then use new style salt (starts with '_' and contains
    # four bytes of iteration count and four bytes of salt).  Otherwise, just use
    # the traditional two-byte salt.
    # see the man page on your system to decide if you have a newer crypt() lib.
    # I believe that 4.4BSD derived systems do (at least BSD/OS 2.0 does).
    # The new style crypt() allows up to 20 characters of the password to be
    # significant rather than only 8.
    #
    my $newstyle_salt_platforms = join '|', qw{bsdos}; #others?
    my $newstyle_salt = $^O =~ /(?:$newstyle_salt_platforms)/;
    
    # Some platforms just can't crypt() for Apache
    #
    my $crypt_not_supported_platforms = join '|', qw{MSWin32 NetWare}; #others?
    my $crypt_not_supported = $^O =~ /(?:$crypt_not_supported_platforms)/;
    
    my $hash_method = "crypt";
    
    if ($crypt_not_supported) {
        $hash_method = "md5";
    }
    
    # Some platforms won't jump through our favorite hoops
    #
    my $not_unix_platforms = join '|', qw{MSWin32 NetWare}; #others?
    my $not_unix = $^O =~ /(?:$not_unix_platforms)/;
    
    if ($crypt_not_supported) {
        $hash_method = "md5";
    }
    
    if (@ARGV[0] eq "-d") {
        shift @ARGV;
        if ($crypt_not_supported) {
            print STDERR
                  "Warning: Apache/$^O does not support crypt()ed passwords!\n\n";
        }
        $hash_method = "crypt";
    }
    
    if (@ARGV[0] eq "-m") {
        shift @ARGV;
        $hash_method = "md5";
    }
    
    if (@ARGV[0] eq "-p") {
        shift @ARGV;
        if (!$crypt_not_supported) {
            print STDERR
                  "Warning: Apache/$^O does not support plaintext passwords!\n\n";
        }
        $hash_method = "plain";
    }
    
    if (@ARGV[0] eq "-s") {
        shift @ARGV;
        need_sha1_hash();
        $hash_method = "sha1";
    }
    
    if ($hash_method eq "md5") {
        need_md5_hash();
    }
    
    my($file,$command,$key,$hashed_pwd,$groups,$comment) = @ARGV;
    
    usage() unless $file and $command and defined &{$dbmc::{$command}};
    
    # remove extension if any
    my $chop = join '|', qw{db.? pag dir};
    $file =~ s/\.($chop)$//;
    
    my $is_update = $command eq "update";
    my %DB = ();
    my @range = ();
    my($mode, $flags) = $command =~
        /^(?:view|check)$/ ? (0644, O_RDONLY) : (0644, O_RDWR|O_CREAT);
    
    tie (%DB, "AnyDBM_File", $file, $flags, $mode) || die "Can't tie $file: $!";
    dbmc->$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 hashpw_crypt {
        my ($pw, $salt) = @_;
        $salt = saltpw_crypt unless $salt;
        crypt $pw, $salt;
    }
    
    sub saltpw_md5 {
        genseed() unless @range;
        randchar(8);
    }
    
    sub hashpw_md5 {
        my($pw, $salt) = @_;
        $salt = saltpw_md5 unless $salt;
        Crypt::PasswdMD5::apache_md5_crypt($pw, $salt);
    }
    
    sub hashpw_sha1 {
        my($pw, $salt) = @_;
        '{SHA}' . Digest::SHA1::sha1_base64($pw) . "=";
    }
    
    sub hashpw {
        if ($hash_method eq "md5") {
            return hashpw_md5(@_);
        } elsif ($hash_method eq "sha1") {
            return hashpw_sha1(@_);
        } elsif ($hash_method eq "crypt") {
            return hashpw_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};
        $hashed_pwd = (split /:/, $DB{$key}, 3)[0] if $hashed_pwd eq '.';
        $groups = (split /:/, $DB{$key}, 3)[1] if !$groups || $groups eq '.';
        $comment = (split /:/, $DB{$key}, 3)[2] if !$comment || $comment eq '.';
        if (!$hashed_pwd || $hashed_pwd eq '-') {
            dbmc->adduser;
        }
        else {
            dbmc->add;
        }
    }
    
    sub dbmc::add {
        die "Can't use empty password!\n" unless $hashed_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;
        $hashed_pwd .= ":" . $groups if $groups;
        $DB{$key} = $hashed_pwd;
        my $action = $is_update ? "updated" : "added";
        print "User $key $action with password hashed to $DB{$key} using $hash_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;
        $hashed_pwd = hashpw $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_hash;
            $hash_method = "md5";
        } elsif (substr($chkpass, 0, 5) eq '{SHA}') {
            need_sha1_hash;
            $hash_method = "sha1";
        } elsif (length($chkpass) == 13 && $chkpass ne $testpass) {
            $hash_method = "crypt";
        } else {
            $hash_method = "plain";
        }
        print $hash_method . (hashpw($testpass, $chkpass) eq $chkpass
                              ? " password ok\n" : " password mismatch\n");
    }
    
    sub dbmc::import {
        while(defined($_ = <STDIN>) and chomp) {
            ($key,$hashed_pwd,$groups,$comment) = split /:/, $_, 4;
            dbmc->add;
        }
    }
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/passwd_common.c����������������������������������������������������������������0000664�0001751�0001751�00000026213�14556746320�017373� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "passwd_common.h"
    #include "apr_strings.h"
    #include "apr_errno.h"
    
    #if APR_HAVE_STDIO_H
    #include <stdio.h>
    #endif
    
    #include "apr_md5.h"
    #include "apr_sha1.h"
    
    #if APR_HAVE_TIME_H
    #include <time.h>
    #endif
    #if APR_HAVE_CRYPT_H
    #include <crypt.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_STRING_H
    #include <string.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if APR_HAVE_IO_H
    #include <io.h>
    #endif
    
    #ifdef _MSC_VER
    #define write _write
    #endif
    
    apr_file_t *errfile;
    
    int abort_on_oom(int rc)
    {
        const char *buf = "Error: out of memory\n";
        int written, count = strlen(buf);
        do {
            written = write(STDERR_FILENO, buf, count);
            if (written == count)
                break;
            if (written > 0) {
                buf += written;
                count -= written;
            }
        } while (written >= 0 || errno == EINTR);
        abort();
        /* NOTREACHED */
        return 0;
    }
    
    static int generate_salt(char *s, size_t size, const char **errstr,
                             apr_pool_t *pool)
    {
        unsigned char rnd[32];
        static const char itoa64[] =
            "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        apr_size_t n;
        unsigned int val = 0, bits = 0;
        apr_status_t rv;
    
        n = (size * 6 + 7)/8;
        if (n > sizeof(rnd)) {
            apr_file_printf(errfile, "generate_salt(): BUG: Buffer too small");
            abort();
        }
        rv = apr_generate_random_bytes(rnd, n);
        if (rv) {
            *errstr = apr_psprintf(pool, "Unable to generate random bytes: %pm",
                                   &rv);
            return ERR_RANDOM;
        }
        n = 0;
        while (size > 0) {
            if (bits < 6) {
                val |= (rnd[n++] << bits);
                bits += 8;
            }
            *s++ = itoa64[val & 0x3f];
            size--;
            val >>= 6;
            bits -= 6;
        }
        *s = '\0';
        return 0;
    }
    
    void putline(apr_file_t *f, const char *l)
    {
        apr_status_t rv;
        if (f == NULL)
            return;
        rv = apr_file_puts(l, f);
        if (rv != APR_SUCCESS) {
            apr_file_printf(errfile, "Error writing temp file: %pm", &rv);
            apr_file_close(f);
            exit(ERR_FILEPERM);
        }
    }
    
    int get_password(struct passwd_ctx *ctx)
    {
        char buf[MAX_STRING_LEN + 1];
        if (ctx->passwd_src == PW_STDIN) {
            apr_file_t *file_stdin;
            apr_size_t nread;
            if (apr_file_open_stdin(&file_stdin, ctx->pool) != APR_SUCCESS) {
                ctx->errstr = "Unable to read from stdin.";
                return ERR_GENERAL;
            }
            if (apr_file_read_full(file_stdin, buf, sizeof(buf) - 1,
                                   &nread) != APR_EOF
                || nread == sizeof(buf) - 1) {
                goto err_too_long;
            }
            buf[nread] = '\0';
            if (nread >= 1 && buf[nread-1] == '\n') {
                buf[nread-1] = '\0';
                if (nread >= 2 && buf[nread-2] == '\r')
                    buf[nread-2] = '\0';
            }
            apr_file_close(file_stdin);
            ctx->passwd = apr_pstrdup(ctx->pool, buf);
        }
        else if (ctx->passwd_src == PW_PROMPT_VERIFY) {
            apr_size_t bufsize = sizeof(buf);
            if (apr_password_get("Enter password: ", buf, &bufsize) != 0)
                goto err_too_long;
            ctx->passwd = apr_pstrdup(ctx->pool, buf);
        }
        else {
            apr_size_t bufsize = sizeof(buf);
            if (apr_password_get("New password: ", buf, &bufsize) != 0)
                goto err_too_long;
            ctx->passwd = apr_pstrdup(ctx->pool, buf);
            bufsize = sizeof(buf);
            buf[0] = '\0';
            apr_password_get("Re-type new password: ", buf, &bufsize);
            if (strcmp(ctx->passwd, buf) != 0) {
                ctx->errstr = "password verification error";
                memset(ctx->passwd, '\0', strlen(ctx->passwd));
                memset(buf, '\0', sizeof(buf));
                return ERR_PWMISMATCH;
            }
        }
        memset(buf, '\0', sizeof(buf));
        return 0;
    
    err_too_long:
        ctx->errstr = apr_psprintf(ctx->pool,
                                   "password too long (>%" APR_SIZE_T_FMT ")",
                                   sizeof(buf) - 1);
        return ERR_OVERFLOW;
    }
    
    /*
     * Make a password record from the given information.  A zero return
     * indicates success; on failure, ctx->errstr points to the error message.
     */
    int mkhash(struct passwd_ctx *ctx)
    {
        char *pw;
        char salt[17];
        apr_status_t rv;
        int ret = 0;
    #if CRYPT_ALGO_SUPPORTED
        char *cbuf;
    #endif
    #ifdef HAVE_CRYPT_SHA2
        const char *setting;
        char method;
    #endif
    
        if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT
            && ctx->alg != ALG_CRYPT_SHA256 && ctx->alg != ALG_CRYPT_SHA512 ) {
            apr_file_printf(errfile,
                            "Warning: Ignoring -C/-r argument for this algorithm." NL);
        }
    
        if (ctx->passwd == NULL) {
            if ((ret = get_password(ctx)) != 0)
                return ret;
        }
        pw = ctx->passwd;
    
        switch (ctx->alg) {
        case ALG_APSHA:
            /* XXX out >= 28 + strlen(sha1) chars - fixed len SHA */
            apr_sha1_base64(pw, strlen(pw), ctx->out);
            break;
    
        case ALG_APMD5:
            ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
            if (ret != 0)
                break;
            rv = apr_md5_encode(pw, salt, ctx->out, ctx->out_len);
            if (rv != APR_SUCCESS) {
                ctx->errstr = apr_psprintf(ctx->pool,
                                           "could not encode password: %pm", &rv);
                ret = ERR_GENERAL;
            }
            break;
    
        case ALG_PLAIN:
            /* XXX this len limitation is not in sync with any HTTPd len. */
            apr_cpystrn(ctx->out, pw, ctx->out_len);
            break;
    
    #if CRYPT_ALGO_SUPPORTED
        case ALG_CRYPT:
            ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
            if (ret != 0)
                break;
            cbuf = crypt(pw, salt);
            if (cbuf == NULL) {
                rv = APR_FROM_OS_ERROR(errno);
                ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
                ret = ERR_PWMISMATCH;
                break;
            }
    
            apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
            if (strlen(pw) > 8) {
                char *truncpw = apr_pstrdup(ctx->pool, pw);
                truncpw[8] = '\0';
                if (!strcmp(ctx->out, crypt(truncpw, salt))) {
                    apr_file_printf(errfile, "Warning: Password truncated to 8 "
                                    "characters by CRYPT algorithm." NL);
                }
                memset(truncpw, '\0', strlen(pw));
            }
            break;
    #endif /* CRYPT_ALGO_SUPPORTED */
    
    #ifdef HAVE_CRYPT_SHA2
        case ALG_CRYPT_SHA256:
        case ALG_CRYPT_SHA512:
            ret = generate_salt(salt, 16, &ctx->errstr, ctx->pool);
            if (ret != 0)
                break;
    
            method = ctx->alg == ALG_CRYPT_SHA256 ? '5': '6';
    
            if (ctx->cost) 
                setting = apr_psprintf(ctx->pool, "$%c$rounds=%d$%s",
                                       method, ctx->cost, salt);
            else
                setting = apr_psprintf(ctx->pool, "$%c$%s",
                                       method, salt);
    
            cbuf = crypt(pw, setting);
            if (cbuf == NULL) {
                rv = APR_FROM_OS_ERROR(errno);
                ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
                ret = ERR_PWMISMATCH;
                break;
            }
    
            apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
            break;
    #endif /* HAVE_CRYPT_SHA2 */
    
    #if BCRYPT_ALGO_SUPPORTED
        case ALG_BCRYPT:
            rv = apr_generate_random_bytes((unsigned char*)salt, 16);
            if (rv != APR_SUCCESS) {
                ctx->errstr = apr_psprintf(ctx->pool, "Unable to generate random "
                                           "bytes: %pm", &rv);
                ret = ERR_RANDOM;
                break;
            }
    
            if (ctx->cost == 0)
                ctx->cost = BCRYPT_DEFAULT_COST;
            rv = apr_bcrypt_encode(pw, ctx->cost, (unsigned char*)salt, 16,
                                   ctx->out, ctx->out_len);
            if (rv != APR_SUCCESS) {
                ctx->errstr = apr_psprintf(ctx->pool, "Unable to encode with "
                                           "bcrypt: %pm", &rv);
                ret = ERR_PWMISMATCH;
                break;
            }
            break;
    #endif /* BCRYPT_ALGO_SUPPORTED */
    
        default:
            apr_file_printf(errfile, "mkhash(): BUG: invalid algorithm %d",
                            ctx->alg);
            abort();
        }
        memset(pw, '\0', strlen(pw));
        return ret;
    }
    
    int parse_common_options(struct passwd_ctx *ctx, char opt,
                              const char *opt_arg)
    {
        switch (opt) {
        case 'b':
            ctx->passwd_src = PW_ARG;
            break;
        case 'i':
            ctx->passwd_src = PW_STDIN;
            break;
        case 'm':
            ctx->alg = ALG_APMD5;
            break;
        case 's':
            ctx->alg = ALG_APSHA;
            break;
    #ifdef HAVE_CRYPT_SHA2
        case '2':
            ctx->alg = ALG_CRYPT_SHA256;
            break;
        case '5':
            ctx->alg = ALG_CRYPT_SHA512;
            break;
    #else
        case '2':
        case '5':
            ctx->errstr = "SHA-2 crypt() algorithms are not supported on this platform.";
            return ERR_ALG_NOT_SUPP;
    #endif
        case 'p':
            ctx->alg = ALG_PLAIN;
    #if !PLAIN_ALGO_SUPPORTED
            /* Backward compatible behavior: Just print a warning */
            apr_file_printf(errfile,
                            "Warning: storing passwords as plain text might just "
                            "not work on this platform." NL);
    #endif
            break;
        case 'd':
    #if CRYPT_ALGO_SUPPORTED
            ctx->alg = ALG_CRYPT;
    #else
            /* Backward compatible behavior: Use MD5. OK since MD5 is more secure */
            apr_file_printf(errfile,
                            "Warning: CRYPT algorithm not supported on this "
                            "platform." NL
                            "Automatically using MD5 format." NL);
            ctx->alg = ALG_APMD5;
    #endif
            break;
        case 'B':
    #if BCRYPT_ALGO_SUPPORTED
            ctx->alg = ALG_BCRYPT;
    #else
            /* Don't fall back to something less secure */
            ctx->errstr = "BCRYPT algorithm not supported on this platform";
            return ERR_ALG_NOT_SUPP;
    #endif
            break;
        case 'C':
        case 'r': {
                char *endptr;
                long num = strtol(opt_arg, &endptr, 10);
                if (*endptr != '\0' || num <= 0) {
                    ctx->errstr = "argument to -C/-r must be a positive integer";
                    return ERR_SYNTAX;
                }
                ctx->cost = num;
                break;
            }
        default:
            apr_file_printf(errfile, 
                            "parse_common_options(): BUG: invalid option %c",
                            opt);
            abort();
        }
        return 0;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htcacheclean.c�����������������������������������������������������������������0000664�0001751�0001751�00000174117�14571615032�017123� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <ast domdv.de>
     * 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_md5.h"
    #include "apr_ring.h"
    #include "apr_date.h"
    #include "apr_buckets.h"
    
    #include "../modules/cache/cache_common.h"
    #include "../modules/cache/cache_disk_common.h"
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    
    /* 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 GBYTE         1073741824
    
    #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 deldirs;     /* flag: true means directories should be deleted */
    static int listurls;    /* flag: true means list cached urls */
    static int listextended;/* flag: true means list cached urls */
    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_file_t *outfile;   /* stdout file handle */
    static apr_off_t unsolicited; /* file size summary for deleted unsolicited
                                     files */
    static ENTRY root; /* ENTRY ring anchor */
    
    /* short program name as called */
    static const char *shortname = "htcacheclean";
    
    /* what did we clean? */
    struct stats {
        apr_off_t total;
        apr_off_t sum;
        apr_off_t max;
        apr_off_t ntotal;
        apr_off_t nodes;
        apr_off_t inodes;
        apr_off_t etotal;
        apr_off_t entries;
        apr_off_t dfuture;
        apr_off_t dexpired;
        apr_off_t dfresh;
    };
    
    
    #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(char *path, struct stats *s)
    {
        char ttype, stype, mtype, utype;
        apr_off_t tfrag, sfrag, ufrag;
    
        if (!verbose) {
            return;
        }
    
        ttype = 'K';
        tfrag = ((s->total * 10) / KBYTE) % 10;
        s->total /= KBYTE;
        if (s->total >= KBYTE) {
            ttype = 'M';
            tfrag = ((s->total * 10) / KBYTE) % 10;
            s->total /= KBYTE;
        }
    
        stype = 'K';
        sfrag = ((s->sum * 10) / KBYTE) % 10;
        s->sum /= KBYTE;
        if (s->sum >= KBYTE) {
            stype = 'M';
            sfrag = ((s->sum * 10) / KBYTE) % 10;
            s->sum /= KBYTE;
        }
    
        mtype = 'K';
        s->max /= KBYTE;
        if (s->max >= KBYTE) {
            mtype = 'M';
            s->max /= KBYTE;
        }
    
        apr_file_printf(errfile, "Cleaned %s. Statistics:" APR_EOL_STR, path);
        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 %" APR_OFF_T_FMT ".0%c" APR_EOL_STR,
                s->max, mtype);
        apr_file_printf(errfile, "inodes limit %" APR_OFF_T_FMT APR_EOL_STR,
                s->inodes);
        apr_file_printf(
                errfile,
                "total size was %" APR_OFF_T_FMT ".%" APR_OFF_T_FMT "%c, total size now "
                "%" APR_OFF_T_FMT ".%" APR_OFF_T_FMT "%c" APR_EOL_STR, s->total,
                tfrag, ttype, s->sum, sfrag, stype);
        apr_file_printf(errfile, "total inodes was %" APR_OFF_T_FMT
                ", total %sinodes now "
                "%" APR_OFF_T_FMT APR_EOL_STR, s->ntotal, dryrun && deldirs ? "estimated "
                : "", s->nodes);
        apr_file_printf(
                errfile,
                "total entries was %" APR_OFF_T_FMT ", total entries now %" APR_OFF_T_FMT
                APR_EOL_STR, s->etotal, s->entries);
        apr_file_printf(
                errfile,
                "%" APR_OFF_T_FMT " entries deleted (%" APR_OFF_T_FMT " from future, %"
                APR_OFF_T_FMT " expired, %" APR_OFF_T_FMT " fresh)" APR_EOL_STR,
                (s->etotal - s->entries), s->dfuture, s->dexpired, s->dfresh);
    }
    
    /**
     * Round the value up to the given threshold.
     */
    static apr_size_t round_up(apr_size_t val, apr_off_t round)
    {
        if (round > 1) {
            return (apr_size_t)(((val + round - 1) / round) * round);
        }
        return val;
    }
    
    /*
     * delete parent directories
     */
    static void delete_parent(const char *path, const char *basename,
            apr_off_t *nodes, apr_pool_t *pool)
    {
        char *nextpath, *name;
        apr_pool_t *p;
    
        /* temp pool, otherwise lots of memory could be allocated */
        apr_pool_create(&p, pool);
        name = apr_pstrdup(p, basename);
    
        /* If asked to delete dirs, do so now. We don't care if it fails.
         * If it fails, it likely means there was something else there.
         */
        if (deldirs && !dryrun) {
            const char *vary;
            char *end = strrchr(name, '/');
            while (end) {
                *end = 0;
    
                /* remove the directory */
                nextpath = apr_pstrcat(p, path, "/", name, NULL);
                if (!apr_dir_remove(nextpath, p)) {
                    (*nodes)--;
    
                    /* vary directory found? */
                    vary = strstr(name, CACHE_VDIR_SUFFIX);
                    if (vary && !vary[sizeof(CACHE_VDIR_SUFFIX) - 1]) {
                        nextpath = apr_pstrcat(p, path, "/", apr_pstrndup(p, name, vary
                                - name), NULL);
                        if (!apr_file_remove(nextpath, p)) {
                            (*nodes)--;
                        }
                    }
    
                }
                else {
                    break;
                }
                end = strrchr(name, '/');
            }
        }
    
        apr_pool_destroy(p);
    
        if (benice) {
            if (++delcount >= DELETE_NICE) {
                apr_sleep(NICE_DELAY);
                delcount = 0;
            }
        }
    
    }
    
    /*
     * delete a single file
     */
    static void delete_file(char *path, char *basename, apr_off_t *nodes,
            apr_pool_t *pool)
    {
        char *nextpath;
        apr_pool_t *p;
    
        /* temp pool, otherwise lots of memory could be allocated */
        apr_pool_create(&p, pool);
        nextpath = apr_pstrcat(p, path, "/", basename, NULL);
    
        if (dryrun) {
            apr_finfo_t finfo;
            if (!apr_stat(&finfo, nextpath, APR_FINFO_NLINK, p)) {
                (*nodes)--;
            }
        }
        else if (!apr_file_remove(nextpath, p)) {
            (*nodes)--;
        }
    
        apr_pool_destroy(p);
    
        if (benice) {
            if (++delcount >= DELETE_NICE) {
                apr_sleep(NICE_DELAY);
                delcount = 0;
            }
        }
    
        delete_parent(path, basename, nodes, pool);
    
    }
    
    /*
     * delete cache file set
     */
    static void delete_entry(char *path, char *basename, apr_off_t *nodes,
            apr_pool_t *pool)
    {
        char *nextpath;
        apr_pool_t *p;
    
        /* temp pool, otherwise lots of memory could be allocated */
        apr_pool_create(&p, pool);
    
        nextpath = apr_pstrcat(p, path, "/", basename, CACHE_HEADER_SUFFIX, NULL);
        if (dryrun) {
            apr_finfo_t finfo;
            if (!apr_stat(&finfo, nextpath, APR_FINFO_NLINK, p)) {
                (*nodes)--;
            }
        }
        else if (!apr_file_remove(nextpath, p)) {
            (*nodes)--;
        }
    
        nextpath = apr_pstrcat(p, path, "/", basename, CACHE_DATA_SUFFIX, NULL);
        if (dryrun) {
            apr_finfo_t finfo;
            if (!apr_stat(&finfo, nextpath, APR_FINFO_NLINK, p)) {
                (*nodes)--;
            }
        }
        else if (!apr_file_remove(nextpath, p)) {
            (*nodes)--;
        }
    
        apr_pool_destroy(p);
    
        if (benice) {
            delcount += 2;
            if (delcount >= DELETE_NICE) {
                apr_sleep(NICE_DELAY);
                delcount = 0;
            }
        }
    
        delete_parent(path, basename, nodes, pool);
    
    }
    
    /*
     * list the cache directory tree
     */
    static int list_urls(char *path, apr_pool_t *pool, apr_off_t round)
    {
        apr_dir_t *dir;
        apr_finfo_t info;
        apr_size_t len;
        apr_pool_t *p;
        apr_file_t *fd;
        const char *ext, *nextpath;
        char *url;
        apr_uint32_t format;
        disk_cache_info_t disk_info;
    
        apr_pool_create(&p, pool);
    
        if (apr_dir_open(&dir, path, p) != APR_SUCCESS) {
            return 1;
        }
    
        while (apr_dir_read(&info, APR_FINFO_TYPE, dir) == APR_SUCCESS && !interrupted) {
    
            if (info.filetype == APR_DIR) {
                if (!strcmp(info.name, ".") || !strcmp(info.name, "..")) {
                    continue;
                }
    
                if (list_urls(apr_pstrcat(p, path, "/", info.name, NULL), pool, round)) {
                    return 1;
                }
            }
    
            else if (info.filetype == APR_REG) {
    
                ext = strchr(info.name, '.');
    
                if (ext && !strcasecmp(ext, CACHE_HEADER_SUFFIX)) {
    
                    nextpath = apr_pstrcat(p, path, "/", info.name, NULL);
    
                    if (apr_file_open(&fd, nextpath, APR_FOPEN_READ
                            | APR_FOPEN_BINARY, APR_OS_DEFAULT, p) == APR_SUCCESS) {
                        len = sizeof(format);
                        if (apr_file_read_full(fd, &format, len, &len)
                                == APR_SUCCESS) {
                            if (format == DISK_FORMAT_VERSION) {
                                apr_off_t offset = 0;
    
                                apr_file_seek(fd, APR_SET, &offset);
    
                                len = sizeof(disk_cache_info_t);
    
                                if (apr_file_read_full(fd, &disk_info, len, &len)
                                        == APR_SUCCESS) {
                                    len = disk_info.name_len;
                                    url = apr_palloc(p, len + 1);
                                    url[len] = 0;
    
                                    if (apr_file_read_full(fd, url, len, &len)
                                            == APR_SUCCESS) {
    
                                        if (listextended) {
                                            apr_finfo_t hinfo, dinfo;
    
                                            /* stat the header file */
                                            if (APR_SUCCESS != apr_file_info_get(
                                                    &hinfo, APR_FINFO_SIZE, fd)) {
                                                /* ignore the file */
                                            }
                                            else if (disk_info.has_body && APR_SUCCESS
                                                    != apr_stat(
                                                            &dinfo,
                                                            apr_pstrcat(
                                                                    p,
                                                                    path,
                                                                    "/",
                                                                    apr_pstrndup(
                                                                            p,
                                                                            info.name,
                                                                            ext
                                                                                    - info.name),
                                                                    CACHE_DATA_SUFFIX,
                                                                    NULL),
                                                            APR_FINFO_SIZE
                                                                    | APR_FINFO_IDENT,
                                                            p)) {
                                                /* ignore the file */
                                            }
                                            else if (disk_info.has_body && (dinfo.device
                                                    != disk_info.device
                                                    || dinfo.inode
                                                            != disk_info.inode)) {
                                                /* ignore the file */
                                            }
                                            else {
    
                                                apr_file_printf(
                                                        outfile,
                                                        "%s %" APR_SIZE_T_FMT
                                                        " %" APR_SIZE_T_FMT
                                                        " %d %" APR_SIZE_T_FMT
                                                        " %" APR_TIME_T_FMT
                                                        " %" APR_TIME_T_FMT
                                                        " %" APR_TIME_T_FMT
                                                        " %" APR_TIME_T_FMT
                                                        " %d %d\n",
                                                        url,
                                                        round_up((apr_size_t)hinfo.size, round),
                                                        round_up(
                                                                disk_info.has_body ? (apr_size_t)dinfo.size
                                                                        : 0, round),
                                                        disk_info.status,
                                                        disk_info.entity_version,
                                                        disk_info.date,
                                                        disk_info.expire,
                                                        disk_info.request_time,
                                                        disk_info.response_time,
                                                        disk_info.has_body,
                                                        disk_info.header_only);
                                            }
                                        }
                                        else {
                                            apr_finfo_t dinfo;
    
                                            /* stat the data file */
                                            if (disk_info.has_body && APR_SUCCESS
                                                    != apr_stat(
                                                            &dinfo,
                                                            apr_pstrcat(
                                                                    p,
                                                                    path,
                                                                    "/",
                                                                    apr_pstrndup(
                                                                            p,
                                                                            info.name,
                                                                            ext
                                                                                    - info.name),
                                                                    CACHE_DATA_SUFFIX,
                                                                    NULL),
                                                            APR_FINFO_SIZE
                                                                    | APR_FINFO_IDENT,
                                                            p)) {
                                                /* ignore the file */
                                            }
                                            else if (disk_info.has_body && (dinfo.device
                                                    != disk_info.device
                                                    || dinfo.inode
                                                            != disk_info.inode)) {
                                                /* ignore the file */
                                            }
                                            else {
                                                apr_file_printf(outfile, "%s\n",
                                                        url);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        apr_file_close(fd);
    
                    }
                }
            }
    
        }
    
        apr_dir_close(dir);
    
        if (interrupted) {
            return 1;
        }
    
        apr_pool_destroy(p);
    
        if (benice) {
            apr_sleep(NICE_DELAY);
        }
    
        if (interrupted) {
            return 1;
        }
    
        return 0;
    }
    
    /*
     * walk the cache directory tree
     */
    static int process_dir(char *path, apr_pool_t *pool, apr_off_t *nodes)
    {
        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;
        DIRENTRY *d, *t, *n, anchor;
        ENTRY *e;
        int skip, retries;
        disk_cache_info_t disk_info;
    
        APR_RING_INIT(&anchor.link, _direntry, link);
        apr_pool_create(&p, pool);
        h = apr_hash_make(p);
        fd = NULL;
        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.link, d, _direntry, link);
            (*nodes)++;
        }
    
        apr_dir_close(dir);
    
        if (interrupted) {
            return 1;
        }
    
        skip = baselen + 1;
    
        for (d = APR_RING_FIRST(&anchor.link);
             !interrupted && d != APR_RING_SENTINEL(&anchor.link, _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 an error 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) {
                char *dirpath = apr_pstrdup(p, d->basename);
    
                if (process_dir(d->basename, pool, nodes)) {
                    return 1;
                }
                /* When given the -t option htcacheclean does not
                 * delete directories that are already empty, so we'll do that here
                 * since process_dir checks all the directories.
                 * If it fails, it likely means there was something else there.
                 */
                if (deldirs && !dryrun) {
                    apr_dir_remove(dirpath, p);
                }
                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_uint32_t format;
    
            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_FOPEN_READ | APR_FOPEN_BINARY,
                                  APR_OS_DEFAULT, p) == APR_SUCCESS) {
                    len = sizeof(format);
                    if (apr_file_read_full(fd, &format, len,
                                           &len) == APR_SUCCESS) {
                        if (format == DISK_FORMAT_VERSION) {
                            apr_off_t offset = 0;
    
                            apr_file_seek(fd, APR_SET, &offset);
    
                            len = sizeof(disk_cache_info_t);
    
                            if (apr_file_read_full(fd, &disk_info, len,
                                                   &len) == APR_SUCCESS) {
                                apr_file_close(fd);
                                e = apr_palloc(pool, sizeof(ENTRY));
                                APR_RING_INSERT_TAIL(&root.link, 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_pstrdup(pool, d->basename);
                                if (!disk_info.has_body) {
                                    delete_file(path, apr_pstrcat(p, path, "/",
                                            d->basename, CACHE_DATA_SUFFIX, NULL),
                                            nodes, p);
                                }
                                break;
                            }
                            else {
                                apr_file_close(fd);
                            }
                        }
                        else if (format == VARY_FORMAT_VERSION) {
                            apr_finfo_t finfo;
    
                            /* This must be a URL that added Vary headers later,
                             * so kill the orphaned .data file
                             */
                            apr_file_close(fd);
    
                            if (apr_stat(&finfo, apr_pstrcat(p, nextpath,
                                    CACHE_VDIR_SUFFIX, NULL), APR_FINFO_TYPE, p)
                                    || finfo.filetype != APR_DIR) {
                                delete_entry(path, d->basename, nodes, p);
                            }
                            else {
                                delete_file(path, apr_pstrcat(p, path, "/",
                                        d->basename, CACHE_DATA_SUFFIX, NULL),
                                        nodes, p);
                            }
                            break;
                        }
                        else {
                            /* We didn't recognise the format, kill the files */
                            apr_file_close(fd);
                            delete_entry(path, d->basename, nodes, p);
                            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, nodes, 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();
                nextpath = apr_pstrcat(p, path, "/", d->basename,
                                       CACHE_HEADER_SUFFIX, NULL);
                if (apr_file_open(&fd, nextpath, APR_FOPEN_READ | APR_FOPEN_BINARY,
                                  APR_OS_DEFAULT, p) == APR_SUCCESS) {
                    len = sizeof(format);
                    if (apr_file_read_full(fd, &format, len,
                                           &len) == APR_SUCCESS) {
                        if (format == VARY_FORMAT_VERSION) {
                            apr_time_t expires;
    
                            len = sizeof(expires);
    
                            if (apr_file_read_full(fd, &expires, len,
                                                   &len) == APR_SUCCESS) {
                                apr_finfo_t finfo;
    
                                apr_file_close(fd);
    
                                if (apr_stat(&finfo, apr_pstrcat(p, nextpath,
                                        CACHE_VDIR_SUFFIX, NULL), APR_FINFO_TYPE, p)
                                        || finfo.filetype != APR_DIR) {
                                    delete_entry(path, d->basename, nodes, p);
                                }
                                else if (expires < current) {
                                    delete_entry(path, d->basename, nodes, p);
                                }
    
                                break;
                            }
                        }
                        else if (format == DISK_FORMAT_VERSION) {
                            apr_off_t offset = 0;
    
                            apr_file_seek(fd, APR_SET, &offset);
    
                            len = sizeof(disk_cache_info_t);
    
                            if (apr_file_read_full(fd, &disk_info, len,
                                                   &len) == APR_SUCCESS) {
                                apr_file_close(fd);
                                e = apr_palloc(pool, sizeof(ENTRY));
                                APR_RING_INSERT_TAIL(&root.link, 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_pstrdup(pool, d->basename);
                                break;
                            }
                            else {
                                apr_file_close(fd);
                            }
                        }
                        else {
                            apr_file_close(fd);
                            delete_entry(path, d->basename, nodes, p);
                            break;
                        }
                    }
                    else {
                        apr_file_close(fd);
                    }
                }
    
                if (realclean || d->htime < current - deviation
                    || d->htime > current + deviation) {
                    delete_entry(path, d->basename, nodes, 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, nodes, 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, nodes, 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 inodes, apr_off_t nodes, apr_off_t round)
    {
        ENTRY *e, *n, *oldest;
    
        struct stats s;
        s.sum = 0;
        s.entries = 0;
        s.dfuture = 0;
        s.dexpired = 0;
        s.dfresh = 0;
        s.max = max;
        s.nodes = nodes;
        s.inodes = inodes;
        s.ntotal = nodes;
    
        for (e = APR_RING_FIRST(&root.link);
             e != APR_RING_SENTINEL(&root.link, _entry, link);
             e = APR_RING_NEXT(e, link)) {
            s.sum += round_up((apr_size_t)e->hsize, round);
            s.sum += round_up((apr_size_t)e->dsize, round);
            s.entries++;
        }
    
        s.total = s.sum;
        s.etotal = s.entries;
    
        if ((!s.max || s.sum <= s.max) && (!s.inodes || s.nodes <= s.inodes)) {
            printstats(path, &s);
            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.link);
             e != APR_RING_SENTINEL(&root.link, _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, &s.nodes, pool);
                s.sum -= round_up((apr_size_t)e->hsize, round);
                s.sum -= round_up((apr_size_t)e->dsize, round);
                s.entries--;
                s.dfuture++;
                APR_RING_REMOVE(e, link);
                if ((!s.max || s.sum <= s.max) && (!s.inodes || s.nodes <= s.inodes)) {
                    if (!interrupted) {
                        printstats(path, &s);
                    }
                    return;
                }
            }
            e = n;
        }
    
        if (interrupted) {
            return;
        }
    
        /* process all entries which are expired */
        for (e = APR_RING_FIRST(&root.link);
             e != APR_RING_SENTINEL(&root.link, _entry, link) && !interrupted;) {
            n = APR_RING_NEXT(e, link);
            if (e->expire != APR_DATE_BAD && e->expire < now) {
                delete_entry(path, e->basename, &s.nodes, pool);
                s.sum -= round_up((apr_size_t)e->hsize, round);
                s.sum -= round_up((apr_size_t)e->dsize, round);
                s.entries--;
                s.dexpired++;
                APR_RING_REMOVE(e, link);
                if ((!s.max || s.sum <= s.max) && (!s.inodes || s.nodes <= s.inodes)) {
                    if (!interrupted) {
                        printstats(path, &s);
                    }
                    return;
                }
            }
            e = n;
        }
    
        if (interrupted) {
             return;
        }
    
        /* process remaining entries oldest to newest, the check for an empty
         * ring actually isn't necessary except when the compiler does
         * corrupt 64bit arithmetics which happened to me once, so better safe
         * than sorry
         */
        while (!((!s.max || s.sum <= s.max) && (!s.inodes || s.nodes <= s.inodes))
                && !interrupted && !APR_RING_EMPTY(&root.link, _entry, link)) {
            oldest = APR_RING_FIRST(&root.link);
    
            for (e = APR_RING_NEXT(oldest, link);
                 e != APR_RING_SENTINEL(&root.link, _entry, link);
                 e = APR_RING_NEXT(e, link)) {
                if (e->dtime < oldest->dtime) {
                    oldest = e;
                }
            }
    
            delete_entry(path, oldest->basename, &s.nodes, pool);
            s.sum -= round_up((apr_size_t)oldest->hsize, round);
            s.sum -= round_up((apr_size_t)oldest->dsize, round);
            s.entries--;
            s.dfresh++;
            APR_RING_REMOVE(oldest, link);
        }
    
        if (!interrupted) {
            printstats(path, &s);
        }
    }
    
    static apr_status_t remove_directory(apr_pool_t *pool, const char *dir)
    {
        apr_status_t rv;
        apr_dir_t *dirp;
        apr_finfo_t dirent;
    
        rv = apr_dir_open(&dirp, dir, pool);
        if (APR_STATUS_IS_ENOENT(rv)) {
            return rv;
        }
        if (rv != APR_SUCCESS) {
            apr_file_printf(errfile, "Could not open directory %s: %pm" APR_EOL_STR,
                    dir, &rv);
            return rv;
        }
    
        while (apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_TYPE, dirp)
                == APR_SUCCESS) {
            if (dirent.filetype == APR_DIR) {
                if (strcmp(dirent.name, ".") && strcmp(dirent.name, "..")) {
                    rv = remove_directory(pool, apr_pstrcat(pool, dir, "/",
                            dirent.name, NULL));
                    /* tolerate the directory not being empty, the cache may have
                     * attempted to recreate the directory in the mean time.
                     */
                    if (APR_SUCCESS != rv && APR_ENOTEMPTY != rv) {
                        break;
                    }
                }
            } else {
                const char *file = apr_pstrcat(pool, dir, "/", dirent.name, NULL);
                rv = apr_file_remove(file, pool);
                if (APR_SUCCESS != rv) {
                    apr_file_printf(errfile,
                            "Could not remove file '%s': %pm" APR_EOL_STR, file,
                            &rv);
                    break;
                }
            }
        }
    
        apr_dir_close(dirp);
    
        if (rv == APR_SUCCESS) {
            rv = apr_dir_remove(dir, pool);
            if (APR_ENOTEMPTY == rv) {
                rv = APR_SUCCESS;
            }
            if (rv != APR_SUCCESS) {
                apr_file_printf(errfile, "Could not remove directory %s: %pm" APR_EOL_STR,
                        dir, &rv);
            }
        }
    
        return rv;
    }
    
    static apr_status_t find_directory(apr_pool_t *pool, const char *base,
            const char *rest)
    {
        apr_status_t rv;
        apr_dir_t *dirp;
        apr_finfo_t dirent;
        int found = 0, files = 0;
        const char *header = apr_pstrcat(pool, rest, CACHE_HEADER_SUFFIX, NULL);
        const char *data = apr_pstrcat(pool, rest, CACHE_DATA_SUFFIX, NULL);
        const char *vdir = apr_pstrcat(pool, rest, CACHE_HEADER_SUFFIX,
                CACHE_VDIR_SUFFIX, NULL);
        const char *dirname = NULL;
    
        rv = apr_dir_open(&dirp, base, pool);
        if (rv != APR_SUCCESS) {
            apr_file_printf(errfile, "Could not open directory %s: %pm" APR_EOL_STR,
                    base, &rv);
            return rv;
        }
    
        rv = APR_ENOENT;
    
        while (apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_TYPE, dirp)
                == APR_SUCCESS) {
            int len = strlen(dirent.name);
            int restlen = strlen(rest);
            if (dirent.filetype == APR_DIR && !strncmp(rest, dirent.name, len)) {
                dirname = apr_pstrcat(pool, base, "/", dirent.name, NULL);
                rv = find_directory(pool, dirname, rest + (len < restlen ? len
                        : restlen));
                if (APR_SUCCESS == rv) {
                    found = 1;
                }
            }
            if (dirent.filetype == APR_DIR) {
                if (!strcmp(dirent.name, vdir)) {
                    files = 1;
                }
            }
            if (dirent.filetype == APR_REG) {
                if (!strcmp(dirent.name, header) || !strcmp(dirent.name, data)) {
                    files = 1;
                }
            }
        }
    
        apr_dir_close(dirp);
    
        if (files) {
            rv = APR_SUCCESS;
            if (!dryrun) {
                const char *remove;
                apr_status_t status;
    
                remove = apr_pstrcat(pool, base, "/", header, NULL);
                status = apr_file_remove(remove, pool);
                if (status != APR_SUCCESS && !APR_STATUS_IS_ENOENT(status)) {
                    apr_file_printf(errfile, "Could not remove file %s: %pm" APR_EOL_STR,
                            remove, &status);
                    rv = status;
                }
    
                remove = apr_pstrcat(pool, base, "/", data, NULL);
                status = apr_file_remove(remove, pool);
                if (status != APR_SUCCESS && !APR_STATUS_IS_ENOENT(status)) {
                    apr_file_printf(errfile, "Could not remove file %s: %pm" APR_EOL_STR,
                            remove, &status);
                    rv = status;
                }
    
                status = remove_directory(pool, apr_pstrcat(pool, base, "/", vdir, NULL));
                if (status != APR_SUCCESS && !APR_STATUS_IS_ENOENT(status)) {
                    rv = status;
                }
            }
        }
    
        /* If asked to delete dirs, do so now. We don't care if it fails.
         * If it fails, it likely means there was something else there.
         */
        if (dirname && deldirs && !dryrun) {
            apr_dir_remove(dirname, pool);
        }
    
        if (found) {
            return APR_SUCCESS;
        }
    
        return rv;
    }
    
    /**
     * Delete a specific URL from the cache.
     */
    static apr_status_t delete_url(apr_pool_t *pool, const char *proxypath, const char *url)
    {
        apr_md5_ctx_t context;
        unsigned char digest[16];
        char tmp[23];
        int i, k;
        unsigned int x;
        static const char enc_table[64] =
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@";
    
        apr_md5_init(&context);
        apr_md5_update(&context, (const unsigned char *) url, strlen(url));
        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];
        tmp[k] = 0;
    
        /* automatically find the directory levels */
        return find_directory(pool, proxypath, tmp);
    }
    
    /*
     * usage info
     */
    #define NL APR_EOL_STR
    static void usage(const char *error)
    {
        if (error) {
            apr_file_printf(errfile, "%s error: %s\n", shortname, error);
        }
        apr_file_printf(errfile,
        "%s -- program for cleaning the disk cache."                             NL
        "Usage: %s [-Dvtrn] -pPATH [-lLIMIT] [-LLIMIT] [-PPIDFILE]"              NL
        "       %s [-nti] -dINTERVAL -pPATH [-lLIMIT] [-LLIMIT] [-PPIDFILE]"     NL
        "       %s [-Dvt] -pPATH URL ..."                                        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. When doing a dry run and deleting" NL
        "       directories with -t, the inodes reported deleted in the stats"   NL
        "       cannot take into account the directories deleted, and will be"   NL
        "       marked as an estimate."                                          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 and implies -t."                                          NL
                                                                                 NL
        "  -n   Be nice. This causes slower processing in favour of other"       NL
        "       processes."                                                      NL
                                                                                 NL
        "  -t   Delete all empty directories. By default only cache files are"   NL
        "       removed, however with some configurations the large number of"   NL
        "       directories created may require attention."                      NL
                                                                                 NL
        "  -p   Specify PATH as the root directory of the disk cache."           NL
                                                                                 NL
        "  -P   Specify PIDFILE as the file to write the pid to."                NL
                                                                                 NL
        "  -R   Specify amount to round sizes up to."                            NL
                                                                                 NL
        "  -l   Specify LIMIT as the total disk cache size limit. Attach 'K',"   NL
        "       'M' or 'G' to the number for specifying KBytes, MBytes or"       NL
        "        GBytes."                                                        NL
                                                                                 NL
        "  -L   Specify LIMIT as the total disk cache inode limit. 'K', 'M' or"  NL
        "       'G' suffix can also be used."                                    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
                                                                                 NL
        "  -a   List the URLs currently stored in the cache. Variants of the"    NL
        "       same URL will be listed once for each variant."                  NL
                                                                                 NL
        "  -A   List the URLs currently stored in the cache, along with their"   NL
        "       attributes in the following order: url, header size, body size," NL
        "       status, entity version, date, expiry, request time,"             NL
        "       response time, body present, head request."                      NL
                                                                                 NL
        "Should an URL be provided on the command line, the URL will be"         NL
        "deleted from the cache. A reverse proxied URL is made up as follows:"   NL
        "http://<hostname>:<port><path>?[query]. So, for the path \"/\" on the"  NL
        "host \"localhost\" and port 80, the URL to delete becomes"              NL
        "\"http://localhost:80/?\". Note the '?' in the URL must always be"      NL
        "specified explicitly, whether a query string is present or not."        NL,
        shortname,
        shortname,
        shortname,
        shortname
        );
    
        exit(1);
    }
    #undef NL
    
    static void usage_repeated_arg(apr_pool_t *pool, char option)
    {
        usage(apr_psprintf(pool,
                           "The option '%c' cannot be specified more than once",
                           option));
    }
    
    static void log_pid(apr_pool_t *pool, const char *pidfilename, apr_file_t **pidfile)
    {
        apr_status_t status;
        pid_t mypid = getpid();
    
        if (APR_SUCCESS == (status = apr_file_open(pidfile, pidfilename,
                    APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE |
                    APR_FOPEN_DELONCLOSE, APR_FPROT_UREAD | APR_FPROT_UWRITE |
                    APR_FPROT_GREAD | APR_FPROT_WREAD, pool))) {
            apr_file_printf(*pidfile, "%" APR_PID_T_FMT APR_EOL_STR, mypid);
        }
        else {
            if (errfile) {
                apr_file_printf(errfile,
                                "Could not write the pid file '%s': %pm" APR_EOL_STR,
                                pidfilename, &status);
            }
            exit(1);
        }
    }
    
    /*
     * main
     */
    int main(int argc, const char * const argv[])
    {
        apr_off_t max, inodes, round;
        apr_time_t current, repeat, delay, previous;
        apr_status_t status;
        apr_pool_t *pool, *instance;
        apr_getopt_t *o;
        apr_finfo_t info;
        apr_file_t *pidfile;
        int retries, isdaemon, limit_found, inodes_found, intelligent, dowork;
        char opt;
        const char *arg;
        char *proxypath, *path, *pidfilename;
    
        interrupted = 0;
        repeat = 0;
        isdaemon = 0;
        dryrun = 0;
        limit_found = 0;
        inodes_found = 0;
        max = 0;
        inodes = 0;
        round = 0;
        verbose = 0;
        realclean = 0;
        benice = 0;
        deldirs = 0;
        intelligent = 0;
        previous = 0; /* avoid compiler warning */
        proxypath = NULL;
        pidfilename = 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_file_open_stdout(&outfile, pool);
        apr_signal(SIGINT, setterm);
        apr_signal(SIGTERM, setterm);
    
        apr_getopt_init(&o, pool, argc, argv);
    
        while (1) {
            status = apr_getopt(o, "iDnvrtd:l:L:p:P:R:aA", &opt, &arg);
            if (status == APR_EOF) {
                break;
            }
            else if (status != APR_SUCCESS) {
                usage(NULL);
            }
            else {
                char *end;
                apr_status_t rv;
                switch (opt) {
                case 'i':
                    if (intelligent) {
                        usage_repeated_arg(pool, opt);
                    }
                    intelligent = 1;
                    break;
    
                case 'D':
                    if (dryrun) {
                        usage_repeated_arg(pool, opt);
                    }
                    dryrun = 1;
                    break;
    
                case 'n':
                    if (benice) {
                        usage_repeated_arg(pool, opt);
                    }
                    benice = 1;
                    break;
    
                case 't':
                    if (deldirs) {
                        usage_repeated_arg(pool, opt);
                    }
                    deldirs = 1;
                    break;
    
                case 'v':
                    if (verbose) {
                        usage_repeated_arg(pool, opt);
                    }
                    verbose = 1;
                    break;
    
                case 'r':
                    if (realclean) {
                        usage_repeated_arg(pool, opt);
                    }
                    realclean = 1;
                    deldirs = 1;
                    break;
    
                case 'd':
                    if (isdaemon) {
                        usage_repeated_arg(pool, opt);
                    }
                    isdaemon = 1;
                    repeat = apr_atoi64(arg);
                    repeat *= SECS_PER_MIN;
                    repeat *= APR_USEC_PER_SEC;
                    break;
    
                case 'l':
                    if (limit_found) {
                        usage_repeated_arg(pool, opt);
                    }
                    limit_found = 1;
    
                    do {
                        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 == 'G' || *end == 'g') && !end[1]) {
                                max *= GBYTE;
                            }
                            else if (*end &&        /* neither empty nor [Bb] */
                                     ((*end != 'B' && *end != 'b') || end[1])) {
                                rv = APR_EGENERAL;
                            }
                        }
                        if (rv != APR_SUCCESS) {
                            usage(apr_psprintf(pool, "Invalid limit: %s"
                                                     APR_EOL_STR APR_EOL_STR, arg));
                        }
                    } while (0);
                    break;
    
                case 'L':
                    if (inodes_found) {
                        usage_repeated_arg(pool, opt);
                    }
                    inodes_found = 1;
    
                    do {
                        rv = apr_strtoff(&inodes, arg, &end, 10);
                        if (rv == APR_SUCCESS) {
                            if ((*end == 'K' || *end == 'k') && !end[1]) {
                                inodes *= KBYTE;
                            }
                            else if ((*end == 'M' || *end == 'm') && !end[1]) {
                                inodes *= MBYTE;
                            }
                            else if ((*end == 'G' || *end == 'g') && !end[1]) {
                                inodes *= GBYTE;
                            }
                            else if (*end &&        /* neither empty nor [Bb] */
                                     ((*end != 'B' && *end != 'b') || end[1])) {
                                rv = APR_EGENERAL;
                            }
                        }
                        if (rv != APR_SUCCESS) {
                            usage(apr_psprintf(pool, "Invalid limit: %s"
                                                     APR_EOL_STR APR_EOL_STR, arg));
                        }
                    } while (0);
                    break;
    
                case 'a':
                    if (listurls) {
                        usage_repeated_arg(pool, opt);
                    }
                    listurls = 1;
                    break;
    
                case 'A':
                    if (listurls) {
                        usage_repeated_arg(pool, opt);
                    }
                    listurls = 1;
                    listextended = 1;
                    break;
    
                case 'p':
                    if (proxypath) {
                        usage_repeated_arg(pool, opt);
                    }
                    proxypath = apr_pstrdup(pool, arg);
                    if ((status = apr_filepath_set(proxypath, pool)) != APR_SUCCESS) {
                        usage(apr_psprintf(pool, "Could not set filepath to '%s': %pm",
                                           proxypath, &status));
                    }
                    break;
    
                case 'P':
                    if (pidfilename) {
                        usage_repeated_arg(pool, opt);
                    }
                    pidfilename = apr_pstrdup(pool, arg);
                    break;
    
                case 'R':
                    if (round) {
                        usage_repeated_arg(pool, opt);
                    }
                    rv = apr_strtoff(&round, arg, &end, 10);
                    if (rv == APR_SUCCESS) {
                        if (*end) {
                            usage(apr_psprintf(pool, "Invalid round value: %s"
                                                     APR_EOL_STR APR_EOL_STR, arg));
                        }
                        else if (round < 0) {
                            usage(apr_psprintf(pool, "Round value must be positive: %s"
                                                     APR_EOL_STR APR_EOL_STR, arg));
                        }
                    }
                    if (rv != APR_SUCCESS) {
                        usage(apr_psprintf(pool, "Invalid round value: %s"
                                                 APR_EOL_STR APR_EOL_STR, arg));
                    }
                    break;
    
                } /* switch */
            } /* else */
        } /* while */
    
        if (argc <= 1) {
            usage(NULL);
        }
    
        if (!proxypath) {
             usage("Option -p must be specified");
        }
    
        if (o->ind < argc) {
            int deleted = 0;
            int error = 0;
            if (isdaemon) {
                usage("Option -d cannot be used with URL arguments, aborting");
            }
            if (intelligent) {
                usage("Option -i cannot be used with URL arguments, aborting");
            }
            if (limit_found) {
                usage("Option -l and -L cannot be used with URL arguments, aborting");
            }
            while (o->ind < argc) {
                status = delete_url(pool, proxypath, argv[o->ind]);
                if (APR_SUCCESS == status) {
                    if (verbose) {
                        apr_file_printf(errfile, "Removed: %s" APR_EOL_STR,
                                argv[o->ind]);
                    }
                    deleted = 1;
                }
                else if (APR_ENOENT == status) {
                    if (verbose) {
                        apr_file_printf(errfile, "Not cached: %s" APR_EOL_STR,
                                argv[o->ind]);
                    }
                }
                else {
                    if (verbose) {
                        apr_file_printf(errfile, "Error while removed: %s" APR_EOL_STR,
                                argv[o->ind]);
                    }
                    error = 1;
                }
                o->ind++;
            }
            return error ? 1 : deleted ? 0 : 2;
        }
    
        if (isdaemon && repeat <= 0) {
             usage("Option -d must be greater than zero");
        }
    
        if (isdaemon && (verbose || realclean || dryrun || listurls)) {
             usage("Option -d cannot be used with -v, -r, -L or -D");
        }
    
        if (!isdaemon && intelligent) {
             usage("Option -i cannot be used without -d");
        }
    
        if (!listurls && max <= 0 && inodes <= 0) {
             usage("At least one of option -l or -L must be greater than zero");
        }
    
        if (apr_filepath_get(&path, 0, pool) != APR_SUCCESS) {
            usage(apr_psprintf(pool, "Could not get the filepath: %pm", &status));
        }
        baselen = strlen(path);
    
        if (pidfilename) {
            log_pid(pool, pidfilename, &pidfile); /* before daemonizing, so we
                                                   * can report errors
                                                   */
        }
    
        if (listurls) {
            list_urls(path, pool, round);
            return (interrupted != 0);
        }
    
    #ifndef DEBUG
        if (isdaemon) {
            apr_file_close(errfile);
            errfile = NULL;
            if (pidfilename) {
                apr_file_close(pidfile); /* delete original pidfile only in parent */
            }
            apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);
            if (pidfilename) {
                log_pid(pool, pidfilename, &pidfile);
            }
        }
    #endif
    
        do {
            apr_pool_create(&instance, pool);
    
            now = apr_time_now();
            APR_RING_INIT(&root.link, _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) {
                apr_off_t nodes = 0;
                if (!process_dir(path, instance, &nodes) && !interrupted) {
                    purge(path, instance, max, inodes, nodes, round);
                }
                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;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/passwd_common.h����������������������������������������������������������������0000664�0001751�0001751�00000006266�14571614732�017404� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 _PASSWD_COMMON_H
    #define _PASSWD_COMMON_H
    
    #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_version.h"
    #if !APR_VERSION_AT_LEAST(2,0,0)
    #include "apu_version.h"
    #endif
    
    #if !defined(WIN32) && !defined(NETWARE)
    #include "ap_config_auto.h"
    #endif
    
    #define MAX_STRING_LEN 256
    
    #define ALG_PLAIN 0
    #define ALG_CRYPT 1
    #define ALG_APMD5 2
    #define ALG_APSHA 3
    #define ALG_BCRYPT 4
    #define ALG_CRYPT_SHA256 5
    #define ALG_CRYPT_SHA512 6
    
    #define BCRYPT_DEFAULT_COST 5
    
    #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 ERR_RANDOM 8
    #define ERR_GENERAL 9
    #define ERR_ALG_NOT_SUPP 10
    
    #define NL APR_EOL_STR
    
    #if defined(WIN32) || defined(NETWARE)
    #define CRYPT_ALGO_SUPPORTED 0
    #define PLAIN_ALGO_SUPPORTED 1
    #else
    #define CRYPT_ALGO_SUPPORTED 1
    #define PLAIN_ALGO_SUPPORTED 0
    #endif
    
    #if APR_VERSION_AT_LEAST(2,0,0) || \
        (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 5)
    #define BCRYPT_ALGO_SUPPORTED 1
    #else
    #define BCRYPT_ALGO_SUPPORTED 0
    #endif
    
    #if APR_CHARSET_EBCDIC
    #undef BCRYPT_ALGO_SUPPORTED
    #define BCRYPT_ALGO_SUPPORTED 0
    #endif
    
    /*
     * Must be initialized with apr_file_open_stderr() before using any of the
     * below functions.
     */
    extern apr_file_t *errfile;
    
    struct passwd_ctx {
        apr_pool_t      *pool;
        const char      *errstr;
        char            *out;
        apr_size_t      out_len;
        char            *passwd;
        int             alg;
        int             cost; /* cost for bcrypt, rounds for SHA-2 */
        enum {
            PW_PROMPT = 0,
            PW_ARG,
            PW_STDIN,
            PW_PROMPT_VERIFY,
        } passwd_src;
    };
    
    
    /*
     * To be used as apr_pool_abort_fn
     */
    int abort_on_oom(int rc);
    
    /*
     * Write a line to the file. On error, print a message and exit
     */
    void putline(apr_file_t *f, const char *l);
    
    /*
     * The following functions return zero on success; otherwise, one of
     * the ERR_* codes is returned and an error message is stored in ctx->errstr.
     */
    
    /*
     * Parse the algorithm specific options.
     */
    int parse_common_options(struct passwd_ctx *ctx, char opt, const char *opt_arg);
    
    /*
     * Ask for password with verification.
     */
    int get_password(struct passwd_ctx *ctx);
    
    /*
     * Make a password record from the given information.
     */
    int mkhash(struct passwd_ctx *ctx);
    
    #endif /* _PASSWD_COMMON_H */
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/apxs.in������������������������������������������������������������������������0000664�0001751�0001751�00000056503�13635137174�015664� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!@perlbin@ -w
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    ##
    
    #   are we building in a cross compile environment? If so, destdir contains
    #   the base directory of the cross compiled environment, otherwise destdir
    #   is the empty string.
    
    my $destdir = "";
    my $ddi = rindex($0, "@exp_bindir@");
    if ($ddi >= 0) {
      $destdir = substr($0, 0, $ddi);
    }
    
    my %config_vars = ();
    
    my $installbuilddir = "@exp_installbuilddir@";
    get_config_vars($destdir . "$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 $CFG_LDFLAGS    = join ' ', map { get_vars($_) }
      qw(LDFLAGS NOTEST_LDFLAGS SH_LDFLAGS);
    my $includedir     = $destdir . get_vars("includedir");
    my $CFG_INCLUDEDIR = eval qq("$includedir");
    my $CFG_CC         = get_vars("CC");
    my $libexecdir     = $destdir . 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;
    my $opt_v = 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 $_;
    
        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 >= 0) {
                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 <var>=<val>] -n <modname>\n";
        print STDERR "       apxs -q [-v] [-S <var>=<val>] [<query> ...]\n";
        print STDERR "       apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]\n";
        print STDERR "               [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]\n";
        print STDERR "               [-Wl,<flags>] [-p] <files> ...\n";
        print STDERR "       apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
        print STDERR "       apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
        exit(1);
    }
    
    #   option handling
    my $rc;
    ($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaApv", @ARGV);
    &usage if ($rc == 0);
    &usage if ($#ARGV == -1 and not $opt_g and not $opt_q);
    &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
    ##
    unless ("@MOD_SO_ENABLED@" eq "yes") {
        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("the server binary.");
        exit 1;
    }
    
    sub get_config_vars{
        my ($file, $rh_config) = @_;
    
        open IN, $file or die "cannot open $file: $!";
        while (<IN>){
            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|;;$||;
        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>);
        $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;
        if ($#args >= 0) { 
            $result = get_vars(@args);
            print "$result\n";
        } else {
            # -q without var name prints all variables and their values
            
            # Additional -v pretty-prints output
            if ($opt_v) {
                # Variable names in alphabetic order
                my @vars = sort {uc($a) cmp uc($b)} keys %config_vars;
                
                # Make the left column as wide as the longest variable name
                my $width = 0;
                foreach (@vars) {
                    my $l = length $_; 
                    $width = $l unless ($l <= $width);
                }
        
                foreach (@vars) {
                    printf "%-${width}s = %s\n", $_, $config_vars{$_};
                }
            } else {
                # Unprettified name=value list
                foreach (keys %config_vars) {
                    print "$_=$config_vars{$_}\n";
                }
            }
        }
    }
    
    my $apr_config = $destdir . get_vars("APR_CONFIG");
    
    if (! -x "$apr_config") {
        error("$apr_config not found!");
        exit(1);
    }
    
    my $apr_major_version = (split /\./, `$apr_config --version`)[0];
    
    my $apu_config = "";
    if ($apr_major_version < 2) {
        $apu_config = $destdir . 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 = "";
    if ($apr_major_version < 2) {
        $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";
        }
    
        my $ldflags = "$CFG_LDFLAGS";
        if ($opt_p == 1) {
            
            my $apr_libs=`$apr_config --cflags --ldflags --link-libtool --libs`;
            chomp($apr_libs);
            my $apu_libs="";
            if ($apr_major_version < 2) {
                $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 $ldflags -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, $destdir . "$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('', <FP>);
                    close(FP);
                    if ($content =~ m|.*AP_DECLARE_MODULE\s*\(\s*([a-zA-Z0-9_]+)\s*\)\s*=.*|s || $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('', <FP>);
            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";
                my $lmd_re = $lmd;
                $lmd_re =~ s/\s+/\\s+/g;
    
                if ($content !~ m|\n#?\s*$lmd_re|) {
                    # check for open <containers>, so that the new LoadModule
                    # directive always appears *outside* of an <container>.
    
                    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*</.*$|mg);
    
                    if ($cntopen == $cntclose) {
                        # fine. Last LoadModule is contextless.
                        $content =~ s|^(.*\n#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|s;
                    }
                    elsif ($cntopen < $cntclose) {
                        error('Configuration file is not valid. There are sections'
                              . ' closed before opened.');
                        exit(1);
                    }
                    else {
                        # put our cmd after the section containing the last
                        # LoadModule.
                        my $found =
                        $content =~ s!\A (               # string and capture start
                                      (?:(?:
                                        ^\s*             # start of conf line with a
                                        (?:[^<]|<[^/])   # directive which does not
                                                         # start with '</'
    
                                        .*(?:$)\n        # rest of the line.
                                                         # the '$' is in parentheses
                                                         # to avoid misinterpreting
                                                         # the string "$\" as
                                                         # perl variable.
    
                                        )*               # catch as much as possible
                                                         # of such lines. (including
                                                         # zero)
    
                                        ^\s*</.*(?:$)\n? # after the above, we
                                                         # expect a config line with
                                                         # a closing container (</)
    
                                      ) {$cntopen}       # the whole pattern (bunch
                                                         # of lines that end up with
                                                         # a closing directive) must
                                                         # be repeated $cntopen
                                                         # times. That's it.
                                                         # Simple, eh? ;-)
    
                                      )                  # capture end
                                     !$1$c$lmd\n!mx;
    
                        unless ($found) {
                            error('Configuration file is not valid. There are '
                                  . 'sections opened and not closed.');
                            exit(1);
                        }
                    }
                } else {
                    # replace already existing LoadModule line
                    $content =~ s|^(.*\n)#?\s*$lmd_re[^\n]*\n|$1$c$lmd\n|s;
                }
                $lmd =~ m|LoadModule\s+(.+?)_module.*|;
                notice("[$what module `$1' in $CFG_SYSCONFDIR/$CFG_TARGET.conf]");
            }
            if (@lmd) {
                if (open(FP, ">$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
    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-yes
    
    #   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
    **    <Location /%NAME%>
    **    SetHandler %NAME%
    **    </Location>
    **
    **  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                      */
    };
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htpasswd.dep�������������������������������������������������������������������0000664�0001751�0001751�00000003661�12674411515�016701� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by htpasswd.mak
    
    .\htpasswd.c : \
    	"..\srclib\apr-util\include\apr_md5.h"\
    	"..\srclib\apr-util\include\apr_sha1.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr-util\include\apu_version.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_signal.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_version.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	".\passwd_common.h"\
    	
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    
    .\passwd_common.c : \
    	"..\srclib\apr-util\include\apr_md5.h"\
    	"..\srclib\apr-util\include\apr_sha1.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr-util\include\apu_version.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_version.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	".\passwd_common.h"\
    	
    �������������������������������������������������������������������������������httpd-2.4.64/support/ab.dsp�������������������������������������������������������������������������0000664�0001751�0001751�00000010166�12520036522�015431� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/ab.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\ab.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/ab.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\ab.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "ab - Win32 Release"
    # Name "ab - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\ab.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/fcgistarter.c������������������������������������������������������������������0000664�0001751�0001751�00000013441�12204401564�017020� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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_pools.h>
    #include <apr_network_io.h>
    #include <apr_thread_proc.h>
    #include <apr_getopt.h>
    #include <apr_portable.h>
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h> /* For EXIT_SUCCESS, EXIT_FAILURE */
    #endif
    
    #if APR_HAVE_UNISTD_H
    #include <unistd.h> /* For execl */
    #endif
    
    static const char *usage_message =
        "usage: fcgistarter -c <command> -p <port> [-i <interface> -N <num>]\n"
        "\n"
        "If an interface is not specified, any available will be used.\n";
    
    static void usage(void)
    {
        fprintf(stderr, "%s", usage_message);
    
        exit(EXIT_FAILURE);
    }
    
    static void exit_error(apr_status_t rv, const char *func)
    {
        char buffer[1024];
    
        fprintf(stderr,
                "%s: %s\n",
                func,
                apr_strerror(rv, buffer, sizeof(buffer)));
    
        exit(EXIT_FAILURE);
    }
    
    int main(int argc, const char * const argv[])
    {
        apr_file_t *infd, *skwrapper;
        apr_sockaddr_t *skaddr;
        apr_getopt_t *gopt;
        apr_socket_t *skt;
        apr_pool_t *pool;
        apr_status_t rv;
        apr_proc_t proc;
    
    
        /* Command line arguments */
        int num_to_start = 1, port = 0;
        const char *interface = NULL;
        const char *command = NULL;
    
        apr_app_initialize(&argc, &argv, NULL);
    
        atexit(apr_terminate);
    
        apr_pool_create(&pool, NULL);
    
        rv = apr_getopt_init(&gopt, pool, argc, argv);
        if (rv) {
            return EXIT_FAILURE;
        }
    
        for (;;) {
            const char *arg;
            char opt;
    
            rv = apr_getopt(gopt, "c:p:i:N:", &opt, &arg);
            if (APR_STATUS_IS_EOF(rv)) {
                break;
            } else if (rv) {
                usage();
            } else {
                switch (opt) {
                case 'c':
                    command = arg;
                    break;
    
                case 'p':
                    port = atoi(arg);
                    if (! port) {
                        usage();
                    }
                    break;
    
                case 'i':
                    interface = arg;
                    break;
    
                case 'N':
                    num_to_start = atoi(arg);
                    if (! num_to_start) {
                        usage();
                    }
                    break;
    
                default:
                    break;
                }
            }
        }
    
        if (! command || ! port) {
            usage();
        }
    
        rv = apr_sockaddr_info_get(&skaddr, interface, APR_UNSPEC, port, 0, pool);
        if (rv) {
            exit_error(rv, "apr_sockaddr_info_get");
        }
    
        rv = apr_socket_create(&skt, skaddr->family, SOCK_STREAM, APR_PROTO_TCP, pool);
        if (rv) {
            exit_error(rv, "apr_socket_create");
        }
    
        rv = apr_socket_opt_set(skt, APR_SO_REUSEADDR, 1);
        if (rv) {
            exit_error(rv, "apr_socket_opt_set(APR_SO_REUSEADDR)");
        }
    
        rv = apr_socket_bind(skt, skaddr);
        if (rv) {
            exit_error(rv, "apr_socket_bind");
        }
    
        rv = apr_socket_listen(skt, 1024);
        if (rv) {
            exit_error(rv, "apr_socket_listen");
        }
    
        rv = apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);
        if (rv) {
            exit_error(rv, "apr_proc_detach");
        }
    
    #if defined(WIN32) || defined(OS2) || defined(NETWARE)
    
    #error "Please implement me."
    
    #else
    
        while (--num_to_start >= 0) {
            rv = apr_proc_fork(&proc, pool);
            if (rv == APR_INCHILD) {
                apr_os_file_t oft = 0;
                apr_os_sock_t oskt;
    
                /* Ok, so we need a file that has file descriptor 0 (which
                 * FastCGI wants), but points to our socket.  This isn't really
                 * possible in APR, so we cheat a bit.  I have no idea how to
                 * do this on a non-unix platform, so for now this is platform
                 * specific.  Ick.
                 *
                 * Note that this has to happen post-detach, otherwise fd 0
                 * gets closed during apr_proc_detach and it's all for nothing.
                 *
                 * Unfortunately, doing this post detach means we have no way
                 * to let anyone know if there's a problem at this point :( */
    
                rv = apr_os_file_put(&infd, &oft, APR_READ | APR_WRITE, pool);
                if (rv) {
                    exit(EXIT_FAILURE);
                }
    
                rv = apr_os_sock_get(&oskt, skt);
                if (rv) {
                    exit(EXIT_FAILURE);
                }
    
                rv = apr_os_file_put(&skwrapper, &oskt, APR_READ | APR_WRITE,
                                     pool);
                if (rv) {
                    exit(EXIT_FAILURE);
                }
    
                rv = apr_file_dup2(infd, skwrapper, pool);
                if (rv) {
                    exit(EXIT_FAILURE);
                }
    
                /* XXX Can't use apr_proc_create because there's no way to get
                 *     infd into the procattr without going through another dup2,
                 *     which means by the time it gets to the fastcgi process it
                 *     is no longer fd 0, so it doesn't work.  Sigh. */
    
                execl(command, command, NULL);
    
            } else if (rv == APR_INPARENT) {
                if (num_to_start == 0) {
                    apr_socket_close(skt);
                }
            } else {
                exit_error(rv, "apr_proc_fork");
            }
        }
    
    #endif
    
        return EXIT_SUCCESS;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/envvars-std.in�����������������������������������������������������������������0000664�0001751�0001751�00000002057�11726155013�017147� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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
    #
    if test "x$@SHLIBPATH_VAR@" != "x" ; then
      @SHLIBPATH_VAR@="@exp_libdir@:$@SHLIBPATH_VAR@"
    else
      @SHLIBPATH_VAR@="@exp_libdir@"
    fi
    export @SHLIBPATH_VAR@
    #
    @OS_SPECIFIC_VARS@
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUmakefile������������������������������������������������������������������0000664�0001751�0001751�00000001711�11540562746�016667� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    
    #
    # 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)/httxt2dbm.nlm \
    	$(OBJDIR)/logres.nlm \
    	$(OBJDIR)/rotlogs.nlm \
    	$(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
    	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/bin/)
    
    #
    # Any specialized rules here
    #
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    
    �������������������������������������������������������httpd-2.4.64/support/check_forensic�����������������������������������������������������������������0000775�0001751�0001751�00000001670�11555560110�017234� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    
    # check_forensic <forensic log file>
    
    # 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
    ������������������������������������������������������������������������httpd-2.4.64/support/ab.c���������������������������������������������������������������������������0000664�0001751�0001751�00000271053�14741720500�015074� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 warranties,
       ** 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 <adam@zeus.co.uk>, March 1996
       **      with input from Mike Belshe <mbelshe@netscape.com> and
       **      Michael Campanella <campanella@stevms.enet.dec.com>
       **    - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997
       **    - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998
       **    - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998
       **    - HTML table output added by David N. Welton <davidw@prosa.it>, January 1999
       **    - Added Cookie, Arbitrary header and auth support. <dirkx@webweaving.org>, 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 & <dirkx@covalent.net>, End 2000.
       **    - Fixed proxy functionality, added median/mean statistics, added gnuplot
       **      output option, added _experimental/rudimentary_ SSL support. Added
       **      confidence guestimators and warnings. Sander & <dirkx@covalent.net>, 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 behavior 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. <dirkx@webweaving.org>, 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 <madhusudan_mathihalli@hp.com>
       **     [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
       **
       ** Version 2.3
       **     SIGINT now triggers output_results().
       **     Contributed by colm, March 30, 2006
       **/
    
    /* 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.3"
    
    /*
     * 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 <stdio.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h> /* for getpid() */
    #endif
    
    #if !defined(WIN32) && !defined(NETWARE)
    #include "ap_config_auto.h"
    #endif
    
    #include <math.h>
    #if APR_HAVE_CTYPE_H
    #include <ctype.h>
    #endif
    #if APR_HAVE_LIMITS_H
    #include <limits.h>
    #endif
    
    #if defined(HAVE_OPENSSL)
    
    #include <openssl/evp.h>
    #include <openssl/crypto.h>
    #include <openssl/x509.h>
    #include <openssl/pem.h>
    #include <openssl/err.h>
    #include <openssl/ssl.h>
    #include <openssl/rand.h>
    #include <openssl/opensslv.h>
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    #include <openssl/core_names.h>
    #endif
    
    #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;
    
    #if defined(_MSC_VER) && !defined(LIBRESSL_VERSION_NUMBER)
    /* The following logic ensures we correctly glue FILE* within one CRT used
     * by the OpenSSL library build to another CRT used by the ab.exe build.
     * This became especially problematic with Visual Studio 2015.
     */
    #include <openssl/applink.c>
    #endif
    
    #if (OPENSSL_VERSION_NUMBER >= 0x00909000)
    #define AB_SSL_METHOD_CONST const
    #else
    #define AB_SSL_METHOD_CONST
    #endif
    #if (OPENSSL_VERSION_NUMBER >= 0x0090707f)
    #define AB_SSL_CIPHER_CONST const
    #else
    #define AB_SSL_CIPHER_CONST
    #endif
    #ifdef SSL_OP_NO_TLSv1_2
    #define HAVE_TLSV1_X
    #endif
    #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_set_tlsext_host_name)
    #define HAVE_TLSEXT
    #endif
    
    #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2060000f
    #define SSL_CTRL_SET_MIN_PROTO_VERSION 123
    #define SSL_CTRL_SET_MAX_PROTO_VERSION 124
    #define SSL_CTX_set_min_proto_version(ctx, version) \
       SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
    #define SSL_CTX_set_max_proto_version(ctx, version) \
       SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
    #endif
    
    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
    #ifdef TLS1_3_VERSION
    #define MAX_SSL_PROTO TLS1_3_VERSION
    #else
    #define MAX_SSL_PROTO TLS1_2_VERSION
    #endif
    #ifndef OPENSSL_NO_SSL3
    #define MIN_SSL_PROTO SSL3_VERSION
    #else
    #define MIN_SSL_PROTO TLS1_VERSION
    #endif
    #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
    
    #endif /* HAVE_OPENSSL */
    
    /* ------------------- 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 (INT_MAX > 50000 ? 50000 : INT_MAX)
    
    /* connection state
     * don't add enums or rearrange or otherwise change values without
     * visiting set_conn_state()
     */
    typedef enum {
        STATE_UNCONNECTED = 0,
        STATE_CONNECTING,           /* TCP connect initiated, but we don't
                                     * know if it worked yet
                                     */
        STATE_CONNECTED,            /* we know TCP connect completed */
        STATE_READ
    } connect_state_e;
    
    #define CBUFFSIZE (8192)
    
    struct connection {
        apr_pool_t *ctx;
        apr_socket_t *aprsock;
        apr_pollfd_t pollfd;
        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 {
        apr_time_t starttime;         /* start time of connection */
        apr_interval_time_t waittime; /* between request and reading response */
        apr_interval_time_t ctime;    /* time to connect */
        apr_interval_time_t time;     /* time for connection */
    };
    
    #define ap_min(a,b) (((a)<(b))?(a):(b))
    #define ap_max(a,b) (((a)>(b))?(a):(b))
    #define ap_round_ms(a) ((apr_time_t)((a) + 500)/1000)
    #define ap_double_ms(a) ((double)(a)/1000.0)
    #define MAX_CONCURRENCY 200000
    
    /* --------------------- GLOBALS ---------------------------- */
    
    int verbosity = 0;      /* no verbosity by default */
    int recverrok = 0;      /* ok to proceed after socket receive errors */
    enum {NO_METH = 0, GET, HEAD, PUT, POST, CUSTOM_METHOD} method = NO_METH;
    const char *method_str[] = {"bug", "GET", "HEAD", "PUT", "POST", ""};
    int send_body = 0;      /* non-zero if sending body with request */
    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 nolength = 0;       /* Accept variable document length */
    int confidence = 1;     /* Show confidence estimator and warnings */
    int tlimit = 0;         /* time limit in secs */
    int keepalive = 0;      /* try and do keepalive connections */
    int windowsize = 0;     /* we use the OS default window size */
    char servername[1024];  /* name that server reports */
    char *hostname;         /* host name from URL */
    const char *host_field;       /* value of "Host:" header field */
    const char *path;             /* path name */
    char *postdata;         /* *buffer containing data from postfile */
    apr_size_t postlen = 0; /* length of data to be POSTed */
    char *content_type = NULL;     /* content type to put in POST header */
    const char *cookie,           /* optional cookie line */
               *auth,             /* optional (basic/uuencoded) auhentication */
               *hdrs;             /* optional arbitrary headers */
    apr_port_t port;        /* port number */
    char *proxyhost = NULL; /* proxy host name */
    int proxyport = 0;      /* proxy port */
    const char *connecthost;
    const char *myhost;
    apr_port_t connectport;
    const char *gnuplot;          /* GNUplot file */
    const char *csvperc;          /* CSV Percentile file */
    const char *fullurl;
    const char *colonhost;
    int isproxy = 0;
    apr_interval_time_t aprtimeout = apr_time_from_sec(30); /* timeout value */
    
    /* overrides for ab-generated common headers */
    const char *opt_host;   /* which optional "Host:" header specified, if any */
    int opt_useragent = 0;  /* was an optional "User-Agent:" header specified? */
    int opt_accept = 0;     /* was an optional "Accept:" header specified? */
     /*
      * 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 */
    apr_int64_t totalread = 0;    /* total number of bytes read */
    apr_int64_t totalbread = 0;   /* totoal amount of entity body read */
    apr_int64_t totalposted = 0;  /* total number of bytes posted, inc. headers */
    int started = 0;           /* number of requests started, so no excess */
    int done = 0;              /* number of requests we have done */
    int doneka = 0;            /* number of keep alive connections done */
    int good = 0, bad = 0;     /* number of good and bad requests */
    int epipe = 0;             /* number of broken pipe writes */
    int err_length = 0;        /* requests failed due to response length */
    int err_conn = 0;          /* requests failed due to connection drop */
    int err_recv = 0;          /* requests failed due to broken read */
    int err_except = 0;        /* requests failed due to exception */
    int err_response = 0;      /* requests with invalid or non-200 response */
    
    #ifdef USE_SSL
    int is_ssl;
    SSL_CTX *ssl_ctx;
    char *ssl_cipher = NULL;
    char *ssl_info = NULL;
    char *ssl_cert = NULL;
    #if OPENSSL_VERSION_NUMBER >= 0x10002000L
    char *ssl_tmp_key = NULL;
    #endif
    BIO *bio_out,*bio_err;
    #ifdef HAVE_TLSEXT
    int tls_use_sni = 1;         /* used by default, -I disables it */
    const char *tls_sni = NULL; /* 'opt_host' if any, 'hostname' otherwise */
    #endif
    #endif
    
    apr_time_t start, lasttime, stoptime;
    
    /* global request (and its length) */
    char _request[8192];
    char *request = _request;
    apr_size_t reqlen;
    int requests_initialized = 0;
    
    /* 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;         /* data for each request */
    apr_pool_t *cntxt;
    
    apr_pollset_t *readbits;
    
    apr_sockaddr_t *mysa;
    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(const char *s)
    {
        fprintf(stderr, "%s\n", s);
        if (done)
            printf("Total of %d requests completed\n" , done);
        exit(1);
    }
    
    /* simple little function to write an APR error string and exit */
    
    static void apr_err(const 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 %d requests completed\n" , done);
        exit(rv);
    }
    
    static void *xmalloc(size_t size)
    {
        void *ret = malloc(size);
        if (ret == NULL) {
            fprintf(stderr, "Could not allocate memory (%"
                    APR_SIZE_T_FMT" bytes)\n", size);
            exit(1);
        }
        return ret;
    }
    
    static void *xcalloc(size_t num, size_t size)
    {
        void *ret = calloc(num, size);
        if (ret == NULL) {
            fprintf(stderr, "Could not allocate memory (%"
                    APR_SIZE_T_FMT" bytes)\n", size*num);
            exit(1);
        }
        return ret;
    }
    
    static char *xstrdup(const char *s)
    {
        char *ret = strdup(s);
        if (ret == NULL) {
            fprintf(stderr, "Could not allocate memory (%"
                    APR_SIZE_T_FMT " bytes)\n", strlen(s));
            exit(1);
        }
        return ret;
    }
    
    /*
     * Similar to standard strstr() but we ignore case in this version.
     * Copied from ap_strcasestr().
     */
    static char *xstrcasestr(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);
    }
    
    /* pool abort function */
    static int abort_on_oom(int retcode)
    {
        fprintf(stderr, "Could not allocate memory\n");
        exit(1);
        /* not reached */
        return retcode;
    }
    
    static void set_polled_events(struct connection *c, apr_int16_t new_reqevents)
    {
        apr_status_t rv;
    
        if (c->pollfd.reqevents != new_reqevents) {
            if (c->pollfd.reqevents != 0) {
                rv = apr_pollset_remove(readbits, &c->pollfd);
                if (rv != APR_SUCCESS) {
                    apr_err("apr_pollset_remove()", rv);
                }
            }
    
            if (new_reqevents != 0) {
                c->pollfd.reqevents = new_reqevents;
                rv = apr_pollset_add(readbits, &c->pollfd);
                if (rv != APR_SUCCESS) {
                    apr_err("apr_pollset_add()", rv);
                }
            }
        }
    }
    
    static void set_conn_state(struct connection *c, connect_state_e new_state)
    {
        apr_int16_t events_by_state[] = {
            0,           /* for STATE_UNCONNECTED */
            APR_POLLOUT, /* for STATE_CONNECTING */
            APR_POLLIN,  /* for STATE_CONNECTED; we don't poll in this state,
                          * so prepare for polling in the following state --
                          * STATE_READ
                          */
            APR_POLLIN   /* for STATE_READ */
        };
    
        c->state = new_state;
    
        set_polled_events(c, events_by_state[new_state]);
    }
    
    /* --------------------------------------------------------- */
    /* write out request to a connection - assumes we can write
     * (small) request out in one go into our new socket buffer
     *
     */
    #ifdef USE_SSL
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    static long ssl_print_cb(BIO *bio, int cmd, const char *argp,
                             size_t len, int argi, long argl, int ret,
                             size_t *processed)
    #else
    static long ssl_print_cb(BIO *bio, int cmd, const char *argp,
                             int argi, long argl, long ret)
    #endif
    {
        BIO *out;
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
        (void)len;
        (void)processed;
    #endif
    
        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 %p [%p] (%d bytes => %ld (0x%lX))\n",
                       bio, argp, argi, (long)ret, (long)ret);
            BIO_dump(out,(char *)argp,(int)ret);
            return(ret);
        }
        else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) {
            BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n",
                       bio, argp, argi, (long)ret, (long)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
    #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 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);
    
        /*
         * seed in the current process id (usually just 4 bytes)
         */
        pid = getpid();
        l = sizeof(pid_t);
        RAND_seed((unsigned char *)&pid, 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);
    }
    
    static int ssl_print_connection_info(BIO *bio, SSL *ssl)
    {
        AB_SSL_CIPHER_CONST SSL_CIPHER *c;
        int alg_bits,bits;
    
        BIO_printf(bio,"Transport Protocol      :%s\n", SSL_get_version(ssl));
    
        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;
        EVP_PKEY *pk;
        char buf[1024];
    
        BIO_printf(bio, "Certificate version: %ld\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");
    
        pk = X509_get_pubkey(cert);
        BIO_printf(bio,"Public key is %d bits\n",
                   EVP_PKEY_bits(pk));
        EVP_PKEY_free(pk);
    
        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; i<count; i++) {
                cert = (X509 *)SK_VALUE(sk, i);
                ssl_print_cert_info(bio_out, cert);
        }
        }
        cert = SSL_get_peer_certificate(c->ssl);
        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;
    
            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) {
                    AB_SSL_CIPHER_CONST 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 = xmalloc(128);
                    apr_snprintf(ssl_info, 128, "%s,%s,%d,%d",
                                 SSL_get_version(c->ssl),
                                 SSL_CIPHER_get_name(ci),
                                 pk_bits, sk_bits);
                    if (cert) X509_free(cert);
                }
    #if OPENSSL_VERSION_NUMBER >= 0x10002000L
                if (ssl_tmp_key == NULL) {
                    EVP_PKEY *key;
                    if (SSL_get_server_tmp_key(c->ssl, &key)) {
                        ssl_tmp_key = xmalloc(128);
                        switch (EVP_PKEY_id(key)) {
                        case EVP_PKEY_RSA:
                            apr_snprintf(ssl_tmp_key, 128, "RSA %d bits",
                                         EVP_PKEY_bits(key));
                            break;
                        case EVP_PKEY_DH:
                            apr_snprintf(ssl_tmp_key, 128, "DH %d bits",
                                         EVP_PKEY_bits(key));
                            break;
    #ifndef OPENSSL_NO_EC
                        case EVP_PKEY_EC: {
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
                            size_t len;
                            char cname[80];
                            if (!EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_GROUP_NAME,
                                                                cname, sizeof(cname), &len)) {
                                cname[0] = '?';
                                len = 1;
                            }
                            cname[len] = '\0';
    #else
                            const char *cname = NULL;
                            EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key);
                            int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
                            EC_KEY_free(ec);
                            cname = EC_curve_nid2nist(nid);
                            if (!cname) {
                                cname = OBJ_nid2sn(nid);
                                if (!cname)
                                    cname = "?";
                            }
    #endif
                            apr_snprintf(ssl_tmp_key, 128, "ECDH %s %d bits",
                                         cname, EVP_PKEY_bits(key));
                            break;
                            }
    #endif
                        default:
                            apr_snprintf(ssl_tmp_key, 128, "%s %d bits",
                                         OBJ_nid2sn(EVP_PKEY_id(key)),
                                         EVP_PKEY_bits(key));
                            break;
                        }
                        EVP_PKEY_free(key);
                    }
                }
    #endif
                write_request(c);
                do_next = 0;
                break;
            case SSL_ERROR_WANT_READ:
                set_polled_events(c, APR_POLLIN);
                do_next = 0;
                break;
            case SSL_ERROR_WANT_WRITE:
                set_polled_events(c, APR_POLLOUT);
                do_next = 0;
                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)
    {
        if (started >= requests) {
            return;
        }
    
        do {
            apr_time_t tnow;
            apr_size_t l = c->rwrite;
            apr_status_t e = APR_SUCCESS; /* prevent gcc warning */
    
            tnow = lasttime = apr_time_now();
    
            /*
             * First time round ?
             */
            if (c->rwrite == 0) {
                apr_socket_timeout_set(c->aprsock, 0);
                c->connect = tnow;
                c->rwrote = 0;
                c->rwrite = reqlen;
                if (send_body)
                    c->rwrite += postlen;
                l = c->rwrite;
            }
            else if (tnow > c->connect + aprtimeout) {
                printf("Send request timed out!\n");
                close_connection(c);
                return;
            }
    
    #ifdef USE_SSL
            if (c->ssl) {
                e = SSL_write(c->ssl, request + c->rwrote, l);
                if (e <= 0) {
                    switch (SSL_get_error(c->ssl, e)) {
                    case SSL_ERROR_WANT_READ:
                        set_polled_events(c, APR_POLLIN);
                        break;
                    case SSL_ERROR_WANT_WRITE:
                        set_polled_events(c, APR_POLLOUT);
                        break;
                    default:
                        BIO_printf(bio_err, "SSL write failed - closing connection\n");
                        ERR_print_errors(bio_err);
                        close_connection (c);
                        break;
                    }
                    return;
                }
                l = e;
            }
            else
    #endif
            {
                e = apr_socket_send(c->aprsock, request + c->rwrote, &l);
                if (e != APR_SUCCESS && !l) {
                    if (!APR_STATUS_IS_EAGAIN(e)) {
                        epipe++;
                        printf("Send request failed!\n");
                        close_connection(c);
                    }
                    else {
                        set_polled_events(c, APR_POLLOUT);
                    }
                    return;
                }
            }
            totalposted += l;
            c->rwrote += l;
            c->rwrite -= l;
        } while (c->rwrite);
    
        c->endwrite = lasttime = apr_time_now();
        started++;
        set_conn_state(c, STATE_READ);
    }
    
    /* --------------------------------------------------------- */
    
    /* 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(int sig)
    {
        double timetaken;
    
        if (sig) {
            lasttime = apr_time_now();  /* record final time if interrupted */
        }
        timetaken = (double) (lasttime - start) / APR_USEC_PER_SEC;
    
        printf("\n\n");
        printf("Server Software:        %s\n", servername);
        printf("Server Hostname:        %s\n", hostname);
        printf("Server Port:            %hu\n", port);
    #ifdef USE_SSL
        if (is_ssl && ssl_info) {
            printf("SSL/TLS Protocol:       %s\n", ssl_info);
        }
    #if OPENSSL_VERSION_NUMBER >= 0x10002000L
        if (is_ssl && ssl_tmp_key) {
            printf("Server Temp Key:        %s\n", ssl_tmp_key);
        }
    #endif
    #ifdef HAVE_TLSEXT
        if (is_ssl && tls_sni) {
            printf("TLS Server Name:        %s\n", tls_sni);
        }
    #endif
    #endif
        printf("\n");
        printf("Document Path:          %s\n", path);
        if (nolength)
            printf("Document Length:        Variable\n");
        else
            printf("Document Length:        %" APR_SIZE_T_FMT " bytes\n", doclen);
        printf("\n");
        printf("Concurrency Level:      %d\n", concurrency);
        printf("Time taken for tests:   %.3f seconds\n", timetaken);
        printf("Complete requests:      %d\n", done);
        printf("Failed requests:        %d\n", bad);
        if (bad)
            printf("   (Connect: %d, Receive: %d, Length: %d, Exceptions: %d)\n",
                err_conn, err_recv, err_length, err_except);
        if (epipe)
            printf("Write errors:           %d\n", epipe);
        if (err_response)
            printf("Non-2xx responses:      %d\n", err_response);
        if (keepalive)
            printf("Keep-Alive requests:    %d\n", doneka);
        printf("Total transferred:      %" APR_INT64_T_FMT " bytes\n", totalread);
        if (send_body)
            printf("Total body sent:        %" APR_INT64_T_FMT "\n",
                   totalposted);
        printf("HTML transferred:       %" APR_INT64_T_FMT " bytes\n", totalbread);
    
        /* avoid divide by zero */
        if (timetaken && done) {
            printf("Requests per second:    %.2f [#/sec] (mean)\n",
                   (double) done / timetaken);
            printf("Time per request:       %.3f [ms] (mean)\n",
                   (double) concurrency * timetaken * 1000 / done);
            printf("Time per request:       %.3f [ms] (mean, across all concurrent requests)\n",
                   (double) timetaken * 1000 / done);
            printf("Transfer rate:          %.2f [Kbytes/sec] received\n",
                   (double) totalread / 1024 / timetaken);
            if (send_body) {
                printf("                        %.2f kb/s sent\n",
                   (double) totalposted / 1024 / timetaken);
                printf("                        %.2f kb/s total\n",
                   (double) (totalread + totalposted) / 1024 / timetaken);
            }
        }
    
        if (done > 0) {
            /* work out connection times */
            int 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 < done; 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 / done;
            meantot = total / done;
            meand = totald / done;
            meanwait = totalwait / done;
    
            /* calculating the sample variance: the sum of the squared deviations, divided by n-1 */
            for (i = 0; i < done; 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 = (done > 1) ? sqrt(sdtot / (done - 1)) : 0;
            sdcon = (done > 1) ? sqrt(sdcon / (done - 1)) : 0;
            sdd = (done > 1) ? sqrt(sdd / (done - 1)) : 0;
            sdwait = (done > 1) ? sqrt(sdwait / (done - 1)) : 0;
    
            /*
             * 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, done, sizeof(struct data),
                  (int (*) (const void *, const void *)) compradre);
            if ((done > 1) && (done % 2))
                mediancon = (stats[done / 2].ctime + stats[done / 2 + 1].ctime) / 2;
            else
                mediancon = stats[done / 2].ctime;
    
            qsort(stats, done, sizeof(struct data),
                  (int (*) (const void *, const void *)) compri);
            if ((done > 1) && (done % 2))
                mediand = (stats[done / 2].time + stats[done / 2 + 1].time \
                -stats[done / 2].ctime - stats[done / 2 + 1].ctime) / 2;
            else
                mediand = stats[done / 2].time - stats[done / 2].ctime;
    
            qsort(stats, done, sizeof(struct data),
                  (int (*) (const void *, const void *)) compwait);
            if ((done > 1) && (done % 2))
                medianwait = (stats[done / 2].waittime + stats[done / 2 + 1].waittime) / 2;
            else
                medianwait = stats[done / 2].waittime;
    
            qsort(stats, done, sizeof(struct data),
                  (int (*) (const void *, const void *)) comprando);
            if ((done > 1) && (done % 2))
                mediantot = (stats[done / 2].time + stats[done / 2 + 1].time) / 2;
            else
                mediantot = stats[done / 2].time;
    
            printf("\nConnection Times (ms)\n");
            /*
             * Reduce stats from apr time to milliseconds
             */
            mincon     = ap_round_ms(mincon);
            mind       = ap_round_ms(mind);
            minwait    = ap_round_ms(minwait);
            mintot     = ap_round_ms(mintot);
            meancon    = ap_round_ms(meancon);
            meand      = ap_round_ms(meand);
            meanwait   = ap_round_ms(meanwait);
            meantot    = ap_round_ms(meantot);
            mediancon  = ap_round_ms(mediancon);
            mediand    = ap_round_ms(mediand);
            medianwait = ap_round_ms(medianwait);
            mediantot  = ap_round_ms(mediantot);
            maxcon     = ap_round_ms(maxcon);
            maxd       = ap_round_ms(maxd);
            maxwait    = ap_round_ms(maxwait);
            maxtot     = ap_round_ms(maxtot);
            sdcon      = ap_double_ms(sdcon);
            sdd        = ap_double_ms(sdd);
            sdwait     = ap_double_ms(sdwait);
            sdtot      = ap_double_ms(sdtot);
    
            if (confidence) {
    #define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %4" APR_TIME_T_FMT " %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, meancon, sdcon, mediancon, maxcon);
                printf("Processing: " CONF_FMT_STRING,
                       mind, meand, sdd, mediand, maxd);
                printf("Waiting:    " CONF_FMT_STRING,
                       minwait, meanwait, sdwait, medianwait, maxwait);
                printf("Total:      " CONF_FMT_STRING,
                       mintot, meantot, 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, mind, meand, maxd);
                printf("Waiting:    " CONF_FMT_STRING, minwait, meanwait, maxwait);
                printf("Total:      " CONF_FMT_STRING, mintot, meantot, maxtot);
    #undef CONF_FMT_STRING
            }
    
    
            /* Sorted on total connect times */
            if (percentile && (done > 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",
                               ap_round_ms(stats[done - 1].time));
                    else
                        printf("  %d%%  %5" APR_TIME_T_FMT "\n", percs[i],
                               ap_round_ms(stats[(unsigned long)done * percs[i] / 100].time));
                }
            }
            if (csvperc) {
                FILE *out = fopen(csvperc, "w");
                if (!out) {
                    perror("Cannot open CSV output file");
                    exit(1);
                }
                fprintf(out, "" "Percentage served" "," "Time in ms" "\n");
                for (i = 0; i <= 100; i++) {
                    double t;
                    if (i == 0)
                        t = ap_double_ms(stats[0].time);
                    else if (i == 100)
                        t = ap_double_ms(stats[done - 1].time);
                    else
                        t = ap_double_ms(stats[(unsigned long) (0.5 + (double)done * i / 100.0)].time);
                    fprintf(out, "%d,%.3f\n", i, t);
                }
                fclose(out);
            }
            if (gnuplot) {
                FILE *out = fopen(gnuplot, "w");
                char tmstring[APR_CTIME_LEN];
                if (!out) {
                    perror("Cannot open gnuplot output file");
                    exit(1);
                }
                fprintf(out, "starttime\tseconds\tctime\tdtime\tttime\twait\n");
                for (i = 0; i < done; i++) {
                    (void) apr_ctime(tmstring, stats[i].starttime);
                    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,
                            apr_time_sec(stats[i].starttime),
                            ap_round_ms(stats[i].ctime),
                            ap_round_ms(stats[i].time - stats[i].ctime),
                            ap_round_ms(stats[i].time),
                            ap_round_ms(stats[i].waittime));
                }
                fclose(out);
            }
        }
    
        if (sig) {
            exit(1);
        }
    }
    
    /* --------------------------------------------------------- */
    
    /* calculate and output results in HTML  */
    
    static void output_html_results(void)
    {
        double timetaken = (double) (lasttime - start) / APR_USEC_PER_SEC;
    
        printf("\n\n<table %s>\n", tablestring);
        printf("<tr %s><th colspan=2 %s>Server Software:</th>"
           "<td colspan=2 %s>%s</td></tr>\n",
           trstring, tdstring, tdstring, servername);
        printf("<tr %s><th colspan=2 %s>Server Hostname:</th>"
           "<td colspan=2 %s>%s</td></tr>\n",
           trstring, tdstring, tdstring, hostname);
        printf("<tr %s><th colspan=2 %s>Server Port:</th>"
           "<td colspan=2 %s>%hu</td></tr>\n",
           trstring, tdstring, tdstring, port);
        printf("<tr %s><th colspan=2 %s>Document Path:</th>"
           "<td colspan=2 %s>%s</td></tr>\n",
           trstring, tdstring, tdstring, path);
        if (nolength)
            printf("<tr %s><th colspan=2 %s>Document Length:</th>"
                "<td colspan=2 %s>Variable</td></tr>\n",
                trstring, tdstring, tdstring);
        else
            printf("<tr %s><th colspan=2 %s>Document Length:</th>"
                "<td colspan=2 %s>%" APR_SIZE_T_FMT " bytes</td></tr>\n",
                trstring, tdstring, tdstring, doclen);
        printf("<tr %s><th colspan=2 %s>Concurrency Level:</th>"
           "<td colspan=2 %s>%d</td></tr>\n",
           trstring, tdstring, tdstring, concurrency);
        printf("<tr %s><th colspan=2 %s>Time taken for tests:</th>"
           "<td colspan=2 %s>%.3f seconds</td></tr>\n",
           trstring, tdstring, tdstring, timetaken);
        printf("<tr %s><th colspan=2 %s>Complete requests:</th>"
           "<td colspan=2 %s>%d</td></tr>\n",
           trstring, tdstring, tdstring, done);
        printf("<tr %s><th colspan=2 %s>Failed requests:</th>"
           "<td colspan=2 %s>%d</td></tr>\n",
           trstring, tdstring, tdstring, bad);
        if (bad)
            printf("<tr %s><td colspan=4 %s >   (Connect: %d, Length: %d, Exceptions: %d)</td></tr>\n",
               trstring, tdstring, err_conn, err_length, err_except);
        if (err_response)
            printf("<tr %s><th colspan=2 %s>Non-2xx responses:</th>"
               "<td colspan=2 %s>%d</td></tr>\n",
               trstring, tdstring, tdstring, err_response);
        if (keepalive)
            printf("<tr %s><th colspan=2 %s>Keep-Alive requests:</th>"
               "<td colspan=2 %s>%d</td></tr>\n",
               trstring, tdstring, tdstring, doneka);
        printf("<tr %s><th colspan=2 %s>Total transferred:</th>"
           "<td colspan=2 %s>%" APR_INT64_T_FMT " bytes</td></tr>\n",
           trstring, tdstring, tdstring, totalread);
        if (send_body)
            printf("<tr %s><th colspan=2 %s>Total body sent:</th>"
               "<td colspan=2 %s>%" APR_INT64_T_FMT "</td></tr>\n",
               trstring, tdstring,
               tdstring, totalposted);
        printf("<tr %s><th colspan=2 %s>HTML transferred:</th>"
           "<td colspan=2 %s>%" APR_INT64_T_FMT " bytes</td></tr>\n",
           trstring, tdstring, tdstring, totalbread);
    
        /* avoid divide by zero */
        if (timetaken) {
            printf("<tr %s><th colspan=2 %s>Requests per second:</th>"
               "<td colspan=2 %s>%.2f</td></tr>\n",
               trstring, tdstring, tdstring, (double) done / timetaken);
            printf("<tr %s><th colspan=2 %s>Transfer rate:</th>"
               "<td colspan=2 %s>%.2f kb/s received</td></tr>\n",
               trstring, tdstring, tdstring, (double) totalread / 1024 / timetaken);
            if (send_body) {
                printf("<tr %s><td colspan=2 %s>&nbsp;</td>"
                   "<td colspan=2 %s>%.2f kb/s sent</td></tr>\n",
                   trstring, tdstring, tdstring,
                   (double) totalposted / 1024 / timetaken);
                printf("<tr %s><td colspan=2 %s>&nbsp;</td>"
                   "<td colspan=2 %s>%.2f kb/s total</td></tr>\n",
                   trstring, tdstring, tdstring,
                   (double) (totalread + totalposted) / 1024 / timetaken);
            }
        }
        {
            /* work out connection times */
            int 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 < done; 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;
            }
            /*
             * Reduce stats from apr time to milliseconds
             */
            mincon   = ap_round_ms(mincon);
            mintot   = ap_round_ms(mintot);
            maxcon   = ap_round_ms(maxcon);
            maxtot   = ap_round_ms(maxtot);
            totalcon = ap_round_ms(totalcon);
            total    = ap_round_ms(total);
    
            if (done > 0) { /* avoid division by zero (if 0 done) */
                printf("<tr %s><th %s colspan=4>Connection Times (ms)</th></tr>\n",
                   trstring, tdstring);
                printf("<tr %s><th %s>&nbsp;</th> <th %s>min</th>   <th %s>avg</th>   <th %s>max</th></tr>\n",
                   trstring, tdstring, tdstring, tdstring, tdstring);
                printf("<tr %s><th %s>Connect:</th>"
                   "<td %s>%5" APR_TIME_T_FMT "</td>"
                   "<td %s>%5" APR_TIME_T_FMT "</td>"
                   "<td %s>%5" APR_TIME_T_FMT "</td></tr>\n",
                   trstring, tdstring, tdstring, mincon, tdstring, totalcon / done, tdstring, maxcon);
                printf("<tr %s><th %s>Processing:</th>"
                   "<td %s>%5" APR_TIME_T_FMT "</td>"
                   "<td %s>%5" APR_TIME_T_FMT "</td>"
                   "<td %s>%5" APR_TIME_T_FMT "</td></tr>\n",
                   trstring, tdstring, tdstring, mintot - mincon, tdstring,
                   (total / done) - (totalcon / done), tdstring, maxtot - maxcon);
                printf("<tr %s><th %s>Total:</th>"
                   "<td %s>%5" APR_TIME_T_FMT "</td>"
                   "<td %s>%5" APR_TIME_T_FMT "</td>"
                   "<td %s>%5" APR_TIME_T_FMT "</td></tr>\n",
                   trstring, tdstring, tdstring, mintot, tdstring, total / done, tdstring, maxtot);
            }
            printf("</table>\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_clear(c->ctx);
        else
            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 (myhost) {
            if ((rv = apr_socket_bind(c->aprsock, mysa)) != APR_SUCCESS) {
                apr_err("bind", rv);
            }
        }
    
        c->pollfd.desc_type = APR_POLL_SOCKET;
        c->pollfd.desc.s = c->aprsock;
        c->pollfd.reqevents = 0;
        c->pollfd.client_data = c;
    
        if ((rv = apr_socket_opt_set(c->aprsock, APR_SO_NONBLOCK, 1))
             != APR_SUCCESS) {
            apr_err("socket nonblock", rv);
        }
    
        if (windowsize != 0) {
            rv = apr_socket_opt_set(c->aprsock, APR_SO_SNDBUF,
                                    windowsize);
            if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                apr_err("socket send buffer", rv);
            }
            rv = apr_socket_opt_set(c->aprsock, APR_SO_RCVBUF,
                                    windowsize);
            if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
                apr_err("socket receive buffer", rv);
            }
        }
    
        c->start = lasttime = 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);
            BIO_set_nbio(bio, 1);
            SSL_set_bio(c->ssl, bio, bio);
            SSL_set_connect_state(c->ssl);
            if (verbosity >= 4) {
    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
                BIO_set_callback_ex(bio, ssl_print_cb);
    #else
                BIO_set_callback(bio, ssl_print_cb);
    #endif
                BIO_set_callback_arg(bio, (void *)bio_err);
            }
    #ifdef HAVE_TLSEXT
            if (tls_sni) {
                SSL_set_tlsext_host_name(c->ssl, tls_sni);
            }
    #endif
        } else {
            c->ssl = NULL;
        }
    #endif
        if ((rv = apr_socket_connect(c->aprsock, destsa)) != APR_SUCCESS) {
            if (APR_STATUS_IS_EINPROGRESS(rv)) {
                set_conn_state(c, STATE_CONNECTING);
                c->rwrite = 0;
                return;
            }
            else {
                set_conn_state(c, STATE_UNCONNECTED);
                apr_socket_close(c->aprsock);
                if (good == 0 && destsa->next) {
                    destsa = destsa->next;
                    err_conn = 0;
                }
                else if (bad++ > 10) {
                    fprintf(stderr,
                       "\nTest aborted after 10 failures\n\n");
                    apr_err("apr_socket_connect()", rv);
                }
                else {
                    err_conn++;
                }
    
                start_connect(c);
                return;
            }
        }
    
        /* connected first time */
        set_conn_state(c, STATE_CONNECTED);
    #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) && !nolength) {
                bad++;
                err_length++;
            }
            /* save out time */
            if (done < requests) {
                struct data *s = &stats[done++];
                c->done      = lasttime = apr_time_now();
                s->starttime = c->start;
                s->ctime     = ap_max(0, c->connect - c->start);
                s->time      = ap_max(0, c->done - c->start);
                s->waittime  = ap_max(0, c->beginread - c->endwrite);
                if (heartbeatres && !(done % heartbeatres)) {
                    fprintf(stderr, "Completed %d requests\n", done);
                    fflush(stderr);
                }
            }
        }
    
        set_conn_state(c, STATE_UNCONNECTED);
    #ifdef USE_SSL
        if (c->ssl) {
            SSL_shutdown(c->ssl);
            SSL_free(c->ssl);
            c->ssl = NULL;
        }
    #endif
        apr_socket_close(c->aprsock);
    
        /* 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 */
        int i;
    
        r = sizeof(buffer);
    read_more:
    #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_SYSCALL
                         && status == 0
                         && c->read != 0) {
                    /* connection closed, but in violation of the protocol, after
                     * some data has already been read; this commonly happens, so
                     * let the length check catch any response errors
                     */
                    good++;
                    close_connection(c);
                }
                else if (scode == SSL_ERROR_SYSCALL 
                         && c->read == 0
                         && destsa->next
                         && c->state == STATE_CONNECTING
                         && good == 0) {
                    return;
                }
                else if (scode == SSL_ERROR_WANT_READ) {
                    set_polled_events(c, APR_POLLIN);
                }
                else if (scode == SSL_ERROR_WANT_WRITE) {
                    set_polled_events(c, APR_POLLOUT);
                }
                else {
                    /* some fatal error: */
                    c->read = 0;
                    BIO_printf(bio_err, "SSL read failed (%d) - closing connection\n", scode);
                    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) {
                if (recverrok) {
                    err_recv++;
                    bad++;
                    close_connection(c);
                    if (verbosity >= 1) {
                        char buf[120];
                        fprintf(stderr,"%s: %s (%d)\n", "apr_socket_recv", apr_strerror(status, buf, sizeof buf), status);
                    }
                    return;
                } else if (destsa->next && c->state == STATE_CONNECTING
                           && c->read == 0 && good == 0) {
                    return;
                }
                else {
                    err_recv++;
                    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/%" APR_SIZE_T_FMT
                                "/%" APR_SIZE_T_FMT ")\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 */
                    set_conn_state(c, STATE_UNCONNECTED);
                    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;
                    size_t len = 0;
                    p = xstrcasestr(c->cbuff, "Server:");
                    q = servername;
                    if (p) {
                        p += 8;
                        /* -1 to not overwrite last '\0' byte */
                        while (*p > 32 && len++ < sizeof(servername) - 1)
                            *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 && xstrcasestr(c->cbuff, "Keep-Alive")) {
                    char *cl;
                    c->keepalive = 1;
                    cl = xstrcasestr(c->cbuff, "Content-Length:");
                    if (cl && method != HEAD) {
                        /* response to HEAD doesn't have entity body */
                        c->length = atoi(cl + 16);
                    }
                    else {
                        c->length = 0;
                    }
                }
                c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy;
                totalbread += c->bread;
    
                /* We have received the header, so we know this destination socket
                 * address is working, so initialize all remaining requests. */
                if (!requests_initialized) {
                    for (i = 1; i < concurrency; i++) {
                        con[i].socknum = i;
                        start_connect(&con[i]);
                    }
                    requests_initialized = 1;
                }
            }
        }
        else {
            /* outside header, everything we have read is entity body */
            c->bread += r;
            totalbread += r;
        }
        if (r == sizeof(buffer) && c->bread < c->length) {
            /* read was full, try more immediately (nonblocking already) */
            goto read_more;
        }
    
        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) && !nolength) {
                bad++;
                err_length++;
            }
            if (done < requests) {
                struct data *s = &stats[done++];
                doneka++;
                c->done      = apr_time_now();
                s->starttime = c->start;
                s->ctime     = ap_max(0, c->connect - c->start);
                s->time      = ap_max(0, c->done - c->start);
                s->waittime  = ap_max(0, c->beginread - c->endwrite);
                if (heartbeatres && !(done % heartbeatres)) {
                    fprintf(stderr, "Completed %d requests\n", done);
                    fflush(stderr);
                }
            }
            c->keepalive = 0;
            c->length = 0;
            c->gotheader = 0;
            c->cbx = 0;
            c->read = c->bread = 0;
            /* zero connect time with keep-alive */
            c->start = c->connect = lasttime = apr_time_now();
            set_conn_state(c, STATE_CONNECTED);
            write_request(c);
        }
    }
    
    /* --------------------------------------------------------- */
    
    /* run the tests */
    
    static void test(void)
    {
        apr_time_t stoptime;
        apr_int16_t rtnev;
        apr_status_t rv;
        int 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);
        }
    
        con = xcalloc(concurrency, sizeof(struct connection));
    
        /*
         * XXX: a way to calculate the stats without requiring O(requests) memory
         * XXX: would be nice.
         */
        stats = xcalloc(requests, sizeof(struct data));
    
        if ((status = apr_pollset_create(&readbits, concurrency, cntxt,
                                         APR_POLLSET_NOCOPY)) != APR_SUCCESS) {
            apr_err("apr_pollset_create failed", status);
        }
    
        /* add default headers if necessary */
        if (!opt_host) {
            /* Host: header not overridden, add default value to hdrs */
            hdrs = apr_pstrcat(cntxt, hdrs, "Host: ", host_field, colonhost, "\r\n", NULL);
        }
        else {
            /* Header overridden, no need to add, as it is already in hdrs */
        }
    
    #ifdef HAVE_TLSEXT
        if (is_ssl && tls_use_sni) {
            apr_ipsubnet_t *ip;
            if (((tls_sni = opt_host) || (tls_sni = hostname)) &&
                (!*tls_sni || apr_ipsubnet_create(&ip, tls_sni, NULL,
                                                   cntxt) == APR_SUCCESS)) {
                /* IP not allowed in TLS SNI extension */
                tls_sni = NULL;
            }
        }
    #endif
    
        if (!opt_useragent) {
            /* User-Agent: header not overridden, add default value to hdrs */
            hdrs = apr_pstrcat(cntxt, hdrs, "User-Agent: ApacheBench/", AP_AB_BASEREVISION, "\r\n", NULL);
        }
        else {
            /* Header overridden, no need to add, as it is already in hdrs */
        }
    
        if (!opt_accept) {
            /* Accept: header not overridden, add default value to hdrs */
            hdrs = apr_pstrcat(cntxt, hdrs, "Accept: */*\r\n", NULL);
        }
        else {
            /* Header overridden, no need to add, as it is already in hdrs */
        }
    
        /* setup request */
        if (!send_body) {
            snprintf_res = apr_snprintf(request, sizeof(_request),
                "%s %s HTTP/1.0\r\n"
                "%s" "%s" "%s"
                "%s" "\r\n",
                method_str[method],
                (isproxy) ? fullurl : path,
                keepalive ? "Connection: Keep-Alive\r\n" : "",
                cookie, auth, hdrs);
        }
        else {
            snprintf_res = apr_snprintf(request,  sizeof(_request),
                "%s %s HTTP/1.0\r\n"
                "%s" "%s" "%s"
                "Content-length: %" APR_SIZE_T_FMT "\r\n"
                "Content-type: %s\r\n"
                "%s"
                "\r\n",
                method_str[method],
                (isproxy) ? fullurl : path,
                keepalive ? "Connection: Keep-Alive\r\n" : "",
                cookie, auth,
                postlen,
                (content_type != NULL) ? content_type : "text/plain", hdrs);
        }
        if (snprintf_res >= sizeof(_request)) {
            err("Request too long\n");
        }
    
        if (verbosity >= 2)
            printf("INFO: %s header == \n---\n%s\n---\n",
                   method_str[method], request);
    
        reqlen = strlen(request);
    
        /*
         * Combine headers and (optional) post file into one continuous buffer
         */
        if (send_body) {
            char *buff = xmalloc(postlen + reqlen + 1);
            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/%"
                            APR_SIZE_T_FMT "/%" APR_SIZE_T_FMT ")\n",
                            status, inbytes_left, outbytes_left);
            exit(1);
        }
    #endif              /* NOT_ASCII */
    
        if (myhost) {
            /* This only needs to be done once */
            if ((rv = apr_sockaddr_info_get(&mysa, myhost, APR_UNSPEC, 0, 0, cntxt)) != APR_SUCCESS) {
                char buf[120];
                apr_snprintf(buf, sizeof(buf),
                             "apr_sockaddr_info_get() for %s", myhost);
                apr_err(buf, rv);
            }
        }
    
        /* This too */
        if ((rv = apr_sockaddr_info_get(&destsa, connecthost,
                                        myhost ? mysa->family : 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 = lasttime = apr_time_now();
        stoptime = tlimit ? (start + apr_time_from_sec(tlimit)) : AB_MAX;
    
    #ifdef SIGINT
        /* Output the results if the user terminates the run early. */
        apr_signal(SIGINT, output_results);
    #endif
    
        /* initialise first connection to determine destination socket address
         * which should be used for next connections. */
        con[0].socknum = 0;
        start_connect(&con[0]);
    
        do {
            apr_int32_t n;
            const apr_pollfd_t *pollresults, *pollfd;
    
            n = concurrency;
            do {
                status = apr_pollset_poll(readbits, aprtimeout, &n, &pollresults);
            } while (APR_STATUS_IS_EINTR(status));
            if (status != APR_SUCCESS)
                apr_err("apr_pollset_poll", status);
    
            for (i = 0, pollfd = pollresults; i < n; i++, pollfd++) {
                struct connection *c;
    
                c = pollfd->client_data;
    
                /*
                 * If the connection isn't connected how can we check it?
                 */
                if (c->state == STATE_UNCONNECTED)
                    continue;
    
                rtnev = pollfd->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 ((rtnev & APR_POLLIN) || (rtnev & APR_POLLPRI) || (rtnev & APR_POLLHUP))
                    read_connection(c);
                if ((rtnev & APR_POLLERR) || (rtnev & APR_POLLNVAL)) {
                    if (destsa->next && c->state == STATE_CONNECTING && good == 0) {
                        destsa = destsa->next;
                        start_connect(c);
                    }
                    else {
                        bad++;
                        err_except++;
                        /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */
                        if (c->state == STATE_CONNECTING) {
                            read_connection(c);
                        }
                        else {
                            start_connect(c);
                        }
                    }
                    continue;
                }
                if (rtnev & APR_POLLOUT) {
                    if (c->state == STATE_CONNECTING) {
                        /* call connect() again to detect errors */
                        rv = apr_socket_connect(c->aprsock, destsa);
                        if (rv != APR_SUCCESS) {
                            set_conn_state(c, STATE_UNCONNECTED);
                            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);
                            }
                            start_connect(c);
                            continue;
                        }
                        else {
                            set_conn_state(c, STATE_CONNECTED);
    #ifdef USE_SSL
                            if (c->ssl)
                                ssl_proceed_handshake(c);
                            else
    #endif
                            write_request(c);
                        }
                    }
                    else {
                        /* POLLOUT is one shot */
                        set_polled_events(c, APR_POLLIN);
                        if (c->state == STATE_READ) {
                            read_connection(c);
                        }
                        else {
                            write_request(c);
                        }
                    }
                }
            }
        } while (lasttime < stoptime && done < requests);
    
        if (heartbeatres)
            fprintf(stderr, "Finished %d requests\n", done);
        else
            printf("..done\n");
    
        if (use_html)
            output_html_results();
        else
            output_results(0);
    }
    
    /* ------------------------------------------------------- */
    
    /* display copyright information */
    static void copyright(void)
    {
        if (!use_html) {
            printf("This is ApacheBench, Version %s\n", AP_AB_BASEREVISION " <$Revision: 1923142 $>");
            printf("Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/\n");
            printf("Licensed to The Apache Software Foundation, http://www.apache.org/\n");
            printf("\n");
        }
        else {
            printf("<p>\n");
            printf(" This is ApacheBench, Version %s <i>&lt;%s&gt;</i><br>\n", AP_AB_BASEREVISION, "$Revision: 1923142 $");
            printf(" Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/<br>\n");
            printf(" Licensed to The Apache Software Foundation, http://www.apache.org/<br>\n");
            printf("</p>\n<p>\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);
    /* 80 column ruler:  ********************************************************************************
     */
        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 at a time\n");
        fprintf(stderr, "    -t timelimit    Seconds to max. to spend on benchmarking\n");
        fprintf(stderr, "                    This implies -n 50000\n");
        fprintf(stderr, "    -s timeout      Seconds to max. wait for each response\n");
        fprintf(stderr, "                    Default is 30 seconds\n");
        fprintf(stderr, "    -b windowsize   Size of TCP send/receive buffer, in bytes\n");
        fprintf(stderr, "    -B address      Address to bind to when making outgoing connections\n");
        fprintf(stderr, "    -p postfile     File containing data to POST. Remember also to set -T\n");
        fprintf(stderr, "    -u putfile      File containing data to PUT. Remember also to set -T\n");
        fprintf(stderr, "    -T content-type Content-type header to use for POST/PUT data, eg.\n");
        fprintf(stderr, "                    'application/x-www-form-urlencoded'\n");
        fprintf(stderr, "                    Default is 'text/plain'\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, "    -q              Do not show progress when doing more than 150 requests\n");
        fprintf(stderr, "    -l              Accept variable document length (use this for dynamic pages)\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, "    -r              Don't exit on socket receive errors.\n");
        fprintf(stderr, "    -m method       Method name\n");
        fprintf(stderr, "    -h              Display usage information (this message)\n");
    #ifdef USE_SSL
    
    #ifndef OPENSSL_NO_SSL2
    #define SSL2_HELP_MSG "SSL2, "
    #else
    #define SSL2_HELP_MSG ""
    #endif
    
    #ifndef OPENSSL_NO_SSL3
    #define SSL3_HELP_MSG "SSL3, "
    #else
    #define SSL3_HELP_MSG ""
    #endif
    
    #ifdef HAVE_TLSV1_X
    
    #ifdef TLS1_3_VERSION
    #define TLS1_X_HELP_MSG ", TLS1.1, TLS1.2, TLS1.3"
    #else
    #define TLS1_X_HELP_MSG ", TLS1.1, TLS1.2"
    #endif
    
    #else
    #define TLS1_X_HELP_MSG ""
    #endif
    
    #ifdef HAVE_TLSEXT
        fprintf(stderr, "    -I              Disable TLS Server Name Indication (SNI) extension\n");
    #endif
        fprintf(stderr, "    -Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)\n");
        fprintf(stderr, "    -f protocol     Specify SSL/TLS protocol\n");
        fprintf(stderr, "                    (" SSL2_HELP_MSG SSL3_HELP_MSG "TLS1" TLS1_X_HELP_MSG " or ALL)\n");
        fprintf(stderr, "    -E certfile     Specify optional client certificate chain and private key\n");
    #endif
        exit(EINVAL);
    }
    
    /* ------------------------------------------------------- */
    
    /* split URL into parts */
    
    static int parse_url(const 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_pstrmemdup(cntxt, url, cp - url);
        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/PUT from file, save contents and length */
    
    static apr_status_t 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;
        }
    
        rv = apr_file_info_get(&finfo, APR_FINFO_NORM, postfd);
        if (rv != APR_SUCCESS) {
            fprintf(stderr, "ab: Could not stat POST data file (%s): %s\n", pfile,
                    apr_strerror(rv, errmsg, sizeof errmsg));
            return rv;
        }
        postlen = (apr_size_t)finfo.size;
        postdata = xmalloc(postlen);
        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 APR_SUCCESS;
    }
    
    /* ------------------------------------------------------- */
    
    /* sort out command-line args and call test */
    int main(int argc, const char * const argv[])
    {
        char tmp[1024];
        apr_status_t status;
        apr_getopt_t *opt;
        const char *opt_arg;
        char c;
    #ifdef USE_SSL
    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
        int max_prot = MAX_SSL_PROTO;
        int min_prot = MIN_SSL_PROTO;
    #endif /* #if OPENSSL_VERSION_NUMBER >= 0x10100000L */
        AB_SSL_METHOD_CONST SSL_METHOD *meth = SSLv23_client_method();
    #endif /* USE_SSL */
    
        /* table defaults  */
        tablestring = "";
        trstring = "";
        tdstring = "bgcolor=white";
        cookie = "";
        auth = "";
        proxyhost = "";
        hdrs = "";
    
        apr_app_initialize(&argc, &argv, NULL);
        atexit(apr_terminate);
        apr_pool_create(&cntxt, NULL);
        apr_pool_abort_set(abort_on_oom, cntxt);
    
    #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
    
        myhost = NULL; /* 0.0.0.0 or :: */
    
        apr_getopt_init(&opt, cntxt, argc, argv);
        while ((status = apr_getopt(opt, "n:c:t:s:b:T:p:u:v:lrkVhwiIx:y:z:C:H:P:A:g:X:de:SqB:m:"
    #ifdef USE_SSL
                "Z:f:E:"
    #endif
                ,&c, &opt_arg)) == APR_SUCCESS) {
            switch (c) {
                case 'n':
                    requests = atoi(opt_arg);
                    if (requests <= 0) {
                        err("Invalid number of requests\n");
                    }
                    break;
                case 'k':
                    keepalive = 1;
                    break;
                case 'q':
                    heartbeatres = 0;
                    break;
                case 'c':
                    concurrency = atoi(opt_arg);
                    break;
                case 'b':
                    windowsize = atoi(opt_arg);
                    break;
                case 'i':
                    if (method != NO_METH)
                        err("Cannot mix HEAD with other methods\n");
                    method = HEAD;
                    break;
                case 'g':
                    gnuplot = xstrdup(opt_arg);
                    break;
                case 'd':
                    percentile = 0;
                    break;
                case 'e':
                    csvperc = xstrdup(opt_arg);
                    break;
                case 'S':
                    confidence = 0;
                    break;
                case 's':
                    aprtimeout = apr_time_from_sec(atoi(opt_arg)); /* timeout value */
                    break;
                case 'p':
                    if (method != NO_METH)
                        err("Cannot mix POST with other methods\n");
                    if (open_postfile(opt_arg) != APR_SUCCESS) {
                        exit(1);
                    }
                    method = POST;
                    send_body = 1;
                    break;
                case 'u':
                    if (method != NO_METH)
                        err("Cannot mix PUT with other methods\n");
                    if (open_postfile(opt_arg) != APR_SUCCESS) {
                        exit(1);
                    }
                    method = PUT;
                    send_body = 1;
                    break;
                case 'l':
                    nolength = 1;
                    break;
                case 'r':
                    recverrok = 1;
                    break;
                case 'v':
                    verbosity = atoi(opt_arg);
                    break;
                case 't':
                    tlimit = atoi(opt_arg);
                    requests = MAX_REQUESTS;    /* need to size data array on
                                                 * something */
                    break;
                case 'T':
                    content_type = apr_pstrdup(cntxt, opt_arg);
                    break;
                case 'C':
                    cookie = apr_pstrcat(cntxt, "Cookie: ", opt_arg, "\r\n", NULL);
                    break;
                case 'A':
                    /*
                     * assume username passwd already to be in colon separated form.
                     * Ready to be uu-encoded.
                     */
                    while (apr_isspace(*opt_arg))
                        opt_arg++;
                    if (apr_base64_encode_len(strlen(opt_arg)) > sizeof(tmp)) {
                        err("Authentication credentials too long\n");
                    }
                    apr_base64_encode(tmp, opt_arg, strlen(opt_arg));
    
                    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(*opt_arg))
                    opt_arg++;
                    if (apr_base64_encode_len(strlen(opt_arg)) > sizeof(tmp)) {
                        err("Proxy credentials too long\n");
                    }
                    apr_base64_encode(tmp, opt_arg, strlen(opt_arg));
    
                    auth = apr_pstrcat(cntxt, auth, "Proxy-Authorization: Basic ",
                                           tmp, "\r\n", NULL);
                    break;
                case 'H':
                    hdrs = apr_pstrcat(cntxt, hdrs, opt_arg, "\r\n", NULL);
                    /*
                     * allow override of some of the common headers that ab adds
                     */
                    if (strncasecmp(opt_arg, "Host:", 5) == 0) {
                        char *host;
                        apr_size_t len;
                        opt_arg += 5;
                        while (apr_isspace(*opt_arg))
                            opt_arg++;
                        len = strlen(opt_arg);
                        host = strdup(opt_arg);
                        while (len && apr_isspace(host[len-1]))
                            host[--len] = '\0';
                        opt_host = host;
                    } else if (strncasecmp(opt_arg, "Accept:", 7) == 0) {
                        opt_accept = 1;
                    } else if (strncasecmp(opt_arg, "User-Agent:", 11) == 0) {
                        opt_useragent = 1;
                    }
                    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 = opt_arg;
                    break;
                case 'X':
                    {
                        char *p;
                        /*
                         * assume proxy-name[:port]
                         */
                        if ((p = strchr(opt_arg, ':'))) {
                            *p = '\0';
                            p++;
                            proxyport = atoi(p);
                        }
                        proxyhost = apr_pstrdup(cntxt, opt_arg);
                        isproxy = 1;
                    }
                    break;
                case 'y':
                    use_html = 1;
                    trstring = opt_arg;
                    break;
                case 'z':
                    use_html = 1;
                    tdstring = opt_arg;
                    break;
                case 'h':
                    usage(argv[0]);
                    break;
                case 'V':
                    copyright();
                    return 0;
                case 'B':
                    myhost = apr_pstrdup(cntxt, opt_arg);
                    break;
                case 'm':
                    method = CUSTOM_METHOD;
                    method_str[CUSTOM_METHOD] = strdup(opt_arg);
                    break;
    #ifdef USE_SSL
                case 'Z':
                    ssl_cipher = strdup(opt_arg);
                    break;
                case 'E':
                    ssl_cert = strdup(opt_arg);
                    break;
                case 'f':
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
                    if (strncasecmp(opt_arg, "ALL", 3) == 0) {
                        meth = SSLv23_client_method();
    #ifndef OPENSSL_NO_SSL2
                    } else if (strncasecmp(opt_arg, "SSL2", 4) == 0) {
                        meth = SSLv2_client_method();
    #ifdef HAVE_TLSEXT
                        tls_use_sni = 0;
    #endif
    #endif
    #ifndef OPENSSL_NO_SSL3
                    } else if (strncasecmp(opt_arg, "SSL3", 4) == 0) {
                        meth = SSLv3_client_method();
    #ifdef HAVE_TLSEXT
                        tls_use_sni = 0;
    #endif
    #endif
    #ifdef HAVE_TLSV1_X
                    } else if (strncasecmp(opt_arg, "TLS1.1", 6) == 0) {
                        meth = TLSv1_1_client_method();
                    } else if (strncasecmp(opt_arg, "TLS1.2", 6) == 0) {
                        meth = TLSv1_2_client_method();
    #endif
                    } else if (strncasecmp(opt_arg, "TLS1", 4) == 0) {
                        meth = TLSv1_client_method();
                    }
    #else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
                    meth = TLS_client_method();
                    if (strncasecmp(opt_arg, "ALL", 3) == 0) {
                        max_prot = MAX_SSL_PROTO;
                        min_prot = MIN_SSL_PROTO;
    #ifndef OPENSSL_NO_SSL3
                    } else if (strncasecmp(opt_arg, "SSL3", 4) == 0) {
                        max_prot = SSL3_VERSION;
                        min_prot = SSL3_VERSION;
    #endif
                    } else if (strncasecmp(opt_arg, "TLS1.1", 6) == 0) {
                        max_prot = TLS1_1_VERSION;
                        min_prot = TLS1_1_VERSION;
                    } else if (strncasecmp(opt_arg, "TLS1.2", 6) == 0) {
                        max_prot = TLS1_2_VERSION;
                        min_prot = TLS1_2_VERSION;
    #ifdef TLS1_3_VERSION
                    } else if (strncasecmp(opt_arg, "TLS1.3", 6) == 0) {
                        max_prot = TLS1_3_VERSION;
                        min_prot = TLS1_3_VERSION;
    #endif
                    } else if (strncasecmp(opt_arg, "TLS1", 4) == 0) {
                        max_prot = TLS1_VERSION;
                        min_prot = TLS1_VERSION;
                    }
    #endif /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
                    break;
    #ifdef HAVE_TLSEXT
                case 'I':
                    tls_use_sni = 0;
                    break;
    #endif
    #endif /* USE_SSL */
            }
        }
    
        if (opt->ind != argc - 1) {
            fprintf(stderr, "%s: wrong number of arguments\n", argv[0]);
            usage(argv[0]);
        }
    
        if (method == NO_METH) {
            method = GET;
        }
    
        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
    #if OPENSSL_VERSION_NUMBER < 0x10100000L
        CRYPTO_malloc_init();
    #endif
    #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 OPENSSL_VERSION_NUMBER >= 0x10100000L
        SSL_CTX_set_max_proto_version(ssl_ctx, max_prot);
        SSL_CTX_set_min_proto_version(ssl_ctx, min_prot);
    #endif
    #ifdef SSL_MODE_RELEASE_BUFFERS
        /* Keep memory usage as low as possible */
        SSL_CTX_set_mode (ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
    #endif
    
        if (ssl_cipher != NULL) {
            int ok;
    #if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(TLS1_3_VERSION)
            if (min_prot >= TLS1_3_VERSION)
                ok = SSL_CTX_set_ciphersuites(ssl_ctx, ssl_cipher);
            else
    #endif
            ok = SSL_CTX_set_cipher_list(ssl_ctx, ssl_cipher);
            if (!ok) {
                BIO_printf(bio_err, "error setting ciphersuite list [%s]\n",
                           ssl_cipher);
                ERR_print_errors(bio_err);
                exit(1);
            }
        }
    
        if (verbosity >= 3) {
            SSL_CTX_set_info_callback(ssl_ctx, ssl_state_cb);
        }
        if (ssl_cert != NULL) {
            if (SSL_CTX_use_certificate_chain_file(ssl_ctx, ssl_cert) <= 0) {
                BIO_printf(bio_err, "unable to get certificate from '%s'\n",
                		ssl_cert);
                ERR_print_errors(bio_err);
                exit(1);
            }
            if (SSL_CTX_use_PrivateKey_file(ssl_ctx, ssl_cert, SSL_FILETYPE_PEM) <= 0) {
                BIO_printf(bio_err, "unable to get private key from '%s'\n",
                    ssl_cert);
                ERR_print_errors(bio_err);
                exit(1);
            }
            if (!SSL_CTX_check_private_key(ssl_ctx)) {
                BIO_printf(bio_err,
                           "private key does not match the certificate public key in %s\n", ssl_cert);
                exit(1);
            }
        }
    
    #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;
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htpasswd.c���������������������������������������������������������������������0000664�0001751�0001751�00000041727�14571614732�016364� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "passwd_common.h"
    #include "apr_signal.h"
    #include "apr_getopt.h"
    
    #if APR_HAVE_STDIO_H
    #include <stdio.h>
    #endif
    
    #include "apr_md5.h"
    #include "apr_sha1.h"
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_STRING_H
    #include <string.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    #ifdef WIN32
    #include <conio.h>
    #define unlink _unlink
    #endif
    
    #define APHTP_NEWFILE        1
    #define APHTP_NOFILE         2
    #define APHTP_DELUSER        4
    #define APHTP_VERIFY         8
    
    apr_file_t *ftemp = NULL;
    
    static int mkrecord(struct passwd_ctx *ctx, char *user)
    {
        char hash_str[MAX_STRING_LEN];
        int ret;
    
        ctx->out = hash_str;
        ctx->out_len = sizeof(hash_str);
    
        ret = mkhash(ctx);
        if (ret) {
            ctx->out = NULL;
            ctx->out_len = 0;
            return ret;
        }
    
        ctx->out = apr_pstrcat(ctx->pool, user, ":", hash_str, NL, NULL);
        ctx->out_len = strlen(ctx->out);
        if (ctx->out_len >= MAX_STRING_LEN) {
            ctx->errstr = "resultant record too long";
            return ERR_OVERFLOW;
        }
        return 0;
    }
    
    static void usage(void)
    {
        apr_file_printf(errfile, "Usage:" NL
            "\thtpasswd [-cimB25dpsDv] [-C cost] [-r rounds] passwordfile username" NL
            "\thtpasswd -b[cmB25dpsDv] [-C cost] [-r rounds] passwordfile username password" NL
            NL
            "\thtpasswd -n[imB25dps] [-C cost] [-r rounds] username" NL
            "\thtpasswd -nb[mB25dps] [-C cost] [-r rounds] username password" NL
            " -c  Create a new file." NL
            " -n  Don't update file; display results on stdout." NL
            " -b  Use the password from the command line rather than prompting "
                "for it." NL
            " -i  Read password from stdin without verification (for script usage)." NL
            " -m  Force MD5 hashing of the password (default)." NL
            " -2  Force SHA-256 hashing of the password (secure)." NL
            " -5  Force SHA-512 hashing of the password (secure)." NL
            " -B  Force bcrypt hashing of the password (very secure)." NL
            " -C  Set the computing time used for the bcrypt algorithm" NL
            "     (higher is more secure but slower, default: %d, valid: 4 to 17)." NL
            " -r  Set the number of rounds used for the SHA-256, SHA-512 algorithms" NL
            "     (higher is more secure but slower, default: 5000)." NL
            " -d  Force CRYPT hashing of the password (8 chars max, insecure)." NL
            " -s  Force SHA-1 hashing of the password (insecure)." NL
            " -p  Do not hash the password (plaintext, insecure)." NL
            " -D  Delete the specified user." NL
            " -v  Verify password for the specified user." NL
            "On other systems than Windows and NetWare the '-p' flag will "
                "probably not work." NL
            "The SHA-1 algorithm does not use a salt and is less secure than the "
                "MD5 algorithm." NL,
            BCRYPT_DEFAULT_COST
        );
        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(int argc, const char *const argv[],
                           struct passwd_ctx *ctx, unsigned *mask, char **user,
                           char **pwfilename)
    {
        const char *arg;
        int args_left = 2;
        int i, ret;
        apr_getopt_t *state;
        apr_status_t rv;
        char opt;
        const char *opt_arg;
        apr_pool_t *pool = ctx->pool;
    
        rv = apr_getopt_init(&state, pool, argc, argv);
        if (rv != APR_SUCCESS)
            exit(ERR_SYNTAX);
    
        while ((rv = apr_getopt(state, "cnmspdBbDi25C:r:v", &opt, &opt_arg)) == APR_SUCCESS) {
            switch (opt) {
            case 'c':
                *mask |= APHTP_NEWFILE;
                break;
            case 'n':
                args_left--;
                *mask |= APHTP_NOFILE;
                break;
            case 'D':
                *mask |= APHTP_DELUSER;
                break;
            case 'v':
                *mask |= APHTP_VERIFY;
                break;
            default:
                ret = parse_common_options(ctx, opt, opt_arg);
                if (ret) {
                    apr_file_printf(errfile, "%s: %s" NL, argv[0], ctx->errstr);
                    exit(ret);
                }
            }
        }
        if (ctx->passwd_src == PW_ARG)
            args_left++;
        if (rv != APR_EOF)
            usage();
    
        if ((*mask) & (*mask - 1)) {
            /* not a power of two, i.e. more than one flag specified */
            apr_file_printf(errfile, "%s: only one of -c -n -v -D may be specified" NL,
                argv[0]);
            exit(ERR_SYNTAX);
        }
        if ((*mask & APHTP_VERIFY) && ctx->passwd_src == PW_PROMPT)
            ctx->passwd_src = PW_PROMPT_VERIFY;
    
        /*
         * Make sure we still have exactly the right number of arguments left
         * (the filename, the username, and possibly the password if -b was
         * specified).
         */
        i = state->ind;
        if ((argc - i) != args_left) {
            usage();
        }
    
        if (!(*mask & APHTP_NOFILE)) {
            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]) > (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++]);
        if ((arg = strchr(*user, ':')) != NULL) {
            apr_file_printf(errfile, "%s: username contains illegal "
                            "character '%c'" NL, argv[0], *arg);
            exit(ERR_BADUSER);
        }
        if (ctx->passwd_src == PW_ARG) {
            if (strlen(argv[i]) > (MAX_STRING_LEN - 1)) {
                apr_file_printf(errfile, "%s: password too long (> %d)" NL,
                    argv[0], MAX_STRING_LEN);
                exit(ERR_OVERFLOW);
            }
            ctx->passwd = apr_pstrdup(pool, argv[i]);
        }
    }
    
    static int verify(struct passwd_ctx *ctx, const char *hash)
    {
        apr_status_t rv;
        int ret;
    
        if (ctx->passwd == NULL && (ret = get_password(ctx)) != 0)
           return ret;
        rv = apr_password_validate(ctx->passwd, hash);
        if (rv == APR_SUCCESS)
            return 0;
        if (APR_STATUS_IS_EMISMATCH(rv)) {
            ctx->errstr = "password verification failed";
            return ERR_PWMISMATCH;
        }
        ctx->errstr = apr_psprintf(ctx->pool, "Could not verify password: %pm",
                                   &rv);
        return ERR_GENERAL;
    }
    
    /*
     * 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 line[MAX_STRING_LEN];
        char *pwfilename = NULL;
        char *user = NULL;
        char tn[] = "htpasswd.tmp.XXXXXX";
        char *dirname;
        char *scratch, cp[MAX_STRING_LEN];
        int found = 0;
        int i;
        unsigned mask = 0;
        apr_pool_t *pool;
        int existing_file = 0;
        struct passwd_ctx ctx = { 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_pool_abort_set(abort_on_oom, pool);
        apr_file_open_stderr(&errfile, pool);
        ctx.pool = pool;
        ctx.alg = ALG_APMD5;
    
    #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(argc, argv, &ctx, &mask, &user, &pwfilename);
    
        /*
         * Only do the file checks if we're supposed to frob it.
         */
        if (!(mask & APHTP_NOFILE)) {
            existing_file = exists(pwfilename, pool);
            if (existing_file && (mask & APHTP_VERIFY) == 0) {
                /*
                 * Check that this existing file is readable and writable.
                 */
                if (!accessible(pool, pwfilename, APR_FOPEN_READ|APR_FOPEN_WRITE)) {
                    apr_file_printf(errfile, "%s: cannot open file %s for "
                                    "read/write access" NL, argv[0], pwfilename);
                    exit(ERR_FILEPERM);
                }
            }
            else if (existing_file && (mask & APHTP_VERIFY) != 0) {
                /*
                 * Check that this existing file is readable.
                 */
                if (!accessible(pool, pwfilename, APR_FOPEN_READ)) {
                    apr_file_printf(errfile, "%s: cannot open file %s for "
                                    "read access" NL, argv[0], pwfilename);
                    exit(ERR_FILEPERM);
                }
            }
            else {
                /*
                 * Error out if -c was omitted for this non-existent 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_FOPEN_WRITE|APR_FOPEN_CREATE)) {
                    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|APHTP_VERIFY)) == 0) {
            i = mkrecord(&ctx, user);
            if (i != 0) {
                apr_file_printf(errfile, "%s: %s" NL, argv[0], ctx.errstr);
                exit(i);
            }
            if (mask & APHTP_NOFILE) {
                printf("%s" NL, ctx.out);
                exit(0);
            }
        }
    
        if ((mask & APHTP_VERIFY) == 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 {
                    /* We found the user we were looking for */
                    found++;
                    if ((mask & APHTP_DELUSER)) {
                        /* Delete entry from the file */
                        apr_file_printf(errfile, "Deleting ");
                    }
                    else if ((mask & APHTP_VERIFY)) {
                        /* Verify */
                        char *hash = colon + 1;
                        size_t len;
    
                        len = strcspn(hash, "\r\n");
                        if (len == 0) {
                            apr_file_printf(errfile, "Empty hash for user %s" NL,
                                            user);
                            exit(ERR_INVALID);
                        }
                        hash[len] = '\0';
    
                        i = verify(&ctx, hash);
                        if (i != 0) {
                            apr_file_printf(errfile, "%s" NL, ctx.errstr);
                            exit(i);
                        }
                    }
                    else {
                        /* Update entry */
                        apr_file_printf(errfile, "Updating ");
                        putline(ftemp, ctx.out);
                    }
                }
            }
            apr_file_close(fpw);
        }
        if (!found) {
            if (mask & APHTP_DELUSER) {
                apr_file_printf(errfile, "User %s not found" NL, user);
                exit(0);
            }
            else if (mask & APHTP_VERIFY) {
                apr_file_printf(errfile, "User %s not found" NL, user);
                exit(ERR_BADUSER);
            }
            else {
                apr_file_printf(errfile, "Adding ");
                putline(ftemp, ctx.out);
            }
        }
        if (mask & APHTP_VERIFY) {
            apr_file_printf(errfile, "Password for user %s correct." 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_OS_DEFAULT, 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;
    }
    �����������������������������������������httpd-2.4.64/support/NWGNUhtdbm���������������������������������������������������������������������0000664�0001751�0001751�00000010466�12061606345�016210� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	=
    
    #
    # 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		= 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 \
    	$(OBJDIR)/passwd_common.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 = \
       	$(PRELUDE) \
    	$(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 = \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/config.m4����������������������������������������������������������������������0000664�0001751�0001751�00000011222�11547410541�016045� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������htpasswd_LTFLAGS=""
    htdigest_LTFLAGS=""
    rotatelogs_LTFLAGS=""
    logresolve_LTFLAGS=""
    htdbm_LTFLAGS=""
    ab_LTFLAGS=""
    checkgid_LTFLAGS=""
    htcacheclean_LTFLAGS=""
    httxt2dbm_LTFLAGS=""
    fcgistarter_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])
      APR_ADDTO(htcacheclean_LTFLAGS, [-static])
      APR_ADDTO(httxt2dbm_LTFLAGS, [-static])
      APR_ADDTO(fcgistarter_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)
    
    AC_ARG_ENABLE(static-htcacheclean,APACHE_HELP_STRING(--enable-static-htcacheclean,Build a statically linked version of htcacheclean),[
    if test "$enableval" = "yes" ; then
      APR_ADDTO(htcacheclean_LTFLAGS, [-static])
    else
      APR_REMOVEFROM(htcacheclean_LTFLAGS, [-static])
    fi
    ])
    APACHE_SUBST(htcacheclean_LTFLAGS)
    
    AC_ARG_ENABLE(static-httxt2dbm,APACHE_HELP_STRING(--enable-static-httxt2dbm,Build a statically linked version of httxt2dbm),[
    if test "$enableval" = "yes" ; then
      APR_ADDTO(httxt2dbm_LTFLAGS, [-static])
    else
      APR_REMOVEFROM(httxt2dbm, [-static])
    fi
    ])
    APACHE_SUBST(httxt2dbm_LTFLAGS)
    
    AC_ARG_ENABLE(static-fcgistarter,APACHE_HELP_STRING(--enable-static-fcgistarter,Build a statically linked version of fcgistarter),[
    if test "$enableval" = "yes" ; then
      APR_ADDTO(fcgistarter_LTFLAGS, [-static])
    else
      APR_REMOVEFROM(fcgistarter, [-static])
    fi
    ])
    APACHE_SUBST(fcgistarter_LTFLAGS)
    
    # Configure or check which of the non-portable support programs can be enabled.
    
    NONPORTABLE_SUPPORT=""
    case $host in
        *mingw*)
            ;;
        *)
            NONPORTABLE_SUPPORT="checkgid fcgistarter"
            ;;
    esac
    APACHE_SUBST(NONPORTABLE_SUPPORT)
    
    # Configure the ulimit -n command used by apachectl.
    
    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 >/dev/null 2>&1; then
                APACHECTL_ULIMIT="ulimit -S -n \`ulimit -H -n\`"
            else
                APACHECTL_ULIMIT=""
            fi
            ;;
    esac
    APACHE_SUBST(APACHECTL_ULIMIT)
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htpasswd.dsp�������������������������������������������������������������������0000664�0001751�0001751�00000010430�12061606345�016704� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/htpasswd.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htpasswd.exe" /d LONG_NAME="Apache htpasswd command line utility"
    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 shell32.lib rpcrt4.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib rpcrt4.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\htpasswd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/htpasswd.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htpasswd.exe" /d LONG_NAME="Apache htpasswd command line utility"
    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 shell32.lib rpcrt4.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib rpcrt4.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\htpasswd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "htpasswd - Win32 Release"
    # Name "htpasswd - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\htpasswd.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\passwd_common.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUhtdigest������������������������������������������������������������������0000664�0001751�0001751�00000010447�11540546347�016732� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	=
    
    #
    # 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		= 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 = \
       	$(PRELUDE) \
    	$(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 = \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/suexec.c�����������������������������������������������������������������������0000664�0001751�0001751�00000046045�14300512413�016000� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <sys/param.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <string.h>
    #include <time.h>
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    
    #include <stdio.h>
    #include <stdarg.h>
    #include <stdlib.h>
    #if APR_HAVE_FCNTL_H
    #include <fcntl.h>
    #endif
    
    #ifdef HAVE_PWD_H
    #include <pwd.h>
    #endif
    
    #ifdef HAVE_GRP_H
    #include <grp.h>
    #endif
    
    #ifdef AP_LOG_SYSLOG
    #include <syslog.h>
    #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;
    
    #ifdef AP_LOG_SYSLOG
    /* Syslog support. */
    #if !defined(AP_LOG_FACILITY) && defined(LOG_AUTHPRIV)
    #define AP_LOG_FACILITY LOG_AUTHPRIV
    #elif !defined(AP_LOG_FACILITY)
    #define AP_LOG_FACILITY LOG_AUTH
    #endif
    
    static int log_open;
    #else
    /* Non-syslog support. */
    static FILE *log = NULL;
    #endif
    
    static const char *const safe_env_lst[] =
    {
        /* variable name starts with */
        "HTTP_",
        "SSL_",
    
        /* variable name is */
        "AUTH_TYPE=",
        "CONTENT_LENGTH=",
        "CONTENT_TYPE=",
        "CONTEXT_DOCUMENT_ROOT=",
        "CONTEXT_PREFIX=",
        "DATE_GMT=",
        "DATE_LOCAL=",
        "DOCUMENT_ARGS=",
        "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_ERROR_NOTES=",
        "REDIRECT_HANDLER=",
        "REDIRECT_QUERY_STRING=",
        "REDIRECT_REMOTE_USER=",
        "REDIRECT_SCRIPT_FILENAME=",
        "REDIRECT_STATUS=",
        "REDIRECT_URL=",
        "REQUEST_METHOD=",
        "REQUEST_SCHEME=",
        "REQUEST_URI=",
        "SCRIPT_FILENAME=",
        "SCRIPT_NAME=",
        "SCRIPT_URI=",
        "SCRIPT_URL=",
        "SERVER_ADDR=",
        "SERVER_ADMIN=",
        "SERVER_NAME=",
        "SERVER_PORT=",
        "SERVER_PROTOCOL=",
        "SERVER_SIGNATURE=",
        "SERVER_SOFTWARE=",
        "UNIQUE_ID=",
        "USER_NAME=",
        "TZ=",
        NULL
    };
    
    static void log_err(const char *fmt,...) 
        __attribute__((format(printf,1,2)));
    static void log_no_err(const char *fmt,...)  
        __attribute__((format(printf,1,2)));
    static void err_output(int is_error, const char *fmt, va_list ap) 
        __attribute__((format(printf,2,0)));
    
    static void err_output(int is_error, const char *fmt, va_list ap)
    {
    #if defined(AP_LOG_SYSLOG)
        if (!log_open) {
            openlog("suexec", LOG_PID, AP_LOG_FACILITY);
            log_open = 1;
        }
    
        vsyslog(is_error ? LOG_ERR : LOG_INFO, fmt, ap);
    #elif defined(AP_LOG_EXEC)
        time_t timevar;
        struct tm *lt;
    
        if (!log) {
    #if defined(_LARGEFILE64_SOURCE) && HAVE_FOPEN64
            if ((log = fopen64(AP_LOG_EXEC, "a")) == NULL) {
    #else
            if ((log = fopen(AP_LOG_EXEC, "a")) == NULL) {
    #endif
                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 **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(123);
        }
    
        cleanenv[cidx] = strdup("PATH=" AP_SAFE_PATH);
        if (cleanenv[cidx] == NULL) {
            log_err("failed to malloc memory for environment\n");
            exit(124);
        }
        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 *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();
    
        /*
         * 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: (%lu)\n", (unsigned long)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
    #if defined(AP_LOG_SYSLOG)
            fprintf(stderr, " -D AP_LOG_SYSLOG\n");
    #elif defined(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);
            }
        }
        else {
            if ((gr = getgrgid(atoi(target_gname))) == NULL) {
                log_err("invalid target group id: (%s)\n", target_gname);
                exit(106);
            }
        }
        gid = gr->gr_gid;
        if ((actual_gname = strdup(gr->gr_name)) == NULL) {
            log_err("failed to alloc memory\n");
            exit(125);
        }
    
    #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);
        if (actual_uname == NULL || target_homedir == NULL) {
            log_err("failed to alloc memory\n");
            exit(126);
        }
    
        /*
         * 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 (%lu/%s)\n", (unsigned long)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 (%lu/%s)\n", (unsigned long)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/initgroups (%lu: %s): %s\n",
                    (unsigned long)gid, cmd, strerror(errno));
            exit(109);
        }
    
        /*
         * setuid() to the target user.  Error out on fail.
         */
        if ((setuid(uid)) != 0) {
            log_err("failed to setuid (%lu: %s): %s\n",
                    (unsigned long)uid, cmd, strerror(errno));
            exit(110);
        }
    
        /*
         * Get the current working directory, as well as the proper
         * document root (dependent 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 (%lu/%lu) mismatch "
                    "with directory (%lu/%lu) or program (%lu/%lu)\n",
                    (unsigned long)uid, (unsigned long)gid,
                    (unsigned long)dir_info.st_uid, (unsigned long)dir_info.st_gid,
                    (unsigned long)prg_info.st_uid, (unsigned long)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. */
    #ifdef AP_LOG_SYSLOG
        if (log_open) {
            closelog();
            log_open = 0;
        }
    #else
        if (log != NULL) {
    #if APR_HAVE_FCNTL_H
            /*
             * ask fcntl(2) to set the FD_CLOEXEC flag on the log file,
             * so it'll be automagically closed if the exec() call succeeds.
             */
            fflush(log);
            setbuf(log, NULL);
            if ((fcntl(fileno(log), F_SETFD, FD_CLOEXEC) == -1)) {
                log_err("error: can't set close-on-exec flag");
                exit(122);
            }
    #else
            /*
             * In this case, exec() errors won't be logged because we have already
             * dropped privileges and won't be able to reopen the log file.
             */
            fclose(log);
            log = NULL;
    #endif
        }
    #endif
    
        /*
         * 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);
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/httxt2dbm.c��������������������������������������������������������������������0000664�0001751�0001751�00000017656�12132772630�016444� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * httxt2dbm.c: simple program for converting RewriteMap text files to DBM
     * Rewrite databases for the Apache HTTP server
     *
     */
    
    #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_getopt.h"
    #include "apu.h"
    #include "apr_dbm.h"
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h> /* for atexit() */
    #endif
    
    static const char *input;
    static const char *output;
    static const char *format;
    static const char *shortname;
    static apr_file_t *errfile;
    static int verbose;
    
    /* From mod_rewrite.c */
    #ifndef REWRITE_MAX_TXT_MAP_LINE
    #define REWRITE_MAX_TXT_MAP_LINE 1024
    #endif
    
    #define NL APR_EOL_STR
    
    #define AVAIL "available"
    #define UNAVAIL "unavailable"
    
    static void usage(void)
    {
        const char *have_sdbm;
        const char *have_gdbm;
        const char *have_ndbm;
        const char *have_db;
    
    #if APU_HAVE_SDBM
        have_sdbm = AVAIL;
    #else
        have_sdbm = UNAVAIL;
    #endif
    #if APU_HAVE_GDBM
        have_gdbm = AVAIL;
    #else
        have_gdbm = UNAVAIL;
    #endif
    #if APU_HAVE_NDBM
        have_ndbm = AVAIL;
    #else
        have_ndbm = UNAVAIL;
    #endif
    #if APU_HAVE_DB
        have_db = AVAIL;
    #else
        have_db = UNAVAIL;
    #endif
    
        apr_file_printf(errfile,
        "%s -- Program to Create DBM Files for use by RewriteMap" NL
        "Usage: %s [-v] [-f format] -i SOURCE_TXT -o OUTPUT_DBM" NL
        NL
        "Options: " NL
        " -v    More verbose output" NL
        NL
        " -i    Source Text File. If '-', use stdin." NL
        NL
        " -o    Output DBM." NL
        NL
        " -f    DBM Format.  If not specified, will use the APR Default." NL
        "           GDBM for GDBM files (%s)" NL
        "           SDBM for SDBM files (%s)" NL
        "           DB   for berkeley DB files (%s)" NL
        "           NDBM for NDBM files (%s)" NL
        "           default for the default DBM type" NL
        NL,
        shortname,
        shortname,
        have_gdbm,
        have_sdbm,
        have_db,
        have_ndbm);
    }
    
    
    static apr_status_t to_dbm(apr_dbm_t *dbm, apr_file_t *fp, apr_pool_t *pool)
    {
        apr_status_t rv = APR_SUCCESS;
        char line[REWRITE_MAX_TXT_MAP_LINE + 1]; /* +1 for \0 */
        apr_datum_t dbmkey;
        apr_datum_t dbmval;
        apr_pool_t* p;
    
        apr_pool_create(&p, pool);
    
        while (apr_file_gets(line, sizeof(line), fp) == APR_SUCCESS) {
            char *c, *value;
    
            if (*line == '#' || apr_isspace(*line)) {
                continue;
            }
    
            c = line;
    
            while (*c && !apr_isspace(*c)) {
                ++c;
            }
    
            if (!*c) {
                /* no value. solid line of data. */
                continue;
            }
    
            dbmkey.dptr = apr_pstrmemdup(p, line,  c - line);
            dbmkey.dsize = (c - line);
    
            while (apr_isspace(*c)) {
                ++c;
            }
    
            if (!*c) {
                apr_pool_clear(p);
                continue;
            }
    
            value = c;
    
            while (*c && !apr_isspace(*c)) {
                ++c;
            }
    
            dbmval.dptr = apr_pstrmemdup(p, value,  c - value);
            dbmval.dsize = (c - value);
    
            if (verbose) {
                apr_file_printf(errfile, "    '%s' -> '%s'" NL,
                                dbmkey.dptr, dbmval.dptr);
            }
    
            rv = apr_dbm_store(dbm, dbmkey, dbmval);
    
            apr_pool_clear(p);
    
            if (rv != APR_SUCCESS) {
                break;
            }
        }
    
        return rv;
    }
    
    int main(int argc, const char *const argv[])
    {
        apr_pool_t *pool;
        apr_status_t rv = APR_SUCCESS;
        apr_getopt_t *opt;
        const char *opt_arg;
        char ch;
        apr_file_t *infile;
        apr_dbm_t *outdbm;
    
        apr_app_initialize(&argc, &argv, NULL);
        atexit(apr_terminate);
    
        verbose = 0;
        format = NULL;
        input = NULL;
        output = NULL;
    
        apr_pool_create(&pool, NULL);
    
        if (argc) {
            shortname = apr_filepath_name_get(argv[0]);
        }
        else {
            shortname = "httxt2dbm";
        }
    
        apr_file_open_stderr(&errfile, pool);
        rv = apr_getopt_init(&opt, pool, argc, argv);
    
        if (rv != APR_SUCCESS) {
            apr_file_printf(errfile, "Error: apr_getopt_init failed." NL NL);
            return 1;
        }
    
        if (argc <= 1) {
            usage();
            return 1;
        }
    
        while ((rv = apr_getopt(opt, "vf::i::o::", &ch, &opt_arg)) == APR_SUCCESS) {
            switch (ch) {
            case 'v':
                if (verbose) {
                    apr_file_printf(errfile, "Error: -v can only be passed once" NL NL);
                    usage();
                    return 1;
                }
                verbose = 1;
                break;
            case 'f':
                if (format) {
                    apr_file_printf(errfile, "Error: -f can only be passed once" NL NL);
                    usage();
                    return 1;
                }
                format = apr_pstrdup(pool, opt_arg);
                break;
            case 'i':
                if (input) {
                    apr_file_printf(errfile, "Error: -i can only be passed once" NL NL);
                    usage();
                    return 1;
                }
                input = apr_pstrdup(pool, opt_arg);
                break;
            case 'o':
                if (output) {
                    apr_file_printf(errfile, "Error: -o can only be passed once" NL NL);
                    usage();
                    return 1;
                }
                output = apr_pstrdup(pool, opt_arg);
                break;
            }
        }
    
        if (rv != APR_EOF) {
            apr_file_printf(errfile, "Error: Parsing Arguments Failed" NL NL);
            usage();
            return 1;
        }
    
        if (!input) {
            apr_file_printf(errfile, "Error: No input file specified." NL NL);
            usage();
            return 1;
        }
    
        if (!output) {
            apr_file_printf(errfile, "Error: No output DBM specified." NL NL);
            usage();
            return 1;
        }
    
        if (!format) {
            format = "default";
        }
    
        if (verbose) {
            apr_file_printf(errfile, "DBM Format: %s" NL, format);
        }
    
        if (!strcmp(input, "-")) {
            rv = apr_file_open_stdin(&infile, pool);
        }
        else {
            rv = apr_file_open(&infile, input, APR_READ|APR_BUFFERED,
                               APR_OS_DEFAULT, pool);
        }
    
        if (rv != APR_SUCCESS) {
            apr_file_printf(errfile,
                            "Error: Cannot open input file '%s': (%d) %pm" NL NL,
                             input, rv, &rv);
            return 1;
        }
    
        if (verbose) {
            apr_file_printf(errfile, "Input File: %s" NL, input);
        }
    
        rv = apr_dbm_open_ex(&outdbm, format, output, APR_DBM_RWCREATE,
                        APR_OS_DEFAULT, pool);
    
        if (APR_STATUS_IS_ENOTIMPL(rv)) {
            apr_file_printf(errfile,
                            "Error: The requested DBM Format '%s' is not available." NL NL,
                             format);
            return 1;
        }
    
        if (rv != APR_SUCCESS) {
            apr_file_printf(errfile,
                            "Error: Cannot open output DBM '%s': (%d) %pm" NL NL,
                             output, rv, &rv);
            return 1;
        }
    
        if (verbose) {
            apr_file_printf(errfile, "DBM File: %s" NL, output);
        }
    
        rv = to_dbm(outdbm, infile, pool);
    
        if (rv != APR_SUCCESS) {
            apr_file_printf(errfile,
                            "Error: Converting to DBM: (%d) %pm" NL NL,
                             rv, &rv);
            return 1;
        }
    
        apr_dbm_close(outdbm);
    
        if (verbose) {
            apr_file_printf(errfile, "Conversion Complete." NL);
        }
    
        return 0;
    }
    
    ����������������������������������������������������������������������������������httpd-2.4.64/support/htdbm.dsp����������������������������������������������������������������������0000664�0001751�0001751�00000010326�12061606345�016151� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/htdbm.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htdbm.exe" /d LONG_NAME="Apache htdbm command line utility"
    BSC32=bscmake.exe
    # ADD BASE BSC32 /nologo
    # ADD BSC32 /nologo
    LINK32=link.exe
    # ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib rpcrt4.lib ws2_32.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\htdbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/htdbm.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htdbm.exe" /d LONG_NAME="Apache htdbm command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\htdbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "htdbm - Win32 Release"
    # Name "htdbm - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\htdbm.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\passwd_common.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/suexec.h�����������������������������������������������������������������������0000664�0001751�0001751�00000007214�11637105701�016010� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  suexec.h
     * @brief 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 */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUhtcacheclean��������������������������������������������������������������0000664�0001751�0001751�00000010453�11540546347�017516� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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	+= \
    			$(STDMOD)/cache \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(AP_WORK)/include \
    			$(APR)/misc/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	= 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	=
    
    #
    # 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)/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 = \
    	$(PRELUDE) \
    	$(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 = \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/logresolve.dsp�����������������������������������������������������������������0000664�0001751�0001751�00000010376�12520036522�017233� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/logresolve.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="logresolve.exe" /d LONG_NAME="Apache logresolve command line pipe"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\logresolve.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/logresolve.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="logresolve.exe" /d LONG_NAME="Apache logresolve command line pipe"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\logresolve.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "logresolve - Win32 Release"
    # Name "logresolve - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\logresolve.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/Makefile.in��������������������������������������������������������������������0000664�0001751�0001751�00000006141�13237272472�016416� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������DISTCLEAN_TARGETS = apxs apachectl dbmmanage log_server_status \
    	logresolve.pl phf_abuse_log.cgi split-logfile envvars-std
    
    CLEAN_TARGETS = suexec
    
    bin_PROGRAMS = htpasswd htdigest htdbm ab logresolve httxt2dbm
    sbin_PROGRAMS = htcacheclean rotatelogs $(NONPORTABLE_SUPPORT)
    TARGETS  = $(bin_PROGRAMS) $(sbin_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 dbmmanage; do \
    	    if test -f "$(builddir)/$$i"; then \
    	        cp -p $$i $(DESTDIR)$(bindir); \
    	        chmod 755 $(DESTDIR)$(bindir)/$$i; \
    	    fi ; \
    	done
    	@for i in apachectl; 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.lo: passwd_common.h
    passwd_common.lo: passwd_common.h
    htpasswd_OBJECTS = htpasswd.lo passwd_common.lo
    htpasswd: $(htpasswd_OBJECTS)
    	$(LINK) $(htpasswd_LTFLAGS) $(htpasswd_OBJECTS) $(PROGRAM_LDADD) $(CRYPT_LIBS)
    
    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.lo: passwd_common.h
    htdbm_OBJECTS = htdbm.lo passwd_common.lo
    htdbm: $(htdbm_OBJECTS)
    	$(LINK) $(htdbm_LTFLAGS) $(htdbm_OBJECTS) $(PROGRAM_LDADD) $(CRYPT_LIBS)
    
    ab_OBJECTS = ab.lo
    ab_LDADD = $(PROGRAM_LDADD) $(MATH_LIBS) $(ab_LIBS)
    ab.lo: ab.c
    	$(LIBTOOL) --mode=compile $(CC) $(ab_CFLAGS) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
    	    $(ALL_INCLUDES) $(PICFLAGS) $(LTCFLAGS) -c $< && touch $@
    ab: $(ab_OBJECTS)
    	$(LIBTOOL) --mode=link $(CC) $(ALL_CFLAGS) $(PILDFLAGS) \
    	    $(LT_LDFLAGS) $(ALL_LDFLAGS) -o $@ $(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)
    
    httxt2dbm_OBJECTS = httxt2dbm.lo
    httxt2dbm: $(httxt2dbm_OBJECTS)
    	$(LINK) $(httxt2dbm_LTFLAGS) $(httxt2dbm_OBJECTS) $(PROGRAM_LDADD)
    
    fcgistarter_OBJECTS = fcgistarter.lo
    fcgistarter: $(fcgistarter_OBJECTS)
    	$(LINK) $(fcgistarter_LTFLAGS) $(fcgistarter_OBJECTS) $(PROGRAM_LDADD)
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/logresolve.c�������������������������������������������������������������������0000664�0001751�0001751�00000024370�13241033601�016662� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 2.0
     *
     * Tom Rathborne - tomr uunet.ca - http://www.uunet.ca/~tomr/
     * UUNET Canada, April 16, 1995
     *
     * Rewritten by David Robinson. (drtr ast.cam.ac.uk)
     * Rewritten again, and ported to APR by Colm MacCarthaigh
     *
     * 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:             (For historical interest)
     *
     * 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.h"
    #include "apr_lib.h"
    #include "apr_hash.h"
    #include "apr_getopt.h"
    #include "apr_strings.h"
    #include "apr_file_io.h"
    #include "apr_network_io.h"
    
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    
    #define READ_BUF_SIZE  128*1024
    #define WRITE_BUF_SIZE 128*1024
    #define LINE_BUF_SIZE  128*1024
    
    static apr_file_t *errfile;
    static const char *shortname = "logresolve";
    static apr_hash_t *cache;
    
    /* Statistics */
    static int cachehits = 0;
    static int cachesize = 0;
    static int entries = 0;
    static int resolves = 0;
    static int withname = 0;
    static int doublefailed = 0;
    static int noreverse = 0;
    
    /*
     * prints various statistics to output
     */
    #define NL APR_EOL_STR
    static void print_statistics (apr_file_t *output)
    {
        apr_file_printf(output, "logresolve Statistics:" NL);
        apr_file_printf(output, "Entries: %d" NL, entries);
        apr_file_printf(output, "    With name   : %d" NL, withname);
        apr_file_printf(output, "    Resolves    : %d" NL, resolves);
    
        if (noreverse) {
            apr_file_printf(output, "    - No reverse : %d" NL,
                            noreverse);
        }
    
        if (doublefailed) {
            apr_file_printf(output, "    - Double lookup failed : %d" NL,
                            doublefailed);
        }
    
        apr_file_printf(output, "Cache hits      : %d" NL, cachehits);
        apr_file_printf(output, "Cache size      : %d" NL, cachesize);
    }
    
    /*
     * usage info
     */
    static void usage(void)
    {
        apr_file_printf(errfile,
        "%s -- Resolve IP-addresses to hostnames in Apache log files."           NL
        "Usage: %s [-s STATFILE] [-c]"                                           NL
                                                                                 NL
        "Options:"                                                               NL
        "  -s   Record statistics to STATFILE when finished."                    NL
                                                                                 NL
        "  -c   Perform double lookups when resolving IP addresses."             NL,
        shortname, shortname);
        exit(1);
    }
    #undef NL
    
    int main(int argc, const char * const argv[])
    {
        apr_file_t * outfile;
        apr_file_t * infile;
        apr_getopt_t * o;
        apr_pool_t * pool;
        apr_pool_t *pline;
        apr_status_t status;
        const char * arg;
        char * stats = NULL;
        char * inbuffer;
        char * outbuffer;
        char * line;
        int doublelookups = 0;
    
        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_file_open_stderr(&errfile, pool);
        apr_getopt_init(&o, pool, argc, argv);
    
        while (1) {
            char opt;
            status = apr_getopt(o, "s:c", &opt, &arg);
            if (status == APR_EOF) {
                break;
            }
            else if (status != APR_SUCCESS) {
                usage();
            }
            else {
                switch (opt) {
                case 'c':
                    if (doublelookups) {
                        usage();
                    }
                    doublelookups = 1;
                    break;
                case 's':
                    if (stats) {
                        usage();
                    }
                    stats = apr_pstrdup(pool, arg);
                    break;
                } /* switch */
            } /* else */
        } /* while */
    
        apr_file_open_stdout(&outfile, pool);
        apr_file_open_stdin(&infile, pool);
    
        /* Allocate two new 10k file buffers */
        if (   (outbuffer = apr_palloc(pool, WRITE_BUF_SIZE)) == NULL
            || (inbuffer  = apr_palloc(pool, READ_BUF_SIZE))  == NULL
            || (line      = apr_palloc(pool, LINE_BUF_SIZE))  == NULL) {
            return 1;
        }
    
        /* Set the buffers */
        apr_file_buffer_set(infile, inbuffer, READ_BUF_SIZE);
        apr_file_buffer_set(outfile, outbuffer, WRITE_BUF_SIZE);
    
        cache = apr_hash_make(pool);
        if (apr_pool_create(&pline, pool) != APR_SUCCESS) {
            return 1;
        }
    
        while (apr_file_gets(line, LINE_BUF_SIZE, infile) == APR_SUCCESS) {
            char *hostname;
            char *space;
            apr_sockaddr_t *ip;
            apr_sockaddr_t *ipdouble;
            char dummy[] = " " APR_EOL_STR;
    
            if (line[0] == '\0') {
                continue;
            }
    
            /* Count our log entries */
            entries++;
    
            /* Check if this could even be an IP address */
            if (!apr_isxdigit(line[0]) && line[0] != ':') {
                withname++;
                apr_file_puts(line, outfile);
                continue;
            }
    
            /* Terminate the line at the next space */
            if ((space = strchr(line, ' ')) != NULL) {
                *space = '\0';
            }
            else {
                space = dummy;
            }
    
            /* See if we have it in our cache */
            hostname = (char *) apr_hash_get(cache, line, APR_HASH_KEY_STRING);
            if (hostname) {
                apr_file_printf(outfile, "%s %s", hostname, space + 1);
                cachehits++;
                continue;
            }
    
            /* Parse the IP address */
            status = apr_sockaddr_info_get(&ip, line, APR_UNSPEC, 0, 0, pline);
            if (status != APR_SUCCESS) {
                /* Not an IP address */
                withname++;
                *space = ' ';
                apr_file_puts(line, outfile);
                continue;
            }
    
            /* This does not make much sense, but historically "resolves" means
             * "parsed as an IP address". It does not mean we actually resolved
             * the IP address into a hostname.
             */
            resolves++;
    
            /* From here on our we cache each result, even if it was not
             * successful
             */
            cachesize++;
    
            /* Try and perform a reverse lookup */
            status = apr_getnameinfo(&hostname, ip, 0) != APR_SUCCESS;
            if (status || hostname == NULL) {
                /* Could not perform a reverse lookup */
                *space = ' ';
                apr_file_puts(line, outfile);
                noreverse++;
    
                /* Add to cache */
                *space = '\0';
                apr_hash_set(cache, line, APR_HASH_KEY_STRING,
                             apr_pstrdup(apr_hash_pool_get(cache), line));
                continue;
            }
    
            /* Perform a double lookup */
            if (doublelookups) {
                /* Do a forward lookup on our hostname, and see if that matches our
                 * original IP address.
                 */
                status = apr_sockaddr_info_get(&ipdouble, hostname, ip->family, 0,
                                               0, pline);
                if (status != APR_SUCCESS ||
                    memcmp(ipdouble->ipaddr_ptr, ip->ipaddr_ptr, ip->ipaddr_len)) {
                    /* Double-lookup failed  */
                    *space = ' ';
                    apr_file_puts(line, outfile);
                    doublefailed++;
    
                    /* Add to cache */
                    *space = '\0';
                    apr_hash_set(cache, line, APR_HASH_KEY_STRING,
                                 apr_pstrdup(apr_hash_pool_get(cache), line));
                    continue;
                }
            }
    
            /* Output the resolved name */
            apr_file_printf(outfile, "%s %s", hostname, space + 1);
    
            /* Store it in the cache */
            apr_hash_set(cache, line, APR_HASH_KEY_STRING,
                         apr_pstrdup(apr_hash_pool_get(cache), hostname));
    
            apr_pool_clear(pline);
        }
    
        /* Flush any remaining output */
        apr_file_flush(outfile);
    
        if (stats) {
            apr_file_t *statsfile;
            if (apr_file_open(&statsfile, stats,
                              APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE,
                              APR_OS_DEFAULT, pool) != APR_SUCCESS) {
                apr_file_printf(errfile, "%s: Could not open %s for writing.",
                                shortname, stats);
                return 1;
            }
            print_statistics(statsfile);
            apr_file_close(statsfile);
        }
    
        return 0;
    }
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/abs.mak������������������������������������������������������������������������0000664�0001751�0001751�00000024653�13076222603�015610� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on abs.dsp
    !IF "$(CFG)" == ""
    CFG=abs - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to abs - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "abs - Win32 Release" && "$(CFG)" != "abs - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF "$(_HAVE_OSSL110)" == "1"
    SSLCRP=libcrypto
    SSLLIB=libssl
    SSLINC=/I ../srclib/openssl/include
    SSLBIN=/libpath:../srclib/openssl
    !ELSE 
    SSLCRP=libeay32
    SSLLIB=ssleay32
    SSLINC=/I ../srclib/openssl/inc32
    SSLBIN=/libpath:../srclib/openssl/out32dll
    !ENDIF 
     
    !IF  "$(CFG)" == "abs - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "..\srclib\openssl\include\openssl\applink.c" "$(OUTDIR)\abs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "..\srclib\openssl\include\openssl\applink.c" "$(OUTDIR)\abs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ab.res"
    	-@erase "$(INTDIR)\abs.obj"
    	-@erase "$(INTDIR)\abs_src.idb"
    	-@erase "$(INTDIR)\abs_src.pdb"
    	-@erase "$(OUTDIR)\abs.exe"
    	-@erase "$(OUTDIR)\abs.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" $(SSLINC) /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\abs_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench/SSL command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\abs.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib $(SSLCRP).lib $(SSLLIB).lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\abs.pdb" /debug /out:"$(OUTDIR)\abs.exe" $(SSLBIN) /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\abs.obj" \
    	"$(INTDIR)\ab.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\abs.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\abs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\abs.exe"
       if exist .\Release\abs.exe.manifest mt.exe -manifest .\Release\abs.exe.manifest -outputresource:.\Release\abs.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "abs - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "..\srclib\openssl\include\openssl\applink.c" "$(OUTDIR)\abs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "..\srclib\openssl\include\openssl\applink.c" "$(OUTDIR)\abs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ab.res"
    	-@erase "$(INTDIR)\abs.obj"
    	-@erase "$(INTDIR)\abs_src.idb"
    	-@erase "$(INTDIR)\abs_src.pdb"
    	-@erase "$(OUTDIR)\abs.exe"
    	-@erase "$(OUTDIR)\abs.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" $(SSLINC) /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\abs_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench/SSL command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\abs.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib $(SSLCRP).lib $(SSLLIB).lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\abs.pdb" /debug /out:"$(OUTDIR)\abs.exe" $(SSLBIN) 
    LINK32_OBJS= \
    	"$(INTDIR)\abs.obj" \
    	"$(INTDIR)\ab.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\abs.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\abs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\abs.exe"
       if exist .\Debug\abs.exe.manifest mt.exe -manifest .\Debug\abs.exe.manifest -outputresource:.\Debug\abs.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("abs.dep")
    !INCLUDE "abs.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "abs.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "abs - Win32 Release" || "$(CFG)" == "abs - Win32 Debug"
    
    !IF  "$(CFG)" == "abs - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "abs - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "abs - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "abs - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=.\ab.c
    
    !IF  "$(CFG)" == "abs - Win32 Release"
    
    CPP_SWITCHES=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" $(SSLINC) /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" /Fo"$(INTDIR)\abs.obj" /Fd"$(INTDIR)\abs_src" /FD /c 
    
    "$(INTDIR)\abs.obj" : $(SOURCE) "$(INTDIR)"
    	$(CPP) @<<
      $(CPP_SWITCHES) $(SOURCE)
    <<
    
    
    !ELSEIF  "$(CFG)" == "abs - Win32 Debug"
    
    CPP_SWITCHES=/nologo /MDd /W3 /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" $(SSLINC) /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" /Fo"$(INTDIR)\abs.obj" /Fd"$(INTDIR)\abs_src" /FD /EHsc /c 
    
    "$(INTDIR)\abs.obj" : $(SOURCE) "$(INTDIR)"
    	$(CPP) @<<
      $(CPP_SWITCHES) $(SOURCE)
    <<
    
    
    !ENDIF 
    
    SOURCE=../include\ap_release.h
    
    !IF  "$(CFG)" == "abs - Win32 Release"
    
    InputPath=../include\ap_release.h
    
    "..\srclib\openssl\include\openssl\applink.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	IF EXIST ..\srclib\openssl\ms\applink.c type ..\srclib\openssl\ms\applink.c > ..\srclib\openssl\include\openssl\applink.c
    << 
    	
    
    !ELSEIF  "$(CFG)" == "abs - Win32 Debug"
    
    InputPath=../include\ap_release.h
    
    "..\srclib\openssl\include\openssl\applink.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	IF EXIST ..\srclib\openssl\ms\applink.c type ..\srclib\openssl\ms\applink.c > ..\srclib\openssl\include\openssl\applink.c
    << 
    	
    
    !ENDIF 
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "abs - Win32 Release"
    
    
    "$(INTDIR)\ab.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench/SSL command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "abs - Win32 Debug"
    
    
    "$(INTDIR)\ab.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench/SSL command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������httpd-2.4.64/support/fcgistarter.mak����������������������������������������������������������������0000664�0001751�0001751�00000020765�12701473373�017366� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on fcgistarter.dsp
    !IF "$(CFG)" == ""
    CFG=fcgistarter - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to fcgistarter - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "fcgistarter - Win32 Release" && "$(CFG)" != "fcgistarter - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 "fcgistarter.mak" CFG="fcgistarter - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "fcgistarter - Win32 Release" (based on "Win32 (x86) Console Application")
    !MESSAGE "fcgistarter - Win32 Debug" (based on "Win32 (x86) Console Application")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "fcgistarter - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\fcgistarter.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\fcgistarter.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\fcgistarter.obj"
    	-@erase "$(INTDIR)\fcgistarter.res"
    	-@erase "$(INTDIR)\fcgistarter_src.idb"
    	-@erase "$(INTDIR)\fcgistarter_src.pdb"
    	-@erase "$(OUTDIR)\fcgistarter.exe"
    	-@erase "$(OUTDIR)\fcgistarter.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\fcgistarter_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\fcgistarter.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="fcgistarter.exe" /d LONG_NAME="Apache fcgi command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\fcgistarter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\fcgistarter.pdb" /debug /out:"$(OUTDIR)\fcgistarter.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\fcgistarter.obj" \
    	"$(INTDIR)\fcgistarter.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\fcgistarter.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\fcgistarter.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\fcgistarter.exe"
       if exist .\Release\fcgistarter.exe.manifest mt.exe -manifest .\Release\fcgistarter.exe.manifest -outputresource:.\Release\fcgistarter.exe;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "fcgistarter - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\fcgistarter.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\fcgistarter.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\fcgistarter.obj"
    	-@erase "$(INTDIR)\fcgistarter.res"
    	-@erase "$(INTDIR)\fcgistarter_src.idb"
    	-@erase "$(INTDIR)\fcgistarter_src.pdb"
    	-@erase "$(OUTDIR)\fcgistarter.exe"
    	-@erase "$(OUTDIR)\fcgistarter.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\fcgistarter_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\fcgistarter.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="fcgistarter.exe" /d LONG_NAME="Apache fcgi command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\fcgistarter.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\fcgistarter.pdb" /debug /out:"$(OUTDIR)\fcgistarter.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\fcgistarter.obj" \
    	"$(INTDIR)\fcgistarter.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\fcgistarter.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\fcgistarter.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\fcgistarter.exe"
       if exist .\Debug\fcgistarter.exe.manifest mt.exe -manifest .\Debug\fcgistarter.exe.manifest -outputresource:.\Debug\fcgistarter.exe;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("fcgistarter.dep")
    !INCLUDE "fcgistarter.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "fcgistarter.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "fcgistarter - Win32 Release" || "$(CFG)" == "fcgistarter - Win32 Debug"
    
    !IF  "$(CFG)" == "fcgistarter - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "fcgistarter - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "fcgistarter - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "fcgistarter - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=.\fcgistarter.c
    
    "$(INTDIR)\fcgistarter.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "fcgistarter - Win32 Release"
    
    
    "$(INTDIR)\fcgistarter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\fcgistarter.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="fcgistarter.exe" /d LONG_NAME="Apache fcgi command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "fcgistarter - Win32 Debug"
    
    
    "$(INTDIR)\fcgistarter.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\fcgistarter.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="fcgistarter.exe" /d LONG_NAME="Apache fcgi command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �����������httpd-2.4.64/support/abs.dsp������������������������������������������������������������������������0000664�0001751�0001751�00000013263�13076222603�015621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/ab.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench/SSL command line utility"
    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 rpcrt4.lib shell32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /libpath:"../srclib/openssl/out32dll"
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /debug /libpath:"../srclib/openssl/out32dll" /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\abs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/ab.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench/SSL command line utility"
    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 rpcrt4.lib shell32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /incremental:no /debug /libpath:"../srclib/openssl/out32dll"
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /incremental:no /debug /libpath:"../srclib/openssl/out32dll"
    # Begin Special Build Tool
    TargetPath=.\Debug\abs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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=../include\ap_release.h
    
    !IF  "$(CFG)" == "abs - Win32 Release"
    
    # Begin Custom Build - Create applink.c from ms/applink.c
    InputPath=../include\ap_release.h
    
    "..\srclib\openssl\include\openssl\applink.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	IF EXIST ..\srclib\openssl\ms\applink.c type ..\srclib\openssl\ms\applink.c > ..\srclib\openssl\include\openssl\applink.c
    
    # End Custom Build
    
    !ELSEIF  "$(CFG)" == "abs - Win32 Debug"
    
    # Begin Custom Build - Create applink.c from ms/applink.c
    InputPath=../include\ap_release.h
    
    "..\srclib\openssl\include\openssl\applink.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	IF EXIST ..\srclib\openssl\ms\applink.c type ..\srclib\openssl\ms\applink.c > ..\srclib\openssl\include\openssl\applink.c
    
    # End Custom Build
    
    !ENDIF 
    
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/ab.mak�������������������������������������������������������������������������0000664�0001751�0001751�00000017561�12701473373�015433� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on ab.dsp
    !IF "$(CFG)" == ""
    CFG=ab - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to ab - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "ab - Win32 Release" && "$(CFG)" != "ab - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "ab - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\ab.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\ab.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ab.obj"
    	-@erase "$(INTDIR)\ab.res"
    	-@erase "$(INTDIR)\ab_src.idb"
    	-@erase "$(INTDIR)\ab_src.pdb"
    	-@erase "$(OUTDIR)\ab.exe"
    	-@erase "$(OUTDIR)\ab.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\ab_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\ab.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\ab.pdb" /debug /out:"$(OUTDIR)\ab.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\ab.obj" \
    	"$(INTDIR)\ab.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\ab.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\ab.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\ab.exe"
       if exist .\Release\ab.exe.manifest mt.exe -manifest .\Release\ab.exe.manifest -outputresource:.\Release\ab.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "ab - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\ab.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\ab.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ab.obj"
    	-@erase "$(INTDIR)\ab.res"
    	-@erase "$(INTDIR)\ab_src.idb"
    	-@erase "$(INTDIR)\ab_src.pdb"
    	-@erase "$(OUTDIR)\ab.exe"
    	-@erase "$(OUTDIR)\ab.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\ab_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\ab.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\ab.pdb" /debug /out:"$(OUTDIR)\ab.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\ab.obj" \
    	"$(INTDIR)\ab.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\ab.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\ab.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\ab.exe"
       if exist .\Debug\ab.exe.manifest mt.exe -manifest .\Debug\ab.exe.manifest -outputresource:.\Debug\ab.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("ab.dep")
    !INCLUDE "ab.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "ab.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "ab - Win32 Release" || "$(CFG)" == "ab - Win32 Debug"
    
    !IF  "$(CFG)" == "ab - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "ab - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "ab - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "ab - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=.\ab.c
    
    "$(INTDIR)\ab.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "ab - Win32 Release"
    
    
    "$(INTDIR)\ab.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "ab - Win32 Debug"
    
    
    "$(INTDIR)\ab.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\ab.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="ab.exe" /d LONG_NAME="ApacheBench command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUrotlogs�������������������������������������������������������������������0000664�0001751�0001751�00000010412�11540546347�016600� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	=
    
    #
    # 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		=  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 = \
       	$(PRELUDE) \
    	$(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 = \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/README�������������������������������������������������������������������������0000664�0001751�0001751�00000003453�11473704740�015232� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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.
    
    htcacheclean
        Keep the size of mod_cache_disk store within a certain limit.
    
    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.
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/checkgid.c���������������������������������������������������������������������0000664�0001751�0001751�00000005573�12757564422�016273� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 identifiers 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 <stdio.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #if HAVE_GRP_H
    #include <grp.h>
    #endif
    #if APR_HAVE_UNISTD_H
    #include <unistd.h>
    #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:
     */
    �������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htcacheclean.mak���������������������������������������������������������������0000664�0001751�0001751�00000021125�12701473373�017442� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on htcacheclean.dsp
    !IF "$(CFG)" == ""
    CFG=htcacheclean - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to htcacheclean - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "htcacheclean - Win32 Release" && "$(CFG)" != "htcacheclean - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 "htcacheclean.mak" CFG="htcacheclean - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "htcacheclean - Win32 Release" (based on "Win32 (x86) Console Application")
    !MESSAGE "htcacheclean - Win32 Debug" (based on "Win32 (x86) Console Application")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "htcacheclean - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htcacheclean.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\htcacheclean.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htcacheclean.obj"
    	-@erase "$(INTDIR)\htcacheclean.res"
    	-@erase "$(INTDIR)\htcacheclean_src.idb"
    	-@erase "$(INTDIR)\htcacheclean_src.pdb"
    	-@erase "$(OUTDIR)\htcacheclean.exe"
    	-@erase "$(OUTDIR)\htcacheclean.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htcacheclean_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htcacheclean.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htcacheclean.exe" /d LONG_NAME="Apache htcacheclean command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htcacheclean.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htcacheclean.pdb" /debug /out:"$(OUTDIR)\htcacheclean.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\htcacheclean.obj" \
    	"$(INTDIR)\htcacheclean.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\htcacheclean.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\htcacheclean.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htcacheclean.exe"
       if exist .\Release\htcacheclean.exe.manifest mt.exe -manifest .\Release\htcacheclean.exe.manifest -outputresource:.\Release\htcacheclean.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "htcacheclean - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htcacheclean.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\htcacheclean.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htcacheclean.obj"
    	-@erase "$(INTDIR)\htcacheclean.res"
    	-@erase "$(INTDIR)\htcacheclean_src.idb"
    	-@erase "$(INTDIR)\htcacheclean_src.pdb"
    	-@erase "$(OUTDIR)\htcacheclean.exe"
    	-@erase "$(OUTDIR)\htcacheclean.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htcacheclean_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htcacheclean.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htcacheclean.exe" /d LONG_NAME="Apache htcacheclean command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htcacheclean.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htcacheclean.pdb" /debug /out:"$(OUTDIR)\htcacheclean.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\htcacheclean.obj" \
    	"$(INTDIR)\htcacheclean.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\htcacheclean.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\htcacheclean.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htcacheclean.exe"
       if exist .\Debug\htcacheclean.exe.manifest mt.exe -manifest .\Debug\htcacheclean.exe.manifest -outputresource:.\Debug\htcacheclean.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("htcacheclean.dep")
    !INCLUDE "htcacheclean.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "htcacheclean.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "htcacheclean - Win32 Release" || "$(CFG)" == "htcacheclean - Win32 Debug"
    
    !IF  "$(CFG)" == "htcacheclean - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htcacheclean - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "htcacheclean - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htcacheclean - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=.\htcacheclean.c
    
    "$(INTDIR)\htcacheclean.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "htcacheclean - Win32 Release"
    
    
    "$(INTDIR)\htcacheclean.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htcacheclean.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htcacheclean.exe" /d LONG_NAME="Apache htcacheclean command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "htcacheclean - Win32 Debug"
    
    
    "$(INTDIR)\htcacheclean.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htcacheclean.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htcacheclean.exe" /d LONG_NAME="Apache htcacheclean command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htdigest.c���������������������������������������������������������������������0000664�0001751�0001751�00000020435�13160166751�016327� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <sys/types.h>
    #endif
    #if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    
    #ifdef WIN32
    #include <conio.h>
    #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
    #define MAX_LINE_LEN 768
    
    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 int getword(char *word, char *line, char stop)
    {
        int x = 0, y;
    
        for (x = 0; ((line[x]) && (line[x] != stop)); x++) {
            if (x == (MAX_STRING_LEN - 1)) {
                return 1;
            }
            word[x] = line[x];
        }
    
        word[x] = '\0';
        if (line[x])
            ++x;
        y = 0;
    
        while ((line[y++] = line[x++]));
    
        return 0;
    }
    
    static int get_line(char *s, int n, apr_file_t *f)
    {
        int i = 0;
        char ch;
        apr_status_t rv = APR_EINVAL;
    
        /* we need 2 remaining bytes in buffer */
        while (i < (n - 2) &&
               ((rv = apr_file_getc(&ch, f)) == APR_SUCCESS) && (ch != '\n')) {
            s[i++] = ch;
        }
        /* First remaining byte potentially used here */
        if (ch == '\n')
            s[i++] = ch;
        /* Second remaining byte used here */
        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_LINE_LEN]; /* this includes room for 2 * ':' + '\0' */
        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 */
        apr_snprintf(string, sizeof(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_LINE_LEN];
        char l[MAX_LINE_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(): %pm (%d)\n",
                    &rv, 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) {
                apr_file_printf(errfile, "Could not open passwd file %s for writing: %pm\n",
                        argv[2], &rv);
                exit(1);
            }
            apr_cpystrn(user, argv[4], sizeof(user));
            apr_cpystrn(realm, argv[3], sizeof(realm));
            apr_file_printf(errfile, "Adding password for %s in realm %s.\n",
                        user, realm);
            add_password(user, realm, 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, sizeof(line), f))) {
            if (found || (line[0] == '#') || (!line[0])) {
                putline(tfp, line);
                continue;
            }
            strcpy(l, line);
            if (getword(w, l, ':') || getword(x, l, ':')) {
                apr_file_printf(errfile, "The following line contains a string longer than the "
                                         "allowed maximum size (%i): %s\n", MAX_STRING_LEN - 1, line);
                cleanup_tempfile_and_exit(1);
            }
            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_OS_DEFAULT, cntxt) !=
                    APR_SUCCESS) {
            apr_file_printf(errfile, "%s: unable to update file %s\n",
                            argv[0], argv[1]);
        }
        apr_file_close(tfp);
    
        return 0;
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/logresolve.pl.in���������������������������������������������������������������0000664�0001751�0001751�00000015337�12757564422�017510� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!@perlbin@
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 <infile >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 noticeable 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 <luuk_de_boer pi.net>
    
    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(<STDIN>) {
    		@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 ($_ = <STDIN>));
    
    		 ## 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 occurred 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;
    }
    
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htdbm.mak����������������������������������������������������������������������0000664�0001751�0001751�00000020425�12701473373�016140� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on htdbm.dsp
    !IF "$(CFG)" == ""
    CFG=htdbm - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to htdbm - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "htdbm - Win32 Release" && "$(CFG)" != "htdbm - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "htdbm - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htdbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\htdbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htdbm.obj"
    	-@erase "$(INTDIR)\htdbm.res"
    	-@erase "$(INTDIR)\htdbm_src.idb"
    	-@erase "$(INTDIR)\htdbm_src.pdb"
    	-@erase "$(INTDIR)\passwd_common.obj"
    	-@erase "$(OUTDIR)\htdbm.exe"
    	-@erase "$(OUTDIR)\htdbm.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htdbm_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htdbm.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htdbm.exe" /d LONG_NAME="Apache htdbm command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htdbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htdbm.pdb" /debug /out:"$(OUTDIR)\htdbm.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\htdbm.obj" \
    	"$(INTDIR)\passwd_common.obj" \
    	"$(INTDIR)\htdbm.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\htdbm.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\htdbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htdbm.exe"
       if exist .\Release\htdbm.exe.manifest mt.exe -manifest .\Release\htdbm.exe.manifest -outputresource:.\Release\htdbm.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "htdbm - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htdbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\htdbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htdbm.obj"
    	-@erase "$(INTDIR)\htdbm.res"
    	-@erase "$(INTDIR)\htdbm_src.idb"
    	-@erase "$(INTDIR)\htdbm_src.pdb"
    	-@erase "$(INTDIR)\passwd_common.obj"
    	-@erase "$(OUTDIR)\htdbm.exe"
    	-@erase "$(OUTDIR)\htdbm.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htdbm_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htdbm.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htdbm.exe" /d LONG_NAME="Apache htdbm command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htdbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htdbm.pdb" /debug /out:"$(OUTDIR)\htdbm.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\htdbm.obj" \
    	"$(INTDIR)\passwd_common.obj" \
    	"$(INTDIR)\htdbm.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\htdbm.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\htdbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htdbm.exe"
       if exist .\Debug\htdbm.exe.manifest mt.exe -manifest .\Debug\htdbm.exe.manifest -outputresource:.\Debug\htdbm.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("htdbm.dep")
    !INCLUDE "htdbm.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "htdbm.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "htdbm - Win32 Release" || "$(CFG)" == "htdbm - Win32 Debug"
    
    !IF  "$(CFG)" == "htdbm - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htdbm - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "htdbm - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htdbm - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=.\htdbm.c
    
    "$(INTDIR)\htdbm.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "htdbm - Win32 Release"
    
    
    "$(INTDIR)\htdbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htdbm.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htdbm.exe" /d LONG_NAME="Apache htdbm command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "htdbm - Win32 Debug"
    
    
    "$(INTDIR)\htdbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htdbm.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htdbm.exe" /d LONG_NAME="Apache htdbm command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\passwd_common.c
    
    "$(INTDIR)\passwd_common.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/.indent.pro��������������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�016424� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/phf_abuse_log.cgi.in�����������������������������������������������������������0000664�0001751�0001751�00000003032�10455010104�020210� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!@perlbin@
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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 "<Location /cgi-bin/phf*>" 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\n<BLINK>Smile, you're on Candid Camera.</BLINK>\n";
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/httxt2dbm.mak������������������������������������������������������������������0000664�0001751�0001751�00000020553�12701473373�016764� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on httxt2dbm.dsp
    !IF "$(CFG)" == ""
    CFG=httxt2dbm - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to httxt2dbm - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "httxt2dbm - Win32 Release" && "$(CFG)" != "httxt2dbm - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 "httxt2dbm.mak" CFG="httxt2dbm - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "httxt2dbm - Win32 Release" (based on "Win32 (x86) Console Application")
    !MESSAGE "httxt2dbm - Win32 Debug" (based on "Win32 (x86) Console Application")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "httxt2dbm - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\httxt2dbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\httxt2dbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httxt2dbm.obj"
    	-@erase "$(INTDIR)\httxt2dbm.res"
    	-@erase "$(INTDIR)\httxt2dbm_src.idb"
    	-@erase "$(INTDIR)\httxt2dbm_src.pdb"
    	-@erase "$(OUTDIR)\httxt2dbm.exe"
    	-@erase "$(OUTDIR)\httxt2dbm.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\httxt2dbm_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httxt2dbm.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="httxt2dbm.exe" /d LONG_NAME="Apache httxt2dbm command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\httxt2dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\httxt2dbm.pdb" /debug /out:"$(OUTDIR)\httxt2dbm.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\httxt2dbm.obj" \
    	"$(INTDIR)\httxt2dbm.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\httxt2dbm.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\httxt2dbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\httxt2dbm.exe"
       if exist .\Release\httxt2dbm.exe.manifest mt.exe -manifest .\Release\httxt2dbm.exe.manifest -outputresource:.\Release\httxt2dbm.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "httxt2dbm - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\httxt2dbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\httxt2dbm.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httxt2dbm.obj"
    	-@erase "$(INTDIR)\httxt2dbm.res"
    	-@erase "$(INTDIR)\httxt2dbm_src.idb"
    	-@erase "$(INTDIR)\httxt2dbm_src.pdb"
    	-@erase "$(OUTDIR)\httxt2dbm.exe"
    	-@erase "$(OUTDIR)\httxt2dbm.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\httxt2dbm_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httxt2dbm.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="httxt2dbm.exe" /d LONG_NAME="Apache httxt2dbm command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\httxt2dbm.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\httxt2dbm.pdb" /debug /out:"$(OUTDIR)\httxt2dbm.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\httxt2dbm.obj" \
    	"$(INTDIR)\httxt2dbm.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\httxt2dbm.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\httxt2dbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\httxt2dbm.exe"
       if exist .\Debug\httxt2dbm.exe.manifest mt.exe -manifest .\Debug\httxt2dbm.exe.manifest -outputresource:.\Debug\httxt2dbm.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("httxt2dbm.dep")
    !INCLUDE "httxt2dbm.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "httxt2dbm.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "httxt2dbm - Win32 Release" || "$(CFG)" == "httxt2dbm - Win32 Debug"
    
    !IF  "$(CFG)" == "httxt2dbm - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "httxt2dbm - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "httxt2dbm - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "httxt2dbm - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "httxt2dbm - Win32 Release"
    
    
    "$(INTDIR)\httxt2dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httxt2dbm.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="httxt2dbm.exe" /d LONG_NAME="Apache httxt2dbm command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "httxt2dbm - Win32 Debug"
    
    
    "$(INTDIR)\httxt2dbm.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httxt2dbm.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="httxt2dbm.exe" /d LONG_NAME="Apache httxt2dbm command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\httxt2dbm.c
    
    "$(INTDIR)\httxt2dbm.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/abs.dep������������������������������������������������������������������������0000664�0001751�0001751�00000002407�12674411515�015606� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by abs.mak
    
    .\ab.c : \
    	"..\include\ap_release.h"\
    	"..\srclib\apr-util\include\apr_base64.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_dso.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_global_mutex.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_network_io.h"\
    	"..\srclib\apr\include\apr_poll.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_portable.h"\
    	"..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\srclib\apr\include\apr_shm.h"\
    	"..\srclib\apr\include\apr_signal.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_thread_proc.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htdigest.dep�������������������������������������������������������������������0000664�0001751�0001751�00000001607�12674411515�016655� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by htdigest.mak
    
    .\htdigest.c : \
    	"..\srclib\apr-util\include\apr_md5.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_signal.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    �������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htpasswd.mak�������������������������������������������������������������������0000664�0001751�0001751�00000020777�12701473373�016711� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on htpasswd.dsp
    !IF "$(CFG)" == ""
    CFG=htpasswd - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to htpasswd - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "htpasswd - Win32 Release" && "$(CFG)" != "htpasswd - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "htpasswd - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htpasswd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\htpasswd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htpasswd.obj"
    	-@erase "$(INTDIR)\htpasswd.res"
    	-@erase "$(INTDIR)\htpasswd_src.idb"
    	-@erase "$(INTDIR)\htpasswd_src.pdb"
    	-@erase "$(INTDIR)\passwd_common.obj"
    	-@erase "$(OUTDIR)\htpasswd.exe"
    	-@erase "$(OUTDIR)\htpasswd.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htpasswd_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htpasswd.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htpasswd.exe" /d LONG_NAME="Apache htpasswd command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htpasswd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib rpcrt4.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htpasswd.pdb" /debug /out:"$(OUTDIR)\htpasswd.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\htpasswd.obj" \
    	"$(INTDIR)\passwd_common.obj" \
    	"$(INTDIR)\htpasswd.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\htpasswd.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\htpasswd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htpasswd.exe"
       if exist .\Release\htpasswd.exe.manifest mt.exe -manifest .\Release\htpasswd.exe.manifest -outputresource:.\Release\htpasswd.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "htpasswd - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htpasswd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\htpasswd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htpasswd.obj"
    	-@erase "$(INTDIR)\htpasswd.res"
    	-@erase "$(INTDIR)\htpasswd_src.idb"
    	-@erase "$(INTDIR)\htpasswd_src.pdb"
    	-@erase "$(INTDIR)\passwd_common.obj"
    	-@erase "$(OUTDIR)\htpasswd.exe"
    	-@erase "$(OUTDIR)\htpasswd.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htpasswd_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htpasswd.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htpasswd.exe" /d LONG_NAME="Apache htpasswd command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htpasswd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib rpcrt4.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htpasswd.pdb" /debug /out:"$(OUTDIR)\htpasswd.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\htpasswd.obj" \
    	"$(INTDIR)\passwd_common.obj" \
    	"$(INTDIR)\htpasswd.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\htpasswd.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\htpasswd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htpasswd.exe"
       if exist .\Debug\htpasswd.exe.manifest mt.exe -manifest .\Debug\htpasswd.exe.manifest -outputresource:.\Debug\htpasswd.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("htpasswd.dep")
    !INCLUDE "htpasswd.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "htpasswd.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "htpasswd - Win32 Release" || "$(CFG)" == "htpasswd - Win32 Debug"
    
    !IF  "$(CFG)" == "htpasswd - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htpasswd - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "htpasswd - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htpasswd - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=.\htpasswd.c
    
    "$(INTDIR)\htpasswd.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "htpasswd - Win32 Release"
    
    
    "$(INTDIR)\htpasswd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htpasswd.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htpasswd.exe" /d LONG_NAME="Apache htpasswd command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "htpasswd - Win32 Debug"
    
    
    "$(INTDIR)\htpasswd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htpasswd.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htpasswd.exe" /d LONG_NAME="Apache htpasswd command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\passwd_common.c
    
    "$(INTDIR)\passwd_common.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �httpd-2.4.64/support/ab.dep�������������������������������������������������������������������������0000664�0001751�0001751�00000002406�12674411515�015422� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by ab.mak
    
    .\ab.c : \
    	"..\include\ap_release.h"\
    	"..\srclib\apr-util\include\apr_base64.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_dso.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_global_mutex.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_network_io.h"\
    	"..\srclib\apr\include\apr_poll.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_portable.h"\
    	"..\srclib\apr\include\apr_proc_mutex.h"\
    	"..\srclib\apr\include\apr_shm.h"\
    	"..\srclib\apr\include\apr_signal.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_thread_proc.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htdbm.dep����������������������������������������������������������������������0000664�0001751�0001751�00000003724�12674411515�016142� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by htdbm.mak
    
    .\htdbm.c : \
    	"..\srclib\apr-util\include\apr_dbm.h"\
    	"..\srclib\apr-util\include\apr_md5.h"\
    	"..\srclib\apr-util\include\apr_sha1.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr-util\include\apu_version.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_signal.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_version.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	".\passwd_common.h"\
    	
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    
    .\passwd_common.c : \
    	"..\srclib\apr-util\include\apr_md5.h"\
    	"..\srclib\apr-util\include\apr_sha1.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr-util\include\apu_version.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_version.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	".\passwd_common.h"\
    	
    ��������������������������������������������httpd-2.4.64/support/logresolve.dep�����������������������������������������������������������������0000664�0001751�0001751�00000001542�12674411515�017221� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by logresolve.mak
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    
    .\logresolve.c : \
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_hash.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_network_io.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/htdigest.mak�������������������������������������������������������������������0000664�0001751�0001751�00000020435�12701473373�016656� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on htdigest.dsp
    !IF "$(CFG)" == ""
    CFG=htdigest - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to htdigest - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "htdigest - Win32 Release" && "$(CFG)" != "htdigest - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "htdigest - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htdigest.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\htdigest.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htdigest.obj"
    	-@erase "$(INTDIR)\htdigest.res"
    	-@erase "$(INTDIR)\htdigest_src.idb"
    	-@erase "$(INTDIR)\htdigest_src.pdb"
    	-@erase "$(OUTDIR)\htdigest.exe"
    	-@erase "$(OUTDIR)\htdigest.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htdigest_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htdigest.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htdigest.exe" /d LONG_NAME="Apache htdigest command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htdigest.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htdigest.pdb" /debug /out:"$(OUTDIR)\htdigest.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\htdigest.obj" \
    	"$(INTDIR)\htdigest.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\htdigest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\htdigest.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htdigest.exe"
       if exist .\Release\htdigest.exe.manifest mt.exe -manifest .\Release\htdigest.exe.manifest -outputresource:.\Release\htdigest.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "htdigest - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\htdigest.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\htdigest.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\htdigest.obj"
    	-@erase "$(INTDIR)\htdigest.res"
    	-@erase "$(INTDIR)\htdigest_src.idb"
    	-@erase "$(INTDIR)\htdigest_src.pdb"
    	-@erase "$(OUTDIR)\htdigest.exe"
    	-@erase "$(OUTDIR)\htdigest.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\htdigest_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\htdigest.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htdigest.exe" /d LONG_NAME="Apache htdigest command line utility" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\htdigest.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\htdigest.pdb" /debug /out:"$(OUTDIR)\htdigest.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\htdigest.obj" \
    	"$(INTDIR)\htdigest.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\htdigest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\htdigest.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\htdigest.exe"
       if exist .\Debug\htdigest.exe.manifest mt.exe -manifest .\Debug\htdigest.exe.manifest -outputresource:.\Debug\htdigest.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("htdigest.dep")
    !INCLUDE "htdigest.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "htdigest.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "htdigest - Win32 Release" || "$(CFG)" == "htdigest - Win32 Debug"
    
    !IF  "$(CFG)" == "htdigest - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htdigest - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "htdigest - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "htdigest - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=.\htdigest.c
    
    "$(INTDIR)\htdigest.obj" : $(SOURCE) "$(INTDIR)"
    
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "htdigest - Win32 Release"
    
    
    "$(INTDIR)\htdigest.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htdigest.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="htdigest.exe" /d LONG_NAME="Apache htdigest command line utility" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "htdigest - Win32 Debug"
    
    
    "$(INTDIR)\htdigest.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\htdigest.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="htdigest.exe" /d LONG_NAME="Apache htdigest command line utility" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/rotatelogs.mak�����������������������������������������������������������������0000664�0001751�0001751�00000020655�12701473373�017232� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on rotatelogs.dsp
    !IF "$(CFG)" == ""
    CFG=rotatelogs - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to rotatelogs - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "rotatelogs - Win32 Release" && "$(CFG)" != "rotatelogs - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "rotatelogs - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\rotatelogs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\rotatelogs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\rotatelogs.obj"
    	-@erase "$(INTDIR)\rotatelogs.res"
    	-@erase "$(INTDIR)\rotatelogs_src.idb"
    	-@erase "$(INTDIR)\rotatelogs_src.pdb"
    	-@erase "$(OUTDIR)\rotatelogs.exe"
    	-@erase "$(OUTDIR)\rotatelogs.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\rotatelogs_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\rotatelogs.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="rotatelogs.exe" /d LONG_NAME="Apache rotatelogs command line pipe" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\rotatelogs.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\rotatelogs.pdb" /debug /out:"$(OUTDIR)\rotatelogs.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\rotatelogs.obj" \
    	"$(INTDIR)\rotatelogs.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\rotatelogs.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\rotatelogs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\rotatelogs.exe"
       if exist .\Release\rotatelogs.exe.manifest mt.exe -manifest .\Release\rotatelogs.exe.manifest -outputresource:.\Release\rotatelogs.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "rotatelogs - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\rotatelogs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\rotatelogs.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\rotatelogs.obj"
    	-@erase "$(INTDIR)\rotatelogs.res"
    	-@erase "$(INTDIR)\rotatelogs_src.idb"
    	-@erase "$(INTDIR)\rotatelogs_src.pdb"
    	-@erase "$(OUTDIR)\rotatelogs.exe"
    	-@erase "$(OUTDIR)\rotatelogs.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\rotatelogs_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\rotatelogs.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="rotatelogs.exe" /d LONG_NAME="Apache rotatelogs command line pipe" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\rotatelogs.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\rotatelogs.pdb" /debug /out:"$(OUTDIR)\rotatelogs.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\rotatelogs.obj" \
    	"$(INTDIR)\rotatelogs.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\rotatelogs.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\rotatelogs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\rotatelogs.exe"
       if exist .\Debug\rotatelogs.exe.manifest mt.exe -manifest .\Debug\rotatelogs.exe.manifest -outputresource:.\Debug\rotatelogs.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("rotatelogs.dep")
    !INCLUDE "rotatelogs.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "rotatelogs.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "rotatelogs - Win32 Release" || "$(CFG)" == "rotatelogs - Win32 Debug"
    
    !IF  "$(CFG)" == "rotatelogs - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "rotatelogs - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "rotatelogs - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "rotatelogs - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "rotatelogs - Win32 Release"
    
    
    "$(INTDIR)\rotatelogs.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\rotatelogs.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="rotatelogs.exe" /d LONG_NAME="Apache rotatelogs command line pipe" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "rotatelogs - Win32 Debug"
    
    
    "$(INTDIR)\rotatelogs.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\rotatelogs.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="rotatelogs.exe" /d LONG_NAME="Apache rotatelogs command line pipe" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\rotatelogs.c
    
    "$(INTDIR)\rotatelogs.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������httpd-2.4.64/support/htcacheclean.dep���������������������������������������������������������������0000664�0001751�0001751�00000002440�12674411515�017440� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by htcacheclean.mak
    
    .\htcacheclean.c : \
    	"..\modules\cache\cache_common.h"\
    	"..\modules\cache\cache_disk_common.h"\
    	"..\srclib\apr-util\include\apr_buckets.h"\
    	"..\srclib\apr-util\include\apr_date.h"\
    	"..\srclib\apr-util\include\apr_md5.h"\
    	"..\srclib\apr-util\include\apr_xlate.h"\
    	"..\srclib\apr-util\include\apu.h"\
    	"..\srclib\apr\include\apr.h"\
    	"..\srclib\apr\include\apr_allocator.h"\
    	"..\srclib\apr\include\apr_errno.h"\
    	"..\srclib\apr\include\apr_file_info.h"\
    	"..\srclib\apr\include\apr_file_io.h"\
    	"..\srclib\apr\include\apr_general.h"\
    	"..\srclib\apr\include\apr_getopt.h"\
    	"..\srclib\apr\include\apr_hash.h"\
    	"..\srclib\apr\include\apr_inherit.h"\
    	"..\srclib\apr\include\apr_lib.h"\
    	"..\srclib\apr\include\apr_mmap.h"\
    	"..\srclib\apr\include\apr_network_io.h"\
    	"..\srclib\apr\include\apr_pools.h"\
    	"..\srclib\apr\include\apr_ring.h"\
    	"..\srclib\apr\include\apr_signal.h"\
    	"..\srclib\apr\include\apr_strings.h"\
    	"..\srclib\apr\include\apr_tables.h"\
    	"..\srclib\apr\include\apr_thread_mutex.h"\
    	"..\srclib\apr\include\apr_thread_proc.h"\
    	"..\srclib\apr\include\apr_time.h"\
    	"..\srclib\apr\include\apr_user.h"\
    	"..\srclib\apr\include\apr_want.h"\
    	
    
    ..\build\win32\httpd.rc : \
    	"..\include\ap_release.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/httxt2dbm.dsp������������������������������������������������������������������0000664�0001751�0001751�00000010356�12520036522�016770� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="httxt2dbm" - Package Owner=<4>
    # Microsoft Developer Studio Generated Build File, Format Version 6.00
    # ** DO NOT EDIT **
    
    # TARGTYPE "Win32 (x86) Console Application" 0x0103
    
    CFG=httxt2dbm - 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 "httxt2dbm.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 "httxt2dbm.mak" CFG="httxt2dbm - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "httxt2dbm - Win32 Release" (based on "Win32 (x86) Console Application")
    !MESSAGE "httxt2dbm - 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)" == "httxt2dbm - 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/httxt2dbm_src" /FD /c
    # ADD BASE RSC /l 0x409 /d "NDEBUG"
    # ADD RSC /l 0x409 /fo"Release/httxt2dbm.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="httxt2dbm.exe" /d LONG_NAME="Apache httxt2dbm command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\httxt2dbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "httxt2dbm - 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 /EHsc /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 /EHsc /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/httxt2dbm_src" /FD /c
    # ADD BASE RSC /l 0x409 /d "_DEBUG"
    # ADD RSC /l 0x409 /fo"Debug/httxt2dbm.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="httxt2dbm.exe" /d LONG_NAME="Apache httxt2dbm command line utility"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\httxt2dbm.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "httxt2dbm - Win32 Release"
    # Name "httxt2dbm - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\httxt2dbm.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/logresolve.mak�����������������������������������������������������������������0000664�0001751�0001751�00000020655�12701473373�017230� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on logresolve.dsp
    !IF "$(CFG)" == ""
    CFG=logresolve - Win32 Debug
    !MESSAGE No configuration specified. Defaulting to logresolve - Win32 Debug.
    !ENDIF 
    
    !IF "$(CFG)" != "logresolve - Win32 Release" && "$(CFG)" != "logresolve - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "logresolve - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\logresolve.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Release" "apr - Win32 Release" "$(OUTDIR)\logresolve.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 ReleaseCLEAN" "aprutil - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\logresolve.obj"
    	-@erase "$(INTDIR)\logresolve.res"
    	-@erase "$(INTDIR)\logresolve_src.idb"
    	-@erase "$(INTDIR)\logresolve_src.pdb"
    	-@erase "$(OUTDIR)\logresolve.exe"
    	-@erase "$(OUTDIR)\logresolve.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\logresolve_src" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\logresolve.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="logresolve.exe" /d LONG_NAME="Apache logresolve command line pipe" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\logresolve.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\logresolve.pdb" /debug /out:"$(OUTDIR)\logresolve.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\logresolve.obj" \
    	"$(INTDIR)\logresolve.res" \
    	"..\srclib\apr\LibR\apr-1.lib" \
    	"..\srclib\apr-util\LibR\aprutil-1.lib"
    
    "$(OUTDIR)\logresolve.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\logresolve.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\logresolve.exe"
       if exist .\Release\logresolve.exe.manifest mt.exe -manifest .\Release\logresolve.exe.manifest -outputresource:.\Release\logresolve.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "logresolve - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\logresolve.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "aprutil - Win32 Debug" "apr - Win32 Debug" "$(OUTDIR)\logresolve.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"apr - Win32 DebugCLEAN" "aprutil - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\logresolve.obj"
    	-@erase "$(INTDIR)\logresolve.res"
    	-@erase "$(INTDIR)\logresolve_src.idb"
    	-@erase "$(INTDIR)\logresolve_src.pdb"
    	-@erase "$(OUTDIR)\logresolve.exe"
    	-@erase "$(OUTDIR)\logresolve.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /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" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\logresolve_src" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\logresolve.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="logresolve.exe" /d LONG_NAME="Apache logresolve command line pipe" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\logresolve.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\logresolve.pdb" /debug /out:"$(OUTDIR)\logresolve.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\logresolve.obj" \
    	"$(INTDIR)\logresolve.res" \
    	"..\srclib\apr\LibD\apr-1.lib" \
    	"..\srclib\apr-util\LibD\aprutil-1.lib"
    
    "$(OUTDIR)\logresolve.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\logresolve.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\logresolve.exe"
       if exist .\Debug\logresolve.exe.manifest mt.exe -manifest .\Debug\logresolve.exe.manifest -outputresource:.\Debug\logresolve.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("logresolve.dep")
    !INCLUDE "logresolve.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "logresolve.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "logresolve - Win32 Release" || "$(CFG)" == "logresolve - Win32 Debug"
    
    !IF  "$(CFG)" == "logresolve - Win32 Release"
    
    "apr - Win32 Release" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" 
       cd "..\..\support"
    
    "apr - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "logresolve - Win32 Debug"
    
    "apr - Win32 Debug" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" 
       cd "..\..\support"
    
    "apr - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\apr.mak" CFG="apr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "logresolve - Win32 Release"
    
    "aprutil - Win32 Release" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" 
       cd "..\..\support"
    
    "aprutil - Win32 ReleaseCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ELSEIF  "$(CFG)" == "logresolve - Win32 Debug"
    
    "aprutil - Win32 Debug" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" 
       cd "..\..\support"
    
    "aprutil - Win32 DebugCLEAN" : 
       cd ".\..\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\aprutil.mak" CFG="aprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\..\support"
    
    !ENDIF 
    
    SOURCE=..\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "logresolve - Win32 Release"
    
    
    "$(INTDIR)\logresolve.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\logresolve.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="logresolve.exe" /d LONG_NAME="Apache logresolve command line pipe" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "logresolve - Win32 Debug"
    
    
    "$(INTDIR)\logresolve.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\logresolve.res" /i "../include" /i "../srclib/apr/include" /i "../build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="logresolve.exe" /d LONG_NAME="Apache logresolve command line pipe" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\logresolve.c
    
    "$(INTDIR)\logresolve.obj" : $(SOURCE) "$(INTDIR)"
    
    
    
    !ENDIF 
    
    �����������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUhtpasswd������������������������������������������������������������������0000664�0001751�0001751�00000010511�12061606345�016736� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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 \
    			$(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	=
    
    #
    # 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		=  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 \
    	$(OBJDIR)/passwd_common.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 = \
       	$(PRELUDE) \
    	$(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 = \
    	@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 $(APBUILD)/NWGNUtail.inc
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/rotatelogs.dsp�����������������������������������������������������������������0000664�0001751�0001751�00000010376�12520036522�017235� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /fo"Release/rotatelogs.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="rotatelogs.exe" /d LONG_NAME="Apache rotatelogs command line pipe"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\rotatelogs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /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 /EHsc /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 /fo"Debug/rotatelogs.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="rotatelogs.exe" /d LONG_NAME="Apache rotatelogs command line pipe"
    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 rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib rpcrt4.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\rotatelogs.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "rotatelogs - Win32 Release"
    # Name "rotatelogs - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\rotatelogs.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/NWGNUab������������������������������������������������������������������������0000664�0001751�0001751�00000013374�11540546347�015503� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # 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
    
    #
    # build this level's files
    #
    # Make sure all needed macro's are defined
    #
    
    ifeq "$(WITH_ABS)" "1"
    
    ifeq "$(USE_NTLS)" "1"
    SSL_INC = $(NTLSSDK)/inc
    SSL_LIB = $(NTLSSDK)/imp
    SSL_BIN = $(NTLSSDK)/bin
    SSL_APP = $(NTLSSDK)/apps
    ifneq "$(wildcard $(SSL_INC)/openssl/opensslv.h)" "$(SSL_INC)/openssl/opensslv.h"
    $(warning '$(NTLSSDK)' does NOT point to a valid NTLS SDK!)
    endif
    else
    SSL_INC = $(OSSLSDK)/outinc_nw_libc
    SSL_LIB = $(OSSLSDK)/out_nw_libc
    SSL_BIN = $(OSSLSDK)/out_nw_libc
    SSL_APP = $(OSSLSDK)/apps
    ifneq "$(wildcard $(SSL_INC)/openssl/opensslv.h)" "$(SSL_INC)/openssl/opensslv.h"
    $(warning '$(OSSLSDK)' does NOT point to a valid OpenSSL SDK!)
    endif
    endif
    ifeq "$(wildcard $(SSL_INC)/openssl/opensslv.h)" "$(SSL_INC)/openssl/opensslv.h"
    HAVE_OPENSSL = 1
    endif
    
    endif
    
    #
    # These directories will be at the beginning of the include list, followed by
    # INCDIRS
    #
    ifdef HAVE_OPENSSL
    XINCDIRS	+= \
    			$(SSL_INC) \
    			$(SSL_INC)/openssl \
    			$(EOLIST)
    endif
    
    XINCDIRS	+= \
    			$(NWOS) \
    			$(AP_WORK)/include \
    			$(APR)/include \
    			$(APRUTIL)/include \
    			$(APR)/misc/netware \
    			$(EOLIST)
    
    #
    # These flags will come after CFLAGS
    #
    XCFLAGS		+= \
    			$(EOLIST)
    
    #
    # These defines will come after DEFINES
    #
    ifdef HAVE_OPENSSL
    XDEFINES	+= \
    			-DHAVE_OPENSSL \
    			$(EOLIST)
    
    #
    # These flags will be added to the link.opt file
    #
    XLFLAGS		+= \
    			-l $(SSL_LIB) \
    			$(EOLIST)
    endif
    
    #
    # 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.
    #
    ifdef HAVE_OPENSSL
    NLM_NAME		= abs
    else
    NLM_NAME		= ab
    endif
    
    #
    # 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	= $(NLM_NAME)
    
    #
    # 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	= 65536
    
    
    #
    # 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)/$(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)/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 = \
    	$(PRELUDE) \
    	$(EOLIST)
    
    ifdef HAVE_OPENSSL
    ifneq "$(USE_NTLS)" "1"
    FILES_nlm_libs += \
    	$(SSL_LIB)/crypto.lib \
    	$(SSL_LIB)/ssl.lib \
    	$(EOLIST)
    endif
    endif
    
    #
    # 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)
    
    ifdef HAVE_OPENSSL
    ifeq "$(USE_NTLS)" "1"
    FILES_nlm_modules += ntls \
    	$(EOLIST)
    endif
    endif
    
    #
    # 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 = \
    	@aprlib.imp \
    	@libc.imp \
    	$(EOLIST)
    
    # Don't link with Winsock if standard sockets are being used
    ifneq "$(USE_STDSOCKETS)" "1"
    FILES_nlm_Ximports += @ws2nlm.imp \
    	$(EOLIST)
    endif
    
    ifdef HAVE_OPENSSL
    ifeq "$(USE_NTLS)" "1"
    FILES_nlm_Ximports += @ntls.imp \
    	$(EOLIST)
    else
    FILES_nlm_Ximports += \
    	GetProcessSwitchCount \
    	RunningProcess \
    	GetSuperHighResolutionTimer \
    	$(EOLIST)
    endif
    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
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/support/fcgistarter.dsp����������������������������������������������������������������0000664�0001751�0001751�00000010376�10732104610�017364� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="fcgistarter" - Package Owner=<4>
    # Microsoft Developer Studio Generated Build File, Format Version 6.00
    # ** DO NOT EDIT **
    
    # TARGTYPE "Win32 (x86) Console Application" 0x0103
    
    CFG=fcgistarter - 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 "fcgistarter.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 "fcgistarter.mak" CFG="fcgistarter - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "fcgistarter - Win32 Release" (based on "Win32 (x86) Console Application")
    !MESSAGE "fcgistarter - 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)" == "fcgistarter - 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/fcgistarter_src" /FD /c
    # ADD BASE RSC /l 0x409 /d "NDEBUG"
    # ADD RSC /l 0x409 /fo"Release/fcgistarter.res" /i "../include" /i "../srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="fcgistarter.exe" /d LONG_NAME="Apache fcgi command line utility"
    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 shell32.lib /nologo /subsystem:console
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib /nologo /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\fcgistarter.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "fcgistarter - 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 /EHsc /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 /EHsc /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/fcgistarter_src" /FD /c
    # ADD BASE RSC /l 0x409 /d "_DEBUG"
    # ADD RSC /l 0x409 /fo"Debug/fcgistarter.res" /i "../include" /i "../srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="fcgistarter.exe" /d LONG_NAME="Apache fcgi command line utility"
    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 shell32.lib /nologo /subsystem:console /incremental:no /debug
    # ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib shell32.lib /nologo /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\fcgistarter.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ENDIF 
    
    # Begin Target
    
    # Name "fcgistarter - Win32 Release"
    # Name "fcgistarter - Win32 Debug"
    # Begin Source File
    
    SOURCE=.\fcgistarter.c
    # End Source File
    # Begin Source File
    
    SOURCE=..\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/CHANGES��������������������������������������������������������������������������������0000664�0001751�0001751�00001342570�15032730241�013626� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������                                                         -*- coding: utf-8 -*-
    Changes with Apache 2.4.64
    
      *) mod_proxy_ajp: Use iobuffersize set on worker level for the IO buffer
         size. PR 69402 [Jari Ahonen <jah@progress.com>]
    
      *) mod_ssl: Drop $SSLKEYLOGFILE handling internally for OpenSSL 3.5
         builds which enable it in libssl natively.  [Joe Orton]
    
      *) mod_asis: Fix the log level of the message AH01236.
         Github #527 [Michael Kaufmann <mail michael-kaufmann.ch>]
    
      *) mod_session_dbd: ensure format used with SessionDBDCookieName and
         SessionDBDCookieName2 are correct.
         Github #503 [Thomas Meyer <thomas m3y3r.de>]
    
      *) mod_headers: 'RequestHeader set|edit|edit_r Content-Type X' could
         inadvertently modify the Content-Type _response_ header. Applies to
         Content-Type only and likely to only affect static file responses.
         [Eric Covener]
    
      *) mod_ssl: Remove warning over potential uninitialised value
         for ssl protocol prior to protocol selection.
         [Graham Leggett]
    
      *) mod_proxy: Reuse ProxyRemote connections when possible, like prior
         to 2.4.59.  [Jean-Frederic Clere, Yann Ylavic]
    
      *) mod_systemd: Add systemd socket activation support.  [Paul Querna,
         Jan Kaluza, Lubos Uhliarik <luhliari redhat.com>, Joe Orton]
    
      *) mod_systemd: Log the SELinux context at startup if available and
         enabled.  [Joe Orton]
    
      *) mod_http2: update to version 2.0.32
         The code setting the connection window size was set wrong,
         preventing `H2WindowSize` to work.
         Fixed <https://github.com/icing/mod_h2/issues/300>.
         [Stefan Eissing, Michael Kaufmann]
    
      *) mod_http2: update to version 2.0.30
         - Fixed bug in handling over long response headers. When the 64 KB limit
           of nghttp2 was exceeded, the request was not reset and the client was
           left hanging, waiting for it. Now the stream is reset.
         - Added new directive `H2MaxHeaderBlockLen` to set the limit on response
           header sizes.
         - Fixed handling of Timeout vs. KeepAliveTimeout when first request on a
           connection was reset.
    
      *) mod_lua: Fix memory handling in LuaOutputFilter. PR 69590.
         [Guillermo Grandes <guillermo.grandes gmail.com>]
    
      * mod_proxy_http2: revert r1912193 for detecting broken backend connections
        as this interferes with backend selection who a node is unresponsive.
        PR69624.
    
      *) mod_proxy_balancer: Fix a regression that caused stickysession keys no
         longer be recognized if they are provided as query parameter in the URL.
         PR 69443 [Ruediger Pluem]
    
      *) mod_md: update to version 2.5.2
         - Fixed TLS-ALPN-01 challenges when multiple `MDPrivateKeys` are specified
           with EC keys before RSA ones. Fixes #377. [Stefan Eissing]
         - Fixed missing newlines in the status page output. [Andreas Groth]
    
      *) mod_dav: Add API to expose DavBasePath setting.  [Joe Orton]
    
      *) mod_md: update to version 2.5.1
         - Added support for ACME profiles with new directives MDProfile and
           MDProfileMandatory.
         - When installing a custom CA file via `MDCACertificateFile`, also set the
           libcurl option CURLSSLOPT_NO_REVOKE that suppresses complains by Schannel
           (when curl is linked with it) about missing CRL/OCSP in certificates.
         - Fixed handling of corrupted httpd.json and added test 300_30 for it.
           File is removed on error and written again. Fixes #369.
         - Added explanation in log for how to proceed when md_store.json could not be
           parsed and prevented the server start.
         - restored fixed to #336 and #337 which got lost in a sync with Apache svn
         - Add Issue Name/Uris to certificate information in md-status handler
         - MDomains with static certificate files have MDRenewMode "manual", unless
           "always" is configured.
    
      *) core: Report invalid Options= argument when parsing AllowOverride
         directives.
         Github #310 [Zhou Qingyang <zhou1615 umn.edu>]
    
      *) scoreboard/mod_http2: record durations of HTTP/2 requests.
         PR 69579 [Pierre Brochard <pierre.brochard.1982@m4x.org>]
    
    Changes with Apache 2.4.63
    
      *) mod_dav: Update redirect-carefully example BrowserMatch config
         to match more recent client versions.  PR 66148, 67039.
         [Michal Maloszewski <michal.maloszewski canonical.com>,
          Romain Tartière <romain blogreen.org>]
    
      *) mod_cache_socache: Fix possible crash on error path. PR 69358.
         [Ruediger Pluem]
    
      *) mod_ssl: Fail cleanly at startup if OpenSSL initialization fails.
         [StephenWall]
    
      *) mod_md: update to version 2.4.31
         - Improved error reporting when waiting for ACME server to verify domains
           or finalizing the order fails, e.g. times out.
         - Increasing the timeouts to wait for ACME server to verify domain names
           and issue the certificate from 30 seconds to 5 minutes.
         - Change a log level from error to debug when Stapling is enabled but a
           certificate carries no OCSP responder URL.
    
      *) mod_proxy_balancer: Fix the handling of the stickysession configuration
         parameter by the balancer manager. PR 69510
         [Yutaka Tokunou <tokunou.yutaka@fujitsu.com>]
    
      *) Add the ldap-search option to mod_authnz_ldap, allowing authorization
         to be based on arbitrary expressions that do not include the username.
         Make sure that when ldap searches are too long, we explicitly log the
         error. [Graham Leggett]
    
      *) mod_proxy: Honor parameters of ProxyPassMatch workers with substitution
         in the host name or port. PR 69233. [Yann Ylavic]
    
      *) mod_log_config: Fix merging for the "LogFormat" directive.
         PR 65222. [Michael Kaufmann <mail michael-kaufmann.ch>]
    
      *) mod_lua: Make r.ap_auth_type writable.  PR 62497.
         [Michael Osipov <michaelo apache.org>]
    
      *) mod_md: update to version 2.4.29
         - Fixed HTTP-01 challenges to not carry a final newline, as some ACME
           server fail to ignore it. [Michael Kaufmann (@mkauf)]
         - Fixed missing label+newline in server-status plain text output when
           MDStapling is enabled.
    
      *) mod_ssl: Restore support for loading PKCS#11 keys via ENGINE
         without "SSLCryptoDevice" configured.  [Joe Orton]
    
      *) mod_authnz_ldap: Fix possible memory corruption if the
         AuthLDAPSubGroupAttribute directive is configured.  [Joe Orton]  
    
      *) mod_proxy_fcgi: Don't re-encode SCRIPT_FILENAME when set via SetHandler.
         PR 69203. [Yann Ylavic]
    
      *) mod_rewrite, mod_proxy: mod_proxy to canonicalize rewritten [P] URLs,
         including "unix:" ones.  PR 69235, PR 69260.  [Yann Ylavic, Ruediger Pluem]
    
      *) mod_rewrite: Error out in case a RewriteRule in directory context uses the
         proxy, but mod_proxy is not loaded. PR 56264.
         [Christophe Jaillet, Michael Streeter <mstreeter1@gmail.com>]
    
      *) http: Remove support for Request-Range header sent by Navigator 2-3 and
         MSIE 3. [Stefan Fritsch]
    
      *) mod_rewrite: Don't require [UNC] flag to preserve a leading //
         added by applying the perdir prefix to the substitution.
         [Ruediger Pluem, Eric Covener]
    
      *) Windows: Restore the ability to "Include" configuration files on UNC
         paths. PR 69313 [Eric Covener]
    
      *) mod_proxy: Avoid AH01059 parsing error for SetHandler "unix:" URLs
         in <Location> (incomplete fix in 2.4.62). PR 69160. [Yann Ylavic]
    
      *) mod_md: update to version 2.4.28
         - When the server starts, it looks for new, staged certificates to
           activate. If the staged set of files in 'md/staging/<domain>' is messed
           up, this could prevent further renewals to happen. Now, when the staging
           set is present, but could not be activated due to an error, purge the
           whole directory. [icing]
         - Fix certificate retrieval on ACME renewal to not require a 'Location:'
           header returned by the ACME CA. This was the way it was done in ACME
           before it became an IETF standard. Let's Encrypt still supports this,
           but other CAs do not. [icing]
         - Restore compatibility with OpenSSL < 1.1. [ylavic]
    
      *) mod_tls: removed the experimental module. It now is availble standalone
         from https://github.com/icing/mod_tls. The rustls provided API is not
         stable and does not align with the httpd release cycle.
         [Stefan Eissing]
    
      *) mod_rewrite: Better question mark tracking to avoid UnsafeAllow3F.
         PR 69197. [Yann Ylavic, Eric Covener]
    
      *) mod_http2: Return connection monitoring to the event MPM when blocking
         on client updates. [Stefan Eissing, Yann Ylavic]
    
    Changes with Apache 2.4.62
    
      *) SECURITY: CVE-2024-40898: Apache HTTP Server: SSRF with
         mod_rewrite in server/vhost context on Windows (cve.mitre.org)
         SSRF in Apache HTTP Server on Windows with mod_rewrite in
         server/vhost context, allows to potentially leak NTML hashes to
         a malicious server via SSRF and malicious requests.
         Users are recommended to upgrade to version 2.4.62 which fixes
         this issue.
         Credits: Smi1e (DBAPPSecurity Ltd.)
    
      *) SECURITY: CVE-2024-40725: Apache HTTP Server: source code
         disclosure with handlers configured via AddType (cve.mitre.org)
         A partial fix for CVE-2024-39884 in the core of Apache HTTP
         Server 2.4.61 ignores some use of the legacy content-type based
         configuration of handlers. "AddType" and similar configuration,
         under some circumstances where files are requested indirectly,
         result in source code disclosure of local content. For example,
         PHP scripts may be served instead of interpreted.
         Users are recommended to upgrade to version 2.4.62, which fixes
         this issue.
    
      *) mod_proxy: Fix canonicalisation and FCGI env (PATH_INFO, SCRIPT_NAME) for
         "balancer:" URLs set via SetHandler, also allowing for "unix:" sockets
         with BalancerMember(s).  PR 69168.  [Yann Ylavic]
    
      *) mod_proxy: Avoid AH01059 parsing error for SetHandler "unix:" URLs.
         PR 69160 [Yann Ylavic]
    
      *) mod_ssl: Fix crashes in PKCS#11 ENGINE support with OpenSSL 3.2.
         [Joe Orton]
    
      *) mod_ssl: Add support for loading certs/keys from pkcs11: URIs
         via OpenSSL 3.x providers.  [Ingo Franzki <ifranzki linux.ibm.com>]
    
      *) mod_ssl: Restore SSL dumping on trace7 loglevel with OpenSSL >= 3.0.
         [Ruediger Pluem, Yann Ylavic]
    
      *) mpm_worker: Fix possible warning (AH00045) about children processes not
         terminating timely.  [Yann Ylavic]
    
    Changes with Apache 2.4.61
    
      *) SECURITY: CVE-2024-39884: Apache HTTP Server: source code
         disclosure with handlers configured via AddType (cve.mitre.org)
         A regression in the core of Apache HTTP Server 2.4.60 ignores
         some use of the legacy content-type based configuration of
         handlers.   "AddType" and similar configuration, under some
         circumstances where files are requested indirectly, result in
         source code disclosure of local content. For example, PHP
         scripts may be served instead of interpreted.
         Users are recommended to upgrade to version 2.4.61, which fixes
         this issue.
    
    Changes with Apache 2.4.60
    
      *) SECURITY: CVE-2024-39573: Apache HTTP Server: mod_rewrite proxy
         handler substitution (cve.mitre.org)
         Potential SSRF in mod_rewrite in Apache HTTP Server 2.4.59 and
         earlier allows an attacker to cause unsafe RewriteRules to
         unexpectedly setup URL's to be handled by mod_proxy.
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) SECURITY: CVE-2024-38477: Apache HTTP Server: Crash resulting in
         Denial of Service in mod_proxy via a malicious request
         (cve.mitre.org)
         null pointer dereference in mod_proxy in Apache HTTP Server
         2.4.59 and earlier allows an attacker to crash the server via a
         malicious request.
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) SECURITY: CVE-2024-38476: Apache HTTP Server may use
         exploitable/malicious backend application output to run local
         handlers via internal redirect (cve.mitre.org)
         Vulnerability in core of Apache HTTP Server 2.4.59 and earlier
         are vulnerably to information disclosure, SSRF or local script
         execution via backend applications whose response headers are
         malicious or exploitable.
    
         Note: Some legacy uses of the 'AddType' directive to connect a
         request to a handler must be ported to 'AddHandler' after this fix.
    
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) SECURITY: CVE-2024-38475: Apache HTTP Server weakness in
         mod_rewrite when first segment of substitution matches
         filesystem path. (cve.mitre.org)
         Improper escaping of output in mod_rewrite in Apache HTTP Server
         2.4.59 and earlier allows an attacker to map URLs to filesystem
         locations that are permitted to be served by the server but are
         not intentionally/directly reachable by any URL, resulting in
         code execution or source code disclosure.
         Substitutions in server context that use a backreferences or
         variables as the first segment of the substitution are affected.
         Some unsafe RewiteRules will be broken by this change and the
         rewrite flag "UnsafePrefixStat" can be used to opt back in once
         ensuring the substitution is appropriately constrained.
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) SECURITY: CVE-2024-38474: Apache HTTP Server weakness with
         encoded question marks in backreferences (cve.mitre.org)
         Substitution encoding issue in mod_rewrite in Apache HTTP Server
         2.4.59 and earlier allows attacker to execute scripts in
         directories permitted by the configuration but not directly
         reachable by any URL or source disclosure of scripts meant to
         only to be executed as CGI.
    
         Note: Some RewriteRules that capture and substitute unsafely will now
         fail unless rewrite flag "UnsafeAllow3F" is specified.
    
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) SECURITY: CVE-2024-38473: Apache HTTP Server proxy encoding
         problem (cve.mitre.org)
         Encoding problem in mod_proxy in Apache HTTP Server 2.4.59 and
         earlier allows request URLs with incorrect encoding to be sent
         to backend services, potentially bypassing authentication via
         crafted requests.
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) SECURITY: CVE-2024-38472: Apache HTTP Server on Windows UNC SSRF
         (cve.mitre.org)
         SSRF in Apache HTTP Server on Windows allows to potentially leak
         NTML hashes to a malicious server via SSRF and malicious
         requests or content
    
         Note: Existing configurations that access UNC paths
         will have to configure new directive "UNCList" to allow access
         during request processing.
    
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) SECURITY: CVE-2024-36387: Apache HTTP Server: DoS by Null
         pointer in websocket over HTTP/2 (cve.mitre.org)
         Serving WebSocket protocol upgrades over a HTTP/2 connection
         could result in a Null Pointer dereference, leading to a crash
         of the server process, degrading performance.
         Credits: Marc Stern (<marc.stern AT approach-cyber.com>)
    
      *) mod_proxy: Fix DNS requests and connections closed before the
         configured addressTTL.  PR 69126.  [Yann Ylavic]
    
      *) core: On Linux, log the real thread ID in error logs.  [Joe Orton]
    
      *) core: Support zone/scope in IPv6 link-local addresses in Listen and
         VirtualHost directives (requires APR 1.7.x or later).  PR 59396
         [Joe Orton]
    
      *) mod_ssl: Reject client-initiated renegotiation with a TLS alert
         (rather than connection closure).  [Joe Orton, Yann Ylavic]
    
      *) Updated mime.types.  [Mohamed Akram <mohd.akram outlook.com>,
         Adam Silverstein <adamsilverstein earthboundhosting.com>]
    
      *) mod_ssl: Fix a regression that causes the default DH parameters for a key
         no longer set and thus effectively disabling DH ciphers when no explicit
         DH parameters are set. PR 68863 [Ruediger Pluem]
    
      *) mod_cgid: Optional support for file descriptor passing, fixing
         error log handling (configure --enable-cgid-fdpassing) on Unix
         platforms. PR 54221.  [Joe Orton]
    
      *) mod_cgid/mod_cgi: Distinguish script stderr output clearly in
         error logs.  PR 61980.  [Hank Ibell <hwibell gmail.com>]
    
      *) mod_tls: update version of rustls-ffi to v0.13.0.
         [Daniel McCarney (@cpu}]
    
      *) mod_md:
         - Using OCSP stapling information to trigger certificate renewals. Proposed
           by @frasertweedale.
         - Added directive `MDCheckInterval` to control how often the server checks
           for detected revocations. Added proposals for configurations in the
           README.md chapter "Revocations".
         - OCSP stapling: accept OCSP responses without a `nextUpdate` entry which is
           allowed in RFC 6960. Treat those as having an update interval of 12 hours.
           Added by @frasertweedale.
         - Adapt OpenSSL usage to changes in their API. By Yann Ylavic.
    
    Changes with Apache 2.4.59
    
      *) SECURITY: CVE-2024-27316: Apache HTTP Server: HTTP/2 DoS by
         memory exhaustion on endless continuation frames (cve.mitre.org)
         HTTP/2 incoming headers exceeding the limit are temporarily
         buffered in nghttp2 in order to generate an informative HTTP 413
         response. If a client does not stop sending headers, this leads
         to memory exhaustion.
         Credits: Bartek Nowotarski (https://nowotarski.info/)
    
      *) SECURITY: CVE-2024-24795: Apache HTTP Server: HTTP Response
         Splitting in multiple modules (cve.mitre.org)
         HTTP Response splitting in multiple modules in Apache HTTP
         Server allows an attacker that can inject malicious response
         headers into backend applications to cause an HTTP
         desynchronization attack.
    
         After this change, CGI-like scripts cannot set Transfer-Encoding
         or Content-Length headers.  To restore the ability to set Content-Length
         header, set per-request environment variable 'ap_trust_cgilike_cl' to any
         non-empty value.
    
         Credits: Keran Mu, Tsinghua University and Zhongguancun
         Laboratory.
    
      *) SECURITY: CVE-2023-38709: Apache HTTP Server: HTTP response
         splitting (cve.mitre.org)
         Faulty input validation in the core of Apache allows malicious
         or exploitable backend/content generators to split HTTP
         responses.
         This issue affects Apache HTTP Server: through 2.4.58.
         Credits: Orange Tsai (@orange_8361) from DEVCORE
    
      *) mod_deflate: Fixes and better logging for handling various
         error and edge cases. [Eric Covener, Yann Ylavic, Joe Orton,
         Eric Norris <enorris etsy.com>]
    
      *) Add CGIScriptTimeout to mod_cgi. [Eric Covener]
    
      *) mod_xml2enc: Tolerate libxml2 2.12.0 and later.  PR 68610
         [ttachi <tachihara AT hotmail.com>]
    
      *) mod_slotmem_shm: Use ap_os_is_path_absolute() to make it portable.
         [Jean-Frederic Clere]
    
      *) mod_ssl: Use OpenSSL-standard functions to assemble CA
         name lists for SSLCACertificatePath/SSLCADNRequestPath.
         Names will now be consistently sorted. PR 61574.
         [Joe Orton]
    
      *) mod_xml2enc: Update check to accept any text/ media type
         or any XML media type per RFC 7303, avoiding
         corruption of Microsoft OOXML formats.  PR 64339.
         [Joseph Heenan <joseph.heenan fintechlabs.io>, Joe Orton]
    
      *) mod_http2: v2.0.26 with the following fixes:
         - Fixed `Date` header on requests upgraded from HTTP/1.1 (h2c). Fixes
           <https://github.com/icing/mod_h2/issues/272>.
         - Fixed small memory leak in h2 header bucket free. Thanks to
           Michael Kaufmann for finding this and providing the fix.
    
      *) htcacheclean: In -a/-A mode, list all files per subdirectory
         rather than only one. PR 65091.
         [Artem Egorenkov <aegorenkov.91 gmail.com>]
    
      *) mod_ssl: SSLProxyMachineCertificateFile/Path may reference files
         which include CA certificates; those CA certs are treated as if
         configured with SSLProxyMachineCertificateChainFile.  [Joe Orton]
    
      *) htpasswd, htdbm, dbmmanage: Update help&docs to refer to
         "hashing", rather than "encrypting" passwords.
         [Michele Preziuso <mpreziuso kaosdynamics.com>]
    
      *) mod_ssl: Fix build with LibreSSL 2.0.7+. PR 64047.
         [Giovanni Bechis, Yann Ylavic]
    
      *) htpasswd: Add support for passwords using SHA-2.  [Joe Orton,
         Yann Ylavic]
    
      *) core: Allow mod_env to override system environment vars. [Joe Orton]
    
      *) Allow mod_dav_fs to tolerate race conditions between PROPFIND and an
         operation which removes a directory/file between apr_dir_read() and
         apr_stat(). Current behaviour is to abort the connection which seems
         inferior to tolerating (and logging) the error. [Joe Orton]
    
      *) mod_ldap: HTML-escape data in the ldap-status handler.
         [Eric Covener, Chamal De Silva]
    
      *) mod_ssl: Disable the OpenSSL ENGINE API when OPENSSL_NO_ENGINE is set.
         Allow for "SSLCryptoDevice builtin" if the ENGINE API is not available,
         notably with OpenSSL >= 3.  PR 68080.  [Yann Ylavic, Joe Orton]
    
      *) mod_ssl: Improve compatibility with OpenSSL 3, fix build warnings about
         deprecated ENGINE_ API, honor OPENSSL_API_COMPAT setting while defaulting
         to compatibitily with version 1.1.1 (including ENGINEs / SSLCryptoDevice).
         [Yann Ylavic]
    
      *) mod_ssl: release memory to the OS when needed. [Giovanni Bechis]
    
      *) mod_proxy: Ignore (and warn about) enablereuse=on for ProxyPassMatch when
         some dollar substitution (backreference) happens in the hostname or port
         part of the URL.  [Yann Ylavic]
    
      *) mod_proxy: Allow to set a TTL for how long DNS resolutions to backend
         systems are cached. [Yann Ylavic]
    
      *) mod_proxy: Add optional third argument for ProxyRemote, which
         configures Basic authentication credentials to pass to the remote
         proxy.  PR 37355.  [Joe Orton]
    
    Changes with Apache 2.4.58
    
      *) SECURITY: CVE-2023-45802: Apache HTTP Server: HTTP/2 stream
         memory not reclaimed right away on RST (cve.mitre.org)
         When a HTTP/2 stream was reset (RST frame) by a client, there
         was a time window were the request's memory resources were not
         reclaimed immediately. Instead, de-allocation was deferred to
         connection close. A client could send new requests and resets,
         keeping the connection busy and open and causing the memory
         footprint to keep on growing. On connection close, all resources
         were reclaimed, but the process might run out of memory before
         that.
         This was found by the reporter during testing of CVE-2023-44487
         (HTTP/2 Rapid Reset Exploit) with their own test client. During
         "normal" HTTP/2 use, the probability to hit this bug is very
         low. The kept memory would not become noticeable before the
         connection closes or times out.
         Users are recommended to upgrade to version 2.4.58, which fixes
         the issue.
         Credits: Will Dormann of Vul Labs
    
      *) SECURITY: CVE-2023-43622: Apache HTTP Server: DoS in HTTP/2 with
         initial windows size 0 (cve.mitre.org)
         An attacker, opening a HTTP/2 connection with an initial window
         size of 0, was able to block handling of that connection
         indefinitely in Apache HTTP Server. This could be used to
         exhaust worker resources in the server, similar to the well
         known "slow loris" attack pattern.
         This has been fixed in version 2.4.58, so that such connection
         are terminated properly after the configured connection timeout.
         This issue affects Apache HTTP Server: from 2.4.55 through
         2.4.57.
         Users are recommended to upgrade to version 2.4.58, which fixes
         the issue.
         Credits: Prof. Sven Dietrich (City University of New York)
    
      *) SECURITY: CVE-2023-31122: mod_macro buffer over-read
         (cve.mitre.org)
         Out-of-bounds Read vulnerability in mod_macro of Apache HTTP
         Server.This issue affects Apache HTTP Server: through 2.4.57.
         Credits: David Shoon (github/davidshoon)
    
      *) mod_ssl: Silence info log message "SSL Library Error: error:0A000126:
         SSL routines::unexpected eof while reading" when using
         OpenSSL 3 by setting SSL_OP_IGNORE_UNEXPECTED_EOF if
         available. [Rainer Jung]
    
      *) mod_http2: improved early cleanup of streams.
         [Stefan Eissing]
    
      *) mod_proxy_http2: improved error handling on connection errors while
         response is already underway.
         [Stefan Eissing]
    
      *) mod_http2: fixed a bug that could lead to a crash in main connection
         output handling. This occured only when the last request on a HTTP/2
         connection had been processed and the session decided to shut down.
         This could lead to an attempt to send a final GOAWAY while the previous
         write was still in progress. See PR 66646.
         [Stefan Eissing]
    
      *) mod_proxy_http2: fix `X-Forward-Host` header to carry the correct value.
         Fixes PR66752.
         [Stefan Eissing]
    
      *) mod_http2: added support for bootstrapping WebSockets via HTTP/2, as
         described in RFC 8441. A new directive 'H2WebSockets on|off' has been
         added. The feature is by default not enabled.
         As also discussed in the manual, this feature should work for setups
         using "ProxyPass backend-url upgrade=websocket" without further changes.
         Special server modules for WebSockets will have to be adapted,
         most likely, as the handling if IO events is different with HTTP/2.
         HTTP/2 WebSockets are supported on platforms with native pipes. This
         excludes Windows.
         [Stefan Eissing]
    
      *) mod_rewrite: Fix a regression with both a trailing ? and [QSA].
         in OCSP stapling. PR 66672. [Frank Meier <frank.meier ergon.ch>, covener]
    
      *) mod_http2: fixed a bug in flushing pending data on an already closed
         connection that could lead to a busy loop, preventing the HTTP/2 session
         to close down successfully. Fixed PR 66624.
         [Stefan Eissing]
    
      *) mod_http2: v2.0.15 with the following fixes and improvements
         - New directive 'H2EarlyHint name value' to add headers to a response,
           picked up already when a "103 Early Hints" response is sent. 'name' and
           'value' must comply to the HTTP field restrictions.
           This directive can be repeated several times and header fields of the
           same names add. Sending a 'Link' header with 'preload' relation will
           also cause a HTTP/2 PUSH if enabled and supported by the client.
         - Fixed an issue where requests were not logged and accounted in a timely
           fashion when the connection returns to "keepalive" handling, e.g. when
           the request served was the last outstanding one.
           This led to late appearance in access logs with wrong duration times
           reported.
         - Accurately report the bytes sent for a request in the '%O' Log format.
           This addresses #203, a long outstanding issue where mod_h2 has reported
           numbers over-eagerly from internal buffering and not what has actually
           been placed on the connection.
           The numbers are now the same with and without H2CopyFiles enabled.
         [Stefan Eissing]
    
      *) mod_proxy_http2: fix retry handling to not leak temporary errors.
         On detecting that that an existing connection was shutdown by the other
         side, a 503 response leaked even though the request was retried on a
         fresh connection.
         [Stefan Eissing]
    
      *) mod_rewrite: Add server directory to include path as mod_rewrite requires
         test_char.h. PR 66571 [Valeria Petrov <valeria.petrov@spinetix.com>]
    
      *) mod_http2: new directive `H2ProxyRequests on|off` to enable handling
         of HTTP/2 requests in a forward proxy configuration.
         General forward proxying is enabled via `ProxyRequests`. If the
         HTTP/2 protocol is also enabled for such a server/host, this new
         directive is needed in addition.
         [Stefan Eissing]
    
      *) core: Updated conf/mime.types:
         - .js moved from 'application/javascript' to 'text/javascript'
         - .mjs was added as 'text/javascript'
         - add .opus ('audio/ogg')
         - add 'application/vnd.geogebra.slides'
         - add WebAssembly MIME types and extension
         [Mathias Bynens <@mathiasbynens> via PR 318,
          Richard de Boer <richard tubul.net>, Dave Hodder <dmh dmh.org.uk>,
          Zbynek Konecny <zbynek1729 gmail.com>]
    
      *) mod_proxy_http2: fixed using the wrong "bucket_alloc" from the backend
         connection when sending data on the frontend one. This caused crashes
         or infinite loops in rare situations.
      *) mod_proxy_http2: fixed a bug in retry/response handling that could lead
         to wrong status codes or HTTP messages send at the end of response bodies
         exceeding the announced content-length.
      *) mod_proxy_http2: fix retry handling to not leak temporary errors.
         On detecting that that an existing connection was shutdown by the other
         side, a 503 response leaked even though the request was retried on a
         fresh connection.
      *) mod_http2: fixed a bug that did cleanup of consumed and pending buckets in
         the wrong order when a bucket_beam was destroyed.
         [Stefan Eissing]
    
      *) mod_http2: avoid double chunked-encoding on internal redirects.
         PR 66597 [Yann Ylavic, Stefan Eissing]
    
      *) mod_http2: Fix reporting of `Total Accesses` in server-status to not count
         HTTP/2 requests twice. Fixes PR 66801.
         [Stefan Eissing]
    
      *) mod_ssl: Fix handling of Certificate Revoked messages
         in OCSP stapling. PR 66626. [<gmoniker gmail.com>]
    
      *) mod_http2: fixed a bug in handling of stream timeouts.
         [Stefan Eissing]
    
      *) mod_tls: updating to rustls-ffi version 0.9.2 or higher.
         Checking in configure for proper version installed. Code
         fixes for changed clienthello member name.
         [Stefan Eissing]
    
      *) mod_md:
         - New directive `MDMatchNames all|servernames` to allow more control over how
           MDomains are matched to VirtualHosts.
         - New directive `MDChallengeDns01Version`. Setting this to `2` will provide
           the command also with the challenge value on `teardown` invocation. In version
           1, the default, only the `setup` invocation gets this parameter.
           Refs #312. Thanks to @domrim for the idea.
         - For Managed Domain in "manual" mode, the checks if all used ServerName and
           ServerAlias are part of the MDomain now reports a warning instead of an error
           (AH10040) when not all names are present.
         - MDChallengeDns01 can now be configured for individual domains.
           Using PR from Jérôme Billiras (@bilhackmac) and adding test case and fixing proper working
         - Fixed a bug found by Jérôme Billiras (@bilhackmac) that caused the challenge
           teardown not being invoked as it should.
    
      *) mod_ldap: Avoid performance overhead of APR-util rebind cache for
         OpenLDAP 2.2+.  PR 64414.  [Joe Orton]
    
      *) mod_http2: new directive 'H2MaxDataFrameLen n' to limit the maximum
         amount of response body bytes put into a single HTTP/2 DATA frame.
         Setting this to 0 places no limit (but the max size allowed by the
         protocol is observed).
         The module, by default, tries to use the maximum size possible, which is
         somewhat around 16KB. This sets the maximum. When less response data is
         available, smaller frames will be sent.
    
      *) mod_md: fixed passing of the server environment variables to programs
         started via MDMessageCmd and MDChallengeDns01 on *nix system.
         See <https://github.com/icing/mod_md/issues/319>.
         [Stefan Eissing]
    
      *) mod_dav: Add DavBasePath directive to configure the repository root
         path.  PR 35077.  [Joe Orton]
    
      *) mod_alias: Add AliasPreservePath directive to map the full
         path after the alias in a location. [Graham Leggett]
    
      *) mod_alias: Add RedirectRelative to allow relative redirect targets to be
         issued as-is. [Eric Covener, Graham Leggett]
    
      *) core: Add formats %{z} and %{strftime-format} to ErrorLogFormat, and make
         sure that if the format is configured early enough it applies to every log
         line.  PR 62161.  [Yann Ylavic]
    
      *) mod_deflate: Add DeflateAlterETag to control how the ETag
         is modified. The 'NoChange' parameter mimics 2.2.x behavior.
         PR 45023, PR 39727. [Eric Covener]
    
      *) core: Optimize send_brigade_nonblocking(). [Yann Ylavic, Christophe Jaillet]
    
      *) mod_status: Remove duplicate keys "BusyWorkers" and "IdleWorkers".
         Resolve inconsistency between the previous two occurrences by
         counting workers in state SERVER_GRACEFUL no longer as busy,
         but instead in a new counter "GracefulWorkers" (or on HTML
         view as "workers gracefully restarting"). Also add the graceful
         counter as a new column to the existing HTML per process table
         for async MPMs. PR 63300. [Rainer Jung]
    
    Changes with Apache 2.4.57
    
      *) mod_proxy: Check before forwarding that a nocanon path has not been
         rewritten with spaces during processing.  [Yann Ylavic]
    
      *) mod_proxy: In case that AllowEncodedSlashes is set to NoDecode do not
         double encode encoded slashes in the URL sent by the reverse proxy to the
         backend. [Ruediger Pluem]
    
      *) mod_http2: fixed a crash during connection termination. See PR 66539.
         [Stefan Eissing]
    
      *) mod_rewrite: Fix a 2.4.56 regression for substitutions ending
         in a question mark. PR66547. [Eric Covener]
    
      *) mod_rewrite: Add "BCTLS" and "BNE" RewriteRule flags. Re-allow encoded
         characters on redirections without the "NE" flag. 
         [Yann Ylavic, Eric Covener]
    
      *) mod_proxy: Fix double encoding of the uri-path of the request forwarded
         to the origin server, when using mapping=encoded|servlet.  [Yann Ylavic]
    
      *) mod_mime: Do not match the extention against possible query string
         parameters in case ProxyPass was used with the nocanon option.
         [Ruediger Pluem]
    
    Changes with Apache 2.4.56
    
      *) SECURITY: CVE-2023-27522: Apache HTTP Server: mod_proxy_uwsgi
         HTTP response splitting (cve.mitre.org)
         HTTP Response Smuggling vulnerability in Apache HTTP Server via
         mod_proxy_uwsgi. This issue affects Apache HTTP Server: from
         2.4.30 through 2.4.55.
         Special characters in the origin response header can
         truncate/split the response forwarded to the client.
         Credits: Dimas Fariski Setyawan Putra (nyxsorcerer)
    
      *) SECURITY: CVE-2023-25690: HTTP request splitting with
         mod_rewrite and mod_proxy (cve.mitre.org)
         Some mod_proxy configurations on Apache HTTP Server versions
         2.4.0 through 2.4.55 allow a HTTP Request Smuggling attack.
         Configurations are affected when mod_proxy is enabled along with
         some form of RewriteRule or ProxyPassMatch in which a non-specific
         pattern matches some portion of the user-supplied request-target (URL)
         data and is then re-inserted into the proxied request-target
         using variable substitution. For example, something like:
            RewriteEngine on
            RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
            ProxyPassReverse /here/  http://example.com:8080/
         Request splitting/smuggling could result in bypass of access
         controls in the proxy server, proxying unintended URLs to
         existing origin servers, and cache poisoning.
         Credits: Lars Krapf of Adobe
    
      *) rotatelogs: Add -T flag to allow subsequent rotated logfiles to be
         truncated without the initial logfile being truncated.  [Eric Covener]
    
      *) mod_ldap: LDAPConnectionPoolTTL should accept negative values in order to
         allow connections of any age to be reused. Up to now, a negative value
         was handled as an error when parsing the configuration file.  PR 66421.
         [nailyk <bzapache nailyk.fr>, Christophe Jaillet]
    
      *) mod_proxy_ajp: Report an error if the AJP backend sends an invalid number
         of headers. [Ruediger Pluem]
    
      *) mod_md:
         - Enabling ED25519 support and certificate transparency information when
           building with libressl v3.5.0 and newer. Thanks to Giovanni Bechis.
         - MDChallengeDns01 can now be configured for individual domains.
           Thanks to Jérôme Billiras (@bilhackmac) for the initial PR.
         - Fixed a bug found by Jérôme Billiras (@bilhackmac) that caused the challenge
           teardown not being invoked as it should.
         [Stefan Eissing]
    
      *) mod_http2: client resets of HTTP/2 streams led to unwanted 500 errors
         reported in access logs and error documents. The processing of the
         reset was correct, only unneccesary reporting was caused.
         [Stefan Eissing]
    
      *) mod_proxy_uwsgi: Stricter backend HTTP response parsing/validation.
         [Yann Ylavic]
    
    Changes with Apache 2.4.55
    
      *) SECURITY: CVE-2022-37436: Apache HTTP Server: mod_proxy prior to
         2.4.55 allows a backend to trigger HTTP response splitting
         (cve.mitre.org)
         Prior to Apache HTTP Server 2.4.55, a malicious backend can
         cause the response headers to be truncated early, resulting in
         some headers being incorporated into the response body. If the
         later headers have any security purpose, they will not be
         interpreted by the client.
         Credits: Dimas Fariski Setyawan Putra (@nyxsorcerer)
    
      *) SECURITY: CVE-2022-36760: Apache HTTP Server: mod_proxy_ajp
         Possible request smuggling (cve.mitre.org)
         Inconsistent Interpretation of HTTP Requests ('HTTP Request
         Smuggling') vulnerability in mod_proxy_ajp of Apache HTTP Server
         allows an attacker to smuggle requests to the AJP server it
         forwards requests to.  This issue affects Apache HTTP Server
         Apache HTTP Server 2.4 version 2.4.54 and prior versions.
         Credits: ZeddYu_Lu from Qi'anxin Research Institute of Legendsec
         at Qi'anxin Group
    
      *) SECURITY: CVE-2006-20001: mod_dav out of  bounds read, or write
         of zero byte (cve.mitre.org)
         A carefully crafted If: request header can cause a memory read,
         or write of a single zero byte, in a pool (heap) memory location
         beyond the header value sent. This could cause the process to
         crash.
         This issue affects Apache HTTP Server 2.4.54 and earlier.
    
      *) mod_dav: Open the lock database read-only when possible.
         PR 36636 [Wilson Felipe <wfelipe gmail.com>, manu]
    
      *) mod_proxy_http2: apply the standard httpd content type handling
         to responses from the backend, as other proxy modules do. Fixes PR 66391.
         Thanks to Jérôme Billiras for providing the patch.
         [Stefan Eissing]
    
      *) mod_dav: mod_dav overrides dav_fs response on PUT failure. PR 35981
         [Basant Kumar Kukreja <basant.kukreja sun.com>, Alejandro Alvarez
         <alejandro.alvarez.ayllon cern.ch>]
    
      *) mod_proxy_hcheck: Honor worker timeout settings.  [Yann Ylavic]
    
      *) mod_http2: version 2.0.11 of the module, synchronizing changes
         with the gitgub version. This is a partial rewrite of how connections
         and streams are handled.
         - an APR pollset and pipes (where supported) are used to monitor
           the main connection and react to IO for request/response handling.
           This replaces the stuttered timed waits of earlier versions.
         - H2SerializeHeaders directive still exists, but has no longer an effect.
         - Clients that seemingly misbehave still get less resources allocated,
           but ongoing requests are no longer disrupted.
         - Fixed an issue since 1.15.24 that "Server" headers in proxied requests
           were overwritten instead of preserved. [PR by @daum3ns]
         - A regression in v1.15.24 was fixed that could lead to httpd child
           processes not being terminated on a graceful reload or when reaching
           MaxConnectionsPerChild. When unprocessed h2 requests were queued at
           the time, these could stall. See #212.
         - Improved information displayed in 'server-status' for H2 connections when
           Extended Status is enabled. Now one can see the last request that IO
           operations happened on and transferred IO stats are updated as well.
         - When reaching server limits, such as MaxRequestsPerChild, the HTTP/2 connection
           send a GOAWAY frame much too early on new connections, leading to invalid
           protocol state and a client failing the request. See PR65731 at
           <https://bz.apache.org/bugzilla/show_bug.cgi?id=65731>.
           The module now initializes the HTTP/2 protocol correctly and allows the
           client to submit one request before the shutdown via a GOAWAY frame
           is being announced.
         - :scheme pseudo-header values, not matching the
           connection scheme, are forwarded via absolute uris to the
           http protocol processing to preserve semantics of the request.
           Checks on combinations of pseudo-headers values/absence
           have been added as described in RFC 7540. Fixes #230.
         - A bug that prevented trailers (e.g. HEADER frame at the end) to be
           generated in certain cases was fixed. See #233 where it prevented
           gRPC responses to be properly generated.
         - Request and response header values are automatically stripped of leading
           and trialing space/tab characters. This is equivalent behaviour to what
           Apache httpd's http/1.1 parser does.
           The checks for this in nghttp2 v1.50.0+ are disabled.
         - Extensive testing in production done by Alessandro Bianchi (@alexskynet)
           on the v2.0.x versions for stability. Many thanks!
    
      *) mod_proxy_http2: fixed #235 by no longer forwarding 'Host:' header when
         request ':authority' is known. Improved test case that did not catch that
         the previous 'fix' was incorrect.
    
      *) mod_proxy_hcheck: hcmethod now allows for HTTP/1.1 requests
         using GET11, HEAD11 and/or OPTIONS11. [Jim Jagielski]
    
      *) mod_proxy: The AH03408 warning for a forcibly closed backend
         connection is now logged at INFO level.  [Yann Ylavic]
    
      *) mod_ssl: When dumping the configuration, the existence of
         certificate/key files is no longer tested.  [Joe Orton]
    
      *) mod_authn_core: Add expression support to AuthName and AuthType.
         [Graham Leggett]
    
      *) mod_ssl: when a proxy connection had handled a request using SSL, an
         error was logged when "SSLProxyEngine" was only configured in the
         location/proxy section and not the overall server. The connection
         continued to work, the error log was in error. Fixed PR66190.
         [Stefan Eissing]
    
      *) mod_proxy_hcheck: Re-enable workers in standard ERROR state. PR 66302.
         [Alessandro Cavaliere <alessandro.cavalier7 unibo.it>]
    
      *) mod_proxy_hcheck: Detect AJP/CPING support correctly. PR 66300.
         [Alessandro Cavaliere <alessandro.cavalier7 unibo.it>]
    
      *) mod_http2: Export mod_http2.h as public header. [Stefan Eissing]
    
      *) mod_md: a new directive `MDStoreLocks` can be used on cluster
         setups with a shared file system for `MDStoreDir` to order
         activation of renewed certificates when several cluster nodes are
         restarted at the same time. Store locks are not enabled by default.
         Restored curl_easy cleanup behaviour from v2.4.14 and refactored
         the use of curl_multi for OCSP requests to work with that.
         Fixes <https://github.com/icing/mod_md/issues/293>.
    
      *) core: Avoid an overflow on large inputs in ap_is_matchexp.  PR 66033
         [Ruediger Pluem]
    
      *) mod_heartmonitor: Allow "HeartbeatMaxServers 0" to use file based
         storage instead of slotmem. Needed after setting
         HeartbeatMaxServers default to the documented value 10 in 2.4.54.
         PR 66131.  [Jérôme Billiras]
    
      *) mod_dav: DAVlockDiscovery option to disable WebDAV lock discovery
         This is a game changer for performances if client use PROPFIND a lot,
         PR 66313. [Emmanuel Dreyfus]
    
    Changes with Apache 2.4.54
    
      *) SECURITY: CVE-2022-31813: mod_proxy X-Forwarded-For dropped by
         hop-by-hop mechanism (cve.mitre.org)
         Apache HTTP Server 2.4.53 and earlier may not send the
         X-Forwarded-* headers to the origin server based on client side
         Connection header hop-by-hop mechanism.
         This may be used to bypass IP based authentication on the origin
         server/application.
         Credits: The Apache HTTP Server project would like to thank
         Gaetan Ferry (Synacktiv) for reporting this issue
    
      *) SECURITY: CVE-2022-30556: Information Disclosure in mod_lua with
         websockets (cve.mitre.org)
         Apache HTTP Server 2.4.53 and earlier may return lengths to
         applications calling r:wsread() that point past the end of the
         storage allocated for the buffer.
         Credits: The Apache HTTP Server project would like to thank
         Ronald Crane (Zippenhop LLC) for reporting this issue
    
      *) SECURITY: CVE-2022-30522: mod_sed denial of service
         (cve.mitre.org)
         If Apache HTTP Server 2.4.53 is configured to do transformations
         with mod_sed in contexts where the input to mod_sed may be very
         large, mod_sed may make excessively large memory allocations and
         trigger an abort.
         Credits: This issue was found by Brian Moussalli from the JFrog
         Security Research team
    
      *) SECURITY: CVE-2022-29404: Denial of service in mod_lua
         r:parsebody (cve.mitre.org)
         In Apache HTTP Server 2.4.53 and earlier, a malicious request to
         a lua script that calls r:parsebody(0) may cause a denial of
         service due to no default limit on possible input size.
         Credits: The Apache HTTP Server project would like to thank
         Ronald Crane (Zippenhop LLC) for reporting this issue
    
      *) SECURITY: CVE-2022-28615: Read beyond bounds in
         ap_strcmp_match() (cve.mitre.org)
         Apache HTTP Server 2.4.53 and earlier may crash or disclose
         information due to a read beyond bounds in ap_strcmp_match()
         when provided with an extremely large input buffer.  While no
         code distributed with the server can be coerced into such a
         call, third-party modules or lua scripts that use
         ap_strcmp_match() may hypothetically be affected.
         Credits: The Apache HTTP Server project would like to thank
         Ronald Crane (Zippenhop LLC) for reporting this issue
    
      *) SECURITY: CVE-2022-28614: read beyond bounds via ap_rwrite()
         (cve.mitre.org)
         The ap_rwrite() function in Apache HTTP Server 2.4.53 and
         earlier may read unintended memory if an attacker can cause the
         server to reflect very large input using ap_rwrite() or
         ap_rputs(), such as with mod_luas r:puts() function.
         Credits: The Apache HTTP Server project would like to thank
         Ronald Crane (Zippenhop LLC) for reporting this issue
    
      *) SECURITY: CVE-2022-28330: read beyond bounds in mod_isapi
         (cve.mitre.org)
         Apache HTTP Server 2.4.53 and earlier on Windows may read beyond
         bounds when configured to process requests with the mod_isapi
         module.
         Credits: The Apache HTTP Server project would like to thank
         Ronald Crane (Zippenhop LLC) for reporting this issue
    
      *) SECURITY: CVE-2022-26377: mod_proxy_ajp: Possible request
         smuggling (cve.mitre.org)
         Inconsistent Interpretation of HTTP Requests ('HTTP Request
         Smuggling') vulnerability in mod_proxy_ajp of Apache HTTP Server
         allows an attacker to smuggle requests to the AJP server it
         forwards requests to.  This issue affects Apache HTTP Server
         Apache HTTP Server 2.4 version 2.4.53 and prior versions.
         Credits: Ricter Z @ 360 Noah Lab
    
      *) mod_ssl: SSLFIPS compatible with OpenSSL 3.0.  PR 66063.
         [Petr Sumbera <petr.sumbera oracle.com>, Yann Ylavic]
    
      *) mod_proxy_http: Avoid 417 responses for non forwardable 100-continue.
         PR 65666.  [Yann Ylavic]
    
      *) mod_md:  a bug was fixed that caused very large MDomains
         with the combined DNS names exceeding ~7k to fail, as
         request bodies would contain partially wrong data from
         uninitialized memory. This would have appeared as failure
         in signing-up/renewing such configurations.
         [Stefan Eissing, Ronald Crane (Zippenhop LLC)]
    
      *) mod_proxy_http: Avoid 417 responses for non forwardable 100-continue.
         PR 65666.  [Yann Ylavic]
    
      *) MPM event: Restart children processes killed before idle maintenance.
         PR 65769.  [Yann Ylavic, Ruediger Pluem]
    
      *) ab: Allow for TLSv1.3 when the SSL library supports it.
         [abhilash1232 gmail.com, xiaolongx.jiang intel.com, Yann Ylavic]
    
      *) core: Disable TCP_NOPUSH optimization on OSX since it might introduce
         transmission delays.  PR 66019.  [Yann Ylavic]
    
      *) MPM event: Fix accounting of active/total processes on ungraceful restart,
         PR 66004 (follow up to PR 65626 from 2.4.52).  [Yann Ylavic]
    
      *) core: make ap_escape_quotes() work correctly on strings
         with more than MAX_INT/2 characters, counting quotes double.
         Credit to <generalbugs@zippenhop.com> for finding this.
         [Stefan Eissing]
    
      *) mod_md: the `MDCertificateAuthority` directive can take more than one URL/name of
         an ACME CA. This gives a failover for renewals when several consecutive attempts
         to get a certificate failed.
         A new directive was added: `MDRetryDelay` sets the delay of retries.
         A new directive was added: `MDRetryFailover` sets the number of errored
         attempts before an alternate CA is selected for certificate renewals.
         [Stefan Eissing]
    
      *) mod_http2: remove unused and insecure code. Fixes PR66037.
         Thanks to Ronald Crane (Zippenhop LLC) for reporting this.
         [Stefan Eissing]
    
      *) mod_proxy: Add backend port to log messages to
         ease identification of involved service.  [Rainer Jung]
    
      *) mod_http2: removing unscheduling of ongoing tasks when
         connection shows potential abuse by a client. This proved
         counter-productive and the abuse detection can false flag
         requests using server-side-events.
         Fixes <https://github.com/icing/mod_h2/issues/231>.
         [Stefan Eissing]
    
      *) mod_md: Implement full auto status ("key: value" type status output).
         Especially not only status summary counts for certificates and
         OCSP stapling but also lists. Auto status format is similar to
         what was used for mod_proxy_balancer.
         [Rainer Jung]
    
      *) mod_md: fixed a bug leading to failed transfers for OCSP
         stapling information when more than 6 certificates needed
         updates in the same run.  [Stefan Eissing]
    
      *) mod_proxy: Set a status code of 502 in case the backend just closed the
         connection in reply to our forwarded request.  [Ruediger Pluem]
    
      *) mod_md: a possible NULL pointer deref was fixed in
         the JSON code for persisting time periods (start+end).
         Fixes #282 on mod_md's github.
         Thanks to @marcstern for finding this.  [Stefan Eissing]
    
      *) mod_heartmonitor: Set the documented default value
         "10" for HeartbeatMaxServers instead of "0". With "0"
         no shared memory slotmem was initialized.  [Rainer Jung]
    
      *) mod_md: added support for managing certificates via a
         local tailscale daemon for users of that secure networking.
         This gives trusted certificates for tailscale assigned
         domain names in the *.ts.net space.
         [Stefan Eissing]
    
      *) core: Change default value of LimitRequestBody from 0 (unlimited)
         to 1GB. [Eric Covener]
    
    Changes with Apache 2.4.53
    
      *) SECURITY: CVE-2022-23943: mod_sed: Read/write beyond bounds
         (cve.mitre.org)
         Out-of-bounds Write vulnerability in mod_sed of Apache HTTP
         Server allows an attacker to overwrite heap memory with possibly
         attacker provided data.
         This issue affects Apache HTTP Server 2.4 version 2.4.52 and
         prior versions.
         Credits: Ronald Crane (Zippenhop LLC)
    
      *) SECURITY: CVE-2022-22721: core: Possible buffer overflow with
         very large or unlimited LimitXMLRequestBody (cve.mitre.org)
         If LimitXMLRequestBody is set to allow request bodies larger
         than 350MB (defaults to 1M) on 32 bit systems an integer
         overflow happens which later causes out of bounds writes.
         This issue affects Apache HTTP Server 2.4.52 and earlier.
         Credits: Anonymous working with Trend Micro Zero Day Initiative
    
      *) SECURITY: CVE-2022-22720: HTTP request smuggling vulnerability
         in Apache HTTP Server 2.4.52 and earlier (cve.mitre.org)
         Apache HTTP Server 2.4.52 and earlier fails to close inbound
         connection when errors are encountered discarding the request
         body, exposing the server to HTTP Request Smuggling
         Credits: James Kettle <james.kettle portswigger.net>
    
      *) SECURITY: CVE-2022-22719: mod_lua Use of uninitialized value of
         in r:parsebody (cve.mitre.org)
         A carefully crafted request body can cause a read to a random
         memory area which could cause the process to crash.
         This issue affects Apache HTTP Server 2.4.52 and earlier.
         Credits: Chamal De Silva
    
      *) core: Make sure and check that LimitXMLRequestBody fits in system memory.
         [Ruediger Pluem, Yann Ylavic]
    
      *) core: Simpler connection close logic if discarding the request body fails.
         [Yann Ylavic, Ruediger Pluem]
    
      *) mod_http2: preserve the port number given in a HTTP/1.1
         request that was Upgraded to HTTP/2. Fixes PR65881.
         [Stefan Eissing]
    
      *) mod_proxy: Allow for larger worker name.  PR 53218.  [Yann Ylavic]
    
      *) dbm: Split the loading of a dbm driver from the opening of a dbm file. When
         an attempt to load a dbm driver fails, log clearly which driver triggered
         the error (not "default"), and what the error was. [Graham Leggett]
    
      *) mod_proxy: Use the maxium of front end and backend timeouts instead of the
         minimum when tunneling requests (websockets, CONNECT requests).
         Backend timeouts can be configured more selectively (per worker if needed)
         as front end timeouts and typically the backend timeouts reflect the
         application requirements better.  PR 65886 [Ruediger Pluem]
    
      *) ap_regex: Use Thread Local Storage (TLS) to recycle ap_regexec() buffers
         when an efficient TLS implementation is available. [Yann Ylavic]
    
      *) core, mod_info: Add compiled and loaded PCRE versions to version
         number display.  [Rainer Jung]
    
      *) mod_md: do not interfere with requests to /.well-known/acme-challenge/
         resources if challenge type 'http-01' is not configured for a domain.
         Fixes <https://github.com/icing/mod_md/issues/279>.
         [Stefan Eissing]
    
      *) mod_dav: Fix regression when gathering properties which could lead to huge
         memory consumption proportional to the number of resources.
         [Evgeny Kotkov, Ruediger Pluem]
    
      *) Support pcre2 (10.x) library in place of the now end-of-life pcre (8.x)
         for regular expression evaluation. This depends on locating pcre2-config.
         [William Rowe, Petr Pisar <ppisar redhat.com>, Rainer Jung]
    
      *) Add the ldap function to the expression API, allowing LDAP filters and
         distinguished names based on expressions to be escaped correctly to
         guard against LDAP injection. [Graham Leggett]
    
      *) mod_md: the status description in MDomain's JSON, exposed in the
         md-status handler (if configured) did sometimes not carry the correct
         message when certificates needed renew.
         [Stefan Eissing]
    
      *) mpm_event: Fix a possible listener deadlock on heavy load when restarting
         and/or reaching MaxConnectionsPerChild.  PR 65769.  [Yann Ylavic]
    
    Changes with Apache 2.4.52
    
      *) SECURITY: CVE-2021-44790: Possible buffer overflow when parsing
         multipart content in mod_lua of Apache HTTP Server 2.4.51 and
         earlier (cve.mitre.org)
         A carefully crafted request body can cause a buffer overflow in
         the mod_lua multipart parser (r:parsebody() called from Lua
         scripts).
         The Apache httpd team is not aware of an exploit for the
         vulnerability though it might be possible to craft one.
         This issue affects Apache HTTP Server 2.4.51 and earlier.
         Credits: Chamal
    
      *) SECURITY: CVE-2021-44224: Possible NULL dereference or SSRF in
         forward proxy configurations in Apache HTTP Server 2.4.51 and
         earlier (cve.mitre.org)
         A crafted URI sent to httpd configured as a forward proxy
         (ProxyRequests on) can cause a crash (NULL pointer dereference)
         or, for configurations mixing forward and reverse proxy
         declarations, can allow for requests to be directed to a
         declared Unix Domain Socket endpoint (Server Side Request
         Forgery).
         This issue affects Apache HTTP Server 2.4.7 up to 2.4.51
         (included).
         Credits: 漂亮鼠
         TengMA(@Te3t123)
    
      *) http: Enforce that fully qualified uri-paths not to be forward-proxied
         have an http(s) scheme, and that the ones to be forward proxied have a
         hostname, per HTTP specifications.  [Ruediger Pluem, Yann Ylavic]
    
      *) configure: OpenSSL detection will now use pkg-config data from
         .../lib64/ within the --with-ssl path. [Jean-Frederic Clere]
    
      *) mod_proxy_connect, mod_proxy: Do not change the status code after we
         already sent it to the client. [Ruediger Pluem]
    
      *) mod_http: Correctly sent a 100 Continue status code when sending an interim
         response as result of an Expect: 100-Continue in the request and not the
         current status code of the request. PR 65725 [Ruediger Pluem]
    
      *) mod_dav: Some DAV extensions, like CalDAV, specify both document
         elements and property elements that need to be taken into account
         when generating a property. The document element and property element
         are made available in the dav_liveprop_elem structure by calling
         dav_get_liveprop_element(). [Graham Leggett]
    
      *) mod_dav: Add utility functions dav_validate_root_ns(),
         dav_find_child_ns(), dav_find_next_ns(), dav_find_attr_ns() and
         dav_find_attr() so that other modules get to play too.
         [Graham Leggett]
    
      *) mpm_event: Restart stopping of idle children after a load peak. PR 65626.
         [Yann Ylavic, Ruediger Pluem]
    
      *) mod_http2: fixes 2 regressions in server limit handling.
         1. When reaching server limits, such as MaxRequestsPerChild, the
            HTTP/2 connection send a GOAWAY frame much too early on new
            connections, leading to invalid protocol state and a client
            failing the request. See PR65731.
            The module now initializes the HTTP/2 protocol correctly and
            allows the client to submit one request before the shutdown
            via a GOAWAY frame is being announced.
         2. A regression in v1.15.24 was fixed that could lead to httpd
            child processes not being terminated on a graceful reload or
            when reaching MaxConnectionsPerChild. When unprocessed h2
            requests were queued at the time, these could stall.
            See <https://github.com/icing/mod_h2/issues/212>.
         [Stefan Eissing]
    
      *) mod_ssl: Add build support for OpenSSL v3. [Rainer Jung,
         Stefan Fritsch, Yann Ylavic, Stefan Eissing, Joe Orton,
         Giovanni Bechis]
    
      *) mod_proxy_connect: Honor the smallest of the backend or client timeout
         while tunneling.  [Yann Ylavic]
    
      *) mod_proxy: SetEnv proxy-nohalfclose (or alike) allows to disable TCP
         half-close forwarding when tunneling protocols.  [Yann Ylavic]
    
      *) core: Be safe with ap_lingering_close() called with a socket NULL-ed by
         a third-party module.  PR 65627.
         [acmondor <bz.apache.org acmondor.ca>, Yann Ylavic]
    
      *) mod_md: Fix memory leak in case of failures to load the private key.
         PR 65620 [ Filipe Casal <filipe.casal@trailofbits.com> ]
    
      *) mod_md: adding v2.4.8 with the following changes
        - Added support for ACME External Account Binding (EAB).
          Use the new directive `MDExternalAccountBinding` to provide the
          server with the value for key identifier and hmac as provided by
          your CA.
          While working on some servers, EAB handling is not uniform
          across CAs. First tests with a Sectigo Certificate Manager in
          demo mode are successful. But ZeroSSL, for example, seems to
          regard EAB values as a one-time-use-only thing, which makes them
          fail if you create a seconde account or retry the creation of the
          first account with the same EAB.
        - The directive 'MDCertificateAuthority' now checks if its parameter
          is a http/https url or one of a set of known names. Those are
          'LetsEncrypt', 'LetsEncrypt-Test', 'Buypass' and 'Buypass-Test'
          for now and they are not case-sensitive.
          The default of LetsEncrypt is unchanged.
        - `MDContactEmail` can now be specified inside a `<MDomain dnsname>`
          section.
        - Treating 401 HTTP status codes for orders like 403, since some ACME
          servers seem to prefer that for accessing oders from other accounts.
        - When retrieving certificate chains, try to read the response even
          if the HTTP Content-Type is unrecognized.
        - Fixed a bug that reset the error counter of a certificate renewal
          and prevented the increasing delays in further attempts.
        - Fixed the renewal process giving up every time on an already existing
          order with some invalid domains. Now, if such are seen in a previous
          order, a new order is created for a clean start over again.
          See <https://github.com/icing/mod_md/issues/268>
        - Fixed a mixup in md-status handler when static certificate files
          and renewal was configured at the same time.
    
      *) mod_md: values for External Account Binding (EAB) can
         now also be configured to be read from a separate JSON
         file. This allows to keep server configuration permissions
         world readable without exposing secrets.
         [Stefan Eissing]
    
      *) mod_proxy_uwsgi: Remove duplicate slashes at the beginning of PATH_INFO.
         PR 65616.  [Ruediger Pluem]
    
    Changes with Apache 2.4.51
    
      *) SECURITY: CVE-2021-42013: Path Traversal and Remote Code
         Execution in Apache HTTP Server 2.4.49 and 2.4.50 (incomplete
         fix of CVE-2021-41773) (cve.mitre.org)
         It was found that the fix for CVE-2021-41773 in Apache HTTP
         Server 2.4.50 was insufficient.  An attacker could use a path
         traversal attack to map URLs to files outside the directories
         configured by Alias-like directives.
         If files outside of these directories are not protected by the
         usual default configuration "require all denied", these requests
         can succeed. If CGI scripts are also enabled for these aliased
         paths, this could allow for remote code execution.
         This issue only affects Apache 2.4.49 and Apache 2.4.50 and not
         earlier versions.
         Credits: Reported by Juan Escobar from Dreamlab Technologies,
         Fernando Muñoz from NULL Life CTF Team, and Shungo Kumasaka
    
      *) core: Add ap_unescape_url_ex() for better decoding control, and deprecate
         unused AP_NORMALIZE_DROP_PARAMETERS flag.
         [Yann Ylavic, Ruediger Pluem, Stefan Eissing, Joe Orton]
    
    Changes with Apache 2.4.50
    
      *) SECURITY: CVE-2021-41773: Path traversal and file disclosure
         vulnerability in Apache HTTP Server 2.4.49 (cve.mitre.org)
         A flaw was found in a change made to path normalization in
         Apache HTTP Server 2.4.49. An attacker could use a path
         traversal attack to map URLs to files outside the expected
         document root.
         If files outside of the document root are not protected by
         "require all denied" these requests can succeed. Additionally
         this flaw could leak the source of interpreted files like CGI
         scripts.
         This issue is known to be exploited in the wild.
         This issue only affects Apache 2.4.49 and not earlier versions.
         Credits: This issue was reported by Ash Daulton along with the
         cPanel Security Team
    
      *) SECURITY: CVE-2021-41524: null pointer dereference in h2 fuzzing
         (cve.mitre.org)
         While fuzzing the 2.4.49 httpd, a new null pointer dereference
         was detected during HTTP/2 request processing,
         allowing an external source to DoS the server. This requires a
         specially crafted request.
         The vulnerability was recently introduced in version 2.4.49. No
         exploit is known to the project.
         Credits: Apache httpd team would like to thank LI ZHI XIN from
         NSFocus Security Team for reporting this issue.
    
      *) core: AP_NORMALIZE_DECODE_UNRESERVED should normalize the second dot in
         the uri-path when it's preceded by a dot.  [Yann Ylavic]
    
      *) mod_md: when MDMessageCmd for a 'challenge-setup:<type>:<dnsname>'
         fails (!= 0 exit), the renewal process is aborted and an error is
         reported for the MDomain. This provides scripts that distribute
         information in a cluster to abort early with bothering an ACME
         server to validate a dns name that will not work. The common
         retry logic will make another attempt in the future, as with
         other failures.
         Fixed a bug when adding private key specs to an already working
         MDomain, see <https://github.com/icing/mod_md/issues/260>.
         [Stefan Eissing]
    
      *) mod_proxy: Handle UDS URIs with empty hostname ("unix:///...") as if they
         had no hostname ("unix:/...").  [Yann Ylavic]
    
      *) mod_md: fixed a bug in handling multiple parallel OCSP requests. These could
         run into an assertion which terminated (and restarted) the child process where
         the task was running. Eventually, all OCSP responses were collected, but not
         in the way that things are supposed to work.
         See also <https://bz.apache.org/bugzilla/show_bug.cgi?id=65567>.
         The bug was possibly triggered when more than one OCSP status needed updating
         at the same time. For example for several renewed certificates after a server
         reload.
    
      *) mod_rewrite: Fix UDS ("unix:") scheme for [P] rules.  PR 57691 + 65590.
         [Janne Peltonen <janne.peltonen sange.fi>]
    
      *) event mpm: Correctly count active child processes in parent process if
         child process dies due to MaxConnectionsPerChild.
         PR 65592 [Ruediger Pluem]
    
      *) mod_http2: when a server is restarted gracefully, any idle h2 worker
         threads are shut down immediately.
         Also, change OpenSSL API use for deprecations in OpenSSL 3.0.
         Adds all other, never proposed code changes to make a clean
         sync of http2 sources. [Stefan Eissing]
    
      *) mod_dav: Correctly handle errors returned by dav providers on REPORT
         requests. [Ruediger Pluem]
    
      *) core: do not install core input/output filters on secondary
         connections. [Stefan Eissing]
    
      *) core: Add ap_pre_connection() as a wrapper to ap_run_pre_connection()
         and use it to prevent that failures in running the pre_connection
         hook cause crashes afterwards. [Ruediger Pluem]
    
      *) mod_speling: Add CheckBasenameMatch PR 44221.  [Christophe Jaillet]
    
    Changes with Apache 2.4.49
    
      *) SECURITY: CVE-2021-40438 (cve.mitre.org)
         mod_proxy: Server Side Request Forgery (SSRF) vulnerability [Yann Ylavic]
    
      *) SECURITY: CVE-2021-39275 (cve.mitre.org)
         core: ap_escape_quotes buffer overflow
    
      *) SECURITY: CVE-2021-36160 (cve.mitre.org)
         mod_proxy_uwsgi: Out of bound read vulnerability [Yann Ylavic]
    
      *) SECURITY: CVE-2021-34798 (cve.mitre.org)
         core: null pointer dereference on malformed request
    
      *) SECURITY: CVE-2021-33193 (cve.mitre.org)
         mod_http2: Request splitting vulnerability with mod_proxy [Stefan Eissing]
    
      *) core/mod_proxy/mod_ssl:
         Adding `outgoing` flag to conn_rec, indicating a connection is
         initiated by the server to somewhere, in contrast to incoming
         connections from clients.
         Adding 'ap_ssl_bind_outgoing()` function that marks a connection
         as outgoing and is used by mod_proxy instead of the previous
         optional function `ssl_engine_set`. This enables other SSL
         module to secure proxy connections.
         The optional functions `ssl_engine_set`, `ssl_engine_disable` and
         `ssl_proxy_enable` are now provided by the core to have backward
         compatibility with non-httpd modules that might use them. mod_ssl
         itself no longer registers these functions, but keeps them in its
         header for backward compatibility.
         The core provided optional function wrap any registered function
         like it was done for `ssl_is_ssl`.
         [Stefan Eissing]
    
      *) mod_ssl: Support logging private key material for use with
         wireshark via log file given by SSLKEYLOGFILE environment
         variable.  Requires OpenSSL 1.1.1.  PR 63391.  [Joe Orton]
    
      *) mod_proxy: Do not canonicalize the proxied URL when both "nocanon" and
         "ProxyPassInterpolateEnv On" are configured.  PR 65549.
         [Joel Self <joelself gmail.com>]
    
      *) mpm_event: Fix children processes possibly not stopped on graceful
         restart.  PR 63169.  [Joel Self <joelself gmail.com>]
    
      *) mod_proxy: Fix a potential infinite loop when tunneling Upgrade(d)
         protocols from mod_proxy_http, and a timeout triggering falsely when
         using mod_proxy_wstunnel, mod_proxy_connect or mod_proxy_http with
         upgrade= setting.  PRs 65521 and 65519.  [Yann Ylavic]
    
      *) mod_unique_id: Reduce the time window where duplicates may be generated
         PR 65159
         [Christophe Jaillet]
    
      *) mpm_prefork: Block signals for child_init hooks to prevent potential
         threads created from there to catch MPM's signals.
         [Ruediger Pluem, Yann Ylavic]
    
      *) Revert "mod_unique_id: Fix potential duplicated ID generation under heavy load.
         PR 65159" added in 2.4.47.
         This causes issue on Windows.
         [Christophe Jaillet]
    
      *) mod_proxy_uwsgi: Fix PATH_INFO setting for generic worker.  [Yann Ylavic]
    
      *) mod_md: Certificate/keys pairs are verified as matching before a renewal is accepted
         as successful or a staged renewal is replacing the existing certificates.
         This avoid potential mess ups in the md store file system to render the active
         certificates non-working. [@mkauf]
    
      *) mod_proxy: Faster unix socket path parsing in the "proxy:" URL.
         [Yann Ylavic]
    
      *) mod_ssl: tighten the handling of ALPN for outgoing (proxy)
         connections. If ALPN protocols are provided and sent to the
         remote server, the received protocol selected is inspected
         and checked for a match. Without match, the peer handshake
         fails.
         An exception is the proposal of "http/1.1" where it is
         accepted if the remote server did not answer ALPN with
         a selected protocol. This accommodates for hosts that do
         not observe/support ALPN and speak http/1.x be default.
    
      *) mod_proxy: Fix possible reuse/merging of Proxy(Pass)Match worker instances
         with others when their URLs contain a '$' substitution.  PR 65419 + 65429.
         [Yann Ylavic]
    
      *) mod_dav: Add method_precondition hook. WebDAV extensions define
         conditions that must exist before a WebDAV method can be executed.
         This hook allows a WebDAV extension to verify these preconditions.
         [Graham Leggett]
    
      *) Add hooks deliver_report and gather_reports to mod_dav.h. Allows other
         modules apart from versioning implementations to handle the REPORT method.
         [Graham Leggett]
    
      *) Add dav_get_provider(), dav_open_lockdb(), dav_close_lockdb() and
         dav_get_resource() to mod_dav.h. [Graham Leggett]
    
      *) core: fix ap_escape_quotes substitution logic. [Eric Covener]
    
      *) core/mpm: add hook 'child_stopping` that gets called when the MPM is
         stopping a child process. The additional `graceful` parameter allows
         registered hooks to free resources early during a graceful shutdown.
         [Yann Ylavic, Stefan Eissing]
    
      *) mod_proxy: Fix icomplete initialization of BalancerMember(s) from the
         balancer-manager, which can lead to a crash.  [Yann Ylavic]
    
      *) mpm_event: Fix graceful stop/restart of children processes if connections
         are in lingering close for too long.  [Yann Ylavic]
    
      *) mod_md: fixed a potential null pointer dereference if ACME/OCSP
         server returned 2xx responses without content type. Reported by chuangwen.
         [chuangwen, Stefan Eissing]
    
      *) mod_md:
         - Domain names in `<MDomain ...>` can now appear in quoted form.
         - Fixed a failure in ACME challenge selection that aborted further searches
           when the tls-alpn-01 method did not seem to be suitable.
         - Changed the tls-alpn-01 setup to only become unsuitable when none of the
           dns names showed support for a configured 'Protocols ... acme-tls/1'. This
           allows use of tls-alpn-01 for dns names that are not mapped to a VirtualHost.
         [Stefan Eissing]
    
      *) Add CPING to health check logic. [Jean-Frederic Clere]
    
      *) core: Split ap_create_request() from ap_read_request(). [Graham Leggett]
    
      *) core, h2: common ap_parse_request_line() and ap_check_request_header()
         code. [Yann Ylavic]
    
      *) core: Add StrictHostCheck to allow unconfigured hostnames to be
         rejected. [Eric Covener]
    
      *) htcacheclean: Improve help messages.  [Christophe Jaillet]
    
    Changes with Apache 2.4.48
    
      *) SECURITY: CVE-2021-31618 (cve.mitre.org)
         mod_http2: Fix a potential NULL pointer dereference [Ivan Zhakov]
    
      *) mod_proxy_wstunnel: Add ProxyWebsocketFallbackToProxyHttp to opt-out the
         fallback to mod_proxy_http for WebSocket upgrade and tunneling.
         [Yann Ylavic]
    
      *) mod_proxy: Fix flushing of THRESHOLD_MIN_WRITE data while tunneling.
         PR 65294.  [Yann Ylavic]
    
      *) core: Fix a regression that stripped the ETag header from 304 responses.
         PR 61820 [Ruediger Pluem, Roy T. Fielding]
    
      *) core: Adding SSL related inquiry functions to the server API.
         These function are always available, even when no module providing
         SSL is loaded. They provide their own "shadowing" implementation for
         the optional functions of similar name that mod_ssl and impersonators
         of mod_ssl provide.
         This enables loading of several SSL providing modules when all but
         one of them registers itself into the new hooks. Two old-style SSL
         modules will not work, as they replace the others optional functions
         with their own.
         Modules using the old-style optional functions will continue to work
         as core supplies its own versions of those.
         The following has been added so far:
         - ap_ssl_conn_is_ssl() to query if a connection is using SSL.
         - ap_ssl_var_lookup() to query SSL related variables for a
           server/connection/request.
         - Hooks for 'ssl_conn_is_ssl' and 'ssl_var_lookup' where modules
           providing SSL can install their own value supplying functions.
         - ap_ssl_add_cert_files() to enable other modules like mod_md to provide
           certificate and keys for an SSL module like mod_ssl.
         - ap_ssl_add_fallback_cert_files() to enable other modules like mod_md to
           provide a fallback certificate in case no 'proper' certificate is
           available for an SSL module like mod_ssl.
         - ap_ssl_answer_challenge() to enable other modules like mod_md to
           provide a certificate as used in the RFC 8555 'tls-alpn-01' challenge
           for the ACME protocol for an SSL module like mod_ssl. The function
           and its hook provide PEM encoded data instead of file names.
         - Hooks for 'ssl_add_cert_files', 'ssl_add_fallback_cert_files' and
           'ssl_answer_challenge' where modules like mod_md can provide providers
           to the above mentioned functions.
         - These functions reside in the new 'http_ssl.h' header file.
         [Stefan Eissing]
    
      *) core/mod_ssl/mod_md: adding OCSP response provisioning as core feature. This
         allows modules to access and provide OCSP response data without being tied
         of each other. The data is exchanged in standard, portable formats (PEM encoded
         certificates and DER encoded responses), so that the actual SSL/crypto
         implementations used by the modules are independant of each other.
         Registration and retrieval happen in the context of a server (server_rec)
         which modules may use to decide if they are configured for this or not.
         The area of changes:
         1. core: defines 2 functions in include/http_ssl.h, so that modules may
            register a certificate, together with its issuer certificate for OCSP
            response provisioning and ask for current response data (DER bytes) later.
            Also, 2 hooks are defined that allow modules to implement this OCSP
            provisioning.
         2. mod_ssl uses the new functions, in addition to what it did already, to
            register its certificates this way. If no one is interested in providing
            OCSP, it falls back to its own (if configured) stapling implementation.
         3. mod_md registers itself at the core hooks for OCSP provisioning. Depending
            on configuration, it will accept registrations of its own certificates only,
            all certificates or none.
         [Stefan Eissing]
    
     *) mod_md: v2.4.0 with improvements and bugfixes
         - MDPrivateKeys allows the specification of several types. Beside "RSA" plus
         optional key lengths elliptic curves can be configured. This means you can
         have multiple certificates for a Managed Domain with different key types.
         With ```MDPrivateKeys secp384r1 rsa2048``` you get one ECDSA  and one RSA
         certificate and all modern client will use the shorter ECDSA, while older
         client will get the RSA certificate.
         Many thanks to @tlhackque who pushed and helped on this.
         - Support added for MDomains consisting of a wildcard. Configuring
         ```MDomain *.host.net``` will match all virtual hosts matching that pattern
         and obtain one certificate for it (assuming you have 'dns-01' challenge
         support configured). Addresses #239.
         - Removed support for ACMEv1 servers. The only known installation used to
         be Let's Encrypt which has disabled that version more than a year ago for
         new accounts.
         - Andreas Ulm (<https://github.com/root360-AndreasUlm>) implemented the
         ```renewing``` call to ```MDMessageCmd``` that can deny a certificate
         renewal attempt. This is useful in clustered installations, as
         discussed in #233).
         - New event ```challenge-setup:<type>:<domain>```, triggered when the
         challenge data for a domain has been created. This is invoked before the
         ACME server is told to check for it. The type is one of the ACME challenge
         types. This is invoked for every DNS name in a MDomain.
         - The max delay for retries has been raised to daily (this is like all
         retries jittered somewhat to avoid repeats at fixed time of day).
         - Certain error codes reported by the ACME server that indicate a problem
         with the configured data now immediately switch to daily retries. For
         example: if the ACME server rejects a contact email or a domain name,
         frequent retries will most likely not solve the problem. But daily retries
         still make sense as there might be an error at the server and un-supervised
         certificate renewal is the goal. Refs #222.
         - Test case and work around for domain names > 64 octets. Fixes #227.
         When the first DNS name of an MD is longer than 63 octets, the certificate
         request will not contain a CN field, but leave it up to the CA to choose one.
         Currently, Lets Encrypt looks for a shorter name in the SAN list given and
         fails the request if none is found. But it is really up to the CA (and what
         browsers/libs accept here) and may change over the years. That is why
         the decision is best made at the CA.
         - Retry delays now have a random +/-[0-50]% modification applied to let
         retries from several servers spread out more, should they have been
         restarted at the same time of day.
         - Fixed several places where the 'badNonce' return code from an ACME server
         was not handled correctly. The test server 'pebble' simulates this behaviour
         by default and helps nicely in verifying this behaviour. Thanks, pebble!
         - Set the default `MDActivationDelay` to 0. This was confusing to users that
         new certificates were deemed not usably before a day of delay. When clocks are
         correct, using a new certificate right away should not pose a problem.
         - When handling ACME authorization resources, the module no longer requires
         the server to return a "Location" header, as was necessary in ACMEv1.
         Fixes #216.
         - Fixed a theoretical uninitialized read when testing for JSON error responses
         from the ACME CA. Reported at <https://bz.apache.org/bugzilla/show_bug.cgi?id=64297>.
         - ACME problem reports from CAs that include parameters in the Content-Type
         header are handled correctly. (Previously, the problem text would not be
         reported and retries could exceed CA limits.)
         - Account Update transactions to V2 CAs now use the correct POST-AS-GET method.
         Previously, an empty JSON object was sent - which apparently LE accepted,
         but others reject.
         [Stefan Eissing, @tlhackque, Andreas Ulm]
    
    Changes with Apache 2.4.47
    
      *) SECURITY: CVE-2021-30641 (cve.mitre.org)
         Unexpected <Location> section matching with 'MergeSlashes OFF'
    
      *) SECURITY: CVE-2020-35452 (cve.mitre.org)
         mod_auth_digest: possible stack overflow by one nul byte while validating
         the Digest nonce.  [Yann Ylavic]
    
      *) SECURITY: CVE-2021-26691 (cve.mitre.org)
         mod_session: Fix possible crash due to NULL pointer dereference, which
         could be used to cause a Denial of Service with a malicious backend
         server and SessionHeader.  [Yann Ylavic]
    
      *) SECURITY: CVE-2021-26690 (cve.mitre.org)
         mod_session: Fix possible crash due to NULL pointer dereference, which
         could be used to cause a Denial of Service.  [Yann Ylavic]
    
      *) SECURITY: CVE-2020-13950 (cve.mitre.org)
         mod_proxy_http: Fix possible crash due to NULL pointer dereference, which
         could be used to cause a Denial of Service.  [Yann Ylavic]
    
      *) SECURITY: CVE-2020-13938 (cve.mitre.org)
         Windows: Prevent local users from stopping the httpd process [Ivan Zhakov]
    
      *) SECURITY: CVE-2019-17567 (cve.mitre.org)
         mod_proxy_wstunnel, mod_proxy_http: Handle Upgradable protocols end-to-end
         negotiation.  [Yann Ylavic]
    
      *) mod_dav_fs: Improve logging output when failing to open files for
         writing.  PR 64413.  [Bingyu Shen <ahshenbingyu gmail.com>]
    
      *) mod_http2: Fixed a race condition that could lead to streams being
         aborted (RST to the client), although a response had been produced.
         [Stefan Eissing]
    
      *) mod_lua: Add support to Lua 5.4  [Joe Orton, Giovanni Bechis, Ruediger Pluem]
    
      *) MPM event/worker: Fix possible crash in child process on early signal
         delivery.  PR 64533.  [Ruediger Pluem]
    
      *) mod_http2: sync with github standalone version 1.15.17
         - Log requests and sent the configured error response in case of early detected
           errors like too many or too long headers. [Ruediger Pluem]
         - new option 'H2OutputBuffering on/off' which controls the buffering of stream output.
           The default is on, which is the behaviour of older mod-h2 versions. When off, all
           bytes are made available immediately to the main connection for sending them
           out to the client. This fixes interop issues with certain flavours of gRPC, see
           also <https://github.com/icing/mod_h2/issues/207>.
           [Stefan Eissing]
    
      *) mod_unique_id: Fix potential duplicated ID generation under heavy load.
         PR 65159
         [Jonas Müntener <jonas.muentener ergon.ch>, Christophe Jaillet]
    
      *) "[mod_dav_fs etag handling] should really honor the FileETag setting".
         - It now does.
         - Add "Digest" to FileETag directive, allowing a strong ETag to be
           generated using a file digest.
         - Add ap_make_etag_ex() and ap_set_etag_fd() to allow full control over
           ETag generation.
         - Add concept of "binary notes" to request_rec, allowing packed bit flags
           to be added to a request.
         - First binary note - AP_REQUEST_STRONG_ETAG - allows modules to force
           the ETag to a strong ETag to comply with RFC requirements, such as those
           mandated by various WebDAV extensions.
         [Graham Leggett]
    
      *) mod_proxy_http: Fix a possibly crash when the origin connection gets
         interrupted before completion.  PR 64234.
         [Barnim Dzwillo <dzwillo strato.de>, Ruediger Pluem]
    
      *) mod_ssl: Do not keep connections to OCSP responders alive when doing
         OCSP requests.  PR 64135.  [Ruediger Pluem]
    
      *) mod_ssl: Improve the coalescing filter to buffer into larger TLS
         records, and avoid revealing the HTTP header size via TLS record
         boundaries (for common response generators).
         [Joe Orton, Ruediger Pluem]
    
      *) mod_proxy_hcheck: Don't pile up health checks if the previous one did
         not finish before hcinterval.  PR 63010.  [Yann Ylavic]
    
      *) mod_session: Improve session parsing.  [Yann Yalvic]
    
      *) mod_authnz_ldap: Prevent authentications with empty passwords for the
         initial bind to fail with status 500. [Ruediger Pluem]
    
      *) mod_proxy_fcgi: Honor "SetEnv proxy-sendcl" to forward a chunked
         Transfer-Encoding from the client, spooling the request body when needed
         to provide a Content-Length to the backend.  PR 57087.  [Yann Ylavic]
    
      *) mod_proxy: Improve tunneling loop to support half closed connections and
         pending data draining (for protocols like rsync). PR 61616. [Yann Ylavic]
    
      *) mod_proxy_wstunnel: Leave Upgrade requests handling to mod_proxy_http,
         allowing for (non-)Upgrade negotiation with the origin server.
         [Yann Ylavic]
    
      *) mod_proxy: Allow ProxyErrorOverride to be restricted to specific status
         codes.  PR63628. [Martin Drößler <mail martindroessler.de>]
    
      *) core: Add ReadBufferSize, FlushMaxThreshold and FlushMaxPipelined
         directives.  [Yann Ylavic]
    
      *) core: Ensure that aborted connections are logged as such. PR 62823
         [Arnaud Grandville <contact@grandville.net>]
    
      *) http: Allow unknown response status' lines returned in the form of
         "HTTP/x.x xxx Status xxx".  [Yann Ylavic]
    
      *) mod_proxy_http: Fix 100-continue deadlock for spooled request bodies,
         leading to Request Timeout (408).  PR 63855.  [Yann Ylavic]
    
      *) core: Remove headers on 304 Not Modified as specified by RFC7234, as
         opposed to passing an explicit subset of headers. PR 61820.
         [Giovanni Bechis]
    
      *) mpm_event: Don't reset connections after lingering close, restoring prior
         to 2.4.28 behaviour.  [Yann Ylavic]
    
      *) mpm_event: Kill connections in keepalive state only when there is no more
         workers available, not when the maximum number of connections is reached,
         restoring prior to 2.4.30 behaviour.  [Yann Ylavic]
    
      *) mod_unique_id: Use base64url encoding for UNIQUE_ID variable,
         avoiding the use of '@'.  PR 57044.
         [Michael Kaufmann <apache-bugzilla michael-kaufmann.ch>]
    
      *) mod_rewrite: Extend the [CO] (cookie) flag of RewriteRule to accept a
         SameSite attribute. [Eric Covener]
    
      *) mod_proxy: Add proxy check_trans hook.  This allows proxy
         modules to decline request handling at early stage.
    
      *) mod_proxy_wstunnel: Decline requests without an Upgrade
         header so ws/wss can be enabled overlapping with later
         http/https.
    
      *) mod_http2: Log requests and sent the configured error response in case of
         early detected errors like too many or too long headers.
         [Ruediger Pluem, Stefan Eissing]
    
      *) mod_md: Lowered the required minimal libcurl version from 7.50 to 7.29
         as proposed by <alexander.gerasimov codeit.pro>. [Stefan Eissing]
    
      *) mod_ssl: Fix request body buffering with PHA in TLSv1.3.  [Joe Orton]
    
      *) mod_proxy_uwsgi: Fix a crash when sending environment variables with no
         value. PR 64598 [Ruediger Pluem]
    
      *) mod_proxy: Recognize parameters from ProxyPassMatch workers with dollar
         substitution, such that they apply to the backend connection.  Note that
         connection reuse is disabled by default to avoid compatibility issues.
         [Takashi Sato, Jan Kaluza, Eric Covener, Yann Ylavic, Jean-Frederic Clere]
    
    Changes with Apache 2.4.46
    
      *) SECURITY: CVE-2020-11984 (cve.mitre.org)
         mod_proxy_uwsgi: Malicious request may result in information disclosure
         or RCE of existing file on the server running under a malicious process
         environment. [Yann Ylavic]
    
      *) SECURITY: CVE-2020-11993 (cve.mitre.org)
         mod_http2: when throttling connection requests, log statements
         where possibly made that result in concurrent, unsafe use of
         a memory pool. [Stefan Eissing]
    
      *) SECURITY: CVE-2020-9490 (cve.mitre.org)
         mod_http2: a specially crafted value for the 'Cache-Digest' header
         request would result in a crash when the server actually tries
         to HTTP/2 PUSH a resource afterwards. [Stefan Eissing]
    
      *) mod_proxy_fcgi: Fix missing APLOGNO macro argument
         [Eric Covener, Christophe Jaillet]
    
    Changes with Apache 2.4.45
    
      *) mod_http2: remove support for abandoned http-wg draft
         <https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/>.
         [Stefan Eissing]
    
    Changes with Apache 2.4.44
    
      *) mod_proxy_uwsgi: Error out on HTTP header larger than 16K (hard
         protocol limit).  [Yann Ylavic]
    
      *) mod_http2:
         Fixes <https://github.com/icing/mod_h2/issues/200>:
         "LimitRequestFields 0" now disables the limit, as documented.
         Fixes <https://github.com/icing/mod_h2/issues/201>:
         Do not count repeated headers with same name against the field
         count limit. The are merged internally, as if sent in a single HTTP/1 line.
         [Stefan Eissing]
    
      *) mod_http2: Avoid segfaults in case of handling certain responses for
         already aborted connections.  [Stefan Eissing, Ruediger Pluem]
    
      *) mod_http2: The module now handles master/secondary connections and has marked
         methods according to use. [Stefan Eissing]
    
      *) core: Drop an invalid Last-Modified header value coming
         from a FCGI/CGI script instead of replacing it with Unix epoch.
         [Yann Ylavic, Luca Toscano]
    
      *) Add support for strict content-length parsing through addition of
         ap_parse_strict_length() [Yann Ylavic]
    
      *) mod_proxy_fcgi: ProxyFCGISetEnvIf unsets variables when expression
         evaluates to false.  PR64365. [Michael König <mail ikoenig.net>]
    
      *) mod_proxy_http: flush spooled request body in one go to avoid
         leaking (or long lived) temporary file. PR 64452. [Yann Ylavic]
    
      *) mod_ssl: Fix a race condition and possible crash when using a proxy client
         certificate (SSLProxyMachineCertificateFile).
         [Armin Abfalterer <a.abfalterer gmail.com>]
    
      *) mod_ssl: Fix memory leak in stapling code. PR63687. [Stefan Eissing]
    
      *) mod_http2: Fixed regression that no longer set H2_STREAM_ID and H2_STREAM_TAG.
         PR64330 [Stefan Eissing]
    
      *) mod_http2: Fixed regression that caused connections to close when mod_reqtimeout
         was configured with a handshake timeout. Fixes gitub issue #196.
         [Stefan Eissing]
    
      *) mod_proxy_http2: the "ping" proxy parameter
         (see <https://httpd.apache.org/docs/2.4/mod/mod_proxy.html>) is now used
         when checking the liveliness of a new or reused h2 connection to the backend.
         With short durations, this makes load-balancing more responsive. The module
         will hold back requests until ping conditions are met, using features of the
         HTTP/2 protocol alone. [Ruediger Pluem, Stefan Eissing]
    
      *) core: httpd is no longer linked against -lsystemd if mod_systemd
         is enabled (and built as a DSO).  [Rainer Jung]
    
      *) mod_proxy_http2: respect ProxyTimeout settings on backend connections
         while waiting on incoming data. [Ruediger Pluem, Stefan Eissing]
    
    Changes with Apache 2.4.43
    
      *) mod_ssl: Fix memory leak of OCSP stapling response. [Yann Ylavic]
    
    Changes with Apache 2.4.42
    
      *) SECURITY: CVE-2020-1934 (cve.mitre.org)
         mod_proxy_ftp: Use of uninitialized value with malicious backend FTP
         server. [Eric Covener]
    
      *) SECURITY: CVE-2020-1927 (cve.mitre.org)
         rewrite, core: Set PCRE_DOTALL flag by default to avoid unpredictable
         matches and substitutions with encoded line break characters.
         The fix for CVE-2019-10098 was not effective.  [Ruediger Pluem]
    
      *) mod_proxy_http: Fix the forwarding of requests with content body when a
         balancer member is unavailable; the retry on the next member was issued
         with an empty body (regression introduced in 2.4.41). PR63891.
         [Yann Ylavic]
    
      *) core: Use a temporary file when writing the pid file, avoiding
         startup failure if an empty pidfile is left over from a
         previous crashed or aborted invocation of httpd.  PR 63140.
         [Nicolas Carrier <carrier.nicolas0 gmail.com>, Joe Orton]
    
      *) mod_http2: Fixes issue where mod_unique_id would generate non-unique request
         identifier under load, see <https://github.com/icing/mod_h2/issues/195>.
         [Michael Kaufmann, Stefan Eissing]
    
      *) mod_proxy_hcheck: Allow healthcheck expressions to use %{Content-Type}.
         PR64140. [Renier Velazco <renier.velazco upr.edu>]
    
      *) mod_authz_groupfile: Drop AH01666 from loglevel "error" to "info".
         PR64172.
    
      *) mod_usertrack: Add CookieSameSite, CookieHTTPOnly, and CookieSecure
         to allow customization of the usertrack cookie. PR64077.
         [Prashant Keshvani <prashant2400 gmail.com>, Eric Covener]
    
      *) mod_proxy_ajp: Add "secret" parameter to proxy workers to implement legacy
         AJP13 authentication.  PR 53098. [Dmitry A. Bakshaev <dab1818 gmail com>]
    
      *) mpm_event: avoid possible KeepAliveTimeout off by -100 ms.
         [Eric Covener, Yann Ylavic]
    
      *) Add a config layout for OpenWRT. [Graham Leggett]
    
      *) Add support for cross compiling to apxs. If apxs is being executed from
         somewhere other than its target location, add that prefix to includes and
         library directories. Without this, apxs would fail to find config_vars.mk
         and exit. [Graham Leggett]
    
      *) mod_ssl: Disable client verification on ACME ALPN challenges. Fixes github
         issue mod_md#172 (https://github.com/icing/mod_md/issues/172).
         [Michael Kaufmann <mail michael-kaufmann.ch>, Stefan Eissing]
    
      *) mod_ssl: use OPENSSL_init_ssl() to initialise OpenSSL on versions 1.1+.
         [Graham Leggett]
    
      *) mod_ssl: Support use of private keys and certificates from an
         OpenSSL ENGINE via PKCS#11 URIs in SSLCertificateFile/KeyFile.
         [Anderson Sasaki <ansasaki redhat.com>, Joe Orton]
    
      *) mod_md:
         - Prefer MDContactEmail directive to ServerAdmin for registration. New directive
           thanks to Timothe Litt (@tlhackque).
         - protocol check for pre-configured "tls-alpn-01" challenge has been improved. It will now
           check all matching virtual hosts for protocol support. Thanks to @mkauf.
         - Corrected a check when OCSP stapling was configured for hosts
           where the responsible MDomain is not clear, by Michal Karm Babacek (@Karm).
         - Softening the restrictions where mod_md configuration directives may appear. This should
           allow for use in <If> and <Macro> sections. If all possible variations lead to the configuration
           you wanted in the first place, is another matter.
         [Michael Kaufmann <mail michael-kaufmann.ch>, Timothe Litt (@tlhackque),
          Michal Karm Babacek (@Karm), Stefan Eissing (@icing)]
    
      *) test: Added continuous testing with Travis CI.
         This tests various scenarios on Ubuntu with the full test suite.
         Architectures tested: amd64, s390x, ppc64le, arm64
         The tests pass successfully.
         [Luca Toscano, Joe Orton, Mike Rumph, and others]
    
      *) core: Be stricter in parsing of Transfer-Encoding headers.
         [ZeddYu <zeddyu.lu gmail.com>, Eric Covener]
    
      *) mod_ssl: negotiate the TLS protocol version per name based vhost
         configuration, when linked with OpenSSL-1.1.1 or later. The base vhost's
         SSLProtocol (from the first vhost declared on the IP:port) is now only
         relevant if no SSLProtocol is declared for the vhost or globally,
         otherwise the vhost or global value apply.  [Yann Ylavic]
    
      *) mod_cgi, mod_cgid: Fix a memory leak in some error cases with large script
         output.  PR 64096.  [Joe Orton]
    
      *) config: Speed up graceful restarts by using pre-hashed command table. PR 64066.
         [Giovanni Bechis <giovanni paclan.it>, Jim Jagielski]
    
      *) mod_systemd: New module providing integration with systemd.  [Jan Kaluza]
    
      *) mod_lua: Add r:headers_in_table, r:headers_out_table, r:err_headers_out_table,
         r:notes_table, r:subprocess_env_table as read-only native table alternatives
         that can be iterated over. [Eric Covener]
    
      *) mod_http2: Fixed rare cases where a h2 worker could deadlock the main connection.
         [Yann Ylavic, Stefan Eissing]
    
      *) mod_lua: Accept nil assignments to the exposed tables (r.subprocess_env,
         r.headers_out, etc) to remove the key from the table. PR63971.
         [Eric Covener]
    
      *) mod_http2: Fixed interaction with mod_reqtimeout. A loaded mod_http2 was disabling the
         ssl handshake timeouts. Also, fixed a mistake of the last version that made `H2Direct`
         always `on`, regardless of configuration. Found and reported by
         <Armin.Abfalterer@united-security-providers.ch> and
         <Marcial.Rion@united-security-providers.ch>. [Stefan Eissing]
    
      *) mod_http2: Multiple field length violations in the same request no longer cause
         several log entries to be written. [@mkauf]
    
      *) mod_ssl: OCSP does not apply to proxy mode.  PR 63679.
         [Lubos Uhliarik <luhliari redhat.com>, Yann Ylavic]
    
      *) mod_proxy_html, mod_xml2enc: Fix build issues with macOS due to r1864469
         [Jim Jagielski]
    
      *) mod_authn_socache: Increase the maximum length of strings that can be cached by
         the module from 100 to 256.  PR 62149 [<thorsten.meinl knime.com>]
    
      *) mod_proxy: Fix crash by resolving pool concurrency problems. PR 63503
         [Ruediger Pluem, Eric Covener]
    
      *) core: On Windows, fix a start-up crash if <IfFile ...> is used with a path that is not
         valid (For example, testing for a file on a flash drive that is not mounted)
         [Christophe Jaillet]
    
      *) mod_deflate, mod_brotli: honor "Accept-Encoding: foo;q=0" as per RFC 7231; which
         means 'foo' is "not acceptable".  PR 58158 [Chistophe Jaillet]
    
      *) mod_md v2.2.3:
         - Configuring MDCAChallenges replaces any previous existing challenge configuration. It
           had been additive before which was not the intended behaviour. [@mkauf]
         - Fixing order of ACME challenges used when nothing else configured. Code now behaves as
           documented for `MDCAChallenges`. Fixes #156. Thanks again to @mkauf for finding this.
         - Fixing a potential, low memory null pointer dereference [thanks to @uhliarik].
         - Fixing an incompatibility with a change in libcurl v7.66.0 that added unwanted
           "transfer-encoding" to POST requests. This failed in direct communication with
           Let's Encrypt boulder server. Thanks to @mkauf for finding and fixing. [Stefan Eissing]
    
      *) mod_md: Adding the several new features.
         The module offers an implementation of OCSP Stapling that can replace fully or
         for a limited set of domains the existing one from mod_ssl. OCSP handling
         is part of mod_md's monitoring and message notifications. If can be used
         for sites that do not have ACME certificates.
         The url for a CTLog Monitor can be configured. It is used in the server-status
         to link to the external status page of a certificate.
         The MDMessageCmd is called with argument "installed" when a new certificate
         has been activated on server restart/reload. This allows for processing of
         the new certificate, for example to applications that require it in different
         locations or formats.
         [Stefan Eissing]
    
      *) mod_proxy_balancer: Fix case-sensitive referer check related to CSRF/XSS
         protection. PR 63688. [Armin Abfalterer <a.abfalterer gmail.com>]
    
    Changes with Apache 2.4.41
    
      *) SECURITY: CVE-2019-10097 (cve.mitre.org)
         mod_remoteip: Fix stack buffer overflow and NULL pointer deference
         when reading the PROXY protocol header.  [Joe Orton,
         Daniel McCarney <cpu letsencrypt.org>]
    
      *) SECURITY: CVE-2019-9517 (cve.mitre.org)
         mod_http2: a malicious client could perform a DoS attack by flooding
            a connection with requests and basically never reading responses
            on the TCP connection. Depending on h2 worker dimensioning, it was
            possible to block those with relatively few connections. [Stefan Eissing]
    
      *) SECURITY: CVE-2019-10098 (cve.mitre.org)
         rewrite, core: Set PCRE_DOTALL flag by default to avoid unpredictable
         matches and substitutions with encoded line break characters.
         [Yann Ylavic]
    
      *) SECURITY: CVE-2019-10092 (cve.mitre.org)
         Remove HTML-escaped URLs from canned error responses to prevent misleading
         text/links being displayed via crafted links. [Eric Covener]
    
      *) SECURITY: CVE-2019-10082 (cve.mitre.org)
         mod_http2: Using fuzzed network input, the http/2 session
         handling could be made to read memory after being freed,
         during connection shutdown. [Stefan Eissing]
    
      *) SECURITY: CVE-2019-10081 (cve.mitre.org)
         mod_http2: HTTP/2 very early pushes, for example configured with "H2PushResource",
            could lead to an overwrite of memory in the pushing request's pool,
            leading to crashes. The memory copied is that of the configured push
            link header values, not data supplied by the client. [Stefan Eissing]
    
      *) mod_proxy_balancer: Improve balancer-manager protection against
         XSS/XSRF attacks from trusted users.  [Joe Orton,
         Niels Heinen <heinenn google.com>]
    
      *) mod_session: Introduce SessionExpiryUpdateInterval which allows to
         configure the session/cookie expiry's update interval. PR 57300.
         [Paul Spangler <paul.spangler ni.com>]
    
      *) modules/filters: Fix broken compilation when using old GCC (<4.2.x).
         PR 63633.  [Rainer Jung, Joe Orton]
    
      *) mod_ssl: Fix startup failure in 2.4.40 with SSLCertificateChainFile
         configured for a domain managed by mod_md.  [Stefan Eissing]
    
    Changes with Apache 2.4.40
    
      *) core, mod_rewrite: Set PCRE_DOTALL by default. Revert via
         RegexDefaultOptions -DOTALL [Yann Ylavic]
    
      *) core: Remove request details from built-in error documents [Eric Covener]
    
      *) mod_http2: core setting "LimitRequestFieldSize" is not additionally checked on
         merged header fields, just as HTTP/1.1 does. [Stefan Eissing, Michael Kaufmann]
    
      *) mod_http2: fixed a bug that prevented proper stream cleanup when connection
         throttling was in place. Stream resets by clients on streams initiated by them
         are counted as possible trigger for throttling. [Stefan Eissing]
    
      *) mod_http2/mpm_event: Fixes the behaviour when a HTTP/2 connection has nothing
         more to write with streams ongoing (flow control block). The timeout waiting
         for the client to send WINODW_UPDATE was incorrectly KeepAliveTimeout and not
         Timeout as it should be. Fixes PR 63534. [Yann Ylavic, Stefan Eissing]
    
      *) mod_proxy_balancer: Load balancer required byrequests when bytraffic chosen.
         PR 62372. [Jim Jagielski]
    
      *) mod_proxy_hcheck: Create the configuration for mod_proxy_hcheck
         when used in BalancerMember. PR 60757. [Jean-Frederic Clere]
    
      *) mod_proxy_hcheck: Mute extremely frequent debug message. [Yann Ylavic]
    
      *) mod_ssl/mod_md: reversing dependency by letting mod_ssl offer hooks for
         adding certificates and keys to a virtual host. An additional hook allows
         answering special TLS connections as used in ACME challenges.
         Adding 2 new hooks for init/get of OCSP stapling status information when
         other modules want to provide those. Falls back to own implementation with
         same behaviour as before.
         [Stefan Eissing]
    
      *) mod_md: new features
         - protocol
           - supports the ACMEv2 protocol. It is the default and will be used on the next
             certificate renewal, unless another "MDCertificateAuthority" is configured
           - ACMEv2 endpoints use the GET via empty POST way of accessing resources, see
             announcement by Let's Encrypt:
             https://community.letsencrypt.org/t/acme-v2-scheduled-deprecation-of-unauthenticated-resource-gets/74380
         - challenges
           - new challenge method 'tls-alpn-01' implemented
           - challenge type 'tls-sni-01' has been removed as CAs do not offer this any longer
           - supports command configuration to setup/teardown 'dns-01' challenges
           - supports wildcard certificates when dns challenges are configured
         - status information and monitoring
           - a domain exposes its status at https://<domain>/.httpd/certificate-status
           - Managed Domains are now in Apache's 'server-status' page
           - A new handler 'md-status' exposes verbose status information in JSON format
         - new directives
           - "MDCertificateFile" and "MDCertificateKeyFile" to configure a
             Managed Domain that uses static files. Auto-renewal is turned off for those.
           - "MDMessageCmd" that is invoked on several events: 'renewed', 'expiring' and
             'errored'.
           - "MDWarnWindow" directive to configure when expiration warnings shall be issued.
         [Stefan Eissing]
    
      *) mod_mime_magic: Fix possible corruption of returned strings.
         [Christophe Jaillet]
    
      *) Default "conf/magic": Fix pattern for "audio/x-wav" for WAV files,
         remove "audio/unknown" pattern for other RIFF files.
         [Àngel Ollé Blázquez <aollebla redhat.com>]
    
      *) mod_proxy_http2: fixing a potential NULL pointer use in logging.
         [Christophe Jaillet, Dr Silvio Cesare InfoSect]
    
      *) mod_dav: Reduce the amount of memory needed when doing PROPFIND's on large
         collections by improving the memory management. [Joe Orton, Ruediger Pluem]
    
      *) mod_proxy_http2: adding support for handling trailers in both directions.
         PR 63502. [Stefan Eissing]
    
      *) mod_proxy_http: forward 100-continue, and minimize race conditions when
         reusing backend connections. PR 60330. [Yann Ylavic, Jean-Frederic Clere]
    
      *) mod_proxy_balancer: Fix some HTML syntax issues.  [Christophe Jaillet]
    
      *) When using mod_status with the Event MPM, report the number of requests
         associated with an active connection in the "ACC" field. Previously
         zero was always reported with this MPM.  PR60647. [Eric Covener]
    
      *) mod_http2: remove the no longer existing h2_ngn_shed.c from Cmake.
         [Stefan Eissing]
    
      *) mod_proxy/ssl: Proxy SSL client certificate configuration and other proxy
         SSL configurations broken inside <Proxy> context.  PR 63430.
         [Ruediger Pluem, Yann Ylavic]
    
      *) mod_proxy: allow SSLProxyCheckPeer* usage for all proxy modules.
         PR 61857.  [Markus Gausling <markusgausling googlemail.com>, Yann Ylavic]
    
      *) mod_reqtimeout: Fix default rates missing (not applied) in 2.4.39.
         PR 63325. [Yann Ylavic]
    
      *) mod_info: Fix output of server settings for PIPE_BUF in mod_info in
         the rare case that PIPE_BUF is defined. [Rainer Jung]
    
      *) mod_md: Store permissions are enforced on file creation, enforcing restrictions in
         spite of umask. Fixes <https://github.com/icing/mod_md/issues/117>. [Stefan Eissing]
    
    Changes with Apache 2.4.39
    
      *) SECURITY: CVE-2019-0197 (cve.mitre.org)
         mod_http2: fixes a possible crash when HTTP/2 was enabled for a http:
         host or H2Upgrade was enabled for h2 on a https: host. An Upgrade
         request from http/1.1 to http/2 that was not the first request on a
         connection could lead to a misconfiguration and crash. Servers that
         never enabled the h2 protocol or only enabled it for https: and
         did not set "H2Upgrade on" are unaffected by this issue.
         [Stefan Eissing]
    
      *) SECURITY: CVE-2019-0196 (cve.mitre.org)
         mod_http2: using fuzzed network input, the http/2 request
         handling could be made to access freed memory in string
         comparison when determining the method of a request and
         thus process the request incorrectly. [Stefan Eissing]
    
      *) SECURITY: CVE-2019-0211 (cve.mitre.org)
         MPMs unix: Fix a local privilege escalation vulnerability by not
         maintaining each child's listener bucket number in the scoreboard,
         preventing unprivileged code like scripts run by/on the server (e.g. via
         mod_php) from modifying it persistently to abuse the privileged main
         process.  [Charles Fol <folcharles gmail.com>, Yann Ylavic]
    
      *) SECURITY: CVE-2019-0217 (cve.mitre.org)
         mod_auth_digest: Fix a race condition checking user credentials which
         could allow a user with valid credentials to impersonate another,
         under a threaded MPM.  PR 63124.  [Simon Kappel <simon.kappel axis.com>]
    
      *) SECURITY: CVE-2019-0215 (cve.mitre.org)
         mod_ssl: Fix access control bypass for per-location/per-dir client
         certificate verification in TLSv1.3.
    
      *) SECURITY: CVE-2019-0220 (cve.mitre.org)
         Merge consecutive slashes in URL's. Opt-out with
         `MergeSlashes OFF`. [Eric Covener]
    
      *) mod_proxy/ssl: Cleanup per-request SSL configuration anytime a backend
         connection is recycled/reused to avoid a possible crash with some SSLProxy
         configurations in <Location> or <Proxy> context. PR 63256. [Yann Ylavic]
    
      *) mod_log_config: Support %{c}h for conn-hostname, %h for useragent_host
         PR 55348
    
      *) mod_socache_redis: Support for Redis as socache storage provider.
    
      *) core: new configuration option 'MergeSlashes on|off' that controls handling of
         multiple, consecutive slash ('/') characters in the path component of the request URL.
         [Eric Covener]
    
      *) mod_http2: when SSL renegotiation is inhibited and a 403 ErrorDocument is
         in play, the proper HTTP/2 stream reset did not trigger with H2_ERR_HTTP_1_1_REQUIRED.
         Fixed. [Michael Kaufmann]
    
      *) mod_http2: new configuration directive: `H2Padding numbits` to control
         padding of HTTP/2 payload frames. 'numbits' is a number from 0-8,
         controlling the range of padding bytes added to a frame. The actual number
         added is chosen randomly per frame. This applies to HEADERS, DATA and PUSH_PROMISE
         frames equally. The default continues to be 0, e.g. no padding. [Stefan Eissing]
    
      *) mod_http2: ripping out all the h2_req_engine internal features now that mod_proxy_http2
         has no more need for it. Optional functions are still declared but no longer implemented.
         While previous mod_proxy_http2 will work with this, it is recommended to run the matching
         versions of both modules. [Stefan Eissing]
    
      *) mod_proxy_http2: changed mod_proxy_http2 implementation and fixed several bugs which
         resolve PR63170. The proxy module does now a single h2 request on the (reused)
         connection and returns. [Stefan Eissing]
    
      *) mod_http2/mod_proxy_http2: proxy_http2 checks correct master connection aborted status
         to trigger immediate shutdown of backend connections. This is now always signalled
         by mod_http2 when the the session is being released.
         proxy_http2 now only sends a PING frame to the backend when there is not already one
         in flight. [Stefan Eissing]
    
      *) mod_proxy_http2: fixed an issue where a proxy_http2 handler entered an infinite
         loop when encountering certain errors on the backend connection.
         See <https://bz.apache.org/bugzilla/show_bug.cgi?id=63170>. [Stefan Eissing]
    
      *) mod_http2: Configuration directives H2Push and H2Upgrade can now be specified per
         Location/Directory, e.g. disabling PUSH for a specific set of resources. [Stefan Eissing]
    
      *) mod_http2: HEAD requests to some module such as mod_cgid caused the stream to
         terminate improperly and cause a HTTP/2 PROTOCOL_ERROR.
         Fixes <https://github.com/icing/mod_h2/issues/167>. [Michael Kaufmann]
    
      *) http: Fix possible empty response with mod_ratelimit for HEAD requests.
         PR 63192. [Yann Ylavic]
    
      *) mod_cache_socache: Avoid reallocations and be safe with outgoing data
         lifetime. [Yann Ylavic]
    
      *) mod_http2: enable re-use of slave connections again. Fixed slave connection
         keepalives counter. [Stefan Eissing]
    
      *) mod_reqtimeout: Allow to configure (TLS-)handshake timeouts.
         PR 61310. [Yann Ylavic]
    
      *) core: Split out the ability to parse wildcard files and directories
         from the Include/IncludeOptional directives into a generic set of
         functions ap_dir_nofnmatch() and ap_dir_fnmatch(). [Graham Leggett]
    
      *) mod_proxy_wstunnel: Fix websocket proxy over UDS.
         PR 62932 <pavel dcmsys.com>
    
      *) mod_ssl: Don't unset FIPS mode on restart unless it's forced by
         configuration (SSLFIPS on) and not active by default in OpenSSL.
         PR 63136. [Yann Ylavic]
    
    Changes with Apache 2.4.38
    
      *) SECURITY: CVE-2018-17199 (cve.mitre.org)
         mod_session: mod_session_cookie does not respect expiry time allowing
         sessions to be reused.  [Hank Ibell]
    
      *) SECURITY: CVE-2018-17189 (cve.mitre.org)
         mod_http2: fixes a DoS attack vector. By sending slow request bodies
         to resources not consuming them, httpd cleanup code occupies a server
         thread unnecessarily. This was changed to an immediate stream reset
         which discards all stream state and incoming data.  [Stefan Eissing]
    
      *) SECURITY: CVE-2019-0190 (cve.mitre.org)
         mod_ssl: Fix infinite loop triggered by a client-initiated
         renegotiation in TLSv1.2 (or earlier) with OpenSSL 1.1.1 and
         later.  PR 63052.  [Joe Orton]
    
      *) mod_ssl: Clear retry flag before aborting client-initiated renegotiation.
         PR 63052 [Joe Orton]
    
      *) mod_negotiation: Treat LanguagePriority as case-insensitive to match
         AddLanguage behavior and HTTP specification. PR 39730 [Christophe Jaillet]
    
      *) mod_md: incorrect behaviour when synchronizing ongoing ACME challenges
         have been fixed. [Michael Kaufmann, Stefan Eissing]
    
      *) mod_setenvif: We can have expressions that become true if a regex pattern
         in the expression does NOT match. In this case val is NULL
         and we should just set the value for the environment variable
         like in the pattern case. [Ruediger Pluem]
    
      *) mod_session: Always decode session attributes early. [Hank Ibell]
    
      *) core: Incorrect values for environment variables are substituted when
         multiple environment variables are specified in a directive. [Hank Ibell]
    
      *) mod_rewrite: Only create the global mutex used by "RewriteMap prg:" when
         this type of map is present in the configuration.  PR62311.
         [Hank Ibell <hwibell gmail.com>]
    
      *) mod_dav: Fix invalid Location header when a resource is created by
         passing an absolute URI on the request line [Jim Jagielski]
    
      *) mod_session_cookie: avoid duplicate Set-Cookie header in the response.
         [Emmanuel Dreyfus <manu@netbsd.org>, Luca Toscano]
    
      *) mod_ssl: clear *SSL errors before loading certificates and checking
         afterwards. Otherwise errors are reported when other SSL using modules
         are in play. Fixes PR 62880. [Michael Kaufmann]
    
      *) mod_ssl: Fix the error code returned in an error path of
         'ssl_io_filter_handshake()'. This messes-up error handling performed
         in 'ssl_io_filter_error()' [Yann Ylavic]
    
      *) mod_ssl: Fix $HTTPS definition for "SSLEngine optional" case, and fix
         authz provider so "Require ssl" works correctly in HTTP/2.
         PR 61519, 62654.  [Joe Orton, Stefan Eissing]
    
      *) mod_proxy: If ProxyPassReverse is used for reverse mapping of relative
         redirects, subsequent ProxyPassReverse statements, whether they are
         relative or absolute, may fail.  PR 60408.  [Peter Haworth <pmh1wheel gmail.com>]
    
      *) mod_lua: Now marked as a stable module [https://s.apache.org/Xnh1]
    
    Changes with Apache 2.4.37
    
      *) mod_ssl: Fix HTTP/2 failures when using OpenSSL 1.1.1. [Rainer Jung]
    
      *) mod_ssl: Fix crash during SSL renegotiation with OptRenegotiate set,
         when client certificates are available from the original handshake
         but were originally not verified and should get verified now.
         This is a regression in 2.4.36 (unreleased). [Ruediger Pluem]
    
      *) mod_ssl: Correctly merge configurations that have client certificates set
         by SSLProxyMachineCertificate{File|Path}. [Ruediger Pluem]
    
    Changes with Apache 2.4.36
    
      *) mod_brotli, mod_deflate: Restore the separate handling of 304 Not Modified
         responses. Regression introduced in 2.4.35.
    
      *) mod_proxy_scgi, mod_proxy_uwsgi: improve error handling when sending the
         body of the response. [Jim Jagielski]
    
      *) mpm_event: Stop issuing AH00484 "server reached MaxRequestWorkers..." when
         there are still idle threads available. When there are less idle threads than
         MinSpareThreads, issue new one-time message AH10159. Matches worker MPM.
         [Eric Covener]
    
      *) mod_http2: adding defensive code for stream EOS handling, in case the request handler
         missed to signal it the normal way (eos buckets). Addresses github issues
         https://github.com/icing/mod_h2/issues/164, https://github.com/icing/mod_h2/issues/167
         and https://github.com/icing/mod_h2/issues/170. [Stefan Eissing]
    
      *) ab: Add client certificate support.  PR 55774.  [Graham Leggett]
    
      *) ab: Disable printing temp key for OpenSSL before
         version 1.0.2. SSL_get_server_tmp_key is not available
         there. [Rainer Jung]
    
      *) mod_ssl: Fix a regression that the configuration settings for verify mode
         and verify depth were taken from the frontend connection in case of
         connections by the proxy to the backend. PR 62769. [Ruediger Pluem]
    
      *) MPMs: Initialize all runtime/asynchronous objects on a dedicated pool and
         before signals handling to avoid lifetime issues on restart or shutdown.
         PR 62658. [Yann Ylavic]
    
      *) mod_ssl: Add support for OpenSSL 1.1.1 and TLSv1.3.  TLSv1.3 has
         behavioural changes compared to v1.2 and earlier; client and
         configuration changes should be expected.  SSLCipherSuite is
         enhanced for TLSv1.3 ciphers, but applies at vhost level only.
         [Stefan Eissing, Yann Ylavic, Ruediger Pluem, Joe Orton]
    
      *) mod_auth_basic: Be less tolerant when parsing the credencial. Only spaces
         should be accepted after the authorization scheme. \t are also tolerated.
         [Christophe Jaillet]
    
      *) mod_socache_redis: New socache submodule provider to allow use
         of Redis as storage backend. [Jim Jagielski]
    
      *) mod_proxy_hcheck: Fix issues with interval determination. PR 62318
         [Jim Jagielski]
    
      *) mod_proxy_hcheck: Fix issues with TCP health checks. PR 61499
         [Dominik Stillhard <dominik.stillhard united-security-providers.ch>]
    
      *) mod_proxy_hcheck: take balancer's SSLProxy* directives into account.
         [Jim Jagielski]
    
      *) mod_status, mod_echo: Fix the display of client addresses.
        They were truncated to 31 characters which is not enough for IPv6 addresses.
        This is done by deprecating the use of the 'client' field and using
        the new 'client64' field in worker_score.
        PR 54848 [Bernhard Schmidt <berni birkenwald de>, Jim Jagielski]
    
    Changes with Apache 2.4.35
    
      *) http: Enforce consistently no response body with both 204 and 304
         statuses.  [Yann Ylavic]
    
      *) mod_status: Cumulate CPU time of exited child processes in the
         "cu" and "cs" values. Add CPU time of the parent process to the
         "c" and "s" values.
         [Rainer Jung]
    
      *) mod_proxy: Improve the balancer member data shown in mod_status when
         "ProxyStatus" is "On": add "busy" count and show byte counts in
         auto mode always in units of kilobytes.  [Rainer Jung]
    
      *) mod_status: Add cumulated response duration time in milliseconds.
         [Rainer Jung]
    
      *) mod_status: Complete the data shown for async MPMs in "auto" mode.
         Added number of processes, number of stopping processes and number
         of busy and idle workers.  [Rainer Jung]
    
      *) mod_ratelimit: Don't interfere with "chunked" encoding, fixing regression
         introduced in 2.4.34.  PR 62568.  [Yann Ylavic]
    
      *) mod_proxy: Remove load order and link dependency between mod_lbmethod_*
         modules and mod_proxy. PR 62557. [Ruediger Pluem, William Rowe]
    
      *) Allow the argument to <IfFile>, <IfDefine>, <IfSection>, <IfDirective>,
         and <IfModule> to be quoted.  This is primarily for the benefit of
         <IfFile>. [Eric Covener]
    
      *) mod_watchdog: Correct some log messages.  [Rainer Jung]
    
      *) mod_md: When the last domain name from an MD is moved to another one,
         that now empty MD gets moved to the store archive. PR 62572.
         [Stefan Eissing]
    
      *) mod_ssl: Fix merging of SSLOCSPOverrideResponder.  [Jeff Trawick,
         [Frank Meier <frank meier ergon.ch>]
    
      *) mod_proxy_balancer: Restore compatibility with APR 1.4.  [Joe Orton]
    
    Changes with Apache 2.4.34
    
      *) SECURITY: CVE-2018-8011 (cve.mitre.org)
         mod_md: DoS via Coredumps on specially crafted requests
    
      *) SECURITY: CVE-2018-1333 (cve.mitre.org)
         mod_http2: DoS for HTTP/2 connections by specially crafted requests
    
      *) Introduce zh-cn and zh-tw (simplified and traditional Chinese) error
         document translations. [CodeingBoy, popcorner]
    
      *) event: avoid possible race conditions with modules on the child pool.
         [Stefan Fritsch]
    
      *) mod_proxy: Fix a corner case where the ProxyPassReverseCookieDomain or
         ProxyPassReverseCookiePath directive could fail to update correctly
         'domain=' or 'path=' in the 'Set-Cookie' header.  PR 61560.
         [Christophe Jaillet]
    
      *) mod_ratelimit: fix behavior when proxing content. PR 62362.
         [Luca Toscano, Yann Ylavic]
    
      *) core: Re-allow '_' (underscore) in hostnames.
         [Eric Covener]
    
      *) mod_authz_core: If several parameters are used in a AuthzProviderAlias
         directive, if these parameters are not enclosed in quotation mark, only
         the first one is handled. The other ones are silently ignored.
         Add a message to warn about such a spurious configuration.
         PR 62469 [Hank Ibell <hwibell gmail.com>, Christophe Jaillet]
    
      *) mod_md: improvements and bugfixes
         - MDNotifyCmd now takes additional parameter that are passed on to the called command.
         - ACME challenges have better checks for interference with other modules
         - ACME challenges are only handled for domains managed by the module, allowing
           other ACME clients to operate for other domains in the server.
         - better libressl integration
    
      *) mod_proxy_wstunnel: Add default schema ports for 'ws' and 'wss'.
         PR 62480. [Lubos Uhliarik <luhliari redhat.com>}
    
      *) logging: Some early logging-related startup messages could be lost
         when using syslog for the global ErrorLog. [Eric Covener]
    
      *) mod_cache: Handle case of an invalid Expires header value RFC compliant
         like the case of an Expires time in the past: allow to overwrite the
         non-caching decision using CacheStoreExpired and respect Cache-Control
         "max-age" and "s-maxage".  [Rainer Jung]
    
      *) mod_xml2enc: Fix forwarding of error metadata/responses. PR 62180.
         [Micha Lenk <micha lenk.info>, Yann Ylavic]
    
      *) mod_proxy_http: Fix response header thrown away after the previous one
         was considered too large and truncated. PR 62196. [Yann Ylavic]
    
      *) core: Add and handle AP_GETLINE_NOSPC_EOL flag for ap_getline() family
         of functions to consume the end of line when the buffer is exhausted.
         PR 62198. [Yann Ylavic]
    
      *) mod_proxy_http: Add new worker parameter 'responsefieldsize' to
         allow maximum HTTP response header size to be increased past 8192
         bytes.  PR 62199.  [Hank Ibell <hwibell gmail.com>]
    
      *) mod_ssl: Extend SSLOCSPEnable with mode 'leaf' that only checks the leaf
         of a certificate chain.  PR62112.
         [Ricardo Martin Camarero <rickyepoderi yahoo.es>]
    
      *) http: Fix small memory leak per request when handling persistent
         connections.  [Ruediger Pluem, Joe Orton]
    
      *) mod_proxy_html: Fix variable interpolation and memory allocation failure
         in ProxyHTMLURLMap.  PR 62344.  [Ewald Dieterich <ewald mailbox.org>]
    
      *) mod_remoteip: Fix RemoteIP{Trusted,Internal}ProxyList loading broken by 2.4.30.
         PR 62220.  [Chritophe Jaillet, Yann Ylavic]
    
      *) mod_remoteip: When overriding the useragent address from X-Forwarded-For,
         zero out what had been initialized as the connection-level port.  PR59931.
         [Hank Ibell <hwibell gmail.com>]
    
      *) core: In ONE_PROCESS/debug mode, cleanup everything when exiting.
         [Yann Ylavic]
    
      *) mod_proxy_balancer: Add hot spare member type and corresponding flag (R).
         Hot spare members are used as drop-in replacements for unusable workers
         in the same load balancer set. This differs from hot standbys which are
         only used when all workers in a set are unusable. PR 61140. [Jim Riggs]
    
      *) suexec: Add --enable-suexec-capabilites support on Linux, to use
         setuid/setgid capability bits rather than a setuid root binary.
         [Joe Orton]
    
      *) suexec: Add support for logging to syslog as an alternative to
         logging to a file; use --without-suexec-logfile --with-suexec-syslog.
         [Joe Orton]
    
      *) mod_ssl: Restore 2.4.29 behaviour in SSL vhost merging/enabling
         which broke some rare but previously-working configs.  [Joe Orton]
    
      *) core, log: improve sanity checks for the ErrorLog's syslog config, and
         explicitly allow only lowercase 'syslog' settings. PR 62102
         [Luca Toscano, Jim Riggs, Christophe Jaillet]
    
      *) mod_http2: accurate reporting of h2 data input/output per request via
         mod_logio. Fixes an issue where output sizes where counted n-times on
         reused slave connections.  [Stefan Eissing]
         See github issue: https://github.com/icing/mod_h2/issues/158
    
      *) mod_http2: Fix unnecessary timeout waits in case streams are aborted.
         [Stefan Eissing]
    
      *) mod_http2: restoring the v1.10.16 keepalive timeout behaviour of mod_http2.
         [Stefan Eissing]
    
      *) mod_proxy: Do not restrict the maximum pool size for backend connections
         any longer by the maximum number of threads per process and use a better
         default if mod_http2 is loaded.
         [Yann Ylavic, Ruediger Pluem, Stefan Eissing, Gregg Smith]
    
      *) mod_slotmem_shm: Add generation number to shm filename to fix races
         with graceful restarts. PRs 62044 and 62308.  [Jim Jagielski, Yann Ylavic]
    
      *) core: Preserve the original HTTP request method in the '%<m' LogFormat
         when an path-based ErrorDocument is used.  PR 62186.
         [Micha Lenk <micha lenk.info>]
    
      *) mod_remoteip: make proxy-protocol work on slave connections, e.g. in
         HTTP/2 requests.  [Stefan Eissing]
         See also https://github.com/roadrunner2/mod-proxy-protocol/issues/6
    
      *) mod_ssl: Fix merging of proxy SSL context outside <Proxy> sections,
         regression introduced in 2.4.30. PR 62232. [Rainer Jung, Yann Ylavic]
    
      *) mod_md: Fix compilation with OpenSSL before version 1.0.2.  [Rainer Jung]
    
      *) mod_dumpio: do nothing below log level TRACE7.  [Yann Ylavic]
    
      *) mod_remoteip: Restore compatibility with APR 1.4 (apr_sockaddr_is_wildcard).
         [Eric Covener]
    
      *) core: On ECBDIC platforms, some errors related to oversized headers
         may be misreported or be logged as ASCII escapes.  PR 62200
         [Hank Ibell <hwibell gmail.com>]
    
      *) mod_ssl: Fix cmake-based build.  PR 62266.  [Rainer Jung]
    
      *) core: Add <IfFile>, <IfDirective> and <IfSection> conditional
         section containers.  [Eric Covener, Joe Orton]
    
      *) rotatelogs: Add -D option to create parent directories.  PR 46669.
         [Philippe Lantin <plantin cobaltgroup.com>, Ben Reser, Rainer Jung]
    
    Changes with Apache 2.4.33
    
      *) core: Fix request timeout logging and possible crash for error_log hooks.
         [Yann Ylavic]
    
      *) mod_slomem_shm: Fix failure to create balancers's slotmems in Windows MPM,
         where children processes need to attach them instead since they are owned
         by the parent process already.  [Yann Ylavic]
    
      *) ab: try all destination socket addresses returned by
         apr_sockaddr_info_get instead of failing on first one when not available.
         Needed for instance if localhost resolves to both ::1 and 127.0.0.1
         e.g. if both are in /etc/hosts.  [Jan Kaluza]
    
      *) ab: Use only one connection to determine working destination socket
         address.  [Jan Kaluza]
    
      *) ab: LibreSSL doesn't have or require Windows applink.c.  [Gregg L. Smith]
    
      *) htpasswd/htdigest: Disable support for bcrypt on EBCDIC platforms.
         apr-util's bcrypt implementation doesn't tolerate EBCDIC.  [Eric Covener]
    
      *) htpasswd/htdbm: report the right limit when get_password() overflows.
         [Yann Ylavic]
    
      *) htpasswd: Don't fail in -v mode if password file is unwritable.
         PR 61631.  [Joe Orton]
    
      *) htpasswd: don't point to (unused) stack memory on output
         to make static analysers happy.  PR 60634.
         [Yann Ylavic, reported by shqking and Zhenwei Zou]
    
    Changes with Apache 2.4.32
    
      *) mod_access_compat: Fail if a comment is found in an Allow or Deny
         directive.  [Jan Kaluza]
    
      *) mod_authz_host: Ignore comments after "Require host", logging a
         warning, or logging an error if the line is otherwise empty.
         [Jan Kaluza, Joe Orton]
    
      *) rotatelogs: Fix expansion of %Z in localtime (-l) mode, and fix
         Y2K38 bug.  [Joe Orton]
    
      *) mod_ssl: Support SSL DN raw variable extraction without conversion
         to UTF-8, using _RAW suffix on variable names.  [Joe Orton]
    
      *) ab: Fix https:// connection failures (regression in 2.4.30); fix
         crash generating CSV output for large -n.  [Joe Orton, Jan Kaluza]
    
    Changes with Apache 2.4.31 (not released)
    
      *) mod_proxy_fcgi: Add the support for mod_proxy's flushpackets and flushwait
         parameters. [Luca Toscano, Ruediger Pluem, Yann Ylavic]
    
      *) mod_ldap: Avoid possible crashes, hangs, and busy loops due to
         improper merging of the cache lock in vhost config.
         PR 43164 [Eric Covener]
    
      *) mpm_event: Do lingering close in worker(s).  [Yann Ylavic]
    
      *) mpm_queue: Put fdqueue code in common for MPMs event and worker.
         [Yann Ylavic]
    
    Changes with Apache 2.4.30 (not released)
    
      *) SECURITY: CVE-2017-15710 (cve.mitre.org)
         Out of bound write in mod_authnz_ldap with AuthLDAPCharsetConfig enabled
         [Eric Covener, Luca Toscano, Yann Ylavic]
    
      *) SECURITY: CVE-2018-1283 (cve.mitre.org)
         mod_session: CGI-like applications that intend to read from mod_session's
         'SessionEnv ON' could be fooled into reading user-supplied data instead.
         [Yann Ylavic]
    
      *) SECURITY: CVE-2018-1303 (cve.mitre.org)
         mod_cache_socache: Fix request headers parsing to avoid a possible crash
         with specially crafted input data.  [Ruediger Pluem]
    
      *) SECURITY: CVE-2018-1301 (cve.mitre.org)
         core: Possible crash with excessively long HTTP request headers.
         Impractical to exploit with a production build and production LogLevel.
         [Yann Ylavic]
    
      *) SECURITY: CVE-2017-15715 (cve.mitre.org)
         core: Configure the regular expression engine to match '$' to the end of
         the input string only, excluding matching the end of any embedded
         newline characters. Behavior can be changed with new directive
         'RegexDefaultOptions'. [Yann Ylavic]
    
      *) SECURITY: CVE-2018-1312 (cve.mitre.org)
         mod_auth_digest: Fix generation of nonce values to prevent replay
         attacks across servers using a common Digest domain. This change
         may cause problems if used with round robin load balancers. PR 54637
         [Stefan Fritsch]
    
      *) SECURITY: CVE-2018-1302 (cve.mitre.org)
         mod_http2: Potential crash w/ mod_http2.
         [Stefan Eissing]
    
      *) mod_proxy: Provide an RFC1035 compliant version of the hostname in the
         proxy_worker_shared structure. PR62085 [Graham Leggett]
    
      *) mod_proxy: Worker schemes and hostnames which are too large are no
         longer fatal errors; it is logged and the truncated values are stored.
         [Jim Jagielski]
    
      *) mod_proxy: Allow setting options to globally defined balancer from
         ProxyPass used in VirtualHost. Balancers are now merged using the new
         merge_balancers method which merges the balancers options.  [Jan Kaluza]
    
      *) logresolve: Fix incorrect behavior or segfault if -c flag is used
         Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=823259
         [Stefan Fritsch]
    
      *) mod_remoteip: Add support for PROXY protocol (code donated by Cloudzilla).
         Add ability for PROXY protocol processing to be optional to donated code.
         See also: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
         [Cloudzilla/roadrunner2@GitHub, Jim Jagielski, Daniel Ruggeri]
    
      *) mod_proxy, mod_ssl: Handle SSLProxy* directives in <Proxy> sections,
         allowing per backend TLS configuration.  [Yann Ylavic]
    
      *) mod_proxy_uwsgi: Add in UWSGI proxy (sub)module. [Roberto De Ioris,
         Jim Jagielski]
    
      *) mod_proxy_balancer,mod_slotmem_shm: Rework SHM reuse/deletion to not
         depend on the number of restarts (non-Unix systems) and preserve shared
         names as much as possible on configuration changes for SHMs and persisted
         files.  PR 62044.  [Yann Ylavic, Jim Jagielski]
    
      *) mod_http2: obsolete code removed, no more events on beam pool destruction,
         discourage content encoders on http2-status response (where they do not work).
         [Stefan Eissing]
    
      *) mpm_event: Let the listener thread do its maintenance job on resources
         shortage.  PR 61979.  [Yann Ylavic]
    
      *) mpm_event: Wakeup the listener to re-enable listening sockets.
         [Yann Ylavic]
    
      *) mod_ssl: The SSLCompression directive will now give an error if used
         with an OpenSSL build which does not support any compression methods.
         [Joe Orton]
    
      *) mpm_event,worker: Mask signals for threads created by modules in child
         init, so that they don't receive (implicitly) the ones meant for the MPM.
         PR 62009. [Armin Abfalterer <a.abfalterer gmail com>, Yann Ylavic]
    
      *) mod_md: new experimental, module for managing domains across virtual hosts,
         implementing the Let's Encrypt ACMEv1 protocol to signup and renew
         certificates. Please read the modules documentation for further instructions
         on how to use it. [Stefan Eissing]
    
      *) mod_proxy_html: skip documents shorter than 4 bytes
         PR 56286 [Micha Lenk <micha lenk info>]
    
      *) core, mpm_event: Avoid a small memory leak of the scoreboard handle, for
         the lifetime of the connection, each time it is processed by MPM event.
         [Yann Ylavic]
    
      *) mpm_event: Update scoreboard status for KeepAlive state.  [Yann Ylavic]
    
      *) mod_ldap: Fix a case where a full LDAP cache would continually fail to
         purge old entries and log AH01323. PR61891.
         [Hendrik Harms <hendrik.harms gmail.com>]
    
      *) mpm_event: close connections not reported as handled by any module to
         avoid losing track of them and leaking scoreboard entries.  PR 61551.
         [Yann Ylavic]
    
      *) core: A signal received while stopping could have crashed the main
         process.  PR 61558.  [Yann Ylavic]
    
      *) mod_ssl: support for mod_md added. [Stefan Eissing]
    
      *) mod_proxy_html: process parsed comments immediately.
         Fixes bug (seen in the wild when used with IBM's HTTPD bundle)
         where parsed comments may be lost. [Nick Kew]
    
      *) mod_proxy_html: introduce doctype for HTML 5 [Nick Kew]
    
      *) mod_proxy_html: fix typo-bug processing "strict" vs "transitional"
         HTML/XHTML.  PR 56457  [Nick Kew]
    
      *) mpm_event: avoid a very unlikely race condition between the listener and
         the workers when the latter fails to add a connection to the pollset.
         [Yann Ylavic]
    
      *) core: silently ignore a not existent file path when IncludeOptional
         is used. PR 57585. [Alberto Murillo Silva <powerbsd yahoo.com>, Luca Toscano]
    
      *) mod_macro: fix usability of globally defined macros in .htaccess files.
         PR 57525.  [Jose Kahan <jose w3.org>, Yann Ylavic]
    
      *) mod_rewrite, core: add the Vary header when a condition evaluates to true
         and the related RewriteRule is used in a Directory context
         (triggering an internal redirect). [Luca Toscano]
    
      *) ab: Make the TLS layer aware that the underlying socket is nonblocking,
         and use/handle POLLOUT where needed to avoid busy IOs and recover write
         errors when appropriate.  [Yann Ylavic]
    
      *) ab: Keep reading nonblocking to exhaust TCP or SSL buffers when previous
         read was incomplete (the SSL case can cause the next poll() to timeout
         since data are buffered already).  PR 61301 [Luca Toscano, Yann Ylavic]
    
      *) mod_http2: avoid unnecessary data retrieval for a trace log. Allow certain
         information retrievals on null bucket beams where it makes sense. [Stefan Eissing]
    
    Changes with Apache 2.4.29
    
      *) mod_unique_id: Use output of the PRNG rather than IP address and
         pid, avoiding sleep() call and possible DNS issues at startup,
         plus improving randomness for IPv6-only hosts.  [Jan Kaluza]
    
      *) mod_rewrite, core: Avoid the 'Vary: Host' response header when HTTP_HOST
         is used in a condition that evaluates to true. PR 58231 [Luca Toscano, Yann Ylavic]
    
      *) mod_http2: v0.10.12, removed optimization for mutex handling in bucket
         beams that could lead to assertion failure in edge cases.
         [Stefan Eissing]
    
      *) mod_proxy: Fix regression for non decimal loadfactor parameter introduced
         in 2.4.28.  [Jim Jagielski]
    
      *) mod_authz_dbd: fix a segmentation fault if AuthzDBDQuery is not set.
         PR 61546.  [Lubos Uhliarik <luhliari redhat.com>]
    
      *) mod_rewrite: Add support for starting External Rewriting Programs
         as non-root user on UNIX systems by specifying username and group
         name as third argument of RewriteMap directive.  [Jan Kaluza]
    
      *) core: Rewrite the Content-Length filter to avoid excessive memory
         consumption. Chunked responses will be generated in more cases
         than in previous releases.  PR 61222.  [Joe Orton, Ruediger Pluem]
    
      *) mod_ssl: Fix SessionTicket callback return value, which does seem to
         matter with OpenSSL 1.1. [Yann Ylavic]
    
    Changes with Apache 2.4.28
    
      *) SECURITY: CVE-2017-9798 (cve.mitre.org)
         Corrupted or freed memory access. <Limit[Except]> must now be used in the
         main configuration file (httpd.conf) to register HTTP methods before the
         .htaccess files.  [Yann Ylavic]
    
      *) event: Avoid possible blocking in the listener thread when shutting down
         connections. PR 60956.  [Yann Ylavic]
    
      *) mod_speling: Don't embed referer data in a link in error page.
         PR 38923 [Nick Kew]
    
      *) htdigest: prevent a buffer overflow when a string exceeds the allowed max
         length in a password file. PR 61511.
         [Luca Toscano, Hanno Böck <hanno hboeck de>]
    
      *) mod_proxy: loadfactor parameter can now be a decimal number (eg: 1.25).
         [Jim Jagielski]
    
      *) mod_proxy_wstunnel: Allow upgrade to any protocol dynamically.
         PR 61142.
    
      *) mod_watchdog/mod_proxy_hcheck: Time intervals can now be specified
         down to the millisecond. Supports 'mi' (minute), 'ms' (millisecond),
         's' (second) and 'hr' (hour!) time suffixes. [Jim Jagielski]
    
      *) mod_http2: Fix for stalling when more than 32KB are written to a
         suspended stream.  [Stefan Eissing]
    
      *) build: allow configuration without APR sources.  [Jacob Champion]
    
      *) mod_ssl, ab: Fix compatibility with LibreSSL.  PR 61184.
         [Bernard Spil <brnrd freebsd.org>, Michael Schlenker <msc contact.de>,
          Yann Ylavic]
    
      *) core/log: Support use of optional "tag" in syslog entries.
         PR 60525. [Ben Rubson <ben.rubson gmail.com>, Jim Jagielski]
    
      *) mod_proxy: Fix ProxyAddHeaders merging.  [Joe Orton]
    
      *) core: Disallow multiple Listen on the same IP:port when listener buckets
         are configured (ListenCoresBucketsRatio > 0), consistently with the single
         bucket case (default), thus avoiding the leak of the corresponding socket
         descriptors on graceful restart.  [Yann Ylavic]
    
      *) event: Avoid listener periodic wake ups by using the pollset wake-ability
         when available.  PR 57399.  [Yann Ylavic, Luca Toscano]
    
      *) mod_proxy_wstunnel: Fix detection of unresponded request which could have
         led to spurious HTTP 502 error messages sent on upgrade connections.
         PR 61283.  [Yann Ylavic]
    
    Changes with Apache 2.4.27
    
      *) SECURITY: CVE-2017-9789 (cve.mitre.org)
         mod_http2: Read after free. When under stress, closing many connections,
         the HTTP/2 handling code would sometimes access memory after it has been
         freed, resulting in potentially erratic behaviour.
         [Stefan Eissing]
    
      *) SECURITY: CVE-2017-9788 (cve.mitre.org)
         mod_auth_digest: Uninitialized memory reflection.  The value placeholder
         in [Proxy-]Authorization headers type 'Digest' was not initialized or
         reset before or between successive key=value assignments.
         [William Rowe]
    
      *) COMPATIBILITY: mod_lua: Remove the undocumented exported 'apr_table'
         global variable when using Lua 5.2 or later. This was exported as a
         side effect from luaL_register, which is no longer supported as of
         Lua 5.2 which deprecates pollution of the global namespace.
         [Rainer Jung]
    
      *) COMPATIBILITY: mod_http2: Disable and give warning when using Prefork.
         The server will continue to run, but HTTP/2 will no longer be negotiated.
         [Stefan Eissing]
    
      *) COMPATIBILITY: mod_proxy_fcgi: Revert to 2.4.20 FCGI behavior for the
         default ProxyFCGIBackendType, fixing a regression with PHP-FPM. PR 61202.
         [Jacob Champion, Jim Jagielski]
    
      *) mod_lua: Improve compatibility with Lua 5.1, 5.2 and 5.3.
         PR58188, PR60831, PR61245. [Rainer Jung]
    
      *) mod_http2: Simplify ready queue, less memory and better performance. Update
         mod_http2 version to 1.10.7. [Stefan Eissing]
    
      *) Allow single-char field names inadvertently disallowed in 2.4.25.
         PR 61220. [Yann Ylavic]
    
      *) htpasswd / htdigest: Do not apply the strict permissions of the temporary
         passwd file to a possibly existing passwd file. PR 61240. [Ruediger Pluem]
    
      *) core: Avoid duplicate HEAD in Allow header.
         This is a regression in 2.4.24 (unreleased), 2.4.25 and 2.4.26.
         PR 61207. [Christophe Jaillet]
    
    Changes with Apache 2.4.26
    
      *) SECURITY: CVE-2017-7679 (cve.mitre.org)
         mod_mime can read one byte past the end of a buffer when sending a
         malicious Content-Type response header.  [Yann Ylavic]
    
      *) SECURITY: CVE-2017-7668 (cve.mitre.org)
         The HTTP strict parsing changes added in 2.2.32 and 2.4.24 introduced a
         bug in token list parsing, which allows ap_find_token() to search past
         the end of its input string. By maliciously crafting a sequence of
         request headers, an attacker may be able to cause a segmentation fault,
         or to force ap_find_token() to return an incorrect value.
         [Jacob Champion]
    
      *) SECURITY: CVE-2017-7659 (cve.mitre.org)
         A maliciously constructed HTTP/2 request could cause mod_http2 to
         dereference a NULL pointer and crash the server process.
    
      *) SECURITY: CVE-2017-3169 (cve.mitre.org)
         mod_ssl may dereference a NULL pointer when third-party modules call
         ap_hook_process_connection() during an HTTP request to an HTTPS port.
         [Yann Ylavic]
    
      *) SECURITY: CVE-2017-3167 (cve.mitre.org)
         Use of the ap_get_basic_auth_pw() by third-party modules outside of the
         authentication phase may lead to authentication requirements being
         bypassed.
         [Emmanuel Dreyfus <manu netbsd.org>, Jacob Champion, Eric Covener]
    
      *) HTTP/2 support no longer tagged as "experimental" but is instead considered
         fully production ready.
    
      *) mod_http2: Fix for possible CPU busy loop introduced in v1.10.3 where a stream may keep
         the session in continuous check for state changes that never happen.
         [Stefan Eissing]
    
      *) mod_proxy_wstunnel: Add "upgrade" parameter to allow upgrade to other
         protocols.  [Jean-Frederic Clere]
    
      *) MPMs unix: Place signals handlers and helpers out of DSOs to avoid
         a possible crash if a signal is caught during (graceful) restart.
         PR 60487.  [Yann Ylavic]
    
      *) mod_rewrite: When a substitution is a fully qualified URL, and the
         scheme/host/port matches the current virtual host, stop interpreting the
         path component as a local path just because the first component of the
         path exists in the filesystem.  Adds RewriteOption "LegacyPrefixDocRoot"
         to revert to previous behavior. PR60009.
         [Hank Ibell <hwibell gmail.com>]
    
      *) core: ap_parse_form_data() URL-decoding doesn't work on EBCDIC
         platforms. PR61124. [Hank Ibell <hwibell gmail.com>]
    
      *) ab: enable option processing for setting a custom HTTP method also for
         non-SSL builds.  [Rainer Jung]
    
      *) core: EBCDIC fixes for interim responses with additional headers.
         [Eric Covener]
    
      *) mod_env: when processing a 'SetEnv' directive, warn if the environment
         variable name includes a '='. It is likely a configuration error.
         PR 60249 [Christophe Jaillet]
    
      *) Evaluate nested If/ElseIf/Else configuration blocks.
         [Luca Toscano, Jacob Champion]
    
      *) mod_rewrite: Add 'BNP' (backreferences-no-plus) flag to RewriteRule to
         allow spaces in backreferences to be encoded as %20 instead of '+'.
         [Eric Covener]
    
      *) mod_rewrite: Add the possibility to limit the escaping to specific
         characters in backreferences by listing them in the B flag.
         [Eric Covener]
    
      *) mod_substitute: Fix spurious AH01328 (Line too long) errors on EBCDIC
         systems.  [Eric Covener]
    
      *) mod_http2: fail requests without ERROR log in case we need to read interim
         responses and see only garbage. This can happen if proxied servers send
         data where none should be, e.g. a body for a HEAD request. [Stefan Eissing]
    
      *) mod_proxy_http2: adding support for Reverse Proxy Request headers.
         [Stefan Eissing]
    
      *) mod_http2: fixed possible deadlock that could occur when connections were
         terminated early with ongoing streams. Fixed possible hanger with timeout
         on race when connection considers itself idle. [Stefan Eissing]
    
      *) mod_http2: MaxKeepAliveRequests now limits the number of times a
         slave connection gets reused. [Stefan Eissing]
    
      *) mod_brotli: Add a new module for dynamic Brotli (RFC 7932) compression.
         [Evgeny Kotkov]
    
      *) mod_proxy_http2: Fixed bug in re-attempting proxy requests after
         connection error. Reliability of reconnect handling improved.
         [Stefan Eissing]
    
      *) mod_http2: better performance, eliminated need for nested locks and
         thread privates. Moving request setups from the main connection to the
         worker threads. Increase number of spare connections kept.
         [Stefan Eissing]
    
      *) mod_http2: input buffering and dynamic flow windows for increased
         throughput. Requires nghttp2 >= v1.5.0 features. Announced at startup
         in mod_http2 INFO log as feature 'DWINS'. [Stefan Eissing]
    
      *) mod_http2: h2 workers with improved scalability for better scheduling
         performance. There are H2MaxWorkers threads created at start and the
         number is kept constant for now. [Stefan Eissing]
    
      *) mod_http2: obsoleted option H2SessionExtraFiles, will be ignored and
         just log a warning. [Stefan Eissing]
    
      *) mod_autoindex: Add IndexOptions UseOldDateFormat to allow the date
         format from 2.2 in the Last Modified column. PR60846.
         [Hank Ibell <hwibell gmail.com>]
    
      *) core: Add %{REMOTE_PORT} to the expression parser. PR59938
         [Hank Ibell <hwibell gmail.com>]
    
      *) mod_cache: Fix a regression in 2.4.25 for the forward proxy case by
         computing and using the same entity key according to when the cache
         checks, loads and saves the request.
         PR 60577.  [Yann Ylavic]
    
      *) mod_proxy_hcheck: Don't validate timed out responses.  [Yann Ylavic]
    
      *) mod_proxy_hcheck: Ensure thread-safety when concurrent healthchecks are
         in use (ProxyHCTPsize > 0).  PR 60071.  [Yann Ylavic, Jim Jagielski]
    
      *) core: %{DOCUMENT_URI} used in nested SSI expressions should point to the
         URI originally requested by the user, not the nested documents URI. This
         restores the behavior of this variable to match the "legacy" SSI parser.
         PR60624. [Hank Ibell <hwibell gmail.com>]
    
      *) mod_proxy_fcgi: Add ProxyFCGISetEnvIf to fixup CGI environment
         variables just before invoking the FastCGI. [Eric Covener,
         Jacob Champion]
    
      *) mod_proxy_fcgi: Return to 2.4.20-and-earlier behavior of leaving
         a "proxy:fcgi://" prefix in the SCRIPT_FILENAME environment variable by
         default.  Add ProxyFCGIBackendType to allow the type of backend to be
         specified so these kinds of fixups can be restored without impacting
         FPM. PR60576 [Eric Covener, Jim Jagielski]
    
      *) mod_ssl: work around leaks on (graceful) restart. [Yann Ylavic]
    
      *) mod_ssl: Add support for OpenSSL 1.1.0. [Rainer Jung]
    
      *) Don't set SO_REUSEPORT unless ListenCoresBucketsRatio is greater
         than zero.  [Eric Covener]
    
      *) mod_http2: moving session cleanup to pre_close hook to avoid races with
         modules already shut down and slave connections still operating.
         [Stefan Eissing]
    
      *) mod_lua: Support for Lua 5.3
    
      *) mod_proxy_http2: support for ProxyPreserverHost directive. [Stefan Eissing]
    
      *) mod_http2: fix for crash when running out of memory.
         [Robert Swiecki <robert swiecki.net>, Stefan Eissing]
    
      *) mod_proxy_fcgi: Return HTTP 504 rather than 503 in case of proxy timeout.
         [Luca Toscano]
    
      *) mod_http2: not counting file buckets again stream max buffer limits.
         Effectively transferring static files in one step from slave to master
         connection. [Stefan Eissing]
    
      *) mod_http2: comforting ap_check_pipeline() on slave connections
         to facilitate reuse (see https://github.com/icing/mod_h2/issues/128).
         [Stefan Eissing, reported by Armin Abfalterer]
    
      *) mod_http2: http/2 streams now with state handling/transitions as defined
         in RFC7540. Stream cleanup/connection shutdown reworked to become easier
         to understand/maintain/debug. Added many asserts on state and cleanup
         transitions. [Stefan Eissing]
    
      *) mod_auth_digest: Use an anonymous shared memory segment by default,
         preventing startup failure after unclean shutdown.  PR 54622.
         [Jan Kaluza]
    
      *) mod_filter: Fix AddOutputFilterByType with non-content-level filters.
         PR 58856. [Micha Lenk <micha lenk.info>]
    
      *) mod_watchdog: Fix semaphore leak over restarts.  [Jim Jagielski]
    
      *) mod_http2: regression fix on PR 59348, on graceful restart, ongoing
         streams are finished normally before the final GOAWAY is sent.
         [Stefan Eissing, <slavko gmail.com>]
    
      *) mod_proxy: Allow the per-request environment variable "no-proxy" to
         be used as an alternative to ProxyPass /path !. This is primarily
         to set exceptions for ProxyPass specified in <Location> context.
         Use SetEnvIf, not SetEnv. PR 60458.  [Eric Covener]
    
      *) mod_http2: fixes PR60599, sending proper response for conditional requests
         answered by mod_cache. [Jeff Wheelhouse, Stefan Eissing]
    
      *) mod_http2: rework of stream resource cleanup to avoid a crash in a close
         of a lingering connection. Prohibit special file bucket beaming for
         shared buckets. Files sent in stream output now use the stream pool
         as read buffer, reducing memory footprint of connections.
         [Yann Ylavic, Stefan Eissing]
    
      *) mod_proxy_fcgi, mod_fcgid: Fix crashes in ap_fcgi_encoded_env_len() when
         modules add empty environment variables to the request. PR 60275.
         [<alex2grad AT gmail.com>]
    
      *) mod_http2: fix for possible page fault when stream is resumed during
         session shutdown. [sidney-j-r-m (github)]
    
      *) mod_http2: fix for h2 session ignoring new responses while already
         open streams continue to have data available. [Stefan Eissing]
    
      *) mod_http2: adding support for MergeTrailers directive. [Stefan Eissing]
    
      *) mod_http2: limiting DATA frame sizes by TLS record sizes in use on the
         connection. Flushing outgoing frames earlier. [Stefan Eissing]
    
      *) mod_http2: cleanup beamer registry on server reload.  PR 60510.
         [Pavel Mateja <pavel verotel.cz>, Stefan Eissing]
    
      *) mod_proxy_{ajp,fcgi}: Fix a possible crash when reusing an established
         backend connection, happening with LogLevel trace2 or higher configured,
         or at any log level with compilers not detected as C99 compliant (e.g.
         MSVC on Windows).  [Yann Ylavic]
    
      *) mod_ext_filter: Don't interfere with "error buckets" issued by other
         modules. PR 60375.  [Eric Covener, Lubos Uhliarik]
    
      *) mod_http2: fixes https://github.com/icing/mod_h2/issues/126 e.g. beam
         bucket lifetime handling when data is sent over temporary pools.
         [Stefan Eissing]
    
    Changes with Apache 2.4.25
    
      *) Fix some build issues related to various modules.
         [Rainer Jung]
    
    Changes with Apache 2.4.24 (not released)
    
      *) SECURITY: CVE-2016-8740 (cve.mitre.org)
         mod_http2: Mitigate DoS memory exhaustion via endless
         CONTINUATION frames.
         [Naveen Tiwari <naveen.tiwari@asu.edu> and CDF/SEFCOM at Arizona State
         University, Stefan Eissing]
    
      *) SECURITY: CVE-2016-2161 (cve.mitre.org)
         mod_auth_digest: Prevent segfaults during client entry allocation when
         the shared memory space is exhausted.
         [Maksim Malyutin <m.malyutin dsec.ru>, Eric Covener, Jacob Champion]
    
      *) SECURITY: CVE-2016-0736 (cve.mitre.org)
         mod_session_crypto: Authenticate the session data/cookie with a
         MAC (SipHash) to prevent deciphering or tampering with a padding
         oracle attack.  [Yann Ylavic, Colm MacCarthaigh]
    
      *) SECURITY: CVE-2016-8743 (cve.mitre.org)
         Enforce HTTP request grammar corresponding to RFC7230 for request lines
         and request headers, to prevent response splitting and cache pollution by
         malicious clients or downstream proxies. [William Rowe, Stefan Fritsch]
    
      *) Validate HTTP response header grammar defined by RFC7230, resulting
         in a 500 error in the event that invalid response header contents are
         detected when serving the response, to avoid response splitting and cache
         pollution by malicious clients, upstream servers or faulty modules.
         [Stefan Fritsch, Eric Covener, Yann Ylavic]
    
      *) core: Mitigate [f]cgi CVE-2016-5387 "httpoxy" issues.
         [Dominic Scheirlinck <dominic vendhq.com>, Yann Ylavic]
    
      *) mod_rewrite: Limit runaway memory use by short circuiting some kinds of
         looping RewriteRules when the local path significantly exceeds
         LimitRequestLine.  PR 60478. [Jeff Wheelhouse <apache wheelhouse.org>]
    
      *) mod_ratelimit: Allow for initial "burst" amount at full speed before
         throttling: PR 60145 [Andy Valencia <ajv-etradanalhos vsta.org>,
         Jim Jagielski]
    
      *) mod_socache_memcache: Provide memcache stats to mod_status.
         [Jim Jagielski]
    
      *) mod_file_cache: mod_file_cache should be able to serve files that
         haven't had a Content-Type set via e.g. mod_mime. [Eric Covener]
    
      *) http_filters: Fix potential looping in new check_headers() due to new
         pattern of ap_die() from http header filter. Explicitly clear the
         previous headers and body.
    
      *) core: Drop Content-Length header and message-body from HTTP 204 responses.
         PR 51350 [Luca Toscano]
    
      *) mod_proxy: Honor a server scoped ProxyPass exception when ProxyPass is
         configured in <Location>, like in 2.2. PR 60458.
         [Eric Covener]
    
      *) mod_lua: Fix default value of LuaInherit directive. It should be
         'parent-first' instead of 'none', as per documentation.  PR 60419
         [Christophe Jaillet]
    
      *) core: New directive HttpProtocolOptions to control httpd enforcement
         of various RFC7230 requirements. [Stefan Fritsch, William Rowe]
    
      *) core: Permit unencoded ';' characters to appear in proxy requests and
         Location: response headers. Corresponds to modern browser behavior.
         [William Rowe]
    
      *) core: ap_rgetline_core now pulls from r->proto_input_filters.
    
      *) core: Correctly parse an IPv6 literal host specification in an absolute
         URL in the request line. [Stefan Fritsch]
    
      *) core: New directive RegisterHttpMethod for registering non-standard
         HTTP methods. [Stefan Fritsch]
    
      *) mod_socache_memcache: Pass expiration time through to memcached. PR 55445.
         [Faidon Liambotis <paravoid debian.org>, Joe Orton]
    
      *) mod_cache: Use the actual URI path and query-string for identifying the
         cached entity (key), such that rewrites are taken into account when
         running afterwards (CacheQuickHandler off).  PR 21935.  [Yann Ylavic]
    
      *) mod_http2: new directive 'H2EarlyHints' to enable sending of HTTP status
         103 interim responses. Disabled by default. [Stefan Eissing]
    
      *) mod_ssl: Fix quick renegotiation (OptRenegotiaton) with no intermediate
         in the client certificate chain.  PR 55786.  [Yann Ylavic]
    
      *) event: Allow to use the whole allocated scoreboard (up to ServerLimit
         slots) to avoid scoreboard full errors when some processes are finishing
         gracefully. Also, make gracefully finishing processes close all
         keep-alive connections. PR 53555. [Stefan Fritsch]
    
      *) mpm_event: Don't take over scoreboard slots from gracefully finishing
         threads. [Stefan Fritsch]
    
      *) mpm_event: Free memory earlier when shutting down processes.
         [Stefan Fritsch]
    
      *) mod_status: Display the process slot number in the async connection
         overview. [Stefan Fritsch]
    
      *) mod_dir: Responses that go through "FallbackResource" might appear to
         hang due to unterminated chunked encoding. PR58292. [Eric Covener]
    
      *) mod_dav: Fix a potential cause of unbounded memory usage or incorrect
         behavior in a routine that sends <DAV:response>'s to the output filters.
         [Evgeny Kotkov]
    
      *) mod_http2: new directive 'H2PushResource' to enable early pushes before
         processing of the main request starts. Resources are announced to the
         client in Link headers on a 103 early hint response.
         All responses with status code <400 are inspected for Link header and
         trigger pushes accordingly. 304 still does prevent pushes.
         'H2PushResource' can mark resources as 'critical' which gives them higher
         priority than the main resource. This leads to preferred scheduling for
         processing and, when content is available, will send it first. 'critical'
         is also recognized on Link headers. [Stefan Eissing]
    
      *) mod_proxy_http2: uris in Link headers are now mapped back to a suitable
         local url when available. Relative uris with an absolute path are mapped
         as well. This makes reverse proxy mapping available for resources
         announced in this header.
         With 103 interim responses being forwarded to the main client connection,
         this effectively allows early pushing of resources by a reverse proxied
         backend server. [Stefan Eissing]
    
      *) mod_proxy_http2: adding support for newly proposed 103 status code.
         [Stefan Eissing]
    
      *) mpm_unix: Apache fails to start if previously crashed then restarted with
         the same PID (e.g. in container).  PR 60261.
         [Val <valentin.bremond gmail.com>, Yann Ylavic]
    
      *) mod_http2: unannounced and multiple interim responses (status code < 200)
         are parsed and forwarded to client until a final response arrives.
         [Stefan Eissing]
    
      *) mod_proxy_http2: improved robustness when main connection is closed early
         by resetting all ongoing streams against the backend.
         [Stefan Eissing]
    
      *) mod_http2: allocators from slave connections are released earlier,
         resulting in less overall memory use on busy, long lived connections.
         [Stefan Eissing]
    
      *) mod_remoteip: Pick up where we left off during a subrequest rather
         than running with the modified XFF but original TCP address.
         PR 49839/PR 60251
    
      *) http: Respond with "408 Request Timeout" when a timeout occurs while
         reading the request body.  [Yann Ylavic]
    
      *) mod_http2: connection shutdown revisited: corrected edge cases on
         shutting down ongoing streams, changed log warnings to be less noisy
         when waiting on long running tasks. [Stefan Eissing]
    
      *) mod_http2: changed all AP_DEBUG_ASSERT to ap_assert to have them
         available also in normal deployments. [Stefan Eissing]
    
      *) mod_http2/mod_proxy_http2: 100-continue handling now properly implemented
         up to the backend. Reused HTTP/2 proxy connections with more than a second
         not used will block request bodies until a PING answer is received.
         Requests headers are not delayed by this, since they are repeatable in
         case of failure. This greatly increases robustness, especially with
         busy server and/or low keepalive connections. [Stefan Eissing]
    
      *) mod_proxy_http2: fixed duplicate symbols with mod_http2.
         [Stefan Eissing]
    
      *) mod_http2: rewrite of how responses and trailers are transferred between
         master and slave connection. Reduction of internal states for tasks
         and streams, stability. Heuristic id generation for slave connections
         to better keep promise of connection ids unique at given point int time.
         Fix for mod_cgid interop in high load situations.
         Fix for handling of incoming trailers when no request body is sent.
         [Stefan Eissing]
    
      *) mod_http2: fix suspended handling for streams. Output could become
         blocked in rare cases. [Stefan Eissing]
    
      *) mpm_winnt: Prevent a denial of service when the 'data' AcceptFilter is in
         use by replacing it with the 'connect' filter. PR 59970. [Jacob Champion]
    
      *) mod_cgid: Resolve a case where a short CGI response causes a subsequent
         CGI to be killed prematurely, resulting in a truncated subsequent
         response. [Eric Covener]
    
      *) mod_proxy_hcheck: Set health check URI and expression correctly for health
         check worker. PR 60038 [zdeno <zdeno@scnet.sk>]
    
      *) mod_http2: if configured with nghttp2 1.14.0 and onward, invalid request
         headers will immediately reset the stream with a PROTOCOL error. Feature
         logged by module on startup as 'INVHD' in info message.
         [Stefan Eissing]
    
      *) mod_http2: fixed handling of stream buffers during shutdown.
         [Stefan Eissing]
    
      *) mod_reqtimeout: Fix body timeout disabling for CONNECT requests to avoid
         triggering mod_proxy_connect's AH01018 once the tunnel is established.
         [Yann Ylavic]
    
      *) ab: Set the Server Name Indication (SNI) extension on outgoing TLS
         connections (unless -I is specified), according to the Host header (if
         any) or the requested URL's hostname otherwise.  [Yann Ylavic]
    
      *) mod_proxy_fcgi: avoid loops when ProxyErrorOverride is enabled
         and the error documents are proxied. PR 55415. [Luca Toscano]
    
      *) mod_proxy_fcgi: read the whole FCGI response even when the content
         has not been modified (HTTP 304) or in case of a precondition failure
         (HTTP 412) to avoid subsequent bogus reads and confusing
         error messages logged. [Luca Toscano]
    
      *) mod_http2: h2 status resource follows latest draft, see
         http://www.ietf.org/id/draft-benfield-http2-debug-state-01.txt
         [Stefan Eissing]
    
      *) mod_http2: handling graceful shutdown gracefully, e.g. handling existing
         streams to the end. [Stefan Eissing]
    
      *) mod_proxy_{http,ajp,fcgi}: don't reuse backend connections with data
         available before the request is sent.  PR 57832.  [Yann Ylavic]
    
      *) mod_proxy_balancer: Prevent redirect loops between workers within a
         balancer by limiting the number of redirects to the number balancer
         members. PR 59864 [Ruediger Pluem]
    
      *) mod_proxy: Correctly consider error response codes by the backend when
         processing failonstatus. PR 59869 [Ruediger Pluem]
    
      *) mod_dav: Add dav_get_provider_name() function to obtain the name
         of the provider from mod_dav.  [Graham Leggett]
    
      *) mod_dav: Add support for childtags to dav_error.
         [Jari Urpalainen <jari.urpalainen nokia.com>]
    
      *) mod_proxy_fcgi: Fix 2.4.23 breakage for mod_rewrite per-dir and query
         string showing up in SCRIPT_FILENAME. PR59815
    
      *) mod_include: Fix a potential memory misuse while evaluating expressions.
         PR59844. [Eric Covener]
    
      *) mod_http2: new H2CopyFiles directive that changes treatment of file
         handles in responses. Necessary in order to fix broken lifetime handling
         in modules such as mod_wsgi.
    
      *) mod_http2: removing timeouts on master connection while requests are
         being processed. Requests may timeout, but the master only times out when
         no more requests are active. [Stefan Eissing]
    
      *) mod_http2: fixes connection flush when answering SETTINGS without any
         stream open. [Moto Ishizawa <@summerwind>, Stefan Eissing]
    
    Changes with Apache 2.4.23
    
      *) mod_ssl: reset client-verify state of ssl when aborting renegotiations.
         [Erki Aring <erki@example.ee>, Stefan Eissing]
    
      *) mod_sed: Fix 'x' command processing. [Christophe Jaillet]
    
      *) configure: Fix ./configure edge-case failures around dependencies
         of mod_proxy_hcheck. [William Rowe, Ruediger Pluem, Jeff Trawick]
    
    Changes with Apache 2.4.22
    
      *) mod_http2: fix for request abort when connections drops, introduced in
         1.5.8
    
    Changes with Apache 2.4.21
    
      *) core: Added support for HTTP code 451. PR 58985.
         [Yehuda Katz <yehuda ymkatz.net>, Jim Jagielski]
    
      *) ab: Use caseless matching for HTTP tokens (e.g. content-length). PR 59111.
         [Yann Ylavic]
    
      *) mod_http2: more rigid error handling in DATA frame assembly, leading
         to deterministic connection errors if assembly fails.
         [Stefan Eissing, Pal Nilsen <https://github.com/maedox>]
    
      *) abs: Include OPENSSL_Applink when compiling on Windows, to resolve
         failures under Visual Studio 2015 and other mismatched MSVCRT flavors.
         PR59630 [Jan Ehrhardt <phpdev ehrhardt.nl>]
    
      *) mod_ssl: Add "no_crl_for_cert_ok" flag to SSLCARevocationCheck directive
         to opt-in previous behaviour (2.2) with CRLs verification when checking
         certificate(s) with no corresponding CRL.  [Yann Ylavic]
    
      *) mpm_event, mpm_worker: Fix computation of MinSpareThreads' lower bound
         according the number of listeners buckets.  [Yann Ylavic]
    
      *) Add ap_cstr_casecmp[n]() - placeholder of apr_cstr_casecmp[n] functions
         for case-insensitive C/POSIX-locale token comparison.
         [Jim Jagielski, William Rowe, Yann Ylavic, Branko Čibej]
    
      *) mod_userdir: Constify and save a few bytes in the conf pool when
         parsing the "UserDir" directive. [Christophe Jaillet]
    
      *) mod_cache: Fix (max-stale with no '=') and enforce (check
         integers after '=') Cache-Control header parsing.
         [Christophe Jaillet]
    
      *) core: Add -DDUMP_INCLUDES configtest option to show the tree
         of Included configuration files.
         [Jacob Champion <champion.pxi gmail.com>]
    
      *) mod_proxy_fcgi: Avoid passing a filename of proxy:fcgi:// as
         SCRIPT_FILENAME to a FastCGI server. PR59618.
         [Jacob Champion <champion.pxi gmail.com>]
    
      *) mod_dav: Add dav_get_provider_name() function to obtain the name
         of the provider from mod_dav.
         [Jari Urpalainen <jari.urpalainen nokia.com>]
    
      *) mod_proxy_http2: properly care for HTTP2 flow control of the frontend
         connection is HTTP/1.1. [Patch supplied by Evgeny Kotkov]
    
      *) mod_http2: improved cleanup of connection/streams/tasks to always
         have deterministic order regardless of event initiating it. Addresses
         reported crashes due to memory read after free issues.
         [Stefan Eissing]
    
      *) mod_ssl: Correct the interaction between SSLProxyCheckPeerCN and newer
         SSLProxyCheckPeerName directives since release 2.4.5, such that disabling
         either disables both, and that enabling either triggers the new, more
         comprehensive SSLProxyCheckPeerName behavior. Only a single configuration
         remains to enable the legacy behavior, which is to explicitly disable
         SSLProxyCheckPeerName, and enable SSLProxyCheckPeerCN. [William Rowe]
    
      *) mod_include: add the <!--#comment ...> syntax in order to include comments
         in a SSI file. [Christophe Jaillet based on a suggestion from Rob]
    
      *) mod_http2: improved event handling for suspended streams, responses
         and window updates. [Stefan Eissing]
    
      *) mod_proxy_hcheck: Provide for dynamic background health
         checks on reverse proxies associated with BalancerMember
         workers. [Jim Jagielski]
    
      *) mod_http2: Fix async write issue that led to selection of wrong timeout
         vs. keepalive timeout selection for idle sessions. [Stefan Eissing]
    
      *) mod_http2: checking LimitRequestLine, LimitRequestFields and
         LimitRequestFieldSize configurated values for incoming streams. Returning
         HTTP status 431 for too long/many headers fields and 414 for a too long
         pseudo header. [Stefan Eissing]
    
      *) mod_http2: tracking conn_rec->current_thread on slave connections, so
         that mod_lua finds the correct one. Fixes PR 59542. [Stefan Eissing]
    
      *) mod_proxy_http2: new experimental http2 proxy module for h2: and h2c: proxy
         urls. Part of the httpd mod_proxy framework, common settings apply.
         Requests from the same HTTP/2 frontend connection against the same backend
         are aggregated on a single connection.
         [Stefan Eissing]
    
      *) mod_http2: slave connections have conn_rec->aborted flag set when a stream
         has been reset by the client. [Stefan Eissing]
    
      *) mod_http2: merge of some 2.4.x adaptions re filters on slave connections.
         Small fixes in bucket beams when forwarding file buckets. Output handling
         on master connection uses less FLUSH and passes automatically when more
         than half of H2StreamMaxMemSize bytes have accumulated.
         Workaround for http: when forwarding partial file buckets to keep the
         output filter from closing these too early. [Stefan Eissing]
    
      *) mod_http2: elimination of fixed master connection buffer for TLS
         connections. New scratch bucket handling optimized for TLS write sizes.
         File bucket data read directly into scratch buffers, avoiding one
         copy. Non-TLS connections continue to pass buckets unchanged to the core
         filters to allow sendfile() usage. [Stefan Eissing]
    
      *) mod_http2/mod_proxy_http2: h2_request.c is no longer shared between these
         modules. This simplifies building on platforms such as Windows, as module
         reference used in logging is now clear. [Stefan Eissing]
    
      *) Scoreboard: Fix a regression in 2.4.20 that causes wrong request data
         to be displayed on the status page. PR 59333. [Yann Ylavic, William Rowe]
    
      *) mod_http2: fixed a bug that caused mod_proxy_http2 to be called for window
         updates on requests it had already reported done. Added synchronization
         on early connection/stream close that lets ongoing requests safely drain
         their input filters.
         [Stefan Eissing]
    
      *) mod_http2: scoreboard updates that summarize the h2 session (and replace
         the last request information) will only happen when the session is idle or
         in shutdown/done phase. [Stefan Eissing]
    
      *) mod_http2: new "bucket beam" technology to transport buckets across
         threads without buffer copy. Delaying response start until flush or
         enough body data has been accumulated. Overall significantly smaller
         memory footprint. [Stefan Eissing]
    
      *) core: New CGIVar directive can configure REQUEST_URI to represent the
         current URI being processed instead of always the original request.
         [Jeff Trawick]
    
      *) scoreboard/status: Restore behavior of showing workers' previous Client,
         VHost and Request values when idle, like in 2.4.18 and earlier.
    
      *) mod_http2: r->protocol changed to "HTTP/2.0" (was "HTTP/2") as this will
         give expected syntax in CGI's SERVER_PROTOCOL is more compatible with
         existing major/minor handling. Fixes PR 59313.
    
      *) mod_http2: disabling mmap for file buckets transport due to segmenation
         faults when files change on the fly.
    
    Changes with Apache 2.4.20
    
      *) SECURITY: CVE-2016-1546 (cve.mitre.org)
         mod_http2: restricting number of concurrent stream workers per connection
         if client is slow.
    
      *) core: Do not read .htaccess if AllowOverride and AllowOverrideList
         are "None". PR 58528.
         [Michael Schlenker <msc contact.de, Ruediger Pluem, Daniel Ruggeri]
    
      *) mod_proxy_express: Fix possible use of DB handle after close.  PR 59230.
         [Petr <pgajdos suse.cz>]
    
      *) core/util_script: relax alphanumeric filter of environment variable names
         on Windows to allow '(' and ')' for passing PROGRAMFILES(X86) et.al.
         unadulterated in 64 bit versions of Windows. PR 46751.
         [John <john leineweb de>]
    
      *) mod_http2: incrementing keepalives on each request started so that logging
         %k gives increasing numbers per master http2 connection.
         New documented variables in env, usable in custom log formats: H2_PUSH,
         H2_PUSHED, H2_PUSHED_ON, H2_STREAM_ID and H2_STREAM_TAG.
         [Stefan Eissing]
    
      *) mod_http2: more efficient passing of response bodies with less contention
         and file bucket forwarding. [Stefan Eissing]
    
      *) mod_http2: fix for missing score board updates on request count, fix for
         memory leak on slave connection reuse. [Stefan Eissing]
    
      *) mod_http2: Fix build on Windows from dsp files.
         [Stefan Eissing]
    
    Changes with Apache 2.4.19
    
      *) mod_ssl: Add missing Upgrade/Connection headers in case of TRACE or
         OPTIONS * requests. PR 58688. [William Rowe]
    
      *) mod_include: Add variable DOCUMENT_ARGS, with the arguments to the
         request for the SSI document.  [Jeff Trawick]
    
      *) mod_authz_host: Add a new "forward-dns" authorization type, not relying on
         reverse DNS lookups.  [Fabien]
    
      *) mod_proxy_http2: new experimental http2 proxy module for h2: and h2c: proxy
         urls. Uses backend connections for concurrent requests if frontend
         connection is http2 as well.
         [Stefan Eissing]
    
      *) mod_ssl: Add hooks to allow other modules to perform processing at
         several stages of initialization and connection handling.  See
         mod_ssl_openssl.h.  [Jeff Trawick]
    
      *) mod_http2: disabling PUSH when client sends GOAWAY. Slave connections are
         reused for several requests, improved performance and better memory use.
         [Stefan Eissing]
    
      *) mod_rewrite: Don't implicitly URL-escape the original query string
         when no substitution has changed it (like PR50447 but server context)
         [Evgeny Kotkov <evgeny.kotkov visualsvn.com>]
    
      *) mod_http2: fixes problem with wrong lifetime of file buckets on main
         connection. [Stefan Eissing]
    
      *) mod_http2: fixes incorrect denial of requests without :authority header.
         [Stefan Eissing]
    
      *) mod_reqtimeout: Prevent long response times from triggering a timeout once
         the request has been fully read.  PR 59045.  [Yann Ylavic]
    
      *) ap_expr: expression support for variable HTTP2=on|off. [Stefan Eissing]
    
      *) mod_http2: give control to async mpm for keepalive timeouts only when
         no streams are open and even if only after 1 sec delay. Under load, event
         mpm discards connections otherwise too quickly. [Stefan Eissing]
    
      *) mod_ssl: Don't lose track of the SSL context if an unlikely failure occurs
         in ssl_init_ssl_connection().  [Graham Leggett]
    
      *) mod_rewrite: Add QSL|qslast flag to allow rewrites to files with
         literal question marks in their names. PR 58777. [Eric Covener]
    
      *) event: use pre_connection hook to properly initialize connection state for
         slave connections. use protocol_switch hook to initialize server config
         early based on SNI selected vhost.
         [Stefan Eissing]
    
      *) hostname: Test and log useragent_host per-request across various modules,
         including the scoreboard, expression and rewrite engines, setenvif,
         authz_host, access_compat, custom logging, ssl and REMOTE_HOST variables.
         PR55348  [William Rowe]
    
      *) core: Track the useragent_host per-request when mod_remoteip or similar
         modules track a per-request useragent_ip.  Modules should be updated
         to inquire for ap_get_useragent_host() in place of ap_get_remote_host().
         [William Rowe]
    
      *) core: fix a bug in <UnDefine ...> directive processing. When used, the last
         <Define...>'ed variable was also withdrawn. PR 59019
         [Christophe Jaillet]
    
      *) mod_http2: Accept-Encoding is, when present on the initiating request,
         added to push promises. This lets compressed content work in pushes.
         by the client. [Stefan Eissing]
    
      *) mod_http2: fixed possible read after free when streams were cancelled early
         by the client. [Stefan Eissing]
    
      *) mod_http2: fixed possible deadlock during connection shutdown. Thanks to
         @FrankStolle for reporting and getting the necessary data.
         [Stefan Eissing]
    
      *) mod_http2: fixed apr_uint64_t formatting in a log statement to user proper
         APR def, thanks to @Sp1l.
    
      *) mod_http2: number of worker threads allowed to a connection is adjusting
         dynamically. Starting with 4, the number is doubled when streams can be
         served without block on http/2 connection flow. The number is halfed, when
         the server has to wait on client flow control grants.
         This can happen with a maximum frequency of 5 times per second.
         When a connection occupies too many workers, repeatable requests
         (GET/HEAD/OPTIONS) are cancelled and placed back in the queue. Should that
         not suffice and a stream is busy longer than the server timeout, the
         connection will be aborted with error code ENHANCE_YOUR_CALM.
         This does *not* limit the number of streams a client may open, rather the
         number of server threads a connection might use.
         [Stefan Eissing]
    
      *) mod_http2: allowing link header to specify multiple "rel" values,
         space-separated inside a quoted string. Prohibiting push when Link
         parameter "nopush" is present.
         [Stefan Eissing]
    
      *) mod_http2: reworked connection state handling. Idle connections accept a
         GOAWAY from the client without further reply. Otherwise the
         module makes a best effort to send one last GOAWAY to the client.
    
      *) mod_http2: the values from standard directives Timeout and KeepAliveTimeout
         properly are applied to http/2 connections.
         [Stefan Eissing]
    
      *) mod_http2: idle connections are returned to async mpms. new hook
         "pre_close_connection" used to send GOAWAY frame when not already done.
         Setting event mpm server config "by hand" for the main connection to
         the correct negotiated server.
         [Stefan Eissing]
    
      *) mod_http2: keep-alive blocking reads are done with 1 second timeouts to
         check for MPM stopping. Will announce early GOAWAY and finish processing
         open streams, then close.
         [Stefan Eissing]
    
      *) mod_http2: bytes read/written on slave connections are reported via the
         optional mod_logio functions. Fixes PR 58871.
    
      *) prefork: Initialize the POD when running in ONE_PROCESS (or -X) mode to
         avoid a crash.  [Jan Kaluza, Yann Ylavic]
    
      *) mod_ssl: When SSLVerify is disabled (NONE), don't force a renegotiation if
         the SSLVerifyDepth applied with the default/handshaken vhost differs from
         the one applicable with the finally selected vhost.  [Yann Ylavic]
    
      *) core: Ensure that httpd exits with an error status when the MPM fails
         to run.  [Yann Ylavic]
    
      *) mod_ssl: Fix a possible memory leak on restart for custom [EC]DH params.
         [Jan Kaluza, Yann Ylavic]
    
      *) mod_ssl: Add SSLOCSPProxyURL to add the possibility to do all queries
         to OCSP responders through a HTTP proxy. [Ruediger Pluem]
    
      *) mod_proxy: Play/restore the TLS-SNI on new backend connections which
         had to be issued because the remote closed the previous/reusable one
         during idle (keep-alive) time.  [Yann Ylavic]
    
      *) mod_cache_socache: Fix a possible cached entity body corruption when it
         is received from an origin server in multiple batches and forwarded by
         mod_proxy.  [Yann Ylavic]
    
      *) core: Add expression support to SetHandler.
         [Eric Covener]
    
      *) mod_remoteip: Prevent an external proxy from presenting an internal
         proxy. PR 55962. [Mike Rumph]
    
      *) core: Prevent a server crash in case of an invalid CONNECT request with
         a custom error page for status code 400 that uses server side includes.
         PR 58929 [Ruediger Pluem]
    
      *) mod_ssl: handle TIMEOUT on empty SSL input as non-fatal, returning
         APR_TIMEUP and preserving connection state for later retry.
         [Stefan Eissing]
    
      *) mod_ssl: Save some TLS record (application data) fragmentations by
         including the last and subsequent suitable buckets when coalescing.
         [Yann Ylavic]
    
      *) mod_proxy_fcgi: Suppress HTTP error 503 and message 01075,
         "Error dispatching request", when the cause appears to be
         due to the client closing the connection.
         PR58118.  [Tobias Adolph <adolph lrz.de>]
    
      *) mod_cgid: Message AH02550, failure to flush a response to the client,
         is now logged at TRACE1 level to match the underlying core output filter
         severity.  [Eric Covener]
    
      *) mime.types: add common extension "m4a" for MPEG 4 Audio.
         PR 57895 [Dylan Millikin <dylan.millikin gmail.com>]
    
      *) Added many log numbers to log statements that had none.
         [Rainer Jung]
    
      *) mod_log_config: Add GlobalLog to allow a globally defined log to
         be inherited by virtual hosts that define a CustomLog.
         [Edward Lu]
    
      *) mod_http2: connections how keep a "push diary" where hashes of already
         pushed resources are kept. See directive H2PushDiarySize for managing this.
         Push diaries can be initialized by clients via the "Cache-Digest" request
         header. This carries a base64url encoded. compressed Golomb set as described
         in https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/
         Introduced a status handler for HTTP/2 connections, giving various counters
         and statistics about the current connection, plus its cache digest value
         in a JSON record. Not a replacement for more HTTP/2 in the server status.
         Configured as
         <Location "/http2-status">
             SetHandler http2-status
         </Location>
         [Stefan Eissing]
    
      *) mod_http2: Fixed flushing of last GOAWAY frame. Previously, that frame
         did not always reach the client, causing some to fail the next request.
         Fixed calculation of last stream id accepted as described in rfc7540.
         Reading in KEEPALIVE state now correctly shown in scoreboard.
         Fixed possible race in connection shutdown after review by Ylavic.
         Fixed segfault on connection shutdown, callback ran into a semi dismantled session.
         [Stefan Eissing]
    
      *) mod_http2: Added support for experimental accept-push-policy draft
         (https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00). Clients
         may now influence server pushes by sending accept-push-policy headers.
         [Stefan Eissing]
    
      *) mod_http2: new r->subprocess_env variables HTTP2 and H2PUSH, set to "on"
         when available for request.
         [Stefan Eissing]
    
      *) mod_http2: fixed bug in input window size calculation by moving chunked
         request body encoding into later stage of processing. Fixes PR 58825.
         [Stefan Eissing]
    
      *) core: new hook "pre_close_connection" which is run before the lingering
         close of connections is started. This gives protocol handlers one last
         chance to use a connection before it goes down.
         [Stefan Eissing]
    
      *) mod_status/scoreboard: showing connection protocol in new column, new
         ap_update_child_status methods for updating server/description. mod_ssl
         sets vhost negotiated by servername directly.
         [Stefan Eissing]
    
    Changes with Apache 2.4.18
    
      *) mod_ssl: for all ssl_engine_vars.c lookups, fall back to master connection
         if conn_rec itself holds no valid SSLConnRec*. Fixes PR58666.
         [Stefan Eissing]
    
      *) mod_http2: connection level window for flow control is set to protocol
         maximum of 2GB-1, preventing window exhaustion when sending data on many
         streams with higher cumulative window size.
         Reducing write frequency unless push promises need to be flushed.
         [Stefan Eissing]
    
      *) mod_http2: required minimum version of libnghttp2 is 1.2.1
         [Stefan Eissing]
    
      *) mod_proxy_fdpass: Fix AH01153 error when using the default configuration.
         In earlier version of httpd, you can explicitly set the 'flusher' parameter
         to 'flush' as a workaround. (i.e. flusher=flush)
         Add documentation for the 'flusher' parameter when defining a proxy worker.
         [Christophe Jaillet]
    
      *) mod_ssl: For the "SSLStaplingReturnResponderErrors off" case, make sure
         to only staple responses with certificate status "good". [Kaspar Brand]
    
      *) mod_http2: new directive 'H2PushPriority' to allow priority specifications
         on server pushed streams according to their content-type.
         [Stefan Eissing]
    
      *) mod_http2: fixes crash on connection abort for a busy connection.
         fixes crash on a request that did not produce any response.
         [Stefan Eissing]
    
      *) mod_http2: trailers are sent after response body if set in request_rec
         trailers_out before the end-of-request bucket is sent through the
         output filters. [Stefan Eissing]
    
      *) mod_http2: incoming trailers (headers after request body) are properly
         forwarded to the processing engine. [Stefan Eissing]
    
      *) mod_http2: new directive 'H2Push' to en-/disable HTTP/2 server
         pushes a server/virtual host. Pushes are initiated by the presence
         of 'Link:' headers with relation 'preload' on a response. [Stefan Eissing]
    
      *) mod_http2: write performance of http2 improved for larger resources,
         especially static files. [Stefan Eissing]
    
      *) core: if the first HTTP/1.1 request on a connection goes to a server that
         prefers different protocols, these protocols are announced in a Upgrade:
         header on the response, mentioning the preferred protocols.
         [Stefan Eissing]
    
      *) mod_http2: new directives 'H2TLSWarmUpSize' and 'H2TLSCoolDownSecs'
         to control TLS record sizes during connection lifetime.
         [Stefan Eissing]
    
      *) mod_http2: new directive 'H2ModernTLSOnly' to enforce security
         requirements of RFC 7540 on TLS connections. [Stefan Eissing]
    
      *) core: add ap_get_protocol_upgrades() to retrieve the list of protocols
         that a client could possibly upgrade to. Use in first request on a
         connection to announce protocol choices. [Stefan Eissing]
    
      *) mod_http2: reworked deallocation on connection shutdown and worker
         abort. Separate parent pool for all workers. worker threads are joined
         on planned worker shutdown. [Yann Ylavic, Stefan Eissing]
    
      *) mod_ssl: when receiving requests for other virtual hosts than the handshake
         server, the SSL parameters are checked for equality. With equal
         configuration, requests are passed for processing. Any change will trigger
         the old behaviour of "421 Misdirected Request".
         SSL now remembers the cipher suite that was used for the last handshake.
         This is compared against for any vhost/directory cipher specification.
         Detailed examination of renegotiation is only done when these do not
         match.
         Renegotiation is 403ed when a master connection is present. Exact reason
         is given additionally in a request note. [Stefan Eissing]
    
      *) mod_ssl: Make the output filter more friendly with deferred write and
         response pipelining. [Yann Ylavic, Joe Orton]
    
      *) core: Fix scoreboard crash (SIGBUS) on hardware requiring strict 64bit
         alignment (SPARC64, PPC64).  [Yann Ylavic]
    
      *) mod_cache: Accept HT (Horizontal Tab) when parsing cache related header
         fields as described in RFC7230. [Christophe Jaillet]
    
      *) core/util_script: making REDIRECT_URL a full URL is now opt-in
         via new 'QualifyRedirectURL' directive.
    
      *) core: Limit to ten the number of tolerated empty lines between request,
         and consume them before the pipelining check to avoid possible response
         delay when reading the next request without flushing.  [Yann Ylavic]
    
      *) mod_ssl: Extend expression parser registration to support ssl variables
         in any expression using mod_rewrite syntax "%{SSL:VARNAME}" or function
         syntax "ssl(VARNAME)". [Rainer Jung]
    
    Changes with Apache 2.4.17
    
      *) mod_http2: added donated HTTP/2 implementation via core module. Similar
         configuration options to mod_ssl. [Stefan Eissing]
    
      *) mod_proxy: don't recycle backend announced "Connection: close" connections
         to avoid reusing it should the close be effective after some new request
         is ready to be sent.  [Yann Ylavic]
    
      *) mod_substitute: Allow to configure the patterns merge order with the new
         SubstituteInheritBefore on|off directive.  PR 57641
         [Marc.Stern <Marc.Stern approach.be>, Yann Ylavic, William Rowe]
    
      *) mod_proxy: Fix ProxySourceAddress binding failure with AH00938.
         PR 56687.  [Arne de Bruijn <apache arbruijn.dds.nl>
    
      *) mod_ssl: Support compilation against libssl built with OPENSSL_NO_SSL3,
         and change the compiled-in default for SSL[Proxy]Protocol to "all -SSLv3",
         in accordance with RFC 7568. PR 58349, PR 57120. [Kaspar Brand]
    
      *) mod_ssl: append :!aNULL:!eNULL:!EXP to the cipher string settings,
         instead of prepending !aNULL:!eNULL:!EXP: (as was the case in 2.4.7
         and later). Enables support for configuring the SUITEB* cipher
         strings introduced in OpenSSL 1.0.2. PR 58213. [Kaspar Brand]
    
      *) mod_ssl: Add support for extracting the msUPN and dnsSRV forms
         of subjectAltName entries of type "otherName" into
         SSL_{CLIENT,SERVER}_SAN_OTHER_{msUPN,dnsSRV}_n environment
         variables. Addresses PR 58020. [Jan Pazdziora <jpazdziora redhat.com>,
         Kaspar Brand]
    
      *) mod_logio: Fix logging of %^FB (time to first byte) on the first request on
         an SSL connection.  PR 58454.
         [Konstantin J. Chernov <k.j.chernov gmail.com>]
    
      *) mod_cache: r->err_headers_out is not merged into
         r->headers when mod_cache is enabled and the response
         is cached for the first time. [Edward Lu]
    
      *) mod_slotmem_shm: Fix slots/SHM files names on restart for systems that
         can't create new (clear) slots while previous children gracefully stopping
         still use the old ones (e.g. Windows, OS2). mod_proxy_balancer failed to
         restart whenever the number of configured balancers/members changed during
         restart.  PR 58024.  [Yann Ylavic]
    
      *) core/util_script: make REDIRECT_URL a full URL.  PR 57785. [Nick Kew]
    
      *) MPMs: Support SO_REUSEPORT to create multiple duplicated listener
         records for scalability. [Yingqi Lu <yingqi.lu@intel.com>,
         Jeff Trawick, Jim Jagielski, Yann Ylavic]
    
      *) mod_alias: Introduce expression parser support for Alias, ScriptAlias
         and Redirect. Limit Redirect expressions to directory (Location) context
         and redirect statuses (implicit or explicit).
         [Graham Leggett, Yann Ylavic, Ruediger Pluem]
    
      *) mod_proxy: Fix a race condition that caused a failed worker to be retried
         before the retry period is over. [Ruediger Pluem]
    
      *) mod_autoindex: Allow autoindexes when neither mod_dir nor mod_mime are
         loaded. [Eric Covener]
    
      *) mod_rewrite:  Allow cookies set by mod_rewrite to contain ':' by accepting
         ';' as an alternate separator.  PR47241.
         [<bugzilla schermesser com>, Eric Covener]
    
      *) apxs: Add HTTPD_VERSION and HTTPD_MMN to the variables available with
         apxs -q. PR58202. [Daniel Shahaf <danielsh apache.org>]
    
      *) mod_rewrite: Avoid a crash when lacking correct DB access permissions
         when using RewriteMap with MapType dbd or fastdbd.  [Christophe Jaillet]
    
      *) mod_authz_dbd: Avoid a crash when lacking correct DB access permissions.
         PR 57868. [Jose Kahan <jose w3.org>, Yann Ylavic]
    
      *) mod_socache_memcache: Add the 'MemcacheConnTTL' directive to control how
         long to keep idle connections with the memcache server(s).
         Change default value from 600 usec (!) to 15 sec. PR 58091
         [Christophe Jaillet]
    
      *) mod_dir: Prevent the internal identifier "httpd/unix-directory" from
         appearing as a Content-Type response header when requests for a directory
         are rewritten by mod_rewrite. [Eric Covener]
    
    Changes with Apache 2.4.16
    
      *) http: Fix LimitRequestBody checks when there is no more bytes to read.
         [Michael Kaufmann <mail michael-kaufmann.ch>]
    
      *) mod_alias: Revert expression parser support for Alias, ScriptAlias
         and Redirect due to a regression (introduced in 2.4.13, not released).
    
      *) mod_reqtimeout: Don't let pipelining checks and keep-alive times interfere
         with the timeouts computed for subsequent requests.  PR 56729.
         [Eric Covener, Yann Ylavic]
    
      *) core: Avoid a possible truncation of the faulty header included in the
         HTML response when LimitRequestFieldSize is reached.  [Yann Ylavic]
    
      *) mod_ldap: In some case, LDAP_NO_SUCH_ATTRIBUTE could be returned instead
         of an error during a compare operation. [Eric Covener]
    
    Changes with Apache 2.4.15 (not released)
    
      *) mod_ext_filter, mod_charset_lite: Avoid inadvertent filtering of protocol
         data during read of chunked request bodies. PR 58049.
         [Edward Lu <Chaosed0 gmail.com>]
    
      *) mod_ldap: Stop leaking LDAP connections when 'LDAPConnectionPoolTTL 0'
         is configured.  PR 58037.  [Ted Phelps <phelps gnusto.com>]
    
      *) core: Allow spaces after chunk-size for compatibility with implementations
         using a pre-filled buffer.  [Yann Ylavic, Jeff Trawick]
    
      *) mod_ssl: Remove deprecated SSLCertificateChainFile warning.
         [Yann Ylavic]
    
    Changes with Apache 2.4.14 (not released)
    
      *) SECURITY: CVE-2015-3183 (cve.mitre.org)
         core: Fix chunk header parsing defect.
         Remove apr_brigade_flatten(), buffering and duplicated code from
         the HTTP_IN filter, parse chunks in a single pass with zero copy.
         Limit accepted chunk-size to 2^63-1 and be strict about chunk-ext
         authorized characters.  [Graham Leggett, Yann Ylavic]
    
      *) SECURITY: CVE-2015-3185 (cve.mitre.org)
         Replacement of ap_some_auth_required (unusable in Apache httpd 2.4)
         with new ap_some_authn_required and ap_force_authn hook.  [Ben Reser]
    
    Changes with Apache 2.4.13 (not released)
    
      *) SECURITY: CVE-2015-0253 (cve.mitre.org)
         core: Fix a crash with ErrorDocument 400 pointing to a local URL-path
         with the INCLUDES filter active, introduced in 2.4.11. PR 57531.
         [Yann Ylavic]
    
      *) SECURITY: CVE-2015-0228 (cve.mitre.org)
         mod_lua: A maliciously crafted websockets PING after a script
         calls r:wsupgrade() can cause a child process crash.
         [Edward Lu <Chaosed0 gmail.com>]
    
      *) mod_proxy: Don't put the worker in error state for 500 or 503 errors
         returned by the backend unless failonstatus is configured to.  PR 56925.
         [Yann Ylavic]
    
      *) core: Don't lowercase the argument to SetHandler if it begins with
         "proxy:unix". PR 57968. [Eric Covener]
    
      *) mod_ssl OCSP Stapling: Don't block initial handshakes while refreshing
         the OCSP response for a different certificate.  mod_ssl has an additional
         global mutex, "ssl-stapling-refresh".  PR 57131 (partial fix).
         [Jeff Trawick]
    
      *) mod_authz_dbm: Fix crashes when "dbm-file-group" is used and
         authz modules were loaded in the "wrong" order.  [Joe Orton]
    
      *) mod_authn_dbd, mod_authz_dbd, mod_session_dbd, mod_rewrite: Fix lifetime
         of DB lookup entries independently of the selected DB engine.  PR 46421.
         [Steven whitson <steven.whitson gmail com>, Jan Kaluza, Yann Ylavic].
    
      *) In alignment with RFC 7525, the default recommended SSLCipherSuite
         and SSLProxyCipherSuite now exclude RC4 as well as MD5. Also, the
         default recommended SSLProtocol and SSLProxyProtocol directives now
         exclude SSLv3. Existing configurations must be adjusted by the
         administrator. [William Rowe]
    
      *) mod_ssl: Add support for extracting subjectAltName entries of type
         rfc822Name and dNSName into SSL_{CLIENT,SERVER}_SAN_{Email,DNS}_n
         environment variables. Also addresses PR 57207. [Kaspar Brand]
    
      *) dav_validate_request: avoid validating locks and ETags when there are
         no If headers providing them on a resource we aren't modifying.
         [Ben Reser]
    
      *) mod_proxy_scgi: ProxySCGIInternalRedirect now allows an alternate
         response header to be used by the application, for when the application
         or framework is unable to return Location in the internal-redirect
         form.  [Jeff Trawick]
    
      *) core: Cleanup the request soon/even if some output filter fails to
         handle the EOR bucket.  [Yann Ylavic]
    
      *) mpm_event: Allow for timer events duplicates. [Jim Jagielski, Yann Ylavic]
    
      *) mod_proxy, mod_ssl, mod_cache_socache, mod_socache_*: Support machine
         readable server-status produced when using the "?auto" query string.
         [Rainer Jung]
    
      *) mod_status: Add more data to machine readable server-status produced
         when using the "?auto" query string.  [Rainer Jung]
    
      *) mod_ssl: Check for the Entropy Gathering Daemon (EGD) availability at
         configure time (RAND_egd), and complain if SSLRandomSeed requires using
         it otherwise.  [Bernard Spil <pil.oss gmail com>, Stefan Sperling,
         Kaspar Brand]
    
      *) mod_ssl: make sure to consistently output SSLCertificateChainFile
         deprecation warnings, when encountered in a VirtualHost block.
         [Falco Schwarz <hiding falco.me>]
    
      *) mod_log_config: Add "%{UNIT}T" format to output request duration in
         seconds, milliseconds or microseconds depending on UNIT ("s", "ms", "us").
         [Ben Reser, Rainer Jung]
    
      *) Allow FallbackResource to work when a directory is requested and
         there is no autoindex nor DirectoryIndex.
         [Jack <tjerk.meesters gmail.com>, Eric Covener]
    
      *) mod_proxy_wstunnel: Bypass the handler while the connection is not
         upgraded to WebSocket, so that other modules can possibly take over
         the leading HTTP requests.  [Yann Ylavic]
    
      *) mod_http: Fix incorrect If-Match handling. PR 57358
         [Kunihiko Sakamoto <ksakamoto google.com>]
    
      *) mod_ssl: Add a warning if protocol given in SSLProtocol or SSLProxyProtocol
         will override other parameters given in the same directive. This could be
         a missing + or - prefix.  PR 52820 [Christophe Jaillet]
    
      *) core, modules: Avoid error response/document handling by the core if some
         handler or input filter already did it while reading the request (causing
         a double response body).  [Yann Ylavic]
    
      *) mod_proxy_ajp: Fix client connection errors handling and logged status
         when it occurs.  PR 56823.  [Yann Ylavic]
    
      *) mod_proxy: Use the correct server name for SNI in case the backend
         SSL connection itself is established via a proxy server.
         PR 57139 [Szabolcs Gyurko <szabolcs gyurko.org>]
    
      *) mod_ssl: Fix possible crash when loading server certificate constraints.
         PR 57694. [Paul Spangler <paul.spangler ni com>, Yann Ylavic]
    
      *) build: Don't load both mod_cgi and mod_cgid in the default configuration
         if they're both built.  [olli hauer <ohauer gmx.de>]
    
      *) mod_logio: Add LogIOTrackTTFB and %^FB logformat to log the time
         taken to start writing response headers. [Eric Covener]
    
      *) mod_ssl: Avoid compilation errors with LibreSSL related to
         the use of ENGINE_CTRL_CHIL_SET_FORKCHECK.
         [Stuart Henderson <sthen openbsd.org>]
    
      *) mod_proxy_http: Use the "Connection: close" header for requests to
         backends not recycling connections (disablereuse), including the default
         reverse and forward proxies.  [Yann Ylavic]
    
      *) mod_proxy: Add ap_connection_reusable() for checking if a connection
         is reusable as of this point in processing.  [Jeff Trawick]
    
      *) mod_proxy_wstunnel: Avoid an empty response by failing with 502 (Bad
         Gateway) when no response is ever received from the backend.
         [Jan Kaluza]
    
      *) core_filters: Restore/disable TCP_NOPUSH option after non-blocking
         sendfile.  PR 53253.  [Yann Ylavic]
    
      *) mod_buffer: Forward flushed input data immediately and avoid (unlikely)
         access to freed memory. [Yann Ylavic, Christophe Jaillet]
    
      *) core: Add CGIPassAuth directive to control whether HTTP authorization
         headers are passed to scripts as CGI variables.  PR 56855.  [Jeff
         Trawick]
    
      *) core: Initialize scoreboard's used optional functions on graceful restarts
         to avoid a crash when relocation occurs.  PR 57177.  [Yann Ylavic]
    
      *) mod_dav: Avoid a potential integer underflow in the lock timeout value sent
         back to a client. The answer to a LOCK request could be an extremely large
         integer if the time needed to lock the resource was longer that the
         requested timeout given in the LOCK request. In such a case, we now answer
         "Second-0".  PR55420
         [Christophe Jaillet]
    
      *) mod_cgid: Within the first minute of a server start or restart,
         allow mod_cgid to retry connecting to its daemon process. Previously,
         'No such file or directory: unable to connect to cgi daemon...' could
         be logged without an actual retry. PR57685.
         [Edward Lu <Chaosed0 gmail.com>]
    
      *) mod_proxy: Use the original (non absolute) form of the request-line's URI
         for requests embedded in CONNECT payloads used to connect SSL backends via
         a ProxyRemote forward-proxy.  PR 55892.  [Hendrik Harms <hendrik.harms
         gmail com>, William Rowe, Yann Ylavic]
    
      *) http: Make ap_die() robust against any HTTP error code and not modify
         response status (finally logged) when nothing is to be done. PR 56035.
         [Yann Ylavic]
    
      *) mod_proxy_connect/wstunnel: If both client and backend sides get readable
         at the same time, don't lose errors occurring while forwarding on the first
         side when none occurs next on the other side, and abort.  [Yann Ylavic]
    
      *) mod_rewrite: Improve relative substitutions in per-directory/htaccess
         context for directories found by mod_userdir and mod_alias.  These no
         longer require RewriteBase to be specified. [Eric Covener]
    
      *) mod_proxy_http: Don't expect the backend to ack the "Connection: close" to
         finally close those not meant to be kept alive by SetEnv proxy-nokeepalive
         or force-proxy-request-1.0.  [Yann Ylavic]
    
      *) core: If explicitly configured, use the KeepaliveTimeout value of the
         virtual host which handled the latest request on the connection, or by
         default the one of the first virtual host bound to the same IP:port.
         PR56226.  [Yann Ylavic]
    
      *) mod_lua: After a r:wsupgrade(), mod_lua was not properly
         responding to a websockets PING but instead invoking the specified
         script. PR57524. [Edward Lu <Chaosed0 gmail.com>]
    
      *) mod_ssl: Add the SSL_CLIENT_CERT_RFC4523_CEA variable, which provides
         a combination of certificate serialNumber and issuer as defined by
         CertificateExactMatch in RFC4523. [Graham Leggett]
    
      *) core: Add expression support to ErrorDocument. Switch from a fixed
         sized 664 byte array per merge to a hash table. [Graham Leggett]
    
      *) ab: Add missing longest request (100%) to CSV export.
         [Marcin Fabrykowski <bugzilla fabrykowski.pl>]
    
      *) mod_macro: Clear macros before initialization to avoid use-after-free
         on startup or restart when the module is linked statically. PR 57525
         [apache.org tech.futurequest.net, Yann Ylavic]
    
      *) mod_alias: Introduce expression parser support for Alias, ScriptAlias
         and Redirect. [Graham Leggett]
    
      *) mod_ssl: 'SSLProtocol ALL' was being ignored in virtual host context.
         PR 57100.  [Michael Kaufmann <apache-bugzilla michael-kaufmann.ch>,
         Yann Ylavic]
    
      *) mpm_event: Avoid access to the scoreboard from the connection while
         it is suspended (waiting for events).  [Eric Covener, Jeff Trawick]
    
      *) mod_ssl: Fix renegotiation failures redirected to an ErrorDocument.
         PR 57334.  [Yann Ylavic].
    
      *) mod_deflate: A misplaced check prevents limiting small bodies with the
         new inflate limits. PR56872. [Edward Lu, Eric Covener, Yann Ylavic]
    
      *) mod_proxy_ajp: Forward SSL protocol name (SSLv3, TLSv1.1 etc.) as a
         request attribute to the backend. Recent Tomcat versions will extract
         it and provide it as a servlet request attribute named
         "org.apache.tomcat.util.net.secure_protocol_version". [Rainer Jung]
    
      *) core: Optimize string concatenation in expression parser when evaluating
         a string expression. [Rainer Jung]
    
      *) acinclude.m4: Generate #LoadModule directive in default httpd.conf for
         every --enable-mpms-shared. PR 53882.  [olli hauer <ohauer gmx.de>,
         Yann Ylavic]
    
      *) mod_authn_dbd: Fix the error message logged in case of error while querying
         the database. This is associated to AH01656 and AH01661. [Christophe Jaillet]
    
      *) mod_authz_groupfile: Reduce the severity of AH01667 from ERROR to DEBUG,
         because it may be evaluated inside <RequireAny>. PR55523. [Eric Covener]
    
      *) mod_ssl: Fix small memory leak during initialization when ECDH is used.
         [Jan Kaluza]
    
    Changes with Apache 2.4.12
    
      *) mpm_winnt: Accept utf-8 (Unicode) service names and descriptions for
         internationalization.  [William Rowe]
    
      *) mpm_winnt: Normalize the error and status messages emitted by service.c,
         the service control interface for Windows.  [William Rowe]
    
      *) configure: Fix --enable-v4-mapped configuration on *BSD. PR 53824.
         [ olli hauer <ohauer gmx.de>, Yann Ylavic ]
    
      *) Reverted <DirectoryMatch > behavior regression introduced in 2.4.11
         (not released).
    
    Changes with Apache 2.4.11 (not released)
    
      *) SECURITY: CVE-2014-3583 (cve.mitre.org)
         mod_proxy_fcgi: Fix a potential crash due to buffer over-read, with
         response headers' size above 8K.  [Yann Ylavic, Jeff Trawick]
    
      *) SECURITY: CVE-2014-3581 (cve.mitre.org)
         mod_cache: Avoid a crash when Content-Type has an empty value.
         PR 56924.  [Mark Montague <mark catseye.org>, Jan Kaluza]
    
      *) SECURITY: CVE-2014-8109 (cve.mitre.org)
         mod_lua: Fix handling of the Require line when a LuaAuthzProvider is
         used in multiple Require directives with different arguments.
         PR57204 [Edward Lu <Chaosed0 gmail.com>]
    
      *) SECURITY: CVE-2013-5704 (cve.mitre.org)
         core: HTTP trailers could be used to replace HTTP headers
         late during request processing, potentially undoing or
         otherwise confusing modules that examined or modified
         request headers earlier.  Adds "MergeTrailers" directive to restore
         legacy behavior.  [Edward Lu, Yann Ylavic, Joe Orton, Eric Covener]
    
      *) mod_ssl: New directive SSLSessionTickets (On|Off).
         The directive controls the use of TLS session tickets (RFC 5077),
         default value is "On" (unchanged behavior).
         Session ticket creation uses a random key created during web
         server startup and recreated during restarts. No other key
         recreation mechanism is available currently. Therefore using session
         tickets without restarting the web server with an appropriate frequency
         (e.g. daily) compromises perfect forward secrecy. [Rainer Jung]
    
      *) mod_proxy_fcgi: Provide some basic alternate options for specifying
         how PATH_INFO is passed to FastCGI backends by adding significance to
         the value of proxy-fcgi-pathinfo. PR 55329. [Eric Covener]
    
      *) mod_proxy_fcgi: Enable UDS backends configured with SetHandler/RewriteRule
         to opt-in to connection reuse and other Proxy options via explicitly
         declared "proxy workers" (<Proxy unix:... enablereuse=on max=...)
         [Eric Covener]
    
      *) mod_proxy: Add "enablereuse" option as the inverse of "disablereuse".
         [Eric Covener]
    
      *) mod_proxy_fcgi: Enable opt-in to TCP connection reuse by explicitly
         setting proxy option disablereuse=off. [Eric Covener] PR 57378.
    
      *) event: Update the internal "connection id" when requests
         move from thread to thread. Reuse can confuse modules like
         mod_cgid. PR 57435. [Michael Thorpe <mike gistnet.com>]
    
      *) mod_proxy_fcgi: Remove proxy:balancer:// prefix from SCRIPT_FILENAME
         passed to fastcgi backends. [Eric Covener]
    
      *) core: Configuration files with long lines and continuation characters
         are not read properly. PR 55910. [Manuel Mausz <manuel-as mausz.at>]
    
      *) mod_include: the 'env' function was incorrectly handled as 'getenv' if the
         leading 'e' was written in upper case in <!--#if expr="..." -->
         statements. [Christophe Jaillet]
    
      *) split-logfile: Fix perl error:  'Can't use string ("example.org:80")
         as a symbol ref while "strict refs"'. PR 56329.
         [Holger Mauermann <mauermann gmail.com>]
    
      *) mod_proxy: Prevent ProxyPassReverse from doing a substitution when
         the URL parameter interpolates to an empty string. PR 56603.
         [<ajprout hotmail.com>]
    
      *) core: Fix -D[efined] or <Define>[d] variables lifetime across restarts.
         PR 57328.  [Armin Abfalterer <a.abfalterer gmail.com>, Yann Ylavic].
    
      *) mod_proxy: Preserve original request headers even if they differ
         from the ones to be forwarded to the backend. PR 45387.
         [Yann Ylavic]
    
      *) mod_ssl: dump SSL IO/state for the write side of the connection(s),
         like reads (level TRACE4). [Yann Ylavic]
    
      *) mod_proxy_fcgi: Ignore body data from backend for 304 responses. PR 57198.
         [Jan Kaluza]
    
      *) mod_ssl: Do not crash when looking up SSL related variables during
         expression evaluation on non SSL connections. PR 57070  [Ruediger Pluem]
    
      *) mod_proxy_ajp: Fix handling of the default port (8009) in the
         ProxyPass and <Proxy> configurations.  PR 57259.  [Yann Ylavic]
    
      *) mpm_event: Avoid a possible use after free when notifying the end of
         connection during lingering close.  PR 57268.  [Eric Covener, Yann Ylavic]
    
      *) mod_ssl: Fix recognition of OCSP stapling responses that are encoded
         improperly or too large.  [Jeff Trawick]
    
      *) core: Add ap_log_data(), ap_log_rdata(), etc. for logging buffers.
         [Jeff Trawick]
    
      *) mod_proxy_fcgi, mod_authnz_fcgi: stop reading the response and issue an
         error when parsing or forwarding the response fails. [Yann Ylavic]
    
      *) mod_ssl: Fix a memory leak in case of graceful restarts with OpenSSL >= 0.9.8e
         PR 53435 [tadanori <tadanori2007 yahoo.com>, Sebastian Wiedenroth <wiedi frubar.net>]
    
      *) mod_proxy_connect: Don't issue AH02447 on sockets hangups, let the read
         determine whether it is a normal close or a real error. PR 57168. [Yann
         Ylavic]
    
      *) mod_proxy_wstunnel: abort backend connection on polling error to avoid
         further processing.  [Yann Ylavic]
    
      *) core: Support custom ErrorDocuments for HTTP 501 and 414 status codes.
         PR 57167 [Edward Lu <Chaosed0 gmail.com>]
    
      *) mod_proxy_connect: Fix ProxyRemote to https:// backends on EBCDIC
         systems. PR 57092 [Edward Lu <Chaosed0 gmail.com>]
    
      *) mod_cache: Avoid a 304 response to an unconditional request when an AH00752
         CacheLock error occurs during cache revalidation. [Eric Covener]
    
      *) mod_ssl: Move OCSP stapling information from a per-certificate store to
         a per-server hash. PR 54357, PR 56919. [Alex Bligh <alex alex.org.uk>,
         Yann Ylavic, Kaspar Brand]
    
      *) mod_cache_socache: Change average object size hint from 32 bytes to
         2048 bytes.  [Rainer Jung]
    
      *) mod_cache_socache: Add cache status to server-status.  [Rainer Jung]
    
      *) event: Fix worker-listener deadlock in graceful restart.
         PR 56960.
    
      *) Concat strings at compile time when possible. PR 53741.
    
      *) mod_substitute: Restrict configuration in .htaccess to
         FileInfo as documented.  [Rainer Jung]
    
      *) mod_substitute: Make maximum line length configurable.  [Rainer Jung]
    
      *) mod_substitute: Fix line length limitation in case of regexp plus flatten.
         [Rainer Jung]
    
      *) mod_proxy: Truncated character worker names are no longer fatal
         errors. PR53218. [Jim Jagielski]
    
      *) mod_dav: Set r->status_line in dav_error_response. PR 55426.
    
      *) mod_proxy_http, mod_cache: Avoid (unlikely) accesses to freed memory.
         [Yann Ylavic, Christophe Jaillet]
    
      *) http_protocol: fix logic in ap_method_list_(add|remove) in order:
           - to correctly reset bits
           - not to modify the 'method_mask' bitfield unnecessarily
         [Christophe Jaillet]
    
      *) mod_slotmem_shm: Increase log level for some originally debug messages.
         [Jim Jagielski]
    
      *) mod_ldap: In 2.4.10, some LDAP searches or comparisons might be done with
         the wrong credentials when a backend connection is reused.
         [Eric Covener]
    
      *) mod_macro: Add missing APLOGNO for some Warning log messages.
         [Christophe Jaillet]
    
      *) mod_cache: Avoid sending 304 responses during failed revalidations
         PR56881. [Eric Covener]
    
      *) mod_status: Honor client IP address using mod_remoteip. PR 55886.
         [Jim Jagielski]
    
      *) cmake-based build for Windows: Fix incompatibility with cmake 2.8.12
         and later.  PR 56615.  [Chuck Liu <cliu81 gmail.com>, Jeff Trawick]
    
      *) mod_ratelimit: Drop severity of AH01455 and AH01457 (ap_pass_brigade
         failed) messages from ERROR to TRACE1.  Other filters do not bother
         re-reporting failures from lower level filters.  PR56832.  [Eric Covener]
    
      *) core: Avoid useless warning message when parsing a section guarded by
         <IfDefine foo> if $(foo) is used within the section.
         PR 56503 [Christophe Jaillet]
    
      *) mod_proxy_fcgi: Fix faulty logging of large amounts of stderr from the
         application.  PR 56858.  [Manuel Mausz <manuel-asf mausz.at>]
    
      *) mod_proxy_http: Proxy responses with error status and
         "ProxyErrorOverride On" hang until proxy timeout.
         PR53420 [Rainer Jung]
    
      *) mod_log_config: Allow three character log formats to be registered. For
         backwards compatibility, the first character of a three-character format
         must be the '^' (caret) character.  [Eric Covener]
    
      *) mod_lua: Don't quote Expires and Path values. PR 56734.
         [Keith Mashinter, <kmashint yahoo com>]
    
      *) mod_authz_core: Allow <AuthzProviderAlias>'es to be seen from auth
         stanzas under virtual hosts. PR 56870. [Eric Covener]
    
    Changes with Apache 2.4.10
    
      *) SECURITY: CVE-2014-0117 (cve.mitre.org)
         mod_proxy: Fix crash in Connection header handling which allowed a denial
         of service attack against a reverse proxy with a threaded MPM.
         [Ben Reser]
    
      *) SECURITY: CVE-2014-3523 (cve.mitre.org)
         Fix a memory consumption denial of service in the WinNT MPM, used in all
         Windows installations. Workaround: AcceptFilter <protocol> {none|connect}
         [Jeff Trawick]
    
      *) SECURITY: CVE-2014-0226 (cve.mitre.org)
         Fix a race condition in scoreboard handling, which could lead to
         a heap buffer overflow.  [Joe Orton, Eric Covener]
    
      *) SECURITY: CVE-2014-0118 (cve.mitre.org)
         mod_deflate: The DEFLATE input filter (inflates request bodies) now
         limits the length and compression ratio of inflated request bodies to
         avoid denial of service via highly compressed bodies.  See directives
         DeflateInflateLimitRequestBody, DeflateInflateRatioLimit,
         and DeflateInflateRatioBurst. [Yann Ylavic, Eric Covener]
    
      *) SECURITY: CVE-2014-0231 (cve.mitre.org)
         mod_cgid: Fix a denial of service against CGI scripts that do
         not consume stdin that could lead to lingering HTTPD child processes
         filling up the scoreboard and eventually hanging the server.  By
         default, the client I/O timeout (Timeout directive) now applies to
         communication with scripts.  The CGIDScriptTimeout directive can be
         used to set a different timeout for communication with scripts.
         [Rainer Jung, Eric Covener, Yann Ylavic]
    
      *) mod_ssl: Extend the scope of SSLSessionCacheTimeout to sessions
         resumed by TLS session resumption (RFC 5077). [Rainer Jung]
    
      *) mod_deflate: Don't fail when flushing inflated data to the user-agent
         and that coincides with the end of stream ("Zlib error flushing inflate
         buffer"). PR 56196. [Christoph Fausak <christoph fausak glueckkanja.com>]
    
      *) mod_proxy_ajp: Forward local IP address as a custom request attribute
         like we already do for the remote port. [Rainer Jung]
    
      *) core: Include any error notes set by modules in the canned error
         response for 403 errors.  [Jeff Trawick]
    
      *) mod_ssl: Set an error note for requests rejected due to
         SSLStrictSNIVHostCheck.  [Jeff Trawick]
    
      *) mod_ssl: Fix issue with redirects to error documents when handling
         SNI errors.  [Jeff Trawick]
    
      *) mod_ssl: Fix tmp DH parameter leak, adjust selection to prefer
         larger keys and support up to 8192-bit keys.  [Ruediger Pluem,
         Joe Orton]
    
      *) mod_dav: Fix improper encoding in PROPFIND responses.  PR 56480.
         [Ben Reser]
    
      *) WinNT MPM: Improve error handling for termination events in child.
         [Jeff Trawick]
    
      *) mod_proxy: When ping/pong is configured for a worker, don't send or
         forward "100 Continue" (interim) response to the client if it does
         not expect one. [Yann Ylavic]
    
      *) mod_ldap: Be more conservative with the last-used time for
         LDAPConnectionPoolTTL. PR54587 [Eric Covener]
    
      *) mod_ldap: LDAP connections used for authn were not respecting
         LDAPConnectionPoolTTL. PR54587 [Eric Covener]
    
      *) mod_proxy_fcgi: Fix occasional high CPU when handling request bodies.
         [Jeff Trawick]
    
      *) event MPM: Fix possible crashes (third-party modules accessing c->sbh)
         or occasional missed mod_status updates under load. PR 56639.
         [Edward Lu <Chaosed0 gmail com>]
    
      *) mod_authnz_ldap: Support primitive LDAP servers do not accept
         filters, such as "SDBM-backed LDAP" on z/OS, by allowing a special
         filter "none" to be specified in AuthLDAPURL. [Eric Covener]
    
      *) mod_deflate: Fix inflation of files larger than 4GB. PR 56062.
         [Lukas Bezdicka <social v3.sk>]
    
      *) mod_deflate: Handle Zlib header and validation bytes received in multiple
         chunks. PR 46146. [Yann Ylavic]
    
      *) mod_proxy: Allow reverse-proxy to be set via explicit handler.
         [ryo takatsuki <ryotakatsuki gmail com>]
    
      *) ab: support custom HTTP method with -m argument. PR 56604.
         [Roman Jurkov <winfinit gmail.com>]
    
      *) mod_proxy_balancer: Correctly encode user provided data in management
         interface. PR 56532 [Maksymilian, <max cert.cx>]
    
      *) mod_proxy: Don't limit the size of the connectable Unix Domain Socket
         paths. [Graham Dumpleton, Christophe Jaillet, Yann Ylavic]
    
      *) mod_proxy_fcgi: Support iobuffersize parameter.  [Jeff Trawick]
    
      *) event: Send the SSL close notify alert when the KeepAliveTimeout
         expires. PR54998. [Yann Ylavic]
    
      *) mod_ssl: Ensure that the SSL close notify alert is flushed to the client.
         PR54998. [Tim Kosse <tim.kosse filezilla-project.org>, Yann Ylavic]
    
      *) mod_proxy: Shutdown (eg. SSL close notify) the backend connection before
         closing. [Yann Ylavic]
    
      *) mod_auth_form: Add a debug message when the fields on a form are not
         recognised. [Graham Leggett]
    
      *) mod_cache: Preserve non-cacheable headers forwarded from an origin 304
         response. PR 55547.  [Yann Ylavic]
    
      *) mod_proxy_wstunnel: Fix the use of SSL connections with the "wss:"
         scheme. PR55320. [Alex Liu <alex.leo.ca gmail.com>]
    
      *) mod_socache_shmcb: Correct counting of expirations for status display.
         Expirations happening during retrieval were not counted. [Rainer Jung]
    
      *) mod_cache: Retry unconditional request with the full URL (including the
         query-string) when the origin server's 304 response does not match the
         conditions used to revalidate the stale entry.  [Yann Ylavic].
    
      *) mod_alias: Stop setting CONTEXT_PREFIX and CONTEXT_DOCUMENT environment
         variables as a result of AliasMatch. [Eric Covener]
    
      *) mod_cache: Don't add cached/revalidated entity headers to a 304 response.
         PR 55547.  [Yann Ylavic]
    
      *) mod_proxy_scgi: Support Unix sockets.  ap_proxy_port_of_scheme():
         Support default SCGI port (4000).  [Jeff Trawick]
    
      *) mod_cache: Fix AH00784 errors on Windows when the the CacheLock directive
         is enabled.  [Eric Covener]
    
      *) mod_expires: don't add Expires header to error responses (4xx/5xx),
         be they generated or forwarded. PR 55669.  [Yann Ylavic]
    
      *) mod_proxy_fcgi: Don't segfault when failing to connect to the backend.
         (regression in 2.4.9 release) [Jeff Trawick]
    
      *) mod_authn_socache: Fix crash at startup in certain configurations.
         PR 56371. (regression in 2.4.7) [Jan Kaluza]
    
      *) mod_ssl: restore argument structure for "exec"-type SSLPassPhraseDialog
         programs to the form used in releases up to 2.4.7, and emulate
         a backwards-compatible behavior for existing setups. [Kaspar Brand]
    
      *) mod_ssl: Add SSLOCSPUseRequestNonce directive to control whether or not
         OCSP requests should use a nonce to be checked against the responder's
         one. PR 56233. [Yann Ylavic, Kaspar Brand]
    
      *) mod_ssl: "SSLEngine off" will now override a Listen-based default
         and does disable mod_ssl for the vhost.  [Joe Orton]
    
      *) mod_lua: Enforce the max post size allowed via r:parsebody()
         [Daniel Gruno]
    
      *) mod_lua: Use binary comparison to find boundaries for multipart
         objects, as to not terminate our search prematurely when hitting
         a NULL byte. [Daniel Gruno]
    
      *) mod_ssl: add workaround for SSLCertificateFile when using OpenSSL
         versions before 0.9.8h and not specifying an SSLCertificateChainFile
         (regression introduced with 2.4.8). PR 56410. [Kaspar Brand]
    
      *) mod_ssl: bring SNI behavior into better conformance with RFC 6066:
         no longer send warning-level unrecognized_name(112) alerts,
         and limit startup warnings to cases where an OpenSSL version
         without TLS extension support is used. PR 56241. [Kaspar Brand]
    
      *) mod_proxy_html: Avoid some possible memory access violation in case of
         specially crafted files, when the ProxyHTMLMeta directive is turned on.
         Follow up of PR 56287 [Christophe Jaillet]
    
      *) mod_auth_form: Make sure the optional functions are loaded even when
         the AuthFormProvider isn't specified. [Graham Leggett]
    
      *) mod_ssl: avoid processing bogus SSLCertificateKeyFile values
         (and logging garbled file names). PR 56306. [Kaspar Brand]
    
      *) mod_ssl: fix merging of global and vhost-level settings with the
         SSLCertificateFile, SSLCertificateKeyFile, and SSLOpenSSLConfCmd
         directives. PR 56353. [Kaspar Brand]
    
      *) mod_headers: Allow the "value" parameter of Header and RequestHeader to
         contain an ap_expr expression if prefixed with "expr=". [Eric Covener]
    
      *) rotatelogs: Avoid creation of zombie processes when -p is used on
         Unix platforms.  [Joe Orton]
    
      *) mod_authnz_fcgi: New module to enable FastCGI authorizer
         applications to authenticate and/or authorize clients.
         [Jeff Trawick]
    
      *) mod_proxy: Do not try to parse the regular expressions passed by
         ProxyPassMatch as URL as they do not follow their syntax.
         PR 56074. [Ruediger Pluem]
    
      *) mod_reqtimeout: Resolve unexpected timeouts on keepalive requests
         under the Event MPM. PR56216.  [Frank Meier <frank meier ergon ch>]
    
      *) mod_proxy_fcgi: Fix sending of response without some HTTP headers
         that might be set by filters.  PR 55558. [Jim Riggs <jim riggs.me>]
    
      *) mod_proxy_html: Do not delete the wrong data from HTML code when a
         "http-equiv" meta tag specifies a Content-Type behind any other
         "http-equiv" meta tag. PR 56287 [Micha Lenk <micha lenk info>]
    
      *) mod_proxy: Don't reuse a SSL backend connection whose requested SNI
         differs. PR 55782.  [Yann Ylavic]
    
      *) Add suspend_connection and resume_connection hooks to notify modules
         when the thread/connection relationship changes.  (Should be implemented
         for any third-party async MPMs.)  [Jeff Trawick]
    
      *) mod_proxy_wstunnel: Don't issue AH02447 and log a 500 on routine
         hangups from websockets origin servers. PR 56299
         [Yann Ylavic, Edward Lu <Chaosed0 gmail com>, Eric Covener]
    
      *) mod_proxy_wstunnel: Don't pool backend websockets connections,
         because we need to handshake every time. PR 55890.
         [Eric Covener]
    
      *) mod_lua: Redesign how request record table access behaves,
         in order to utilize the request record from within these tables.
         [Daniel Gruno]
    
      *) mod_lua: Add r:wspeek for peeking at WebSocket frames. [Daniel Gruno]
    
      *) mod_lua: Log an error when the initial parsing of a Lua file fails.
         [Daniel Gruno, Felipe Daragon <filipe syhunt com>]
    
      *) mod_lua: Reformat and escape script error output.
         [Daniel Gruno, Felipe Daragon <filipe syhunt com>]
    
      *) mod_lua: URL-escape cookie keys/values to prevent tainted cookie data
         from causing response splitting.
         [Daniel Gruno, Felipe Daragon <filipe syhunt com>]
    
      *) mod_lua: Disallow newlines in table values inside the request_rec,
         to prevent HTTP Response Splitting via tainted headers.
         [Daniel Gruno, Felipe Daragon <filipe syhunt com>]
    
      *) mod_lua: Remove the non-working early/late arguments for
         LuaHookCheckUserID. [Daniel Gruno]
    
      *) mod_lua: Change IVM storage to use shm [Daniel Gruno]
    
      *) mod_lua: More verbose error logging when a handler function cannot be
         found. [Daniel Gruno]
    
    Changes with Apache 2.4.9
    
      *) mod_ssl: Work around a bug in some older versions of OpenSSL that
         would cause a crash in SSL_get_certificate for servers where the
         certificate hadn't been sent. [Stephen Henson]
    
      *) mod_lua: Add a fixups hook that checks if the original request is intended
         for LuaMapHandler. This fixes a bug where FallbackResource invalidates the
         LuaMapHandler directive in certain cases by changing the URI before the map
         handler code executes [Daniel Gruno, Daniel Ferradal <dferradal gmail com>].
    
    Changes with Apache 2.4.8 (not released)
    
      *) SECURITY: CVE-2014-0098 (cve.mitre.org)
         Clean up cookie logging with fewer redundant string parsing passes.
         Log only cookies with a value assignment. Prevents segfaults when
         logging truncated cookies.
         [William Rowe, Ruediger Pluem, Jim Jagielski]
    
      *) SECURITY: CVE-2013-6438 (cve.mitre.org)
         mod_dav: Keep track of length of cdata properly when removing
         leading spaces. Eliminates a potential denial of service from
         specifically crafted DAV WRITE requests
         [Amin Tora <Amin.Tora neustar.biz>]
    
      *) core: Support named groups and backreferences within the LocationMatch,
         DirectoryMatch, FilesMatch and ProxyMatch directives. (Requires
         non-ancient PCRE library) [Graham Leggett]
    
      *) core: draft-ietf-httpbis-p1-messaging-23 corrections regarding
         TE/CL conflicts. [Yann Ylavic, Jim Jagielski]
    
      *) core: Detect incomplete request and response bodies, log an error and
         forward it to the underlying filters. PR 55475 [Yann Ylavic]
    
      *) mod_dir: Add DirectoryCheckHandler to allow a 2.2-like behavior, skipping
         execution when a handler is already set. PR53929. [Eric Covener]
    
      *) mod_ssl: Do not perform SNI / Host header comparison in case of a
         forward proxy request. [Ruediger Pluem]
    
      *) mod_ssl: Remove the hardcoded algorithm-type dependency for the
         SSLCertificateFile and SSLCertificateKeyFile directives, to enable
         future algorithm agility, and deprecate the SSLCertificateChainFile
         directive (obsoleted by SSLCertificateFile). [Kaspar Brand]
    
      *) mod_rewrite: Add RewriteOptions InheritDown, InheritDownBefore,
         and IgnoreInherit to allow RewriteRules to be pushed from parent scopes
         to child scopes without explicitly configuring each child scope.
         PR56153.  [Edward Lu <Chaosed0 gmail com>]
    
      *) prefork: Fix long delays when doing a graceful restart.
         PR 54852 [Jim Jagielski, Arkadiusz Miskiewicz <arekm maven pl>]
    
      *) FreeBSD: Disable IPv4-mapped listening sockets by default for versions
         5+ instead of just for FreeBSD 5. PR 53824. [Jeff Trawick]
    
      *) mod_proxy_wstunnel: Avoid busy loop on client errors, drop message
         IDs 02445, 02446, and 02448 to TRACE1 from DEBUG. PR 56145.
         [Joffroy Christen <joffroy.christen solvaxis com>, Eric Covener]
    
      *) mod_remoteip: Correct the trusted proxy match test. PR 54651.
         [Yoshinori Ehara <yoshinori ehara gmail com>, Eugene L <eugenel amazon com>]
    
      *) mod_proxy_fcgi: Fix error message when an unexpected protocol version
         number is received from the application.  PR 56110.  [Jeff Trawick]
    
      *) mod_remoteip: Use the correct IP addresses to populate the proxy_ips field.
         PR 55972. [Mike Rumph]
    
      *) mod_lua: Update r:setcookie() to accept a table of options and add domain,
         path and httponly to the list of options available to set.
         PR 56128 [Edward Lu <Chaosed0 gmail com>, Daniel Gruno]
    
      *) mod_lua: Fix r:setcookie() to add, rather than replace,
         the Set-Cookie header. PR56105
         [Kevin J Walters <kjw ms com>, Edward Lu <Chaosed0 gmail com>]
    
      *) mod_lua: Allow for database results to be returned as a hash with
         row-name/value pairs instead of just row-number/value. [Daniel Gruno]
    
      *) mod_rewrite: Add %{CONN_REMOTE_ADDR} as the non-useragent counterpart to
         %{REMOTE_ADDR}. PR 56094. [Edward Lu <Chaosed0 gmail com>]
    
      *) WinNT MPM: If ap_run_pre_connection() fails or sets c->aborted, don't
         save the socket for reuse by the next worker as if it were an
         APR_SO_DISCONNECTED socket. Restores 2.2 behavior. [Eric Covener]
    
      *) mod_dir: Don't search for a DirectoryIndex or DirectorySlash on a URL
         that was just rewritten by mod_rewrite. PR53929. [Eric Covener]
    
      *) mod_session: When we have a session we were unable to decode,
         behave as if there was no session at all. [Thomas Eckert
         <thomas.r.w.eckert gmail com>]
    
      *) mod_session: Fix problems interpreting the SessionInclude and
         SessionExclude configuration. PR 56038. [Erik Pearson
         <erik adaptations.com>]
    
      *) mod_authn_core: Allow <AuthnProviderAlias>'es to be seen from auth
         stanzas under virtual hosts. PR 55622. [Eric Covener]
    
      *) mod_proxy_fcgi: Use apr_socket_timeout_get instead of hard-coded
         30 seconds timeout. [Jan Kaluza]
    
      *) build: only search for modules (config*.m4) in known subdirectories, see
         build/config-stubs. [Stefan Fritsch]
    
      *) mod_cache_disk: Fix potential hangs on Windows when using mod_cache_disk.
         PR 55833. [Eric Covener]
    
      *) mod_ssl: Add support for OpenSSL configuration commands by introducing
         the SSLOpenSSLConfCmd directive. [Stephen Henson, Kaspar Brand]
    
      *) mod_proxy: Remove (never documented) <Proxy ~ wildcard-url> syntax which
         is equivalent to <ProxyMatch wildcard-url>. [Christophe Jaillet]
    
      *) mod_authz_user, mod_authz_host, mod_authz_groupfile, mod_authz_dbm,
         mod_authz_dbd, mod_authnz_ldap: Support the expression parser within the
         require directives. [Graham Leggett]
    
      *) mod_proxy_http: Core dumped under high load. PR 50335.
         [Jan Kaluza <jkaluza redhat.com>]
    
      *) mod_socache_shmcb.c: Remove arbitrary restriction on shared memory size
         previously limited to 64MB. [Jens Låås <jelaas gmail.com>]
    
      *) mod_lua: Use binary copy when dealing with uploads through r:parsebody()
         to prevent truncating files. [Daniel Gruno]
    
    Changes with Apache 2.4.7
    
      *) SECURITY: CVE-2013-4352 (cve.mitre.org)
         mod_cache: Fix a NULL pointer deference which allowed untrusted
         origin servers to crash mod_cache in a forward proxy
         configuration.  [Graham Leggett]
    
      *) APR 1.5.0 or later is now required for the event MPM.
    
      *) slotmem_shm: Error detection. [Jim Jagielski]
    
      *) event: Use skiplist data structure. [Jim Jagielski]
    
      *) event: Fail at startup with message AP02405 if the APR atomic
         implementation is not compatible with the MPM.  [Jim Jagielski]
    
      *) mpm_unix: Add ap_mpm_podx_* implementation to avoid code duplication
         and align w/ trunk. [Jim Jagielski]
    
      *) Fix potential rejection of valid MaxMemFree and ThreadStackSize
         directives.  [Mike Rumph <mike.rumph oracle.com>]
    
      *) mod_proxy_fcgi: Remove 64K limit on encoded length of all envvars.
         An individual envvar with an encoded length of more than 16K will be
         omitted.  [Jeff Trawick]
    
      *) mod_proxy_fcgi: Handle reading protocol data that is split between
         packets.  [Jeff Trawick]
    
      *) mod_ssl: Improve handling of ephemeral DH and ECDH keys by
         allowing custom parameters to be configured via SSLCertificateFile,
         and by adding standardized DH parameters for 1024/2048/3072/4096 bits.
         Unless custom parameters are configured, the standardized parameters
         are applied based on the certificate's RSA/DSA key size. [Kaspar Brand]
    
      *) mod_ssl, configure: Require OpenSSL 0.9.8a or later. [Kaspar Brand]
    
      *) mod_ssl: drop support for export-grade ciphers with ephemeral RSA
         keys, and unconditionally disable aNULL, eNULL and EXP ciphers
         (not overridable via SSLCipherSuite). [Kaspar Brand]
    
      *) mod_proxy: Added support for unix domain sockets as the
         backend server endpoint. This also introduces an unintended
         incompatibility for third party modules using the mod_proxy
         proxy_worker_shared structure, especially for balancer lbmethod
         modules. [Jim Jagielski, Blaise Tarr <blaise tarr gmail com>]
    
      *) Add experimental cmake-based build system for Windows.  [Jeff Trawick,
         Tom Donovan]
    
      *) event MPM: Fix possible crashes (third party modules accessing c->sbh)
         or occasional missed mod_status updates for some keepalive requests
         under load. [Eric Covener]
    
      *) mod_authn_socache: Support optional initialization arguments for
         socache providers.  [Chris Darroch]
    
      *) mod_session: Reset the max-age on session save. PR 47476. [Alexey
         Varlamov <alexey.v.varlamov gmail com>]
    
      *) mod_session: After parsing the value of the header specified by the
         SessionHeader directive, remove the value from the response. PR 55279.
         [Graham Leggett]
    
      *) mod_headers: Allow for format specifiers in the substitution string
         when using Header edit. [Daniel Ruggeri]
    
      *) mod_dav: dav_resource->uri is treated as unencoded. This was an
         unnecessary ABI changed introduced in 2.4.6. PR 55397.
    
      *) mod_dav: Don't require lock tokens for COPY source. PR 55306.
    
      *) core: Don't truncate output when sending is interrupted by a signal,
         such as from an exiting CGI process. PR 55643. [Jeff Trawick]
    
      *) WinNT MPM: Exit the child if the parent process crashes or is terminated.
         [Oracle Corporation]
    
      *) Windows: Correct failure to discard stderr in some error log
         configurations.  (Error message AH00093)  [Jeff Trawick]
    
      *) mod_session_crypto: Allow using exec: calls to obtain session
         encryption key.  [Daniel Ruggeri]
    
      *) core: Add missing Reason-Phrase in HTTP response headers.
         PR 54946. [Rainer Jung]
    
      *) mod_rewrite: Make rewrite websocket-aware to allow proxying.
         PR 55598. [Chris Harris <chris.harris kitware com>]
    
      *) mod_ldap: When looking up sub-groups, use an implicit objectClass=*
         instead of an explicit cn=* filter. [David Hawes <dhawes vt.edu>]
    
      *) ab: Add wait time, fix processing time, and output write errors only if
         they occurred. [Christophe Jaillet]
    
      *) worker MPM: Don't forcibly kill worker threads if the child process is
         exiting gracefully.  [Oracle Corporation]
    
      *) core: apachectl -S prints wildcard name-based virtual hosts twice.
         PR54948 [Eric Covener]
    
      *) mod_auth_basic: Add AuthBasicUseDigestAlgorithm directive to
         allow migration of passwords from digest to basic authentication.
         [Chris Darroch]
    
      *) ab: Add a new -l parameter in order not to check the length of the responses.
         This can be useful with dynamic pages.
         PR9945, PR27888, PR42040 [<ccikrs1 cranbrook edu>]
    
      *) Suppress formatting of startup messages written to the console when
         ErrorLogFormat is used.  [Jeff Trawick]
    
      *) mod_auth_digest: Be more specific when the realm mismatches because the
         realm has not been specified. [Graham Leggett]
    
      *) mod_proxy: Add a note in the balancer manager stating whether changes
         will or will not be persisted and whether settings are inherited.
         [Daniel Ruggeri, Jim Jagielski]
    
      *) core: Add util_fcgi.h and associated definitions and support
         routines for FastCGI, based largely on mod_proxy_fcgi.
         [Jeff Trawick]
    
      *) mod_headers: Add 'Header note header-name note-name' for copying a response
         headers value into a note. [Eric Covener]
    
      *) mod_headers: Add 'setifempty' command to Header and RequestHeader.
         [Eric Covener]
    
      *) mod_logio: new format-specifier %S (sum) which is the sum of received
         and sent byte counts.
         PR54015 [Christophe Jaillet]
    
      *) mod_deflate: Improve error detection when decompressing request bodies
         with trailing garbage: handle case where trailing bytes are in
         the same bucket. [Rainer Jung]
    
      *) mod_authz_groupfile, mod_authz_user: Reduce severity of AH01671 and AH01663
         from ERROR to DEBUG, since these modules do not know what mod_authz_core
         is doing with their AUTHZ_DENIED return value. [Eric Covener]
    
      *) mod_ldap: add TRACE5 for LDAP retries. [Eric Covener]
    
      *) mod_ldap: retry on an LDAP timeout during authn. [Eric Covener]
    
      *) mod_ldap: Change "LDAPReferrals off" to actually set the underlying LDAP
         SDK option to OFF, and introduce "LDAPReferrals default" to take the SDK
         default, sans rebind authentication callback.
         [Jan Kaluza <kaluze AT redhat.com>]
    
      *) core: Log a message at TRACE1 when the client aborts a connection.
         [Eric Covener]
    
      *) WinNT MPM: Don't crash during child process initialization if the
         Listen protocol is unrecognized.  [Jeff Trawick]
    
      *) modules: Fix some compiler warnings. [Guenter Knauf]
    
      *) Sync 2.4 and trunk
           - Avoid some memory allocation and work when TRACE1 is not activated
           - fix typo in include guard
           - indent
           - No need to lower the string before removing the path, it is just
             a waste of time...
           - Save a few cycles
         [Christophe Jaillet <christophe.jaillet wanadoo.fr>]
    
      *) mod_filter: Add "change=no" as a proto-flag to FilterProtocol
         to remove a providers initial flags set at registration time.
         [Eric Covener]
    
      *) core, mod_ssl: Enable the ability for a module to reverse the sense of
         a poll event from a read to a write or vice versa. This is a step on
         the way to allow mod_ssl taking full advantage of the event MPM.
         [Graham Leggett]
    
      *) Makefile.win: Install proper pcre DLL file during debug build install.
         PR 55235.  [Ben Reser <ben reser org>]
    
      *) mod_ldap: Fix a potential memory leak or corruption.  PR 54936.
         [Zhenbo Xu <zhenbo1987 gmail com>]
    
      *) ab: Fix potential buffer overflows when processing the T and X
         command-line options.  PR 55360.
         [Mike Rumph <mike.rumph oracle.com>]
    
      *) fcgistarter: Specify SO_REUSEADDR to allow starting a server
         with old connections in TIME_WAIT.  [Jeff Trawick]
    
      *) core: Add open_htaccess hook which, in conjunction with dirwalk_stat
         and post_perdir_config (introduced in 2.4.5), allows mpm-itk to be
         used without patches to httpd core. [Stefan Fritsch]
    
      *) support/htdbm: fix processing of -t command line switch. Regression
         introduced in 2.4.4
         PR 55264 [Jo Rhett <jrhett netconsonance com>]
    
      *) mod_lua: add websocket support via r:wsupgrade, r:wswrite, r:wsread
         and r:wsping. [Daniel Gruno]
    
      *) mod_lua: add support for writing/reading cookies via r:getcookie and
         r:setcookie. [Daniel Gruno]
    
      *) mod_lua: If the first yield() of a LuaOutputFilter returns a string, it should
         be prefixed to the response as documented. [Eric Covener]
         Note: Not present in 2.4.7 CHANGES
    
      *) mod_lua: Remove ETAG, Content-Length, and Content-MD5 when a LuaOutputFilter
         is configured without mod_filter. [Eric Covener]
         Note: Not present in 2.4.7 CHANGES
    
      *) mod_lua: Register LuaOutputFilter scripts as changing the content and
         content-length by default, when run my mod_filter.  Previously,
         growing or shrinking a response that started with Content-Length set
         would require mod_filter and FilterProtocol change=yes. [Eric Covener]
         Note: Not present in 2.4.7 CHANGES
    
      *) mod_lua: Return a 500 error if a LuaHook* script doesn't return a
         numeric return code. [Eric Covener]
         Note: Not present in 2.4.7 CHANGES
    
    Changes with Apache 2.4.6
    
      *) Revert a broken fix for PR54948 that was applied to 2.4.5 (which was
         not released) and found post-2.4.5 tagging.
    
    Changes with Apache 2.4.5
    
      *) SECURITY: CVE-2013-1896 (cve.mitre.org)
         mod_dav: Sending a MERGE request against a URI handled by mod_dav_svn with
         the source href (sent as part of the request body as XML) pointing to a
         URI that is not configured for DAV will trigger a segfault. [Ben Reser
         <ben reser.org>]
    
      *) SECURITY: CVE-2013-2249 (cve.mitre.org)
         mod_session_dbd: Make sure that dirty flag is respected when saving
         sessions, and ensure the session ID is changed each time the session
         changes. This changes the format of the updatesession SQL statement.
         Existing configurations must be changed.
         [Takashi Sato, Graham Leggett]
    
      *) mod_auth_basic: Add a generic mechanism to fake basic authentication
         using the ap_expr parser. AuthBasicFake allows the administrator to
         construct their own username and password for basic authentication based
         on their needs. [Graham Leggett]
    
      *) mpm_event: Check that AsyncRequestWorkerFactor is not negative. PR 54254.
         [Jackie Zhang <jackie qq zhang gmail com>]
    
      *) mod_proxy: Ensure we don't attempt to amend a table we are iterating
         through, ensuring that all headers listed by Connection are removed.
         [Graham Leggett, Co-Advisor <coad measurement-factory.com>]
    
      *) mod_proxy_http: Make the proxy-interim-response environment variable
         effective by formally overriding origin server behaviour. [Graham
         Leggett, Co-Advisor <coad measurement-factory.com>]
    
      *) mod_proxy: Fix seg-faults when using the global pool on threaded
         MPMs [Thomas Eckert <thomas.r.w.eckert gmail.com>, Graham Leggett,
         Jim Jagielski]
    
      *) mod_deflate: Remove assumptions as to when an EOS bucket might arrive.
         Gracefully step aside if the body size is zero. [Graham Leggett]
    
      *) mod_ssl: Fix possible truncation of OCSP responses when reading from the
         server.  [Joe Orton]
    
      *) core: Support the SINGLE_LISTEN_UNSERIALIZED_ACCEPT optimization
         on Linux kernel versions 3.x and above.  PR 55121.  [Bradley Heilbrun
         <apache heilbrun.org>]
    
      *) mod_cache_socache: Make sure the CacheSocacheMaxSize directive is merged
         correctly. [Jens Låås <jelaas gmail.com>]
    
      *) rotatelogs: add -n number-of-files option to rotate through a number
         of fixed-name logfiles. [Eric Covener]
    
      *) mod_proxy: Support web-socket tunnels via mod_proxy_wstunnel.
         [Jim Jagielski]
    
      *) mod_cache_socache: Use the name of the socache implementation when performing
         a lookup rather than using the raw arguments. [Martin Ksellmann
         <martin@ksellmann.de>]
    
      *) core: Add dirwalk_stat hook.  [Jeff Trawick]
    
      *) core: Add post_perdir_config hook.
         [Steinar Gunderson <sgunderson bigfoot.com>]
    
      *) proxy_util: NULL terminate the right buffer in 'send_http_connect'.
         [Christophe Jaillet]
    
      *) mod_remoteip: close file in error path. [Christophe Jaillet]
    
      *) core: make the "default" parameter of the "ErrorDocument" option case
         insensitive. PR 54419 [Tianyin Xu <tixu cs ucsd edu>]
    
      *) mod_proxy_html: make the "ProxyHTMLFixups" options case insensitive.
         PR 54420 [Tianyin Xu <tixu cs ucsd edu>]
    
      *) mod_cache: Make option "CacheDisable" in mod_cache case insensitive.
         PR 54462 [Tianyin Xu <tixu cs ucsd edu>]
    
      *) mod_cache: If a 304 response indicates an entity not currently cached, then
         the cache MUST disregard the response and repeat the request without the
         conditional. [Graham Leggett, Co-Advisor <coad measurement-factory.com>]
    
      *) mod_cache: Ensure that we don't attempt to replace a cached response
         with an older response as per RFC2616 13.12. [Graham Leggett, Co-Advisor
         <coad measurement-factory.com>]
    
      *) core, mod_cache: Ensure RFC2616 compliance in ap_meets_conditions()
         with weak validation combined with If-Range and Range headers. Break
         out explicit conditional header checks to be useable elsewhere in the
         server. Ensure weak validation RFC compliance in the byteranges filter.
         Ensure RFC validation compliance when serving cached entities. PR 16142
         [Graham Leggett, Co-Advisor <coad measurement-factory.com>]
    
      *) core: Add the ability to do explicit matching on weak and strong ETags
         as per RFC2616 Section 13.3.3. [Graham Leggett, Co-Advisor
         <coad measurement-factory.com>]
    
      *) mod_cache: Ensure that updated responses to HEAD requests don't get
         mistakenly paired with a previously cached body. Ensure that any existing
         body is removed when a HEAD request is cached. [Graham Leggett,
         Co-Advisor <coad measurement-factory.com>]
    
      *) mod_cache: Honour Cache-Control: no-store in a request. [Graham Leggett]
    
      *) mod_cache: Make sure that contradictory entity headers present in a 304
         Not Modified response are caught and cause the entity to be removed.
         [Graham Leggett]
    
      *) mod_cache: Make sure Vary processing handles multivalued Vary headers and
         multivalued headers referred to via Vary. [Graham Leggett]
    
      *) mod_cache: When serving from cache, only the last header of a multivalued
         header was taken into account. Fixed. Ensure that Warning headers are
         correctly handled as per RFC2616. [Graham Leggett]
    
      *) mod_cache: Ignore response headers specified by no-cache=header and
         private=header as specified by RFC2616 14.9.1 What is Cacheable. Ensure
         that these headers are still processed when multiple Cache-Control
         headers are present in the response. PR 54706 [Graham Leggett,
         Yann Ylavic <ylavic.dev gmail.com>]
    
      *) mod_cache: Invalidate cached entities in response to RFC2616 Section
         13.10 Invalidation After Updates or Deletions. PR 15868 [Graham
         Leggett]
    
      *) mod_dav: Improve error handling in dav_method_put(), add new
         dav_join_error() function.  PR 54145.  [Ben Reser <ben reser.org>]
    
      *) mod_dav: Do not fail PROPPATCH when prop namespace is not known.
         PR 52559 [Diego Santa Cruz <diego.santaCruz spinetix.com>]
    
      *) mod_dav: When a PROPPATCH attempts to remove a non-existent dead
         property on a resource for which there is no dead property in the same
         namespace httpd segfaults. PR 52559 [Diego Santa Cruz
         <diego.santaCruz spinetix.com>]
    
      *) mod_dav: Sending an If or If-Match header with an invalid ETag doesn't
         result in a 412 Precondition Failed for a COPY operation. PR54610
         [Timothy Wood <tjw omnigroup.com>]
    
      *) mod_dav: Make sure that when we prepare an If URL for Etag comparison,
         we compare unencoded paths. PR 53910 [Timothy Wood <tjw omnigroup.com>]
    
      *) mod_deflate: Remove assumptions as to when an EOS bucket might arrive.
         Gracefully step aside if the body size is zero. [Graham Leggett]
    
      *) 'AuthGroupFile' and 'AuthUserFile' do not accept anymore the optional
         'standard' keyword . It was unused and not documented.
         PR54463 [Tianyin Xu <tixu cs.ucsd.edu> and Christophe Jaillet]
    
      *) core: Do not over allocate memory within 'ap_rgetline_core' for
         the common case. [Christophe Jaillet]
    
      *) core: speed up (for common cases) and reduce memory usage of
         ap_escape_logitem(). This should save 70-100 bytes in the request
         pool for a default config. [Christophe Jaillet]
    
      *) mod_dav: Ensure URI is correctly uriencoded on return. PR 54611
         [Timothy Wood <tjw omnigroup.com>]
    
      *) mod_proxy: Reject invalid values for Max-Forwards. [Graham Leggett,
         Co-Advisor <coad measurement-factory.com>]
    
      *) mod_cache: RFC2616 14.9.3 The s-maxage directive also implies the
         semantics of the proxy-revalidate directive. [Graham Leggett]
    
      *) mod_ssl: add support for subjectAltName-based host name checking
         in proxy mode (SSLProxyCheckPeerName). PR 54030. [Kaspar Brand]
    
      *) core: Use the proper macro for HTTP/1.1. [Graham Leggett]
    
      *) event MPM: Provide error handling for ThreadStackSize. PR 54311
         [Tianyin Xu <tixu cs.ucsd.edu>, Christophe Jaillet]
    
      *) mod_dav: Do not segfault on PROPFIND with a zero length DBM.
         PR 52559 [Diego Santa Cruz <diego.santaCruz spinetix.com>]
    
      *) core: Improve error message where client's request-line exceeds
         LimitRequestLine. PR 54384 [Christophe Jaillet]
    
      *) mod_macro: New module that provides macros within configuration files.
         [Fabien Coelho]
    
      *) mod_cache_socache: New cache implementation backed by mod_socache
         that replaces mod_mem_cache known from httpd 2.2. [Graham
         Leggett]
    
      *) htpasswd: Add -v option to verify a password. [Stefan Fritsch]
    
      *) mod_proxy: Add BalancerInherit and ProxyPassInherit to control
         whether Proxy Balancers and Workers are inherited by vhosts
         (default is On). [Jim Jagielski]
    
      *) mod_authnz_ldap: Allow using exec: calls to obtain LDAP bind
         password.  [Daniel Ruggeri]
    
      *) Added balancer parameter failontimeout to allow server admin
         to configure an IO timeout as an error in the balancer.
         [Daniel Ruggeri]
    
      *) mod_auth_digest: Fix crashes if shm initialization failed. [Stefan
         Fritsch]
    
      *) htpasswd, htdbm: Fix password generation. PR 54735. [Stefan Fritsch]
    
      *) core: Add workaround for gcc bug on sparc/64bit. PR 52900.
         [Stefan Fritsch]
    
      *) mod_setenvif: Fix crash in case SetEnvif and SetEnvIfExpr are used
         together. PR 54881. [Ruediger Pluem]
    
      *) htdigest: Fix buffer overflow when reading digest password file
         with very long lines. PR 54893. [Rainer Jung]
    
      *) ap_expr: Add the ability to base64 encode and base64 decode
         strings and to generate their SHA1 and MD5 hash.
         [Graham Leggett, Stefan Fritsch]
    
      *) mod_log_config: Fix crash when logging request end time for a failed
         request.  PR 54828 [Rainer Jung]
    
      *) mod_ssl: Catch missing, mismatched or encrypted client cert/key pairs
         with SSLProxyMachineCertificateFile/Path directives. PR 52212, PR 54698.
         [Keith Burdis <keith burdis.org>, Joe Orton, Kaspar Brand]
    
      *) mod_ssl: Quiet FIPS mode weak keys disabled and FIPS not selected emits
         in the error log to debug level.  [William Rowe]
    
      *) mod_cache_disk: CacheMinFileSize and CacheMaxFileSize were always
         using compiled in defaults of 1000000/1 respectively. [Eric Covener]
    
      *) mod_lbmethod_heartbeat, mod_heartmonitor: Respect DefaultRuntimeDir/
         DEFAULT_REL_RUNTIMEDIR for the heartbeat storage file.  [Jeff Trawick]
    
      *) mod_include: Use new ap_expr for 'elif', like 'if',
         if legacy parser is not specified.  PR 54548 [Tom Donovan]
    
      *) mod_lua: Add some new functions: r:htpassword(), r:mkdir(), r:mkrdir(),
         r:rmdir(), r:touch(), r:get_direntries(), r.date_parse_rfc().
         [Guenter Knauf]
    
      *) mod_lua: Add multipart form data handling. [Daniel Gruno]
    
      *) mod_lua: If a LuaMapHandler doesn't return any value, log a warning
         and treat it as apache2.OK. [Eric Covener]
    
      *) mod_lua: Add bindings for apr_dbd/mod_dbd database access
         [Daniel Gruno]
    
      *) mod_lua: Add LuaInputFilter/LuaOutputFilter for creating content
         filters in Lua [Daniel Gruno]
    
      *) mod_lua: Allow scripts handled by the lua-script handler to return
         a status code to the client (such as a 302 or a 500) [Daniel Gruno]
    
      *) mod_lua: Decline handling 'lua-script' if the file doesn't exist,
         rather than throwing an internal server error. [Daniel Gruno]
    
      *) mod_lua: Add functions r:flush and r:sendfile as well as additional
         request information to the request_rec structure. [Daniel Gruno]
    
      *) mod_lua: Add a server scope for Lua states, which creates a pool of
         states with manageable minimum and maximum size. [Daniel Gruno]
    
      *) mod_lua: Add new directive, LuaMapHandler, for dynamically mapping
         URIs to Lua scripts and functions using regular expressions.
         [Daniel Gruno]
    
      *) mod_lua: Add new directive LuaCodeCache for controlling in-memory
         caching of lua scripts. [Daniel Gruno]
    
    Changes with Apache 2.4.4
    
      *) SECURITY: CVE-2012-3499 (cve.mitre.org)
         Various XSS flaws due to unescaped hostnames and URIs HTML output in
         mod_info, mod_status, mod_imagemap, mod_ldap, and mod_proxy_ftp.
         [Jim Jagielski, Stefan Fritsch, Niels Heinen <heinenn google com>]
    
      *) SECURITY: CVE-2012-4558 (cve.mitre.org)
         XSS in mod_proxy_balancer manager interface. [Jim Jagielski,
         Niels Heinen <heinenn google com>]
    
      *) mod_dir: Add support for the value 'disabled' in FallbackResource.
         [Vincent Deffontaines]
    
      *) mod_proxy_connect: Don't keepalive the connection to the client if the
         backend closes the connection. PR 54474. [Pavel Mateja <pavel netsafe cz>]
    
      *) mod_lua: Add bindings for mod_dbd/apr_dbd database access.
         [Daniel Gruno]
    
      *) mod_proxy: Allow for persistence of local changes made via the
         balancer-manager between graceful/normal restarts and power
         cycles. [Jim Jagielski]
    
      *) mod_proxy: Fix startup crash with mis-defined balancers.
         PR 52402. [Jim Jagielski]
    
      *) --with-module: Fix failure to integrate them into some existing
         module directories.  PR 40097.  [Jeff Trawick]
    
      *) htcacheclean: Fix potential segfault if "-p" is omitted.  [Joe Orton]
    
      *) mod_proxy_http: Honour special value 0 (unlimited) of LimitRequestBody
         PR 54435.  [Pavel Mateja <pavel netsafe.cz>]
    
      *) mod_proxy_ajp: Support unknown HTTP methods. PR 54416.
         [Rainer Jung]
    
      *) htcacheclean: Fix list options "-a" and "-A".
         [Rainer Jung]
    
      *) mod_slotmem_shm: Fix mistaken reset of num_free for restored shm.
         [Jim Jagielski]
    
      *) mod_proxy: non-existence of byrequests is not an immediate error.
         [Jim Jagielski]
    
      *) mod_proxy_balancer: Improve output of balancer-manager (re: Drn,
         Dis, Ign, Stby). PR 52478 [Danijel <dt-ng rbfh de>]
    
      *) configure: Fix processing of --disable-FEATURE for various features.
         [Jeff Trawick]
    
      *) mod_dialup/mod_http: Prevent a crash in mod_dialup in case of internal
         redirect. PR 52230.
    
      *) various modules, rotatelogs: Replace use of apr_file_write() with
         apr_file_write_full() to prevent incomplete writes. PR 53131.
         [Nicolas Viennot <apache viennot biz>, Stefan Fritsch]
    
      *) ab: Support socket timeout (-s timeout).
         [Guido Serra <zeph fsfe org>]
    
      *) httxt2dbm: Correct length computation for the 'value' stored in the
         DBM file. PR 47650 [jon buckybox com]
    
      *) core: Be more correct about rejecting directives that cannot work in <If>
         sections. [Stefan Fritsch]
    
      *) core: Fix directives like LogLevel that need to know if they are invoked
         at virtual host context or in Directory/Files/Location/If sections to
         work properly in If sections that are not in a Directory/Files/Location.
         [Stefan Fritsch]
    
      *) mod_xml2enc: Fix problems with charset conversion altering the
         Content-Length. [Micha Lenk <micha lenk info>]
    
      *) ap_expr: Add req_novary function that allows HTTP header lookups
         without adding the name to the Vary header. [Stefan Fritsch]
    
      *) mod_slotmem_*: Add in new fgrab() function which forces a grab and
         slot allocation on a specified slot. Allow for clearing of inuse
         array. [Jim Jagielski]
    
      *) mod_proxy_ftp: Fix segfaults on IPv4 requests to hosts with DNS
         AAAA records. PR  40841. [Andrew Rucker Jones <arjones simultan
         dyndns org>, <ast domdv de>, Jim Jagielski]
    
      *) mod_auth_form: Make sure that get_notes_auth() sets the user as does
         get_form_auth() and get_session_auth(). Makes sure that REMOTE_USER
         does not vanish during mod_include driven subrequests. [Graham
         Leggett]
    
      *) mod_cache_disk: Resolve errors while revalidating disk-cached files on
         Windows ("...rename tempfile to datafile failed..."). PR 38827
         [Eric Covener]
    
      *) mod_proxy_balancer: Bring XML output up to date. [Jim Jagielski]
    
      *) htpasswd, htdbm: Optionally read passwords from stdin, as more
         secure alternative to -b.  PR 40243. [Adomas Paltanavicius <adomas
         paltanavicius gmail com>, Stefan Fritsch]
    
      *) htpasswd, htdbm: Add support for bcrypt algorithm (requires
         apr-util 1.5 or higher). PR 49288. [Stefan Fritsch]
    
      *) htpasswd, htdbm: Put full 48bit of entropy into salt, improve
         error handling. Add some of htpasswd's improvements to htdbm,
         e.g. warn if password is truncated by crypt(). [Stefan Fritsch]
    
      *) mod_auth_form: Support the expr parser in the
         AuthFormLoginRequiredLocation, AuthFormLoginSuccessLocation and
         AuthFormLogoutLocation directives. [Graham Leggett]
    
      *) mod_ssl: Add support for TLS-SRP (Secure Remote Password key exchange
         for TLS, RFC 5054). PR 51075. [Quinn Slack <sqs cs stanford edu>,
         Christophe Renou, Peter Sylvester]
    
      *) mod_rewrite: Stop mergeing RewriteBase down to subdirectories
         unless new option 'RewriteOptions MergeBase' is configured.
         PR 53963. [Eric Covener]
    
      *) mod_header: Allow for exposure of loadavg and server load using new
         format specifiers %l, %i, %b [Jim Jagielski]
    
      *) core: Make ap_regcomp() return AP_REG_ESPACE if out of memory.  Make
         ap_pregcomp() abort if out of memory. This raises the minimum PCRE
         requirement to version 6.0. [Stefan Fritsch]
    
      *) mod_proxy: Add ability to configure the sticky session separator.
         PR 53893. [<inu inusasha de>, Jim Jagielski]
    
      *) mod_dumpio: Correctly log large messages
         PR 54179 [Marek Wianecki <mieszek2 interia pl>]
    
      *) core: Don't fail at startup with AH00554 when Include points to
         a directory without any wildcard character. [Eric Covener]
    
      *) core: Fail startup if the argument to ServerTokens is unrecognized.
         [Jackie Zhang  <jackie.qq.zhang gmail.com>]
    
      *) mod_log_forensic: Don't log a spurious "-" if a request has been rejected
         before mod_log_forensic could attach its id to it. [Stefan Fritsch]
    
      *) rotatelogs: Omit the second argument for the first invocation of
         a post-rotate program when -p is used, per the documentation.
         [Joe Orton]
    
      *) mod_session_dbd: fix a segmentation fault in the function dbd_remove.
         PR 53452. [<rebanerebane gmail com>, Reimo Rebane]
    
      *) core: Functions to provide server load values: ap_get_sload() and
         ap_get_loadavg(). [Jim Jagielski, Jan Kaluza <jkaluza redhat.com>,
         Jeff Trawick]
    
      *) mod_ldap: Fix regression in handling "server unavailable" errors on
         Windows.  PR 54140.  [Eric Covener]
    
      *) syslog logging: Remove stray ", referer" at the end of some messages.
         [Jeff Trawick]
    
      *) "Iterate" directives: Report an error if no arguments are provided.
         [Jeff Trawick]
    
      *) mod_ssl: Change default for SSLCompression to off, as compression
         causes security issues in most setups. (The so called "CRIME" attack).
         [Stefan Fritsch]
    
      *) ab: add TLS1.1/TLS1.2 options to -f switch, and adapt output
         to more accurately report the negotiated protocol. PR 53916.
         [Nicolás Pernas Maradei <nico emutex com>, Kaspar Brand]
    
      *) core: ErrorDocument now works for requests without a Host header.
         PR 48357.  [Jeff Trawick]
    
      *) prefork: Avoid logging harmless errors during graceful stop.
         [Joe Orton, Jeff Trawick]
    
      *) mod_proxy: When concatting for PPR, avoid cases where we
         concat ".../" and "/..." to create "...//..." [Jim Jagielski]
    
      *) mod_cache: Wrong content type and character set when
         mod_cache serves stale content because of a proxy error.
         PR 53539.  [Rainer Jung, Ruediger Pluem]
    
      *) mod_proxy_ajp: Fix crash in packet dump code when logging
         with LogLevel trace7 or trace8.  PR 53730.  [Rainer Jung]
    
      *) httpd.conf: Removed the configuration directives setting a bad_DNT
         environment introduced in 2.4.3. The actual directives are commented
         out in the default conf file.
    
      *) core: Apply length limit when logging Status header values.
         [Jeff Trawick, Chris Darroch]
    
      *) mod_proxy_balancer: The nonce is only derived from the UUID iff
         not set via the 'nonce' balancer param. [Jim Jagielski]
    
      *) mod_ssl: Match wildcard SSL certificate names in proxy mode.
         PR 53006.  [Joe Orton]
    
      *) Windows: Fix output of -M, -L, and similar command-line options
         which display information about the server configuration.
         [Jeff Trawick]
    
    Changes with Apache 2.4.3
    
      *) SECURITY: CVE-2012-3502  (cve.mitre.org)
         mod_proxy_ajp, mod_proxy_http: Fix an issue in back end
         connection closing which could lead to privacy issues due
         to a response mixup. PR 53727. [Rainer Jung]
    
      *) SECURITY: CVE-2012-2687 (cve.mitre.org)
         mod_negotiation: Escape filenames in variant list to prevent a
         possible XSS for a site where untrusted users can upload files to
         a location with MultiViews enabled. [Niels Heinen <heinenn google.com>]
    
      *) mod_authnz_ldap: Don't try a potentially expensive nested groups
         search before exhausting all AuthLDAPGroupAttribute checks on the
         current group. PR 52464 [Eric Covener]
    
      *) mod_lua: Add new directive LuaAuthzProvider to allow implementing an
         authorization provider in lua. [Stefan Fritsch]
    
      *) core: Be less strict when checking whether Content-Type is set to
         "application/x-www-form-urlencoded" when parsing POST data,
         or we risk losing data with an appended charset. PR 53698
         [Petter Berntsen <petterb gmail.com>]
    
      *) httpd.conf: Added configuration directives to set a bad_DNT environment
         variable based on User-Agent and to remove the DNT header field from
         incoming requests when a match occurs. This currently has the effect of
         removing DNT from requests by MSIE 10.0 because it deliberately violates
         the current specification of DNT semantics for HTTP. [Roy T. Fielding]
    
      *) mod_socache_shmcb: Fix bus error due to a misalignment
         in some 32 bit builds, especially on Solaris Sparc.
         PR 53040.  [Rainer Jung]
    
      *) mod_cache: Set content type in case we return stale content.
         [Ruediger Pluem]
    
      *) Windows: Fix SSL failures on windows with AcceptFilter https none.
         PR 52476.  [Jeff Trawick]
    
      *) ab: Fix read failure when targeting SSL server.  [Jeff Trawick]
    
      *) The following now respect DefaultRuntimeDir/DEFAULT_REL_RUNTIMEDIR:
         - mod_auth_digest: shared memory file
         [Jeff Trawick]
    
      *) htpasswd: Use correct file mode for checking if file is writable.
         PR 45923. [Stefan Fritsch]
    
      *) mod_rewrite: Fix crash with dbd RewriteMaps. PR 53663. [Mikhail T.
         <mi apache aldan algebra com>]
    
      *) mod_ssl: Add new directive SSLCompression to disable TLS-level
         compression. PR 53219. [Björn Jacke <bjoern j3e de>, Stefan Fritsch]
    
      *) mod_lua: Add a few missing request_rec fields. Rename remote_ip to
         client_ip to match conn_rec. [Stefan Fritsch]
    
      *) mod_lua: Change prototype of vm_construct, to work around gcc bug which
         causes a segfault. PR 52779. [Dick Snippe <Dick Snippe tech omroep nl>]
    
      *) mpm_event: Don't count connections in lingering close state when
         calculating how many additional connections may be accepted.
         [Stefan Fritsch]
    
      *) mod_ssl: If exiting during initialization because of a fatal error,
         log a message to the main error log pointing to the appropriate
         virtual host error log. [Stefan Fritsch]
    
      *) mod_proxy_ajp: Reduce memory usage in case of many keep-alive requests on
         one connection. PR 52275. [Naohiro Ooiwa <naohiro ooiwa miraclelinux com>]
    
      *) mod_proxy_balancer: Restore balancing after a failed worker has
         recovered when using lbmethod_bybusyness.  PR 48735.  [Jeff Trawick]
    
      *) mod_setenvif: Compile some global regex only once during startup.
         This should save some memory, especially with .htaccess.
         [Stefan Fritsch]
    
      *) core: Add the port number to the vhost's name in the scoreboard.
         [Stefan Fritsch]
    
      *) mod_proxy: Fix ProxyPassReverse for balancer configurations.
         PR 45434.  [Joe Orton]
    
      *) mod_lua: Add the parsebody function for parsing POST data. PR 53064.
         [Daniel Gruno]
    
      *) apxs: Use LDFLAGS from config_vars.mk in addition to CFLAGS and CPPFLAGS.
         [Stefan Fritsch]
    
      *) mod_proxy: Fix memory leak or possible corruption in ProxyBlock
         implementation.  [Ruediger Pluem, Joe Orton]
    
      *) mod_proxy: Check hostname from request URI against ProxyBlock list,
         not forward proxy, if ProxyRemote* is configured.  [Joe Orton]
    
      *) mod_proxy_connect: Avoid DNS lookup on hostname from request URI
         if ProxyRemote* is configured.  PR 43697.  [Joe Orton]
    
      *) mpm_event, mpm_worker: Remain active amidst prevalent child process
         resource shortages.  [Jeff Trawick]
    
      *) Add "strict" and "warnings" pragmas to Perl scripts.  [Rich Bowen]
    
      *) The following now respect DefaultRuntimeDir/DEFAULT_REL_RUNTIMEDIR:
         - core: the scoreboard (ScoreBoardFile), pid file (PidFile), and
           mutexes (Mutex)
         [Jim Jagielski]
    
      *) ab: Fix bind() errors.  [Joe Orton]
    
      *) mpm_event: Don't do a blocking write when starting a lingering close
         from the listener thread. PR 52229. [Stefan Fritsch]
    
      *) mod_so: If a filename without slashes is specified for LoadFile or
         LoadModule and the file cannot be found in the server root directory,
         try to use the standard dlopen() search path. [Stefan Fritsch]
    
      *) mpm_event, mpm_worker: Fix cases where the spawn rate wasn't reduced
         after child process resource shortages.  [Jeff Trawick]
    
      *) mpm_prefork: Reduce spawn rate after a child process exits due to
         unexpected poll or accept failure.  [Jeff Trawick]
    
      *) core: Log value of Status header line in script responses rather
         than the fixed header name.  [Chris Darroch]
    
      *) mod_ssl: Fix handling of empty response from OCSP server.
         [Jim Meyering <meyering redhat.com>, Joe Orton]
    
      *) mpm_event: Fix handling of MaxConnectionsPerChild. [Stefan Fritsch]
    
      *) mod_authz_core: If an expression in "Require expr" returns denied and
         references %{REMOTE_USER}, trigger authentication and retry. PR 52892.
         [Stefan Fritsch]
    
      *) core: Always log if LimitRequestFieldSize triggers.  [Stefan Fritsch]
    
      *) mod_deflate: Skip compression if compression is enabled at SSL level.
         [Stefan Fritsch]
    
      *) core: Add missing HTTP status codes registered with IANA.
         [Julian Reschke <julian.reschke gmx.de>, Rainer Jung]
    
      *) mod_ldap: Treat the "server unavailable" condition as a transient
         error with all LDAP SDKs.  [Filip Valder <filip.valder vsb.cz>]
    
      *) core: Fix spurious "not allowed here" error returned when the Options
         directive is used in .htaccess and "AllowOverride Options" (with no
         specific options restricted) is configured.  PR 53444. [Eric Covener]
    
      *) mod_authz_core: Fix parsing of Require arguments in <AuthzProviderAlias>.
         PR 53048. [Stefan Fritsch]
    
      *) mod_log_config: Fix %{abc}C truncating cookie values at first "=".
         PR 53104. [Greg Ames]
    
      *) mod_ext_filter: Fix error_log spam when input filters are configured.
         [Joe Orton]
    
      *) mod_rewrite: Add "AllowAnyURI" option. PR 52774. [Joe Orton]
    
      *) htdbm, htpasswd: Don't crash if crypt() fails (e.g. with FIPS enabled).
         [Paul Wouters <pwouters redhat.com>, Joe Orton]
    
      *) core: Use a TLS 1.0 close_notify alert for internal dummy connection if
         the chosen listener is configured for https. [Joe Orton]
    
      *) mod_proxy: Use the the same hostname for SNI as for the HTTP request when
         forwarding to SSL backends. PR 53134.
         [Michael Weiser <michael weiser.dinsnail.net>, Ruediger Pluem]
    
      *) mod_info: Display all registered providers. [Stefan Fritsch]
    
      *) mod_ssl: Send the error message for speaking http to an https port using
         HTTP/1.0 instead of HTTP/0.9, and omit the link that may be wrong when
         using SNI. PR 50823. [Stefan Fritsch]
    
      *) core: Fix segfault in logging if r->useragent_addr or c->client_addr is
         unset. PR 53265. [Stefan Fritsch]
    
      *) log_server_status: Bring Perl style forward to the present, use
         standard modules, update for new format of server-status output.
         PR 45424. [Richard Bowen, Dave Brondsema, and others]
    
      *) mod_sed, mod_log_debug, mod_rewrite: Symbol namespace cleanups.
         [Joe Orton, André Malo]
    
      *) core: Prevent "httpd -k restart" from killing server in presence of
         config error. [Joe Orton]
    
      *) mod_proxy_fcgi: If there is an error reading the headers from the
         backend, send an error to the client. PR 52879. [Stefan Fritsch]
    
    Changes with Apache 2.4.2
    
      *) SECURITY: CVE-2012-0883 (cve.mitre.org)
         envvars: Fix insecure handling of LD_LIBRARY_PATH that could lead to the
         current working directory to be searched for DSOs. [Stefan Fritsch]
    
      *) mod_slotmem_shm: Honor DefaultRuntimeDir [Jim Jagielski]
    
      *) mod_ssl: Fix crash with threaded MPMs due to race condition when
         initializing EC temporary keys. [Stefan Fritsch]
    
      *) mod_rewrite: Fix RewriteCond integer checks to be parsed correctly.
         PR 53023. [Axel Reinhold <apache freakout.de>, André Malo]
    
      *) mod_proxy: Add the forcerecovery balancer parameter that determines if
         recovery for balancer workers is enforced. [Ruediger Pluem]
    
      *) Fix MPM DSO load failure on AIX.  [Jeff Trawick]
    
      *) mod_proxy: Correctly set up reverse proxy worker. PR 52935.
         [Petter Berntsen <petterb gmail.com>]
    
      *) mod_sed: Don't define PATH_MAX to a potentially undefined value, causing
         compile problems on GNU hurd. [Stefan Fritsch]
    
      *) core: Add ap_runtime_dir_relative() and DefaultRuntimeDir.
         [Jeff Trawick]
    
      *) core: Fix breakage of Listen directives with MPMs that use a
         per-directory config. PR 52904. [Stefan Fritsch]
    
      *) core: Disallow directives in AllowOverrideList which are only allowed
         in VirtualHost or server context. These are usually not prepared to be
         called in .htaccess files. [Stefan Fritsch]
    
      *) core: In AllowOverrideList, do not allow 'None' together with other
         directives. PR 52823. [Stefan Fritsch]
    
      *) mod_slotmem_shm: Support DEFAULT_REL_RUNTIMEDIR for file-based shm.
         [Jim Jagielski]
    
      *) core: Fix merging of AllowOverrideList and ContentDigest.
         [Stefan Fritsch]
    
      *) mod_request: Fix validation of the KeptBodySize argument so it
         doesn't always throw a configuration error. PR 52981 [Eric Covener]
    
      *) core: Add filesystem paths to access denied / access failed messages
         AH00035 and AH00036. [Eric Covener]
    
      *) mod_dumpio: Properly handle errors from subsequent input filters.
         PR 52914. [Stefan Fritsch]
    
      *) Unix MPMs: Fix small memory leak in parent process if connect()
         failed when waking up children.  [Joe Orton]
    
      *) "DirectoryIndex disabled" now undoes DirectoryIndex settings in
         the current configuration section, not just previous config sections.
         PR 52845. [Eric Covener]
    
      *) mod_xml2enc: Fix broken handling of EOS buckets which could lead to
         response headers not being sent. PR 52766. [Stefan Fritsch]
    
      *) mod_ssl: Properly free the GENERAL_NAMEs. PR 32652. [Kaspar Brand]
    
      *) core: Check during config test that directories for the access
         logs actually exist. PR 29941. [Stefan Fritsch]
    
      *) mod_xml2enc, mod_proxy_html: Enable per-module loglevels.
         [Stefan Fritsch]
    
      *) mod_filter: Fix segfault with AddOutputFilterByType. PR 52755.
         [Stefan Fritsch]
    
      *) mod_session: Sessions are encoded as application/x-www-form-urlencoded
         strings, however we do not handle the encoding of spaces properly.
         Fixed. [Graham Leggett]
    
      *) Configuration: Example in comment should use a path consistent
         with the default configuration. PR 52715.
         [Rich Bowen, Jens Schleusener, Rainer Jung]
    
      *) Configuration: Switch documentation links from trunk to 2.4.
         [Rainer Jung]
    
      *) configure: Fix out of tree build using apr and apr-util in srclib.
         [Rainer Jung]
    
    Changes with Apache 2.4.1
    
      *) SECURITY: CVE-2012-0053 (cve.mitre.org)
         Fix an issue in error responses that could expose "httpOnly" cookies
         when no custom ErrorDocument is specified for status code 400.
         [Eric Covener]
    
      *) mod_proxy_balancer: Fix crash on Windows. PR 52402 [Mladen Turk]
    
      *) core: Check during configtest that the directories for error logs exist.
         PR 29941 [Stefan Fritsch]
    
      *) Core configuration: add AllowOverride option to treat syntax
         errors in .htaccess as non-fatal. PR 52439 [Nick Kew, Jim Jagielski]
    
      *) core: Fix memory consumption in core output filter with streaming
         bucket types like CGI or PIPE.  [Joe Orton, Stefan Fritsch]
    
      *) configure: Disable modules at configure time if a prerequisite module
         is not enabled. PR 52487. [Stefan Fritsch]
    
      *) Rewrite and proxy now decline what they don't support rather
         than fail the request. [Joe Orton]
    
      *) Fix building against external apr plus apr-util if apr is not installed
         in a system default path. [Rainer Jung]
    
      *) Doxygen fixes and improvements. [Joe Orton, Igor Galić]
    
      *) core: Fix building against PCRE 8.30 by switching from the obsolete
         pcre_info() to pcre_fullinfo(). PR 52623 [Ruediger Pluem, Rainer Jung]
    
    Changes with Apache 2.4.0
    
      *) SECURITY: CVE-2012-0031 (cve.mitre.org)
         Fix scoreboard issue which could allow an unprivileged child process
         to cause the parent to crash at shutdown rather than terminate
         cleanly.  [Joe Orton]
    
      *) mod_ssl: Fix compilation with xlc on AIX. PR 52394. [Stefan Fritsch]
    
      *) SECURITY: CVE-2012-0021 (cve.mitre.org)
         mod_log_config: Fix segfault (crash) when the '%{cookiename}C' log format
         string is in use and a client sends a nameless, valueless cookie, causing
         a denial of service. The issue existed since version 2.2.17 and 2.3.3.
         PR 52256.  [Rainer Canavan <rainer-apache 7val com>]
    
      *) mod_ssl: when compiled against OpenSSL 1.0.1 or later, allow explicit
         control of TLSv1.1 and TLSv1.2 through the SSLProtocol directive.
         [Kaspar Brand]
    
      *) mod_ssl: set OPENSSL_NO_SSL_INTERN when compiling against OpenSSL 1.0.1
         or later, to improve binary compatibility with future OpenSSL releases.
         [Kaspar Brand]
    
      *) mod_mime: Don't arbitrarily bypass AddOutputFilter during a ProxyPass,
         but then allow AddOutputFilter during a RewriteRule [P]. Make mod_mime
         behave identically in both cases. PR52342. [Graham Leggett]
    
      *) Move ab, logresolve, httxt2dbm and apxs to bin from sbin, along with
         corresponding man pages. [Graham Leggett]
    
      *) Distinguish properly between the bindir and sbindir directories when
         installing binaries. Previously all binaries were silently installed to
         sbindir, whether they were system administration commands or not.
         [Graham Leggett]
    
    Changes with Apache 2.3.16
    
      *) SECURITY: CVE-2011-4317 (cve.mitre.org)
         Resolve additional cases of URL rewriting with ProxyPassMatch or
         RewriteRule, where particular request-URIs could result in undesired
         backend network exposure in some configurations.
         [Joe Orton]
    
      *) core: Limit line length in .htaccess to 8K like in 2.2.x, to avoid
         additional DoS potential. [Stefan Fritsch]
    
      *) core, all modules: Add unique tag to most error log messages. [Stefan
         Fritsch]
    
      *) mod_socache_memcache: Change provider name from "mc" to "memcache" to
         match module name. [Stefan Fritsch]
    
      *) mod_slotmem_shm: Change provider name from "shared" to "shm" to match
         module name. [Stefan Fritsch]
    
      *) mod_ldap: Fix segfault with Solaris LDAP when enabling ldaps. This
         requires an apr-util fix in which is available in apr-util >= 1.4.0.
         PR 42682. [Stefan Fritsch]
    
      *) mod_rewrite: Add the AllowNoSlash RewriteOption, which makes it possible
         for RewriteRules to be placed in .htaccess files that match the directory
         with no trailing slash. PR 48304.
         [Matthew Byng-Maddick <matthew byng-maddick bbc.co.uk>]
    
      *) mod_session_crypto: Add a SessionCryptoPassphraseFile directive so that
         the administrator can hide the keys from the configuration. [Graham
         Leggett]
    
      *) Introduce a per request version of the remote IP address, which can be
         optionally modified by a module when the effective IP of the client
         is not the same as the real IP of the client (such as a load balancer).
         Introduce a per connection "peer_ip" and a per request "client_ip" to
         distinguish between the raw IP address of the connection and the effective
         IP address of the request. [Graham Leggett]
    
      *) ap_pass_brigade_fchk() function added. [Jim Jagielski]
    
      *) core: Pass ap_errorlog_info struct to error log hook. [Stefan Fritsch]
    
      *) mod_cache_disk: Make sure we check return codes on all writes and
         attempts to close, and clean up after ourselves in these cases.
         PR43589. [Graham Leggett]
    
      *) mod_cache_disk: Remove the unnecessary intermediate brigade while
         writing to disk. Fixes a problem where mod_disk_cache was leaving
         buckets in the intermediate brigade and not passing them to out on
         exit. [Florian S. <f_los_ch yahoo.com>, Graham Leggett]
    
      *) mod_ssl: use a shorter setting for SSLCipherSuite in the default
         default configuration file, and add some more information about
         configuring a speed-optimized alternative.
         [Kaspar Brand]
    
      *) mod_ssl: drop support for the SSLv2 protocol. [Kaspar Brand]
    
      *) mod_lua: Stop losing track of all but the most specific LuaHook* directives
         when multiple per-directory config sections are used.  Adds LuaInherit
         directive to control how parent sections are merged.  [Eric Covener]
    
      *) Server directive display (-L): Include directives of DSOs.
         [Jeff Trawick]
    
      *) mod_cache: Make sure we merge headers correctly when we handle a
         non cacheable conditional response. PR52120. [Graham Leggett]
    
      *) Pre GA removal of components that will not be included:
         - mod_noloris was superseded by mod_reqtimeout
         - mod_serf
         - mpm_simple
         [Rainer Jung]
    
      *) core: Set MaxMemFree 2048 by default. [Stefan Fritsch]
    
      *) mpm_event: Fix assertion failure during very high load. [Stefan Fritsch]
    
      *) configure: Additional modules loaded by default: mod_headers.
         Modules moved from module set "few" to "most" and no longer loaded
         by default: mod_actions, mod_allowmethods, mod_auth_form, mod_buffer,
         mod_cgi(d), mod_include, mod_negotiation, mod_ratelimit, mod_request,
         mod_userdir. [Rainer Jung]
    
      *) mod_lua: Use the right lua scope when used as a hook. [Rainer Jung]
    
      *) configure: Only load the really imporant modules (i.e. those enabled by
         the 'few' selection) by default. Don't handle modules enabled with
         --enable-foo specially. [Stefan Fritsch]
    
      *) end-generation hook: Fix false notification of end-of-generation for
         temporary intervals with no active MPM children.  [Jeff Trawick]
    
      *) mod_ssl: Add support for configuring persistent TLS session ticket
         encryption/decryption keys (useful for clustered environments).
         [Paul Querna, Kaspar Brand]
    
      *) mod_usertrack: Use random value instead of remote IP address.
         [Stefan Fritsch]
    
    Changes with Apache 2.3.15
    
      *) SECURITY: CVE-2011-3348 (cve.mitre.org)
         mod_proxy_ajp: Respond with HTTP_NOT_IMPLEMENTED when the method is not
         recognized.  [Jean-Frederic Clere]
    
      *) SECURITY: CVE-2011-3192 (cve.mitre.org)
         core: Fix handling of byte-range requests to use less memory, to avoid
         denial of service. If the sum of all ranges in a request is larger than
         the original file, ignore the ranges and send the complete file.
         PR 51714. [Stefan Fritsch, Jim Jagielski, Ruediger Pluem, Eric Covener,
         <lowprio20 gmail.com>]
    
      *) SECURITY: CVE-2011-3607 (cve.mitre.org)
         core: Fix integer overflow in ap_pregsub. This can be triggered e.g.
         with mod_setenvif via a malicious .htaccess. [Stefan Fritsch]
    
      *) SECURITY: CVE-2011-3368 (cve.mitre.org)
         Reject requests where the request-URI does not match the HTTP
         specification, preventing unexpected expansion of target URLs in
         some reverse proxy configurations.  [Joe Orton]
    
      *) configure: Load all modules in the generated default configuration
         when using --enable-load-all-modules. [Rainer Jung]
    
      *) mod_reqtimeout: Change the default to set some reasonable timeout
         values. [Stefan Fritsch]
    
      *) core, mod_dav_fs: Change default ETag to be "size mtime", i.e. remove
         the inode. PR 49623. [Stefan Fritsch]
    
      *) mod_lua: Expose SSL variables via r:ssl_var_lookup().  [Eric Covener]
    
      *) mod_lua: LuaHook{AccessChecker,AuthChecker,CheckUserID,TranslateName}
         can now additionally be run as "early" or "late" relative to other modules.
         [Eric Covener]
    
      *) configure: By default, only load those modules that are either required
         or explicitly selected by a configure --enable-foo argument. The
         LoadModule statements for modules enabled by --enable-mods-shared=most
         and friends will be commented out. [Stefan Fritsch]
    
      *) mod_lua: Prevent early Lua hooks (LuaHookTranslateName and
         LuaHookQuickHandler) from being configured in <Directory>, <Files>,
         and htaccess where the configuration would have been ignored.
         [Eric Covener]
    
      *) mod_lua: Resolve "attempt to index local 'r' (a userdata value)" errors
         in LuaMapHandler scripts [Eric Covener]
    
      *) mod_log_debug: Rename optional argument from if= to expr=, to be more
         in line with other config directives. [Stefan Fritsch]
    
      *) mod_headers: Require an expression to be specified with expr=, to be more
         in line with other config directives. [Stefan Fritsch]
    
      *) mod_substitute: To prevent overboarding memory usage, limit line length
         to 1MB. [Stefan Fritsch]
    
      *) mod_lua: Make the query string (r.args) writable. [Eric Covener]
    
      *) mod_include: Add support for application/x-www-form-urlencoded encoding
         and decoding. [Graham Leggett]
    
      *) rotatelogs: Add -c option to force logfile creation in every rotation
         interval, even if empty.  [Jan Kaluža <jkaluza redhat.com>]
    
      *) core: Limit ap_pregsub() to 64K, add ap_pregsub_ex() for longer strings.
         [Stefan Fritsch]
    
      *) mod_session_crypto: Refactor to support the new apr_crypto API.
         [Graham Leggett]
    
      *) http: Add missing Location header if local URL-path is used as
         ErrorDocument for 30x. [Stefan Fritsch]
    
      *) mod_buffer: Make sure we step down for subrequests, but not for internal
         redirects triggered by mod_rewrite. [Graham Leggett]
    
      *) mod_lua: add r:construct_url as a wrapper for ap_construct_url.
         [Eric Covener]
    
      *) mod_remote_ip: Fix configuration of internal proxies. PR 49272.
         [Jim Riggs <jim riggs me>]
    
      *) mpm_winnt: Handle AcceptFilter 'none' mode correctly; resolve specific
         server IP endpoint and remote client IP upon connection.  [William Rowe]
    
      *) mod_setenvif: Remove OID match which is obsoleted by SetEnvIfExpr with
         PeerExtList(). [Stefan Fritsch]
    
      *) mpm_prefork, mpm_worker, mpm_event: If a child is created just before
         graceful restart and then exits because of a missing lock file, don't
         shutdown the whole server. PR 39311. [Shawn Michael
         <smichael rightnow com>]
    
      *) mpm_event: Check the return value from ap_run_create_connection.
         PR 41194. [Davi Arnaut]
    
      *) mod_mime_magic: Add signatures for PNG and SWF to the example config.
         PR 48352. [Jeremy Wagner-Kaiser <jwagner-kaiser adknowledge com>]
    
      *) core, unixd: Add -D DUMP_RUN_CFG option to dump some configuration items
         from the parsed (or default) config. This is useful for init scripts that
         need to setup temporary directories and permissions. [Stefan Fritsch]
    
      *) core, mod_actions, mod_asis: Downgrade error log messages which accompany
         a 404 request status from loglevel error to info. PR 35768. [Stefan
         Fritsch]
    
      *) core: Fix hook sorting with Perl modules. PR 45076. [Torsten Foertsch
         <torsten foertsch gmx net>]
    
      *) core: Enforce LimitRequestFieldSize after multiple headers with the same
         name have been merged. [Stefan Fritsch]
    
      *) mod_ssl: If MaxMemFree is set, ask OpenSSL >= 1.0.0 to reduce memory
         usage.  PR 51618. [Cristian Rodríguez <crrodriguez opensuse org>,
         Stefan Fritsch]
    
      *) mod_ssl: At startup, when checking a server certificate whether it
         matches the configured ServerName, also take dNSName entries in the
         subjectAltName extension into account. PR 32652, PR 47051. [Kaspar Brand]
    
      *) mod_substitute: Reduce memory usage and copying of data. PR 50559.
         [Stefan Fritsch]
    
      *) mod_ssl/proxy: enable the SNI extension for backend TLS connections
         [Kaspar Brand]
    
      *) Add wrappers for malloc, calloc, realloc that check for out of memory
         situations and use them in many places. PR 51568, PR 51569, PR 51571.
         [Stefan Fritsch]
    
      *) Fix cross-compilation of mod_cgi/mod_cgid when APR_HAVE_STRUCT_RLIMIT is
         false but RLIMIT_* are defined.  PR51371. [Eric Covener]
    
      *) core: Correctly obey ServerName / ServerAlias if the Host header from the
         request matches the VirtualHost address.
         PR 51709. [Micha Lenk <micha lenk.info>]
    
      *) mod_unique_id: Use random number generator to initialize counter.
         PR 45110. [Stefan Fritsch]
    
      *) core: Add convenience API for apr_random. [Stefan Fritsch]
    
      *) core: Add MaxRangeOverlaps and MaxRangeReversals directives to control
         the number of overlapping and reversing ranges (respectively) permitted
         before returning the entire resource, with a default limit of 20.
         [Jim Jagielski]
    
      *) mod_ldap: Optional function uldap_ssl_supported(r) always returned false
         if called from a virtual host with mod_ldap directives in it.  Did not
         affect mod_authnz_ldap's usage of mod_ldap.  [Eric Covener]
    
      *) mod_filter: Instead of dropping the Accept-Ranges header when a filter
         registered with AP_FILTER_PROTO_NO_BYTERANGE is present,
         set the header value to "none". [Eric Covener, Ruediger Pluem]
    
      *) core: Allow MaxRanges none|unlimited|default and set 'Accept-Ranges: none'
         in the case Ranges are being ignored with MaxRanges none.
         [Eric Covener]
    
      *) mod_ssl: revamp CRL-based revocation checking when validating
         certificates of clients or proxied servers. Completely delegate
         CRL processing to OpenSSL, and add a new [Proxy]CARevocationCheck
         directive for controlling the revocation checking mode. [Kaspar Brand]
    
      *) core: Add MaxRanges directive to control the number of ranges permitted
         before returning the entire resource, with a default limit of 200.
         [Eric Covener]
    
      *) mod_cache: Ensure that CacheDisable can correctly appear within
         a LocationMatch. [Graham Leggett]
    
      *) mod_cache: Fix the moving of the CACHE filter, which erroneously
         stood down if the original filter was not added by configuration.
         [Graham Leggett]
    
      *) mod_ssl: improve certificate error logging. PR 47408. [Kaspar Brand]
    
      *) mod_authz_groupfile: Increase length limit of lines in the group file to
         16MB. PR 43084. [Stefan Fritsch]
    
      *) core: Increase length limit of lines in the configuration file to 16MB.
         PR 45888. PR 50824. [Stefan Fritsch]
    
      *) core: Add API for resizable buffers. [Stefan Fritsch]
    
      *) mod_ldap: Enable LDAPConnectionTimeout for LDAP toolkits that have
         LDAP_OPT_CONNECT_TIMEOUT instead of LDAP_OPT_NETWORK_TIMEOUT, such
         as Tivoli Directory Server 6.3 and later. [Eric Covener]
    
      *) mod_ldap: Change default number of retries from 10 to 3, and add
         an LDAPRetries and LDAPRetryDelay directives. [Eric Covener]
    
      *) mod_authnz_ldap: Don't retry during authentication, because this just
         multiplies the ample retries already being done by mod_ldap. [Eric Covener]
    
      *) configure: Allow to explicitly disable modules even with module selection
         'reallyall'. [Stefan Fritsch]
    
      *) mod_rewrite: Check validity of each internal (int:) RewriteMap even if the
         RewriteEngine is disabled in server context, avoiding a crash while
         referencing the invalid int: map at runtime. PR 50994.
         [Ben Noordhuis <info noordhuis nl>]
    
      *) mod_ssl, configure: require OpenSSL 0.9.7 or later. [Kaspar Brand]
    
      *) mod_ssl: remove ssl_toolkit_compat layer. [Kaspar Brand]
    
      *) mod_ssl, configure, ab: drop support for RSA BSAFE SSL-C toolkit.
         [Kaspar Brand]
    
      *) mod_usertrack: Run mod_usertrack earlier in the fixups hook to ensure the
         cookie is set when modules such as mod_rewrite trigger a redirect. Also
         use r->err_headers_out for the cookie, for the same reason.  PR29755.
         [Sami J. Mäkinen <sjm almamedia fi>, Eric Covener]
    
      *) mod_proxy_http, mod_proxy_connect: Add 'proxy-status' and
         'proxy-source-port' request notes for logging. PR 30195. [Stefan Fritsch]
    
      *) configure: Enable ldap modules in 'all' and 'most' selections if ldap
         is compiled into apr-util. [Stefan Fritsch]
    
      *) core: Add ap_check_cmd_context()-check if a command is executed in
         .htaccess file. [Stefan Fritsch]
    
      *) mod_deflate: Fix endless loop if first bucket is metadata. PR 51590.
         [Torsten Foertsch <torsten foertsch gmx net>]
    
      *) mod_authn_socache: Fix to work in .htaccess if not configured anywhere
         in httpd.conf, and introduce an AuthnCacheEnable directive.
         PR 51991 [Nick Kew]
    
      *) mod_xml2enc: new (formerly third-party) module supporting
         internationalisation for filters via smart charset sniffing
         and conversion. [Nick Kew]
    
      *) mod_proxy_html: new (formerly third-party) module to fix up
         HTML links in a reverse proxy situation, where a backend
         generates URLs that are not resolvable by Clients. [Nick Kew]
    
    Changes with Apache 2.3.14
    
      *) mod_proxy_ajp: Improve trace logging.  [Rainer Jung]
    
      *) mod_proxy_ajp: Respect "reuse" flag in END_REPONSE packets.
         [Rainer Jung]
    
      *) mod_proxy: enable absolute URLs to be rewritten with ProxyPassReverse,
         e.g. to reverse proxy "Location: https://other-internal-server/login"
         [Nick Kew]
    
      *) prefork, worker, event: Make sure crashes are logged to the error log if
         httpd has already detached from the console. [Stefan Fritsch]
    
      *) prefork, worker, event: Reduce period during startup/restart where a
         successive signal may be lost. PR 43696. [Arun Bhalla <arun shme net>]
    
      *) mod_allowmethods: Correct Merging of "reset" and do not allow an
         empty parameter list for the AllowMethods directive. [Rainer Jung]
    
      *) configure: Update selection of modules for 'all' and 'most'. 'all' will
         now enable all modules except for example and test modules. Make the
         selection for 'most' more useful (including ssl and proxy). Both 'all'
         and 'most' will now disable modules if dependencies are missing instead
         of aborting. If a specific module is requested with --enable-XXX=yes,
         missing dependencies will still cause configure to exit with an error.
         [Stefan Fritsch]
    
      *) mod_ldap: Revert the integration of apr-ldap as ap_ldap which was done
         in 2.3.13. [Stefan Fritsch]
    
      *) core: For '*' or '_default_' vhosts, use a wildcard address of any
         address family, rather than IPv4 only.  [Joe Orton]
    
      *) core, mod_rewrite, mod_ssl, mod_nw_ssl: Make the SERVER_NAME variable
         include [ ] for literal IPv6 addresses, as mandated by RFC 3875.
         PR 26005. [Stefan Fritsch]
    
      *) mod_negotiation: Fix parsing of Content-Length in type maps. PR 42203.
         [Nagae Hidetake <nagae eagan jp>]
    
      *) core: Add more logging to ap_scan_script_header_err* functions. Add
         ap_scan_script_header_err*_ex functions that take a module index for
         logging.
         mod_cgi, mod_cgid, mod_proxy_fcgi, mod_proxy_scgi, mod_isapi: Use the
         new functions in order to make logging configurable per-module.
         [Stefan Fritsch]
    
      *) mod_dir: Add DirectoryIndexRedirect to send an external redirect to
         the proper index.  [Eric Covener]
    
      *) mod_deflate: Don't try to compress requests with a zero sized body.
         PR 51350. [Stefan Fritsch]
    
      *) core: Fix startup on IPv6-only systems. PR 50592. [Joe Orton,
         <root linkage white-void net>]
    
      *) suexec: Add environment variables CONTEXT_DOCUMENT_ROOT, CONTEXT_PREFIX,
         REDIRECT_ERROR_NOTES, REDIRECT_SCRIPT_FILENAME, REQUEST_SCHEME to the
         whitelist in suexec. PR 51499. [Graham Laverty <graham reg ca>,
         Stefan Fritsch]
    
      *) mod_rewrite: Fix regexp RewriteCond with NoCase. [Stefan Fritsch]
    
      *) mod_log_debug: New module that allows to log custom messages at various
         phases in the request processing. [Stefan Fritsch]
    
      *) mod_ssl: Add some debug logging when loading server certificates.
         PR 37912. [Nick Burch <nick burch alfresco com>]
    
      *) configure: Support reallyall option also for --enable-mods-static.
         [Rainer Jung]
    
      *) mod_socache_dc: add --with-distcache to configure for choosing
         the distcache installation directory. [Rainer Jung]
    
      *) mod_socache_dc: use correct build variable MOD_SOCACHE_DC_LDADD
         instead of MOD_SOCACHE_LDADD in build macro. [Rainer Jung]
    
      *) mod_lua, mod_deflate: respect platform specific runpath linker
         flag. [Rainer Jung]
    
      *) configure: Only link the httpd binary against PCRE. No other support
         binary needs PCRE. [Rainer Jung]
    
      *) configure: tolerate dependency checking failures for modules if
         they have been enabled implicitly. [Rainer Jung]
    
      *) configure: Allow to specify module specific custom linker flags via
         the MOD_XXX_LDADD variables. [Rainer Jung]
    
    Changes with Apache 2.3.13
    
      *) ab: Support specifying the local address to use. PR 48930.
         [Peter Schuller <scode spotify com>]
    
      *) core: Add support to ErrorLogFormat for logging the system unique
         thread id under Linux. [Stefan Fritsch]
    
      *) event: New AsyncRequestWorkerFactor directive to influence how many
         connections will be accepted per process. [Stefan Fritsch]
    
      *) prefork, worker, event: Rename MaxClients to MaxRequestWorkers which
         describes more accurately what it does. [Stefan Fritsch]
    
      *) rotatelogs: Add -p argument to specify custom program to invoke
         after a log rotation.  PR 51285. [Sven Ulland <sveniu ifi.uio.no>,
         Joe Orton]
    
      *) mod_ssl: Don't do OCSP checks for valid self-issued certs. [Kaspar Brand]
    
      *) mod_ssl: Avoid unnecessary renegotiations with SSLVerifyDepth 0.
         PR 48215. [Kaspar Brand]
    
      *) mod_status: Display information about asynchronous connections in the
         server-status. PR 44377. [Stefan Fritsch]
    
      *) mpm_event: If the number of connections of a process is very high, or if
         all workers are busy, don't accept new connections in that process.
         [Stefan Fritsch]
    
      *) mpm_event: Process lingering close asynchronously instead of tying up
         worker threads. [Jeff Trawick, Stefan Fritsch]
    
      *) mpm_event: If MaxMemFree is set, limit the number of pools that is kept
         around. [Stefan Fritsch]
    
      *) mpm_event: Fix graceful restart aborting connections. PR 43359.
         [Takashi Sato <takashi lans-tv com>]
    
      *) mod_ssl: Disable AECDH ciphers in example config. PR 51363.
         [Rob Stradling <rob comodo com>]
    
      *) core: Introduce new function ap_get_conn_socket() to access the socket of
         a connection. [Stefan Fritsch]
    
      *) mod_data: Introduce a filter to support RFC2397 data URLs. [Graham
         Leggett]
    
      *) mod_userdir/mod_alias/mod_vhost_alias: Correctly set DOCUMENT_ROOT,
         CONTEXT_DOCUMENT_ROOT, CONTEXT_PREFIX. PR 26052. PR 46198.
         [Stefan Fritsch]
    
      *) core: Allow to override document_root on a per-request basis. Introduce
         new context_document_root and context_prefix which provide information
         about non-global URI-to-directory mappings (from e.g. mod_userdir or
         mod_alias) to scripts. PR 49705. [Stefan Fritsch]
    
      *) core: Add <ElseIf> and <Else> to complement <If> sections.
         [Stefan Fritsch]
    
      *) mod_ext_filter: Remove DebugLevel option in favor of per-module loglevel.
         [Stefan Fritsch]
    
      *) mod_include: Make the "#if expr" element use the new "ap_expr" expression
         parser. The old parser can still be used by setting the new directive
         SSILegacyExprParser. [Stefan Fritsch]
    
      *) core: Add some features to ap_expr for use by mod_include: a restricted
         mode that does not allow to bypass request access restrictions; new
         variables DOCUMENT_URI (alias for REQUEST_URI), LAST_MODIFIED; -A as an
         alias for -U; an additional data entry in ap_expr_eval_ctx_t for use by
         the consumer; an extensible ap_expr_exec_ctx() API that allows to use that
         data entry. [Stefan Fritsch]
    
      *) mod_include: Merge directory configs instead of one SSI* config directive
         causing all other per-directory SSI* config directives to be reset.
         [Stefan Fritsch]
    
      *) mod_charset_lite: Remove DebugLevel option in favour of per-module
         loglevel. [Stefan Fritsch]
    
      *) core: Add ap_regexec_len() function that works with non-null-terminated
         strings. PR 51231. [Yehezkel Horowitz <horowity checkpoint com>]
    
      *) mod_authnz_ldap: If the LDAP server returns constraint violation,
         don't treat this as an error but as "auth denied". [Stefan Fritsch]
    
      *) mod_proxy_fcgi|scgi: Add support for "best guess" of PATH_INFO
         for SCGI/FCGI. PR 50880, 50851. [Mark Montague <mark catseye.org>,
         Jim Jagielski]
    
      *) mod_cache: When content is served stale, and there is no means to
         revalidate the content using ETag or Last-Modified, and we have
         mandated no stale-on-error behaviour, stand down and don't cache.
         Saves a cache write that will never be read.
         [Graham Leggett]
    
      *) mod_reqtimeout: Fix a timed out connection going into the keep-alive
         state after a timeout when discarding a request body. PR 51103.
         [Stefan Fritsch]
    
      *) core: Add various file existence test operators to ap_expr.
         [Stefan Fritsch]
    
      *) mod_proxy_express: New mass reverse-proxy switch extension for
         mod_proxy. [Jim Jagielski]
    
      *) configure: Fix script error when configuring module set "reallyall".
         [Rainer Jung]
    
    Changes with Apache 2.3.12
    
      *) configure, core: Provide easier support for APR's hook probe
         capability. [Jim Jagielski, Jeff Trawick]
    
      *) Silence autoconf 2.68 warnings.  [Rainer Jung]
    
      *) mod_authnz_ldap: Resolve crash when LDAP is used for authorization only
         [Scott Hill <shill genscape.com>]
    
      *) support: Make sure check_forensic works with mod_unique_id loaded
         [Joe Schaefer]
    
      *) Add child_status hook for tracking creation/termination of MPM child
         processes.  Add end_generation hook for notification when the last
         MPM child of a generation exits. [Jeff Trawick]
    
      *) mod_ldap: Make LDAPSharedCacheSize 0 create a non-shared-memory cache per
         process as opposed to disabling caching completely. This allows to use
         the non-shared-memory cache as a workaround for the shared memory cache
         not being available during graceful restarts. PR 48958. [Stefan Fritsch]
    
      *) Add new ap_reserve_module_slots/ap_reserve_module_slots_directive API,
         necessary if a module (like mod_perl) registers additional modules late
         in the startup phase. [Stefan Fritsch]
    
      *) core: Prevent segfault if DYNAMIC_MODULE_LIMIT is reached. PR 51072.
         [Torsten Förtsch <torsten foertsch gmx net>]
    
      *) WinNT MPM: Improve robustness under heavy load.  [Jeff Trawick]
    
      *) MinGW build improvements.  PR 49535.  [John Vandenberg
         <jayvdb gmail.com>, Jeff Trawick]
    
      *) core: Support module names with colons in loglevel configuration.
         [Torsten Förtsch <torsten foertsch gmx net>]
    
      *) mod_ssl, ab: Support OpenSSL compiled without SSLv2 support.
         [Stefan Fritsch]
    
      *) core: Abort if the MPM is changed across restart.  [Jeff Trawick]
    
      *) mod_proxy_ajp: Add support for 'ProxyErrorOverride on'. PR 50945.
         [Peter Pramberger <peter pramberger.at>, Jim Jagielski]
    
      *) mod_proxy_fcgi: Add support for 'ProxyErrorOverride on'. PR 50913.
         [Mark Montague <mark catseye.org>, Jim Jagielski]
    
      *) core: Change the APIs of ap_cfg_getline() and ap_cfg_getc() to return an
         error code. Abort with a nice error message if a config line is too long.
         Partial fix for PR 50824. [Stefan Fritsch]
    
      *) mod_info: Dump config to stdout during startup if -DDUMP_CONFIG is
         specified. PR 31956. [Stefan Fritsch]
    
      *) Restore visibility of DEFAULT_PIDLOG to core and modules.  MPM
         helper function ap_remove_pid() added.  [Jeff Trawick]
    
      *) Enable DEFAULT_REL_RUNTIMEDIR on Windows and NetWare.  [various]
    
      *) Correct C++ incompatibility with http_log.h.  [Stefan Fritsch, Jeff
         Trawick]
    
      *) mod_log_config: Prevent segfault. PR 50861. [Torsten Förtsch
         <torsten.foertsch gmx.net>]
    
      *) core: AllowEncodedSlashes new option NoDecode to allow encoded slashes
         in request URL path info but not decode them. Change behavior of option
         "On" to decode the encoded slashes as 2.0 and 2.2 do.  PR 35256,
         PR 46830.  [Dan Poirier]
    
      *) mod_ssl: Check SNI hostname against Host header case-insensitively.
         PR 49491.  [Mayank Agrawal <magrawal.08 gmail.com>]
    
      *) mod_ldap: Add LDAPConnectionPoolTTL to give control over lifetime
         of bound backend LDAP connections.  PR47634 [Eric Covener]
    
      *) mod_cache: Make CacheEnable and CacheDisable configurable per
         directory in addition to per server, making them work from within
         a LocationMatch. [Graham Leggett]
    
      *) worker, event, prefork: Correct several issues when built as
         DSOs; most notably, the scoreboard was reinitialized during graceful
         restart, such that processes of the previous generation were not
         observable.  [Jeff Trawick]
    
    Changes with Apache 2.3.11
    
      *) mod_win32: Added shebang check for '! so that .vbs scripts work as CGI.
         Win32's cscript interpreter can only use a single quote as comment char.
         [Guenter Knauf]
    
      *) mod_proxy: balancer-manager now uses POST instead of GET.
         [Jim Jagielski]
    
      *) core: new util function: ap_parse_form_data(). Previously,
         this capability was tucked away in mod_request. [Jim Jagielski]
    
      *) core: new hook: ap_run_pre_read_request. [Jim Jagielski]
    
      *) modules: Fix many modules that were not correctly initializing if they
         were not active during server startup but got enabled later during a
         graceful restart. [Stefan Fritsch]
    
      *) core: Create new ap_state_query function that allows modules to determine
         if the current configuration run is the initial one at server startup,
         and if the server is started for testing/config dumping only.
         [Stefan Fritsch]
    
      *) mod_proxy: Runtime configuration of many parameters for existing
         balancers via the balancer-manager. [Jim Jagielski]
    
      *) mod_proxy: Runtime addition of new workers (BalancerMember) for existing
         balancers via the balancer-manager. [Jim Jagielski]
    
      *) mod_cache: When a bad Expires date is present, we need to behave as if
         the Expires is in the past, not as if the Expires is missing. PR 16521.
         [Co-Advisor <coad measurement-factory.com>]
    
      *) mod_cache: We must ignore quoted-string values that appear in a
         Cache-Control header. PR 50199. [Graham Leggett]
    
      *) mod_dav: Revert change to send 501 error if unknown Content-* header is
        received for a PUT request. PR 42978. [Stefan Fritsch]
    
      *) mod_cache: Respect s-maxage as described by RFC2616 14.9.3, which must
         take precedence if present. PR 35247. [Graham Leggett]
    
      *) mod_ssl: Fix a possible startup failure if multiple SSL vhosts
         are configured with the same ServerName and private key file.
         [Masahiro Matsuya <mmatsuya redhat.com>, Joe Orton]
    
      *) mod_socache_dc: Make module compile by fixing some typos.
         PR 50735 [Mark Montague <mark catseye.org>]
    
      *) prefork: Update MPM state in children during a graceful stop or
         restart.  PR 41743.  [Andrew Punch <andrew.punch 247realmedia.com>]
    
      *) mod_mime: Ignore leading dots when looking for mime extensions.
         PR 50434 [Stefan Fritsch]
    
      *) core: Add support to set variables with the 'Define' directive. The
         variables that can then be used in the config using the ${VAR} syntax
         known from envvar interpolation. [Stefan Fritsch]
    
      *) mod_proxy_http: make adding of X-Forwarded-* headers configurable.
         ProxyAddHeaders defaults to On. [Vincent Deffontaines]
    
      *) mod_slotmem_shm: Increase memory alignment for slotmem data.
         [Rainer Jung]
    
      *) mod_ssl: Add config options for OCSP: SSLOCSPResponderTimeout,
         SSLOCSPResponseMaxAge, SSLOCSPResponseTimeSkew.
         [Kaspar Brand <httpd-dev.2011 velox.ch>]
    
      *) mod_ssl: Revamp output buffering to reduce network overhead for
         output fragmented into many buckets, such as chunked HTTP responses.
         [Joe Orton]
    
      *) core: Apply <If> sections to all requests, not only to file base requests.
         Allow to use <If> inside <Directory>, <Location>, and <Files> sections.
         The merging of <If> sections now happens after the merging of <Location>
         sections, even if an <If> section is embedded inside a <Directory> or
         <Files> section.  [Stefan Fritsch]
    
      *) mod_proxy: Refactor usage of shared data by dropping the scoreboard
         and using slotmem. Create foundation for dynamic growth/changes of
         members within a balancer. Remove BalancerNonce in favor of a
         per-balancer 'nonce' parameter. [Jim Jagielski]
    
      *) mod_status: Don't show slots which are disabled by MaxClients as open.
         PR 47022 [Jordi Prats <jordi prats gmail com>, Stefan Fritsch]
    
      *) mpm_prefork: Fix ap_mpm_query results for AP_MPMQ_MAX_DAEMONS and
         AP_MPMQ_MAX_THREADS.
    
      *) mod_authz_core: Fix bug in merging logic if user-based and non-user-based
         authorization directives were mixed. [Stefan Fritsch]
    
      *) mod_authn_socache: change directive name from AuthnCacheProvider
         to AuthnCacheProvideFor.  The term "provider" is overloaded in
         this module, and we should avoid confusion between the provider
         of a backend (AuthnCacheSOCache) and the authn provider(s) for
         which this module provides cacheing (AuthnCacheProvideFor).
         [Nick Kew]
    
      *) mod_proxy_http: Allocate the fake backend request from a child pool
         of the backend connection, instead of misusing the pool of the frontend
         request. Fixes a thread safety issue where buckets set aside in the
         backend connection leak into other threads, and then disappear when
         the frontend request is cleaned up, in turn causing corrupted buckets
         to make other threads spin. [Graham Leggett]
    
      *) mod_ssl: Change the format of the SSL_{CLIENT,SERVER}_{I,S}_DN variables
         to be RFC 2253 compatible, convert non-ASCII characters to UTF8, and
         escape other special characters with backslashes. The old format can
         still be used with the LegacyDNStringFormat argument to SSLOptions.
    
      *) core, mod_rewrite: Make the REQUEST_SCHEME variable available to
         scripts and mod_rewrite. [Stefan Fritsch]
    
      *) mod_rewrite: Allow to use arbitrary boolean expressions (ap_expr) in
         RewriteCond. [Stefan Fritsch]
    
      *) mod_rewrite: Allow to unset environment variables using E=!VAR.
         PR 49512. [Mark Drayton <mark markdrayton info>, Stefan Fritsch]
    
      *) mod_headers: Restore the 2.3.8 and earlier default for the first
         argument of the Header directive ("onsuccess").  [Eric Covener]
    
      *) core: Disallow the mixing of relative and absolute Options PR 33708.
         [Sönke Tesch <st kino-fahrplan.de>]
    
      *) core: When exporting request headers to HTTP_* environment variables,
         drop variables whose names contain invalid characters. Describe in the
         docs how to restore the old behaviour. [Malte S. Stretz <mss apache org>]
    
      *) core: When selecting an IP-based virtual host, favor an exact match for
         the port over a wildcard (or omitted) port instead of favoring the one
         that came first in the configuration file. [Eric Covener]
    
      *) core: Overlapping virtual host address/port combinations  now implicitly
         enable name-based virtual hosting for that address.  The NameVirtualHost
         directive has no effect, and _default_ is interpreted the same as "*".
         [Eric Covener]
    
      *) core: In the absence of any Options directives, the default is now
         "FollowSymlinks" instead of "All".  [Igor Galić]
    
      *) rotatelogs: Add -e option to write logs through to stdout for optional
         further processing. [Graham Leggett]
    
      *) mod_ssl: Correctly read full lines in input filter when the line is
         incomplete during first read. PR 50481. [Ruediger Pluem]
    
      *) mod_authz_core: Add AuthzSendForbiddenOnFailure directive to allow
         sending '403 FORBIDDEN' instead of '401 UNAUTHORIZED' if authorization
         fails for an authenticated user. PR 40721. [Stefan Fritsch]
    
    Changes with Apache 2.3.10
    
      *) mod_rewrite: Don't implicitly URL-escape the original query string
         when no substitution has changed it. PR 50447. [Eric Covener]
    
      *) core: Honor 'AcceptPathInfo OFF' during internal redirects,
         such as per-directory mod_rewrite substitutions.  PR 50349.
         [Eric Covener]
    
      *) mod_rewrite: Add 'RewriteOptions InheritBefore' to put the base
         rules/conditions before the overridden rules/conditions.  PR 39313.
         [Jérôme Grandjanny <jerome.grandjanny cea.fr>]
    
      *) mod_autoindex: add IndexIgnoreReset to reset the list of IndexIgnored
         filenames in higher precedence configuration sections.  PR 24243.
         [Eric Covener]
    
      *) mod_cgid: RLimit* directive support for mod_cgid.  PR 42135
         [Eric Covener]
    
      *) core: Fail startup when the argument to ServerName looks like a glob
         or a regular expression instead of a hostname (*?[]).  PR 39863
         [Rahul Nair <rahul.g.nair gmail.com>]
    
      *) mod_userdir: Add merging of enable, disable, and filename arguments
         to UserDir directive, leaving enable/disable of userlists unmerged.
         PR 44076 [Eric Covener]
    
      *) httpd: When no -k option is provided on the httpd command line, the server
         was starting without checking for an existing pidfile.  PR 50350
         [Eric Covener]
    
      *) mod_proxy: Put the worker in error state if the SSL handshake with the
         backend fails. PR 50332.
         [Daniel Ruggeri <DRuggeri primary.net>, Ruediger Pluem]
    
      *) mod_cache_disk: Fix Windows build which was broken after renaming
         the module. [Gregg L. Smith]
    
    Changes with Apache 2.3.9
    
      *) SECURITY: CVE-2010-1623 (cve.mitre.org)
         Fix a denial of service attack against mod_reqtimeout.
         [Stefan Fritsch]
    
      *) mod_headers: Change default first argument of Header directive
         from "onsuccess" to "always". [Eric Covener]
    
      *) mod_include: Add the onerror attribute to the include element,
         allowing an URL to be specified to include on error. [Graham
         Leggett]
    
      *) mod_cache_disk: mod_disk_cache renamed to mod_cache_disk, to be
         consistent with the naming of other modules. [Graham Leggett]
    
      *) mod_setenvif: Add SetEnvIfExpr directive to set env var depending on
         expression. [Stefan Fritsch]
    
      *) mod_proxy: Fix ProxyPassInterpolateEnv directive. PR 50292.
         [Stefan Fritsch]
    
      *) suEXEC: Add Suexec directive to disable suEXEC without renaming the
         binary (Suexec Off), or force startup failure if suEXEC is required
         but not supported (Suexec On).  Change SuexecUserGroup to fail
         startup instead of just printing a warning if suEXEC is disabled.
         [Jeff Trawick]
    
      *) core: Add Error directive for aborting startup or htaccess processing
         with a specified error message.  [Jeff Trawick]
    
      *) mod_rewrite: Fix the RewriteEngine directive to work within a
         location. Previously, once RewriteEngine was switched on globally,
         it was impossible to switch off. [Graham Leggett]
    
      *) core, mod_include, mod_ssl: Move the expression parser derived from
         mod_include back into mod_include. Replace ap_expr with a parser
         derived from mod_ssl's parser. Make mod_ssl use the new parser. Rework
         ap_expr's public interface and provide hooks for modules to add variables
         and functions. [Stefan Fritsch]
    
      *) core: Do the hook sorting earlier so that the hooks are properly sorted
         for the pre_config hook and during parsing the config. [Stefan Fritsch]
    
      *) core: In the absence of any AllowOverride directives, the default is now
         "None" instead of "All".  PR49823 [Eric Covener]
    
      *) mod_proxy: Don't allow ProxyPass or ProxyPassReverse in
         <Directory> or <Files>. PR47765 [Eric Covener]
    
      *) prefork/worker/event MPMS: default value (when no directive is present)
         of MaxConnectionsPerChild/MaxRequestsPerChild is changed to 0 from 10000
         to match default configuration and manual. PR47782 [Eric Covener]
    
      *) proxy_connect: Don't give up in the middle of a CONNECT tunnel
         when the child process is starting to exit.  PR50220. [Eric Covener]
    
      *) mod_autoindex: Fix inheritance of mod_autoindex directives into
         contexts that don't have any mod_autoindex directives. PR47766.
         [Eric Covener]
    
      *) mod_rewrite: Add END flag for RewriteRule to prevent further rounds
         of rewrite processing when a per-directory substitution occurs.
         [Eric Covener]
    
      *) mod_ssl: Make sure to always log an error if loading of CA certificates
         fails. PR 40312. [Paul Tiemann <issues apache org ourdetour com>]
    
      *) mod_dav: Send 501 error if unknown Content-* header is received for a PUT
         request (RFC 2616 9.6). PR 42978. [Stefan Fritsch]
    
      *) mod_dav: Send 400 error if malformed Content-Range header is received for
         a put request (RFC 2616 14.16). PR 49825. [Stefan Fritsch]
    
      *) mod_proxy: Release the backend connection as soon as EOS is detected,
         so the backend isn't forced to wait for the client to eventually
         acknowledge the data. [Graham Leggett]
    
      *) mod_proxy: Optimise ProxyPass within a Location so that it is stored
         per-directory, and chosen during the location walk. Make ProxyPass
         work correctly from within a LocationMatch. [Graham Leggett]
    
      *) core: Fix segfault if per-module LogLevel is on virtual host
         scope. PR 50117. [Stefan Fritsch]
    
      *) mod_proxy: Move the ProxyErrorOverride directive to have per
         directory scope. [Graham Leggett]
    
      *) mod_allowmethods: New module to deny certain HTTP methods without
         interfering with authentication/authorization. [Paul Querna,
         Igor Galić, Stefan Fritsch]
    
      *) mod_ssl: Log certificate information and improve error message if client
         cert verification fails. PR 50093, PR 50094. [Lassi Tuura <lat cern ch>,
         Stefan Fritsch]
    
      *) htcacheclean: Teach htcacheclean to limit cache size by number of
         inodes in addition to size of files. Prevents a cache disk from
         running out of space when many small files are cached.
         [Graham Leggett]
    
      *) core: Rename MaxRequestsPerChild to MaxConnectionsPerChild, which
         describes more accurately what the directive does. The old name
         still works but logs a warning. [Stefan Fritsch]
    
      *) mod_cache: Optionally serve stale data when a revalidation returns a
         5xx response, controlled by the CacheStaleOnError directive.
         [Graham Leggett]
    
      *) htcacheclean: Allow the listing of valid URLs within the cache, with
         the option to list entry metadata such as sizes and times. [Graham
         Leggett]
    
      *) mod_cache: correctly parse quoted strings in cache headers.
         PR 50199 [Nick Kew]
    
      *) mod_cache: Allow control over the base URL of reverse proxied requests
         using the CacheKeyBaseURL directive, so that the cache key can be
         calculated from the endpoint URL instead of the server URL. [Graham
         Leggett]
    
      *) mod_cache: CacheLastModifiedFactor, CacheStoreNoStore, CacheStorePrivate,
         CacheStoreExpired, CacheIgnoreNoLastMod, CacheDefaultExpire,
         CacheMinExpire and CacheMaxExpire can be set per directory/location.
         [Graham Leggett]
    
      *) mod_disk_cache: CacheMaxFileSize, CacheMinFileSize, CacheReadSize and
         CacheReadTime can be set per directory/location. [Graham Leggett]
    
      *) core: Speed up config parsing if using a very large number of config
         files. PR 50002 [andrew cloudaccess net]
    
      *) mod_cache: Support the caching of HEAD requests. [Graham Leggett]
    
      *) htcacheclean: Allow the option to round up file sizes to a given
         block size, improving the accuracy of disk usage. [Graham Leggett]
    
      *) mod_ssl: Add authz providers for use with mod_authz_core and its
         RequireAny/RequireAll containers: 'ssl' (equivalent to SSLRequireSSL),
         'ssl-verify-client' (for use with 'SSLVerifyClient optional'), and
         'ssl-require' (expressions with same syntax as SSLRequire).
         [Stefan Fritsch]
    
      *) mod_ssl: Make the ssl expression parser thread-safe. It now requires
         bison instead of yacc. [Stefan Fritsch]
    
      *) mod_disk_cache: Change on-disk header file format to support the
         link of the device/inode of the data file to the matching header
         file, and to support the option of not writing a data file when
         the data file is empty. [Graham Leggett]
    
      *) core/mod_unique_id: Add generate_log_id hook to allow to use
         the ID generated by mod_unique_id as error log ID for requests.
         [Stefan Fritsch]
    
      *) mod_cache: Make sure that we never allow a 304 Not Modified response
         that we asked for to leak to the client should the 304 response be
         uncacheable. PR45341 [Graham Leggett]
    
      *) mod_cache: Add the cache_status hook to register the final cache
         decision hit/miss/revalidate. Add optional support for an X-Cache
         and/or an X-Cache-Detail header to add the cache status to the
         response. PR48241 [Graham Leggett]
    
      *) mod_authz_host: Add 'local' provider that matches connections originating
         on the local host. PR 19938. [Stefan Fritsch]
    
      *) Event MPM: Fix crash accessing pollset on worker thread when child
         process is exiting.  [Jeff Trawick]
    
      *) core: For process invocation (cgi, fcgid, piped loggers and so forth)
         pass the system library path (LD_LIBRARY_PATH or platform-specific
         variables) along with the system PATH, by default.  Both should be
         overridden together as desired using PassEnv etc; see mod_env.
         [William Rowe]
    
      *) mod_cache: Introduce CacheStoreExpired, to allow administrators to
         capture a stale backend response, perform If-Modified-Since requests
         against the backend, and serving from the cache all 304 responses.
         This restores pre-2.2.4 cache behavior.  [William Rowe]
    
      *) mod_rewrite: Introduce <=, >= string comparison operators, and integer
         comparators -lt, -le, -eq, -ge, and -gt.  To help bash users and drop
         the ambiguity of the symlink test "-ltest", introduce -h or -L as
         symlink test operators.  [William Rowe]
    
      *) mod_cache: Give the cache provider the opportunity to choose to cache
         or not cache based on the buckets present in the brigade, such as the
         presence of a FILE bucket.
         [Graham Leggett]
    
      *) mod_authz_core: Allow authz providers to check args while reading the
         config and allow to cache parsed args. Move 'all' and 'env' authz
         providers from mod_authz_host to mod_authz_core. Add 'method' authz
         provider depending on the HTTP method.  [Stefan Fritsch]
    
      *) mod_include: Move the request_rec within mod_include to be
         exposed within include_ctx_t. [Graham Leggett]
    
      *) mod_include: Reinstate support for UTF-8 character sets by allowing a
         variable being echoed or set to be decoded and then encoded as separate
         steps. PR47686 [Graham Leggett]
    
      *) mod_cache: Add a discrete commit_entity() provider function within the
         mod_cache provider interface which is called to indicate to the
         provider that caching is complete, giving the provider the opportunity
         to commit temporary files permanently to the cache in an atomic
         fashion. Replace the inconsistent use of error cleanups with a formal
         set of pool cleanups attached to a subpool, which is destroyed on error.
         [Graham Leggett]
    
      *) mod_cache: Change the signature of the store_body() provider function
         within the mod_cache provider interface to support an "in" brigade
         and an "out" brigade instead of just a single input brigade. This
         gives a cache provider the option to consume only part of the brigade
         passed to it, rather than the whole brigade as was required before.
         This fixes an out of memory and a request timeout condition that would
         occur when the original document was a large file. Introduce
         CacheReadSize and CacheReadTime directives to mod_disk_cache to control
         the amount of data to attempt to cache at a time. [Graham Leggett]
    
      *) core: Add ErrorLogFormat to allow configuring error log format, including
         additional information that is logged once per connection or request. Add
         error log IDs for connections and request to allow correlating error log
         lines and the corresponding access log entry. [Stefan Fritsch]
    
      *) core: Disable sendfile by default. [Stefan Fritsch]
    
      *) mod_cache: Check the request to determine whether we are allowed
         to return cached content at all, and respect a "Cache-Control:
         no-cache" header from a client. Previously, "no-cache" would
         behave like "max-age=0". [Graham Leggett]
    
      *) mod_cache: Use a proper filter context to hold filter data instead
         of misusing the per-request configuration. Fixes a segfault on trunk
         when the normal handler is used. [Graham Leggett]
    
      *) mod_cgid: Log a warning if the ScriptSock path is truncated because
         it is too long. PR 49388.  [Stefan Fritsch]
    
      *) vhosts: Do not allow _default_ in NameVirtualHost, or mixing *
         and non-* ports on NameVirtualHost, or multiple NameVirtualHost
         directives for the same address:port, or NameVirtualHost
         directives with no matching VirtualHosts, or multiple ip-based
         VirtualHost sections for the same address:port.  These were
         previously accepted with a warning, but the behavior was
         undefined.  [Dan Poirier]
    
      *) mod_remoteip: Fix a segfault when using mod_remoteip in conjunction with
         Allow/Deny. PR 49838.  [Andrew Skalski <voltara gmail.com>]
    
      *) core: DirectoryMatch can now match on the end of line character ($),
         and sub-directories of matched directories are no longer implicitly
         matched.  PR49809 [Eric Covener]
    
      *) Regexps: introduce new higher-level regexp utility including parsing
         and executing perl-style regexp ops (e.g s/foo/bar/i) and regexp memory
         [Nick Kew]
    
      *) Proxy: support setting source address.  PR 29404
         [Multiple contributors iterating through bugzilla,
          Aron Ujvari <xanco nikhok.hu>, Aleksey Midenkov <asm uezku.kemsu.ru>,
          <dan listening-station.net; trunk version Nick Kew]
    
      *) HTTP protocol: return 400 not 503 if we have to abort due to malformed
         chunked encoding. [Nick Kew]
    
    Changes with Apache 2.3.8
    
      *) suexec: Support large log files. PR 45856. [Stefan Fritsch]
    
      *) core: Abort with sensible error message if no or more than one MPM is
         loaded. [Stefan Fritsch]
    
      *) mod_proxy: Rename erroronstatus to failonstatus.
         [Daniel Ruggeri <DRuggeri primary.net>]
    
      *) mod_dav_fs: Fix broken "creationdate" property.
         Regression in version 2.3.7. [Rainer Jung]
    
    Changes with Apache 2.3.7
    
      *) SECURITY: CVE-2010-1452 (cve.mitre.org)
         mod_dav, mod_cache, mod_session: Fix Handling of requests without a path
         segment. PR 49246 [Mark Drayton, Jeff Trawick]
    
      *) mod_ldap: Properly check the result returned by apr_ldap_init. PR 46076.
         [Stefan Fritsch]
    
      *) mod_rewrite: Log errors if rewrite map files cannot be opened. PR 49639.
         [Stefan Fritsch]
    
      *) mod_proxy_http: Support the 'ping' property for backend HTTP/1.1 servers
         via leveraging 100-Continue as the initial "request".
         [Jim Jagielski]
    
      *) core/mod_authz_core: Introduce new access_checker_ex hook that enables
         mod_authz_core to bypass authentication if access should be allowed by
         IP address/env var/... [Stefan Fritsch]
    
      *) core: Introduce note_auth_failure hook to allow modules to add support
         for additional auth types. This makes ap_note_auth_failure() work with
         mod_auth_digest again. PR 48807. [Stefan Fritsch]
    
      *) socache modules: return APR_NOTFOUND when a lookup is not found [Nick Kew]
    
      *) mod_authn_socache: new module [Nick Kew]
    
      *) configure: Add reallyall option for --enable-mods-shared. [Stefan Fritsch]
    
      *) Fix Windows build when using VC6. [Gregg L. Smith <lists glewis com>]
    
      *) mod_rewrite: Allow to set environment variables without explicitly
         giving a value. [Rainer Jung]
    
      *) mod_rewrite: Remove superfluous EOL from rewrite logging. [Rainer Jung]
    
      *) mod_include: recognise "text/html; parameters" as text/html
         PR 49616 [Andrey Chernov <ache nagual.pp.ru>]
    
      *) CGI vars: allow PATH to be set by SetEnv, consistent with LD_LIBRARY_PATH
         PR 43906 [Nick Kew]
    
      *) Core: Extra robustness: don't try authz and segfault if authn
         fails to set r->user.  Log bug and return 500 instead.
         PR 42995 [Nick Kew]
    
      *) HTTP protocol filter: fix handling of longer chunk extensions
         PR 49474 [<tee.bee gmx.de>]
    
      *) Update SSL cipher suite and add example for SSLHonorCipherOrder.
         [Lars Eilebrecht, Rainer Jung]
    
      *) move AddOutputFilterByType from core to mod_filter.  This should
         fix nasty side-effects that happen when content_type is set
         more than once in processing a request, and make it fully
         compatible with dynamic and proxied contents. [Nick Kew]
    
      *) mod_log_config: Implement logging for sub second timestamps and
         request end time.  [Rainer Jung]
    
    Changes with Apache 2.3.6
    
      *) SECURITY: CVE-2009-3555 (cve.mitre.org)
         mod_ssl: Comprehensive fix of the TLS renegotiation prefix injection
         attack when compiled against OpenSSL version 0.9.8m or later. Introduces
         the 'SSLInsecureRenegotiation' directive to reopen this vulnerability
         and offer unsafe legacy renegotiation with clients which do not yet
         support the new secure renegotiation protocol, RFC 5746.
         [Joe Orton, and with thanks to the OpenSSL Team]
    
      *) SECURITY: CVE-2009-3555 (cve.mitre.org)
         mod_ssl: A partial fix for the TLS renegotiation prefix injection attack
         by rejecting any client-initiated renegotiations. Forcibly disable
         keepalive for the connection if there is any buffered data readable. Any
         configuration which requires renegotiation for per-directory/location
         access control is still vulnerable, unless using OpenSSL >= 0.9.8l.
         [Joe Orton, Ruediger Pluem, Hartmut Keil <Hartmut.Keil adnovum.ch>]
    
      *) SECURITY: CVE-2010-0408 (cve.mitre.org)
         mod_proxy_ajp: Respond with HTTP_BAD_REQUEST when the body is not sent
         when request headers indicate a request body is incoming; not a case of
         HTTP_INTERNAL_SERVER_ERROR.  [Niku Toivola <niku.toivola sulake.com>]
    
      *) SECURITY: CVE-2010-0425 (cve.mitre.org)
         mod_isapi: Do not unload an isapi .dll module until the request
         processing is completed, avoiding orphaned callback pointers.
         [Brett Gervasoni <brettg senseofsecurity.com>, Jeff Trawick]
    
      *) core: Filter init functions are now run strictly once per request
         before handler invocation.  The init functions are no longer run
         for connection filters.  PR 49328.  [Joe Orton]
    
      *) core: Adjust the output filter chain correctly in an internal
         redirect from a subrequest, preserving filters from the main
         request as necessary.  PR 17629.  [Joe Orton]
    
      *) mod_cache: Explicitly allow cache implementations to cache a 206 Partial
         Response if they so choose to do so. Previously an attempt to cache a 206
         was arbitrarily allowed if the response contained an Expires or
         Cache-Control header, and arbitrarily denied if both headers were missing.
         [Graham Leggett]
    
      *) core: Add microsecond timestamp fractions, process id and thread id
         to the error log. [Rainer Jung]
    
      *) configure: The "most" module set gets build by default.  [Rainer Jung]
    
      *) configure: Building dynamic modules (DSO) by default.  [Rainer Jung]
    
      *) configure: Fix broken VPATH build when using included APR.
         [Rainer Jung]
    
      *) mod_session_crypto: Fix configure problem when building
         with APR 2 and for VPATH builds with included APR.
         [Rainer Jung]
    
      *) mod_session_crypto: API compatibility with APR 2 crypto and
         APR Util 1.x crypto. [Rainer Jung]
    
      *) ab: Fix memory leak with -v2 and SSL. PR 49383.
         [Pavel Kankovsky <peak argo troja mff cuni cz>]
    
      *) core: Add per-module and per-directory loglevel configuration.
               Add some more trace logging.
         mod_rewrite: Replace RewriteLog/RewriteLogLevel with trace log levels.
         mod_ssl: Replace LogLevelDebugDump with trace log levels.
         mod_ssl/mod_proxy*: Adjust loglevels to be less verbose at levels info
               and debug.
         mod_dumpio:  Replace DumpIOLogLevel with trace log levels.
         [Stefan Fritsch]
    
      *) mod_ldap: LDAP caching was suppressed (and ldap-status handler returns
         title page only) when any mod_ldap directives were used in VirtualHost
         context.  [Eric Covener]
    
      *) mod_disk_cache: Decline the opportunity to cache if the response is
         a 206 Partial Content. This stops a reverse proxied partial response
         from becoming cached, and then being served in subsequent responses.
         [Graham Leggett]
    
      *) mod_deflate: avoid the risk of forwarding data before headers are set.
         PR 49369 [Matthew Steele <mdsteele google.com>]
    
      *) mod_authnz_ldap: Ensure nested groups are checked when the
         top-level group doesn't have any direct non-group members
         of attributes in AuthLDAPGroupAttribute. [Eric Covener]
    
      *) mod_authnz_ldap: Search or Comparison during authorization phase
         can use the credentials from the authentication phase
         (AuthLDAPSearchAsUSer,AuthLDAPCompareAsUser).
         PR 48340 [Domenico Rotiroti, Eric Covener]
    
      *) mod_authnz_ldap: Allow the initial DN search during authentication
         to use the HTTP username/pass instead of an anonymous or hard-coded
         LDAP id (AuthLDAPInitialBindAsUser, AuthLDAPInitialBindPattern).
         [Eric Covener]
    
      *) mod_authnz_ldap: Publish requested LDAP data with an AUTHORIZE_ prefix
         when this module is used for authorization. See AuthLDAPAuthorizePrefix.
         PR 45584 [Eric Covener]
    
      *) apxs -q: Stop filtering out ':' characters from the reported values.
         PR 45343.  [Bill Cole]
    
      *) prefork MPM: Work around possible crashes on child exit in APR reslist
         cleanup code.  PR 43857.  [Tom Donovan]
    
      *) ab: fix number of requests sent by ab when keepalive is enabled.  PR 48497.
         [Bryn Dole <dole blekko.com>]
    
      *) Log an error for failures to read a chunk-size, and return 408 instead of
         413 when this is due to a read timeout.  This change also fixes some cases
         of two error documents being sent in the response for the same scenario.
         [Eric Covener] PR49167
    
      *) mod_proxy_balancer: Add new directive BalancerNonce to allow admin
         to control/set the nonce used in the balancer-manager application.
         [Jim Jagielski]
    
      *) mod_proxy_connect: Support port ranges in AllowConnect. PR 23673.
         [Stefan Fritsch]
    
      *) Proxy balancer: support setting error status according to HTTP response
         code from a backend.  PR 48939.  [Daniel Ruggeri <DRuggeri primary.net>]
    
      *) htcacheclean: Introduce the ability to clean specific URLs from the
         cache, if provided as an optional parameter on the command line.
         [Graham Leggett]
    
      *) core: Introduce the IncludeStrict directive, which explicitly fails
         server startup if no files or directories match a wildcard path.
         [Graham Leggett]
    
      *) htcacheclean: Report additional statistics about entries deleted.
         PR 48944. [Mark Drayton mark markdrayton.info]
    
      *) Introduce SSLFIPS directive to support OpenSSL FIPS_mode; permits all
         builds of mod_ssl to use 'SSLFIPS off' for portability, but the proper
         build of openssl is required for 'SSLFIPS on'.  PR 46270.
         [Dr Stephen Henson <steve openssl.org>, William Rowe]
    
      *) mod_proxy_http: Log the port of the remote server in various messages.
         PR 48812. [Igor Galić <i galic brainsware org>]
    
      *) mod_reqtimeout: Do not wrongly enforce timeouts for mod_proxy's backend
         connections and other protocol handlers (like mod_ftp). [Stefan Fritsch]
    
      *) mod_proxy_ajp: Really regard the operation a success, when the client
         aborted the connection. In addition adjust the log message if the client
         aborted the connection. [Ruediger Pluem]
    
      *) mod_ssl: Add the 'SSLInsecureRenegotiation' directive, which
         allows insecure renegotiation with clients which do not yet
         support the secure renegotiation protocol.  [Joe Orton]
    
      *) mod_ssl: Fix a potential I/O hang if a long list of trusted CAs
         is configured for client cert auth. PR 46952.  [Joe Orton]
    
      *) core: Only log a 408 if it is no keepalive timeout. PR 39785
         [Ruediger Pluem,  Mark Montague <markmont umich.edu>]
    
      *) support/rotatelogs: Add -L option to create a link to the current
         log file.  PR 48761 [<lyndon orthanc.ca>, Dan Poirier]
    
      *) mod_ldap: Update LDAPTrustedClientCert to consistently be a per-directory
         setting only, matching most of the documentation and examples.
         PR 46541 [Paul Reder, Eric Covener]
    
      *) mod_ldap: LDAPTrustedClientCert now accepts CA_DER/CA_BASE64 argument
         types previously allowed only in LDAPTrustedGlobalCert. [Eric Covener]
    
      *) mod_negotiation: Preserve query string over multiviews negotiation.
         This buglet was fixed for type maps in 2.2.6, but the same issue
         affected multiviews and was overlooked.
         PR 33112 [Joergen Thomsen <apache jth.net>]
    
      *) mod_ldap: Eliminate a potential crash with multiple LDAPTrustedClientCert
         when some are not password-protected. [Eric Covener]
    
      *) Fix startup segfault when the Mutex directive is used but no loaded
         modules use httpd mutexes.  PR 48787.  [Jeff Trawick]
    
      *) Proxy: get the headers right in a HEAD request with
         ProxyErrorOverride, by checking for an overridden error
         before not after going into a catch-all code path.
         PR 41646.  [Nick Kew, Stuart Children]
    
      *) support/rotatelogs: Support the simplest log rotation case, log
         truncation. Useful when the log is being processed in real time
         using a command like tail. [Graham Leggett]
    
      *) support/htcacheclean: Teach it how to write a pid file (modelled on
         httpd's writing of a pid file) so that it becomes possible to run
         more than one instance of htcacheclean on the same machine.
         [Graham Leggett]
    
      *) Log command line on startup, so there's a record of command line
         arguments like -f.  PR 48752.  [Dan Poirier]
    
      *) Introduce mod_reflector, a handler capable of reflecting POSTed
         request bodies back within the response through the output filter
         stack. Can be used to turn an output filter into a web service.
         [Graham Leggett]
    
      *) mod_proxy_http: Make sure that when an ErrorDocument is served
         from a reverse proxied URL, that the subrequest respects the status
         of the original request. This brings the behaviour of proxy_handler
         in line with default_handler. PR 47106. [Graham Leggett]
    
      *) Support wildcards in both the directory and file components of
         the path specified by the Include directive. [Graham Leggett]
    
      *) mod_proxy, mod_proxy_http: Support remote https proxies
         by using HTTP CONNECT.  PR 19188.
         [Philippe Dutrueux <lilas evidian.com>, Rainer Jung]
    
      *) apxs: Fix -A and -a options to ignore whitespace in httpd.conf
         [Philip M. Gollucci]
    
      *) worker: Don't report server has reached MaxClients until it has.
         Add message when server gets within MinSpareThreads of MaxClients.
         PR 46996.  [Dan Poirier]
    
      *) mod_session: Session expiry was being initialised, but not updated
         on each session save, resulting in timed out sessions when there
         should not have been. Fixed. [Graham Leggett]
    
      *) mod_log_config: Add the R option to log the handler used within the
         request. [Christian Folini <christian.folini netnea com>]
    
      *) mod_include: Allow fine control over the removal of Last-Modified and
         ETag headers within the INCLUDES filter, making it possible to cache
         responses if desired. Fix the default value of the SSIAccessEnable
         directive.  [Graham Leggett]
    
      *) Add new UnDefine directive to undefine a variable. PR 35350.
         [Stefan Fritsch]
    
      *) Make ap_pregsub(), used by AliasMatch and friends, use the same syntax
         for regex backreferences as mod_rewrite and mod_include: Remove the use
         of '&' as an alias for '$0' and allow to escape any character with a
         backslash. PR 48351. [Stefan Fritsch]
    
      *) mod_authnz_ldap: If AuthLDAPCharsetConfig is set, also convert the
         password to UTF-8. PR 45318.
         [Johannes Müller <joh_m gmx.de>, Stefan Fritsch]
    
      *) ab: Fix calculation of requests per second in HTML output. PR 48594.
         [Stefan Fritsch]
    
      *) mod_authnz_ldap: Failures to map a username to a DN, or to check a user
         password now result in an informational level log entry instead of
         warning level.  [Eric Covener]
    
    Changes with Apache 2.3.5
    
      *) SECURITY: CVE-2010-0434 (cve.mitre.org)
         Ensure each subrequest has a shallow copy of headers_in so that the
         parent request headers are not corrupted.  Eliminates a problematic
         optimization in the case of no request body.  PR 48359
         [Jake Scott, William Rowe, Ruediger Pluem]
    
      *) Turn static function get_server_name_for_url() into public
         ap_get_server_name_for_url() and use it where appropriate. This
         fixes mod_rewrite generating invalid URLs for redirects to IPv6
         literal addresses. [Stefan Fritsch]
    
      *) mod_ldap: Introduce new config option LDAPTimeout to set the timeout
         for LDAP operations like bind and search. [Stefan Fritsch]
    
      *) mod_proxy, mod_proxy_ftp: Move ProxyFtpDirCharset from mod_proxy to
         mod_proxy_ftp. [Takashi Sato]
    
      *) mod_proxy, mod_proxy_connect: Move AllowCONNECT from mod_proxy to
         mod_proxy_connect. [Takashi Sato]
    
      *) mod_cache: Do an exact match of the keys defined by
         CacheIgnoreURLSessionIdentifiers against the querystring instead of
         a partial match.  PR 48401.
         [Dodou Wang <wangdong.08 gmail.com>, Ruediger Pluem]
    
      *) mod_proxy_balancer: Fix crash in balancer-manager. [Rainer Jung]
    
      *) Core HTTP: disable keepalive when the Client has sent
         Expect: 100-continue
         but we respond directly with a non-100 response.
         Keepalive here led to data from clients continuing being treated as
         a new request.
         PR 47087 [Nick Kew]
    
      *) Core: reject NULLs in request line or request headers.
         PR 43039 [Nick Kew]
    
      *) Core: (re)-introduce -T commandline option to suppress documentroot
         check at startup.
         PR 41887 [Jan van den Berg <janvdberg gmail.com>]
    
      *) mod_autoindex: support XHTML as equivalent to HTML in IndexOptions,
                        ScanHTMLTitles, ReadmeName, HeaderName
         PR 48416 [Dmitry Bakshaev <dab18 izhnet.ru>, Nick Kew]
    
      *) Proxy: Fix ProxyPassReverse with relative URL
         Derived (slightly erroneously) from PR 38864 [Nick Kew]
    
      *) mod_headers: align Header Edit with Header Set when used on Content-Type
         PR 48422 [Cyril Bonté <cyril.bonte free.fr>, Nick Kew>]
    
      *) mod_headers: Enable multi-match-and-replace edit option
         PR 46594 [Nick Kew]
    
      *) mod_filter: enable it to act on non-200 responses.
         PR 48377 [Nick Kew]
    
    Changes with Apache 2.3.4
    
      *) Replace AcceptMutex, LockFile, RewriteLock, SSLMutex, SSLStaplingMutex,
         and WatchdogMutexPath with a single Mutex directive.  Add APIs to
         simplify setup and user customization of APR proc and global mutexes.
         (See util_mutex.h.)  Build-time setting DEFAULT_LOCKFILE is no longer
         respected; set DEFAULT_REL_RUNTIMEDIR instead.  [Jeff Trawick]
    
      *) http_core: KeepAlive no longer accepts other than On|Off.
         [Takashi Sato]
    
      *) mod_dav: Remove errno from dav_error interface.  Calls to dav_new_error()
         and dav_new_error_tag() must be adjusted to add an apr_status_t parameter.
         [Jeff Trawick]
    
      *) mod_authnz_ldap: Add AuthLDAPBindAuthoritative to allow Authentication to
         try other providers in the case of an LDAP bind failure.
         PR 46608 [Justin Erenkrantz, Joe Schaefer, Tony Stevenson]
    
      *) Build: fix --with-module to work as documented
         PR 43881 [Gez Saunders <gez.saunders virgin.net>]
    
    Changes with Apache 2.3.3
    
      *) SECURITY: CVE-2009-3095 (cve.mitre.org)
         mod_proxy_ftp: sanity check authn credentials.
         [Stefan Fritsch <sf fritsch.de>, Joe Orton]
    
      *) SECURITY: CVE-2009-3094 (cve.mitre.org)
         mod_proxy_ftp: NULL pointer dereference on error paths.
         [Stefan Fritsch <sf fritsch.de>, Joe Orton]
    
      *) mod_ssl: enable support for ECC keys and ECDH ciphers.  Tested against
         OpenSSL 1.0.0b3.  [Vipul Gupta <vipul.gupta sun.com>, Sander Temme]
    
      *) mod_dav: Include uri when logging a PUT error due to connection abort.
         PR 38149. [Stefan Fritsch]
    
      *) mod_dav: Return 409 instead of 500 for a LOCK request if the parent
         resource does not exist or is not a collection. PR 43465. [Stefan Fritsch]
    
      *) mod_dav_fs: Return 409 instead of 500 for Litmus test case copy_nodestcoll
         (a COPY request where the parent of the destination resource does not
         exist). PR 39299. [Stefan Fritsch]
    
      *) mod_dav_fs: Don't delete the whole file if a PUT with content-range failed.
         PR 42896. [Stefan Fritsch]
    
      *) mod_dav_fs: Make PUT create files atomically and no longer destroy the
         old file if the transfer aborted. PR 39815. [Paul Querna, Stefan Fritsch]
    
      *) mod_dav_fs: Remove inode keyed locking as this conflicts with atomically
         creating files. On systems with inode numbers, this is a format change of
         the DavLockDB. The old DavLockDB must be deleted on upgrade.
         [Stefan Fritsch]
    
      *) mod_log_config: Make ${cookie}C correctly match whole cookie names
         instead of substrings. PR 28037. [Dan Franklin <dan dan-franklin.com>,
         Stefan Fritsch]
    
      *) vhost: A purely-numeric Host: header should not be treated as a port.
         PR 44979 [Nick Kew]
    
      *) mod_ldap: Avoid 500 errors with "Unable to set LDAP_OPT_REFHOPLIMIT option to 5"
         when built against openldap by using SDK LDAP_OPT_REFHOPLIMIT defaults unless
         LDAPReferralHopLimit is explicitly configured.
         [Eric Covener]
    
      *) mod_charset_lite: Honor 'CharsetOptions NoImplicitAdd'.
         [Eric Covener]
    
      *) mod_ssl: Add support for OCSP Stapling.  PR 43822.
         [Dr Stephen Henson <shenson oss-institute.org>]
    
      *) mod_socache_shmcb: Allow parens in file name if cache size is given.
         Fixes SSLSessionCache directive mis-parsing parens in pathname.
         PR 47945. [Stefan Fritsch]
    
      *) htpasswd: Improve out of disk space handling. PR 30877. [Stefan Fritsch]
    
      *) htpasswd: Use MD5 hash by default on all platforms. [Stefan Fritsch]
    
      *) mod_sed: Reduce memory consumption when processing very long lines.
         PR 48024 [Basant Kumar Kukreja <basant.kukreja sun.com>]
    
      *) ab: Fix segfault in case the argument for -n is a very large number.
         PR 47178. [Philipp Hagemeister <oss phihag.de>]
    
      *) Allow ProxyPreserveHost to work in <Proxy> sections. PR 34901.
         [Stefan Fritsch]
    
      *) configure: Fix THREADED_MPMS so that mod_cgid is enabled again
         for worker MPM. [Takashi Sato]
    
      *) mod_dav: Provide a mechanism to obtain the request_rec and pathname
         from the dav_resource. [Jari Urpalainen <jari.urpalainen nokia.com>,
         Brian France <brian brianfrance.com>]
    
      *) Build: Use install instead of cp if available on installing
         modules to avoid segmentation fault. PR 47951. [hirose31 gmail.com]
    
      *) mod_cache: correctly consider s-maxage in cacheability
         decisions.  [Dan Poirier]
    
      *) mod_logio/core: Report more accurate byte counts in mod_status if
         mod_logio is loaded. PR 25656. [Stefan Fritsch]
    
      *) mod_ldap: If LDAPSharedCacheSize is too small, try harder to purge
         some cache entries and log a warning. Also increase the default
         LDAPSharedCacheSize to 500000. This is a more realistic size suitable
         for the default values of 1024 for LdapCacheEntries/LdapOpCacheEntries.
         PR 46749. [Stefan Fritsch]
    
      *) mod_rewrite: Make sure that a hostname:port isn't fully qualified if
         the request is a CONNECT request. [Bill Zajac <billz consultla.com>]
    
      *) mod_cache: Teach CacheEnable and CacheDisable to work from within a
         Location section, in line with how ProxyPass works. [Graham Leggett]
    
      *) mod_reqtimeout: New module to set timeouts and minimum data rates for
         receiving requests from the client. [Stefan Fritsch]
    
      *) core: Fix potential memory leaks by making sure to not destroy
         bucket brigades that have been created by earlier filters.
         [Stefan Fritsch]
    
      *) core, mod_deflate, mod_sed: Reduce memory usage by reusing bucket
         brigades in several places. [Stefan Fritsch]
    
      *) mod_cache: Fix uri_meets_conditions() so that CacheEnable will
         match by scheme, or by a wildcarded hostname. PR 40169
         [Peter Grandi <pg_asf asf.for.sabi.co.uk>, Graham Leggett]
    
      *) suxec: Allow to log an error if exec fails by setting FD_CLOEXEC
         on the log file instead of closing it. PR 10744. [Nicolas Rachinsky]
    
      *) mod_mime: Make RemoveType override the info from TypesConfig.
         PR 38330. [Stefan Fritsch]
    
      *) mod_cache: Introduce the option to run the cache from within the
         normal request handler, and to allow fine grained control over
         where in the filter chain content is cached. Adds CacheQuickHandler
         directive.  [Graham Leggett]
    
      *) core: Treat timeout reading request as 408 error, not 400.
         Log 408 errors in access log as was done in Apache 1.3.x.
         PR 39785 [Nobutaka Mantani <nobutaka nobutaka.org>,
         Stefan Fritsch <sf fritsch.de>, Dan Poirier]
    
      *) mod_ssl: Reintroduce SSL_CLIENT_S_DN, SSL_CLIENT_I_DN, SSL_SERVER_S_DN,
         SSL_SERVER_I_DN back to the environment variables to be set by mod_ssl.
         [Peter Sylvester <peter.sylvester edelweb.fr>]
    
      *) mod_disk_cache: don't cache incomplete responses, per RFC 2616, 13.8.
         PR15866.  [Dan Poirier]
    
      *) ab: ab segfaults in verbose mode on https sites
         PR46393.  [Ryan Niebur]
    
      *) mod_dav: Allow other modules to become providers and add resource types
         to the DAV response. [Jari Urpalainen <jari.urpalainen nokia.com>,
         Brian France <brian brianfrance.com>]
    
      *) mod_dav: Allow other modules to add things to the DAV or Allow headers
         of an OPTIONS request. [Jari Urpalainen <jari.urpalainen nokia.com>,
         Brian France <brian brianfrance.com>]
    
      *) core: Lower memory usage of core output filter.
         [Stefan Fritsch <sf sfritsch.de>]
    
      *) mod_mime: Detect invalid use of MultiviewsMatch inside Location and
         LocationMatch sections.  PR47754. [Dan Poirier]
    
      *) mod_request: Make sure the KeptBodySize directive rejects values
         that aren't valid numbers. [Graham Leggett]
    
      *) mod_session_crypto: Sanity check should the potentially encrypted
         session cookie be too short. [Graham Leggett]
    
      *) mod_session.c: Prevent a segfault when session is added but not
         configured. [Graham Leggett]
    
      *) htcacheclean: 19 ways to fail, 1 error message. Fixed. [Graham Leggett]
    
      *) mod_auth_digest: Fail server start when nonce count checking
         is configured without shared memory, or md5-sess algorithm is
         configured. [Dan Poirier]
    
      *) mod_proxy_connect: The connect method doesn't work if the client is
         connecting to the apache proxy through an ssl socket. Fixed.
         PR29744. [Brad Boyer, Mark Cave-Ayland, Julian Gilbey, Fabrice Durand,
         David Gence, Tim Dodge, Per Gunnar Hans, Emmanuel Elango,
         Kevin Croft, Rudolf Cardinal]
    
      *) mod_ssl: The error message when SSLCertificateFile is missing should
         at least give the name or position of the problematic virtual host
         definition. [Stefan Fritsch sf sfritsch.de]
    
      *) mod_auth_digest: Fix null pointer when qop=none. [Dan Poirier]
    
      *) Add support for HTTP PUT to ab. [Jeff Barnes <jbarnesweb yahoo.com>]
    
      *) mod_headers: generalise the envclause to support expression
         evaluation with ap_expr parser [Nick Kew]
    
      *) mod_cache: Introduce the thundering herd lock, a mechanism to keep
         the flood of requests at bay that strike a backend webserver as
         a cached entity goes stale. [Graham Leggett]
    
      *) mod_auth_digest: Fix usage of shared memory and re-enable it.
         PR 16057 [Dan Poirier]
    
      *) Preserve Port information over internal redirects
         PR 35999 [Jonas Ringh <jonas.ringh cixit.se>]
    
      *) Proxy: unable to connect to a backend is SERVICE_UNAVAILABLE,
         rather than BAD_GATEWAY or (especially) NOT_FOUND.
         PR 46971 [evanc nortel.com]
    
      *) Various modules: Do better checking of pollset operations in order to
         avoid segmentation faults if they fail. PR 46467
         [Stefan Fritsch <sf sfritsch.de>]
    
      *) mod_autoindex: Correctly create an empty cell if the description
         for a file is missing. PR 47682 [Peter Poeml <poeml suse.de>]
    
      *) ab: Fix broken error messages after resolver or connect() failures.
         [Jeff Trawick]
    
      *) SECURITY: CVE-2009-1890 (cve.mitre.org)
         Fix a potential Denial-of-Service attack against mod_proxy in a
         reverse proxy configuration, where a remote attacker can force a
         proxy process to consume CPU time indefinitely.  [Nick Kew, Joe Orton]
    
      *) SECURITY: CVE-2009-1191 (cve.mitre.org)
         mod_proxy_ajp: Avoid delivering content from a previous request which
         failed to send a request body. PR 46949 [Ruediger Pluem]
    
      *) htdbm: Fix possible buffer overflow if dbm database has very
         long values.  PR 30586 [Dan Poirier]
    
      *) core: Return APR_EOF if request body is shorter than the length announced
         by the client. PR 33098 [ Stefan Fritsch <sf sfritsch.de>]
    
      *) mod_suexec: correctly set suexec_enabled when httpd is run by a
         non-root user and may have insufficient permissions.
         PR 42175 [Jim Radford <radford blackbean.org>]
    
      *) mod_ssl: Fix SSL_*_DN_UID variables to use the 'userID' attribute
         type.  PR 45107.  [Michael Ströder <michael stroeder.com>,
         Peter Sylvester <peter.sylvester edelweb.fr>]
    
      *) mod_proxy_http: fix case sensitivity checking transfer encoding
         PR 47383 [Ryuzo Yamamoto <ryuzo.yamamoto gmail.com>]
    
      *) mod_alias: ensure Redirect issues a valid URL.
         PR 44020 [Håkon Stordahl <hakon stordahl.org>]
    
      *) mod_dir: add FallbackResource directive, to enable admin to specify
         an action to happen when a URL maps to no file, without resorting
         to ErrorDocument or mod_rewrite.  PR 47184 [Nick Kew]
    
      *) mod_cgid: Do not leak the listening Unix socket file descriptor to the
         CGI process. PR 47335 [Kornél Pál <kornelpal gmail.com>]
    
      *) mod_rewrite: Remove locking for writing to the rewritelog.
         PR 46942 [Dan Poirier <poirier pobox.com>]
    
      *) mod_alias: check sanity in Redirect arguments.
         PR 44729 [Sönke Tesch <st kino-fahrplan.de>, Jim Jagielski]
    
      *) mod_proxy_http: fix Host: header for literal IPv6 addresses.
         PR 47177 [Carlos Garcia Braschi <cgbraschi gmail.com>]
    
      *) mod_cache: Add CacheIgnoreURLSessionIdentifiers directive to ignore
         defined session identifiers encoded in the URL when caching.
         [Ruediger Pluem]
    
      *) mod_rewrite: Fix the error string returned by RewriteRule.
         RewriteRule returned "RewriteCond: bad flag delimiters" when the 3rd
         argument of RewriteRule was not started with "[" or not ended with "]".
         PR 45082 [Vitaly Polonetsky <m_vitaly topixoft.com>]
    
      *) Windows: Fix usage message.
         [Rainer Jung]
    
      *) apachectl: When passing through arguments to httpd in
         non-SysV mode, use the "$@" syntax to preserve arguments.
         [Eric Covener]
    
      *) mod_dbd: add DBDInitSQL directive to enable SQL statements to
         be run when a connection is opened.  PR 46827
         [Marko Kevac <mkevac gmail.com>]
    
      *) mod_cgid: Improve handling of long AF_UNIX socket names (ScriptSock).
         PR 47037.  [Jeff Trawick]
    
      *) mod_proxy_ajp: Check more strictly that the backend follows the AJP
         protocol. [Mladen Turk]
    
      *) mod_proxy_ajp: Forward remote port information by default.
         [Rainer Jung]
    
      *) Allow MPMs to be loaded dynamically, as with most other modules.  Use
         --enable-mpms-shared={list|"all"} to enable.  This required changes to
         the MPM interfaces.  Removed: mpm.h, mpm_default.h (as an installed
         header), APACHE_MPM_DIR, MPM_NAME, ap_threads_per_child,
         ap_max_daemons_limit, ap_my_generation, etc.  ap_mpm_query() can't be
         called until after the register-hooks phase.  [Jeff Trawick]
    
      *) mod_ssl: Add SSLProxyCheckPeerExpire and SSLProxyCheckPeerCN directives
         to enable stricter checking of remote server certificates.
         [Ruediger Pluem]
    
      *) ab: Fix a 100% CPU loop on platforms where a failed non-blocking connect
         returns EINPROGRESS and a subsequent poll() returns only POLLERR.
         Observed on HP-UX.  [Eric Covener]
    
      *) Remove broken support for BeOS, TPF, and even older platforms such
         as A/UX, Next, and Tandem.  [Jeff Trawick]
    
      *) mod_proxy_ftp: Add ProxyFtpListOnWildcard directive to allow files with
         globbing characters to be retrieved instead of converted into a
         directory listing.  PR 46789 [Dan Poirier <poirier pobox.com>]
    
      *) Provide ap_retained_data_create()/ap_retained_data_get() for preservation
         of module state across unload/load.  [Jeff Trawick]
    
      *) mod_substitute: Fix a memory leak. PR 44948
         [Dan Poirier <poirier pobox.com>]
    
    Changes with Apache 2.3.2
    
      *) mod_mime_magic: Fix detection of compressed content. [Rainer Jung]
    
      *) mod_negotiation: Escape paths of filenames in 406 responses to avoid
         HTML injections and HTTP response splitting.  PR 46837.
         [Geoff Keating <geoffk apple.com>]
    
      *) mod_ssl: add support for type-safe STACK constructs in OpenSSL
         development HEAD.  PR 45521.  [Kaspar Brand, Sander Temme]
    
      *) ab: Fix maintenance of the pollset to resolve EALREADY errors
         with kqueue (BSD/OS X) and excessive CPU with event ports (Solaris).
         PR 44584.  Use APR_POLLSET_NOCOPY for better performance with some
         pollset implementations.  [Jeff Trawick]
    
      *) mod_disk_cache: The module now turns off sendfile support if
         'EnableSendfile off' is defined globally. [Lars Eilebrecht]
    
      *) mod_deflate: Adjust content metadata before bailing out on 304
         responses so that the metadata does not differ from 200 response.
         [Roy T. Fielding]
    
      *) mod_deflate: Fix creation of invalid Etag headers. We now make sure
         that the Etag value is properly quoted when adding the gzip marker.
         PR 39727, 45023. [Lars Eilebrecht, Roy T. Fielding]
    
      *) Added 20x22 icons for ODF, SVG, and XML documents.  PR 37185.
         [Peter Harlow]
    
      *) Disabled DefaultType directive and removed ap_default_type()
         from core.  We now exclude Content-Type from responses for which
         a media type has not been configured via mime.types, AddType,
         ForceType, or some other mechanism. PR 13986. [Roy T. Fielding]
    
      *) mod_rewrite: Add IPV6 variable to RewriteCond
         [Ryan Phillips <ryan-apache trolocsis.com>]
    
      *) core: Enhance KeepAliveTimeout to support a value in milliseconds.
         PR 46275. [Takashi Sato]
    
      *) rotatelogs: Allow size units B, K, M, G and combination of
         time and size based rotation. [Rainer Jung]
    
      *) rotatelogs: Add flag for verbose (debug) output. [Rainer Jung]
    
      *) mod_ssl: Fix merging of SSLRenegBufferSize directive. PR 46508
         [<tlhackque yahoo.com>]
    
      *) core: Translate the the status line to ASCII on EBCDIC platforms in
         ap_send_interim_response() and for locally generated "100 Continue"
         responses.  [Eric Covener]
    
      *) prefork: Fix child process hang during graceful restart/stop in
         configurations with multiple listening sockets.  PR 42829.  [Joe Orton,
         Jeff Trawick]
    
      *) mod_session_crypto: Ensure that SessionCryptoDriver can only be
         set in the global scope. [Graham Leggett]
    
      *) mod_ext_filter: We need to detect failure to startup the filter
         program (a mangled response is not acceptable).  Fix to detect
         failure, and offer configuration option either to abort or
         to remove the filter and continue.
         PR 41120 [Nick Kew]
    
      *) mod_session_crypto: Rewrite the session_crypto module against the
         apr_crypto API. [Graham Leggett]
    
      *) mod_auth_form: Fix a pool lifetime issue, don't remove the subrequest
         until the main request is cleaned up. [Graham Leggett]
    
    Changes with Apache 2.3.1
    
      *) ap_slotmem: Add in new slot-based memory access API impl., including
         2 providers (mod_sharedmem and mod_plainmem) [Jim Jagielski,
         Jean-Frederic Clere, Brian Akins <brian.akins turner.com>]
    
      *) mod_include: support generating non-ASCII characters as entities in SSI
         PR 25202 [Nick Kew]
    
      *) core/utils: Enhance ap_escape_html API to support escaping non-ASCII chars
         PR 25202 [Nick Kew]
    
      *) mod_rewrite: fix "B" flag breakage by reverting r5589343
        PR 45529 [Bob Ionescu <bobsiegen googlemail.com>]
    
      *) CGI: return 504 (Gateway timeout) rather than 500 when a script
         times out before returning status line/headers.
         PR 42190 [Nick Kew]
    
      *) mod_cgid: fix segfault problem on solaris.
         PR 39332 [Masaoki Kobayashi <masaoki techfirm.co.jp>]
    
      *) mod_proxy_scgi: Added. [André Malo]
    
      *) mod_cache: Introduce 'no-cache' per-request environment variable
         to prevent the saving of an otherwise cacheable response.
         [Eric Covener]
    
      *) mod_rewrite: Introduce DiscardPathInfo|DPI flag to stop the troublesome
         way that per-directory rewrites append the previous notion of PATH_INFO
         to each substitution before evaluating subsequent rules.
         PR 38642 [Eric Covener]
    
      *) mod_cgid: Do not add an empty argument when calling the CGI script.
         PR 46380 [Ruediger Pluem]
    
      *) scoreboard: Remove unused sb_type from process_score.
         [Torsten Foertsch <torsten.foertsch gmx.net>, Chris Darroch]
    
      *) mod_ssl: Add SSLRenegBufferSize directive to allow changing the
         size of the buffer used for the request-body where necessary
         during a per-dir renegotiation.  PR 39243.  [Joe Orton]
    
      *) mod_proxy_fdpass: New module to pass a client connection over to a separate
         process that is reading from a unix daemon socket.
    
      *) mod_ssl: Improve environment variable extraction to be more
         efficient and to correctly handle DNs with duplicate tags.
         PR 45975.  [Joe Orton]
    
      *) Remove the obsolete serial attribute from the RPM spec file. Compile
         against the external pcre. Add missing binaries fcgistarter, and
         mod_socache* and mod_session*. [Graham Leggett]
    
    Changes with Apache 2.3.0
    
      *) mod_ratelimit: New module to do bandwidth rate limiting. [Paul Querna]
    
      *) Remove X-Pad header which was added as a work around to a bug in
         Netscape 2.x to 4.0b2. [Takashi Sato <takashi lans-tv.com>]
    
      *) Add DTrace Statically Defined Tracing (SDT) probes.
        [Theo Schlossnagle <jesus omniti.com>, Paul Querna]
    
      *) mod_proxy_balancer: Move all load balancing implementations
         as individual, self-contained mod_proxy submodules under
         modules/proxy/balancers [Jim Jagielski]
    
      *) Rename APIs to include ap_ prefix:
            find_child_by_pid -> ap_find_child_by_pid
            suck_in_APR -> ap_suck_in_APR
            sys_privileges_handlers -> ap_sys_privileges_handlers
            unixd_accept -> ap_unixd_accept
            unixd_config -> ap_unixd_config
            unixd_killpg -> ap_unixd_killpg
            unixd_set_global_mutex_perms -> ap_unixd_set_global_mutex_perms
            unixd_set_proc_mutex_perms -> ap_unixd_set_proc_mutex_perms
            unixd_set_rlimit -> ap_unixd_set_rlimit
         [Paul Querna]
    
      *) mod_lbmethod_heartbeat: New module to load balance mod_proxy workers
         based on heartbeats. [Paul Querna]
    
      *) mod_heartmonitor: New module to collect heartbeats, and write out a file
         so that other modules can load balance traffic as needed. [Paul Querna]
    
      *) mod_heartbeat: New module to generate multicast heartbeats to know if a
         server is online. [Paul Querna]
    
      *) mod_buffer: Honour the flush bucket and flush the buffer in the
         input filter. Make sure that metadata buckets are written to
         the buffer, not to the final brigade. [Graham Leggett]
    
      *) mod_buffer: Optimise the buffering of heap buckets when the heap
         buckets stay exactly APR_BUCKET_BUFF_SIZE long. [Graham Leggett,
         Ruediger Pluem]
    
      *) mod_buffer: Optional support for buffering of the input and output
         filter stacks. Can collapse many small buckets into fewer larger
         buckets, and prevents excessively small chunks being sent over
         the wire. [Graham Leggett]
    
      *) mod_privileges: new module to make httpd on Solaris privileges-aware
         and to enable different virtualhosts to run with different
         privileges and Unix user/group IDs [Nick Kew]
    
      *) mod_mem_cache: this module has been removed. [William Rowe]
    
      *) authn/z: Remove mod_authn_default and mod_authz_default.
         [Chris Darroch]
    
      *) authz: Fix handling of authz configurations, make default authz
         logic replicate 2.2.x authz logic, and replace <Satisfy*>, Reject,
         and AuthzMergeRules directives with Match, <Match*>, and AuthzMerge
         directives.  [Chris Darroch]
    
      *) mod_authn_core: Prevent crash when provider alias created to
         provider which is not yet registered.  [Chris Darroch]
    
      *) mod_authn_core: Add AuthType of None to support disabling
         authentication.  [Chris Darroch]
    
      *) core: Allow <Limit> and <LimitExcept> directives to nest, and
         constrain their use to conform with that of other access control
         and authorization directives.  [Chris Darroch]
    
      *) unixd: turn existing code into a module, and turn the set user/group
         and chroot into a child_init function. [Nick Kew]
    
      *) mod_dir: Support "DirectoryIndex disabled"
         Suggested By André Warnier <aw ice-sa.com> [Eric Covener]
    
      *) mod_ssl: Send Content-Type application/ocsp-request for POST requests to
         OSCP responders. PR 46014 [Dr Stephen Henson <steve openssl.org>]
    
      *) mod_authnz_ldap: don't return NULL-valued environment variables to
         other modules.  PR 39045 [Francois Pesce <francois.pesce gmail.com>]
    
      *) Don't adjust case in pathname components that are not of interest
         to mod_mime.  Fixes mod_negotiation's use of such components.
         PR 43250 [Basant Kumar Kukreja <basant.kukreja sun.com>]
    
      *) Be tolerant in what you accept - accept slightly broken
         status lines from a backend provided they include a valid status code.
         PR 44995 [Rainer Jung <rainer.jung kippdata.de>]
    
      *) New module mod_sed: filter Request/Response bodies through sed
         [Basant Kumar Kukreja <basant.kukreja sun.com>]
    
      *) mod_auth_form: Make sure that basic authentication is correctly
         faked directly after login. [Graham Leggett]
    
      *) mod_session_cookie, mod_session_dbd: Make sure cookies are set both
         within the output headers and error output headers, so that the
         session is maintained across redirects. [Graham Leggett]
    
      *) mod_auth_form: Make sure the logged in user is populated correctly
         after a form login. Fixes a missing REMOTE_USER variable directly
         following a login. [Graham Leggett]
    
      *) mod_session_cookie: Make sure that cookie attributes are correctly
         included in the blank cookie when cookies are removed. This fixes an
         inability to log out when using mod_auth_form. [Graham Leggett]
    
      *) mod_session: Prevent a segfault when a CGI script sets a cookie with a
         null value. [David Shane Holden <dpejesh apache.org>]
    
      *) core, authn/z: Determine registered authn/z providers directly in
         ap_setup_auth_internal(), which allows optional functions that just
         wrapped ap_list_provider_names() to be removed from authn/z modules.
         [Chris Darroch]
    
      *) authn/z: Convert common provider version strings to macros.
         [Chris Darroch]
    
      *) core: When testing for slash-terminated configuration paths in
         ap_location_walk(), don't look past the start of an empty string
         such as that created by a <Location ""> directive.
         [Chris Darroch]
    
      *) core, mod_proxy: If a kept_body is present, it becomes safe for
         subrequests to support message bodies. Make sure that safety
         checks within the core and within the proxy are not triggered
         when kept_body is present. This makes it possible to embed
         proxied POST requests within mod_include. [Graham Leggett]
    
      *) mod_auth_form: Make sure the input filter stack is properly set
         up before reading the login form. Make sure the kept body filter
         is correctly inserted to ensure the body can be read a second
         time safely should the authn be successful. [Graham Leggett,
         Ruediger Pluem]
    
      *) mod_request: Insert the KEPT_BODY filter via the insert_filter
         hook instead of during fixups. Add a safety check to ensure the
         filters cannot be inserted more than once. [Graham Leggett,
         Ruediger Pluem]
    
      *) ap_cache_cacheable_headers_out() will (now) always
         merge an error headers _before_ clearing them and _before_
         merging in the actual entity headers and doing normal
         hop-by-hop cleansing. [Dirk-Willem van Gulik].
    
      *) cache: retire ap_cache_cacheable_hdrs_out() which was used
         for both in- and out-put headers; and replace it by a single
         ap_cache_cacheable_headers() wrapped in a in- and out-put
         specific ap_cache_cacheable_headers_in()/out(). The latter
         which will also merge error and ensure content-type. To keep
         cache modules consistent with ease. This API change bumps
         up the minor MM by one [Dirk-Willem van Gulik].
    
      *) Move the KeptBodySize directive, kept_body filters and the
         ap_parse_request_body function out of the http module and into a
         new module called mod_request, reducing the size of the core.
         [Graham Leggett]
    
      *) mod_dbd: Handle integer configuration directive parameters with a
         dedicated function.
    
      *) Change the directives within the mod_session* modules to be valid
         both inside and outside the location/directory sections, as
         suggested by wrowe. [Graham Leggett]
    
      *) mod_auth_form: Add a module capable of allowing end users to log
         in using an HTML form, storing the credentials within mod_session.
         [Graham Leggett]
    
      *) Add a function to the http filters that is able to parse an HTML
         form request with the type of application/x-www-form-urlencoded.
         [Graham Leggett]
    
      *) mod_session_crypto: Initialise SSL in the post config hook.
         [Ruediger Pluem, Graham Leggett]
    
      *) mod_session_dbd: Add a session implementation capable of storing
         session information in a SQL database via the dbd interface. Useful
         for sites where session privacy is important. [Graham Leggett]
    
      *) mod_session_crypto: Add a session encoding implementation capable
         of encrypting and decrypting sessions wherever they may be stored.
         Introduces a level of privacy when sessions are stored on the
         browser. [Graham Leggett]
    
      *) mod_session_cookie: Add a session implementation capable of storing
         session information within cookies on the browser. Useful for high
         volume sites where server bound sessions are too resource intensive.
         [Graham Leggett]
    
      *) mod_session: Add a generic session interface to unify the different
         attempts at saving persistent sessions across requests.
         [Graham Leggett]
    
      *) core, authn/z: Avoid calling access control hooks for internal requests
         with configurations which match those of initial request.  Revert to
         original behaviour (call access control hooks for internal requests
         with URIs different from initial request) if any access control hooks or
         providers are not registered as permitting this optimization.
         Introduce wrappers for access control hook and provider registration
         which can accept additional mode and flag data.  [Chris Darroch]
    
      *) Introduced ap_expr API for expression evaluation.
         This is adapted from mod_include, which is the first module
         to use the new API.
         [Nick Kew]
    
      *) mod_authz_dbd: When redirecting after successful login/logout per
         AuthzDBDRedirectQuery, do not report authorization failure, and use
         first row returned by database query instead of last row.
         [Chris Darroch]
    
      *) mod_ldap: Correctly return all requested attribute values
         when some attributes have a null value.
         PR 44560 [Anders Kaseorg <anders kaseorg.com>]
    
      *) core: check symlink ownership if both FollowSymlinks and
         SymlinksIfOwnerMatch are set [Nick Kew]
    
      *) core: fix origin checking in SymlinksIfOwnerMatch
         PR 36783 [Robert L Mathews <rob-apache.org.bugs tigertech.net>]
    
      *) Activate mod_cache, mod_file_cache and mod_disk_cache as part of the
         'most' set for '--enable-modules' and '--enable-shared-mods'. Include
         mod_mem_cache in 'all' as well. [Dirk-Willem van Gulik]
    
      *) Also install mod_so.h, mod_rewrite.h and mod_cache.h; as these
         contain public function declarations which are useful for
         third party module authors. PR 42431 [Dirk-Willem van Gulik].
    
      *) mod_dir, mod_negotiation: pass the output filter information
         to newly created sub requests; as these are later on used
         as true requests with an internal redirect. This allows for
         mod_cache et.al. to trap the results of the redirect.
         [Dirk-Willem van Gulik, Ruediger Pluem]
    
      *) mod_ldap: Add support (taking advantage of the new APR capability)
         for ldap rebind callback while chasing referrals. This allows direct
         searches on LDAP servers (in particular MS Active Directory 2003+)
         using referrals without the use of the global catalog.
         PRs 26538, 40268, and 42557 [Paul J. Reder]
    
      *) ApacheMonitor.exe: Introduce --kill argument for use by the
         installer.  This will permit the installation tool to remove
         all running instances before attempting to remove the .exe.
         [William Rowe]
    
      *) mod_ssl: Add support for OCSP validation of client certificates.
         PR 41123.  [Marc Stern <marc.stern approach.be>, Joe Orton]
    
      *) mod_serf: New module for Reverse Proxying. [Paul Querna]
    
      *) core: Add the option to keep aside a request body up to a certain
         size that would otherwise be discarded, to be consumed by filters
         such as mod_include. When enabled for a directory, POST requests
         to shtml files can be passed through to embedded scripts as POST
         requests, rather being downgraded to GET requests. [Graham Leggett]
    
      *) mod_ssl: Fix TLS upgrade (RFC 2817) support.  PR 41231.  [Joe Orton]
    
      *) scoreboard: Correctly declare ap_time_process_request.
         PR 43789 [Tom Donovan <Tom.Donovan acm.org>]
    
      *) core; scoreboard: ap_get_scoreboard_worker(sbh) now takes the sbh member
         from the connection rec, ap_get_scoreboard_worker(proc, thread) will now
         provide the unusual legacy lookup.  [William Rowe]
    
      *) mpm winnt: fix null pointer dereference
         PR 42572 [Davi Arnaut]
    
      *) mod_authnz_ldap, mod_authn_dbd: Tidy up the code to expose authn
         parameters to the environment. Improve portability to
         EBCDIC machines by using apr_toupper(). [Martin Kraemer]
    
      *) mod_ldap, mod_authnz_ldap: Add support for nested groups (i.e. the ability
         to authorize an authenticated user via a "require ldap-group X" directive
         where the user is not in group X, but is in a subgroup contained in X.
         PR 42891 [Paul J. Reder]
    
      *) mod_ssl: Add support for caching SSL Sessions in memcached. [Paul Querna]
    
      *) apxs: Enhance -q flag to print all known variables and their values
         when invoked without variable name(s).
         [William Rowe, Sander Temme]
    
      *) apxs: Eliminate run-time check for mod_so.  PR 40653.
         [David M. Lee <dmlee crossroads.com>]
    
      *) beos MPM: Create pmain pool and run modules' child_init hooks when
         entering ap_mpm_run(), then destroy pmain when exiting ap_mpm_run().
         [Chris Darroch]
    
      *) netware MPM: Destroy pmain pool when exiting ap_mpm_run() so that
         cleanups registered in modules' child_init hooks are performed.
         [Chris Darroch]
    
      *) Fix issue which could cause error messages to be written to access logs
         on Win32.  PR 40476.  [Tom Donovan <Tom.Donovan acm.org>]
    
      *) The LockFile directive, which specifies the location of
         the accept() mutex lockfile, is deprecated. Instead, the
         AcceptMutex directive now takes an optional lockfile
         location parameter, ala SSLMutex. [Jim Jagielski]
    
      *) mod_authn_dbd: Export any additional columns queried in the SQL select
         into the environment with the name AUTHENTICATE_<COLUMN>. This brings
         mod_authn_dbd behaviour in line with mod_authnz_ldap. [Graham Leggett]
    
      *) mod_dbd: Key the storage of prepared statements on the hex string
         value of server_rec, rather than the server name, as the server name
         may change (eg when the server name is set) at any time, causing
         weird behaviour in modules dependent on mod_dbd. [Graham Leggett]
    
      *) mod_proxy_fcgi: Added win32 build. [Mladen Turk]
    
      *) sendfile_nonblocking() takes the _brigade_ as an argument, gets
         the first bucket from the brigade, finds it not to be a FILE
         bucket and barfs. The fix is to pass a bucket rather than a brigade.
         [Niklas Edmundsson <nikke acc.umu.se>]
    
      *) mod_rewrite: support rewritemap by SQL query [Nick Kew]
    
      *) ap_get_server_version() has been removed.  Third-party modules must
         now use ap_get_server_banner() or ap_get_server_description().
         [Jeff Trawick]
    
      *) All MPMs: Introduce a check_config phase between pre_config and
         open_logs, to allow modules to review interdependent configuration
         directive values and adjust them while messages can still be logged
         to the console.  Handle relevant MPM directives during this phase
         and format messages for both the console and the error log, as
         appropriate.  [Chris Darroch]
    
      *) core: Do not allow internal redirects like the DirectoryIndex of mod_dir
         to circumvent the symbolic link checks imposed by FollowSymLinks and
         SymLinksIfOwnerMatch. [Nick Kew, Ruediger Pluem, William Rowe]
    
      *) New SSLLogLevelDebugDump [ None (default) | IO (not bytes) | Bytes ]
         configures the I/O Dump of SSL traffic, when LogLevel is set to Debug.
         The default is none as this is far greater debugging resolution than
         the typical administrator is prepared to untangle.  [William Rowe]
    
      *) mod_disk_cache: If possible, check if the size of an object to cache is
         within the configured boundaries before actually saving data.
         [Niklas Edmundsson <nikke acc.umu.se>]
    
      *) Worker and event MPMs: Remove improper scoreboard updates which were
         performed in the event of a fork() failure.  [Chris Darroch]
    
      *) Add support for fcgi:// proxies to mod_rewrite.
         [Markus Schiegl <ms schiegl.com>]
    
      *) Remove incorrect comments from scoreboard.h regarding conditional
         loading of worker_score structure with mod_status, and remove unused
         definitions relating to old life_status field.
         [Chris Darroch <chrisd pearsoncmg.com>]
    
      *) Remove allocation of memory for unused array of lb_score pointers
         in ap_init_scoreboard().  [Chris Darroch <chrisd pearsoncmg.com>]
    
      *) Add mod_proxy_fcgi, a FastCGI back end for mod_proxy.
         [Garrett Rooney, Jim Jagielski, Paul Querna]
    
      *) Event MPM: Fill in the scoreboard's tid field. PR 38736.
         [Chris Darroch <chrisd pearsoncmg.com>]
    
      *) mod_charset_lite: Remove Content-Length when output filter can
         invalidate it.  Warn when input filter can invalidate it.
         [Jeff Trawick]
    
      *) Authz: Add the new module mod_authn_core that will provide common
         authn directives such as 'AuthType', 'AuthName'.  Move the directives
         'AuthType' and 'AuthName' out of the core module and merge mod_authz_alias
         into mod_authn_core. [Brad Nicholes]
    
      *) Authz: Move the directives 'Order', 'Allow', 'Deny' and 'Satisfy'
         into the new module mod_access_compat which can be loaded to provide
         support for these directives.
         [Brad Nicholes]
    
      *) Authz: Move the 'Require' directive from the core module as well as
         add the directives '<SatisfyAll>', '<SatisfyOne>', '<RequireAlias>'
         and 'Reject' to mod_authz_core. The new directives introduce 'AND/OR'
         logic into the authorization processing. [Brad Nicholes]
    
      *) Authz: Add the new module mod_authz_core which acts as the
         authorization provider vector and contains common authz
         directives. [Brad Nicholes]
    
      *) Authz: Renamed mod_authz_dbm authz providers from 'group' and
         'file-group' to 'dbm-group' and 'dbm-file-group'. [Brad Nicholes]
    
      *) Authz: Added the new authz providers 'env', 'ip', 'host', 'all' to handle
         host-based access control provided by mod_authz_host and invoked
         through the 'Require' directive. [Brad Nicholes]
    
      *) Authz: Convert all of the authz modules from hook based to
         provider based. [Brad Nicholes]
    
      *) mod_cache: Add CacheMinExpire directive to set the minimum time in
         seconds to cache a document.
         [Brian Akins <brian.akins turner.com>, Ruediger Pluem]
    
      *) mod_authz_dbd: SQL authz with Login/Session support [Nick Kew]
    
      *) Fix typo in ProxyStatus syntax error message.
         [Christophe Jaillet <christophe.jaillet wanadoo.fr>]
    
      *) Asynchronous write completion for the Event MPM.  [Brian Pane]
    
      *) Added an End-Of-Request bucket type.  The logging of a request and
         the freeing of its pool are now done when the EOR bucket is destroyed.
         This has the effect of delaying the logging until right after the last
         of the response is sent; ap_core_output_filter() calls the access logger
         indirectly when it destroys the EOR bucket.  [Brian Pane]
    
      *) Rewrite of logresolve support utility: IPv6 addresses are now supported
         and the format of statistical output has changed. [Colm MacCarthaigh]
    
      *) Rewrite of ap_coreoutput_filter to do nonblocking writes  [Brian Pane]
    
      *) Added new connection states for handler and write completion
         [Brian Pane]
    
      *) mod_cgid: Refuse to work on Solaris 10 due to OS bugs.  PR 34264.
         [Justin Erenkrantz]
    
      *) Teach mod_ssl to use arbitrary OIDs in an SSLRequire directive,
         allowing string-valued client certificate attributes to be used for
         access control, as in: SSLRequire "value" in OID("1.3.6.1.4.1.18060.1")
         [Martin Kraemer, David Reid]
    
      [Apache 2.3.0-dev includes those bug fixes and changes with the
       Apache 2.2.xx tree as documented, and except as noted, below.]
    
    Changes with Apache 2.2.x and later:
    
      *) http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?view=markup
    
    Changes with Apache 2.0.x and later:
    
      *) http://svn.apache.org/viewvc/httpd/httpd/branches/2.0.x/CHANGES?view=markup
    ����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/README.cmake���������������������������������������������������������������������������0000664�0001751�0001751�00000031567�15022007067�014574� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Experimental cmake-based build support for Apache httpd on Microsoft Windows
    
    Status
    ------
    
    This build support is currently intended only for Microsoft Windows.
    
    This build support is experimental.  Specifically,
    
    * It does not support all features of Apache httpd.
    * Some components may not be built correctly and/or in a manner
      compatible with the previous Windows build support.
    * Build interfaces, such as the mechanisms which are used to enable
      optional functionality or specify prerequisites, may change from
      release to release as feedback is received from users and bugs and
      limitations are resolved.
    
    Important: Refer to the "Known Bugs and Limitations" section for further
               information.
    
               It is beyond the scope of this document to document or explain
               how to utilize the various cmake features, such as different
               build backends or provisions for finding support libraries.
    
               Please refer to the cmake documentation for additional information
               that applies to building any project with cmake.
    
    Prerequisites
    -------------
    
    The following tools must be in PATH:
    
    * cmake, version 2.8 or later
      cmake version 3.1.3 or later is required to work with current OpenSSL
      releases.  (OpenSSL is an optional prerequisite of httpd.)
    * Perl
    * If using a command-line compiler: compiler and linker and related tools
      (Refer to the cmake documentation for more information.)
    
    The following support libraries are mandatory:
    
    * APR, built with cmake
      + Either APR 2.0-dev (trunk) or APR 1.5.x and APR-Util 1.5.x.
      + When building APR (but not APR-Util), specify the build option
        APR_INSTALL_PRIVATE_H so that non-standard files required for building
        Apache httpd are installed.
      + Additional APR settings affect httpd but are not mandatory, such as
        APR_HAVE_IPV6.
    * PCRE
    
    Certain optional features of APR 2.0-dev (trunk) or APR-Util 1.5.x
    allow some optional features of httpd to be enabled.  For example,
    APU_HAVE_CRYPTO is required for mod_session_crypto.
    
    Additional support libraries allow some optional features of httpd to be
    enabled:
    
    * libxml2 (e.g., mod_proxy_html)
    * lua 5.1 (mod_lua)
    * nghttp2 (mod_http2)
    * openssl (mod_ssl and https support for ab)
    * zlib (mod_deflate)
    
    OpenSSL
    -------
    
    If you have a binary install of OpenSSL in a well-known directory (e.g.,
    %HOME%\OpenSSL-Win64) and you wish to build httpd against a different
    install of OpenSSL, the cmake build may unexpectedly select OpenSSL
    libraries in the well-known directory even if the expected include files
    are used.  Check the cmake output from your httpd build to confirm that
    the expected OpenSSL libraries and include files are used.
    
    The cmake FindOpenSSL module searches for OpenSSL libraries in a "VC"
    subdirectory of the OpenSSL install with filenames that indicate the build
    type (e.g., "<PREFIX>/lib/VC/ssleay32MD.lib"); defining CMAKE_PREFIX_PATH
    or OPENSSL_ROOT_DIR or even OPENSSL_LIBRARIES does not circumvent finding
    these libraries.
    
    To work around this issue, rename the well-known OpenSSL directory while
    building httpd.  Let us know if you find a better solution.
    
    nghttp2
    -------
    
    This is required for mod_http2.
    
    cmake-based build support for nghttp2 for Windows can be found at
    https://github.com/trawick/nghttp2-minimal-cmake.  That easily fits into
    a build system that already uses cmake for httpd, apr, and perhaps other
    packages.  A dynamic build of nghttp2 using its normal Windows build
    system should also be usable by nghttp2.
    
    How to build
    ------------
    
    1. cd to a clean directory for building (i.e., don't build in your
       source tree)
    
    2. Make sure cmake and Perl are in PATH.  Additionally, some backends 
       require compile tools in PATH.  (Hint: "Visual Studio Command Prompt")
    
    3. cmake -G "some backend, like 'NMake Makefiles'"
         -DCMAKE_INSTALL_PREFIX=d:/path/to/httpdinst
         -DENABLE_foo=A|I|O|a|i
         -DENABLE_MODULES=A|I|O|a|i
         d:/path/to/httpdsource
    
       Alternately, you can use the cmake-gui and update settings in the GUI.
    
       PCRE_INCLUDE_DIR, PCRE_LIBRARIES, APR_INCLUDE_DIR, APR_LIBRARIES,
         NGHTTP2_INCLUDE_DIR, NGHTTP2_LIBRARIES:
    
           cmake doesn't bundle FindXXX for these packages, so the crucial
           information has to be specified in this manner if they aren't found
           in their default location.
    
         -DPCRE_INCLUDE_DIR=d:/path/to/pcreinst/include
         -DPCRE_LIBRARIES=d:/path/to/pcreinst/lib/pcre[d].lib
    
           These will have to be specified only if PCRE is installed to a different
           directory than httpd, or if debug *and* release builds of PCRE were
           installed there and you want to control which is used.  (Currently the
           build will use pcred.lib (debug) if it is found in the default location
           and not overridden with -DPCRE_LIBRARIES.)
    
         -DAPR_INCLUDE_DIR=d:/path/to/aprinst/include
         -DAPR_LIBRARIES="d:/path/to/aprinst/lib/libapr-1.lib;d:/path/to/aprinst/lib/libaprutil-1.lib"
    
           These will have to be specified if APR[-Util] was installed to a
           different directory than httpd.
    
           When building with APR trunk (future APR 2.x, with integrated APR-Util),
           specify just the path to libapr-2.lib:
    
               -DAPR_LIBRARIES=d:/path/to/aprinst/lib/libapr-2.lib
    
           APR+APR-Util 1.x vs. APR trunk will be detected automatically if they
           are installed to the same location as httpd.
    
           APR-Util 1.x has an optional LDAP library.  If APR-Util has LDAP enabled
           and httpd's mod_ldap and mod_authnz_ldap are being used, include the
           path to the LDAP library in the APR_LIBRARIES setting.  (If APR and
           APR-Util are found in the default location, the LDAP library will be
           included if it is present.
    
         -DNGHTTP2_INCLUDE_DIR=d:/path/to/nghttp2inst/include  (which has nghttp2/*.h)
         -DNGHTTP2_LIBRARIES="d:/path/to/nghttp2inst/lib/nghttp2.lib"
    
           These will have to be specified if nghttp2 was installed to a different
           directory than httpd.
    
       LIBXML2_ICONV_INCLUDE_DIR, LIBXML2_ICONV_LIBRARIES
    
          If using a module that requires libxml2 *and* the build of libxml2 requires
          iconv, set these variables to allow iconv includes and libraries to be
          used.  For example:
    
          -DLIBXML2_ICONV_INCLUDE_DIR=c:\iconv-1.9.2.win32\include
          -DLIBXML2_ICONV_LIBRARIES=c:\iconv-1.9.2.win32\lib\iconv.lib
    
       CMAKE_C_FLAGS_RELEASE, _DEBUG, _RELWITHDEBINFO, _MINSIZEREL
       CMAKE_BUILD_TYPE
    
           For NMake Makefiles the choices are at least DEBUG, RELEASE,
           RELWITHDEBINFO, and MINSIZEREL
           Other backends may have other selections.
    
       ENABLE_foo:
    
           Each module has a default setting which can be overridden with one of
           the following values:
               A        build and Activate module
               a        build and Activate module IFF prereqs are available; if
                        prereqs are unavailable, don't build it
               I        build module but leave it Inactive (commented-out
                        LoadModule directive)
               i        build module but leave it Inactive IFF prereqs are
                        available; if prereqs are unavailable, don't build it
               O        Omit module completely
    
           Examples: -DENABLE_ACCESS_COMPAT=O
                     -DENABLE_PROXY_HTML=i
    
       ENABLE_MODULES:
    
           This changes the *minimum* enablement of all modules to the specified
           value (one of A, a, I, i, O, as described under ENABLE_foo above).
    
           The ranking of enablement from lowest to highest is O, i, I, a, A.
           If a specific module has a higher rank enablement setting, either from
           a built-in default or from -DENABLE_foo, ENABLE_MODULES won't affect
           that module.  However, if a specific module has a lower-rank enablement
           setting, presumably from a built-in default, the value of ENABLE_MODULES
           will be used for that module.
    
           Explanations for possible values:
    
           -DENABLE_MODULES=a      build and activate all possible modules,
                                   ignoring any with missing prereqs
                                   (doesn't affect modules with A for ENABLE_foo)
    
           -DENABLE_MODULES=i      build but leave inactive all possible
                                   modules, ignoring any with missing
                                   prereqs
                                   (doesn't affect modules with A, a, or I for 
                                   ENABLE_foo)
    
           -DENABLE_MODULES=O      no impact, since all modules are either
                                   already disabled or have a higher setting
    
           -DENABLE_MODULES=A      build and activate all possible modules,
                                   failing the build if any module is missing
                                   a prereq
    
           -DENABLE_MODULES=I      similar to -DENABLE_MODULES=A
                                   (doesn't affect modules with A or a for
                                   ENABLE_foo)
    
       WITH_MODULES:
    
           Comma-separated paths to single file modules to statically linked into
           the server, like the --with-module=modpath:/path/to/mod_foo.c with
           the autoconf-based build.  Key differences: The modpath (e.g., 
           "generators") isn't provided or used, and the copy of the module
           source being built is automatically updated when it changes.
           See also EXTRA_COMPILE_FLAGS, EXTRA_INCLUDES, and EXTRA_LIBS.
    
       EXTRA_COMPILE_FLAGS:
    
           Space-delimited compile flags to define with the build.
    
       EXTRA_INCLUDES:
    
           List of additional directories to search for .h files.  This may
           be necessary when including third-party modules in the httpd build
           via WITH_MODULES.
    
       EXTRA_LIBS:
    
           List of additional libraries to link with.  This may be necessary when
           including third-party modules in the httpd build via WITH_MODULES.
    
       Port and SSLPort:
    
           Port numbers for substitution into default .conf files.  (The defaults
           are 80 and 443.)
    
       INSTALL_PDB:
    
           If .pdb files are generated for debugging, install them.
           Default: ON
    
           The .pdb files are generally needed for debugging low-level code
           problems.  If they aren't installed, they are still available in the
           build directory for use by alternate packaging implementations or when
           debugging on the build machine.
    
       INSTALL_MANUAL:
    
           Install the Apache HTTP Server manual.
           Default: ON
    
           This could be turned off when developing changes in order to speed up
           installation time.
    
    4. Build using the chosen generator (e.g., "nmake install" for cmake's "NMake
       Makefiles" generator).
    
    Running the server and support programs
    ---------------------------------------
    
    This build system does not copy binaries such as dlls from other projects
    into the httpd install location.  Without taking some precautions, httpd
    and support programs can fail to start or modules can fail to load because
    a support library can't be found in PATH or in the directory of the httpd
    binary.
    
    This can be resolved in several different ways:
    
    * Install httpd and the various support libraries to a common install
      prefix so that support libraries and httpd programs are installed in
      the same bin directory and are found without setting PATH.
    
    * Update PATH to include the bin directories of all necessary support
      libraries.
    
      Depending on where PATH is set, it may not affect starting httpd as
      a service.
    
    * Maintain a script which combines required binaries into a common 
      location, such as the httpd installion bin directory, and use that
      script after building or otherwise installing or updating support
      libraries.
    
    * AVOID THE USE of any unrepeatable process of copying dll files around
      from different install locations until something starts working.  The
      result is that when you later update a support library to pick up a
      security fix, httpd will likely continue to use the old, vulnerable
      library file.
    
    Known Bugs and Limitations
    --------------------------
    
    * no standard script or makefile is provided to tie together the builds
      of httpd and support libraries in a manner suitable for typical users
    * no logic to find support libraries or otherwise build these modules:
      + mod_socache_dc (requires distcache), mod_serf (requires serf)
      + additionally, mod_firehose doesn't compile on Windows anyway
    * buildmark.c isn't necessarily rebuilt when httpd.exe is regenerated
    * ApacheMonitor has a build error and is disabled
    * CGI examples aren't installed
    * dbmmanage.pl and wintty aren't built/installed
    * module enablement defaults are not in sync with the autoconf-based build
    * no support for static support library builds; unclear if that is a
      requirement; if so: taking PCRE as an example, we'd need to detect that it
      is static and then turn on PCRE_STATIC for the libhttpd build
    
    Generally:
    
    * Many httpd features have not been tested with this build.
    * Developers need to examine the existing Windows build in great detail and see
      what is missing from the cmake-based build, whether a feature or some build
      nuance.
    * Any feedback you can provide on your experiences with this build will be
      helpful.
    �����������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/NOTICE���������������������������������������������������������������������������������0000664�0001751�0001751�00000001321�14744525602�013534� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Apache HTTP Server
    Copyright 2025 The Apache Software Foundation.
    
    This product includes software developed at
    The Apache Software Foundation (https://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).
    
    This software contains code derived from the PCRE library pcreposix.c
    source code, written by Philip Hazel, Copyright 1997-2004
    by the University of Cambridge, England.
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/������������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�013256� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/unix/�������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014241� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/unix/unixd.h������������������������������������������������������������������������0000664�0001751�0001751�00000010214�13114242336�015523� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  unixd.h
     * @brief common stuff that unix MPMs will want
     *
     * @addtogroup APACHE_OS_UNIX
     * @{
     */
    
    #ifndef UNIXD_H
    #define UNIXD_H
    
    #include "httpd.h"
    #include "http_config.h"
    #include "scoreboard.h"
    #include "ap_listen.h"
    #ifdef HAVE_SYS_TIME_H
    #include <sys/time.h>
    #endif
    #ifdef HAVE_SYS_RESOURCE_H
    #include <sys/resource.h>
    #endif
    #include "apr_hooks.h"
    #include "apr_thread_proc.h"
    #include "apr_proc_mutex.h"
    #include "apr_global_mutex.h"
    
    #include <pwd.h>
    #include <grp.h>
    #if APR_HAVE_SYS_TYPES_H
    #include <sys/types.h>
    #endif
    #ifdef HAVE_SYS_IPC_H
    #include <sys/ipc.h>
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #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))
    
    
    /* 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;
        const char *group_name;
        uid_t user_id;
        gid_t group_id;
        int suexec_enabled;
        const char *chroot_dir;
        const char *suexec_disabled_reason; /* suitable msg if !suexec_enabled */
    } unixd_config_rec;
    AP_DECLARE_DATA extern unixd_config_rec ap_unixd_config;
    
    #if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS)
    AP_DECLARE(void) ap_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) ap_unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex);
    AP_DECLARE(apr_status_t) ap_unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex);
    AP_DECLARE(apr_status_t) ap_unixd_accept(void **accepted, ap_listen_rec *lr, apr_pool_t *ptrans);
    
    #ifdef HAVE_KILLPG
    #define ap_unixd_killpg(x, y)   (killpg ((x), (y)))
    #define ap_os_killpg(x, y)      (killpg ((x), (y)))
    #else /* HAVE_KILLPG */
    #define ap_unixd_killpg(x, y)   (kill (-(x), (y)))
    #define ap_os_killpg(x, y)      (kill (-(x), (y)))
    #endif /* HAVE_KILLPG */
    
    typedef struct {
        void            *baton;  /* MPM's */
    
        /* volatile because they're updated from signals' handlers */
        int volatile    mpm_state;
        int volatile    shutdown_pending;
        int volatile    restart_pending;
        int volatile    is_ungraceful;
    
        ap_generation_t my_generation;
        int             module_loads;
        int             was_graceful;
    
        /*
         * Current number of listeners buckets and maximum reached across
         * restarts (to size retained data according to dynamic num_buckets,
         * eg. idle_spawn_rate).
         */
        int num_buckets, max_buckets;
    } ap_unixd_mpm_retained_data;
    
    AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data(void);
    AP_DECLARE(void) ap_unixd_mpm_set_signals(apr_pool_t *pconf, int once_process);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    /** @} */
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/unix/os.h���������������������������������������������������������������������������0000664�0001751�0001751�00000003204�11637145452�015027� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file unix/os.h
     * @brief 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
     *
     * @defgroup APACHE_OS_UNIX unix
     * @ingroup  APACHE_OS
     * @{
     */
    
    #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 1
    
    /* Define command-line rewriting for this platform, handled by core.
     */
    #define AP_PLATFORM_REWRITE_ARGS_HOOK ap_mpm_rewrite_args
    
    #ifdef _OSD_POSIX
    pid_t os_fork(const char *user);
    #endif
    
    #endif  /* !APACHE_OS_H */
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/unix/unixd.c������������������������������������������������������������������������0000664�0001751�0001751�00000053701�14557153357�015546� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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"
    #include "http_config.h"
    #include "http_main.h"
    #include "http_core.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_signal.h"
    #include "apr_strings.h"
    #include "apr_portable.h"
    #ifdef HAVE_PWD_H
    #include <pwd.h>
    #endif
    #ifdef HAVE_SYS_RESOURCE_H
    #include <sys/resource.h>
    #endif
    /* XXX */
    #include <sys/stat.h>
    #ifdef HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #ifdef HAVE_GRP_H
    #include <grp.h>
    #endif
    #ifdef HAVE_STRINGS_H
    #include <strings.h>
    #endif
    #ifdef HAVE_SYS_SEM_H
    #include <sys/sem.h>
    #endif
    #ifdef HAVE_SYS_PRCTL_H
    #include <sys/prctl.h>
    #endif
    
    unixd_config_rec ap_unixd_config;
    
    APLOG_USE_MODULE(core);
    
    AP_DECLARE(void) ap_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, APLOGNO(02172)
                         "%s: getrlimit failed", cmd->cmd->name);
            return;
        }
    
        if (*(str = ap_getword_conf(cmd->temp_pool, &arg)) != '\0') {
            if (!strcasecmp(str, "max")) {
                cur = limit->rlim_max;
            }
            else {
                cur = atol(str);
            }
        }
        else {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, APLOGNO(02173)
                         "Invalid parameters for %s", cmd->cmd->name);
            return;
        }
    
        if (arg2 && (*(str = ap_getword_conf(cmd->temp_pool, &arg2)) != '\0')) {
            max = atol(str);
        }
    
        /* if we aren't running as root, cannot increase max */
        if (geteuid()) {
            limit->rlim_cur = cur;
            if (max && (max > limit->rlim_max)) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, APLOGNO(02174)
                             "Must be uid 0 to raise maximum %s", cmd->cmd->name);
            }
            else if (max) {
                limit->rlim_max = max;
            }
        }
        else {
            if (cur) {
                limit->rlim_cur = cur;
            }
            if (max) {
                limit->rlim_max = max;
            }
        }
    #else
    
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, APLOGNO(02175)
                     "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 (!ap_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;
        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) ap_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 = { { 0 } };
    
                apr_os_proc_mutex_get(&ospmutex, pmutex);
                buf.sem_perm.uid = ap_unixd_config.user_id;
                buf.sem_perm.gid = ap_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, ap_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) ap_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 ap_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 ap_unixd_set_proc_mutex_perms(gmutex);
    #endif /* APR_PROC_MUTEX_IS_GLOBAL */
    }
    
    AP_DECLARE(apr_status_t) ap_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, ap_server_conf, APLOGNO(02176)
                             "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, APLOGNO(02177)
                             "apr_socket_accept: giving up.");
                return APR_EGENERAL;
    #endif /*ENETDOWN*/
    
            default:
                /* If the socket has been closed in ap_close_listeners()
                 * by the restart/stop action, we may get EBADF.
                 * Do not print an error in this case.
                 */
                if (!lr->active) {
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, status, ap_server_conf, APLOGNO(02178)
                                 "apr_socket_accept failed for inactive listener");
                    return status;
                }
                ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, APLOGNO(02179)
                             "apr_socket_accept: (client socket)");
                return APR_EGENERAL;
        }
        return status;
    }
    
    
    /* Unixes MPMs' */
    
    static ap_unixd_mpm_retained_data *retained_data = NULL;
    static apr_status_t retained_data_cleanup(void *unused)
    {
        (void)unused;
        retained_data = NULL;
        return APR_SUCCESS;
    }
    
    AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data(void)
    {
        if (!retained_data) {
            retained_data = ap_retained_data_create("ap_unixd_mpm_retained_data",
                                                    sizeof(*retained_data));
            apr_pool_pre_cleanup_register(ap_pglobal, NULL, retained_data_cleanup);
            retained_data->mpm_state = AP_MPMQ_STARTING;
        }
        return retained_data;
    }
    
    static void sig_term(int sig)
    {
        if (!retained_data) {
            /* Main process (ap_pglobal) is dying */
            return;
        }
        retained_data->mpm_state = AP_MPMQ_STOPPING;
        if (retained_data->shutdown_pending
                && (retained_data->is_ungraceful
                    || sig == AP_SIG_GRACEFUL_STOP)) {
            /* Already handled */
            return;
        }
    
        retained_data->shutdown_pending = 1;
        if (sig != AP_SIG_GRACEFUL_STOP) {
            retained_data->is_ungraceful = 1;
        }
    }
    
    static void sig_restart(int sig)
    {
        if (!retained_data) {
            /* Main process (ap_pglobal) is dying */
            return;
        }
        retained_data->mpm_state = AP_MPMQ_STOPPING;
        if (retained_data->restart_pending
                && (retained_data->is_ungraceful
                    || sig == AP_SIG_GRACEFUL)) {
            /* Already handled */
            return;
        }
    
        retained_data->restart_pending = 1;
        if (sig != AP_SIG_GRACEFUL) {
            retained_data->is_ungraceful = 1;
        }
    }
    
    static apr_status_t unset_signals(void *unused)
    {
        if (!retained_data) {
            /* Main process (ap_pglobal) is dying */
            return APR_SUCCESS;
        }
        retained_data->shutdown_pending = retained_data->restart_pending = 0;
        retained_data->was_graceful = !retained_data->is_ungraceful;
        retained_data->is_ungraceful = 0;
    
        return APR_SUCCESS;
    }
    
    static void ap_terminate(void)
    {
        ap_main_state = AP_SQ_MS_EXITING;
        apr_pool_destroy(ap_pglobal);
        apr_terminate();
    }
    
    AP_DECLARE(void) ap_unixd_mpm_set_signals(apr_pool_t *pconf, int one_process)
    {
    #ifndef NO_USE_SIGACTION
        struct sigaction sa;
    #endif
    
        if (!one_process) {
            ap_fatal_signal_setup(ap_server_conf, pconf);
        }
        else if (!ap_retained_data_get("ap_unixd_mpm_one_process_cleanup")) {
            /* In one process mode (debug), httpd will exit immediately when asked
             * to (SIGTERM/SIGINT) and never restart. We still want the cleanups to
             * run though (such that e.g. temporary files/IPCs don't leak on the
             * system), so the first time around we use atexit() to cleanup after
             * ourselves.
             */
            ap_retained_data_create("ap_unixd_mpm_one_process_cleanup", 1);
            atexit(ap_terminate);
        }
    
        /* Signals' handlers depend on retained data */
        (void)ap_unixd_mpm_get_retained_data();
    
    #ifndef NO_USE_SIGACTION
        memset(&sa, 0, sizeof sa);
        sigemptyset(&sa.sa_mask);
    
    #ifdef SIGPIPE
        sa.sa_handler = SIG_IGN;
        if (sigaction(SIGPIPE, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00269)
                         "sigaction(SIGPIPE)");
    #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, APLOGNO(00267)
                         "sigaction(SIGXCPU)");
    #endif
    #ifdef SIGXFSZ
        /* For systems following the LFS standard, ignoring SIGXFSZ allows
         * a write() beyond the 2GB limit to fail gracefully with E2BIG
         * rather than terminate the process. */
        sa.sa_handler = SIG_IGN;
        if (sigaction(SIGXFSZ, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00268)
                         "sigaction(SIGXFSZ)");
    #endif
    
        sa.sa_handler = sig_term;
        if (sigaction(SIGTERM, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00264)
                         "sigaction(SIGTERM)");
    #ifdef SIGINT
        if (sigaction(SIGINT, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00266)
                         "sigaction(SIGINT)");
    #endif
    #ifdef AP_SIG_GRACEFUL_STOP
        if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00265)
                         "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
    #endif
    
        /* Don't catch restart signals in ONE_PROCESS mode :) */
        if (!one_process) {
            sa.sa_handler = sig_restart;
            if (sigaction(SIGHUP, &sa, NULL) < 0)
                ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00270)
                             "sigaction(SIGHUP)");
            if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
                ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00271)
                             "sigaction(" AP_SIG_GRACEFUL_STRING ")");
        }
    
    #else  /* NO_USE_SIGACTION */
    
    #ifdef SIGPIPE
        apr_signal(SIGPIPE, SIG_IGN);
    #endif /* SIGPIPE */
    #ifdef SIGXCPU
        apr_signal(SIGXCPU, SIG_DFL);
    #endif /* SIGXCPU */
    #ifdef SIGXFSZ
        apr_signal(SIGXFSZ, SIG_IGN);
    #endif /* SIGXFSZ */
    
        apr_signal(SIGTERM, sig_term);
    #ifdef AP_SIG_GRACEFUL_STOP
        apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
    #endif /* AP_SIG_GRACEFUL_STOP */
    
        if (!one_process) {
            /* Don't restart in ONE_PROCESS mode :) */
    #ifdef SIGHUP
            apr_signal(SIGHUP, sig_restart);
    #endif /* SIGHUP */
    #ifdef AP_SIG_GRACEFUL
            apr_signal(AP_SIG_GRACEFUL, sig_restart);
    #endif /* AP_SIG_GRACEFUL */
        }
    
    #endif /* NO_USE_SIGACTION */
    
        apr_pool_cleanup_register(pconf, NULL, unset_signals,
                                  apr_pool_cleanup_null);
    }
    
    
    #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;
    
    /* 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, APLOGNO(02180)
                         "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, ap_server_conf,
                             APLOGNO(02181) "ufork: Possible mis-configuration "
                             "for user %s - Aborting.", user);
                exit(1);
            }
            break;
    
          default:
            pid = 0;
            break;
        }
    
        return pid;
    }
    
    #endif /* _OSD_POSIX */
    
    ���������������������������������������������������������������httpd-2.4.64/os/unix/config.m4����������������������������������������������������������������������0000664�0001751�0001751�00000000240�10150161574�015731� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/unix/Makefile.in��������������������������������������������������������������������0000664�0001751�0001751�00000000140�10150161574�016266� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    LTLIBRARY_NAME    = libos.la
    LTLIBRARY_SOURCES = unixd.c
    
    include $(top_srcdir)/build/ltlib.mk
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014220� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/util_win32.c������������������������������������������������������������������0000664�0001751�0001751�00000006375�14037675642�016401� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "ap_mpm.h"
    
    #include <stdarg.h>
    #include <time.h>
    #include <stdlib.h>
    
    
    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);
    }
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/os.h��������������������������������������������������������������������������0000664�0001751�0001751�00000010564�14037675642�015023� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file win32/os.h
     * @brief 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
     *
     * @defgroup APACHE_OS_WIN32 win32
     * @ingroup  APACHE_OS
     * @{
     */
    
    #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 <io.h>
    #include <fcntl.h>
    
    #ifdef _WIN64
    #define PLATFORM "Win64"
    #else
    #define PLATFORM "Win32"
    #endif
    
    /* Define command-line rewriting for this platform, handled by core.
     * For Windows, this is currently handled inside the WinNT MPM.
     * XXX To support a choice of MPMs, extract common platform behavior
     * into a function specified here.
     */
    #define AP_PLATFORM_REWRITE_ARGS_HOOK NULL
    
    /* going away shortly... */
    #define HAVE_DRIVE_LETTERS
    #define HAVE_UNC_PATHS
    #define CASE_BLIND_FILESYSTEM
    
    #include <stddef.h>
    #include <stdlib.h> /* for exit() */
    
    #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);
    
    #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; \
        static APR_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 */
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/modules.c���������������������������������������������������������������������0000664�0001751�0001751�00000003244�11573243040�016023� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
     */
    
    #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, /* core must come first */
      &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
    };
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/ap_regkey.c�������������������������������������������������������������������0000664�0001751�0001751�00000050165�12757564422�016344� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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;
    }
    
    
    static 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, (LPDWORD)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, (LPDWORD)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, (LPDWORD)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, (LPDWORD)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;
        apr_int32_t 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;
    
            /* ###: 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 possibility 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 */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/win32_config_layout.h���������������������������������������������������������0000664�0001751�0001751�00000002272�11544014604�020244� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file win32/win32_config_layout.h
     * @brief This provides layout definitions for non-autoconf-based Windows
     * builds, and is copied to include/ap_config_layout.h during the build.
     */
    
    #ifndef AP_CONFIG_LAYOUT_H
    #define AP_CONFIG_LAYOUT_H
    
    /* Check for definition of DEFAULT_REL_RUNTIMEDIR */
    #ifndef DEFAULT_REL_RUNTIMEDIR
    #define DEFAULT_REL_RUNTIMEDIR "logs"
    #endif
    
    #endif /* AP_CONFIG_LAYOUT_H */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/BaseAddr.ref������������������������������������������������������������������0000664�0001751�0001751�00000015534�13446306656�016375� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������; 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    0x000E0000
    mod_auth_basic.so           0x6FFE0000    0x00020000
    mod_auth_digest.so          0x70000000    0x00020000
    mod_cern_meta.so            0x70020000    0x00010000
    mod_expires.so              0x70030000    0x00010000
    mod_headers.so              0x70040000    0x00020000
    mod_info.so                 0x70060000    0x00020000
    mod_rewrite.so              0x70080000    0x00030000
    mod_speling.so              0x700B0000    0x00010000
    mod_status.so               0x700C0000    0x00020000
    mod_usertrack.so            0x700E0000    0x00010000
    mod_file_cache.so           0x700F0000    0x00020000
    mod_unique_id.so            0x70110000    0x00010000
    mod_vhost_alias.so          0x70120000    0x00010000
    mod_mime_magic.so           0x70130000    0x00020000
    mod_dav.so                  0x70150000    0x00040000
    mod_dav_fs.so               0x70190000    0x00030000
    mod_proxy_connect.so        0x701C0000    0x00020000
    mod_proxy_ftp.so            0x701E0000    0x00020000
    mod_proxy_http.so           0x70200000    0x00020000
    mod_ssl.so                  0x70220000    0x00070000
    mod_actions.so              0x70290000    0x00010000
    mod_alias.so                0x702A0000    0x00020000
    mod_asis.so                 0x702C0000    0x00010000
    mod_autoindex.so            0x702D0000    0x00020000
    mod_cgi.so                  0x702F0000    0x00020000
    mod_dir.so                  0x70310000    0x00010000
    mod_env.so                  0x70320000    0x00010000
    mod_imagemap.so             0x70330000    0x00020000
    mod_include.so              0x70350000    0x00030000
    mod_isapi.so                0x70380000    0x00020000
    mod_log_config.so           0x703A0000    0x00020000
    mod_mime.so                 0x703C0000    0x00020000
    mod_negotiation.so          0x703E0000    0x00020000
    mod_setenvif.so             0x70400000    0x00020000
    mod_userdir.so              0x70420000    0x00010000
    mod_cache.so                0x70430000    0x00030000
    mod_cache_disk.so           0x70460000    0x00020000
    mod_buffer.so               0x70480000    0x00010000
    mod_deflate.so              0x70490000    0x00020000
    mod_ext_filter.so           0x704B0000    0x00020000
    mod_charset_lite.so         0x704D0000    0x00010000
    mod_authn_anon.so           0x704E0000    0x00010000
    mod_authn_dbm.so            0x704F0000    0x00010000
    mod_authn_file.so           0x70500000    0x00010000
    mod_authz_dbm.so            0x70510000    0x00010000
    mod_authz_groupfile.so      0x70520000    0x00010000
    mod_authz_host.so           0x70530000    0x00010000
    mod_authz_user.so           0x70540000    0x00010000
    mod_logio.so                0x70550000    0x00010000
    mod_ldap.so                 0x70560000    0x00030000
    mod_authnz_ldap.so          0x70590000    0x00020000
    mod_ident.so                0x705B0000    0x00010000
    mod_proxy_ajp.so            0x705C0000    0x00020000
    mod_proxy_balancer.so       0x705E0000    0x00020000
    mod_log_forensic.so         0x70600000    0x00010000
    mod_version.so              0x70610000    0x00010000
    mod_bucketeer.so            0x70620000    0x00010000
    mod_dumpio.so               0x70630000    0x00010000
    mod_echo.so                 0x70640000    0x00010000
    mod_authn_dbd.so            0x70650000    0x00010000
    mod_dbd.so                  0x70660000    0x00020000
    mod_proxy.so                0x70680000    0x00040000
    mod_access_compat.so        0x706C0000    0x00010000
    mod_authz_core.so           0x706D0000    0x00020000
    mod_proxy_fcgi.so           0x706F0000    0x00020000
    mod_authn_core.so           0x70710000    0x00010000
    mod_authz_dbd.so            0x70720000    0x00010000
    mod_authz_owner.so          0x70730000    0x00010000
    mod_example_hooks.so        0x70740000    0x00020000
    mod_case_filter.so          0x70760000    0x00010000
    mod_case_filter_in.so       0x70770000    0x00010000
    mod_substitute.so           0x70780000    0x00020000
    mod_filter.so               0x707A0000    0x00020000
    mod_dav_lock.so             0x707C0000    0x00020000
    mod_auth_form.so            0x707E0000    0x00020000
    mod_example_ipc.so          0x70800000    0x00010000
    mod_request.so              0x70810000    0x00010000
    mod_session.so              0x70830000    0x00020000
    mod_session_cookie.so       0x70850000    0x00010000
    mod_session_crypto.so       0x70860000    0x00020000
    mod_session_dbd.so          0x70880000    0x00020000
    mod_socache_dbm.so          0x708A0000    0x00020000
    mod_socache_dc.so           0x708C0000    0x00010000
    mod_socache_memcache.so     0x708D0000    0x00010000
    mod_socache_shmcb.so        0x708E0000    0x00020000
    mod_sed.so                  0x70900000    0x00020000
    mod_lua.so                  0x70920000    0x00040000
    mod_ratelimit.so            0x70960000    0x00010000
    mod_remoteip.so             0x70970000    0x00010000
    mod_lbmethod_bybusyness.so  0x70980000    0x00010000
    mod_lbmethod_byrequests.so  0x70990000    0x00010000
    mod_lbmethod_bytraffic.so   0x709A0000    0x00010000
    mod_lbmethod_heartbeat.so   0x709B0000    0x00020000
    mod_heartbeat.so            0x709D0000    0x00010000
    mod_heartmonitor.so         0x709E0000    0x00020000
    mod_watchdog.so             0x70A00000    0x00020000
    mod_proxy_scgi.so           0x70A20000    0x00020000
    mod_reqtimeout.so           0x70A40000    0x00020000
    mod_reflector.so            0x70A60000    0x00010000
    mod_slotmem_plain.so        0x70A70000    0x00010000
    mod_slotmem_shm.so          0x70A80000    0x00020000
    mod_authn_socache.so        0x70AA0000    0x00020000
    mod_proxy_express.so        0x70AC0000    0x00010000
    mod_log_debug.so            0x70AD0000    0x00010000
    mod_proxy_html.so           0x70AE0000    0x00020000
    mod_xml2enc.so              0x70B00000    0x00020000
    mod_data.so                 0x70B20000    0x00010000
    mod_allowmethods.so         0x70B30000    0x00010000
    mod_macro.so                0x70B40000    0x00020000
    mod_cache_socache.so        0x70B60000    0x00020000
    mod_proxy_wstunnel.so       0x70B80000    0x00020000
    mod_dialup.so               0x70BA0000    0x00010000
    mod_optional_fn_export.so   0x70BB0000    0x00010000
    mod_optional_fn_import.so   0x70BC0000    0x00010000
    mod_optional_hook_export.so 0x70BD0000    0x00010000
    mod_optional_hook_import.so 0x70BE0000    0x00010000
    mod_authnz_fcgi.so          0x70BF0000    0x00020000
    mod_proxy_hcheck.so         0x70C10000    0x00020000
    mod_proxy_http2.so          0x70C30000    0x00020000
    mod_http2.so                0x70C50000    0x00040000
    mod_brotli.so               0x70C90000    0x000C0000
    mod_md.so                   0x70D50000    0x00030000
    mod_proxy_uwsgi.so          0x70D80000    0x00020000
    mod_socache_redis.so        0x70DA0000    0x00010000��������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/win32/Makefile.in�������������������������������������������������������������������0000664�0001751�0001751�00000000173�10471411046�016251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    LTLIBRARY_NAME    = libos.la
    LTLIBRARY_SOURCES = util_win32.c ap_regkey.c modules.c
    
    include $(top_srcdir)/build/ltlib.mk
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/bs2000/�����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014164� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/bs2000/ebcdic.h���������������������������������������������������������������������0000664�0001751�0001751�00000002433�10455005461�015535� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  bs2000/ebcdic.h
     * @brief EBCDIC/ASCII converson function declarations
     *
     * @addtogroup APACHE_OS_BS2000
     * @{
     */
    
    #include <sys/types.h>
    
    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);
    /** @} */
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/bs2000/os.c�������������������������������������������������������������������������0000664�0001751�0001751�00000007501�12402343253�014737� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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
    
    APLOG_USE_MODULE(core);
    
    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;
    
    /* 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, APLOGNO(02170)
                         "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, ap_server_conf,
                             APLOGNO(02171) "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 */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/bs2000/ebcdic.c���������������������������������������������������������������������0000664�0001751�0001751�00000026736�12757564422�015562� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <Martin.Kraemer Mch.SNI.De>
    
    "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 ambiguous 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*/
    ����������������������������������httpd-2.4.64/os/bs2000/os.h�������������������������������������������������������������������������0000664�0001751�0001751�00000002534�10455005461�014747� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file bs2000/os.h
     * @brief 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
     *
     * @defgroup APACHE_OS_BS2000 bs2000
     * @ingroup  APACHE_OS
     * @{
     */
    
    #ifndef APACHE_OS_BS2000_H
    #define APACHE_OS_BS2000_H
    
    #define PLATFORM "BS2000"
    
    #include "../unix/os.h"
    
    /* Other ap_os_ routines not used by this platform */
    
    extern pid_t os_fork(const char *user);
    
    #endif /* APACHE_OS_BS2000_H */
    /** @} */
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/netware/����������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�014723� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/netware/modules.c�������������������������������������������������������������������0000664�0001751�0001751�00000006201�11573243040�016522� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 NetWare.
     * Only insert an entry for a module if it must be compiled into
     * the core server
     */
    
    
    #include "httpd.h"
    #include "http_config.h"
    
    extern module core_module;
    extern module mpm_netware_module;
    extern module http_module;
    extern module so_module;
    extern module mime_module;
    extern module authn_core_module;
    extern module authz_core_module;
    extern module authz_host_module;
    extern module negotiation_module;
    extern module include_module;
    extern module dir_module;
    extern module alias_module;
    extern module env_module;
    extern module log_config_module;
    extern module setenvif_module;
    extern module watchdog_module;
    #ifdef USE_WINSOCK
    extern module nwssl_module;
    #endif
    extern module netware_module;
    
    module *ap_prelinked_modules[] = {
      &core_module, /* core must come first */
      &mpm_netware_module,
      &http_module,
      &so_module,
      &mime_module,
      &authn_core_module,
      &authz_core_module,
      &authz_host_module,
      &negotiation_module,
      &include_module,
      &dir_module,
      &alias_module,
      &env_module,
      &log_config_module,
      &setenvif_module,
      &watchdog_module,
    #ifdef USE_WINSOCK
      &nwssl_module,
    #endif
      &netware_module,
      NULL
    };
    
    ap_module_symbol_t ap_prelinked_module_symbols[] = {
      {"core_module", &core_module},
      {"mpm_netware_module", &mpm_netware_module},
      {"http_module", &http_module},
      {"so_module", &so_module},
      {"mime_module", &mime_module},
      {"authn_core_module", &authn_core_module},
      {"authz_core_module", &authz_core_module},
      {"authz_host_module", &authz_host_module},
      {"negotiation_module", &negotiation_module},
      {"include_module", &include_module},
      {"dir_module", &dir_module},
      {"alias_module", &alias_module},
      {"env_module", &env_module},
      {"log_config_module", &log_config_module},
      {"setenvif_module", &setenvif_module},
      {"watchdog module", &watchdog_module},
    #ifdef USE_WINSOCK
      {"nwssl_module", &nwssl_module},
    #endif
      {"netware_module", &netware_module},
      {NULL, NULL}
    };
    
    module *ap_preloaded_modules[] = {
      &core_module,
      &mpm_netware_module,
      &http_module,
      &so_module,
      &mime_module,
      &authn_core_module,
      &authz_core_module,
      &authz_host_module,
      &negotiation_module,
      &include_module,
      &dir_module,
      &alias_module,
      &env_module,
      &log_config_module,
      &setenvif_module,
      &watchdog_module,
    #ifdef USE_WINSOCK
      &nwssl_module,
    #endif
      &netware_module,
      NULL
    };
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/netware/os.h������������������������������������������������������������������������0000664�0001751�0001751�00000004061�11637105701�015504� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file netware/os.h
     * @brief 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
     *
     * @defgroup APACHE_OS_NETWARE netware
     * @ingroup  APACHE_OS
     * @{
     */
    
    #ifndef APACHE_OS_H
    #define APACHE_OS_H
    
    #ifndef PLATFORM
    #define PLATFORM "NETWARE"
    #endif
    
    /* Define command-line rewriting for this platform, handled by core.
     * For Netware, this is currently handled inside the Netware MPM.
     * XXX To support a choice of MPMs, extract common platform behavior
     * into a function specified here.
     */
    #define AP_PLATFORM_REWRITE_ARGS_HOOK NULL
    
    #include <screen.h>
    
    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 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 */
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/netware/apache.xdc������������������������������������������������������������������0000664�0001751�0001751�00000000200�10150161574�016621� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BAGF������������������������������������MPK_Bag��������MT Safe NLM�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/netware/pre_nw.h��������������������������������������������������������������������0000664�0001751�0001751�00000003513�12757564422�016373� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file  pre_nw.h
     * @brief Definitions for Netware systems
     *
     * @addtogroup APACHE_OS_NETWARE
     * @{
     */
    
    #ifndef __pre_nw__
    #define __pre_nw__
    
    #include <stdint.h>
    
    #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 definition 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
    
    /* Restrict the number of nested includes */
    #define AP_MAX_INCLUDE_DEPTH    48
    
    #endif
    /** @} */
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/netware/util_nw.c�������������������������������������������������������������������0000664�0001751�0001751�00000006225�11452373610�016544� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 "ap_mpm.h"
    
    #include <netware.h>
    #include <nks/netware.h>
    #include <nks/vm.h>
    
    void ap_down_server_cb(void *, void *);
    void ap_dummy_cb(void *, void *);
    void ap_cb_destroy(void *);
    
    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 *a, void *b)
    {
        nlmUnloadSignaled(0);
        return;
    }
    
    /* Required place holder event callback */
    void ap_dummy_cb(void *a, void *b)
    {
        return;
    }
    
    /* destroy callback resources */
    void ap_cb_destroy(void *a)
    {
        /* 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);
    
        return 0;
    }
    
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/netware/netware_config_layout.h�����������������������������������������������������0000664�0001751�0001751�00000002276�11544014604�021456� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file netware/netware_config_layout.h
     * @brief This provides layout definitions for non-autoconf-based NetWare
     * builds, and is copied to include/ap_config_layout.h during the build.
     */
    
    #ifndef AP_CONFIG_LAYOUT_H
    #define AP_CONFIG_LAYOUT_H
    
    /* Check for definition of DEFAULT_REL_RUNTIMEDIR */
    #ifndef DEFAULT_REL_RUNTIMEDIR
    #define DEFAULT_REL_RUNTIMEDIR "logs"
    #endif
    
    #endif /* AP_CONFIG_LAYOUT_H */
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/os2/��������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766615�013761� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/os2/os.h����������������������������������������������������������������������������0000664�0001751�0001751�00000002537�11410123263�014540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /**
     * @file os2/os.h
     * @brief 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
     *
     * @defgroup APACHE_OS_OS2 os2
     * @ingroup  APACHE_OS
     * @{
     */
    
    #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
    #define AP_PLATFORM_REWRITE_ARGS_HOOK NULL
    
    #endif   /* ! APACHE_OS_H */
    /** @} */
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/os2/core_header.def�����������������������������������������������������������������0000664�0001751�0001751�00000000443�11245174255�016675� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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"
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/os2/config.m4�����������������������������������������������������������������������0000664�0001751�0001751�00000000101�11245174255�015453� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������if test "$OS" = "os2" ; then
      APR_ADDTO(CFLAGS, [-DOS2 -O2])
    fi
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/os2/Makefile.in���������������������������������������������������������������������0000664�0001751�0001751�00000000143�11245174255�016017� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    LTLIBRARY_NAME    = libos.la
    LTLIBRARY_SOURCES = util_os2.c
    
    include $(top_srcdir)/build/ltlib.mk
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/os2/util_os2.c����������������������������������������������������������������������0000664�0001751�0001751�00000002507�11245174255�015664� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT 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 <os2.h>
    #include "ap_config.h"
    #include "httpd.h"
    #include "http_log.h"
    #include "os.h"
    #include <sys/time.h>
    #include <sys/signal.h>
    #include <ctype.h>
    #include <string.h>
    #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);
    }
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/os2/core.mk�������������������������������������������������������������������������0000664�0001751�0001751�00000000546�11245174255�015242� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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
    ����������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/.indent.pro�������������������������������������������������������������������������0000664�0001751�0001751�00000001275�10150161574�015331� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-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
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/Makefile.in�������������������������������������������������������������������������0000664�0001751�0001751�00000000075�10150161574�015312� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    SUBDIRS = $(OS_DIR)
    
    include $(top_builddir)/build/rules.mk
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/os/config.m4���������������������������������������������������������������������������0000664�0001751�0001751�00000000476�11245174255�014767� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_MSG_CHECKING(for target platform)
    
    case $host in
    *pc-os2-emx*)
      OS="os2"
      OS_DIR=$OS
      ;;
    bs2000*)
      OS="unix"
      OS_DIR=$OS
      ;;
    *cygwin*)
      OS="cygwin"
      OS_DIR="unix"
      ;;
    *mingw32*)
      OS="win32"
      OS_DIR=$OS
      ;;
    *)
      OS="unix"
      OS_DIR=$OS;;
    esac
    
    AC_MSG_RESULT($OS)
    APACHE_FAST_OUTPUT(os/${OS_DIR}/Makefile)
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/ABOUT_APACHE���������������������������������������������������������������������������0000664�0001751�0001751�00000032270�14737240630�014432� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
                         The Apache HTTP Server Project
    
                            http://httpd.apache.org/
    
    The Apache HTTP Server 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. 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 (as 
    it was called in the early days), 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.
    
     ============================================================================
    
    The current project management committee of the Apache HTTP Server
    project (as of March, 2011) is:
    
        Aaron Bannert       André Malo              Astrid Stolper
        Ben Laurie          Bojan Smojver           Brad Nicholes
        Brian Havard        Brian McCallister       Chris Darroch
        Chuck Murcko        Colm MacCárthaigh       Dan Poirier
        Dirk-Willem van Gulik                       Doug MacEachern     
        Eric Covener        Erik Abele              Graham Dumpleton    
        Graham Leggett      Greg Ames               Greg Stein 
        Gregory Trubetskoy  Guenter Knauf           Issac Goldstand     
        Jeff Trawick        Jim Gallacher           Jim Jagielski      
        Joe Orton           Joe Schaefer            Joshua Slive
        Justin Erenkrantz   Ken Coar                Lars Eilebrecht
        Manoj Kasichainula  Marc Slemko             Mark J. Cox
        Martin Kraemer      Maxime Petazzoni        Nick Kew
        Nicolas Lehuen      Noirin Shirley          Paul Querna
        Philip M. Gollucci  Ralf S. Engelschall     Randy Kobes
        Rasmus Lerdorf      Rich Bowen              Roy T. Fielding
        Rüdiger Plüm        Sander Striker          Sander Temm
        Stefan Fritsch      Tony Stevenson          Victor J. Orlikowski
        Wilfredo Sanchez    William A. Rowe Jr.     Yoshiki Hayashi     
    
    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:
    <http://modules.apache.org/>, 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.
    
     ============================================================================
    
    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 <http://httpd.apache.org/bug_report.html>. 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 <http://httpd.apache.org/dev/>.
    
    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 <http://httpd.apache.org/userslist> 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
    svn repository.  Everyone has access to the svn 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 svn.  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 The Apache HTTP Server Is Free
    
    Apache HTTP Server 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 httpd 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 httpd 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 httpd. We would even be happy if 
    some commercial software companies completely dropped their own HTTP server
    development plans and used Apache httpd as a base, with the proper attributions
    as described in the LICENSE file.
    
    Thanks for using Apache HTTP Server!
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/configure.in���������������������������������������������������������������������������0000664�0001751�0001751�00000077373�14635307332�015162� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl
    dnl Autoconf configuration for Apache httpd
    dnl
    dnl     Use ./buildconf to produce a configure script
    dnl
    
    AC_PREREQ(2.50)
    AC_INIT(ABOUT_APACHE)
    
    AC_CONFIG_HEADER(include/ap_config_auto.h)
    AC_CONFIG_AUX_DIR(build)
    
    dnl Absolute source/build directory
    abs_srcdir=`(cd $srcdir && pwd)`
    abs_builddir=`pwd`
    
    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`
    HTTPD_MMN=`$abs_srcdir/build/get-version.sh mmn $abs_srcdir/include/ap_mmn.h MODULE_MAGIC_NUMBER`
    
    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 Later versions of autoconf (>= 2.62) by default cause the produced
    dnl configure script to emit at least warnings when it comes across unknown
    dnl command line options. These versions also have the macro
    dnl AC_DISABLE_OPTION_CHECKING defined which turns this off by default.
    dnl We want to have this turned off here since our configure calls can
    dnl contain options for APR / APR-UTIL configure that are unknown to us.
    dnl So avoid confusing the user by turning this off. See also PR 45221.
    ifdef([AC_DISABLE_OPTION_CHECKING], [AC_DISABLE_OPTION_CHECKING])
    
    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 get an EGREP to use in the Makefiles
    AC_PROG_EGREP
    APACHE_SUBST(EGREP)
    
    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"
    
    AC_MSG_NOTICE([])
    AC_MSG_NOTICE([Configuring Apache Portable Runtime library...])
    AC_MSG_NOTICE([])
    
    AC_ARG_WITH(included-apr,
    APACHE_HELP_STRING(--with-included-apr,Use bundled copies of APR/APR-Util))
    
    if test "x$with_included_apr" = "xyes"; then
      apr_found=reconfig
      if test ! -d srclib/apr && test ! -d $srcdir/srclib/apr; then
        AC_MSG_ERROR([Bundled APR requested but not found at ./srclib/. Download and unpack the corresponding apr and apr-util packages to ./srclib/.])
      fi
    else 
      APR_FIND_APR("$srcdir/srclib/apr", "./srclib/apr", 1, 1 2, [
        version=`$apr_config --version`
        case x${version} in
        x1.[[0-3]].*) 
          AC_MSG_WARN([APR version 1.4.0 or later is required, found $version])
          apr_acceptable=no
          ;;
        esac
        unset version
       ])
    fi
    
    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"
    
      dnl We have to find apr-N-config when we reconfigure APR.
      for majorver in 1 2; do
        test_apr_config="./srclib/apr/apr-${majorver}-config"
        if test -f "$test_apr_config"; then
          apr_config="$test_apr_config"
        fi
      done
    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`)
    dnl internal-only CPPFLAGS (shouldn't affect third-party module builds)
    INTERNAL_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_INCLUDES=`$apr_config --includes`
    APR_VERSION=`$apr_config --version`
    apr_major_version=`echo ${APR_VERSION} | sed 's,\..*,,'`
    APR_CONFIG="$APR_BINDIR/apr-${apr_major_version}-config"
    
    AC_MSG_NOTICE([])
    AC_MSG_NOTICE([Configuring Apache Portable Runtime Utility library...])
    AC_MSG_NOTICE([])
    
    if test "x${apr_major_version}" = "x2"; then
      apu_found=obsolete
    elif test "x$with_included_apr" = "xyes"; then
      apu_found=reconfig
      if test ! -d srclib/apr-util && test ! -d $srcdir/srclib/apr-util; then
        AC_MSG_ERROR([Bundled APR-Util requested but not found at ./srclib/. Download and unpack the corresponding apr and apr-util packages to ./srclib/.])
      fi
    else 
       dnl If httpd is buildconf'ed against an apr 2.x tree, then 1.x
       dnl isn't supported. 
       ifdef([APR_FIND_APU], [
         APR_FIND_APU("$srcdir/srclib/apr-util", "./srclib/apr-util", 
                      1, ${apr_major_version})
       ], [apu_found=no])
    fi
    
    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"
      dnl APR and APR-Util major versions must match
      apu_config="./srclib/apr-util/apu-${apr_major_version}-config"
    fi
    
    if test "$apu_found" = "obsolete"; then
      AC_MSG_NOTICE([APR-util obsoleted, woohoo])
    else
      APR_ADDTO(LDFLAGS, `$apu_config --ldflags`)
      APU_BINDIR=`$apu_config --bindir`
      APU_INCLUDEDIR=`$apu_config --includedir`
      APU_INCLUDES=`$apu_config --includes`
      APU_VERSION=`$apu_config --version`
      APU_CONFIG="$APU_BINDIR/apu-`echo ${APU_VERSION} | sed 's,\..*,,'`-config"
    fi
    
    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
    
    dnl Try to get c99 support for variadic macros
    ifdef([AC_PROG_CC_C99], [AC_PROG_CC_C99])
    
    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
    
    AC_ARG_WITH(pcre,
    APACHE_HELP_STRING(--with-pcre=PATH,Use external PCRE library))
    if test "x$with_pcre" = "x" || test "$with_pcre" = "yes"; then
      with_pcre="$PATH"
    else if which $with_pcre 2>/dev/null; then :; else
      with_pcre="$with_pcre/bin:$with_pcre"
    fi
    fi
    
    AC_CHECK_TARGET_TOOLS(PCRE_CONFIG, [pcre2-config pcre-config],
                          [`which $with_pcre 2>/dev/null`], $with_pcre)
    
    if test "x$PCRE_CONFIG" != "x"; then
      if $PCRE_CONFIG --version >/dev/null 2>&1; then :; else
        AC_MSG_ERROR([Did not find working script at $PCRE_CONFIG])
      fi
      case `$PCRE_CONFIG --version` in
      [1[0-9].*])
        AC_DEFINE(HAVE_PCRE2, 1, [Detected PCRE2]) 
        ;;
      [[1-5].*])
        AC_MSG_ERROR([Need at least pcre version 6.0])
        ;;
      esac
      AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG])
      APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`])
      APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`])
    else
      AC_MSG_ERROR([pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/])
    fi
    APACHE_SUBST(PCRE_LIBS)
    
    AC_MSG_NOTICE([])
    AC_MSG_NOTICE([Configuring Apache httpd...])
    AC_MSG_NOTICE([])
    
    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)/include])
    
    # 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_INCLUDES)
    APR_ADDTO(INCLUDES, $APU_INCLUDES)
    
    dnl Add in path to PCRE includes
    APR_ADDTO(INCLUDES, $PCRE_INCLUDES)
    
    save_CPPFLAGS="$CPPFLAGS"
    CPPFLAGS="$CPPFLAGS $PCRE_INCLUDES"
    AC_EGREP_CPP(yes,
    [
    #ifdef HAVE_PCRE2
    yes
    #else
    #include <pcre.h>
    #ifdef PCRE_DUPNAMES
    yes
    #endif
    #endif
    ],pcre_have_dupnames=yes,pcre_have_dupnames=no)
    if test "$pcre_have_dupnames" != "yes"; then
        AC_MSG_ERROR([pcre version does not support PCRE_DUPNAMES])
    fi
    CPPFLAGS="$save_CPPFLAGS"
    
    AC_MSG_NOTICE([])
    AC_MSG_NOTICE([Applying OS-specific hints for httpd...])
    AC_MSG_NOTICE([])
    
    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]]* | *[[2-9]].[[0-9]]*)
                  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)
    
    case $host in
      *-apple-aux3*)
          APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1])
          ;;
      *os2-emx*)
          APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1])
          ;;
      *-linux-*)
          case `uname -r` in
            # Unserialized accept() was not recommended until Linux 2.2.
            [[01]].* | 2.[[01]]* )
                ;;
            * )
                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(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1])
          ;;
      *mingw32*)
          APR_ADDTO(INTERNAL_CPPFLAGS, [-DAP_DECLARE_EXPORT])
          APR_SETIFNULL(ac_cv_func_times, [no])
          APR_SETIFNULL(ac_cv_func_getpwnam, [no])
          APR_SETIFNULL(ac_cv_func_getgrnam, [no])
          ;;
      *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_PATH_PROG(RSYNC, rsync)
    AC_PATH_PROG(SVN, svn)
    AC_PROG_AWK
    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])
    
    # Hard-coded install programs
    MKINSTALLDIRS="\$(abs_srcdir)/build/mkdir.sh"
    INSTALL="\$(LIBTOOL) --mode=install \$(abs_srcdir)/build/install.sh -c"
    APACHE_SUBST(MKINSTALLDIRS)
    APACHE_SUBST(INSTALL)
    
    dnl Various OS checks that apparently set required flags
    ifdef([AC_USE_SYSTEM_EXTENSIONS], [
    AC_USE_SYSTEM_EXTENSIONS
    ], [
    AC_AIX
    AC_MINIX
    ])
    
    AC_ISC_POSIX
    
    # Ensure that satisfactory versions of apr and apr-util are 
    # found if external copies are configured.
    if test "${apr_found}" = "yes"; then
      # Require at least APR 1.3.x otherwise fail
      APACHE_CHECK_APxVER([apr], 1, 3)
    fi
    
    if test "${apu_found}" = "yes"; then
      # Require at least APR-util 1.3.x otherwise fail
      if test "${apr_found}" = "yes"; then
        # we need to add the APR includes to CPPFLAGS
        apu_ckver_CPPFLAGS="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS `$apr_config --includes`"
        APACHE_CHECK_APxVER([apu], 1, 3)
        CPPFLAGS="$apu_ckver_CPPFLAGS"
      else
        APACHE_CHECK_APxVER([apu], 1, 3)
      fi
    fi
    
    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 \
    sys/sdt.h \
    sys/loadavg.h
    )
    AC_HEADER_SYS_WAIT
    
    dnl ## Check for typedefs, structures, and compiler characteristics.
    
    AC_C_CONST
    
    dnl ## Check for library functions
    dnl ## sqrt() only needed in support/ab.c
    saved_LIBS="$LIBS"
    LIBS=""
    AC_SEARCH_LIBS(sqrt, m)
    MATH_LIBS="$LIBS"
    APACHE_SUBST(MATH_LIBS)
    LIBS="$saved_LIBS"
    
    saved_LIBS="$LIBS"
    LIBS=""
    AC_SEARCH_LIBS(crypt, crypt)
    CRYPT_LIBS="$LIBS"
    APACHE_SUBST(CRYPT_LIBS)
    
    if test "$ac_cv_search_crypt" != "no"; then
       # Test crypt() with the SHA-512 test vector from https://akkadia.org/drepper/SHA-crypt.txt
       AC_CACHE_CHECK([whether crypt() supports SHA-2], [ap_cv_crypt_sha2], [
        AC_RUN_IFELSE([AC_LANG_PROGRAM([[
    #include <crypt.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define PASSWD_0 "Hello world!"
    #define SALT_0 "\$6\$saltstring"
    #define EXPECT_0 "\$6\$saltstring\$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" \
                   "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"
    ]], [char *result = crypt(PASSWD_0, SALT_0);
         if (!result) return 1;
         if (strcmp(result, EXPECT_0)) return 2;
    ])], [ap_cv_crypt_sha2=yes], [ap_cv_crypt_sha2=no], [ap_cv_crypt_sha2=no])])
       if test "$ap_cv_crypt_sha2" = yes; then
         AC_DEFINE([HAVE_CRYPT_SHA2], 1, [Define if crypt() supports SHA-2 hashes])
       fi
    fi
    
    LIBS="$saved_LIBS"
    
    dnl See Comment #Spoon
    
    AC_CHECK_FUNCS( \
    getpwnam \
    getgrnam \
    initgroups \
    bindprocessor \
    prctl \
    timegm \
    getpgid \
    fopen64 \
    getloadavg \
    gettid
    )
    
    dnl confirm that a void pointer is large enough to store a long integer
    APACHE_CHECK_VOID_PTR_LEN
    
    if test $ac_cv_func_gettid = no; then
      # On Linux before glibc 2.30, gettid() is only usable via syscall()
      AC_CACHE_CHECK([for gettid() via syscall], ap_cv_gettid,
    [AC_TRY_RUN(#define _GNU_SOURCE
    #include <unistd.h>
    #include <sys/syscall.h>
    #include <sys/types.h>
    int main(int argc, char **argv) {
    pid_t t = syscall(SYS_gettid); return t == -1 ? 1 : 0; },
      [ap_cv_gettid=yes], [ap_cv_gettid=no], [ap_cv_gettid=no])])
      if test "$ap_cv_gettid" = "yes"; then
          AC_DEFINE(HAVE_SYS_GETTID, 1, [Define if you have gettid() via syscall()])
      fi
    fi
    
    case ${host}X${ac_cv_func_gettid}X${ap_cv_gettid} in
    *linux-*XyesX* | *linux-*XnoXyes)
         AC_DEFINE(DEFAULT_LOG_TID, ["g"], [Define as default argument for thread id in error logging])
         ;;
    esac
    
    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 <sys/types.h>
    #include <time.h>], [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
    
    APACHE_CHECK_SYSTEMD
    
    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])
    
    AC_ARG_WITH(sslport,APACHE_HELP_STRING(--with-sslport=SSLPORT,Port on which to securelisten (default is 443)),
            [if test "$withval" = "yes"; then AC_MSG_ERROR('option --with-sslport requires a value (the SSL TCP port number)'); else SSLPORT="$withval"; fi],
    	[SSLPORT=443])
    
    DTRACE=true
    AC_ARG_ENABLE(dtrace,APACHE_HELP_STRING(--enable-dtrace,Enable DTrace probes),
    [
      enable_dtrace=$enableval
      if test "$enableval" = "yes"; then
        APR_ADDTO(CPPFLAGS, -DAPR_DTRACE_PROVIDER)
        AC_MSG_ERROR('DTrace Support in the build system is not complete. Patches Welcome!')
      fi
    ],
    [
      enable_dtrace=no
    ])
    
    dnl Disabled dtrace build for now.
    enable_dtrace=no
    
    case $host in
      *-solaris2*)
        if test $enable_dtrace = "yes" -a "$ac_cv_header_sys_sdt_h" = "yes"; then
            AC_DEFINE(AP_ENABLE_DTRACE, 1,
                      [Enable DTrace probes])
            DTRACE="/usr/sbin/dtrace $DTRACEFLAGS"
            test -f include/apache_probes.h || $DTRACE -h -s apache_probes.d -o include/apache_probes.h
        fi
        ;;
    esac
    
    APACHE_SUBST(DTRACE)
    
    AC_ARG_ENABLE(hook-probes,APACHE_HELP_STRING(--enable-hook-probes,Enable APR hook probes),
    [
        if test "$enableval" = "yes"; then
            AC_DEFINE(AP_HOOK_PROBES_ENABLED, 1,
                      [Enable the APR hook probes capability, reading from ap_hook_probes.h])
            APR_ADDTO(INTERNAL_CPPFLAGS, -DAP_HOOK_PROBES_ENABLED)
        fi
    ])dnl
    
    AC_ARG_ENABLE(exception-hook,APACHE_HELP_STRING(--enable-exception-hook,Enable fatal exception hook),
    [
        if test "$enableval" = "yes"; then
            AC_DEFINE(AP_ENABLE_EXCEPTION_HOOK, 1,
                      [Allow modules to run hook after a fatal exception])
        fi
    ])dnl
    
    AC_ARG_ENABLE(load-all-modules,APACHE_HELP_STRING(--enable-load-all-modules,Load all modules),
    [
      LOAD_ALL_MODULES=$enableval
      AC_MSG_NOTICE([Setting "LOAD_ALL_MODULES" to $LOAD_ALL_MODULES])
    ],
    [
      LOAD_ALL_MODULES="no"
    ])
    
    AC_ARG_ENABLE(maintainer-mode,APACHE_HELP_STRING(--enable-maintainer-mode,Turn on debugging and compile time warnings and load all compiled modules),
    [
      if test "$enableval" = "yes"; then
        APR_ADDTO(NOTEST_CPPFLAGS, -DAP_DEBUG)
        if test "$GCC" = "yes"; then
          APACHE_ADD_GCC_CFLAG([-std=c89])
          APACHE_ADD_GCC_CFLAG([-Werror])
          APACHE_ADD_GCC_CFLAG([-Wall])
          APACHE_ADD_GCC_CFLAG([-Wstrict-prototypes])
          APACHE_ADD_GCC_CFLAG([-Wmissing-prototypes])
          APACHE_ADD_GCC_CFLAG([-Wmissing-declarations])
          APACHE_ADD_GCC_CFLAG([-Wdeclaration-after-statement])
          APACHE_ADD_GCC_CFLAG([-Wpointer-arith])
          APACHE_ADD_GCC_CFLAG([-Wformat])
          APACHE_ADD_GCC_CFLAG([-Wformat-security])
          APACHE_ADD_GCC_CFLAG([-Wunused])
        elif test "$AIX_XLC" = "yes"; then
          APR_ADDTO(NOTEST_CFLAGS,-qfullpath -qcheck=all -qinfo=pro)
        fi
        if test "x$enable_load_all_modules" = "x"; then
          LOAD_ALL_MODULES=yes
          AC_MSG_NOTICE([Maintainer mode setting "LOAD_ALL_MODULES" to $LOAD_ALL_MODULES])
        fi
        if test "x$enable_bucketeer" = "x"; then
          enable_bucketeer=yes
          AC_MSG_NOTICE([Maintainer mode setting "enable_bucketeer" to yes])
        fi
      fi
    ])dnl
    
    AC_ARG_ENABLE(debugger-mode,APACHE_HELP_STRING(--enable-debugger-mode,Turn on debugging and compile time warnings and turn off optimization),
    [
      if test "$enableval" = "yes"; then
        APR_ADDTO(NOTEST_CPPFLAGS, -DAP_DEBUG)
        if test "$GCC" = "yes"; then
          APACHE_ADD_GCC_CFLAG([-O0])
          APACHE_ADD_GCC_CFLAG([-Wall])
          APACHE_ADD_GCC_CFLAG([-Wstrict-prototypes])
          APACHE_ADD_GCC_CFLAG([-Wmissing-prototypes])
          APACHE_ADD_GCC_CFLAG([-Wmissing-declarations])
          APACHE_ADD_GCC_CFLAG([-Wdeclaration-after-statement])
          APACHE_ADD_GCC_CFLAG([-Werror=declaration-after-statement])
          APACHE_ADD_GCC_CFLAG([-Wpointer-arith])
          APACHE_ADD_GCC_CFLAG([-Wformat])
          APACHE_ADD_GCC_CFLAG([-Wformat-security])
          APACHE_ADD_GCC_CFLAG([-Werror=format-security])
        elif test "$AIX_XLC" = "yes"; then
          APR_ADDTO(NOTEST_CFLAGS,-qfullpath -qinitauto=FE -qcheck=all -qinfo=pro)
        fi
      fi
    ])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
    APACHE_SUBST(PICFLAGS)
    APACHE_SUBST(PILDFLAGS)
    
    prefix="$orig_prefix"
    APACHE_ENABLE_MODULES
    
    dnl reading config stubs
    esyscmd(./build/config-stubs .)
    
    APACHE_SUBST(progname)
    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" -o "$enable_so" = "static"; then
      case $host in
        *-ibm-aix*)
          APR_ADDTO(HTTPD_LDFLAGS, [-Wl,-uXML_Parse -Wl,-bE:$abs_builddir/server/httpd.exp])
          APR_ADDTO(SH_LDFLAGS, [\$(EXTRA_LDFLAGS) \$(EXTRA_LIBS)])
          APR_ADDTO(UTIL_LDFLAGS, [-Wl,-uXML_Parse])
          ;;
        *os390)
          APR_ADDTO(HTTPD_LDFLAGS, [--main=$abs_srcdir/server/main.o --core-dll=$abs_srcdir/apachecore.dll])
          APR_ADDTO(SH_LDFLAGS, [--core-dll=$abs_srcdir/apachecore.dll])
      esac
      MOD_SO_ENABLED=yes
    fi
    AC_SUBST(MOD_SO_ENABLED)
    
    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),[
      if test "x$withval" = "xyes"; then
        AC_MSG_ERROR([log filename required for --with-suexec-logfile option])
      elif test "x$withval" != "xno"; then
        AC_DEFINE_UNQUOTED(AP_LOG_EXEC, "$withval", [SuExec log file])
      fi
    ])
    
    AC_ARG_WITH(suexec-syslog,
    APACHE_HELP_STRING(--with-suexec-syslog,Use syslog for suexec logging),[
      if test $withval = "yes"; then
        if test "x${with_suexec_logfile}" != "xno"; then
          AC_MSG_NOTICE([hint: use "--without-suexec-logfile --with-suexec-syslog"])
          AC_MSG_ERROR([suexec does not support both logging to file and syslog])
        fi
        AC_CHECK_FUNCS([vsyslog], [], [
           AC_MSG_ERROR([cannot support syslog from suexec without vsyslog()])])
        AC_DEFINE(AP_LOG_SYSLOG, 1, [SuExec log to syslog])
      fi    
    ])
    
    
    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] ) ] )
    
    INSTALL_SUEXEC=setuid
    AC_ARG_ENABLE([suexec-capabilities], 
    APACHE_HELP_STRING(--enable-suexec-capabilities,Use Linux capability bits not setuid root suexec), [
    INSTALL_SUEXEC=caps
    AC_DEFINE(AP_SUEXEC_CAPABILITIES, 1, 
              [Enable if suexec is installed with Linux capabilities, not setuid])
    ])
    APACHE_SUBST(INSTALL_SUEXEC)
    
    dnl APR should go after the other libs, so the right symbols can be picked up
    if test x${apu_found} != xobsolete; then
      AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool --libs`"
    fi
    AP_LIBS="$AP_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
    
    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
        *freebsd[[1234]].*)
            v4mapped=yes
            ;;
        *freebsd*|*netbsd*|*openbsd*)
            v4mapped=no
            ;;
        *)
            v4mapped=yes
            ;;
        esac
        if ap_mpm_is_enabled winnt; then
            dnl WinNT MPM doesn't support this.
            v4mapped=no
        fi
    ])
    
    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
    
    APACHE_FAST_OUTPUT(Makefile modules/Makefile srclib/Makefile) 
    APACHE_FAST_OUTPUT(os/Makefile server/Makefile)
    APACHE_FAST_OUTPUT(support/Makefile)
    
    if test -d ./test; then
        APACHE_FAST_OUTPUT(test/Makefile)
    fi
    if test -d ./test/modules/http2; then
        APACHE_FAST_OUTPUT(test/Makefile)
        AC_CONFIG_FILES([test/pyhttpd/config.ini])
        APACHE_FAST_OUTPUT(test/clients/Makefile)
    fi
    
    dnl ## Finalize the variables
    AC_MSG_NOTICE([])
    AC_MSG_NOTICE([Restore user-defined environment settings...])
    AC_MSG_NOTICE([])
    
    APACHE_CONF_SEL_CC=${CC}
    APACHE_CONF_SEL_CFLAGS="${CFLAGS} ${EXTRA_CFLAGS} ${NOTEST_CFLAGS}"
    APACHE_CONF_SEL_CPPFLAGS="${CPPFLAGS} ${EXTRA_CPPFLAGS} ${NOTEST_CPPFLAGS}"
    APACHE_CONF_SEL_LDFLAGS="${LDFLAGS} ${EXTRA_LDFLAGS} ${NOTEST_LDFLAGS}"
    APACHE_CONF_SEL_LIBS="${LIBS} ${EXTRA_LIBS} ${NOTEST_LIBS}"
    APACHE_CONF_SEL_CPP=${CPP}
    
    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_)
    
    AC_MSG_NOTICE([])
    AC_MSG_NOTICE([Construct makefiles and header files...])
    AC_MSG_NOTICE([])
    
    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])
    
    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
    
    AC_CONFIG_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 docs/conf/extra/proxy-html.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 build/config_vars.sh)
    AC_CONFIG_COMMANDS([default], [true], [APACHE_GEN_MAKEFILES])
    AC_OUTPUT
    AC_MSG_NOTICE([summary of build options:
    
        Server Version: ${HTTPD_VERSION}
        Install prefix: ${prefix}
        C compiler:     ${APACHE_CONF_SEL_CC}
        CFLAGS:         ${APACHE_CONF_SEL_CFLAGS}
        CPPFLAGS:       ${APACHE_CONF_SEL_CPPFLAGS}
        LDFLAGS:        ${APACHE_CONF_SEL_LDFLAGS}
        LIBS:           ${APACHE_CONF_SEL_LIBS}
        C preprocessor: ${APACHE_CONF_SEL_CPP}
    ])
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/srclib/��������������������������������������������������������������������������������0000775�0001751�0001751�00000000000�15032766627�014116� 5����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/srclib/Makefile.in���������������������������������������������������������������������0000664�0001751�0001751�00000000171�10203136130�016131� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    BUILD_SUBDIRS = $(AP_BUILD_SRCLIB_DIRS)
    CLEAN_SUBDIRS = $(AP_CLEAN_SRCLIB_DIRS)
    
    include $(top_builddir)/build/rules.mk
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/.gitignore�����������������������������������������������������������������������������0000664�0001751�0001751�00000012166�14356741666�014642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# global
    .deps
    .libs
    *.swp
    *.o
    *.a
    *.lo
    *.la
    *.slo
    *.so
    *.vcproj
    *.vcproj.*
    *.x
    *.aps
    *.plg
    *.dep
    *.rc
    *.stc
    *.stt
    *.sto
    *.mak
    Makefile
    modules.mk
    BuildLog.htm
    Debug
    Release
    
    # /
    /config.nice
    /configure
    /missing
    /install-sh
    /mkinstalldirs
    /aclocal.m4
    /generated_lists
    /buildmk.stamp
    /config.log
    /libtool
    /shlibtool
    /config.status
    /modules.c
    /config.cache
    /httpd
    /httpd.exe
    /LibD
    /LibR
    /Apache.suo
    /Apache.ncb
    /Apache.opt
    /apachecore.dll
    /Apache.sln
    /autom4te.cache
    /httpd.spec
    /tags
    /TAGS
    /*.kdev4
    /.kdev_include_paths
    /.cproject
    /.project
    
    # /built/
    /built/
    
    # /cmake-build-debug/
    /cmake-build-debug/
    
    # /build/
    /build/rules.mk
    /build/config_vars.mk
    /build/apr_common.m4
    /build/find_apr.m4
    /build/find_apu.m4
    /build/ltconfig
    /build/ltmain.sh
    /build/PrintPath
    /build/config.sub
    /build/config.guess
    /build/config_vars.sh
    
    # /build/pkg/
    /build/pkg/pkginfo
    
    # /build/win32/
    !/build/win32/httpd.rc
    
    # /docs/
    /docs/dox
    
    # /docs/conf/
    /docs/conf/httpd-std.conf
    /docs/conf/ssl-std.conf
    /docs/conf/httpd.conf
    
    # /docs/conf/extra/
    /docs/conf/extra/*.conf
    
    # /docs/log-message-tags/
    /docs/log-message-tags/list
    
    # /docs/manual/
    /docs/manual/_chm
    /docs/manual/_off
    /docs/manual/_tools
    /docs/manual/_dist
    /docs/manual/build
    /docs/manual/*.tex
    /docs/manual/*.aux
    /docs/manual/*.out
    /docs/manual/*.log
    /docs/manual/*.pdf
    /docs/manual/*.toc
    /docs/manual/.outdated*
    
    # /docs/manual/developer/
    /docs/manual/developer/*.tex
    /docs/manual/developer/*.aux
    
    # /docs/manual/faq/
    /docs/manual/faq/*.tex
    /docs/manual/faq/*.aux
    
    # /docs/manual/howto/
    /docs/manual/howto/*.aux
    /docs/manual/howto/*.tex
    /docs/manual/howto/Working-Copy.txt
    
    # /docs/manual/misc/
    /docs/manual/misc/*.tex
    /docs/manual/misc/*.aux
    
    # /docs/manual/mod/
    /docs/manual/mod/*.tex
    /docs/manual/mod/*.aux
    /docs/manual/mod/.translated.*
    
    # /docs/manual/platform/
    /docs/manual/platform/*.tex
    /docs/manual/platform/*.aux
    
    # /docs/manual/programs/
    /docs/manual/programs/*.tex
    /docs/manual/programs/*.aux
    
    # /docs/manual/rewrite/
    /docs/manual/rewrite/_chm
    /docs/manual/rewrite/_off
    /docs/manual/rewrite/_tools
    /docs/manual/rewrite/_dist
    /docs/manual/rewrite/build
    /docs/manual/rewrite/*.tex
    /docs/manual/rewrite/*.aux
    /docs/manual/rewrite/*.out
    /docs/manual/rewrite/*.log
    /docs/manual/rewrite/*.pdf
    /docs/manual/rewrite/*.toc
    /docs/manual/rewrite/.outdated*
    
    # /docs/manual/ssl/
    /docs/manual/ssl/*.tex
    /docs/manual/ssl/*.aux
    
    # /docs/manual/style/
    /docs/manual/style/_generated
    
    # /docs/manual/vhosts/
    /docs/manual/vhosts/*.tex
    /docs/manual/vhosts/*.aux
    
    # /include/
    /include/ap_config_auto.h
    /include/ap_config_auto.h.in
    /include/ap_config_layout.h
    /include/ap_ldap.h
    /include/mod_cgi.h
    /include/mod_dav.h
    /include/mod_include.h
    /include/mod_proxy.h
    /include/mod_so.h
    /include/mpm.h
    /include/mpm_default.h
    /include/os.h
    
    # /modules/aaa/
    
    # /modules/apreq/
    
    # /modules/arch/
    
    # /modules/arch/unix/
    
    # /modules/arch/win32/
    
    # /modules/cache/
    
    # /modules/cluster/
    
    # /modules/core/
    
    # /modules/core/test/
    /modules/core/test/out
    
    # /modules/database/
    
    # /modules/dav/
    
    # /modules/dav/fs/
    
    # /modules/dav/lock/
    
    # /modules/dav/main/
    
    # /modules/debugging/
    
    # /modules/echo/
    
    # /modules/examples/
    
    # /modules/experimental/
    
    # /modules/filters/
    
    # /modules/generators/
    
    # /modules/http/
    
    # /modules/http2/
    
    # /modules/ldap/
    
    # /modules/loggers/
    
    # /modules/lua/
    
    # /modules/lua/test/
    /modules/lua/test/cycle
    /modules/lua/test/httpd.conf
    
    # /modules/mappers/
    
    # /modules/md/
    /modules/md/a2md
    
    # /modules/metadata/
    
    # /modules/proxy/
    
    # /modules/proxy/balancers/
    
    # /modules/proxy/examples/
    
    # /modules/session/
    
    # /modules/slotmem/
    
    # /modules/ssl/
    
    # /modules/test/
    
    # /os/
    
    # /os/bs2000/
    
    # /os/os2/
    
    # /os/unix/
    
    # /os/win32/
    /os/win32/*.mdp
    /os/win32/*.ncb
    /os/win32/*.opt
    /os/win32/*.dsw
    /os/win32/mod_*D
    /os/win32/mod_*R
    
    # /server/
    /server/test_char.h
    /server/gen_test_char
    /server/gen_test_char.exe
    /server/gen_test_char.exe.manifest
    /server/export_files
    /server/exports.c
    /server/export_vars.h
    /server/ApacheCoreOS2.def
    /server/httpd.exp
    /server/buildmarked.c
    
    # /server/mpm/
    
    # /server/mpm/event/
    
    # /server/mpm/motorz/
    
    # /server/mpm/mpmt_os2/
    
    # /server/mpm/prefork/
    
    # /server/mpm/simple/
    
    # /server/mpm/winnt/
    
    # /server/mpm/worker/
    
    # /srclib/
    /srclib/pth
    /srclib/apr
    /srclib/apr-util
    /srclib/apr-iconv
    /srclib/distcache
    /srclib/lua
    /srclib/pcre
    /srclib/openssl
    /srclib/zlib
    
    # /support/
    /support/rotatelogs
    /support/htpasswd
    /support/htdbm
    /support/htdigest
    /support/htcacheclean
    /support/unescape
    /support/inc2shtml
    /support/httpd_monitor
    /support/suexec
    /support/logresolve
    /support/ab
    /support/apxs
    /support/apachectl
    /support/checkgid
    /support/dbmmanage
    /support/envvars-std
    /support/log_server_status
    /support/logresolve.pl
    /support/split-logfile
    /support/phf_abuse_log.cgi
    /support/httxt2dbm
    /support/fcgistarter
    /support/firehose
    /support/*.exe
    
    # /support/win32/
    !/support/win32/ApacheMonitor.rc
    /support/win32/ApacheMonitorVer.rc
    
    # /test/
    /test/a.out
    /test/time-FCNTL
    /test/time-FLOCK
    /test/time-SYSVSEM
    /test/time-SYSVSEM2
    /test/time-PTHREAD
    /test/time-USLOCK
    /test/zb
    /test/test-writev
    /test/test_date
    /test/test_select
    /test/dbu
    /test/sni
    /test/httpdunit
    /test/httpdunit.cases
    
    # /test/unit/
    /test/unit/*.tests
    
    # Intellij
    /.idea/
    
    test/gen
    test/pyhttpd/config.ini
    __pycache__
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/README���������������������������������������������������������������������������������0000664�0001751�0001751�00000011052�14373501447�013511� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
                              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 https://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
      https://httpd.apache.org/docs/2.4/.
    
      Installation
      ------------
    
      Please see the file called INSTALL.  Platform specific notes can be
      found in README.platforms.
    
      Licensing
      ---------
    
      Please see the file called LICENSE.
    
      Cryptographic Software Notice
      -----------------------------
    
      This distribution may include software that has been designed for use
      with cryptographic software.  The country in which you currently reside
      may have restrictions on the import, possession, use, and/or re-export
      to another country, of encryption software.  BEFORE using any encryption
      software, please check your country's laws, regulations and policies
      concerning the import, possession, or use, and re-export of encryption
      software, to see if this is permitted.  See <https://www.wassenaar.org/>
      for more information.
    
      The U.S. Government Department of Commerce, Bureau of Industry and
      Security (BIS), has classified this software as Export Commodity 
      Control Number (ECCN) 5D002.C.1, which includes information security
      software using or performing cryptographic functions with asymmetric
      algorithms.  The form and manner of this Apache Software Foundation
      distribution makes it eligible for export under the License Exception
      ENC Technology Software Unrestricted (TSU) exception (see the BIS 
      Export Administration Regulations, Section 740.13) for both object 
      code and source code.
    
      The following provides more details on the included files that
      may be subject to export controls on cryptographic software:
    
        Apache httpd 2.0 and later versions include the mod_ssl module under
           modules/ssl/
        for configuring and listening to connections over SSL encrypted
        network sockets by performing calls to a general-purpose encryption
        library, such as OpenSSL or the operating system's platform-specific
        SSL facilities.
    
        In addition, some versions of apr-util provide an abstract interface
        for symmetrical cryptographic functions that make use of a
        general-purpose encryption library, such as OpenSSL, NSS, or the
        operating system's platform-specific facilities. This interface is
        known as the apr_crypto interface, with implementation beneath the
        /crypto directory. The apr_crypto interface is used by the
        mod_session_crypto module available under
          modules/session
        for optional encryption of session information.
    
        Some object code distributions of Apache httpd, indicated with the
        word "crypto" in the package name, may include object code for the
        OpenSSL encryption library as distributed in open source form from
        <https://www.openssl.org/source/>.
    
      The above files are optional and may be removed if the cryptographic
      functionality is not desired or needs to be excluded from redistribution.
      Distribution packages of Apache httpd that include the word "nossl"
      in the package name have been created without the above files and are
      therefore not subject to this notice.
    
      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
           <https://httpd.apache.org/lists.html#http-announce>
    
         o If you want freely available support for running Apache please see the
           resources at <https://httpd.apache.org/support.html>
    
         o If you have a concrete bug report for Apache please see the instructions
           for bug reporting at <https://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
           <https://httpd.apache.org/lists.html#http-dev>
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/README.CHANGES�������������������������������������������������������������������������0000664�0001751�0001751�00000002014�14455322601�014550� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Changes can be documented in two ways now: Either by directly editing the
    CHANGES file like it was done until now or by storing each entry for the
    CHANGES file correctly formated in a separate file in the changes-entries
    directory.
    
    The benefit of the single file per change approach is that it eases backporting
    the CHANGES entry to a stable branch as it avoids the frequent merge conflicts
    as changes are merged in different orders or not at all in the stable branch.
    
    In order to keep the current CHANGES file for the users as is there is a new
    make target called 'update-changes'. It merges all change files in the
    changes-entries directory to the top of the CHANGES file and removes them
    afterwards.
    
    This make target can be seen in a similar way as the scripts to update the
    documentation files from its xml sources. It can be executed immediately
    after the new file in the changes-entries directory has been created / merged
    and committed or it can be executed later. It should be executed at least before
    a release gets tagged.
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/libhttpd.mak���������������������������������������������������������������������������0000664�0001751�0001751�00000114460�14047304210�015127� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on libhttpd.dsp
    !IF "$(CFG)" == ""
    CFG=libhttpd - Win32 Release
    !MESSAGE No configuration specified. Defaulting to libhttpd - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "libhttpd - Win32 Release" && "$(CFG)" != "libhttpd - Win32 Debug" && "$(CFG)" != "libhttpd - Win32 Lexical"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 "libhttpd - Win32 Lexical" (based on "Win32 (x86) Dynamic-Link Library")
    !MESSAGE 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : ".\include\mod_dav.h" ".\include\mod_watchdog.h" "$(OUTDIR)\libhttpd.dll" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "gen_test_char - Win32 Release" "libaprutil - Win32 Release" "libapriconv - Win32 Release" "libapr - Win32 Release" ".\include\mod_dav.h" ".\include\mod_watchdog.h" "$(OUTDIR)\libhttpd.dll" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libapriconv - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "gen_test_char - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ap_regkey.obj"
    	-@erase "$(INTDIR)\byterange_filter.obj"
    	-@erase "$(INTDIR)\child.obj"
    	-@erase "$(INTDIR)\chunk_filter.obj"
    	-@erase "$(INTDIR)\config.obj"
    	-@erase "$(INTDIR)\connection.obj"
    	-@erase "$(INTDIR)\core.obj"
    	-@erase "$(INTDIR)\core_filters.obj"
    	-@erase "$(INTDIR)\eoc_bucket.obj"
    	-@erase "$(INTDIR)\eor_bucket.obj"
    	-@erase "$(INTDIR)\error_bucket.obj"
    	-@erase "$(INTDIR)\http_core.obj"
    	-@erase "$(INTDIR)\http_etag.obj"
    	-@erase "$(INTDIR)\http_filters.obj"
    	-@erase "$(INTDIR)\http_protocol.obj"
    	-@erase "$(INTDIR)\http_request.obj"
    	-@erase "$(INTDIR)\libhttpd.res"
    	-@erase "$(INTDIR)\libhttpd_cl.idb"
    	-@erase "$(INTDIR)\libhttpd_cl.pdb"
    	-@erase "$(INTDIR)\listen.obj"
    	-@erase "$(INTDIR)\log.obj"
    	-@erase "$(INTDIR)\mod_so.obj"
    	-@erase "$(INTDIR)\mod_win32.obj"
    	-@erase "$(INTDIR)\modules.obj"
    	-@erase "$(INTDIR)\mpm_common.obj"
    	-@erase "$(INTDIR)\mpm_winnt.obj"
    	-@erase "$(INTDIR)\nt_eventlog.obj"
    	-@erase "$(INTDIR)\protocol.obj"
    	-@erase "$(INTDIR)\provider.obj"
    	-@erase "$(INTDIR)\request.obj"
    	-@erase "$(INTDIR)\scoreboard.obj"
    	-@erase "$(INTDIR)\service.obj"
    	-@erase "$(INTDIR)\ssl.obj"
    	-@erase "$(INTDIR)\util.obj"
    	-@erase "$(INTDIR)\util_cfgtree.obj"
    	-@erase "$(INTDIR)\util_cookies.obj"
    	-@erase "$(INTDIR)\util_debug.obj"
    	-@erase "$(INTDIR)\util_expr_eval.obj"
    	-@erase "$(INTDIR)\util_expr_parse.obj"
    	-@erase "$(INTDIR)\util_expr_scan.obj"
    	-@erase "$(INTDIR)\util_fcgi.obj"
    	-@erase "$(INTDIR)\util_filter.obj"
    	-@erase "$(INTDIR)\util_md5.obj"
    	-@erase "$(INTDIR)\util_mutex.obj"
    	-@erase "$(INTDIR)\util_pcre.obj"
    	-@erase "$(INTDIR)\util_regex.obj"
    	-@erase "$(INTDIR)\util_script.obj"
    	-@erase "$(INTDIR)\util_time.obj"
    	-@erase "$(INTDIR)\util_win32.obj"
    	-@erase "$(INTDIR)\util_xml.obj"
    	-@erase "$(INTDIR)\vhost.obj"
    	-@erase "$(OUTDIR)\libhttpd.dll"
    	-@erase "$(OUTDIR)\libhttpd.exp"
    	-@erase "$(OUTDIR)\libhttpd.lib"
    	-@erase "$(OUTDIR)\libhttpd.pdb"
    	-@erase ".\include\mod_dav.h"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\libhttpd_cl" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libhttpd.res" /i "./include" /i "./srclib/apr/include" /d "NDEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\libhttpd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=pcre.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Release\buildmark.obj" /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\libhttpd.pdb" /debug /out:"$(OUTDIR)\libhttpd.dll" /implib:"$(OUTDIR)\libhttpd.lib" /libpath:"./srclib/pcre" /base:@"os\win32\BaseAddr.ref",libhttpd.dll /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\byterange_filter.obj" \
    	"$(INTDIR)\chunk_filter.obj" \
    	"$(INTDIR)\config.obj" \
    	"$(INTDIR)\connection.obj" \
    	"$(INTDIR)\core.obj" \
    	"$(INTDIR)\core_filters.obj" \
    	"$(INTDIR)\http_core.obj" \
    	"$(INTDIR)\http_etag.obj" \
    	"$(INTDIR)\http_filters.obj" \
    	"$(INTDIR)\http_protocol.obj" \
    	"$(INTDIR)\http_request.obj" \
    	"$(INTDIR)\log.obj" \
    	"$(INTDIR)\protocol.obj" \
    	"$(INTDIR)\request.obj" \
    	"$(INTDIR)\vhost.obj" \
    	"$(INTDIR)\mod_so.obj" \
    	"$(INTDIR)\mod_win32.obj" \
    	"$(INTDIR)\modules.obj" \
    	"$(INTDIR)\eoc_bucket.obj" \
    	"$(INTDIR)\eor_bucket.obj" \
    	"$(INTDIR)\error_bucket.obj" \
    	"$(INTDIR)\util.obj" \
    	"$(INTDIR)\util_cfgtree.obj" \
    	"$(INTDIR)\util_cookies.obj" \
    	"$(INTDIR)\util_debug.obj" \
    	"$(INTDIR)\util_expr_eval.obj" \
    	"$(INTDIR)\util_expr_scan.obj" \
    	"$(INTDIR)\util_expr_parse.obj" \
    	"$(INTDIR)\util_fcgi.obj" \
    	"$(INTDIR)\util_filter.obj" \
    	"$(INTDIR)\util_md5.obj" \
    	"$(INTDIR)\util_mutex.obj" \
    	"$(INTDIR)\util_pcre.obj" \
    	"$(INTDIR)\util_regex.obj" \
    	"$(INTDIR)\util_script.obj" \
    	"$(INTDIR)\util_time.obj" \
    	"$(INTDIR)\util_win32.obj" \
    	"$(INTDIR)\util_xml.obj" \
    	"$(INTDIR)\ap_regkey.obj" \
    	"$(INTDIR)\child.obj" \
    	"$(INTDIR)\listen.obj" \
    	"$(INTDIR)\mpm_common.obj" \
    	"$(INTDIR)\mpm_winnt.obj" \
    	"$(INTDIR)\nt_eventlog.obj" \
    	"$(INTDIR)\provider.obj" \
    	"$(INTDIR)\scoreboard.obj" \
    	"$(INTDIR)\service.obj" \
    	"$(INTDIR)\ssl.obj" \
    	"$(INTDIR)\libhttpd.res" \
    	".\srclib\apr\Release\libapr-1.lib" \
    	".\srclib\apr-iconv\Release\libapriconv-1.lib" \
    	".\srclib\apr-util\Release\libaprutil-1.lib"
    
    "$(OUTDIR)\libhttpd.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
       cl.exe /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 "AP_DECLARE_EXPORT" /Fd"Release\libhttpd" /FD /c server\buildmark.c /Fo"Release\buildmark.obj"
    	 $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\libhttpd.dll
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\libhttpd.dll"
       if exist .\Release\libhttpd.dll.manifest mt.exe -manifest .\Release\libhttpd.dll.manifest -outputresource:.\Release\libhttpd.dll;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : ".\server\test_char.h" ".\include\mod_watchdog.h" ".\include\mod_so.h" ".\include\mod_proxy.h" ".\include\mod_include.h" ".\include\mod_dav.h" ".\include\mod_cgi.h" ".\include\ap_config_layout.h" "$(OUTDIR)\libhttpd.dll" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "gen_test_char - Win32 Debug" "libaprutil - Win32 Debug" "libapriconv - Win32 Debug" "libapr - Win32 Debug" ".\server\test_char.h" ".\include\mod_watchdog.h" ".\include\mod_so.h" ".\include\mod_proxy.h" ".\include\mod_include.h" ".\include\mod_dav.h" ".\include\mod_cgi.h" ".\include\ap_config_layout.h" "$(OUTDIR)\libhttpd.dll" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libapriconv - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "gen_test_char - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ap_regkey.obj"
    	-@erase "$(INTDIR)\byterange_filter.obj"
    	-@erase "$(INTDIR)\child.obj"
    	-@erase "$(INTDIR)\chunk_filter.obj"
    	-@erase "$(INTDIR)\config.obj"
    	-@erase "$(INTDIR)\connection.obj"
    	-@erase "$(INTDIR)\core.obj"
    	-@erase "$(INTDIR)\core_filters.obj"
    	-@erase "$(INTDIR)\eoc_bucket.obj"
    	-@erase "$(INTDIR)\eor_bucket.obj"
    	-@erase "$(INTDIR)\error_bucket.obj"
    	-@erase "$(INTDIR)\http_core.obj"
    	-@erase "$(INTDIR)\http_etag.obj"
    	-@erase "$(INTDIR)\http_filters.obj"
    	-@erase "$(INTDIR)\http_protocol.obj"
    	-@erase "$(INTDIR)\http_request.obj"
    	-@erase "$(INTDIR)\libhttpd.res"
    	-@erase "$(INTDIR)\libhttpd_cl.idb"
    	-@erase "$(INTDIR)\libhttpd_cl.pdb"
    	-@erase "$(INTDIR)\listen.obj"
    	-@erase "$(INTDIR)\log.obj"
    	-@erase "$(INTDIR)\mod_so.obj"
    	-@erase "$(INTDIR)\mod_win32.obj"
    	-@erase "$(INTDIR)\modules.obj"
    	-@erase "$(INTDIR)\mpm_common.obj"
    	-@erase "$(INTDIR)\mpm_winnt.obj"
    	-@erase "$(INTDIR)\nt_eventlog.obj"
    	-@erase "$(INTDIR)\protocol.obj"
    	-@erase "$(INTDIR)\provider.obj"
    	-@erase "$(INTDIR)\request.obj"
    	-@erase "$(INTDIR)\scoreboard.obj"
    	-@erase "$(INTDIR)\service.obj"
    	-@erase "$(INTDIR)\ssl.obj"
    	-@erase "$(INTDIR)\util.obj"
    	-@erase "$(INTDIR)\util_cfgtree.obj"
    	-@erase "$(INTDIR)\util_cookies.obj"
    	-@erase "$(INTDIR)\util_debug.obj"
    	-@erase "$(INTDIR)\util_expr_eval.obj"
    	-@erase "$(INTDIR)\util_expr_parse.obj"
    	-@erase "$(INTDIR)\util_expr_scan.obj"
    	-@erase "$(INTDIR)\util_fcgi.obj"
    	-@erase "$(INTDIR)\util_filter.obj"
    	-@erase "$(INTDIR)\util_md5.obj"
    	-@erase "$(INTDIR)\util_mutex.obj"
    	-@erase "$(INTDIR)\util_pcre.obj"
    	-@erase "$(INTDIR)\util_regex.obj"
    	-@erase "$(INTDIR)\util_script.obj"
    	-@erase "$(INTDIR)\util_time.obj"
    	-@erase "$(INTDIR)\util_win32.obj"
    	-@erase "$(INTDIR)\util_xml.obj"
    	-@erase "$(INTDIR)\vhost.obj"
    	-@erase "$(OUTDIR)\libhttpd.dll"
    	-@erase "$(OUTDIR)\libhttpd.exp"
    	-@erase "$(OUTDIR)\libhttpd.lib"
    	-@erase "$(OUTDIR)\libhttpd.pdb"
    	-@erase ".\include\ap_config_layout.h"
    	-@erase ".\include\mod_cgi.h"
    	-@erase ".\include\mod_dav.h"
    	-@erase ".\include\mod_include.h"
    	-@erase ".\include\mod_proxy.h"
    	-@erase ".\include\mod_so.h"
    	-@erase ".\include\mod_watchdog.h"
    	-@erase ".\server\test_char.h"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\libhttpd_cl" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libhttpd.res" /i "./include" /i "./srclib/apr/include" /d "_DEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\libhttpd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=pcred.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Debug\buildmark.obj" /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\libhttpd.pdb" /debug /out:"$(OUTDIR)\libhttpd.dll" /implib:"$(OUTDIR)\libhttpd.lib" /libpath:"./srclib/pcre" /base:@"os\win32\BaseAddr.ref",libhttpd.dll 
    LINK32_OBJS= \
    	"$(INTDIR)\byterange_filter.obj" \
    	"$(INTDIR)\chunk_filter.obj" \
    	"$(INTDIR)\config.obj" \
    	"$(INTDIR)\connection.obj" \
    	"$(INTDIR)\core.obj" \
    	"$(INTDIR)\core_filters.obj" \
    	"$(INTDIR)\http_core.obj" \
    	"$(INTDIR)\http_etag.obj" \
    	"$(INTDIR)\http_filters.obj" \
    	"$(INTDIR)\http_protocol.obj" \
    	"$(INTDIR)\http_request.obj" \
    	"$(INTDIR)\log.obj" \
    	"$(INTDIR)\protocol.obj" \
    	"$(INTDIR)\request.obj" \
    	"$(INTDIR)\vhost.obj" \
    	"$(INTDIR)\mod_so.obj" \
    	"$(INTDIR)\mod_win32.obj" \
    	"$(INTDIR)\modules.obj" \
    	"$(INTDIR)\eoc_bucket.obj" \
    	"$(INTDIR)\eor_bucket.obj" \
    	"$(INTDIR)\error_bucket.obj" \
    	"$(INTDIR)\util.obj" \
    	"$(INTDIR)\util_cfgtree.obj" \
    	"$(INTDIR)\util_cookies.obj" \
    	"$(INTDIR)\util_debug.obj" \
    	"$(INTDIR)\util_expr_eval.obj" \
    	"$(INTDIR)\util_expr_scan.obj" \
    	"$(INTDIR)\util_expr_parse.obj" \
    	"$(INTDIR)\util_fcgi.obj" \
    	"$(INTDIR)\util_filter.obj" \
    	"$(INTDIR)\util_md5.obj" \
    	"$(INTDIR)\util_mutex.obj" \
    	"$(INTDIR)\util_pcre.obj" \
    	"$(INTDIR)\util_regex.obj" \
    	"$(INTDIR)\util_script.obj" \
    	"$(INTDIR)\util_time.obj" \
    	"$(INTDIR)\util_win32.obj" \
    	"$(INTDIR)\util_xml.obj" \
    	"$(INTDIR)\ap_regkey.obj" \
    	"$(INTDIR)\child.obj" \
    	"$(INTDIR)\listen.obj" \
    	"$(INTDIR)\mpm_common.obj" \
    	"$(INTDIR)\mpm_winnt.obj" \
    	"$(INTDIR)\nt_eventlog.obj" \
    	"$(INTDIR)\provider.obj" \
    	"$(INTDIR)\scoreboard.obj" \
    	"$(INTDIR)\service.obj" \
    	"$(INTDIR)\ssl.obj" \
    	"$(INTDIR)\libhttpd.res" \
    	".\srclib\apr\Debug\libapr-1.lib" \
    	".\srclib\apr-iconv\Debug\libapriconv-1.lib" \
    	".\srclib\apr-util\Debug\libaprutil-1.lib"
    
    "$(OUTDIR)\libhttpd.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
       cl.exe /nologo /MDd /W3 /EHsc /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /Fd"Debug\libhttpd" /FD /c server\buildmark.c /Fo"Debug\buildmark.obj"
    	 $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\libhttpd.dll
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\libhttpd.dll"
       if exist .\Debug\libhttpd.dll.manifest mt.exe -manifest .\Debug\libhttpd.dll.manifest -outputresource:.\Debug\libhttpd.dll;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : ".\server\util_expr_parse.h" ".\server\util_expr_parse.c" ".\server\test_char.h" "$(OUTDIR)\libhttpd.dll" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : ".\server\util_expr_parse.h" ".\server\util_expr_parse.c" ".\server\test_char.h" "$(OUTDIR)\libhttpd.dll" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\ap_regkey.obj"
    	-@erase "$(INTDIR)\byterange_filter.obj"
    	-@erase "$(INTDIR)\child.obj"
    	-@erase "$(INTDIR)\chunk_filter.obj"
    	-@erase "$(INTDIR)\config.obj"
    	-@erase "$(INTDIR)\connection.obj"
    	-@erase "$(INTDIR)\core.obj"
    	-@erase "$(INTDIR)\core_filters.obj"
    	-@erase "$(INTDIR)\eoc_bucket.obj"
    	-@erase "$(INTDIR)\eor_bucket.obj"
    	-@erase "$(INTDIR)\error_bucket.obj"
    	-@erase "$(INTDIR)\http_core.obj"
    	-@erase "$(INTDIR)\http_etag.obj"
    	-@erase "$(INTDIR)\http_filters.obj"
    	-@erase "$(INTDIR)\http_protocol.obj"
    	-@erase "$(INTDIR)\http_request.obj"
    	-@erase "$(INTDIR)\libhttpd.res"
    	-@erase "$(INTDIR)\libhttpd_cl.idb"
    	-@erase "$(INTDIR)\libhttpd_cl.pdb"
    	-@erase "$(INTDIR)\listen.obj"
    	-@erase "$(INTDIR)\log.obj"
    	-@erase "$(INTDIR)\mod_so.obj"
    	-@erase "$(INTDIR)\mod_win32.obj"
    	-@erase "$(INTDIR)\modules.obj"
    	-@erase "$(INTDIR)\mpm_common.obj"
    	-@erase "$(INTDIR)\mpm_winnt.obj"
    	-@erase "$(INTDIR)\nt_eventlog.obj"
    	-@erase "$(INTDIR)\protocol.obj"
    	-@erase "$(INTDIR)\provider.obj"
    	-@erase "$(INTDIR)\request.obj"
    	-@erase "$(INTDIR)\scoreboard.obj"
    	-@erase "$(INTDIR)\service.obj"
    	-@erase "$(INTDIR)\ssl.obj"
    	-@erase "$(INTDIR)\util.obj"
    	-@erase "$(INTDIR)\util_cfgtree.obj"
    	-@erase "$(INTDIR)\util_cookies.obj"
    	-@erase "$(INTDIR)\util_debug.obj"
    	-@erase "$(INTDIR)\util_expr_eval.obj"
    	-@erase "$(INTDIR)\util_expr_parse.obj"
    	-@erase "$(INTDIR)\util_expr_scan.obj"
    	-@erase "$(INTDIR)\util_fcgi.obj"
    	-@erase "$(INTDIR)\util_filter.obj"
    	-@erase "$(INTDIR)\util_md5.obj"
    	-@erase "$(INTDIR)\util_mutex.obj"
    	-@erase "$(INTDIR)\util_pcre.obj"
    	-@erase "$(INTDIR)\util_regex.obj"
    	-@erase "$(INTDIR)\util_script.obj"
    	-@erase "$(INTDIR)\util_time.obj"
    	-@erase "$(INTDIR)\util_win32.obj"
    	-@erase "$(INTDIR)\util_xml.obj"
    	-@erase "$(INTDIR)\vhost.obj"
    	-@erase "$(OUTDIR)\libhttpd.dll"
    	-@erase "$(OUTDIR)\libhttpd.exp"
    	-@erase "$(OUTDIR)\libhttpd.lib"
    	-@erase "$(OUTDIR)\libhttpd.pdb"
    	-@erase ".\server\test_char.h"
    	-@erase ".\server\util_expr_parse.c"
    	-@erase ".\server\util_expr_parse.h"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\libhttpd_cl" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    MTL=midl.exe
    MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libhttpd.res" /i "./include" /i "./srclib/apr/include" /d "NDEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\libhttpd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=pcre.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Release\buildmark.obj" /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\libhttpd.pdb" /debug /out:"$(OUTDIR)\libhttpd.dll" /implib:"$(OUTDIR)\libhttpd.lib" /libpath:"./srclib/pcre" /base:@"os\win32\BaseAddr.ref",libhttpd.dll /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\byterange_filter.obj" \
    	"$(INTDIR)\chunk_filter.obj" \
    	"$(INTDIR)\config.obj" \
    	"$(INTDIR)\connection.obj" \
    	"$(INTDIR)\core.obj" \
    	"$(INTDIR)\core_filters.obj" \
    	"$(INTDIR)\http_core.obj" \
    	"$(INTDIR)\http_etag.obj" \
    	"$(INTDIR)\http_filters.obj" \
    	"$(INTDIR)\http_protocol.obj" \
    	"$(INTDIR)\http_request.obj" \
    	"$(INTDIR)\log.obj" \
    	"$(INTDIR)\protocol.obj" \
    	"$(INTDIR)\request.obj" \
    	"$(INTDIR)\vhost.obj" \
    	"$(INTDIR)\mod_so.obj" \
    	"$(INTDIR)\mod_win32.obj" \
    	"$(INTDIR)\modules.obj" \
    	"$(INTDIR)\eoc_bucket.obj" \
    	"$(INTDIR)\eor_bucket.obj" \
    	"$(INTDIR)\error_bucket.obj" \
    	"$(INTDIR)\util.obj" \
    	"$(INTDIR)\util_cfgtree.obj" \
    	"$(INTDIR)\util_cookies.obj" \
    	"$(INTDIR)\util_debug.obj" \
    	"$(INTDIR)\util_expr_eval.obj" \
    	"$(INTDIR)\util_expr_scan.obj" \
    	"$(INTDIR)\util_expr_parse.obj" \
    	"$(INTDIR)\util_fcgi.obj" \
    	"$(INTDIR)\util_filter.obj" \
    	"$(INTDIR)\util_md5.obj" \
    	"$(INTDIR)\util_mutex.obj" \
    	"$(INTDIR)\util_pcre.obj" \
    	"$(INTDIR)\util_regex.obj" \
    	"$(INTDIR)\util_script.obj" \
    	"$(INTDIR)\util_time.obj" \
    	"$(INTDIR)\util_win32.obj" \
    	"$(INTDIR)\util_xml.obj" \
    	"$(INTDIR)\ap_regkey.obj" \
    	"$(INTDIR)\child.obj" \
    	"$(INTDIR)\listen.obj" \
    	"$(INTDIR)\mpm_common.obj" \
    	"$(INTDIR)\mpm_winnt.obj" \
    	"$(INTDIR)\nt_eventlog.obj" \
    	"$(INTDIR)\provider.obj" \
    	"$(INTDIR)\scoreboard.obj" \
    	"$(INTDIR)\service.obj" \
    	"$(INTDIR)\ssl.obj" \
    	"$(INTDIR)\libhttpd.res"
    
    "$(OUTDIR)\libhttpd.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
       cl.exe /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 "AP_DECLARE_EXPORT" /Fd"Release\libhttpd" /FD /c server\buildmark.c /Fo"Release\buildmark.obj"
    	 $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\libhttpd.dll
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\libhttpd.dll"
       if exist .\Release\libhttpd.dll.manifest mt.exe -manifest .\Release\libhttpd.dll.manifest -outputresource:.\Release\libhttpd.dll;2
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("libhttpd.dep")
    !INCLUDE "libhttpd.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "libhttpd.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "libhttpd - Win32 Release" || "$(CFG)" == "libhttpd - Win32 Debug" || "$(CFG)" == "libhttpd - Win32 Lexical"
    SOURCE=.\modules\generators\mod_cgi.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\modules\generators\mod_cgi.h
    
    ".\include\mod_cgi.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\generators\mod_cgi.h > .\include\mod_cgi.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\modules\generators\mod_cgi.h
    
    ".\include\mod_cgi.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\generators\mod_cgi.h > .\include\mod_cgi.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\modules\dav\main\mod_dav.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\modules\dav\main\mod_dav.h
    
    ".\include\mod_dav.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\dav\main\mod_dav.h > .\include\mod_dav.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\modules\dav\main\mod_dav.h
    
    ".\include\mod_dav.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\dav\main\mod_dav.h > .\include\mod_dav.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\modules\filters\mod_include.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\modules\filters\mod_include.h
    
    ".\include\mod_include.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\filters\mod_include.h > .\include\mod_include.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\modules\filters\mod_include.h
    
    ".\include\mod_include.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\filters\mod_include.h > .\include\mod_include.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\modules\proxy\mod_proxy.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\modules\proxy\mod_proxy.h
    
    ".\include\mod_proxy.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\proxy\mod_proxy.h > .\include\mod_proxy.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\modules\proxy\mod_proxy.h
    
    ".\include\mod_proxy.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\proxy\mod_proxy.h > .\include\mod_proxy.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\modules\core\mod_so.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\modules\core\mod_so.h
    
    ".\include\mod_so.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\core\mod_so.h > .\include\mod_so.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\modules\core\mod_so.h
    
    ".\include\mod_so.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\core\mod_so.h > .\include\mod_so.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\modules\core\mod_watchdog.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\modules\core\mod_watchdog.h
    
    ".\include\mod_watchdog.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\core\mod_watchdog.h > .\include\mod_watchdog.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\modules\core\mod_watchdog.h
    
    ".\include\mod_watchdog.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\modules\core\mod_watchdog.h > .\include\mod_watchdog.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\os\win32\os.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\os\win32\os.h
    
    ".\include\os.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\os\win32\os.h > .\include\os.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\os\win32\os.h
    
    ".\include\os.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\os\win32\os.h > .\include\os.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\os\win32\win32_config_layout.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\os\win32\win32_config_layout.h
    
    ".\include\ap_config_layout.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\os\win32\win32_config_layout.h > .\include\ap_config_layout.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\os\win32\win32_config_layout.h
    
    ".\include\ap_config_layout.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	type .\os\win32\win32_config_layout.h > .\include\ap_config_layout.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\server\buildmark.c
    SOURCE=.\modules\http\byterange_filter.c
    
    "$(INTDIR)\byterange_filter.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\http\chunk_filter.c
    
    "$(INTDIR)\chunk_filter.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\config.c
    
    "$(INTDIR)\config.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\connection.c
    
    "$(INTDIR)\connection.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\core.c
    
    "$(INTDIR)\core.obj" : $(SOURCE) "$(INTDIR)" ".\include\mod_proxy.h" ".\include\mod_so.h" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\core_filters.c
    
    "$(INTDIR)\core_filters.obj" : $(SOURCE) "$(INTDIR)" ".\include\mod_so.h" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\http\http_core.c
    
    "$(INTDIR)\http_core.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\http\http_etag.c
    
    "$(INTDIR)\http_etag.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\http\http_filters.c
    
    "$(INTDIR)\http_filters.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\http\http_protocol.c
    
    "$(INTDIR)\http_protocol.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\http\http_request.c
    
    "$(INTDIR)\http_request.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\log.c
    
    "$(INTDIR)\log.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\protocol.c
    
    "$(INTDIR)\protocol.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\request.c
    
    "$(INTDIR)\request.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\vhost.c
    
    "$(INTDIR)\vhost.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\core\mod_so.c
    
    "$(INTDIR)\mod_so.obj" : $(SOURCE) "$(INTDIR)" ".\modules\core\mod_so.h" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\modules\arch\win32\mod_win32.c
    
    "$(INTDIR)\mod_win32.obj" : $(SOURCE) "$(INTDIR)" ".\include\mod_cgi.h" ".\include\os.h" ".\include\ap_config_layout.h" ".\include\mod_include.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\os\win32\modules.c
    
    "$(INTDIR)\modules.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\eoc_bucket.c
    
    "$(INTDIR)\eoc_bucket.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\eor_bucket.c
    
    "$(INTDIR)\eor_bucket.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\error_bucket.c
    
    "$(INTDIR)\error_bucket.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util.c
    
    "$(INTDIR)\util.obj" : $(SOURCE) "$(INTDIR)" ".\server\test_char.h" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_cfgtree.c
    
    "$(INTDIR)\util_cfgtree.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_cookies.c
    
    "$(INTDIR)\util_cookies.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_debug.c
    
    "$(INTDIR)\util_debug.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_expr_eval.c
    
    "$(INTDIR)\util_expr_eval.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_expr_parse.c
    
    "$(INTDIR)\util_expr_parse.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_expr_scan.c
    
    "$(INTDIR)\util_expr_scan.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_fcgi.c
    
    "$(INTDIR)\util_fcgi.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_filter.c
    
    "$(INTDIR)\util_filter.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_md5.c
    
    "$(INTDIR)\util_md5.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_mutex.c
    
    "$(INTDIR)\util_mutex.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_pcre.c
    
    "$(INTDIR)\util_pcre.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_regex.c
    
    "$(INTDIR)\util_regex.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_script.c
    
    "$(INTDIR)\util_script.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_time.c
    
    "$(INTDIR)\util_time.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\os\win32\util_win32.c
    
    "$(INTDIR)\util_win32.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_xml.c
    
    "$(INTDIR)\util_xml.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\os\win32\ap_regkey.c
    
    "$(INTDIR)\ap_regkey.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\mpm\winnt\child.c
    
    "$(INTDIR)\child.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\listen.c
    
    "$(INTDIR)\listen.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\mpm_common.c
    
    "$(INTDIR)\mpm_common.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\mpm\winnt\mpm_winnt.c
    
    "$(INTDIR)\mpm_winnt.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\mpm\winnt\nt_eventlog.c
    
    "$(INTDIR)\nt_eventlog.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\provider.c
    
    "$(INTDIR)\provider.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\scoreboard.c
    
    "$(INTDIR)\scoreboard.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\mpm\winnt\service.c
    
    "$(INTDIR)\service.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\ssl.c
    
    "$(INTDIR)\ssl.obj" : $(SOURCE) "$(INTDIR)" ".\include\os.h" ".\include\ap_config_layout.h"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    SOURCE=.\server\util_expr_parse.y
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    InputPath=.\server\util_expr_parse.y
    
    ".\server\util_expr_parse.c"	".\server\util_expr_parse.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	bison -pap_expr_yy --defines=.\server\util_expr_parse.h -o .\server\util_expr_parse.c .\server\util_expr_parse.y
    << 
    	
    
    !ENDIF 
    
    SOURCE=.\server\util_expr_scan.l
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    InputPath=.\server\util_expr_scan.l
    
    ".\server\util_expr_scan.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	<<tempfile.bat 
    	@echo off 
    	flex -Pap_expr_yy -o .\server\util_expr_scan.c .\server\util_expr_scan.l
    << 
    	
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\.."
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\.."
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    "libapriconv - Win32 Release" : 
       cd ".\srclib\apr-iconv"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapriconv.mak" CFG="libapriconv - Win32 Release" 
       cd "..\.."
    
    "libapriconv - Win32 ReleaseCLEAN" : 
       cd ".\srclib\apr-iconv"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapriconv.mak" CFG="libapriconv - Win32 Release" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    "libapriconv - Win32 Debug" : 
       cd ".\srclib\apr-iconv"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapriconv.mak" CFG="libapriconv - Win32 Debug" 
       cd "..\.."
    
    "libapriconv - Win32 DebugCLEAN" : 
       cd ".\srclib\apr-iconv"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapriconv.mak" CFG="libapriconv - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\.."
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\.."
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    "gen_test_char - Win32 Release" : 
       cd ".\server"
       $(MAKE) /$(MAKEFLAGS) /F ".\gen_test_char.mak" CFG="gen_test_char - Win32 Release" 
       cd ".."
    
    "gen_test_char - Win32 ReleaseCLEAN" : 
       cd ".\server"
       $(MAKE) /$(MAKEFLAGS) /F ".\gen_test_char.mak" CFG="gen_test_char - Win32 Release" RECURSE=1 CLEAN 
       cd ".."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    "gen_test_char - Win32 Debug" : 
       cd ".\server"
       $(MAKE) /$(MAKEFLAGS) /F ".\gen_test_char.mak" CFG="gen_test_char - Win32 Debug" 
       cd ".."
    
    "gen_test_char - Win32 DebugCLEAN" : 
       cd ".\server"
       $(MAKE) /$(MAKEFLAGS) /F ".\gen_test_char.mak" CFG="gen_test_char - Win32 Debug" RECURSE=1 CLEAN 
       cd ".."
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    SOURCE=.\server\gen_test_char.exe
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    InputPath=.\server\gen_test_char.exe
    USERDEP__GEN_T=".\include\os.h"	
    
    ".\server\test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(USERDEP__GEN_T)
    	<<tempfile.bat 
    	@echo off 
    	.\server\gen_test_char.exe >.\server\test_char.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    InputPath=.\server\gen_test_char.exe
    USERDEP__GEN_T=".\include\os.h"	
    
    ".\server\test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(USERDEP__GEN_T)
    	<<tempfile.bat 
    	@echo off 
    	.\server\gen_test_char.exe >.\server\test_char.h
    << 
    	
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    InputPath=.\server\gen_test_char.exe
    USERDEP__GEN_T=".\include\os.h"	
    
    ".\server\test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(USERDEP__GEN_T)
    	<<tempfile.bat 
    	@echo off 
    	.\server\gen_test_char.exe >.\server\test_char.h
    << 
    	
    
    !ENDIF 
    
    SOURCE=.\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    
    "$(INTDIR)\libhttpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\libhttpd.res" /i "./include" /i "./srclib/apr/include" /i "build\win32" /d "NDEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    
    "$(INTDIR)\libhttpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\libhttpd.res" /i "./include" /i "./srclib/apr/include" /i "build\win32" /d "_DEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    
    "$(INTDIR)\libhttpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\libhttpd.res" /i "./include" /i "./srclib/apr/include" /i "build\win32" /d "NDEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core" $(SOURCE)
    
    
    !ENDIF 
    
    
    !ENDIF 
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/acinclude.m4���������������������������������������������������������������������������0000664�0001751�0001751�00000062701�14155717546�015040� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    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(HTTPD_VERSION)
      APACHE_SUBST(HTTPD_MMN)
      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(INTERNAL_CPPFLAGS)
      APACHE_SUBST(LIBTOOL)
      APACHE_SUBST(SHELL)
      APACHE_SUBST(RSYNC)
      APACHE_SUBST(SVN)
      APACHE_SUBST(MODULE_DIRS)
      APACHE_SUBST(MODULE_CLEANDIRS)
      APACHE_SUBST(PORT)
      APACHE_SUBST(SSLPORT)
      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(MPM_MODULES)
      APACHE_SUBST(ENABLED_MPM_MODULE)
      APACHE_SUBST(DSO_MODULES)
      APACHE_SUBST(ENABLED_DSO_MODULES)
      APACHE_SUBST(LOAD_ALL_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)`"
    
      AC_MSG_NOTICE([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
    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 the list of build variables which are available for customization on a
    dnl per module subdir basis (to be inserted into modules.mk with a "MOD_"
    dnl prefix, i.e. MOD_CFLAGS etc.). Used in APACHE_MODPATH_{INIT,FINISH}.
    define(mod_buildvars, [CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES])
    dnl
    dnl APACHE_MODPATH_INIT(modpath)
    AC_DEFUN([APACHE_MODPATH_INIT],[
      current_dir=$1
      modpath_current=modules/$1
      modpath_static=
      modpath_shared=
      for var in mod_buildvars; do
        eval MOD_$var=
      done
      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
      for var in mod_buildvars; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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
          if test ! -z "$5"; then
            APR_ADDTO(AP_LIBS, [$5])
          fi
        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_MPM_MODULE(name[, shared[, objects[, config[, path[, libs]]]]])
    dnl
    dnl Provide information for building the MPM.  (Enablement is handled using
    dnl --with-mpm/--enable-mpms-shared.)
    dnl
    dnl name     -- name of MPM, same as MPM directory name
    dnl shared   -- "shared" to indicate shared module build, empty string otherwise
    dnl objects  -- one or more .lo files to link into the MPM module (default: mpmname.lo)
    dnl config   -- configuration logic to run if the MPM is enabled
    dnl path     -- relative path to MPM (default: server/mpm/mpmname)
    dnl libs     -- libs needed by this MPM
    dnl
    AC_DEFUN([APACHE_MPM_MODULE],[
        if ap_mpm_is_enabled $1; then
            if test -z "$3"; then
                objects="$1.lo"
            else
                objects="$3"
            fi
    
            if test -z "$5"; then
                mpmpath="server/mpm/$1"
            else
                mpmpath=$5
            fi
    
            dnl VPATH support
            test -d $mpmpath || $srcdir/build/mkdir.sh $mpmpath
    
            APACHE_FAST_OUTPUT($mpmpath/Makefile)
    
            if test -z "$2"; then
                APR_ADDTO(AP_LIBS, [$6])
                libname="lib$1.la"
                cat >$mpmpath/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
            else
                apache_need_shared=yes
                libname="mod_mpm_$1.la"
                shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
                cat >$mpmpath/modules.mk<<EOF
    $libname: $shobjects
    	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $objects $6
    DISTCLEAN_TARGETS = modules.mk
    static =
    shared = $libname
    EOF
                MPM_MODULES="$MPM_MODULES mpm_$1"
                # add default MPM to LoadModule list
                if test $1 = $default_mpm; then
                    ENABLED_MPM_MODULE="mpm_$1"
                fi
            fi
            $4
        fi
    ])dnl
    
    dnl
    dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config[, prereq_module]]]]])
    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             XXX: The arg must really be empty here. Passing an empty shell
    dnl             XXX: variable doesn't work for some reason. This should be
    dnl             XXX: fixed.
    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, except if the user selects
    dnl            "reallyall".
    dnl
    dnl prereq_module is a module (without the "mod_" prefix) that must be enabled
    dnl   if the current module is enabled.  If the current module is built
    dnl   statically, prereq_module must be built statically, too.  If these
    dnl   conditions are not fulfilled, configure will abort if the current module
    dnl   has been enabled explicitly. Otherwise, configure will disable the
    dnl   current module.
    dnl   prereq_module's APACHE_MODULE() statement must have been processed
    dnl   before the current APACHE_MODULE() statement.
    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),force_$1=$enableval,enable_$1=ifelse($5,,maybe-all,$5))
      undefine([optname])dnl
      _apmod_extra_msg=""
      dnl If the module was not explicitly requested, allow it to disable itself if
      dnl its pre-reqs fail.
      case "$enable_$1" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_$1" = "static" -o "$enable_$1" = "shared"; then
        :
      elif test "$enable_$1" = "yes"; then
        enable_$1=$module_default
      elif test "$enable_$1" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_$1=$module_default
        else
          enable_$1=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_$1" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_$1=$module_default
        else
          enable_$1=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_$1" = "all" -o "$enable_$1" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_$1=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_$1=no
        fi
      elif test "$enable_$1" = "reallyall" -o "$enable_$1" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_$1" != "no" ; then
          enable_$1=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_$1=no
        fi
      else
        enable_$1=no
      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$7],,:,
               [AC_MSG_RESULT([checking dependencies])
                ifelse([$7],,:,[m4_foreach([prereq],[$7],
                               [if test "$enable_[]prereq" = "no" ; then
                                  enable_$1=no
                                  AC_MSG_WARN("mod_[]prereq is disabled but required for mod_$1")
                                elif test "$enable_$1" = "static" && test "$enable_[]prereq" != "static" ; then
                                  enable_$1=$enable_[]prereq
                                  AC_MSG_WARN("building mod_$1 shared because mod_[]prereq is built shared")
                                el])se])
                ifelse([$6],,:,[  $6])
                ifelse([$7],,:,[fi])
                AC_MSG_CHECKING(whether to enable mod_$1)
                if test "$enable_$1" = "no"; then
                  if test "$_apmod_required" = "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
        static*)
          MODLIST="$MODLIST ifelse($4,,$1,$4)"
          if test "$1" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES $1"
          if test "$5" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},$1"
          fi
          ;;
        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=most
      module_default=shared
    
      dnl Check whether we have DSO support.
      dnl If "yes", we build shared modules by default.
      APR_CHECK_APR_DEFINE(APR_HAS_DSO)
    
      if test $ac_cv_define_APR_HAS_DSO = "no"; then
        AC_MSG_WARN([Missing DSO support - building static modules by default.])
        module_default=static
      fi
    
    
      AC_ARG_ENABLE(modules,
      APACHE_HELP_STRING(--enable-modules=MODULE-LIST,Space-separated list of modules to enable | "all" | "most" | "few" | "none" | "reallyall"),[
        if test "$enableval" = "none"; then
           module_default=no
           module_selection=none
        else
          for i in $enableval; do
            if test "$i" = "all" -o "$i" = "most" -o "$i" = "few" -o "$i" = "reallyall"
            then
              module_selection=$i
            else
              i=`echo $i | sed 's/-/_/g'`
              eval "enable_$i=shared"
            fi
          done
        fi
      ])
      
      AC_ARG_ENABLE(mods-shared,
      APACHE_HELP_STRING(--enable-mods-shared=MODULE-LIST,Space-separated list of shared modules to enable | "all" | "most" | "few" | "reallyall"),[
        for i in $enableval; do
          if test "$i" = "all" -o "$i" = "most" -o "$i" = "few" -o "$i" = "reallyall"
          then
            module_selection=$i
            module_default=shared
          else
            i=`echo $i | sed 's/-/_/g'`
        	eval "enable_$i=shared"
          fi
        done
      ])
      
      AC_ARG_ENABLE(mods-static,
      APACHE_HELP_STRING(--enable-mods-static=MODULE-LIST,Space-separated list of static modules to enable | "all" | "most" | "few" | "reallyall"),[
        for i in $enableval; do
          if test "$i" = "all" -o "$i" = "most" -o "$i" = "few" -o "$i" = "reallyall"; then
            module_selection=$i
            module_default=static
          else
            i=`echo $i | sed 's/-/_/g'`
        	eval "enable_$i=static"
          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_OPENSSL
    dnl
    dnl Configure for OpenSSL, giving preference to
    dnl "--with-ssl=<path>" if it was specified.
    dnl
    AC_DEFUN([APACHE_CHECK_OPENSSL],[
      AC_CACHE_CHECK([for OpenSSL], [ac_cv_openssl], [
        dnl initialise the variables we use
        ac_cv_openssl=no
        ap_openssl_found=""
        ap_openssl_base=""
        ap_openssl_libs=""
        ap_openssl_mod_cflags=""
        ap_openssl_mod_ldflags=""
    
        dnl Determine the OpenSSL base directory, if any
        AC_MSG_CHECKING([for user-provided OpenSSL base directory])
        AC_ARG_WITH(ssl, APACHE_HELP_STRING(--with-ssl=PATH,OpenSSL installation directory), [
          dnl If --with-ssl specifies a directory, we use that directory
          if test "x$withval" != "xyes" -a "x$withval" != "x"; then
            dnl This ensures $withval is actually a directory and that it is absolute
            ap_openssl_base="`cd $withval ; pwd`"
          fi
        ])
        if test "x$ap_openssl_base" = "x"; then
          AC_MSG_RESULT(none)
        else
          AC_MSG_RESULT($ap_openssl_base)
        fi
    
        dnl Run header and version checks
        saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
        dnl Before doing anything else, load in pkg-config variables
        if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          if test "x$ap_openssl_base" != "x"; then
            if test -f "${ap_openssl_base}/lib/pkgconfig/openssl.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system openssl.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_openssl_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_openssl_base}/lib64/pkgconfig/openssl.pc"; then
              dnl Ensure that the given path is used by pkg-config too, otherwise
              dnl the system openssl.pc might be picked up instead.
              PKG_CONFIG_PATH="${ap_openssl_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          AC_ARG_ENABLE(ssl-staticlib-deps,APACHE_HELP_STRING(--enable-ssl-staticlib-deps,[link mod_ssl with dependencies of OpenSSL's static libraries (as indicated by "pkg-config --static"). Must be specified in addition to --enable-ssl.]), [
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
          ])
          ap_openssl_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors openssl`"
          if test $? -eq 0; then
            ap_openssl_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I openssl`"
            APR_ADDTO(CPPFLAGS, [$pkglookup])
            APR_ADDTO(MOD_CFLAGS, [$pkglookup])
            APR_ADDTO(ab_CFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L openssl`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other openssl`"
            APR_ADDTO(LDFLAGS, [$pkglookup])
            APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
        dnl fall back to the user-supplied directory if not found via pkg-config
        if test "x$ap_openssl_base" != "x" -a "x$ap_openssl_found" = "x"; then
          APR_ADDTO(CPPFLAGS, [-I$ap_openssl_base/include])
          APR_ADDTO(MOD_CFLAGS, [-I$ap_openssl_base/include])
          APR_ADDTO(ab_CFLAGS, [-I$ap_openssl_base/include])
          APR_ADDTO(LDFLAGS, [-L$ap_openssl_base/lib])
          APR_ADDTO(MOD_LDFLAGS, [-L$ap_openssl_base/lib])
          if test "x$ap_platform_runtime_link_flag" != "x"; then
            APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_openssl_base/lib])
            APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_openssl_base/lib])
          fi
        fi
    
        AC_MSG_CHECKING([for OpenSSL version >= 0.9.8a])
        AC_TRY_COMPILE([#include <openssl/opensslv.h>],[
    #if !defined(OPENSSL_VERSION_NUMBER)
    #error "Missing OpenSSL version"
    #endif
    #if OPENSSL_VERSION_NUMBER < 0x0090801f
    #error "Unsupported OpenSSL version " OPENSSL_VERSION_TEXT
    #endif],
          [AC_MSG_RESULT(OK)
           ac_cv_openssl=yes],
          [AC_MSG_RESULT(FAILED)])
    
        if test "x$ac_cv_openssl" = "xyes"; then
          ap_openssl_libs="${ap_openssl_libs:--lssl -lcrypto} `$apr_config --libs`"
          APR_ADDTO(MOD_LDFLAGS, [$ap_openssl_libs])
          APR_ADDTO(LIBS, [$ap_openssl_libs])
          APR_SETVAR(ab_LIBS, [$MOD_LDFLAGS])
          APACHE_SUBST(ab_CFLAGS)
          APACHE_SUBST(ab_LIBS)
    
          dnl Run library and function checks
          liberrors=""
          AC_CHECK_HEADERS([openssl/engine.h])
          AC_CHECK_FUNCS([SSL_CTX_new], [], [liberrors="yes"])
          AC_CHECK_FUNCS([OPENSSL_init_ssl])
          AC_CHECK_FUNCS([ENGINE_init ENGINE_load_builtin_engines RAND_egd])
          if test "x$liberrors" != "x"; then
            AC_MSG_WARN([OpenSSL libraries are unusable])
          fi
        else
          AC_MSG_WARN([OpenSSL version is too old])
        fi
    
        dnl restore
        CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
        dnl cache MOD_LDFLAGS, MOD_CFLAGS
        ap_openssl_mod_cflags=$MOD_CFLAGS
        ap_openssl_mod_ldflags=$MOD_LDFLAGS
      ])
      if test "x$ac_cv_openssl" = "xyes"; then
        AC_DEFINE(HAVE_OPENSSL, 1, [Define if OpenSSL is available])
        APR_ADDTO(MOD_LDFLAGS, [$ap_openssl_mod_ldflags])
        APR_ADDTO(MOD_CFLAGS, [$ap_openssl_mod_cflags])
      fi
    ])
    
    AC_DEFUN([APACHE_CHECK_SYSTEMD], [
    dnl Check for systemd support for listen.c's socket activation.
    case $host in
    *-linux-*)
       if test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd; then
          SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd`
       elif test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd-daemon; then
          SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd-daemon`
       else
          AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon")
       fi
       if test -n "$SYSTEMD_LIBS"; then
          AC_CHECK_HEADERS(systemd/sd-daemon.h)
          if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
            AC_MSG_WARN([Your system does not support systemd.])
          else
            AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
          fi
       fi
       ;;
    esac
    ])
    
    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)
    ])
    
    dnl 
    dnl APACHE_CHECK_APxVER({apr|apu}, major, minor, 
    dnl                     [actions-if-ok], [actions-if-not-ok])
    dnl
    dnl Checks for APR or APR-util of given major/minor version or later; 
    dnl if so, runs actions-if-ok; otherwise runs actions-if-not-ok if given.
    dnl If the version is not satisfactory and actions-if-not-ok is not
    dnl given, then an error is printed and the configure script is aborted.
    dnl
    dnl The first argument must be [apr] or [apu].
    dnl
    AC_DEFUN([APACHE_CHECK_APxVER], [
    define(ap_ckver_major, translit($1, [apru], [APRU])[_MAJOR_VERSION])
    define(ap_ckver_minor, translit($1, [apru], [APRU])[_MINOR_VERSION])
    define(ap_ckver_cvar, [ap_cv_$1ver$2$3])
    define(ap_ckver_name, ifelse([$1],[apr],[APR],[APR-util]))
    
    ap_ckver_CPPFLAGS="$CPPFLAGS"
    CPPFLAGS="$CPPFLAGS `$[$1]_config --includes`"
    
    AC_CACHE_CHECK([for ap_ckver_name version $2.$3.0 or later], ap_ckver_cvar, [
    AC_EGREP_CPP([good], [
    #include <$1_version.h>
    #if ]ap_ckver_major[ > $2 || (]ap_ckver_major[ == $2 && ]ap_ckver_minor[ >= $3)
    good
    #endif
    ], [ap_ckver_cvar=yes], [ap_ckver_cvar=no])])
    
    if test "$ap_ckver_cvar" = "yes"; then
      ifelse([$4],[],[:],[$4])
    else
      ifelse([$5],[],[AC_MSG_ERROR([ap_ckver_name version $2.$3.0 or later is required])], [$5])
    fi
    
    CPPFLAGS="$ap_ckver_CPPFLAGS"
    
    undefine([ap_ckver_major])
    undefine([ap_ckver_minor])
    undefine([ap_ckver_cvar])
    undefine([ap_ckver_name])
    ])
    
    dnl
    dnl APACHE_CHECK_VOID_PTR_LEN
    dnl
    dnl Checks if the size of a void pointer is at least as big as a "long" 
    dnl integer type.
    dnl
    AC_DEFUN([APACHE_CHECK_VOID_PTR_LEN], [
    
    AC_CACHE_CHECK([for void pointer length], [ap_cv_void_ptr_lt_long],
    [AC_TRY_RUN([
    int main(void)
    {
        return sizeof(void *) < sizeof(long); 
    }], [ap_cv_void_ptr_lt_long=no], [ap_cv_void_ptr_lt_long=yes], 
        [ap_cv_void_ptr_lt_long=yes])])
    
    if test "$ap_cv_void_ptr_lt_long" = "yes"; then
        AC_MSG_ERROR([Size of "void *" is less than size of "long"])
    fi
    ])
    
    dnl
    dnl APACHE_CHECK_APR_HAS_LDAP
    dnl
    dnl Check if APR_HAS_LDAP is 1
    dnl Unfortunately, we can't use APR_CHECK_APR_DEFINE (because it only includes apr.h)
    dnl or APR_CHECK_DEFINE (because it only checks for defined'ness and not for 0/1).
    dnl
    AC_DEFUN([APACHE_CHECK_APR_HAS_LDAP], [
      AC_CACHE_CHECK([for ldap support in apr/apr-util],ac_cv_APR_HAS_LDAP,[
        apache_old_cppflags="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS $INCLUDES"
        AC_EGREP_CPP(YES_IS_DEFINED, [
    #include <apr_ldap.h>
    #if APR_HAS_LDAP
    YES_IS_DEFINED
    #endif
        ], ac_cv_APR_HAS_LDAP=yes, ac_cv_APR_HAS_LDAP=no)
        CPPFLAGS="$apache_old_cppflags"
      ])
    ])
    
    dnl
    dnl APACHE_ADD_GCC_CFLAG
    dnl
    dnl Check if compiler is gcc and supports flag. If yes, add to NOTEST_CFLAGS.
    dnl NOTEST_CFLAGS is merged lately, thus it won't accumulate in CFLAGS here.
    dnl Also, AC_LANG_PROGRAM() itself is known to trigger [-Wstrict-prototypes]
    dnl with some autoconf versions, so we force -Wno-strict-prototypes for the
    dnl check to avoid spurious failures when adding flags like -Werror.
    dnl
    AC_DEFUN([APACHE_ADD_GCC_CFLAG], [
      define([ap_gcc_ckvar], [ac_cv_gcc_]translit($1, [-:.=], [____]))
      if test "$GCC" = "yes"; then
        AC_CACHE_CHECK([whether gcc accepts $1], ap_gcc_ckvar, [
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS $1 -Wno-strict-prototypes"
          AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
            [ap_gcc_ckvar=yes], [ap_gcc_ckvar=no])
          CFLAGS="$save_CFLAGS"
        ])
        if test "$]ap_gcc_ckvar[" = "yes" ; then
           APR_ADDTO(NOTEST_CFLAGS,[$1])
        fi
      fi
      undefine([ap_gcc_ckvar])
    ])
    ���������������������������������������������������������������httpd-2.4.64/config.layout��������������������������������������������������������������������������0000664�0001751�0001751�00000033544�13623623272�015345� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������##
    ##  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 
    ##    `/<target>' suffix where <target> is currently hardcoded to 'apache2'.
    ##    (This may become a configurable parameter at some point.)
    ##
    
    #   Classical Apache path layout.
    <Layout Apache>
        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
    </Layout>
    
    #   GNU standards conforming path layout.
    #   See FSF's GNU project `make-stds' document for details.
    <Layout GNU>
        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
    </Layout>
    
    #   Mac OS X Server (Rhapsody)
    <Layout Mac OS X Server>
        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
    </Layout>
    
    #   Darwin/Mac OS Layout
    <Layout Darwin>
        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
    </Layout>
    
    #   Red Hat Linux 7.x layout
    <Layout RedHat>
        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
    </Layout>     
    
    # Layout used in Fedora httpd packaging.
    <Layout Fedora>
        prefix:        /usr
        localstatedir: /var
        exec_prefix:   ${prefix}
        bindir:        ${prefix}/bin
        sbindir:       ${prefix}/sbin
        libdir:        ${prefix}/lib
        libexecdir:    ${prefix}/libexec
        mandir:        ${prefix}/man
        sysconfdir:    /etc/httpd/conf
        datadir:       ${prefix}/share/httpd
        installbuilddir: ${libdir}/httpd/build
        errordir:      ${datadir}/error
        iconsdir:      ${datadir}/icons
        htdocsdir:     ${localstatedir}/www/html
        manualdir:     ${datadir}/manual
        cgidir:        ${localstatedir}/www/cgi-bin
        includedir:    ${prefix}/include/httpd
        runtimedir:    /run/httpd
        logfiledir:    ${localstatedir}/log/httpd
        proxycachedir: ${localstatedir}/cache/httpd/proxy
    </Layout>     
    
    #   According to the /opt filesystem conventions
    <Layout opt>
        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
    </Layout>
    
    #   SuSE 6.x layout
    <Layout SuSE>
        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
    </Layout>
    
    #   BSD/OS layout
    <Layout BSDI>
        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
    </Layout>
    
    #   Solaris 8 Layout
    <Layout Solaris>
        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
    </Layout>
    
    #   OpenBSD Layout
    <Layout OpenBSD>
        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
    </Layout>
    
    # FreeBSD Layout
    <Layout FreeBSD>
      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
    </Layout>
    
    # Debian layout
    <Layout Debian>
        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/lock/apache2
        runtimedir:    ${prefix}/var/run/apache2
        logfiledir:    ${prefix}/var/log/apache2
        proxycachedir: ${prefix}/var/cache/apache2/proxy
        infodir:       ${exec_prefix}/share/info
        installbuilddir: ${prefix}/usr/share/apache2/build
        errordir:      ${datadir}/error
    </Layout>
    
    # Generic RPM layout
    <Layout RPM>
        prefix:        /usr
        exec_prefix:   ${prefix}
        bindir:        ${prefix}/bin
        sbindir:       ${prefix}/sbin
        libdir:        ${prefix}/lib
        libexecdir:    ${libdir}/httpd/modules
        mandir:        ${prefix}/share/man
        sysconfdir:    /etc/httpd/conf
        installbuilddir: ${libdir}/httpd/build
        includedir:    ${prefix}/include/httpd
        localstatedir: /var
        datadir:       ${localstatedir}/www
        errordir:      ${datadir}/error
        iconsdir:      ${datadir}/icons
        htdocsdir:     ${datadir}/html
        manualdir:     ${datadir}/manual
        cgidir:        ${datadir}/cgi-bin
        runtimedir:    ${localstatedir}/run
        logfiledir:    ${localstatedir}/log/httpd
        proxycachedir: ${localstatedir}/cache/httpd/cache-root
    </Layout>
    
    # AIX layout
    <Layout AIX>
        prefix:        /opt/httpd
        exec_prefix:   /opt/httpd
        bindir:        ${exec_prefix}/bin
        sbindir:       ${exec_prefix}/sbin
        libdir:        ${exec_prefix}/lib
        libexecdir:    ${exec_prefix}/libexec
        mandir:        /usr/share/man
        sysconfdir:    /etc/httpd
        datadir:       /var/httpd
        installbuilddir: ${datadir}/build
        errordir:      ${datadir}/error
        htdocsdir:     ${datadir}/htdocs
        cgidir:        ${datadir}/cgi-bin
        iconsdir:      ${prefix}/icons
        manualdir:     ${prefix}/manual
        includedir:    ${prefix}/include
        localstatedir: /var/httpd
        runtimedir:    ${localstatedir}/run
        logfiledir:    ${localstatedir}/logs
        proxycachedir: ${localstatedir}/proxy
    </Layout>
    
    # FHS layout
    <Layout Slackware-FHS>
        prefix:          /usr
        exec_prefix:     ${prefix}
        bindir:          ${prefix}/bin
        sbindir:         ${prefix}/sbin
        libdir:          ${prefix}/lib/httpd
        libexecdir:      ${prefix}/lib/httpd/modules
        installbuilddir: ${prefix}/lib/httpd/build
        mandir:          ${prefix}/man
        sysconfdir:      /etc/httpd
        datadir:         /srv/httpd
        iconsdir:        ${datadir}/icons
        htdocsdir:       ${datadir}/htdocs
        manualdir:       ${htdocsdir}/manual
        cgidir:          ${datadir}/cgi-bin
        errordir:        ${datadir}/error
        includedir:      ${prefix}/include/httpd
        localstatedir:   /var
        runtimedir:      ${localstatedir}/run/httpd
        logfiledir:      ${localstatedir}/log/httpd
        proxycachedir:   ${localstatedir}/cache/httpd
    </Layout>
    
    # OpenWrt layout
    <Layout OpenWrt>
        prefix:          /usr
        exec_prefix:     ${prefix}
        bindir:          ${prefix}/bin
        sbindir:         ${prefix}/sbin
        libdir:          ${prefix}/lib
        libexecdir:      ${prefix}/lib+
        mandir:          ${prefix}/share/man
        sysconfdir:      /etc+
        datadir:         ${prefix}/share+
        installbuilddir: ${datadir}/build
        errordir:        ${datadir}/error
        iconsdir:        ${datadir}/icons
        htdocsdir:       ${datadir}/htdocs
        manualdir:       /usr/share/doc/apache2/manual
        cgidir:          ${datadir}/cgi-bin
        includedir:      ${prefix}/include+
        localstatedir:   /var
        runtimedir:      ${localstatedir}/run+
        logfiledir:      ${localstatedir}/log+
        proxycachedir:   ${localstatedir}/cache/apache2
    </Layout>
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/Apache-apr2.dsw������������������������������������������������������������������������0000664�0001751�0001751�00000202350�13446306656�015403� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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 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
    }}}
    
    ###############################################################################
    
    Project: "BuildAll"=.\BuildAll.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name BuildBin
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authnz_ldap
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_bucketeer
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_case_filter
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_case_filter_in
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_echo
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_example_hooks
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_example_ipc
        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 mod_access_compat
        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_allowmethods
        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_auth_form
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_anon
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_core
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_dbm
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_file
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_socache
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authnz_fcgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authz_core
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authz_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authz_dbm
        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_owner
        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_buffer
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_cache_disk
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_cache_socache
        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_data
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dav_fs
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dav_lock
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dir
        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_filter
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_headers
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_heartbeat
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_heartmonitor
        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_lbmethod_bybusyness
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_lbmethod_byrequests
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_lbmethod_bytraffic
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_lbmethod_heartbeat
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_log_config
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_log_debug
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_log_forensic
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_logio
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_macro
        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_proxy_ajp
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_connect
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_express
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_fcgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_ftp
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_hcheck
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_http
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_scgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_uwsgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_wstunnel
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_ratelimit
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_reflector
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_remoteip
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_reqtimeout
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_request
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_rewrite
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_sed
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session_cookie
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_setenvif
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_slotmem_plain
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_slotmem_shm
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_dbm
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_memcache
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_shmcb
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_redis
        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_substitute
        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 ab
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name htcacheclean
        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 httxt2dbm
        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
    }}}
    
    ###############################################################################
    
    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
    }}}
    
    ###############################################################################
    
    Project: "abs"=.\support\abs.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name apr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr"=.\srclib\apr\apr.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_odbc"=".\srclib\apr\dbd\apr_dbd_odbc.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_mysql"=".\srclib\apr\dbd\apr_dbd_mysql.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_oracle"=".\srclib\apr\dbd\apr_dbd_oracle.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_pgsql"=".\srclib\apr\dbd\apr_dbd_pgsql.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_sqlite2"=".\srclib\apr\dbd\apr_dbd_sqlite2.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_sqlite3"=".\srclib\apr\dbd\apr_dbd_sqlite3.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr_dbm_db"=".\srclib\apr\dbm\apr_dbm_db.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "apr_dbm_gdbm"=".\srclib\apr\dbm\apr_dbm_gdbm.dsp" - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "fcgistarter"=.\support\fcgistarter.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name apr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    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: "htcacheclean"=.\support\htcacheclean.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name apr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "htdbm"=.\support\htdbm.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name apr
        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
    }}}
    
    ###############################################################################
    
    Project: "htpasswd"=.\support\htpasswd.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name apr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "httxt2dbm"=.\support\httxt2dbm.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name apr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "libapr"=.\srclib\apr\libapr.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
    }}}
    
    ###############################################################################
    
    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 gen_test_char
        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
    }}}
    
    ###############################################################################
    
    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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_allowmethods"=.\modules\aaa\mod_allowmethods.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 libhttpd
        End Project Dependency
    }}}
    
    
    ###############################################################################
    
    Project: "mod_access_compat"=.\modules\aaa\mod_access_compat.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_auth_form"=.\modules\aaa\mod_auth_form.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_auth_basic
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_authn_core"=.\modules\aaa\mod_authn_core.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_dbd"=.\modules\aaa\mod_authn_dbd.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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
        Begin Project Dependency
        Project_Dep_Name mod_dbd
        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 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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_auth_basic
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_authn_socache"=.\modules\aaa\mod_authn_socache.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_authnz_fcgi"=.\modules\aaa\mod_authnz_fcgi.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_ldap
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_authz_core"=.\modules\aaa\mod_authz_core.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_dbd"=.\modules\aaa\mod_authz_dbd.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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
        Begin Project Dependency
        Project_Dep_Name mod_dbd
        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 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 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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_auth_basic
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_authz_owner"=.\modules\aaa\mod_authz_owner.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_brotli"=.\modules\filters\mod_brotli.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_bucketeer"=.\modules\debugging\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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_buffer"=.\modules\filters\mod_buffer.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_case_filter"=.\modules\examples\mod_case_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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_case_filter_in"=.\modules\examples\mod_case_filter_in.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_charset_lite"=.\modules\filters\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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_data"=.\modules\filters\mod_data.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dav
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_dav_lock"=.\modules\dav\lock\mod_dav_lock.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_dbd"=.\modules\database\mod_dbd.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_cache_disk"=.\modules\cache\mod_cache_disk.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_cache_socache"=.\modules\cache\mod_cache_socache.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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\debugging\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 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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_example_hooks"=.\modules\examples\mod_example_hooks.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_example_ipc"=.\modules\examples\mod_example_ipc.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_filter"=.\modules\filters\mod_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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_http2"=.\modules\http2\mod_http2.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_heartbeat"=.\modules\cluster\mod_heartbeat.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_watchdog
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_heartmonitor"=.\modules\cluster\mod_heartmonitor.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_watchdog
        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 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 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 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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lbmethod_bybusyness"=.\modules\proxy\balancers\mod_lbmethod_bybusyness.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lbmethod_byrequests"=.\modules\proxy\balancers\mod_lbmethod_byrequests.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lbmethod_bytraffic"=.\modules\proxy\balancers\mod_lbmethod_bytraffic.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lbmethod_heartbeat"=.\modules\proxy\balancers\mod_lbmethod_heartbeat.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_log_debug"=.\modules\loggers\mod_log_debug.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lua"=.\modules\lua\mod_lua.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_macro"=.\modules\core\mod_macro.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_md"=.\modules\md\mod_md.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        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 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 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 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 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 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 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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_proxy_express"=.\modules\proxy\mod_proxy_express.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_fcgi"=.\modules\proxy\mod_proxy_fcgi.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_proxy_hcheck"=.\modules\proxy\mod_proxy_hcheck.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_html"=.\modules\filters\mod_proxy_html.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        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 libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_proxy_http2"=.\modules\http2\mod_proxy_http2.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_http2
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_proxy_scgi"=.\modules\proxy\mod_proxy_scgi.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_uwsgi"=.\modules\proxy\mod_proxy_uwsgi.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_wstunnel"=.\modules\proxy\mod_proxy_wstunnel.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_ratelimit"=.\modules\filters\mod_ratelimit.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_reflector"=.\modules\filters\mod_reflector.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_remoteip"=.\modules\metadata\mod_remoteip.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_reqtimeout"=.\modules\filters\mod_reqtimeout.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_request"=.\modules\filters\mod_request.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_sed"=.\modules\filters\mod_sed.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_session"=.\modules\session\mod_session.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_session_crypto"=.\modules\session\mod_session_crypto.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_session_cookie"=.\modules\session\mod_session_cookie.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_session_dbd"=.\modules\session\mod_session_dbd.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session
        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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_slotmem_plain"=.\modules\slotmem\mod_slotmem_plain.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_slotmem_shm"=.\modules\slotmem\mod_slotmem_shm.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_socache_dbm"=.\modules\cache\mod_socache_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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_socache_dc"=.\modules\cache\mod_socache_dc.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_socache_memcache"=.\modules\cache\mod_socache_memcache.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_socache_shmcb"=.\modules\cache\mod_socache_shmcb.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_socache_redis"=.\modules\cache\mod_socache_redis.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_substitute"=.\modules\filters\mod_substitute.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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 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 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 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 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 libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_watchdog"=.\modules\core\mod_watchdog.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_xml2enc"=.\modules\filters\mod_xml2enc.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libhttpd
        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
    }}}
    
    ###############################################################################
    
    Project: "wintty"=.\support\win32\wintty.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name apr
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Global:
    
    Package=<5>
    {{{
    }}}
    
    Package=<3>
    {{{
    }}}
    
    ###############################################################################
    
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/.gdbinit�������������������������������������������������������������������������������0000664�0001751�0001751�00000040154�14037105435�014251� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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' [%p]\n", $i, $t[$i].key, $t[$i].val, $t[$i].val
            end
            set $i = $i + 1
        end
    end
    document dump_table
        Print the key/value pairs in a table.
    end
    
    define dump_skiplist
        set $sl = (apr_skiplist *)$arg0
        set $m = $sl->bottom
        printf "skiplist@%p: size=%lu: height=%d\n", $sl, $sl->size, $sl->height
        while ($m)
            printf "(%p,%.12lx)", $m, $m->data
            set $u = $m->up
            while ($u)
                printf " (%p,%.12lx)", $u, $u->data
                set $u = $u->up
            end
            printf "\n"
            set $m = $m->next
        end
    end
    document dump_skiplist
        Print the nodes/values in a skiplist
    end
    
    define dump_string_hash
        set $h = $arg0->array
        set $n = $arg0->max
        set $i = 0
        while $i < $n
            set $ent = $h[$i]       
            while $ent != (void *)0L
                printf "'%s' => '%p'\n", $ent->key, $ent->val
                set $ent = $ent->next
            end
            set $i = $i + 1
        end
    end
    document dump_string_hash
        Print the entries in a hash table indexed by strings
    end
    
    define dump_string_shash
        set $h = $arg0->array
        set $n = $arg0->max
        set $i = 0
        while $i < $n
            set $ent = $h[$i]       
            while $ent != (void *)0L
                printf "'%s' => '%s'\n", $ent->key, $ent->val
                set $ent = $ent->next
            end
            set $i = $i + 1
        end
    end
    document dump_string_shash
        Print the entries in a hash table indexed by strings with string values
    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 "(%12lx)", (unsigned long)$bucket
        print_bkt_datacol "length" "%-6ld" (long)($bucket->length) $sh
        print_bkt_datacol "data" "%12lx" $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)
    
            # file bucket, can show fd and refcount
            set $fd = ((apr_bucket_file*)$bucket->data)->fd->filedes
            print_bkt_datacol "contents" "[***file***] fd=%-6ld" (long)$fd $sh
            set $refcount = ((apr_bucket_refcount *)$bucket->data)->refcount
            print_bkt_datacol "rc" "%-3d" $refcount $sh
    
        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 $isValidAddress($data) == 1
                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
            else
                printf "Iv addr %12lx]", $data
            end
    
            if $refcount != -1
                print_bkt_datacol "rc" "%-3d" $refcount $sh
            else
                print_bkt_datacol "rc" "n/%c" 'a' $sh
            end
    
        else
            if ($bucket->type == &apr_bucket_type_pipe)
    
                # pipe bucket, can show fd
                set $fd = ((apr_file_t*)$bucket->data)->filedes
                print_bkt_datacol "contents" "[***pipe***] fd=%-3ld" (long)$fd $sh
    
            else
            if ($bucket->type == &apr_bucket_type_socket)
    
                # file bucket, can show fd
                set $fd = ((apr_socket_t*)$bucket->data)->socketdes
                print_bkt_datacol "contents" "[**socket**] fd=%-3ld" (long)$fd $sh
    
            else
    
                # 3rd-party bucket type
                print_bkt_datacol "contents" "[**opaque**]%-7c" ' ' $sh
            end
            end
    
            # no refcount
            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 address | contents               | rc\n"
        printf "-------------------------------------------"
        printf "----------------------------------------\n"
    
        if $bucket == $sentinel
            printf "brigade is empty\n"
        end
    
        set $j = 0
        set $brigade_length = 0
        while $bucket != $sentinel
            printf "%2d", $j
            dump_bucket_ex $bucket 1
            set $j = $j + 1
            if $bucket->length > 0
                set $brigade_length = $brigade_length + $bucket->length
            end
            set $bucket = $bucket->link.next
        end
        printf "end of brigade\n"
        printf "Length of brigade (excluding buckets of unknown length): %u\n", $brigade_length
    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_filter_chain
        set $r = $arg0
        set $f = $r->output_filters
        while $f
            if $f == $r->output_filters
                printf "r->output_filters =>\n"
            end
            if $f == $r->proto_output_filters
                printf "r->proto_output_filters =>\n"
            end
            if $f == $r->connection->output_filters
                printf "r->connection->output_filters =>\n"
            end
            
            printf "  %s(0x%lx): type=%d, ctx=0x%lx, r=%s(0x%lx), c=0x%lx\n", \
              $f->frec->name, (unsigned long)$f, $f->frec->ftype, (unsigned long)$f->ctx, \
              $f->r == $r ? "r" : ($f->r == 0L ? "null" : \
              ($f->r == $r->main ? "r->main" :  \
              ($r->main && $f->r == $r->main->main ? "r->main->main" : "????"))), \
              $f->r, $f->c
    
            set $f = $f->next
        end
    end
    document dump_filter_chain
        Print filter chain info given a request_rec pointer
    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_addr_recs
        set $sa_ = $arg0
        set $san_ = 0
        while $sa_
          ### need to call apr_sockaddr_info_getbuf to print ->host_addr properly
          ### which is a PITA since we need a buffer :(
          printf " addr#%d: vhost=%s -> :%d\n", $san_++, $sa_->virthost, $sa_->host_port
          set $sa_ = $sa_->next
        end
    end
    document dump_server_addr_recs
        Print server_addr_rec info
    end
    
    
    define dump_server_rec
        set $s = $arg0
        printf "name=%s:%d (0x%lx)\n", \
                $s->server_hostname, $s->port, $s
        dump_server_addr_recs $s->addrs
        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
    
    define dump_request_tree
        set $r = $arg0
        set $i
        while $r
            printf "r=(0x%lx): uri=%s, handler=%s, r->main=0x%lx\n", \
              $r, $r->unparsed_uri, $r->handler ? $r->handler : "(none)", $r->main
            set $r = $r->main
        end
    end        
    
    define dump_scoreboard
        # Need to reserve size of array first before string literals could be
        # put in
        set $status = {0, 1, 2, 3, 4 ,5 ,6 ,7 ,8 ,9 ,10}
        set $status = {"DEAD", "STARTING", "READY", "BUSY_READ", "BUSY_WRITE", "BUSY_KEEPALIVE", "BUSY_LOG", "BUSY_DNS", "CLOSING", "GRACEFUL", "IDLE_KILL"}
        set $i = 0
        while ($i < server_limit)
            if ap_scoreboard_image->servers[$i][0].pid != 0
                set $j = 0
                while ($j < threads_per_child)
                    set $ws = ap_scoreboard_image->servers[$i][$j]
                    printf "pid: %d, tid: 0x%lx, status: %s\n", $ws.pid, $ws.tid, $status[$ws.status]
                    set $j = $j +1
                end
            end
            set $i = $i +1
        end
    end
    document dump_scoreboard
        Dump the scoreboard
    end
    
    define dump_allocator
        printf "Allocator current_free_index = %d, max_free_index = %d\n", \
                ($arg0)->current_free_index, ($arg0)->max_free_index
        printf "Allocator free list:\n"
        set $i = 0
        set $max =(sizeof $arg0->free)/(sizeof $arg0->free[0])
        set $kb = 0
        while $i < $max
            set $node = $arg0->free[$i]
            if $node != 0
                printf " #%2d: ", $i
                while $node != 0
                    printf "%d, ", ($node->index + 1) << 12
                    set $kb = $kb + (($node->index + 1) << 2)
                    set $node = $node->next
                end
                printf "ends.\n"
            end
            set $i = $i + 1
        end
        printf "Sum of free blocks: %dkiB\n", $kb
    end
    document dump_allocator
        Print status of an allocator and its freelists.
    end
    
    define dump_one_pool
        set $p = $arg0
        set $size = 0
        set $free = 0
        set $nodes = 0
        set $node = $arg0->active
        set $done = 0
        while $done == 0
            set $size = $size + (($node->index + 1) << 12)
            set $free = $free + ($node->endp - $node->first_avail)
            set $nodes = $nodes + 1
            set $node = $node->next
            if $node == $arg0->active
                set $done = 1
            end
        end
        printf "Pool '"
        if $p->tag
            printf "%s", $p->tag
        else
            printf "no tag"
        end
        printf "' [%p]: %d/%d free (%d blocks)\n", $p, $free, $size, $nodes
    end
    
    define dump_all_pools
        if $argc > 0
            set $root = $arg0
        else
            set $root = ap_pglobal
        end
        while $root->parent
            set $root = $root->parent
        end
        dump_pool_and_children $root
    end
    document dump_all_pools
        Dump the whole pool hierarchy starting from apr_global_pool. Optionally takes an arbitrary pool as starting parameter.
    end
    
    python
    
    from __future__ import print_function
    
    class DumpPoolAndChilds (gdb.Command):
      """Dump the whole pool hierarchy starting from the given pool."""
    
      def __init__ (self):
        super (DumpPoolAndChilds, self).__init__ ("dump_pool_and_children", gdb.COMMAND_USER)
    
      def _allocator_free_blocks(self, alloc):
        salloc = "%s" % (alloc)
        if self.total_free_blocks.get(salloc) != None:
          return self.total_free_blocks[salloc]
        i = 0
        dalloc = alloc.dereference()
        max =(dalloc['free'].type.sizeof)/(dalloc['free'][0].type.sizeof)
        kb = 0
        while i < max:
          node = dalloc['free'][i]
          if node != 0:
            while node != 0:
              noded = node.dereference()
              kb = kb + ((int(noded['index']) + 1) << 2)
              node = noded['next']
          i = i + 1
        self.total_free_blocks[salloc] = kb
        return kb
    
    
      def _dump_one_pool(self, arg):
        size = 0
        free = 0
        nodes = 0
        darg = arg.dereference()
        active = darg['active']
        node = active
        done = 0
        while done == 0:
          noded = node.dereference()
          size = size + ((int(noded['index']) + 1) << 12)
          free = free + (noded['endp'] - noded['first_avail'])
          nodes = nodes + 1
          node = noded['next']
          if node == active:
            done = 1
        if darg['tag'] != 0:
          tag = darg['tag'].string()
        else:
          tag = "No tag"
        print("Pool '%s' [%s]: %d/%d free (%d blocks) allocator: %s free blocks in allocator: %i kiB" % (tag, arg, free, size, nodes, darg['allocator'], self._allocator_free_blocks(darg['allocator'])))
        self.free = self.free + free
        self.size = self.size + size
        self.nodes = self.nodes + nodes
    
      def _dump(self, arg, depth):
        pool = arg
        while pool:
            print("%*c" % (depth * 4 + 1, " "), end="")
            self._dump_one_pool(pool)
            if pool['child'] != 0:
                self._dump(pool['child'], depth + 1)
            pool = pool['sibling']
    
      def invoke (self, arg, from_tty):
        pool = gdb.parse_and_eval(arg)
        self.free = 0
        self.size = 0
        self.nodes = 0
        self.total_free_blocks = {}
        self._dump(pool, 0)
        print("Total %d/%d free (%d blocks)" % (self.free, self.size, self.nodes))
        sum = 0
        for key in self.total_free_blocks:
          sum = sum + self.total_free_blocks[key]
        print("Total free allocator blocks: %i kiB" % (sum))
    
    DumpPoolAndChilds ()
    end
    document dump_pool_and_children
        Dump the whole pool hierarchy starting from the given pool.
    end
    
    python
    
    class isValidAddress (gdb.Function):
        """Determines if the argument is a valid address."""
    
        def __init__(self):
            super(isValidAddress, self).__init__("isValidAddress")
    
        def invoke(self, address):
            inf = gdb.inferiors()[0]
            result = 1
            try:
                inf.read_memory(address, 8)
            except:
                result = 0
            return result
    
    isValidAddress()
    
    end
    
    # Set sane defaults for common signals:
    handle SIGPIPE noprint pass nostop
    handle SIGUSR1 print pass nostop
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/LICENSE��������������������������������������������������������������������������������0000664�0001751�0001751�00000061607�13607376315�013654� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������                                 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_imagemap.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 util_pcre.c and ap_regex.h components:
    
               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.
    -----------------------------------------------------------------------------
    
    
    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\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 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 warranties, 
    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)
    
    */
    
    �������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/libhttpd.dsp���������������������������������������������������������������������������0000664�0001751�0001751�00000052230�14046725222�015152� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 "libhttpd - Win32 Lexical" (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 "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 /fo"Release/libhttpd.res" /i "./include" /i "./srclib/apr/include" /d "NDEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core"
    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
    # ADD LINK32 pcre.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Release\buildmark.obj" /nologo /subsystem:windows /dll /debug /libpath:"./srclib/pcre" /base:@"os\win32\BaseAddr.ref",libhttpd.dll /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\libhttpd.dll
    SOURCE="$(InputPath)"
    PreLink_Desc=Compiling buildmark
    PreLink_Cmds=cl.exe /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 "AP_DECLARE_EXPORT" /Fd"Release\libhttpd" /FD /c server\buildmark.c /Fo"Release\buildmark.obj"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # 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 /EHsc /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /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 /fo"Debug/libhttpd.res" /i "./include" /i "./srclib/apr/include" /d "_DEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core"
    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
    # ADD LINK32 pcred.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Debug\buildmark.obj" /nologo /subsystem:windows /dll /incremental:no /debug /libpath:"./srclib/pcre" /base:@"os\win32\BaseAddr.ref",libhttpd.dll
    # Begin Special Build Tool
    TargetPath=.\Debug\libhttpd.dll
    SOURCE="$(InputPath)"
    PreLink_Desc=Compiling buildmark
    PreLink_Cmds=cl.exe /nologo /MDd /W3 /EHsc /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /Fd"Debug\libhttpd" /FD /c server\buildmark.c /Fo"Debug\buildmark.obj"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    # 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 "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 /fo"Release/libhttpd.res" /i "./include" /i "./srclib/apr/include" /d "NDEBUG" /d BIN_NAME="libhttpd.dll" /d LONG_NAME="Apache HTTP Server Core"
    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
    # ADD LINK32 pcre.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Release\buildmark.obj" /nologo /subsystem:windows /dll /debug /libpath:"./srclib/pcre" /base:@"os\win32\BaseAddr.ref",libhttpd.dll /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\libhttpd.dll
    SOURCE="$(InputPath)"
    PreLink_Desc=Compiling buildmark
    PreLink_Cmds=cl.exe /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 "AP_DECLARE_EXPORT" /Fd"Release\libhttpd" /FD /c server\buildmark.c /Fo"Release\buildmark.obj"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
    # End Special Build Tool
    
    
    !ENDIF 
    
    # Begin Target
    
    # Name "libhttpd - Win32 Release"
    # Name "libhttpd - Win32 Debug"
    # Name "libhttpd - Win32 Lexical"
    # 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_expr.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_ssl.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=.\os\win32\win32_config_layout.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    # PROP Ignore_Default_Tool 1
    # Begin Custom Build - Creating include/ap_config_layout.h
    InputPath=.\os\win32\win32_config_layout.h
    
    ".\include\ap_config_layout.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	type .\os\win32\win32_config_layout.h > .\include\ap_config_layout.h
    
    # End Custom Build
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    # PROP Ignore_Default_Tool 1
    # Begin Custom Build - Creating include/ap_config_layout.h
    InputPath=.\os\win32\win32_config_layout.h
    
    ".\include\ap_config_layout.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	type .\os\win32\win32_config_layout.h > .\include\ap_config_layout.h
    
    # End Custom Build
    
    !ENDIF 
    
    # 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=.\include\mod_core.h
    # 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\core\mod_so.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    # PROP Ignore_Default_Tool 1
    # Begin Custom Build - Creating include/mod_so.h
    InputPath=.\modules\core\mod_so.h
    
    ".\include\mod_so.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	type .\modules\core\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\core\mod_so.h
    
    ".\include\mod_so.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	type .\modules\core\mod_so.h > .\include\mod_so.h
    
    # End Custom Build
    
    !ENDIF 
    
    # End Source File
    # Begin Source File
    
    SOURCE=.\modules\core\mod_watchdog.h
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    # PROP Ignore_Default_Tool 1
    # Begin Custom Build - Creating include/mod_watchdog.h
    InputPath=.\modules\core\mod_watchdog.h
    
    ".\include\mod_watchdog.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	type .\modules\core\mod_watchdog.h > .\include\mod_watchdog.h
    
    # End Custom Build
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    # PROP Ignore_Default_Tool 1
    # Begin Custom Build - Creating include/mod_watchdog.h
    InputPath=.\modules\core\mod_watchdog.h
    
    ".\include\mod_watchdog.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	type .\modules\core\mod_watchdog.h > .\include\mod_watchdog.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
    # Begin Source File
    
    SOURCE=.\include\util_cookies.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\ssl.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\core\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\eor_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=.\server\util_cookies.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_debug.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\include\util_ebcdic.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_expr_private.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_expr_eval.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_expr_scan.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_expr_scan.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_expr_parse.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_expr_parse.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_fcgi.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\include\util_fcgi.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_mutex.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\include\util_mutex.h
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_pcre.c
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_regex.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=.\include\util_varbuf.h
    # 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=.\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_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
    
    # 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
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    # 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 Group "Generated Files"
    
    # PROP Default_Filter ""
    # Begin Source File
    
    SOURCE=.\server\util_expr_parse.y
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    # PROP Exclude_From_Build 1
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    # PROP Exclude_From_Build 1
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    # PROP Ignore_Default_Tool 1
    # Begin Custom Build - Generating util_expr_parse.c/.h from util_expr_parse.y
    InputPath=.\server\util_expr_parse.y
    
    BuildCmds= \
    	bison -pap_expr_yy --defines=.\server\util_expr_parse.h -o .\server\util_expr_parse.c .\server\util_expr_parse.y
    
    ".\server\util_expr_parse.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
       $(BuildCmds)
    
    ".\server\util_expr_parse.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
       $(BuildCmds)
    # End Custom Build
    
    !ENDIF
    
    # End Source File
    # Begin Source File
    
    SOURCE=.\server\util_expr_scan.l
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    # PROP Exclude_From_Build 1
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    # PROP Exclude_From_Build 1
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    # PROP Ignore_Default_Tool 1
    # Begin Custom Build - Generating util_expr_scan.c from util_expr_scan.l
    InputPath=.\server\util_expr_scan.l
    
    ".\server\util_expr_scan.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
    	flex -Pap_expr_yy -o .\server\util_expr_scan.c .\server\util_expr_scan.l
    
    # End Custom Build
    
    !ENDIF
    
    # End Source File
    # End Group
    # Begin Source File
    
    SOURCE=.\build\win32\httpd.rc
    # End Source File
    # End Target
    # End Project
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/VERSIONING�����������������������������������������������������������������������������0000664�0001751�0001751�00000017772�13623622544�014255� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������APACHE 2.x VERSIONING
    =====================
    [$LastChangedDate: 2020-02-20 19:33:40 -0500 (Thu, 20 Feb 2020) $]
    
    
    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 compatibility 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 subversion tree should not remain unstable at any time.  Atomic 
        commits ought 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 SVN trunk 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 accommodate 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 responsibility 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
    ������httpd-2.4.64/ROADMAP��������������������������������������������������������������������������������0000664�0001751�0001751�00000023710�13623622544�013642� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������APACHE 2.x ROADMAP
    ==================
    Last modified at [$Date: 2020-02-20 19:33:40 -0500 (Thu, 20 Feb 2020) $]
    
    
    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 mechanism 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_negotiation
          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?
    ��������������������������������������������������������httpd-2.4.64/Makefile.win���������������������������������������������������������������������������0000664�0001751�0001751�00000150765�13446306656�015111� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile for Windows NT and Windows 95/98/2000
    
    # Targets are:
    #   _buildr   - build Apache in Release mode
    #   _buildd   - 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     /Apache24
    #   PORT        80
    #   SSLPORT     443
    #   DOMAINNAME  example.com
    #   SERVERNAME  www.example.com
    #   SERVERNAME  admin@example.com
    #
    #   ALL         (unset)     Includes additional modules for build testing
    #
    # Provide a DBD_LIST argument after configuring LIB and INCLUDE with
    # the SDK paths of the corresponding client support libraries.
    # The ODBC driver is always built on Windows
    #
    #     DBD_LIST="sqlite3 pgsql oracle mysql freetds"
    #
    # Provide a DBM_LIST argument after configuring LIB and INCLUDE with
    # the SDK paths of the corresponding client support libraries.
    # The sdbm driver is always built in.
    #
    #     DBM_LIST="db gdbm"
    #
    # For example;
    #
    #   nmake -f Makefile.win PORT=80 INSTDIR="d:\Program Files\Apache" installr
    #
    # Be aware that certain awk's will not accept backslashed names,
    # so the server root should be given in forward slashes (quoted),
    # preferably with the drive designation!
    
    !IF EXIST("Apache.sln") && ([devenv /help > NUL 2>&1] == 0) \
        && !defined(USEMAK) && !defined(USEDSW)
    USESLN=1
    USEMAK=0
    USEDSW=0
    !ELSEIF EXIST("httpd.mak") && !defined(USEDSW)
    USESLN=0
    USEMAK=1
    USEDSW=0
    !ELSE
    USESLN=0
    USEMAK=0
    USEDSW=1
    !ENDIF
    
    # APU 1.6 (and up?)
    !IF EXIST("srclib\apr-util\xml\xml.mak")
    EXPAT=xml
    EXPBCK = ..
    !ELSE
    EXPAT=xml\expat\lib
    EXPBCK = ..\..\..
    !ENDIF
    
    default: _buildr
    
    !IF ("$(CTARGET)" == "") && ($(USESLN) == 1)
    CTARGET=/build
    !ENDIF
    
    !IF EXIST("srclib\apr\include\apu.h")
    TLP=Apache-apr2
    UTILDIR=apr
    !ELSEIF !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 srclib dir.
    !MESSAGE Apache cannot build without these libraries!
    !MESSAGE 
    !ERROR Need srclib\  apr, apr-iconv and apr-util
    !ELSE
    TLP=Apache
    UTILDIR=apr-util
    !ENDIF
    
    !IF !EXIST("srclib\expat") && !EXIST("srclib\apr-util\xml\expat")
    !MESSAGE Please check out or download and unpack the current expat library source
    !MESSAGE under your srclib dir for apr 2.x, or srclib\apr-util\xml\expat for apr 1.x
    !MESSAGE Apache cannot build without this library!
    !MESSAGE 
    !ERROR Need srclib\expat or srclib\apr-util\xml\expat
    !ENDIF
    
    !IF !EXIST("srclib\pcre")
    !MESSAGE Please check out or download and unpack the current PCRE library source
    !MESSAGE under your srclib dir, and compile the pcre.dll with CMake options
    !MESSAGE BUILD_SHARED_LIBS and CMAKE_BUILD_TYPE RelWithDebInfo.
    !MESSAGE Apache cannot build without this library!
    !MESSAGE 
    !ERROR Need srclib\pcre
    !ENDIF
    
    
    # Note; _tryfoo: blocks are used only by the msvc developer studio environment 
    #	to 'fix up' the build, since conditional dependencies aren't supported.
    #
    
    !IF EXIST("srclib\openssl")
    !IF "$(LONG)" == "Debug" && EXIST("srclib\openssl\out32dll.dbg\openssl.exe")
    SSLBIN=out32dll.dbg
    SSLAPP=out32dll.dbg
    SSLCRP=libeay32
    SSLLIB=ssleay32
    !ELSEIF EXIST("srclib\openssl\libcrypto.lib")
    !MESSAGE Building with OpenSSL 1.1.0
    !MESSAGE 
    SSLBIN=.
    SSLAPP=apps
    SSLCRP=libcrypto
    SSLLIB=libssl
    SSLOPT=_HAVE_OSSL110=1
    !ELSE
    SSLBIN=out32dll
    SSLAPP=out32dll
    SSLCRP=libeay32
    SSLLIB=ssleay32
    !ENDIF
    
    
    _tryssl:
    !IF $(USEMAK) == 1
    	cd modules\ssl
    	$(MAKE) $(MAKEOPT) $(SSLOPT) -f mod_ssl.mak CFG="mod_ssl - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd support
    	$(MAKE) $(MAKEOPT) $(SSLOPT) -f abs.mak CFG="abs - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..
    !ELSEIF $(USESLN) == 1
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_ssl
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project abs
    !ELSE
    	@msdev $(TLP).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.8d.
    	@echo Available from http://www.openssl.org/
    !ENDIF
    #     NOT EXIST("srclib\openssl")
    
    !IF EXIST("srclib\zlib")
    
    _tryzlib:
    !IF $(USEMAK) == 1
    	cd modules\filters
    	$(MAKE) $(MAKEOPT) -f mod_deflate.mak CFG="mod_deflate - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ELSEIF $(USESLN) == 1
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_deflate
    !ELSE
    	@msdev $(TLP).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 built 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 EXIST("srclib\libxml2")
    
    _tryxml:
    !IF $(USEMAK) == 1
    	cd modules\filters
    	$(MAKE) $(MAKEOPT) -f mod_proxy_html.mak CFG="mod_proxy_html - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	$(MAKE) $(MAKEOPT) -f mod_xml2enc.mak CFG="mod_xml2enc - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ELSEIF $(USESLN) == 1
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_proxy_html
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_xml2enc
    !ELSE
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_proxy_html - Win32 $(LONG)" /NORECURSE $(CTARGET)
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_xml2enc - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    
    !ELSE
    #     NOT EXIST("srclib\libxml2")
    
    _tryxml:
    	@echo -----
    	@echo mod_proxy_html and mod_xml2enc will not build unless libxml2 is 
    	@echo built in srclib\libxml2. Version 2.7.7 and later available from
    	@echo http://xmlsoft.org/ will satisfy this requirement.
    
    !ENDIF
    
    
    !IF EXIST("srclib\lua")
    
    _trylua:
    !IF $(USEMAK) == 1
    	cd modules\lua
    	$(MAKE) $(MAKEOPT) -f mod_lua.mak CFG="mod_lua - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ELSEIF $(USESLN) == 1
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_lua
    !ELSE
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_lua - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    
    !ELSE
    #     NOT EXIST("srclib\lua")
    
    _trylua:
    	@echo -----
    	@echo mod_lua will not build unless lua is installed in srclib\lua.
    	@echo Version 5.1 includes an etc\luavs.bat that will satisfy this requirement.
    
    !ENDIF
    
    !IF EXIST("srclib\nghttp2")
    
    _trynghttp2:
    !IF $(USEMAK) == 1
    	cd modules\http2
    	$(MAKE) $(MAKEOPT) -f mod_http2.mak       CFG="mod_http2 - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	$(MAKE) $(MAKEOPT) -f mod_proxy_http2.mak CFG="mod_proxy_http2 - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ELSEIF $(USESLN) == 1
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_http2
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_proxy_http2
    !ELSE
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_http2 - Win32 $(LONG)" /NORECURSE $(CTARGET)
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_proxy_http2 - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    
    !ELSE
    #     NOT EXIST("srclib\nghttp2")
    
    _trynghttp2:
    	@echo -----
    	@echo mod_http2 will not build unless nghttp2 is installed in srclib\nghttp2.
    	@echo Version 1.0 includes an lib\makefile.msvc that will satisfy this
    	@echo requirement.
    
    !ENDIF
    
    !IF EXIST("srclib\brotli")
    
    _trybrotli:
    !IF $(USEMAK) == 1
    	cd modules\filters
    	$(MAKE) $(MAKEOPT) -f mod_brotli.mak CFG="mod_brotli - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ELSEIF $(USESLN) == 1
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_brotli
    !ELSE
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_brotli - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    
    !ELSE
    #     NOT EXIST("srclib\brotli")
    
    _trybrotli:
    	@echo -----
    	@echo mod_brotli will not build unless brotli is built in srclib\brotli.  
    	@echo Version 1.0.0 and later available from https://github.com/google/brotli/releases
    	@echo build with:
    	@echo cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
    	@echo nmake
    
    !ENDIF
    
    !IF EXIST("srclib\openssl") && EXIST("srclib\jansson") && EXIST("srclib\curl")
    
    _trymd:
    !IF $(USEMAK) == 1
    	cd modules\md
    	$(MAKE) $(MAKEOPT) $(SSLOPT) -f mod_md.mak CFG="mod_md - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ELSEIF $(USESLN) == 1
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_md
    !ELSE
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_md - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    
    !ELSE
    #     NOT EXIST("srclib\openssl") && EXIST("srclib\jansson") && EXIST("srclib\curl")
    
    _trymd:
    	@echo -----
    	@echo mod_md will not build unless OpenSSL, Jansson and Curl are built and placed
    	@echo in srclib. Example: srclib/openssl, srclib/jansson and srclib/curl
    
    !ENDIF
    
    _trydb:
    !IF $(USEMAK) == 1
    	cd srclib\$(UTILDIR)\dbd
    	for %d in (odbc $(DBD_LIST)) do \
    	  $(MAKE) $(MAKEOPT) -f apr_dbd_%d.mak CFG="apr_dbd_%d - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\dbm
    	for %d in ($(DBM_LIST) x) do if not %d == x \
    	  $(MAKE) $(MAKEOPT) -f apr_dbm_%d.mak CFG="apr_dbm_%d - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..\..
    !ELSEIF $(USESLN) == 1
    	for %d in (odbc $(DBD_LIST)) do \
    	  devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project apr_dbd_%d
    	for %d in ($(DBM_LIST) x) do if not %d == x \
    	  devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project apr_dbm_%d
    !ELSE
    	@for %d in (odbc $(DBD_LIST)) do \
    	  msdev $(TLP).dsw /USEENV /MAKE \
    		"apr_dbd_%d - Win32 $(LONG)" /NORECURSE $(CTARGET)
    	@for %d in ($(DBM_LIST) x) do if not %d == x \
    	  msdev $(TLP).dsw /USEENV /MAKE \
    		"apr_dbm_%d - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    
    
    !IF "$(INSTDIR)" == ""
    INSTDIR=\Apache24
    !ENDIF
    !IF "$(DOMAINNAME)" == ""
    DOMAINNAME=example.com
    !ENDIF 
    !IF "$(SERVERNAME)" == ""
    SERVERNAME=www.$(DOMAINNAME)
    !ENDIF
    !IF "$(SERVERADMIN)" == ""
    SERVERADMIN=admin@$(DOMAINNAME)
    !ENDIF
    !IF "$(PORT)" == ""
    PORT=80
    !ENDIF 
    !IF "$(SSLPORT)" == ""
    SSLPORT=443
    !ENDIF 
    
    !IF "$(LONG)" == ""
    !MESSAGE
    !MESSAGE INSTDIR     = $(INSTDIR)
    !MESSAGE DOMAINNAME  = $(DOMAINNAME)
    !MESSAGE SERVERNAME  = $(SERVERNAME)
    !MESSAGE SERVERADMIN = $(SERVERADMIN)
    !MESSAGE PORT        = $(PORT)
    !IF EXIST("srclib\openssl")
    !MESSAGE SSLPORT     = $(SSLPORT)
    !ENDIF
    !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
    !IFDEF _NMAKE_VER
    # 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 ..
    
    _buildr: 
    	@$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=R LONG=Release _build
    
    _buildd: 
    	@$(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 $(USEMAK) == 1
    
    _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)
    !IF !EXIST("srclib\apr-util")
    	cd srclib\expat\lib
    	 $(MAKE) $(MAKEOPT) -f expat.mak             CFG="expat - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..\..
    !ENDIF
    	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 ..\..
    !IF EXIST("srclib\apr-util")
    	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) $(MAKEOPT) -f Makefile.win all \
    		BUILD_MODE=$(LONG) BIND_MODE=shared
    	cd ..\ces
    	$(MAKE) $(MAKEOPT) -f Makefile.win all \
    		BUILD_MODE=$(LONG) BIND_MODE=shared
    	cd ..
    !ENDIF
    	cd ..\..
    	cd srclib\apr-util\$(EXPAT)
    	 $(MAKE) $(MAKEOPT) -f xml.mak             CFG="xml - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd $(EXPBCK)
    	 $(MAKE) $(MAKEOPT) $(SSLOPT) -f aprutil.mak         CFG="aprutil - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) $(SSLOPT) -f libaprutil.mak      CFG="libaprutil - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ldap
    	 $(MAKE) $(MAKEOPT) -f apr_ldap.mak        CFG="apr_ldap - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..
    !ELSE
    	# DBD, DBM components live now in apr
    	cd srclib\apr
    !ENDIF
    	cd dbd
    	  for %d in (odbc $(DBD_LIST)) do \
    	    $(MAKE) $(MAKEOPT) -f apr_dbd_%d.mak   CFG="apr_dbd_%d - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..
    	cd dbm
    	  for %d in ($(DBM_LIST) x) do if not %d == x \
    	    $(MAKE) $(MAKEOPT) -f apr_dbm_%d.mak   CFG="apr_dbm_%d - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..
    	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\database
    	 $(MAKE) $(MAKEOPT) -f mod_dbd.mak         CFG="mod_dbd - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd modules\aaa
    	 $(MAKE) $(MAKEOPT) -f mod_access_compat.mak CFG="mod_access_compat - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_allowmethods.mak CFG="mod_allowmethods - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(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_auth_form.mak   CFG="mod_auth_form - 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_core.mak  CFG="mod_authn_core - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_authn_dbd.mak   CFG="mod_authn_dbd - 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_file.mak  CFG="mod_authn_file - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_authn_socache.mak  CFG="mod_authn_socache - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_authnz_fcgi.mak CFG="mod_authnz_fcgi - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_authnz_ldap.mak CFG="mod_authnz_ldap - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_authz_core.mak  CFG="mod_authz_core - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_authz_dbd.mak   CFG="mod_authz_dbd - 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_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_owner.mak CFG="mod_authz_owner - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_authz_user.mak  CFG="mod_authz_user - 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_cache_disk.mak  CFG="mod_cache_disk - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_cache_socache.mak  CFG="mod_cache_socache - 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_socache_dbm.mak CFG="mod_socache_dbm - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    #	 $(MAKE) $(MAKEOPT) -f mod_socache_dc.mak  CFG="mod_socache_dc - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_socache_memcache.mak CFG="mod_socache_memcache - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_socache_shmcb.mak CFG="mod_socache_shmcb - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_socache_redis.mak CFG="mod_socache_redis - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd modules\core
    	 $(MAKE) $(MAKEOPT) -f mod_macro.mak    CFG="mod_macro - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_watchdog.mak    CFG="mod_watchdog - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd modules\cluster
    	 $(MAKE) $(MAKEOPT) -f mod_heartbeat.mak   CFG="mod_heartbeat - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_heartmonitor.mak CFG="mod_heartmonitor - 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\dav\lock
    	 $(MAKE) $(MAKEOPT) -f mod_dav_lock.mak    CFG="mod_dav_lock - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..\..
    	cd modules\debugging
    !IFDEF ALL
    	 $(MAKE) $(MAKEOPT) -f mod_bucketeer.mak   CFG="mod_bucketeer - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    !ENDIF
    	 $(MAKE) $(MAKEOPT) -f mod_dumpio.mak      CFG="mod_dumpio - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd modules\echo
    !IFDEF ALL
    	 $(MAKE) $(MAKEOPT) -f mod_echo.mak        CFG="mod_echo - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    !ENDIF
    	cd ..\..
    !IFDEF ALL
    	cd modules\examples
    	 $(MAKE) $(MAKEOPT) -f mod_case_filter.mak    CFG="mod_case_filter - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_case_filter_in.mak CFG="mod_case_filter_in - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_example_hooks.mak  CFG="mod_example_hooks - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_example_ipc.mak    CFG="mod_example_ipc - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ENDIF
    	cd modules\filters
    !IF EXIST("srclib\brotli")
    	 $(MAKE) $(MAKEOPT) -f mod_brotli.mak      CFG="mod_brotli - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    !ENDIF
    	 $(MAKE) $(MAKEOPT) -f mod_buffer.mak      CFG="mod_buffer - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_charset_lite.mak CFG="mod_charset_lite - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_data.mak        CFG="mod_data - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    !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_filter.mak      CFG="mod_filter - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_include.mak     CFG="mod_include - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    !IF EXIST("srclib\libxml2")
    	 $(MAKE) $(MAKEOPT) -f mod_proxy_html.mak     CFG="mod_proxy_html - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_xml2enc.mak     CFG="mod_xml2enc - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    !ENDIF
    	 $(MAKE) $(MAKEOPT) -f mod_ratelimit.mak   CFG="mod_ratelimit - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_reflector.mak   CFG="mod_reflector - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_reqtimeout.mak  CFG="mod_reqtimeout - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_request.mak     CFG="mod_request - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_sed.mak         CFG="mod_sed - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_substitute.mak  CFG="mod_substitute - 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_debug.mak  CFG="mod_log_debug - 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 ..\..
    !IF EXIST("srclib\lua")
    	cd modules\lua
    	 $(MAKE) $(MAKEOPT) -f mod_lua.mak         CFG="mod_lua - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ENDIF
    	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 ..\..
    !IF EXIST("srclib\openssl") && EXIST("srclib\jansson") && EXIST("srclib\curl")
    	cd modules\md
    	 $(MAKE) $(MAKEOPT) $(SSLOPT) -f mod_md.mak          CFG="mod_md - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ENDIF
    	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_remoteip.mak    CFG="mod_remoteip - 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_express.mak CFG="mod_proxy_express - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_proxy_fcgi.mak  CFG="mod_proxy_fcgi - 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_hcheck.mak  CFG="mod_proxy_hcheck - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_proxy_http.mak  CFG="mod_proxy_http - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_proxy_scgi.mak  CFG="mod_proxy_scgi - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_proxy_uwsgi.mak  CFG="mod_proxy_uwsgi - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_proxy_wstunnel.mak  CFG="mod_proxy_wstunnel - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd modules\proxy\balancers
    	 $(MAKE) $(MAKEOPT) -f mod_lbmethod_bybusyness.mak CFG="mod_lbmethod_bybusyness - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_lbmethod_byrequests.mak CFG="mod_lbmethod_byrequests - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_lbmethod_bytraffic.mak  CFG="mod_lbmethod_bytraffic - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_lbmethod_heartbeat.mak  CFG="mod_lbmethod_heartbeat - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..\..
    # mod_proxy_http2 must be built after mod_proxy and mod_http2
    !IF EXIST("srclib\nghttp2")
    	cd modules\http2
    	 $(MAKE) $(MAKEOPT) -f mod_http2.mak         CFG="mod_http2 - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_proxy_http2.mak   CFG="mod_proxy_http2 - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !ENDIF
    	cd modules\session
    	 $(MAKE) $(MAKEOPT) -f mod_session.mak        CFG="mod_session - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_session_cookie.mak CFG="mod_session_cookie - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_session_dbd.mak    CFG="mod_session_dbd - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd modules\slotmem
    	 $(MAKE) $(MAKEOPT) -f mod_slotmem_plain.mak  CFG="mod_slotmem_plain - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f mod_slotmem_shm.mak    CFG="mod_slotmem_shm - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    !IF EXIST("srclib\openssl")
    #	cd modules\session
    #	 $(MAKE) $(MAKEOPT) -f mod_session_crypto.mak CFG="mod_session_crypto - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    #	cd ..\..
    	cd modules\ssl
    	 $(MAKE) $(MAKEOPT) $(SSLOPT) -f mod_ssl.mak         CFG="mod_ssl - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	cd ..\..
    	cd support
    	 $(MAKE) $(MAKEOPT) $(SSLOPT) -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 fcgistarter.mak     CFG="fcgistarter - Win32 $(LONG)" RECURSE=0 $(CTARGET)
    	 $(MAKE) $(MAKEOPT) -f htcacheclean.mak    CFG="htcacheclean - 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 httxt2dbm.mak       CFG="httxt2dbm - 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 $(USESLN) == 1
    
    _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)
    !IFDEF ALL
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project BuildAll
    !ELSE
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project BuildBin
    !ENDIF
    !IF EXIST("srclib\openssl")
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_ssl
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project abs
    !ENDIF
    !IF EXIST("srclib\zlib")
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_deflate
    !ENDIF
    !IF EXIST("srclib\lua")
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_lua
    !ENDIF
    !IF EXIST("srclib\libxml2")
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_proxy_html
    	devenv $(TLP).sln /useenv $(CTARGET) $(LONG) /project mod_xml2enc
    !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)
    !IFDEF ALL
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"BuildAll - Win32 $(LONG)" $(CTARGET)
    !ELSE
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"BuildBin - Win32 $(LONG)" $(CTARGET)
    !ENDIF
    !IF "$(CTARGET)" == "/CLEAN"
    !IF EXIST("srclib\apr-iconv")
    	@cd srclib\apr-iconv
    	@$(MAKE) $(MAKEOPT) -f build\modules.mk.win clean \
    		BUILD_MODE=$(LONG) BIND_MODE=shared API_SOURCE=.
    	@cd ..\..
    !ENDIF
    !ENDIF
    !IF EXIST("srclib\openssl")
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_ssl - Win32 $(LONG)" \
    		"abs - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    !IF EXIST("srclib\zlib")
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_deflate - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    !IF EXIST("srclib\lua")
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_lua - Win32 $(LONG)" /NORECURSE $(CTARGET)
    !ENDIF
    !IF EXIST("srclib\libxml2")
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_proxy_html - Win32 $(LONG)" /NORECURSE $(CTARGET)
    	@msdev $(TLP).dsw /USEENV /MAKE \
    		"mod_xml2enc - 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
    !IF EXIST("srclib\apr-util")
    	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 srclib\apr-util\ldap\$(LONG)\apr_ldap-1.$(src_dll) "$(inst_dll)" <.y
    !ENDIF
    	for %d in (odbc $(DBD_LIST)) do ( \
    	  copy srclib\$(UTILDIR)\dbd\$(LONG)\apr_dbd_%d-1.$(src_dll) "$(inst_dll)" <.y \
    	)
    	for %d in ($(DBM_LIST) x) do if not %d == x ( \
    	  copy srclib\$(UTILDIR)\dbm\$(LONG)\apr_dbm_%d-1.$(src_dll) "$(inst_dll)" <.y \
    	)
    !IF "$(SHORT)" == "D"
    	copy srclib\pcre\pcred.$(src_dll)			"$(inst_dll)" <.y
    !ELSE
    	copy srclib\pcre\pcre.$(src_dll)			"$(inst_dll)" <.y
    !ENDIF	
    	copy modules\aaa\$(LONG)\mod_access_compat.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_allowmethods.$(src_so) 	"$(inst_so)" <.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_auth_form.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authn_anon.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authn_core.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authn_dbd.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authn_dbm.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authn_file.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authn_socache.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authnz_fcgi.$(src_so)	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authnz_ldap.$(src_so)	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authz_core.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authz_dbd.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authz_dbm.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authz_core.$(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_owner.$(src_so) 	"$(inst_so)" <.y
    	copy modules\aaa\$(LONG)\mod_authz_user.$(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_cache_disk.$(src_so)	"$(inst_so)" <.y
    	copy modules\cache\$(LONG)\mod_cache_socache.$(src_so)	"$(inst_so)" <.y
    	copy modules\cache\$(LONG)\mod_file_cache.$(src_so) 	"$(inst_so)" <.y
    	copy modules\cache\$(LONG)\mod_socache_dbm.$(src_so)	"$(inst_so)" <.y
    #	copy modules\cache\$(LONG)\mod_socache_dc.$(src_so)	"$(inst_so)" <.y
    	copy modules\cache\$(LONG)\mod_socache_memcache.$(src_so) "$(inst_so)" <.y
    	copy modules\cache\$(LONG)\mod_socache_shmcb.$(src_so)	"$(inst_so)" <.y
    	copy modules\cache\$(LONG)\mod_socache_redis.$(src_so)	"$(inst_so)" <.y
    	copy modules\core\$(LONG)\mod_macro.$(src_so) 	"$(inst_so)" <.y
    	copy modules\core\$(LONG)\mod_watchdog.$(src_so) 	"$(inst_so)" <.y
    	copy modules\cluster\$(LONG)\mod_heartbeat.$(src_so)	"$(inst_so)" <.y
    	copy modules\cluster\$(LONG)\mod_heartmonitor.$(src_so)	"$(inst_so)" <.y
    	copy modules\database\$(LONG)\mod_dbd.$(src_so)		"$(inst_so)" <.y
    	copy modules\dav\fs\$(LONG)\mod_dav_fs.$(src_so) 	"$(inst_so)" <.y
    	copy modules\dav\lock\$(LONG)\mod_dav_lock.$(src_so) 	"$(inst_so)" <.y
    	copy modules\dav\main\$(LONG)\mod_dav.$(src_so)		"$(inst_so)" <.y
    !IFDEF ALL
    	copy modules\debugging\$(LONG)\mod_bucketeer.$(src_so)	"$(inst_so)" <.y
    !ENDIF
    	copy modules\debugging\$(LONG)\mod_dumpio.$(src_so)	"$(inst_so)" <.y
    !IFDEF ALL
    	copy modules\echo\$(LONG)\mod_echo.$(src_so)		"$(inst_so)" <.y
    	copy modules\examples\$(LONG)\mod_case_filter.$(src_so)    "$(inst_so)" <.y
    	copy modules\examples\$(LONG)\mod_case_filter_in.$(src_so) "$(inst_so)" <.y
    	copy modules\examples\$(LONG)\mod_example_hooks.$(src_so)  "$(inst_so)" <.y
    	copy modules\examples\$(LONG)\mod_example_ipc.$(src_so)	   "$(inst_so)" <.y
    !ENDIF
    !IF EXIST("srclib\brotli")
    	copy modules\filters\$(LONG)\mod_brotli.$(src_so) 	"$(inst_so)" <.y
    !ENDIF
    	copy modules\filters\$(LONG)\mod_buffer.$(src_so) 	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_charset_lite.$(src_so)	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_data.$(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_filter.$(src_so) 	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_include.$(src_so) 	"$(inst_so)" <.y
    !IF EXIST("srclib\libxml2")
    	copy modules\filters\$(LONG)\mod_proxy_html.$(src_so) 	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_xml2enc.$(src_so) 	"$(inst_so)" <.y
    !IF EXIST("srclib\libxml2\win32\bin.msvc\libxml2.$(src_dll)")
    	copy srclib\libxml2\win32\bin.msvc\libxml2.$(src_dll)		 	"$(inst_dll)" <.y
    !ENDIF
    !ENDIF
    	copy modules\filters\$(LONG)\mod_ratelimit.$(src_so) 	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_reflector.$(src_so) 	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_reqtimeout.$(src_so) 	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_request.$(src_so) 	"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_sed.$(src_so) 		"$(inst_so)" <.y
    	copy modules\filters\$(LONG)\mod_substitute.$(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
    !IF EXIST("srclib\nghttp2")
    	copy modules\http2\$(LONG)\mod_http2.$(src_so) 		"$(inst_so)" <.y
    	copy modules\http2\$(LONG)\mod_proxy_http2.$(src_so) 		"$(inst_so)" <.y
    !IF "$(SHORT)" == "D"
    	copy srclib\nghttp2\lib\MSVC_obj\nghttp2d.$(src_dll)		 	"$(inst_dll)" <.y
    !ELSE
    	copy srclib\nghttp2\lib\MSVC_obj\nghttp2.$(src_dll)		 	"$(inst_dll)" <.y
    !ENDIF
    !ENDIF
    	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_debug.$(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
    !IF EXIST("srclib\lua")
    	copy modules\lua\$(LONG)\mod_lua.$(src_so) 		"$(inst_so)" <.y
    !IF EXIST("srclib\lua\src\lua51.$(src_dll)")
    	copy srclib\lua\src\lua51.$(src_dll)		 	"$(inst_dll)" <.y
    !ENDIF
    !ENDIF
    	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
    !IF EXIST("srclib\openssl") &&  EXIST("srclib\jansson") &&  EXIST("srclib\curl")
    	copy modules\md\$(LONG)\mod_md.$(src_so) 		"$(inst_so)" <.y
    !IF "$(SHORT)" == "D"
    	-copy srclib\curl\bin\libcurl_debug.$(src_dll)		"$(inst_dll)" <.y
    	-copy srclib\jansson\bin\jansson_d.$(src_dll)		"$(inst_dll)" <.y
    !ELSE
    	-copy srclib\curl\bin\libcurl.$(src_dll)		"$(inst_dll)" <.y
    	-copy srclib\jansson\bin\jansson.$(src_dll)		"$(inst_dll)" <.y
    !ENDIF
    !ENDIF
    	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_remoteip.$(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_express.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\$(LONG)\mod_proxy_fcgi.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\$(LONG)\mod_proxy_ftp.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\$(LONG)\mod_proxy_hcheck.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\$(LONG)\mod_proxy_http.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\$(LONG)\mod_proxy_scgi.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\$(LONG)\mod_proxy_uwsgi.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\$(LONG)\mod_proxy_wstunnel.$(src_so) 	"$(inst_so)" <.y
    	copy modules\proxy\balancers\$(LONG)\mod_lbmethod_bybusyness.$(src_so) "$(inst_so)" <.y
    	copy modules\proxy\balancers\$(LONG)\mod_lbmethod_byrequests.$(src_so) "$(inst_so)" <.y
    	copy modules\proxy\balancers\$(LONG)\mod_lbmethod_bytraffic.$(src_so)  "$(inst_so)" <.y
    	copy modules\proxy\balancers\$(LONG)\mod_lbmethod_heartbeat.$(src_so)  "$(inst_so)" <.y
    	copy modules\session\$(LONG)\mod_session.$(src_so)        "$(inst_so)" <.y
    	copy modules\session\$(LONG)\mod_session_cookie.$(src_so) "$(inst_so)" <.y
    	copy modules\session\$(LONG)\mod_session_dbd.$(src_so)    "$(inst_so)" <.y
    	copy modules\slotmem\$(LONG)\mod_slotmem_plain.$(src_so)    "$(inst_so)" <.y
    	copy modules\slotmem\$(LONG)\mod_slotmem_shm.$(src_so)    "$(inst_so)" <.y
    !IF EXIST("srclib\openssl")
    #	copy modules\session\$(LONG)\mod_session_crypto.$(src_so) "$(inst_so)" <.y
    	copy modules\ssl\$(LONG)\mod_ssl.$(src_so) 		"$(inst_so)" <.y
    	-copy srclib\openssl\$(SSLBIN)\$(SSLCRP)*.$(src_dll) 	"$(inst_dll)" <.y
    	-copy srclib\openssl\$(SSLBIN)\$(SSLLIB)*.$(src_dll) 	"$(inst_dll)" <.y
    	-copy srclib\openssl\$(SSLAPP)\openssl.$(src_exe) 	"$(inst_exe)" <.y
    	copy support\$(LONG)\abs.$(src_exe) 			"$(inst_exe)" <.y
    !ENDIF
    	copy support\$(LONG)\ab.$(src_exe) 			"$(inst_exe)" <.y
    #	copy support\$(LONG)\fcgistarter.$(src_exe)		"$(inst_exe)" <.y
    	copy support\$(LONG)\htcacheclean.$(src_exe)		"$(inst_exe)" <.y
    	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)\httxt2dbm.$(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"
    !IF EXIST("srclib\apr-util")
    	-mkdir "$(INSTDIR)\bin\iconv"
    !ENDIF
    	-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"
    	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 NOTICE       "$(INSTDIR)\NOTICE.txt" <.y
    	copy README       "$(INSTDIR)\README.txt" <.y
    	type << >> "$(INSTDIR)\NOTICE.txt"
    
    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/
    <<
    	-awk -f <<script1.awk < "srclib\pcre\LICENCE" >> "$(INSTDIR)\LICENSE.txt"
    BEGIN {
        print "";
        print "For the pcre.dll component:";
        print "";
        while ( getline > 0 ) {
    	if ( $$0 ~ /^End$$/ ) $$0 = "END OF PCRE LICENSE";
    	print $$0;
       }
    }
    <<
    !IF EXIST("srclib\openssl")
    	-copy srclib\openssl\apps\openssl.cnf "$(INSTDIR)\conf\openssl.cnf" <.y
    	type << >> "$(INSTDIR)\NOTICE.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 openssl.exe components:";
        print "";
        while ( getline > 0 ) {
    	print $$0;
       }
    }
    <<
    	copy << "$(INSTDIR)\OPENSSL-NEWS.txt" <.y
    
     Apache HTTP Server 2.4 Limited OpenSSL Distribution
    
     This binary distribution includes the minimal components of OpenSSL required
     to support mod_ssl for Apache HTTP Server version 2.4 (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 "$(INSTDIR)\OPENSSL-NEWS.txt" \
    	    + srclib\openssl\NEWS "$(INSTDIR)\OPENSSL-NEWS.txt"
    	copy << "$(INSTDIR)\OPENSSL-README.txt" <.y
    
     Apache HTTP Server 2.4 Limited OpenSSL Distribution
    
     This binary installation of OpenSSL is a limited distribution of the
     files derived from the OpenSSL project:
    
       LICENSE.txt (includes openssl LICENSE)
       OPENSSL-NEWS.txt
       OPENSSL-README.txt
       conf\openssl.cnf
       bin\libeay32.dll
       bin\ssleay32.dll
       bin\openssl.exe
    
     These are the minimal libraries and tools required to use mod_ssl as 
     distributed with Apache HTTP Server version 2.4.  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.
    
    --------------------------------------------------------------------------------
    
    <<
    	-copy "$(INSTDIR)\OPENSSL-README.txt" \
    	    + srclib\openssl\README "$(INSTDIR)\OPENSSL-README.txt"
    !ENDIF
    !IF EXIST("srclib\zlib")
    	type << >> "$(INSTDIR)\NOTICE.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
    !IF EXIST("srclib\lua")
    	type << >> "$(INSTDIR)\NOTICE.txt"
    
    This binary distribution of mod_lua.so includes the Lua language, 
    developed at Lua.org, a laboratory of the Department of Computer Science 
    of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro in Brazil).
    For complete information, visit Lua's web site at http://www.lua.org/
    <<
    	-awk -f <<script.awk < "srclib\lua\COPYRIGHT" >> "$(INSTDIR)\LICENSE.txt"
    BEGIN {
        print "";
        print "For the mod_lua language component:";
        print "";
        while ( getline > 0 && $$0 !~ /end of COPYRIGHT/ ) {
    	print $$0;
        }
        exit 0;
    }
    <<
    !ENDIF
    !IF EXIST("srclib\libxml2")
    	type << >> "$(INSTDIR)\NOTICE.txt"
    
    This binary distributions of mod_proxy_html.so and mod_xml2enc.so include the
    libxml2 C library written by Daniel Veillard (daniel veillard.com), Bjorn 
    Reese (breese users.sourceforge.net) and Gary Pennington (Gary.Pennington 
    uk.sun.com). For complete information, visit LibXML2's web site at 
    https://http://www.xmlsoft.org/
    <<
    	-awk -f <<script.awk < "srclib\libxml2\Copyright" >> "$(INSTDIR)\LICENSE.txt"
    BEGIN {
        print "";
        print "For the mod_proxy_html and mod_xml2enc components:";
        print "";
    	    while ( getline > 0 ) {
    	print $$0;
        }
        exit 0;
    }
    <<
    !ENDIF
    !IF EXIST("srclib\nghttp2")
    	type << >> "$(INSTDIR)\NOTICE.txt"
    
    This binary distribution of mod_http2.so includes nghttp2 C library written 
    by Tatsuhiro Tsujikawa. For complete information, visit nghttp2's web site 
    at https://nghttp2.org/
    <<
    	-awk -f <<script.awk < "srclib\nghttp2\COPYING" >> "$(INSTDIR)\LICENSE.txt"
    BEGIN {
        print "";
        print "For the mod_http2 component:";
        print "";
    	    while ( getline > 0 ) {
    	print $$0;
        }
        exit 0;
    }
    <<
    !ENDIF
    !IF EXIST("srclib\brotli")
    	type << >> "$(INSTDIR)\NOTICE.txt"
    
    This binary distribution of mod_brotli.so includes Brotli C library written 
    by the Brotli Authors. For complete information, visit Brotli's web site 
    at https://github.com/google/brotli
    <<
    	-awk -f <<script.awk < "srclib\brotli\LICENSE" >> "$(INSTDIR)\LICENSE.txt"
    BEGIN {
        print "";
        print "For the mod_brotli component:";
        print "";
    	    while ( getline > 0 ) {
    	print $$0;
        }
        exit 0;
    }
    <<
    !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            \
    		inst_exe="$(INSTDIR)\bin"                              \
    		inst_dll="$(INSTDIR)\bin"                              \
    		inst_so="$(INSTDIR)\modules"
    !IF EXIST("srclib\apr-util")
     	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 ..\..
    !ENDIF
    	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
    	for %f in ( \
    		srclib\expat\lib\expat.h \
    		srclib\apr-util\xml\expat\lib\expat.h \
    		srclib\apr\include\*.h \
    		srclib\apr-util\include\*.h \
    		include\*.h \
    		os\win32\os.h \
    		modules\cache\mod_cache.h \
    		modules\cache\cache_common.h \
    		modules\core\mod_so.h \
    		modules\core\mod_watchdog.h \
    		modules\database\mod_dbd.h \
    		modules\dav\main\mod_dav.h \
    		modules\filters\mod_include.h \
    		modules\generators\mod_cgi.h \
    		modules\generators\mod_status.h \
    		modules\http2\mod_http2.h \
    		modules\loggers\mod_log_config.h \
    		modules\mappers\mod_rewrite.h \
    		modules\proxy\mod_proxy.h \
    		modules\ssl\mod_ssl.h \
    		modules\ssl\mod_ssl_openssl.h \
              ) do \
    	    @copy %f "$(INSTDIR)\include" < .y > nul
    	copy srclib\apr\Lib$(SHORT)\apr-1.lib		"$(INSTDIR)\lib" <.y
    	copy srclib\apr\Lib$(SHORT)\apr-1.pdb		"$(INSTDIR)\lib" <.y
    	copy srclib\apr\$(LONG)\libapr-1.lib 		"$(INSTDIR)\lib" <.y
    	copy srclib\apr\$(LONG)\libapr-1.exp 		"$(INSTDIR)\lib" <.y
    !IF EXIST("srclib\apr-util")
    	copy srclib\apr-util\Lib$(SHORT)\aprutil-1.lib	"$(INSTDIR)\lib" <.y
    	copy srclib\apr-util\Lib$(SHORT)\aprutil-1.pdb	"$(INSTDIR)\lib" <.y
    	copy srclib\apr-util\$(EXPAT)\Lib$(SHORT)\xml.lib "$(INSTDIR)\lib" <.y
    	copy srclib\apr-util\$(EXPAT)\Lib$(SHORT)\xml.pdb "$(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 srclib\apr-iconv\$(LONG)\libapriconv-1.lib	"$(INSTDIR)\lib" <.y
    	copy srclib\apr-iconv\$(LONG)\libapriconv-1.exp "$(INSTDIR)\lib" <.y
    !ELSE
    	copy srclib\expat\win32\$(LONG)\libexpatMT.lib  "$(INSTDIR)\lib" <.y
    	copy srclib\expat\win32\$(LONG)\libexpatMT.exp  "$(INSTDIR)\lib" <.y
    	copy srclib\expat\win32\$(LONG)\libexpat.lib    "$(INSTDIR)\lib" <.y
    	copy srclib\expat\win32\$(LONG)\libexpat.exp    "$(INSTDIR)\lib" <.y
    	copy srclib\expat\win32\$(LONG)\libexpat.dll    "$(INSTDIR)\bin" <.y
    !ENDIF
    	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
    	for %f in ( charset.conv magic mime.types ) do ( \
    	  copy docs\conf\%f "$(INSTDIR)\conf\original\%f" <.y )
    	awk -f build\installwinconf.awk $(DOMAINNAME) $(SERVERNAME) \
    	    $(SERVERADMIN) $(PORT) $(SSLPORT) "$(INSTDIR) " docs/conf/ 
    	copy "support\dbmmanage.in" "$(INSTDIR)\bin\dbmmanage.pl"
    	-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
    �����������httpd-2.4.64/buildconf������������������������������������������������������������������������������0000775�0001751�0001751�00000024667�13154520653�014540� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh
    #
    # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You under the Apache License, Version 2.0
    # (the "License"); you may not use this file except in compliance with
    # the License.  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT 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.
    
    # version check for AC_PROG_CC_C99
    ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|sed -e 's/^[^0-9]*//;s/[a-z]* *$//;q'`
    case "$ac_version" in
    # versions older than 2.50 are denied by AC_PREREQ
    2.5*)
        echo WARNING: You are using an outdated version of autoconf.
        echo WARNING: This may lead to less than optimal performance of httpd.
        echo WARNING: You should use autoconf 2.60 or newer.
        sleep 1
        ;;
    esac
    
    # 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=""
    
    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
            ;;
    
        --with-apr-util=*)
            apu_src_dir=$optarg
            ;;
    
        -h|--help)
            cat <<EOF
    buildconf: generates the files needed to configure httpd.
    
    Usage: $0 [OPTION]...
    
    Configuration:
      -h, --help               display this help and exit
    
      --with-apr=SRCDIR        define a space-separated list of directories to
                               search for the APR source code. If, instead of a
                               directory, an apr-config executable name is passed,
                               APR-Config Mode is enabled (see below). Defaults to
                               "srclib/apr ../apr"
      --with-apr-util=SRCDIR   define a space-separated list of directories to
                               search for the APR-util source code. Defaults to the
                               same location as the --with-apr SRCDIR, but with
                               "apr" replaced with "apr-util" or "aprutil". Ignored
                               in APR-Config Mode.
    
    APR-Config Mode:
    
      When passing an apr-config executable to --with-apr, buildconf will attempt to
      copy build scripts from various installed locations on your system instead of
      an APR source tree. This allows you to configure httpd from source without
      also requiring you to download the APR and/or APR-util sources.
    
      For example:
    
          ./buildconf --with-apr=apr-1-config
    
      For this functionality to work reliably, you must have automake >= 1.12 and be
      using a distribution that includes both find_apr.m4 and find_apu.m4 in the
      --installbuilddir pointed to by apr-config.
    
    Environment variables used by buildconf:
      AUTOCONF           autoconf executable name [autoconf]
      AUTOMAKE           automake executable name [automake]
      AUTOHEADER         autoheader executable name [autoheader]
    EOF
            exit
            ;;
    
        *)
            echo "unknown option $1 (try --help for usage)"
            exit 1
            ;;
        esac
    
        shift
    done
    
    #
    # Check to be sure that we have the srclib dependencies checked-out, or that a
    # working apr-config installation has been specified.
    #
    
    should_exit=0
    apr_config=         # path to apr-config (empty if using a source directory)
    apr_found=0
    apu_found=0
    apr_major_version=2
    
    for dir in $apr_src_dir
    do
        if [ -f "${dir}/build/apr_common.m4" ]; then
            echo "found apr source: ${dir}"
            apr_src_dir=$dir
            apr_found=1
            break
        elif which "${dir}" >/dev/null 2>&1; then
            # We're using apr-config. Do a sanity check.
            apr_config=`which "${dir}"`
            echo "testing apr-config executable: ${apr_config}"
    
            version=`"${apr_config}" --version`
            version=`echo "${version}" | sed -n '/^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/p'`
    
            if [ -z "${version}" ]; then
                echo "apr-config gave us an invalid --version"
                apr_config=
                continue
            fi
    
            echo "using apr-config version ${version}"
            apr_major_version=${version} # we'll make a real "major version" later
            apr_src_dir=`"${apr_config}" --installbuilddir`
            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
    elif [ -n "${apr_config}" ]; then
        apr_major_version=`echo "${apr_major_version}" | sed 's/\..*//'`
    else
        apr_major_version=`grep "#define APR_MAJOR_VERSION" \
                          $apr_src_dir/include/apr_version.h | sed 's/[^0-9]//g'`
    fi
    
    # Find APR-util. Note: if we're using apr-config, we can completely skip this,
    # even if APR is version 1. That's because we only end up caring about
    # find_apu.m4, which is not actually installed in the standard APR-util
    # distribution to begin with.
    if [ -z "${apr_config}" -a $apr_major_version -lt 2 ] ; then
        if test -z "$apu_src_dir"; then
            apu_src_dir=`echo $apr_src_dir | sed -e 's#/apr#/apr-util#g;'`
            apu_src_dir="$apu_src_dir `echo $apr_src_dir | sed -e 's#/apr#/aprutil#;g'`"
            apu_src_dir="$apu_src_dir srclib/apr-util ../apr-util"
        fi
    
        for dir in $apu_src_dir
        do
            if [ -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/branches/1.5.x srclib/apr-util"
            echo ""
            should_exit=1
        fi
    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
    
    # Remove autoconf 2.5x cache directories
    rm -rf autom4te*.cache
    
    case "`uname`" in
    *BSD/OS*)
        ./build/bsd_makefile;;
    esac
    #
    # end temporary stuff
    
    apr_configure="$apr_src_dir/configure"
    if [ $apr_major_version -lt 2 ] ; then
        aprutil_configure="$apu_src_dir/configure"
    fi
    config_h_in="include/ap_config_auto.h.in"
    
    cross_compile_warning="warning: AC_TRY_RUN called without default to allow cross compiling"
    
    if [ "$apr_src_dir" = "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
    
    apr_src_dir=`cd $apr_src_dir && pwd` 
    
    if [ $apr_major_version -lt 2 ] ; then
        if [ "$apu_src_dir" = "srclib/apr-util" ]; then
            echo rebuilding $aprutil_configure
            (cd srclib/apr-util && ./buildconf --with-apr=$apr_src_dir) || {
                echo "./buildconf failed for apr-util" 
                exit 1
            }
            rm -f srclib/apr-util/apr-util.spec
        fi
    
        apu_src_dir=`cd $apu_src_dir && pwd`
    fi
    
    echo copying build files
    if [ -n "${apr_config}" ]; then
        # If we're using apr-config, we switch things up a little bit:
        # - use automake's config.* scripts instead of APR's
        # - use the included PrintPath instead of copying from APR
        # - assume find_apu.m4 is also in APR's --installbuilddir
    
        # Figure out where to copy config.* from.
        automake=${AUTOMAKE:-automake}
        am_libdir=`"${automake}" --print-libdir`
        cp "${am_libdir}/config.guess" "${am_libdir}/config.sub" build
    
        # Remember that in this case, $apr_src_dir points to the build directory.
        cp "$apr_src_dir/apr_common.m4" "$apr_src_dir/find_apr.m4" build
        if [ $apr_major_version -lt 2 ] ; then
            cp "$apr_src_dir/find_apu.m4" build
        fi
    else
        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 build
        if [ $apr_major_version -lt 2 ] ; then
            cp $apu_src_dir/build/find_apu.m4 build
        fi
    fi
    
    # 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)
    
    if [ -z "${apr_config}" ]; then
        # 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
    fi
    
    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
    
    if [ -f `which cut` ]; then
      echo rebuilding rpm spec file
      ( VMMN=`build/get-version.sh mmn include/ap_mmn.h MODULE_MAGIC_NUMBER`
        EPOCH=`build/get-version.sh epoch include/ap_release.h AP_SERVER`
        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/" \
            -e "s/APACHE_EPOCH/$EPOCH/" \
        > httpd.spec )
    fi
    
    # ensure that the ap_expr expression parser sources are never regenerated
    # when running make
    echo fixing timestamps for ap_expr sources
    cd server
    touch util_expr_parse.y util_expr_scan.l
    sleep 1
    touch util_expr_parse.c util_expr_parse.h util_expr_scan.c
    cd ..
    
    exit 0
    �������������������������������������������������������������������������httpd-2.4.64/BuildBin.dsp���������������������������������������������������������������������������0000664�0001751�0001751�00000005340�13226637151�015032� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 "\Apache2\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="\Apache2" LONG=Release _trydb _trylua _tryxml _tryssl _tryzlib _trynghttp2 _trybrotli _trymd _dummy"
    # PROP Rebuild_Opt ""
    # PROP Target_File "\Apache2\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 "\Apache2\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="\Apache2" LONG=Debug _trydb _trylua _tryxml _tryssl _tryzlib _trynghttp2 _trybrotli _trymd _dummy"
    # PROP Rebuild_Opt ""
    # PROP Target_File "\Apache2\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
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/Apache.dsw�����������������������������������������������������������������������������0000664�0001751�0001751�00000237777�13446306656�014566� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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: "BuildAll"=.\BuildAll.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name BuildBin
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_bucketeer
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_case_filter
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_case_filter_in
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_echo
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_example_hooks
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_example_ipc
        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 apr_ldap
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libapriconv_ces_modules
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name libapriconv_ccs_modules
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_access_compat
        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_allowmethods
        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_auth_form
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_anon
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_core
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_dbm
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_file
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authn_socache
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authnz_fcgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authnz_ldap
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authz_core
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authz_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_authz_dbm
        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_owner
        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_buffer
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_cache_disk
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_cache_socache
        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_data
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dav_fs
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dav_lock
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_dir
        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_filter
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_headers
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_heartbeat
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_heartmonitor
        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_lbmethod_bybusyness
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_lbmethod_byrequests
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_lbmethod_bytraffic
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_lbmethod_heartbeat
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_log_config
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_log_debug
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_log_forensic
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_logio
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_macro
        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_proxy_ajp
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_connect
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_express
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_fcgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_ftp
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_hcheck
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_http
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_scgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_uwsgi
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy_wstunnel
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_ratelimit
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_reflector
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_remoteip
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_reqtimeout
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_request
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_rewrite
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_sed
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session_cookie
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_setenvif
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_slotmem_plain
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_slotmem_shm
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_dbm
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_memcache
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_shmcb
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_socache_redis
        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_substitute
        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 ab
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name htcacheclean
        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 httxt2dbm
        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
    }}}
    
    ###############################################################################
    
    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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_odbc"=".\srclib\apr-util\dbd\apr_dbd_odbc.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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_mysql"=".\srclib\apr-util\dbd\apr_dbd_mysql.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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_oracle"=".\srclib\apr-util\dbd\apr_dbd_oracle.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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_pgsql"=".\srclib\apr-util\dbd\apr_dbd_pgsql.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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_sqlite2"=".\srclib\apr-util\dbd\apr_dbd_sqlite2.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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbd_sqlite3"=".\srclib\apr-util\dbd\apr_dbd_sqlite3.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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbm_db"=".\srclib\apr-util\dbm\apr_dbm_db.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
    }}}
    
    ###############################################################################
    
    Project: "apr_dbm_gdbm"=".\srclib\apr-util\dbm\apr_dbm_gdbm.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
    }}}
    
    ###############################################################################
    
    Project: "apr_ldap"=".\srclib\apr-util\ldap\apr_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
    }}}
    
    ###############################################################################
    
    Project: "fcgistarter"=.\support\fcgistarter.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: "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: "htcacheclean"=.\support\htcacheclean.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: "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: "httxt2dbm"=.\support\httxt2dbm.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
        Begin Project Dependency
        Project_Dep_Name libapriconv_ces_modules
        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
    }}}
    
    ###############################################################################
    
    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
    }}}
    
    ###############################################################################
    
    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_allowmethods"=.\modules\aaa\mod_allowmethods.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_access_compat"=.\modules\aaa\mod_access_compat.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_auth_form"=.\modules\aaa\mod_auth_form.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_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_core"=.\modules\aaa\mod_authn_core.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_dbd"=.\modules\aaa\mod_authn_dbd.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
        Begin Project Dependency
        Project_Dep_Name mod_dbd
        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_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_authn_socache"=.\modules\aaa\mod_authn_socache.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_fcgi"=.\modules\aaa\mod_authnz_fcgi.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_authz_core"=.\modules\aaa\mod_authz_core.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_dbd"=.\modules\aaa\mod_authz_dbd.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
        Begin Project Dependency
        Project_Dep_Name mod_dbd
        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_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_owner"=.\modules\aaa\mod_authz_owner.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_brotli"=.\modules\filters\mod_brotli.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\debugging\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_buffer"=.\modules\filters\mod_buffer.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_case_filter"=.\modules\examples\mod_case_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_case_filter_in"=.\modules\examples\mod_case_filter_in.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\filters\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_data"=.\modules\filters\mod_data.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_dav_lock"=.\modules\dav\lock\mod_dav_lock.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_dbd"=.\modules\database\mod_dbd.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_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_cache_disk"=.\modules\cache\mod_cache_disk.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_cache_socache"=.\modules\cache\mod_cache_socache.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\debugging\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_example_hooks"=.\modules\examples\mod_example_hooks.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_example_ipc"=.\modules\examples\mod_example_ipc.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_filter"=.\modules\filters\mod_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_http2"=.\modules\http2\mod_http2.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_heartbeat"=.\modules\cluster\mod_heartbeat.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_watchdog
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_heartmonitor"=.\modules\cluster\mod_heartmonitor.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_watchdog
        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_lbmethod_bybusyness"=.\modules\proxy\balancers\mod_lbmethod_bybusyness.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
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lbmethod_byrequests"=.\modules\proxy\balancers\mod_lbmethod_byrequests.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
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lbmethod_bytraffic"=.\modules\proxy\balancers\mod_lbmethod_bytraffic.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
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_lbmethod_heartbeat"=.\modules\proxy\balancers\mod_lbmethod_heartbeat.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
        Begin Project Dependency
        Project_Dep_Name mod_proxy_balancer
        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_debug"=.\modules\loggers\mod_log_debug.dsp - Package Owner=<4>
    
    Package=<5>
    {{{
    }}}
    
    Package=<4>
    {{{
        Begin Project Dependency
        Project_Dep_Name libapr
        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_lua"=.\modules\lua\mod_lua.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_macro"=.\modules\core\mod_macro.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_md"=.\modules\md\mod_md.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"=.\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_express"=.\modules\proxy\mod_proxy_express.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_fcgi"=.\modules\proxy\mod_proxy_fcgi.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_hcheck"=.\modules\proxy\mod_proxy_hcheck.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_html"=.\modules\filters\mod_proxy_html.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_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_proxy_http2"=.\modules\http2\mod_proxy_http2.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_http2
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_proxy
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_proxy_scgi"=.\modules\proxy\mod_proxy_scgi.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_uwsgi"=.\modules\proxy\mod_proxy_uwsgi.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_wstunnel"=.\modules\proxy\mod_proxy_wstunnel.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_ratelimit"=.\modules\filters\mod_ratelimit.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_reflector"=.\modules\filters\mod_reflector.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_remoteip"=.\modules\metadata\mod_remoteip.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_reqtimeout"=.\modules\filters\mod_reqtimeout.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_request"=.\modules\filters\mod_request.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_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_sed"=.\modules\filters\mod_sed.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_session"=.\modules\session\mod_session.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_session_crypto"=.\modules\session\mod_session_crypto.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_session
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_session_cookie"=.\modules\session\mod_session_cookie.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_session
        End Project Dependency
    }}}
    
    ###############################################################################
    
    Project: "mod_session_dbd"=.\modules\session\mod_session_dbd.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_dbd
        End Project Dependency
        Begin Project Dependency
        Project_Dep_Name mod_session
        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_slotmem_plain"=.\modules\slotmem\mod_slotmem_plain.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_slotmem_shm"=.\modules\slotmem\mod_slotmem_shm.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_socache_dbm"=.\modules\cache\mod_socache_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
    }}}
    
    ###############################################################################
    
    Project: "mod_socache_dc"=.\modules\cache\mod_socache_dc.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_socache_memcache"=.\modules\cache\mod_socache_memcache.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_socache_shmcb"=.\modules\cache\mod_socache_shmcb.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_socache_redis"=.\modules\cache\mod_socache_redis.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_substitute"=.\modules\filters\mod_substitute.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: "mod_watchdog"=.\modules\core\mod_watchdog.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_xml2enc"=.\modules\filters\mod_xml2enc.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: "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
    }}}
    
    ###############################################################################
    
    Global:
    
    Package=<5>
    {{{
    }}}
    
    Package=<3>
    {{{
    }}}
    
    ###############################################################################
    
    �httpd-2.4.64/INSTALL��������������������������������������������������������������������������������0000664�0001751�0001751�00000007306�12716655767�013707� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
      APACHE INSTALLATION OVERVIEW
    
      Quick Start - Unix
      ------------------
    
      For complete installation documentation, see [ht]docs/manual/install.html or
      http://httpd.apache.org/docs/2.4/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).
    
                * Consider if you want to use a previously installed APR and
                  APR-Util (such as those provided with many OSes) or if you
                  need to use the APR and APR-Util from the apr.apache.org
                  project. If the latter, download the latest versions and
                  unpack them to ./srclib/apr and ./srclib/apr-util (no
                  version numbers in the directory names) and use
                  ./configure's --with-included-apr option. This is required
                  if you don't have the compiler which the system APR was
                  built with.  It can also be advantageous if you are a
                  developer who will be linking your code with Apache or using
                  a debugger to step through server code, as it removes the
                  possibility of version or compile-option mismatches with APR
                  and APR-Util code. As a convenience, prepackaged source-code
                  bundles of APR and APR-Util are occasionally also provided
                  as a httpd-2.X.X-deps.tar.gz download.
    
                * If you are a developer building Apache directly from
                  Subversion, you will need to run ./buildconf before running
                  configure. This script bootstraps the build environment and
                  requires Python as well as GNU autoconf and libtool. If you
                  build Apache from a release tarball, you don't have to run
                  buildconf.
    
                * If you want to build a threaded MPM (for instance worker)
                  on  FreeBSD, be aware that threads do not work well with
                  Apache on FreeBSD versions before 5.4-RELEASE. If you wish
                  to try a threaded Apache on an earlier version of FreeBSD,
                  use the --enable-threads parameter to ./configure in
                  addition to the --with-mpm parameter.
    
                * If you are building directly from Subversion on Mac OS X
                  (Darwin), make sure to use GNU Libtool 1.4.2 or newer. All
                  recent versions of the developer tools on this platform
                  include a sufficiently recent version of GNU Libtool (named
                  glibtool, but buildconf knows where to find it).
    
      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.4
      is to run ./configure --help.
    
    
      Quick Start - Windows
      ---------------------
    
      For complete documentation, see manual/platform/windows.html.en or
      <http://httpd.apache.org/docs/2.4/platform/windows.html>
    
    
      Postscript
      ----------
    
      To obtain help with installation problems, please see the resources at
      <http://httpd.apache.org/support.html>
    
      Thanks for using the Apache HTTP Server, version 2.4.
    
                                         The Apache Software Foundation
                                         http://www.apache.org/
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/httpd.dep������������������������������������������������������������������������������0000664�0001751�0001751�00000004252�12674411515�014450� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by httpd.mak
    
    .\build\win32\httpd.rc : \
    	".\include\ap_release.h"\
    	
    
    .\server\main.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\http_request.h"\
    	".\include\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_md5.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr-util\include\apu_version.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_getopt.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_version.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/libhttpd.dep���������������������������������������������������������������������������0000664�0001751�0001751�00000232336�12674411515�015145� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated Dependency File, included by libhttpd.mak
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    .\modules\http\byterange_filter.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\include\util_time.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_date.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_signal.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\http\chunk_filter.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_connection.h"\
    	".\include\http_core.h"\
    	".\include\http_protocol.h"\
    	".\include\http_request.h"\
    	".\include\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\config.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\mpm_common.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\include\util_varbuf.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_fnmatch.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\connection.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_connection.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_protocol.h"\
    	".\include\http_request.h"\
    	".\include\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\core.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_provider.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\ap_slotmem.h"\
    	".\include\apache_noprobes.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\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\mod_proxy.h"\
    	".\include\mod_so.h"\
    	".\include\mpm_common.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\include\util_md5.h"\
    	".\include\util_mutex.h"\
    	".\include\util_time.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_date.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_md5.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_reslist.h"\
    	".\srclib\apr-util\include\apr_strmatch.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_uuid.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_fnmatch.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_random.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\core_filters.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\mod_so.h"\
    	".\include\mpm_common.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\include\util_md5.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_md5.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_fnmatch.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\http\http_core.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_connection.h"\
    	".\include\http_core.h"\
    	".\include\http_protocol.h"\
    	".\include\http_request.h"\
    	".\include\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\http\http_etag.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_connection.h"\
    	".\include\http_core.h"\
    	".\include\http_protocol.h"\
    	".\include\http_request.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\http\http_filters.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\include\util_time.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_date.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_signal.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\http\http_protocol.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\include\util_time.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_date.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_signal.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\http\http_request.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_fnmatch.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\log.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\include\util_time.h"\
    	".\srclib\apr-util\include\apr_base64.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_signal.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\protocol.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_strmatch.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_signal.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\request.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_provider.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\httpd.h"\
    	".\include\mod_auth.h"\
    	".\include\mod_core.h"\
    	".\include\mod_request.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_filter.h"\
    	".\include\util_script.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_fnmatch.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\vhost.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_protocol.h"\
    	".\include\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\core\mod_so.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\modules\core\mod_so.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\modules\arch\win32\mod_win32.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_regkey.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_protocol.h"\
    	".\include\http_request.h"\
    	".\include\httpd.h"\
    	".\include\mod_cgi.h"\
    	".\include\mod_core.h"\
    	".\include\mod_include.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\include\util_script.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\os\win32\modules.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\eoc_bucket.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_connection.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\eor_bucket.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_protocol.h"\
    	".\include\http_request.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\error_bucket.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_protocol.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\http_protocol.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\include\util_varbuf.h"\
    	".\server\test_char.h"\
    	".\srclib\apr-util\include\apr_base64.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_cfgtree.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\apache_noprobes.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_cookies.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_cookies.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_expr_eval.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_provider.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_protocol.h"\
    	".\include\http_request.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\include\util_md5.h"\
    	".\server\util_expr_private.h"\
    	".\srclib\apr-util\include\apr_base64.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_md5.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_sha1.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_fnmatch.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_expr_parse.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\server\util_expr_private.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_expr_scan.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\server\util_expr_parse.h"\
    	".\server\util_expr_private.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_fcgi.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_fcgi.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_filter.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_md5.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_md5.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_md5.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_mutex.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\include\util_mutex.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_pcre.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_regex.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_script.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.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\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_ebcdic.h"\
    	".\include\util_filter.h"\
    	".\include\util_script.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_date.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\util_time.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_time.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\os\win32\util_win32.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_log.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_getopt.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	".\srclib\apr\include\arch\apr_private_common.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_file_io.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_misc.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_utf8.h"\
    	".\srclib\apr\include\arch\win32\apr_private.h"\
    	
    
    .\server\util_xml.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_protocol.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_charset.h"\
    	".\include\util_filter.h"\
    	".\include\util_xml.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apr_xlate.h"\
    	".\srclib\apr-util\include\apr_xml.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\os\win32\ap_regkey.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_regkey.h"\
    	".\include\apache_noprobes.h"\
    	".\include\os.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_getopt.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	".\srclib\apr\include\arch\apr_private_common.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_file_io.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_misc.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_utf8.h"\
    	".\srclib\apr\include\arch\win32\apr_private.h"\
    	
    
    .\server\mpm\winnt\child.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_connection.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\http_vhost.h"\
    	".\include\httpd.h"\
    	".\include\mpm_common.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\server\mpm\winnt\mpm_default.h"\
    	".\server\mpm\winnt\mpm_winnt.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_atomic.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_getopt.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\listen.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\httpd.h"\
    	".\include\mpm_common.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\mpm_common.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\httpd.h"\
    	".\include\mod_core.h"\
    	".\include\mpm_common.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\include\util_mutex.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_getopt.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_signal.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\mpm\winnt\mpm_winnt.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_connection.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\httpd.h"\
    	".\include\mpm_common.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\server\mpm\winnt\mpm_default.h"\
    	".\server\mpm\winnt\mpm_winnt.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_atomic.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_getopt.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\mpm\winnt\nt_eventlog.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_regkey.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_log.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\server\mpm\winnt\mpm_winnt.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\provider.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_provider.h"\
    	".\include\apache_noprobes.h"\
    	".\include\os.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\scoreboard.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_expr.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_mpm.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_core.h"\
    	".\include\http_log.h"\
    	".\include\http_main.h"\
    	".\include\http_protocol.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\scoreboard.h"\
    	".\include\util_cfgtree.h"\
    	".\include\util_filter.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_hash.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	
    
    .\server\mpm\winnt\service.c : \
    	".\include\ap_config.h"\
    	".\include\ap_config_layout.h"\
    	".\include\ap_hooks.h"\
    	".\include\ap_listen.h"\
    	".\include\ap_mmn.h"\
    	".\include\ap_regex.h"\
    	".\include\ap_regkey.h"\
    	".\include\ap_release.h"\
    	".\include\apache_noprobes.h"\
    	".\include\http_config.h"\
    	".\include\http_log.h"\
    	".\include\httpd.h"\
    	".\include\os.h"\
    	".\include\util_cfgtree.h"\
    	".\server\mpm\winnt\mpm_winnt.h"\
    	".\srclib\apr-util\include\apr_buckets.h"\
    	".\srclib\apr-util\include\apr_hooks.h"\
    	".\srclib\apr-util\include\apr_optional_hooks.h"\
    	".\srclib\apr-util\include\apr_uri.h"\
    	".\srclib\apr-util\include\apu.h"\
    	".\srclib\apr\include\apr.h"\
    	".\srclib\apr\include\apr_allocator.h"\
    	".\srclib\apr\include\apr_dso.h"\
    	".\srclib\apr\include\apr_errno.h"\
    	".\srclib\apr\include\apr_file_info.h"\
    	".\srclib\apr\include\apr_file_io.h"\
    	".\srclib\apr\include\apr_general.h"\
    	".\srclib\apr\include\apr_getopt.h"\
    	".\srclib\apr\include\apr_global_mutex.h"\
    	".\srclib\apr\include\apr_inherit.h"\
    	".\srclib\apr\include\apr_lib.h"\
    	".\srclib\apr\include\apr_mmap.h"\
    	".\srclib\apr\include\apr_network_io.h"\
    	".\srclib\apr\include\apr_poll.h"\
    	".\srclib\apr\include\apr_pools.h"\
    	".\srclib\apr\include\apr_portable.h"\
    	".\srclib\apr\include\apr_proc_mutex.h"\
    	".\srclib\apr\include\apr_ring.h"\
    	".\srclib\apr\include\apr_shm.h"\
    	".\srclib\apr\include\apr_strings.h"\
    	".\srclib\apr\include\apr_tables.h"\
    	".\srclib\apr\include\apr_thread_mutex.h"\
    	".\srclib\apr\include\apr_thread_proc.h"\
    	".\srclib\apr\include\apr_time.h"\
    	".\srclib\apr\include\apr_user.h"\
    	".\srclib\apr\include\apr_want.h"\
    	".\srclib\apr\include\arch\apr_private_common.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_misc.h"\
    	".\srclib\apr\include\arch\win32\apr_arch_utf8.h"\
    	".\srclib\apr\include\arch\win32\apr_private.h"\
    	
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    !IF  "$(CFG)" == "libhttpd - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Debug"
    
    !ELSEIF  "$(CFG)" == "libhttpd - Win32 Lexical"
    
    !ENDIF 
    
    .\build\win32\httpd.rc : \
    	".\include\ap_release.h"\
    	
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/httpd.mak������������������������������������������������������������������������������0000664�0001751�0001751�00000021442�12674411515�014450� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Generated NMAKE File, Based on httpd.dsp
    !IF "$(CFG)" == ""
    CFG=httpd - Win32 Release
    !MESSAGE No configuration specified. Defaulting to httpd - Win32 Release.
    !ENDIF 
    
    !IF "$(CFG)" != "httpd - Win32 Release" && "$(CFG)" != "httpd - Win32 Debug"
    !MESSAGE Invalid configuration "$(CFG)" specified.
    !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 
    !ERROR An invalid configuration is specified.
    !ENDIF 
    
    !IF "$(OS)" == "Windows_NT"
    NULL=
    !ELSE 
    NULL=nul
    !ENDIF 
    
    !IF  "$(CFG)" == "httpd - Win32 Release"
    
    OUTDIR=.\Release
    INTDIR=.\Release
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\httpd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\httpd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.idb"
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\main.obj"
    	-@erase "$(OUTDIR)\httpd.exe"
    	-@erase "$(OUTDIR)\httpd.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\httpd" /FD /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "./include" /i "./srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="httpd.exe" /d LONG_NAME="Apache HTTP Server" /d ICON_FILE="apache.ico" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\httpd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /stack:0x40000 /subsystem:console /incremental:no /pdb:"$(OUTDIR)\httpd.pdb" /debug /out:"$(OUTDIR)\httpd.exe" /opt:ref 
    LINK32_OBJS= \
    	"$(INTDIR)\main.obj" \
    	"$(INTDIR)\httpd.res" \
    	".\srclib\apr\Release\libapr-1.lib" \
    	".\srclib\apr-util\Release\libaprutil-1.lib" \
    	"$(OUTDIR)\libhttpd.lib"
    
    "$(OUTDIR)\httpd.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Release\httpd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Release
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\httpd.exe"
       if exist .\Release\httpd.exe.manifest mt.exe -manifest .\Release\httpd.exe.manifest -outputresource:.\Release\httpd.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ELSEIF  "$(CFG)" == "httpd - Win32 Debug"
    
    OUTDIR=.\Debug
    INTDIR=.\Debug
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    !IF "$(RECURSE)" == "0" 
    
    ALL : "$(OUTDIR)\httpd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ELSE 
    
    ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\httpd.exe" "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    !IF "$(RECURSE)" == "1" 
    CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" 
    !ELSE 
    CLEAN :
    !ENDIF 
    	-@erase "$(INTDIR)\httpd.idb"
    	-@erase "$(INTDIR)\httpd.res"
    	-@erase "$(INTDIR)\main.obj"
    	-@erase "$(OUTDIR)\httpd.exe"
    	-@erase "$(OUTDIR)\httpd.pdb"
    
    "$(OUTDIR)" :
        if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
    
    CPP=cl.exe
    CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\httpd" /FD /EHsc /c 
    
    .c{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.obj::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .c{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cpp{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    .cxx{$(INTDIR)}.sbr::
       $(CPP) @<<
       $(CPP_PROJ) $< 
    <<
    
    RSC=rc.exe
    RSC_PROJ=/l 0x409 /fo"$(INTDIR)\httpd.res" /i "./include" /i "./srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="httpd.exe" /d LONG_NAME="Apache HTTP Server" /d ICON_FILE="apache.ico" 
    BSC32=bscmake.exe
    BSC32_FLAGS=/nologo /o"$(OUTDIR)\httpd.bsc" 
    BSC32_SBRS= \
    	
    LINK32=link.exe
    LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /stack:0x40000 /subsystem:console /incremental:no /pdb:"$(OUTDIR)\httpd.pdb" /debug /out:"$(OUTDIR)\httpd.exe" 
    LINK32_OBJS= \
    	"$(INTDIR)\main.obj" \
    	"$(INTDIR)\httpd.res" \
    	".\srclib\apr\Debug\libapr-1.lib" \
    	".\srclib\apr-util\Debug\libaprutil-1.lib" \
    	"$(OUTDIR)\libhttpd.lib"
    
    "$(OUTDIR)\httpd.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
        $(LINK32) @<<
      $(LINK32_FLAGS) $(LINK32_OBJS)
    <<
    
    TargetPath=.\Debug\httpd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
    
    # Begin Custom Macros
    OutDir=.\Debug
    # End Custom Macros
    
    "$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\httpd.exe"
       if exist .\Debug\httpd.exe.manifest mt.exe -manifest .\Debug\httpd.exe.manifest -outputresource:.\Debug\httpd.exe;1
    	echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
    
    !ENDIF 
    
    
    !IF "$(NO_EXTERNAL_DEPS)" != "1"
    !IF EXISTS("httpd.dep")
    !INCLUDE "httpd.dep"
    !ELSE 
    !MESSAGE Warning: cannot find "httpd.dep"
    !ENDIF 
    !ENDIF 
    
    
    !IF "$(CFG)" == "httpd - Win32 Release" || "$(CFG)" == "httpd - Win32 Debug"
    
    !IF  "$(CFG)" == "httpd - Win32 Release"
    
    "libapr - Win32 Release" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" 
       cd "..\.."
    
    "libapr - Win32 ReleaseCLEAN" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "httpd - Win32 Debug"
    
    "libapr - Win32 Debug" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" 
       cd "..\.."
    
    "libapr - Win32 DebugCLEAN" : 
       cd ".\srclib\apr"
       $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ENDIF 
    
    !IF  "$(CFG)" == "httpd - Win32 Release"
    
    "libaprutil - Win32 Release" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" 
       cd "..\.."
    
    "libaprutil - Win32 ReleaseCLEAN" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ELSEIF  "$(CFG)" == "httpd - Win32 Debug"
    
    "libaprutil - Win32 Debug" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" 
       cd "..\.."
    
    "libaprutil - Win32 DebugCLEAN" : 
       cd ".\srclib\apr-util"
       $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN 
       cd "..\.."
    
    !ENDIF 
    
    !IF  "$(CFG)" == "httpd - Win32 Release"
    
    "libhttpd - Win32 Release" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" 
       cd "."
    
    "libhttpd - Win32 ReleaseCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN 
       cd "."
    
    !ELSEIF  "$(CFG)" == "httpd - Win32 Debug"
    
    "libhttpd - Win32 Debug" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" 
       cd "."
    
    "libhttpd - Win32 DebugCLEAN" : 
       cd "."
       $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN 
       cd "."
    
    !ENDIF 
    
    SOURCE=.\build\win32\httpd.rc
    
    !IF  "$(CFG)" == "httpd - Win32 Release"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "./include" /i "./srclib/apr/include" /i "build\win32" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="httpd.exe" /d LONG_NAME="Apache HTTP Server" /d ICON_FILE="apache.ico" $(SOURCE)
    
    
    !ELSEIF  "$(CFG)" == "httpd - Win32 Debug"
    
    
    "$(INTDIR)\httpd.res" : $(SOURCE) "$(INTDIR)"
    	$(RSC) /l 0x409 /fo"$(INTDIR)\httpd.res" /i "./include" /i "./srclib/apr/include" /i "build\win32" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="httpd.exe" /d LONG_NAME="Apache HTTP Server" /d ICON_FILE="apache.ico" $(SOURCE)
    
    
    !ENDIF 
    
    SOURCE=.\server\main.c
    
    "$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)"
    	$(CPP) $(CPP_PROJ) $(SOURCE)
    
    
    
    !ENDIF 
    
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/NWGNUmakefile��������������������������������������������������������������������������0000664�0001751�0001751�00000033074�12673543425�015163� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#
    # Define our required macro's if not already done.
    #
    
    ifndef AP_WORK
    export AP_WORK = $(CURDIR)
    endif
    
    ifndef APR_WORK
    ifeq "$(wildcard $(AP_WORK)/srclib/apr)" "$(AP_WORK)/srclib/apr"
    export APR_WORK = $(AP_WORK)/srclib/apr
    endif
    endif
    ifneq "$(wildcard $(APR_WORK)/include/apr_version.h)" "$(APR_WORK)/include/apr_version.h"
    $(error APR_WORK does not point to a valid APR source tree) 
    endif
    
    ifndef APU_WORK
    ifeq "$(wildcard $(AP_WORK)/srclib/apr-util)" "$(AP_WORK)/srclib/apr-util"
    export APU_WORK = $(AP_WORK)/srclib/apr-util
    endif
    endif
    ifndef APU_WORK
    ifeq "$(wildcard $(APR_WORK)/include/apu_version.h)" "$(APR_WORK)/include/apu_version.h"
    export APU_WORK = $(APR_WORK)
    endif
    endif
    ifneq "$(wildcard $(APU_WORK)/include/apu_version.h)" "$(APU_WORK)/include/apu_version.h"
    $(error APU_WORK does not point to a valid APU source tree) 
    endif
    
    #
    # 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 \
    			$(SRC)/include \
    			$(STDMOD)/aaa \
    			$(STDMOD)/core \
    			$(STDMOD)/filters \
    			$(STDMOD)/generators \
    			$(STDMOD)/http \
    			$(STDMOD)/loggers \
    			$(STDMOD)/mappers \
    			$(STDMOD)/proxy \
    			$(STDMOD)/ssl \
    			$(SERVER) \
    			$(SERVER)/mpm/netware \
    			$(PCRE) \
    			$(NWOS) \
    			$(EOLIST)
    
    #
    # These flags will come after CFLAGS
    #
    XCFLAGS		+= \
    			-DHAVE_CONFIG_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	= Apache2
    
    #
    # This is used by the link '-desc ' directive.
    # If left blank, NLM_NAME will be used.
    #
    NLM_DESCRIPTION	= Apache Web Server $(VERSION_STR) $(VERSION_SKT)
    
    #
    # This is used by the '-threadname' directive.  If left blank,
    # NLM_NAME Thread will be used.
    #
    NLM_THREAD_NAME	= $(NLM_NAME)
    
    #
    # 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	=
    
    #
    # 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	= _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)/$(NLM_NAME).nlm \
    	$(EOLIST)
    
    #
    # If there is an LIB target, put it here
    #
    TARGET_lib = \
    	$(PCRELIB) \
    	$(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)/eor_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_authn_core.o \
    	$(OBJDIR)/mod_authz_core.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)/mod_watchdog.o \
    	$(OBJDIR)/modules.o \
    	$(OBJDIR)/mpm_common.o \
    	$(OBJDIR)/mpm_netware.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_cookies.o \
    	$(OBJDIR)/util_debug.o \
    	$(OBJDIR)/util_expr_eval.o \
    	$(OBJDIR)/util_expr_parse.o \
    	$(OBJDIR)/util_expr_scan.o \
    	$(OBJDIR)/util_fcgi.o \
    	$(OBJDIR)/util_filter.o \
    	$(OBJDIR)/util_md5.o \
    	$(OBJDIR)/util_mutex.o \
    	$(OBJDIR)/util_nw.o \
    	$(OBJDIR)/util_pcre.o \
    	$(OBJDIR)/util_regex.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 = \
    	$(PCRELIB) \
    	$(PRELUDE) \
    	$(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 = \
    	@aprlib.imp \
    	@libc.imp \
    	@netware.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 = \
    	@httpd.imp \
    	$(EOLIST)
    
    #
    # These are the OBJ files needed to create the LIB target above.
    # Paths must all use the '/' character
    #
    ifeq "$(wildcard $(PCRE)/pcre.c)" "$(PCRE)/pcre.c"
    
    FILES_lib_objs = \
    	$(OBJDIR)/pcre.o \
    	$(EOLIST)
    
    else
    
    FILES_lib_objs = \
    	$(OBJDIR)/chartables.o \
    	$(OBJDIR)/pcre_compile.o \
    	$(OBJDIR)/pcre_exec.o \
    	$(OBJDIR)/pcre_fullinfo.o \
    	$(OBJDIR)/pcre_globals.o \
    	$(OBJDIR)/pcre_newline.o \
    	$(OBJDIR)/pcre_tables.o \
    	$(OBJDIR)/pcre_version.o \
    	$(EOLIST)
    ifeq "$(wildcard $(PCRE)/pcre_try_flipped.c)" "$(PCRE)/pcre_try_flipped.c"
    FILES_lib_objs += \
    	$(OBJDIR)/pcre_try_flipped.o \
    	$(EOLIST)
    endif 
    
    endif
    
    #
    # 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)
    #
    MKCNF	= $(AWK) -v BDIR=$(BASEDIR) -v PORT=$(PORT) -v SSLPORT=$(SSLPORT) -v MODSSL=$(WITH_SSL) -v BSDSKT=$(USE_STDSOCKETS) -f build/mkconfNW.awk $1 > $2
    
    install :: nlms instscripts FORCE
    	$(call COPY,$(OBJDIR)/$(NLM_NAME).nlm,                         $(INSTALLBASE)/)
    	$(call COPY,ABOUT_APACHE,                                      $(INSTALLBASE)/)
    	$(call COPY,CHANGES,                                           $(INSTALLBASE)/)
    	$(call COPY,LICENSE,                                           $(INSTALLBASE)/)
    	$(call COPY,README,                                            $(INSTALLBASE)/)
    	$(call COPY,VERSIONING,                                        $(INSTALLBASE)/)
    	$(call COPY,STATUS,                                            $(INSTALLBASE)/)
    	$(call COPY,support/dbmmanage.in,                              $(INSTALLBASE)/bin/dbmmanage.pl)
    	$(call COPY,support/logresolve.pl.in,                          $(INSTALLBASE)/bin/logresolve.pl)
    	$(call COPY,support/split-logfile.in,                          $(INSTALLBASE)/bin/split-logfile.pl)
    	$(call COPY,support/check_forensic,                            $(INSTALLBASE)/bin/check_forensic.sh)
    	$(call COPY,docs/conf/magic,                                   $(INSTALLBASE)/conf/)
    	$(call COPY,docs/conf/mime.types,                              $(INSTALLBASE)/conf/)
    	$(call COPY,docs/conf/charset.conv,                            $(INSTALLBASE)/conf/)
    	$(call COPY,docs/cgi-examples/printenv,                        $(INSTALLBASE)/cgi-bin/printenv.pl)
    	$(call MKCNF,docs/conf/httpd.conf.in,                          $(INSTALLBASE)/conf/httpd.conf)
    	$(call MKCNF,docs/conf/extra/httpd-autoindex.conf.in,          $(INSTALLBASE)/conf/extra/httpd-autoindex.conf)
    	$(call MKCNF,docs/conf/extra/httpd-dav.conf.in,                $(INSTALLBASE)/conf/extra/httpd-dav.conf)
    	$(call MKCNF,docs/conf/extra/httpd-default.conf.in,            $(INSTALLBASE)/conf/extra/httpd-default.conf)
    	$(call MKCNF,docs/conf/extra/httpd-info.conf.in,               $(INSTALLBASE)/conf/extra/httpd-info.conf)
    	$(call MKCNF,docs/conf/extra/httpd-languages.conf.in,          $(INSTALLBASE)/conf/extra/httpd-languages.conf)
    	$(call MKCNF,docs/conf/extra/httpd-manual.conf.in,             $(INSTALLBASE)/conf/extra/httpd-manual.conf)
    	$(call MKCNF,docs/conf/extra/httpd-mpm.conf.in,                $(INSTALLBASE)/conf/extra/httpd-mpm.conf)
    	$(call MKCNF,docs/conf/extra/httpd-multilang-errordoc.conf.in, $(INSTALLBASE)/conf/extra/httpd-multilang-errordoc.conf)
    	$(call MKCNF,docs/conf/extra/httpd-userdir.conf.in,            $(INSTALLBASE)/conf/extra/httpd-userdir.conf)
    	$(call MKCNF,docs/conf/extra/httpd-vhosts.conf.in,             $(INSTALLBASE)/conf/extra/httpd-vhosts.conf)
    	$(call MKCNF,docs/conf/extra/httpd-ssl.conf.in,                $(INSTALLBASE)/conf/extra/httpd-ssl.conf)
    	$(call MKCNF,docs/conf/extra/proxy-html.conf.in,               $(INSTALLBASE)/conf/extra/proxy-html.conf)
    	$(call COPYR,docs/docroot,                                     $(INSTALLBASE)/htdocs)
    	$(call COPYR,docs/error,                                       $(INSTALLBASE)/error)
    	$(call COPYR,docs/icons,                                       $(INSTALLBASE)/icons)
    	$(call COPYR,docs/man,                                         $(INSTALLBASE)/man)
    	$(call COPYR,docs/manual,                                      $(INSTALLBASE)/manual)
    
    installdev :: FORCE
    	$(call COPY,$(SRC)/include/*.h,                                $(INSTALLBASE)/include/)
    	$(call COPY,$(NWOS)/*.h,                                       $(INSTALLBASE)/include/)
    	$(call COPY,$(APR)/include/*.h,                                $(INSTALLBASE)/include/)
    	$(call COPY,$(APRUTIL)/include/*.h,                            $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/core/mod_so.h,                           $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/core/mod_watchdog.h,                     $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/cache/mod_cache.h,                       $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/cache/cache_common.h,                    $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/database/mod_dbd.h,                      $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/dav/main/mod_dav.h,                      $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/filters/mod_include.h,                   $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/generators/mod_cgi.h,                    $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/generators/mod_status.h,                 $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/loggers/mod_log_config.h,                $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/mappers/mod_rewrite.h,                   $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/proxy/mod_proxy.h,                       $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/session/mod_session.h,                   $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/ssl/mod_ssl.h,                           $(INSTALLBASE)/include/)
    	$(call COPY,$(STDMOD)/ssl/mod_ssl_openssl.h,                   $(INSTALLBASE)/include/)
    	$(call COPY,$(APR)/*.imp,                                      $(INSTALLBASE)/lib/)
    	$(call COPY,$(NWOS)/*.imp,                                     $(INSTALLBASE)/lib/)
    	$(call COPY,$(NWOS)/*.xdc,                                     $(INSTALLBASE)/lib/)
    	$(call COPY,$(APBUILD)/NWGNU*.inc,                             $(INSTALLBASE)/build/)
    
    prebuild :: FORCE
    	$(MAKE) -C $(SERVER) -f NWGNUmakefile
    	$(MAKE) -C $(PCRE) -f NWGNUmakefile
    	$(call MKDIR,$(PREBUILD_INST))
    	$(call COPY,$(SERVER)/$(OBJDIR)/*.nlm,                         $(PREBUILD_INST)/)
    	$(call COPY,$(PCRE)/$(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 modules/core:os/netware:server/mpm/netware:$(PCRE)
    
    $(OBJDIR)/chartables.o: os/netware/chartables.c
    
    #
    # Include the 'tail' makefile that has targets that depend on variables defined
    # in this makefile
    #
    
    include $(APBUILD)/NWGNUtail.inc
    
    include $(APBUILD)/NWGNUscripts.inc
    
    
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/LAYOUT���������������������������������������������������������������������������������0000664�0001751�0001751�00000010001�12241452212�013545� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������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_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_scache.c ............ session cache abstraction layer
        ssl_util.c .............. utility functions
        ssl_util_ssl.c .......... the OpenSSL companion source
        ssl_util_ssl.h .......... the OpenSSL companion header
    
      test/ ................... not distributed with released source tarballs
    
    os/ ..................... 
    
      bs2000/ ................. 
    
      netware/ ................ 
    
      os2/ .................... 
    
      unix/ ................... 
    
      win32/ .................. 
    
    server/ ................. 
    
      mpm/ .................... 
    
        event/ .................. 
    
        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
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/InstallBin.dsp�������������������������������������������������������������������������0000664�0001751�0001751�00000005535�11660326534�015407� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 "\Apache24\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="\Apache24" SHORT=R LONG=Release _install"
    # PROP Rebuild_Opt ""
    # PROP Target_File "\Apache24\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 "\Apache24\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="\Apache24" SHORT=D LONG=Debug _install"
    # PROP Rebuild_Opt ""
    # PROP Target_File "\Apache24\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
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/httpd.dsp������������������������������������������������������������������������������0000664�0001751�0001751�00000010034�11023777214�014457� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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 /i "./include" /i "./srclib/apr/include" /d "NDEBUG" /d "APP_FILE" /d BIN_NAME="httpd.exe" /d LONG_NAME="Apache HTTP Server" /d ICON_FILE="apache.ico"
    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
    # ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /stack:0x40000 /subsystem:console /debug /opt:ref
    # Begin Special Build Tool
    TargetPath=.\Release\httpd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /c
    # ADD CPP /nologo /MDd /W3 /EHsc /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 /i "./include" /i "./srclib/apr/include" /d "_DEBUG" /d "APP_FILE" /d BIN_NAME="httpd.exe" /d LONG_NAME="Apache HTTP Server" /d ICON_FILE="apache.ico"
    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
    # ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /stack:0x40000 /subsystem:console /incremental:no /debug
    # Begin Special Build Tool
    TargetPath=.\Debug\httpd.exe
    SOURCE="$(InputPath)"
    PostBuild_Desc=Embed .manifest
    PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);1
    # End Special Build Tool
    
    !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
    # End Target
    # End Project
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/ap.d�����������������������������������������������������������������������������������0000664�0001751�0001751�00000004720�11123517417�013374� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#pragma D depends_on provider io
    typedef struct request_rec {
        uintptr_t pool;
        uintptr_t connection;
        uintptr_t server;
        uintptr_t next;
        uintptr_t prev;
        uintptr_t main;
        char *the_request;
        int assbackwards;
        int proxyreq;
        int header_only;
        char *protocol;
        int proto_num;
        char *hostname;
        int64_t request_time;
        char *status_line;
        int status;
        const char *method;
        int method_number;
        int64_t allowed;
        uintptr_t allowed_xmethods;
        uintptr_t allowed_methods;
        offset_t sent_bodyct;
        offset_t bytes_sent;
        int64_t mtime;
        int chunked;
        char *range;
        offset_t clength;
        offset_t remaining;
        offset_t read_length;
        int read_body;
        int read_chunked;
        unsigned expecting_100;
        uintptr_t headers_in;
        uintptr_t headers_out;
        uintptr_t err_headers_out;
        uintptr_t subprocess_env;
        uintptr_t notes;
        char *content_type;   /* Break these out --- we dispatch on 'em */
        char *handler;        /* What we *really* dispatch on */
        char *content_encoding;
        uintptr_t content_languages;
        char *vlist_validator;
        char *user;
        char *ap_auth_type;
        int no_cache;
        int no_local_copy;
        char *unparsed_uri;
        char *uri;
        char *filename;
        char *canonical_filename;
        char *path_info;
        char *args;
        /* finfo */
        uintptr_t finfo_pool;
        int32_t finfo_valid;
        int32_t finfo_protection;
        int32_t finfo_filetype;
        int finfo_user;
        int finfo_group;
        uint64_t finfo_inode;
        uint64_t finfo_device;
        int32_t finfo_nlink;
        offset_t finfo_size;
        offset_t finfo_csize;
        int64_t finfo_atime;
        int64_t finfo_mtime;
        int64_t finfo_ctime;
        char *finfo_fname;
        char *finfo_name;
        uintptr_t finfo_ffilehand;
        /* parsed_uri */
        char *uri_scheme;
        char *uri_hostinfo;
        char *uri_user;
        char *uri_password;
        char *uri_hostname;
        char *uri_port_str;
        char *uri_path;
        char *uri_query;
        char *uri_fragment;
        uintptr_t uri_hostent;
        uint16_t uri_port;
        unsigned uri_is_initialized:1;
        unsigned uri_dns_looked_up:1;
        unsigned uri_dns_resolved:1;
    
        /* back to request_rec */
        int used_path_info;
        uintptr_t per_dir_config;
        uintptr_t request_config;
        uintptr_t htaccess;
        uintptr_t output_filters;
        uintptr_t input_filters;
        uintptr_t proto_output_filters;
        uintptr_t proto_input_filters;
        int eos_sent;
        uintptr_t kept_body;
        uintptr_t invoke_mtx;
    } request_rec;
    
    ������������������������������������������������httpd-2.4.64/README.platforms�����������������������������������������������������������������������0000664�0001751�0001751�00000010502�12377404546�015522� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
                              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.
    
       You will note that GNU libtool should actually be installed as
       glibtool, to avoid conflict with a Darwin program of the same
       name.
    
       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.
    
       With Leopard (at least up to 10.5.2), when running configure
       you will likely see errors such as:
    
          rm: conftest.dSYM: is a directory
    
       This is a known issue and will be fixed in a later version of the
       autoconf suite. These errors can be safely ignored.
    
       For later versions of OS X, (10.8 and 10.9), be sure to have Xcode
       AND Xcode Command Line Tools installed. httpd will built both with
       gcc and clang.
       
    ==========
      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+.)
    
    ================
      Solaris:
    
        On Solaris, better performance may be achieved by using the Sun Studio
        compiler instead of gcc.  As of version 11, it is now free (registration
        required).  Download the compiler from:
    
        http://developers.sun.com/prodtech/cc/downloads/index.jsp
    
        If you use Sun Studio, the following compiler flags (CFLAGS) are
        recommended:
    
          -XO4 -xchip=generic
    
    ================
      Ubuntu:
    
        You will need to ensure that you have either libtool 1.5.6
        or 2.2.6b, or later. Expat 2.0.1 and PCRE 8.02 are also
        recommended to be installed. If building PCRE from source,
        you'll also need g++.
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/apache_probes.d������������������������������������������������������������������������0000664�0001751�0001751�00000023263�11312717763�015600� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������provider ap {
      /* Explicit, core */
      probe internal__redirect(char *, char *);
      probe process__request__entry(uintptr_t, char *);
      probe process__request__return(uintptr_t, char *, uint32_t);
      probe read__request__entry(uintptr_t, uintptr_t);
      probe read__request__success(uintptr_t, char *, char *, char *, uint32_t);
      probe read__request__failure(uintptr_t);
    
      /* Explicit, modules */
      probe proxy__run(uintptr_t, uintptr_t, uintptr_t, char *, int);
      probe proxy__run__finished(uintptr_t, int, int);
      probe rewrite__log(uintptr_t, int, int, char *, char *);
    
      /* Implicit, APR hooks */
      probe access_checker__entry();
      probe access_checker__dispatch__invoke(char *);
      probe access_checker__dispatch__complete(char *, uint32_t);
      probe access_checker__return(uint32_t);
      probe auth_checker__entry();
      probe auth_checker__dispatch__invoke(char *);
      probe auth_checker__dispatch__complete(char *, uint32_t);
      probe auth_checker__return(uint32_t);
      probe check_config__entry();
      probe check_config__dispatch__invoke(char *);
      probe check_config__dispatch__complete(char *, uint32_t);
      probe check_config__return(uint32_t);
      probe check_user_id__entry();
      probe check_user_id__dispatch__invoke(char *);
      probe check_user_id__dispatch__complete(char *, uint32_t);
      probe check_user_id__return(uint32_t);
      probe child_init__entry();
      probe child_init__dispatch__invoke(char *);
      probe child_init__dispatch__complete(char *, uint32_t);
      probe child_init__return(uint32_t);
      probe create_connection__entry();
      probe create_connection__dispatch__invoke(char *);
      probe create_connection__dispatch__complete(char *, uint32_t);
      probe create_connection__return(uint32_t);
      probe create_request__entry();
      probe create_request__dispatch__invoke(char *);
      probe create_request__dispatch__complete(char *, uint32_t);
      probe create_request__return(uint32_t);
      probe default_port__entry();
      probe default_port__dispatch__invoke(char *);
      probe default_port__dispatch__complete(char *, uint32_t);
      probe default_port__return(uint32_t);
      probe drop_privileges__entry();
      probe drop_privileges__dispatch__invoke(char *);
      probe drop_privileges__dispatch__complete(char *, uint32_t);
      probe drop_privileges__return(uint32_t);
      probe error_log__entry();
      probe error_log__dispatch__invoke(char *);
      probe error_log__dispatch__complete(char *, uint32_t);
      probe error_log__return(uint32_t);
      probe fatal_exception__entry();
      probe fatal_exception__dispatch__invoke(char *);
      probe fatal_exception__dispatch__complete(char *, uint32_t);
      probe fatal_exception__return(uint32_t);
      probe fixups__entry();
      probe fixups__dispatch__invoke(char *);
      probe fixups__dispatch__complete(char *, uint32_t);
      probe fixups__return(uint32_t);
      probe get_mgmt_items__entry();
      probe get_mgmt_items__dispatch__invoke(char *);
      probe get_mgmt_items__dispatch__complete(char *, uint32_t);
      probe get_mgmt_items__return(uint32_t);
      probe get_suexec_identity__entry();
      probe get_suexec_identity__dispatch__invoke(char *);
      probe get_suexec_identity__dispatch__complete(char *, uint32_t);
      probe get_suexec_identity__return(uint32_t);
      probe handler__entry();
      probe handler__dispatch__invoke(char *);
      probe handler__dispatch__complete(char *, uint32_t);
      probe handler__return(uint32_t);
      probe header_parser__entry();
      probe header_parser__dispatch__invoke(char *);
      probe header_parser__dispatch__complete(char *, uint32_t);
      probe header_parser__return(uint32_t);
      probe http_scheme__entry();
      probe http_scheme__dispatch__invoke(char *);
      probe http_scheme__dispatch__complete(char *, uint32_t);
      probe http_scheme__return(uint32_t);
      probe insert_error_filter__entry();
      probe insert_error_filter__dispatch__invoke(char *);
      probe insert_error_filter__dispatch__complete(char *, uint32_t);
      probe insert_error_filter__return(uint32_t);
      probe insert_filter__entry();
      probe insert_filter__dispatch__invoke(char *);
      probe insert_filter__dispatch__complete(char *, uint32_t);
      probe insert_filter__return(uint32_t);
      probe log_transaction__entry();
      probe log_transaction__dispatch__invoke(char *);
      probe log_transaction__dispatch__complete(char *, uint32_t);
      probe log_transaction__return(uint32_t);
      probe map_to_storage__entry();
      probe map_to_storage__dispatch__invoke(char *);
      probe map_to_storage__dispatch__complete(char *, uint32_t);
      probe map_to_storage__return(uint32_t);
      probe monitor__entry();
      probe monitor__dispatch__invoke(char *);
      probe monitor__dispatch__complete(char *, uint32_t);
      probe monitor__return(uint32_t);
      probe mpm__entry();
      probe mpm__dispatch__invoke(char *);
      probe mpm__dispatch__complete(char *, uint32_t);
      probe mpm__return(uint32_t);
      probe mpm_get_name__entry();
      probe mpm_get_name__dispatch__invoke(char *);
      probe mpm_get_name__dispatch__complete(char *, uint32_t);
      probe mpm_get_name__return(uint32_t);
      probe mpm_note_child_killed__entry();
      probe mpm_note_child_killed__dispatch__invoke(char *);
      probe mpm_note_child_killed__dispatch__complete(char *, uint32_t);
      probe mpm_note_child_killed__return(uint32_t);
      probe mpm_register_timed_callback__entry();
      probe mpm_register_timed_callback__dispatch__invoke(char *);
      probe mpm_register_timed_callback__dispatch__complete(char *, uint32_t);
      probe mpm_register_timed_callback__return(uint32_t);
      probe mpm_query__entry();
      probe mpm_query__dispatch__invoke(char *);
      probe mpm_query__dispatch__complete(char *, uint32_t);
      probe mpm_query__return(uint32_t);
      probe open_logs__entry();
      probe open_logs__dispatch__invoke(char *);
      probe open_logs__dispatch__complete(char *, uint32_t);
      probe open_logs__return(uint32_t);
      probe optional_fn_retrieve__entry();
      probe optional_fn_retrieve__dispatch__invoke(char *);
      probe optional_fn_retrieve__dispatch__complete(char *, uint32_t);
      probe optional_fn_retrieve__return(uint32_t);
      probe post_config__entry();
      probe post_config__dispatch__invoke(char *);
      probe post_config__dispatch__complete(char *, uint32_t);
      probe post_config__return(uint32_t);
      probe post_read_request__entry();
      probe post_read_request__dispatch__invoke(char *);
      probe post_read_request__dispatch__complete(char *, uint32_t);
      probe post_read_request__return(uint32_t);
      probe pre_config__entry();
      probe pre_config__dispatch__invoke(char *);
      probe pre_config__dispatch__complete(char *, uint32_t);
      probe pre_config__return(uint32_t);
      probe pre_connection__entry();
      probe pre_connection__dispatch__invoke(char *);
      probe pre_connection__dispatch__complete(char *, uint32_t);
      probe pre_connection__return(uint32_t);
      probe pre_mpm__entry();
      probe pre_mpm__dispatch__invoke(char *);
      probe pre_mpm__dispatch__complete(char *, uint32_t);
      probe pre_mpm__return(uint32_t);
      probe process_connection__entry();
      probe process_connection__dispatch__invoke(char *);
      probe process_connection__dispatch__complete(char *, uint32_t);
      probe process_connection__return(uint32_t);
      probe quick_handler__entry();
      probe quick_handler__dispatch__invoke(char *);
      probe quick_handler__dispatch__complete(char *, uint32_t);
      probe quick_handler__return(uint32_t);
      probe test_config__entry();
      probe test_config__dispatch__invoke(char *);
      probe test_config__dispatch__complete(char *, uint32_t);
      probe test_config__return(uint32_t);
      probe translate_name__entry();
      probe translate_name__dispatch__invoke(char *);
      probe translate_name__dispatch__complete(char *, uint32_t);
      probe translate_name__return(uint32_t);
      probe type_checker__entry();
      probe type_checker__dispatch__invoke(char *);
      probe type_checker__dispatch__complete(char *, uint32_t);
      probe type_checker__return(uint32_t);
    
      /* Implicit, APR hooks for proxy */
      probe canon_handler__entry();
      probe canon_handler__dispatch__invoke(char *);
      probe canon_handler__dispatch__complete(char *, uint32_t);
      probe canon_handler__return(uint32_t);
      probe post_request__entry();
      probe post_request__dispatch__invoke(char *);
      probe post_request__dispatch__complete(char *, uint32_t);
      probe post_request__return(uint32_t);
      probe pre_request__entry();
      probe pre_request__dispatch__invoke(char *);
      probe pre_request__dispatch__complete(char *, uint32_t);
      probe pre_request__return(uint32_t);
      probe scheme_handler__entry();
      probe scheme_handler__dispatch__invoke(char *);
      probe scheme_handler__dispatch__complete(char *, uint32_t);
      probe scheme_handler__return(uint32_t);
    
      /* Implicit, APR hooks for dav */
      probe find_liveprop__entry();
      probe find_liveprop__dispatch__invoke(char *);
      probe find_liveprop__dispatch__complete(char *, uint32_t);
      probe find_liveprop__return(uint32_t);
      probe gather_propsets__entry();
      probe gather_propsets__dispatch__invoke(char *);
      probe gather_propsets__dispatch__complete(char *, uint32_t);
      probe gather_propsets__return(uint32_t);
      probe insert_all_liveprops__entry();
      probe insert_all_liveprops__dispatch__invoke(char *);
      probe insert_all_liveprops__dispatch__complete(char *, uint32_t);
      probe insert_all_liveprops__return(uint32_t);
    
      /* Implicit, APR hooks for watchdog */
      probe watchdog_exit__entry();
      probe watchdog_exit__dispatch__invoke(char *);
      probe watchdog_exit__dispatch__complete(char *, uint32_t);
      probe watchdog_exit__return(uint32_t);
      probe watchdog_init__entry();
      probe watchdog_init__dispatch__invoke(char *);
      probe watchdog_init__dispatch__complete(char *, uint32_t);
      probe watchdog_init__return(uint32_t);
      probe watchdog_need__entry();
      probe watchdog_need__dispatch__invoke(char *);
      probe watchdog_need__dispatch__complete(char *, uint32_t);
      probe watchdog_need__return(uint32_t);
      probe watchdog_step__entry();
      probe watchdog_step__dispatch__invoke(char *);
      probe watchdog_step__dispatch__complete(char *, uint32_t);
      probe watchdog_step__return(uint32_t);
    };
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/BuildAll.dsp���������������������������������������������������������������������������0000664�0001751�0001751�00000005124�10663436562�015037� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Microsoft Developer Studio Project File - Name="BuildAll" - Package Owner=<4>
    # Microsoft Developer Studio Generated Build File, Format Version 6.00
    # ** DO NOT EDIT **
    
    # TARGTYPE "Win32 (x86) External Target" 0x0106
    
    CFG=BuildAll - 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 "BuildAll.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 "BuildAll.mak" CFG="BuildAll - Win32 Debug"
    !MESSAGE 
    !MESSAGE Possible choices for configuration are:
    !MESSAGE 
    !MESSAGE "BuildAll - Win32 Release" (based on "Win32 (x86) External Target")
    !MESSAGE "BuildAll - Win32 Debug" (based on "Win32 (x86) External Target")
    !MESSAGE 
    
    # Begin Project
    # PROP AllowPerConfigDependencies 0
    # PROP Scc_ProjName ""
    # PROP Scc_LocalPath ""
    
    !IF  "$(CFG)" == "BuildAll - 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 "\Apache2\bin\httpd.exe"
    # PROP BASE Bsc_Name ".\Browse\BuildAll.bsc"
    # PROP BASE Target_Dir ""
    # PROP Use_Debug_Libraries 0
    # PROP Output_Dir ""
    # PROP Intermediate_Dir ""
    # PROP Cmd_Line "NMAKE /f makefile.win INSTDIR="\Apache2" LONG=Release _dummy"
    # PROP Rebuild_Opt ""
    # PROP Target_File "\Apache2\bin\httpd.exe"
    # PROP Bsc_Name ".\Browse\httpd.bsc"
    # PROP Target_Dir ""
    
    !ELSEIF  "$(CFG)" == "BuildAll - 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 "\Apache2\bin\httpd.exe"
    # PROP BASE Bsc_Name ".\Browse\BuildAll.bsc"
    # PROP BASE Target_Dir ""
    # PROP Use_Debug_Libraries 1
    # PROP Output_Dir ""
    # PROP Intermediate_Dir ""
    # PROP Cmd_Line "NMAKE /f makefile.win INSTDIR="\Apache2" LONG=Debug _dummy"
    # PROP Rebuild_Opt ""
    # PROP Target_File "\Apache2\bin\httpd.exe"
    # PROP Bsc_Name ".\Browse\httpd.bsc"
    # PROP Target_Dir ""
    
    !ENDIF 
    
    # Begin Target
    
    # Name "BuildAll - Win32 Release"
    # Name "BuildAll - Win32 Debug"
    
    !IF  "$(CFG)" == "BuildAll - Win32 Release"
    
    !ELSEIF  "$(CFG)" == "BuildAll - 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
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/emacs-style����������������������������������������������������������������������������0000664�0001751�0001751�00000000623�10150161574�014774� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(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)
    �������������������������������������������������������������������������������������������������������������httpd-2.4.64/.deps����������������������������������������������������������������������������������0000664�0001751�0001751�00000000000�15032766617�013561� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/configure������������������������������������������������������������������������������0000775�0001751�0001751�00004615325�15032766626�014566� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh
    # Guess values for system-dependent variables and create Makefiles.
    # Generated by GNU Autoconf 2.71.
    #
    #
    # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
    # Inc.
    #
    #
    # This configure script is free software; the Free Software Foundation
    # gives unlimited permission to copy, distribute and modify it.
    ## -------------------- ##
    ## M4sh Initialization. ##
    ## -------------------- ##
    
    # Be more Bourne compatible
    DUALCASE=1; export DUALCASE # for MKS sh
    as_nop=:
    if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
    then :
      emulate sh
      NULLCMD=:
      # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
      # is contrary to our usage.  Disable this feature.
      alias -g '${1+"$@"}'='"$@"'
      setopt NO_GLOB_SUBST
    else $as_nop
      case `(set -o) 2>/dev/null` in #(
      *posix*) :
        set -o posix ;; #(
      *) :
         ;;
    esac
    fi
    
    
    
    # Reset variables that may have inherited troublesome values from
    # the environment.
    
    # IFS needs to be set, to space, tab, and newline, in precisely that order.
    # (If _AS_PATH_WALK were called with IFS unset, it would have the
    # side effect of setting IFS to empty, thus disabling word splitting.)
    # Quoting is to prevent editors from complaining about space-tab.
    as_nl='
    '
    export as_nl
    IFS=" ""	$as_nl"
    
    PS1='$ '
    PS2='> '
    PS4='+ '
    
    # Ensure predictable behavior from utilities with locale-dependent output.
    LC_ALL=C
    export LC_ALL
    LANGUAGE=C
    export LANGUAGE
    
    # We cannot yet rely on "unset" to work, but we need these variables
    # to be unset--not just set to an empty or harmless value--now, to
    # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
    # also avoids known problems related to "unset" and subshell syntax
    # in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
    for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
    do eval test \${$as_var+y} \
      && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
    done
    
    # Ensure that fds 0, 1, and 2 are open.
    if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
    if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
    if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
    
    # The user is always right.
    if ${PATH_SEPARATOR+false} :; then
      PATH_SEPARATOR=:
      (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
        (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
          PATH_SEPARATOR=';'
      }
    fi
    
    
    # Find who we are.  Look in the path if we contain no directory separator.
    as_myself=
    case $0 in #((
      *[\\/]* ) as_myself=$0 ;;
      *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        test -r "$as_dir$0" && as_myself=$as_dir$0 && break
      done
    IFS=$as_save_IFS
    
         ;;
    esac
    # We did not find ourselves, most probably we were run as `sh COMMAND'
    # in which case we are not to be found in the path.
    if test "x$as_myself" = x; then
      as_myself=$0
    fi
    if test ! -f "$as_myself"; then
      printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
      exit 1
    fi
    
    
    # Use a proper internal environment variable to ensure we don't fall
      # into an infinite loop, continuously re-executing ourselves.
      if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
        _as_can_reexec=no; export _as_can_reexec;
        # We cannot yet assume a decent shell, so we have to provide a
    # neutralization value for shells without unset; and this also
    # works around shells that cannot unset nonexistent variables.
    # Preserve -v and -x to the replacement shell.
    BASH_ENV=/dev/null
    ENV=/dev/null
    (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
    case $- in # ((((
      *v*x* | *x*v* ) as_opts=-vx ;;
      *v* ) as_opts=-v ;;
      *x* ) as_opts=-x ;;
      * ) as_opts= ;;
    esac
    exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
    # Admittedly, this is quite paranoid, since all the known shells bail
    # out after a failed `exec'.
    printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
    exit 255
      fi
      # We don't want this to propagate to other subprocesses.
              { _as_can_reexec=; unset _as_can_reexec;}
    if test "x$CONFIG_SHELL" = x; then
      as_bourne_compatible="as_nop=:
    if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
    then :
      emulate sh
      NULLCMD=:
      # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
      # is contrary to our usage.  Disable this feature.
      alias -g '\${1+\"\$@\"}'='\"\$@\"'
      setopt NO_GLOB_SUBST
    else \$as_nop
      case \`(set -o) 2>/dev/null\` in #(
      *posix*) :
        set -o posix ;; #(
      *) :
         ;;
    esac
    fi
    "
      as_required="as_fn_return () { (exit \$1); }
    as_fn_success () { as_fn_return 0; }
    as_fn_failure () { as_fn_return 1; }
    as_fn_ret_success () { return 0; }
    as_fn_ret_failure () { return 1; }
    
    exitcode=0
    as_fn_success || { exitcode=1; echo as_fn_success failed.; }
    as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
    as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
    as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
    if ( set x; as_fn_ret_success y && test x = \"\$1\" )
    then :
    
    else \$as_nop
      exitcode=1; echo positional parameters were not saved.
    fi
    test x\$exitcode = x0 || exit 1
    blah=\$(echo \$(echo blah))
    test x\"\$blah\" = xblah || exit 1
    test -x / || exit 1"
      as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
      as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
      eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
      test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
    test \$(( 1 + 1 )) = 2 || exit 1"
      if (eval "$as_required") 2>/dev/null
    then :
      as_have_required=yes
    else $as_nop
      as_have_required=no
    fi
      if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
    then :
    
    else $as_nop
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    as_found=false
    for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
      as_found=:
      case $as_dir in #(
    	 /*)
    	   for as_base in sh bash ksh sh5; do
    	     # Try only shells that exist, to save several forks.
    	     as_shell=$as_dir$as_base
    	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
    		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
    then :
      CONFIG_SHELL=$as_shell as_have_required=yes
    		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
    then :
      break 2
    fi
    fi
    	   done;;
           esac
      as_found=false
    done
    IFS=$as_save_IFS
    if $as_found
    then :
    
    else $as_nop
      if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
    	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
    then :
      CONFIG_SHELL=$SHELL as_have_required=yes
    fi
    fi
    
    
          if test "x$CONFIG_SHELL" != x
    then :
      export CONFIG_SHELL
                 # We cannot yet assume a decent shell, so we have to provide a
    # neutralization value for shells without unset; and this also
    # works around shells that cannot unset nonexistent variables.
    # Preserve -v and -x to the replacement shell.
    BASH_ENV=/dev/null
    ENV=/dev/null
    (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
    case $- in # ((((
      *v*x* | *x*v* ) as_opts=-vx ;;
      *v* ) as_opts=-v ;;
      *x* ) as_opts=-x ;;
      * ) as_opts= ;;
    esac
    exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
    # Admittedly, this is quite paranoid, since all the known shells bail
    # out after a failed `exec'.
    printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
    exit 255
    fi
    
        if test x$as_have_required = xno
    then :
      printf "%s\n" "$0: This script requires a shell more modern than all"
      printf "%s\n" "$0: the shells that I found on your system."
      if test ${ZSH_VERSION+y} ; then
        printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
        printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
      else
        printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system,
    $0: including any error possibly output before this
    $0: message. Then install a modern shell, or manually run
    $0: the script under such a shell if you do have one."
      fi
      exit 1
    fi
    fi
    fi
    SHELL=${CONFIG_SHELL-/bin/sh}
    export SHELL
    # Unset more variables known to interfere with behavior of common tools.
    CLICOLOR_FORCE= GREP_OPTIONS=
    unset CLICOLOR_FORCE GREP_OPTIONS
    
    ## --------------------- ##
    ## M4sh Shell Functions. ##
    ## --------------------- ##
    # as_fn_unset VAR
    # ---------------
    # Portably unset VAR.
    as_fn_unset ()
    {
      { eval $1=; unset $1;}
    }
    as_unset=as_fn_unset
    
    
    # as_fn_set_status STATUS
    # -----------------------
    # Set $? to STATUS, without forking.
    as_fn_set_status ()
    {
      return $1
    } # as_fn_set_status
    
    # as_fn_exit STATUS
    # -----------------
    # Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
    as_fn_exit ()
    {
      set +e
      as_fn_set_status $1
      exit $1
    } # as_fn_exit
    # as_fn_nop
    # ---------
    # Do nothing but, unlike ":", preserve the value of $?.
    as_fn_nop ()
    {
      return $?
    }
    as_nop=as_fn_nop
    
    # as_fn_mkdir_p
    # -------------
    # Create "$as_dir" as a directory, including parents if necessary.
    as_fn_mkdir_p ()
    {
    
      case $as_dir in #(
      -*) as_dir=./$as_dir;;
      esac
      test -d "$as_dir" || eval $as_mkdir_p || {
        as_dirs=
        while :; do
          case $as_dir in #(
          *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
          *) as_qdir=$as_dir;;
          esac
          as_dirs="'$as_qdir' $as_dirs"
          as_dir=`$as_dirname -- "$as_dir" ||
    $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
    	 X"$as_dir" : 'X\(//\)[^/]' \| \
    	 X"$as_dir" : 'X\(//\)$' \| \
    	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
    printf "%s\n" X"$as_dir" |
        sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)[^/].*/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\).*/{
    	    s//\1/
    	    q
    	  }
    	  s/.*/./; q'`
          test -d "$as_dir" && break
        done
        test -z "$as_dirs" || eval "mkdir $as_dirs"
      } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
    
    
    } # as_fn_mkdir_p
    
    # as_fn_executable_p FILE
    # -----------------------
    # Test if FILE is an executable regular file.
    as_fn_executable_p ()
    {
      test -f "$1" && test -x "$1"
    } # as_fn_executable_p
    # as_fn_append VAR VALUE
    # ----------------------
    # Append the text in VALUE to the end of the definition contained in VAR. Take
    # advantage of any shell optimizations that allow amortized linear growth over
    # repeated appends, instead of the typical quadratic growth present in naive
    # implementations.
    if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
    then :
      eval 'as_fn_append ()
      {
        eval $1+=\$2
      }'
    else $as_nop
      as_fn_append ()
      {
        eval $1=\$$1\$2
      }
    fi # as_fn_append
    
    # as_fn_arith ARG...
    # ------------------
    # Perform arithmetic evaluation on the ARGs, and store the result in the
    # global $as_val. Take advantage of shells that can avoid forks. The arguments
    # must be portable across $(()) and expr.
    if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
    then :
      eval 'as_fn_arith ()
      {
        as_val=$(( $* ))
      }'
    else $as_nop
      as_fn_arith ()
      {
        as_val=`expr "$@" || test $? -eq 1`
      }
    fi # as_fn_arith
    
    # as_fn_nop
    # ---------
    # Do nothing but, unlike ":", preserve the value of $?.
    as_fn_nop ()
    {
      return $?
    }
    as_nop=as_fn_nop
    
    # as_fn_error STATUS ERROR [LINENO LOG_FD]
    # ----------------------------------------
    # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
    # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
    # script with STATUS, using 1 if that was 0.
    as_fn_error ()
    {
      as_status=$1; test $as_status -eq 0 && as_status=1
      if test "$4"; then
        as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
      fi
      printf "%s\n" "$as_me: error: $2" >&2
      as_fn_exit $as_status
    } # as_fn_error
    
    if expr a : '\(a\)' >/dev/null 2>&1 &&
       test "X`expr 00001 : '.*\(...\)'`" = X001; then
      as_expr=expr
    else
      as_expr=false
    fi
    
    if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
      as_basename=basename
    else
      as_basename=false
    fi
    
    if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
      as_dirname=dirname
    else
      as_dirname=false
    fi
    
    as_me=`$as_basename -- "$0" ||
    $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
    	 X"$0" : 'X\(//\)$' \| \
    	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
    printf "%s\n" X/"$0" |
        sed '/^.*\/\([^/][^/]*\)\/*$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\/\(\/\/\)$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\/\(\/\).*/{
    	    s//\1/
    	    q
    	  }
    	  s/.*/./; q'`
    
    # Avoid depending upon Character Ranges.
    as_cr_letters='abcdefghijklmnopqrstuvwxyz'
    as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    as_cr_Letters=$as_cr_letters$as_cr_LETTERS
    as_cr_digits='0123456789'
    as_cr_alnum=$as_cr_Letters$as_cr_digits
    
    
      as_lineno_1=$LINENO as_lineno_1a=$LINENO
      as_lineno_2=$LINENO as_lineno_2a=$LINENO
      eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
      test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
      # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
      sed -n '
        p
        /[$]LINENO/=
      ' <$as_myself |
        sed '
          s/[$]LINENO.*/&-/
          t lineno
          b
          :lineno
          N
          :loop
          s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
          t loop
          s/-\n.*//
        ' >$as_me.lineno &&
      chmod +x "$as_me.lineno" ||
        { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
    
      # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
      # already done that, so ensure we don't try to do so again and fall
      # in an infinite loop.  This has already happened in practice.
      _as_can_reexec=no; export _as_can_reexec
      # Don't try to exec as it changes $[0], causing all sort of problems
      # (the dirname of $[0] is not the place where we might find the
      # original and so on.  Autoconf is especially sensitive to this).
      . "./$as_me.lineno"
      # Exit status is that of the last command.
      exit
    }
    
    
    # Determine whether it's possible to make 'echo' print without a newline.
    # These variables are no longer used directly by Autoconf, but are AC_SUBSTed
    # for compatibility with existing Makefiles.
    ECHO_C= ECHO_N= ECHO_T=
    case `echo -n x` in #(((((
    -n*)
      case `echo 'xy\c'` in
      *c*) ECHO_T='	';;	# ECHO_T is single tab character.
      xy)  ECHO_C='\c';;
      *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
           ECHO_T='	';;
      esac;;
    *)
      ECHO_N='-n';;
    esac
    
    # For backward compatibility with old third-party macros, we provide
    # the shell variables $as_echo and $as_echo_n.  New code should use
    # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
    as_echo='printf %s\n'
    as_echo_n='printf %s'
    
    
    rm -f conf$$ conf$$.exe conf$$.file
    if test -d conf$$.dir; then
      rm -f conf$$.dir/conf$$.file
    else
      rm -f conf$$.dir
      mkdir conf$$.dir 2>/dev/null
    fi
    if (echo >conf$$.file) 2>/dev/null; then
      if ln -s conf$$.file conf$$ 2>/dev/null; then
        as_ln_s='ln -s'
        # ... but there are two gotchas:
        # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
        # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
        # In both cases, we have to default to `cp -pR'.
        ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
          as_ln_s='cp -pR'
      elif ln conf$$.file conf$$ 2>/dev/null; then
        as_ln_s=ln
      else
        as_ln_s='cp -pR'
      fi
    else
      as_ln_s='cp -pR'
    fi
    rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
    rmdir conf$$.dir 2>/dev/null
    
    if mkdir -p . 2>/dev/null; then
      as_mkdir_p='mkdir -p "$as_dir"'
    else
      test -d ./-p && rmdir ./-p
      as_mkdir_p=false
    fi
    
    as_test_x='test -x'
    as_executable_p=as_fn_executable_p
    
    # Sed expression to map a string onto a valid CPP name.
    as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
    
    # Sed expression to map a string onto a valid variable name.
    as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
    
    
    test -n "$DJDIR" || exec 7<&0 </dev/null
    exec 6>&1
    
    # Name of the host.
    # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
    # so uname gets run too.
    ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
    
    #
    # Initializations.
    #
    ac_default_prefix=/usr/local
    ac_clean_files=
    ac_config_libobj_dir=.
    LIBOBJS=
    cross_compiling=no
    subdirs=
    MFLAGS=
    MAKEFLAGS=
    
    # Identity of this package.
    PACKAGE_NAME=''
    PACKAGE_TARNAME=''
    PACKAGE_VERSION=''
    PACKAGE_STRING=''
    PACKAGE_BUGREPORT=''
    PACKAGE_URL=''
    
    ac_unique_file="ABOUT_APACHE"
    enable_option_checking=no
    ac_default_prefix=/usr/local/apache2
    # Factoring default headers for most tests.
    ac_includes_default="\
    #include <stddef.h>
    #ifdef HAVE_STDIO_H
    # include <stdio.h>
    #endif
    #ifdef HAVE_STDLIB_H
    # include <stdlib.h>
    #endif
    #ifdef HAVE_STRING_H
    # include <string.h>
    #endif
    #ifdef HAVE_INTTYPES_H
    # include <inttypes.h>
    #endif
    #ifdef HAVE_STDINT_H
    # include <stdint.h>
    #endif
    #ifdef HAVE_STRINGS_H
    # include <strings.h>
    #endif
    #ifdef HAVE_SYS_TYPES_H
    # include <sys/types.h>
    #endif
    #ifdef HAVE_SYS_STAT_H
    # include <sys/stat.h>
    #endif
    #ifdef HAVE_UNISTD_H
    # include <unistd.h>
    #endif"
    
    ac_header_c_list=
    ac_subst_vars='LTLIBOBJS
    LIBOBJS
    ap_make_delimiter
    ap_make_include
    perlbin
    APU_CONFIG
    APU_VERSION
    APU_INCLUDEDIR
    APU_BINDIR
    APR_CONFIG
    APR_VERSION
    APR_INCLUDEDIR
    APR_BINDIR
    LOAD_ALL_MODULES
    ENABLED_DSO_MODULES
    DSO_MODULES
    ENABLED_MPM_MODULE
    MPM_MODULES
    INSTALL_PROG_FLAGS
    MK_IMPLIB
    SH_LIBTOOL
    SH_LIBS
    CORE_IMPLIB
    CORE_IMPLIB_FILE
    SSLPORT
    PORT
    MODULE_CLEANDIRS
    MODULE_DIRS
    LIBTOOL
    INTERNAL_CPPFLAGS
    NOTEST_LIBS
    NOTEST_LDFLAGS
    NOTEST_CXXFLAGS
    NOTEST_CFLAGS
    NOTEST_CPPFLAGS
    INCLUDES
    UTIL_LDFLAGS
    HTTPD_LDFLAGS
    SH_LDFLAGS
    LT_LDFLAGS
    LTFLAGS
    CXXFLAGS
    CXX
    other_targets
    proxycachedir
    runtimedir
    installbuilddir
    iconsdir
    errordir
    manualdir
    htdocsdir
    logfiledir
    cgidir
    abs_srcdir
    HTTPD_MMN
    HTTPD_VERSION
    EXTRA_INCLUDES
    EXTRA_LIBS
    EXTRA_LDFLAGS
    EXTRA_CXXFLAGS
    EXTRA_CFLAGS
    EXTRA_CPPFLAGS
    AP_CLEAN_SRCLIB_DIRS
    AP_BUILD_SRCLIB_DIRS
    AP_LIBS
    INSTALL_SUEXEC
    shared_build
    POST_SHARED_CMDS
    PRE_SHARED_CMDS
    MOD_SO_ENABLED
    OS_SPECIFIC_VARS
    SHLIBPATH_VAR
    BUILTIN_LIBS
    OS_DIR
    OS
    progname
    MOD_REWRITE_LDADD
    MOD_ALIAS_LDADD
    MOD_USERDIR_LDADD
    MOD_SPELING_LDADD
    MOD_ACTIONS_LDADD
    MOD_IMAGEMAP_LDADD
    MOD_DIR_LDADD
    MOD_NEGOTIATION_LDADD
    MOD_VHOST_ALIAS_LDADD
    MOD_DAV_LOCK_LDADD
    MOD_DAV_FS_LDADD
    MOD_CGI_LDADD
    MOD_CGID_LDADD
    MOD_SUEXEC_LDADD
    MOD_INFO_LDADD
    MOD_ASIS_LDADD
    MOD_AUTOINDEX_LDADD
    MOD_STATUS_LDADD
    MOD_DAV_LDADD
    MOD_HEARTMONITOR_LDADD
    MOD_HEARTBEAT_LDADD
    MOD_SYSTEMD_LDADD
    MOD_PRIVILEGES_LDADD
    MOD_UNIXD_LDADD
    MOD_MPM_EVENT_LDADD
    MPM_LIB
    MPM_SUBDIRS
    MOD_LBMETHOD_HEARTBEAT_LDADD
    MOD_LBMETHOD_BYBUSYNESS_LDADD
    MOD_LBMETHOD_BYTRAFFIC_LDADD
    MOD_LBMETHOD_BYREQUESTS_LDADD
    MOD_MD_LDADD
    MOD_PROXY_HTTP2_LDADD
    MOD_HTTP2_LDADD
    APACHECTL_ULIMIT
    NONPORTABLE_SUPPORT
    fcgistarter_LTFLAGS
    httxt2dbm_LTFLAGS
    htcacheclean_LTFLAGS
    checkgid_LTFLAGS
    ab_LTFLAGS
    htdbm_LTFLAGS
    logresolve_LTFLAGS
    rotatelogs_LTFLAGS
    htdigest_LTFLAGS
    htpasswd_LTFLAGS
    MOD_DIALUP_LDADD
    MOD_OPTIONAL_FN_EXPORT_LDADD
    MOD_OPTIONAL_FN_IMPORT_LDADD
    MOD_OPTIONAL_HOOK_IMPORT_LDADD
    MOD_OPTIONAL_HOOK_EXPORT_LDADD
    MOD_SSL_LDADD
    ab_LIBS
    ab_CFLAGS
    MOD_SLOTMEM_PLAIN_LDADD
    MOD_SLOTMEM_SHM_LDADD
    MOD_SESSION_DBD_LDADD
    MOD_SESSION_CRYPTO_LDADD
    MOD_SESSION_COOKIE_LDADD
    MOD_SESSION_LDADD
    MOD_PROXY_HCHECK_LDADD
    MOD_PROXY_EXPRESS_LDADD
    MOD_PROXY_BALANCER_LDADD
    MOD_PROXY_AJP_LDADD
    MOD_PROXY_WSTUNNEL_LDADD
    MOD_PROXY_FDPASS_LDADD
    MOD_PROXY_UWSGI_LDADD
    MOD_PROXY_SCGI_LDADD
    MOD_PROXY_FCGI_LDADD
    MOD_PROXY_HTTP_LDADD
    MOD_PROXY_FTP_LDADD
    MOD_PROXY_CONNECT_LDADD
    MOD_PROXY_LDADD
    MOD_REMOTEIP_LDADD
    MOD_VERSION_LDADD
    MOD_SETENVIF_LDADD
    MOD_UNIQUE_ID_LDADD
    MOD_USERTRACK_LDADD
    MOD_IDENT_LDADD
    MOD_HEADERS_LDADD
    MOD_EXPIRES_LDADD
    MOD_CERN_META_LDADD
    MOD_MIME_MAGIC_LDADD
    MOD_ENV_LDADD
    MOD_LUA_LDADD
    LUA_CFLAGS
    LUA_LIBS
    MOD_LOGIO_LDADD
    MOD_LOG_FORENSIC_LDADD
    MOD_LOG_DEBUG_LDADD
    MOD_LOG_CONFIG_LDADD
    MOD_LDAP_LDADD
    MOD_MIME_LDADD
    MOD_HTTP_LDADD
    MOD_BROTLI_LDADD
    MOD_PROXY_HTML_LDADD
    MOD_XML2ENC_LDADD
    MOD_DEFLATE_LDADD
    MOD_CHARSET_LITE_LDADD
    MOD_SED_LDADD
    MOD_SUBSTITUTE_LDADD
    MOD_REFLECTOR_LDADD
    MOD_FILTER_LDADD
    MOD_INCLUDE_LDADD
    MOD_REQUEST_LDADD
    MOD_EXT_FILTER_LDADD
    MOD_REQTIMEOUT_LDADD
    MOD_RATELIMIT_LDADD
    MOD_DATA_LDADD
    MOD_BUFFER_LDADD
    MOD_EXAMPLE_IPC_LDADD
    MOD_CASE_FILTER_IN_LDADD
    MOD_CASE_FILTER_LDADD
    MOD_EXAMPLE_HOOKS_LDADD
    MOD_ECHO_LDADD
    MOD_DUMPIO_LDADD
    MOD_BUCKETEER_LDADD
    MOD_DBD_LDADD
    MOD_MACRO_LDADD
    MOD_WATCHDOG_LDADD
    MOD_SO_LDADD
    INSTALL_DSO
    MOD_SOCACHE_DC_LDADD
    MOD_SOCACHE_REDIS_LDADD
    MOD_SOCACHE_MEMCACHE_LDADD
    MOD_SOCACHE_DBM_LDADD
    MOD_SOCACHE_SHMCB_LDADD
    MOD_CACHE_SOCACHE_LDADD
    MOD_CACHE_DISK_LDADD
    MOD_CACHE_LDADD
    MOD_FILE_CACHE_LDADD
    MOD_ISAPI_LDADD
    MOD_ALLOWMETHODS_LDADD
    MOD_AUTH_DIGEST_LDADD
    MOD_AUTH_FORM_LDADD
    MOD_AUTH_BASIC_LDADD
    MOD_ACCESS_COMPAT_LDADD
    MOD_AUTHNZ_FCGI_LDADD
    MOD_AUTHNZ_LDAP_LDADD
    MOD_AUTHZ_CORE_LDADD
    MOD_AUTHZ_DBD_LDADD
    MOD_AUTHZ_OWNER_LDADD
    MOD_AUTHZ_DBM_LDADD
    MOD_AUTHZ_USER_LDADD
    MOD_AUTHZ_GROUPFILE_LDADD
    MOD_AUTHZ_HOST_LDADD
    MOD_AUTHN_CORE_LDADD
    MOD_AUTHN_SOCACHE_LDADD
    MOD_AUTHN_DBD_LDADD
    MOD_AUTHN_ANON_LDADD
    MOD_AUTHN_DBM_LDADD
    MOD_AUTHN_FILE_LDADD
    PILDFLAGS
    PICFLAGS
    DTRACE
    CRYPT_LIBS
    MATH_LIBS
    MKDEP
    INSTALL
    MKINSTALLDIRS
    LYNX_PATH
    RANLIB
    LN_S
    AWK
    SVN
    RSYNC
    PKGCONFIG
    RM
    LTCFLAGS
    SHLTCFLAGS
    PCRE_LIBS
    ac_ct_PCRE_CONFIG
    PCRE_CONFIG
    CPP
    OBJEXT
    EXEEXT
    ac_ct_CC
    CPPFLAGS
    LDFLAGS
    CFLAGS
    CC
    target_os
    target_vendor
    target_cpu
    target
    host_os
    host_vendor
    host_cpu
    host
    build_os
    build_vendor
    build_cpu
    build
    EGREP
    GREP
    rel_proxycachedir
    exp_proxycachedir
    rel_logfiledir
    exp_logfiledir
    rel_runtimedir
    exp_runtimedir
    rel_localstatedir
    exp_localstatedir
    rel_includedir
    exp_includedir
    rel_cgidir
    exp_cgidir
    rel_manualdir
    exp_manualdir
    rel_htdocsdir
    exp_htdocsdir
    rel_iconsdir
    exp_iconsdir
    rel_errordir
    exp_errordir
    rel_installbuilddir
    exp_installbuilddir
    rel_datadir
    exp_datadir
    rel_sysconfdir
    exp_sysconfdir
    rel_mandir
    exp_mandir
    rel_libexecdir
    exp_libexecdir
    rel_libdir
    exp_libdir
    rel_sbindir
    exp_sbindir
    rel_bindir
    exp_bindir
    rel_exec_prefix
    exp_exec_prefix
    target_alias
    host_alias
    build_alias
    LIBS
    ECHO_T
    ECHO_N
    ECHO_C
    DEFS
    mandir
    localedir
    libdir
    psdir
    pdfdir
    dvidir
    htmldir
    infodir
    docdir
    oldincludedir
    includedir
    runstatedir
    localstatedir
    sharedstatedir
    sysconfdir
    datadir
    datarootdir
    libexecdir
    sbindir
    bindir
    program_transform_name
    prefix
    exec_prefix
    PACKAGE_URL
    PACKAGE_BUGREPORT
    PACKAGE_STRING
    PACKAGE_VERSION
    PACKAGE_TARNAME
    PACKAGE_NAME
    PATH_SEPARATOR
    SHELL'
    ac_subst_files=''
    ac_user_opts='
    enable_option_checking
    enable_layout
    with_included_apr
    with_apr
    with_apr_util
    with_pcre
    with_port
    with_sslport
    enable_dtrace
    enable_hook_probes
    enable_exception_hook
    enable_load_all_modules
    enable_maintainer_mode
    enable_debugger_mode
    enable_pie
    enable_modules
    enable_mods_shared
    enable_mods_static
    enable_authn_file
    enable_authn_dbm
    enable_authn_anon
    enable_authn_dbd
    enable_authn_socache
    enable_authn_core
    enable_authz_host
    enable_authz_groupfile
    enable_authz_user
    enable_authz_dbm
    enable_authz_owner
    enable_authz_dbd
    enable_authz_core
    enable_authnz_ldap
    enable_authnz_fcgi
    enable_access_compat
    enable_auth_basic
    enable_auth_form
    enable_auth_digest
    enable_allowmethods
    enable_isapi
    enable_file_cache
    enable_cache
    enable_cache_disk
    enable_cache_socache
    enable_socache_shmcb
    enable_socache_dbm
    enable_socache_memcache
    enable_socache_redis
    enable_socache_dc
    with_distcache
    enable_so
    enable_watchdog
    enable_macro
    enable_dbd
    enable_bucketeer
    enable_dumpio
    enable_echo
    enable_example_hooks
    enable_case_filter
    enable_case_filter_in
    enable_example_ipc
    enable_buffer
    enable_data
    enable_ratelimit
    enable_reqtimeout
    enable_ext_filter
    enable_request
    enable_include
    enable_filter
    enable_reflector
    enable_substitute
    enable_sed
    enable_charset_lite
    enable_deflate
    with_z
    enable_xml2enc
    with_libxml2
    enable_proxy_html
    enable_brotli
    with_brotli
    enable_http
    enable_mime
    enable_ldap
    enable_log_config
    enable_log_debug
    enable_log_forensic
    enable_logio
    enable_lua
    with_lua
    enable_luajit
    enable_env
    enable_mime_magic
    enable_cern_meta
    enable_expires
    enable_headers
    enable_ident
    enable_usertrack
    enable_unique_id
    enable_setenvif
    enable_version
    enable_remoteip
    enable_proxy
    enable_proxy_connect
    enable_proxy_ftp
    enable_proxy_http
    enable_proxy_fcgi
    enable_proxy_scgi
    enable_proxy_uwsgi
    enable_proxy_fdpass
    enable_proxy_wstunnel
    enable_proxy_ajp
    enable_proxy_balancer
    enable_proxy_express
    enable_proxy_hcheck
    enable_session
    enable_session_cookie
    enable_session_crypto
    enable_session_dbd
    enable_slotmem_shm
    enable_slotmem_plain
    enable_ssl
    with_ssl
    enable_ssl_staticlib_deps
    enable_optional_hook_export
    enable_optional_hook_import
    enable_optional_fn_import
    enable_optional_fn_export
    enable_dialup
    enable_static_support
    enable_static_htpasswd
    enable_static_htdigest
    enable_static_rotatelogs
    enable_static_logresolve
    enable_static_htdbm
    enable_static_ab
    enable_static_checkgid
    enable_static_htcacheclean
    enable_static_httxt2dbm
    enable_static_fcgistarter
    enable_http2
    with_nghttp2
    enable_nghttp2_staticlib_deps
    enable_proxy_http2
    enable_md
    with_jansson
    enable_jansson_staticlib_deps
    with_curl
    enable_curl_staticlib_deps
    enable_lbmethod_byrequests
    enable_lbmethod_bytraffic
    enable_lbmethod_bybusyness
    enable_lbmethod_heartbeat
    with_mpm
    enable_mpms_shared
    enable_unixd
    enable_privileges
    enable_systemd
    enable_heartbeat
    enable_heartmonitor
    enable_dav
    enable_status
    enable_autoindex
    enable_asis
    enable_info
    enable_suexec
    enable_cgid
    enable_cgi
    enable_cgid_fdpassing
    enable_dav_fs
    enable_dav_lock
    with_module
    enable_vhost_alias
    enable_negotiation
    enable_dir
    enable_imagemap
    enable_actions
    enable_speling
    enable_userdir
    enable_alias
    enable_rewrite
    with_program_name
    with_suexec_bin
    with_suexec_caller
    with_suexec_userdir
    with_suexec_docroot
    with_suexec_uidmin
    with_suexec_gidmin
    with_suexec_logfile
    with_suexec_syslog
    with_suexec_safepath
    with_suexec_umask
    enable_suexec_capabilities
    enable_v4_mapped
    '
          ac_precious_vars='build_alias
    host_alias
    target_alias
    CC
    CFLAGS
    LDFLAGS
    LIBS
    CPPFLAGS
    CPP'
    
    
    # Initialize some variables set by options.
    ac_init_help=
    ac_init_version=false
    ac_unrecognized_opts=
    ac_unrecognized_sep=
    # The variables have the same names as the options, with
    # dashes changed to underlines.
    cache_file=/dev/null
    exec_prefix=NONE
    no_create=
    no_recursion=
    prefix=NONE
    program_prefix=NONE
    program_suffix=NONE
    program_transform_name=s,x,x,
    silent=
    site=
    srcdir=
    verbose=
    x_includes=NONE
    x_libraries=NONE
    
    # Installation directory options.
    # These are left unexpanded so users can "make install exec_prefix=/foo"
    # and all the variables that are supposed to be based on exec_prefix
    # by default will actually change.
    # Use braces instead of parens because sh, perl, etc. also accept them.
    # (The list follows the same order as the GNU Coding Standards.)
    bindir='${exec_prefix}/bin'
    sbindir='${exec_prefix}/sbin'
    libexecdir='${exec_prefix}/libexec'
    datarootdir='${prefix}/share'
    datadir='${datarootdir}'
    sysconfdir='${prefix}/etc'
    sharedstatedir='${prefix}/com'
    localstatedir='${prefix}/var'
    runstatedir='${localstatedir}/run'
    includedir='${prefix}/include'
    oldincludedir='/usr/include'
    docdir='${datarootdir}/doc/${PACKAGE}'
    infodir='${datarootdir}/info'
    htmldir='${docdir}'
    dvidir='${docdir}'
    pdfdir='${docdir}'
    psdir='${docdir}'
    libdir='${exec_prefix}/lib'
    localedir='${datarootdir}/locale'
    mandir='${datarootdir}/man'
    
    ac_prev=
    ac_dashdash=
    for ac_option
    do
      # If the previous option needs an argument, assign it.
      if test -n "$ac_prev"; then
        eval $ac_prev=\$ac_option
        ac_prev=
        continue
      fi
    
      case $ac_option in
      *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
      *=)   ac_optarg= ;;
      *)    ac_optarg=yes ;;
      esac
    
      case $ac_dashdash$ac_option in
      --)
        ac_dashdash=yes ;;
    
      -bindir | --bindir | --bindi | --bind | --bin | --bi)
        ac_prev=bindir ;;
      -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
        bindir=$ac_optarg ;;
    
      -build | --build | --buil | --bui | --bu)
        ac_prev=build_alias ;;
      -build=* | --build=* | --buil=* | --bui=* | --bu=*)
        build_alias=$ac_optarg ;;
    
      -cache-file | --cache-file | --cache-fil | --cache-fi \
      | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
        ac_prev=cache_file ;;
      -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
      | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
        cache_file=$ac_optarg ;;
    
      --config-cache | -C)
        cache_file=config.cache ;;
    
      -datadir | --datadir | --datadi | --datad)
        ac_prev=datadir ;;
      -datadir=* | --datadir=* | --datadi=* | --datad=*)
        datadir=$ac_optarg ;;
    
      -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
      | --dataroo | --dataro | --datar)
        ac_prev=datarootdir ;;
      -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
      | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
        datarootdir=$ac_optarg ;;
    
      -disable-* | --disable-*)
        ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
        # Reject names that are not valid shell variable names.
        expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          as_fn_error $? "invalid feature name: \`$ac_useropt'"
        ac_useropt_orig=$ac_useropt
        ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
        case $ac_user_opts in
          *"
    "enable_$ac_useropt"
    "*) ;;
          *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
    	 ac_unrecognized_sep=', ';;
        esac
        eval enable_$ac_useropt=no ;;
    
      -docdir | --docdir | --docdi | --doc | --do)
        ac_prev=docdir ;;
      -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
        docdir=$ac_optarg ;;
    
      -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
        ac_prev=dvidir ;;
      -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
        dvidir=$ac_optarg ;;
    
      -enable-* | --enable-*)
        ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
        # Reject names that are not valid shell variable names.
        expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          as_fn_error $? "invalid feature name: \`$ac_useropt'"
        ac_useropt_orig=$ac_useropt
        ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
        case $ac_user_opts in
          *"
    "enable_$ac_useropt"
    "*) ;;
          *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
    	 ac_unrecognized_sep=', ';;
        esac
        eval enable_$ac_useropt=\$ac_optarg ;;
    
      -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
      | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
      | --exec | --exe | --ex)
        ac_prev=exec_prefix ;;
      -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
      | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
      | --exec=* | --exe=* | --ex=*)
        exec_prefix=$ac_optarg ;;
    
      -gas | --gas | --ga | --g)
        # Obsolete; use --with-gas.
        with_gas=yes ;;
    
      -help | --help | --hel | --he | -h)
        ac_init_help=long ;;
      -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
        ac_init_help=recursive ;;
      -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
        ac_init_help=short ;;
    
      -host | --host | --hos | --ho)
        ac_prev=host_alias ;;
      -host=* | --host=* | --hos=* | --ho=*)
        host_alias=$ac_optarg ;;
    
      -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
        ac_prev=htmldir ;;
      -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
      | --ht=*)
        htmldir=$ac_optarg ;;
    
      -includedir | --includedir | --includedi | --included | --include \
      | --includ | --inclu | --incl | --inc)
        ac_prev=includedir ;;
      -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
      | --includ=* | --inclu=* | --incl=* | --inc=*)
        includedir=$ac_optarg ;;
    
      -infodir | --infodir | --infodi | --infod | --info | --inf)
        ac_prev=infodir ;;
      -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
        infodir=$ac_optarg ;;
    
      -libdir | --libdir | --libdi | --libd)
        ac_prev=libdir ;;
      -libdir=* | --libdir=* | --libdi=* | --libd=*)
        libdir=$ac_optarg ;;
    
      -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
      | --libexe | --libex | --libe)
        ac_prev=libexecdir ;;
      -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
      | --libexe=* | --libex=* | --libe=*)
        libexecdir=$ac_optarg ;;
    
      -localedir | --localedir | --localedi | --localed | --locale)
        ac_prev=localedir ;;
      -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
        localedir=$ac_optarg ;;
    
      -localstatedir | --localstatedir | --localstatedi | --localstated \
      | --localstate | --localstat | --localsta | --localst | --locals)
        ac_prev=localstatedir ;;
      -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
      | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
        localstatedir=$ac_optarg ;;
    
      -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
        ac_prev=mandir ;;
      -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
        mandir=$ac_optarg ;;
    
      -nfp | --nfp | --nf)
        # Obsolete; use --without-fp.
        with_fp=no ;;
    
      -no-create | --no-create | --no-creat | --no-crea | --no-cre \
      | --no-cr | --no-c | -n)
        no_create=yes ;;
    
      -no-recursion | --no-recursion | --no-recursio | --no-recursi \
      | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
        no_recursion=yes ;;
    
      -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
      | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
      | --oldin | --oldi | --old | --ol | --o)
        ac_prev=oldincludedir ;;
      -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
      | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
      | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
        oldincludedir=$ac_optarg ;;
    
      -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
        ac_prev=prefix ;;
      -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
        prefix=$ac_optarg ;;
    
      -program-prefix | --program-prefix | --program-prefi | --program-pref \
      | --program-pre | --program-pr | --program-p)
        ac_prev=program_prefix ;;
      -program-prefix=* | --program-prefix=* | --program-prefi=* \
      | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
        program_prefix=$ac_optarg ;;
    
      -program-suffix | --program-suffix | --program-suffi | --program-suff \
      | --program-suf | --program-su | --program-s)
        ac_prev=program_suffix ;;
      -program-suffix=* | --program-suffix=* | --program-suffi=* \
      | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
        program_suffix=$ac_optarg ;;
    
      -program-transform-name | --program-transform-name \
      | --program-transform-nam | --program-transform-na \
      | --program-transform-n | --program-transform- \
      | --program-transform | --program-transfor \
      | --program-transfo | --program-transf \
      | --program-trans | --program-tran \
      | --progr-tra | --program-tr | --program-t)
        ac_prev=program_transform_name ;;
      -program-transform-name=* | --program-transform-name=* \
      | --program-transform-nam=* | --program-transform-na=* \
      | --program-transform-n=* | --program-transform-=* \
      | --program-transform=* | --program-transfor=* \
      | --program-transfo=* | --program-transf=* \
      | --program-trans=* | --program-tran=* \
      | --progr-tra=* | --program-tr=* | --program-t=*)
        program_transform_name=$ac_optarg ;;
    
      -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
        ac_prev=pdfdir ;;
      -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
        pdfdir=$ac_optarg ;;
    
      -psdir | --psdir | --psdi | --psd | --ps)
        ac_prev=psdir ;;
      -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
        psdir=$ac_optarg ;;
    
      -q | -quiet | --quiet | --quie | --qui | --qu | --q \
      | -silent | --silent | --silen | --sile | --sil)
        silent=yes ;;
    
      -runstatedir | --runstatedir | --runstatedi | --runstated \
      | --runstate | --runstat | --runsta | --runst | --runs \
      | --run | --ru | --r)
        ac_prev=runstatedir ;;
      -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
      | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
      | --run=* | --ru=* | --r=*)
        runstatedir=$ac_optarg ;;
    
      -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
        ac_prev=sbindir ;;
      -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
      | --sbi=* | --sb=*)
        sbindir=$ac_optarg ;;
    
      -sharedstatedir | --sharedstatedir | --sharedstatedi \
      | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
      | --sharedst | --shareds | --shared | --share | --shar \
      | --sha | --sh)
        ac_prev=sharedstatedir ;;
      -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
      | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
      | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
      | --sha=* | --sh=*)
        sharedstatedir=$ac_optarg ;;
    
      -site | --site | --sit)
        ac_prev=site ;;
      -site=* | --site=* | --sit=*)
        site=$ac_optarg ;;
    
      -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
        ac_prev=srcdir ;;
      -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
        srcdir=$ac_optarg ;;
    
      -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
      | --syscon | --sysco | --sysc | --sys | --sy)
        ac_prev=sysconfdir ;;
      -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
      | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
        sysconfdir=$ac_optarg ;;
    
      -target | --target | --targe | --targ | --tar | --ta | --t)
        ac_prev=target_alias ;;
      -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
        target_alias=$ac_optarg ;;
    
      -v | -verbose | --verbose | --verbos | --verbo | --verb)
        verbose=yes ;;
    
      -version | --version | --versio | --versi | --vers | -V)
        ac_init_version=: ;;
    
      -with-* | --with-*)
        ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
        # Reject names that are not valid shell variable names.
        expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          as_fn_error $? "invalid package name: \`$ac_useropt'"
        ac_useropt_orig=$ac_useropt
        ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
        case $ac_user_opts in
          *"
    "with_$ac_useropt"
    "*) ;;
          *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
    	 ac_unrecognized_sep=', ';;
        esac
        eval with_$ac_useropt=\$ac_optarg ;;
    
      -without-* | --without-*)
        ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
        # Reject names that are not valid shell variable names.
        expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          as_fn_error $? "invalid package name: \`$ac_useropt'"
        ac_useropt_orig=$ac_useropt
        ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
        case $ac_user_opts in
          *"
    "with_$ac_useropt"
    "*) ;;
          *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
    	 ac_unrecognized_sep=', ';;
        esac
        eval with_$ac_useropt=no ;;
    
      --x)
        # Obsolete; use --with-x.
        with_x=yes ;;
    
      -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
      | --x-incl | --x-inc | --x-in | --x-i)
        ac_prev=x_includes ;;
      -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
      | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
        x_includes=$ac_optarg ;;
    
      -x-libraries | --x-libraries | --x-librarie | --x-librari \
      | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
        ac_prev=x_libraries ;;
      -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
      | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
        x_libraries=$ac_optarg ;;
    
      -*) as_fn_error $? "unrecognized option: \`$ac_option'
    Try \`$0 --help' for more information"
        ;;
    
      *=*)
        ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
        # Reject names that are not valid shell variable names.
        case $ac_envvar in #(
          '' | [0-9]* | *[!_$as_cr_alnum]* )
          as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
        esac
        eval $ac_envvar=\$ac_optarg
        export $ac_envvar ;;
    
      *)
        # FIXME: should be removed in autoconf 3.0.
        printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
        expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
          printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
        : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
        ;;
    
      esac
    done
    
    if test -n "$ac_prev"; then
      ac_option=--`echo $ac_prev | sed 's/_/-/g'`
      as_fn_error $? "missing argument to $ac_option"
    fi
    
    if test -n "$ac_unrecognized_opts"; then
      case $enable_option_checking in
        no) ;;
        fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
        *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
      esac
    fi
    
    # Check all directory arguments for consistency.
    for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
    		datadir sysconfdir sharedstatedir localstatedir includedir \
    		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
    		libdir localedir mandir runstatedir
    do
      eval ac_val=\$$ac_var
      # Remove trailing slashes.
      case $ac_val in
        */ )
          ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
          eval $ac_var=\$ac_val;;
      esac
      # Be sure to have absolute directory names.
      case $ac_val in
        [\\/$]* | ?:[\\/]* )  continue;;
        NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
      esac
      as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
    done
    
    # There might be people who depend on the old broken behavior: `$host'
    # used to hold the argument of --host etc.
    # FIXME: To remove some day.
    build=$build_alias
    host=$host_alias
    target=$target_alias
    
    # FIXME: To remove some day.
    if test "x$host_alias" != x; then
      if test "x$build_alias" = x; then
        cross_compiling=maybe
      elif test "x$build_alias" != "x$host_alias"; then
        cross_compiling=yes
      fi
    fi
    
    ac_tool_prefix=
    test -n "$host_alias" && ac_tool_prefix=$host_alias-
    
    test "$silent" = yes && exec 6>/dev/null
    
    
    ac_pwd=`pwd` && test -n "$ac_pwd" &&
    ac_ls_di=`ls -di .` &&
    ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
      as_fn_error $? "working directory cannot be determined"
    test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
      as_fn_error $? "pwd does not report name of working directory"
    
    
    # Find the source files, if location was not specified.
    if test -z "$srcdir"; then
      ac_srcdir_defaulted=yes
      # Try the directory containing this script, then the parent directory.
      ac_confdir=`$as_dirname -- "$as_myself" ||
    $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
    	 X"$as_myself" : 'X\(//\)[^/]' \| \
    	 X"$as_myself" : 'X\(//\)$' \| \
    	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
    printf "%s\n" X"$as_myself" |
        sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)[^/].*/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\).*/{
    	    s//\1/
    	    q
    	  }
    	  s/.*/./; q'`
      srcdir=$ac_confdir
      if test ! -r "$srcdir/$ac_unique_file"; then
        srcdir=..
      fi
    else
      ac_srcdir_defaulted=no
    fi
    if test ! -r "$srcdir/$ac_unique_file"; then
      test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
      as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
    fi
    ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
    ac_abs_confdir=`(
    	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
    	pwd)`
    # When building in place, set srcdir=.
    if test "$ac_abs_confdir" = "$ac_pwd"; then
      srcdir=.
    fi
    # Remove unnecessary trailing slashes from srcdir.
    # Double slashes in file names in object file debugging info
    # mess up M-x gdb in Emacs.
    case $srcdir in
    */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
    esac
    for ac_var in $ac_precious_vars; do
      eval ac_env_${ac_var}_set=\${${ac_var}+set}
      eval ac_env_${ac_var}_value=\$${ac_var}
      eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
      eval ac_cv_env_${ac_var}_value=\$${ac_var}
    done
    
    #
    # Report the --help message.
    #
    if test "$ac_init_help" = "long"; then
      # Omit some internal or obsolete options to make the list less imposing.
      # This message is too long to be a string in the A/UX 3.1 sh.
      cat <<_ACEOF
    \`configure' configures this package to adapt to many kinds of systems.
    
    Usage: $0 [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.
    
    Defaults for the options are specified in brackets.
    
    Configuration:
      -h, --help              display this help and exit
          --help=short        display options specific to this package
          --help=recursive    display the short help of all the included packages
      -V, --version           display version information and exit
      -q, --quiet, --silent   do not print \`checking ...' messages
          --cache-file=FILE   cache test results in FILE [disabled]
      -C, --config-cache      alias for \`--cache-file=config.cache'
      -n, --no-create         do not create output files
          --srcdir=DIR        find the sources in DIR [configure dir or \`..']
    
    Installation directories:
      --prefix=PREFIX         install architecture-independent files in PREFIX
                              [$ac_default_prefix]
      --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                              [PREFIX]
    
    By default, \`make install' will install all the files in
    \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
    an installation prefix other than \`$ac_default_prefix' using \`--prefix',
    for instance \`--prefix=\$HOME'.
    
    For better control, use the options below.
    
    Fine tuning of the installation directories:
      --bindir=DIR            user executables [EPREFIX/bin]
      --sbindir=DIR           system admin executables [EPREFIX/sbin]
      --libexecdir=DIR        program executables [EPREFIX/libexec]
      --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
      --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
      --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
      --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
      --libdir=DIR            object code libraries [EPREFIX/lib]
      --includedir=DIR        C header files [PREFIX/include]
      --oldincludedir=DIR     C header files for non-gcc [/usr/include]
      --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
      --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
      --infodir=DIR           info documentation [DATAROOTDIR/info]
      --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
      --mandir=DIR            man documentation [DATAROOTDIR/man]
      --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
      --htmldir=DIR           html documentation [DOCDIR]
      --dvidir=DIR            dvi documentation [DOCDIR]
      --pdfdir=DIR            pdf documentation [DOCDIR]
      --psdir=DIR             ps documentation [DOCDIR]
    _ACEOF
    
      cat <<\_ACEOF
    
    System types:
      --build=BUILD     configure for building on BUILD [guessed]
      --host=HOST       cross-compile to build programs to run on HOST [BUILD]
      --target=TARGET   configure for building compilers for TARGET [HOST]
    _ACEOF
    fi
    
    if test -n "$ac_init_help"; then
    
      cat <<\_ACEOF
    
    Optional Features:
      --disable-option-checking  ignore unrecognized --enable/--with options
      --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
      --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
      --enable-layout=LAYOUT
      --enable-dtrace         Enable DTrace probes
      --enable-hook-probes    Enable APR hook probes
      --enable-exception-hook Enable fatal exception hook
      --enable-load-all-modules
                              Load all modules
      --enable-maintainer-mode
                              Turn on debugging and compile time warnings and load
                              all compiled modules
      --enable-debugger-mode  Turn on debugging and compile time warnings and turn
                              off optimization
      --enable-pie            Build httpd as a Position Independent Executable
      --enable-modules=MODULE-LIST
                              Space-separated list of modules to enable | "all" |
                              "most" | "few" | "none" | "reallyall"
      --enable-mods-shared=MODULE-LIST
                              Space-separated list of shared modules to enable |
                              "all" | "most" | "few" | "reallyall"
      --enable-mods-static=MODULE-LIST
                              Space-separated list of static modules to enable |
                              "all" | "most" | "few" | "reallyall"
      --disable-authn-file    file-based authentication control
      --enable-authn-dbm      DBM-based authentication control
      --enable-authn-anon     anonymous user authentication control
      --enable-authn-dbd      SQL-based authentication control
      --enable-authn-socache  Cached authentication control
      --disable-authn-core    core authentication module
      --disable-authz-host    host-based authorization control
      --disable-authz-groupfile
                              'require group' authorization control
      --disable-authz-user    'require user' authorization control
      --enable-authz-dbm      DBM-based authorization control
      --enable-authz-owner    'require file-owner' authorization control
      --enable-authz-dbd      SQL based authorization and Login/Session support
      --disable-authz-core    core authorization provider vector module
      --enable-authnz-ldap    LDAP based authentication
      --enable-authnz-fcgi    FastCGI authorizer-based authentication and
                              authorization
      --disable-access-compat mod_access compatibility
      --disable-auth-basic    basic authentication
      --enable-auth-form      form authentication
      --enable-auth-digest    RFC2617 Digest authentication
      --enable-allowmethods   restrict allowed HTTP methods
      --enable-isapi          isapi extension support
      --enable-file-cache     File cache
      --enable-cache          dynamic file caching. At least one storage
                              management module (e.g. mod_cache_disk) is also
                              necessary.
      --enable-cache-disk     disk caching module
      --enable-cache-socache  shared object caching module
      --enable-socache-shmcb  shmcb small object cache provider
      --enable-socache-dbm    dbm small object cache provider
      --enable-socache-memcache
                              memcache small object cache provider
      --enable-socache-redis  redis small object cache provider
      --enable-socache-dc     distcache small object cache provider
      --enable-so             DSO capability. This module will be automatically
                              enabled unless you build all modules statically.
      --enable-watchdog       Watchdog module
      --enable-macro          Define and use macros in configuration files
      --enable-dbd            Apache DBD Framework
      --enable-bucketeer      buckets manipulation filter. Useful only for
                              developers and testing purposes.
      --enable-dumpio         I/O dump filter
      --enable-echo           ECHO server
      --enable-example-hooks  Example hook callback handler module
      --enable-case-filter    Example uppercase conversion filter
      --enable-case-filter-in Example uppercase conversion input filter
      --enable-example-ipc    Example of shared memory and mutex usage
      --enable-buffer         Filter Buffering
      --enable-data           RFC2397 data encoder
      --enable-ratelimit      Output Bandwidth Limiting
      --disable-reqtimeout    Limit time waiting for request from client
      --enable-ext-filter     external filter module
      --enable-request        Request Body Filtering
      --enable-include        Server Side Includes
      --disable-filter        Smart Filtering
      --enable-reflector      Reflect request through the output filter stack
      --enable-substitute     response content rewrite-like filtering
      --enable-sed            filter request and/or response bodies through sed
      --disable-charset-lite  character set translation. Enabled by default only
                              on EBCDIC systems.
      --enable-charset-lite   character set translation. Enabled by default only
                              on EBCDIC systems.
      --enable-deflate        Deflate transfer encoding support
      --enable-xml2enc        i18n support for markup filters
      --enable-proxy-html     Fix HTML Links in a Reverse Proxy
      --enable-brotli         Brotli compression support
      --enable-http           HTTP protocol handling. The http module is a basic
                              one that enables 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-mime          mapping of file-extension to MIME. Disabling this
                              module is normally not recommended.
      --enable-ldap           LDAP caching and connection pooling services
      --disable-log-config    logging configuration. You won't be able to log
                              requests to the server without this module.
      --enable-log-debug      configurable debug logging
      --enable-log-forensic   forensic logging
      --enable-logio          input and output logging
      --enable-lua            Apache Lua Framework
      --enable-luajit         Enable LuaJit Support
      --disable-env           clearing/setting of ENV vars
      --enable-mime-magic     automagically determining MIME type
      --enable-cern-meta      CERN-type meta files
      --enable-expires        Expires header control
      --disable-headers       HTTP header control
      --enable-ident          RFC 1413 identity check
      --enable-usertrack      user-session tracking
      --enable-unique-id      per-request unique ids
      --disable-setenvif      basing ENV vars on headers
      --disable-version       determining httpd version in config files
      --enable-remoteip       translate header contents to an apparent client
                              remote_ip
      --enable-proxy          Apache proxy module
      --enable-proxy-connect  Apache proxy CONNECT module. Requires
                              --enable-proxy.
      --enable-proxy-ftp      Apache proxy FTP module. Requires --enable-proxy.
      --enable-proxy-http     Apache proxy HTTP module. Requires --enable-proxy.
      --enable-proxy-fcgi     Apache proxy FastCGI module. Requires
                              --enable-proxy.
      --enable-proxy-scgi     Apache proxy SCGI module. Requires --enable-proxy.
      --enable-proxy-uwsgi    Apache proxy UWSGI module. Requires --enable-proxy.
      --enable-proxy-fdpass   Apache proxy to Unix Daemon Socket module. Requires
                              --enable-proxy.
      --enable-proxy-wstunnel Apache proxy Websocket Tunnel module. Requires
                              --enable-proxy.
      --enable-proxy-ajp      Apache proxy AJP module. Requires --enable-proxy.
      --enable-proxy-balancer Apache proxy BALANCER module. Requires
                              --enable-proxy.
      --enable-proxy-express  mass reverse-proxy module. Requires --enable-proxy.
      --enable-proxy-hcheck   reverse-proxy health-check module. Requires
                              --enable-proxy and --enable-watchdog.
      --enable-session        session module
      --enable-session-cookie session cookie module
      --enable-session-crypto session crypto module
      --enable-session-dbd    session dbd module
      --enable-slotmem-shm    slotmem provider that uses shared memory
      --enable-slotmem-plain  slotmem provider that uses plain memory
      --enable-ssl            SSL/TLS support (mod_ssl)
      --enable-ssl-staticlib-deps
                              link mod_ssl with dependencies of OpenSSL's static
                              libraries (as indicated by "pkg-config --static").
                              Must be specified in addition to --enable-ssl.
      --enable-optional-hook-export
                              example optional hook exporter
      --enable-optional-hook-import
                              example optional hook importer
      --enable-optional-fn-import
                              example optional function importer
      --enable-optional-fn-export
                              example optional function exporter
      --enable-dialup         rate limits static files to dialup modem speeds
      --enable-static-support Build a statically linked version of the support
                              binaries
      --enable-static-htpasswd
                              Build a statically linked version of htpasswd
      --enable-static-htdigest
                              Build a statically linked version of htdigest
      --enable-static-rotatelogs
                              Build a statically linked version of rotatelogs
      --enable-static-logresolve
                              Build a statically linked version of logresolve
      --enable-static-htdbm   Build a statically linked version of htdbm
      --enable-static-ab      Build a statically linked version of ab
      --enable-static-checkgid
                              Build a statically linked version of checkgid
      --enable-static-htcacheclean
                              Build a statically linked version of htcacheclean
      --enable-static-httxt2dbm
                              Build a statically linked version of httxt2dbm
      --enable-static-fcgistarter
                              Build a statically linked version of fcgistarter
      --enable-http2          HTTP/2 protocol handling in addition to HTTP
                              protocol handling. Implemented by mod_http2. This
                              module requires a libnghttp2 installation. See
                              --with-nghttp2 on how to manage non-standard
                              locations. This module is usually linked shared and
                              requires loading.
      --enable-nghttp2-staticlib-deps
                              link mod_http2 with dependencies of libnghttp2's
                              static libraries (as indicated by "pkg-config
                              --static"). Must be specified in addition to
                              --enable-http2.
      --enable-proxy-http2    HTTP/2 proxy module. This module requires a
                              libnghttp2 installation. See --with-nghttp2 on how
                              to manage non-standard locations. Also requires
                              --enable-proxy.
      --enable-md             Managed Domain handling
      --enable-jansson-staticlib-deps
                              link mod_md with dependencies of libjansson's static
                              libraries (as indicated by "pkg-config --static").
                              Must be specified in addition to --enable-md.
      --enable-curl-staticlib-deps
                              link mod_md with dependencies of libcurl's static
                              libraries (as indicated by "pkg-config --static").
                              Must be specified in addition to --enable-md.
      --enable-lbmethod-byrequests
                              Apache proxy Load balancing by request counting
      --enable-lbmethod-bytraffic
                              Apache proxy Load balancing by traffic counting
      --enable-lbmethod-bybusyness
                              Apache proxy Load balancing by busyness
      --enable-lbmethod-heartbeat
                              Apache proxy Load balancing from Heartbeats
      --enable-mpms-shared=MPM-LIST
                              Space-separated list of MPM modules to enable for
                              dynamic loading. MPM-LIST=list | "all"
      --enable-unixd          unix specific support
      --enable-privileges     Per-virtualhost Unix UserIDs and enhanced security
                              for Solaris
      --enable-systemd        Systemd support
      --enable-heartbeat      Generates Heartbeats
      --enable-heartmonitor   Collects Heartbeats
      --enable-dav            WebDAV protocol handling. --enable-dav also enables
                              mod_dav_fs
      --disable-status        process/thread monitoring
      --disable-autoindex     directory listing
      --enable-asis           as-is filetypes
      --enable-info           server information
      --enable-suexec         set uid and gid for spawned processes
      --enable-cgid           CGI scripts. Enabled by default with threaded MPMs
      --enable-cgi            CGI scripts. Enabled by default with non-threaded
                              MPMs
      --enable-cgid-fdpassing Enable experimental mod_cgid support for fd passing
      --enable-dav-fs         DAV provider for the filesystem. --enable-dav also
                              enables mod_dav_fs.
      --enable-dav-lock       DAV provider for generic locking
      --enable-vhost-alias    mass virtual hosting module
      --enable-negotiation    content negotiation
      --disable-dir           directory request handling
      --enable-imagemap       server-side imagemaps
      --enable-actions        Action triggering on requests
      --enable-speling        correct common URL misspellings
      --enable-userdir        mapping of requests to user-specific directories
      --disable-alias         mapping of requests to different filesystem parts
      --enable-rewrite        rule based URL manipulation
      --enable-suexec-capabilities
                              Use Linux capability bits not setuid root suexec
      --enable-v4-mapped      Allow IPv6 sockets to handle IPv4 connections
    
    Optional Packages:
      --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
      --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
      --with-included-apr     Use bundled copies of APR/APR-Util
      --with-apr=PATH         prefix for installed APR or the full path to
                                 apr-config
      --with-apr-util=PATH    prefix for installed APU or the full path to
                                 apu-config
      --with-pcre=PATH        Use external PCRE library
      --with-port=PORT        Port on which to listen (default is 80)
      --with-sslport=SSLPORT  Port on which to securelisten (default is 443)
      --with-distcache=PATH   Distcache installation directory
      --with-z=PATH           use a specific zlib library
      --with-libxml2=PATH     location for libxml2
      --with-brotli=PATH      Brotli installation directory
      --with-lua=PATH         Path to the Lua installation prefix
      --with-ssl=PATH         OpenSSL installation directory
      --with-nghttp2=PATH     nghttp2 installation directory
      --with-jansson=PATH     jansson installation directory
      --with-curl=PATH        curl installation directory
      --with-mpm=MPM          Choose the process model for Apache to use by
                              default. MPM={event|worker|prefork|winnt} This will
                              be statically linked as the only available MPM
                              unless --enable-mpms-shared is also specified.
      --with-module=module-type:module-file
                              Enable module-file in the modules/<module-type>
                              directory.
      --with-program-name     alternate executable name
      --with-suexec-bin       Path to suexec binary
      --with-suexec-caller    User allowed to call SuExec
      --with-suexec-userdir   User subdirectory
      --with-suexec-docroot   SuExec root directory
      --with-suexec-uidmin    Minimal allowed UID
      --with-suexec-gidmin    Minimal allowed GID
      --with-suexec-logfile   Set the logfile
      --with-suexec-syslog    Use syslog for suexec logging
      --with-suexec-safepath  Set the safepath
      --with-suexec-umask     umask for suexec'd process
    
    Some influential environment variables:
      CC          C compiler command
      CFLAGS      C compiler flags
      LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
                  nonstandard directory <lib dir>
      LIBS        libraries to pass to the linker, e.g. -l<library>
      CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
                  you have headers in a nonstandard directory <include dir>
      CPP         C preprocessor
    
    Use these variables to override the choices made by `configure' or to help
    it to find libraries and programs with nonstandard names/locations.
    
    Report bugs to the package provider.
    _ACEOF
    ac_status=$?
    fi
    
    if test "$ac_init_help" = "recursive"; then
      # If there are subdirs, report their specific --help.
      for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
        test -d "$ac_dir" ||
          { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
          continue
        ac_builddir=.
    
    case "$ac_dir" in
    .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
    *)
      ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
      # A ".." for each directory in $ac_dir_suffix.
      ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
      case $ac_top_builddir_sub in
      "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
      *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
      esac ;;
    esac
    ac_abs_top_builddir=$ac_pwd
    ac_abs_builddir=$ac_pwd$ac_dir_suffix
    # for backward compatibility:
    ac_top_builddir=$ac_top_build_prefix
    
    case $srcdir in
      .)  # We are building in place.
        ac_srcdir=.
        ac_top_srcdir=$ac_top_builddir_sub
        ac_abs_top_srcdir=$ac_pwd ;;
      [\\/]* | ?:[\\/]* )  # Absolute name.
        ac_srcdir=$srcdir$ac_dir_suffix;
        ac_top_srcdir=$srcdir
        ac_abs_top_srcdir=$srcdir ;;
      *) # Relative name.
        ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
        ac_top_srcdir=$ac_top_build_prefix$srcdir
        ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
    esac
    ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
    
        cd "$ac_dir" || { ac_status=$?; continue; }
        # Check for configure.gnu first; this name is used for a wrapper for
        # Metaconfig's "Configure" on case-insensitive file systems.
        if test -f "$ac_srcdir/configure.gnu"; then
          echo &&
          $SHELL "$ac_srcdir/configure.gnu" --help=recursive
        elif test -f "$ac_srcdir/configure"; then
          echo &&
          $SHELL "$ac_srcdir/configure" --help=recursive
        else
          printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
        fi || ac_status=$?
        cd "$ac_pwd" || { ac_status=$?; break; }
      done
    fi
    
    test -n "$ac_init_help" && exit $ac_status
    if $ac_init_version; then
      cat <<\_ACEOF
    configure
    generated by GNU Autoconf 2.71
    
    Copyright (C) 2021 Free Software Foundation, Inc.
    This configure script is free software; the Free Software Foundation
    gives unlimited permission to copy, distribute and modify it.
    _ACEOF
      exit
    fi
    
    ## ------------------------ ##
    ## Autoconf initialization. ##
    ## ------------------------ ##
    
    # ac_fn_c_try_compile LINENO
    # --------------------------
    # Try to compile conftest.$ac_ext, and return whether this succeeded.
    ac_fn_c_try_compile ()
    {
      as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
      rm -f conftest.$ac_objext conftest.beam
      if { { ac_try="$ac_compile"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_compile") 2>conftest.err
      ac_status=$?
      if test -s conftest.err; then
        grep -v '^ *+' conftest.err >conftest.er1
        cat conftest.er1 >&5
        mv -f conftest.er1 conftest.err
      fi
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; } && {
    	 test -z "$ac_c_werror_flag" ||
    	 test ! -s conftest.err
           } && test -s conftest.$ac_objext
    then :
      ac_retval=0
    else $as_nop
      printf "%s\n" "$as_me: failed program was:" >&5
    sed 's/^/| /' conftest.$ac_ext >&5
    
    	ac_retval=1
    fi
      eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
      as_fn_set_status $ac_retval
    
    } # ac_fn_c_try_compile
    
    # ac_fn_c_try_cpp LINENO
    # ----------------------
    # Try to preprocess conftest.$ac_ext, and return whether this succeeded.
    ac_fn_c_try_cpp ()
    {
      as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
      if { { ac_try="$ac_cpp conftest.$ac_ext"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
      ac_status=$?
      if test -s conftest.err; then
        grep -v '^ *+' conftest.err >conftest.er1
        cat conftest.er1 >&5
        mv -f conftest.er1 conftest.err
      fi
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; } > conftest.i && {
    	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
    	 test ! -s conftest.err
           }
    then :
      ac_retval=0
    else $as_nop
      printf "%s\n" "$as_me: failed program was:" >&5
    sed 's/^/| /' conftest.$ac_ext >&5
    
        ac_retval=1
    fi
      eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
      as_fn_set_status $ac_retval
    
    } # ac_fn_c_try_cpp
    
    # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
    # -------------------------------------------------------
    # Tests whether HEADER exists and can be compiled using the include files in
    # INCLUDES, setting the cache variable VAR accordingly.
    ac_fn_c_check_header_compile ()
    {
      as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
    printf %s "checking for $2... " >&6; }
    if eval test \${$3+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    $4
    #include <$2>
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      eval "$3=yes"
    else $as_nop
      eval "$3=no"
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    eval ac_res=\$$3
    	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
    printf "%s\n" "$ac_res" >&6; }
      eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
    
    } # ac_fn_c_check_header_compile
    
    # ac_fn_c_try_link LINENO
    # -----------------------
    # Try to link conftest.$ac_ext, and return whether this succeeded.
    ac_fn_c_try_link ()
    {
      as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
      rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
      if { { ac_try="$ac_link"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_link") 2>conftest.err
      ac_status=$?
      if test -s conftest.err; then
        grep -v '^ *+' conftest.err >conftest.er1
        cat conftest.er1 >&5
        mv -f conftest.er1 conftest.err
      fi
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; } && {
    	 test -z "$ac_c_werror_flag" ||
    	 test ! -s conftest.err
           } && test -s conftest$ac_exeext && {
    	 test "$cross_compiling" = yes ||
    	 test -x conftest$ac_exeext
           }
    then :
      ac_retval=0
    else $as_nop
      printf "%s\n" "$as_me: failed program was:" >&5
    sed 's/^/| /' conftest.$ac_ext >&5
    
    	ac_retval=1
    fi
      # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
      # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
      # interfere with the next link command; also delete a directory that is
      # left behind by Apple's compiler.  We do this before executing the actions.
      rm -rf conftest.dSYM conftest_ipa8_conftest.oo
      eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
      as_fn_set_status $ac_retval
    
    } # ac_fn_c_try_link
    
    # ac_fn_c_try_run LINENO
    # ----------------------
    # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
    # executables *can* be run.
    ac_fn_c_try_run ()
    {
      as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
      if { { ac_try="$ac_link"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_link") 2>&5
      ac_status=$?
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
      { { case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_try") 2>&5
      ac_status=$?
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; }; }
    then :
      ac_retval=0
    else $as_nop
      printf "%s\n" "$as_me: program exited with status $ac_status" >&5
           printf "%s\n" "$as_me: failed program was:" >&5
    sed 's/^/| /' conftest.$ac_ext >&5
    
           ac_retval=$ac_status
    fi
      rm -rf conftest.dSYM conftest_ipa8_conftest.oo
      eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
      as_fn_set_status $ac_retval
    
    } # ac_fn_c_try_run
    
    # ac_fn_c_check_func LINENO FUNC VAR
    # ----------------------------------
    # Tests whether FUNC exists, setting the cache variable VAR accordingly
    ac_fn_c_check_func ()
    {
      as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
    printf %s "checking for $2... " >&6; }
    if eval test \${$3+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
       For example, HP-UX 11i <limits.h> declares gettimeofday.  */
    #define $2 innocuous_$2
    
    /* System header to define __stub macros and hopefully few prototypes,
       which can conflict with char $2 (); below.  */
    
    #include <limits.h>
    #undef $2
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    #ifdef __cplusplus
    extern "C"
    #endif
    char $2 ();
    /* The GNU C library defines this for functions which it implements
        to always fail with ENOSYS.  Some functions are actually named
        something starting with __ and the normal name is an alias.  */
    #if defined __stub_$2 || defined __stub___$2
    choke me
    #endif
    
    int
    main (void)
    {
    return $2 ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      eval "$3=yes"
    else $as_nop
      eval "$3=no"
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    fi
    eval ac_res=\$$3
    	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
    printf "%s\n" "$ac_res" >&6; }
      eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
    
    } # ac_fn_c_check_func
    
    # ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR
    # ------------------------------------------------------------------
    # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
    # accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR.
    ac_fn_check_decl ()
    {
      as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
      as_decl_name=`echo $2|sed 's/ *(.*//'`
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
    printf %s "checking whether $as_decl_name is declared... " >&6; }
    if eval test \${$3+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
      eval ac_save_FLAGS=\$$6
      as_fn_append $6 " $5"
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    $4
    int
    main (void)
    {
    #ifndef $as_decl_name
    #ifdef __cplusplus
      (void) $as_decl_use;
    #else
      (void) $as_decl_name;
    #endif
    #endif
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      eval "$3=yes"
    else $as_nop
      eval "$3=no"
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
      eval $6=\$ac_save_FLAGS
    
    fi
    eval ac_res=\$$3
    	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
    printf "%s\n" "$ac_res" >&6; }
      eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
    
    } # ac_fn_check_decl
    ac_configure_args_raw=
    for ac_arg
    do
      case $ac_arg in
      *\'*)
        ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
      esac
      as_fn_append ac_configure_args_raw " '$ac_arg'"
    done
    
    case $ac_configure_args_raw in
      *$as_nl*)
        ac_safe_unquote= ;;
      *)
        ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
        ac_unsafe_a="$ac_unsafe_z#~"
        ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
        ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
    esac
    
    cat >config.log <<_ACEOF
    This file contains any messages produced by compilers while
    running configure, to aid debugging if configure makes a mistake.
    
    It was created by $as_me, which was
    generated by GNU Autoconf 2.71.  Invocation command line was
    
      $ $0$ac_configure_args_raw
    
    _ACEOF
    exec 5>>config.log
    {
    cat <<_ASUNAME
    ## --------- ##
    ## Platform. ##
    ## --------- ##
    
    hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
    uname -m = `(uname -m) 2>/dev/null || echo unknown`
    uname -r = `(uname -r) 2>/dev/null || echo unknown`
    uname -s = `(uname -s) 2>/dev/null || echo unknown`
    uname -v = `(uname -v) 2>/dev/null || echo unknown`
    
    /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
    /bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
    
    /bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
    /usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
    /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
    /usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
    /bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
    /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
    /bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
    
    _ASUNAME
    
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        printf "%s\n" "PATH: $as_dir"
      done
    IFS=$as_save_IFS
    
    } >&5
    
    cat >&5 <<_ACEOF
    
    
    ## ----------- ##
    ## Core tests. ##
    ## ----------- ##
    
    _ACEOF
    
    
    # Keep a trace of the command line.
    # Strip out --no-create and --no-recursion so they do not pile up.
    # Strip out --silent because we don't want to record it for future runs.
    # Also quote any args containing shell meta-characters.
    # Make two passes to allow for proper duplicate-argument suppression.
    ac_configure_args=
    ac_configure_args0=
    ac_configure_args1=
    ac_must_keep_next=false
    for ac_pass in 1 2
    do
      for ac_arg
      do
        case $ac_arg in
        -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
        -q | -quiet | --quiet | --quie | --qui | --qu | --q \
        | -silent | --silent | --silen | --sile | --sil)
          continue ;;
        *\'*)
          ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
        esac
        case $ac_pass in
        1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
        2)
          as_fn_append ac_configure_args1 " '$ac_arg'"
          if test $ac_must_keep_next = true; then
    	ac_must_keep_next=false # Got value, back to normal.
          else
    	case $ac_arg in
    	  *=* | --config-cache | -C | -disable-* | --disable-* \
    	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
    	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
    	  | -with-* | --with-* | -without-* | --without-* | --x)
    	    case "$ac_configure_args0 " in
    	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
    	    esac
    	    ;;
    	  -* ) ac_must_keep_next=true ;;
    	esac
          fi
          as_fn_append ac_configure_args " '$ac_arg'"
          ;;
        esac
      done
    done
    { ac_configure_args0=; unset ac_configure_args0;}
    { ac_configure_args1=; unset ac_configure_args1;}
    
    # When interrupted or exit'd, cleanup temporary files, and complete
    # config.log.  We remove comments because anyway the quotes in there
    # would cause problems or look ugly.
    # WARNING: Use '\'' to represent an apostrophe within the trap.
    # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
    trap 'exit_status=$?
      # Sanitize IFS.
      IFS=" ""	$as_nl"
      # Save into config.log some information that might help in debugging.
      {
        echo
    
        printf "%s\n" "## ---------------- ##
    ## Cache variables. ##
    ## ---------------- ##"
        echo
        # The following way of writing the cache mishandles newlines in values,
    (
      for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
        eval ac_val=\$$ac_var
        case $ac_val in #(
        *${as_nl}*)
          case $ac_var in #(
          *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
    printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
          esac
          case $ac_var in #(
          _ | IFS | as_nl) ;; #(
          BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
          *) { eval $ac_var=; unset $ac_var;} ;;
          esac ;;
        esac
      done
      (set) 2>&1 |
        case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
        *${as_nl}ac_space=\ *)
          sed -n \
    	"s/'\''/'\''\\\\'\'''\''/g;
    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
          ;; #(
        *)
          sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
          ;;
        esac |
        sort
    )
        echo
    
        printf "%s\n" "## ----------------- ##
    ## Output variables. ##
    ## ----------------- ##"
        echo
        for ac_var in $ac_subst_vars
        do
          eval ac_val=\$$ac_var
          case $ac_val in
          *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
          esac
          printf "%s\n" "$ac_var='\''$ac_val'\''"
        done | sort
        echo
    
        if test -n "$ac_subst_files"; then
          printf "%s\n" "## ------------------- ##
    ## File substitutions. ##
    ## ------------------- ##"
          echo
          for ac_var in $ac_subst_files
          do
    	eval ac_val=\$$ac_var
    	case $ac_val in
    	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
    	esac
    	printf "%s\n" "$ac_var='\''$ac_val'\''"
          done | sort
          echo
        fi
    
        if test -s confdefs.h; then
          printf "%s\n" "## ----------- ##
    ## confdefs.h. ##
    ## ----------- ##"
          echo
          cat confdefs.h
          echo
        fi
        test "$ac_signal" != 0 &&
          printf "%s\n" "$as_me: caught signal $ac_signal"
        printf "%s\n" "$as_me: exit $exit_status"
      } >&5
      rm -f core *.core core.conftest.* &&
        rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
        exit $exit_status
    ' 0
    for ac_signal in 1 2 13 15; do
      trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
    done
    ac_signal=0
    
    # confdefs.h avoids OS command line length limits that DEFS can exceed.
    rm -f -r conftest* confdefs.h
    
    printf "%s\n" "/* confdefs.h */" > confdefs.h
    
    # Predefined preprocessor variables.
    
    printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
    
    printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
    
    printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
    
    printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
    
    printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
    
    printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
    
    
    # Let the site file select an alternate cache file if it wants to.
    # Prefer an explicitly selected file to automatically selected ones.
    if test -n "$CONFIG_SITE"; then
      ac_site_files="$CONFIG_SITE"
    elif test "x$prefix" != xNONE; then
      ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
    else
      ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
    fi
    
    for ac_site_file in $ac_site_files
    do
      case $ac_site_file in #(
      */*) :
         ;; #(
      *) :
        ac_site_file=./$ac_site_file ;;
    esac
      if test -f "$ac_site_file" && test -r "$ac_site_file"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
    printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
        sed 's/^/| /' "$ac_site_file" >&5
        . "$ac_site_file" \
          || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "failed to load site script $ac_site_file
    See \`config.log' for more details" "$LINENO" 5; }
      fi
    done
    
    if test -r "$cache_file"; then
      # Some versions of bash will fail to source /dev/null (special files
      # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
      if test /dev/null != "$cache_file" && test -f "$cache_file"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
    printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
        case $cache_file in
          [\\/]* | ?:[\\/]* ) . "$cache_file";;
          *)                      . "./$cache_file";;
        esac
      fi
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
    printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
      >$cache_file
    fi
    
    # Test code for whether the C compiler supports C89 (global declarations)
    ac_c_conftest_c89_globals='
    /* Does the compiler advertise C89 conformance?
       Do not test the value of __STDC__, because some compilers set it to 0
       while being otherwise adequately conformant. */
    #if !defined __STDC__
    # error "Compiler does not advertise C89 conformance"
    #endif
    
    #include <stddef.h>
    #include <stdarg.h>
    struct stat;
    /* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
    struct buf { int x; };
    struct buf * (*rcsopen) (struct buf *, struct stat *, int);
    static char *e (p, i)
         char **p;
         int i;
    {
      return p[i];
    }
    static char *f (char * (*g) (char **, int), char **p, ...)
    {
      char *s;
      va_list v;
      va_start (v,p);
      s = g (p, va_arg (v,int));
      va_end (v);
      return s;
    }
    
    /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
       function prototypes and stuff, but not \xHH hex character constants.
       These do not provoke an error unfortunately, instead are silently treated
       as an "x".  The following induces an error, until -std is added to get
       proper ANSI mode.  Curiously \x00 != x always comes out true, for an
       array size at least.  It is necessary to write \x00 == 0 to get something
       that is true only with -std.  */
    int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
    
    /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
       inside strings and character constants.  */
    #define FOO(x) '\''x'\''
    int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
    
    int test (int i, double x);
    struct s1 {int (*f) (int a);};
    struct s2 {int (*f) (double a);};
    int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
                   int, int);'
    
    # Test code for whether the C compiler supports C89 (body of main).
    ac_c_conftest_c89_main='
    ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
    '
    
    # Test code for whether the C compiler supports C99 (global declarations)
    ac_c_conftest_c99_globals='
    // Does the compiler advertise C99 conformance?
    #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
    # error "Compiler does not advertise C99 conformance"
    #endif
    
    #include <stdbool.h>
    extern int puts (const char *);
    extern int printf (const char *, ...);
    extern int dprintf (int, const char *, ...);
    extern void *malloc (size_t);
    
    // Check varargs macros.  These examples are taken from C99 6.10.3.5.
    // dprintf is used instead of fprintf to avoid needing to declare
    // FILE and stderr.
    #define debug(...) dprintf (2, __VA_ARGS__)
    #define showlist(...) puts (#__VA_ARGS__)
    #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
    static void
    test_varargs_macros (void)
    {
      int x = 1234;
      int y = 5678;
      debug ("Flag");
      debug ("X = %d\n", x);
      showlist (The first, second, and third items.);
      report (x>y, "x is %d but y is %d", x, y);
    }
    
    // Check long long types.
    #define BIG64 18446744073709551615ull
    #define BIG32 4294967295ul
    #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
    #if !BIG_OK
      #error "your preprocessor is broken"
    #endif
    #if BIG_OK
    #else
      #error "your preprocessor is broken"
    #endif
    static long long int bignum = -9223372036854775807LL;
    static unsigned long long int ubignum = BIG64;
    
    struct incomplete_array
    {
      int datasize;
      double data[];
    };
    
    struct named_init {
      int number;
      const wchar_t *name;
      double average;
    };
    
    typedef const char *ccp;
    
    static inline int
    test_restrict (ccp restrict text)
    {
      // See if C++-style comments work.
      // Iterate through items via the restricted pointer.
      // Also check for declarations in for loops.
      for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
        continue;
      return 0;
    }
    
    // Check varargs and va_copy.
    static bool
    test_varargs (const char *format, ...)
    {
      va_list args;
      va_start (args, format);
      va_list args_copy;
      va_copy (args_copy, args);
    
      const char *str = "";
      int number = 0;
      float fnumber = 0;
    
      while (*format)
        {
          switch (*format++)
    	{
    	case '\''s'\'': // string
    	  str = va_arg (args_copy, const char *);
    	  break;
    	case '\''d'\'': // int
    	  number = va_arg (args_copy, int);
    	  break;
    	case '\''f'\'': // float
    	  fnumber = va_arg (args_copy, double);
    	  break;
    	default:
    	  break;
    	}
        }
      va_end (args_copy);
      va_end (args);
    
      return *str && number && fnumber;
    }
    '
    
    # Test code for whether the C compiler supports C99 (body of main).
    ac_c_conftest_c99_main='
      // Check bool.
      _Bool success = false;
      success |= (argc != 0);
    
      // Check restrict.
      if (test_restrict ("String literal") == 0)
        success = true;
      char *restrict newvar = "Another string";
    
      // Check varargs.
      success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
      test_varargs_macros ();
    
      // Check flexible array members.
      struct incomplete_array *ia =
        malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
      ia->datasize = 10;
      for (int i = 0; i < ia->datasize; ++i)
        ia->data[i] = i * 1.234;
    
      // Check named initializers.
      struct named_init ni = {
        .number = 34,
        .name = L"Test wide string",
        .average = 543.34343,
      };
    
      ni.number = 58;
    
      int dynamic_array[ni.number];
      dynamic_array[0] = argv[0][0];
      dynamic_array[ni.number - 1] = 543;
    
      // work around unused variable warnings
      ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
    	 || dynamic_array[ni.number - 1] != 543);
    '
    
    # Test code for whether the C compiler supports C11 (global declarations)
    ac_c_conftest_c11_globals='
    // Does the compiler advertise C11 conformance?
    #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
    # error "Compiler does not advertise C11 conformance"
    #endif
    
    // Check _Alignas.
    char _Alignas (double) aligned_as_double;
    char _Alignas (0) no_special_alignment;
    extern char aligned_as_int;
    char _Alignas (0) _Alignas (int) aligned_as_int;
    
    // Check _Alignof.
    enum
    {
      int_alignment = _Alignof (int),
      int_array_alignment = _Alignof (int[100]),
      char_alignment = _Alignof (char)
    };
    _Static_assert (0 < -_Alignof (int), "_Alignof is signed");
    
    // Check _Noreturn.
    int _Noreturn does_not_return (void) { for (;;) continue; }
    
    // Check _Static_assert.
    struct test_static_assert
    {
      int x;
      _Static_assert (sizeof (int) <= sizeof (long int),
                      "_Static_assert does not work in struct");
      long int y;
    };
    
    // Check UTF-8 literals.
    #define u8 syntax error!
    char const utf8_literal[] = u8"happens to be ASCII" "another string";
    
    // Check duplicate typedefs.
    typedef long *long_ptr;
    typedef long int *long_ptr;
    typedef long_ptr long_ptr;
    
    // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
    struct anonymous
    {
      union {
        struct { int i; int j; };
        struct { int k; long int l; } w;
      };
      int m;
    } v1;
    '
    
    # Test code for whether the C compiler supports C11 (body of main).
    ac_c_conftest_c11_main='
      _Static_assert ((offsetof (struct anonymous, i)
    		   == offsetof (struct anonymous, w.k)),
    		  "Anonymous union alignment botch");
      v1.i = 2;
      v1.w.k = 5;
      ok |= v1.i != 5;
    '
    
    # Test code for whether the C compiler supports C11 (complete).
    ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
    ${ac_c_conftest_c99_globals}
    ${ac_c_conftest_c11_globals}
    
    int
    main (int argc, char **argv)
    {
      int ok = 0;
      ${ac_c_conftest_c89_main}
      ${ac_c_conftest_c99_main}
      ${ac_c_conftest_c11_main}
      return ok;
    }
    "
    
    # Test code for whether the C compiler supports C99 (complete).
    ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
    ${ac_c_conftest_c99_globals}
    
    int
    main (int argc, char **argv)
    {
      int ok = 0;
      ${ac_c_conftest_c89_main}
      ${ac_c_conftest_c99_main}
      return ok;
    }
    "
    
    # Test code for whether the C compiler supports C89 (complete).
    ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
    
    int
    main (int argc, char **argv)
    {
      int ok = 0;
      ${ac_c_conftest_c89_main}
      return ok;
    }
    "
    
    as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
    as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
    as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
    as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
    as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
    as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
    as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
    as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
    as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
    as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H"
    as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H"
    
    # Auxiliary files required by this configure script.
    ac_aux_files="config.guess config.sub"
    
    # Locations in which to look for auxiliary files.
    ac_aux_dir_candidates="${srcdir}/build"
    
    # Search for a directory containing all of the required auxiliary files,
    # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates.
    # If we don't find one directory that contains all the files we need,
    # we report the set of missing files from the *first* directory in
    # $ac_aux_dir_candidates and give up.
    ac_missing_aux_files=""
    ac_first_candidate=:
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    as_found=false
    for as_dir in $ac_aux_dir_candidates
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
      as_found=:
    
      printf "%s\n" "$as_me:${as_lineno-$LINENO}:  trying $as_dir" >&5
      ac_aux_dir_found=yes
      ac_install_sh=
      for ac_aux in $ac_aux_files
      do
        # As a special case, if "install-sh" is required, that requirement
        # can be satisfied by any of "install-sh", "install.sh", or "shtool",
        # and $ac_install_sh is set appropriately for whichever one is found.
        if test x"$ac_aux" = x"install-sh"
        then
          if test -f "${as_dir}install-sh"; then
            printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install-sh found" >&5
            ac_install_sh="${as_dir}install-sh -c"
          elif test -f "${as_dir}install.sh"; then
            printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install.sh found" >&5
            ac_install_sh="${as_dir}install.sh -c"
          elif test -f "${as_dir}shtool"; then
            printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}shtool found" >&5
            ac_install_sh="${as_dir}shtool install -c"
          else
            ac_aux_dir_found=no
            if $ac_first_candidate; then
              ac_missing_aux_files="${ac_missing_aux_files} install-sh"
            else
              break
            fi
          fi
        else
          if test -f "${as_dir}${ac_aux}"; then
            printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}${ac_aux} found" >&5
          else
            ac_aux_dir_found=no
            if $ac_first_candidate; then
              ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}"
            else
              break
            fi
          fi
        fi
      done
      if test "$ac_aux_dir_found" = yes; then
        ac_aux_dir="$as_dir"
        break
      fi
      ac_first_candidate=false
    
      as_found=false
    done
    IFS=$as_save_IFS
    if $as_found
    then :
    
    else $as_nop
      as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5
    fi
    
    
    # These three variables are undocumented and unsupported,
    # and are intended to be withdrawn in a future Autoconf release.
    # They can cause serious problems if a builder's source tree is in a directory
    # whose full name contains unusual characters.
    if test -f "${ac_aux_dir}config.guess"; then
      ac_config_guess="$SHELL ${ac_aux_dir}config.guess"
    fi
    if test -f "${ac_aux_dir}config.sub"; then
      ac_config_sub="$SHELL ${ac_aux_dir}config.sub"
    fi
    if test -f "$ac_aux_dir/configure"; then
      ac_configure="$SHELL ${ac_aux_dir}configure"
    fi
    
    # Check that the precious variables saved in the cache have kept the same
    # value.
    ac_cache_corrupted=false
    for ac_var in $ac_precious_vars; do
      eval ac_old_set=\$ac_cv_env_${ac_var}_set
      eval ac_new_set=\$ac_env_${ac_var}_set
      eval ac_old_val=\$ac_cv_env_${ac_var}_value
      eval ac_new_val=\$ac_env_${ac_var}_value
      case $ac_old_set,$ac_new_set in
        set,)
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
    printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
          ac_cache_corrupted=: ;;
        ,set)
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
    printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
          ac_cache_corrupted=: ;;
        ,);;
        *)
          if test "x$ac_old_val" != "x$ac_new_val"; then
    	# differences in whitespace do not lead to failure.
    	ac_old_val_w=`echo x $ac_old_val`
    	ac_new_val_w=`echo x $ac_new_val`
    	if test "$ac_old_val_w" != "$ac_new_val_w"; then
    	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
    printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
    	  ac_cache_corrupted=:
    	else
    	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
    printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
    	  eval $ac_var=\$ac_old_val
    	fi
    	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
    printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
    	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
    printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
          fi;;
      esac
      # Pass precious variables to config.status.
      if test "$ac_new_set" = set; then
        case $ac_new_val in
        *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
        *) ac_arg=$ac_var=$ac_new_val ;;
        esac
        case " $ac_configure_args " in
          *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
          *) as_fn_append ac_configure_args " '$ac_arg'" ;;
        esac
      fi
    done
    if $ac_cache_corrupted; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
    printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
      as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
    	    and start over" "$LINENO" 5
    fi
    ## -------------------- ##
    ## Main body of script. ##
    ## -------------------- ##
    
    ac_ext=c
    ac_cpp='$CPP $CPPFLAGS'
    ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
    ac_compiler_gnu=$ac_cv_c_compiler_gnu
    
    
    
    ac_config_headers="$ac_config_headers include/ap_config_auto.h"
    
    
    
    abs_srcdir=`(cd $srcdir && pwd)`
    abs_builddir=`pwd`
    
    HTTPD_VERSION=`$abs_srcdir/build/get-version.sh all $abs_srcdir/include/ap_release.h AP_SERVER`
    HTTPD_MMN=`$abs_srcdir/build/get-version.sh mmn $abs_srcdir/include/ap_mmn.h MODULE_MAGIC_NUMBER`
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    # Check whether --enable-layout was given.
    if test ${enable_layout+y}
    then :
      enableval=$enable_layout;
      LAYOUT=$enableval
    
    fi
    
    
    if test -z "$LAYOUT"; then
      LAYOUT="Apache"
    fi
    
      if test ! -f $srcdir/config.layout; then
        echo "** Error: Layout file $srcdir/config.layout not found"
        echo "** Error: Cannot use undefined layout '$LAYOUT'"
        exit 1
      fi
      # Catch layout names including a slash which will otherwise
      # confuse the heck out of the sed script.
      case $LAYOUT in
      */*)
        echo "** Error: $LAYOUT is not a valid layout name"
        exit 1 ;;
      esac
      pldconf=./config.pld
    
      sed -e "1s/[ 	]*<[lL]ayout[ 	]*$LAYOUT[ 	]*>[ 	]*//;1t" \
          -e "1,/[ 	]*<[lL]ayout[ 	]*$LAYOUT[ 	]*>[ 	]*/d" \
          -e '/[ 	]*<\/Layout>[ 	]*/,$d' \
          -e "s/^[ 	]*//g" \
          -e "s/:[ 	]*/=\'/g" \
          -e "s/[ 	]*$/'/g" \
          $srcdir/config.layout > $pldconf
      layout_name=$LAYOUT
      if test ! -s $pldconf; then
        echo "** Error: unable to find layout $layout_name"
        exit 1
      fi
      . $pldconf
      rm $pldconf
      for var in prefix exec_prefix bindir sbindir libexecdir mandir \
                 sysconfdir datadir includedir localstatedir runtimedir \
                 logfiledir libdir installbuilddir libsuffix errordir iconsdir htdocsdir cgidir; do
        eval "val=\"\$$var\""
        case $val in
          *+)
            val=`echo $val | sed -e 's;\+$;;'`
            eval "$var=\"\$val\""
            autosuffix=yes
            ;;
          *)
            autosuffix=no
            ;;
        esac
        val=`echo $val | sed -e 's:\(.\)/*$:\1:'`
        val=`echo $val | sed -e 's:[\$]\([a-z_]*\):$\1:g'`
        if test "$autosuffix" = "yes"; then
          if echo $val | grep apache >/dev/null; then
            addtarget=no
          else
            addtarget=yes
          fi
          if test "$addtarget" = "yes"; then
            val="$val/apache2"
          fi
        fi
        eval "$var='$val'"
      done
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for chosen layout" >&5
    printf %s "checking for chosen layout... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $layout_name" >&5
    printf "%s\n" "$layout_name" >&6; }
    
    
    
    ac_prev=
    # Retrieve the command-line arguments.  The eval is needed because
    # the arguments are quoted to preserve accuracy.
    eval "set x $ac_configure_args"
    shift
    for ac_option
    do
      # If the previous option needs an argument, assign it.
      if test -n "$ac_prev"; then
        eval "$ac_prev=\$ac_option"
        ac_prev=
        continue
      fi
    
      ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
    
      case $ac_option in
    
      -bindir | --bindir | --bindi | --bind | --bin | --bi)
        ac_prev=bindir ;;
      -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
        bindir="$ac_optarg" ;;
    
      -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
        ac_prev=datadir ;;
      -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
      | --da=*)
        datadir="$ac_optarg" ;;
    
      -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
      | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
      | --exec | --exe | --ex)
        ac_prev=exec_prefix ;;
      -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
      | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
      | --exec=* | --exe=* | --ex=*)
        exec_prefix="$ac_optarg" ;;
    
      -includedir | --includedir | --includedi | --included | --include \
      | --includ | --inclu | --incl | --inc)
        ac_prev=includedir ;;
      -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
      | --includ=* | --inclu=* | --incl=* | --inc=*)
        includedir="$ac_optarg" ;;
    
      -infodir | --infodir | --infodi | --infod | --info | --inf)
        ac_prev=infodir ;;
      -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
        infodir="$ac_optarg" ;;
    
      -libdir | --libdir | --libdi | --libd)
        ac_prev=libdir ;;
      -libdir=* | --libdir=* | --libdi=* | --libd=*)
        libdir="$ac_optarg" ;;
    
      -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
      | --libexe | --libex | --libe)
        ac_prev=libexecdir ;;
      -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
      | --libexe=* | --libex=* | --libe=*)
        libexecdir="$ac_optarg" ;;
    
      -localstatedir | --localstatedir | --localstatedi | --localstated \
      | --localstate | --localstat | --localsta | --localst \
      | --locals | --local | --loca | --loc | --lo)
        ac_prev=localstatedir ;;
      -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
      | --localstate=* | --localstat=* | --localsta=* | --localst=* \
      | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
        localstatedir="$ac_optarg" ;;
    
      -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
        ac_prev=mandir ;;
      -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
        mandir="$ac_optarg" ;;
    
      -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
        ac_prev=prefix ;;
      -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
        prefix="$ac_optarg" ;;
    
      -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
        ac_prev=sbindir ;;
      -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
      | --sbi=* | --sb=*)
        sbindir="$ac_optarg" ;;
    
      -sharedstatedir | --sharedstatedir | --sharedstatedi \
      | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
      | --sharedst | --shareds | --shared | --share | --shar \
      | --sha | --sh)
        ac_prev=sharedstatedir ;;
      -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
      | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
      | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
      | --sha=* | --sh=*)
        sharedstatedir="$ac_optarg" ;;
    
      -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
      | --syscon | --sysco | --sysc | --sys | --sy)
        ac_prev=sysconfdir ;;
      -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
      | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
        sysconfdir="$ac_optarg" ;;
    
      esac
    done
    
    # Be sure to have absolute paths.
    for ac_var in exec_prefix prefix
    do
      eval ac_val=$`echo $ac_var`
      case $ac_val in
        [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
        *)  as_fn_error $? "expected an absolute path for --$ac_var: $ac_val" "$LINENO" 5;;
      esac
    done
    
    
    
    
    
    
    ap_last=
    ap_cur="$exec_prefix"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_exec_prefix="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_exec_prefix"
    
    
    
    ap_stripped=`echo $exp_exec_prefix | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_exec_prefix" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_exec_prefix="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_exec_prefix="$exp_exec_prefix"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_exec_prefix"
    
    
    
    
    
    ap_last=
    ap_cur="$bindir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_bindir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_bindir"
    
    
    
    ap_stripped=`echo $exp_bindir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_bindir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_bindir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_bindir="$exp_bindir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_bindir"
    
    
    
    
    
    ap_last=
    ap_cur="$sbindir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_sbindir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_sbindir"
    
    
    
    ap_stripped=`echo $exp_sbindir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_sbindir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_sbindir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_sbindir="$exp_sbindir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_sbindir"
    
    
    
    
    
    ap_last=
    ap_cur="$libdir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_libdir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_libdir"
    
    
    
    ap_stripped=`echo $exp_libdir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_libdir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_libdir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_libdir="$exp_libdir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_libdir"
    
    
    
    
    
    ap_last=
    ap_cur="$libexecdir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_libexecdir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_libexecdir"
    
    
    
    ap_stripped=`echo $exp_libexecdir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_libexecdir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_libexecdir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_libexecdir="$exp_libexecdir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_libexecdir"
    
    
    
    
    
    ap_last=
    ap_cur="$mandir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_mandir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_mandir"
    
    
    
    ap_stripped=`echo $exp_mandir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_mandir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_mandir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_mandir="$exp_mandir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_mandir"
    
    
    
    
    
    ap_last=
    ap_cur="$sysconfdir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_sysconfdir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_sysconfdir"
    
    
    
    ap_stripped=`echo $exp_sysconfdir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_sysconfdir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_sysconfdir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_sysconfdir="$exp_sysconfdir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_sysconfdir"
    
    
    
    
    
    ap_last=
    ap_cur="$datadir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_datadir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_datadir"
    
    
    
    ap_stripped=`echo $exp_datadir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_datadir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_datadir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_datadir="$exp_datadir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_datadir"
    
    
    
    
    
    ap_last=
    ap_cur="$installbuilddir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_installbuilddir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_installbuilddir"
    
    
    
    ap_stripped=`echo $exp_installbuilddir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_installbuilddir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_installbuilddir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_installbuilddir="$exp_installbuilddir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_installbuilddir"
    
    
    
    
    
    ap_last=
    ap_cur="$errordir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_errordir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_errordir"
    
    
    
    ap_stripped=`echo $exp_errordir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_errordir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_errordir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_errordir="$exp_errordir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_errordir"
    
    
    
    
    
    ap_last=
    ap_cur="$iconsdir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_iconsdir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_iconsdir"
    
    
    
    ap_stripped=`echo $exp_iconsdir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_iconsdir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_iconsdir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_iconsdir="$exp_iconsdir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_iconsdir"
    
    
    
    
    
    ap_last=
    ap_cur="$htdocsdir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_htdocsdir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_htdocsdir"
    
    
    
    ap_stripped=`echo $exp_htdocsdir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_htdocsdir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_htdocsdir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_htdocsdir="$exp_htdocsdir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_htdocsdir"
    
    
    
    
    
    ap_last=
    ap_cur="$manualdir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_manualdir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_manualdir"
    
    
    
    ap_stripped=`echo $exp_manualdir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_manualdir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_manualdir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_manualdir="$exp_manualdir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_manualdir"
    
    
    
    
    
    ap_last=
    ap_cur="$cgidir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_cgidir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_cgidir"
    
    
    
    ap_stripped=`echo $exp_cgidir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_cgidir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_cgidir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_cgidir="$exp_cgidir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_cgidir"
    
    
    
    
    
    ap_last=
    ap_cur="$includedir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_includedir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_includedir"
    
    
    
    ap_stripped=`echo $exp_includedir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_includedir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_includedir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_includedir="$exp_includedir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_includedir"
    
    
    
    
    
    ap_last=
    ap_cur="$localstatedir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_localstatedir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_localstatedir"
    
    
    
    ap_stripped=`echo $exp_localstatedir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_localstatedir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_localstatedir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_localstatedir="$exp_localstatedir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_localstatedir"
    
    
    
    
    
    ap_last=
    ap_cur="$runtimedir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_runtimedir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_runtimedir"
    
    
    
    ap_stripped=`echo $exp_runtimedir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_runtimedir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_runtimedir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_runtimedir="$exp_runtimedir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_runtimedir"
    
    
    
    
    
    ap_last=
    ap_cur="$logfiledir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_logfiledir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_logfiledir"
    
    
    
    ap_stripped=`echo $exp_logfiledir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_logfiledir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_logfiledir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_logfiledir="$exp_logfiledir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_logfiledir"
    
    
    
    
    
    ap_last=
    ap_cur="$proxycachedir"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    exp_proxycachedir="${ap_cur}"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exp_proxycachedir"
    
    
    
    ap_stripped=`echo $exp_proxycachedir | sed -e "s#^${prefix}##"`
    # check if the stripping was successful
    if test "x$exp_proxycachedir" != "x${ap_stripped}"; then
        # it was, so strip of any leading slashes
        rel_proxycachedir="`echo ${ap_stripped} | sed -e 's#^/*##'`"
    else
        # it wasn't so return the original
        rel_proxycachedir="$exp_proxycachedir"
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rel_proxycachedir"
    
    
    
    
    
    
      apr_ste_save_CPPFLAGS="$CPPFLAGS"
    
    
      apr_ste_save_CFLAGS="$CFLAGS"
    
    
      apr_ste_save_CXXFLAGS="$CXXFLAGS"
    
    
      apr_ste_save_LDFLAGS="$LDFLAGS"
    
    
      apr_ste_save_LIBS="$LIBS"
    
    
      apr_ste_save_INCLUDES="$INCLUDES"
    
    
    
      rm -f config.nice
      cat >config.nice<<EOF
    #! /bin/sh
    #
    # Created by configure
    
    EOF
      if test -n "$CC"; then
        echo "CC=\"$CC\"; export CC" >> config.nice
      fi
      if test -n "$CFLAGS"; then
        echo "CFLAGS=\"$CFLAGS\"; export CFLAGS" >> config.nice
      fi
      if test -n "$CPPFLAGS"; then
        echo "CPPFLAGS=\"$CPPFLAGS\"; export CPPFLAGS" >> config.nice
      fi
      if test -n "$LDFLAGS"; then
        echo "LDFLAGS=\"$LDFLAGS\"; export LDFLAGS" >> config.nice
      fi
      if test -n "$LTFLAGS"; then
        echo "LTFLAGS=\"$LTFLAGS\"; export LTFLAGS" >> config.nice
      fi
      if test -n "$LIBS"; then
        echo "LIBS=\"$LIBS\"; export LIBS" >> config.nice
      fi
      if test -n "$INCLUDES"; then
        echo "INCLUDES=\"$INCLUDES\"; export INCLUDES" >> config.nice
      fi
      if test -n "$NOTEST_CFLAGS"; then
        echo "NOTEST_CFLAGS=\"$NOTEST_CFLAGS\"; export NOTEST_CFLAGS" >> config.nice
      fi
      if test -n "$NOTEST_CPPFLAGS"; then
        echo "NOTEST_CPPFLAGS=\"$NOTEST_CPPFLAGS\"; export NOTEST_CPPFLAGS" >> config.nice
      fi
      if test -n "$NOTEST_LDFLAGS"; then
        echo "NOTEST_LDFLAGS=\"$NOTEST_LDFLAGS\"; export NOTEST_LDFLAGS" >> config.nice
      fi
      if test -n "$NOTEST_LIBS"; then
        echo "NOTEST_LIBS=\"$NOTEST_LIBS\"; export NOTEST_LIBS" >> config.nice
      fi
    
      # Retrieve command-line arguments.
      eval "set x $0 $ac_configure_args"
      shift
    
      for arg
      do
    
    ap_last=
    ap_cur="$arg"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    arg="${ap_cur}"
    
        echo "\"$arg\" \\" >> config.nice
      done
      echo '"$@"' >> config.nice
      chmod +x config.nice
    
    
    nl='
    '
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working mkdir -p" >&5
    printf %s "checking for working mkdir -p... " >&6; }
    if test ${ac_cv_mkdir_p+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
        test -d conftestdir && rm -rf conftestdir
        mkdir -p conftestdir/somedir >/dev/null 2>&1
        if test -d conftestdir/somedir; then
          ac_cv_mkdir_p=yes
        else
          ac_cv_mkdir_p=no
        fi
        rm -rf conftestdir
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mkdir_p" >&5
    printf "%s\n" "$ac_cv_mkdir_p" >&6; }
      if test "$ac_cv_mkdir_p" = "yes"; then
          mkdir_p="mkdir -p"
      else
          mkdir_p="$top_srcdir/build/mkdir.sh"
      fi
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
    printf %s "checking for grep that handles long lines and -e... " >&6; }
    if test ${ac_cv_path_GREP+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -z "$GREP"; then
      ac_path_GREP_found=false
      # Loop through the user's path and test for each of PROGNAME-LIST
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_prog in grep ggrep
       do
        for ac_exec_ext in '' $ac_executable_extensions; do
          ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"
          as_fn_executable_p "$ac_path_GREP" || continue
    # Check for GNU ac_path_GREP and select it if it is found.
      # Check for GNU $ac_path_GREP
    case `"$ac_path_GREP" --version 2>&1` in
    *GNU*)
      ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
    *)
      ac_count=0
      printf %s 0123456789 >"conftest.in"
      while :
      do
        cat "conftest.in" "conftest.in" >"conftest.tmp"
        mv "conftest.tmp" "conftest.in"
        cp "conftest.in" "conftest.nl"
        printf "%s\n" 'GREP' >> "conftest.nl"
        "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
        diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
        as_fn_arith $ac_count + 1 && ac_count=$as_val
        if test $ac_count -gt ${ac_path_GREP_max-0}; then
          # Best one so far, save it but keep looking for a better one
          ac_cv_path_GREP="$ac_path_GREP"
          ac_path_GREP_max=$ac_count
        fi
        # 10*(2^10) chars as input seems more than enough
        test $ac_count -gt 10 && break
      done
      rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
    esac
    
          $ac_path_GREP_found && break 3
        done
      done
      done
    IFS=$as_save_IFS
      if test -z "$ac_cv_path_GREP"; then
        as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
      fi
    else
      ac_cv_path_GREP=$GREP
    fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
    printf "%s\n" "$ac_cv_path_GREP" >&6; }
     GREP="$ac_cv_path_GREP"
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
    printf %s "checking for egrep... " >&6; }
    if test ${ac_cv_path_EGREP+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
       then ac_cv_path_EGREP="$GREP -E"
       else
         if test -z "$EGREP"; then
      ac_path_EGREP_found=false
      # Loop through the user's path and test for each of PROGNAME-LIST
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_prog in egrep
       do
        for ac_exec_ext in '' $ac_executable_extensions; do
          ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"
          as_fn_executable_p "$ac_path_EGREP" || continue
    # Check for GNU ac_path_EGREP and select it if it is found.
      # Check for GNU $ac_path_EGREP
    case `"$ac_path_EGREP" --version 2>&1` in
    *GNU*)
      ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
    *)
      ac_count=0
      printf %s 0123456789 >"conftest.in"
      while :
      do
        cat "conftest.in" "conftest.in" >"conftest.tmp"
        mv "conftest.tmp" "conftest.in"
        cp "conftest.in" "conftest.nl"
        printf "%s\n" 'EGREP' >> "conftest.nl"
        "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
        diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
        as_fn_arith $ac_count + 1 && ac_count=$as_val
        if test $ac_count -gt ${ac_path_EGREP_max-0}; then
          # Best one so far, save it but keep looking for a better one
          ac_cv_path_EGREP="$ac_path_EGREP"
          ac_path_EGREP_max=$ac_count
        fi
        # 10*(2^10) chars as input seems more than enough
        test $ac_count -gt 10 && break
      done
      rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
    esac
    
          $ac_path_EGREP_found && break 3
        done
      done
      done
    IFS=$as_save_IFS
      if test -z "$ac_cv_path_EGREP"; then
        as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
      fi
    else
      ac_cv_path_EGREP=$EGREP
    fi
    
       fi
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
    printf "%s\n" "$ac_cv_path_EGREP" >&6; }
     EGREP="$ac_cv_path_EGREP"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST EGREP"
    
    
    
    
    
    
    
    
      # Make sure we can run config.sub.
    $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 ||
      as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
    printf %s "checking build system type... " >&6; }
    if test ${ac_cv_build+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_build_alias=$build_alias
    test "x$ac_build_alias" = x &&
      ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"`
    test "x$ac_build_alias" = x &&
      as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
    ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` ||
      as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
    printf "%s\n" "$ac_cv_build" >&6; }
    case $ac_cv_build in
    *-*-*) ;;
    *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
    esac
    build=$ac_cv_build
    ac_save_IFS=$IFS; IFS='-'
    set x $ac_cv_build
    shift
    build_cpu=$1
    build_vendor=$2
    shift; shift
    # Remember, the first character of IFS is used to create $*,
    # except with old shells:
    build_os=$*
    IFS=$ac_save_IFS
    case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
    printf %s "checking host system type... " >&6; }
    if test ${ac_cv_host+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test "x$host_alias" = x; then
      ac_cv_host=$ac_cv_build
    else
      ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` ||
        as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5
    fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
    printf "%s\n" "$ac_cv_host" >&6; }
    case $ac_cv_host in
    *-*-*) ;;
    *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
    esac
    host=$ac_cv_host
    ac_save_IFS=$IFS; IFS='-'
    set x $ac_cv_host
    shift
    host_cpu=$1
    host_vendor=$2
    shift; shift
    # Remember, the first character of IFS is used to create $*,
    # except with old shells:
    host_os=$*
    IFS=$ac_save_IFS
    case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
    printf %s "checking target system type... " >&6; }
    if test ${ac_cv_target+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test "x$target_alias" = x; then
      ac_cv_target=$ac_cv_host
    else
      ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` ||
        as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5
    fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
    printf "%s\n" "$ac_cv_target" >&6; }
    case $ac_cv_target in
    *-*-*) ;;
    *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
    esac
    target=$ac_cv_target
    ac_save_IFS=$IFS; IFS='-'
    set x $ac_cv_target
    shift
    target_cpu=$1
    target_vendor=$2
    shift; shift
    # Remember, the first character of IFS is used to create $*,
    # except with old shells:
    target_os=$*
    IFS=$ac_save_IFS
    case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
    
    
    # The aliases save the names the user supplied, while $host etc.
    # will get canonicalized.
    test -n "$target_alias" &&
      test "$program_prefix$program_suffix$program_transform_name" = \
        NONENONEs,x,x, &&
      program_prefix=${target_alias}-
    
    
    orig_prefix="$prefix"
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuring Apache Portable Runtime library..." >&5
    printf "%s\n" "$as_me: Configuring Apache Portable Runtime library..." >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    
    
    # Check whether --with-included-apr was given.
    if test ${with_included_apr+y}
    then :
      withval=$with_included_apr;
    fi
    
    
    if test "x$with_included_apr" = "xyes"; then
      apr_found=reconfig
      if test ! -d srclib/apr && test ! -d $srcdir/srclib/apr; then
        as_fn_error $? "Bundled APR requested but not found at ./srclib/. Download and unpack the corresponding apr and apr-util packages to ./srclib/." "$LINENO" 5
      fi
    else
    
      apr_found="no"
    
      if test "$target_os" = "os2-emx"; then
        # Scripts don't pass test -x on OS/2
        TEST_X="test -f"
      else
        TEST_X="test -x"
      fi
    
      acceptable_majors="1 2"
    
      apr_temp_acceptable_apr_config=""
      for apr_temp_major in $acceptable_majors
      do
        case $apr_temp_major in
          0)
          apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-config"
          ;;
          *)
          apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-$apr_temp_major-config"
          ;;
        esac
      done
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for APR" >&5
    printf %s "checking for APR... " >&6; }
    
    # Check whether --with-apr was given.
    if test ${with_apr+y}
    then :
      withval=$with_apr;
        if test "$withval" = "no" || test "$withval" = "yes"; then
          as_fn_error $? "--with-apr requires a directory or file to be provided" "$LINENO" 5
        fi
    
        for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config
        do
          for lookdir in "$withval/bin" "$withval"
          do
            if $TEST_X "$lookdir/$apr_temp_apr_config_file"; then
              apr_config="$lookdir/$apr_temp_apr_config_file"
    
              apr_acceptable="yes"
    
        version=`$apr_config --version`
        case x${version} in
        x1.[0-3].*)
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: APR version 1.4.0 or later is required, found $version" >&5
    printf "%s\n" "$as_me: WARNING: APR version 1.4.0 or later is required, found $version" >&2;}
          apr_acceptable=no
          ;;
        esac
        unset version
    
              if test "$apr_acceptable" != "yes"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Found APR in $apr_config, but we think it is considered unacceptable" >&5
    printf "%s\n" "$as_me: WARNING: Found APR in $apr_config, but we think it is considered unacceptable" >&2;}
                continue
              fi
              apr_found="yes"
              break 2
            fi
          done
        done
    
        if test "$apr_found" != "yes" && $TEST_X "$withval" && $withval --help > /dev/null 2>&1 ; then
          apr_config="$withval"
    
              apr_acceptable="yes"
    
        version=`$apr_config --version`
        case x${version} in
        x1.[0-3].*)
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: APR version 1.4.0 or later is required, found $version" >&5
    printf "%s\n" "$as_me: WARNING: APR version 1.4.0 or later is required, found $version" >&2;}
          apr_acceptable=no
          ;;
        esac
        unset version
    
              if test "$apr_acceptable" = "yes"; then
                    apr_found="yes"
              fi
        fi
    
                if test "$apr_found" != "yes"; then
          as_fn_error $? "the --with-apr parameter is incorrect. It must specify an install prefix, a build directory, or an apr-config file." "$LINENO" 5
        fi
    
    else $as_nop
    
            if test -n "1" && test "1" = "1"; then
          for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config
          do
            if $apr_temp_apr_config_file --help > /dev/null 2>&1 ; then
              apr_config="$apr_temp_apr_config_file"
    
              apr_acceptable="yes"
    
        version=`$apr_config --version`
        case x${version} in
        x1.[0-3].*)
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: APR version 1.4.0 or later is required, found $version" >&5
    printf "%s\n" "$as_me: WARNING: APR version 1.4.0 or later is required, found $version" >&2;}
          apr_acceptable=no
          ;;
        esac
        unset version
    
              if test "$apr_acceptable" != "yes"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: skipped APR at $apr_config, version not acceptable" >&5
    printf "%s\n" "$as_me: WARNING: skipped APR at $apr_config, version not acceptable" >&2;}
                continue
              fi
              apr_found="yes"
              break
            else
                        for lookdir in /usr /usr/local /usr/local/apr /opt/apr; do
                if $TEST_X "$lookdir/bin/$apr_temp_apr_config_file"; then
                  apr_config="$lookdir/bin/$apr_temp_apr_config_file"
    
                  apr_acceptable="yes"
    
        version=`$apr_config --version`
        case x${version} in
        x1.[0-3].*)
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: APR version 1.4.0 or later is required, found $version" >&5
    printf "%s\n" "$as_me: WARNING: APR version 1.4.0 or later is required, found $version" >&2;}
          apr_acceptable=no
          ;;
        esac
        unset version
    
                  if test "$apr_acceptable" != "yes"; then
                    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: skipped APR at $apr_config, version not acceptable" >&5
    printf "%s\n" "$as_me: WARNING: skipped APR at $apr_config, version not acceptable" >&2;}
                    continue
                  fi
                  apr_found="yes"
                  break 2
                fi
              done
            fi
          done
        fi
            if test "$apr_found" = "no" && test -d ""$srcdir/srclib/apr""; then
          apr_temp_abs_srcdir="`cd \""$srcdir/srclib/apr"\" && pwd`"
          apr_found="reconfig"
          apr_bundled_major="`sed -n '/#define.*APR_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \""$srcdir/srclib/apr"/include/apr_version.h\"`"
          case $apr_bundled_major in
            "")
              as_fn_error $? "failed to find major version of bundled APR" "$LINENO" 5
            ;;
            0)
              apr_temp_apr_config_file="apr-config"
            ;;
            *)
              apr_temp_apr_config_file="apr-$apr_bundled_major-config"
            ;;
          esac
          if test -n ""./srclib/apr""; then
            apr_config=""./srclib/apr"/$apr_temp_apr_config_file"
          else
            apr_config=""$srcdir/srclib/apr"/$apr_temp_apr_config_file"
          fi
        fi
    
    fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $apr_found" >&5
    printf "%s\n" "$apr_found" >&6; }
    
    fi
    
    if test "$apr_found" = "no"; then
      as_fn_error $? "APR not found.  Please read the documentation." "$LINENO" 5
    fi
    
    if test "$apr_found" = "reconfig"; then
    
      # save our work to this point; this allows the sub-package to use it
      cat >confcache <<\_ACEOF
    # This file is a shell script that caches the results of configure
    # tests run on this system so they can be shared between configure
    # scripts and configure runs, see configure's option --config-cache.
    # It is not useful on other systems.  If it contains results you don't
    # want to keep, you may remove or edit it.
    #
    # config.status only pays attention to the cache file if you give it
    # the --recheck option to rerun configure.
    #
    # `ac_cv_env_foo' variables (set or unset) will be overridden when
    # loading this file, other *unset* `ac_cv_foo' will be assigned the
    # following values.
    
    _ACEOF
    
    # The following way of writing the cache mishandles newlines in values,
    # but we know of no workaround that is simple, portable, and efficient.
    # So, we kill variables containing newlines.
    # Ultrix sh set writes to stderr and can't be redirected directly,
    # and sets the high bit in the cache file unless we assign to the vars.
    (
      for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
        eval ac_val=\$$ac_var
        case $ac_val in #(
        *${as_nl}*)
          case $ac_var in #(
          *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
    printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
          esac
          case $ac_var in #(
          _ | IFS | as_nl) ;; #(
          BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
          *) { eval $ac_var=; unset $ac_var;} ;;
          esac ;;
        esac
      done
    
      (set) 2>&1 |
        case $as_nl`(ac_space=' '; set) 2>&1` in #(
        *${as_nl}ac_space=\ *)
          # `set' does not quote correctly, so add quotes: double-quote
          # substitution turns \\\\ into \\, and sed turns \\ into \.
          sed -n \
    	"s/'/'\\\\''/g;
    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
          ;; #(
        *)
          # `set' quotes correctly as required by POSIX, so do not add quotes.
          sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
          ;;
        esac |
        sort
    ) |
      sed '
         /^ac_cv_env_/b end
         t clear
         :clear
         s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
         t end
         s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
         :end' >>confcache
    if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
      if test -w "$cache_file"; then
        if test "x$cache_file" != "x/dev/null"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
    printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
          if test ! -f "$cache_file" || test -h "$cache_file"; then
    	cat confcache >"$cache_file"
          else
            case $cache_file in #(
            */* | ?:*)
    	  mv -f confcache "$cache_file"$$ &&
    	  mv -f "$cache_file"$$ "$cache_file" ;; #(
            *)
    	  mv -f confcache "$cache_file" ;;
    	esac
          fi
        fi
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
    printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
      fi
    fi
    rm -f confcache
    
      echo "configuring package in srclib/apr now"
      ac_popdir=`pwd`
      apr_config_subdirs="srclib/apr"
      test -d srclib/apr || $mkdir_p srclib/apr
      ac_abs_srcdir=`(cd $srcdir/srclib/apr && pwd)`
      cd srclib/apr
    
          # A "../" for each directory in /$config_subdirs.
          ac_dots=`echo $apr_config_subdirs|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
    
      # Make the cache file pathname absolute for the subdirs
      # required to correctly handle subdirs that might actually
      # be symlinks
      case "$cache_file" in
      /*) # already absolute
        ac_sub_cache_file=$cache_file ;;
      *)  # Was relative path.
        ac_sub_cache_file="$ac_popdir/$cache_file" ;;
      esac
    
    
      apr_configure_args=
      apr_sep=
      for apr_configure_arg in $ac_configure_args
      do
        case "$apr_configure_arg" in
          --enable-layout=*|\'--enable-layout=*)
            continue ;;
        esac
        apr_configure_args="$apr_configure_args$apr_sep'$apr_configure_arg'"
        apr_sep=" "
      done
    
    
        test "x$silent" = "xyes" && apr_configure_args="$apr_configure_args --silent"
    
        apr_configure_args="--disable-option-checking $apr_configure_args"
    
                  if eval $SHELL $ac_abs_srcdir/configure $apr_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_abs_srcdir $apache_apr_flags --prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir --datadir=$datadir --with-installbuilddir=$installbuilddir
      then :
        echo "srclib/apr configured properly"
      else
        echo "configure failed for srclib/apr"
        exit 1
      fi
    
      cd $ac_popdir
    
      # grab any updates from the sub-package
      if test -r "$cache_file"; then
      # Some versions of bash will fail to source /dev/null (special files
      # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
      if test /dev/null != "$cache_file" && test -f "$cache_file"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
    printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
        case $cache_file in
          [\\/]* | ?:[\\/]* ) . "$cache_file";;
          *)                      . "./$cache_file";;
        esac
      fi
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
    printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
      >$cache_file
    fi
    
    
        AP_BUILD_SRCLIB_DIRS="apr $AP_BUILD_SRCLIB_DIRS"
      AP_CLEAN_SRCLIB_DIRS="$AP_CLEAN_SRCLIB_DIRS apr"
    
        for majorver in 1 2; do
        test_apr_config="./srclib/apr/apr-${majorver}-config"
        if test -f "$test_apr_config"; then
          apr_config="$test_apr_config"
        fi
      done
    fi
    
    
      if test -z "$CC"; then
        test "x$silent" != "xyes" && echo "  setting CC to \"`$apr_config --cc`\""
        CC="`$apr_config --cc`"
      fi
    
    
      if test -z "$CPP"; then
        test "x$silent" != "xyes" && echo "  setting CPP to \"`$apr_config --cpp`\""
        CPP="`$apr_config --cpp`"
      fi
    
    
      if test "x$CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CFLAGS to \"`$apr_config --cflags`\""
        CFLAGS="`$apr_config --cflags`"
      else
        apr_addto_bugger="`$apr_config --cflags`"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CFLAGS"
            CFLAGS="$CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"`$apr_config --cppflags`\""
        CPPFLAGS="`$apr_config --cppflags`"
      else
        apr_addto_bugger="`$apr_config --cppflags`"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    INTERNAL_CPPFLAGS=""
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"`$apr_config --ldflags`\""
        LDFLAGS="`$apr_config --ldflags`"
      else
        apr_addto_bugger="`$apr_config --ldflags`"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    SHLIBPATH_VAR=`$apr_config --shlib-path-var`
    APR_BINDIR=`$apr_config --bindir`
    APR_INCLUDEDIR=`$apr_config --includedir`
    APR_INCLUDES=`$apr_config --includes`
    APR_VERSION=`$apr_config --version`
    apr_major_version=`echo ${APR_VERSION} | sed 's,\..*,,'`
    APR_CONFIG="$APR_BINDIR/apr-${apr_major_version}-config"
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuring Apache Portable Runtime Utility library..." >&5
    printf "%s\n" "$as_me: Configuring Apache Portable Runtime Utility library..." >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    
    if test "x${apr_major_version}" = "x2"; then
      apu_found=obsolete
    elif test "x$with_included_apr" = "xyes"; then
      apu_found=reconfig
      if test ! -d srclib/apr-util && test ! -d $srcdir/srclib/apr-util; then
        as_fn_error $? "Bundled APR-Util requested but not found at ./srclib/. Download and unpack the corresponding apr and apr-util packages to ./srclib/." "$LINENO" 5
      fi
    else
    
    
      apu_found="no"
    
      if test "$target_os" = "os2-emx"; then
        # Scripts don't pass test -x on OS/2
        TEST_X="test -f"
      else
        TEST_X="test -x"
      fi
    
      acceptable_majors="${apr_major_version}"
    
      apu_temp_acceptable_apu_config=""
      for apu_temp_major in $acceptable_majors
      do
        case $apu_temp_major in
          0)
          apu_temp_acceptable_apu_config="$apu_temp_acceptable_apu_config apu-config"
          ;;
          *)
          apu_temp_acceptable_apu_config="$apu_temp_acceptable_apu_config apu-$apu_temp_major-config"
          ;;
        esac
      done
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for APR-util" >&5
    printf %s "checking for APR-util... " >&6; }
    
    # Check whether --with-apr-util was given.
    if test ${with_apr_util+y}
    then :
      withval=$with_apr_util;
        if test "$withval" = "no" || test "$withval" = "yes"; then
          as_fn_error $? "--with-apr-util requires a directory or file to be provided" "$LINENO" 5
        fi
    
        for apu_temp_apu_config_file in $apu_temp_acceptable_apu_config
        do
          for lookdir in "$withval/bin" "$withval"
          do
            if $TEST_X "$lookdir/$apu_temp_apu_config_file"; then
              apu_config="$lookdir/$apu_temp_apu_config_file"
    
              apu_found="yes"
              break 2
            fi
          done
        done
    
        if test "$apu_found" != "yes" && $TEST_X "$withval" && $withval --help > /dev/null 2>&1 ; then
          apu_config="$withval"
          apu_found="yes"
        fi
    
                if test "$apu_found" != "yes"; then
          as_fn_error $? "the --with-apr-util parameter is incorrect. It must specify an install prefix, a build directory, or an apu-config file." "$LINENO" 5
        fi
    
    else $as_nop
    
        if test -n "1" && test "1" = "1"; then
          for apu_temp_apu_config_file in $apu_temp_acceptable_apu_config
          do
            if $apu_temp_apu_config_file --help > /dev/null 2>&1 ; then
              apu_config="$apu_temp_apu_config_file"
    
              apu_found="yes"
              break
            else
                        for lookdir in /usr /usr/local /usr/local/apr /opt/apr; do
                if $TEST_X "$lookdir/bin/$apu_temp_apu_config_file"; then
                  apu_config="$lookdir/bin/$apu_temp_apu_config_file"
    
                  apu_found="yes"
                  break 2
                fi
              done
            fi
          done
        fi
            if test "$apu_found" = "no" && test -d ""$srcdir/srclib/apr-util""; then
          apu_temp_abs_srcdir="`cd \""$srcdir/srclib/apr-util"\" && pwd`"
          apu_found="reconfig"
          apu_bundled_major="`sed -n '/#define.*APU_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \""$srcdir/srclib/apr-util"/include/apu_version.h\"`"
          case $apu_bundled_major in
            "")
              as_fn_error $? "failed to find major version of bundled APU" "$LINENO" 5
            ;;
            0)
              apu_temp_apu_config_file="apu-config"
            ;;
            *)
              apu_temp_apu_config_file="apu-$apu_bundled_major-config"
            ;;
          esac
          if test -n ""./srclib/apr-util""; then
            apu_config=""./srclib/apr-util"/$apu_temp_apu_config_file"
          else
            apu_config=""$srcdir/srclib/apr-util"/$apu_temp_apu_config_file"
          fi
        fi
    
    fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $apu_found" >&5
    printf "%s\n" "$apu_found" >&6; }
    
    
    fi
    
    if test "$apu_found" = "no"; then
      as_fn_error $? "APR-util not found.  Please read the documentation." "$LINENO" 5
    fi
    
    # Catch some misconfigurations:
    case ${apr_found}.${apu_found} in
    reconfig.yes)
      as_fn_error $? "Cannot use an external APR-util with the bundled APR" "$LINENO" 5
      ;;
    yes.reconfig)
      as_fn_error $? "Cannot use an external APR with the bundled APR-util" "$LINENO" 5
      ;;
    esac
    
    if test "$apu_found" = "reconfig"; then
    
      # save our work to this point; this allows the sub-package to use it
      cat >confcache <<\_ACEOF
    # This file is a shell script that caches the results of configure
    # tests run on this system so they can be shared between configure
    # scripts and configure runs, see configure's option --config-cache.
    # It is not useful on other systems.  If it contains results you don't
    # want to keep, you may remove or edit it.
    #
    # config.status only pays attention to the cache file if you give it
    # the --recheck option to rerun configure.
    #
    # `ac_cv_env_foo' variables (set or unset) will be overridden when
    # loading this file, other *unset* `ac_cv_foo' will be assigned the
    # following values.
    
    _ACEOF
    
    # The following way of writing the cache mishandles newlines in values,
    # but we know of no workaround that is simple, portable, and efficient.
    # So, we kill variables containing newlines.
    # Ultrix sh set writes to stderr and can't be redirected directly,
    # and sets the high bit in the cache file unless we assign to the vars.
    (
      for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
        eval ac_val=\$$ac_var
        case $ac_val in #(
        *${as_nl}*)
          case $ac_var in #(
          *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
    printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
          esac
          case $ac_var in #(
          _ | IFS | as_nl) ;; #(
          BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
          *) { eval $ac_var=; unset $ac_var;} ;;
          esac ;;
        esac
      done
    
      (set) 2>&1 |
        case $as_nl`(ac_space=' '; set) 2>&1` in #(
        *${as_nl}ac_space=\ *)
          # `set' does not quote correctly, so add quotes: double-quote
          # substitution turns \\\\ into \\, and sed turns \\ into \.
          sed -n \
    	"s/'/'\\\\''/g;
    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
          ;; #(
        *)
          # `set' quotes correctly as required by POSIX, so do not add quotes.
          sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
          ;;
        esac |
        sort
    ) |
      sed '
         /^ac_cv_env_/b end
         t clear
         :clear
         s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
         t end
         s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
         :end' >>confcache
    if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
      if test -w "$cache_file"; then
        if test "x$cache_file" != "x/dev/null"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
    printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
          if test ! -f "$cache_file" || test -h "$cache_file"; then
    	cat confcache >"$cache_file"
          else
            case $cache_file in #(
            */* | ?:*)
    	  mv -f confcache "$cache_file"$$ &&
    	  mv -f "$cache_file"$$ "$cache_file" ;; #(
            *)
    	  mv -f confcache "$cache_file" ;;
    	esac
          fi
        fi
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
    printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
      fi
    fi
    rm -f confcache
    
      echo "configuring package in srclib/apr-util now"
      ac_popdir=`pwd`
      apr_config_subdirs="srclib/apr-util"
      test -d srclib/apr-util || $mkdir_p srclib/apr-util
      ac_abs_srcdir=`(cd $srcdir/srclib/apr-util && pwd)`
      cd srclib/apr-util
    
          # A "../" for each directory in /$config_subdirs.
          ac_dots=`echo $apr_config_subdirs|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
    
      # Make the cache file pathname absolute for the subdirs
      # required to correctly handle subdirs that might actually
      # be symlinks
      case "$cache_file" in
      /*) # already absolute
        ac_sub_cache_file=$cache_file ;;
      *)  # Was relative path.
        ac_sub_cache_file="$ac_popdir/$cache_file" ;;
      esac
    
    
      apr_configure_args=
      apr_sep=
      for apr_configure_arg in $ac_configure_args
      do
        case "$apr_configure_arg" in
          --enable-layout=*|\'--enable-layout=*)
            continue ;;
        esac
        apr_configure_args="$apr_configure_args$apr_sep'$apr_configure_arg'"
        apr_sep=" "
      done
    
    
        test "x$silent" = "xyes" && apr_configure_args="$apr_configure_args --silent"
    
        apr_configure_args="--disable-option-checking $apr_configure_args"
    
                  if eval $SHELL $ac_abs_srcdir/configure $apr_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_abs_srcdir --with-apr=../apr --prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir
      then :
        echo "srclib/apr-util configured properly"
      else
        echo "configure failed for srclib/apr-util"
        exit 1
      fi
    
      cd $ac_popdir
    
      # grab any updates from the sub-package
      if test -r "$cache_file"; then
      # Some versions of bash will fail to source /dev/null (special files
      # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
      if test /dev/null != "$cache_file" && test -f "$cache_file"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
    printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
        case $cache_file in
          [\\/]* | ?:[\\/]* ) . "$cache_file";;
          *)                      . "./$cache_file";;
        esac
      fi
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
    printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
      >$cache_file
    fi
    
    
        AP_BUILD_SRCLIB_DIRS="$AP_BUILD_SRCLIB_DIRS apr-util"
      AP_CLEAN_SRCLIB_DIRS="apr-util $AP_CLEAN_SRCLIB_DIRS"
        apu_config="./srclib/apr-util/apu-${apr_major_version}-config"
    fi
    
    if test "$apu_found" = "obsolete"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: APR-util obsoleted, woohoo" >&5
    printf "%s\n" "$as_me: APR-util obsoleted, woohoo" >&6;}
    else
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"`$apu_config --ldflags`\""
        LDFLAGS="`$apu_config --ldflags`"
      else
        apr_addto_bugger="`$apu_config --ldflags`"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
      APU_BINDIR=`$apu_config --bindir`
      APU_INCLUDEDIR=`$apu_config --includedir`
      APU_INCLUDES=`$apu_config --includes`
      APU_VERSION=`$apu_config --version`
      APU_CONFIG="$APU_BINDIR/apu-`echo ${APU_VERSION} | sed 's,\..*,,'`-config"
    fi
    
    
    
    
    
    
    
    
    
    
    ac_ext=c
    ac_cpp='$CPP $CPPFLAGS'
    ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
    ac_compiler_gnu=$ac_cv_c_compiler_gnu
    if test -n "$ac_tool_prefix"; then
      # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
    set dummy ${ac_tool_prefix}gcc; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$CC"; then
      ac_cv_prog_CC="$CC" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_CC="${ac_tool_prefix}gcc"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    CC=$ac_cv_prog_CC
    if test -n "$CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
    printf "%s\n" "$CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    fi
    if test -z "$ac_cv_prog_CC"; then
      ac_ct_CC=$CC
      # Extract the first word of "gcc", so it can be a program name with args.
    set dummy gcc; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_ac_ct_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$ac_ct_CC"; then
      ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_ac_ct_CC="gcc"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    ac_ct_CC=$ac_cv_prog_ac_ct_CC
    if test -n "$ac_ct_CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
    printf "%s\n" "$ac_ct_CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
      if test "x$ac_ct_CC" = x; then
        CC=""
      else
        case $cross_compiling:$ac_tool_warned in
    yes:)
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
    printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
    ac_tool_warned=yes ;;
    esac
        CC=$ac_ct_CC
      fi
    else
      CC="$ac_cv_prog_CC"
    fi
    
    if test -z "$CC"; then
              if test -n "$ac_tool_prefix"; then
        # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
    set dummy ${ac_tool_prefix}cc; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$CC"; then
      ac_cv_prog_CC="$CC" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_CC="${ac_tool_prefix}cc"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    CC=$ac_cv_prog_CC
    if test -n "$CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
    printf "%s\n" "$CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
      fi
    fi
    if test -z "$CC"; then
      # Extract the first word of "cc", so it can be a program name with args.
    set dummy cc; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$CC"; then
      ac_cv_prog_CC="$CC" # Let the user override the test.
    else
      ac_prog_rejected=no
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
           ac_prog_rejected=yes
           continue
         fi
        ac_cv_prog_CC="cc"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    if test $ac_prog_rejected = yes; then
      # We found a bogon in the path, so make sure we never use it.
      set dummy $ac_cv_prog_CC
      shift
      if test $# != 0; then
        # We chose a different compiler from the bogus one.
        # However, it has the same basename, so the bogon will be chosen
        # first if we set CC to just the basename; use the full file name.
        shift
        ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
      fi
    fi
    fi
    fi
    CC=$ac_cv_prog_CC
    if test -n "$CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
    printf "%s\n" "$CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    fi
    if test -z "$CC"; then
      if test -n "$ac_tool_prefix"; then
      for ac_prog in cl.exe
      do
        # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
    set dummy $ac_tool_prefix$ac_prog; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$CC"; then
      ac_cv_prog_CC="$CC" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    CC=$ac_cv_prog_CC
    if test -n "$CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
    printf "%s\n" "$CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
        test -n "$CC" && break
      done
    fi
    if test -z "$CC"; then
      ac_ct_CC=$CC
      for ac_prog in cl.exe
    do
      # Extract the first word of "$ac_prog", so it can be a program name with args.
    set dummy $ac_prog; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_ac_ct_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$ac_ct_CC"; then
      ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_ac_ct_CC="$ac_prog"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    ac_ct_CC=$ac_cv_prog_ac_ct_CC
    if test -n "$ac_ct_CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
    printf "%s\n" "$ac_ct_CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
      test -n "$ac_ct_CC" && break
    done
    
      if test "x$ac_ct_CC" = x; then
        CC=""
      else
        case $cross_compiling:$ac_tool_warned in
    yes:)
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
    printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
    ac_tool_warned=yes ;;
    esac
        CC=$ac_ct_CC
      fi
    fi
    
    fi
    if test -z "$CC"; then
      if test -n "$ac_tool_prefix"; then
      # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
    set dummy ${ac_tool_prefix}clang; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$CC"; then
      ac_cv_prog_CC="$CC" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_CC="${ac_tool_prefix}clang"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    CC=$ac_cv_prog_CC
    if test -n "$CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
    printf "%s\n" "$CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    fi
    if test -z "$ac_cv_prog_CC"; then
      ac_ct_CC=$CC
      # Extract the first word of "clang", so it can be a program name with args.
    set dummy clang; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_ac_ct_CC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$ac_ct_CC"; then
      ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_ac_ct_CC="clang"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    ac_ct_CC=$ac_cv_prog_ac_ct_CC
    if test -n "$ac_ct_CC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
    printf "%s\n" "$ac_ct_CC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
      if test "x$ac_ct_CC" = x; then
        CC=""
      else
        case $cross_compiling:$ac_tool_warned in
    yes:)
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
    printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
    ac_tool_warned=yes ;;
    esac
        CC=$ac_ct_CC
      fi
    else
      CC="$ac_cv_prog_CC"
    fi
    
    fi
    
    
    test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "no acceptable C compiler found in \$PATH
    See \`config.log' for more details" "$LINENO" 5; }
    
    # Provide some information about the compiler.
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
    set X $ac_compile
    ac_compiler=$2
    for ac_option in --version -v -V -qversion -version; do
      { { ac_try="$ac_compiler $ac_option >&5"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_compiler $ac_option >&5") 2>conftest.err
      ac_status=$?
      if test -s conftest.err; then
        sed '10a\
    ... rest of stderr output deleted ...
             10q' conftest.err >conftest.er1
        cat conftest.er1 >&5
      fi
      rm -f conftest.er1 conftest.err
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; }
    done
    
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    ac_clean_files_save=$ac_clean_files
    ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
    # Try to create an executable without -o first, disregard a.out.
    # It will help us diagnose broken compilers, and finding out an intuition
    # of exeext.
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
    printf %s "checking whether the C compiler works... " >&6; }
    ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
    
    # The possible output files:
    ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
    
    ac_rmfiles=
    for ac_file in $ac_files
    do
      case $ac_file in
        *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
        * ) ac_rmfiles="$ac_rmfiles $ac_file";;
      esac
    done
    rm -f $ac_rmfiles
    
    if { { ac_try="$ac_link_default"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_link_default") 2>&5
      ac_status=$?
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; }
    then :
      # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
    # So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
    # in a Makefile.  We should not override ac_cv_exeext if it was cached,
    # so that the user can short-circuit this test for compilers unknown to
    # Autoconf.
    for ac_file in $ac_files ''
    do
      test -f "$ac_file" || continue
      case $ac_file in
        *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
    	;;
        [ab].out )
    	# We found the default executable, but exeext='' is most
    	# certainly right.
    	break;;
        *.* )
    	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
    	then :; else
    	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
    	fi
    	# We set ac_cv_exeext here because the later test for it is not
    	# safe: cross compilers may not add the suffix if given an `-o'
    	# argument, so we may need to know it at that point already.
    	# Even if this section looks crufty: it has the advantage of
    	# actually working.
    	break;;
        * )
    	break;;
      esac
    done
    test "$ac_cv_exeext" = no && ac_cv_exeext=
    
    else $as_nop
      ac_file=''
    fi
    if test -z "$ac_file"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    printf "%s\n" "$as_me: failed program was:" >&5
    sed 's/^/| /' conftest.$ac_ext >&5
    
    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error 77 "C compiler cannot create executables
    See \`config.log' for more details" "$LINENO" 5; }
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
    printf %s "checking for C compiler default output file name... " >&6; }
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
    printf "%s\n" "$ac_file" >&6; }
    ac_exeext=$ac_cv_exeext
    
    rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
    ac_clean_files=$ac_clean_files_save
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
    printf %s "checking for suffix of executables... " >&6; }
    if { { ac_try="$ac_link"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_link") 2>&5
      ac_status=$?
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; }
    then :
      # If both `conftest.exe' and `conftest' are `present' (well, observable)
    # catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
    # work properly (i.e., refer to `conftest.exe'), while it won't with
    # `rm'.
    for ac_file in conftest.exe conftest conftest.*; do
      test -f "$ac_file" || continue
      case $ac_file in
        *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
        *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
    	  break;;
        * ) break;;
      esac
    done
    else $as_nop
      { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "cannot compute suffix of executables: cannot compile and link
    See \`config.log' for more details" "$LINENO" 5; }
    fi
    rm -f conftest conftest$ac_cv_exeext
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
    printf "%s\n" "$ac_cv_exeext" >&6; }
    
    rm -f conftest.$ac_ext
    EXEEXT=$ac_cv_exeext
    ac_exeext=$EXEEXT
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <stdio.h>
    int
    main (void)
    {
    FILE *f = fopen ("conftest.out", "w");
     return ferror (f) || fclose (f) != 0;
    
      ;
      return 0;
    }
    _ACEOF
    ac_clean_files="$ac_clean_files conftest.out"
    # Check that the compiler produces executables we can run.  If not, either
    # the compiler is broken, or we cross compile.
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
    printf %s "checking whether we are cross compiling... " >&6; }
    if test "$cross_compiling" != yes; then
      { { ac_try="$ac_link"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_link") 2>&5
      ac_status=$?
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; }
      if { ac_try='./conftest$ac_cv_exeext'
      { { case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_try") 2>&5
      ac_status=$?
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; }; }; then
        cross_compiling=no
      else
        if test "$cross_compiling" = maybe; then
    	cross_compiling=yes
        else
    	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error 77 "cannot run C compiled programs.
    If you meant to cross compile, use \`--host'.
    See \`config.log' for more details" "$LINENO" 5; }
        fi
      fi
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
    printf "%s\n" "$cross_compiling" >&6; }
    
    rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
    ac_clean_files=$ac_clean_files_save
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
    printf %s "checking for suffix of object files... " >&6; }
    if test ${ac_cv_objext+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    rm -f conftest.o conftest.obj
    if { { ac_try="$ac_compile"
    case "(($ac_try" in
      *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
      *) ac_try_echo=$ac_try;;
    esac
    eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
    printf "%s\n" "$ac_try_echo"; } >&5
      (eval "$ac_compile") 2>&5
      ac_status=$?
      printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
      test $ac_status = 0; }
    then :
      for ac_file in conftest.o conftest.obj conftest.*; do
      test -f "$ac_file" || continue;
      case $ac_file in
        *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
        *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
           break;;
      esac
    done
    else $as_nop
      printf "%s\n" "$as_me: failed program was:" >&5
    sed 's/^/| /' conftest.$ac_ext >&5
    
    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "cannot compute suffix of object files: cannot compile
    See \`config.log' for more details" "$LINENO" 5; }
    fi
    rm -f conftest.$ac_cv_objext conftest.$ac_ext
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
    printf "%s\n" "$ac_cv_objext" >&6; }
    OBJEXT=$ac_cv_objext
    ac_objext=$OBJEXT
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
    printf %s "checking whether the compiler supports GNU C... " >&6; }
    if test ${ac_cv_c_compiler_gnu+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    #ifndef __GNUC__
           choke me
    #endif
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_compiler_gnu=yes
    else $as_nop
      ac_compiler_gnu=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    ac_cv_c_compiler_gnu=$ac_compiler_gnu
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
    printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
    ac_compiler_gnu=$ac_cv_c_compiler_gnu
    
    if test $ac_compiler_gnu = yes; then
      GCC=yes
    else
      GCC=
    fi
    ac_test_CFLAGS=${CFLAGS+y}
    ac_save_CFLAGS=$CFLAGS
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
    printf %s "checking whether $CC accepts -g... " >&6; }
    if test ${ac_cv_prog_cc_g+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_save_c_werror_flag=$ac_c_werror_flag
       ac_c_werror_flag=yes
       ac_cv_prog_cc_g=no
       CFLAGS="-g"
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_prog_cc_g=yes
    else $as_nop
      CFLAGS=""
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
    
    else $as_nop
      ac_c_werror_flag=$ac_save_c_werror_flag
    	 CFLAGS="-g"
    	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_prog_cc_g=yes
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
       ac_c_werror_flag=$ac_save_c_werror_flag
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
    printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
    if test $ac_test_CFLAGS; then
      CFLAGS=$ac_save_CFLAGS
    elif test $ac_cv_prog_cc_g = yes; then
      if test "$GCC" = yes; then
        CFLAGS="-g -O2"
      else
        CFLAGS="-g"
      fi
    else
      if test "$GCC" = yes; then
        CFLAGS="-O2"
      else
        CFLAGS=
      fi
    fi
    ac_prog_cc_stdc=no
    if test x$ac_prog_cc_stdc = xno
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
    printf %s "checking for $CC option to enable C11 features... " >&6; }
    if test ${ac_cv_prog_cc_c11+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_cv_prog_cc_c11=no
    ac_save_CC=$CC
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    $ac_c_conftest_c11_program
    _ACEOF
    for ac_arg in '' -std=gnu11
    do
      CC="$ac_save_CC $ac_arg"
      if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_prog_cc_c11=$ac_arg
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam
      test "x$ac_cv_prog_cc_c11" != "xno" && break
    done
    rm -f conftest.$ac_ext
    CC=$ac_save_CC
    fi
    
    if test "x$ac_cv_prog_cc_c11" = xno
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
    printf "%s\n" "unsupported" >&6; }
    else $as_nop
      if test "x$ac_cv_prog_cc_c11" = x
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
    printf "%s\n" "none needed" >&6; }
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
    printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
         CC="$CC $ac_cv_prog_cc_c11"
    fi
      ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
      ac_prog_cc_stdc=c11
    fi
    fi
    if test x$ac_prog_cc_stdc = xno
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
    printf %s "checking for $CC option to enable C99 features... " >&6; }
    if test ${ac_cv_prog_cc_c99+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_cv_prog_cc_c99=no
    ac_save_CC=$CC
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    $ac_c_conftest_c99_program
    _ACEOF
    for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
    do
      CC="$ac_save_CC $ac_arg"
      if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_prog_cc_c99=$ac_arg
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam
      test "x$ac_cv_prog_cc_c99" != "xno" && break
    done
    rm -f conftest.$ac_ext
    CC=$ac_save_CC
    fi
    
    if test "x$ac_cv_prog_cc_c99" = xno
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
    printf "%s\n" "unsupported" >&6; }
    else $as_nop
      if test "x$ac_cv_prog_cc_c99" = x
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
    printf "%s\n" "none needed" >&6; }
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
    printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
         CC="$CC $ac_cv_prog_cc_c99"
    fi
      ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
      ac_prog_cc_stdc=c99
    fi
    fi
    if test x$ac_prog_cc_stdc = xno
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
    printf %s "checking for $CC option to enable C89 features... " >&6; }
    if test ${ac_cv_prog_cc_c89+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_cv_prog_cc_c89=no
    ac_save_CC=$CC
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    $ac_c_conftest_c89_program
    _ACEOF
    for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
    do
      CC="$ac_save_CC $ac_arg"
      if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_prog_cc_c89=$ac_arg
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam
      test "x$ac_cv_prog_cc_c89" != "xno" && break
    done
    rm -f conftest.$ac_ext
    CC=$ac_save_CC
    fi
    
    if test "x$ac_cv_prog_cc_c89" = xno
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
    printf "%s\n" "unsupported" >&6; }
    else $as_nop
      if test "x$ac_cv_prog_cc_c89" = x
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
    printf "%s\n" "none needed" >&6; }
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
    printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
         CC="$CC $ac_cv_prog_cc_c89"
    fi
      ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
      ac_prog_cc_stdc=c89
    fi
    fi
    
    ac_ext=c
    ac_cpp='$CPP $CPPFLAGS'
    ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
    ac_compiler_gnu=$ac_cv_c_compiler_gnu
    
    ac_ext=c
    ac_cpp='$CPP $CPPFLAGS'
    ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
    ac_compiler_gnu=$ac_cv_c_compiler_gnu
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
    printf %s "checking how to run the C preprocessor... " >&6; }
    # On Suns, sometimes $CPP names a directory.
    if test -n "$CPP" && test -d "$CPP"; then
      CPP=
    fi
    if test -z "$CPP"; then
      if test ${ac_cv_prog_CPP+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
          # Double quotes because $CC needs to be expanded
        for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp
        do
          ac_preproc_ok=false
    for ac_c_preproc_warn_flag in '' yes
    do
      # Use a header file that comes with gcc, so configuring glibc
      # with a fresh cross-compiler works.
      # On the NeXT, cc -E runs the code through the compiler's parser,
      # not just through cpp. "Syntax error" is here to catch this case.
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <limits.h>
    		     Syntax error
    _ACEOF
    if ac_fn_c_try_cpp "$LINENO"
    then :
    
    else $as_nop
      # Broken: fails on valid input.
    continue
    fi
    rm -f conftest.err conftest.i conftest.$ac_ext
    
      # OK, works on sane cases.  Now check whether nonexistent headers
      # can be detected and how.
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <ac_nonexistent.h>
    _ACEOF
    if ac_fn_c_try_cpp "$LINENO"
    then :
      # Broken: success on invalid input.
    continue
    else $as_nop
      # Passes both tests.
    ac_preproc_ok=:
    break
    fi
    rm -f conftest.err conftest.i conftest.$ac_ext
    
    done
    # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
    rm -f conftest.i conftest.err conftest.$ac_ext
    if $ac_preproc_ok
    then :
      break
    fi
    
        done
        ac_cv_prog_CPP=$CPP
    
    fi
      CPP=$ac_cv_prog_CPP
    else
      ac_cv_prog_CPP=$CPP
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
    printf "%s\n" "$CPP" >&6; }
    ac_preproc_ok=false
    for ac_c_preproc_warn_flag in '' yes
    do
      # Use a header file that comes with gcc, so configuring glibc
      # with a fresh cross-compiler works.
      # On the NeXT, cc -E runs the code through the compiler's parser,
      # not just through cpp. "Syntax error" is here to catch this case.
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <limits.h>
    		     Syntax error
    _ACEOF
    if ac_fn_c_try_cpp "$LINENO"
    then :
    
    else $as_nop
      # Broken: fails on valid input.
    continue
    fi
    rm -f conftest.err conftest.i conftest.$ac_ext
    
      # OK, works on sane cases.  Now check whether nonexistent headers
      # can be detected and how.
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <ac_nonexistent.h>
    _ACEOF
    if ac_fn_c_try_cpp "$LINENO"
    then :
      # Broken: success on invalid input.
    continue
    else $as_nop
      # Passes both tests.
    ac_preproc_ok=:
    break
    fi
    rm -f conftest.err conftest.i conftest.$ac_ext
    
    done
    # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
    rm -f conftest.i conftest.err conftest.$ac_ext
    if $ac_preproc_ok
    then :
    
    else $as_nop
      { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
    See \`config.log' for more details" "$LINENO" 5; }
    fi
    
    ac_ext=c
    ac_cpp='$CPP $CPPFLAGS'
    ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
    ac_compiler_gnu=$ac_cv_c_compiler_gnu
    
    
    
    
    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
    
    
    # Check whether --with-pcre was given.
    if test ${with_pcre+y}
    then :
      withval=$with_pcre;
    fi
    
    if test "x$with_pcre" = "x" || test "$with_pcre" = "yes"; then
      with_pcre="$PATH"
    else if which $with_pcre 2>/dev/null; then :; else
      with_pcre="$with_pcre/bin:$with_pcre"
    fi
    fi
    
    for ac_prog in pcre2-config pcre-config
    do
      # Extract the first word of "$target_alias-$ac_prog", so it can be a program name with args.
    set dummy $target_alias-$ac_prog; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_PCRE_CONFIG+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$PCRE_CONFIG"; then
      ac_cv_prog_PCRE_CONFIG="$PCRE_CONFIG" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $with_pcre
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_PCRE_CONFIG="$target_alias-$ac_prog"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    PCRE_CONFIG=$ac_cv_prog_PCRE_CONFIG
    if test -n "$PCRE_CONFIG"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PCRE_CONFIG" >&5
    printf "%s\n" "$PCRE_CONFIG" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
      test -n "$PCRE_CONFIG" && break
    done
    if test -z "$PCRE_CONFIG"; then
      if test "$build" = "$target"; then
        ac_ct_PCRE_CONFIG=$PCRE_CONFIG
        for ac_prog in pcre2-config pcre-config
    do
      # Extract the first word of "$ac_prog", so it can be a program name with args.
    set dummy $ac_prog; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_ac_ct_PCRE_CONFIG+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$ac_ct_PCRE_CONFIG"; then
      ac_cv_prog_ac_ct_PCRE_CONFIG="$ac_ct_PCRE_CONFIG" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $with_pcre
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_ac_ct_PCRE_CONFIG="$ac_prog"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    ac_ct_PCRE_CONFIG=$ac_cv_prog_ac_ct_PCRE_CONFIG
    if test -n "$ac_ct_PCRE_CONFIG"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PCRE_CONFIG" >&5
    printf "%s\n" "$ac_ct_PCRE_CONFIG" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
      test -n "$ac_ct_PCRE_CONFIG" && break
    done
    test -n "$ac_ct_PCRE_CONFIG" || ac_ct_PCRE_CONFIG="`which $with_pcre 2>/dev/null`"
    
        PCRE_CONFIG=$ac_ct_PCRE_CONFIG
      else
        PCRE_CONFIG="`which $with_pcre 2>/dev/null`"
      fi
    fi
    
    
    if test "x$PCRE_CONFIG" != "x"; then
      if $PCRE_CONFIG --version >/dev/null 2>&1; then :; else
        as_fn_error $? "Did not find working script at $PCRE_CONFIG" "$LINENO" 5
      fi
      case `$PCRE_CONFIG --version` in
      1[0-9].*)
    
    printf "%s\n" "#define HAVE_PCRE2 1" >>confdefs.h
    
        ;;
      [1-5].*)
        as_fn_error $? "Need at least pcre version 6.0" "$LINENO" 5
        ;;
      esac
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using external PCRE library from $PCRE_CONFIG" >&5
    printf "%s\n" "$as_me: Using external PCRE library from $PCRE_CONFIG" >&6;}
    
      if test "x$PCRE_INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting PCRE_INCLUDES to \"`$PCRE_CONFIG --cflags`\""
        PCRE_INCLUDES="`$PCRE_CONFIG --cflags`"
      else
        apr_addto_bugger="`$PCRE_CONFIG --cflags`"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $PCRE_INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to PCRE_INCLUDES"
            PCRE_INCLUDES="$PCRE_INCLUDES $i"
          fi
        done
      fi
    
    
      if test "x$PCRE_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting PCRE_LIBS to \"`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`\""
        PCRE_LIBS="`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`"
      else
        apr_addto_bugger="`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $PCRE_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to PCRE_LIBS"
            PCRE_LIBS="$PCRE_LIBS $i"
          fi
        done
      fi
    
    else
      as_fn_error $? "pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/" "$LINENO" 5
    fi
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST PCRE_LIBS"
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuring Apache httpd..." >&5
    printf "%s\n" "$as_me: Configuring Apache httpd..." >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I.\""
        INCLUDES="-I."
      else
        apr_addto_bugger="-I."
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    if test "$abs_builddir" != "$abs_srcdir"; then
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_builddir)/include\""
        INCLUDES="-I\$(top_builddir)/include"
      else
        apr_addto_bugger="-I\$(top_builddir)/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    fi
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/os/\$(OS_DIR) -I\$(top_srcdir)/include\""
        INCLUDES="-I\$(top_srcdir)/os/\$(OS_DIR) -I\$(top_srcdir)/include"
      else
        apr_addto_bugger="-I\$(top_srcdir)/os/\$(OS_DIR) -I\$(top_srcdir)/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    # apr/apr-util --includes may pick up system paths for dependent
    # libraries, so ensure these are later in INCLUDES than local source
    # directories.
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"$APR_INCLUDES\""
        INCLUDES="$APR_INCLUDES"
      else
        apr_addto_bugger="$APR_INCLUDES"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"$APU_INCLUDES\""
        INCLUDES="$APU_INCLUDES"
      else
        apr_addto_bugger="$APU_INCLUDES"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"$PCRE_INCLUDES\""
        INCLUDES="$PCRE_INCLUDES"
      else
        apr_addto_bugger="$PCRE_INCLUDES"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    save_CPPFLAGS="$CPPFLAGS"
    CPPFLAGS="$CPPFLAGS $PCRE_INCLUDES"
    
    
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #ifdef HAVE_PCRE2
    yes
    #else
    #include <pcre.h>
    #ifdef PCRE_DUPNAMES
    yes
    #endif
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "yes" >/dev/null 2>&1
    then :
      pcre_have_dupnames=yes
    else $as_nop
      pcre_have_dupnames=no
    fi
    rm -rf conftest*
    
    if test "$pcre_have_dupnames" != "yes"; then
        as_fn_error $? "pcre version does not support PCRE_DUPNAMES" "$LINENO" 5
    fi
    CPPFLAGS="$save_CPPFLAGS"
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Applying OS-specific hints for httpd..." >&5
    printf "%s\n" "$as_me: Applying OS-specific hints for httpd..." >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    
    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]* | *[2-9].[0-9]*)
                  SH_LIBTOOL='$(LIBTOOL)'
                  SHLTCFLAGS="-prefer-pic"
                  LTCFLAGS="-prefer-non-pic -static"
                  ;;
              *)
                  SH_LIBTOOL='$(SHELL) $(top_builddir)/shlibtool $(LTFLAGS)'
                  SHLTCFLAGS=""
                  LTCFLAGS=""
                  ;;
          esac
          ;;
    esac
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SHLTCFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST LTCFLAGS"
    
    
    
    case $host in
      *-apple-aux3*)
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
          ;;
      *os2-emx*)
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
          ;;
      *-linux-*)
          case `uname -r` in
            # Unserialized accept() was not recommended until Linux 2.2.
            [01].* | 2.[01]* )
                ;;
            * )
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
                ;;
          esac
          ;;
      *486-*-bsdi* | *-netbsd* | *-freebsd* | *-apple-darwin* | *-dec-osf* | *-qnx)
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
          ;;
      *-solaris2*)
                ap_platform_runtime_link_flag="-R"
                      case `uname -r` in
            5.[567]*)
                ;;
            * )
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
                ;;
          esac
          ;;
      *cygwin*)
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
          ;;
      *mingw32*)
    
      if test "x$INTERNAL_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INTERNAL_CPPFLAGS to \"-DAP_DECLARE_EXPORT\""
        INTERNAL_CPPFLAGS="-DAP_DECLARE_EXPORT"
      else
        apr_addto_bugger="-DAP_DECLARE_EXPORT"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INTERNAL_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INTERNAL_CPPFLAGS"
            INTERNAL_CPPFLAGS="$INTERNAL_CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test -z "$ac_cv_func_times"; then
        test "x$silent" != "xyes" && echo "  setting ac_cv_func_times to \"no\""
        ac_cv_func_times="no"
      fi
    
    
      if test -z "$ac_cv_func_getpwnam"; then
        test "x$silent" != "xyes" && echo "  setting ac_cv_func_getpwnam to \"no\""
        ac_cv_func_getpwnam="no"
      fi
    
    
      if test -z "$ac_cv_func_getgrnam"; then
        test "x$silent" != "xyes" && echo "  setting ac_cv_func_getgrnam to \"no\""
        ac_cv_func_getgrnam="no"
      fi
    
          ;;
      *aix*)
          aixver=`echo $host | sed 's/^[^0-9]*//' | sed 's/\.//g'`
          if test $aixver -ge 4320; then
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
          fi
          ;;
      *os390*)
    
      test "x$silent" != "xyes" && echo "  forcing SINGLE_LISTEN_UNSERIALIZED_ACCEPT to \"1\""
      SINGLE_LISTEN_UNSERIALIZED_ACCEPT="1"
    
          ;;
    esac
    
    
      test "x$silent" != "xyes" && echo "  forcing AP_NONBLOCK_WHEN_MULTI_LISTEN to \"1\""
      AP_NONBLOCK_WHEN_MULTI_LISTEN="1"
    
    
    
    
    # Extract the first word of "rm", so it can be a program name with args.
    set dummy rm; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_path_RM+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      case $RM in
      [\\/]* | ?:[\\/]*)
      ac_cv_path_RM="$RM" # Let the user override the test with a path.
      ;;
      *)
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_path_RM="$as_dir$ac_word$ac_exec_ext"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
      ;;
    esac
    fi
    RM=$ac_cv_path_RM
    if test -n "$RM"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RM" >&5
    printf "%s\n" "$RM" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    # Extract the first word of "pkg-config", so it can be a program name with args.
    set dummy pkg-config; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_path_PKGCONFIG+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      case $PKGCONFIG in
      [\\/]* | ?:[\\/]*)
      ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path.
      ;;
      *)
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_path_PKGCONFIG="$as_dir$ac_word$ac_exec_ext"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
      ;;
    esac
    fi
    PKGCONFIG=$ac_cv_path_PKGCONFIG
    if test -n "$PKGCONFIG"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5
    printf "%s\n" "$PKGCONFIG" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    # Extract the first word of "rsync", so it can be a program name with args.
    set dummy rsync; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_path_RSYNC+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      case $RSYNC in
      [\\/]* | ?:[\\/]*)
      ac_cv_path_RSYNC="$RSYNC" # Let the user override the test with a path.
      ;;
      *)
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_path_RSYNC="$as_dir$ac_word$ac_exec_ext"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
      ;;
    esac
    fi
    RSYNC=$ac_cv_path_RSYNC
    if test -n "$RSYNC"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RSYNC" >&5
    printf "%s\n" "$RSYNC" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    # Extract the first word of "svn", so it can be a program name with args.
    set dummy svn; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_path_SVN+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      case $SVN in
      [\\/]* | ?:[\\/]*)
      ac_cv_path_SVN="$SVN" # Let the user override the test with a path.
      ;;
      *)
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_path_SVN="$as_dir$ac_word$ac_exec_ext"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
      ;;
    esac
    fi
    SVN=$ac_cv_path_SVN
    if test -n "$SVN"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SVN" >&5
    printf "%s\n" "$SVN" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    for ac_prog in gawk mawk nawk awk
    do
      # Extract the first word of "$ac_prog", so it can be a program name with args.
    set dummy $ac_prog; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_AWK+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$AWK"; then
      ac_cv_prog_AWK="$AWK" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_AWK="$ac_prog"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    AWK=$ac_cv_prog_AWK
    if test -n "$AWK"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
    printf "%s\n" "$AWK" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
      test -n "$AWK" && break
    done
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
    printf %s "checking whether ln -s works... " >&6; }
    LN_S=$as_ln_s
    if test "$LN_S" = "ln -s"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
    printf "%s\n" "no, using $LN_S" >&6; }
    fi
    
    if test -n "$ac_tool_prefix"; then
      # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
    set dummy ${ac_tool_prefix}ranlib; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_RANLIB+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$RANLIB"; then
      ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    RANLIB=$ac_cv_prog_RANLIB
    if test -n "$RANLIB"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
    printf "%s\n" "$RANLIB" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
    fi
    if test -z "$ac_cv_prog_RANLIB"; then
      ac_ct_RANLIB=$RANLIB
      # Extract the first word of "ranlib", so it can be a program name with args.
    set dummy ranlib; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_ac_ct_RANLIB+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$ac_ct_RANLIB"; then
      ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_ac_ct_RANLIB="ranlib"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
    if test -n "$ac_ct_RANLIB"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
    printf "%s\n" "$ac_ct_RANLIB" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
      if test "x$ac_ct_RANLIB" = x; then
        RANLIB="true"
      else
        case $cross_compiling:$ac_tool_warned in
    yes:)
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
    printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
    ac_tool_warned=yes ;;
    esac
        RANLIB=$ac_ct_RANLIB
      fi
    else
      RANLIB="$ac_cv_prog_RANLIB"
    fi
    
    for ac_prog in lynx links elinks
    do
      # Extract the first word of "$ac_prog", so it can be a program name with args.
    set dummy $ac_prog; ac_word=$2
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    printf %s "checking for $ac_word... " >&6; }
    if test ${ac_cv_prog_LYNX_PATH+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test -n "$LYNX_PATH"; then
      ac_cv_prog_LYNX_PATH="$LYNX_PATH" # Let the user override the test.
    else
    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_exec_ext in '' $ac_executable_extensions; do
      if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
        ac_cv_prog_LYNX_PATH="$ac_prog"
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
        break 2
      fi
    done
      done
    IFS=$as_save_IFS
    
    fi
    fi
    LYNX_PATH=$ac_cv_prog_LYNX_PATH
    if test -n "$LYNX_PATH"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LYNX_PATH" >&5
    printf "%s\n" "$LYNX_PATH" >&6; }
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    fi
    
    
      test -n "$LYNX_PATH" && break
    done
    test -n "$LYNX_PATH" || LYNX_PATH="lynx"
    
    
    # Hard-coded install programs
    MKINSTALLDIRS="\$(abs_srcdir)/build/mkdir.sh"
    INSTALL="\$(LIBTOOL) --mode=install \$(abs_srcdir)/build/install.sh -c"
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MKINSTALLDIRS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST INSTALL"
    
    
    
    
    ac_header= ac_cache=
    for ac_item in $ac_header_c_list
    do
      if test $ac_cache; then
        ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
        if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
          printf "%s\n" "#define $ac_item 1" >> confdefs.h
        fi
        ac_header= ac_cache=
      elif test $ac_header; then
        ac_cache=$ac_item
      else
        ac_header=$ac_item
      fi
    done
    
    
    
    
    
    
    
    
    if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
    then :
    
    printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
    
    fi
    
    
    
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
    printf %s "checking whether it is safe to define __EXTENSIONS__... " >&6; }
    if test ${ac_cv_safe_to_define___extensions__+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #         define __EXTENSIONS__ 1
              $ac_includes_default
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_safe_to_define___extensions__=yes
    else $as_nop
      ac_cv_safe_to_define___extensions__=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
    printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; }
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5
    printf %s "checking whether _XOPEN_SOURCE should be defined... " >&6; }
    if test ${ac_cv_should_define__xopen_source+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_cv_should_define__xopen_source=no
        if test $ac_cv_header_wchar_h = yes
    then :
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
              #include <wchar.h>
              mbstate_t x;
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
    
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
                #define _XOPEN_SOURCE 500
                #include <wchar.h>
                mbstate_t x;
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_should_define__xopen_source=yes
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5
    printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; }
    
      printf "%s\n" "#define _ALL_SOURCE 1" >>confdefs.h
    
      printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h
    
      printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h
    
      printf "%s\n" "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h
    
      printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h
    
      printf "%s\n" "#define _OPENBSD_SOURCE 1" >>confdefs.h
    
      printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
    
      printf "%s\n" "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h
    
      printf "%s\n" "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h
    
      printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h
    
      printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h
    
      printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h
    
      printf "%s\n" "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h
    
      printf "%s\n" "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h
    
      printf "%s\n" "#define _TANDEM_SOURCE 1" >>confdefs.h
    
      if test $ac_cv_header_minix_config_h = yes
    then :
      MINIX=yes
        printf "%s\n" "#define _MINIX 1" >>confdefs.h
    
        printf "%s\n" "#define _POSIX_SOURCE 1" >>confdefs.h
    
        printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h
    
    else $as_nop
      MINIX=
    fi
      if test $ac_cv_safe_to_define___extensions__ = yes
    then :
      printf "%s\n" "#define __EXTENSIONS__ 1" >>confdefs.h
    
    fi
      if test $ac_cv_should_define__xopen_source = yes
    then :
      printf "%s\n" "#define _XOPEN_SOURCE 500" >>confdefs.h
    
    fi
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
    printf %s "checking for library containing strerror... " >&6; }
    if test ${ac_cv_search_strerror+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_func_search_save_LIBS=$LIBS
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char strerror ();
    int
    main (void)
    {
    return strerror ();
      ;
      return 0;
    }
    _ACEOF
    for ac_lib in '' cposix
    do
      if test -z "$ac_lib"; then
        ac_res="none required"
      else
        ac_res=-l$ac_lib
        LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
      fi
      if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_search_strerror=$ac_res
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext
      if test ${ac_cv_search_strerror+y}
    then :
      break
    fi
    done
    if test ${ac_cv_search_strerror+y}
    then :
    
    else $as_nop
      ac_cv_search_strerror=no
    fi
    rm conftest.$ac_ext
    LIBS=$ac_func_search_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
    printf "%s\n" "$ac_cv_search_strerror" >&6; }
    ac_res=$ac_cv_search_strerror
    if test "$ac_res" != no
    then :
      test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
    
    fi
    
    
    # Ensure that satisfactory versions of apr and apr-util are
    # found if external copies are configured.
    if test "${apr_found}" = "yes"; then
      # Require at least APR 1.3.x otherwise fail
    
    
    
    
    
    
    ap_ckver_CPPFLAGS="$CPPFLAGS"
    CPPFLAGS="$CPPFLAGS `$apr_config --includes`"
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for APR version 1.3.0 or later" >&5
    printf %s "checking for APR version 1.3.0 or later... " >&6; }
    if test ${ap_cv_aprver13+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr_version.h>
    #if APR_MAJOR_VERSION > 1 || (APR_MAJOR_VERSION == 1 && APR_MINOR_VERSION >= 3)
    good
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "good" >/dev/null 2>&1
    then :
      ap_cv_aprver13=yes
    else $as_nop
      ap_cv_aprver13=no
    fi
    rm -rf conftest*
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_cv_aprver13" >&5
    printf "%s\n" "$ap_cv_aprver13" >&6; }
    
    if test "$ap_cv_aprver13" = "yes"; then
      :
    else
      as_fn_error $? "APR version 1.3.0 or later is required" "$LINENO" 5
    fi
    
    CPPFLAGS="$ap_ckver_CPPFLAGS"
    
    
    
    
    
    
    fi
    
    if test "${apu_found}" = "yes"; then
      # Require at least APR-util 1.3.x otherwise fail
      if test "${apr_found}" = "yes"; then
        # we need to add the APR includes to CPPFLAGS
        apu_ckver_CPPFLAGS="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS `$apr_config --includes`"
    
    
    
    
    
    
    ap_ckver_CPPFLAGS="$CPPFLAGS"
    CPPFLAGS="$CPPFLAGS `$apu_config --includes`"
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for APR-util version 1.3.0 or later" >&5
    printf %s "checking for APR-util version 1.3.0 or later... " >&6; }
    if test ${ap_cv_apuver13+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apu_version.h>
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3)
    good
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "good" >/dev/null 2>&1
    then :
      ap_cv_apuver13=yes
    else $as_nop
      ap_cv_apuver13=no
    fi
    rm -rf conftest*
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_cv_apuver13" >&5
    printf "%s\n" "$ap_cv_apuver13" >&6; }
    
    if test "$ap_cv_apuver13" = "yes"; then
      :
    else
      as_fn_error $? "APR-util version 1.3.0 or later is required" "$LINENO" 5
    fi
    
    CPPFLAGS="$ap_ckver_CPPFLAGS"
    
    
    
    
    
    
        CPPFLAGS="$apu_ckver_CPPFLAGS"
      else
    
    
    
    
    
    
    ap_ckver_CPPFLAGS="$CPPFLAGS"
    CPPFLAGS="$CPPFLAGS `$apu_config --includes`"
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for APR-util version 1.3.0 or later" >&5
    printf %s "checking for APR-util version 1.3.0 or later... " >&6; }
    if test ${ap_cv_apuver13+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apu_version.h>
    #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3)
    good
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "good" >/dev/null 2>&1
    then :
      ap_cv_apuver13=yes
    else $as_nop
      ap_cv_apuver13=no
    fi
    rm -rf conftest*
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_cv_apuver13" >&5
    printf "%s\n" "$ap_cv_apuver13" >&6; }
    
    if test "$ap_cv_apuver13" = "yes"; then
      :
    else
      as_fn_error $? "APR-util version 1.3.0 or later is required" "$LINENO" 5
    fi
    
    CPPFLAGS="$ap_ckver_CPPFLAGS"
    
    
    
    
    
    
      fi
    fi
    
    
    if test "$GCC" = "yes"; then
      MKDEP='$(CC) -MM'
    else
      rm -f conftest.c
      cat > conftest.c <<EOF
    #include <sys/types.h>
      int main(int argc, const char *argv) { return 0; }
    EOF
      MKDEP="true"
      for i in "$CC -MM" "$CC -M" "$CPP -MM" "$CPP -M" "cpp -M"; do
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $i can create proper make dependencies" >&5
    printf %s "checking if $i can create proper make dependencies... " >&6; }
        if $i conftest.c 2>/dev/null | grep 'conftest.o: conftest.c' >/dev/null; then
          MKDEP=$i
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
          break;
        fi
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
      done
      rm -f conftest.c
    fi
    
    
    
    
    
    
    
    
    # Autoupdate added the next two lines to ensure that your configure
    # script's behavior did not change.  They are probably safe to remove.
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
    printf %s "checking for egrep... " >&6; }
    if test ${ac_cv_path_EGREP+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
       then ac_cv_path_EGREP="$GREP -E"
       else
         if test -z "$EGREP"; then
      ac_path_EGREP_found=false
      # Loop through the user's path and test for each of PROGNAME-LIST
      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        for ac_prog in egrep
       do
        for ac_exec_ext in '' $ac_executable_extensions; do
          ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"
          as_fn_executable_p "$ac_path_EGREP" || continue
    # Check for GNU ac_path_EGREP and select it if it is found.
      # Check for GNU $ac_path_EGREP
    case `"$ac_path_EGREP" --version 2>&1` in
    *GNU*)
      ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
    *)
      ac_count=0
      printf %s 0123456789 >"conftest.in"
      while :
      do
        cat "conftest.in" "conftest.in" >"conftest.tmp"
        mv "conftest.tmp" "conftest.in"
        cp "conftest.in" "conftest.nl"
        printf "%s\n" 'EGREP' >> "conftest.nl"
        "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
        diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
        as_fn_arith $ac_count + 1 && ac_count=$as_val
        if test $ac_count -gt ${ac_path_EGREP_max-0}; then
          # Best one so far, save it but keep looking for a better one
          ac_cv_path_EGREP="$ac_path_EGREP"
          ac_path_EGREP_max=$ac_count
        fi
        # 10*(2^10) chars as input seems more than enough
        test $ac_count -gt 10 && break
      done
      rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
    esac
    
          $ac_path_EGREP_found && break 3
        done
      done
      done
    IFS=$as_save_IFS
      if test -z "$ac_cv_path_EGREP"; then
        as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
      fi
    else
      ac_cv_path_EGREP=$EGREP
    fi
    
       fi
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
    printf "%s\n" "$ac_cv_path_EGREP" >&6; }
     EGREP="$ac_cv_path_EGREP"
    
    
    
    ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
    if test "x$ac_cv_header_string_h" = xyes
    then :
      printf "%s\n" "#define HAVE_STRING_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
    if test "x$ac_cv_header_limits_h" = xyes
    then :
      printf "%s\n" "#define HAVE_LIMITS_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
    if test "x$ac_cv_header_unistd_h" = xyes
    then :
      printf "%s\n" "#define HAVE_UNISTD_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_socket_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "pwd.h" "ac_cv_header_pwd_h" "$ac_includes_default"
    if test "x$ac_cv_header_pwd_h" = xyes
    then :
      printf "%s\n" "#define HAVE_PWD_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default"
    if test "x$ac_cv_header_grp_h" = xyes
    then :
      printf "%s\n" "#define HAVE_GRP_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default"
    if test "x$ac_cv_header_strings_h" = xyes
    then :
      printf "%s\n" "#define HAVE_STRINGS_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/prctl.h" "ac_cv_header_sys_prctl_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_prctl_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_PRCTL_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/processor.h" "ac_cv_header_sys_processor_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_processor_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_PROCESSOR_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/sem.h" "ac_cv_header_sys_sem_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_sem_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_SEM_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_sdt_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_SDT_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/loadavg.h" "ac_cv_header_sys_loadavg_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_loadavg_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_LOADAVG_H 1" >>confdefs.h
    
    fi
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
    printf %s "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
    if test ${ac_cv_header_sys_wait_h+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <sys/types.h>
    #include <sys/wait.h>
    #ifndef WEXITSTATUS
    # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
    #endif
    #ifndef WIFEXITED
    # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
    #endif
    
    int
    main (void)
    {
      int s;
      wait (&s);
      s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_header_sys_wait_h=yes
    else $as_nop
      ac_cv_header_sys_wait_h=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
    printf "%s\n" "$ac_cv_header_sys_wait_h" >&6; }
    if test $ac_cv_header_sys_wait_h = yes; then
    
    printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
    
    fi
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
    printf %s "checking for an ANSI C-conforming const... " >&6; }
    if test ${ac_cv_c_const+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
    #ifndef __cplusplus
      /* Ultrix mips cc rejects this sort of thing.  */
      typedef int charset[2];
      const charset cs = { 0, 0 };
      /* SunOS 4.1.1 cc rejects this.  */
      char const *const *pcpcc;
      char **ppc;
      /* NEC SVR4.0.2 mips cc rejects this.  */
      struct point {int x, y;};
      static struct point const zero = {0,0};
      /* IBM XL C 1.02.0.0 rejects this.
         It does not let you subtract one const X* pointer from another in
         an arm of an if-expression whose if-part is not a constant
         expression */
      const char *g = "string";
      pcpcc = &g + (g ? g-g : 0);
      /* HPUX 7.0 cc rejects these. */
      ++pcpcc;
      ppc = (char**) pcpcc;
      pcpcc = (char const *const *) ppc;
      { /* SCO 3.2v4 cc rejects this sort of thing.  */
        char tx;
        char *t = &tx;
        char const *s = 0 ? (char *) 0 : (char const *) 0;
    
        *t++ = 0;
        if (s) return 0;
      }
      { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
        int x[] = {25, 17};
        const int *foo = &x[0];
        ++foo;
      }
      { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
        typedef const int *iptr;
        iptr p = 0;
        ++p;
      }
      { /* IBM XL C 1.02.0.0 rejects this sort of thing, saying
           "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
        struct s { int j; const int *ap[3]; } bx;
        struct s *b = &bx; b->j = 5;
      }
      { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
        const int foo = 10;
        if (!foo) return 0;
      }
      return !cs[0] && !zero.x;
    #endif
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_c_const=yes
    else $as_nop
      ac_cv_c_const=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
    printf "%s\n" "$ac_cv_c_const" >&6; }
    if test $ac_cv_c_const = no; then
    
    printf "%s\n" "#define const /**/" >>confdefs.h
    
    fi
    
    
    saved_LIBS="$LIBS"
    LIBS=""
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing sqrt" >&5
    printf %s "checking for library containing sqrt... " >&6; }
    if test ${ac_cv_search_sqrt+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_func_search_save_LIBS=$LIBS
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char sqrt ();
    int
    main (void)
    {
    return sqrt ();
      ;
      return 0;
    }
    _ACEOF
    for ac_lib in '' m
    do
      if test -z "$ac_lib"; then
        ac_res="none required"
      else
        ac_res=-l$ac_lib
        LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
      fi
      if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_search_sqrt=$ac_res
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext
      if test ${ac_cv_search_sqrt+y}
    then :
      break
    fi
    done
    if test ${ac_cv_search_sqrt+y}
    then :
    
    else $as_nop
      ac_cv_search_sqrt=no
    fi
    rm conftest.$ac_ext
    LIBS=$ac_func_search_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sqrt" >&5
    printf "%s\n" "$ac_cv_search_sqrt" >&6; }
    ac_res=$ac_cv_search_sqrt
    if test "$ac_res" != no
    then :
      test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
    
    fi
    
    MATH_LIBS="$LIBS"
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MATH_LIBS"
    
    
    LIBS="$saved_LIBS"
    
    saved_LIBS="$LIBS"
    LIBS=""
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5
    printf %s "checking for library containing crypt... " >&6; }
    if test ${ac_cv_search_crypt+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_func_search_save_LIBS=$LIBS
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char crypt ();
    int
    main (void)
    {
    return crypt ();
      ;
      return 0;
    }
    _ACEOF
    for ac_lib in '' crypt
    do
      if test -z "$ac_lib"; then
        ac_res="none required"
      else
        ac_res=-l$ac_lib
        LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
      fi
      if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_search_crypt=$ac_res
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext
      if test ${ac_cv_search_crypt+y}
    then :
      break
    fi
    done
    if test ${ac_cv_search_crypt+y}
    then :
    
    else $as_nop
      ac_cv_search_crypt=no
    fi
    rm conftest.$ac_ext
    LIBS=$ac_func_search_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5
    printf "%s\n" "$ac_cv_search_crypt" >&6; }
    ac_res=$ac_cv_search_crypt
    if test "$ac_res" != no
    then :
      test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
    
    fi
    
    CRYPT_LIBS="$LIBS"
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CRYPT_LIBS"
    
    
    
    if test "$ac_cv_search_crypt" != "no"; then
       # Test crypt() with the SHA-512 test vector from https://akkadia.org/drepper/SHA-crypt.txt
       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether crypt() supports SHA-2" >&5
    printf %s "checking whether crypt() supports SHA-2... " >&6; }
    if test ${ap_cv_crypt_sha2+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
        if test "$cross_compiling" = yes
    then :
      ap_cv_crypt_sha2=no
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <crypt.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define PASSWD_0 "Hello world!"
    #define SALT_0 "\$6\$saltstring"
    #define EXPECT_0 "\$6\$saltstring\$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" \
                   "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"
    
    int
    main (void)
    {
    char *result = crypt(PASSWD_0, SALT_0);
         if (!result) return 1;
         if (strcmp(result, EXPECT_0)) return 2;
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_run "$LINENO"
    then :
      ap_cv_crypt_sha2=yes
    else $as_nop
      ap_cv_crypt_sha2=no
    fi
    rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
      conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_cv_crypt_sha2" >&5
    printf "%s\n" "$ap_cv_crypt_sha2" >&6; }
       if test "$ap_cv_crypt_sha2" = yes; then
    
    printf "%s\n" "#define HAVE_CRYPT_SHA2 1" >>confdefs.h
    
       fi
    fi
    
    LIBS="$saved_LIBS"
    
    
    ac_fn_c_check_func "$LINENO" "getpwnam" "ac_cv_func_getpwnam"
    if test "x$ac_cv_func_getpwnam" = xyes
    then :
      printf "%s\n" "#define HAVE_GETPWNAM 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "getgrnam" "ac_cv_func_getgrnam"
    if test "x$ac_cv_func_getgrnam" = xyes
    then :
      printf "%s\n" "#define HAVE_GETGRNAM 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "initgroups" "ac_cv_func_initgroups"
    if test "x$ac_cv_func_initgroups" = xyes
    then :
      printf "%s\n" "#define HAVE_INITGROUPS 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "bindprocessor" "ac_cv_func_bindprocessor"
    if test "x$ac_cv_func_bindprocessor" = xyes
    then :
      printf "%s\n" "#define HAVE_BINDPROCESSOR 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "prctl" "ac_cv_func_prctl"
    if test "x$ac_cv_func_prctl" = xyes
    then :
      printf "%s\n" "#define HAVE_PRCTL 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm"
    if test "x$ac_cv_func_timegm" = xyes
    then :
      printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "getpgid" "ac_cv_func_getpgid"
    if test "x$ac_cv_func_getpgid" = xyes
    then :
      printf "%s\n" "#define HAVE_GETPGID 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "fopen64" "ac_cv_func_fopen64"
    if test "x$ac_cv_func_fopen64" = xyes
    then :
      printf "%s\n" "#define HAVE_FOPEN64 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "getloadavg" "ac_cv_func_getloadavg"
    if test "x$ac_cv_func_getloadavg" = xyes
    then :
      printf "%s\n" "#define HAVE_GETLOADAVG 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "gettid" "ac_cv_func_gettid"
    if test "x$ac_cv_func_gettid" = xyes
    then :
      printf "%s\n" "#define HAVE_GETTID 1" >>confdefs.h
    
    fi
    
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for void pointer length" >&5
    printf %s "checking for void pointer length... " >&6; }
    if test ${ap_cv_void_ptr_lt_long+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test "$cross_compiling" = yes
    then :
      ap_cv_void_ptr_lt_long=yes
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int main(void)
    {
        return sizeof(void *) < sizeof(long);
    }
    _ACEOF
    if ac_fn_c_try_run "$LINENO"
    then :
      ap_cv_void_ptr_lt_long=no
    else $as_nop
      ap_cv_void_ptr_lt_long=yes
    fi
    rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
      conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_cv_void_ptr_lt_long" >&5
    printf "%s\n" "$ap_cv_void_ptr_lt_long" >&6; }
    
    if test "$ap_cv_void_ptr_lt_long" = "yes"; then
        as_fn_error $? "Size of \"void *\" is less than size of \"long\"" "$LINENO" 5
    fi
    
    
    if test $ac_cv_func_gettid = no; then
      # On Linux before glibc 2.30, gettid() is only usable via syscall()
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gettid() via syscall" >&5
    printf %s "checking for gettid() via syscall... " >&6; }
    if test ${ap_cv_gettid+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      if test "$cross_compiling" = yes
    then :
      ap_cv_gettid=no
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #define _GNU_SOURCE
    #include <unistd.h>
    #include <sys/syscall.h>
    #include <sys/types.h>
    int main(int argc, char **argv) {
    pid_t t = syscall(SYS_gettid); return t == -1 ? 1 : 0; }
    _ACEOF
    if ac_fn_c_try_run "$LINENO"
    then :
      ap_cv_gettid=yes
    else $as_nop
      ap_cv_gettid=no
    fi
    rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
      conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_cv_gettid" >&5
    printf "%s\n" "$ap_cv_gettid" >&6; }
      if test "$ap_cv_gettid" = "yes"; then
    
    printf "%s\n" "#define HAVE_SYS_GETTID 1" >>confdefs.h
    
      fi
    fi
    
    case ${host}X${ac_cv_func_gettid}X${ap_cv_gettid} in
    *linux-*XyesX* | *linux-*XnoXyes)
    
    printf "%s\n" "#define DEFAULT_LOG_TID \"g\"" >>confdefs.h
    
         ;;
    esac
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff in struct tm" >&5
    printf %s "checking for tm_gmtoff in struct tm... " >&6; }
    if test ${ac_cv_struct_tm_gmtoff+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <sys/types.h>
    #include <time.h>
    int
    main (void)
    {
    struct tm tm; tm.tm_gmtoff;
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_struct_tm_gmtoff=yes
    else $as_nop
      ac_cv_struct_tm_gmtoff=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm_gmtoff" >&5
    printf "%s\n" "$ac_cv_struct_tm_gmtoff" >&6; }
    if test "$ac_cv_struct_tm_gmtoff" = "yes"; then
    
    printf "%s\n" "#define HAVE_GMTOFF 1" >>confdefs.h
    
    fi
    
    
    case $host in
    *-linux-*)
       if test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd; then
          SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd`
       elif test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd-daemon; then
          SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd-daemon`
       else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sd_notify in -lsystemd-daemon" >&5
    printf %s "checking for sd_notify in -lsystemd-daemon... " >&6; }
    if test ${ac_cv_lib_systemd_daemon_sd_notify+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-lsystemd-daemon  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char sd_notify ();
    int
    main (void)
    {
    return sd_notify ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_systemd_daemon_sd_notify=yes
    else $as_nop
      ac_cv_lib_systemd_daemon_sd_notify=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_daemon_sd_notify" >&5
    printf "%s\n" "$ac_cv_lib_systemd_daemon_sd_notify" >&6; }
    if test "x$ac_cv_lib_systemd_daemon_sd_notify" = xyes
    then :
      SYSTEMD_LIBS="-lsystemd-daemon"
    fi
    
       fi
       if test -n "$SYSTEMD_LIBS"; then
          ac_fn_c_check_header_compile "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default"
    if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYSTEMD_SD_DAEMON_H 1" >>confdefs.h
    
    fi
    
          if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Your system does not support systemd." >&5
    printf "%s\n" "$as_me: WARNING: Your system does not support systemd." >&2;}
          else
    
    printf "%s\n" "#define HAVE_SYSTEMD 1" >>confdefs.h
    
          fi
       fi
       ;;
    esac
    
    
    
    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
    
    
    # Check whether --with-port was given.
    if test ${with_port+y}
    then :
      withval=$with_port; if test "$withval" = "yes"; then as_fn_error $? "'option --with-port requires a value (the TCP port number)'" "$LINENO" 5; else PORT="$withval"; fi
    else $as_nop
      PORT=80
    fi
    
    
    
    # Check whether --with-sslport was given.
    if test ${with_sslport+y}
    then :
      withval=$with_sslport; if test "$withval" = "yes"; then as_fn_error $? "'option --with-sslport requires a value (the SSL TCP port number)'" "$LINENO" 5; else SSLPORT="$withval"; fi
    else $as_nop
      SSLPORT=443
    fi
    
    
    DTRACE=true
    # Check whether --enable-dtrace was given.
    if test ${enable_dtrace+y}
    then :
      enableval=$enable_dtrace;
      enable_dtrace=$enableval
      if test "$enableval" = "yes"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-DAPR_DTRACE_PROVIDER\""
        CPPFLAGS="-DAPR_DTRACE_PROVIDER"
      else
        apr_addto_bugger="-DAPR_DTRACE_PROVIDER"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
        as_fn_error $? "'DTrace Support in the build system is not complete. Patches Welcome!'" "$LINENO" 5
      fi
    
    else $as_nop
    
      enable_dtrace=no
    
    fi
    
    
    enable_dtrace=no
    
    case $host in
      *-solaris2*)
        if test $enable_dtrace = "yes" -a "$ac_cv_header_sys_sdt_h" = "yes"; then
    
    printf "%s\n" "#define AP_ENABLE_DTRACE 1" >>confdefs.h
    
            DTRACE="/usr/sbin/dtrace $DTRACEFLAGS"
            test -f include/apache_probes.h || $DTRACE -h -s apache_probes.d -o include/apache_probes.h
        fi
        ;;
    esac
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST DTRACE"
    
    
    
    # Check whether --enable-hook-probes was given.
    if test ${enable_hook_probes+y}
    then :
      enableval=$enable_hook_probes;
        if test "$enableval" = "yes"; then
    
    printf "%s\n" "#define AP_HOOK_PROBES_ENABLED 1" >>confdefs.h
    
    
      if test "x$INTERNAL_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INTERNAL_CPPFLAGS to \"-DAP_HOOK_PROBES_ENABLED\""
        INTERNAL_CPPFLAGS="-DAP_HOOK_PROBES_ENABLED"
      else
        apr_addto_bugger="-DAP_HOOK_PROBES_ENABLED"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INTERNAL_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INTERNAL_CPPFLAGS"
            INTERNAL_CPPFLAGS="$INTERNAL_CPPFLAGS $i"
          fi
        done
      fi
    
        fi
    
    fi
    
    # Check whether --enable-exception-hook was given.
    if test ${enable_exception_hook+y}
    then :
      enableval=$enable_exception_hook;
        if test "$enableval" = "yes"; then
    
    printf "%s\n" "#define AP_ENABLE_EXCEPTION_HOOK 1" >>confdefs.h
    
        fi
    
    fi
    
    # Check whether --enable-load-all-modules was given.
    if test ${enable_load_all_modules+y}
    then :
      enableval=$enable_load_all_modules;
      LOAD_ALL_MODULES=$enableval
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Setting \"LOAD_ALL_MODULES\" to $LOAD_ALL_MODULES" >&5
    printf "%s\n" "$as_me: Setting \"LOAD_ALL_MODULES\" to $LOAD_ALL_MODULES" >&6;}
    
    else $as_nop
    
      LOAD_ALL_MODULES="no"
    
    fi
    
    
    # Check whether --enable-maintainer-mode was given.
    if test ${enable_maintainer_mode+y}
    then :
      enableval=$enable_maintainer_mode;
      if test "$enableval" = "yes"; then
    
      if test "x$NOTEST_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CPPFLAGS to \"-DAP_DEBUG\""
        NOTEST_CPPFLAGS="-DAP_DEBUG"
      else
        apr_addto_bugger="-DAP_DEBUG"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CPPFLAGS"
            NOTEST_CPPFLAGS="$NOTEST_CPPFLAGS $i"
          fi
        done
      fi
    
        if test "$GCC" = "yes"; then
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -std=c89" >&5
    printf %s "checking whether gcc accepts -std=c89... " >&6; }
    if test ${ac_cv_gcc__std_c89+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -std=c89 -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__std_c89=yes
    else $as_nop
      ac_cv_gcc__std_c89=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__std_c89" >&5
    printf "%s\n" "$ac_cv_gcc__std_c89" >&6; }
        if test "$ac_cv_gcc__std_c89" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-std=c89\""
        NOTEST_CFLAGS="-std=c89"
      else
        apr_addto_bugger="-std=c89"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Werror" >&5
    printf %s "checking whether gcc accepts -Werror... " >&6; }
    if test ${ac_cv_gcc__Werror+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Werror -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Werror=yes
    else $as_nop
      ac_cv_gcc__Werror=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Werror" >&5
    printf "%s\n" "$ac_cv_gcc__Werror" >&6; }
        if test "$ac_cv_gcc__Werror" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Werror\""
        NOTEST_CFLAGS="-Werror"
      else
        apr_addto_bugger="-Werror"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wall" >&5
    printf %s "checking whether gcc accepts -Wall... " >&6; }
    if test ${ac_cv_gcc__Wall+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wall -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wall=yes
    else $as_nop
      ac_cv_gcc__Wall=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wall" >&5
    printf "%s\n" "$ac_cv_gcc__Wall" >&6; }
        if test "$ac_cv_gcc__Wall" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wall\""
        NOTEST_CFLAGS="-Wall"
      else
        apr_addto_bugger="-Wall"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wstrict-prototypes" >&5
    printf %s "checking whether gcc accepts -Wstrict-prototypes... " >&6; }
    if test ${ac_cv_gcc__Wstrict_prototypes+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wstrict-prototypes -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wstrict_prototypes=yes
    else $as_nop
      ac_cv_gcc__Wstrict_prototypes=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wstrict_prototypes" >&5
    printf "%s\n" "$ac_cv_gcc__Wstrict_prototypes" >&6; }
        if test "$ac_cv_gcc__Wstrict_prototypes" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wstrict-prototypes\""
        NOTEST_CFLAGS="-Wstrict-prototypes"
      else
        apr_addto_bugger="-Wstrict-prototypes"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wmissing-prototypes" >&5
    printf %s "checking whether gcc accepts -Wmissing-prototypes... " >&6; }
    if test ${ac_cv_gcc__Wmissing_prototypes+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wmissing-prototypes -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wmissing_prototypes=yes
    else $as_nop
      ac_cv_gcc__Wmissing_prototypes=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wmissing_prototypes" >&5
    printf "%s\n" "$ac_cv_gcc__Wmissing_prototypes" >&6; }
        if test "$ac_cv_gcc__Wmissing_prototypes" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wmissing-prototypes\""
        NOTEST_CFLAGS="-Wmissing-prototypes"
      else
        apr_addto_bugger="-Wmissing-prototypes"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wmissing-declarations" >&5
    printf %s "checking whether gcc accepts -Wmissing-declarations... " >&6; }
    if test ${ac_cv_gcc__Wmissing_declarations+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wmissing-declarations -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wmissing_declarations=yes
    else $as_nop
      ac_cv_gcc__Wmissing_declarations=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wmissing_declarations" >&5
    printf "%s\n" "$ac_cv_gcc__Wmissing_declarations" >&6; }
        if test "$ac_cv_gcc__Wmissing_declarations" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wmissing-declarations\""
        NOTEST_CFLAGS="-Wmissing-declarations"
      else
        apr_addto_bugger="-Wmissing-declarations"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wdeclaration-after-statement" >&5
    printf %s "checking whether gcc accepts -Wdeclaration-after-statement... " >&6; }
    if test ${ac_cv_gcc__Wdeclaration_after_statement+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wdeclaration-after-statement -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wdeclaration_after_statement=yes
    else $as_nop
      ac_cv_gcc__Wdeclaration_after_statement=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wdeclaration_after_statement" >&5
    printf "%s\n" "$ac_cv_gcc__Wdeclaration_after_statement" >&6; }
        if test "$ac_cv_gcc__Wdeclaration_after_statement" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wdeclaration-after-statement\""
        NOTEST_CFLAGS="-Wdeclaration-after-statement"
      else
        apr_addto_bugger="-Wdeclaration-after-statement"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wpointer-arith" >&5
    printf %s "checking whether gcc accepts -Wpointer-arith... " >&6; }
    if test ${ac_cv_gcc__Wpointer_arith+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wpointer-arith -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wpointer_arith=yes
    else $as_nop
      ac_cv_gcc__Wpointer_arith=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wpointer_arith" >&5
    printf "%s\n" "$ac_cv_gcc__Wpointer_arith" >&6; }
        if test "$ac_cv_gcc__Wpointer_arith" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wpointer-arith\""
        NOTEST_CFLAGS="-Wpointer-arith"
      else
        apr_addto_bugger="-Wpointer-arith"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wformat" >&5
    printf %s "checking whether gcc accepts -Wformat... " >&6; }
    if test ${ac_cv_gcc__Wformat+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wformat -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wformat=yes
    else $as_nop
      ac_cv_gcc__Wformat=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wformat" >&5
    printf "%s\n" "$ac_cv_gcc__Wformat" >&6; }
        if test "$ac_cv_gcc__Wformat" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wformat\""
        NOTEST_CFLAGS="-Wformat"
      else
        apr_addto_bugger="-Wformat"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wformat-security" >&5
    printf %s "checking whether gcc accepts -Wformat-security... " >&6; }
    if test ${ac_cv_gcc__Wformat_security+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wformat-security -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wformat_security=yes
    else $as_nop
      ac_cv_gcc__Wformat_security=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wformat_security" >&5
    printf "%s\n" "$ac_cv_gcc__Wformat_security" >&6; }
        if test "$ac_cv_gcc__Wformat_security" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wformat-security\""
        NOTEST_CFLAGS="-Wformat-security"
      else
        apr_addto_bugger="-Wformat-security"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wunused" >&5
    printf %s "checking whether gcc accepts -Wunused... " >&6; }
    if test ${ac_cv_gcc__Wunused+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wunused -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wunused=yes
    else $as_nop
      ac_cv_gcc__Wunused=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wunused" >&5
    printf "%s\n" "$ac_cv_gcc__Wunused" >&6; }
        if test "$ac_cv_gcc__Wunused" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wunused\""
        NOTEST_CFLAGS="-Wunused"
      else
        apr_addto_bugger="-Wunused"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
        elif test "$AIX_XLC" = "yes"; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-qfullpath -qcheck=all -qinfo=pro\""
        NOTEST_CFLAGS="-qfullpath -qcheck=all -qinfo=pro"
      else
        apr_addto_bugger="-qfullpath -qcheck=all -qinfo=pro"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
        if test "x$enable_load_all_modules" = "x"; then
          LOAD_ALL_MODULES=yes
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Maintainer mode setting \"LOAD_ALL_MODULES\" to $LOAD_ALL_MODULES" >&5
    printf "%s\n" "$as_me: Maintainer mode setting \"LOAD_ALL_MODULES\" to $LOAD_ALL_MODULES" >&6;}
        fi
        if test "x$enable_bucketeer" = "x"; then
          enable_bucketeer=yes
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Maintainer mode setting \"enable_bucketeer\" to yes" >&5
    printf "%s\n" "$as_me: Maintainer mode setting \"enable_bucketeer\" to yes" >&6;}
        fi
      fi
    
    fi
    
    # Check whether --enable-debugger-mode was given.
    if test ${enable_debugger_mode+y}
    then :
      enableval=$enable_debugger_mode;
      if test "$enableval" = "yes"; then
    
      if test "x$NOTEST_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CPPFLAGS to \"-DAP_DEBUG\""
        NOTEST_CPPFLAGS="-DAP_DEBUG"
      else
        apr_addto_bugger="-DAP_DEBUG"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CPPFLAGS"
            NOTEST_CPPFLAGS="$NOTEST_CPPFLAGS $i"
          fi
        done
      fi
    
        if test "$GCC" = "yes"; then
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -O0" >&5
    printf %s "checking whether gcc accepts -O0... " >&6; }
    if test ${ac_cv_gcc__O0+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -O0 -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__O0=yes
    else $as_nop
      ac_cv_gcc__O0=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__O0" >&5
    printf "%s\n" "$ac_cv_gcc__O0" >&6; }
        if test "$ac_cv_gcc__O0" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-O0\""
        NOTEST_CFLAGS="-O0"
      else
        apr_addto_bugger="-O0"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wall" >&5
    printf %s "checking whether gcc accepts -Wall... " >&6; }
    if test ${ac_cv_gcc__Wall+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wall -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wall=yes
    else $as_nop
      ac_cv_gcc__Wall=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wall" >&5
    printf "%s\n" "$ac_cv_gcc__Wall" >&6; }
        if test "$ac_cv_gcc__Wall" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wall\""
        NOTEST_CFLAGS="-Wall"
      else
        apr_addto_bugger="-Wall"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wstrict-prototypes" >&5
    printf %s "checking whether gcc accepts -Wstrict-prototypes... " >&6; }
    if test ${ac_cv_gcc__Wstrict_prototypes+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wstrict-prototypes -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wstrict_prototypes=yes
    else $as_nop
      ac_cv_gcc__Wstrict_prototypes=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wstrict_prototypes" >&5
    printf "%s\n" "$ac_cv_gcc__Wstrict_prototypes" >&6; }
        if test "$ac_cv_gcc__Wstrict_prototypes" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wstrict-prototypes\""
        NOTEST_CFLAGS="-Wstrict-prototypes"
      else
        apr_addto_bugger="-Wstrict-prototypes"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wmissing-prototypes" >&5
    printf %s "checking whether gcc accepts -Wmissing-prototypes... " >&6; }
    if test ${ac_cv_gcc__Wmissing_prototypes+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wmissing-prototypes -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wmissing_prototypes=yes
    else $as_nop
      ac_cv_gcc__Wmissing_prototypes=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wmissing_prototypes" >&5
    printf "%s\n" "$ac_cv_gcc__Wmissing_prototypes" >&6; }
        if test "$ac_cv_gcc__Wmissing_prototypes" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wmissing-prototypes\""
        NOTEST_CFLAGS="-Wmissing-prototypes"
      else
        apr_addto_bugger="-Wmissing-prototypes"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wmissing-declarations" >&5
    printf %s "checking whether gcc accepts -Wmissing-declarations... " >&6; }
    if test ${ac_cv_gcc__Wmissing_declarations+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wmissing-declarations -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wmissing_declarations=yes
    else $as_nop
      ac_cv_gcc__Wmissing_declarations=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wmissing_declarations" >&5
    printf "%s\n" "$ac_cv_gcc__Wmissing_declarations" >&6; }
        if test "$ac_cv_gcc__Wmissing_declarations" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wmissing-declarations\""
        NOTEST_CFLAGS="-Wmissing-declarations"
      else
        apr_addto_bugger="-Wmissing-declarations"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wdeclaration-after-statement" >&5
    printf %s "checking whether gcc accepts -Wdeclaration-after-statement... " >&6; }
    if test ${ac_cv_gcc__Wdeclaration_after_statement+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wdeclaration-after-statement -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wdeclaration_after_statement=yes
    else $as_nop
      ac_cv_gcc__Wdeclaration_after_statement=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wdeclaration_after_statement" >&5
    printf "%s\n" "$ac_cv_gcc__Wdeclaration_after_statement" >&6; }
        if test "$ac_cv_gcc__Wdeclaration_after_statement" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wdeclaration-after-statement\""
        NOTEST_CFLAGS="-Wdeclaration-after-statement"
      else
        apr_addto_bugger="-Wdeclaration-after-statement"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Werror=declaration-after-statement" >&5
    printf %s "checking whether gcc accepts -Werror=declaration-after-statement... " >&6; }
    if test ${ac_cv_gcc__Werror_declaration_after_statement+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Werror=declaration-after-statement -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Werror_declaration_after_statement=yes
    else $as_nop
      ac_cv_gcc__Werror_declaration_after_statement=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Werror_declaration_after_statement" >&5
    printf "%s\n" "$ac_cv_gcc__Werror_declaration_after_statement" >&6; }
        if test "$ac_cv_gcc__Werror_declaration_after_statement" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Werror=declaration-after-statement\""
        NOTEST_CFLAGS="-Werror=declaration-after-statement"
      else
        apr_addto_bugger="-Werror=declaration-after-statement"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wpointer-arith" >&5
    printf %s "checking whether gcc accepts -Wpointer-arith... " >&6; }
    if test ${ac_cv_gcc__Wpointer_arith+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wpointer-arith -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wpointer_arith=yes
    else $as_nop
      ac_cv_gcc__Wpointer_arith=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wpointer_arith" >&5
    printf "%s\n" "$ac_cv_gcc__Wpointer_arith" >&6; }
        if test "$ac_cv_gcc__Wpointer_arith" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wpointer-arith\""
        NOTEST_CFLAGS="-Wpointer-arith"
      else
        apr_addto_bugger="-Wpointer-arith"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wformat" >&5
    printf %s "checking whether gcc accepts -Wformat... " >&6; }
    if test ${ac_cv_gcc__Wformat+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wformat -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wformat=yes
    else $as_nop
      ac_cv_gcc__Wformat=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wformat" >&5
    printf "%s\n" "$ac_cv_gcc__Wformat" >&6; }
        if test "$ac_cv_gcc__Wformat" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wformat\""
        NOTEST_CFLAGS="-Wformat"
      else
        apr_addto_bugger="-Wformat"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Wformat-security" >&5
    printf %s "checking whether gcc accepts -Wformat-security... " >&6; }
    if test ${ac_cv_gcc__Wformat_security+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Wformat-security -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Wformat_security=yes
    else $as_nop
      ac_cv_gcc__Wformat_security=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Wformat_security" >&5
    printf "%s\n" "$ac_cv_gcc__Wformat_security" >&6; }
        if test "$ac_cv_gcc__Wformat_security" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Wformat-security\""
        NOTEST_CFLAGS="-Wformat-security"
      else
        apr_addto_bugger="-Wformat-security"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
    
    
      if test "$GCC" = "yes"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gcc accepts -Werror=format-security" >&5
    printf %s "checking whether gcc accepts -Werror=format-security... " >&6; }
    if test ${ac_cv_gcc__Werror_format_security+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          save_CFLAGS="$CFLAGS"
          CFLAGS="$CFLAGS -Werror=format-security -Wno-strict-prototypes"
          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ac_cv_gcc__Werror_format_security=yes
    else $as_nop
      ac_cv_gcc__Werror_format_security=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          CFLAGS="$save_CFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc__Werror_format_security" >&5
    printf "%s\n" "$ac_cv_gcc__Werror_format_security" >&6; }
        if test "$ac_cv_gcc__Werror_format_security" = "yes" ; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-Werror=format-security\""
        NOTEST_CFLAGS="-Werror=format-security"
      else
        apr_addto_bugger="-Werror=format-security"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    
        elif test "$AIX_XLC" = "yes"; then
    
      if test "x$NOTEST_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting NOTEST_CFLAGS to \"-qfullpath -qinitauto=FE -qcheck=all -qinfo=pro\""
        NOTEST_CFLAGS="-qfullpath -qinitauto=FE -qcheck=all -qinfo=pro"
      else
        apr_addto_bugger="-qfullpath -qinitauto=FE -qcheck=all -qinfo=pro"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $NOTEST_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to NOTEST_CFLAGS"
            NOTEST_CFLAGS="$NOTEST_CFLAGS $i"
          fi
        done
      fi
    
        fi
      fi
    
    fi
    
    # Check whether --enable-pie was given.
    if test ${enable_pie+y}
    then :
      enableval=$enable_pie;
    fi
    
    if test "$enable_pie" = "yes"; then
       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts PIE flags" >&5
    printf %s "checking whether $CC accepts PIE flags... " >&6; }
    if test ${ap_cv_cc_pie+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
         save_CFLAGS=$CFLAGS
         save_LDFLAGS=$LDFLAGS
         CFLAGS="$CFLAGS -fPIE"
         LDFLAGS="$LDFLAGS -pie"
         if test "$cross_compiling" = yes
    then :
      ap_cv_cc_pie=yes
    else $as_nop
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    static int foo[30000]; int main () { return 0; }
    _ACEOF
    if ac_fn_c_try_run "$LINENO"
    then :
      ap_cv_cc_pie=yes
    else $as_nop
      ap_cv_cc_pie=no
    fi
    rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
      conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    
         CFLAGS=$save_CFLAGS
         LDFLAGS=$save_LDFLAGS
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_cv_cc_pie" >&5
    printf "%s\n" "$ap_cv_cc_pie" >&6; }
       if test "$ap_cv_cc_pie" = "yes"; then
         PICFLAGS="-fPIE"
         PILDFLAGS="-pie"
       else
         as_fn_error $? "--enable-pie requested but $CC failed using PIE flags" "$LINENO" 5
       fi
    fi
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST PICFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST PILDFLAGS"
    
    
    
    prefix="$orig_prefix"
    
      module_selection=most
      module_default=shared
    
    
    apr_old_cppflags=$CPPFLAGS
    CPPFLAGS="$CPPFLAGS $INCLUDES"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr.h>
    #if APR_HAS_DSO
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_define_APR_HAS_DSO=yes
    else $as_nop
      ac_cv_define_APR_HAS_DSO=no
    fi
    rm -rf conftest*
    
    CPPFLAGS=$apr_old_cppflags
    
    
      if test $ac_cv_define_APR_HAS_DSO = "no"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Missing DSO support - building static modules by default." >&5
    printf "%s\n" "$as_me: WARNING: Missing DSO support - building static modules by default." >&2;}
        module_default=static
      fi
    
    
      # Check whether --enable-modules was given.
    if test ${enable_modules+y}
    then :
      enableval=$enable_modules;
        if test "$enableval" = "none"; then
           module_default=no
           module_selection=none
        else
          for i in $enableval; do
            if test "$i" = "all" -o "$i" = "most" -o "$i" = "few" -o "$i" = "reallyall"
            then
              module_selection=$i
            else
              i=`echo $i | sed 's/-/_/g'`
              eval "enable_$i=shared"
            fi
          done
        fi
    
    fi
    
    
      # Check whether --enable-mods-shared was given.
    if test ${enable_mods_shared+y}
    then :
      enableval=$enable_mods_shared;
        for i in $enableval; do
          if test "$i" = "all" -o "$i" = "most" -o "$i" = "few" -o "$i" = "reallyall"
          then
            module_selection=$i
            module_default=shared
          else
            i=`echo $i | sed 's/-/_/g'`
        	eval "enable_$i=shared"
          fi
        done
    
    fi
    
    
      # Check whether --enable-mods-static was given.
    if test ${enable_mods_static+y}
    then :
      enableval=$enable_mods_static;
        for i in $enableval; do
          if test "$i" = "all" -o "$i" = "most" -o "$i" = "few" -o "$i" = "reallyall"; then
            module_selection=$i
            module_default=static
          else
            i=`echo $i | sed 's/-/_/g'`
        	eval "enable_$i=static"
          fi
        done
    
    fi
    
    
    
    
    
    
    
      current_dir=aaa
      modpath_current=modules/aaa
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d aaa || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authn_file" >&5
    printf %s "checking whether to enable mod_authn_file... " >&6; }
        # Check whether --enable-authn-file was given.
    if test ${enable_authn_file+y}
    then :
      enableval=$enable_authn_file; force_authn_file=$enableval
    else $as_nop
      enable_authn_file=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_authn_file" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authn_file" = "static" -o "$enable_authn_file" = "shared"; then
        :
      elif test "$enable_authn_file" = "yes"; then
        enable_authn_file=$module_default
      elif test "$enable_authn_file" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_file=$module_default
        else
          enable_authn_file=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_file" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authn_file=$module_default
        else
          enable_authn_file=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_file" = "all" -o "$enable_authn_file" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_file=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_file=no
        fi
      elif test "$enable_authn_file" = "reallyall" -o "$enable_authn_file" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authn_file" != "no" ; then
          enable_authn_file=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_file=no
        fi
      else
        enable_authn_file=no
      fi
      if test "$enable_authn_file" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authn_file$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authn_file$_apmod_extra_msg" >&6; }
      if test "$enable_authn_file" != "no"; then
        case "$enable_authn_file" in
        static*)
          MODLIST="$MODLIST authn_file"
          if test "authn_file" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authn_file"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authn_file"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authn_file.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authn_file.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHN_FILE_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHN_FILE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHN_FILE_LDADD)\""
        AP_LIBS="\$(MOD_AUTHN_FILE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHN_FILE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authn_file.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  $objects \$(MOD_AUTHN_FILE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHN_FILE_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authn_dbm" >&5
    printf %s "checking whether to enable mod_authn_dbm... " >&6; }
        # Check whether --enable-authn-dbm was given.
    if test ${enable_authn_dbm+y}
    then :
      enableval=$enable_authn_dbm; force_authn_dbm=$enableval
    else $as_nop
      enable_authn_dbm=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authn_dbm" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authn_dbm" = "static" -o "$enable_authn_dbm" = "shared"; then
        :
      elif test "$enable_authn_dbm" = "yes"; then
        enable_authn_dbm=$module_default
      elif test "$enable_authn_dbm" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_dbm=$module_default
        else
          enable_authn_dbm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_dbm" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authn_dbm=$module_default
        else
          enable_authn_dbm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_dbm" = "all" -o "$enable_authn_dbm" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_dbm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_dbm=no
        fi
      elif test "$enable_authn_dbm" = "reallyall" -o "$enable_authn_dbm" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authn_dbm" != "no" ; then
          enable_authn_dbm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_dbm=no
        fi
      else
        enable_authn_dbm=no
      fi
      if test "$enable_authn_dbm" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authn_dbm$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authn_dbm$_apmod_extra_msg" >&6; }
      if test "$enable_authn_dbm" != "no"; then
        case "$enable_authn_dbm" in
        static*)
          MODLIST="$MODLIST authn_dbm"
          if test "authn_dbm" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authn_dbm"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authn_dbm"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authn_dbm.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authn_dbm.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHN_DBM_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHN_DBM_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHN_DBM_LDADD)\""
        AP_LIBS="\$(MOD_AUTHN_DBM_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHN_DBM_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authn_dbm.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  $objects \$(MOD_AUTHN_DBM_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHN_DBM_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authn_anon" >&5
    printf %s "checking whether to enable mod_authn_anon... " >&6; }
        # Check whether --enable-authn-anon was given.
    if test ${enable_authn_anon+y}
    then :
      enableval=$enable_authn_anon; force_authn_anon=$enableval
    else $as_nop
      enable_authn_anon=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authn_anon" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authn_anon" = "static" -o "$enable_authn_anon" = "shared"; then
        :
      elif test "$enable_authn_anon" = "yes"; then
        enable_authn_anon=$module_default
      elif test "$enable_authn_anon" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_anon=$module_default
        else
          enable_authn_anon=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_anon" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authn_anon=$module_default
        else
          enable_authn_anon=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_anon" = "all" -o "$enable_authn_anon" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_anon=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_anon=no
        fi
      elif test "$enable_authn_anon" = "reallyall" -o "$enable_authn_anon" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authn_anon" != "no" ; then
          enable_authn_anon=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_anon=no
        fi
      else
        enable_authn_anon=no
      fi
      if test "$enable_authn_anon" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authn_anon$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authn_anon$_apmod_extra_msg" >&6; }
      if test "$enable_authn_anon" != "no"; then
        case "$enable_authn_anon" in
        static*)
          MODLIST="$MODLIST authn_anon"
          if test "authn_anon" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authn_anon"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authn_anon"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authn_anon.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authn_anon.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHN_ANON_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHN_ANON_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHN_ANON_LDADD)\""
        AP_LIBS="\$(MOD_AUTHN_ANON_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHN_ANON_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authn_anon.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  $objects \$(MOD_AUTHN_ANON_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHN_ANON_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authn_dbd" >&5
    printf %s "checking whether to enable mod_authn_dbd... " >&6; }
        # Check whether --enable-authn-dbd was given.
    if test ${enable_authn_dbd+y}
    then :
      enableval=$enable_authn_dbd; force_authn_dbd=$enableval
    else $as_nop
      enable_authn_dbd=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authn_dbd" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authn_dbd" = "static" -o "$enable_authn_dbd" = "shared"; then
        :
      elif test "$enable_authn_dbd" = "yes"; then
        enable_authn_dbd=$module_default
      elif test "$enable_authn_dbd" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_dbd=$module_default
        else
          enable_authn_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_dbd" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authn_dbd=$module_default
        else
          enable_authn_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_dbd" = "all" -o "$enable_authn_dbd" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_dbd=no
        fi
      elif test "$enable_authn_dbd" = "reallyall" -o "$enable_authn_dbd" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authn_dbd" != "no" ; then
          enable_authn_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_dbd=no
        fi
      else
        enable_authn_dbd=no
      fi
      if test "$enable_authn_dbd" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authn_dbd$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authn_dbd$_apmod_extra_msg" >&6; }
      if test "$enable_authn_dbd" != "no"; then
        case "$enable_authn_dbd" in
        static*)
          MODLIST="$MODLIST authn_dbd"
          if test "authn_dbd" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authn_dbd"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authn_dbd"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authn_dbd.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authn_dbd.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHN_DBD_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHN_DBD_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHN_DBD_LDADD)\""
        AP_LIBS="\$(MOD_AUTHN_DBD_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHN_DBD_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authn_dbd.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  $objects \$(MOD_AUTHN_DBD_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHN_DBD_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authn_socache" >&5
    printf %s "checking whether to enable mod_authn_socache... " >&6; }
        # Check whether --enable-authn-socache was given.
    if test ${enable_authn_socache+y}
    then :
      enableval=$enable_authn_socache; force_authn_socache=$enableval
    else $as_nop
      enable_authn_socache=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authn_socache" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authn_socache" = "static" -o "$enable_authn_socache" = "shared"; then
        :
      elif test "$enable_authn_socache" = "yes"; then
        enable_authn_socache=$module_default
      elif test "$enable_authn_socache" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_socache=$module_default
        else
          enable_authn_socache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_socache" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authn_socache=$module_default
        else
          enable_authn_socache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_socache" = "all" -o "$enable_authn_socache" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_socache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_socache=no
        fi
      elif test "$enable_authn_socache" = "reallyall" -o "$enable_authn_socache" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authn_socache" != "no" ; then
          enable_authn_socache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_socache=no
        fi
      else
        enable_authn_socache=no
      fi
      if test "$enable_authn_socache" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authn_socache$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authn_socache$_apmod_extra_msg" >&6; }
      if test "$enable_authn_socache" != "no"; then
        case "$enable_authn_socache" in
        static*)
          MODLIST="$MODLIST authn_socache"
          if test "authn_socache" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authn_socache"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authn_socache"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authn_socache.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authn_socache.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHN_SOCACHE_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHN_SOCACHE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHN_SOCACHE_LDADD)\""
        AP_LIBS="\$(MOD_AUTHN_SOCACHE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHN_SOCACHE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authn_socache.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  $objects \$(MOD_AUTHN_SOCACHE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHN_SOCACHE_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authn_core" >&5
    printf %s "checking whether to enable mod_authn_core... " >&6; }
        # Check whether --enable-authn-core was given.
    if test ${enable_authn_core+y}
    then :
      enableval=$enable_authn_core; force_authn_core=$enableval
    else $as_nop
      enable_authn_core=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_authn_core" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authn_core" = "static" -o "$enable_authn_core" = "shared"; then
        :
      elif test "$enable_authn_core" = "yes"; then
        enable_authn_core=$module_default
      elif test "$enable_authn_core" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_core=$module_default
        else
          enable_authn_core=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_core" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authn_core=$module_default
        else
          enable_authn_core=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authn_core" = "all" -o "$enable_authn_core" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authn_core=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_core=no
        fi
      elif test "$enable_authn_core" = "reallyall" -o "$enable_authn_core" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authn_core" != "no" ; then
          enable_authn_core=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authn_core=no
        fi
      else
        enable_authn_core=no
      fi
      if test "$enable_authn_core" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authn_core$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authn_core$_apmod_extra_msg" >&6; }
      if test "$enable_authn_core" != "no"; then
        case "$enable_authn_core" in
        static*)
          MODLIST="$MODLIST authn_core"
          if test "authn_core" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authn_core"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authn_core"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authn_core.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authn_core.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHN_CORE_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHN_CORE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHN_CORE_LDADD)\""
        AP_LIBS="\$(MOD_AUTHN_CORE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHN_CORE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authn_core.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  $objects \$(MOD_AUTHN_CORE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHN_CORE_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authz_host" >&5
    printf %s "checking whether to enable mod_authz_host... " >&6; }
        # Check whether --enable-authz-host was given.
    if test ${enable_authz_host+y}
    then :
      enableval=$enable_authz_host; force_authz_host=$enableval
    else $as_nop
      enable_authz_host=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_authz_host" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authz_host" = "static" -o "$enable_authz_host" = "shared"; then
        :
      elif test "$enable_authz_host" = "yes"; then
        enable_authz_host=$module_default
      elif test "$enable_authz_host" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_host=$module_default
        else
          enable_authz_host=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_host" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authz_host=$module_default
        else
          enable_authz_host=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_host" = "all" -o "$enable_authz_host" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_host=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_host=no
        fi
      elif test "$enable_authz_host" = "reallyall" -o "$enable_authz_host" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authz_host" != "no" ; then
          enable_authz_host=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_host=no
        fi
      else
        enable_authz_host=no
      fi
      if test "$enable_authz_host" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authz_host$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authz_host$_apmod_extra_msg" >&6; }
      if test "$enable_authz_host" != "no"; then
        case "$enable_authz_host" in
        static*)
          MODLIST="$MODLIST authz_host"
          if test "authz_host" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authz_host"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authz_host"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authz_host.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authz_host.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHZ_HOST_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHZ_HOST_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHZ_HOST_LDADD)\""
        AP_LIBS="\$(MOD_AUTHZ_HOST_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHZ_HOST_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authz_host.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  $objects \$(MOD_AUTHZ_HOST_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHZ_HOST_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authz_groupfile" >&5
    printf %s "checking whether to enable mod_authz_groupfile... " >&6; }
        # Check whether --enable-authz-groupfile was given.
    if test ${enable_authz_groupfile+y}
    then :
      enableval=$enable_authz_groupfile; force_authz_groupfile=$enableval
    else $as_nop
      enable_authz_groupfile=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_authz_groupfile" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authz_groupfile" = "static" -o "$enable_authz_groupfile" = "shared"; then
        :
      elif test "$enable_authz_groupfile" = "yes"; then
        enable_authz_groupfile=$module_default
      elif test "$enable_authz_groupfile" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_groupfile=$module_default
        else
          enable_authz_groupfile=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_groupfile" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authz_groupfile=$module_default
        else
          enable_authz_groupfile=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_groupfile" = "all" -o "$enable_authz_groupfile" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_groupfile=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_groupfile=no
        fi
      elif test "$enable_authz_groupfile" = "reallyall" -o "$enable_authz_groupfile" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authz_groupfile" != "no" ; then
          enable_authz_groupfile=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_groupfile=no
        fi
      else
        enable_authz_groupfile=no
      fi
      if test "$enable_authz_groupfile" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authz_groupfile$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authz_groupfile$_apmod_extra_msg" >&6; }
      if test "$enable_authz_groupfile" != "no"; then
        case "$enable_authz_groupfile" in
        static*)
          MODLIST="$MODLIST authz_groupfile"
          if test "authz_groupfile" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authz_groupfile"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authz_groupfile"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authz_groupfile.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authz_groupfile.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHZ_GROUPFILE_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHZ_GROUPFILE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHZ_GROUPFILE_LDADD)\""
        AP_LIBS="\$(MOD_AUTHZ_GROUPFILE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHZ_GROUPFILE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authz_groupfile.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  $objects \$(MOD_AUTHZ_GROUPFILE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHZ_GROUPFILE_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authz_user" >&5
    printf %s "checking whether to enable mod_authz_user... " >&6; }
        # Check whether --enable-authz-user was given.
    if test ${enable_authz_user+y}
    then :
      enableval=$enable_authz_user; force_authz_user=$enableval
    else $as_nop
      enable_authz_user=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_authz_user" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authz_user" = "static" -o "$enable_authz_user" = "shared"; then
        :
      elif test "$enable_authz_user" = "yes"; then
        enable_authz_user=$module_default
      elif test "$enable_authz_user" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_user=$module_default
        else
          enable_authz_user=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_user" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authz_user=$module_default
        else
          enable_authz_user=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_user" = "all" -o "$enable_authz_user" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_user=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_user=no
        fi
      elif test "$enable_authz_user" = "reallyall" -o "$enable_authz_user" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authz_user" != "no" ; then
          enable_authz_user=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_user=no
        fi
      else
        enable_authz_user=no
      fi
      if test "$enable_authz_user" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authz_user$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authz_user$_apmod_extra_msg" >&6; }
      if test "$enable_authz_user" != "no"; then
        case "$enable_authz_user" in
        static*)
          MODLIST="$MODLIST authz_user"
          if test "authz_user" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authz_user"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authz_user"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authz_user.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authz_user.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHZ_USER_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHZ_USER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHZ_USER_LDADD)\""
        AP_LIBS="\$(MOD_AUTHZ_USER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHZ_USER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authz_user.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  $objects \$(MOD_AUTHZ_USER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHZ_USER_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authz_dbm" >&5
    printf %s "checking whether to enable mod_authz_dbm... " >&6; }
        # Check whether --enable-authz-dbm was given.
    if test ${enable_authz_dbm+y}
    then :
      enableval=$enable_authz_dbm; force_authz_dbm=$enableval
    else $as_nop
      enable_authz_dbm=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authz_dbm" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authz_dbm" = "static" -o "$enable_authz_dbm" = "shared"; then
        :
      elif test "$enable_authz_dbm" = "yes"; then
        enable_authz_dbm=$module_default
      elif test "$enable_authz_dbm" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_dbm=$module_default
        else
          enable_authz_dbm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_dbm" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authz_dbm=$module_default
        else
          enable_authz_dbm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_dbm" = "all" -o "$enable_authz_dbm" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_dbm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_dbm=no
        fi
      elif test "$enable_authz_dbm" = "reallyall" -o "$enable_authz_dbm" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authz_dbm" != "no" ; then
          enable_authz_dbm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_dbm=no
        fi
      else
        enable_authz_dbm=no
      fi
      if test "$enable_authz_dbm" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authz_dbm$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authz_dbm$_apmod_extra_msg" >&6; }
      if test "$enable_authz_dbm" != "no"; then
        case "$enable_authz_dbm" in
        static*)
          MODLIST="$MODLIST authz_dbm"
          if test "authz_dbm" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authz_dbm"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authz_dbm"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authz_dbm.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authz_dbm.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHZ_DBM_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHZ_DBM_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHZ_DBM_LDADD)\""
        AP_LIBS="\$(MOD_AUTHZ_DBM_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHZ_DBM_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authz_dbm.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  $objects \$(MOD_AUTHZ_DBM_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHZ_DBM_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authz_owner" >&5
    printf %s "checking whether to enable mod_authz_owner... " >&6; }
        # Check whether --enable-authz-owner was given.
    if test ${enable_authz_owner+y}
    then :
      enableval=$enable_authz_owner; force_authz_owner=$enableval
    else $as_nop
      enable_authz_owner=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authz_owner" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authz_owner" = "static" -o "$enable_authz_owner" = "shared"; then
        :
      elif test "$enable_authz_owner" = "yes"; then
        enable_authz_owner=$module_default
      elif test "$enable_authz_owner" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_owner=$module_default
        else
          enable_authz_owner=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_owner" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authz_owner=$module_default
        else
          enable_authz_owner=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_owner" = "all" -o "$enable_authz_owner" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_owner=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_owner=no
        fi
      elif test "$enable_authz_owner" = "reallyall" -o "$enable_authz_owner" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authz_owner" != "no" ; then
          enable_authz_owner=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_owner=no
        fi
      else
        enable_authz_owner=no
      fi
      if test "$enable_authz_owner" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authz_owner$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authz_owner$_apmod_extra_msg" >&6; }
      if test "$enable_authz_owner" != "no"; then
        case "$enable_authz_owner" in
        static*)
          MODLIST="$MODLIST authz_owner"
          if test "authz_owner" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authz_owner"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authz_owner"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authz_owner.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authz_owner.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHZ_OWNER_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHZ_OWNER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHZ_OWNER_LDADD)\""
        AP_LIBS="\$(MOD_AUTHZ_OWNER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHZ_OWNER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authz_owner.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  $objects \$(MOD_AUTHZ_OWNER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHZ_OWNER_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authz_dbd" >&5
    printf %s "checking whether to enable mod_authz_dbd... " >&6; }
        # Check whether --enable-authz-dbd was given.
    if test ${enable_authz_dbd+y}
    then :
      enableval=$enable_authz_dbd; force_authz_dbd=$enableval
    else $as_nop
      enable_authz_dbd=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authz_dbd" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authz_dbd" = "static" -o "$enable_authz_dbd" = "shared"; then
        :
      elif test "$enable_authz_dbd" = "yes"; then
        enable_authz_dbd=$module_default
      elif test "$enable_authz_dbd" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_dbd=$module_default
        else
          enable_authz_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_dbd" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authz_dbd=$module_default
        else
          enable_authz_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_dbd" = "all" -o "$enable_authz_dbd" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_dbd=no
        fi
      elif test "$enable_authz_dbd" = "reallyall" -o "$enable_authz_dbd" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authz_dbd" != "no" ; then
          enable_authz_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_dbd=no
        fi
      else
        enable_authz_dbd=no
      fi
      if test "$enable_authz_dbd" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authz_dbd$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authz_dbd$_apmod_extra_msg" >&6; }
      if test "$enable_authz_dbd" != "no"; then
        case "$enable_authz_dbd" in
        static*)
          MODLIST="$MODLIST authz_dbd"
          if test "authz_dbd" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authz_dbd"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authz_dbd"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authz_dbd.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authz_dbd.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHZ_DBD_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHZ_DBD_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHZ_DBD_LDADD)\""
        AP_LIBS="\$(MOD_AUTHZ_DBD_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHZ_DBD_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authz_dbd.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  $objects \$(MOD_AUTHZ_DBD_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHZ_DBD_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authz_core" >&5
    printf %s "checking whether to enable mod_authz_core... " >&6; }
        # Check whether --enable-authz-core was given.
    if test ${enable_authz_core+y}
    then :
      enableval=$enable_authz_core; force_authz_core=$enableval
    else $as_nop
      enable_authz_core=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_authz_core" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authz_core" = "static" -o "$enable_authz_core" = "shared"; then
        :
      elif test "$enable_authz_core" = "yes"; then
        enable_authz_core=$module_default
      elif test "$enable_authz_core" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_core=$module_default
        else
          enable_authz_core=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_core" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authz_core=$module_default
        else
          enable_authz_core=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authz_core" = "all" -o "$enable_authz_core" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authz_core=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_core=no
        fi
      elif test "$enable_authz_core" = "reallyall" -o "$enable_authz_core" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authz_core" != "no" ; then
          enable_authz_core=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authz_core=no
        fi
      else
        enable_authz_core=no
      fi
      if test "$enable_authz_core" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authz_core$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authz_core$_apmod_extra_msg" >&6; }
      if test "$enable_authz_core" != "no"; then
        case "$enable_authz_core" in
        static*)
          MODLIST="$MODLIST authz_core"
          if test "authz_core" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authz_core"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authz_core"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authz_core.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authz_core.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHZ_CORE_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHZ_CORE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHZ_CORE_LDADD)\""
        AP_LIBS="\$(MOD_AUTHZ_CORE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHZ_CORE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authz_core.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  $objects \$(MOD_AUTHZ_CORE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHZ_CORE_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authnz_ldap" >&5
    printf %s "checking whether to enable mod_authnz_ldap... " >&6; }
        # Check whether --enable-authnz-ldap was given.
    if test ${enable_authnz_ldap+y}
    then :
      enableval=$enable_authnz_ldap; force_authnz_ldap=$enableval
    else $as_nop
      enable_authnz_ldap=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_authnz_ldap" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authnz_ldap" = "static" -o "$enable_authnz_ldap" = "shared"; then
        :
      elif test "$enable_authnz_ldap" = "yes"; then
        enable_authnz_ldap=$module_default
      elif test "$enable_authnz_ldap" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authnz_ldap=$module_default
        else
          enable_authnz_ldap=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authnz_ldap" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authnz_ldap=$module_default
        else
          enable_authnz_ldap=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authnz_ldap" = "all" -o "$enable_authnz_ldap" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authnz_ldap=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authnz_ldap=no
        fi
      elif test "$enable_authnz_ldap" = "reallyall" -o "$enable_authnz_ldap" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authnz_ldap" != "no" ; then
          enable_authnz_ldap=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authnz_ldap=no
        fi
      else
        enable_authnz_ldap=no
      fi
      if test "$enable_authnz_ldap" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ldap support in apr/apr-util" >&5
    printf %s "checking for ldap support in apr/apr-util... " >&6; }
    if test ${ac_cv_APR_HAS_LDAP+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
        apache_old_cppflags="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS $INCLUDES"
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr_ldap.h>
    #if APR_HAS_LDAP
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_APR_HAS_LDAP=yes
    else $as_nop
      ac_cv_APR_HAS_LDAP=no
    fi
    rm -rf conftest*
    
        CPPFLAGS="$apache_old_cppflags"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_APR_HAS_LDAP" >&5
    printf "%s\n" "$ac_cv_APR_HAS_LDAP" >&6; }
    
      if test "$ac_cv_APR_HAS_LDAP" = "yes" ; then
        if test -z "$apu_config" ; then
          LDAP_LIBS="`$apr_config --ldap-libs`"
        else
          LDAP_LIBS="`$apu_config --ldap-libs`"
        fi
    
      if test "x$MOD_AUTHNZ_LDAP_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_AUTHNZ_LDAP_LDADD to \"$LDAP_LIBS\""
        MOD_AUTHNZ_LDAP_LDADD="$LDAP_LIBS"
      else
        apr_addto_bugger="$LDAP_LIBS"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_AUTHNZ_LDAP_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_AUTHNZ_LDAP_LDADD"
            MOD_AUTHNZ_LDAP_LDADD="$MOD_AUTHNZ_LDAP_LDADD $i"
          fi
        done
      fi
    
    
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: apr/apr-util is compiled without ldap support" >&5
    printf "%s\n" "$as_me: WARNING: apr/apr-util is compiled without ldap support" >&2;}
        enable_authnz_ldap=no
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authnz_ldap" >&5
    printf %s "checking whether to enable mod_authnz_ldap... " >&6; }
                if test "$enable_authnz_ldap" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_authnz_ldap has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authnz_ldap$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authnz_ldap$_apmod_extra_msg" >&6; }
      if test "$enable_authnz_ldap" != "no"; then
        case "$enable_authnz_ldap" in
        static*)
          MODLIST="$MODLIST authnz_ldap"
          if test "authnz_ldap" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authnz_ldap"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authnz_ldap"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authnz_ldap.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authnz_ldap.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHNZ_LDAP_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHNZ_LDAP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHNZ_LDAP_LDADD)\""
        AP_LIBS="\$(MOD_AUTHNZ_LDAP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHNZ_LDAP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authnz_ldap.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  $objects \$(MOD_AUTHNZ_LDAP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHNZ_LDAP_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_authnz_fcgi" >&5
    printf %s "checking whether to enable mod_authnz_fcgi... " >&6; }
        # Check whether --enable-authnz-fcgi was given.
    if test ${enable_authnz_fcgi+y}
    then :
      enableval=$enable_authnz_fcgi; force_authnz_fcgi=$enableval
    else $as_nop
      enable_authnz_fcgi=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_authnz_fcgi" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_authnz_fcgi" = "static" -o "$enable_authnz_fcgi" = "shared"; then
        :
      elif test "$enable_authnz_fcgi" = "yes"; then
        enable_authnz_fcgi=$module_default
      elif test "$enable_authnz_fcgi" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authnz_fcgi=$module_default
        else
          enable_authnz_fcgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authnz_fcgi" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_authnz_fcgi=$module_default
        else
          enable_authnz_fcgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_authnz_fcgi" = "all" -o "$enable_authnz_fcgi" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_authnz_fcgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authnz_fcgi=no
        fi
      elif test "$enable_authnz_fcgi" = "reallyall" -o "$enable_authnz_fcgi" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_authnz_fcgi" != "no" ; then
          enable_authnz_fcgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_authnz_fcgi=no
        fi
      else
        enable_authnz_fcgi=no
      fi
      if test "$enable_authnz_fcgi" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_authnz_fcgi$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_authnz_fcgi$_apmod_extra_msg" >&6; }
      if test "$enable_authnz_fcgi" != "no"; then
        case "$enable_authnz_fcgi" in
        static*)
          MODLIST="$MODLIST authnz_fcgi"
          if test "authnz_fcgi" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES authnz_fcgi"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},authnz_fcgi"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_authnz_fcgi.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_authnz_fcgi.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTHNZ_FCGI_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTHNZ_FCGI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTHNZ_FCGI_LDADD)\""
        AP_LIBS="\$(MOD_AUTHNZ_FCGI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTHNZ_FCGI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_authnz_fcgi.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  $objects \$(MOD_AUTHNZ_FCGI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTHNZ_FCGI_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_access_compat" >&5
    printf %s "checking whether to enable mod_access_compat... " >&6; }
        # Check whether --enable-access-compat was given.
    if test ${enable_access_compat+y}
    then :
      enableval=$enable_access_compat; force_access_compat=$enableval
    else $as_nop
      enable_access_compat=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_access_compat" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_access_compat" = "static" -o "$enable_access_compat" = "shared"; then
        :
      elif test "$enable_access_compat" = "yes"; then
        enable_access_compat=$module_default
      elif test "$enable_access_compat" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_access_compat=$module_default
        else
          enable_access_compat=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_access_compat" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_access_compat=$module_default
        else
          enable_access_compat=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_access_compat" = "all" -o "$enable_access_compat" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_access_compat=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_access_compat=no
        fi
      elif test "$enable_access_compat" = "reallyall" -o "$enable_access_compat" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_access_compat" != "no" ; then
          enable_access_compat=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_access_compat=no
        fi
      else
        enable_access_compat=no
      fi
      if test "$enable_access_compat" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_access_compat$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_access_compat$_apmod_extra_msg" >&6; }
      if test "$enable_access_compat" != "no"; then
        case "$enable_access_compat" in
        static*)
          MODLIST="$MODLIST access_compat"
          if test "access_compat" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES access_compat"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},access_compat"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_access_compat.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_access_compat.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ACCESS_COMPAT_LDADD)
    EOF
          if test ! -z "\$(MOD_ACCESS_COMPAT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ACCESS_COMPAT_LDADD)\""
        AP_LIBS="\$(MOD_ACCESS_COMPAT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ACCESS_COMPAT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_access_compat.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  $objects \$(MOD_ACCESS_COMPAT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ACCESS_COMPAT_LDADD"
    
    
    
      fi
    
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_auth_basic" >&5
    printf %s "checking whether to enable mod_auth_basic... " >&6; }
        # Check whether --enable-auth-basic was given.
    if test ${enable_auth_basic+y}
    then :
      enableval=$enable_auth_basic; force_auth_basic=$enableval
    else $as_nop
      enable_auth_basic=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_auth_basic" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_auth_basic" = "static" -o "$enable_auth_basic" = "shared"; then
        :
      elif test "$enable_auth_basic" = "yes"; then
        enable_auth_basic=$module_default
      elif test "$enable_auth_basic" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_auth_basic=$module_default
        else
          enable_auth_basic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_auth_basic" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_auth_basic=$module_default
        else
          enable_auth_basic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_auth_basic" = "all" -o "$enable_auth_basic" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_auth_basic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_auth_basic=no
        fi
      elif test "$enable_auth_basic" = "reallyall" -o "$enable_auth_basic" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_auth_basic" != "no" ; then
          enable_auth_basic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_auth_basic=no
        fi
      else
        enable_auth_basic=no
      fi
      if test "$enable_auth_basic" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_auth_basic$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_auth_basic$_apmod_extra_msg" >&6; }
      if test "$enable_auth_basic" != "no"; then
        case "$enable_auth_basic" in
        static*)
          MODLIST="$MODLIST auth_basic"
          if test "auth_basic" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES auth_basic"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},auth_basic"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_auth_basic.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_auth_basic.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTH_BASIC_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTH_BASIC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTH_BASIC_LDADD)\""
        AP_LIBS="\$(MOD_AUTH_BASIC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTH_BASIC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_auth_basic.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  $objects \$(MOD_AUTH_BASIC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTH_BASIC_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_auth_form" >&5
    printf %s "checking whether to enable mod_auth_form... " >&6; }
        # Check whether --enable-auth-form was given.
    if test ${enable_auth_form+y}
    then :
      enableval=$enable_auth_form; force_auth_form=$enableval
    else $as_nop
      enable_auth_form=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_auth_form" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_auth_form" = "static" -o "$enable_auth_form" = "shared"; then
        :
      elif test "$enable_auth_form" = "yes"; then
        enable_auth_form=$module_default
      elif test "$enable_auth_form" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_auth_form=$module_default
        else
          enable_auth_form=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_auth_form" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_auth_form=$module_default
        else
          enable_auth_form=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_auth_form" = "all" -o "$enable_auth_form" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_auth_form=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_auth_form=no
        fi
      elif test "$enable_auth_form" = "reallyall" -o "$enable_auth_form" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_auth_form" != "no" ; then
          enable_auth_form=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_auth_form=no
        fi
      else
        enable_auth_form=no
      fi
      if test "$enable_auth_form" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_auth_form$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_auth_form$_apmod_extra_msg" >&6; }
      if test "$enable_auth_form" != "no"; then
        case "$enable_auth_form" in
        static*)
          MODLIST="$MODLIST auth_form"
          if test "auth_form" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES auth_form"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},auth_form"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_auth_form.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_auth_form.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTH_FORM_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTH_FORM_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTH_FORM_LDADD)\""
        AP_LIBS="\$(MOD_AUTH_FORM_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTH_FORM_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_auth_form.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  $objects \$(MOD_AUTH_FORM_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTH_FORM_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_auth_digest" >&5
    printf %s "checking whether to enable mod_auth_digest... " >&6; }
        # Check whether --enable-auth-digest was given.
    if test ${enable_auth_digest+y}
    then :
      enableval=$enable_auth_digest; force_auth_digest=$enableval
    else $as_nop
      enable_auth_digest=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_auth_digest" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_auth_digest" = "static" -o "$enable_auth_digest" = "shared"; then
        :
      elif test "$enable_auth_digest" = "yes"; then
        enable_auth_digest=$module_default
      elif test "$enable_auth_digest" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_auth_digest=$module_default
        else
          enable_auth_digest=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_auth_digest" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_auth_digest=$module_default
        else
          enable_auth_digest=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_auth_digest" = "all" -o "$enable_auth_digest" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_auth_digest=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_auth_digest=no
        fi
      elif test "$enable_auth_digest" = "reallyall" -o "$enable_auth_digest" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_auth_digest" != "no" ; then
          enable_auth_digest=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_auth_digest=no
        fi
      else
        enable_auth_digest=no
      fi
      if test "$enable_auth_digest" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
    apr_old_cppflags=$CPPFLAGS
    CPPFLAGS="$CPPFLAGS $INCLUDES"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr.h>
    #if APR_HAS_RANDOM
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_define_APR_HAS_RANDOM=yes
    else $as_nop
      ac_cv_define_APR_HAS_RANDOM=no
    fi
    rm -rf conftest*
    
    CPPFLAGS=$apr_old_cppflags
    
      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
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_auth_digest" >&5
    printf %s "checking whether to enable mod_auth_digest... " >&6; }
                if test "$enable_auth_digest" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_auth_digest has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_auth_digest$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_auth_digest$_apmod_extra_msg" >&6; }
      if test "$enable_auth_digest" != "no"; then
        case "$enable_auth_digest" in
        static*)
          MODLIST="$MODLIST auth_digest"
          if test "auth_digest" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES auth_digest"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},auth_digest"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_auth_digest.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_auth_digest.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTH_DIGEST_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTH_DIGEST_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTH_DIGEST_LDADD)\""
        AP_LIBS="\$(MOD_AUTH_DIGEST_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTH_DIGEST_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_auth_digest.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  $objects \$(MOD_AUTH_DIGEST_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTH_DIGEST_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_allowmethods" >&5
    printf %s "checking whether to enable mod_allowmethods... " >&6; }
        # Check whether --enable-allowmethods was given.
    if test ${enable_allowmethods+y}
    then :
      enableval=$enable_allowmethods; force_allowmethods=$enableval
    else $as_nop
      enable_allowmethods=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_allowmethods" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_allowmethods" = "static" -o "$enable_allowmethods" = "shared"; then
        :
      elif test "$enable_allowmethods" = "yes"; then
        enable_allowmethods=$module_default
      elif test "$enable_allowmethods" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_allowmethods=$module_default
        else
          enable_allowmethods=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_allowmethods" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_allowmethods=$module_default
        else
          enable_allowmethods=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_allowmethods" = "all" -o "$enable_allowmethods" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_allowmethods=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_allowmethods=no
        fi
      elif test "$enable_allowmethods" = "reallyall" -o "$enable_allowmethods" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_allowmethods" != "no" ; then
          enable_allowmethods=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_allowmethods=no
        fi
      else
        enable_allowmethods=no
      fi
      if test "$enable_allowmethods" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_allowmethods$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_allowmethods$_apmod_extra_msg" >&6; }
      if test "$enable_allowmethods" != "no"; then
        case "$enable_allowmethods" in
        static*)
          MODLIST="$MODLIST allowmethods"
          if test "allowmethods" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES allowmethods"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},allowmethods"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_allowmethods.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_allowmethods.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ALLOWMETHODS_LDADD)
    EOF
          if test ! -z "\$(MOD_ALLOWMETHODS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ALLOWMETHODS_LDADD)\""
        AP_LIBS="\$(MOD_ALLOWMETHODS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ALLOWMETHODS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_allowmethods.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  $objects \$(MOD_ALLOWMETHODS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ALLOWMETHODS_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=arch/win32
      modpath_current=modules/arch/win32
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d arch/win32 || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_isapi" >&5
    printf %s "checking whether to enable mod_isapi... " >&6; }
        # Check whether --enable-isapi was given.
    if test ${enable_isapi+y}
    then :
      enableval=$enable_isapi; force_isapi=$enableval
    else $as_nop
      enable_isapi=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_isapi" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_isapi" = "static" -o "$enable_isapi" = "shared"; then
        :
      elif test "$enable_isapi" = "yes"; then
        enable_isapi=$module_default
      elif test "$enable_isapi" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_isapi=$module_default
        else
          enable_isapi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_isapi" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_isapi=$module_default
        else
          enable_isapi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_isapi" = "all" -o "$enable_isapi" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_isapi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_isapi=no
        fi
      elif test "$enable_isapi" = "reallyall" -o "$enable_isapi" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_isapi" != "no" ; then
          enable_isapi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_isapi=no
        fi
      else
        enable_isapi=no
      fi
      if test "$enable_isapi" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_isapi$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_isapi$_apmod_extra_msg" >&6; }
      if test "$enable_isapi" != "no"; then
        case "$enable_isapi" in
        static*)
          MODLIST="$MODLIST isapi"
          if test "isapi" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES isapi"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},isapi"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_isapi.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_isapi.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ISAPI_LDADD)
    EOF
          if test ! -z "\$(MOD_ISAPI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ISAPI_LDADD)\""
        AP_LIBS="\$(MOD_ISAPI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ISAPI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_isapi.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  $objects \$(MOD_ISAPI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ISAPI_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=cache
      modpath_current=modules/cache
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d cache || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_file_cache" >&5
    printf %s "checking whether to enable mod_file_cache... " >&6; }
        # Check whether --enable-file-cache was given.
    if test ${enable_file_cache+y}
    then :
      enableval=$enable_file_cache; force_file_cache=$enableval
    else $as_nop
      enable_file_cache=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_file_cache" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_file_cache" = "static" -o "$enable_file_cache" = "shared"; then
        :
      elif test "$enable_file_cache" = "yes"; then
        enable_file_cache=$module_default
      elif test "$enable_file_cache" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_file_cache=$module_default
        else
          enable_file_cache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_file_cache" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_file_cache=$module_default
        else
          enable_file_cache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_file_cache" = "all" -o "$enable_file_cache" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_file_cache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_file_cache=no
        fi
      elif test "$enable_file_cache" = "reallyall" -o "$enable_file_cache" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_file_cache" != "no" ; then
          enable_file_cache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_file_cache=no
        fi
      else
        enable_file_cache=no
      fi
      if test "$enable_file_cache" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_file_cache$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_file_cache$_apmod_extra_msg" >&6; }
      if test "$enable_file_cache" != "no"; then
        case "$enable_file_cache" in
        static*)
          MODLIST="$MODLIST file_cache"
          if test "file_cache" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES file_cache"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},file_cache"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_file_cache.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_file_cache.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_FILE_CACHE_LDADD)
    EOF
          if test ! -z "\$(MOD_FILE_CACHE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_FILE_CACHE_LDADD)\""
        AP_LIBS="\$(MOD_FILE_CACHE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_FILE_CACHE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_file_cache.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  $objects \$(MOD_FILE_CACHE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_FILE_CACHE_LDADD"
    
    
    
      fi
    
    
    cache_objs="mod_cache.lo cache_storage.lo cache_util.lo "
    cache_disk_objs="mod_cache_disk.lo"
    cache_socache_objs="mod_cache_socache.lo"
    
    case "$host" in
      *os2*)
        # OS/2 DLLs must resolve all symbols at build time
        # and we need some from main cache module
        cache_disk_objs="$cache_disk_objs mod_cache.la"
        cache_socache_objs="$cache_socache_objs mod_cache.la"
        ;;
    esac
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cache" >&5
    printf %s "checking whether to enable mod_cache... " >&6; }
        # Check whether --enable-cache was given.
    if test ${enable_cache+y}
    then :
      enableval=$enable_cache; force_cache=$enableval
    else $as_nop
      enable_cache=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_cache" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cache" = "static" -o "$enable_cache" = "shared"; then
        :
      elif test "$enable_cache" = "yes"; then
        enable_cache=$module_default
      elif test "$enable_cache" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cache=$module_default
        else
          enable_cache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cache" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cache=$module_default
        else
          enable_cache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cache" = "all" -o "$enable_cache" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cache=no
        fi
      elif test "$enable_cache" = "reallyall" -o "$enable_cache" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cache" != "no" ; then
          enable_cache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cache=no
        fi
      else
        enable_cache=no
      fi
      if test "$enable_cache" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cache$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cache$_apmod_extra_msg" >&6; }
      if test "$enable_cache" != "no"; then
        case "$enable_cache" in
        static*)
          MODLIST="$MODLIST cache"
          if test "cache" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cache"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cache"
          fi
          ;;
        esac
    
    
      if test -z "$cache_objs"; then
        objects="mod_cache.lo"
      else
        objects="$cache_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cache.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CACHE_LDADD)
    EOF
          if test ! -z "\$(MOD_CACHE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CACHE_LDADD)\""
        AP_LIBS="\$(MOD_CACHE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CACHE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cache.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  $objects \$(MOD_CACHE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CACHE_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cache_disk" >&5
    printf %s "checking whether to enable mod_cache_disk... " >&6; }
        # Check whether --enable-cache-disk was given.
    if test ${enable_cache_disk+y}
    then :
      enableval=$enable_cache_disk; force_cache_disk=$enableval
    else $as_nop
      enable_cache_disk=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_cache_disk" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cache_disk" = "static" -o "$enable_cache_disk" = "shared"; then
        :
      elif test "$enable_cache_disk" = "yes"; then
        enable_cache_disk=$module_default
      elif test "$enable_cache_disk" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cache_disk=$module_default
        else
          enable_cache_disk=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cache_disk" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cache_disk=$module_default
        else
          enable_cache_disk=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cache_disk" = "all" -o "$enable_cache_disk" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cache_disk=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cache_disk=no
        fi
      elif test "$enable_cache_disk" = "reallyall" -o "$enable_cache_disk" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cache_disk" != "no" ; then
          enable_cache_disk=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cache_disk=no
        fi
      else
        enable_cache_disk=no
      fi
      if test "$enable_cache_disk" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_cache" = "no" ; then
                                  enable_cache_disk=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_cache is disabled but required for mod_cache_disk\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_cache is disabled but required for mod_cache_disk\"" >&2;}
                                elif test "$enable_cache_disk" = "static" && test "$enable_cache" != "static" ; then
                                  enable_cache_disk=$enable_cache
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_cache_disk shared because mod_cache is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_cache_disk shared because mod_cache is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cache_disk" >&5
    printf %s "checking whether to enable mod_cache_disk... " >&6; }
                if test "$enable_cache_disk" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_cache_disk has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cache_disk$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cache_disk$_apmod_extra_msg" >&6; }
      if test "$enable_cache_disk" != "no"; then
        case "$enable_cache_disk" in
        static*)
          MODLIST="$MODLIST cache_disk"
          if test "cache_disk" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cache_disk"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cache_disk"
          fi
          ;;
        esac
    
    
      if test -z "$cache_disk_objs"; then
        objects="mod_cache_disk.lo"
      else
        objects="$cache_disk_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cache_disk.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CACHE_DISK_LDADD)
    EOF
          if test ! -z "\$(MOD_CACHE_DISK_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CACHE_DISK_LDADD)\""
        AP_LIBS="\$(MOD_CACHE_DISK_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CACHE_DISK_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cache_disk.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  $objects \$(MOD_CACHE_DISK_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CACHE_DISK_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cache_socache" >&5
    printf %s "checking whether to enable mod_cache_socache... " >&6; }
        # Check whether --enable-cache-socache was given.
    if test ${enable_cache_socache+y}
    then :
      enableval=$enable_cache_socache; force_cache_socache=$enableval
    else $as_nop
      enable_cache_socache=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_cache_socache" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cache_socache" = "static" -o "$enable_cache_socache" = "shared"; then
        :
      elif test "$enable_cache_socache" = "yes"; then
        enable_cache_socache=$module_default
      elif test "$enable_cache_socache" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cache_socache=$module_default
        else
          enable_cache_socache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cache_socache" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cache_socache=$module_default
        else
          enable_cache_socache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cache_socache" = "all" -o "$enable_cache_socache" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cache_socache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cache_socache=no
        fi
      elif test "$enable_cache_socache" = "reallyall" -o "$enable_cache_socache" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cache_socache" != "no" ; then
          enable_cache_socache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cache_socache=no
        fi
      else
        enable_cache_socache=no
      fi
      if test "$enable_cache_socache" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cache_socache$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cache_socache$_apmod_extra_msg" >&6; }
      if test "$enable_cache_socache" != "no"; then
        case "$enable_cache_socache" in
        static*)
          MODLIST="$MODLIST cache_socache"
          if test "cache_socache" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cache_socache"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cache_socache"
          fi
          ;;
        esac
    
    
      if test -z "$cache_socache_objs"; then
        objects="mod_cache_socache.lo"
      else
        objects="$cache_socache_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cache_socache.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CACHE_SOCACHE_LDADD)
    EOF
          if test ! -z "\$(MOD_CACHE_SOCACHE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CACHE_SOCACHE_LDADD)\""
        AP_LIBS="\$(MOD_CACHE_SOCACHE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CACHE_SOCACHE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cache_socache.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  $objects \$(MOD_CACHE_SOCACHE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CACHE_SOCACHE_LDADD"
    
    
    
      fi
    
    
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_socache_shmcb" >&5
    printf %s "checking whether to enable mod_socache_shmcb... " >&6; }
        # Check whether --enable-socache-shmcb was given.
    if test ${enable_socache_shmcb+y}
    then :
      enableval=$enable_socache_shmcb; force_socache_shmcb=$enableval
    else $as_nop
      enable_socache_shmcb=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_socache_shmcb" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_socache_shmcb" = "static" -o "$enable_socache_shmcb" = "shared"; then
        :
      elif test "$enable_socache_shmcb" = "yes"; then
        enable_socache_shmcb=$module_default
      elif test "$enable_socache_shmcb" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_shmcb=$module_default
        else
          enable_socache_shmcb=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_shmcb" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_socache_shmcb=$module_default
        else
          enable_socache_shmcb=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_shmcb" = "all" -o "$enable_socache_shmcb" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_shmcb=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_shmcb=no
        fi
      elif test "$enable_socache_shmcb" = "reallyall" -o "$enable_socache_shmcb" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_socache_shmcb" != "no" ; then
          enable_socache_shmcb=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_shmcb=no
        fi
      else
        enable_socache_shmcb=no
      fi
      if test "$enable_socache_shmcb" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_socache_shmcb$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_socache_shmcb$_apmod_extra_msg" >&6; }
      if test "$enable_socache_shmcb" != "no"; then
        case "$enable_socache_shmcb" in
        static*)
          MODLIST="$MODLIST socache_shmcb"
          if test "socache_shmcb" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES socache_shmcb"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},socache_shmcb"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_socache_shmcb.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_socache_shmcb.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SOCACHE_SHMCB_LDADD)
    EOF
          if test ! -z "\$(MOD_SOCACHE_SHMCB_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SOCACHE_SHMCB_LDADD)\""
        AP_LIBS="\$(MOD_SOCACHE_SHMCB_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SOCACHE_SHMCB_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_socache_shmcb.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  $objects \$(MOD_SOCACHE_SHMCB_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SOCACHE_SHMCB_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_socache_dbm" >&5
    printf %s "checking whether to enable mod_socache_dbm... " >&6; }
        # Check whether --enable-socache-dbm was given.
    if test ${enable_socache_dbm+y}
    then :
      enableval=$enable_socache_dbm; force_socache_dbm=$enableval
    else $as_nop
      enable_socache_dbm=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_socache_dbm" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_socache_dbm" = "static" -o "$enable_socache_dbm" = "shared"; then
        :
      elif test "$enable_socache_dbm" = "yes"; then
        enable_socache_dbm=$module_default
      elif test "$enable_socache_dbm" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_dbm=$module_default
        else
          enable_socache_dbm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_dbm" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_socache_dbm=$module_default
        else
          enable_socache_dbm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_dbm" = "all" -o "$enable_socache_dbm" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_dbm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_dbm=no
        fi
      elif test "$enable_socache_dbm" = "reallyall" -o "$enable_socache_dbm" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_socache_dbm" != "no" ; then
          enable_socache_dbm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_dbm=no
        fi
      else
        enable_socache_dbm=no
      fi
      if test "$enable_socache_dbm" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_socache_dbm$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_socache_dbm$_apmod_extra_msg" >&6; }
      if test "$enable_socache_dbm" != "no"; then
        case "$enable_socache_dbm" in
        static*)
          MODLIST="$MODLIST socache_dbm"
          if test "socache_dbm" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES socache_dbm"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},socache_dbm"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_socache_dbm.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_socache_dbm.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SOCACHE_DBM_LDADD)
    EOF
          if test ! -z "\$(MOD_SOCACHE_DBM_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SOCACHE_DBM_LDADD)\""
        AP_LIBS="\$(MOD_SOCACHE_DBM_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SOCACHE_DBM_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_socache_dbm.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  $objects \$(MOD_SOCACHE_DBM_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SOCACHE_DBM_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_socache_memcache" >&5
    printf %s "checking whether to enable mod_socache_memcache... " >&6; }
        # Check whether --enable-socache-memcache was given.
    if test ${enable_socache_memcache+y}
    then :
      enableval=$enable_socache_memcache; force_socache_memcache=$enableval
    else $as_nop
      enable_socache_memcache=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_socache_memcache" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_socache_memcache" = "static" -o "$enable_socache_memcache" = "shared"; then
        :
      elif test "$enable_socache_memcache" = "yes"; then
        enable_socache_memcache=$module_default
      elif test "$enable_socache_memcache" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_memcache=$module_default
        else
          enable_socache_memcache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_memcache" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_socache_memcache=$module_default
        else
          enable_socache_memcache=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_memcache" = "all" -o "$enable_socache_memcache" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_memcache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_memcache=no
        fi
      elif test "$enable_socache_memcache" = "reallyall" -o "$enable_socache_memcache" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_socache_memcache" != "no" ; then
          enable_socache_memcache=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_memcache=no
        fi
      else
        enable_socache_memcache=no
      fi
      if test "$enable_socache_memcache" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_socache_memcache$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_socache_memcache$_apmod_extra_msg" >&6; }
      if test "$enable_socache_memcache" != "no"; then
        case "$enable_socache_memcache" in
        static*)
          MODLIST="$MODLIST socache_memcache"
          if test "socache_memcache" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES socache_memcache"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},socache_memcache"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_socache_memcache.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_socache_memcache.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SOCACHE_MEMCACHE_LDADD)
    EOF
          if test ! -z "\$(MOD_SOCACHE_MEMCACHE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SOCACHE_MEMCACHE_LDADD)\""
        AP_LIBS="\$(MOD_SOCACHE_MEMCACHE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SOCACHE_MEMCACHE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_socache_memcache.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  $objects \$(MOD_SOCACHE_MEMCACHE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SOCACHE_MEMCACHE_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_socache_redis" >&5
    printf %s "checking whether to enable mod_socache_redis... " >&6; }
        # Check whether --enable-socache-redis was given.
    if test ${enable_socache_redis+y}
    then :
      enableval=$enable_socache_redis; force_socache_redis=$enableval
    else $as_nop
      enable_socache_redis=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_socache_redis" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_socache_redis" = "static" -o "$enable_socache_redis" = "shared"; then
        :
      elif test "$enable_socache_redis" = "yes"; then
        enable_socache_redis=$module_default
      elif test "$enable_socache_redis" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_redis=$module_default
        else
          enable_socache_redis=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_redis" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_socache_redis=$module_default
        else
          enable_socache_redis=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_redis" = "all" -o "$enable_socache_redis" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_redis=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_redis=no
        fi
      elif test "$enable_socache_redis" = "reallyall" -o "$enable_socache_redis" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_socache_redis" != "no" ; then
          enable_socache_redis=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_redis=no
        fi
      else
        enable_socache_redis=no
      fi
      if test "$enable_socache_redis" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_socache_redis$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_socache_redis$_apmod_extra_msg" >&6; }
      if test "$enable_socache_redis" != "no"; then
        case "$enable_socache_redis" in
        static*)
          MODLIST="$MODLIST socache_redis"
          if test "socache_redis" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES socache_redis"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},socache_redis"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_socache_redis.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_socache_redis.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SOCACHE_REDIS_LDADD)
    EOF
          if test ! -z "\$(MOD_SOCACHE_REDIS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SOCACHE_REDIS_LDADD)\""
        AP_LIBS="\$(MOD_SOCACHE_REDIS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SOCACHE_REDIS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_socache_redis.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  $objects \$(MOD_SOCACHE_REDIS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SOCACHE_REDIS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_socache_dc" >&5
    printf %s "checking whether to enable mod_socache_dc... " >&6; }
        # Check whether --enable-socache-dc was given.
    if test ${enable_socache_dc+y}
    then :
      enableval=$enable_socache_dc; force_socache_dc=$enableval
    else $as_nop
      enable_socache_dc=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_socache_dc" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_socache_dc" = "static" -o "$enable_socache_dc" = "shared"; then
        :
      elif test "$enable_socache_dc" = "yes"; then
        enable_socache_dc=$module_default
      elif test "$enable_socache_dc" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_dc=$module_default
        else
          enable_socache_dc=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_dc" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_socache_dc=$module_default
        else
          enable_socache_dc=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_socache_dc" = "all" -o "$enable_socache_dc" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_socache_dc=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_dc=no
        fi
      elif test "$enable_socache_dc" = "reallyall" -o "$enable_socache_dc" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_socache_dc" != "no" ; then
          enable_socache_dc=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_socache_dc=no
        fi
      else
        enable_socache_dc=no
      fi
      if test "$enable_socache_dc" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
    if test "x$ap_distcache_configured" = "x"; then
        ap_distcache_found=""
      ap_distcache_base=""
      ap_distcache_libs=""
      ap_distcache_ldflags=""
      ap_distcache_with=""
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided distcache base" >&5
    printf %s "checking for user-provided distcache base... " >&6; }
    
    # Check whether --with-distcache was given.
    if test ${with_distcache+y}
    then :
      withval=$with_distcache;
            if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                ap_distcache_with="yes"
          ap_distcache_base="`cd $withval ; pwd`"
        fi
    
    fi
    
      if test "x$ap_distcache_base" = "x"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_distcache_base" >&5
    printf "%s\n" "$ap_distcache_base" >&6; }
      fi
    
        saved_CPPFLAGS="$CPPFLAGS"
      saved_LIBS="$LIBS"
      saved_LDFLAGS="$LDFLAGS"
    
      if test "x$ap_distcache_base" != "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_distcache_base/include\""
        CPPFLAGS="-I$ap_distcache_base/include"
      else
        apr_addto_bugger="-I$ap_distcache_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_INCLUDES to \"-I$ap_distcache_base/include\""
        MOD_INCLUDES="-I$ap_distcache_base/include"
      else
        apr_addto_bugger="-I$ap_distcache_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_INCLUDES"
            MOD_INCLUDES="$MOD_INCLUDES $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_distcache_base/lib\""
        LDFLAGS="-L$ap_distcache_base/lib"
      else
        apr_addto_bugger="-L$ap_distcache_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ap_distcache_ldflags" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ap_distcache_ldflags to \"-L$ap_distcache_base/lib\""
        ap_distcache_ldflags="-L$ap_distcache_base/lib"
      else
        apr_addto_bugger="-L$ap_distcache_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ap_distcache_ldflags; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ap_distcache_ldflags"
            ap_distcache_ldflags="$ap_distcache_ldflags $i"
          fi
        done
      fi
    
        if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_distcache_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_distcache_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_distcache_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ap_distcache_ldflags" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ap_distcache_ldflags to \"$ap_platform_runtime_link_flag$ap_distcache_base/lib\""
        ap_distcache_ldflags="$ap_platform_runtime_link_flag$ap_distcache_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_distcache_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ap_distcache_ldflags; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ap_distcache_ldflags"
            ap_distcache_ldflags="$ap_distcache_ldflags $i"
          fi
        done
      fi
    
        fi
      fi
               for ac_header in distcache/dc_client.h
    do :
      ac_fn_c_check_header_compile "$LINENO" "distcache/dc_client.h" "ac_cv_header_distcache_dc_client_h" "$ac_includes_default"
    if test "x$ac_cv_header_distcache_dc_client_h" = xyes
    then :
      printf "%s\n" "#define HAVE_DISTCACHE_DC_CLIENT_H 1" >>confdefs.h
     ap_distcache_found="yes"
    fi
    
    done
      if test "$ap_distcache_found" = "yes"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for distcache version" >&5
    printf %s "checking for distcache version... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <distcache/dc_client.h>
    int
    main (void)
    {
    
    #if DISTCACHE_CLIENT_API != 0x0001
    #error "distcache API version is unrecognised"
    #endif
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
    
    else $as_nop
      ap_distcache_found="no"
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_distcache_found" >&5
    printf "%s\n" "$ap_distcache_found" >&6; }
      fi
      if test "$ap_distcache_found" != "yes"; then
        if test "x$ap_distcache_with" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: ...No distcache detected" >&5
    printf "%s\n" "$as_me: WARNING: ...No distcache detected" >&2;}
        else
          as_fn_error $? "...No distcache detected" "$LINENO" 5
        fi
      else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for distcache libraries" >&5
    printf %s "checking for distcache libraries... " >&6; }
        ap_distcache_libs="-ldistcache -lnal"
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_distcache_libs\""
        LIBS="$ap_distcache_libs"
      else
        apr_addto_bugger="$ap_distcache_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
    
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <distcache/dc_client.h>
    int
    main (void)
    {
    DC_CTX *foo = DC_CTX_new((const char *)0,0);
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
    
    else $as_nop
      ap_distcache_found="no"
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_distcache_found" >&5
    printf "%s\n" "$ap_distcache_found" >&6; }
        if test "$ap_distcache_found" != "yes"; then
          if test "x$ap_distcache_base" = "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: ... Error, distcache libraries were missing or unusable" >&5
    printf "%s\n" "$as_me: WARNING: ... Error, distcache libraries were missing or unusable" >&2;}
          else
            as_fn_error $? "... Error, distcache libraries were missing or unusable" "$LINENO" 5
          fi
        fi
      fi
    
        CPPFLAGS="$saved_CPPFLAGS"
      LIBS="$saved_LIBS"
      LDFLAGS="$saved_LDFLAGS"
    
        if test "$ap_distcache_found" = "yes"; then
    
      if test "x$MOD_SOCACHE_DC_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_SOCACHE_DC_LDADD to \"$ap_distcache_ldflags $ap_distcache_libs\""
        MOD_SOCACHE_DC_LDADD="$ap_distcache_ldflags $ap_distcache_libs"
      else
        apr_addto_bugger="$ap_distcache_ldflags $ap_distcache_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_SOCACHE_DC_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_SOCACHE_DC_LDADD"
            MOD_SOCACHE_DC_LDADD="$MOD_SOCACHE_DC_LDADD $i"
          fi
        done
      fi
    
    
    printf "%s\n" "#define HAVE_DISTCACHE 1" >>confdefs.h
    
      else
        enable_socache_dc=no
      fi
      ap_distcache_configured="yes"
    fi
    
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_socache_dc" >&5
    printf %s "checking whether to enable mod_socache_dc... " >&6; }
                if test "$enable_socache_dc" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_socache_dc has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_socache_dc$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_socache_dc$_apmod_extra_msg" >&6; }
      if test "$enable_socache_dc" != "no"; then
        case "$enable_socache_dc" in
        static*)
          MODLIST="$MODLIST socache_dc"
          if test "socache_dc" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES socache_dc"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},socache_dc"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_socache_dc.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_socache_dc.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SOCACHE_DC_LDADD)
    EOF
          if test ! -z "\$(MOD_SOCACHE_DC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SOCACHE_DC_LDADD)\""
        AP_LIBS="\$(MOD_SOCACHE_DC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SOCACHE_DC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_socache_dc.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  $objects \$(MOD_SOCACHE_DC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SOCACHE_DC_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=core
      modpath_current=modules/core
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d core || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
    apr_old_cppflags=$CPPFLAGS
    CPPFLAGS="$CPPFLAGS $INCLUDES"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr.h>
    #if APR_HAS_DSO
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_define_APR_HAS_DSO=yes
    else $as_nop
      ac_cv_define_APR_HAS_DSO=no
    fi
    rm -rf conftest*
    
    CPPFLAGS=$apr_old_cppflags
    
    
    case "x$enable_so" in
        "xyes")
            if test $ac_cv_define_APR_HAS_DSO = "no"; then
                as_fn_error $? "mod_so has been requested but cannot be built on your system" "$LINENO" 5
            fi
            ;;
        "xshared")
            as_fn_error $? "mod_so can not be built as a shared DSO" "$LINENO" 5
            ;;
        "xno")
            ;;
        "x")
            enable_so=$ac_cv_define_APR_HAS_DSO
            ;;
    esac
    
    if test "x$enable_so" = "xyes"; then
        enable_so="static"
    fi
    
    if test "x$enable_so" = "xstatic"; then
    
      if test "x$HTTPD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting HTTPD_LDFLAGS to \"-export-dynamic\""
        HTTPD_LDFLAGS="-export-dynamic"
      else
        apr_addto_bugger="-export-dynamic"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $HTTPD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to HTTPD_LDFLAGS"
            HTTPD_LDFLAGS="$HTTPD_LDFLAGS $i"
          fi
        done
      fi
    
        INSTALL_DSO=yes
    else
        INSTALL_DSO=no
    fi
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST INSTALL_DSO"
    
    
    
    if test "$sharedobjs" = "yes"; then
        if test $ac_cv_define_APR_HAS_DSO = "no"; then
            as_fn_error $? "shared objects have been requested but cannot be built since mod_so cannot be built" "$LINENO" 5
        elif test $enable_so = "no"; then
            as_fn_error $? "shared objects have been requested but cannot be built since mod_so was disabled" "$LINENO" 5
        fi
    fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_so" >&5
    printf %s "checking whether to enable mod_so... " >&6; }
        # Check whether --enable-so was given.
    if test ${enable_so+y}
    then :
      enableval=$enable_so; force_so=$enableval
    else $as_nop
      enable_so=$enable_so
    fi
    
        _apmod_extra_msg=""
          case "$enable_so" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_so" = "static" -o "$enable_so" = "shared"; then
        :
      elif test "$enable_so" = "yes"; then
        enable_so=$module_default
      elif test "$enable_so" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_so=$module_default
        else
          enable_so=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_so" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_so=$module_default
        else
          enable_so=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_so" = "all" -o "$enable_so" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_so=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_so=no
        fi
      elif test "$enable_so" = "reallyall" -o "$enable_so" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_so" != "no" ; then
          enable_so=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_so=no
        fi
      else
        enable_so=no
      fi
      if test "$enable_so" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_so$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_so$_apmod_extra_msg" >&6; }
      if test "$enable_so" != "no"; then
        case "$enable_so" in
        static*)
          MODLIST="$MODLIST so"
          if test "so" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES so"
          if test "$enable_so" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},so"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_so.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_so.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SO_LDADD)
    EOF
          if test ! -z "\$(MOD_SO_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SO_LDADD)\""
        AP_LIBS="\$(MOD_SO_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SO_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_so.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  $objects \$(MOD_SO_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SO_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_watchdog" >&5
    printf %s "checking whether to enable mod_watchdog... " >&6; }
        # Check whether --enable-watchdog was given.
    if test ${enable_watchdog+y}
    then :
      enableval=$enable_watchdog; force_watchdog=$enableval
    else $as_nop
      enable_watchdog=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_watchdog" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_watchdog" = "static" -o "$enable_watchdog" = "shared"; then
        :
      elif test "$enable_watchdog" = "yes"; then
        enable_watchdog=$module_default
      elif test "$enable_watchdog" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_watchdog=$module_default
        else
          enable_watchdog=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_watchdog" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_watchdog=$module_default
        else
          enable_watchdog=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_watchdog" = "all" -o "$enable_watchdog" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_watchdog=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_watchdog=no
        fi
      elif test "$enable_watchdog" = "reallyall" -o "$enable_watchdog" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_watchdog" != "no" ; then
          enable_watchdog=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_watchdog=no
        fi
      else
        enable_watchdog=no
      fi
      if test "$enable_watchdog" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
    apr_old_cppflags=$CPPFLAGS
    CPPFLAGS="$CPPFLAGS $INCLUDES"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr.h>
    #if APR_HAS_THREADS
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_define_APR_HAS_THREADS=yes
    else $as_nop
      ac_cv_define_APR_HAS_THREADS=no
    fi
    rm -rf conftest*
    
    CPPFLAGS=$apr_old_cppflags
    
        if test $ac_cv_define_APR_HAS_THREADS = "no"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: mod_watchdog requires apr to be built with --enable-threads" >&5
    printf "%s\n" "$as_me: WARNING: mod_watchdog requires apr to be built with --enable-threads" >&2;}
            enable_watchdog=no
        fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_watchdog" >&5
    printf %s "checking whether to enable mod_watchdog... " >&6; }
                if test "$enable_watchdog" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_watchdog has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_watchdog$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_watchdog$_apmod_extra_msg" >&6; }
      if test "$enable_watchdog" != "no"; then
        case "$enable_watchdog" in
        static*)
          MODLIST="$MODLIST watchdog"
          if test "watchdog" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES watchdog"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},watchdog"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_watchdog.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_watchdog.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_WATCHDOG_LDADD)
    EOF
          if test ! -z "\$(MOD_WATCHDOG_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_WATCHDOG_LDADD)\""
        AP_LIBS="\$(MOD_WATCHDOG_LDADD)"
      else
        apr_addto_bugger="\$(MOD_WATCHDOG_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_watchdog.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  $objects \$(MOD_WATCHDOG_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_WATCHDOG_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_macro" >&5
    printf %s "checking whether to enable mod_macro... " >&6; }
        # Check whether --enable-macro was given.
    if test ${enable_macro+y}
    then :
      enableval=$enable_macro; force_macro=$enableval
    else $as_nop
      enable_macro=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_macro" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_macro" = "static" -o "$enable_macro" = "shared"; then
        :
      elif test "$enable_macro" = "yes"; then
        enable_macro=$module_default
      elif test "$enable_macro" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_macro=$module_default
        else
          enable_macro=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_macro" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_macro=$module_default
        else
          enable_macro=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_macro" = "all" -o "$enable_macro" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_macro=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_macro=no
        fi
      elif test "$enable_macro" = "reallyall" -o "$enable_macro" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_macro" != "no" ; then
          enable_macro=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_macro=no
        fi
      else
        enable_macro=no
      fi
      if test "$enable_macro" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_macro$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_macro$_apmod_extra_msg" >&6; }
      if test "$enable_macro" != "no"; then
        case "$enable_macro" in
        static*)
          MODLIST="$MODLIST macro"
          if test "macro" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES macro"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},macro"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_macro.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_macro.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_MACRO_LDADD)
    EOF
          if test ! -z "\$(MOD_MACRO_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_MACRO_LDADD)\""
        AP_LIBS="\$(MOD_MACRO_LDADD)"
      else
        apr_addto_bugger="\$(MOD_MACRO_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_macro.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  $objects \$(MOD_MACRO_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_MACRO_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=database
      modpath_current=modules/database
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d database || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dbd" >&5
    printf %s "checking whether to enable mod_dbd... " >&6; }
        # Check whether --enable-dbd was given.
    if test ${enable_dbd+y}
    then :
      enableval=$enable_dbd; force_dbd=$enableval
    else $as_nop
      enable_dbd=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_dbd" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_dbd" = "static" -o "$enable_dbd" = "shared"; then
        :
      elif test "$enable_dbd" = "yes"; then
        enable_dbd=$module_default
      elif test "$enable_dbd" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dbd=$module_default
        else
          enable_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dbd" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_dbd=$module_default
        else
          enable_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dbd" = "all" -o "$enable_dbd" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dbd=no
        fi
      elif test "$enable_dbd" = "reallyall" -o "$enable_dbd" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_dbd" != "no" ; then
          enable_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dbd=no
        fi
      else
        enable_dbd=no
      fi
      if test "$enable_dbd" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_dbd$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_dbd$_apmod_extra_msg" >&6; }
      if test "$enable_dbd" != "no"; then
        case "$enable_dbd" in
        static*)
          MODLIST="$MODLIST dbd"
          if test "dbd" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES dbd"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},dbd"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_dbd.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_dbd.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DBD_LDADD)
    EOF
          if test ! -z "\$(MOD_DBD_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DBD_LDADD)\""
        AP_LIBS="\$(MOD_DBD_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DBD_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_dbd.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  $objects \$(MOD_DBD_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DBD_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=debugging
      modpath_current=modules/debugging
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d debugging || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_bucketeer" >&5
    printf %s "checking whether to enable mod_bucketeer... " >&6; }
        # Check whether --enable-bucketeer was given.
    if test ${enable_bucketeer+y}
    then :
      enableval=$enable_bucketeer; force_bucketeer=$enableval
    else $as_nop
      enable_bucketeer=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_bucketeer" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_bucketeer" = "static" -o "$enable_bucketeer" = "shared"; then
        :
      elif test "$enable_bucketeer" = "yes"; then
        enable_bucketeer=$module_default
      elif test "$enable_bucketeer" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_bucketeer=$module_default
        else
          enable_bucketeer=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_bucketeer" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_bucketeer=$module_default
        else
          enable_bucketeer=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_bucketeer" = "all" -o "$enable_bucketeer" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_bucketeer=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_bucketeer=no
        fi
      elif test "$enable_bucketeer" = "reallyall" -o "$enable_bucketeer" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_bucketeer" != "no" ; then
          enable_bucketeer=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_bucketeer=no
        fi
      else
        enable_bucketeer=no
      fi
      if test "$enable_bucketeer" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_bucketeer$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_bucketeer$_apmod_extra_msg" >&6; }
      if test "$enable_bucketeer" != "no"; then
        case "$enable_bucketeer" in
        static*)
          MODLIST="$MODLIST bucketeer"
          if test "bucketeer" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES bucketeer"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},bucketeer"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_bucketeer.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_bucketeer.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_BUCKETEER_LDADD)
    EOF
          if test ! -z "\$(MOD_BUCKETEER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_BUCKETEER_LDADD)\""
        AP_LIBS="\$(MOD_BUCKETEER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_BUCKETEER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_bucketeer.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  $objects \$(MOD_BUCKETEER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_BUCKETEER_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dumpio" >&5
    printf %s "checking whether to enable mod_dumpio... " >&6; }
        # Check whether --enable-dumpio was given.
    if test ${enable_dumpio+y}
    then :
      enableval=$enable_dumpio; force_dumpio=$enableval
    else $as_nop
      enable_dumpio=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_dumpio" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_dumpio" = "static" -o "$enable_dumpio" = "shared"; then
        :
      elif test "$enable_dumpio" = "yes"; then
        enable_dumpio=$module_default
      elif test "$enable_dumpio" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dumpio=$module_default
        else
          enable_dumpio=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dumpio" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_dumpio=$module_default
        else
          enable_dumpio=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dumpio" = "all" -o "$enable_dumpio" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dumpio=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dumpio=no
        fi
      elif test "$enable_dumpio" = "reallyall" -o "$enable_dumpio" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_dumpio" != "no" ; then
          enable_dumpio=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dumpio=no
        fi
      else
        enable_dumpio=no
      fi
      if test "$enable_dumpio" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_dumpio$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_dumpio$_apmod_extra_msg" >&6; }
      if test "$enable_dumpio" != "no"; then
        case "$enable_dumpio" in
        static*)
          MODLIST="$MODLIST dumpio"
          if test "dumpio" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES dumpio"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},dumpio"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_dumpio.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_dumpio.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DUMPIO_LDADD)
    EOF
          if test ! -z "\$(MOD_DUMPIO_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DUMPIO_LDADD)\""
        AP_LIBS="\$(MOD_DUMPIO_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DUMPIO_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_dumpio.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  $objects \$(MOD_DUMPIO_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DUMPIO_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=echo
      modpath_current=modules/echo
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d echo || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_echo" >&5
    printf %s "checking whether to enable mod_echo... " >&6; }
        # Check whether --enable-echo was given.
    if test ${enable_echo+y}
    then :
      enableval=$enable_echo; force_echo=$enableval
    else $as_nop
      enable_echo=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_echo" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_echo" = "static" -o "$enable_echo" = "shared"; then
        :
      elif test "$enable_echo" = "yes"; then
        enable_echo=$module_default
      elif test "$enable_echo" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_echo=$module_default
        else
          enable_echo=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_echo" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_echo=$module_default
        else
          enable_echo=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_echo" = "all" -o "$enable_echo" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_echo=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_echo=no
        fi
      elif test "$enable_echo" = "reallyall" -o "$enable_echo" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_echo" != "no" ; then
          enable_echo=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_echo=no
        fi
      else
        enable_echo=no
      fi
      if test "$enable_echo" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_echo$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_echo$_apmod_extra_msg" >&6; }
      if test "$enable_echo" != "no"; then
        case "$enable_echo" in
        static*)
          MODLIST="$MODLIST echo"
          if test "echo" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES echo"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},echo"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_echo.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_echo.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ECHO_LDADD)
    EOF
          if test ! -z "\$(MOD_ECHO_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ECHO_LDADD)\""
        AP_LIBS="\$(MOD_ECHO_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ECHO_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_echo.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  $objects \$(MOD_ECHO_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ECHO_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=examples
      modpath_current=modules/examples
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d examples || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_example_hooks" >&5
    printf %s "checking whether to enable mod_example_hooks... " >&6; }
        # Check whether --enable-example-hooks was given.
    if test ${enable_example_hooks+y}
    then :
      enableval=$enable_example_hooks; force_example_hooks=$enableval
    else $as_nop
      enable_example_hooks=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_example_hooks" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_example_hooks" = "static" -o "$enable_example_hooks" = "shared"; then
        :
      elif test "$enable_example_hooks" = "yes"; then
        enable_example_hooks=$module_default
      elif test "$enable_example_hooks" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_example_hooks=$module_default
        else
          enable_example_hooks=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_example_hooks" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_example_hooks=$module_default
        else
          enable_example_hooks=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_example_hooks" = "all" -o "$enable_example_hooks" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_example_hooks=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_example_hooks=no
        fi
      elif test "$enable_example_hooks" = "reallyall" -o "$enable_example_hooks" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_example_hooks" != "no" ; then
          enable_example_hooks=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_example_hooks=no
        fi
      else
        enable_example_hooks=no
      fi
      if test "$enable_example_hooks" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_example_hooks$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_example_hooks$_apmod_extra_msg" >&6; }
      if test "$enable_example_hooks" != "no"; then
        case "$enable_example_hooks" in
        static*)
          MODLIST="$MODLIST example_hooks"
          if test "example_hooks" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES example_hooks"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},example_hooks"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_example_hooks.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_example_hooks.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_EXAMPLE_HOOKS_LDADD)
    EOF
          if test ! -z "\$(MOD_EXAMPLE_HOOKS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_EXAMPLE_HOOKS_LDADD)\""
        AP_LIBS="\$(MOD_EXAMPLE_HOOKS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_EXAMPLE_HOOKS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_example_hooks.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  $objects \$(MOD_EXAMPLE_HOOKS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_EXAMPLE_HOOKS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_case_filter" >&5
    printf %s "checking whether to enable mod_case_filter... " >&6; }
        # Check whether --enable-case-filter was given.
    if test ${enable_case_filter+y}
    then :
      enableval=$enable_case_filter; force_case_filter=$enableval
    else $as_nop
      enable_case_filter=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_case_filter" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_case_filter" = "static" -o "$enable_case_filter" = "shared"; then
        :
      elif test "$enable_case_filter" = "yes"; then
        enable_case_filter=$module_default
      elif test "$enable_case_filter" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_case_filter=$module_default
        else
          enable_case_filter=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_case_filter" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_case_filter=$module_default
        else
          enable_case_filter=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_case_filter" = "all" -o "$enable_case_filter" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_case_filter=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_case_filter=no
        fi
      elif test "$enable_case_filter" = "reallyall" -o "$enable_case_filter" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_case_filter" != "no" ; then
          enable_case_filter=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_case_filter=no
        fi
      else
        enable_case_filter=no
      fi
      if test "$enable_case_filter" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_case_filter$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_case_filter$_apmod_extra_msg" >&6; }
      if test "$enable_case_filter" != "no"; then
        case "$enable_case_filter" in
        static*)
          MODLIST="$MODLIST case_filter"
          if test "case_filter" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES case_filter"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},case_filter"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_case_filter.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_case_filter.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CASE_FILTER_LDADD)
    EOF
          if test ! -z "\$(MOD_CASE_FILTER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CASE_FILTER_LDADD)\""
        AP_LIBS="\$(MOD_CASE_FILTER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CASE_FILTER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_case_filter.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  $objects \$(MOD_CASE_FILTER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CASE_FILTER_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_case_filter_in" >&5
    printf %s "checking whether to enable mod_case_filter_in... " >&6; }
        # Check whether --enable-case-filter-in was given.
    if test ${enable_case_filter_in+y}
    then :
      enableval=$enable_case_filter_in; force_case_filter_in=$enableval
    else $as_nop
      enable_case_filter_in=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_case_filter_in" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_case_filter_in" = "static" -o "$enable_case_filter_in" = "shared"; then
        :
      elif test "$enable_case_filter_in" = "yes"; then
        enable_case_filter_in=$module_default
      elif test "$enable_case_filter_in" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_case_filter_in=$module_default
        else
          enable_case_filter_in=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_case_filter_in" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_case_filter_in=$module_default
        else
          enable_case_filter_in=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_case_filter_in" = "all" -o "$enable_case_filter_in" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_case_filter_in=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_case_filter_in=no
        fi
      elif test "$enable_case_filter_in" = "reallyall" -o "$enable_case_filter_in" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_case_filter_in" != "no" ; then
          enable_case_filter_in=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_case_filter_in=no
        fi
      else
        enable_case_filter_in=no
      fi
      if test "$enable_case_filter_in" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_case_filter_in$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_case_filter_in$_apmod_extra_msg" >&6; }
      if test "$enable_case_filter_in" != "no"; then
        case "$enable_case_filter_in" in
        static*)
          MODLIST="$MODLIST case_filter_in"
          if test "case_filter_in" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES case_filter_in"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},case_filter_in"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_case_filter_in.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_case_filter_in.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CASE_FILTER_IN_LDADD)
    EOF
          if test ! -z "\$(MOD_CASE_FILTER_IN_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CASE_FILTER_IN_LDADD)\""
        AP_LIBS="\$(MOD_CASE_FILTER_IN_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CASE_FILTER_IN_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_case_filter_in.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  $objects \$(MOD_CASE_FILTER_IN_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CASE_FILTER_IN_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_example_ipc" >&5
    printf %s "checking whether to enable mod_example_ipc... " >&6; }
        # Check whether --enable-example-ipc was given.
    if test ${enable_example_ipc+y}
    then :
      enableval=$enable_example_ipc; force_example_ipc=$enableval
    else $as_nop
      enable_example_ipc=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_example_ipc" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_example_ipc" = "static" -o "$enable_example_ipc" = "shared"; then
        :
      elif test "$enable_example_ipc" = "yes"; then
        enable_example_ipc=$module_default
      elif test "$enable_example_ipc" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_example_ipc=$module_default
        else
          enable_example_ipc=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_example_ipc" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_example_ipc=$module_default
        else
          enable_example_ipc=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_example_ipc" = "all" -o "$enable_example_ipc" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_example_ipc=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_example_ipc=no
        fi
      elif test "$enable_example_ipc" = "reallyall" -o "$enable_example_ipc" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_example_ipc" != "no" ; then
          enable_example_ipc=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_example_ipc=no
        fi
      else
        enable_example_ipc=no
      fi
      if test "$enable_example_ipc" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_example_ipc$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_example_ipc$_apmod_extra_msg" >&6; }
      if test "$enable_example_ipc" != "no"; then
        case "$enable_example_ipc" in
        static*)
          MODLIST="$MODLIST example_ipc"
          if test "example_ipc" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES example_ipc"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},example_ipc"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_example_ipc.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_example_ipc.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_EXAMPLE_IPC_LDADD)
    EOF
          if test ! -z "\$(MOD_EXAMPLE_IPC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_EXAMPLE_IPC_LDADD)\""
        AP_LIBS="\$(MOD_EXAMPLE_IPC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_EXAMPLE_IPC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_example_ipc.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  $objects \$(MOD_EXAMPLE_IPC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_EXAMPLE_IPC_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=experimental
      modpath_current=modules/experimental
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d experimental || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=filters
      modpath_current=modules/filters
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d filters || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_buffer" >&5
    printf %s "checking whether to enable mod_buffer... " >&6; }
        # Check whether --enable-buffer was given.
    if test ${enable_buffer+y}
    then :
      enableval=$enable_buffer; force_buffer=$enableval
    else $as_nop
      enable_buffer=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_buffer" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_buffer" = "static" -o "$enable_buffer" = "shared"; then
        :
      elif test "$enable_buffer" = "yes"; then
        enable_buffer=$module_default
      elif test "$enable_buffer" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_buffer=$module_default
        else
          enable_buffer=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_buffer" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_buffer=$module_default
        else
          enable_buffer=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_buffer" = "all" -o "$enable_buffer" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_buffer=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_buffer=no
        fi
      elif test "$enable_buffer" = "reallyall" -o "$enable_buffer" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_buffer" != "no" ; then
          enable_buffer=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_buffer=no
        fi
      else
        enable_buffer=no
      fi
      if test "$enable_buffer" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_buffer$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_buffer$_apmod_extra_msg" >&6; }
      if test "$enable_buffer" != "no"; then
        case "$enable_buffer" in
        static*)
          MODLIST="$MODLIST buffer"
          if test "buffer" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES buffer"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},buffer"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_buffer.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_buffer.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_BUFFER_LDADD)
    EOF
          if test ! -z "\$(MOD_BUFFER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_BUFFER_LDADD)\""
        AP_LIBS="\$(MOD_BUFFER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_BUFFER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_buffer.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  $objects \$(MOD_BUFFER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_BUFFER_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_data" >&5
    printf %s "checking whether to enable mod_data... " >&6; }
        # Check whether --enable-data was given.
    if test ${enable_data+y}
    then :
      enableval=$enable_data; force_data=$enableval
    else $as_nop
      enable_data=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_data" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_data" = "static" -o "$enable_data" = "shared"; then
        :
      elif test "$enable_data" = "yes"; then
        enable_data=$module_default
      elif test "$enable_data" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_data=$module_default
        else
          enable_data=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_data" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_data=$module_default
        else
          enable_data=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_data" = "all" -o "$enable_data" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_data=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_data=no
        fi
      elif test "$enable_data" = "reallyall" -o "$enable_data" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_data" != "no" ; then
          enable_data=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_data=no
        fi
      else
        enable_data=no
      fi
      if test "$enable_data" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_data$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_data$_apmod_extra_msg" >&6; }
      if test "$enable_data" != "no"; then
        case "$enable_data" in
        static*)
          MODLIST="$MODLIST data"
          if test "data" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES data"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},data"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_data.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_data.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DATA_LDADD)
    EOF
          if test ! -z "\$(MOD_DATA_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DATA_LDADD)\""
        AP_LIBS="\$(MOD_DATA_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DATA_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_data.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  $objects \$(MOD_DATA_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DATA_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_ratelimit" >&5
    printf %s "checking whether to enable mod_ratelimit... " >&6; }
        # Check whether --enable-ratelimit was given.
    if test ${enable_ratelimit+y}
    then :
      enableval=$enable_ratelimit; force_ratelimit=$enableval
    else $as_nop
      enable_ratelimit=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_ratelimit" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_ratelimit" = "static" -o "$enable_ratelimit" = "shared"; then
        :
      elif test "$enable_ratelimit" = "yes"; then
        enable_ratelimit=$module_default
      elif test "$enable_ratelimit" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ratelimit=$module_default
        else
          enable_ratelimit=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ratelimit" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_ratelimit=$module_default
        else
          enable_ratelimit=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ratelimit" = "all" -o "$enable_ratelimit" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ratelimit=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ratelimit=no
        fi
      elif test "$enable_ratelimit" = "reallyall" -o "$enable_ratelimit" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_ratelimit" != "no" ; then
          enable_ratelimit=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ratelimit=no
        fi
      else
        enable_ratelimit=no
      fi
      if test "$enable_ratelimit" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_ratelimit$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_ratelimit$_apmod_extra_msg" >&6; }
      if test "$enable_ratelimit" != "no"; then
        case "$enable_ratelimit" in
        static*)
          MODLIST="$MODLIST ratelimit"
          if test "ratelimit" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES ratelimit"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},ratelimit"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_ratelimit.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_ratelimit.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_RATELIMIT_LDADD)
    EOF
          if test ! -z "\$(MOD_RATELIMIT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_RATELIMIT_LDADD)\""
        AP_LIBS="\$(MOD_RATELIMIT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_RATELIMIT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_ratelimit.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  $objects \$(MOD_RATELIMIT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_RATELIMIT_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_reqtimeout" >&5
    printf %s "checking whether to enable mod_reqtimeout... " >&6; }
        # Check whether --enable-reqtimeout was given.
    if test ${enable_reqtimeout+y}
    then :
      enableval=$enable_reqtimeout; force_reqtimeout=$enableval
    else $as_nop
      enable_reqtimeout=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_reqtimeout" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_reqtimeout" = "static" -o "$enable_reqtimeout" = "shared"; then
        :
      elif test "$enable_reqtimeout" = "yes"; then
        enable_reqtimeout=$module_default
      elif test "$enable_reqtimeout" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_reqtimeout=$module_default
        else
          enable_reqtimeout=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_reqtimeout" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_reqtimeout=$module_default
        else
          enable_reqtimeout=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_reqtimeout" = "all" -o "$enable_reqtimeout" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_reqtimeout=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_reqtimeout=no
        fi
      elif test "$enable_reqtimeout" = "reallyall" -o "$enable_reqtimeout" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_reqtimeout" != "no" ; then
          enable_reqtimeout=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_reqtimeout=no
        fi
      else
        enable_reqtimeout=no
      fi
      if test "$enable_reqtimeout" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_reqtimeout$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_reqtimeout$_apmod_extra_msg" >&6; }
      if test "$enable_reqtimeout" != "no"; then
        case "$enable_reqtimeout" in
        static*)
          MODLIST="$MODLIST reqtimeout"
          if test "reqtimeout" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES reqtimeout"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},reqtimeout"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_reqtimeout.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_reqtimeout.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_REQTIMEOUT_LDADD)
    EOF
          if test ! -z "\$(MOD_REQTIMEOUT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_REQTIMEOUT_LDADD)\""
        AP_LIBS="\$(MOD_REQTIMEOUT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_REQTIMEOUT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_reqtimeout.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  $objects \$(MOD_REQTIMEOUT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_REQTIMEOUT_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_ext_filter" >&5
    printf %s "checking whether to enable mod_ext_filter... " >&6; }
        # Check whether --enable-ext-filter was given.
    if test ${enable_ext_filter+y}
    then :
      enableval=$enable_ext_filter; force_ext_filter=$enableval
    else $as_nop
      enable_ext_filter=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_ext_filter" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_ext_filter" = "static" -o "$enable_ext_filter" = "shared"; then
        :
      elif test "$enable_ext_filter" = "yes"; then
        enable_ext_filter=$module_default
      elif test "$enable_ext_filter" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ext_filter=$module_default
        else
          enable_ext_filter=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ext_filter" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_ext_filter=$module_default
        else
          enable_ext_filter=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ext_filter" = "all" -o "$enable_ext_filter" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ext_filter=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ext_filter=no
        fi
      elif test "$enable_ext_filter" = "reallyall" -o "$enable_ext_filter" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_ext_filter" != "no" ; then
          enable_ext_filter=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ext_filter=no
        fi
      else
        enable_ext_filter=no
      fi
      if test "$enable_ext_filter" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_ext_filter$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_ext_filter$_apmod_extra_msg" >&6; }
      if test "$enable_ext_filter" != "no"; then
        case "$enable_ext_filter" in
        static*)
          MODLIST="$MODLIST ext_filter"
          if test "ext_filter" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES ext_filter"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},ext_filter"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_ext_filter.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_ext_filter.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_EXT_FILTER_LDADD)
    EOF
          if test ! -z "\$(MOD_EXT_FILTER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_EXT_FILTER_LDADD)\""
        AP_LIBS="\$(MOD_EXT_FILTER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_EXT_FILTER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_ext_filter.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  $objects \$(MOD_EXT_FILTER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_EXT_FILTER_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_request" >&5
    printf %s "checking whether to enable mod_request... " >&6; }
        # Check whether --enable-request was given.
    if test ${enable_request+y}
    then :
      enableval=$enable_request; force_request=$enableval
    else $as_nop
      enable_request=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_request" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_request" = "static" -o "$enable_request" = "shared"; then
        :
      elif test "$enable_request" = "yes"; then
        enable_request=$module_default
      elif test "$enable_request" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_request=$module_default
        else
          enable_request=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_request" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_request=$module_default
        else
          enable_request=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_request" = "all" -o "$enable_request" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_request=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_request=no
        fi
      elif test "$enable_request" = "reallyall" -o "$enable_request" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_request" != "no" ; then
          enable_request=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_request=no
        fi
      else
        enable_request=no
      fi
      if test "$enable_request" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_request$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_request$_apmod_extra_msg" >&6; }
      if test "$enable_request" != "no"; then
        case "$enable_request" in
        static*)
          MODLIST="$MODLIST request"
          if test "request" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES request"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},request"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_request.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_request.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_REQUEST_LDADD)
    EOF
          if test ! -z "\$(MOD_REQUEST_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_REQUEST_LDADD)\""
        AP_LIBS="\$(MOD_REQUEST_LDADD)"
      else
        apr_addto_bugger="\$(MOD_REQUEST_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_request.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  $objects \$(MOD_REQUEST_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_REQUEST_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_include" >&5
    printf %s "checking whether to enable mod_include... " >&6; }
        # Check whether --enable-include was given.
    if test ${enable_include+y}
    then :
      enableval=$enable_include; force_include=$enableval
    else $as_nop
      enable_include=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_include" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_include" = "static" -o "$enable_include" = "shared"; then
        :
      elif test "$enable_include" = "yes"; then
        enable_include=$module_default
      elif test "$enable_include" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_include=$module_default
        else
          enable_include=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_include" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_include=$module_default
        else
          enable_include=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_include" = "all" -o "$enable_include" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_include=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_include=no
        fi
      elif test "$enable_include" = "reallyall" -o "$enable_include" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_include" != "no" ; then
          enable_include=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_include=no
        fi
      else
        enable_include=no
      fi
      if test "$enable_include" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_include$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_include$_apmod_extra_msg" >&6; }
      if test "$enable_include" != "no"; then
        case "$enable_include" in
        static*)
          MODLIST="$MODLIST include"
          if test "include" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES include"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},include"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_include.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_include.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_INCLUDE_LDADD)
    EOF
          if test ! -z "\$(MOD_INCLUDE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_INCLUDE_LDADD)\""
        AP_LIBS="\$(MOD_INCLUDE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_INCLUDE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_include.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  $objects \$(MOD_INCLUDE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_INCLUDE_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_filter" >&5
    printf %s "checking whether to enable mod_filter... " >&6; }
        # Check whether --enable-filter was given.
    if test ${enable_filter+y}
    then :
      enableval=$enable_filter; force_filter=$enableval
    else $as_nop
      enable_filter=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_filter" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_filter" = "static" -o "$enable_filter" = "shared"; then
        :
      elif test "$enable_filter" = "yes"; then
        enable_filter=$module_default
      elif test "$enable_filter" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_filter=$module_default
        else
          enable_filter=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_filter" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_filter=$module_default
        else
          enable_filter=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_filter" = "all" -o "$enable_filter" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_filter=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_filter=no
        fi
      elif test "$enable_filter" = "reallyall" -o "$enable_filter" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_filter" != "no" ; then
          enable_filter=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_filter=no
        fi
      else
        enable_filter=no
      fi
      if test "$enable_filter" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_filter$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_filter$_apmod_extra_msg" >&6; }
      if test "$enable_filter" != "no"; then
        case "$enable_filter" in
        static*)
          MODLIST="$MODLIST filter"
          if test "filter" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES filter"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},filter"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_filter.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_filter.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_FILTER_LDADD)
    EOF
          if test ! -z "\$(MOD_FILTER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_FILTER_LDADD)\""
        AP_LIBS="\$(MOD_FILTER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_FILTER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_filter.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  $objects \$(MOD_FILTER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_FILTER_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_reflector" >&5
    printf %s "checking whether to enable mod_reflector... " >&6; }
        # Check whether --enable-reflector was given.
    if test ${enable_reflector+y}
    then :
      enableval=$enable_reflector; force_reflector=$enableval
    else $as_nop
      enable_reflector=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_reflector" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_reflector" = "static" -o "$enable_reflector" = "shared"; then
        :
      elif test "$enable_reflector" = "yes"; then
        enable_reflector=$module_default
      elif test "$enable_reflector" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_reflector=$module_default
        else
          enable_reflector=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_reflector" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_reflector=$module_default
        else
          enable_reflector=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_reflector" = "all" -o "$enable_reflector" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_reflector=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_reflector=no
        fi
      elif test "$enable_reflector" = "reallyall" -o "$enable_reflector" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_reflector" != "no" ; then
          enable_reflector=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_reflector=no
        fi
      else
        enable_reflector=no
      fi
      if test "$enable_reflector" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_reflector$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_reflector$_apmod_extra_msg" >&6; }
      if test "$enable_reflector" != "no"; then
        case "$enable_reflector" in
        static*)
          MODLIST="$MODLIST reflector"
          if test "reflector" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES reflector"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},reflector"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_reflector.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_reflector.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_REFLECTOR_LDADD)
    EOF
          if test ! -z "\$(MOD_REFLECTOR_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_REFLECTOR_LDADD)\""
        AP_LIBS="\$(MOD_REFLECTOR_LDADD)"
      else
        apr_addto_bugger="\$(MOD_REFLECTOR_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_reflector.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  $objects \$(MOD_REFLECTOR_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_REFLECTOR_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_substitute" >&5
    printf %s "checking whether to enable mod_substitute... " >&6; }
        # Check whether --enable-substitute was given.
    if test ${enable_substitute+y}
    then :
      enableval=$enable_substitute; force_substitute=$enableval
    else $as_nop
      enable_substitute=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_substitute" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_substitute" = "static" -o "$enable_substitute" = "shared"; then
        :
      elif test "$enable_substitute" = "yes"; then
        enable_substitute=$module_default
      elif test "$enable_substitute" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_substitute=$module_default
        else
          enable_substitute=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_substitute" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_substitute=$module_default
        else
          enable_substitute=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_substitute" = "all" -o "$enable_substitute" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_substitute=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_substitute=no
        fi
      elif test "$enable_substitute" = "reallyall" -o "$enable_substitute" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_substitute" != "no" ; then
          enable_substitute=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_substitute=no
        fi
      else
        enable_substitute=no
      fi
      if test "$enable_substitute" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_substitute$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_substitute$_apmod_extra_msg" >&6; }
      if test "$enable_substitute" != "no"; then
        case "$enable_substitute" in
        static*)
          MODLIST="$MODLIST substitute"
          if test "substitute" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES substitute"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},substitute"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_substitute.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_substitute.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SUBSTITUTE_LDADD)
    EOF
          if test ! -z "\$(MOD_SUBSTITUTE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SUBSTITUTE_LDADD)\""
        AP_LIBS="\$(MOD_SUBSTITUTE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SUBSTITUTE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_substitute.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  $objects \$(MOD_SUBSTITUTE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SUBSTITUTE_LDADD"
    
    
    
      fi
    
    
    sed_obj="mod_sed.lo sed0.lo sed1.lo regexp.lo"
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_sed" >&5
    printf %s "checking whether to enable mod_sed... " >&6; }
        # Check whether --enable-sed was given.
    if test ${enable_sed+y}
    then :
      enableval=$enable_sed; force_sed=$enableval
    else $as_nop
      enable_sed=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_sed" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_sed" = "static" -o "$enable_sed" = "shared"; then
        :
      elif test "$enable_sed" = "yes"; then
        enable_sed=$module_default
      elif test "$enable_sed" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_sed=$module_default
        else
          enable_sed=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_sed" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_sed=$module_default
        else
          enable_sed=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_sed" = "all" -o "$enable_sed" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_sed=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_sed=no
        fi
      elif test "$enable_sed" = "reallyall" -o "$enable_sed" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_sed" != "no" ; then
          enable_sed=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_sed=no
        fi
      else
        enable_sed=no
      fi
      if test "$enable_sed" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
        if test "x$enable_sed" = "xshared"; then
            # The only symbol which needs to be exported is the module
            # structure, so ask libtool to hide libsed internals:
    
      if test "x$MOD_SED_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_SED_LDADD to \"-export-symbols-regex sed_module\""
        MOD_SED_LDADD="-export-symbols-regex sed_module"
      else
        apr_addto_bugger="-export-symbols-regex sed_module"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_SED_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_SED_LDADD"
            MOD_SED_LDADD="$MOD_SED_LDADD $i"
          fi
        done
      fi
    
        fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_sed" >&5
    printf %s "checking whether to enable mod_sed... " >&6; }
                if test "$enable_sed" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_sed has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_sed$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_sed$_apmod_extra_msg" >&6; }
      if test "$enable_sed" != "no"; then
        case "$enable_sed" in
        static*)
          MODLIST="$MODLIST sed"
          if test "sed" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES sed"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},sed"
          fi
          ;;
        esac
    
    
      if test -z "$sed_obj"; then
        objects="mod_sed.lo"
      else
        objects="$sed_obj"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_sed.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SED_LDADD)
    EOF
          if test ! -z "\$(MOD_SED_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SED_LDADD)\""
        AP_LIBS="\$(MOD_SED_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SED_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_sed.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  $objects \$(MOD_SED_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SED_LDADD"
    
    
    
      fi
    
    
    if test "$ac_cv_ebcdic" = "yes"; then
    # mod_charset_lite can be very useful on an ebcdic system,
    #   so include it by default
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_charset_lite" >&5
    printf %s "checking whether to enable mod_charset_lite... " >&6; }
        # Check whether --enable-charset-lite was given.
    if test ${enable_charset_lite+y}
    then :
      enableval=$enable_charset_lite; force_charset_lite=$enableval
    else $as_nop
      enable_charset_lite=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_charset_lite" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_charset_lite" = "static" -o "$enable_charset_lite" = "shared"; then
        :
      elif test "$enable_charset_lite" = "yes"; then
        enable_charset_lite=$module_default
      elif test "$enable_charset_lite" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_charset_lite=$module_default
        else
          enable_charset_lite=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_charset_lite" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_charset_lite=$module_default
        else
          enable_charset_lite=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_charset_lite" = "all" -o "$enable_charset_lite" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_charset_lite=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_charset_lite=no
        fi
      elif test "$enable_charset_lite" = "reallyall" -o "$enable_charset_lite" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_charset_lite" != "no" ; then
          enable_charset_lite=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_charset_lite=no
        fi
      else
        enable_charset_lite=no
      fi
      if test "$enable_charset_lite" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_charset_lite$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_charset_lite$_apmod_extra_msg" >&6; }
      if test "$enable_charset_lite" != "no"; then
        case "$enable_charset_lite" in
        static*)
          MODLIST="$MODLIST charset_lite"
          if test "charset_lite" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES charset_lite"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},charset_lite"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_charset_lite.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_charset_lite.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CHARSET_LITE_LDADD)
    EOF
          if test ! -z "\$(MOD_CHARSET_LITE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CHARSET_LITE_LDADD)\""
        AP_LIBS="\$(MOD_CHARSET_LITE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CHARSET_LITE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_charset_lite.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  $objects \$(MOD_CHARSET_LITE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CHARSET_LITE_LDADD"
    
    
    
      fi
    
    else
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_charset_lite" >&5
    printf %s "checking whether to enable mod_charset_lite... " >&6; }
        # Check whether --enable-charset-lite was given.
    if test ${enable_charset_lite+y}
    then :
      enableval=$enable_charset_lite; force_charset_lite=$enableval
    else $as_nop
      enable_charset_lite=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_charset_lite" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_charset_lite" = "static" -o "$enable_charset_lite" = "shared"; then
        :
      elif test "$enable_charset_lite" = "yes"; then
        enable_charset_lite=$module_default
      elif test "$enable_charset_lite" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_charset_lite=$module_default
        else
          enable_charset_lite=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_charset_lite" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_charset_lite=$module_default
        else
          enable_charset_lite=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_charset_lite" = "all" -o "$enable_charset_lite" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_charset_lite=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_charset_lite=no
        fi
      elif test "$enable_charset_lite" = "reallyall" -o "$enable_charset_lite" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_charset_lite" != "no" ; then
          enable_charset_lite=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_charset_lite=no
        fi
      else
        enable_charset_lite=no
      fi
      if test "$enable_charset_lite" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_charset_lite$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_charset_lite$_apmod_extra_msg" >&6; }
      if test "$enable_charset_lite" != "no"; then
        case "$enable_charset_lite" in
        static*)
          MODLIST="$MODLIST charset_lite"
          if test "charset_lite" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES charset_lite"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},charset_lite"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_charset_lite.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_charset_lite.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CHARSET_LITE_LDADD)
    EOF
          if test ! -z "\$(MOD_CHARSET_LITE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CHARSET_LITE_LDADD)\""
        AP_LIBS="\$(MOD_CHARSET_LITE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CHARSET_LITE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_charset_lite.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  $objects \$(MOD_CHARSET_LITE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CHARSET_LITE_LDADD"
    
    
    
      fi
    
    fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_deflate" >&5
    printf %s "checking whether to enable mod_deflate... " >&6; }
        # Check whether --enable-deflate was given.
    if test ${enable_deflate+y}
    then :
      enableval=$enable_deflate; force_deflate=$enableval
    else $as_nop
      enable_deflate=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_deflate" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_deflate" = "static" -o "$enable_deflate" = "shared"; then
        :
      elif test "$enable_deflate" = "yes"; then
        enable_deflate=$module_default
      elif test "$enable_deflate" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_deflate=$module_default
        else
          enable_deflate=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_deflate" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_deflate=$module_default
        else
          enable_deflate=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_deflate" = "all" -o "$enable_deflate" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_deflate=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_deflate=no
        fi
      elif test "$enable_deflate" = "reallyall" -o "$enable_deflate" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_deflate" != "no" ; then
          enable_deflate=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_deflate=no
        fi
      else
        enable_deflate=no
      fi
      if test "$enable_deflate" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
    # Check whether --with-z was given.
    if test ${with_z+y}
    then :
      withval=$with_z;
        if test "x$withval" != "xyes" && test "x$withval" != "x"; then
          ap_zlib_base="$withval"
          ap_zlib_with="yes"
        fi
    
    fi
    
      if test "x$ap_zlib_base" = "x"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib location" >&5
    printf %s "checking for zlib location... " >&6; }
        if test ${ap_cv_zlib+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
          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
    
    fi
    
        ap_zlib_base=$ap_cv_zlib
        if test "x$ap_zlib_base" = "x"; then
          enable_deflate=no
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
    printf "%s\n" "not found" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_zlib_base" >&5
    printf "%s\n" "$ap_zlib_base" >&6; }
        fi
      fi
      if test "$enable_deflate" != "no"; then
        ap_save_includes=$INCLUDES
        ap_save_ldflags=$LDFLAGS
        ap_save_cppflags=$CPPFLAGS
        ap_zlib_ldflags=""
        if test "$ap_zlib_base" != "/usr"; then
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I${ap_zlib_base}/include\""
        INCLUDES="-I${ap_zlib_base}/include"
      else
        apr_addto_bugger="-I${ap_zlib_base}/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
      if test "x$MOD_INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_INCLUDES to \"-I${ap_zlib_base}/include\""
        MOD_INCLUDES="-I${ap_zlib_base}/include"
      else
        apr_addto_bugger="-I${ap_zlib_base}/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_INCLUDES"
            MOD_INCLUDES="$MOD_INCLUDES $i"
          fi
        done
      fi
    
                CPPFLAGS="$CPPFLAGS $INCLUDES"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L${ap_zlib_base}/lib\""
        LDFLAGS="-L${ap_zlib_base}/lib"
      else
        apr_addto_bugger="-L${ap_zlib_base}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ap_zlib_ldflags" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ap_zlib_ldflags to \"-L${ap_zlib_base}/lib\""
        ap_zlib_ldflags="-L${ap_zlib_base}/lib"
      else
        apr_addto_bugger="-L${ap_zlib_base}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ap_zlib_ldflags; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ap_zlib_ldflags"
            ap_zlib_ldflags="$ap_zlib_ldflags $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag${ap_zlib_base}/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag${ap_zlib_base}/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${ap_zlib_base}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ap_zlib_ldflags" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ap_zlib_ldflags to \"$ap_platform_runtime_link_flag${ap_zlib_base}/lib\""
        ap_zlib_ldflags="$ap_platform_runtime_link_flag${ap_zlib_base}/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${ap_zlib_base}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ap_zlib_ldflags; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ap_zlib_ldflags"
            ap_zlib_ldflags="$ap_zlib_ldflags $i"
          fi
        done
      fi
    
          fi
        fi
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"-lz\""
        LIBS="-lz"
      else
        apr_addto_bugger="-lz"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib library" >&5
    printf %s "checking for zlib library... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <zlib.h>
    int
    main (void)
    {
    int i = Z_OK;
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5
    printf "%s\n" "found" >&6; }
    
      if test "x$MOD_DEFLATE_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_DEFLATE_LDADD to \"$ap_zlib_ldflags -lz\""
        MOD_DEFLATE_LDADD="$ap_zlib_ldflags -lz"
      else
        apr_addto_bugger="$ap_zlib_ldflags -lz"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_DEFLATE_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_DEFLATE_LDADD"
            MOD_DEFLATE_LDADD="$MOD_DEFLATE_LDADD $i"
          fi
        done
      fi
    
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
    printf "%s\n" "not found" >&6; }
           enable_deflate=no
           if test "x$ap_zlib_with" = "x"; then
             { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: ... Error, zlib was missing or unusable" >&5
    printf "%s\n" "$as_me: WARNING: ... Error, zlib was missing or unusable" >&2;}
           else
             as_fn_error $? "... Error, zlib was missing or unusable" "$LINENO" 5
           fi
    
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
        INCLUDES=$ap_save_includes
        LDFLAGS=$ap_save_ldflags
        CPPFLAGS=$ap_save_cppflags
    
      if test "x$LIBS" = "x-lz"; then
        test "x$silent" != "xyes" && echo "  nulling LIBS"
        LIBS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $LIBS; do
          if test "x$i" != "x-lz"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-lz\" from LIBS"
          LIBS=$apr_new_bugger
        fi
      fi
    
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_deflate" >&5
    printf %s "checking whether to enable mod_deflate... " >&6; }
                if test "$enable_deflate" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_deflate has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_deflate$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_deflate$_apmod_extra_msg" >&6; }
      if test "$enable_deflate" != "no"; then
        case "$enable_deflate" in
        static*)
          MODLIST="$MODLIST deflate"
          if test "deflate" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES deflate"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},deflate"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_deflate.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_deflate.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DEFLATE_LDADD)
    EOF
          if test ! -z "\$(MOD_DEFLATE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DEFLATE_LDADD)\""
        AP_LIBS="\$(MOD_DEFLATE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DEFLATE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_deflate.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  $objects \$(MOD_DEFLATE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DEFLATE_LDADD"
    
    
    
      fi
    
    
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_xml2enc" >&5
    printf %s "checking whether to enable mod_xml2enc... " >&6; }
        # Check whether --enable-xml2enc was given.
    if test ${enable_xml2enc+y}
    then :
      enableval=$enable_xml2enc; force_xml2enc=$enableval
    else $as_nop
      enable_xml2enc=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_xml2enc" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_xml2enc" = "static" -o "$enable_xml2enc" = "shared"; then
        :
      elif test "$enable_xml2enc" = "yes"; then
        enable_xml2enc=$module_default
      elif test "$enable_xml2enc" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_xml2enc=$module_default
        else
          enable_xml2enc=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_xml2enc" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_xml2enc=$module_default
        else
          enable_xml2enc=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_xml2enc" = "all" -o "$enable_xml2enc" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_xml2enc=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_xml2enc=no
        fi
      elif test "$enable_xml2enc" = "reallyall" -o "$enable_xml2enc" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_xml2enc" != "no" ; then
          enable_xml2enc=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_xml2enc=no
        fi
      else
        enable_xml2enc=no
      fi
      if test "$enable_xml2enc" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libxml2" >&5
    printf %s "checking for libxml2... " >&6; }
    if test ${ac_cv_libxml2+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
    
    # Check whether --with-libxml2 was given.
    if test ${with_libxml2+y}
    then :
      withval=$with_libxml2; test_paths="${with_libxml2}/include/libxml2 ${with_libxml2}/include ${with_libxml2}"
    else $as_nop
      test_paths="/usr/include/libxml2 /usr/local/include/libxml2 /usr/include /usr/local/include"
    
    fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libxml2" >&5
    printf %s "checking for libxml2... " >&6; }
        xml2_path=""
        for x in ${test_paths}; do
            if test -f "${x}/libxml/parser.h"; then
              xml2_path="${x}"
              break
            fi
        done
        if test -n "${xml2_path}" ; then
          ac_cv_libxml2=yes
          XML2_INCLUDES="${xml2_path}"
        else
          ac_cv_libxml2=no
        fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libxml2" >&5
    printf "%s\n" "$ac_cv_libxml2" >&6; }
    
      if test "$ac_cv_libxml2" = "yes" ; then
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I${XML2_INCLUDES}\""
        MOD_CFLAGS="-I${XML2_INCLUDES}"
      else
        apr_addto_bugger="-I${XML2_INCLUDES}"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_XML2ENC_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_XML2ENC_LDADD to \"-lxml2\""
        MOD_XML2ENC_LDADD="-lxml2"
      else
        apr_addto_bugger="-lxml2"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_XML2ENC_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_XML2ENC_LDADD"
            MOD_XML2ENC_LDADD="$MOD_XML2ENC_LDADD $i"
          fi
        done
      fi
    
      else
        enable_xml2enc=no
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_xml2enc" >&5
    printf %s "checking whether to enable mod_xml2enc... " >&6; }
                if test "$enable_xml2enc" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_xml2enc has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_xml2enc$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_xml2enc$_apmod_extra_msg" >&6; }
      if test "$enable_xml2enc" != "no"; then
        case "$enable_xml2enc" in
        static*)
          MODLIST="$MODLIST xml2enc"
          if test "xml2enc" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES xml2enc"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},xml2enc"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_xml2enc.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_xml2enc.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_XML2ENC_LDADD)
    EOF
          if test ! -z "\$(MOD_XML2ENC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_XML2ENC_LDADD)\""
        AP_LIBS="\$(MOD_XML2ENC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_XML2ENC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_xml2enc.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  $objects \$(MOD_XML2ENC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_XML2ENC_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_html" >&5
    printf %s "checking whether to enable mod_proxy_html... " >&6; }
        # Check whether --enable-proxy-html was given.
    if test ${enable_proxy_html+y}
    then :
      enableval=$enable_proxy_html; force_proxy_html=$enableval
    else $as_nop
      enable_proxy_html=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_html" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_html" = "static" -o "$enable_proxy_html" = "shared"; then
        :
      elif test "$enable_proxy_html" = "yes"; then
        enable_proxy_html=$module_default
      elif test "$enable_proxy_html" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_html=$module_default
        else
          enable_proxy_html=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_html" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_html=$module_default
        else
          enable_proxy_html=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_html" = "all" -o "$enable_proxy_html" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_html=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_html=no
        fi
      elif test "$enable_proxy_html" = "reallyall" -o "$enable_proxy_html" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_html" != "no" ; then
          enable_proxy_html=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_html=no
        fi
      else
        enable_proxy_html=no
      fi
      if test "$enable_proxy_html" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libxml2" >&5
    printf %s "checking for libxml2... " >&6; }
    if test ${ac_cv_libxml2+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
    
    # Check whether --with-libxml2 was given.
    if test ${with_libxml2+y}
    then :
      withval=$with_libxml2; test_paths="${with_libxml2}/include/libxml2 ${with_libxml2}/include ${with_libxml2}"
    else $as_nop
      test_paths="/usr/include/libxml2 /usr/local/include/libxml2 /usr/include /usr/local/include"
    
    fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libxml2" >&5
    printf %s "checking for libxml2... " >&6; }
        xml2_path=""
        for x in ${test_paths}; do
            if test -f "${x}/libxml/parser.h"; then
              xml2_path="${x}"
              break
            fi
        done
        if test -n "${xml2_path}" ; then
          ac_cv_libxml2=yes
          XML2_INCLUDES="${xml2_path}"
        else
          ac_cv_libxml2=no
        fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libxml2" >&5
    printf "%s\n" "$ac_cv_libxml2" >&6; }
    
      if test "$ac_cv_libxml2" = "yes" ; then
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I${XML2_INCLUDES}\""
        MOD_CFLAGS="-I${XML2_INCLUDES}"
      else
        apr_addto_bugger="-I${XML2_INCLUDES}"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_PROXY_HTML_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_PROXY_HTML_LDADD to \"-lxml2\""
        MOD_PROXY_HTML_LDADD="-lxml2"
      else
        apr_addto_bugger="-lxml2"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_PROXY_HTML_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_PROXY_HTML_LDADD"
            MOD_PROXY_HTML_LDADD="$MOD_PROXY_HTML_LDADD $i"
          fi
        done
      fi
    
      else
        enable_proxy_html=no
      fi
    
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_html" >&5
    printf %s "checking whether to enable mod_proxy_html... " >&6; }
                if test "$enable_proxy_html" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_html has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_html$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_html$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_html" != "no"; then
        case "$enable_proxy_html" in
        static*)
          MODLIST="$MODLIST proxy_html"
          if test "proxy_html" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_html"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_html"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_proxy_html.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_html.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_HTML_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_HTML_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_HTML_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_HTML_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_HTML_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_html.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  $objects \$(MOD_PROXY_HTML_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_HTML_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_brotli" >&5
    printf %s "checking whether to enable mod_brotli... " >&6; }
        # Check whether --enable-brotli was given.
    if test ${enable_brotli+y}
    then :
      enableval=$enable_brotli; force_brotli=$enableval
    else $as_nop
      enable_brotli=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_brotli" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_brotli" = "static" -o "$enable_brotli" = "shared"; then
        :
      elif test "$enable_brotli" = "yes"; then
        enable_brotli=$module_default
      elif test "$enable_brotli" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_brotli=$module_default
        else
          enable_brotli=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_brotli" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_brotli=$module_default
        else
          enable_brotli=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_brotli" = "all" -o "$enable_brotli" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_brotli=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_brotli=no
        fi
      elif test "$enable_brotli" = "reallyall" -o "$enable_brotli" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_brotli" != "no" ; then
          enable_brotli=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_brotli=no
        fi
      else
        enable_brotli=no
      fi
      if test "$enable_brotli" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
    # Check whether --with-brotli was given.
    if test ${with_brotli+y}
    then :
      withval=$with_brotli;
        if test "$withval" != "yes" -a "x$withval" != "x"; then
          ap_brotli_base="$withval"
          ap_brotli_with=yes
        fi
    
    fi
    
      ap_brotli_found=no
      if test -n "$ap_brotli_base"; then
        ap_save_cppflags=$CPPFLAGS
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I${ap_brotli_base}/include\""
        CPPFLAGS="-I${ap_brotli_base}/include"
      else
        apr_addto_bugger="-I${ap_brotli_base}/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Brotli library >= 0.6.0 via prefix" >&5
    printf %s "checking for Brotli library >= 0.6.0 via prefix... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <brotli/encode.h>
    int
    main (void)
    {
    
    const uint8_t *o = BrotliEncoderTakeOutput((BrotliEncoderState*)0, (size_t*)0);
    if (o) return *o;
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
           ap_brotli_found=yes
           ap_brotli_cflags="-I${ap_brotli_base}/include"
           ap_brotli_libs="-L${ap_brotli_base}/lib -lbrotlienc -lbrotlicommon"
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
    
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
        CPPFLAGS=$ap_save_cppflags
      else
        if test -n "$PKGCONFIG"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Brotli library >= 0.6.0 via pkg-config" >&5
    printf %s "checking for Brotli library >= 0.6.0 via pkg-config... " >&6; }
          if $PKGCONFIG --exists "libbrotlienc >= 0.6.0"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            ap_brotli_found=yes
            ap_brotli_cflags=`$PKGCONFIG libbrotlienc --cflags`
            ap_brotli_libs=`$PKGCONFIG libbrotlienc --libs`
          else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
          fi
        fi
      fi
      if test "$ap_brotli_found" = "yes"; then
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$ap_brotli_cflags\""
        MOD_CFLAGS="$ap_brotli_cflags"
      else
        apr_addto_bugger="$ap_brotli_cflags"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_BROTLI_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_BROTLI_LDADD to \"$ap_brotli_libs\""
        MOD_BROTLI_LDADD="$ap_brotli_libs"
      else
        apr_addto_bugger="$ap_brotli_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_BROTLI_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_BROTLI_LDADD"
            MOD_BROTLI_LDADD="$MOD_BROTLI_LDADD $i"
          fi
        done
      fi
    
        if test "$enable_brotli" = "shared"; then
    
      if test "x$MOD_BROTLI_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_BROTLI_LDADD to \"-export-symbols-regex brotli_module\""
        MOD_BROTLI_LDADD="-export-symbols-regex brotli_module"
      else
        apr_addto_bugger="-export-symbols-regex brotli_module"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_BROTLI_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_BROTLI_LDADD"
            MOD_BROTLI_LDADD="$MOD_BROTLI_LDADD $i"
          fi
        done
      fi
    
        fi
      else
        enable_brotli=no
        if test "$ap_brotli_with" = "yes"; then
          as_fn_error $? "Brotli library was missing or unusable" "$LINENO" 5
        fi
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_brotli" >&5
    printf %s "checking whether to enable mod_brotli... " >&6; }
                if test "$enable_brotli" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_brotli has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_brotli$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_brotli$_apmod_extra_msg" >&6; }
      if test "$enable_brotli" != "no"; then
        case "$enable_brotli" in
        static*)
          MODLIST="$MODLIST brotli"
          if test "brotli" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES brotli"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},brotli"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_brotli.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_brotli.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_BROTLI_LDADD)
    EOF
          if test ! -z "\$(MOD_BROTLI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_BROTLI_LDADD)\""
        AP_LIBS="\$(MOD_BROTLI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_BROTLI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_brotli.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  $objects \$(MOD_BROTLI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_BROTLI_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=http
      modpath_current=modules/http
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d http || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    http_objects="http_core.lo http_protocol.lo http_request.lo http_filters.lo chunk_filter.lo byterange_filter.lo http_etag.lo"
    
    if test "$enable_http" = "yes"; then
        enable_http="static"
    elif test "$enable_http" = "shared"; then
        as_fn_error $? "mod_http can not be built as a shared DSO" "$LINENO" 5
    fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_http" >&5
    printf %s "checking whether to enable mod_http... " >&6; }
        # Check whether --enable-http was given.
    if test ${enable_http+y}
    then :
      enableval=$enable_http; force_http=$enableval
    else $as_nop
      enable_http=static
    fi
    
        _apmod_extra_msg=""
          case "$enable_http" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_http" = "static" -o "$enable_http" = "shared"; then
        :
      elif test "$enable_http" = "yes"; then
        enable_http=$module_default
      elif test "$enable_http" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_http=$module_default
        else
          enable_http=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_http" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_http=$module_default
        else
          enable_http=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_http" = "all" -o "$enable_http" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_http=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_http=no
        fi
      elif test "$enable_http" = "reallyall" -o "$enable_http" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_http" != "no" ; then
          enable_http=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_http=no
        fi
      else
        enable_http=no
      fi
      if test "$enable_http" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_http$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_http$_apmod_extra_msg" >&6; }
      if test "$enable_http" != "no"; then
        case "$enable_http" in
        static*)
          MODLIST="$MODLIST http"
          if test "http" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES http"
          if test "static" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},http"
          fi
          ;;
        esac
    
    
      if test -z "$http_objects"; then
        objects="mod_http.lo"
      else
        objects="$http_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_http.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_HTTP_LDADD)
    EOF
          if test ! -z "\$(MOD_HTTP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_HTTP_LDADD)\""
        AP_LIBS="\$(MOD_HTTP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_HTTP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_http.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  $objects \$(MOD_HTTP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_HTTP_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_mime" >&5
    printf %s "checking whether to enable mod_mime... " >&6; }
        # Check whether --enable-mime was given.
    if test ${enable_mime+y}
    then :
      enableval=$enable_mime; force_mime=$enableval
    else $as_nop
      enable_mime=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_mime" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_mime" = "static" -o "$enable_mime" = "shared"; then
        :
      elif test "$enable_mime" = "yes"; then
        enable_mime=$module_default
      elif test "$enable_mime" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_mime=$module_default
        else
          enable_mime=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_mime" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_mime=$module_default
        else
          enable_mime=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_mime" = "all" -o "$enable_mime" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_mime=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_mime=no
        fi
      elif test "$enable_mime" = "reallyall" -o "$enable_mime" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_mime" != "no" ; then
          enable_mime=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_mime=no
        fi
      else
        enable_mime=no
      fi
      if test "$enable_mime" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_mime$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_mime$_apmod_extra_msg" >&6; }
      if test "$enable_mime" != "no"; then
        case "$enable_mime" in
        static*)
          MODLIST="$MODLIST mime"
          if test "mime" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES mime"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},mime"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_mime.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_mime.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_MIME_LDADD)
    EOF
          if test ! -z "\$(MOD_MIME_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_MIME_LDADD)\""
        AP_LIBS="\$(MOD_MIME_LDADD)"
      else
        apr_addto_bugger="\$(MOD_MIME_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_mime.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  $objects \$(MOD_MIME_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_MIME_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=ldap
      modpath_current=modules/ldap
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d ldap || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    ldap_objects="util_ldap.lo util_ldap_cache.lo util_ldap_cache_mgr.lo"
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_ldap" >&5
    printf %s "checking whether to enable mod_ldap... " >&6; }
        # Check whether --enable-ldap was given.
    if test ${enable_ldap+y}
    then :
      enableval=$enable_ldap; force_ldap=$enableval
    else $as_nop
      enable_ldap=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_ldap" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_ldap" = "static" -o "$enable_ldap" = "shared"; then
        :
      elif test "$enable_ldap" = "yes"; then
        enable_ldap=$module_default
      elif test "$enable_ldap" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ldap=$module_default
        else
          enable_ldap=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ldap" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_ldap=$module_default
        else
          enable_ldap=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ldap" = "all" -o "$enable_ldap" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ldap=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ldap=no
        fi
      elif test "$enable_ldap" = "reallyall" -o "$enable_ldap" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_ldap" != "no" ; then
          enable_ldap=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ldap=no
        fi
      else
        enable_ldap=no
      fi
      if test "$enable_ldap" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ldap support in apr/apr-util" >&5
    printf %s "checking for ldap support in apr/apr-util... " >&6; }
    if test ${ac_cv_APR_HAS_LDAP+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
        apache_old_cppflags="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS $INCLUDES"
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr_ldap.h>
    #if APR_HAS_LDAP
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_APR_HAS_LDAP=yes
    else $as_nop
      ac_cv_APR_HAS_LDAP=no
    fi
    rm -rf conftest*
    
        CPPFLAGS="$apache_old_cppflags"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_APR_HAS_LDAP" >&5
    printf "%s\n" "$ac_cv_APR_HAS_LDAP" >&6; }
    
      if test "$ac_cv_APR_HAS_LDAP" = "yes" ; then
        if test -z "$apu_config" ; then
          LDAP_LIBS="`$apr_config --ldap-libs`"
        else
          LDAP_LIBS="`$apu_config --ldap-libs`"
        fi
    
      if test "x$MOD_LDAP_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDAP_LDADD to \"$LDAP_LIBS\""
        MOD_LDAP_LDADD="$LDAP_LIBS"
      else
        apr_addto_bugger="$LDAP_LIBS"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDAP_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDAP_LDADD"
            MOD_LDAP_LDADD="$MOD_LDAP_LDADD $i"
          fi
        done
      fi
    
    
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: apr/apr-util is compiled without ldap support" >&5
    printf "%s\n" "$as_me: WARNING: apr/apr-util is compiled without ldap support" >&2;}
        enable_ldap=no
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_ldap" >&5
    printf %s "checking whether to enable mod_ldap... " >&6; }
                if test "$enable_ldap" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_ldap has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_ldap$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_ldap$_apmod_extra_msg" >&6; }
      if test "$enable_ldap" != "no"; then
        case "$enable_ldap" in
        static*)
          MODLIST="$MODLIST ldap"
          if test "ldap" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES ldap"
          if test "most " = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},ldap"
          fi
          ;;
        esac
    
    
      if test -z "$ldap_objects"; then
        objects="mod_ldap.lo"
      else
        objects="$ldap_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_ldap.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LDAP_LDADD)
    EOF
          if test ! -z "\$(MOD_LDAP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LDAP_LDADD)\""
        AP_LIBS="\$(MOD_LDAP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LDAP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_ldap.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  $objects \$(MOD_LDAP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LDAP_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=loggers
      modpath_current=modules/loggers
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d loggers || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_log_config" >&5
    printf %s "checking whether to enable mod_log_config... " >&6; }
        # Check whether --enable-log-config was given.
    if test ${enable_log_config+y}
    then :
      enableval=$enable_log_config; force_log_config=$enableval
    else $as_nop
      enable_log_config=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_log_config" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_log_config" = "static" -o "$enable_log_config" = "shared"; then
        :
      elif test "$enable_log_config" = "yes"; then
        enable_log_config=$module_default
      elif test "$enable_log_config" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_log_config=$module_default
        else
          enable_log_config=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_log_config" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_log_config=$module_default
        else
          enable_log_config=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_log_config" = "all" -o "$enable_log_config" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_log_config=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_log_config=no
        fi
      elif test "$enable_log_config" = "reallyall" -o "$enable_log_config" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_log_config" != "no" ; then
          enable_log_config=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_log_config=no
        fi
      else
        enable_log_config=no
      fi
      if test "$enable_log_config" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_log_config$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_log_config$_apmod_extra_msg" >&6; }
      if test "$enable_log_config" != "no"; then
        case "$enable_log_config" in
        static*)
          MODLIST="$MODLIST log_config"
          if test "log_config" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES log_config"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},log_config"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_log_config.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_log_config.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LOG_CONFIG_LDADD)
    EOF
          if test ! -z "\$(MOD_LOG_CONFIG_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LOG_CONFIG_LDADD)\""
        AP_LIBS="\$(MOD_LOG_CONFIG_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LOG_CONFIG_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_log_config.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  $objects \$(MOD_LOG_CONFIG_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LOG_CONFIG_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_log_debug" >&5
    printf %s "checking whether to enable mod_log_debug... " >&6; }
        # Check whether --enable-log-debug was given.
    if test ${enable_log_debug+y}
    then :
      enableval=$enable_log_debug; force_log_debug=$enableval
    else $as_nop
      enable_log_debug=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_log_debug" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_log_debug" = "static" -o "$enable_log_debug" = "shared"; then
        :
      elif test "$enable_log_debug" = "yes"; then
        enable_log_debug=$module_default
      elif test "$enable_log_debug" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_log_debug=$module_default
        else
          enable_log_debug=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_log_debug" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_log_debug=$module_default
        else
          enable_log_debug=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_log_debug" = "all" -o "$enable_log_debug" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_log_debug=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_log_debug=no
        fi
      elif test "$enable_log_debug" = "reallyall" -o "$enable_log_debug" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_log_debug" != "no" ; then
          enable_log_debug=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_log_debug=no
        fi
      else
        enable_log_debug=no
      fi
      if test "$enable_log_debug" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_log_debug$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_log_debug$_apmod_extra_msg" >&6; }
      if test "$enable_log_debug" != "no"; then
        case "$enable_log_debug" in
        static*)
          MODLIST="$MODLIST log_debug"
          if test "log_debug" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES log_debug"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},log_debug"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_log_debug.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_log_debug.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LOG_DEBUG_LDADD)
    EOF
          if test ! -z "\$(MOD_LOG_DEBUG_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LOG_DEBUG_LDADD)\""
        AP_LIBS="\$(MOD_LOG_DEBUG_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LOG_DEBUG_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_log_debug.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  $objects \$(MOD_LOG_DEBUG_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LOG_DEBUG_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_log_forensic" >&5
    printf %s "checking whether to enable mod_log_forensic... " >&6; }
        # Check whether --enable-log-forensic was given.
    if test ${enable_log_forensic+y}
    then :
      enableval=$enable_log_forensic; force_log_forensic=$enableval
    else $as_nop
      enable_log_forensic=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_log_forensic" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_log_forensic" = "static" -o "$enable_log_forensic" = "shared"; then
        :
      elif test "$enable_log_forensic" = "yes"; then
        enable_log_forensic=$module_default
      elif test "$enable_log_forensic" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_log_forensic=$module_default
        else
          enable_log_forensic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_log_forensic" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_log_forensic=$module_default
        else
          enable_log_forensic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_log_forensic" = "all" -o "$enable_log_forensic" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_log_forensic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_log_forensic=no
        fi
      elif test "$enable_log_forensic" = "reallyall" -o "$enable_log_forensic" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_log_forensic" != "no" ; then
          enable_log_forensic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_log_forensic=no
        fi
      else
        enable_log_forensic=no
      fi
      if test "$enable_log_forensic" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_log_forensic$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_log_forensic$_apmod_extra_msg" >&6; }
      if test "$enable_log_forensic" != "no"; then
        case "$enable_log_forensic" in
        static*)
          MODLIST="$MODLIST log_forensic"
          if test "log_forensic" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES log_forensic"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},log_forensic"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_log_forensic.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_log_forensic.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LOG_FORENSIC_LDADD)
    EOF
          if test ! -z "\$(MOD_LOG_FORENSIC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LOG_FORENSIC_LDADD)\""
        AP_LIBS="\$(MOD_LOG_FORENSIC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LOG_FORENSIC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_log_forensic.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  $objects \$(MOD_LOG_FORENSIC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LOG_FORENSIC_LDADD"
    
    
    
      fi
    
    
    if test "x$enable_log_forensic" != "xno"; then
        # mod_log_forensic needs test_char.h
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_builddir)/server\""
        INCLUDES="-I\$(top_builddir)/server"
      else
        apr_addto_bugger="-I\$(top_builddir)/server"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_logio" >&5
    printf %s "checking whether to enable mod_logio... " >&6; }
        # Check whether --enable-logio was given.
    if test ${enable_logio+y}
    then :
      enableval=$enable_logio; force_logio=$enableval
    else $as_nop
      enable_logio=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_logio" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_logio" = "static" -o "$enable_logio" = "shared"; then
        :
      elif test "$enable_logio" = "yes"; then
        enable_logio=$module_default
      elif test "$enable_logio" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_logio=$module_default
        else
          enable_logio=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_logio" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_logio=$module_default
        else
          enable_logio=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_logio" = "all" -o "$enable_logio" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_logio=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_logio=no
        fi
      elif test "$enable_logio" = "reallyall" -o "$enable_logio" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_logio" != "no" ; then
          enable_logio=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_logio=no
        fi
      else
        enable_logio=no
      fi
      if test "$enable_logio" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_logio$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_logio$_apmod_extra_msg" >&6; }
      if test "$enable_logio" != "no"; then
        case "$enable_logio" in
        static*)
          MODLIST="$MODLIST logio"
          if test "logio" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES logio"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},logio"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_logio.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_logio.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LOGIO_LDADD)
    EOF
          if test ! -z "\$(MOD_LOGIO_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LOGIO_LDADD)\""
        AP_LIBS="\$(MOD_LOGIO_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LOGIO_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_logio.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  $objects \$(MOD_LOGIO_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LOGIO_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=lua
      modpath_current=modules/lua
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d lua || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
    
    
    
    lua_objects="lua_apr.lo lua_config.lo mod_lua.lo lua_request.lo lua_vmprep.lo lua_dbd.lo lua_passwd.lo"
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lua" >&5
    printf %s "checking whether to enable mod_lua... " >&6; }
        # Check whether --enable-lua was given.
    if test ${enable_lua+y}
    then :
      enableval=$enable_lua; force_lua=$enableval
    else $as_nop
      enable_lua=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_lua" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_lua" = "static" -o "$enable_lua" = "shared"; then
        :
      elif test "$enable_lua" = "yes"; then
        enable_lua=$module_default
      elif test "$enable_lua" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lua=$module_default
        else
          enable_lua=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lua" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_lua=$module_default
        else
          enable_lua=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lua" = "all" -o "$enable_lua" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lua=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lua=no
        fi
      elif test "$enable_lua" = "reallyall" -o "$enable_lua" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_lua" != "no" ; then
          enable_lua=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lua=no
        fi
      else
        enable_lua=no
      fi
      if test "$enable_lua" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
    
    # Check whether --with-lua was given.
    if test ${with_lua+y}
    then :
      withval=$with_lua; lua_path="$withval"
    else $as_nop
      :
    fi
    
    
    if test -z "$lua_path"; then
        test_paths=". /usr/local /usr"
    else
        test_paths="${lua_path}"
    fi
    
    for pklua in lua lua5.4 lua5.3 lua5.2 lua5.1; do
      if test -n "$PKGCONFIG" -a -z "$lua_path" \
         && $PKGCONFIG --atleast-version=5.1 $pklua; then
        LUA_LIBS="`$PKGCONFIG --libs $pklua`"
        LUA_CFLAGS="`$PKGCONFIG --cflags $pklua`"
        LUA_VERSION="`$PKGCONFIG --modversion $pklua`"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: using Lua $LUA_VERSION configuration from pkg-config" >&5
    printf "%s\n" "$as_me: using Lua $LUA_VERSION configuration from pkg-config" >&6;}
        break
      fi
    done
    
    if test -z "$LUA_VERSION"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5
    printf %s "checking for pow in -lm... " >&6; }
    if test ${ac_cv_lib_m_pow+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-lm  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char pow ();
    int
    main (void)
    {
    return pow ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_m_pow=yes
    else $as_nop
      ac_cv_lib_m_pow=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5
    printf "%s\n" "$ac_cv_lib_m_pow" >&6; }
    if test "x$ac_cv_lib_m_pow" = xyes
    then :
      lib_m="-lm"
    fi
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
    printf %s "checking for sqrt in -lm... " >&6; }
    if test ${ac_cv_lib_m_sqrt+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-lm  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char sqrt ();
    int
    main (void)
    {
    return sqrt ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_m_sqrt=yes
    else $as_nop
      ac_cv_lib_m_sqrt=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5
    printf "%s\n" "$ac_cv_lib_m_sqrt" >&6; }
    if test "x$ac_cv_lib_m_sqrt" = xyes
    then :
      lib_m="-lm"
    fi
    
      for x in $test_paths ; do
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua-5.4" >&5
    printf %s "checking for lua.h in ${x}/include/lua-5.4... " >&6; }
        if test -f ${x}/include/lua-5.4/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua-5.4 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua-5.4" >&5
    printf %s "checking for luaL_newstate in -llua-5.4... " >&6; }
    if test ${ac_cv_lib_lua_5_4_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua-5.4  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_5_4_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_5_4_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_5_4_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_5_4_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_5_4_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua-5.4 -llua-5.4 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua-5.4\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua-5.4"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua-5.4"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua-5.4"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua5.4" >&5
    printf %s "checking for lua.h in ${x}/include/lua5.4... " >&6; }
        if test -f ${x}/include/lua5.4/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua5.4" >&5
    printf %s "checking for luaL_newstate in -llua5.4... " >&6; }
    if test ${ac_cv_lib_lua5_4_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua5.4  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua5_4_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua5_4_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua5_4_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua5_4_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua5_4_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib -llua5.4 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua5.4"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua54" >&5
    printf %s "checking for lua.h in ${x}/include/lua54... " >&6; }
        if test -f ${x}/include/lua54/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua54 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua" >&5
    printf %s "checking for luaL_newstate in -llua... " >&6; }
    if test ${ac_cv_lib_lua_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua54 -llua $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua54\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua54"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua54"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua54"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua-5.3" >&5
    printf %s "checking for lua.h in ${x}/include/lua-5.3... " >&6; }
        if test -f ${x}/include/lua-5.3/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua-5.3 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua-5.3" >&5
    printf %s "checking for luaL_newstate in -llua-5.3... " >&6; }
    if test ${ac_cv_lib_lua_5_3_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua-5.3  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_5_3_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_5_3_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_5_3_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_5_3_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_5_3_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua-5.3 -llua-5.3 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua-5.3\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua-5.3"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua-5.3"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua-5.3"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua5.3" >&5
    printf %s "checking for lua.h in ${x}/include/lua5.3... " >&6; }
        if test -f ${x}/include/lua5.3/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua5.3" >&5
    printf %s "checking for luaL_newstate in -llua5.3... " >&6; }
    if test ${ac_cv_lib_lua5_3_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua5.3  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua5_3_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua5_3_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua5_3_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua5_3_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua5_3_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib -llua5.3 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua5.3"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua53" >&5
    printf %s "checking for lua.h in ${x}/include/lua53... " >&6; }
        if test -f ${x}/include/lua53/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua53 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua" >&5
    printf %s "checking for luaL_newstate in -llua... " >&6; }
    if test ${ac_cv_lib_lua_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua53 -llua $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua53\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua53"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua53"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua53"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include" >&5
    printf %s "checking for lua.h in ${x}/include... " >&6; }
        if test -f ${x}/include/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua" >&5
    printf %s "checking for luaL_newstate in -llua... " >&6; }
    if test ${ac_cv_lib_lua_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib -llua $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua-5.2" >&5
    printf %s "checking for lua.h in ${x}/include/lua-5.2... " >&6; }
        if test -f ${x}/include/lua-5.2/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua-5.2 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua-5.2" >&5
    printf %s "checking for luaL_newstate in -llua-5.2... " >&6; }
    if test ${ac_cv_lib_lua_5_2_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua-5.2  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_5_2_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_5_2_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_5_2_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_5_2_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_5_2_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua-5.2 -llua-5.2 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua-5.2\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua-5.2"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua-5.2"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua-5.2"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua5.2" >&5
    printf %s "checking for lua.h in ${x}/include/lua5.2... " >&6; }
        if test -f ${x}/include/lua5.2/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua5.2" >&5
    printf %s "checking for luaL_newstate in -llua5.2... " >&6; }
    if test ${ac_cv_lib_lua5_2_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua5.2  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua5_2_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua5_2_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua5_2_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua5_2_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua5_2_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib -llua5.2 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua5.2"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua52" >&5
    printf %s "checking for lua.h in ${x}/include/lua52... " >&6; }
        if test -f ${x}/include/lua52/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua52 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua" >&5
    printf %s "checking for luaL_newstate in -llua... " >&6; }
    if test ${ac_cv_lib_lua_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua52 -llua $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua52\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua52"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua52"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua52"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua-5.1" >&5
    printf %s "checking for lua.h in ${x}/include/lua-5.1... " >&6; }
        if test -f ${x}/include/lua-5.1/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua-5.1 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua-5.1" >&5
    printf %s "checking for luaL_newstate in -llua-5.1... " >&6; }
    if test ${ac_cv_lib_lua_5_1_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua-5.1  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_5_1_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_5_1_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_5_1_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_5_1_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_5_1_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua-5.1 -llua-5.1 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua-5.1\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua-5.1"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua-5.1"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua-5.1"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua5.1" >&5
    printf %s "checking for lua.h in ${x}/include/lua5.1... " >&6; }
        if test -f ${x}/include/lua5.1/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua5.1" >&5
    printf %s "checking for luaL_newstate in -llua5.1... " >&6; }
    if test ${ac_cv_lib_lua5_1_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua5.1  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua5_1_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua5_1_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua5_1_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua5_1_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua5_1_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib -llua5.1 $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua5.1"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in ${x}/include/lua51" >&5
    printf %s "checking for lua.h in ${x}/include/lua51... " >&6; }
        if test -f ${x}/include/lua51/lua.h; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
            save_CFLAGS=$CFLAGS
            save_LDFLAGS=$LDFLAGS
            CFLAGS="$CFLAGS"
            LDFLAGS="-L${x}/lib/lua51 $LDFLAGS $lib_m"
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua" >&5
    printf %s "checking for luaL_newstate in -llua... " >&6; }
    if test ${ac_cv_lib_lua_luaL_newstate+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-llua  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char luaL_newstate ();
    int
    main (void)
    {
    return luaL_newstate ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_lua_luaL_newstate=yes
    else $as_nop
      ac_cv_lib_lua_luaL_newstate=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua_luaL_newstate" >&5
    printf "%s\n" "$ac_cv_lib_lua_luaL_newstate" >&6; }
    if test "x$ac_cv_lib_lua_luaL_newstate" = xyes
    then :
    
                LUA_LIBS="-L${x}/lib/lua51 -llua $lib_m"
                if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LUA_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LUA_LIBS to \"$ap_platform_runtime_link_flag${x}/lib/lua51\""
        LUA_LIBS="$ap_platform_runtime_link_flag${x}/lib/lua51"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag${x}/lib/lua51"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LUA_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LUA_LIBS"
            LUA_LIBS="$LUA_LIBS $i"
          fi
        done
      fi
    
                fi
                LUA_CFLAGS="-I${x}/include/lua51"
    
    fi
    
            CFLAGS=$save_CFLAGS
            LDFLAGS=$save_LDFLAGS
    
            if test -n "${LUA_LIBS}"; then
                break
            fi
        else
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
        fi
    
      done
    fi
    
    
    
    
    if test -z "${LUA_LIBS}"; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** Lua 5.4 5.3 5.2 or 5.1 library not found." >&5
    printf "%s\n" "$as_me: WARNING: *** Lua 5.4 5.3 5.2 or 5.1 library not found." >&2;}
      enable_lua="no"
        if test -z "${lua_path}"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Lua 5.4 5.3 5.2 or 5.1 library is required" >&5
    printf "%s\n" "$as_me: WARNING: Lua 5.4 5.3 5.2 or 5.1 library is required" >&2;}
        else
            as_fn_error $? "Lua 5.4 5.3 5.2 or 5.1 library is required" "$LINENO" 5
        fi
    else
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: using '${LUA_LIBS}' for Lua Library" >&5
    printf "%s\n" "$as_me: using '${LUA_LIBS}' for Lua Library" >&6;}
      # Check whether --enable-luajit was given.
    if test ${enable_luajit+y}
    then :
      enableval=$enable_luajit;
        if test "$enableval" = "yes"; then
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DAP_ENABLE_LUAJIT"\""
        MOD_CPPFLAGS=""-DAP_ENABLE_LUAJIT""
      else
        apr_addto_bugger=""-DAP_ENABLE_LUAJIT""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
        fi
    
    fi
    
    
    fi
    
      if test "x$enable_lua" != "xno" ; then
    
      if test "x$MOD_INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_INCLUDES to \"$LUA_CFLAGS\""
        MOD_INCLUDES="$LUA_CFLAGS"
      else
        apr_addto_bugger="$LUA_CFLAGS"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_INCLUDES"
            MOD_INCLUDES="$MOD_INCLUDES $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LUA_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LUA_LDADD to \"$LUA_LIBS $CRYPT_LIBS\""
        MOD_LUA_LDADD="$LUA_LIBS $CRYPT_LIBS"
      else
        apr_addto_bugger="$LUA_LIBS $CRYPT_LIBS"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LUA_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LUA_LDADD"
            MOD_LUA_LDADD="$MOD_LUA_LDADD $i"
          fi
        done
      fi
    
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lua" >&5
    printf %s "checking whether to enable mod_lua... " >&6; }
                if test "$enable_lua" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_lua has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_lua$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_lua$_apmod_extra_msg" >&6; }
      if test "$enable_lua" != "no"; then
        case "$enable_lua" in
        static*)
          MODLIST="$MODLIST lua"
          if test "lua" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES lua"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},lua"
          fi
          ;;
        esac
    
    
      if test -z "$lua_objects"; then
        objects="mod_lua.lo"
      else
        objects="$lua_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_lua.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LUA_LDADD)
    EOF
          if test ! -z "\$(MOD_LUA_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LUA_LDADD)\""
        AP_LIBS="\$(MOD_LUA_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LUA_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_lua.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  $objects \$(MOD_LUA_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LUA_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=metadata
      modpath_current=modules/metadata
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d metadata || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_env" >&5
    printf %s "checking whether to enable mod_env... " >&6; }
        # Check whether --enable-env was given.
    if test ${enable_env+y}
    then :
      enableval=$enable_env; force_env=$enableval
    else $as_nop
      enable_env=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_env" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_env" = "static" -o "$enable_env" = "shared"; then
        :
      elif test "$enable_env" = "yes"; then
        enable_env=$module_default
      elif test "$enable_env" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_env=$module_default
        else
          enable_env=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_env" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_env=$module_default
        else
          enable_env=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_env" = "all" -o "$enable_env" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_env=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_env=no
        fi
      elif test "$enable_env" = "reallyall" -o "$enable_env" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_env" != "no" ; then
          enable_env=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_env=no
        fi
      else
        enable_env=no
      fi
      if test "$enable_env" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_env$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_env$_apmod_extra_msg" >&6; }
      if test "$enable_env" != "no"; then
        case "$enable_env" in
        static*)
          MODLIST="$MODLIST env"
          if test "env" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES env"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},env"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_env.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_env.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ENV_LDADD)
    EOF
          if test ! -z "\$(MOD_ENV_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ENV_LDADD)\""
        AP_LIBS="\$(MOD_ENV_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ENV_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_env.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  $objects \$(MOD_ENV_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ENV_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_mime_magic" >&5
    printf %s "checking whether to enable mod_mime_magic... " >&6; }
        # Check whether --enable-mime-magic was given.
    if test ${enable_mime_magic+y}
    then :
      enableval=$enable_mime_magic; force_mime_magic=$enableval
    else $as_nop
      enable_mime_magic=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_mime_magic" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_mime_magic" = "static" -o "$enable_mime_magic" = "shared"; then
        :
      elif test "$enable_mime_magic" = "yes"; then
        enable_mime_magic=$module_default
      elif test "$enable_mime_magic" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_mime_magic=$module_default
        else
          enable_mime_magic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_mime_magic" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_mime_magic=$module_default
        else
          enable_mime_magic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_mime_magic" = "all" -o "$enable_mime_magic" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_mime_magic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_mime_magic=no
        fi
      elif test "$enable_mime_magic" = "reallyall" -o "$enable_mime_magic" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_mime_magic" != "no" ; then
          enable_mime_magic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_mime_magic=no
        fi
      else
        enable_mime_magic=no
      fi
      if test "$enable_mime_magic" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_mime_magic$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_mime_magic$_apmod_extra_msg" >&6; }
      if test "$enable_mime_magic" != "no"; then
        case "$enable_mime_magic" in
        static*)
          MODLIST="$MODLIST mime_magic"
          if test "mime_magic" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES mime_magic"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},mime_magic"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_mime_magic.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_mime_magic.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_MIME_MAGIC_LDADD)
    EOF
          if test ! -z "\$(MOD_MIME_MAGIC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_MIME_MAGIC_LDADD)\""
        AP_LIBS="\$(MOD_MIME_MAGIC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_MIME_MAGIC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_mime_magic.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  $objects \$(MOD_MIME_MAGIC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_MIME_MAGIC_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cern_meta" >&5
    printf %s "checking whether to enable mod_cern_meta... " >&6; }
        # Check whether --enable-cern-meta was given.
    if test ${enable_cern_meta+y}
    then :
      enableval=$enable_cern_meta; force_cern_meta=$enableval
    else $as_nop
      enable_cern_meta=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_cern_meta" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cern_meta" = "static" -o "$enable_cern_meta" = "shared"; then
        :
      elif test "$enable_cern_meta" = "yes"; then
        enable_cern_meta=$module_default
      elif test "$enable_cern_meta" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cern_meta=$module_default
        else
          enable_cern_meta=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cern_meta" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cern_meta=$module_default
        else
          enable_cern_meta=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cern_meta" = "all" -o "$enable_cern_meta" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cern_meta=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cern_meta=no
        fi
      elif test "$enable_cern_meta" = "reallyall" -o "$enable_cern_meta" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cern_meta" != "no" ; then
          enable_cern_meta=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cern_meta=no
        fi
      else
        enable_cern_meta=no
      fi
      if test "$enable_cern_meta" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cern_meta$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cern_meta$_apmod_extra_msg" >&6; }
      if test "$enable_cern_meta" != "no"; then
        case "$enable_cern_meta" in
        static*)
          MODLIST="$MODLIST cern_meta"
          if test "cern_meta" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cern_meta"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cern_meta"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_cern_meta.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cern_meta.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CERN_META_LDADD)
    EOF
          if test ! -z "\$(MOD_CERN_META_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CERN_META_LDADD)\""
        AP_LIBS="\$(MOD_CERN_META_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CERN_META_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cern_meta.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  $objects \$(MOD_CERN_META_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CERN_META_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_expires" >&5
    printf %s "checking whether to enable mod_expires... " >&6; }
        # Check whether --enable-expires was given.
    if test ${enable_expires+y}
    then :
      enableval=$enable_expires; force_expires=$enableval
    else $as_nop
      enable_expires=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_expires" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_expires" = "static" -o "$enable_expires" = "shared"; then
        :
      elif test "$enable_expires" = "yes"; then
        enable_expires=$module_default
      elif test "$enable_expires" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_expires=$module_default
        else
          enable_expires=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_expires" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_expires=$module_default
        else
          enable_expires=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_expires" = "all" -o "$enable_expires" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_expires=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_expires=no
        fi
      elif test "$enable_expires" = "reallyall" -o "$enable_expires" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_expires" != "no" ; then
          enable_expires=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_expires=no
        fi
      else
        enable_expires=no
      fi
      if test "$enable_expires" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_expires$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_expires$_apmod_extra_msg" >&6; }
      if test "$enable_expires" != "no"; then
        case "$enable_expires" in
        static*)
          MODLIST="$MODLIST expires"
          if test "expires" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES expires"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},expires"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_expires.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_expires.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_EXPIRES_LDADD)
    EOF
          if test ! -z "\$(MOD_EXPIRES_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_EXPIRES_LDADD)\""
        AP_LIBS="\$(MOD_EXPIRES_LDADD)"
      else
        apr_addto_bugger="\$(MOD_EXPIRES_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_expires.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  $objects \$(MOD_EXPIRES_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_EXPIRES_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_headers" >&5
    printf %s "checking whether to enable mod_headers... " >&6; }
        # Check whether --enable-headers was given.
    if test ${enable_headers+y}
    then :
      enableval=$enable_headers; force_headers=$enableval
    else $as_nop
      enable_headers=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_headers" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_headers" = "static" -o "$enable_headers" = "shared"; then
        :
      elif test "$enable_headers" = "yes"; then
        enable_headers=$module_default
      elif test "$enable_headers" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_headers=$module_default
        else
          enable_headers=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_headers" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_headers=$module_default
        else
          enable_headers=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_headers" = "all" -o "$enable_headers" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_headers=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_headers=no
        fi
      elif test "$enable_headers" = "reallyall" -o "$enable_headers" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_headers" != "no" ; then
          enable_headers=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_headers=no
        fi
      else
        enable_headers=no
      fi
      if test "$enable_headers" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_headers$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_headers$_apmod_extra_msg" >&6; }
      if test "$enable_headers" != "no"; then
        case "$enable_headers" in
        static*)
          MODLIST="$MODLIST headers"
          if test "headers" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES headers"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},headers"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_headers.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_headers.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_HEADERS_LDADD)
    EOF
          if test ! -z "\$(MOD_HEADERS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_HEADERS_LDADD)\""
        AP_LIBS="\$(MOD_HEADERS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_HEADERS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_headers.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  $objects \$(MOD_HEADERS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_HEADERS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_ident" >&5
    printf %s "checking whether to enable mod_ident... " >&6; }
        # Check whether --enable-ident was given.
    if test ${enable_ident+y}
    then :
      enableval=$enable_ident; force_ident=$enableval
    else $as_nop
      enable_ident=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_ident" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_ident" = "static" -o "$enable_ident" = "shared"; then
        :
      elif test "$enable_ident" = "yes"; then
        enable_ident=$module_default
      elif test "$enable_ident" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ident=$module_default
        else
          enable_ident=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ident" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_ident=$module_default
        else
          enable_ident=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ident" = "all" -o "$enable_ident" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ident=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ident=no
        fi
      elif test "$enable_ident" = "reallyall" -o "$enable_ident" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_ident" != "no" ; then
          enable_ident=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ident=no
        fi
      else
        enable_ident=no
      fi
      if test "$enable_ident" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_ident$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_ident$_apmod_extra_msg" >&6; }
      if test "$enable_ident" != "no"; then
        case "$enable_ident" in
        static*)
          MODLIST="$MODLIST ident"
          if test "ident" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES ident"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},ident"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_ident.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_ident.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_IDENT_LDADD)
    EOF
          if test ! -z "\$(MOD_IDENT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_IDENT_LDADD)\""
        AP_LIBS="\$(MOD_IDENT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_IDENT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_ident.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  $objects \$(MOD_IDENT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_IDENT_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_usertrack" >&5
    printf %s "checking whether to enable mod_usertrack... " >&6; }
        # Check whether --enable-usertrack was given.
    if test ${enable_usertrack+y}
    then :
      enableval=$enable_usertrack; force_usertrack=$enableval
    else $as_nop
      enable_usertrack=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_usertrack" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_usertrack" = "static" -o "$enable_usertrack" = "shared"; then
        :
      elif test "$enable_usertrack" = "yes"; then
        enable_usertrack=$module_default
      elif test "$enable_usertrack" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_usertrack=$module_default
        else
          enable_usertrack=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_usertrack" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_usertrack=$module_default
        else
          enable_usertrack=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_usertrack" = "all" -o "$enable_usertrack" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_usertrack=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_usertrack=no
        fi
      elif test "$enable_usertrack" = "reallyall" -o "$enable_usertrack" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_usertrack" != "no" ; then
          enable_usertrack=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_usertrack=no
        fi
      else
        enable_usertrack=no
      fi
      if test "$enable_usertrack" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
      ac_fn_c_check_header_compile "$LINENO" "sys/times.h" "ac_cv_header_sys_times_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_times_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_TIMES_H 1" >>confdefs.h
    
    fi
    
      ac_fn_c_check_func "$LINENO" "times" "ac_cv_func_times"
    if test "x$ac_cv_func_times" = xyes
    then :
      printf "%s\n" "#define HAVE_TIMES 1" >>confdefs.h
    
    fi
    
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_usertrack" >&5
    printf %s "checking whether to enable mod_usertrack... " >&6; }
                if test "$enable_usertrack" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_usertrack has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_usertrack$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_usertrack$_apmod_extra_msg" >&6; }
      if test "$enable_usertrack" != "no"; then
        case "$enable_usertrack" in
        static*)
          MODLIST="$MODLIST usertrack"
          if test "usertrack" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES usertrack"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},usertrack"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_usertrack.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_usertrack.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_USERTRACK_LDADD)
    EOF
          if test ! -z "\$(MOD_USERTRACK_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_USERTRACK_LDADD)\""
        AP_LIBS="\$(MOD_USERTRACK_LDADD)"
      else
        apr_addto_bugger="\$(MOD_USERTRACK_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_usertrack.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  $objects \$(MOD_USERTRACK_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_USERTRACK_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_unique_id" >&5
    printf %s "checking whether to enable mod_unique_id... " >&6; }
        # Check whether --enable-unique-id was given.
    if test ${enable_unique_id+y}
    then :
      enableval=$enable_unique_id; force_unique_id=$enableval
    else $as_nop
      enable_unique_id=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_unique_id" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_unique_id" = "static" -o "$enable_unique_id" = "shared"; then
        :
      elif test "$enable_unique_id" = "yes"; then
        enable_unique_id=$module_default
      elif test "$enable_unique_id" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_unique_id=$module_default
        else
          enable_unique_id=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_unique_id" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_unique_id=$module_default
        else
          enable_unique_id=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_unique_id" = "all" -o "$enable_unique_id" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_unique_id=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_unique_id=no
        fi
      elif test "$enable_unique_id" = "reallyall" -o "$enable_unique_id" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_unique_id" != "no" ; then
          enable_unique_id=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_unique_id=no
        fi
      else
        enable_unique_id=no
      fi
      if test "$enable_unique_id" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_unique_id$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_unique_id$_apmod_extra_msg" >&6; }
      if test "$enable_unique_id" != "no"; then
        case "$enable_unique_id" in
        static*)
          MODLIST="$MODLIST unique_id"
          if test "unique_id" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES unique_id"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},unique_id"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_unique_id.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_unique_id.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_UNIQUE_ID_LDADD)
    EOF
          if test ! -z "\$(MOD_UNIQUE_ID_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_UNIQUE_ID_LDADD)\""
        AP_LIBS="\$(MOD_UNIQUE_ID_LDADD)"
      else
        apr_addto_bugger="\$(MOD_UNIQUE_ID_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_unique_id.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  $objects \$(MOD_UNIQUE_ID_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_UNIQUE_ID_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_setenvif" >&5
    printf %s "checking whether to enable mod_setenvif... " >&6; }
        # Check whether --enable-setenvif was given.
    if test ${enable_setenvif+y}
    then :
      enableval=$enable_setenvif; force_setenvif=$enableval
    else $as_nop
      enable_setenvif=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_setenvif" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_setenvif" = "static" -o "$enable_setenvif" = "shared"; then
        :
      elif test "$enable_setenvif" = "yes"; then
        enable_setenvif=$module_default
      elif test "$enable_setenvif" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_setenvif=$module_default
        else
          enable_setenvif=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_setenvif" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_setenvif=$module_default
        else
          enable_setenvif=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_setenvif" = "all" -o "$enable_setenvif" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_setenvif=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_setenvif=no
        fi
      elif test "$enable_setenvif" = "reallyall" -o "$enable_setenvif" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_setenvif" != "no" ; then
          enable_setenvif=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_setenvif=no
        fi
      else
        enable_setenvif=no
      fi
      if test "$enable_setenvif" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_setenvif$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_setenvif$_apmod_extra_msg" >&6; }
      if test "$enable_setenvif" != "no"; then
        case "$enable_setenvif" in
        static*)
          MODLIST="$MODLIST setenvif"
          if test "setenvif" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES setenvif"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},setenvif"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_setenvif.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_setenvif.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SETENVIF_LDADD)
    EOF
          if test ! -z "\$(MOD_SETENVIF_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SETENVIF_LDADD)\""
        AP_LIBS="\$(MOD_SETENVIF_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SETENVIF_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_setenvif.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  $objects \$(MOD_SETENVIF_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SETENVIF_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_version" >&5
    printf %s "checking whether to enable mod_version... " >&6; }
        # Check whether --enable-version was given.
    if test ${enable_version+y}
    then :
      enableval=$enable_version; force_version=$enableval
    else $as_nop
      enable_version=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_version" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_version" = "static" -o "$enable_version" = "shared"; then
        :
      elif test "$enable_version" = "yes"; then
        enable_version=$module_default
      elif test "$enable_version" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_version=$module_default
        else
          enable_version=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_version" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_version=$module_default
        else
          enable_version=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_version" = "all" -o "$enable_version" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_version=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_version=no
        fi
      elif test "$enable_version" = "reallyall" -o "$enable_version" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_version" != "no" ; then
          enable_version=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_version=no
        fi
      else
        enable_version=no
      fi
      if test "$enable_version" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_version$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_version$_apmod_extra_msg" >&6; }
      if test "$enable_version" != "no"; then
        case "$enable_version" in
        static*)
          MODLIST="$MODLIST version"
          if test "version" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES version"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},version"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_version.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_version.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_VERSION_LDADD)
    EOF
          if test ! -z "\$(MOD_VERSION_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_VERSION_LDADD)\""
        AP_LIBS="\$(MOD_VERSION_LDADD)"
      else
        apr_addto_bugger="\$(MOD_VERSION_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_version.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  $objects \$(MOD_VERSION_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_VERSION_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_remoteip" >&5
    printf %s "checking whether to enable mod_remoteip... " >&6; }
        # Check whether --enable-remoteip was given.
    if test ${enable_remoteip+y}
    then :
      enableval=$enable_remoteip; force_remoteip=$enableval
    else $as_nop
      enable_remoteip=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_remoteip" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_remoteip" = "static" -o "$enable_remoteip" = "shared"; then
        :
      elif test "$enable_remoteip" = "yes"; then
        enable_remoteip=$module_default
      elif test "$enable_remoteip" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_remoteip=$module_default
        else
          enable_remoteip=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_remoteip" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_remoteip=$module_default
        else
          enable_remoteip=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_remoteip" = "all" -o "$enable_remoteip" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_remoteip=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_remoteip=no
        fi
      elif test "$enable_remoteip" = "reallyall" -o "$enable_remoteip" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_remoteip" != "no" ; then
          enable_remoteip=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_remoteip=no
        fi
      else
        enable_remoteip=no
      fi
      if test "$enable_remoteip" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_remoteip$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_remoteip$_apmod_extra_msg" >&6; }
      if test "$enable_remoteip" != "no"; then
        case "$enable_remoteip" in
        static*)
          MODLIST="$MODLIST remoteip"
          if test "remoteip" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES remoteip"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},remoteip"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_remoteip.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_remoteip.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_REMOTEIP_LDADD)
    EOF
          if test ! -z "\$(MOD_REMOTEIP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_REMOTEIP_LDADD)\""
        AP_LIBS="\$(MOD_REMOTEIP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_REMOTEIP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_remoteip.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  $objects \$(MOD_REMOTEIP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_REMOTEIP_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=proxy
      modpath_current=modules/proxy
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d proxy || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    proxy_objs="mod_proxy.lo proxy_util.lo"
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy" >&5
    printf %s "checking whether to enable mod_proxy... " >&6; }
        # Check whether --enable-proxy was given.
    if test ${enable_proxy+y}
    then :
      enableval=$enable_proxy; force_proxy=$enableval
    else $as_nop
      enable_proxy=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy" = "static" -o "$enable_proxy" = "shared"; then
        :
      elif test "$enable_proxy" = "yes"; then
        enable_proxy=$module_default
      elif test "$enable_proxy" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy=$module_default
        else
          enable_proxy=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy=$module_default
        else
          enable_proxy=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy" = "all" -o "$enable_proxy" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy=no
        fi
      elif test "$enable_proxy" = "reallyall" -o "$enable_proxy" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy" != "no" ; then
          enable_proxy=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy=no
        fi
      else
        enable_proxy=no
      fi
      if test "$enable_proxy" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy$_apmod_extra_msg" >&6; }
      if test "$enable_proxy" != "no"; then
        case "$enable_proxy" in
        static*)
          MODLIST="$MODLIST proxy"
          if test "proxy" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_objs"; then
        objects="mod_proxy.lo"
      else
        objects="$proxy_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy.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  $objects \$(MOD_PROXY_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_LDADD"
    
    
    
      fi
    
    
    save_module_selection=$module_selection
    save_module_default=$module_default
    if test "$enable_proxy" != "no"; then
        module_selection=most
        if test "$enable_proxy" = "shared" -o "$enable_proxy" = "static"; then
            module_default=$enable_proxy
        fi
    fi
    
    proxy_connect_objs="mod_proxy_connect.lo"
    proxy_ftp_objs="mod_proxy_ftp.lo"
    proxy_http_objs="mod_proxy_http.lo"
    proxy_fcgi_objs="mod_proxy_fcgi.lo"
    proxy_scgi_objs="mod_proxy_scgi.lo"
    proxy_uwsgi_objs="mod_proxy_uwsgi.lo"
    proxy_fdpass_objs="mod_proxy_fdpass.lo"
    proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo ajp_utils.lo"
    proxy_wstunnel_objs="mod_proxy_wstunnel.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_fcgi_objs="$proxy_fcgi_objs mod_proxy.la"
        proxy_scgi_objs="$proxy_scgi_objs mod_proxy.la"
        proxy_uwsgi_objs="$proxy_uwsgi_objs mod_proxy.la"
        proxy_fdpass_objs="$proxy_fdpass_objs mod_proxy.la"
        proxy_ajp_objs="$proxy_ajp_objs mod_proxy.la"
        proxy_wstunnel_objs="$proxy_wstunnel_objs mod_proxy.la"
        proxy_balancer_objs="$proxy_balancer_objs mod_proxy.la"
        ;;
    esac
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_connect" >&5
    printf %s "checking whether to enable mod_proxy_connect... " >&6; }
        # Check whether --enable-proxy-connect was given.
    if test ${enable_proxy_connect+y}
    then :
      enableval=$enable_proxy_connect; force_proxy_connect=$enableval
    else $as_nop
      enable_proxy_connect=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_connect" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_connect" = "static" -o "$enable_proxy_connect" = "shared"; then
        :
      elif test "$enable_proxy_connect" = "yes"; then
        enable_proxy_connect=$module_default
      elif test "$enable_proxy_connect" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_connect=$module_default
        else
          enable_proxy_connect=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_connect" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_connect=$module_default
        else
          enable_proxy_connect=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_connect" = "all" -o "$enable_proxy_connect" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_connect=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_connect=no
        fi
      elif test "$enable_proxy_connect" = "reallyall" -o "$enable_proxy_connect" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_connect" != "no" ; then
          enable_proxy_connect=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_connect=no
        fi
      else
        enable_proxy_connect=no
      fi
      if test "$enable_proxy_connect" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_connect=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_connect\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_connect\"" >&2;}
                                elif test "$enable_proxy_connect" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_connect=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_connect shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_connect shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_connect" >&5
    printf %s "checking whether to enable mod_proxy_connect... " >&6; }
                if test "$enable_proxy_connect" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_connect has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_connect$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_connect$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_connect" != "no"; then
        case "$enable_proxy_connect" in
        static*)
          MODLIST="$MODLIST proxy_connect"
          if test "proxy_connect" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_connect"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_connect"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_connect_objs"; then
        objects="mod_proxy_connect.lo"
      else
        objects="$proxy_connect_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_connect.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_CONNECT_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_CONNECT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_CONNECT_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_CONNECT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_CONNECT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_connect.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  $objects \$(MOD_PROXY_CONNECT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_CONNECT_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_ftp" >&5
    printf %s "checking whether to enable mod_proxy_ftp... " >&6; }
        # Check whether --enable-proxy-ftp was given.
    if test ${enable_proxy_ftp+y}
    then :
      enableval=$enable_proxy_ftp; force_proxy_ftp=$enableval
    else $as_nop
      enable_proxy_ftp=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_ftp" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_ftp" = "static" -o "$enable_proxy_ftp" = "shared"; then
        :
      elif test "$enable_proxy_ftp" = "yes"; then
        enable_proxy_ftp=$module_default
      elif test "$enable_proxy_ftp" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_ftp=$module_default
        else
          enable_proxy_ftp=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_ftp" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_ftp=$module_default
        else
          enable_proxy_ftp=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_ftp" = "all" -o "$enable_proxy_ftp" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_ftp=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_ftp=no
        fi
      elif test "$enable_proxy_ftp" = "reallyall" -o "$enable_proxy_ftp" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_ftp" != "no" ; then
          enable_proxy_ftp=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_ftp=no
        fi
      else
        enable_proxy_ftp=no
      fi
      if test "$enable_proxy_ftp" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_ftp=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_ftp\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_ftp\"" >&2;}
                                elif test "$enable_proxy_ftp" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_ftp=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_ftp shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_ftp shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_ftp" >&5
    printf %s "checking whether to enable mod_proxy_ftp... " >&6; }
                if test "$enable_proxy_ftp" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_ftp has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_ftp$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_ftp$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_ftp" != "no"; then
        case "$enable_proxy_ftp" in
        static*)
          MODLIST="$MODLIST proxy_ftp"
          if test "proxy_ftp" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_ftp"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_ftp"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_ftp_objs"; then
        objects="mod_proxy_ftp.lo"
      else
        objects="$proxy_ftp_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_ftp.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_FTP_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_FTP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_FTP_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_FTP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_FTP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_ftp.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  $objects \$(MOD_PROXY_FTP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_FTP_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_http" >&5
    printf %s "checking whether to enable mod_proxy_http... " >&6; }
        # Check whether --enable-proxy-http was given.
    if test ${enable_proxy_http+y}
    then :
      enableval=$enable_proxy_http; force_proxy_http=$enableval
    else $as_nop
      enable_proxy_http=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_http" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_http" = "static" -o "$enable_proxy_http" = "shared"; then
        :
      elif test "$enable_proxy_http" = "yes"; then
        enable_proxy_http=$module_default
      elif test "$enable_proxy_http" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_http=$module_default
        else
          enable_proxy_http=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_http" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_http=$module_default
        else
          enable_proxy_http=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_http" = "all" -o "$enable_proxy_http" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_http=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_http=no
        fi
      elif test "$enable_proxy_http" = "reallyall" -o "$enable_proxy_http" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_http" != "no" ; then
          enable_proxy_http=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_http=no
        fi
      else
        enable_proxy_http=no
      fi
      if test "$enable_proxy_http" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_http=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_http\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_http\"" >&2;}
                                elif test "$enable_proxy_http" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_http=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_http shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_http shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_http" >&5
    printf %s "checking whether to enable mod_proxy_http... " >&6; }
                if test "$enable_proxy_http" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_http has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_http$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_http$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_http" != "no"; then
        case "$enable_proxy_http" in
        static*)
          MODLIST="$MODLIST proxy_http"
          if test "proxy_http" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_http"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_http"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_http_objs"; then
        objects="mod_proxy_http.lo"
      else
        objects="$proxy_http_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_http.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_HTTP_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_HTTP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_HTTP_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_HTTP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_HTTP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_http.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  $objects \$(MOD_PROXY_HTTP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_HTTP_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_fcgi" >&5
    printf %s "checking whether to enable mod_proxy_fcgi... " >&6; }
        # Check whether --enable-proxy-fcgi was given.
    if test ${enable_proxy_fcgi+y}
    then :
      enableval=$enable_proxy_fcgi; force_proxy_fcgi=$enableval
    else $as_nop
      enable_proxy_fcgi=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_fcgi" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_fcgi" = "static" -o "$enable_proxy_fcgi" = "shared"; then
        :
      elif test "$enable_proxy_fcgi" = "yes"; then
        enable_proxy_fcgi=$module_default
      elif test "$enable_proxy_fcgi" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_fcgi=$module_default
        else
          enable_proxy_fcgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_fcgi" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_fcgi=$module_default
        else
          enable_proxy_fcgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_fcgi" = "all" -o "$enable_proxy_fcgi" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_fcgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_fcgi=no
        fi
      elif test "$enable_proxy_fcgi" = "reallyall" -o "$enable_proxy_fcgi" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_fcgi" != "no" ; then
          enable_proxy_fcgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_fcgi=no
        fi
      else
        enable_proxy_fcgi=no
      fi
      if test "$enable_proxy_fcgi" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_fcgi=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_fcgi\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_fcgi\"" >&2;}
                                elif test "$enable_proxy_fcgi" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_fcgi=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_fcgi shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_fcgi shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_fcgi" >&5
    printf %s "checking whether to enable mod_proxy_fcgi... " >&6; }
                if test "$enable_proxy_fcgi" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_fcgi has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_fcgi$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_fcgi$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_fcgi" != "no"; then
        case "$enable_proxy_fcgi" in
        static*)
          MODLIST="$MODLIST proxy_fcgi"
          if test "proxy_fcgi" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_fcgi"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_fcgi"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_fcgi_objs"; then
        objects="mod_proxy_fcgi.lo"
      else
        objects="$proxy_fcgi_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_fcgi.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_FCGI_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_FCGI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_FCGI_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_FCGI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_FCGI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_fcgi.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  $objects \$(MOD_PROXY_FCGI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_FCGI_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_scgi" >&5
    printf %s "checking whether to enable mod_proxy_scgi... " >&6; }
        # Check whether --enable-proxy-scgi was given.
    if test ${enable_proxy_scgi+y}
    then :
      enableval=$enable_proxy_scgi; force_proxy_scgi=$enableval
    else $as_nop
      enable_proxy_scgi=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_scgi" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_scgi" = "static" -o "$enable_proxy_scgi" = "shared"; then
        :
      elif test "$enable_proxy_scgi" = "yes"; then
        enable_proxy_scgi=$module_default
      elif test "$enable_proxy_scgi" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_scgi=$module_default
        else
          enable_proxy_scgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_scgi" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_scgi=$module_default
        else
          enable_proxy_scgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_scgi" = "all" -o "$enable_proxy_scgi" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_scgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_scgi=no
        fi
      elif test "$enable_proxy_scgi" = "reallyall" -o "$enable_proxy_scgi" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_scgi" != "no" ; then
          enable_proxy_scgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_scgi=no
        fi
      else
        enable_proxy_scgi=no
      fi
      if test "$enable_proxy_scgi" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_scgi=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_scgi\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_scgi\"" >&2;}
                                elif test "$enable_proxy_scgi" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_scgi=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_scgi shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_scgi shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_scgi" >&5
    printf %s "checking whether to enable mod_proxy_scgi... " >&6; }
                if test "$enable_proxy_scgi" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_scgi has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_scgi$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_scgi$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_scgi" != "no"; then
        case "$enable_proxy_scgi" in
        static*)
          MODLIST="$MODLIST proxy_scgi"
          if test "proxy_scgi" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_scgi"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_scgi"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_scgi_objs"; then
        objects="mod_proxy_scgi.lo"
      else
        objects="$proxy_scgi_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_scgi.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_SCGI_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_SCGI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_SCGI_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_SCGI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_SCGI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_scgi.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  $objects \$(MOD_PROXY_SCGI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_SCGI_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_uwsgi" >&5
    printf %s "checking whether to enable mod_proxy_uwsgi... " >&6; }
        # Check whether --enable-proxy-uwsgi was given.
    if test ${enable_proxy_uwsgi+y}
    then :
      enableval=$enable_proxy_uwsgi; force_proxy_uwsgi=$enableval
    else $as_nop
      enable_proxy_uwsgi=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_uwsgi" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_uwsgi" = "static" -o "$enable_proxy_uwsgi" = "shared"; then
        :
      elif test "$enable_proxy_uwsgi" = "yes"; then
        enable_proxy_uwsgi=$module_default
      elif test "$enable_proxy_uwsgi" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_uwsgi=$module_default
        else
          enable_proxy_uwsgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_uwsgi" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_uwsgi=$module_default
        else
          enable_proxy_uwsgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_uwsgi" = "all" -o "$enable_proxy_uwsgi" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_uwsgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_uwsgi=no
        fi
      elif test "$enable_proxy_uwsgi" = "reallyall" -o "$enable_proxy_uwsgi" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_uwsgi" != "no" ; then
          enable_proxy_uwsgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_uwsgi=no
        fi
      else
        enable_proxy_uwsgi=no
      fi
      if test "$enable_proxy_uwsgi" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_uwsgi=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_uwsgi\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_uwsgi\"" >&2;}
                                elif test "$enable_proxy_uwsgi" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_uwsgi=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_uwsgi shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_uwsgi shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_uwsgi" >&5
    printf %s "checking whether to enable mod_proxy_uwsgi... " >&6; }
                if test "$enable_proxy_uwsgi" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_uwsgi has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_uwsgi$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_uwsgi$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_uwsgi" != "no"; then
        case "$enable_proxy_uwsgi" in
        static*)
          MODLIST="$MODLIST proxy_uwsgi"
          if test "proxy_uwsgi" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_uwsgi"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_uwsgi"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_uwsgi_objs"; then
        objects="mod_proxy_uwsgi.lo"
      else
        objects="$proxy_uwsgi_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_uwsgi.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_UWSGI_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_UWSGI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_UWSGI_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_UWSGI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_UWSGI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_uwsgi.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  $objects \$(MOD_PROXY_UWSGI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_UWSGI_LDADD"
    
    
    
      fi
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5
    printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; }
    if test ${ac_cv_c_undeclared_builtin_options+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_save_CFLAGS=$CFLAGS
       ac_cv_c_undeclared_builtin_options='cannot detect'
       for ac_arg in '' -fno-builtin; do
         CFLAGS="$ac_save_CFLAGS $ac_arg"
         # This test program should *not* compile successfully.
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    int
    main (void)
    {
    (void) strchr;
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
    
    else $as_nop
      # This test program should compile successfully.
            # No library function is consistently available on
            # freestanding implementations, so test against a dummy
            # declaration.  Include always-available headers on the
            # off chance that they somehow elicit warnings.
            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <float.h>
    #include <limits.h>
    #include <stdarg.h>
    #include <stddef.h>
    extern void ac_decl (int, char *);
    
    int
    main (void)
    {
    (void) ac_decl (0, (char *) 0);
      (void) ac_decl;
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      if test x"$ac_arg" = x
    then :
      ac_cv_c_undeclared_builtin_options='none needed'
    else $as_nop
      ac_cv_c_undeclared_builtin_options=$ac_arg
    fi
              break
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
        done
        CFLAGS=$ac_save_CFLAGS
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5
    printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; }
      case $ac_cv_c_undeclared_builtin_options in #(
      'cannot detect') :
        { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "cannot make $CC report undeclared builtins
    See \`config.log' for more details" "$LINENO" 5; } ;; #(
      'none needed') :
        ac_c_undeclared_builtin_options='' ;; #(
      *) :
        ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;;
    esac
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_fdpass" >&5
    printf %s "checking whether to enable mod_proxy_fdpass... " >&6; }
        # Check whether --enable-proxy-fdpass was given.
    if test ${enable_proxy_fdpass+y}
    then :
      enableval=$enable_proxy_fdpass; force_proxy_fdpass=$enableval
    else $as_nop
      enable_proxy_fdpass=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_fdpass" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_fdpass" = "static" -o "$enable_proxy_fdpass" = "shared"; then
        :
      elif test "$enable_proxy_fdpass" = "yes"; then
        enable_proxy_fdpass=$module_default
      elif test "$enable_proxy_fdpass" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_fdpass=$module_default
        else
          enable_proxy_fdpass=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_fdpass" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_fdpass=$module_default
        else
          enable_proxy_fdpass=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_fdpass" = "all" -o "$enable_proxy_fdpass" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_fdpass=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_fdpass=no
        fi
      elif test "$enable_proxy_fdpass" = "reallyall" -o "$enable_proxy_fdpass" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_fdpass" != "no" ; then
          enable_proxy_fdpass=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_fdpass=no
        fi
      else
        enable_proxy_fdpass=no
      fi
      if test "$enable_proxy_fdpass" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_fdpass=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_fdpass\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_fdpass\"" >&2;}
                                elif test "$enable_proxy_fdpass" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_fdpass=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_fdpass shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_fdpass shared because mod_proxy is built shared\"" >&2;}
                                else
    
      ac_fn_check_decl "$LINENO" "CMSG_DATA" "ac_cv_have_decl_CMSG_DATA" "
        #include <sys/types.h>
        #include <sys/socket.h>
    
    " "$ac_c_undeclared_builtin_options" "CFLAGS"
    if test "x$ac_cv_have_decl_CMSG_DATA" = xyes
    then :
    
    fi
      if test $ac_cv_have_decl_CMSG_DATA = "no"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Your system does not support CMSG_DATA." >&5
    printf "%s\n" "$as_me: WARNING: Your system does not support CMSG_DATA." >&2;}
        enable_proxy_fdpass=no
      fi
    
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_fdpass" >&5
    printf %s "checking whether to enable mod_proxy_fdpass... " >&6; }
                if test "$enable_proxy_fdpass" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_fdpass has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_fdpass$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_fdpass$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_fdpass" != "no"; then
        case "$enable_proxy_fdpass" in
        static*)
          MODLIST="$MODLIST proxy_fdpass"
          if test "proxy_fdpass" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_fdpass"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_fdpass"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_fdpass_objs"; then
        objects="mod_proxy_fdpass.lo"
      else
        objects="$proxy_fdpass_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_fdpass.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_FDPASS_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_FDPASS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_FDPASS_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_FDPASS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_FDPASS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_fdpass.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  $objects \$(MOD_PROXY_FDPASS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_FDPASS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_wstunnel" >&5
    printf %s "checking whether to enable mod_proxy_wstunnel... " >&6; }
        # Check whether --enable-proxy-wstunnel was given.
    if test ${enable_proxy_wstunnel+y}
    then :
      enableval=$enable_proxy_wstunnel; force_proxy_wstunnel=$enableval
    else $as_nop
      enable_proxy_wstunnel=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_wstunnel" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_wstunnel" = "static" -o "$enable_proxy_wstunnel" = "shared"; then
        :
      elif test "$enable_proxy_wstunnel" = "yes"; then
        enable_proxy_wstunnel=$module_default
      elif test "$enable_proxy_wstunnel" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_wstunnel=$module_default
        else
          enable_proxy_wstunnel=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_wstunnel" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_wstunnel=$module_default
        else
          enable_proxy_wstunnel=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_wstunnel" = "all" -o "$enable_proxy_wstunnel" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_wstunnel=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_wstunnel=no
        fi
      elif test "$enable_proxy_wstunnel" = "reallyall" -o "$enable_proxy_wstunnel" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_wstunnel" != "no" ; then
          enable_proxy_wstunnel=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_wstunnel=no
        fi
      else
        enable_proxy_wstunnel=no
      fi
      if test "$enable_proxy_wstunnel" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_wstunnel=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_wstunnel\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_wstunnel\"" >&2;}
                                elif test "$enable_proxy_wstunnel" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_wstunnel=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_wstunnel shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_wstunnel shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_wstunnel" >&5
    printf %s "checking whether to enable mod_proxy_wstunnel... " >&6; }
                if test "$enable_proxy_wstunnel" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_wstunnel has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_wstunnel$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_wstunnel$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_wstunnel" != "no"; then
        case "$enable_proxy_wstunnel" in
        static*)
          MODLIST="$MODLIST proxy_wstunnel"
          if test "proxy_wstunnel" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_wstunnel"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_wstunnel"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_wstunnel_objs"; then
        objects="mod_proxy_wstunnel.lo"
      else
        objects="$proxy_wstunnel_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_wstunnel.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_WSTUNNEL_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_WSTUNNEL_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_WSTUNNEL_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_WSTUNNEL_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_WSTUNNEL_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_wstunnel.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  $objects \$(MOD_PROXY_WSTUNNEL_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_WSTUNNEL_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_ajp" >&5
    printf %s "checking whether to enable mod_proxy_ajp... " >&6; }
        # Check whether --enable-proxy-ajp was given.
    if test ${enable_proxy_ajp+y}
    then :
      enableval=$enable_proxy_ajp; force_proxy_ajp=$enableval
    else $as_nop
      enable_proxy_ajp=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_ajp" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_ajp" = "static" -o "$enable_proxy_ajp" = "shared"; then
        :
      elif test "$enable_proxy_ajp" = "yes"; then
        enable_proxy_ajp=$module_default
      elif test "$enable_proxy_ajp" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_ajp=$module_default
        else
          enable_proxy_ajp=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_ajp" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_ajp=$module_default
        else
          enable_proxy_ajp=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_ajp" = "all" -o "$enable_proxy_ajp" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_ajp=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_ajp=no
        fi
      elif test "$enable_proxy_ajp" = "reallyall" -o "$enable_proxy_ajp" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_ajp" != "no" ; then
          enable_proxy_ajp=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_ajp=no
        fi
      else
        enable_proxy_ajp=no
      fi
      if test "$enable_proxy_ajp" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_ajp=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_ajp\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_ajp\"" >&2;}
                                elif test "$enable_proxy_ajp" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_ajp=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_ajp shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_ajp shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_ajp" >&5
    printf %s "checking whether to enable mod_proxy_ajp... " >&6; }
                if test "$enable_proxy_ajp" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_ajp has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_ajp$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_ajp$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_ajp" != "no"; then
        case "$enable_proxy_ajp" in
        static*)
          MODLIST="$MODLIST proxy_ajp"
          if test "proxy_ajp" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_ajp"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_ajp"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_ajp_objs"; then
        objects="mod_proxy_ajp.lo"
      else
        objects="$proxy_ajp_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_ajp.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_AJP_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_AJP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_AJP_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_AJP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_AJP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_ajp.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  $objects \$(MOD_PROXY_AJP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_AJP_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_balancer" >&5
    printf %s "checking whether to enable mod_proxy_balancer... " >&6; }
        # Check whether --enable-proxy-balancer was given.
    if test ${enable_proxy_balancer+y}
    then :
      enableval=$enable_proxy_balancer; force_proxy_balancer=$enableval
    else $as_nop
      enable_proxy_balancer=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_balancer" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_balancer" = "static" -o "$enable_proxy_balancer" = "shared"; then
        :
      elif test "$enable_proxy_balancer" = "yes"; then
        enable_proxy_balancer=$module_default
      elif test "$enable_proxy_balancer" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_balancer=$module_default
        else
          enable_proxy_balancer=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_balancer" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_balancer=$module_default
        else
          enable_proxy_balancer=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_balancer" = "all" -o "$enable_proxy_balancer" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_balancer=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_balancer=no
        fi
      elif test "$enable_proxy_balancer" = "reallyall" -o "$enable_proxy_balancer" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_balancer" != "no" ; then
          enable_proxy_balancer=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_balancer=no
        fi
      else
        enable_proxy_balancer=no
      fi
      if test "$enable_proxy_balancer" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_balancer=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_balancer\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_balancer\"" >&2;}
                                elif test "$enable_proxy_balancer" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_balancer=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_balancer shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_balancer shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_balancer" >&5
    printf %s "checking whether to enable mod_proxy_balancer... " >&6; }
                if test "$enable_proxy_balancer" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_balancer has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_balancer$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_balancer$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_balancer" != "no"; then
        case "$enable_proxy_balancer" in
        static*)
          MODLIST="$MODLIST proxy_balancer"
          if test "proxy_balancer" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_balancer"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_balancer"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_balancer_objs"; then
        objects="mod_proxy_balancer.lo"
      else
        objects="$proxy_balancer_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_balancer.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_BALANCER_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_BALANCER_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_BALANCER_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_BALANCER_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_BALANCER_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_balancer.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  $objects \$(MOD_PROXY_BALANCER_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_BALANCER_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_express" >&5
    printf %s "checking whether to enable mod_proxy_express... " >&6; }
        # Check whether --enable-proxy-express was given.
    if test ${enable_proxy_express+y}
    then :
      enableval=$enable_proxy_express; force_proxy_express=$enableval
    else $as_nop
      enable_proxy_express=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_express" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_express" = "static" -o "$enable_proxy_express" = "shared"; then
        :
      elif test "$enable_proxy_express" = "yes"; then
        enable_proxy_express=$module_default
      elif test "$enable_proxy_express" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_express=$module_default
        else
          enable_proxy_express=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_express" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_express=$module_default
        else
          enable_proxy_express=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_express" = "all" -o "$enable_proxy_express" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_express=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_express=no
        fi
      elif test "$enable_proxy_express" = "reallyall" -o "$enable_proxy_express" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_express" != "no" ; then
          enable_proxy_express=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_express=no
        fi
      else
        enable_proxy_express=no
      fi
      if test "$enable_proxy_express" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_express=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_express\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_express\"" >&2;}
                                elif test "$enable_proxy_express" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_express=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_express shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_express shared because mod_proxy is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_express" >&5
    printf %s "checking whether to enable mod_proxy_express... " >&6; }
                if test "$enable_proxy_express" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_express has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_express$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_express$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_express" != "no"; then
        case "$enable_proxy_express" in
        static*)
          MODLIST="$MODLIST proxy_express"
          if test "proxy_express" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_express"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_express"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_proxy_express.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_express.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_EXPRESS_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_EXPRESS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_EXPRESS_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_EXPRESS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_EXPRESS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_express.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  $objects \$(MOD_PROXY_EXPRESS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_EXPRESS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_hcheck" >&5
    printf %s "checking whether to enable mod_proxy_hcheck... " >&6; }
        # Check whether --enable-proxy-hcheck was given.
    if test ${enable_proxy_hcheck+y}
    then :
      enableval=$enable_proxy_hcheck; force_proxy_hcheck=$enableval
    else $as_nop
      enable_proxy_hcheck=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_hcheck" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_hcheck" = "static" -o "$enable_proxy_hcheck" = "shared"; then
        :
      elif test "$enable_proxy_hcheck" = "yes"; then
        enable_proxy_hcheck=$module_default
      elif test "$enable_proxy_hcheck" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_hcheck=$module_default
        else
          enable_proxy_hcheck=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_hcheck" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_hcheck=$module_default
        else
          enable_proxy_hcheck=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_hcheck" = "all" -o "$enable_proxy_hcheck" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_hcheck=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_hcheck=no
        fi
      elif test "$enable_proxy_hcheck" = "reallyall" -o "$enable_proxy_hcheck" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_hcheck" != "no" ; then
          enable_proxy_hcheck=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_hcheck=no
        fi
      else
        enable_proxy_hcheck=no
      fi
      if test "$enable_proxy_hcheck" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_hcheck=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_hcheck\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_hcheck\"" >&2;}
                                elif test "$enable_proxy_hcheck" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_hcheck=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_hcheck shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_hcheck shared because mod_proxy is built shared\"" >&2;}
                                elif test "$enable_watchdog" = "no" ; then
                                  enable_proxy_hcheck=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_watchdog is disabled but required for mod_proxy_hcheck\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_watchdog is disabled but required for mod_proxy_hcheck\"" >&2;}
                                elif test "$enable_proxy_hcheck" = "static" && test "$enable_watchdog" != "static" ; then
                                  enable_proxy_hcheck=$enable_watchdog
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_hcheck shared because mod_watchdog is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_hcheck shared because mod_watchdog is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_hcheck" >&5
    printf %s "checking whether to enable mod_proxy_hcheck... " >&6; }
                if test "$enable_proxy_hcheck" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_hcheck has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_hcheck$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_hcheck$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_hcheck" != "no"; then
        case "$enable_proxy_hcheck" in
        static*)
          MODLIST="$MODLIST proxy_hcheck"
          if test "proxy_hcheck" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_hcheck"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_hcheck"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_proxy_hcheck.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_hcheck.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_HCHECK_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_HCHECK_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_HCHECK_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_HCHECK_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_HCHECK_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_hcheck.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  $objects \$(MOD_PROXY_HCHECK_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_HCHECK_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current -I\$(top_srcdir)/modules/http2\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current -I\$(top_srcdir)/modules/http2"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current -I\$(top_srcdir)/modules/http2"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    module_selection=$save_module_selection
    module_default=$save_module_default
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    if test -z "$enable_session" ; then
      session_mods_enable=most
    else
      session_mods_enable=$enable_session
    fi
    
    
    
    
      current_dir=session
      modpath_current=modules/session
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d session || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    session_cookie_objects='mod_session_cookie.lo'
    session_crypto_objects='mod_session_crypto.lo'
    session_dbd_objects='mod_session_dbd.lo'
    
    case "$host" in
      *os2*)
        # OS/2 DLLs must resolve all symbols at build time
        # and we need some from main session module
        session_cookie_objects="$session_cookie_objects mod_session.la"
        session_crypto_objects="$session_crypto_objects mod_session.la"
        session_dbd_objects="$session_dbd_objects mod_session.la"
        ;;
    esac
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_session" >&5
    printf %s "checking whether to enable mod_session... " >&6; }
        # Check whether --enable-session was given.
    if test ${enable_session+y}
    then :
      enableval=$enable_session; force_session=$enableval
    else $as_nop
      enable_session=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_session" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_session" = "static" -o "$enable_session" = "shared"; then
        :
      elif test "$enable_session" = "yes"; then
        enable_session=$module_default
      elif test "$enable_session" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session=$module_default
        else
          enable_session=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_session=$module_default
        else
          enable_session=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session" = "all" -o "$enable_session" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session=no
        fi
      elif test "$enable_session" = "reallyall" -o "$enable_session" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_session" != "no" ; then
          enable_session=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session=no
        fi
      else
        enable_session=no
      fi
      if test "$enable_session" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_session$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_session$_apmod_extra_msg" >&6; }
      if test "$enable_session" != "no"; then
        case "$enable_session" in
        static*)
          MODLIST="$MODLIST session"
          if test "session" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES session"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},session"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_session.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_session.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SESSION_LDADD)
    EOF
          if test ! -z "\$(MOD_SESSION_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SESSION_LDADD)\""
        AP_LIBS="\$(MOD_SESSION_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SESSION_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_session.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  $objects \$(MOD_SESSION_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SESSION_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_session_cookie" >&5
    printf %s "checking whether to enable mod_session_cookie... " >&6; }
        # Check whether --enable-session-cookie was given.
    if test ${enable_session_cookie+y}
    then :
      enableval=$enable_session_cookie; force_session_cookie=$enableval
    else $as_nop
      enable_session_cookie=$session_mods_enable
    fi
    
        _apmod_extra_msg=""
          case "$enable_session_cookie" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_session_cookie" = "static" -o "$enable_session_cookie" = "shared"; then
        :
      elif test "$enable_session_cookie" = "yes"; then
        enable_session_cookie=$module_default
      elif test "$enable_session_cookie" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session_cookie=$module_default
        else
          enable_session_cookie=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session_cookie" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_session_cookie=$module_default
        else
          enable_session_cookie=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session_cookie" = "all" -o "$enable_session_cookie" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session_cookie=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session_cookie=no
        fi
      elif test "$enable_session_cookie" = "reallyall" -o "$enable_session_cookie" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_session_cookie" != "no" ; then
          enable_session_cookie=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session_cookie=no
        fi
      else
        enable_session_cookie=no
      fi
      if test "$enable_session_cookie" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_session" = "no" ; then
                                  enable_session_cookie=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_session is disabled but required for mod_session_cookie\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_session is disabled but required for mod_session_cookie\"" >&2;}
                                elif test "$enable_session_cookie" = "static" && test "$enable_session" != "static" ; then
                                  enable_session_cookie=$enable_session
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_session_cookie shared because mod_session is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_session_cookie shared because mod_session is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_session_cookie" >&5
    printf %s "checking whether to enable mod_session_cookie... " >&6; }
                if test "$enable_session_cookie" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_session_cookie has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_session_cookie$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_session_cookie$_apmod_extra_msg" >&6; }
      if test "$enable_session_cookie" != "no"; then
        case "$enable_session_cookie" in
        static*)
          MODLIST="$MODLIST session_cookie"
          if test "session_cookie" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES session_cookie"
          if test "$session_mods_enable" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},session_cookie"
          fi
          ;;
        esac
    
    
      if test -z "$session_cookie_objects"; then
        objects="mod_session_cookie.lo"
      else
        objects="$session_cookie_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_session_cookie.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SESSION_COOKIE_LDADD)
    EOF
          if test ! -z "\$(MOD_SESSION_COOKIE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SESSION_COOKIE_LDADD)\""
        AP_LIBS="\$(MOD_SESSION_COOKIE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SESSION_COOKIE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_session_cookie.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  $objects \$(MOD_SESSION_COOKIE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SESSION_COOKIE_LDADD"
    
    
    
      fi
    
    
    if test "$enable_session_crypto" != ""; then
      session_mods_enable_crypto=$enable_session_crypto
    else
      session_mods_enable_crypto=$session_mods_enable
    fi
    if test "$session_mods_enable_crypto" != "no"; then
      saved_CPPFLAGS="$CPPFLAGS"
      CPPFLAGS="$CPPFLAGS $APR_INCLUDES $APU_INCLUDES"
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <apr_crypto.h>
    int
    main (void)
    {
    
    #if APU_HAVE_CRYPTO == 0
    #error no crypto support
    #endif
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      ap_HAVE_APR_CRYPTO="yes"
    else $as_nop
      ap_HAVE_APR_CRYPTO="no"
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
      CPPFLAGS="$saved_CPPFLAGS"
      if test $ap_HAVE_APR_CRYPTO = "no"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Your APR does not include SSL/EVP support. To enable it: configure --with-crypto" >&5
    printf "%s\n" "$as_me: WARNING: Your APR does not include SSL/EVP support. To enable it: configure --with-crypto" >&2;}
        if test "$enable_session_crypto" != "" -a "$enable_session_crypto" != "no"; then
            as_fn_error $? "mod_session_crypto cannot be enabled" "$LINENO" 5
        fi
        session_mods_enable_crypto="no"
      fi
    fi
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_session_crypto" >&5
    printf %s "checking whether to enable mod_session_crypto... " >&6; }
        # Check whether --enable-session-crypto was given.
    if test ${enable_session_crypto+y}
    then :
      enableval=$enable_session_crypto; force_session_crypto=$enableval
    else $as_nop
      enable_session_crypto=$session_mods_enable_crypto
    fi
    
        _apmod_extra_msg=""
          case "$enable_session_crypto" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_session_crypto" = "static" -o "$enable_session_crypto" = "shared"; then
        :
      elif test "$enable_session_crypto" = "yes"; then
        enable_session_crypto=$module_default
      elif test "$enable_session_crypto" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session_crypto=$module_default
        else
          enable_session_crypto=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session_crypto" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_session_crypto=$module_default
        else
          enable_session_crypto=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session_crypto" = "all" -o "$enable_session_crypto" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session_crypto=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session_crypto=no
        fi
      elif test "$enable_session_crypto" = "reallyall" -o "$enable_session_crypto" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_session_crypto" != "no" ; then
          enable_session_crypto=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session_crypto=no
        fi
      else
        enable_session_crypto=no
      fi
      if test "$enable_session_crypto" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_session" = "no" ; then
                                  enable_session_crypto=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_session is disabled but required for mod_session_crypto\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_session is disabled but required for mod_session_crypto\"" >&2;}
                                elif test "$enable_session_crypto" = "static" && test "$enable_session" != "static" ; then
                                  enable_session_crypto=$enable_session
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_session_crypto shared because mod_session is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_session_crypto shared because mod_session is built shared\"" >&2;}
                                else
    
    if test "$session_mods_enable_crypto" = "no" ; then
      enable_session_crypto=no
    fi
    
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_session_crypto" >&5
    printf %s "checking whether to enable mod_session_crypto... " >&6; }
                if test "$enable_session_crypto" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_session_crypto has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_session_crypto$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_session_crypto$_apmod_extra_msg" >&6; }
      if test "$enable_session_crypto" != "no"; then
        case "$enable_session_crypto" in
        static*)
          MODLIST="$MODLIST session_crypto"
          if test "session_crypto" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES session_crypto"
          if test "$session_mods_enable_crypto" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},session_crypto"
          fi
          ;;
        esac
    
    
      if test -z "$session_crypto_objects"; then
        objects="mod_session_crypto.lo"
      else
        objects="$session_crypto_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_session_crypto.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SESSION_CRYPTO_LDADD)
    EOF
          if test ! -z "\$(MOD_SESSION_CRYPTO_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SESSION_CRYPTO_LDADD)\""
        AP_LIBS="\$(MOD_SESSION_CRYPTO_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SESSION_CRYPTO_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_session_crypto.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  $objects \$(MOD_SESSION_CRYPTO_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SESSION_CRYPTO_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_session_dbd" >&5
    printf %s "checking whether to enable mod_session_dbd... " >&6; }
        # Check whether --enable-session-dbd was given.
    if test ${enable_session_dbd+y}
    then :
      enableval=$enable_session_dbd; force_session_dbd=$enableval
    else $as_nop
      enable_session_dbd=$session_mods_enable
    fi
    
        _apmod_extra_msg=""
          case "$enable_session_dbd" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_session_dbd" = "static" -o "$enable_session_dbd" = "shared"; then
        :
      elif test "$enable_session_dbd" = "yes"; then
        enable_session_dbd=$module_default
      elif test "$enable_session_dbd" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session_dbd=$module_default
        else
          enable_session_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session_dbd" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_session_dbd=$module_default
        else
          enable_session_dbd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_session_dbd" = "all" -o "$enable_session_dbd" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_session_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session_dbd=no
        fi
      elif test "$enable_session_dbd" = "reallyall" -o "$enable_session_dbd" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_session_dbd" != "no" ; then
          enable_session_dbd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_session_dbd=no
        fi
      else
        enable_session_dbd=no
      fi
      if test "$enable_session_dbd" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_session" = "no" ; then
                                  enable_session_dbd=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_session is disabled but required for mod_session_dbd\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_session is disabled but required for mod_session_dbd\"" >&2;}
                                elif test "$enable_session_dbd" = "static" && test "$enable_session" != "static" ; then
                                  enable_session_dbd=$enable_session
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_session_dbd shared because mod_session is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_session_dbd shared because mod_session is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_session_dbd" >&5
    printf %s "checking whether to enable mod_session_dbd... " >&6; }
                if test "$enable_session_dbd" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_session_dbd has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_session_dbd$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_session_dbd$_apmod_extra_msg" >&6; }
      if test "$enable_session_dbd" != "no"; then
        case "$enable_session_dbd" in
        static*)
          MODLIST="$MODLIST session_dbd"
          if test "session_dbd" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES session_dbd"
          if test "$session_mods_enable" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},session_dbd"
          fi
          ;;
        esac
    
    
      if test -z "$session_dbd_objects"; then
        objects="mod_session_dbd.lo"
      else
        objects="$session_dbd_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_session_dbd.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SESSION_DBD_LDADD)
    EOF
          if test ! -z "\$(MOD_SESSION_DBD_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SESSION_DBD_LDADD)\""
        AP_LIBS="\$(MOD_SESSION_DBD_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SESSION_DBD_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_session_dbd.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  $objects \$(MOD_SESSION_DBD_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SESSION_DBD_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
    
      current_dir=slotmem
      modpath_current=modules/slotmem
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d slotmem || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_slotmem_shm" >&5
    printf %s "checking whether to enable mod_slotmem_shm... " >&6; }
        # Check whether --enable-slotmem-shm was given.
    if test ${enable_slotmem_shm+y}
    then :
      enableval=$enable_slotmem_shm; force_slotmem_shm=$enableval
    else $as_nop
      enable_slotmem_shm=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_slotmem_shm" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_slotmem_shm" = "static" -o "$enable_slotmem_shm" = "shared"; then
        :
      elif test "$enable_slotmem_shm" = "yes"; then
        enable_slotmem_shm=$module_default
      elif test "$enable_slotmem_shm" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_slotmem_shm=$module_default
        else
          enable_slotmem_shm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_slotmem_shm" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_slotmem_shm=$module_default
        else
          enable_slotmem_shm=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_slotmem_shm" = "all" -o "$enable_slotmem_shm" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_slotmem_shm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_slotmem_shm=no
        fi
      elif test "$enable_slotmem_shm" = "reallyall" -o "$enable_slotmem_shm" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_slotmem_shm" != "no" ; then
          enable_slotmem_shm=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_slotmem_shm=no
        fi
      else
        enable_slotmem_shm=no
      fi
      if test "$enable_slotmem_shm" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_slotmem_shm$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_slotmem_shm$_apmod_extra_msg" >&6; }
      if test "$enable_slotmem_shm" != "no"; then
        case "$enable_slotmem_shm" in
        static*)
          MODLIST="$MODLIST slotmem_shm"
          if test "slotmem_shm" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES slotmem_shm"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},slotmem_shm"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_slotmem_shm.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_slotmem_shm.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SLOTMEM_SHM_LDADD)
    EOF
          if test ! -z "\$(MOD_SLOTMEM_SHM_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SLOTMEM_SHM_LDADD)\""
        AP_LIBS="\$(MOD_SLOTMEM_SHM_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SLOTMEM_SHM_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_slotmem_shm.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  $objects \$(MOD_SLOTMEM_SHM_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SLOTMEM_SHM_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_slotmem_plain" >&5
    printf %s "checking whether to enable mod_slotmem_plain... " >&6; }
        # Check whether --enable-slotmem-plain was given.
    if test ${enable_slotmem_plain+y}
    then :
      enableval=$enable_slotmem_plain; force_slotmem_plain=$enableval
    else $as_nop
      enable_slotmem_plain=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_slotmem_plain" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_slotmem_plain" = "static" -o "$enable_slotmem_plain" = "shared"; then
        :
      elif test "$enable_slotmem_plain" = "yes"; then
        enable_slotmem_plain=$module_default
      elif test "$enable_slotmem_plain" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_slotmem_plain=$module_default
        else
          enable_slotmem_plain=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_slotmem_plain" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_slotmem_plain=$module_default
        else
          enable_slotmem_plain=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_slotmem_plain" = "all" -o "$enable_slotmem_plain" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_slotmem_plain=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_slotmem_plain=no
        fi
      elif test "$enable_slotmem_plain" = "reallyall" -o "$enable_slotmem_plain" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_slotmem_plain" != "no" ; then
          enable_slotmem_plain=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_slotmem_plain=no
        fi
      else
        enable_slotmem_plain=no
      fi
      if test "$enable_slotmem_plain" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_slotmem_plain$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_slotmem_plain$_apmod_extra_msg" >&6; }
      if test "$enable_slotmem_plain" != "no"; then
        case "$enable_slotmem_plain" in
        static*)
          MODLIST="$MODLIST slotmem_plain"
          if test "slotmem_plain" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES slotmem_plain"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},slotmem_plain"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_slotmem_plain.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_slotmem_plain.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SLOTMEM_PLAIN_LDADD)
    EOF
          if test ! -z "\$(MOD_SLOTMEM_PLAIN_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SLOTMEM_PLAIN_LDADD)\""
        AP_LIBS="\$(MOD_SLOTMEM_PLAIN_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SLOTMEM_PLAIN_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_slotmem_plain.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  $objects \$(MOD_SLOTMEM_PLAIN_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SLOTMEM_PLAIN_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=ssl
      modpath_current=modules/ssl
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d ssl || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    ssl_objs="mod_ssl.lo ssl_engine_config.lo ssl_engine_init.lo ssl_engine_io.lo ssl_engine_kernel.lo ssl_engine_log.lo ssl_engine_mutex.lo ssl_engine_pphrase.lo ssl_engine_rand.lo ssl_engine_vars.lo ssl_scache.lo ssl_util_stapling.lo ssl_util.lo ssl_util_ssl.lo ssl_engine_ocsp.lo ssl_util_ocsp.lo "
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_ssl" >&5
    printf %s "checking whether to enable mod_ssl... " >&6; }
        # Check whether --enable-ssl was given.
    if test ${enable_ssl+y}
    then :
      enableval=$enable_ssl; force_ssl=$enableval
    else $as_nop
      enable_ssl=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_ssl" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_ssl" = "static" -o "$enable_ssl" = "shared"; then
        :
      elif test "$enable_ssl" = "yes"; then
        enable_ssl=$module_default
      elif test "$enable_ssl" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ssl=$module_default
        else
          enable_ssl=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ssl" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_ssl=$module_default
        else
          enable_ssl=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_ssl" = "all" -o "$enable_ssl" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_ssl=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ssl=no
        fi
      elif test "$enable_ssl" = "reallyall" -o "$enable_ssl" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_ssl" != "no" ; then
          enable_ssl=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_ssl=no
        fi
      else
        enable_ssl=no
      fi
      if test "$enable_ssl" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenSSL" >&5
    printf %s "checking for OpenSSL... " >&6; }
    if test ${ac_cv_openssl+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
            ac_cv_openssl=no
        ap_openssl_found=""
        ap_openssl_base=""
        ap_openssl_libs=""
        ap_openssl_mod_cflags=""
        ap_openssl_mod_ldflags=""
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided OpenSSL base directory" >&5
    printf %s "checking for user-provided OpenSSL base directory... " >&6; }
    
    # Check whether --with-ssl was given.
    if test ${with_ssl+y}
    then :
      withval=$with_ssl;
                if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                    ap_openssl_base="`cd $withval ; pwd`"
          fi
    
    fi
    
        if test "x$ap_openssl_base" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_openssl_base" >&5
    printf "%s\n" "$ap_openssl_base" >&6; }
        fi
    
            saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
            if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          if test "x$ap_openssl_base" != "x"; then
            if test -f "${ap_openssl_base}/lib/pkgconfig/openssl.pc"; then
                                  PKG_CONFIG_PATH="${ap_openssl_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_openssl_base}/lib64/pkgconfig/openssl.pc"; then
                                  PKG_CONFIG_PATH="${ap_openssl_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          # Check whether --enable-ssl-staticlib-deps was given.
    if test ${enable_ssl_staticlib_deps+y}
    then :
      enableval=$enable_ssl_staticlib_deps;
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
    
    fi
    
          ap_openssl_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors openssl`"
          if test $? -eq 0; then
            ap_openssl_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I openssl`"
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"$pkglookup\""
        CPPFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$pkglookup\""
        MOD_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ab_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_CFLAGS to \"$pkglookup\""
        ab_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_CFLAGS"
            ab_CFLAGS="$ab_CFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L openssl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other openssl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
            if test "x$ap_openssl_base" != "x" -a "x$ap_openssl_found" = "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_openssl_base/include\""
        CPPFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I$ap_openssl_base/include\""
        MOD_CFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ab_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_CFLAGS to \"-I$ap_openssl_base/include\""
        ab_CFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_CFLAGS"
            ab_CFLAGS="$ab_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_openssl_base/lib\""
        LDFLAGS="-L$ap_openssl_base/lib"
      else
        apr_addto_bugger="-L$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"-L$ap_openssl_base/lib\""
        MOD_LDFLAGS="-L$ap_openssl_base/lib"
      else
        apr_addto_bugger="-L$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_openssl_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_platform_runtime_link_flag$ap_openssl_base/lib\""
        MOD_LDFLAGS="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
        fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenSSL version >= 0.9.8a" >&5
    printf %s "checking for OpenSSL version >= 0.9.8a... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <openssl/opensslv.h>
    int
    main (void)
    {
    
    #if !defined(OPENSSL_VERSION_NUMBER)
    #error "Missing OpenSSL version"
    #endif
    #if OPENSSL_VERSION_NUMBER < 0x0090801f
    #error "Unsupported OpenSSL version " OPENSSL_VERSION_TEXT
    #endif
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: OK" >&5
    printf "%s\n" "OK" >&6; }
           ac_cv_openssl=yes
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FAILED" >&5
    printf "%s\n" "FAILED" >&6; }
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
        if test "x$ac_cv_openssl" = "xyes"; then
          ap_openssl_libs="${ap_openssl_libs:--lssl -lcrypto} `$apr_config --libs`"
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_openssl_libs\""
        MOD_LDFLAGS="$ap_openssl_libs"
      else
        apr_addto_bugger="$ap_openssl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_openssl_libs\""
        LIBS="$ap_openssl_libs"
      else
        apr_addto_bugger="$ap_openssl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
    
      test "x$silent" != "xyes" && echo "  forcing ab_LIBS to \"$MOD_LDFLAGS\""
      ab_LIBS="$MOD_LDFLAGS"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ab_CFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ab_LIBS"
    
    
    
                liberrors=""
          ac_fn_c_check_header_compile "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default"
    if test "x$ac_cv_header_openssl_engine_h" = xyes
    then :
      printf "%s\n" "#define HAVE_OPENSSL_ENGINE_H 1" >>confdefs.h
    
    fi
    
    
      for ac_func in SSL_CTX_new
    do :
      ac_fn_c_check_func "$LINENO" "SSL_CTX_new" "ac_cv_func_SSL_CTX_new"
    if test "x$ac_cv_func_SSL_CTX_new" = xyes
    then :
      printf "%s\n" "#define HAVE_SSL_CTX_NEW 1" >>confdefs.h
    
    else $as_nop
      liberrors="yes"
    fi
    
    done
          ac_fn_c_check_func "$LINENO" "OPENSSL_init_ssl" "ac_cv_func_OPENSSL_init_ssl"
    if test "x$ac_cv_func_OPENSSL_init_ssl" = xyes
    then :
      printf "%s\n" "#define HAVE_OPENSSL_INIT_SSL 1" >>confdefs.h
    
    fi
    
          ac_fn_c_check_func "$LINENO" "ENGINE_init" "ac_cv_func_ENGINE_init"
    if test "x$ac_cv_func_ENGINE_init" = xyes
    then :
      printf "%s\n" "#define HAVE_ENGINE_INIT 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "ENGINE_load_builtin_engines" "ac_cv_func_ENGINE_load_builtin_engines"
    if test "x$ac_cv_func_ENGINE_load_builtin_engines" = xyes
    then :
      printf "%s\n" "#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "RAND_egd" "ac_cv_func_RAND_egd"
    if test "x$ac_cv_func_RAND_egd" = xyes
    then :
      printf "%s\n" "#define HAVE_RAND_EGD 1" >>confdefs.h
    
    fi
    
          if test "x$liberrors" != "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSL libraries are unusable" >&5
    printf "%s\n" "$as_me: WARNING: OpenSSL libraries are unusable" >&2;}
          fi
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSL version is too old" >&5
    printf "%s\n" "$as_me: WARNING: OpenSSL version is too old" >&2;}
        fi
    
            CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
            ap_openssl_mod_cflags=$MOD_CFLAGS
        ap_openssl_mod_ldflags=$MOD_LDFLAGS
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_openssl" >&5
    printf "%s\n" "$ac_cv_openssl" >&6; }
      if test "x$ac_cv_openssl" = "xyes"; then
    
    printf "%s\n" "#define HAVE_OPENSSL 1" >>confdefs.h
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_openssl_mod_ldflags\""
        MOD_LDFLAGS="$ap_openssl_mod_ldflags"
      else
        apr_addto_bugger="$ap_openssl_mod_ldflags"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$ap_openssl_mod_cflags\""
        MOD_CFLAGS="$ap_openssl_mod_cflags"
      else
        apr_addto_bugger="$ap_openssl_mod_cflags"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
      fi
    
        if test "$ac_cv_openssl" = "yes" ; then
            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:
    
      if test "x$MOD_SSL_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_SSL_LDADD to \"-export-symbols-regex ssl_module\""
        MOD_SSL_LDADD="-export-symbols-regex ssl_module"
      else
        apr_addto_bugger="-export-symbols-regex ssl_module"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_SSL_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_SSL_LDADD"
            MOD_SSL_LDADD="$MOD_SSL_LDADD $i"
          fi
        done
      fi
    
            fi
        else
            enable_ssl=no
        fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_ssl" >&5
    printf %s "checking whether to enable mod_ssl... " >&6; }
                if test "$enable_ssl" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_ssl has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_ssl$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_ssl$_apmod_extra_msg" >&6; }
      if test "$enable_ssl" != "no"; then
        case "$enable_ssl" in
        static*)
          MODLIST="$MODLIST ssl"
          if test "ssl" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES ssl"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},ssl"
          fi
          ;;
        esac
    
    
      if test -z "$ssl_objs"; then
        objects="mod_ssl.lo"
      else
        objects="$ssl_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_ssl.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SSL_LDADD)
    EOF
          if test ! -z "\$(MOD_SSL_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SSL_LDADD)\""
        AP_LIBS="\$(MOD_SSL_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SSL_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_ssl.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  $objects \$(MOD_SSL_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SSL_LDADD"
    
    
    
      fi
    
    
    # Ensure that other modules can pick up mod_ssl.h
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=test
      modpath_current=modules/test
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d test || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_optional_hook_export" >&5
    printf %s "checking whether to enable mod_optional_hook_export... " >&6; }
        # Check whether --enable-optional-hook-export was given.
    if test ${enable_optional_hook_export+y}
    then :
      enableval=$enable_optional_hook_export; force_optional_hook_export=$enableval
    else $as_nop
      enable_optional_hook_export=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_optional_hook_export" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_optional_hook_export" = "static" -o "$enable_optional_hook_export" = "shared"; then
        :
      elif test "$enable_optional_hook_export" = "yes"; then
        enable_optional_hook_export=$module_default
      elif test "$enable_optional_hook_export" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_hook_export=$module_default
        else
          enable_optional_hook_export=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_hook_export" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_optional_hook_export=$module_default
        else
          enable_optional_hook_export=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_hook_export" = "all" -o "$enable_optional_hook_export" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_hook_export=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_hook_export=no
        fi
      elif test "$enable_optional_hook_export" = "reallyall" -o "$enable_optional_hook_export" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_optional_hook_export" != "no" ; then
          enable_optional_hook_export=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_hook_export=no
        fi
      else
        enable_optional_hook_export=no
      fi
      if test "$enable_optional_hook_export" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_optional_hook_export$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_optional_hook_export$_apmod_extra_msg" >&6; }
      if test "$enable_optional_hook_export" != "no"; then
        case "$enable_optional_hook_export" in
        static*)
          MODLIST="$MODLIST optional_hook_export"
          if test "optional_hook_export" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES optional_hook_export"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},optional_hook_export"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_optional_hook_export.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_optional_hook_export.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_OPTIONAL_HOOK_EXPORT_LDADD)
    EOF
          if test ! -z "\$(MOD_OPTIONAL_HOOK_EXPORT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_OPTIONAL_HOOK_EXPORT_LDADD)\""
        AP_LIBS="\$(MOD_OPTIONAL_HOOK_EXPORT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_OPTIONAL_HOOK_EXPORT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_optional_hook_export.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  $objects \$(MOD_OPTIONAL_HOOK_EXPORT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_OPTIONAL_HOOK_EXPORT_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_optional_hook_import" >&5
    printf %s "checking whether to enable mod_optional_hook_import... " >&6; }
        # Check whether --enable-optional-hook-import was given.
    if test ${enable_optional_hook_import+y}
    then :
      enableval=$enable_optional_hook_import; force_optional_hook_import=$enableval
    else $as_nop
      enable_optional_hook_import=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_optional_hook_import" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_optional_hook_import" = "static" -o "$enable_optional_hook_import" = "shared"; then
        :
      elif test "$enable_optional_hook_import" = "yes"; then
        enable_optional_hook_import=$module_default
      elif test "$enable_optional_hook_import" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_hook_import=$module_default
        else
          enable_optional_hook_import=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_hook_import" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_optional_hook_import=$module_default
        else
          enable_optional_hook_import=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_hook_import" = "all" -o "$enable_optional_hook_import" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_hook_import=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_hook_import=no
        fi
      elif test "$enable_optional_hook_import" = "reallyall" -o "$enable_optional_hook_import" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_optional_hook_import" != "no" ; then
          enable_optional_hook_import=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_hook_import=no
        fi
      else
        enable_optional_hook_import=no
      fi
      if test "$enable_optional_hook_import" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_optional_hook_import$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_optional_hook_import$_apmod_extra_msg" >&6; }
      if test "$enable_optional_hook_import" != "no"; then
        case "$enable_optional_hook_import" in
        static*)
          MODLIST="$MODLIST optional_hook_import"
          if test "optional_hook_import" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES optional_hook_import"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},optional_hook_import"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_optional_hook_import.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_optional_hook_import.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_OPTIONAL_HOOK_IMPORT_LDADD)
    EOF
          if test ! -z "\$(MOD_OPTIONAL_HOOK_IMPORT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_OPTIONAL_HOOK_IMPORT_LDADD)\""
        AP_LIBS="\$(MOD_OPTIONAL_HOOK_IMPORT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_OPTIONAL_HOOK_IMPORT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_optional_hook_import.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  $objects \$(MOD_OPTIONAL_HOOK_IMPORT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_OPTIONAL_HOOK_IMPORT_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_optional_fn_import" >&5
    printf %s "checking whether to enable mod_optional_fn_import... " >&6; }
        # Check whether --enable-optional-fn-import was given.
    if test ${enable_optional_fn_import+y}
    then :
      enableval=$enable_optional_fn_import; force_optional_fn_import=$enableval
    else $as_nop
      enable_optional_fn_import=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_optional_fn_import" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_optional_fn_import" = "static" -o "$enable_optional_fn_import" = "shared"; then
        :
      elif test "$enable_optional_fn_import" = "yes"; then
        enable_optional_fn_import=$module_default
      elif test "$enable_optional_fn_import" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_fn_import=$module_default
        else
          enable_optional_fn_import=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_fn_import" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_optional_fn_import=$module_default
        else
          enable_optional_fn_import=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_fn_import" = "all" -o "$enable_optional_fn_import" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_fn_import=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_fn_import=no
        fi
      elif test "$enable_optional_fn_import" = "reallyall" -o "$enable_optional_fn_import" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_optional_fn_import" != "no" ; then
          enable_optional_fn_import=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_fn_import=no
        fi
      else
        enable_optional_fn_import=no
      fi
      if test "$enable_optional_fn_import" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_optional_fn_import$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_optional_fn_import$_apmod_extra_msg" >&6; }
      if test "$enable_optional_fn_import" != "no"; then
        case "$enable_optional_fn_import" in
        static*)
          MODLIST="$MODLIST optional_fn_import"
          if test "optional_fn_import" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES optional_fn_import"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},optional_fn_import"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_optional_fn_import.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_optional_fn_import.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_OPTIONAL_FN_IMPORT_LDADD)
    EOF
          if test ! -z "\$(MOD_OPTIONAL_FN_IMPORT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_OPTIONAL_FN_IMPORT_LDADD)\""
        AP_LIBS="\$(MOD_OPTIONAL_FN_IMPORT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_OPTIONAL_FN_IMPORT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_optional_fn_import.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  $objects \$(MOD_OPTIONAL_FN_IMPORT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_OPTIONAL_FN_IMPORT_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_optional_fn_export" >&5
    printf %s "checking whether to enable mod_optional_fn_export... " >&6; }
        # Check whether --enable-optional-fn-export was given.
    if test ${enable_optional_fn_export+y}
    then :
      enableval=$enable_optional_fn_export; force_optional_fn_export=$enableval
    else $as_nop
      enable_optional_fn_export=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_optional_fn_export" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_optional_fn_export" = "static" -o "$enable_optional_fn_export" = "shared"; then
        :
      elif test "$enable_optional_fn_export" = "yes"; then
        enable_optional_fn_export=$module_default
      elif test "$enable_optional_fn_export" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_fn_export=$module_default
        else
          enable_optional_fn_export=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_fn_export" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_optional_fn_export=$module_default
        else
          enable_optional_fn_export=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_optional_fn_export" = "all" -o "$enable_optional_fn_export" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_optional_fn_export=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_fn_export=no
        fi
      elif test "$enable_optional_fn_export" = "reallyall" -o "$enable_optional_fn_export" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_optional_fn_export" != "no" ; then
          enable_optional_fn_export=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_optional_fn_export=no
        fi
      else
        enable_optional_fn_export=no
      fi
      if test "$enable_optional_fn_export" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_optional_fn_export$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_optional_fn_export$_apmod_extra_msg" >&6; }
      if test "$enable_optional_fn_export" != "no"; then
        case "$enable_optional_fn_export" in
        static*)
          MODLIST="$MODLIST optional_fn_export"
          if test "optional_fn_export" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES optional_fn_export"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},optional_fn_export"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_optional_fn_export.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_optional_fn_export.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_OPTIONAL_FN_EXPORT_LDADD)
    EOF
          if test ! -z "\$(MOD_OPTIONAL_FN_EXPORT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_OPTIONAL_FN_EXPORT_LDADD)\""
        AP_LIBS="\$(MOD_OPTIONAL_FN_EXPORT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_OPTIONAL_FN_EXPORT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_optional_fn_export.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  $objects \$(MOD_OPTIONAL_FN_EXPORT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_OPTIONAL_FN_EXPORT_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dialup" >&5
    printf %s "checking whether to enable mod_dialup... " >&6; }
        # Check whether --enable-dialup was given.
    if test ${enable_dialup+y}
    then :
      enableval=$enable_dialup; force_dialup=$enableval
    else $as_nop
      enable_dialup=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_dialup" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_dialup" = "static" -o "$enable_dialup" = "shared"; then
        :
      elif test "$enable_dialup" = "yes"; then
        enable_dialup=$module_default
      elif test "$enable_dialup" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dialup=$module_default
        else
          enable_dialup=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dialup" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_dialup=$module_default
        else
          enable_dialup=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dialup" = "all" -o "$enable_dialup" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dialup=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dialup=no
        fi
      elif test "$enable_dialup" = "reallyall" -o "$enable_dialup" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_dialup" != "no" ; then
          enable_dialup=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dialup=no
        fi
      else
        enable_dialup=no
      fi
      if test "$enable_dialup" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_dialup$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_dialup$_apmod_extra_msg" >&6; }
      if test "$enable_dialup" != "no"; then
        case "$enable_dialup" in
        static*)
          MODLIST="$MODLIST dialup"
          if test "dialup" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES dialup"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},dialup"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_dialup.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_dialup.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DIALUP_LDADD)
    EOF
          if test ! -z "\$(MOD_DIALUP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DIALUP_LDADD)\""
        AP_LIBS="\$(MOD_DIALUP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DIALUP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_dialup.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  $objects \$(MOD_DIALUP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DIALUP_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for target platform" >&5
    printf %s "checking for target platform... " >&6; }
    
    case $host in
    *pc-os2-emx*)
      OS="os2"
      OS_DIR=$OS
      ;;
    bs2000*)
      OS="unix"
      OS_DIR=$OS
      ;;
    *cygwin*)
      OS="cygwin"
      OS_DIR="unix"
      ;;
    *mingw32*)
      OS="win32"
      OS_DIR=$OS
      ;;
    *)
      OS="unix"
      OS_DIR=$OS;;
    esac
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OS" >&5
    printf "%s\n" "$OS" >&6; }
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES os/${OS_DIR}/Makefile"
    
    
    if test "$OS" = "os2" ; then
    
      if test "x$CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CFLAGS to \"-DOS2 -O2\""
        CFLAGS="-DOS2 -O2"
      else
        apr_addto_bugger="-DOS2 -O2"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CFLAGS"
            CFLAGS="$CFLAGS $i"
          fi
        done
      fi
    
    fi
    
    if test "$OS" = "unix" ; then
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rlim_t" >&5
    printf %s "checking for rlim_t... " >&6; }
    if test ${ac_cv_type_rlim_t+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <sys/types.h>
    #include <sys/time.h>
    #include <sys/resource.h>
    
    int
    main (void)
    {
    rlim_t spoon;
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
    
          ac_cv_type_rlim_t=yes
    
    else $as_nop
      ac_cv_type_rlim_t=no
    
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_rlim_t" >&5
    printf "%s\n" "$ac_cv_type_rlim_t" >&6; }
      if test "$ac_cv_type_rlim_t" = "no" ; then
    
    printf "%s\n" "#define rlim_t int" >>confdefs.h
    
      fi
    
    
        ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_time_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_resource_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_RESOURCE_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/sem.h" "ac_cv_header_sys_sem_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_sem_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_SEM_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "sys/ipc.h" "ac_cv_header_sys_ipc_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_ipc_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_IPC_H 1" >>confdefs.h
    
    fi
    
    
        ac_fn_c_check_func "$LINENO" "setsid" "ac_cv_func_setsid"
    if test "x$ac_cv_func_setsid" = xyes
    then :
      printf "%s\n" "#define HAVE_SETSID 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "killpg" "ac_cv_func_killpg"
    if test "x$ac_cv_func_killpg" = xyes
    then :
      printf "%s\n" "#define HAVE_KILLPG 1" >>confdefs.h
    
    fi
    
    fi
    
    
    
    ac_fn_c_check_header_compile "$LINENO" "bstring.h" "ac_cv_header_bstring_h" "$ac_includes_default"
    if test "x$ac_cv_header_bstring_h" = xyes
    then :
      printf "%s\n" "#define HAVE_BSTRING_H 1" >>confdefs.h
    
    fi
    ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
    if test "x$ac_cv_header_unistd_h" = xyes
    then :
      printf "%s\n" "#define HAVE_UNISTD_H 1" >>confdefs.h
    
    fi
    
    
    
    
    ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog"
    if test "x$ac_cv_func_syslog" = xyes
    then :
      printf "%s\n" "#define HAVE_SYSLOG 1" >>confdefs.h
    
    fi
    
    
        ac_fn_c_check_header_compile "$LINENO" "sys/times.h" "ac_cv_header_sys_times_h" "$ac_includes_default"
    if test "x$ac_cv_header_sys_times_h" = xyes
    then :
      printf "%s\n" "#define HAVE_SYS_TIMES_H 1" >>confdefs.h
    
    fi
    
        ac_fn_c_check_func "$LINENO" "times" "ac_cv_func_times"
    if test "x$ac_cv_func_times" = xyes
    then :
      printf "%s\n" "#define HAVE_TIMES 1" >>confdefs.h
    
    fi
    
    
    # util_expr needs header files in server source dir
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/server\""
        INCLUDES="-I\$(top_srcdir)/server"
      else
        apr_addto_bugger="-I\$(top_srcdir)/server"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
    
    apr_old_cppflags=$CPPFLAGS
    CPPFLAGS="$CPPFLAGS $INCLUDES"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr.h>
    #if APR_HAS_THREADS
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_define_APR_HAS_THREADS=yes
    else $as_nop
      ac_cv_define_APR_HAS_THREADS=no
    fi
    rm -rf conftest*
    
    CPPFLAGS=$apr_old_cppflags
    
    
    have_threaded_sig_graceful=yes
    case $host in
        *-linux-*)
            case `uname -r` in
              2.0* )
                                                    have_threaded_sig_graceful=no
              ;;
            esac
        ;;
    esac
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether APR supports thread-safe pollsets" >&5
    printf %s "checking whether APR supports thread-safe pollsets... " >&6; }
    if test ${ac_cv_have_threadsafe_pollset+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
        case $host in
            *-apple-darwin[1-9].*)
    
      if test -z "$ac_cv_func_kqueue"; then
        test "x$silent" != "xyes" && echo "  setting ac_cv_func_kqueue to \"no\""
        ac_cv_func_kqueue="no"
      fi
    
                ;;
        esac
        ac_fn_c_check_func "$LINENO" "kqueue" "ac_cv_func_kqueue"
    if test "x$ac_cv_func_kqueue" = xyes
    then :
      printf "%s\n" "#define HAVE_KQUEUE 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "port_create" "ac_cv_func_port_create"
    if test "x$ac_cv_func_port_create" = xyes
    then :
      printf "%s\n" "#define HAVE_PORT_CREATE 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "epoll_create" "ac_cv_func_epoll_create"
    if test "x$ac_cv_func_epoll_create" = xyes
    then :
      printf "%s\n" "#define HAVE_EPOLL_CREATE 1" >>confdefs.h
    
    fi
    
        if test "$ac_cv_func_kqueue$ac_cv_func_port_create$ac_cv_func_epoll_create" != "nonono"; then
            ac_cv_have_threadsafe_pollset=yes
        else
            ac_cv_have_threadsafe_pollset=no
        fi
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_threadsafe_pollset" >&5
    printf "%s\n" "$ac_cv_have_threadsafe_pollset" >&6; }
    
    case $APR_VERSION in
        1.4*)
            apr_has_skiplist=no
            ;;
        *)
            apr_has_skiplist=yes
    esac
    
    case $host in
        *mingw32* | *os2-emx*)
            forking_mpms_supported=no
            ;;
        *)
            forking_mpms_supported=yes
            ;;
    esac
    
    
    
    ap_mpm_is_supported ()
    {
        eval "tmp=\$ap_supported_mpm_$1"
        if test -z "$tmp"; then
            return 1
        else
            return 0
        fi
    }
    
    ap_mpm_supports_shared ()
    {
        eval "tmp=\$ap_supported_mpm_$1"
        if test "$tmp" = "shared"; then
            return 0
        else
            return 1
        fi
    }
    
    ap_mpm_is_threaded ()
    {
        if test "$mpm_build" = "shared" -a ac_cv_define_APR_HAS_THREADS = "yes"; then
            return 0
        fi
    
        for mpm in $ap_enabled_mpms; do
            eval "tmp=\$ap_threaded_mpm_$mpm"
            if test "$tmp" = "yes"; then
                return 0
            fi
        done
        return 1
    }
    
    ap_mpm_is_enabled ()
    {
        eval "tmp=\$ap_enabled_mpm_$1"
        if test "$tmp" = "yes"; then
            return 0
        else
            return 1
        fi
    }
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if event MPM supports this platform" >&5
    printf %s "checking if event MPM supports this platform... " >&6; }
    if test $forking_mpms_supported != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - This is not a forking platform" >&5
    printf "%s\n" "no - This is not a forking platform" >&6; }
    elif test $ac_cv_define_APR_HAS_THREADS != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - APR does not support threads" >&5
    printf "%s\n" "no - APR does not support threads" >&6; }
    elif test $have_threaded_sig_graceful != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - SIG_GRACEFUL cannot be used with a threaded MPM" >&5
    printf "%s\n" "no - SIG_GRACEFUL cannot be used with a threaded MPM" >&6; }
    elif test $ac_cv_have_threadsafe_pollset != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - APR_POLLSET_THREADSAFE is not supported" >&5
    printf "%s\n" "no - APR_POLLSET_THREADSAFE is not supported" >&6; }
    elif test $apr_has_skiplist != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - APR skiplist is not available" >&5
    printf "%s\n" "no - APR skiplist is not available" >&6; }
    else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
    
        if test "yes" = "yes"; then
            eval "ap_supported_mpm_event=shared"
            ap_supported_shared_mpms="$ap_supported_shared_mpms event "
        else
            eval "ap_supported_mpm_event=static"
        fi
        if test "yes" = "yes"; then
            eval "ap_threaded_mpm_event=yes"
        fi
    
    fi
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if mpmt_os2 MPM supports this platform" >&5
    printf %s "checking if mpmt_os2 MPM supports this platform... " >&6; }
    case $host in
        *os2-emx*)
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
    
        if test "no" = "yes"; then
            eval "ap_supported_mpm_mpmt_os2=shared"
            ap_supported_shared_mpms="$ap_supported_shared_mpms mpmt_os2 "
        else
            eval "ap_supported_mpm_mpmt_os2=static"
        fi
        if test "yes" = "yes"; then
            eval "ap_threaded_mpm_mpmt_os2=yes"
        fi
    
            ;;
        *)
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
            ;;
    esac
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if prefork MPM supports this platform" >&5
    printf %s "checking if prefork MPM supports this platform... " >&6; }
    if test $forking_mpms_supported != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - This is not a forking platform" >&5
    printf "%s\n" "no - This is not a forking platform" >&6; }
    else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
    
        if test "yes" = "yes"; then
            eval "ap_supported_mpm_prefork=shared"
            ap_supported_shared_mpms="$ap_supported_shared_mpms prefork "
        else
            eval "ap_supported_mpm_prefork=static"
        fi
        if test "no" = "yes"; then
            eval "ap_threaded_mpm_prefork=yes"
        fi
    
    fi
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if WinNT MPM supports this platform" >&5
    printf %s "checking if WinNT MPM supports this platform... " >&6; }
    case $host in
        *mingw32*)
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
    
        if test "no" = "yes"; then
            eval "ap_supported_mpm_winnt=shared"
            ap_supported_shared_mpms="$ap_supported_shared_mpms winnt "
        else
            eval "ap_supported_mpm_winnt=static"
        fi
        if test "yes" = "yes"; then
            eval "ap_threaded_mpm_winnt=yes"
        fi
    
            ;;
        *)
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
    printf "%s\n" "no" >&6; }
            ;;
    esac
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if worker MPM supports this platform" >&5
    printf %s "checking if worker MPM supports this platform... " >&6; }
    if test $forking_mpms_supported != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - This is not a forking platform" >&5
    printf "%s\n" "no - This is not a forking platform" >&6; }
    elif test $ac_cv_define_APR_HAS_THREADS != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - APR does not support threads" >&5
    printf "%s\n" "no - APR does not support threads" >&6; }
    elif test $have_threaded_sig_graceful != yes; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - SIG_GRACEFUL cannot be used with a threaded MPM" >&5
    printf "%s\n" "no - SIG_GRACEFUL cannot be used with a threaded MPM" >&6; }
    else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
    
        if test "yes" = "yes"; then
            eval "ap_supported_mpm_worker=shared"
            ap_supported_shared_mpms="$ap_supported_shared_mpms worker "
        else
            eval "ap_supported_mpm_worker=static"
        fi
        if test "yes" = "yes"; then
            eval "ap_threaded_mpm_worker=yes"
        fi
    
    fi
    
    htpasswd_LTFLAGS=""
    htdigest_LTFLAGS=""
    rotatelogs_LTFLAGS=""
    logresolve_LTFLAGS=""
    htdbm_LTFLAGS=""
    ab_LTFLAGS=""
    checkgid_LTFLAGS=""
    htcacheclean_LTFLAGS=""
    httxt2dbm_LTFLAGS=""
    fcgistarter_LTFLAGS=""
    
    # Check whether --enable-static-support was given.
    if test ${enable_static_support+y}
    then :
      enableval=$enable_static_support;
    if test "$enableval" = "yes" ; then
    
      if test "x$htpasswd_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htpasswd_LTFLAGS to \"-static\""
        htpasswd_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htpasswd_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htpasswd_LTFLAGS"
            htpasswd_LTFLAGS="$htpasswd_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$htdigest_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htdigest_LTFLAGS to \"-static\""
        htdigest_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htdigest_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htdigest_LTFLAGS"
            htdigest_LTFLAGS="$htdigest_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$rotatelogs_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting rotatelogs_LTFLAGS to \"-static\""
        rotatelogs_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $rotatelogs_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to rotatelogs_LTFLAGS"
            rotatelogs_LTFLAGS="$rotatelogs_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$logresolve_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting logresolve_LTFLAGS to \"-static\""
        logresolve_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $logresolve_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to logresolve_LTFLAGS"
            logresolve_LTFLAGS="$logresolve_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$htdbm_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htdbm_LTFLAGS to \"-static\""
        htdbm_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htdbm_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htdbm_LTFLAGS"
            htdbm_LTFLAGS="$htdbm_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ab_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_LTFLAGS to \"-static\""
        ab_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_LTFLAGS"
            ab_LTFLAGS="$ab_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$checkgid_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting checkgid_LTFLAGS to \"-static\""
        checkgid_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $checkgid_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to checkgid_LTFLAGS"
            checkgid_LTFLAGS="$checkgid_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$htcacheclean_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htcacheclean_LTFLAGS to \"-static\""
        htcacheclean_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htcacheclean_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htcacheclean_LTFLAGS"
            htcacheclean_LTFLAGS="$htcacheclean_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$httxt2dbm_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting httxt2dbm_LTFLAGS to \"-static\""
        httxt2dbm_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $httxt2dbm_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to httxt2dbm_LTFLAGS"
            httxt2dbm_LTFLAGS="$httxt2dbm_LTFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$fcgistarter_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting fcgistarter_LTFLAGS to \"-static\""
        fcgistarter_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $fcgistarter_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to fcgistarter_LTFLAGS"
            fcgistarter_LTFLAGS="$fcgistarter_LTFLAGS $i"
          fi
        done
      fi
    
    fi
    
    fi
    
    
    # Check whether --enable-static-htpasswd was given.
    if test ${enable_static_htpasswd+y}
    then :
      enableval=$enable_static_htpasswd;
    if test "$enableval" = "yes" ; then
    
      if test "x$htpasswd_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htpasswd_LTFLAGS to \"-static\""
        htpasswd_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htpasswd_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htpasswd_LTFLAGS"
            htpasswd_LTFLAGS="$htpasswd_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$htpasswd_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling htpasswd_LTFLAGS"
        htpasswd_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $htpasswd_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from htpasswd_LTFLAGS"
          htpasswd_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST htpasswd_LTFLAGS"
    
    
    
    # Check whether --enable-static-htdigest was given.
    if test ${enable_static_htdigest+y}
    then :
      enableval=$enable_static_htdigest;
    if test "$enableval" = "yes" ; then
    
      if test "x$htdigest_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htdigest_LTFLAGS to \"-static\""
        htdigest_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htdigest_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htdigest_LTFLAGS"
            htdigest_LTFLAGS="$htdigest_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$htdigest_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling htdigest_LTFLAGS"
        htdigest_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $htdigest_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from htdigest_LTFLAGS"
          htdigest_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST htdigest_LTFLAGS"
    
    
    
    # Check whether --enable-static-rotatelogs was given.
    if test ${enable_static_rotatelogs+y}
    then :
      enableval=$enable_static_rotatelogs;
    if test "$enableval" = "yes" ; then
    
      if test "x$rotatelogs_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting rotatelogs_LTFLAGS to \"-static\""
        rotatelogs_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $rotatelogs_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to rotatelogs_LTFLAGS"
            rotatelogs_LTFLAGS="$rotatelogs_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$rotatelogs_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling rotatelogs_LTFLAGS"
        rotatelogs_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $rotatelogs_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from rotatelogs_LTFLAGS"
          rotatelogs_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST rotatelogs_LTFLAGS"
    
    
    
    # Check whether --enable-static-logresolve was given.
    if test ${enable_static_logresolve+y}
    then :
      enableval=$enable_static_logresolve;
    if test "$enableval" = "yes" ; then
    
      if test "x$logresolve_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting logresolve_LTFLAGS to \"-static\""
        logresolve_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $logresolve_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to logresolve_LTFLAGS"
            logresolve_LTFLAGS="$logresolve_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$logresolve_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling logresolve_LTFLAGS"
        logresolve_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $logresolve_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from logresolve_LTFLAGS"
          logresolve_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST logresolve_LTFLAGS"
    
    
    
    # Check whether --enable-static-htdbm was given.
    if test ${enable_static_htdbm+y}
    then :
      enableval=$enable_static_htdbm;
    if test "$enableval" = "yes" ; then
    
      if test "x$htdbm_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htdbm_LTFLAGS to \"-static\""
        htdbm_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htdbm_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htdbm_LTFLAGS"
            htdbm_LTFLAGS="$htdbm_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$htdbm_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling htdbm_LTFLAGS"
        htdbm_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $htdbm_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from htdbm_LTFLAGS"
          htdbm_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST htdbm_LTFLAGS"
    
    
    
    # Check whether --enable-static-ab was given.
    if test ${enable_static_ab+y}
    then :
      enableval=$enable_static_ab;
    if test "$enableval" = "yes" ; then
    
      if test "x$ab_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_LTFLAGS to \"-static\""
        ab_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_LTFLAGS"
            ab_LTFLAGS="$ab_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$ab_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling ab_LTFLAGS"
        ab_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $ab_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from ab_LTFLAGS"
          ab_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ab_LTFLAGS"
    
    
    
    # Check whether --enable-static-checkgid was given.
    if test ${enable_static_checkgid+y}
    then :
      enableval=$enable_static_checkgid;
    if test "$enableval" = "yes" ; then
    
      if test "x$checkgid_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting checkgid_LTFLAGS to \"-static\""
        checkgid_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $checkgid_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to checkgid_LTFLAGS"
            checkgid_LTFLAGS="$checkgid_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$checkgid_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling checkgid_LTFLAGS"
        checkgid_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $checkgid_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from checkgid_LTFLAGS"
          checkgid_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST checkgid_LTFLAGS"
    
    
    
    # Check whether --enable-static-htcacheclean was given.
    if test ${enable_static_htcacheclean+y}
    then :
      enableval=$enable_static_htcacheclean;
    if test "$enableval" = "yes" ; then
    
      if test "x$htcacheclean_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting htcacheclean_LTFLAGS to \"-static\""
        htcacheclean_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $htcacheclean_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to htcacheclean_LTFLAGS"
            htcacheclean_LTFLAGS="$htcacheclean_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$htcacheclean_LTFLAGS" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling htcacheclean_LTFLAGS"
        htcacheclean_LTFLAGS=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $htcacheclean_LTFLAGS; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from htcacheclean_LTFLAGS"
          htcacheclean_LTFLAGS=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST htcacheclean_LTFLAGS"
    
    
    
    # Check whether --enable-static-httxt2dbm was given.
    if test ${enable_static_httxt2dbm+y}
    then :
      enableval=$enable_static_httxt2dbm;
    if test "$enableval" = "yes" ; then
    
      if test "x$httxt2dbm_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting httxt2dbm_LTFLAGS to \"-static\""
        httxt2dbm_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $httxt2dbm_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to httxt2dbm_LTFLAGS"
            httxt2dbm_LTFLAGS="$httxt2dbm_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$httxt2dbm" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling httxt2dbm"
        httxt2dbm=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $httxt2dbm; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from httxt2dbm"
          httxt2dbm=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST httxt2dbm_LTFLAGS"
    
    
    
    # Check whether --enable-static-fcgistarter was given.
    if test ${enable_static_fcgistarter+y}
    then :
      enableval=$enable_static_fcgistarter;
    if test "$enableval" = "yes" ; then
    
      if test "x$fcgistarter_LTFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting fcgistarter_LTFLAGS to \"-static\""
        fcgistarter_LTFLAGS="-static"
      else
        apr_addto_bugger="-static"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $fcgistarter_LTFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to fcgistarter_LTFLAGS"
            fcgistarter_LTFLAGS="$fcgistarter_LTFLAGS $i"
          fi
        done
      fi
    
    else
    
      if test "x$fcgistarter" = "x-static"; then
        test "x$silent" != "xyes" && echo "  nulling fcgistarter"
        fcgistarter=""
      else
        apr_new_bugger=""
        apr_removed=0
        for i in $fcgistarter; do
          if test "x$i" != "x-static"; then
            apr_new_bugger="$apr_new_bugger $i"
          else
            apr_removed=1
          fi
        done
        if test $apr_removed = "1"; then
          test "x$silent" != "xyes" && echo "  removed \"-static\" from fcgistarter"
          fcgistarter=$apr_new_bugger
        fi
      fi
    
    fi
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST fcgistarter_LTFLAGS"
    
    
    
    # Configure or check which of the non-portable support programs can be enabled.
    
    NONPORTABLE_SUPPORT=""
    case $host in
        *mingw*)
            ;;
        *)
            NONPORTABLE_SUPPORT="checkgid fcgistarter"
            ;;
    esac
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST NONPORTABLE_SUPPORT"
    
    
    
    # Configure the ulimit -n command used by apachectl.
    
    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 >/dev/null 2>&1; then
                APACHECTL_ULIMIT="ulimit -S -n \`ulimit -H -n\`"
            else
                APACHECTL_ULIMIT=""
            fi
            ;;
    esac
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APACHECTL_ULIMIT"
    
    
    
    
    
      current_dir=http2
      modpath_current=modules/http2
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d http2 || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    http2_objs="mod_http2.lo h2_bucket_beam.lo h2_bucket_eos.lo h2_c1.lo h2_c1_io.lo h2_c2.lo h2_c2_filter.lo h2_config.lo h2_conn_ctx.lo h2_headers.lo h2_mplx.lo h2_protocol.lo h2_push.lo h2_request.lo h2_session.lo h2_stream.lo h2_switch.lo h2_util.lo h2_workers.lo h2_ws.lo "
    
    
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_http2" >&5
    printf %s "checking whether to enable mod_http2... " >&6; }
        # Check whether --enable-http2 was given.
    if test ${enable_http2+y}
    then :
      enableval=$enable_http2; force_http2=$enableval
    else $as_nop
      enable_http2=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_http2" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_http2" = "static" -o "$enable_http2" = "shared"; then
        :
      elif test "$enable_http2" = "yes"; then
        enable_http2=$module_default
      elif test "$enable_http2" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_http2=$module_default
        else
          enable_http2=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_http2" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_http2=$module_default
        else
          enable_http2=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_http2" = "all" -o "$enable_http2" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_http2=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_http2=no
        fi
      elif test "$enable_http2" = "reallyall" -o "$enable_http2" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_http2" != "no" ; then
          enable_http2=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_http2=no
        fi
      else
        enable_http2=no
      fi
      if test "$enable_http2" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenSSL" >&5
    printf %s "checking for OpenSSL... " >&6; }
    if test ${ac_cv_openssl+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
            ac_cv_openssl=no
        ap_openssl_found=""
        ap_openssl_base=""
        ap_openssl_libs=""
        ap_openssl_mod_cflags=""
        ap_openssl_mod_ldflags=""
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided OpenSSL base directory" >&5
    printf %s "checking for user-provided OpenSSL base directory... " >&6; }
    
    # Check whether --with-ssl was given.
    if test ${with_ssl+y}
    then :
      withval=$with_ssl;
                if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                    ap_openssl_base="`cd $withval ; pwd`"
          fi
    
    fi
    
        if test "x$ap_openssl_base" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_openssl_base" >&5
    printf "%s\n" "$ap_openssl_base" >&6; }
        fi
    
            saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
            if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          if test "x$ap_openssl_base" != "x"; then
            if test -f "${ap_openssl_base}/lib/pkgconfig/openssl.pc"; then
                                  PKG_CONFIG_PATH="${ap_openssl_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_openssl_base}/lib64/pkgconfig/openssl.pc"; then
                                  PKG_CONFIG_PATH="${ap_openssl_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          # Check whether --enable-ssl-staticlib-deps was given.
    if test ${enable_ssl_staticlib_deps+y}
    then :
      enableval=$enable_ssl_staticlib_deps;
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
    
    fi
    
          ap_openssl_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors openssl`"
          if test $? -eq 0; then
            ap_openssl_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I openssl`"
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"$pkglookup\""
        CPPFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$pkglookup\""
        MOD_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ab_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_CFLAGS to \"$pkglookup\""
        ab_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_CFLAGS"
            ab_CFLAGS="$ab_CFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L openssl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other openssl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
            if test "x$ap_openssl_base" != "x" -a "x$ap_openssl_found" = "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_openssl_base/include\""
        CPPFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I$ap_openssl_base/include\""
        MOD_CFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ab_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_CFLAGS to \"-I$ap_openssl_base/include\""
        ab_CFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_CFLAGS"
            ab_CFLAGS="$ab_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_openssl_base/lib\""
        LDFLAGS="-L$ap_openssl_base/lib"
      else
        apr_addto_bugger="-L$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"-L$ap_openssl_base/lib\""
        MOD_LDFLAGS="-L$ap_openssl_base/lib"
      else
        apr_addto_bugger="-L$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_openssl_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_platform_runtime_link_flag$ap_openssl_base/lib\""
        MOD_LDFLAGS="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
        fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenSSL version >= 0.9.8a" >&5
    printf %s "checking for OpenSSL version >= 0.9.8a... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <openssl/opensslv.h>
    int
    main (void)
    {
    
    #if !defined(OPENSSL_VERSION_NUMBER)
    #error "Missing OpenSSL version"
    #endif
    #if OPENSSL_VERSION_NUMBER < 0x0090801f
    #error "Unsupported OpenSSL version " OPENSSL_VERSION_TEXT
    #endif
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: OK" >&5
    printf "%s\n" "OK" >&6; }
           ac_cv_openssl=yes
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FAILED" >&5
    printf "%s\n" "FAILED" >&6; }
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
        if test "x$ac_cv_openssl" = "xyes"; then
          ap_openssl_libs="${ap_openssl_libs:--lssl -lcrypto} `$apr_config --libs`"
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_openssl_libs\""
        MOD_LDFLAGS="$ap_openssl_libs"
      else
        apr_addto_bugger="$ap_openssl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_openssl_libs\""
        LIBS="$ap_openssl_libs"
      else
        apr_addto_bugger="$ap_openssl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
    
      test "x$silent" != "xyes" && echo "  forcing ab_LIBS to \"$MOD_LDFLAGS\""
      ab_LIBS="$MOD_LDFLAGS"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ab_CFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ab_LIBS"
    
    
    
                liberrors=""
          ac_fn_c_check_header_compile "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default"
    if test "x$ac_cv_header_openssl_engine_h" = xyes
    then :
      printf "%s\n" "#define HAVE_OPENSSL_ENGINE_H 1" >>confdefs.h
    
    fi
    
    
      for ac_func in SSL_CTX_new
    do :
      ac_fn_c_check_func "$LINENO" "SSL_CTX_new" "ac_cv_func_SSL_CTX_new"
    if test "x$ac_cv_func_SSL_CTX_new" = xyes
    then :
      printf "%s\n" "#define HAVE_SSL_CTX_NEW 1" >>confdefs.h
    
    else $as_nop
      liberrors="yes"
    fi
    
    done
          ac_fn_c_check_func "$LINENO" "OPENSSL_init_ssl" "ac_cv_func_OPENSSL_init_ssl"
    if test "x$ac_cv_func_OPENSSL_init_ssl" = xyes
    then :
      printf "%s\n" "#define HAVE_OPENSSL_INIT_SSL 1" >>confdefs.h
    
    fi
    
          ac_fn_c_check_func "$LINENO" "ENGINE_init" "ac_cv_func_ENGINE_init"
    if test "x$ac_cv_func_ENGINE_init" = xyes
    then :
      printf "%s\n" "#define HAVE_ENGINE_INIT 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "ENGINE_load_builtin_engines" "ac_cv_func_ENGINE_load_builtin_engines"
    if test "x$ac_cv_func_ENGINE_load_builtin_engines" = xyes
    then :
      printf "%s\n" "#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "RAND_egd" "ac_cv_func_RAND_egd"
    if test "x$ac_cv_func_RAND_egd" = xyes
    then :
      printf "%s\n" "#define HAVE_RAND_EGD 1" >>confdefs.h
    
    fi
    
          if test "x$liberrors" != "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSL libraries are unusable" >&5
    printf "%s\n" "$as_me: WARNING: OpenSSL libraries are unusable" >&2;}
          fi
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSL version is too old" >&5
    printf "%s\n" "$as_me: WARNING: OpenSSL version is too old" >&2;}
        fi
    
            CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
            ap_openssl_mod_cflags=$MOD_CFLAGS
        ap_openssl_mod_ldflags=$MOD_LDFLAGS
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_openssl" >&5
    printf "%s\n" "$ac_cv_openssl" >&6; }
      if test "x$ac_cv_openssl" = "xyes"; then
    
    printf "%s\n" "#define HAVE_OPENSSL 1" >>confdefs.h
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_openssl_mod_ldflags\""
        MOD_LDFLAGS="$ap_openssl_mod_ldflags"
      else
        apr_addto_bugger="$ap_openssl_mod_ldflags"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$ap_openssl_mod_cflags\""
        MOD_CFLAGS="$ap_openssl_mod_cflags"
      else
        apr_addto_bugger="$ap_openssl_mod_cflags"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
      fi
    
        if test "$ac_cv_openssl" = "yes" ; then
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_OPENSSL"\""
        MOD_CPPFLAGS=""-DH2_OPENSSL""
      else
        apr_addto_bugger=""-DH2_OPENSSL""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
        fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for nghttp2" >&5
    printf %s "checking for nghttp2... " >&6; }
    if test ${ac_cv_nghttp2+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
            ac_cv_nghttp2=no
        ap_nghttp2_found=""
        ap_nghttp2_base=""
        ap_nghttp2_libs=""
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided nghttp2 base directory" >&5
    printf %s "checking for user-provided nghttp2 base directory... " >&6; }
    
    # Check whether --with-nghttp2 was given.
    if test ${with_nghttp2+y}
    then :
      withval=$with_nghttp2;
                if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                    ap_nghttp2_base="`cd $withval ; pwd`"
          fi
    
    fi
    
        if test "x$ap_nghttp2_base" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_nghttp2_base" >&5
    printf "%s\n" "$ap_nghttp2_base" >&6; }
        fi
    
            saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
            if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pkg-config along $PKG_CONFIG_PATH" >&5
    printf %s "checking for pkg-config along $PKG_CONFIG_PATH... " >&6; }
          if test "x$ap_nghttp2_base" != "x" ; then
            if test -f "${ap_nghttp2_base}/lib/pkgconfig/libnghttp2.pc"; then
                                  PKG_CONFIG_PATH="${ap_nghttp2_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_nghttp2_base}/lib64/pkgconfig/libnghttp2.pc"; then
                                  PKG_CONFIG_PATH="${ap_nghttp2_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          # Check whether --enable-nghttp2-staticlib-deps was given.
    if test ${enable_nghttp2_staticlib_deps+y}
    then :
      enableval=$enable_nghttp2_staticlib_deps;
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
    
    fi
    
          ap_nghttp2_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libnghttp2`"
          if test $? -eq 0; then
            ap_nghttp2_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I libnghttp2`"
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"$pkglookup\""
        CPPFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$pkglookup\""
        MOD_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libnghttp2`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libnghttp2`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
            if test "x$ap_nghttp2_base" != "x" -a "x$ap_nghttp2_found" = "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_nghttp2_base/include\""
        CPPFLAGS="-I$ap_nghttp2_base/include"
      else
        apr_addto_bugger="-I$ap_nghttp2_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I$ap_nghttp2_base/include\""
        MOD_CFLAGS="-I$ap_nghttp2_base/include"
      else
        apr_addto_bugger="-I$ap_nghttp2_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_nghttp2_base/lib\""
        LDFLAGS="-L$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="-L$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"-L$ap_nghttp2_base/lib\""
        MOD_LDFLAGS="-L$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="-L$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_nghttp2_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_platform_runtime_link_flag$ap_nghttp2_base/lib\""
        MOD_LDFLAGS="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
        fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for nghttp2 version >= 1.2.1" >&5
    printf %s "checking for nghttp2 version >= 1.2.1... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <nghttp2/nghttp2ver.h>
    int
    main (void)
    {
    
    #if !defined(NGHTTP2_VERSION_NUM)
    #error "Missing nghttp2 version"
    #endif
    #if NGHTTP2_VERSION_NUM < 0x010201
    #error "Unsupported nghttp2 version " NGHTTP2_VERSION_TEXT
    #endif
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: OK" >&5
    printf "%s\n" "OK" >&6; }
           ac_cv_nghttp2=yes
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FAILED" >&5
    printf "%s\n" "FAILED" >&6; }
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
        if test "x$ac_cv_nghttp2" = "xyes"; then
          ap_nghttp2_libs="${ap_nghttp2_libs:--lnghttp2} `$apr_config --libs`"
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_nghttp2_libs\""
        MOD_LDFLAGS="$ap_nghttp2_libs"
      else
        apr_addto_bugger="$ap_nghttp2_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_nghttp2_libs\""
        LIBS="$ap_nghttp2_libs"
      else
        apr_addto_bugger="$ap_nghttp2_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
    
                liberrors=""
          ac_fn_c_check_header_compile "$LINENO" "nghttp2/nghttp2.h" "ac_cv_header_nghttp2_nghttp2_h" "$ac_includes_default"
    if test "x$ac_cv_header_nghttp2_nghttp2_h" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_NGHTTP2_H 1" >>confdefs.h
    
    fi
    
    
      for ac_func in nghttp2_session_server_new2
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_server_new2" "ac_cv_func_nghttp2_session_server_new2"
    if test "x$ac_cv_func_nghttp2_session_server_new2" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_SERVER_NEW2 1" >>confdefs.h
    
    else $as_nop
      liberrors="yes"
    fi
    
    done
          if test "x$liberrors" != "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: nghttp2 library is unusable" >&5
    printf "%s\n" "$as_me: WARNING: nghttp2 library is unusable" >&2;}
          fi
    
      for ac_func in nghttp2_stream_get_weight
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_stream_get_weight" "ac_cv_func_nghttp2_stream_get_weight"
    if test "x$ac_cv_func_nghttp2_stream_get_weight" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_STREAM_GET_WEIGHT 1" >>confdefs.h
    
    else $as_nop
      liberrors="yes"
    fi
    
    done
          if test "x$liberrors" != "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: nghttp2 version >= 1.3.0 is required" >&5
    printf "%s\n" "$as_me: WARNING: nghttp2 version >= 1.3.0 is required" >&2;}
          fi
    
      for ac_func in nghttp2_session_change_stream_priority
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_change_stream_priority" "ac_cv_func_nghttp2_session_change_stream_priority"
    if test "x$ac_cv_func_nghttp2_session_change_stream_priority" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_CHANGE_STREAM_PRIORITY 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_CHANGE_PRIO"\""
        MOD_CPPFLAGS=""-DH2_NG2_CHANGE_PRIO""
      else
        apr_addto_bugger=""-DH2_NG2_CHANGE_PRIO""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_session_callbacks_set_on_invalid_header_callback
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_callbacks_set_on_invalid_header_callback" "ac_cv_func_nghttp2_session_callbacks_set_on_invalid_header_callback"
    if test "x$ac_cv_func_nghttp2_session_callbacks_set_on_invalid_header_callback" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_CALLBACKS_SET_ON_INVALID_HEADER_CALLBACK 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_INVALID_HEADER_CB"\""
        MOD_CPPFLAGS=""-DH2_NG2_INVALID_HEADER_CB""
      else
        apr_addto_bugger=""-DH2_NG2_INVALID_HEADER_CB""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_session_get_stream_local_window_size
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_get_stream_local_window_size" "ac_cv_func_nghttp2_session_get_stream_local_window_size"
    if test "x$ac_cv_func_nghttp2_session_get_stream_local_window_size" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_GET_STREAM_LOCAL_WINDOW_SIZE 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_LOCAL_WIN_SIZE"\""
        MOD_CPPFLAGS=""-DH2_NG2_LOCAL_WIN_SIZE""
      else
        apr_addto_bugger=""-DH2_NG2_LOCAL_WIN_SIZE""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_option_set_no_closed_streams
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_option_set_no_closed_streams" "ac_cv_func_nghttp2_option_set_no_closed_streams"
    if test "x$ac_cv_func_nghttp2_option_set_no_closed_streams" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_OPTION_SET_NO_CLOSED_STREAMS 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_NO_CLOSED_STREAMS"\""
        MOD_CPPFLAGS=""-DH2_NG2_NO_CLOSED_STREAMS""
      else
        apr_addto_bugger=""-DH2_NG2_NO_CLOSED_STREAMS""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation" "ac_cv_func_nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation"
    if test "x$ac_cv_func_nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_OPTION_SET_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_RFC9113_STRICTNESS"\""
        MOD_CPPFLAGS=""-DH2_NG2_RFC9113_STRICTNESS""
      else
        apr_addto_bugger=""-DH2_NG2_RFC9113_STRICTNESS""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: nghttp2 version is too old" >&5
    printf "%s\n" "$as_me: WARNING: nghttp2 version is too old" >&2;}
        fi
    
            CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_nghttp2" >&5
    printf "%s\n" "$ac_cv_nghttp2" >&6; }
      if test "x$ac_cv_nghttp2" = "xyes"; then
    
    printf "%s\n" "#define HAVE_NGHTTP2 1" >>confdefs.h
    
      fi
    
        if test "$ac_cv_nghttp2" = "yes" ; then
            if test "x$enable_http2" = "xshared"; then
               # The only symbol which needs to be exported is the module
               # structure, so ask libtool to hide everything else:
    
      if test "x$MOD_HTTP2_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_HTTP2_LDADD to \"-export-symbols-regex http2_module\""
        MOD_HTTP2_LDADD="-export-symbols-regex http2_module"
      else
        apr_addto_bugger="-export-symbols-regex http2_module"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_HTTP2_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_HTTP2_LDADD"
            MOD_HTTP2_LDADD="$MOD_HTTP2_LDADD $i"
          fi
        done
      fi
    
            fi
        else
            enable_http2=no
        fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_http2" >&5
    printf %s "checking whether to enable mod_http2... " >&6; }
                if test "$enable_http2" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_http2 has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_http2$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_http2$_apmod_extra_msg" >&6; }
      if test "$enable_http2" != "no"; then
        case "$enable_http2" in
        static*)
          MODLIST="$MODLIST http2"
          if test "http2" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES http2"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},http2"
          fi
          ;;
        esac
    
    
      if test -z "$http2_objs"; then
        objects="mod_http2.lo"
      else
        objects="$http2_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_http2.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_HTTP2_LDADD)
    EOF
          if test ! -z "\$(MOD_HTTP2_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_HTTP2_LDADD)\""
        AP_LIBS="\$(MOD_HTTP2_LDADD)"
      else
        apr_addto_bugger="\$(MOD_HTTP2_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_http2.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  $objects \$(MOD_HTTP2_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_HTTP2_LDADD"
    
    
    
      fi
    
    
    # Ensure that other modules can pick up mod_http2.h
    # icing: hold back for now until it is more stable
    #APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
    
    
    
    proxy_http2_objs="mod_proxy_http2.lo h2_proxy_session.lo h2_proxy_util.lo "
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_http2" >&5
    printf %s "checking whether to enable mod_proxy_http2... " >&6; }
        # Check whether --enable-proxy-http2 was given.
    if test ${enable_proxy_http2+y}
    then :
      enableval=$enable_proxy_http2; force_proxy_http2=$enableval
    else $as_nop
      enable_proxy_http2=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_proxy_http2" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_proxy_http2" = "static" -o "$enable_proxy_http2" = "shared"; then
        :
      elif test "$enable_proxy_http2" = "yes"; then
        enable_proxy_http2=$module_default
      elif test "$enable_proxy_http2" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_http2=$module_default
        else
          enable_proxy_http2=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_http2" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_proxy_http2=$module_default
        else
          enable_proxy_http2=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_proxy_http2" = "all" -o "$enable_proxy_http2" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_proxy_http2=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_http2=no
        fi
      elif test "$enable_proxy_http2" = "reallyall" -o "$enable_proxy_http2" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_proxy_http2" != "no" ; then
          enable_proxy_http2=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_proxy_http2=no
        fi
      else
        enable_proxy_http2=no
      fi
      if test "$enable_proxy_http2" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy" = "no" ; then
                                  enable_proxy_http2=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy is disabled but required for mod_proxy_http2\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy is disabled but required for mod_proxy_http2\"" >&2;}
                                elif test "$enable_proxy_http2" = "static" && test "$enable_proxy" != "static" ; then
                                  enable_proxy_http2=$enable_proxy
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_proxy_http2 shared because mod_proxy is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_proxy_http2 shared because mod_proxy is built shared\"" >&2;}
                                else
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for nghttp2" >&5
    printf %s "checking for nghttp2... " >&6; }
    if test ${ac_cv_nghttp2+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
            ac_cv_nghttp2=no
        ap_nghttp2_found=""
        ap_nghttp2_base=""
        ap_nghttp2_libs=""
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided nghttp2 base directory" >&5
    printf %s "checking for user-provided nghttp2 base directory... " >&6; }
    
    # Check whether --with-nghttp2 was given.
    if test ${with_nghttp2+y}
    then :
      withval=$with_nghttp2;
                if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                    ap_nghttp2_base="`cd $withval ; pwd`"
          fi
    
    fi
    
        if test "x$ap_nghttp2_base" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_nghttp2_base" >&5
    printf "%s\n" "$ap_nghttp2_base" >&6; }
        fi
    
            saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
            if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pkg-config along $PKG_CONFIG_PATH" >&5
    printf %s "checking for pkg-config along $PKG_CONFIG_PATH... " >&6; }
          if test "x$ap_nghttp2_base" != "x" ; then
            if test -f "${ap_nghttp2_base}/lib/pkgconfig/libnghttp2.pc"; then
                                  PKG_CONFIG_PATH="${ap_nghttp2_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_nghttp2_base}/lib64/pkgconfig/libnghttp2.pc"; then
                                  PKG_CONFIG_PATH="${ap_nghttp2_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          # Check whether --enable-nghttp2-staticlib-deps was given.
    if test ${enable_nghttp2_staticlib_deps+y}
    then :
      enableval=$enable_nghttp2_staticlib_deps;
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
    
    fi
    
          ap_nghttp2_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libnghttp2`"
          if test $? -eq 0; then
            ap_nghttp2_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I libnghttp2`"
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"$pkglookup\""
        CPPFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$pkglookup\""
        MOD_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libnghttp2`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libnghttp2`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
            if test "x$ap_nghttp2_base" != "x" -a "x$ap_nghttp2_found" = "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_nghttp2_base/include\""
        CPPFLAGS="-I$ap_nghttp2_base/include"
      else
        apr_addto_bugger="-I$ap_nghttp2_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I$ap_nghttp2_base/include\""
        MOD_CFLAGS="-I$ap_nghttp2_base/include"
      else
        apr_addto_bugger="-I$ap_nghttp2_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_nghttp2_base/lib\""
        LDFLAGS="-L$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="-L$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"-L$ap_nghttp2_base/lib\""
        MOD_LDFLAGS="-L$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="-L$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_nghttp2_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_platform_runtime_link_flag$ap_nghttp2_base/lib\""
        MOD_LDFLAGS="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_nghttp2_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
        fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for nghttp2 version >= 1.2.1" >&5
    printf %s "checking for nghttp2 version >= 1.2.1... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <nghttp2/nghttp2ver.h>
    int
    main (void)
    {
    
    #if !defined(NGHTTP2_VERSION_NUM)
    #error "Missing nghttp2 version"
    #endif
    #if NGHTTP2_VERSION_NUM < 0x010201
    #error "Unsupported nghttp2 version " NGHTTP2_VERSION_TEXT
    #endif
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: OK" >&5
    printf "%s\n" "OK" >&6; }
           ac_cv_nghttp2=yes
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FAILED" >&5
    printf "%s\n" "FAILED" >&6; }
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
        if test "x$ac_cv_nghttp2" = "xyes"; then
          ap_nghttp2_libs="${ap_nghttp2_libs:--lnghttp2} `$apr_config --libs`"
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_nghttp2_libs\""
        MOD_LDFLAGS="$ap_nghttp2_libs"
      else
        apr_addto_bugger="$ap_nghttp2_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_nghttp2_libs\""
        LIBS="$ap_nghttp2_libs"
      else
        apr_addto_bugger="$ap_nghttp2_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
    
                liberrors=""
          ac_fn_c_check_header_compile "$LINENO" "nghttp2/nghttp2.h" "ac_cv_header_nghttp2_nghttp2_h" "$ac_includes_default"
    if test "x$ac_cv_header_nghttp2_nghttp2_h" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_NGHTTP2_H 1" >>confdefs.h
    
    fi
    
    
      for ac_func in nghttp2_session_server_new2
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_server_new2" "ac_cv_func_nghttp2_session_server_new2"
    if test "x$ac_cv_func_nghttp2_session_server_new2" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_SERVER_NEW2 1" >>confdefs.h
    
    else $as_nop
      liberrors="yes"
    fi
    
    done
          if test "x$liberrors" != "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: nghttp2 library is unusable" >&5
    printf "%s\n" "$as_me: WARNING: nghttp2 library is unusable" >&2;}
          fi
    
      for ac_func in nghttp2_stream_get_weight
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_stream_get_weight" "ac_cv_func_nghttp2_stream_get_weight"
    if test "x$ac_cv_func_nghttp2_stream_get_weight" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_STREAM_GET_WEIGHT 1" >>confdefs.h
    
    else $as_nop
      liberrors="yes"
    fi
    
    done
          if test "x$liberrors" != "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: nghttp2 version >= 1.3.0 is required" >&5
    printf "%s\n" "$as_me: WARNING: nghttp2 version >= 1.3.0 is required" >&2;}
          fi
    
      for ac_func in nghttp2_session_change_stream_priority
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_change_stream_priority" "ac_cv_func_nghttp2_session_change_stream_priority"
    if test "x$ac_cv_func_nghttp2_session_change_stream_priority" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_CHANGE_STREAM_PRIORITY 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_CHANGE_PRIO"\""
        MOD_CPPFLAGS=""-DH2_NG2_CHANGE_PRIO""
      else
        apr_addto_bugger=""-DH2_NG2_CHANGE_PRIO""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_session_callbacks_set_on_invalid_header_callback
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_callbacks_set_on_invalid_header_callback" "ac_cv_func_nghttp2_session_callbacks_set_on_invalid_header_callback"
    if test "x$ac_cv_func_nghttp2_session_callbacks_set_on_invalid_header_callback" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_CALLBACKS_SET_ON_INVALID_HEADER_CALLBACK 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_INVALID_HEADER_CB"\""
        MOD_CPPFLAGS=""-DH2_NG2_INVALID_HEADER_CB""
      else
        apr_addto_bugger=""-DH2_NG2_INVALID_HEADER_CB""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_session_get_stream_local_window_size
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_session_get_stream_local_window_size" "ac_cv_func_nghttp2_session_get_stream_local_window_size"
    if test "x$ac_cv_func_nghttp2_session_get_stream_local_window_size" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_SESSION_GET_STREAM_LOCAL_WINDOW_SIZE 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_LOCAL_WIN_SIZE"\""
        MOD_CPPFLAGS=""-DH2_NG2_LOCAL_WIN_SIZE""
      else
        apr_addto_bugger=""-DH2_NG2_LOCAL_WIN_SIZE""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_option_set_no_closed_streams
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_option_set_no_closed_streams" "ac_cv_func_nghttp2_option_set_no_closed_streams"
    if test "x$ac_cv_func_nghttp2_option_set_no_closed_streams" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_OPTION_SET_NO_CLOSED_STREAMS 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_NO_CLOSED_STREAMS"\""
        MOD_CPPFLAGS=""-DH2_NG2_NO_CLOSED_STREAMS""
      else
        apr_addto_bugger=""-DH2_NG2_NO_CLOSED_STREAMS""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
      for ac_func in nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation
    do :
      ac_fn_c_check_func "$LINENO" "nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation" "ac_cv_func_nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation"
    if test "x$ac_cv_func_nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation" = xyes
    then :
      printf "%s\n" "#define HAVE_NGHTTP2_OPTION_SET_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DH2_NG2_RFC9113_STRICTNESS"\""
        MOD_CPPFLAGS=""-DH2_NG2_RFC9113_STRICTNESS""
      else
        apr_addto_bugger=""-DH2_NG2_RFC9113_STRICTNESS""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: nghttp2 version is too old" >&5
    printf "%s\n" "$as_me: WARNING: nghttp2 version is too old" >&2;}
        fi
    
            CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_nghttp2" >&5
    printf "%s\n" "$ac_cv_nghttp2" >&6; }
      if test "x$ac_cv_nghttp2" = "xyes"; then
    
    printf "%s\n" "#define HAVE_NGHTTP2 1" >>confdefs.h
    
      fi
    
        if test "$ac_cv_nghttp2" = "yes" ; then
            if test "x$enable_http2" = "xshared"; then
               # The only symbol which needs to be exported is the module
               # structure, so ask libtool to hide everything else:
    
      if test "x$MOD_PROXY_HTTP2_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_PROXY_HTTP2_LDADD to \"-export-symbols-regex proxy_http2_module\""
        MOD_PROXY_HTTP2_LDADD="-export-symbols-regex proxy_http2_module"
      else
        apr_addto_bugger="-export-symbols-regex proxy_http2_module"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_PROXY_HTTP2_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_PROXY_HTTP2_LDADD"
            MOD_PROXY_HTTP2_LDADD="$MOD_PROXY_HTTP2_LDADD $i"
          fi
        done
      fi
    
            fi
        else
            enable_proxy_http2=no
        fi
    
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_proxy_http2" >&5
    printf %s "checking whether to enable mod_proxy_http2... " >&6; }
                if test "$enable_proxy_http2" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_proxy_http2 has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_proxy_http2$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_proxy_http2$_apmod_extra_msg" >&6; }
      if test "$enable_proxy_http2" != "no"; then
        case "$enable_proxy_http2" in
        static*)
          MODLIST="$MODLIST proxy_http2"
          if test "proxy_http2" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES proxy_http2"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},proxy_http2"
          fi
          ;;
        esac
    
    
      if test -z "$proxy_http2_objs"; then
        objects="mod_proxy_http2.lo"
      else
        objects="$proxy_http2_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_proxy_http2.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PROXY_HTTP2_LDADD)
    EOF
          if test ! -z "\$(MOD_PROXY_HTTP2_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PROXY_HTTP2_LDADD)\""
        AP_LIBS="\$(MOD_PROXY_HTTP2_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PROXY_HTTP2_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_proxy_http2.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  $objects \$(MOD_PROXY_HTTP2_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PROXY_HTTP2_LDADD"
    
    
    
      fi
    
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
    
    
    
    
    
    
      current_dir=md
      modpath_current=modules/md
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d md || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    md_objs="md_acme.lo md_acme_acct.lo md_acme_authz.lo md_acme_drive.lo md_acmev2_drive.lo md_acme_order.lo md_core.lo md_curl.lo md_crypt.lo md_event.lo md_http.lo md_json.lo md_jws.lo md_log.lo md_ocsp.lo md_result.lo md_reg.lo md_status.lo md_store.lo md_store_fs.lo md_tailscale.lo md_time.lo md_util.lo mod_md.lo mod_md_config.lo mod_md_drive.lo mod_md_ocsp.lo mod_md_os.lo mod_md_status.lo "
    
    # Ensure that other modules can pick up mod_md.h
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_md" >&5
    printf %s "checking whether to enable mod_md... " >&6; }
        # Check whether --enable-md was given.
    if test ${enable_md+y}
    then :
      enableval=$enable_md; force_md=$enableval
    else $as_nop
      enable_md=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_md" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_md" = "static" -o "$enable_md" = "shared"; then
        :
      elif test "$enable_md" = "yes"; then
        enable_md=$module_default
      elif test "$enable_md" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_md=$module_default
        else
          enable_md=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_md" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_md=$module_default
        else
          enable_md=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_md" = "all" -o "$enable_md" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_md=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_md=no
        fi
      elif test "$enable_md" = "reallyall" -o "$enable_md" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_md" != "no" ; then
          enable_md=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_md=no
        fi
      else
        enable_md=no
      fi
      if test "$enable_md" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenSSL" >&5
    printf %s "checking for OpenSSL... " >&6; }
    if test ${ac_cv_openssl+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
            ac_cv_openssl=no
        ap_openssl_found=""
        ap_openssl_base=""
        ap_openssl_libs=""
        ap_openssl_mod_cflags=""
        ap_openssl_mod_ldflags=""
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided OpenSSL base directory" >&5
    printf %s "checking for user-provided OpenSSL base directory... " >&6; }
    
    # Check whether --with-ssl was given.
    if test ${with_ssl+y}
    then :
      withval=$with_ssl;
                if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                    ap_openssl_base="`cd $withval ; pwd`"
          fi
    
    fi
    
        if test "x$ap_openssl_base" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_openssl_base" >&5
    printf "%s\n" "$ap_openssl_base" >&6; }
        fi
    
            saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
            if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          if test "x$ap_openssl_base" != "x"; then
            if test -f "${ap_openssl_base}/lib/pkgconfig/openssl.pc"; then
                                  PKG_CONFIG_PATH="${ap_openssl_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_openssl_base}/lib64/pkgconfig/openssl.pc"; then
                                  PKG_CONFIG_PATH="${ap_openssl_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          # Check whether --enable-ssl-staticlib-deps was given.
    if test ${enable_ssl_staticlib_deps+y}
    then :
      enableval=$enable_ssl_staticlib_deps;
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
    
    fi
    
          ap_openssl_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors openssl`"
          if test $? -eq 0; then
            ap_openssl_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I openssl`"
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"$pkglookup\""
        CPPFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$pkglookup\""
        MOD_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ab_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_CFLAGS to \"$pkglookup\""
        ab_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_CFLAGS"
            ab_CFLAGS="$ab_CFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L openssl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other openssl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
            if test "x$ap_openssl_base" != "x" -a "x$ap_openssl_found" = "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_openssl_base/include\""
        CPPFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I$ap_openssl_base/include\""
        MOD_CFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$ab_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting ab_CFLAGS to \"-I$ap_openssl_base/include\""
        ab_CFLAGS="-I$ap_openssl_base/include"
      else
        apr_addto_bugger="-I$ap_openssl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $ab_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to ab_CFLAGS"
            ab_CFLAGS="$ab_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_openssl_base/lib\""
        LDFLAGS="-L$ap_openssl_base/lib"
      else
        apr_addto_bugger="-L$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"-L$ap_openssl_base/lib\""
        MOD_LDFLAGS="-L$ap_openssl_base/lib"
      else
        apr_addto_bugger="-L$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_openssl_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_platform_runtime_link_flag$ap_openssl_base/lib\""
        MOD_LDFLAGS="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_openssl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
        fi
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenSSL version >= 0.9.8a" >&5
    printf %s "checking for OpenSSL version >= 0.9.8a... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <openssl/opensslv.h>
    int
    main (void)
    {
    
    #if !defined(OPENSSL_VERSION_NUMBER)
    #error "Missing OpenSSL version"
    #endif
    #if OPENSSL_VERSION_NUMBER < 0x0090801f
    #error "Unsupported OpenSSL version " OPENSSL_VERSION_TEXT
    #endif
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: OK" >&5
    printf "%s\n" "OK" >&6; }
           ac_cv_openssl=yes
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FAILED" >&5
    printf "%s\n" "FAILED" >&6; }
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
        if test "x$ac_cv_openssl" = "xyes"; then
          ap_openssl_libs="${ap_openssl_libs:--lssl -lcrypto} `$apr_config --libs`"
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_openssl_libs\""
        MOD_LDFLAGS="$ap_openssl_libs"
      else
        apr_addto_bugger="$ap_openssl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_openssl_libs\""
        LIBS="$ap_openssl_libs"
      else
        apr_addto_bugger="$ap_openssl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
    
      test "x$silent" != "xyes" && echo "  forcing ab_LIBS to \"$MOD_LDFLAGS\""
      ab_LIBS="$MOD_LDFLAGS"
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ab_CFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ab_LIBS"
    
    
    
                liberrors=""
          ac_fn_c_check_header_compile "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default"
    if test "x$ac_cv_header_openssl_engine_h" = xyes
    then :
      printf "%s\n" "#define HAVE_OPENSSL_ENGINE_H 1" >>confdefs.h
    
    fi
    
    
      for ac_func in SSL_CTX_new
    do :
      ac_fn_c_check_func "$LINENO" "SSL_CTX_new" "ac_cv_func_SSL_CTX_new"
    if test "x$ac_cv_func_SSL_CTX_new" = xyes
    then :
      printf "%s\n" "#define HAVE_SSL_CTX_NEW 1" >>confdefs.h
    
    else $as_nop
      liberrors="yes"
    fi
    
    done
          ac_fn_c_check_func "$LINENO" "OPENSSL_init_ssl" "ac_cv_func_OPENSSL_init_ssl"
    if test "x$ac_cv_func_OPENSSL_init_ssl" = xyes
    then :
      printf "%s\n" "#define HAVE_OPENSSL_INIT_SSL 1" >>confdefs.h
    
    fi
    
          ac_fn_c_check_func "$LINENO" "ENGINE_init" "ac_cv_func_ENGINE_init"
    if test "x$ac_cv_func_ENGINE_init" = xyes
    then :
      printf "%s\n" "#define HAVE_ENGINE_INIT 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "ENGINE_load_builtin_engines" "ac_cv_func_ENGINE_load_builtin_engines"
    if test "x$ac_cv_func_ENGINE_load_builtin_engines" = xyes
    then :
      printf "%s\n" "#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1" >>confdefs.h
    
    fi
    ac_fn_c_check_func "$LINENO" "RAND_egd" "ac_cv_func_RAND_egd"
    if test "x$ac_cv_func_RAND_egd" = xyes
    then :
      printf "%s\n" "#define HAVE_RAND_EGD 1" >>confdefs.h
    
    fi
    
          if test "x$liberrors" != "x"; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSL libraries are unusable" >&5
    printf "%s\n" "$as_me: WARNING: OpenSSL libraries are unusable" >&2;}
          fi
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSL version is too old" >&5
    printf "%s\n" "$as_me: WARNING: OpenSSL version is too old" >&2;}
        fi
    
            CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
            ap_openssl_mod_cflags=$MOD_CFLAGS
        ap_openssl_mod_ldflags=$MOD_LDFLAGS
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_openssl" >&5
    printf "%s\n" "$ac_cv_openssl" >&6; }
      if test "x$ac_cv_openssl" = "xyes"; then
    
    printf "%s\n" "#define HAVE_OPENSSL 1" >>confdefs.h
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_openssl_mod_ldflags\""
        MOD_LDFLAGS="$ap_openssl_mod_ldflags"
      else
        apr_addto_bugger="$ap_openssl_mod_ldflags"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$ap_openssl_mod_cflags\""
        MOD_CFLAGS="$ap_openssl_mod_cflags"
      else
        apr_addto_bugger="$ap_openssl_mod_cflags"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
      fi
    
        if test "x$ac_cv_openssl" = "xno" ; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libssl (or compatible) not found" >&5
    printf "%s\n" "$as_me: WARNING: libssl (or compatible) not found" >&2;}
            enable_md=no
        fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for jansson" >&5
    printf %s "checking for jansson... " >&6; }
    if test ${ac_cv_jansson+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
            ac_cv_jansson=no
        ap_jansson_found=""
        ap_jansson_base=""
        ap_jansson_libs=""
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided jansson base directory" >&5
    printf %s "checking for user-provided jansson base directory... " >&6; }
    
    # Check whether --with-jansson was given.
    if test ${with_jansson+y}
    then :
      withval=$with_jansson;
                if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                    ap_jansson_base="`cd $withval ; pwd`"
          fi
    
    fi
    
        if test "x$ap_jansson_base" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_jansson_base" >&5
    printf "%s\n" "$ap_jansson_base" >&6; }
        fi
    
            saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
            if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pkg-config along $PKG_CONFIG_PATH" >&5
    printf %s "checking for pkg-config along $PKG_CONFIG_PATH... " >&6; }
          if test "x$ap_jansson_base" != "x" ; then
            if test -f "${ap_jansson_base}/lib/pkgconfig/libjansson.pc"; then
                                  PKG_CONFIG_PATH="${ap_jansson_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_jansson_base}/lib64/pkgconfig/libjansson.pc"; then
                                  PKG_CONFIG_PATH="${ap_jansson_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          # Check whether --enable-jansson-staticlib-deps was given.
    if test ${enable_jansson_staticlib_deps+y}
    then :
      enableval=$enable_jansson_staticlib_deps;
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
    
    fi
    
          ap_jansson_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libjansson`"
          if test $? -eq 0; then
            ap_jansson_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I libjansson`"
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"$pkglookup\""
        CPPFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$pkglookup\""
        MOD_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libjansson`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libjansson`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
            if test "x$ap_jansson_base" != "x" -a "x$ap_jansson_found" = "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_jansson_base/include\""
        CPPFLAGS="-I$ap_jansson_base/include"
      else
        apr_addto_bugger="-I$ap_jansson_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I$ap_jansson_base/include\""
        MOD_CFLAGS="-I$ap_jansson_base/include"
      else
        apr_addto_bugger="-I$ap_jansson_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_jansson_base/lib\""
        LDFLAGS="-L$ap_jansson_base/lib"
      else
        apr_addto_bugger="-L$ap_jansson_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"-L$ap_jansson_base/lib\""
        MOD_LDFLAGS="-L$ap_jansson_base/lib"
      else
        apr_addto_bugger="-L$ap_jansson_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_jansson_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_jansson_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_jansson_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_platform_runtime_link_flag$ap_jansson_base/lib\""
        MOD_LDFLAGS="$ap_platform_runtime_link_flag$ap_jansson_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_jansson_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
        fi
    
        # attempts to include jansson.h fail me. So lets make sure we can at least
        # include its other header file
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <jansson_config.h>
    int
    main (void)
    {
    
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: OK" >&5
    printf "%s\n" "OK" >&6; }
           ac_cv_jansson=yes
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FAILED" >&5
    printf "%s\n" "FAILED" >&6; }
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
        if test "x$ac_cv_jansson" = "xyes"; then
          ap_jansson_libs="${ap_jansson_libs:--ljansson} `$apr_config --libs`"
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_jansson_libs\""
        MOD_LDFLAGS="$ap_jansson_libs"
      else
        apr_addto_bugger="$ap_jansson_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_jansson_libs\""
        LIBS="$ap_jansson_libs"
      else
        apr_addto_bugger="$ap_jansson_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
        fi
    
            CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_jansson" >&5
    printf "%s\n" "$ac_cv_jansson" >&6; }
      if test "x$ac_cv_jansson" = "xyes"; then
    
    printf "%s\n" "#define HAVE_JANSSON 1" >>confdefs.h
    
      fi
    
        if test "x$ac_cv_jansson" != "xyes" ; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libjansson not found" >&5
    printf "%s\n" "$as_me: WARNING: libjansson not found" >&2;}
            enable_md=no
        fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curl" >&5
    printf %s "checking for curl... " >&6; }
    if test ${ac_cv_curl+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
    
            ac_cv_curl=no
        ap_curl_found=""
        ap_curl_base=""
        ap_curl_libs=""
    
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user-provided curl base directory" >&5
    printf %s "checking for user-provided curl base directory... " >&6; }
    
    # Check whether --with-curl was given.
    if test ${with_curl+y}
    then :
      withval=$with_curl;
                if test "x$withval" != "xyes" -a "x$withval" != "x"; then
                    ap_curl_base="`cd $withval ; pwd`"
          fi
    
    fi
    
        if test "x$ap_curl_base" = "x"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
        else
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ap_curl_base" >&5
    printf "%s\n" "$ap_curl_base" >&6; }
        fi
    
            saved_CPPFLAGS="$CPPFLAGS"
        saved_LIBS="$LIBS"
        saved_LDFLAGS="$LDFLAGS"
    
            if test -n "$PKGCONFIG"; then
          saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pkg-config along $PKG_CONFIG_PATH" >&5
    printf %s "checking for pkg-config along $PKG_CONFIG_PATH... " >&6; }
          if test "x$ap_curl_base" != "x" ; then
            if test -f "${ap_curl_base}/lib/pkgconfig/libcurl.pc"; then
                                  PKG_CONFIG_PATH="${ap_curl_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            elif test -f "${ap_curl_base}/lib64/pkgconfig/libcurl.pc"; then
                                  PKG_CONFIG_PATH="${ap_curl_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
              export PKG_CONFIG_PATH
            fi
          fi
          # Check whether --enable-curl-staticlib-deps was given.
    if test ${enable_curl_staticlib_deps+y}
    then :
      enableval=$enable_curl_staticlib_deps;
            if test "$enableval" = "yes"; then
              PKGCONFIG_LIBOPTS="--static"
            fi
    
    fi
    
          ap_curl_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libcurl`"
          if test $? -eq 0; then
            ap_curl_found="yes"
            pkglookup="`$PKGCONFIG --cflags-only-I libcurl`"
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"$pkglookup\""
        CPPFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"$pkglookup\""
        MOD_CFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libcurl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
            pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libcurl`"
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$pkglookup\""
        LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$pkglookup\""
        MOD_LDFLAGS="$pkglookup"
      else
        apr_addto_bugger="$pkglookup"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
          PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
        fi
    
            if test "x$ap_curl_base" != "x" -a "x$ap_curl_found" = "x"; then
    
      if test "x$CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-I$ap_curl_base/include\""
        CPPFLAGS="-I$ap_curl_base/include"
      else
        apr_addto_bugger="-I$ap_curl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CPPFLAGS"
            CPPFLAGS="$CPPFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CFLAGS to \"-I$ap_curl_base/include\""
        MOD_CFLAGS="-I$ap_curl_base/include"
      else
        apr_addto_bugger="-I$ap_curl_base/include"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CFLAGS"
            MOD_CFLAGS="$MOD_CFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"-L$ap_curl_base/lib\""
        LDFLAGS="-L$ap_curl_base/lib"
      else
        apr_addto_bugger="-L$ap_curl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"-L$ap_curl_base/lib\""
        MOD_LDFLAGS="-L$ap_curl_base/lib"
      else
        apr_addto_bugger="-L$ap_curl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          if test "x$ap_platform_runtime_link_flag" != "x"; then
    
      if test "x$LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LDFLAGS to \"$ap_platform_runtime_link_flag$ap_curl_base/lib\""
        LDFLAGS="$ap_platform_runtime_link_flag$ap_curl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_curl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LDFLAGS"
            LDFLAGS="$LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_platform_runtime_link_flag$ap_curl_base/lib\""
        MOD_LDFLAGS="$ap_platform_runtime_link_flag$ap_curl_base/lib"
      else
        apr_addto_bugger="$ap_platform_runtime_link_flag$ap_curl_base/lib"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
          fi
        fi
    
        ac_fn_c_check_header_compile "$LINENO" "curl/curl.h" "ac_cv_header_curl_curl_h" "$ac_includes_default"
    if test "x$ac_cv_header_curl_curl_h" = xyes
    then :
      printf "%s\n" "#define HAVE_CURL_CURL_H 1" >>confdefs.h
    
    fi
    
    
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curl version >= 7.29" >&5
    printf %s "checking for curl version >= 7.29... " >&6; }
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    #include <curl/curlver.h>
    int
    main (void)
    {
    
    #if !defined(LIBCURL_VERSION_MAJOR)
    #error "Missing libcurl version"
    #endif
    #if LIBCURL_VERSION_MAJOR < 7
    #error "Unsupported libcurl version " LIBCURL_VERSION
    #endif
    #if LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR < 29
    #error "Unsupported libcurl version " LIBCURL_VERSION
    #endif
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_compile "$LINENO"
    then :
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: OK" >&5
    printf "%s\n" "OK" >&6; }
           ac_cv_curl=yes
    else $as_nop
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FAILED" >&5
    printf "%s\n" "FAILED" >&6; }
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    
        if test "x$ac_cv_curl" = "xyes"; then
          ap_curl_libs="${ap_curl_libs:--lcurl} `$apr_config --libs`"
    
      if test "x$MOD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_LDFLAGS to \"$ap_curl_libs\""
        MOD_LDFLAGS="$ap_curl_libs"
      else
        apr_addto_bugger="$ap_curl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_LDFLAGS"
            MOD_LDFLAGS="$MOD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting LIBS to \"$ap_curl_libs\""
        LIBS="$ap_curl_libs"
      else
        apr_addto_bugger="$ap_curl_libs"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to LIBS"
            LIBS="$LIBS $i"
          fi
        done
      fi
    
        fi
    
            CPPFLAGS="$saved_CPPFLAGS"
        LIBS="$saved_LIBS"
        LDFLAGS="$saved_LDFLAGS"
    
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_curl" >&5
    printf "%s\n" "$ac_cv_curl" >&6; }
      if test "x$ac_cv_curl" = "xyes"; then
    
    printf "%s\n" "#define HAVE_CURL 1" >>confdefs.h
    
      fi
    
        if test "x$ac_cv_curl" != "xyes" ; then
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libcurl not found" >&5
    printf "%s\n" "$as_me: WARNING: libcurl not found" >&2;}
            enable_md=no
        fi
    
    
      for ac_func in arc4random_buf
    do :
      ac_fn_c_check_func "$LINENO" "arc4random_buf" "ac_cv_func_arc4random_buf"
    if test "x$ac_cv_func_arc4random_buf" = xyes
    then :
      printf "%s\n" "#define HAVE_ARC4RANDOM_BUF 1" >>confdefs.h
    
      if test "x$MOD_CPPFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_CPPFLAGS to \""-DMD_HAVE_ARC4RANDOM"\""
        MOD_CPPFLAGS=""-DMD_HAVE_ARC4RANDOM""
      else
        apr_addto_bugger=""-DMD_HAVE_ARC4RANDOM""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_CPPFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_CPPFLAGS"
            MOD_CPPFLAGS="$MOD_CPPFLAGS $i"
          fi
        done
      fi
    
    fi
    
    done
    
        if test "x$enable_md" = "xshared"; then
    
      if test "x$MOD_MD_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_MD_LDADD to \"-export-symbols-regex md_module\""
        MOD_MD_LDADD="-export-symbols-regex md_module"
      else
        apr_addto_bugger="-export-symbols-regex md_module"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_MD_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_MD_LDADD"
            MOD_MD_LDADD="$MOD_MD_LDADD $i"
          fi
        done
      fi
    
        fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_md" >&5
    printf %s "checking whether to enable mod_md... " >&6; }
                if test "$enable_md" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_md has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_md$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_md$_apmod_extra_msg" >&6; }
      if test "$enable_md" != "no"; then
        case "$enable_md" in
        static*)
          MODLIST="$MODLIST md"
          if test "md" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES md"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},md"
          fi
          ;;
        esac
    
    
      if test -z "$md_objs"; then
        objects="mod_md.lo"
      else
        objects="$md_objs"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_md.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_MD_LDADD)
    EOF
          if test ! -z "\$(MOD_MD_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_MD_LDADD)\""
        AP_LIBS="\$(MOD_MD_LDADD)"
      else
        apr_addto_bugger="\$(MOD_MD_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_md.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  $objects \$(MOD_MD_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_MD_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=proxy/balancers
      modpath_current=modules/proxy/balancers
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d proxy/balancers || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_byrequests" >&5
    printf %s "checking whether to enable mod_lbmethod_byrequests... " >&6; }
        # Check whether --enable-lbmethod-byrequests was given.
    if test ${enable_lbmethod_byrequests+y}
    then :
      enableval=$enable_lbmethod_byrequests; force_lbmethod_byrequests=$enableval
    else $as_nop
      enable_lbmethod_byrequests=$enable_proxy_balancer
    fi
    
        _apmod_extra_msg=""
          case "$enable_lbmethod_byrequests" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_lbmethod_byrequests" = "static" -o "$enable_lbmethod_byrequests" = "shared"; then
        :
      elif test "$enable_lbmethod_byrequests" = "yes"; then
        enable_lbmethod_byrequests=$module_default
      elif test "$enable_lbmethod_byrequests" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_byrequests=$module_default
        else
          enable_lbmethod_byrequests=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_byrequests" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_lbmethod_byrequests=$module_default
        else
          enable_lbmethod_byrequests=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_byrequests" = "all" -o "$enable_lbmethod_byrequests" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_byrequests=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_byrequests=no
        fi
      elif test "$enable_lbmethod_byrequests" = "reallyall" -o "$enable_lbmethod_byrequests" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_lbmethod_byrequests" != "no" ; then
          enable_lbmethod_byrequests=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_byrequests=no
        fi
      else
        enable_lbmethod_byrequests=no
      fi
      if test "$enable_lbmethod_byrequests" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy_balancer" = "no" ; then
                                  enable_lbmethod_byrequests=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_byrequests\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_byrequests\"" >&2;}
                                elif test "$enable_lbmethod_byrequests" = "static" && test "$enable_proxy_balancer" != "static" ; then
                                  enable_lbmethod_byrequests=$enable_proxy_balancer
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_lbmethod_byrequests shared because mod_proxy_balancer is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_lbmethod_byrequests shared because mod_proxy_balancer is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_byrequests" >&5
    printf %s "checking whether to enable mod_lbmethod_byrequests... " >&6; }
                if test "$enable_lbmethod_byrequests" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_lbmethod_byrequests has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_lbmethod_byrequests$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_lbmethod_byrequests$_apmod_extra_msg" >&6; }
      if test "$enable_lbmethod_byrequests" != "no"; then
        case "$enable_lbmethod_byrequests" in
        static*)
          MODLIST="$MODLIST lbmethod_byrequests"
          if test "lbmethod_byrequests" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES lbmethod_byrequests"
          if test "$enable_proxy_balancer" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},lbmethod_byrequests"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_lbmethod_byrequests.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_lbmethod_byrequests.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LBMETHOD_BYREQUESTS_LDADD)
    EOF
          if test ! -z "\$(MOD_LBMETHOD_BYREQUESTS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LBMETHOD_BYREQUESTS_LDADD)\""
        AP_LIBS="\$(MOD_LBMETHOD_BYREQUESTS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LBMETHOD_BYREQUESTS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_lbmethod_byrequests.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  $objects \$(MOD_LBMETHOD_BYREQUESTS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LBMETHOD_BYREQUESTS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_bytraffic" >&5
    printf %s "checking whether to enable mod_lbmethod_bytraffic... " >&6; }
        # Check whether --enable-lbmethod-bytraffic was given.
    if test ${enable_lbmethod_bytraffic+y}
    then :
      enableval=$enable_lbmethod_bytraffic; force_lbmethod_bytraffic=$enableval
    else $as_nop
      enable_lbmethod_bytraffic=$enable_proxy_balancer
    fi
    
        _apmod_extra_msg=""
          case "$enable_lbmethod_bytraffic" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_lbmethod_bytraffic" = "static" -o "$enable_lbmethod_bytraffic" = "shared"; then
        :
      elif test "$enable_lbmethod_bytraffic" = "yes"; then
        enable_lbmethod_bytraffic=$module_default
      elif test "$enable_lbmethod_bytraffic" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_bytraffic=$module_default
        else
          enable_lbmethod_bytraffic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_bytraffic" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_lbmethod_bytraffic=$module_default
        else
          enable_lbmethod_bytraffic=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_bytraffic" = "all" -o "$enable_lbmethod_bytraffic" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_bytraffic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_bytraffic=no
        fi
      elif test "$enable_lbmethod_bytraffic" = "reallyall" -o "$enable_lbmethod_bytraffic" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_lbmethod_bytraffic" != "no" ; then
          enable_lbmethod_bytraffic=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_bytraffic=no
        fi
      else
        enable_lbmethod_bytraffic=no
      fi
      if test "$enable_lbmethod_bytraffic" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy_balancer" = "no" ; then
                                  enable_lbmethod_bytraffic=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_bytraffic\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_bytraffic\"" >&2;}
                                elif test "$enable_lbmethod_bytraffic" = "static" && test "$enable_proxy_balancer" != "static" ; then
                                  enable_lbmethod_bytraffic=$enable_proxy_balancer
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_lbmethod_bytraffic shared because mod_proxy_balancer is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_lbmethod_bytraffic shared because mod_proxy_balancer is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_bytraffic" >&5
    printf %s "checking whether to enable mod_lbmethod_bytraffic... " >&6; }
                if test "$enable_lbmethod_bytraffic" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_lbmethod_bytraffic has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_lbmethod_bytraffic$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_lbmethod_bytraffic$_apmod_extra_msg" >&6; }
      if test "$enable_lbmethod_bytraffic" != "no"; then
        case "$enable_lbmethod_bytraffic" in
        static*)
          MODLIST="$MODLIST lbmethod_bytraffic"
          if test "lbmethod_bytraffic" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES lbmethod_bytraffic"
          if test "$enable_proxy_balancer" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},lbmethod_bytraffic"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_lbmethod_bytraffic.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_lbmethod_bytraffic.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LBMETHOD_BYTRAFFIC_LDADD)
    EOF
          if test ! -z "\$(MOD_LBMETHOD_BYTRAFFIC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LBMETHOD_BYTRAFFIC_LDADD)\""
        AP_LIBS="\$(MOD_LBMETHOD_BYTRAFFIC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LBMETHOD_BYTRAFFIC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_lbmethod_bytraffic.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  $objects \$(MOD_LBMETHOD_BYTRAFFIC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LBMETHOD_BYTRAFFIC_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_bybusyness" >&5
    printf %s "checking whether to enable mod_lbmethod_bybusyness... " >&6; }
        # Check whether --enable-lbmethod-bybusyness was given.
    if test ${enable_lbmethod_bybusyness+y}
    then :
      enableval=$enable_lbmethod_bybusyness; force_lbmethod_bybusyness=$enableval
    else $as_nop
      enable_lbmethod_bybusyness=$enable_proxy_balancer
    fi
    
        _apmod_extra_msg=""
          case "$enable_lbmethod_bybusyness" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_lbmethod_bybusyness" = "static" -o "$enable_lbmethod_bybusyness" = "shared"; then
        :
      elif test "$enable_lbmethod_bybusyness" = "yes"; then
        enable_lbmethod_bybusyness=$module_default
      elif test "$enable_lbmethod_bybusyness" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_bybusyness=$module_default
        else
          enable_lbmethod_bybusyness=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_bybusyness" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_lbmethod_bybusyness=$module_default
        else
          enable_lbmethod_bybusyness=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_bybusyness" = "all" -o "$enable_lbmethod_bybusyness" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_bybusyness=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_bybusyness=no
        fi
      elif test "$enable_lbmethod_bybusyness" = "reallyall" -o "$enable_lbmethod_bybusyness" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_lbmethod_bybusyness" != "no" ; then
          enable_lbmethod_bybusyness=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_bybusyness=no
        fi
      else
        enable_lbmethod_bybusyness=no
      fi
      if test "$enable_lbmethod_bybusyness" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy_balancer" = "no" ; then
                                  enable_lbmethod_bybusyness=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_bybusyness\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_bybusyness\"" >&2;}
                                elif test "$enable_lbmethod_bybusyness" = "static" && test "$enable_proxy_balancer" != "static" ; then
                                  enable_lbmethod_bybusyness=$enable_proxy_balancer
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_lbmethod_bybusyness shared because mod_proxy_balancer is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_lbmethod_bybusyness shared because mod_proxy_balancer is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_bybusyness" >&5
    printf %s "checking whether to enable mod_lbmethod_bybusyness... " >&6; }
                if test "$enable_lbmethod_bybusyness" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_lbmethod_bybusyness has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_lbmethod_bybusyness$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_lbmethod_bybusyness$_apmod_extra_msg" >&6; }
      if test "$enable_lbmethod_bybusyness" != "no"; then
        case "$enable_lbmethod_bybusyness" in
        static*)
          MODLIST="$MODLIST lbmethod_bybusyness"
          if test "lbmethod_bybusyness" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES lbmethod_bybusyness"
          if test "$enable_proxy_balancer" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},lbmethod_bybusyness"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_lbmethod_bybusyness.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_lbmethod_bybusyness.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LBMETHOD_BYBUSYNESS_LDADD)
    EOF
          if test ! -z "\$(MOD_LBMETHOD_BYBUSYNESS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LBMETHOD_BYBUSYNESS_LDADD)\""
        AP_LIBS="\$(MOD_LBMETHOD_BYBUSYNESS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LBMETHOD_BYBUSYNESS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_lbmethod_bybusyness.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  $objects \$(MOD_LBMETHOD_BYBUSYNESS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LBMETHOD_BYBUSYNESS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_heartbeat" >&5
    printf %s "checking whether to enable mod_lbmethod_heartbeat... " >&6; }
        # Check whether --enable-lbmethod-heartbeat was given.
    if test ${enable_lbmethod_heartbeat+y}
    then :
      enableval=$enable_lbmethod_heartbeat; force_lbmethod_heartbeat=$enableval
    else $as_nop
      enable_lbmethod_heartbeat=$enable_proxy_balancer
    fi
    
        _apmod_extra_msg=""
          case "$enable_lbmethod_heartbeat" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_lbmethod_heartbeat" = "static" -o "$enable_lbmethod_heartbeat" = "shared"; then
        :
      elif test "$enable_lbmethod_heartbeat" = "yes"; then
        enable_lbmethod_heartbeat=$module_default
      elif test "$enable_lbmethod_heartbeat" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_heartbeat=$module_default
        else
          enable_lbmethod_heartbeat=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_heartbeat" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_lbmethod_heartbeat=$module_default
        else
          enable_lbmethod_heartbeat=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_lbmethod_heartbeat" = "all" -o "$enable_lbmethod_heartbeat" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_lbmethod_heartbeat=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_heartbeat=no
        fi
      elif test "$enable_lbmethod_heartbeat" = "reallyall" -o "$enable_lbmethod_heartbeat" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_lbmethod_heartbeat" != "no" ; then
          enable_lbmethod_heartbeat=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_lbmethod_heartbeat=no
        fi
      else
        enable_lbmethod_heartbeat=no
      fi
      if test "$enable_lbmethod_heartbeat" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_proxy_balancer" = "no" ; then
                                  enable_lbmethod_heartbeat=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_heartbeat\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_proxy_balancer is disabled but required for mod_lbmethod_heartbeat\"" >&2;}
                                elif test "$enable_lbmethod_heartbeat" = "static" && test "$enable_proxy_balancer" != "static" ; then
                                  enable_lbmethod_heartbeat=$enable_proxy_balancer
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_lbmethod_heartbeat shared because mod_proxy_balancer is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_lbmethod_heartbeat shared because mod_proxy_balancer is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_lbmethod_heartbeat" >&5
    printf %s "checking whether to enable mod_lbmethod_heartbeat... " >&6; }
                if test "$enable_lbmethod_heartbeat" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_lbmethod_heartbeat has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_lbmethod_heartbeat$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_lbmethod_heartbeat$_apmod_extra_msg" >&6; }
      if test "$enable_lbmethod_heartbeat" != "no"; then
        case "$enable_lbmethod_heartbeat" in
        static*)
          MODLIST="$MODLIST lbmethod_heartbeat"
          if test "lbmethod_heartbeat" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES lbmethod_heartbeat"
          if test "$enable_proxy_balancer" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},lbmethod_heartbeat"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_lbmethod_heartbeat.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_lbmethod_heartbeat.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_LBMETHOD_HEARTBEAT_LDADD)
    EOF
          if test ! -z "\$(MOD_LBMETHOD_HEARTBEAT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_LBMETHOD_HEARTBEAT_LDADD)\""
        AP_LIBS="\$(MOD_LBMETHOD_HEARTBEAT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_LBMETHOD_HEARTBEAT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_lbmethod_heartbeat.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  $objects \$(MOD_LBMETHOD_HEARTBEAT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_LBMETHOD_HEARTBEAT_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which MPM to use by default" >&5
    printf %s "checking which MPM to use by default... " >&6; }
    
    # Check whether --with-mpm was given.
    if test ${with_mpm+y}
    then :
      withval=$with_mpm;
        default_mpm=$withval
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
    printf "%s\n" "$withval" >&6; };
    
    else $as_nop
    
                    if ap_mpm_is_supported "winnt"; then
            default_mpm=winnt
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: winnt" >&5
    printf "%s\n" "winnt" >&6; }
        elif ap_mpm_is_supported "mpmt_os2"; then
            default_mpm=mpmt_os2
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: mpmt_os2" >&5
    printf "%s\n" "mpmt_os2" >&6; }
        elif ap_mpm_is_supported "event"; then
            default_mpm=event
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: event" >&5
    printf "%s\n" "event" >&6; }
        elif ap_mpm_is_supported "worker"; then
            default_mpm=worker
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: worker - event is not supported" >&5
    printf "%s\n" "worker - event is not supported" >&6; }
        else
            default_mpm=prefork
            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: prefork - event and worker are not supported" >&5
    printf "%s\n" "prefork - event and worker are not supported" >&6; }
        fi
    
    fi
    
    
    
        if ap_mpm_is_enabled $default_mpm; then
            :
        else
            eval "ap_enabled_mpm_$default_mpm=yes"
            ap_enabled_mpms="$ap_enabled_mpms $default_mpm "
        fi
    
    
    # Check whether --enable-mpms-shared was given.
    if test ${enable_mpms_shared+y}
    then :
      enableval=$enable_mpms_shared;
        if test "$enableval" = "no"; then
            mpm_build=static
        else
            mpm_build=shared
            if test "$enableval" = "yes"; then
                enableval=$default_mpm
            fi
            for i in $enableval; do
                if test "$i" = "all"; then
                    for j in $ap_supported_shared_mpms; do
                        eval "enable_mpm_$j=shared"
    
        if ap_mpm_is_enabled $j; then
            :
        else
            eval "ap_enabled_mpm_$j=yes"
            ap_enabled_mpms="$ap_enabled_mpms $j "
        fi
    
                    done
                else
                    i=`echo $i | sed 's/-/_/g'`
                    if ap_mpm_supports_shared $i; then
                        eval "enable_mpm_$i=shared"
    
        if ap_mpm_is_enabled $i; then
            :
        else
            eval "ap_enabled_mpm_$i=yes"
            ap_enabled_mpms="$ap_enabled_mpms $i "
        fi
    
                    else
                        as_fn_error $? "MPM $i does not support dynamic loading." "$LINENO" 5
                    fi
                fi
            done
        fi
    
    else $as_nop
      mpm_build=static
    fi
    
    
    for i in $ap_enabled_mpms; do
        if ap_mpm_is_supported $i; then
            :
        else
            as_fn_error $? "MPM $i is not supported on this platform." "$LINENO" 5
        fi
    done
    
    if test $mpm_build = "shared"; then
        eval "tmp=\$enable_mpm_$default_mpm"
        if test "$tmp" != "shared"; then
            as_fn_error $? "The default MPM ($default_mpm) must be included in --enable-mpms-shared.  Use --with-mpm to change the default MPM." "$LINENO" 5
        fi
    fi
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES server/mpm/Makefile"
    
    
    if test $mpm_build = "shared"; then
        MPM_LIB=""
    else
        MPM_LIB=server/mpm/$default_mpm/lib${default_mpm}.la
        MODLIST="$MODLIST mpm_${default_mpm}"
    fi
    
    MPM_SUBDIRS=$ap_enabled_mpms
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MPM_SUBDIRS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MPM_LIB"
    
    
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_MPM_EVENT_LDADD"
    
    
    
    
        if ap_mpm_is_enabled event; then
            if test -z "event.lo"; then
                objects="event.lo"
            else
                objects="event.lo"
            fi
    
            if test -z ""; then
                mpmpath="server/mpm/event"
            else
                mpmpath=
            fi
    
                    test -d $mpmpath || $srcdir/build/mkdir.sh $mpmpath
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES $mpmpath/Makefile"
    
    
            if test -z "$enable_mpm_event"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_MPM_EVENT_LDADD)\""
        AP_LIBS="\$(MOD_MPM_EVENT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_MPM_EVENT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
                libname="libevent.la"
                cat >$mpmpath/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
            else
                apache_need_shared=yes
                libname="mod_mpm_event.la"
                shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
                cat >$mpmpath/modules.mk<<EOF
    $libname: $shobjects
    	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $objects \$(MOD_MPM_EVENT_LDADD)
    DISTCLEAN_TARGETS = modules.mk
    static =
    shared = $libname
    EOF
                MPM_MODULES="$MPM_MODULES mpm_event"
                # add default MPM to LoadModule list
                if test event = $default_mpm; then
                    ENABLED_MPM_MODULE="mpm_event"
                fi
            fi
    
        ac_fn_c_check_func "$LINENO" "pthread_kill" "ac_cv_func_pthread_kill"
    if test "x$ac_cv_func_pthread_kill" = xyes
    then :
      printf "%s\n" "#define HAVE_PTHREAD_KILL 1" >>confdefs.h
    
    fi
    
    
        fi
    
    
    
        if ap_mpm_is_enabled prefork; then
            if test -z ""; then
                objects="prefork.lo"
            else
                objects=""
            fi
    
            if test -z ""; then
                mpmpath="server/mpm/prefork"
            else
                mpmpath=
            fi
    
                    test -d $mpmpath || $srcdir/build/mkdir.sh $mpmpath
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES $mpmpath/Makefile"
    
    
            if test -z "$enable_mpm_prefork"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\""
        AP_LIBS=""
      else
        apr_addto_bugger=""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
                libname="libprefork.la"
                cat >$mpmpath/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
            else
                apache_need_shared=yes
                libname="mod_mpm_prefork.la"
                shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
                cat >$mpmpath/modules.mk<<EOF
    $libname: $shobjects
    	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $objects
    DISTCLEAN_TARGETS = modules.mk
    static =
    shared = $libname
    EOF
                MPM_MODULES="$MPM_MODULES mpm_prefork"
                # add default MPM to LoadModule list
                if test prefork = $default_mpm; then
                    ENABLED_MPM_MODULE="mpm_prefork"
                fi
            fi
    
        fi
    
    
    winnt_objects="child.lo mpm_winnt.lo nt_eventlog.lo service.lo"
    
        if ap_mpm_is_enabled winnt; then
            if test -z "$winnt_objects"; then
                objects="winnt.lo"
            else
                objects="$winnt_objects"
            fi
    
            if test -z ""; then
                mpmpath="server/mpm/winnt"
            else
                mpmpath=
            fi
    
                    test -d $mpmpath || $srcdir/build/mkdir.sh $mpmpath
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES $mpmpath/Makefile"
    
    
            if test -z "$enable_mpm_winnt"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\""
        AP_LIBS=""
      else
        apr_addto_bugger=""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
                libname="libwinnt.la"
                cat >$mpmpath/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
            else
                apache_need_shared=yes
                libname="mod_mpm_winnt.la"
                shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
                cat >$mpmpath/modules.mk<<EOF
    $libname: $shobjects
    	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $objects
    DISTCLEAN_TARGETS = modules.mk
    static =
    shared = $libname
    EOF
                MPM_MODULES="$MPM_MODULES mpm_winnt"
                # add default MPM to LoadModule list
                if test winnt = $default_mpm; then
                    ENABLED_MPM_MODULE="mpm_winnt"
                fi
            fi
    
        fi
    
    
    
    
        if ap_mpm_is_enabled worker; then
            if test -z "worker.lo"; then
                objects="worker.lo"
            else
                objects="worker.lo"
            fi
    
            if test -z ""; then
                mpmpath="server/mpm/worker"
            else
                mpmpath=
            fi
    
                    test -d $mpmpath || $srcdir/build/mkdir.sh $mpmpath
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES $mpmpath/Makefile"
    
    
            if test -z "$enable_mpm_worker"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\""
        AP_LIBS=""
      else
        apr_addto_bugger=""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
                libname="libworker.la"
                cat >$mpmpath/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
            else
                apache_need_shared=yes
                libname="mod_mpm_worker.la"
                shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
                cat >$mpmpath/modules.mk<<EOF
    $libname: $shobjects
    	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $objects
    DISTCLEAN_TARGETS = modules.mk
    static =
    shared = $libname
    EOF
                MPM_MODULES="$MPM_MODULES mpm_worker"
                # add default MPM to LoadModule list
                if test worker = $default_mpm; then
                    ENABLED_MPM_MODULE="mpm_worker"
                fi
            fi
    
        ac_fn_c_check_func "$LINENO" "pthread_kill" "ac_cv_func_pthread_kill"
    if test "x$ac_cv_func_pthread_kill" = xyes
    then :
      printf "%s\n" "#define HAVE_PTHREAD_KILL 1" >>confdefs.h
    
    fi
    
    
        fi
    
    
    
    
      current_dir=arch/unix
      modpath_current=modules/arch/unix
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d arch/unix || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    if ap_mpm_is_enabled "worker" \
       || ap_mpm_is_enabled "event" \
       || ap_mpm_is_enabled "prefork"; then
        unixd_mods_enable=yes
    else
        unixd_mods_enable=no
    fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_unixd" >&5
    printf %s "checking whether to enable mod_unixd... " >&6; }
        # Check whether --enable-unixd was given.
    if test ${enable_unixd+y}
    then :
      enableval=$enable_unixd; force_unixd=$enableval
    else $as_nop
      enable_unixd=$unixd_mods_enable
    fi
    
        _apmod_extra_msg=""
          case "$enable_unixd" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_unixd" = "static" -o "$enable_unixd" = "shared"; then
        :
      elif test "$enable_unixd" = "yes"; then
        enable_unixd=$module_default
      elif test "$enable_unixd" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_unixd=$module_default
        else
          enable_unixd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_unixd" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_unixd=$module_default
        else
          enable_unixd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_unixd" = "all" -o "$enable_unixd" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_unixd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_unixd=no
        fi
      elif test "$enable_unixd" = "reallyall" -o "$enable_unixd" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_unixd" != "no" ; then
          enable_unixd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_unixd=no
        fi
      else
        enable_unixd=no
      fi
      if test "$enable_unixd" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_unixd$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_unixd$_apmod_extra_msg" >&6; }
      if test "$enable_unixd" != "no"; then
        case "$enable_unixd" in
        static*)
          MODLIST="$MODLIST unixd"
          if test "unixd" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES unixd"
          if test "$unixd_mods_enable" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},unixd"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_unixd.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_unixd.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_UNIXD_LDADD)
    EOF
          if test ! -z "\$(MOD_UNIXD_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_UNIXD_LDADD)\""
        AP_LIBS="\$(MOD_UNIXD_LDADD)"
      else
        apr_addto_bugger="\$(MOD_UNIXD_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_unixd.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  $objects \$(MOD_UNIXD_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_UNIXD_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_privileges" >&5
    printf %s "checking whether to enable mod_privileges... " >&6; }
        # Check whether --enable-privileges was given.
    if test ${enable_privileges+y}
    then :
      enableval=$enable_privileges; force_privileges=$enableval
    else $as_nop
      enable_privileges=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_privileges" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_privileges" = "static" -o "$enable_privileges" = "shared"; then
        :
      elif test "$enable_privileges" = "yes"; then
        enable_privileges=$module_default
      elif test "$enable_privileges" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_privileges=$module_default
        else
          enable_privileges=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_privileges" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_privileges=$module_default
        else
          enable_privileges=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_privileges" = "all" -o "$enable_privileges" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_privileges=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_privileges=no
        fi
      elif test "$enable_privileges" = "reallyall" -o "$enable_privileges" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_privileges" != "no" ; then
          enable_privileges=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_privileges=no
        fi
      else
        enable_privileges=no
      fi
      if test "$enable_privileges" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
             for ac_header in priv.h
    do :
      ac_fn_c_check_header_compile "$LINENO" "priv.h" "ac_cv_header_priv_h" "$ac_includes_default"
    if test "x$ac_cv_header_priv_h" = xyes
    then :
      printf "%s\n" "#define HAVE_PRIV_H 1" >>confdefs.h
     ap_HAVE_PRIV_H="yes"
    else $as_nop
      ap_HAVE_PRIV_H="no"
    fi
    
    done
      if test $ap_HAVE_PRIV_H = "no"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Your system does not support privileges." >&5
    printf "%s\n" "$as_me: WARNING: Your system does not support privileges." >&2;}
        enable_privileges="no"
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_privileges" >&5
    printf %s "checking whether to enable mod_privileges... " >&6; }
                if test "$enable_privileges" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_privileges has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_privileges$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_privileges$_apmod_extra_msg" >&6; }
      if test "$enable_privileges" != "no"; then
        case "$enable_privileges" in
        static*)
          MODLIST="$MODLIST privileges"
          if test "privileges" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES privileges"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},privileges"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_privileges.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_privileges.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_PRIVILEGES_LDADD)
    EOF
          if test ! -z "\$(MOD_PRIVILEGES_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_PRIVILEGES_LDADD)\""
        AP_LIBS="\$(MOD_PRIVILEGES_LDADD)"
      else
        apr_addto_bugger="\$(MOD_PRIVILEGES_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_privileges.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  $objects \$(MOD_PRIVILEGES_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_PRIVILEGES_LDADD"
    
    
    
      fi
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_systemd" >&5
    printf %s "checking whether to enable mod_systemd... " >&6; }
        # Check whether --enable-systemd was given.
    if test ${enable_systemd+y}
    then :
      enableval=$enable_systemd; force_systemd=$enableval
    else $as_nop
      enable_systemd=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_systemd" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_systemd" = "static" -o "$enable_systemd" = "shared"; then
        :
      elif test "$enable_systemd" = "yes"; then
        enable_systemd=$module_default
      elif test "$enable_systemd" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_systemd=$module_default
        else
          enable_systemd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_systemd" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_systemd=$module_default
        else
          enable_systemd=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_systemd" = "all" -o "$enable_systemd" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_systemd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_systemd=no
        fi
      elif test "$enable_systemd" = "reallyall" -o "$enable_systemd" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_systemd" != "no" ; then
          enable_systemd=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_systemd=no
        fi
      else
        enable_systemd=no
      fi
      if test "$enable_systemd" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
      if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Your system does not support systemd." >&5
    printf "%s\n" "$as_me: WARNING: Your system does not support systemd." >&2;}
        enable_systemd="no"
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for is_selinux_enabled in -lselinux" >&5
    printf %s "checking for is_selinux_enabled in -lselinux... " >&6; }
    if test ${ac_cv_lib_selinux_is_selinux_enabled+y}
    then :
      printf %s "(cached) " >&6
    else $as_nop
      ac_check_lib_save_LIBS=$LIBS
    LIBS="-lselinux  $LIBS"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    /* Override any GCC internal prototype to avoid an error.
       Use char because int might match the return type of a GCC
       builtin and then its argument prototype would still apply.  */
    char is_selinux_enabled ();
    int
    main (void)
    {
    return is_selinux_enabled ();
      ;
      return 0;
    }
    _ACEOF
    if ac_fn_c_try_link "$LINENO"
    then :
      ac_cv_lib_selinux_is_selinux_enabled=yes
    else $as_nop
      ac_cv_lib_selinux_is_selinux_enabled=no
    fi
    rm -f core conftest.err conftest.$ac_objext conftest.beam \
        conftest$ac_exeext conftest.$ac_ext
    LIBS=$ac_check_lib_save_LIBS
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5
    printf "%s\n" "$ac_cv_lib_selinux_is_selinux_enabled" >&6; }
    if test "x$ac_cv_lib_selinux_is_selinux_enabled" = xyes
    then :
    
    
    printf "%s\n" "#define HAVE_SELINUX 1" >>confdefs.h
    
    
      if test "x$MOD_SYSTEMD_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_SYSTEMD_LDADD to \"-lselinux\""
        MOD_SYSTEMD_LDADD="-lselinux"
      else
        apr_addto_bugger="-lselinux"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_SYSTEMD_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_SYSTEMD_LDADD"
            MOD_SYSTEMD_LDADD="$MOD_SYSTEMD_LDADD $i"
          fi
        done
      fi
    
    
    fi
    
    
    
      if test "x$MOD_SYSTEMD_LDADD" = "x"; then
        test "x$silent" != "xyes" && echo "  setting MOD_SYSTEMD_LDADD to \"$SYSTEMD_LIBS\""
        MOD_SYSTEMD_LDADD="$SYSTEMD_LIBS"
      else
        apr_addto_bugger="$SYSTEMD_LIBS"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $MOD_SYSTEMD_LDADD; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to MOD_SYSTEMD_LDADD"
            MOD_SYSTEMD_LDADD="$MOD_SYSTEMD_LDADD $i"
          fi
        done
      fi
    
      fi
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_systemd" >&5
    printf %s "checking whether to enable mod_systemd... " >&6; }
                if test "$enable_systemd" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_systemd has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_systemd$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_systemd$_apmod_extra_msg" >&6; }
      if test "$enable_systemd" != "no"; then
        case "$enable_systemd" in
        static*)
          MODLIST="$MODLIST systemd"
          if test "systemd" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES systemd"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},systemd"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_systemd.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_systemd.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SYSTEMD_LDADD)
    EOF
          if test ! -z "\$(MOD_SYSTEMD_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SYSTEMD_LDADD)\""
        AP_LIBS="\$(MOD_SYSTEMD_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SYSTEMD_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_systemd.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  $objects \$(MOD_SYSTEMD_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SYSTEMD_LDADD"
    
    
    
      fi
    
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=cluster
      modpath_current=modules/cluster
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d cluster || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    heartbeat_objects='mod_heartbeat.lo'
    
    case "$host" in
      *os2*)
        # OS/2 DLLs must resolve all symbols at build time
        # and we need some from the watchdog module
        heartbeat_objects="$heartbeat_objects ../core/mod_watchdog.la"
        ;;
    esac
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_heartbeat" >&5
    printf %s "checking whether to enable mod_heartbeat... " >&6; }
        # Check whether --enable-heartbeat was given.
    if test ${enable_heartbeat+y}
    then :
      enableval=$enable_heartbeat; force_heartbeat=$enableval
    else $as_nop
      enable_heartbeat=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_heartbeat" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_heartbeat" = "static" -o "$enable_heartbeat" = "shared"; then
        :
      elif test "$enable_heartbeat" = "yes"; then
        enable_heartbeat=$module_default
      elif test "$enable_heartbeat" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_heartbeat=$module_default
        else
          enable_heartbeat=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_heartbeat" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_heartbeat=$module_default
        else
          enable_heartbeat=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_heartbeat" = "all" -o "$enable_heartbeat" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_heartbeat=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_heartbeat=no
        fi
      elif test "$enable_heartbeat" = "reallyall" -o "$enable_heartbeat" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_heartbeat" != "no" ; then
          enable_heartbeat=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_heartbeat=no
        fi
      else
        enable_heartbeat=no
      fi
      if test "$enable_heartbeat" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_watchdog" = "no" ; then
                                  enable_heartbeat=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_watchdog is disabled but required for mod_heartbeat\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_watchdog is disabled but required for mod_heartbeat\"" >&2;}
                                elif test "$enable_heartbeat" = "static" && test "$enable_watchdog" != "static" ; then
                                  enable_heartbeat=$enable_watchdog
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_heartbeat shared because mod_watchdog is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_heartbeat shared because mod_watchdog is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_heartbeat" >&5
    printf %s "checking whether to enable mod_heartbeat... " >&6; }
                if test "$enable_heartbeat" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_heartbeat has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_heartbeat$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_heartbeat$_apmod_extra_msg" >&6; }
      if test "$enable_heartbeat" != "no"; then
        case "$enable_heartbeat" in
        static*)
          MODLIST="$MODLIST heartbeat"
          if test "heartbeat" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES heartbeat"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},heartbeat"
          fi
          ;;
        esac
    
    
      if test -z "$heartbeat_objects"; then
        objects="mod_heartbeat.lo"
      else
        objects="$heartbeat_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_heartbeat.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_HEARTBEAT_LDADD)
    EOF
          if test ! -z "\$(MOD_HEARTBEAT_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_HEARTBEAT_LDADD)\""
        AP_LIBS="\$(MOD_HEARTBEAT_LDADD)"
      else
        apr_addto_bugger="\$(MOD_HEARTBEAT_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_heartbeat.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  $objects \$(MOD_HEARTBEAT_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_HEARTBEAT_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_heartmonitor" >&5
    printf %s "checking whether to enable mod_heartmonitor... " >&6; }
        # Check whether --enable-heartmonitor was given.
    if test ${enable_heartmonitor+y}
    then :
      enableval=$enable_heartmonitor; force_heartmonitor=$enableval
    else $as_nop
      enable_heartmonitor=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_heartmonitor" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_heartmonitor" = "static" -o "$enable_heartmonitor" = "shared"; then
        :
      elif test "$enable_heartmonitor" = "yes"; then
        enable_heartmonitor=$module_default
      elif test "$enable_heartmonitor" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_heartmonitor=$module_default
        else
          enable_heartmonitor=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_heartmonitor" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_heartmonitor=$module_default
        else
          enable_heartmonitor=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_heartmonitor" = "all" -o "$enable_heartmonitor" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_heartmonitor=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_heartmonitor=no
        fi
      elif test "$enable_heartmonitor" = "reallyall" -o "$enable_heartmonitor" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_heartmonitor" != "no" ; then
          enable_heartmonitor=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_heartmonitor=no
        fi
      else
        enable_heartmonitor=no
      fi
      if test "$enable_heartmonitor" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_heartmonitor$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_heartmonitor$_apmod_extra_msg" >&6; }
      if test "$enable_heartmonitor" != "no"; then
        case "$enable_heartmonitor" in
        static*)
          MODLIST="$MODLIST heartmonitor"
          if test "heartmonitor" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES heartmonitor"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},heartmonitor"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_heartmonitor.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_heartmonitor.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_HEARTMONITOR_LDADD)
    EOF
          if test ! -z "\$(MOD_HEARTMONITOR_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_HEARTMONITOR_LDADD)\""
        AP_LIBS="\$(MOD_HEARTMONITOR_LDADD)"
      else
        apr_addto_bugger="\$(MOD_HEARTMONITOR_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_heartmonitor.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  $objects \$(MOD_HEARTMONITOR_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_HEARTMONITOR_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=dav/main
      modpath_current=modules/dav/main
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d dav/main || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    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
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dav" >&5
    printf %s "checking whether to enable mod_dav... " >&6; }
        # Check whether --enable-dav was given.
    if test ${enable_dav+y}
    then :
      enableval=$enable_dav; force_dav=$enableval
    else $as_nop
      enable_dav=$dav_enable
    fi
    
        _apmod_extra_msg=""
          case "$enable_dav" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_dav" = "static" -o "$enable_dav" = "shared"; then
        :
      elif test "$enable_dav" = "yes"; then
        enable_dav=$module_default
      elif test "$enable_dav" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dav=$module_default
        else
          enable_dav=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dav" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_dav=$module_default
        else
          enable_dav=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dav" = "all" -o "$enable_dav" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dav=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dav=no
        fi
      elif test "$enable_dav" = "reallyall" -o "$enable_dav" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_dav" != "no" ; then
          enable_dav=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dav=no
        fi
      else
        enable_dav=no
      fi
      if test "$enable_dav" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_dav$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_dav$_apmod_extra_msg" >&6; }
      if test "$enable_dav" != "no"; then
        case "$enable_dav" in
        static*)
          MODLIST="$MODLIST dav"
          if test "dav" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES dav"
          if test "$dav_enable" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},dav"
          fi
          ;;
        esac
    
    
      if test -z "$dav_objects"; then
        objects="mod_dav.lo"
      else
        objects="$dav_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_dav.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DAV_LDADD)
    EOF
          if test ! -z "\$(MOD_DAV_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DAV_LDADD)\""
        AP_LIBS="\$(MOD_DAV_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DAV_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_dav.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  $objects \$(MOD_DAV_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DAV_LDADD"
    
    
    
      fi
    
    
    if test "$dav_enable" != "no" -o "$enable_dav" != "no"; then
      apache_need_expat=yes
    fi
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      current_dir=generators
      modpath_current=modules/generators
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d generators || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_status" >&5
    printf %s "checking whether to enable mod_status... " >&6; }
        # Check whether --enable-status was given.
    if test ${enable_status+y}
    then :
      enableval=$enable_status; force_status=$enableval
    else $as_nop
      enable_status=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_status" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_status" = "static" -o "$enable_status" = "shared"; then
        :
      elif test "$enable_status" = "yes"; then
        enable_status=$module_default
      elif test "$enable_status" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_status=$module_default
        else
          enable_status=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_status" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_status=$module_default
        else
          enable_status=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_status" = "all" -o "$enable_status" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_status=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_status=no
        fi
      elif test "$enable_status" = "reallyall" -o "$enable_status" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_status" != "no" ; then
          enable_status=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_status=no
        fi
      else
        enable_status=no
      fi
      if test "$enable_status" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_status$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_status$_apmod_extra_msg" >&6; }
      if test "$enable_status" != "no"; then
        case "$enable_status" in
        static*)
          MODLIST="$MODLIST status"
          if test "status" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES status"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},status"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_status.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_status.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_STATUS_LDADD)
    EOF
          if test ! -z "\$(MOD_STATUS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_STATUS_LDADD)\""
        AP_LIBS="\$(MOD_STATUS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_STATUS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_status.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  $objects \$(MOD_STATUS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_STATUS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_autoindex" >&5
    printf %s "checking whether to enable mod_autoindex... " >&6; }
        # Check whether --enable-autoindex was given.
    if test ${enable_autoindex+y}
    then :
      enableval=$enable_autoindex; force_autoindex=$enableval
    else $as_nop
      enable_autoindex=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_autoindex" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_autoindex" = "static" -o "$enable_autoindex" = "shared"; then
        :
      elif test "$enable_autoindex" = "yes"; then
        enable_autoindex=$module_default
      elif test "$enable_autoindex" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_autoindex=$module_default
        else
          enable_autoindex=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_autoindex" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_autoindex=$module_default
        else
          enable_autoindex=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_autoindex" = "all" -o "$enable_autoindex" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_autoindex=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_autoindex=no
        fi
      elif test "$enable_autoindex" = "reallyall" -o "$enable_autoindex" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_autoindex" != "no" ; then
          enable_autoindex=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_autoindex=no
        fi
      else
        enable_autoindex=no
      fi
      if test "$enable_autoindex" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_autoindex$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_autoindex$_apmod_extra_msg" >&6; }
      if test "$enable_autoindex" != "no"; then
        case "$enable_autoindex" in
        static*)
          MODLIST="$MODLIST autoindex"
          if test "autoindex" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES autoindex"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},autoindex"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_autoindex.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_autoindex.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_AUTOINDEX_LDADD)
    EOF
          if test ! -z "\$(MOD_AUTOINDEX_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_AUTOINDEX_LDADD)\""
        AP_LIBS="\$(MOD_AUTOINDEX_LDADD)"
      else
        apr_addto_bugger="\$(MOD_AUTOINDEX_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_autoindex.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  $objects \$(MOD_AUTOINDEX_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_AUTOINDEX_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_asis" >&5
    printf %s "checking whether to enable mod_asis... " >&6; }
        # Check whether --enable-asis was given.
    if test ${enable_asis+y}
    then :
      enableval=$enable_asis; force_asis=$enableval
    else $as_nop
      enable_asis=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_asis" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_asis" = "static" -o "$enable_asis" = "shared"; then
        :
      elif test "$enable_asis" = "yes"; then
        enable_asis=$module_default
      elif test "$enable_asis" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_asis=$module_default
        else
          enable_asis=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_asis" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_asis=$module_default
        else
          enable_asis=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_asis" = "all" -o "$enable_asis" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_asis=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_asis=no
        fi
      elif test "$enable_asis" = "reallyall" -o "$enable_asis" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_asis" != "no" ; then
          enable_asis=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_asis=no
        fi
      else
        enable_asis=no
      fi
      if test "$enable_asis" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_asis$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_asis$_apmod_extra_msg" >&6; }
      if test "$enable_asis" != "no"; then
        case "$enable_asis" in
        static*)
          MODLIST="$MODLIST asis"
          if test "asis" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES asis"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},asis"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_asis.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_asis.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ASIS_LDADD)
    EOF
          if test ! -z "\$(MOD_ASIS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ASIS_LDADD)\""
        AP_LIBS="\$(MOD_ASIS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ASIS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_asis.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  $objects \$(MOD_ASIS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ASIS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_info" >&5
    printf %s "checking whether to enable mod_info... " >&6; }
        # Check whether --enable-info was given.
    if test ${enable_info+y}
    then :
      enableval=$enable_info; force_info=$enableval
    else $as_nop
      enable_info=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_info" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_info" = "static" -o "$enable_info" = "shared"; then
        :
      elif test "$enable_info" = "yes"; then
        enable_info=$module_default
      elif test "$enable_info" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_info=$module_default
        else
          enable_info=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_info" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_info=$module_default
        else
          enable_info=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_info" = "all" -o "$enable_info" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_info=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_info=no
        fi
      elif test "$enable_info" = "reallyall" -o "$enable_info" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_info" != "no" ; then
          enable_info=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_info=no
        fi
      else
        enable_info=no
      fi
      if test "$enable_info" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_info$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_info$_apmod_extra_msg" >&6; }
      if test "$enable_info" != "no"; then
        case "$enable_info" in
        static*)
          MODLIST="$MODLIST info"
          if test "info" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES info"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},info"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_info.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_info.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_INFO_LDADD)
    EOF
          if test ! -z "\$(MOD_INFO_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_INFO_LDADD)\""
        AP_LIBS="\$(MOD_INFO_LDADD)"
      else
        apr_addto_bugger="\$(MOD_INFO_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_info.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  $objects \$(MOD_INFO_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_INFO_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_suexec" >&5
    printf %s "checking whether to enable mod_suexec... " >&6; }
        # Check whether --enable-suexec was given.
    if test ${enable_suexec+y}
    then :
      enableval=$enable_suexec; force_suexec=$enableval
    else $as_nop
      enable_suexec=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_suexec" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_suexec" = "static" -o "$enable_suexec" = "shared"; then
        :
      elif test "$enable_suexec" = "yes"; then
        enable_suexec=$module_default
      elif test "$enable_suexec" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_suexec=$module_default
        else
          enable_suexec=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_suexec" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_suexec=$module_default
        else
          enable_suexec=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_suexec" = "all" -o "$enable_suexec" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_suexec=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_suexec=no
        fi
      elif test "$enable_suexec" = "reallyall" -o "$enable_suexec" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_suexec" != "no" ; then
          enable_suexec=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_suexec=no
        fi
      else
        enable_suexec=no
      fi
      if test "$enable_suexec" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
                  other_targets=suexec
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_suexec" >&5
    printf %s "checking whether to enable mod_suexec... " >&6; }
                if test "$enable_suexec" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_suexec has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_suexec$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_suexec$_apmod_extra_msg" >&6; }
      if test "$enable_suexec" != "no"; then
        case "$enable_suexec" in
        static*)
          MODLIST="$MODLIST suexec"
          if test "suexec" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES suexec"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},suexec"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_suexec.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_suexec.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SUEXEC_LDADD)
    EOF
          if test ! -z "\$(MOD_SUEXEC_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SUEXEC_LDADD)\""
        AP_LIBS="\$(MOD_SUEXEC_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SUEXEC_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_suexec.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  $objects \$(MOD_SUEXEC_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SUEXEC_LDADD"
    
    
    
      fi
    
    
    # Is mod_cgid needed?
    case $host in
        *mingw*)
                    cgid_needed="no"
            ;;
        *)
            if ap_mpm_is_threaded; then
                                                    cgid_needed="yes"
            else
                                        cgid_needed="no"
            fi
            ;;
    esac
    
    if test $cgid_needed = "yes"; then
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cgid" >&5
    printf %s "checking whether to enable mod_cgid... " >&6; }
        # Check whether --enable-cgid was given.
    if test ${enable_cgid+y}
    then :
      enableval=$enable_cgid; force_cgid=$enableval
    else $as_nop
      enable_cgid=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_cgid" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cgid" = "static" -o "$enable_cgid" = "shared"; then
        :
      elif test "$enable_cgid" = "yes"; then
        enable_cgid=$module_default
      elif test "$enable_cgid" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgid=$module_default
        else
          enable_cgid=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgid" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cgid=$module_default
        else
          enable_cgid=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgid" = "all" -o "$enable_cgid" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgid=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgid=no
        fi
      elif test "$enable_cgid" = "reallyall" -o "$enable_cgid" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cgid" != "no" ; then
          enable_cgid=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgid=no
        fi
      else
        enable_cgid=no
      fi
      if test "$enable_cgid" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                :
    
        case $host in
          *-solaris2*)
            case `uname -r` in
              5.10)
                        case `uname -p` in
                i386)
                  patch_id="120665"
                  ;;
                sparc)
                  patch_id="120664"
                  ;;
                *)
                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Unknown platform" >&5
    printf "%s\n" "$as_me: WARNING: Unknown platform" >&2;}
                  patch_id="120664"
                  ;;
              esac
              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Solaris patch $patch_id" >&5
    printf %s "checking for Solaris patch $patch_id... " >&6; }
              showrev -p | grep "$patch_id" >/dev/null 2>&1
              if test $? -eq 1; then
                                  as_fn_error $? "Please apply either patch # 120664 (Sparc) or # 120665 (x86).
    Without these patches, mod_cgid is non-functional on Solaris 10 due to an OS
    bug with AF_UNIX sockets.
    If you can not apply these patches, you can do one of the following:
     - run configure with --disable-cgid
     - switch to the prefork MPM
    For more info: <http://issues.apache.org/bugzilla/show_bug.cgi?id=34264>" "$LINENO" 5
              else
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    printf "%s\n" "yes" >&6; }
              fi
              ;;
            esac
            ;;
        esac
    
                :
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cgid" >&5
    printf %s "checking whether to enable mod_cgid... " >&6; }
                if test "$enable_cgid" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_cgid has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cgid$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cgid$_apmod_extra_msg" >&6; }
      if test "$enable_cgid" != "no"; then
        case "$enable_cgid" in
        static*)
          MODLIST="$MODLIST cgid"
          if test "cgid" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cgid"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cgid"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_cgid.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cgid.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CGID_LDADD)
    EOF
          if test ! -z "\$(MOD_CGID_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CGID_LDADD)\""
        AP_LIBS="\$(MOD_CGID_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CGID_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cgid.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  $objects \$(MOD_CGID_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CGID_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cgi" >&5
    printf %s "checking whether to enable mod_cgi... " >&6; }
        # Check whether --enable-cgi was given.
    if test ${enable_cgi+y}
    then :
      enableval=$enable_cgi; force_cgi=$enableval
    else $as_nop
      enable_cgi=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_cgi" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cgi" = "static" -o "$enable_cgi" = "shared"; then
        :
      elif test "$enable_cgi" = "yes"; then
        enable_cgi=$module_default
      elif test "$enable_cgi" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgi=$module_default
        else
          enable_cgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgi" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cgi=$module_default
        else
          enable_cgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgi" = "all" -o "$enable_cgi" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgi=no
        fi
      elif test "$enable_cgi" = "reallyall" -o "$enable_cgi" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cgi" != "no" ; then
          enable_cgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgi=no
        fi
      else
        enable_cgi=no
      fi
      if test "$enable_cgi" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cgi$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cgi$_apmod_extra_msg" >&6; }
      if test "$enable_cgi" != "no"; then
        case "$enable_cgi" in
        static*)
          MODLIST="$MODLIST cgi"
          if test "cgi" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cgi"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cgi"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_cgi.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cgi.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CGI_LDADD)
    EOF
          if test ! -z "\$(MOD_CGI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CGI_LDADD)\""
        AP_LIBS="\$(MOD_CGI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CGI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cgi.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  $objects \$(MOD_CGI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CGI_LDADD"
    
    
    
      fi
    
    else
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cgi" >&5
    printf %s "checking whether to enable mod_cgi... " >&6; }
        # Check whether --enable-cgi was given.
    if test ${enable_cgi+y}
    then :
      enableval=$enable_cgi; force_cgi=$enableval
    else $as_nop
      enable_cgi=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_cgi" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cgi" = "static" -o "$enable_cgi" = "shared"; then
        :
      elif test "$enable_cgi" = "yes"; then
        enable_cgi=$module_default
      elif test "$enable_cgi" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgi=$module_default
        else
          enable_cgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgi" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cgi=$module_default
        else
          enable_cgi=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgi" = "all" -o "$enable_cgi" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgi=no
        fi
      elif test "$enable_cgi" = "reallyall" -o "$enable_cgi" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cgi" != "no" ; then
          enable_cgi=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgi=no
        fi
      else
        enable_cgi=no
      fi
      if test "$enable_cgi" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cgi$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cgi$_apmod_extra_msg" >&6; }
      if test "$enable_cgi" != "no"; then
        case "$enable_cgi" in
        static*)
          MODLIST="$MODLIST cgi"
          if test "cgi" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cgi"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cgi"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_cgi.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cgi.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CGI_LDADD)
    EOF
          if test ! -z "\$(MOD_CGI_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CGI_LDADD)\""
        AP_LIBS="\$(MOD_CGI_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CGI_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cgi.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  $objects \$(MOD_CGI_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CGI_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_cgid" >&5
    printf %s "checking whether to enable mod_cgid... " >&6; }
        # Check whether --enable-cgid was given.
    if test ${enable_cgid+y}
    then :
      enableval=$enable_cgid; force_cgid=$enableval
    else $as_nop
      enable_cgid=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_cgid" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_cgid" = "static" -o "$enable_cgid" = "shared"; then
        :
      elif test "$enable_cgid" = "yes"; then
        enable_cgid=$module_default
      elif test "$enable_cgid" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgid=$module_default
        else
          enable_cgid=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgid" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_cgid=$module_default
        else
          enable_cgid=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_cgid" = "all" -o "$enable_cgid" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_cgid=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgid=no
        fi
      elif test "$enable_cgid" = "reallyall" -o "$enable_cgid" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_cgid" != "no" ; then
          enable_cgid=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_cgid=no
        fi
      else
        enable_cgid=no
      fi
      if test "$enable_cgid" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cgid$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_cgid$_apmod_extra_msg" >&6; }
      if test "$enable_cgid" != "no"; then
        case "$enable_cgid" in
        static*)
          MODLIST="$MODLIST cgid"
          if test "cgid" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES cgid"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},cgid"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_cgid.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_cgid.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_CGID_LDADD)
    EOF
          if test ! -z "\$(MOD_CGID_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_CGID_LDADD)\""
        AP_LIBS="\$(MOD_CGID_LDADD)"
      else
        apr_addto_bugger="\$(MOD_CGID_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_cgid.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  $objects \$(MOD_CGID_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_CGID_LDADD"
    
    
    
      fi
    
    fi
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    # Check whether --enable-cgid-fdpassing was given.
    if test ${enable_cgid_fdpassing+y}
    then :
      enableval=$enable_cgid_fdpassing; if test "$enableval" = "yes"; then
         ac_fn_check_decl "$LINENO" "CMSG_DATA" "ac_cv_have_decl_CMSG_DATA" "
    #include <sys/types.h>
    #include <sys/socket.h>
    " "$ac_c_undeclared_builtin_options" "CFLAGS"
    if test "x$ac_cv_have_decl_CMSG_DATA" = xyes
    then :
    
    printf "%s\n" "#define HAVE_CGID_FDPASSING 1" >>confdefs.h
    
    else $as_nop
      as_fn_error $? "cannot support mod_cgid fd-passing on this system" "$LINENO" 5
    fi
      fi
    
    fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
        if ap_mpm_is_enabled mpmt_os2; then
            if test -z "mpmt_os2.lo mpmt_os2_child.lo"; then
                objects="mpmt_os2.lo"
            else
                objects="mpmt_os2.lo mpmt_os2_child.lo"
            fi
    
            if test -z ""; then
                mpmpath="server/mpm/mpmt_os2"
            else
                mpmpath=
            fi
    
                    test -d $mpmpath || $srcdir/build/mkdir.sh $mpmpath
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES $mpmpath/Makefile"
    
    
            if test -z "$enable_mpm_mpmt_os2"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\""
        AP_LIBS=""
      else
        apr_addto_bugger=""
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
                libname="libmpmt_os2.la"
                cat >$mpmpath/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
            else
                apache_need_shared=yes
                libname="mod_mpm_mpmt_os2.la"
                shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
                cat >$mpmpath/modules.mk<<EOF
    $libname: $shobjects
    	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $objects
    DISTCLEAN_TARGETS = modules.mk
    static =
    shared = $libname
    EOF
                MPM_MODULES="$MPM_MODULES mpm_mpmt_os2"
                # add default MPM to LoadModule list
                if test mpmt_os2 = $default_mpm; then
                    ENABLED_MPM_MODULE="mpm_mpmt_os2"
                fi
            fi
    
    
      if test "x$CFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting CFLAGS to \"-Zmt\""
        CFLAGS="-Zmt"
      else
        apr_addto_bugger="-Zmt"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $CFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to CFLAGS"
            CFLAGS="$CFLAGS $i"
          fi
        done
      fi
    
    
        fi
    
    
    
    
      current_dir=dav/fs
      modpath_current=modules/dav/fs
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d dav/fs || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    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
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dav_fs" >&5
    printf %s "checking whether to enable mod_dav_fs... " >&6; }
        # Check whether --enable-dav-fs was given.
    if test ${enable_dav_fs+y}
    then :
      enableval=$enable_dav_fs; force_dav_fs=$enableval
    else $as_nop
      enable_dav_fs=$dav_fs_enable
    fi
    
        _apmod_extra_msg=""
          case "$enable_dav_fs" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_dav_fs" = "static" -o "$enable_dav_fs" = "shared"; then
        :
      elif test "$enable_dav_fs" = "yes"; then
        enable_dav_fs=$module_default
      elif test "$enable_dav_fs" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dav_fs=$module_default
        else
          enable_dav_fs=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dav_fs" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_dav_fs=$module_default
        else
          enable_dav_fs=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dav_fs" = "all" -o "$enable_dav_fs" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dav_fs=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dav_fs=no
        fi
      elif test "$enable_dav_fs" = "reallyall" -o "$enable_dav_fs" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_dav_fs" != "no" ; then
          enable_dav_fs=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dav_fs=no
        fi
      else
        enable_dav_fs=no
      fi
      if test "$enable_dav_fs" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_dav" = "no" ; then
                                  enable_dav_fs=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_dav is disabled but required for mod_dav_fs\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_dav is disabled but required for mod_dav_fs\"" >&2;}
                                elif test "$enable_dav_fs" = "static" && test "$enable_dav" != "static" ; then
                                  enable_dav_fs=$enable_dav
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_dav_fs shared because mod_dav is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_dav_fs shared because mod_dav is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dav_fs" >&5
    printf %s "checking whether to enable mod_dav_fs... " >&6; }
                if test "$enable_dav_fs" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_dav_fs has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_dav_fs$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_dav_fs$_apmod_extra_msg" >&6; }
      if test "$enable_dav_fs" != "no"; then
        case "$enable_dav_fs" in
        static*)
          MODLIST="$MODLIST dav_fs"
          if test "dav_fs" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES dav_fs"
          if test "$dav_fs_enable" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},dav_fs"
          fi
          ;;
        esac
    
    
      if test -z "$dav_fs_objects"; then
        objects="mod_dav_fs.lo"
      else
        objects="$dav_fs_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_dav_fs.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DAV_FS_LDADD)
    EOF
          if test ! -z "\$(MOD_DAV_FS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DAV_FS_LDADD)\""
        AP_LIBS="\$(MOD_DAV_FS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DAV_FS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_dav_fs.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  $objects \$(MOD_DAV_FS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DAV_FS_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
      current_dir=dav/lock
      modpath_current=modules/dav/lock
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d dav/lock || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    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
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dav_lock" >&5
    printf %s "checking whether to enable mod_dav_lock... " >&6; }
        # Check whether --enable-dav-lock was given.
    if test ${enable_dav_lock+y}
    then :
      enableval=$enable_dav_lock; force_dav_lock=$enableval
    else $as_nop
      enable_dav_lock=maybe-all
    fi
    
        _apmod_extra_msg=""
          case "$enable_dav_lock" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_dav_lock" = "static" -o "$enable_dav_lock" = "shared"; then
        :
      elif test "$enable_dav_lock" = "yes"; then
        enable_dav_lock=$module_default
      elif test "$enable_dav_lock" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dav_lock=$module_default
        else
          enable_dav_lock=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dav_lock" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_dav_lock=$module_default
        else
          enable_dav_lock=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dav_lock" = "all" -o "$enable_dav_lock" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dav_lock=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dav_lock=no
        fi
      elif test "$enable_dav_lock" = "reallyall" -o "$enable_dav_lock" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_dav_lock" != "no" ; then
          enable_dav_lock=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dav_lock=no
        fi
      else
        enable_dav_lock=no
      fi
      if test "$enable_dav_lock" != "no"; then
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: checking dependencies" >&5
    printf "%s\n" "checking dependencies" >&6; }
                if test "$enable_dav" = "no" ; then
                                  enable_dav_lock=no
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"mod_dav is disabled but required for mod_dav_lock\"" >&5
    printf "%s\n" "$as_me: WARNING: \"mod_dav is disabled but required for mod_dav_lock\"" >&2;}
                                elif test "$enable_dav_lock" = "static" && test "$enable_dav" != "static" ; then
                                  enable_dav_lock=$enable_dav
                                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: \"building mod_dav_lock shared because mod_dav is built shared\"" >&5
    printf "%s\n" "$as_me: WARNING: \"building mod_dav_lock shared because mod_dav is built shared\"" >&2;}
                                else
                :
                fi
                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dav_lock" >&5
    printf %s "checking whether to enable mod_dav_lock... " >&6; }
                if test "$enable_dav_lock" = "no"; then
                  if test "$_apmod_required" = "no"; then
                    _apmod_extra_msg=" (disabled)"
                  else
                    as_fn_error $? "mod_dav_lock has been requested but can not be built due to prerequisite failures" "$LINENO" 5
                  fi
                fi
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_dav_lock$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_dav_lock$_apmod_extra_msg" >&6; }
      if test "$enable_dav_lock" != "no"; then
        case "$enable_dav_lock" in
        static*)
          MODLIST="$MODLIST dav_lock"
          if test "dav_lock" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES dav_lock"
          if test "" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},dav_lock"
          fi
          ;;
        esac
    
    
      if test -z "$dav_lock_objects"; then
        objects="mod_dav_lock.lo"
      else
        objects="$dav_lock_objects"
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_dav_lock.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DAV_LOCK_LDADD)
    EOF
          if test ! -z "\$(MOD_DAV_LOCK_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DAV_LOCK_LDADD)\""
        AP_LIBS="\$(MOD_DAV_LOCK_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DAV_LOCK_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_dav_lock.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  $objects \$(MOD_DAV_LOCK_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DAV_LOCK_LDADD"
    
    
    
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for extra modules" >&5
    printf %s "checking for extra modules... " >&6; }
    
    # Check whether --with-module was given.
    if test ${with_module+y}
    then :
      withval=$with_module;
        withval=`echo $withval | sed -e 's/,/ /g'`
        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<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    DISTCLEAN_TARGETS = modules.mk
    static = $libname
    shared =
    EOF
          else
            cat >>$modpath_current/modules.mk.tmp<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects
    EOF
            cat $modpath_current/modules.mk >> $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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
        done
        if test ! -z "$EXTRA_MODLIST"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: added:$EXTRA_MODLIST" >&5
    printf "%s\n" "added:$EXTRA_MODLIST" >&6; }
        fi
    
    else $as_nop
       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
    printf "%s\n" "none" >&6; }
    
    fi
    
    
    
    
    
      current_dir=mappers
      modpath_current=modules/mappers
      modpath_static=
      modpath_shared=
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        eval MOD_$var=
      done
      test -d mappers || $srcdir/build/mkdir.sh $modpath_current
      > $modpath_current/modules.mk
    
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_vhost_alias" >&5
    printf %s "checking whether to enable mod_vhost_alias... " >&6; }
        # Check whether --enable-vhost-alias was given.
    if test ${enable_vhost_alias+y}
    then :
      enableval=$enable_vhost_alias; force_vhost_alias=$enableval
    else $as_nop
      enable_vhost_alias=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_vhost_alias" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_vhost_alias" = "static" -o "$enable_vhost_alias" = "shared"; then
        :
      elif test "$enable_vhost_alias" = "yes"; then
        enable_vhost_alias=$module_default
      elif test "$enable_vhost_alias" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_vhost_alias=$module_default
        else
          enable_vhost_alias=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_vhost_alias" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_vhost_alias=$module_default
        else
          enable_vhost_alias=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_vhost_alias" = "all" -o "$enable_vhost_alias" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_vhost_alias=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_vhost_alias=no
        fi
      elif test "$enable_vhost_alias" = "reallyall" -o "$enable_vhost_alias" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_vhost_alias" != "no" ; then
          enable_vhost_alias=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_vhost_alias=no
        fi
      else
        enable_vhost_alias=no
      fi
      if test "$enable_vhost_alias" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_vhost_alias$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_vhost_alias$_apmod_extra_msg" >&6; }
      if test "$enable_vhost_alias" != "no"; then
        case "$enable_vhost_alias" in
        static*)
          MODLIST="$MODLIST vhost_alias"
          if test "vhost_alias" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES vhost_alias"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},vhost_alias"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_vhost_alias.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_vhost_alias.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_VHOST_ALIAS_LDADD)
    EOF
          if test ! -z "\$(MOD_VHOST_ALIAS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_VHOST_ALIAS_LDADD)\""
        AP_LIBS="\$(MOD_VHOST_ALIAS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_VHOST_ALIAS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_vhost_alias.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  $objects \$(MOD_VHOST_ALIAS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_VHOST_ALIAS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_negotiation" >&5
    printf %s "checking whether to enable mod_negotiation... " >&6; }
        # Check whether --enable-negotiation was given.
    if test ${enable_negotiation+y}
    then :
      enableval=$enable_negotiation; force_negotiation=$enableval
    else $as_nop
      enable_negotiation=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_negotiation" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_negotiation" = "static" -o "$enable_negotiation" = "shared"; then
        :
      elif test "$enable_negotiation" = "yes"; then
        enable_negotiation=$module_default
      elif test "$enable_negotiation" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_negotiation=$module_default
        else
          enable_negotiation=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_negotiation" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_negotiation=$module_default
        else
          enable_negotiation=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_negotiation" = "all" -o "$enable_negotiation" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_negotiation=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_negotiation=no
        fi
      elif test "$enable_negotiation" = "reallyall" -o "$enable_negotiation" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_negotiation" != "no" ; then
          enable_negotiation=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_negotiation=no
        fi
      else
        enable_negotiation=no
      fi
      if test "$enable_negotiation" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_negotiation$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_negotiation$_apmod_extra_msg" >&6; }
      if test "$enable_negotiation" != "no"; then
        case "$enable_negotiation" in
        static*)
          MODLIST="$MODLIST negotiation"
          if test "negotiation" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES negotiation"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},negotiation"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_negotiation.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_negotiation.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_NEGOTIATION_LDADD)
    EOF
          if test ! -z "\$(MOD_NEGOTIATION_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_NEGOTIATION_LDADD)\""
        AP_LIBS="\$(MOD_NEGOTIATION_LDADD)"
      else
        apr_addto_bugger="\$(MOD_NEGOTIATION_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_negotiation.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  $objects \$(MOD_NEGOTIATION_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_NEGOTIATION_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_dir" >&5
    printf %s "checking whether to enable mod_dir... " >&6; }
        # Check whether --enable-dir was given.
    if test ${enable_dir+y}
    then :
      enableval=$enable_dir; force_dir=$enableval
    else $as_nop
      enable_dir=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_dir" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_dir" = "static" -o "$enable_dir" = "shared"; then
        :
      elif test "$enable_dir" = "yes"; then
        enable_dir=$module_default
      elif test "$enable_dir" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dir=$module_default
        else
          enable_dir=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dir" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_dir=$module_default
        else
          enable_dir=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_dir" = "all" -o "$enable_dir" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_dir=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dir=no
        fi
      elif test "$enable_dir" = "reallyall" -o "$enable_dir" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_dir" != "no" ; then
          enable_dir=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_dir=no
        fi
      else
        enable_dir=no
      fi
      if test "$enable_dir" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_dir$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_dir$_apmod_extra_msg" >&6; }
      if test "$enable_dir" != "no"; then
        case "$enable_dir" in
        static*)
          MODLIST="$MODLIST dir"
          if test "dir" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES dir"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},dir"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_dir.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_dir.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_DIR_LDADD)
    EOF
          if test ! -z "\$(MOD_DIR_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_DIR_LDADD)\""
        AP_LIBS="\$(MOD_DIR_LDADD)"
      else
        apr_addto_bugger="\$(MOD_DIR_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_dir.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  $objects \$(MOD_DIR_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_DIR_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_imagemap" >&5
    printf %s "checking whether to enable mod_imagemap... " >&6; }
        # Check whether --enable-imagemap was given.
    if test ${enable_imagemap+y}
    then :
      enableval=$enable_imagemap; force_imagemap=$enableval
    else $as_nop
      enable_imagemap=no
    fi
    
        _apmod_extra_msg=""
          case "$enable_imagemap" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_imagemap" = "static" -o "$enable_imagemap" = "shared"; then
        :
      elif test "$enable_imagemap" = "yes"; then
        enable_imagemap=$module_default
      elif test "$enable_imagemap" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_imagemap=$module_default
        else
          enable_imagemap=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_imagemap" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_imagemap=$module_default
        else
          enable_imagemap=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_imagemap" = "all" -o "$enable_imagemap" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_imagemap=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_imagemap=no
        fi
      elif test "$enable_imagemap" = "reallyall" -o "$enable_imagemap" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_imagemap" != "no" ; then
          enable_imagemap=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_imagemap=no
        fi
      else
        enable_imagemap=no
      fi
      if test "$enable_imagemap" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_imagemap$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_imagemap$_apmod_extra_msg" >&6; }
      if test "$enable_imagemap" != "no"; then
        case "$enable_imagemap" in
        static*)
          MODLIST="$MODLIST imagemap"
          if test "imagemap" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES imagemap"
          if test "no" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},imagemap"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_imagemap.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_imagemap.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_IMAGEMAP_LDADD)
    EOF
          if test ! -z "\$(MOD_IMAGEMAP_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_IMAGEMAP_LDADD)\""
        AP_LIBS="\$(MOD_IMAGEMAP_LDADD)"
      else
        apr_addto_bugger="\$(MOD_IMAGEMAP_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_imagemap.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  $objects \$(MOD_IMAGEMAP_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_IMAGEMAP_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_actions" >&5
    printf %s "checking whether to enable mod_actions... " >&6; }
        # Check whether --enable-actions was given.
    if test ${enable_actions+y}
    then :
      enableval=$enable_actions; force_actions=$enableval
    else $as_nop
      enable_actions=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_actions" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_actions" = "static" -o "$enable_actions" = "shared"; then
        :
      elif test "$enable_actions" = "yes"; then
        enable_actions=$module_default
      elif test "$enable_actions" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_actions=$module_default
        else
          enable_actions=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_actions" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_actions=$module_default
        else
          enable_actions=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_actions" = "all" -o "$enable_actions" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_actions=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_actions=no
        fi
      elif test "$enable_actions" = "reallyall" -o "$enable_actions" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_actions" != "no" ; then
          enable_actions=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_actions=no
        fi
      else
        enable_actions=no
      fi
      if test "$enable_actions" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_actions$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_actions$_apmod_extra_msg" >&6; }
      if test "$enable_actions" != "no"; then
        case "$enable_actions" in
        static*)
          MODLIST="$MODLIST actions"
          if test "actions" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES actions"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},actions"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_actions.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_actions.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ACTIONS_LDADD)
    EOF
          if test ! -z "\$(MOD_ACTIONS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ACTIONS_LDADD)\""
        AP_LIBS="\$(MOD_ACTIONS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ACTIONS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_actions.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  $objects \$(MOD_ACTIONS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ACTIONS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_speling" >&5
    printf %s "checking whether to enable mod_speling... " >&6; }
        # Check whether --enable-speling was given.
    if test ${enable_speling+y}
    then :
      enableval=$enable_speling; force_speling=$enableval
    else $as_nop
      enable_speling=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_speling" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_speling" = "static" -o "$enable_speling" = "shared"; then
        :
      elif test "$enable_speling" = "yes"; then
        enable_speling=$module_default
      elif test "$enable_speling" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_speling=$module_default
        else
          enable_speling=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_speling" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_speling=$module_default
        else
          enable_speling=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_speling" = "all" -o "$enable_speling" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_speling=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_speling=no
        fi
      elif test "$enable_speling" = "reallyall" -o "$enable_speling" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_speling" != "no" ; then
          enable_speling=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_speling=no
        fi
      else
        enable_speling=no
      fi
      if test "$enable_speling" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_speling$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_speling$_apmod_extra_msg" >&6; }
      if test "$enable_speling" != "no"; then
        case "$enable_speling" in
        static*)
          MODLIST="$MODLIST speling"
          if test "speling" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES speling"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},speling"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_speling.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_speling.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_SPELING_LDADD)
    EOF
          if test ! -z "\$(MOD_SPELING_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_SPELING_LDADD)\""
        AP_LIBS="\$(MOD_SPELING_LDADD)"
      else
        apr_addto_bugger="\$(MOD_SPELING_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_speling.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  $objects \$(MOD_SPELING_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_SPELING_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_userdir" >&5
    printf %s "checking whether to enable mod_userdir... " >&6; }
        # Check whether --enable-userdir was given.
    if test ${enable_userdir+y}
    then :
      enableval=$enable_userdir; force_userdir=$enableval
    else $as_nop
      enable_userdir=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_userdir" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_userdir" = "static" -o "$enable_userdir" = "shared"; then
        :
      elif test "$enable_userdir" = "yes"; then
        enable_userdir=$module_default
      elif test "$enable_userdir" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_userdir=$module_default
        else
          enable_userdir=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_userdir" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_userdir=$module_default
        else
          enable_userdir=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_userdir" = "all" -o "$enable_userdir" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_userdir=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_userdir=no
        fi
      elif test "$enable_userdir" = "reallyall" -o "$enable_userdir" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_userdir" != "no" ; then
          enable_userdir=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_userdir=no
        fi
      else
        enable_userdir=no
      fi
      if test "$enable_userdir" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_userdir$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_userdir$_apmod_extra_msg" >&6; }
      if test "$enable_userdir" != "no"; then
        case "$enable_userdir" in
        static*)
          MODLIST="$MODLIST userdir"
          if test "userdir" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES userdir"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},userdir"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_userdir.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_userdir.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_USERDIR_LDADD)
    EOF
          if test ! -z "\$(MOD_USERDIR_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_USERDIR_LDADD)\""
        AP_LIBS="\$(MOD_USERDIR_LDADD)"
      else
        apr_addto_bugger="\$(MOD_USERDIR_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_userdir.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  $objects \$(MOD_USERDIR_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_USERDIR_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_alias" >&5
    printf %s "checking whether to enable mod_alias... " >&6; }
        # Check whether --enable-alias was given.
    if test ${enable_alias+y}
    then :
      enableval=$enable_alias; force_alias=$enableval
    else $as_nop
      enable_alias=yes
    fi
    
        _apmod_extra_msg=""
          case "$enable_alias" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_alias" = "static" -o "$enable_alias" = "shared"; then
        :
      elif test "$enable_alias" = "yes"; then
        enable_alias=$module_default
      elif test "$enable_alias" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_alias=$module_default
        else
          enable_alias=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_alias" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_alias=$module_default
        else
          enable_alias=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_alias" = "all" -o "$enable_alias" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_alias=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_alias=no
        fi
      elif test "$enable_alias" = "reallyall" -o "$enable_alias" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_alias" != "no" ; then
          enable_alias=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_alias=no
        fi
      else
        enable_alias=no
      fi
      if test "$enable_alias" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_alias$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_alias$_apmod_extra_msg" >&6; }
      if test "$enable_alias" != "no"; then
        case "$enable_alias" in
        static*)
          MODLIST="$MODLIST alias"
          if test "alias" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES alias"
          if test "yes" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},alias"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_alias.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_alias.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_ALIAS_LDADD)
    EOF
          if test ! -z "\$(MOD_ALIAS_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_ALIAS_LDADD)\""
        AP_LIBS="\$(MOD_ALIAS_LDADD)"
      else
        apr_addto_bugger="\$(MOD_ALIAS_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_alias.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  $objects \$(MOD_ALIAS_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_ALIAS_LDADD"
    
    
    
      fi
    
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable mod_rewrite" >&5
    printf %s "checking whether to enable mod_rewrite... " >&6; }
        # Check whether --enable-rewrite was given.
    if test ${enable_rewrite+y}
    then :
      enableval=$enable_rewrite; force_rewrite=$enableval
    else $as_nop
      enable_rewrite=most
    fi
    
        _apmod_extra_msg=""
          case "$enable_rewrite" in
        yes|static|shared)
          _apmod_required="yes"
          ;;
        *)
          _apmod_required="no"
          ;;
      esac
      if test "$enable_rewrite" = "static" -o "$enable_rewrite" = "shared"; then
        :
      elif test "$enable_rewrite" = "yes"; then
        enable_rewrite=$module_default
      elif test "$enable_rewrite" = "few"; then
        if test "$module_selection" = "few" -o "$module_selection" = "most" -o \
                "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_rewrite=$module_default
        else
          enable_rewrite=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_rewrite" = "most"; then
        if test "$module_selection" = "most" -o "$module_selection" = "all" -o \
                "$module_selection" = "reallyall"
        then
          enable_rewrite=$module_default
        else
          enable_rewrite=no
        fi
        _apmod_extra_msg=" ($module_selection)"
      elif test "$enable_rewrite" = "all" -o "$enable_rewrite" = "maybe-all"; then
        if test "$module_selection" = "all" -o "$module_selection" = "reallyall"
        then
          enable_rewrite=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_rewrite=no
        fi
      elif test "$enable_rewrite" = "reallyall" -o "$enable_rewrite" = "no" ; then
        if test "$module_selection" = "reallyall" -a "$force_rewrite" != "no" ; then
          enable_rewrite=$module_default
          _apmod_extra_msg=" ($module_selection)"
        else
          enable_rewrite=no
        fi
      else
        enable_rewrite=no
      fi
      if test "$enable_rewrite" != "no"; then
                :
      fi
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_rewrite$_apmod_extra_msg" >&5
    printf "%s\n" "$enable_rewrite$_apmod_extra_msg" >&6; }
      if test "$enable_rewrite" != "no"; then
        case "$enable_rewrite" in
        static*)
          MODLIST="$MODLIST rewrite"
          if test "rewrite" = "so"; then
              sharedobjs=yes
          fi
          shared="";;
        *)
          sharedobjs=yes
          shared=yes
          DSO_MODULES="$DSO_MODULES rewrite"
          if test "most" = "yes" ; then
            ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},rewrite"
          fi
          ;;
        esac
    
    
      if test -z ""; then
        objects="mod_rewrite.lo"
      else
        objects=""
      fi
    
      if test -z "$module_standalone"; then
        if test -z "$shared"; then
          # The filename of a convenience library must have a "lib" prefix:
          libname="libmod_rewrite.la"
          BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
          modpath_static="$modpath_static $libname"
          cat >>$modpath_current/modules.mk<<EOF
    $libname: $objects
    	\$(MOD_LINK) $objects \$(MOD_REWRITE_LDADD)
    EOF
          if test ! -z "\$(MOD_REWRITE_LDADD)"; then
    
      if test "x$AP_LIBS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\$(MOD_REWRITE_LDADD)\""
        AP_LIBS="\$(MOD_REWRITE_LDADD)"
      else
        apr_addto_bugger="\$(MOD_REWRITE_LDADD)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $AP_LIBS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
            AP_LIBS="$AP_LIBS $i"
          fi
        done
      fi
    
          fi
        else
          apache_need_shared=yes
          libname="mod_rewrite.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  $objects \$(MOD_REWRITE_LDADD)
    EOF
        fi
      fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MOD_REWRITE_LDADD"
    
    
    
      fi
    
    
    if test "x$enable_rewrite" != "xno"; then
        # mod_rewrite needs test_char.h
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_builddir)/server\""
        INCLUDES="-I\$(top_builddir)/server"
      else
        apr_addto_bugger="-I\$(top_builddir)/server"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    fi
    
    
      if test "x$INCLUDES" = "x"; then
        test "x$silent" != "xyes" && echo "  setting INCLUDES to \"-I\$(top_srcdir)/$modpath_current\""
        INCLUDES="-I\$(top_srcdir)/$modpath_current"
      else
        apr_addto_bugger="-I\$(top_srcdir)/$modpath_current"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $INCLUDES; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to INCLUDES"
            INCLUDES="$INCLUDES $i"
          fi
        done
      fi
    
    
    
      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
      for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS LIBS INCLUDES; do
        if eval val=\"\$MOD_$var\"; test -n "$val"; then
          echo "MOD_$var = $val" >> $modpath_current/modules.mk
        fi
      done
      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_FILES="$APACHE_FAST_OUTPUT_FILES $modpath_current/Makefile"
    
    
    
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST progname"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST OS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST OS_DIR"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST BUILTIN_LIBS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SHLIBPATH_VAR"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST OS_SPECIFIC_VARS"
    
    
    
    PRE_SHARED_CMDS='echo ""'
    POST_SHARED_CMDS='echo ""'
    
    
    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
    
    
    if test "$enable_so" = "yes" -o "$enable_so" = "static"; then
      case $host in
        *-ibm-aix*)
    
      if test "x$HTTPD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting HTTPD_LDFLAGS to \"-Wl,-uXML_Parse -Wl,-bE:$abs_builddir/server/httpd.exp\""
        HTTPD_LDFLAGS="-Wl,-uXML_Parse -Wl,-bE:$abs_builddir/server/httpd.exp"
      else
        apr_addto_bugger="-Wl,-uXML_Parse -Wl,-bE:$abs_builddir/server/httpd.exp"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $HTTPD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to HTTPD_LDFLAGS"
            HTTPD_LDFLAGS="$HTTPD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$SH_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting SH_LDFLAGS to \"\$(EXTRA_LDFLAGS) \$(EXTRA_LIBS)\""
        SH_LDFLAGS="\$(EXTRA_LDFLAGS) \$(EXTRA_LIBS)"
      else
        apr_addto_bugger="\$(EXTRA_LDFLAGS) \$(EXTRA_LIBS)"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $SH_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to SH_LDFLAGS"
            SH_LDFLAGS="$SH_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$UTIL_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting UTIL_LDFLAGS to \"-Wl,-uXML_Parse\""
        UTIL_LDFLAGS="-Wl,-uXML_Parse"
      else
        apr_addto_bugger="-Wl,-uXML_Parse"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $UTIL_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to UTIL_LDFLAGS"
            UTIL_LDFLAGS="$UTIL_LDFLAGS $i"
          fi
        done
      fi
    
          ;;
        *os390)
    
      if test "x$HTTPD_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting HTTPD_LDFLAGS to \"--main=$abs_srcdir/server/main.o --core-dll=$abs_srcdir/apachecore.dll\""
        HTTPD_LDFLAGS="--main=$abs_srcdir/server/main.o --core-dll=$abs_srcdir/apachecore.dll"
      else
        apr_addto_bugger="--main=$abs_srcdir/server/main.o --core-dll=$abs_srcdir/apachecore.dll"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $HTTPD_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to HTTPD_LDFLAGS"
            HTTPD_LDFLAGS="$HTTPD_LDFLAGS $i"
          fi
        done
      fi
    
    
      if test "x$SH_LDFLAGS" = "x"; then
        test "x$silent" != "xyes" && echo "  setting SH_LDFLAGS to \"--core-dll=$abs_srcdir/apachecore.dll\""
        SH_LDFLAGS="--core-dll=$abs_srcdir/apachecore.dll"
      else
        apr_addto_bugger="--core-dll=$abs_srcdir/apachecore.dll"
        for i in $apr_addto_bugger; do
          apr_addto_duplicate="0"
          for j in $SH_LDFLAGS; do
            if test "x$i" = "x$j"; then
              apr_addto_duplicate="1"
              break
            fi
          done
          if test $apr_addto_duplicate = "0"; then
            test "x$silent" != "xyes" && echo "  adding \"$i\" to SH_LDFLAGS"
            SH_LDFLAGS="$SH_LDFLAGS $i"
          fi
        done
      fi
    
      esac
      MOD_SO_ENABLED=yes
    fi
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST PRE_SHARED_CMDS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST POST_SHARED_CMDS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST shared_build"
    
    
    
    
    # Check whether --with-program-name was given.
    if test ${with_program_name+y}
    then :
      withval=$with_program_name;
      progname="$withval"
    else $as_nop
    
      progname="httpd"
    fi
    
    
    # SuExec parameters
    
    # Check whether --with-suexec-bin was given.
    if test ${with_suexec_bin+y}
    then :
      withval=$with_suexec_bin;
    
    printf "%s\n" "#define SUEXEC_BIN \"$withval\"" >>confdefs.h
    
    
    fi
    
    
    
    # Check whether --with-suexec-caller was given.
    if test ${with_suexec_caller+y}
    then :
      withval=$with_suexec_caller;
    
    printf "%s\n" "#define AP_HTTPD_USER \"$withval\"" >>confdefs.h
    
    fi
    
    
    
    # Check whether --with-suexec-userdir was given.
    if test ${with_suexec_userdir+y}
    then :
      withval=$with_suexec_userdir;
    
    printf "%s\n" "#define AP_USERDIR_SUFFIX \"$withval\"" >>confdefs.h
    
    fi
    
    
    
    # Check whether --with-suexec-docroot was given.
    if test ${with_suexec_docroot+y}
    then :
      withval=$with_suexec_docroot;
    
    printf "%s\n" "#define AP_DOC_ROOT \"$withval\"" >>confdefs.h
    
    fi
    
    
    
    # Check whether --with-suexec-uidmin was given.
    if test ${with_suexec_uidmin+y}
    then :
      withval=$with_suexec_uidmin;
    
    printf "%s\n" "#define AP_UID_MIN $withval" >>confdefs.h
    
    fi
    
    
    
    # Check whether --with-suexec-gidmin was given.
    if test ${with_suexec_gidmin+y}
    then :
      withval=$with_suexec_gidmin;
    
    printf "%s\n" "#define AP_GID_MIN $withval" >>confdefs.h
    
    fi
    
    
    
    # Check whether --with-suexec-logfile was given.
    if test ${with_suexec_logfile+y}
    then :
      withval=$with_suexec_logfile;
      if test "x$withval" = "xyes"; then
        as_fn_error $? "log filename required for --with-suexec-logfile option" "$LINENO" 5
      elif test "x$withval" != "xno"; then
    
    printf "%s\n" "#define AP_LOG_EXEC \"$withval\"" >>confdefs.h
    
      fi
    
    fi
    
    
    
    # Check whether --with-suexec-syslog was given.
    if test ${with_suexec_syslog+y}
    then :
      withval=$with_suexec_syslog;
      if test $withval = "yes"; then
        if test "x${with_suexec_logfile}" != "xno"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: hint: use \"--without-suexec-logfile --with-suexec-syslog\"" >&5
    printf "%s\n" "$as_me: hint: use \"--without-suexec-logfile --with-suexec-syslog\"" >&6;}
          as_fn_error $? "suexec does not support both logging to file and syslog" "$LINENO" 5
        fi
    
      for ac_func in vsyslog
    do :
      ac_fn_c_check_func "$LINENO" "vsyslog" "ac_cv_func_vsyslog"
    if test "x$ac_cv_func_vsyslog" = xyes
    then :
      printf "%s\n" "#define HAVE_VSYSLOG 1" >>confdefs.h
    
    else $as_nop
    
           as_fn_error $? "cannot support syslog from suexec without vsyslog()" "$LINENO" 5
    fi
    
    done
    
    printf "%s\n" "#define AP_LOG_SYSLOG 1" >>confdefs.h
    
      fi
    
    fi
    
    
    
    
    # Check whether --with-suexec-safepath was given.
    if test ${with_suexec_safepath+y}
    then :
      withval=$with_suexec_safepath;
    
    printf "%s\n" "#define AP_SAFE_PATH \"$withval\"" >>confdefs.h
    
    fi
    
    
    
    # Check whether --with-suexec-umask was given.
    if test ${with_suexec_umask+y}
    then :
      withval=$with_suexec_umask;
    
    printf "%s\n" "#define AP_SUEXEC_UMASK 0$withval" >>confdefs.h
    
    fi
    
    
    INSTALL_SUEXEC=setuid
    # Check whether --enable-suexec-capabilities was given.
    if test ${enable_suexec_capabilities+y}
    then :
      enableval=$enable_suexec_capabilities;
    INSTALL_SUEXEC=caps
    
    printf "%s\n" "#define AP_SUEXEC_CAPABILITIES 1" >>confdefs.h
    
    
    fi
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST INSTALL_SUEXEC"
    
    
    
    if test x${apu_found} != xobsolete; then
      AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool --libs`"
    fi
    AP_LIBS="$AP_LIBS `$apr_config --link-libtool --libs`"
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST AP_LIBS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST AP_BUILD_SRCLIB_DIRS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST AP_CLEAN_SRCLIB_DIRS"
    
    
    
    
    printf "%s\n" "#define AP_USING_AUTOCONF 1" >>confdefs.h
    
    
    if test "$SINGLE_LISTEN_UNSERIALIZED_ACCEPT" = "1"; then
    
    printf "%s\n" "#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT 1" >>confdefs.h
    
    fi
    
    if test "$AP_NONBLOCK_WHEN_MULTI_LISTEN" = "1"; then
    
    printf "%s\n" "#define AP_NONBLOCK_WHEN_MULTI_LISTEN 1" >>confdefs.h
    
    fi
    
    
    apr_old_cppflags=$CPPFLAGS
    CPPFLAGS="$CPPFLAGS $INCLUDES"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h.  */
    
    #include <apr.h>
    #if APR_HAVE_IPV6
    YES_IS_DEFINED
    #endif
    
    _ACEOF
    if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
      $EGREP "YES_IS_DEFINED" >/dev/null 2>&1
    then :
      ac_cv_define_APR_HAVE_IPV6=yes
    else $as_nop
      ac_cv_define_APR_HAVE_IPV6=no
    fi
    rm -rf conftest*
    
    CPPFLAGS=$apr_old_cppflags
    
    
    # Check whether --enable-v4-mapped was given.
    if test ${enable_v4_mapped+y}
    then :
      enableval=$enable_v4_mapped;
      v4mapped=$enableval
    
    else $as_nop
    
        case $host in
        *freebsd[1234].*)
            v4mapped=yes
            ;;
        *freebsd*|*netbsd*|*openbsd*)
            v4mapped=no
            ;;
        *)
            v4mapped=yes
            ;;
        esac
        if ap_mpm_is_enabled winnt; then
                    v4mapped=no
        fi
    
    fi
    
    
    if test $v4mapped = "yes" -a $ac_cv_define_APR_HAVE_IPV6 = "yes"; then
    
    printf "%s\n" "#define AP_ENABLE_V4_MAPPED 1" >>confdefs.h
    
    fi
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES Makefile modules/Makefile srclib/Makefile"
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES os/Makefile server/Makefile"
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES support/Makefile"
    
    
    if test -d ./test; then
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES test/Makefile"
    
    fi
    if test -d ./test/modules/http2; then
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES test/Makefile"
    
        ac_config_files="$ac_config_files test/pyhttpd/config.ini"
    
    
      APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES test/clients/Makefile"
    
    fi
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Restore user-defined environment settings..." >&5
    printf "%s\n" "$as_me: Restore user-defined environment settings..." >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    
    APACHE_CONF_SEL_CC=${CC}
    APACHE_CONF_SEL_CFLAGS="${CFLAGS} ${EXTRA_CFLAGS} ${NOTEST_CFLAGS}"
    APACHE_CONF_SEL_CPPFLAGS="${CPPFLAGS} ${EXTRA_CPPFLAGS} ${NOTEST_CPPFLAGS}"
    APACHE_CONF_SEL_LDFLAGS="${LDFLAGS} ${EXTRA_LDFLAGS} ${NOTEST_LDFLAGS}"
    APACHE_CONF_SEL_LIBS="${LIBS} ${EXTRA_LIBS} ${NOTEST_LIBS}"
    APACHE_CONF_SEL_CPP=${CPP}
    
    
    set X $apr_ste_save_CPPFLAGS
    if test ${#} -eq 1; then
      EXTRA_CPPFLAGS="$CPPFLAGS"
      CPPFLAGS=
    else
      if test "x$apr_ste_save_CPPFLAGS" = "x$CPPFLAGS"; then
        EXTRA_CPPFLAGS=
      else
        EXTRA_CPPFLAGS=`echo "$CPPFLAGS" | sed -e "s%${apr_ste_save_CPPFLAGS}%%"`
        CPPFLAGS="$apr_ste_save_CPPFLAGS"
      fi
    fi
    if test "x$silent" != "xyes"; then
      echo "  restoring CPPFLAGS to \"$CPPFLAGS\""
      echo "  setting EXTRA_CPPFLAGS to \"$EXTRA_CPPFLAGS\""
    fi
    
    
    
    set X $apr_ste_save_CFLAGS
    if test ${#} -eq 1; then
      EXTRA_CFLAGS="$CFLAGS"
      CFLAGS=
    else
      if test "x$apr_ste_save_CFLAGS" = "x$CFLAGS"; then
        EXTRA_CFLAGS=
      else
        EXTRA_CFLAGS=`echo "$CFLAGS" | sed -e "s%${apr_ste_save_CFLAGS}%%"`
        CFLAGS="$apr_ste_save_CFLAGS"
      fi
    fi
    if test "x$silent" != "xyes"; then
      echo "  restoring CFLAGS to \"$CFLAGS\""
      echo "  setting EXTRA_CFLAGS to \"$EXTRA_CFLAGS\""
    fi
    
    
    
    set X $apr_ste_save_CXXFLAGS
    if test ${#} -eq 1; then
      EXTRA_CXXFLAGS="$CXXFLAGS"
      CXXFLAGS=
    else
      if test "x$apr_ste_save_CXXFLAGS" = "x$CXXFLAGS"; then
        EXTRA_CXXFLAGS=
      else
        EXTRA_CXXFLAGS=`echo "$CXXFLAGS" | sed -e "s%${apr_ste_save_CXXFLAGS}%%"`
        CXXFLAGS="$apr_ste_save_CXXFLAGS"
      fi
    fi
    if test "x$silent" != "xyes"; then
      echo "  restoring CXXFLAGS to \"$CXXFLAGS\""
      echo "  setting EXTRA_CXXFLAGS to \"$EXTRA_CXXFLAGS\""
    fi
    
    
    
    set X $apr_ste_save_LDFLAGS
    if test ${#} -eq 1; then
      EXTRA_LDFLAGS="$LDFLAGS"
      LDFLAGS=
    else
      if test "x$apr_ste_save_LDFLAGS" = "x$LDFLAGS"; then
        EXTRA_LDFLAGS=
      else
        EXTRA_LDFLAGS=`echo "$LDFLAGS" | sed -e "s%${apr_ste_save_LDFLAGS}%%"`
        LDFLAGS="$apr_ste_save_LDFLAGS"
      fi
    fi
    if test "x$silent" != "xyes"; then
      echo "  restoring LDFLAGS to \"$LDFLAGS\""
      echo "  setting EXTRA_LDFLAGS to \"$EXTRA_LDFLAGS\""
    fi
    
    
    
    set X $apr_ste_save_LIBS
    if test ${#} -eq 1; then
      EXTRA_LIBS="$LIBS"
      LIBS=
    else
      if test "x$apr_ste_save_LIBS" = "x$LIBS"; then
        EXTRA_LIBS=
      else
        EXTRA_LIBS=`echo "$LIBS" | sed -e "s%${apr_ste_save_LIBS}%%"`
        LIBS="$apr_ste_save_LIBS"
      fi
    fi
    if test "x$silent" != "xyes"; then
      echo "  restoring LIBS to \"$LIBS\""
      echo "  setting EXTRA_LIBS to \"$EXTRA_LIBS\""
    fi
    
    
    
    set X $apr_ste_save_INCLUDES
    if test ${#} -eq 1; then
      EXTRA_INCLUDES="$INCLUDES"
      INCLUDES=
    else
      if test "x$apr_ste_save_INCLUDES" = "x$INCLUDES"; then
        EXTRA_INCLUDES=
      else
        EXTRA_INCLUDES=`echo "$INCLUDES" | sed -e "s%${apr_ste_save_INCLUDES}%%"`
        INCLUDES="$apr_ste_save_INCLUDES"
      fi
    fi
    if test "x$silent" != "xyes"; then
      echo "  restoring INCLUDES to \"$INCLUDES\""
      echo "  setting EXTRA_INCLUDES to \"$EXTRA_INCLUDES\""
    fi
    
    
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Construct makefiles and header files..." >&5
    printf "%s\n" "$as_me: Construct makefiles and header files..." >&6;}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5
    printf "%s\n" "$as_me: " >&6;}
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST HTTPD_VERSION"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST HTTPD_MMN"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST abs_srcdir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST bindir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST sbindir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST cgidir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST logfiledir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST exec_prefix"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST datadir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST localstatedir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST mandir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST libdir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST libexecdir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST htdocsdir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST manualdir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST includedir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST errordir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST iconsdir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST sysconfdir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST installbuilddir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST runtimedir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST proxycachedir"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST other_targets"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST progname"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST prefix"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST AWK"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CC"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CPP"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CXX"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CPPFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CXXFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST LTFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST LDFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST LT_LDFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SH_LDFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST HTTPD_LDFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST UTIL_LDFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST LIBS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST DEFS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST INCLUDES"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST NOTEST_CPPFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST NOTEST_CFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST NOTEST_CXXFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST NOTEST_LDFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST NOTEST_LIBS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST EXTRA_CPPFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST EXTRA_CFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST EXTRA_CXXFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST EXTRA_LDFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST EXTRA_LIBS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST EXTRA_INCLUDES"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST INTERNAL_CPPFLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST LIBTOOL"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SHELL"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST RSYNC"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SVN"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MODULE_DIRS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MODULE_CLEANDIRS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST PORT"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SSLPORT"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CORE_IMPLIB_FILE"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST CORE_IMPLIB"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SH_LIBS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST SH_LIBTOOL"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MK_IMPLIB"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MKDEP"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST INSTALL_PROG_FLAGS"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST MPM_MODULES"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ENABLED_MPM_MODULE"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST DSO_MODULES"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST ENABLED_DSO_MODULES"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST LOAD_ALL_MODULES"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APR_BINDIR"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APR_INCLUDEDIR"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APR_VERSION"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APR_CONFIG"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APU_BINDIR"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APU_INCLUDEDIR"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APU_VERSION"
    
    
    
      APACHE_VAR_SUBST="$APACHE_VAR_SUBST APU_CONFIG"
    
    
    
      abs_srcdir="`(cd $srcdir && pwd)`"
    
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating config_vars.mk" >&5
    printf "%s\n" "$as_me: creating config_vars.mk" >&6;}
      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
    
    
    rm -f modules.c
    echo $MODLIST | $AWK -f $srcdir/build/build-modules-c.awk > modules.c
    
    
    ap_last=
    ap_cur="$prefix"
    while test "x${ap_cur}" != "x${ap_last}";
    do
      ap_last="${ap_cur}"
      ap_cur=`eval "echo ${ap_cur}"`
    done
    ap_prefix="${ap_cur}"
    
    
    printf "%s\n" "#define HTTPD_ROOT \"${ap_prefix}\"" >>confdefs.h
    
    
    printf "%s\n" "#define SERVER_CONFIG_FILE \"${rel_sysconfdir}/${progname}.conf\"" >>confdefs.h
    
    
    printf "%s\n" "#define AP_TYPES_CONFIG_FILE \"${rel_sysconfdir}/mime.types\"" >>confdefs.h
    
    
    perlbin=`$ac_aux_dir/PrintPath perl`
    if test "x$perlbin" = "x"; then
        perlbin="/replace/with/path/to/perl/interpreter"
    fi
    
    
    
    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
    
    
    
    test -d docs/conf||$mkdir_p docs/conf
    
    ac_config_files="$ac_config_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 docs/conf/extra/proxy-html.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 build/config_vars.sh"
    
    ac_config_commands="$ac_config_commands default"
    
    cat >confcache <<\_ACEOF
    # This file is a shell script that caches the results of configure
    # tests run on this system so they can be shared between configure
    # scripts and configure runs, see configure's option --config-cache.
    # It is not useful on other systems.  If it contains results you don't
    # want to keep, you may remove or edit it.
    #
    # config.status only pays attention to the cache file if you give it
    # the --recheck option to rerun configure.
    #
    # `ac_cv_env_foo' variables (set or unset) will be overridden when
    # loading this file, other *unset* `ac_cv_foo' will be assigned the
    # following values.
    
    _ACEOF
    
    # The following way of writing the cache mishandles newlines in values,
    # but we know of no workaround that is simple, portable, and efficient.
    # So, we kill variables containing newlines.
    # Ultrix sh set writes to stderr and can't be redirected directly,
    # and sets the high bit in the cache file unless we assign to the vars.
    (
      for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
        eval ac_val=\$$ac_var
        case $ac_val in #(
        *${as_nl}*)
          case $ac_var in #(
          *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
    printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
          esac
          case $ac_var in #(
          _ | IFS | as_nl) ;; #(
          BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
          *) { eval $ac_var=; unset $ac_var;} ;;
          esac ;;
        esac
      done
    
      (set) 2>&1 |
        case $as_nl`(ac_space=' '; set) 2>&1` in #(
        *${as_nl}ac_space=\ *)
          # `set' does not quote correctly, so add quotes: double-quote
          # substitution turns \\\\ into \\, and sed turns \\ into \.
          sed -n \
    	"s/'/'\\\\''/g;
    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
          ;; #(
        *)
          # `set' quotes correctly as required by POSIX, so do not add quotes.
          sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
          ;;
        esac |
        sort
    ) |
      sed '
         /^ac_cv_env_/b end
         t clear
         :clear
         s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
         t end
         s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
         :end' >>confcache
    if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
      if test -w "$cache_file"; then
        if test "x$cache_file" != "x/dev/null"; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
    printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
          if test ! -f "$cache_file" || test -h "$cache_file"; then
    	cat confcache >"$cache_file"
          else
            case $cache_file in #(
            */* | ?:*)
    	  mv -f confcache "$cache_file"$$ &&
    	  mv -f "$cache_file"$$ "$cache_file" ;; #(
            *)
    	  mv -f confcache "$cache_file" ;;
    	esac
          fi
        fi
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
    printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
      fi
    fi
    rm -f confcache
    
    test "x$prefix" = xNONE && prefix=$ac_default_prefix
    # Let make expand exec_prefix.
    test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
    
    DEFS=-DHAVE_CONFIG_H
    
    ac_libobjs=
    ac_ltlibobjs=
    U=
    for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
      # 1. Remove the extension, and $U if already installed.
      ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
      ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
      # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
      #    will be set to the directory where LIBOBJS objects are built.
      as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
      as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
    done
    LIBOBJS=$ac_libobjs
    
    LTLIBOBJS=$ac_ltlibobjs
    
    
    
    : "${CONFIG_STATUS=./config.status}"
    ac_write_fail=0
    ac_clean_files_save=$ac_clean_files
    ac_clean_files="$ac_clean_files $CONFIG_STATUS"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
    printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
    as_write_fail=0
    cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
    #! $SHELL
    # Generated by $as_me.
    # Run this file to recreate the current configuration.
    # Compiler output produced by configure, useful for debugging
    # configure, is in config.log if it exists.
    
    debug=false
    ac_cs_recheck=false
    ac_cs_silent=false
    
    SHELL=\${CONFIG_SHELL-$SHELL}
    export SHELL
    _ASEOF
    cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
    ## -------------------- ##
    ## M4sh Initialization. ##
    ## -------------------- ##
    
    # Be more Bourne compatible
    DUALCASE=1; export DUALCASE # for MKS sh
    as_nop=:
    if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
    then :
      emulate sh
      NULLCMD=:
      # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
      # is contrary to our usage.  Disable this feature.
      alias -g '${1+"$@"}'='"$@"'
      setopt NO_GLOB_SUBST
    else $as_nop
      case `(set -o) 2>/dev/null` in #(
      *posix*) :
        set -o posix ;; #(
      *) :
         ;;
    esac
    fi
    
    
    
    # Reset variables that may have inherited troublesome values from
    # the environment.
    
    # IFS needs to be set, to space, tab, and newline, in precisely that order.
    # (If _AS_PATH_WALK were called with IFS unset, it would have the
    # side effect of setting IFS to empty, thus disabling word splitting.)
    # Quoting is to prevent editors from complaining about space-tab.
    as_nl='
    '
    export as_nl
    IFS=" ""	$as_nl"
    
    PS1='$ '
    PS2='> '
    PS4='+ '
    
    # Ensure predictable behavior from utilities with locale-dependent output.
    LC_ALL=C
    export LC_ALL
    LANGUAGE=C
    export LANGUAGE
    
    # We cannot yet rely on "unset" to work, but we need these variables
    # to be unset--not just set to an empty or harmless value--now, to
    # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
    # also avoids known problems related to "unset" and subshell syntax
    # in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
    for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
    do eval test \${$as_var+y} \
      && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
    done
    
    # Ensure that fds 0, 1, and 2 are open.
    if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
    if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
    if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
    
    # The user is always right.
    if ${PATH_SEPARATOR+false} :; then
      PATH_SEPARATOR=:
      (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
        (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
          PATH_SEPARATOR=';'
      }
    fi
    
    
    # Find who we are.  Look in the path if we contain no directory separator.
    as_myself=
    case $0 in #((
      *[\\/]* ) as_myself=$0 ;;
      *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    for as_dir in $PATH
    do
      IFS=$as_save_IFS
      case $as_dir in #(((
        '') as_dir=./ ;;
        */) ;;
        *) as_dir=$as_dir/ ;;
      esac
        test -r "$as_dir$0" && as_myself=$as_dir$0 && break
      done
    IFS=$as_save_IFS
    
         ;;
    esac
    # We did not find ourselves, most probably we were run as `sh COMMAND'
    # in which case we are not to be found in the path.
    if test "x$as_myself" = x; then
      as_myself=$0
    fi
    if test ! -f "$as_myself"; then
      printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
      exit 1
    fi
    
    
    
    # as_fn_error STATUS ERROR [LINENO LOG_FD]
    # ----------------------------------------
    # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
    # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
    # script with STATUS, using 1 if that was 0.
    as_fn_error ()
    {
      as_status=$1; test $as_status -eq 0 && as_status=1
      if test "$4"; then
        as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
        printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
      fi
      printf "%s\n" "$as_me: error: $2" >&2
      as_fn_exit $as_status
    } # as_fn_error
    
    
    
    # as_fn_set_status STATUS
    # -----------------------
    # Set $? to STATUS, without forking.
    as_fn_set_status ()
    {
      return $1
    } # as_fn_set_status
    
    # as_fn_exit STATUS
    # -----------------
    # Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
    as_fn_exit ()
    {
      set +e
      as_fn_set_status $1
      exit $1
    } # as_fn_exit
    
    # as_fn_unset VAR
    # ---------------
    # Portably unset VAR.
    as_fn_unset ()
    {
      { eval $1=; unset $1;}
    }
    as_unset=as_fn_unset
    
    # as_fn_append VAR VALUE
    # ----------------------
    # Append the text in VALUE to the end of the definition contained in VAR. Take
    # advantage of any shell optimizations that allow amortized linear growth over
    # repeated appends, instead of the typical quadratic growth present in naive
    # implementations.
    if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
    then :
      eval 'as_fn_append ()
      {
        eval $1+=\$2
      }'
    else $as_nop
      as_fn_append ()
      {
        eval $1=\$$1\$2
      }
    fi # as_fn_append
    
    # as_fn_arith ARG...
    # ------------------
    # Perform arithmetic evaluation on the ARGs, and store the result in the
    # global $as_val. Take advantage of shells that can avoid forks. The arguments
    # must be portable across $(()) and expr.
    if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
    then :
      eval 'as_fn_arith ()
      {
        as_val=$(( $* ))
      }'
    else $as_nop
      as_fn_arith ()
      {
        as_val=`expr "$@" || test $? -eq 1`
      }
    fi # as_fn_arith
    
    
    if expr a : '\(a\)' >/dev/null 2>&1 &&
       test "X`expr 00001 : '.*\(...\)'`" = X001; then
      as_expr=expr
    else
      as_expr=false
    fi
    
    if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
      as_basename=basename
    else
      as_basename=false
    fi
    
    if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
      as_dirname=dirname
    else
      as_dirname=false
    fi
    
    as_me=`$as_basename -- "$0" ||
    $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
    	 X"$0" : 'X\(//\)$' \| \
    	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
    printf "%s\n" X/"$0" |
        sed '/^.*\/\([^/][^/]*\)\/*$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\/\(\/\/\)$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\/\(\/\).*/{
    	    s//\1/
    	    q
    	  }
    	  s/.*/./; q'`
    
    # Avoid depending upon Character Ranges.
    as_cr_letters='abcdefghijklmnopqrstuvwxyz'
    as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    as_cr_Letters=$as_cr_letters$as_cr_LETTERS
    as_cr_digits='0123456789'
    as_cr_alnum=$as_cr_Letters$as_cr_digits
    
    
    # Determine whether it's possible to make 'echo' print without a newline.
    # These variables are no longer used directly by Autoconf, but are AC_SUBSTed
    # for compatibility with existing Makefiles.
    ECHO_C= ECHO_N= ECHO_T=
    case `echo -n x` in #(((((
    -n*)
      case `echo 'xy\c'` in
      *c*) ECHO_T='	';;	# ECHO_T is single tab character.
      xy)  ECHO_C='\c';;
      *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
           ECHO_T='	';;
      esac;;
    *)
      ECHO_N='-n';;
    esac
    
    # For backward compatibility with old third-party macros, we provide
    # the shell variables $as_echo and $as_echo_n.  New code should use
    # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
    as_echo='printf %s\n'
    as_echo_n='printf %s'
    
    rm -f conf$$ conf$$.exe conf$$.file
    if test -d conf$$.dir; then
      rm -f conf$$.dir/conf$$.file
    else
      rm -f conf$$.dir
      mkdir conf$$.dir 2>/dev/null
    fi
    if (echo >conf$$.file) 2>/dev/null; then
      if ln -s conf$$.file conf$$ 2>/dev/null; then
        as_ln_s='ln -s'
        # ... but there are two gotchas:
        # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
        # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
        # In both cases, we have to default to `cp -pR'.
        ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
          as_ln_s='cp -pR'
      elif ln conf$$.file conf$$ 2>/dev/null; then
        as_ln_s=ln
      else
        as_ln_s='cp -pR'
      fi
    else
      as_ln_s='cp -pR'
    fi
    rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
    rmdir conf$$.dir 2>/dev/null
    
    
    # as_fn_mkdir_p
    # -------------
    # Create "$as_dir" as a directory, including parents if necessary.
    as_fn_mkdir_p ()
    {
    
      case $as_dir in #(
      -*) as_dir=./$as_dir;;
      esac
      test -d "$as_dir" || eval $as_mkdir_p || {
        as_dirs=
        while :; do
          case $as_dir in #(
          *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
          *) as_qdir=$as_dir;;
          esac
          as_dirs="'$as_qdir' $as_dirs"
          as_dir=`$as_dirname -- "$as_dir" ||
    $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
    	 X"$as_dir" : 'X\(//\)[^/]' \| \
    	 X"$as_dir" : 'X\(//\)$' \| \
    	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
    printf "%s\n" X"$as_dir" |
        sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)[^/].*/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\).*/{
    	    s//\1/
    	    q
    	  }
    	  s/.*/./; q'`
          test -d "$as_dir" && break
        done
        test -z "$as_dirs" || eval "mkdir $as_dirs"
      } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
    
    
    } # as_fn_mkdir_p
    if mkdir -p . 2>/dev/null; then
      as_mkdir_p='mkdir -p "$as_dir"'
    else
      test -d ./-p && rmdir ./-p
      as_mkdir_p=false
    fi
    
    
    # as_fn_executable_p FILE
    # -----------------------
    # Test if FILE is an executable regular file.
    as_fn_executable_p ()
    {
      test -f "$1" && test -x "$1"
    } # as_fn_executable_p
    as_test_x='test -x'
    as_executable_p=as_fn_executable_p
    
    # Sed expression to map a string onto a valid CPP name.
    as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
    
    # Sed expression to map a string onto a valid variable name.
    as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
    
    
    exec 6>&1
    ## ----------------------------------- ##
    ## Main body of $CONFIG_STATUS script. ##
    ## ----------------------------------- ##
    _ASEOF
    test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
    
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    # Save the log message, to keep $0 and so on meaningful, and to
    # report actual input values of CONFIG_FILES etc. instead of their
    # values after options handling.
    ac_log="
    This file was extended by $as_me, which was
    generated by GNU Autoconf 2.71.  Invocation command line was
    
      CONFIG_FILES    = $CONFIG_FILES
      CONFIG_HEADERS  = $CONFIG_HEADERS
      CONFIG_LINKS    = $CONFIG_LINKS
      CONFIG_COMMANDS = $CONFIG_COMMANDS
      $ $0 $@
    
    on `(hostname || uname -n) 2>/dev/null | sed 1q`
    "
    
    _ACEOF
    
    case $ac_config_files in *"
    "*) set x $ac_config_files; shift; ac_config_files=$*;;
    esac
    
    case $ac_config_headers in *"
    "*) set x $ac_config_headers; shift; ac_config_headers=$*;;
    esac
    
    
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
    # Files that config.status was made for.
    config_files="$ac_config_files"
    config_headers="$ac_config_headers"
    config_commands="$ac_config_commands"
    
    _ACEOF
    
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    ac_cs_usage="\
    \`$as_me' instantiates files and other configuration actions
    from templates according to the current configuration.  Unless the files
    and actions are specified as TAGs, all are instantiated by default.
    
    Usage: $0 [OPTION]... [TAG]...
    
      -h, --help       print this help, then exit
      -V, --version    print version number and configuration settings, then exit
          --config     print configuration, then exit
      -q, --quiet, --silent
                       do not print progress messages
      -d, --debug      don't remove temporary files
          --recheck    update $as_me by reconfiguring in the same conditions
          --file=FILE[:TEMPLATE]
                       instantiate the configuration file FILE
          --header=FILE[:TEMPLATE]
                       instantiate the configuration header FILE
    
    Configuration files:
    $config_files
    
    Configuration headers:
    $config_headers
    
    Configuration commands:
    $config_commands
    
    Report bugs to the package provider."
    
    _ACEOF
    ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
    ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
    ac_cs_config='$ac_cs_config_escaped'
    ac_cs_version="\\
    config.status
    configured by $0, generated by GNU Autoconf 2.71,
      with options \\"\$ac_cs_config\\"
    
    Copyright (C) 2021 Free Software Foundation, Inc.
    This config.status script is free software; the Free Software Foundation
    gives unlimited permission to copy, distribute and modify it."
    
    ac_pwd='$ac_pwd'
    srcdir='$srcdir'
    AWK='$AWK'
    test -n "\$AWK" || AWK=awk
    _ACEOF
    
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    # The default lists apply if the user does not specify any file.
    ac_need_defaults=:
    while test $# != 0
    do
      case $1 in
      --*=?*)
        ac_option=`expr "X$1" : 'X\([^=]*\)='`
        ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
        ac_shift=:
        ;;
      --*=)
        ac_option=`expr "X$1" : 'X\([^=]*\)='`
        ac_optarg=
        ac_shift=:
        ;;
      *)
        ac_option=$1
        ac_optarg=$2
        ac_shift=shift
        ;;
      esac
    
      case $ac_option in
      # Handling of the options.
      -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
        ac_cs_recheck=: ;;
      --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
        printf "%s\n" "$ac_cs_version"; exit ;;
      --config | --confi | --conf | --con | --co | --c )
        printf "%s\n" "$ac_cs_config"; exit ;;
      --debug | --debu | --deb | --de | --d | -d )
        debug=: ;;
      --file | --fil | --fi | --f )
        $ac_shift
        case $ac_optarg in
        *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
        '') as_fn_error $? "missing file argument" ;;
        esac
        as_fn_append CONFIG_FILES " '$ac_optarg'"
        ac_need_defaults=false;;
      --header | --heade | --head | --hea )
        $ac_shift
        case $ac_optarg in
        *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
        esac
        as_fn_append CONFIG_HEADERS " '$ac_optarg'"
        ac_need_defaults=false;;
      --he | --h)
        # Conflict between --help and --header
        as_fn_error $? "ambiguous option: \`$1'
    Try \`$0 --help' for more information.";;
      --help | --hel | -h )
        printf "%s\n" "$ac_cs_usage"; exit ;;
      -q | -quiet | --quiet | --quie | --qui | --qu | --q \
      | -silent | --silent | --silen | --sile | --sil | --si | --s)
        ac_cs_silent=: ;;
    
      # This is an error.
      -*) as_fn_error $? "unrecognized option: \`$1'
    Try \`$0 --help' for more information." ;;
    
      *) as_fn_append ac_config_targets " $1"
         ac_need_defaults=false ;;
    
      esac
      shift
    done
    
    ac_configure_extra_args=
    
    if $ac_cs_silent; then
      exec 6>/dev/null
      ac_configure_extra_args="$ac_configure_extra_args --silent"
    fi
    
    _ACEOF
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
    if \$ac_cs_recheck; then
      set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
      shift
      \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
      CONFIG_SHELL='$SHELL'
      export CONFIG_SHELL
      exec "\$@"
    fi
    
    _ACEOF
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    exec 5>>config.log
    {
      echo
      sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
    ## Running $as_me. ##
    _ASBOX
      printf "%s\n" "$ac_log"
    } >&5
    
    _ACEOF
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
    #
    # INIT-COMMANDS
    #
    
      $SHELL $srcdir/build/fastgen.sh $srcdir $ac_cv_mkdir_p $BSD_MAKEFILE $APACHE_FAST_OUTPUT_FILES
    
    
    _ACEOF
    
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    
    # Handling of arguments.
    for ac_config_target in $ac_config_targets
    do
      case $ac_config_target in
        "include/ap_config_auto.h") CONFIG_HEADERS="$CONFIG_HEADERS include/ap_config_auto.h" ;;
        "test/pyhttpd/config.ini") CONFIG_FILES="$CONFIG_FILES test/pyhttpd/config.ini" ;;
        "docs/conf/httpd.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/httpd.conf" ;;
        "docs/conf/extra/httpd-autoindex.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-autoindex.conf" ;;
        "docs/conf/extra/httpd-dav.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-dav.conf" ;;
        "docs/conf/extra/httpd-default.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-default.conf" ;;
        "docs/conf/extra/httpd-info.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-info.conf" ;;
        "docs/conf/extra/httpd-languages.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-languages.conf" ;;
        "docs/conf/extra/httpd-manual.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-manual.conf" ;;
        "docs/conf/extra/httpd-mpm.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-mpm.conf" ;;
        "docs/conf/extra/httpd-multilang-errordoc.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-multilang-errordoc.conf" ;;
        "docs/conf/extra/httpd-ssl.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-ssl.conf" ;;
        "docs/conf/extra/httpd-userdir.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-userdir.conf" ;;
        "docs/conf/extra/httpd-vhosts.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/httpd-vhosts.conf" ;;
        "docs/conf/extra/proxy-html.conf") CONFIG_FILES="$CONFIG_FILES docs/conf/extra/proxy-html.conf" ;;
        "include/ap_config_layout.h") CONFIG_FILES="$CONFIG_FILES include/ap_config_layout.h" ;;
        "support/apxs") CONFIG_FILES="$CONFIG_FILES support/apxs" ;;
        "support/apachectl") CONFIG_FILES="$CONFIG_FILES support/apachectl" ;;
        "support/dbmmanage") CONFIG_FILES="$CONFIG_FILES support/dbmmanage" ;;
        "support/envvars-std") CONFIG_FILES="$CONFIG_FILES support/envvars-std" ;;
        "support/log_server_status") CONFIG_FILES="$CONFIG_FILES support/log_server_status" ;;
        "support/logresolve.pl") CONFIG_FILES="$CONFIG_FILES support/logresolve.pl" ;;
        "support/phf_abuse_log.cgi") CONFIG_FILES="$CONFIG_FILES support/phf_abuse_log.cgi" ;;
        "support/split-logfile") CONFIG_FILES="$CONFIG_FILES support/split-logfile" ;;
        "build/rules.mk") CONFIG_FILES="$CONFIG_FILES build/rules.mk" ;;
        "build/pkg/pkginfo") CONFIG_FILES="$CONFIG_FILES build/pkg/pkginfo" ;;
        "build/config_vars.sh") CONFIG_FILES="$CONFIG_FILES build/config_vars.sh" ;;
        "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
    
      *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
      esac
    done
    
    
    # If the user did not use the arguments to specify the items to instantiate,
    # then the envvar interface is used.  Set only those that are not.
    # We use the long form for the default assignment because of an extremely
    # bizarre bug on SunOS 4.1.3.
    if $ac_need_defaults; then
      test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
      test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
      test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands
    fi
    
    # Have a temporary directory for convenience.  Make it in the build tree
    # simply because there is no reason against having it here, and in addition,
    # creating and moving files from /tmp can sometimes cause problems.
    # Hook for its removal unless debugging.
    # Note that there is a small window in which the directory will not be cleaned:
    # after its creation but before its name has been assigned to `$tmp'.
    $debug ||
    {
      tmp= ac_tmp=
      trap 'exit_status=$?
      : "${ac_tmp:=$tmp}"
      { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
    ' 0
      trap 'as_fn_exit 1' 1 2 13 15
    }
    # Create a (secure) tmp directory for tmp files.
    
    {
      tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
      test -d "$tmp"
    }  ||
    {
      tmp=./conf$$-$RANDOM
      (umask 077 && mkdir "$tmp")
    } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
    ac_tmp=$tmp
    
    # Set up the scripts for CONFIG_FILES section.
    # No need to generate them if there are no CONFIG_FILES.
    # This happens for instance with `./config.status config.h'.
    if test -n "$CONFIG_FILES"; then
    
    
    ac_cr=`echo X | tr X '\015'`
    # On cygwin, bash can eat \r inside `` if the user requested igncr.
    # But we know of no other shell where ac_cr would be empty at this
    # point, so we can use a bashism as a fallback.
    if test "x$ac_cr" = x; then
      eval ac_cr=\$\'\\r\'
    fi
    ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
    if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
      ac_cs_awk_cr='\\r'
    else
      ac_cs_awk_cr=$ac_cr
    fi
    
    echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
    _ACEOF
    
    
    {
      echo "cat >conf$$subs.awk <<_ACEOF" &&
      echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
      echo "_ACEOF"
    } >conf$$subs.sh ||
      as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
    ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
    ac_delim='%!_!# '
    for ac_last_try in false false false false false :; do
      . ./conf$$subs.sh ||
        as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
    
      ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
      if test $ac_delim_n = $ac_delim_num; then
        break
      elif $ac_last_try; then
        as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
      else
        ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
      fi
    done
    rm -f conf$$subs.sh
    
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
    cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
    _ACEOF
    sed -n '
    h
    s/^/S["/; s/!.*/"]=/
    p
    g
    s/^[^!]*!//
    :repl
    t repl
    s/'"$ac_delim"'$//
    t delim
    :nl
    h
    s/\(.\{148\}\)..*/\1/
    t more1
    s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
    p
    n
    b repl
    :more1
    s/["\\]/\\&/g; s/^/"/; s/$/"\\/
    p
    g
    s/.\{148\}//
    t nl
    :delim
    h
    s/\(.\{148\}\)..*/\1/
    t more2
    s/["\\]/\\&/g; s/^/"/; s/$/"/
    p
    b
    :more2
    s/["\\]/\\&/g; s/^/"/; s/$/"\\/
    p
    g
    s/.\{148\}//
    t delim
    ' <conf$$subs.awk | sed '
    /^[^""]/{
      N
      s/\n//
    }
    ' >>$CONFIG_STATUS || ac_write_fail=1
    rm -f conf$$subs.awk
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
    _ACAWK
    cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
      for (key in S) S_is_set[key] = 1
      FS = ""
    
    }
    {
      line = $ 0
      nfields = split(line, field, "@")
      substed = 0
      len = length(field[1])
      for (i = 2; i < nfields; i++) {
        key = field[i]
        keylen = length(key)
        if (S_is_set[key]) {
          value = S[key]
          line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
          len += length(value) + length(field[++i])
          substed = 1
        } else
          len += 1 + keylen
      }
    
      print line
    }
    
    _ACAWK
    _ACEOF
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
      sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
    else
      cat
    fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
      || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
    _ACEOF
    
    # VPATH may cause trouble with some makes, so we remove sole $(srcdir),
    # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
    # trailing colons and then remove the whole line if VPATH becomes empty
    # (actually we leave an empty line to preserve line numbers).
    if test "x$srcdir" = x.; then
      ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
    h
    s///
    s/^/:/
    s/[	 ]*$/:/
    s/:\$(srcdir):/:/g
    s/:\${srcdir}:/:/g
    s/:@srcdir@:/:/g
    s/^:*//
    s/:*$//
    x
    s/\(=[	 ]*\).*/\1/
    G
    s/\n//
    s/^[^=]*=[	 ]*$//
    }'
    fi
    
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    fi # test -n "$CONFIG_FILES"
    
    # Set up the scripts for CONFIG_HEADERS section.
    # No need to generate them if there are no CONFIG_HEADERS.
    # This happens for instance with `./config.status Makefile'.
    if test -n "$CONFIG_HEADERS"; then
    cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
    BEGIN {
    _ACEOF
    
    # Transform confdefs.h into an awk script `defines.awk', embedded as
    # here-document in config.status, that substitutes the proper values into
    # config.h.in to produce config.h.
    
    # Create a delimiter string that does not exist in confdefs.h, to ease
    # handling of long lines.
    ac_delim='%!_!# '
    for ac_last_try in false false :; do
      ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
      if test -z "$ac_tt"; then
        break
      elif $ac_last_try; then
        as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
      else
        ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
      fi
    done
    
    # For the awk script, D is an array of macro values keyed by name,
    # likewise P contains macro parameters if any.  Preserve backslash
    # newline sequences.
    
    ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
    sed -n '
    s/.\{148\}/&'"$ac_delim"'/g
    t rset
    :rset
    s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
    t def
    d
    :def
    s/\\$//
    t bsnl
    s/["\\]/\\&/g
    s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
    D["\1"]=" \3"/p
    s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
    d
    :bsnl
    s/["\\]/\\&/g
    s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
    D["\1"]=" \3\\\\\\n"\\/p
    t cont
    s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
    t cont
    d
    :cont
    n
    s/.\{148\}/&'"$ac_delim"'/g
    t clear
    :clear
    s/\\$//
    t bsnlc
    s/["\\]/\\&/g; s/^/"/; s/$/"/p
    d
    :bsnlc
    s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
    b cont
    ' <confdefs.h | sed '
    s/'"$ac_delim"'/"\\\
    "/g' >>$CONFIG_STATUS || ac_write_fail=1
    
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
      for (key in D) D_is_set[key] = 1
      FS = ""
    }
    /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
      line = \$ 0
      split(line, arg, " ")
      if (arg[1] == "#") {
        defundef = arg[2]
        mac1 = arg[3]
      } else {
        defundef = substr(arg[1], 2)
        mac1 = arg[2]
      }
      split(mac1, mac2, "(") #)
      macro = mac2[1]
      prefix = substr(line, 1, index(line, defundef) - 1)
      if (D_is_set[macro]) {
        # Preserve the white space surrounding the "#".
        print prefix "define", macro P[macro] D[macro]
        next
      } else {
        # Replace #undef with comments.  This is necessary, for example,
        # in the case of _POSIX_SOURCE, which is predefined and required
        # on some systems where configure will not decide to define it.
        if (defundef == "undef") {
          print "/*", prefix defundef, macro, "*/"
          next
        }
      }
    }
    { print }
    _ACAWK
    _ACEOF
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
      as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
    fi # test -n "$CONFIG_HEADERS"
    
    
    eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
    shift
    for ac_tag
    do
      case $ac_tag in
      :[FHLC]) ac_mode=$ac_tag; continue;;
      esac
      case $ac_mode$ac_tag in
      :[FHL]*:*);;
      :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
      :[FH]-) ac_tag=-:-;;
      :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
      esac
      ac_save_IFS=$IFS
      IFS=:
      set x $ac_tag
      IFS=$ac_save_IFS
      shift
      ac_file=$1
      shift
    
      case $ac_mode in
      :L) ac_source=$1;;
      :[FH])
        ac_file_inputs=
        for ac_f
        do
          case $ac_f in
          -) ac_f="$ac_tmp/stdin";;
          *) # Look for the file first in the build tree, then in the source tree
    	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
    	 # because $ac_f cannot contain `:'.
    	 test -f "$ac_f" ||
    	   case $ac_f in
    	   [\\/$]*) false;;
    	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
    	   esac ||
    	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
          esac
          case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
          as_fn_append ac_file_inputs " '$ac_f'"
        done
    
        # Let's still pretend it is `configure' which instantiates (i.e., don't
        # use $as_me), people would be surprised to read:
        #    /* config.h.  Generated by config.status.  */
        configure_input='Generated from '`
    	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
    	`' by configure.'
        if test x"$ac_file" != x-; then
          configure_input="$ac_file.  $configure_input"
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
    printf "%s\n" "$as_me: creating $ac_file" >&6;}
        fi
        # Neutralize special characters interpreted by sed in replacement strings.
        case $configure_input in #(
        *\&* | *\|* | *\\* )
           ac_sed_conf_input=`printf "%s\n" "$configure_input" |
           sed 's/[\\\\&|]/\\\\&/g'`;; #(
        *) ac_sed_conf_input=$configure_input;;
        esac
    
        case $ac_tag in
        *:-:* | *:-) cat >"$ac_tmp/stdin" \
          || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
        esac
        ;;
      esac
    
      ac_dir=`$as_dirname -- "$ac_file" ||
    $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
    	 X"$ac_file" : 'X\(//\)[^/]' \| \
    	 X"$ac_file" : 'X\(//\)$' \| \
    	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
    printf "%s\n" X"$ac_file" |
        sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)[^/].*/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\/\)$/{
    	    s//\1/
    	    q
    	  }
    	  /^X\(\/\).*/{
    	    s//\1/
    	    q
    	  }
    	  s/.*/./; q'`
      as_dir="$ac_dir"; as_fn_mkdir_p
      ac_builddir=.
    
    case "$ac_dir" in
    .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
    *)
      ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
      # A ".." for each directory in $ac_dir_suffix.
      ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
      case $ac_top_builddir_sub in
      "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
      *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
      esac ;;
    esac
    ac_abs_top_builddir=$ac_pwd
    ac_abs_builddir=$ac_pwd$ac_dir_suffix
    # for backward compatibility:
    ac_top_builddir=$ac_top_build_prefix
    
    case $srcdir in
      .)  # We are building in place.
        ac_srcdir=.
        ac_top_srcdir=$ac_top_builddir_sub
        ac_abs_top_srcdir=$ac_pwd ;;
      [\\/]* | ?:[\\/]* )  # Absolute name.
        ac_srcdir=$srcdir$ac_dir_suffix;
        ac_top_srcdir=$srcdir
        ac_abs_top_srcdir=$srcdir ;;
      *) # Relative name.
        ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
        ac_top_srcdir=$ac_top_build_prefix$srcdir
        ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
    esac
    ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
    
    
      case $ac_mode in
      :F)
      #
      # CONFIG_FILE
      #
    
    _ACEOF
    
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    # If the template does not know about datarootdir, expand it.
    # FIXME: This hack should be removed a few years after 2.60.
    ac_datarootdir_hack=; ac_datarootdir_seen=
    ac_sed_dataroot='
    /datarootdir/ {
      p
      q
    }
    /@datadir@/p
    /@docdir@/p
    /@infodir@/p
    /@localedir@/p
    /@mandir@/p'
    case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
    *datarootdir*) ac_datarootdir_seen=yes;;
    *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
    printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
    _ACEOF
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
      ac_datarootdir_hack='
      s&@datadir@&$datadir&g
      s&@docdir@&$docdir&g
      s&@infodir@&$infodir&g
      s&@localedir@&$localedir&g
      s&@mandir@&$mandir&g
      s&\\\${datarootdir}&$datarootdir&g' ;;
    esac
    _ACEOF
    
    # Neutralize VPATH when `$srcdir' = `.'.
    # Shell code in configure.ac might set extrasub.
    # FIXME: do we really want to maintain this feature?
    cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
    ac_sed_extra="$ac_vpsub
    $extrasub
    _ACEOF
    cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
    :t
    /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
    s|@configure_input@|$ac_sed_conf_input|;t t
    s&@top_builddir@&$ac_top_builddir_sub&;t t
    s&@top_build_prefix@&$ac_top_build_prefix&;t t
    s&@srcdir@&$ac_srcdir&;t t
    s&@abs_srcdir@&$ac_abs_srcdir&;t t
    s&@top_srcdir@&$ac_top_srcdir&;t t
    s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
    s&@builddir@&$ac_builddir&;t t
    s&@abs_builddir@&$ac_abs_builddir&;t t
    s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
    $ac_datarootdir_hack
    "
    eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
      >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
    
    test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
      { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
      { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
          "$ac_tmp/out"`; test -z "$ac_out"; } &&
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
    which seems to be undefined.  Please make sure it is defined" >&5
    printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
    which seems to be undefined.  Please make sure it is defined" >&2;}
    
      rm -f "$ac_tmp/stdin"
      case $ac_file in
      -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
      *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
      esac \
      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     ;;
      :H)
      #
      # CONFIG_HEADER
      #
      if test x"$ac_file" != x-; then
        {
          printf "%s\n" "/* $configure_input  */" >&1 \
          && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
        } >"$ac_tmp/config.h" \
          || as_fn_error $? "could not create $ac_file" "$LINENO" 5
        if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
    printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
        else
          rm -f "$ac_file"
          mv "$ac_tmp/config.h" "$ac_file" \
    	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
        fi
      else
        printf "%s\n" "/* $configure_input  */" >&1 \
          && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
          || as_fn_error $? "could not create -" "$LINENO" 5
      fi
     ;;
    
      :C)  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
    printf "%s\n" "$as_me: executing $ac_file commands" >&6;}
     ;;
      esac
    
    
      case $ac_file$ac_mode in
        "default":C) true ;;
    
      esac
    done # for ac_tag
    
    
    as_fn_exit 0
    _ACEOF
    ac_clean_files=$ac_clean_files_save
    
    test $ac_write_fail = 0 ||
      as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
    
    
    # configure is writing to config.log, and then calls config.status.
    # config.status does its own redirection, appending to config.log.
    # Unfortunately, on DOS this fails, as config.log is still kept open
    # by configure, so config.status won't be able to write to it; its
    # output is simply discarded.  So we exec the FD to /dev/null,
    # effectively closing config.log, so it can be properly (re)opened and
    # appended to by config.status.  When coming back to configure, we
    # need to make the FD available again.
    if test "$no_create" != yes; then
      ac_cs_success=:
      ac_config_status_args=
      test "$silent" = yes &&
        ac_config_status_args="$ac_config_status_args --quiet"
      exec 5>/dev/null
      $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
      exec 5>>config.log
      # Use ||, not &&, to avoid exiting from the if with $? = 1, which
      # would make configure fail if this is the last instruction.
      $ac_cs_success || as_fn_exit 1
    fi
    if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
    printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
    fi
    
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: summary of build options:
    
        Server Version: ${HTTPD_VERSION}
        Install prefix: ${prefix}
        C compiler:     ${APACHE_CONF_SEL_CC}
        CFLAGS:         ${APACHE_CONF_SEL_CFLAGS}
        CPPFLAGS:       ${APACHE_CONF_SEL_CPPFLAGS}
        LDFLAGS:        ${APACHE_CONF_SEL_LDFLAGS}
        LIBS:           ${APACHE_CONF_SEL_LIBS}
        C preprocessor: ${APACHE_CONF_SEL_CPP}
    " >&5
    printf "%s\n" "$as_me: summary of build options:
    
        Server Version: ${HTTPD_VERSION}
        Install prefix: ${prefix}
        C compiler:     ${APACHE_CONF_SEL_CC}
        CFLAGS:         ${APACHE_CONF_SEL_CFLAGS}
        CPPFLAGS:       ${APACHE_CONF_SEL_CPPFLAGS}
        LDFLAGS:        ${APACHE_CONF_SEL_LDFLAGS}
        LIBS:           ${APACHE_CONF_SEL_LIBS}
        C preprocessor: ${APACHE_CONF_SEL_CPP}
    " >&6;}
    
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������httpd-2.4.64/httpd.spec�����������������������������������������������������������������������������0000664�0001751�0001751�00000041641�15032766626�014644� 0����������������������������������������������������������������������������������������������������ustar  �covener�������������������������covener����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%define contentdir /var/www
    %define suexec_caller apache
    %define mmn 20120211
    
    Summary: Apache HTTP Server
    Name: httpd
    Version: 2.4.64
    Release: 1
    URL: http://httpd.apache.org/
    Vendor: Apache Software Foundation
    Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
    License: Apache License, Version 2.0
    Group: System Environment/Daemons
    BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
    BuildRequires: autoconf, perl, pkgconfig, findutils
    BuildRequires: zlib-devel, libselinux-devel, libuuid-devel
    BuildRequires: apr-devel >= 1.4.0, apr-util-devel >= 1.4.0, pcre-devel >= 5.0
    Requires: initscripts >= 8.36, /etc/mime.types
    Obsoletes: httpd-suexec
    Requires(pre): /usr/sbin/useradd
    Requires(post): chkconfig
    Provides: webserver
    Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release}
    Provides: httpd-mmn = %{mmn}
    
    %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: apr-devel, apr-util-devel, pkgconfig, libtool
    Requires: httpd = %{version}-%{release}
    
    %description devel
    The httpd-devel package contains the APXS binary and other files
    that you need to build Dynamic Shared Objects (DSOs) for the
    Apache HTTP Server.
    
    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.
    Requires: httpd = :%{version}-%{release}
    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 tools
    Group: System Environment/Daemons
    Summary: Tools for use with the Apache HTTP Server
    
    %description tools
    The httpd-tools package contains tools which can be used with 
    the Apache HTTP Server.
    
    %package -n mod_authnz_ldap
    Group: System Environment/Daemons
    Summary: LDAP modules for the Apache HTTP server
    BuildRequires: openldap-devel
    Requires: httpd = %{version}-%{release}, httpd-mmn = %{mmn}, apr-util-ldap
    
    %description -n mod_authnz_ldap
    The mod_authnz_ldap module for the Apache HTTP server provides
    authentication and authorization against an LDAP server, while
    mod_ldap provides an LDAP cache.
    
    %package -n mod_lua
    Group: System Environment/Daemons
    Summary: Lua language module for the Apache HTTP server
    BuildRequires: lua-devel
    Requires: httpd = %{version}-%{release}, httpd-mmn = %{mmn}
    
    %description -n mod_lua
    The mod_lua module for the Apache HTTP server allows the server to be
    extended with scripts written in the Lua programming language.
    
    %package -n mod_proxy_html
    Group: System Environment/Daemons
    Summary: Proxy HTML filter modules for the Apache HTTP server
    Epoch: 1
    BuildRequires: libxml2-devel
    Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmn}
    
    %description -n mod_proxy_html
    The mod_proxy_html module for the Apache HTTP server provides
    a filter to rewrite HTML links within web content when used within
    a reverse proxy environment. The mod_xml2enc module provides
    enhanced charset/internationalisation support for mod_proxy_html.
    
    %package -n mod_ssl
    Group: System Environment/Daemons
    Summary: SSL/TLS module for the Apache HTTP server
    Epoch: 1
    BuildRequires: openssl-devel
    Requires(post): openssl, /bin/cat
    Requires(pre): httpd
    Requires: httpd = 0:%{version}-%{release}, 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 include/ap_mmn.h | sed -n '
    /^2/p'`
    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
    
    %build
    # forcibly prevent use of bundled apr, apr-util, pcre
    rm -rf srclib/{apr,apr-util,pcre}
    
    %configure \
    	--enable-layout=RPM \
    	--libdir=%{_libdir} \
    	--sysconfdir=%{_sysconfdir}/httpd/conf \
    	--includedir=%{_includedir}/httpd \
    	--libexecdir=%{_libdir}/httpd/modules \
    	--datadir=%{contentdir} \
            --with-installbuilddir=%{_libdir}/httpd/build \
            --enable-mpms-shared=all \
            --with-apr=%{_prefix} --with-apr-util=%{_prefix} \
    	--enable-suexec --with-suexec \
    	--with-suexec-caller=%{suexec_caller} \
    	--with-suexec-docroot=%{contentdir} \
    	--with-suexec-logfile=%{_localstatedir}/log/httpd/suexec.log \
    	--with-suexec-bin=%{_sbindir}/suexec \
    	--with-suexec-uidmin=500 --with-suexec-gidmin=100 \
            --enable-pie \
            --with-pcre \
            --enable-mods-shared=all \
            --enable-ssl --with-ssl --enable-bucketeer \
            --enable-case-filter --enable-case-filter-in \
            --disable-imagemap
    
    make %{?_smp_mflags}
    
    %install
    rm -rf $RPM_BUILD_ROOT
    make DESTDIR=$RPM_BUILD_ROOT install
    
    # 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}
    
    # Make the MMN accessible to module packages
    echo %{mmn} > $RPM_BUILD_ROOT%{_includedir}/httpd/.mmn
    
    # Set up /var directories
    mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/log/httpd
    mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd/cache-root
    
    # 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
    mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d
    
    # 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
    install -m755 ./build/rpm/htcacheclean.init \
            $RPM_BUILD_ROOT/etc/rc.d/init.d/htcacheclean
    
    # 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}/cgi-bin/* 
    
    # Make suexec a+rw so it can be stripped.  %%files lists real permissions
    chmod 755 $RPM_BUILD_ROOT%{_sbindir}/suexec
    
    %pre
    # Add the "apache" user
    /usr/sbin/useradd -c "Apache" -u 48 \
    	-s /sbin/nologin -r -d %{contentdir} apache 2> /dev/null || :
    
    %post
    # Register the httpd service
    /sbin/chkconfig --add httpd
    /sbin/chkconfig --add htcacheclean
    
    %preun
    if [ $1 = 0 ]; then
    	/sbin/service httpd stop > /dev/null 2>&1
            /sbin/service htcacheclean stop > /dev/null 2>&1
    	/sbin/chkconfig --del httpd
            /sbin/chkconfig --del htcacheclean
    fi
    
    %post -n mod_ssl
    umask 077
    
    if [ ! -f %{_sysconfdir}/httpd/conf/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/server.key 2> /dev/null
    fi
    
    FQDN=`hostname`
    if [ "x${FQDN}" = "x" ]; then
       FQDN=localhost.localdomain
    fi
    
    if [ ! -f %{_sysconfdir}/httpd/conf/server.crt ] ; then
    cat << EOF | %{_bindir}/openssl req -new -key %{_sysconfdir}/httpd/conf/server.key -x509 -days 365 -out %{_sysconfdir}/httpd/conf/server.crt 2>/dev/null
    --
    SomeState
    SomeCity
    SomeOrganization
    SomeOrganizationalUnit
    ${FQDN}
    root@${FQDN}
    EOF
    fi
    
    %check
    # Check the built modules are all PIC
    if readelf -d $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so | grep TEXTREL; then
       : modules contain non-relocatable code
       exit 1
    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
    %dir %{_sysconfdir}/httpd/conf.d
    %config(noreplace) %{_sysconfdir}/httpd/conf/httpd.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/magic
    %config(noreplace) %{_sysconfdir}/httpd/conf/mime.types
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-autoindex.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-dav.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-default.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-info.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-languages.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-manual.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-mpm.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-multilang-errordoc.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-userdir.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-vhosts.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/proxy-html.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-autoindex.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-dav.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-default.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-info.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-languages.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-manual.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-mpm.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-multilang-errordoc.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-userdir.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-vhosts.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/proxy-html.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/httpd.conf
    
    %config %{_sysconfdir}/logrotate.d/httpd
    %config %{_sysconfdir}/rc.d/init.d/httpd
    %config %{_sysconfdir}/rc.d/init.d/htcacheclean
    
    %{_sbindir}/fcgistarter
    %{_sbindir}/htcacheclean
    %{_sbindir}/httpd
    %{_sbindir}/apachectl
    %attr(4510,root,%{suexec_caller}) %{_sbindir}/suexec
    
    %dir %{_libdir}/httpd
    %dir %{_libdir}/httpd/modules
    %{_libdir}/httpd/modules/mod_access_compat.so
    %{_libdir}/httpd/modules/mod_actions.so
    %{_libdir}/httpd/modules/mod_alias.so
    %{_libdir}/httpd/modules/mod_allowmethods.so
    %{_libdir}/httpd/modules/mod_asis.so
    %{_libdir}/httpd/modules/mod_auth_basic.so
    %{_libdir}/httpd/modules/mod_auth_digest.so
    %{_libdir}/httpd/modules/mod_auth_form.so
    %{_libdir}/httpd/modules/mod_authn_anon.so
    %{_libdir}/httpd/modules/mod_authn_core.so
    %{_libdir}/httpd/modules/mod_authn_dbd.so
    %{_libdir}/httpd/modules/mod_authn_dbm.so
    %{_libdir}/httpd/modules/mod_authn_file.so
    %{_libdir}/httpd/modules/mod_authn_socache.so
    %{_libdir}/httpd/modules/mod_authz_core.so
    %{_libdir}/httpd/modules/mod_authz_dbd.so
    %{_libdir}/httpd/modules/mod_authz_dbm.so
    %{_libdir}/httpd/modules/mod_authz_groupfile.so
    %{_libdir}/httpd/modules/mod_authz_host.so
    %{_libdir}/httpd/modules/mod_authz_owner.so
    %{_libdir}/httpd/modules/mod_authz_user.so
    %{_libdir}/httpd/modules/mod_autoindex.so
    %{_libdir}/httpd/modules/mod_bucketeer.so
    %{_libdir}/httpd/modules/mod_buffer.so
    %{_libdir}/httpd/modules/mod_cache_disk.so
    %{_libdir}/httpd/modules/mod_cache_socache.so
    %{_libdir}/httpd/modules/mod_cache.so
    %{_libdir}/httpd/modules/mod_case_filter.so
    %{_libdir}/httpd/modules/mod_case_filter_in.so
    %{_libdir}/httpd/modules/mod_cgid.so
    %{_libdir}/httpd/modules/mod_charset_lite.so
    %{_libdir}/httpd/modules/mod_data.so
    %{_libdir}/httpd/modules/mod_dav_fs.so
    %{_libdir}/httpd/modules/mod_dav_lock.so
    %{_libdir}/httpd/modules/mod_dav.so
    %{_libdir}/httpd/modules/mod_dbd.so
    %{_libdir}/httpd/modules/mod_deflate.so
    %{_libdir}/httpd/modules/mod_dialup.so
    %{_libdir}/httpd/modules/mod_dir.so
    %{_libdir}/httpd/modules/mod_dumpio.so
    %{_libdir}/httpd/modules/mod_echo.so
    %{_libdir}/httpd/modules/mod_env.so
    %{_libdir}/httpd/modules/mod_expires.so
    %{_libdir}/httpd/modules/mod_ext_filter.so
    %{_libdir}/httpd/modules/mod_file_cache.so
    %{_libdir}/httpd/modules/mod_filter.so
    %{_libdir}/httpd/modules/mod_headers.so
    %{_libdir}/httpd/modules/mod_heartbeat.so
    %{_libdir}/httpd/modules/mod_heartmonitor.so
    %{_libdir}/httpd/modules/mod_include.so
    %{_libdir}/httpd/modules/mod_info.so
    %{_libdir}/httpd/modules/mod_lbmethod_bybusyness.so
    %{_libdir}/httpd/modules/mod_lbmethod_byrequests.so
    %{_libdir}/httpd/modules/mod_lbmethod_bytraffic.so
    %{_libdir}/httpd/modules/mod_lbmethod_heartbeat.so
    %{_libdir}/httpd/modules/mod_log_config.so
    %{_libdir}/httpd/modules/mod_log_debug.so
    %{_libdir}/httpd/modules/mod_log_forensic.so
    %{_libdir}/httpd/modules/mod_logio.so
    %{_libdir}/httpd/modules/mod_macro.so
    %{_libdir}/httpd/modules/mod_mime_magic.so
    %{_libdir}/httpd/modules/mod_mime.so
    %{_libdir}/httpd/modules/mod_mpm_event.so
    %{_libdir}/httpd/modules/mod_mpm_prefork.so
    %{_libdir}/httpd/modules/mod_mpm_worker.so
    %{_libdir}/httpd/modules/mod_negotiation.so
    %{_libdir}/httpd/modules/mod_proxy_ajp.so
    %{_libdir}/httpd/modules/mod_proxy_balancer.so
    %{_libdir}/httpd/modules/mod_proxy_connect.so
    %{_libdir}/httpd/modules/mod_proxy_express.so
    %{_libdir}/httpd/modules/mod_proxy_fcgi.so
    %{_libdir}/httpd/modules/mod_proxy_fdpass.so
    %{_libdir}/httpd/modules/mod_proxy_ftp.so
    %{_libdir}/httpd/modules/mod_proxy_http.so
    %{_libdir}/httpd/modules/mod_proxy_scgi.so
    %{_libdir}/httpd/modules/mod_proxy_uwsgi.so
    %{_libdir}/httpd/modules/mod_proxy_wstunnel.so
    %{_libdir}/httpd/modules/mod_proxy_hcheck.so
    %{_libdir}/httpd/modules/mod_proxy.so
    %{_libdir}/httpd/modules/mod_ratelimit.so
    %{_libdir}/httpd/modules/mod_reflector.so
    %{_libdir}/httpd/modules/mod_remoteip.so
    %{_libdir}/httpd/modules/mod_reqtimeout.so
    %{_libdir}/httpd/modules/mod_request.so
    %{_libdir}/httpd/modules/mod_rewrite.so
    %{_libdir}/httpd/modules/mod_sed.so
    %{_libdir}/httpd/modules/mod_session_cookie.so
    %{_libdir}/httpd/modules/mod_session_crypto.so
    %{_libdir}/httpd/modules/mod_session_dbd.so
    %{_libdir}/httpd/modules/mod_session.so
    %{_libdir}/httpd/modules/mod_setenvif.so
    %{_libdir}/httpd/modules/mod_slotmem_plain.so
    %{_libdir}/httpd/modules/mod_slotmem_shm.so
    %{_libdir}/httpd/modules/mod_socache_dbm.so
    %{_libdir}/httpd/modules/mod_socache_memcache.so
    %{_libdir}/httpd/modules/mod_socache_redis.so
    %{_libdir}/httpd/modules/mod_socache_shmcb.so
    %{_libdir}/httpd/modules/mod_speling.so
    %{_libdir}/httpd/modules/mod_status.so
    %{_libdir}/httpd/modules/mod_substitute.so
    %{_libdir}/httpd/modules/mod_suexec.so
    %{_libdir}/httpd/modules/mod_unique_id.so
    %{_libdir}/httpd/modules/mod_unixd.so
    %{_libdir}/httpd/modules/mod_userdir.so
    %{_libdir}/httpd/modules/mod_usertrack.so
    %{_libdir}/httpd/modules/mod_version.so
    %{_libdir}/httpd/modules/mod_vhost_alias.so
    %{_libdir}/httpd/modules/mod_watchdog.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
    %{contentdir}/html/index.html
    %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
    %attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd/cache-root
    
    %{_mandir}/man1/*
    %{_mandir}/man8/suexec*
    %{_mandir}/man8/apachectl.8*
    %{_mandir}/man8/httpd.8*
    %{_mandir}/man8/htcacheclean.8*
    %{_mandir}/man8/fcgistarter.8*
    
    %files manual
    %defattr(-,root,root)
    %{contentdir}/manual
    %{contentdir}/error/README
    
    %files tools
    %defattr(-,root,root)
    %{_bindir}/ab
    %{_bindir}/htdbm
    %{_bindir}/htdigest
    %{_bindir}/htpasswd
    %{_bindir}/logresolve
    %{_bindir}/httxt2dbm
    %{_sbindir}/rotatelogs
    %{_mandir}/man1/htdbm.1*
    %{_mandir}/man1/htdigest.1*
    %{_mandir}/man1/htpasswd.1*
    %{_mandir}/man1/httxt2dbm.1*
    %{_mandir}/man1/ab.1*
    %{_mandir}/man1/logresolve.1*
    %{_mandir}/man8/rotatelogs.8*
    %doc LICENSE NOTICE
    
    %files -n mod_authnz_ldap
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_ldap.so
    %{_libdir}/httpd/modules/mod_authnz_ldap.so
    
    %files -n mod_lua
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_lua.so
    
    %files -n mod_proxy_html
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_proxy_html.so
    %{_libdir}/httpd/modules/mod_xml2enc.so
    
    %files -n mod_ssl
    %defattr(-,root,root)
    %{_libdir}/httpd/modules/mod_ssl.so
    %config(noreplace) %{_sysconfdir}/httpd/conf/original/extra/httpd-ssl.conf
    %config(noreplace) %{_sysconfdir}/httpd/conf/extra/httpd-ssl.conf
    %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
    %{_bindir}/apxs
    %{_sbindir}/checkgid
    %{_bindir}/dbmmanage
    %{_sbindir}/envvars*
    %{_mandir}/man1/dbmmanage.1*
    %{_mandir}/man1/apxs.1*
    %dir %{_libdir}/httpd/build
    %{_libdir}/httpd/build/*.mk
    %{_libdir}/httpd/build/instdso.sh
    %{_libdir}/httpd/build/config.nice
    %{_libdir}/httpd/build/mkdir.sh
    
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������